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.
149 lines
21 KiB
149 lines
21 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 { Platform } from '@angular/cdk/platform';
|
|
import { Injectable, NgZone, Optional, Inject } from '@angular/core';
|
|
import { Subject } from 'rxjs';
|
|
import { auditTime } from 'rxjs/operators';
|
|
import { DOCUMENT } from '@angular/common';
|
|
import * as i0 from "@angular/core";
|
|
import * as i1 from "@angular/cdk/platform";
|
|
import * as i2 from "@angular/common";
|
|
/** Time in ms to throttle the resize events by default. */
|
|
import * as ɵngcc0 from '@angular/core';
|
|
import * as ɵngcc1 from '@angular/cdk/platform';
|
|
export const DEFAULT_RESIZE_TIME = 20;
|
|
/**
|
|
* Simple utility for getting the bounds of the browser viewport.
|
|
* @docs-private
|
|
*/
|
|
export class ViewportRuler {
|
|
constructor(_platform, ngZone, document) {
|
|
this._platform = _platform;
|
|
/** Stream of viewport change events. */
|
|
this._change = new Subject();
|
|
/** Event listener that will be used to handle the viewport change events. */
|
|
this._changeListener = (event) => {
|
|
this._change.next(event);
|
|
};
|
|
this._document = document;
|
|
ngZone.runOutsideAngular(() => {
|
|
if (_platform.isBrowser) {
|
|
const window = this._getWindow();
|
|
// Note that bind the events ourselves, rather than going through something like RxJS's
|
|
// `fromEvent` so that we can ensure that they're bound outside of the NgZone.
|
|
window.addEventListener('resize', this._changeListener);
|
|
window.addEventListener('orientationchange', this._changeListener);
|
|
}
|
|
// Clear the cached position so that the viewport is re-measured next time it is required.
|
|
// We don't need to keep track of the subscription, because it is completed on destroy.
|
|
this.change().subscribe(() => this._viewportSize = null);
|
|
});
|
|
}
|
|
ngOnDestroy() {
|
|
if (this._platform.isBrowser) {
|
|
const window = this._getWindow();
|
|
window.removeEventListener('resize', this._changeListener);
|
|
window.removeEventListener('orientationchange', this._changeListener);
|
|
}
|
|
this._change.complete();
|
|
}
|
|
/** Returns the viewport's width and height. */
|
|
getViewportSize() {
|
|
if (!this._viewportSize) {
|
|
this._updateViewportSize();
|
|
}
|
|
const output = { width: this._viewportSize.width, height: this._viewportSize.height };
|
|
// If we're not on a browser, don't cache the size since it'll be mocked out anyway.
|
|
if (!this._platform.isBrowser) {
|
|
this._viewportSize = null;
|
|
}
|
|
return output;
|
|
}
|
|
/** Gets a ClientRect for the viewport's bounds. */
|
|
getViewportRect() {
|
|
// Use the document element's bounding rect rather than the window scroll properties
|
|
// (e.g. pageYOffset, scrollY) due to in issue in Chrome and IE where window scroll
|
|
// properties and client coordinates (boundingClientRect, clientX/Y, etc.) are in different
|
|
// conceptual viewports. Under most circumstances these viewports are equivalent, but they
|
|
// can disagree when the page is pinch-zoomed (on devices that support touch).
|
|
// See https://bugs.chromium.org/p/chromium/issues/detail?id=489206#c4
|
|
// We use the documentElement instead of the body because, by default (without a css reset)
|
|
// browsers typically give the document body an 8px margin, which is not included in
|
|
// getBoundingClientRect().
|
|
const scrollPosition = this.getViewportScrollPosition();
|
|
const { width, height } = this.getViewportSize();
|
|
return {
|
|
top: scrollPosition.top,
|
|
left: scrollPosition.left,
|
|
bottom: scrollPosition.top + height,
|
|
right: scrollPosition.left + width,
|
|
height,
|
|
width,
|
|
};
|
|
}
|
|
/** Gets the (top, left) scroll position of the viewport. */
|
|
getViewportScrollPosition() {
|
|
// While we can get a reference to the fake document
|
|
// during SSR, it doesn't have getBoundingClientRect.
|
|
if (!this._platform.isBrowser) {
|
|
return { top: 0, left: 0 };
|
|
}
|
|
// The top-left-corner of the viewport is determined by the scroll position of the document
|
|
// body, normally just (scrollLeft, scrollTop). However, Chrome and Firefox disagree about
|
|
// whether `document.body` or `document.documentElement` is the scrolled element, so reading
|
|
// `scrollTop` and `scrollLeft` is inconsistent. However, using the bounding rect of
|
|
// `document.documentElement` works consistently, where the `top` and `left` values will
|
|
// equal negative the scroll position.
|
|
const document = this._document;
|
|
const window = this._getWindow();
|
|
const documentElement = document.documentElement;
|
|
const documentRect = documentElement.getBoundingClientRect();
|
|
const top = -documentRect.top || document.body.scrollTop || window.scrollY ||
|
|
documentElement.scrollTop || 0;
|
|
const left = -documentRect.left || document.body.scrollLeft || window.scrollX ||
|
|
documentElement.scrollLeft || 0;
|
|
return { top, left };
|
|
}
|
|
/**
|
|
* Returns a stream that emits whenever the size of the viewport changes.
|
|
* This stream emits outside of the Angular zone.
|
|
* @param throttleTime Time in milliseconds to throttle the stream.
|
|
*/
|
|
change(throttleTime = DEFAULT_RESIZE_TIME) {
|
|
return throttleTime > 0 ? this._change.pipe(auditTime(throttleTime)) : this._change;
|
|
}
|
|
/** Use defaultView of injected document if available or fallback to global window reference */
|
|
_getWindow() {
|
|
return this._document.defaultView || window;
|
|
}
|
|
/** Updates the cached viewport size. */
|
|
_updateViewportSize() {
|
|
const window = this._getWindow();
|
|
this._viewportSize = this._platform.isBrowser ?
|
|
{ width: window.innerWidth, height: window.innerHeight } :
|
|
{ width: 0, height: 0 };
|
|
}
|
|
}
|
|
ViewportRuler.ɵfac = function ViewportRuler_Factory(t) { return new (t || ViewportRuler)(ɵngcc0.ɵɵinject(ɵngcc1.Platform), ɵngcc0.ɵɵinject(ɵngcc0.NgZone), ɵngcc0.ɵɵinject(DOCUMENT, 8)); };
|
|
ViewportRuler.ɵprov = i0.ɵɵdefineInjectable({ factory: function ViewportRuler_Factory() { return new ViewportRuler(i0.ɵɵinject(i1.Platform), i0.ɵɵinject(i0.NgZone), i0.ɵɵinject(i2.DOCUMENT, 8)); }, token: ViewportRuler, providedIn: "root" });
|
|
ViewportRuler.ctorParameters = () => [
|
|
{ type: Platform },
|
|
{ type: NgZone },
|
|
{ type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [DOCUMENT,] }] }
|
|
];
|
|
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && ɵngcc0.ɵsetClassMetadata(ViewportRuler, [{
|
|
type: Injectable,
|
|
args: [{ providedIn: 'root' }]
|
|
}], function () { return [{ type: ɵngcc1.Platform }, { type: ɵngcc0.NgZone }, { type: undefined, decorators: [{
|
|
type: Optional
|
|
}, {
|
|
type: Inject,
|
|
args: [DOCUMENT]
|
|
}] }]; }, null); })();
|
|
|
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmlld3BvcnQtcnVsZXIuanMiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9jZGsvc2Nyb2xsaW5nL3ZpZXdwb3J0LXJ1bGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFFSCxPQUFPLEVBQUMsUUFBUSxFQUFDLE1BQU0sdUJBQXVCLENBQUM7QUFDL0MsT0FBTyxFQUFDLFVBQVUsRUFBRSxNQUFNLEVBQWEsUUFBUSxFQUFFLE1BQU0sRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUM5RSxPQUFPLEVBQWEsT0FBTyxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBQ3pDLE9BQU8sRUFBQyxTQUFTLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUN6QyxPQUFPLEVBQUMsUUFBUSxFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFDekM7QUFDb0M7QUFDZjtBQURyQiwyREFBMkQ7OztBQUMzRCxNQUFNLENBQUMsTUFBTSxtQkFBbUIsR0FBRyxFQUFFLENBQUM7QUFRdEM7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUVILE1BQU0sT0FBTyxhQUFhO0FBQUcsSUFlM0IsWUFBb0IsU0FBbUIsRUFDM0IsTUFBYyxFQUNnQixRQUFhO0FBQ3pELFFBSHNCLGNBQVMsR0FBVCxTQUFTLENBQVU7QUFBQyxRQVh4Qyx3Q0FBd0M7QUFDMUMsUUFBbUIsWUFBTyxHQUFHLElBQUksT0FBTyxFQUFTLENBQUM7QUFDbEQsUUFDRSw2RUFBNkU7QUFDL0UsUUFBVSxvQkFBZSxHQUFHLENBQUMsS0FBWSxFQUFFLEVBQUU7QUFDN0MsWUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUM3QixRQUFFLENBQUMsQ0FBQTtBQUNILFFBT0ksSUFBSSxDQUFDLFNBQVMsR0FBRyxRQUFRLENBQUM7QUFDOUIsUUFDSSxNQUFNLENBQUMsaUJBQWlCLENBQUMsR0FBRyxFQUFFO0FBQ2xDLFlBQU0s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QUMsU0FBUyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUM7QUFDeEYsSUFBRSxDQUFDO0FBQ0gsSUFDRSwrRkFBK0Y7QUFDakcsSUFBVSxVQUFVO0FBQUssUUFDckIsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLFdBQVcsSUFBSSxNQUFNLENBQUM7QUFDaEQsSUFBRSxDQUFDO0FBQ0gsSUFDRSx3Q0FBd0M7QUFDMUMsSUFBVSxtQkFBbUI7QUFDN0IsUUFBSSxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7QUFDckMsUUFBSSxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLENBQUM7QUFDbkQsWUFBUSxFQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLENBQUMsV0FBVyxFQUFDLENBQUMsQ0FBQztBQUNoRSxZQUFRLEVBQUMsS0FBSyxFQUFFLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFDLENBQUM7QUFDOUIsSUFBRSxDQUFDO0FBQ0g7NExBQUM7QUFDRCxrUEF4SUs7QUFBQztFQURMLFVBQVUsU0FBQyxFQUFDLHZCQUNnQyxZQXBCckMsUUFBUTtTQW1CTyxFQUFFLE1BQU0sRUFBQyxuQkFuQlosWUFDQSxNQUFNO0FBQUksNENBb0NmLFFBQVEsWUFBSSxNQUFNLFNBQUMsUUFBUTtBQUFROzs7Ozs7Ozs7a0NBQUU7QUFBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBHb29nbGUgTExDIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuXG5pbXBvcnQge1BsYXRmb3JtfSBmcm9tICdAYW5ndWxhci9jZGsvcGxhdGZvcm0nO1xuaW1wb3J0IHtJbmplY3RhYmxlLCBOZ1pvbmUsIE9uRGVzdHJveSwgT3B0aW9uYWwsIEluamVjdH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge09ic2VydmFibGUsIFN1YmplY3R9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHthdWRpdFRpbWV9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7RE9DVU1FTlR9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5cbi8qKiBUaW1lIGluIG1zIHRvIHRocm90dGxlIHRoZSByZXNpemUgZXZlbnRzIGJ5IGRlZmF1bHQuICovXG5leHBvcnQgY29uc3QgREVGQVVMVF9SRVNJWkVfVElNRSA9IDIwO1xuXG4vKiogT2JqZWN0IHRoYXQgaG9sZHMgdGhlIHNjcm9sbCBwb3NpdGlvbiBvZiB0aGUgdmlld3BvcnQgaW4gZWFjaCBkaXJlY3Rpb24uICovXG5leHBvcnQgaW50ZXJmYWNlIFZpZXdwb3J0U2Nyb2xsUG9zaXRpb24ge1xuICB0b3A6IG51bWJlcjtcbiAgbGVmdDogbnVtYmVyO1xufVxuXG4vKipcbiAqIFNpbXBsZSB1dGlsaXR5IGZvciBnZXR0aW5nIHRoZSBib3VuZHMgb2YgdGhlIGJyb3dzZXIgdmlld3BvcnQuXG4gKiBAZG9jcy1wcml2YXRlXG4gKi9cbkBJbmplY3RhYmxlKHtwcm92aWRlZEluOiAncm9vdCd9KVxuZXhwb3J0IGNsYXNzIFZpZXdwb3J0UnVsZXIgaW1wbGVtZW50cyBPbkRlc3Ryb3kge1xuICAvKiogQ2FjaGVkIHZpZXdwb3J0IGRpbWVuc2lvbnMuICovXG4gIHByaXZhdGUgX3ZpZXdwb3J0U2l6ZToge3dpZHRoOiBudW1iZXI7IGhlaWdodDogbnVtYmVyfSB8IG51bGw7XG5cbiAgLyoqIFN0cmVhbSBvZiB2aWV3cG9ydCBjaGFuZ2UgZXZlbnRzLiAqL1xuICBwcml2YXRlIHJlYWRvbmx5IF9jaGFuZ2UgPSBuZXcgU3ViamVjdDxFdmVudD4oKTtcblxuICAvKiogRXZlbnQgbGlzdGVuZXIgdGhhdCB3aWxsIGJlIHVzZWQgdG8gaGFuZGxlIHRoZSB2aWV3cG9ydCBjaGFuZ2UgZXZlbnRzLiAqL1xuICBwcml2YXRlIF9jaGFuZ2VMaXN0ZW5lciA9IChldmVudDogRXZlbnQpID0+IHtcbiAgICB0aGlzLl9jaGFuZ2UubmV4dChldmVudCk7XG4gIH1cblxuICAvKiogVXNlZCB0byByZWZlcmVuY2UgY29ycmVjdCBkb2N1bWVudC93aW5kb3cgKi9cbiAgcHJvdGVjdGVkIF9kb2N1bWVudDogRG9jdW1lbnQ7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBfcGxhdGZvcm06IFBsYXRmb3JtLFxuICAgICAgICAgICAgICBuZ1pvbmU6IE5nWm9uZSxcbiAgICAgICAgICAgICAgQE9wdGlvbmFsKCkgQEluamVjdChET0NVTUVOVCkgZG9jdW1lbnQ6IGFueSkge1xuICAgIHRoaXMuX2RvY3VtZW50ID0gZG9jdW1lbnQ7XG5cbiAgICBuZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgaWYgKF9wbGF0Zm9ybS5pc0Jyb3dzZXIpIHtcbiAgICAgICAgY29uc3Qgd2luZG93ID0gdGhpcy5fZ2V0V2luZG93KCk7XG5cbiAgICAgICAgLy8gTm90ZSB0aGF0IGJpbmQgdGhlIGV2ZW50cyBvdXJzZWx2ZXMsIHJhdGhlciB0aGFuIGdvaW5nIHRocm91Z2ggc29tZXRoaW5nIGxpa2UgUnhKUydzXG4gICAgICAgIC8vIGBmcm9tRXZlbnRgIHNvIHRoYXQgd2UgY2FuIGVuc3VyZSB0aGF0IHRoZXkncmUgYm91bmQgb3V0c2lkZSBvZiB0aGUgTmdab25lLlxuICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncmVzaXplJywgdGhpcy5fY2hhbmdlTGlzdGVuZXIpO1xuICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignb3JpZW50YXRpb25jaGFuZ2UnLCB0aGlzLl9jaGFuZ2VMaXN0ZW5lcik7XG4gICAgICB9XG5cbiAgICAgIC8vIENsZWFyIHRoZSBjYWNoZWQgcG9zaXRpb24gc28gdGhhdCB0aGUgdmlld3BvcnQgaXMgcmUtbWVhc3VyZWQgbmV4dCB0aW1lIGl0IGlzIHJlcXVpcmVkLlxuICAgICAgLy8gV2UgZG9uJ3QgbmVlZCB0byBrZWVwIHRyYWNrIG9mIHRoZSBzdWJzY3JpcHRpb24sIGJlY2F1c2UgaXQgaXMgY29tcGxldGVkIG9uIGRlc3Ryb3kuXG4gICAgICB0aGlzLmNoYW5nZSgpLnN1YnNjcmliZSgoKSA9PiB0aGlzLl92aWV3cG9ydFNpemUgPSBudWxsKTtcbiAgICB9KTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIGlmICh0aGlzLl9wbGF0Zm9ybS5pc0Jyb3dzZXIpIHtcbiAgICAgIGNvbnN0IHdpbmRvdyA9IHRoaXMuX2dldFdpbmRvdygpO1xuICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsIHRoaXMuX2NoYW5nZUxpc3RlbmVyKTtcbiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdvcmllbnRhdGlvbmNoYW5nZScsIHRoaXMuX2NoYW5nZUxpc3RlbmVyKTtcbiAgICB9XG5cbiAgICB0aGlzLl9jaGFuZ2UuY29tcGxldGUoKTtcbiAgfVxuXG4gIC8qKiBSZXR1cm5zIHRoZSB2aWV3cG9ydCdzIHdpZHRoIGFuZCBoZWlnaHQuICovXG4gIGdldFZpZXdwb3J0U2l6ZSgpOiBSZWFkb25seTx7d2lkdGg6IG51bWJlciwgaGVpZ2h0OiBudW1iZXJ9PiB7XG4gICAgaWYgKCF0aGlzLl92aWV3cG9ydFNpemUpIHtcbiAgICAgIHRoaXMuX3VwZGF0ZVZpZXdwb3J0U2l6ZSgpO1xuICAgIH1cblxuICAgIGNvbnN0IG91dHB1dCA9IHt3aWR0aDogdGhpcy5fdmlld3BvcnRTaXplIS53aWR0aCwgaGVpZ2h0OiB0aGlzLl92aWV3cG9ydFNpemUhLmhlaWdodH07XG5cbiAgICAvLyBJZiB3ZSdyZSBub3Qgb24gYSBicm93c2VyLCBkb24ndCBjYWNoZSB0aGUgc2l6ZSBzaW5jZSBpdCdsbCBiZSBtb2NrZWQgb3V0IGFueXdheS5cbiAgICBpZiAoIXRoaXMuX3BsYXRmb3JtLmlzQnJvd3Nlcikge1xuICAgICAgdGhpcy5fdmlld3BvcnRTaXplID0gbnVsbCE7XG4gICAgfVxuXG4gICAgcmV0dXJuIG91dHB1dDtcbiAgfVxuXG4gIC8qKiBHZXRzIGEgQ2xpZW50UmVjdCBmb3IgdGhlIHZpZXdwb3J0J3MgYm91bmRzLiAqL1xuICBnZXRWaWV3cG9ydFJlY3QoKTogQ2xpZW50UmVjdCB7XG4gICAgLy8gVXNlIHRoZSBkb2N1bWVudCBlbGVtZW50J3MgYm91bmRpbmcgcmVjdCByYXRoZXIgdGhhbiB0aGUgd2luZG93IHNjcm9sbCBwcm9wZXJ0aWVzXG4gICAgLy8gKGUuZy4gcGFnZVlPZmZzZXQsIHNjcm9sbFkpIGR1ZSB0byBpbiBpc3N1ZSBpbiBDaHJvbWUgYW5kIElFIHdoZXJlIHdpbmRvdyBzY3JvbGxcbiAgICAvLyBwcm9wZXJ0aWVzIGFuZCBjbGllbnQgY29vcmRpbmF0ZXMgKGJvdW5kaW5nQ2xpZW50UmVjdCwgY2xpZW50WC9ZLCBldGMuKSBhcmUgaW4gZGlmZmVyZW50XG4gICAgLy8gY29uY2VwdHVhbCB2aWV3cG9ydHMuIFVuZGVyIG1vc3QgY2lyY3Vtc3RhbmNlcyB0aGVzZSB2aWV3cG9ydHMgYXJlIGVxdWl2YWxlbnQsIGJ1dCB0aGV5XG4gICAgLy8gY2FuIGRpc2FncmVlIHdoZW4gdGhlIHBhZ2UgaXMgcGluY2gtem9vbWVkIChvbiBkZXZpY2VzIHRoYXQgc3VwcG9ydCB0b3VjaCkuXG4gICAgLy8gU2VlIGh0dHBzOi8vYnVncy5jaHJvbWl1bS5vcmcvcC9jaHJvbWl1bS9pc3N1ZXMvZGV0YWlsP2lkPTQ4OTIwNiNjNFxuICAgIC8vIFdlIHVzZSB0aGUgZG9jdW1lbnRFbGVtZW50IGluc3RlYWQgb2YgdGhlIGJvZHkgYmVjYXVzZSwgYnkgZGVmYXVsdCAod2l0aG91dCBhIGNzcyByZXNldClcbiAgICAvLyBicm93c2VycyB0eXBpY2FsbHkgZ2l2ZSB0aGUgZG9jdW1lbnQgYm9keSBhbiA4cHggbWFyZ2luLCB3aGljaCBpcyBub3QgaW5jbHVkZWQgaW5cbiAgICAvLyBnZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5cbiAgICBjb25zdCBzY3JvbGxQb3NpdGlvbiA9IHRoaXMuZ2V0Vmlld3BvcnRTY3JvbGxQb3NpdGlvbigpO1xuICAgIGNvbnN0IHt3aWR0aCwgaGVpZ2h0fSA9IHRoaXMuZ2V0Vmlld3BvcnRTaXplKCk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgdG9wOiBzY3JvbGxQb3NpdGlvbi50b3AsXG4gICAgICBsZWZ0OiBzY3JvbGxQb3NpdGlvbi5sZWZ0LFxuICAgICAgYm90dG9tOiBzY3JvbGxQb3NpdGlvbi50b3AgKyBoZWlnaHQsXG4gICAgICByaWdodDogc2Nyb2xsUG9zaXRpb24ubGVmdCArIHdpZHRoLFxuICAgICAgaGVpZ2h0LFxuICAgICAgd2lkdGgsXG4gICAgfTtcbiAgfVxuXG4gIC8qKiBHZXRzIHRoZSAodG9wLCBsZWZ0KSBzY3JvbGwgcG9zaXRpb24gb2YgdGhlIHZpZXdwb3J0LiAqL1xuICBnZXRWaWV3cG9ydFNjcm9sbFBvc2l0aW9uKCk6IFZpZXdwb3J0U2Nyb2xsUG9zaXRpb24ge1xuICAgIC8vIFdoaWxlIHdlIGNhbiBnZXQgYSByZWZlcmVuY2UgdG8gdGhlIGZha2UgZG9jdW1lbnRcbiAgICAvLyBkdXJpbmcgU1NSLCBpdCBkb2Vzbid0IGhhdmUgZ2V0Qm91bmRpbmdDbGllbnRSZWN0LlxuICAgIGlmICghdGhpcy5fcGxhdGZvcm0uaXNCcm93c2VyKSB7XG4gICAgICByZXR1cm4ge3RvcDogMCwgbGVmdDogMH07XG4gICAgfVxuXG4gICAgLy8gVGhlIHRvcC1sZWZ0LWNvcm5lciBvZiB0aGUgdmlld3BvcnQgaXMgZGV0ZXJtaW5lZCBieSB0aGUgc2Nyb2xsIHBvc2l0aW9uIG9mIHRoZSBkb2N1bWVudFxuICAgIC8vIGJvZHksIG5vcm1hbGx5IGp1c3QgKHNjcm9sbExlZnQsIHNjcm9sbFRvcCkuIEhvd2V2ZXIsIENocm9tZSBhbmQgRmlyZWZveCBkaXNhZ3JlZSBhYm91dFxuICAgIC8vIHdoZXRoZXIgYGRvY3VtZW50LmJvZHlgIG9yIGBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnRgIGlzIHRoZSBzY3JvbGxlZCBlbGVtZW50LCBzbyByZWFkaW5nXG4gICAgLy8gYHNjcm9sbFRvcGAgYW5kIGBzY3JvbGxMZWZ0YCBpcyBpbmNvbnNpc3RlbnQuIEhvd2V2ZXIsIHVzaW5nIHRoZSBib3VuZGluZyByZWN0IG9mXG4gICAgLy8gYGRvY3VtZW50LmRvY3VtZW50RWxlbWVudGAgd29ya3MgY29uc2lzdGVudGx5LCB3aGVyZSB0aGUgYHRvcGAgYW5kIGBsZWZ0YCB2YWx1ZXMgd2lsbFxuICAgIC8vIGVxdWFsIG5lZ2F0aXZlIHRoZSBzY3JvbGwgcG9zaXRpb24uXG4gICAgY29uc3QgZG9jdW1lbnQgPSB0aGlzLl9kb2N1bWVudDtcbiAgICBjb25zdCB3aW5kb3cgPSB0aGlzLl9nZXRXaW5kb3coKTtcbiAgICBjb25zdCBkb2N1bWVudEVsZW1lbnQgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQhO1xuICAgIGNvbnN0IGRvY3VtZW50UmVjdCA9IGRvY3VtZW50RWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblxuICAgIGNvbnN0IHRvcCA9IC1kb2N1bWVudFJlY3QudG9wIHx8IGRvY3VtZW50LmJvZHkuc2Nyb2xsVG9wIHx8IHdpbmRvdy5zY3JvbGxZIHx8XG4gICAgICAgICAgICAgICAgIGRvY3VtZW50RWxlbWVudC5zY3JvbGxUb3AgfHwgMDtcblxuICAgIGNvbnN0IGxlZnQgPSAtZG9jdW1lbnRSZWN0LmxlZnQgfHwgZG9jdW1lbnQuYm9keS5zY3JvbGxMZWZ0IHx8IHdpbmRvdy5zY3JvbGxYIHx8XG4gICAgICAgICAgICAgICAgICBkb2N1bWVudEVsZW1lbnQuc2Nyb2xsTGVmdCB8fCAwO1xuXG4gICAgcmV0dXJuIHt0b3AsIGxlZnR9O1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYSBzdHJlYW0gdGhhdCBlbWl0cyB3aGVuZXZlciB0aGUgc2l6ZSBvZiB0aGUgdmlld3BvcnQgY2hhbmdlcy5cbiAgICogVGhpcyBzdHJlYW0gZW1pdHMgb3V0c2lkZSBvZiB0aGUgQW5ndWxhciB6b25lLlxuICAgKiBAcGFyYW0gdGhyb3R0bGVUaW1lIFRpbWUgaW4gbWlsbGlzZWNvbmRzIHRvIHRocm90dGxlIHRoZSBzdHJlYW0uXG4gICAqL1xuICBjaGFuZ2UodGhyb3R0bGVUaW1lOiBudW1iZXIgPSBERUZBVUxUX1JFU0laRV9USU1FKTogT2JzZXJ2YWJsZTxFdmVudD4ge1xuICAgIHJldHVybiB0aHJvdHRsZVRpbWUgPiAwID8gdGhpcy5fY2hhbmdlLnBpcGUoYXVkaXRUaW1lKHRocm90dGxlVGltZSkpIDogdGhpcy5fY2hhbmdlO1xuICB9XG5cbiAgLyoqIFVzZSBkZWZhdWx0VmlldyBvZiBpbmplY3RlZCBkb2N1bWVudCBpZiBhdmFpbGFibGUgb3IgZmFsbGJhY2sgdG8gZ2xvYmFsIHdpbmRvdyByZWZlcmVuY2UgKi9cbiAgcHJpdmF0ZSBfZ2V0V2luZG93KCk6IFdpbmRvdyB7XG4gICAgcmV0dXJuIHRoaXMuX2RvY3VtZW50LmRlZmF1bHRWaWV3IHx8IHdpbmRvdztcbiAgfVxuXG4gIC8qKiBVcGRhdGVzIHRoZSBjYWNoZWQgdmlld3BvcnQgc2l6ZS4gKi9cbiAgcHJpdmF0ZSBfdXBkYXRlVmlld3BvcnRTaXplKCkge1xuICAgIGNvbnN0IHdpbmRvdyA9IHRoaXMuX2dldFdpbmRvdygpO1xuICAgIHRoaXMuX3ZpZXdwb3J0U2l6ZSA9IHRoaXMuX3BsYXRmb3JtLmlzQnJvd3NlciA/XG4gICAgICAgIHt3aWR0aDogd2luZG93LmlubmVyV2lkdGgsIGhlaWdodDogd2luZG93LmlubmVySGVpZ2h0fSA6XG4gICAgICAgIHt3aWR0aDogMCwgaGVpZ2h0OiAwfTtcbiAgfVxufVxuIl19
|