ngx-pluto
Version:
542 lines • 46.9 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import { coerceArray, coerceBooleanProperty } from '@angular/cdk/coercion';
import { ContentChildren, ElementRef, EventEmitter, forwardRef, Input, Output, QueryList, Optional, Directive, ChangeDetectorRef, SkipSelf, Inject, } from '@angular/core';
import { DOCUMENT } from '@angular/common';
import { Directionality } from '@angular/cdk/bidi';
import { CdkDrag } from './drag';
import { DragDropRegistry } from '../drag-drop-registry';
import { CDK_DROP_LIST_CONTAINER } from '../drop-list-container';
import { CdkDropListGroup } from './drop-list-group';
import { DropListRef } from '../drop-list-ref';
import { DragDrop } from '../drag-drop';
import { Subject } from 'rxjs';
import { startWith, takeUntil } from 'rxjs/operators';
/**
* Counter used to generate unique ids for drop zones.
* @type {?}
*/
let _uniqueIdCounter = 0;
/**
* @ignore
* Internal compile-time-only representation of a `CdkDropList`.
* Used to avoid circular import issues between the `CdkDropList` and the `CdkDrag`.
* \@docs-private
* @record
*/
export function CdkDropListInternal() { }
const ɵ0 = undefined;
// @breaking-change 8.0.0 `CdkDropList` implements `CdkDropListContainer` for backwards
// compatiblity. The implements clause, as well as all the methods that it enforces can
// be removed when `CdkDropListContainer` is deleted.
/**
* @ignore
* Container that wraps a set of draggable items.
*
* @template T
*/
export class CdkDropList {
/**
* @param {?} element
* @param {?} dragDropRegistry
* @param {?} _changeDetectorRef
* @param {?=} _dir
* @param {?=} _group
* @param {?=} _document
* @param {?=} dragDrop
*/
constructor(element, dragDropRegistry, _changeDetectorRef, _dir, _group, _document,
/**
* @deprecated `dragDropRegistry` and `_document` parameters to be removed.
* Also `dragDrop` parameter to be made required.
* @breaking-change 8.0.0.
*/
dragDrop) {
this.element = element;
this._changeDetectorRef = _changeDetectorRef;
this._dir = _dir;
this._group = _group;
/**
* Emits when the list has been destroyed.
*/
this._destroyed = new Subject();
/**
* Other draggable containers that this container is connected to and into which the
* container's items can be transferred. Can either be references to other drop containers,
* or their unique IDs.
*/
this.connectedTo = [];
/**
* Direction in which the list is oriented.
*/
this.orientation = 'vertical';
/**
* Unique ID for the drop zone. Can be used as a reference
* in the `connectedTo` of another `CdkDropList`.
*/
this.id = `cdk-drop-list-${_uniqueIdCounter++}`;
this._disabled = false;
/**
* Function that is used to determine whether an item
* is allowed to be moved into a drop container.
*/
this.enterPredicate = (/**
* @return {?}
*/
() => true);
/**
* Emits when the user drops an item inside the container.
*/
this.dropped = new EventEmitter();
/**
* Emits when the user has moved a new drag item into this container.
*/
this.entered = new EventEmitter();
/**
* Emits when the user removes an item from the container
* by dragging it into another container.
*/
this.exited = new EventEmitter();
/**
* Emits as the user is swapping items while actively dragging.
*/
this.sorted = new EventEmitter();
// @breaking-change 8.0.0 Remove null check once `dragDrop` parameter is made required.
if (dragDrop) {
this._dropListRef = dragDrop.createDropList(element);
}
else {
this._dropListRef = new DropListRef(element, dragDropRegistry, _document || document);
}
this._dropListRef.data = this;
this._dropListRef.enterPredicate = (/**
* @param {?} drag
* @param {?} drop
* @return {?}
*/
(drag, drop) => {
return this.enterPredicate(drag.data, drop.data);
});
this._syncInputs(this._dropListRef);
this._handleEvents(this._dropListRef);
CdkDropList._dropLists.push(this);
if (_group) {
_group._items.add(this);
}
}
/**
* Whether starting a dragging sequence from this container is disabled.
* @return {?}
*/
get disabled() {
return this._disabled || (!!this._group && this._group.disabled);
}
/**
* @param {?} value
* @return {?}
*/
set disabled(value) {
this._disabled = coerceBooleanProperty(value);
}
/**
* @return {?}
*/
ngAfterContentInit() {
this._draggables.changes
.pipe(startWith(this._draggables), takeUntil(this._destroyed))
.subscribe((/**
* @param {?} items
* @return {?}
*/
(items) => {
this._dropListRef.withItems(items.map((/**
* @param {?} drag
* @return {?}
*/
drag => drag._dragRef)));
}));
}
/**
* @return {?}
*/
ngOnDestroy() {
/** @type {?} */
const index = CdkDropList._dropLists.indexOf(this);
if (index > -1) {
CdkDropList._dropLists.splice(index, 1);
}
if (this._group) {
this._group._items.delete(this);
}
this._dropListRef.dispose();
this._destroyed.next();
this._destroyed.complete();
}
/**
* Starts dragging an item.
* @return {?}
*/
start() {
this._dropListRef.start();
}
/**
* Drops an item into this container.
* @param {?} item Item being dropped into the container.
* @param {?} currentIndex Index at which the item should be inserted.
* @param {?} previousContainer Container from which the item got dragged in.
* @param {?} isPointerOverContainer Whether the user's pointer was over the
* container when the item was dropped.
* @return {?}
*/
drop(item, currentIndex, previousContainer, isPointerOverContainer) {
this._dropListRef.drop(item._dragRef, currentIndex, ((/** @type {?} */ (previousContainer)))._dropListRef, isPointerOverContainer);
}
/**
* Emits an event to indicate that the user moved an item into the container.
* @param {?} item Item that was moved into the container.
* @param {?} pointerX Position of the item along the X axis.
* @param {?} pointerY Position of the item along the Y axis.
* @return {?}
*/
enter(item, pointerX, pointerY) {
this._dropListRef.enter(item._dragRef, pointerX, pointerY);
}
/**
* Removes an item from the container after it was dragged into another container by the user.
* @param {?} item Item that was dragged out.
* @return {?}
*/
exit(item) {
this._dropListRef.exit(item._dragRef);
}
/**
* Figures out the index of an item in the container.
* @param {?} item Item whose index should be determined.
* @return {?}
*/
getItemIndex(item) {
return this._dropListRef.getItemIndex(item._dragRef);
}
/**
* Sorts an item inside the container based on its position.
* @param {?} item Item to be sorted.
* @param {?} pointerX Position of the item along the X axis.
* @param {?} pointerY Position of the item along the Y axis.
* @param {?} pointerDelta Direction in which the pointer is moving along each axis.
* @return {?}
*/
_sortItem(item, pointerX, pointerY, pointerDelta) {
return this._dropListRef._sortItem(item._dragRef, pointerX, pointerY, pointerDelta);
}
/**
* Figures out whether an item should be moved into a sibling
* drop container, based on its current position.
* @param {?} item Drag item that is being moved.
* @param {?} x Position of the item along the X axis.
* @param {?} y Position of the item along the Y axis.
* @return {?}
*/
_getSiblingContainerFromPosition(item, x, y) {
/** @type {?} */
const result = this._dropListRef._getSiblingContainerFromPosition(item._dragRef, x, y);
return result ? result.data : null;
}
/**
* Checks whether the user's pointer is positioned over the container.
* @param {?} x Pointer position along the X axis.
* @param {?} y Pointer position along the Y axis.
* @return {?}
*/
_isOverContainer(x, y) {
return this._dropListRef._isOverContainer(x, y);
}
/**
* Syncs the inputs of the CdkDropList with the options of the underlying DropListRef.
* @private
* @param {?} ref
* @return {?}
*/
_syncInputs(ref) {
if (this._dir) {
this._dir.change
.pipe(startWith(this._dir.value), takeUntil(this._destroyed))
.subscribe((/**
* @param {?} value
* @return {?}
*/
value => ref.withDirection(value)));
}
ref.beforeStarted.subscribe((/**
* @return {?}
*/
() => {
/** @type {?} */
const siblings = coerceArray(this.connectedTo).map((/**
* @param {?} drop
* @return {?}
*/
drop => {
return typeof drop === 'string' ?
(/** @type {?} */ (CdkDropList._dropLists.find((/**
* @param {?} list
* @return {?}
*/
list => list.id === drop)))) : drop;
}));
if (this._group) {
this._group._items.forEach((/**
* @param {?} drop
* @return {?}
*/
drop => {
if (siblings.indexOf(drop) === -1) {
siblings.push(drop);
}
}));
}
ref.lockAxis = this.lockAxis;
ref
.connectedTo(siblings.filter((/**
* @param {?} drop
* @return {?}
*/
drop => drop && drop !== this)).map((/**
* @param {?} list
* @return {?}
*/
list => list._dropListRef)))
.withOrientation(this.orientation);
}));
}
/**
* Handles events from the underlying DropListRef.
* @private
* @param {?} ref
* @return {?}
*/
_handleEvents(ref) {
ref.beforeStarted.subscribe((/**
* @return {?}
*/
() => {
this._changeDetectorRef.markForCheck();
}));
ref.entered.subscribe((/**
* @param {?} event
* @return {?}
*/
event => {
this.entered.emit({
container: this,
item: event.item.data
});
}));
ref.exited.subscribe((/**
* @param {?} event
* @return {?}
*/
event => {
this.exited.emit({
container: this,
item: event.item.data
});
}));
ref.sorted.subscribe((/**
* @param {?} event
* @return {?}
*/
event => {
this.sorted.emit({
previousIndex: event.previousIndex,
currentIndex: event.currentIndex,
container: this,
item: event.item.data
});
}));
ref.dropped.subscribe((/**
* @param {?} event
* @return {?}
*/
event => {
this.dropped.emit({
previousIndex: event.previousIndex,
currentIndex: event.currentIndex,
previousContainer: event.previousContainer.data,
container: event.container.data,
item: event.item.data,
isPointerOverContainer: event.isPointerOverContainer
});
// Mark for check since all of these events run outside of change
// detection and we're not guaranteed for something else to have triggered it.
this._changeDetectorRef.markForCheck();
}));
}
}
/**
* Keeps track of the drop lists that are currently on the page.
*/
CdkDropList._dropLists = [];
CdkDropList.decorators = [
{ type: Directive, args: [{
selector: '[cdkDropList], cdk-drop-list',
exportAs: 'cdkDropList',
providers: [
// Prevent child drop lists from picking up the same group as their parent.
{ provide: CdkDropListGroup, useValue: ɵ0 },
{ provide: CDK_DROP_LIST_CONTAINER, useExisting: CdkDropList },
],
host: {
'class': 'cdk-drop-list',
'[id]': 'id',
'[class.cdk-drop-list-disabled]': 'disabled',
'[class.cdk-drop-list-dragging]': '_dropListRef.isDragging()',
'[class.cdk-drop-list-receiving]': '_dropListRef.isReceiving()',
}
},] }
];
/** @nocollapse */
CdkDropList.ctorParameters = () => [
{ type: ElementRef },
{ type: DragDropRegistry },
{ type: ChangeDetectorRef },
{ type: Directionality, decorators: [{ type: Optional }] },
{ type: CdkDropListGroup, decorators: [{ type: Optional }, { type: SkipSelf }] },
{ type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [DOCUMENT,] }] },
{ type: DragDrop }
];
CdkDropList.propDecorators = {
_draggables: [{ type: ContentChildren, args: [forwardRef((/**
* @return {?}
*/
() => CdkDrag)), {
// Explicitly set to false since some of the logic below makes assumptions about it.
// The `.withItems` call below should be updated if we ever need to switch this to `true`.
descendants: false
},] }],
connectedTo: [{ type: Input, args: ['cdkDropListConnectedTo',] }],
data: [{ type: Input, args: ['cdkDropListData',] }],
orientation: [{ type: Input, args: ['cdkDropListOrientation',] }],
id: [{ type: Input }],
lockAxis: [{ type: Input, args: ['cdkDropListLockAxis',] }],
disabled: [{ type: Input, args: ['cdkDropListDisabled',] }],
enterPredicate: [{ type: Input, args: ['cdkDropListEnterPredicate',] }],
dropped: [{ type: Output, args: ['cdkDropListDropped',] }],
entered: [{ type: Output, args: ['cdkDropListEntered',] }],
exited: [{ type: Output, args: ['cdkDropListExited',] }],
sorted: [{ type: Output, args: ['cdkDropListSorted',] }]
};
if (false) {
/**
* Keeps track of the drop lists that are currently on the page.
* @type {?}
* @private
*/
CdkDropList._dropLists;
/**
* Emits when the list has been destroyed.
* @type {?}
* @private
*/
CdkDropList.prototype._destroyed;
/**
* Reference to the underlying drop list instance.
* @type {?}
*/
CdkDropList.prototype._dropListRef;
/**
* Draggable items in the container.
* @type {?}
*/
CdkDropList.prototype._draggables;
/**
* Other draggable containers that this container is connected to and into which the
* container's items can be transferred. Can either be references to other drop containers,
* or their unique IDs.
* @type {?}
*/
CdkDropList.prototype.connectedTo;
/**
* Arbitrary data to attach to this container.
* @type {?}
*/
CdkDropList.prototype.data;
/**
* Direction in which the list is oriented.
* @type {?}
*/
CdkDropList.prototype.orientation;
/**
* Unique ID for the drop zone. Can be used as a reference
* in the `connectedTo` of another `CdkDropList`.
* @type {?}
*/
CdkDropList.prototype.id;
/**
* Locks the position of the draggable elements inside the container along the specified axis.
* @type {?}
*/
CdkDropList.prototype.lockAxis;
/**
* @type {?}
* @private
*/
CdkDropList.prototype._disabled;
/**
* Function that is used to determine whether an item
* is allowed to be moved into a drop container.
* @type {?}
*/
CdkDropList.prototype.enterPredicate;
/**
* Emits when the user drops an item inside the container.
* @type {?}
*/
CdkDropList.prototype.dropped;
/**
* Emits when the user has moved a new drag item into this container.
* @type {?}
*/
CdkDropList.prototype.entered;
/**
* Emits when the user removes an item from the container
* by dragging it into another container.
* @type {?}
*/
CdkDropList.prototype.exited;
/**
* Emits as the user is swapping items while actively dragging.
* @type {?}
*/
CdkDropList.prototype.sorted;
/**
* Element that the drop list is attached to.
* @type {?}
*/
CdkDropList.prototype.element;
/**
* @type {?}
* @private
*/
CdkDropList.prototype._changeDetectorRef;
/**
* @type {?}
* @private
*/
CdkDropList.prototype._dir;
/**
* @type {?}
* @private
*/
CdkDropList.prototype._group;
}
export { ɵ0 };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHJvcC1saXN0LmpzIiwic291cmNlUm9vdCI6Im5nOi8vbmd4LXBsdXRvLyIsInNvdXJjZXMiOlsibGliL2RyYWctZHJvcC9kaXJlY3RpdmVzL2Ryb3AtbGlzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7OztBQVFBLE9BQU8sRUFBQyxXQUFXLEVBQUUscUJBQXFCLEVBQUMsTUFBTSx1QkFBdUIsQ0FBQztBQUN6RSxPQUFPLEVBQ0wsZUFBZSxFQUNmLFVBQVUsRUFDVixZQUFZLEVBQ1osVUFBVSxFQUNWLEtBQUssRUFFTCxNQUFNLEVBQ04sU0FBUyxFQUNULFFBQVEsRUFDUixTQUFTLEVBQ1QsaUJBQWlCLEVBQ2pCLFFBQVEsRUFDUixNQUFNLEdBRVAsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFDLFFBQVEsRUFBQyxNQUFNLGlCQUFpQixDQUFDO0FBQ3pDLE9BQU8sRUFBQyxjQUFjLEVBQUMsTUFBTSxtQkFBbUIsQ0FBQztBQUNqRCxPQUFPLEVBQUMsT0FBTyxFQUFDLE1BQU0sUUFBUSxDQUFDO0FBQy9CLE9BQU8sRUFBQyxnQkFBZ0IsRUFBQyxNQUFNLHVCQUF1QixDQUFDO0FBRXZELE9BQU8sRUFBQyx1QkFBdUIsRUFBdUIsTUFBTSx3QkFBd0IsQ0FBQztBQUNyRixPQUFPLEVBQUMsZ0JBQWdCLEVBQUMsTUFBTSxtQkFBbUIsQ0FBQztBQUNuRCxPQUFPLEVBQUMsV0FBVyxFQUFDLE1BQU0sa0JBQWtCLENBQUM7QUFFN0MsT0FBTyxFQUFDLFFBQVEsRUFBQyxNQUFNLGNBQWMsQ0FBQztBQUN0QyxPQUFPLEVBQUMsT0FBTyxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBQzdCLE9BQU8sRUFBQyxTQUFTLEVBQUUsU0FBUyxFQUFDLE1BQU0sZ0JBQWdCLENBQUM7Ozs7O0lBR2hELGdCQUFnQixHQUFHLENBQUM7Ozs7Ozs7O0FBUXhCLHlDQUEyRDtXQWVqQixTQUFTOzs7Ozs7Ozs7O0FBV25ELE1BQU0sT0FBTyxXQUFXOzs7Ozs7Ozs7O0lB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S0FBSzt1QkFHTCxLQUFLLFNBQUMscUJBQXFCO3VCQUczQixLQUFLLFNBQUMscUJBQXFCOzZCQWEzQixLQUFLLFNBQUMsMkJBQTJCO3NCQUlqQyxNQUFNLFNBQUMsb0JBQW9CO3NCQU0zQixNQUFNLFNBQUMsb0JBQW9CO3FCQU8zQixNQUFNLFNBQUMsbUJBQW1CO3FCQUkxQixNQUFNLFNBQUMsbUJBQW1COzs7Ozs7OztJQXRFM0IsdUJBQThDOzs7Ozs7SUFIOUMsaUNBQXlDOzs7OztJQU16QyxtQ0FBMEM7Ozs7O0lBRzFDLGtDQUltQzs7Ozs7OztJQU9uQyxrQ0FDa0U7Ozs7O0lBR2xFLDJCQUFrQzs7Ozs7SUFHbEMsa0NBQXFGOzs7Ozs7SUFNckYseUJBQTREOzs7OztJQUc1RCwrQkFBa0Q7Ozs7O0lBVWxELGdDQUEwQjs7Ozs7O0lBTTFCLHFDQUMwRTs7Ozs7SUFHMUUsOEJBQ3FGOzs7OztJQUtyRiw4QkFDNkU7Ozs7OztJQU03RSw2QkFDMEU7Ozs7O0lBRzFFLDZCQUNvRjs7Ozs7SUFJbEYsOEJBQXVDOzs7OztJQUV2Qyx5Q0FBNkM7Ozs7O0lBQzdDLDJCQUF5Qzs7Ozs7SUFDekMsNkJBQXNFIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXHJcbiAqIEBsaWNlbnNlXHJcbiAqIENvcHlyaWdodCBHb29nbGUgTExDIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXHJcbiAqXHJcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXHJcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcclxuICovXHJcblxyXG5pbXBvcnQge2NvZXJjZUFycmF5LCBjb2VyY2VCb29sZWFuUHJvcGVydHl9IGZyb20gJ0Bhbmd1bGFyL2Nkay9jb2VyY2lvbic7XHJcbmltcG9ydCB7XHJcbiAgQ29udGVudENoaWxkcmVuLFxyXG4gIEVsZW1lbnRSZWYsXHJcbiAgRXZlbnRFbWl0dGVyLFxyXG4gIGZvcndhcmRSZWYsXHJcbiAgSW5wdXQsXHJcbiAgT25EZXN0cm95LFxyXG4gIE91dHB1dCxcclxuICBRdWVyeUxpc3QsXHJcbiAgT3B0aW9uYWwsXHJcbiAgRGlyZWN0aXZlLFxyXG4gIENoYW5nZURldGVjdG9yUmVmLFxyXG4gIFNraXBTZWxmLFxyXG4gIEluamVjdCxcclxuICBBZnRlckNvbnRlbnRJbml0LFxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQge0RPQ1VNRU5UfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xyXG5pbXBvcnQge0RpcmVjdGlvbmFsaXR5fSBmcm9tICdAYW5ndWxhci9jZGsvYmlkaSc7XHJcbmltcG9ydCB7Q2RrRHJhZ30gZnJvbSAnLi9kcmFnJztcclxuaW1wb3J0IHtEcmFnRHJvcFJlZ2lzdHJ5fSBmcm9tICcuLi9kcmFnLWRyb3AtcmVnaXN0cnknO1xyXG5pbXBvcnQge0Nka0RyYWdEcm9wLCBDZGtEcmFnRW50ZXIsIENka0RyYWdFeGl0LCBDZGtEcmFnU29ydEV2ZW50fSBmcm9tICcuLi9kcmFnLWV2ZW50cyc7XHJcbmltcG9ydCB7Q0RLX0RST1BfTElTVF9DT05UQUlORVIsIENka0Ryb3BMaXN0Q29udGFpbmVyfSBmcm9tICcuLi9kcm9wLWxpc3QtY29udGFpbmVyJztcclxuaW1wb3J0IHtDZGtEcm9wTGlzdEdyb3VwfSBmcm9tICcuL2Ryb3AtbGlzdC1ncm91cCc7XHJcbmltcG9ydCB7RHJvcExpc3RSZWZ9IGZyb20gJy4uL2Ryb3AtbGlzdC1yZWYnO1xyXG5pbXBvcnQge0RyYWdSZWZ9IGZyb20gJy4uL2RyYWctcmVmJztcclxuaW1wb3J0IHtEcmFnRHJvcH0gZnJvbSAnLi4vZHJhZy1kcm9wJztcclxuaW1wb3J0IHtTdWJqZWN0fSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHtzdGFydFdpdGgsIHRha2VVbnRpbH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xyXG5cclxuLyoqIENvdW50ZXIgdXNlZCB0byBnZW5lcmF0ZSB1bmlxdWUgaWRzIGZvciBkcm9wIHpvbmVzLiAqL1xyXG5sZXQgX3VuaXF1ZUlkQ291bnRlciA9IDA7XHJcblxyXG4vKipcclxuICogQGlnbm9yZVxyXG4gKiBJbnRlcm5hbCBjb21waWxlLXRpbWUtb25seSByZXByZXNlbnRhdGlvbiBvZiBhIGBDZGtEcm9wTGlzdGAuXHJcbiAqIFVzZWQgdG8gYXZvaWQgY2lyY3VsYXIgaW1wb3J0IGlzc3VlcyBiZXR3ZWVuIHRoZSBgQ2RrRHJvcExpc3RgIGFuZCB0aGUgYENka0RyYWdgLlxyXG4gKiBAZG9jcy1wcml2YXRlXHJcbiAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIENka0Ryb3BMaXN0SW50ZXJuYWwgZXh0ZW5kcyBDZGtEcm9wTGlzdCB7fVxyXG5cclxuLy8gQGJyZWFraW5nLWNoYW5nZSA4LjAuMCBgQ2RrRHJvcExpc3RgIGltcGxlbWVudHMgYENka0Ryb3BMaXN0Q29udGFpbmVyYCBmb3IgYmFja3dhcmRzXHJcbi8vIGNvbXBhdGlibGl0eS4gVGhlIGltcGxlbWVudHMgY2xhdXNlLCBhcyB3ZWxsIGFzIGFsbCB0aGUgbWV0aG9kcyB0aGF0IGl0IGVuZm9yY2VzIGNhblxyXG4vLyBiZSByZW1vdmVkIHdoZW4gYENka0Ryb3BMaXN0Q29udGFpbmVyYCBpcyBkZWxldGVkLlxyXG5cclxuLyoqIFxyXG4gKiBAaWdub3JlXHJcbiAqIENvbnRhaW5lciB0aGF0IHdyYXBzIGEgc2V0IG9mIGRyYWdnYWJsZSBpdGVtcy4gXHJcbiAqICovXHJcbkBEaXJlY3RpdmUoe1xyXG4gIHNlbGVjdG9yOiAnW2Nka0Ryb3BMaXN0XSwgY2RrLWRyb3AtbGlzdCcsXHJcbiAgZXhwb3J0QXM6ICdjZGtEcm9wTGlzdCcsXHJcbiAgcHJvdmlkZXJzOiBbXHJcbiAgICAvLyBQcmV2ZW50IGNoaWxkIGRyb3AgbGlzdHMgZnJvbSBwaWNraW5nIHVwIHRoZSBzYW1lIGdyb3VwIGFzIHRoZWlyIHBhcmVudC5cclxuICAgIHtwcm92aWRlOiBDZGtEcm9wTGlzdEdyb3VwLCB1c2VWYWx1ZTogdW5kZWZpbmVkfSxcclxuICAgIHtwcm92aWRlOiBDREtfRFJPUF9MSVNUX0NPTlRBSU5FUiwgdXNlRXhpc3Rpbmc6IENka0Ryb3BMaXN0fSxcclxuICBdLFxyXG4gIGhvc3Q6IHtcclxuICAgICdjbGFzcyc6ICdjZGstZHJvcC1saXN0JyxcclxuICAgICdbaWRdJzogJ2lkJyxcclxuICAgICdbY2xhc3MuY2RrLWRyb3AtbGlzdC1kaXNhYmxlZF0nOiAnZGlzYWJsZWQnLFxyXG4gICAgJ1tjbGFzcy5jZGstZHJvcC1saXN0LWRyYWdnaW5nXSc6ICdfZHJvcExpc3RSZWYuaXNEcmFnZ2luZygpJyxcclxuICAgICdbY2xhc3MuY2RrLWRyb3AtbGlzdC1yZWNlaXZpbmddJzogJ19kcm9wTGlzdFJlZi5pc1JlY2VpdmluZygpJyxcclxuICB9XHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBDZGtEcm9wTGlzdDxUID0gYW55PiBpbXBsZW1lbnRzIENka0Ryb3BMaXN0Q29udGFpbmVyLCBBZnRlckNvbnRlbnRJbml0LCBPbkRlc3Ryb3kge1xyXG4gIC8qKiBFbWl0cyB3aGVuIHRoZSBsaXN0IGhhcyBiZWVuIGRlc3Ryb3llZC4gKi9cclxuICBwcml2YXRlIF9kZXN0cm95ZWQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xyXG5cclxuICAvKiogS2VlcHMgdHJhY2sgb2YgdGhlIGRyb3AgbGlzdHMgdGhhdCBhcmUgY3VycmVudGx5IG9uIHRoZSBwYWdlLiAqL1xyXG4gIHByaXZhdGUgc3RhdGljIF9kcm9wTGlzdHM6IENka0Ryb3BMaXN0W10gPSBbXTtcclxuXHJcbiAgLyoqIFJlZmVyZW5jZSB0byB0aGUgdW5kZXJseWluZyBkcm9wIGxpc3QgaW5zdGFuY2UuICovXHJcbiAgX2Ryb3BMaXN0UmVmOiBEcm9wTGlzdFJlZjxDZGtEcm9wTGlzdDxUPj47XHJcblxyXG4gIC8qKiBEcmFnZ2FibGUgaXRlbXMgaW4gdGhlIGNvbnRhaW5lci4gKi9cclxuICBAQ29udGVudENoaWxkcmVuKGZvcndhcmRSZWYoKCkgPT4gQ2RrRHJhZyksIHtcclxuICAgIC8vIEV4cGxpY2l0bHkgc2V0IHRvIGZhbHNlIHNpbmNlIHNvbWUgb2YgdGhlIGxvZ2ljIGJlbG93IG1ha2VzIGFzc3VtcHRpb25zIGFib3V0IGl0LlxyXG4gICAgLy8gVGhlIGAud2l0aEl0ZW1zYCBjYWxsIGJlbG93IHNob3VsZCBiZSB1cGRhdGVkIGlmIHdlIGV2ZXIgbmVlZCB0byBzd2l0Y2ggdGhpcyB0byBgdHJ1ZWAuXHJcbiAgICBkZXNjZW5kYW50czogZmFsc2VcclxuICB9KSBfZHJhZ2dhYmxlczogUXVlcnlMaXN0PENka0RyYWc+O1xyXG5cclxuICAvKipcclxuICAgKiBPdGhlciBkcmFnZ2FibGUgY29udGFpbmVycyB0aGF0IHRoaXMgY29udGFpbmVyIGlzIGNvbm5lY3RlZCB0byBhbmQgaW50byB3aGljaCB0aGVcclxuICAgKiBjb250YWluZXIncyBpdGVtcyBjYW4gYmUgdHJhbnNmZXJyZWQuIENhbiBlaXRoZXIgYmUgcmVmZXJlbmNlcyB0byBvdGhlciBkcm9wIGNvbnRhaW5lcnMsXHJcbiAgICogb3IgdGhlaXIgdW5pcXVlIElEcy5cclxuICAgKi9cclxuICBASW5wdXQoJ2Nka0Ryb3BMaXN0Q29ubmVjdGVkVG8nKVxyXG4gIGNvbm5lY3RlZFRvOiAoQ2RrRHJvcExpc3QgfCBzdHJpbmcpW10gfCBDZGtEcm9wTGlzdCB8IHN0cmluZyA9IFtdO1xyXG5cclxuICAvKiogQXJiaXRyYXJ5IGRhdGEgdG8gYXR0YWNoIHRvIHRoaXMgY29udGFpbmVyLiAqL1xyXG4gIEBJbnB1dCgnY2RrRHJvcExpc3REYXRhJykgZGF0YTogVDtcclxuXHJcbiAgLyoqIERpcmVjdGlvbiBpbiB3aGljaCB0aGUgbGlzdCBpcyBvcmllbnRlZC4gKi9cclxuICBASW5wdXQoJ2Nka0Ryb3BMaXN0T3JpZW50YXRpb24nKSBvcmllbnRhdGlvbjogJ2hvcml6b250YWwnIHwgJ3ZlcnRpY2FsJyA9ICd2ZXJ0aWNhbCc7XHJcblxyXG4gIC8qKlxyXG4gICAqIFVuaXF1ZSBJRCBmb3IgdGhlIGRyb3Agem9uZS4gQ2FuIGJlIHVzZWQgYXMgYSByZWZlcmVuY2VcclxuICAgKiBpbiB0aGUgYGNvbm5lY3RlZFRvYCBvZiBhbm90aGVyIGBDZGtEcm9wTGlzdGAuXHJcbiAgICovXHJcbiAgQElucHV0KCkgaWQ6IHN0cmluZyA9IGBjZGstZHJvcC1saXN0LSR7X3VuaXF1ZUlkQ291bnRlcisrfWA7XHJcblxyXG4gIC8qKiBMb2NrcyB0aGUgcG9zaXRpb24gb2YgdGhlIGRyYWdnYWJsZSBlbGVtZW50cyBpbnNpZGUgdGhlIGNvbnRhaW5lciBhbG9uZyB0aGUgc3BlY2lmaWVkIGF4aXMuICovXHJcbiAgQElucHV0KCdjZGtEcm9wTGlzdExvY2tBeGlzJykgbG9ja0F4aXM6ICd4JyB8ICd5JztcclxuXHJcbiAgLyoqIFdoZXRoZXIgc3RhcnRpbmcgYSBkcmFnZ2luZyBzZXF1ZW5jZSBmcm9tIHRoaXMgY29udGFpbmVyIGlzIGRpc2FibGVkLiAqL1xyXG4gIEBJbnB1dCgnY2RrRHJvcExpc3REaXNhYmxlZCcpXHJcbiAgZ2V0IGRpc2FibGVkKCk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHRoaXMuX2Rpc2FibGVkIHx8ICghIXRoaXMuX2dyb3VwICYmIHRoaXMuX2dyb3VwLmRpc2FibGVkKTtcclxuICB9XHJcbiAgc2V0IGRpc2FibGVkKHZhbHVlOiBib29sZWFuKSB7XHJcbiAgICB0aGlzLl9kaXNhYmxlZCA9IGNvZXJjZUJvb2xlYW5Qcm9wZXJ0eSh2YWx1ZSk7XHJcbiAgfVxyXG4gIHByaXZhdGUgX2Rpc2FibGVkID0gZmFsc2U7XHJcblxyXG4gIC8qKlxyXG4gICAqIEZ1bmN0aW9uIHRoYXQgaXMgdXNlZCB0byBkZXRlcm1pbmUgd2hldGhlciBhbiBpdGVtXHJcbiAgICogaXMgYWxsb3dlZCB0byBiZSBtb3ZlZCBpbnRvIGEgZHJvcCBjb250YWluZXIuXHJcbiAgICovXHJcbiAgQElucHV0KCdjZGtEcm9wTGlzdEVudGVyUHJlZGljYXRlJylcclxuICBlbnRlclByZWRpY2F0ZTogKGRyYWc6IENka0RyYWcsIGRyb3A6IENka0Ryb3BMaXN0KSA9PiBib29sZWFuID0gKCkgPT4gdHJ1ZVxyXG5cclxuICAvKiogRW1pdHMgd2hlbiB0aGUgdXNlciBkcm9wcyBhbiBpdGVtIGluc2lkZSB0aGUgY29udGFpbmVyLiAqL1xyXG4gIEBPdXRwdXQoJ2Nka0Ryb3BMaXN0RHJvcHBlZCcpXHJcbiAgZHJvcHBlZDogRXZlbnRFbWl0dGVyPENka0RyYWdEcm9wPFQsIGFueT4+ID0gbmV3IEV2ZW50RW1pdHRlcjxDZGtEcmFnRHJvcDxULCBhbnk+PigpO1xyXG5cclxuICAvKipcclxuICAgKiBFbWl0cyB3aGVuIHRoZSB1c2VyIGhhcyBtb3ZlZCBhIG5ldyBkcmFnIGl0ZW0gaW50byB0aGlzIGNvbnRhaW5lci5cclxuICAgKi9cclxuICBAT3V0cHV0KCdjZGtEcm9wTGlzdEVudGVyZWQnKVxyXG4gIGVudGVyZWQ6IEV2ZW50RW1pdHRlcjxDZGtEcmFnRW50ZXI8VD4+ID0gbmV3IEV2ZW50RW1pdHRlcjxDZGtEcmFnRW50ZXI8VD4+KCk7XHJcblxyXG4gIC8qKlxyXG4gICAqIEVtaXRzIHdoZW4gdGhlIHVzZXIgcmVtb3ZlcyBhbiBpdGVtIGZyb20gdGhlIGNvbnRhaW5lclxyXG4gICAqIGJ5IGRyYWdnaW5nIGl0IGludG8gYW5vdGhlciBjb250YWluZXIuXHJcbiAgICovXHJcbiAgQE91dHB1dCgnY2RrRHJvcExpc3RFeGl0ZWQnKVxyXG4gIGV4aXRlZDogRXZlbnRFbWl0dGVyPENka0RyYWdFeGl0PFQ+PiA9IG5ldyBFdmVudEVtaXR0ZXI8Q2RrRHJhZ0V4aXQ8VD4+KCk7XHJcblxyXG4gIC8qKiBFbWl0cyBhcyB0aGUgdXNlciBpcyBzd2FwcGluZyBpdGVtcyB3aGlsZSBhY3RpdmVseSBkcmFnZ2luZy4gKi9cclxuICBAT3V0cHV0KCdjZGtEcm9wTGlzdFNvcnRlZCcpXHJcbiAgc29ydGVkOiBFdmVudEVtaXR0ZXI8Q2RrRHJhZ1NvcnRFdmVudDxUPj4gPSBuZXcgRXZlbnRFbWl0dGVyPENka0RyYWdTb3J0RXZlbnQ8VD4+KCk7XHJcblxyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAgLyoqIEVsZW1lbnQgdGhhdCB0aGUgZHJvcCBsaXN0IGlzIGF0dGFjaGVkIHRvLiAqL1xyXG4gICAgcHVibGljIGVsZW1lbnQ6IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+LFxyXG4gICAgZHJhZ0Ryb3BSZWdpc3RyeTogRHJhZ0Ryb3BSZWdpc3RyeTxEcmFnUmVmLCBEcm9wTGlzdFJlZj4sXHJcbiAgICBwcml2YXRlIF9jaGFuZ2VEZXRlY3RvclJlZjogQ2hhbmdlRGV0ZWN0b3JSZWYsXHJcbiAgICBAT3B0aW9uYWwoKSBwcml2YXRlIF9kaXI/OiBEaXJlY3Rpb25hbGl0eSxcclxuICAgIEBPcHRpb25hbCgpIEBTa2lwU2VsZigpIHByaXZhdGUgX2dyb3VwPzogQ2RrRHJvcExpc3RHcm91cDxDZGtEcm9wTGlzdD4sXHJcbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KERPQ1VNRU5UKSBfZG9jdW1lbnQ/OiBhbnksXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBAZGVwcmVjYXRlZCBgZHJhZ0Ryb3BSZWdpc3RyeWAgYW5kIGBfZG9jdW1lbnRgIHBhcmFtZXRlcnMgdG8gYmUgcmVtb3ZlZC5cclxuICAgICAqIEFsc28gYGRyYWdEcm9wYCBwYXJhbWV0ZXIgdG8gYmUgbWFkZSByZXF1aXJlZC5cclxuICAgICAqIEBicmVha2luZy1jaGFuZ2UgOC4wLjAuXHJcbiAgICAgKi9cclxuICAgIGRyYWdEcm9wPzogRHJhZ0Ryb3ApIHtcclxuXHJcbiAgICAvLyBAYnJlYWtpbmctY2hhbmdlIDguMC4wIFJlbW92ZSBudWxsIGNoZWNrIG9uY2UgYGRyYWdEcm9wYCBwYXJhbWV0ZXIgaXMgbWFkZSByZXF1aXJlZC5cclxuICAgIGlmIChkcmFnRHJvcCkge1xyXG4gICAgICB0aGlzLl9kcm9wTGlzdFJlZiA9IGRyYWdEcm9wLmNyZWF0ZURyb3BMaXN0KGVsZW1lbnQpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5fZHJvcExpc3RSZWYgPSBuZXcgRHJvcExpc3RSZWYoZWxlbWVudCwgZHJhZ0Ryb3BSZWdpc3RyeSwgX2RvY3VtZW50IHx8IGRvY3VtZW50KTtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLl9kcm9wTGlzdFJlZi5kYXRhID0gdGhpcztcclxuICAgIHRoaXMuX2Ryb3BMaXN0UmVmLmVudGVyUHJlZGljYXRlID0gKGRyYWc6IERyYWdSZWY8Q2RrRHJhZz4sIGRyb3A6IERyb3BMaXN0UmVmPENka0Ryb3BMaXN0PikgPT4ge1xyXG4gICAgICByZXR1cm4gdGhpcy5lbnRlclByZWRpY2F0ZShkcmFnLmRhdGEsIGRyb3AuZGF0YSk7XHJcbiAgICB9O1xyXG5cclxuICAgIHRoaXMuX3N5bmNJbnB1dHModGhpcy5fZHJvcExpc3RSZWYpO1xyXG4gICAgdGhpcy5faGFuZGxlRXZlbnRzKHRoaXMuX2Ryb3BMaXN0UmVmKTtcclxuICAgIENka0Ryb3BMaXN0Ll9kcm9wTGlzdHMucHVzaCh0aGlzKTtcclxuXHJcbiAgICBpZiAoX2dyb3VwKSB7XHJcbiAgICAgIF9ncm91cC5faXRlbXMuYWRkKHRoaXMpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgbmdBZnRlckNvbnRlbnRJbml0KCkge1xyXG4gICAgdGhpcy5fZHJhZ2dhYmxlcy5jaGFuZ2VzXHJcbiAgICAgIC5waXBlKHN0YXJ0V2l0aCh0aGlzLl9kcmFnZ2FibGVzKSwgdGFrZVVudGlsKHRoaXMuX2Rlc3Ryb3llZCkpXHJcbiAgICAgIC5zdWJzY3JpYmUoKGl0ZW1zOiBRdWVyeUxpc3Q8Q2RrRHJhZz4pID0+IHtcclxuICAgICAgICB0aGlzLl9kcm9wTGlzdFJlZi53aXRoSXRlbXMoaXRlbXMubWFwKGRyYWcgPT4gZHJhZy5fZHJhZ1JlZikpO1xyXG4gICAgICB9KTtcclxuICB9XHJcblxyXG4gIG5nT25EZXN0cm95KCkge1xyXG4gICAgY29uc3QgaW5kZXggPSBDZGtEcm9wTGlzdC5fZHJvcExpc3RzLmluZGV4T2YodGhpcyk7XHJcblxyXG4gICAgaWYgKGluZGV4ID4gLTEpIHtcclxuICAgICAgQ2RrRHJvcExpc3QuX2Ryb3BMaXN0cy5zcGxpY2UoaW5kZXgsIDEpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLl9ncm91cCkge1xyXG4gICAgICB0aGlzLl9ncm91cC5faXRlbXMuZGVsZXRlKHRoaXMpO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuX2Ryb3BMaXN0UmVmLmRpc3Bvc2UoKTtcclxuICAgIHRoaXMuX2Rlc3Ryb3llZC5uZXh0KCk7XHJcbiAgICB0aGlzLl9kZXN0cm95ZWQuY29tcGxldGUoKTtcclxuICB9XHJcblxyXG4gIC8qKiBTdGFydHMgZHJhZ2dpbmcgYW4gaXRlbS4gKi9cclxuICBzdGFydCgpOiB2b2lkIHtcclxuICAgIHRoaXMuX2Ryb3BMaXN0UmVmLnN0YXJ0KCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBEcm9wcyBhbiBpdGVtIGludG8gdGhpcyBjb250YWluZXIuXHJcbiAgICogQHBhcmFtIGl0ZW0gSXRlbSBiZWluZyBkcm9wcGVkIGludG8gdGhlIGNvbnRhaW5lci5cclxuICAgKiBAcGFyYW0gY3VycmVudEluZGV4IEluZGV4IGF0IHdoaWNoIHRoZSBpdGVtIHNob3VsZCBiZSBpbnNlcnRlZC5cclxuICAgKiBAcGFyYW0gcHJldmlvdXNDb250YWluZXIgQ29udGFpbmVyIGZyb20gd2hpY2ggdGhlIGl0ZW0gZ290IGRyYWdnZWQgaW4uXHJcbiAgICogQHBhcmFtIGlzUG9pbnRlck92ZXJDb250YWluZXIgV2hldGhlciB0aGUgdXNlcidzIHBvaW50ZXIgd2FzIG92ZXIgdGhlXHJcbiAgICogICAgY29udGFpbmVyIHdoZW4gdGhlIGl0ZW0gd2FzIGRyb3BwZWQuXHJcbiAgICovXHJcbiAgZHJvcChpdGVtOiBDZGtEcmFnLCBjdXJyZW50SW5kZXg6IG51bWJlciwgcHJldmlvdXNDb250YWluZXI6IFBhcnRpYWw8Q2RrRHJvcExpc3RDb250YWluZXI+LFxyXG4gICAgaXNQb2ludGVyT3ZlckNvbnRhaW5lcjogYm9vbGVhbik6IHZvaWQge1xyXG4gICAgdGhpcy5fZHJvcExpc3RSZWYuZHJvcChpdGVtLl9kcmFnUmVmLCBjdXJyZW50SW5kZXgsXHJcbiAgICAgIChwcmV2aW91c0NvbnRhaW5lciBhcyBDZGtEcm9wTGlzdCkuX2Ryb3BMaXN0UmVmLCBpc1BvaW50ZXJPdmVyQ29udGFpbmVyKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEVtaXRzIGFuIGV2ZW50IHRvIGluZGljYXRlIHRoYXQgdGhlIHVzZXIgbW92ZWQgYW4gaXRlbSBpbnRvIHRoZSBjb250YWluZXIuXHJcbiAgICogQHBhcmFtIGl0ZW0gSXRlbSB0aGF0IHdhcyBtb3ZlZCBpbnRvIHRoZSBjb250YWluZXIuXHJcbiAgICogQHBhcmFtIHBvaW50ZXJYIFBvc2l0aW9uIG9mIHRoZSBpdGVtIGFsb25nIHRoZSBYIGF4aXMuXHJcbiAgICogQHBhcmFtIHBvaW50ZXJZIFBvc2l0aW9uIG9mIHRoZSBpdGVtIGFsb25nIHRoZSBZIGF4aXMuXHJcbiAgICovXHJcbiAgZW50ZXIoaXRlbTogQ2RrRHJhZywgcG9pbnRlclg6IG51bWJlciwgcG9pbnRlclk6IG51bWJlcik6IHZvaWQge1xyXG4gICAgdGhpcy5fZHJvcExpc3RSZWYuZW50ZXIoaXRlbS5fZHJhZ1JlZiwgcG9pbnRlclgsIHBvaW50ZXJZKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFJlbW92ZXMgYW4gaXRlbSBmcm9tIHRoZSBjb250YWluZXIgYWZ0ZXIgaXQgd2FzIGRyYWdnZWQgaW50byBhbm90aGVyIGNvbnRhaW5lciBieSB0aGUgdXNlci5cclxuICAgKiBAcGFyYW0gaXRlbSBJdGVtIHRoYXQgd2FzIGRyYWdnZWQgb3V0LlxyXG4gICAqL1xyXG4gIGV4aXQoaXRlbTogQ2RrRHJhZyk6IHZvaWQge1xyXG4gICAgdGhpcy5fZHJvcExpc3RSZWYuZXhpdChpdGVtLl9kcmFnUmVmKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEZpZ3VyZXMgb3V0IHRoZSBpbmRleCBvZiBhbiBpdGVtIGluIHRoZSBjb250YWluZXIuXHJcbiAgICogQHBhcmFtIGl0ZW0gSXRlbSB3aG9zZSBpbmRleCBzaG91bGQgYmUgZGV0ZXJtaW5lZC5cclxuICAgKi9cclxuICBnZXRJdGVtSW5kZXgoaXRlbTogQ2RrRHJhZyk6IG51bWJlciB7XHJcbiAgICByZXR1cm4gdGhpcy5fZHJvcExpc3RSZWYuZ2V0SXRlbUluZGV4KGl0ZW0uX2RyYWdSZWYpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogU29ydHMgYW4gaXRlbSBpbnNpZGUgdGhlIGNvbnRhaW5lciBiYXNlZCBvbiBpdHMgcG9zaXRpb24uXHJcbiAgICogQHBhcmFtIGl0ZW0gSXRlbSB0byBiZSBzb3J0ZWQuXHJcbiAgICogQHBhcmFtIHBvaW50ZXJYIFBvc2l0aW9uIG9mIHRoZSBpdGVtIGFsb25nIHRoZSBYIGF4aXMuXHJcbiAgICogQHBhcmFtIHBvaW50ZXJZIFBvc2l0aW9uIG9mIHRoZSBpdGVtIGFsb25nIHRoZSBZIGF4aXMuXHJcbiAgICogQHBhcmFtIHBvaW50ZXJEZWx0YSBEaXJlY3Rpb24gaW4gd2hpY2ggdGhlIHBvaW50ZXIgaXMgbW92aW5nIGFsb25nIGVhY2ggYXhpcy5cclxuICAgKi9cclxuICBfc29ydEl0ZW0oaXRlbTogQ2RrRHJhZywgcG9pbnRlclg6IG51bWJlciwgcG9pbnRlclk6IG51bWJlcixcclxuICAgICAgICAgICAgcG9pbnRlckRlbHRhOiB7eDogbnVtYmVyLCB5OiBudW1iZXJ9KTogdm9pZCB7XHJcbiAgICByZXR1cm4gdGhpcy5fZHJvcExpc3RSZWYuX3NvcnRJdGVtKGl0ZW0uX2RyYWdSZWYsIHBvaW50ZXJYLCBwb2ludGVyWSwgcG9pbnRlckRlbHRhKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEZpZ3VyZXMgb3V0IHdoZXRoZXIgYW4gaXRlbSBzaG91bGQgYmUgbW92ZWQgaW50byBhIHNpYmxpbmdcclxuICAgKiBkcm9wIGNvbnRhaW5lciwgYmFzZWQgb24gaXRzIGN1cnJlbnQgcG9zaXRpb24uXHJcbiAgICogQHBhcmFtIGl0ZW0gRHJhZyBpdGVtIHRoYXQgaXMgYmVpbmcgbW92ZWQuXHJcbiAgICogQHBhcmFtIHggUG9zaXRpb24gb2YgdGhlIGl0ZW0gYWxvbmcgdGhlIFggYXhpcy5cclxuICAgKiBAcGFyYW0geSBQb3NpdGlvbiBvZiB0aGUgaXRlbSBhbG9uZyB0aGUgWSBheGlzLlxyXG4gICAqL1xyXG4gIF9nZXRTaWJsaW5nQ29udGFpbmVyRnJvbVBvc2l0aW9uKGl0ZW06IENka0RyYWcsIHg6IG51bWJlciwgeTogbnVtYmVyKTpcclxuICAgIENka0Ryb3BMaXN0Q29udGFpbmVyIHwgbnVsbCB7XHJcbiAgICBjb25zdCByZXN1bHQgPSB0aGlzLl9kcm9wTGlzdFJlZi5fZ2V0U2libGluZ0NvbnRhaW5lckZyb21Qb3NpdGlvbihpdGVtLl9kcmFnUmVmLCB4LCB5KTtcclxuICAgIHJldHVybiByZXN1bHQgPyByZXN1bHQuZGF0YSA6IG51bGw7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDaGVja3Mgd2hldGhlciB0aGUgdXNlcidzIHBvaW50ZXIgaXMgcG9zaXRpb25lZCBvdmVyIHRoZSBjb250YWluZXIuXHJcbiAgICogQHBhcmFtIHggUG9pbnRlciBwb3NpdGlvbiBhbG9uZyB0aGUgWCBheGlzLlxyXG4gICAqIEBwYXJhbSB5IFBvaW50ZXIgcG9zaXRpb24gYWxvbmcgdGhlIFkgYXhpcy5cclxuICAgKi9cclxuICBfaXNPdmVyQ29udGFpbmVyKHg6IG51bWJlciwgeTogbnVtYmVyKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gdGhpcy5fZHJvcExpc3RSZWYuX2lzT3ZlckNvbnRhaW5lcih4LCB5KTtcclxuICB9XHJcblxyXG4gIC8qKiBTeW5jcyB0aGUgaW5wdXRzIG9mIHRoZSBDZGtEcm9wTGlzdCB3aXRoIHRoZSBvcHRpb25zIG9mIHRoZSB1bmRlcmx5aW5nIERyb3BMaXN0UmVmLiAqL1xyXG4gIHByaXZhdGUgX3N5bmNJbnB1dHMocmVmOiBEcm9wTGlzdFJlZjxDZGtEcm9wTGlzdD4pIHtcclxuICAgIGlmICh0aGlzLl9kaXIpIHtcclxuICAgICAgdGhpcy5fZGlyLmNoYW5nZVxyXG4gICAgICAgIC5waXBlKHN0YXJ0V2l0aCh0aGlzLl9kaXIudmFsdWUpLCB0YWtlVW50aWwodGhpcy5fZGVzdHJveWVkKSlcclxuICAgICAgICAuc3Vic2NyaWJlKHZhbHVlID0+IHJlZi53aXRoRGlyZWN0aW9uKHZhbHVlKSk7XHJcbiAgICB9XHJcblxyXG4gICAgcmVmLmJlZm9yZVN0YXJ0ZWQuc3Vic2NyaWJlKCgpID0+IHtcclxuICAgICAgY29uc3Qgc2libGluZ3MgPSBjb2VyY2VBcnJheSh0aGlzLmNvbm5lY3RlZFRvKS5tYXAoZHJvcCA9PiB7XHJcbiAgICAgICAgcmV0dXJuIHR5cGVvZiBkcm9wID09PSAnc3RyaW5nJyA/XHJcbiAgICAgICAgICAgIENka0Ryb3BMaXN0Ll9kcm9wTGlzdHMuZmluZChsaXN0ID0+IGxpc3QuaWQgPT09IGRyb3ApISA6IGRyb3A7XHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgaWYgKHRoaXMuX2dyb3VwKSB7XHJcbiAgICAgICAgdGhpcy5fZ3JvdXAuX2l0ZW1zLmZvckVhY2goZHJvcCA9PiB7XHJcbiAgICAgICAgICBpZiAoc2libGluZ3MuaW5kZXhPZihkcm9wKSA9PT0gLTEpIHtcclxuICAgICAgICAgICAgc2libGluZ3MucHVzaChkcm9wKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmVmLmxvY2tBeGlzID0gdGhpcy5sb2NrQXhpcztcclxuICAgICAgcmVmXHJcbiAgICAgICAgLmNvbm5lY3RlZFRvKHNpYmxpbmdzLmZpbHRlcihkcm9wID0+IGRyb3AgJiYgZHJvcCAhPT0gdGhpcykubWFwKGxpc3QgPT4gbGlzdC5fZHJvcExpc3RSZWYpKVxyXG4gICAgICAgIC53aXRoT3JpZW50YXRpb24odGhpcy5vcmllbnRhdGlvbik7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKiBIYW5kbGVzIGV2ZW50cyBmcm9tIHRoZSB1bmRlcmx5aW5nIERyb3BMaXN0UmVmLiAqL1xyXG4gIHByaXZhdGUgX2hhbmRsZUV2ZW50cyhyZWY6IERyb3BMaXN0UmVmPENka0Ryb3BMaXN0Pikge1xyXG4gICAgcmVmLmJlZm9yZVN0YXJ0ZWQuc3Vic2NyaWJlKCgpID0+IHtcclxuICAgICAgdGhpcy5fY2hhbmdlRGV0ZWN0b3JSZWYubWFya0ZvckNoZWNrKCk7XHJcbiAgICB9KTtcclxuXHJcbiAgICByZWYuZW50ZXJlZC5zdWJzY3JpYmUoZXZlbnQgPT4ge1xyXG4gICAgICB0aGlzLmVudGVyZWQuZW1pdCh7XHJcbiAgICAgICAgY29udGFpbmVyOiB0aGlzLFxyXG4gICAgICAgIGl0ZW06IGV2ZW50Lml0ZW0uZGF0YVxyXG4gICAgICB9KTtcclxuICAgIH0pO1xyXG5cclxuICAgIHJlZi5leGl0ZWQuc3Vic2NyaWJlKGV2ZW50ID0+IHtcclxuICAgICAgdGhpcy5leGl0ZWQuZW1pdCh7XHJcbiAgICAgICAgY29udGFpbmVyOiB0aGlzLFxyXG4gICAgICAgIGl0ZW06IGV2ZW50Lml0ZW0uZGF0YVxyXG4gICAgICB9KTtcclxuICAgIH0pO1xyXG5cclxuICAgIHJlZi5zb3J0ZWQuc3Vic2NyaWJlKGV2ZW50ID0+IHtcclxuICAgICAgdGhpcy5zb3J0ZWQuZW1pdCh7XHJcbiAgICAgICAgcHJldmlvdXNJbmRleDogZXZlbnQucHJldmlvdXNJbmRleCxcclxuICAgICAgICBjdXJyZW50SW5kZXg6IGV2ZW50LmN1cnJlbnRJbmRleCxcclxuICAgICAgICBjb250YWluZXI6IHRoaXMsXHJcbiAgICAgICAgaXRlbTogZXZlbnQuaXRlbS5kYXRhXHJcbiAgICAgIH0pO1xyXG4gICAgfSk7XHJcblxyXG4gICAgcmVmLmRyb3BwZWQuc3Vic2NyaWJlKGV2ZW50ID0+IHtcclxuICAgICAgdGhpcy5kcm9wcGVkLmVtaXQoe1xyXG4gICAgICAgIHByZXZpb3VzSW5kZXg6IGV2ZW50LnByZXZpb3VzSW5kZXgsXHJcbiAgICAgICAgY3VycmVudEluZGV4OiBldmVudC5jdXJyZW50SW5kZXgsXHJcbiAgICAgICAgcHJldmlvdXNDb250YWluZXI6IGV2ZW50LnByZXZpb3VzQ29udGFpbmVyLmRhdGEsXHJcbiAgICAgICAgY29udGFpbmVyOiBldmVudC5jb250YWluZXIuZGF0YSxcclxuICAgICAgICBpdGVtOiBldmVudC5pdGVtLmRhdGEsXHJcbiAgICAgICAgaXNQb2ludGVyT3ZlckNvbnRhaW5lcjogZXZlbnQuaXNQb2ludGVyT3ZlckNvbnRhaW5lclxyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIC8vIE1hcmsgZm9yIGNoZWNrIHNpbmNlIGFsbCBvZiB0aGVzZSBldmVudHMgcnVuIG91dHNpZGUgb2YgY2hhbmdlXHJcbiAgICAgIC8vIGRldGVjdGlvbiBhbmQgd2UncmUgbm90IGd1YXJhbnRlZWQgZm9yIHNvbWV0aGluZyBlbHNlIHRvIGhhdmUgdHJpZ2dlcmVkIGl0LlxyXG4gICAgICB0aGlzLl9jaGFuZ2VEZXRlY3RvclJlZi5tYXJrRm9yQ2hlY2soKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbn1cclxuIl19