UNPKG

@openfisca/json-model

Version:

Library to handle informations extracted in JSON or YAML format from OpenFisca parameters, variables, etc

158 lines (155 loc) 30.2 kB
import { auditArray, auditBoolean, auditChain, auditCleanArray, auditDateIso8601String, auditFunction, auditKeyValueDictionary, auditRequire, auditString, auditSwitch, auditTrimString, auditUnique } from "@auditors/core"; import { auditReferencesByDate } from "./references.js"; export function auditCustomization(audit, dataUnknown) { if (dataUnknown == null) { return [dataUnknown, null]; } if (typeof dataUnknown !== "object") { return audit.unexpectedType(dataUnknown, "object"); } const data = { ...dataUnknown }; const errors = {}; const remainingKeys = new Set(Object.keys(data)); auditDecompositionCoreContent(audit, data, errors, remainingKeys); audit.attribute(data, "input", true, errors, remainingKeys, auditBoolean, auditFunction(value => value || undefined) // Delete false. ); audit.attribute(data, "linked_other_variables", true, errors, remainingKeys, auditCleanArray(auditTrimString), auditUnique); audit.attribute(data, "main_parameters", true, errors, remainingKeys, auditCleanArray(auditTrimString), auditUnique); audit.attribute(data, "variables", true, errors, remainingKeys, auditCleanArray(auditTrimString), auditUnique); return audit.reduceRemaining(data, errors, remainingKeys); } export const auditCustomizationByName = auditKeyValueDictionary(auditTrimString, [auditCustomization, auditRequire]); export function auditDecomposition(audit, dataUnknown) { if (dataUnknown == null) { return [dataUnknown, null]; } if (typeof dataUnknown !== "object") { return audit.unexpectedType(dataUnknown, "object"); } const data = { ...dataUnknown }; const errors = {}; const remainingKeys = new Set(Object.keys(data)); auditDecompositionCoreContent(audit, data, errors, remainingKeys); audit.attribute(data, "label", true, errors, remainingKeys, auditRequire); return audit.reduceRemaining(data, errors, remainingKeys); } export const auditDecompositionByName = auditKeyValueDictionary(auditTrimString, [auditDecomposition, auditRequire]); function auditDecompositionCoreContent(audit, data, errors, remainingKeys) { audit.attribute(data, "children", false, // Don't delete nullish children (nullish means null after a JSON.parse). errors, remainingKeys, auditCleanArray(auditDecompositionReference)); audit.attribute(data, "description", true, errors, remainingKeys, auditReferencesByDate); // Note: `"hidden": false` is not the same as `undefined`. audit.attribute(data, "hidden", true, errors, remainingKeys, auditBoolean); for (const key of ["label", "short_label"]) { audit.attribute(data, key, true, errors, remainingKeys, auditTrimString); } audit.attribute(data, "last_value_still_valid_on", true, errors, remainingKeys, auditDateIso8601String); for (const key of ["obsolete", "virtual"]) { audit.attribute(data, key, true, errors, remainingKeys, auditBoolean, auditFunction(value => value || undefined) // Delete false. ); } audit.attribute(data, "options", true, errors, remainingKeys, auditSwitch([auditArray(), auditCleanArray(auditDecompositionOptions)], [auditDecompositionOptions, auditFunction(options => [options])])); audit.attribute(data, "reference", true, errors, remainingKeys, auditReferencesByDate); } export function auditDecompositionOptions(audit, dataUnknown) { if (dataUnknown == null) { return [dataUnknown, null]; } if (typeof dataUnknown !== "object") { return audit.unexpectedType(dataUnknown, "object"); } const data = { ...dataUnknown }; const errors = {}; const remainingKeys = new Set(Object.keys(data)); audit.attribute(data, "waterfall", true, errors, remainingKeys, auditSwitch([auditArray(), auditCleanArray(auditTrimString), auditUnique], [auditTrimString, auditFunction(name => [name])]) // TODO: Test existence of waterfall names. ); if (errors.waterfall === undefined) { if (data.waterfall === undefined) { // Variables options for (const key of ["else", "then"]) { audit.attribute(data, key, true, errors, remainingKeys, auditVariablesCustomization); } for (const variableName of remainingKeys) { const [validVariableName, variableNameError] = auditChain(auditTrimString, // TODO: Test existence of variable name. auditRequire)(audit, variableName); if (variableNameError === null) { audit.attribute(data, variableName, true, errors, remainingKeys, auditSwitch([auditArray(auditBoolean), auditCleanArray(auditBoolean), auditUnique], [auditArray(auditString), auditCleanArray(auditTrimString), auditUnique], [auditBoolean, auditFunction(value => [value])], [auditTrimString, auditFunction(value => [value])]), // TODO: Test existence of variable value. auditRequire); if (errors[variableName] === undefined && validVariableName !== variableName) { data[validVariableName] = data[variableName]; delete data[variableName]; } } } } else { // Waterfall options for (const key of ["else", "then"]) { audit.attribute(data, key, true, errors, remainingKeys, auditWaterfallCustomization); } } } return audit.reduceRemaining(data, errors, remainingKeys); } export function auditDecompositionReference(audit, dataUnknown) { if (dataUnknown == null) { return [dataUnknown, null]; } if (typeof dataUnknown !== "object") { return audit.unexpectedType(dataUnknown, "object"); } const data = { ...dataUnknown }; const errors = {}; const remainingKeys = new Set(Object.keys(data)); audit.attribute(data, "name", true, errors, remainingKeys, auditTrimString, auditRequire); audit.attribute(data, "negate", true, errors, remainingKeys, auditBoolean, auditFunction(value => value || undefined) // Replace false with undefined. ); return audit.reduceRemaining(data, errors, remainingKeys); } export function auditVariablesCustomization(audit, dataUnknown) { if (dataUnknown == null) { return [dataUnknown, null]; } if (typeof dataUnknown !== "object") { return audit.unexpectedType(dataUnknown, "object"); } const data = { ...dataUnknown }; const errors = {}; const remainingKeys = new Set(Object.keys(data)); // Note: `"hidden": false` is not the same as `undefined`. audit.attribute(data, "hidden", true, errors, remainingKeys, auditBoolean); return audit.reduceRemaining(data, errors, remainingKeys); } export function auditWaterfallCustomization(audit, dataUnknown) { if (dataUnknown == null) { return [dataUnknown, null]; } if (typeof dataUnknown !== "object") { return audit.unexpectedType(dataUnknown, "object"); } const data = { ...dataUnknown }; const errors = {}; const remainingKeys = new Set(Object.keys(data)); audit.attribute(data, "children", false, // Don't delete nullish children (nullish means null after a JSON.parse). errors, remainingKeys, auditCleanArray(auditDecompositionReference)); // Note: `"hidden": false` is not the same as `undefined`. audit.attribute(data, "hidden", true, errors, remainingKeys, auditBoolean); return audit.reduceRemaining(data, errors, remainingKeys); } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJhdWRpdEFycmF5IiwiYXVkaXRCb29sZWFuIiwiYXVkaXRDaGFpbiIsImF1ZGl0Q2xlYW5BcnJheSIsImF1ZGl0RGF0ZUlzbzg2MDFTdHJpbmciLCJhdWRpdEZ1bmN0aW9uIiwiYXVkaXRLZXlWYWx1ZURpY3Rpb25hcnkiLCJhdWRpdFJlcXVpcmUiLCJhdWRpdFN0cmluZyIsImF1ZGl0U3dpdGNoIiwiYXVkaXRUcmltU3RyaW5nIiwiYXVkaXRVbmlxdWUiLCJhdWRpdFJlZmVyZW5jZXNCeURhdGUiLCJhdWRpdEN1c3RvbWl6YXRpb24iLCJhdWRpdCIsImRhdGFVbmtub3duIiwidW5leHBlY3RlZFR5cGUiLCJkYXRhIiwiZXJyb3JzIiwicmVtYWluaW5nS2V5cyIsIlNldCIsIk9iamVjdCIsImtleXMiLCJhdWRpdERlY29tcG9zaXRpb25Db3JlQ29udGVudCIsImF0dHJpYnV0ZSIsInZhbHVlIiwidW5kZWZpbmVkIiwicmVkdWNlUmVtYWluaW5nIiwiYXVkaXRDdXN0b21pemF0aW9uQnlOYW1lIiwiYXVkaXREZWNvbXBvc2l0aW9uIiwiYXVkaXREZWNvbXBvc2l0aW9uQnlOYW1lIiwiYXVkaXREZWNvbXBvc2l0aW9uUmVmZXJlbmNlIiwia2V5IiwiYXVkaXREZWNvbXBvc2l0aW9uT3B0aW9ucyIsIm9wdGlvbnMiLCJuYW1lIiwid2F0ZXJmYWxsIiwiYXVkaXRWYXJpYWJsZXNDdXN0b21pemF0aW9uIiwidmFyaWFibGVOYW1lIiwidmFsaWRWYXJpYWJsZU5hbWUiLCJ2YXJpYWJsZU5hbWVFcnJvciIsImF1ZGl0V2F0ZXJmYWxsQ3VzdG9taXphdGlvbiJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hdWRpdG9ycy9kZWNvbXBvc2l0aW9ucy50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IEF1ZGl0IH0gZnJvbSBcIkBhdWRpdG9ycy9jb3JlXCJcbmltcG9ydCB7XG4gIGF1ZGl0QXJyYXksXG4gIGF1ZGl0Qm9vbGVhbixcbiAgYXVkaXRDaGFpbixcbiAgYXVkaXRDbGVhbkFycmF5LFxuICBhdWRpdERhdGVJc284NjAxU3RyaW5nLFxuICBhdWRpdEZ1bmN0aW9uLFxuICBhdWRpdEtleVZhbHVlRGljdGlvbmFyeSxcbiAgYXVkaXRSZXF1aXJlLFxuICBhdWRpdFN0cmluZyxcbiAgYXVkaXRTd2l0Y2gsXG4gIGF1ZGl0VHJpbVN0cmluZyxcbiAgYXVkaXRVbmlxdWUsXG59IGZyb20gXCJAYXVkaXRvcnMvY29yZVwiXG5cbmltcG9ydCB7IGF1ZGl0UmVmZXJlbmNlc0J5RGF0ZSB9IGZyb20gXCIuL3JlZmVyZW5jZXNcIlxuXG5leHBvcnQgZnVuY3Rpb24gYXVkaXRDdXN0b21pemF0aW9uKFxuICBhdWRpdDogQXVkaXQsXG4gIGRhdGFVbmtub3duOiB1bmtub3duLFxuKTogW3Vua25vd24sIHVua25vd25dIHtcbiAgaWYgKGRhdGFVbmtub3duID09IG51bGwpIHtcbiAgICByZXR1cm4gW2RhdGFVbmtub3duLCBudWxsXVxuICB9XG4gIGlmICh0eXBlb2YgZGF0YVVua25vd24gIT09IFwib2JqZWN0XCIpIHtcbiAgICByZXR1cm4gYXVkaXQudW5leHBlY3RlZFR5cGUoZGF0YVVua25vd24sIFwib2JqZWN0XCIpXG4gIH1cblxuICBjb25zdCBkYXRhOiB7IFtrZXk6IHN0cmluZ106IHVua25vd24gfSA9IHsgLi4uZGF0YVVua25vd24gfVxuICBjb25zdCBlcnJvcnM6IHsgW2tleTogc3RyaW5nXTogdW5rbm93biB9ID0ge31cbiAgY29uc3QgcmVtYWluaW5nS2V5cyA9IG5ldyBTZXQoT2JqZWN0LmtleXMoZGF0YSkpXG5cbiAgYXVkaXREZWNvbXBvc2l0aW9uQ29yZUNvbnRlbnQoYXVkaXQsIGRhdGEsIGVycm9ycywgcmVtYWluaW5nS2V5cylcblxuICBhdWRpdC5hdHRyaWJ1dGUoXG4gICAgZGF0YSxcbiAgICBcImlucHV0XCIsXG4gICAgdHJ1ZSxcbiAgICBlcnJvcnMsXG4gICAgcmVtYWluaW5nS2V5cyxcbiAgICBhdWRpdEJvb2xlYW4sXG4gICAgYXVkaXRGdW5jdGlvbigodmFsdWUpID0+IHZhbHVlIHx8IHVuZGVmaW5lZCksIC8vIERlbGV0ZSBmYWxzZS5cbiAgKVxuICBhdWRpdC5hdHRyaWJ1dGUoXG4gICAgZGF0YSxcbiAgICBcImxpbmtlZF9vdGhlcl92YXJpYWJsZXNcIixcbiAgICB0cnVlLFxuICAgIGVycm9ycyxcbiAgICByZW1haW5pbmdLZXlzLFxuICAgIGF1ZGl0Q2xlYW5BcnJheShhdWRpdFRyaW1TdHJpbmcpLFxuICAgIGF1ZGl0VW5pcXVlLFxuICApXG4gIGF1ZGl0LmF0dHJpYnV0ZShcbiAgICBkYXRhLFxuICAgIFwibWFpbl9wYXJhbWV0ZXJzXCIsXG4gICAgdHJ1ZSxcbiAgICBlcnJvcnMsXG4gICAgcmVtYWluaW5nS2V5cyxcbiAgICBhdWRpdENsZWFuQXJyYXkoYXVkaXRUcmltU3RyaW5nKSxcbiAgICBhdWRpdFVuaXF1ZSxcbiAgKVxuICBhdWRpdC5hdHRyaWJ1dGUoXG4gICAgZGF0YSxcbiAgICBcInZhcmlhYmxlc1wiLFxuICAgIHRydWUsXG4gICAgZXJyb3JzLFxuICAgIHJlbWFpbmluZ0tleXMsXG4gICAgYXVkaXRDbGVhbkFycmF5KGF1ZGl0VHJpbVN0cmluZyksXG4gICAgYXVkaXRVbmlxdWUsXG4gIClcblxuICByZXR1cm4gYXVkaXQucmVkdWNlUmVtYWluaW5nKGRhdGEsIGVycm9ycywgcmVtYWluaW5nS2V5cylcbn1cblxuZXhwb3J0IGNvbnN0IGF1ZGl0Q3VzdG9taXphdGlvbkJ5TmFtZSA9IGF1ZGl0S2V5VmFsdWVEaWN0aW9uYXJ5KFxuICBhdWRpdFRyaW1TdHJpbmcsXG4gIFthdWRpdEN1c3RvbWl6YXRpb24sIGF1ZGl0UmVxdWlyZV0sXG4pXG5cbmV4cG9ydCBmdW5jdGlvbiBhdWRpdERlY29tcG9zaXRpb24oXG4gIGF1ZGl0OiBBdWRpdCxcbiAgZGF0YVVua25vd246IHVua25vd24sXG4pOiBbdW5rbm93biwgdW5rbm93bl0ge1xuICBpZiAoZGF0YVVua25vd24gPT0gbnVsbCkge1xuICAgIHJldHVybiBbZGF0YVVua25vd24sIG51bGxdXG4gIH1cbiAgaWYgKHR5cGVvZiBkYXRhVW5rbm93biAhPT0gXCJvYmplY3RcIikge1xuICAgIHJldHVybiBhdWRpdC51bmV4cGVjdGVkVHlwZShkYXRhVW5rbm93biwgXCJvYmplY3RcIilcbiAgfVxuXG4gIGNvbnN0IGRhdGE6IHsgW2tleTogc3RyaW5nXTogdW5rbm93biB9ID0geyAuLi5kYXRhVW5rbm93biB9XG4gIGNvbnN0IGVycm9yczogeyBba2V5OiBzdHJpbmddOiB1bmtub3duIH0gPSB7fVxuICBjb25zdCByZW1haW5pbmdLZXlzID0gbmV3IFNldChPYmplY3Qua2V5cyhkYXRhKSlcblxuICBhdWRpdERlY29tcG9zaXRpb25Db3JlQ29udGVudChhdWRpdCwgZGF0YSwgZXJyb3JzLCByZW1haW5pbmdLZXlzKVxuXG4gIGF1ZGl0LmF0dHJpYnV0ZShkYXRhLCBcImxhYmVsXCIsIHRydWUsIGVycm9ycywgcmVtYWluaW5nS2V5cywgYXVkaXRSZXF1aXJlKVxuXG4gIHJldHVybiBhdWRpdC5yZWR1Y2VSZW1haW5pbmcoZGF0YSwgZXJyb3JzLCByZW1haW5pbmdLZXlzKVxufVxuXG5leHBvcnQgY29uc3QgYXVkaXREZWNvbXBvc2l0aW9uQnlOYW1lID0gYXVkaXRLZXlWYWx1ZURpY3Rpb25hcnkoXG4gIGF1ZGl0VHJpbVN0cmluZyxcbiAgW2F1ZGl0RGVjb21wb3NpdGlvbiwgYXVkaXRSZXF1aXJlXSxcbilcblxuZnVuY3Rpb24gYXVkaXREZWNvbXBvc2l0aW9uQ29yZUNvbnRlbnQoXG4gIGF1ZGl0OiBBdWRpdCxcbiAgZGF0YTogeyBba2V5OiBzdHJpbmddOiB1bmtub3duIH0sXG4gIGVycm9yczogeyBba2V5OiBzdHJpbmddOiB1bmtub3duIH0sXG4gIHJlbWFpbmluZ0tleXM6IFNldDxzdHJpbmc+LFxuKTogdm9pZCB7XG4gIGF1ZGl0LmF0dHJpYnV0ZShcbiAgICBkYXRhLFxuICAgIFwiY2hpbGRyZW5cIixcbiAgICBmYWxzZSwgLy8gRG9uJ3QgZGVsZXRlIG51bGxpc2ggY2hpbGRyZW4gKG51bGxpc2ggbWVhbnMgbnVsbCBhZnRlciBhIEpTT04ucGFyc2UpLlxuICAgIGVycm9ycyxcbiAgICByZW1haW5pbmdLZXlzLFxuICAgIGF1ZGl0Q2xlYW5BcnJheShhdWRpdERlY29tcG9zaXRpb25SZWZlcmVuY2UpLFxuICApXG4gIGF1ZGl0LmF0dHJpYnV0ZShcbiAgICBkYXRhLFxuICAgIFwiZGVzY3JpcHRpb25cIixcbiAgICB0cnVlLFxuICAgIGVycm9ycyxcbiAgICByZW1haW5pbmdLZXlzLFxuICAgIGF1ZGl0UmVmZXJlbmNlc0J5RGF0ZSxcbiAgKVxuICAvLyBOb3RlOiBgXCJoaWRkZW5cIjogZmFsc2VgIGlzIG5vdCB0aGUgc2FtZSBhcyBgdW5kZWZpbmVkYC5cbiAgYXVkaXQuYXR0cmlidXRlKGRhdGEsIFwiaGlkZGVuXCIsIHRydWUsIGVycm9ycywgcmVtYWluaW5nS2V5cywgYXVkaXRCb29sZWFuKVxuICBmb3IgKGNvbnN0IGtleSBvZiBbXCJsYWJlbFwiLCBcInNob3J0X2xhYmVsXCJdKSB7XG4gICAgYXVkaXQuYXR0cmlidXRlKGRhdGEsIGtleSwgdHJ1ZSwgZXJyb3JzLCByZW1haW5pbmdLZXlzLCBhdWRpdFRyaW1TdHJpbmcpXG4gIH1cbiAgYXVkaXQuYXR0cmlidXRlKFxuICAgIGRhdGEsXG4gICAgXCJsYXN0X3ZhbHVlX3N0aWxsX3ZhbGlkX29uXCIsXG4gICAgdHJ1ZSxcbiAgICBlcnJvcnMsXG4gICAgcmVtYWluaW5nS2V5cyxcbiAgICBhdWRpdERhdGVJc284NjAxU3RyaW5nLFxuICApXG4gIGZvciAoY29uc3Qga2V5IG9mIFtcIm9ic29sZXRlXCIsIFwidmlydHVhbFwiXSkge1xuICAgIGF1ZGl0LmF0dHJpYnV0ZShcbiAgICAgIGRhdGEsXG4gICAgICBrZXksXG4gICAgICB0cnVlLFxuICAgICAgZXJyb3JzLFxuICAgICAgcmVtYWluaW5nS2V5cyxcbiAgICAgIGF1ZGl0Qm9vbGVhbixcbiAgICAgIGF1ZGl0RnVuY3Rpb24oKHZhbHVlKSA9PiB2YWx1ZSB8fCB1bmRlZmluZWQpLCAvLyBEZWxldGUgZmFsc2UuXG4gICAgKVxuICB9XG4gIGF1ZGl0LmF0dHJpYnV0ZShcbiAgICBkYXRhLFxuICAgIFwib3B0aW9uc1wiLFxuICAgIHRydWUsXG4gICAgZXJyb3JzLFxuICAgIHJlbWFpbmluZ0tleXMsXG4gICAgYXVkaXRTd2l0Y2goXG4gICAgICBbYXVkaXRBcnJheSgpLCBhdWRpdENsZWFuQXJyYXkoYXVkaXREZWNvbXBvc2l0aW9uT3B0aW9ucyldLFxuICAgICAgW2F1ZGl0RGVjb21wb3NpdGlvbk9wdGlvbnMsIGF1ZGl0RnVuY3Rpb24oKG9wdGlvbnMpID0+IFtvcHRpb25zXSldLFxuICAgICksXG4gIClcbiAgYXVkaXQuYXR0cmlidXRlKFxuICAgIGRhdGEsXG4gICAgXCJyZWZlcmVuY2VcIixcbiAgICB0cnVlLFxuICAgIGVycm9ycyxcbiAgICByZW1haW5pbmdLZXlzLFxuICAgIGF1ZGl0UmVmZXJlbmNlc0J5RGF0ZSxcbiAgKVxufVxuXG5leHBvcnQgZnVuY3Rpb24gYXVkaXREZWNvbXBvc2l0aW9uT3B0aW9ucyhcbiAgYXVkaXQ6IEF1ZGl0LFxuICBkYXRhVW5rbm93bjogdW5rbm93bixcbik6IFt1bmtub3duLCB1bmtub3duXSB7XG4gIGlmIChkYXRhVW5rbm93biA9PSBudWxsKSB7XG4gICAgcmV0dXJuIFtkYXRhVW5rbm93biwgbnVsbF1cbiAgfVxuICBpZiAodHlwZW9mIGRhdGFVbmtub3duICE9PSBcIm9iamVjdFwiKSB7XG4gICAgcmV0dXJuIGF1ZGl0LnVuZXhwZWN0ZWRUeXBlKGRhdGFVbmtub3duLCBcIm9iamVjdFwiKVxuICB9XG5cbiAgY29uc3QgZGF0YTogeyBba2V5OiBzdHJpbmddOiB1bmtub3duIH0gPSB7IC4uLmRhdGFVbmtub3duIH1cbiAgY29uc3QgZXJyb3JzOiB7IFtrZXk6IHN0cmluZ106IHVua25vd24gfSA9IHt9XG4gIGNvbnN0IHJlbWFpbmluZ0tleXMgPSBuZXcgU2V0KE9iamVjdC5rZXlzKGRhdGEpKVxuXG4gIGF1ZGl0LmF0dHJpYnV0ZShcbiAgICBkYXRhLFxuICAgIFwid2F0ZXJmYWxsXCIsXG4gICAgdHJ1ZSxcbiAgICBlcnJvcnMsXG4gICAgcmVtYWluaW5nS2V5cyxcbiAgICBhdWRpdFN3aXRjaChcbiAgICAgIFthdWRpdEFycmF5KCksIGF1ZGl0Q2xlYW5BcnJheShhdWRpdFRyaW1TdHJpbmcpLCBhdWRpdFVuaXF1ZV0sXG4gICAgICBbYXVkaXRUcmltU3RyaW5nLCBhdWRpdEZ1bmN0aW9uKChuYW1lKSA9PiBbbmFtZV0pXSxcbiAgICApLFxuICAgIC8vIFRPRE86IFRlc3QgZXhpc3RlbmNlIG9mIHdhdGVyZmFsbCBuYW1lcy5cbiAgKVxuXG4gIGlmIChlcnJvcnMud2F0ZXJmYWxsID09PSB1bmRlZmluZWQpIHtcbiAgICBpZiAoZGF0YS53YXRlcmZhbGwgPT09IHVuZGVmaW5lZCkge1xuICAgICAgLy8gVmFyaWFibGVzIG9wdGlvbnNcblxuICAgICAgZm9yIChjb25zdCBrZXkgb2YgW1wiZWxzZVwiLCBcInRoZW5cIl0pIHtcbiAgICAgICAgYXVkaXQuYXR0cmlidXRlKFxuICAgICAgICAgIGRhdGEsXG4gICAgICAgICAga2V5LFxuICAgICAgICAgIHRydWUsXG4gICAgICAgICAgZXJyb3JzLFxuICAgICAgICAgIHJlbWFpbmluZ0tleXMsXG4gICAgICAgICAgYXVkaXRWYXJpYWJsZXNDdXN0b21pemF0aW9uLFxuICAgICAgICApXG4gICAgICB9XG5cbiAgICAgIGZvciAoY29uc3QgdmFyaWFibGVOYW1lIG9mIHJlbWFpbmluZ0tleXMpIHtcbiAgICAgICAgY29uc3QgW3ZhbGlkVmFyaWFibGVOYW1lLCB2YXJpYWJsZU5hbWVFcnJvcl0gPSBhdWRpdENoYWluKFxuICAgICAgICAgIGF1ZGl0VHJpbVN0cmluZyxcbiAgICAgICAgICAvLyBUT0RPOiBUZXN0IGV4aXN0ZW5jZSBvZiB2YXJpYWJsZSBuYW1lLlxuICAgICAgICAgIGF1ZGl0UmVxdWlyZSxcbiAgICAgICAgKShhdWRpdCwgdmFyaWFibGVOYW1lKVxuICAgICAgICBpZiAodmFyaWFibGVOYW1lRXJyb3IgPT09IG51bGwpIHtcbiAgICAgICAgICBhdWRpdC5hdHRyaWJ1dGUoXG4gICAgICAgICAgICBkYXRhLFxuICAgICAgICAgICAgdmFyaWFibGVOYW1lLFxuICAgICAgICAgICAgdHJ1ZSxcbiAgICAgICAgICAgIGVycm9ycyxcbiAgICAgICAgICAgIHJlbWFpbmluZ0tleXMsXG4gICAgICAgICAgICBhdWRpdFN3aXRjaChcbiAgICAgICAgICAgICAgW1xuICAgICAgICAgICAgICAgIGF1ZGl0QXJyYXkoYXVkaXRCb29sZWFuKSxcbiAgICAgICAgICAgICAgICBhdWRpdENsZWFuQXJyYXkoYXVkaXRCb29sZWFuKSxcbiAgICAgICAgICAgICAgICBhdWRpdFVuaXF1ZSxcbiAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgW1xuICAgICAgICAgICAgICAgIGF1ZGl0QXJyYXkoYXVkaXRTdHJpbmcpLFxuICAgICAgICAgICAgICAgIGF1ZGl0Q2xlYW5BcnJheShhdWRpdFRyaW1TdHJpbmcpLFxuICAgICAgICAgICAgICAgIGF1ZGl0VW5pcXVlLFxuICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICBbYXVkaXRCb29sZWFuLCBhdWRpdEZ1bmN0aW9uKCh2YWx1ZSkgPT4gW3ZhbHVlXSldLFxuICAgICAgICAgICAgICBbYXVkaXRUcmltU3RyaW5nLCBhdWRpdEZ1bmN0aW9uKCh2YWx1ZSkgPT4gW3ZhbHVlXSldLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIC8vIFRPRE86IFRlc3QgZXhpc3RlbmNlIG9mIHZhcmlhYmxlIHZhbHVlLlxuICAgICAgICAgICAgYXVkaXRSZXF1aXJlLFxuICAgICAgICAgIClcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBlcnJvcnNbdmFyaWFibGVOYW1lXSA9PT0gdW5kZWZpbmVkICYmXG4gICAgICAgICAgICB2YWxpZFZhcmlhYmxlTmFtZSAhPT0gdmFyaWFibGVOYW1lXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICBkYXRhW3ZhbGlkVmFyaWFibGVOYW1lXSA9IGRhdGFbdmFyaWFibGVOYW1lXVxuICAgICAgICAgICAgZGVsZXRlIGRhdGFbdmFyaWFibGVOYW1lXVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBXYXRlcmZhbGwgb3B0aW9uc1xuXG4gICAgICBmb3IgKGNvbnN0IGtleSBvZiBbXCJlbHNlXCIsIFwidGhlblwiXSkge1xuICAgICAgICBhdWRpdC5hdHRyaWJ1dGUoXG4gICAgICAgICAgZGF0YSxcbiAgICAgICAgICBrZXksXG4gICAgICAgICAgdHJ1ZSxcbiAgICAgICAgICBlcnJvcnMsXG4gICAgICAgICAgcmVtYWluaW5nS2V5cyxcbiAgICAgICAgICBhdWRpdFdhdGVyZmFsbEN1c3RvbWl6YXRpb24sXG4gICAgICAgIClcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gYXVkaXQucmVkdWNlUmVtYWluaW5nKGRhdGEsIGVycm9ycywgcmVtYWluaW5nS2V5cylcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGF1ZGl0RGVjb21wb3NpdGlvblJlZmVyZW5jZShcbiAgYXVkaXQ6IEF1ZGl0LFxuICBkYXRhVW5rbm93bjogdW5rbm93bixcbik6IFt1bmtub3duLCB1bmtub3duXSB7XG4gIGlmIChkYXRhVW5rbm93biA9PSBudWxsKSB7XG4gICAgcmV0dXJuIFtkYXRhVW5rbm93biwgbnVsbF1cbiAgfVxuICBpZiAodHlwZW9mIGRhdGFVbmtub3duICE9PSBcIm9iamVjdFwiKSB7XG4gICAgcmV0dXJuIGF1ZGl0LnVuZXhwZWN0ZWRUeXBlKGRhdGFVbmtub3duLCBcIm9iamVjdFwiKVxuICB9XG5cbiAgY29uc3QgZGF0YTogeyBba2V5OiBzdHJpbmddOiB1bmtub3duIH0gPSB7IC4uLmRhdGFVbmtub3duIH1cbiAgY29uc3QgZXJyb3JzOiB7IFtrZXk6IHN0cmluZ106IHVua25vd24gfSA9IHt9XG4gIGNvbnN0IHJlbWFpbmluZ0tleXMgPSBuZXcgU2V0KE9iamVjdC5rZXlzKGRhdGEpKVxuXG4gIGF1ZGl0LmF0dHJpYnV0ZShcbiAgICBkYXRhLFxuICAgIFwibmFtZVwiLFxuICAgIHRydWUsXG4gICAgZXJyb3JzLFxuICAgIHJlbWFpbmluZ0tleXMsXG4gICAgYXVkaXRUcmltU3RyaW5nLFxuICAgIGF1ZGl0UmVxdWlyZSxcbiAgKVxuICBhdWRpdC5hdHRyaWJ1dGUoXG4gICAgZGF0YSxcbiAgICBcIm5lZ2F0ZVwiLFxuICAgIHRydWUsXG4gICAgZXJyb3JzLFxuICAgIHJlbWFpbmluZ0tleXMsXG4gICAgYXVkaXRCb29sZWFuLFxuICAgIGF1ZGl0RnVuY3Rpb24oKHZhbHVlKSA9PiB2YWx1ZSB8fCB1bmRlZmluZWQpLCAvLyBSZXBsYWNlIGZhbHNlIHdpdGggdW5kZWZpbmVkLlxuICApXG5cbiAgcmV0dXJuIGF1ZGl0LnJlZHVjZVJlbWFpbmluZyhkYXRhLCBlcnJvcnMsIHJlbWFpbmluZ0tleXMpXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhdWRpdFZhcmlhYmxlc0N1c3RvbWl6YXRpb24oXG4gIGF1ZGl0OiBBdWRpdCxcbiAgZGF0YVVua25vd246IHVua25vd24sXG4pOiBbdW5rbm93biwgdW5rbm93bl0ge1xuICBpZiAoZGF0YVVua25vd24gPT0gbnVsbCkge1xuICAgIHJldHVybiBbZGF0YVVua25vd24sIG51bGxdXG4gIH1cbiAgaWYgKHR5cGVvZiBkYXRhVW5rbm93biAhPT0gXCJvYmplY3RcIikge1xuICAgIHJldHVybiBhdWRpdC51bmV4cGVjdGVkVHlwZShkYXRhVW5rbm93biwgXCJvYmplY3RcIilcbiAgfVxuXG4gIGNvbnN0IGRhdGE6IHsgW2tleTogc3RyaW5nXTogdW5rbm93biB9ID0geyAuLi5kYXRhVW5rbm93biB9XG4gIGNvbnN0IGVycm9yczogeyBba2V5OiBzdHJpbmddOiB1bmtub3duIH0gPSB7fVxuICBjb25zdCByZW1haW5pbmdLZXlzID0gbmV3IFNldChPYmplY3Qua2V5cyhkYXRhKSlcblxuICAvLyBOb3RlOiBgXCJoaWRkZW5cIjogZmFsc2VgIGlzIG5vdCB0aGUgc2FtZSBhcyBgdW5kZWZpbmVkYC5cbiAgYXVkaXQuYXR0cmlidXRlKGRhdGEsIFwiaGlkZGVuXCIsIHRydWUsIGVycm9ycywgcmVtYWluaW5nS2V5cywgYXVkaXRCb29sZWFuKVxuXG4gIHJldHVybiBhdWRpdC5yZWR1Y2VSZW1haW5pbmcoZGF0YSwgZXJyb3JzLCByZW1haW5pbmdLZXlzKVxufVxuXG5leHBvcnQgZnVuY3Rpb24gYXVkaXRXYXRlcmZhbGxDdXN0b21pemF0aW9uKFxuICBhdWRpdDogQXVkaXQsXG4gIGRhdGFVbmtub3duOiB1bmtub3duLFxuKTogW3Vua25vd24sIHVua25vd25dIHtcbiAgaWYgKGRhdGFVbmtub3duID09IG51bGwpIHtcbiAgICByZXR1cm4gW2RhdGFVbmtub3duLCBudWxsXVxuICB9XG4gIGlmICh0eXBlb2YgZGF0YVVua25vd24gIT09IFwib2JqZWN0XCIpIHtcbiAgICByZXR1cm4gYXVkaXQudW5leHBlY3RlZFR5cGUoZGF0YVVua25vd24sIFwib2JqZWN0XCIpXG4gIH1cblxuICBjb25zdCBkYXRhOiB7IFtrZXk6IHN0cmluZ106IHVua25vd24gfSA9IHsgLi4uZGF0YVVua25vd24gfVxuICBjb25zdCBlcnJvcnM6IHsgW2tleTogc3RyaW5nXTogdW5rbm93biB9ID0ge31cbiAgY29uc3QgcmVtYWluaW5nS2V5cyA9IG5ldyBTZXQoT2JqZWN0LmtleXMoZGF0YSkpXG5cbiAgYXVkaXQuYXR0cmlidXRlKFxuICAgIGRhdGEsXG4gICAgXCJjaGlsZHJlblwiLFxuICAgIGZhbHNlLCAvLyBEb24ndCBkZWxldGUgbnVsbGlzaCBjaGlsZHJlbiAobnVsbGlzaCBtZWFucyBudWxsIGFmdGVyIGEgSlNPTi5wYXJzZSkuXG4gICAgZXJyb3JzLFxuICAgIHJlbWFpbmluZ0tleXMsXG4gICAgYXVkaXRDbGVhbkFycmF5KGF1ZGl0RGVjb21wb3NpdGlvblJlZmVyZW5jZSksXG4gIClcbiAgLy8gTm90ZTogYFwiaGlkZGVuXCI6IGZhbHNlYCBpcyBub3QgdGhlIHNhbWUgYXMgYHVuZGVmaW5lZGAuXG4gIGF1ZGl0LmF0dHJpYnV0ZShkYXRhLCBcImhpZGRlblwiLCB0cnVlLCBlcnJvcnMsIHJlbWFpbmluZ0tleXMsIGF1ZGl0Qm9vbGVhbilcblxuICByZXR1cm4gYXVkaXQucmVkdWNlUmVtYWluaW5nKGRhdGEsIGVycm9ycywgcmVtYWluaW5nS2V5cylcbn1cbiJdLCJtYXBwaW5ncyI6IkFBQ0EsU0FDRUEsVUFBVSxFQUNWQyxZQUFZLEVBQ1pDLFVBQVUsRUFDVkMsZUFBZSxFQUNmQyxzQkFBc0IsRUFDdEJDLGFBQWEsRUFDYkMsdUJBQXVCLEVBQ3ZCQyxZQUFZLEVBQ1pDLFdBQVcsRUFDWEMsV0FBVyxFQUNYQyxlQUFlLEVBQ2ZDLFdBQVcsUUFDTixnQkFBZ0I7QUFBQSxTQUVkQyxxQkFBcUI7QUFFOUIsT0FBTyxTQUFTQyxrQkFBa0JBLENBQ2hDQyxLQUFZLEVBQ1pDLFdBQW9CLEVBQ0E7RUFDcEIsSUFBSUEsV0FBVyxJQUFJLElBQUksRUFBRTtJQUN2QixPQUFPLENBQUNBLFdBQVcsRUFBRSxJQUFJLENBQUM7RUFDNUI7RUFDQSxJQUFJLE9BQU9BLFdBQVcsS0FBSyxRQUFRLEVBQUU7SUFDbkMsT0FBT0QsS0FBSyxDQUFDRSxjQUFjLENBQUNELFdBQVcsRUFBRSxRQUFRLENBQUM7RUFDcEQ7RUFFQSxNQUFNRSxJQUFnQyxHQUFHO0lBQUUsR0FBR0Y7RUFBWSxDQUFDO0VBQzNELE1BQU1HLE1BQWtDLEdBQUcsQ0FBQyxDQUFDO0VBQzdDLE1BQU1DLGFBQWEsR0FBRyxJQUFJQyxHQUFHLENBQUNDLE1BQU0sQ0FBQ0MsSUFBSSxDQUFDTCxJQUFJLENBQUMsQ0FBQztFQUVoRE0sNkJBQTZCLENBQUNULEtBQUssRUFBRUcsSUFBSSxFQUFFQyxNQUFNLEVBQUVDLGFBQWEsQ0FBQztFQUVqRUwsS0FBSyxDQUFDVSxTQUFTLENBQ2JQLElBQUksRUFDSixPQUFPLEVBQ1AsSUFBSSxF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