@decaf-ts/db-decorators
Version:
Agnostic database decorators and repository
125 lines • 20.1 kB
JavaScript
import { ModelErrorDefinition, ModelKeys, ReservedModels, sf, Validation, ValidationKeys, } from "@decaf-ts/decorator-validation";
import { Reflection } from "@decaf-ts/reflection";
import { UpdateValidationKeys } from "../validation";
import { findModelId } from "../identity";
/**
* @summary Validates the update of a model
*
* @param {T} oldModel
* @param {T} newModel
* @param {string[]} [exceptions]
*
* @function validateCompare
* @return {ModelErrorDefinition | undefined}
*
* @memberOf module:db-decorators.Model
*/
export function validateCompare(oldModel, newModel, ...exceptions) {
const decoratedProperties = [];
for (const prop in newModel)
if (Object.prototype.hasOwnProperty.call(newModel, prop) &&
exceptions.indexOf(prop) === -1)
decoratedProperties.push(Reflection.getPropertyDecorators(UpdateValidationKeys.REFLECT, newModel, prop));
let result = undefined;
for (const decoratedProperty of decoratedProperties) {
const { prop, decorators } = decoratedProperty;
decorators.shift(); // remove the design:type decorator, since the type will already be checked
if (!decorators || !decorators.length)
continue;
let errs = undefined;
for (const decorator of decorators) {
const validator = Validation.get(decorator.key);
if (!validator) {
console.error(`Could not find Matching validator for ${decorator.key} for property ${String(decoratedProperty.prop)}`);
continue;
}
const err = validator.updateHasErrors(newModel[prop.toString()], oldModel[prop.toString()], ...Object.values(decorator.props));
if (err) {
errs = errs || {};
errs[decorator.key] = err;
}
}
if (errs) {
result = result || {};
result[decoratedProperty.prop.toString()] = errs;
}
}
// tests nested classes
for (const prop of Object.keys(newModel).filter((k) => {
if (exceptions.includes(k))
return false;
return !result || !result[k];
})) {
let err;
// if a nested Model
const allDecorators = Reflection.getPropertyDecorators(ValidationKeys.REFLECT, newModel, prop).decorators;
const decorators = Reflection.getPropertyDecorators(ValidationKeys.REFLECT, newModel, prop).decorators.filter((d) => [ModelKeys.TYPE, ValidationKeys.TYPE].indexOf(d.key) !== -1);
if (!decorators || !decorators.length)
continue;
const dec = decorators.pop();
const clazz = dec.props.name
? [dec.props.name]
: Array.isArray(dec.props.customTypes)
? dec.props.customTypes
: [dec.props.customTypes];
const reserved = Object.values(ReservedModels).map((v) => v.toLowerCase());
for (const c of clazz) {
if (reserved.indexOf(c.toLowerCase()) === -1) {
switch (c) {
case Array.name:
case Set.name:
if (allDecorators.length) {
const listDec = allDecorators.find((d) => d.key === ValidationKeys.LIST);
if (listDec) {
let currentList, oldList;
switch (c) {
case Array.name:
currentList = newModel[prop];
oldList = oldModel[prop];
break;
case Set.name:
currentList = newModel[prop].values();
oldList = oldModel[prop].values();
break;
default:
throw new Error(`Invalid attribute type ${c}`);
}
err = currentList
.map((v) => {
const id = findModelId(v, true);
if (!id)
return "Failed to find model id";
const oldModel = oldList.find((el) => id === findModelId(el, true));
if (!oldModel)
return; // nothing to compare with
return v.hasErrors(oldModel);
})
.filter((e) => !!e);
if (!err?.length) {
// if the result is an empty list...
err = undefined;
}
}
}
break;
default:
try {
if (newModel[prop] &&
oldModel[prop])
err = newModel[prop].hasErrors(oldModel[prop]);
// eslint-disable-next-line @typescript-eslint/no-unused-vars
}
catch (e) {
console.warn(sf("Model should be validatable but its not"));
}
}
}
if (err) {
result = result || {};
result[prop] = err;
}
}
}
return result ? new ModelErrorDefinition(result) : undefined;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9tb2RlbC92YWxpZGF0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFFTCxvQkFBb0IsRUFFcEIsU0FBUyxFQUNULGNBQWMsRUFDZCxFQUFFLEVBRUYsVUFBVSxFQUNWLGNBQWMsR0FFZixNQUFNLGdDQUFnQyxDQUFDO0FBQ3hDLE9BQU8sRUFBcUIsVUFBVSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDckUsT0FBTyxFQUFFLG9CQUFvQixFQUFtQixNQUFNLGVBQWUsQ0FBQztBQUN0RSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBRTFDOzs7Ozs7Ozs7OztHQVdHO0FBQ0gsTUFBTSxVQUFVLGVBQWUsQ0FDN0IsUUFBVyxFQUNYLFFBQVcsRUFDWCxHQUFHLFVBQW9CO0lBRXZCLE1BQU0sbUJBQW1CLEdBQTRDLEVBQUUsQ0FBQztJQUN4RSxLQUFLLE1BQU0sSUFBSSxJQUFJLFFBQVE7UUFDekIsSUFDRSxNQUFNLENBQUMsU0FBUyxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQztZQUNwRCxVQUFVLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUUvQixtQkFBbUIsQ0FBQyxJQUFJLENBQ3RCLFVBQVUsQ0FBQyxxQkFBcUIsQ0FDOUIsb0JBQW9CLENBQUMsT0FBTyxFQUM1QixRQUFRLEVBQ1IsSUFBSSxDQUNvQyxDQUMzQyxDQUFDO0lBRU4sSUFBSSxNQUFNLEdBQTRCLFNBQVMsQ0FBQztJQUVoRCxLQUFLLE1BQU0saUJBQWlCLElBQUksbUJBQW1CLEVBQUUsQ0FBQztRQUNwRCxNQUFNLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxHQUFHLGlCQUFpQixDQUFDO1FBRS9DLFVBQVUsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLDJFQUEyRTtRQUUvRixJQUFJ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SSxHQUFHLEVBQUUsQ0FBQztnQkFDUixNQUFNLEdBQUcsTUFBTSxJQUFJLEVBQUUsQ0FBQztnQkFDdEIsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLEdBQVUsQ0FBQztZQUM1QixDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7SUFDRCxPQUFPLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxvQkFBb0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO0FBQy9ELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBNb2RlbCxcbiAgTW9kZWxFcnJvckRlZmluaXRpb24sXG4gIE1vZGVsRXJyb3JzLFxuICBNb2RlbEtleXMsXG4gIFJlc2VydmVkTW9kZWxzLFxuICBzZixcbiAgVmFsaWRhdGFibGUsXG4gIFZhbGlkYXRpb24sXG4gIFZhbGlkYXRpb25LZXlzLFxuICBWYWxpZGF0aW9uUHJvcGVydHlEZWNvcmF0b3JEZWZpbml0aW9uLFxufSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBEZWNvcmF0b3JNZXRhZGF0YSwgUmVmbGVjdGlvbiB9IGZyb20gXCJAZGVjYWYtdHMvcmVmbGVjdGlvblwiO1xuaW1wb3J0IHsgVXBkYXRlVmFsaWRhdGlvbktleXMsIFVwZGF0ZVZhbGlkYXRvciB9IGZyb20gXCIuLi92YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBmaW5kTW9kZWxJZCB9IGZyb20gXCIuLi9pZGVudGl0eVwiO1xuXG4vKipcbiAqIEBzdW1tYXJ5IFZhbGlkYXRlcyB0aGUgdXBkYXRlIG9mIGEgbW9kZWxcbiAqXG4gKiBAcGFyYW0ge1R9IG9sZE1vZGVsXG4gKiBAcGFyYW0ge1R9IG5ld01vZGVsXG4gKiBAcGFyYW0ge3N0cmluZ1tdfSBbZXhjZXB0aW9uc11cbiAqXG4gKiBAZnVuY3Rpb24gdmFsaWRhdGVDb21wYXJlXG4gKiBAcmV0dXJuIHtNb2RlbEVycm9yRGVmaW5pdGlvbiB8IHVuZGVmaW5lZH1cbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRiLWRlY29yYXRvcnMuTW9kZWxcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlQ29tcGFyZTxNIGV4dGVuZHMgTW9kZWw+KFxuICBvbGRNb2RlbDogTSxcbiAgbmV3TW9kZWw6IE0sXG4gIC4uLmV4Y2VwdGlvbnM6IHN0cmluZ1tdXG4pOiBNb2RlbEVycm9yRGVmaW5pdGlvbiB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IGRlY29yYXRlZFByb3BlcnRpZXM6IFZhbGlkYXRpb25Qcm9wZXJ0eURlY29yYXRvckRlZmluaXRpb25bXSA9IFtdO1xuICBmb3IgKGNvbnN0IHByb3AgaW4gbmV3TW9kZWwpXG4gICAgaWYgKFxuICAgICAgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG5ld01vZGVsLCBwcm9wKSAmJlxuICAgICAgZXhjZXB0aW9ucy5pbmRleE9mKHByb3ApID09PSAtMVxuICAgIClcbiAgICAgIGRlY29yYXRlZFByb3BlcnRpZXMucHVzaChcbiAgICAgICAgUmVmbGVjdGlvbi5nZXRQcm9wZXJ0eURlY29yYXRvcnMoXG4gICAgICAgICAgVXBkYXRlVmFsaWRhdGlvbktleXMuUkVGTEVDVCxcbiAgICAgICAgICBuZXdNb2RlbCxcbiAgICAgICAgICBwcm9wXG4gICAgICAgICkgYXMgVmFsaWRhdGlvblByb3BlcnR5RGVjb3JhdG9yRGVmaW5pdGlvblxuICAgICAgKTtcblxuICBsZXQgcmVzdWx0OiBNb2RlbEVycm9ycyB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcblxuICBmb3IgKGNvbnN0IGRlY29yYXRlZFByb3BlcnR5IG9mIGRlY29yYXRlZFByb3BlcnRpZXMpIHtcbiAgICBjb25zdCB7IHByb3AsIGRlY29yYXRvcnMgfSA9IGRlY29yYXRlZFByb3BlcnR5O1xuXG4gICAgZGVjb3JhdG9ycy5zaGlmdCgpOyAvLyByZW1vdmUgdGhlIGRlc2lnbjp0eXBlIGRlY29yYXRvciwgc2luY2UgdGhlIHR5cGUgd2lsbCBhbHJlYWR5IGJlIGNoZWNrZWRcblxuICAgIGlmICghZGVjb3JhdG9ycyB8fCAhZGVjb3JhdG9ycy5sZW5ndGgpIGNvbnRpbnVlO1xuICAgIGxldCBlcnJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCB1bmRlZmluZWQ+IHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuXG4gICAgZm9yIChjb25zdCBkZWNvcmF0b3Igb2YgZGVjb3JhdG9ycykge1xuICAgICAgY29uc3QgdmFsaWRhdG9yOiBVcGRhdGVWYWxpZGF0b3IgPSBWYWxpZGF0aW9uLmdldChcbiAgICAgICAgZGVjb3JhdG9yLmtleVxuICAgICAgKSBhcyBVcGRhdGVWYWxpZGF0b3I7XG4gICAgICBpZiAoIXZhbGlkYXRvcikge1xuICAgICAgICBjb25zb2xlLmVycm9yKFxuICAgICAgICAgIGBDb3VsZCBub3QgZmluZCBNYXRjaGluZyB2YWxpZGF0b3IgZm9yICR7ZGVjb3JhdG9yLmtleX0gZm9yIHByb3BlcnR5ICR7U3RyaW5nKGRlY29yYXRlZFByb3BlcnR5LnByb3ApfWBcbiAgICAgICAgKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGVycjogc3RyaW5nIHwgdW5kZWZpbmVkID0gdmFsaWRhdG9yLnVwZGF0ZUhhc0Vycm9ycyhcbiAgICAgICAgKG5ld01vZGVsIGFzIGFueSlbcHJvcC50b1N0cmluZygpXSxcbiAgICAgICAgKG9sZE1vZGVsIGFzIGFueSlbcHJvcC50b1N0cmluZygpXSxcbiAgICAgICAgLi4uT2JqZWN0LnZhbHVlcyhkZWNvcmF0b3IucHJvcHMpXG4gICAgICApO1xuXG4gICAgICBpZiAoZXJyKSB7XG4gICAgICAgIGVycnMgPSBlcnJzIHx8IHt9O1xuICAgICAgICBlcnJzW2RlY29yYXRvci5rZXldID0gZXJyO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChlcnJzKSB7XG4gICAgICByZXN1bHQgPSByZXN1bHQgfHwge307XG4gICAgICByZXN1bHRbZGVjb3JhdGVkUHJvcGVydHkucHJvcC50b1N0cmluZygpXSA9IGVycnM7XG4gICAgfVxuICB9XG4gIC8vIHRlc3RzIG5lc3RlZCBjbGFzc2VzXG4gIGZvciAoY29uc3QgcHJvcCBvZiBPYmplY3Qua2V5cyhuZXdNb2RlbCkuZmlsdGVyKChrKSA9PiB7XG4gICAgaWYgKGV4Y2VwdGlvbnMuaW5jbHVkZXMoaykpIHJldHVybiBmYWxzZTtcbiAgICByZXR1cm4gIXJlc3VsdCB8fCAhcmVzdWx0W2tdO1xuICB9KSkge1xuICAgIGxldCBlcnI6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICAvLyBpZiBhIG5lc3RlZCBNb2RlbFxuICAgIGNvbnN0IGFsbERlY29yYXRvcnMgPSBSZWZsZWN0aW9uLmdldFByb3BlcnR5RGVjb3JhdG9ycyhcbiAgICAgIFZhbGlkYXRpb25LZXlzLlJFRkxFQ1QsXG4gICAgICBuZXdNb2RlbCxcbiAgICAgIHByb3BcbiAgICApLmRlY29yYXRvcnM7XG4gICAgY29uc3QgZGVjb3JhdG9ycyA9IFJlZmxlY3Rpb24uZ2V0UHJvcGVydHlEZWNvcmF0b3JzKFxuICAgICAgVmFsaWRhdGlvbktleXMuUkVGTEVDVCxcbiAgICAgIG5ld01vZGVsLFxuICAgICAgcHJvcFxuICAgICkuZGVjb3JhdG9ycy5maWx0ZXIoXG4gICAgICAoZCkgPT4gW01vZGVsS2V5cy5UWVBFLCBWYWxpZGF0aW9uS2V5cy5UWVBFXS5pbmRleE9mKGQua2V5IGFzIGFueSkgIT09IC0xXG4gICAgKTtcbiAgICBpZiAoIWRlY29yYXRvcnMgfHwgIWRlY29yYXRvcnMubGVuZ3RoKSBjb250aW51ZTtcbiAgICBjb25zdCBkZWMgPSBkZWNvcmF0b3JzLnBvcCgpIGFzIERlY29yYXRvck1ldGFkYXRhO1xuICAgIGNvbnN0IGNsYXp6ID0gZGVjLnByb3BzLm5hbWVcbiAgICAgID8gW2RlYy5wcm9wcy5uYW1lXVxuICAgICAgOiBBcnJheS5pc0FycmF5KGRlYy5wcm9wcy5jdXN0b21UeXBlcylcbiAgICAgICAgPyBkZWMucHJvcHMuY3VzdG9tVHlwZXNcbiAgICAgICAgOiBbZGVjLnByb3BzLmN1c3RvbVR5cGVzXTtcbiAgICBjb25zdCByZXNlcnZlZCA9IE9iamVjdC52YWx1ZXMoUmVzZXJ2ZWRNb2RlbHMpLm1hcCgodikgPT5cbiAgICAgIHYudG9Mb3dlckNhc2UoKVxuICAgICkgYXMgc3RyaW5nW107XG5cbiAgICBmb3IgKGNvbnN0IGMgb2YgY2xhenopIHtcbiAgICAgIGlmIChyZXNlcnZlZC5pbmRleE9mKGMudG9Mb3dlckNhc2UoKSkgPT09IC0xKSB7XG4gICAgICAgIHN3aXRjaCAoYykge1xuICAgICAgICAgIGNhc2UgQXJyYXkubmFtZTpcbiAgICAgICAgICBjYXNlIFNldC5uYW1lOlxuICAgICAgICAgICAgaWYgKGFsbERlY29yYXRvcnMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgIGNvbnN0IGxpc3REZWMgPSBhbGxEZWNvcmF0b3JzLmZpbmQoXG4gICAgICAgICAgICAgICAgKGQpID0+IGQua2V5ID09PSBWYWxpZGF0aW9uS2V5cy5MSVNUXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIGlmIChsaXN0RGVjKSB7XG4gICAgICAgICAgICAgICAgbGV0IGN1cnJlbnRMaXN0LCBvbGRMaXN0O1xuXG4gICAgICAgICAgICAgICAgc3dpdGNoIChjKSB7XG4gICAgICAgICAgICAgICAgICBjYXNlIEFycmF5Lm5hbWU6XG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRMaXN0ID0gKG5ld01vZGVsIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW3Byb3BdO1xuICAgICAgICAgICAgICAgICAgICBvbGRMaXN0ID0gKG9sZE1vZGVsIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW3Byb3BdO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgIGNhc2UgU2V0Lm5hbWU6XG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRMaXN0ID0gKG5ld01vZGVsIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW1xuICAgICAgICAgICAgICAgICAgICAgIHByb3BcbiAgICAgICAgICAgICAgICAgICAgXS52YWx1ZXMoKTtcbiAgICAgICAgICAgICAgICAgICAgb2xkTGlzdCA9IChvbGRNb2RlbCBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+KVtwcm9wXS52YWx1ZXMoKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgYXR0cmlidXRlIHR5cGUgJHtjfWApO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGVyciA9IGN1cnJlbnRMaXN0XG4gICAgICAgICAgICAgICAgICAubWFwKCh2OiBWYWxpZGF0YWJsZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBpZCA9IGZpbmRNb2RlbElkKHYgYXMgYW55LCB0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFpZCkgcmV0dXJuIFwiRmFpbGVkIHRvIGZpbmQgbW9kZWwgaWRcIjtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgb2xkTW9kZWwgPSBvbGRMaXN0LmZpbmQoXG4gICAgICAgICAgICAgICAgICAgICAgKGVsOiBhbnkpID0+IGlkID09PSBmaW5kTW9kZWxJZChlbCwgdHJ1ZSlcbiAgICAgICAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAoIW9sZE1vZGVsKSByZXR1cm47IC8vIG5vdGhpbmcgdG8gY29tcGFyZSB3aXRoXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB2Lmhhc0Vycm9ycyhvbGRNb2RlbCk7XG4gICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgLmZpbHRlcigoZTogYW55KSA9PiAhIWUpIGFzIGFueTtcblxuICAgICAgICAgICAgICAgIGlmICghZXJyPy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgIC8vIGlmIHRoZSByZXN1bHQgaXMgYW4gZW1wdHkgbGlzdC4uLlxuICAgICAgICAgICAgICAgICAgZXJyID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAobmV3TW9kZWwgYXMgUmVjb3JkPHN0cmluZywgYW55PilbcHJvcF0gJiZcbiAgICAgICAgICAgICAgICAob2xkTW9kZWwgYXMgUmVjb3JkPHN0cmluZywgYW55PilbcHJvcF1cbiAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIGVyciA9IChuZXdNb2RlbCBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+KVtwcm9wXS5oYXNFcnJvcnMoXG4gICAgICAgICAgICAgICAgICAob2xkTW9kZWwgYXMgUmVjb3JkPHN0cmluZywgYW55PilbcHJvcF1cbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgICAgICAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgICAgICAgICAgY29uc29sZS53YXJuKHNmKFwiTW9kZWwgc2hvdWxkIGJlIHZhbGlkYXRhYmxlIGJ1dCBpdHMgbm90XCIpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGVycikge1xuICAgICAgICByZXN1bHQgPSByZXN1bHQgfHwge307XG4gICAgICAgIHJlc3VsdFtwcm9wXSA9IGVyciBhcyBhbnk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQgPyBuZXcgTW9kZWxFcnJvckRlZmluaXRpb24ocmVzdWx0KSA6IHVuZGVmaW5lZDtcbn1cbiJdfQ==