ngx-pluto
Version:
407 lines • 31.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 { Injectable, NgZone, Inject } from '@angular/core';
import { DOCUMENT } from '@angular/common';
import { Subject } from 'rxjs';
import { normalizePassiveListenerOptions } from './utils/passive-listeners';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
/**
* Event options that can be used to bind an active, capturing event.
* @type {?}
*/
var activeCapturingEventOptions = normalizePassiveListenerOptions({
passive: false,
capture: true
});
/**
* @ignore
* Service that keeps track of all the drag item and drop container
* instances, and manages global event listeners on the `document`.
* \@docs-private
* @template I, C
*/
// Note: this class is generic, rather than referencing CdkDrag and CdkDropList directly, in order
// to avoid circular imports. If we were to reference them here, importing the registry into the
// classes that are registering themselves will introduce a circular import.
var DragDropRegistry = /** @class */ (function () {
function DragDropRegistry(_ngZone, _document) {
var _this = this;
this._ngZone = _ngZone;
/**
* Registered drop container instances.
*/
this._dropInstances = new Set();
/**
* Registered drag item instances.
*/
this._dragInstances = new Set();
/**
* Drag item instances that are currently being dragged.
*/
this._activeDragInstances = new Set();
/**
* Keeps track of the event listeners that we've bound to the `document`.
*/
this._globalListeners = new Map();
/**
* Emits the `touchmove` or `mousemove` events that are dispatched
* while the user is dragging a drag item instance.
*/
this.pointerMove = new Subject();
/**
* Emits the `touchend` or `mouseup` events that are dispatched
* while the user is dragging a drag item instance.
*/
this.pointerUp = new Subject();
/**
* Event listener that will prevent the default browser action while the user is dragging.
* @param event Event whose default action should be prevented.
*/
this._preventDefaultWhileDragging = (/**
* @param {?} event
* @return {?}
*/
function (event) {
if (_this._activeDragInstances.size) {
event.preventDefault();
}
});
this._document = _document;
}
/** Adds a drop container to the registry. */
/**
* Adds a drop container to the registry.
* @param {?} drop
* @return {?}
*/
DragDropRegistry.prototype.registerDropContainer = /**
* Adds a drop container to the registry.
* @param {?} drop
* @return {?}
*/
function (drop) {
if (!this._dropInstances.has(drop)) {
if (this.getDropContainer(drop.id)) {
throw Error("Drop instance with id \"" + drop.id + "\" has already been registered.");
}
this._dropInstances.add(drop);
}
};
/** Adds a drag item instance to the registry. */
/**
* Adds a drag item instance to the registry.
* @param {?} drag
* @return {?}
*/
DragDropRegistry.prototype.registerDragItem = /**
* Adds a drag item instance to the registry.
* @param {?} drag
* @return {?}
*/
function (drag) {
var _this = this;
this._dragInstances.add(drag);
// The `touchmove` event gets bound once, ahead of time, because WebKit
// won't preventDefault on a dynamically-added `touchmove` listener.
// See https://bugs.webkit.org/show_bug.cgi?id=184250.
if (this._dragInstances.size === 1) {
this._ngZone.runOutsideAngular((/**
* @return {?}
*/
function () {
// The event handler has to be explicitly active,
// because newer browsers make it passive by default.
_this._document.addEventListener('touchmove', _this._preventDefaultWhileDragging, activeCapturingEventOptions);
}));
}
};
/** Removes a drop container from the registry. */
/**
* Removes a drop container from the registry.
* @param {?} drop
* @return {?}
*/
DragDropRegistry.prototype.removeDropContainer = /**
* Removes a drop container from the registry.
* @param {?} drop
* @return {?}
*/
function (drop) {
this._dropInstances.delete(drop);
};
/** Removes a drag item instance from the registry. */
/**
* Removes a drag item instance from the registry.
* @param {?} drag
* @return {?}
*/
DragDropRegistry.prototype.removeDragItem = /**
* Removes a drag item instance from the registry.
* @param {?} drag
* @return {?}
*/
function (drag) {
this._dragInstances.delete(drag);
this.stopDragging(drag);
if (this._dragInstances.size === 0) {
this._document.removeEventListener('touchmove', this._preventDefaultWhileDragging, activeCapturingEventOptions);
}
};
/**
* Starts the dragging sequence for a drag instance.
* @param drag Drag instance which is being dragged.
* @param event Event that initiated the dragging.
*/
/**
* Starts the dragging sequence for a drag instance.
* @param {?} drag Drag instance which is being dragged.
* @param {?} event Event that initiated the dragging.
* @return {?}
*/
DragDropRegistry.prototype.startDragging = /**
* Starts the dragging sequence for a drag instance.
* @param {?} drag Drag instance which is being dragged.
* @param {?} event Event that initiated the dragging.
* @return {?}
*/
function (drag, event) {
var _this = this;
this._activeDragInstances.add(drag);
if (this._activeDragInstances.size === 1) {
/** @type {?} */
var isTouchEvent = event.type.startsWith('touch');
/** @type {?} */
var moveEvent = isTouchEvent ? 'touchmove' : 'mousemove';
/** @type {?} */
var upEvent = isTouchEvent ? 'touchend' : 'mouseup';
// We explicitly bind __active__ listeners here, because newer browsers will default to
// passive ones for `mousemove` and `touchmove`. The events need to be active, because we
// use `preventDefault` to prevent the page from scrolling while the user is dragging.
this._globalListeners
.set(moveEvent, {
handler: (/**
* @param {?} e
* @return {?}
*/
function (e) { return _this.pointerMove.next((/** @type {?} */ (e))); }),
options: activeCapturingEventOptions
})
.set(upEvent, {
handler: (/**
* @param {?} e
* @return {?}
*/
function (e) { return _this.pointerUp.next((/** @type {?} */ (e))); }),
options: true
})
// Preventing the default action on `mousemove` isn't enough to disable text selection
// on Safari so we need to prevent the selection event as well. Alternatively this can
// be done by setting `user-select: none` on the `body`, however it has causes a style
// recalculation which can be expensive on pages with a lot of elements.
.set('selectstart', {
handler: this._preventDefaultWhileDragging,
options: activeCapturingEventOptions
});
// TODO(crisbeto): prevent mouse wheel scrolling while
// dragging until we've set up proper scroll handling.
if (!isTouchEvent) {
this._globalListeners.set('wheel', {
handler: this._preventDefaultWhileDragging,
options: activeCapturingEventOptions
});
}
this._ngZone.runOutsideAngular((/**
* @return {?}
*/
function () {
_this._globalListeners.forEach((/**
* @param {?} config
* @param {?} name
* @return {?}
*/
function (config, name) {
_this._document.addEventListener(name, config.handler, config.options);
}));
}));
}
};
/** Stops dragging a drag item instance. */
/**
* Stops dragging a drag item instance.
* @param {?} drag
* @return {?}
*/
DragDropRegistry.prototype.stopDragging = /**
* Stops dragging a drag item instance.
* @param {?} drag
* @return {?}
*/
function (drag) {
this._activeDragInstances.delete(drag);
if (this._activeDragInstances.size === 0) {
this._clearGlobalListeners();
}
};
/** Gets whether a drag item instance is currently being dragged. */
/**
* Gets whether a drag item instance is currently being dragged.
* @param {?} drag
* @return {?}
*/
DragDropRegistry.prototype.isDragging = /**
* Gets whether a drag item instance is currently being dragged.
* @param {?} drag
* @return {?}
*/
function (drag) {
return this._activeDragInstances.has(drag);
};
/**
* Gets a drop container by its id.
* @deprecated No longer being used. To be removed.
* @breaking-change 8.0.0
*/
/**
* Gets a drop container by its id.
* @deprecated No longer being used. To be removed.
* \@breaking-change 8.0.0
* @param {?} id
* @return {?}
*/
DragDropRegistry.prototype.getDropContainer = /**
* Gets a drop container by its id.
* @deprecated No longer being used. To be removed.
* \@breaking-change 8.0.0
* @param {?} id
* @return {?}
*/
function (id) {
return Array.from(this._dropInstances).find((/**
* @param {?} instance
* @return {?}
*/
function (instance) { return instance.id === id; }));
};
/**
* @return {?}
*/
DragDropRegistry.prototype.ngOnDestroy = /**
* @return {?}
*/
function () {
var _this = this;
this._dragInstances.forEach((/**
* @param {?} instance
* @return {?}
*/
function (instance) { return _this.removeDragItem(instance); }));
this._dropInstances.forEach((/**
* @param {?} instance
* @return {?}
*/
function (instance) { return _this.removeDropContainer(instance); }));
this._clearGlobalListeners();
this.pointerMove.complete();
this.pointerUp.complete();
};
/** Clears out the global event listeners from the `document`. */
/**
* Clears out the global event listeners from the `document`.
* @private
* @return {?}
*/
DragDropRegistry.prototype._clearGlobalListeners = /**
* Clears out the global event listeners from the `document`.
* @private
* @return {?}
*/
function () {
var _this = this;
this._globalListeners.forEach((/**
* @param {?} config
* @param {?} name
* @return {?}
*/
function (config, name) {
_this._document.removeEventListener(name, config.handler, config.options);
}));
this._globalListeners.clear();
};
DragDropRegistry.decorators = [
{ type: Injectable, args: [{ providedIn: 'root' },] }
];
/** @nocollapse */
DragDropRegistry.ctorParameters = function () { return [
{ type: NgZone },
{ type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] }
]; };
/** @nocollapse */ DragDropRegistry.ngInjectableDef = i0.defineInjectable({ factory: function DragDropRegistry_Factory() { return new DragDropRegistry(i0.inject(i0.NgZone), i0.inject(i1.DOCUMENT)); }, token: DragDropRegistry, providedIn: "root" });
return DragDropRegistry;
}());
export { DragDropRegistry };
if (false) {
/**
* @type {?}
* @private
*/
DragDropRegistry.prototype._document;
/**
* Registered drop container instances.
* @type {?}
* @private
*/
DragDropRegistry.prototype._dropInstances;
/**
* Registered drag item instances.
* @type {?}
* @private
*/
DragDropRegistry.prototype._dragInstances;
/**
* Drag item instances that are currently being dragged.
* @type {?}
* @private
*/
DragDropRegistry.prototype._activeDragInstances;
/**
* Keeps track of the event listeners that we've bound to the `document`.
* @type {?}
* @private
*/
DragDropRegistry.prototype._globalListeners;
/**
* Emits the `touchmove` or `mousemove` events that are dispatched
* while the user is dragging a drag item instance.
* @type {?}
*/
DragDropRegistry.prototype.pointerMove;
/**
* Emits the `touchend` or `mouseup` events that are dispatched
* while the user is dragging a drag item instance.
* @type {?}
*/
DragDropRegistry.prototype.pointerUp;
/**
* Event listener that will prevent the default browser action while the user is dragging.
* \@param event Event whose default action should be prevented.
* @type {?}
* @private
*/
DragDropRegistry.prototype._preventDefaultWhileDragging;
/**
* @type {?}
* @private
*/
DragDropRegistry.prototype._ngZone;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHJhZy1kcm9wLXJlZ2lzdHJ5LmpzIiwic291cmNlUm9vdCI6Im5nOi8vbmd4LXBsdXRvLyIsInNvdXJjZXMiOlsibGliL2RyYWctZHJvcC9kcmFnLWRyb3AtcmVnaXN0cnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7QUFRQSxPQUFPLEVBQUMsVUFBVSxFQUFFLE1BQU0sRUFBYSxNQUFNLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFDcEUsT0FBTyxFQUFDLFFBQVEsRUFBQyxNQUFNLGlCQUFpQixDQUFDO0FBQ3pDLE9BQU8sRUFBQyxPQUFPLEVBQUMsTUFBTSxNQUFNLENBQUM7QUFDN0IsT0FBTyxFQUFFLCtCQUErQixFQUFFLE1BQU0sMkJBQTJCLENBQUM7Ozs7Ozs7SUFHdEUsMkJBQTJCLEdBQUcsK0JBQStCLENBQUM7SUFDbEUsT0FBTyxFQUFFLEtBQUs7SUFDZCxPQUFPLEVBQUUsSUFBSTtDQUNkLENBQUM7Ozs7Ozs7Ozs7O0FBV0Y7SUErQkUsMEJBQ1UsT0FBZSxFQUNMLFNBQWM7UUFGbEMsaUJBSUM7UUFIUyxZQUFPLEdBQVAsT0FBTyxDQUFROzs7O1FBM0JqQixtQkFBYyxHQUFHLElBQUksR0FBRyxFQUFLLENBQUM7Ozs7UUFHOUIsbUJBQWMsR0FBRyxJQUFJLEdBQUcsRUFBSyxDQUFDOzs7O1FBRzlCLHlCQUFvQixHQUFHLElBQUksR0FBRyxFQUFLLENBQUM7Ozs7UUFHcEMscUJBQWdCLEdBQUcsSUFBSSxHQUFHLEVBRzlCLENBQUM7Ozs7O1FBTUksZ0JBQVcsR0FBcUMsSUFBSSxPQUFPLEVBQTJCLENBQUM7Ozs7O1FBTXZGLGNBQVMsR0FBcUMsSUFBSSxPQUFPLEVBQTJCLENBQUM7Ozs7O1FBMEl0RixpQ0FBNEI7Ozs7UUFBRyxVQUFDLEtBQVk7WUFDbEQsSUFBSSxLQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxFQUFFO2dCQUNsQyxLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7YUFDeEI7UUFDSCxDQUFDLEVBQUE7UUF6SUMs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Q0FBQyxDQUFDO1FBQzNFLENBQUMsRUFBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEtBQUssRUFBRSxDQUFDO0lBQ2hDLENBQUM7O2dCQXBMRixVQUFVLFNBQUMsRUFBQyxVQUFVLEVBQUUsTUFBTSxFQUFDOzs7O2dCQXBCWixNQUFNO2dEQXFEckIsTUFBTSxTQUFDLFFBQVE7OzsyQkE3RHBCO0NBaU5DLEFBckxELElBcUxDO1NBcExZLGdCQUFnQjs7Ozs7O0lBQzNCLHFDQUE0Qjs7Ozs7O0lBRzVCLDBDQUFzQzs7Ozs7O0lBR3RDLDBDQUFzQzs7Ozs7O0lBR3RDLGdEQUE0Qzs7Ozs7O0lBRzVDLDRDQUdLOzs7Ozs7SUFNTCx1Q0FBZ0c7Ozs7OztJQU1oRyxxQ0FBOEY7Ozs7Ozs7SUEwSTlGLHdEQUlDOzs7OztJQTNJQyxtQ0FBdUIiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcclxuICogQGxpY2Vuc2VcclxuICogQ29weXJpZ2h0IEdvb2dsZSBMTEMgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cclxuICpcclxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcclxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxyXG4gKi9cclxuXHJcbmltcG9ydCB7SW5qZWN0YWJsZSwgTmdab25lLCBPbkRlc3Ryb3ksIEluamVjdH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7RE9DVU1FTlR9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XHJcbmltcG9ydCB7U3ViamVjdH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IG5vcm1hbGl6ZVBhc3NpdmVMaXN0ZW5lck9wdGlvbnMgfSBmcm9tICcuL3V0aWxzL3Bhc3NpdmUtbGlzdGVuZXJzJztcclxuXHJcbi8qKiBFdmVudCBvcHRpb25zIHRoYXQgY2FuIGJlIHVzZWQgdG8gYmluZCBhbiBhY3RpdmUsIGNhcHR1cmluZyBldmVudC4gKi9cclxuY29uc3QgYWN0aXZlQ2FwdHVyaW5nRXZlbnRPcHRpb25zID0gbm9ybWFsaXplUGFzc2l2ZUxpc3RlbmVyT3B0aW9ucyh7XHJcbiAgcGFzc2l2ZTogZmFsc2UsXHJcbiAgY2FwdHVyZTogdHJ1ZVxyXG59KTtcclxuXHJcbi8qKlxyXG4gKiBAaWdub3JlXHJcbiAqIFNlcnZpY2UgdGhhdCBrZWVwcyB0cmFjayBvZiBhbGwgdGhlIGRyYWcgaXRlbSBhbmQgZHJvcCBjb250YWluZXJcclxuICogaW5zdGFuY2VzLCBhbmQgbWFuYWdlcyBnbG9iYWwgZXZlbnQgbGlzdGVuZXJzIG9uIHRoZSBgZG9jdW1lbnRgLlxyXG4gKiBAZG9jcy1wcml2YXRlXHJcbiAqL1xyXG4vLyBOb3RlOiB0aGlzIGNsYXNzIGlzIGdlbmVyaWMsIHJhdGhlciB0aGFuIHJlZmVyZW5jaW5nIENka0RyYWcgYW5kIENka0Ryb3BMaXN0IGRpcmVjdGx5LCBpbiBvcmRlclxyXG4vLyB0byBhdm9pZCBjaXJjdWxhciBpbXBvcnRzLiBJZiB3ZSB3ZXJlIHRvIHJlZmVyZW5jZSB0aGVtIGhlcmUsIGltcG9ydGluZyB0aGUgcmVnaXN0cnkgaW50byB0aGVcclxuLy8gY2xhc3NlcyB0aGF0IGFyZSByZWdpc3RlcmluZyB0aGVtc2VsdmVzIHdpbGwgaW50cm9kdWNlIGEgY2lyY3VsYXIgaW1wb3J0LlxyXG5ASW5qZWN0YWJsZSh7cHJvdmlkZWRJbjogJ3Jvb3QnfSlcclxuZXhwb3J0IGNsYXNzIERyYWdEcm9wUmVnaXN0cnk8SSwgQyBleHRlbmRzIHtpZDogc3RyaW5nfT4gaW1wbGVtZW50cyBPbkRlc3Ryb3kge1xyXG4gIHByaXZhdGUgX2RvY3VtZW50OiBEb2N1bWVudDtcclxuXHJcbiAgLyoqIFJlZ2lzdGVyZWQgZHJvcCBjb250YWluZXIgaW5zdGFuY2VzLiAqL1xyXG4gIHByaXZhdGUgX2Ryb3BJbnN0YW5jZXMgPSBuZXcgU2V0PEM+KCk7XHJcblxyXG4gIC8qKiBSZWdpc3RlcmVkIGRyYWcgaXRlbSBpbnN0YW5jZXMuICovXHJcbiAgcHJpdmF0ZSBfZHJhZ0luc3RhbmNlcyA9IG5ldyBTZXQ8ST4oKTtcclxuXHJcbiAgLyoqIERyYWcgaXRlbSBpbnN0YW5jZXMgdGhhdCBhcmUgY3VycmVudGx5IGJlaW5nIGRyYWdnZWQuICovXHJcbiAgcHJpdmF0ZSBfYWN0aXZlRHJhZ0luc3RhbmNlcyA9IG5ldyBTZXQ8ST4oKTtcclxuXHJcbiAgLyoqIEtlZXBzIHRyYWNrIG9mIHRoZSBldmVudCBsaXN0ZW5lcnMgdGhhdCB3ZSd2ZSBib3VuZCB0byB0aGUgYGRvY3VtZW50YC4gKi9cclxuICBwcml2YXRlIF9nbG9iYWxMaXN0ZW5lcnMgPSBuZXcgTWFwPHN0cmluZywge1xyXG4gICAgaGFuZGxlcjogKGV2ZW50OiBFdmVudCkgPT4gdm9pZCxcclxuICAgIG9wdGlvbnM/OiBBZGRFdmVudExpc3RlbmVyT3B0aW9ucyB8IGJvb2xlYW5cclxuICB9PigpO1xyXG5cclxuICAvKipcclxuICAgKiBFbWl0cyB0aGUgYHRvdWNobW92ZWAgb3IgYG1vdXNlbW92ZWAgZXZlbnRzIHRoYXQgYXJlIGRpc3BhdGNoZWRcclxuICAgKiB3aGlsZSB0aGUgdXNlciBpcyBkcmFnZ2luZyBhIGRyYWcgaXRlbSBpbnN0YW5jZS5cclxuICAgKi9cclxuICByZWFkb25seSBwb2ludGVyTW92ZTogU3ViamVjdDxUb3VjaEV2ZW50IHwgTW91c2VFdmVudD4gPSBuZXcgU3ViamVjdDxUb3VjaEV2ZW50IHwgTW91c2VFdmVudD4oKTtcclxuXHJcbiAgLyoqXHJcbiAgICogRW1pdHMgdGhlIGB0b3VjaGVuZGAgb3IgYG1vdXNldXBgIGV2ZW50cyB0aGF0IGFyZSBkaXNwYXRjaGVkXHJcbiAgICogd2hpbGUgdGhlIHVzZXIgaXMgZHJhZ2dpbmcgYSBkcmFnIGl0ZW0gaW5zdGFuY2UuXHJcbiAgICovXHJcbiAgcmVhZG9ubHkgcG9pbnRlclVwOiBTdWJqZWN0PFRvdWNoRXZlbnQgfCBNb3VzZUV2ZW50PiA9IG5ldyBTdWJqZWN0PFRvdWNoRXZlbnQgfCBNb3VzZUV2ZW50PigpO1xyXG5cclxuICBjb25zdHJ1Y3RvcihcclxuICAgIHByaXZhdGUgX25nWm9uZTogTmdab25lLFxyXG4gICAgQEluamVjdChET0NVTUVOVCkgX2RvY3VtZW50OiBhbnkpIHtcclxuICAgIHRoaXMuX2RvY3VtZW50ID0gX2RvY3VtZW50O1xyXG4gIH1cclxuXHJcbiAgLyoqIEFkZHMgYSBkcm9wIGNvbnRhaW5lciB0byB0aGUgcmVnaXN0cnkuICovXHJcbiAgcmVnaXN0ZXJEcm9wQ29udGFpbmVyKGRyb3A6IEMpIHtcclxuICAgIGlmICghdGhpcy5fZHJvcEluc3RhbmNlcy5oYXMoZHJvcCkpIHtcclxuICAgICAgaWYgKHRoaXMuZ2V0RHJvcENvbnRhaW5lcihkcm9wLmlkKSkge1xyXG4gICAgICAgIHRocm93IEVycm9yKGBEcm9wIGluc3RhbmNlIHdpdGggaWQgXCIke2Ryb3AuaWR9XCIgaGFzIGFscmVhZHkgYmVlbiByZWdpc3RlcmVkLmApO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB0aGlzLl9kcm9wSW5zdGFuY2VzLmFkZChkcm9wKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKiBBZGRzIGEgZHJhZyBpdGVtIGluc3RhbmNlIHRvIHRoZSByZWdpc3RyeS4gKi9cclxuICByZWdpc3RlckRyYWdJdGVtKGRyYWc6IEkpIHtcclxuICAgIHRoaXMuX2RyYWdJbnN0YW5jZXMuYWRkKGRyYWcpO1xyXG5cclxuICAgIC8vIFRoZSBgdG91Y2htb3ZlYCBldmVudCBnZXRzIGJvdW5kIG9uY2UsIGFoZWFkIG9mIHRpbWUsIGJlY2F1c2UgV2ViS2l0XHJcbiAgICAvLyB3b24ndCBwcmV2ZW50RGVmYXVsdCBvbiBhIGR5bmFtaWNhbGx5LWFkZGVkIGB0b3VjaG1vdmVgIGxpc3RlbmVyLlxyXG4gICAgLy8gU2VlIGh0dHBzOi8vYnVncy53ZWJraXQub3JnL3Nob3dfYnVnLmNnaT9pZD0xODQyNTAuXHJcbiAgICBpZiAodGhpcy5fZHJhZ0luc3RhbmNlcy5zaXplID09PSAxKSB7XHJcbiAgICAgIHRoaXMuX25nWm9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XHJcbiAgICAgICAgLy8gVGhlIGV2ZW50IGhhbmRsZXIgaGFzIHRvIGJlIGV4cGxpY2l0bHkgYWN0aXZlLFxyXG4gICAgICAgIC8vIGJlY2F1c2UgbmV3ZXIgYnJvd3NlcnMgbWFrZSBpdCBwYXNzaXZlIGJ5IGRlZmF1bHQuXHJcbiAgICAgICAgdGhpcy5fZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2htb3ZlJywgdGhpcy5fcHJldmVudERlZmF1bHRXaGlsZURyYWdnaW5nLFxyXG4gICAgICAgICAgICBhY3RpdmVDYXB0dXJpbmdFdmVudE9wdGlvbnMpO1xyXG4gICAgICB9KTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKiBSZW1vdmVzIGEgZHJvcCBjb250YWluZXIgZnJvbSB0aGUgcmVnaXN0cnkuICovXHJcbiAgcmVtb3ZlRHJvcENvbnRhaW5lcihkcm9wOiBDKSB7XHJcbiAgICB0aGlzLl9kcm9wSW5zdGFuY2VzLmRlbGV0ZShkcm9wKTtcclxuICB9XHJcblxyXG4gIC8qKiBSZW1vdmVzIGEgZHJhZyBpdGVtIGluc3RhbmNlIGZyb20gdGhlIHJlZ2lzdHJ5LiAqL1xyXG4gIHJlbW92ZURyYWdJdGVtKGRyYWc6IEkpIHtcclxuICAgIHRoaXMuX2RyYWdJbnN0YW5jZXMuZGVsZXRlKGRyYWcpO1xyXG4gICAgdGhpcy5zdG9wRHJhZ2dpbmcoZHJhZyk7XHJcblxyXG4gICAgaWYgKHRoaXMuX2RyYWdJbnN0YW5jZXMuc2l6ZSA9PT0gMCkge1xyXG4gICAgICB0aGlzLl9kb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCd0b3VjaG1vdmUnLCB0aGlzLl9wcmV2ZW50RGVmYXVsdFdoaWxlRHJhZ2dpbmcsXHJcbiAgICAgICAgICBhY3RpdmVDYXB0dXJpbmdFdmVudE9wdGlvbnMpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogU3RhcnRzIHRoZSBkcmFnZ2luZyBzZXF1ZW5jZSBmb3IgYSBkcmFnIGluc3RhbmNlLlxyXG4gICAqIEBwYXJhbSBkcmFnIERyYWcgaW5zdGFuY2Ugd2hpY2ggaXMgYmVpbmcgZHJhZ2dlZC5cclxuICAgKiBAcGFyYW0gZXZlbnQgRXZlbnQgdGhhdCBpbml0aWF0ZWQgdGhlIGRyYWdnaW5nLlxyXG4gICAqL1xyXG4gIHN0YXJ0RHJhZ2dpbmcoZHJhZzogSSwgZXZlbnQ6IFRvdWNoRXZlbnQgfCBNb3VzZUV2ZW50KSB7XHJcbiAgICB0aGlzLl9hY3RpdmVEcmFnSW5zdGFuY2VzLmFkZChkcmFnKTtcclxuXHJcbiAgICBpZiAodGhpcy5fYWN0aXZlRHJhZ0luc3RhbmNlcy5zaXplID09PSAxKSB7XHJcbiAgICAgIGNvbnN0IGlzVG91Y2hFdmVudCA9IGV2ZW50LnR5cGUuc3RhcnRzV2l0aCgndG91Y2gnKTtcclxuICAgICAgY29uc3QgbW92ZUV2ZW50ID0gaXNUb3VjaEV2ZW50ID8gJ3RvdWNobW92ZScgOiAnbW91c2Vtb3ZlJztcclxuICAgICAgY29uc3QgdXBFdmVudCA9IGlzVG91Y2hFdmVudCA/ICd0b3VjaGVuZCcgOiAnbW91c2V1cCc7XHJcblxyXG4gICAgICAvLyBXZSBleHBsaWNpdGx5IGJpbmQgX19hY3RpdmVfXyBsaXN0ZW5lcnMgaGVyZSwgYmVjYXVzZSBuZXdlciBicm93c2VycyB3aWxsIGRlZmF1bHQgdG9cclxuICAgICAgLy8gcGFzc2l2ZSBvbmVzIGZvciBgbW91c2Vtb3ZlYCBhbmQgYHRvdWNobW92ZWAuIFRoZSBldmVudHMgbmVlZCB0byBiZSBhY3RpdmUsIGJlY2F1c2Ugd2VcclxuICAgICAgLy8gdXNlIGBwcmV2ZW50RGVmYXVsdGAgdG8gcHJldmVudCB0aGUgcGFnZSBmcm9tIHNjcm9sbGluZyB3aGlsZSB0aGUgdXNlciBpcyBkcmFnZ2luZy5cclxuICAgICAgdGhpcy5fZ2xvYmFsTGlzdGVuZXJzXHJcbiAgICAgICAgLnNldChtb3ZlRXZlbnQsIHtcclxuICAgICAgICAgIGhhbmRsZXI6IChlOiBFdmVudCkgPT4gdGhpcy5wb2ludGVyTW92ZS5uZXh0KGUgYXMgVG91Y2hFdmVudCB8IE1vdXNlRXZlbnQpLFxyXG4gICAgICAgICAgb3B0aW9uczogYWN0aXZlQ2FwdHVyaW5nRXZlbnRPcHRpb25zXHJcbiAgICAgICAgfSlcclxuICAgICAgICAuc2V0KHVwRXZlbnQsIHtcclxuICAgICAgICAgIGhhbmRsZXI6IChlOiBFdmVudCkgPT4gdGhpcy5wb2ludGVyVXAubmV4dChlIGFzIFRvdWNoRXZlbnQgfCBNb3VzZUV2ZW50KSxcclxuICAgICAgICAgIG9wdGlvbnM6IHRydWVcclxuICAgICAgICB9KVxyXG4gICAgICAgIC8vIFByZXZlbnRpbmcgdGhlIGRlZmF1bHQgYWN0aW9uIG9uIGBtb3VzZW1vdmVgIGlzbid0IGVub3VnaCB0byBkaXNhYmxlIHRleHQgc2VsZWN0aW9uXHJcbiAgICAgICAgLy8gb24gU2FmYXJpIHNvIHdlIG5lZWQgdG8gcHJldmVudCB0aGUgc2VsZWN0aW9uIGV2ZW50IGFzIHdlbGwuIEFsdGVybmF0aXZlbHkgdGhpcyBjYW5cclxuICAgICAgICAvLyBiZSBkb25lIGJ5IHNldHRpbmcgYHVzZXItc2VsZWN0OiBub25lYCBvbiB0aGUgYGJvZHlgLCBob3dldmVyIGl0IGhhcyBjYXVzZXMgYSBzdHlsZVxyXG4gICAgICAgIC8vIHJlY2FsY3VsYXRpb24gd2hpY2ggY2FuIGJlIGV4cGVuc2l2ZSBvbiBwYWdlcyB3aXRoIGEgbG90IG9mIGVsZW1lbnRzLlxyXG4gICAgICAgIC5zZXQoJ3NlbGVjdHN0YXJ0Jywge1xyXG4gICAgICAgICAgaGFuZGxlcjogdGhpcy5fcHJldmVudERlZmF1bHRXaGlsZURyYWdnaW5nLFxyXG4gICAgICAgICAgb3B0aW9uczogYWN0aXZlQ2FwdHVyaW5nRXZlbnRPcHRpb25zXHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAvLyBUT0RPKGNyaXNiZXRvKTogcHJldmVudCBtb3VzZSB3aGVlbCBzY3JvbGxpbmcgd2hpbGVcclxuICAgICAgLy8gZHJhZ2dpbmcgdW50aWwgd2UndmUgc2V0IHVwIHByb3BlciBzY3JvbGwgaGFuZGxpbmcuXHJcbiAgICAgIGlmICghaXNUb3VjaEV2ZW50KSB7XHJcbiAgICAgICAgdGhpcy5fZ2xvYmFsTGlzdGVuZXJzLnNldCgnd2hlZWwnLCB7XHJcbiAgICAgICAgICBoYW5kbGVyOiB0aGlzLl9wcmV2ZW50RGVmYXVsdFdoaWxlRHJhZ2dpbmcsXHJcbiAgICAgICAgICBvcHRpb25zOiBhY3RpdmVDYXB0dXJpbmdFdmVudE9wdGlvbnNcclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdGhpcy5fbmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcclxuICAgICAgICB0aGlzLl9nbG9iYWxMaXN0ZW5lcnMuZm9yRWFjaCgoY29uZmlnLCBuYW1lKSA9PiB7XHJcbiAgICAgICAgICB0aGlzLl9kb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKG5hbWUsIGNvbmZpZy5oYW5kbGVyLCBjb25maWcub3B0aW9ucyk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqIFN0b3BzIGRyYWdnaW5nIGEgZHJhZyBpdGVtIGluc3RhbmNlLiAqL1xyXG4gIHN0b3BEcmFnZ2luZyhkcmFnOiBJKSB7XHJcbiAgICB0aGlzLl9hY3RpdmVEcmFnSW5zdGFuY2VzLmRlbGV0ZShkcmFnKTtcclxuXHJcbiAgICBpZiAodGhpcy5fYWN0aXZlRHJhZ0luc3RhbmNlcy5zaXplID09PSAwKSB7XHJcbiAgICAgIHRoaXMuX2NsZWFyR2xvYmFsTGlzdGVuZXJzKCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKiogR2V0cyB3aGV0aGVyIGEgZHJhZyBpdGVtIGluc3RhbmNlIGlzIGN1cnJlbnRseSBiZWluZyBkcmFnZ2VkLiAqL1xyXG4gIGlzRHJhZ2dpbmcoZHJhZzogSSkge1xyXG4gICAgcmV0dXJuIHRoaXMuX2FjdGl2ZURyYWdJbnN0YW5jZXMuaGFzKGRyYWcpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0cyBhIGRyb3AgY29udGFpbmVyIGJ5IGl0cyBpZC5cclxuICAgKiBAZGVwcmVjYXRlZCBObyBsb25nZXIgYmVpbmcgdXNlZC4gVG8gYmUgcmVtb3ZlZC5cclxuICAgKiBAYnJlYWtpbmctY2hhbmdlIDguMC4wXHJcbiAgICovXHJcbiAgZ2V0RHJvcENvbnRhaW5lcihpZDogc3RyaW5nKTogQyB8IHVuZGVmaW5lZCB7XHJcbiAgICByZXR1cm4gQXJyYXkuZnJvbSh0aGlzLl9kcm9wSW5zdGFuY2VzKS5maW5kKGluc3RhbmNlID0+IGluc3RhbmNlLmlkID09PSBpZCk7XHJcbiAgfVxyXG5cclxuICBuZ09uRGVzdHJveSgpIHtcclxuICAgIHRoaXMuX2RyYWdJbnN0YW5jZXMuZm9yRWFjaChpbnN0YW5jZSA9PiB0aGlzLnJlbW92ZURyYWdJdGVtKGluc3RhbmNlKSk7XHJcbiAgICB0aGlzLl9kcm9wSW5zdGFuY2VzLmZvckVhY2goaW5zdGFuY2UgPT4gdGhpcy5yZW1vdmVEcm9wQ29udGFpbmVyKGluc3RhbmNlKSk7XHJcbiAgICB0aGlzLl9jbGVhckdsb2JhbExpc3RlbmVycygpO1xyXG4gICAgdGhpcy5wb2ludGVyTW92ZS5jb21wbGV0ZSgpO1xyXG4gICAgdGhpcy5wb2ludGVyVXAuY29tcGxldGUoKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEV2ZW50IGxpc3RlbmVyIHRoYXQgd2lsbCBwcmV2ZW50IHRoZSBkZWZhdWx0IGJyb3dzZXIgYWN0aW9uIHdoaWxlIHRoZSB1c2VyIGlzIGRyYWdnaW5nLlxyXG4gICAqIEBwYXJhbSBldmVudCBFdmVudCB3aG9zZSBkZWZhdWx0IGFjdGlvbiBzaG91bGQgYmUgcHJldmVudGVkLlxyXG4gICAqL1xyXG4gIHByaXZhdGUgX3ByZXZlbnREZWZhdWx0V2hpbGVEcmFnZ2luZyA9IChldmVudDogRXZlbnQpID0+IHtcclxuICAgIGlmICh0aGlzLl9hY3RpdmVEcmFnSW5zdGFuY2VzLnNpemUpIHtcclxuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKiBDbGVhcnMgb3V0IHRoZSBnbG9iYWwgZXZlbnQgbGlzdGVuZXJzIGZyb20gdGhlIGBkb2N1bWVudGAuICovXHJcbiAgcHJpdmF0ZSBfY2xlYXJHbG9iYWxMaXN0ZW5lcnMoKSB7XHJcbiAgICB0aGlzLl9nbG9iYWxMaXN0ZW5lcnMuZm9yRWFjaCgoY29uZmlnLCBuYW1lKSA9PiB7XHJcbiAgICAgIHRoaXMuX2RvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIobmFtZSwgY29uZmlnLmhhbmRsZXIsIGNvbmZpZy5vcHRpb25zKTtcclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMuX2dsb2JhbExpc3RlbmVycy5jbGVhcigpO1xyXG4gIH1cclxufVxyXG4iXX0=