@antischematic/angular-state-library
Version:
Reactive state without boilerplate
177 lines • 25.6 kB
JavaScript
import { createEnvironmentInjector, EnvironmentInjector, ErrorHandler, inject, INJECTOR } from "@angular/core";
import { EventType } from "./interfaces";
import { getActions, getDeps, getMeta, getMetaValues, getSelectors, getToken, injector, markDirty, setMeta, tracked } from "./metadata";
import { ACTION, Changes, CONTEXT, EffectScheduler, EventScheduler, ROOT_CONFIG, STORE_CONFIG, StoreErrorHandler, Teardown } from "./providers";
import { createProxy, getChanges, popStack, pushStack, untrack } from "./proxy";
import { store, subscribe } from "./select";
import { call, wrap } from "./utils";
function checkDeps(deps) {
let dirty = false;
for (const [object, keyValues] of deps) {
for (const [key, previous] of keyValues) {
const current = object[key];
if (!Object.is(current, previous)) {
keyValues.set(key, current);
dirty = true;
}
}
}
return dirty;
}
export function decorateCheck(target, name) {
const actions = getActions(target, name);
wrap(target, name, function check(fn) {
const events = getToken(EventScheduler, this);
for (const action of actions) {
const deps = getDeps(this, action.key);
const dirty = action.track && deps && checkDeps(deps);
if (action.descriptor?.value.length === 0 && (!deps && action.immediate && action.phase === name || dirty)) {
markDirty(this);
call(this, action.key);
}
}
for (const action of actions) {
const effect = getToken(EffectScheduler, this, action.key);
effect.dequeue();
}
if (events.flush()) {
check.call(this, fn);
}
else {
fn.apply(this);
}
});
}
function getConfig() {
return inject(STORE_CONFIG, { self: true, optional: true }) ?? inject(ROOT_CONFIG);
}
function provideValue(provide, useValue) {
return { provide, useValue };
}
export function setup(target, factory, ...args) {
const instance = factory(...args);
const prototype = target.prototype;
const parent = inject(INJECTOR);
const storeInjector = createEnvironmentInjector([
provideValue(Changes, new Changes(instance)),
provideValue(ErrorHandler, new StoreErrorHandler(prototype, instance)),
provideValue(EventScheduler, new EventScheduler(instance)),
Teardown
], parent);
let storeConfig = getConfig();
setMeta(injector, storeInjector, instance);
for (const action of getActions(prototype)) {
const actionInjector = createEnvironmentInjector([
provideValue(ACTION, action),
provideValue(CONTEXT, { instance }),
EffectScheduler,
Teardown,
storeConfig?.actionProviders ?? []
], storeInjector);
setMeta(injector, actionInjector, instance, action.key);
}
return instance;
}
export const stores = new Set();
const decorated = new WeakSet();
export function decorateFactory(target, fn, ...additionalArgs) {
const factory = target["ɵfac"];
if (factory) {
Object.defineProperty(target, "ɵfac", {
configurable: true,
value: function (...args) {
return fn(target, factory, ...additionalArgs, ...args);
}
});
}
}
export function runInContext(deps, fn, context = {}, catchError = true, key, ...args) {
const injector = getToken(EnvironmentInjector, untrack(context), key);
const errorHandler = injector.get(ErrorHandler);
pushStack(deps);
try {
return injector.runInContext(() => fn.apply(context, args));
}
catch (e) {
if (catchError) {
errorHandler.handleError(e);
}
else {
throw e;
}
}
finally {
popStack();
}
}
function runAction(fn, key, deps, args) {
const event = inject(EventScheduler);
event.schedule(EventType.Dispatch, key, args.length === 1 ? args[0] : args, getChanges(deps));
return fn.apply(this, args);
}
export function decorateActions(target) {
for (const { key, catchError } of getActions(target)) {
wrap(target, key, function (fn, ...args) {
const proxy = createProxy(this);
const deps = new Map();
setMeta(tracked, deps, this, key);
teardown(this, key);
return runInContext(deps, runAction, proxy, catchError, key, fn, key, deps, args);
});
}
}
export function decorateSelect(target) {
var _a;
(_a = target.prototype).ngOnSelect ?? (_a.ngOnSelect = function (observer) {
return store(target).subscribe(observer);
});
}
export function decorateSelectors(target) {
for (const { key } of getSelectors(target, true)) {
wrap(target, key, function (fn, ...args) {
const cacheKey = key + JSON.stringify(args);
const proxy = createProxy(this);
const deps = getDeps(this, cacheKey);
const dirty = deps ? checkDeps(deps) : true;
let result = getMeta(cacheKey, this, key);
if (dirty) {
const newDeps = new Map();
result = runInContext(newDeps, fn, proxy, true, void 0, ...args);
setMeta(cacheKey, result, this, key);
setMeta(tracked, newDeps, this, cacheKey);
}
return result;
});
}
}
export function decorateChanges(target) {
wrap(target, "ngOnChanges", function (fn, value) {
const events = getToken(EventScheduler, this);
const changes = Object.entries(value).map(([key, change]) => [key, change.previousValue]);
events.schedule(EventType.Dispatch, "ngOnChanges", { ...value }, new Map([[this, new Map(changes)]]));
fn.call(this, value);
});
}
export function decorateOnInit(target) {
wrap(target, "ngOnInit", function (fn) {
const injector = getToken(EnvironmentInjector, this);
for (const attachment of getSelectors(target, false)) {
injector.runInContext(() => {
subscribe(attachment.token, this, attachment.key);
});
}
fn.call(this);
});
}
export function decorateDestroy(target) {
wrap(target, "ngOnDestroy", function (fn) {
for (const environmentInjector of getMetaValues(injector, this)) {
environmentInjector.destroy();
}
fn.apply(this);
});
}
function teardown(context, key) {
getToken(Teardown, context, key)?.unsubscribe();
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29yZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Byb2plY3RzL2NvcmUvc3JjL2NvcmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNKLHlCQUF5QixFQUN6QixtQkFBbUIsRUFDbkIsWUFBWSxFQUNaLE1BQU0sRUFDTixRQUFRLEVBRVYsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFTLFNBQVMsRUFBd0IsTUFBTSxjQUFjLENBQUM7QUFDdEUsT0FBTyxFQUNKLFVBQVUsRUFDVixPQUFPLEVBQ1AsT0FBTyxFQUNQLGFBQWEsRUFDYixZQUFZLEVBQ1osUUFBUSxFQUNSLFFBQVEsRUFDUixTQUFTLEVBQ1QsT0FBTyxFQUNQLE9BQU8sRUFDVCxNQUFNLFlBQVksQ0FBQztBQUNwQixPQUFPLEVBQ0osTUFBTSxFQUNOLE9BQU8sRUFDUCxPQUFPLEVBQ1AsZUFBZSxFQUNmLGNBQWMsRUFDZCxXQUFXLEVBQ1gsWUFBWSxFQUNaLGlCQUFpQixFQUNqQixRQUFRLEVBQ1YsTUFBTSxhQUFhLENBQUM7QUFDckIsT0FBTyxFQUFDLFdBQVcsRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUMsTUFBTSxTQUFTLENBQUM7QUFDOUUsT0FBTyxFQUFDLEtBQUssRUFBRSxTQUFTLEVBQUMsTUFBTSxVQUFVLENBQUM7QUFDMUMsT0FBTyxFQUFDLElBQUksRUFBRSxJQUFJLEVBQUMsTUFBTSxTQUFTLENBQUM7QUFFbkMsU0FBUyxTQUFTLENBQUMsSUFBWTtJQUM1QixJQUFJLEtBQUssR0FBRyxLQUFLLENBQUE7SUFDakIsS0FBSyxNQUFNLENBQUMsTUFBTSxFQUFFLFNBQVMsQ0FBQyxJQUFJLElBQUksRUFBRTtRQUNyQyxLQUFLLE1BQU0sQ0FBQyxHQUFHLEVBQUUsUUFBUSxDQUFDLElBQUksU0FBUyxFQUFFO1lBQ3RDLE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQTtZ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QVc7SUFDdkMsUUFBUSxDQUFDLFFBQVEsRUFBRSxPQUFPLEVBQUUsR0FBRyxDQUFDLEVBQUUsV0FBVyxFQUFFLENBQUE7QUFDbEQsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gICBjcmVhdGVFbnZpcm9ubWVudEluamVjdG9yLFxuICAgRW52aXJvbm1lbnRJbmplY3RvcixcbiAgIEVycm9ySGFuZGxlcixcbiAgIGluamVjdCxcbiAgIElOSkVDVE9SLFxuICAgUHJvdmlkZXJUb2tlblxufSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuaW1wb3J0IHtEZXBNYXAsIEV2ZW50VHlwZSwgUGhhc2UsIFNlbGVjdE1ldGFkYXRhfSBmcm9tIFwiLi9pbnRlcmZhY2VzXCI7XG5pbXBvcnQge1xuICAgZ2V0QWN0aW9ucyxcbiAgIGdldERlcHMsXG4gICBnZXRNZXRhLFxuICAgZ2V0TWV0YVZhbHVlcyxcbiAgIGdldFNlbGVjdG9ycyxcbiAgIGdldFRva2VuLFxuICAgaW5qZWN0b3IsXG4gICBtYXJrRGlydHksXG4gICBzZXRNZXRhLFxuICAgdHJhY2tlZFxufSBmcm9tIFwiLi9tZXRhZGF0YVwiO1xuaW1wb3J0IHtcbiAgIEFDVElPTixcbiAgIENoYW5nZXMsXG4gICBDT05URVhULFxuICAgRWZmZWN0U2NoZWR1bGVyLFxuICAgRXZlbnRTY2hlZHVsZXIsXG4gICBST09UX0NPTkZJRyxcbiAgIFNUT1JFX0NPTkZJRyxcbiAgIFN0b3JlRXJyb3JIYW5kbGVyLFxuICAgVGVhcmRvd25cbn0gZnJvbSBcIi4vcHJvdmlkZXJzXCI7XG5pbXBvcnQge2NyZWF0ZVByb3h5LCBnZXRDaGFuZ2VzLCBwb3BTdGFjaywgcHVzaFN0YWNrLCB1bnRyYWNrfSBmcm9tIFwiLi9wcm94eVwiO1xuaW1wb3J0IHtzdG9yZSwgc3Vic2NyaWJlfSBmcm9tIFwiLi9zZWxlY3RcIjtcbmltcG9ydCB7Y2FsbCwgd3JhcH0gZnJvbSBcIi4vdXRpbHNcIjtcblxuZnVuY3Rpb24gY2hlY2tEZXBzKGRlcHM6IERlcE1hcCkge1xuICAgbGV0IGRpcnR5ID0gZmFsc2VcbiAgIGZvciAoY29uc3QgW29iamVjdCwga2V5VmFsdWVzXSBvZiBkZXBzKSB7XG4gICAgICBmb3IgKGNvbnN0IFtrZXksIHByZXZpb3VzXSBvZiBrZXlWYWx1ZXMpIHtcbiAgICAgICAgIGNvbnN0IGN1cnJlbnQgPSBvYmplY3Rba2V5XVxuICAgICAgICAgaWYgKCFPYmplY3QuaXMoY3VycmVudCwgcHJldmlvdXMpKSB7XG4gICAgICAgICAgICBrZXlWYWx1ZXMuc2V0KGtleSwgY3VycmVudClcbiAgICAgICAgICAgIGRpcnR5ID0gdHJ1ZVxuICAgICAgICAgfVxuICAgICAgfVxuICAgfVxuICAgcmV0dXJuIGRpcnR5XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBkZWNvcmF0ZUNoZWNrKHRhcmdldDoge30sIG5hbWU6IFBoYXNlKSB7XG4gICBjb25zdCBhY3Rpb25zID0gZ2V0QWN0aW9ucyh0YXJnZXQsIG5hbWUpXG4gICB3cmFwKHRhcmdldCwgbmFtZSwgZnVuY3Rpb24gY2hlY2soZm4pIHtcbiAgICAgIGNvbnN0IGV2ZW50cyA9IGdldFRva2VuKEV2ZW50U2NoZWR1bGVyLCB0aGlzKVxuICAgICAgZm9yIChjb25zdCBhY3Rpb24gb2YgYWN0aW9ucykge1xuICAgICAgICAgY29uc3QgZGVwcyA9IGdldERlcHModGhpcywgYWN0aW9uLmtleSlcbiAgICAgICAgIGNvbnN0IGRpcnR5ID0gYWN0aW9uLnRyYWNrICYmIGRlcHMgJiYgY2hlY2tEZXBzKGRlcHMpXG4gICAgICAgICBpZiAoYWN0aW9uLmRlc2NyaXB0b3I/LnZhbHVlLmxlbmd0aCA9PT0gMCAmJiAoIWRlcHMgJiYgYWN0aW9uLmltbWVkaWF0ZSAmJiBhY3Rpb24ucGhhc2UgPT09IG5hbWUgfHwgZGlydHkpKSB7XG4gICAgICAgICAgICBtYXJrRGlydHkodGhpcylcbiAgICAgICAgICAgIGNhbGwodGhpcywgYWN0aW9uLmtleSlcbiAgICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGZvciAoY29uc3QgYWN0aW9uIG9mIGFjdGlvbnMpIHtcbiAgICAgICAgIGNvbnN0IGVmZmVjdCA9IGdldFRva2VuKEVmZmVjdFNjaGVkdWxlciwgdGhpcywgYWN0aW9uLmtleSlcbiAgICAgICAgIGVmZmVjdC5kZXF1ZXVlKClcbiAgICAgIH1cbiAgICAgIGlmIChldmVudHMuZmx1c2goKSkge1xuICAgICAgICAgY2hlY2suY2FsbCh0aGlzLCBmbilcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgICBmbi5hcHBseSh0aGlzKVxuICAgICAgfVxuICAgfSlcbn1cblxuZnVuY3Rpb24gZ2V0Q29uZmlnKCkge1xuICAgcmV0dXJuIGluamVjdChTVE9SRV9DT05GSUcsIHsgc2VsZjogdHJ1ZSwgb3B0aW9uYWw6IHRydWUgfSkgPz8gaW5qZWN0KFJPT1RfQ09ORklHKVxufVxuXG5mdW5jdGlvbiBwcm92aWRlVmFsdWUocHJvdmlkZTogYW55LCB1c2VWYWx1ZTogYW55KSB7XG4gICByZXR1cm4geyBwcm92aWRlLCB1c2VWYWx1ZX1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNldHVwKHRhcmdldDogYW55LCBmYWN0b3J5OiBhbnksIC4uLmFyZ3M6IGFueVtdKSB7XG4gICBjb25zdCBpbnN0YW5jZSA9IGZhY3RvcnkoLi4uYXJncylcbiAgIGNvbnN0IHByb3RvdHlwZSA9IHRhcmdldC5wcm90b3R5cGVcbiAgIGNvbnN0IHBhcmVudCA9IGluamVjdChJTkpFQ1RPUikgYXMgRW52aXJvbm1lbnRJbmplY3RvclxuICAgY29uc3Qgc3RvcmVJbmplY3RvciA9IGNyZWF0ZUVudmlyb25tZW50SW5qZWN0b3IoW1xuICAgICAgcHJvdmlkZVZhbHVlKENoYW5nZXMsIG5ldyBDaGFuZ2VzKGluc3RhbmNlKSksXG4gICAgICBwcm92aWRlVmFsdWUoRXJyb3JIYW5kbGVyLCBuZXcgU3RvcmVFcnJvckhhbmRsZXIocHJvdG90eXBlLCBpbnN0YW5jZSkpLFxuICAgICAgcHJvdmlkZVZhbHVlKEV2ZW50U2NoZWR1bGVyLCBuZXcgRXZlbnRTY2hlZHVsZXIoaW5zdGFuY2UpKSxcbiAgICAgIFRlYXJkb3duXG4gICBdLCBwYXJlbnQpXG4gICBsZXQgc3RvcmVDb25maWcgPSBnZXRDb25maWcoKVxuICAgc2V0TWV0YShpbmplY3Rvciwgc3RvcmVJbmplY3RvciwgaW5zdGFuY2UpXG4gICBmb3IgKGNvbnN0IGFjdGlvbiBvZiBnZXRBY3Rpb25zKHByb3RvdHlwZSkpIHtcbiAgICAgIGNvbnN0IGFjdGlvbkluamVjdG9yID0gY3JlYXRlRW52aXJvbm1lbnRJbmplY3RvcihbXG4gICAgICAgICBwcm92aWRlVmFsdWUoQUNUSU9OLCBhY3Rpb24pLFxuICAgICAgICAgcHJvdmlkZVZhbHVlKENPTlRFWFQsIHsgaW5zdGFuY2UgfSksXG4gICAgICAgICBFZmZlY3RTY2hlZHVsZXIsXG4gICAgICAgICBUZWFyZG93bixcbiAgICAgICAgIHN0b3JlQ29uZmlnPy5hY3Rpb25Qcm92aWRlcnMgPz8gW11cbiAgICAgIF0sIHN0b3JlSW5qZWN0b3IpXG4gICAgICBzZXRNZXRhKGluamVjdG9yLCBhY3Rpb25JbmplY3RvciwgaW5zdGFuY2UsIGFjdGlvbi5rZXkpXG4gICB9XG4gICByZXR1cm4gaW5zdGFuY2Vcbn1cblxuZXhwb3J0IGNvbnN0IHN0b3JlcyA9IG5ldyBTZXQ8YW55PigpXG5jb25zdCBkZWNvcmF0ZWQgPSBuZXcgV2Vha1NldCgpXG5cbmV4cG9ydCBmdW5jdGlvbiBkZWNvcmF0ZUZhY3RvcnkodGFyZ2V0OiBhbnksIGZuOiAodGhpczogYW55LCAuLi5hcmdzOiBhbnlbXSkgPT4gYW55LCAuLi5hZGRpdGlvbmFsQXJnczogYW55W10pIHtcbiAgIGNvbnN0IGZhY3RvcnkgPSB0YXJnZXRbXCLJtWZhY1wiXVxuICAgaWYgKGZhY3RvcnkpIHtcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIFwiybVmYWNcIiwge1xuICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgdmFsdWU6IGZ1bmN0aW9uICguLi5hcmdzOiBhbnlbXSkge1xuICAgICAgICAgICAgcmV0dXJuIGZuKHRhcmdldCwgZmFjdG9yeSwgLi4uYWRkaXRpb25hbEFyZ3MsIC4uLmFyZ3MpXG4gICAgICAgICB9XG4gICAgICB9KVxuICAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gcnVuSW5Db250ZXh0PFQgZXh0ZW5kcyAoLi4uYXJnczogYW55KSA9PiBhbnk+KGRlcHM6IERlcE1hcCwgZm46IFQsIGNvbnRleHQgPSB7fSwgY2F0Y2hFcnJvciA9IHRydWUsIGtleT86IHN0cmluZywgLi4uYXJnczogUGFyYW1ldGVyczxUPikge1xuICAgY29uc3QgaW5qZWN0b3IgPSBnZXRUb2tlbihFbnZpcm9ubWVudEluamVjdG9yLCB1bnRyYWNrKGNvbnRleHQpLCBrZXkpXG4gICBjb25zdCBlcnJvckhhbmRsZXIgPSBpbmplY3Rvci5nZXQoRXJyb3JIYW5kbGVyKVxuICAgcHVzaFN0YWNrKGRlcHMpXG4gICB0cnkge1xuICAgICAgcmV0dXJuIGluamVjdG9yLnJ1bkluQ29udGV4dCgoKSA9PiBmbi5hcHBseShjb250ZXh0LCBhcmdzKSlcbiAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGlmIChjYXRjaEVycm9yKSB7XG4gICAgICAgICBlcnJvckhhbmRsZXIuaGFuZGxlRXJyb3IoZSlcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgICB0aHJvdyBlXG4gICAgICB9XG4gICB9IGZpbmFsbHkge1xuICAgICAgcG9wU3RhY2soKVxuICAgfVxufVxuXG5mdW5jdGlvbiBydW5BY3Rpb24odGhpczogYW55LCBmbjogYW55LCBrZXk6IGFueSwgZGVwczogRGVwTWFwLCBhcmdzOiBhbnlbXSkge1xuICAgY29uc3QgZXZlbnQgPSBpbmplY3QoRXZlbnRTY2hlZHVsZXIpXG4gICBldmVudC5zY2hlZHVsZShFdmVudFR5cGUuRGlzcGF0Y2gsIGtleSwgYXJncy5sZW5ndGggPT09IDEgPyBhcmdzWzBdIDogYXJncywgZ2V0Q2hhbmdlcyhkZXBzKSlcbiAgIHJldHVybiBmbi5hcHBseSh0aGlzLCBhcmdzKVxufVxuXG5leHBvcnQgZnVuY3Rpb24gZGVjb3JhdGVBY3Rpb25zKHRhcmdldDoge30pIHtcbiAgIGZvciAoY29uc3QgeyBrZXksIGNhdGNoRXJyb3IgfSBvZiBnZXRBY3Rpb25zKHRhcmdldCkpIHtcbiAgICAgIHdyYXAodGFyZ2V0LCBrZXksIGZ1bmN0aW9uIChmbiwgLi4uYXJncykge1xuICAgICAgICAgY29uc3QgcHJveHkgPSBjcmVhdGVQcm94eSh0aGlzKVxuICAgICAgICAgY29uc3QgZGVwcyA9IG5ldyBNYXAoKVxuICAgICAgICAgc2V0TWV0YSh0cmFja2VkLCBkZXBzLCB0aGlzLCBrZXkpXG4gICAgICAgICB0ZWFyZG93bih0aGlzLCBrZXkpXG4gICAgICAgICByZXR1cm4gcnVuSW5Db250ZXh0KGRlcHMsIHJ1bkFjdGlvbiwgcHJveHksIGNhdGNoRXJyb3IsIGtleSwgZm4sIGtleSwgZGVwcywgYXJncylcbiAgICAgIH0pXG4gICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBkZWNvcmF0ZVNlbGVjdCh0YXJnZXQ6IGFueSkge1xuICAgdGFyZ2V0LnByb3RvdHlwZS5uZ09uU2VsZWN0ID8/PSBmdW5jdGlvbiAodGhpczogYW55LCBvYnNlcnZlcjogYW55KSB7XG4gICAgICByZXR1cm4gc3RvcmUodGFyZ2V0KS5zdWJzY3JpYmUob2JzZXJ2ZXIpXG4gICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBkZWNvcmF0ZVNlbGVjdG9ycyh0YXJnZXQ6IHt9KSB7XG4gICBmb3IgKGNvbnN0IHsga2V5IH0gb2YgZ2V0U2VsZWN0b3JzPFNlbGVjdE1ldGFkYXRhPih0YXJnZXQsIHRydWUpKSB7XG4gICAgICB3cmFwKHRhcmdldCwga2V5LCBmdW5jdGlvbiAoZm4sIC4uLmFyZ3MpIHtcbiAgICAgICAgIGNvbnN0IGNhY2hlS2V5ID0ga2V5ICsgSlNPTi5zdHJpbmdpZnkoYXJncylcbiAgICAgICAgIGNvbnN0IHByb3h5ID0gY3JlYXRlUHJveHkodGhpcylcbiAgICAgICAgIGNvbnN0IGRlcHMgPSBnZXREZXBzKHRoaXMsIGNhY2hlS2V5KVxuICAgICAgICAgY29uc3QgZGlydHkgPSBkZXBzID8gY2hlY2tEZXBzKGRlcHMpIDogdHJ1ZVxuICAgICAgICAgbGV0IHJlc3VsdCA9IGdldE1ldGEoY2FjaGVLZXksIHRoaXMsIGtleSlcbiAgICAgICAgIGlmIChkaXJ0eSkge1xuICAgICAgICAgICAgY29uc3QgbmV3RGVwcyA9IG5ldyBNYXAoKVxuICAgICAgICAgICAgcmVzdWx0ID0gcnVuSW5Db250ZXh0KG5ld0RlcHMsIGZuLCBwcm94eSwgdHJ1ZSwgdm9pZCAwLCAuLi5hcmdzKVxuICAgICAgICAgICAgc2V0TWV0YShjYWNoZUtleSwgcmVzdWx0LCB0aGlzLCBrZXkpXG4gICAgICAgICAgICBzZXRNZXRhKHRyYWNrZWQsIG5ld0RlcHMsIHRoaXMsIGNhY2hlS2V5KVxuICAgICAgICAgfVxuICAgICAgICAgcmV0dXJuIHJlc3VsdFxuICAgICAgfSlcbiAgIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGRlY29yYXRlQ2hhbmdlcyh0YXJnZXQ6IHt9KSB7XG4gICB3cmFwKHRhcmdldCwgXCJuZ09uQ2hhbmdlc1wiLCBmdW5jdGlvbiAoZm4sIHZhbHVlKSB7XG4gICAgICBjb25zdCBldmVudHMgPSBnZXRUb2tlbihFdmVudFNjaGVkdWxlciwgdGhpcylcbiAgICAgIGNvbnN0IGNoYW5nZXMgPSBPYmplY3QuZW50cmllcyh2YWx1ZSkubWFwKChba2V5LCBjaGFuZ2VdKSA9PiBba2V5LCAoY2hhbmdlIGFzIGFueSkucHJldmlvdXNWYWx1ZV0pIGFzIGFueVtdXG4gICAgICBldmVudHMuc2NoZWR1bGUoRXZlbnRUeXBlLkRpc3BhdGNoLCBcIm5nT25DaGFuZ2VzXCIsIHsuLi52YWx1ZX0sIG5ldyBNYXAoW1t0aGlzLCBuZXcgTWFwKGNoYW5nZXMpXV0pKVxuICAgICAgZm4uY2FsbCh0aGlzLCB2YWx1ZSlcbiAgIH0pXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBkZWNvcmF0ZU9uSW5pdCh0YXJnZXQ6IHt9KSB7XG4gICB3cmFwKHRhcmdldCwgXCJuZ09uSW5pdFwiLCBmdW5jdGlvbiAoZm4pIHtcbiAgICAgIGNvbnN0IGluamVjdG9yID0gZ2V0VG9rZW4oRW52aXJvbm1lbnRJbmplY3RvciwgdGhpcylcbiAgICAgIGZvciAoY29uc3QgYXR0YWNobWVudCBvZiBnZXRTZWxlY3RvcnM8eyB0b2tlbjogUHJvdmlkZXJUb2tlbjxhbnk+IHwgdW5kZWZpbmVkIH0+KHRhcmdldCwgZmFsc2UpKSB7XG4gICAgICAgICBpbmplY3Rvci5ydW5JbkNvbnRleHQoKCkgPT4ge1xuICAgICAgICAgICAgc3Vic2NyaWJlKGF0dGFjaG1lbnQudG9rZW4sIHRoaXMsIGF0dGFjaG1lbnQua2V5KVxuICAgICAgICAgfSlcbiAgICAgIH1cbiAgICAgIGZuLmNhbGwodGhpcylcbiAgIH0pXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBkZWNvcmF0ZURlc3Ryb3kodGFyZ2V0OiB7fSkge1xuICAgd3JhcCh0YXJnZXQsIFwibmdPbkRlc3Ryb3lcIiwgZnVuY3Rpb24gKGZuKSB7XG4gICAgICBmb3IgKGNvbnN0IGVudmlyb25tZW50SW5qZWN0b3Igb2YgZ2V0TWV0YVZhbHVlczxFbnZpcm9ubWVudEluamVjdG9yPihpbmplY3RvciwgdGhpcykpIHtcbiAgICAgICAgIGVudmlyb25tZW50SW5qZWN0b3IuZGVzdHJveSgpXG4gICAgICB9XG4gICAgICBmbi5hcHBseSh0aGlzKVxuICAgfSlcbn1cblxuZnVuY3Rpb24gdGVhcmRvd24oY29udGV4dDoge30sIGtleTogc3RyaW5nKSB7XG4gICBnZXRUb2tlbihUZWFyZG93biwgY29udGV4dCwga2V5KT8udW5zdWJzY3JpYmUoKVxufVxuIl19