UNPKG

@ngbracket/ngx-layout

Version:
191 lines 24.2 kB
/** * @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 } from '@angular/core'; import { asapScheduler, of, Subject } from 'rxjs'; import { debounceTime, distinctUntilChanged, filter, map, switchMap, takeUntil, } from 'rxjs/operators'; import { mergeAlias } from '../add-alias'; import { MediaChange } from '../media-change'; import { coerceArray } from '../utils/array'; import { sortDescendingPriority } from '../utils/sort'; import * as i0 from "@angular/core"; import * as i1 from "../breakpoints/break-point-registry"; import * as i2 from "../match-media/match-media"; import * as i3 from "../media-marshaller/print-hook"; /** * MediaObserver enables applications to listen for 1..n mediaQuery activations and to determine * if a mediaQuery is currently activated. * * Since a breakpoint change will first deactivate 1...n mediaQueries and then possibly activate * 1..n mediaQueries, the MediaObserver will debounce notifications and report ALL *activations* * in 1 event notification. The reported activations will be sorted in descending priority order. * * This class uses the BreakPoint Registry to inject alias information into the raw MediaChange * notification. For custom mediaQuery notifications, alias information will not be injected and * those fields will be ''. * * Note: Developers should note that only mediaChange activations (not de-activations) * are announced by the MediaObserver. * * @usage * * // RxJS * import { filter } from 'rxjs/operators'; * import { MediaObserver } from '@ngbracket/ngx-layout'; * * @Component({ ... }) * export class AppComponent { * status: string = ''; * * constructor(mediaObserver: MediaObserver) { * const media$ = mediaObserver.asObservable().pipe( * filter((changes: MediaChange[]) => true) // silly noop filter * ); * * media$.subscribe((changes: MediaChange[]) => { * let status = ''; * changes.forEach( change => { * status += `'${change.mqAlias}' = (${change.mediaQuery}) <br/>` ; * }); * this.status = status; * }); * * } * } */ export class MediaObserver { constructor(breakpoints, matchMedia, hook) { this.breakpoints = breakpoints; this.matchMedia = matchMedia; this.hook = hook; /** Filter MediaChange notifications for overlapping breakpoints */ this.filterOverlaps = false; this.destroyed$ = new Subject(); this._media$ = this.watchActivations(); } /** * Completes the active subject, signalling to all complete for all * MediaObserver subscribers */ ngOnDestroy() { this.destroyed$.next(); this.destroyed$.complete(); } // ************************************************ // Public Methods // ************************************************ /** * Observe changes to current activation 'list' */ asObservable() { return this._media$; } /** * Allow programmatic query to determine if one or more media query/alias match * the current viewport size. * @param value One or more media queries (or aliases) to check. * @returns Whether any of the media queries match. */ isActive(value) { const aliases = splitQueries(coerceArray(value)); return aliases.some((alias) => { const query = toMediaQuery(alias, this.breakpoints); return query !== null && this.matchMedia.isActive(query); }); } // ************************************************ // Internal Methods // ************************************************ /** * Register all the mediaQueries registered in the BreakPointRegistry * This is needed so subscribers can be auto-notified of all standard, registered * mediaQuery activations */ watchActivations() { const queries = this.breakpoints.items.map((bp) => bp.mediaQuery); return this.buildObservable(queries); } /** * Only pass/announce activations (not de-activations) * * Since multiple-mediaQueries can be activation in a cycle, * gather all current activations into a single list of changes to observers * * Inject associated (if any) alias information into the MediaChange event * - Exclude mediaQuery activations for overlapping mQs. List bounded mQ ranges only * - Exclude print activations that do not have an associated mediaQuery * * NOTE: the raw MediaChange events [from MatchMedia] do not * contain important alias information; as such this info * must be injected into the MediaChange */ buildObservable(mqList) { const hasChanges = (changes) => { const isValidQuery = (change) => change.mediaQuery.length > 0; return changes.filter(isValidQuery).length > 0; }; const excludeOverlaps = (changes) => { return !this.filterOverlaps ? changes : changes.filter((change) => { const bp = this.breakpoints.findByQuery(change.mediaQuery); return bp?.overlapping ?? true; }); }; const ignoreDuplicates = (previous, current) => { if (previous.length !== current.length) { return false; } const previousMqs = previous.map((mc) => mc.mediaQuery); const currentMqs = new Set(current.map((mc) => mc.mediaQuery)); const difference = new Set(previousMqs.filter((mq) => !currentMqs.has(mq))); return difference.size === 0; }; /** */ return this.matchMedia.observe(this.hook.withPrintQuery(mqList)).pipe(filter((change) => change.matches), debounceTime(0, asapScheduler), switchMap((_) => of(this.findAllActivations())), map(excludeOverlaps), filter(hasChanges), distinctUntilChanged(ignoreDuplicates), takeUntil(this.destroyed$)); } /** * Find all current activations and prepare single list of activations * sorted by descending priority. */ findAllActivations() { const mergeMQAlias = (change) => { const bp = this.breakpoints.findByQuery(change.mediaQuery); return mergeAlias(change, bp); }; const replaceWithPrintAlias = (change) => this.hook.isPrintEvent(change) ? this.hook.updateEvent(change) : change; return this.matchMedia.activations .map((query) => new MediaChange(true, query)) .map(replaceWithPrintAlias) .map(mergeMQAlias) .sort(sortDescendingPriority); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.0", ngImport: i0, type: MediaObserver, deps: [{ token: i1.BreakPointRegistry }, { token: i2.MatchMedia }, { token: i3.PrintHook }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.1.0", ngImport: i0, type: MediaObserver, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.0", ngImport: i0, type: MediaObserver, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: () => [{ type: i1.BreakPointRegistry }, { type: i2.MatchMedia }, { type: i3.PrintHook }] }); /** * Find associated breakpoint (if any) */ function toMediaQuery(query, locator) { const bp = locator.findByAlias(query) ?? locator.findByQuery(query); return bp?.mediaQuery ?? null; } /** * Split each query string into separate query strings if two queries are provided as comma * separated. */ function splitQueries(queries) { return queries .flatMap((query) => query.split(',')) .map((query) => query.trim()); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVkaWEtb2JzZXJ2ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9saWJzL2ZsZXgtbGF5b3V0L2NvcmUvbWVkaWEtb2JzZXJ2ZXIvbWVkaWEtb2JzZXJ2ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7OztHQU1HO0FBQ0gsT0FBTyxFQUFFLFVBQVUsRUFBYSxNQUFNLGVBQWUsQ0FBQztBQUN0RCxPQUFPLEVBQUUsYUFBYSxFQUFjLEVBQUUsRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDOUQsT0FBTyxFQUNMLFlBQVksRUFDWixvQkFBb0IsRUFDcEIsTUFBTSxFQUNOLEdBQUcsRUFDSCxTQUFTLEVBQ1QsU0FBUyxHQUNWLE1BQU0sZ0JBQWdCLENBQUM7QUFFeEIsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQU0xQyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFHOUMsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzdDLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLGVBQWUsQ0FBQzs7Ozs7QUFFdkQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0F3Q0c7QUFFSCxNQUFNLE9BQU8sYUFBYTtJQUl4QixZQUNZLFdBQStCLEVBQy9CLFVBQXNCLEVBQ3RCLElBQWU7UUFGZixnQkFBVyxHQUFYLFdBQVcsQ0FBb0I7UUFDL0IsZUFBVSxHQUFWLFVBQVUsQ0FBWTtRQUN0QixTQUFJLEdBQUosSUFBSSxDQUFXO1FBTjNCLG1FQUFtRTtRQUNuRSxtQkFBYyxHQUFHLEtBQUssQ0FBQztRQTBJTixlQUFVLEdBQUcsSUFBSSxPQUFPLEVBQVEsQ0FBQztRQW5JaEQsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztJQUN6QyxDQUFDO0lBRUQ7OztP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Q0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsSUFBSSxXQUFXLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDO2FBQzVDLEdBQUcsQ0FBQyxxQkFBcUIsQ0FBQzthQUMxQixHQUFHLENBQUMsWUFBWSxDQUFDO2FBQ2pCLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO0lBQ2xDLENBQUM7OEdBeklVLGFBQWE7a0hBQWIsYUFBYSxjQURBLE1BQU07OzJGQUNuQixhQUFhO2tCQUR6QixVQUFVO21CQUFDLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRTs7QUFnSmxDOztHQUVHO0FBQ0gsU0FBUyxZQUFZLENBQ25CLEtBQWEsRUFDYixPQUEyQjtJQUUzQixNQUFNLEVBQUUsR0FBRyxPQUFPLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxJQUFJLE9BQU8sQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDcEUsT0FBTyxFQUFFLEVBQUUsVUFBVSxJQUFJLElBQUksQ0FBQztBQUNoQyxDQUFDO0FBRUQ7OztHQUdHO0FBQ0gsU0FBUyxZQUFZLENBQUMsT0FBaUI7SUFDckMsT0FBTyxPQUFPO1NBQ1gsT0FBTyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1NBQ3BDLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7QUFDbEMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBHb29nbGUgTExDIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuaW1wb3J0IHsgSW5qZWN0YWJsZSwgT25EZXN0cm95IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBhc2FwU2NoZWR1bGVyLCBPYnNlcnZhYmxlLCBvZiwgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHtcbiAgZGVib3VuY2VUaW1lLFxuICBkaXN0aW5jdFVudGlsQ2hhbmdlZCxcbiAgZmlsdGVyLFxuICBtYXAsXG4gIHN3aXRjaE1hcCxcbiAgdGFrZVVudGlsLFxufSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7IG1lcmdlQWxpYXMgfSBmcm9tICcuLi9hZGQtYWxpYXMnO1xuaW1wb3J0IHtcbiAgQnJlYWtQb2ludFJlZ2lzdHJ5LFxuICBPcHRpb25hbEJyZWFrUG9pbnQsXG59IGZyb20gJy4uL2JyZWFrcG9pbnRzL2JyZWFrLXBvaW50LXJlZ2lzdHJ5JztcbmltcG9ydCB7IE1hdGNoTWVkaWEgfSBmcm9tICcuLi9tYXRjaC1tZWRpYS9tYXRjaC1tZWRpYSc7XG5pbXBvcnQgeyBNZWRpYUNoYW5nZSB9IGZyb20gJy4uL21lZGlhLWNoYW5nZSc7XG5pbXBvcnQgeyBQcmludEhvb2sgfSBmcm9tICcuLi9tZWRpYS1tYXJzaGFsbGVyL3ByaW50LWhvb2snO1xuXG5pbXBvcnQgeyBjb2VyY2VBcnJheSB9IGZyb20gJy4uL3V0aWxzL2FycmF5JztcbmltcG9ydCB7IHNvcnREZXNjZW5kaW5nUHJpb3JpdHkgfSBmcm9tICcuLi91dGlscy9zb3J0JztcblxuLyoqXG4gKiBNZWRpYU9ic2VydmVyIGVuYWJsZXMgYXBwbGljYXRpb25zIHRvIGxpc3RlbiBmb3IgMS4ubiBtZWRpYVF1ZXJ5IGFjdGl2YXRpb25zIGFuZCB0byBkZXRlcm1pbmVcbiAqIGlmIGEgbWVkaWFRdWVyeSBpcyBjdXJyZW50bHkgYWN0aXZhdGVkLlxuICpcbiAqIFNpbmNlIGEgYnJlYWtwb2ludCBjaGFuZ2Ugd2lsbCBmaXJzdCBkZWFjdGl2YXRlIDEuLi5uIG1lZGlhUXVlcmllcyBhbmQgdGhlbiBwb3NzaWJseSBhY3RpdmF0ZVxuICogMS4ubiBtZWRpYVF1ZXJpZXMsIHRoZSBNZWRpYU9ic2VydmVyIHdpbGwgZGVib3VuY2Ugbm90aWZpY2F0aW9ucyBhbmQgcmVwb3J0IEFMTCAqYWN0aXZhdGlvbnMqXG4gKiBpbiAxIGV2ZW50IG5vdGlmaWNhdGlvbi4gVGhlIHJlcG9ydGVkIGFjdGl2YXRpb25zIHdpbGwgYmUgc29ydGVkIGluIGRlc2NlbmRpbmcgcHJpb3JpdHkgb3JkZXIuXG4gKlxuICogVGhpcyBjbGFzcyB1c2VzIHRoZSBCcmVha1BvaW50IFJlZ2lzdHJ5IHRvIGluamVjdCBhbGlhcyBpbmZvcm1hdGlvbiBpbnRvIHRoZSByYXcgTWVkaWFDaGFuZ2VcbiAqIG5vdGlmaWNhdGlvbi4gRm9yIGN1c3RvbSBtZWRpYVF1ZXJ5IG5vdGlmaWNhdGlvbnMsIGFsaWFzIGluZm9ybWF0aW9uIHdpbGwgbm90IGJlIGluamVjdGVkIGFuZFxuICogdGhvc2UgZmllbGRzIHdpbGwgYmUgJycuXG4gKlxuICogTm90ZTogRGV2ZWxvcGVycyBzaG91bGQgbm90ZSB0aGF0IG9ubHkgbWVkaWFDaGFuZ2UgYWN0aXZhdGlvbnMgKG5vdCBkZS1hY3RpdmF0aW9ucylcbiAqICAgICAgIGFyZSBhbm5vdW5jZWQgYnkgdGhlIE1lZGlhT2JzZXJ2ZXIuXG4gKlxuICogIEB1c2FnZVxuICpcbiAqICAvLyBSeEpTXG4gKiAgaW1wb3J0IHsgZmlsdGVyIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuICogIGltcG9ydCB7IE1lZGlhT2JzZXJ2ZXIgfSBmcm9tICdAbmdicmFja2V0L25neC1sYXlvdXQnO1xuICpcbiAqICBAQ29tcG9uZW50KHsgLi4uIH0pXG4gKiAgZXhwb3J0IGNsYXNzIEFwcENvbXBvbmVudCB7XG4gKiAgICBzdGF0dXM6IHN0cmluZyA9ICcnO1xuICpcbiAqICAgIGNvbnN0cnVjdG9yKG1lZGlhT2JzZXJ2ZXI6IE1lZGlhT2JzZXJ2ZXIpIHtcbiAqICAgICAgY29uc3QgbWVkaWEkID0gbWVkaWFPYnNlcnZlci5hc09ic2VydmFibGUoKS5waXBlKFxuICogICAgICAgIGZpbHRlcigoY2hhbmdlczogTWVkaWFDaGFuZ2VbXSkgPT4gdHJ1ZSkgICAvLyBzaWxseSBub29wIGZpbHRlclxuICogICAgICApO1xuICpcbiAqICAgICAgbWVkaWEkLnN1YnNjcmliZSgoY2hhbmdlczogTWVkaWFDaGFuZ2VbXSkgPT4ge1xuICogICAgICAgIGxldCBzdGF0dXMgPSAnJztcbiAqICAgICAgICBjaGFuZ2VzLmZvckVhY2goIGNoYW5nZSA9PiB7XG4gKiAgICAgICAgICBzdGF0dXMgKz0gYCcke2NoYW5nZS5tcUFsaWFzfScgPSAoJHtjaGFuZ2UubWVkaWFRdWVyeX0pIDxici8+YCA7XG4gKiAgICAgICAgfSk7XG4gKiAgICAgICAgdGhpcy5zdGF0dXMgPSBzdGF0dXM7XG4gKiAgICAgfSk7XG4gKlxuICogICAgfVxuICogIH1cbiAqL1xuQEluamVjdGFibGUoeyBwcm92aWRlZEluOiAncm9vdCcgfSlcbmV4cG9ydCBjbGFzcyBNZWRpYU9ic2VydmVyIGltcGxlbWVudHMgT25EZXN0cm95IHtcbiAgLyoqIEZpbHRlciBNZWRpYUNoYW5nZSBub3RpZmljYXRpb25zIGZvciBvdmVybGFwcGluZyBicmVha3BvaW50cyAqL1xuICBmaWx0ZXJPdmVybGFwcyA9IGZhbHNlO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByb3RlY3RlZCBicmVha3BvaW50czogQnJlYWtQb2ludFJlZ2lzdHJ5LFxuICAgIHByb3RlY3RlZCBtYXRjaE1lZGlhOiBNYXRjaE1lZGlhLFxuICAgIHByb3RlY3RlZCBob29rOiBQcmludEhvb2tcbiAgKSB7XG4gICAgdGhpcy5fbWVkaWEkID0gdGhpcy53YXRjaEFjdGl2YXRpb25zKCk7XG4gIH1cblxuICAvKipcbiAgICogQ29tcGxldGVzIHRoZSBhY3RpdmUgc3ViamVjdCwgc2lnbmFsbGluZyB0byBhbGwgY29tcGxldGUgZm9yIGFsbFxuICAgKiBNZWRpYU9ic2VydmVyIHN1YnNjcmliZXJzXG4gICAqL1xuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLmRlc3Ryb3llZCQubmV4dCgpO1xuICAgIHRoaXMuZGVzdHJveWVkJC5jb21wbGV0ZSgpO1xuICB9XG5cbiAgLy8gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG4gIC8vIFB1YmxpYyBNZXRob2RzXG4gIC8vICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuXG4gIC8qKlxuICAgKiBPYnNlcnZlIGNoYW5nZXMgdG8gY3VycmVudCBhY3RpdmF0aW9uICdsaXN0J1xuICAgKi9cbiAgYXNPYnNlcnZhYmxlKCk6IE9ic2VydmFibGU8TWVkaWFDaGFuZ2VbXT4ge1xuICAgIHJldHVybiB0aGlzLl9tZWRpYSQ7XG4gIH1cblxuICAvKipcbiAgICogQWxsb3cgcHJvZ3JhbW1hdGljIHF1ZXJ5IHRvIGRldGVybWluZSBpZiBvbmUgb3IgbW9yZSBtZWRpYSBxdWVyeS9hbGlhcyBtYXRjaFxuICAgKiB0aGUgY3VycmVudCB2aWV3cG9ydCBzaXplLlxuICAgKiBAcGFyYW0gdmFsdWUgT25lIG9yIG1vcmUgbWVkaWEgcXVlcmllcyAob3IgYWxpYXNlcykgdG8gY2hlY2suXG4gICAqIEByZXR1cm5zIFdoZXRoZXIgYW55IG9mIHRoZSBtZWRpYSBxdWVyaWVzIG1hdGNoLlxuICAgKi9cbiAgaXNBY3RpdmUodmFsdWU6IHN0cmluZyB8IHN0cmluZ1tdKTogYm9vbGVhbiB7XG4gICAgY29uc3QgYWxpYXNlcyA9IHNwbGl0UXVlcmllcyhjb2VyY2VBcnJheSh2YWx1ZSkpO1xuICAgIHJldHVybiBhbGlhc2VzLnNvbWUoKGFsaWFzKSA9PiB7XG4gICAgICBjb25zdCBxdWVyeSA9IHRvTWVkaWFRdWVyeShhbGlhcywgdGhpcy5icmVha3BvaW50cyk7XG4gICAgICByZXR1cm4gcXVlcnkgIT09IG51bGwgJiYgdGhpcy5tYXRjaE1lZGlhLmlzQWN0aXZlKHF1ZXJ5KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8vICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuICAvLyBJbnRlcm5hbCBNZXRob2RzXG4gIC8vICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxuXG4gIC8qKlxuICAgKiBSZWdpc3RlciBhbGwgdGhlIG1lZGlhUXVlcmllcyByZWdpc3RlcmVkIGluIHRoZSBCcmVha1BvaW50UmVnaXN0cnlcbiAgICogVGhpcyBpcyBuZWVkZWQgc28gc3Vic2NyaWJlcnMgY2FuIGJlIGF1dG8tbm90aWZpZWQgb2YgYWxsIHN0YW5kYXJkLCByZWdpc3RlcmVkXG4gICAqIG1lZGlhUXVlcnkgYWN0aXZhdGlvbnNcbiAgICovXG4gIHByaXZhdGUgd2F0Y2hBY3RpdmF0aW9ucygpIHtcbiAgICBjb25zdCBxdWVyaWVzID0gdGhpcy5icmVha3BvaW50cy5pdGVtcy5tYXAoKGJwKSA9PiBicC5tZWRpYVF1ZXJ5KTtcbiAgICByZXR1cm4gdGhpcy5idWlsZE9ic2VydmFibGUocXVlcmllcyk7XG4gIH1cblxuICAvKipcbiAgICogT25seSBwYXNzL2Fubm91bmNlIGFjdGl2YXRpb25zIChub3QgZGUtYWN0aXZhdGlvbnMpXG4gICAqXG4gICAqIFNpbmNlIG11bHRpcGxlLW1lZGlhUXVlcmllcyBjYW4gYmUgYWN0aXZhdGlvbiBpbiBhIGN5Y2xlLFxuICAgKiBnYXRoZXIgYWxsIGN1cnJlbnQgYWN0aXZhdGlvbnMgaW50byBhIHNpbmdsZSBsaXN0IG9mIGNoYW5nZXMgdG8gb2JzZXJ2ZXJzXG4gICAqXG4gICAqIEluamVjdCBhc3NvY2lhdGVkIChpZiBhbnkpIGFsaWFzIGluZm9ybWF0aW9uIGludG8gdGhlIE1lZGlhQ2hhbmdlIGV2ZW50XG4gICAqIC0gRXhjbHVkZSBtZWRpYVF1ZXJ5IGFjdGl2YXRpb25zIGZvciBvdmVybGFwcGluZyBtUXMuIExpc3QgYm91bmRlZCBtUSByYW5nZXMgb25seVxuICAgKiAtIEV4Y2x1ZGUgcHJpbnQgYWN0aXZhdGlvbnMgdGhhdCBkbyBub3QgaGF2ZSBhbiBhc3NvY2lhdGVkIG1lZGlhUXVlcnlcbiAgICpcbiAgICogTk9URTogdGhlIHJhdyBNZWRpYUNoYW5nZSBldmVudHMgW2Zyb20gTWF0Y2hNZWRpYV0gZG8gbm90XG4gICAqICAgICAgIGNvbnRhaW4gaW1wb3J0YW50IGFsaWFzIGluZm9ybWF0aW9uOyBhcyBzdWNoIHRoaXMgaW5mb1xuICAgKiAgICAgICBtdXN0IGJlIGluamVjdGVkIGludG8gdGhlIE1lZGlhQ2hhbmdlXG4gICAqL1xuICBwcml2YXRlIGJ1aWxkT2JzZXJ2YWJsZShtcUxpc3Q6IHN0cmluZ1tdKTogT2JzZXJ2YWJsZTxNZWRpYUNoYW5nZVtdPiB7XG4gICAgY29uc3QgaGFzQ2hhbmdlcyA9IChjaGFuZ2VzOiBNZWRpYUNoYW5nZVtdKSA9PiB7XG4gICAgICBjb25zdCBpc1ZhbGlkUXVlcnkgPSAoY2hhbmdlOiBNZWRpYUNoYW5nZSkgPT5cbiAgICAgICAgY2hhbmdlLm1lZGlhUXVlcnkubGVuZ3RoID4gMDtcbiAgICAgIHJldHVybiBjaGFuZ2VzLmZpbHRlcihpc1ZhbGlkUXVlcnkpLmxlbmd0aCA+IDA7XG4gICAgfTtcbiAgICBjb25zdCBleGNsdWRlT3ZlcmxhcHMgPSAoY2hhbmdlczogTWVkaWFDaGFuZ2VbXSkgPT4ge1xuICAgICAgcmV0dXJuICF0aGlzLmZpbHRlck92ZXJsYXBzXG4gICAgICAgID8gY2hhbmdlc1xuICAgICAgICA6IGNoYW5nZXMuZmlsdGVyKChjaGFuZ2UpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGJwID0gdGhpcy5icmVha3BvaW50cy5maW5kQnlRdWVyeShjaGFuZ2UubWVkaWFRdWVyeSk7XG4gICAgICAgICAgICByZXR1cm4gYnA/Lm92ZXJsYXBwaW5nID8/IHRydWU7XG4gICAgICAgICAgfSk7XG4gICAgfTtcbiAgICBjb25zdCBpZ25vcmVEdXBsaWNhdGVzID0gKFxuICAgICAgcHJldmlvdXM6IE1lZGlhQ2hhbmdlW10sXG4gICAgICBjdXJyZW50OiBNZWRpYUNoYW5nZVtdXG4gICAgKTogYm9vbGVhbiA9PiB7XG4gICAgICBpZiAocHJldmlvdXMubGVuZ3RoICE9PSBjdXJyZW50Lmxlbmd0aCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHByZXZpb3VzTXFzID0gcHJldmlvdXMubWFwKChtYykgPT4gbWMubWVkaWFRdWVyeSk7XG4gICAgICBjb25zdCBjdXJyZW50TXFzID0gbmV3IFNldChjdXJyZW50Lm1hcCgobWMpID0+IG1jLm1lZGlhUXVlcnkpKTtcbiAgICAgIGNvbnN0IGRpZmZlcmVuY2UgPSBuZXcgU2V0KFxuICAgICAgICBwcmV2aW91c01xcy5maWx0ZXIoKG1xKSA9PiAhY3VycmVudE1xcy5oYXMobXEpKVxuICAgICAgKTtcblxuICAgICAgcmV0dXJuIGRpZmZlcmVuY2Uuc2l6ZSA9PT0gMDtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICovXG4gICAgcmV0dXJuIHRoaXMubWF0Y2hNZWRpYS5vYnNlcnZlKHRoaXMuaG9vay53aXRoUHJpbnRRdWVyeShtcUxpc3QpKS5waXBlKFxuICAgICAgZmlsdGVyKChjaGFuZ2U6IE1lZGlhQ2hhbmdlKSA9PiBjaGFuZ2UubWF0Y2hlcyksXG4gICAgICBkZWJvdW5jZVRpbWUoMCwgYXNhcFNjaGVkdWxlciksXG4gICAgICBzd2l0Y2hNYXAoKF8pID0+IG9mKHRoaXMuZmluZEFsbEFjdGl2YXRpb25zKCkpKSxcbiAgICAgIG1hcChleGNsdWRlT3ZlcmxhcHMpLFxuICAgICAgZmlsdGVyKGhhc0NoYW5nZXMpLFxuICAgICAgZGlzdGluY3RVbnRpbENoYW5nZWQoaWdub3JlRHVwbGljYXRlcyksXG4gICAgICB0YWtlVW50aWwodGhpcy5kZXN0cm95ZWQkKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogRmluZCBhbGwgY3VycmVudCBhY3RpdmF0aW9ucyBhbmQgcHJlcGFyZSBzaW5nbGUgbGlzdCBvZiBhY3RpdmF0aW9uc1xuICAgKiBzb3J0ZWQgYnkgZGVzY2VuZGluZyBwcmlvcml0eS5cbiAgICovXG4gIHByaXZhdGUgZmluZEFsbEFjdGl2YXRpb25zKCk6IE1lZGlhQ2hhbmdlW10ge1xuICAgIGNvbnN0IG1lcmdlTVFBbGlhcyA9IChjaGFuZ2U6IE1lZGlhQ2hhbmdlKSA9PiB7XG4gICAgICBjb25zdCBicDogT3B0aW9uYWxCcmVha1BvaW50ID0gdGhpcy5icmVha3BvaW50cy5maW5kQnlRdWVyeShcbiAgICAgICAgY2hhbmdlLm1lZGlhUXVlcnlcbiAgICAgICk7XG4gICAgICByZXR1cm4gbWVyZ2VBbGlhcyhjaGFuZ2UsIGJwKTtcbiAgICB9O1xuICAgIGNvbnN0IHJlcGxhY2VXaXRoUHJpbnRBbGlhcyA9IChjaGFuZ2U6IE1lZGlhQ2hhbmdlKSA9PlxuICAgICAgdGhpcy5ob29rLmlzUHJpbnRFdmVudChjaGFuZ2UpID8gdGhpcy5ob29rLnVwZGF0ZUV2ZW50KGNoYW5nZSkgOiBjaGFuZ2U7XG5cbiAgICByZXR1cm4gdGhpcy5tYXRjaE1lZGlhLmFjdGl2YXRpb25zXG4gICAgICAubWFwKChxdWVyeSkgPT4gbmV3IE1lZGlhQ2hhbmdlKHRydWUsIHF1ZXJ5KSlcbiAgICAgIC5tYXAocmVwbGFjZVdpdGhQcmludEFsaWFzKVxuICAgICAgLm1hcChtZXJnZU1RQWxpYXMpXG4gICAgICAuc29ydChzb3J0RGVzY2VuZGluZ1ByaW9yaXR5KTtcbiAgfVxuXG4gIHByaXZhdGUgcmVhZG9ubHkgX21lZGlhJDogT2JzZXJ2YWJsZTxNZWRpYUNoYW5nZVtdPjtcbiAgcHJpdmF0ZSByZWFkb25seSBkZXN0cm95ZWQkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcbn1cblxuLyoqXG4gKiBGaW5kIGFzc29jaWF0ZWQgYnJlYWtwb2ludCAoaWYgYW55KVxuICovXG5mdW5jdGlvbiB0b01lZGlhUXVlcnkoXG4gIHF1ZXJ5OiBzdHJpbmcsXG4gIGxvY2F0b3I6IEJyZWFrUG9pbnRSZWdpc3RyeVxuKTogc3RyaW5nIHwgbnVsbCB7XG4gIGNvbnN0IGJwID0gbG9jYXRvci5maW5kQnlBbGlhcyhxdWVyeSkgPz8gbG9jYXRvci5maW5kQnlRdWVyeShxdWVyeSk7XG4gIHJldHVybiBicD8ubWVkaWFRdWVyeSA/PyBudWxsO1xufVxuXG4vKipcbiAqIFNwbGl0IGVhY2ggcXVlcnkgc3RyaW5nIGludG8gc2VwYXJhdGUgcXVlcnkgc3RyaW5ncyBpZiB0d28gcXVlcmllcyBhcmUgcHJvdmlkZWQgYXMgY29tbWFcbiAqIHNlcGFyYXRlZC5cbiAqL1xuZnVuY3Rpb24gc3BsaXRRdWVyaWVzKHF1ZXJpZXM6IHN0cmluZ1tdKTogc3RyaW5nW10ge1xuICByZXR1cm4gcXVlcmllc1xuICAgIC5mbGF0TWFwKChxdWVyeSkgPT4gcXVlcnkuc3BsaXQoJywnKSlcbiAgICAubWFwKChxdWVyeSkgPT4gcXVlcnkudHJpbSgpKTtcbn1cbiJdfQ==