@mmuscat/angular-resource
Version:
Data fetching library for Angular Composition API
225 lines • 28.4 kB
JavaScript
import { Injectable } from "@angular/core";
import { inject, select, Service, subscribe, use, } from "@mmuscat/angular-composition-api";
import { exhaust, filter, materialize, repeat, sample, switchMap, takeUntil, tap, } from "rxjs/operators";
import { merge, of, Subject, } from "rxjs";
import * as i0 from "@angular/core";
export class Resource {
constructor(value, error, pending, done) {
this.value = value;
this.error = error;
this.pending = pending;
this.done = done;
}
static createPending(value) {
return new Resource(value, undefined, true, false);
}
static createNext(value) {
return new Resource(value, undefined, false, false);
}
static createError(value, error) {
return new Resource(value, error, false, true);
}
static createComplete(value) {
return new Resource(value, undefined, false, true);
}
}
class ResultObserver {
constructor(value) {
this.value = value;
}
next(value) {
this.value.next(Resource.createNext(value));
}
error(error) {
this.value.next(Resource.createError(this.value.value.value, error));
}
complete() {
this.value.next(Resource.createComplete(this.value.value.value));
}
}
class PendingObserver {
constructor(value) {
this.value = value;
}
next() {
this.value.next(Resource.createPending(this.value.value.value));
}
}
class Cache {
constructor(factory, cache, unsubscribe) {
this.factory = factory;
this.cache = cache;
this.unsubscribe = unsubscribe;
}
get(params, invalidate) {
this.params = params;
const { cache, factory } = this;
const key = JSON.stringify(params);
if (invalidate) {
cache.delete(key);
}
if (cache.has(key)) {
return of(cache.get(key));
}
return factory(params).pipe(tap((value) => cache.set(key, value)));
}
clear() {
this.cache.clear();
}
invalidate() {
return this.get(this.params, true);
}
subscribe() {
return this;
}
}
const globalCache = new Map();
class CacheFactory {
get(token, queryFactory) {
function unsubscribe() {
var _a;
(_a = globalCache.get(token)) === null || _a === void 0 ? void 0 : _a.delete(this);
}
const cache = new Cache(queryFactory, new Map(), unsubscribe);
if (globalCache.has(token)) {
globalCache.get(token).add(cache);
return cache;
}
else {
globalCache.set(token, new Set([cache]));
return cache;
}
}
}
CacheFactory.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.4", ngImport: i0, type: CacheFactory, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
CacheFactory.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.0.4", ngImport: i0, type: CacheFactory, providedIn: "root" });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.4", ngImport: i0, type: CacheFactory, decorators: [{
type: Injectable,
args: [{ providedIn: "root" }]
}] });
function queryFactory(factory, forwardRef, config) {
const cacheFactory = inject(CacheFactory);
const queryFunction = factory();
return function query(...params) {
var _a;
const args = params[params.length - 2];
const options = params[params.length - 1];
const value = use(Resource.createNext(options.initialValue));
const query = select({
next(valueOrCommand) {
if (valueOrCommand instanceof Command) {
switch (valueOrCommand.signal) {
case CANCEL:
cancel.next();
break;
case INVALIDATE:
if (valueOrCommand.params) {
fetch(valueOrCommand.params, true);
}
else {
cache.clear();
}
break;
default:
throwInvalidCommand();
}
}
else {
value(valueOrCommand);
}
},
value,
});
const cache = cacheFactory.get(forwardRef(), queryFunction);
const operator = (_a = config === null || config === void 0 ? void 0 : config.operator) !== null && _a !== void 0 ? _a : switchMap;
const cancel = new Subject();
const fetch = use((args, invalidate) => [
args,
invalidate,
]);
const result = fetch.pipe(operator(([args, invalidate]) => cache.get(args, invalidate)), materialize(), takeUntil(cancel), repeat());
subscribe(cache);
subscribe(fetch, new PendingObserver(value));
subscribe(result, new ResultObserver(value));
if (options.refetch) {
const signal = merge(...options.refetch).pipe(filter((value) => (value instanceof Resource ? value.done : true)));
subscribe(fetch.pipe(sample(signal)), (params) => fetch(params, true));
}
if (args) {
subscribe(merge(...(Array.isArray(args) ? args : [args])), fetch);
}
return query;
};
}
function createQueryFactory(factory, config) {
const Query = new Service(queryFactory, {
providedIn: "root",
name: factory.name,
arguments: [factory, () => Query, config],
});
return Query;
}
export const Query = createQueryFactory;
const CANCEL = 0;
const INVALIDATE = 1;
class Command {
constructor(signal, params) {
this.signal = signal;
this.params = params;
}
}
function throwInvalidCommand() {
throw new Error("Invalid command");
}
function mutateFactory(factory, config) {
var _a, _b;
const operator = (_b = (_a = config === null || config === void 0 ? void 0 : config.operator) === null || _a === void 0 ? void 0 : _a.call(config)) !== null && _b !== void 0 ? _b : exhaust();
const queue = use(Function);
const cancel = new Subject();
const result = queue.pipe(operator);
const createStream = factory();
const value = use(Resource.createNext(undefined));
function mutate(params) {
if (params instanceof Command) {
switch (params.signal) {
case CANCEL:
return cancel.next();
default:
throwInvalidCommand();
}
}
queue.next(createStream(params).pipe(materialize(), takeUntil(cancel)));
}
const mutation = select({
next: mutate,
value,
});
subscribe(queue, new PendingObserver(value));
subscribe(result, new ResultObserver(value));
return mutation;
}
function createMutationFactory(factory, config) {
return new Service(mutateFactory, {
providedIn: "root",
name: factory.name,
arguments: [factory, config],
});
}
export const Mutation = createMutationFactory;
export function cancel(resource) {
resource.next(new Command(CANCEL));
}
export function invalidate(query, params) {
var _a;
if (query.__ng_value) {
query.next(new Command(INVALIDATE, params));
}
else {
const set = (_a = globalCache.get(query)) !== null && _a !== void 0 ? _a : [];
for (const cache of set) {
cache.clear();
cache.invalidate();
}
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzb3VyY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9wYWNrYWdlcy9yZXNvdXJjZS9zcmMvcmVzb3VyY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBUSxNQUFNLGVBQWUsQ0FBQTtBQUNoRCxPQUFPLEVBQ0osTUFBTSxFQUNOLE1BQU0sRUFDTixPQUFPLEVBQ1AsU0FBUyxFQUNULEdBQUcsR0FHTCxNQUFNLGtDQUFrQyxDQUFBO0FBQ3pDLE9BQU8sRUFDSixPQUFPLEVBQ1AsTUFBTSxFQUNOLFdBQVcsRUFDWCxNQUFNLEVBQ04sTUFBTSxFQUNOLFNBQVMsRUFDVCxTQUFTLEVBQ1QsR0FBRyxHQUNMLE1BQU0sZ0JBQWdCLENBQUE7QUFDdkIsT0FBTyxFQUNKLEtBQUssRUFLTCxFQUFFLEVBRUYsT0FBTyxHQUNULE1BQU0sTUFBTSxDQUFBOztBQW1CYixNQUFNLE9BQU8sUUFBUTtJQWFsQixZQUNVLEtBQVEsRUFDUixLQUFjLEVBQ2QsT0FBZ0IsRUFDaEIsSUFBYTtRQUhiLFVBQUssR0FBTCxLQUFLLENBQUc7UUFDUixVQUFLLEdBQUwsS0FBSyxDQUFTO1FBQ2QsWUFBTyxHQUFQLE9BQU8sQ0FBUztRQUNoQixTQUFJLEdBQUosSUFBSSxDQUFTO0lBQ3BCLENBQUM7SUFqQkosTUFBTSxDQUFDLGFBQWEsQ0FBQyxLQUFVO1FBQzVCLE9BQU8sSUFBSSxRQUFRLENBQUMsS0FBSyxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUE7SUFDckQsQ0FBQztJQUNELE1BQU0sQ0FBQyxVQUFVLENBQUMsS0FBVTtRQUN6QixPQUFPLElBQUksUUFBUSxDQUFDLEtBQUssRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFBO0lBQ3RELENBQUM7SUFDRCxNQUFNLENBQUMsV0FBVyxDQUFDLEtBQVUsRUFBRSxLQUFVO1FBQ3RDLE9BQU8sSUFBSSxRQUFRLENBQUMs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QUE7S0FDN0M7U0FBTTtRQUNKLE1BQU0sR0FBRyxHQUFHLE1BQUEsV0FBVyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsbUNBQUksRUFBRSxDQUFBO1FBQ3hDLEtBQUssTUFBTSxLQUFLLElBQUksR0FBRyxFQUFFO1lBQ3RCLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQTtZQUNiLEtBQUssQ0FBQyxVQUFVLEVBQUUsQ0FBQTtTQUNwQjtLQUNIO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUsIFR5cGUgfSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiXG5pbXBvcnQge1xuICAgaW5qZWN0LFxuICAgc2VsZWN0LFxuICAgU2VydmljZSxcbiAgIHN1YnNjcmliZSxcbiAgIHVzZSxcbiAgIFZhbHVlLFxuICAgVmFsdWVBY2Nlc3Nvcixcbn0gZnJvbSBcIkBtbXVzY2F0L2FuZ3VsYXItY29tcG9zaXRpb24tYXBpXCJcbmltcG9ydCB7XG4gICBleGhhdXN0LFxuICAgZmlsdGVyLFxuICAgbWF0ZXJpYWxpemUsXG4gICByZXBlYXQsXG4gICBzYW1wbGUsXG4gICBzd2l0Y2hNYXAsXG4gICB0YWtlVW50aWwsXG4gICB0YXAsXG59IGZyb20gXCJyeGpzL29wZXJhdG9yc1wiXG5pbXBvcnQge1xuICAgbWVyZ2UsXG4gICBOZXh0T2JzZXJ2ZXIsXG4gICBOb3RpZmljYXRpb24sXG4gICBPYnNlcnZhYmxlLFxuICAgT2JzZXJ2ZXIsXG4gICBvZixcbiAgIE9wZXJhdG9yRnVuY3Rpb24sXG4gICBTdWJqZWN0LFxufSBmcm9tIFwicnhqc1wiXG5cbmV4cG9ydCBpbnRlcmZhY2UgUXVlcnlPcHRpb25zPFQ+IHtcbiAgIGluaXRpYWxWYWx1ZTogVFxuICAgcmVmZXRjaD86IE9ic2VydmFibGU8YW55PltdXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUXVlcnk8VCwgVT4ge1xuICAgKGNvbmZpZzogUXVlcnlPcHRpb25zPFQ+KTogVmFsdWVBY2Nlc3NvcjxSZXNvdXJjZTxUPiwgVT5cbiAgIChcbiAgICAgIHBhcmFtczogT2JzZXJ2YWJsZTxVPiB8IE9ic2VydmFibGU8VT5bXSxcbiAgICAgIGNvbmZpZzogUXVlcnlPcHRpb25zPFQ+LFxuICAgKTogVmFsdWVBY2Nlc3NvcjxSZXNvdXJjZTxUPiwgVT5cbn1cblxuaW50ZXJmYWNlIFF1ZXJ5U3RhdGljIHtcbiAgIG5ldyA8VCwgVT4oZmFjdG9yeTogKCkgPT4gKHBhcmFtczogVSkgPT4gT2JzZXJ2YWJsZTxUPik6IFR5cGU8UXVlcnk8VCwgVT4+XG59XG5cbmV4cG9ydCBjbGFzcyBSZXNvdXJjZTxUPiB7XG4gICBzdGF0aWMgY3JlYXRlUGVuZGluZyh2YWx1ZTogYW55KSB7XG4gICAgICByZXR1cm4gbmV3IFJlc291cmNlKHZhbHVlLCB1bmRlZmluZWQsIHRydWUsIGZhbHNlKVxuICAgfVxuICAgc3RhdGljIGNyZWF0ZU5leHQodmFsdWU6IGFueSkge1xuICAgICAgcmV0dXJuIG5ldyBSZXNvdXJjZSh2YWx1ZSwgdW5kZWZpbmVkLCBmYWxzZSwgZmFsc2UpXG4gICB9XG4gICBzdGF0aWMgY3JlYXRlRXJyb3IodmFsdWU6IGFueSwgZXJyb3I6IGFueSkge1xuICAgICAgcmV0dXJuIG5ldyBSZXNvdXJjZSh2YWx1ZSwgZXJyb3IsIGZhbHNlLCB0cnVlKVxuICAgfVxuICAgc3RhdGljIGNyZWF0ZUNvbXBsZXRlKHZhbHVlOiBhbnkpIHtcbiAgICAgIHJldHVybiBuZXcgUmVzb3VyY2UodmFsdWUsIHVuZGVmaW5lZCwgZmFsc2UsIHRydWUpXG4gICB9XG4gICBjb25zdHJ1Y3RvcihcbiAgICAgIHB1YmxpYyB2YWx1ZTogVCxcbiAgICAgIHB1YmxpYyBlcnJvcjogdW5rbm93bixcbiAgICAgIHB1YmxpYyBwZW5kaW5nOiBib29sZWFuLFxuICAgICAgcHVibGljIGRvbmU6IGJvb2xlYW4sXG4gICApIHt9XG59XG5cbmNsYXNzIFJlc3VsdE9ic2VydmVyIGltcGxlbWVudHMgT2JzZXJ2ZXI8YW55PiB7XG4gICBuZXh0KHZhbHVlOiBhbnkpIHtcbiAgICAgIHRoaXMudmFsdWUubmV4dChSZXNvdXJjZS5jcmVhdGVOZXh0KHZhbHVlKSlcbiAgIH1cbiAgIGVycm9yKGVycm9yOiBhbnkpIHtcbiAgICAgIHRoaXMudmFsdWUubmV4dChSZXNvdXJjZS5jcmVhdGVFcnJvcih0aGlzLnZhbHVlLnZhbHVlLnZhbHVlLCBlcnJvcikpXG4gICB9XG4gICBjb21wbGV0ZSgpIHtcbiAgICAgIHRoaXMudmFsdWUubmV4dChSZXNvdXJjZS5jcmVhdGVDb21wbGV0ZSh0aGlzLnZhbHVlLnZhbHVlLnZhbHVlKSlcbiAgIH1cbiAgIGNvbnN0cnVjdG9yKHByaXZhdGUgdmFsdWU6IFZhbHVlPGFueT4pIHt9XG59XG5cbmNsYXNzIFBlbmRpbmdPYnNlcnZlciBpbXBsZW1lbnRzIE5leHRPYnNlcnZlcjxhbnk+IHtcbiAgIG5leHQoKSB7XG4gICAgICB0aGlzLnZhbHVlLm5leHQoUmVzb3VyY2UuY3JlYXRlUGVuZGluZyh0aGlzLnZhbHVlLnZhbHVlLnZhbHVlKSlcbiAgIH1cbiAgIGNvbnN0cnVjdG9yKHByaXZhdGUgdmFsdWU6IFZhbHVlPGFueT4pIHt9XG59XG5cbmNsYXNzIENhY2hlIHtcbiAgIHBhcmFtczogYW55XG4gICBnZXQocGFyYW1zOiBhbnksIGludmFsaWRhdGU/OiBib29sZWFuKTogYW55IHtcbiAgICAgIHRoaXMucGFyYW1zID0gcGFyYW1zXG4gICAgICBjb25zdCB7IGNhY2hlLCBmYWN0b3J5IH0gPSB0aGlzXG4gICAgICBjb25zdCBrZXkgPSBKU09OLnN0cmluZ2lmeShwYXJhbXMpXG4gICAgICBpZiAoaW52YWxpZGF0ZSkge1xuICAgICAgICAgY2FjaGUuZGVsZXRlKGtleSlcbiAgICAgIH1cbiAgICAgIGlmIChjYWNoZS5oYXMoa2V5KSkge1xuICAgICAgICAgcmV0dXJuIG9mKGNhY2hlLmdldChrZXkpKVxuICAgICAgfVxuICAgICAgcmV0dXJuIGZhY3RvcnkocGFyYW1zKS5waXBlKHRhcCgodmFsdWUpID0+IGNhY2hlLnNldChrZXksIHZhbHVlKSkpXG4gICB9XG4gICBjbGVhcigpIHtcbiAgICAgIHRoaXMuY2FjaGUuY2xlYXIoKVxuICAgfVxuICAgaW52YWxpZGF0ZSgpIHtcbiAgICAgIHJldHVybiB0aGlzLmdldCh0aGlzLnBhcmFtcywgdHJ1ZSlcbiAgIH1cbiAgIHN1YnNjcmliZSgpIHtcbiAgICAgIHJldHVybiB0aGlzXG4gICB9XG4gICBjb25zdHJ1Y3RvcihcbiAgICAgIHByaXZhdGUgZmFjdG9yeTogKGFyZ3M6IGFueSkgPT4gT2JzZXJ2YWJsZTxhbnk+LFxuICAgICAgcHJpdmF0ZSBjYWNoZTogTWFwPGFueSwgYW55PixcbiAgICAgIHB1YmxpYyB1bnN1YnNjcmliZTogKHRoaXM6IENhY2hlKSA9PiB2b2lkLFxuICAgKSB7fVxufVxuXG5jb25zdCBnbG9iYWxDYWNoZSA9IG5ldyBNYXA8VHlwZTxhbnk+LCBTZXQ8Q2FjaGU+PigpXG5cbkBJbmplY3RhYmxlKHsgcHJvdmlkZWRJbjogXCJyb290XCIgfSlcbmNsYXNzIENhY2hlRmFjdG9yeSB7XG4gICBnZXQodG9rZW46IGFueSwgcXVlcnlGYWN0b3J5OiBhbnkpIHtcbiAgICAgIGZ1bmN0aW9uIHVuc3Vic2NyaWJlKHRoaXM6IENhY2hlKSB7XG4gICAgICAgICBnbG9iYWxDYWNoZS5nZXQodG9rZW4pPy5kZWxldGUodGhpcylcbiAgICAgIH1cbiAgICAgIGNvbnN0IGNhY2hlID0gbmV3IENhY2hlKHF1ZXJ5RmFjdG9yeSwgbmV3IE1hcCgpLCB1bnN1YnNjcmliZSlcbiAgICAgIGlmIChnbG9iYWxDYWNoZS5oYXModG9rZW4pKSB7XG4gICAgICAgICBnbG9iYWxDYWNoZS5nZXQodG9rZW4pIS5hZGQoY2FjaGUpXG4gICAgICAgICByZXR1cm4gY2FjaGVcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgICBnbG9iYWxDYWNoZS5zZXQodG9rZW4sIG5ldyBTZXQoW2NhY2hlXSkpXG4gICAgICAgICByZXR1cm4gY2FjaGVcbiAgICAgIH1cbiAgIH1cbn1cblxuZXhwb3J0IGludGVyZmFjZSBRdWVyeUNvbmZpZyB7XG4gICBvcGVyYXRvcj86ICgpID0+IE9wZXJhdG9yRnVuY3Rpb248YW55LCBhbnk+XG59XG5cbmZ1bmN0aW9uIHF1ZXJ5RmFjdG9yeShcbiAgIGZhY3Rvcnk6ICgpID0+IChhcmdzOiBhbnkpID0+IE9ic2VydmFibGU8YW55PixcbiAgIGZvcndhcmRSZWY6ICgpID0+IGFueSxcbiAgIGNvbmZpZzogUXVlcnlDb25maWcsXG4pIHtcbiAgIGNvbnN0IGNhY2hlRmFjdG9yeSA9IGluamVjdChDYWNoZUZhY3RvcnkpXG4gICBjb25zdCBxdWVyeUZ1bmN0aW9uID0gZmFjdG9yeSgpXG5cbiAgIHJldHVybiBmdW5jdGlvbiBxdWVyeSguLi5wYXJhbXM6IGFueVtdKSB7XG4gICAgICBjb25zdCBhcmdzID0gcGFyYW1zW3BhcmFtcy5sZW5ndGggLSAyXVxuICAgICAgY29uc3Qgb3B0aW9ucyA9IHBhcmFtc1twYXJhbXMubGVuZ3RoIC0gMV1cbiAgICAgIGNvbnN0IHZhbHVlID0gdXNlKFJlc291cmNlLmNyZWF0ZU5leHQob3B0aW9ucy5pbml0aWFsVmFsdWUpKVxuICAgICAgY29uc3QgcXVlcnkgPSBzZWxlY3Qoe1xuICAgICAgICAgbmV4dCh2YWx1ZU9yQ29tbWFuZDogYW55KSB7XG4gICAgICAgICAgICBpZiAodmFsdWVPckNvbW1hbmQgaW5zdGFuY2VvZiBDb21tYW5kKSB7XG4gICAgICAgICAgICAgICBzd2l0Y2ggKHZhbHVlT3JDb21tYW5kLnNpZ25hbCkge1xuICAgICAgICAgICAgICAgICAgY2FzZSBDQU5DRUw6XG4gICAgICAgICAgICAgICAgICAgICBjYW5jZWwubmV4dCgpXG4gICAgICAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgICAgICAgY2FzZSBJTlZBTElEQVRFOlxuICAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlT3JDb21tYW5kLnBhcmFtcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgZmV0Y2godmFsdWVPckNvbW1hbmQucGFyYW1zLCB0cnVlKVxuICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhY2hlLmNsZWFyKClcbiAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICAgdGhyb3dJbnZhbGlkQ29tbWFuZCgpXG4gICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgdmFsdWUodmFsdWVPckNvbW1hbmQpXG4gICAgICAgICAgICB9XG4gICAgICAgICB9LFxuICAgICAgICAgdmFsdWUsXG4gICAgICB9KVxuICAgICAgY29uc3QgY2FjaGUgPSBjYWNoZUZhY3RvcnkuZ2V0KGZvcndhcmRSZWYoKSwgcXVlcnlGdW5jdGlvbilcbiAgICAgIGNvbnN0IG9wZXJhdG9yID0gY29uZmlnPy5vcGVyYXRvciA/PyBzd2l0Y2hNYXBcbiAgICAgIGNvbnN0IGNhbmNlbCA9IG5ldyBTdWJqZWN0KClcbiAgICAgIGNvbnN0IGZldGNoID0gdXNlKChhcmdzOiBhbnksIGludmFsaWRhdGU6IGFueSkgPT4gW1xuICAgICAgICAgYXJncyxcbiAgICAgICAgIGludmFsaWRhdGUsXG4gICAgICBdKSBhcyBhbnlcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGZldGNoLnBpcGUoXG4gICAgICAgICBvcGVyYXRvcigoW2FyZ3MsIGludmFsaWRhdGVdKSA9PiBjYWNoZS5nZXQoYXJncywgaW52YWxpZGF0ZSkpLFxuICAgICAgICAgbWF0ZXJpYWxpemUoKSxcbiAgICAgICAgIHRha2VVbnRpbChjYW5jZWwpLFxuICAgICAgICAgcmVwZWF0KCksXG4gICAgICApXG5cbiAgICAgIHN1YnNjcmliZShjYWNoZSlcbiAgICAgIHN1YnNjcmliZShmZXRjaCwgbmV3IFBlbmRpbmdPYnNlcnZlcih2YWx1ZSkpXG4gICAgICBzdWJzY3JpYmUocmVzdWx0LCBuZXcgUmVzdWx0T2JzZXJ2ZXIodmFsdWUpKVxuXG4gICAgICBpZiAob3B0aW9ucy5yZWZldGNoKSB7XG4gICAgICAgICBjb25zdCBzaWduYWwgPSBtZXJnZSguLi5vcHRpb25zLnJlZmV0Y2gpLnBpcGUoXG4gICAgICAgICAgICBmaWx0ZXIoKHZhbHVlKSA9PiAodmFsdWUgaW5zdGFuY2VvZiBSZXNvdXJjZSA/IHZhbHVlLmRvbmUgOiB0cnVlKSksXG4gICAgICAgICApXG4gICAgICAgICBzdWJzY3JpYmUoZmV0Y2gucGlwZShzYW1wbGUoc2lnbmFsKSksIChwYXJhbXMpID0+IGZldGNoKHBhcmFtcywgdHJ1ZSkpXG4gICAgICB9XG5cbiAgICAgIGlmIChhcmdzKSB7XG4gICAgICAgICBzdWJzY3JpYmUobWVyZ2UoLi4uKEFycmF5LmlzQXJyYXkoYXJncykgPyBhcmdzIDogW2FyZ3NdKSksIGZldGNoKVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gcXVlcnlcbiAgIH1cbn1cblxuZnVuY3Rpb24gY3JlYXRlUXVlcnlGYWN0b3J5KGZhY3Rvcnk6ICgpID0+IEZ1bmN0aW9uLCBjb25maWc/OiBhbnkpIHtcbiAgIGNvbnN0IFF1ZXJ5ID0gbmV3IFNlcnZpY2UocXVlcnlGYWN0b3J5LCB7XG4gICAgICBwcm92aWRlZEluOiBcInJvb3RcIixcbiAgICAgIG5hbWU6IGZhY3RvcnkubmFtZSxcbiAgICAgIGFyZ3VtZW50czogW2ZhY3RvcnksICgpID0+IFF1ZXJ5LCBjb25maWddLFxuICAgfSlcbiAgIHJldHVybiBRdWVyeVxufVxuXG5leHBvcnQgY29uc3QgUXVlcnk6IFF1ZXJ5U3RhdGljID0gY3JlYXRlUXVlcnlGYWN0b3J5IGFzIGFueVxuXG5jb25zdCBDQU5DRUwgPSAwXG5jb25zdCBJTlZBTElEQVRFID0gMVxuXG5jbGFzcyBDb21tYW5kIHtcbiAgIGNvbnN0cnVjdG9yKHB1YmxpYyBzaWduYWw6IG51bWJlciwgcHVibGljIHBhcmFtcz86IGFueSkge31cbn1cblxuZnVuY3Rpb24gdGhyb3dJbnZhbGlkQ29tbWFuZCgpIHtcbiAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgY29tbWFuZFwiKVxufVxuXG5mdW5jdGlvbiBtdXRhdGVGYWN0b3J5KFxuICAgZmFjdG9yeTogKCkgPT4gKC4uLmFyZ3M6IGFueVtdKSA9PiBPYnNlcnZhYmxlPGFueT4sXG4gICBjb25maWc6IE11dGF0aW9uQ29uZmlnLFxuKSB7XG4gICBjb25zdCBvcGVyYXRvciA9IGNvbmZpZz8ub3BlcmF0b3I/LigpID8/IGV4aGF1c3QoKVxuICAgY29uc3QgcXVldWUgPSB1c2U8T2JzZXJ2YWJsZTxOb3RpZmljYXRpb248YW55Pj4+KEZ1bmN0aW9uKVxuICAgY29uc3QgY2FuY2VsID0gbmV3IFN1YmplY3QoKVxuICAgY29uc3QgcmVzdWx0ID0gcXVldWUucGlwZShvcGVyYXRvcilcbiAgIGNvbnN0IGNyZWF0ZVN0cmVhbSA9IGZhY3RvcnkoKVxuICAgY29uc3QgdmFsdWUgPSB1c2UoUmVzb3VyY2UuY3JlYXRlTmV4dCh1bmRlZmluZWQpKVxuICAgZnVuY3Rpb24gbXV0YXRlKHBhcmFtczogYW55KSB7XG4gICAgICBpZiAocGFyYW1zIGluc3RhbmNlb2YgQ29tbWFuZCkge1xuICAgICAgICAgc3dpdGNoIChwYXJhbXMuc2lnbmFsKSB7XG4gICAgICAgICAgICBjYXNlIENBTkNFTDpcbiAgICAgICAgICAgICAgIHJldHVybiBjYW5jZWwubmV4dCgpXG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgdGhyb3dJbnZhbGlkQ29tbWFuZCgpXG4gICAgICAgICB9XG4gICAgICB9XG4gICAgICBxdWV1ZS5uZXh0KGNyZWF0ZVN0cmVhbShwYXJhbXMpLnBpcGUobWF0ZXJpYWxpemUoKSwgdGFrZVVudGlsKGNhbmNlbCkpKVxuICAgfVxuICAgY29uc3QgbXV0YXRpb24gPSBzZWxlY3Qoe1xuICAgICAgbmV4dDogbXV0YXRlLFxuICAgICAgdmFsdWUsXG4gICB9KVxuXG4gICBzdWJzY3JpYmUocXVldWUsIG5ldyBQZW5kaW5nT2JzZXJ2ZXIodmFsdWUpKVxuICAgc3Vic2NyaWJlKHJlc3VsdCwgbmV3IFJlc3VsdE9ic2VydmVyKHZhbHVlKSlcblxuICAgcmV0dXJuIG11dGF0aW9uXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTXV0YXRpb25Db25maWcge1xuICAgb3BlcmF0b3I/OiAoKSA9PiBPcGVyYXRvckZ1bmN0aW9uPE9ic2VydmFibGU8YW55PiwgYW55PlxufVxuXG5leHBvcnQgaW50ZXJmYWNlIE11dGF0aW9uU3RhdGljIHtcbiAgIG5ldyA8VCwgVT4oXG4gICAgICBmYWN0b3J5OiAoKSA9PiAocGFyYW1zOiBVKSA9PiBPYnNlcnZhYmxlPFQ+LFxuICAgICAgY29uZmlnPzogTXV0YXRpb25Db25maWcsXG4gICApOiBUeXBlPFZhbHVlQWNjZXNzb3I8UmVzb3VyY2U8VD4sIFU+PlxufVxuXG5mdW5jdGlvbiBjcmVhdGVNdXRhdGlvbkZhY3RvcnkoXG4gICBmYWN0b3J5OiAoKSA9PiAoLi4uYXJnczogYW55KSA9PiBPYnNlcnZhYmxlPGFueT4sXG4gICBjb25maWc6IE11dGF0aW9uQ29uZmlnLFxuKSB7XG4gICByZXR1cm4gbmV3IFNlcnZpY2UobXV0YXRlRmFjdG9yeSwge1xuICAgICAgcHJvdmlkZWRJbjogXCJyb290XCIsXG4gICAgICBuYW1lOiBmYWN0b3J5Lm5hbWUsXG4gICAgICBhcmd1bWVudHM6IFtmYWN0b3J5LCBjb25maWddLFxuICAgfSlcbn1cblxuZXhwb3J0IGNvbnN0IE11dGF0aW9uOiBNdXRhdGlvblN0YXRpYyA9IGNyZWF0ZU11dGF0aW9uRmFjdG9yeSBhcyBhbnlcblxuZXhwb3J0IGZ1bmN0aW9uIGNhbmNlbChyZXNvdXJjZTogYW55KSB7XG4gICByZXNvdXJjZS5uZXh0KG5ldyBDb21tYW5kKENBTkNFTCkpXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpbnZhbGlkYXRlKHF1ZXJ5OiBhbnksIHBhcmFtcz86IGFueSkge1xuICAgaWYgKHF1ZXJ5Ll9fbmdfdmFsdWUpIHtcbiAgICAgIHF1ZXJ5Lm5leHQobmV3IENvbW1hbmQoSU5WQUxJREFURSwgcGFyYW1zKSlcbiAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBzZXQgPSBnbG9iYWxDYWNoZS5nZXQocXVlcnkpID8/IFtdXG4gICAgICBmb3IgKGNvbnN0IGNhY2hlIG9mIHNldCkge1xuICAgICAgICAgY2FjaGUuY2xlYXIoKVxuICAgICAgICAgY2FjaGUuaW52YWxpZGF0ZSgpXG4gICAgICB9XG4gICB9XG59XG4iXX0=