UNPKG

tc-ui-toolkit

Version:

React components used to develop tools for the desktop app translationCore

333 lines (270 loc) 33.9 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.bibleRefSort = bibleRefSort; exports.generateMenuData = generateMenuData; exports.generateMenuItem = generateMenuItem; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _ = require(".."); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } /** * zero fill string to make minimum length * @param text * @param len * @returns {*} */ function zeroAdjustLength(text, len) { var parts = text.split('-'); text = parts[0]; while (text.length < len) { text = '0' + text; } parts[0] = text; return parts.join('-'); } function splitChapterVerse(ref_) { var _ref_$split = ref_.split(':'), _ref_$split2 = (0, _slicedToArray2["default"])(_ref_$split, 2), chapter = _ref_$split2[0], verse = _ref_$split2[1]; return { chapter: chapter, verse: verse }; } /** * create a reference where chapter and verse is zero filled to be same width * @param ref * @returns {null|string} */ function normalizeRef(ref) { var _splitChapterVerse = splitChapterVerse(ref), chapter = _splitChapterVerse.chapter, verse = _splitChapterVerse.verse; if (chapter && verse) { chapter = zeroAdjustLength(chapter, 3); verse = zeroAdjustLength(verse, 3); return "".concat(chapter, "_").concat(verse); } return null; } function bibleRefSort(a, b) { // sorts by numerical chapter/verse order var akey = normalizeRef(a); var bkey = normalizeRef(b); // eslint-disable-next-line no-nested-ternary return akey < bkey ? -1 : akey > bkey ? 1 : 0; } /** * Helper utility to generate data for the menu organized by group. * @param {[]} index - the group index * @param {object} data - the group data * @param {string} direction - layout direction - default 'ltr' * @param {string} progressKey - the key by which the group progress will be measured * @param {function} [onProcessItem=null] - an optional callback to perform additional processing on a menu item. This is executed before the `progressKey` is evaluated. * @param {[]} menu - returns the nested menu * @param {string} progressKey2 - the secondary key by which the group progress will be measured */ function generateMenuByGroup(data, index, direction, onProcessItem, menu, progressKey, progressKey2) { var dataKeys = Object.keys(data); for (var i = 0, len = index.length; i < len; i++) { var entry = index[i]; if (dataKeys.includes(entry.id)) { // generate menu group var group = data[entry.id]; var gl = group.length; var children = new Array(gl); for (var j = 0; j < gl; j++) { var item = processMenuItem(group[j]); item.direction = direction; children[j] = onProcessItem ? onProcessItem(item) : item; } menu.push({ title: entry.name, progress: calculateProgress(children, progressKey, progressKey2), id: entry.id, children: children }); } } } /** * Helper utility to generate data for the menu organized by reference. * @param {[]} index - the group index * @param {object} data - the group data * @param {string} direction - layout direction - default 'ltr' * @param {string} progressKey - the key by which the group progress will be measured * @param {function} [onProcessItem=null] - an optional callback to perform additional processing on a menu item. This is executed before the `progressKey` is evaluated. * @param {[]} menu - returns the nested menu * @param {string} progressKey2 - the secondary key by which the group progress will be measured */ function generateMenuByRef(data, index, direction, onProcessItem, menu, progressKey, progressKey2) { var refs = {}; var groups = {}; for (var i = 0, len = index.length; i < len; i++) { var entry = index[i]; var id = entry === null || entry === void 0 ? void 0 : entry.id; groups[id] = (entry === null || entry === void 0 ? void 0 : entry.name) || ''; var dataItems = data[id] || []; var _iterator = _createForOfIteratorHelper(dataItems), _step; try { for (_iterator.s(); !(_step = _iterator.n()).done;) { var _item$contextId; var item = _step.value; var ref = item === null || item === void 0 ? void 0 : (_item$contextId = item.contextId) === null || _item$contextId === void 0 ? void 0 : _item$contextId.reference; if (ref) { var refStr = "".concat(ref.chapter, ":").concat(ref.verse); var children = refs[refStr]; if (!children) { children = []; refs[refStr] = children; } var newItem = _objectSpread(_objectSpread({}, item), {}, { organizeByRef: refStr }); children.push(newItem); } } } catch (err) { _iterator.e(err); } finally { _iterator.f(); } } var sortedRefs = Object.keys(refs).sort(bibleRefSort); var _iterator2 = _createForOfIteratorHelper(sortedRefs), _step2; try { for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { var _ref = _step2.value; var _children = refs[_ref]; for (var _i = 0, _len = _children.length; _i < _len; _i++) { var _entry = _children[_i]; var _item = processMenuItem(_entry); _item.direction = direction; _item.groupName = groups[_item.groupId] || _item.groupId; var processed = onProcessItem ? onProcessItem(_item, true) : _item; _children[_i] = processed; } menu.push({ title: _ref, progress: calculateProgress(_children, progressKey, progressKey2), id: _ref, children: _children, organizeByRef: _ref }); } } catch (err) { _iterator2.e(err); } finally { _iterator2.f(); } } /** * Helper utility to generate data for the menu. * @param {[]} index - the group index * @param {object} data - the group data * @param {string} direction - layout direction - default 'ltr' * @param {string} progressKey - the key by which the group progress will be measured * @param {function} [onProcessItem=null] - an optional callback to perform additional processing on a menu item. This is executed before the `progressKey` is evaluated. * @param {string} progressKey2 - the secondary key by which the group progress will be measured * @param {boolean} organizeByRef - optional, if true then group by references * @returns {[]} the menu data */ function generateMenuData(index, data, progressKey) { var direction = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'ltr'; var onProcessItem = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null; var progressKey2 = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : null; var organizeByRef = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : false; var menu = []; if (organizeByRef) { generateMenuByRef(data, index, direction, onProcessItem, menu, progressKey, progressKey2); } else { generateMenuByGroup(data, index, direction, onProcessItem, menu, progressKey, progressKey2); } return menu; } /** * Produces a valid menu item from a context id or a group data entry. * This is useful for pre-processing the active entry. * @param {object} contextId - a context id or group data entry. * @param {string} direction - layout direction - default 'ltr' * @param {function} [onProcessItem=null] - an optional preprocessor * @param {boolean} organizeByRef - optional, if true then group by references * @returns {object} */ function generateMenuItem(contextId) { var direction = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'ltr'; var onProcessItem = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; var organizeByRef = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; // TRICKY: determine if this is a contextId or group data entry. var item; if (contextId.hasOwnProperty('contextId')) { item = contextId; } else { item = { contextId: contextId }; } item.direction = direction; if (organizeByRef) { var _item2, _item2$contextId; var ref = (_item2 = item) === null || _item2 === void 0 ? void 0 : (_item2$contextId = _item2.contextId) === null || _item2$contextId === void 0 ? void 0 : _item2$contextId.reference; if (ref) { var refStr = "".concat(ref.chapter, ":").concat(ref.verse); item.organizeByRef = refStr; } } // perform pre-processing if (typeof onProcessItem === 'function') { return onProcessItem(processMenuItem(item)); } else { return processMenuItem(item); } } /** * Calculates the progress over an array of objects * @param {object[]} data - an array of objects * @param {string} progressKey - the key used to check the completion status of each object * @param {string} progressKey2 - the secondary key used to check the completion status of each object * @returns {number} - returns a number between 0 and 100 inclusive */ function calculateProgress(data, progressKey, progressKey2) { var total = data.length; var completed = 0; for (var i = 0, len = data.length; i < len; i++) { if (data[i][progressKey] || progressKey2 && data[i][progressKey2]) { completed++; } } return completed / total * 100; } /** * Performs some default child generation operations. * For advanced menu item customization you should provide a callback to {@link generateMenuData} * @param {object} data - the menu item data * @returns {object} - the formatted menu item data */ function processMenuItem(data) { // TRICKY: use the context id to pre-populate some fields var _data$contextId = data.contextId, groupId = _data$contextId.groupId, _data$contextId$refer = _data$contextId.reference, bookId = _data$contextId$refer.bookId, chapter = _data$contextId$refer.chapter, verse = _data$contextId$refer.verse; var refStr = (0, _.getReferenceStr)(chapter, verse); var passageTitle = (0, _.getTitleStr)(bookId, refStr, data.direction); return _objectSpread(_objectSpread({}, data), {}, { groupId: groupId, itemId: refStr, title: passageTitle }); } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9Hcm91cGVkTWVudS91dGlscy5qcyJdLCJuYW1lcyI6WyJ6ZXJvQWRqdXN0TGVuZ3RoIiwidGV4dCIsImxlbiIsInBhcnRzIiwic3BsaXQiLCJsZW5ndGgiLCJqb2luIiwic3BsaXRDaGFwdGVyVmVyc2UiLCJyZWZfIiwiY2hhcHRlciIsInZlcnNlIiwibm9ybWFsaXplUmVmIiwicmVmIiwiYmlibGVSZWZTb3J0IiwiYSIsImIiLCJha2V5IiwiYmtleSIsImdlbmVyYXRlTWVudUJ5R3JvdXAiLCJkYXRhIiwiaW5kZXgiLCJkaXJlY3Rpb24iLCJvblByb2Nlc3NJdGVtIiwibWVudSIsInByb2dyZXNzS2V5IiwicHJvZ3Jlc3NLZXkyIiwiZGF0YUtleXMiLCJPYmplY3QiLCJrZXlzIiwiaSIsImVudHJ5IiwiaW5jbHVkZXMiLCJpZCIsImdyb3VwIiwiZ2wiLCJjaGlsZHJlbiIsIkFycmF5IiwiaiIsIml0ZW0iLCJwcm9jZXNzTWVudUl0ZW0iLCJwdXNoIiwidGl0bGUiLCJuYW1lIiwicHJvZ3Jlc3MiLCJjYWxjdWxhdGVQcm9ncmVzcyIsImdlbmVyYXRlTWVudUJ5UmVmIiwicmVmcyIsImdyb3VwcyIsImRhdGFJdGVtcyIsImNvbnRleHRJZCIsInJlZmVyZW5jZSIsInJlZlN0ciIsIm5ld0l0ZW0iLCJvcmdhbml6ZUJ5UmVmIiwic29ydGVkUmVmcyIsInNvcnQiLCJncm91cE5hbWUiLCJncm91cElkIiwicHJvY2Vzc2VkIiwiZ2VuZXJhdGVNZW51RGF0YSIsImdlbmVyYXRlTWVudUl0ZW0iLCJoYXNPd25Qcm9wZXJ0eSIsInRvdGFsIiwiY29tcGxldGVkIiwiYm9va0lkIiwicGFzc2FnZVRpdGxlIiwiaXRlbUlkIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7QUFBQTs7Ozs7Ozs7Ozs7O0FBRUE7Ozs7OztBQU1BLFNBQVNBLGdCQUFULENBQTBCQyxJQUExQixFQUFnQ0MsR0FBaEMsRUFBcUM7QUFDbkMsTUFBSUMsS0FBSyxHQUFHRixJ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SUFBQUEsTUFBTSxFQUFFZixNQUhWO0FBSUVWLElBQUFBLEtBQUssRUFBRXdCO0FBSlQ7QUFNRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGdldFJlZmVyZW5jZVN0ciwgZ2V0VGl0bGVTdHIgfSBmcm9tICcuLic7XG5cbi8qKlxuICogemVybyBmaWxsIHN0cmluZyB0byBtYWtlIG1pbmltdW0gbGVuZ3RoXG4gKiBAcGFyYW0gdGV4dFxuICogQHBhcmFtIGxlblxuICogQHJldHVybnMgeyp9XG4gKi9cbmZ1bmN0aW9uIHplcm9BZGp1c3RMZW5ndGgodGV4dCwgbGVuKSB7XG4gIGxldCBwYXJ0cyA9IHRleHQuc3BsaXQoJy0nKTtcbiAgdGV4dCA9IHBhcnRzWzBdO1xuXG4gIHdoaWxlICh0ZXh0Lmxlbmd0aCA8IGxlbikge1xuICAgIHRleHQgPSAnMCcgKyB0ZXh0O1xuICB9XG4gIHBhcnRzWzBdID0gdGV4dDtcbiAgcmV0dXJuIHBhcnRzLmpvaW4oJy0nKTtcbn1cblxuZnVuY3Rpb24gc3BsaXRDaGFwdGVyVmVyc2UocmVmXykge1xuICBjb25zdCBbY2hhcHRlciwgdmVyc2VdID0gcmVmXy5zcGxpdCgnOicpO1xuICByZXR1cm4geyBjaGFwdGVyLCB2ZXJzZSB9O1xufVxuXG4vKipcbiAqIGNyZWF0ZSBhIHJlZmVyZW5jZSB3aGVyZSBjaGFwdGVyIGFuZCB2ZXJzZSBpcyB6ZXJvIGZpbGxlZCB0byBiZSBzYW1lIHdpZHRoXG4gKiBAcGFyYW0gcmVmXG4gKiBAcmV0dXJucyB7bnVsbHxzdHJpbmd9XG4gKi9cbmZ1bmN0aW9uIG5vcm1hbGl6ZVJlZihyZWYpIHtcbiAgbGV0IHsgY2hhcHRlciwgdmVyc2UgfSA9IHNwbGl0Q2hhcHRlclZlcnNlKHJlZik7XG5cbiAgaWYgKGNoYXB0ZXIgJiYgdmVyc2UpIHtcbiAgICBjaGFwdGVyID0gemVyb0FkanVzdExlbmd0aChjaGFwdGVyLCAzKTtcbiAgICB2ZXJzZSA9IHplcm9BZGp1c3RMZW5ndGgodmVyc2UsIDMpO1xuICAgIHJldHVybiBgJHtjaGFwdGVyfV8ke3ZlcnNlfWA7XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGJpYmxlUmVmU29ydChhLCBiKSB7IC8vIHNvcnRzIGJ5IG51bWVyaWNhbCBjaGFwdGVyL3ZlcnNlIG9yZGVyXG4gIGNvbnN0IGFrZXkgPSBub3JtYWxpemVSZWYoYSk7XG4gIGNvbnN0IGJrZXkgPSBub3JtYWxpemVSZWYoYik7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1uZXN0ZWQtdGVybmFyeVxuICByZXR1cm4gYWtleSA8IGJrZXkgPyAtMSA6IGFrZXkgPiBia2V5ID8gMSA6IDA7XG59XG5cbi8qKlxuICogSGVscGVyIHV0aWxpdHkgdG8gZ2VuZXJhdGUgZGF0YSBmb3IgdGhlIG1lbnUgb3JnYW5pemVkIGJ5IGdyb3VwLlxuICogQHBhcmFtIHtbXX0gaW5kZXggLSB0aGUgZ3JvdXAgaW5kZXhcbiAqIEBwYXJhbSB7b2JqZWN0fSBkYXRhIC0gdGhlIGdyb3VwIGRhdGFcbiAqIEBwYXJhbSB7c3RyaW5nfSBkaXJlY3Rpb24gLSBsYXlvdXQgZGlyZWN0aW9uIC0gZGVmYXVsdCAnbHRyJ1xuICogQHBhcmFtIHtzdHJpbmd9IHByb2dyZXNzS2V5IC0gdGhlIGtleSBieSB3aGljaCB0aGUgZ3JvdXAgcHJvZ3Jlc3Mgd2lsbCBiZSBtZWFzdXJlZFxuICogQHBhcmFtIHtmdW5jdGlvbn0gW29uUHJvY2Vzc0l0ZW09bnVsbF0gLSBhbiBvcHRpb25hbCBjYWxsYmFjayB0byBwZXJmb3JtIGFkZGl0aW9uYWwgcHJvY2Vzc2luZyBvbiBhIG1lbnUgaXRlbS4gVGhpcyBpcyBleGVjdXRlZCBiZWZvcmUgdGhlIGBwcm9ncmVzc0tleWAgaXMgZXZhbHVhdGVkLlxuICogQHBhcmFtIHtbXX0gbWVudSAtIHJldHVybnMgdGhlIG5lc3RlZCBtZW51XG4gKiBAcGFyYW0ge3N0cmluZ30gcHJvZ3Jlc3NLZXkyIC0gdGhlIHNlY29uZGFyeSBrZXkgYnkgd2hpY2ggdGhlIGdyb3VwIHByb2dyZXNzIHdpbGwgYmUgbWVhc3VyZWRcbiAqL1xuZnVuY3Rpb24gZ2VuZXJhdGVNZW51QnlHcm91cChkYXRhLCBpbmRleCwgZGlyZWN0aW9uLCBvblByb2Nlc3NJdGVtLCBtZW51LCBwcm9ncmVzc0tleSwgcHJvZ3Jlc3NLZXkyKSB7XG4gIGNvbnN0IGRhdGFLZXlzID0gT2JqZWN0LmtleXMoZGF0YSk7XG5cbiAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGluZGV4Lmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgY29uc3QgZW50cnkgPSBpbmRleFtpXTtcblxuICAgIGlmIChkYXRhS2V5cy5pbmNsdWRlcyhlbnRyeS5pZCkpIHtcbiAgICAgIC8vIGdlbmVyYXRlIG1lbnUgZ3JvdXBcbiAgICAgIGNvbnN0IGdyb3VwID0gZGF0YVtlbnRyeS5pZF07XG4gICAgICBjb25zdCBnbCA9IGdyb3VwLmxlbmd0aDtcbiAgICAgIGNvbnN0IGNoaWxkcmVuID0gbmV3IEFycmF5KGdsKTtcblxuICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBnbDsgaisrKSB7XG4gICAgICAgIGNvbnN0IGl0ZW0gPSBwcm9jZXNzTWVudUl0ZW0oZ3JvdXBbal0pO1xuICAgICAgICBpdGVtLmRpcmVjdGlvbiA9IGRpcmVjdGlvbjtcbiAgICAgICAgY2hpbGRyZW5bal0gPSBvblByb2Nlc3NJdGVtID8gb25Qcm9jZXNzSXRlbShpdGVtKSA6IGl0ZW07XG4gICAgICB9XG4gICAgICBtZW51LnB1c2goe1xuICAgICAgICB0aXRsZTogZW50cnkubmFtZSxcbiAgICAgICAgcHJvZ3Jlc3M6IGNhbGN1bGF0ZVByb2dyZXNzKGNoaWxkcmVuLCBwcm9ncmVzc0tleSwgcHJvZ3Jlc3NLZXkyKSxcbiAgICAgICAgaWQ6IGVudHJ5LmlkLFxuICAgICAgICBjaGlsZHJlbixcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIEhlbHBlciB1dGlsaXR5IHRvIGdlbmVyYXRlIGRhdGEgZm9yIHRoZSBtZW51IG9yZ2FuaXplZCBieSByZWZlcmVuY2UuXG4gKiBAcGFyYW0ge1tdfSBpbmRleCAtIHRoZSBncm91cCBpbmRleFxuICogQHBhcmFtIHtvYmplY3R9IGRhdGEgLSB0aGUgZ3JvdXAgZGF0YVxuICogQHBhcmFtIHtzdHJpbmd9IGRpcmVjdGlvbiAtIGxheW91dCBkaXJlY3Rpb24gLSBkZWZhdWx0ICdsdHInXG4gKiBAcGFyYW0ge3N0cmluZ30gcHJvZ3Jlc3NLZXkgLSB0aGUga2V5IGJ5IHdoaWNoIHRoZSBncm91cCBwcm9ncmVzcyB3aWxsIGJlIG1lYXN1cmVkXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufSBbb25Qcm9jZXNzSXRlbT1udWxsXSAtIGFuIG9wdGlvbmFsIGNhbGxiYWNrIHRvIHBlcmZvcm0gYWRkaXRpb25hbCBwcm9jZXNzaW5nIG9uIGEgbWVudSBpdGVtLiBUaGlzIGlzIGV4ZWN1dGVkIGJlZm9yZSB0aGUgYHByb2dyZXNzS2V5YCBpcyBldmFsdWF0ZWQuXG4gKiBAcGFyYW0ge1tdfSBtZW51IC0gcmV0dXJucyB0aGUgbmVzdGVkIG1lbnVcbiAqIEBwYXJhbSB7c3RyaW5nfSBwcm9ncmVzc0tleTIgLSB0aGUgc2Vjb25kYXJ5IGtleSBieSB3aGljaCB0aGUgZ3JvdXAgcHJvZ3Jlc3Mgd2lsbCBiZSBtZWFzdXJlZFxuICovXG5mdW5jdGlvbiBnZW5lcmF0ZU1lbnVCeVJlZihkYXRhLCBpbmRleCwgZGlyZWN0aW9uLCBvblByb2Nlc3NJdGVtLCBtZW51LCBwcm9ncmVzc0tleSwgcHJvZ3Jlc3NLZXkyKSB7XG4gIGxldCByZWZzID0ge307XG4gIGxldCBncm91cHMgPSB7fTtcblxuICBmb3IgKGxldCBpID0gMCwgbGVuID0gaW5kZXgubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICBjb25zdCBlbnRyeSA9IGluZGV4W2ldO1xuICAgIGNvbnN0IGlkID0gZW50cnk/LmlkO1xuICAgIGdyb3Vwc1tpZF0gPSBlbnRyeT8ubmFtZSB8fCAnJztcbiAgICBjb25zdCBkYXRhSXRlbXMgPSBkYXRhW2lkXSB8fCBbXTtcblxuICAgIGZvciAoY29uc3QgaXRlbSBvZiBkYXRhSXRlbXMpIHtcbiAgICAgIGNvbnN0IHJlZiA9IGl0ZW0/LmNvbnRleHRJZD8ucmVmZXJlbmNlO1xuXG4gICAgICBpZiAocmVmKSB7XG4gICAgICAgIGNvbnN0IHJlZlN0ciA9IGAke3JlZi5jaGFwdGVyfToke3JlZi52ZXJzZX1gO1xuICAgICAgICBsZXQgY2hpbGRyZW4gPSByZWZzW3JlZlN0cl07XG5cbiAgICAgICAgaWYgKCFjaGlsZHJlbikge1xuICAgICAgICAgIGNoaWxkcmVuID0gW107XG4gICAgICAgICAgcmVmc1tyZWZTdHJdID0gY2hpbGRyZW47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBuZXdJdGVtID0ge1xuICAgICAgICAgIC4uLml0ZW0sXG4gICAgICAgICAgb3JnYW5pemVCeVJlZjogcmVmU3RyLFxuICAgICAgICB9O1xuICAgICAgICBjaGlsZHJlbi5wdXNoKG5ld0l0ZW0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGNvbnN0IHNvcnRlZFJlZnMgPSBPYmplY3Qua2V5cyhyZWZzKS5zb3J0KGJpYmxlUmVmU29ydCk7XG5cbiAgZm9yIChjb25zdCByZWYgb2Ygc29ydGVkUmVmcykge1xuICAgIGNvbnN0IGNoaWxkcmVuID0gcmVmc1tyZWZdO1xuXG4gICAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGNoaWxkcmVuLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICBjb25zdCBlbnRyeSA9IGNoaWxkcmVuW2ldO1xuICAgICAgY29uc3QgaXRlbSA9IHByb2Nlc3NNZW51SXRlbShlbnRyeSk7XG4gICAgICBpdGVtLmRpcmVjdGlvbiA9IGRpcmVjdGlvbjtcbiAgICAgIGl0ZW0uZ3JvdXBOYW1lID0gZ3JvdXBzW2l0ZW0uZ3JvdXBJZF0gfHwgaXRlbS5ncm91cElkO1xuICAgICAgbGV0IHByb2Nlc3NlZCA9IG9uUHJvY2Vzc0l0ZW0gPyBvblByb2Nlc3NJdGVtKGl0ZW0sIHRydWUpIDogaXRlbTtcbiAgICAgIGNoaWxkcmVuW2ldID0gcHJvY2Vzc2VkO1xuICAgIH1cblxuICAgIG1lbnUucHVzaCh7XG4gICAgICB0aXRsZTogcmVmLFxuICAgICAgcHJvZ3Jlc3M6IGNhbGN1bGF0ZVByb2dyZXNzKGNoaWxkcmVuLCBwcm9ncmVzc0tleSwgcHJvZ3Jlc3NLZXkyKSxcbiAgICAgIGlkOiByZWYsXG4gICAgICBjaGlsZHJlbixcbiAgICAgIG9yZ2FuaXplQnlSZWY6IHJlZixcbiAgICB9KTtcbiAgfVxufVxuXG4vKipcbiAqIEhlbHBlciB1dGlsaXR5IHRvIGdlbmVyYXRlIGRhdGEgZm9yIHRoZSBtZW51LlxuICogQHBhcmFtIHtbXX0gaW5kZXggLSB0aGUgZ3JvdXAgaW5kZXhcbiAqIEBwYXJhbSB7b2JqZWN0fSBkYXRhIC0gdGhlIGdyb3VwIGRhdGFcbiAqIEBwYXJhbSB7c3RyaW5nfSBkaXJlY3Rpb24gLSBsYXlvdXQgZGlyZWN0aW9uIC0gZGVmYXVsdCAnbHRyJ1xuICogQHBhcmFtIHtzdHJpbmd9IHByb2dyZXNzS2V5IC0gdGhlIGtleSBieSB3aGljaCB0aGUgZ3JvdXAgcHJvZ3Jlc3Mgd2lsbCBiZSBtZWFzdXJlZFxuICogQHBhcmFtIHtmdW5jdGlvbn0gW29uUHJvY2Vzc0l0ZW09bnVsbF0gLSBhbiBvcHRpb25hbCBjYWxsYmFjayB0byBwZXJmb3JtIGFkZGl0aW9uYWwgcHJvY2Vzc2luZyBvbiBhIG1lbnUgaXRlbS4gVGhpcyBpcyBleGVjdXRlZCBiZWZvcmUgdGhlIGBwcm9ncmVzc0tleWAgaXMgZXZhbHVhdGVkLlxuICogQHBhcmFtIHtzdHJpbmd9IHByb2dyZXNzS2V5MiAtIHRoZSBzZWNvbmRhcnkga2V5IGJ5IHdoaWNoIHRoZSBncm91cCBwcm9ncmVzcyB3aWxsIGJlIG1lYXN1cmVkXG4gKiBAcGFyYW0ge2Jvb2xlYW59IG9yZ2FuaXplQnlSZWYgLSBvcHRpb25hbCwgaWYgdHJ1ZSB0aGVuIGdyb3VwIGJ5IHJlZmVyZW5jZXNcbiAqIEByZXR1cm5zIHtbXX0gdGhlIG1lbnUgZGF0YVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2VuZXJhdGVNZW51RGF0YShcbiAgaW5kZXgsXG4gIGRhdGEsXG4gIHByb2dyZXNzS2V5LFxuICBkaXJlY3Rpb24gPSAnbHRyJyxcbiAgb25Qcm9jZXNzSXRlbSA9IG51bGwsXG4gIHByb2dyZXNzS2V5MiA9IG51bGwsXG4gIG9yZ2FuaXplQnlSZWYgPSBmYWxzZSxcbikge1xuICBjb25zdCBtZW51ID0gW107XG5cbiAgaWYgKG9yZ2FuaXplQnlSZWYpIHtcbiAgICBnZW5lcmF0ZU1lbnVCeVJlZihkYXRhLCBpbmRleCwgZGlyZWN0aW9uLCBvblByb2Nlc3NJdGVtLCBtZW51LCBwcm9ncmVzc0tleSwgcHJvZ3Jlc3NLZXkyKTtcbiAgfSBlbHNlIHtcbiAgICBnZW5lcmF0ZU1lbnVCeUdyb3VwKGRhdGEsIGluZGV4LCBkaXJlY3Rpb24sIG9uUHJvY2Vzc0l0ZW0sIG1lbnUsIHByb2dyZXNzS2V5LCBwcm9ncmVzc0tleTIpO1xuICB9XG4gIHJldHVybiBtZW51O1xufVxuXG5cblxuLyoqXG4gKiBQcm9kdWNlcyBhIHZhbGlkIG1lbnUgaXRlbSBmcm9tIGEgY29udGV4dCBpZCBvciBhIGdyb3VwIGRhdGEgZW50cnkuXG4gKiBUaGlzIGlzIHVzZWZ1bCBmb3IgcHJlLXByb2Nlc3NpbmcgdGhlIGFjdGl2ZSBlbnRyeS5cbiAqIEBwYXJhbSB7b2JqZWN0fSBjb250ZXh0SWQgLSBhIGNvbnRleHQgaWQgb3IgZ3JvdXAgZGF0YSBlbnRyeS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBkaXJlY3Rpb24gLSBsYXlvdXQgZGlyZWN0aW9uIC0gZGVmYXVsdCAnbHRyJ1xuICogQHBhcmFtIHtmdW5jdGlvbn0gW29uUHJvY2Vzc0l0ZW09bnVsbF0gLSBhbiBvcHRpb25hbCBwcmVwcm9jZXNzb3JcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gb3JnYW5pemVCeVJlZiAtIG9wdGlvbmFsLCBpZiB0cnVlIHRoZW4gZ3JvdXAgYnkgcmVmZXJlbmNlc1xuICogQHJldHVybnMge29iamVjdH1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdlbmVyYXRlTWVudUl0ZW0oXG4gIGNvbnRleHRJZCxcbiAgZGlyZWN0aW9uID0gJ2x0cicsXG4gIG9uUHJvY2Vzc0l0ZW0gPSBudWxsLFxuICBvcmdhbml6ZUJ5UmVmID0gZmFsc2UsXG4pIHtcbiAgLy8gVFJJQ0tZOiBkZXRlcm1pbmUgaWYgdGhpcyBpcyBhIGNvbnRleHRJZCBvciBncm91cCBkYXRhIGVudHJ5LlxuICBsZXQgaXRlbTtcblxuICBpZiAoY29udGV4dElkLmhhc093blByb3BlcnR5KCdjb250ZXh0SWQnKSkge1xuICAgIGl0ZW0gPSBjb250ZXh0SWQ7XG4gIH0gZWxzZSB7XG4gICAgaXRlbSA9IHsgY29udGV4dElkIH07XG4gIH1cbiAgaXRlbS5kaXJlY3Rpb24gPSBkaXJlY3Rpb247XG5cbiAgaWYgKG9yZ2FuaXplQnlSZWYpIHtcbiAgICBjb25zdCByZWYgPSBpdGVtPy5jb250ZXh0SWQ/LnJlZmVyZW5jZTtcblxuICAgIGlmIChyZWYpIHtcbiAgICAgIGNvbnN0IHJlZlN0ciA9IGAke3JlZi5jaGFwdGVyfToke3JlZi52ZXJzZX1gO1xuICAgICAgaXRlbS5vcmdhbml6ZUJ5UmVmID0gcmVmU3RyO1xuICAgIH1cbiAgfVxuXG4gIC8vIHBlcmZvcm0gcHJlLXByb2Nlc3NpbmdcbiAgaWYgKHR5cGVvZiBvblByb2Nlc3NJdGVtID09PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIG9uUHJvY2Vzc0l0ZW0ocHJvY2Vzc01lbnVJdGVtKGl0ZW0pKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gcHJvY2Vzc01lbnVJdGVtKGl0ZW0pO1xuICB9XG59XG5cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgcHJvZ3Jlc3Mgb3ZlciBhbiBhcnJheSBvZiBvYmplY3RzXG4gKiBAcGFyYW0ge29iamVjdFtdfSBkYXRhIC0gYW4gYXJyYXkgb2Ygb2JqZWN0c1xuICogQHBhcmFtIHtzdHJpbmd9IHByb2dyZXNzS2V5IC0gdGhlIGtleSB1c2VkIHRvIGNoZWNrIHRoZSBjb21wbGV0aW9uIHN0YXR1cyBvZiBlYWNoIG9iamVjdFxuICogQHBhcmFtIHtzdHJpbmd9IHByb2dyZXNzS2V5MiAtIHRoZSBzZWNvbmRhcnkga2V5IHVzZWQgdG8gY2hlY2sgdGhlIGNvbXBsZXRpb24gc3RhdHVzIG9mIGVhY2ggb2JqZWN0XG4gKiBAcmV0dXJucyB7bnVtYmVyfSAtIHJldHVybnMgYSBudW1iZXIgYmV0d2VlbiAwIGFuZCAxMDAgaW5jbHVzaXZlXG4gKi9cbmZ1bmN0aW9uIGNhbGN1bGF0ZVByb2dyZXNzKGRhdGEsIHByb2dyZXNzS2V5LCBwcm9ncmVzc0tleTIpIHtcbiAgY29uc3QgdG90YWwgPSBkYXRhLmxlbmd0aDtcbiAgbGV0IGNvbXBsZXRlZCA9IDA7XG5cbiAgZm9yIChsZXQgaSA9IDAsIGxlbiA9IGRhdGEubGVuZ3RoOyBpIDwgbGVuOyBpICsrKSB7XG4gICAgaWYgKGRhdGFbaV1bcHJvZ3Jlc3NLZXldIHx8IChwcm9ncmVzc0tleTIgJiYgZGF0YVtpXVtwcm9ncmVzc0tleTJdKSkge1xuICAgICAgY29tcGxldGVkKys7XG4gICAgfVxuICB9XG4gIHJldHVybiAoY29tcGxldGVkIC8gdG90YWwpICogMTAwO1xufVxuXG4vKipcbiAqIFBlcmZvcm1zIHNvbWUgZGVmYXVsdCBjaGlsZCBnZW5lcmF0aW9uIG9wZXJhdGlvbnMuXG4gKiBGb3IgYWR2YW5jZWQgbWVudSBpdGVtIGN1c3RvbWl6YXRpb24geW91IHNob3VsZCBwcm92aWRlIGEgY2FsbGJhY2sgdG8ge0BsaW5rIGdlbmVyYXRlTWVudURhdGF9XG4gKiBAcGFyYW0ge29iamVjdH0gZGF0YSAtIHRoZSBtZW51IGl0ZW0gZGF0YVxuICogQHJldHVybnMge29iamVjdH0gLSB0aGUgZm9ybWF0dGVkIG1lbnUgaXRlbSBkYXRhXG4gKi9cbmZ1bmN0aW9uIHByb2Nlc3NNZW51SXRlbShkYXRhKSB7XG4gIC8vIFRSSUNLWTogdXNlIHRoZSBjb250ZXh0IGlkIHRvIHByZS1wb3B1bGF0ZSBzb21lIGZpZWxkc1xuICBjb25zdCB7XG4gICAgY29udGV4dElkOiB7XG4gICAgICBncm91cElkLFxuICAgICAgcmVmZXJlbmNlOiB7XG4gICAgICAgIGJvb2tJZCwgY2hhcHRlciwgdmVyc2UsXG4gICAgICB9LFxuICAgIH0sXG4gIH0gPSBkYXRhO1xuICBjb25zdCByZWZTdHIgPSBnZXRSZWZlcmVuY2VTdHIoY2hhcHRlciwgdmVyc2UpO1xuICBjb25zdCBwYXNzYWdlVGl0bGUgPSBnZXRUaXRsZVN0cihib29rSWQsIHJlZlN0ciwgZGF0YS5kaXJlY3Rpb24pO1xuXG4gIHJldHVybiB7XG4gICAgLi4uZGF0YSxcbiAgICBncm91cElkLFxuICAgIGl0ZW1JZDogcmVmU3RyLFxuICAgIHRpdGxlOiBwYXNzYWdlVGl0bGUsXG4gIH07XG59XG4iXX0=