UNPKG

@angular-redux-ivy/form

Version:

Build Angular 2+ forms with Redux

238 lines 32.5 kB
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==