UNPKG

matrix-react-sdk

Version:
173 lines (167 loc) 22.8 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = withValidation; var _react = _interopRequireDefault(require("react")); var _classnames = _interopRequireDefault(require("classnames")); var _memoizeOne = _interopRequireDefault(require("memoize-one")); /* Copyright 2024 New Vector Ltd. Copyright 2020 The Matrix.org Foundation C.I.C. Copyright 2019 New Vector Ltd SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only Please see LICENSE files in the repository root for full details. */ /** * Creates a validation function from a set of rules describing what to validate. * Generic T is the "this" type passed to the rule methods * * @param {Function} description * Function that returns a string summary of the kind of value that will * meet the validation rules. Shown at the top of the validation feedback. * @param {boolean} hideDescriptionIfValid * If true, don't show the description if the validation passes validation. * @param {Function} deriveData * Optional function that returns a Promise to an object of generic type D. * The result of this Promise is passed to rule methods `skip`, `test`, `valid`, and `invalid`. * Useful for doing calculations per-value update once rather than in each of the above rule methods. * @param {Object} rules * An array of rules describing how to check to input value. Each rule in an object * and may have the following properties: * - `key`: A unique ID for the rule. Required. * - `skip`: A function used to determine whether the rule should even be evaluated. * - `test`: A function used to determine the rule's current validity. Required. * - `valid`: Function returning text to show when the rule is valid. Only shown if set. * - `invalid`: Function returning text to show when the rule is invalid. Only shown if set. * - `final`: A Boolean if true states that this rule will only be considered if all rules before it returned valid. * @param {boolean?} memoize * If true, will use memoization to avoid calling deriveData & rules unless the value or allowEmpty change. * Be careful to not use this if your validation is not pure and depends on other fields, such as "repeat password". * @returns {Function} * A validation function that takes in the current input value and returns * the overall validity and a feedback UI that can be rendered for more detail. */ function withValidation({ description, hideDescriptionIfValid, deriveData, rules, memoize }) { let checkRules = async function (data, derivedData) { const results = []; let valid = true; for (const rule of rules) { if (!rule.key || !rule.test) { continue; } if (!valid && rule.final) { continue; } if (rule.skip?.call(this, data, derivedData)) { continue; } // We're setting `this` to whichever component holds the validation // function. That allows rules to access the state of the component. const ruleValid = await rule.test.call(this, data, derivedData); valid = valid && ruleValid; if (ruleValid && rule.valid) { // If the rule's result is valid and has text to show for // the valid state, show it. const text = rule.valid.call(this, derivedData); if (!text) { continue; } results.push({ key: rule.key, valid: true, text }); } else if (!ruleValid && rule.invalid) { // If the rule's result is invalid and has text to show for // the invalid state, show it. const text = rule.invalid.call(this, derivedData); if (!text) { continue; } results.push({ key: rule.key, valid: false, text }); } } return [valid, results]; }; // We have to memoize it in chunks as `focused` can change frequently, but it isn't passed to these methods if (memoize) { if (deriveData) deriveData = (0, _memoizeOne.default)(deriveData, isDataEqual); checkRules = (0, _memoizeOne.default)(checkRules, isDerivedDataEqual); } return async function onValidate({ value, focused, allowEmpty = true }) { if (!value && allowEmpty) { return {}; } const data = { value, allowEmpty }; // We know that if deriveData is set then D will not be undefined const derivedData = await deriveData?.call(this, data); const [valid, results] = await checkRules.call(this, data, derivedData); // Hide feedback when not focused if (!focused) { return { valid }; } let details; if (results && results.length) { details = /*#__PURE__*/_react.default.createElement("ul", { className: "mx_Validation_details" }, results.map(result => { const classes = (0, _classnames.default)({ mx_Validation_detail: true, mx_Validation_valid: result.valid, mx_Validation_invalid: !result.valid }); return /*#__PURE__*/_react.default.createElement("li", { key: result.key, className: classes }, result.text); })); } let summary; if (description && (details || !hideDescriptionIfValid)) { // We're setting `this` to whichever component holds the validation // function. That allows rules to access the state of the component. const content = description.call(this, derivedData, results); summary = content ? /*#__PURE__*/_react.default.createElement("div", { className: "mx_Validation_description" }, content) : undefined; } let feedback; if (summary || details) { feedback = /*#__PURE__*/_react.default.createElement("div", { className: "mx_Validation" }, summary, details); } return { valid, feedback }; }; } function isDataEqual([a], [b]) { return a.value === b.value && a.allowEmpty === b.allowEmpty; } function isDerivedDataEqual([a1, a2], [b1, b2]) { return a2 === b2 && isDataEqual([a1], [b1]); } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwicmVxdWlyZSIsIl9jbGFzc25hbWVzIiwiX21lbW9pemVPbmUiLCJ3aXRoVmFsaWRhdGlvbiIsImRlc2NyaXB0aW9uIiwiaGlkZURlc2NyaXB0aW9uSWZWYWxpZCIsImRlcml2ZURhdGEiLCJydWxlcyIsIm1lbW9pemUiLCJjaGVja1J1bGVzIiwiZGF0YSIsImRlcml2ZWREYXRhIiwicmVzdWx0cyIsInZhbGlkIiwicnVsZSIsImtleSIsInRlc3QiLCJmaW5hbCIsInNraXAiLCJjYWxsIiwicnVsZVZhbGlkIiwidGV4dCIsInB1c2giLCJpbnZhbGlkIiwibWVtb2l6ZU9uZSIsImlzRGF0YUVxdWFsIiwiaXNEZXJpdmVkRGF0YUVxdWFsIiwib25WYWxpZGF0ZSIsInZhbHVlIiwiZm9jdXNlZCIsImFsbG93RW1wdHkiLCJkZXRhaWxzIiwibGVuZ3RoIiwiZGVmYXVsdCIsImNyZWF0ZUVsZW1lbnQiLCJjbGFzc05hbWUiLCJtYXAiLCJyZXN1bHQiLCJjbGFzc2VzIiwiY2xhc3NOYW1lcyIsIm14X1ZhbGlkYXRpb25fZGV0YWlsIiwibXhfVmFsaWRhdGlvbl92YWxpZCIsIm14X1ZhbGlkYXRpb25faW52YWxpZCIsInN1bW1hcnkiLCJjb250ZW50IiwidW5kZWZpbmVkIiwiZmVlZGJhY2siLCJhIiwiYiIsImExIiwiYTIiLCJiMSIsImIyIl0sInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBvbmVudHMvdmlld3MvZWxlbWVudHMvVmFsaWRhdGlvbi50c3giXSwic291cmNlc0NvbnRlbnQiOlsiLypcbkNvcHlyaWdodCAyMDI0IE5ldyBWZWN0b3IgTHRkLlxuQ29weXJpZ2h0IDIwMjAgVGhlIE1hdHJpeC5vcmcgRm91bmRhdGlvbiBDLkkuQy5cbkNvcHlyaWdodCAyMDE5IE5ldyBWZWN0b3IgTHRkXG5cblNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBR1BMLTMuMC1vbmx5IE9SIEdQTC0zLjAtb25seVxuUGxlYXNlIHNlZSBMSUNFTlNFIGZpbGVzIGluIHRoZSByZXBvc2l0b3J5IHJvb3QgZm9yIGZ1bGwgZGV0YWlscy5cbiovXG5cbmltcG9ydCBSZWFjdCwgeyBSZWFjdENoaWxkLCBSZWFjdE5vZGUgfSBmcm9tIFwicmVhY3RcIjtcbmltcG9ydCBjbGFzc05hbWVzIGZyb20gXCJjbGFzc25hbWVzXCI7XG5pbXBvcnQgbWVtb2l6ZU9uZSBmcm9tIFwibWVtb2l6ZS1vbmVcIjtcblxudHlwZSBEYXRhID0gUGljazxJRmllbGRTdGF0ZSwgXCJ2YWx1ZVwiIHwgXCJhbGxvd0VtcHR5XCI+O1xuXG5pbnRlcmZhY2UgSVJlc3VsdCB7XG4gICAga2V5OiBzdHJpbmc7XG4gICAgdmFsaWQ6IGJvb2xlYW47XG4gICAgdGV4dDogc3RyaW5nO1xufVxuXG5pbnRlcmZhY2UgSVJ1bGU8VCwgRCA9IHVuZGVmaW5lZD4ge1xuICAgIGtleTogc3RyaW5nO1xuICAgIGZpbmFsPzogYm9vbGVhbjtcbiAgICBza2lwPyh0aGlzOiBULCBkYXRhOiBEYXRhLCBkZXJpdmVkRGF0YTogRCk6IGJvb2xlYW47XG4gICAgdGVzdCh0aGlzOiBULCBkYXRhOiBEYXRhLCBkZXJpdmVkRGF0YTogRCk6IGJvb2xlYW4gfCBQcm9taXNlPGJvb2xlYW4+O1xuICAgIHZhbGlkPyh0aGlzOiBULCBkZXJpdmVkRGF0YTogRCk6IHN0cmluZyB8IG51bGw7XG4gICAgaW52YWxpZD8odGhpczogVCwgZGVyaXZlZERhdGE6IEQpOiBzdHJpbmcgfCBudWxsO1xufVxuXG5pbnRlcmZhY2UgSUFyZ3M8VCwgRCA9IHZvaWQ+IHtcbiAgICBydWxlczogSVJ1bGU8VCwgRD5bXTtcbiAgICBkZXNjcmlwdGlvbj8odGhpczogVCwgZGVyaXZlZERhdGE6IEQsIHJlc3VsdHM6IElSZXN1bHRbXSk6IFJlYWN0Tm9kZTtcbiAgICBoaWRlRGVzY3JpcHRpb25JZlZhbGlkPzogYm9vbGVhbjtcbiAgICBkZXJpdmVEYXRhPyhkYXRhOiBEYXRhKTogUHJvbWlzZTxEPjtcbiAgICBtZW1vaXplPzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJRmllbGRTdGF0ZSB7XG4gICAgdmFsdWU6IHN0cmluZyB8IG51bGw7XG4gICAgZm9jdXNlZDogYm9vbGVhbjtcbiAgICBhbGxvd0VtcHR5PzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJVmFsaWRhdGlvblJlc3VsdCB7XG4gICAgdmFsaWQ/OiBib29sZWFuO1xuICAgIGZlZWRiYWNrPzogUmVhY3QuUmVhY3RDaGlsZDtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgdmFsaWRhdGlvbiBmdW5jdGlvbiBmcm9tIGEgc2V0IG9mIHJ1bGVzIGRlc2NyaWJpbmcgd2hhdCB0byB2YWxpZGF0ZS5cbiAqIEdlbmVyaWMgVCBpcyB0aGUgXCJ0aGlzXCIgdHlwZSBwYXNzZWQgdG8gdGhlIHJ1bGUgbWV0aG9kc1xuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGRlc2NyaXB0aW9uXG4gKiAgICAgRnVuY3Rpb24gdGhhdCByZXR1cm5zIGEgc3RyaW5nIHN1bW1hcnkgb2YgdGhlIGtpbmQgb2YgdmFsdWUgdGhhdCB3aWxsXG4gKiAgICAgbWVldCB0aGUgdmFsaWRhdGlvbiBydWxlcy4gU2hvd24gYXQgdGhlIHRvcCBvZiB0aGUgdmFsaWRhdGlvbiBmZWVkYmFjay5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gaGlkZURlc2NyaXB0aW9uSWZWYWxpZFxuICogICAgIElmIHRydWUsIGRvbid0IHNob3cgdGhlIGRlc2NyaXB0aW9uIGlmIHRoZSB2YWxpZGF0aW9uIHBhc3NlcyB2YWxpZGF0aW9uLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZGVyaXZlRGF0YVxuICogICAgIE9wdGlvbmFsIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyBhIFByb21pc2UgdG8gYW4gb2JqZWN0IG9mIGdlbmVyaWMgdHlwZSBELlxuICogICAgIFRoZSByZXN1bHQgb2YgdGhpcyBQcm9taXNlIGlzIHBhc3NlZCB0byBydWxlIG1ldGhvZHMgYHNraXBgLCBgdGVzdGAsIGB2YWxpZGAsIGFuZCBgaW52YWxpZGAuXG4gKiAgICAgVXNlZnVsIGZvciBkb2luZyBjYWxjdWxhdGlvbnMgcGVyLXZhbHVlIHVwZGF0ZSBvbmNlIHJhdGhlciB0aGFuIGluIGVhY2ggb2YgdGhlIGFib3ZlIHJ1bGUgbWV0aG9kcy5cbiAqIEBwYXJhbSB7T2JqZWN0fSBydWxlc1xuICogICAgIEFuIGFycmF5IG9mIHJ1bGVzIGRlc2NyaWJpbmcgaG93IHRvIGNoZWNrIHRvIGlucHV0IHZhbHVlLiBFYWNoIHJ1bGUgaW4gYW4gb2JqZWN0XG4gKiAgICAgYW5kIG1heSBoYXZlIHRoZSBmb2xsb3dpbmcgcHJvcGVydGllczpcbiAqICAgICAtIGBrZXlgOiBBIHVuaXF1ZSBJRCBmb3IgdGhlIHJ1bGUuIFJlcXVpcmVkLlxuICogICAgIC0gYHNraXBgOiBBIGZ1bmN0aW9uIHVzZWQgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgdGhlIHJ1bGUgc2hvdWxkIGV2ZW4gYmUgZXZhbHVhdGVkLlxuICogICAgIC0gYHRlc3RgOiBBIGZ1bmN0aW9uIHVzZWQgdG8gZGV0ZXJtaW5lIHRoZSBydWxlJ3MgY3VycmVudCB2YWxpZGl0eS4gUmVxdWlyZWQuXG4gKiAgICAgLSBgdmFsaWRgOiBGdW5jdGlvbiByZXR1cm5pbmcgdGV4dCB0byBzaG93IHdoZW4gdGhlIHJ1bGUgaXMgdmFsaWQuIE9ubHkgc2hvd24gaWYgc2V0LlxuICogICAgIC0gYGludmFsaWRgOiBGdW5jdGlvbiByZXR1cm5pbmcgdGV4dCB0byBzaG93IHdoZW4gdGhlIHJ1bGUgaXMgaW52YWxpZC4gT25seSBzaG93biBpZiBzZXQuXG4gKiAgICAgLSBgZmluYWxgOiBBIEJvb2xlYW4gaWYgdHJ1ZSBzdGF0ZXMgdGhhdCB0aGlzIHJ1bGUgd2lsbCBvbmx5IGJlIGNvbnNpZGVyZWQgaWYgYWxsIHJ1bGVzIGJlZm9yZSBpdCByZXR1cm5lZCB2YWxpZC5cbiAqIEBwYXJhbSB7Ym9vbGVhbj99IG1lbW9pemVcbiAqICAgICBJZiB0cnVlLCB3aWxsIHVzZSBtZW1vaXphdGlvbiB0byBhdm9pZCBjYWxsaW5nIGRlcml2ZURhdGEgJiBydWxlcyB1bmxlc3MgdGhlIHZhbHVlIG9yIGFsbG93RW1wdHkgY2hhbmdlLlxuICogICAgIEJlIGNhcmVmdWwgdG8gbm90IHVzZSB0aGlzIGlmIHlvdXIgdmFsaWRhdGlvbiBpcyBub3QgcHVyZSBhbmQgZGVwZW5kcyBvbiBvdGhlciBmaWVsZHMsIHN1Y2ggYXMgXCJyZXBlYXQgcGFzc3dvcmRcIi5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn1cbiAqICAgICBBIHZhbGlkYXRpb24gZnVuY3Rpb24gdGhhdCB0YWtlcyBpbiB0aGUgY3VycmVudCBpbnB1dCB2YWx1ZSBhbmQgcmV0dXJuc1xuICogICAgIHRoZSBvdmVyYWxsIHZhbGlkaXR5IGFuZCBhIGZlZWRiYWNrIFVJIHRoYXQgY2FuIGJlIHJlbmRlcmVkIGZvciBtb3JlIGRldGFpbC5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gd2l0aFZhbGlkYXRpb248VCA9IHZvaWQsIEQgPSB2b2lkPih7XG4gICAgZGVzY3JpcHRpb24sXG4gICAgaGlkZURlc2NyaXB0aW9uSWZWYWxpZCxcbiAgICBkZXJpdmVEYXRhLFxuICAgIHJ1bGVzLFxuICAgIG1lbW9pemUsXG59OiBJQXJnczxULCBEPik6IChmaWVsZFN0YXRlOiBJRmllbGRTdGF0ZSkgPT4gUHJvbWlzZTxJVmFsaWRhdGlvblJlc3VsdD4ge1xuICAgIGxldCBjaGVja1J1bGVzID0gYXN5bmMgZnVuY3Rpb24gKFxuICAgICAgICB0aGlzOiBULFxuICAgICAgICBkYXRhOiBEYXRhLFxuICAgICAgICBkZXJpdmVkRGF0YTogRCxcbiAgICApOiBQcm9taXNlPFt2YWxpZDogYm9vbGVhbiwgcmVzdWx0czogSVJlc3VsdFtdXT4ge1xuICAgICAgICBjb25zdCByZXN1bHRzOiBJUmVzdWx0W10gPSBbXTtcbiAgICAgICAgbGV0IHZhbGlkID0gdHJ1ZTtcbiAgICAgICAgZm9yIChjb25zdCBydWxlIG9mIHJ1bGVzKSB7XG4gICAgICAgICAgICBpZiAoIXJ1bGUua2V5IHx8ICFydWxlLnRlc3QpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKCF2YWxpZCAmJiBydWxlLmZpbmFsKSB7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChydWxlLnNraXA/LmNhbGwodGhpcywgZGF0YSwgZGVyaXZlZERhdGEpKSB7XG4gICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFdlJ3JlIHNldHRpbmcgYHRoaXNgIHRvIHdoaWNoZXZlciBjb21wb25lbnQgaG9sZHMgdGhlIHZhbGlkYXRpb25cbiAgICAgICAgICAgIC8vIGZ1bmN0aW9uLiBUaGF0IGFsbG93cyBydWxlcyB0byBhY2Nlc3MgdGhlIHN0YXRlIG9mIHRoZSBjb21wb25lbnQuXG4gICAgICAgICAgICBjb25zdCBydWxlVmFsaWQ6IGJvb2xlYW4gPSBhd2FpdCBydWxlLnRlc3QuY2FsbCh0aGlzLCBkYXRhLCBkZXJpdmVkRGF0YSk7XG4gICAgICAgICAgICB2YWxpZCA9IHZhbGlkICYmIHJ1bGVWYWxpZDtcbiAgICAgICAgICAgIGlmIChydWxlVmFsaWQgJiYgcnVsZS52YWxpZCkge1xuICAgICAgICAgICAgICAgIC8vIElmIHRoZSBydWxlJ3MgcmVzdWx0IGlzIHZhbGlkIGFuZCBoYXMgdGV4dCB0byBzaG93IGZvclxuICAgICAgICAgICAgICAgIC8vIHRoZSB2YWxpZCBzdGF0ZSwgc2hvdyBpdC5cbiAgICAgICAgICAgICAgICBjb25zdCB0ZXh0ID0gcnVsZS52YWxpZC5jYWxsKHRoaXMsIGRlcml2ZWREYXRhKTtcbiAgICAgICAgICAgICAgICBpZiAoIXRleHQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJlc3VsdHMucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgIGtleTogcnVsZS5rZXksXG4gICAgICAgICAgICAgICAgICAgIHZhbGlkOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICB0ZXh0LFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIGlmICghcnVsZVZhbGlkICYmIHJ1bGUuaW52YWxpZCkge1xuICAgICAgICAgICAgICAgIC8vIElmIHRoZSBydWxlJ3MgcmVzdWx0IGlzIGludmFsaWQgYW5kIGhhcyB0ZXh0IHRvIHNob3cgZm9yXG4gICAgICAgICAgICAgICAgLy8gdGhlIGludmFsaWQgc3RhdGUsIHNob3cgaXQuXG4gICAgICAgICAgICAgICAgY29uc3QgdGV4dCA9IHJ1bGUuaW52YWxpZC5jYWxsKHRoaXMsIGRlcml2ZWREYXRhKTtcbiAgICAgICAgICAgICAgICBpZiAoIXRleHQpIHtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJlc3VsdHMucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgIGtleTogcnVsZS5rZXksXG4gICAgICAgICAgICAgICAgICAgIHZhbGlkOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgdGV4dCxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBbdmFsaWQsIHJlc3VsdHNdO1xuICAgIH07XG5cbiAgICAvLyBXZSBoYXZlIHRvIG1lbW9pemUgaXQgaW4gY2h1bmtzIGFzIGBmb2N1c2VkYCBjYW4gY2hhbmdlIGZyZXF1ZW50bHksIGJ1dCBpdCBpc24ndCBwYXNzZWQgdG8gdGhlc2UgbWV0aG9kc1xuICAgIGlmIChtZW1vaXplKSB7XG4gICAgICAgIGlmIChkZXJpdmVEYXRhKSBkZXJpdmVEYXRhID0gbWVtb2l6ZU9uZShkZXJpdmVEYXRhLCBpc0RhdGFFcXVhbCk7XG4gICAgICAgIGNoZWNrUnVsZXMgPSBtZW1vaXplT25lKGNoZWNrUnVsZXMsIGlzRGVyaXZlZERhdGFFcXVhbCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGFzeW5jIGZ1bmN0aW9uIG9uVmFsaWRhdGUoXG4gICAgICAgIHRoaXM6IFQsXG4gICAgICAgIHsgdmFsdWUsIGZvY3VzZWQsIGFsbG93RW1wdHkgPSB0cnVlIH06IElGaWVsZFN0YXRlLFxuICAgICk6IFByb21pc2U8SVZhbGlkYXRpb25SZXN1bHQ+IHtcbiAgICAgICAgaWYgKCF2YWx1ZSAmJiBhbGxvd0VtcHR5KSB7XG4gICAgICAgICAgICByZXR1cm4ge307XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBkYXRhID0geyB2YWx1ZSwgYWxsb3dFbXB0eSB9O1xuICAgICAgICAvLyBXZSBrbm93IHRoYXQgaWYgZGVyaXZlRGF0YSBpcyBzZXQgdGhlbiBEIHdpbGwgbm90IGJlIHVuZGVmaW5lZFxuICAgICAgICBjb25zdCBkZXJpdmVkRGF0YSA9IChhd2FpdCBkZXJpdmVEYXRhPy5jYWxsKHRoaXMsIGRhdGEpKSBhcyBEO1xuICAgICAgICBjb25zdCBbdmFsaWQsIHJlc3VsdHNdID0gYXdhaXQgY2hlY2tSdWxlcy5jYWxsKHRoaXMsIGRhdGEsIGRlcml2ZWREYXRhKTtcblxuICAgICAgICAvLyBIaWRlIGZlZWRiYWNrIHdoZW4gbm90IGZvY3VzZWRcbiAgICAgICAgaWYgKCFmb2N1c2VkKSB7XG4gICAgICAgICAgICByZXR1cm4geyB2YWxpZCB9O1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGRldGFpbHM6IFJlYWN0Tm9kZSB8IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKHJlc3VsdHMgJiYgcmVzdWx0cy5sZW5ndGgpIHtcbiAgICAgICAgICAgIGRldGFpbHMgPSAoXG4gICAgICAgICAgICAgICAgPHVsIGNsYXNzTmFtZT1cIm14X1ZhbGlkYXRpb25fZGV0YWlsc1wiPlxuICAgICAgICAgICAgICAgICAgICB7cmVzdWx0cy5tYXAoKHJlc3VsdCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2xhc3NlcyA9IGNsYXNzTmFtZXMoe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG14X1ZhbGlkYXRpb25fZGV0YWlsOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG14X1ZhbGlkYXRpb25fdmFsaWQ6IHJlc3VsdC52YWxpZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBteF9WYWxpZGF0aW9uX2ludmFsaWQ6ICFyZXN1bHQudmFsaWQsXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxpIGtleT17cmVzdWx0LmtleX0gY2xhc3NOYW1lPXtjbGFzc2VzfT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3Jlc3VsdC50ZXh0fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGk+XG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICB9KX1cbiAgICAgICAgICAgICAgICA8L3VsPlxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBzdW1tYXJ5OiBSZWFjdE5vZGUgfCB1bmRlZmluZWQ7XG4gICAgICAgIGlmIChkZXNjcmlwdGlvbiAmJiAoZGV0YWlscyB8fCAhaGlkZURlc2NyaXB0aW9uSWZWYWxpZCkpIHtcbiAgICAgICAgICAgIC8vIFdlJ3JlIHNldHRpbmcgYHRoaXNgIHRvIHdoaWNoZXZlciBjb21wb25lbnQgaG9sZHMgdGhlIHZhbGlkYXRpb25cbiAgICAgICAgICAgIC8vIGZ1bmN0aW9uLiBUaGF0IGFsbG93cyBydWxlcyB0byBhY2Nlc3MgdGhlIHN0YXRlIG9mIHRoZSBjb21wb25lbnQuXG4gICAgICAgICAgICBjb25zdCBjb250ZW50ID0gZGVzY3JpcHRpb24uY2FsbCh0aGlzLCBkZXJpdmVkRGF0YSwgcmVzdWx0cyk7XG4gICAgICAgICAgICBzdW1tYXJ5ID0gY29udGVudCA/IDxkaXYgY2xhc3NOYW1lPVwibXhfVmFsaWRhdGlvbl9kZXNjcmlwdGlvblwiPntjb250ZW50fTwvZGl2PiA6IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBmZWVkYmFjazogUmVhY3RDaGlsZCB8IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKHN1bW1hcnkgfHwgZGV0YWlscykge1xuICAgICAgICAgICAgZmVlZGJhY2sgPSAoXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJteF9WYWxpZGF0aW9uXCI+XG4gICAgICAgICAgICAgICAgICAgIHtzdW1tYXJ5fVxuICAgICAgICAgICAgICAgICAgICB7ZGV0YWlsc31cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdmFsaWQsXG4gICAgICAgICAgICBmZWVkYmFjayxcbiAgICAgICAgfTtcbiAgICB9O1xufVxuXG5mdW5jdGlvbiBpc0RhdGFFcXVhbChbYV06IFtEYXRhXSwgW2JdOiBbRGF0YV0pOiBib29sZWFuIHtcbiAgICByZXR1cm4gYS52YWx1ZSA9PT0gYi52YWx1ZSAmJiBhLmFsbG93RW1wdHkgPT09IGIuYWxsb3dFbXB0eTtcbn1cblxuZnVuY3Rpb24gaXNEZXJpdmVkRGF0YUVxdWFsKFthMSwgYTJdOiBbRGF0YSwgYW55XSwgW2IxLCBiMl06IFtEYXRhLCBhbnldKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGEyID09PSBiMiAmJiBpc0RhdGFFcXVhbChbYTFdLCBbYjFdKTtcbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQVNBLElBQUFBLE1BQUEsR0FBQUMsc0JBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFDLFdBQUEsR0FBQUYsc0JBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFFLFdBQUEsR0FBQUgsc0JBQUEsQ0FBQUMsT0FBQTtBQVhBO0FB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