UNPKG

@antischematic/angular-state-library

Version:
133 lines 20.2 kB
import { DOCUMENT } from "@angular/common"; import { inject, Injectable } from "@angular/core"; import { BehaviorSubject, debounce, EMPTY, filter, finalize, fromEvent, interval, merge, of, ReplaySubject, retry, share, startWith, Subject, switchAll, switchMap, takeUntil, tap, throttle, timer, } from "rxjs"; import { observeInZone } from "./utils"; import * as i0 from "@angular/core"; function onVisible(document, refCount) { return toggle(refCount, fromEvent(document, "visibilitychange").pipe(filter(() => document.visibilityState === "visible"))); } function onReconnect(document, refCount) { const window = document.defaultView; if (window) { return toggle(refCount, fromEvent(window, "online")); } else { return EMPTY; } } function toggle(refCount, source) { const delay = refCount.pipe(filter((count) => count > 0)); const resume = of(null); return source.pipe(debounce(() => refCount.value > 0 ? resume : delay)); } export class ResourceManager { constructor() { this.cache = new Map(); this.document = inject(DOCUMENT); } query(source, options) { const key = this.keygen(options.key); const { cache, document } = this; if (cache.has(key)) { const { resource, fetch, errors } = cache.get(key); if (options.refreshIfStale !== false) { fetch.next(source); } return merge(resource, errors); } const cancel = new Subject(); const invalidate = new Subject(); const fetch = new BehaviorSubject(source); const refCount = new BehaviorSubject(0); const invalidators = [fetch]; if (options.refreshOnFocus) { invalidators.push(onVisible(document, refCount)); } if (options.refreshOnReconnect) { invalidators.push(onReconnect(document, refCount)); } if (options.refreshInterval) { const nativeInterval = observeInZone(interval(options.refreshInterval), Zone.root); invalidators.push(toggle(refCount, nativeInterval)); } const errors = new Subject(); const reload = merge(...invalidators).pipe(switchMap(() => fetch.pipe(takeUntil(cancel))), takeUntil(cancel), throttle(() => observeInZone(timer(options.staleTime ?? 0), Zone.root))); const resource = invalidate.pipe(startWith(null), switchMap(() => reload), switchAll(), retry({ resetOnSuccess: true, delay: (error, retryCount) => { fetch.next(void 0); errors.error(new QueryError(error, retryCount)); return resource; } }), share({ connector: () => new ReplaySubject(1, options.cacheTime ?? Infinity), resetOnError: false, resetOnComplete: false, resetOnRefCountZero: false }), tap({ subscribe: () => refCount.next(refCount.value + 1), unsubscribe: () => refCount.next(refCount.value - 1) })); cache.set(key, { resource, errors, fetch, cancel, invalidate, source, options }); return merge(resource, errors); } mutate(source, options) { const keys = options.invalidate ? Array.isArray(options.invalidate[0]) ? options.invalidate.map(this.keygen) : [this.keygen(options.invalidate)] : []; for (const key of keys) { this.invalidate(key, true); } return source.pipe(finalize(() => { for (const key of keys) { this.invalidate(key, false); } })); } revalidate(key) { this.invalidate(this.keygen(key), true); this.invalidate(this.keygen(key), false); } keygen(seed) { return JSON.stringify(seed); } invalidate(key, doCancel) { for (const [matchKey, { invalidate, cancel }] of this.cache) { if (matchKey.startsWith(key.slice(0, key.length - 2))) { if (doCancel) { cancel.next(); } else { invalidate.next(); } } } } } ResourceManager.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: ResourceManager, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); ResourceManager.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: ResourceManager, providedIn: "root" }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: ResourceManager, decorators: [{ type: Injectable, args: [{ providedIn: "root" }] }] }); export function useQuery(options) { const resource = options.resource ?? inject(ResourceManager); return source => resource.query(source, options); } export function useMutation(options) { const resource = options.resource ?? inject(ResourceManager); return source => resource.mutate(source, options); } export class QueryError { constructor(error, retryCount) { this.error = error; this.retryCount = retryCount; } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Byb2plY3RzL2NvcmUvc3JjL2RhdGEudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFDLFFBQVEsRUFBQyxNQUFNLGlCQUFpQixDQUFDO0FBQ3pDLE9BQU8sRUFBQyxNQUFNLEVBQUUsVUFBVSxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBQ2pELE9BQU8sRUFDSixlQUFlLEVBQ2YsUUFBUSxFQUNSLEtBQUssRUFDTCxNQUFNLEVBQ04sUUFBUSxFQUNSLFNBQVMsRUFDVCxRQUFRLEVBQ1IsS0FBSyxFQUdMLEVBQUUsRUFDRixhQUFhLEVBQ2IsS0FBSyxFQUNMLEtBQUssRUFDTCxTQUFTLEVBQ1QsT0FBTyxFQUNQLFNBQVMsRUFDVCxTQUFTLEVBQ1QsU0FBUyxFQUNULEdBQUcsRUFDSCxRQUFRLEVBQ1IsS0FBSyxHQUNQLE1BQU0sTUFBTSxDQUFDO0FBQ2QsT0FBTyxFQUFDLGFBQWEsRUFBQyxNQUFNLFNBQVMsQ0FBQzs7QUFrQnRDLFNBQVMsU0FBUyxDQUFDLFFBQWtCLEVBQUUsUUFBOEI7SUFDbEUsT0FBTyxNQUFNLENBQUMsUUFBUSxFQUFFLFNBQVMsQ0FBQyxRQUFRLEVBQUUsa0JBQWtCLENBQUMsQ0FBQyxJQUFJLENBQ2pFLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxRQUFRLENBQUMsZUFBZSxLQUFLLFNBQVMsQ0FBQyxDQUN0RCxDQUFDLENBQUE7QUFDTCxDQUFDO0FBRUQsU0FBUyxXQUFXLENBQUMsUUFBa0IsRUFBRSxRQUE4QjtJQUNwRSxNQUFNLE1BQU0sR0FBRyxRQUFRLENBQUMsV0FBVyxDQUFBO0lBQ25DLElBQUksTUFBTSxFQUFFO1FBQ1QsT0FBTyxNQUFNLENBQUMsUUFBUSxFQUFFLFNBQVMsQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQTtLQUN0RDtTQUFNO1FBQ0osT0FBTyxLQUFLLENBQUE7S0FDZDtBQUNKLENBQUM7QUFFRCxTQUFTLE1BQU0sQ0FBQyxRQUFpQyxFQUFFLE1BQXVCO0lBQ3ZFLE1BQU0sS0FBSyxHQUFHLFFBQVEsQ0FBQyxJQUFJLENBQ3hCLE1BQU0sQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUM5QixDQUFBO0lBQ0QsTUFBTSxNQUFNLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFBO0lBQ3ZCLE9BQU8sTUFBTSxDQUFDLElBQUksQ0FDZixRQUFRLENBQUMsR0FBRyxFQUFFLENBQUMsUUFBUSxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQ3JELENBQUE7QUFDSixDQUFDO0FBR0QsTUFBTSxPQUFPLGVBQWU7SUFENUI7UUFFRyxVQUFLLEdBQUcsSUFBSSxHQUFHLEVBQUUsQ0FBQTtRQUNqQixhQUFRLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFBO0tBaUg3QjtJQS9HRSxLQUFLLENBQUksTUFBcUIsRUFBRSxPQUFxQjtRQUNsRCxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQTtRQUNwQyxNQUFNLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxHQUFHLElBQUksQ0FBQTtRQUVoQyxJQUFJLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUU7WUFDakIsTUFBTSxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLEdBQUcsS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQTtZQUNsRCxJQUFJLE9BQU8sQ0FBQyxjQUFjLEtBQUssS0FBSyxFQUFFO2dCQUNuQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFBO2FBQ3BCO1lBQ0QsT0FBTyxLQUFLLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBa0IsQ0FBQTtTQUNqRDtRQUVELE1BQU0sTUFBTSxHQUFHLElBQUksT0FBTyxFQUFRLENBQUE7UUFDbEMsTUFBTSxVQUFVLEdBQUcsSUFBSSxPQUFPLEVBQWlCLENBQUE7UUFDL0MsTUFBTSxLQUFLLEdBQUcsSUFBSSxlQUFlLENBQWdCLE1BQU0sQ0FBQyxDQUFBO1FBQ3hELE1BQU0sUUFBUSxHQUFHLElBQUksZUFBZSxDQUFDLENBQUMsQ0FBQyxDQUFBO1FBQ3ZDLE1BQU0sWUFBWSxHQUFHLENBQUMsS0FBSyxDQUFzQixDQUFBO1FBRWpELElBQUksT0FBTyxDQUFDLGNBQWMsRUFBRTtZQUN6QixZQUFZLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQTtTQUNsRDtRQUVELElBQUksT0FBTyxDQUFDLGtCQUFrQixFQUFFO1lBQzdCLFlBQVksQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFBO1NBQ3BEO1FBRUQsSUFBSSxPQUFPLENBQUMsZUFBZSxFQUFFO1lBQzFCLE1BQU0sY0FBYyxHQUFHLGFBQWEsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLGVBQWUsQ0FBQyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQTtZQUNsRixZQUFZLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsY0FBYyxDQUFDLENBQUMsQ0FBQTtTQUNyRDtRQUNELE1BQU0sTUFBTSxHQUFHLElBQUksT0FBTyxFQUFTLENBQUE7UUFFbkMsTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLEdBQUcsWUFBWSxDQUFDLENBQUMsSUFBSSxDQUN2QyxTQUFTLENBQUMsR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDLElBQUksQ0FDdkIsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUNuQixDQUFDLEVBQ0YsU0FBUyxDQUFDLE1BQU0sQ0FBQyxFQUNqQixRQUFRLENBQUMsR0FBRyxFQUFFLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsU0FBUyxJQUFJLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUN6RSxDQUFBO1FBRUQsTUFBTSxRQUFRLEdBQWtCLFVBQVUsQ0FBQyxJQUFJLENBQzVDLFNBQVMsQ0FBQyxJQUFJLENBQUMsRUFDZixTQUFTLENBQUMsR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDLEVBQ3ZCLFNBQVMsRUFBRSxFQUNYLEtBQUssQ0FBQztZQUNILGNBQWMsRUFBRSxJQUFJO1lBQ3BCLEtBQUssRUFBRSxDQUFDLEtBQUssRUFBRSxVQUFVLEVBQUUsRUFBRTtnQkFDMUIsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQVEsQ0FBQyxDQUFBO2dCQUN6QixNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksVUFBVSxDQUFDLEtBQUssRUFBRSxVQUFVLENBQUMsQ0FBQyxDQUFBO2dCQUMvQyxPQUFPLFFBQVEsQ0FBQTtZQUNsQixDQUFDO1NBQ0gsQ0FBQyxFQUNGLEtBQUssQ0FBQztZQUNILFNBQVMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLGFBQWEsQ0FBQyxDQUFDLEVBQUUsT0FBTyxDQUFDLFNBQVMsSUFBSSxRQUFRLENBQUM7WUFDcEUsWUFBWSxFQUFFLEtBQUs7WUFDbkIsZUFBZSxFQUFFLEtBQUs7WUFDdEIsbUJBQW1CLEVBQUUsS0FBSztTQUM1QixDQUFDLEVBQ0YsR0FBRyxDQUFDO1lBQ0QsU0FBUyxFQUFFLEdBQUcsRUFBRSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUM7WUFDbEQsV0FBVyxFQUFFLEdBQUcsRUFBRSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUM7U0FDdEQsQ0FBQyxDQUNKLENBQUE7UUFFRCxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRTtZQUNaLFFBQVE7WUFDUixNQUFNO1lBQ04sS0FBSztZQUNMLE1BQU07WUFDTixVQUFVO1lBQ1YsTUFBTTtZQUNOLE9BQU87U0FDVCxDQUFDLENBQUE7UUFFRixPQUFPLEtBQUssQ0FBQyxRQUFRLEVBQUUsTUFBTSxDQUFDLENBQUE7SUFDakMsQ0FBQztJQUVELE1BQU0sQ0FBSSxNQUFxQixFQUFFLE9BQXNCO1FBQ3BELE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBRSxPQUFPLENBQUMsVUFBMEIsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQTtRQUN0SyxLQUFLLE1BQU0sR0FBRyxJQUFJLElBQUksRUFBRTtZQUNyQixJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQTtTQUM1QjtRQUNELE9BQU8sTUFBTSxDQUFDLElBQUksQ0FDZixRQUFRLENBQUMsR0FBRyxFQUFFO1lBQ1gsS0FBSyxNQUFNLEdBQUcsSUFBSSxJQUFJLEVBQUU7Z0JBQ3JCLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFBO2FBQzdCO1FBQ0osQ0FBQyxDQUFDLENBQ0osQ0FBQTtJQUNKLENBQUM7SUFFRCxVQUFVLENBQUMsR0FBVTtRQUNsQixJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUE7UUFDdkMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFBO0lBQzNDLENBQUM7SUFFTyxNQUFNLENBQUMsSUFBZTtRQUMzQixPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUE7SUFDOUIsQ0FBQztJQUVPLFVBQVUsQ0FBQyxHQUFXLEVBQUUsUUFBaUI7UUFDOUMsS0FBSyxNQUFNLENBQUMsUUFBUSxFQUFFLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxDQUFDLElBQUksSUFBSSxDQUFDLEtBQUssRUFBRTtZQUMxRCxJQUFJLFFBQVEsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFO2dCQUNwRCxJQUFJLFFBQVEsRUFBRTtvQkFDWCxNQUFNLENBQUMsSUFBSSxFQUFFLENBQUE7aUJBQ2Y7cUJBQU07b0JBQ0osVUFBVSxDQUFDLElBQUksRUFBRSxDQUFBO2lCQUNuQjthQUNIO1NBQ0g7SUFDSixDQUFDOzs0R0FsSFMsZUFBZTtnSEFBZixlQUFlLGNBREYsTUFBTTsyRkFDbkIsZUFBZTtrQkFEM0IsVUFBVTttQkFBQyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUU7O0FBc0hsQyxNQUFNLFVBQVUsUUFBUSxDQUFJLE9BQXdCO0lBQ2pELE1BQU0sUUFBUSxHQUFHLE9BQU8sQ0FBQyxRQUFRLElBQUksTUFBTSxDQUFDLGVBQWUsQ0FBQyxDQUFBO0lBQzVELE9BQU8sTUFBTSxDQUFDLEVBQUUsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxPQUFPLENBQUMsQ0FBQTtBQUNuRCxDQUFDO0FBRUQsTUFBTSxVQUFVLFdBQVcsQ0FBSSxPQUFzQjtJQUNsRCxNQUFNLFFBQVEsR0FBRyxPQUFPLENBQUMsUUFBUSxJQUFJLE1BQU0sQ0FBQyxlQUFlLENBQUMsQ0FBQTtJQUM1RCxPQUFPLE1BQU0sQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsT0FBTyxDQUFDLENBQUE7QUFDcEQsQ0FBQztBQUVELE1BQU0sT0FBTyxVQUFVO0lBQ3BCLFlBQW1CLEtBQWMsRUFBUyxVQUFtQjtRQUExQyxVQUFLLEdBQUwsS0FBSyxDQUFTO1FBQVMsZUFBVSxHQUFWLFVBQVUsQ0FBUztJQUFHLENBQUM7Q0FDbkUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0RPQ1VNRU5UfSBmcm9tIFwiQGFuZ3VsYXIvY29tbW9uXCI7XG5pbXBvcnQge2luamVjdCwgSW5qZWN0YWJsZX0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7XG4gICBCZWhhdmlvclN1YmplY3QsXG4gICBkZWJvdW5jZSxcbiAgIEVNUFRZLFxuICAgZmlsdGVyLFxuICAgZmluYWxpemUsXG4gICBmcm9tRXZlbnQsXG4gICBpbnRlcnZhbCxcbiAgIG1lcmdlLFxuICAgTW9ub1R5cGVPcGVyYXRvckZ1bmN0aW9uLFxuICAgT2JzZXJ2YWJsZSxcbiAgIG9mLFxuICAgUmVwbGF5U3ViamVjdCxcbiAgIHJldHJ5LFxuICAgc2hhcmUsXG4gICBzdGFydFdpdGgsXG4gICBTdWJqZWN0LFxuICAgc3dpdGNoQWxsLFxuICAgc3dpdGNoTWFwLFxuICAgdGFrZVVudGlsLFxuICAgdGFwLFxuICAgdGhyb3R0bGUsXG4gICB0aW1lcixcbn0gZnJvbSBcInJ4anNcIjtcbmltcG9ydCB7b2JzZXJ2ZUluWm9uZX0gZnJvbSBcIi4vdXRpbHNcIjtcblxuZXhwb3J0IGludGVyZmFjZSBRdWVyeU9wdGlvbnM8VCA9IGFueT4ge1xuICAga2V5OiB1bmtub3duW11cbiAgIHJlZnJlc2hJbnRlcnZhbD86IG51bWJlclxuICAgcmVmcmVzaE9uRm9jdXM/OiBib29sZWFuXG4gICByZWZyZXNoT25SZWNvbm5lY3Q/OiBib29sZWFuXG4gICByZWZyZXNoSWZTdGFsZT86IGJvb2xlYW5cbiAgIHN0YWxlVGltZT86IG51bWJlclxuICAgY2FjaGVUaW1lPzogbnVtYmVyXG4gICByZXNvdXJjZT86IFJlc291cmNlTWFuYWdlclxufVxuXG5leHBvcnQgaW50ZXJmYWNlIE11dGF0ZU9wdGlvbnMge1xuICAgaW52YWxpZGF0ZT86IHVua25vd25bXSB8IHVua25vd25bXVtdXG4gICByZXNvdXJjZT86IFJlc291cmNlTWFuYWdlclxufVxuXG5mdW5jdGlvbiBvblZpc2libGUoZG9jdW1lbnQ6IERvY3VtZW50LCByZWZDb3VudDogQmVoYXZpb3JTdWJqZWN0PGFueT4pIHtcbiAgIHJldHVybiB0b2dnbGUocmVmQ291bnQsIGZyb21FdmVudChkb2N1bWVudCwgXCJ2aXNpYmlsaXR5Y2hhbmdlXCIpLnBpcGUoXG4gICAgICBmaWx0ZXIoKCkgPT4gZG9jdW1lbnQudmlzaWJpbGl0eVN0YXRlID09PSBcInZpc2libGVcIilcbiAgICkpXG59XG5cbmZ1bmN0aW9uIG9uUmVjb25uZWN0KGRvY3VtZW50OiBEb2N1bWVudCwgcmVmQ291bnQ6IEJlaGF2aW9yU3ViamVjdDxhbnk+KSB7XG4gICBjb25zdCB3aW5kb3cgPSBkb2N1bWVudC5kZWZhdWx0Vmlld1xuICAgaWYgKHdpbmRvdykge1xuICAgICAgcmV0dXJuIHRvZ2dsZShyZWZDb3VudCwgZnJvbUV2ZW50KHdpbmRvdywgXCJvbmxpbmVcIikpXG4gICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIEVNUFRZXG4gICB9XG59XG5cbmZ1bmN0aW9uIHRvZ2dsZShyZWZDb3VudDogQmVoYXZpb3JTdWJqZWN0PG51bWJlcj4sIHNvdXJjZTogT2JzZXJ2YWJsZTxhbnk+KSB7XG4gICBjb25zdCBkZWxheSA9IHJlZkNvdW50LnBpcGUoXG4gICAgICBmaWx0ZXIoKGNvdW50KSA9PiBjb3VudCA+IDApXG4gICApXG4gICBjb25zdCByZXN1bWUgPSBvZihudWxsKVxuICAgcmV0dXJuIHNvdXJjZS5waXBlKFxuICAgICAgZGVib3VuY2UoKCkgPT4gcmVmQ291bnQudmFsdWUgPiAwID8gcmVzdW1lIDogZGVsYXkpXG4gICApXG59XG5cbkBJbmplY3RhYmxlKHsgcHJvdmlkZWRJbjogXCJyb290XCIgfSlcbmV4cG9ydCBjbGFzcyBSZXNvdXJjZU1hbmFnZXIge1xuICAgY2FjaGUgPSBuZXcgTWFwKClcbiAgIGRvY3VtZW50ID0gaW5qZWN0KERPQ1VNRU5UKVxuXG4gICBxdWVyeTxUPihzb3VyY2U6IE9ic2VydmFibGU8VD4sIG9wdGlvbnM6IFF1ZXJ5T3B0aW9ucyk6IE9ic2VydmFibGU8VD4ge1xuICAgICAgY29uc3Qga2V5ID0gdGhpcy5rZXlnZW4ob3B0aW9ucy5rZXkpXG4gICAgICBjb25zdCB7IGNhY2hlLCBkb2N1bWVudCB9ID0gdGhpc1xuXG4gICAgICBpZiAoY2FjaGUuaGFzKGtleSkpIHtcbiAgICAgICAgIGNvbnN0IHsgcmVzb3VyY2UsIGZldGNoLCBlcnJvcnMgfSA9IGNhY2hlLmdldChrZXkpXG4gICAgICAgICBpZiAob3B0aW9ucy5yZWZyZXNoSWZTdGFsZSAhPT0gZmFsc2UpIHtcbiAgICAgICAgICAgIGZldGNoLm5leHQoc291cmNlKVxuICAgICAgICAgfVxuICAgICAgICAgcmV0dXJuIG1lcmdlKHJlc291cmNlLCBlcnJvcnMpIGFzIE9ic2VydmFibGU8VD5cbiAgICAgIH1cblxuICAgICAgY29uc3QgY2FuY2VsID0gbmV3IFN1YmplY3Q8dm9pZD4oKVxuICAgICAgY29uc3QgaW52YWxpZGF0ZSA9IG5ldyBTdWJqZWN0PE9ic2VydmFibGU8VD4+KClcbiAgICAgIGNvbnN0IGZldGNoID0gbmV3IEJlaGF2aW9yU3ViamVjdDxPYnNlcnZhYmxlPFQ+Pihzb3VyY2UpXG4gICAgICBjb25zdCByZWZDb3VudCA9IG5ldyBCZWhhdmlvclN1YmplY3QoMClcbiAgICAgIGNvbnN0IGludmFsaWRhdG9ycyA9IFtmZXRjaF0gYXMgT2JzZXJ2YWJsZTxhbnk+W11cblxuICAgICAgaWYgKG9wdGlvbnMucmVmcmVzaE9uRm9jdXMpIHtcbiAgICAgICAgIGludmFsaWRhdG9ycy5wdXNoKG9uVmlzaWJsZShkb2N1bWVudCwgcmVmQ291bnQpKVxuICAgICAgfVxuXG4gICAgICBpZiAob3B0aW9ucy5yZWZyZXNoT25SZWNvbm5lY3QpIHtcbiAgICAgICAgIGludmFsaWRhdG9ycy5wdXNoKG9uUmVjb25uZWN0KGRvY3VtZW50LCByZWZDb3VudCkpXG4gICAgICB9XG5cbiAgICAgIGlmIChvcHRpb25zLnJlZnJlc2hJbnRlcnZhbCkge1xuICAgICAgICAgY29uc3QgbmF0aXZlSW50ZXJ2YWwgPSBvYnNlcnZlSW5ab25lKGludGVydmFsKG9wdGlvbnMucmVmcmVzaEludGVydmFsKSwgWm9uZS5yb290KVxuICAgICAgICAgaW52YWxpZGF0b3JzLnB1c2godG9nZ2xlKHJlZkNvdW50LCBuYXRpdmVJbnRlcnZhbCkpXG4gICAgICB9XG4gICAgICBjb25zdCBlcnJvcnMgPSBuZXcgU3ViamVjdDxuZXZlcj4oKVxuXG4gICAgICBjb25zdCByZWxvYWQgPSBtZXJnZSguLi5pbnZhbGlkYXRvcnMpLnBpcGUoXG4gICAgICAgICBzd2l0Y2hNYXAoKCkgPT4gZmV0Y2gucGlwZShcbiAgICAgICAgICAgIHRha2VVbnRpbChjYW5jZWwpXG4gICAgICAgICApKSxcbiAgICAgICAgIHRha2VVbnRpbChjYW5jZWwpLFxuICAgICAgICAgdGhyb3R0bGUoKCkgPT4gb2JzZXJ2ZUluWm9uZSh0aW1lcihvcHRpb25zLnN0YWxlVGltZSA/PyAwKSwgWm9uZS5yb290KSksXG4gICAgICApXG5cbiAgICAgIGNvbnN0IHJlc291cmNlOiBPYnNlcnZhYmxlPFQ+ID0gaW52YWxpZGF0ZS5waXBlKFxuICAgICAgICAgc3RhcnRXaXRoKG51bGwpLFxuICAgICAgICAgc3dpdGNoTWFwKCgpID0+IHJlbG9hZCksXG4gICAgICAgICBzd2l0Y2hBbGwoKSxcbiAgICAgICAgIHJldHJ5KHtcbiAgICAgICAgICAgIHJlc2V0T25TdWNjZXNzOiB0cnVlLFxuICAgICAgICAgICAgZGVsYXk6IChlcnJvciwgcmV0cnlDb3VudCkgPT4ge1xuICAgICAgICAgICAgICAgZmV0Y2gubmV4dCh2b2lkIDAgYXMgYW55KVxuICAgICAgICAgICAgICAgZXJyb3JzLmVycm9yKG5ldyBRdWVyeUVycm9yKGVycm9yLCByZXRyeUNvdW50KSlcbiAgICAgICAgICAgICAgIHJldHVybiByZXNvdXJjZVxuICAgICAgICAgICAgfVxuICAgICAgICAgfSksXG4gICAgICAgICBzaGFyZSh7XG4gICAgICAgICAgICBjb25uZWN0b3I6ICgpID0+IG5ldyBSZXBsYXlTdWJqZWN0KDEsIG9wdGlvbnMuY2FjaGVUaW1lID8/IEluZmluaXR5KSxcbiAgICAgICAgICAgIHJlc2V0T25FcnJvcjogZmFsc2UsXG4gICAgICAgICAgICByZXNldE9uQ29tcGxldGU6IGZhbHNlLFxuICAgICAgICAgICAgcmVzZXRPblJlZkNvdW50WmVybzogZmFsc2VcbiAgICAgICAgIH0pLFxuICAgICAgICAgdGFwKHtcbiAgICAgICAgICAgIHN1YnNjcmliZTogKCkgPT4gcmVmQ291bnQubmV4dChyZWZDb3VudC52YWx1ZSArIDEpLFxuICAgICAgICAgICAgdW5zdWJzY3JpYmU6ICgpID0+IHJlZkNvdW50Lm5leHQocmVmQ291bnQudmFsdWUgLSAxKVxuICAgICAgICAgfSlcbiAgICAgIClcblxuICAgICAgY2FjaGUuc2V0KGtleSwge1xuICAgICAgICAgcmVzb3VyY2UsXG4gICAgICAgICBlcnJvcnMsXG4gICAgICAgICBmZXRjaCxcbiAgICAgICAgIGNhbmNlbCxcbiAgICAgICAgIGludmFsaWRhdGUsXG4gICAgICAgICBzb3VyY2UsXG4gICAgICAgICBvcHRpb25zXG4gICAgICB9KVxuXG4gICAgICByZXR1cm4gbWVyZ2UocmVzb3VyY2UsIGVycm9ycylcbiAgIH1cblxuICAgbXV0YXRlPFQ+KHNvdXJjZTogT2JzZXJ2YWJsZTxUPiwgb3B0aW9uczogTXV0YXRlT3B0aW9ucykge1xuICAgICAgY29uc3Qga2V5cyA9IG9wdGlvbnMuaW52YWxpZGF0ZSA/IEFycmF5LmlzQXJyYXkob3B0aW9ucy5pbnZhbGlkYXRlWzBdKSA/IChvcHRpb25zLmludmFsaWRhdGUgYXMgdW5rbm93bltdW10pLm1hcCh0aGlzLmtleWdlbikgOiBbdGhpcy5rZXlnZW4ob3B0aW9ucy5pbnZhbGlkYXRlKV0gOiBbXVxuICAgICAgZm9yIChjb25zdCBrZXkgb2Yga2V5cykge1xuICAgICAgICAgdGhpcy5pbnZhbGlkYXRlKGtleSwgdHJ1ZSlcbiAgICAgIH1cbiAgICAgIHJldHVybiBzb3VyY2UucGlwZShcbiAgICAgICAgIGZpbmFsaXplKCgpID0+IHtcbiAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IG9mIGtleXMpIHtcbiAgICAgICAgICAgICAgIHRoaXMuaW52YWxpZGF0ZShrZXksIGZhbHNlKVxuICAgICAgICAgICAgfVxuICAgICAgICAgfSksXG4gICAgICApXG4gICB9XG5cbiAgIHJldmFsaWRhdGUoa2V5OiBhbnlbXSkge1xuICAgICAgdGhpcy5pbnZhbGlkYXRlKHRoaXMua2V5Z2VuKGtleSksIHRydWUpXG4gICAgICB0aGlzLmludmFsaWRhdGUodGhpcy5rZXlnZW4oa2V5KSwgZmFsc2UpXG4gICB9XG5cbiAgIHByaXZhdGUga2V5Z2VuKHNlZWQ6IHVua25vd25bXSkge1xuICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHNlZWQpXG4gICB9XG5cbiAgIHByaXZhdGUgaW52YWxpZGF0ZShrZXk6IHN0cmluZywgZG9DYW5jZWw6IGJvb2xlYW4pIHtcbiAgICAgIGZvciAoY29uc3QgW21hdGNoS2V5LCB7IGludmFsaWRhdGUsIGNhbmNlbCB9XSBvZiB0aGlzLmNhY2hlKSB7XG4gICAgICAgICBpZiAobWF0Y2hLZXkuc3RhcnRzV2l0aChrZXkuc2xpY2UoMCwga2V5Lmxlbmd0aCAtIDIpKSkge1xuICAgICAgICAgICAgaWYgKGRvQ2FuY2VsKSB7XG4gICAgICAgICAgICAgICBjYW5jZWwubmV4dCgpXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgaW52YWxpZGF0ZS5uZXh0KClcbiAgICAgICAgICAgIH1cbiAgICAgICAgIH1cbiAgICAgIH1cbiAgIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHVzZVF1ZXJ5PFQ+KG9wdGlvbnM6IFF1ZXJ5T3B0aW9uczxUPik6IE1vbm9UeXBlT3BlcmF0b3JGdW5jdGlvbjxUPiB7XG4gICBjb25zdCByZXNvdXJjZSA9IG9wdGlvbnMucmVzb3VyY2UgPz8gaW5qZWN0KFJlc291cmNlTWFuYWdlcilcbiAgIHJldHVybiBzb3VyY2UgPT4gcmVzb3VyY2UucXVlcnkoc291cmNlLCBvcHRpb25zKVxufVxuXG5leHBvcnQgZnVuY3Rpb24gdXNlTXV0YXRpb248VD4ob3B0aW9uczogTXV0YXRlT3B0aW9ucyk6IE1vbm9UeXBlT3BlcmF0b3JGdW5jdGlvbjxUPiB7XG4gICBjb25zdCByZXNvdXJjZSA9IG9wdGlvbnMucmVzb3VyY2UgPz8gaW5qZWN0KFJlc291cmNlTWFuYWdlcilcbiAgIHJldHVybiBzb3VyY2UgPT4gcmVzb3VyY2UubXV0YXRlKHNvdXJjZSwgb3B0aW9ucylcbn1cblxuZXhwb3J0IGNsYXNzIFF1ZXJ5RXJyb3Ige1xuICAgY29uc3RydWN0b3IocHVibGljIGVycm9yOiB1bmtub3duLCBwdWJsaWMgcmV0cnlDb3VudDogdW5rbm93bikge31cbn1cbiJdfQ==