UNPKG

tc-ui-toolkit

Version:

React components used to develop tools for the desktop app translationCore

369 lines (302 loc) 40.6 kB
'use strict'; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.isWordArrayMatch = isWordArrayMatch; exports.isWordMatch = isWordMatch; exports.getWordHighlightedDetails = getWordHighlightedDetails; exports.getWordsFromNestedMilestone = getWordsFromNestedMilestone; exports.getDeepNestedWords = getDeepNestedWords; exports.isPunctuationHighlighted = isPunctuationHighlighted; exports.addSpace = addSpace; var _react = _interopRequireDefault(require("react")); var _isEqual = _interopRequireDefault(require("lodash/isEqual")); var _stringHelpers = require("./stringHelpers"); var _usfmHelpers = require("./usfmHelpers"); /** * check if occurrence is correct match. Corrects occurrence by adding word count from previous verse * @param {number|string} occurrence * @param {array} verseWordCounts * @param {object} wordItem * @returns {boolean} */ function doesOccurrenceMatch(occurrence, verseWordCounts, wordItem) { if (typeof occurrence === 'string' && occurrence.length === 0) { occurrence = 1; } if (occurrence === -1) { return true; } else { var previousCount = 0; if (verseWordCounts) { var verseCnt = wordItem.verseCnt || 0; if (verseCnt) { var previousVerseCounts = verseWordCounts[verseCnt - 1]; previousCount = (previousVerseCounts === null || previousVerseCounts === void 0 ? void 0 : previousVerseCounts[wordItem.content]) || 0; } } return occurrence === wordItem.occurrence + previousCount; } } /** * check if word is part of quote * @param {object} word * @param {object} contextId * @param {array} verseWordCounts - array of word counts for multi-verse * @returns {boolean} */ function isWordArrayMatch(word, contextId) { var verseWordCounts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; var isMatch = false; if (word && word.content && Array.isArray(word.content) && contextId && contextId.quote) { isMatch = word.content.some(function (wordItem) { var foundMatch = false; if (Array.isArray(contextId.quote)) { for (var i = 0, l = contextId.quote.length; i < l; i++) { var quote = contextId.quote[i]; if (quote.word === wordItem.content) { foundMatch = doesOccurrenceMatch(quote.occurrence, verseWordCounts, wordItem); if (foundMatch) { break; } } } } else if (contextId.quote.split(' ').includes(wordItem.content)) { foundMatch = doesOccurrenceMatch(contextId.occurrence, verseWordCounts, wordItem); } return foundMatch; }); } return isMatch; } /** * search word list to match occurrence of word. Counts occurrences current word and makes sure it matches occurrence * @param {number} index - position of word to stop at * @param {Array} words - list of word objects to search * @param {String} wordText - text to match * @param {number} occurrence - to match (if -1, then match all occurrences) * @return {Boolean} - true if same occurrence */ function matchOccurrenceOfWord(index, words, wordText, occurrence) { // get occurrence of word var _occurrence = 0; for (var i = 0; i <= index; i++) { var wordItem = words[i]; if (wordItem.type === 'word' && wordItem.text === wordText) { _occurrence++; } } var isMatch = _occurrence === occurrence || occurrence === -1; return isMatch; } /** * see if this word is part of quote for current context id. * @param {Object} word * @param {Object} contextId * @param {Array} words * @param {number} index * @return {boolean} - true if in quote */ function isWordMatch(word, contextId, words, index) { var isMatch = false; try { if (word && word.text && contextId && contextId.quote) { if (Array.isArray(contextId.quote)) { // if list of words in quote see if this word matches one of the words for (var i = 0, l = contextId.quote.length; i < l; i++) { var quote = contextId.quote[i]; if (quote.word === word.text) { isMatch = matchOccurrenceOfWord(index, words, word.text, quote.occurrence); if (isMatch) { break; } } else if (word.text && word.text.includes('’') && word.text.replace('’', '') === quote.word) { var wordText = word.text.replace('’', ''); // Deep cloning array to avoid referencing the old array address in memory var newWords = JSON.parse(JSON.stringify(words)); // remove apostrophe from each word in the words array var wordsWithoutApostrophe = []; for (var _i = 0; _i <= index; _i++) { var wordItem = newWords[_i]; if (wordItem.text && wordItem.text.includes('’')) { wordItem.text = wordItem.text.replace('’', ''); } wordsWithoutApostrophe.push(wordItem); } isMatch = matchOccurrenceOfWord(index, wordsWithoutApostrophe, wordText, quote.occurrence); if (isMatch) { break; } } } } else { // is string with one or more words var quotes = contextId.quote.split(' '); for (var _i2 = 0, _l = quotes.length; _i2 < _l; _i2++) { var _quote = quotes[_i2]; if (_quote === word.text) { isMatch = matchOccurrenceOfWord(index, words, _quote, contextId.occurrence); } } } } return isMatch; } catch (e) { console.error(e); } } /** * determine highlighting for word and previous white space * @param {Object} contextId * @param {Object} previousWord * @param {Object} word * @param {array} verseWordCounts - array of word counts for multi-verse * @returns {{isHighlightedWord: boolean, isBetweenHighlightedWord: boolean}} */ function getWordHighlightedDetails(contextId, previousWord, word) { var verseWordCounts = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null; var isHighlightedWord = isWordArrayMatch(word, contextId, verseWordCounts); var isBetweenHighlightedWord = isHighlightedWord && previousWord && !(0, _isEqual["default"])(previousWord, word) && isWordArrayMatch(previousWord, contextId, verseWordCounts); return { isHighlightedWord: isHighlightedWord, isBetweenHighlightedWord: isBetweenHighlightedWord }; } function getWordsFromNestedMilestone(nestedWords, contextId, index, previousWord, wordSpacing, fontClass, verseWordCounts) { // if its an array of an array thus get deep nested words array. if (Array.isArray(nestedWords[0])) { nestedWords = getDeepNestedWords(nestedWords); } var isHighlightedWord = false; var isBetweenHighlightedWord = false; var nestedPreviousWord = previousWord; var nestedWordSpacing = wordSpacing; var wordSpans = []; for (var i = 0, len = nestedWords.length; i < len; i++) { var nestedWord = nestedWords[i]; var nestedWordIndex = i; var wordsArray = nestedWords; var nestedWordSpanIndex = "".concat(index.toString(), "_").concat(nestedWordIndex.toString(), "_").concat(nestedWord.text); var nestedNextWord = wordsArray[index + 1]; if ((0, _stringHelpers.isWord)(nestedWord)) { var padding = nestedWordSpacing; nestedWordSpacing = ' '; // spacing between words if (nestedPreviousWord && isPuntuationAndNeedsNoSpace(nestedPreviousWord)) { padding = ''; } var highlightedDetails = getWordHighlightedDetails(contextId, nestedPreviousWord, nestedWord, verseWordCounts); isHighlightedWord = highlightedDetails.isHighlightedWord; isBetweenHighlightedWord = highlightedDetails.isBetweenHighlightedWord; nestedPreviousWord = nestedWord; var paddingSpanStyle = { backgroundColor: isBetweenHighlightedWord ? 'var(--highlight-color)' : 'transparent' }; wordSpans.push( /*#__PURE__*/_react["default"].createElement("span", { key: nestedWordSpanIndex.toString() }, /*#__PURE__*/_react["default"].createElement("span", { style: paddingSpanStyle }, padding), /*#__PURE__*/_react["default"].createElement("span", { className: fontClass, style: { backgroundColor: isHighlightedWord ? 'var(--highlight-color)' : '' } }, (0, _usfmHelpers.removeMarker)(nestedWord.text)))); } else if (nestedWord.text) { nestedWordSpacing = (0, _stringHelpers.punctuationWordSpacing)(nestedWord); // spacing before words var text = (0, _usfmHelpers.removeMarker)(nestedWord.text); if (isPunctuationHighlighted(nestedPreviousWord, nestedNextWord, contextId, verseWordCounts)) { wordSpans.push( /*#__PURE__*/_react["default"].createElement("span", { key: nestedWordSpanIndex, className: fontClass, style: { backgroundColor: 'var(--highlight-color)' } }, text)); } else { wordSpans.push( /*#__PURE__*/_react["default"].createElement("span", { className: fontClass, key: nestedWordSpanIndex }, text)); } } } return { wordSpans: wordSpans, nestedPreviousWord: nestedPreviousWord, nestedWordSpacing: nestedWordSpacing }; } /** * Determines if the previous word is a punctuation that * doesnt need spacing after it. * @param {Object} wordObject */ function isPuntuationAndNeedsNoSpace(wordObject) { return !(0, _stringHelpers.isWord)(wordObject) && wordObject.text === '"' || wordObject.text === '\''; } /** * Gets a words object array from a deep nested milestone. * @param {array} nestedWords */ function getDeepNestedWords(nestedWords) { var deepNestedWords = null; for (var i = 0, len = nestedWords.length; i < len; i++) { var nestedWord = nestedWords[i]; if (nestedWord.text) { deepNestedWords = nestedWords; } else { deepNestedWords = getDeepNestedWords(nestedWord); } } return deepNestedWords; } /** * Determines if a punctuation should be highlighted or not. * @param {object} previousWord * @param {object} nextWord * @param {object} contextId * @param {array} words * @param {number} index * @param {array} verseWordCounts - array of word counts for multi-verse * @returns {bool} true or false. highlighted or not highlighted. */ function isPunctuationHighlighted(previousWord, nextWord, contextId, words, index) { var verseWordCounts = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : null; // handle nested previous words if (previousWord && Array.isArray(previousWord[0])) { var nestedPreviousWord = getDeepNestedWords(previousWord); // get the last item in the array previousWord = nestedPreviousWord[nestedPreviousWord.length - 1]; } // handle nested next words if (nextWord) { if (Array.isArray(nextWord) || Array.isArray(nextWord[0])) { var nestedNextWords = getDeepNestedWords(nextWord); nextWord = nestedNextWords[0]; } } var isPreviousWordMatch = previousWord && previousWord.content ? isWordArrayMatch(previousWord, contextId, verseWordCounts) : isWordMatch(previousWord, contextId, words, index - 1); var isNextWordMatch = nextWord && nextWord.content ? isWordArrayMatch(nextWord, contextId, verseWordCounts) : isWordMatch(nextWord, contextId, words, index + 1); if (previousWord && nextWord) { return isPreviousWordMatch && isNextWordMatch; } else if (previousWord) { return isPreviousWordMatch; } else if (nextWord) { return isNextWordMatch; } else { return false; } } var spaceCounter = 0; /** * pushes a span to the array * @param {Array} verseSpan * @param {String} fontClass */ function addSpace(verseSpan, fontClass) { verseSpan.push( /*#__PURE__*/_react["default"].createElement("span", { key: 'space_' + ++spaceCounter, className: fontClass, style: { backgroundColor: 'transparent' } }, ' ')); } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9TY3JpcHR1cmVQYW5lL2hlbHBlcnMvaGlnaGxpZ2h0SGVscGVycy5qcyJdLCJuYW1lcyI6WyJkb2VzT2NjdXJyZW5jZU1hdGNoIiwib2NjdXJyZW5jZSIsInZlcnNlV29yZENvdW50cyIsIndvcmRJdGVtIiwibGVuZ3RoIiwicHJldmlvdXNDb3VudCIsInZlcnNlQ250IiwicHJldmlvdXNWZXJzZUNvdW50cyIsImNvbnRlbnQiLCJpc1dvcmRBcnJheU1hdGNoIiwid29yZCIsImNvbnRleHRJZCIsImlzTWF0Y2giLCJBcnJheSIsImlzQXJyYXkiLCJxdW90ZSIsInNvbWUiLCJmb3VuZE1hdGNoIiwiaSIsImwiLCJzcGxpdCIsImluY2x1ZGVzIiwibWF0Y2hPY2N1cnJlbmNlT2ZXb3JkIiwiaW5kZXgiLCJ3b3JkcyIsIndvcmRUZXh0IiwiX29jY3VycmVuY2UiLCJ0eXBlIiwidGV4dCIsImlzV29yZE1hdGNoIiwicmVwbGFjZSIsIm5ld1dvcmRzIiwiSlNPTiIsInBhcnNlIiwic3RyaW5naWZ5Iiwid29yZHNXaXRob3V0QXBvc3Ryb3BoZSIsInB1c2giLCJxdW90ZXMiLCJlIiwiY29uc29sZSIsImVycm9yIiwiZ2V0V29yZEhpZ2hsaWdodGVkRGV0YWlscyIsInByZXZpb3VzV29yZCIsImlzSGlnaGxpZ2h0ZWRXb3JkIiwiaXNCZXR3ZWVuSGlnaGxpZ2h0ZWRXb3JkIiwiZ2V0V29yZHNGcm9tTmVzdGVkTWlsZXN0b25lIiwibmVzdGVkV29yZHMiLCJ3b3JkU3BhY2luZyIsImZvbnRDbGFzcyIsImdldERlZXBOZXN0ZWRXb3JkcyIsIm5lc3RlZFByZXZpb3VzV29yZCIsIm5lc3RlZFdvcmRTcGFjaW5nIiwid29yZFNwYW5zIiwibGVuIiwibmVzdGVkV29yZCIsIm5lc3RlZFdvcmRJbmRleCIsIndvcmRzQXJyYXkiLCJuZXN0ZWRXb3JkU3BhbkluZGV4IiwidG9TdHJpbmciLCJuZXN0ZWROZXh0V29yZCIsInBhZGRpbmciLCJpc1B1bnR1YXRpb25BbmROZWVkc05vU3BhY2UiLCJoaWdobGlnaHRlZERldGFpbHMiLCJwYWRkaW5nU3BhblN0eWxlIiwiYmFja2dyb3VuZENvbG9yIiwiaXNQdW5jdHVhdGlvbkhpZ2hsaWdodGVkIiwid29yZE9iamVjdCIsImRlZXBOZXN0ZWRXb3JkcyIsIm5leHRXb3JkIiwibmVzdGVkTmV4dFdvcmRzIiwiaXNQcmV2aW91c1dvcmRNYXRjaCIsImlzTmV4dFdvcmRNYXRjaCIsInNwYWNlQ291bnRlciIsImFkZFNwYWNlIiwidmVyc2VTcGFuIl0sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBRUE7Ozs7Ozs7QUFPQSxTQUFTQSxtQkFBVCxDQUE2QkMsVUFBN0IsRUFBeUNDLGVBQXpDLEVBQTBEQyxRQUExRCxFQUFvRTtBQUNsRSxNQUFJLE9BQU9GLFVBQVAsS0FBc0IsUUFBdEIsSUFBa0NBLFVBQVUsQ0FBQ0csTUFBWCxLQUFzQixDQUE1RCxFQUErRDtBQUM3REgsSUFBQUEsVUFBVSxHQUFHLENBQWI7QUFDRDs7QUFFRCxNQUFJQSxVQUFVLEtBQUssQ0FBQyxDQUFwQixFQUF1QjtBQUNyQixXQUFPLElBQVA7QUFDRCxHQUZELE1BRU87QUFDTCxRQUFJSSxhQUFhLEdBQUcsQ0FBcEI7O0FBRUEsUUFBSUgsZUFBSixFQUFxQjtBQUNuQixVQUFNSSxRQUFRLEdBQUdILFFBQVEsQ0FBQ0csUUFBVCxJQUFxQixDQUF0Qzs7QUFFQSxVQUFJQSxRQUFKLEVBQWM7QUFDWixZQUFNQyxtQkFBbUIsR0FBR0wsZUFBZSxDQUFDSSxRQUFRLEdBQUcsQ0FBWixDQUEzQztBQUNBRCxRQUFBQSxhQUFhLEdBQUcsQ0FBQUUsbUJBQW1CLFNBQW5CLElBQUFBLG1CQUFtQixXQUFuQixZQUFBQSxtQkFBbUIsQ0FBR0osUUFBUSxDQUFDSyxPQUFaLENBQW5CLEtBQTJDLENBQTNEO0FBQ0Q7QUFDRjs7QUFDRCxXQUFRUCxVQUFVLEtBQUtFLFFBQVEsQ0FBQ0YsVUFBVCxHQUFzQkks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QVMsQ0FBQ3RDLElBQVYsZUFDRTtBQUFNLElBQUEsR0FBRyxFQUFFLFdBQVcsRUFBRW9DLFlBQXhCO0FBQXVDLElBQUEsU0FBUyxFQUFFeEIsU0FBbEQ7QUFBNkQsSUFBQSxLQUFLLEVBQUU7QUFBRWdCLE1BQUFBLGVBQWUsRUFBRTtBQUFuQjtBQUFwRSxLQUNHLEdBREgsQ0FERjtBQUtEIiwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCBpc0VxdWFsIGZyb20gJ2xvZGFzaC9pc0VxdWFsJztcbmltcG9ydCB7IGlzV29yZCwgcHVuY3R1YXRpb25Xb3JkU3BhY2luZyB9IGZyb20gJy4vc3RyaW5nSGVscGVycyc7XG5pbXBvcnQgeyByZW1vdmVNYXJrZXIgfSBmcm9tICcuL3VzZm1IZWxwZXJzJztcblxuLyoqXG4gKiBjaGVjayBpZiBvY2N1cnJlbmNlIGlzIGNvcnJlY3QgbWF0Y2guICBDb3JyZWN0cyBvY2N1cnJlbmNlIGJ5IGFkZGluZyB3b3JkIGNvdW50IGZyb20gcHJldmlvdXMgdmVyc2VcbiAqIEBwYXJhbSB7bnVtYmVyfHN0cmluZ30gb2NjdXJyZW5jZVxuICogQHBhcmFtIHthcnJheX0gdmVyc2VXb3JkQ291bnRzXG4gKiBAcGFyYW0ge29iamVjdH0gd29yZEl0ZW1cbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5mdW5jdGlvbiBkb2VzT2NjdXJyZW5jZU1hdGNoKG9jY3VycmVuY2UsIHZlcnNlV29yZENvdW50cywgd29yZEl0ZW0pIHtcbiAgaWYgKHR5cGVvZiBvY2N1cnJlbmNlID09PSAnc3RyaW5nJyAmJiBvY2N1cnJlbmNlLmxlbmd0aCA9PT0gMCkge1xuICAgIG9jY3VycmVuY2UgPSAxO1xuICB9XG5cbiAgaWYgKG9jY3VycmVuY2UgPT09IC0xKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH0gZWxzZSB7XG4gICAgbGV0IHByZXZpb3VzQ291bnQgPSAwO1xuXG4gICAgaWYgKHZlcnNlV29yZENvdW50cykge1xuICAgICAgY29uc3QgdmVyc2VDbnQgPSB3b3JkSXRlbS52ZXJzZUNudCB8fCAwO1xuXG4gICAgICBpZiAodmVyc2VDbnQpIHtcbiAgICAgICAgY29uc3QgcHJldmlvdXNWZXJzZUNvdW50cyA9IHZlcnNlV29yZENvdW50c1t2ZXJzZUNudCAtIDFdO1xuICAgICAgICBwcmV2aW91c0NvdW50ID0gcHJldmlvdXNWZXJzZUNvdW50cz8uW3dvcmRJdGVtLmNvbnRlbnRdIHx8IDA7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiAob2NjdXJyZW5jZSA9PT0gd29yZEl0ZW0ub2NjdXJyZW5jZSArIHByZXZpb3VzQ291bnQpO1xuICB9XG59XG5cbi8qKlxuICogY2hlY2sgaWYgd29yZCBpcyBwYXJ0IG9mIHF1b3RlXG4gKiBAcGFyYW0ge29iamVjdH0gd29yZFxuICogQHBhcmFtIHtvYmplY3R9IGNvbnRleHRJZFxuICogQHBhcmFtIHthcnJheX0gdmVyc2VXb3JkQ291bnRzIC0gYXJyYXkgb2Ygd29yZCBjb3VudHMgZm9yIG11bHRpLXZlcnNlXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzV29yZEFycmF5TWF0Y2god29yZCwgY29udGV4dElkLCB2ZXJzZVdvcmRDb3VudHMgPSBudWxsKSB7XG4gIGxldCBpc01hdGNoID0gZmFsc2U7XG5cbiAgaWYgKHdvcmQgJiYgd29yZC5jb250ZW50ICYmIEFycmF5LmlzQXJyYXkod29yZC5jb250ZW50KSAmJiBjb250ZXh0SWQgJiYgY29udGV4dElkLnF1b3RlKSB7XG4gICAgaXNNYXRjaCA9IHdvcmQuY29udGVudC5zb21lKHdvcmRJdGVtID0+IHtcbiAgICAgIGxldCBmb3VuZE1hdGNoID0gZmFsc2U7XG5cbiAgICAgIGlmIChBcnJheS5pc0FycmF5KGNvbnRleHRJZC5xdW90ZSkpIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDAsIGwgPSBjb250ZXh0SWQucXVvdGUubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgICAgY29uc3QgcXVvdGUgPSBjb250ZXh0SWQucXVvdGVbaV07XG5cbiAgICAgICAgICBpZiAocXVvdGUud29yZCA9PT0gd29yZEl0ZW0uY29udGVudCkge1xuICAgICAgICAgICAgZm91bmRNYXRjaCA9IGRvZXNPY2N1cnJlbmNlTWF0Y2gocXVvdGUub2NjdXJyZW5jZSwgdmVyc2VXb3JkQ291bnRzLCB3b3JkSXRlbSk7XG5cbiAgICAgICAgICAgIGlmIChmb3VuZE1hdGNoKSB7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChjb250ZXh0SWQucXVvdGUuc3BsaXQoJyAnKS5pbmNsdWRlcyh3b3JkSXRlbS5jb250ZW50KSkge1xuICAgICAgICBmb3VuZE1hdGNoID0gZG9lc09jY3VycmVuY2VNYXRjaChjb250ZXh0SWQub2NjdXJyZW5jZSwgdmVyc2VXb3JkQ291bnRzLCB3b3JkSXRlbSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gZm91bmRNYXRjaDtcbiAgICB9KTtcbiAgfVxuICByZXR1cm4gaXNNYXRjaDtcbn1cblxuLyoqXG4gKiBzZWFyY2ggd29yZCBsaXN0IHRvIG1hdGNoIG9jY3VycmVuY2Ugb2Ygd29yZC4gQ291bnRzIG9jY3VycmVuY2VzIGN1cnJlbnQgd29yZCBhbmQgbWFrZXMgc3VyZSBpdCBtYXRjaGVzIG9jY3VycmVuY2VcbiAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleCAtIHBvc2l0aW9uIG9mIHdvcmQgdG8gc3RvcCBhdFxuICogQHBhcmFtIHtBcnJheX0gd29yZHMgLSBsaXN0IG9mIHdvcmQgb2JqZWN0cyB0byBzZWFyY2hcbiAqIEBwYXJhbSB7U3RyaW5nfSB3b3JkVGV4dCAtIHRleHQgdG8gbWF0Y2hcbiAqIEBwYXJhbSB7bnVtYmVyfSBvY2N1cnJlbmNlIC0gdG8gbWF0Y2ggKGlmIC0xLCB0aGVuIG1hdGNoIGFsbCBvY2N1cnJlbmNlcylcbiAqIEByZXR1cm4ge0Jvb2xlYW59IC0gdHJ1ZSBpZiBzYW1lIG9jY3VycmVuY2VcbiAqL1xuZnVuY3Rpb24gbWF0Y2hPY2N1cnJlbmNlT2ZXb3JkKGluZGV4LCB3b3Jkcywgd29yZFRleHQsIG9jY3VycmVuY2UpIHtcbi8vIGdldCBvY2N1cnJlbmNlIG9mIHdvcmRcbiAgbGV0IF9vY2N1cnJlbmNlID0gMDtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8PSBpbmRleDsgaSsrKSB7XG4gICAgY29uc3Qgd29yZEl0ZW0gPSB3b3Jkc1tpXTtcblxuICAgIGlmICgod29yZEl0ZW0udHlwZSA9PT0gJ3dvcmQnKSAmJiAod29yZEl0ZW0udGV4dCA9PT0gd29yZFRleHQpKSB7XG4gICAgICBfb2NjdXJyZW5jZSsrO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IGlzTWF0Y2ggPSAoX29jY3VycmVuY2UgPT09IG9jY3VycmVuY2UpIHx8IChvY2N1cnJlbmNlID09PSAtMSk7XG4gIHJldHVybiBpc01hdGNoO1xufVxuXG4vKipcbiAqIHNlZSBpZiB0aGlzIHdvcmQgaXMgcGFydCBvZiBxdW90ZSBmb3IgY3VycmVudCBjb250ZXh0IGlkLlxuICogQHBhcmFtIHtPYmplY3R9IHdvcmRcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0SWRcbiAqIEBwYXJhbSB7QXJyYXl9IHdvcmRzXG4gKiBAcGFyYW0ge251bWJlcn0gaW5kZXhcbiAqIEByZXR1cm4ge2Jvb2xlYW59IC0gdHJ1ZSBpZiBpbiBxdW90ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNXb3JkTWF0Y2god29yZCwgY29udGV4dElkLCB3b3JkcywgaW5kZXgpIHtcbiAgbGV0IGlzTWF0Y2ggPSBmYWxzZTtcblxuICB0cnkge1xuICAgIGlmICh3b3JkICYmIHdvcmQudGV4dCAmJiBjb250ZXh0SWQgJiYgY29udGV4dElkLnF1b3RlKSB7XG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShjb250ZXh0SWQucXVvdGUpKSB7XG4gICAgICAgIC8vIGlmIGxpc3Qgb2Ygd29yZHMgaW4gcXVvdGUgc2VlIGlmIHRoaXMgd29yZCBtYXRjaGVzIG9uZSBvZiB0aGUgd29yZHNcbiAgICAgICAgZm9yIChsZXQgaSA9IDAsIGwgPSBjb250ZXh0SWQucXVvdGUubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgICAgY29uc3QgcXVvdGUgPSBjb250ZXh0SWQucXVvdGVbaV07XG5cbiAgICAgICAgICBpZiAocXVvdGUud29yZCA9PT0gd29yZC50ZXh0KSB7XG4gICAgICAgICAgICBpc01hdGNoID0gbWF0Y2hPY2N1cnJlbmNlT2ZXb3JkKGluZGV4LCB3b3Jkcywgd29yZC50ZXh0LCBxdW90ZS5vY2N1cnJlbmNlKTtcblxuICAgICAgICAgICAgaWYgKGlzTWF0Y2gpIHtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIGlmICh3b3JkLnRleHQgJiYgd29yZC50ZXh0LmluY2x1ZGVzKCfigJknKSAmJiB3b3JkLnRleHQucmVwbGFjZSgn4oCZJywgJycpID09PSBxdW90ZS53b3JkKSB7XG4gICAgICAgICAgICBjb25zdCB3b3JkVGV4dCA9IHdvcmQudGV4dC5yZXBsYWNlKCfigJknLCAnJyk7XG4gICAgICAgICAgICAvLyBEZWVwIGNsb25pbmcgYXJyYXkgdG8gYXZvaWQgcmVmZXJlbmNpbmcgdGhlIG9sZCBhcnJheSBhZGRyZXNzIGluIG1lbW9yeVxuICAgICAgICAgICAgY29uc3QgbmV3V29yZHMgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHdvcmRzKSk7XG4gICAgICAgICAgICAvLyByZW1vdmUgYXBvc3Ryb3BoZSBmcm9tIGVhY2ggd29yZCBpbiB0aGUgd29yZHMgYXJyYXlcbiAgICAgICAgICAgIGNvbnN0IHdvcmRzV2l0aG91dEFwb3N0cm9waGUgPSBbXTtcblxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPD0gaW5kZXg7IGkrKykge1xuICAgICAgICAgICAgICBjb25zdCB3b3JkSXRlbSA9IG5ld1dvcmRzW2ldO1xuXG4gICAgICAgICAgICAgIGlmICh3b3JkSXRlbS50ZXh0ICYmIHdvcmRJdGVtLnRleHQuaW5jbHVkZXMoJ+KAmScpKSB7XG4gICAgICAgICAgICAgICAgd29yZEl0ZW0udGV4dCA9IHdvcmRJdGVtLnRleHQucmVwbGFjZSgn4oCZJywgJycpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHdvcmRzV2l0aG91dEFwb3N0cm9waGUucHVzaCh3b3JkSXRlbSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlzTWF0Y2ggPSBtYXRjaE9jY3VycmVuY2VPZldvcmQoaW5kZXgsIHdvcmRzV2l0aG91dEFwb3N0cm9waGUsIHdvcmRUZXh0LCBxdW90ZS5vY2N1cnJlbmNlKTtcblxuICAgICAgICAgICAgaWYgKGlzTWF0Y2gpIHtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2UgeyAvLyBpcyBzdHJpbmcgd2l0aCBvbmUgb3IgbW9yZSB3b3Jkc1xuICAgICAgICBjb25zdCBxdW90ZXMgPSBjb250ZXh0SWQucXVvdGUuc3BsaXQoJyAnKTtcblxuICAgICAgICBmb3IgKGxldCBpID0gMCwgbCA9IHF1b3Rlcy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgICBjb25zdCBxdW90ZSA9IHF1b3Rlc1tpXTtcblxuICAgICAgICAgIGlmIChxdW90ZSA9PT0gd29yZC50ZXh0KSB7XG4gICAgICAgICAgICBpc01hdGNoID0gbWF0Y2hPY2N1cnJlbmNlT2ZXb3JkKGluZGV4LCB3b3JkcywgcXVvdGUsIGNvbnRleHRJZC5vY2N1cnJlbmNlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGlzTWF0Y2g7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBjb25zb2xlLmVycm9yKGUpO1xuICB9XG59XG5cbi8qKlxuICogZGV0ZXJtaW5lIGhpZ2hsaWdodGluZyBmb3Igd29yZCBhbmQgcHJldmlvdXMgd2hpdGUgc3BhY2VcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0SWRcbiAqIEBwYXJhbSB7T2JqZWN0fSBwcmV2aW91c1dvcmRcbiAqIEBwYXJhbSB7T2JqZWN0fSB3b3JkXG4gKiBAcGFyYW0ge2FycmF5fSB2ZXJzZVdvcmRDb3VudHMgLSBhcnJheSBvZiB3b3JkIGNvdW50cyBmb3IgbXVsdGktdmVyc2VcbiAqIEByZXR1cm5zIHt7aXNIaWdobGlnaHRlZFdvcmQ6IGJvb2xlYW4sIGlzQmV0d2VlbkhpZ2hsaWdodGVkV29yZDogYm9vbGVhbn19XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRXb3JkSGlnaGxpZ2h0ZWREZXRhaWxzKGNvbnRleHRJZCwgcHJldmlvdXNXb3JkLCB3b3JkLCB2ZXJzZVdvcmRDb3VudHMgPSBudWxsKSB7XG4gIGNvbnN0IGlzSGlnaGxpZ2h0ZWRXb3JkID0gaXNXb3JkQXJyYXlNYXRjaCh3b3JkLCBjb250ZXh0SWQsIHZlcnNlV29yZENvdW50cyk7XG4gIGNvbnN0IGlzQmV0d2VlbkhpZ2hsaWdodGVkV29yZCA9IGlzSGlnaGxpZ2h0ZWRXb3JkICYmIHByZXZpb3VzV29yZCAmJiAhaXNFcXVhbChwcmV2aW91c1dvcmQsIHdvcmQpXG4gICAgICAmJiBpc1dvcmRBcnJheU1hdGNoKHByZXZpb3VzV29yZCwgY29udGV4dElkLCB2ZXJzZVdvcmRDb3VudHMpO1xuICByZXR1cm4ge1xuICAgIGlzSGlnaGxpZ2h0ZWRXb3JkLFxuICAgIGlzQmV0d2VlbkhpZ2hsaWdodGVkV29yZCxcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFdvcmRzRnJvbU5lc3RlZE1pbGVzdG9uZShuZXN0ZWRXb3JkcywgY29udGV4dElkLCBpbmRleCwgcHJldmlvdXNXb3JkLCB3b3JkU3BhY2luZywgZm9udENsYXNzLCB2ZXJzZVdvcmRDb3VudHMpIHtcbiAgLy8gaWYgaXRzIGFuIGFycmF5IG9mIGFuIGFycmF5IHRodXMgZ2V0IGRlZXAgbmVzdGVkIHdvcmRzIGFycmF5LlxuICBpZiAoQXJyYXkuaXNBcnJheShuZXN0ZWRXb3Jkc1swXSkpIHtcbiAgICBuZXN0ZWRXb3JkcyA9IGdldERlZXBOZXN0ZWRXb3JkcyhuZXN0ZWRXb3Jkcyk7XG4gIH1cblxuICBsZXQgaXNIaWdobGlnaHRlZFdvcmQgPSBmYWxzZTtcbiAgbGV0IGlzQmV0d2VlbkhpZ2hsaWdodGVkV29yZCA9IGZhbHNlO1xuICBsZXQgbmVzdGVkUHJldmlvdXNXb3JkID0gcHJldmlvdXNXb3JkO1xuICBsZXQgbmVzdGVkV29yZFNwYWNpbmcgPSB3b3JkU3BhY2luZztcbiAgY29uc3Qgd29yZFNwYW5zID1bXTtcblxuICBmb3IgKGxldCBpID0gMCwgbGVuID0gbmVzdGVkV29yZHMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICBjb25zdCBuZXN0ZWRXb3JkID0gbmVzdGVkV29yZHNbaV07XG4gICAgY29uc3QgbmVzdGVkV29yZEluZGV4ID0gaTtcbiAgICBjb25zdCB3b3Jkc0FycmF5ID0gbmVzdGVkV29yZHM7XG5cbiAgICBjb25zdCBuZXN0ZWRXb3JkU3BhbkluZGV4ID0gYCR7aW5kZXgudG9TdHJpbmcoKX1fJHtuZXN0ZWRXb3JkSW5kZXgudG9TdHJpbmcoKX1fJHtuZXN0ZWRXb3JkLnRleHR9YDtcbiAgICBjb25zdCBuZXN0ZWROZXh0V29yZCA9IHdvcmRzQXJyYXlbaW5kZXggKyAxXTtcblxuICAgIGlmIChpc1dvcmQobmVzdGVkV29yZCkpIHtcbiAgICAgIGxldCBwYWRkaW5nID0gbmVzdGVkV29yZFNwYWNpbmc7XG4gICAgICBuZXN0ZWRXb3JkU3BhY2luZyA9ICcgJzsgLy8gc3BhY2luZyBiZXR3ZWVuIHdvcmRzXG5cbiAgICAgIGlmIChuZXN0ZWRQcmV2aW91c1dvcmQgJiYgaXNQdW50dWF0aW9uQW5kTmVlZHNOb1NwYWNlKG5lc3RlZFByZXZpb3VzV29yZCkpIHtcbiAgICAgICAgcGFkZGluZyA9ICcnO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBoaWdobGlnaHRlZERldGFpbHMgPSBnZXRXb3JkSGlnaGxpZ2h0ZWREZXRhaWxzKFxuICAgICAgICBjb250ZXh0SWQsXG4gICAgICAgIG5lc3RlZFByZXZpb3VzV29yZCxcbiAgICAgICAgbmVzdGVkV29yZCxcbiAgICAgICAgdmVyc2VXb3JkQ291bnRzLFxuICAgICAgKTtcbiAgICAgIGlzSGlnaGxpZ2h0ZWRXb3JkID0gaGlnaGxpZ2h0ZWREZXRhaWxzLmlzSGlnaGxpZ2h0ZWRXb3JkO1xuICAgICAgaXNCZXR3ZWVuSGlnaGxpZ2h0ZWRXb3JkID0gaGlnaGxpZ2h0ZWREZXRhaWxzLmlzQmV0d2VlbkhpZ2hsaWdodGVkV29yZDtcbiAgICAgIG5lc3RlZFByZXZpb3VzV29yZCA9IG5lc3RlZFdvcmQ7XG4gICAgICBjb25zdCBwYWRkaW5nU3BhblN0eWxlID0geyBiYWNrZ3JvdW5kQ29sb3I6IGlzQmV0d2VlbkhpZ2hsaWdodGVkV29yZCA/ICd2YXIoLS1oaWdobGlnaHQtY29sb3IpJyA6ICd0cmFuc3BhcmVudCcgfTtcblxuICAgICAgd29yZFNwYW5zLnB1c2goXG4gICAgICAgIDxzcGFuIGtleT17bmVzdGVkV29yZFNwYW5JbmRleC50b1N0cmluZygpfT5cbiAgICAgICAgICA8c3BhbiBzdHlsZT17cGFkZGluZ1NwYW5TdHlsZX0+XG4gICAgICAgICAgICB7cGFkZGluZ31cbiAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgPHNwYW4gY2xhc3NOYW1lPXtmb250Q2xhc3N9IHN0eWxlPXt7IGJhY2tncm91bmRDb2xvcjogaXNIaWdobGlnaHRlZFdvcmQgPyAndmFyKC0taGlnaGxpZ2h0LWNvbG9yKScgOiAnJyB9fT5cbiAgICAgICAgICAgIHtyZW1vdmVNYXJrZXIobmVzdGVkV29yZC50ZXh0KX1cbiAgICAgICAgICA8L3NwYW4+XG4gICAgICAgIDwvc3Bhbj4sXG4gICAgICApO1xuICAgIH0gZWxzZSBpZiAobmVzdGVkV29yZC50ZXh0KSB7XG4gICAgICBuZXN0ZWRXb3JkU3BhY2luZyA9IHB1bmN0dWF0aW9uV29yZFNwYWNpbmcobmVzdGVkV29yZCk7IC8vIHNwYWNpbmcgYmVmb3JlIHdvcmRzXG4gICAgICBjb25zdCB0ZXh0ID0gcmVtb3ZlTWFya2VyKG5lc3RlZFdvcmQudGV4dCk7XG5cbiAgICAgIGlmIChpc1B1bmN0dWF0aW9uSGlnaGxpZ2h0ZWQobmVzdGVkUHJldmlvdXNXb3JkLCBuZXN0ZWROZXh0V29yZCwgY29udGV4dElkLCB2ZXJzZVdvcmRDb3VudHMpKSB7XG4gICAgICAgIHdvcmRTcGFucy5wdXNoKFxuICAgICAgICAgIDxzcGFuIGtleT17bmVzdGVkV29yZFNwYW5JbmRleH0gY2xhc3NOYW1lPXtmb250Q2xhc3N9IHN0eWxlPXt7IGJhY2tncm91bmRDb2xvcjogJ3ZhcigtLWhpZ2hsaWdodC1jb2xvciknIH19PlxuICAgICAgICAgICAge3RleHR9XG4gICAgICAgICAgPC9zcGFuPixcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHdvcmRTcGFucy5wdXNoKFxuICAgICAgICAgIDxzcGFuIGNsYXNzTmFtZT17Zm9udENsYXNzfSBrZXk9e25lc3RlZFdvcmRTcGFuSW5kZXh9PlxuICAgICAgICAgICAge3RleHR9XG4gICAgICAgICAgPC9zcGFuPixcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4ge1xuICAgIHdvcmRTcGFucyxcbiAgICBuZXN0ZWRQcmV2aW91c1dvcmQsXG4gICAgbmVzdGVkV29yZFNwYWNpbmcsXG4gIH07XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lcyBpZiB0aGUgcHJldmlvdXMgd29yZCBpcyBhIHB1bmN0dWF0aW9uIHRoYXRcbiAqIGRvZXNudCBuZWVkIHNwYWNpbmcgYWZ0ZXIgaXQuXG4gKiBAcGFyYW0ge09iamVjdH0gd29yZE9iamVjdFxuICovXG5mdW5jdGlvbiBpc1B1bnR1YXRpb25BbmROZWVkc05vU3BhY2Uod29yZE9iamVjdCkge1xuICByZXR1cm4gIWlzV29yZCh3b3JkT2JqZWN0KSAmJiAod29yZE9iamVjdC50ZXh0ID09PSAnXCInKSB8fCAod29yZE9iamVjdC50ZXh0ID09PSAnXFwnJyk7XG59XG5cbi8qKlxuICogR2V0cyBhIHdvcmRzIG9iamVjdCBhcnJheSBmcm9tIGEgZGVlcCBuZXN0ZWQgbWlsZXN0b25lLlxuICogQHBhcmFtIHthcnJheX0gbmVzdGVkV29yZHNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldERlZXBOZXN0ZWRXb3JkcyhuZXN0ZWRXb3Jkcykge1xuICBsZXQgZGVlcE5lc3RlZFdvcmRzID0gbnVsbDtcblxuICBmb3IgKGxldCBpID0gMCwgbGVuID0gbmVzdGVkV29yZHMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICBjb25zdCBuZXN0ZWRXb3JkID0gbmVzdGVkV29yZHNbaV07XG5cbiAgICBpZiAobmVzdGVkV29yZC50ZXh0KSB7XG4gICAgICBkZWVwTmVzdGVkV29yZHMgPSBuZXN0ZWRXb3JkcztcbiAgICB9IGVsc2Uge1xuICAgICAgZGVlcE5lc3RlZFdvcmRzID0gZ2V0RGVlcE5lc3RlZFdvcmRzKG5lc3RlZFdvcmQpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBkZWVwTmVzdGVkV29yZHM7XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lcyBpZiBhIHB1bmN0dWF0aW9uIHNob3VsZCBiZSBoaWdobGlnaHRlZCBvciBub3QuXG4gKiBAcGFyYW0ge29iamVjdH0gcHJldmlvdXNXb3JkXG4gKiBAcGFyYW0ge29iamVjdH0gbmV4dFdvcmRcbiAqIEBwYXJhbSB7b2JqZWN0fSBjb250ZXh0SWRcbiAqIEBwYXJhbSB7YXJyYXl9IHdvcmRzXG4gKiBAcGFyYW0ge251bWJlcn0gaW5kZXhcbiAqIEBwYXJhbSB7YXJyYXl9IHZlcnNlV29yZENvdW50cyAtIGFycmF5IG9mIHdvcmQgY291bnRzIGZvciBtdWx0aS12ZXJzZVxuICogQHJldHVybnMge2Jvb2x9IHRydWUgb3IgZmFsc2UuIGhpZ2hsaWdodGVkIG9yIG5vdCBoaWdobGlnaHRlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzUHVuY3R1YXRpb25IaWdobGlnaHRlZChwcmV2aW91c1dvcmQsIG5leHRXb3JkLCBjb250ZXh0SWQsIHdvcmRzLCBpbmRleCwgdmVyc2VXb3JkQ291bnRzID0gbnVsbCkge1xuICAvLyBoYW5kbGUgbmVzdGVkIHByZXZpb3VzIHdvcmRzXG4gIGlmIChwcmV2aW91c1dvcmQgJiYgQXJyYXkuaXNBcnJheShwcmV2aW91c1dvcmRbMF0pKSB7XG4gICAgY29uc3QgbmVzdGVkUHJldmlvdXNXb3JkID0gZ2V0RGVlcE5lc3RlZFdvcmRzKHByZXZpb3VzV29yZCk7XG4gICAgLy8gZ2V0IHRoZSBsYXN0IGl0ZW0gaW4gdGhlIGFycmF5XG4gICAgcHJldmlvdXNXb3JkID0gbmVzdGVkUHJldmlvdXNXb3JkW25lc3RlZFByZXZpb3VzV29yZC5sZW5ndGggLSAxXTtcbiAgfVxuXG4gIC8vIGhhbmRsZSBuZXN0ZWQgbmV4dCB3b3Jkc1xuICBpZiAobmV4dFdvcmQpIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShuZXh0V29yZCkgfHwgQXJyYXkuaXNBcnJheShuZXh0V29yZFswXSkpIHtcbiAgICAgIGxldCBuZXN0ZWROZXh0V29yZHMgPSBnZXREZWVwTmVzdGVkV29yZHMobmV4dFdvcmQpO1xuICAgICAgbmV4dFdvcmQgPSBuZXN0ZWROZXh0V29yZHNbMF07XG4gICAgfVxuICB9XG5cbiAgY29uc3QgaXNQcmV2aW91c1dvcmRNYXRjaCA9IHByZXZpb3VzV29yZCAmJiBwcmV2aW91c1dvcmQuY29udGVudCA/XG4gICAgaXNXb3JkQXJyYXlNYXRjaChwcmV2aW91c1dvcmQsIGNvbnRleHRJZCwgdmVyc2VXb3JkQ291bnRzKSA6IGlzV29yZE1hdGNoKHByZXZpb3VzV29yZCwgY29udGV4dElkLCB3b3JkcywgaW5kZXggLSAxKTtcbiAgY29uc3QgaXNOZXh0V29yZE1hdGNoID0gbmV4dFdvcmQgJiYgbmV4dFdvcmQuY29udGVudCA/XG4gICAgaXNXb3JkQXJyYXlNYXRjaChuZXh0V29yZCwgY29udGV4dElkLCB2ZXJzZVdvcmRDb3VudHMpIDogaXNXb3JkTWF0Y2gobmV4dFdvcmQsIGNvbnRleHRJZCwgd29yZHMsIGluZGV4ICsgMSk7XG5cbiAgaWYgKHByZXZpb3VzV29yZCAmJiBuZXh0V29yZCkge1xuICAgIHJldHVybiBpc1ByZXZpb3VzV29yZE1hdGNoICYmIGlzTmV4dFdvcmRNYXRjaDtcbiAgfSBlbHNlIGlmIChwcmV2aW91c1dvcmQpIHtcbiAgICByZXR1cm4gaXNQcmV2aW91c1dvcmRNYXRjaDtcbiAgfSBlbHNlIGlmIChuZXh0V29yZCkge1xuICAgIHJldHVybiBpc05leHRXb3JkTWF0Y2g7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbmxldCBzcGFjZUNvdW50ZXIgPSAwO1xuXG4vKipcbiAqIHB1c2hlcyBhIHNwYW4gdG8gdGhlIGFycmF5XG4gKiBAcGFyYW0ge0FycmF5fSB2ZXJzZVNwYW5cbiAqIEBwYXJhbSB7U3RyaW5nfSBmb250Q2xhc3NcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFkZFNwYWNlKHZlcnNlU3BhbiwgZm9udENsYXNzKSB7XG4gIHZlcnNlU3Bhbi5wdXNoKFxuICAgIDxzcGFuIGtleT17J3NwYWNlXycgKygrK3NwYWNlQ291bnRlcil9IGNsYXNzTmFtZT17Zm9udENsYXNzfSBzdHlsZT17eyBiYWNrZ3JvdW5kQ29sb3I6ICd0cmFuc3BhcmVudCcgfX0+XG4gICAgICB7JyAnfVxuICAgIDwvc3Bhbj4sXG4gICk7XG59XG4iXX0=