UNPKG

matrix-react-sdk

Version:
135 lines (130 loc) 19.7 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _lodash = require("lodash"); var _utils = require("matrix-js-sdk/src/utils"); function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } /* Copyright 2024 New Vector Ltd. Copyright 2018 Michael Telatynski <7t3chguy@gmail.com> Copyright 2018 New Vector Ltd Copyright 2017 Aviral Dasgupta SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only Please see LICENSE files in the repository root for full details. */ /** * Simple search matcher that matches any results with the query string anywhere * in the search string. Returns matches in the order the query string appears * in the search key, earliest first, then in the order the search key appears * in the provided array of keys, then in the order the items appeared in the * source array. * * @param {Object[]} objects Initial list of objects. Equivalent to calling * setObjects() after construction * @param {Object} options Options object * @param {string[]} options.keys List of keys to use as indexes on the objects * @param {function[]} options.funcs List of functions that when called with the * object as an arg will return a string to use as an index */ class QueryMatcher { constructor(objects, options = { keys: [] }) { (0, _defineProperty2.default)(this, "_options", void 0); (0, _defineProperty2.default)(this, "_items", new Map()); this._options = options; this.setObjects(objects); // By default, we remove any non-alphanumeric characters ([^A-Za-z0-9_]) from the // query and the value being queried before matching if (this._options.shouldMatchWordsOnly === undefined) { this._options.shouldMatchWordsOnly = true; } } setObjects(objects) { this._items = new Map(); for (const object of objects) { // Need to use unsafe coerce here because the objects can have any // type for their values. We assume that those values who's keys have // been specified will be string. Also, we cannot infer all the // types of the keys of the objects at compile. const keyValues = (0, _lodash.at)(object, this._options.keys); if (this._options.funcs) { for (const f of this._options.funcs) { const v = f(object); if (Array.isArray(v)) { keyValues.push(...v); } else { keyValues.push(v); } } } for (const [index, keyValue] of Object.entries(keyValues)) { if (!keyValue) continue; // skip falsy keyValues const key = this.processQuery(keyValue); if (!this._items.has(key)) { this._items.set(key, []); } this._items.get(key).push({ keyWeight: Number(index), object }); } } } match(query, limit = -1) { query = this.processQuery(query); if (this._options.shouldMatchWordsOnly) { query = query.replace(/[^\w]/g, ""); } if (query.length === 0) { return []; } const matches = []; // Iterate through the map & check each key. // ES6 Map iteration order is defined to be insertion order, so results // here will come out in the order they were put in. for (const [key, candidates] of this._items.entries()) { let resultKey = key; if (this._options.shouldMatchWordsOnly) { resultKey = resultKey.replace(/[^\w]/g, ""); } const index = resultKey.indexOf(query); if (index !== -1) { matches.push(...candidates.map(candidate => _objectSpread({ index }, candidate))); } } // Sort matches by where the query appeared in the search key, then by // where the matched key appeared in the provided array of keys. matches.sort((a, b) => { if (a.index < b.index) { return -1; } else if (a.index === b.index) { if (a.keyWeight < b.keyWeight) { return -1; } else if (a.keyWeight === b.keyWeight) { return 0; } } return 1; }); // Now map the keys to the result objects. Also remove any duplicates. const dedupped = (0, _lodash.uniq)(matches.map(match => match.object)); const maxLength = limit === -1 ? dedupped.length : limit; return dedupped.slice(0, maxLength); } processQuery(query) { if (this._options.fuzzy !== false) { // lower case both the input and the output for consistency return (0, _utils.removeHiddenChars)(query.toLowerCase()).toLowerCase(); } return query.toLowerCase(); } } exports.default = QueryMatcher; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfbG9kYXNoIiwicmVxdWlyZSIsIl91dGlscyIsIm93bktleXMiLCJlIiwiciIsInQiLCJPYmplY3QiLCJrZXlzIiwiZ2V0T3duUHJvcGVydHlTeW1ib2xzIiwibyIsImZpbHRlciIsImdldE93blByb3BlcnR5RGVzY3JpcHRvciIsImVudW1lcmFibGUiLCJwdXNoIiwiYXBwbHkiLCJfb2JqZWN0U3ByZWFkIiwiYXJndW1lbnRzIiwibGVuZ3RoIiwiZm9yRWFjaCIsIl9kZWZpbmVQcm9wZXJ0eTIiLCJkZWZhdWx0IiwiZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycyIsImRlZmluZVByb3BlcnRpZXMiLCJkZWZpbmVQcm9wZXJ0eSIsIlF1ZXJ5TWF0Y2hlciIsImNvbnN0cnVjdG9yIiwib2JqZWN0cyIsIm9wdGlvbnMiLCJNYXAiLCJfb3B0aW9ucyIsInNldE9iamVjdHMiLCJzaG91bGRNYXRjaFdvcmRzT25seSIsInVuZGVmaW5lZCIsIl9pdGVtcyIsIm9iamVjdCIsImtleVZhbHVlcyIsImF0IiwiZnVuY3MiLCJmIiwidiIsIkFycmF5IiwiaXNBcnJheSIsImluZGV4Iiwia2V5VmFsdWUiLCJlbnRyaWVzIiwia2V5IiwicHJvY2Vzc1F1ZXJ5IiwiaGFzIiwic2V0IiwiZ2V0Iiwia2V5V2VpZ2h0IiwiTnVtYmVyIiwibWF0Y2giLCJxdWVyeSIsImxpbWl0IiwicmVwbGFjZSIsIm1hdGNoZXMiLCJjYW5kaWRhdGVzIiwicmVzdWx0S2V5IiwiaW5kZXhPZiIsIm1hcCIsImNhbmRpZGF0ZSIsInNvcnQiLCJhIiwiYiIsImRlZHVwcGVkIiwidW5pcSIsIm1heExlbmd0aCIsInNsaWNlIiwiZnV6enkiLCJyZW1vdmVIaWRkZW5DaGFycyIsInRvTG93ZXJDYXNlIiwiZXhwb3J0cyJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hdXRvY29tcGxldGUvUXVlcnlNYXRjaGVyLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qXG5Db3B5cmlnaHQgMjAyNCBOZXcgVmVjdG9yIEx0ZC5cbkNvcHlyaWdodCAyMDE4IE1pY2hhZWwgVGVsYXR5bnNraSA8N3QzY2hndXlAZ21haWwuY29tPlxuQ29weXJpZ2h0IDIwMTggTmV3IFZlY3RvciBMdGRcbkNvcHlyaWdodCAyMDE3IEF2aXJhbCBEYXNndXB0YVxuXG5TUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQUdQTC0zLjAtb25seSBPUiBHUEwtMy4wLW9ubHlcblBsZWFzZSBzZWUgTElDRU5TRSBmaWxlcyBpbiB0aGUgcmVwb3NpdG9yeSByb290IGZvciBmdWxsIGRldGFpbHMuXG4qL1xuXG5pbXBvcnQgeyBhdCwgdW5pcSB9IGZyb20gXCJsb2Rhc2hcIjtcbmltcG9ydCB7IHJlbW92ZUhpZGRlbkNoYXJzIH0gZnJvbSBcIm1hdHJpeC1qcy1zZGsvc3JjL3V0aWxzXCI7XG5cbmltcG9ydCB7IFRpbWVsaW5lUmVuZGVyaW5nVHlwZSB9IGZyb20gXCIuLi9jb250ZXh0cy9Sb29tQ29udGV4dFwiO1xuaW1wb3J0IHsgTGVhdmVzIH0gZnJvbSBcIi4uL0B0eXBlcy9jb21tb25cIjtcblxuaW50ZXJmYWNlIElPcHRpb25zPFQgZXh0ZW5kcyB7fT4ge1xuICAgIGtleXM6IEFycmF5PExlYXZlczxUPj47XG4gICAgZnVuY3M/OiBBcnJheTwobzogVCkgPT4gc3RyaW5nIHwgc3RyaW5nW10+O1xuICAgIHNob3VsZE1hdGNoV29yZHNPbmx5PzogYm9vbGVhbjtcbiAgICAvLyB3aGV0aGVyIHRvIGFwcGx5IHVuaG9tb2dseXBoIGFuZCBzdHJpcCBkaWFjcml0aWNzIHRvIGZ1enogdXAgdGhlIHNlYXJjaC4gRGVmYXVsdHMgdG8gdHJ1ZVxuICAgIGZ1enp5PzogYm9vbGVhbjtcbiAgICBjb250ZXh0PzogVGltZWxpbmVSZW5kZXJpbmdUeXBlO1xufVxuXG4vKipcbiAqIFNpbXBsZSBzZWFyY2ggbWF0Y2hlciB0aGF0IG1hdGNoZXMgYW55IHJlc3VsdHMgd2l0aCB0aGUgcXVlcnkgc3RyaW5nIGFueXdoZXJlXG4gKiBpbiB0aGUgc2VhcmNoIHN0cmluZy4gUmV0dXJucyBtYXRjaGVzIGluIHRoZSBvcmRlciB0aGUgcXVlcnkgc3RyaW5nIGFwcGVhcnNcbiAqIGluIHRoZSBzZWFyY2gga2V5LCBlYXJsaWVzdCBmaXJzdCwgdGhlbiBpbiB0aGUgb3JkZXIgdGhlIHNlYXJjaCBrZXkgYXBwZWFyc1xuICogaW4gdGhlIHByb3ZpZGVkIGFycmF5IG9mIGtleXMsIHRoZW4gaW4gdGhlIG9yZGVyIHRoZSBpdGVtcyBhcHBlYXJlZCBpbiB0aGVcbiAqIHNvdXJjZSBhcnJheS5cbiAqXG4gKiBAcGFyYW0ge09iamVjdFtdfSBvYmplY3RzIEluaXRpYWwgbGlzdCBvZiBvYmplY3RzLiBFcXVpdmFsZW50IHRvIGNhbGxpbmdcbiAqICAgICBzZXRPYmplY3RzKCkgYWZ0ZXIgY29uc3RydWN0aW9uXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyBPcHRpb25zIG9iamVjdFxuICogQHBhcmFtIHtzdHJpbmdbXX0gb3B0aW9ucy5rZXlzIExpc3Qgb2Yga2V5cyB0byB1c2UgYXMgaW5kZXhlcyBvbiB0aGUgb2JqZWN0c1xuICogQHBhcmFtIHtmdW5jdGlvbltdfSBvcHRpb25zLmZ1bmNzIExpc3Qgb2YgZnVuY3Rpb25zIHRoYXQgd2hlbiBjYWxsZWQgd2l0aCB0aGVcbiAqICAgICBvYmplY3QgYXMgYW4gYXJnIHdpbGwgcmV0dXJuIGEgc3RyaW5nIHRvIHVzZSBhcyBhbiBpbmRleFxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBRdWVyeU1hdGNoZXI8VCBleHRlbmRzIHt9PiB7XG4gICAgcHJpdmF0ZSBfb3B0aW9uczogSU9wdGlvbnM8VD47XG4gICAgcHJpdmF0ZSBfaXRlbXMgPSBuZXcgTWFwPHN0cmluZywgeyBvYmplY3Q6IFQ7IGtleVdlaWdodDogbnVtYmVyIH1bXT4oKTtcblxuICAgIHB1YmxpYyBjb25zdHJ1Y3RvcihvYmplY3RzOiBUW10sIG9wdGlvbnM6IElPcHRpb25zPFQ+ID0geyBrZXlzOiBbXSB9KSB7XG4gICAgICAgIHRoaXMuX29wdGlvbnMgPSBvcHRpb25zO1xuXG4gICAgICAgIHRoaXMuc2V0T2JqZWN0cyhvYmplY3RzKTtcblxuICAgICAgICAvLyBCeSBkZWZhdWx0LCB3ZSByZW1vdmUgYW55IG5vbi1hbHBoYW51bWVyaWMgY2hhcmFjdGVycyAoW15BLVphLXowLTlfXSkgZnJvbSB0aGVcbiAgICAgICAgLy8gcXVlcnkgYW5kIHRoZSB2YWx1ZSBiZWluZyBxdWVyaWVkIGJlZm9yZSBtYXRjaGluZ1xuICAgICAgICBpZiAodGhpcy5fb3B0aW9ucy5zaG91bGRNYXRjaFdvcmRzT25seSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aGlzLl9vcHRpb25zLnNob3VsZE1hdGNoV29yZHNPbmx5ID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBzZXRPYmplY3RzKG9iamVjdHM6IFRbXSk6IHZvaWQge1xuICAgICAgICB0aGlzLl9pdGVtcyA9IG5ldyBNYXAoKTtcblxuICAgICAgICBmb3IgKGNvbnN0IG9iamVjdCBvZiBvYmplY3RzKSB7XG4gICAgICAgICAgICAvLyBOZWVkIHRvIHVzZSB1bnNhZmUgY29lcmNlIGhlcmUgYmVjYXVzZSB0aGUgb2JqZWN0cyBjYW4gaGF2ZSBhbnlcbiAgICAgICAgICAgIC8vIHR5cGUgZm9yIHRoZWlyIHZhbHVlcy4gV2UgYXNzdW1lIHRoYXQgdGhvc2UgdmFsdWVzIHdobydzIGtleXMgaGF2ZVxuICAgICAgICAgICAgLy8gYmVlbiBzcGVjaWZpZWQgd2lsbCBiZSBzdHJpbmcuIEFsc28sIHdlIGNhbm5vdCBpbmZlciBhbGwgdGhlXG4gICAgICAgICAgICAvLyB0eXBlcyBvZiB0aGUga2V5cyBvZiB0aGUgb2JqZWN0cyBhdCBjb21waWxlLlxuICAgICAgICAgICAgY29uc3Qga2V5VmFsdWVzID0gYXQ8c3RyaW5nPig8YW55Pm9iamVjdCwgdGhpcy5fb3B0aW9ucy5rZXlzKTtcblxuICAgICAgICAgICAgaWYgKHRoaXMuX29wdGlvbnMuZnVuY3MpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGYgb2YgdGhpcy5fb3B0aW9ucy5mdW5jcykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB2ID0gZihvYmplY3QpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh2KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAga2V5VmFsdWVzLnB1c2goLi4udik7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBrZXlWYWx1ZXMucHVzaCh2KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZm9yIChjb25zdCBbaW5kZXgsIGtleVZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhrZXlWYWx1ZXMpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFrZXlWYWx1ZSkgY29udGludWU7IC8vIHNraXAgZmFsc3kga2V5VmFsdWVzXG4gICAgICAgICAgICAgICAgY29uc3Qga2V5ID0gdGhpcy5wcm9jZXNzUXVlcnkoa2V5VmFsdWUpO1xuICAgICAgICAgICAgICAgIGlmICghdGhpcy5faXRlbXMuaGFzKGtleSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5faXRlbXMuc2V0KGtleSwgW10pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLl9pdGVtcy5nZXQoa2V5KSEucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgIGtleVdlaWdodDogTnVtYmVyKGluZGV4KSxcbiAgICAgICAgICAgICAgICAgICAgb2JqZWN0LFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIG1hdGNoKHF1ZXJ5OiBzdHJpbmcsIGxpbWl0ID0gLTEpOiBUW10ge1xuICAgICAgICBxdWVyeSA9IHRoaXMucHJvY2Vzc1F1ZXJ5KHF1ZXJ5KTtcbiAgICAgICAgaWYgKHRoaXMuX29wdGlvbnMuc2hvdWxkTWF0Y2hXb3Jkc09ubHkpIHtcbiAgICAgICAgICAgIHF1ZXJ5ID0gcXVlcnkucmVwbGFjZSgvW15cXHddL2csIFwiXCIpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChxdWVyeS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBtYXRjaGVzOiB7XG4gICAgICAgICAgICBpbmRleDogbnVtYmVyO1xuICAgICAgICAgICAgb2JqZWN0OiBUO1xuICAgICAgICAgICAga2V5V2VpZ2h0OiBudW1iZXI7XG4gICAgICAgIH1bXSA9IFtdO1xuICAgICAgICAvLyBJdGVyYXRlIHRocm91Z2ggdGhlIG1hcCAmIGNoZWNrIGVhY2gga2V5LlxuICAgICAgICAvLyBFUzYgTWFwIGl0ZXJhdGlvbiBvcmRlciBpcyBkZWZpbmVkIHRvIGJlIGluc2VydGlvbiBvcmRlciwgc28gcmVzdWx0c1xuICAgICAgICAvLyBoZXJlIHdpbGwgY29tZSBvdXQgaW4gdGhlIG9yZGVyIHRoZXkgd2VyZSBwdXQgaW4uXG4gICAgICAgIGZvciAoY29uc3QgW2tleSwgY2FuZGlkYXRlc10gb2YgdGhpcy5faXRlbXMuZW50cmllcygpKSB7XG4gICAgICAgICAgICBsZXQgcmVzdWx0S2V5ID0ga2V5O1xuICAgICAgICAgICAgaWYgKHRoaXMuX29wdGlvbnMuc2hvdWxkTWF0Y2hXb3Jkc09ubHkpIHtcbiAgICAgICAgICAgICAgICByZXN1bHRLZXkgPSByZXN1bHRLZXkucmVwbGFjZSgvW15cXHddL2csIFwiXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgaW5kZXggPSByZXN1bHRLZXkuaW5kZXhPZihxdWVyeSk7XG4gICAgICAgICAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgbWF0Y2hlcy5wdXNoKC4uLmNhbmRpZGF0ZXMubWFwKChjYW5kaWRhdGUpID0+ICh7IGluZGV4LCAuLi5jYW5kaWRhdGUgfSkpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNvcnQgbWF0Y2hlcyBieSB3aGVyZSB0aGUgcXVlcnkgYXBwZWFyZWQgaW4gdGhlIHNlYXJjaCBrZXksIHRoZW4gYnlcbiAgICAgICAgLy8gd2hlcmUgdGhlIG1hdGNoZWQga2V5IGFwcGVhcmVkIGluIHRoZSBwcm92aWRlZCBhcnJheSBvZiBrZXlzLlxuICAgICAgICBtYXRjaGVzLnNvcnQoKGEsIGIpID0+IHtcbiAgICAgICAgICAgIGlmIChhLmluZGV4IDwgYi5pbmRleCkge1xuICAgICAgICAgICAgICAgIHJldHVybiAtMTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoYS5pbmRleCA9PT0gYi5pbmRleCkge1xuICAgICAgICAgICAgICAgIGlmIChhLmtleVdlaWdodCA8IGIua2V5V2VpZ2h0KSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGEua2V5V2VpZ2h0ID09PSBiLmtleVdlaWdodCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBOb3cgbWFwIHRoZSBrZXlzIHRvIHRoZSByZXN1bHQgb2JqZWN0cy4gQWxzbyByZW1vdmUgYW55IGR1cGxpY2F0ZXMuXG4gICAgICAgIGNvbnN0IGRlZHVwcGVkID0gdW5pcShtYXRjaGVzLm1hcCgobWF0Y2gpID0+IG1hdGNoLm9iamVjdCkpO1xuICAgICAgICBjb25zdCBtYXhMZW5ndGggPSBsaW1pdCA9PT0gLTEgPyBkZWR1cHBlZC5sZW5ndGggOiBsaW1pdDtcblxuICAgICAgICByZXR1cm4gZGVkdXBwZWQuc2xpY2UoMCwgbWF4TGVuZ3RoKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHByb2Nlc3NRdWVyeShxdWVyeTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICAgICAgaWYgKHRoaXMuX29wdGlvbnMuZnV6enkgIT09IGZhbHNlKSB7XG4gICAgICAgICAgICAvLyBsb3dlciBjYXNlIGJvdGggdGhlIGlucHV0IGFuZCB0aGUgb3V0cHV0IGZvciBjb25zaXN0ZW5jeVxuICAgICAgICAgICAgcmV0dXJuIHJlbW92ZUhpZGRlbkNoYXJzKHF1ZXJ5LnRvTG93ZXJDYXNlKCkpLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHF1ZXJ5LnRvTG93ZXJDYXNlKCk7XG4gICAgfVxufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7OztBQVVBLElBQUFBLE9BQUEsR0FBQUMsT0FBQTtBQUNBLElBQUFDLE1BQUEsR0FBQUQsT0FBQTtBQUE0RCxTQUFBRSxRQUFBQyxDQUFBLEVBQUFDLENBQUEsUUFBQUMsQ0FBQSxHQUFBQyxNQUFBLENBQUFDLElBQUEsQ0FBQUosQ0FBQSxPQUFBRyxNQUFBLENBQUFFLHFCQUFBLFFBQUFDLENBQUEsR0FBQUgsTUFBQSxDQUFBRSxxQkFBQSxDQUFBTCxDQUFBLEdBQUFDLENBQUEsS0FBQUssQ0FBQSxHQUFBQSxDQUFBLENBQUFDLE1BQUEsV0FBQU4sQ0FBQSxXQUFBRSxNQUFBLENBQUFLLHdCQUFBLENBQUFSLENBQUEsRUFBQUMsQ0FBQSxFQUFBUSxVQUFBLE9BQUFQLENBQUEsQ0FBQVEsSUFBQSxDQUFBQyxLQUFBLENBQUFULENBQUEsRUFBQUksQ0FBQSxZQUFBSixDQUFBO0FBQUEsU0FBQVUsY0FBQVosQ0FBQSxhQUFBQyxDQUFBLE1BQUFBLENBQUEsR0FBQVksU0FBQSxDQUFBQyxNQUFBLEVBQUFiLENBQUEsVUFBQUMsQ0FBQSxXQUFBVyxTQUFBLENBQUFaLENBQUEsSUFBQVksU0FBQSxDQUFBWixDQUFBLFFBQUFBLENBQUEsT0FBQUYsT0FBQSxDQUFBSSxNQUFBLENBQUFELENBQUEsT0FBQWEsT0FBQSxXQUFBZCxDQUFBLFFBQUFlLGdCQUFBLENBQUFDLE9BQUEsRUFBQWpCLENBQUEsRUFBQUMs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