@angular-redux-ivy/form
Version:
Build Angular 2+ forms with Redux
238 lines • 32.5 kB
JavaScript
import { isCollection, Map as ImmutableMap } from 'immutable';
import { FormException } from './form-exception';
export class State {
static traverse(state, path, fn) {
let deepValue = state;
for (const k of path) {
const parent = deepValue;
if (isCollection(deepValue)) {
const m = deepValue;
if (typeof m.get === 'function') {
deepValue = m.get(k);
}
else {
throw new FormException(`Cannot retrieve value from immutable nonassociative container: ${k}`);
}
}
else if (deepValue instanceof Map) {
deepValue = deepValue.get(k);
}
else {
deepValue = deepValue[k];
}
if (typeof fn === 'function') {
const transformed = fn(parent, k, path.slice(path.indexOf(k) + 1), deepValue);
deepValue = transformed[k];
Object.assign(parent, transformed);
}
// If we were not able to find this state inside of our root state
// structure, then we return undefined -- not null -- to indicate that
// state. But this could be a perfectly normal use-case so we don't
// want to throw an exception or anything along those lines.
if (deepValue === undefined) {
return undefined;
}
}
return deepValue;
}
static get(state, path) {
return State.traverse(state, path);
}
static assign(state, path, value) {
const operations = State.inspect(state);
if (path.length === 0) {
return operations.update(null, value);
}
const root = operations.clone();
// We want to shallow clone the object, and then trace a path to the place
// we want to update, cloning each object we traversed on our way and then
// finally updating the value on the last parent to be @value. This seems
// to offer the best performance: we can shallow clone everything that has
// not been modified, and {deep clone + update} the path down to the value
// that we wish to update.
State.traverse(root, path, (parent, key, remainingPath, innerValue) => {
const parentOperations = State.inspect(parent);
if (innerValue) {
const innerOperations = State.inspect(innerValue);
return parentOperations.update(key, remainingPath.length > 0
? innerOperations.clone()
: innerOperations.merge(null, value));
}
else {
const getProbableType = (stateKey) => {
// NOTE(cbond): If your code gets here, you might not be using the library
/// correctly. If you are assigning into a path in your state, try to
/// ensure that there is a path to traverse, even if everything is just
/// empty objects and arrays. If we have to guess the type of the containers
/// and then create them ourselves, we may not get the types right. Use
/// the Redux `initial state' construct to resolve this issue if you like.
return typeof stateKey === 'number'
? new Array()
: Array.isArray(stateKey)
? ImmutableMap()
: new Object();
};
return parentOperations.update(key, remainingPath.length > 0
? getProbableType(remainingPath[0])
: value);
}
});
return root;
}
static inspect(object) {
const metaOperations = (
// TODO: Write proper type declarations for following Function types
update, merge, clone) => {
const operations = {
/// Clone the object (shallow)
clone: typeof clone === 'function'
? () => clone(object)
: () => object,
/// Update a specific key inside of the container object
update: (key, value) => update(operations.clone(), key, value),
/// Merge existing values with new values
merge: (key, value) => {
const cloned = operations.clone();
return merge(cloned, key, value, (v) => update(cloned, key, v));
},
};
return operations;
};
if (isCollection(object)) {
return metaOperations(
// Replace
(parent, key, value) => {
if (key != null) {
return parent.set(key, value);
}
else {
return value;
}
},
// Merge
(parent, key, value) => {
if (key) {
return parent.mergeDeepIn(Array.isArray(key) ? key : [key], value);
}
else {
if (ImmutableMap.isMap(value)) {
return parent.mergeDeep(value);
}
else {
return parent.concat(value);
}
}
});
}
else if (Array.isArray(object)) {
return metaOperations(
// Replace array contents
(parent, key, value) => {
if (key != null) {
parent[key] = value;
}
else {
parent.splice.apply(parent, [0, parent.length].concat(Array.isArray(value) ? value : [value]));
}
},
// Merge
(parent, _, value, setter) => {
setter(parent.concat(value));
return parent;
},
// Clone
() => Array.prototype.slice.call(object, 0));
}
else if (object instanceof Map) {
return metaOperations(
// Update map key
(parent, key, value) => {
if (key != null) {
return parent.set(key, value);
}
else {
const m = new Map(value);
parent.clear();
m.forEach((mapValue, index) => parent.set(index, mapValue));
return parent;
}
},
// Merge
(parent, _, value) => {
const m = new Map(value);
m.forEach((mapValue, key) => parent.set(key, mapValue));
return parent;
},
// Clone
() => object instanceof WeakMap
? new WeakMap(object)
: new Map(object));
}
else if (object instanceof WeakSet || object instanceof Set) {
return metaOperations(
// Update element at index in set
(parent, key, value) => {
if (key != null) {
return parent.set(key, value);
}
else {
const s = new Set(value);
s.forEach((setValue, index) => parent.set(index, setValue));
s.clear();
return parent;
}
},
// Merge
(parent, _, value) => {
for (const element of value) {
parent.add(element);
}
return parent;
},
// Clone
() => object instanceof WeakSet
? new WeakSet(object)
: new Set(object));
}
else if (object instanceof Date) {
throw new FormException('Cannot understand why a Date object appears in the mutation path!');
}
else {
switch (typeof object) {
case 'boolean':
case 'function':
case 'number':
case 'string':
case 'symbol':
case 'undefined':
break;
case 'object':
if (object == null) {
break;
}
return metaOperations((parent, key, value) => {
if (key != null) {
return { ...parent, [key]: value };
}
return { ...parent, ...value };
}, (parent, _, value) => {
for (const k of Object.keys(value)) {
parent[k] = value[k];
}
return parent;
}, () => ({ ...object }));
default:
break;
}
}
throw new Error(`An object of type ${typeof object} has appeared in the mutation path! Every element ` +
'in the mutation path should be an array, an associative container, or a set');
}
static empty(value) {
return (value == null ||
(value.length === 0 ||
(typeof value.length === 'undefined' &&
Object.keys(value).length === 0)));
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhdGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc3RhdGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFlBQVksRUFBRSxHQUFHLElBQUksWUFBWSxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBRTlELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQW9CakQsTUFBTSxPQUFnQixLQUFLO0lBQ3pCLE1BQU0sQ0FBQyxRQUFRLENBQ2IsS0FBZ0IsRUFDaEIsSUFBYyxFQUNkLEVBQXFCO1FBRXJCLElBQUksU0FBUyxHQUFHLEtBQUssQ0FBQztRQUV0QixLQUFLLE1BQU0sQ0FBQyxJQUFJLElBQUksRUFBRTtZQUNwQixNQUFNLE1BQU0sR0FBRyxTQUFTLENBQUM7WUFFekIsSUFBSSxZQUFZLENBQUMsU0FBUyxDQUFDLEVBQUU7Z0JBQzNCLE1BQU0sQ0FBQyxHQUFJLFNBQThDLENBQUM7Z0JBQzFELElBQUksT0FBTyxDQUFDLENBQUMsR0FBRyxLQUFLLFVBQVUsRUFBRTtvQkFDL0IsU0FBUyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7aUJBQ3RCO3FCQUFNO29CQUNMLE1BQU0sSUFBSSxhQUFhLENBQ3JCLGtFQUFrRSxDQUFDLEVBQUUsQ0FDdEUsQ0FBQztpQkFDSDthQUNGO2lCQUFNLElBQUksU0FBUyxZQUFZLEdBQUcsRUFBRTtnQkFDbkMsU0FBUyxHQUFLLFNBQXNDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO2FBQzdEO2lCQUFNO2dCQUNMLFNBQVMsR0FBSSxTQUFpQixDQUFDLENBQUMsQ0FBQyxDQUFDO2FBQ25DO1lBRUQsSUFBSSxPQUFPLEVBQUUsS0FBSyxVQUFVLEVBQUU7Z0JBQzVCLE1BQU0sV0FBVyxHQUFHLEVBQUUsQ0FDcEIsTUFBTSxFQUNOLENBQUMsRUFDRCxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMs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QUFDLE1BQU0sS0FBSyxDQUFDO2dCQUNqQixDQUFDLE9BQU8sS0FBSyxDQUFDLE1BQU0sS0FBSyxXQUFXO29CQUNsQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLE1BQU0sS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUN0QyxDQUFDO0lBQ0osQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgaXNDb2xsZWN0aW9uLCBNYXAgYXMgSW1tdXRhYmxlTWFwIH0gZnJvbSAnaW1tdXRhYmxlJztcblxuaW1wb3J0IHsgRm9ybUV4Y2VwdGlvbiB9IGZyb20gJy4vZm9ybS1leGNlcHRpb24nO1xuXG5leHBvcnQgaW50ZXJmYWNlIE9wZXJhdGlvbnM8VD4ge1xuICAvLy8gU2hhbGxvdyBjbG9uZSB0aGUgb2JqZWN0XG4gIGNsb25lKCk6IFQ7XG5cbiAgLy8vIENsb25lIGFuZCBtZXJnZVxuICBtZXJnZShrZXk6IG51bWJlciB8IHN0cmluZyB8IG51bGwsIHZhbHVlOiBUKTogYW55O1xuXG4gIC8vLyBDbG9uZSB0aGUgb2JqZWN0IGFuZCB1cGRhdGUgYSBzcGVjaWZpYyBrZXkgaW5zaWRlIG9mIGl0XG4gIHVwZGF0ZShrZXk6IG51bWJlciB8IHN0cmluZyB8IG51bGwsIHZhbHVlOiBUKTogYW55O1xufVxuXG5leHBvcnQgdHlwZSBUcmF2ZXJzZUNhbGxiYWNrID0gKFxuICBwYXJlbnQ6IGFueSxcbiAga2V5OiBudW1iZXIgfCBzdHJpbmcsXG4gIHJlbWFpbmluZ1BhdGg6IHN0cmluZ1tdLFxuICB2YWx1ZT86IGFueSxcbikgPT4gYW55O1xuXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgU3RhdGUge1xuICBzdGF0aWMgdHJhdmVyc2U8U3RhdGVUeXBlPihcbiAgICBzdGF0ZTogU3RhdGVUeXBlLFxuICAgIHBhdGg6IHN0cmluZ1tdLFxuICAgIGZuPzogVHJhdmVyc2VDYWxsYmFjayxcbiAgKSB7XG4gICAgbGV0IGRlZXBWYWx1ZSA9IHN0YXRlO1xuXG4gICAgZm9yIChjb25zdCBrIG9mIHBhdGgpIHtcbiAgICAgIGNvbnN0IHBhcmVudCA9IGRlZXBWYWx1ZTtcblxuICAgICAgaWYgKGlzQ29sbGVjdGlvbihkZWVwVmFsdWUpKSB7XG4gICAgICAgIGNvbnN0IG0gPSAoZGVlcFZhbHVlIGFzIGFueSkgYXMgSW1tdXRhYmxlTWFwPHN0cmluZywgYW55PjtcbiAgICAgICAgaWYgKHR5cGVvZiBtLmdldCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgIGRlZXBWYWx1ZSA9IG0uZ2V0KGspO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IG5ldyBGb3JtRXhjZXB0aW9uKFxuICAgICAgICAgICAgYENhbm5vdCByZXRyaWV2ZSB2YWx1ZSBmcm9tIGltbXV0YWJsZSBub25hc3NvY2lhdGl2ZSBjb250YWluZXI6ICR7a31gLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoZGVlcFZhbHVlIGluc3RhbmNlb2YgTWFwKSB7XG4gICAgICAgIGRlZXBWYWx1ZSA9ICgoZGVlcFZhbHVlIGFzIGFueSkgYXMgTWFwPHN0cmluZywgYW55PikuZ2V0KGspO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZGVlcFZhbHVlID0gKGRlZXBWYWx1ZSBhcyBhbnkpW2tdO1xuICAgICAgfVxuXG4gICAgICBpZiAodHlwZW9mIGZuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGNvbnN0IHRyYW5zZm9ybWVkID0gZm4oXG4gICAgICAgICAgcGFyZW50LFxuICAgICAgICAgIGssXG4gICAgICAgICAgcGF0aC5zbGljZShwYXRoLmluZGV4T2YoaykgKyAxKSxcbiAgICAgICAgICBkZWVwVmFsdWUsXG4gICAgICAgICk7XG5cbiAgICAgICAgZGVlcFZhbHVlID0gdHJhbnNmb3JtZWRba107XG5cbiAgICAgICAgT2JqZWN0LmFzc2lnbihwYXJlbnQsIHRyYW5zZm9ybWVkKTtcbiAgICAgIH1cblxuICAgICAgLy8gSWYgd2Ugd2VyZSBub3QgYWJsZSB0byBmaW5kIHRoaXMgc3RhdGUgaW5zaWRlIG9mIG91ciByb290IHN0YXRlXG4gICAgICAvLyBzdHJ1Y3R1cmUsIHRoZW4gd2UgcmV0dXJuIHVuZGVmaW5lZCAtLSBub3QgbnVsbCAtLSB0byBpbmRpY2F0ZSB0aGF0XG4gICAgICAvLyBzdGF0ZS4gQnV0IHRoaXMgY291bGQgYmUgYSBwZXJmZWN0bHkgbm9ybWFsIHVzZS1jYXNlIHNvIHdlIGRvbid0XG4gICAgICAvLyB3YW50IHRvIHRocm93IGFuIGV4Y2VwdGlvbiBvciBhbnl0aGluZyBhbG9uZyB0aG9zZSBsaW5lcy5cbiAgICAgIGlmIChkZWVwVmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBkZWVwVmFsdWU7XG4gIH1cblxuICBzdGF0aWMgZ2V0PFN0YXRlVHlwZT4oc3RhdGU6IFN0YXRlVHlwZSwgcGF0aDogc3RyaW5nW10pOiBhbnkge1xuICAgIHJldHVybiBTdGF0ZS50cmF2ZXJzZShzdGF0ZSwgcGF0aCk7XG4gIH1cblxuICBzdGF0aWMgYXNzaWduPFN0YXRlVHlwZT4oc3RhdGU6IFN0YXRlVHlwZSwgcGF0aDogc3RyaW5nW10sIHZhbHVlPzogYW55KSB7XG4gICAgY29uc3Qgb3BlcmF0aW9ucyA9IFN0YXRlLmluc3BlY3Qoc3RhdGUpO1xuXG4gICAgaWYgKHBhdGgubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gb3BlcmF0aW9ucy51cGRhdGUobnVsbCwgdmFsdWUpO1xuICAgIH1cblxuICAgIGNvbnN0IHJvb3QgPSBvcGVyYXRpb25zLmNsb25lKCk7XG5cbiAgICAvLyBXZSB3YW50IHRvIHNoYWxsb3cgY2xvbmUgdGhlIG9iamVjdCwgYW5kIHRoZW4gdHJhY2UgYSBwYXRoIHRvIHRoZSBwbGFjZVxuICAgIC8vIHdlIHdhbnQgdG8gdXBkYXRlLCBjbG9uaW5nIGVhY2ggb2JqZWN0IHdlIHRyYXZlcnNlZCBvbiBvdXIgd2F5IGFuZCB0aGVuXG4gICAgLy8gZmluYWxseSB1cGRhdGluZyB0aGUgdmFsdWUgb24gdGhlIGxhc3QgcGFyZW50IHRvIGJlIEB2YWx1ZS4gVGhpcyBzZWVtc1xuICAgIC8vIHRvIG9mZmVyIHRoZSBiZXN0IHBlcmZvcm1hbmNlOiB3ZSBjYW4gc2hhbGxvdyBjbG9uZSBldmVyeXRoaW5nIHRoYXQgaGFzXG4gICAgLy8gbm90IGJlZW4gbW9kaWZpZWQsIGFuZCB7ZGVlcCBjbG9uZSArIHVwZGF0ZX0gdGhlIHBhdGggZG93biB0byB0aGUgdmFsdWVcbiAgICAvLyB0aGF0IHdlIHdpc2ggdG8gdXBkYXRlLlxuICAgIFN0YXRlLnRyYXZlcnNlKFxuICAgICAgcm9vdCxcbiAgICAgIHBhdGgsXG4gICAgICAocGFyZW50LCBrZXk6IG51bWJlciB8IHN0cmluZywgcmVtYWluaW5nUGF0aDogc3RyaW5nW10sIGlubmVyVmFsdWU/KSA9PiB7XG4gICAgICAgIGNvbnN0IHBhcmVudE9wZXJhdGlvbnMgPSBTdGF0ZS5pbnNwZWN0KHBhcmVudCk7XG5cbiAgICAgICAgaWYgKGlubmVyVmFsdWUpIHtcbiAgICAgICAgICBjb25zdCBpbm5lck9wZXJhdGlvbnMgPSBTdGF0ZS5pbnNwZWN0KGlubmVyVmFsdWUpO1xuXG4gICAgICAgICAgcmV0dXJuIHBhcmVudE9wZXJhdGlvbnMudXBkYXRlKFxuICAgICAgICAgICAga2V5LFxuICAgICAgICAgICAgcmVtYWluaW5nUGF0aC5sZW5ndGggPiAwXG4gICAgICAgICAgICAgID8gaW5uZXJPcGVyYXRpb25zLmNsb25lKClcbiAgICAgICAgICAgICAgOiBpbm5lck9wZXJhdGlvbnMubWVyZ2UobnVsbCwgdmFsdWUpLFxuICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3QgZ2V0UHJvYmFibGVUeXBlID0gKHN0YXRlS2V5OiBzdHJpbmcgfCBudW1iZXIpID0+IHtcbiAgICAgICAgICAgIC8vIE5PVEUoY2JvbmQpOiBJZiB5b3VyIGNvZGUgZ2V0cyBoZXJlLCB5b3UgbWlnaHQgbm90IGJlIHVzaW5nIHRoZSBsaWJyYXJ5XG4gICAgICAgICAgICAvLy8gY29ycmVjdGx5LiBJZiB5b3UgYXJlIGFzc2lnbmluZyBpbnRvIGEgcGF0aCBpbiB5b3VyIHN0YXRlLCB0cnkgdG9cbiAgICAgICAgICAgIC8vLyBlbnN1cmUgdGhhdCB0aGVyZSBpcyBhIHBhdGggdG8gdHJhdmVyc2UsIGV2ZW4gaWYgZXZlcnl0aGluZyBpcyBqdXN0XG4gICAgICAgICAgICAvLy8gZW1wdHkgb2JqZWN0cyBhbmQgYXJyYXlzLiBJZiB3ZSBoYXZlIHRvIGd1ZXNzIHRoZSB0eXBlIG9mIHRoZSBjb250YWluZXJzXG4gICAgICAgICAgICAvLy8gYW5kIHRoZW4gY3JlYXRlIHRoZW0gb3Vyc2VsdmVzLCB3ZSBtYXkgbm90IGdldCB0aGUgdHlwZXMgcmlnaHQuIFVzZVxuICAgICAgICAgICAgLy8vIHRoZSBSZWR1eCBgaW5pdGlhbCBzdGF0ZScgY29uc3RydWN0IHRvIHJlc29sdmUgdGhpcyBpc3N1ZSBpZiB5b3UgbGlrZS5cbiAgICAgICAgICAgIHJldHVybiB0eXBlb2Ygc3RhdGVLZXkgPT09ICdudW1iZXInXG4gICAgICAgICAgICAgID8gbmV3IEFycmF5KClcbiAgICAgICAgICAgICAgOiBBcnJheS5pc0FycmF5KHN0YXRlS2V5KVxuICAgICAgICAgICAgICA/IEltbXV0YWJsZU1hcCgpXG4gICAgICAgICAgICAgIDogbmV3IE9iamVjdCgpO1xuICAgICAgICAgIH07XG5cbiAgICAgICAgICByZXR1cm4gcGFyZW50T3BlcmF0aW9ucy51cGRhdGUoXG4gICAgICAgICAgICBrZXksXG4gICAgICAgICAgICByZW1haW5pbmdQYXRoLmxlbmd0aCA+IDBcbiAgICAgICAgICAgICAgPyBnZXRQcm9iYWJsZVR5cGUocmVtYWluaW5nUGF0aFswXSlcbiAgICAgICAgICAgICAgOiB2YWx1ZSxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICk7XG5cbiAgICByZXR1cm4gcm9vdDtcbiAgfVxuXG4gIHN0YXRpYyBpbnNwZWN0PEs+KG9iamVjdDogSyk6IE9wZXJhdGlvbnM8Sz4ge1xuICAgIGNvbnN0IG1ldGFPcGVyYXRpb25zID0gKFxuICAgICAgLy8gVE9ETzogV3JpdGUgcHJvcGVyIHR5cGUgZGVjbGFyYXRpb25zIGZvciBmb2xsb3dpbmcgRnVuY3Rpb24gdHlwZXNcbiAgICAgIHVwZGF0ZTogRnVuY3Rpb24sXG4gICAgICBtZXJnZTogRnVuY3Rpb24sXG4gICAgICBjbG9uZT86IEZ1bmN0aW9uLFxuICAgICkgPT4ge1xuICAgICAgY29uc3Qgb3BlcmF0aW9ucyA9IHtcbiAgICAgICAgLy8vIENsb25lIHRoZSBvYmplY3QgKHNoYWxsb3cpXG4gICAgICAgIGNsb25lOlxuICAgICAgICAgIHR5cGVvZiBjbG9uZSA9PT0gJ2Z1bmN0aW9uJ1xuICAgICAgICAgICAgPyAoKSA9PiBjbG9uZShvYmplY3QgYXMgYW55KSBhcyBhbnlcbiAgICAgICAgICAgIDogKCkgPT4gb2JqZWN0LFxuXG4gICAgICAgIC8vLyBVcGRhdGUgYSBzcGVjaWZpYyBrZXkgaW5zaWRlIG9mIHRoZSBjb250YWluZXIgb2JqZWN0XG4gICAgICAgIHVwZGF0ZTogKGtleTogc3RyaW5nLCB2YWx1ZTogSykgPT5cbiAgICAgICAgICB1cGRhdGUob3BlcmF0aW9ucy5jbG9uZSgpLCBrZXksIHZhbHVlKSxcblxuICAgICAgICAvLy8gTWVyZ2UgZXhpc3RpbmcgdmFsdWVzIHdpdGggbmV3IHZhbHVlc1xuICAgICAgICBtZXJnZTogKGtleTogc3RyaW5nLCB2YWx1ZTogSykgPT4ge1xuICAgICAgICAgIGNvbnN0IGNsb25lZCA9IG9wZXJhdGlvbnMuY2xvbmUoKTtcbiAgICAgICAgICByZXR1cm4gbWVyZ2UoY2xvbmVkLCBrZXksIHZhbHVlLCAodjogYW55KSA9PiB1cGRhdGUoY2xvbmVkLCBrZXksIHYpKTtcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIHJldHVybiBvcGVyYXRpb25zO1xuICAgIH07XG5cbiAgICBpZiAoaXNDb2xsZWN0aW9uKG9iamVjdCkpIHtcbiAgICAgIHJldHVybiBtZXRhT3BlcmF0aW9ucyhcbiAgICAgICAgLy8gUmVwbGFjZVxuICAgICAgICAocGFyZW50OiBhbnksIGtleTogbnVtYmVyIHwgc3RyaW5nLCB2YWx1ZTogSykgPT4ge1xuICAgICAgICAgIGlmIChrZXkgIT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIHBhcmVudC5zZXQoa2V5LCB2YWx1ZSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIC8vIE1lcmdlXG4gICAgICAgIChwYXJlbnQ6IGFueSwga2V5OiBudW1iZXIgfCBzdHJpbmcgfCBzdHJpbmdbXSwgdmFsdWU6IEspID0+IHtcbiAgICAgICAgICBpZiAoa2V5KSB7XG4gICAgICAgICAgICByZXR1cm4gcGFyZW50Lm1lcmdlRGVlcEluKEFycmF5LmlzQXJyYXkoa2V5KSA/IGtleSA6IFtrZXldLCB2YWx1ZSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmIChJbW11dGFibGVNYXAuaXNNYXAodmFsdWUpKSB7XG4gICAgICAgICAgICAgIHJldHVybiBwYXJlbnQubWVyZ2VEZWVwKHZhbHVlKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHJldHVybiBwYXJlbnQuY29uY2F0KHZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICApO1xuICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShvYmplY3QpKSB7XG4gICAgICByZXR1cm4gbWV0YU9wZXJhdGlvbnMoXG4gICAgICAgIC8vIFJlcGxhY2UgYXJyYXkgY29udGVudHNcbiAgICAgICAgKHBhcmVudDogYW55LCBrZXk6IG51bWJlciwgdmFsdWU6IEspID0+IHtcbiAgICAgICAgICBpZiAoa2V5ICE9IG51bGwpIHtcbiAgICAgICAgICAgIHBhcmVudFtrZXldID0gdmFsdWU7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHBhcmVudC5zcGxpY2UuYXBwbHkoXG4gICAgICAgICAgICAgIHBhcmVudCxcbiAgICAgICAgICAgICAgWzAsIHBhcmVudC5sZW5ndGhdLmNvbmNhdChBcnJheS5pc0FycmF5KHZhbHVlKSA/IHZhbHVlIDogW3ZhbHVlXSksXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICAvLyBNZXJnZVxuICAgICAgICAocGFyZW50OiBhbnksIF86IGFueSwgdmFsdWU6IEssIHNldHRlcjogKHY6IEspID0+IEspID0+IHtcbiAgICAgICAgICBzZXR0ZXIocGFyZW50LmNvbmNhdCh2YWx1ZSkpO1xuICAgICAgICAgIHJldHVybiBwYXJlbnQ7XG4gICAgICAgIH0sXG5cbiAgICAgICAgLy8gQ2xvbmVcbiAgICAgICAgKCkgPT4gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwob2JqZWN0LCAwKSxcbiAgICAgICk7XG4gICAgfSBlbHNlIGlmIChvYmplY3QgaW5zdGFuY2VvZiBNYXApIHtcbiAgICAgIHJldHVybiBtZXRhT3BlcmF0aW9ucyhcbiAgICAgICAgLy8gVXBkYXRlIG1hcCBrZXlcbiAgICAgICAgKHBhcmVudDogYW55LCBrZXk6IG51bWJlciB8IHN0cmluZywgdmFsdWU6IEspID0+IHtcbiAgICAgICAgICBpZiAoa2V5ICE9IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBwYXJlbnQuc2V0KGtleSwgdmFsdWUpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBtID0gbmV3IE1hcCh2YWx1ZSBhcyBhbnkpO1xuICAgICAgICAgICAgcGFyZW50LmNsZWFyKCk7XG4gICAgICAgICAgICBtLmZvckVhY2goKG1hcFZhbHVlLCBpbmRleCkgPT4gcGFyZW50LnNldChpbmRleCwgbWFwVmFsdWUpKTtcbiAgICAgICAgICAgIHJldHVybiBwYXJlbnQ7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuXG4gICAgICAgIC8vIE1lcmdlXG4gICAgICAgIChwYXJlbnQ6IE1hcDxzdHJpbmcsIGFueT4sIF86IGFueSwgdmFsdWU6IEspID0+IHtcbiAgICAgICAgICBjb25zdCBtID0gbmV3IE1hcDxzdHJpbmcsIGFueT4odmFsdWUgYXMgYW55KTtcbiAgICAgICAgICBtLmZvckVhY2goKG1hcFZhbHVlLCBrZXkpID0+IHBhcmVudC5zZXQoa2V5LCBtYXBWYWx1ZSkpO1xuICAgICAgICAgIHJldHVybiBwYXJlbnQ7XG4gICAgICAgIH0sXG5cbiAgICAgICAgLy8gQ2xvbmVcbiAgICAgICAgKCkgPT5cbiAgICAgICAgICBvYmplY3QgaW5zdGFuY2VvZiBXZWFrTWFwXG4gICAgICAgICAgICA/IG5ldyBXZWFrTWFwPG9iamVjdCwgYW55PihvYmplY3QgYXMgYW55KVxuICAgICAgICAgICAgOiBuZXcgTWFwPHN0cmluZywgYW55PihvYmplY3QgYXMgYW55KSxcbiAgICAgICk7XG4gICAgfSBlbHNlIGlmIChvYmplY3QgaW5zdGFuY2VvZiBXZWFrU2V0IHx8IG9iamVjdCBpbnN0YW5jZW9mIFNldCkge1xuICAgICAgcmV0dXJuIG1ldGFPcGVyYXRpb25zKFxuICAgICAgICAvLyBVcGRhdGUgZWxlbWVudCBhdCBpbmRleCBpbiBzZXRcbiAgICAgICAgKHBhcmVudDogYW55LCBrZXk6IG51bWJlciwgdmFsdWU6IEspID0+IHtcbiAgICAgICAgICBpZiAoa2V5ICE9IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBwYXJlbnQuc2V0KGtleSwgdmFsdWUpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBzID0gbmV3IFNldCh2YWx1ZSBhcyBhbnkpO1xuICAgICAgICAgICAgcy5mb3JFYWNoKChzZXRWYWx1ZSwgaW5kZXgpID0+IHBhcmVudC5zZXQoaW5kZXgsIHNldFZhbHVlKSk7XG4gICAgICAgICAgICBzLmNsZWFyKCk7XG4gICAgICAgICAgICByZXR1cm4gcGFyZW50O1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICAvLyBNZXJnZVxuICAgICAgICAocGFyZW50OiBTZXQ8YW55PiwgXzogYW55LCB2YWx1ZTogYW55KSA9PiB7XG4gICAgICAgICAgZm9yIChjb25zdCBlbGVtZW50IG9mIHZhbHVlKSB7XG4gICAgICAgICAgICBwYXJlbnQuYWRkKGVsZW1lbnQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gcGFyZW50O1xuICAgICAgICB9LFxuXG4gICAgICAgIC8vIENsb25lXG4gICAgICAgICgpID0+XG4gICAgICAgICAgb2JqZWN0IGluc3RhbmNlb2YgV2Vha1NldFxuICAgICAgICAgICAgPyBuZXcgV2Vha1NldDxhbnk+KG9iamVjdCBhcyBhbnkpXG4gICAgICAgICAgICA6IG5ldyBTZXQ8YW55PihvYmplY3QgYXMgYW55KSxcbiAgICAgICk7XG4gICAgfSBlbHNlIGlmIChvYmplY3QgaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgICB0aHJvdyBuZXcgRm9ybUV4Y2VwdGlvbihcbiAgICAgICAgJ0Nhbm5vdCB1bmRlcnN0YW5kIHdoeSBhIERhdGUgb2JqZWN0IGFwcGVhcnMgaW4gdGhlIG11dGF0aW9uIHBhdGghJyxcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN3aXRjaCAodHlwZW9mIG9iamVjdCkge1xuICAgICAgICBjYXNlICdib29sZWFuJzpcbiAgICAgICAgY2FzZSAnZnVuY3Rpb24nOlxuICAgICAgICBjYXNlICdudW1iZXInOlxuICAgICAgICBjYXNlICdzdHJpbmcnOlxuICAgICAgICBjYXNlICdzeW1ib2wnOlxuICAgICAgICBjYXNlICd1bmRlZmluZWQnOlxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdvYmplY3QnOlxuICAgICAgICAgIGlmIChvYmplY3QgPT0gbnVsbCkge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBtZXRhT3BlcmF0aW9ucyhcbiAgICAgICAgICAgIChwYXJlbnQ6IGFueSwga2V5OiBhbnksIHZhbHVlOiBLKSA9PiB7XG4gICAgICAgICAgICAgIGlmIChrZXkgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB7IC4uLnBhcmVudCwgW2tleV06IHZhbHVlIH07XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmV0dXJuIHsgLi4ucGFyZW50LCAuLi4odmFsdWUgYXMgYW55KSB9O1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIChwYXJlbnQ6IGFueSwgXzogYW55LCB2YWx1ZTogSykgPT4ge1xuICAgICAgICAgICAgICBmb3IgKGNvbnN0IGsgb2YgT2JqZWN0LmtleXModmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgcGFyZW50W2tdID0gKHZhbHVlIGFzIGFueSlba107XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmV0dXJuIHBhcmVudDtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAoKSA9PiAoeyAuLi4ob2JqZWN0IGFzIGFueSkgfSksXG4gICAgICAgICAgKTtcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgQW4gb2JqZWN0IG9mIHR5cGUgJHt0eXBlb2Ygb2JqZWN0fSBoYXMgYXBwZWFyZWQgaW4gdGhlIG11dGF0aW9uIHBhdGghIEV2ZXJ5IGVsZW1lbnQgYCArXG4gICAgICAgICdpbiB0aGUgbXV0YXRpb24gcGF0aCBzaG91bGQgYmUgYW4gYXJyYXksIGFuIGFzc29jaWF0aXZlIGNvbnRhaW5lciwgb3IgYSBzZXQnLFxuICAgICk7XG4gIH1cblxuICBzdGF0aWMgZW1wdHkodmFsdWU6IGFueSk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAoXG4gICAgICB2YWx1ZSA9PSBudWxsIHx8XG4gICAgICAodmFsdWUubGVuZ3RoID09PSAwIHx8XG4gICAgICAgICh0eXBlb2YgdmFsdWUubGVuZ3RoID09PSAndW5kZWZpbmVkJyAmJlxuICAgICAgICAgIE9iamVjdC5rZXlzKHZhbHVlKS5sZW5ndGggPT09IDApKVxuICAgICk7XG4gIH1cbn1cbiJdfQ==