UNPKG

@blueprintjs/core

Version:
245 lines (243 loc) 38.4 kB
/* * Copyright 2016 Palantir Technologies, Inc. All rights reserved. * Licensed under the BSD-3 License as modified (the “License”); you may obtain a copy * of the license at https://github.com/palantir/blueprint/blob/master/LICENSE * and https://github.com/palantir/blueprint/blob/master/PATENTS */ "use strict"; var __extends = (this && this.__extends) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; var __assign = (this && this.__assign) || Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var classNames = require("classnames"); var PureRender = require("pure-render-decorator"); var React = require("react"); var Classes = require("../../common/classes"); var Keys = require("../../common/keys"); var utils_1 = require("../../common/utils"); var BUFFER_WIDTH = 30; var EditableText = (function (_super) { __extends(EditableText, _super); function EditableText(props, context) { var _this = this; _super.call(this, props, context); this.refHandlers = { content: function (spanElement) { _this.valueElement = spanElement; }, input: function (input) { if (input != null) { input.focus(); var length_1 = input.value.length; input.setSelectionRange(_this.props.selectAllOnFocus ? 0 : length_1, length_1); } }, }; this.cancelEditing = function () { var lastValue = _this.state.lastValue; _this.setState({ isEditing: false, value: lastValue }); // invoke onCancel after onChange so consumers' onCancel can override their onChange utils_1.safeInvoke(_this.props.onChange, lastValue); utils_1.safeInvoke(_this.props.onCancel, lastValue); }; this.toggleEditing = function () { if (_this.state.isEditing) { var value = _this.state.value; _this.setState({ isEditing: false, lastValue: value, }); utils_1.safeInvoke(_this.props.onChange, value); utils_1.safeInvoke(_this.props.onConfirm, value); } else if (!_this.props.disabled) { _this.setState({ isEditing: true }); } }; this.handleFocus = function () { if (!_this.props.disabled) { _this.setState({ isEditing: true }); } }; this.handleTextChange = function (event) { var value = event.target.value; // state value should be updated only when uncontrolled if (_this.props.value == null) { _this.setState({ value: value }); } utils_1.safeInvoke(_this.props.onChange, value); }; this.handleKeyEvent = function (_a) { var ctrlKey = _a.ctrlKey, metaKey = _a.metaKey, which = _a.which; if (which === Keys.ENTER && (!_this.props.multiline || ctrlKey || metaKey)) { _this.toggleEditing(); } else if (which === Keys.ESCAPE) { _this.cancelEditing(); } }; this.state = { inputHeight: 0, inputWidth: 0, isEditing: props.isEditing === true && props.disabled === false, lastValue: getValue(props), value: getValue(props), }; } EditableText.prototype.render = function () { var _a = this.props, disabled = _a.disabled, multiline = _a.multiline; var value = (this.props.value == null ? this.state.value : this.props.value); var hasValue = (value != null && value !== ""); var classes = classNames(Classes.EDITABLE_TEXT, Classes.intentClass(this.props.intent), (_b = {}, _b[Classes.DISABLED] = disabled, _b["pt-editable-editing"] = this.state.isEditing, _b["pt-editable-placeholder"] = !hasValue, _b["pt-multiline"] = multiline, _b ), this.props.className); var contentStyle; if (multiline) { // set height only in multiline mode when not editing // otherwise we're measuring this element to determine appropriate height of text contentStyle = { height: !this.state.isEditing ? this.state.inputHeight : null }; } else { // minWidth only applies in single line mode (multiline == width 100%) contentStyle = { height: this.state.inputHeight, lineHeight: this.state.inputHeight != null ? this.state.inputHeight + "px" : null, minWidth: this.props.minWidth, }; } // make enclosing div focusable when not editing, so it can still be tabbed to focus // (when editing, input itself is focusable so div doesn't need to be) var tabIndex = this.state.isEditing || disabled ? null : 0; return (React.createElement("div", {className: classes, onFocus: this.handleFocus, tabIndex: tabIndex}, this.maybeRenderInput(value), React.createElement("span", {className: "pt-editable-content", ref: this.refHandlers.content, style: contentStyle}, hasValue ? value : this.props.placeholder))); var _b; }; EditableText.prototype.componentDidMount = function () { this.updateInputDimensions(); }; EditableText.prototype.componentDidUpdate = function (_, prevState) { if (this.state.isEditing && !prevState.isEditing) { utils_1.safeInvoke(this.props.onEdit); } this.updateInputDimensions(); }; EditableText.prototype.componentWillReceiveProps = function (nextProps) { var state = { value: getValue(nextProps) }; if (nextProps.isEditing != null) { state.isEditing = nextProps.isEditing; } if (nextProps.disabled || (nextProps.disabled == null && this.props.disabled)) { state.isEditing = false; } this.setState(state); }; EditableText.prototype.maybeRenderInput = function (value) { var multiline = this.props.multiline; if (!this.state.isEditing) { return undefined; } var props = { className: "pt-editable-input", onBlur: this.toggleEditing, onChange: this.handleTextChange, onKeyDown: this.handleKeyEvent, ref: this.refHandlers.input, style: { height: this.state.inputHeight, lineHeight: !multiline && this.state.inputHeight != null ? this.state.inputHeight + "px" : null, width: multiline ? "100%" : this.state.inputWidth, }, value: value, }; return multiline ? React.createElement("textarea", __assign({}, props)) : React.createElement("input", __assign({type: "text"}, props)); }; EditableText.prototype.updateInputDimensions = function () { if (this.valueElement != null) { var _a = this.props, maxLines = _a.maxLines, minLines = _a.minLines, minWidth = _a.minWidth, multiline = _a.multiline; var _b = this.valueElement, parentElement_1 = _b.parentElement, scrollHeight_1 = _b.scrollHeight, scrollWidth = _b.scrollWidth, textContent = _b.textContent; var lineHeight = getLineHeight(this.valueElement); // add one line to computed <span> height if text ends in newline // because <span> collapses that trailing whitespace but <textarea> shows it if (multiline && this.state.isEditing && /\n$/.test(textContent)) { scrollHeight_1 += lineHeight; } if (lineHeight > 0) { // line height could be 0 if the isNaN block from getLineHeight kicks in scrollHeight_1 = utils_1.clamp(scrollHeight_1, minLines * lineHeight, maxLines * lineHeight); } // Chrome's input caret height misaligns text so the line-height must be larger than font-size. // The computed scrollHeight must also account for a larger inherited line-height from the parent. scrollHeight_1 = Math.max(scrollHeight_1, getFontSize(this.valueElement) + 1, getLineHeight(parentElement_1)); // IE11 needs a small buffer so text does not shift prior to resizing this.setState({ inputHeight: scrollHeight_1, inputWidth: Math.max(scrollWidth + BUFFER_WIDTH, minWidth), }); // synchronizes the ::before pseudo-element's height while editing for Chrome 53 if (multiline && this.state.isEditing) { setTimeout(function () { return parentElement_1.style.height = scrollHeight_1 + "px"; }); } } }; EditableText.defaultProps = { defaultValue: "", disabled: false, maxLines: Infinity, minLines: 1, minWidth: 80, multiline: false, placeholder: "Click to Edit", }; EditableText = __decorate([ PureRender ], EditableText); return EditableText; }(React.Component)); exports.EditableText = EditableText; function getValue(props) { return props.value == null ? props.defaultValue : props.value; } function getFontSize(element) { var fontSize = getComputedStyle(element).fontSize; return fontSize === "" ? 0 : parseInt(fontSize.slice(0, -2), 10); } function getLineHeight(element) { // getComputedStyle() => 18.0001px => 18 var lineHeight = parseInt(getComputedStyle(element).lineHeight.slice(0, -2), 10); // this check will be true if line-height is a keyword like "normal" if (isNaN(lineHeight)) { // @see http://stackoverflow.com/a/18430767/6342931 var line = document.createElement("span"); line.innerHTML = "<br>"; element.appendChild(line); var singleLineHeight = element.offsetHeight; line.innerHTML = "<br><br>"; var doubleLineHeight = element.offsetHeight; element.removeChild(line); // this can return 0 in edge cases lineHeight = doubleLineHeight - singleLineHeight; } return lineHeight; } exports.EditableTextFactory = React.createFactory(EditableText); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9jb21wb25lbnRzL2VkaXRhYmxlLXRleHQvZWRpdGFibGVUZXh0LnRzeCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7R0FLRzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBRUgsSUFBWSxVQUFVLFdBQU0sWUFBWSxDQUFDLENBQUE7QUFDekMsSUFBWSxVQUFVLFdBQU0sdUJBQXVCLENBQUMsQ0FBQTtBQUNwRCxJQUFZLEtBQUssV0FBTSxPQUFPLENBQUMsQ0FBQTtBQUUvQixJQUFZLE9BQU8sV0FBTSxzQkFBc0IsQ0FBQyxDQUFBO0FBQ2hELElBQVksSUFBSSxXQUFNLG1CQUFtQixDQUFDLENBQUE7QUFFMUMsc0JBQWtDLG9CQUFvQixDQUFDLENBQUE7QUE4RXZELElBQU0sWUFBWSxHQUFHLEVBQUUsQ0FBQztBQUd4QjtJQUFrQyxnQ0FBdUQ7SUF5QnJGLHNCQUFtQixLQUEwQixFQUFFLE9BQWE7UUF6QmhFLGlCQW1NQztRQXpLTyxrQkFBTSxLQUFLLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFkbEIsZ0JBQVcsR0FBRztZQUNsQixPQUFPLEVBQUUsVUFBQyxXQUE0QjtnQkFDbEMsS0FBSSxDQUFDLFlBQVksR0FBRyxXQUFXLENBQUM7WUFDcEMsQ0FBQztZQUNELEtBQUssRUFBRSxVQUFDLEtBQTZDO2dCQUNqRCxFQUFFLENBQUMsQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQztvQkFDaEIsS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDO29CQUNOLGlDQUFNLENBQWlCO29CQUMvQixLQUFLLENBQUMsaUJBQWlCLENBQUMsS0FBSSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsR0FBRyxDQUFDLEdBQUcsUUFBTSxFQUFFLFFBQU0sQ0FBQyxDQUFDO2dCQUM5RSxDQUFDO1lBQ0wsQ0FBQztTQUNKLENBQUM7UUFnRkssa0JBQWEsR0FBRztZQUNYLHFDQUFTLENBQWdCO1lBQ2pDLEtBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFDO1lBQ3RELG9GQUFvRjtZQUNwRixrQkFBVSxDQUFDLEtBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxFQUFFLFNBQVMsQ0FBQyxDQUFDO1lBQzNDLGtCQUFVLENBQUMsS0FBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFDL0MsQ0FBQyxDQUFBO1FBRU0sa0JBQWEsR0FBRztZQUNuQixFQUFFLENBQUMsQ0FBQyxLQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7Z0JBQ2YsNkJBQUssQ0FBZ0I7Z0JBQzdCLEtBQUksQ0FBQyxRQUFRLENBQUM7b0JBQ1YsU0FBUyxFQUFFLEtBQUs7b0JBQ2hCLFNBQVMsRUFBRSxLQUFLO2lCQUNuQixDQUFDLENBQUM7Z0JBQ0gsa0JBQVUsQ0FBQyxLQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsRUFBRSxLQUFLLENBQUMsQ0FBQztnQkFDdkMsa0JBQVUsQ0FBQyxLQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUM1QyxDQUFDO1lBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO2dCQUM5QixLQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7WUFDdkMsQ0FBQztRQUNMLENBQUMsQ0FBQTtRQUVPLGdCQUFXLEdBQUc7WUFDbEIsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7Z0JBQ3ZCLEtBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztZQUN2QyxDQUFDO1FBQ0wsQ0FBQyxDQUFBO1FBRU8scUJBQWdCLEdBQUcsVUFBQyxLQUFtQztZQUMzRCxJQUFNLEtBQUssR0FBSSxLQUFLLENBQUMsTUFBMkIsQ0FBQyxLQUFLLENBQUM7WUFDdkQsdURBQXVEO1lBQ3ZELEVBQUUsQ0FBQyxDQUFDLEtBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUM7Z0JBQUMsS0FBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLFlBQUssRUFBRSxDQUFDLENBQUM7WUFBQyxDQUFDO1lBQzNELGtCQUFVLENBQUMsS0FBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDM0MsQ0FBQyxDQUFBO1FBRU8sbUJBQWMsR0FBRyxVQUFDLEVBQTZEO2dCQUEzRCxvQkFBTyxFQUFFLG9CQUFPLEVBQUUsZ0JBQUs7WUFDL0MsRUFBRSxDQUFDLENBQUMsS0FBSyxLQUFLLElBQUksQ0FBQyxLQUFLLElBQUksQ0FBQyxDQUFDLEtBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxJQUFJLE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ3hFLEtBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUN6QixDQUFDO1lBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEtBQUssS0FBSyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztnQkFDL0IsS0FBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQ3pCLENBQUM7UUFDTCxDQUFDLENBQUE7UUFwSEcsSUFBSSxDQUFDLEtBQUssR0FBRztZQUNULFdBQVcsRUFBRSxDQUFDO1lBQ2QsVUFBVSxFQUFFLENBQUM7WUFDYixTQUFTLEVBQUUsS0FBSyxDQUFDLFNBQVMsS0FBSyxJQUFJLElBQUksS0FBSyxDQUFDLFFBQVEsS0FBSyxLQUFLO1lBQy9ELFNBQVMsRUFBRSxRQUFRLENBQUMsS0FBSyxDQUFDO1lBQzFCLEtBQUssRUFBRSxRQUFRLENBQUMsS0FBSyxDQUFDO1NBQ3pCLENBQUM7SUFDTixDQUFDO0lBRU0sNkJBQU0sR0FBYjtRQUNJLElBQUEsZUFBMEMsRUFBbEMsc0JBQVEsRUFBRSx3QkFBUyxDQUFnQjtRQUMzQyxJQUFNLEtBQUssR0FBRyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxJQUFJLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQy9FLElBQU0sUUFBUSxHQUFHLENBQUMsS0FBSyxJQUFJLElBQUksSUFBSSxLQUFLLEtBQUssRUFBRSxDQUFDLENBQUM7UUFFakQsSUFBTSxPQUFPLEdBQUcsVUFBVSxDQUN0QixPQUFPLENBQUMsYUFBYSxFQUNyQixPQUFPLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEVBQ3RDO1lBQ0ksR0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLEdBQUUsUUFBUTtZQUM1Qix5QkFBcUIsR0FBRSxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVM7WUFDM0MsNkJBQXlCLEdBQUUsQ0FBQyxRQUFRO1lBQ3BDLGtCQUFjLEdBQUUsU0FBUzs7U0FDNUIsRUFDRCxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FDdkIsQ0FBQztRQUVGLElBQUksWUFBaUMsQ0FBQztRQUN0QyxFQUFFLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO1lBQ1oscURBQXFEO1lBQ3JELGlGQUFpRjtZQUNqRixZQUFZLEdBQUcsRUFBRSxNQUFNLEVBQUUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsR0FBRyxJQUFJLEVBQUUsQ0FBQztRQUNyRixDQUFDO1FBQUMsSUFBSSxDQUFDLENBQUM7WUFDSixzRUFBc0U7WUFDdEUsWUFBWSxHQUFHO2dCQUNYLE1BQU0sRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVc7Z0JBQzlCLFVBQVUsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsSUFBSSxJQUFJLEdBQU0sSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLE9BQUksR0FBRyxJQUFJO2dCQUNqRixRQUFRLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRO2FBQ2hDLENBQUM7UUFDTixDQUFDO1FBRUQsb0ZBQW9GO1FBQ3BGLHNFQUFzRTtRQUN0RSxJQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsSUFBSSxRQUFRLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQztRQUM3RCxNQUFNLENBQUMsQ0FDSCxxQkFBQyxHQUFHLElBQUMsU0FBUyxFQUFFLE9BQVEsRUFBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLFdBQVksRUFBQyxRQUFRLEVBQUUsUUFBUztZQUNsRSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxDQUFFO1lBQzlCLHFCQUFDLElBQUksSUFBQyxTQUFTLEVBQUMscUJBQXFCLEVBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsT0FBUSxFQUFDLEtBQUssRUFBRSxZQUFhLEdBQ3BGLFFBQVEsR0FBRyxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFZLENBQ3hDLENBQ0wsQ0FDVCxDQUFDOztJQUNOLENBQUM7SUFFTSx3Q0FBaUIsR0FBeEI7UUFDSSxJQUFJLENBQUMscUJBQXFCLEVBQUUsQ0FBQztJQUNqQyxDQUFDO0lBRU0seUNBQWtCLEdBQXpCLFVBQTBCLENBQXFCLEVBQUUsU0FBNkI7UUFDMUUsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztZQUMvQyxrQkFBVSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDbEMsQ0FBQztRQUNELElBQUksQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO0lBQ2pDLENBQUM7SUFFTSxnREFBeUIsR0FBaEMsVUFBaUMsU0FBNkI7UUFDMUQsSUFBTSxLQUFLLEdBQXVCLEVBQUUsS0FBSyxFQUFFLFFBQVEsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO1FBQ2pFLEVBQUUsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxTQUFTLElBQUksSUFBSSxDQUFDLENBQUUsQ0FBQztZQUMvQixLQUFLLENBQUMsU0FBUyxHQUFHLFNBQVMsQ0FBQyxTQUFTLENBQUM7UUFDMUMsQ0FBQztRQUNELEVBQUUsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxRQUFRLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxJQUFJLElBQUksSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUM1RSxLQUFLLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQztRQUM1QixDQUFDO1FBQ0QsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUN6QixDQUFDO0lBNkNPLHVDQUFnQixHQUF4QixVQUF5QixLQUFhO1FBQzFCLG9DQUFTLENBQWdCO1FBQ2pDLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO1lBQ3hCLE1BQU0sQ0FBQyxTQUFTLENBQUM7UUFDckIsQ0FBQztRQUNELElBQU0sS0FBSyxHQUE0RDtZQUNuRSxTQUFTLEVBQUUsbUJBQW1CO1lBQzlCLE1BQU0sRUFBRSxJQUFJLENBQUMsYUFBYTtZQUMxQixRQUFRLEVBQUUsSUFBSSxDQUFDLGdCQUFnQjtZQUMvQixTQUFTLEVBQUUsSUFBSSxDQUFDLGNBQWM7WUFDOUIsR0FBRyxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSztZQUMzQixLQUFLLEVBQUU7Z0JBQ0gsTUFBTSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVztnQkFDOUIsVUFBVSxFQUFFLENBQUMsU0FBUyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxJQUFJLElBQUksR0FBTSxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsT0FBSSxHQUFHLElBQUk7Z0JBQy9GLEtBQUssRUFBRSxTQUFTLEdBQUcsTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVTthQUNwRDtZQUNELFlBQUs7U0FDUixDQUFDO1FBQ0YsTUFBTSxDQUFDLFNBQVMsR0FBRyxxQkFBQyxRQUFRLGdCQUFLLEtBQUssRUFBSSxHQUFHLHFCQUFDLEtBQUssYUFBQyxJQUFJLEVBQUMsTUFBTSxHQUFLLEtBQUssRUFBSSxDQUFDO0lBQ2xGLENBQUM7SUFFTyw0Q0FBcUIsR0FBN0I7UUFDSSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsWUFBWSxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUM7WUFDNUIsSUFBQSxlQUE4RCxFQUF0RCxzQkFBUSxFQUFFLHNCQUFRLEVBQUUsc0JBQVEsRUFBRSx3QkFBUyxDQUFnQjtZQUMvRCxJQUFBLHNCQUFpRixFQUEzRSxrQ0FBYSxFQUFFLGdDQUFZLEVBQUUsNEJBQVcsRUFBRSw0QkFBVyxDQUF1QjtZQUNsRixJQUFNLFVBQVUsR0FBRyxhQUFhLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQ3BELGlFQUFpRTtZQUNqRSw0RUFBNEU7WUFDNUUsRUFBRSxDQUFDLENBQUMsU0FBUyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxJQUFJLEtBQUssQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUMvRCxjQUFZLElBQUksVUFBVSxDQUFDO1lBQy9CLENBQUM7WUFDRCxFQUFFLENBQUMsQ0FBQyxVQUFVLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDakIsd0VBQXdFO2dCQUN4RSxjQUFZLEdBQUcsYUFBSyxDQUFDLGNBQVksRUFBRSxRQUFRLEdBQUcsVUFBVSxFQUFFLFFBQVEsR0FBRyxVQUFVLENBQUMsQ0FBQztZQUNyRixDQUFDO1lBQ0QsK0ZBQStGO1lBQy9GLGtHQUFrRztZQUNsRyxjQUFZLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxjQUFZLEVBQUUsV0FBVyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLEVBQUUsYUFBYSxDQUFDLGVBQWEsQ0FBQyxDQUFDLENBQUM7WUFDeEcscUVBQXFFO1lBQ3JFLElBQUksQ0FBQyxRQUFRLENBQUM7Z0JBQ1YsV0FBVyxFQUFFLGNBQVk7Z0JBQ3pCLFVBQVUsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLFdBQVcsR0FBRyxZQUFZLEVBQUUsUUFBUSxDQUFDO2FBQzdELENBQUMsQ0FBQztZQUNILGdGQUFnRjtZQUNoRixFQUFFLENBQUMsQ0FBQyxTQUFTLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO2dCQUNwQyxVQUFVLENBQUMsY0FBTSxPQUFBLGVBQWEsQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFNLGNBQVksT0FBSSxFQUFoRCxDQUFnRCxDQUFDLENBQUM7WUFDdkUsQ0FBQztRQUNMLENBQUM7SUFDTCxDQUFDO0lBak1hLHlCQUFZLEdBQXVCO1FBQzdDLFlBQVksRUFBRSxFQUFFO1FBQ2hCLFFBQVEsRUFBRSxLQUFLO1FBQ2YsUUFBUSxFQUFFLFFBQVE7UUFDbEIsUUFBUSxFQUFFLENBQUM7UUFDWCxRQUFRLEVBQUUsRUFBRTtRQUNaLFNBQVMsRUFBRSxLQUFLO1FBQ2hCLFdBQVcsRUFBRSxlQUFlO0tBQy9CLENBQUM7SUFWTjtRQUFDLFVBQVU7b0JBQUE7SUFvTVgsbUJBQUM7QUFBRCxDQW5NQSxBQW1NQyxDQW5NaUMsS0FBSyxDQUFDLFNBQVMsR0FtTWhEO0FBbk1ZLG9CQUFZLGVBbU14QixDQUFBO0FBRUQsa0JBQWtCLEtBQXlCO0lBQ3ZDLE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxJQUFJLElBQUksR0FBRyxLQUFLLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUM7QUFDbEUsQ0FBQztBQUVELHFCQUFxQixPQUFvQjtJQUNyQyxJQUFNLFFBQVEsR0FBRyxnQkFBZ0IsQ0FBQyxPQUFPLENBQUMsQ0FBQyxRQUFRLENBQUM7SUFDcEQsTUFBTSxDQUFDLFFBQVEsS0FBSyxFQUFFLEdBQUcsQ0FBQyxHQUFHLFFBQVEsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0FBQ3JFLENBQUM7QUFFRCx1QkFBdUIsT0FBb0I7SUFDdkMsd0NBQXdDO0lBQ3hDLElBQUksVUFBVSxHQUFHLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLENBQUMsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQ2pGLG9FQUFvRTtJQUNwRSxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3BCLG1EQUFtRDtRQUNuRCxJQUFNLElBQUksR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzVDLElBQUksQ0FBQyxTQUFTLEdBQUcsTUFBTSxDQUFDO1FBQ3hCLE9BQU8sQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDMUIsSUFBTSxnQkFBZ0IsR0FBRyxPQUFPLENBQUMsWUFBWSxDQUFDO1FBQzlDLElBQUksQ0FBQyxTQUFTLEdBQUcsVUFBVSxDQUFDO1FBQzVCLElBQU0sZ0JBQWdCLEdBQUcsT0FBTyxDQUFDLFlBQVksQ0FBQztRQUM5QyxPQUFPLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzFCLGtDQUFrQztRQUNsQyxVQUFVLEdBQUcsZ0JBQWdCLEdBQUcsZ0JBQWdCLENBQUM7SUFDckQsQ0FBQztJQUNELE1BQU0sQ0FBQyxVQUFVLENBQUM7QUFDdEIsQ0FBQztBQUVZLDJCQUFtQixHQUFHLEtBQUssQ0FBQyxhQUFhLENBQUMsWUFBWSxDQUFDLENBQUMiLCJmaWxlIjoiY29tcG9uZW50cy9lZGl0YWJsZS10ZXh0L2VkaXRhYmxlVGV4dC5qcyIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gKiBDb3B5cmlnaHQgMjAxNiBQYWxhbnRpciBUZWNobm9sb2dpZXMsIEluYy4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBCU0QtMyBMaWNlbnNlIGFzIG1vZGlmaWVkICh0aGUg4oCcTGljZW5zZeKAnSk7IHlvdSBtYXkgb2J0YWluIGEgY29weVxuICogb2YgdGhlIGxpY2Vuc2UgYXQgaHR0cHM6Ly9naXRodWIuY29tL3BhbGFudGlyL2JsdWVwcmludC9ibG9iL21hc3Rlci9MSUNFTlNFXG4gKiBhbmQgaHR0cHM6Ly9naXRodWIuY29tL3BhbGFudGlyL2JsdWVwcmludC9ibG9iL21hc3Rlci9QQVRFTlRTXG4gKi9cblxuaW1wb3J0ICogYXMgY2xhc3NOYW1lcyBmcm9tIFwiY2xhc3NuYW1lc1wiO1xuaW1wb3J0ICogYXMgUHVyZVJlbmRlciBmcm9tIFwicHVyZS1yZW5kZXItZGVjb3JhdG9yXCI7XG5pbXBvcnQgKiBhcyBSZWFjdCBmcm9tIFwicmVhY3RcIjtcblxuaW1wb3J0ICogYXMgQ2xhc3NlcyBmcm9tIFwiLi4vLi4vY29tbW9uL2NsYXNzZXNcIjtcbmltcG9ydCAqIGFzIEtleXMgZnJvbSBcIi4uLy4uL2NvbW1vbi9rZXlzXCI7XG5pbXBvcnQgeyBJSW50ZW50UHJvcHMsIElQcm9wcyB9IGZyb20gXCIuLi8uLi9jb21tb24vcHJvcHNcIjtcbmltcG9ydCB7IGNsYW1wLCBzYWZlSW52b2tlIH0gZnJvbSBcIi4uLy4uL2NvbW1vbi91dGlsc1wiO1xuXG5leHBvcnQgaW50ZXJmYWNlIElFZGl0YWJsZVRleHRQcm9wcyBleHRlbmRzIElJbnRlbnRQcm9wcywgSVByb3BzIHtcbiAgICAvKiogRGVmYXVsdCB0ZXh0IHZhbHVlIG9mIHVuY29udHJvbGxlZCBpbnB1dC4gKi9cbiAgICBkZWZhdWx0VmFsdWU/OiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRoZSB0ZXh0IGNhbiBiZSBlZGl0ZWQuXG4gICAgICogQGRlZmF1bHQgZmFsc2VcbiAgICAgKi9cbiAgICBkaXNhYmxlZD86IGJvb2xlYW47XG5cbiAgICAvKiogV2hldGhlciB0aGUgY29tcG9uZW50IGlzIGN1cnJlbnRseSBiZWluZyBlZGl0ZWQuICovXG4gICAgaXNFZGl0aW5nPzogYm9vbGVhbjtcblxuICAgIC8qKiBNaW5pbXVtIHdpZHRoIGluIHBpeGVscyBvZiB0aGUgaW5wdXQsIHdoZW4gbm90IGBtdWx0aWxpbmVgLiAqL1xuICAgIG1pbldpZHRoPzogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogV2hldGhlciB0aGUgY29tcG9uZW50IHN1cHBvcnRzIG11bHRpcGxlIGxpbmVzIG9mIHRleHQuXG4gICAgICogVGhpcyBwcm9wIHNob3VsZCBub3QgYmUgY2hhbmdlZCBkdXJpbmcgdGhlIGNvbXBvbmVudCdzIGxpZmV0aW1lLlxuICAgICAqIEBkZWZhdWx0IGZhbHNlXG4gICAgICovXG4gICAgbXVsdGlsaW5lPzogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIE1heGltdW0gbnVtYmVyIG9mIGxpbmVzIGJlZm9yZSBzY3JvbGxpbmcgYmVnaW5zLCB3aGVuIGBtdWx0aWxpbmVgLlxuICAgICAqL1xuICAgIG1heExpbmVzPzogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICogTWluaW11bSBudW1iZXIgb2YgbGluZXMgKGVzc2VudGlhbGx5IG1pbmltdW0gaGVpZ2h0KSwgd2hlbiBgbXVsdGlsaW5lYC5cbiAgICAgKiBAZGVmYXVsdCAxXG4gICAgICovXG4gICAgbWluTGluZXM/OiBudW1iZXI7XG5cbiAgICAvKipcbiAgICAgKiBQbGFjZWhvbGRlciB0ZXh0IHdoZW4gdGhlcmUgaXMgbm8gdmFsdWUuXG4gICAgICogQGRlZmF1bHQgXCJDbGljayB0byBFZGl0XCJcbiAgICAgKi9cbiAgICBwbGFjZWhvbGRlcj86IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIGVudGlyZSB0ZXh0IGZpZWxkIHNob3VsZCBiZSBzZWxlY3RlZCBvbiBmb2N1cy5cbiAgICAgKiBJZiBmYWxzZSwgdGhlIGN1cnNvciBpcyBwbGFjZWQgYXQgdGhlIGVuZCBvZiB0aGUgdGV4dC5cbiAgICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgICAqL1xuICAgIHNlbGVjdEFsbE9uRm9jdXM/OiBib29sZWFuO1xuXG4gICAgLyoqIFRleHQgdmFsdWUgb2YgY29udHJvbGxlZCBpbnB1dC4gKi9cbiAgICB2YWx1ZT86IHN0cmluZztcblxuICAgIC8qKiBDYWxsYmFjayBpbnZva2VkIHdoZW4gdXNlciBjYW5jZWxzIGlucHV0IHdpdGggdGhlIGBlc2NgIGtleS4gUmVjZWl2ZXMgbGFzdCBjb25maXJtZWQgdmFsdWUuICovXG4gICAgb25DYW5jZWw/KHZhbHVlOiBzdHJpbmcpOiB2b2lkO1xuXG4gICAgLyoqIENhbGxiYWNrIGludm9rZWQgd2hlbiB1c2VyIGNoYW5nZXMgaW5wdXQgaW4gYW55IHdheS4gKi9cbiAgICBvbkNoYW5nZT8odmFsdWU6IHN0cmluZyk6IHZvaWQ7XG5cbiAgICAvKiogQ2FsbGJhY2sgaW52b2tlZCB3aGVuIHVzZXIgY29uZmlybXMgdmFsdWUgd2l0aCBgZW50ZXJgIGtleSBvciBieSBibHVycmluZyBpbnB1dC4gKi9cbiAgICBvbkNvbmZpcm0/KHZhbHVlOiBzdHJpbmcpOiB2b2lkO1xuXG4gICAgLyoqIENhbGxiYWNrIGludm9rZWQgYWZ0ZXIgdGhlIHVzZXIgZW50ZXJzIGVkaXQgbW9kZS4gKi9cbiAgICBvbkVkaXQ/KCk6IHZvaWQ7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSUVkaXRhYmxlVGV4dFN0YXRlIHtcbiAgICAvKiogUGl4ZWwgaGVpZ2h0IG9mIHRoZSBpbnB1dCwgbWVhc3VyZWQgZnJvbSBzcGFuIHNpemUgKi9cbiAgICBpbnB1dEhlaWdodD86IG51bWJlcjtcbiAgICAvKiogUGl4ZWwgd2lkdGggb2YgdGhlIGlucHV0LCBtZWFzdXJlZCBmcm9tIHNwYW4gc2l6ZSAqL1xuICAgIGlucHV0V2lkdGg/OiBudW1iZXI7XG4gICAgLyoqIFdoZXRoZXIgdGhlIHZhbHVlIGlzIGN1cnJlbnRseSBiZWluZyBlZGl0ZWQgKi9cbiAgICBpc0VkaXRpbmc/OiBib29sZWFuO1xuICAgIC8qKiBUaGUgbGFzdCBjb25maXJtZWQgdmFsdWUgKi9cbiAgICBsYXN0VmFsdWU/OiBzdHJpbmc7XG4gICAgLyoqIFRoZSBjb250cm9sbGVkIGlucHV0IHZhbHVlLCBtYXkgYmUgZGlmZmVyZW50IGZyb20gcHJvcCBkdXJpbmcgZWRpdGluZyAqL1xuICAgIHZhbHVlPzogc3RyaW5nO1xufVxuXG5jb25zdCBCVUZGRVJfV0lEVEggPSAzMDtcblxuQFB1cmVSZW5kZXJcbmV4cG9ydCBjbGFzcyBFZGl0YWJsZVRleHQgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQ8SUVkaXRhYmxlVGV4dFByb3BzLCBJRWRpdGFibGVUZXh0U3RhdGU+IHtcbiAgICBwdWJsaWMgc3RhdGljIGRlZmF1bHRQcm9wczogSUVkaXRhYmxlVGV4dFByb3BzID0ge1xuICAgICAgICBkZWZhdWx0VmFsdWU6IFwiXCIsXG4gICAgICAgIGRpc2FibGVkOiBmYWxzZSxcbiAgICAgICAgbWF4TGluZXM6IEluZmluaXR5LFxuICAgICAgICBtaW5MaW5lczogMSxcbiAgICAgICAgbWluV2lkdGg6IDgwLFxuICAgICAgICBtdWx0aWxpbmU6IGZhbHNlLFxuICAgICAgICBwbGFjZWhvbGRlcjogXCJDbGljayB0byBFZGl0XCIsXG4gICAgfTtcblxuICAgIHByaXZhdGUgdmFsdWVFbGVtZW50OiBIVE1MU3BhbkVsZW1lbnQ7XG4gICAgcHJpdmF0ZSByZWZIYW5kbGVycyA9IHtcbiAgICAgICAgY29udGVudDogKHNwYW5FbGVtZW50OiBIVE1MU3BhbkVsZW1lbnQpID0+IHtcbiAgICAgICAgICAgIHRoaXMudmFsdWVFbGVtZW50ID0gc3BhbkVsZW1lbnQ7XG4gICAgICAgIH0sXG4gICAgICAgIGlucHV0OiAoaW5wdXQ6IEhUTUxJbnB1dEVsZW1lbnQgfCBIVE1MVGV4dEFyZWFFbGVtZW50KSA9PiB7XG4gICAgICAgICAgICBpZiAoaW5wdXQgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGlucHV0LmZvY3VzKCk7XG4gICAgICAgICAgICAgICAgY29uc3QgeyBsZW5ndGggfSA9IGlucHV0LnZhbHVlO1xuICAgICAgICAgICAgICAgIGlucHV0LnNldFNlbGVjdGlvblJhbmdlKHRoaXMucHJvcHMuc2VsZWN0QWxsT25Gb2N1cyA/IDAgOiBsZW5ndGgsIGxlbmd0aCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgfTtcblxuICAgIHB1YmxpYyBjb25zdHJ1Y3Rvcihwcm9wcz86IElFZGl0YWJsZVRleHRQcm9wcywgY29udGV4dD86IGFueSkge1xuICAgICAgICBzdXBlcihwcm9wcywgY29udGV4dCk7XG5cbiAgICAgICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgICAgICAgIGlucHV0SGVpZ2h0OiAwLFxuICAgICAgICAgICAgaW5wdXRXaWR0aDogMCxcbiAgICAgICAgICAgIGlzRWRpdGluZzogcHJvcHMuaXNFZGl0aW5nID09PSB0cnVlICYmIHByb3BzLmRpc2FibGVkID09PSBmYWxzZSxcbiAgICAgICAgICAgIGxhc3RWYWx1ZTogZ2V0VmFsdWUocHJvcHMpLFxuICAgICAgICAgICAgdmFsdWU6IGdldFZhbHVlKHByb3BzKSxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwdWJsaWMgcmVuZGVyKCkge1xuICAgICAgICBjb25zdCB7IGRpc2FibGVkLCBtdWx0aWxpbmUgfSA9IHRoaXMucHJvcHM7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gKHRoaXMucHJvcHMudmFsdWUgPT0gbnVsbCA/IHRoaXMuc3RhdGUudmFsdWUgOiB0aGlzLnByb3BzLnZhbHVlKTtcbiAgICAgICAgY29uc3QgaGFzVmFsdWUgPSAodmFsdWUgIT0gbnVsbCAmJiB2YWx1ZSAhPT0gXCJcIik7XG5cbiAgICAgICAgY29uc3QgY2xhc3NlcyA9IGNsYXNzTmFtZXMoXG4gICAgICAgICAgICBDbGFzc2VzLkVESVRBQkxFX1RFWFQsXG4gICAgICAgICAgICBDbGFzc2VzLmludGVudENsYXNzKHRoaXMucHJvcHMuaW50ZW50KSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBbQ2xhc3Nlcy5ESVNBQkxFRF06IGRpc2FibGVkLFxuICAgICAgICAgICAgICAgIFwicHQtZWRpdGFibGUtZWRpdGluZ1wiOiB0aGlzLnN0YXRlLmlzRWRpdGluZyxcbiAgICAgICAgICAgICAgICBcInB0LWVkaXRhYmxlLXBsYWNlaG9sZGVyXCI6ICFoYXNWYWx1ZSxcbiAgICAgICAgICAgICAgICBcInB0LW11bHRpbGluZVwiOiBtdWx0aWxpbmUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdGhpcy5wcm9wcy5jbGFzc05hbWUsXG4gICAgICAgICk7XG5cbiAgICAgICAgbGV0IGNvbnRlbnRTdHlsZTogUmVhY3QuQ1NTUHJvcGVydGllcztcbiAgICAgICAgaWYgKG11bHRpbGluZSkge1xuICAgICAgICAgICAgLy8gc2V0IGhlaWdodCBvbmx5IGluIG11bHRpbGluZSBtb2RlIHdoZW4gbm90IGVkaXRpbmdcbiAgICAgICAgICAgIC8vIG90aGVyd2lzZSB3ZSdyZSBtZWFzdXJpbmcgdGhpcyBlbGVtZW50IHRvIGRldGVybWluZSBhcHByb3ByaWF0ZSBoZWlnaHQgb2YgdGV4dFxuICAgICAgICAgICAgY29udGVudFN0eWxlID0geyBoZWlnaHQ6ICF0aGlzLnN0YXRlLmlzRWRpdGluZyA/IHRoaXMuc3RhdGUuaW5wdXRIZWlnaHQgOiBudWxsIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBtaW5XaWR0aCBvbmx5IGFwcGxpZXMgaW4gc2luZ2xlIGxpbmUgbW9kZSAobXVsdGlsaW5lID09IHdpZHRoIDEwMCUpXG4gICAgICAgICAgICBjb250ZW50U3R5bGUgPSB7XG4gICAgICAgICAgICAgICAgaGVpZ2h0OiB0aGlzLnN0YXRlLmlucHV0SGVpZ2h0LFxuICAgICAgICAgICAgICAgIGxpbmVIZWlnaHQ6IHRoaXMuc3RhdGUuaW5wdXRIZWlnaHQgIT0gbnVsbCA/IGAke3RoaXMuc3RhdGUuaW5wdXRIZWlnaHR9cHhgIDogbnVsbCxcbiAgICAgICAgICAgICAgICBtaW5XaWR0aDogdGhpcy5wcm9wcy5taW5XaWR0aCxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgICAvLyBtYWtlIGVuY2xvc2luZyBkaXYgZm9jdXNhYmxlIHdoZW4gbm90IGVkaXRpbmcsIHNvIGl0IGNhbiBzdGlsbCBiZSB0YWJiZWQgdG8gZm9jdXNcbiAgICAgICAgLy8gKHdoZW4gZWRpdGluZywgaW5wdXQgaXRzZWxmIGlzIGZvY3VzYWJsZSBzbyBkaXYgZG9lc24ndCBuZWVkIHRvIGJlKVxuICAgICAgICBjb25zdCB0YWJJbmRleCA9IHRoaXMuc3RhdGUuaXNFZGl0aW5nIHx8IGRpc2FibGVkID8gbnVsbCA6IDA7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT17Y2xhc3Nlc30gb25Gb2N1cz17dGhpcy5oYW5kbGVGb2N1c30gdGFiSW5kZXg9e3RhYkluZGV4fT5cbiAgICAgICAgICAgICAgICB7dGhpcy5tYXliZVJlbmRlcklucHV0KHZhbHVlKX1cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzc05hbWU9XCJwdC1lZGl0YWJsZS1jb250ZW50XCIgcmVmPXt0aGlzLnJlZkhhbmRsZXJzLmNvbnRlbnR9IHN0eWxlPXtjb250ZW50U3R5bGV9PlxuICAgICAgICAgICAgICAgICAgICB7aGFzVmFsdWUgPyB2YWx1ZSA6IHRoaXMucHJvcHMucGxhY2Vob2xkZXJ9XG4gICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgcHVibGljIGNvbXBvbmVudERpZE1vdW50KCkge1xuICAgICAgICB0aGlzLnVwZGF0ZUlucHV0RGltZW5zaW9ucygpO1xuICAgIH1cblxuICAgIHB1YmxpYyBjb21wb25lbnREaWRVcGRhdGUoXzogSUVkaXRhYmxlVGV4dFByb3BzLCBwcmV2U3RhdGU6IElFZGl0YWJsZVRleHRTdGF0ZSkge1xuICAgICAgICBpZiAodGhpcy5zdGF0ZS5pc0VkaXRpbmcgJiYgIXByZXZTdGF0ZS5pc0VkaXRpbmcpIHtcbiAgICAgICAgICAgIHNhZmVJbnZva2UodGhpcy5wcm9wcy5vbkVkaXQpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMudXBkYXRlSW5wdXREaW1lbnNpb25zKCk7XG4gICAgfVxuXG4gICAgcHVibGljIGNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMobmV4dFByb3BzOiBJRWRpdGFibGVUZXh0UHJvcHMpIHtcbiAgICAgICAgY29uc3Qgc3RhdGU6IElFZGl0YWJsZVRleHRTdGF0ZSA9IHsgdmFsdWU6IGdldFZhbHVlKG5leHRQcm9wcykgfTtcbiAgICAgICAgaWYgKG5leHRQcm9wcy5pc0VkaXRpbmcgIT0gbnVsbCkgIHtcbiAgICAgICAgICAgIHN0YXRlLmlzRWRpdGluZyA9IG5leHRQcm9wcy5pc0VkaXRpbmc7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG5leHRQcm9wcy5kaXNhYmxlZCB8fCAobmV4dFByb3BzLmRpc2FibGVkID09IG51bGwgJiYgdGhpcy5wcm9wcy5kaXNhYmxlZCkpIHtcbiAgICAgICAgICAgIHN0YXRlLmlzRWRpdGluZyA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoc3RhdGUpO1xuICAgIH1cblxuICAgIHB1YmxpYyBjYW5jZWxFZGl0aW5nID0gKCkgPT4ge1xuICAgICAgICBjb25zdCB7IGxhc3RWYWx1ZSB9ID0gdGhpcy5zdGF0ZTtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGlzRWRpdGluZzogZmFsc2UsIHZhbHVlOiBsYXN0VmFsdWUgfSk7XG4gICAgICAgIC8vIGludm9rZSBvbkNhbmNlbCBhZnRlciBvbkNoYW5nZSBzbyBjb25zdW1lcnMnIG9uQ2FuY2VsIGNhbiBvdmVycmlkZSB0aGVpciBvbkNoYW5nZVxuICAgICAgICBzYWZlSW52b2tlKHRoaXMucHJvcHMub25DaGFuZ2UsIGxhc3RWYWx1ZSk7XG4gICAgICAgIHNhZmVJbnZva2UodGhpcy5wcm9wcy5vbkNhbmNlbCwgbGFzdFZhbHVlKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgdG9nZ2xlRWRpdGluZyA9ICgpID0+IHtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUuaXNFZGl0aW5nKSB7XG4gICAgICAgICAgICBjb25zdCB7IHZhbHVlIH0gPSB0aGlzLnN0YXRlO1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgICAgaXNFZGl0aW5nOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBsYXN0VmFsdWU6IHZhbHVlLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBzYWZlSW52b2tlKHRoaXMucHJvcHMub25DaGFuZ2UsIHZhbHVlKTtcbiAgICAgICAgICAgIHNhZmVJbnZva2UodGhpcy5wcm9wcy5vbkNvbmZpcm0sIHZhbHVlKTtcbiAgICAgICAgfSBlbHNlIGlmICghdGhpcy5wcm9wcy5kaXNhYmxlZCkge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGlzRWRpdGluZzogdHJ1ZSB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgaGFuZGxlRm9jdXMgPSAoKSA9PiB7XG4gICAgICAgIGlmICghdGhpcy5wcm9wcy5kaXNhYmxlZCkge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGlzRWRpdGluZzogdHJ1ZSB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgaGFuZGxlVGV4dENoYW5nZSA9IChldmVudDogUmVhY3QuRm9ybUV2ZW50PEhUTUxFbGVtZW50PikgPT4ge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IChldmVudC50YXJnZXQgYXMgSFRNTElucHV0RWxlbWVudCkudmFsdWU7XG4gICAgICAgIC8vIHN0YXRlIHZhbHVlIHNob3VsZCBiZSB1cGRhdGVkIG9ubHkgd2hlbiB1bmNvbnRyb2xsZWRcbiAgICAgICAgaWYgKHRoaXMucHJvcHMudmFsdWUgPT0gbnVsbCkgeyB0aGlzLnNldFN0YXRlKHsgdmFsdWUgfSk7IH1cbiAgICAgICAgc2FmZUludm9rZSh0aGlzLnByb3BzLm9uQ2hhbmdlLCB2YWx1ZSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBoYW5kbGVLZXlFdmVudCA9ICh7IGN0cmxLZXksIG1ldGFLZXksIHdoaWNoIH06IFJlYWN0LktleWJvYXJkRXZlbnQ8SFRNTEVsZW1lbnQ+KSA9PiB7XG4gICAgICAgIGlmICh3aGljaCA9PT0gS2V5cy5FTlRFUiAmJiAoIXRoaXMucHJvcHMubXVsdGlsaW5lIHx8IGN0cmxLZXkgfHwgbWV0YUtleSkpIHtcbiAgICAgICAgICAgIHRoaXMudG9nZ2xlRWRpdGluZygpO1xuICAgICAgICB9IGVsc2UgaWYgKHdoaWNoID09PSBLZXlzLkVTQ0FQRSkge1xuICAgICAgICAgICAgdGhpcy5jYW5jZWxFZGl0aW5nKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIG1heWJlUmVuZGVySW5wdXQodmFsdWU6IHN0cmluZykge1xuICAgICAgICBjb25zdCB7IG11bHRpbGluZSB9ID0gdGhpcy5wcm9wcztcbiAgICAgICAgaWYgKCF0aGlzLnN0YXRlLmlzRWRpdGluZykge1xuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBwcm9wczogUmVhY3QuSFRNTFByb3BzPEhUTUxJbnB1dEVsZW1lbnQgfCBIVE1MVGV4dEFyZWFFbGVtZW50PiA9IHtcbiAgICAgICAgICAgIGNsYXNzTmFtZTogXCJwdC1lZGl0YWJsZS1pbnB1dFwiLFxuICAgICAgICAgICAgb25CbHVyOiB0aGlzLnRvZ2dsZUVkaXRpbmcsXG4gICAgICAgICAgICBvbkNoYW5nZTogdGhpcy5oYW5kbGVUZXh0Q2hhbmdlLFxuICAgICAgICAgICAgb25LZXlEb3duOiB0aGlzLmhhbmRsZUtleUV2ZW50LFxuICAgICAgICAgICAgcmVmOiB0aGlzLnJlZkhhbmRsZXJzLmlucHV0LFxuICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICBoZWlnaHQ6IHRoaXMuc3RhdGUuaW5wdXRIZWlnaHQsXG4gICAgICAgICAgICAgICAgbGluZUhlaWdodDogIW11bHRpbGluZSAmJiB0aGlzLnN0YXRlLmlucHV0SGVpZ2h0ICE9IG51bGwgPyBgJHt0aGlzLnN0YXRlLmlucHV0SGVpZ2h0fXB4YCA6IG51bGwsXG4gICAgICAgICAgICAgICAgd2lkdGg6IG11bHRpbGluZSA/IFwiMTAwJVwiIDogdGhpcy5zdGF0ZS5pbnB1dFdpZHRoLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHZhbHVlLFxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gbXVsdGlsaW5lID8gPHRleHRhcmVhIHsuLi5wcm9wc30gLz4gOiA8aW5wdXQgdHlwZT1cInRleHRcIiB7Li4ucHJvcHN9IC8+O1xuICAgIH1cblxuICAgIHByaXZhdGUgdXBkYXRlSW5wdXREaW1lbnNpb25zKCkge1xuICAgICAgICBpZiAodGhpcy52YWx1ZUVsZW1lbnQgIT0gbnVsbCkge1xuICAgICAgICAgICAgY29uc3QgeyBtYXhMaW5lcywgbWluTGluZXMsIG1pbldpZHRoLCBtdWx0aWxpbmUgfSA9IHRoaXMucHJvcHM7XG4gICAgICAgICAgICBsZXQgeyBwYXJlbnRFbGVtZW50LCBzY3JvbGxIZWlnaHQsIHNjcm9sbFdpZHRoLCB0ZXh0Q29udGVudCB9ID0gdGhpcy52YWx1ZUVsZW1lbnQ7XG4gICAgICAgICAgICBjb25zdCBsaW5lSGVpZ2h0ID0gZ2V0TGluZUhlaWdodCh0aGlzLnZhbHVlRWxlbWVudCk7XG4gICAgICAgICAgICAvLyBhZGQgb25lIGxpbmUgdG8gY29tcHV0ZWQgPHNwYW4+IGhlaWdodCBpZiB0ZXh0IGVuZHMgaW4gbmV3bGluZVxuICAgICAgICAgICAgLy8gYmVjYXVzZSA8c3Bhbj4gY29sbGFwc2VzIHRoYXQgdHJhaWxpbmcgd2hpdGVzcGFjZSBidXQgPHRleHRhcmVhPiBzaG93cyBpdFxuICAgICAgICAgICAgaWYgKG11bHRpbGluZSAmJiB0aGlzLnN0YXRlLmlzRWRpdGluZyAmJiAvXFxuJC8udGVzdCh0ZXh0Q29udGVudCkpIHtcbiAgICAgICAgICAgICAgICBzY3JvbGxIZWlnaHQgKz0gbGluZUhlaWdodDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChsaW5lSGVpZ2h0ID4gMCkge1xuICAgICAgICAgICAgICAgIC8vIGxpbmUgaGVpZ2h0IGNvdWxkIGJlIDAgaWYgdGhlIGlzTmFOIGJsb2NrIGZyb20gZ2V0TGluZUhlaWdodCBraWNrcyBpblxuICAgICAgICAgICAgICAgIHNjcm9sbEhlaWdodCA9IGNsYW1wKHNjcm9sbEhlaWdodCwgbWluTGluZXMgKiBsaW5lSGVpZ2h0LCBtYXhMaW5lcyAqIGxpbmVIZWlnaHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQ2hyb21lJ3MgaW5wdXQgY2FyZXQgaGVpZ2h0IG1pc2FsaWducyB0ZXh0IHNvIHRoZSBsaW5lLWhlaWdodCBtdXN0IGJlIGxhcmdlciB0aGFuIGZvbnQtc2l6ZS5cbiAgICAgICAgICAgIC8vIFRoZSBjb21wdXRlZCBzY3JvbGxIZWlnaHQgbXVzdCBhbHNvIGFjY291bnQgZm9yIGEgbGFyZ2VyIGluaGVyaXRlZCBsaW5lLWhlaWdodCBmcm9tIHRoZSBwYXJlbnQuXG4gICAgICAgICAgICBzY3JvbGxIZWlnaHQgPSBNYXRoLm1heChzY3JvbGxIZWlnaHQsIGdldEZvbnRTaXplKHRoaXMudmFsdWVFbGVtZW50KSArIDEsIGdldExpbmVIZWlnaHQocGFyZW50RWxlbWVudCkpO1xuICAgICAgICAgICAgLy8gSUUxMSBuZWVkcyBhIHNtYWxsIGJ1ZmZlciBzbyB0ZXh0IGRvZXMgbm90IHNoaWZ0IHByaW9yIHRvIHJlc2l6aW5nXG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgICAgICBpbnB1dEhlaWdodDogc2Nyb2xsSGVpZ2h0LFxuICAgICAgICAgICAgICAgIGlucHV0V2lkdGg6IE1hdGgubWF4KHNjcm9sbFdpZHRoICsgQlVGRkVSX1dJRFRILCBtaW5XaWR0aCksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIC8vIHN5bmNocm9uaXplcyB0aGUgOjpiZWZvcmUgcHNldWRvLWVsZW1lbnQncyBoZWlnaHQgd2hpbGUgZWRpdGluZyBmb3IgQ2hyb21lIDUzXG4gICAgICAgICAgICBpZiAobXVsdGlsaW5lICYmIHRoaXMuc3RhdGUuaXNFZGl0aW5nKSB7XG4gICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiBwYXJlbnRFbGVtZW50LnN0eWxlLmhlaWdodCA9IGAke3Njcm9sbEhlaWdodH1weGApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuXG5mdW5jdGlvbiBnZXRWYWx1ZShwcm9wczogSUVkaXRhYmxlVGV4dFByb3BzKSB7XG4gICAgcmV0dXJuIHByb3BzLnZhbHVlID09IG51bGwgPyBwcm9wcy5kZWZhdWx0VmFsdWUgOiBwcm9wcy52YWx1ZTtcbn1cblxuZnVuY3Rpb24gZ2V0Rm9udFNpemUoZWxlbWVudDogSFRNTEVsZW1lbnQpIHtcbiAgICBjb25zdCBmb250U2l6ZSA9IGdldENvbXB1dGVkU3R5bGUoZWxlbWVudCkuZm9udFNpemU7XG4gICAgcmV0dXJuIGZvbnRTaXplID09PSBcIlwiID8gMCA6IHBhcnNlSW50KGZvbnRTaXplLnNsaWNlKDAsIC0yKSwgMTApO1xufVxuXG5mdW5jdGlvbiBnZXRMaW5lSGVpZ2h0KGVsZW1lbnQ6IEhUTUxFbGVtZW50KSB7XG4gICAgLy8gZ2V0Q29tcHV0ZWRTdHlsZSgpID0+IDE4LjAwMDFweCA9PiAxOFxuICAgIGxldCBsaW5lSGVpZ2h0ID0gcGFyc2VJbnQoZ2V0Q29tcHV0ZWRTdHlsZShlbGVtZW50KS5saW5lSGVpZ2h0LnNsaWNlKDAsIC0yKSwgMTApO1xuICAgIC8vIHRoaXMgY2hlY2sgd2lsbCBiZSB0cnVlIGlmIGxpbmUtaGVpZ2h0IGlzIGEga2V5d29yZCBsaWtlIFwibm9ybWFsXCJcbiAgICBpZiAoaXNOYU4obGluZUhlaWdodCkpIHtcbiAgICAgICAgLy8gQHNlZSBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8xODQzMDc2Ny82MzQyOTMxXG4gICAgICAgIGNvbnN0IGxpbmUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic3BhblwiKTtcbiAgICAgICAgbGluZS5pbm5lckhUTUwgPSBcIjxicj5cIjtcbiAgICAgICAgZWxlbWVudC5hcHBlbmRDaGlsZChsaW5lKTtcbiAgICAgICAgY29uc3Qgc2luZ2xlTGluZUhlaWdodCA9IGVsZW1lbnQub2Zmc2V0SGVpZ2h0O1xuICAgICAgICBsaW5lLmlubmVySFRNTCA9IFwiPGJyPjxicj5cIjtcbiAgICAgICAgY29uc3QgZG91YmxlTGluZUhlaWdodCA9IGVsZW1lbnQub2Zmc2V0SGVpZ2h0O1xuICAgICAgICBlbGVtZW50LnJlbW92ZUNoaWxkKGxpbmUpO1xuICAgICAgICAvLyB0aGlzIGNhbiByZXR1cm4gMCBpbiBlZGdlIGNhc2VzXG4gICAgICAgIGxpbmVIZWlnaHQgPSBkb3VibGVMaW5lSGVpZ2h0IC0gc2luZ2xlTGluZUhlaWdodDtcbiAgICB9XG4gICAgcmV0dXJuIGxpbmVIZWlnaHQ7XG59XG5cbmV4cG9ydCBjb25zdCBFZGl0YWJsZVRleHRGYWN0b3J5ID0gUmVhY3QuY3JlYXRlRmFjdG9yeShFZGl0YWJsZVRleHQpO1xuIl0sInNvdXJjZVJvb3QiOiIvc291cmNlLyJ9