You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
238 lines
34 KiB
238 lines
34 KiB
/**
|
|
* @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 { normalizePassiveListenerOptions } from '@angular/cdk/platform';
|
|
import { merge, Observable, Subject } from 'rxjs';
|
|
import * as i0 from "@angular/core";
|
|
import * as i1 from "@angular/common";
|
|
/** Event options that can be used to bind an active, capturing event. */
|
|
import * as ɵngcc0 from '@angular/core';
|
|
const activeCapturingEventOptions = normalizePassiveListenerOptions({
|
|
passive: false,
|
|
capture: true
|
|
});
|
|
/**
|
|
* Service that keeps track of all the drag item and drop container
|
|
* instances, and manages global event listeners on the `document`.
|
|
* @docs-private
|
|
*/
|
|
// 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.
|
|
export class DragDropRegistry {
|
|
constructor(_ngZone, _document) {
|
|
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 = [];
|
|
/** Keeps track of the event listeners that we've bound to the `document`. */
|
|
this._globalListeners = new Map();
|
|
/**
|
|
* Predicate function to check if an item is being dragged. Moved out into a property,
|
|
* because it'll be called a lot and we don't want to create a new function every time.
|
|
*/
|
|
this._draggingPredicate = (item) => item.isDragging();
|
|
/**
|
|
* 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();
|
|
/**
|
|
* Emits when the viewport has been scrolled while the user is dragging an item.
|
|
* @deprecated To be turned into a private member. Use the `scrolled` method instead.
|
|
* @breaking-change 13.0.0
|
|
*/
|
|
this.scroll = 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 = (event) => {
|
|
if (this._activeDragInstances.length > 0) {
|
|
event.preventDefault();
|
|
}
|
|
};
|
|
/** Event listener for `touchmove` that is bound even if no dragging is happening. */
|
|
this._persistentTouchmoveListener = (event) => {
|
|
if (this._activeDragInstances.length > 0) {
|
|
// Note that we only want to prevent the default action after dragging has actually started.
|
|
// Usually this is the same time at which the item is added to the `_activeDragInstances`,
|
|
// but it could be pushed back if the user has set up a drag delay or threshold.
|
|
if (this._activeDragInstances.some(this._draggingPredicate)) {
|
|
event.preventDefault();
|
|
}
|
|
this.pointerMove.next(event);
|
|
}
|
|
};
|
|
this._document = _document;
|
|
}
|
|
/** Adds a drop container to the registry. */
|
|
registerDropContainer(drop) {
|
|
if (!this._dropInstances.has(drop)) {
|
|
this._dropInstances.add(drop);
|
|
}
|
|
}
|
|
/** Adds a drag item instance to the registry. */
|
|
registerDragItem(drag) {
|
|
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(() => {
|
|
// The event handler has to be explicitly active,
|
|
// because newer browsers make it passive by default.
|
|
this._document.addEventListener('touchmove', this._persistentTouchmoveListener, activeCapturingEventOptions);
|
|
});
|
|
}
|
|
}
|
|
/** Removes a drop container from the registry. */
|
|
removeDropContainer(drop) {
|
|
this._dropInstances.delete(drop);
|
|
}
|
|
/** Removes a drag item instance from the registry. */
|
|
removeDragItem(drag) {
|
|
this._dragInstances.delete(drag);
|
|
this.stopDragging(drag);
|
|
if (this._dragInstances.size === 0) {
|
|
this._document.removeEventListener('touchmove', this._persistentTouchmoveListener, activeCapturingEventOptions);
|
|
}
|
|
}
|
|
/**
|
|
* Starts the dragging sequence for a drag instance.
|
|
* @param drag Drag instance which is being dragged.
|
|
* @param event Event that initiated the dragging.
|
|
*/
|
|
startDragging(drag, event) {
|
|
// Do not process the same drag twice to avoid memory leaks and redundant listeners
|
|
if (this._activeDragInstances.indexOf(drag) > -1) {
|
|
return;
|
|
}
|
|
this._activeDragInstances.push(drag);
|
|
if (this._activeDragInstances.length === 1) {
|
|
const isTouchEvent = event.type.startsWith('touch');
|
|
// 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(isTouchEvent ? 'touchend' : 'mouseup', {
|
|
handler: (e) => this.pointerUp.next(e),
|
|
options: true
|
|
})
|
|
.set('scroll', {
|
|
handler: (e) => this.scroll.next(e),
|
|
// Use capturing so that we pick up scroll changes in any scrollable nodes that aren't
|
|
// the document. See https://github.com/angular/components/issues/17144.
|
|
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
|
|
});
|
|
// We don't have to bind a move event for touch drag sequences, because
|
|
// we already have a persistent global one bound from `registerDragItem`.
|
|
if (!isTouchEvent) {
|
|
this._globalListeners.set('mousemove', {
|
|
handler: (e) => this.pointerMove.next(e),
|
|
options: activeCapturingEventOptions
|
|
});
|
|
}
|
|
this._ngZone.runOutsideAngular(() => {
|
|
this._globalListeners.forEach((config, name) => {
|
|
this._document.addEventListener(name, config.handler, config.options);
|
|
});
|
|
});
|
|
}
|
|
}
|
|
/** Stops dragging a drag item instance. */
|
|
stopDragging(drag) {
|
|
const index = this._activeDragInstances.indexOf(drag);
|
|
if (index > -1) {
|
|
this._activeDragInstances.splice(index, 1);
|
|
if (this._activeDragInstances.length === 0) {
|
|
this._clearGlobalListeners();
|
|
}
|
|
}
|
|
}
|
|
/** Gets whether a drag item instance is currently being dragged. */
|
|
isDragging(drag) {
|
|
return this._activeDragInstances.indexOf(drag) > -1;
|
|
}
|
|
/**
|
|
* Gets a stream that will emit when any element on the page is scrolled while an item is being
|
|
* dragged.
|
|
* @param shadowRoot Optional shadow root that the current dragging sequence started from.
|
|
* Top-level listeners won't pick up events coming from the shadow DOM so this parameter can
|
|
* be used to include an additional top-level listener at the shadow root level.
|
|
*/
|
|
scrolled(shadowRoot) {
|
|
const streams = [this.scroll];
|
|
if (shadowRoot && shadowRoot !== this._document) {
|
|
// Note that this is basically the same as `fromEvent` from rjxs, but we do it ourselves,
|
|
// because we want to guarantee that the event is bound outside of the `NgZone`. With
|
|
// `fromEvent` it'll only happen if the subscription is outside the `NgZone`.
|
|
streams.push(new Observable((observer) => {
|
|
return this._ngZone.runOutsideAngular(() => {
|
|
const eventOptions = true;
|
|
const callback = (event) => {
|
|
if (this._activeDragInstances.length) {
|
|
observer.next(event);
|
|
}
|
|
};
|
|
shadowRoot.addEventListener('scroll', callback, eventOptions);
|
|
return () => {
|
|
shadowRoot.removeEventListener('scroll', callback, eventOptions);
|
|
};
|
|
});
|
|
}));
|
|
}
|
|
return merge(...streams);
|
|
}
|
|
ngOnDestroy() {
|
|
this._dragInstances.forEach(instance => this.removeDragItem(instance));
|
|
this._dropInstances.forEach(instance => this.removeDropContainer(instance));
|
|
this._clearGlobalListeners();
|
|
this.pointerMove.complete();
|
|
this.pointerUp.complete();
|
|
}
|
|
/** Clears out the global event listeners from the `document`. */
|
|
_clearGlobalListeners() {
|
|
this._globalListeners.forEach((config, name) => {
|
|
this._document.removeEventListener(name, config.handler, config.options);
|
|
});
|
|
this._globalListeners.clear();
|
|
}
|
|
}
|
|
DragDropRegistry.ɵfac = function DragDropRegistry_Factory(t) { return new (t || DragDropRegistry)(ɵngcc0.ɵɵinject(ɵngcc0.NgZone), ɵngcc0.ɵɵinject(DOCUMENT)); };
|
|
DragDropRegistry.ɵprov = i0.ɵɵdefineInjectable({ factory: function DragDropRegistry_Factory() { return new DragDropRegistry(i0.ɵɵinject(i0.NgZone), i0.ɵɵinject(i1.DOCUMENT)); }, token: DragDropRegistry, providedIn: "root" });
|
|
DragDropRegistry.ctorParameters = () => [
|
|
{ type: NgZone },
|
|
{ type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] }
|
|
];
|
|
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && ɵngcc0.ɵsetClassMetadata(DragDropRegistry, [{
|
|
type: Injectable,
|
|
args: [{ providedIn: 'root' }]
|
|
}], function () { return [{ type: ɵngcc0.NgZone }, { type: undefined, decorators: [{
|
|
type: Inject,
|
|
args: [DOCUMENT]
|
|
}] }]; }, null); })();
|
|
|
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHJhZy1kcm9wLXJlZ2lzdHJ5LmpzIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvY2RrL2RyYWctZHJvcC9kcmFnLWRyb3AtcmVnaXN0cnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUVILE9BQU8sRUFBQyxVQUFVLEVBQUUsTUFBTSxFQUFhLE1BQU0sRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUNwRSxPQUFPLEVBQUMsUUFBUSxFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFDekMsT0FBTyxFQUFDLCtCQUErQixFQUFDLE1BQU0sdUJBQXVCLENBQUM7QUFDdEUsT0FBTyxFQUFDLEtBQUssRUFBRSxVQUFVLEVBQVksT0FBTyxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBQzFEO0FBQ29DO0FBQXBDLHlFQUF5RTs7QUFDekUsTUFBTSwyQkFBMkIsR0FBRywrQkFBK0IsQ0FBQztBQUNwRSxJQUFFLE9BQU8sRUFBRSxLQUFLO0FBQ2hCLElBQUUsT0FBTyxFQUFFLElBQUk7QUFDZixDQUFDLENBQUMsQ0FBQztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNILGtHQUFrRztBQUNsRyxnR0FBZ0c7QUFDaEcsNEVBQTRFO0FBRTVFLE1BQU0sT0FBTyxnQkFBZ0I7QUFBRyxJQTJDOUIsWUFDVSxPQUFlLEVBQ0wsU0FBYztBQUNwQyxRQUZZLFlBQU8sR0FBUCxPQUFPLENBQVE7QUFBQyxRQXpDMUIsMkNBQTJDO0FBQzdDLFFBQVUsbUJBQWMsR0FBRyxJQUFJLEdBQUcsRUFBSyxDQUFDO0FBQ3hDLFFBQ0Usc0NBQXNDO0FBQ3hDLFFBQVUsbUJBQWMsR0FBRyxJQUFJLEdBQUcsRUFBSyxDQUFDO0FBQ3hDLFFBQ0UsNERBQTREO0FBQzlELFFBQVUseUJBQW9CLEdBQVEsRUFBRSxDQUFDO0FBQ3pDLFFBQ0UsNkVBQTZFO0FBQy9FLFFBQVUscUJBQWdCLEdBQUcsSUFBSSxHQUFHLEVB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LENBQUMsUUFBUSxFQUFFLENBQUM7QUFDOUIsSUFBRSxDQUFDO0FBQ0gsSUF5QkUsaUVBQWlFO0FBQ25FLElBQVUscUJBQXFCO0FBQy9CLFFBQUksSUFBSSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxDQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUUsRUFBRTtBQUNuRCxZQUFNLElBQUksQ0FBQyxTQUFTLENBQUMsbUJBQW1CLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQy9FLFFBQUksQ0FBQyxDQUFDLENBQUM7QUFDUCxRQUNJLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLEVBQUUsQ0FBQztBQUNsQyxJQUFFLENBQUM7QUFDSDtnS0FBQztBQUNELGlPQS9PSztBQUFDO0VBREwsVUFBVSxTQUFDLHJCQUNvQyxZQXBCNUIsTUFBTTtDQW1CYixVQUFVLEVBQUUsTUFBTSxFQUFDLHJCQW5CRiw0Q0FpRXpCLE1BQU0sU0FBQyxRQUFRO0FBQVE7Ozs7Ozs7a0NBQUU7QUFBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBHb29nbGUgTExDIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuXG5pbXBvcnQge0luamVjdGFibGUsIE5nWm9uZSwgT25EZXN0cm95LCBJbmplY3R9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtET0NVTUVOVH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7bm9ybWFsaXplUGFzc2l2ZUxpc3RlbmVyT3B0aW9uc30gZnJvbSAnQGFuZ3VsYXIvY2RrL3BsYXRmb3JtJztcbmltcG9ydCB7bWVyZ2UsIE9ic2VydmFibGUsIE9ic2VydmVyLCBTdWJqZWN0fSBmcm9tICdyeGpzJztcblxuLyoqIEV2ZW50IG9wdGlvbnMgdGhhdCBjYW4gYmUgdXNlZCB0byBiaW5kIGFuIGFjdGl2ZSwgY2FwdHVyaW5nIGV2ZW50LiAqL1xuY29uc3QgYWN0aXZlQ2FwdHVyaW5nRXZlbnRPcHRpb25zID0gbm9ybWFsaXplUGFzc2l2ZUxpc3RlbmVyT3B0aW9ucyh7XG4gIHBhc3NpdmU6IGZhbHNlLFxuICBjYXB0dXJlOiB0cnVlXG59KTtcblxuLyoqXG4gKiBTZXJ2aWNlIHRoYXQga2VlcHMgdHJhY2sgb2YgYWxsIHRoZSBkcmFnIGl0ZW0gYW5kIGRyb3AgY29udGFpbmVyXG4gKiBpbnN0YW5jZXMsIGFuZCBtYW5hZ2VzIGdsb2JhbCBldmVudCBsaXN0ZW5lcnMgb24gdGhlIGBkb2N1bWVudGAuXG4gKiBAZG9jcy1wcml2YXRlXG4gKi9cbi8vIE5vdGU6IHRoaXMgY2xhc3MgaXMgZ2VuZXJpYywgcmF0aGVyIHRoYW4gcmVmZXJlbmNpbmcgQ2RrRHJhZyBhbmQgQ2RrRHJvcExpc3QgZGlyZWN0bHksIGluIG9yZGVyXG4vLyB0byBhdm9pZCBjaXJjdWxhciBpbXBvcnRzLiBJZiB3ZSB3ZXJlIHRvIHJlZmVyZW5jZSB0aGVtIGhlcmUsIGltcG9ydGluZyB0aGUgcmVnaXN0cnkgaW50byB0aGVcbi8vIGNsYXNzZXMgdGhhdCBhcmUgcmVnaXN0ZXJpbmcgdGhlbXNlbHZlcyB3aWxsIGludHJvZHVjZSBhIGNpcmN1bGFyIGltcG9ydC5cbkBJbmplY3RhYmxlKHtwcm92aWRlZEluOiAncm9vdCd9KVxuZXhwb3J0IGNsYXNzIERyYWdEcm9wUmVnaXN0cnk8SSBleHRlbmRzIHtpc0RyYWdnaW5nKCk6IGJvb2xlYW59LCBDPiBpbXBsZW1lbnRzIE9uRGVzdHJveSB7XG4gIHByaXZhdGUgX2RvY3VtZW50OiBEb2N1bWVudDtcblxuICAvKiogUmVnaXN0ZXJlZCBkcm9wIGNvbnRhaW5lciBpbnN0YW5jZXMuICovXG4gIHByaXZhdGUgX2Ryb3BJbnN0YW5jZXMgPSBuZXcgU2V0PEM+KCk7XG5cbiAgLyoqIFJlZ2lzdGVyZWQgZHJhZyBpdGVtIGluc3RhbmNlcy4gKi9cbiAgcHJpdmF0ZSBfZHJhZ0luc3RhbmNlcyA9IG5ldyBTZXQ8ST4oKTtcblxuICAvKiogRHJhZyBpdGVtIGluc3RhbmNlcyB0aGF0IGFyZSBjdXJyZW50bHkgYmVpbmcgZHJhZ2dlZC4gKi9cbiAgcHJpdmF0ZSBfYWN0aXZlRHJhZ0luc3RhbmNlczogSVtdID0gW107XG5cbiAgLyoqIEtlZXBzIHRyYWNrIG9mIHRoZSBldmVudCBsaXN0ZW5lcnMgdGhhdCB3ZSd2ZSBib3VuZCB0byB0aGUgYGRvY3VtZW50YC4gKi9cbiAgcHJpdmF0ZSBfZ2xvYmFsTGlzdGVuZXJzID0gbmV3IE1hcDxzdHJpbmcsIHtcbiAgICBoYW5kbGVyOiAoZXZlbnQ6IEV2ZW50KSA9PiB2b2lkLFxuICAgIG9wdGlvbnM/OiBBZGRFdmVudExpc3RlbmVyT3B0aW9ucyB8IGJvb2xlYW5cbiAgfT4oKTtcblxuICAvKipcbiAgICogUHJlZGljYXRlIGZ1bmN0aW9uIHRvIGNoZWNrIGlmIGFuIGl0ZW0gaXMgYmVpbmcgZHJhZ2dlZC4gIE1vdmVkIG91dCBpbnRvIGEgcHJvcGVydHksXG4gICAqIGJlY2F1c2UgaXQnbGwgYmUgY2FsbGVkIGEgbG90IGFuZCB3ZSBkb24ndCB3YW50IHRvIGNyZWF0ZSBhIG5ldyBmdW5jdGlvbiBldmVyeSB0aW1lLlxuICAgKi9cbiAgcHJpdmF0ZSBfZHJhZ2dpbmdQcmVkaWNhdGUgPSAoaXRlbTogSSkgPT4gaXRlbS5pc0RyYWdnaW5nKCk7XG5cbiAgLyoqXG4gICAqIEVtaXRzIHRoZSBgdG91Y2htb3ZlYCBvciBgbW91c2Vtb3ZlYCBldmVudHMgdGhhdCBhcmUgZGlzcGF0Y2hlZFxuICAgKiB3aGlsZSB0aGUgdXNlciBpcyBkcmFnZ2luZyBhIGRyYWcgaXRlbSBpbnN0YW5jZS5cbiAgICovXG4gIHJlYWRvbmx5IHBvaW50ZXJNb3ZlOiBTdWJqZWN0PFRvdWNoRXZlbnQgfCBNb3VzZUV2ZW50PiA9IG5ldyBTdWJqZWN0PFRvdWNoRXZlbnQgfCBNb3VzZUV2ZW50PigpO1xuXG4gIC8qKlxuICAgKiBFbWl0cyB0aGUgYHRvdWNoZW5kYCBvciBgbW91c2V1cGAgZXZlbnRzIHRoYXQgYXJlIGRpc3BhdGNoZWRcbiAgICogd2hpbGUgdGhlIHVzZXIgaXMgZHJhZ2dpbmcgYSBkcmFnIGl0ZW0gaW5zdGFuY2UuXG4gICAqL1xuICByZWFkb25seSBwb2ludGVyVXA6IFN1YmplY3Q8VG91Y2hFdmVudCB8IE1vdXNlRXZlbnQ+ID0gbmV3IFN1YmplY3Q8VG91Y2hFdmVudCB8IE1vdXNlRXZlbnQ+KCk7XG5cbiAgLyoqXG4gICAqIEVtaXRzIHdoZW4gdGhlIHZpZXdwb3J0IGhhcyBiZWVuIHNjcm9sbGVkIHdoaWxlIHRoZSB1c2VyIGlzIGRyYWdnaW5nIGFuIGl0ZW0uXG4gICAqIEBkZXByZWNhdGVkIFRvIGJlIHR1cm5lZCBpbnRvIGEgcHJpdmF0ZSBtZW1iZXIuIFVzZSB0aGUgYHNjcm9sbGVkYCBtZXRob2QgaW5zdGVhZC5cbiAgICogQGJyZWFraW5nLWNoYW5nZSAxMy4wLjBcbiAgICovXG4gIHJlYWRvbmx5IHNjcm9sbDogU3ViamVjdDxFdmVudD4gPSBuZXcgU3ViamVjdDxFdmVudD4oKTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIF9uZ1pvbmU6IE5nWm9uZSxcbiAgICBASW5qZWN0KERPQ1VNRU5UKSBfZG9jdW1lbnQ6IGFueSkge1xuICAgIHRoaXMuX2RvY3VtZW50ID0gX2RvY3VtZW50O1xuICB9XG5cbiAgLyoqIEFkZHMgYSBkcm9wIGNvbnRhaW5lciB0byB0aGUgcmVnaXN0cnkuICovXG4gIHJlZ2lzdGVyRHJvcENvbnRhaW5lcihkcm9wOiBDKSB7XG4gICAgaWYgKCF0aGlzLl9kcm9wSW5zdGFuY2VzLmhhcyhkcm9wKSkge1xuICAgICAgdGhpcy5fZHJvcEluc3RhbmNlcy5hZGQoZHJvcCk7XG4gICAgfVxuICB9XG5cbiAgLyoqIEFkZHMgYSBkcmFnIGl0ZW0gaW5zdGFuY2UgdG8gdGhlIHJlZ2lzdHJ5LiAqL1xuICByZWdpc3RlckRyYWdJdGVtKGRyYWc6IEkpIHtcbiAgICB0aGlzLl9kcmFnSW5zdGFuY2VzLmFkZChkcmFnKTtcblxuICAgIC8vIFRoZSBgdG91Y2htb3ZlYCBldmVudCBnZXRzIGJvdW5kIG9uY2UsIGFoZWFkIG9mIHRpbWUsIGJlY2F1c2UgV2ViS2l0XG4gICAgLy8gd29uJ3QgcHJldmVudERlZmF1bHQgb24gYSBkeW5hbWljYWxseS1hZGRlZCBgdG91Y2htb3ZlYCBsaXN0ZW5lci5cbiAgICAvLyBTZWUgaHR0cHM6Ly9idWdzLndlYmtpdC5vcmcvc2hvd19idWcuY2dpP2lkPTE4NDI1MC5cbiAgICBpZiAodGhpcy5fZHJhZ0luc3RhbmNlcy5zaXplID09PSAxKSB7XG4gICAgICB0aGlzLl9uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgICAvLyBUaGUgZXZlbnQgaGFuZGxlciBoYXMgdG8gYmUgZXhwbGljaXRseSBhY3RpdmUsXG4gICAgICAgIC8vIGJlY2F1c2UgbmV3ZXIgYnJvd3NlcnMgbWFrZSBpdCBwYXNzaXZlIGJ5IGRlZmF1bHQuXG4gICAgICAgIHRoaXMuX2RvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNobW92ZScsIHRoaXMuX3BlcnNpc3RlbnRUb3VjaG1vdmVMaXN0ZW5lcixcbiAgICAgICAgICAgIGFjdGl2ZUNhcHR1cmluZ0V2ZW50T3B0aW9ucyk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICAvKiogUmVtb3ZlcyBhIGRyb3AgY29udGFpbmVyIGZyb20gdGhlIHJlZ2lzdHJ5LiAqL1xuICByZW1vdmVEcm9wQ29udGFpbmVyKGRyb3A6IEMpIHtcbiAgICB0aGlzLl9kcm9wSW5zdGFuY2VzLmRlbGV0ZShkcm9wKTtcbiAgfVxuXG4gIC8qKiBSZW1vdmVzIGEgZHJhZyBpdGVtIGluc3RhbmNlIGZyb20gdGhlIHJlZ2lzdHJ5LiAqL1xuICByZW1vdmVEcmFnSXRlbShkcmFnOiBJKSB7XG4gICAgdGhpcy5fZHJhZ0luc3RhbmNlcy5kZWxldGUoZHJhZyk7XG4gICAgdGhpcy5zdG9wRHJhZ2dpbmcoZHJhZyk7XG5cbiAgICBpZiAodGhpcy5fZHJhZ0luc3RhbmNlcy5zaXplID09PSAwKSB7XG4gICAgICB0aGlzLl9kb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCd0b3VjaG1vdmUnLCB0aGlzLl9wZXJzaXN0ZW50VG91Y2htb3ZlTGlzdGVuZXIsXG4gICAgICAgICAgYWN0aXZlQ2FwdHVyaW5nRXZlbnRPcHRpb25zKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU3RhcnRzIHRoZSBkcmFnZ2luZyBzZXF1ZW5jZSBmb3IgYSBkcmFnIGluc3RhbmNlLlxuICAgKiBAcGFyYW0gZHJhZyBEcmFnIGluc3RhbmNlIHdoaWNoIGlzIGJlaW5nIGRyYWdnZWQuXG4gICAqIEBwYXJhbSBldmVudCBFdmVudCB0aGF0IGluaXRpYXRlZCB0aGUgZHJhZ2dpbmcuXG4gICAqL1xuICBzdGFydERyYWdnaW5nKGRyYWc6IEksIGV2ZW50OiBUb3VjaEV2ZW50IHwgTW91c2VFdmVudCkge1xuICAgIC8vIERvIG5vdCBwcm9jZXNzIHRoZSBzYW1lIGRyYWcgdHdpY2UgdG8gYXZvaWQgbWVtb3J5IGxlYWtzIGFuZCByZWR1bmRhbnQgbGlzdGVuZXJzXG4gICAgaWYgKHRoaXMuX2FjdGl2ZURyYWdJbnN0YW5jZXMuaW5kZXhPZihkcmFnKSA+IC0xKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5fYWN0aXZlRHJhZ0luc3RhbmNlcy5wdXNoKGRyYWcpO1xuXG4gICAgaWYgKHRoaXMuX2FjdGl2ZURyYWdJbnN0YW5jZXMubGVuZ3RoID09PSAxKSB7XG4gICAgICBjb25zdCBpc1RvdWNoRXZlbnQgPSBldmVudC50eXBlLnN0YXJ0c1dpdGgoJ3RvdWNoJyk7XG5cbiAgICAgIC8vIFdlIGV4cGxpY2l0bHkgYmluZCBfX2FjdGl2ZV9fIGxpc3RlbmVycyBoZXJlLCBiZWNhdXNlIG5ld2VyIGJyb3dzZXJzIHdpbGwgZGVmYXVsdCB0b1xuICAgICAgLy8gcGFzc2l2ZSBvbmVzIGZvciBgbW91c2Vtb3ZlYCBhbmQgYHRvdWNobW92ZWAuIFRoZSBldmVudHMgbmVlZCB0byBiZSBhY3RpdmUsIGJlY2F1c2Ugd2VcbiAgICAgIC8vIHVzZSBgcHJldmVudERlZmF1bHRgIHRvIHByZXZlbnQgdGhlIHBhZ2UgZnJvbSBzY3JvbGxpbmcgd2hpbGUgdGhlIHVzZXIgaXMgZHJhZ2dpbmcuXG4gICAgICB0aGlzLl9nbG9iYWxMaXN0ZW5lcnNcbiAgICAgICAgLnNldChpc1RvdWNoRXZlbnQgPyAndG91Y2hlbmQnIDogJ21vdXNldXAnLCB7XG4gICAgICAgICAgaGFuZGxlcjogKGU6IEV2ZW50KSA9PiB0aGlzLnBvaW50ZXJVcC5uZXh0KGUgYXMgVG91Y2hFdmVudCB8IE1vdXNlRXZlbnQpLFxuICAgICAgICAgIG9wdGlvbnM6IHRydWVcbiAgICAgICAgfSlcbiAgICAgICAgLnNldCgnc2Nyb2xsJywge1xuICAgICAgICAgIGhhbmRsZXI6IChlOiBFdmVudCkgPT4gdGhpcy5zY3JvbGwubmV4dChlKSxcbiAgICAgICAgICAvLyBVc2UgY2FwdHVyaW5nIHNvIHRoYXQgd2UgcGljayB1cCBzY3JvbGwgY2hhbmdlcyBpbiBhbnkgc2Nyb2xsYWJsZSBub2RlcyB0aGF0IGFyZW4ndFxuICAgICAgICAgIC8vIHRoZSBkb2N1bWVudC4gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9hbmd1bGFyL2NvbXBvbmVudHMvaXNzdWVzLzE3MTQ0LlxuICAgICAgICAgIG9wdGlvbnM6IHRydWVcbiAgICAgICAgfSlcbiAgICAgICAgLy8gUHJldmVudGluZyB0aGUgZGVmYXVsdCBhY3Rpb24gb24gYG1vdXNlbW92ZWAgaXNuJ3QgZW5vdWdoIHRvIGRpc2FibGUgdGV4dCBzZWxlY3Rpb25cbiAgICAgICAgLy8gb24gU2FmYXJpIHNvIHdlIG5lZWQgdG8gcHJldmVudCB0aGUgc2VsZWN0aW9uIGV2ZW50IGFzIHdlbGwuIEFsdGVybmF0aXZlbHkgdGhpcyBjYW5cbiAgICAgICAgLy8gYmUgZG9uZSBieSBzZXR0aW5nIGB1c2VyLXNlbGVjdDogbm9uZWAgb24gdGhlIGBib2R5YCwgaG93ZXZlciBpdCBoYXMgY2F1c2VzIGEgc3R5bGVcbiAgICAgICAgLy8gcmVjYWxjdWxhdGlvbiB3aGljaCBjYW4gYmUgZXhwZW5zaXZlIG9uIHBhZ2VzIHdpdGggYSBsb3Qgb2YgZWxlbWVudHMuXG4gICAgICAgIC5zZXQoJ3NlbGVjdHN0YXJ0Jywge1xuICAgICAgICAgIGhhbmRsZXI6IHRoaXMuX3ByZXZlbnREZWZhdWx0V2hpbGVEcmFnZ2luZyxcbiAgICAgICAgICBvcHRpb25zOiBhY3RpdmVDYXB0dXJpbmdFdmVudE9wdGlvbnNcbiAgICAgICAgfSk7XG5cbiAgICAgIC8vIFdlIGRvbid0IGhhdmUgdG8gYmluZCBhIG1vdmUgZXZlbnQgZm9yIHRvdWNoIGRyYWcgc2VxdWVuY2VzLCBiZWNhdXNlXG4gICAgICAvLyB3ZSBhbHJlYWR5IGhhdmUgYSBwZXJzaXN0ZW50IGdsb2JhbCBvbmUgYm91bmQgZnJvbSBgcmVnaXN0ZXJEcmFnSXRlbWAuXG4gICAgICBpZiAoIWlzVG91Y2hFdmVudCkge1xuICAgICAgICB0aGlzLl9nbG9iYWxMaXN0ZW5lcnMuc2V0KCdtb3VzZW1vdmUnLCB7XG4gICAgICAgICAgaGFuZGxlcjogKGU6IEV2ZW50KSA9PiB0aGlzLnBvaW50ZXJNb3ZlLm5leHQoZSBhcyBNb3VzZUV2ZW50KSxcbiAgICAgICAgICBvcHRpb25zOiBhY3RpdmVDYXB0dXJpbmdFdmVudE9wdGlvbnNcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuX25nWm9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XG4gICAgICAgIHRoaXMuX2dsb2JhbExpc3RlbmVycy5mb3JFYWNoKChjb25maWcsIG5hbWUpID0+IHtcbiAgICAgICAgICB0aGlzLl9kb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKG5hbWUsIGNvbmZpZy5oYW5kbGVyLCBjb25maWcub3B0aW9ucyk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqIFN0b3BzIGRyYWdnaW5nIGEgZHJhZyBpdGVtIGluc3RhbmNlLiAqL1xuICBzdG9wRHJhZ2dpbmcoZHJhZzogSSkge1xuICAgIGNvbnN0IGluZGV4ID0gdGhpcy5fYWN0aXZlRHJhZ0luc3RhbmNlcy5pbmRleE9mKGRyYWcpO1xuXG4gICAgaWYgKGluZGV4ID4gLTEpIHtcbiAgICAgIHRoaXMuX2FjdGl2ZURyYWdJbnN0YW5jZXMuc3BsaWNlKGluZGV4LCAxKTtcblxuICAgICAgaWYgKHRoaXMuX2FjdGl2ZURyYWdJbnN0YW5jZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHRoaXMuX2NsZWFyR2xvYmFsTGlzdGVuZXJzKCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqIEdldHMgd2hldGhlciBhIGRyYWcgaXRlbSBpbnN0YW5jZSBpcyBjdXJyZW50bHkgYmVpbmcgZHJhZ2dlZC4gKi9cbiAgaXNEcmFnZ2luZyhkcmFnOiBJKSB7XG4gICAgcmV0dXJuIHRoaXMuX2FjdGl2ZURyYWdJbnN0YW5jZXMuaW5kZXhPZihkcmFnKSA+IC0xO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgYSBzdHJlYW0gdGhhdCB3aWxsIGVtaXQgd2hlbiBhbnkgZWxlbWVudCBvbiB0aGUgcGFnZSBpcyBzY3JvbGxlZCB3aGlsZSBhbiBpdGVtIGlzIGJlaW5nXG4gICAqIGRyYWdnZWQuXG4gICAqIEBwYXJhbSBzaGFkb3dSb290IE9wdGlvbmFsIHNoYWRvdyByb290IHRoYXQgdGhlIGN1cnJlbnQgZHJhZ2dpbmcgc2VxdWVuY2Ugc3RhcnRlZCBmcm9tLlxuICAgKiAgIFRvcC1sZXZlbCBsaXN0ZW5lcnMgd29uJ3QgcGljayB1cCBldmVudHMgY29taW5nIGZyb20gdGhlIHNoYWRvdyBET00gc28gdGhpcyBwYXJhbWV0ZXIgY2FuXG4gICAqICAgYmUgdXNlZCB0byBpbmNsdWRlIGFuIGFkZGl0aW9uYWwgdG9wLWxldmVsIGxpc3RlbmVyIGF0IHRoZSBzaGFkb3cgcm9vdCBsZXZlbC5cbiAgICovXG4gIHNjcm9sbGVkKHNoYWRvd1Jvb3Q/OiBEb2N1bWVudE9yU2hhZG93Um9vdCB8IG51bGwpOiBPYnNlcnZhYmxlPEV2ZW50PiB7XG4gICAgY29uc3Qgc3RyZWFtczogT2JzZXJ2YWJsZTxFdmVudD5bXSA9IFt0aGlzLnNjcm9sbF07XG5cbiAgICBpZiAoc2hhZG93Um9vdCAmJiBzaGFkb3dSb290ICE9PSB0aGlzLl9kb2N1bWVudCkge1xuICAgICAgLy8gTm90ZSB0aGF0IHRoaXMgaXMgYmFzaWNhbGx5IHRoZSBzYW1lIGFzIGBmcm9tRXZlbnRgIGZyb20gcmp4cywgYnV0IHdlIGRvIGl0IG91cnNlbHZlcyxcbiAgICAgIC8vIGJlY2F1c2Ugd2Ugd2FudCB0byBndWFyYW50ZWUgdGhhdCB0aGUgZXZlbnQgaXMgYm91bmQgb3V0c2lkZSBvZiB0aGUgYE5nWm9uZWAuIFdpdGhcbiAgICAgIC8vIGBmcm9tRXZlbnRgIGl0J2xsIG9ubHkgaGFwcGVuIGlmIHRoZSBzdWJzY3JpcHRpb24gaXMgb3V0c2lkZSB0aGUgYE5nWm9uZWAuXG4gICAgICBzdHJlYW1zLnB1c2gobmV3IE9ic2VydmFibGUoKG9ic2VydmVyOiBPYnNlcnZlcjxFdmVudD4pID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX25nWm9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XG4gICAgICAgICAgY29uc3QgZXZlbnRPcHRpb25zID0gdHJ1ZTtcbiAgICAgICAgICBjb25zdCBjYWxsYmFjayA9IChldmVudDogRXZlbnQpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9hY3RpdmVEcmFnSW5zdGFuY2VzLmxlbmd0aCkge1xuICAgICAgICAgICAgICBvYnNlcnZlci5uZXh0KGV2ZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgKHNoYWRvd1Jvb3QgYXMgU2hhZG93Um9vdCkuYWRkRXZlbnRMaXN0ZW5lcignc2Nyb2xsJywgY2FsbGJhY2ssIGV2ZW50T3B0aW9ucyk7XG5cbiAgICAgICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICAgICAgKHNoYWRvd1Jvb3QgYXMgU2hhZG93Um9vdCkucmVtb3ZlRXZlbnRMaXN0ZW5lcignc2Nyb2xsJywgY2FsbGJhY2ssIGV2ZW50T3B0aW9ucyk7XG4gICAgICAgICAgfTtcbiAgICAgICAgfSk7XG4gICAgICB9KSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG1lcmdlKC4uLnN0cmVhbXMpO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgdGhpcy5fZHJhZ0luc3RhbmNlcy5mb3JFYWNoKGluc3RhbmNlID0+IHRoaXMucmVtb3ZlRHJhZ0l0ZW0oaW5zdGFuY2UpKTtcbiAgICB0aGlzLl9kcm9wSW5zdGFuY2VzLmZvckVhY2goaW5zdGFuY2UgPT4gdGhpcy5yZW1vdmVEcm9wQ29udGFpbmVyKGluc3RhbmNlKSk7XG4gICAgdGhpcy5fY2xlYXJHbG9iYWxMaXN0ZW5lcnMoKTtcbiAgICB0aGlzLnBvaW50ZXJNb3ZlLmNvbXBsZXRlKCk7XG4gICAgdGhpcy5wb2ludGVyVXAuY29tcGxldGUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFdmVudCBsaXN0ZW5lciB0aGF0IHdpbGwgcHJldmVudCB0aGUgZGVmYXVsdCBicm93c2VyIGFjdGlvbiB3aGlsZSB0aGUgdXNlciBpcyBkcmFnZ2luZy5cbiAgICogQHBhcmFtIGV2ZW50IEV2ZW50IHdob3NlIGRlZmF1bHQgYWN0aW9uIHNob3VsZCBiZSBwcmV2ZW50ZWQuXG4gICAqL1xuICBwcml2YXRlIF9wcmV2ZW50RGVmYXVsdFdoaWxlRHJhZ2dpbmcgPSAoZXZlbnQ6IEV2ZW50KSA9PiB7XG4gICAgaWYgKHRoaXMuX2FjdGl2ZURyYWdJbnN0YW5jZXMubGVuZ3RoID4gMCkge1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG4gIH1cblxuICAvKiogRXZlbnQgbGlzdGVuZXIgZm9yIGB0b3VjaG1vdmVgIHRoYXQgaXMgYm91bmQgZXZlbiBpZiBubyBkcmFnZ2luZyBpcyBoYXBwZW5pbmcuICovXG4gIHByaXZhdGUgX3BlcnNpc3RlbnRUb3VjaG1vdmVMaXN0ZW5lciA9IChldmVudDogVG91Y2hFdmVudCkgPT4ge1xuICAgIGlmICh0aGlzLl9hY3RpdmVEcmFnSW5zdGFuY2VzLmxlbmd0aCA+IDApIHtcbiAgICAgIC8vIE5vdGUgdGhhdCB3ZSBvbmx5IHdhbnQgdG8gcHJldmVudCB0aGUgZGVmYXVsdCBhY3Rpb24gYWZ0ZXIgZHJhZ2dpbmcgaGFzIGFjdHVhbGx5IHN0YXJ0ZWQuXG4gICAgICAvLyBVc3VhbGx5IHRoaXMgaXMgdGhlIHNhbWUgdGltZSBhdCB3aGljaCB0aGUgaXRlbSBpcyBhZGRlZCB0byB0aGUgYF9hY3RpdmVEcmFnSW5zdGFuY2VzYCxcbiAgICAgIC8vIGJ1dCBpdCBjb3VsZCBiZSBwdXNoZWQgYmFjayBpZiB0aGUgdXNlciBoYXMgc2V0IHVwIGEgZHJhZyBkZWxheSBvciB0aHJlc2hvbGQuXG4gICAgICBpZiAodGhpcy5fYWN0aXZlRHJhZ0luc3RhbmNlcy5zb21lKHRoaXMuX2RyYWdnaW5nUHJlZGljYXRlKSkge1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnBvaW50ZXJNb3ZlLm5leHQoZXZlbnQpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBDbGVhcnMgb3V0IHRoZSBnbG9iYWwgZXZlbnQgbGlzdGVuZXJzIGZyb20gdGhlIGBkb2N1bWVudGAuICovXG4gIHByaXZhdGUgX2NsZWFyR2xvYmFsTGlzdGVuZXJzKCkge1xuICAgIHRoaXMuX2dsb2JhbExpc3RlbmVycy5mb3JFYWNoKChjb25maWcsIG5hbWUpID0+IHtcbiAgICAgIHRoaXMuX2RvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIobmFtZSwgY29uZmlnLmhhbmRsZXIsIGNvbmZpZy5vcHRpb25zKTtcbiAgICB9KTtcblxuICAgIHRoaXMuX2dsb2JhbExpc3RlbmVycy5jbGVhcigpO1xuICB9XG59XG4iXX0=
|