UNPKG

tc-ui-toolkit

Version:

React components used to develop tools for the desktop app translationCore

253 lines (200 loc) 27.2 kB
"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); 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 _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _react = _interopRequireWildcard(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _deepEqual = _interopRequireDefault(require("deep-equal")); var windowSelectionHelpers = _interopRequireWildcard(require("../helpers/windowSelectionHelpers")); var selectionHelpers = _interopRequireWildcard(require("../helpers/selectionHelpers")); var stringHelpers = _interopRequireWildcard(require("../helpers/stringHelpers")); 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 _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2["default"])(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2["default"])(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2["default"])(this, result); }; } function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } var DBL_CLK_TIME = 1500; // time in ms var DBL_CLK_DISTANCE = 10; // in pixels var RenderSelectionTextComponent = /*#__PURE__*/function (_Component) { (0, _inherits2["default"])(RenderSelectionTextComponent, _Component); var _super = _createSuper(RenderSelectionTextComponent); function RenderSelectionTextComponent() { (0, _classCallCheck2["default"])(this, RenderSelectionTextComponent); return _super.apply(this, arguments); } (0, _createClass2["default"])(RenderSelectionTextComponent, [{ key: "UNSAFE_componentWillMount", value: function UNSAFE_componentWillMount() { // track when the selections change to prevent false clicks of removals this.renderTimestamp = Date.now(); } }, { key: "UNSAFE_componentWillReceiveProps", value: function UNSAFE_componentWillReceiveProps(nextProps) { // track when the selections change to prevent false clicks of removals if (!(0, _deepEqual["default"])(this.props.selections, nextProps.selections)) { this.renderTimestamp = Date.now(); } } /** * get new selected text and update selections * @param {String} verseText - current verse text */ }, { key: "getSelectionText", value: function getSelectionText(verseText) { var selection = windowSelectionHelpers.getSelectionFromCurrentWindowSelection(verseText, this.doubleClick); this.addSelection(selection); } /** * keep track of mouse down events for double click calculation * @param {Object} event - mouse event from callback */ }, { key: "recordMouseDown", value: function recordMouseDown(event) { this.lastMouseDnEvent = this.mouseDnEvent; // need two mouse down events for double click calcs this.mouseDnEvent = _objectSpread({}, event); // shallow copy if (this.lastMouseDnEvent) { // if we had a previous mouse down, check if this is a double click var delta = this.mouseDnEvent.timeStamp - this.lastMouseDnEvent.timeStamp; var isDblClkTime = delta < DBL_CLK_TIME; // both clicks must be within time limit var deltaX = this.mouseDnEvent.clientX - this.lastMouseDnEvent.clientX; var isDblClkX = Math.abs(deltaX) < DBL_CLK_DISTANCE; // both clicks X change must be within limit var deltaY = this.mouseDnEvent.clientY - this.lastMouseDnEvent.clientY; var isDblClkY = Math.abs(deltaY) < DBL_CLK_DISTANCE; // both clicks Y change must be within limit this.doubleClick = isDblClkTime && isDblClkX && isDblClkY; if (this.doubleClick) { console.log("recordMouseDown() - Double Click detected"); } } } }, { key: "addSelection", value: function addSelection(selection) { var _this$props = this.props, selections = _this$props.selections, verseText = _this$props.verseText, translate = _this$props.translate, openAlertDialog = _this$props.openAlertDialog, changeSelectionsInLocalState = _this$props.changeSelectionsInLocalState; selections = selectionHelpers.addSelectionToSelections(selection, selections, verseText); // this is a good place to preview selections before saved in state if (selections.length <= this.props.maximumSelections) { changeSelectionsInLocalState(selections); } else { var message = translate('select_too_many', { maximum: this.props.maximumSelections }); openAlertDialog(message); } } }, { key: "removeSelection", value: function removeSelection(selection) { var _this$props2 = this.props, selections = _this$props2.selections, verseText = _this$props2.verseText, changeSelectionsInLocalState = _this$props2.changeSelectionsInLocalState; var newSelections = selectionHelpers.removeSelectionFromSelections(selection, selections, verseText); changeSelectionsInLocalState(newSelections); } }, { key: "inDisplayBox", value: function inDisplayBox(insideDisplayBox) { var verseText = this.props.verseText; this.setState({ inBox: insideDisplayBox }); if (!insideDisplayBox && Math.abs(window.getSelection().extentOffset - window.getSelection().baseOffset) > 0) { this.getSelectionText(verseText); } } }, { key: "verseTextSpans", value: function verseTextSpans(selections, verseText) { var _this = this; var verseTextSpans; // return var stringSplices = selectionHelpers.selectionsToStringSplices(verseText, selections); verseTextSpans = stringSplices.map(function (stringSplice, index) { var selectMode = _this.props.mode === 'select'; // use selectMode to conditionally use highlight and remove var style = { color: 'black' }; var callback = function callback() {}; if (stringSplice.selected) { style.backgroundColor = 'var(--highlight-color)'; if (selectMode) { style.cursor = 'pointer'; // only show hand if in select mode callback = function callback() { var timePassed = Date.now() - _this.renderTimestamp; // see how long between now and last selection var isRealClick = timePassed > 100; // if the click happened quicker than 100ms, it was likely false click if (isRealClick) { _this.removeSelection(stringSplice); } // actually remove since it was likely a real click }; } } var targetLanguageFontClassName = _this.props.targetLanguageFontClassName; return /*#__PURE__*/_react["default"].createElement("span", { key: index, className: targetLanguageFontClassName, style: style, onClick: callback }, stringSplice.text); }); return verseTextSpans; } }, { key: "render", value: function render() { var _this2 = this; var _this$props3 = this.props, verseText = _this$props3.verseText, selections = _this$props3.selections, targetLanguageFontClassName = _this$props3.targetLanguageFontClassName; // normalize whitespace for text rendering in order to display highlights with more than one space since html selections show one space verseText = stringHelpers.normalizeString(verseText); var verseTextSpans = /*#__PURE__*/_react["default"].createElement("span", { className: targetLanguageFontClassName }, verseText); if (selections && selections.length > 0) { verseTextSpans = this.verseTextSpans(selections, verseText); } return /*#__PURE__*/_react["default"].createElement("div", { onMouseUp: function onMouseUp() { return _this2.getSelectionText(verseText); }, onMouseDown: function onMouseDown(e) { return _this2.recordMouseDown(e); }, onMouseLeave: function onMouseLeave() { return _this2.inDisplayBox(false); }, onMouseEnter: function onMouseEnter() { return _this2.inDisplayBox(true); } }, verseTextSpans); } }]); return RenderSelectionTextComponent; }(_react.Component); RenderSelectionTextComponent.propTypes = { mode: _propTypes["default"].string.isRequired, verseText: _propTypes["default"].string.isRequired, selections: _propTypes["default"].array.isRequired, translate: _propTypes["default"].func.isRequired, maximumSelections: _propTypes["default"].number.isRequired, changeSelectionsInLocalState: _propTypes["default"].func.isRequired, openAlertDialog: _propTypes["default"].func.isRequired, targetLanguageFontClassName: _propTypes["default"].string }; var _default = RenderSelectionTextComponent; exports["default"] = _default; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9WZXJzZUNoZWNrL1JlbmRlclNlbGVjdGlvblRleHRDb21wb25lbnQvaW5kZXguanMiXSwibmFtZXMiOlsiREJMX0NMS19USU1FIiwiREJMX0NMS19ESVNUQU5DRSIsIlJlbmRlclNlbGVjdGlvblRleHRDb21wb25lbnQiLCJyZW5kZXJUaW1lc3RhbXAiLCJEYXRlIiwibm93IiwibmV4dFByb3BzIiwicHJvcHMiLCJzZWxlY3Rpb25zIiwidmVyc2VUZXh0Iiwic2VsZWN0aW9uIiwid2luZG93U2VsZWN0aW9uSGVscGVycyIsImdldFNlbGVjdGlvbkZyb21DdXJyZW50V2luZG93U2VsZWN0aW9uIiwiZG91YmxlQ2xpY2siLCJhZGRTZWxlY3Rpb24iLCJldmVudCIsImxhc3RNb3VzZURuRXZlbnQiLCJtb3VzZURuRXZlbnQiLCJkZWx0YSIsInRpbWVTdGFtcCIsImlzRGJsQ2xrVGltZSIsImRlbHRhWCIsImNsaWVudFgiLCJpc0RibENsa1giLCJNYXRoIiwiYWJzIiwiZGVsdGFZIiwiY2xpZW50WSIsImlzRGJsQ2xrWSIsImNvbnNvbGUiLCJsb2ciLCJ0cmFuc2xhdGUiLCJvcGVuQWxlcnREaWFsb2ciLCJjaGFuZ2VTZWxlY3Rpb25zSW5Mb2NhbFN0YXRlIiwic2VsZWN0aW9uSGVscGVycyIsImFkZFNlbGVjdGlvblRvU2VsZWN0aW9ucyIsImxlbmd0aCIsIm1heGltdW1TZWxlY3Rpb25zIiwibWVzc2FnZSIsIm1heGltdW0iLCJuZXdTZWxlY3Rpb25zIiwicmVtb3ZlU2VsZWN0aW9uRnJvbVNlbGVjdGlvbnMiLCJpbnNpZGVEaXNwbGF5Qm94Iiwic2V0U3RhdGUiLCJpbkJveCIsIndpbmRvdyIsImdldFNlbGVjdGlvbiIsImV4dGVudE9mZnNldCIsImJhc2VPZmZzZXQiLCJnZXRTZWxlY3Rpb25UZXh0IiwidmVyc2VUZXh0U3BhbnMiLCJzdHJpbmdTcGxpY2VzIiwic2VsZWN0aW9uc1RvU3RyaW5nU3BsaWNlcyIsIm1hcCIsInN0cmluZ1NwbGljZSIsImluZGV4Iiwic2VsZWN0TW9kZSIsIm1vZGUiLCJzdHlsZSIsImNvbG9yIiwiY2FsbGJhY2siLCJzZWxlY3RlZCIsImJhY2tncm91bmRDb2xvciIsImN1cnNvciIsInRpbWVQYXNzZWQiLCJpc1JlYWxDbGljayIsInJlbW92ZVNlbGVjdGlvbiIsInRhcmdldExhbmd1YWdlRm9udENsYXNzTmFtZSIsInRleHQiLCJzdHJpbmdIZWxwZXJzIiwibm9ybWFsaXplU3RyaW5nIiwiZSIsInJlY29yZE1vdXNlRG93biIsImluRGlzcGxheUJveCIsIkNvbXBvbmVudCIsInByb3BUeXBlcyIsIlByb3BUeXBlcyIsInN0cmluZyIsImlzUmVxdWlyZWQiLCJhcnJheSIsImZ1bmMiLCJudW1iZXIiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBRUE7O0FBQ0E7O0FBQ0E7Ozs7Ozs7Ozs7QUFFQSxJQUFNQSxZQUFZLEdBQUcsSUFBckIsQyxDQUEyQjs7QUFDM0IsSUFBTUMsZ0JBQWdCLEdBQUcsRUFBekIsQyxDQUE2Qjs7SUFFdkJDLDRCOzs7Ozs7Ozs7Ozs7Z0RBQ3dCO0FBQzFCO0FBQ0EsV0FBS0MsZUFBTCxHQUF1QkMsSUFBSSxDQUFDQyxHQUFMLEVBQXZCO0FBQ0Q7OztxREFFZ0NDLFMsRUFBVztBQUMxQztBQUNBLFVBQUksQ0FBQywyQkFBUSxLQUFLQyxLQUFMLENBQVdDLFVBQW5CLEVBQStCRixTQUFTLENBQUNFLFVBQXpDLENBQUwsRUFBMkQ7QUFDekQsYUFBS0wsZUFBTCxHQUF1QkMsSUFBSSxDQUFDQyxHQUFMLEVBQXZCO0FBQ0Q7QUFDRjtBQUVEOzs7Ozs7O3FDQUlpQkksUyxFQUFXO0FBQzFCLFVBQU1DLFNBQVMsR0FBR0Msc0JBQXNCLENBQUNDLHNDQUF2QixDQUE4REgsU0FBOUQsRUFBeUUsS0FBS0ksV0FBOUUsQ0FBbEI7QUFDQSxXQUFLQyxZQUFMLENBQWtCSixTQUFsQjtBQUNEO0FBRUQ7Ozs7Ozs7b0NBSWdCSyxLLEVBQU87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aEIsU0FLR3ZCLGNBTEgsQ0FERjtBQVNEOzs7RUEvSXdDd0IsZ0I7O0FBa0ozQ3hFLDRCQUE0QixDQUFDeUUsU0FBN0IsR0FBeUM7QUFDdkNsQixFQUFBQSxJQUFJLEVBQUVtQixzQkFBVUMsTUFBVixDQUFpQkMsVUFEZ0I7QUFFdkNyRSxFQUFBQSxTQUFTLEVBQUVtRSxzQkFBVUMsTUFBVixDQUFpQkMsVUFGVztBQUd2Q3RFLEVBQUFBLFVBQVUsRUFBRW9FLHNCQUFVRyxLQUFWLENBQWdCRCxVQUhXO0FBSXZDL0MsRUFBQUEsU0FBUyxFQUFFNkMsc0JBQVVJLElBQVYsQ0FBZUYsVUFKYTtBQUt2Q3pDLEVBQUFBLGlCQUFpQixFQUFFdUMsc0JBQVVLLE1BQVYsQ0FBaUJILFVBTEc7QUFNdkM3QyxFQUFBQSw0QkFBNEIsRUFBRTJDLHNCQUFVSSxJQUFWLENBQWVGLFVBTk47QUFPdkM5QyxFQUFBQSxlQUFlLEVBQUU0QyxzQkFBVUksSUFBVixDQUFlRixVQVBPO0FBUXZDWCxFQUFBQSwyQkFBMkIsRUFBRVMsc0JBQVVDO0FBUkEsQ0FBekM7ZUFXZTNFLDRCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFJlYWN0LCB7IENvbXBvbmVudCB9IGZyb20gJ3JlYWN0JztcbmltcG9ydCBQcm9wVHlwZXMgZnJvbSAncHJvcC10eXBlcyc7XG5pbXBvcnQgaXNFcXVhbCBmcm9tICdkZWVwLWVxdWFsJztcbi8vIGhlbHBlcnNcbmltcG9ydCAqIGFzIHdpbmRvd1NlbGVjdGlvbkhlbHBlcnMgZnJvbSAnLi4vaGVscGVycy93aW5kb3dTZWxlY3Rpb25IZWxwZXJzJztcbmltcG9ydCAqIGFzIHNlbGVjdGlvbkhlbHBlcnMgZnJvbSAnLi4vaGVscGVycy9zZWxlY3Rpb25IZWxwZXJzJztcbmltcG9ydCAqIGFzIHN0cmluZ0hlbHBlcnMgZnJvbSAnLi4vaGVscGVycy9zdHJpbmdIZWxwZXJzJztcblxuY29uc3QgREJMX0NMS19USU1FID0gMTUwMDsgLy8gdGltZSBpbiBtc1xuY29uc3QgREJMX0NMS19ESVNUQU5DRSA9IDEwOyAvLyBpbiBwaXhlbHNcblxuY2xhc3MgUmVuZGVyU2VsZWN0aW9uVGV4dENvbXBvbmVudCBleHRlbmRzIENvbXBvbmVudCB7XG4gIFVOU0FGRV9jb21wb25lbnRXaWxsTW91bnQoKSB7XG4gICAgLy8gdHJhY2sgd2hlbiB0aGUgc2VsZWN0aW9ucyBjaGFuZ2UgdG8gcHJldmVudCBmYWxzZSBjbGlja3Mgb2YgcmVtb3ZhbHNcbiAgICB0aGlzLnJlbmRlclRpbWVzdGFtcCA9IERhdGUubm93KCk7XG4gIH1cblxuICBVTlNBRkVfY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyhuZXh0UHJvcHMpIHtcbiAgICAvLyB0cmFjayB3aGVuIHRoZSBzZWxlY3Rpb25zIGNoYW5nZSB0byBwcmV2ZW50IGZhbHNlIGNsaWNrcyBvZiByZW1vdmFsc1xuICAgIGlmICghaXNFcXVhbCh0aGlzLnByb3BzLnNlbGVjdGlvbnMsIG5leHRQcm9wcy5zZWxlY3Rpb25zKSkge1xuICAgICAgdGhpcy5yZW5kZXJUaW1lc3RhbXAgPSBEYXRlLm5vdygpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBnZXQgbmV3IHNlbGVjdGVkIHRleHQgYW5kIHVwZGF0ZSBzZWxlY3Rpb25zXG4gICAqIEBwYXJhbSB7U3RyaW5nfSB2ZXJzZVRleHQgLSBjdXJyZW50IHZlcnNlIHRleHRcbiAgICovXG4gIGdldFNlbGVjdGlvblRleHQodmVyc2VUZXh0KSB7XG4gICAgY29uc3Qgc2VsZWN0aW9uID0gd2luZG93U2VsZWN0aW9uSGVscGVycy5nZXRTZWxlY3Rpb25Gcm9tQ3VycmVudFdpbmRvd1NlbGVjdGlvbih2ZXJzZVRleHQsIHRoaXMuZG91YmxlQ2xpY2spO1xuICAgIHRoaXMuYWRkU2VsZWN0aW9uKHNlbGVjdGlvbik7XG4gIH1cblxuICAvKipcbiAgICoga2VlcCB0cmFjayBvZiBtb3VzZSBkb3duIGV2ZW50cyBmb3IgZG91YmxlIGNsaWNrIGNhbGN1bGF0aW9uXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBldmVudCAtIG1vdXNlIGV2ZW50IGZyb20gY2FsbGJhY2tcbiAgICovXG4gIHJlY29yZE1vdXNlRG93bihldmVudCkge1xuICAgIHRoaXMubGFzdE1vdXNlRG5FdmVudCA9IHRoaXMubW91c2VEbkV2ZW50OyAvLyBuZWVkIHR3byBtb3VzZSBkb3duIGV2ZW50cyBmb3IgZG91YmxlIGNsaWNrIGNhbGNzXG4gICAgdGhpcy5tb3VzZURuRXZlbnQgPSB7IC4uLmV2ZW50IH07IC8vIHNoYWxsb3cgY29weVxuXG4gICAgaWYgKHRoaXMubGFzdE1vdXNlRG5FdmVudCkgeyAvLyBpZiB3ZSBoYWQgYSBwcmV2aW91cyBtb3VzZSBkb3duLCBjaGVjayBpZiB0aGlzIGlzIGEgZG91YmxlIGNsaWNrXG4gICAgICBjb25zdCBkZWx0YSA9IHRoaXMubW91c2VEbkV2ZW50LnRpbWVTdGFtcCAtIHRoaXMubGFzdE1vdXNlRG5FdmVudC50aW1lU3RhbXA7XG4gICAgICBjb25zdCBpc0RibENsa1RpbWUgPSBkZWx0YSA8IERCTF9DTEtfVElNRTsgLy8gYm90aCBjbGlja3MgbXVzdCBiZSB3aXRoaW4gdGltZSBsaW1pdFxuXG4gICAgICBjb25zdCBkZWx0YVggPSB0aGlzLm1vdXNlRG5FdmVudC5jbGllbnRYIC0gdGhpcy5sYXN0TW91c2VEbkV2ZW50LmNsaWVudFg7XG4gICAgICBjb25zdCBpc0RibENsa1ggPSBNYXRoLmFicyhkZWx0YVgpIDwgREJMX0NMS19ESVNUQU5DRTsgLy8gYm90aCBjbGlja3MgWCBjaGFuZ2UgbXVzdCBiZSB3aXRoaW4gbGltaXRcblxuICAgICAgY29uc3QgZGVsdGFZID0gdGhpcy5tb3VzZURuRXZlbnQuY2xpZW50WSAtIHRoaXMubGFzdE1vdXNlRG5FdmVudC5jbGllbnRZO1xuICAgICAgY29uc3QgaXNEYmxDbGtZID0gTWF0aC5hYnMoZGVsdGFZKSA8IERCTF9DTEtfRElTVEFOQ0U7IC8vIGJvdGggY2xpY2tzIFkgY2hhbmdlIG11c3QgYmUgd2l0aGluIGxpbWl0XG5cbiAgICAgIHRoaXMuZG91YmxlQ2xpY2sgPSBpc0RibENsa1RpbWUgJiYgaXNEYmxDbGtYICYmIGlzRGJsQ2xrWTtcblxuICAgICAgaWYgKHRoaXMuZG91YmxlQ2xpY2spIHtcbiAgICAgICAgY29uc29sZS5sb2coYHJlY29yZE1vdXNlRG93bigpIC0gRG91YmxlIENsaWNrIGRldGVjdGVkYCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgYWRkU2VsZWN0aW9uKHNlbGVjdGlvbikge1xuICAgIGxldCB7XG4gICAgICBzZWxlY3Rpb25zLFxuICAgICAgdmVyc2VUZXh0LFxuICAgICAgdHJhbnNsYXRlLFxuICAgICAgb3BlbkFsZXJ0RGlhbG9nLFxuICAgICAgY2hhbmdlU2VsZWN0aW9uc0luTG9jYWxTdGF0ZSxcbiAgICB9ID0gdGhpcy5wcm9wcztcbiAgICBzZWxlY3Rpb25zID0gc2VsZWN0aW9uSGVscGVycy5hZGRTZWxlY3Rpb25Ub1NlbGVjdGlvbnMoc2VsZWN0aW9uLCBzZWxlY3Rpb25zLCB2ZXJzZVRleHQpO1xuXG4gICAgLy8gdGhpcyBpcyBhIGdvb2QgcGxhY2UgdG8gcHJldmlldyBzZWxlY3Rpb25zIGJlZm9yZSBzYXZlZCBpbiBzdGF0ZVxuICAgIGlmIChzZWxlY3Rpb25zLmxlbmd0aCA8PSB0aGlzLnByb3BzLm1heGltdW1TZWxlY3Rpb25zKSB7XG4gICAgICBjaGFuZ2VTZWxlY3Rpb25zSW5Mb2NhbFN0YXRlKHNlbGVjdGlvbnMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBtZXNzYWdlID0gdHJhbnNsYXRlKCdzZWxlY3RfdG9vX21hbnknLCB7IG1heGltdW06IHRoaXMucHJvcHMubWF4aW11bVNlbGVjdGlvbnMgfSk7XG4gICAgICBvcGVuQWxlcnREaWFsb2cobWVzc2FnZSk7XG4gICAgfVxuICB9XG5cbiAgcmVtb3ZlU2VsZWN0aW9uKHNlbGVjdGlvbikge1xuICAgIGNvbnN0IHtcbiAgICAgIHNlbGVjdGlvbnMsXG4gICAgICB2ZXJzZVRleHQsXG4gICAgICBjaGFuZ2VTZWxlY3Rpb25zSW5Mb2NhbFN0YXRlLFxuICAgIH0gPSB0aGlzLnByb3BzO1xuICAgIGNvbnN0IG5ld1NlbGVjdGlvbnMgPSBzZWxlY3Rpb25IZWxwZXJzLnJlbW92ZVNlbGVjdGlvbkZyb21TZWxlY3Rpb25zKHNlbGVjdGlvbiwgc2VsZWN0aW9ucywgdmVyc2VUZXh0KTtcbiAgICBjaGFuZ2VTZWxlY3Rpb25zSW5Mb2NhbFN0YXRlKG5ld1NlbGVjdGlvbnMpO1xuICB9XG5cbiAgaW5EaXNwbGF5Qm94KGluc2lkZURpc3BsYXlCb3gpIHtcbiAgICBjb25zdCB7IHZlcnNlVGV4dCB9ID0gdGhpcy5wcm9wcztcbiAgICB0aGlzLnNldFN0YXRlKHsgaW5Cb3g6IGluc2lkZURpc3BsYXlCb3ggfSk7XG5cbiAgICBpZiAoIWluc2lkZURpc3BsYXlCb3ggJiYgTWF0aC5hYnMod2luZG93LmdldFNlbGVjdGlvbigpLmV4dGVudE9mZnNldCAtIHdpbmRvdy5nZXRTZWxlY3Rpb24oKS5iYXNlT2Zmc2V0KSA+IDApIHtcbiAgICAgIHRoaXMuZ2V0U2VsZWN0aW9uVGV4dCh2ZXJzZVRleHQpO1xuICAgIH1cbiAgfVxuXG4gIHZlcnNlVGV4dFNwYW5zKHNlbGVjdGlvbnMsIHZlcnNlVGV4dCkge1xuICAgIGxldCB2ZXJzZVRleHRTcGFuczsgLy8gcmV0dXJuXG4gICAgY29uc3Qgc3RyaW5nU3BsaWNlcyA9IHNlbGVjdGlvbkhlbHBlcnMuc2VsZWN0aW9uc1RvU3RyaW5nU3BsaWNlcyh2ZXJzZVRleHQsIHNlbGVjdGlvbnMpO1xuXG4gICAgdmVyc2VUZXh0U3BhbnMgPSBzdHJpbmdTcGxpY2VzLm1hcCgoc3RyaW5nU3BsaWNlLCBpbmRleCkgPT4ge1xuICAgICAgY29uc3Qgc2VsZWN0TW9kZSA9ICh0aGlzLnByb3BzLm1vZGUgPT09ICdzZWxlY3QnKTsgLy8gdXNlIHNlbGVjdE1vZGUgdG8gY29uZGl0aW9uYWxseSB1c2UgaGlnaGxpZ2h0IGFuZCByZW1vdmVcbiAgICAgIGxldCBzdHlsZSA9IHsgY29sb3I6ICdibGFjaycgfTtcblxuICAgICAgbGV0IGNhbGxiYWNrID0gKCkgPT4ge307XG5cbiAgICAgIGlmIChzdHJpbmdTcGxpY2Uuc2VsZWN0ZWQpIHtcbiAgICAgICAgc3R5bGUuYmFja2dyb3VuZENvbG9yID0gJ3ZhcigtLWhpZ2hsaWdodC1jb2xvciknO1xuXG4gICAgICAgIGlmIChzZWxlY3RNb2RlKSB7XG4gICAgICAgICAgc3R5bGUuY3Vyc29yID0gJ3BvaW50ZXInOyAvLyBvbmx5IHNob3cgaGFuZCBpZiBpbiBzZWxlY3QgbW9kZVxuICAgICAgICAgIGNhbGxiYWNrID0gKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgdGltZVBhc3NlZCA9IERhdGUubm93KCkgLSB0aGlzLnJlbmRlclRpbWVzdGFtcDsgLy8gc2VlIGhvdyBsb25nIGJldHdlZW4gbm93IGFuZCBsYXN0IHNlbGVjdGlvblxuICAgICAgICAgICAgY29uc3QgaXNSZWFsQ2xpY2sgPSB0aW1lUGFzc2VkID4gMTAwOyAvLyBpZiB0aGUgY2xpY2sgaGFwcGVuZWQgcXVpY2tlciB0aGFuIDEwMG1zLCBpdCB3YXMgbGlrZWx5IGZhbHNlIGNsaWNrXG5cbiAgICAgICAgICAgIGlmIChpc1JlYWxDbGljaykge1xuICAgICAgICAgICAgICB0aGlzLnJlbW92ZVNlbGVjdGlvbihzdHJpbmdTcGxpY2UpO1xuICAgICAgICAgICAgfSAvLyBhY3R1YWxseSByZW1vdmUgc2luY2UgaXQgd2FzIGxpa2VseSBhIHJlYWwgY2xpY2tcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHsgdGFyZ2V0TGFuZ3VhZ2VGb250Q2xhc3NOYW1lIH0gPSB0aGlzLnByb3BzO1xuXG4gICAgICByZXR1cm4gKFxuICAgICAgICA8c3BhbiBrZXk9e2luZGV4fSBjbGFzc05hbWU9e3RhcmdldExhbmd1YWdlRm9udENsYXNzTmFtZX0gc3R5bGU9e3N0eWxlfSBvbkNsaWNrPXtjYWxsYmFja30+XG4gICAgICAgICAge3N0cmluZ1NwbGljZS50ZXh0fVxuICAgICAgICA8L3NwYW4+XG4gICAgICApO1xuICAgIH0pO1xuICAgIHJldHVybiB2ZXJzZVRleHRTcGFucztcbiAgfVxuXG4gIHJlbmRlcigpIHtcbiAgICBsZXQge1xuICAgICAgdmVyc2VUZXh0LCBzZWxlY3Rpb25zLCB0YXJnZXRMYW5ndWFnZUZvbnRDbGFzc05hbWUsXG4gICAgfSA9IHRoaXMucHJvcHM7XG4gICAgLy8gbm9ybWFsaXplIHdoaXRlc3BhY2UgZm9yIHRleHQgcmVuZGVyaW5nIGluIG9yZGVyIHRvIGRpc3BsYXkgaGlnaGxpZ2h0cyB3aXRoIG1vcmUgdGhhbiBvbmUgc3BhY2Ugc2luY2UgaHRtbCBzZWxlY3Rpb25zIHNob3cgb25lIHNwYWNlXG4gICAgdmVyc2VUZXh0ID0gc3RyaW5nSGVscGVycy5ub3JtYWxpemVTdHJpbmcodmVyc2VUZXh0KTtcbiAgICBsZXQgdmVyc2VUZXh0U3BhbnMgPSA8c3BhbiBjbGFzc05hbWU9e3RhcmdldExhbmd1YWdlRm9udENsYXNzTmFtZX0+e3ZlcnNlVGV4dH08L3NwYW4+O1xuXG4gICAgaWYgKHNlbGVjdGlvbnMgJiYgc2VsZWN0aW9ucy5sZW5ndGggPiAwKSB7XG4gICAgICB2ZXJzZVRleHRTcGFucyA9IHRoaXMudmVyc2VUZXh0U3BhbnMoc2VsZWN0aW9ucywgdmVyc2VUZXh0KTtcbiAgICB9XG4gICAgcmV0dXJuIChcbiAgICAgIDxkaXZcbiAgICAgICAgb25Nb3VzZVVwPXsoKSA9PiB0aGlzLmdldFNlbGVjdGlvblRleHQodmVyc2VUZXh0KX1cbiAgICAgICAgb25Nb3VzZURvd249eyhlKSA9PiB0aGlzLnJlY29yZE1vdXNlRG93bihlKX1cbiAgICAgICAgb25Nb3VzZUxlYXZlPXsoKSA9PiB0aGlzLmluRGlzcGxheUJveChmYWxzZSl9XG4gICAgICAgIG9uTW91c2VFbnRlcj17KCkgPT4gdGhpcy5pbkRpc3BsYXlCb3godHJ1ZSl9PlxuICAgICAgICB7dmVyc2VUZXh0U3BhbnN9XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9XG59XG5cblJlbmRlclNlbGVjdGlvblRleHRDb21wb25lbnQucHJvcFR5cGVzID0ge1xuICBtb2RlOiBQcm9wVHlwZXMuc3RyaW5nLmlzUmVxdWlyZWQsXG4gIHZlcnNlVGV4dDogUHJvcFR5cGVzLnN0cmluZy5pc1JlcXVpcmVkLFxuICBzZWxlY3Rpb25zOiBQcm9wVHlwZXMuYXJyYXkuaXNSZXF1aXJlZCxcbiAgdHJhbnNsYXRlOiBQcm9wVHlwZXMuZnVuYy5pc1JlcXVpcmVkLFxuICBtYXhpbXVtU2VsZWN0aW9uczogUHJvcFR5cGVzLm51bWJlci5pc1JlcXVpcmVkLFxuICBjaGFuZ2VTZWxlY3Rpb25zSW5Mb2NhbFN0YXRlOiBQcm9wVHlwZXMuZnVuYy5pc1JlcXVpcmVkLFxuICBvcGVuQWxlcnREaWFsb2c6IFByb3BUeXBlcy5mdW5jLmlzUmVxdWlyZWQsXG4gIHRhcmdldExhbmd1YWdlRm9udENsYXNzTmFtZTogUHJvcFR5cGVzLnN0cmluZyxcbn07XG5cbmV4cG9ydCBkZWZhdWx0IFJlbmRlclNlbGVjdGlvblRleHRDb21wb25lbnQ7XG4iXX0=