(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.ShareDialog = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } var _LabelDescriptionPanel = require('./LabelDescriptionPanel'); var _LabelDescriptionPanel2 = _interopRequireDefault(_LabelDescriptionPanel); var _NotificationPanel = require('./NotificationPanel'); var _NotificationPanel2 = _interopRequireDefault(_NotificationPanel); var _PublicLinkTemplate = require('./PublicLinkTemplate'); var _PublicLinkTemplate2 = _interopRequireDefault(_PublicLinkTemplate); var _VisibilityPanel = require('./VisibilityPanel'); var _VisibilityPanel2 = _interopRequireDefault(_VisibilityPanel); var _ShareContextConsumer = require('../ShareContextConsumer'); var _ShareContextConsumer2 = _interopRequireDefault(_ShareContextConsumer); var _mainCard = require('../main/Card'); var _mainCard2 = _interopRequireDefault(_mainCard); var React = require('react'); var ShareModel = require('pydio').requireLib('ReactModelShare'); var _require = require('material-ui'); var Divider = _require.Divider; var Panel = React.createClass({ displayName: 'Panel', propTypes: { pydio: React.PropTypes.instanceOf(Pydio), shareModel: React.PropTypes.instanceOf(ShareModel) }, render: function render() { var layoutData = ShareModel.compileLayoutData(this.props.pydio, this.props.shareModel.getNode()); var layoutPane = undefined, visibilityPanel = undefined; var _props = this.props; var style = _props.style; var props = _objectWithoutProperties(_props, ['style']); if (!this.props.shareModel.getNode().isLeaf() && layoutData.length > 1 && this.props.shareModel.hasPublicLink()) { layoutPane = React.createElement(_PublicLinkTemplate2['default'], _extends({}, props, { linkData: this.props.shareModel.getPublicLinks()[0], layoutData: layoutData })); } if (!this.props.shareModel.currentRepoIsUserScope()) { visibilityPanel = React.createElement(_VisibilityPanel2['default'], _extends({}, props, { style: { paddingBottom: 16 } })); } return React.createElement( 'div', null, React.createElement( _mainCard2['default'], { style: this.props.style, title: this.props.getMessage('486', '') }, React.createElement(_LabelDescriptionPanel2['default'], _extends({}, props, { style: { marginTop: -10 } })), React.createElement(_NotificationPanel2['default'], props), layoutPane ), visibilityPanel ); } }); exports['default'] = Panel = (0, _ShareContextConsumer2['default'])(Panel); exports['default'] = Panel; module.exports = exports['default']; },{"../ShareContextConsumer":1,"../main/Card":10,"./LabelDescriptionPanel":2,"./NotificationPanel":3,"./PublicLinkTemplate":5,"./VisibilityPanel":6,"material-ui":"material-ui","pydio":"pydio","react":"react"}],5:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } var _ShareContextConsumer = require('../ShareContextConsumer'); var _ShareContextConsumer2 = _interopRequireDefault(_ShareContextConsumer); var React = require('react'); var _require = require('material-ui'); var TextField = _require.TextField; var SelectField = _require.SelectField; var MenuItem = _require.MenuItem; var PublicLinkTemplate = React.createClass({ displayName: 'PublicLinkTemplate', propTypes: { linkData: React.PropTypes.object }, onDropDownChange: function onDropDownChange(event, index, value) { this.props.shareModel.setTemplate(this.props.linkData.hash, value); }, render: function render() { var crtLabel = undefined; var selected = this.props.shareModel.getTemplate(this.props.linkData.hash); var menuItems = this.props.layoutData.map(function (l) { if (selected && l.LAYOUT_ELEMENT === selected) { crtLabel = l.LAYOUT_LABEL; } if (!selected && !crtLabel) { selected = l.LAYOUT_ELEMENT, crtLabel = l.LAYOUT_LABEL; } return React.createElement(MenuItem, { key: l.LAYOUT_ELEMENT, value: l.LAYOUT_ELEMENT, primaryText: l.LAYOUT_LABEL }); }); var unusedLegend = React.createElement( 'div', { className: 'form-legend' }, this.props.getMessage('198') ); return React.createElement( 'div', { style: this.props.style }, React.createElement( SelectField, { fullWidth: true, value: selected, onChange: this.onDropDownChange, disabled: this.props.isReadonly(), floatingLabelText: this.props.getMessage('151') }, menuItems ) ); } }); PublicLinkTemplate = (0, _ShareContextConsumer2['default'])(PublicLinkTemplate); exports['default'] = PublicLinkTemplate; module.exports = exports['default']; },{"../ShareContextConsumer":1,"material-ui":"material-ui","react":"react"}],6:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } var _ShareContextConsumer = require('../ShareContextConsumer'); var _ShareContextConsumer2 = _interopRequireDefault(_ShareContextConsumer); var _mainCard = require('../main/Card'); var _mainCard2 = _interopRequireDefault(_mainCard); var React = require('react'); var _require = require('material-ui'); var Checkbox = _require.Checkbox; var RaisedButton = _require.RaisedButton; var TextField = _require.TextField; var VisibilityPanel = React.createClass({ displayName: 'VisibilityPanel', toggleVisibility: function toggleVisibility() { this.props.shareModel.toggleVisibility(); }, transferOwnership: function transferOwnership() { this.props.shareModel.setNewShareOwner(this.refs['newOwner'].getValue()); }, render: function render() { var currentIsOwner = this.props.shareModel.currentIsOwner(); var legend; if (this.props.shareModel.isPublic()) { if (currentIsOwner) { legend = this.props.getMessage('201'); } else { legend = this.props.getMessage('202'); } } else { legend = this.props.getMessage('206'); } var showToggle = React.createElement( 'div', null, React.createElement(Checkbox, { type: 'checkbox', name: 'share_visibility', disabled: !currentIsOwner || this.props.isReadonly(), onCheck: this.toggleVisibility, checked: this.props.shareModel.isPublic(), label: this.props.getMessage('200') }), React.createElement( 'div', { className: 'section-legend' }, legend ) ); if (this.props.shareModel.isPublic() && currentIsOwner && !this.props.isReadonly()) { var showTransfer = React.createElement( 'div', { className: 'ownership-form' }, React.createElement( 'h4', null, this.props.getMessage('203') ), React.createElement( 'div', { className: 'section-legend' }, this.props.getMessage('204') ), React.createElement( 'div', null, React.createElement(TextField, { ref: 'newOwner', floatingLabelText: this.props.getMessage('205') }), React.createElement(RaisedButton, { label: this.props.getMessage('203b'), onClick: this.transferOwnership }) ) ); } return React.createElement( _mainCard2['default'], { style: this.props.style, title: this.props.getMessage('199') }, showToggle, showTransfer ); } }); VisibilityPanel = (0, _ShareContextConsumer2['default'])(VisibilityPanel); exports['default'] = VisibilityPanel; module.exports = exports['default']; },{"../ShareContextConsumer":1,"../main/Card":10,"material-ui":"material-ui","react":"react"}],7:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } var _mainPanel = require('./main/Panel'); var _mainPanel2 = _interopRequireDefault(_mainPanel); var _publicField = require('./public/Field'); var _publicField2 = _interopRequireDefault(_publicField); var _publicPanel = require('./public/Panel'); var _publicPanel2 = _interopRequireDefault(_publicPanel); exports.MainPanel = _mainPanel2['default']; exports.PublicLinkField = _publicField2['default']; exports.PublicLinkPanel = _publicPanel2['default']; },{"./main/Panel":12,"./public/Field":13,"./public/Panel":14}],8:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var _ShareContextConsumer = require('../ShareContextConsumer'); var _ShareContextConsumer2 = _interopRequireDefault(_ShareContextConsumer); var _require = require('react'); var Component = _require.Component; var PropTypes = _require.PropTypes; var _require2 = require('material-ui'); var IconButton = _require2.IconButton; var _require3 = require('material-ui/styles'); var muiThemeable = _require3.muiThemeable; var ActionButton = (function (_Component) { _inherits(ActionButton, _Component); function ActionButton() { _classCallCheck(this, ActionButton); _get(Object.getPrototypeOf(ActionButton.prototype), 'constructor', this).apply(this, arguments); } _createClass(ActionButton, [{ key: 'render', value: function render() { var palette = this.props.muiTheme.palette; var style = { root: { borderRadius: '50%', backgroundColor: palette.primary1Color, width: 36, height: 36, padding: 8, margin: '0 6px', zIndex: 0 }, icon: { color: 'white', fontSize: 20, lineHeight: '20px' } }; return React.createElement(IconButton, { style: style.root, iconStyle: style.icon, onTouchTap: this.props.callback || this.props.onTouchTap, iconClassName: "mdi mdi-" + this.props.mdiIcon, tooltip: this.props.getMessage(this.props.messageId, this.props.messageCoreNamespace ? '' : undefined) }); } }]); return ActionButton; })(Component); ActionButton.propTypes = { callback: PropTypes.func, onTouchTap: PropTypes.func, mdiIcon: PropTypes.string, messageId: PropTypes.string }; ActionButton = (0, _ShareContextConsumer2['default'])(ActionButton); ActionButton = muiThemeable()(ActionButton); exports['default'] = ActionButton; module.exports = exports['default']; },{"../ShareContextConsumer":1,"material-ui":"material-ui","material-ui/styles":"material-ui/styles","react":"react"}],9:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } var _require = require('material-ui'); var FlatButton = _require.FlatButton; var IconButton = _require.IconButton; var ButtonsComputer = (function () { function ButtonsComputer(pydio, shareModel, buttonsUpdater, dismissCallback, getMessage) { var useIconButtons = arguments.length <= 5 || arguments[5] === undefined ? false : arguments[5]; _classCallCheck(this, ButtonsComputer); this.pydio = pydio; this._buttonsUpdater = buttonsUpdater; this._dismissCallback = dismissCallback; this._shareModel = shareModel; this._saveDisabled = false; this._getMessage = getMessage; this._iconButtons = useIconButtons; } _createClass(ButtonsComputer, [{ key: 'enableSave', value: function enableSave() { this._saveDisabled = false; this.modelUpdated(); } }, { key: 'disableSave', value: function disableSave() { this._saveDisabled = true; this.modelUpdated(); } }, { key: 'triggerModelSave', value: function triggerModelSave() { this._shareModel.save(); } }, { key: 'triggerModelRevert', value: function triggerModelRevert() { this._shareModel.revertChanges(); } }, { key: 'disableAllShare', value: function disableAllShare() { this._shareModel.stopSharing(this._dismissCallback.bind(this)); } }, { key: 'modelUpdated', value: function modelUpdated() { this._buttonsUpdater(this.getButtons()); } }, { key: 'validStatusObserver', value: function validStatusObserver(status) { if (status) this.enableSave();else this.disableSave(); } }, { key: 'start', value: function start() { this._modelObserver = this.modelUpdated.bind(this); this._disableSaveObserver = this.disableSave.bind(this); this._enableSaveObserver = this.enableSave.bind(this); this._validStatusObserver = this.validStatusObserver.bind(this); this._shareModel.observe("status_changed", this._modelObserver); this._shareModel.observe('saving', this._disableSaveObserver); this._shareModel.observe('saved', this._enableSaveObserver); this._shareModel.observe('valid_status', this._validStatusObserver); } }, { key: 'stop', value: function stop() { this._shareModel.stopObserving("status_changed", this._modelObserver); this._shareModel.stopObserving('saving', this._disableSaveObserver); this._shareModel.stopObserving('saved', this._enableSaveObserver); this._shareModel.stopObserving('valid_status', this._validStatusObserver); } }, { key: 'getButtons', value: function getButtons() { var buttons = []; var ic = this._iconButtons; if (this._shareModel.getStatus() == 'modified') { if (ic) { buttons.push(React.createElement(IconButton, { iconClassName: 'mdi mdi-undo-variant', onTouchTap: this.triggerModelRevert.bind(this), tooltip: this._getMessage('179') })); buttons.push(React.createElement(IconButton, { iconClassName: 'mdi mdi-check', secondary: true, disabled: this._saveDisabled, tooltip: this._getMessage('53', ''), onTouchTap: this.triggerModelSave.bind(this) })); buttons.push(React.createElement(IconButton, { iconClassName: 'mdi mdi-close', secondary: false, tooltip: this._getMessage('86', ''), onTouchTap: this._dismissCallback.bind(this) })); } else { buttons.push(React.createElement( 'a', { style: { cursor: 'pointer', color: 'rgba(0,0,0,0.53)' }, onClick: this.triggerModelRevert.bind(this) }, this._getMessage('179') )); buttons.push(React.createElement(FlatButton, { secondary: true, disabled: this._saveDisabled, label: this._getMessage('53', ''), onTouchTap: this.triggerModelSave.bind(this) })); buttons.push(React.createElement(FlatButton, { secondary: false, label: this._getMessage('86', ''), onTouchTap: this._dismissCallback.bind(this) })); } } else { if (this._shareModel.hasActiveShares() && this._shareModel.currentIsOwner() || this._shareModel.getStatus() === 'error' || this.pydio.user.activeRepository === "ajxp_conf") { if (ic) { buttons.push(React.createElement(IconButton, { iconClassName: 'mdi mdi-cancel', disabled: this._saveDisabled, secondary: true, tooltip: this._getMessage('6'), onTouchTap: this.disableAllShare.bind(this) })); } else { buttons.push(React.createElement(FlatButton, { disabled: this._saveDisabled, secondary: true, label: this._getMessage('6'), onTouchTap: this.disableAllShare.bind(this) })); } } if (ic) { buttons.push(React.createElement(IconButton, { iconClassName: 'mdi mdi-close', secondary: false, tooltip: this._getMessage('86', ''), onTouchTap: this._dismissCallback.bind(this) })); } else { buttons.push(React.createElement(FlatButton, { secondary: false, label: this._getMessage('86', ''), onTouchTap: this._dismissCallback.bind(this) })); } } return buttons; } }]); return ButtonsComputer; })(); exports['default'] = ButtonsComputer; module.exports = exports['default']; },{"material-ui":"material-ui"}],10:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var _require = require('react'); var Component = _require.Component; var _require2 = require('material-ui'); var Paper = _require2.Paper; var Card = (function (_Component) { _inherits(Card, _Component); function Card() { _classCallCheck(this, Card); _get(Object.getPrototypeOf(Card.prototype), 'constructor', this).apply(this, arguments); } _createClass(Card, [{ key: 'render', value: function render() { var style = { panel: _extends({ padding: 16, margin: 10 }, this.props.style), title: _extends({ paddingTop: 0, fontSize: 18 }, this.props.titleStyle) }; return React.createElement( Paper, { zDepth: 1, rounded: false, style: style.panel }, this.props.title && React.createElement( 'h3', { style: style.title }, this.props.title ), this.props.children, this.props.actions && React.createElement( 'div', { style: { textAlign: 'center', clear: 'both', position: 'relative', padding: '10px 0' } }, this.props.actions ) ); } }]); return Card; })(Component); exports['default'] = Card; module.exports = exports['default']; },{"material-ui":"material-ui","react":"react"}],11:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } var _ShareContextConsumer = require('../ShareContextConsumer'); var _ShareContextConsumer2 = _interopRequireDefault(_ShareContextConsumer); var React = require('react'); var _require = require('react-textfit'); var Textfit = _require.Textfit; var _require2 = require('material-ui/styles'); var muiThemeable = _require2.muiThemeable; var PathUtils = require('pydio/util/path'); var HeaderPanel = React.createClass({ displayName: 'HeaderPanel', render: function render() { if (this.props.noModal) { return null; } var nodePath = this.props.shareModel.getNode().getPath(); return React.createElement( 'div', { className: 'headerPanel', style: { backgroundColor: this.props.muiTheme.palette.primary1Color } }, React.createElement( Textfit, { mode: 'single', max: 30 }, this.props.getMessage('44').replace('%s', PathUtils.getBasename(nodePath)) ) ); } }); exports['default'] = HeaderPanel = (0, _ShareContextConsumer2['default'])(HeaderPanel); exports['default'] = HeaderPanel = muiThemeable()(HeaderPanel); exports['default'] = HeaderPanel; module.exports = exports['default']; },{"../ShareContextConsumer":1,"material-ui/styles":"material-ui/styles","pydio/util/path":"pydio/util/path","react":"react","react-textfit":"react-textfit"}],12:[function(require,module,exports){ (function (global){ 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); var _get = function get(_x5, _x6, _x7) { var _again = true; _function: while (_again) { var object = _x5, property = _x6, receiver = _x7; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x5 = parent; _x6 = property; _x7 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var _Header = require('./Header'); var _Header2 = _interopRequireDefault(_Header); var _publicPanel = require('../public/Panel'); var _publicPanel2 = _interopRequireDefault(_publicPanel); var _usersPanel = require('../users/Panel'); var _usersPanel2 = _interopRequireDefault(_usersPanel); var _advancedPanel = require('../advanced/Panel'); var _advancedPanel2 = _interopRequireDefault(_advancedPanel); var _ButtonsComputer = require('./ButtonsComputer'); var _ButtonsComputer2 = _interopRequireDefault(_ButtonsComputer); var React = require('react'); var _require = require('material-ui'); var Tabs = _require.Tabs; var Tab = _require.Tab; var Toggle = _require.Toggle; var _require$requireLib = require('pydio').requireLib('boot'); var ActionDialogMixin = _require$requireLib.ActionDialogMixin; var ShareModel = require('pydio').requireLib('ReactModelShare'); var _require$requireLib2 = require('pydio').requireLib('hoc'); var PaletteModifier = _require$requireLib2.PaletteModifier; var MainPanel = React.createClass({ displayName: 'MainPanel', mixins: [ActionDialogMixin], getDefaultProps: function getDefaultProps() { return { dialogTitle: '', dialogIsModal: false, dialogPadding: false }; }, propTypes: { pydio: React.PropTypes.instanceOf(Pydio).isRequired, selection: React.PropTypes.instanceOf(PydioDataModel).isRequired, readonly: React.PropTypes.bool }, childContextTypes: { messages: React.PropTypes.object, getMessage: React.PropTypes.func, isReadonly: React.PropTypes.func }, getChildContext: function getChildContext() { var messages = this.props.pydio.MessageHash; return { messages: messages, getMessage: function getMessage(messageId) { var namespace = arguments.length <= 1 || arguments[1] === undefined ? 'share_center' : arguments[1]; try { return messages[namespace + (namespace ? "." : "") + messageId] || messageId; } catch (e) { return messageId; } }, isReadonly: (function () { return this.props.readonly; }).bind(this) }; }, modelUpdated: function modelUpdated(eventData) { var _this = this; if (this.isMounted()) { var modelFirstLoad = this.state.modelFirstLoad; var afterState = undefined; if (modelFirstLoad) { afterState = function () { _this.setState({ modelFirstLoad: false }); }; } this.setState({ status: eventData.status, model: eventData.model }, afterState); } }, getInitialState: function getInitialState() { return { status: 'idle', mailerData: false, model: new ShareModel(this.props.pydio, this.props.selection.getUniqueNode(), this.props.selection), modelFirstLoad: true }; }, componentDidMount: function componentDidMount() { this.state.model.observe("status_changed", this.modelUpdated); this.state.model.initLoad(); }, componentWillUnmount: function componentWillUnmount() { if (this.buttonsComputer) this.buttonsComputer.stop(); }, componentWillReceiveProps: function componentWillReceiveProps(nextProps) { var _this2 = this; if (nextProps.selection && nextProps.selection !== this.props.selection) { var nextModel = new ShareModel(this.props.pydio, nextProps.selection.getUniqueNode(), nextProps.selection); this.setState({ model: nextModel, status: 'idle', mailerData: false }, function () { _this2.componentDidMount(); }); } }, getButtons: function getButtons(updater) { this.buttonsComputer = new _ButtonsComputer2['default'](this.props.pydio, this.state.model, updater, this.dismiss, this.getMessage, this.props.noModal); this.buttonsComputer.start(); return this.buttonsComputer.getButtons(); }, showMailer: function showMailer(subject, message) { var users = arguments.length <= 2 || arguments[2] === undefined ? [] : arguments[2]; var hash = arguments.length <= 3 || arguments[3] === undefined ? null : arguments[3]; if (ShareModel.forceMailerOldSchool()) { subject = encodeURIComponent(subject); global.location.href = "mailto:custom-email@domain.com?Subject=" + subject + "&Body=" + message; return; } var linkData = hash ? this.state.model.getLinkData(hash) : undefined; global.ResourcesManager.loadClassesAndApply(['PydioMailer'], (function () { this.setState({ mailerData: { subject: subject, message: message, users: users, hash: hash, enableIdentification: linkData && linkData.target_users, crippleIdentificationKeys: true, identifiedOnly: linkData && linkData.restrict_to_target_users } }); }).bind(this)); }, toggleMailerData: function toggleMailerData(data) { this.setState({ mailerData: _extends({}, this.state.mailerData, data) }); }, dismissMailer: function dismissMailer() { this.setState({ mailerData: false }); }, mailerProcessPost: function mailerProcessPost(Email, users, subject, message, link, callback) { var _state = this.state; var model = _state.model; var mailerData = _state.mailerData; var crippleIdentificationKeys = mailerData.crippleIdentificationKeys; var identifiedOnly = mailerData.identifiedOnly; var hash = mailerData.hash; var client = PydioApi.getClient(); var shareLabels = {}, shareMails = {}; Object.keys(users).forEach(function (u) { var k = crippleIdentificationKeys ? Math.random().toString(36).substring(7) : u; shareLabels[k] = users[u].getLabel(); shareMails[k] = u; }); // Store keys client.request({ get_action: 'share_link_update_target_users', hash: hash, json_users: JSON.stringify(shareLabels), restrict: identifiedOnly ? 'true' : 'false' }, function () { var email = new Email(); var originalLink = model.getPublicLink(hash); var regexp = new RegExp(originalLink, 'g'); Object.keys(shareMails).forEach(function (u) { var newLink = originalLink + '?u=' + u; var newMessage = message.replace(regexp, newLink); email.addTarget(shareMails[u], subject, newMessage); }); email.post(function (res) { if (res) { model.load(true); // Reload data } callback(res); }); }); }, getMessage: function getMessage(key) { var namespace = arguments.length <= 1 || arguments[1] === undefined ? 'share_center' : arguments[1]; return this.props.pydio.MessageHash[namespace + (namespace ? '.' : '') + key]; }, render: function render() { var _this3 = this; var _state2 = this.state; var model = _state2.model; var modelFirstLoad = _state2.modelFirstLoad; var buttonStyle = { textTransform: 'none' }; var showMailer = ShareModel.mailerActive() ? this.showMailer : null; var auth = ShareModel.getAuthorizations(this.props.pydio); var panels = [], hasPublicLink = undefined, initialSelectedIndex = undefined; if (model.getNode().isLeaf() && auth.file_public_link || !model.getNode().isLeaf() && auth.folder_public_link) { var publicLinks = model.getPublicLinks(); var linkData = undefined; if (publicLinks.length) { linkData = publicLinks[0]; } var pubLabel = this.getMessage(121); if (model.hasPublicLink()) { pubLabel = React.createElement( 'span', null, pubLabel, ' ', React.createElement('span', { className: 'mdi mdi-check' }) ); hasPublicLink = true; } panels.push(React.createElement( Tab, { key: 'public-link', value: 'public-link', label: pubLabel, buttonStyle: buttonStyle }, React.createElement(_publicPanel2['default'], { showMailer: showMailer, linkData: linkData, pydio: this.props.pydio, shareModel: model, authorizations: auth, style: { height: '100%', overflowY: 'auto' } }) )); } if (model.getNode().isLeaf() && auth.file_workspaces || !model.getNode().isLeaf() && auth.folder_workspaces) { var totalUsers = model.getSharedUsers().length + model.getOcsLinks().length; panels.push(React.createElement( Tab, { key: 'target-users', value: 'target-users', label: this.getMessage(249, '') + (totalUsers ? ' (' + totalUsers + ')' : ''), buttonStyle: buttonStyle }, React.createElement(_usersPanel2['default'], { showMailer: showMailer, shareModel: model, pydio: this.props.pydio, style: { height: '100%', overflowY: 'auto' } }) )); if (modelFirstLoad && !hasPublicLink && totalUsers) { initialSelectedIndex = 'target-users'; } } if (panels.length > 0) { panels.push(React.createElement( Tab, { key: 'share-permissions', value: 'share-permissions', label: this.getMessage(486, ''), buttonStyle: buttonStyle }, React.createElement(_advancedPanel2['default'], { showMailer: showMailer, pydio: this.props.pydio, shareModel: model, style: { height: '100%', overflowY: 'auto' } }) )); } var mailer = undefined; if (this.state.mailerData) { var mailerData = this.state.mailerData; var customizeMessagePane = undefined; if (mailerData.hash) { var style = mailerData.enableIdentification ? { padding: '10px 20px', backgroundColor: '#ECEFF1' } : { padding: '10px 20px 0' }; var letUserChooseCripple = this.props.pydio.getPluginConfigs('action.share').get('EMAIL_PERSONAL_LINK_SEND_CLEAR'); customizeMessagePane = React.createElement( 'div', { style: style }, React.createElement(Toggle, { label: this.getMessage(235), toggled: mailerData.enableIdentification, onToggle: function (e, c) { _this3.toggleMailerData({ enableIdentification: c }); } }), mailerData.enableIdentification && React.createElement(Toggle, { label: "-- " + this.getMessage(236), toggled: mailerData.identifiedOnly, onToggle: function (e, c) { _this3.toggleMailerData({ identifiedOnly: c }); } }), mailerData.enableIdentification && letUserChooseCripple && React.createElement(Toggle, { label: "-- " + this.getMessage(237), toggled: mailerData.crippleIdentificationKeys, onToggle: function (e, c) { _this3.toggleMailerData({ crippleIdentificationKeys: c }); } }) ); } mailer = React.createElement(PydioMailer.Pane, _extends({}, mailerData, { onDismiss: this.dismissMailer, overlay: true, className: 'share-center-mailer', panelTitle: this.props.pydio.MessageHash["share_center.45"], additionalPaneTop: customizeMessagePane, processPost: mailerData.enableIdentification ? this.mailerProcessPost : null })); } return React.createElement(Content, _extends({}, this.props, { model: this.state.model, panels: panels, mailer: mailer, initialSelectedIndex: initialSelectedIndex })); } }); var Content = (function (_React$Component) { _inherits(Content, _React$Component); function Content() { _classCallCheck(this, Content); _get(Object.getPrototypeOf(Content.prototype), 'constructor', this).apply(this, arguments); } _createClass(Content, [{ key: 'render', value: function render() { var tabStyles = { style: { flexGrow: 1, overflow: 'hidden', display: 'flex', flexDirection: 'column' }, tabItemContainerStyle: { flexShrink: 0 }, contentContainerStyle: { flexGrow: 1, overflowY: 'auto' }, tabTemplateStyle: { height: '100%', backgroundColor: '#fafafa' } }; return React.createElement( 'div', { className: 'react_share_form', style: _extends({ width: 420, display: 'flex', flexDirection: 'column' }, this.props.style) }, React.createElement(_Header2['default'], _extends({}, this.props, { shareModel: this.props.model })), React.createElement( Tabs, _extends({ value: this.props.initialSelectedIndex }, tabStyles), this.props.panels ), this.props.mailer ); } }]); return Content; })(React.Component); Content = PaletteModifier({ primary1Color: '#4aceb0' })(Content); exports['default'] = MainPanel; module.exports = exports['default']; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"../advanced/Panel":4,"../public/Panel":14,"../users/Panel":18,"./ButtonsComputer":9,"./Header":11,"material-ui":"material-ui","pydio":"pydio","react":"react"}],13:[function(require,module,exports){ (function (global){ 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } var _ShareContextConsumer = require('../ShareContextConsumer'); var _ShareContextConsumer2 = _interopRequireDefault(_ShareContextConsumer); var _TargetedUsers = require('./TargetedUsers'); var _TargetedUsers2 = _interopRequireDefault(_TargetedUsers); var _mainActionButton = require('../main/ActionButton'); var _mainActionButton2 = _interopRequireDefault(_mainActionButton); var React = require('react'); var _require = require('material-ui'); var RaisedButton = _require.RaisedButton; var FloatingActionButton = _require.FloatingActionButton; var TextField = _require.TextField; var Paper = _require.Paper; var ShareModel = require('pydio').requireLib('ReactModelShare'); var QRCode = require('qrcode.react'); var Clipboard = require('clipboard'); var PathUtils = require('pydio/util/path'); var LangUtils = require('pydio/util/lang'); var PublicLinkField = React.createClass({ displayName: 'PublicLinkField', propTypes: { linkData: React.PropTypes.object.isRequired, shareModel: React.PropTypes.instanceOf(ShareModel), editAllowed: React.PropTypes.bool, onChange: React.PropTypes.func, showMailer: React.PropTypes.func }, getInitialState: function getInitialState() { return { editLink: false, copyMessage: '', showQRCode: false }; }, toggleEditMode: function toggleEditMode() { if (this.state.editLink && this.state.customLink) { this.props.shareModel.updateCustomLink(this.props.linkData.hash, this.state.customLink); } this.setState({ editLink: !this.state.editLink }); }, changeLink: function changeLink(event) { var value = event.target.value; value = LangUtils.computeStringSlug(value); this.setState({ customLink: value }); }, clearCopyMessage: function clearCopyMessage() { global.setTimeout((function () { this.setState({ copyMessage: '' }); }).bind(this), 5000); }, attachClipboard: function attachClipboard() { this.detachClipboard(); if (this.refs['copy-button']) { this._clip = new Clipboard(this.refs['copy-button'], { text: (function (trigger) { return this.props.linkData['public_link']; }).bind(this) }); this._clip.on('success', (function () { this.setState({ copyMessage: this.props.getMessage('192') }, this.clearCopyMessage); }).bind(this)); this._clip.on('error', (function () { var copyMessage = undefined; if (global.navigator.platform.indexOf("Mac") === 0) { copyMessage = this.props.getMessage('144'); } else { copyMessage = this.props.getMessage('143'); } this.refs['public-link-field'].focus(); this.setState({ copyMessage: copyMessage }, this.clearCopyMessage); }).bind(this)); } }, detachClipboard: function detachClipboard() { if (this._clip) { this._clip.destroy(); } }, componentDidUpdate: function componentDidUpdate(prevProps, prevState) { this.attachClipboard(); }, componentDidMount: function componentDidMount() { this.attachClipboard(); }, componentWillUnmount: function componentWillUnmount() { this.detachClipboard(); }, openMailer: function openMailer() { var mailData = this.props.shareModel.prepareEmail("link", this.props.linkData.hash); this.props.showMailer(mailData.subject, mailData.message, [], this.props.linkData.hash); }, toggleQRCode: function toggleQRCode() { this.setState({ showQRCode: !this.state.showQRCode }); }, render: function render() { var publicLink = this.props.linkData['public_link']; var editAllowed = this.props.editAllowed && !this.props.linkData['hash_is_shorten'] && !this.props.isReadonly() && this.props.shareModel.currentIsOwner(); if (this.state.editLink && editAllowed) { return React.createElement( Paper, { zDepth: 0, rounded: false, className: "public-link-container edit-link" }, React.createElement( 'div', { style: { display: 'flex', alignItems: 'center' } }, React.createElement( 'span', { style: { fontSize: 16, color: 'rgba(0,0,0,0.4)', display: 'inline-block', maxWidth: 200, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' } }, PathUtils.getDirname(publicLink) + '/ ' ), React.createElement(TextField, { style: { flex: 1, marginRight: 10, marginLeft: 10 }, onChange: this.changeLink, value: this.state.customLink !== undefined ? this.state.customLink : this.props.linkData['hash'] }), React.createElement(FloatingActionButton, { mini: true, iconClassName: 'mdi mdi-check', onTouchTap: this.toggleEditMode }) ), React.createElement( 'div', { className: 'section-legend' }, this.props.getMessage('194') ) ); } else { var copyButton = React.createElement('span', { ref: 'copy-button', className: 'copy-link-button mdi mdi-content-copy', title: this.props.getMessage('191') }); var setHtml = (function () { return { __html: this.state.copyMessage }; }).bind(this); var _focus = function _focus(e) { e.target.select(); }; var actionLinks = [], qrCode = undefined; if (this.props.showMailer) { actionLinks.push(React.createElement(_mainActionButton2['default'], { key: 'outline', callback: this.openMailer, mdiIcon: 'email-outline', messageId: '45' })); } if (editAllowed) { actionLinks.push(React.createElement(_mainActionButton2['default'], { key: 'pencil', callback: this.toggleEditMode, mdiIcon: 'pencil', messageId: "193" })); } if (ShareModel.qrcodeEnabled()) { actionLinks.push(React.createElement(_mainActionButton2['default'], { key: 'qrcode', callback: this.toggleQRCode, mdiIcon: 'qrcode', messageId: '94' })); } if (actionLinks.length) { actionLinks = React.createElement( 'div', { className: 'additional-actions-links' }, actionLinks ); } else { actionLinks = null; } if (this.state.showQRCode) { qrCode = React.createElement( 'div', { className: 'qrCode' }, React.createElement(QRCode, { size: 128, value: publicLink, level: 'Q' }) ); } return React.createElement( Paper, { zDepth: 0, rounded: false, className: 'public-link-container' }, React.createElement( 'div', { style: { position: 'relative' } }, React.createElement(TextField, { className: "public-link" + (this.props.linkData['is_expired'] ? ' link-expired' : ''), type: 'text', name: 'Link', ref: 'public-link-field', value: publicLink, onFocus: _focus, fullWidth: true }), ' ', copyButton ), React.createElement('div', { style: { textAlign: 'center' }, className: 'section-legend', dangerouslySetInnerHTML: setHtml() }), this.props.linkData.target_users && React.createElement(_TargetedUsers2['default'], this.props), actionLinks, qrCode ); } } }); exports['default'] = PublicLinkField = (0, _ShareContextConsumer2['default'])(PublicLinkField); exports['default'] = PublicLinkField; module.exports = exports['default']; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"../ShareContextConsumer":1,"../main/ActionButton":8,"./TargetedUsers":17,"clipboard":"clipboard","material-ui":"material-ui","pydio":"pydio","pydio/util/lang":"pydio/util/lang","pydio/util/path":"pydio/util/path","qrcode.react":"qrcode.react","react":"react"}],14:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } var _ShareContextConsumer = require('../ShareContextConsumer'); var _ShareContextConsumer2 = _interopRequireDefault(_ShareContextConsumer); var _Field = require('./Field'); var _Field2 = _interopRequireDefault(_Field); var _Permissions = require('./Permissions'); var _Permissions2 = _interopRequireDefault(_Permissions); var _SecureOptions = require('./SecureOptions'); var _SecureOptions2 = _interopRequireDefault(_SecureOptions); var _mainCard = require('../main/Card'); var _mainCard2 = _interopRequireDefault(_mainCard); var React = require('react'); var _require$requireLib = require('pydio').requireLib('form'); var ValidPassword = _require$requireLib.ValidPassword; var _require = require('material-ui'); var RaisedButton = _require.RaisedButton; var Checkbox = _require.Checkbox; var Divider = _require.Divider; var PublicLinkPanel = React.createClass({ displayName: 'PublicLinkPanel', propTypes: { linkData: React.PropTypes.object, pydio: React.PropTypes.instanceOf(Pydio), shareModel: React.PropTypes.instanceOf(ReactModel.Share), authorizations: React.PropTypes.object, showMailer: React.PropTypes.func }, disableSave: function disableSave() { this.setState({ disabled: true }); }, enableSave: function enableSave() { this.setState({ disabled: false }); }, componentDidMount: function componentDidMount() { this.props.shareModel.observe('saving', this.disableSave); this.props.shareModel.observe('saved', this.enableSave); }, componendWillUnmount: function componendWillUnmount() { this.props.shareModel.stopObserving('saving', this.disableSave); this.props.shareModel.stopObserving('saved', this.enableSave); }, toggleLink: function toggleLink() { var publicLinks = this.props.shareModel.getPublicLinks(); if (this.state.showTemporaryPassword) { this.setState({ showTemporaryPassword: false, temporaryPassword: null }); } else if (!publicLinks.length && ReactModel.Share.getAuthorizations(this.props.pydio).password_mandatory) { this.setState({ showTemporaryPassword: true, temporaryPassword: '' }); } else { this.props.shareModel.togglePublicLink(); } }, getInitialState: function getInitialState() { return { showTemporaryPassword: false, temporaryPassword: null, passValid: false, disabled: false }; }, updateTemporaryPassword: function updateTemporaryPassword(value, event) { if (value == undefined) value = event.currentTarget.getValue(); var passValid = this.refs.passField.isValid(); this.setState({ temporaryPassword: value, passValid: passValid }); }, enableLinkWithPassword: function enableLinkWithPassword() { this.props.shareModel.enablePublicLinkWithPassword(this.state.temporaryPassword); this.setState({ showTemporaryPassword: false, temporaryPassword: null }); }, render: function render() { var publicLinkPanes = undefined, publicLinkField = undefined; if (this.props.linkData) { publicLinkField = React.createElement(_Field2['default'], { showMailer: this.props.showMailer, linkData: this.props.linkData, shareModel: this.props.shareModel, editAllowed: this.props.authorizations.editable_hash, key: 'public-link' }); publicLinkPanes = [React.createElement(_Permissions2['default'], { linkData: this.props.linkData, shareModel: this.props.shareModel, key: 'public-perm' }), React.createElement(_SecureOptions2['default'], { linkData: this.props.linkData, shareModel: this.props.shareModel, pydio: this.props.pydio, key: 'public-secure' })]; } else if (this.state.showTemporaryPassword) { publicLinkField = React.createElement( 'div', null, React.createElement( 'div', { className: 'section-legend', style: { marginTop: 20 } }, this.props.getMessage('215') ), React.createElement( 'div', { style: { display: 'flex', alignItems: 'baseline' } }, React.createElement( 'div', { style: { flex: 1 } }, React.createElement(ValidPassword, { ref: 'passField', attributes: { label: this.props.getMessage('23') }, value: this.state.temporaryPassword, onChange: this.updateTemporaryPassword }) ), React.createElement( 'div', { style: { marginLeft: 7, marginTop: 26 } }, React.createElement(RaisedButton, { label: this.props.getMessage('92'), secondary: true, disabled: !this.state.passValid, onClick: this.enableLinkWithPassword }) ) ) ); } else { publicLinkField = React.createElement( 'div', { className: 'section-legend', style: { paddingBottom: 16, paddingTop: 16 } }, this.props.getMessage('190') ); } var checked = !!this.props.linkData; var disableForNotOwner = false; if (checked && !this.props.shareModel.currentIsOwner()) { disableForNotOwner = true; } return React.createElement( 'div', { style: this.props.style }, React.createElement( _mainCard2['default'], null, React.createElement(Checkbox, { disabled: this.props.isReadonly() || disableForNotOwner || this.state.disabled, onCheck: this.toggleLink, checked: !!this.props.linkData || this.state.showTemporaryPassword, label: this.props.getMessage('189'), labelStyle: { fontSize: 18 } }), publicLinkField ), publicLinkPanes ); } }); exports['default'] = PublicLinkPanel = (0, _ShareContextConsumer2['default'])(PublicLinkPanel); exports['default'] = PublicLinkPanel; module.exports = exports['default']; },{"../ShareContextConsumer":1,"../main/Card":10,"./Field":13,"./Permissions":15,"./SecureOptions":16,"material-ui":"material-ui","pydio":"pydio","react":"react"}],15:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } var _ShareContextConsumer = require('../ShareContextConsumer'); var _ShareContextConsumer2 = _interopRequireDefault(_ShareContextConsumer); var _mainCard = require('../main/Card'); var _mainCard2 = _interopRequireDefault(_mainCard); var React = require('react'); var _require = require('material-ui'); var Checkbox = _require.Checkbox; var Paper = _require.Paper; var ShareModel = require('pydio').requireLib('ReactModelShare'); var PublicLinkPermissions = React.createClass({ displayName: 'PublicLinkPermissions', propTypes: { linkData: React.PropTypes.object.isRequired, shareModel: React.PropTypes.instanceOf(ShareModel), style: React.PropTypes.object }, changePermission: function changePermission(event) { var name = event.target.name; var checked = event.target.checked; this.props.shareModel.setPublicLinkPermission(this.props.linkData.hash, name, checked); }, render: function render() { var linkId = this.props.linkData.hash; var perms = [], previewWarning; var currentIsFolder = !this.props.shareModel.getNode().isLeaf(); perms.push({ NAME: 'read', LABEL: this.props.getMessage('72'), DISABLED: currentIsFolder && !this.props.shareModel.getPublicLinkPermission(linkId, 'write') }); perms.push({ NAME: 'download', LABEL: this.props.getMessage('73') }); if (currentIsFolder) { perms.push({ NAME: 'write', LABEL: this.props.getMessage('74') }); } else if (this.props.shareModel.fileHasWriteableEditors()) { perms.push({ NAME: 'write', LABEL: this.props.getMessage('74b') }); } if (this.props.shareModel.isPublicLinkPreviewDisabled() && this.props.shareModel.getPublicLinkPermission(linkId, 'read')) { previewWarning = React.createElement( 'div', null, this.props.getMessage('195') ); } return React.createElement( _mainCard2['default'], { title: this.props.getMessage('71'), style: this.props.style }, React.createElement( 'div', { className: 'section-legend' }, this.props.getMessage('70r') ), React.createElement( 'div', { style: { margin: '10px 0 20px' }, className: 'ie_material_checkbox_fix' }, perms.map((function (p) { return React.createElement( 'div', { key: p.NAME, style: { display: 'inline-block', width: '33%' } }, React.createElement(Checkbox, { disabled: p.DISABLED || this.props.isReadonly(), type: 'checkbox', name: p.NAME, label: p.LABEL, onCheck: this.changePermission, checked: this.props.shareModel.getPublicLinkPermission(linkId, p.NAME), labelStyle: { whiteSpace: 'nowrap' } }) ); }).bind(this)), previewWarning ) ); } }); exports['default'] = PublicLinkPermissions = (0, _ShareContextConsumer2['default'])(PublicLinkPermissions); exports['default'] = PublicLinkPermissions; module.exports = exports['default']; },{"../ShareContextConsumer":1,"../main/Card":10,"material-ui":"material-ui","pydio":"pydio","react":"react"}],16:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } var _ShareContextConsumer = require('../ShareContextConsumer'); var _ShareContextConsumer2 = _interopRequireDefault(_ShareContextConsumer); var _mainCard = require('../main/Card'); var _mainCard2 = _interopRequireDefault(_mainCard); var React = require('react'); var _require = require('material-ui'); var FlatButton = _require.FlatButton; var TextField = _require.TextField; var DatePicker = _require.DatePicker; var _require$requireLib = require('pydio').requireLib('form'); var ValidPassword = _require$requireLib.ValidPassword; var ShareModel = require('pydio').requireLib('ReactModelShare'); var PublicLinkSecureOptions = React.createClass({ displayName: 'PublicLinkSecureOptions', propTypes: { linkData: React.PropTypes.object.isRequired, shareModel: React.PropTypes.instanceOf(ShareModel), style: React.PropTypes.object }, updateDLExpirationField: function updateDLExpirationField(event) { var newValue = event.currentTarget.value; if (parseInt(newValue) < 0) newValue = -parseInt(newValue); this.props.shareModel.setExpirationFor(this.props.linkData.hash, "downloads", newValue); }, updateDaysExpirationField: function updateDaysExpirationField(event, newValue) { if (!newValue) { newValue = event.currentTarget.getValue(); } this.props.shareModel.setExpirationFor(this.props.linkData.hash, "days", newValue); }, onDateChange: function onDateChange(event, value) { var today = new Date(); var date1 = Date.UTC(today.getFullYear(), today.getMonth(), today.getDate()); var date2 = Date.UTC(value.getFullYear(), value.getMonth(), value.getDate()); var ms = Math.abs(date1 - date2); var integerVal = Math.floor(ms / 1000 / 60 / 60 / 24); //floor should be unnecessary, but just in case this.updateDaysExpirationField(event, integerVal); }, resetPassword: function resetPassword() { this.props.shareModel.resetPassword(this.props.linkData.hash); }, updatePassword: function updatePassword(newValue, oldValue) { if (newValue && !this.refs.passField.isValid()) { this.props.shareModel.setValidStatus(false); } else { this.props.shareModel.setValidStatus(true); } this.props.shareModel.updatePassword(this.props.linkData.hash, newValue); }, renderPasswordContainer: function renderPasswordContainer() { var linkId = this.props.linkData.hash; var passwordField; if (this.props.shareModel.hasHiddenPassword(linkId)) { var resetPassword = React.createElement(FlatButton, { disabled: this.props.isReadonly(), secondary: true, onClick: this.resetPassword, label: this.props.getMessage('174') }); passwordField = React.createElement(TextField, { floatingLabelText: this.props.getMessage('23'), disabled: true, value: '********', fullWidth: true }); } else if (!this.props.isReadonly()) { passwordField = React.createElement(ValidPassword, { name: 'share-password', ref: 'passField', attributes: { label: this.props.getMessage('23') }, value: this.props.shareModel.getPassword(linkId), onChange: this.updatePassword }); } if (passwordField) { return React.createElement( 'div', { className: 'password-container', style: { display: 'flex', alignItems: 'baseline', marginBottom: 10 } }, React.createElement('span', { className: 'ajxp_icon_span mdi mdi-file-lock' }), React.createElement( 'div', { style: { width: resetPassword ? '50%' : '100%', display: 'inline-block' } }, passwordField ), resetPassword && React.createElement( 'div', { style: { width: '50%', display: 'inline-block' } }, resetPassword ) ); } else { return null; } }, formatDate: function formatDate(dateObject) { var dateFormatDay = this.props.getMessage('date_format', '').split(' ').shift(); return dateFormatDay.replace('Y', dateObject.getFullYear()).replace('m', dateObject.getMonth() + 1).replace('d', dateObject.getDate()); }, render: function render() { var linkId = this.props.linkData.hash; var passContainer = this.renderPasswordContainer(); var crtLinkDLAllowed = this.props.shareModel.getPublicLinkPermission(linkId, 'download'); var dlLimitValue = this.props.shareModel.getExpirationFor(linkId, 'downloads') === 0 ? "" : this.props.shareModel.getExpirationFor(linkId, 'downloads'); var expirationDateValue = this.props.shareModel.getExpirationFor(linkId, 'days') === 0 ? "" : this.props.shareModel.getExpirationFor(linkId, 'days'); var auth = ShareModel.getAuthorizations(this.props.pydio); var today = new Date(); var calIcon = React.createElement('span', { className: 'ajxp_icon_span mdi mdi-calendar-clock' }); var expDate = undefined, maxDate = undefined, maxDownloads = null, dateExpired = false, dlExpired = false; if (parseInt(auth.max_expiration) > 0) { maxDate = new Date(); maxDate.setDate(today.getDate() + parseInt(auth.max_expiration)); } if (parseInt(auth.max_downloads) > 0) { maxDownloads = parseInt(auth.max_downloads); dlLimitValue = Math.min(dlLimitValue, maxDownloads); } if (expirationDateValue) { if (expirationDateValue < 0) { dateExpired = true; } expDate = new Date(); expDate.setDate(today.getDate() + parseInt(expirationDateValue)); var clearValue = (function () { this.props.shareModel.setExpirationFor(linkId, "days", ""); }).bind(this); calIcon = React.createElement('span', { className: 'mdi mdi-close-circle ajxp_icon_span', onClick: clearValue }); var calLabel = React.createElement( 'span', { className: 'calLabelHasValue' }, this.props.getMessage(dateExpired ? '21b' : '21') ); } if (dlLimitValue) { var dlCounter = this.props.shareModel.getDownloadCounter(linkId); var resetDl = (function () { if (window.confirm(this.props.getMessage('106'))) { this.props.shareModel.resetDownloadCounter(linkId, function () {}); } }).bind(this); if (dlCounter) { var resetLink = React.createElement( 'a', { style: { cursor: 'pointer' }, onClick: resetDl, title: this.props.getMessage('17') }, '(', this.props.getMessage('16'), ')' ); if (dlCounter >= dlLimitValue) { dlExpired = true; } } var dlCounterString = React.createElement( 'span', { className: 'dlCounterString' }, dlCounter + '/' + dlLimitValue, ' ', resetLink ); } return React.createElement( _mainCard2['default'], { style: this.props.style, title: this.props.getMessage('196') }, React.createElement( 'div', { className: 'section-legend' }, this.props.getMessage('24') ), passContainer, React.createElement( 'div', { className: 'expires', style: { display: 'flex', alignItems: 'center' } }, React.createElement( 'div', { style: { flex: 1, display: 'flex', alignItems: 'center', position: 'relative' }, className: dateExpired ? 'limit-block-expired' : null }, calIcon, React.createElement(DatePicker, { ref: 'expirationDate', key: 'start', value: expDate, minDate: new Date(), maxDate: maxDate, autoOk: true, disabled: this.props.isReadonly(), onChange: this.onDateChange, showYearSelector: true, floatingLabelText: this.props.getMessage(dateExpired ? '21b' : '21'), mode: 'landscape', formatDate: this.formatDate, style: { flex: 1 }, fullWidth: true }) ), React.createElement( 'div', { style: { flex: 1, alignItems: 'center', display: crtLinkDLAllowed ? 'flex' : 'none', position: 'relative' }, className: dlExpired ? 'limit-block-expired' : null }, React.createElement('span', { className: 'mdi mdi-download ajxp_icon_span' }), React.createElement(TextField, { type: 'number', disabled: this.props.isReadonly(), floatingLabelText: this.props.getMessage(dlExpired ? '22b' : '22'), value: dlLimitValue > 0 ? dlLimitValue : '', onChange: this.updateDLExpirationField, fullWidth: true, style: { flex: 1 } }), dlCounterString ) ) ); } }); exports['default'] = PublicLinkSecureOptions = (0, _ShareContextConsumer2['default'])(PublicLinkSecureOptions); exports['default'] = PublicLinkSecureOptions; module.exports = exports['default']; },{"../ShareContextConsumer":1,"../main/Card":10,"material-ui":"material-ui","pydio":"pydio","react":"react"}],17:[function(require,module,exports){ (function (global){ 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var _ShareContextConsumer = require('../ShareContextConsumer'); var _ShareContextConsumer2 = _interopRequireDefault(_ShareContextConsumer); var React = require('react'); var ReactDOM = require('react-dom'); var _require = require('material-ui'); var RaisedButton = _require.RaisedButton; var TextField = _require.TextField; var Paper = _require.Paper; var IconButton = _require.IconButton; var ShareModel = require('pydio').requireLib('ReactModelShare'); var Clipboard = require('clipboard'); var TargetedUserLink = (function (_React$Component) { _inherits(TargetedUserLink, _React$Component); function TargetedUserLink(props) { _classCallCheck(this, TargetedUserLink); _get(Object.getPrototypeOf(TargetedUserLink.prototype), 'constructor', this).call(this, props); this.state = { copyMessage: '' }; } _createClass(TargetedUserLink, [{ key: 'componentDidMount', value: function componentDidMount() { if (this._clip) { this._clip.destroy(); } if (this._button) { this._clip = new Clipboard(this._button, { text: (function (trigger) { return this.props.link; }).bind(this) }); this._clip.on('success', (function () { this.setState({ copyMessage: this.props.getMessage('192') }, this.clearCopyMessage); }).bind(this)); this._clip.on('error', (function () { var copyMessage = undefined; if (global.navigator.platform.indexOf("Mac") === 0) { copyMessage = this.props.getMessage('144'); } else { copyMessage = this.props.getMessage('share_center.143'); } this.setState({ copyMessage: copyMessage }, this.clearCopyMessage); }).bind(this)); } } }, { key: 'componentWillUnmount', value: function componentWillUnmount() { if (this._clip) { this._clip.destroy(); } } }, { key: 'clearCopyMessage', value: function clearCopyMessage() { setTimeout((function () { this.setState({ copyMessage: '' }); }).bind(this), 5000); } }, { key: 'render', value: function render() { var _this = this; var _props = this.props; var display = _props.display; var link = _props.link; var download_count = _props.download_count; return React.createElement( 'div', { style: { display: 'flex' } }, React.createElement( 'div', { style: { flex: 1 } }, display, React.createElement(IconButton, { pydio: this.props.pydio, ref: function (ref) { _this._button = ReactDOM.findDOMNode(ref); }, iconClassName: 'mdi mdi-link', tooltip: this.state.copyMessage || link, iconStyle: { fontSize: 13, lineHeight: '17px' }, style: { width: 34, height: 34, padding: 6 } }) ), React.createElement( 'div', { style: { width: 40, textAlign: 'center' } }, download_count ) ); } }]); return TargetedUserLink; })(React.Component); var TargetedUsers = (function (_React$Component2) { _inherits(TargetedUsers, _React$Component2); function TargetedUsers(props, context) { _classCallCheck(this, TargetedUsers); _get(Object.getPrototypeOf(TargetedUsers.prototype), 'constructor', this).call(this, props, context); this.state = { open: false }; } _createClass(TargetedUsers, [{ key: 'render', value: function render() { var _this2 = this; var target_users = this.props.linkData.target_users; var items = Object.keys(target_users).map(function (k) { var userData = target_users[k]; var title = _this2.props.linkData.public_link + '?u=' + k; return React.createElement(TargetedUserLink, _extends({}, userData, { link: title })); }); if (!items.length) return null; var rootStyle = { lineHeight: '34px', padding: '4px 10px 4px', fontSize: 14, backgroundColor: '#fafafa', borderRadius: 2 }; var headerStyle = { borderBottom: this.state.open ? '1px solid #757575' : '', color: 'rgba(0, 0, 0, 0.36)' }; return React.createElement( 'div', { style: rootStyle }, React.createElement( 'div', { style: _extends({ display: 'flex' }, headerStyle) }, React.createElement( 'div', { style: { flex: 1 } }, this.props.getMessage('245').replace('%s', items.length), ' ', React.createElement('span', { className: 'mdi mdi-chevron-' + (this.state.open ? 'up' : 'down'), style: { cursor: 'pointer' }, onClick: function () { _this2.setState({ open: !_this2.state.open }); } }) ), this.state.open && React.createElement( 'div', { style: { width: 40, textAlign: 'center' } }, '#DL' ) ), this.state.open && React.createElement( 'div', null, items ) ); } }]); return TargetedUsers; })(React.Component); TargetedUsers.propTypes = { linkData: React.PropTypes.object.isRequired, shareModel: React.PropTypes.instanceOf(ShareModel) }; exports['default'] = TargetedUsers = (0, _ShareContextConsumer2['default'])(TargetedUsers); TargetedUserLink = (0, _ShareContextConsumer2['default'])(TargetedUserLink); exports['default'] = TargetedUsers; module.exports = exports['default']; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"../ShareContextConsumer":1,"clipboard":"clipboard","material-ui":"material-ui","pydio":"pydio","react":"react","react-dom":"react-dom"}],18:[function(require,module,exports){ (function (global){ 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } var _ShareContextConsumer = require('../ShareContextConsumer'); var _ShareContextConsumer2 = _interopRequireDefault(_ShareContextConsumer); var _RemoteUsers = require('./RemoteUsers'); var _RemoteUsers2 = _interopRequireDefault(_RemoteUsers); var _SharedUsers = require('./SharedUsers'); var _SharedUsers2 = _interopRequireDefault(_SharedUsers); var React = require('react'); var _require = require('material-ui'); var Divider = _require.Divider; var ShareModel = require('pydio').requireLib('ReactModelShare'); var UsersPanel = React.createClass({ displayName: 'UsersPanel', propTypes: { shareModel: React.PropTypes.instanceOf(ShareModel), showMailer: React.PropTypes.func }, onUserUpdate: function onUserUpdate(operation, userId, userData) { this.props.shareModel.updateSharedUser(operation, userId, userData); }, onSaveSelection: function onSaveSelection() { var label = window.prompt(this.props.getMessage(510, '')); if (!label) return; this.props.shareModel.saveSelectionAsTeam(label); }, sendInvitations: function sendInvitations(userObjects) { try { var mailData = this.props.shareModel.prepareEmail("repository"); this.props.showMailer(mailData.subject, mailData.message, userObjects); } catch (e) { global.alert(e.message); } }, render: function render() { var currentUsers = this.props.shareModel.getSharedUsers(); var federatedEnabled = ShareModel.federatedSharingEnabled(); return React.createElement( 'div', { style: this.props.style }, React.createElement(_SharedUsers2['default'], { showTitle: federatedEnabled, users: currentUsers, userObjects: this.props.shareModel.getSharedUsersAsObjects(), sendInvitations: this.props.showMailer ? this.sendInvitations : null, onUserUpdate: this.onUserUpdate, saveSelectionAsTeam: PydioUsers.Client.saveSelectionSupported() ? this.onSaveSelection : null, pydio: this.props.pydio }), federatedEnabled && React.createElement(_RemoteUsers2['default'], { shareModel: this.props.shareModel, onUserUpdate: this.onUserUpdate, pydio: this.props.pydio }) ); } }); exports['default'] = UsersPanel = (0, _ShareContextConsumer2['default'])(UsersPanel); exports['default'] = UsersPanel; module.exports = exports['default']; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"../ShareContextConsumer":1,"./RemoteUsers":20,"./SharedUsers":22,"material-ui":"material-ui","pydio":"pydio","react":"react"}],19:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } var _ShareContextConsumer = require('../ShareContextConsumer'); var _ShareContextConsumer2 = _interopRequireDefault(_ShareContextConsumer); var _UserBadge = require('./UserBadge'); var _UserBadge2 = _interopRequireDefault(_UserBadge); var React = require('react'); var RemoteUserEntry = React.createClass({ displayName: 'RemoteUserEntry', propTypes: { shareModel: React.PropTypes.instanceOf(ReactModel.Share), linkData: React.PropTypes.object.isRequired, onRemoveUser: React.PropTypes.func.isRequired, onUserUpdate: React.PropTypes.func.isRequired }, getInitialState: function getInitialState() { return { internalUser: this.props.shareModel.getSharedUser(this.props.linkData['internal_user_id']) }; }, componentWillReceiveProps: function componentWillReceiveProps(newProps, oldProps) { this.setState({ internalUser: newProps.shareModel.getSharedUser(newProps.linkData['internal_user_id']) }); }, getStatus: function getStatus() { var link = this.props.linkData; if (!link.invitation) return -1;else return link.invitation.STATUS; }, getStatusString: function getStatusString() { var statuses = { 's-1': 214, 's1': 211, 's2': 212, 's4': 213 }; return this.props.getMessage(statuses['s' + this.getStatus()]); }, buildLabel: function buildLabel() { var link = this.props.linkData; var host = link.HOST || (link.invitation ? link.invitation.HOST : null); var user = link.USER || (link.invitation ? link.invitation.USER : null); if (!host || !user) return "Error"; return user + " @ " + host; }, removeUser: function removeUser() { this.props.onRemoveUser(this.props.linkData['hash']); }, onUpdateRight: function onUpdateRight(event) { var target = event.target; this.props.onUserUpdate('update_right', this.state.internalUser.ID, { right: target.name, add: target.checked }); }, render: function render() { var menuItems = []; if (!this.props.isReadonly()) { menuItems = [{ text: this.props.getMessage('257', ''), callback: this.removeUser }]; } var status = this.getStatus(); var additionalItem; if (status == 2) { additionalItem = React.createElement( 'span', { className: 'user-badge-rights-container' }, React.createElement('input', { type: 'checkbox', name: 'read', disabled: this.props.isReadonly(), checked: this.state.internalUser.RIGHT.indexOf('r') !== -1, onChange: this.onUpdateRight }), React.createElement('input', { type: 'checkbox', name: 'write', disabled: this.props.isReadonly(), checked: this.state.internalUser.RIGHT.indexOf('w') !== -1, onChange: this.onUpdateRight }) ); } else { additionalItem = React.createElement( 'span', { className: 'user-badge-rights-container' }, this.getStatusString() ); } return React.createElement( _UserBadge2['default'], { label: this.buildLabel(), avatar: null, type: "remote_user", menus: menuItems }, additionalItem ); } }); exports['default'] = RemoteUserEntry = (0, _ShareContextConsumer2['default'])(RemoteUserEntry); exports['default'] = RemoteUserEntry; module.exports = exports['default']; },{"../ShareContextConsumer":1,"./UserBadge":23,"react":"react"}],20:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } var _ShareContextConsumer = require('../ShareContextConsumer'); var _ShareContextConsumer2 = _interopRequireDefault(_ShareContextConsumer); var _RemoteUserEntry = require('./RemoteUserEntry'); var _RemoteUserEntry2 = _interopRequireDefault(_RemoteUserEntry); var _mainCard = require('../main/Card'); var _mainCard2 = _interopRequireDefault(_mainCard); var _mainActionButton = require('../main/ActionButton'); var _mainActionButton2 = _interopRequireDefault(_mainActionButton); var React = require('react'); var _require = require('material-ui'); var TextField = _require.TextField; var IconButton = _require.IconButton; var Paper = _require.Paper; var Pydio = require('pydio'); var _Pydio$requireLib = Pydio.requireLib('ReactModelShare'); var ReactModelShare = _Pydio$requireLib.ReactModelShare; var _Pydio$requireLib2 = Pydio.requireLib('components'); var AddressBook = _Pydio$requireLib2.AddressBook; var RemoteUsers = React.createClass({ displayName: 'RemoteUsers', propTypes: { shareModel: React.PropTypes.instanceOf(ReactModelShare), onUserUpdate: React.PropTypes.func.isRequired, pydio: React.PropTypes.instanceOf(Pydio) }, getInitialState: function getInitialState() { return { addDisabled: true, showUserForm: false }; }, addUser: function addUser() { var h = this.refs["host"].getValue(); var u = this.refs["user"].getValue(); this.props.shareModel.createRemoteLink(h, u); }, removeUser: function removeUser(linkId) { this.props.shareModel.removeRemoteLink(linkId); }, monitorInput: function monitorInput() { var h = this.refs["host"].getValue(); var u = this.refs["user"].getValue(); this.setState({ addDisabled: !(h && u) }); }, onAddressBookItemSelected: function onAddressBookItemSelected(uObject, parent) { var trustedServerId = uObject.trustedServerId; var userId = uObject.getId(); this.props.shareModel.createRemoteLink('trusted://' + trustedServerId, userId); }, getActions: function getActions() { var _this = this; var ocsRemotes = this.props.pydio.getPluginConfigs('core.ocs').get('TRUSTED_SERVERS'); var hasTrusted = ocsRemotes && ocsRemotes.length; return [React.createElement(_mainActionButton2['default'], { key: 'manual', mdiIcon: 'account-plus', messageId: '45', onTouchTap: function () { _this.setState({ showUserForm: true }); } }), React.createElement(AddressBook, { key: 'addressbook', mode: 'popover', pydio: this.props.pydio, onItemSelected: this.onAddressBookItemSelected, usersFrom: 'remote', disableSearch: true, popoverButton: React.createElement(_mainActionButton2['default'], { mdiIcon: 'server-network', messageId: '45' }) })]; }, renderUserForm: function renderUserForm() { var _this2 = this; if (this.props.isReadonly()) { return null; } return React.createElement( Paper, { zDepth: 0, style: { padding: '0 16px', backgroundColor: '#FAFAFA', marginTop: 10 } }, React.createElement( 'div', null, React.createElement(TextField, { fullWidth: true, ref: 'host', floatingLabelText: this.props.getMessage('209'), onChange: this.monitorInput }), React.createElement(TextField, { fullWidth: true, ref: 'user', type: 'text', floatingLabelText: this.props.getMessage('210'), onChange: this.monitorInput }) ), React.createElement( 'div', { style: { textAlign: 'right' } }, React.createElement(IconButton, { tooltip: 'Cancel', iconClassName: 'mdi mdi-undo', onClick: function () { _this2.setState({ showUserForm: false }); } }), React.createElement(IconButton, { tooltip: this.props.getMessage('45'), iconClassName: 'icon-plus-sign', onClick: this.addUser, disabled: this.state.addDisabled }) ) ); }, render: function render() { var ocsLinks = this.props.shareModel.getOcsLinksByStatus(), inv, rwHeader, hasActiveOcsLink = false; inv = ocsLinks.map((function (link) { hasActiveOcsLink = !hasActiveOcsLink && link && link.invitation && link.invitation.STATUS == 2 ? true : hasActiveOcsLink; return React.createElement(_RemoteUserEntry2['default'], { shareModel: this.props.shareModel, linkData: link, onRemoveUser: this.removeUser, onUserUpdate: this.props.onUserUpdate }); }).bind(this)); if (hasActiveOcsLink) { rwHeader = React.createElement( 'div', null, React.createElement( 'div', { className: 'shared-users-rights-header' }, React.createElement( 'span', { className: 'read' }, this.props.getMessage('361', '') ), React.createElement( 'span', { className: 'read' }, this.props.getMessage('181') ) ) ); } return React.createElement( _mainCard2['default'], { title: this.props.getMessage('207'), actions: this.getActions() }, !ocsLinks.length && React.createElement( 'div', { style: { color: 'rgba(0,0,0,0.43)', paddingBottom: 16 } }, this.props.getMessage('208') ), React.createElement( 'div', null, rwHeader, inv ), this.state.showUserForm && this.renderUserForm() ); } }); exports['default'] = RemoteUsers = (0, _ShareContextConsumer2['default'])(RemoteUsers); exports['default'] = RemoteUsers; module.exports = exports['default']; },{"../ShareContextConsumer":1,"../main/ActionButton":8,"../main/Card":10,"./RemoteUserEntry":19,"material-ui":"material-ui","pydio":"pydio","react":"react"}],21:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } var _UserBadge = require('./UserBadge'); var _UserBadge2 = _interopRequireDefault(_UserBadge); var _ShareContextConsumer = require('../ShareContextConsumer'); var _ShareContextConsumer2 = _interopRequireDefault(_ShareContextConsumer); var React = require('react'); var SharedUserEntry = React.createClass({ displayName: 'SharedUserEntry', propTypes: { userEntry: React.PropTypes.object.isRequired, userObject: React.PropTypes.instanceOf(PydioUsers.User).isRequired, onUserUpdate: React.PropTypes.func.isRequired, sendInvitations: React.PropTypes.func }, onRemove: function onRemove() { this.props.onUserUpdate('remove', this.props.userEntry.ID, this.props.userEntry); }, onToggleWatch: function onToggleWatch() { this.props.onUserUpdate('update_right', this.props.userEntry.ID, { right: 'watch', add: !this.props.userEntry['WATCH'] }); }, onInvite: function onInvite() { var targets = {}; targets[this.props.userObject.getId()] = this.props.userObject; this.props.sendInvitations(targets); }, onUpdateRight: function onUpdateRight(event) { var target = event.target; this.props.onUserUpdate('update_right', this.props.userEntry.ID, { right: target.name, add: target.checked }); }, render: function render() { var menuItems = []; if (this.props.userEntry.TYPE != 'group') { if (!this.props.isReadonly()) { // Toggle Notif menuItems.push({ text: this.props.getMessage('183'), callback: this.onToggleWatch, checked: this.props.userEntry.WATCH }); } if (this.props.sendInvitations) { // Send invitation menuItems.push({ text: this.props.getMessage('45'), callback: this.onInvite }); } } if (!this.props.isReadonly()) { // Remove Entry menuItems.push({ text: this.props.getMessage('257', ''), callback: this.onRemove }); } return React.createElement( _UserBadge2['default'], { label: this.props.userEntry.LABEL || this.props.userEntry.ID, avatar: this.props.userEntry.AVATAR, type: this.props.userEntry.TYPE, menus: menuItems }, React.createElement( 'span', { className: 'user-badge-rights-container', style: !menuItems.length ? { marginRight: 48 } : {} }, React.createElement('input', { type: 'checkbox', name: 'read', disabled: this.props.isReadonly(), checked: this.props.userEntry.RIGHT.indexOf('r') !== -1, onChange: this.onUpdateRight }), React.createElement('input', { type: 'checkbox', name: 'write', disabled: this.props.isReadonly(), checked: this.props.userEntry.RIGHT.indexOf('w') !== -1, onChange: this.onUpdateRight }) ) ); } }); exports['default'] = SharedUserEntry = (0, _ShareContextConsumer2['default'])(SharedUserEntry); exports['default'] = SharedUserEntry; module.exports = exports['default']; },{"../ShareContextConsumer":1,"./UserBadge":23,"react":"react"}],22:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } var _ShareContextConsumer = require('../ShareContextConsumer'); var _ShareContextConsumer2 = _interopRequireDefault(_ShareContextConsumer); var _UserBadge = require('./UserBadge'); var _UserBadge2 = _interopRequireDefault(_UserBadge); var _SharedUserEntry = require('./SharedUserEntry'); var _SharedUserEntry2 = _interopRequireDefault(_SharedUserEntry); var _mainActionButton = require('../main/ActionButton'); var _mainActionButton2 = _interopRequireDefault(_mainActionButton); var _mainCard = require('../main/Card'); var _mainCard2 = _interopRequireDefault(_mainCard); var React = require('react'); var Pydio = require('pydio'); var _Pydio$requireLib = Pydio.requireLib('components'); var UsersCompleter = _Pydio$requireLib.UsersCompleter; var _require = require('material-ui'); var Paper = _require.Paper; var SharedUsers = React.createClass({ displayName: 'SharedUsers', propTypes: { pydio: React.PropTypes.instanceOf(Pydio), users: React.PropTypes.array.isRequired, userObjects: React.PropTypes.object.isRequired, onUserUpdate: React.PropTypes.func.isRequired, saveSelectionAsTeam: React.PropTypes.func, sendInvitations: React.PropTypes.func, showTitle: React.PropTypes.bool }, sendInvitationToAllUsers: function sendInvitationToAllUsers() { this.props.sendInvitations(this.props.userObjects); }, clearAllUsers: function clearAllUsers() { this.props.users.map((function (entry) { this.props.onUserUpdate('remove', entry.ID, entry); }).bind(this)); }, valueSelected: function valueSelected(userObject) { var newEntry = { ID: userObject.getId(), RIGHT: 'r', LABEL: userObject.getLabel(), TYPE: userObject.getGroup() ? 'group' : 'user' }; this.props.onUserUpdate('add', newEntry.ID, newEntry); }, completerRenderSuggestion: function completerRenderSuggestion(userObject) { var type = userObject.getType() === 'team' || userObject.getId().indexOf('/AJXP_TEAM/') === 0 ? 'team' : userObject.getGroup() ? 'group' : userObject.getTemporary() ? 'temporary' : userObject.getExternal() ? 'tmp_user' : 'user'; return React.createElement(_UserBadge2['default'], { label: userObject.getExtendedLabel() || userObject.getLabel(), avatar: userObject.getAvatar(), type: type }); }, render: function render() { // sort by group/user then by ID; var userEntries = this.props.users.sort(function (a, b) { return b.TYPE === 'group' || b.TYPE === 'team' ? 1 : a.TYPE === 'group' || a.TYPE === 'team' ? -1 : a.ID > b.ID ? 1 : b.ID > a.ID ? -1 : 0; }).map((function (u) { return React.createElement(_SharedUserEntry2['default'], { userEntry: u, userObject: this.props.userObjects[u.ID], key: u.ID, shareModel: this.props.shareModel, onUserUpdate: this.props.onUserUpdate, sendInvitations: this.props.sendInvitations }); }).bind(this)); var actionLinks = []; if (this.props.users.length && !this.props.isReadonly()) { actionLinks.push(React.createElement(_mainActionButton2['default'], { key: 'clear', callback: this.clearAllUsers, mdiIcon: 'delete', messageId: '180' })); } if (this.props.sendInvitations && this.props.users.length) { actionLinks.push(React.createElement(_mainActionButton2['default'], { key: 'invite', callback: this.sendInvitationToAllUsers, mdiIcon: 'email-outline', messageId: '45' })); } if (this.props.saveSelectionAsTeam && this.props.users.length > 1 && !this.props.isReadonly()) { actionLinks.push(React.createElement(_mainActionButton2['default'], { key: 'team', callback: this.props.saveSelectionAsTeam, mdiIcon: 'account-multiple-plus', messageId: '509', messageCoreNamespace: true })); } var rwHeader = undefined, usersInput = undefined; if (this.props.users.length) { rwHeader = React.createElement( 'div', null, React.createElement( 'div', { className: 'shared-users-rights-header' }, React.createElement( 'span', { className: 'read' }, this.props.getMessage('361', '') ), React.createElement( 'span', { className: 'read' }, this.props.getMessage('181') ) ) ); } if (!this.props.isReadonly()) { var excludes = this.props.users.map(function (u) { return u.ID; }); usersInput = React.createElement(UsersCompleter, { className: 'share-form-users', fieldLabel: this.props.getMessage('34'), renderSuggestion: this.completerRenderSuggestion, onValueSelected: this.valueSelected, excludes: excludes, pydio: this.props.pydio, showAddressBook: true, usersFrom: 'local' }); } return React.createElement( _mainCard2['default'], { title: this.props.showTitle ? this.props.getMessage('217') : null, actions: actionLinks }, React.createElement( 'div', { style: userEntries.length ? { margin: '-20px 8px 16px' } : { marginTop: -20 } }, usersInput ), rwHeader, React.createElement( 'div', null, userEntries ), !userEntries.length && React.createElement( 'div', { style: { color: 'rgba(0,0,0,0.43)' } }, this.props.getMessage('182') ) ); } }); exports['default'] = SharedUsers = (0, _ShareContextConsumer2['default'])(SharedUsers); exports['default'] = SharedUsers; module.exports = exports['default']; },{"../ShareContextConsumer":1,"../main/ActionButton":8,"../main/Card":10,"./SharedUserEntry":21,"./UserBadge":23,"material-ui":"material-ui","pydio":"pydio","react":"react"}],23:[function(require,module,exports){ 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var _require = require('react'); var Component = _require.Component; var PropTypes = _require.PropTypes; var _require2 = require('material-ui'); var MenuItem = _require2.MenuItem; var IconMenu = _require2.IconMenu; var IconButton = _require2.IconButton; var _require3 = require('material-ui/styles'); var muiThemeable = _require3.muiThemeable; var Color = require('color'); var UserBadge = (function (_Component) { _inherits(UserBadge, _Component); function UserBadge() { _classCallCheck(this, UserBadge); _get(Object.getPrototypeOf(UserBadge.prototype), 'constructor', this).apply(this, arguments); } _createClass(UserBadge, [{ key: 'renderMenu', value: function renderMenu() { if (!this.props.menus || !this.props.menus.length) { return null; } var menuItems = this.props.menus.map(function (m) { var rightIcon = undefined; if (m.checked) { rightIcon = React.createElement('span', { className: 'mdi mdi-check' }); } return React.createElement(MenuItem, { primaryText: m.text, onTouchTap: m.callback, rightIcon: rightIcon }); }); var iconStyle = { fontSize: 18 }; return React.createElement( IconMenu, { iconButtonElement: React.createElement(IconButton, { style: { padding: 16 }, iconStyle: iconStyle, iconClassName: 'icon-ellipsis-vertical' }), anchorOrigin: { horizontal: 'right', vertical: 'top' }, targetOrigin: { horizontal: 'right', vertical: 'top' } }, menuItems ); } }, { key: 'render', value: function render() { var avatar = undefined; var avatarColor = this.props.muiTheme.palette.avatarsColor; if (this.props.type == 'group') { avatarColor = Color(avatarColor).darken(.2).toString(); avatar = React.createElement('span', { className: 'avatar mdi mdi-account-multiple', style: { backgroundColor: avatarColor } }); } else if (this.props.type == 'team') { avatarColor = Color(avatarColor).darken(.2).toString(); avatar = React.createElement('span', { className: 'avatar mdi mdi-account-multiple-outline', style: { backgroundColor: avatarColor } }); } else if (this.props.type == 'temporary') { avatarColor = Color(avatarColor).lighten(.2).toString(); avatar = React.createElement('span', { className: 'avatar mdi mdi-account-plus', style: { backgroundColor: avatarColor } }); } else if (this.props.type == 'remote_user') { avatar = React.createElement('span', { className: 'avatar mdi mdi-account-network', style: { backgroundColor: avatarColor } }); } else { avatar = React.createElement('span', { className: 'avatar mdi mdi-account', style: { backgroundColor: avatarColor } }); } var menu = this.renderMenu(); return React.createElement( 'div', { className: "share-dialog user-badge user-type-" + this.props.type }, avatar, React.createElement( 'span', { className: 'user-badge-label' }, this.props.label ), this.props.children, menu ); } }]); return UserBadge; })(Component); UserBadge.propTypes = { label: PropTypes.string, avatar: PropTypes.string, type: PropTypes.string, menus: PropTypes.object, muiTheme: PropTypes.object }; exports['default'] = UserBadge = muiThemeable()(UserBadge); exports['default'] = UserBadge; module.exports = exports['default']; },{"color":"color","material-ui":"material-ui","material-ui/styles":"material-ui/styles","react":"react"}]},{},[7])(7) }); //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJyZXMvYnVpbGQvZGlhbG9nL1NoYXJlQ29udGV4dENvbnN1bWVyLmpzIiwicmVzL2J1aWxkL2RpYWxvZy9hZHZhbmNlZC9MYWJlbERlc2NyaXB0aW9uUGFuZWwuanMiLCJyZXMvYnVpbGQvZGlhbG9nL2FkdmFuY2VkL05vdGlmaWNhdGlvblBhbmVsLmpzIiwicmVzL2J1aWxkL2RpYWxvZy9hZHZhbmNlZC9QYW5lbC5qcyIsInJlcy9idWlsZC9kaWFsb2cvYWR2YW5jZWQvUHVibGljTGlua1RlbXBsYXRlLmpzIiwicmVzL2J1aWxkL2RpYWxvZy9hZHZhbmNlZC9WaXNpYmlsaXR5UGFuZWwuanMiLCJyZXMvYnVpbGQvZGlhbG9nL2luZGV4LmpzIiwicmVzL2J1aWxkL2RpYWxvZy9tYWluL0FjdGlvbkJ1dHRvbi5qcyIsInJlcy9idWlsZC9kaWFsb2cvbWFpbi9CdXR0b25zQ29tcHV0ZXIuanMiLCJyZXMvYnVpbGQvZGlhbG9nL21haW4vQ2FyZC5qcyIsInJlcy9idWlsZC9kaWFsb2cvbWFpbi9IZWFkZXIuanMiLCJyZXMvYnVpbGQvZGlhbG9nL21haW4vUGFuZWwuanMiLCJyZXMvYnVpbGQvZGlhbG9nL3B1YmxpYy9GaWVsZC5qcyIsInJlcy9idWlsZC9kaWFsb2cvcHVibGljL1BhbmVsLmpzIiwicmVzL2J1aWxkL2RpYWxvZy9wdWJsaWMvUGVybWlzc2lvbnMuanMiLCJyZXMvYnVpbGQvZGlhbG9nL3B1YmxpYy9TZWN1cmVPcHRpb25zLmpzIiwicmVzL2J1aWxkL2RpYWxvZy9wdWJsaWMvVGFyZ2V0ZWRVc2Vycy5qcyIsInJlcy9idWlsZC9kaWFsb2cvdXNlcnMvUGFuZWwuanMiLCJyZXMvYnVpbGQvZGlhbG9nL3VzZXJzL1JlbW90ZVVzZXJFbnRyeS5qcyIsInJlcy9idWlsZC9kaWFsb2cvdXNlcnMvUmVtb3RlVXNlcnMuanMiLCJyZXMvYnVpbGQvZGlhbG9nL3VzZXJzL1NoYXJlZFVzZXJFbnRyeS5qcyIsInJlcy9idWlsZC9kaWFsb2cvdXNlcnMvU2hhcmVkVXNlcnMuanMiLCJyZXMvYnVpbGQvZGlhbG9nL3VzZXJzL1VzZXJCYWRnZS5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3REQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDbERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ2xaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDN01BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbExBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDdlBBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDN01BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNsRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3R0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkxBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6S0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbigpe2Z1bmN0aW9uIHIoZSxuLHQpe2Z1bmN0aW9uIG8oaSxmKXtpZighbltpXSl7aWYoIWVbaV0pe3ZhciBjPVwiZnVuY3Rpb25cIj09dHlwZW9mIHJlcXVpcmUmJnJlcXVpcmU7aWYoIWYmJmMpcmV0dXJuIGMoaSwhMCk7aWYodSlyZXR1cm4gdShpLCEwKTt2YXIgYT1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK2krXCInXCIpO3Rocm93IGEuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixhfXZhciBwPW5baV09e2V4cG9ydHM6e319O2VbaV1bMF0uY2FsbChwLmV4cG9ydHMsZnVuY3Rpb24ocil7dmFyIG49ZVtpXVsxXVtyXTtyZXR1cm4gbyhufHxyKX0scCxwLmV4cG9ydHMscixlLG4sdCl9cmV0dXJuIG5baV0uZXhwb3J0c31mb3IodmFyIHU9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZSxpPTA7aTx0Lmxlbmd0aDtpKyspbyh0W2ldKTtyZXR1cm4gb31yZXR1cm4gcn0pKCkiLCIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnX19lc01vZHVsZScsIHtcbiAgICB2YWx1ZTogdHJ1ZVxufSk7XG5cbnZhciBfZXh0ZW5kcyA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gKHRhcmdldCkgeyBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgeyB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldOyBmb3IgKHZhciBrZXkgaW4gc291cmNlKSB7IGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoc291cmNlLCBrZXkpKSB7IHRhcmdldFtrZXldID0gc291cmNlW2tleV07IH0gfSB9IHJldHVybiB0YXJnZXQ7IH07XG5cbnZhciBfY3JlYXRlQ2xhc3MgPSAoZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKCd2YWx1ZScgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9IHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH07IH0pKCk7XG5cbnZhciBfZ2V0ID0gZnVuY3Rpb24gZ2V0KF94LCBfeDIsIF94MykgeyB2YXIgX2FnYWluID0gdHJ1ZTsgX2Z1bmN0aW9uOiB3aGlsZSAoX2FnYWluKSB7IHZhciBvYmplY3QgPSBfeCwgcHJvcGVydHkgPSBfeDIsIHJlY2VpdmVyID0gX3gzOyBfYWdhaW4gPSBmYWxzZTsgaWYgKG9iamVjdCA9PT0gbnVsbCkgb2JqZWN0ID0gRnVuY3Rpb24ucHJvdG90eXBlOyB2YXIgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Iob2JqZWN0LCBwcm9wZXJ0eSk7IGlmIChkZXNjID09PSB1bmRlZmluZWQpIHsgdmFyIHBhcmVudCA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihvYmplY3QpOyBpZiAocGFyZW50ID09PSBudWxsKSB7IHJldHVybiB1bmRlZmluZWQ7IH0gZWxzZSB7IF94ID0gcGFyZW50OyBfeDIgPSBwcm9wZXJ0eTsgX3gzID0gcmVjZWl2ZXI7IF9hZ2FpbiA9IHRydWU7IGRlc2MgPSBwYXJlbnQgPSB1bmRlZmluZWQ7IGNvbnRpbnVlIF9mdW5jdGlvbjsgfSB9IGVsc2UgaWYgKCd2YWx1ZScgaW4gZGVzYykgeyByZXR1cm4gZGVzYy52YWx1ZTsgfSBlbHNlIHsgdmFyIGdldHRlciA9IGRlc2MuZ2V0OyBpZiAoZ2V0dGVyID09PSB1bmRlZmluZWQpIHsgcmV0dXJuIHVuZGVmaW5lZDsgfSByZXR1cm4gZ2V0dGVyLmNhbGwocmVjZWl2ZXIpOyB9IH0gfTtcblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24nKTsgfSB9XG5cbmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09ICdmdW5jdGlvbicgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90ICcgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5zZXRQcm90b3R5cGVPZihzdWJDbGFzcywgc3VwZXJDbGFzcykgOiBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9XG5cbnZhciBSZWFjdCA9IHJlcXVpcmUoJ3JlYWN0Jyk7XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IGZ1bmN0aW9uIChQeWRpb0NvbXBvbmVudCkge1xuICAgIHZhciBTaGFyZUNvbnRleHRDb25zdW1lciA9IChmdW5jdGlvbiAoX1JlYWN0JENvbXBvbmVudCkge1xuICAgICAgICBfaW5oZXJpdHMoU2hhcmVDb250ZXh0Q29uc3VtZXIsIF9SZWFjdCRDb21wb25lbnQpO1xuXG4gICAgICAgIGZ1bmN0aW9uIFNoYXJlQ29udGV4dENvbnN1bWVyKCkge1xuICAgICAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFNoYXJlQ29udGV4dENvbnN1bWVyKTtcblxuICAgICAgICAgICAgX2dldChPYmplY3QuZ2V0UHJvdG90eXBlT2YoU2hhcmVDb250ZXh0Q29uc3VtZXIucHJvdG90eXBlKSwgJ2NvbnN0cnVjdG9yJywgdGhpcykuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIF9jcmVhdGVDbGFzcyhTaGFyZUNvbnRleHRDb25zdW1lciwgW3tcbiAgICAgICAgICAgIGtleTogJ3JlbmRlcicsXG4gICAgICAgICAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgICAgICAgICAgIHZhciBfY29udGV4dCA9IHRoaXMuY29udGV4dDtcbiAgICAgICAgICAgICAgICB2YXIgbWVzc2FnZXMgPSBfY29udGV4dC5tZXNzYWdlcztcbiAgICAgICAgICAgICAgICB2YXIgZ2V0TWVzc2FnZSA9IF9jb250ZXh0LmdldE1lc3NhZ2U7XG4gICAgICAgICAgICAgICAgdmFyIGlzUmVhZG9ubHkgPSBfY29udGV4dC5pc1JlYWRvbmx5O1xuXG4gICAgICAgICAgICAgICAgdmFyIGNvbnRleHRQcm9wcyA9IHsgbWVzc2FnZXM6IG1lc3NhZ2VzLCBnZXRNZXNzYWdlOiBnZXRNZXNzYWdlLCBpc1JlYWRvbmx5OiBpc1JlYWRvbmx5IH07XG4gICAgICAgICAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoUHlkaW9Db21wb25lbnQsIF9leHRlbmRzKHt9LCB0aGlzLnByb3BzLCBjb250ZXh0UHJvcHMpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfV0pO1xuXG4gICAgICAgIHJldHVybiBTaGFyZUNvbnRleHRDb25zdW1lcjtcbiAgICB9KShSZWFjdC5Db21wb25lbnQpO1xuXG4gICAgU2hhcmVDb250ZXh0Q29uc3VtZXIuY29udGV4dFR5cGVzID0ge1xuICAgICAgICBtZXNzYWdlczogUmVhY3QuUHJvcFR5cGVzLm9iamVjdCxcbiAgICAgICAgZ2V0TWVzc2FnZTogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsXG4gICAgICAgIGlzUmVhZG9ubHk6IFJlYWN0LlByb3BUeXBlcy5mdW5jXG4gICAgfTtcblxuICAgIHJldHVybiBTaGFyZUNvbnRleHRDb25zdW1lcjtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ19fZXNNb2R1bGUnLCB7XG4gICAgdmFsdWU6IHRydWVcbn0pO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyAnZGVmYXVsdCc6IG9iaiB9OyB9XG5cbnZhciBfU2hhcmVDb250ZXh0Q29uc3VtZXIgPSByZXF1aXJlKCcuLi9TaGFyZUNvbnRleHRDb25zdW1lcicpO1xuXG52YXIgX1NoYXJlQ29udGV4dENvbnN1bWVyMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1NoYXJlQ29udGV4dENvbnN1bWVyKTtcblxudmFyIFJlYWN0ID0gcmVxdWlyZSgncmVhY3QnKTtcblxudmFyIF9yZXF1aXJlID0gcmVxdWlyZSgnbWF0ZXJpYWwtdWknKTtcblxudmFyIFRleHRGaWVsZCA9IF9yZXF1aXJlLlRleHRGaWVsZDtcbnZhciBTdWJoZWFkZXIgPSBfcmVxdWlyZS5TdWJoZWFkZXI7XG5cbnZhciBMYWJlbERlc2NyaXB0aW9uUGFuZWwgPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG4gICAgZGlzcGxheU5hbWU6ICdMYWJlbERlc2NyaXB0aW9uUGFuZWwnLFxuXG4gICAgdXBkYXRlTGFiZWw6IGZ1bmN0aW9uIHVwZGF0ZUxhYmVsKGV2ZW50KSB7XG4gICAgICAgIHRoaXMucHJvcHMuc2hhcmVNb2RlbC5zZXRHbG9iYWwoXCJsYWJlbFwiLCBldmVudC5jdXJyZW50VGFyZ2V0LnZhbHVlKTtcbiAgICB9LFxuXG4gICAgdXBkYXRlRGVzY3JpcHRpb246IGZ1bmN0aW9uIHVwZGF0ZURlc2NyaXB0aW9uKGV2ZW50KSB7XG4gICAgICAgIHRoaXMucHJvcHMuc2hhcmVNb2RlbC5zZXRHbG9iYWwoXCJkZXNjcmlwdGlvblwiLCBldmVudC5jdXJyZW50VGFyZ2V0LnZhbHVlKTtcbiAgICB9LFxuXG4gICAgcmVuZGVyOiBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgICAgIHZhciBsYWJlbCA9IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGxhYmVsTGVnZW5kID0gdW5kZWZpbmVkO1xuICAgICAgICBpZiAoIXRoaXMucHJvcHMuc2hhcmVNb2RlbC5nZXROb2RlKCkuaXNMZWFmKCkpIHtcbiAgICAgICAgICAgIGxhYmVsID0gUmVhY3QuY3JlYXRlRWxlbWVudChUZXh0RmllbGQsIHtcbiAgICAgICAgICAgICAgICBkaXNhYmxlZDogdGhpcy5wcm9wcy5pc1JlYWRvbmx5KCksXG4gICAgICAgICAgICAgICAgZmxvYXRpbmdMYWJlbFRleHQ6IHRoaXMucHJvcHMuZ2V0TWVzc2FnZSgnMzUnKSArICcgKCAnICsgdGhpcy5wcm9wcy5nZXRNZXNzYWdlKCcxNDYnKSArICcgKScsXG4gICAgICAgICAgICAgICAgZmxvYXRpbmdMYWJlbFN0eWxlOiB7IHdoaXRlU3BhY2U6ICdub3dyYXAnLCBvdmVyZmxvdzogJ2hpZGRlbicsIHRleHRPdmVyZmxvdzogJ2VsbGlwc2lzJyB9LFxuICAgICAgICAgICAgICAgIG5hbWU6ICdsYWJlbCcsXG4gICAgICAgICAgICAgICAgb25DaGFuZ2U6IHRoaXMudXBkYXRlTGFiZWwsXG4gICAgICAgICAgICAgICAgdmFsdWU6IHRoaXMucHJvcHMuc2hhcmVNb2RlbC5nZXRHbG9iYWwoJ2xhYmVsJykgfHwgJycsXG4gICAgICAgICAgICAgICAgZnVsbFdpZHRoOiB0cnVlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgeyBzdHlsZTogdGhpcy5wcm9wcy5zdHlsZSB9LFxuICAgICAgICAgICAgbGFiZWwsXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFRleHRGaWVsZCwge1xuICAgICAgICAgICAgICAgIGRpc2FibGVkOiB0aGlzLnByb3BzLmlzUmVhZG9ubHkoKSxcbiAgICAgICAgICAgICAgICBmbG9hdGluZ0xhYmVsVGV4dDogdGhpcy5wcm9wcy5nZXRNZXNzYWdlKCcxNDUnKSArICcgKCAnICsgdGhpcy5wcm9wcy5nZXRNZXNzYWdlKCcxOTcnKSArICcgKScsXG4gICAgICAgICAgICAgICAgZmxvYXRpbmdMYWJlbFN0eWxlOiB7IHdoaXRlU3BhY2U6ICdub3dyYXAnLCBvdmVyZmxvdzogJ2hpZGRlbicsIHRleHRPdmVyZmxvdzogJ2VsbGlwc2lzJyB9LFxuICAgICAgICAgICAgICAgIG5hbWU6ICdkZXNjcmlwdGlvbicsXG4gICAgICAgICAgICAgICAgb25DaGFuZ2U6IHRoaXMudXBkYXRlRGVzY3JpcHRpb24sXG4gICAgICAgICAgICAgICAgdmFsdWU6IHRoaXMucHJvcHMuc2hhcmVNb2RlbC5nZXRHbG9iYWwoJ2Rlc2NyaXB0aW9uJykgfHwgJycsXG4gICAgICAgICAgICAgICAgZnVsbFdpZHRoOiB0cnVlXG4gICAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgIH1cbn0pO1xuXG5leHBvcnRzWydkZWZhdWx0J10gPSBMYWJlbERlc2NyaXB0aW9uUGFuZWwgPSAoMCwgX1NoYXJlQ29udGV4dENvbnN1bWVyMlsnZGVmYXVsdCddKShMYWJlbERlc2NyaXB0aW9uUGFuZWwpO1xuXG5leHBvcnRzWydkZWZhdWx0J10gPSBMYWJlbERlc2NyaXB0aW9uUGFuZWw7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTtcbiIsIid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdfX2VzTW9kdWxlJywge1xuICAgIHZhbHVlOiB0cnVlXG59KTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgJ2RlZmF1bHQnOiBvYmogfTsgfVxuXG52YXIgX1NoYXJlQ29udGV4dENvbnN1bWVyID0gcmVxdWlyZSgnLi4vU2hhcmVDb250ZXh0Q29uc3VtZXInKTtcblxudmFyIF9TaGFyZUNvbnRleHRDb25zdW1lcjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9TaGFyZUNvbnRleHRDb25zdW1lcik7XG5cbnZhciBSZWFjdCA9IHJlcXVpcmUoJ3JlYWN0Jyk7XG5cbnZhciBfcmVxdWlyZSA9IHJlcXVpcmUoJ21hdGVyaWFsLXVpJyk7XG5cbnZhciBUZXh0RmllbGQgPSBfcmVxdWlyZS5UZXh0RmllbGQ7XG52YXIgU2VsZWN0RmllbGQgPSBfcmVxdWlyZS5TZWxlY3RGaWVsZDtcbnZhciBNZW51SXRlbSA9IF9yZXF1aXJlLk1lbnVJdGVtO1xuXG52YXIgTm90aWZpY2F0aW9uUGFuZWwgPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG4gICAgZGlzcGxheU5hbWU6ICdOb3RpZmljYXRpb25QYW5lbCcsXG5cbiAgICBkcm9wRG93bkNoYW5nZTogZnVuY3Rpb24gZHJvcERvd25DaGFuZ2UoZXZlbnQsIGluZGV4LCB2YWx1ZSkge1xuICAgICAgICB0aGlzLnByb3BzLnNoYXJlTW9kZWwuc2V0R2xvYmFsKCd3YXRjaCcsIHZhbHVlICE9PSAnbm9fd2F0Y2gnKTtcbiAgICB9LFxuXG4gICAgcmVuZGVyOiBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgICAgIHZhciBtZW51SXRlbXMgPSBbUmVhY3QuY3JlYXRlRWxlbWVudChNZW51SXRlbSwgeyB2YWx1ZTogJ25vX3dhdGNoJywgcHJpbWFyeVRleHQ6IHRoaXMucHJvcHMuZ2V0TWVzc2FnZSgnMTg3JykgfSksIFJlYWN0LmNyZWF0ZUVsZW1lbnQoTWVudUl0ZW0sIHsgdmFsdWU6ICd3YXRjaF9yZWFkJywgcHJpbWFyeVRleHQ6IHRoaXMucHJvcHMuZ2V0TWVzc2FnZSgnMTg0JykgfSldO1xuXG4gICAgICAgIHZhciBzZWxlY3RlZEluZGV4ID0gdGhpcy5wcm9wcy5zaGFyZU1vZGVsLmdldEdsb2JhbCgnd2F0Y2gnKSA/ICd3YXRjaF9yZWFkJyA6ICdub193YXRjaCc7XG5cbiAgICAgICAgdmFyIHVudXNlZExlZ2VuZCA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAnZm9ybS1sZWdlbmQnIH0sXG4gICAgICAgICAgICB0aGlzLnByb3BzLmdldE1lc3NhZ2UoJzE4OCcpXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICB7IHN0eWxlOiB0aGlzLnByb3BzLnN0eWxlIH0sXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgIFNlbGVjdEZpZWxkLFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgZGlzYWJsZWQ6IHRoaXMucHJvcHMuaXNSZWFkb25seSgpLFxuICAgICAgICAgICAgICAgICAgICBmdWxsV2lkdGg6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOiBzZWxlY3RlZEluZGV4LFxuICAgICAgICAgICAgICAgICAgICBvbkNoYW5nZTogdGhpcy5kcm9wRG93bkNoYW5nZSxcbiAgICAgICAgICAgICAgICAgICAgZmxvYXRpbmdMYWJlbFRleHQ6IHRoaXMucHJvcHMuZ2V0TWVzc2FnZSgnMjE4JylcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIG1lbnVJdGVtc1xuICAgICAgICAgICAgKVxuICAgICAgICApO1xuICAgIH1cbn0pO1xuXG5Ob3RpZmljYXRpb25QYW5lbCA9ICgwLCBfU2hhcmVDb250ZXh0Q29uc3VtZXIyWydkZWZhdWx0J10pKE5vdGlmaWNhdGlvblBhbmVsKTtcbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IE5vdGlmaWNhdGlvblBhbmVsO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG4iLCIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnX19lc01vZHVsZScsIHtcbiAgICB2YWx1ZTogdHJ1ZVxufSk7XG5cbnZhciBfZXh0ZW5kcyA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gKHRhcmdldCkgeyBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgeyB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldOyBmb3IgKHZhciBrZXkgaW4gc291cmNlKSB7IGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoc291cmNlLCBrZXkpKSB7IHRhcmdldFtrZXldID0gc291cmNlW2tleV07IH0gfSB9IHJldHVybiB0YXJnZXQ7IH07XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7ICdkZWZhdWx0Jzogb2JqIH07IH1cblxuZnVuY3Rpb24gX29iamVjdFdpdGhvdXRQcm9wZXJ0aWVzKG9iaiwga2V5cykgeyB2YXIgdGFyZ2V0ID0ge307IGZvciAodmFyIGkgaW4gb2JqKSB7IGlmIChrZXlzLmluZGV4T2YoaSkgPj0gMCkgY29udGludWU7IGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgaSkpIGNvbnRpbnVlOyB0YXJnZXRbaV0gPSBvYmpbaV07IH0gcmV0dXJuIHRhcmdldDsgfVxuXG52YXIgX0xhYmVsRGVzY3JpcHRpb25QYW5lbCA9IHJlcXVpcmUoJy4vTGFiZWxEZXNjcmlwdGlvblBhbmVsJyk7XG5cbnZhciBfTGFiZWxEZXNjcmlwdGlvblBhbmVsMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX0xhYmVsRGVzY3JpcHRpb25QYW5lbCk7XG5cbnZhciBfTm90aWZpY2F0aW9uUGFuZWwgPSByZXF1aXJlKCcuL05vdGlmaWNhdGlvblBhbmVsJyk7XG5cbnZhciBfTm90aWZpY2F0aW9uUGFuZWwyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfTm90aWZpY2F0aW9uUGFuZWwpO1xuXG52YXIgX1B1YmxpY0xpbmtUZW1wbGF0ZSA9IHJlcXVpcmUoJy4vUHVibGljTGlua1RlbXBsYXRlJyk7XG5cbnZhciBfUHVibGljTGlua1RlbXBsYXRlMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1B1YmxpY0xpbmtUZW1wbGF0ZSk7XG5cbnZhciBfVmlzaWJpbGl0eVBhbmVsID0gcmVxdWlyZSgnLi9WaXNpYmlsaXR5UGFuZWwnKTtcblxudmFyIF9WaXNpYmlsaXR5UGFuZWwyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfVmlzaWJpbGl0eVBhbmVsKTtcblxudmFyIF9TaGFyZUNvbnRleHRDb25zdW1lciA9IHJlcXVpcmUoJy4uL1NoYXJlQ29udGV4dENvbnN1bWVyJyk7XG5cbnZhciBfU2hhcmVDb250ZXh0Q29uc3VtZXIyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfU2hhcmVDb250ZXh0Q29uc3VtZXIpO1xuXG52YXIgX21haW5DYXJkID0gcmVxdWlyZSgnLi4vbWFpbi9DYXJkJyk7XG5cbnZhciBfbWFpbkNhcmQyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfbWFpbkNhcmQpO1xuXG52YXIgUmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpO1xuXG52YXIgU2hhcmVNb2RlbCA9IHJlcXVpcmUoJ3B5ZGlvJykucmVxdWlyZUxpYignUmVhY3RNb2RlbFNoYXJlJyk7XG5cbnZhciBfcmVxdWlyZSA9IHJlcXVpcmUoJ21hdGVyaWFsLXVpJyk7XG5cbnZhciBEaXZpZGVyID0gX3JlcXVpcmUuRGl2aWRlcjtcblxudmFyIFBhbmVsID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuICAgIGRpc3BsYXlOYW1lOiAnUGFuZWwnLFxuXG4gICAgcHJvcFR5cGVzOiB7XG4gICAgICAgIHB5ZGlvOiBSZWFjdC5Qcm9wVHlwZXMuaW5zdGFuY2VPZihQeWRpbyksXG4gICAgICAgIHNoYXJlTW9kZWw6IFJlYWN0LlByb3BUeXBlcy5pbnN0YW5jZU9mKFNoYXJlTW9kZWwpXG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gcmVuZGVyKCkge1xuXG4gICAgICAgIHZhciBsYXlvdXREYXRhID0gU2hhcmVNb2RlbC5jb21waWxlTGF5b3V0RGF0YSh0aGlzLnByb3BzLnB5ZGlvLCB0aGlzLnByb3BzLnNoYXJlTW9kZWwuZ2V0Tm9kZSgpKTtcbiAgICAgICAgdmFyIGxheW91dFBhbmUgPSB1bmRlZmluZWQsXG4gICAgICAgICAgICB2aXNpYmlsaXR5UGFuZWwgPSB1bmRlZmluZWQ7XG4gICAgICAgIHZhciBfcHJvcHMgPSB0aGlzLnByb3BzO1xuICAgICAgICB2YXIgc3R5bGUgPSBfcHJvcHMuc3R5bGU7XG5cbiAgICAgICAgdmFyIHByb3BzID0gX29iamVjdFdpdGhvdXRQcm9wZXJ0aWVzKF9wcm9wcywgWydzdHlsZSddKTtcblxuICAgICAgICBpZiAoIXRoaXMucHJvcHMuc2hhcmVNb2RlbC5nZXROb2RlKCkuaXNMZWFmKCkgJiYgbGF5b3V0RGF0YS5sZW5ndGggPiAxICYmIHRoaXMucHJvcHMuc2hhcmVNb2RlbC5oYXNQdWJsaWNMaW5rKCkpIHtcbiAgICAgICAgICAgIGxheW91dFBhbmUgPSBSZWFjdC5jcmVhdGVFbGVtZW50KF9QdWJsaWNMaW5rVGVtcGxhdGUyWydkZWZhdWx0J10sIF9leHRlbmRzKHt9LCBwcm9wcywgeyBsaW5rRGF0YTogdGhpcy5wcm9wcy5zaGFyZU1vZGVsLmdldFB1YmxpY0xpbmtzKClbMF0sIGxheW91dERhdGE6IGxheW91dERhdGEgfSkpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdGhpcy5wcm9wcy5zaGFyZU1vZGVsLmN1cnJlbnRSZXBvSXNVc2VyU2NvcGUoKSkge1xuICAgICAgICAgICAgdmlzaWJpbGl0eVBhbmVsID0gUmVhY3QuY3JlYXRlRWxlbWVudChfVmlzaWJpbGl0eVBhbmVsMlsnZGVmYXVsdCddLCBfZXh0ZW5kcyh7fSwgcHJvcHMsIHsgc3R5bGU6IHsgcGFkZGluZ0JvdHRvbTogMTYgfSB9KSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgIF9tYWluQ2FyZDJbJ2RlZmF1bHQnXSxcbiAgICAgICAgICAgICAgICB7IHN0eWxlOiB0aGlzLnByb3BzLnN0eWxlLCB0aXRsZTogdGhpcy5wcm9wcy5nZXRNZXNzYWdlKCc0ODYnLCAnJykgfSxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KF9MYWJlbERlc2NyaXB0aW9uUGFuZWwyWydkZWZhdWx0J10sIF9leHRlbmRzKHt9LCBwcm9wcywgeyBzdHlsZTogeyBtYXJnaW5Ub3A6IC0xMCB9IH0pKSxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KF9Ob3RpZmljYXRpb25QYW5lbDJbJ2RlZmF1bHQnXSwgcHJvcHMpLFxuICAgICAgICAgICAgICAgIGxheW91dFBhbmVcbiAgICAgICAgICAgICksXG4gICAgICAgICAgICB2aXNpYmlsaXR5UGFuZWxcbiAgICAgICAgKTtcbiAgICB9XG59KTtcblxuZXhwb3J0c1snZGVmYXVsdCddID0gUGFuZWwgPSAoMCwgX1NoYXJlQ29udGV4dENvbnN1bWVyMlsnZGVmYXVsdCddKShQYW5lbCk7XG5leHBvcnRzWydkZWZhdWx0J10gPSBQYW5lbDtcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ19fZXNNb2R1bGUnLCB7XG4gICAgdmFsdWU6IHRydWVcbn0pO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyAnZGVmYXVsdCc6IG9iaiB9OyB9XG5cbnZhciBfU2hhcmVDb250ZXh0Q29uc3VtZXIgPSByZXF1aXJlKCcuLi9TaGFyZUNvbnRleHRDb25zdW1lcicpO1xuXG52YXIgX1NoYXJlQ29udGV4dENvbnN1bWVyMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1NoYXJlQ29udGV4dENvbnN1bWVyKTtcblxudmFyIFJlYWN0ID0gcmVxdWlyZSgncmVhY3QnKTtcblxudmFyIF9yZXF1aXJlID0gcmVxdWlyZSgnbWF0ZXJpYWwtdWknKTtcblxudmFyIFRleHRGaWVsZCA9IF9yZXF1aXJlLlRleHRGaWVsZDtcbnZhciBTZWxlY3RGaWVsZCA9IF9yZXF1aXJlLlNlbGVjdEZpZWxkO1xudmFyIE1lbnVJdGVtID0gX3JlcXVpcmUuTWVudUl0ZW07XG5cbnZhciBQdWJsaWNMaW5rVGVtcGxhdGUgPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG4gICAgZGlzcGxheU5hbWU6ICdQdWJsaWNMaW5rVGVtcGxhdGUnLFxuXG4gICAgcHJvcFR5cGVzOiB7XG4gICAgICAgIGxpbmtEYXRhOiBSZWFjdC5Qcm9wVHlwZXMub2JqZWN0XG4gICAgfSxcblxuICAgIG9uRHJvcERvd25DaGFuZ2U6IGZ1bmN0aW9uIG9uRHJvcERvd25DaGFuZ2UoZXZlbnQsIGluZGV4LCB2YWx1ZSkge1xuICAgICAgICB0aGlzLnByb3BzLnNoYXJlTW9kZWwuc2V0VGVtcGxhdGUodGhpcy5wcm9wcy5saW5rRGF0YS5oYXNoLCB2YWx1ZSk7XG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgICB2YXIgY3J0TGFiZWwgPSB1bmRlZmluZWQ7XG4gICAgICAgIHZhciBzZWxlY3RlZCA9IHRoaXMucHJvcHMuc2hhcmVNb2RlbC5nZXRUZW1wbGF0ZSh0aGlzLnByb3BzLmxpbmtEYXRhLmhhc2gpO1xuICAgICAgICB2YXIgbWVudUl0ZW1zID0gdGhpcy5wcm9wcy5sYXlvdXREYXRhLm1hcChmdW5jdGlvbiAobCkge1xuICAgICAgICAgICAgaWYgKHNlbGVjdGVkICYmIGwuTEFZT1VUX0VMRU1FTlQgPT09IHNlbGVjdGVkKSB7XG4gICAgICAgICAgICAgICAgY3J0TGFiZWwgPSBsLkxBWU9VVF9MQUJFTDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghc2VsZWN0ZWQgJiYgIWNydExhYmVsKSB7XG4gICAgICAgICAgICAgICAgc2VsZWN0ZWQgPSBsLkxBWU9VVF9FTEVNRU5ULCBjcnRMYWJlbCA9IGwuTEFZT1VUX0xBQkVMO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoTWVudUl0ZW0sIHsga2V5OiBsLkxBWU9VVF9FTEVNRU5ULCB2YWx1ZTogbC5MQVlPVVRfRUxFTUVOVCwgcHJpbWFyeVRleHQ6IGwuTEFZT1VUX0xBQkVMIH0pO1xuICAgICAgICB9KTtcbiAgICAgICAgdmFyIHVudXNlZExlZ2VuZCA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAnZm9ybS1sZWdlbmQnIH0sXG4gICAgICAgICAgICB0aGlzLnByb3BzLmdldE1lc3NhZ2UoJzE5OCcpXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICB7IHN0eWxlOiB0aGlzLnByb3BzLnN0eWxlIH0sXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgIFNlbGVjdEZpZWxkLFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgZnVsbFdpZHRoOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogc2VsZWN0ZWQsXG4gICAgICAgICAgICAgICAgICAgIG9uQ2hhbmdlOiB0aGlzLm9uRHJvcERvd25DaGFuZ2UsXG4gICAgICAgICAgICAgICAgICAgIGRpc2FibGVkOiB0aGlzLnByb3BzLmlzUmVhZG9ubHkoKSxcbiAgICAgICAgICAgICAgICAgICAgZmxvYXRpbmdMYWJlbFRleHQ6IHRoaXMucHJvcHMuZ2V0TWVzc2FnZSgnMTUxJylcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIG1lbnVJdGVtc1xuICAgICAgICAgICAgKVxuICAgICAgICApO1xuICAgIH1cbn0pO1xuXG5QdWJsaWNMaW5rVGVtcGxhdGUgPSAoMCwgX1NoYXJlQ29udGV4dENvbnN1bWVyMlsnZGVmYXVsdCddKShQdWJsaWNMaW5rVGVtcGxhdGUpO1xuZXhwb3J0c1snZGVmYXVsdCddID0gUHVibGljTGlua1RlbXBsYXRlO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG4iLCIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnX19lc01vZHVsZScsIHtcbiAgICB2YWx1ZTogdHJ1ZVxufSk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7ICdkZWZhdWx0Jzogb2JqIH07IH1cblxudmFyIF9TaGFyZUNvbnRleHRDb25zdW1lciA9IHJlcXVpcmUoJy4uL1NoYXJlQ29udGV4dENvbnN1bWVyJyk7XG5cbnZhciBfU2hhcmVDb250ZXh0Q29uc3VtZXIyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfU2hhcmVDb250ZXh0Q29uc3VtZXIpO1xuXG52YXIgX21haW5DYXJkID0gcmVxdWlyZSgnLi4vbWFpbi9DYXJkJyk7XG5cbnZhciBfbWFpbkNhcmQyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfbWFpbkNhcmQpO1xuXG52YXIgUmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpO1xuXG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKCdtYXRlcmlhbC11aScpO1xuXG52YXIgQ2hlY2tib3ggPSBfcmVxdWlyZS5DaGVja2JveDtcbnZhciBSYWlzZWRCdXR0b24gPSBfcmVxdWlyZS5SYWlzZWRCdXR0b247XG52YXIgVGV4dEZpZWxkID0gX3JlcXVpcmUuVGV4dEZpZWxkO1xuXG52YXIgVmlzaWJpbGl0eVBhbmVsID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuICAgIGRpc3BsYXlOYW1lOiAnVmlzaWJpbGl0eVBhbmVsJyxcblxuICAgIHRvZ2dsZVZpc2liaWxpdHk6IGZ1bmN0aW9uIHRvZ2dsZVZpc2liaWxpdHkoKSB7XG4gICAgICAgIHRoaXMucHJvcHMuc2hhcmVNb2RlbC50b2dnbGVWaXNpYmlsaXR5KCk7XG4gICAgfSxcbiAgICB0cmFuc2Zlck93bmVyc2hpcDogZnVuY3Rpb24gdHJhbnNmZXJPd25lcnNoaXAoKSB7XG4gICAgICAgIHRoaXMucHJvcHMuc2hhcmVNb2RlbC5zZXROZXdTaGFyZU93bmVyKHRoaXMucmVmc1snbmV3T3duZXInXS5nZXRWYWx1ZSgpKTtcbiAgICB9LFxuICAgIHJlbmRlcjogZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgICB2YXIgY3VycmVudElzT3duZXIgPSB0aGlzLnByb3BzLnNoYXJlTW9kZWwuY3VycmVudElzT3duZXIoKTtcblxuICAgICAgICB2YXIgbGVnZW5kO1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5zaGFyZU1vZGVsLmlzUHVibGljKCkpIHtcbiAgICAgICAgICAgIGlmIChjdXJyZW50SXNPd25lcikge1xuICAgICAgICAgICAgICAgIGxlZ2VuZCA9IHRoaXMucHJvcHMuZ2V0TWVzc2FnZSgnMjAxJyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGxlZ2VuZCA9IHRoaXMucHJvcHMuZ2V0TWVzc2FnZSgnMjAyJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsZWdlbmQgPSB0aGlzLnByb3BzLmdldE1lc3NhZ2UoJzIwNicpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBzaG93VG9nZ2xlID0gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoQ2hlY2tib3gsIHsgdHlwZTogJ2NoZWNrYm94JyxcbiAgICAgICAgICAgICAgICBuYW1lOiAnc2hhcmVfdmlzaWJpbGl0eScsXG4gICAgICAgICAgICAgICAgZGlzYWJsZWQ6ICFjdXJyZW50SXNPd25lciB8fCB0aGlzLnByb3BzLmlzUmVhZG9ubHkoKSxcbiAgICAgICAgICAgICAgICBvbkNoZWNrOiB0aGlzLnRvZ2dsZVZpc2liaWxpdHksXG4gICAgICAgICAgICAgICAgY2hlY2tlZDogdGhpcy5wcm9wcy5zaGFyZU1vZGVsLmlzUHVibGljKCksXG4gICAgICAgICAgICAgICAgbGFiZWw6IHRoaXMucHJvcHMuZ2V0TWVzc2FnZSgnMjAwJylcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ3NlY3Rpb24tbGVnZW5kJyB9LFxuICAgICAgICAgICAgICAgIGxlZ2VuZFxuICAgICAgICAgICAgKVxuICAgICAgICApO1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5zaGFyZU1vZGVsLmlzUHVibGljKCkgJiYgY3VycmVudElzT3duZXIgJiYgIXRoaXMucHJvcHMuaXNSZWFkb25seSgpKSB7XG4gICAgICAgICAgICB2YXIgc2hvd1RyYW5zZmVyID0gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ293bmVyc2hpcC1mb3JtJyB9LFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICdoNCcsXG4gICAgICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucHJvcHMuZ2V0TWVzc2FnZSgnMjAzJylcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ3NlY3Rpb24tbGVnZW5kJyB9LFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnByb3BzLmdldE1lc3NhZ2UoJzIwNCcpXG4gICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChUZXh0RmllbGQsIHsgcmVmOiAnbmV3T3duZXInLCBmbG9hdGluZ0xhYmVsVGV4dDogdGhpcy5wcm9wcy5nZXRNZXNzYWdlKCcyMDUnKSB9KSxcbiAgICAgICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChSYWlzZWRCdXR0b24sIHsgbGFiZWw6IHRoaXMucHJvcHMuZ2V0TWVzc2FnZSgnMjAzYicpLCBvbkNsaWNrOiB0aGlzLnRyYW5zZmVyT3duZXJzaGlwIH0pXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgIF9tYWluQ2FyZDJbJ2RlZmF1bHQnXSxcbiAgICAgICAgICAgIHsgc3R5bGU6IHRoaXMucHJvcHMuc3R5bGUsIHRpdGxlOiB0aGlzLnByb3BzLmdldE1lc3NhZ2UoJzE5OScpIH0sXG4gICAgICAgICAgICBzaG93VG9nZ2xlLFxuICAgICAgICAgICAgc2hvd1RyYW5zZmVyXG4gICAgICAgICk7XG4gICAgfVxufSk7XG5cblZpc2liaWxpdHlQYW5lbCA9ICgwLCBfU2hhcmVDb250ZXh0Q29uc3VtZXIyWydkZWZhdWx0J10pKFZpc2liaWxpdHlQYW5lbCk7XG5leHBvcnRzWydkZWZhdWx0J10gPSBWaXNpYmlsaXR5UGFuZWw7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTtcbiIsIid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdfX2VzTW9kdWxlJywge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7ICdkZWZhdWx0Jzogb2JqIH07IH1cblxudmFyIF9tYWluUGFuZWwgPSByZXF1aXJlKCcuL21haW4vUGFuZWwnKTtcblxudmFyIF9tYWluUGFuZWwyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfbWFpblBhbmVsKTtcblxudmFyIF9wdWJsaWNGaWVsZCA9IHJlcXVpcmUoJy4vcHVibGljL0ZpZWxkJyk7XG5cbnZhciBfcHVibGljRmllbGQyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfcHVibGljRmllbGQpO1xuXG52YXIgX3B1YmxpY1BhbmVsID0gcmVxdWlyZSgnLi9wdWJsaWMvUGFuZWwnKTtcblxudmFyIF9wdWJsaWNQYW5lbDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9wdWJsaWNQYW5lbCk7XG5cbmV4cG9ydHMuTWFpblBhbmVsID0gX21haW5QYW5lbDJbJ2RlZmF1bHQnXTtcbmV4cG9ydHMuUHVibGljTGlua0ZpZWxkID0gX3B1YmxpY0ZpZWxkMlsnZGVmYXVsdCddO1xuZXhwb3J0cy5QdWJsaWNMaW5rUGFuZWwgPSBfcHVibGljUGFuZWwyWydkZWZhdWx0J107XG4iLCIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnX19lc01vZHVsZScsIHtcbiAgICB2YWx1ZTogdHJ1ZVxufSk7XG5cbnZhciBfY3JlYXRlQ2xhc3MgPSAoZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKCd2YWx1ZScgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9IHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH07IH0pKCk7XG5cbnZhciBfZ2V0ID0gZnVuY3Rpb24gZ2V0KF94LCBfeDIsIF94MykgeyB2YXIgX2FnYWluID0gdHJ1ZTsgX2Z1bmN0aW9uOiB3aGlsZSAoX2FnYWluKSB7IHZhciBvYmplY3QgPSBfeCwgcHJvcGVydHkgPSBfeDIsIHJlY2VpdmVyID0gX3gzOyBfYWdhaW4gPSBmYWxzZTsgaWYgKG9iamVjdCA9PT0gbnVsbCkgb2JqZWN0ID0gRnVuY3Rpb24ucHJvdG90eXBlOyB2YXIgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Iob2JqZWN0LCBwcm9wZXJ0eSk7IGlmIChkZXNjID09PSB1bmRlZmluZWQpIHsgdmFyIHBhcmVudCA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihvYmplY3QpOyBpZiAocGFyZW50ID09PSBudWxsKSB7IHJldHVybiB1bmRlZmluZWQ7IH0gZWxzZSB7IF94ID0gcGFyZW50OyBfeDIgPSBwcm9wZXJ0eTsgX3gzID0gcmVjZWl2ZXI7IF9hZ2FpbiA9IHRydWU7IGRlc2MgPSBwYXJlbnQgPSB1bmRlZmluZWQ7IGNvbnRpbnVlIF9mdW5jdGlvbjsgfSB9IGVsc2UgaWYgKCd2YWx1ZScgaW4gZGVzYykgeyByZXR1cm4gZGVzYy52YWx1ZTsgfSBlbHNlIHsgdmFyIGdldHRlciA9IGRlc2MuZ2V0OyBpZiAoZ2V0dGVyID09PSB1bmRlZmluZWQpIHsgcmV0dXJuIHVuZGVmaW5lZDsgfSByZXR1cm4gZ2V0dGVyLmNhbGwocmVjZWl2ZXIpOyB9IH0gfTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgJ2RlZmF1bHQnOiBvYmogfTsgfVxuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbicpOyB9IH1cblxuZnVuY3Rpb24gX2luaGVyaXRzKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7IGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gJ2Z1bmN0aW9uJyAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ1N1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uLCBub3QgJyArIHR5cGVvZiBzdXBlckNsYXNzKTsgfSBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHsgY29uc3RydWN0b3I6IHsgdmFsdWU6IHN1YkNsYXNzLCBlbnVtZXJhYmxlOiBmYWxzZSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IH0pOyBpZiAoc3VwZXJDbGFzcykgT2JqZWN0LnNldFByb3RvdHlwZU9mID8gT2JqZWN0LnNldFByb3RvdHlwZU9mKHN1YkNsYXNzLCBzdXBlckNsYXNzKSA6IHN1YkNsYXNzLl9fcHJvdG9fXyA9IHN1cGVyQ2xhc3M7IH1cblxudmFyIF9TaGFyZUNvbnRleHRDb25zdW1lciA9IHJlcXVpcmUoJy4uL1NoYXJlQ29udGV4dENvbnN1bWVyJyk7XG5cbnZhciBfU2hhcmVDb250ZXh0Q29uc3VtZXIyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfU2hhcmVDb250ZXh0Q29uc3VtZXIpO1xuXG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKCdyZWFjdCcpO1xuXG52YXIgQ29tcG9uZW50ID0gX3JlcXVpcmUuQ29tcG9uZW50O1xudmFyIFByb3BUeXBlcyA9IF9yZXF1aXJlLlByb3BUeXBlcztcblxudmFyIF9yZXF1aXJlMiA9IHJlcXVpcmUoJ21hdGVyaWFsLXVpJyk7XG5cbnZhciBJY29uQnV0dG9uID0gX3JlcXVpcmUyLkljb25CdXR0b247XG5cbnZhciBfcmVxdWlyZTMgPSByZXF1aXJlKCdtYXRlcmlhbC11aS9zdHlsZXMnKTtcblxudmFyIG11aVRoZW1lYWJsZSA9IF9yZXF1aXJlMy5tdWlUaGVtZWFibGU7XG5cbnZhciBBY3Rpb25CdXR0b24gPSAoZnVuY3Rpb24gKF9Db21wb25lbnQpIHtcbiAgICBfaW5oZXJpdHMoQWN0aW9uQnV0dG9uLCBfQ29tcG9uZW50KTtcblxuICAgIGZ1bmN0aW9uIEFjdGlvbkJ1dHRvbigpIHtcbiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIEFjdGlvbkJ1dHRvbik7XG5cbiAgICAgICAgX2dldChPYmplY3QuZ2V0UHJvdG90eXBlT2YoQWN0aW9uQnV0dG9uLnByb3RvdHlwZSksICdjb25zdHJ1Y3RvcicsIHRoaXMpLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfVxuXG4gICAgX2NyZWF0ZUNsYXNzKEFjdGlvbkJ1dHRvbiwgW3tcbiAgICAgICAga2V5OiAncmVuZGVyJyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgICAgICAgIHZhciBwYWxldHRlID0gdGhpcy5wcm9wcy5tdWlUaGVtZS5wYWxldHRlO1xuXG4gICAgICAgICAgICB2YXIgc3R5bGUgPSB7XG4gICAgICAgICAgICAgICAgcm9vdDoge1xuICAgICAgICAgICAgICAgICAgICBib3JkZXJSYWRpdXM6ICc1MCUnLFxuICAgICAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IHBhbGV0dGUucHJpbWFyeTFDb2xvcixcbiAgICAgICAgICAgICAgICAgICAgd2lkdGg6IDM2LCBoZWlnaHQ6IDM2LFxuICAgICAgICAgICAgICAgICAgICBwYWRkaW5nOiA4LFxuICAgICAgICAgICAgICAgICAgICBtYXJnaW46ICcwIDZweCcsXG4gICAgICAgICAgICAgICAgICAgIHpJbmRleDogMFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgaWNvbjoge1xuICAgICAgICAgICAgICAgICAgICBjb2xvcjogJ3doaXRlJyxcbiAgICAgICAgICAgICAgICAgICAgZm9udFNpemU6IDIwLFxuICAgICAgICAgICAgICAgICAgICBsaW5lSGVpZ2h0OiAnMjBweCdcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChJY29uQnV0dG9uLCB7XG4gICAgICAgICAgICAgICAgc3R5bGU6IHN0eWxlLnJvb3QsXG4gICAgICAgICAgICAgICAgaWNvblN0eWxlOiBzdHlsZS5pY29uLFxuICAgICAgICAgICAgICAgIG9uVG91Y2hUYXA6IHRoaXMucHJvcHMuY2FsbGJhY2sgfHwgdGhpcy5wcm9wcy5vblRvdWNoVGFwLFxuICAgICAgICAgICAgICAgIGljb25DbGFzc05hbWU6IFwibWRpIG1kaS1cIiArIHRoaXMucHJvcHMubWRpSWNvbixcbiAgICAgICAgICAgICAgICB0b29sdGlwOiB0aGlzLnByb3BzLmdldE1lc3NhZ2UodGhpcy5wcm9wcy5tZXNzYWdlSWQsIHRoaXMucHJvcHMubWVzc2FnZUNvcmVOYW1lc3BhY2UgPyAnJyA6IHVuZGVmaW5lZClcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfV0pO1xuXG4gICAgcmV0dXJuIEFjdGlvbkJ1dHRvbjtcbn0pKENvbXBvbmVudCk7XG5cbkFjdGlvbkJ1dHRvbi5wcm9wVHlwZXMgPSB7XG4gICAgY2FsbGJhY2s6IFByb3BUeXBlcy5mdW5jLFxuICAgIG9uVG91Y2hUYXA6IFByb3BUeXBlcy5mdW5jLFxuICAgIG1kaUljb246IFByb3BUeXBlcy5zdHJpbmcsXG4gICAgbWVzc2FnZUlkOiBQcm9wVHlwZXMuc3RyaW5nXG59O1xuXG5BY3Rpb25CdXR0b24gPSAoMCwgX1NoYXJlQ29udGV4dENvbnN1bWVyMlsnZGVmYXVsdCddKShBY3Rpb25CdXR0b24pO1xuQWN0aW9uQnV0dG9uID0gbXVpVGhlbWVhYmxlKCkoQWN0aW9uQnV0dG9uKTtcblxuZXhwb3J0c1snZGVmYXVsdCddID0gQWN0aW9uQnV0dG9uO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG4iLCIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnX19lc01vZHVsZScsIHtcbiAgICB2YWx1ZTogdHJ1ZVxufSk7XG5cbnZhciBfY3JlYXRlQ2xhc3MgPSAoZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKCd2YWx1ZScgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9IHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH07IH0pKCk7XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uJyk7IH0gfVxuXG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKCdtYXRlcmlhbC11aScpO1xuXG52YXIgRmxhdEJ1dHRvbiA9IF9yZXF1aXJlLkZsYXRCdXR0b247XG52YXIgSWNvbkJ1dHRvbiA9IF9yZXF1aXJlLkljb25CdXR0b247XG5cbnZhciBCdXR0b25zQ29tcHV0ZXIgPSAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIEJ1dHRvbnNDb21wdXRlcihweWRpbywgc2hhcmVNb2RlbCwgYnV0dG9uc1VwZGF0ZXIsIGRpc21pc3NDYWxsYmFjaywgZ2V0TWVzc2FnZSkge1xuICAgICAgICB2YXIgdXNlSWNvbkJ1dHRvbnMgPSBhcmd1bWVudHMubGVuZ3RoIDw9IDUgfHwgYXJndW1lbnRzWzVdID09PSB1bmRlZmluZWQgPyBmYWxzZSA6IGFyZ3VtZW50c1s1XTtcblxuICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgQnV0dG9uc0NvbXB1dGVyKTtcblxuICAgICAgICB0aGlzLnB5ZGlvID0gcHlkaW87XG4gICAgICAgIHRoaXMuX2J1dHRvbnNVcGRhdGVyID0gYnV0dG9uc1VwZGF0ZXI7XG4gICAgICAgIHRoaXMuX2Rpc21pc3NDYWxsYmFjayA9IGRpc21pc3NDYWxsYmFjaztcbiAgICAgICAgdGhpcy5fc2hhcmVNb2RlbCA9IHNoYXJlTW9kZWw7XG4gICAgICAgIHRoaXMuX3NhdmVEaXNhYmxlZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLl9nZXRNZXNzYWdlID0gZ2V0TWVzc2FnZTtcbiAgICAgICAgdGhpcy5faWNvbkJ1dHRvbnMgPSB1c2VJY29uQnV0dG9ucztcbiAgICB9XG5cbiAgICBfY3JlYXRlQ2xhc3MoQnV0dG9uc0NvbXB1dGVyLCBbe1xuICAgICAgICBrZXk6ICdlbmFibGVTYXZlJyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGVuYWJsZVNhdmUoKSB7XG4gICAgICAgICAgICB0aGlzLl9zYXZlRGlzYWJsZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMubW9kZWxVcGRhdGVkKCk7XG4gICAgICAgIH1cbiAgICB9LCB7XG4gICAgICAgIGtleTogJ2Rpc2FibGVTYXZlJyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGRpc2FibGVTYXZlKCkge1xuICAgICAgICAgICAgdGhpcy5fc2F2ZURpc2FibGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMubW9kZWxVcGRhdGVkKCk7XG4gICAgICAgIH1cbiAgICB9LCB7XG4gICAgICAgIGtleTogJ3RyaWdnZXJNb2RlbFNhdmUnLFxuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gdHJpZ2dlck1vZGVsU2F2ZSgpIHtcbiAgICAgICAgICAgIHRoaXMuX3NoYXJlTW9kZWwuc2F2ZSgpO1xuICAgICAgICB9XG4gICAgfSwge1xuICAgICAgICBrZXk6ICd0cmlnZ2VyTW9kZWxSZXZlcnQnLFxuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gdHJpZ2dlck1vZGVsUmV2ZXJ0KCkge1xuICAgICAgICAgICAgdGhpcy5fc2hhcmVNb2RlbC5yZXZlcnRDaGFuZ2VzKCk7XG4gICAgICAgIH1cbiAgICB9LCB7XG4gICAgICAgIGtleTogJ2Rpc2FibGVBbGxTaGFyZScsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiBkaXNhYmxlQWxsU2hhcmUoKSB7XG4gICAgICAgICAgICB0aGlzLl9zaGFyZU1vZGVsLnN0b3BTaGFyaW5nKHRoaXMuX2Rpc21pc3NDYWxsYmFjay5iaW5kKHRoaXMpKTtcbiAgICAgICAgfVxuICAgIH0sIHtcbiAgICAgICAga2V5OiAnbW9kZWxVcGRhdGVkJyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIG1vZGVsVXBkYXRlZCgpIHtcbiAgICAgICAgICAgIHRoaXMuX2J1dHRvbnNVcGRhdGVyKHRoaXMuZ2V0QnV0dG9ucygpKTtcbiAgICAgICAgfVxuICAgIH0sIHtcbiAgICAgICAga2V5OiAndmFsaWRTdGF0dXNPYnNlcnZlcicsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiB2YWxpZFN0YXR1c09ic2VydmVyKHN0YXR1cykge1xuICAgICAgICAgICAgaWYgKHN0YXR1cykgdGhpcy5lbmFibGVTYXZlKCk7ZWxzZSB0aGlzLmRpc2FibGVTYXZlKCk7XG4gICAgICAgIH1cbiAgICB9LCB7XG4gICAgICAgIGtleTogJ3N0YXJ0JyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHN0YXJ0KCkge1xuICAgICAgICAgICAgdGhpcy5fbW9kZWxPYnNlcnZlciA9IHRoaXMubW9kZWxVcGRhdGVkLmJpbmQodGhpcyk7XG4gICAgICAgICAgICB0aGlzLl9kaXNhYmxlU2F2ZU9ic2VydmVyID0gdGhpcy5kaXNhYmxlU2F2ZS5iaW5kKHRoaXMpO1xuICAgICAgICAgICAgdGhpcy5fZW5hYmxlU2F2ZU9ic2VydmVyID0gdGhpcy5lbmFibGVTYXZlLmJpbmQodGhpcyk7XG4gICAgICAgICAgICB0aGlzLl92YWxpZFN0YXR1c09ic2VydmVyID0gdGhpcy52YWxpZFN0YXR1c09ic2VydmVyLmJpbmQodGhpcyk7XG4gICAgICAgICAgICB0aGlzLl9zaGFyZU1vZGVsLm9ic2VydmUoXCJzdGF0dXNfY2hhbmdlZFwiLCB0aGlzLl9tb2RlbE9ic2VydmVyKTtcbiAgICAgICAgICAgIHRoaXMuX3NoYXJlTW9kZWwub2JzZXJ2ZSgnc2F2aW5nJywgdGhpcy5fZGlzYWJsZVNhdmVPYnNlcnZlcik7XG4gICAgICAgICAgICB0aGlzLl9zaGFyZU1vZGVsLm9ic2VydmUoJ3NhdmVkJywgdGhpcy5fZW5hYmxlU2F2ZU9ic2VydmVyKTtcbiAgICAgICAgICAgIHRoaXMuX3NoYXJlTW9kZWwub2JzZXJ2ZSgndmFsaWRfc3RhdHVzJywgdGhpcy5fdmFsaWRTdGF0dXNPYnNlcnZlcik7XG4gICAgICAgIH1cbiAgICB9LCB7XG4gICAgICAgIGtleTogJ3N0b3AnLFxuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gc3RvcCgpIHtcbiAgICAgICAgICAgIHRoaXMuX3NoYXJlTW9kZWwuc3RvcE9ic2VydmluZyhcInN0YXR1c19jaGFuZ2VkXCIsIHRoaXMuX21vZGVsT2JzZXJ2ZXIpO1xuICAgICAgICAgICAgdGhpcy5fc2hhcmVNb2RlbC5zdG9wT2JzZXJ2aW5nKCdzYXZpbmcnLCB0aGlzLl9kaXNhYmxlU2F2ZU9ic2VydmVyKTtcbiAgICAgICAgICAgIHRoaXMuX3NoYXJlTW9kZWwuc3RvcE9ic2VydmluZygnc2F2ZWQnLCB0aGlzLl9lbmFibGVTYXZlT2JzZXJ2ZXIpO1xuICAgICAgICAgICAgdGhpcy5fc2hhcmVNb2RlbC5zdG9wT2JzZXJ2aW5nKCd2YWxpZF9zdGF0dXMnLCB0aGlzLl92YWxpZFN0YXR1c09ic2VydmVyKTtcbiAgICAgICAgfVxuICAgIH0sIHtcbiAgICAgICAga2V5OiAnZ2V0QnV0dG9ucycsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiBnZXRCdXR0b25zKCkge1xuICAgICAgICAgICAgdmFyIGJ1dHRvbnMgPSBbXTtcbiAgICAgICAgICAgIHZhciBpYyA9IHRoaXMuX2ljb25CdXR0b25zO1xuICAgICAgICAgICAgaWYgKHRoaXMuX3NoYXJlTW9kZWwuZ2V0U3RhdHVzKCkgPT0gJ21vZGlmaWVkJykge1xuICAgICAgICAgICAgICAgIGlmIChpYykge1xuICAgICAgICAgICAgICAgICAgICBidXR0b25zLnB1c2goUmVhY3QuY3JlYXRlRWxlbWVudChJY29uQnV0dG9uLCB7IGljb25DbGFzc05hbWU6ICdtZGkgbWRpLXVuZG8tdmFyaWFudCcsIG9uVG91Y2hUYXA6IHRoaXMudHJpZ2dlck1vZGVsUmV2ZXJ0LmJpbmQodGhpcyksIHRvb2x0aXA6IHRoaXMuX2dldE1lc3NhZ2UoJzE3OScpIH0pKTtcbiAgICAgICAgICAgICAgICAgICAgYnV0dG9ucy5wdXNoKFJlYWN0LmNyZWF0ZUVsZW1lbnQoSWNvbkJ1dHRvbiwgeyBpY29uQ2xhc3NOYW1lOiAnbWRpIG1kaS1jaGVjaycsIHNlY29uZGFyeTogdHJ1ZSwgZGlzYWJsZWQ6IHRoaXMuX3NhdmVEaXNhYmxlZCwgdG9vbHRpcDogdGhpcy5fZ2V0TWVzc2FnZSgnNTMnLCAnJyksIG9uVG91Y2hUYXA6IHRoaXMudHJpZ2dlck1vZGVsU2F2ZS5iaW5kKHRoaXMpIH0pKTtcbiAgICAgICAgICAgICAgICAgICAgYnV0dG9ucy5wdXNoKFJlYWN0LmNyZWF0ZUVsZW1lbnQoSWNvbkJ1dHRvbiwgeyBpY29uQ2xhc3NOYW1lOiAnbWRpIG1kaS1jbG9zZScsIHNlY29uZGFyeTogZmFsc2UsIHRvb2x0aXA6IHRoaXMuX2dldE1lc3NhZ2UoJzg2JywgJycpLCBvblRvdWNoVGFwOiB0aGlzLl9kaXNtaXNzQ2FsbGJhY2suYmluZCh0aGlzKSB9KSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgYnV0dG9ucy5wdXNoKFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICAgICAnYScsXG4gICAgICAgICAgICAgICAgICAgICAgICB7IHN0eWxlOiB7IGN1cnNvcjogJ3BvaW50ZXInLCBjb2xvcjogJ3JnYmEoMCwwLDAsMC41MyknIH0sIG9uQ2xpY2s6IHRoaXMudHJpZ2dlck1vZGVsUmV2ZXJ0LmJpbmQodGhpcykgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX2dldE1lc3NhZ2UoJzE3OScpXG4gICAgICAgICAgICAgICAgICAgICkpO1xuICAgICAgICAgICAgICAgICAgICBidXR0b25zLnB1c2goUmVhY3QuY3JlYXRlRWxlbWVudChGbGF0QnV0dG9uLCB7IHNlY29uZGFyeTogdHJ1ZSwgZGlzYWJsZWQ6IHRoaXMuX3NhdmVEaXNhYmxlZCwgbGFiZWw6IHRoaXMuX2dldE1lc3NhZ2UoJzUzJywgJycpLCBvblRvdWNoVGFwOiB0aGlzLnRyaWdnZXJNb2RlbFNhdmUuYmluZCh0aGlzKSB9KSk7XG4gICAgICAgICAgICAgICAgICAgIGJ1dHRvbnMucHVzaChSZWFjdC5jcmVhdGVFbGVtZW50KEZsYXRCdXR0b24sIHsgc2Vjb25kYXJ5OiBmYWxzZSwgbGFiZWw6IHRoaXMuX2dldE1lc3NhZ2UoJzg2JywgJycpLCBvblRvdWNoVGFwOiB0aGlzLl9kaXNtaXNzQ2FsbGJhY2suYmluZCh0aGlzKSB9KSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fc2hhcmVNb2RlbC5oYXNBY3RpdmVTaGFyZXMoKSAmJiB0aGlzLl9zaGFyZU1vZGVsLmN1cnJlbnRJc093bmVyKCkgfHwgdGhpcy5fc2hhcmVNb2RlbC5nZXRTdGF0dXMoKSA9PT0gJ2Vycm9yJyB8fCB0aGlzLnB5ZGlvLnVzZXIuYWN0aXZlUmVwb3NpdG9yeSA9PT0gXCJhanhwX2NvbmZcIikge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaWMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJ1dHRvbnMucHVzaChSZWFjdC5jcmVhdGVFbGVtZW50KEljb25CdXR0b24sIHsgaWNvbkNsYXNzTmFtZTogJ21kaSBtZGktY2FuY2VsJywgZGlzYWJsZWQ6IHRoaXMuX3NhdmVEaXNhYmxlZCwgc2Vjb25kYXJ5OiB0cnVlLCB0b29sdGlwOiB0aGlzLl9nZXRNZXNzYWdlKCc2JyksIG9uVG91Y2hUYXA6IHRoaXMuZGlzYWJsZUFsbFNoYXJlLmJpbmQodGhpcykgfSkpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgYnV0dG9ucy5wdXNoKFJlYWN0LmNyZWF0ZUVsZW1lbnQoRmxhdEJ1dHRvbiwgeyBkaXNhYmxlZDogdGhpcy5fc2F2ZURpc2FibGVkLCBzZWNvbmRhcnk6IHRydWUsIGxhYmVsOiB0aGlzLl9nZXRNZXNzYWdlKCc2JyksIG9uVG91Y2hUYXA6IHRoaXMuZGlzYWJsZUFsbFNoYXJlLmJpbmQodGhpcykgfSkpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChpYykge1xuICAgICAgICAgICAgICAgICAgICBidXR0b25zLnB1c2goUmVhY3QuY3JlYXRlRWxlbWVudChJY29uQnV0dG9uLCB7IGljb25DbGFzc05hbWU6ICdtZGkgbWRpLWNsb3NlJywgc2Vjb25kYXJ5OiBmYWxzZSwgdG9vbHRpcDogdGhpcy5fZ2V0TWVzc2FnZSgnODYnLCAnJyksIG9uVG91Y2hUYXA6IHRoaXMuX2Rpc21pc3NDYWxsYmFjay5iaW5kKHRoaXMpIH0pKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBidXR0b25zLnB1c2goUmVhY3QuY3JlYXRlRWxlbWVudChGbGF0QnV0dG9uLCB7IHNlY29uZGFyeTogZmFsc2UsIGxhYmVsOiB0aGlzLl9nZXRNZXNzYWdlKCc4NicsICcnKSwgb25Ub3VjaFRhcDogdGhpcy5fZGlzbWlzc0NhbGxiYWNrLmJpbmQodGhpcykgfSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBidXR0b25zO1xuICAgICAgICB9XG4gICAgfV0pO1xuXG4gICAgcmV0dXJuIEJ1dHRvbnNDb21wdXRlcjtcbn0pKCk7XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IEJ1dHRvbnNDb21wdXRlcjtcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ19fZXNNb2R1bGUnLCB7XG4gICAgdmFsdWU6IHRydWVcbn0pO1xuXG52YXIgX2V4dGVuZHMgPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uICh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTsgZm9yICh2YXIga2V5IGluIHNvdXJjZSkgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkgeyB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldOyB9IH0gfSByZXR1cm4gdGFyZ2V0OyB9O1xuXG52YXIgX2NyZWF0ZUNsYXNzID0gKGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmICgndmFsdWUnIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KSgpO1xuXG52YXIgX2dldCA9IGZ1bmN0aW9uIGdldChfeCwgX3gyLCBfeDMpIHsgdmFyIF9hZ2FpbiA9IHRydWU7IF9mdW5jdGlvbjogd2hpbGUgKF9hZ2FpbikgeyB2YXIgb2JqZWN0ID0gX3gsIHByb3BlcnR5ID0gX3gyLCByZWNlaXZlciA9IF94MzsgX2FnYWluID0gZmFsc2U7IGlmIChvYmplY3QgPT09IG51bGwpIG9iamVjdCA9IEZ1bmN0aW9uLnByb3RvdHlwZTsgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iamVjdCwgcHJvcGVydHkpOyBpZiAoZGVzYyA9PT0gdW5kZWZpbmVkKSB7IHZhciBwYXJlbnQgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2Yob2JqZWN0KTsgaWYgKHBhcmVudCA9PT0gbnVsbCkgeyByZXR1cm4gdW5kZWZpbmVkOyB9IGVsc2UgeyBfeCA9IHBhcmVudDsgX3gyID0gcHJvcGVydHk7IF94MyA9IHJlY2VpdmVyOyBfYWdhaW4gPSB0cnVlOyBkZXNjID0gcGFyZW50ID0gdW5kZWZpbmVkOyBjb250aW51ZSBfZnVuY3Rpb247IH0gfSBlbHNlIGlmICgndmFsdWUnIGluIGRlc2MpIHsgcmV0dXJuIGRlc2MudmFsdWU7IH0gZWxzZSB7IHZhciBnZXR0ZXIgPSBkZXNjLmdldDsgaWYgKGdldHRlciA9PT0gdW5kZWZpbmVkKSB7IHJldHVybiB1bmRlZmluZWQ7IH0gcmV0dXJuIGdldHRlci5jYWxsKHJlY2VpdmVyKTsgfSB9IH07XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uJyk7IH0gfVxuXG5mdW5jdGlvbiBfaW5oZXJpdHMoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSAnZnVuY3Rpb24nICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCAnICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfVxuXG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKCdyZWFjdCcpO1xuXG52YXIgQ29tcG9uZW50ID0gX3JlcXVpcmUuQ29tcG9uZW50O1xuXG52YXIgX3JlcXVpcmUyID0gcmVxdWlyZSgnbWF0ZXJpYWwtdWknKTtcblxudmFyIFBhcGVyID0gX3JlcXVpcmUyLlBhcGVyO1xuXG52YXIgQ2FyZCA9IChmdW5jdGlvbiAoX0NvbXBvbmVudCkge1xuICAgIF9pbmhlcml0cyhDYXJkLCBfQ29tcG9uZW50KTtcblxuICAgIGZ1bmN0aW9uIENhcmQoKSB7XG4gICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBDYXJkKTtcblxuICAgICAgICBfZ2V0KE9iamVjdC5nZXRQcm90b3R5cGVPZihDYXJkLnByb3RvdHlwZSksICdjb25zdHJ1Y3RvcicsIHRoaXMpLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfVxuXG4gICAgX2NyZWF0ZUNsYXNzKENhcmQsIFt7XG4gICAgICAgIGtleTogJ3JlbmRlcicsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXIoKSB7XG5cbiAgICAgICAgICAgIHZhciBzdHlsZSA9IHtcbiAgICAgICAgICAgICAgICBwYW5lbDogX2V4dGVuZHMoe1xuICAgICAgICAgICAgICAgICAgICBwYWRkaW5nOiAxNixcbiAgICAgICAgICAgICAgICAgICAgbWFyZ2luOiAxMFxuICAgICAgICAgICAgICAgIH0sIHRoaXMucHJvcHMuc3R5bGUpLFxuICAgICAgICAgICAgICAgIHRpdGxlOiBfZXh0ZW5kcyh7XG4gICAgICAgICAgICAgICAgICAgIHBhZGRpbmdUb3A6IDAsXG4gICAgICAgICAgICAgICAgICAgIGZvbnRTaXplOiAxOFxuICAgICAgICAgICAgICAgIH0sIHRoaXMucHJvcHMudGl0bGVTdHlsZSlcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgIFBhcGVyLFxuICAgICAgICAgICAgICAgIHsgekRlcHRoOiAxLCByb3VuZGVkOiBmYWxzZSwgc3R5bGU6IHN0eWxlLnBhbmVsIH0sXG4gICAgICAgICAgICAgICAgdGhpcy5wcm9wcy50aXRsZSAmJiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICAnaDMnLFxuICAgICAgICAgICAgICAgICAgICB7IHN0eWxlOiBzdHlsZS50aXRsZSB9LFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnByb3BzLnRpdGxlXG4gICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICB0aGlzLnByb3BzLmNoaWxkcmVuLFxuICAgICAgICAgICAgICAgIHRoaXMucHJvcHMuYWN0aW9ucyAmJiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICAgICAgeyBzdHlsZTogeyB0ZXh0QWxpZ246ICdjZW50ZXInLCBjbGVhcjogJ2JvdGgnLCBwb3NpdGlvbjogJ3JlbGF0aXZlJywgcGFkZGluZzogJzEwcHggMCcgfSB9LFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnByb3BzLmFjdGlvbnNcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgfV0pO1xuXG4gICAgcmV0dXJuIENhcmQ7XG59KShDb21wb25lbnQpO1xuXG5leHBvcnRzWydkZWZhdWx0J10gPSBDYXJkO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG4iLCIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnX19lc01vZHVsZScsIHtcbiAgICB2YWx1ZTogdHJ1ZVxufSk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7ICdkZWZhdWx0Jzogb2JqIH07IH1cblxudmFyIF9TaGFyZUNvbnRleHRDb25zdW1lciA9IHJlcXVpcmUoJy4uL1NoYXJlQ29udGV4dENvbnN1bWVyJyk7XG5cbnZhciBfU2hhcmVDb250ZXh0Q29uc3VtZXIyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfU2hhcmVDb250ZXh0Q29uc3VtZXIpO1xuXG52YXIgUmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpO1xuXG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKCdyZWFjdC10ZXh0Zml0Jyk7XG5cbnZhciBUZXh0Zml0ID0gX3JlcXVpcmUuVGV4dGZpdDtcblxudmFyIF9yZXF1aXJlMiA9IHJlcXVpcmUoJ21hdGVyaWFsLXVpL3N0eWxlcycpO1xuXG52YXIgbXVpVGhlbWVhYmxlID0gX3JlcXVpcmUyLm11aVRoZW1lYWJsZTtcblxudmFyIFBhdGhVdGlscyA9IHJlcXVpcmUoJ3B5ZGlvL3V0aWwvcGF0aCcpO1xuXG52YXIgSGVhZGVyUGFuZWwgPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG4gICAgZGlzcGxheU5hbWU6ICdIZWFkZXJQYW5lbCcsXG5cbiAgICByZW5kZXI6IGZ1bmN0aW9uIHJlbmRlcigpIHtcblxuICAgICAgICBpZiAodGhpcy5wcm9wcy5ub01vZGFsKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICB2YXIgbm9kZVBhdGggPSB0aGlzLnByb3BzLnNoYXJlTW9kZWwuZ2V0Tm9kZSgpLmdldFBhdGgoKTtcbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAnaGVhZGVyUGFuZWwnLCBzdHlsZTogeyBiYWNrZ3JvdW5kQ29sb3I6IHRoaXMucHJvcHMubXVpVGhlbWUucGFsZXR0ZS5wcmltYXJ5MUNvbG9yIH0gfSxcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgVGV4dGZpdCxcbiAgICAgICAgICAgICAgICB7IG1vZGU6ICdzaW5nbGUnLCBtYXg6IDMwIH0sXG4gICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5nZXRNZXNzYWdlKCc0NCcpLnJlcGxhY2UoJyVzJywgUGF0aFV0aWxzLmdldEJhc2VuYW1lKG5vZGVQYXRoKSlcbiAgICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICB9XG59KTtcblxuZXhwb3J0c1snZGVmYXVsdCddID0gSGVhZGVyUGFuZWwgPSAoMCwgX1NoYXJlQ29udGV4dENvbnN1bWVyMlsnZGVmYXVsdCddKShIZWFkZXJQYW5lbCk7XG5leHBvcnRzWydkZWZhdWx0J10gPSBIZWFkZXJQYW5lbCA9IG11aVRoZW1lYWJsZSgpKEhlYWRlclBhbmVsKTtcblxuZXhwb3J0c1snZGVmYXVsdCddID0gSGVhZGVyUGFuZWw7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTtcbiIsIid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdfX2VzTW9kdWxlJywge1xuICAgIHZhbHVlOiB0cnVlXG59KTtcblxudmFyIF9jcmVhdGVDbGFzcyA9IChmdW5jdGlvbiAoKSB7IGZ1bmN0aW9uIGRlZmluZVByb3BlcnRpZXModGFyZ2V0LCBwcm9wcykgeyBmb3IgKHZhciBpID0gMDsgaSA8IHByb3BzLmxlbmd0aDsgaSsrKSB7IHZhciBkZXNjcmlwdG9yID0gcHJvcHNbaV07IGRlc2NyaXB0b3IuZW51bWVyYWJsZSA9IGRlc2NyaXB0b3IuZW51bWVyYWJsZSB8fCBmYWxzZTsgZGVzY3JpcHRvci5jb25maWd1cmFibGUgPSB0cnVlOyBpZiAoJ3ZhbHVlJyBpbiBkZXNjcmlwdG9yKSBkZXNjcmlwdG9yLndyaXRhYmxlID0gdHJ1ZTsgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgZGVzY3JpcHRvci5rZXksIGRlc2NyaXB0b3IpOyB9IH0gcmV0dXJuIGZ1bmN0aW9uIChDb25zdHJ1Y3RvciwgcHJvdG9Qcm9wcywgc3RhdGljUHJvcHMpIHsgaWYgKHByb3RvUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IucHJvdG90eXBlLCBwcm90b1Byb3BzKTsgaWYgKHN0YXRpY1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLCBzdGF0aWNQcm9wcyk7IHJldHVybiBDb25zdHJ1Y3RvcjsgfTsgfSkoKTtcblxudmFyIF9nZXQgPSBmdW5jdGlvbiBnZXQoX3g1LCBfeDYsIF94NykgeyB2YXIgX2FnYWluID0gdHJ1ZTsgX2Z1bmN0aW9uOiB3aGlsZSAoX2FnYWluKSB7IHZhciBvYmplY3QgPSBfeDUsIHByb3BlcnR5ID0gX3g2LCByZWNlaXZlciA9IF94NzsgX2FnYWluID0gZmFsc2U7IGlmIChvYmplY3QgPT09IG51bGwpIG9iamVjdCA9IEZ1bmN0aW9uLnByb3RvdHlwZTsgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iamVjdCwgcHJvcGVydHkpOyBpZiAoZGVzYyA9PT0gdW5kZWZpbmVkKSB7IHZhciBwYXJlbnQgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2Yob2JqZWN0KTsgaWYgKHBhcmVudCA9PT0gbnVsbCkgeyByZXR1cm4gdW5kZWZpbmVkOyB9IGVsc2UgeyBfeDUgPSBwYXJlbnQ7IF94NiA9IHByb3BlcnR5OyBfeDcgPSByZWNlaXZlcjsgX2FnYWluID0gdHJ1ZTsgZGVzYyA9IHBhcmVudCA9IHVuZGVmaW5lZDsgY29udGludWUgX2Z1bmN0aW9uOyB9IH0gZWxzZSBpZiAoJ3ZhbHVlJyBpbiBkZXNjKSB7IHJldHVybiBkZXNjLnZhbHVlOyB9IGVsc2UgeyB2YXIgZ2V0dGVyID0gZGVzYy5nZXQ7IGlmIChnZXR0ZXIgPT09IHVuZGVmaW5lZCkgeyByZXR1cm4gdW5kZWZpbmVkOyB9IHJldHVybiBnZXR0ZXIuY2FsbChyZWNlaXZlcik7IH0gfSB9O1xuXG52YXIgX2V4dGVuZHMgPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uICh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTsgZm9yICh2YXIga2V5IGluIHNvdXJjZSkgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkgeyB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldOyB9IH0gfSByZXR1cm4gdGFyZ2V0OyB9O1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyAnZGVmYXVsdCc6IG9iaiB9OyB9XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uJyk7IH0gfVxuXG5mdW5jdGlvbiBfaW5oZXJpdHMoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSAnZnVuY3Rpb24nICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCAnICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfVxuXG52YXIgX0hlYWRlciA9IHJlcXVpcmUoJy4vSGVhZGVyJyk7XG5cbnZhciBfSGVhZGVyMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX0hlYWRlcik7XG5cbnZhciBfcHVibGljUGFuZWwgPSByZXF1aXJlKCcuLi9wdWJsaWMvUGFuZWwnKTtcblxudmFyIF9wdWJsaWNQYW5lbDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9wdWJsaWNQYW5lbCk7XG5cbnZhciBfdXNlcnNQYW5lbCA9IHJlcXVpcmUoJy4uL3VzZXJzL1BhbmVsJyk7XG5cbnZhciBfdXNlcnNQYW5lbDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF91c2Vyc1BhbmVsKTtcblxudmFyIF9hZHZhbmNlZFBhbmVsID0gcmVxdWlyZSgnLi4vYWR2YW5jZWQvUGFuZWwnKTtcblxudmFyIF9hZHZhbmNlZFBhbmVsMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2FkdmFuY2VkUGFuZWwpO1xuXG52YXIgX0J1dHRvbnNDb21wdXRlciA9IHJlcXVpcmUoJy4vQnV0dG9uc0NvbXB1dGVyJyk7XG5cbnZhciBfQnV0dG9uc0NvbXB1dGVyMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX0J1dHRvbnNDb21wdXRlcik7XG5cbnZhciBSZWFjdCA9IHJlcXVpcmUoJ3JlYWN0Jyk7XG5cbnZhciBfcmVxdWlyZSA9IHJlcXVpcmUoJ21hdGVyaWFsLXVpJyk7XG5cbnZhciBUYWJzID0gX3JlcXVpcmUuVGFicztcbnZhciBUYWIgPSBfcmVxdWlyZS5UYWI7XG52YXIgVG9nZ2xlID0gX3JlcXVpcmUuVG9nZ2xlO1xuXG52YXIgX3JlcXVpcmUkcmVxdWlyZUxpYiA9IHJlcXVpcmUoJ3B5ZGlvJykucmVxdWlyZUxpYignYm9vdCcpO1xuXG52YXIgQWN0aW9uRGlhbG9nTWl4aW4gPSBfcmVxdWlyZSRyZXF1aXJlTGliLkFjdGlvbkRpYWxvZ01peGluO1xuXG52YXIgU2hhcmVNb2RlbCA9IHJlcXVpcmUoJ3B5ZGlvJykucmVxdWlyZUxpYignUmVhY3RNb2RlbFNoYXJlJyk7XG5cbnZhciBfcmVxdWlyZSRyZXF1aXJlTGliMiA9IHJlcXVpcmUoJ3B5ZGlvJykucmVxdWlyZUxpYignaG9jJyk7XG5cbnZhciBQYWxldHRlTW9kaWZpZXIgPSBfcmVxdWlyZSRyZXF1aXJlTGliMi5QYWxldHRlTW9kaWZpZXI7XG5cbnZhciBNYWluUGFuZWwgPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG4gICAgZGlzcGxheU5hbWU6ICdNYWluUGFuZWwnLFxuXG4gICAgbWl4aW5zOiBbQWN0aW9uRGlhbG9nTWl4aW5dLFxuXG4gICAgZ2V0RGVmYXVsdFByb3BzOiBmdW5jdGlvbiBnZXREZWZhdWx0UHJvcHMoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBkaWFsb2dUaXRsZTogJycsXG4gICAgICAgICAgICBkaWFsb2dJc01vZGFsOiBmYWxzZSxcbiAgICAgICAgICAgIGRpYWxvZ1BhZGRpbmc6IGZhbHNlXG4gICAgICAgIH07XG4gICAgfSxcblxuICAgIHByb3BUeXBlczoge1xuICAgICAgICBweWRpbzogUmVhY3QuUHJvcFR5cGVzLmluc3RhbmNlT2YoUHlkaW8pLmlzUmVxdWlyZWQsXG4gICAgICAgIHNlbGVjdGlvbjogUmVhY3QuUHJvcFR5cGVzLmluc3RhbmNlT2YoUHlkaW9EYXRhTW9kZWwpLmlzUmVxdWlyZWQsXG4gICAgICAgIHJlYWRvbmx5OiBSZWFjdC5Qcm9wVHlwZXMuYm9vbFxuICAgIH0sXG5cbiAgICBjaGlsZENvbnRleHRUeXBlczoge1xuICAgICAgICBtZXNzYWdlczogUmVhY3QuUHJvcFR5cGVzLm9iamVjdCxcbiAgICAgICAgZ2V0TWVzc2FnZTogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsXG4gICAgICAgIGlzUmVhZG9ubHk6IFJlYWN0LlByb3BUeXBlcy5mdW5jXG4gICAgfSxcblxuICAgIGdldENoaWxkQ29udGV4dDogZnVuY3Rpb24gZ2V0Q2hpbGRDb250ZXh0KCkge1xuICAgICAgICB2YXIgbWVzc2FnZXMgPSB0aGlzLnByb3BzLnB5ZGlvLk1lc3NhZ2VIYXNoO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgbWVzc2FnZXM6IG1lc3NhZ2VzLFxuICAgICAgICAgICAgZ2V0TWVzc2FnZTogZnVuY3Rpb24gZ2V0TWVzc2FnZShtZXNzYWdlSWQpIHtcbiAgICAgICAgICAgICAgICB2YXIgbmFtZXNwYWNlID0gYXJndW1lbnRzLmxlbmd0aCA8PSAxIHx8IGFyZ3VtZW50c1sxXSA9PT0gdW5kZWZpbmVkID8gJ3NoYXJlX2NlbnRlcicgOiBhcmd1bWVudHNbMV07XG5cbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbWVzc2FnZXNbbmFtZXNwYWNlICsgKG5hbWVzcGFjZSA/IFwiLlwiIDogXCJcIikgKyBtZXNzYWdlSWRdIHx8IG1lc3NhZ2VJZDtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBtZXNzYWdlSWQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGlzUmVhZG9ubHk6IChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMucHJvcHMucmVhZG9ubHk7XG4gICAgICAgICAgICB9KS5iaW5kKHRoaXMpXG4gICAgICAgIH07XG4gICAgfSxcblxuICAgIG1vZGVsVXBkYXRlZDogZnVuY3Rpb24gbW9kZWxVcGRhdGVkKGV2ZW50RGF0YSkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgICAgIGlmICh0aGlzLmlzTW91bnRlZCgpKSB7XG4gICAgICAgICAgICB2YXIgbW9kZWxGaXJzdExvYWQgPSB0aGlzLnN0YXRlLm1vZGVsRmlyc3RMb2FkO1xuXG4gICAgICAgICAgICB2YXIgYWZ0ZXJTdGF0ZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIGlmIChtb2RlbEZpcnN0TG9hZCkge1xuICAgICAgICAgICAgICAgIGFmdGVyU3RhdGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzLnNldFN0YXRlKHsgbW9kZWxGaXJzdExvYWQ6IGZhbHNlIH0pO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgICAgICBzdGF0dXM6IGV2ZW50RGF0YS5zdGF0dXMsXG4gICAgICAgICAgICAgICAgbW9kZWw6IGV2ZW50RGF0YS5tb2RlbFxuICAgICAgICAgICAgfSwgYWZ0ZXJTdGF0ZSk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgZ2V0SW5pdGlhbFN0YXRlOiBmdW5jdGlvbiBnZXRJbml0aWFsU3RhdGUoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdGF0dXM6ICdpZGxlJyxcbiAgICAgICAgICAgIG1haWxlckRhdGE6IGZhbHNlLFxuICAgICAgICAgICAgbW9kZWw6IG5ldyBTaGFyZU1vZGVsKHRoaXMucHJvcHMucHlkaW8sIHRoaXMucHJvcHMuc2VsZWN0aW9uLmdldFVuaXF1ZU5vZGUoKSwgdGhpcy5wcm9wcy5zZWxlY3Rpb24pLFxuICAgICAgICAgICAgbW9kZWxGaXJzdExvYWQ6IHRydWVcbiAgICAgICAgfTtcbiAgICB9LFxuXG4gICAgY29tcG9uZW50RGlkTW91bnQ6IGZ1bmN0aW9uIGNvbXBvbmVudERpZE1vdW50KCkge1xuICAgICAgICB0aGlzLnN0YXRlLm1vZGVsLm9ic2VydmUoXCJzdGF0dXNfY2hhbmdlZFwiLCB0aGlzLm1vZGVsVXBkYXRlZCk7XG4gICAgICAgIHRoaXMuc3RhdGUubW9kZWwuaW5pdExvYWQoKTtcbiAgICB9LFxuXG4gICAgY29tcG9uZW50V2lsbFVubW91bnQ6IGZ1bmN0aW9uIGNvbXBvbmVudFdpbGxVbm1vdW50KCkge1xuICAgICAgICBpZiAodGhpcy5idXR0b25zQ29tcHV0ZXIpIHRoaXMuYnV0dG9uc0NvbXB1dGVyLnN0b3AoKTtcbiAgICB9LFxuXG4gICAgY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wczogZnVuY3Rpb24gY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyhuZXh0UHJvcHMpIHtcbiAgICAgICAgdmFyIF90aGlzMiA9IHRoaXM7XG5cbiAgICAgICAgaWYgKG5leHRQcm9wcy5zZWxlY3Rpb24gJiYgbmV4dFByb3BzLnNlbGVjdGlvbiAhPT0gdGhpcy5wcm9wcy5zZWxlY3Rpb24pIHtcbiAgICAgICAgICAgIHZhciBuZXh0TW9kZWwgPSBuZXcgU2hhcmVNb2RlbCh0aGlzLnByb3BzLnB5ZGlvLCBuZXh0UHJvcHMuc2VsZWN0aW9uLmdldFVuaXF1ZU5vZGUoKSwgbmV4dFByb3BzLnNlbGVjdGlvbik7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgbW9kZWw6IG5leHRNb2RlbCwgc3RhdHVzOiAnaWRsZScsIG1haWxlckRhdGE6IGZhbHNlIH0sIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBfdGhpczIuY29tcG9uZW50RGlkTW91bnQoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIGdldEJ1dHRvbnM6IGZ1bmN0aW9uIGdldEJ1dHRvbnModXBkYXRlcikge1xuXG4gICAgICAgIHRoaXMuYnV0dG9uc0NvbXB1dGVyID0gbmV3IF9CdXR0b25zQ29tcHV0ZXIyWydkZWZhdWx0J10odGhpcy5wcm9wcy5weWRpbywgdGhpcy5zdGF0ZS5tb2RlbCwgdXBkYXRlciwgdGhpcy5kaXNtaXNzLCB0aGlzLmdldE1lc3NhZ2UsIHRoaXMucHJvcHMubm9Nb2RhbCk7XG4gICAgICAgIHRoaXMuYnV0dG9uc0NvbXB1dGVyLnN0YXJ0KCk7XG4gICAgICAgIHJldHVybiB0aGlzLmJ1dHRvbnNDb21wdXRlci5nZXRCdXR0b25zKCk7XG4gICAgfSxcblxuICAgIHNob3dNYWlsZXI6IGZ1bmN0aW9uIHNob3dNYWlsZXIoc3ViamVjdCwgbWVzc2FnZSkge1xuICAgICAgICB2YXIgdXNlcnMgPSBhcmd1bWVudHMubGVuZ3RoIDw9IDIgfHwgYXJndW1lbnRzWzJdID09PSB1bmRlZmluZWQgPyBbXSA6IGFyZ3VtZW50c1syXTtcbiAgICAgICAgdmFyIGhhc2ggPSBhcmd1bWVudHMubGVuZ3RoIDw9IDMgfHwgYXJndW1lbnRzWzNdID09PSB1bmRlZmluZWQgPyBudWxsIDogYXJndW1lbnRzWzNdO1xuXG4gICAgICAgIGlmIChTaGFyZU1vZGVsLmZvcmNlTWFpbGVyT2xkU2Nob29sKCkpIHtcbiAgICAgICAgICAgIHN1YmplY3QgPSBlbmNvZGVVUklDb21wb25lbnQoc3ViamVjdCk7XG4gICAgICAgICAgICBnbG9iYWwubG9jYXRpb24uaHJlZiA9IFwibWFpbHRvOmN1c3RvbS1lbWFpbEBkb21haW4uY29tP1N1YmplY3Q9XCIgKyBzdWJqZWN0ICsgXCImQm9keT1cIiArIG1lc3NhZ2U7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGxpbmtEYXRhID0gaGFzaCA/IHRoaXMuc3RhdGUubW9kZWwuZ2V0TGlua0RhdGEoaGFzaCkgOiB1bmRlZmluZWQ7XG4gICAgICAgIGdsb2JhbC5SZXNvdXJjZXNNYW5hZ2VyLmxvYWRDbGFzc2VzQW5kQXBwbHkoWydQeWRpb01haWxlciddLCAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgICAgbWFpbGVyRGF0YToge1xuICAgICAgICAgICAgICAgICAgICBzdWJqZWN0OiBzdWJqZWN0LFxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICAgICAgICAgICAgICAgICAgICB1c2VyczogdXNlcnMsXG4gICAgICAgICAgICAgICAgICAgIGhhc2g6IGhhc2gsXG4gICAgICAgICAgICAgICAgICAgIGVuYWJsZUlkZW50aWZpY2F0aW9uOiBsaW5rRGF0YSAmJiBsaW5rRGF0YS50YXJnZXRfdXNlcnMsXG4gICAgICAgICAgICAgICAgICAgIGNyaXBwbGVJZGVudGlmaWNhdGlvbktleXM6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIGlkZW50aWZpZWRPbmx5OiBsaW5rRGF0YSAmJiBsaW5rRGF0YS5yZXN0cmljdF90b190YXJnZXRfdXNlcnNcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSkuYmluZCh0aGlzKSk7XG4gICAgfSxcblxuICAgIHRvZ2dsZU1haWxlckRhdGE6IGZ1bmN0aW9uIHRvZ2dsZU1haWxlckRhdGEoZGF0YSkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgbWFpbGVyRGF0YTogX2V4dGVuZHMoe30sIHRoaXMuc3RhdGUubWFpbGVyRGF0YSwgZGF0YSkgfSk7XG4gICAgfSxcblxuICAgIGRpc21pc3NNYWlsZXI6IGZ1bmN0aW9uIGRpc21pc3NNYWlsZXIoKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBtYWlsZXJEYXRhOiBmYWxzZSB9KTtcbiAgICB9LFxuXG4gICAgbWFpbGVyUHJvY2Vzc1Bvc3Q6IGZ1bmN0aW9uIG1haWxlclByb2Nlc3NQb3N0KEVtYWlsLCB1c2Vycywgc3ViamVjdCwgbWVzc2FnZSwgbGluaywgY2FsbGJhY2spIHtcbiAgICAgICAgdmFyIF9zdGF0ZSA9IHRoaXMuc3RhdGU7XG4gICAgICAgIHZhciBtb2RlbCA9IF9zdGF0ZS5tb2RlbDtcbiAgICAgICAgdmFyIG1haWxlckRhdGEgPSBfc3RhdGUubWFpbGVyRGF0YTtcbiAgICAgICAgdmFyIGNyaXBwbGVJZGVudGlmaWNhdGlvbktleXMgPSBtYWlsZXJEYXRhLmNyaXBwbGVJZGVudGlmaWNhdGlvbktleXM7XG4gICAgICAgIHZhciBpZGVudGlmaWVkT25seSA9IG1haWxlckRhdGEuaWRlbnRpZmllZE9ubHk7XG4gICAgICAgIHZhciBoYXNoID0gbWFpbGVyRGF0YS5oYXNoO1xuXG4gICAgICAgIHZhciBjbGllbnQgPSBQeWRpb0FwaS5nZXRDbGllbnQoKTtcbiAgICAgICAgdmFyIHNoYXJlTGFiZWxzID0ge30sXG4gICAgICAgICAgICBzaGFyZU1haWxzID0ge307XG4gICAgICAgIE9iamVjdC5rZXlzKHVzZXJzKS5mb3JFYWNoKGZ1bmN0aW9uICh1KSB7XG4gICAgICAgICAgICB2YXIgayA9IGNyaXBwbGVJZGVudGlmaWNhdGlvbktleXMgPyBNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKDM2KS5zdWJzdHJpbmcoNykgOiB1O1xuICAgICAgICAgICAgc2hhcmVMYWJlbHNba10gPSB1c2Vyc1t1XS5nZXRMYWJlbCgpO1xuICAgICAgICAgICAgc2hhcmVNYWlsc1trXSA9IHU7XG4gICAgICAgIH0pO1xuICAgICAgICAvLyBTdG9yZSBrZXlzXG4gICAgICAgIGNsaWVudC5yZXF1ZXN0KHtcbiAgICAgICAgICAgIGdldF9hY3Rpb246ICdzaGFyZV9saW5rX3VwZGF0ZV90YXJnZXRfdXNlcnMnLFxuICAgICAgICAgICAgaGFzaDogaGFzaCxcbiAgICAgICAgICAgIGpzb25fdXNlcnM6IEpTT04uc3RyaW5naWZ5KHNoYXJlTGFiZWxzKSxcbiAgICAgICAgICAgIHJlc3RyaWN0OiBpZGVudGlmaWVkT25seSA/ICd0cnVlJyA6ICdmYWxzZSdcbiAgICAgICAgfSwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIGVtYWlsID0gbmV3IEVtYWlsKCk7XG4gICAgICAgICAgICB2YXIgb3JpZ2luYWxMaW5rID0gbW9kZWwuZ2V0UHVibGljTGluayhoYXNoKTtcbiAgICAgICAgICAgIHZhciByZWdleHAgPSBuZXcgUmVnRXhwKG9yaWdpbmFsTGluaywgJ2cnKTtcbiAgICAgICAgICAgIE9iamVjdC5rZXlzKHNoYXJlTWFpbHMpLmZvckVhY2goZnVuY3Rpb24gKHUpIHtcbiAgICAgICAgICAgICAgICB2YXIgbmV3TGluayA9IG9yaWdpbmFsTGluayArICc/dT0nICsgdTtcbiAgICAgICAgICAgICAgICB2YXIgbmV3TWVzc2FnZSA9IG1lc3NhZ2UucmVwbGFjZShyZWdleHAsIG5ld0xpbmspO1xuICAgICAgICAgICAgICAgIGVtYWlsLmFkZFRhcmdldChzaGFyZU1haWxzW3VdLCBzdWJqZWN0LCBuZXdNZXNzYWdlKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgZW1haWwucG9zdChmdW5jdGlvbiAocmVzKSB7XG4gICAgICAgICAgICAgICAgaWYgKHJlcykge1xuICAgICAgICAgICAgICAgICAgICBtb2RlbC5sb2FkKHRydWUpOyAvLyBSZWxvYWQgZGF0YVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYWxsYmFjayhyZXMpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH0sXG5cbiAgICBnZXRNZXNzYWdlOiBmdW5jdGlvbiBnZXRNZXNzYWdlKGtleSkge1xuICAgICAgICB2YXIgbmFtZXNwYWNlID0gYXJndW1lbnRzLmxlbmd0aCA8PSAxIHx8IGFyZ3VtZW50c1sxXSA9PT0gdW5kZWZpbmVkID8gJ3NoYXJlX2NlbnRlcicgOiBhcmd1bWVudHNbMV07XG5cbiAgICAgICAgcmV0dXJuIHRoaXMucHJvcHMucHlkaW8uTWVzc2FnZUhhc2hbbmFtZXNwYWNlICsgKG5hbWVzcGFjZSA/ICcuJyA6ICcnKSArIGtleV07XG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgICB2YXIgX3RoaXMzID0gdGhpcztcblxuICAgICAgICB2YXIgX3N0YXRlMiA9IHRoaXMuc3RhdGU7XG4gICAgICAgIHZhciBtb2RlbCA9IF9zdGF0ZTIubW9kZWw7XG4gICAgICAgIHZhciBtb2RlbEZpcnN0TG9hZCA9IF9zdGF0ZTIubW9kZWxGaXJzdExvYWQ7XG5cbiAgICAgICAgdmFyIGJ1dHRvblN0eWxlID0geyB0ZXh0VHJhbnNmb3JtOiAnbm9uZScgfTtcbiAgICAgICAgdmFyIHNob3dNYWlsZXIgPSBTaGFyZU1vZGVsLm1haWxlckFjdGl2ZSgpID8gdGhpcy5zaG93TWFpbGVyIDogbnVsbDtcbiAgICAgICAgdmFyIGF1dGggPSBTaGFyZU1vZGVsLmdldEF1dGhvcml6YXRpb25zKHRoaXMucHJvcHMucHlkaW8pO1xuICAgICAgICB2YXIgcGFuZWxzID0gW10sXG4gICAgICAgICAgICBoYXNQdWJsaWNMaW5rID0gdW5kZWZpbmVkLFxuICAgICAgICAgICAgaW5pdGlhbFNlbGVjdGVkSW5kZXggPSB1bmRlZmluZWQ7XG5cbiAgICAgICAgaWYgKG1vZGVsLmdldE5vZGUoKS5pc0xlYWYoKSAmJiBhdXRoLmZpbGVfcHVibGljX2xpbmsgfHwgIW1vZGVsLmdldE5vZGUoKS5pc0xlYWYoKSAmJiBhdXRoLmZvbGRlcl9wdWJsaWNfbGluaykge1xuICAgICAgICAgICAgdmFyIHB1YmxpY0xpbmtzID0gbW9kZWwuZ2V0UHVibGljTGlua3MoKTtcbiAgICAgICAgICAgIHZhciBsaW5rRGF0YSA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIGlmIChwdWJsaWNMaW5rcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBsaW5rRGF0YSA9IHB1YmxpY0xpbmtzWzBdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIHB1YkxhYmVsID0gdGhpcy5nZXRNZXNzYWdlKDEyMSk7XG4gICAgICAgICAgICBpZiAobW9kZWwuaGFzUHVibGljTGluaygpKSB7XG4gICAgICAgICAgICAgICAgcHViTGFiZWwgPSBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICAnc3BhbicsXG4gICAgICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgICAgIHB1YkxhYmVsLFxuICAgICAgICAgICAgICAgICAgICAnICcsXG4gICAgICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nLCB7IGNsYXNzTmFtZTogJ21kaSBtZGktY2hlY2snIH0pXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICBoYXNQdWJsaWNMaW5rID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHBhbmVscy5wdXNoKFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgVGFiLFxuICAgICAgICAgICAgICAgIHsga2V5OiAncHVibGljLWxpbmsnLCB2YWx1ZTogJ3B1YmxpYy1saW5rJywgbGFiZWw6IHB1YkxhYmVsLCBidXR0b25TdHlsZTogYnV0dG9uU3R5bGUgfSxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KF9wdWJsaWNQYW5lbDJbJ2RlZmF1bHQnXSwge1xuICAgICAgICAgICAgICAgICAgICBzaG93TWFpbGVyOiBzaG93TWFpbGVyLFxuICAgICAgICAgICAgICAgICAgICBsaW5rRGF0YTogbGlua0RhdGEsXG4gICAgICAgICAgICAgICAgICAgIHB5ZGlvOiB0aGlzLnByb3BzLnB5ZGlvLFxuICAgICAgICAgICAgICAgICAgICBzaGFyZU1vZGVsOiBtb2RlbCxcbiAgICAgICAgICAgICAgICAgICAgYXV0aG9yaXphdGlvbnM6IGF1dGgsXG4gICAgICAgICAgICAgICAgICAgIHN0eWxlOiB7IGhlaWdodDogJzEwMCUnLCBvdmVyZmxvd1k6ICdhdXRvJyB9XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICkpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChtb2RlbC5nZXROb2RlKCkuaXNMZWFmKCkgJiYgYXV0aC5maWxlX3dvcmtzcGFjZXMgfHwgIW1vZGVsLmdldE5vZGUoKS5pc0xlYWYoKSAmJiBhdXRoLmZvbGRlcl93b3Jrc3BhY2VzKSB7XG4gICAgICAgICAgICB2YXIgdG90YWxVc2VycyA9IG1vZGVsLmdldFNoYXJlZFVzZXJzKCkubGVuZ3RoICsgbW9kZWwuZ2V0T2NzTGlua3MoKS5sZW5ndGg7XG4gICAgICAgICAgICBwYW5lbHMucHVzaChSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgIFRhYixcbiAgICAgICAgICAgICAgICB7IGtleTogJ3RhcmdldC11c2VycycsIHZhbHVlOiAndGFyZ2V0LXVzZXJzJywgbGFiZWw6IHRoaXMuZ2V0TWVzc2FnZSgyNDksICcnKSArICh0b3RhbFVzZXJzID8gJyAoJyArIHRvdGFsVXNlcnMgKyAnKScgOiAnJyksIGJ1dHRvblN0eWxlOiBidXR0b25TdHlsZSB9LFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoX3VzZXJzUGFuZWwyWydkZWZhdWx0J10sIHtcbiAgICAgICAgICAgICAgICAgICAgc2hvd01haWxlcjogc2hvd01haWxlcixcbiAgICAgICAgICAgICAgICAgICAgc2hhcmVNb2RlbDogbW9kZWwsXG4gICAgICAgICAgICAgICAgICAgIHB5ZGlvOiB0aGlzLnByb3BzLnB5ZGlvLFxuICAgICAgICAgICAgICAgICAgICBzdHlsZTogeyBoZWlnaHQ6ICcxMDAlJywgb3ZlcmZsb3dZOiAnYXV0bycgfVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICApKTtcbiAgICAgICAgICAgIGlmIChtb2RlbEZpcnN0TG9hZCAmJiAhaGFzUHVibGljTGluayAmJiB0b3RhbFVzZXJzKSB7XG4gICAgICAgICAgICAgICAgaW5pdGlhbFNlbGVjdGVkSW5kZXggPSAndGFyZ2V0LXVzZXJzJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAocGFuZWxzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHBhbmVscy5wdXNoKFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgVGFiLFxuICAgICAgICAgICAgICAgIHsga2V5OiAnc2hhcmUtcGVybWlzc2lvbnMnLCB2YWx1ZTogJ3NoYXJlLXBlcm1pc3Npb25zJywgbGFiZWw6IHRoaXMuZ2V0TWVzc2FnZSg0ODYsICcnKSwgYnV0dG9uU3R5bGU6IGJ1dHRvblN0eWxlIH0sXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChfYWR2YW5jZWRQYW5lbDJbJ2RlZmF1bHQnXSwge1xuICAgICAgICAgICAgICAgICAgICBzaG93TWFpbGVyOiBzaG93TWFpbGVyLFxuICAgICAgICAgICAgICAgICAgICBweWRpbzogdGhpcy5wcm9wcy5weWRpbyxcbiAgICAgICAgICAgICAgICAgICAgc2hhcmVNb2RlbDogbW9kZWwsXG4gICAgICAgICAgICAgICAgICAgIHN0eWxlOiB7IGhlaWdodDogJzEwMCUnLCBvdmVyZmxvd1k6ICdhdXRvJyB9XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICkpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBtYWlsZXIgPSB1bmRlZmluZWQ7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlLm1haWxlckRhdGEpIHtcbiAgICAgICAgICAgIHZhciBtYWlsZXJEYXRhID0gdGhpcy5zdGF0ZS5tYWlsZXJEYXRhO1xuXG4gICAgICAgICAgICB2YXIgY3VzdG9taXplTWVzc2FnZVBhbmUgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICBpZiAobWFpbGVyRGF0YS5oYXNoKSB7XG4gICAgICAgICAgICAgICAgdmFyIHN0eWxlID0gbWFpbGVyRGF0YS5lbmFibGVJZGVudGlmaWNhdGlvbiA/IHsgcGFkZGluZzogJzEwcHggMjBweCcsIGJhY2tncm91bmRDb2xvcjogJyNFQ0VGRjEnIH0gOiB7IHBhZGRpbmc6ICcxMHB4IDIwcHggMCcgfTtcbiAgICAgICAgICAgICAgICB2YXIgbGV0VXNlckNob29zZUNyaXBwbGUgPSB0aGlzLnByb3BzLnB5ZGlvLmdldFBsdWdpbkNvbmZpZ3MoJ2FjdGlvbi5zaGFyZScpLmdldCgnRU1BSUxfUEVSU09OQUxfTElOS19TRU5EX0NMRUFSJyk7XG4gICAgICAgICAgICAgICAgY3VzdG9taXplTWVzc2FnZVBhbmUgPSBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICAgICAgeyBzdHlsZTogc3R5bGUgfSxcbiAgICAgICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChUb2dnbGUsIHsgbGFiZWw6IHRoaXMuZ2V0TWVzc2FnZSgyMzUpLCB0b2dnbGVkOiBtYWlsZXJEYXRhLmVuYWJsZUlkZW50aWZpY2F0aW9uLCBvblRvZ2dsZTogZnVuY3Rpb24gKGUsIGMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdGhpczMudG9nZ2xlTWFpbGVyRGF0YSh7IGVuYWJsZUlkZW50aWZpY2F0aW9uOiBjIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSB9KSxcbiAgICAgICAgICAgICAgICAgICAgbWFpbGVyRGF0YS5lbmFibGVJZGVudGlmaWNhdGlvbiAmJiBSZWFjdC5jcmVhdGVFbGVtZW50KFRvZ2dsZSwgeyBsYWJlbDogXCItLSBcIiArIHRoaXMuZ2V0TWVzc2FnZSgyMzYpLCB0b2dnbGVkOiBtYWlsZXJEYXRhLmlkZW50aWZpZWRPbmx5LCBvblRvZ2dsZTogZnVuY3Rpb24gKGUsIGMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdGhpczMudG9nZ2xlTWFpbGVyRGF0YSh7IGlkZW50aWZpZWRPbmx5OiBjIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSB9KSxcbiAgICAgICAgICAgICAgICAgICAgbWFpbGVyRGF0YS5lbmFibGVJZGVudGlmaWNhdGlvbiAmJiBsZXRVc2VyQ2hvb3NlQ3JpcHBsZSAmJiBSZWFjdC5jcmVhdGVFbGVtZW50KFRvZ2dsZSwgeyBsYWJlbDogXCItLSBcIiArIHRoaXMuZ2V0TWVzc2FnZSgyMzcpLCB0b2dnbGVkOiBtYWlsZXJEYXRhLmNyaXBwbGVJZGVudGlmaWNhdGlvbktleXMsIG9uVG9nZ2xlOiBmdW5jdGlvbiAoZSwgYykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzMy50b2dnbGVNYWlsZXJEYXRhKHsgY3JpcHBsZUlkZW50aWZpY2F0aW9uS2V5czogYyB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gfSlcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbWFpbGVyID0gUmVhY3QuY3JlYXRlRWxlbWVudChQeWRpb01haWxlci5QYW5lLCBfZXh0ZW5kcyh7fSwgbWFpbGVyRGF0YSwge1xuICAgICAgICAgICAgICAgIG9uRGlzbWlzczogdGhpcy5kaXNtaXNzTWFpbGVyLFxuICAgICAgICAgICAgICAgIG92ZXJsYXk6IHRydWUsXG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lOiAnc2hhcmUtY2VudGVyLW1haWxlcicsXG4gICAgICAgICAgICAgICAgcGFuZWxUaXRsZTogdGhpcy5wcm9wcy5weWRpby5NZXNzYWdlSGFzaFtcInNoYXJlX2NlbnRlci40NVwiXSxcbiAgICAgICAgICAgICAgICBhZGRpdGlvbmFsUGFuZVRvcDogY3VzdG9taXplTWVzc2FnZVBhbmUsXG4gICAgICAgICAgICAgICAgcHJvY2Vzc1Bvc3Q6IG1haWxlckRhdGEuZW5hYmxlSWRlbnRpZmljYXRpb24gPyB0aGlzLm1haWxlclByb2Nlc3NQb3N0IDogbnVsbFxuICAgICAgICAgICAgfSkpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoQ29udGVudCwgX2V4dGVuZHMoe30sIHRoaXMucHJvcHMsIHtcbiAgICAgICAgICAgIG1vZGVsOiB0aGlzLnN0YXRlLm1vZGVsLFxuICAgICAgICAgICAgcGFuZWxzOiBwYW5lbHMsXG4gICAgICAgICAgICBtYWlsZXI6IG1haWxlcixcbiAgICAgICAgICAgIGluaXRpYWxTZWxlY3RlZEluZGV4OiBpbml0aWFsU2VsZWN0ZWRJbmRleFxuICAgICAgICB9KSk7XG4gICAgfVxuXG59KTtcblxudmFyIENvbnRlbnQgPSAoZnVuY3Rpb24gKF9SZWFjdCRDb21wb25lbnQpIHtcbiAgICBfaW5oZXJpdHMoQ29udGVudCwgX1JlYWN0JENvbXBvbmVudCk7XG5cbiAgICBmdW5jdGlvbiBDb250ZW50KCkge1xuICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgQ29udGVudCk7XG5cbiAgICAgICAgX2dldChPYmplY3QuZ2V0UHJvdG90eXBlT2YoQ29udGVudC5wcm90b3R5cGUpLCAnY29uc3RydWN0b3InLCB0aGlzKS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cblxuICAgIF9jcmVhdGVDbGFzcyhDb250ZW50LCBbe1xuICAgICAgICBrZXk6ICdyZW5kZXInLFxuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyKCkge1xuXG4gICAgICAgICAgICB2YXIgdGFiU3R5bGVzID0ge1xuICAgICAgICAgICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgIGZsZXhHcm93OiAxLFxuICAgICAgICAgICAgICAgICAgICBvdmVyZmxvdzogJ2hpZGRlbicsXG4gICAgICAgICAgICAgICAgICAgIGRpc3BsYXk6ICdmbGV4JyxcbiAgICAgICAgICAgICAgICAgICAgZmxleERpcmVjdGlvbjogJ2NvbHVtbidcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHRhYkl0ZW1Db250YWluZXJTdHlsZToge1xuICAgICAgICAgICAgICAgICAgICBmbGV4U2hyaW5rOiAwXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBjb250ZW50Q29udGFpbmVyU3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgZmxleEdyb3c6IDEsXG4gICAgICAgICAgICAgICAgICAgIG92ZXJmbG93WTogJ2F1dG8nXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB0YWJUZW1wbGF0ZVN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgIGhlaWdodDogJzEwMCUnLFxuICAgICAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6ICcjZmFmYWZhJ1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAncmVhY3Rfc2hhcmVfZm9ybScsIHN0eWxlOiBfZXh0ZW5kcyh7IHdpZHRoOiA0MjAsIGRpc3BsYXk6ICdmbGV4JywgZmxleERpcmVjdGlvbjogJ2NvbHVtbicgfSwgdGhpcy5wcm9wcy5zdHlsZSkgfSxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KF9IZWFkZXIyWydkZWZhdWx0J10sIF9leHRlbmRzKHt9LCB0aGlzLnByb3BzLCB7IHNoYXJlTW9kZWw6IHRoaXMucHJvcHMubW9kZWwgfSkpLFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgIFRhYnMsXG4gICAgICAgICAgICAgICAgICAgIF9leHRlbmRzKHsgdmFsdWU6IHRoaXMucHJvcHMuaW5pdGlhbFNlbGVjdGVkSW5kZXggfSwgdGFiU3R5bGVzKSxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5wYW5lbHNcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgIHRoaXMucHJvcHMubWFpbGVyXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgfV0pO1xuXG4gICAgcmV0dXJuIENvbnRlbnQ7XG59KShSZWFjdC5Db21wb25lbnQpO1xuXG5Db250ZW50ID0gUGFsZXR0ZU1vZGlmaWVyKHsgcHJpbWFyeTFDb2xvcjogJyM0YWNlYjAnIH0pKENvbnRlbnQpO1xuXG5leHBvcnRzWydkZWZhdWx0J10gPSBNYWluUGFuZWw7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTtcbiIsIid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdfX2VzTW9kdWxlJywge1xuICAgIHZhbHVlOiB0cnVlXG59KTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgJ2RlZmF1bHQnOiBvYmogfTsgfVxuXG52YXIgX1NoYXJlQ29udGV4dENvbnN1bWVyID0gcmVxdWlyZSgnLi4vU2hhcmVDb250ZXh0Q29uc3VtZXInKTtcblxudmFyIF9TaGFyZUNvbnRleHRDb25zdW1lcjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9TaGFyZUNvbnRleHRDb25zdW1lcik7XG5cbnZhciBfVGFyZ2V0ZWRVc2VycyA9IHJlcXVpcmUoJy4vVGFyZ2V0ZWRVc2VycycpO1xuXG52YXIgX1RhcmdldGVkVXNlcnMyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfVGFyZ2V0ZWRVc2Vycyk7XG5cbnZhciBfbWFpbkFjdGlvbkJ1dHRvbiA9IHJlcXVpcmUoJy4uL21haW4vQWN0aW9uQnV0dG9uJyk7XG5cbnZhciBfbWFpbkFjdGlvbkJ1dHRvbjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9tYWluQWN0aW9uQnV0dG9uKTtcblxudmFyIFJlYWN0ID0gcmVxdWlyZSgncmVhY3QnKTtcblxudmFyIF9yZXF1aXJlID0gcmVxdWlyZSgnbWF0ZXJpYWwtdWknKTtcblxudmFyIFJhaXNlZEJ1dHRvbiA9IF9yZXF1aXJlLlJhaXNlZEJ1dHRvbjtcbnZhciBGbG9hdGluZ0FjdGlvbkJ1dHRvbiA9IF9yZXF1aXJlLkZsb2F0aW5nQWN0aW9uQnV0dG9uO1xudmFyIFRleHRGaWVsZCA9IF9yZXF1aXJlLlRleHRGaWVsZDtcbnZhciBQYXBlciA9IF9yZXF1aXJlLlBhcGVyO1xuXG52YXIgU2hhcmVNb2RlbCA9IHJlcXVpcmUoJ3B5ZGlvJykucmVxdWlyZUxpYignUmVhY3RNb2RlbFNoYXJlJyk7XG52YXIgUVJDb2RlID0gcmVxdWlyZSgncXJjb2RlLnJlYWN0Jyk7XG52YXIgQ2xpcGJvYXJkID0gcmVxdWlyZSgnY2xpcGJvYXJkJyk7XG5cbnZhciBQYXRoVXRpbHMgPSByZXF1aXJlKCdweWRpby91dGlsL3BhdGgnKTtcbnZhciBMYW5nVXRpbHMgPSByZXF1aXJlKCdweWRpby91dGlsL2xhbmcnKTtcblxudmFyIFB1YmxpY0xpbmtGaWVsZCA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcbiAgICBkaXNwbGF5TmFtZTogJ1B1YmxpY0xpbmtGaWVsZCcsXG5cbiAgICBwcm9wVHlwZXM6IHtcbiAgICAgICAgbGlua0RhdGE6IFJlYWN0LlByb3BUeXBlcy5vYmplY3QuaXNSZXF1aXJlZCxcbiAgICAgICAgc2hhcmVNb2RlbDogUmVhY3QuUHJvcFR5cGVzLmluc3RhbmNlT2YoU2hhcmVNb2RlbCksXG4gICAgICAgIGVkaXRBbGxvd2VkOiBSZWFjdC5Qcm9wVHlwZXMuYm9vbCxcbiAgICAgICAgb25DaGFuZ2U6IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgICAgICBzaG93TWFpbGVyOiBSZWFjdC5Qcm9wVHlwZXMuZnVuY1xuICAgIH0sXG4gICAgZ2V0SW5pdGlhbFN0YXRlOiBmdW5jdGlvbiBnZXRJbml0aWFsU3RhdGUoKSB7XG4gICAgICAgIHJldHVybiB7IGVkaXRMaW5rOiBmYWxzZSwgY29weU1lc3NhZ2U6ICcnLCBzaG93UVJDb2RlOiBmYWxzZSB9O1xuICAgIH0sXG4gICAgdG9nZ2xlRWRpdE1vZGU6IGZ1bmN0aW9uIHRvZ2dsZUVkaXRNb2RlKCkge1xuICAgICAgICBpZiAodGhpcy5zdGF0ZS5lZGl0TGluayAmJiB0aGlzLnN0YXRlLmN1c3RvbUxpbmspIHtcbiAgICAgICAgICAgIHRoaXMucHJvcHMuc2hhcmVNb2RlbC51cGRhdGVDdXN0b21MaW5rKHRoaXMucHJvcHMubGlua0RhdGEuaGFzaCwgdGhpcy5zdGF0ZS5jdXN0b21MaW5rKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNldFN0YXRlKHsgZWRpdExpbms6ICF0aGlzLnN0YXRlLmVkaXRMaW5rIH0pO1xuICAgIH0sXG4gICAgY2hhbmdlTGluazogZnVuY3Rpb24gY2hhbmdlTGluayhldmVudCkge1xuICAgICAgICB2YXIgdmFsdWUgPSBldmVudC50YXJnZXQudmFsdWU7XG4gICAgICAgIHZhbHVlID0gTGFuZ1V0aWxzLmNvbXB1dGVTdHJpbmdTbHVnKHZhbHVlKTtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGN1c3RvbUxpbms6IHZhbHVlIH0pO1xuICAgIH0sXG4gICAgY2xlYXJDb3B5TWVzc2FnZTogZnVuY3Rpb24gY2xlYXJDb3B5TWVzc2FnZSgpIHtcbiAgICAgICAgZ2xvYmFsLnNldFRpbWVvdXQoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBjb3B5TWVzc2FnZTogJycgfSk7XG4gICAgICAgIH0pLmJpbmQodGhpcyksIDUwMDApO1xuICAgIH0sXG5cbiAgICBhdHRhY2hDbGlwYm9hcmQ6IGZ1bmN0aW9uIGF0dGFjaENsaXBib2FyZCgpIHtcbiAgICAgICAgdGhpcy5kZXRhY2hDbGlwYm9hcmQoKTtcbiAgICAgICAgaWYgKHRoaXMucmVmc1snY29weS1idXR0b24nXSkge1xuICAgICAgICAgICAgdGhpcy5fY2xpcCA9IG5ldyBDbGlwYm9hcmQodGhpcy5yZWZzWydjb3B5LWJ1dHRvbiddLCB7XG4gICAgICAgICAgICAgICAgdGV4dDogKGZ1bmN0aW9uICh0cmlnZ2VyKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnByb3BzLmxpbmtEYXRhWydwdWJsaWNfbGluayddO1xuICAgICAgICAgICAgICAgIH0pLmJpbmQodGhpcylcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5fY2xpcC5vbignc3VjY2VzcycsIChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGNvcHlNZXNzYWdlOiB0aGlzLnByb3BzLmdldE1lc3NhZ2UoJzE5MicpIH0sIHRoaXMuY2xlYXJDb3B5TWVzc2FnZSk7XG4gICAgICAgICAgICB9KS5iaW5kKHRoaXMpKTtcbiAgICAgICAgICAgIHRoaXMuX2NsaXAub24oJ2Vycm9yJywgKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB2YXIgY29weU1lc3NhZ2UgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgaWYgKGdsb2JhbC5uYXZpZ2F0b3IucGxhdGZvcm0uaW5kZXhPZihcIk1hY1wiKSA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICBjb3B5TWVzc2FnZSA9IHRoaXMucHJvcHMuZ2V0TWVzc2FnZSgnMTQ0Jyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29weU1lc3NhZ2UgPSB0aGlzLnByb3BzLmdldE1lc3NhZ2UoJzE0MycpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLnJlZnNbJ3B1YmxpYy1saW5rLWZpZWxkJ10uZm9jdXMoKTtcbiAgICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgY29weU1lc3NhZ2U6IGNvcHlNZXNzYWdlIH0sIHRoaXMuY2xlYXJDb3B5TWVzc2FnZSk7XG4gICAgICAgICAgICB9KS5iaW5kKHRoaXMpKTtcbiAgICAgICAgfVxuICAgIH0sXG4gICAgZGV0YWNoQ2xpcGJvYXJkOiBmdW5jdGlvbiBkZXRhY2hDbGlwYm9hcmQoKSB7XG4gICAgICAgIGlmICh0aGlzLl9jbGlwKSB7XG4gICAgICAgICAgICB0aGlzLl9jbGlwLmRlc3Ryb3koKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBjb21wb25lbnREaWRVcGRhdGU6IGZ1bmN0aW9uIGNvbXBvbmVudERpZFVwZGF0ZShwcmV2UHJvcHMsIHByZXZTdGF0ZSkge1xuICAgICAgICB0aGlzLmF0dGFjaENsaXBib2FyZCgpO1xuICAgIH0sXG5cbiAgICBjb21wb25lbnREaWRNb3VudDogZnVuY3Rpb24gY29tcG9uZW50RGlkTW91bnQoKSB7XG4gICAgICAgIHRoaXMuYXR0YWNoQ2xpcGJvYXJkKCk7XG4gICAgfSxcblxuICAgIGNvbXBvbmVudFdpbGxVbm1vdW50OiBmdW5jdGlvbiBjb21wb25lbnRXaWxsVW5tb3VudCgpIHtcbiAgICAgICAgdGhpcy5kZXRhY2hDbGlwYm9hcmQoKTtcbiAgICB9LFxuXG4gICAgb3Blbk1haWxlcjogZnVuY3Rpb24gb3Blbk1haWxlcigpIHtcbiAgICAgICAgdmFyIG1haWxEYXRhID0gdGhpcy5wcm9wcy5zaGFyZU1vZGVsLnByZXBhcmVFbWFpbChcImxpbmtcIiwgdGhpcy5wcm9wcy5saW5rRGF0YS5oYXNoKTtcbiAgICAgICAgdGhpcy5wcm9wcy5zaG93TWFpbGVyKG1haWxEYXRhLnN1YmplY3QsIG1haWxEYXRhLm1lc3NhZ2UsIFtdLCB0aGlzLnByb3BzLmxpbmtEYXRhLmhhc2gpO1xuICAgIH0sXG5cbiAgICB0b2dnbGVRUkNvZGU6IGZ1bmN0aW9uIHRvZ2dsZVFSQ29kZSgpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNob3dRUkNvZGU6ICF0aGlzLnN0YXRlLnNob3dRUkNvZGUgfSk7XG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgICB2YXIgcHVibGljTGluayA9IHRoaXMucHJvcHMubGlua0RhdGFbJ3B1YmxpY19saW5rJ107XG4gICAgICAgIHZhciBlZGl0QWxsb3dlZCA9IHRoaXMucHJvcHMuZWRpdEFsbG93ZWQgJiYgIXRoaXMucHJvcHMubGlua0RhdGFbJ2hhc2hfaXNfc2hvcnRlbiddICYmICF0aGlzLnByb3BzLmlzUmVhZG9ubHkoKSAmJiB0aGlzLnByb3BzLnNoYXJlTW9kZWwuY3VycmVudElzT3duZXIoKTtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUuZWRpdExpbmsgJiYgZWRpdEFsbG93ZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgIFBhcGVyLFxuICAgICAgICAgICAgICAgIHsgekRlcHRoOiAwLCByb3VuZGVkOiBmYWxzZSwgY2xhc3NOYW1lOiBcInB1YmxpYy1saW5rLWNvbnRhaW5lciBlZGl0LWxpbmtcIiB9LFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgICAgICB7IHN0eWxlOiB7IGRpc3BsYXk6ICdmbGV4JywgYWxpZ25JdGVtczogJ2NlbnRlcicgfSB9LFxuICAgICAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICAgICAgJ3NwYW4nLFxuICAgICAgICAgICAgICAgICAgICAgICAgeyBzdHlsZTogeyBmb250U2l6ZTogMTYsIGNvbG9yOiAncmdiYSgwLDAsMCwwLjQpJywgZGlzcGxheTogJ2lubGluZS1ibG9jaycsIG1heFdpZHRoOiAyMDAsIHdoaXRlU3BhY2U6ICdub3dyYXAnLCBvdmVyZmxvdzogJ2hpZGRlbicsIHRleHRPdmVyZmxvdzogJ2VsbGlwc2lzJyB9IH0sXG4gICAgICAgICAgICAgICAgICAgICAgICBQYXRoVXRpbHMuZ2V0RGlybmFtZShwdWJsaWNMaW5rKSArICcvICdcbiAgICAgICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChUZXh0RmllbGQsIHsgc3R5bGU6IHsgZmxleDogMSwgbWFyZ2luUmlnaHQ6IDEwLCBtYXJnaW5MZWZ0OiAxMCB9LCBvbkNoYW5nZTogdGhpcy5jaGFuZ2VMaW5rLCB2YWx1ZTogdGhpcy5zdGF0ZS5jdXN0b21MaW5rICE9PSB1bmRlZmluZWQgPyB0aGlzLnN0YXRlLmN1c3RvbUxpbmsgOiB0aGlzLnByb3BzLmxpbmtEYXRhWydoYXNoJ10gfSksXG4gICAgICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoRmxvYXRpbmdBY3Rpb25CdXR0b24sIHsgbWluaTogdHJ1ZSwgaWNvbkNsYXNzTmFtZTogJ21kaSBtZGktY2hlY2snLCBvblRvdWNoVGFwOiB0aGlzLnRvZ2dsZUVkaXRNb2RlIH0pXG4gICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6ICdzZWN0aW9uLWxlZ2VuZCcgfSxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5nZXRNZXNzYWdlKCcxOTQnKVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2YXIgY29weUJ1dHRvbiA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nLCB7IHJlZjogJ2NvcHktYnV0dG9uJywgY2xhc3NOYW1lOiAnY29weS1saW5rLWJ1dHRvbiBtZGkgbWRpLWNvbnRlbnQtY29weScsIHRpdGxlOiB0aGlzLnByb3BzLmdldE1lc3NhZ2UoJzE5MScpIH0pO1xuICAgICAgICAgICAgdmFyIHNldEh0bWwgPSAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB7IF9faHRtbDogdGhpcy5zdGF0ZS5jb3B5TWVzc2FnZSB9O1xuICAgICAgICAgICAgfSkuYmluZCh0aGlzKTtcbiAgICAgICAgICAgIHZhciBfZm9jdXMgPSBmdW5jdGlvbiBfZm9jdXMoZSkge1xuICAgICAgICAgICAgICAgIGUudGFyZ2V0LnNlbGVjdCgpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHZhciBhY3Rpb25MaW5rcyA9IFtdLFxuICAgICAgICAgICAgICAgIHFyQ29kZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIGlmICh0aGlzLnByb3BzLnNob3dNYWlsZXIpIHtcbiAgICAgICAgICAgICAgICBhY3Rpb25MaW5rcy5wdXNoKFJlYWN0LmNyZWF0ZUVsZW1lbnQoX21haW5BY3Rpb25CdXR0b24yWydkZWZhdWx0J10sIHsga2V5OiAnb3V0bGluZScsIGNhbGxiYWNrOiB0aGlzLm9wZW5NYWlsZXIsIG1kaUljb246ICdlbWFpbC1vdXRsaW5lJywgbWVzc2FnZUlkOiAnNDUnIH0pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChlZGl0QWxsb3dlZCkge1xuICAgICAgICAgICAgICAgIGFjdGlvbkxpbmtzLnB1c2goUmVhY3QuY3JlYXRlRWxlbWVudChfbWFpbkFjdGlvbkJ1dHRvbjJbJ2RlZmF1bHQnXSwgeyBrZXk6ICdwZW5jaWwnLCBjYWxsYmFjazogdGhpcy50b2dnbGVFZGl0TW9kZSwgbWRpSWNvbjogJ3BlbmNpbCcsIG1lc3NhZ2VJZDogXCIxOTNcIiB9KSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoU2hhcmVNb2RlbC5xcmNvZGVFbmFibGVkKCkpIHtcbiAgICAgICAgICAgICAgICBhY3Rpb25MaW5rcy5wdXNoKFJlYWN0LmNyZWF0ZUVsZW1lbnQoX21haW5BY3Rpb25CdXR0b24yWydkZWZhdWx0J10sIHsga2V5OiAncXJjb2RlJywgY2FsbGJhY2s6IHRoaXMudG9nZ2xlUVJDb2RlLCBtZGlJY29uOiAncXJjb2RlJywgbWVzc2FnZUlkOiAnOTQnIH0pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChhY3Rpb25MaW5rcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBhY3Rpb25MaW5rcyA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ2FkZGl0aW9uYWwtYWN0aW9ucy1saW5rcycgfSxcbiAgICAgICAgICAgICAgICAgICAgYWN0aW9uTGlua3NcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBhY3Rpb25MaW5rcyA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5zdGF0ZS5zaG93UVJDb2RlKSB7XG4gICAgICAgICAgICAgICAgcXJDb2RlID0gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAncXJDb2RlJyB9LFxuICAgICAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFFSQ29kZSwgeyBzaXplOiAxMjgsIHZhbHVlOiBwdWJsaWNMaW5rLCBsZXZlbDogJ1EnIH0pXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgIFBhcGVyLFxuICAgICAgICAgICAgICAgIHsgekRlcHRoOiAwLCByb3VuZGVkOiBmYWxzZSwgY2xhc3NOYW1lOiAncHVibGljLWxpbmstY29udGFpbmVyJyB9LFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgICAgICB7IHN0eWxlOiB7IHBvc2l0aW9uOiAncmVsYXRpdmUnIH0gfSxcbiAgICAgICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChUZXh0RmllbGQsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogXCJwdWJsaWMtbGlua1wiICsgKHRoaXMucHJvcHMubGlua0RhdGFbJ2lzX2V4cGlyZWQnXSA/ICcgbGluay1leHBpcmVkJyA6ICcnKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICd0ZXh0JyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6ICdMaW5rJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlZjogJ3B1YmxpYy1saW5rLWZpZWxkJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlOiBwdWJsaWNMaW5rLFxuICAgICAgICAgICAgICAgICAgICAgICAgb25Gb2N1czogX2ZvY3VzLFxuICAgICAgICAgICAgICAgICAgICAgICAgZnVsbFdpZHRoOiB0cnVlXG4gICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICAgICAnICcsXG4gICAgICAgICAgICAgICAgICAgIGNvcHlCdXR0b25cbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoJ2RpdicsIHsgc3R5bGU6IHsgdGV4dEFsaWduOiAnY2VudGVyJyB9LCBjbGFzc05hbWU6ICdzZWN0aW9uLWxlZ2VuZCcsIGRhbmdlcm91c2x5U2V0SW5uZXJIVE1MOiBzZXRIdG1sKCkgfSksXG4gICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5saW5rRGF0YS50YXJnZXRfdXNlcnMgJiYgUmVhY3QuY3JlYXRlRWxlbWVudChfVGFyZ2V0ZWRVc2VyczJbJ2RlZmF1bHQnXSwgdGhpcy5wcm9wcyksXG4gICAgICAgICAgICAgICAgYWN0aW9uTGlua3MsXG4gICAgICAgICAgICAgICAgcXJDb2RlXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgfVxufSk7XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IFB1YmxpY0xpbmtGaWVsZCA9ICgwLCBfU2hhcmVDb250ZXh0Q29uc3VtZXIyWydkZWZhdWx0J10pKFB1YmxpY0xpbmtGaWVsZCk7XG5leHBvcnRzWydkZWZhdWx0J10gPSBQdWJsaWNMaW5rRmllbGQ7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTtcbiIsIid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdfX2VzTW9kdWxlJywge1xuICAgIHZhbHVlOiB0cnVlXG59KTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgJ2RlZmF1bHQnOiBvYmogfTsgfVxuXG52YXIgX1NoYXJlQ29udGV4dENvbnN1bWVyID0gcmVxdWlyZSgnLi4vU2hhcmVDb250ZXh0Q29uc3VtZXInKTtcblxudmFyIF9TaGFyZUNvbnRleHRDb25zdW1lcjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9TaGFyZUNvbnRleHRDb25zdW1lcik7XG5cbnZhciBfRmllbGQgPSByZXF1aXJlKCcuL0ZpZWxkJyk7XG5cbnZhciBfRmllbGQyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfRmllbGQpO1xuXG52YXIgX1Blcm1pc3Npb25zID0gcmVxdWlyZSgnLi9QZXJtaXNzaW9ucycpO1xuXG52YXIgX1Blcm1pc3Npb25zMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1Blcm1pc3Npb25zKTtcblxudmFyIF9TZWN1cmVPcHRpb25zID0gcmVxdWlyZSgnLi9TZWN1cmVPcHRpb25zJyk7XG5cbnZhciBfU2VjdXJlT3B0aW9uczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9TZWN1cmVPcHRpb25zKTtcblxudmFyIF9tYWluQ2FyZCA9IHJlcXVpcmUoJy4uL21haW4vQ2FyZCcpO1xuXG52YXIgX21haW5DYXJkMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX21haW5DYXJkKTtcblxudmFyIFJlYWN0ID0gcmVxdWlyZSgncmVhY3QnKTtcblxudmFyIF9yZXF1aXJlJHJlcXVpcmVMaWIgPSByZXF1aXJlKCdweWRpbycpLnJlcXVpcmVMaWIoJ2Zvcm0nKTtcblxudmFyIFZhbGlkUGFzc3dvcmQgPSBfcmVxdWlyZSRyZXF1aXJlTGliLlZhbGlkUGFzc3dvcmQ7XG5cbnZhciBfcmVxdWlyZSA9IHJlcXVpcmUoJ21hdGVyaWFsLXVpJyk7XG5cbnZhciBSYWlzZWRCdXR0b24gPSBfcmVxdWlyZS5SYWlzZWRCdXR0b247XG52YXIgQ2hlY2tib3ggPSBfcmVxdWlyZS5DaGVja2JveDtcbnZhciBEaXZpZGVyID0gX3JlcXVpcmUuRGl2aWRlcjtcblxudmFyIFB1YmxpY0xpbmtQYW5lbCA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcbiAgICBkaXNwbGF5TmFtZTogJ1B1YmxpY0xpbmtQYW5lbCcsXG5cbiAgICBwcm9wVHlwZXM6IHtcbiAgICAgICAgbGlua0RhdGE6IFJlYWN0LlByb3BUeXBlcy5vYmplY3QsXG4gICAgICAgIHB5ZGlvOiBSZWFjdC5Qcm9wVHlwZXMuaW5zdGFuY2VPZihQeWRpbyksXG4gICAgICAgIHNoYXJlTW9kZWw6IFJlYWN0LlByb3BUeXBlcy5pbnN0YW5jZU9mKFJlYWN0TW9kZWwuU2hhcmUpLFxuICAgICAgICBhdXRob3JpemF0aW9uczogUmVhY3QuUHJvcFR5cGVzLm9iamVjdCxcbiAgICAgICAgc2hvd01haWxlcjogUmVhY3QuUHJvcFR5cGVzLmZ1bmNcbiAgICB9LFxuXG4gICAgZGlzYWJsZVNhdmU6IGZ1bmN0aW9uIGRpc2FibGVTYXZlKCkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgZGlzYWJsZWQ6IHRydWUgfSk7XG4gICAgfSxcbiAgICBlbmFibGVTYXZlOiBmdW5jdGlvbiBlbmFibGVTYXZlKCkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgZGlzYWJsZWQ6IGZhbHNlIH0pO1xuICAgIH0sXG4gICAgY29tcG9uZW50RGlkTW91bnQ6IGZ1bmN0aW9uIGNvbXBvbmVudERpZE1vdW50KCkge1xuICAgICAgICB0aGlzLnByb3BzLnNoYXJlTW9kZWwub2JzZXJ2ZSgnc2F2aW5nJywgdGhpcy5kaXNhYmxlU2F2ZSk7XG4gICAgICAgIHRoaXMucHJvcHMuc2hhcmVNb2RlbC5vYnNlcnZlKCdzYXZlZCcsIHRoaXMuZW5hYmxlU2F2ZSk7XG4gICAgfSxcbiAgICBjb21wb25lbmRXaWxsVW5tb3VudDogZnVuY3Rpb24gY29tcG9uZW5kV2lsbFVubW91bnQoKSB7XG4gICAgICAgIHRoaXMucHJvcHMuc2hhcmVNb2RlbC5zdG9wT2JzZXJ2aW5nKCdzYXZpbmcnLCB0aGlzLmRpc2FibGVTYXZlKTtcbiAgICAgICAgdGhpcy5wcm9wcy5zaGFyZU1vZGVsLnN0b3BPYnNlcnZpbmcoJ3NhdmVkJywgdGhpcy5lbmFibGVTYXZlKTtcbiAgICB9LFxuXG4gICAgdG9nZ2xlTGluazogZnVuY3Rpb24gdG9nZ2xlTGluaygpIHtcbiAgICAgICAgdmFyIHB1YmxpY0xpbmtzID0gdGhpcy5wcm9wcy5zaGFyZU1vZGVsLmdldFB1YmxpY0xpbmtzKCk7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlLnNob3dUZW1wb3JhcnlQYXNzd29yZCkge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNob3dUZW1wb3JhcnlQYXNzd29yZDogZmFsc2UsIHRlbXBvcmFyeVBhc3N3b3JkOiBudWxsIH0pO1xuICAgICAgICB9IGVsc2UgaWYgKCFwdWJsaWNMaW5rcy5sZW5ndGggJiYgUmVhY3RNb2RlbC5TaGFyZS5nZXRBdXRob3JpemF0aW9ucyh0aGlzLnByb3BzLnB5ZGlvKS5wYXNzd29yZF9tYW5kYXRvcnkpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBzaG93VGVtcG9yYXJ5UGFzc3dvcmQ6IHRydWUsIHRlbXBvcmFyeVBhc3N3b3JkOiAnJyB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMucHJvcHMuc2hhcmVNb2RlbC50b2dnbGVQdWJsaWNMaW5rKCk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgZ2V0SW5pdGlhbFN0YXRlOiBmdW5jdGlvbiBnZXRJbml0aWFsU3RhdGUoKSB7XG4gICAgICAgIHJldHVybiB7IHNob3dUZW1wb3JhcnlQYXNzd29yZDogZmFsc2UsIHRlbXBvcmFyeVBhc3N3b3JkOiBudWxsLCBwYXNzVmFsaWQ6IGZhbHNlLCBkaXNhYmxlZDogZmFsc2UgfTtcbiAgICB9LFxuXG4gICAgdXBkYXRlVGVtcG9yYXJ5UGFzc3dvcmQ6IGZ1bmN0aW9uIHVwZGF0ZVRlbXBvcmFyeVBhc3N3b3JkKHZhbHVlLCBldmVudCkge1xuICAgICAgICBpZiAodmFsdWUgPT0gdW5kZWZpbmVkKSB2YWx1ZSA9IGV2ZW50LmN1cnJlbnRUYXJnZXQuZ2V0VmFsdWUoKTtcbiAgICAgICAgdmFyIHBhc3NWYWxpZCA9IHRoaXMucmVmcy5wYXNzRmllbGQuaXNWYWxpZCgpO1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgdGVtcG9yYXJ5UGFzc3dvcmQ6IHZhbHVlLCBwYXNzVmFsaWQ6IHBhc3NWYWxpZCB9KTtcbiAgICB9LFxuXG4gICAgZW5hYmxlTGlua1dpdGhQYXNzd29yZDogZnVuY3Rpb24gZW5hYmxlTGlua1dpdGhQYXNzd29yZCgpIHtcbiAgICAgICAgdGhpcy5wcm9wcy5zaGFyZU1vZGVsLmVuYWJsZVB1YmxpY0xpbmtXaXRoUGFzc3dvcmQodGhpcy5zdGF0ZS50ZW1wb3JhcnlQYXNzd29yZCk7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBzaG93VGVtcG9yYXJ5UGFzc3dvcmQ6IGZhbHNlLCB0ZW1wb3JhcnlQYXNzd29yZDogbnVsbCB9KTtcbiAgICB9LFxuXG4gICAgcmVuZGVyOiBmdW5jdGlvbiByZW5kZXIoKSB7XG5cbiAgICAgICAgdmFyIHB1YmxpY0xpbmtQYW5lcyA9IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIHB1YmxpY0xpbmtGaWVsZCA9IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMubGlua0RhdGEpIHtcbiAgICAgICAgICAgIHB1YmxpY0xpbmtGaWVsZCA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoX0ZpZWxkMlsnZGVmYXVsdCddLCB7XG4gICAgICAgICAgICAgICAgc2hvd01haWxlcjogdGhpcy5wcm9wcy5zaG93TWFpbGVyLFxuICAgICAgICAgICAgICAgIGxpbmtEYXRhOiB0aGlzLnByb3BzLmxpbmtEYXRhLFxuICAgICAgICAgICAgICAgIHNoYXJlTW9kZWw6IHRoaXMucHJvcHMuc2hhcmVNb2RlbCxcbiAgICAgICAgICAgICAgICBlZGl0QWxsb3dlZDogdGhpcy5wcm9wcy5hdXRob3JpemF0aW9ucy5lZGl0YWJsZV9oYXNoLFxuICAgICAgICAgICAgICAgIGtleTogJ3B1YmxpYy1saW5rJ1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBwdWJsaWNMaW5rUGFuZXMgPSBbUmVhY3QuY3JlYXRlRWxlbWVudChfUGVybWlzc2lvbnMyWydkZWZhdWx0J10sIHtcbiAgICAgICAgICAgICAgICBsaW5rRGF0YTogdGhpcy5wcm9wcy5saW5rRGF0YSxcbiAgICAgICAgICAgICAgICBzaGFyZU1vZGVsOiB0aGlzLnByb3BzLnNoYXJlTW9kZWwsXG4gICAgICAgICAgICAgICAga2V5OiAncHVibGljLXBlcm0nXG4gICAgICAgICAgICB9KSwgUmVhY3QuY3JlYXRlRWxlbWVudChfU2VjdXJlT3B0aW9uczJbJ2RlZmF1bHQnXSwge1xuICAgICAgICAgICAgICAgIGxpbmtEYXRhOiB0aGlzLnByb3BzLmxpbmtEYXRhLFxuICAgICAgICAgICAgICAgIHNoYXJlTW9kZWw6IHRoaXMucHJvcHMuc2hhcmVNb2RlbCxcbiAgICAgICAgICAgICAgICBweWRpbzogdGhpcy5wcm9wcy5weWRpbyxcbiAgICAgICAgICAgICAgICBrZXk6ICdwdWJsaWMtc2VjdXJlJ1xuICAgICAgICAgICAgfSldO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuc3RhdGUuc2hvd1RlbXBvcmFyeVBhc3N3b3JkKSB7XG4gICAgICAgICAgICBwdWJsaWNMaW5rRmllbGQgPSBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAnc2VjdGlvbi1sZWdlbmQnLCBzdHlsZTogeyBtYXJnaW5Ub3A6IDIwIH0gfSxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5nZXRNZXNzYWdlKCcyMTUnKVxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgICAgIHsgc3R5bGU6IHsgZGlzcGxheTogJ2ZsZXgnLCBhbGlnbkl0ZW1zOiAnYmFzZWxpbmUnIH0gfSxcbiAgICAgICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgICAgICAgICAgeyBzdHlsZTogeyBmbGV4OiAxIH0gfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoVmFsaWRQYXNzd29yZCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZjogJ3Bhc3NGaWVsZCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlczogeyBsYWJlbDogdGhpcy5wcm9wcy5nZXRNZXNzYWdlKCcyMycpIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IHRoaXMuc3RhdGUudGVtcG9yYXJ5UGFzc3dvcmQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb25DaGFuZ2U6IHRoaXMudXBkYXRlVGVtcG9yYXJ5UGFzc3dvcmRcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHsgc3R5bGU6IHsgbWFyZ2luTGVmdDogNywgbWFyZ2luVG9wOiAyNiB9IH0sXG4gICAgICAgICAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFJhaXNlZEJ1dHRvbiwgeyBsYWJlbDogdGhpcy5wcm9wcy5nZXRNZXNzYWdlKCc5MicpLCBzZWNvbmRhcnk6IHRydWUsIGRpc2FibGVkOiAhdGhpcy5zdGF0ZS5wYXNzVmFsaWQsIG9uQ2xpY2s6IHRoaXMuZW5hYmxlTGlua1dpdGhQYXNzd29yZCB9KVxuICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHB1YmxpY0xpbmtGaWVsZCA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6ICdzZWN0aW9uLWxlZ2VuZCcsIHN0eWxlOiB7IHBhZGRpbmdCb3R0b206IDE2LCBwYWRkaW5nVG9wOiAxNiB9IH0sXG4gICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5nZXRNZXNzYWdlKCcxOTAnKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgY2hlY2tlZCA9ICEhdGhpcy5wcm9wcy5saW5rRGF0YTtcbiAgICAgICAgdmFyIGRpc2FibGVGb3JOb3RPd25lciA9IGZhbHNlO1xuICAgICAgICBpZiAoY2hlY2tlZCAmJiAhdGhpcy5wcm9wcy5zaGFyZU1vZGVsLmN1cnJlbnRJc093bmVyKCkpIHtcbiAgICAgICAgICAgIGRpc2FibGVGb3JOb3RPd25lciA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgIHsgc3R5bGU6IHRoaXMucHJvcHMuc3R5bGUgfSxcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgX21haW5DYXJkMlsnZGVmYXVsdCddLFxuICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChDaGVja2JveCwge1xuICAgICAgICAgICAgICAgICAgICBkaXNhYmxlZDogdGhpcy5wcm9wcy5pc1JlYWRvbmx5KCkgfHwgZGlzYWJsZUZvck5vdE93bmVyIHx8IHRoaXMuc3RhdGUuZGlzYWJsZWQsXG4gICAgICAgICAgICAgICAgICAgIG9uQ2hlY2s6IHRoaXMudG9nZ2xlTGluayxcbiAgICAgICAgICAgICAgICAgICAgY2hlY2tlZDogISF0aGlzLnByb3BzLmxpbmtEYXRhIHx8IHRoaXMuc3RhdGUuc2hvd1RlbXBvcmFyeVBhc3N3b3JkLFxuICAgICAgICAgICAgICAgICAgICBsYWJlbDogdGhpcy5wcm9wcy5nZXRNZXNzYWdlKCcxODknKSxcbiAgICAgICAgICAgICAgICAgICAgbGFiZWxTdHlsZTogeyBmb250U2l6ZTogMTggfVxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgIHB1YmxpY0xpbmtGaWVsZFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIHB1YmxpY0xpbmtQYW5lc1xuICAgICAgICApO1xuICAgIH1cbn0pO1xuXG5leHBvcnRzWydkZWZhdWx0J10gPSBQdWJsaWNMaW5rUGFuZWwgPSAoMCwgX1NoYXJlQ29udGV4dENvbnN1bWVyMlsnZGVmYXVsdCddKShQdWJsaWNMaW5rUGFuZWwpO1xuZXhwb3J0c1snZGVmYXVsdCddID0gUHVibGljTGlua1BhbmVsO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG4iLCIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnX19lc01vZHVsZScsIHtcbiAgICB2YWx1ZTogdHJ1ZVxufSk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7ICdkZWZhdWx0Jzogb2JqIH07IH1cblxudmFyIF9TaGFyZUNvbnRleHRDb25zdW1lciA9IHJlcXVpcmUoJy4uL1NoYXJlQ29udGV4dENvbnN1bWVyJyk7XG5cbnZhciBfU2hhcmVDb250ZXh0Q29uc3VtZXIyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfU2hhcmVDb250ZXh0Q29uc3VtZXIpO1xuXG52YXIgX21haW5DYXJkID0gcmVxdWlyZSgnLi4vbWFpbi9DYXJkJyk7XG5cbnZhciBfbWFpbkNhcmQyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfbWFpbkNhcmQpO1xuXG52YXIgUmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpO1xuXG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKCdtYXRlcmlhbC11aScpO1xuXG52YXIgQ2hlY2tib3ggPSBfcmVxdWlyZS5DaGVja2JveDtcbnZhciBQYXBlciA9IF9yZXF1aXJlLlBhcGVyO1xuXG52YXIgU2hhcmVNb2RlbCA9IHJlcXVpcmUoJ3B5ZGlvJykucmVxdWlyZUxpYignUmVhY3RNb2RlbFNoYXJlJyk7XG5cbnZhciBQdWJsaWNMaW5rUGVybWlzc2lvbnMgPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG4gICAgZGlzcGxheU5hbWU6ICdQdWJsaWNMaW5rUGVybWlzc2lvbnMnLFxuXG4gICAgcHJvcFR5cGVzOiB7XG4gICAgICAgIGxpbmtEYXRhOiBSZWFjdC5Qcm9wVHlwZXMub2JqZWN0LmlzUmVxdWlyZWQsXG4gICAgICAgIHNoYXJlTW9kZWw6IFJlYWN0LlByb3BUeXBlcy5pbnN0YW5jZU9mKFNoYXJlTW9kZWwpLFxuICAgICAgICBzdHlsZTogUmVhY3QuUHJvcFR5cGVzLm9iamVjdFxuICAgIH0sXG5cbiAgICBjaGFuZ2VQZXJtaXNzaW9uOiBmdW5jdGlvbiBjaGFuZ2VQZXJtaXNzaW9uKGV2ZW50KSB7XG4gICAgICAgIHZhciBuYW1lID0gZXZlbnQudGFyZ2V0Lm5hbWU7XG4gICAgICAgIHZhciBjaGVja2VkID0gZXZlbnQudGFyZ2V0LmNoZWNrZWQ7XG4gICAgICAgIHRoaXMucHJvcHMuc2hhcmVNb2RlbC5zZXRQdWJsaWNMaW5rUGVybWlzc2lvbih0aGlzLnByb3BzLmxpbmtEYXRhLmhhc2gsIG5hbWUsIGNoZWNrZWQpO1xuICAgIH0sXG5cbiAgICByZW5kZXI6IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgICAgdmFyIGxpbmtJZCA9IHRoaXMucHJvcHMubGlua0RhdGEuaGFzaDtcbiAgICAgICAgdmFyIHBlcm1zID0gW10sXG4gICAgICAgICAgICBwcmV2aWV3V2FybmluZztcbiAgICAgICAgdmFyIGN1cnJlbnRJc0ZvbGRlciA9ICF0aGlzLnByb3BzLnNoYXJlTW9kZWwuZ2V0Tm9kZSgpLmlzTGVhZigpO1xuICAgICAgICBwZXJtcy5wdXNoKHtcbiAgICAgICAgICAgIE5BTUU6ICdyZWFkJyxcbiAgICAgICAgICAgIExBQkVMOiB0aGlzLnByb3BzLmdldE1lc3NhZ2UoJzcyJyksXG4gICAgICAgICAgICBESVNBQkxFRDogY3VycmVudElzRm9sZGVyICYmICF0aGlzLnByb3BzLnNoYXJlTW9kZWwuZ2V0UHVibGljTGlua1Blcm1pc3Npb24obGlua0lkLCAnd3JpdGUnKVxuICAgICAgICB9KTtcbiAgICAgICAgcGVybXMucHVzaCh7XG4gICAgICAgICAgICBOQU1FOiAnZG93bmxvYWQnLFxuICAgICAgICAgICAgTEFCRUw6IHRoaXMucHJvcHMuZ2V0TWVzc2FnZSgnNzMnKVxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKGN1cnJlbnRJc0ZvbGRlcikge1xuICAgICAgICAgICAgcGVybXMucHVzaCh7XG4gICAgICAgICAgICAgICAgTkFNRTogJ3dyaXRlJyxcbiAgICAgICAgICAgICAgICBMQUJFTDogdGhpcy5wcm9wcy5nZXRNZXNzYWdlKCc3NCcpXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLnByb3BzLnNoYXJlTW9kZWwuZmlsZUhhc1dyaXRlYWJsZUVkaXRvcnMoKSkge1xuICAgICAgICAgICAgcGVybXMucHVzaCh7XG4gICAgICAgICAgICAgICAgTkFNRTogJ3dyaXRlJyxcbiAgICAgICAgICAgICAgICBMQUJFTDogdGhpcy5wcm9wcy5nZXRNZXNzYWdlKCc3NGInKVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMucHJvcHMuc2hhcmVNb2RlbC5pc1B1YmxpY0xpbmtQcmV2aWV3RGlzYWJsZWQoKSAmJiB0aGlzLnByb3BzLnNoYXJlTW9kZWwuZ2V0UHVibGljTGlua1Blcm1pc3Npb24obGlua0lkLCAncmVhZCcpKSB7XG4gICAgICAgICAgICBwcmV2aWV3V2FybmluZyA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgICAgICB0aGlzLnByb3BzLmdldE1lc3NhZ2UoJzE5NScpXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgX21haW5DYXJkMlsnZGVmYXVsdCddLFxuICAgICAgICAgICAgeyB0aXRsZTogdGhpcy5wcm9wcy5nZXRNZXNzYWdlKCc3MScpLCBzdHlsZTogdGhpcy5wcm9wcy5zdHlsZSB9LFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ3NlY3Rpb24tbGVnZW5kJyB9LFxuICAgICAgICAgICAgICAgIHRoaXMucHJvcHMuZ2V0TWVzc2FnZSgnNzByJylcbiAgICAgICAgICAgICksXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgIHsgc3R5bGU6IHsgbWFyZ2luOiAnMTBweCAwIDIwcHgnIH0sIGNsYXNzTmFtZTogJ2llX21hdGVyaWFsX2NoZWNrYm94X2ZpeCcgfSxcbiAgICAgICAgICAgICAgICBwZXJtcy5tYXAoKGZ1bmN0aW9uIChwKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgICAgICAgICB7IGtleTogcC5OQU1FLCBzdHlsZTogeyBkaXNwbGF5OiAnaW5saW5lLWJsb2NrJywgd2lkdGg6ICczMyUnIH0gfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoQ2hlY2tib3gsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXNhYmxlZDogcC5ESVNBQkxFRCB8fCB0aGlzLnByb3BzLmlzUmVhZG9ubHkoKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAnY2hlY2tib3gnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6IHAuTkFNRSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbDogcC5MQUJFTCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbkNoZWNrOiB0aGlzLmNoYW5nZVBlcm1pc3Npb24sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hlY2tlZDogdGhpcy5wcm9wcy5zaGFyZU1vZGVsLmdldFB1YmxpY0xpbmtQZXJtaXNzaW9uKGxpbmtJZCwgcC5OQU1FKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbFN0eWxlOiB7IHdoaXRlU3BhY2U6ICdub3dyYXAnIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfSkuYmluZCh0aGlzKSksXG4gICAgICAgICAgICAgICAgcHJldmlld1dhcm5pbmdcbiAgICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICB9XG59KTtcblxuZXhwb3J0c1snZGVmYXVsdCddID0gUHVibGljTGlua1Blcm1pc3Npb25zID0gKDAsIF9TaGFyZUNvbnRleHRDb25zdW1lcjJbJ2RlZmF1bHQnXSkoUHVibGljTGlua1Blcm1pc3Npb25zKTtcbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IFB1YmxpY0xpbmtQZXJtaXNzaW9ucztcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ19fZXNNb2R1bGUnLCB7XG4gICAgdmFsdWU6IHRydWVcbn0pO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyAnZGVmYXVsdCc6IG9iaiB9OyB9XG5cbnZhciBfU2hhcmVDb250ZXh0Q29uc3VtZXIgPSByZXF1aXJlKCcuLi9TaGFyZUNvbnRleHRDb25zdW1lcicpO1xuXG52YXIgX1NoYXJlQ29udGV4dENvbnN1bWVyMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1NoYXJlQ29udGV4dENvbnN1bWVyKTtcblxudmFyIF9tYWluQ2FyZCA9IHJlcXVpcmUoJy4uL21haW4vQ2FyZCcpO1xuXG52YXIgX21haW5DYXJkMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX21haW5DYXJkKTtcblxudmFyIFJlYWN0ID0gcmVxdWlyZSgncmVhY3QnKTtcblxudmFyIF9yZXF1aXJlID0gcmVxdWlyZSgnbWF0ZXJpYWwtdWknKTtcblxudmFyIEZsYXRCdXR0b24gPSBfcmVxdWlyZS5GbGF0QnV0dG9uO1xudmFyIFRleHRGaWVsZCA9IF9yZXF1aXJlLlRleHRGaWVsZDtcbnZhciBEYXRlUGlja2VyID0gX3JlcXVpcmUuRGF0ZVBpY2tlcjtcblxudmFyIF9yZXF1aXJlJHJlcXVpcmVMaWIgPSByZXF1aXJlKCdweWRpbycpLnJlcXVpcmVMaWIoJ2Zvcm0nKTtcblxudmFyIFZhbGlkUGFzc3dvcmQgPSBfcmVxdWlyZSRyZXF1aXJlTGliLlZhbGlkUGFzc3dvcmQ7XG5cbnZhciBTaGFyZU1vZGVsID0gcmVxdWlyZSgncHlkaW8nKS5yZXF1aXJlTGliKCdSZWFjdE1vZGVsU2hhcmUnKTtcblxudmFyIFB1YmxpY0xpbmtTZWN1cmVPcHRpb25zID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuICAgIGRpc3BsYXlOYW1lOiAnUHVibGljTGlua1NlY3VyZU9wdGlvbnMnLFxuXG4gICAgcHJvcFR5cGVzOiB7XG4gICAgICAgIGxpbmtEYXRhOiBSZWFjdC5Qcm9wVHlwZXMub2JqZWN0LmlzUmVxdWlyZWQsXG4gICAgICAgIHNoYXJlTW9kZWw6IFJlYWN0LlByb3BUeXBlcy5pbnN0YW5jZU9mKFNoYXJlTW9kZWwpLFxuICAgICAgICBzdHlsZTogUmVhY3QuUHJvcFR5cGVzLm9iamVjdFxuICAgIH0sXG5cbiAgICB1cGRhdGVETEV4cGlyYXRpb25GaWVsZDogZnVuY3Rpb24gdXBkYXRlRExFeHBpcmF0aW9uRmllbGQoZXZlbnQpIHtcbiAgICAgICAgdmFyIG5ld1ZhbHVlID0gZXZlbnQuY3VycmVudFRhcmdldC52YWx1ZTtcbiAgICAgICAgaWYgKHBhcnNlSW50KG5ld1ZhbHVlKSA8IDApIG5ld1ZhbHVlID0gLXBhcnNlSW50KG5ld1ZhbHVlKTtcbiAgICAgICAgdGhpcy5wcm9wcy5zaGFyZU1vZGVsLnNldEV4cGlyYXRpb25Gb3IodGhpcy5wcm9wcy5saW5rRGF0YS5oYXNoLCBcImRvd25sb2Fkc1wiLCBuZXdWYWx1ZSk7XG4gICAgfSxcblxuICAgIHVwZGF0ZURheXNFeHBpcmF0aW9uRmllbGQ6IGZ1bmN0aW9uIHVwZGF0ZURheXNFeHBpcmF0aW9uRmllbGQoZXZlbnQsIG5ld1ZhbHVlKSB7XG4gICAgICAgIGlmICghbmV3VmFsdWUpIHtcbiAgICAgICAgICAgIG5ld1ZhbHVlID0gZXZlbnQuY3VycmVudFRhcmdldC5nZXRWYWx1ZSgpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucHJvcHMuc2hhcmVNb2RlbC5zZXRFeHBpcmF0aW9uRm9yKHRoaXMucHJvcHMubGlua0RhdGEuaGFzaCwgXCJkYXlzXCIsIG5ld1ZhbHVlKTtcbiAgICB9LFxuXG4gICAgb25EYXRlQ2hhbmdlOiBmdW5jdGlvbiBvbkRhdGVDaGFuZ2UoZXZlbnQsIHZhbHVlKSB7XG4gICAgICAgIHZhciB0b2RheSA9IG5ldyBEYXRlKCk7XG4gICAgICAgIHZhciBkYXRlMSA9IERhdGUuVVRDKHRvZGF5LmdldEZ1bGxZZWFyKCksIHRvZGF5LmdldE1vbnRoKCksIHRvZGF5LmdldERhdGUoKSk7XG4gICAgICAgIHZhciBkYXRlMiA9IERhdGUuVVRDKHZhbHVlLmdldEZ1bGxZZWFyKCksIHZhbHVlLmdldE1vbnRoKCksIHZhbHVlLmdldERhdGUoKSk7XG4gICAgICAgIHZhciBtcyA9IE1hdGguYWJzKGRhdGUxIC0gZGF0ZTIpO1xuICAgICAgICB2YXIgaW50ZWdlclZhbCA9IE1hdGguZmxvb3IobXMgLyAxMDAwIC8gNjAgLyA2MCAvIDI0KTsgLy9mbG9vciBzaG91bGQgYmUgdW5uZWNlc3NhcnksIGJ1dCBqdXN0IGluIGNhc2VcbiAgICAgICAgdGhpcy51cGRhdGVEYXlzRXhwaXJhdGlvbkZpZWxkKGV2ZW50LCBpbnRlZ2VyVmFsKTtcbiAgICB9LFxuXG4gICAgcmVzZXRQYXNzd29yZDogZnVuY3Rpb24gcmVzZXRQYXNzd29yZCgpIHtcbiAgICAgICAgdGhpcy5wcm9wcy5zaGFyZU1vZGVsLnJlc2V0UGFzc3dvcmQodGhpcy5wcm9wcy5saW5rRGF0YS5oYXNoKTtcbiAgICB9LFxuXG4gICAgdXBkYXRlUGFzc3dvcmQ6IGZ1bmN0aW9uIHVwZGF0ZVBhc3N3b3JkKG5ld1ZhbHVlLCBvbGRWYWx1ZSkge1xuICAgICAgICBpZiAobmV3VmFsdWUgJiYgIXRoaXMucmVmcy5wYXNzRmllbGQuaXNWYWxpZCgpKSB7XG4gICAgICAgICAgICB0aGlzLnByb3BzLnNoYXJlTW9kZWwuc2V0VmFsaWRTdGF0dXMoZmFsc2UpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5wcm9wcy5zaGFyZU1vZGVsLnNldFZhbGlkU3RhdHVzKHRydWUpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucHJvcHMuc2hhcmVNb2RlbC51cGRhdGVQYXNzd29yZCh0aGlzLnByb3BzLmxpbmtEYXRhLmhhc2gsIG5ld1ZhbHVlKTtcbiAgICB9LFxuXG4gICAgcmVuZGVyUGFzc3dvcmRDb250YWluZXI6IGZ1bmN0aW9uIHJlbmRlclBhc3N3b3JkQ29udGFpbmVyKCkge1xuICAgICAgICB2YXIgbGlua0lkID0gdGhpcy5wcm9wcy5saW5rRGF0YS5oYXNoO1xuICAgICAgICB2YXIgcGFzc3dvcmRGaWVsZDtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMuc2hhcmVNb2RlbC5oYXNIaWRkZW5QYXNzd29yZChsaW5rSWQpKSB7XG4gICAgICAgICAgICB2YXIgcmVzZXRQYXNzd29yZCA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoRmxhdEJ1dHRvbiwge1xuICAgICAgICAgICAgICAgIGRpc2FibGVkOiB0aGlzLnByb3BzLmlzUmVhZG9ubHkoKSxcbiAgICAgICAgICAgICAgICBzZWNvbmRhcnk6IHRydWUsXG4gICAgICAgICAgICAgICAgb25DbGljazogdGhpcy5yZXNldFBhc3N3b3JkLFxuICAgICAgICAgICAgICAgIGxhYmVsOiB0aGlzLnByb3BzLmdldE1lc3NhZ2UoJzE3NCcpXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHBhc3N3b3JkRmllbGQgPSBSZWFjdC5jcmVhdGVFbGVtZW50KFRleHRGaWVsZCwge1xuICAgICAgICAgICAgICAgIGZsb2F0aW5nTGFiZWxUZXh0OiB0aGlzLnByb3BzLmdldE1lc3NhZ2UoJzIzJyksXG4gICAgICAgICAgICAgICAgZGlzYWJsZWQ6IHRydWUsXG4gICAgICAgICAgICAgICAgdmFsdWU6ICcqKioqKioqKicsXG4gICAgICAgICAgICAgICAgZnVsbFdpZHRoOiB0cnVlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIGlmICghdGhpcy5wcm9wcy5pc1JlYWRvbmx5KCkpIHtcbiAgICAgICAgICAgIHBhc3N3b3JkRmllbGQgPSBSZWFjdC5jcmVhdGVFbGVtZW50KFZhbGlkUGFzc3dvcmQsIHtcbiAgICAgICAgICAgICAgICBuYW1lOiAnc2hhcmUtcGFzc3dvcmQnLFxuICAgICAgICAgICAgICAgIHJlZjogJ3Bhc3NGaWVsZCcsXG4gICAgICAgICAgICAgICAgYXR0cmlidXRlczogeyBsYWJlbDogdGhpcy5wcm9wcy5nZXRNZXNzYWdlKCcyMycpIH0sXG4gICAgICAgICAgICAgICAgdmFsdWU6IHRoaXMucHJvcHMuc2hhcmVNb2RlbC5nZXRQYXNzd29yZChsaW5rSWQpLFxuICAgICAgICAgICAgICAgIG9uQ2hhbmdlOiB0aGlzLnVwZGF0ZVBhc3N3b3JkXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocGFzc3dvcmRGaWVsZCkge1xuICAgICAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6ICdwYXNzd29yZC1jb250YWluZXInLCBzdHlsZTogeyBkaXNwbGF5OiAnZmxleCcsIGFsaWduSXRlbXM6ICdiYXNlbGluZScsIG1hcmdpbkJvdHRvbTogMTAgfSB9LFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nLCB7IGNsYXNzTmFtZTogJ2FqeHBfaWNvbl9zcGFuIG1kaSBtZGktZmlsZS1sb2NrJyB9KSxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICAgICAgeyBzdHlsZTogeyB3aWR0aDogcmVzZXRQYXNzd29yZCA/ICc1MCUnIDogJzEwMCUnLCBkaXNwbGF5OiAnaW5saW5lLWJsb2NrJyB9IH0sXG4gICAgICAgICAgICAgICAgICAgIHBhc3N3b3JkRmllbGRcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgIHJlc2V0UGFzc3dvcmQgJiYgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgICAgIHsgc3R5bGU6IHsgd2lkdGg6ICc1MCUnLCBkaXNwbGF5OiAnaW5saW5lLWJsb2NrJyB9IH0sXG4gICAgICAgICAgICAgICAgICAgIHJlc2V0UGFzc3dvcmRcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgZm9ybWF0RGF0ZTogZnVuY3Rpb24gZm9ybWF0RGF0ZShkYXRlT2JqZWN0KSB7XG4gICAgICAgIHZhciBkYXRlRm9ybWF0RGF5ID0gdGhpcy5wcm9wcy5nZXRNZXNzYWdlKCdkYXRlX2Zvcm1hdCcsICcnKS5zcGxpdCgnICcpLnNoaWZ0KCk7XG4gICAgICAgIHJldHVybiBkYXRlRm9ybWF0RGF5LnJlcGxhY2UoJ1knLCBkYXRlT2JqZWN0LmdldEZ1bGxZZWFyKCkpLnJlcGxhY2UoJ20nLCBkYXRlT2JqZWN0LmdldE1vbnRoKCkgKyAxKS5yZXBsYWNlKCdkJywgZGF0ZU9iamVjdC5nZXREYXRlKCkpO1xuICAgIH0sXG5cbiAgICByZW5kZXI6IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgICAgdmFyIGxpbmtJZCA9IHRoaXMucHJvcHMubGlua0RhdGEuaGFzaDtcbiAgICAgICAgdmFyIHBhc3NDb250YWluZXIgPSB0aGlzLnJlbmRlclBhc3N3b3JkQ29udGFpbmVyKCk7XG4gICAgICAgIHZhciBjcnRMaW5rRExBbGxvd2VkID0gdGhpcy5wcm9wcy5zaGFyZU1vZGVsLmdldFB1YmxpY0xpbmtQZXJtaXNzaW9uKGxpbmtJZCwgJ2Rvd25sb2FkJyk7XG4gICAgICAgIHZhciBkbExpbWl0VmFsdWUgPSB0aGlzLnByb3BzLnNoYXJlTW9kZWwuZ2V0RXhwaXJhdGlvbkZvcihsaW5rSWQsICdkb3dubG9hZHMnKSA9PT0gMCA/IFwiXCIgOiB0aGlzLnByb3BzLnNoYXJlTW9kZWwuZ2V0RXhwaXJhdGlvbkZvcihsaW5rSWQsICdkb3dubG9hZHMnKTtcbiAgICAgICAgdmFyIGV4cGlyYXRpb25EYXRlVmFsdWUgPSB0aGlzLnByb3BzLnNoYXJlTW9kZWwuZ2V0RXhwaXJhdGlvbkZvcihsaW5rSWQsICdkYXlzJykgPT09IDAgPyBcIlwiIDogdGhpcy5wcm9wcy5zaGFyZU1vZGVsLmdldEV4cGlyYXRpb25Gb3IobGlua0lkLCAnZGF5cycpO1xuICAgICAgICB2YXIgYXV0aCA9IFNoYXJlTW9kZWwuZ2V0QXV0aG9yaXphdGlvbnModGhpcy5wcm9wcy5weWRpbyk7XG4gICAgICAgIHZhciB0b2RheSA9IG5ldyBEYXRlKCk7XG5cbiAgICAgICAgdmFyIGNhbEljb24gPSBSZWFjdC5jcmVhdGVFbGVtZW50KCdzcGFuJywgeyBjbGFzc05hbWU6ICdhanhwX2ljb25fc3BhbiBtZGkgbWRpLWNhbGVuZGFyLWNsb2NrJyB9KTtcbiAgICAgICAgdmFyIGV4cERhdGUgPSB1bmRlZmluZWQsXG4gICAgICAgICAgICBtYXhEYXRlID0gdW5kZWZpbmVkLFxuICAgICAgICAgICAgbWF4RG93bmxvYWRzID0gbnVsbCxcbiAgICAgICAgICAgIGRhdGVFeHBpcmVkID0gZmFsc2UsXG4gICAgICAgICAgICBkbEV4cGlyZWQgPSBmYWxzZTtcbiAgICAgICAgaWYgKHBhcnNlSW50KGF1dGgubWF4X2V4cGlyYXRpb24pID4gMCkge1xuICAgICAgICAgICAgbWF4RGF0ZSA9IG5ldyBEYXRlKCk7XG4gICAgICAgICAgICBtYXhEYXRlLnNldERhdGUodG9kYXkuZ2V0RGF0ZSgpICsgcGFyc2VJbnQoYXV0aC5tYXhfZXhwaXJhdGlvbikpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwYXJzZUludChhdXRoLm1heF9kb3dubG9hZHMpID4gMCkge1xuICAgICAgICAgICAgbWF4RG93bmxvYWRzID0gcGFyc2VJbnQoYXV0aC5tYXhfZG93bmxvYWRzKTtcbiAgICAgICAgICAgIGRsTGltaXRWYWx1ZSA9IE1hdGgubWluKGRsTGltaXRWYWx1ZSwgbWF4RG93bmxvYWRzKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZXhwaXJhdGlvbkRhdGVWYWx1ZSkge1xuICAgICAgICAgICAgaWYgKGV4cGlyYXRpb25EYXRlVmFsdWUgPCAwKSB7XG4gICAgICAgICAgICAgICAgZGF0ZUV4cGlyZWQgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZXhwRGF0ZSA9IG5ldyBEYXRlKCk7XG4gICAgICAgICAgICBleHBEYXRlLnNldERhdGUodG9kYXkuZ2V0RGF0ZSgpICsgcGFyc2VJbnQoZXhwaXJhdGlvbkRhdGVWYWx1ZSkpO1xuICAgICAgICAgICAgdmFyIGNsZWFyVmFsdWUgPSAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHRoaXMucHJvcHMuc2hhcmVNb2RlbC5zZXRFeHBpcmF0aW9uRm9yKGxpbmtJZCwgXCJkYXlzXCIsIFwiXCIpO1xuICAgICAgICAgICAgfSkuYmluZCh0aGlzKTtcbiAgICAgICAgICAgIGNhbEljb24gPSBSZWFjdC5jcmVhdGVFbGVtZW50KCdzcGFuJywgeyBjbGFzc05hbWU6ICdtZGkgbWRpLWNsb3NlLWNpcmNsZSBhanhwX2ljb25fc3BhbicsIG9uQ2xpY2s6IGNsZWFyVmFsdWUgfSk7XG4gICAgICAgICAgICB2YXIgY2FsTGFiZWwgPSBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICdzcGFuJyxcbiAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ2NhbExhYmVsSGFzVmFsdWUnIH0sXG4gICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5nZXRNZXNzYWdlKGRhdGVFeHBpcmVkID8gJzIxYicgOiAnMjEnKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZGxMaW1pdFZhbHVlKSB7XG4gICAgICAgICAgICB2YXIgZGxDb3VudGVyID0gdGhpcy5wcm9wcy5zaGFyZU1vZGVsLmdldERvd25sb2FkQ291bnRlcihsaW5rSWQpO1xuICAgICAgICAgICAgdmFyIHJlc2V0RGwgPSAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGlmICh3aW5kb3cuY29uZmlybSh0aGlzLnByb3BzLmdldE1lc3NhZ2UoJzEwNicpKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnByb3BzLnNoYXJlTW9kZWwucmVzZXREb3dubG9hZENvdW50ZXIobGlua0lkLCBmdW5jdGlvbiAoKSB7fSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSkuYmluZCh0aGlzKTtcbiAgICAgICAgICAgIGlmIChkbENvdW50ZXIpIHtcbiAgICAgICAgICAgICAgICB2YXIgcmVzZXRMaW5rID0gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgICAgJ2EnLFxuICAgICAgICAgICAgICAgICAgICB7IHN0eWxlOiB7IGN1cnNvcjogJ3BvaW50ZXInIH0sIG9uQ2xpY2s6IHJlc2V0RGwsIHRpdGxlOiB0aGlzLnByb3BzLmdldE1lc3NhZ2UoJzE3JykgfSxcbiAgICAgICAgICAgICAgICAgICAgJygnLFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnByb3BzLmdldE1lc3NhZ2UoJzE2JyksXG4gICAgICAgICAgICAgICAgICAgICcpJ1xuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgaWYgKGRsQ291bnRlciA+PSBkbExpbWl0VmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgZGxFeHBpcmVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgZGxDb3VudGVyU3RyaW5nID0gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAnc3BhbicsXG4gICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6ICdkbENvdW50ZXJTdHJpbmcnIH0sXG4gICAgICAgICAgICAgICAgZGxDb3VudGVyICsgJy8nICsgZGxMaW1pdFZhbHVlLFxuICAgICAgICAgICAgICAgICcgJyxcbiAgICAgICAgICAgICAgICByZXNldExpbmtcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICBfbWFpbkNhcmQyWydkZWZhdWx0J10sXG4gICAgICAgICAgICB7IHN0eWxlOiB0aGlzLnByb3BzLnN0eWxlLCB0aXRsZTogdGhpcy5wcm9wcy5nZXRNZXNzYWdlKCcxOTYnKSB9LFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ3NlY3Rpb24tbGVnZW5kJyB9LFxuICAgICAgICAgICAgICAgIHRoaXMucHJvcHMuZ2V0TWVzc2FnZSgnMjQnKVxuICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIHBhc3NDb250YWluZXIsXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAnZXhwaXJlcycsIHN0eWxlOiB7IGRpc3BsYXk6ICdmbGV4JywgYWxpZ25JdGVtczogJ2NlbnRlcicgfSB9LFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgICAgICB7IHN0eWxlOiB7IGZsZXg6IDEsIGRpc3BsYXk6ICdmbGV4JywgYWxpZ25JdGVtczogJ2NlbnRlcicsIHBvc2l0aW9uOiAncmVsYXRpdmUnIH0sIGNsYXNzTmFtZTogZGF0ZUV4cGlyZWQgPyAnbGltaXQtYmxvY2stZXhwaXJlZCcgOiBudWxsIH0sXG4gICAgICAgICAgICAgICAgICAgIGNhbEljb24sXG4gICAgICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoRGF0ZVBpY2tlciwge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVmOiAnZXhwaXJhdGlvbkRhdGUnLFxuICAgICAgICAgICAgICAgICAgICAgICAga2V5OiAnc3RhcnQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IGV4cERhdGUsXG4gICAgICAgICAgICAgICAgICAgICAgICBtaW5EYXRlOiBuZXcgRGF0ZSgpLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWF4RGF0ZTogbWF4RGF0ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGF1dG9PazogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGRpc2FibGVkOiB0aGlzLnByb3BzLmlzUmVhZG9ubHkoKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG9uQ2hhbmdlOiB0aGlzLm9uRGF0ZUNoYW5nZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHNob3dZZWFyU2VsZWN0b3I6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBmbG9hdGluZ0xhYmVsVGV4dDogdGhpcy5wcm9wcy5nZXRNZXNzYWdlKGRhdGVFeHBpcmVkID8gJzIxYicgOiAnMjEnKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1vZGU6ICdsYW5kc2NhcGUnLFxuICAgICAgICAgICAgICAgICAgICAgICAgZm9ybWF0RGF0ZTogdGhpcy5mb3JtYXREYXRlLFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHsgZmxleDogMSB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgZnVsbFdpZHRoOiB0cnVlXG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICAgICAgeyBzdHlsZTogeyBmbGV4OiAxLCBhbGlnbkl0ZW1zOiAnY2VudGVyJywgZGlzcGxheTogY3J0TGlua0RMQWxsb3dlZCA/ICdmbGV4JyA6ICdub25lJywgcG9zaXRpb246ICdyZWxhdGl2ZScgfSwgY2xhc3NOYW1lOiBkbEV4cGlyZWQgPyAnbGltaXQtYmxvY2stZXhwaXJlZCcgOiBudWxsIH0sXG4gICAgICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nLCB7IGNsYXNzTmFtZTogJ21kaSBtZGktZG93bmxvYWQgYWp4cF9pY29uX3NwYW4nIH0pLFxuICAgICAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFRleHRGaWVsZCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ251bWJlcicsXG4gICAgICAgICAgICAgICAgICAgICAgICBkaXNhYmxlZDogdGhpcy5wcm9wcy5pc1JlYWRvbmx5KCksXG4gICAgICAgICAgICAgICAgICAgICAgICBmbG9hdGluZ0xhYmVsVGV4dDogdGhpcy5wcm9wcy5nZXRNZXNzYWdlKGRsRXhwaXJlZCA/ICcyMmInIDogJzIyJyksXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogZGxMaW1pdFZhbHVlID4gMCA/IGRsTGltaXRWYWx1ZSA6ICcnLFxuICAgICAgICAgICAgICAgICAgICAgICAgb25DaGFuZ2U6IHRoaXMudXBkYXRlRExFeHBpcmF0aW9uRmllbGQsXG4gICAgICAgICAgICAgICAgICAgICAgICBmdWxsV2lkdGg6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBzdHlsZTogeyBmbGV4OiAxIH1cbiAgICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgICAgIGRsQ291bnRlclN0cmluZ1xuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICB9XG59KTtcblxuZXhwb3J0c1snZGVmYXVsdCddID0gUHVibGljTGlua1NlY3VyZU9wdGlvbnMgPSAoMCwgX1NoYXJlQ29udGV4dENvbnN1bWVyMlsnZGVmYXVsdCddKShQdWJsaWNMaW5rU2VjdXJlT3B0aW9ucyk7XG5leHBvcnRzWydkZWZhdWx0J10gPSBQdWJsaWNMaW5rU2VjdXJlT3B0aW9ucztcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ19fZXNNb2R1bGUnLCB7XG4gICAgdmFsdWU6IHRydWVcbn0pO1xuXG52YXIgX2V4dGVuZHMgPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uICh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTsgZm9yICh2YXIga2V5IGluIHNvdXJjZSkgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkgeyB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldOyB9IH0gfSByZXR1cm4gdGFyZ2V0OyB9O1xuXG52YXIgX2NyZWF0ZUNsYXNzID0gKGZ1bmN0aW9uICgpIHsgZnVuY3Rpb24gZGVmaW5lUHJvcGVydGllcyh0YXJnZXQsIHByb3BzKSB7IGZvciAodmFyIGkgPSAwOyBpIDwgcHJvcHMubGVuZ3RoOyBpKyspIHsgdmFyIGRlc2NyaXB0b3IgPSBwcm9wc1tpXTsgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gZGVzY3JpcHRvci5lbnVtZXJhYmxlIHx8IGZhbHNlOyBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7IGlmICgndmFsdWUnIGluIGRlc2NyaXB0b3IpIGRlc2NyaXB0b3Iud3JpdGFibGUgPSB0cnVlOyBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBkZXNjcmlwdG9yLmtleSwgZGVzY3JpcHRvcik7IH0gfSByZXR1cm4gZnVuY3Rpb24gKENvbnN0cnVjdG9yLCBwcm90b1Byb3BzLCBzdGF0aWNQcm9wcykgeyBpZiAocHJvdG9Qcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIHByb3RvUHJvcHMpOyBpZiAoc3RhdGljUHJvcHMpIGRlZmluZVByb3BlcnRpZXMoQ29uc3RydWN0b3IsIHN0YXRpY1Byb3BzKTsgcmV0dXJuIENvbnN0cnVjdG9yOyB9OyB9KSgpO1xuXG52YXIgX2dldCA9IGZ1bmN0aW9uIGdldChfeCwgX3gyLCBfeDMpIHsgdmFyIF9hZ2FpbiA9IHRydWU7IF9mdW5jdGlvbjogd2hpbGUgKF9hZ2FpbikgeyB2YXIgb2JqZWN0ID0gX3gsIHByb3BlcnR5ID0gX3gyLCByZWNlaXZlciA9IF94MzsgX2FnYWluID0gZmFsc2U7IGlmIChvYmplY3QgPT09IG51bGwpIG9iamVjdCA9IEZ1bmN0aW9uLnByb3RvdHlwZTsgdmFyIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG9iamVjdCwgcHJvcGVydHkpOyBpZiAoZGVzYyA9PT0gdW5kZWZpbmVkKSB7IHZhciBwYXJlbnQgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2Yob2JqZWN0KTsgaWYgKHBhcmVudCA9PT0gbnVsbCkgeyByZXR1cm4gdW5kZWZpbmVkOyB9IGVsc2UgeyBfeCA9IHBhcmVudDsgX3gyID0gcHJvcGVydHk7IF94MyA9IHJlY2VpdmVyOyBfYWdhaW4gPSB0cnVlOyBkZXNjID0gcGFyZW50ID0gdW5kZWZpbmVkOyBjb250aW51ZSBfZnVuY3Rpb247IH0gfSBlbHNlIGlmICgndmFsdWUnIGluIGRlc2MpIHsgcmV0dXJuIGRlc2MudmFsdWU7IH0gZWxzZSB7IHZhciBnZXR0ZXIgPSBkZXNjLmdldDsgaWYgKGdldHRlciA9PT0gdW5kZWZpbmVkKSB7IHJldHVybiB1bmRlZmluZWQ7IH0gcmV0dXJuIGdldHRlci5jYWxsKHJlY2VpdmVyKTsgfSB9IH07XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7ICdkZWZhdWx0Jzogb2JqIH07IH1cblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24nKTsgfSB9XG5cbmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09ICdmdW5jdGlvbicgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90ICcgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5zZXRQcm90b3R5cGVPZihzdWJDbGFzcywgc3VwZXJDbGFzcykgOiBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9XG5cbnZhciBfU2hhcmVDb250ZXh0Q29uc3VtZXIgPSByZXF1aXJlKCcuLi9TaGFyZUNvbnRleHRDb25zdW1lcicpO1xuXG52YXIgX1NoYXJlQ29udGV4dENvbnN1bWVyMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1NoYXJlQ29udGV4dENvbnN1bWVyKTtcblxudmFyIFJlYWN0ID0gcmVxdWlyZSgncmVhY3QnKTtcbnZhciBSZWFjdERPTSA9IHJlcXVpcmUoJ3JlYWN0LWRvbScpO1xuXG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKCdtYXRlcmlhbC11aScpO1xuXG52YXIgUmFpc2VkQnV0dG9uID0gX3JlcXVpcmUuUmFpc2VkQnV0dG9uO1xudmFyIFRleHRGaWVsZCA9IF9yZXF1aXJlLlRleHRGaWVsZDtcbnZhciBQYXBlciA9IF9yZXF1aXJlLlBhcGVyO1xudmFyIEljb25CdXR0b24gPSBfcmVxdWlyZS5JY29uQnV0dG9uO1xuXG52YXIgU2hhcmVNb2RlbCA9IHJlcXVpcmUoJ3B5ZGlvJykucmVxdWlyZUxpYignUmVhY3RNb2RlbFNoYXJlJyk7XG52YXIgQ2xpcGJvYXJkID0gcmVxdWlyZSgnY2xpcGJvYXJkJyk7XG5cbnZhciBUYXJnZXRlZFVzZXJMaW5rID0gKGZ1bmN0aW9uIChfUmVhY3QkQ29tcG9uZW50KSB7XG4gICAgX2luaGVyaXRzKFRhcmdldGVkVXNlckxpbmssIF9SZWFjdCRDb21wb25lbnQpO1xuXG4gICAgZnVuY3Rpb24gVGFyZ2V0ZWRVc2VyTGluayhwcm9wcykge1xuICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgVGFyZ2V0ZWRVc2VyTGluayk7XG5cbiAgICAgICAgX2dldChPYmplY3QuZ2V0UHJvdG90eXBlT2YoVGFyZ2V0ZWRVc2VyTGluay5wcm90b3R5cGUpLCAnY29uc3RydWN0b3InLCB0aGlzKS5jYWxsKHRoaXMsIHByb3BzKTtcbiAgICAgICAgdGhpcy5zdGF0ZSA9IHsgY29weU1lc3NhZ2U6ICcnIH07XG4gICAgfVxuXG4gICAgX2NyZWF0ZUNsYXNzKFRhcmdldGVkVXNlckxpbmssIFt7XG4gICAgICAgIGtleTogJ2NvbXBvbmVudERpZE1vdW50JyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGNvbXBvbmVudERpZE1vdW50KCkge1xuICAgICAgICAgICAgaWYgKHRoaXMuX2NsaXApIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9jbGlwLmRlc3Ryb3koKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLl9idXR0b24pIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9jbGlwID0gbmV3IENsaXBib2FyZCh0aGlzLl9idXR0b24sIHtcbiAgICAgICAgICAgICAgICAgICAgdGV4dDogKGZ1bmN0aW9uICh0cmlnZ2VyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5wcm9wcy5saW5rO1xuICAgICAgICAgICAgICAgICAgICB9KS5iaW5kKHRoaXMpXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgdGhpcy5fY2xpcC5vbignc3VjY2VzcycsIChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBjb3B5TWVzc2FnZTogdGhpcy5wcm9wcy5nZXRNZXNzYWdlKCcxOTInKSB9LCB0aGlzLmNsZWFyQ29weU1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgIH0pLmJpbmQodGhpcykpO1xuICAgICAgICAgICAgICAgIHRoaXMuX2NsaXAub24oJ2Vycm9yJywgKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNvcHlNZXNzYWdlID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZ2xvYmFsLm5hdmlnYXRvci5wbGF0Zm9ybS5pbmRleE9mKFwiTWFjXCIpID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb3B5TWVzc2FnZSA9IHRoaXMucHJvcHMuZ2V0TWVzc2FnZSgnMTQ0Jyk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb3B5TWVzc2FnZSA9IHRoaXMucHJvcHMuZ2V0TWVzc2FnZSgnc2hhcmVfY2VudGVyLjE0MycpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBjb3B5TWVzc2FnZTogY29weU1lc3NhZ2UgfSwgdGhpcy5jbGVhckNvcHlNZXNzYWdlKTtcbiAgICAgICAgICAgICAgICB9KS5iaW5kKHRoaXMpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0sIHtcbiAgICAgICAga2V5OiAnY29tcG9uZW50V2lsbFVubW91bnQnLFxuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gY29tcG9uZW50V2lsbFVubW91bnQoKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5fY2xpcCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX2NsaXAuZGVzdHJveSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSwge1xuICAgICAgICBrZXk6ICdjbGVhckNvcHlNZXNzYWdlJyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIGNsZWFyQ29weU1lc3NhZ2UoKSB7XG4gICAgICAgICAgICBzZXRUaW1lb3V0KChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGNvcHlNZXNzYWdlOiAnJyB9KTtcbiAgICAgICAgICAgIH0pLmJpbmQodGhpcyksIDUwMDApO1xuICAgICAgICB9XG4gICAgfSwge1xuICAgICAgICBrZXk6ICdyZW5kZXInLFxuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgICAgICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgICAgICAgICAgdmFyIF9wcm9wcyA9IHRoaXMucHJvcHM7XG4gICAgICAgICAgICB2YXIgZGlzcGxheSA9IF9wcm9wcy5kaXNwbGF5O1xuICAgICAgICAgICAgdmFyIGxpbmsgPSBfcHJvcHMubGluaztcbiAgICAgICAgICAgIHZhciBkb3dubG9hZF9jb3VudCA9IF9wcm9wcy5kb3dubG9hZF9jb3VudDtcblxuICAgICAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgeyBzdHlsZTogeyBkaXNwbGF5OiAnZmxleCcgfSB9LFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgICAgICB7IHN0eWxlOiB7IGZsZXg6IDEgfSB9LFxuICAgICAgICAgICAgICAgICAgICBkaXNwbGF5LFxuICAgICAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KEljb25CdXR0b24sIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHB5ZGlvOiB0aGlzLnByb3BzLnB5ZGlvLFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVmOiBmdW5jdGlvbiAocmVmKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMuX2J1dHRvbiA9IFJlYWN0RE9NLmZpbmRET01Ob2RlKHJlZik7XG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgaWNvbkNsYXNzTmFtZTogJ21kaSBtZGktbGluaycsXG4gICAgICAgICAgICAgICAgICAgICAgICB0b29sdGlwOiB0aGlzLnN0YXRlLmNvcHlNZXNzYWdlIHx8IGxpbmssXG4gICAgICAgICAgICAgICAgICAgICAgICBpY29uU3R5bGU6IHsgZm9udFNpemU6IDEzLCBsaW5lSGVpZ2h0OiAnMTdweCcgfSwgc3R5bGU6IHsgd2lkdGg6IDM0LCBoZWlnaHQ6IDM0LCBwYWRkaW5nOiA2IH1cbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgICAgICB7IHN0eWxlOiB7IHdpZHRoOiA0MCwgdGV4dEFsaWduOiAnY2VudGVyJyB9IH0sXG4gICAgICAgICAgICAgICAgICAgIGRvd25sb2FkX2NvdW50XG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgIH1dKTtcblxuICAgIHJldHVybiBUYXJnZXRlZFVzZXJMaW5rO1xufSkoUmVhY3QuQ29tcG9uZW50KTtcblxudmFyIFRhcmdldGVkVXNlcnMgPSAoZnVuY3Rpb24gKF9SZWFjdCRDb21wb25lbnQyKSB7XG4gICAgX2luaGVyaXRzKFRhcmdldGVkVXNlcnMsIF9SZWFjdCRDb21wb25lbnQyKTtcblxuICAgIGZ1bmN0aW9uIFRhcmdldGVkVXNlcnMocHJvcHMsIGNvbnRleHQpIHtcbiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFRhcmdldGVkVXNlcnMpO1xuXG4gICAgICAgIF9nZXQoT2JqZWN0LmdldFByb3RvdHlwZU9mKFRhcmdldGVkVXNlcnMucHJvdG90eXBlKSwgJ2NvbnN0cnVjdG9yJywgdGhpcykuY2FsbCh0aGlzLCBwcm9wcywgY29udGV4dCk7XG4gICAgICAgIHRoaXMuc3RhdGUgPSB7IG9wZW46IGZhbHNlIH07XG4gICAgfVxuXG4gICAgX2NyZWF0ZUNsYXNzKFRhcmdldGVkVXNlcnMsIFt7XG4gICAgICAgIGtleTogJ3JlbmRlcicsXG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgICAgICAgICB2YXIgX3RoaXMyID0gdGhpcztcblxuICAgICAgICAgICAgdmFyIHRhcmdldF91c2VycyA9IHRoaXMucHJvcHMubGlua0RhdGEudGFyZ2V0X3VzZXJzO1xuXG4gICAgICAgICAgICB2YXIgaXRlbXMgPSBPYmplY3Qua2V5cyh0YXJnZXRfdXNlcnMpLm1hcChmdW5jdGlvbiAoaykge1xuICAgICAgICAgICAgICAgIHZhciB1c2VyRGF0YSA9IHRhcmdldF91c2Vyc1trXTtcbiAgICAgICAgICAgICAgICB2YXIgdGl0bGUgPSBfdGhpczIucHJvcHMubGlua0RhdGEucHVibGljX2xpbmsgKyAnP3U9JyArIGs7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoVGFyZ2V0ZWRVc2VyTGluaywgX2V4dGVuZHMoe30sIHVzZXJEYXRhLCB7IGxpbms6IHRpdGxlIH0pKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKCFpdGVtcy5sZW5ndGgpIHJldHVybiBudWxsO1xuXG4gICAgICAgICAgICB2YXIgcm9vdFN0eWxlID0ge1xuICAgICAgICAgICAgICAgIGxpbmVIZWlnaHQ6ICczNHB4JyxcbiAgICAgICAgICAgICAgICBwYWRkaW5nOiAnNHB4IDEwcHggNHB4JyxcbiAgICAgICAgICAgICAgICBmb250U2l6ZTogMTQsXG4gICAgICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yOiAnI2ZhZmFmYScsXG4gICAgICAgICAgICAgICAgYm9yZGVyUmFkaXVzOiAyXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgdmFyIGhlYWRlclN0eWxlID0ge1xuICAgICAgICAgICAgICAgIGJvcmRlckJvdHRvbTogdGhpcy5zdGF0ZS5vcGVuID8gJzFweCBzb2xpZCAjNzU3NTc1JyA6ICcnLFxuICAgICAgICAgICAgICAgIGNvbG9yOiAncmdiYSgwLCAwLCAwLCAwLjM2KSdcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgIHsgc3R5bGU6IHJvb3RTdHlsZSB9LFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgICAgICB7IHN0eWxlOiBfZXh0ZW5kcyh7IGRpc3BsYXk6ICdmbGV4JyB9LCBoZWFkZXJTdHlsZSkgfSxcbiAgICAgICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgICAgICAgICAgeyBzdHlsZTogeyBmbGV4OiAxIH0gfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucHJvcHMuZ2V0TWVzc2FnZSgnMjQ1JykucmVwbGFjZSgnJXMnLCBpdGVtcy5sZW5ndGgpLFxuICAgICAgICAgICAgICAgICAgICAgICAgJyAnLFxuICAgICAgICAgICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudCgnc3BhbicsIHsgY2xhc3NOYW1lOiAnbWRpIG1kaS1jaGV2cm9uLScgKyAodGhpcy5zdGF0ZS5vcGVuID8gJ3VwJyA6ICdkb3duJyksIHN0eWxlOiB7IGN1cnNvcjogJ3BvaW50ZXInIH0sIG9uQ2xpY2s6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMyLnNldFN0YXRlKHsgb3BlbjogIV90aGlzMi5zdGF0ZS5vcGVuIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gfSlcbiAgICAgICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0ZS5vcGVuICYmIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHsgc3R5bGU6IHsgd2lkdGg6IDQwLCB0ZXh0QWxpZ246ICdjZW50ZXInIH0gfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICcjREwnXG4gICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgIHRoaXMuc3RhdGUub3BlbiAmJiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgaXRlbXNcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgfV0pO1xuXG4gICAgcmV0dXJuIFRhcmdldGVkVXNlcnM7XG59KShSZWFjdC5Db21wb25lbnQpO1xuXG5UYXJnZXRlZFVzZXJzLnByb3BUeXBlcyA9IHtcblxuICAgIGxpbmtEYXRhOiBSZWFjdC5Qcm9wVHlwZXMub2JqZWN0LmlzUmVxdWlyZWQsXG4gICAgc2hhcmVNb2RlbDogUmVhY3QuUHJvcFR5cGVzLmluc3RhbmNlT2YoU2hhcmVNb2RlbClcblxufTtcblxuZXhwb3J0c1snZGVmYXVsdCddID0gVGFyZ2V0ZWRVc2VycyA9ICgwLCBfU2hhcmVDb250ZXh0Q29uc3VtZXIyWydkZWZhdWx0J10pKFRhcmdldGVkVXNlcnMpO1xuVGFyZ2V0ZWRVc2VyTGluayA9ICgwLCBfU2hhcmVDb250ZXh0Q29uc3VtZXIyWydkZWZhdWx0J10pKFRhcmdldGVkVXNlckxpbmspO1xuXG5leHBvcnRzWydkZWZhdWx0J10gPSBUYXJnZXRlZFVzZXJzO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG4iLCIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnX19lc01vZHVsZScsIHtcbiAgICB2YWx1ZTogdHJ1ZVxufSk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7ICdkZWZhdWx0Jzogb2JqIH07IH1cblxudmFyIF9TaGFyZUNvbnRleHRDb25zdW1lciA9IHJlcXVpcmUoJy4uL1NoYXJlQ29udGV4dENvbnN1bWVyJyk7XG5cbnZhciBfU2hhcmVDb250ZXh0Q29uc3VtZXIyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfU2hhcmVDb250ZXh0Q29uc3VtZXIpO1xuXG52YXIgX1JlbW90ZVVzZXJzID0gcmVxdWlyZSgnLi9SZW1vdGVVc2VycycpO1xuXG52YXIgX1JlbW90ZVVzZXJzMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1JlbW90ZVVzZXJzKTtcblxudmFyIF9TaGFyZWRVc2VycyA9IHJlcXVpcmUoJy4vU2hhcmVkVXNlcnMnKTtcblxudmFyIF9TaGFyZWRVc2VyczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9TaGFyZWRVc2Vycyk7XG5cbnZhciBSZWFjdCA9IHJlcXVpcmUoJ3JlYWN0Jyk7XG5cbnZhciBfcmVxdWlyZSA9IHJlcXVpcmUoJ21hdGVyaWFsLXVpJyk7XG5cbnZhciBEaXZpZGVyID0gX3JlcXVpcmUuRGl2aWRlcjtcblxudmFyIFNoYXJlTW9kZWwgPSByZXF1aXJlKCdweWRpbycpLnJlcXVpcmVMaWIoJ1JlYWN0TW9kZWxTaGFyZScpO1xuXG52YXIgVXNlcnNQYW5lbCA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcbiAgICBkaXNwbGF5TmFtZTogJ1VzZXJzUGFuZWwnLFxuXG4gICAgcHJvcFR5cGVzOiB7XG4gICAgICAgIHNoYXJlTW9kZWw6IFJlYWN0LlByb3BUeXBlcy5pbnN0YW5jZU9mKFNoYXJlTW9kZWwpLFxuICAgICAgICBzaG93TWFpbGVyOiBSZWFjdC5Qcm9wVHlwZXMuZnVuY1xuICAgIH0sXG5cbiAgICBvblVzZXJVcGRhdGU6IGZ1bmN0aW9uIG9uVXNlclVwZGF0ZShvcGVyYXRpb24sIHVzZXJJZCwgdXNlckRhdGEpIHtcbiAgICAgICAgdGhpcy5wcm9wcy5zaGFyZU1vZGVsLnVwZGF0ZVNoYXJlZFVzZXIob3BlcmF0aW9uLCB1c2VySWQsIHVzZXJEYXRhKTtcbiAgICB9LFxuXG4gICAgb25TYXZlU2VsZWN0aW9uOiBmdW5jdGlvbiBvblNhdmVTZWxlY3Rpb24oKSB7XG4gICAgICAgIHZhciBsYWJlbCA9IHdpbmRvdy5wcm9tcHQodGhpcy5wcm9wcy5nZXRNZXNzYWdlKDUxMCwgJycpKTtcbiAgICAgICAgaWYgKCFsYWJlbCkgcmV0dXJuO1xuICAgICAgICB0aGlzLnByb3BzLnNoYXJlTW9kZWwuc2F2ZVNlbGVjdGlvbkFzVGVhbShsYWJlbCk7XG4gICAgfSxcblxuICAgIHNlbmRJbnZpdGF0aW9uczogZnVuY3Rpb24gc2VuZEludml0YXRpb25zKHVzZXJPYmplY3RzKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICB2YXIgbWFpbERhdGEgPSB0aGlzLnByb3BzLnNoYXJlTW9kZWwucHJlcGFyZUVtYWlsKFwicmVwb3NpdG9yeVwiKTtcbiAgICAgICAgICAgIHRoaXMucHJvcHMuc2hvd01haWxlcihtYWlsRGF0YS5zdWJqZWN0LCBtYWlsRGF0YS5tZXNzYWdlLCB1c2VyT2JqZWN0cyk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGdsb2JhbC5hbGVydChlLm1lc3NhZ2UpO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgICB2YXIgY3VycmVudFVzZXJzID0gdGhpcy5wcm9wcy5zaGFyZU1vZGVsLmdldFNoYXJlZFVzZXJzKCk7XG4gICAgICAgIHZhciBmZWRlcmF0ZWRFbmFibGVkID0gU2hhcmVNb2RlbC5mZWRlcmF0ZWRTaGFyaW5nRW5hYmxlZCgpO1xuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgeyBzdHlsZTogdGhpcy5wcm9wcy5zdHlsZSB9LFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChfU2hhcmVkVXNlcnMyWydkZWZhdWx0J10sIHtcbiAgICAgICAgICAgICAgICBzaG93VGl0bGU6IGZlZGVyYXRlZEVuYWJsZWQsXG4gICAgICAgICAgICAgICAgdXNlcnM6IGN1cnJlbnRVc2VycyxcbiAgICAgICAgICAgICAgICB1c2VyT2JqZWN0czogdGhpcy5wcm9wcy5zaGFyZU1vZGVsLmdldFNoYXJlZFVzZXJzQXNPYmplY3RzKCksXG4gICAgICAgICAgICAgICAgc2VuZEludml0YXRpb25zOiB0aGlzLnByb3BzLnNob3dNYWlsZXIgPyB0aGlzLnNlbmRJbnZpdGF0aW9ucyA6IG51bGwsXG4gICAgICAgICAgICAgICAgb25Vc2VyVXBkYXRlOiB0aGlzLm9uVXNlclVwZGF0ZSxcbiAgICAgICAgICAgICAgICBzYXZlU2VsZWN0aW9uQXNUZWFtOiBQeWRpb1VzZXJzLkNsaWVudC5zYXZlU2VsZWN0aW9uU3VwcG9ydGVkKCkgPyB0aGlzLm9uU2F2ZVNlbGVjdGlvbiA6IG51bGwsXG4gICAgICAgICAgICAgICAgcHlkaW86IHRoaXMucHJvcHMucHlkaW9cbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgZmVkZXJhdGVkRW5hYmxlZCAmJiBSZWFjdC5jcmVhdGVFbGVtZW50KF9SZW1vdGVVc2VyczJbJ2RlZmF1bHQnXSwge1xuICAgICAgICAgICAgICAgIHNoYXJlTW9kZWw6IHRoaXMucHJvcHMuc2hhcmVNb2RlbCxcbiAgICAgICAgICAgICAgICBvblVzZXJVcGRhdGU6IHRoaXMub25Vc2VyVXBkYXRlLFxuICAgICAgICAgICAgICAgIHB5ZGlvOiB0aGlzLnByb3BzLnB5ZGlvXG4gICAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgIH1cbn0pO1xuXG5leHBvcnRzWydkZWZhdWx0J10gPSBVc2Vyc1BhbmVsID0gKDAsIF9TaGFyZUNvbnRleHRDb25zdW1lcjJbJ2RlZmF1bHQnXSkoVXNlcnNQYW5lbCk7XG5leHBvcnRzWydkZWZhdWx0J10gPSBVc2Vyc1BhbmVsO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG4iLCIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnX19lc01vZHVsZScsIHtcbiAgICB2YWx1ZTogdHJ1ZVxufSk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7ICdkZWZhdWx0Jzogb2JqIH07IH1cblxudmFyIF9TaGFyZUNvbnRleHRDb25zdW1lciA9IHJlcXVpcmUoJy4uL1NoYXJlQ29udGV4dENvbnN1bWVyJyk7XG5cbnZhciBfU2hhcmVDb250ZXh0Q29uc3VtZXIyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfU2hhcmVDb250ZXh0Q29uc3VtZXIpO1xuXG52YXIgX1VzZXJCYWRnZSA9IHJlcXVpcmUoJy4vVXNlckJhZGdlJyk7XG5cbnZhciBfVXNlckJhZGdlMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1VzZXJCYWRnZSk7XG5cbnZhciBSZWFjdCA9IHJlcXVpcmUoJ3JlYWN0Jyk7XG5cbnZhciBSZW1vdGVVc2VyRW50cnkgPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG4gICAgZGlzcGxheU5hbWU6ICdSZW1vdGVVc2VyRW50cnknLFxuXG4gICAgcHJvcFR5cGVzOiB7XG4gICAgICAgIHNoYXJlTW9kZWw6IFJlYWN0LlByb3BUeXBlcy5pbnN0YW5jZU9mKFJlYWN0TW9kZWwuU2hhcmUpLFxuICAgICAgICBsaW5rRGF0YTogUmVhY3QuUHJvcFR5cGVzLm9iamVjdC5pc1JlcXVpcmVkLFxuICAgICAgICBvblJlbW92ZVVzZXI6IFJlYWN0LlByb3BUeXBlcy5mdW5jLmlzUmVxdWlyZWQsXG4gICAgICAgIG9uVXNlclVwZGF0ZTogUmVhY3QuUHJvcFR5cGVzLmZ1bmMuaXNSZXF1aXJlZFxuICAgIH0sXG5cbiAgICBnZXRJbml0aWFsU3RhdGU6IGZ1bmN0aW9uIGdldEluaXRpYWxTdGF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGludGVybmFsVXNlcjogdGhpcy5wcm9wcy5zaGFyZU1vZGVsLmdldFNoYXJlZFVzZXIodGhpcy5wcm9wcy5saW5rRGF0YVsnaW50ZXJuYWxfdXNlcl9pZCddKVxuICAgICAgICB9O1xuICAgIH0sXG5cbiAgICBjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzOiBmdW5jdGlvbiBjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzKG5ld1Byb3BzLCBvbGRQcm9wcykge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIGludGVybmFsVXNlcjogbmV3UHJvcHMuc2hhcmVNb2RlbC5nZXRTaGFyZWRVc2VyKG5ld1Byb3BzLmxpbmtEYXRhWydpbnRlcm5hbF91c2VyX2lkJ10pXG4gICAgICAgIH0pO1xuICAgIH0sXG5cbiAgICBnZXRTdGF0dXM6IGZ1bmN0aW9uIGdldFN0YXR1cygpIHtcbiAgICAgICAgdmFyIGxpbmsgPSB0aGlzLnByb3BzLmxpbmtEYXRhO1xuICAgICAgICBpZiAoIWxpbmsuaW52aXRhdGlvbikgcmV0dXJuIC0xO2Vsc2UgcmV0dXJuIGxpbmsuaW52aXRhdGlvbi5TVEFUVVM7XG4gICAgfSxcblxuICAgIGdldFN0YXR1c1N0cmluZzogZnVuY3Rpb24gZ2V0U3RhdHVzU3RyaW5nKCkge1xuICAgICAgICB2YXIgc3RhdHVzZXMgPSB7ICdzLTEnOiAyMTQsICdzMSc6IDIxMSwgJ3MyJzogMjEyLCAnczQnOiAyMTMgfTtcbiAgICAgICAgcmV0dXJuIHRoaXMucHJvcHMuZ2V0TWVzc2FnZShzdGF0dXNlc1sncycgKyB0aGlzLmdldFN0YXR1cygpXSk7XG4gICAgfSxcblxuICAgIGJ1aWxkTGFiZWw6IGZ1bmN0aW9uIGJ1aWxkTGFiZWwoKSB7XG4gICAgICAgIHZhciBsaW5rID0gdGhpcy5wcm9wcy5saW5rRGF0YTtcbiAgICAgICAgdmFyIGhvc3QgPSBsaW5rLkhPU1QgfHwgKGxpbmsuaW52aXRhdGlvbiA/IGxpbmsuaW52aXRhdGlvbi5IT1NUIDogbnVsbCk7XG4gICAgICAgIHZhciB1c2VyID0gbGluay5VU0VSIHx8IChsaW5rLmludml0YXRpb24gPyBsaW5rLmludml0YXRpb24uVVNFUiA6IG51bGwpO1xuICAgICAgICBpZiAoIWhvc3QgfHwgIXVzZXIpIHJldHVybiBcIkVycm9yXCI7XG4gICAgICAgIHJldHVybiB1c2VyICsgXCIgQCBcIiArIGhvc3Q7XG4gICAgfSxcblxuICAgIHJlbW92ZVVzZXI6IGZ1bmN0aW9uIHJlbW92ZVVzZXIoKSB7XG4gICAgICAgIHRoaXMucHJvcHMub25SZW1vdmVVc2VyKHRoaXMucHJvcHMubGlua0RhdGFbJ2hhc2gnXSk7XG4gICAgfSxcblxuICAgIG9uVXBkYXRlUmlnaHQ6IGZ1bmN0aW9uIG9uVXBkYXRlUmlnaHQoZXZlbnQpIHtcbiAgICAgICAgdmFyIHRhcmdldCA9IGV2ZW50LnRhcmdldDtcbiAgICAgICAgdGhpcy5wcm9wcy5vblVzZXJVcGRhdGUoJ3VwZGF0ZV9yaWdodCcsIHRoaXMuc3RhdGUuaW50ZXJuYWxVc2VyLklELCB7IHJpZ2h0OiB0YXJnZXQubmFtZSwgYWRkOiB0YXJnZXQuY2hlY2tlZCB9KTtcbiAgICB9LFxuXG4gICAgcmVuZGVyOiBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgICAgIHZhciBtZW51SXRlbXMgPSBbXTtcbiAgICAgICAgaWYgKCF0aGlzLnByb3BzLmlzUmVhZG9ubHkoKSkge1xuICAgICAgICAgICAgbWVudUl0ZW1zID0gW3tcbiAgICAgICAgICAgICAgICB0ZXh0OiB0aGlzLnByb3BzLmdldE1lc3NhZ2UoJzI1NycsICcnKSxcbiAgICAgICAgICAgICAgICBjYWxsYmFjazogdGhpcy5yZW1vdmVVc2VyXG4gICAgICAgICAgICB9XTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgc3RhdHVzID0gdGhpcy5nZXRTdGF0dXMoKTtcbiAgICAgICAgdmFyIGFkZGl0aW9uYWxJdGVtO1xuICAgICAgICBpZiAoc3RhdHVzID09IDIpIHtcbiAgICAgICAgICAgIGFkZGl0aW9uYWxJdGVtID0gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAnc3BhbicsXG4gICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6ICd1c2VyLWJhZGdlLXJpZ2h0cy1jb250YWluZXInIH0sXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudCgnaW5wdXQnLCB7IHR5cGU6ICdjaGVja2JveCcsIG5hbWU6ICdyZWFkJywgZGlzYWJsZWQ6IHRoaXMucHJvcHMuaXNSZWFkb25seSgpLCBjaGVja2VkOiB0aGlzLnN0YXRlLmludGVybmFsVXNlci5SSUdIVC5pbmRleE9mKCdyJykgIT09IC0xLCBvbkNoYW5nZTogdGhpcy5vblVwZGF0ZVJpZ2h0IH0pLFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoJ2lucHV0JywgeyB0eXBlOiAnY2hlY2tib3gnLCBuYW1lOiAnd3JpdGUnLCBkaXNhYmxlZDogdGhpcy5wcm9wcy5pc1JlYWRvbmx5KCksIGNoZWNrZWQ6IHRoaXMuc3RhdGUuaW50ZXJuYWxVc2VyLlJJR0hULmluZGV4T2YoJ3cnKSAhPT0gLTEsIG9uQ2hhbmdlOiB0aGlzLm9uVXBkYXRlUmlnaHQgfSlcbiAgICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhZGRpdGlvbmFsSXRlbSA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgJ3NwYW4nLFxuICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAndXNlci1iYWRnZS1yaWdodHMtY29udGFpbmVyJyB9LFxuICAgICAgICAgICAgICAgIHRoaXMuZ2V0U3RhdHVzU3RyaW5nKClcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgIF9Vc2VyQmFkZ2UyWydkZWZhdWx0J10sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgbGFiZWw6IHRoaXMuYnVpbGRMYWJlbCgpLFxuICAgICAgICAgICAgICAgIGF2YXRhcjogbnVsbCxcbiAgICAgICAgICAgICAgICB0eXBlOiBcInJlbW90ZV91c2VyXCIsXG4gICAgICAgICAgICAgICAgbWVudXM6IG1lbnVJdGVtc1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGFkZGl0aW9uYWxJdGVtXG4gICAgICAgICk7XG4gICAgfVxuXG59KTtcblxuZXhwb3J0c1snZGVmYXVsdCddID0gUmVtb3RlVXNlckVudHJ5ID0gKDAsIF9TaGFyZUNvbnRleHRDb25zdW1lcjJbJ2RlZmF1bHQnXSkoUmVtb3RlVXNlckVudHJ5KTtcbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IFJlbW90ZVVzZXJFbnRyeTtcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ19fZXNNb2R1bGUnLCB7XG4gICAgdmFsdWU6IHRydWVcbn0pO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyAnZGVmYXVsdCc6IG9iaiB9OyB9XG5cbnZhciBfU2hhcmVDb250ZXh0Q29uc3VtZXIgPSByZXF1aXJlKCcuLi9TaGFyZUNvbnRleHRDb25zdW1lcicpO1xuXG52YXIgX1NoYXJlQ29udGV4dENvbnN1bWVyMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1NoYXJlQ29udGV4dENvbnN1bWVyKTtcblxudmFyIF9SZW1vdGVVc2VyRW50cnkgPSByZXF1aXJlKCcuL1JlbW90ZVVzZXJFbnRyeScpO1xuXG52YXIgX1JlbW90ZVVzZXJFbnRyeTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9SZW1vdGVVc2VyRW50cnkpO1xuXG52YXIgX21haW5DYXJkID0gcmVxdWlyZSgnLi4vbWFpbi9DYXJkJyk7XG5cbnZhciBfbWFpbkNhcmQyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfbWFpbkNhcmQpO1xuXG52YXIgX21haW5BY3Rpb25CdXR0b24gPSByZXF1aXJlKCcuLi9tYWluL0FjdGlvbkJ1dHRvbicpO1xuXG52YXIgX21haW5BY3Rpb25CdXR0b24yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfbWFpbkFjdGlvbkJ1dHRvbik7XG5cbnZhciBSZWFjdCA9IHJlcXVpcmUoJ3JlYWN0Jyk7XG5cbnZhciBfcmVxdWlyZSA9IHJlcXVpcmUoJ21hdGVyaWFsLXVpJyk7XG5cbnZhciBUZXh0RmllbGQgPSBfcmVxdWlyZS5UZXh0RmllbGQ7XG52YXIgSWNvbkJ1dHRvbiA9IF9yZXF1aXJlLkljb25CdXR0b247XG52YXIgUGFwZXIgPSBfcmVxdWlyZS5QYXBlcjtcblxudmFyIFB5ZGlvID0gcmVxdWlyZSgncHlkaW8nKTtcblxudmFyIF9QeWRpbyRyZXF1aXJlTGliID0gUHlkaW8ucmVxdWlyZUxpYignUmVhY3RNb2RlbFNoYXJlJyk7XG5cbnZhciBSZWFjdE1vZGVsU2hhcmUgPSBfUHlkaW8kcmVxdWlyZUxpYi5SZWFjdE1vZGVsU2hhcmU7XG5cbnZhciBfUHlkaW8kcmVxdWlyZUxpYjIgPSBQeWRpby5yZXF1aXJlTGliKCdjb21wb25lbnRzJyk7XG5cbnZhciBBZGRyZXNzQm9vayA9IF9QeWRpbyRyZXF1aXJlTGliMi5BZGRyZXNzQm9vaztcblxudmFyIFJlbW90ZVVzZXJzID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuICAgIGRpc3BsYXlOYW1lOiAnUmVtb3RlVXNlcnMnLFxuXG4gICAgcHJvcFR5cGVzOiB7XG4gICAgICAgIHNoYXJlTW9kZWw6IFJlYWN0LlByb3BUeXBlcy5pbnN0YW5jZU9mKFJlYWN0TW9kZWxTaGFyZSksXG4gICAgICAgIG9uVXNlclVwZGF0ZTogUmVhY3QuUHJvcFR5cGVzLmZ1bmMuaXNSZXF1aXJlZCxcbiAgICAgICAgcHlkaW86IFJlYWN0LlByb3BUeXBlcy5pbnN0YW5jZU9mKFB5ZGlvKVxuICAgIH0sXG5cbiAgICBnZXRJbml0aWFsU3RhdGU6IGZ1bmN0aW9uIGdldEluaXRpYWxTdGF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHsgYWRkRGlzYWJsZWQ6IHRydWUsIHNob3dVc2VyRm9ybTogZmFsc2UgfTtcbiAgICB9LFxuXG4gICAgYWRkVXNlcjogZnVuY3Rpb24gYWRkVXNlcigpIHtcbiAgICAgICAgdmFyIGggPSB0aGlzLnJlZnNbXCJob3N0XCJdLmdldFZhbHVlKCk7XG4gICAgICAgIHZhciB1ID0gdGhpcy5yZWZzW1widXNlclwiXS5nZXRWYWx1ZSgpO1xuICAgICAgICB0aGlzLnByb3BzLnNoYXJlTW9kZWwuY3JlYXRlUmVtb3RlTGluayhoLCB1KTtcbiAgICB9LFxuXG4gICAgcmVtb3ZlVXNlcjogZnVuY3Rpb24gcmVtb3ZlVXNlcihsaW5rSWQpIHtcbiAgICAgICAgdGhpcy5wcm9wcy5zaGFyZU1vZGVsLnJlbW92ZVJlbW90ZUxpbmsobGlua0lkKTtcbiAgICB9LFxuXG4gICAgbW9uaXRvcklucHV0OiBmdW5jdGlvbiBtb25pdG9ySW5wdXQoKSB7XG4gICAgICAgIHZhciBoID0gdGhpcy5yZWZzW1wiaG9zdFwiXS5nZXRWYWx1ZSgpO1xuICAgICAgICB2YXIgdSA9IHRoaXMucmVmc1tcInVzZXJcIl0uZ2V0VmFsdWUoKTtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGFkZERpc2FibGVkOiAhKGggJiYgdSkgfSk7XG4gICAgfSxcblxuICAgIG9uQWRkcmVzc0Jvb2tJdGVtU2VsZWN0ZWQ6IGZ1bmN0aW9uIG9uQWRkcmVzc0Jvb2tJdGVtU2VsZWN0ZWQodU9iamVjdCwgcGFyZW50KSB7XG4gICAgICAgIHZhciB0cnVzdGVkU2VydmVySWQgPSB1T2JqZWN0LnRydXN0ZWRTZXJ2ZXJJZDtcblxuICAgICAgICB2YXIgdXNlcklkID0gdU9iamVjdC5nZXRJZCgpO1xuICAgICAgICB0aGlzLnByb3BzLnNoYXJlTW9kZWwuY3JlYXRlUmVtb3RlTGluaygndHJ1c3RlZDovLycgKyB0cnVzdGVkU2VydmVySWQsIHVzZXJJZCk7XG4gICAgfSxcblxuICAgIGdldEFjdGlvbnM6IGZ1bmN0aW9uIGdldEFjdGlvbnMoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICAgICAgdmFyIG9jc1JlbW90ZXMgPSB0aGlzLnByb3BzLnB5ZGlvLmdldFBsdWdpbkNvbmZpZ3MoJ2NvcmUub2NzJykuZ2V0KCdUUlVTVEVEX1NFUlZFUlMnKTtcbiAgICAgICAgdmFyIGhhc1RydXN0ZWQgPSBvY3NSZW1vdGVzICYmIG9jc1JlbW90ZXMubGVuZ3RoO1xuXG4gICAgICAgIHJldHVybiBbUmVhY3QuY3JlYXRlRWxlbWVudChfbWFpbkFjdGlvbkJ1dHRvbjJbJ2RlZmF1bHQnXSwgeyBrZXk6ICdtYW51YWwnLCBtZGlJY29uOiAnYWNjb3VudC1wbHVzJywgbWVzc2FnZUlkOiAnNDUnLCBvblRvdWNoVGFwOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgX3RoaXMuc2V0U3RhdGUoeyBzaG93VXNlckZvcm06IHRydWUgfSk7XG4gICAgICAgICAgICB9IH0pLCBSZWFjdC5jcmVhdGVFbGVtZW50KEFkZHJlc3NCb29rLCB7XG4gICAgICAgICAgICBrZXk6ICdhZGRyZXNzYm9vaycsXG4gICAgICAgICAgICBtb2RlOiAncG9wb3ZlcicsXG4gICAgICAgICAgICBweWRpbzogdGhpcy5wcm9wcy5weWRpbyxcbiAgICAgICAgICAgIG9uSXRlbVNlbGVjdGVkOiB0aGlzLm9uQWRkcmVzc0Jvb2tJdGVtU2VsZWN0ZWQsXG4gICAgICAgICAgICB1c2Vyc0Zyb206ICdyZW1vdGUnLFxuICAgICAgICAgICAgZGlzYWJsZVNlYXJjaDogdHJ1ZSxcbiAgICAgICAgICAgIHBvcG92ZXJCdXR0b246IFJlYWN0LmNyZWF0ZUVsZW1lbnQoX21haW5BY3Rpb25CdXR0b24yWydkZWZhdWx0J10sIHsgbWRpSWNvbjogJ3NlcnZlci1uZXR3b3JrJywgbWVzc2FnZUlkOiAnNDUnIH0pXG4gICAgICAgIH0pXTtcbiAgICB9LFxuXG4gICAgcmVuZGVyVXNlckZvcm06IGZ1bmN0aW9uIHJlbmRlclVzZXJGb3JtKCkge1xuICAgICAgICB2YXIgX3RoaXMyID0gdGhpcztcblxuICAgICAgICBpZiAodGhpcy5wcm9wcy5pc1JlYWRvbmx5KCkpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgUGFwZXIsXG4gICAgICAgICAgICB7IHpEZXB0aDogMCwgc3R5bGU6IHsgcGFkZGluZzogJzAgMTZweCcsIGJhY2tncm91bmRDb2xvcjogJyNGQUZBRkEnLCBtYXJnaW5Ub3A6IDEwIH0gfSxcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFRleHRGaWVsZCwgeyBmdWxsV2lkdGg6IHRydWUsIHJlZjogJ2hvc3QnLCBmbG9hdGluZ0xhYmVsVGV4dDogdGhpcy5wcm9wcy5nZXRNZXNzYWdlKCcyMDknKSwgb25DaGFuZ2U6IHRoaXMubW9uaXRvcklucHV0IH0pLFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoVGV4dEZpZWxkLCB7IGZ1bGxXaWR0aDogdHJ1ZSwgcmVmOiAndXNlcicsIHR5cGU6ICd0ZXh0JywgZmxvYXRpbmdMYWJlbFRleHQ6IHRoaXMucHJvcHMuZ2V0TWVzc2FnZSgnMjEwJyksIG9uQ2hhbmdlOiB0aGlzLm1vbml0b3JJbnB1dCB9KVxuICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgeyBzdHlsZTogeyB0ZXh0QWxpZ246ICdyaWdodCcgfSB9LFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoSWNvbkJ1dHRvbiwgeyB0b29sdGlwOiAnQ2FuY2VsJywgaWNvbkNsYXNzTmFtZTogJ21kaSBtZGktdW5kbycsIG9uQ2xpY2s6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzMi5zZXRTdGF0ZSh7IHNob3dVc2VyRm9ybTogZmFsc2UgfSk7XG4gICAgICAgICAgICAgICAgICAgIH0gfSksXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChJY29uQnV0dG9uLCB7IHRvb2x0aXA6IHRoaXMucHJvcHMuZ2V0TWVzc2FnZSgnNDUnKSwgaWNvbkNsYXNzTmFtZTogJ2ljb24tcGx1cy1zaWduJywgb25DbGljazogdGhpcy5hZGRVc2VyLCBkaXNhYmxlZDogdGhpcy5zdGF0ZS5hZGREaXNhYmxlZCB9KVxuICAgICAgICAgICAgKVxuICAgICAgICApO1xuICAgIH0sXG5cbiAgICByZW5kZXI6IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgICAgdmFyIG9jc0xpbmtzID0gdGhpcy5wcm9wcy5zaGFyZU1vZGVsLmdldE9jc0xpbmtzQnlTdGF0dXMoKSxcbiAgICAgICAgICAgIGludixcbiAgICAgICAgICAgIHJ3SGVhZGVyLFxuICAgICAgICAgICAgaGFzQWN0aXZlT2NzTGluayA9IGZhbHNlO1xuXG4gICAgICAgIGludiA9IG9jc0xpbmtzLm1hcCgoZnVuY3Rpb24gKGxpbmspIHtcbiAgICAgICAgICAgIGhhc0FjdGl2ZU9jc0xpbmsgPSAhaGFzQWN0aXZlT2NzTGluayAmJiBsaW5rICYmIGxpbmsuaW52aXRhdGlvbiAmJiBsaW5rLmludml0YXRpb24uU1RBVFVTID09IDIgPyB0cnVlIDogaGFzQWN0aXZlT2NzTGluaztcblxuICAgICAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoX1JlbW90ZVVzZXJFbnRyeTJbJ2RlZmF1bHQnXSwge1xuICAgICAgICAgICAgICAgIHNoYXJlTW9kZWw6IHRoaXMucHJvcHMuc2hhcmVNb2RlbCxcbiAgICAgICAgICAgICAgICBsaW5rRGF0YTogbGluayxcbiAgICAgICAgICAgICAgICBvblJlbW92ZVVzZXI6IHRoaXMucmVtb3ZlVXNlcixcbiAgICAgICAgICAgICAgICBvblVzZXJVcGRhdGU6IHRoaXMucHJvcHMub25Vc2VyVXBkYXRlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSkuYmluZCh0aGlzKSk7XG5cbiAgICAgICAgaWYgKGhhc0FjdGl2ZU9jc0xpbmspIHtcbiAgICAgICAgICAgIHJ3SGVhZGVyID0gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ3NoYXJlZC11c2Vycy1yaWdodHMtaGVhZGVyJyB9LFxuICAgICAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICAgICAgJ3NwYW4nLFxuICAgICAgICAgICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6ICdyZWFkJyB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5nZXRNZXNzYWdlKCczNjEnLCAnJylcbiAgICAgICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgICAgICAgICdzcGFuJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAncmVhZCcgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucHJvcHMuZ2V0TWVzc2FnZSgnMTgxJylcbiAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgIF9tYWluQ2FyZDJbJ2RlZmF1bHQnXSxcbiAgICAgICAgICAgIHsgdGl0bGU6IHRoaXMucHJvcHMuZ2V0TWVzc2FnZSgnMjA3JyksIGFjdGlvbnM6IHRoaXMuZ2V0QWN0aW9ucygpIH0sXG4gICAgICAgICAgICAhb2NzTGlua3MubGVuZ3RoICYmIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgeyBzdHlsZTogeyBjb2xvcjogJ3JnYmEoMCwwLDAsMC40MyknLCBwYWRkaW5nQm90dG9tOiAxNiB9IH0sXG4gICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5nZXRNZXNzYWdlKCcyMDgnKVxuICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgICAgICByd0hlYWRlcixcbiAgICAgICAgICAgICAgICBpbnZcbiAgICAgICAgICAgICksXG4gICAgICAgICAgICB0aGlzLnN0YXRlLnNob3dVc2VyRm9ybSAmJiB0aGlzLnJlbmRlclVzZXJGb3JtKClcbiAgICAgICAgKTtcbiAgICB9XG59KTtcblxuZXhwb3J0c1snZGVmYXVsdCddID0gUmVtb3RlVXNlcnMgPSAoMCwgX1NoYXJlQ29udGV4dENvbnN1bWVyMlsnZGVmYXVsdCddKShSZW1vdGVVc2Vycyk7XG5leHBvcnRzWydkZWZhdWx0J10gPSBSZW1vdGVVc2Vycztcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ19fZXNNb2R1bGUnLCB7XG4gICAgdmFsdWU6IHRydWVcbn0pO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyAnZGVmYXVsdCc6IG9iaiB9OyB9XG5cbnZhciBfVXNlckJhZGdlID0gcmVxdWlyZSgnLi9Vc2VyQmFkZ2UnKTtcblxudmFyIF9Vc2VyQmFkZ2UyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfVXNlckJhZGdlKTtcblxudmFyIF9TaGFyZUNvbnRleHRDb25zdW1lciA9IHJlcXVpcmUoJy4uL1NoYXJlQ29udGV4dENvbnN1bWVyJyk7XG5cbnZhciBfU2hhcmVDb250ZXh0Q29uc3VtZXIyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfU2hhcmVDb250ZXh0Q29uc3VtZXIpO1xuXG52YXIgUmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpO1xuXG52YXIgU2hhcmVkVXNlckVudHJ5ID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuICAgIGRpc3BsYXlOYW1lOiAnU2hhcmVkVXNlckVudHJ5JyxcblxuICAgIHByb3BUeXBlczoge1xuICAgICAgICB1c2VyRW50cnk6IFJlYWN0LlByb3BUeXBlcy5vYmplY3QuaXNSZXF1aXJlZCxcbiAgICAgICAgdXNlck9iamVjdDogUmVhY3QuUHJvcFR5cGVzLmluc3RhbmNlT2YoUHlkaW9Vc2Vycy5Vc2VyKS5pc1JlcXVpcmVkLFxuICAgICAgICBvblVzZXJVcGRhdGU6IFJlYWN0LlByb3BUeXBlcy5mdW5jLmlzUmVxdWlyZWQsXG4gICAgICAgIHNlbmRJbnZpdGF0aW9uczogUmVhY3QuUHJvcFR5cGVzLmZ1bmNcbiAgICB9LFxuICAgIG9uUmVtb3ZlOiBmdW5jdGlvbiBvblJlbW92ZSgpIHtcbiAgICAgICAgdGhpcy5wcm9wcy5vblVzZXJVcGRhdGUoJ3JlbW92ZScsIHRoaXMucHJvcHMudXNlckVudHJ5LklELCB0aGlzLnByb3BzLnVzZXJFbnRyeSk7XG4gICAgfSxcbiAgICBvblRvZ2dsZVdhdGNoOiBmdW5jdGlvbiBvblRvZ2dsZVdhdGNoKCkge1xuICAgICAgICB0aGlzLnByb3BzLm9uVXNlclVwZGF0ZSgndXBkYXRlX3JpZ2h0JywgdGhpcy5wcm9wcy51c2VyRW50cnkuSUQsIHsgcmlnaHQ6ICd3YXRjaCcsIGFkZDogIXRoaXMucHJvcHMudXNlckVudHJ5WydXQVRDSCddIH0pO1xuICAgIH0sXG4gICAgb25JbnZpdGU6IGZ1bmN0aW9uIG9uSW52aXRlKCkge1xuICAgICAgICB2YXIgdGFyZ2V0cyA9IHt9O1xuICAgICAgICB0YXJnZXRzW3RoaXMucHJvcHMudXNlck9iamVjdC5nZXRJZCgpXSA9IHRoaXMucHJvcHMudXNlck9iamVjdDtcbiAgICAgICAgdGhpcy5wcm9wcy5zZW5kSW52aXRhdGlvbnModGFyZ2V0cyk7XG4gICAgfSxcbiAgICBvblVwZGF0ZVJpZ2h0OiBmdW5jdGlvbiBvblVwZGF0ZVJpZ2h0KGV2ZW50KSB7XG4gICAgICAgIHZhciB0YXJnZXQgPSBldmVudC50YXJnZXQ7XG4gICAgICAgIHRoaXMucHJvcHMub25Vc2VyVXBkYXRlKCd1cGRhdGVfcmlnaHQnLCB0aGlzLnByb3BzLnVzZXJFbnRyeS5JRCwgeyByaWdodDogdGFyZ2V0Lm5hbWUsIGFkZDogdGFyZ2V0LmNoZWNrZWQgfSk7XG4gICAgfSxcbiAgICByZW5kZXI6IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgICAgdmFyIG1lbnVJdGVtcyA9IFtdO1xuICAgICAgICBpZiAodGhpcy5wcm9wcy51c2VyRW50cnkuVFlQRSAhPSAnZ3JvdXAnKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMucHJvcHMuaXNSZWFkb25seSgpKSB7XG4gICAgICAgICAgICAgICAgLy8gVG9nZ2xlIE5vdGlmXG4gICAgICAgICAgICAgICAgbWVudUl0ZW1zLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICB0ZXh0OiB0aGlzLnByb3BzLmdldE1lc3NhZ2UoJzE4MycpLFxuICAgICAgICAgICAgICAgICAgICBjYWxsYmFjazogdGhpcy5vblRvZ2dsZVdhdGNoLFxuICAgICAgICAgICAgICAgICAgICBjaGVja2VkOiB0aGlzLnByb3BzLnVzZXJFbnRyeS5XQVRDSFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMucHJvcHMuc2VuZEludml0YXRpb25zKSB7XG4gICAgICAgICAgICAgICAgLy8gU2VuZCBpbnZpdGF0aW9uXG4gICAgICAgICAgICAgICAgbWVudUl0ZW1zLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICB0ZXh0OiB0aGlzLnByb3BzLmdldE1lc3NhZ2UoJzQ1JyksXG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrOiB0aGlzLm9uSW52aXRlXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF0aGlzLnByb3BzLmlzUmVhZG9ubHkoKSkge1xuICAgICAgICAgICAgLy8gUmVtb3ZlIEVudHJ5XG4gICAgICAgICAgICBtZW51SXRlbXMucHVzaCh7XG4gICAgICAgICAgICAgICAgdGV4dDogdGhpcy5wcm9wcy5nZXRNZXNzYWdlKCcyNTcnLCAnJyksXG4gICAgICAgICAgICAgICAgY2FsbGJhY2s6IHRoaXMub25SZW1vdmVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgX1VzZXJCYWRnZTJbJ2RlZmF1bHQnXSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBsYWJlbDogdGhpcy5wcm9wcy51c2VyRW50cnkuTEFCRUwgfHwgdGhpcy5wcm9wcy51c2VyRW50cnkuSUQsXG4gICAgICAgICAgICAgICAgYXZhdGFyOiB0aGlzLnByb3BzLnVzZXJFbnRyeS5BVkFUQVIsXG4gICAgICAgICAgICAgICAgdHlwZTogdGhpcy5wcm9wcy51c2VyRW50cnkuVFlQRSxcbiAgICAgICAgICAgICAgICBtZW51czogbWVudUl0ZW1zXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAnc3BhbicsXG4gICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6ICd1c2VyLWJhZGdlLXJpZ2h0cy1jb250YWluZXInLCBzdHlsZTogIW1lbnVJdGVtcy5sZW5ndGggPyB7IG1hcmdpblJpZ2h0OiA0OCB9IDoge30gfSxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KCdpbnB1dCcsIHsgdHlwZTogJ2NoZWNrYm94JywgbmFtZTogJ3JlYWQnLCBkaXNhYmxlZDogdGhpcy5wcm9wcy5pc1JlYWRvbmx5KCksIGNoZWNrZWQ6IHRoaXMucHJvcHMudXNlckVudHJ5LlJJR0hULmluZGV4T2YoJ3InKSAhPT0gLTEsIG9uQ2hhbmdlOiB0aGlzLm9uVXBkYXRlUmlnaHQgfSksXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudCgnaW5wdXQnLCB7IHR5cGU6ICdjaGVja2JveCcsIG5hbWU6ICd3cml0ZScsIGRpc2FibGVkOiB0aGlzLnByb3BzLmlzUmVhZG9ubHkoKSwgY2hlY2tlZDogdGhpcy5wcm9wcy51c2VyRW50cnkuUklHSFQuaW5kZXhPZigndycpICE9PSAtMSwgb25DaGFuZ2U6IHRoaXMub25VcGRhdGVSaWdodCB9KVxuICAgICAgICAgICAgKVxuICAgICAgICApO1xuICAgIH1cbn0pO1xuXG5leHBvcnRzWydkZWZhdWx0J10gPSBTaGFyZWRVc2VyRW50cnkgPSAoMCwgX1NoYXJlQ29udGV4dENvbnN1bWVyMlsnZGVmYXVsdCddKShTaGFyZWRVc2VyRW50cnkpO1xuZXhwb3J0c1snZGVmYXVsdCddID0gU2hhcmVkVXNlckVudHJ5O1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG4iLCIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnX19lc01vZHVsZScsIHtcbiAgICB2YWx1ZTogdHJ1ZVxufSk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7ICdkZWZhdWx0Jzogb2JqIH07IH1cblxudmFyIF9TaGFyZUNvbnRleHRDb25zdW1lciA9IHJlcXVpcmUoJy4uL1NoYXJlQ29udGV4dENvbnN1bWVyJyk7XG5cbnZhciBfU2hhcmVDb250ZXh0Q29uc3VtZXIyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfU2hhcmVDb250ZXh0Q29uc3VtZXIpO1xuXG52YXIgX1VzZXJCYWRnZSA9IHJlcXVpcmUoJy4vVXNlckJhZGdlJyk7XG5cbnZhciBfVXNlckJhZGdlMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1VzZXJCYWRnZSk7XG5cbnZhciBfU2hhcmVkVXNlckVudHJ5ID0gcmVxdWlyZSgnLi9TaGFyZWRVc2VyRW50cnknKTtcblxudmFyIF9TaGFyZWRVc2VyRW50cnkyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfU2hhcmVkVXNlckVudHJ5KTtcblxudmFyIF9tYWluQWN0aW9uQnV0dG9uID0gcmVxdWlyZSgnLi4vbWFpbi9BY3Rpb25CdXR0b24nKTtcblxudmFyIF9tYWluQWN0aW9uQnV0dG9uMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX21haW5BY3Rpb25CdXR0b24pO1xuXG52YXIgX21haW5DYXJkID0gcmVxdWlyZSgnLi4vbWFpbi9DYXJkJyk7XG5cbnZhciBfbWFpbkNhcmQyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfbWFpbkNhcmQpO1xuXG52YXIgUmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpO1xuXG52YXIgUHlkaW8gPSByZXF1aXJlKCdweWRpbycpO1xuXG52YXIgX1B5ZGlvJHJlcXVpcmVMaWIgPSBQeWRpby5yZXF1aXJlTGliKCdjb21wb25lbnRzJyk7XG5cbnZhciBVc2Vyc0NvbXBsZXRlciA9IF9QeWRpbyRyZXF1aXJlTGliLlVzZXJzQ29tcGxldGVyO1xuXG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKCdtYXRlcmlhbC11aScpO1xuXG52YXIgUGFwZXIgPSBfcmVxdWlyZS5QYXBlcjtcblxudmFyIFNoYXJlZFVzZXJzID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuICAgIGRpc3BsYXlOYW1lOiAnU2hhcmVkVXNlcnMnLFxuXG4gICAgcHJvcFR5cGVzOiB7XG4gICAgICAgIHB5ZGlvOiBSZWFjdC5Qcm9wVHlwZXMuaW5zdGFuY2VPZihQeWRpbyksXG4gICAgICAgIHVzZXJzOiBSZWFjdC5Qcm9wVHlwZXMuYXJyYXkuaXNSZXF1aXJlZCxcbiAgICAgICAgdXNlck9iamVjdHM6IFJlYWN0LlByb3BUeXBlcy5vYmplY3QuaXNSZXF1aXJlZCxcbiAgICAgICAgb25Vc2VyVXBkYXRlOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYy5pc1JlcXVpcmVkLFxuICAgICAgICBzYXZlU2VsZWN0aW9uQXNUZWFtOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgICAgICAgc2VuZEludml0YXRpb25zOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgICAgICAgc2hvd1RpdGxlOiBSZWFjdC5Qcm9wVHlwZXMuYm9vbFxuICAgIH0sXG4gICAgc2VuZEludml0YXRpb25Ub0FsbFVzZXJzOiBmdW5jdGlvbiBzZW5kSW52aXRhdGlvblRvQWxsVXNlcnMoKSB7XG4gICAgICAgIHRoaXMucHJvcHMuc2VuZEludml0YXRpb25zKHRoaXMucHJvcHMudXNlck9iamVjdHMpO1xuICAgIH0sXG4gICAgY2xlYXJBbGxVc2VyczogZnVuY3Rpb24gY2xlYXJBbGxVc2VycygpIHtcbiAgICAgICAgdGhpcy5wcm9wcy51c2Vycy5tYXAoKGZ1bmN0aW9uIChlbnRyeSkge1xuICAgICAgICAgICAgdGhpcy5wcm9wcy5vblVzZXJVcGRhdGUoJ3JlbW92ZScsIGVudHJ5LklELCBlbnRyeSk7XG4gICAgICAgIH0pLmJpbmQodGhpcykpO1xuICAgIH0sXG4gICAgdmFsdWVTZWxlY3RlZDogZnVuY3Rpb24gdmFsdWVTZWxlY3RlZCh1c2VyT2JqZWN0KSB7XG4gICAgICAgIHZhciBuZXdFbnRyeSA9IHtcbiAgICAgICAgICAgIElEOiB1c2VyT2JqZWN0LmdldElkKCksXG4gICAgICAgICAgICBSSUdIVDogJ3InLFxuICAgICAgICAgICAgTEFCRUw6IHVzZXJPYmplY3QuZ2V0TGFiZWwoKSxcbiAgICAgICAgICAgIFRZUEU6IHVzZXJPYmplY3QuZ2V0R3JvdXAoKSA/ICdncm91cCcgOiAndXNlcidcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5wcm9wcy5vblVzZXJVcGRhdGUoJ2FkZCcsIG5ld0VudHJ5LklELCBuZXdFbnRyeSk7XG4gICAgfSxcbiAgICBjb21wbGV0ZXJSZW5kZXJTdWdnZXN0aW9uOiBmdW5jdGlvbiBjb21wbGV0ZXJSZW5kZXJTdWdnZXN0aW9uKHVzZXJPYmplY3QpIHtcbiAgICAgICAgdmFyIHR5cGUgPSB1c2VyT2JqZWN0LmdldFR5cGUoKSA9PT0gJ3RlYW0nIHx8IHVzZXJPYmplY3QuZ2V0SWQoKS5pbmRleE9mKCcvQUpYUF9URUFNLycpID09PSAwID8gJ3RlYW0nIDogdXNlck9iamVjdC5nZXRHcm91cCgpID8gJ2dyb3VwJyA6IHVzZXJPYmplY3QuZ2V0VGVtcG9yYXJ5KCkgPyAndGVtcG9yYXJ5JyA6IHVzZXJPYmplY3QuZ2V0RXh0ZXJuYWwoKSA/ICd0bXBfdXNlcicgOiAndXNlcic7XG5cbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoX1VzZXJCYWRnZTJbJ2RlZmF1bHQnXSwge1xuICAgICAgICAgICAgbGFiZWw6IHVzZXJPYmplY3QuZ2V0RXh0ZW5kZWRMYWJlbCgpIHx8IHVzZXJPYmplY3QuZ2V0TGFiZWwoKSxcbiAgICAgICAgICAgIGF2YXRhcjogdXNlck9iamVjdC5nZXRBdmF0YXIoKSxcbiAgICAgICAgICAgIHR5cGU6IHR5cGVcbiAgICAgICAgfSk7XG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgICAvLyBzb3J0IGJ5IGdyb3VwL3VzZXIgdGhlbiBieSBJRDtcbiAgICAgICAgdmFyIHVzZXJFbnRyaWVzID0gdGhpcy5wcm9wcy51c2Vycy5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgICAgICAgICByZXR1cm4gYi5UWVBFID09PSAnZ3JvdXAnIHx8IGIuVFlQRSA9PT0gJ3RlYW0nID8gMSA6IGEuVFlQRSA9PT0gJ2dyb3VwJyB8fCBhLlRZUEUgPT09ICd0ZWFtJyA/IC0xIDogYS5JRCA+IGIuSUQgPyAxIDogYi5JRCA+IGEuSUQgPyAtMSA6IDA7XG4gICAgICAgIH0pLm1hcCgoZnVuY3Rpb24gKHUpIHtcbiAgICAgICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KF9TaGFyZWRVc2VyRW50cnkyWydkZWZhdWx0J10sIHtcbiAgICAgICAgICAgICAgICB1c2VyRW50cnk6IHUsXG4gICAgICAgICAgICAgICAgdXNlck9iamVjdDogdGhpcy5wcm9wcy51c2VyT2JqZWN0c1t1LklEXSxcbiAgICAgICAgICAgICAgICBrZXk6IHUuSUQsXG4gICAgICAgICAgICAgICAgc2hhcmVNb2RlbDogdGhpcy5wcm9wcy5zaGFyZU1vZGVsLFxuICAgICAgICAgICAgICAgIG9uVXNlclVwZGF0ZTogdGhpcy5wcm9wcy5vblVzZXJVcGRhdGUsXG4gICAgICAgICAgICAgICAgc2VuZEludml0YXRpb25zOiB0aGlzLnByb3BzLnNlbmRJbnZpdGF0aW9uc1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pLmJpbmQodGhpcykpO1xuICAgICAgICB2YXIgYWN0aW9uTGlua3MgPSBbXTtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMudXNlcnMubGVuZ3RoICYmICF0aGlzLnByb3BzLmlzUmVhZG9ubHkoKSkge1xuICAgICAgICAgICAgYWN0aW9uTGlua3MucHVzaChSZWFjdC5jcmVhdGVFbGVtZW50KF9tYWluQWN0aW9uQnV0dG9uMlsnZGVmYXVsdCddLCB7IGtleTogJ2NsZWFyJywgY2FsbGJhY2s6IHRoaXMuY2xlYXJBbGxVc2VycywgbWRpSWNvbjogJ2RlbGV0ZScsIG1lc3NhZ2VJZDogJzE4MCcgfSkpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnByb3BzLnNlbmRJbnZpdGF0aW9ucyAmJiB0aGlzLnByb3BzLnVzZXJzLmxlbmd0aCkge1xuICAgICAgICAgICAgYWN0aW9uTGlua3MucHVzaChSZWFjdC5jcmVhdGVFbGVtZW50KF9tYWluQWN0aW9uQnV0dG9uMlsnZGVmYXVsdCddLCB7IGtleTogJ2ludml0ZScsIGNhbGxiYWNrOiB0aGlzLnNlbmRJbnZpdGF0aW9uVG9BbGxVc2VycywgbWRpSWNvbjogJ2VtYWlsLW91dGxpbmUnLCBtZXNzYWdlSWQ6ICc0NScgfSkpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnByb3BzLnNhdmVTZWxlY3Rpb25Bc1RlYW0gJiYgdGhpcy5wcm9wcy51c2Vycy5sZW5ndGggPiAxICYmICF0aGlzLnByb3BzLmlzUmVhZG9ubHkoKSkge1xuICAgICAgICAgICAgYWN0aW9uTGlua3MucHVzaChSZWFjdC5jcmVhdGVFbGVtZW50KF9tYWluQWN0aW9uQnV0dG9uMlsnZGVmYXVsdCddLCB7IGtleTogJ3RlYW0nLCBjYWxsYmFjazogdGhpcy5wcm9wcy5zYXZlU2VsZWN0aW9uQXNUZWFtLCBtZGlJY29uOiAnYWNjb3VudC1tdWx0aXBsZS1wbHVzJywgbWVzc2FnZUlkOiAnNTA5JywgbWVzc2FnZUNvcmVOYW1lc3BhY2U6IHRydWUgfSkpO1xuICAgICAgICB9XG4gICAgICAgIHZhciByd0hlYWRlciA9IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIHVzZXJzSW5wdXQgPSB1bmRlZmluZWQ7XG4gICAgICAgIGlmICh0aGlzLnByb3BzLnVzZXJzLmxlbmd0aCkge1xuICAgICAgICAgICAgcndIZWFkZXIgPSBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAnc2hhcmVkLXVzZXJzLXJpZ2h0cy1oZWFkZXInIH0sXG4gICAgICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICAgICAnc3BhbicsXG4gICAgICAgICAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ3JlYWQnIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnByb3BzLmdldE1lc3NhZ2UoJzM2MScsICcnKVxuICAgICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICAgICAgJ3NwYW4nLFxuICAgICAgICAgICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6ICdyZWFkJyB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5nZXRNZXNzYWdlKCcxODEnKVxuICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXRoaXMucHJvcHMuaXNSZWFkb25seSgpKSB7XG4gICAgICAgICAgICB2YXIgZXhjbHVkZXMgPSB0aGlzLnByb3BzLnVzZXJzLm1hcChmdW5jdGlvbiAodSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB1LklEO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB1c2Vyc0lucHV0ID0gUmVhY3QuY3JlYXRlRWxlbWVudChVc2Vyc0NvbXBsZXRlciwge1xuICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogJ3NoYXJlLWZvcm0tdXNlcnMnLFxuICAgICAgICAgICAgICAgIGZpZWxkTGFiZWw6IHRoaXMucHJvcHMuZ2V0TWVzc2FnZSgnMzQnKSxcbiAgICAgICAgICAgICAgICByZW5kZXJTdWdnZXN0aW9uOiB0aGlzLmNvbXBsZXRlclJlbmRlclN1Z2dlc3Rpb24sXG4gICAgICAgICAgICAgICAgb25WYWx1ZVNlbGVjdGVkOiB0aGlzLnZhbHVlU2VsZWN0ZWQsXG4gICAgICAgICAgICAgICAgZXhjbHVkZXM6IGV4Y2x1ZGVzLFxuICAgICAgICAgICAgICAgIHB5ZGlvOiB0aGlzLnByb3BzLnB5ZGlvLFxuICAgICAgICAgICAgICAgIHNob3dBZGRyZXNzQm9vazogdHJ1ZSxcbiAgICAgICAgICAgICAgICB1c2Vyc0Zyb206ICdsb2NhbCdcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgX21haW5DYXJkMlsnZGVmYXVsdCddLFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHRpdGxlOiB0aGlzLnByb3BzLnNob3dUaXRsZSA/IHRoaXMucHJvcHMuZ2V0TWVzc2FnZSgnMjE3JykgOiBudWxsLFxuICAgICAgICAgICAgICAgIGFjdGlvbnM6IGFjdGlvbkxpbmtzXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICB7IHN0eWxlOiB1c2VyRW50cmllcy5sZW5ndGggPyB7IG1hcmdpbjogJy0yMHB4IDhweCAxNnB4JyB9IDogeyBtYXJnaW5Ub3A6IC0yMCB9IH0sXG4gICAgICAgICAgICAgICAgdXNlcnNJbnB1dFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIHJ3SGVhZGVyLFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgICAgIHVzZXJFbnRyaWVzXG4gICAgICAgICAgICApLFxuICAgICAgICAgICAgIXVzZXJFbnRyaWVzLmxlbmd0aCAmJiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgIHsgc3R5bGU6IHsgY29sb3I6ICdyZ2JhKDAsMCwwLDAuNDMpJyB9IH0sXG4gICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5nZXRNZXNzYWdlKCcxODInKVxuICAgICAgICAgICAgKVxuICAgICAgICApO1xuICAgIH1cbn0pO1xuXG5leHBvcnRzWydkZWZhdWx0J10gPSBTaGFyZWRVc2VycyA9ICgwLCBfU2hhcmVDb250ZXh0Q29uc3VtZXIyWydkZWZhdWx0J10pKFNoYXJlZFVzZXJzKTtcbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IFNoYXJlZFVzZXJzO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG4iLCIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnX19lc01vZHVsZScsIHtcbiAgICB2YWx1ZTogdHJ1ZVxufSk7XG5cbnZhciBfY3JlYXRlQ2xhc3MgPSAoZnVuY3Rpb24gKCkgeyBmdW5jdGlvbiBkZWZpbmVQcm9wZXJ0aWVzKHRhcmdldCwgcHJvcHMpIHsgZm9yICh2YXIgaSA9IDA7IGkgPCBwcm9wcy5sZW5ndGg7IGkrKykgeyB2YXIgZGVzY3JpcHRvciA9IHByb3BzW2ldOyBkZXNjcmlwdG9yLmVudW1lcmFibGUgPSBkZXNjcmlwdG9yLmVudW1lcmFibGUgfHwgZmFsc2U7IGRlc2NyaXB0b3IuY29uZmlndXJhYmxlID0gdHJ1ZTsgaWYgKCd2YWx1ZScgaW4gZGVzY3JpcHRvcikgZGVzY3JpcHRvci53cml0YWJsZSA9IHRydWU7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGRlc2NyaXB0b3Iua2V5LCBkZXNjcmlwdG9yKTsgfSB9IHJldHVybiBmdW5jdGlvbiAoQ29uc3RydWN0b3IsIHByb3RvUHJvcHMsIHN0YXRpY1Byb3BzKSB7IGlmIChwcm90b1Byb3BzKSBkZWZpbmVQcm9wZXJ0aWVzKENvbnN0cnVjdG9yLnByb3RvdHlwZSwgcHJvdG9Qcm9wcyk7IGlmIChzdGF0aWNQcm9wcykgZGVmaW5lUHJvcGVydGllcyhDb25zdHJ1Y3Rvciwgc3RhdGljUHJvcHMpOyByZXR1cm4gQ29uc3RydWN0b3I7IH07IH0pKCk7XG5cbnZhciBfZ2V0ID0gZnVuY3Rpb24gZ2V0KF94LCBfeDIsIF94MykgeyB2YXIgX2FnYWluID0gdHJ1ZTsgX2Z1bmN0aW9uOiB3aGlsZSAoX2FnYWluKSB7IHZhciBvYmplY3QgPSBfeCwgcHJvcGVydHkgPSBfeDIsIHJlY2VpdmVyID0gX3gzOyBfYWdhaW4gPSBmYWxzZTsgaWYgKG9iamVjdCA9PT0gbnVsbCkgb2JqZWN0ID0gRnVuY3Rpb24ucHJvdG90eXBlOyB2YXIgZGVzYyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Iob2JqZWN0LCBwcm9wZXJ0eSk7IGlmIChkZXNjID09PSB1bmRlZmluZWQpIHsgdmFyIHBhcmVudCA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihvYmplY3QpOyBpZiAocGFyZW50ID09PSBudWxsKSB7IHJldHVybiB1bmRlZmluZWQ7IH0gZWxzZSB7IF94ID0gcGFyZW50OyBfeDIgPSBwcm9wZXJ0eTsgX3gzID0gcmVjZWl2ZXI7IF9hZ2FpbiA9IHRydWU7IGRlc2MgPSBwYXJlbnQgPSB1bmRlZmluZWQ7IGNvbnRpbnVlIF9mdW5jdGlvbjsgfSB9IGVsc2UgaWYgKCd2YWx1ZScgaW4gZGVzYykgeyByZXR1cm4gZGVzYy52YWx1ZTsgfSBlbHNlIHsgdmFyIGdldHRlciA9IGRlc2MuZ2V0OyBpZiAoZ2V0dGVyID09PSB1bmRlZmluZWQpIHsgcmV0dXJuIHVuZGVmaW5lZDsgfSByZXR1cm4gZ2V0dGVyLmNhbGwocmVjZWl2ZXIpOyB9IH0gfTtcblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24nKTsgfSB9XG5cbmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09ICdmdW5jdGlvbicgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90ICcgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5zZXRQcm90b3R5cGVPZihzdWJDbGFzcywgc3VwZXJDbGFzcykgOiBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9XG5cbnZhciBfcmVxdWlyZSA9IHJlcXVpcmUoJ3JlYWN0Jyk7XG5cbnZhciBDb21wb25lbnQgPSBfcmVxdWlyZS5Db21wb25lbnQ7XG52YXIgUHJvcFR5cGVzID0gX3JlcXVpcmUuUHJvcFR5cGVzO1xuXG52YXIgX3JlcXVpcmUyID0gcmVxdWlyZSgnbWF0ZXJpYWwtdWknKTtcblxudmFyIE1lbnVJdGVtID0gX3JlcXVpcmUyLk1lbnVJdGVtO1xudmFyIEljb25NZW51ID0gX3JlcXVpcmUyLkljb25NZW51O1xudmFyIEljb25CdXR0b24gPSBfcmVxdWlyZTIuSWNvbkJ1dHRvbjtcblxudmFyIF9yZXF1aXJlMyA9IHJlcXVpcmUoJ21hdGVyaWFsLXVpL3N0eWxlcycpO1xuXG52YXIgbXVpVGhlbWVhYmxlID0gX3JlcXVpcmUzLm11aVRoZW1lYWJsZTtcblxudmFyIENvbG9yID0gcmVxdWlyZSgnY29sb3InKTtcblxudmFyIFVzZXJCYWRnZSA9IChmdW5jdGlvbiAoX0NvbXBvbmVudCkge1xuICAgIF9pbmhlcml0cyhVc2VyQmFkZ2UsIF9Db21wb25lbnQpO1xuXG4gICAgZnVuY3Rpb24gVXNlckJhZGdlKCkge1xuICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgVXNlckJhZGdlKTtcblxuICAgICAgICBfZ2V0KE9iamVjdC5nZXRQcm90b3R5cGVPZihVc2VyQmFkZ2UucHJvdG90eXBlKSwgJ2NvbnN0cnVjdG9yJywgdGhpcykuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG5cbiAgICBfY3JlYXRlQ2xhc3MoVXNlckJhZGdlLCBbe1xuICAgICAgICBrZXk6ICdyZW5kZXJNZW51JyxcbiAgICAgICAgdmFsdWU6IGZ1bmN0aW9uIHJlbmRlck1lbnUoKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMucHJvcHMubWVudXMgfHwgIXRoaXMucHJvcHMubWVudXMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgbWVudUl0ZW1zID0gdGhpcy5wcm9wcy5tZW51cy5tYXAoZnVuY3Rpb24gKG0pIHtcbiAgICAgICAgICAgICAgICB2YXIgcmlnaHRJY29uID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIGlmIChtLmNoZWNrZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmlnaHRJY29uID0gUmVhY3QuY3JlYXRlRWxlbWVudCgnc3BhbicsIHsgY2xhc3NOYW1lOiAnbWRpIG1kaS1jaGVjaycgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KE1lbnVJdGVtLCB7XG4gICAgICAgICAgICAgICAgICAgIHByaW1hcnlUZXh0OiBtLnRleHQsXG4gICAgICAgICAgICAgICAgICAgIG9uVG91Y2hUYXA6IG0uY2FsbGJhY2ssXG4gICAgICAgICAgICAgICAgICAgIHJpZ2h0SWNvbjogcmlnaHRJY29uIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB2YXIgaWNvblN0eWxlID0geyBmb250U2l6ZTogMTggfTtcbiAgICAgICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgIEljb25NZW51LFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgaWNvbkJ1dHRvbkVsZW1lbnQ6IFJlYWN0LmNyZWF0ZUVsZW1lbnQoSWNvbkJ1dHRvbiwgeyBzdHlsZTogeyBwYWRkaW5nOiAxNiB9LCBpY29uU3R5bGU6IGljb25TdHlsZSwgaWNvbkNsYXNzTmFtZTogJ2ljb24tZWxsaXBzaXMtdmVydGljYWwnIH0pLFxuICAgICAgICAgICAgICAgICAgICBhbmNob3JPcmlnaW46IHsgaG9yaXpvbnRhbDogJ3JpZ2h0JywgdmVydGljYWw6ICd0b3AnIH0sXG4gICAgICAgICAgICAgICAgICAgIHRhcmdldE9yaWdpbjogeyBob3Jpem9udGFsOiAncmlnaHQnLCB2ZXJ0aWNhbDogJ3RvcCcgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgbWVudUl0ZW1zXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgfSwge1xuICAgICAgICBrZXk6ICdyZW5kZXInLFxuICAgICAgICB2YWx1ZTogZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgICAgICAgdmFyIGF2YXRhciA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIHZhciBhdmF0YXJDb2xvciA9IHRoaXMucHJvcHMubXVpVGhlbWUucGFsZXR0ZS5hdmF0YXJzQ29sb3I7XG4gICAgICAgICAgICBpZiAodGhpcy5wcm9wcy50eXBlID09ICdncm91cCcpIHtcbiAgICAgICAgICAgICAgICBhdmF0YXJDb2xvciA9IENvbG9yKGF2YXRhckNvbG9yKS5kYXJrZW4oLjIpLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgYXZhdGFyID0gUmVhY3QuY3JlYXRlRWxlbWVudCgnc3BhbicsIHsgY2xhc3NOYW1lOiAnYXZhdGFyIG1kaSBtZGktYWNjb3VudC1tdWx0aXBsZScsIHN0eWxlOiB7IGJhY2tncm91bmRDb2xvcjogYXZhdGFyQ29sb3IgfSB9KTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5wcm9wcy50eXBlID09ICd0ZWFtJykge1xuICAgICAgICAgICAgICAgIGF2YXRhckNvbG9yID0gQ29sb3IoYXZhdGFyQ29sb3IpLmRhcmtlbiguMikudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICBhdmF0YXIgPSBSZWFjdC5jcmVhdGVFbGVtZW50KCdzcGFuJywgeyBjbGFzc05hbWU6ICdhdmF0YXIgbWRpIG1kaS1hY2NvdW50LW11bHRpcGxlLW91dGxpbmUnLCBzdHlsZTogeyBiYWNrZ3JvdW5kQ29sb3I6IGF2YXRhckNvbG9yIH0gfSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMucHJvcHMudHlwZSA9PSAndGVtcG9yYXJ5Jykge1xuICAgICAgICAgICAgICAgIGF2YXRhckNvbG9yID0gQ29sb3IoYXZhdGFyQ29sb3IpLmxpZ2h0ZW4oLjIpLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgYXZhdGFyID0gUmVhY3QuY3JlYXRlRWxlbWVudCgnc3BhbicsIHsgY2xhc3NOYW1lOiAnYXZhdGFyIG1kaSBtZGktYWNjb3VudC1wbHVzJywgc3R5bGU6IHsgYmFja2dyb3VuZENvbG9yOiBhdmF0YXJDb2xvciB9IH0pO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLnByb3BzLnR5cGUgPT0gJ3JlbW90ZV91c2VyJykge1xuICAgICAgICAgICAgICAgIGF2YXRhciA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nLCB7IGNsYXNzTmFtZTogJ2F2YXRhciBtZGkgbWRpLWFjY291bnQtbmV0d29yaycsIHN0eWxlOiB7IGJhY2tncm91bmRDb2xvcjogYXZhdGFyQ29sb3IgfSB9KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgYXZhdGFyID0gUmVhY3QuY3JlYXRlRWxlbWVudCgnc3BhbicsIHsgY2xhc3NOYW1lOiAnYXZhdGFyIG1kaSBtZGktYWNjb3VudCcsIHN0eWxlOiB7IGJhY2tncm91bmRDb2xvcjogYXZhdGFyQ29sb3IgfSB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBtZW51ID0gdGhpcy5yZW5kZXJNZW51KCk7XG4gICAgICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogXCJzaGFyZS1kaWFsb2cgdXNlci1iYWRnZSB1c2VyLXR5cGUtXCIgKyB0aGlzLnByb3BzLnR5cGUgfSxcbiAgICAgICAgICAgICAgICBhdmF0YXIsXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgICAgJ3NwYW4nLFxuICAgICAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ3VzZXItYmFkZ2UtbGFiZWwnIH0sXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucHJvcHMubGFiZWxcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgIHRoaXMucHJvcHMuY2hpbGRyZW4sXG4gICAgICAgICAgICAgICAgbWVudVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgIH1dKTtcblxuICAgIHJldHVybiBVc2VyQmFkZ2U7XG59KShDb21wb25lbnQpO1xuXG5Vc2VyQmFkZ2UucHJvcFR5cGVzID0ge1xuICAgIGxhYmVsOiBQcm9wVHlwZXMuc3RyaW5nLFxuICAgIGF2YXRhcjogUHJvcFR5cGVzLnN0cmluZyxcbiAgICB0eXBlOiBQcm9wVHlwZXMuc3RyaW5nLFxuICAgIG1lbnVzOiBQcm9wVHlwZXMub2JqZWN0LFxuICAgIG11aVRoZW1lOiBQcm9wVHlwZXMub2JqZWN0XG59O1xuXG5leHBvcnRzWydkZWZhdWx0J10gPSBVc2VyQmFkZ2UgPSBtdWlUaGVtZWFibGUoKShVc2VyQmFkZ2UpO1xuXG5leHBvcnRzWydkZWZhdWx0J10gPSBVc2VyQmFkZ2U7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTtcbiJdfQ==