UNPKG

ngrx-forms

Version:

Proper integration of forms in Angular 4 applications using ngrx

122 lines (120 loc) 18 kB
import { ALL_NGRX_FORMS_ACTION_TYPES } from './actions'; import { formArrayReducer } from './array/reducer'; import { formControlReducer } from './control/reducer'; import { formGroupReducer } from './group/reducer'; import { isArrayState, isFormState, isGroupState } from './state'; export function formStateReducer(state, action) { if (!state) { throw new Error('The form state must be defined!'); } if (!isFormState(state)) { throw new Error(`state must be a form state, got ${state}`); } if (isGroupState(state)) { return formGroupReducer(state, action); } if (isArrayState(state)) { return formArrayReducer(state, action); } return formControlReducer(state, action); } /** * This function creates a reducer function that first applies an action to the state * and afterwards applies all given update functions one after another to the resulting * form state. However, the update functions are only applied if the form state changed * as result of applying the action. If you need the update functions to be applied * regardless of whether the state changed (e.g. because the update function closes * over variables that may change independently of the form state) you can simply apply * the update manually (e.g. `updateFunction(formStateReducer(state, action))`). * * The following (contrived) example uses this function to create a reducer that after * each action validates the child control `name` to be required and sets the child * control `email`'s value to be `''` if the name is invalid. * ```typescript interface FormValue { name: string; email: string; } const updateFormState = updateGroup<FormValue>( { name: validate(required), }, { email: (email, parentGroup) => parentGroup.controls.name.isInvalid ? setValue('', email) : email, }, ); const reducer = createFormStateReducerWithUpdate<FormValue>(updateFormState); ``` */ export function createFormStateReducerWithUpdate(updateFnOrUpdateFnArr, ...updateFnArr) { updateFnArr = [...(Array.isArray(updateFnOrUpdateFnArr) ? updateFnOrUpdateFnArr : [updateFnOrUpdateFnArr]), ...updateFnArr]; return (state, action) => { const newState = formStateReducer(state, action); return newState === state ? state : updateFnArr.reduce((s, f) => f(s), newState); }; } function reduceNestedFormState(state, key, action) { const value = state[key]; if (!isFormState(value)) { return state; } return Object.assign(Object.assign({}, state), { [key]: formStateReducer(value, action) }); } function reduceNestedFormStates(state, action) { return Object.keys(state).reduce((s, key) => reduceNestedFormState(s, key, action), state); } /** * This function returns an object that can be passed to ngrx's `createReducer` * function (available starting with ngrx version 8). By doing this all form * state properties on the state will be updated whenever necessary (i.e. * whenever an ngrx-forms action is dispatched). * * To manually update a form state (e.g. to validate it) use * `wrapReducerWithFormStateUpdate`. */ export function onNgrxForms() { return { reducer: (state, action) => isFormState(state) ? formStateReducer(state, action) : reduceNestedFormStates(state, action), types: ALL_NGRX_FORMS_ACTION_TYPES, }; } /** * Define a reducer for a ngrx-forms action. This functions works the same as * ngrx's `on` except that you provide the ngrx-forms action class instead of * your action creator as a parameter. */ export function onNgrxFormsAction(actionCons, reducer) { return { reducer: (state, action) => reducer(reduceNestedFormStates(state, action), action), types: [actionCons.TYPE], }; } /** * This function wraps a reducer and returns another reducer that first calls * the given reducer and then calls the given update function for the form state * that is specified by the form state locator function. * * The update function is passed the form state and the updated containing state * as parameters. */ export function wrapReducerWithFormStateUpdate(reducer, formStateLocator, updateFn) { return (state, action) => { const updatedState = reducer(state, action); const formState = formStateLocator(updatedState); // if the state itself is the form state, update it directly if (formState === updatedState) { return updateFn(formState, updatedState); } const formStateKey = Object.keys(updatedState).find(key => updatedState[key] === formState); const updatedFormState = updateFn(formState, updatedState); if (updatedFormState === formState) { return updatedState; } return Object.assign(Object.assign({}, updatedState), { [formStateKey]: updatedFormState }); }; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVkdWNlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9yZWR1Y2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE9BQU8sRUFBVywyQkFBMkIsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNqRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNuRCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUN2RCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNuRCxPQUFPLEVBQXFFLFlBQVksRUFBRSxXQUFXLEVBQUUsWUFBWSxFQUFZLE1BQU0sU0FBUyxDQUFDO0FBRy9JLE1BQU0sVUFBVSxnQkFBZ0IsQ0FDOUIsS0FBbUUsRUFDbkUsTUFBYztJQUVkLElBQUksQ0FBQyxLQUFLLEVBQUU7UUFDVixNQUFNLElBQUksS0FBSyxDQUFDLGlDQUFpQyxDQUFDLENBQUM7S0FDcEQ7SUFFRCxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxFQUFFO1FBQ3ZCLE1BQU0sSUFBSSxLQUFLLENBQUMsbUNBQW1DLEtBQUssRUFBRSxDQUFDLENBQUM7S0FDN0Q7SUFFRCxJQUFJLFlBQVksQ0FBQyxLQUFLLENBQUMsRUFBRTtRQUN2QixPQUFPLGdCQUFnQixDQUFDLEtBQUssRUFBRSxNQUFNLENBQVEsQ0FBQztLQUMvQztJQUVELElBQUksWUFBWSxDQUFDLEtBQUssQ0FBQyxFQUFFO1FBQ3ZCLE9BQU8sZ0JBQWdCLENBQUMsS0FBNEIsRUFBRSxNQUFNLENBQVEsQ0FBQztLQUN0RTtJQUVELE9BQU8sa0JBQWtCLENBQUMsS0FBOEIsRUFBRSxNQUFNLENBQVEsQ0FBQztBQUMzRSxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQWlDRztBQUNILE1BQU0sVUFBVSxnQ0FBZ0MsQ0FDOUMscUJBQW9GLEVBQ3BGLEdBQUcsV0FBMkM7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QUFRLEtBQUssU0FBUyxDQUFFLENBQUM7UUFFcEgsTUFBTSxnQkFBZ0IsR0FBRyxRQUFRLENBQUMsU0FBUyxFQUFFLFlBQVksQ0FBQyxDQUFDO1FBRTNELElBQUksZ0JBQWdCLEtBQUssU0FBUyxFQUFFO1lBQ2xDLE9BQU8sWUFBWSxDQUFDO1NBQ3JCO1FBRUQsdUNBQ0ssWUFBWSxLQUNmLENBQUMsWUFBWSxDQUFDLEVBQUUsZ0JBQWdCLElBQ2hDO0lBQ0osQ0FBQyxDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFjdGlvbiwgQWN0aW9uUmVkdWNlciB9IGZyb20gJ0BuZ3J4L3N0b3JlJztcclxuXHJcbmltcG9ydCB7IEFjdGlvbnMsIEFMTF9OR1JYX0ZPUk1TX0FDVElPTl9UWVBFUyB9IGZyb20gJy4vYWN0aW9ucyc7XHJcbmltcG9ydCB7IGZvcm1BcnJheVJlZHVjZXIgfSBmcm9tICcuL2FycmF5L3JlZHVjZXInO1xyXG5pbXBvcnQgeyBmb3JtQ29udHJvbFJlZHVjZXIgfSBmcm9tICcuL2NvbnRyb2wvcmVkdWNlcic7XHJcbmltcG9ydCB7IGZvcm1Hcm91cFJlZHVjZXIgfSBmcm9tICcuL2dyb3VwL3JlZHVjZXInO1xyXG5pbXBvcnQgeyBBYnN0cmFjdENvbnRyb2xTdGF0ZSwgRm9ybUFycmF5U3RhdGUsIEZvcm1Db250cm9sU3RhdGUsIEZvcm1TdGF0ZSwgaXNBcnJheVN0YXRlLCBpc0Zvcm1TdGF0ZSwgaXNHcm91cFN0YXRlLCBLZXlWYWx1ZSB9IGZyb20gJy4vc3RhdGUnO1xyXG5pbXBvcnQgeyBQcm9qZWN0Rm4gfSBmcm9tICcuL3VwZGF0ZS1mdW5jdGlvbi91dGlsJztcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBmb3JtU3RhdGVSZWR1Y2VyPFRWYWx1ZT4oXHJcbiAgc3RhdGU6IEZvcm1TdGF0ZTxUVmFsdWU+IHwgQWJzdHJhY3RDb250cm9sU3RhdGU8VFZhbHVlPiB8IHVuZGVmaW5lZCxcclxuICBhY3Rpb246IEFjdGlvbixcclxuKTogRm9ybVN0YXRlPFRWYWx1ZT4ge1xyXG4gIGlmICghc3RhdGUpIHtcclxuICAgIHRocm93IG5ldyBFcnJvcignVGhlIGZvcm0gc3RhdGUgbXVzdCBiZSBkZWZpbmVkIScpO1xyXG4gIH1cclxuXHJcbiAgaWYgKCFpc0Zvcm1TdGF0ZShzdGF0ZSkpIHtcclxuICAgIHRocm93IG5ldyBFcnJvcihgc3RhdGUgbXVzdCBiZSBhIGZvcm0gc3RhdGUsIGdvdCAke3N0YXRlfWApO1xyXG4gIH1cclxuXHJcbiAgaWYgKGlzR3JvdXBTdGF0ZShzdGF0ZSkpIHtcclxuICAgIHJldHVybiBmb3JtR3JvdXBSZWR1Y2VyKHN0YXRlLCBhY3Rpb24pIGFzIGFueTtcclxuICB9XHJcblxyXG4gIGlmIChpc0FycmF5U3RhdGUoc3RhdGUpKSB7XHJcbiAgICByZXR1cm4gZm9ybUFycmF5UmVkdWNlcihzdGF0ZSBhcyBGb3JtQXJyYXlTdGF0ZTxhbnk+LCBhY3Rpb24pIGFzIGFueTtcclxuICB9XHJcblxyXG4gIHJldHVybiBmb3JtQ29udHJvbFJlZHVjZXIoc3RhdGUgYXMgRm9ybUNvbnRyb2xTdGF0ZTxhbnk+LCBhY3Rpb24pIGFzIGFueTtcclxufVxyXG5cclxuLyoqXHJcbiAqIFRoaXMgZnVuY3Rpb24gY3JlYXRlcyBhIHJlZHVjZXIgZnVuY3Rpb24gdGhhdCBmaXJzdCBhcHBsaWVzIGFuIGFjdGlvbiB0byB0aGUgc3RhdGVcclxuICogYW5kIGFmdGVyd2FyZHMgYXBwbGllcyBhbGwgZ2l2ZW4gdXBkYXRlIGZ1bmN0aW9ucyBvbmUgYWZ0ZXIgYW5vdGhlciB0byB0aGUgcmVzdWx0aW5nXHJcbiAqIGZvcm0gc3RhdGUuIEhvd2V2ZXIsIHRoZSB1cGRhdGUgZnVuY3Rpb25zIGFyZSBvbmx5IGFwcGxpZWQgaWYgdGhlIGZvcm0gc3RhdGUgY2hhbmdlZFxyXG4gKiBhcyByZXN1bHQgb2YgYXBwbHlpbmcgdGhlIGFjdGlvbi4gSWYgeW91IG5lZWQgdGhlIHVwZGF0ZSBmdW5jdGlvbnMgdG8gYmUgYXBwbGllZFxyXG4gKiByZWdhcmRsZXNzIG9mIHdoZXRoZXIgdGhlIHN0YXRlIGNoYW5nZWQgKGUuZy4gYmVjYXVzZSB0aGUgdXBkYXRlIGZ1bmN0aW9uIGNsb3Nlc1xyXG4gKiBvdmVyIHZhcmlhYmxlcyB0aGF0IG1heSBjaGFuZ2UgaW5kZXBlbmRlbnRseSBvZiB0aGUgZm9ybSBzdGF0ZSkgeW91IGNhbiBzaW1wbHkgYXBwbHlcclxuICogdGhlIHVwZGF0ZSBtYW51YWxseSAoZS5nLiBgdXBkYXRlRnVuY3Rpb24oZm9ybVN0YXRlUmVkdWNlcihzdGF0ZSwgYWN0aW9uKSlgKS5cclxuICpcclxuICogVGhlIGZvbGxvd2luZyAoY29udHJpdmVkKSBleGFtcGxlIHVzZXMgdGhpcyBmdW5jdGlvbiB0byBjcmVhdGUgYSByZWR1Y2VyIHRoYXQgYWZ0ZXJcclxuICogZWFjaCBhY3Rpb24gdmFsaWRhdGVzIHRoZSBjaGlsZCBjb250cm9sIGBuYW1lYCB0byBiZSByZXF1aXJlZCBhbmQgc2V0cyB0aGUgY2hpbGRcclxuICogY29udHJvbCBgZW1haWxgJ3MgdmFsdWUgdG8gYmUgYCcnYCBpZiB0aGUgbmFtZSBpcyBpbnZhbGlkLlxyXG4gKlxyXG5gYGB0eXBlc2NyaXB0XHJcbmludGVyZmFjZSBGb3JtVmFsdWUge1xyXG4gIG5hbWU6IHN0cmluZztcclxuICBlbWFpbDogc3RyaW5nO1xyXG59XHJcblxyXG5jb25zdCB1cGRhdGVGb3JtU3RhdGUgPSB1cGRhdGVHcm91cDxGb3JtVmFsdWU+KFxyXG4gIHtcclxuICAgIG5hbWU6IHZhbGlkYXRlKHJlcXVpcmVkKSxcclxuICB9LFxyXG4gIHtcclxuICAgIGVtYWlsOiAoZW1haWwsIHBhcmVudEdyb3VwKSA9PlxyXG4gICAgICBwYXJlbnRHcm91cC5jb250cm9scy5uYW1lLmlzSW52YWxpZFxyXG4gICAgICAgID8gc2V0VmFsdWUoJycsIGVtYWlsKVxyXG4gICAgICAgIDogZW1haWwsXHJcbiAgfSxcclxuKTtcclxuXHJcbmNvbnN0IHJlZHVjZXIgPSBjcmVhdGVGb3JtU3RhdGVSZWR1Y2VyV2l0aFVwZGF0ZTxGb3JtVmFsdWU+KHVwZGF0ZUZvcm1TdGF0ZSk7XHJcbmBgYFxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUZvcm1TdGF0ZVJlZHVjZXJXaXRoVXBkYXRlPFRWYWx1ZT4oXHJcbiAgdXBkYXRlRm5PclVwZGF0ZUZuQXJyOiBQcm9qZWN0Rm48Rm9ybVN0YXRlPFRWYWx1ZT4+IHwgUHJvamVjdEZuPEZvcm1TdGF0ZTxUVmFsdWU+PltdLFxyXG4gIC4uLnVwZGF0ZUZuQXJyOiBQcm9qZWN0Rm48Rm9ybVN0YXRlPFRWYWx1ZT4+W11cclxuKTogQWN0aW9uUmVkdWNlcjxGb3JtU3RhdGU8VFZhbHVlPj4ge1xyXG4gIHVwZGF0ZUZuQXJyID0gWy4uLihBcnJheS5pc0FycmF5KHVwZGF0ZUZuT3JVcGRhdGVGbkFycikgPyB1cGRhdGVGbk9yVXBkYXRlRm5BcnIgOiBbdXBkYXRlRm5PclVwZGF0ZUZuQXJyXSksIC4uLnVwZGF0ZUZuQXJyXTtcclxuICByZXR1cm4gKHN0YXRlOiBGb3JtU3RhdGU8VFZhbHVlPiB8IHVuZGVmaW5lZCwgYWN0aW9uOiBBY3Rpb24pOiBGb3JtU3RhdGU8VFZhbHVlPiA9PiB7XHJcbiAgICBjb25zdCBuZXdTdGF0ZSA9IGZvcm1TdGF0ZVJlZHVjZXIoc3RhdGUgYXMgQWJzdHJhY3RDb250cm9sU3RhdGU8VFZhbHVlPiwgYWN0aW9uKTtcclxuICAgIHJldHVybiBuZXdTdGF0ZSA9PT0gc3RhdGUgPyBzdGF0ZSA6IHVwZGF0ZUZuQXJyLnJlZHVjZSgocywgZikgPT4gZihzKSwgbmV3U3RhdGUpO1xyXG4gIH07XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHJlZHVjZU5lc3RlZEZvcm1TdGF0ZTxUU3RhdGU+KHN0YXRlOiBUU3RhdGUsIGtleToga2V5b2YgVFN0YXRlLCBhY3Rpb246IEFjdGlvbik6IFRTdGF0ZSB7XHJcbiAgY29uc3QgdmFsdWUgPSBzdGF0ZVtrZXldO1xyXG5cclxuICBpZiAoIWlzRm9ybVN0YXRlKHZhbHVlKSkge1xyXG4gICAgcmV0dXJuIHN0YXRlO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIHtcclxuICAgIC4uLnN0YXRlLFxyXG4gICAgW2tleV06IGZvcm1TdGF0ZVJlZHVjZXIodmFsdWUsIGFjdGlvbiksXHJcbiAgfTtcclxufVxyXG5cclxuZnVuY3Rpb24gcmVkdWNlTmVzdGVkRm9ybVN0YXRlczxUU3RhdGUgZXh0ZW5kcyBLZXlWYWx1ZT4oc3RhdGU6IFRTdGF0ZSwgYWN0aW9uOiBBY3Rpb24pOiBUU3RhdGUge1xyXG4gIHJldHVybiBPYmplY3Qua2V5cyhzdGF0ZSkucmVkdWNlKChzLCBrZXkpID0+IHJlZHVjZU5lc3RlZEZvcm1TdGF0ZShzLCBrZXkgYXMga2V5b2YgVFN0YXRlLCBhY3Rpb24pLCBzdGF0ZSk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBUaGlzIGZ1bmN0aW9uIHJldHVybnMgYW4gb2JqZWN0IHRoYXQgY2FuIGJlIHBhc3NlZCB0byBuZ3J4J3MgYGNyZWF0ZVJlZHVjZXJgXHJcbiAqIGZ1bmN0aW9uIChhdmFpbGFibGUgc3RhcnRpbmcgd2l0aCBuZ3J4IHZlcnNpb24gOCkuIEJ5IGRvaW5nIHRoaXMgYWxsIGZvcm1cclxuICogc3RhdGUgcHJvcGVydGllcyBvbiB0aGUgc3RhdGUgd2lsbCBiZSB1cGRhdGVkIHdoZW5ldmVyIG5lY2Vzc2FyeSAoaS5lLlxyXG4gKiB3aGVuZXZlciBhbiBuZ3J4LWZvcm1zIGFjdGlvbiBpcyBkaXNwYXRjaGVkKS5cclxuICpcclxuICogVG8gbWFudWFsbHkgdXBkYXRlIGEgZm9ybSBzdGF0ZSAoZS5nLiB0byB2YWxpZGF0ZSBpdCkgdXNlXHJcbiAqIGB3cmFwUmVkdWNlcldpdGhGb3JtU3RhdGVVcGRhdGVgLlxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIG9uTmdyeEZvcm1zPFRTdGF0ZSA9IGFueT4oKTogeyByZWR1Y2VyOiBBY3Rpb25SZWR1Y2VyPFRTdGF0ZT47IHR5cGVzOiBzdHJpbmdbXSB9IHtcclxuICByZXR1cm4ge1xyXG4gICAgcmVkdWNlcjogKHN0YXRlLCBhY3Rpb24pID0+IGlzRm9ybVN0YXRlKHN0YXRlKSA/IGZvcm1TdGF0ZVJlZHVjZXIoc3RhdGUhLCBhY3Rpb24pIGFzIHVua25vd24gYXMgVFN0YXRlIDogcmVkdWNlTmVzdGVkRm9ybVN0YXRlcyhzdGF0ZSEsIGFjdGlvbiksXHJcbiAgICB0eXBlczogQUxMX05HUlhfRk9STVNfQUNUSU9OX1RZUEVTLFxyXG4gIH07XHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgQWN0aW9uQ29uc3RydWN0b3Ige1xyXG4gIG5ldyguLi5hcmdzOiBhbnlbXSk6IEFjdGlvbnM8YW55PjtcclxuICByZWFkb25seSBUWVBFOiBzdHJpbmc7XHJcbn1cclxuXHJcbmV4cG9ydCB0eXBlIENyZWF0ZWRBY3Rpb248VEFjdGlvbkNvbnM+ID0gVEFjdGlvbkNvbnMgZXh0ZW5kcyBuZXcgKC4uLmFyZ3M6IGFueVtdKSA9PiBpbmZlciBUQWN0aW9uID8gVEFjdGlvbiA6IG5ldmVyO1xyXG5cclxuLyoqXHJcbiAqIERlZmluZSBhIHJlZHVjZXIgZm9yIGEgbmdyeC1mb3JtcyBhY3Rpb24uIFRoaXMgZnVuY3Rpb25zIHdvcmtzIHRoZSBzYW1lIGFzXHJcbiAqIG5ncngncyBgb25gIGV4Y2VwdCB0aGF0IHlvdSBwcm92aWRlIHRoZSBuZ3J4LWZvcm1zIGFjdGlvbiBjbGFzcyBpbnN0ZWFkIG9mXHJcbiAqIHlvdXIgYWN0aW9uIGNyZWF0b3IgYXMgYSBwYXJhbWV0ZXIuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gb25OZ3J4Rm9ybXNBY3Rpb248XHJcbiAgVEFjdGlvbkNvbnMgZXh0ZW5kcyBBY3Rpb25Db25zdHJ1Y3RvcixcclxuICBUU3RhdGVcclxuPihcclxuICBhY3Rpb25Db25zOiBUQWN0aW9uQ29ucyxcclxuICByZWR1Y2VyOiAoc3RhdGU6IFRTdGF0ZSwgYWN0aW9uOiBDcmVhdGVkQWN0aW9uPFRBY3Rpb25Db25zPikgPT4gVFN0YXRlLFxyXG4pOiB7IHJlZHVjZXI6IEFjdGlvblJlZHVjZXI8VFN0YXRlPjsgdHlwZXM6IHN0cmluZ1tdIH0ge1xyXG4gIHJldHVybiB7XHJcbiAgICByZWR1Y2VyOiAoc3RhdGUsIGFjdGlvbikgPT4gcmVkdWNlcihyZWR1Y2VOZXN0ZWRGb3JtU3RhdGVzKHN0YXRlISwgYWN0aW9uKSwgYWN0aW9uIGFzIGFueSksXHJcbiAgICB0eXBlczogW2FjdGlvbkNvbnMuVFlQRV0sXHJcbiAgfTtcclxufVxyXG5cclxuLyoqXHJcbiAqIFRoaXMgZnVuY3Rpb24gd3JhcHMgYSByZWR1Y2VyIGFuZCByZXR1cm5zIGFub3RoZXIgcmVkdWNlciB0aGF0IGZpcnN0IGNhbGxzXHJcbiAqIHRoZSBnaXZlbiByZWR1Y2VyIGFuZCB0aGVuIGNhbGxzIHRoZSBnaXZlbiB1cGRhdGUgZnVuY3Rpb24gZm9yIHRoZSBmb3JtIHN0YXRlXHJcbiAqIHRoYXQgaXMgc3BlY2lmaWVkIGJ5IHRoZSBmb3JtIHN0YXRlIGxvY2F0b3IgZnVuY3Rpb24uXHJcbiAqXHJcbiAqIFRoZSB1cGRhdGUgZnVuY3Rpb24gaXMgcGFzc2VkIHRoZSBmb3JtIHN0YXRlIGFuZCB0aGUgdXBkYXRlZCBjb250YWluaW5nIHN0YXRlXHJcbiAqIGFzIHBhcmFtZXRlcnMuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gd3JhcFJlZHVjZXJXaXRoRm9ybVN0YXRlVXBkYXRlPFRTdGF0ZSBleHRlbmRzIEtleVZhbHVlLCBURm9ybVN0YXRlIGV4dGVuZHMgQWJzdHJhY3RDb250cm9sU3RhdGU8YW55Pj4oXHJcbiAgcmVkdWNlcjogQWN0aW9uUmVkdWNlcjxUU3RhdGU+LFxyXG4gIGZvcm1TdGF0ZUxvY2F0b3I6IChzdGF0ZTogVFN0YXRlKSA9PiBURm9ybVN0YXRlLFxyXG4gIHVwZGF0ZUZuOiAoZm9ybVN0YXRlOiBURm9ybVN0YXRlLCBzdGF0ZTogVFN0YXRlKSA9PiBURm9ybVN0YXRlLFxyXG4pOiBBY3Rpb25SZWR1Y2VyPFRTdGF0ZT4ge1xyXG4gIHJldHVybiAoc3RhdGUsIGFjdGlvbikgPT4ge1xyXG4gICAgY29uc3QgdXBkYXRlZFN0YXRlID0gcmVkdWNlcihzdGF0ZSwgYWN0aW9uKTtcclxuXHJcbiAgICBjb25zdCBmb3JtU3RhdGUgPSBmb3JtU3RhdGVMb2NhdG9yKHVwZGF0ZWRTdGF0ZSk7XHJcblxyXG4gICAgLy8gaWYgdGhlIHN0YXRlIGl0c2VsZiBpcyB0aGUgZm9ybSBzdGF0ZSwgdXBkYXRlIGl0IGRpcmVjdGx5XHJcbiAgICBpZiAoZm9ybVN0YXRlID09PSB1cGRhdGVkU3RhdGUgYXMgdW5rbm93bikge1xyXG4gICAgICByZXR1cm4gdXBkYXRlRm4oZm9ybVN0YXRlLCB1cGRhdGVkU3RhdGUpIGFzIHVua25vd24gYXMgVFN0YXRlO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IGZvcm1TdGF0ZUtleSA9IE9iamVjdC5rZXlzKHVwZGF0ZWRTdGF0ZSkuZmluZChrZXkgPT4gdXBkYXRlZFN0YXRlW2tleSBhcyBrZXlvZiBUU3RhdGVdIGFzIGFueSA9PT0gZm9ybVN0YXRlKSE7XHJcblxyXG4gICAgY29uc3QgdXBkYXRlZEZvcm1TdGF0ZSA9IHVwZGF0ZUZuKGZvcm1TdGF0ZSwgdXBkYXRlZFN0YXRlKTtcclxuXHJcbiAgICBpZiAodXBkYXRlZEZvcm1TdGF0ZSA9PT0gZm9ybVN0YXRlKSB7XHJcbiAgICAgIHJldHVybiB1cGRhdGVkU3RhdGU7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHtcclxuICAgICAgLi4udXBkYXRlZFN0YXRlLFxyXG4gICAgICBbZm9ybVN0YXRlS2V5XTogdXBkYXRlZEZvcm1TdGF0ZSxcclxuICAgIH07XHJcbiAgfTtcclxufVxyXG4iXX0=