(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.PydioComponents = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o child into a function."))}function a(){!d&&p&&(d=!0,console.error("With React 0.13, you need to wrap child into a function."))}function l(e){return e<0?0:e}function s(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:function(e){return e},n={};for(var o in e)e.hasOwnProperty(o)&&(n[o]=t(e[o]));return n}function u(e){var t=e.version;if("string"!=typeof t)return!0;var n=t.split("."),o=parseInt(n[0],10),r=parseInt(n[1],10);return 0===o&&13===r}Object.defineProperty(t,"__esModule",{value:!0}),t.findDOMNode=r,t.warnAboutFunctionChild=i,t.warnAboutElementChild=a,t.positiveOrZero=l,t.modifyObjValues=s,t.isReact13=u;var c=n(1),f=o(c),p=u(f.default),d=!1},function(e,t){function n(){throw new Error("setTimeout has not been defined")}function o(){throw new Error("clearTimeout has not been defined")}function r(e){if(c===setTimeout)return setTimeout(e,0);if((c===n||!c)&&setTimeout)return c=setTimeout,setTimeout(e,0);try{return c(e,0)}catch(t){try{return c.call(null,e,0)}catch(t){return c.call(this,e,0)}}}function i(e){if(f===clearTimeout)return clearTimeout(e);if((f===o||!f)&&clearTimeout)return f=clearTimeout,clearTimeout(e);try{return f(e)}catch(t){try{return f.call(null,e)}catch(t){return f.call(this,e)}}}function a(){y&&d&&(y=!1,d.length?h=d.concat(h):v=-1,h.length&&l())}function l(){if(!y){var e=r(a);y=!0;for(var t=h.length;t;){for(d=h,h=[];++v1)for(var n=1;nt.realHeight-t.containerHeight&&(e=t.realHeight-t.containerHeight),e<0&&(e=0),e}},{key:"normalizeLeftPosition",value:function(e,t){return e>t.realWidth-t.containerWidth?e=t.realWidth-t.containerWidth:e<0&&(e=0),e}},{key:"computeSizes",value:function(){var e=this.content.offsetHeight,t=this.wrapper.offsetHeight,n=this.content.offsetWidth,o=this.wrapper.offsetWidth;return{realHeight:e,containerHeight:t,realWidth:n,containerWidth:o}}},{key:"setSizesToState",value:function(){var e=this.computeSizes();e.realHeight===this.state.realHeight&&e.realWidth===this.state.realWidth||this.setStateFromEvent(this.getModifiedPositionsIfNeeded(e))}},{key:"scrollTop",value:function(){this.scrollYTo(0)}},{key:"scrollBottom",value:function(){this.scrollYTo(this.state.realHeight-this.state.containerHeight)}},{key:"scrollLeft",value:function(){this.scrollXTo(0)}},{key:"scrollRight",value:function(){this.scrollXTo(this.state.realWidth-this.state.containerWidth)}},{key:"scrollYTo",value:function(e){if(this.canScrollY()){var t=this.normalizeTopPosition(e,this.computeSizes());this.setStateFromEvent({topPosition:t},g.api)}}},{key:"scrollXTo",value:function(e){if(this.canScrollX()){var t=this.normalizeLeftPosition(e,this.computeSizes());this.setStateFromEvent({leftPosition:t},g.api)}}},{key:"canScrollY",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.state,t=e.realHeight>e.containerHeight;return t&&this.props.vertical}},{key:"canScrollX",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.state,t=e.realWidth>e.containerWidth;return t&&this.props.horizontal}},{key:"canScroll",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.state;return this.canScrollY(e)||this.canScrollX(e)}},{key:"getModifiedPositionsIfNeeded",value:function(e){var t=e.realHeight-e.containerHeight;this.state.topPosition>=t&&(e.topPosition=this.canScrollY(e)?(0,m.positiveOrZero)(t):0);var n=e.realWidth-e.containerWidth;return this.state.leftPosition>=n&&(e.leftPosition=this.canScrollX(e)?(0,m.positiveOrZero)(n):0),e}},{key:"focusContent",value:function(){this.content&&(0,m.findDOMNode)(this.content).focus()}}]),t}(f.default.Component);t.default=w,w.childContextTypes={scrollArea:d.default.object},w.propTypes={className:d.default.string,style:d.default.object,speed:d.default.number,contentClassName:d.default.string,contentStyle:d.default.object,vertical:d.default.bool,verticalContainerStyle:d.default.object,verticalScrollbarStyle:d.default.object,horizontal:d.default.bool,horizontalContainerStyle:d.default.object,horizontalScrollbarStyle:d.default.object,onScroll:d.default.func,contentWindow:d.default.any,ownerDocument:d.default.any,smoothScrolling:d.default.bool,minScrollSize:d.default.number,swapWheelAxes:d.default.bool,stopScrollPropagation:d.default.bool,focusableTabIndex:d.default.number},w.defaultProps={speed:1,vertical:!0,horizontal:!0,smoothScrolling:!1,swapWheelAxes:!1,contentWindow:"object"===("undefined"==typeof window?"undefined":l(window))?window:void 0,ownerDocument:"object"===("undefined"==typeof document?"undefined":l(document))?document:void 0,focusableTabIndex:1}},function(e,t,n){"use strict";function o(e){return e&&e.__esModule?e:{default:e}}function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function i(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function a(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(t,"__esModule",{value:!0});var l=Object.assign||function(e){for(var t=1;t10*k&&(o.accumulatedTime=0),0===o.accumulatedTime)return o.animationID=null,void o.startAnimationIfNecessary();var i=(o.accumulatedTime-Math.floor(o.accumulatedTime/k)*k)/k,a=Math.floor(o.accumulatedTime/k),l={},s={},u={},c={};for(var f in t)if(Object.prototype.hasOwnProperty.call(t,f)){var p=t[f];if("number"==typeof p)u[f]=p,c[f]=0,l[f]=p,s[f]=0;else{for(var h=o.state.lastIdealStyle[f],v=o.state.lastIdealVelocity[f],m=0;m10*O&&(o.accumulatedTime=0),0===o.accumulatedTime)return o.animationID=null,void o.startAnimationIfNecessary();for(var i=(o.accumulatedTime-Math.floor(o.accumulatedTime/O)*O)/O,l=Math.floor(o.accumulatedTime/O),s=[],u=[],c=[],f=[],p=0;p10*D&&(o.accumulatedTime=0),0===o.accumulatedTime)return o.animationID=null,void o.startAnimationIfNecessary();for(var u=(o.accumulatedTime-Math.floor(o.accumulatedTime/D)*D)/D,c=Math.floor(o.accumulatedTime/D),f=s(o.props.willEnter,o.props.willLeave,o.props.didLeave,o.state.mergedPropsStyles,n,o.state.currentStyles,o.state.currentVelocities,o.state.lastIdealStyles,o.state.lastIdealVelocities),p=f[0],d=f[1],h=f[2],y=f[3],m=f[4],b=0;bo[c])return-1;if(r>i[c]&&so[c])return 1;if(a>i[c]&&l=0&&S.splice(t,1)}function l(e){var t=document.createElement("style");return t.type="text/css",i(e,t),t}function s(e){var t=document.createElement("link");return t.rel="stylesheet",i(e,t),t}function u(e,t){var n,o,r;if(t.singleton){var i=b++;n=m||(m=l(t)),o=c.bind(null,n,i,!1),r=c.bind(null,n,i,!0)}else e.sourceMap&&"function"==typeof URL&&"function"==typeof URL.createObjectURL&&"function"==typeof URL.revokeObjectURL&&"function"==typeof Blob&&"function"==typeof btoa?(n=s(t),o=p.bind(null,n),r=function(){a(n),n.href&&URL.revokeObjectURL(n.href)}):(n=l(t),o=f.bind(null,n),r=function(){a(n)});return o(e),function(t){if(t){if(t.css===e.css&&t.media===e.media&&t.sourceMap===e.sourceMap)return;o(e=t)}else r()}}function c(e,t,n,o){var r=n?"":o.css;if(e.styleSheet)e.styleSheet.cssText=g(t,r);else{var i=document.createTextNode(r),a=e.childNodes;a[t]&&e.removeChild(a[t]),a.length?e.insertBefore(i,a[t]):e.appendChild(i)}}function f(e,t){var n=t.css,o=t.media;if(o&&e.setAttribute("media",o),e.styleSheet)e.styleSheet.cssText=n;else{for(;e.firstChild;)e.removeChild(e.firstChild);e.appendChild(document.createTextNode(n))}}function p(e,t){var n=t.css,o=t.sourceMap;o&&(n+="\n/*# sourceMappingURL=data:application/json;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(o))))+" */");var r=new Blob([n],{type:"text/css"}),i=e.href;e.href=URL.createObjectURL(r),i&&URL.revokeObjectURL(i)}var d={},h=function(e){var t;return function(){return"undefined"==typeof t&&(t=e.apply(this,arguments)),t}},y=h(function(){return/msie [6-9]\b/.test(window.navigator.userAgent.toLowerCase())}),v=h(function(){return document.head||document.getElementsByTagName("head")[0]}),m=null,b=0,S=[];e.exports=function(e,t){t=t||{},"undefined"==typeof t.singleton&&(t.singleton=y()),"undefined"==typeof t.insertAt&&(t.insertAt="bottom");var n=r(e);return o(n,t),function(e){for(var i=[],a=0;a * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = 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; }; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } var _Store = require('./Store'); var _Store2 = _interopRequireDefault(_Store); var _GridBuilder = require('./GridBuilder'); var _GridBuilder2 = _interopRequireDefault(_GridBuilder); /** * Automatic layout for presenting draggable cards to users. Used for user and admin dashboard. */ var React = require('react'); var Pydio = require('pydio'); var _require = require('react-grid-layout'); var Responsive = _require.Responsive; var WidthProvider = _require.WidthProvider; var _Pydio$requireLib = Pydio.requireLib('boot'); var PydioContextConsumer = _Pydio$requireLib.PydioContextConsumer; var CardsGrid = React.createClass({ displayName: 'CardsGrid', /** * Save layouts in the users preference. * * @param {object} allLayouts Responsive layouts passed for saving */ saveFullLayouts: function saveFullLayouts(allLayouts) { var savedPref = this.props.store.getUserPreference('Layout'); // Compare JSON versions to avoid saving unnecessary changes if (savedPref && this.previousLayout && this.previousLayout == JSON.stringify(allLayouts)) { return; } this.previousLayout = JSON.stringify(allLayouts); this.props.store.saveUserPreference('Layout', allLayouts); }, onLayoutChange: function onLayoutChange(currentLayout, allLayouts) { if (this._blockLayoutSave) return; this.saveFullLayouts(allLayouts); }, componentWillUnmount: function componentWillUnmount() { this.props.store.stopObserving("cards", this._storeObserver); }, componentWillReceiveProps: function componentWillReceiveProps(nextProps) { if (this.props && nextProps.editMode !== this.props.editMode) { Object.keys(this.refs).forEach((function (k) { this.refs[k].toggleEditMode(nextProps.editMode); }).bind(this)); } }, shouldComponentUpdate: function shouldComponentUpdate(nextProps, nextState) { return this._forceUpdate || false; }, getInitialState: function getInitialState() { this._storeObserver = (function (e) { var _this = this; this._forceUpdate = true; this.setState({ cards: this.props.store.getCards() }, function () { _this._forceUpdate = false; }); }).bind(this); this.props.store.observe("cards", this._storeObserver); return { cards: this.props.store.getCards() }; }, removeCard: function removeCard(itemKey) { this.props.removeCard(itemKey); }, buildCards: function buildCards(cards) { var index = 0; var layouts = { lg: [], md: [], sm: [], xs: [], xxs: [] }; var items = []; var additionalNamespaces = []; var rand = Math.random(); var savedLayouts = this.props.store.getUserPreference('Layout'); var buildLayout = function buildLayout(classObject, itemKey, item, x, y) { var layout = classObject.getGridLayout(x, y); layout['handle'] = 'h4'; if (item['gridHandle']) { layout['handle'] = item['gridHandle']; } layout['i'] = itemKey; return layout; }; cards.map((function (item) { var parts = item.componentClass.split("."); var classNS = parts[0]; var className = parts[1]; var classObject; if (global[classNS] && global[classNS][className]) { classObject = global[classNS][className]; } else { if (!global[classNS]) { additionalNamespaces.push(classNS); } return; } var props = _extends({}, item.props); var itemKey = props['key'] = item['id'] || 'item_' + index; props.ref = itemKey; props.pydio = this.props.pydio; props.onCloseAction = (function () { this.removeCard(itemKey); }).bind(this); props.preferencesProvider = this.props.store; var defaultX = 0, defaultY = 0; if (item.defaultPosition) { defaultX = item.defaultPosition.x; defaultY = item.defaultPosition.y; } var defaultLayout = buildLayout(classObject, itemKey, item, defaultX, defaultY); for (var breakpoint in layouts) { if (!layouts.hasOwnProperty(breakpoint)) continue; var breakLayout = layouts[breakpoint]; // Find corresponding element in preference var existing; if (savedLayouts && savedLayouts[breakpoint]) { savedLayouts[breakpoint].map(function (gridData) { if (gridData['i'] == itemKey && gridData['h'] == defaultLayout['h']) { existing = gridData; } }); } if (existing) { breakLayout.push(existing); } else if (item.defaultLayouts && item.defaultLayouts[breakpoint]) { var crtLayout = buildLayout(classObject, itemKey, item, item.defaultLayouts[breakpoint].x, item.defaultLayouts[breakpoint].y); breakLayout.push(crtLayout); } else { breakLayout.push(defaultLayout); } } index++; items.push(React.createElement(classObject, props)); }).bind(this)); if (additionalNamespaces.length) { this._blockLayoutSave = true; ResourcesManager.loadClassesAndApply(additionalNamespaces, (function () { this.setState({ additionalNamespacesLoaded: additionalNamespaces }, (function () { this._blockLayoutSave = false; }).bind(this)); }).bind(this)); } return { cards: items, layouts: layouts }; }, render: function render() { var _buildCards = this.buildCards(this.state.cards); var cards = _buildCards.cards; var layouts = _buildCards.layouts; var ResponsiveGridLayout = WidthProvider(Responsive); return React.createElement( ResponsiveGridLayout, { className: 'dashboard-layout', cols: this.props.cols || { lg: 10, md: 8, sm: 8, xs: 4, xxs: 2 }, layouts: layouts, rowHeight: 5, onLayoutChange: this.onLayoutChange, isDraggable: !this.props.disableDrag, style: this.props.style, autoSize: false }, cards ); } }); var DynamicGrid = React.createClass({ displayName: 'DynamicGrid', propTypes: { storeNamespace: React.PropTypes.string.isRequired, builderNamespaces: React.PropTypes.array, defaultCards: React.PropTypes.array, pydio: React.PropTypes.instanceOf(Pydio), disableDrag: React.PropTypes.bool }, removeCard: function removeCard(cardId) { this.state.store.removeCard(cardId); }, addCard: function addCard(cardDefinition) { this.state.store.addCard(cardDefinition); }, resetCardsAndLayout: function resetCardsAndLayout() { this.state.store.saveUserPreference('Layout', null); this.state.store.setCards(this.props.defaultCards); }, getInitialState: function getInitialState() { var store = new _Store2['default'](this.props.storeNamespace, this.props.defaultCards, this.props.pydio); return { editMode: false, store: store }; }, toggleEditMode: function toggleEditMode() { this.setState({ editMode: !this.state.editMode }); }, render: function render() { var _this2 = this; var monitorWidgetEditing = (function (status) { this.setState({ widgetEditing: status }); }).bind(this); var builder = undefined; if (this.props.builderNamespaces && this.state.editMode) { builder = React.createElement(_GridBuilder2['default'], { className: 'admin-helper-panel', namespaces: this.props.builderNamespaces, onCreateCard: this.addCard, onResetLayout: this.resetCardsAndLayout, onEditStatusChange: monitorWidgetEditing, getMessage: function (id) { var ns = arguments.length <= 1 || arguments[1] === undefined ? 'ajxp_admin' : arguments[1]; return _this2.props.getMessage(id, ns); } }); } var propStyle = this.props.style || {}; var rglStyle = this.props.rglStyle || {}; return React.createElement( 'div', { style: _extends({}, this.props.style, { width: '100%', flex: '1' }), className: this.state.editMode ? "builder-open" : "" }, React.createElement( 'div', { style: { position: 'absolute', bottom: 30, right: 18, zIndex: 11 } }, React.createElement(MaterialUI.FloatingActionButton, { tooltip: this.props.getMessage('home.49'), onClick: this.toggleEditMode, iconClassName: this.state.editMode ? "icon-ok" : "mdi mdi-pencil", mini: this.state.editMode, disabled: this.state.editMode && this.state.widgetEditing }) ), builder, React.createElement( 'div', { className: 'home-dashboard', style: { height: '100%' } }, React.createElement(CardsGrid, { disableDrag: this.props.disableDrag, cols: this.props.cols, store: this.state.store, style: rglStyle, pydio: this.props.pydio, editMode: this.state.editMode, removeCard: this.removeCard }) ) ); } }); exports['default'] = DynamicGrid = PydioContextConsumer(DynamicGrid); exports['default'] = DynamicGrid; module.exports = exports['default']; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"./GridBuilder":3,"./Store":5,"pydio":"pydio","react":"react","react-grid-layout":"react-grid-layout"}],3:[function(require,module,exports){ (function (global){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = 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 React = require('react'); var Pydio = require('pydio'); var _Pydio$requireLib = Pydio.requireLib('boot'); var PydioContextConsumer = _Pydio$requireLib.PydioContextConsumer; var AsyncComponent = _Pydio$requireLib.AsyncComponent; var GridBuilder = React.createClass({ displayName: 'GridBuilder', propTypes: { namespaces: React.PropTypes.array, onCreateCard: React.PropTypes.func, onEditStatusChange: React.PropTypes.func }, getInitialState: function getInitialState() { return { selectedIndex: 0, availableWidgets: this.listAvailableWidgets() }; }, listAvailableWidgets: function listAvailableWidgets() { var secondPass = arguments.length <= 0 || arguments[0] === undefined ? false : arguments[0]; var widgets = []; var additionalNamespaces = []; this.props.namespaces.map(function (ns) { if (!global[ns]) { additionalNamespaces.push(ns); return; } for (var k in global[ns]) { if (global[ns].hasOwnProperty(k)) { var widgetClass = global[ns][k]; if (widgetClass.hasBuilderFields && widgetClass.hasBuilderFields()) { widgets.push({ reactClass: widgetClass, fullName: ns + '.' + widgetClass.displayName }); } } } }); if (additionalNamespaces.length && !secondPass) { ResourcesManager.loadClassesAndApply(additionalNamespaces, (function () { this.setState({ availableWidgets: this.listAvailableWidgets(true) }); }).bind(this)); } return widgets; }, onDropDownChange: function onDropDownChange(event, index, item) { var defaultValues = {}; if (index != 0) { item.payload['reactClass'].getBuilderFields().map(function (f) { if (f['default']) defaultValues[f.name] = f['default']; }); } if (this.props.onEditStatusChange) { this.props.onEditStatusChange(index != 0); } this.setState({ selectedIndex: index, selectedWidget: item.payload, currentFormValues: defaultValues }); }, cancel: function cancel() { if (this.props.onEditStatusChange) { this.props.onEditStatusChange(false); } this.setState({ selectedIndex: 0 }); }, onFormValueChange: function onFormValueChange(newValues) { this.setState({ currentFormValues: newValues }); }, onFormSubmit: function onFormSubmit() { var values = this.state.currentFormValues; var selectedWidget = this.state.selectedWidget; var title = values.title ? values.title : values.legend; if (!title) title = this.state.selectedWidget['reactClass'].builderDisplayName; this.props.onCreateCard({ componentClass: selectedWidget.fullName, title: title, props: values }); this.cancel(); }, resetLayout: function resetLayout() { if (window.confirm(this.props.getMessage('home.51'))) { this.props.onResetLayout(); } }, render: function render() { var getMessage = this.props.getMessage; var selectorItems = [{ payload: 0, text: getMessage('home.50') }].concat(this.state.availableWidgets.map(function (w, index) { return { payload: w, text: w['reactClass'].builderDisplayName }; })); var selector = React.createElement(ReactMUI.DropDownMenu, { menuItems: selectorItems, onChange: this.onDropDownChange, selectedIndex: this.state.selectedIndex, autoWidth: false, className: 'widget-type-selector' }); var form, add; if (this.state.selectedIndex != 0) { var fields = this.state.selectedWidget['reactClass'].getBuilderFields(); var defaultValues = {}; fields.map(function (f) { if (f['default']) defaultValues[f.name] = f['default']; }); if (this.state.currentFormValues) { defaultValues = LangUtils.mergeObjectsRecursive(defaultValues, this.state.currentFormValues); } form = React.createElement(AsyncComponent, { namespace: 'PydioForm', componentName: 'FormPanel', parameters: fields, depth: -1, values: defaultValues, onChange: this.onFormValueChange }); add = React.createElement( 'div', { style: { textAlign: 'center', paddingBottom: 100 } }, React.createElement(ReactMUI.RaisedButton, { label: getMessage('home.52'), onClick: this.onFormSubmit }), ' ', React.createElement(ReactMUI.RaisedButton, { label: getMessage('54', ''), onClick: this.cancel }) ); } return React.createElement( ReactMUI.Paper, _extends({}, this.props, { zDepth: 3 }), React.createElement( 'h3', null, getMessage('home.53') ), React.createElement( 'div', { className: 'legend' }, getMessage('home.54'), React.createElement('br', null), getMessage('home.55') ), selector, form, add, React.createElement( 'div', { style: { position: 'absolute', bottom: 30, left: 10 } }, React.createElement(ReactMUI.FlatButton, { disabled: this.state.selectedIndex != 0, label: getMessage('home.56'), secondary: true, onClick: this.resetLayout }) ) ); } }); exports['default'] = GridBuilder = PydioContextConsumer(GridBuilder); exports['default'] = GridBuilder; module.exports = exports['default']; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"pydio":"pydio","react":"react"}],4:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = 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; }; exports['default'] = { propTypes: { showCloseAction: React.PropTypes.bool, onCloseAction: React.PropTypes.func }, focusItem: function focusItem() { this.setState({ focus: true }); }, blurItem: function blurItem() { this.setState({ focus: false }); }, mergeStyleWithFocus: function mergeStyleWithFocus() { return _extends({}, this.props.style, { zIndex: this.state.focus ? 1 : null }); }, getInitialSate: function getInitialSate() { return { focus: false, showCloseAction: false }; }, toggleEditMode: function toggleEditMode() { var value = arguments.length <= 0 || arguments[0] === undefined ? undefined : arguments[0]; if (value === undefined) { this.setState({ showCloseAction: !(this.state && this.state.showCloseAction) }); } else { this.setState({ showCloseAction: value }); } }, getCloseButton: function getCloseButton() { if (this.state && this.state.showCloseAction) { var closeAction = this.props.onCloseAction || function () {}; var overlayStyle = { position: 'absolute', backgroundColor: 'rgba(0,0,0,0.53)', zIndex: 10, top: 0, left: 0, bottom: 0, right: 0, display: 'flex', alignItems: 'center', justifyContent: 'center' }; return React.createElement( 'div', { style: overlayStyle }, React.createElement(MaterialUI.FlatButton, { label: pydio.MessageHash['ajxp_admin.home.48'], className: 'card-close-button', onTouchTap: closeAction, style: { color: 'white' } }) ); } else { return null; } }, statics: { getGridLayout: function getGridLayout(x, y) { return { x: x || 0, y: y || 0, w: this.gridWidth || 4, h: this.gridHeight || 12, isResizable: false }; }, hasBuilderFields: function hasBuilderFields() { return this.builderFields ? true : false; }, getBuilderFields: function getBuilderFields() { return this.builderFields; } } }; module.exports = exports['default']; },{}],5:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; 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 Store = (function (_Observable) { _inherits(Store, _Observable); /** * Init a card store * @param prefNamespace Namespace for getting/setting user preferences * @param defaultCards Array of cards to be displayed by default */ function Store(prefNamespace, defaultCards, pydioObject) { _classCallCheck(this, Store); _Observable.call(this); this._namespace = prefNamespace; this._pydio = pydioObject; this._cards = this.getUserPreference("Cards"); if (!this._cards) { this._cards = defaultCards; } } Store.prototype.getUserPreference = function getUserPreference(prefName) { var prefKey = this._namespace + prefName; var guiPrefs = this._pydio.user.getPreference('gui_preferences', true); if (guiPrefs && guiPrefs[prefKey]) { return guiPrefs[prefKey]; } else { return null; } }; Store.prototype.saveUserPreference = function saveUserPreference(prefName, prefValue) { var prefKey = this._namespace + prefName; var guiPrefs = this._pydio.user.getPreference('gui_preferences', true); if (!guiPrefs) guiPrefs = {}; guiPrefs[prefKey] = prefValue; this._pydio.user.setPreference('gui_preferences', guiPrefs, true); this._pydio.user.savePreference('gui_preferences'); }; Store.prototype.saveCards = function saveCards(cards) { this.saveUserPreference('Cards', cards); }; Store.prototype.resetCards = function resetCards() { this.saveUserPreference('Cards', null); }; Store.prototype.setCards = function setCards(newCards) { this._cards = newCards; this.notify("cards", this._cards); this.saveCards(newCards); }; Store.prototype.getCards = function getCards() { return this._cards; }; Store.prototype.removeCard = function removeCard(cardId) { var index = -1; var currentCards = this.getCards(); currentCards.map(function (card, arrayIndex) { if (card.id == cardId) index = arrayIndex; }); if (index == -1) { console.warn('Card ID not found, this is strange.', cardId); return; } var newCards; if (index == 0) newCards = currentCards.slice(1);else if (index == currentCards.length - 1) newCards = currentCards.slice(0, -1);else newCards = currentCards.slice(0, index).concat(currentCards.slice(index + 1)); this.setCards(newCards); }; Store.prototype.createCardId = function createCardId(cardDefinition) { var randomize = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1]; var id = LangUtils.computeStringSlug(cardDefinition['title']); if (randomize) { id += '-' + Math.round(Math.random() * 100 + 10); } var alreadyExists = false; this._cards.map((function (card) { if (card.id == id) alreadyExists = true; }).bind(this)); if (alreadyExists) { id = this.createCardId(cardDefinition, true); } return id; }; Store.prototype.addCard = function addCard(cardDefinition) { //console.log(cardDefinition); cardDefinition['id'] = this.createCardId(cardDefinition); this.setCards(this._cards.concat([cardDefinition])); }; return Store; })(Observable); exports['default'] = Store; module.exports = exports['default']; },{}],6:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = 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; }; 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 FlatButton = _require2.FlatButton; var _require3 = require('material-ui/styles'); var muiThemeable = _require3.muiThemeable; exports['default'] = function (PydioComponent, displayName) { var gridDimension = arguments.length <= 2 || arguments[2] === undefined ? { gridWidth: 4, gridHeight: 12 } : arguments[2]; var builderFields = arguments.length <= 3 || arguments[3] === undefined ? undefined : arguments[3]; var originalDisplayName = PydioComponent.displayName || PydioComponent.name; PydioComponent = muiThemeable()(PydioComponent); var GridItem = (function (_Component) { _inherits(GridItem, _Component); function GridItem(props, context) { _classCallCheck(this, GridItem); _Component.call(this, props, context); this.state = { focus: false, showCloseAction: false }; } GridItem.prototype.focusItem = function focusItem() { this.setState({ focus: true }); }; GridItem.prototype.blurItem = function blurItem() { this.setState({ focus: false }); }; GridItem.prototype.mergeStyleWithFocus = function mergeStyleWithFocus() { return _extends({}, this.props.style, { zIndex: this.state.focus ? 1 : null }); }; GridItem.prototype.toggleEditMode = function toggleEditMode() { var value = arguments.length <= 0 || arguments[0] === undefined ? undefined : arguments[0]; if (value === undefined) { this.setState({ showCloseAction: !(this.state && this.state.showCloseAction) }); } else { this.setState({ showCloseAction: value }); } }; GridItem.prototype.getCloseButton = function getCloseButton() { var closeAction = this.props.onCloseAction || function () {}; var overlayStyle = { position: 'absolute', backgroundColor: 'rgba(0,0,0,0.53)', zIndex: 10, top: 0, left: 0, bottom: 0, right: 0, display: 'flex', alignItems: 'center', justifyContent: 'center' }; return React.createElement( 'div', { style: overlayStyle }, React.createElement(FlatButton, { label: this.props.pydio.MessageHash['ajxp_admin.home.48'], className: 'card-close-button', onTouchTap: closeAction, style: { color: 'white' } }) ); }; GridItem.prototype.render = function render() { var props = _extends({}, this.props, { style: this.mergeStyleWithFocus(), closeButton: this.state.showCloseAction ? this.getCloseButton() : null, onFocusItem: this.focusItem.bind(this), onBlurItem: this.blurItem.bind(this) }); return React.createElement(PydioComponent, props); }; return GridItem; })(Component); GridItem.propTypes = { onCloseAction: PropTypes.func }; GridItem.displayName = originalDisplayName; GridItem.builderDisplayName = displayName; GridItem.getGridLayout = function (x, y) { return { x: x || 0, y: y || 0, w: gridDimension.gridWidth || 4, h: gridDimension.gridHeight || 12, isResizable: false }; }; GridItem.hasBuilderFields = function () { return builderFields !== undefined; }; GridItem.getBuilderFields = function () { return builderFields; }; return GridItem; }; module.exports = exports['default']; },{"material-ui":"material-ui","material-ui/styles":"material-ui/styles","react":"react"}],7:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ /** * Two columns layout used for Workspaces and Plugins editors */ 'use strict'; exports.__esModule = true; var PaperEditorLayout = React.createClass({ displayName: 'PaperEditorLayout', propTypes: { title: React.PropTypes.any, titleActionBar: React.PropTypes.any, leftNav: React.PropTypes.any, contentFill: React.PropTypes.bool, className: React.PropTypes.string }, toggleMenu: function toggleMenu() { var crtLeftOpen = this.state && this.state.forceLeftOpen; this.setState({ forceLeftOpen: !crtLeftOpen }); }, render: function render() { return React.createElement( 'div', { className: "paper-editor-content layout-fill vertical-layout" + (this.props.className ? ' ' + this.props.className : '') }, React.createElement( 'div', { className: 'paper-editor-title' }, React.createElement( 'h2', null, this.props.title, ' ', React.createElement( 'div', { className: 'left-picker-toggle' }, React.createElement(ReactMUI.IconButton, { iconClassName: 'icon-caret-down', onClick: this.toggleMenu }) ) ), React.createElement( 'div', { className: 'title-bar' }, this.props.titleActionBar ) ), React.createElement( 'div', { className: 'layout-fill main-layout-nav-to-stack' }, React.createElement( 'div', { className: "paper-editor-left" + (this.state && this.state.forceLeftOpen ? ' picker-open' : ''), onClick: this.toggleMenu }, this.props.leftNav ), React.createElement( 'div', { className: "layout-fill paper-editor-right" + (this.props.contentFill ? ' vertical-layout' : ''), style: this.props.contentFill ? {} : { overflowY: 'auto' } }, this.props.children ) ) ); } }); /** * Navigation subheader used by PaperEditorLayout */ var PaperEditorNavHeader = React.createClass({ displayName: 'PaperEditorNavHeader', propTypes: { label: React.PropTypes.string }, render: function render() { return React.createElement( 'div', { className: 'mui-subheader' }, this.props.children, this.props.label ); } }); /** * Navigation entry used by PaperEditorLayout. */ var PaperEditorNavEntry = React.createClass({ displayName: 'PaperEditorNavEntry', propTypes: { keyName: React.PropTypes.string.isRequired, onClick: React.PropTypes.func.isRequired, label: React.PropTypes.string, selectedKey: React.PropTypes.string, isLast: React.PropTypes.bool, // Drop Down Data dropDown: React.PropTypes.bool, dropDownData: React.PropTypes.object, dropDownChange: React.PropTypes.func, dropDownDefaultItems: React.PropTypes.array }, onClick: function onClick() { this.props.onClick(this.props.keyName); }, captureDropDownClick: function captureDropDownClick() { if (this.preventClick) { this.preventClick = false; return; } this.props.onClick(this.props.keyName); }, dropDownChange: function dropDownChange(event, index, item) { this.preventClick = true; this.props.dropDownChange(item); }, render: function render() { if (!this.props.dropDown || !this.props.dropDownData) { return React.createElement( 'div', { className: 'menu-entry' + (this.props.keyName == this.props.selectedKey ? ' menu-entry-selected' : '') + (this.props.isLast ? ' last' : ''), onClick: this.onClick }, this.props.children, this.props.label ); } // dropDown & dropDownData are loaded var menuItemsTpl = [{ text: this.props.label, payload: '-1' }]; if (this.props.dropDownDefaultItems) { menuItemsTpl = menuItemsTpl.concat(this.props.dropDownDefaultItems); } this.props.dropDownData.forEach(function (v, k) { menuItemsTpl.push({ text: v.label, payload: v }); }); return React.createElement( 'div', { onClick: this.captureDropDownClick, className: 'menu-entry-dropdown' + (this.props.keyName == this.props.selectedKey ? ' menu-entry-selected' : '') + (this.props.isLast ? ' last' : '') }, React.createElement(ReactMUI.DropDownMenu, { menuItems: menuItemsTpl, className: 'dropdown-full-width', style: { width: 256 }, autoWidth: false, onChange: this.dropDownChange }) ); } }); exports.PaperEditorLayout = PaperEditorLayout; exports.PaperEditorNavEntry = PaperEditorNavEntry; exports.PaperEditorNavHeader = PaperEditorNavHeader; },{}],8:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ "use strict"; exports.__esModule = true; 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 propTypes = { node: React.PropTypes.instanceOf(AjxpNode).isRequired, registry: React.PropTypes.instanceOf(Registry).isRequired, editorData: React.PropTypes.object.isRequired, icon: React.PropTypes.bool }; var defaultProps = { icon: false }; var ReactEditorOpener = (function (_React$Component) { _inherits(ReactEditorOpener, _React$Component); function ReactEditorOpener(props) { _classCallCheck(this, ReactEditorOpener); _React$Component.call(this, props); var node = props.node; var editorData = props.editorData; this.state = { ready: false }; } ReactEditorOpener.prototype.componentDidMount = function componentDidMount() { var _this = this; var _props = this.props; var editorData = _props.editorData; var registry = _props.registry; registry.loadEditorResources(editorData.resourcesManager, function () { return _this.setState({ ready: true }); }); }; ReactEditorOpener.prototype.render = function render() { var editorData = this.props.editorData; var ready = this.state.ready; if (!ready) return null; var EditorClass = null; if (!(EditorClass = FuncUtils.getFunctionByName(editorData.editorClass, window))) { return React.createElement( "div", null, "Cannot find editor component (" + editorData.editorClass + ")!" ); } // Getting HOC of the class return React.createElement(EditorClass.Editor, this.props); }; return ReactEditorOpener; })(React.Component); ReactEditorOpener.propTypes = propTypes; ReactEditorOpener.defaultProps = defaultProps; exports["default"] = ReactEditorOpener; module.exports = exports["default"]; },{}],9:[function(require,module,exports){ (function (global){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = 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; }; exports['default'] = React.createClass({ displayName: 'ClipboardTextField', propTypes: { floatingLabelText: React.PropTypes.string, inputValue: React.PropTypes.string, inputClassName: React.PropTypes.string, getMessage: React.PropTypes.func, inputCopyMessage: React.PropTypes.string }, getInitialState: function getInitialState() { return { copyMessage: null }; }, componentDidMount: function componentDidMount() { this.attachClipboard(); }, componentDidUpdate: function componentDidUpdate() { this.attachClipboard(); }, attachClipboard: function attachClipboard() { if (this._clip) { this._clip.destroy(); } if (!this.refs['copy-button']) { return; } this._clip = new Clipboard(this.refs['copy-button'], { text: (function (trigger) { return this.props.inputValue; }).bind(this) }); this._clip.on('success', (function () { this.setState({ copyMessage: this.props.getMessage(this.props.inputCopyMessage || '192') }, this.clearCopyMessage); }).bind(this)); this._clip.on('error', (function () { var copyMessage; if (global.navigator.platform.indexOf("Mac") === 0) { copyMessage = this.props.getMessage('144'); } else { copyMessage = this.props.getMessage('143'); } this.refs['input'].focus(); this.setState({ copyMessage: copyMessage }, this.clearCopyMessage); }).bind(this)); }, clearCopyMessage: function clearCopyMessage() { global.setTimeout((function () { this.setState({ copyMessage: '' }); }).bind(this), 3000); }, render: function render() { var select = function select(e) { e.currentTarget.select(); }; var copyMessage = null; if (this.state.copyMessage) { var setHtml = (function () { return { __html: this.state.copyMessage }; }).bind(this); copyMessage = React.createElement('div', { style: { color: 'rgba(0,0,0,0.23)' }, className: 'copy-message', dangerouslySetInnerHTML: setHtml() }); } var buttonStyle = _extends({ position: 'absolute', right: -8, bottom: 13, fontSize: 15, color: this.props.buttonColor || 'rgba(0, 150, 136, 0.52)', height: 26, width: 26, lineHeight: '28px', textAlign: 'center', cursor: 'pointer', borderRadius: '50%' }, this.props.buttonStyle); return React.createElement( 'div', null, React.createElement( 'div', { style: { position: 'relative' } }, React.createElement(MaterialUI.TextField, { fullWidth: true, ref: 'input', floatingLabelText: this.props.floatingLabelText, floatingLabelStyle: { whiteSpace: 'nowrap' }, underlineShow: this.props.underlineShow, defaultValue: this.props.inputValue, className: this.props.inputClassName, multiLine: this.props.multiLine, rows: this.props.rows, rowsMax: this.props.rowsMax, readOnly: true, onClick: select, style: { marginTop: -10, width: '92%', fontSize: 14 } }), React.createElement('span', { ref: 'copy-button', style: buttonStyle, title: this.props.getMessage('191'), className: 'copy-button mdi mdi-content-copy' }) ), copyMessage ); } }); module.exports = exports['default']; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{}],10:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; exports['default'] = React.createClass({ displayName: 'LabelWithTip', propTypes: { label: React.PropTypes.string, labelElement: React.PropTypes.object, tooltip: React.PropTypes.string, tooltipClassName: React.PropTypes.string, className: React.PropTypes.string, style: React.PropTypes.object }, getInitialState: function getInitialState() { return { show: false }; }, show: function show() { this.setState({ show: true }); }, hide: function hide() { this.setState({ show: false }); }, render: function render() { if (this.props.tooltip) { var tooltipStyle = {}; if (this.props.label || this.props.labelElement) { if (this.state.show) { tooltipStyle = { bottom: -10, top: 'inherit' }; } } else { tooltipStyle = { position: 'relative' }; } var label = undefined; if (this.props.label) { label = React.createElement( 'span', { className: 'ellipsis-label' }, this.props.label ); } else if (this.props.labelElement) { label = this.props.labelElement; } var style = this.props.style || { position: 'relative' }; return React.createElement( 'span', { onMouseEnter: this.show, onMouseLeave: this.hide, style: style, className: this.props.className }, label, this.props.children, React.createElement(ReactMUI.Tooltip, { label: this.props.tooltip, style: tooltipStyle, className: this.props.tooltipClassName, show: this.state.show }) ); } else { if (this.props.label) { return React.createElement( 'span', null, this.props.label ); } else if (this.props.labelElement) { return this.props.labelElement; } else { return React.createElement( 'span', null, this.props.children ); } } } }); module.exports = exports['default']; },{}],11:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ /** * Simple MuiPaper with a figure and a legend */ 'use strict'; exports.__esModule = true; exports['default'] = React.createClass({ displayName: 'SimpleFigureBadge', propTypes: { colorIndicator: React.PropTypes.string, figure: React.PropTypes.number.isRequired, legend: React.PropTypes.string }, getDefaultProps: function getDefaultProps() { return { colorIndicator: '' }; }, render: function render() { return React.createElement( ReactMUI.Paper, { style: { display: 'inline-block', marginLeft: 16 } }, React.createElement( 'div', { className: 'figure-badge', style: this.props.colorIndicator ? { borderLeftColor: this.props.colorIndicator } : {} }, React.createElement( 'div', { className: 'figure' }, this.props.figure ), React.createElement( 'div', { className: 'legend' }, this.props.legend ) ) ); } }); module.exports = exports['default']; },{}],12:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } var _listSortableList = require('./list/SortableList'); var _listSortableList2 = _interopRequireDefault(_listSortableList); var _listSimpleList = require('./list/SimpleList'); var _listSimpleList2 = _interopRequireDefault(_listSimpleList); var _listNodeListCustomProvider = require('./list/NodeListCustomProvider'); var _listNodeListCustomProvider2 = _interopRequireDefault(_listNodeListCustomProvider); var _listListEntry = require('./list/ListEntry'); var _listListPaginator = require('./list/ListPaginator'); var _listListPaginator2 = _interopRequireDefault(_listListPaginator); var _viewsTreeView = require('./views/TreeView'); var _elementsLabelWithTip = require('./elements/LabelWithTip'); var _elementsLabelWithTip2 = _interopRequireDefault(_elementsLabelWithTip); var _elementsSimpleFigureBadge = require('./elements/SimpleFigureBadge'); var _elementsSimpleFigureBadge2 = _interopRequireDefault(_elementsSimpleFigureBadge); var _viewsSearchBox = require('./views/SearchBox'); var _viewsSearchBox2 = _interopRequireDefault(_viewsSearchBox); var _elementsClipboardTextField = require('./elements/ClipboardTextField'); var _elementsClipboardTextField2 = _interopRequireDefault(_elementsClipboardTextField); var _viewsEmptyStateView = require('./views/EmptyStateView'); var _viewsEmptyStateView2 = _interopRequireDefault(_viewsEmptyStateView); var _viewsModalAppBar = require('./views/ModalAppBar'); var _viewsModalAppBar2 = _interopRequireDefault(_viewsModalAppBar); var _editorReactEditorOpener = require('./editor/ReactEditorOpener'); var _editorReactEditorOpener2 = _interopRequireDefault(_editorReactEditorOpener); var _editorPaperEditor = require('./editor/PaperEditor'); var _dynamicGridDynamicGrid = require('./dynamic-grid/DynamicGrid'); var _dynamicGridDynamicGrid2 = _interopRequireDefault(_dynamicGridDynamicGrid); var _dynamicGridStore = require('./dynamic-grid/Store'); var _dynamicGridStore2 = _interopRequireDefault(_dynamicGridStore); var _dynamicGridGridItemMixin = require('./dynamic-grid/GridItemMixin'); var _dynamicGridGridItemMixin2 = _interopRequireDefault(_dynamicGridGridItemMixin); var _dynamicGridAsGridItem = require('./dynamic-grid/asGridItem'); var _dynamicGridAsGridItem2 = _interopRequireDefault(_dynamicGridAsGridItem); var _utilDND = require('./util/DND'); var _usersAvatarUserAvatar = require('./users/avatar/UserAvatar'); var _usersAvatarUserAvatar2 = _interopRequireDefault(_usersAvatarUserAvatar); var _usersUsersCompleter = require('./users/UsersCompleter'); var _usersUsersCompleter2 = _interopRequireDefault(_usersUsersCompleter); var _usersTeamCreationForm = require('./users/TeamCreationForm'); var _usersTeamCreationForm2 = _interopRequireDefault(_usersTeamCreationForm); var _menuButtonMenu = require('./menu/ButtonMenu'); var _menuButtonMenu2 = _interopRequireDefault(_menuButtonMenu); var _menuContextMenu = require('./menu/ContextMenu'); var _menuContextMenu2 = _interopRequireDefault(_menuContextMenu); var _menuIconButtonMenu = require('./menu/IconButtonMenu'); var _menuIconButtonMenu2 = _interopRequireDefault(_menuIconButtonMenu); var _menuToolbar = require('./menu/Toolbar'); var _menuToolbar2 = _interopRequireDefault(_menuToolbar); var _usersAddressbookAddressBook = require('./users/addressbook/AddressBook'); var _usersAddressbookAddressBook2 = _interopRequireDefault(_usersAddressbookAddressBook); var PydioComponents = { SortableList: _listSortableList2['default'], SimpleList: _listSimpleList2['default'], NodeListCustomProvider: _listNodeListCustomProvider2['default'], ListEntry: _listListEntry.ListEntry, ListPaginator: _listListPaginator2['default'], TreeView: _viewsTreeView.TreeView, DNDTreeView: _viewsTreeView.DNDTreeView, FoldersTree: _viewsTreeView.FoldersTree, ClipboardTextField: _elementsClipboardTextField2['default'], LabelWithTip: _elementsLabelWithTip2['default'], EmptyStateView: _viewsEmptyStateView2['default'], SimpleFigureBadge: _elementsSimpleFigureBadge2['default'], SearchBox: _viewsSearchBox2['default'], ModalAppBar: _viewsModalAppBar2['default'], ReactEditorOpener: _editorReactEditorOpener2['default'], PaperEditorLayout: _editorPaperEditor.PaperEditorLayout, PaperEditorNavEntry: _editorPaperEditor.PaperEditorNavEntry, PaperEditorNavHeader: _editorPaperEditor.PaperEditorNavHeader, DynamicGrid: _dynamicGridDynamicGrid2['default'], DynamicGridItemMixin: _dynamicGridGridItemMixin2['default'], asGridItem: _dynamicGridAsGridItem2['default'], DynamicGridStore: _dynamicGridStore2['default'], DND: { Types: _utilDND.Types, collect: _utilDND.collect, collectDrop: _utilDND.collectDrop, nodeDragSource: _utilDND.nodeDragSource, nodeDropTarget: _utilDND.nodeDropTarget, DNDActionParameter: _utilDND.DNDActionParameter }, DNDActionParameter: _utilDND.DNDActionParameter, UserAvatar: _usersAvatarUserAvatar2['default'], UsersCompleter: _usersUsersCompleter2['default'], TeamCreationForm: _usersTeamCreationForm2['default'], AddressBook: _usersAddressbookAddressBook2['default'], ContextMenu: _menuContextMenu2['default'], Toolbar: _menuToolbar2['default'], ButtonMenu: _menuButtonMenu2['default'], IconButtonMenu: _menuIconButtonMenu2['default'] }; exports['default'] = PydioComponents; module.exports = exports['default']; },{"./dynamic-grid/DynamicGrid":2,"./dynamic-grid/GridItemMixin":4,"./dynamic-grid/Store":5,"./dynamic-grid/asGridItem":6,"./editor/PaperEditor":7,"./editor/ReactEditorOpener":8,"./elements/ClipboardTextField":9,"./elements/LabelWithTip":10,"./elements/SimpleFigureBadge":11,"./list/ListEntry":15,"./list/ListPaginator":17,"./list/NodeListCustomProvider":18,"./list/SimpleList":19,"./list/SortableList":21,"./menu/ButtonMenu":24,"./menu/ContextMenu":25,"./menu/IconButtonMenu":26,"./menu/Toolbar":30,"./users/TeamCreationForm":32,"./users/UsersCompleter":33,"./users/addressbook/AddressBook":34,"./users/avatar/UserAvatar":46,"./util/DND":47,"./views/EmptyStateView":49,"./views/ModalAppBar":50,"./views/SearchBox":51,"./views/TreeView":53}],13:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = 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; }; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _ListEntryNodeListenerMixin = require('./ListEntryNodeListenerMixin'); var _ListEntryNodeListenerMixin2 = _interopRequireDefault(_ListEntryNodeListenerMixin); var _InlineEditor = require('./InlineEditor'); var _InlineEditor2 = _interopRequireDefault(_InlineEditor); var _ListEntry = require('./ListEntry'); var _materialUi = require('material-ui'); /** * Callback based material list entry with custom icon render, firstLine, secondLine, etc. */ exports['default'] = _react2['default'].createClass({ displayName: 'ConfigurableListEntry', mixins: [_ListEntryNodeListenerMixin2['default']], propTypes: { node: _react2['default'].PropTypes.instanceOf(AjxpNode), // SEE ALSO ListEntry PROPS renderIcon: _react2['default'].PropTypes.func, renderFirstLine: _react2['default'].PropTypes.func, renderSecondLine: _react2['default'].PropTypes.func, renderThirdLine: _react2['default'].PropTypes.func, renderActions: _react2['default'].PropTypes.func, style: _react2['default'].PropTypes.object }, render: function render() { var _this = this; var icon = undefined, firstLine = undefined, secondLine = undefined, thirdLine = undefined, style = this.props.style || {}; if (this.props.renderIcon) { icon = this.props.renderIcon(this.props.node, this.props); } else { var node = this.props.node; var iconClass = node.getMetadata().get("icon_class") ? node.getMetadata().get("icon_class") : node.isLeaf() ? "icon-file-alt" : "icon-folder-close"; icon = _react2['default'].createElement(_materialUi.FontIcon, { className: iconClass }); } if (this.props.renderFirstLine) { firstLine = this.props.renderFirstLine(this.props.node); } else { firstLine = this.props.node.getLabel(); } if (this.state && this.state.inlineEdition) { firstLine = _react2['default'].createElement( 'span', null, _react2['default'].createElement(_InlineEditor2['default'], { node: this.props.node, onClose: function () { _this.setState({ inlineEdition: false }); }, callback: this.state.inlineEditionCallback }), firstLine ); style.position = 'relative'; } if (this.props.renderSecondLine) { secondLine = this.props.renderSecondLine(this.props.node); } if (this.props.renderThirdLine) { thirdLine = this.props.renderThirdLine(this.props.node); } var actions = this.props.actions; if (this.props.renderActions) { actions = this.props.renderActions(this.props.node); } return _react2['default'].createElement(_ListEntry.DragDropListEntry, _extends({}, this.props, { iconCell: icon, firstLine: firstLine, secondLine: secondLine, thirdLine: thirdLine, actions: actions, style: style })); } }); module.exports = exports['default']; },{"./InlineEditor":14,"./ListEntry":15,"./ListEntryNodeListenerMixin":16,"material-ui":"material-ui","react":"react"}],14:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; var React = require('react'); var Pydio = require('pydio'); var AjxpNode = require('pydio/model/node'); var _Pydio$requireLib = Pydio.requireLib('boot'); var PydioContextConsumer = _Pydio$requireLib.PydioContextConsumer; var _require = require('material-ui'); var Paper = _require.Paper; var TextField = _require.TextField; var FlatButton = _require.FlatButton; var InlineEditor = React.createClass({ displayName: 'InlineEditor', propTypes: { node: React.PropTypes.instanceOf(AjxpNode), callback: React.PropTypes.func, onClose: React.PropTypes.func, detached: React.PropTypes.bool }, submit: function submit() { if (!this.state || !this.state.value || this.state.value === this.props.node.getLabel()) { this.setState({ errorString: 'Please use a different value for renaming!' }); this.props.getPydio().displayMessage('ERROR', 'Please use a different value for renaming!'); } else { this.props.callback(this.state.value); this.props.onClose(); } }, componentDidMount: function componentDidMount() { this.refs.text.focus(); }, catchClicks: function catchClicks(e) { e.stopPropagation(); }, onKeyDown: function onKeyDown(e) { if (e.key === 'Enter') { this.submit(); } this.setState({ errorString: '' }); e.stopPropagation(); }, render: function render() { var _this = this; return React.createElement( Paper, { className: "inline-editor" + (this.props.detached ? " detached" : ""), style: { padding: 8 }, zDepth: 2 }, React.createElement(TextField, { ref: 'text', defaultValue: this.props.node.getLabel(), onChange: function (e, value) { _this.setState({ value: value }); }, onClick: this['catch'], onDoubleClick: this.catchClicks, tabIndex: '0', onKeyDown: this.onKeyDown, errorText: this.state ? this.state.errorString : null }), React.createElement( 'div', { style: { textAlign: 'right', paddingTop: 8 } }, React.createElement(FlatButton, { label: 'Cancel', onClick: this.props.onClose }), React.createElement(FlatButton, { label: 'Submit', onClick: this.submit }) ) ); } }); exports['default'] = InlineEditor = PydioContextConsumer(InlineEditor); exports['default'] = InlineEditor; module.exports = exports['default']; },{"material-ui":"material-ui","pydio":"pydio","pydio/model/node":"pydio/model/node","react":"react"}],15:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = 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; }; 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 _reactDom = require('react-dom'); var _reactDom2 = _interopRequireDefault(_reactDom); var _utilDND = require('../util/DND'); var _reactDnd = require('react-dnd'); var _materialUi = require('material-ui'); var _materialUiStyles = require('material-ui/styles'); var _color = require('color'); var _color2 = _interopRequireDefault(_color); /** * Material List Entry */ var ListEntry = (function (_React$Component) { _inherits(ListEntry, _React$Component); function ListEntry() { _classCallCheck(this, ListEntry); _React$Component.apply(this, arguments); } ListEntry.prototype.onClick = function onClick(event) { if (this.props.showSelector) { if (this.props.selectorDisabled) return; this.props.onSelect(this.props.node, event); event.stopPropagation(); event.preventDefault(); } else if (this.props.onClick) { this.props.onClick(this.props.node, event); } }; ListEntry.prototype.onDoubleClick = function onDoubleClick(event) { if (this.props.onDoubleClick) { this.props.onDoubleClick(this.props.node, event); } }; ListEntry.prototype.render = function render() { var _this = this; var selector = undefined, icon = undefined, additionalClassName = undefined; var _props = this.props; var node = _props.node; var showSelector = _props.showSelector; var selected = _props.selected; var selectorDisabled = _props.selectorDisabled; var firstLine = _props.firstLine; var secondLine = _props.secondLine; var thirdLine = _props.thirdLine; var style = _props.style; var actions = _props.actions; var iconCell = _props.iconCell; var mainIcon = _props.mainIcon; var className = _props.className; var canDrop = _props.canDrop; var isOver = _props.isOver; var connectDragSource = _props.connectDragSource; var connectDropTarget = _props.connectDropTarget; var mainClasses = ['material-list-entry', 'material-list-entry-' + (thirdLine ? 3 : secondLine ? 2 : 1) + '-lines']; if (className) mainClasses.push(className); if (showSelector) { selector = React.createElement( 'div', { className: 'material-list-selector' }, React.createElement(_materialUi.Checkbox, { checked: selected, ref: 'selector', disabled: selectorDisabled }) ); } if (iconCell) { icon = this.props.iconCell; } else if (this.props.mainIcon) { icon = React.createElement(_materialUi.FontIcon, { className: "mui-font-icon " + this.props.mainIcon, style: { fontSize: 18 /*, color: "#FFFFFF"*/ } }); } if (canDrop && isOver) { mainClasses.push('droppable-active'); } if (node) { mainClasses.push('listentry' + node.getPath().replace(/\//g, '_')); mainClasses.push('ajxp_node_' + (node.isLeaf() ? 'leaf' : 'collection')); if (node.getAjxpMime()) { mainClasses.push('ajxp_mime_' + node.getAjxpMime()); } } var additionalStyle = { /*transition:'background-color 250ms cubic-bezier(0.23, 1, 0.32, 1) 0ms, color 250ms cubic-bezier(0.23, 1, 0.32, 1) 0ms'*/ }; if (this.state && this.state.hover && !this.props.noHover) { additionalStyle = _extends({}, additionalStyle, { backgroundColor: 'rgba(0,0,0,0.05)', borderBottom: '1px solid transparent' }); } if (selected) { var selectionColor = this.props.muiTheme.palette.accent2Color; var selectionColorDark = _color2['default'](selectionColor).dark(); additionalStyle = _extends({}, additionalStyle, { backgroundColor: selectionColor, color: selectionColorDark ? 'white' : 'rgba(0,0,0,.87)' }); mainClasses.push('selected'); mainClasses.push('selected-' + (selectionColorDark ? 'dark' : 'light')); } return React.createElement( ContextMenuWrapper, _extends({}, this.props, { ref: function (instance) { var node = _reactDom2['default'].findDOMNode(instance); if (typeof connectDropTarget === 'function') connectDropTarget(node); if (typeof connectDragSource === 'function') connectDragSource(node); }, onClick: this.onClick.bind(this), onDoubleClick: showSelector ? null : this.onDoubleClick.bind(this), className: mainClasses.join(' '), onMouseOver: function () { _this.setState({ hover: true }); }, onMouseOut: function () { _this.setState({ hover: false }); }, style: _extends({}, style, additionalStyle) }), selector, React.createElement( 'div', { className: "material-list-icon" + (mainIcon || iconCell ? "" : " material-list-icon-none") }, icon ), React.createElement( 'div', { className: 'material-list-text' }, React.createElement( 'div', { key: 'line-1', className: 'material-list-line-1' }, firstLine ), React.createElement( 'div', { key: 'line-2', className: 'material-list-line-2' }, secondLine ), React.createElement( 'div', { key: 'line-3', className: 'material-list-line-3' }, thirdLine ) ), React.createElement( 'div', { className: 'material-list-actions' }, actions ) ); }; return ListEntry; })(React.Component); var ContextMenuWrapper = function ContextMenuWrapper(props) { return React.createElement('div', props); }; ContextMenuWrapper = PydioHOCs.withContextMenu(ContextMenuWrapper); ListEntry.propTypes = { showSelector: React.PropTypes.bool, selected: React.PropTypes.bool, selectorDisabled: React.PropTypes.bool, onSelect: React.PropTypes.func, onClick: React.PropTypes.func, iconCell: React.PropTypes.element, mainIcon: React.PropTypes.string, firstLine: React.PropTypes.node, secondLine: React.PropTypes.node, thirdLine: React.PropTypes.node, actions: React.PropTypes.element, activeDroppable: React.PropTypes.bool, className: React.PropTypes.string, style: React.PropTypes.object, noHover: React.PropTypes.bool }; exports.ListEntry = ListEntry = _materialUiStyles.muiThemeable()(ListEntry); var DragDropListEntry = _reactDnd.flow(_reactDnd.DragSource(_utilDND.Types.NODE_PROVIDER, _utilDND.nodeDragSource, _utilDND.collect), _reactDnd.DropTarget(_utilDND.Types.NODE_PROVIDER, _utilDND.nodeDropTarget, _utilDND.collectDrop))(ListEntry); exports.DragDropListEntry = DragDropListEntry; exports.ListEntry = ListEntry; },{"../util/DND":47,"color":"color","material-ui":"material-ui","material-ui/styles":"material-ui/styles","react-dnd":"react-dnd","react-dom":"react-dom"}],16:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ "use strict"; exports.__esModule = true; exports["default"] = { attach: function attach(node) { this._nodeListener = (function () { if (!this.isMounted()) { this.detach(node); return; } this.forceUpdate(); }).bind(this); this._actionListener = (function (eventMemo) { if (!this.isMounted()) { this.detach(node); return; } if (eventMemo && eventMemo.type === 'prompt-rename' && eventMemo.callback) { this.setState({ inlineEdition: true, inlineEditionCallback: eventMemo.callback }); } return true; }).bind(this); node.observe("node_replaced", this._nodeListener); node.observe("node_action", this._actionListener); }, detach: function detach(node) { if (this._nodeListener) { node.stopObserving("node_replaced", this._nodeListener); node.stopObserving("node_action", this._actionListener); } }, componentDidMount: function componentDidMount() { this.attach(this.props.node); }, componentWillUnmount: function componentWillUnmount() { this.detach(this.props.node); } }; module.exports = exports["default"]; },{}],17:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ "use strict"; exports.__esModule = true; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } var _utilMessagesConsumerMixin = require('../util/MessagesConsumerMixin'); var _utilMessagesConsumerMixin2 = _interopRequireDefault(_utilMessagesConsumerMixin); /** * Pagination component reading metadata "paginationData" from current node. */ exports["default"] = React.createClass({ displayName: "ListPaginator", mixins: [_utilMessagesConsumerMixin2["default"]], propTypes: { dataModel: React.PropTypes.instanceOf(PydioDataModel).isRequired, node: React.PropTypes.instanceOf(AjxpNode) }, componentDidMount: function componentDidMount() { var _this = this; if (!this.props.node) { (function () { var dm = _this.props.dataModel; _this._dmObserver = (function () { this.setState({ node: dm.getContextNode() }); }).bind(_this); dm.observe("context_changed", _this._dmObserver); _this.setState({ node: dm.getContextNode() }); })(); } }, componentWillUnmount: function componentWillUnmount() { if (this._dmObserver) { this.props.dataModel.stopObserving("context_changed", this._dmObserver); } }, getInitialState: function getInitialState() { return { node: this.props.node }; }, changePage: function changePage(event) { this.state.node.getMetadata().get("paginationData").set("new_page", event.currentTarget.getAttribute('data-page')); this.props.dataModel.requireContextChange(this.state.node); }, onMenuChange: function onMenuChange(event, index, item) { this.state.node.getMetadata().get("paginationData").set("new_page", item.payload); this.props.dataModel.requireContextChange(this.state.node); }, render: function render() { if (!this.state.node || !this.state.node.getMetadata().get("paginationData")) { return null; } var pData = this.state.node.getMetadata().get("paginationData"); var current = parseInt(pData.get("current")); var total = parseInt(pData.get("total")); var pages = [], next, last, previous, first; var pageWord = this.context.getMessage ? this.context.getMessage('331', '') : this.props.getMessage('331', ''); for (var i = 1; i <= total; i++) { pages.push({ payload: i, text: pageWord + ' ' + i + (i == current ? ' / ' + total : '') }); } if (pages.length <= 1) { return null; } var sep = undefined; if (this.props.toolbarDisplay) { if (current > 1) previous = React.createElement( "span", { className: "toolbars-button-menu" }, React.createElement(ReactMUI.IconButton, { onClick: this.changePage, "data-page": current - 1, iconClassName: "icon-caret-left" }) ); if (current < total) next = React.createElement( "span", { className: "toolbars-button-menu" }, React.createElement(ReactMUI.IconButton, { onClick: this.changePage, "data-page": current + 1, iconClassName: "icon-caret-right" }) ); } else { if (current > 1) previous = React.createElement(ReactMUI.FontIcon, { onClick: this.changePage, "data-page": current - 1, className: "icon-angle-left" }); if (current < total) next = React.createElement(ReactMUI.FontIcon, { onClick: this.changePage, "data-page": current + 1, className: "icon-angle-right" }); sep = React.createElement( "span", { className: "mui-toolbar-separator" }, " " ); } return React.createElement( "span", { id: this.props.id, style: this.props.style }, first, previous, React.createElement(ReactMUI.DropDownMenu, { onChange: this.onMenuChange, menuItems: pages, selectedIndex: current - 1 }), next, last, sep ); } }); module.exports = exports["default"]; },{"../util/MessagesConsumerMixin":48}],18:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ "use strict"; exports.__esModule = 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; }; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } var _SimpleList = require('./SimpleList'); var _SimpleList2 = _interopRequireDefault(_SimpleList); /** * Simple to use list component encapsulated with its own query mechanism * using a set of properties for the remote node provider. */ exports["default"] = React.createClass({ displayName: "NodeListCustomProvider", propTypes: { nodeProviderProperties: React.PropTypes.object, presetDataModel: React.PropTypes.instanceOf(PydioDataModel), autoRefresh: React.PropTypes.number, actionBarGroups: React.PropTypes.array, heightAutoWithMax: React.PropTypes.number, elementHeight: React.PropTypes.number.isRequired, nodeClicked: React.PropTypes.func, reloadOnServerMessage: React.PropTypes.string, entryRenderAsCard: React.PropTypes.func }, reload: function reload() { if (this.refs.list && this.isMounted()) { this.refs.list.reload(); } }, componentWillUnmount: function componentWillUnmount() { if (this._smObs) { this.props.pydio.stopObserving("server_message", this._smObs); this.props.pydio.stopObserving("server_message:" + this.props.reloadOnServerMessage, this.reload); } }, componentWillReceiveProps: function componentWillReceiveProps(nextProps) { if (this.props.nodeProviderProperties && this.props.nodeProviderProperties !== nextProps.nodeProviderProperties) { var _state = this.state; var dataModel = _state.dataModel; var node = _state.node; var provider = new RemoteNodeProvider(nextProps.nodeProviderProperties); dataModel.setAjxpNodeProvider(provider); node.updateProvider(provider); this.setState({ dataModel: dataModel, node: node }); } else if (this.props.presetDataModel !== nextProps.presetDataModel) { this.setState({ dataModel: nextProps.presetDataModel, node: nextProps.presetDataModel.getRootNode() }); } }, getInitialState: function getInitialState() { var dataModel = undefined; if (this.props.presetDataModel) { dataModel = this.props.presetDataModel; } else { dataModel = PydioDataModel.RemoteDataModelFactory(this.props.nodeProviderProperties); } var rootNode = dataModel.getRootNode(); if (this.props.nodeClicked) { // leaf this.openEditor = (function (node) { this.props.nodeClicked(node); return false; }).bind(this); // dir dataModel.observe("selection_changed", (function (event) { var selectedNodes = event.memo.getSelectedNodes(); if (selectedNodes.length) { this.props.nodeClicked(selectedNodes[0]); event.memo.setSelectedNodes([]); } }).bind(this)); } if (this.props.reloadOnServerMessage && this.props.pydio) { this._smObs = (function (event) { if (XMLUtils.XPathSelectSingleNode(event, this.props.reloadOnServerMessage)) this.reload(); }).bind(this); this.props.pydio.observe("server_message", this._smObs); this.props.pydio.observe("server_message:" + this.props.reloadOnServerMessage, this.reload); } return { node: rootNode, dataModel: dataModel }; }, render: function render() { var legend; if (this.props.legend) { legend = React.createElement( "div", { className: "subtitle" }, this.props.legend ); } return React.createElement( "div", { className: this.props.heightAutoWithMax ? "" : "layout-fill vertical-layout" }, React.createElement(_SimpleList2["default"], _extends({}, this.props, { openEditor: this.openEditor, ref: "list", style: Object.assign({ height: '100%' }, this.props.style || {}), node: this.state.node, dataModel: this.state.dataModel, actionBarGroups: this.props.actionBarGroups, skipParentNavigation: true, observeNodeReload: true })) ); } }); module.exports = exports["default"]; },{"./SimpleList":19}],19:[function(require,module,exports){ (function (global){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = 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; }; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } var _reactScrollbar = require('react-scrollbar'); var _reactScrollbar2 = _interopRequireDefault(_reactScrollbar); var _utilMessagesConsumerMixin = require('../util/MessagesConsumerMixin'); var _utilMessagesConsumerMixin2 = _interopRequireDefault(_utilMessagesConsumerMixin); var _ListEntry = require('./ListEntry'); var _TableListEntry = require('./TableListEntry'); var _TableListEntry2 = _interopRequireDefault(_TableListEntry); var _TableListHeader = require('./TableListHeader'); var _TableListHeader2 = _interopRequireDefault(_TableListHeader); var _ConfigurableListEntry = require('./ConfigurableListEntry'); var _ConfigurableListEntry2 = _interopRequireDefault(_ConfigurableListEntry); var _SortColumns = require('./SortColumns'); var _SortColumns2 = _interopRequireDefault(_SortColumns); var _ListPaginator = require('./ListPaginator'); var _ListPaginator2 = _interopRequireDefault(_ListPaginator); var _viewsSimpleReactActionBar = require('../views/SimpleReactActionBar'); var _viewsSimpleReactActionBar2 = _interopRequireDefault(_viewsSimpleReactActionBar); var _InlineEditor = require('./InlineEditor'); var _InlineEditor2 = _interopRequireDefault(_InlineEditor); var _viewsEmptyStateView = require('../views/EmptyStateView'); var _viewsEmptyStateView2 = _interopRequireDefault(_viewsEmptyStateView); var React = require('react'); var Infinite = require('react-infinite'); var DOMUtils = require('pydio/util/dom'); var LangUtils = require('pydio/util/lang'); var PydioDataModel = require('pydio/model/data-model'); var PeriodicalExecuter = require('pydio/util/periodical-executer'); /** * Generic List component, using Infinite for cell virtualization, pagination, various * displays, etc... It provides many hooks for rendering cells on-demand. */ var SimpleList = React.createClass({ displayName: 'SimpleList', mixins: [_utilMessagesConsumerMixin2['default']], propTypes: { infiniteSliceCount: React.PropTypes.number, filterNodes: React.PropTypes.func, customToolbar: React.PropTypes.object, tableKeys: React.PropTypes.object, autoRefresh: React.PropTypes.number, reloadAtCursor: React.PropTypes.bool, clearSelectionOnReload: React.PropTypes.bool, heightAutoWithMax: React.PropTypes.number, containerHeight: React.PropTypes.number, observeNodeReload: React.PropTypes.bool, defaultGroupBy: React.PropTypes.string, defaultGroupByLabel: React.PropTypes.string, defaultSortingInfo: React.PropTypes.object, skipParentNavigation: React.PropTypes.bool, skipInternalDataModel: React.PropTypes.bool, delayInitialLoad: React.PropTypes.number, entryEnableSelector: React.PropTypes.func, renderCustomEntry: React.PropTypes.func, entryRenderIcon: React.PropTypes.func, entryRenderActions: React.PropTypes.func, entryRenderFirstLine: React.PropTypes.func, entryRenderSecondLine: React.PropTypes.func, entryRenderThirdLine: React.PropTypes.func, entryHandleClicks: React.PropTypes.func, hideToolbar: React.PropTypes.bool, computeActionsForNode: React.PropTypes.bool, multipleActions: React.PropTypes.array, openEditor: React.PropTypes.func, openCollection: React.PropTypes.func, elementStyle: React.PropTypes.object, passScrollingStateToChildren: React.PropTypes.bool, elementHeight: React.PropTypes.oneOfType([React.PropTypes.number, React.PropTypes.object]).isRequired }, statics: { HEIGHT_ONE_LINE: 50, HEIGHT_TWO_LINES: 73, CLICK_TYPE_SIMPLE: 'simple', CLICK_TYPE_DOUBLE: 'double', PARENT_FOLDER_ICON: 'mdi mdi-chevron-left' }, getDefaultProps: function getDefaultProps() { return { infiniteSliceCount: 30, clearSelectionOnReload: true }; }, clickRow: function clickRow(gridRow, event) { var node = undefined; if (gridRow.props) { node = gridRow.props.data.node; } else { node = gridRow; } if (this.props.entryHandleClicks) { this.props.entryHandleClicks(node, SimpleList.CLICK_TYPE_SIMPLE, event); return; } if (node.isLeaf() && this.props.openEditor) { if (this.props.openEditor(node) === false) { return; } var uniqueSelection = new Map(); uniqueSelection.set(node, true); this.setState({ selection: uniqueSelection }, this.rebuildLoadedElements); } else if (!node.isLeaf()) { if (this.props.openCollection) { this.props.openCollection(node); } else { this.props.dataModel.setSelectedNodes([node]); } } }, doubleClickRow: function doubleClickRow(gridRow, event) { var node = undefined; if (gridRow.props) { node = gridRow.props.data.node; } else { node = gridRow; } if (this.props.entryHandleClicks) { this.props.entryHandleClicks(node, SimpleList.CLICK_TYPE_DOUBLE, event); } }, onColumnSort: function onColumnSort(column) { var stateSetCallback = arguments.length <= 1 || arguments[1] === undefined ? null : arguments[1]; var pagination = this.props.node.getMetadata().get('paginationData'); if (pagination && pagination.get('total') > 1 && pagination.get('remote_order')) { var dir = 'asc'; if (this.props.node.getMetadata().get('paginationData').get('currentOrderDir')) { dir = this.props.node.getMetadata().get('paginationData').get('currentOrderDir') === 'asc' ? 'desc' : 'asc'; } var orderData = new Map(); orderData.set('order_column', column['remoteSortAttribute'] ? column.remoteSortAttribute : column.name); orderData.set('order_direction', dir); this.props.node.getMetadata().set("remote_order", orderData); this.props.dataModel.requireContextChange(this.props.node, true); } else { var att = column['sortAttribute'] ? column['sortAttribute'] : column.name; var sortingInfo = undefined; var _state$sortingInfo = this.state.sortingInfo; var attribute = _state$sortingInfo.attribute; var direction = _state$sortingInfo.direction; if (attribute === att && direction) { if (direction === 'asc') { // Switch direction sortingInfo = { attribute: att, sortType: column.sortType, direction: 'desc' }; } else { // Reset sorting sortingInfo = this.props.defaultSortingInfo || {}; } } else { sortingInfo = { attribute: att, sortType: column.sortType, direction: 'asc' }; } this.setState({ sortingInfo: sortingInfo }, (function () { this.rebuildLoadedElements(); if (stateSetCallback) { stateSetCallback(); } }).bind(this)); } }, computeSelectionFromCurrentPlusTargetNode: function computeSelectionFromCurrentPlusTargetNode(currentSelection, targetNode) { var currentIndexStart = undefined, currentIndexEnd = undefined, nodeBefore = false; if (!this.indexedElements) { return []; } var firstSelected = currentSelection[0]; var lastSelected = currentSelection[currentSelection.length - 1]; var newSelection = []; for (var i = 0; i < this.indexedElements.length; i++) { if (currentIndexStart !== undefined) { newSelection.push(this.indexedElements[i].node); } if (this.indexedElements[i].node === targetNode) { if (currentIndexStart !== undefined && currentIndexEnd === undefined) { currentIndexEnd = i; break; } currentIndexStart = i; nodeBefore = true; newSelection.push(this.indexedElements[i].node); } if (this.indexedElements[i].node === firstSelected && currentIndexStart === undefined) { currentIndexStart = i; newSelection.push(this.indexedElements[i].node); } if (this.indexedElements[i].node === lastSelected && nodeBefore) { currentIndexEnd = i; break; } } return newSelection; }, onKeyDown: function onKeyDown(e) { var currentIndexStart = undefined, currentIndexEnd = undefined; var contextHolder = window.pydio.getContextHolder(); var elementsPerLine = this.props.elementsPerLine || 1; var shiftKey = e.shiftKey; var key = e.key; if (contextHolder.isEmpty() || !this.indexedElements) { return; } var downKeys = ['ArrowDown', 'ArrowRight', 'PageDown', 'End']; var position = shiftKey && downKeys.indexOf(key) > -1 ? 'first' : 'last'; var currentSelection = contextHolder.getSelectedNodes(); var firstSelected = currentSelection[0]; var lastSelected = currentSelection[currentSelection.length - 1]; if (key === 'Enter') { this.doubleClickRow(firstSelected); return; } if (key === 'Delete' && global.pydio.Controller.fireActionByKey('key_delete')) { return; } for (var i = 0; i < this.indexedElements.length; i++) { if (this.indexedElements[i].node === firstSelected) { currentIndexStart = i; } if (this.indexedElements[i].node === lastSelected) { currentIndexEnd = i; break; } } var selectionIndex = undefined; var maxIndex = this.indexedElements.length - 1; var increment = key === 'PageDown' || key === 'PageUp' ? 10 : 1; if (key === 'ArrowDown' || key === 'PageDown') { selectionIndex = Math.min(currentIndexEnd + elementsPerLine * increment, maxIndex); } else if (key === 'ArrowUp' || key === 'PageUp') { selectionIndex = Math.max(currentIndexStart - elementsPerLine * increment, 0); } else if (key === 'Home') { selectionIndex = 0; } else if (key === 'End') { selectionIndex = maxIndex; } if (elementsPerLine > 1) { if (key === 'ArrowRight') { selectionIndex = currentIndexEnd + 1; } else if (key === 'ArrowLeft') { selectionIndex = currentIndexStart - 1; } } if (shiftKey && selectionIndex !== undefined) { var min = Math.min(currentIndexStart, currentIndexEnd, selectionIndex); var max = Math.max(currentIndexStart, currentIndexEnd, selectionIndex); if (min !== max) { var selection = []; for (var i = min; i < max + 1; i++) { if (this.indexedElements[i]) selection.push(this.indexedElements[i].node); } contextHolder.setSelectedNodes(selection); } } else if (this.indexedElements[selectionIndex] && this.indexedElements[selectionIndex].node) { contextHolder.setSelectedNodes([this.indexedElements[selectionIndex].node]); } }, getInitialState: function getInitialState() { this.actionsCache = { multiple: new Map() }; if (!this.props.skipInternalDataModel) { this.dm = new PydioDataModel(); this.dm.setRootNode(this.props.dataModel.getContextNode()); this.dm.setContextNode(this.props.dataModel.getContextNode()); } else { this.dm = this.props.dataModel; } var sortingInfo = this.props.defaultSortingInfo || null; var state = { loaded: this.props.node.isLoaded(), loading: !this.props.node.isLoaded(), showSelector: false, elements: this.props.node.isLoaded() ? this.buildElements(sortingInfo, 0, this.props.infiniteSliceCount) : [], containerHeight: this.props.containerHeight ? this.props.containerHeight : this.props.heightAutoWithMax ? 0 : 500, sortingInfo: sortingInfo }; if (this.props.elementHeight instanceof Object) { state.elementHeight = this.computeElementHeightResponsive(); } state.infiniteLoadBeginBottomOffset = 200; return state; }, componentWillReceiveProps: function componentWillReceiveProps(nextProps) { var _this = this; this.indexedElements = null; var currentLength = Math.max(this.state.elements.length, nextProps.infiniteSliceCount); var sortingInfo = this.state.sortingInfo || nextProps.defaultSortingInfo || null; this.setState({ loaded: nextProps.node.isLoaded(), loading: !nextProps.node.isLoaded(), showSelector: false, elements: nextProps.node.isLoaded() ? this.buildElements(sortingInfo, 0, currentLength, nextProps.node) : [], infiniteLoadBeginBottomOffset: 200, sortingInfo: sortingInfo }, function () { if (nextProps.node.isLoaded()) _this.updateInfiniteContainerHeight(); }); if (!nextProps.autoRefresh && this.refreshInterval) { window.clearInterval(this.refreshInterval); this.refreshInterval = null; } else if (nextProps.autoRefresh && !this.refreshInterval) { this.refreshInterval = window.setInterval(this.reload, nextProps.autoRefresh); } this.patchInfiniteGrid(nextProps.elementsPerLine); if (this.props.node && nextProps.node !== this.props.node) { this.observeNodeChildren(this.props.node, true); } if (this._manualScrollPe) { this._manualScrollPe.stop(); this._manualScrollPe = null; } }, observeNodeChildren: function observeNodeChildren(node) { var stop = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1]; if (stop && !this._childrenObserver) return; if (!this._childrenObserver) { this._childrenObserver = (function () { this.indexedElements = null; this.rebuildLoadedElements(); }).bind(this); } if (!this._childrenActionsObserver) { this._childrenActionsObserver = (function (eventMemo) { if (eventMemo.type === 'prompt-rename') { this.setState({ inlineEditionForNode: eventMemo.child, inlineEditionCallback: eventMemo.callback }); } }).bind(this); } if (stop) { node.stopObserving("child_added", this._childrenObserver); node.stopObserving("child_removed", this._childrenObserver); node.stopObserving("child_node_action", this._childrenActionsObserver); } else { node.observe("child_added", this._childrenObserver); node.observe("child_removed", this._childrenObserver); node.observe("child_node_action", this._childrenActionsObserver); } }, _loadNodeIfNotLoaded: function _loadNodeIfNotLoaded() { var node = this.props.node; if (!node.isLoaded()) { node.observeOnce("loaded", (function () { if (!this.isMounted()) return; if (this.props.node === node) { this.observeNodeChildren(node); this.setState({ loaded: true, loading: false, elements: this.buildElements(this.state.sortingInfo, 0, this.props.infiniteSliceCount) }); } if (this.props.heightAutoWithMax) { this.updateInfiniteContainerHeight(); } }).bind(this)); node.load(); } else { this.observeNodeChildren(node); } }, _loadingListener: function _loadingListener() { this.observeNodeChildren(this.props.node, true); this.setState({ loaded: false, loading: true }); this.indexedElements = null; }, _loadedListener: function _loadedListener() { var currentLength = Math.max(this.state.elements.length, this.props.infiniteSliceCount); this.setState({ loading: false, elements: this.buildElements(this.state.sortingInfo, 0, currentLength, this.props.node) }); if (this.props.heightAutoWithMax) { this.updateInfiniteContainerHeight(); } this.observeNodeChildren(this.props.node); }, reload: function reload() { if (this.props.reloadAtCursor && this._currentCursor) { this.loadStartingAtCursor(); return; } if (this.props.clearSelectionOnReload) { this.props.dataModel.setSelectedNodes([]); } this._loadingListener(); this.props.node.observeOnce("loaded", this._loadedListener); this.props.node.reload(); }, loadStartingAtCursor: function loadStartingAtCursor() { this._loadingListener(); var node = this.props.node; var cachedChildren = node.getChildren(); var newChildren = []; node.observeOnce("loaded", (function () { var reorderedChildren = new Map(); newChildren.map(function (c) { reorderedChildren.set(c.getPath(), c); }); cachedChildren.forEach(function (c) { reorderedChildren.set(c.getPath(), c); }); node._children = reorderedChildren; this._loadedListener(); }).bind(this)); node.setLoaded(false); node.observe("child_added", function (newChild) { newChildren.push(node._children.get(newChild)); }); this.props.node.load(null, { cursor: this._currentCursor }); }, wireReloadListeners: function wireReloadListeners() { this.wrappedLoading = this._loadingListener; this.wrappedLoaded = this._loadedListener; this.props.node.observe("loading", this.wrappedLoading); this.props.node.observe("loaded", this.wrappedLoaded); }, stopReloadListeners: function stopReloadListeners() { this.props.node.stopObserving("loading", this.wrappedLoading); this.props.node.stopObserving("loaded", this.wrappedLoaded); }, toggleSelector: function toggleSelector() { // Force rebuild elements this.setState({ showSelector: !this.state.showSelector, selection: new Map() }, this.rebuildLoadedElements); }, toggleSelection: function toggleSelection(node) { var selection = this.state.selection || new Map(); if (selection.get(node)) selection['delete'](node);else selection.set(node, true); if (this.refs.all_selector) this.refs.all_selector.setChecked(false); this.setState({ selection: selection }, this.rebuildLoadedElements); }, selectAll: function selectAll() { var _this2 = this; if (this.refs.all_selector && !this.refs.all_selector.isChecked()) { this.setState({ selection: new Map() }, this.rebuildLoadedElements); } else { (function () { var selection = new Map(); _this2.props.node.getChildren().forEach((function (child) { if (this.props.filterNodes && !this.props.filterNodes(child)) { return; } if (child.isLeaf()) { selection.set(child, true); } }).bind(_this2)); if (_this2.refs.all_selector) _this2.refs.all_selector.setChecked(true); _this2.setState({ selection: selection }, _this2.rebuildLoadedElements); })(); } }, applyMultipleAction: function applyMultipleAction(ev) { if (!this.state.selection || !this.state.selection.size) { return; } var actionName = ev.currentTarget.getAttribute('data-action'); var dm = this.dm || new PydioDataModel(); dm.setContextNode(this.props.node); var selNodes = []; this.state.selection.forEach(function (v, node) { selNodes.push(node); }); dm.setSelectedNodes(selNodes); var a = this.props.pydio.Controller.getActionByName(actionName); a.fireContextChange(dm, true, this.props.pydio.user); a.apply([dm]); ev.stopPropagation(); ev.preventDefault(); }, getActionsForNode: function getActionsForNode(dm, node) { if (!this.props.computeActionsForNode) { return []; } var cacheKey = node.isLeaf() ? 'file-' + node.getAjxpMime() : 'folder'; var selectionType = node.isLeaf() ? 'file' : 'dir'; var nodeActions = []; if (this.actionsCache[cacheKey]) { nodeActions = this.actionsCache[cacheKey]; } else { dm.setSelectedNodes([node]); window.pydio.Controller.actions.forEach((function (a) { a.fireContextChange(dm, true, window.pydio.user); if (a.context.selection && a.context.actionBar && a.selectionContext[selectionType] && !a.deny && a.options.icon_class && (!this.props.actionBarGroups || this.props.actionBarGroups.indexOf(a.context.actionBarGroup) !== -1) && (!a.selectionContext.allowedMimes.length || a.selectionContext.allowedMimes.indexOf(node.getAjxpMime()) !== -1)) { nodeActions.push(a); if (node.isLeaf() && a.selectionContext.unique === false) { this.actionsCache.multiple.set(a.options.name, a); } } }).bind(this)); this.actionsCache[cacheKey] = nodeActions; } return nodeActions; }, updateInfiniteContainerHeight: function updateInfiniteContainerHeight() { var retries = arguments.length <= 0 || arguments[0] === undefined ? false : arguments[0]; if (this.props.containerHeight) { return this.props.containerHeight; } if (!this.refs.infiniteParent) { return; } var containerHeight = this.refs.infiniteParent.clientHeight; if (this.props.heightAutoWithMax) { var number = this.indexedElements ? this.indexedElements.length : this.props.node.getChildren().size; var elementHeight = this.state.elementHeight ? this.state.elementHeight : this.props.elementHeight; containerHeight = Math.min(number * elementHeight, this.props.heightAutoWithMax); } if (!containerHeight && !retries) { global.setTimeout((function () { this.updateInfiniteContainerHeight(true); }).bind(this), 50); } this.setState({ containerHeight: containerHeight }); }, computeElementHeightResponsive: function computeElementHeightResponsive() { var breaks = this.props.elementHeight; if (!(breaks instanceof Object)) { breaks = { "min-width:480px": this.props.elementHeight, "max-width:480px": Object.keys(this.props.tableKeys).length * 24 + 33 }; } if (window.matchMedia) { for (var k in breaks) { if (breaks.hasOwnProperty(k) && window.matchMedia('(' + k + ')').matches) { return breaks[k]; } } } else { var width = DOMUtils.getViewportWidth(); if (width < 480) return breaks["max-width:480px"];else return breaks["max-width:480px"]; } return 50; }, updateElementHeightResponsive: function updateElementHeightResponsive() { var newH = this.computeElementHeightResponsive(); if (!this.state || !this.state.elementHeight || this.state.elementHeight != newH) { this.setState({ elementHeight: newH }, (function () { if (this.props.heightAutoWithMax) { this.updateInfiniteContainerHeight(); } }).bind(this)); } }, patchInfiniteGrid: function patchInfiniteGrid(els) { if (this.refs.infinite && els > 1) { this.refs.infinite.state.infiniteComputer.__proto__.getDisplayIndexStart = function (windowTop) { return els * Math.floor(windowTop / this.heightData / els); }; this.refs.infinite.state.infiniteComputer.__proto__.getDisplayIndexEnd = function (windowBottom) { return els * Math.ceil(windowBottom / this.heightData / els); }; } }, componentDidMount: function componentDidMount() { var _this3 = this; if (this.props.delayInitialLoad) { setTimeout(function () { _this3._loadNodeIfNotLoaded(); }, this.props.delayInitialLoad); } else { this._loadNodeIfNotLoaded(); } this.patchInfiniteGrid(this.props.elementsPerLine); if (this.refs.infiniteParent) { this.updateInfiniteContainerHeight(); if (!this.props.heightAutoWithMax && !this.props.externalResize) { if (window.addEventListener) { window.addEventListener('resize', this.updateInfiniteContainerHeight); } else { window.attachEvent('onresize', this.updateInfiniteContainerHeight); } } } if (this.props.autoRefresh) { this.refreshInterval = window.setInterval(this.reload, this.props.autoRefresh); } if (this.props.observeNodeReload) { this.wireReloadListeners(); } if (this.props.elementHeight instanceof Object || this.props.tableKeys) { if (window.addEventListener) { window.addEventListener('resize', this.updateElementHeightResponsive); } else { window.attachEvent('onresize', this.updateElementHeightResponsive); } this.updateElementHeightResponsive(); } this.props.dataModel.observe('selection_changed', (function () { var _this4 = this; if (!this.isMounted()) return; var selection = new Map(); var selectedNodes = this.props.dataModel.getSelectedNodes(); selectedNodes.map(function (n) { selection.set(n, true); }); this.setState({ selection: selection }, function () { _this4.rebuildLoadedElements(); if (selectedNodes.length === 1) { _this4.scrollToView(selectedNodes[0]); } }); }).bind(this)); }, componentWillUnmount: function componentWillUnmount() { if (!this.props.heightAutoWithMax) { if (window.removeEventListener) { window.removeEventListener('resize', this.updateInfiniteContainerHeight); } else { window.detachEvent('onresize', this.updateInfiniteContainerHeight); } } if (this.props.elementHeight instanceof Object || this.props.tableKeys) { if (window.removeEventListener) { window.removeEventListener('resize', this.updateElementHeightResponsive); } else { window.detachEvent('resize', this.updateElementHeightResponsive); } } if (this.refreshInterval) { window.clearInterval(this.refreshInterval); } if (this.props.observeNodeReload) { this.stopReloadListeners(); } if (this.props.node) { this.observeNodeChildren(this.props.node, true); } }, componentDidUpdate: function componentDidUpdate(prevProps, prevState) { if (prevProps.node && this.props.node && prevProps.node.getPath() === this.props.node.getPath()) { return; } this._loadNodeIfNotLoaded(); }, onScroll: function onScroll(scrollTop) { if (!this.props.passScrollingStateToChildren) { return; } // Maintains a series of timeouts to set this.state.isScrolling // to be true when the element is scrolling. if (this.state.scrollTimeout) { clearTimeout(this.state.scrollTimeout); } var that = this, scrollTimeout = setTimeout(function () { that.setState({ isScrolling: false, scrollTimeout: undefined }); }, 150); this.setState({ isScrolling: true, scrollTimeout: scrollTimeout }); }, scrollToLast: function scrollToLast() { if (this.indexedElements && this.indexedElements[this.indexedElements.length - 1].node) { this.scrollToView(this.indexedElements[this.indexedElements.length - 1].node); } }, scrollToView: function scrollToView(node) { var _this5 = this; if (!this.indexedElements || !this.refs.infinite || !this.refs.infinite.scrollable) return; var scrollable = this.refs.infinite.scrollable; var visibleFrame = { top: scrollable.scrollTop + this.props.elementHeight / 2, bottom: scrollable.scrollTop + this.state.containerHeight - this.props.elementHeight / 2 }; var realMaxScrollTop = this.indexedElements.length * this.props.elementHeight - this.state.containerHeight; var position = -1; this.indexedElements.forEach(function (e, k) { if (e.node && e.node === node) position = k; }); if (position === -1) return; var elementHeight = this.props.elementHeight; var scrollTarget = position * elementHeight; if (scrollTarget > visibleFrame.top && scrollTarget < visibleFrame.bottom) { // already visible; return; } else if (scrollTarget >= visibleFrame.bottom) { scrollTarget -= this.state.containerHeight - elementHeight * 2; } scrollTarget = Math.min(scrollTarget, realMaxScrollTop); scrollable.scrollTop = scrollTarget; if (this._manualScrollPe) this._manualScrollPe.stop(); if (scrollable.scrollHeight < scrollTarget) { this._manualScrollPe = new PeriodicalExecuter(function () { scrollable.scrollTop = scrollTarget; if (scrollable.scrollHeight >= scrollTarget) { _this5._manualScrollPe.stop(); _this5._manualScrollPe = null; } }, .25); } }, buildElementsFromNodeEntries: function buildElementsFromNodeEntries(nodeEntries, showSelector) { var components = [], index = 0; var nodeEntriesLength = nodeEntries.length; nodeEntries.forEach((function (entry) { var data = undefined; if (entry.parent) { data = { node: entry.node, key: entry.node.getPath(), id: entry.node.getPath(), mainIcon: SimpleList.PARENT_FOLDER_ICON, firstLine: "..", className: "list-parent-node", secondLine: this.context.getMessage('react.1'), onClick: this.clickRow, onDoubleClick: this.doubleClickRow, showSelector: false, selectorDisabled: true, noHover: false }; if (this.props.entryRenderParentIcon && !this.props.tableKeys) { data['iconCell'] = this.props.entryRenderParentIcon(entry.node, entry); } else { data['mainIcon'] = SimpleList.PARENT_FOLDER_ICON; } if (this.props.elementStyle) { data['style'] = this.props.elementStyle; } if (this.props.passScrollingStateToChildren) { data['parentIsScrolling'] = this.state.isScrolling; } components.push(React.createElement(_ListEntry.ListEntry, data)); } else if (entry.groupHeader) { var id = entry.groupHeader, firstLine = entry.groupHeaderLabel; if (this.props.entryRenderGroupHeader) { firstLine = this.props.entryRenderGroupHeader(id, firstLine); } data = { node: null, key: entry.groupHeader, id: id, mainIcon: null, firstLine: firstLine, className: 'list-group-header', onClick: null, showSelector: false, selectorDisabled: true, noHover: true }; if (this.props.passScrollingStateToChildren) { data['parentIsScrolling'] = this.state.isScrolling; } components.push(React.createElement(_ListEntry.ListEntry, data)); } else { data = { node: entry.node, onClick: this.clickRow, onDoubleClick: this.doubleClickRow, onSelect: this.toggleSelection, key: entry.node.getPath(), id: entry.node.getPath(), renderIcon: this.props.entryRenderIcon, renderFirstLine: this.props.entryRenderFirstLine, renderSecondLine: this.props.entryRenderSecondLine, renderThirdLine: this.props.entryRenderThirdLine, renderActions: this.props.entryRenderActions, showSelector: showSelector, selected: this.state && this.state.selection ? this.state.selection.get(entry.node) : false, actions: React.createElement(_viewsSimpleReactActionBar2['default'], { node: entry.node, actions: entry.actions, dataModel: this.dm }), selectorDisabled: !(this.props.entryEnableSelector ? this.props.entryEnableSelector(entry.node) : entry.node.isLeaf()) }; data['isFirst'] = index === 0; data['isLast'] = index === nodeEntriesLength - 1; index++; if (this.props.elementStyle) { data['style'] = this.props.elementStyle; } if (this.props.passScrollingStateToChildren) { data['parentIsScrolling'] = this.state.isScrolling; } if (this.props.renderCustomEntry) { components.push(this.props.renderCustomEntry(data)); } else if (this.props.tableKeys) { if (this.props.defaultGroupBy) { data['tableKeys'] = LangUtils.deepCopy(this.props.tableKeys); delete data['tableKeys'][this.props.defaultGroupBy]; } else { data['tableKeys'] = this.props.tableKeys; } components.push(React.createElement(_TableListEntry2['default'], data)); } else { components.push(React.createElement(_ConfigurableListEntry2['default'], data)); } } }).bind(this)); return components; }, buildElements: function buildElements(sortingInfo, start, end, node, showSelector) { var _this6 = this; var theNode = this.props.node; if (node) theNode = node; var theShowSelector = this.state && this.state.showSelector; if (showSelector !== undefined) theShowSelector = showSelector; if (!this.indexedElements || this.indexedElements.length !== theNode.getChildren().size) { (function () { _this6.indexedElements = []; var groupBy = undefined, groupByLabel = undefined, groups = undefined, groupKeys = undefined, groupLabels = undefined; if (_this6.props.defaultGroupBy) { groupBy = _this6.props.defaultGroupBy; groupByLabel = _this6.props.groupByLabel || false; groups = {}, groupKeys = [], groupLabels = {}; } if (!_this6.props.skipParentNavigation && theNode.getParent() && (_this6.props.dataModel.getContextNode() !== theNode || _this6.props.skipInternalDataModel)) { _this6.indexedElements.push({ node: theNode.getParent(), parent: true, actions: null }); } theNode.getChildren().forEach((function (child) { if (child.getMetadata().has('cursor')) { var childCursor = parseInt(child.getMetadata().get('cursor')); this._currentCursor = Math.max(this._currentCursor ? this._currentCursor : 0, childCursor); } if (this.props.filterNodes && !this.props.filterNodes(child)) { return; } var nodeActions = this.getActionsForNode(this.dm, child); if (groupBy) { var groupValue = child.getMetadata().get(groupBy) || 'N/A'; if (!groups[groupValue]) { groups[groupValue] = []; groupKeys.push(groupValue); } if (groupByLabel && child.getMetadata().has(groupByLabel) && !groupLabels[groupValue]) { groupLabels[groupValue] = child.getMetadata().get(groupByLabel); } groups[groupValue].push({ node: child, parent: false, actions: nodeActions }); } else { this.indexedElements.push({ node: child, parent: false, actions: nodeActions }); } }).bind(_this6)); if (groupBy) { groupKeys = groupKeys.sort(); groupKeys.map((function (k) { var label = k; if (groupLabels[k]) { label = groupLabels[k]; } else if (this.props.renderGroupLabels) { label = this.props.renderGroupLabels(groupBy, k); } this.indexedElements.push({ node: null, groupHeader: k, groupHeaderLabel: label, parent: false, actions: null }); this.indexedElements = this.indexedElements.concat(groups[k]); }).bind(_this6)); } })(); } if (sortingInfo && !this.remoteSortingInfo()) { (function () { var attribute = sortingInfo.attribute; var direction = sortingInfo.direction; var sortType = sortingInfo.sortType; var sortFunction = undefined; if (sortType === 'file-natural') { sortFunction = function (a, b) { if (a.parent) { return -1; } if (b.parent) { return 1; } var nodeA = a.node; var nodeB = b.node; // Recycle always last if (nodeA.isRecycle()) return 1; if (nodeB.isRecycle()) return -1; // Folders first var aLeaf = nodeA.isLeaf(); var bLeaf = nodeB.isLeaf(); var res = aLeaf && !bLeaf ? 1 : !aLeaf && bLeaf ? -1 : 0; if (res !== 0) return res; res = nodeA.getLabel().localeCompare(nodeB.getLabel()); return res; }; } else { sortFunction = function (a, b) { if (a.parent) { return -1; } var aMeta = a.node.getMetadata().get(attribute) || ""; var bMeta = b.node.getMetadata().get(attribute) || ""; var res = undefined; if (sortType === 'number') { aMeta = parseFloat(aMeta); bMeta = parseFloat(bMeta); res = direction === 'asc' ? aMeta - bMeta : bMeta - aMeta; } else if (sortType === 'string') { res = direction === 'asc' ? aMeta.localeCompare(bMeta) : bMeta.localeCompare(aMeta); } if (res === 0) { // Resort by label to make it stable var labComp = a.node.getLabel().localeCompare(b.node.getLabel()); res = direction === 'asc' ? labComp : -labComp; } return res; }; } _this6.indexedElements.sort(sortFunction); })(); } if (this.props.elementPerLine > 1) { end = end * this.props.elementPerLine; start = start * this.props.elementPerLine; } return this.indexedElements.slice(start, end); }, rebuildLoadedElements: function rebuildLoadedElements() { var newElements = this.buildElements(this.state.sortingInfo, 0, Math.max(this.state.elements.length, this.props.infiniteSliceCount)); var infiniteLoadBeginBottomOffset = newElements.length ? 200 : 0; this.setState({ elements: newElements, infiniteLoadBeginBottomOffset: infiniteLoadBeginBottomOffset }); this.updateInfiniteContainerHeight(); }, handleInfiniteLoad: function handleInfiniteLoad() { var elemLength = this.state.elements.length; var newElements = this.buildElements(this.state.sortingInfo, elemLength, elemLength + this.props.infiniteSliceCount); var infiniteLoadBeginBottomOffset = newElements.length ? 200 : 0; this.setState({ isInfiniteLoading: false, elements: this.state.elements.concat(newElements), infiniteLoadBeginBottomOffset: infiniteLoadBeginBottomOffset }); }, /** * Extract remote sorting info from current node metadata */ remoteSortingInfo: function remoteSortingInfo() { var meta = this.props.node.getMetadata().get('paginationData'); if (meta && meta.get('total') > 1 && meta.has('remote_order')) { var col = meta.get('currentOrderCol'); var dir = meta.get('currentOrderDir'); if (col && dir) { return { remote: true, attribute: col, direction: dir }; } } return null; }, renderToolbar: function renderToolbar() { var _this7 = this; var rightButtons = [React.createElement(ReactMUI.FontIcon, { key: 1, tooltip: 'Reload', className: "icon-refresh" + (this.state.loading ? " rotating" : ""), onClick: this.reload })]; var i = 2; if (this.props.sortKeys) { var sortingInfo = undefined, remoteSortingInfo = this.remoteSortingInfo(); if (remoteSortingInfo) { sortingInfo = remoteSortingInfo; } else { sortingInfo = this.state ? this.state.sortingInfo : null; } rightButtons.push(React.createElement(_SortColumns2['default'], { key: i, displayMode: 'menu', tableKeys: this.props.sortKeys, columnClicked: this.onColumnSort, sortingInfo: sortingInfo })); i++; } if (this.props.additionalActions) { rightButtons.push(this.props.additionalActions); } var leftToolbar = undefined, paginator = undefined; if (this.props.node.getMetadata().get("paginationData") && this.props.node.getMetadata().get("paginationData").get('total') > 1) { paginator = React.createElement(_ListPaginator2['default'], { dataModel: this.dm, node: this.props.node }); } if (this.props.listTitle) { leftToolbar = React.createElement( ReactMUI.ToolbarGroup, { key: 0, float: 'left' }, React.createElement( 'div', { className: 'list-title' }, this.props.listTitle ) ); } if (this.props.searchResultData) { leftToolbar = React.createElement( ReactMUI.ToolbarGroup, { key: 0, float: 'left' }, React.createElement( 'h2', { className: 'search-results-title' }, this.context.getMessage('react.3').replace('%s', this.props.searchResultData.term) ) ); rightButtons = React.createElement(ReactMUI.RaisedButton, { key: 1, label: this.context.getMessage('react.4'), primary: true, onClick: this.props.searchResultData.toggleState }); } else if (this.actionsCache.multiple.size || this.props.multipleActions) { var bulkLabel = this.context.getMessage('react.2'); if (this.state.selection && this.state.showSelector) { bulkLabel += " (" + this.state.selection.size + ")"; } leftToolbar = React.createElement( ReactMUI.ToolbarGroup, { key: 0, float: 'left', className: 'hide-on-vertical-layout' }, React.createElement(ReactMUI.Checkbox, { ref: 'all_selector', onClick: this.selectAll }), React.createElement(ReactMUI.FlatButton, { label: bulkLabel, onClick: this.toggleSelector }) ); if (this.state.showSelector) { (function () { rightButtons = []; var index = 0; var actions = _this7.props.multipleActions || _this7.actionsCache.multiple; actions.forEach((function (a) { rightButtons.push(React.createElement(ReactMUI.RaisedButton, { key: index, label: a.options.text, 'data-action': a.options.name, onClick: this.applyMultipleAction, primary: true })); }).bind(_this7)); rightButtons = React.createElement( 'span', null, rightButtons ); })(); } } return React.createElement( ReactMUI.Toolbar, null, leftToolbar, React.createElement( ReactMUI.ToolbarGroup, { key: 1, float: 'right' }, paginator, rightButtons ) ); }, render: function render() { var _this8 = this; var containerClasses = "material-list vertical-layout layout-fill"; if (this.props.className) { containerClasses += " " + this.props.className; } if (this.state.showSelector) { containerClasses += " list-show-selectors"; } if (this.props.tableKeys) { containerClasses += " table-mode"; } var toolbar = undefined; if (this.props.tableKeys) { var tableKeys = undefined; if (this.props.defaultGroupBy) { tableKeys = LangUtils.deepCopy(this.props.tableKeys); delete tableKeys[this.props.defaultGroupBy]; } else { tableKeys = this.props.tableKeys; } var sortingInfo = undefined, remoteSortingInfo = this.remoteSortingInfo(); if (remoteSortingInfo) { sortingInfo = remoteSortingInfo; } else { sortingInfo = this.state ? this.state.sortingInfo : null; } toolbar = React.createElement(_TableListHeader2['default'], { tableKeys: tableKeys, loading: this.state.loading, reload: this.reload, ref: 'loading_indicator', dm: this.props.dataModel, node: this.props.node, additionalActions: this.props.additionalActions, onHeaderClick: this.onColumnSort, sortingInfo: sortingInfo }); } else { toolbar = this.props.customToolbar ? this.props.customToolbar : !this.props.hideToolbar ? this.renderToolbar() : null; } var inlineEditor = undefined; if (this.state.inlineEditionForNode) { inlineEditor = React.createElement(_InlineEditor2['default'], { detached: true, node: this.state.inlineEditionForNode, callback: this.state.inlineEditionCallback, onClose: function () { _this8.setState({ inlineEditionForNode: null }); } }); } var emptyState = undefined; var _props = this.props; var emptyStateProps = _props.emptyStateProps; var node = _props.node; if (emptyStateProps && this.props.node.isLoaded() && !this.props.node.isLoading() && (!this.state.elements.length || this.state.elements.length === 1 && this.state.elements[0].parent)) { var actionProps = {}; if (this.state.elements.length === 1 && this.state.elements[0].parent) { (function () { var parentNode = _this8.state.elements[0].node; actionProps = { actionLabelId: 'react.1', actionIconClassName: SimpleList.PARENT_FOLDER_ICON, actionCallback: function actionCallback(e) { if (_this8.props.entryHandleClicks) { _this8.props.entryHandleClicks(parentNode, SimpleList.CLICK_TYPE_DOUBLE, e); } } }; })(); } emptyState = React.createElement(_viewsEmptyStateView2['default'], _extends({}, emptyStateProps, actionProps)); } else if (emptyStateProps && emptyStateProps.checkEmptyState && emptyStateProps.checkEmptyState(this.props.node)) { emptyState = React.createElement(_viewsEmptyStateView2['default'], emptyStateProps); } var elements = this.buildElementsFromNodeEntries(this.state.elements, this.state.showSelector); return React.createElement( 'div', { className: containerClasses, onContextMenu: this.contextMenuResponder, tabIndex: '0', onKeyDown: this.onKeyDown, style: this.props.style }, toolbar, inlineEditor, React.createElement( 'div', { className: this.props.heightAutoWithMax ? "infinite-parent-smooth-height" : emptyState ? "layout-fill vertical_layout" : "layout-fill", ref: 'infiniteParent' }, !emptyState && !this.props.verticalScroller && React.createElement( Infinite, { elementHeight: this.state.elementHeight ? this.state.elementHeight : this.props.elementHeight, containerHeight: this.state.containerHeight ? this.state.containerHeight : 1, infiniteLoadBeginEdgeOffset: this.state.infiniteLoadBeginBottomOffset, onInfiniteLoad: this.handleInfiniteLoad, handleScroll: this.onScroll, ref: 'infinite' }, elements ), !emptyState && this.props.verticalScroller && React.createElement( _reactScrollbar2['default'], { speed: 0.8, horizontalScroll: false, style: { height: this.state.containerHeight }, verticalScrollbarStyle: { borderRadius: 10, width: 6 }, verticalContainerStyle: { width: 8 } }, React.createElement( 'div', null, elements ) ), emptyState ) ); } }); exports['default'] = SimpleList; module.exports = exports['default']; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"../util/MessagesConsumerMixin":48,"../views/EmptyStateView":49,"../views/SimpleReactActionBar":52,"./ConfigurableListEntry":13,"./InlineEditor":14,"./ListEntry":15,"./ListPaginator":17,"./SortColumns":20,"./TableListEntry":22,"./TableListHeader":23,"pydio/model/data-model":"pydio/model/data-model","pydio/util/dom":"pydio/util/dom","pydio/util/lang":"pydio/util/lang","pydio/util/periodical-executer":"pydio/util/periodical-executer","react":"react","react-infinite":"react-infinite","react-scrollbar":1}],20:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } var _menuIconButtonMenu = require('../menu/IconButtonMenu'); var _menuIconButtonMenu2 = _interopRequireDefault(_menuIconButtonMenu); var React = require('react'); var Pydio = require('pydio'); var _Pydio$requireLib = Pydio.requireLib('boot'); var PydioContextConsumer = _Pydio$requireLib.PydioContextConsumer; var _require = require('material-ui-legacy'); var ToolbarGroup = _require.ToolbarGroup; var SortColumns = React.createClass({ displayName: 'SortColumns', propTypes: { tableKeys: React.PropTypes.object.isRequired, columnClicked: React.PropTypes.func, sortingInfo: React.PropTypes.object, displayMode: React.PropTypes.string }, onMenuClicked: function onMenuClicked(object) { this.props.columnClicked(object.payload); }, onHeaderClick: function onHeaderClick(key, callback) { var data = this.props.tableKeys[key]; if (data && data['sortType'] && this.props.columnClicked) { data['name'] = key; this.props.columnClicked(data, callback); } }, getColumnsItems: function getColumnsItems(displayMode) { var _this = this; var controller = arguments.length <= 1 || arguments[1] === undefined ? null : arguments[1]; var items = []; var _callback = function _callback() { if (controller) { controller.notify('actions_refreshed'); } }; var _loop = function (key) { if (!_this.props.tableKeys.hasOwnProperty(key)) return 'continue'; var data = _this.props.tableKeys[key]; var style = data['width'] ? { width: data['width'] } : null; var icon = undefined; var className = 'cell header_cell cell-' + key; if (data['sortType']) { className += ' sortable'; if (_this.props.sortingInfo && (_this.props.sortingInfo.attribute === key || _this.props.sortingInfo.attribute === data['sortAttribute'] || _this.props.sortingInfo.attribute === data['remoteSortAttribute'])) { icon = _this.props.sortingInfo.direction === 'asc' ? 'mdi mdi-arrow-up' : 'mdi mdi-arrow-down'; className += ' active-sort-' + _this.props.sortingInfo.direction; } } if (displayMode === 'menu') { data['name'] = key; items.push({ payload: data, text: data['label'], iconClassName: icon }); } else if (displayMode === 'menu_data') { items.push({ name: data['label'], callback: function callback() { _this.onHeaderClick(key, _callback); }, icon_class: icon || '__INSET__' }); } else { items.push(React.createElement( 'span', { key: key, className: className, style: style, onClick: function () { _this.onHeaderClick(key, _callback); } }, data['label'] )); } }; for (var key in this.props.tableKeys) { var _ret = _loop(key); if (_ret === 'continue') continue; } return items; }, buildSortingMenuItems: function buildSortingMenuItems(controller) { return this.getColumnsItems('menu_data', controller); }, componentDidMount: function componentDidMount() { var sortAction = new Action({ name: 'sort_action', icon_class: 'mdi mdi-sort-descending', text_id: 450, title_id: 450, text: this.props.getMessage(450), title: this.props.getMessage(450), hasAccessKey: false, subMenu: true, subMenuUpdateImage: true }, { selection: false, dir: true, actionBar: true, actionBarGroup: 'display_toolbar', contextMenu: false, infoPanel: false }, {}, {}, { dynamicBuilder: this.buildSortingMenuItems }); var buttons = new Map(); buttons.set('sort_action', sortAction); this.props.pydio.getController().updateGuiActions(buttons); }, componentWillUnmount: function componentWillUnmount() { this.props.pydio.getController().deleteFromGuiActions('sort_action'); }, render: function render() { if (this.props.displayMode === 'menu') { return React.createElement(_menuIconButtonMenu2['default'], { buttonTitle: 'Sort by...', buttonClassName: 'mdi mdi-sort-descending', menuItems: this.getColumnsItems('menu', this.props.pydio.getController()), onMenuClicked: this.onMenuClicked }); } else { return React.createElement( ToolbarGroup, { float: 'left' }, this.getColumnsItems('header', this.props.pydio.getController()) ); } } }); exports['default'] = SortColumns = PydioContextConsumer(SortColumns); exports['default'] = SortColumns; module.exports = exports['default']; },{"../menu/IconButtonMenu":26,"material-ui-legacy":"material-ui-legacy","pydio":"pydio","react":"react"}],21:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ "use strict"; exports.__esModule = true; var _utilDND = require('../util/DND'); /***************************/ /* REACT DND SORTABLE LIST /**************************/ /** * Specifies the drag source contract. * Only `beginDrag` function is required. */ var sortableItemSource = { beginDrag: function beginDrag(props) { // Return the data describing the dragged item return { id: props.id }; }, endDrag: function endDrag(props) { props.endSwitching(); } }; var sortableItemTarget = { hover: function hover(props, monitor) { var draggedId = monitor.getItem().id; if (draggedId !== props.id) { props.switchItems(draggedId, props.id); } } }; var sortableItem = React.createClass({ displayName: "sortableItem", propTypes: { connectDragSource: React.PropTypes.func.isRequired, connectDropTarget: React.PropTypes.func.isRequired, isDragging: React.PropTypes.bool.isRequired, id: React.PropTypes.any.isRequired, label: React.PropTypes.string.isRequired, switchItems: React.PropTypes.func.isRequired, removable: React.PropTypes.bool, onRemove: React.PropTypes.func }, removeClicked: function removeClicked() { this.props.onRemove(this.props.id); }, render: function render() { // Your component receives its own props as usual var id = this.props.id; // These two props are injected by React DnD, // as defined by your `collect` function above: var isDragging = this.props.isDragging; var connectDragSource = this.props.connectDragSource; var connectDropTarget = this.props.connectDropTarget; var remove; if (this.props.removable) { remove = React.createElement("span", { className: "button mdi mdi-close", onClick: this.removeClicked }); } return React.createElement( ReactMUI.Paper, { ref: function (instance) { connectDropTarget(ReactDOM.findDOMNode(instance)); connectDragSource(ReactDOM.findDOMNode(instance)); }, zDepth: 1, style: { opacity: isDragging ? 0 : 1 } }, React.createElement( "div", { className: this.props.className }, this.props.label, remove ) ); } }); var NonDraggableListItem = React.createClass({ displayName: "NonDraggableListItem", render: function render() { var remove; if (this.props.removable) { remove = React.createElement("span", { className: "button mdi mdi-close", onClick: this.removeClicked }); } return React.createElement( ReactMUI.Paper, { zDepth: 1 }, React.createElement( "div", { className: this.props.className }, this.props.label, remove ) ); } }); var DraggableListItem; if (window.ReactDND) { DraggableListItem = ReactDND.flow(ReactDND.DragSource(_utilDND.Types.SORTABLE_LIST_ITEM, sortableItemSource, _utilDND.collect), ReactDND.DropTarget(_utilDND.Types.SORTABLE_LIST_ITEM, sortableItemTarget, _utilDND.collectDrop))(sortableItem); } else { DraggableListItem = NonDraggableListItem; } var SortableList = React.createClass({ displayName: "SortableList", propTypes: { values: React.PropTypes.array.isRequired, onOrderUpdated: React.PropTypes.func, removable: React.PropTypes.bool, onRemove: React.PropTypes.func, className: React.PropTypes.string, itemClassName: React.PropTypes.string }, getInitialState: function getInitialState() { return { values: this.props.values }; }, componentWillReceiveProps: function componentWillReceiveProps(props) { this.setState({ values: props.values, switchData: null }); }, findItemIndex: function findItemIndex(itemId, data) { for (var i = 0; i < data.length; i++) { if (data[i]['payload'] == itemId) { return i; } } }, switchItems: function switchItems(oldId, newId) { var oldIndex = this.findItemIndex(oldId, this.state.values); var oldItem = this.state.values[oldIndex]; var newIndex = this.findItemIndex(newId, this.state.values); var newItem = this.state.values[newIndex]; var currentValues = this.state.values.slice(); currentValues[oldIndex] = newItem; currentValues[newIndex] = oldItem; // Check that it did not come back to original state var oldPrevious = this.findItemIndex(oldId, this.props.values); var newPrevious = this.findItemIndex(newId, this.props.values); if (oldPrevious == newIndex && newPrevious == oldIndex) { this.setState({ values: currentValues, switchData: null }); //console.log("no more moves"); } else { this.setState({ values: currentValues, switchData: { oldId: oldId, newId: newId } }); //console.log({oldId:oldIndex, newId:newIndex}); } }, endSwitching: function endSwitching() { if (this.state.switchData) { // Check that it did not come back to original state if (this.props.onOrderUpdated) { this.props.onOrderUpdated(this.state.switchData.oldId, this.state.switchData.newId, this.state.values); } } this.setState({ switchData: null }); }, render: function render() { var switchItems = this.switchItems; return React.createElement( "div", { className: this.props.className }, this.state.values.map((function (item) { return React.createElement(DraggableListItem, { id: item.payload, key: item.payload, label: item.text, switchItems: switchItems, endSwitching: this.endSwitching, removable: this.props.removable, onRemove: this.props.onRemove, className: this.props.itemClassName }); }).bind(this)) ); } }); exports["default"] = SortableList; module.exports = exports["default"]; },{"../util/DND":47}],22:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = 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; }; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } var _ListEntryNodeListenerMixin = require('./ListEntryNodeListenerMixin'); var _ListEntryNodeListenerMixin2 = _interopRequireDefault(_ListEntryNodeListenerMixin); var _ListEntry = require('./ListEntry'); var _InlineEditor = require('./InlineEditor'); var _InlineEditor2 = _interopRequireDefault(_InlineEditor); /** * Specific list entry rendered as a table row. Not a real table, CSS used. */ exports['default'] = React.createClass({ displayName: 'TableListEntry', mixins: [_ListEntryNodeListenerMixin2['default']], propTypes: { node: React.PropTypes.instanceOf(AjxpNode), tableKeys: React.PropTypes.object.isRequired, renderActions: React.PropTypes.func // See also ListEntry nodes }, render: function render() { var _this = this; var actions = this.props.actions; if (this.props.renderActions) { actions = this.props.renderActions(this.props.node); } var cells = []; var firstKey = true; var meta = this.props.node.getMetadata(); for (var key in this.props.tableKeys) { if (!this.props.tableKeys.hasOwnProperty(key)) continue; var data = this.props.tableKeys[key]; var style = data['width'] ? { width: data['width'] } : null; var value = undefined, rawValue = undefined; if (data.renderCell) { data['name'] = key; value = data.renderCell(this.props.node, data); } else if (key === 'ajxp_modiftime' && meta.get('ajxp_relativetime')) { value = meta.get('ajxp_relativetime'); } else { value = meta.get(key); } rawValue = meta.get(key); var inlineEditor = undefined; if (this.state && this.state.inlineEdition && firstKey) { inlineEditor = React.createElement(_InlineEditor2['default'], { node: this.props.node, onClose: function () { _this.setState({ inlineEdition: false }); }, callback: this.state.inlineEditionCallback }); var _style = this.props.style || {}; _style.position = 'relative'; this.props.style = _style; } cells.push(React.createElement( 'span', { key: key, className: 'cell cell-' + key, title: rawValue, style: style, 'data-label': data['label'] }, inlineEditor, value )); firstKey = false; } return React.createElement(_ListEntry.DragDropListEntry, _extends({}, this.props, { iconCell: null, firstLine: cells, actions: actions })); } }); module.exports = exports['default']; },{"./InlineEditor":14,"./ListEntry":15,"./ListEntryNodeListenerMixin":16}],23:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = 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; }; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } var _utilMessagesConsumerMixin = require('../util/MessagesConsumerMixin'); var _utilMessagesConsumerMixin2 = _interopRequireDefault(_utilMessagesConsumerMixin); var _SortColumns = require('./SortColumns'); var _SortColumns2 = _interopRequireDefault(_SortColumns); var _ListPaginator = require('./ListPaginator'); var _ListPaginator2 = _interopRequireDefault(_ListPaginator); /** * Specific header for Table layout, reading metadata from node and using keys */ exports['default'] = React.createClass({ displayName: 'TableListHeader', mixins: [_utilMessagesConsumerMixin2['default']], propTypes: { tableKeys: React.PropTypes.object.isRequired, loading: React.PropTypes.bool, reload: React.PropTypes.func, dm: React.PropTypes.instanceOf(PydioDataModel), node: React.PropTypes.instanceOf(AjxpNode), onHeaderClick: React.PropTypes.func, sortingInfo: React.PropTypes.object }, render: function render() { var headers = undefined, paginator = undefined; if (this.props.node.getMetadata().get("paginationData") && this.props.node.getMetadata().get("paginationData").get('total') > 1) { paginator = React.createElement(_ListPaginator2['default'], { dataModel: this.props.dm, node: this.props.node }); } return React.createElement( ReactMUI.Toolbar, { className: 'toolbarTableHeader' }, React.createElement(_SortColumns2['default'], _extends({ displayMode: 'tableHeader' }, this.props, { columnClicked: this.props.onHeaderClick })), React.createElement( ReactMUI.ToolbarGroup, { float: 'right' }, paginator, React.createElement(ReactMUI.FontIcon, { key: 1, tooltip: this.context.getMessage('149', ''), className: "icon-refresh" + (this.props.loading ? " rotating" : ""), onClick: this.props.reload }), this.props.additionalActions ) ); } }); module.exports = exports['default']; },{"../util/MessagesConsumerMixin":48,"./ListPaginator":17,"./SortColumns":20}],24:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = 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; }; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } var _Utils = require('./Utils'); var _Utils2 = _interopRequireDefault(_Utils); var _MenuItemsConsumer = require('./MenuItemsConsumer'); var _MenuItemsConsumer2 = _interopRequireDefault(_MenuItemsConsumer); var React = require('react'); var ReactDOM = require('react-dom'); var _require = require('material-ui'); var Menu = _require.Menu; var Controller = require('pydio/model/controller'); var ButtonMenu = React.createClass({ displayName: 'ButtonMenu', propTypes: { buttonTitle: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.object]).isRequired, menuItems: React.PropTypes.array.isRequired, className: React.PropTypes.string, raised: React.PropTypes.bool, direction: React.PropTypes.oneOf(['left', 'right']) }, componentDidMount: function componentDidMount() { var _this = this; if (this.props.openOnEvent) { this.props.pydio.observe(this.props.openOnEvent, function () { _this.showMenu(); }); } }, getInitialState: function getInitialState() { return { showMenu: false }; }, showMenu: function showMenu(event) { var anchor = undefined; if (event) { anchor = event.currentTarget; } else { anchor = this._buttonDOM; } this.setState({ showMenu: true, anchor: anchor }); }, menuClicked: function menuClicked(event, index, object) { //object.payload(); this.setState({ showMenu: false }); }, render: function render() { var _this2 = this; var label = React.createElement( 'span', null, this.props.buttonTitle, ' ', React.createElement('span', { className: 'icon-caret-down' }) ); var button = undefined; var props = { primary: this.props.primary, secondary: this.props.secondary, disabled: this.props.disabeld, label: label, onTouchTap: this.showMenu, onClick: function onClick(e) { return e.stopPropagation(); } }; var menuItems = this.props.menuItems; var _state = this.state; var showMenu = _state.showMenu; var anchor = _state.anchor; if (menuItems.length) { if (this.props.raised) { button = React.createElement(MaterialUI.RaisedButton, _extends({}, props, { style: this.props.buttonStyle, labelStyle: this.props.buttonLabelStyle, ref: function (b) { _this2._buttonDOM = ReactDOM.findDOMNode(b); } })); } else { button = React.createElement(MaterialUI.FlatButton, _extends({}, props, { style: this.props.buttonStyle, labelStyle: this.props.buttonLabelStyle, ref: function (b) { _this2._buttonDOM = ReactDOM.findDOMNode(b); } })); } } return React.createElement( 'span', { id: this.props.id, className: this.props.className }, button, React.createElement( MaterialUI.Popover, { className: 'menuPopover', open: showMenu, anchorEl: anchor, anchorOrigin: { horizontal: this.props.direction || 'left', vertical: 'bottom' }, targetOrigin: { horizontal: this.props.direction || 'left', vertical: 'top' }, onRequestClose: function () { _this2.setState({ showMenu: false }); }, style: { marginTop: 1 }, useLayerForClickAway: false }, _Utils2['default'].itemsToMenu(menuItems, this.menuClicked) ) ); } }); exports['default'] = _MenuItemsConsumer2['default'](ButtonMenu); module.exports = exports['default']; },{"./MenuItemsConsumer":28,"./Utils":31,"material-ui":"material-ui","pydio/model/controller":"pydio/model/controller","react":"react","react-dom":"react-dom"}],25:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; 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 _pydioModelContextMenu = require('pydio/model/context-menu'); var _pydioModelContextMenu2 = _interopRequireDefault(_pydioModelContextMenu); var _Utils = require('./Utils'); var _Utils2 = _interopRequireDefault(_Utils); var _PopupMenu = require('./PopupMenu'); var _PopupMenu2 = _interopRequireDefault(_PopupMenu); var _require = require('react'); var Component = _require.Component; var dims = { MENU_ITEM_HEIGHT: 32, //48 if not display:compact MENU_SEP_HEIGHT: 16, MENU_VERTICAL_PADDING: 8, MENU_WIDTH: 250, OFFSET_VERTICAL: 8, OFFSET_HORIZONTAL: 8 }; var ContextMenu = (function (_Component) { _inherits(ContextMenu, _Component); function ContextMenu() { _classCallCheck(this, ContextMenu); _Component.apply(this, arguments); } ContextMenu.prototype.modelOpen = function modelOpen(node) { var position = _pydioModelContextMenu2['default'].getInstance().getPosition(); var items = undefined; if (node) { var dm = pydio.getContextHolder(); if (dm.getSelectedNodes().indexOf(node) !== -1) { this.openMenu('selectionContext', position); } else { pydio.observeOnce("actions_refreshed", (function (dataModel) { this.openMenu('selectionContext', position); }).bind(this)); dm.setSelectedNodes([node]); } } else { this.openMenu('genericContext', position); } }; ContextMenu.prototype.openMenu = function openMenu(context, position) { var items = this.computeMenuItems(context); this._items = items; var mobile = this.props.pydio.UI.MOBILE_EXTENSIONS; if (!mobile) { position = this.computeVisiblePosition(position, items); this.refs['menu'].showMenu({ top: position.y, left: position.x }, items); } else { this.refs['menu'].showMenu({ bottom: 0, left: 0, right: 0, height: 200, zIndex: 10000, overflowY: 'auto' }, items); } }; ContextMenu.prototype.computeMenuItems = function computeMenuItems(context) { var actions = this.props.pydio.Controller.getContextActions(context, ['inline', 'info_panel', 'info_panel_share']); return _Utils2['default'].pydioActionsToItems(actions); }; ContextMenu.prototype.computeVisiblePosition = function computeVisiblePosition(position, items) { var menuHeight = dims.MENU_VERTICAL_PADDING * 2; items.map(function (it) { if (it.separator) menuHeight += dims.MENU_SEP_HEIGHT;else menuHeight += dims.MENU_ITEM_HEIGHT; }); var menuWidth = dims.MENU_WIDTH; var windowW = Math.max(document.documentElement.clientWidth, window.innerWidth || 0); var windowH = Math.max(document.documentElement.clientHeight, window.innerHeight || 0); if (position.x + menuWidth > windowW) { position.x = Math.max(position.x - menuWidth, 10) - dims.OFFSET_HORIZONTAL; } else { position.x += dims.OFFSET_HORIZONTAL; } if (position.y + menuHeight > windowH) { position.y = Math.max(position.y - menuHeight, 10) - dims.OFFSET_VERTICAL; } else { position.y += dims.OFFSET_VERTICAL; } return position; }; ContextMenu.prototype.componentDidMount = function componentDidMount() { this._modelOpen = this.modelOpen.bind(this); _pydioModelContextMenu2['default'].getInstance().observe("open", this._modelOpen); }; ContextMenu.prototype.componentWillUnmount = function componentWillUnmount() { _pydioModelContextMenu2['default'].getInstance().stopObserving("open", this._modelOpen); }; ContextMenu.prototype.render = function render() { var mobile = this.props.pydio.UI.MOBILE_EXTENSIONS; return React.createElement(_PopupMenu2['default'], { ref: 'menu', menuItems: this._items || [], onMenuClosed: this.props.onMenuClosed, menuProps: mobile ? { width: 600, autoWidth: false, desktop: false } : {}, zDepth: mobile ? 2 : 1 }); }; return ContextMenu; })(Component); exports['default'] = ContextMenu; module.exports = exports['default']; },{"./PopupMenu":29,"./Utils":31,"pydio/model/context-menu":"pydio/model/context-menu","react":"react"}],26:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; 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 _Utils = require('./Utils'); var _Utils2 = _interopRequireDefault(_Utils); var _MenuItemsConsumer = require('./MenuItemsConsumer'); var _MenuItemsConsumer2 = _interopRequireDefault(_MenuItemsConsumer); var React = require('react'); var _require = require('material-ui'); var IconButton = _require.IconButton; var Popover = _require.Popover; var IconButtonMenu = (function (_React$Component) { _inherits(IconButtonMenu, _React$Component); function IconButtonMenu(props, context) { _classCallCheck(this, IconButtonMenu); _React$Component.call(this, props, context); this.state = { showMenu: false }; } IconButtonMenu.prototype.showMenu = function showMenu(event) { this.setState({ showMenu: true, anchor: event.currentTarget }); }; IconButtonMenu.prototype.closeMenu = function closeMenu(event, index, menuItem) { this.setState({ showMenu: false }); }; IconButtonMenu.prototype.render = function render() { var _this = this; return React.createElement( 'span', { className: "toolbars-button-menu " + (this.props.className ? this.props.className : '') }, React.createElement(IconButton, { ref: 'menuButton', tooltip: this.props.buttonTitle, iconClassName: this.props.buttonClassName, onTouchTap: this.showMenu.bind(this), iconStyle: this.props.buttonStyle }), React.createElement( Popover, { open: this.state.showMenu, anchorEl: this.state.anchor, anchorOrigin: { horizontal: this.props.popoverDirection || 'right', vertical: this.props.popoverTargetPosition || 'bottom' }, targetOrigin: { horizontal: this.props.popoverDirection || 'right', vertical: 'top' }, onRequestClose: function () { _this.setState({ showMenu: false }); }, useLayerForClickAway: false }, _Utils2['default'].itemsToMenu(this.props.menuItems, this.closeMenu.bind(this), false, this.props.menuProps || undefined) ) ); }; return IconButtonMenu; })(React.Component); IconButtonMenu.propTypes = { buttonTitle: React.PropTypes.string.isRequired, buttonClassName: React.PropTypes.string.isRequired, className: React.PropTypes.string, popoverDirection: React.PropTypes.oneOf(['right', 'left']), popoverPosition: React.PropTypes.oneOf(['top', 'bottom']), menuProps: React.PropTypes.object, menuItems: React.PropTypes.array.isRequired }; exports['default'] = _MenuItemsConsumer2['default'](IconButtonMenu); module.exports = exports['default']; },{"./MenuItemsConsumer":28,"./Utils":31,"material-ui":"material-ui","react":"react"}],27:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; 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 React = require('react'); var _require = require('material-ui'); var IconButton = _require.IconButton; var Popover = _require.Popover; var IconButtonPopover = (function (_React$Component) { _inherits(IconButtonPopover, _React$Component); function IconButtonPopover(props, context) { _classCallCheck(this, IconButtonPopover); _React$Component.call(this, props, context); this.state = { showPopover: false }; } IconButtonPopover.prototype.showPopover = function showPopover(event) { this.setState({ showPopover: true, anchor: event.currentTarget }); }; IconButtonPopover.prototype.render = function render() { var _this = this; return React.createElement( 'span', { className: "toolbars-button-menu " + (this.props.className ? this.props.className : '') }, React.createElement(IconButton, { ref: 'menuButton', tooltip: this.props.buttonTitle, iconClassName: this.props.buttonClassName, onTouchTap: this.showPopover.bind(this), iconStyle: this.props.buttonStyle }), React.createElement( Popover, { open: this.state.showPopover, anchorEl: this.state.anchor, anchorOrigin: { horizontal: this.props.direction || 'right', vertical: 'bottom' }, targetOrigin: { horizontal: this.props.direction || 'right', vertical: 'top' }, onRequestClose: function () { _this.setState({ showPopover: false }); }, useLayerForClickAway: false }, this.props.popoverContent ) ); }; return IconButtonPopover; })(React.Component); IconButtonPopover.propTypes = { buttonTitle: React.PropTypes.string.isRequired, buttonClassName: React.PropTypes.string.isRequired, className: React.PropTypes.string, direction: React.PropTypes.oneOf(['right', 'left']), popoverContent: React.PropTypes.object.isRequired }; exports['default'] = IconButtonPopover; module.exports = exports['default']; },{"material-ui":"material-ui","react":"react"}],28:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = 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; }; 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 _Utils = require('./Utils'); var _Utils2 = _interopRequireDefault(_Utils); var React = require('react'); var Controller = require('pydio/model/controller'); exports['default'] = function (Component) { var Wrapped = (function (_React$Component) { _inherits(Wrapped, _React$Component); function Wrapped(props, context) { _classCallCheck(this, Wrapped); _React$Component.call(this, props, context); this.state = { menuItems: this.props.menuItems || [] }; } Wrapped.prototype.componentDidMount = function componentDidMount() { var _this = this; if (this.props.controller && !this.props.menuItems) { this._observer = function () { var actions = _this.props.controller.getContextActions('genericContext', null, _this.props.toolbars); var menuItems = _Utils2['default'].pydioActionsToItems(actions); _this.setState({ menuItems: menuItems }); }; if (this.props.controller === this.props.pydio.Controller) { this.props.pydio.observe("actions_refreshed", this._observer); } else { this.props.controller.observe("actions_refreshed", this._observer); } this._observer(); } }; Wrapped.prototype.componentWillUnmount = function componentWillUnmount() { if (this._observer) { if (this.props.controller === this.props.pydio.Controller) { this.props.pydio.stopObserving("actions_refreshed", this._observer); } else { this.props.controller.stopObserving("actions_refreshed", this._observer); } } }; Wrapped.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) { if (nextProps.menuItems && nextProps.menuItems !== this.props.menuItems) { this.setState({ menuItems: nextProps.menuItems }); } }; Wrapped.prototype.render = function render() { return React.createElement(Component, _extends({}, this.props, { menuItems: this.state.menuItems })); }; return Wrapped; })(React.Component); Wrapped.propTypes = { menuItems: React.PropTypes.array, toolbars: React.PropTypes.array, controller: React.PropTypes.instanceOf(Controller), pydio: React.PropTypes.instanceOf(Pydio) }; return Wrapped; }; module.exports = exports['default']; },{"./Utils":31,"pydio/model/controller":"pydio/model/controller","react":"react"}],29:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = 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; }; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } var _Utils = require('./Utils'); var _Utils2 = _interopRequireDefault(_Utils); var React = require('react'); var ReactDOM = require('react-dom'); var _require = require('material-ui'); var Menu = _require.Menu; var Paper = _require.Paper; exports['default'] = React.createClass({ displayName: 'PopupMenu', propTypes: { menuItems: React.PropTypes.array.isRequired, onExternalClickCheckElements: React.PropTypes.func, className: React.PropTypes.string, style: React.PropTypes.object, onMenuClosed: React.PropTypes.func }, getInitialState: function getInitialState() { return { showMenu: false, menuItems: this.props.menuItems }; }, showMenu: function showMenu() { var style = arguments.length <= 0 || arguments[0] === undefined ? null : arguments[0]; var menuItems = arguments.length <= 1 || arguments[1] === undefined ? null : arguments[1]; this.setState({ showMenu: true, style: style, menuItems: menuItems ? menuItems : this.state.menuItems }); }, hideMenu: function hideMenu(event) { if (!event) { this.setState({ showMenu: false }); if (this.props.onMenuClosed) this.props.onMenuClosed(); return; } // Firefox trigger a click event when you mouse up on contextmenu event if (typeof event !== 'undefined' && event.button === 2 && event.type !== 'contextmenu') { return; } var node = ReactDOM.findDOMNode(this.refs.menuContainer); if (node.contains(event.target) || node === event.target) { return; } this.setState({ showMenu: false }); if (this.props.onMenuClosed) this.props.onMenuClosed(); }, componentDidMount: function componentDidMount() { this._observer = this.hideMenu; }, componentWillUnmount: function componentWillUnmount() { document.removeEventListener('click', this._observer, false); }, componentWillReceiveProps: function componentWillReceiveProps(nextProps) { if (nextProps.menuItems) { this.setState({ menuItems: nextProps.menuItems }); } }, componentDidUpdate: function componentDidUpdate(prevProps, nextProps) { if (this.state.showMenu) { document.addEventListener('click', this._observer, false); } else { document.removeEventListener('click', this._observer, false); } }, menuClicked: function menuClicked(event, index, menuItem) { this.hideMenu(); }, render: function render() { var style = this.state.style || {}; style = _extends({}, style, { zIndex: 1000 }); var menu = _Utils2['default'].itemsToMenu(this.state.menuItems, this.menuClicked, false, _extends({ desktop: true, display: 'right', width: 250 }, this.props.menuProps)); if (this.state.showMenu) { return React.createElement( Paper, { zDepth: this.props.zDepth || 1, ref: 'menuContainer', className: 'menu-positioner', style: style }, menu ); } else { return null; } } }); module.exports = exports['default']; },{"./Utils":31,"material-ui":"material-ui","react":"react","react-dom":"react-dom"}],30:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } var _Utils = require('./Utils'); var _Utils2 = _interopRequireDefault(_Utils); var _IconButtonMenu = require('./IconButtonMenu'); var _IconButtonMenu2 = _interopRequireDefault(_IconButtonMenu); var _ButtonMenu = require('./ButtonMenu'); var _ButtonMenu2 = _interopRequireDefault(_ButtonMenu); var _IconButtonPopover = require('./IconButtonPopover'); var _IconButtonPopover2 = _interopRequireDefault(_IconButtonPopover); (function (global) { exports['default'] = React.createClass({ displayName: 'Toolbar', propTypes: { toolbars: React.PropTypes.array, groupOtherList: React.PropTypes.array, renderingType: React.PropTypes.string, controller: React.PropTypes.instanceOf(Controller), toolbarStyle: React.PropTypes.object, buttonStyle: React.PropTypes.object }, componentDidMount: function componentDidMount() { this._observer = (function () { if (!this.isMounted()) return; this.setState({ groups: this.props.controller.getToolbarsActions(this.props.toolbars, this.props.groupOtherList) }); }).bind(this); if (this.props.controller === pydio.Controller) { pydio.observe("actions_refreshed", this._observer); } else { this.props.controller.observe("actions_refreshed", this._observer); } }, componentWillUnmount: function componentWillUnmount() { if (this.props.controller === pydio.Controller) { pydio.stopObserving("actions_refreshed", this._observer); } else { this.props.controller.stopObserving("actions_refreshed", this._observer); } }, componentWillReceiveProps: function componentWillReceiveProps(nextProps) { if (nextProps.toolbars !== this.props.toolbars) { this.setState({ groups: this.props.controller.getToolbarsActions(nextProps.toolbars, nextProps.groupOtherList) }); } }, getInitialState: function getInitialState() { return { groups: this.props.controller.getToolbarsActions(this.props.toolbars, this.props.groupOtherList) }; }, getDefaultProps: function getDefaultProps() { return { controller: global.pydio.Controller, renderingType: 'button', groupOtherList: [] }; }, render: function render() { var groups = this.state.groups; var actions = []; var _props = this.props; var toolbars = _props.toolbars; var renderingType = _props.renderingType; var groupOtherList = _props.groupOtherList; var buttonStyle = _props.buttonStyle; var tooltipPosition = _props.tooltipPosition; var controller = _props.controller; var allToolbars = [].concat(toolbars); if (groupOtherList.length) { allToolbars = allToolbars.concat(['MORE_ACTION']); } allToolbars.map(function (barName) { if (!groups.has(barName)) return; groups.get(barName).map(function (action) { if (action.deny) return; var menuItems = undefined, popoverContent = undefined, menuTitle = undefined, menuIcon = undefined; var actionName = action.options.name; menuTitle = action.options.text; menuIcon = action.options.icon_class; if (barName === 'MORE_ACTION') { (function () { var subItems = action.subMenuItems.dynamicItems; var items = []; subItems.map(function (obj) { if (obj.separator) { items.push(obj); } else if (obj.actionId && !obj.actionId.deny) { items.push(obj.actionId.getMenuData()); } }); menuItems = _Utils2['default'].pydioActionsToItems(items); })(); } else if (action.subMenuItems.staticItems) { menuItems = _Utils2['default'].pydioActionsToItems(action.subMenuItems.staticItems); } else if (action.subMenuItems.dynamicBuilder) { menuItems = _Utils2['default'].pydioActionsToItems(action.subMenuItems.dynamicBuilder(controller)); } else if (action.subMenuItems.popoverContent) { popoverContent = action.subMenuItems.popoverContent; } else {} var id = 'action-' + action.options.name; if (renderingType === 'button-icon') { menuTitle = React.createElement( 'span', { className: 'button-icon' }, React.createElement('span', { className: "button-icon-icon " + menuIcon }), React.createElement( 'span', { className: 'button-icon-label' }, menuTitle ) ); } if (menuItems) { if (renderingType === 'button' || renderingType === 'button-icon') { actions.push(React.createElement(_ButtonMenu2['default'], { key: actionName, className: id, buttonTitle: menuTitle, menuItems: menuItems, buttonLabelStyle: buttonStyle })); } else { actions.push(React.createElement(_IconButtonMenu2['default'], { key: actionName, className: id, onMenuClicked: function (object) { object.payload(); }, buttonClassName: menuIcon, buttonTitle: menuTitle, menuItems: menuItems, buttonStyle: buttonStyle })); } } else if (popoverContent) { actions.push(React.createElement(_IconButtonPopover2['default'], { key: actionName, className: id, buttonClassName: menuIcon, buttonTitle: menuTitle, buttonStyle: buttonStyle, popoverContent: popoverContent })); } else { var click = function click(synthEvent) { action.apply(); }; if (renderingType === 'button-icon') { actions.push(React.createElement(ReactMUI.FlatButton, { key: actionName, className: id, onTouchTap: click, label: menuTitle, labelStyle: buttonStyle })); } else if (renderingType === 'button') { actions.push(React.createElement(MaterialUI.FlatButton, { key: actionName, className: id, onTouchTap: click, label: menuTitle, labelStyle: buttonStyle })); } else { actions.push(React.createElement(MaterialUI.IconButton, { key: actionName, iconClassName: menuIcon + ' ' + id, iconStyle: buttonStyle, onTouchTap: click, tooltip: menuTitle, tooltipPosition: tooltipPosition })); } } }); }); var cName = this.props.className ? this.props.className : ''; cName += ' ' + 'toolbar'; if (!actions.length) { cName += ' empty-toolbar'; } return React.createElement( 'div', { className: cName, style: this.props.toolbarStyle, id: this.props.id }, actions ); } }); })(window); module.exports = exports['default']; },{"./ButtonMenu":24,"./IconButtonMenu":26,"./IconButtonPopover":27,"./Utils":31}],31:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = 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 _require = require('material-ui'); var Divider = _require.Divider; var Menu = _require.Menu; var MenuItem = _require.MenuItem; var FontIcon = _require.FontIcon; function pydioActionsToItems() { var actions = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0]; var items = []; var lastIsSeparator = false; actions.map((function (action, index) { if (action.separator) { if (lastIsSeparator) return; items.push(action); lastIsSeparator = true; return; } lastIsSeparator = false; var label = action.raw_name ? action.raw_name : action.name; var iconClass = action.icon_class; var payload = undefined; if (action.subMenu) { var subItems = action.subMenuBeforeShow ? pydioActionsToItems(action.subMenuBeforeShow()) : action.subMenu; items.push({ text: label, iconClassName: iconClass, subItems: subItems }); } else { items.push({ text: label, iconClassName: iconClass, payload: action.callback }); } }).bind(this)); if (lastIsSeparator) { items = items.slice(0, items.length - 1); } if (items.length && items[0] && items[0].separator) { items.shift(); } return items; } function itemsToMenu(items, closeMenuCallback) { var subItemsOnly = arguments.length <= 2 || arguments[2] === undefined ? false : arguments[2]; var menuProps = arguments.length <= 3 || arguments[3] === undefined ? {} : arguments[3]; menuProps = _extends({ display: 'normal', width: 216, desktop: true, autoWidth: false }, menuProps); var menuItems = items.map(function (item, index) { if (item.separator) return React.createElement(Divider, { key: "divider" + index }); var subItems = undefined, payload = undefined; if (item.subItems) { subItems = itemsToMenu(item.subItems, closeMenuCallback, true); } else if (item.payload) { payload = function () { item.payload(); closeMenuCallback(); }; } var leftIcon = undefined, rightIcon = undefined; var iconClassName = item.iconClassName;var inset = false; if (iconClassName === '__INSET__') { iconClassName = ''; inset = true; } if (menuProps.display === 'normal') { leftIcon = iconClassName ? React.createElement(FontIcon, { className: item.iconClassName + ' menu-icons', style: { fontSize: 16, padding: 5 } }) : null; } else if (menuProps.display === 'right') { rightIcon = iconClassName ? React.createElement(FontIcon, { className: item.iconClassName + ' menu-icons', style: { fontSize: 16, padding: 5 } }) : null; } rightIcon = subItems && subItems.length ? React.createElement(FontIcon, { className: 'mdi mdi-menu-right menu-icons' }) : rightIcon; return React.createElement(MenuItem, { key: item.text, primaryText: item.text, insetChildren: inset, leftIcon: leftIcon, rightIcon: rightIcon, onTouchTap: payload, menuItems: subItems }); }); if (subItemsOnly) { return menuItems; } else { return React.createElement( Menu, menuProps, menuItems ); } } exports['default'] = { pydioActionsToItems: pydioActionsToItems, itemsToMenu: itemsToMenu }; module.exports = exports['default']; },{"material-ui":"material-ui"}],32:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; 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 TextField = _require2.TextField; var FlatButton = _require2.FlatButton; var _require$requireLib = require('pydio').requireLib('boot'); var PydioContextConsumer = _require$requireLib.PydioContextConsumer; /** * Simple form for creating a team */ var TeamCreationForm = (function (_Component) { _inherits(TeamCreationForm, _Component); TeamCreationForm.updateTeamUsers = function updateTeamUsers(team, operation, users, callback) { var teamId = team.id.replace('/AJXP_TEAM/', ''); var clearUserCache = function clearUserCache(uId) { MetaCacheService.getInstance().deleteKey('user_public_data-rich', uId); }; if (operation === 'add') { users.forEach(function (user) { var userId = user.getId ? user.getId() : user.id; PydioUsers.Client.addUserToTeam(teamId, userId, callback); clearUserCache(userId); }); } else if (operation === 'delete') { users.forEach(function (user) { var userId = user.getId ? user.getId() : user.id; PydioUsers.Client.removeUserFromTeam(teamId, userId, callback); clearUserCache(userId); }); } else if (operation === 'create') { PydioUsers.Client.saveSelectionAsTeam(teamId, users, callback); users.forEach(function (user) { clearUserCache(user.getId ? user.getId() : user.id); }); } }; function TeamCreationForm(props, context) { _classCallCheck(this, TeamCreationForm); _Component.call(this, props, context); this.state = { value: '' }; } TeamCreationForm.prototype.onChange = function onChange(e, value) { this.setState({ value: value }); }; TeamCreationForm.prototype.submitCreationForm = function submitCreationForm() { var value = this.state.value; TeamCreationForm.updateTeamUsers({ id: value }, 'create', [], this.props.onTeamCreated); }; TeamCreationForm.prototype.render = function render() { var getMessage = this.props.getMessage; return React.createElement( 'div', { style: { padding: 20 } }, React.createElement( 'div', null, getMessage(591) ), React.createElement(TextField, { floatingLabelText: getMessage(578), value: this.state.value, onChange: this.onChange.bind(this), fullWidth: true }), React.createElement( 'div', null, React.createElement( 'div', { style: { textAlign: 'right', paddingTop: 10 } }, React.createElement(FlatButton, { label: getMessage(49), onTouchTap: this.props.onCancel.bind(this) }), React.createElement(FlatButton, { label: getMessage(579), secondary: true, onTouchTap: this.submitCreationForm.bind(this) }) ) ) ); }; return TeamCreationForm; })(Component); TeamCreationForm.propTypes = { /** * Callback triggered after team creation succeeded */ onTeamCreated: PropTypes.func.isRequired, /** * Request modal close */ onCancel: PropTypes.func.isRequired }; exports['default'] = TeamCreationForm = PydioContextConsumer(TeamCreationForm); exports['default'] = TeamCreationForm; module.exports = exports['default']; },{"material-ui":"material-ui","pydio":"pydio","react":"react"}],33:[function(require,module,exports){ (function (global){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } var _addressbookAddressBook = require('./addressbook/AddressBook'); var _addressbookAddressBook2 = _interopRequireDefault(_addressbookAddressBook); var _require$requireLib = require('pydio/http/resources-manager').requireLib('boot'); var AsyncComponent = _require$requireLib.AsyncComponent; var _require = require('material-ui'); var TextField = _require.TextField; var AutoComplete = _require.AutoComplete; var RefreshIndicator = _require.RefreshIndicator; var IconButton = _require.IconButton; var Popover = _require.Popover; var React = require('react'); var FuncUtils = require('pydio/util/func'); /** * Ready to use autocomplete field that will load users/groups/roles from * the server (using user_list_authorized_users API). * Used for sharing, addressbooks, send email, etc. * * Can also open a "selector-style" adress book. */ var UsersLoader = React.createClass({ displayName: 'UsersLoader', propTypes: { /** * Method called to render a commponent, taking a UserObject as input */ renderSuggestion: React.PropTypes.func.isRequired, /** * Callback when a value is finally selected */ onValueSelected: React.PropTypes.func.isRequired, /** * Floating Label Text displayed on the field */ fieldLabel: React.PropTypes.string.isRequired, /** * Array of values to ignore */ excludes: React.PropTypes.array.isRequired, /** * Display only users, no groups nor roles */ usersOnly: React.PropTypes.bool, /** * Display users from local directory and/or from remote. */ usersFrom: React.PropTypes.oneOf(['local', 'remote', 'any']), /** * Do not propose a "Create user" option */ existingOnly: React.PropTypes.bool, /** * Allow free typing */ freeValueAllowed: React.PropTypes.bool, /** * Will be passed to the root component */ className: React.PropTypes.string }, getInitialState: function getInitialState() { return { dataSource: [], loading: false, searchText: '', minChars: parseInt(global.pydio.getPluginConfigs("core.conf").get("USERS_LIST_COMPLETE_MIN_CHARS")) }; }, /** * Loads values from server * @param {string} input Currently searched text * @param {Function} callback Called with the values */ suggestionLoader: function suggestionLoader(input, callback) { var excludes = this.props.excludes; var disallowTemporary = this.props.existingOnly && !this.props.freeValueAllowed; this.setState({ loading: this.state.loading + 1 }); PydioUsers.Client.authorizedUsersStartingWith(input, (function (users) { this.setState({ loading: this.state.loading - 1 }); if (disallowTemporary) { users = users.filter(function (user) { return !user.getTemporary(); }); } if (excludes && excludes.length) { users = users.filter(function (user) { return excludes.indexOf(user.getId()) == -1; }); } callback(users); }).bind(this), this.props.usersOnly, this.props.existingOnly); }, /** * Called when the field is updated * @param value */ textFieldUpdate: function textFieldUpdate(value) { this.setState({ searchText: value }); if (this.state.minChars && value && value.length < this.state.minChars) { return; } this.loadBuffered(value, 350); }, getPendingSearchText: function getPendingSearchText() { return this.state.searchText || false; }, /** * Debounced call for rendering search * @param value {string} * @param timeout {int} */ loadBuffered: function loadBuffered(value, timeout) { if (!value && this._emptyValueList) { this.setState({ dataSource: this._emptyValueList }); return; } FuncUtils.bufferCallback('remote_users_search', timeout, (function () { this.setState({ loading: true }); this.suggestionLoader(value, (function (users) { var crtValueFound = false; var values = users.map((function (userObject) { var component = React.createElement( MaterialUI.MenuItem, null, this.props.renderSuggestion(userObject) ); return { userObject: userObject, text: userObject.getExtendedLabel(), value: component }; }).bind(this)); if (!value) { this._emptyValueList = values; } this.setState({ dataSource: values, loading: false }); }).bind(this)); }).bind(this)); }, /** * Called when user selects a value from the list * @param value * @param index */ onCompleterRequest: function onCompleterRequest(value, index) { if (index === -1) { this.state.dataSource.map(function (entry) { if (entry.text === value) { value = entry; } }); if (value && !value.userObject && this.props.freeValueAllowed) { var fake = new PydioUsers.User(value, value, 'user', null, null, true); this.props.onValueSelected(fake); this.setState({ searchText: '', dataSource: [] }); return; } } if (value && value.userObject) { var object = value.userObject; if (object.getTemporary()) { if (this.props.freeValueAllowed) { this.props.onValueSelected(object); } else { this.setState({ createUser: object.getLabel() }); } } else { this.props.onValueSelected(object); } this.setState({ searchText: '', dataSource: [] }); } }, /** * Triggers onValueSelected props callback * @param {Pydio.User} newUser */ onUserCreated: function onUserCreated(newUser) { this.props.onValueSelected(newUser); this.setState({ createUser: null }); }, /** * Close user creation form */ onCreationCancelled: function onCreationCancelled() { this.setState({ createUser: null }); }, /** * Open address book inside a Popover * @param event */ openAddressBook: function openAddressBook(event) { this.setState({ addressBookOpen: true, addressBookAnchor: event.currentTarget }); }, /** * Close address book popover */ closeAddressBook: function closeAddressBook() { this.setState({ addressBookOpen: false }); }, /** * Triggered when user clicks on an entry from adress book. * @param item */ onAddressBookItemSelected: function onAddressBookItemSelected(item) { this.props.onValueSelected(item); }, render: function render() { var _this = this; var _state = this.state; var dataSource = _state.dataSource; var createUser = _state.createUser; var containerStyle = { position: 'relative', overflow: 'visible' }; /* if(createUser){ return (
); } */ return React.createElement( 'div', { style: containerStyle, ref: function (el) { _this._popoverAnchor = el; } }, !createUser && React.createElement(AutoComplete, { filter: MaterialUI.AutoComplete.noFilter, dataSource: dataSource, searchText: this.state.searchText, onUpdateInput: this.textFieldUpdate, className: this.props.className, openOnFocus: true, floatingLabelText: this.props.fieldLabel, underlineShow: !this.props.underlineHide, fullWidth: true, onNewRequest: this.onCompleterRequest, listStyle: { maxHeight: 350, overflowY: 'auto' }, onFocus: function () { _this.loadBuffered(_this.state.searchText, 100); } }), createUser && React.createElement(TextField, { floatingLabelText: this.props.fieldLabel, value: global.pydio.MessageHash[485] + ' (' + this.state.createUser + ')', disabled: true, fullWidth: true, underlineShow: !this.props.underlineHide }), !createUser && React.createElement( 'div', { style: { position: 'absolute', right: 4, bottom: 14, height: 20, width: 20 } }, React.createElement(RefreshIndicator, { size: 20, left: 0, top: 0, status: this.state.loading ? 'loading' : 'hide' }) ), this.props.showAddressBook && !createUser && React.createElement(_addressbookAddressBook2['default'], { mode: 'popover', pydio: this.props.pydio, loaderStyle: { width: 320, height: 420 }, onItemSelected: this.onAddressBookItemSelected, usersFrom: this.props.usersFrom, disableSearch: true }), React.createElement( Popover, { open: createUser, anchorEl: this._popoverAnchor, anchorOrigin: { horizontal: 'left', vertical: 'bottom' }, targetOrigin: { horizontal: 'left', vertical: 'top' }, onRequestClose: this.onCreationCancelled, canAutoPosition: false }, createUser && React.createElement(AsyncComponent, { namespace: "PydioForm", componentName: "UserCreationForm", style: { width: 350, height: 320 }, newUserName: this.state.createUser, onUserCreated: this.onUserCreated, onCancel: this.onCreationCancelled, pydio: this.props.pydio }) ) ); } }); exports['default'] = UsersLoader; module.exports = exports['default']; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"./addressbook/AddressBook":34,"material-ui":"material-ui","pydio/http/resources-manager":"pydio/http/resources-manager","pydio/util/func":"pydio/util/func","react":"react"}],34:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = 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; }; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } var _NestedListItem = require('./NestedListItem'); var _NestedListItem2 = _interopRequireDefault(_NestedListItem); var _UsersList = require('./UsersList'); var _UsersList2 = _interopRequireDefault(_UsersList); var _RightPanelCard = require('./RightPanelCard'); var _RightPanelCard2 = _interopRequireDefault(_RightPanelCard); var _SearchPanel = require('./SearchPanel'); var _SearchPanel2 = _interopRequireDefault(_SearchPanel); var _Loaders = require('./Loaders'); var _Loaders2 = _interopRequireDefault(_Loaders); var _TeamCreationForm = require('../TeamCreationForm'); var _TeamCreationForm2 = _interopRequireDefault(_TeamCreationForm); var React = require('react'); var Pydio = require('pydio'); var _Pydio$requireLib = Pydio.requireLib('boot'); var AsyncComponent = _Pydio$requireLib.AsyncComponent; var PydioContextConsumer = _Pydio$requireLib.PydioContextConsumer; var _require = require('material-ui'); var Popover = _require.Popover; var IconButton = _require.IconButton; var _require2 = require('material-ui/styles'); var muiThemeable = _require2.muiThemeable; var colors = _require2.colors; /** * High level component to browse users, groups and teams, either in a large format (mode='book') or a more compact * format (mode='selector'|'popover'). * Address book allows to create external users, teams, and also to browse trusted server directories if Federated Sharing * is active. */ var AddressBook = React.createClass({ displayName: 'AddressBook', propTypes: { /** * Main instance of pydio */ pydio: React.PropTypes.instanceOf(Pydio), /** * Display mode, either large (book) or small picker ('selector', 'popover'). */ mode: React.PropTypes.oneOf(['book', 'selector', 'popover']).isRequired, /** * Callback triggered in 'selector' mode whenever an item is clicked. */ onItemSelected: React.PropTypes.func, /** * Display users only, no teams or groups */ usersOnly: React.PropTypes.bool, /** * Choose various user sources, either the local directory or remote ( = trusted ) servers. */ usersFrom: React.PropTypes.oneOf(['local', 'remote', 'any']), /** * Disable the search engine */ disableSearch: React.PropTypes.bool, /** * Theme object passed by muiThemeable() wrapper */ muiTheme: React.PropTypes.object, /** * Will be passed to the Popover object */ popoverStyle: React.PropTypes.object, /** * Used as a button to open the selector in a popover */ popoverButton: React.PropTypes.object, /** * Will be passed to the Popover container object */ popoverContainerStyle: React.PropTypes.object, /** * Will be passed to the Popover Icon Button. */ popoverIconButtonStyle: React.PropTypes.object }, getDefaultProps: function getDefaultProps() { return { mode: 'book', usersOnly: false, usersFrom: 'any', teamsOnly: false, disableSearch: false }; }, getInitialState: function getInitialState() { var _this = this; var _props = this.props; var pydio = _props.pydio; var mode = _props.mode; var usersOnly = _props.usersOnly; var usersFrom = _props.usersFrom; var teamsOnly = _props.teamsOnly; var disableSearch = _props.disableSearch; var getMessage = function getMessage(id) { return _this.props.getMessage(id, ''); }; var confConfigs = pydio.getPluginConfigs('core.conf'); var root = undefined; if (teamsOnly) { root = { id: 'teams', label: getMessage(568), childrenLoader: _Loaders2['default'].loadTeams, _parent: null, _notSelectable: true, actions: { type: 'teams', create: '+ ' + getMessage(569), remove: getMessage(570), multiple: true } }; return { root: root, selectedItem: root, loading: false, rightPaneItem: null }; } root = { id: 'root', label: getMessage(592), type: 'root', collections: [] }; if (usersFrom !== 'remote') { if (confConfigs.get('USER_CREATE_USERS')) { root.collections.push({ id: 'ext', label: getMessage(593), //icon:'mdi mdi-account-network', itemsLoader: _Loaders2['default'].loadExternalUsers, _parent: root, _notSelectable: true, actions: { type: 'users', create: '+ ' + getMessage(484), remove: getMessage(582), multiple: true } }); } if (!usersOnly) { root.collections.push({ id: 'teams', label: getMessage(568), //icon: 'mdi mdi-account-multiple', childrenLoader: _Loaders2['default'].loadTeams, _parent: root, _notSelectable: true, actions: { type: 'teams', create: '+ ' + getMessage(569), remove: getMessage(570), multiple: true } }); } if (confConfigs.get('ALLOW_CROSSUSERS_SHARING')) { var groupOrUsers = confConfigs.get('ADDRESSBOOK_GROUP_OR_USERS'); if (groupOrUsers && groupOrUsers.group_switch_value) groupOrUsers = groupOrUsers.group_switch_value;else groupOrUsers = 'both'; if (groupOrUsers === 'search') { if (!disableSearch) { root.collections.push({ id: 'search', label: getMessage(583), //icon:'mdi mdi-account-search', type: 'search', _parent: root, _notSelectable: true }); } } else { root.collections.push({ id: 'AJXP_GRP_/', label: getMessage(584), //icon:'mdi mdi-account-box', childrenLoader: groupOrUsers === 'both' || groupOrUsers === 'groups' ? _Loaders2['default'].loadGroups : null, itemsLoader: groupOrUsers === 'both' || groupOrUsers === 'users' ? _Loaders2['default'].loadGroupUsers : null, _parent: root, _notSelectable: true }); } } } var ocsRemotes = pydio.getPluginConfigs('core.ocs').get('TRUSTED_SERVERS'); if (ocsRemotes && !usersOnly && usersFrom !== 'local') { var remotes = JSON.parse(ocsRemotes); var remotesNodes = { id: 'remotes', label: getMessage(594), //icon:'mdi mdi-server', collections: [], _parent: root, _notSelectable: true }; for (var k in remotes) { if (!remotes.hasOwnProperty(k)) continue; remotesNodes.collections.push({ id: k, label: remotes[k], icon: 'mdi mdi-server-network', type: 'remote', _parent: remotesNodes, _notSelectable: true }); } if (remotesNodes.collections.length) { root.collections.push(remotesNodes); } } return { root: root, selectedItem: mode === 'selector' ? root : root.collections[0], loading: false, rightPaneItem: null }; }, componentDidMount: function componentDidMount() { this.state.selectedItem && this.onFolderClicked(this.state.selectedItem); }, onFolderClicked: function onFolderClicked(item) { var _this2 = this; var callback = arguments.length <= 1 || arguments[1] === undefined ? undefined : arguments[1]; // Special case for teams if (item.type === 'group' && item.id.indexOf('/AJXP_TEAM/') === 0) { this.onUserListItemClicked(item); return; } this.setState({ loading: true }); _Loaders2['default'].childrenAsPromise(item, false).then(function (children) { _Loaders2['default'].childrenAsPromise(item, true).then(function (children) { _this2.setState({ selectedItem: item, loading: false }, callback); }); }); }, onUserListItemClicked: function onUserListItemClicked(item) { if (this.props.onItemSelected) { var uObject = new PydioUsers.User(item.id, item.label, item.type, item.group, item.avatar, item.temporary, item.external); if (item.trusted_server_id) { uObject.trustedServerId = item.trusted_server_id; uObject.trustedServerLabel = item.trusted_server_label; } this.props.onItemSelected(uObject); } else { this.setState({ rightPaneItem: item }); } }, onCreateAction: function onCreateAction(item) { this.setState({ createDialogItem: item }); }, closeCreateDialogAndReload: function closeCreateDialogAndReload() { this.setState({ createDialogItem: null }); this.reloadCurrentNode(); }, onCardUpdateAction: function onCardUpdateAction(item) { if (item._parent && item._parent === this.state.selectedItem) { this.reloadCurrentNode(); } }, onDeleteAction: function onDeleteAction(parentItem, selection) { if (!confirm(this.props.getMessage(278))) { return; } switch (parentItem.actions.type) { case 'users': selection.forEach((function (user) { if (this.state.rightPaneItem === user) this.setState({ rightPaneItem: null }); PydioUsers.Client.deleteUser(user.id, this.reloadCurrentNode.bind(this)); }).bind(this)); break; case 'teams': selection.forEach((function (team) { if (this.state.rightPaneItem === team) this.setState({ rightPaneItem: null }); PydioUsers.Client.deleteTeam(team.id.replace('/AJXP_TEAM/', ''), this.reloadCurrentNode.bind(this)); }).bind(this)); break; case 'team': _TeamCreationForm2['default'].updateTeamUsers(parentItem, 'delete', selection, this.reloadCurrentNode.bind(this)); break; default: break; } }, openPopover: function openPopover(event) { this.setState({ popoverOpen: true, popoverAnchor: event.currentTarget }); }, closePopover: function closePopover() { this.setState({ popoverOpen: false }); }, reloadCurrentNode: function reloadCurrentNode() { var _this3 = this; this.state.selectedItem.leafLoaded = false; this.state.selectedItem.collectionsLoaded = false; this.onFolderClicked(this.state.selectedItem, function () { if (_this3.state.rightPaneItem) { (function () { var rPaneId = _this3.state.rightPaneItem.id; var foundItem = null; var leafs = _this3.state.selectedItem.leafs || []; var collections = _this3.state.selectedItem.collections || []; [].concat(leafs, collections).forEach(function (leaf) { if (leaf.id === rPaneId) foundItem = leaf; }); _this3.setState({ rightPaneItem: foundItem }); })(); } }); }, reloadCurrentAtPage: function reloadCurrentAtPage(letterOrRange) { this.state.selectedItem.leafLoaded = false; this.state.selectedItem.collectionsLoaded = false; if (letterOrRange === -1) { this.state.selectedItem.currentParams = null; } else if (letterOrRange.indexOf('-') !== -1) { this.state.selectedItem.range = letterOrRange; } else { this.state.selectedItem.range = null; this.state.selectedItem.currentParams = { alpha_pages: 'true', value: letterOrRange }; } this.onFolderClicked(this.state.selectedItem); }, reloadCurrentWithSearch: function reloadCurrentWithSearch(value) { if (!value) { this.reloadCurrentAtPage(-1); return; } this.state.selectedItem.leafLoaded = false; this.state.selectedItem.collectionsLoaded = false; this.state.selectedItem.currentParams = { has_search: true, value: value, existing_only: true }; this.onFolderClicked(this.state.selectedItem); }, render: function render() { var _this4 = this; var _props2 = this.props; var mode = _props2.mode; var muiTheme = _props2.muiTheme; var getMessage = _props2.getMessage; if (mode === 'popover') { var popoverStyle = this.props.popoverStyle || {}; var popoverContainerStyle = this.props.popoverContainerStyle || {}; var iconButtonStyle = this.props.popoverIconButtonStyle || {}; var iconButton = React.createElement(IconButton, { style: _extends({ position: 'absolute', padding: 15, zIndex: 100, right: 0, top: 25, display: this.state.loading ? 'none' : 'initial' }, iconButtonStyle), iconStyle: { fontSize: 19, color: 'rgba(0,0,0,0.6)' }, iconClassName: 'mdi mdi-book-open-variant', onTouchTap: this.openPopover }); if (this.props.popoverButton) { iconButton = React.createElement(this.props.popoverButton.type, _extends({}, this.props.popoverButton.props, { onTouchTap: this.openPopover })); } return React.createElement( 'span', null, iconButton, React.createElement( Popover, { open: this.state.popoverOpen, anchorEl: this.state.popoverAnchor, anchorOrigin: { horizontal: 'right', vertical: 'top' }, targetOrigin: { horizontal: 'left', vertical: 'top' }, onRequestClose: this.closePopover, style: _extends({ marginLeft: 20 }, popoverStyle), zDepth: 2 }, React.createElement( 'div', { style: _extends({ width: 320, height: 420 }, popoverContainerStyle) }, React.createElement(AddressBook, _extends({}, this.props, { mode: 'selector' })) ) ) ); } var _state = this.state; var selectedItem = _state.selectedItem; var root = _state.root; var rightPaneItem = _state.rightPaneItem; var createDialogItem = _state.createDialogItem; var leftColumnStyle = { backgroundColor: colors.grey100, width: 256, overflowY: 'auto', overflowX: 'hidden' }; var centerComponent = undefined, rightPanel = undefined, leftPanel = undefined; if (selectedItem.id === 'search') { centerComponent = React.createElement(_SearchPanel2['default'], { item: selectedItem, title: getMessage(583, ''), searchLabel: getMessage(595, ''), onItemClicked: this.onUserListItemClicked, onFolderClicked: this.onFolderClicked, mode: mode }); } else if (selectedItem.type === 'remote') { centerComponent = React.createElement(_SearchPanel2['default'], { item: selectedItem, params: { trusted_server_id: selectedItem.id }, searchLabel: getMessage(595, ''), title: getMessage(596, '').replace('%s', selectedItem.label), onItemClicked: this.onUserListItemClicked, onFolderClicked: this.onFolderClicked, mode: mode }); } else { var emptyStatePrimary = undefined; var emptyStateSecondary = undefined; var otherProps = {}; if (selectedItem.id === 'teams') { emptyStatePrimary = getMessage(571, ''); emptyStateSecondary = getMessage(572, ''); } else if (selectedItem.id === 'ext') { emptyStatePrimary = getMessage(585, ''); emptyStateSecondary = getMessage(586, ''); } else if (selectedItem.id.indexOf('AJXP_GRP_/') === 0) { otherProps = { showSubheaders: true, paginatorType: !(selectedItem.currentParams && selectedItem.currentParams.has_search) && 'alpha', paginatorCallback: this.reloadCurrentAtPage.bind(this), enableSearch: !this.props.disableSearch, searchLabel: getMessage(595, ''), onSearch: this.reloadCurrentWithSearch.bind(this) }; } centerComponent = React.createElement(_UsersList2['default'], _extends({ item: selectedItem, onItemClicked: this.onUserListItemClicked, onFolderClicked: this.onFolderClicked, onCreateAction: this.onCreateAction, onDeleteAction: this.onDeleteAction, loading: this.state.loading, mode: mode, emptyStatePrimaryText: emptyStatePrimary, emptyStateSecondaryText: emptyStateSecondary, onTouchTap: this.state.rightPaneItem ? function () { _this4.setState({ rightPaneItem: null }); } : null }, otherProps)); } var rightPanelStyle = _extends({}, leftColumnStyle, { transformOrigin: 'right', backgroundColor: 'white' }); if (!rightPaneItem) { rightPanelStyle = _extends({}, rightPanelStyle, { transform: 'translateX(256px)', width: 0 }); } rightPanel = React.createElement(_RightPanelCard2['default'], { pydio: this.props.pydio, onRequestClose: function () { _this4.setState({ rightPaneItem: null }); }, style: rightPanelStyle, onCreateAction: this.onCreateAction, onDeleteAction: this.onDeleteAction, onUpdateAction: this.onCardUpdateAction, item: rightPaneItem }); if (mode === 'book') { leftPanel = React.createElement( MaterialUI.Paper, { zDepth: 0, style: _extends({}, leftColumnStyle, { zIndex: 2 }) }, React.createElement( MaterialUI.List, null, root.collections.map((function (e) { return React.createElement(_NestedListItem2['default'], { key: e.id, selected: selectedItem.id, nestedLevel: 0, entry: e, onTouchTap: this.onFolderClicked }); }).bind(this)) ) ); } var dialogTitle = undefined, dialogContent = undefined; if (createDialogItem) { if (createDialogItem.actions.type === 'users') { dialogTitle = getMessage(484, ''); dialogContent = React.createElement( 'div', { style: { height: 500 } }, React.createElement(AsyncComponent, { namespace: 'PydioForm', componentName: 'UserCreationForm', zDepth: 0, style: { height: 500 }, newUserName: "", onUserCreated: this.closeCreateDialogAndReload, onCancel: function () { _this4.setState({ createDialogItem: null }); }, pydio: this.props.pydio }) ); } else if (createDialogItem.actions.type === 'teams') { dialogTitle = getMessage(569, ''); dialogContent = React.createElement(_TeamCreationForm2['default'], { onTeamCreated: this.closeCreateDialogAndReload, onCancel: function () { _this4.setState({ createDialogItem: null }); } }); } else if (createDialogItem.actions.type === 'team') { var selectUser = function selectUser(item) { _TeamCreationForm2['default'].updateTeamUsers(createDialogItem, 'add', [item], _this4.reloadCurrentNode.bind(_this4)); }; dialogTitle = null; dialogContent = React.createElement(AddressBook, { pydio: this.props.pydio, mode: 'selector', usersOnly: true, disableSearch: true, onItemSelected: selectUser }); } } var style = this.props.style || {}; return React.createElement( 'div', { style: _extends({ display: 'flex', height: mode === 'selector' ? 420 : 450 }, style) }, leftPanel, centerComponent, rightPanel, React.createElement( MaterialUI.Dialog, { contentStyle: { width: 380, minWidth: 380, maxWidth: 380, padding: 0 }, bodyStyle: { padding: 0 }, title: React.createElement( 'div', { style: { padding: 20 } }, dialogTitle ), actions: null, modal: false, open: createDialogItem ? true : false, onRequestClose: function () { _this4.setState({ createDialogItem: null }); } }, dialogContent ) ); } }); exports['default'] = AddressBook = PydioContextConsumer(AddressBook); exports['default'] = AddressBook = muiThemeable()(AddressBook); exports['default'] = AddressBook; module.exports = exports['default']; },{"../TeamCreationForm":32,"./Loaders":36,"./NestedListItem":37,"./RightPanelCard":38,"./SearchPanel":40,"./UsersList":43,"material-ui":"material-ui","material-ui/styles":"material-ui/styles","pydio":"pydio","react":"react"}],35:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = 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; }; 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 _react = require('react'); var _materialUiStyles = require('material-ui/styles'); var _pydio = require('pydio'); var _pydio2 = _interopRequireDefault(_pydio); var _materialUi = require('material-ui'); /** * Alphabet and pages generator to give a first-letter-based pagination */ var _Pydio$requireLib = _pydio2['default'].requireLib('boot'); var PydioContextConsumer = _Pydio$requireLib.PydioContextConsumer; var AlphaPaginator = (function (_Component) { _inherits(AlphaPaginator, _Component); function AlphaPaginator() { _classCallCheck(this, AlphaPaginator); _Component.apply(this, arguments); } AlphaPaginator.prototype.render = function render() { var letters = 'abcdefghijklmnopqrstuvwxyz0123456789'.split(''); letters = [-1].concat(letters); var _props = this.props; var item = _props.item; var paginatorCallback = _props.paginatorCallback; var style = _props.style; var getMessage = _props.getMessage; var paginator = undefined; if (item.pagination) { (function () { var _item$pagination = item.pagination; var start = _item$pagination.start; var end = _item$pagination.end; var max = _item$pagination.max; var interval = _item$pagination.interval; var total_pages = Math.ceil(max / interval); var current = Math.ceil(start / interval); var pages = []; for (var i = 0; i < total_pages; i++) { pages.push(i); }paginator = React.createElement( _materialUi.SelectField, { floatingLabelText: getMessage(331), style: { width: 60 }, fullWidth: true, value: current, onChange: function (e, i, v) { paginatorCallback(v * interval + '-' + (v + 1) * interval); } }, pages.map(function (p) { return React.createElement(_materialUi.MenuItem, { value: p, key: p, primaryText: p + 1 }); }) ); })(); } var currentPage = item.currentParams && item.currentParams.alpha_pages && item.currentParams.value || -1; return React.createElement( 'div', { style: _extends({}, style, { display: 'flex', paddingRight: 8, alignItems: 'center' }) }, React.createElement( 'div', { style: { flex: 1 } }, getMessage(249, '') ), paginator, React.createElement( _materialUi.SelectField, { floatingLabelText: getMessage(625), style: { width: 60, marginLeft: 20 }, fullWidth: true, value: currentPage, onChange: function (e, i, v) { paginatorCallback(v); } }, letters.map(function (l) { return React.createElement(_materialUi.MenuItem, { value: l, key: l, primaryText: l === -1 ? getMessage(597, '') : l }); }) ) ); }; return AlphaPaginator; })(_react.Component); AlphaPaginator.propTypes = { /** * Currently selected Item */ item: _react.PropTypes.object, /** * When a letter is clicked, function(letter) */ paginatorCallback: _react.PropTypes.func.isRequired, /** * Main instance of pydio */ pydio: _react.PropTypes.instanceOf(_pydio2['default']), /** * Display mode, either large (book) or small picker ('selector', 'popover'). */ mode: _react.PropTypes.oneOf(['book', 'selector', 'popover']).isRequired }; exports['default'] = AlphaPaginator = PydioContextConsumer(AlphaPaginator); exports['default'] = AlphaPaginator = _materialUiStyles.muiThemeable()(AlphaPaginator); exports['default'] = AlphaPaginator; module.exports = exports['default']; },{"material-ui":"material-ui","material-ui/styles":"material-ui/styles","pydio":"pydio","react":"react"}],36:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = 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; }; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } var Loaders = (function () { function Loaders() { _classCallCheck(this, Loaders); } Loaders.childrenAsPromise = function childrenAsPromise(item) { var leaf = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1]; var childrenLoader = item.childrenLoader; var itemsLoader = item.itemsLoader; var leafLoaded = item.leafLoaded; var collectionsLoaded = item.collectionsLoaded; var leafs = item.leafs; var collections = item.collections; var loader = leaf ? itemsLoader : childrenLoader; var loaded = leaf ? leafLoaded : collectionsLoaded; return new Promise(function (resolve, reject) { if (!loaded && loader) { loader(item, function (newChildren) { if (leaf) { item.leafs = newChildren; item.leafLoaded = true; } else { item.collections = newChildren; item.collectionsLoaded = true; } resolve(newChildren); }); } else { var res = (leaf ? leafs : collections) || []; resolve(res); } }); }; Loaders.listUsers = function listUsers(params, callback) { var parent = arguments.length <= 2 || arguments[2] === undefined ? null : arguments[2]; var baseParams = { get_action: 'user_list_authorized_users', format: 'json' }; baseParams = _extends({}, baseParams, params); var cb = callback; if (parent) { if (parent.range) { baseParams['range'] = parent.range; } cb = function (children) { callback(children.map(function (c) { c._parent = parent;return c; })); }; } PydioApi.getClient().request(baseParams, function (transport) { cb(transport.responseJSON); var cRange = transport.responseObject.headers.get('Content-Range'); var aRange = transport.responseObject.headers.get('Accept-Range'); if (cRange && aRange && parent) { var _aRange$split = aRange.split(' '); var type = _aRange$split[0]; var interval = _aRange$split[1]; var _cRange$split = cRange.split('/'); var range = _cRange$split[0]; var max = _cRange$split[1]; var _range$split = range.split('-'); var start = _range$split[0]; var end = _range$split[1]; parent.pagination = { start: parseInt(start), end: parseInt(end), max: parseInt(max), interval: parseInt(interval) }; } }); }; Loaders.loadTeams = function loadTeams(entry, callback) { var wrapped = function wrapped(children) { children.map(function (child) { child.icon = 'mdi mdi-account-multiple'; child.itemsLoader = Loaders.loadTeamUsers; child.actions = { type: 'team', create: '573', remove: '574', multiple: true }; child._notSelectable = true; }); callback(children); }; Loaders.listUsers({ filter_value: 8 }, wrapped, entry); }; Loaders.loadGroups = function loadGroups(entry, callback) { var wrapped = function wrapped(children) { children.map(function (child) { child.icon = 'mdi mdi-account-multiple'; child.childrenLoader = entry.childrenLoader ? Loaders.loadGroups : null; child.itemsLoader = entry.itemsLoader ? Loaders.loadGroupUsers : null; if (entry.currentParams && entry.currentParams.alpha_pages) { child.currentParams = _extends({}, entry.currentParams); } }); callback(children); }; var path = entry.id.replace('AJXP_GRP_', ''); var params = { filter_value: 4, group_path: path }; if (entry.currentParams && !entry.currentParams.alpha_pages) { params = _extends({}, params, entry.currentParams); } Loaders.listUsers(params, wrapped, entry); }; Loaders.loadExternalUsers = function loadExternalUsers(entry, callback) { Loaders.listUsers({ filter_value: 2 }, callback, entry); }; Loaders.loadGroupUsers = function loadGroupUsers(entry, callback) { var path = entry.id.replace('AJXP_GRP_', ''); var params = { filter_value: 1, group_path: path }; if (entry.currentParams) { params = _extends({}, params, entry.currentParams); } Loaders.listUsers(params, callback, entry); }; Loaders.loadTeamUsers = function loadTeamUsers(entry, callback) { Loaders.listUsers({ filter_value: 3, group_path: entry.id }, callback, entry); }; return Loaders; })(); exports['default'] = Loaders; module.exports = exports['default']; },{}],37:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; 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; /** * Left panel of the address book * Display treeview hierarchy of users, teams, groups. */ var NestedListItem = (function (_Component) { _inherits(NestedListItem, _Component); function NestedListItem() { _classCallCheck(this, NestedListItem); _Component.apply(this, arguments); } /** * Triggers this.props.onTouchTap */ NestedListItem.prototype.onTouchTap = function onTouchTap() { this.props.onTouchTap(this.props.entry); }; /** * Recursively build other NestedListItem * @param data */ NestedListItem.prototype.buildNestedItems = function buildNestedItems(data) { return data.map((function (entry) { return React.createElement(NestedListItem, { nestedLevel: this.props.nestedLevel + 1, entry: entry, onTouchTap: this.props.onTouchTap, selected: this.props.selected }); }).bind(this)); }; NestedListItem.prototype.render = function render() { var _props$entry = this.props.entry; var id = _props$entry.id; var label = _props$entry.label; var icon = _props$entry.icon; var selected = _props$entry.selected; var children = this.props.entry.collections || []; var nested = this.buildNestedItems(children); var fontIcon = undefined; if (icon) { fontIcon = React.createElement(MaterialUI.FontIcon, { className: icon }); } return React.createElement(MaterialUI.ListItem, { nestedLevel: this.props.nestedLevel, key: id, primaryText: label, onTouchTap: this.onTouchTap.bind(this), nestedItems: nested, initiallyOpen: true, leftIcon: false && fontIcon, innerDivStyle: { fontWeight: this.props.selected === this.props.entry.id ? 500 : 400 } }); }; return NestedListItem; })(Component); NestedListItem.propTypes = { /** * Keeps track of the current depth level */ nestedLevel: PropTypes.number, /** * Currently selected node id */ selected: PropTypes.string, /** * Callback triggered when an entry is selected */ onTouchTap: PropTypes.func }; exports['default'] = NestedListItem; module.exports = exports['default']; },{"react":"react"}],38:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = 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; }; 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 _TeamCard = require('./TeamCard'); var _TeamCard2 = _interopRequireDefault(_TeamCard); var _UserCard = require('./UserCard'); var _UserCard2 = _interopRequireDefault(_UserCard); var React = require('react'); var _require = require('material-ui'); var Paper = _require.Paper; /** * Container for UserCard or TeamCard */ var RightPanelCard = (function (_React$Component) { _inherits(RightPanelCard, _React$Component); function RightPanelCard() { _classCallCheck(this, RightPanelCard); _React$Component.apply(this, arguments); } RightPanelCard.prototype.render = function render() { var content = undefined; var item = this.props.item || {}; if (item.type === 'user') { content = React.createElement(_UserCard2['default'], this.props); } else if (item.type === 'group' && item.id.indexOf('/AJXP_TEAM/') === 0) { content = React.createElement(_TeamCard2['default'], this.props); } return React.createElement( Paper, { zDepth: 2, style: _extends({ position: 'relative' }, this.props.style) }, content ); }; return RightPanelCard; })(React.Component); RightPanelCard.propTypes = { /** * Pydio instance */ pydio: React.PropTypes.instanceOf(Pydio), /** * Selected item */ item: React.PropTypes.object, /** * Applies to root container */ style: React.PropTypes.object, /** * Forwarded to child */ onRequestClose: React.PropTypes.func, /** * Forwarded to child */ onDeleteAction: React.PropTypes.func, /** * Forwarded to child */ onUpdateAction: React.PropTypes.func }; exports['default'] = RightPanelCard; module.exports = exports['default']; },{"./TeamCard":41,"./UserCard":42,"material-ui":"material-ui","react":"react"}],39:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = 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; }; 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; /** * Ready to use Form + Result List for search users */ var SearchForm = (function (_Component) { _inherits(SearchForm, _Component); function SearchForm(props, context) { _classCallCheck(this, SearchForm); _Component.call(this, props.context); this.state = { value: '' }; } SearchForm.prototype.search = function search() { this.props.onSearch(this.state.value); }; SearchForm.prototype.onChange = function onChange(event, value) { this.setState({ value: value }); FuncUtils.bufferCallback('search_users_list', 300, this.search.bind(this)); }; SearchForm.prototype.render = function render() { return React.createElement( 'div', { style: _extends({ minWidth: 320 }, this.props.style) }, React.createElement(MaterialUI.TextField, { fullWidth: true, value: this.state.value, onChange: this.onChange.bind(this), hintText: this.props.searchLabel }) ); }; return SearchForm; })(Component); SearchForm.propTypes = { /** * Label displayed in the search field */ searchLabel: PropTypes.string.isRequired, /** * Callback triggered to search */ onSearch: PropTypes.func.isRequired, /** * Will be appended to the root element */ style: PropTypes.object }; exports['default'] = SearchForm; module.exports = exports['default']; },{"react":"react"}],40:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = 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; }; 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 _SearchForm = require('./SearchForm'); var _SearchForm2 = _interopRequireDefault(_SearchForm); var _UsersList = require('./UsersList'); var _UsersList2 = _interopRequireDefault(_UsersList); var _Loaders = require('./Loaders'); var _Loaders2 = _interopRequireDefault(_Loaders); /** * Ready to use Form + Result List for search users */ var _require = require('react'); var Component = _require.Component; var PropTypes = _require.PropTypes; var _require$requireLib = require('pydio').requireLib('boot'); var PydioContextConsumer = _require$requireLib.PydioContextConsumer; var SearchPanel = (function (_Component) { _inherits(SearchPanel, _Component); function SearchPanel(props, context) { _classCallCheck(this, SearchPanel); _Component.call(this, props.context); this.state = { items: [] }; } SearchPanel.prototype.onSearch = function onSearch(value) { var _this = this; if (!value) { this.setState({ items: [] }); return; } var params = { value: value, existing_only: 'true' }; if (this.props.params) { params = _extends({}, params, this.props.params); } _Loaders2['default'].listUsers(params, function (children) { _this.setState({ items: children }); }); }; SearchPanel.prototype.render = function render() { var _this2 = this; var _props = this.props; var mode = _props.mode; var item = _props.item; var getMessage = _props.getMessage; return React.createElement( 'div', { style: { flex: 1, display: 'flex', flexDirection: 'column' } }, React.createElement( 'div', { style: { padding: 10, height: 56, backgroundColor: this.state.select ? activeTbarColor : '#fafafa', display: 'flex', alignItems: 'center', transition: DOMUtils.getBeziersTransition() } }, mode === "selector" && item._parent && React.createElement(MaterialUI.IconButton, { iconClassName: 'mdi mdi-chevron-left', onTouchTap: function () { _this2.props.onFolderClicked(item._parent); } }), mode === 'book' && React.createElement( 'div', { style: { fontSize: 20, color: 'rgba(0,0,0,0.87)', flex: 1 } }, this.props.title ), React.createElement(_SearchForm2['default'], { style: mode === 'book' ? { minWidth: 320 } : { flex: 1 }, searchLabel: this.props.searchLabel, onSearch: this.onSearch.bind(this) }) ), React.createElement(_UsersList2['default'], { mode: this.props.mode, onItemClicked: this.props.onItemClicked, item: { leafs: this.state.items }, noToolbar: true, emptyStatePrimaryText: getMessage(587, ''), emptyStateSecondaryText: getMessage(588, '') }) ); }; return SearchPanel; })(Component); SearchPanel.propTypes = { /** * Optional parameters added to listUsers() request */ params: PropTypes.object, /** * Label displayed in the toolbar */ searchLabel: PropTypes.string, /** * Callback triggered when a search result is clicked */ onItemClicked: PropTypes.func, /** * Currently selected item, required for navigation */ item: PropTypes.object, /** * Callback triggered if the result is a collection */ onFolderClicked: PropTypes.func }; exports['default'] = SearchPanel = PydioContextConsumer(SearchPanel); exports['default'] = SearchPanel; module.exports = exports['default']; },{"./Loaders":36,"./SearchForm":39,"./UsersList":43,"pydio":"pydio","react":"react"}],41:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = 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; }; 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 _UsersList = require('./UsersList'); var _UsersList2 = _interopRequireDefault(_UsersList); var _Loaders = require('./Loaders'); var _Loaders2 = _interopRequireDefault(_Loaders); var _avatarActionsPanel = require('../avatar/ActionsPanel'); var _avatarActionsPanel2 = _interopRequireDefault(_avatarActionsPanel); var React = require('react'); var _require = require('material-ui'); var TextField = _require.TextField; var FlatButton = _require.FlatButton; var CardTitle = _require.CardTitle; var Divider = _require.Divider; var _require$requireLib = require('pydio').requireLib('boot'); var PydioContextConsumer = _require$requireLib.PydioContextConsumer; /** * Display info about a Team inside a popover-able card */ var TeamCard = (function (_React$Component) { _inherits(TeamCard, _React$Component); function TeamCard(props, context) { _classCallCheck(this, TeamCard); _React$Component.call(this, props, context); this.state = { label: this.props.item.label }; } /** * Use loader to get team participants * @param item */ TeamCard.prototype.loadMembers = function loadMembers(item) { var _this = this; this.setState({ loading: true }); _Loaders2['default'].childrenAsPromise(item, false).then(function (children) { _Loaders2['default'].childrenAsPromise(item, true).then(function (children) { _this.setState({ members: item.leafs, loading: false }); }); }); }; TeamCard.prototype.componentWillMount = function componentWillMount() { this.loadMembers(this.props.item); }; TeamCard.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) { this.loadMembers(nextProps.item); this.setState({ label: nextProps.item.label }); }; TeamCard.prototype.onLabelChange = function onLabelChange(e, value) { this.setState({ label: value }); }; TeamCard.prototype.updateLabel = function updateLabel() { var _this2 = this; if (this.state.label !== this.props.item.label) { PydioUsers.Client.updateTeamLabel(this.props.item.id.replace('/AJXP_TEAM/', ''), this.state.label, function () { _this2.props.onUpdateAction(_this2.props.item); }); } this.setState({ editMode: false }); }; TeamCard.prototype.render = function render() { var _this3 = this; var _props = this.props; var item = _props.item; var onDeleteAction = _props.onDeleteAction; var onCreateAction = _props.onCreateAction; var getMessage = _props.getMessage; var editProps = { team: item, userEditable: true, onDeleteAction: function onDeleteAction() { _this3.props.onDeleteAction(item._parent, [item]); }, onEditAction: function onEditAction() { _this3.setState({ editMode: !_this3.state.editMode }); }, reloadAction: function reloadAction() { _this3.props.onUpdateAction(item); } }; var title = undefined; if (this.state.editMode) { title = React.createElement( 'div', { style: { display: 'flex', alignItems: 'center', margin: 16 } }, React.createElement(TextField, { style: { flex: 1, fontSize: 24 }, fullWidth: true, disabled: false, underlineShow: false, value: this.state.label, onChange: this.onLabelChange.bind(this) }), React.createElement(FlatButton, { secondary: true, label: getMessage(48), onTouchTap: function () { _this3.updateLabel(); } }) ); } else { title = React.createElement(CardTitle, { title: this.state.label, subtitle: item.leafs && item.leafs.length ? getMessage(576).replace('%s', item.leafs.length) : getMessage(577) }); } return React.createElement( 'div', null, title, React.createElement(_avatarActionsPanel2['default'], _extends({}, this.props, editProps)), React.createElement(Divider, null), React.createElement(_UsersList2['default'], { subHeader: getMessage(575), onItemClicked: function () {}, item: item, mode: 'inner', onDeleteAction: onDeleteAction }) ); }; return TeamCard; })(React.Component); TeamCard.propTypes = { /** * Pydio instance */ pydio: React.PropTypes.instanceOf(Pydio), /** * Team data object */ item: React.PropTypes.object, /** * Applied to root container */ style: React.PropTypes.object, /** * Called to dismiss the popover */ onRequestClose: React.PropTypes.func, /** * Delete current team */ onDeleteAction: React.PropTypes.func, /** * Update current team */ onUpdateAction: React.PropTypes.func }; exports['default'] = TeamCard = PydioContextConsumer(TeamCard); exports['default'] = TeamCard; module.exports = exports['default']; },{"../avatar/ActionsPanel":44,"./Loaders":36,"./UsersList":43,"material-ui":"material-ui","pydio":"pydio","react":"react"}],42:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = 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; }; 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 _avatarUserAvatar = require('../avatar/UserAvatar'); var _avatarUserAvatar2 = _interopRequireDefault(_avatarUserAvatar); var React = require('react'); var _require$requireLib = require('pydio').requireLib('boot'); var AsyncComponent = _require$requireLib.AsyncComponent; /** * Card presentation of a user. Relies on the UserAvatar object, * plus the PydioForm.UserCreationForm when in edit mode. */ var UserCard = (function (_React$Component) { _inherits(UserCard, _React$Component); function UserCard(props, context) { _classCallCheck(this, UserCard); _React$Component.call(this, props, context); this.state = { editForm: false }; } UserCard.prototype.render = function render() { var _this = this; var item = this.props.item; var editableProps = {}, editForm = undefined; if (item._parent && item._parent.id === 'ext') { editableProps = { userEditable: true, onDeleteAction: function onDeleteAction() { _this.props.onDeleteAction(item._parent, [item]); }, onEditAction: function onEditAction() { _this.setState({ editForm: true }); }, reloadAction: function reloadAction() { _this.props.onUpdateAction(item); } }; } if (this.state.editForm) { editForm = React.createElement(AsyncComponent, { namespace: 'PydioForm', componentName: 'UserCreationForm', pydio: this.props.pydio, zDepth: 0, style: { height: 500 }, newUserName: item.id, editMode: true, userData: item, onUserCreated: function () { _this.props.onUpdateAction(item);_this.setState({ editForm: false }); }, onCancel: function () { _this.setState({ editForm: false }); } }); } return React.createElement( 'div', null, React.createElement( _avatarUserAvatar2['default'], _extends({ userId: this.props.item.id, richCard: true, pydio: this.props.pydio, cardSize: this.props.style.width }, editableProps), editForm ) ); }; return UserCard; })(React.Component); UserCard.propTypes = { /** * Pydio instance */ pydio: React.PropTypes.instanceOf(Pydio), /** * Team data object */ item: React.PropTypes.object, /** * Applied to root container */ style: React.PropTypes.object, /** * Called to dismiss the popover */ onRequestClose: React.PropTypes.func, /** * Delete current team */ onDeleteAction: React.PropTypes.func, /** * Update current team */ onUpdateAction: React.PropTypes.func }; exports['default'] = UserCard; module.exports = exports['default']; },{"../avatar/UserAvatar":46,"pydio":"pydio","react":"react"}],43:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = 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; }; 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 _avatarUserAvatar = require('../avatar/UserAvatar'); var _avatarUserAvatar2 = _interopRequireDefault(_avatarUserAvatar); var _viewsEmptyStateView = require('../../views/EmptyStateView'); var _viewsEmptyStateView2 = _interopRequireDefault(_viewsEmptyStateView); var _AlphaPaginator = require('./AlphaPaginator'); var _AlphaPaginator2 = _interopRequireDefault(_AlphaPaginator); var _SearchForm = require('./SearchForm'); var _SearchForm2 = _interopRequireDefault(_SearchForm); var _require = require('material-ui'); var IconButton = _require.IconButton; var Checkbox = _require.Checkbox; var FlatButton = _require.FlatButton; var RaisedButton = _require.RaisedButton; var ListItem = _require.ListItem; var FontIcon = _require.FontIcon; var Avatar = _require.Avatar; var Divider = _require.Divider; var Subheader = _require.Subheader; var List = _require.List; var _require2 = require('material-ui/styles'); var muiThemeable = _require2.muiThemeable; var _require$requireLib = require('pydio').requireLib('boot'); var Loader = _require$requireLib.Loader; var PydioContextConsumer = _require$requireLib.PydioContextConsumer; var UsersList = (function (_React$Component) { _inherits(UsersList, _React$Component); function UsersList(props, context) { _classCallCheck(this, UsersList); _React$Component.call(this, props, context); this.state = { select: false, selection: [] }; } UsersList.prototype.render = function render() { var _this = this; var _props = this.props; var item = _props.item; var mode = _props.mode; var paginatorType = _props.paginatorType; var loading = _props.loading; var enableSearch = _props.enableSearch; var showSubheaders = _props.showSubheaders; var getMessage = _props.getMessage; var folders = item.collections || []; var leafs = item.leafs || []; var foldersSubHeader = folders.length && (leafs.length || showSubheaders) ? [{ subheader: getMessage('532') }] : []; var usersSubHeader = []; if ((showSubheaders || paginatorType) && leafs.length) { usersSubHeader = [{ subheader: paginatorType ? React.createElement(_AlphaPaginator2['default'], _extends({}, this.props, { style: { lineHeight: '20px', padding: '14px 0' } })) : getMessage('249') }]; } var items = [].concat(foldersSubHeader, folders, usersSubHeader, leafs); var total = items.length; var elements = []; var toggleSelect = function toggleSelect() { _this.setState({ select: !_this.state.select, selection: [] }); }; var createAction = function createAction() { _this.props.onCreateAction(item); }; var deleteAction = function deleteAction() { _this.props.onDeleteAction(item, _this.state.selection);_this.setState({ select: false, selection: [] }); }; var activeTbarColor = this.props.muiTheme.palette.accent2Color; var toolbar = React.createElement( 'div', { style: { padding: 10, height: 56, backgroundColor: this.state.select ? activeTbarColor : '#fafafa', display: 'flex', alignItems: 'center', transition: DOMUtils.getBeziersTransition() } }, mode === "selector" && item._parent && React.createElement(IconButton, { iconClassName: 'mdi mdi-chevron-left', onTouchTap: function () { _this.props.onFolderClicked(item._parent); } }), mode === 'book' && total > 0 && item.actions && item.actions.multiple && React.createElement(Checkbox, { style: { width: 'initial', marginLeft: this.state.select ? 7 : 14 }, checked: this.state.select, onCheck: toggleSelect }), React.createElement( 'div', { style: { flex: 1, fontSize: 20, color: this.state.select ? 'white' : 'rgba(0,0,0,0.87)' } }, item.label ), mode === 'book' && item.actions && item.actions.create && !this.state.select && React.createElement(FlatButton, { secondary: true, label: getMessage(item.actions.create), onTouchTap: createAction }), mode === 'book' && item.actions && item.actions.remove && this.state.select && React.createElement(RaisedButton, { secondary: true, label: getMessage(item.actions.remove), disabled: !this.state.selection.length, onTouchTap: deleteAction }), enableSearch && React.createElement(_SearchForm2['default'], { searchLabel: this.props.searchLabel, onSearch: this.props.onSearch, style: { flex: 1, minWidth: 200 } }) ); // PARENT NODE if (item._parent && mode === 'book' && item._parent._parent) { elements.push(React.createElement(ListItem, { key: '__parent__', primaryText: "..", onTouchTap: function (e) { e.stopPropagation();_this.props.onFolderClicked(item._parent); }, leftAvatar: React.createElement(Avatar, { icon: React.createElement(FontIcon, { className: 'mdi mdi-arrow-up' }) }) })); if (total) { elements.push(React.createElement(Divider, { inset: true, key: 'parent-divider' })); } } // ITEMS items.forEach((function (item, index) { var _this2 = this; if (item.subheader) { elements.push(React.createElement( Subheader, null, item.subheader )); return; } var fontIcon = React.createElement(_avatarUserAvatar2['default'], { avatarSize: 36, pydio: this.props.pydio || pydio, userId: item.id, userLabel: item.label, avatar: item.avatar, icon: item.icon, avatarOnly: true, useDefaultAvatar: true }); var rightIconButton = undefined; var touchTap = function touchTap(e) { e.stopPropagation();_this2.props.onItemClicked(item); }; if (folders.indexOf(item) > -1 && this.props.onFolderClicked) { touchTap = function (e) { e.stopPropagation();_this2.props.onFolderClicked(item); }; if (mode === 'selector' && !item._notSelectable) { rightIconButton = React.createElement(IconButton, { iconClassName: "mdi mdi-account-multiple-plus", tooltip: "Select this group", tooltipPosition: 'bottom-left', onTouchTap: function () { _this2.props.onItemClicked(item); } }); } } else if (mode === 'inner' && this.props.onDeleteAction) { rightIconButton = React.createElement(IconButton, { iconClassName: "mdi mdi-delete", tooltip: getMessage(257), tooltipPosition: 'bottom-left', iconStyle: { color: 'rgba(0,0,0,0.13)', hoverColor: 'rgba(0,0,0,0.53)' }, onTouchTap: function () { _this2.props.onDeleteAction(_this2.props.item, [item]); } }); } var select = function select(e, checked) { if (checked) { _this2.setState({ selection: [].concat(_this2.state.selection, [item]) }); } else { var stateSel = _this2.state.selection; var selection = [].concat(stateSel.slice(0, stateSel.indexOf(item)), stateSel.slice(stateSel.indexOf(item) + 1)); _this2.setState({ selection: selection }); } }; elements.push(React.createElement(ListItem, { key: item.id, primaryText: item.label, onTouchTap: touchTap, disabled: mode === 'inner', leftAvatar: !this.state.select && fontIcon, rightIconButton: rightIconButton, leftCheckbox: this.state.select && React.createElement(Checkbox, { checked: this.state.selection.indexOf(item) > -1, onCheck: select }) })); if (mode !== 'inner' && index < total - 1) { elements.push(React.createElement(Divider, { inset: true, key: item.id + '-divider' })); } }).bind(this)); var emptyState = undefined; if (!elements.length) { var emptyStateProps = { style: { backgroundColor: 'rgb(250, 250, 250)' }, iconClassName: 'mdi mdi-account-off', primaryTextId: this.props.emptyStatePrimaryText || getMessage(629), secondaryTextId: mode === 'book' ? this.props.emptyStateSecondaryText || null : null }; if (mode === 'book' && item.actions && item.actions.create) { emptyStateProps = _extends({}, emptyStateProps, { actionLabelId: getMessage(item.actions.create), actionCallback: createAction }); } emptyState = React.createElement(_viewsEmptyStateView2['default'], emptyStateProps); } return React.createElement( 'div', { style: { flex: 1, flexDirection: 'column', display: 'flex' }, onTouchTap: this.props.onTouchTap }, mode !== 'inner' && /*(!emptyState || mode !== 'book') &&*/!this.props.noToolbar && toolbar, !emptyState && !loading && React.createElement( List, { style: { flex: 1, overflowY: mode !== 'inner' ? 'auto' : 'initial' } }, this.props.subHeader && React.createElement( Subheader, null, this.props.subHeader ), elements ), loading && React.createElement(Loader, { style: { flex: 1 } }), !loading && emptyState ); }; return UsersList; })(React.Component); UsersList.propTypes = { item: React.PropTypes.object, onCreateAction: React.PropTypes.func, onDeleteAction: React.PropTypes.func, onItemClicked: React.PropTypes.func, onFolderClicked: React.PropTypes.func, mode: React.PropTypes.oneOf(['book', 'selector', 'inner']) }; exports['default'] = UsersList = PydioContextConsumer(UsersList); exports['default'] = UsersList = muiThemeable()(UsersList); exports['default'] = UsersList; module.exports = exports['default']; },{"../../views/EmptyStateView":49,"../avatar/UserAvatar":46,"./AlphaPaginator":35,"./SearchForm":39,"material-ui":"material-ui","material-ui/styles":"material-ui/styles","pydio":"pydio"}],44:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; 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 _addressbookAddressBook = require('../addressbook/AddressBook'); var _addressbookAddressBook2 = _interopRequireDefault(_addressbookAddressBook); var React = require('react'); var _require = require('pydio/http/users-api'); var UsersApi = _require.UsersApi; var ResourcesManager = require('pydio/http/resources-manager'); var _require2 = require('material-ui'); var IconButton = _require2.IconButton; var Popover = _require2.Popover; var _require3 = require('material-ui/styles'); var muiThemeable = _require3.muiThemeable; var _require$requireLib = require('pydio').requireLib('boot'); var PydioContextConsumer = _require$requireLib.PydioContextConsumer; var AsyncComponent = _require$requireLib.AsyncComponent; var ActionsPanel = (function (_React$Component) { _inherits(ActionsPanel, _React$Component); function ActionsPanel(props, context) { _classCallCheck(this, ActionsPanel); _React$Component.call(this, props, context); this.state = { showPicker: false, pickerAnchor: null, showMailer: false, mailerAnchor: null }; } ActionsPanel.prototype.onTeamSelected = function onTeamSelected(item) { this.setState({ showPicker: false }); if (item.getType() === 'group' && item.getId().indexOf('/AJXP_TEAM/') === 0) { UsersApi.addUserToTeam(item.getId().replace('/AJXP_TEAM/', ''), this.props.userId, this.props.reloadAction); } }; ActionsPanel.prototype.onUserSelected = function onUserSelected(item) { this.setState({ showPicker: false }); UsersApi.addUserToTeam(this.props.team.id, item.getId(), this.props.reloadAction); }; ActionsPanel.prototype.openPicker = function openPicker(event) { this.setState({ showPicker: true, pickerAnchor: event.currentTarget }); }; ActionsPanel.prototype.openMailer = function openMailer(event) { var _this = this; var target = event.currentTarget; ResourcesManager.loadClassesAndApply(['PydioMailer'], function () { _this.setState({ mailerLibLoaded: true }, function () { _this.setState({ showMailer: true, mailerAnchor: target }); }); }); }; ActionsPanel.prototype.componentDidUpdate = function componentDidUpdate(prevProps, prevState) { if (!this.props.lockOnSubPopoverOpen) return; if ((this.state.showPicker || this.state.showMailer) && !(prevState.showPicker || prevState.showMailer)) { this.props.lockOnSubPopoverOpen(true); } else if (!(this.state.showPicker || this.state.showMailer) && (prevState.showPicker || prevState.showMailer)) { this.props.lockOnSubPopoverOpen(false); } }; ActionsPanel.prototype.render = function render() { var _this2 = this; var _props = this.props; var getMessage = _props.getMessage; var muiTheme = _props.muiTheme; var team = _props.team; var user = _props.user; var userEditable = _props.userEditable; var styles = { button: { backgroundColor: muiTheme.palette.accent2Color, borderRadius: '50%', margin: '0 4px', width: 44, height: 44, padding: 10 }, icon: { color: 'white' } }; var mailer = undefined, usermails = {}; var actions = []; if (user && user.hasEmail) { actions.push({ key: 'message', label: getMessage(598), icon: 'email', callback: this.openMailer.bind(this) }); usermails[this.props.user.id] = PydioUsers.User.fromObject(this.props.user); } if (team) { actions.push({ key: 'users', label: getMessage(599), icon: 'account-multiple-plus', callback: this.openPicker.bind(this) }); } else { actions.push({ key: 'teams', label: getMessage(573), icon: 'account-multiple-plus', callback: this.openPicker.bind(this) }); } if (userEditable) { actions.push({ key: 'edit', label: this.props.team ? getMessage(580) : getMessage(600), icon: 'pencil', callback: this.props.onEditAction }); actions.push({ key: 'delete', label: this.props.team ? getMessage(570) : getMessage(582), icon: 'delete', callback: this.props.onDeleteAction }); } return React.createElement( 'div', { style: { textAlign: 'center', marginBottom: 16 } }, actions.map(function (a) { return React.createElement(IconButton, { key: a.key, style: styles.button, iconStyle: styles.icon, tooltip: a.label, iconClassName: "mdi mdi-" + a.icon, onTouchTap: a.callback }); }), React.createElement( Popover, { open: this.state.showPicker, anchorEl: this.state.pickerAnchor, anchorOrigin: { horizontal: 'right', vertical: 'top' }, targetOrigin: { horizontal: 'right', vertical: 'top' }, onRequestClose: function () { _this2.setState({ showPicker: false }); }, useLayerForClickAway: false, style: { zIndex: 2200 } }, React.createElement( 'div', { style: { width: 256, height: 320 } }, React.createElement(_addressbookAddressBook2['default'], { mode: 'selector', pydio: this.props.pydio, loaderStyle: { width: 320, height: 420 }, onItemSelected: this.props.team ? this.onUserSelected.bind(this) : this.onTeamSelected.bind(this), teamsOnly: this.props.team ? false : true, usersOnly: this.props.team ? true : false }) ) ), React.createElement( Popover, { open: this.state.showMailer, anchorEl: this.state.mailerAnchor, anchorOrigin: { horizontal: 'right', vertical: 'top' }, targetOrigin: { horizontal: 'right', vertical: 'top' }, useLayerForClickAway: false, style: { zIndex: 2200 } }, React.createElement( 'div', { style: { width: 256, height: 320 } }, this.state.mailerLibLoaded && React.createElement(AsyncComponent, { namespace: 'PydioMailer', componentName: 'Pane', zDepth: 0, panelTitle: getMessage(598), uniqueUserStyle: true, users: usermails, onDismiss: function () { _this2.setState({ showMailer: false }); }, onFieldFocus: this.props.otherPopoverMouseOver }) ) ) ); }; return ActionsPanel; })(React.Component); ActionsPanel.propTypes = { /** * User data, props must pass at least one of 'user' or 'team' */ user: React.PropTypes.object, /** * Team data, props must pass at least one of 'user' or 'team' */ team: React.PropTypes.object, /** * For users, whether it is editable or not */ userEditable: React.PropTypes.object }; exports['default'] = ActionsPanel = PydioContextConsumer(ActionsPanel); exports['default'] = ActionsPanel = muiThemeable()(ActionsPanel); exports['default'] = ActionsPanel; module.exports = exports['default']; },{"../addressbook/AddressBook":34,"material-ui":"material-ui","material-ui/styles":"material-ui/styles","pydio":"pydio","pydio/http/resources-manager":"pydio/http/resources-manager","pydio/http/users-api":"pydio/http/users-api","react":"react"}],45:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; 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 _addressbookUsersList = require('../addressbook/UsersList'); var _addressbookUsersList2 = _interopRequireDefault(_addressbookUsersList); var _require = require('react'); var Component = _require.Component; var PropTypes = _require.PropTypes; var _require2 = require('material-ui'); var Divider = _require2.Divider; var _require3 = require('pydio/http/users-api'); var UsersApi = _require3.UsersApi; var _require$requireLib = require('pydio').requireLib('boot'); var PydioContextConsumer = _require$requireLib.PydioContextConsumer; /** * Display information about user or team relations */ var GraphPanel = (function (_Component) { _inherits(GraphPanel, _Component); function GraphPanel() { _classCallCheck(this, GraphPanel); _Component.apply(this, arguments); } GraphPanel.prototype.render = function render() { var _props = this.props; var graph = _props.graph; var userLabel = _props.userLabel; var pydio = _props.pydio; var getMessage = _props.getMessage; var elements = []; if (graph.teams && graph.teams.length) { var onDeleteAction = (function (parentItem, team) { var _this = this; UsersApi.removeUserFromTeam(team[0].id, this.props.userId, function (response) { if (response.message) pydio.UI.displayMessage('SUCCESS', response.message); _this.props.reloadAction(); }); }).bind(this); elements.push(React.createElement( 'div', { key: 'teams' }, React.createElement(Divider, null), React.createElement(_addressbookUsersList2['default'], { subHeader: getMessage(581).replace('%s', graph.teams.length), onItemClicked: function () {}, item: { leafs: graph.teams }, mode: 'inner', onDeleteAction: onDeleteAction }) )); } if (graph.source && Object.keys(graph.source).length) { elements.push(React.createElement( 'div', { key: 'source' }, elements.length ? React.createElement(Divider, null) : null, React.createElement( 'div', { style: { padding: 16 } }, getMessage(601).replace('%1', userLabel).replace('%2', Object.keys(graph.source).length) ) )); } if (graph.target && Object.keys(graph.target).length) { elements.push(React.createElement( 'div', { key: 'target' }, elements.length ? React.createElement(Divider, null) : null, React.createElement( 'div', { style: { padding: 16 } }, getMessage(602).replace('%1', userLabel).replace('%2', Object.keys(graph.target).length) ) )); } return React.createElement( 'div', null, elements ); }; return GraphPanel; })(Component); exports['default'] = GraphPanel = PydioContextConsumer(GraphPanel); exports['default'] = GraphPanel; module.exports = exports['default']; },{"../addressbook/UsersList":43,"material-ui":"material-ui","pydio":"pydio","pydio/http/users-api":"pydio/http/users-api","react":"react"}],46:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = 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; }; 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 _GraphPanel = require('./GraphPanel'); var _GraphPanel2 = _interopRequireDefault(_GraphPanel); var _ActionsPanel = require('./ActionsPanel'); var _ActionsPanel2 = _interopRequireDefault(_ActionsPanel); var debounce = require('lodash.debounce'); var React = require('react'); var Color = require('color'); var _require = require('material-ui'); var FontIcon = _require.FontIcon; var Popover = _require.Popover; var Paper = _require.Paper; var Avatar = _require.Avatar; var CardTitle = _require.CardTitle; var _require2 = require('material-ui/styles'); var muiThemeable = _require2.muiThemeable; var MetaCacheService = require('pydio/http/meta-cache-service'); var PydioApi = require('pydio/http/api'); /** * Generic component for display a user and her avatar (first letters or photo) */ var UserAvatar = (function (_React$Component) { _inherits(UserAvatar, _React$Component); function UserAvatar(props, context) { _classCallCheck(this, UserAvatar); _React$Component.call(this, props, context); this.state = { user: null, avatar: null, graph: null }; } UserAvatar.prototype.componentDidMount = function componentDidMount() { if (this.props.pydio.user && this.props.pydio.user.id === this.props.userId) { this.loadLocalData(); if (!this._userLoggedObs) { this._userLoggedObs = this.loadLocalData.bind(this); this.props.pydio.observe('user_logged', this._userLoggedObs); } } else if (this.props.userType === 'user') { this.cache = MetaCacheService.getInstance(); this.cache.registerMetaStream('user_public_data', 'EXPIRATION_MANUAL_TRIGGER'); this.cache.registerMetaStream('user_public_data-rich', 'EXPIRATION_MANUAL_TRIGGER'); this.loadPublicData(this.props.userId); } }; UserAvatar.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) { if (!this.props.userId || this.props.userId !== nextProps.userId) { this.setState({ label: nextProps.userId }); } if (this.props.pydio && this.props.pydio.user && this.props.pydio.user.id === nextProps.userId) { this.loadLocalData(); if (!this._userLoggedObs) { this._userLoggedObs = this.loadLocalData.bind(this); this.props.pydio.observe('user_logged', this._userLoggedObs); } } else { if (this._userLoggedObs) { this.props.pydio.stopObserving('user_logged', this._userLoggedObs); } this.cache = MetaCacheService.getInstance(); this.cache.registerMetaStream('user_public_data', 'EXPIRATION_MANUAL_TRIGGER'); this.cache.registerMetaStream('user_public_data-rich', 'EXPIRATION_MANUAL_TRIGGER'); this.loadPublicData(nextProps.userId); } }; UserAvatar.prototype.componentWillUnmount = function componentWillUnmount() { if (this._userLoggedObs) { this.props.pydio.stopObserving('user_logged', this._userLoggedObs); } }; UserAvatar.prototype.loadLocalData = function loadLocalData() { var pydio = this.props.pydio; if (!pydio.user) { this.setState({ label: '', avatar: null }); return; } var userName = pydio.user.getPreference('USER_DISPLAY_NAME') || pydio.user.id; var avatarId = pydio.user.getPreference('avatar'); var avatarUrl = PydioApi.getClient().buildUserAvatarUrl(pydio.user.id, avatarId); this.setState({ label: userName, avatar: avatarUrl }); if (!avatarUrl) { this.loadFromExternalProvider(); } }; UserAvatar.prototype.loadPublicData = function loadPublicData(userId) { var namespace = this.props.richCard ? 'user_public_data-rich' : 'user_public_data'; if (this.cache.hasKey(namespace, userId)) { this.setState(this.cache.getByKey(namespace, userId)); return; } PydioApi.getClient().request({ get_action: 'user_public_data', user_id: userId, graph: this.props.richCard ? 'true' : 'false' }, (function (transport) { var data = transport.responseJSON; if (!data || data.error) { this.cache.setKey(namespace, userId, {}); return; } var user = data.user; var graph = data.graph; var avatarUrl = undefined; var avatarId = user.avatar || null; var label = user.label || userId; if (!user.avatar) { this.loadFromExternalProvider(); } else { avatarUrl = PydioApi.getClient().buildUserAvatarUrl(userId, avatarId); } this.cache.setKey(namespace, userId, { user: user, graph: graph, avatar: avatarUrl }); this.setState({ user: user, graph: graph, avatar: avatarUrl }); }).bind(this)); }; UserAvatar.prototype.loadFromExternalProvider = function loadFromExternalProvider() { if (!this.props.pydio.getPluginConfigs("ajxp_plugin[@id='action.avatar']").get("AVATAR_PROVIDER")) { return; } var namespace = this.props.richCard ? 'user_public_data-rich' : 'user_public_data'; PydioApi.getClient().request({ get_action: 'get_avatar_url', userid: this.props.userId }, (function (transport) { this.setState({ avatar: transport.responseText }); }).bind(this)); }; UserAvatar.prototype.render = function render() { var _this = this; var _state = this.state; var user = _state.user; var avatar = _state.avatar; var graph = _state.graph; var _props = this.props; var pydio = _props.pydio; var userId = _props.userId; var userType = _props.userType; var icon = _props.icon; var style = _props.style; var labelStyle = _props.labelStyle; var avatarStyle = _props.avatarStyle; var avatarSize = _props.avatarSize; var className = _props.className; var avatarClassName = _props.avatarClassName; var labelClassName = _props.labelClassName; var displayLabel = _props.displayLabel; var displayAvatar = _props.displayAvatar; var useDefaultAvatar = _props.useDefaultAvatar; var richCard = _props.richCard; var cardSize = _props.cardSize; var muiTheme = _props.muiTheme; var label = this.state.label; var userTypeLabel = undefined; if (user) { label = user.label; } else if (!label) { label = this.props.userLabel || this.props.userId; } var avatarContent = undefined, avatarColor = undefined, avatarIcon = undefined; if (richCard) { displayAvatar = useDefaultAvatar = displayLabel = true; } if (displayAvatar && !avatar && label && (!displayLabel || useDefaultAvatar)) { var avatarsColor = muiTheme.palette.avatarsColor; if (userType === 'group' || userType === 'team' || userId.indexOf('AJXP_GRP_/') === 0 || userId.indexOf('/AJXP_TEAM/') === 0) { avatarsColor = Color(avatarsColor).darken(0.2).toString(); } var iconClassName = undefined; switch (userType) { case 'group': iconClassName = 'mdi mdi-account-multiple'; userTypeLabel = '289'; break; case 'team': iconClassName = 'mdi mdi-account-multiple-outline'; userTypeLabel = '603'; break; case 'remote': iconClassName = 'mdi mdi-account-network'; userTypeLabel = '604'; break; default: iconClassName = 'mdi mdi-account'; userTypeLabel = user ? user.external ? '589' : '590' : '288'; break; } if (icon) iconClassName = icon; if (userTypeLabel) userTypeLabel = pydio.MessageHash[userTypeLabel]; if (richCard) { avatarIcon = React.createElement(FontIcon, { className: iconClassName, style: { color: avatarsColor } }); avatarColor = '#f5f5f5'; } else { avatarColor = avatarsColor; if (iconClassName) { avatarIcon = React.createElement(FontIcon, { className: iconClassName }); } else { avatarContent = label.split(' ').map(function (word) { return word[0]; }).join('').substring(0, 2); if (avatarContent.length < 2) avatarContent = label.substring(0, 2); } } } var reloadAction = undefined, onEditAction = undefined, onMouseOver = undefined, onMouseOut = undefined, popover = undefined; if (richCard) { (function () { displayAvatar = true; style = _extends({}, style, { flexDirection: 'column' }); avatarSize = cardSize ? cardSize : '100%'; avatarStyle = { borderRadius: 0 }; var localReload = function localReload() { MetaCacheService.getInstance().deleteKey('user_public_data-rich', _this.props.userId); _this.loadPublicData(_this.props.userId); }; reloadAction = function () { localReload(); if (_this.props.reloadAction) _this.props.reloadAction(); }; onEditAction = function () { localReload(); if (_this.props.onEditAction) _this.props.onEditAction(); }; })(); } else if (this.props.richOnHover) { (function () { onMouseOut = function () { if (!_this.lockedBySubPopover) { _this.setState({ showPopover: false }); } }; onMouseOut = debounce(onMouseOut, 350); onMouseOver = function (e) { _this.setState({ showPopover: true, popoverAnchor: e.currentTarget }); onMouseOut.cancel(); }; var onMouseOverInner = function onMouseOverInner(e) { _this.setState({ showPopover: true }); onMouseOut.cancel(); }; var lockOnSubPopoverOpen = function lockOnSubPopoverOpen(status) { _this.lockedBySubPopover = status; onMouseOverInner(); }; popover = React.createElement( Popover, { open: _this.state.showPopover, anchorEl: _this.state.popoverAnchor, onRequestClose: function (reason) { if (reason !== 'clickAway' || !_this.lockedBySubPopover) { _this.setState({ showPopover: false }); } }, anchorOrigin: { horizontal: "left", vertical: "center" }, targetOrigin: { horizontal: "right", vertical: "center" }, useLayerForClickAway: false }, React.createElement( Paper, { zDepth: 2, style: { width: 220, height: 320, overflowY: 'auto' }, onMouseOver: onMouseOverInner, onMouseOut: onMouseOut }, React.createElement(UserAvatar, _extends({}, _this.props, { richCard: true, richOnHover: false, cardSize: 220, lockOnSubPopoverOpen: lockOnSubPopoverOpen })) ) ); })(); } var avatarComponent = React.createElement( Avatar, { src: avatar, icon: avatarIcon, size: avatarSize, style: this.props.avatarOnly ? this.props.style : avatarStyle, backgroundColor: avatarColor }, avatarContent ); if (this.props.avatarOnly) { return avatarComponent; } return React.createElement( 'div', { className: className, style: style, onMouseOver: onMouseOver, onMouseOut: onMouseOut }, displayAvatar && (avatar || avatarContent || avatarIcon) && avatarComponent, displayLabel && !richCard && React.createElement( 'div', { className: labelClassName, style: labelStyle }, label ), displayLabel && richCard && React.createElement(CardTitle, { style: { textAlign: 'center' }, title: label, subtitle: userTypeLabel }), richCard && user && React.createElement(_ActionsPanel2['default'], _extends({}, this.state, this.props, { reloadAction: reloadAction, onEditAction: onEditAction })), graph && React.createElement(_GraphPanel2['default'], _extends({ graph: graph }, this.props, { userLabel: label, reloadAction: reloadAction, onEditAction: onEditAction })), this.props.children, popover ); }; return UserAvatar; })(React.Component); UserAvatar.propTypes = { /** * Id of the user to be loaded */ userId: React.PropTypes.string.isRequired, /** * Pydio instance */ pydio: React.PropTypes.instanceOf(Pydio), /** * Label of the user, if we already have it (otherwise will be loaded) */ userLabel: React.PropTypes.string, /** * Type of user */ userType: React.PropTypes.oneOf(['user', 'group', 'remote', 'team']), /** * Icon to be displayed in avatar */ icon: React.PropTypes.string, /** * Display a rich card or a simple avatar+label chip */ richCard: React.PropTypes.bool, /** * If not rich, display a rich card as popover on mouseover */ richOnHover: React.PropTypes.bool, /** * Add edit action to the card */ userEditable: React.PropTypes.bool, /** * Triggered after successful edition */ onEditAction: React.PropTypes.func, /** * Triggered after deletion */ onDeleteAction: React.PropTypes.func, /** * Triggered if a reload is required */ reloadAction: React.PropTypes.func, /** * Display label element or not */ displayLabel: React.PropTypes.bool, /** * Display avatar element or not */ displayAvatar: React.PropTypes.bool, /** * Display only avatar */ avatarOnly: React.PropTypes.bool, /** * Use default avatar */ useDefaultAvatar: React.PropTypes.bool, /** * Avatar size, 40px by default */ avatarSize: React.PropTypes.number, /** * Add class name to root element */ className: React.PropTypes.string, /** * Add class name to label element */ labelClassName: React.PropTypes.string, /** * Add class name to avatar element */ avatarClassName: React.PropTypes.string, /** * Add style to root element */ style: React.PropTypes.object, /** * Add style to label element */ labelStyle: React.PropTypes.object, /** * Add style to avatar element */ avatarStyle: React.PropTypes.object }; UserAvatar.defaultProps = { displayLabel: true, displayAvatar: true, avatarSize: 40, userType: 'user', className: 'user-avatar-widget', avatarClassName: 'user-avatar', labelClassName: 'user-label' }; exports['default'] = UserAvatar = muiThemeable()(UserAvatar); exports['default'] = UserAvatar; module.exports = exports['default']; },{"./ActionsPanel":44,"./GraphPanel":45,"color":"color","lodash.debounce":"lodash.debounce","material-ui":"material-ui","material-ui/styles":"material-ui/styles","pydio/http/api":"pydio/http/api","pydio/http/meta-cache-service":"pydio/http/meta-cache-service","react":"react"}],47:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ "use strict"; exports.__esModule = true; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var FuncUtils = require("pydio/util/func"); var ResourcesManager = require("pydio/http/resources-manager"); /******************************/ /* REACT DND GENERIC COMPONENTS /******************************/ var Types = { NODE_PROVIDER: 'node', SORTABLE_LIST_ITEM: 'sortable-list-item' }; /** * Specifies which props to inject into your component. */ function collect(connect, monitor) { return { connectDragSource: connect.dragSource(), isDragging: monitor.isDragging() }; } function collectDrop(connect, monitor) { return { connectDropTarget: connect.dropTarget(), canDrop: monitor.canDrop(), isOver: monitor.isOver(), isOverCurrent: monitor.isOver({ shallow: true }) }; } var DNDActionParameter = (function () { function DNDActionParameter(source, target, step) { _classCallCheck(this, DNDActionParameter); this._source = source; this._target = target; this._step = step; } DNDActionParameter.prototype.getSource = function getSource() { return this._source; }; DNDActionParameter.prototype.getTarget = function getTarget() { return this._target; }; DNDActionParameter.prototype.getStep = function getStep() { return this._step; }; return DNDActionParameter; })(); DNDActionParameter.STEP_BEGIN_DRAG = 'beginDrag'; DNDActionParameter.STEP_END_DRAG = 'endDrag'; DNDActionParameter.STEP_CAN_DROP = 'canDrop'; DNDActionParameter.STEP_HOVER_DROP = 'hover'; var applyDNDAction = function applyDNDAction(source, target, step) { var Controller = window.pydio.Controller; var dnd = Controller.defaultActions.get("dragndrop"); if (dnd) { var dndAction = Controller.getActionByName(dnd); dndAction.enable(); var params = new DNDActionParameter(source, target, step); var checkModule = dndAction.options.dragndropCheckModule; if (step === DNDActionParameter.STEP_CAN_DROP && checkModule) { if (!FuncUtils.getFunctionByName(checkModule, window)) { ResourcesManager.detectModuleToLoadAndApply(checkModule, function () {}); throw new Error('Cannot find test module, trying to load it'); } FuncUtils.executeFunctionByName(dndAction.options.dragndropCheckModule, window, Controller, params); } else { dndAction.apply(params); } } else { throw new Error('No DND Actions available'); } }; /****************************/ /* REACT DND DRAG/DROP NODES /***************************/ var nodeDragSource = { beginDrag: function beginDrag(props) { // Return the data describing the dragged item return { node: props.node }; }, endDrag: function endDrag(props, monitor, component) { if (!monitor.didDrop()) { return; } var item = monitor.getItem(); var dropResult = monitor.getDropResult(); try { applyDNDAction(item.node, dropResult.node, DNDActionParameter.STEP_END_DRAG); } catch (e) {} } }; var nodeDropTarget = { hover: function hover(props, monitor) {}, canDrop: function canDrop(props, monitor) { var source = monitor.getItem().node; var target = props.node; try { applyDNDAction(source, target, DNDActionParameter.STEP_CAN_DROP); } catch (e) { return false; } return true; }, drop: function drop(props, monitor) { var hasDroppedOnChild = monitor.didDrop(); if (hasDroppedOnChild) { return; } return { node: props.node }; } }; exports.Types = Types; exports.collect = collect; exports.collectDrop = collectDrop; exports.nodeDragSource = nodeDragSource; exports.nodeDropTarget = nodeDropTarget; exports.DNDActionParameter = DNDActionParameter; },{"pydio/http/resources-manager":"pydio/http/resources-manager","pydio/util/func":"pydio/util/func"}],48:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ "use strict"; exports.__esModule = true; exports["default"] = { contextTypes: { messages: React.PropTypes.object, getMessage: React.PropTypes.func } }; module.exports = exports["default"]; },{}],49:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = 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; }; 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 FlatButton = _require2.FlatButton; var FontIcon = _require2.FontIcon; var _require3 = require('material-ui/styles'); var muiThemeable = _require3.muiThemeable; var Color = require('color'); var Pydio = require('pydio'); var _Pydio$requireLib = Pydio.requireLib('boot'); var PydioContextConsumer = _Pydio$requireLib.PydioContextConsumer; var EmptyStateView = (function (_Component) { _inherits(EmptyStateView, _Component); function EmptyStateView(props, context) { _classCallCheck(this, EmptyStateView); _Component.call(this, props, context); } EmptyStateView.prototype.render = function render() { var _props = this.props; var style = _props.style; var iconClassName = _props.iconClassName; var primaryTextId = _props.primaryTextId; var secondaryTextId = _props.secondaryTextId; var actionLabelId = _props.actionLabelId; var actionCallback = _props.actionCallback; var actionStyle = _props.actionStyle; var actionIconClassName = _props.actionIconClassName; var getMessage = _props.getMessage; var mainColor = Color(this.props.muiTheme.palette.primary1Color); var styles = { container: _extends({ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%', width: '100%', flex: 1, backgroundColor: mainColor.lightness(97).rgb().toString() }, style), centered: { maxWidth: 280, textAlign: 'center', color: mainColor.fade(0.6).toString() }, icon: { fontSize: 100 }, primaryText: { fontSize: 16, fontWeight: 500 }, secondaryText: { marginTop: 20, fontSize: 13 }, buttonContainer: { marginTop: 100, textAlign: 'center' }, buttonStyle: { color: this.props.muiTheme.palette.accent2Color } }; var buttonIcon = actionIconClassName ? React.createElement(FontIcon, { className: actionIconClassName }) : null; return React.createElement( 'div', { style: styles.container }, React.createElement( 'div', { style: styles.centered }, React.createElement('div', { className: iconClassName, style: styles.icon }), React.createElement( 'div', { style: styles.primaryText }, getMessage(primaryTextId) ), secondaryTextId && React.createElement( 'div', { style: styles.secondaryText }, getMessage(secondaryTextId) ), actionLabelId && actionCallback && React.createElement( 'div', { style: _extends({}, styles.buttonContainer, actionStyle) }, React.createElement(FlatButton, { style: styles.buttonStyle, label: getMessage(actionLabelId), onTouchTap: actionCallback, icon: buttonIcon }) ) ) ); }; return EmptyStateView; })(Component); EmptyStateView.propTypes = { pydio: PropTypes.instanceOf(Pydio).isRequired, iconClassName: PropTypes.string.isRequired, primaryTextId: PropTypes.string.isRequired, secondaryTextId: PropTypes.string, actionLabelId: PropTypes.string, actionCallback: PropTypes.func, actionStyle: PropTypes.object, style: PropTypes.object, getMessage: PropTypes.func }; exports['default'] = EmptyStateView = PydioContextConsumer(EmptyStateView); exports['default'] = EmptyStateView = muiThemeable()(EmptyStateView); exports['default'] = EmptyStateView; module.exports = exports['default']; },{"color":"color","material-ui":"material-ui","material-ui/styles":"material-ui/styles","pydio":"pydio","react":"react"}],50:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = 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; }; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _materialUi = require('material-ui'); var ModalAppBar = function ModalAppBar(props) { var style = props.style; var titleStyle = props.titleStyle; var iconStyleRight = props.iconStyleRight; var iconStyleLeft = props.iconStyleLeft; var otherProps = _objectWithoutProperties(props, ['style', 'titleStyle', 'iconStyleRight', 'iconStyleLeft']); var styles = { style: _extends({ flexShrink: 0 }, style), titleStyle: _extends({ lineHeight: '56px', height: 56, marginLeft: -8 }, titleStyle), iconStyleRight: _extends({ marginTop: 4 }, iconStyleRight), iconStyleLeft: _extends({ marginTop: 4 }, iconStyleLeft) }; return _react2['default'].createElement(_materialUi.AppBar, _extends({}, otherProps, styles)); }; exports['default'] = ModalAppBar; module.exports = exports['default']; /*borderRadius: '2px 2px 0 0',*/ },{"material-ui":"material-ui","react":"react"}],51:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ /** * Search input building a set of query parameters and calling * the callbacks to display / hide results */ 'use strict'; exports.__esModule = true; exports['default'] = React.createClass({ displayName: 'SearchBox', propTypes: { // Required parameters: React.PropTypes.object.isRequired, queryParameterName: React.PropTypes.string.isRequired, // Other textLabel: React.PropTypes.string, displayResults: React.PropTypes.func, hideResults: React.PropTypes.func, displayResultsState: React.PropTypes.bool, limit: React.PropTypes.number }, getInitialState: function getInitialState() { return { displayResult: this.props.displayResultsState ? true : false }; }, getDefaultProps: function getDefaultProps() { var dm = new PydioDataModel(); dm.setRootNode(new AjxpNode()); return { dataModel: dm }; }, displayResultsState: function displayResultsState() { this.setState({ displayResult: true }); }, hideResultsState: function hideResultsState() { this.setState({ displayResult: false }); this.props.hideResults(); }, onClickSearch: function onClickSearch() { var value = this.refs.query.getValue(); var dm = this.props.dataModel; var params = this.props.parameters; params[this.props.queryParameterName] = value; params['limit'] = this.props.limit || 100; dm.getRootNode().setChildren([]); PydioApi.getClient().request(params, (function (transport) { var remoteNodeProvider = new RemoteNodeProvider({}); remoteNodeProvider.parseNodes(dm.getRootNode(), transport); dm.getRootNode().setLoaded(true); this.displayResultsState(); this.props.displayResults(value, dm); }).bind(this)); }, keyDown: function keyDown(event) { if (event.key == 'Enter') { this.onClickSearch(); } }, render: function render() { return React.createElement( 'div', { className: this.props.className ? this.props.className : '' }, React.createElement( 'div', { style: { paddingTop: 22, float: 'right', opacity: 0.3 } }, React.createElement(ReactMUI.IconButton, { ref: 'button', onClick: this.onClickSearch, iconClassName: 'icon-search', tooltip: 'Search' }) ), React.createElement( 'div', { className: 'searchbox-input-fill', style: { width: 220, float: 'right' } }, React.createElement(ReactMUI.TextField, { ref: 'query', onKeyDown: this.keyDown, floatingLabelText: this.props.textLabel }) ) ); } }); module.exports = exports['default']; },{}],52:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ /** * Get info from Pydio controller an build an * action bar with active actions. * TBC */ 'use strict'; exports.__esModule = true; exports['default'] = React.createClass({ displayName: 'SimpleReactActionBar', propTypes: { dataModel: React.PropTypes.instanceOf(PydioDataModel).isRequired, node: React.PropTypes.instanceOf(AjxpNode).isRequired, actions: React.PropTypes.array }, clickAction: function clickAction(event) { var actionName = event.currentTarget.getAttribute("data-action"); this.props.dataModel.setSelectedNodes([this.props.node]); var a = window.pydio.Controller.getActionByName(actionName); a.fireContextChange(this.props.dataModel, true, window.pydio.user); //a.fireSelectionChange(this.props.dataModel); a.apply([this.props.dataModel]); event.stopPropagation(); event.preventDefault(); }, render: function render() { var actions = this.props.actions.map((function (a) { return React.createElement('div', { key: a.options.name, className: a.options.icon_class + ' material-list-action-inline' || '', title: a.options.title, 'data-action': a.options.name, onClick: this.clickAction }); }).bind(this)); return React.createElement( 'span', null, actions ); } }); module.exports = exports['default']; },{}],53:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = 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 _utilDND = require('../util/DND'); var React = require('react'); var _Pydio$requireLib = Pydio.requireLib('hoc'); var withContextMenu = _Pydio$requireLib.withContextMenu; var ContextMenuWrapper = function ContextMenuWrapper(props) { return React.createElement('div', props); }; ContextMenuWrapper = withContextMenu(ContextMenuWrapper); /** * Tree Node */ var SimpleTreeNode = React.createClass({ displayName: 'SimpleTreeNode', propTypes: { collapse: React.PropTypes.bool, forceExpand: React.PropTypes.bool, childrenOnly: React.PropTypes.bool, depth: React.PropTypes.number, onNodeSelect: React.PropTypes.func, node: React.PropTypes.instanceOf(AjxpNode), dataModel: React.PropTypes.instanceOf(PydioDataModel), forceLabel: React.PropTypes.string, // Optional currently selected detection nodeIsSelected: React.PropTypes.func, // Optional checkboxes checkboxes: React.PropTypes.array, checkboxesValues: React.PropTypes.object, checkboxesComputeStatus: React.PropTypes.func, onCheckboxCheck: React.PropTypes.func }, getDefaultProps: function getDefaultProps() { return { collapse: false, childrenOnly: false, depth: 0, onNodeSelect: function onNodeSelect(node) {} }; }, listenToNode: function listenToNode(node) { this._childrenListener = (function () { if (!this.isMounted()) return; this.setState({ children: this._nodeToChildren(node) }); }).bind(this); this._nodeListener = (function () { if (!this.isMounted()) return; this.forceUpdate(); }).bind(this); node.observe("child_added", this._childrenListener); node.observe("child_removed", this._childrenListener); node.observe("node_replaced", this._nodeListener); }, stopListening: function stopListening(node) { node.stopObserving("child_added", this._childrenListener); node.stopObserving("child_removed", this._childrenListener); node.stopObserving("node_replaced", this._nodeListener); }, componentDidMount: function componentDidMount() { this.listenToNode(this.props.node); }, componentWillUnmount: function componentWillUnmount() { this.stopListening(this.props.node); }, componentWillReceiveProps: function componentWillReceiveProps(nextProps) { var oldNode = this.props.node; var newNode = nextProps.node; if (newNode == oldNode && newNode.getMetadata().get("paginationData")) { var remapedChildren = this.state.children.map(function (c) { c.setParent(newNode);return c; }); var remapedPathes = this.state.children.map(function (c) { return c.getPath(); }); var newChildren = this._nodeToChildren(newNode); newChildren.forEach(function (nc) { if (remapedPathes.indexOf(nc.getPath()) === -1) { remapedChildren.push(nc); } }); this.setState({ children: remapedChildren }); } else { this.setState({ children: this._nodeToChildren(newNode) }); } if (newNode !== oldNode) { this.stopListening(oldNode); this.listenToNode(newNode); } }, getInitialState: function getInitialState() { return { showChildren: !this.props.collapse || this.props.forceExpand, children: this._nodeToChildren(this.props.node) }; }, _nodeToChildren: function _nodeToChildren() { var children = []; this.props.node.getChildren().forEach(function (c) { if (!c.isLeaf() || c.getAjxpMime() === 'ajxp_browsable_archive') children.push(c); }); return children; }, onNodeSelect: function onNodeSelect(ev) { if (this.props.onNodeSelect) { this.props.onNodeSelect(this.props.node); } ev.preventDefault(); ev.stopPropagation(); }, onChildDisplayToggle: function onChildDisplayToggle(ev) { if (this.props.node.getChildren().size) { this.setState({ showChildren: !this.state.showChildren }); } ev.preventDefault(); ev.stopPropagation(); }, nodeIsSelected: function nodeIsSelected(n) { if (this.props.nodeIsSelected) return this.props.nodeIsSelected(n);else return this.props.dataModel.getSelectedNodes().indexOf(n) !== -1; }, render: function render() { var _this = this; var _props = this.props; var node = _props.node; var childrenOnly = _props.childrenOnly; var canDrop = _props.canDrop; var isOverCurrent = _props.isOverCurrent; var checkboxes = _props.checkboxes; var checkboxesComputeStatus = _props.checkboxesComputeStatus; var checkboxesValues = _props.checkboxesValues; var onCheckboxCheck = _props.onCheckboxCheck; var depth = _props.depth; var forceExpand = _props.forceExpand; var selectedItemStyle = _props.selectedItemStyle; var getItemStyle = _props.getItemStyle; var forceLabel = _props.forceLabel; var hasFolderChildrens = this.state.children.length ? true : false; var hasChildren; if (hasFolderChildrens) { hasChildren = React.createElement( 'span', { onClick: this.onChildDisplayToggle }, this.state.showChildren || forceExpand ? React.createElement('span', { className: 'tree-icon icon-angle-down' }) : React.createElement('span', { className: 'tree-icon icon-angle-right' }) ); } else { var cname = "tree-icon icon-angle-right"; if (node.isLoaded()) { cname += " no-folder-children"; } hasChildren = React.createElement('span', { className: cname }); } var isSelected = this.nodeIsSelected(node) ? 'mui-menu-item mui-is-selected' : 'mui-menu-item'; var selfLabel; if (!childrenOnly) { if (canDrop && isOverCurrent) { isSelected += ' droppable-active'; } var boxes; if (checkboxes) { var values = {}, inherited = false, disabled = {}, additionalClassName = ''; if (checkboxesComputeStatus) { var status = checkboxesComputeStatus(node); values = status.VALUES; inherited = status.INHERITED; disabled = status.DISABLED; if (status.CLASSNAME) additionalClassName = ' ' + status.CLASSNAME; } else if (checkboxesValues && checkboxesValues[node.getPath()]) { values = checkboxesValues[node.getPath()]; } var valueClasses = []; boxes = checkboxes.map((function (c) { var selected = values[c] !== undefined ? values[c] : false; var click = (function (event, value) { onCheckboxCheck(node, c, value); }).bind(this); if (selected) valueClasses.push(c); return React.createElement(ReactMUI.Checkbox, { name: c, key: c + "-" + (selected ? "true" : "false"), checked: selected, onCheck: click, disabled: disabled[c], className: "cbox-" + c }); }).bind(this)); isSelected += inherited ? " inherited " : ""; isSelected += valueClasses.length ? " checkbox-values-" + valueClasses.join('-') : " checkbox-values-empty"; boxes = React.createElement( 'div', { className: "tree-checkboxes" + additionalClassName }, boxes ); } var itemStyle = { paddingLeft: depth * 20 }; if (this.nodeIsSelected(node) && selectedItemStyle) { itemStyle = _extends({}, itemStyle, selectedItemStyle); } if (getItemStyle) { itemStyle = _extends({}, itemStyle, getItemStyle(node)); } var icon = 'mdi mdi-folder'; var ajxpMime = node.getAjxpMime(); if (ajxpMime === 'ajxp_browsable_archive') { icon = 'mdi mdi-archive'; } else if (ajxpMime === 'ajxp_recycle') { icon = 'mdi mdi-delete'; } selfLabel = React.createElement( ContextMenuWrapper, { node: node, className: 'tree-item ' + isSelected + (boxes ? ' has-checkboxes' : ''), style: itemStyle }, React.createElement( 'div', { className: 'tree-item-label', onClick: this.onNodeSelect, title: node.getLabel(), 'data-id': node.getPath() }, hasChildren, React.createElement('span', { className: "tree-icon " + icon }), forceLabel ? forceLabel : node.getLabel() ), boxes ); } var children = []; var connector = function connector(instance) { return instance; }; var draggable = false; if (window.ReactDND && this.props.connectDropTarget && this.props.connectDragSource) { (function () { var connectDragSource = _this.props.connectDragSource; var connectDropTarget = _this.props.connectDropTarget; connector = function (instance) { connectDragSource(ReactDOM.findDOMNode(instance)); connectDropTarget(ReactDOM.findDOMNode(instance)); }; draggable = true; })(); } if (this.state.showChildren || forceExpand) { children = this.state.children.map((function (child) { var props = _extends({}, this.props, { forceLabel: null, childrenOnly: false, key: child.getPath(), node: child, depth: depth + 1 }); return React.createElement(draggable ? DragDropTreeNode : SimpleTreeNode, props); }).bind(this)); } return React.createElement( 'li', { ref: connector, className: "treenode" + node.getPath().replace(/\//g, '_') }, selfLabel, React.createElement( 'ul', null, children ) ); } }); var DragDropTreeNode; if (window.ReactDND) { DragDropTreeNode = ReactDND.flow(ReactDND.DragSource(_utilDND.Types.NODE_PROVIDER, _utilDND.nodeDragSource, _utilDND.collect), ReactDND.DropTarget(_utilDND.Types.NODE_PROVIDER, _utilDND.nodeDropTarget, _utilDND.collectDrop))(SimpleTreeNode); } else { DragDropTreeNode = SimpleTreeNode; } /** * Simple openable / loadable tree taking AjxpNode as inputs */ var DNDTreeView = React.createClass({ displayName: 'DNDTreeView', propTypes: { showRoot: React.PropTypes.bool, rootLabel: React.PropTypes.string, onNodeSelect: React.PropTypes.func, node: React.PropTypes.instanceOf(AjxpNode).isRequired, dataModel: React.PropTypes.instanceOf(PydioDataModel).isRequired, selectable: React.PropTypes.bool, selectableMultiple: React.PropTypes.bool, initialSelectionModel: React.PropTypes.array, onSelectionChange: React.PropTypes.func, forceExpand: React.PropTypes.bool, // Optional currently selected detection nodeIsSelected: React.PropTypes.func, // Optional checkboxes checkboxes: React.PropTypes.array, checkboxesValues: React.PropTypes.object, checkboxesComputeStatus: React.PropTypes.func, onCheckboxCheck: React.PropTypes.func }, getDefaultProps: function getDefaultProps() { return { showRoot: true, onNodeSelect: this.onNodeSelect }; }, onNodeSelect: function onNodeSelect(node) { if (this.props.onNodeSelect) { this.props.onNodeSelect(node); } else { this.props.dataModel.setSelectedNodes([node]); } }, render: function render() { return React.createElement( 'ul', { className: this.props.className }, React.createElement(DragDropTreeNode, { childrenOnly: !this.props.showRoot, forceExpand: this.props.forceExpand, node: this.props.node ? this.props.node : this.props.dataModel.getRootNode(), dataModel: this.props.dataModel, onNodeSelect: this.onNodeSelect, nodeIsSelected: this.props.nodeIsSelected, forceLabel: this.props.rootLabel, checkboxes: this.props.checkboxes, checkboxesValues: this.props.checkboxesValues, checkboxesComputeStatus: this.props.checkboxesComputeStatus, onCheckboxCheck: this.props.onCheckboxCheck, selectedItemStyle: this.props.selectedItemStyle, getItemStyle: this.props.getItemStyle }) ); } }); var TreeView = React.createClass({ displayName: 'TreeView', propTypes: { showRoot: React.PropTypes.bool, rootLabel: React.PropTypes.string, onNodeSelect: React.PropTypes.func, node: React.PropTypes.instanceOf(AjxpNode).isRequired, dataModel: React.PropTypes.instanceOf(PydioDataModel).isRequired, selectable: React.PropTypes.bool, selectableMultiple: React.PropTypes.bool, initialSelectionModel: React.PropTypes.array, onSelectionChange: React.PropTypes.func, forceExpand: React.PropTypes.bool, // Optional currently selected detection nodeIsSelected: React.PropTypes.func, // Optional checkboxes checkboxes: React.PropTypes.array, checkboxesValues: React.PropTypes.object, checkboxesComputeStatus: React.PropTypes.func, onCheckboxCheck: React.PropTypes.func }, getDefaultProps: function getDefaultProps() { return { showRoot: true, onNodeSelect: this.onNodeSelect }; }, onNodeSelect: function onNodeSelect(node) { if (this.props.onNodeSelect) { this.props.onNodeSelect(node); } else { this.props.dataModel.setSelectedNodes([node]); } }, render: function render() { return React.createElement( 'ul', { className: this.props.className }, React.createElement(SimpleTreeNode, { childrenOnly: !this.props.showRoot, forceExpand: this.props.forceExpand, node: this.props.node ? this.props.node : this.props.dataModel.getRootNode(), dataModel: this.props.dataModel, onNodeSelect: this.onNodeSelect, nodeIsSelected: this.props.nodeIsSelected, forceLabel: this.props.rootLabel, checkboxes: this.props.checkboxes, checkboxesValues: this.props.checkboxesValues, checkboxesComputeStatus: this.props.checkboxesComputeStatus, onCheckboxCheck: this.props.onCheckboxCheck, selectedItemStyle: this.props.selectedItemStyle, getItemStyle: this.props.getItemStyle }) ); } }); var FoldersTree = React.createClass({ displayName: 'FoldersTree', propTypes: { pydio: React.PropTypes.instanceOf(Pydio).isRequired, dataModel: React.PropTypes.instanceOf(PydioDataModel).isRequired, className: React.PropTypes.string, onNodeSelected: React.PropTypes.func, draggable: React.PropTypes.bool }, nodeObserver: function nodeObserver() { var r = this.props.dataModel.getRootNode(); if (!r.isLoaded()) { r.observeOnce("loaded", (function () { this.forceUpdate(); }).bind(this)); } else { this.forceUpdate(); } }, componentDidMount: function componentDidMount() { var dm = this.props.dataModel; this._dmObs = this.nodeObserver; dm.observe("context_changed", this._dmObs); dm.observe("root_node_changed", this._dmObs); this.nodeObserver(); }, componentWillUnmount: function componentWillUnmount() { if (this._dmObs) { var dm = this.props.dataModel; dm.stopObserving("context_changed", this._dmObs); dm.stopObserving("root_node_changed", this._dmObs); } }, treeNodeSelected: function treeNodeSelected(n) { if (this.props.onNodeSelected) { this.props.onNodeSelected(n); } else { this.props.dataModel.requireContextChange(n); } }, nodeIsSelected: function nodeIsSelected(n) { return n === this.props.dataModel.getContextNode(); }, render: function render() { if (this.props.draggable) { return React.createElement(PydioComponents.DNDTreeView, { onNodeSelect: this.treeNodeSelected, nodeIsSelected: this.nodeIsSelected, dataModel: this.props.dataModel, node: this.props.dataModel.getRootNode(), showRoot: this.props.showRoot ? true : false, selectedItemStyle: this.props.selectedItemStyle, getItemStyle: this.props.getItemStyle, className: "folders-tree" + (this.props.className ? ' ' + this.props.className : '') }); } else { return React.createElement(PydioComponents.TreeView, { onNodeSelect: this.treeNodeSelected, nodeIsSelected: this.nodeIsSelected, dataModel: this.props.dataModel, node: this.props.dataModel.getRootNode(), selectedItemStyle: this.props.selectedItemStyle, getItemStyle: this.props.getItemStyle, showRoot: this.props.showRoot ? true : false, className: "folders-tree" + (this.props.className ? ' ' + this.props.className : '') }); } } }); exports.TreeView = TreeView; exports.DNDTreeView = DNDTreeView; exports.FoldersTree = FoldersTree; },{"../util/DND":47,"react":"react"}]},{},[12])(12) }); //# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJub2RlX21vZHVsZXMvcmVhY3Qtc2Nyb2xsYmFyL2Rpc3Qvc2Nyb2xsQXJlYS5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL2R5bmFtaWMtZ3JpZC9EeW5hbWljR3JpZC5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL2R5bmFtaWMtZ3JpZC9HcmlkQnVpbGRlci5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL2R5bmFtaWMtZ3JpZC9HcmlkSXRlbU1peGluLmpzIiwicmVzL2J1aWxkL3VpL0NvbXBvbmVudHMvZHluYW1pYy1ncmlkL1N0b3JlLmpzIiwicmVzL2J1aWxkL3VpL0NvbXBvbmVudHMvZHluYW1pYy1ncmlkL2FzR3JpZEl0ZW0uanMiLCJyZXMvYnVpbGQvdWkvQ29tcG9uZW50cy9lZGl0b3IvUGFwZXJFZGl0b3IuanMiLCJyZXMvYnVpbGQvdWkvQ29tcG9uZW50cy9lZGl0b3IvUmVhY3RFZGl0b3JPcGVuZXIuanMiLCJyZXMvYnVpbGQvdWkvQ29tcG9uZW50cy9lbGVtZW50cy9DbGlwYm9hcmRUZXh0RmllbGQuanMiLCJyZXMvYnVpbGQvdWkvQ29tcG9uZW50cy9lbGVtZW50cy9MYWJlbFdpdGhUaXAuanMiLCJyZXMvYnVpbGQvdWkvQ29tcG9uZW50cy9lbGVtZW50cy9TaW1wbGVGaWd1cmVCYWRnZS5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL2luZGV4LmpzIiwicmVzL2J1aWxkL3VpL0NvbXBvbmVudHMvbGlzdC9Db25maWd1cmFibGVMaXN0RW50cnkuanMiLCJyZXMvYnVpbGQvdWkvQ29tcG9uZW50cy9saXN0L0lubGluZUVkaXRvci5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL2xpc3QvTGlzdEVudHJ5LmpzIiwicmVzL2J1aWxkL3VpL0NvbXBvbmVudHMvbGlzdC9MaXN0RW50cnlOb2RlTGlzdGVuZXJNaXhpbi5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL2xpc3QvTGlzdFBhZ2luYXRvci5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL2xpc3QvTm9kZUxpc3RDdXN0b21Qcm92aWRlci5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL2xpc3QvU2ltcGxlTGlzdC5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL2xpc3QvU29ydENvbHVtbnMuanMiLCJyZXMvYnVpbGQvdWkvQ29tcG9uZW50cy9saXN0L1NvcnRhYmxlTGlzdC5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL2xpc3QvVGFibGVMaXN0RW50cnkuanMiLCJyZXMvYnVpbGQvdWkvQ29tcG9uZW50cy9saXN0L1RhYmxlTGlzdEhlYWRlci5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL21lbnUvQnV0dG9uTWVudS5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL21lbnUvQ29udGV4dE1lbnUuanMiLCJyZXMvYnVpbGQvdWkvQ29tcG9uZW50cy9tZW51L0ljb25CdXR0b25NZW51LmpzIiwicmVzL2J1aWxkL3VpL0NvbXBvbmVudHMvbWVudS9JY29uQnV0dG9uUG9wb3Zlci5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL21lbnUvTWVudUl0ZW1zQ29uc3VtZXIuanMiLCJyZXMvYnVpbGQvdWkvQ29tcG9uZW50cy9tZW51L1BvcHVwTWVudS5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL21lbnUvVG9vbGJhci5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL21lbnUvVXRpbHMuanMiLCJyZXMvYnVpbGQvdWkvQ29tcG9uZW50cy91c2Vycy9UZWFtQ3JlYXRpb25Gb3JtLmpzIiwicmVzL2J1aWxkL3VpL0NvbXBvbmVudHMvdXNlcnMvVXNlcnNDb21wbGV0ZXIuanMiLCJyZXMvYnVpbGQvdWkvQ29tcG9uZW50cy91c2Vycy9hZGRyZXNzYm9vay9BZGRyZXNzQm9vay5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL3VzZXJzL2FkZHJlc3Nib29rL0FscGhhUGFnaW5hdG9yLmpzIiwicmVzL2J1aWxkL3VpL0NvbXBvbmVudHMvdXNlcnMvYWRkcmVzc2Jvb2svTG9hZGVycy5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL3VzZXJzL2FkZHJlc3Nib29rL05lc3RlZExpc3RJdGVtLmpzIiwicmVzL2J1aWxkL3VpL0NvbXBvbmVudHMvdXNlcnMvYWRkcmVzc2Jvb2svUmlnaHRQYW5lbENhcmQuanMiLCJyZXMvYnVpbGQvdWkvQ29tcG9uZW50cy91c2Vycy9hZGRyZXNzYm9vay9TZWFyY2hGb3JtLmpzIiwicmVzL2J1aWxkL3VpL0NvbXBvbmVudHMvdXNlcnMvYWRkcmVzc2Jvb2svU2VhcmNoUGFuZWwuanMiLCJyZXMvYnVpbGQvdWkvQ29tcG9uZW50cy91c2Vycy9hZGRyZXNzYm9vay9UZWFtQ2FyZC5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL3VzZXJzL2FkZHJlc3Nib29rL1VzZXJDYXJkLmpzIiwicmVzL2J1aWxkL3VpL0NvbXBvbmVudHMvdXNlcnMvYWRkcmVzc2Jvb2svVXNlcnNMaXN0LmpzIiwicmVzL2J1aWxkL3VpL0NvbXBvbmVudHMvdXNlcnMvYXZhdGFyL0FjdGlvbnNQYW5lbC5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL3VzZXJzL2F2YXRhci9HcmFwaFBhbmVsLmpzIiwicmVzL2J1aWxkL3VpL0NvbXBvbmVudHMvdXNlcnMvYXZhdGFyL1VzZXJBdmF0YXIuanMiLCJyZXMvYnVpbGQvdWkvQ29tcG9uZW50cy91dGlsL0RORC5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL3V0aWwvTWVzc2FnZXNDb25zdW1lck1peGluLmpzIiwicmVzL2J1aWxkL3VpL0NvbXBvbmVudHMvdmlld3MvRW1wdHlTdGF0ZVZpZXcuanMiLCJyZXMvYnVpbGQvdWkvQ29tcG9uZW50cy92aWV3cy9Nb2RhbEFwcEJhci5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL3ZpZXdzL1NlYXJjaEJveC5qcyIsInJlcy9idWlsZC91aS9Db21wb25lbnRzL3ZpZXdzL1NpbXBsZVJlYWN0QWN0aW9uQmFyLmpzIiwicmVzL2J1aWxkL3VpL0NvbXBvbmVudHMvdmlld3MvVHJlZVZpZXcuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTtBQUNBOzs7QUNEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ3pUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUN4TUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3R0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUM5RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzNJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNPQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUMvSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQy95Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeE5BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9HQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9HQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4R0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL09BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUNySUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDdldBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwb0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDektBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVRQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNU9BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3SEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxZUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9KQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25FQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsIiFmdW5jdGlvbihlLHQpe1wib2JqZWN0XCI9PXR5cGVvZiBleHBvcnRzJiZcIm9iamVjdFwiPT10eXBlb2YgbW9kdWxlP21vZHVsZS5leHBvcnRzPXQocmVxdWlyZShcInJlYWN0XCIpKTpcImZ1bmN0aW9uXCI9PXR5cGVvZiBkZWZpbmUmJmRlZmluZS5hbWQ/ZGVmaW5lKFtcInJlYWN0XCJdLHQpOlwib2JqZWN0XCI9PXR5cGVvZiBleHBvcnRzP2V4cG9ydHMuU2Nyb2xsQXJlYT10KHJlcXVpcmUoXCJyZWFjdFwiKSk6ZS5TY3JvbGxBcmVhPXQoZS5SZWFjdCl9KHRoaXMsZnVuY3Rpb24oZSl7cmV0dXJuIGZ1bmN0aW9uKGUpe2Z1bmN0aW9uIHQobyl7aWYobltvXSlyZXR1cm4gbltvXS5leHBvcnRzO3ZhciByPW5bb109e2V4cG9ydHM6e30saWQ6byxsb2FkZWQ6ITF9O3JldHVybiBlW29dLmNhbGwoci5leHBvcnRzLHIsci5leHBvcnRzLHQpLHIubG9hZGVkPSEwLHIuZXhwb3J0c312YXIgbj17fTtyZXR1cm4gdC5tPWUsdC5jPW4sdC5wPVwiXCIsdCgwKX0oW2Z1bmN0aW9uKGUsdCxuKXtcInVzZSBzdHJpY3RcIjtmdW5jdGlvbiBvKGUpe3JldHVybiBlJiZlLl9fZXNNb2R1bGU/ZTp7ZGVmYXVsdDplfX1PYmplY3QuZGVmaW5lUHJvcGVydHkodCxcIl9fZXNNb2R1bGVcIix7dmFsdWU6ITB9KSxuKDMxKTt2YXIgcj1uKDEzKSxpPW8ocik7dC5kZWZhdWx0PWkuZGVmYXVsdH0sZnVuY3Rpb24odCxuKXt0LmV4cG9ydHM9ZX0sZnVuY3Rpb24oZSx0LG4pe2UuZXhwb3J0cz1uKDE5KSgpfSxmdW5jdGlvbihlLHQpe1widXNlIHN0cmljdFwiO2Z1bmN0aW9uIG4oZSl7dmFyIHQ9e307Zm9yKHZhciBuIGluIGUpT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGUsbikmJih0W25dPVwibnVtYmVyXCI9PXR5cGVvZiBlW25dP2Vbbl06ZVtuXS52YWwpO3JldHVybiB0fXQuX19lc01vZHVsZT0hMCx0LmRlZmF1bHQ9bixlLmV4cG9ydHM9dC5kZWZhdWx0fSxmdW5jdGlvbihlLHQsbil7KGZ1bmN0aW9uKHQpeyhmdW5jdGlvbigpe3ZhciBuLG8scjtcInVuZGVmaW5lZFwiIT10eXBlb2YgcGVyZm9ybWFuY2UmJm51bGwhPT1wZXJmb3JtYW5jZSYmcGVyZm9ybWFuY2Uubm93P2UuZXhwb3J0cz1mdW5jdGlvbigpe3JldHVybiBwZXJmb3JtYW5jZS5ub3coKX06XCJ1bmRlZmluZWRcIiE9dHlwZW9mIHQmJm51bGwhPT10JiZ0LmhydGltZT8oZS5leHBvcnRzPWZ1bmN0aW9uKCl7cmV0dXJuKG4oKS1yKS8xZTZ9LG89dC5ocnRpbWUsbj1mdW5jdGlvbigpe3ZhciBlO3JldHVybiBlPW8oKSwxZTkqZVswXStlWzFdfSxyPW4oKSk6RGF0ZS5ub3c/KGUuZXhwb3J0cz1mdW5jdGlvbigpe3JldHVybiBEYXRlLm5vdygpLXJ9LHI9RGF0ZS5ub3coKSk6KGUuZXhwb3J0cz1mdW5jdGlvbigpe3JldHVybihuZXcgRGF0ZSkuZ2V0VGltZSgpLXJ9LHI9KG5ldyBEYXRlKS5nZXRUaW1lKCkpfSkuY2FsbCh0aGlzKX0pLmNhbGwodCxuKDEwKSl9LGZ1bmN0aW9uKGUsdCxuKXsoZnVuY3Rpb24odCl7Zm9yKHZhciBvPW4oMjMpLHI9XCJ1bmRlZmluZWRcIj09dHlwZW9mIHdpbmRvdz90OndpbmRvdyxpPVtcIm1velwiLFwid2Via2l0XCJdLGE9XCJBbmltYXRpb25GcmFtZVwiLGw9cltcInJlcXVlc3RcIithXSxzPXJbXCJjYW5jZWxcIithXXx8cltcImNhbmNlbFJlcXVlc3RcIithXSx1PTA7IWwmJnU8aS5sZW5ndGg7dSsrKWw9cltpW3VdK1wiUmVxdWVzdFwiK2FdLHM9cltpW3VdK1wiQ2FuY2VsXCIrYV18fHJbaVt1XStcIkNhbmNlbFJlcXVlc3RcIithXTtpZighbHx8IXMpe3ZhciBjPTAsZj0wLHA9W10sZD0xZTMvNjA7bD1mdW5jdGlvbihlKXtpZigwPT09cC5sZW5ndGgpe3ZhciB0PW8oKSxuPU1hdGgubWF4KDAsZC0odC1jKSk7Yz1uK3Qsc2V0VGltZW91dChmdW5jdGlvbigpe3ZhciBlPXAuc2xpY2UoMCk7cC5sZW5ndGg9MDtmb3IodmFyIHQ9MDt0PGUubGVuZ3RoO3QrKylpZighZVt0XS5jYW5jZWxsZWQpdHJ5e2VbdF0uY2FsbGJhY2soYyl9Y2F0Y2goZSl7c2V0VGltZW91dChmdW5jdGlvbigpe3Rocm93IGV9LDApfX0sTWF0aC5yb3VuZChuKSl9cmV0dXJuIHAucHVzaCh7aGFuZGxlOisrZixjYWxsYmFjazplLGNhbmNlbGxlZDohMX0pLGZ9LHM9ZnVuY3Rpb24oZSl7Zm9yKHZhciB0PTA7dDxwLmxlbmd0aDt0KyspcFt0XS5oYW5kbGU9PT1lJiYocFt0XS5jYW5jZWxsZWQ9ITApfX1lLmV4cG9ydHM9ZnVuY3Rpb24oZSl7cmV0dXJuIGwuY2FsbChyLGUpfSxlLmV4cG9ydHMuY2FuY2VsPWZ1bmN0aW9uKCl7cy5hcHBseShyLGFyZ3VtZW50cyl9LGUuZXhwb3J0cy5wb2x5ZmlsbD1mdW5jdGlvbihlKXtlfHwoZT1yKSxlLnJlcXVlc3RBbmltYXRpb25GcmFtZT1sLGUuY2FuY2VsQW5pbWF0aW9uRnJhbWU9c319KS5jYWxsKHQsZnVuY3Rpb24oKXtyZXR1cm4gdGhpc30oKSl9LGZ1bmN0aW9uKGUsdCl7XCJ1c2Ugc3RyaWN0XCI7ZnVuY3Rpb24gbihlKXt2YXIgdD17fTtmb3IodmFyIG4gaW4gZSlPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoZSxuKSYmKHRbbl09MCk7cmV0dXJuIHR9dC5fX2VzTW9kdWxlPSEwLHQuZGVmYXVsdD1uLGUuZXhwb3J0cz10LmRlZmF1bHR9LGZ1bmN0aW9uKGUsdCl7XCJ1c2Ugc3RyaWN0XCI7ZnVuY3Rpb24gbihlLHQsbil7Zm9yKHZhciBvIGluIHQpaWYoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHQsbykpe2lmKDAhPT1uW29dKXJldHVybiExO3ZhciByPVwibnVtYmVyXCI9PXR5cGVvZiB0W29dP3Rbb106dFtvXS52YWw7aWYoZVtvXSE9PXIpcmV0dXJuITF9cmV0dXJuITB9dC5fX2VzTW9kdWxlPSEwLHQuZGVmYXVsdD1uLGUuZXhwb3J0cz10LmRlZmF1bHR9LGZ1bmN0aW9uKGUsdCl7XCJ1c2Ugc3RyaWN0XCI7ZnVuY3Rpb24gbihlLHQsbixyLGksYSxsKXt2YXIgcz0taSoodC1yKSx1PS1hKm4sYz1zK3UsZj1uK2MqZSxwPXQrZiplO3JldHVybiBNYXRoLmFicyhmKTxsJiZNYXRoLmFicyhwLXIpPGw/KG9bMF09cixvWzFdPTAsbyk6KG9bMF09cCxvWzFdPWYsbyl9dC5fX2VzTW9kdWxlPSEwLHQuZGVmYXVsdD1uO3ZhciBvPVswLDBdO2UuZXhwb3J0cz10LmRlZmF1bHR9LGZ1bmN0aW9uKGUsdCxuKXtcInVzZSBzdHJpY3RcIjtmdW5jdGlvbiBvKGUpe3JldHVybiBlJiZlLl9fZXNNb2R1bGU/ZTp7ZGVmYXVsdDplfX1mdW5jdGlvbiByKGUpe3JldHVybiBwP2YuZGVmYXVsdC5maW5kRE9NTm9kZShlKTplfWZ1bmN0aW9uIGkoKXtkfHxwfHwoZD0hMCxjb25zb2xlLmVycm9yKFwiV2l0aCBSZWFjdCAwLjE0IGFuZCBsYXRlciB2ZXJzaW9ucywgeW91IG5vIGxvbmdlciBuZWVkIHRvIHdyYXAgPFNjcm9sbEFyZWE+IGNoaWxkIGludG8gYSBmdW5jdGlvbi5cIikpfWZ1bmN0aW9uIGEoKXshZCYmcCYmKGQ9ITAsY29uc29sZS5lcnJvcihcIldpdGggUmVhY3QgMC4xMywgeW91IG5lZWQgdG8gd3JhcCA8U2Nyb2xsQXJlYT4gY2hpbGQgaW50byBhIGZ1bmN0aW9uLlwiKSl9ZnVuY3Rpb24gbChlKXtyZXR1cm4gZTwwPzA6ZX1mdW5jdGlvbiBzKGUpe3ZhciB0PWFyZ3VtZW50cy5sZW5ndGg+MSYmdm9pZCAwIT09YXJndW1lbnRzWzFdP2FyZ3VtZW50c1sxXTpmdW5jdGlvbihlKXtyZXR1cm4gZX0sbj17fTtmb3IodmFyIG8gaW4gZSllLmhhc093blByb3BlcnR5KG8pJiYobltvXT10KGVbb10pKTtyZXR1cm4gbn1mdW5jdGlvbiB1KGUpe3ZhciB0PWUudmVyc2lvbjtpZihcInN0cmluZ1wiIT10eXBlb2YgdClyZXR1cm4hMDt2YXIgbj10LnNwbGl0KFwiLlwiKSxvPXBhcnNlSW50KG5bMF0sMTApLHI9cGFyc2VJbnQoblsxXSwxMCk7cmV0dXJuIDA9PT1vJiYxMz09PXJ9T2JqZWN0LmRlZmluZVByb3BlcnR5KHQsXCJfX2VzTW9kdWxlXCIse3ZhbHVlOiEwfSksdC5maW5kRE9NTm9kZT1yLHQud2FybkFib3V0RnVuY3Rpb25DaGlsZD1pLHQud2FybkFib3V0RWxlbWVudENoaWxkPWEsdC5wb3NpdGl2ZU9yWmVybz1sLHQubW9kaWZ5T2JqVmFsdWVzPXMsdC5pc1JlYWN0MTM9dTt2YXIgYz1uKDEpLGY9byhjKSxwPXUoZi5kZWZhdWx0KSxkPSExfSxmdW5jdGlvbihlLHQpe2Z1bmN0aW9uIG4oKXt0aHJvdyBuZXcgRXJyb3IoXCJzZXRUaW1lb3V0IGhhcyBub3QgYmVlbiBkZWZpbmVkXCIpfWZ1bmN0aW9uIG8oKXt0aHJvdyBuZXcgRXJyb3IoXCJjbGVhclRpbWVvdXQgaGFzIG5vdCBiZWVuIGRlZmluZWRcIil9ZnVuY3Rpb24gcihlKXtpZihjPT09c2V0VGltZW91dClyZXR1cm4gc2V0VGltZW91dChlLDApO2lmKChjPT09bnx8IWMpJiZzZXRUaW1lb3V0KXJldHVybiBjPXNldFRpbWVvdXQsc2V0VGltZW91dChlLDApO3RyeXtyZXR1cm4gYyhlLDApfWNhdGNoKHQpe3RyeXtyZXR1cm4gYy5jYWxsKG51bGwsZSwwKX1jYXRjaCh0KXtyZXR1cm4gYy5jYWxsKHRoaXMsZSwwKX19fWZ1bmN0aW9uIGkoZSl7aWYoZj09PWNsZWFyVGltZW91dClyZXR1cm4gY2xlYXJUaW1lb3V0KGUpO2lmKChmPT09b3x8IWYpJiZjbGVhclRpbWVvdXQpcmV0dXJuIGY9Y2xlYXJUaW1lb3V0LGNsZWFyVGltZW91dChlKTt0cnl7cmV0dXJuIGYoZSl9Y2F0Y2godCl7dHJ5e3JldHVybiBmLmNhbGwobnVsbCxlKX1jYXRjaCh0KXtyZXR1cm4gZi5jYWxsKHRoaXMsZSl9fX1mdW5jdGlvbiBhKCl7eSYmZCYmKHk9ITEsZC5sZW5ndGg/aD1kLmNvbmNhdChoKTp2PS0xLGgubGVuZ3RoJiZsKCkpfWZ1bmN0aW9uIGwoKXtpZigheSl7dmFyIGU9cihhKTt5PSEwO2Zvcih2YXIgdD1oLmxlbmd0aDt0Oyl7Zm9yKGQ9aCxoPVtdOysrdjx0OylkJiZkW3ZdLnJ1bigpO3Y9LTEsdD1oLmxlbmd0aH1kPW51bGwseT0hMSxpKGUpfX1mdW5jdGlvbiBzKGUsdCl7dGhpcy5mdW49ZSx0aGlzLmFycmF5PXR9ZnVuY3Rpb24gdSgpe312YXIgYyxmLHA9ZS5leHBvcnRzPXt9OyFmdW5jdGlvbigpe3RyeXtjPVwiZnVuY3Rpb25cIj09dHlwZW9mIHNldFRpbWVvdXQ/c2V0VGltZW91dDpufWNhdGNoKGUpe2M9bn10cnl7Zj1cImZ1bmN0aW9uXCI9PXR5cGVvZiBjbGVhclRpbWVvdXQ/Y2xlYXJUaW1lb3V0Om99Y2F0Y2goZSl7Zj1vfX0oKTt2YXIgZCxoPVtdLHk9ITEsdj0tMTtwLm5leHRUaWNrPWZ1bmN0aW9uKGUpe3ZhciB0PW5ldyBBcnJheShhcmd1bWVudHMubGVuZ3RoLTEpO2lmKGFyZ3VtZW50cy5sZW5ndGg+MSlmb3IodmFyIG49MTtuPGFyZ3VtZW50cy5sZW5ndGg7bisrKXRbbi0xXT1hcmd1bWVudHNbbl07aC5wdXNoKG5ldyBzKGUsdCkpLDEhPT1oLmxlbmd0aHx8eXx8cihsKX0scy5wcm90b3R5cGUucnVuPWZ1bmN0aW9uKCl7dGhpcy5mdW4uYXBwbHkobnVsbCx0aGlzLmFycmF5KX0scC50aXRsZT1cImJyb3dzZXJcIixwLmJyb3dzZXI9ITAscC5lbnY9e30scC5hcmd2PVtdLHAudmVyc2lvbj1cIlwiLHAudmVyc2lvbnM9e30scC5vbj11LHAuYWRkTGlzdGVuZXI9dSxwLm9uY2U9dSxwLm9mZj11LHAucmVtb3ZlTGlzdGVuZXI9dSxwLnJlbW92ZUFsbExpc3RlbmVycz11LHAuZW1pdD11LHAuYmluZGluZz1mdW5jdGlvbihlKXt0aHJvdyBuZXcgRXJyb3IoXCJwcm9jZXNzLmJpbmRpbmcgaXMgbm90IHN1cHBvcnRlZFwiKX0scC5jd2Q9ZnVuY3Rpb24oKXtyZXR1cm5cIi9cIn0scC5jaGRpcj1mdW5jdGlvbihlKXt0aHJvdyBuZXcgRXJyb3IoXCJwcm9jZXNzLmNoZGlyIGlzIG5vdCBzdXBwb3J0ZWRcIil9LHAudW1hc2s9ZnVuY3Rpb24oKXtyZXR1cm4gMH19LGZ1bmN0aW9uKGUsdCl7XCJ1c2Ugc3RyaWN0XCI7dC5fX2VzTW9kdWxlPSEwLHQuZGVmYXVsdD17bm9Xb2JibGU6e3N0aWZmbmVzczoxNzAsZGFtcGluZzoyNn0sZ2VudGxlOntzdGlmZm5lc3M6MTIwLGRhbXBpbmc6MTR9LHdvYmJseTp7c3RpZmZuZXNzOjE4MCxkYW1waW5nOjEyfSxzdGlmZjp7c3RpZmZuZXNzOjIxMCxkYW1waW5nOjIwfX0sZS5leHBvcnRzPXQuZGVmYXVsdH0sZnVuY3Rpb24oZSx0LG4pe1widXNlIHN0cmljdFwiO2Z1bmN0aW9uIG8oZSl7cmV0dXJuIGUmJmUuX19lc01vZHVsZT9lLmRlZmF1bHQ6ZX10Ll9fZXNNb2R1bGU9ITA7dmFyIHI9bigyNCk7dC5Nb3Rpb249byhyKTt2YXIgaT1uKDI1KTt0LlN0YWdnZXJlZE1vdGlvbj1vKGkpO3ZhciBhPW4oMjYpO3QuVHJhbnNpdGlvbk1vdGlvbj1vKGEpO3ZhciBsPW4oMjkpO3Quc3ByaW5nPW8obCk7dmFyIHM9bigxMSk7dC5wcmVzZXRzPW8ocyk7dmFyIHU9bigzKTt0LnN0cmlwU3R5bGU9byh1KTt2YXIgYz1uKDI4KTt0LnJlb3JkZXJLZXlzPW8oYyl9LGZ1bmN0aW9uKGUsdCxuKXtcInVzZSBzdHJpY3RcIjtmdW5jdGlvbiBvKGUpe3JldHVybiBlJiZlLl9fZXNNb2R1bGU/ZTp7ZGVmYXVsdDplfX1mdW5jdGlvbiByKGUsdCl7aWYoIShlIGluc3RhbmNlb2YgdCkpdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKX1mdW5jdGlvbiBpKGUsdCl7aWYoIWUpdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKFwidGhpcyBoYXNuJ3QgYmVlbiBpbml0aWFsaXNlZCAtIHN1cGVyKCkgaGFzbid0IGJlZW4gY2FsbGVkXCIpO3JldHVybiF0fHxcIm9iamVjdFwiIT10eXBlb2YgdCYmXCJmdW5jdGlvblwiIT10eXBlb2YgdD9lOnR9ZnVuY3Rpb24gYShlLHQpe2lmKFwiZnVuY3Rpb25cIiE9dHlwZW9mIHQmJm51bGwhPT10KXRocm93IG5ldyBUeXBlRXJyb3IoXCJTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90IFwiK3R5cGVvZiB0KTtlLnByb3RvdHlwZT1PYmplY3QuY3JlYXRlKHQmJnQucHJvdG90eXBlLHtjb25zdHJ1Y3Rvcjp7dmFsdWU6ZSxlbnVtZXJhYmxlOiExLHdyaXRhYmxlOiEwLGNvbmZpZ3VyYWJsZTohMH19KSx0JiYoT2JqZWN0LnNldFByb3RvdHlwZU9mP09iamVjdC5zZXRQcm90b3R5cGVPZihlLHQpOmUuX19wcm90b19fPXQpfU9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LFwiX19lc01vZHVsZVwiLHt2YWx1ZTohMH0pO3ZhciBsPVwiZnVuY3Rpb25cIj09dHlwZW9mIFN5bWJvbCYmXCJzeW1ib2xcIj09dHlwZW9mIFN5bWJvbC5pdGVyYXRvcj9mdW5jdGlvbihlKXtyZXR1cm4gdHlwZW9mIGV9OmZ1bmN0aW9uKGUpe3JldHVybiBlJiZcImZ1bmN0aW9uXCI9PXR5cGVvZiBTeW1ib2wmJmUuY29uc3RydWN0b3I9PT1TeW1ib2wmJmUhPT1TeW1ib2wucHJvdG90eXBlP1wic3ltYm9sXCI6dHlwZW9mIGV9LHM9T2JqZWN0LmFzc2lnbnx8ZnVuY3Rpb24oZSl7Zm9yKHZhciB0PTE7dDxhcmd1bWVudHMubGVuZ3RoO3QrKyl7dmFyIG49YXJndW1lbnRzW3RdO2Zvcih2YXIgbyBpbiBuKU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChuLG8pJiYoZVtvXT1uW29dKX1yZXR1cm4gZX0sdT1mdW5jdGlvbigpe2Z1bmN0aW9uIGUoZSx0KXtmb3IodmFyIG49MDtuPHQubGVuZ3RoO24rKyl7dmFyIG89dFtuXTtvLmVudW1lcmFibGU9by5lbnVtZXJhYmxlfHwhMSxvLmNvbmZpZ3VyYWJsZT0hMCxcInZhbHVlXCJpbiBvJiYoby53cml0YWJsZT0hMCksT2JqZWN0LmRlZmluZVByb3BlcnR5KGUsby5rZXksbyl9fXJldHVybiBmdW5jdGlvbih0LG4sbyl7cmV0dXJuIG4mJmUodC5wcm90b3R5cGUsbiksbyYmZSh0LG8pLHR9fSgpLGM9bigxKSxmPW8oYykscD1uKDIpLGQ9byhwKSxoPW4oMTgpLHk9byhoKSx2PW4oMTIpLG09big5KSxiPW4oMTQpLFM9byhiKSxnPXt3aGVlbDpcIndoZWVsXCIsYXBpOlwiYXBpXCIsdG91Y2g6XCJ0b3VjaFwiLHRvdWNoRW5kOlwidG91Y2hFbmRcIixtb3VzZW1vdmU6XCJtb3VzZW1vdmVcIixrZXlQcmVzczpcImtleXByZXNzXCJ9LHc9ZnVuY3Rpb24oZSl7ZnVuY3Rpb24gdChlKXtyKHRoaXMsdCk7dmFyIG49aSh0aGlzLCh0Ll9fcHJvdG9fX3x8T2JqZWN0LmdldFByb3RvdHlwZU9mKHQpKS5jYWxsKHRoaXMsZSkpO3JldHVybiBuLnN0YXRlPXt0b3BQb3NpdGlvbjowLGxlZnRQb3NpdGlvbjowLHJlYWxIZWlnaHQ6MCxjb250YWluZXJIZWlnaHQ6MCxyZWFsV2lkdGg6MCxjb250YWluZXJXaWR0aDowfSxuLnNjcm9sbEFyZWE9e3JlZnJlc2g6ZnVuY3Rpb24oKXtuLnNldFNpemVzVG9TdGF0ZSgpfSxzY3JvbGxUb3A6ZnVuY3Rpb24oKXtuLnNjcm9sbFRvcCgpfSxzY3JvbGxCb3R0b206ZnVuY3Rpb24oKXtuLnNjcm9sbEJvdHRvbSgpfSxzY3JvbGxZVG86ZnVuY3Rpb24oZSl7bi5zY3JvbGxZVG8oZSl9LHNjcm9sbExlZnQ6ZnVuY3Rpb24oKXtuLnNjcm9sbExlZnQoKX0sc2Nyb2xsUmlnaHQ6ZnVuY3Rpb24oKXtuLnNjcm9sbFJpZ2h0KCl9LHNjcm9sbFhUbzpmdW5jdGlvbihlKXtuLnNjcm9sbFhUbyhlKX19LG4uZXZudHNQcmV2aW91c1ZhbHVlcz17Y2xpZW50WDowLGNsaWVudFk6MCxkZWx0YVg6MCxkZWx0YVk6MH0sbi5iaW5kZWRIYW5kbGVXaW5kb3dSZXNpemU9bi5oYW5kbGVXaW5kb3dSZXNpemUuYmluZChuKSxufXJldHVybiBhKHQsZSksdSh0LFt7a2V5OlwiZ2V0Q2hpbGRDb250ZXh0XCIsdmFsdWU6ZnVuY3Rpb24oKXtyZXR1cm57c2Nyb2xsQXJlYTp0aGlzLnNjcm9sbEFyZWF9fX0se2tleTpcImNvbXBvbmVudERpZE1vdW50XCIsdmFsdWU6ZnVuY3Rpb24oKXt0aGlzLnByb3BzLmNvbnRlbnRXaW5kb3cmJnRoaXMucHJvcHMuY29udGVudFdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwicmVzaXplXCIsdGhpcy5iaW5kZWRIYW5kbGVXaW5kb3dSZXNpemUpLHRoaXMubGluZUhlaWdodFB4PSgwLHkuZGVmYXVsdCkoKDAsbS5maW5kRE9NTm9kZSkodGhpcy5jb250ZW50KSksdGhpcy5zZXRTaXplc1RvU3RhdGUoKX19LHtrZXk6XCJjb21wb25lbnRXaWxsVW5tb3VudFwiLHZhbHVlOmZ1bmN0aW9uKCl7dGhpcy5wcm9wcy5jb250ZW50V2luZG93JiZ0aGlzLnByb3BzLmNvbnRlbnRXaW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInJlc2l6ZVwiLHRoaXMuYmluZGVkSGFuZGxlV2luZG93UmVzaXplKX19LHtrZXk6XCJjb21wb25lbnREaWRVcGRhdGVcIix2YWx1ZTpmdW5jdGlvbigpe3RoaXMuc2V0U2l6ZXNUb1N0YXRlKCl9fSx7a2V5OlwicmVuZGVyXCIsdmFsdWU6ZnVuY3Rpb24oKXt2YXIgZT10aGlzLHQ9dGhpcy5wcm9wcyxuPXQuY2hpbGRyZW4sbz10LmNsYXNzTmFtZSxyPXQuY29udGVudENsYXNzTmFtZSxpPXQub3duZXJEb2N1bWVudCxhPXRoaXMucHJvcHMuc21vb3RoU2Nyb2xsaW5nJiYodGhpcy5zdGF0ZS5ldmVudFR5cGU9PT1nLndoZWVsfHx0aGlzLnN0YXRlLmV2ZW50VHlwZT09PWcuYXBpfHx0aGlzLnN0YXRlLmV2ZW50VHlwZT09PWcudG91Y2hFbmR8fHRoaXMuc3RhdGUuZXZlbnRUeXBlPT09Zy5rZXlQcmVzcyksbD10aGlzLmNhblNjcm9sbFkoKT9mLmRlZmF1bHQuY3JlYXRlRWxlbWVudChTLmRlZmF1bHQse293bmVyRG9jdW1lbnQ6aSxyZWFsU2l6ZTp0aGlzLnN0YXRlLnJlYWxIZWlnaHQsY29udGFpbmVyU2l6ZTp0aGlzLnN0YXRlLmNvbnRhaW5lckhlaWdodCxwb3NpdGlvbjp0aGlzLnN0YXRlLnRvcFBvc2l0aW9uLG9uTW92ZTp0aGlzLmhhbmRsZVNjcm9sbGJhck1vdmUuYmluZCh0aGlzKSxvblBvc2l0aW9uQ2hhbmdlOnRoaXMuaGFuZGxlU2Nyb2xsYmFyWVBvc2l0aW9uQ2hhbmdlLmJpbmQodGhpcyksY29udGFpbmVyU3R5bGU6dGhpcy5wcm9wcy52ZXJ0aWNhbENvbnRhaW5lclN0eWxlLHNjcm9sbGJhclN0eWxlOnRoaXMucHJvcHMudmVydGljYWxTY3JvbGxiYXJTdHlsZSxzbW9vdGhTY3JvbGxpbmc6YSxtaW5TY3JvbGxTaXplOnRoaXMucHJvcHMubWluU2Nyb2xsU2l6ZSxvbkZvY3VzOnRoaXMuZm9jdXNDb250ZW50LmJpbmQodGhpcyksdHlwZTpcInZlcnRpY2FsXCJ9KTpudWxsLHU9dGhpcy5jYW5TY3JvbGxYKCk/Zi5kZWZhdWx0LmNyZWF0ZUVsZW1lbnQoUy5kZWZhdWx0LHtvd25lckRvY3VtZW50OmkscmVhbFNpemU6dGhpcy5zdGF0ZS5yZWFsV2lkdGgsY29udGFpbmVyU2l6ZTp0aGlzLnN0YXRlLmNvbnRhaW5lcldpZHRoLHBvc2l0aW9uOnRoaXMuc3RhdGUubGVmdFBvc2l0aW9uLG9uTW92ZTp0aGlzLmhhbmRsZVNjcm9sbGJhck1vdmUuYmluZCh0aGlzKSxvblBvc2l0aW9uQ2hhbmdlOnRoaXMuaGFuZGxlU2Nyb2xsYmFyWFBvc2l0aW9uQ2hhbmdlLmJpbmQodGhpcyksY29udGFpbmVyU3R5bGU6dGhpcy5wcm9wcy5ob3Jpem9udGFsQ29udGFpbmVyU3R5bGUsc2Nyb2xsYmFyU3R5bGU6dGhpcy5wcm9wcy5ob3Jpem9udGFsU2Nyb2xsYmFyU3R5bGUsc21vb3RoU2Nyb2xsaW5nOmEsbWluU2Nyb2xsU2l6ZTp0aGlzLnByb3BzLm1pblNjcm9sbFNpemUsb25Gb2N1czp0aGlzLmZvY3VzQ29udGVudC5iaW5kKHRoaXMpLHR5cGU6XCJob3Jpem9udGFsXCJ9KTpudWxsO1wiZnVuY3Rpb25cIj09dHlwZW9mIG4/KCgwLG0ud2FybkFib3V0RnVuY3Rpb25DaGlsZCkoKSxuPW4oKSk6KDAsbS53YXJuQWJvdXRFbGVtZW50Q2hpbGQpKCk7dmFyIGM9XCJzY3JvbGxhcmVhIFwiKyhvfHxcIlwiKSxwPVwic2Nyb2xsYXJlYS1jb250ZW50IFwiKyhyfHxcIlwiKSxkPXttYXJnaW5Ub3A6LXRoaXMuc3RhdGUudG9wUG9zaXRpb24sbWFyZ2luTGVmdDotdGhpcy5zdGF0ZS5sZWZ0UG9zaXRpb259LGg9YT8oMCxtLm1vZGlmeU9ialZhbHVlcykoZCxmdW5jdGlvbihlKXtyZXR1cm4oMCx2LnNwcmluZykoZSl9KTpkO3JldHVybiBmLmRlZmF1bHQuY3JlYXRlRWxlbWVudCh2Lk1vdGlvbix7c3R5bGU6aH0sZnVuY3Rpb24odCl7cmV0dXJuIGYuZGVmYXVsdC5jcmVhdGVFbGVtZW50KFwiZGl2XCIse3JlZjpmdW5jdGlvbih0KXtyZXR1cm4gZS53cmFwcGVyPXR9LGNsYXNzTmFtZTpjLHN0eWxlOmUucHJvcHMuc3R5bGUsb25XaGVlbDplLmhhbmRsZVdoZWVsLmJpbmQoZSl9LGYuZGVmYXVsdC5jcmVhdGVFbGVtZW50KFwiZGl2XCIse3JlZjpmdW5jdGlvbih0KXtyZXR1cm4gZS5jb250ZW50PXR9LHN0eWxlOnMoe30sZS5wcm9wcy5jb250ZW50U3R5bGUsdCksY2xhc3NOYW1lOnAsb25Ub3VjaFN0YXJ0OmUuaGFuZGxlVG91Y2hTdGFydC5iaW5kKGUpLG9uVG91Y2hNb3ZlOmUuaGFuZGxlVG91Y2hNb3ZlLmJpbmQoZSksb25Ub3VjaEVuZDplLmhhbmRsZVRvdWNoRW5kLmJpbmQoZSksb25LZXlEb3duOmUuaGFuZGxlS2V5RG93bi5iaW5kKGUpLHRhYkluZGV4OmUucHJvcHMuZm9jdXNhYmxlVGFiSW5kZXh9LG4pLGwsdSl9KX19LHtrZXk6XCJzZXRTdGF0ZUZyb21FdmVudFwiLHZhbHVlOmZ1bmN0aW9uKGUsdCl7dGhpcy5wcm9wcy5vblNjcm9sbCYmdGhpcy5wcm9wcy5vblNjcm9sbChlKSx0aGlzLnNldFN0YXRlKHMoe30sZSx7ZXZlbnRUeXBlOnR9KSl9fSx7a2V5OlwiaGFuZGxlVG91Y2hTdGFydFwiLHZhbHVlOmZ1bmN0aW9uKGUpe3ZhciB0PWUudG91Y2hlcztpZigxPT09dC5sZW5ndGgpe3ZhciBuPXRbMF0sbz1uLmNsaWVudFgscj1uLmNsaWVudFk7dGhpcy5ldmVudFByZXZpb3VzVmFsdWVzPXMoe30sdGhpcy5ldmVudFByZXZpb3VzVmFsdWVzLHtjbGllbnRZOnIsY2xpZW50WDpvLHRpbWVzdGFtcDpEYXRlLm5vdygpfSl9fX0se2tleTpcImhhbmRsZVRvdWNoTW92ZVwiLHZhbHVlOmZ1bmN0aW9uKGUpe3RoaXMuY2FuU2Nyb2xsKCkmJihlLnByZXZlbnREZWZhdWx0KCksZS5zdG9wUHJvcGFnYXRpb24oKSk7dmFyIHQ9ZS50b3VjaGVzO2lmKDE9PT10Lmxlbmd0aCl7dmFyIG49dFswXSxvPW4uY2xpZW50WCxyPW4uY2xpZW50WSxpPXRoaXMuZXZlbnRQcmV2aW91c1ZhbHVlcy5jbGllbnRZLXIsYT10aGlzLmV2ZW50UHJldmlvdXNWYWx1ZXMuY2xpZW50WC1vO3RoaXMuZXZlbnRQcmV2aW91c1ZhbHVlcz1zKHt9LHRoaXMuZXZlbnRQcmV2aW91c1ZhbHVlcyx7ZGVsdGFZOmksZGVsdGFYOmEsY2xpZW50WTpyLGNsaWVudFg6byx0aW1lc3RhbXA6RGF0ZS5ub3coKX0pLHRoaXMuc2V0U3RhdGVGcm9tRXZlbnQodGhpcy5jb21wb3NlTmV3U3RhdGUoLWEsLWkpKX19fSx7a2V5OlwiaGFuZGxlVG91Y2hFbmRcIix2YWx1ZTpmdW5jdGlvbihlKXt2YXIgdD10aGlzLmV2ZW50UHJldmlvdXNWYWx1ZXMsbj10LmRlbHRhWCxvPXQuZGVsdGFZLHI9dC50aW1lc3RhbXA7XCJ1bmRlZmluZWRcIj09dHlwZW9mIG4mJihuPTApLFwidW5kZWZpbmVkXCI9PXR5cGVvZiBvJiYobz0wKSxEYXRlLm5vdygpLXI8MjAwJiZ0aGlzLnNldFN0YXRlRnJvbUV2ZW50KHRoaXMuY29tcG9zZU5ld1N0YXRlKDEwKi1uLDEwKi1vKSxnLnRvdWNoRW5kKSx0aGlzLmV2ZW50UHJldmlvdXNWYWx1ZXM9cyh7fSx0aGlzLmV2ZW50UHJldmlvdXNWYWx1ZXMse2RlbHRhWTowLGRlbHRhWDowfSl9fSx7a2V5OlwiaGFuZGxlU2Nyb2xsYmFyTW92ZVwiLHZhbHVlOmZ1bmN0aW9uKGUsdCl7dGhpcy5zZXRTdGF0ZUZyb21FdmVudCh0aGlzLmNvbXBvc2VOZXdTdGF0ZSh0LGUpKX19LHtrZXk6XCJoYW5kbGVTY3JvbGxiYXJYUG9zaXRpb25DaGFuZ2VcIix2YWx1ZTpmdW5jdGlvbihlKXt0aGlzLnNjcm9sbFhUbyhlKX19LHtrZXk6XCJoYW5kbGVTY3JvbGxiYXJZUG9zaXRpb25DaGFuZ2VcIix2YWx1ZTpmdW5jdGlvbihlKXt0aGlzLnNjcm9sbFlUbyhlKX19LHtrZXk6XCJoYW5kbGVXaGVlbFwiLHZhbHVlOmZ1bmN0aW9uKGUpe3ZhciB0PWUuZGVsdGFZLG49ZS5kZWx0YVg7aWYodGhpcy5wcm9wcy5zd2FwV2hlZWxBeGVzKXt2YXIgbz1bbix0XTt0PW9bMF0sbj1vWzFdfTE9PT1lLmRlbHRhTW9kZSYmKHQqPXRoaXMubGluZUhlaWdodFB4LG4qPXRoaXMubGluZUhlaWdodFB4KSx0Kj10aGlzLnByb3BzLnNwZWVkLG4qPXRoaXMucHJvcHMuc3BlZWQ7dmFyIHI9dGhpcy5jb21wb3NlTmV3U3RhdGUoLW4sLXQpOyhyLnRvcFBvc2l0aW9uJiZ0aGlzLnN0YXRlLnRvcFBvc2l0aW9uIT09ci50b3BQb3NpdGlvbnx8ci5sZWZ0UG9zaXRpb24mJnRoaXMuc3RhdGUubGVmdFBvc2l0aW9uIT09ci5sZWZ0UG9zaXRpb258fHRoaXMucHJvcHMuc3RvcFNjcm9sbFByb3BhZ2F0aW9uKSYmKGUucHJldmVudERlZmF1bHQoKSxlLnN0b3BQcm9wYWdhdGlvbigpKSx0aGlzLnNldFN0YXRlRnJvbUV2ZW50KHIsZy53aGVlbCksdGhpcy5mb2N1c0NvbnRlbnQoKX19LHtrZXk6XCJoYW5kbGVLZXlEb3duXCIsdmFsdWU6ZnVuY3Rpb24oZSl7aWYoXCJpbnB1dFwiIT09ZS50YXJnZXQudGFnTmFtZS50b0xvd2VyQ2FzZSgpJiZcInRleHRhcmVhXCIhPT1lLnRhcmdldC50YWdOYW1lLnRvTG93ZXJDYXNlKCkmJiFlLnRhcmdldC5pc0NvbnRlbnRFZGl0YWJsZSl7dmFyIHQ9MCxuPTAsbz10aGlzLmxpbmVIZWlnaHRQeD90aGlzLmxpbmVIZWlnaHRQeDoxMDtzd2l0Y2goZS5rZXlDb2RlKXtjYXNlIDMzOnQ9dGhpcy5zdGF0ZS5jb250YWluZXJIZWlnaHQtbzticmVhaztjYXNlIDM0OnQ9LXRoaXMuc3RhdGUuY29udGFpbmVySGVpZ2h0K287YnJlYWs7Y2FzZSAzNzpuPW87YnJlYWs7Y2FzZSAzODp0PW87YnJlYWs7Y2FzZSAzOTpuPS1vO2JyZWFrO2Nhc2UgNDA6dD0tb31pZigwIT09dHx8MCE9PW4pe3ZhciByPXRoaXMuY29tcG9zZU5ld1N0YXRlKG4sdCk7ZS5wcmV2ZW50RGVmYXVsdCgpLGUuc3RvcFByb3BhZ2F0aW9uKCksdGhpcy5zZXRTdGF0ZUZyb21FdmVudChyLGcua2V5UHJlc3MpfX19fSx7a2V5OlwiaGFuZGxlV2luZG93UmVzaXplXCIsdmFsdWU6ZnVuY3Rpb24oKXt2YXIgZT10aGlzLmNvbXB1dGVTaXplcygpO2U9dGhpcy5nZXRNb2RpZmllZFBvc2l0aW9uc0lmTmVlZGVkKGUpLHRoaXMuc2V0U3RhdGVGcm9tRXZlbnQoZSl9fSx7a2V5OlwiY29tcG9zZU5ld1N0YXRlXCIsdmFsdWU6ZnVuY3Rpb24oZSx0KXt2YXIgbj10aGlzLmNvbXB1dGVTaXplcygpO3JldHVybiB0aGlzLmNhblNjcm9sbFkobik/bi50b3BQb3NpdGlvbj10aGlzLmNvbXB1dGVUb3BQb3NpdGlvbih0LG4pOm4udG9wUG9zaXRpb249MCx0aGlzLmNhblNjcm9sbFgobikmJihuLmxlZnRQb3NpdGlvbj10aGlzLmNvbXB1dGVMZWZ0UG9zaXRpb24oZSxuKSksbn19LHtrZXk6XCJjb21wdXRlVG9wUG9zaXRpb25cIix2YWx1ZTpmdW5jdGlvbihlLHQpe3ZhciBuPXRoaXMuc3RhdGUudG9wUG9zaXRpb24tZTtyZXR1cm4gdGhpcy5ub3JtYWxpemVUb3BQb3NpdGlvbihuLHQpfX0se2tleTpcImNvbXB1dGVMZWZ0UG9zaXRpb25cIix2YWx1ZTpmdW5jdGlvbihlLHQpe3ZhciBuPXRoaXMuc3RhdGUubGVmdFBvc2l0aW9uLWU7cmV0dXJuIHRoaXMubm9ybWFsaXplTGVmdFBvc2l0aW9uKG4sdCl9fSx7a2V5Olwibm9ybWFsaXplVG9wUG9zaXRpb25cIix2YWx1ZTpmdW5jdGlvbihlLHQpe3JldHVybiBlPnQucmVhbEhlaWdodC10LmNvbnRhaW5lckhlaWdodCYmKGU9dC5yZWFsSGVpZ2h0LXQuY29udGFpbmVySGVpZ2h0KSxlPDAmJihlPTApLGV9fSx7a2V5Olwibm9ybWFsaXplTGVmdFBvc2l0aW9uXCIsdmFsdWU6ZnVuY3Rpb24oZSx0KXtyZXR1cm4gZT50LnJlYWxXaWR0aC10LmNvbnRhaW5lcldpZHRoP2U9dC5yZWFsV2lkdGgtdC5jb250YWluZXJXaWR0aDplPDAmJihlPTApLGV9fSx7a2V5OlwiY29tcHV0ZVNpemVzXCIsdmFsdWU6ZnVuY3Rpb24oKXt2YXIgZT10aGlzLmNvbnRlbnQub2Zmc2V0SGVpZ2h0LHQ9dGhpcy53cmFwcGVyLm9mZnNldEhlaWdodCxuPXRoaXMuY29udGVudC5vZmZzZXRXaWR0aCxvPXRoaXMud3JhcHBlci5vZmZzZXRXaWR0aDtyZXR1cm57cmVhbEhlaWdodDplLGNvbnRhaW5lckhlaWdodDp0LHJlYWxXaWR0aDpuLGNvbnRhaW5lcldpZHRoOm99fX0se2tleTpcInNldFNpemVzVG9TdGF0ZVwiLHZhbHVlOmZ1bmN0aW9uKCl7dmFyIGU9dGhpcy5jb21wdXRlU2l6ZXMoKTtlLnJlYWxIZWlnaHQ9PT10aGlzLnN0YXRlLnJlYWxIZWlnaHQmJmUucmVhbFdpZHRoPT09dGhpcy5zdGF0ZS5yZWFsV2lkdGh8fHRoaXMuc2V0U3RhdGVGcm9tRXZlbnQodGhpcy5nZXRNb2RpZmllZFBvc2l0aW9uc0lmTmVlZGVkKGUpKX19LHtrZXk6XCJzY3JvbGxUb3BcIix2YWx1ZTpmdW5jdGlvbigpe3RoaXMuc2Nyb2xsWVRvKDApfX0se2tleTpcInNjcm9sbEJvdHRvbVwiLHZhbHVlOmZ1bmN0aW9uKCl7dGhpcy5zY3JvbGxZVG8odGhpcy5zdGF0ZS5yZWFsSGVpZ2h0LXRoaXMuc3RhdGUuY29udGFpbmVySGVpZ2h0KX19LHtrZXk6XCJzY3JvbGxMZWZ0XCIsdmFsdWU6ZnVuY3Rpb24oKXt0aGlzLnNjcm9sbFhUbygwKX19LHtrZXk6XCJzY3JvbGxSaWdodFwiLHZhbHVlOmZ1bmN0aW9uKCl7dGhpcy5zY3JvbGxYVG8odGhpcy5zdGF0ZS5yZWFsV2lkdGgtdGhpcy5zdGF0ZS5jb250YWluZXJXaWR0aCl9fSx7a2V5Olwic2Nyb2xsWVRvXCIsdmFsdWU6ZnVuY3Rpb24oZSl7aWYodGhpcy5jYW5TY3JvbGxZKCkpe3ZhciB0PXRoaXMubm9ybWFsaXplVG9wUG9zaXRpb24oZSx0aGlzLmNvbXB1dGVTaXplcygpKTt0aGlzLnNldFN0YXRlRnJvbUV2ZW50KHt0b3BQb3NpdGlvbjp0fSxnLmFwaSl9fX0se2tleTpcInNjcm9sbFhUb1wiLHZhbHVlOmZ1bmN0aW9uKGUpe2lmKHRoaXMuY2FuU2Nyb2xsWCgpKXt2YXIgdD10aGlzLm5vcm1hbGl6ZUxlZnRQb3NpdGlvbihlLHRoaXMuY29tcHV0ZVNpemVzKCkpO3RoaXMuc2V0U3RhdGVGcm9tRXZlbnQoe2xlZnRQb3NpdGlvbjp0fSxnLmFwaSl9fX0se2tleTpcImNhblNjcm9sbFlcIix2YWx1ZTpmdW5jdGlvbigpe3ZhciBlPWFyZ3VtZW50cy5sZW5ndGg+MCYmdm9pZCAwIT09YXJndW1lbnRzWzBdP2FyZ3VtZW50c1swXTp0aGlzLnN0YXRlLHQ9ZS5yZWFsSGVpZ2h0PmUuY29udGFpbmVySGVpZ2h0O3JldHVybiB0JiZ0aGlzLnByb3BzLnZlcnRpY2FsfX0se2tleTpcImNhblNjcm9sbFhcIix2YWx1ZTpmdW5jdGlvbigpe3ZhciBlPWFyZ3VtZW50cy5sZW5ndGg+MCYmdm9pZCAwIT09YXJndW1lbnRzWzBdP2FyZ3VtZW50c1swXTp0aGlzLnN0YXRlLHQ9ZS5yZWFsV2lkdGg+ZS5jb250YWluZXJXaWR0aDtyZXR1cm4gdCYmdGhpcy5wcm9wcy5ob3Jpem9udGFsfX0se2tleTpcImNhblNjcm9sbFwiLHZhbHVlOmZ1bmN0aW9uKCl7dmFyIGU9YXJndW1lbnRzLmxlbmd0aD4wJiZ2b2lkIDAhPT1hcmd1bWVudHNbMF0/YXJndW1lbnRzWzBdOnRoaXMuc3RhdGU7cmV0dXJuIHRoaXMuY2FuU2Nyb2xsWShlKXx8dGhpcy5jYW5TY3JvbGxYKGUpfX0se2tleTpcImdldE1vZGlmaWVkUG9zaXRpb25zSWZOZWVkZWRcIix2YWx1ZTpmdW5jdGlvbihlKXt2YXIgdD1lLnJlYWxIZWlnaHQtZS5jb250YWluZXJIZWlnaHQ7dGhpcy5zdGF0ZS50b3BQb3NpdGlvbj49dCYmKGUudG9wUG9zaXRpb249dGhpcy5jYW5TY3JvbGxZKGUpPygwLG0ucG9zaXRpdmVPclplcm8pKHQpOjApO3ZhciBuPWUucmVhbFdpZHRoLWUuY29udGFpbmVyV2lkdGg7cmV0dXJuIHRoaXMuc3RhdGUubGVmdFBvc2l0aW9uPj1uJiYoZS5sZWZ0UG9zaXRpb249dGhpcy5jYW5TY3JvbGxYKGUpPygwLG0ucG9zaXRpdmVPclplcm8pKG4pOjApLGV9fSx7a2V5OlwiZm9jdXNDb250ZW50XCIsdmFsdWU6ZnVuY3Rpb24oKXt0aGlzLmNvbnRlbnQmJigwLG0uZmluZERPTU5vZGUpKHRoaXMuY29udGVudCkuZm9jdXMoKX19XSksdH0oZi5kZWZhdWx0LkNvbXBvbmVudCk7dC5kZWZhdWx0PXcsdy5jaGlsZENvbnRleHRUeXBlcz17c2Nyb2xsQXJlYTpkLmRlZmF1bHQub2JqZWN0fSx3LnByb3BUeXBlcz17Y2xhc3NOYW1lOmQuZGVmYXVsdC5zdHJpbmcsc3R5bGU6ZC5kZWZhdWx0Lm9iamVjdCxzcGVlZDpkLmRlZmF1bHQubnVtYmVyLGNvbnRlbnRDbGFzc05hbWU6ZC5kZWZhdWx0LnN0cmluZyxjb250ZW50U3R5bGU6ZC5kZWZhdWx0Lm9iamVjdCx2ZXJ0aWNhbDpkLmRlZmF1bHQuYm9vbCx2ZXJ0aWNhbENvbnRhaW5lclN0eWxlOmQuZGVmYXVsdC5vYmplY3QsdmVydGljYWxTY3JvbGxiYXJTdHlsZTpkLmRlZmF1bHQub2JqZWN0LGhvcml6b250YWw6ZC5kZWZhdWx0LmJvb2wsaG9yaXpvbnRhbENvbnRhaW5lclN0eWxlOmQuZGVmYXVsdC5vYmplY3QsaG9yaXpvbnRhbFNjcm9sbGJhclN0eWxlOmQuZGVmYXVsdC5vYmplY3Qsb25TY3JvbGw6ZC5kZWZhdWx0LmZ1bmMsY29udGVudFdpbmRvdzpkLmRlZmF1bHQuYW55LG93bmVyRG9jdW1lbnQ6ZC5kZWZhdWx0LmFueSxzbW9vdGhTY3JvbGxpbmc6ZC5kZWZhdWx0LmJvb2wsbWluU2Nyb2xsU2l6ZTpkLmRlZmF1bHQubnVtYmVyLHN3YXBXaGVlbEF4ZXM6ZC5kZWZhdWx0LmJvb2wsc3RvcFNjcm9sbFByb3BhZ2F0aW9uOmQuZGVmYXVsdC5ib29sLGZvY3VzYWJsZVRhYkluZGV4OmQuZGVmYXVsdC5udW1iZXJ9LHcuZGVmYXVsdFByb3BzPXtzcGVlZDoxLHZlcnRpY2FsOiEwLGhvcml6b250YWw6ITAsc21vb3RoU2Nyb2xsaW5nOiExLHN3YXBXaGVlbEF4ZXM6ITEsY29udGVudFdpbmRvdzpcIm9iamVjdFwiPT09KFwidW5kZWZpbmVkXCI9PXR5cGVvZiB3aW5kb3c/XCJ1bmRlZmluZWRcIjpsKHdpbmRvdykpP3dpbmRvdzp2b2lkIDAsb3duZXJEb2N1bWVudDpcIm9iamVjdFwiPT09KFwidW5kZWZpbmVkXCI9PXR5cGVvZiBkb2N1bWVudD9cInVuZGVmaW5lZFwiOmwoZG9jdW1lbnQpKT9kb2N1bWVudDp2b2lkIDAsZm9jdXNhYmxlVGFiSW5kZXg6MX19LGZ1bmN0aW9uKGUsdCxuKXtcInVzZSBzdHJpY3RcIjtmdW5jdGlvbiBvKGUpe3JldHVybiBlJiZlLl9fZXNNb2R1bGU/ZTp7ZGVmYXVsdDplfX1mdW5jdGlvbiByKGUsdCl7aWYoIShlIGluc3RhbmNlb2YgdCkpdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKX1mdW5jdGlvbiBpKGUsdCl7aWYoIWUpdGhyb3cgbmV3IFJlZmVyZW5jZUVycm9yKFwidGhpcyBoYXNuJ3QgYmVlbiBpbml0aWFsaXNlZCAtIHN1cGVyKCkgaGFzbid0IGJlZW4gY2FsbGVkXCIpO3JldHVybiF0fHxcIm9iamVjdFwiIT10eXBlb2YgdCYmXCJmdW5jdGlvblwiIT10eXBlb2YgdD9lOnR9ZnVuY3Rpb24gYShlLHQpe2lmKFwiZnVuY3Rpb25cIiE9dHlwZW9mIHQmJm51bGwhPT10KXRocm93IG5ldyBUeXBlRXJyb3IoXCJTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90IFwiK3R5cGVvZiB0KTtlLnByb3RvdHlwZT1PYmplY3QuY3JlYXRlKHQmJnQucHJvdG90eXBlLHtjb25zdHJ1Y3Rvcjp7dmFsdWU6ZSxlbnVtZXJhYmxlOiExLHdyaXRhYmxlOiEwLGNvbmZpZ3VyYWJsZTohMH19KSx0JiYoT2JqZWN0LnNldFByb3RvdHlwZU9mP09iamVjdC5zZXRQcm90b3R5cGVPZihlLHQpOmUuX19wcm90b19fPXQpfU9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0LFwiX19lc01vZHVsZVwiLHt2YWx1ZTohMH0pO3ZhciBsPU9iamVjdC5hc3NpZ258fGZ1bmN0aW9uKGUpe2Zvcih2YXIgdD0xO3Q8YXJndW1lbnRzLmxlbmd0aDt0Kyspe3ZhciBuPWFyZ3VtZW50c1t0XTtmb3IodmFyIG8gaW4gbilPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobixvKSYmKGVbb109bltvXSl9cmV0dXJuIGV9LHM9ZnVuY3Rpb24oKXtmdW5jdGlvbiBlKGUsdCl7Zm9yKHZhciBuPTA7bjx0Lmxlbmd0aDtuKyspe3ZhciBvPXRbbl07by5lbnVtZXJhYmxlPW8uZW51bWVyYWJsZXx8ITEsby5jb25maWd1cmFibGU9ITAsXCJ2YWx1ZVwiaW4gbyYmKG8ud3JpdGFibGU9ITApLE9iamVjdC5kZWZpbmVQcm9wZXJ0eShlLG8ua2V5LG8pfX1yZXR1cm4gZnVuY3Rpb24odCxuLG8pe3JldHVybiBuJiZlKHQucHJvdG90eXBlLG4pLG8mJmUodCxvKSx0fX0oKSx1PW4oMSksYz1vKHUpLGY9bigyKSxwPW8oZiksZD1uKDEyKSxoPW4oOSkseT1mdW5jdGlvbihlKXtmdW5jdGlvbiB0KGUpe3IodGhpcyx0KTt2YXIgbj1pKHRoaXMsKHQuX19wcm90b19ffHxPYmplY3QuZ2V0UHJvdG90eXBlT2YodCkpLmNhbGwodGhpcyxlKSksbz1uLmNhbGN1bGF0ZVN0YXRlKGUpO3JldHVybiBuLnN0YXRlPXtwb3NpdGlvbjpvLnBvc2l0aW9uLHNjcm9sbFNpemU6by5zY3JvbGxTaXplLGlzRHJhZ2dpbmc6ITEsbGFzdENsaWVudFBvc2l0aW9uOjB9LFwidmVydGljYWxcIj09PWUudHlwZT9uLmJpbmRlZEhhbmRsZU1vdXNlTW92ZT1uLmhhbmRsZU1vdXNlTW92ZUZvclZlcnRpY2FsLmJpbmQobik6bi5iaW5kZWRIYW5kbGVNb3VzZU1vdmU9bi5oYW5kbGVNb3VzZU1vdmVGb3JIb3Jpem9udGFsLmJpbmQobiksbi5iaW5kZWRIYW5kbGVNb3VzZVVwPW4uaGFuZGxlTW91c2VVcC5iaW5kKG4pLG59cmV0dXJuIGEodCxlKSxzKHQsW3trZXk6XCJjb21wb25lbnREaWRNb3VudFwiLHZhbHVlOmZ1bmN0aW9uKCl7dGhpcy5wcm9wcy5vd25lckRvY3VtZW50JiYodGhpcy5wcm9wcy5vd25lckRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJtb3VzZW1vdmVcIix0aGlzLmJpbmRlZEhhbmRsZU1vdXNlTW92ZSksdGhpcy5wcm9wcy5vd25lckRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJtb3VzZXVwXCIsdGhpcy5iaW5kZWRIYW5kbGVNb3VzZVVwKSl9fSx7a2V5OlwiY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wc1wiLHZhbHVlOmZ1bmN0aW9uKGUpe3RoaXMuc2V0U3RhdGUodGhpcy5jYWxjdWxhdGVTdGF0ZShlKSl9fSx7a2V5OlwiY29tcG9uZW50V2lsbFVubW91bnRcIix2YWx1ZTpmdW5jdGlvbigpe3RoaXMucHJvcHMub3duZXJEb2N1bWVudCYmKHRoaXMucHJvcHMub3duZXJEb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwibW91c2Vtb3ZlXCIsdGhpcy5iaW5kZWRIYW5kbGVNb3VzZU1vdmUpLHRoaXMucHJvcHMub3duZXJEb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFwibW91c2V1cFwiLHRoaXMuYmluZGVkSGFuZGxlTW91c2VVcCkpfX0se2tleTpcImNhbGN1bGF0ZUZyYWN0aW9uYWxQb3NpdGlvblwiLHZhbHVlOmZ1bmN0aW9uKGUsdCxuKXt2YXIgbz1lLXQ7cmV0dXJuIDEtKG8tbikvb319LHtrZXk6XCJjYWxjdWxhdGVTdGF0ZVwiLHZhbHVlOmZ1bmN0aW9uKGUpe3ZhciB0PXRoaXMuY2FsY3VsYXRlRnJhY3Rpb25hbFBvc2l0aW9uKGUucmVhbFNpemUsZS5jb250YWluZXJTaXplLGUucG9zaXRpb24pLG49ZS5jb250YWluZXJTaXplKmUuY29udGFpbmVyU2l6ZS9lLnJlYWxTaXplLG89bjxlLm1pblNjcm9sbFNpemU/ZS5taW5TY3JvbGxTaXplOm4scj0oZS5jb250YWluZXJTaXplLW8pKnQ7cmV0dXJue3Njcm9sbFNpemU6byxwb3NpdGlvbjpNYXRoLnJvdW5kKHIpfX19LHtrZXk6XCJyZW5kZXJcIix2YWx1ZTpmdW5jdGlvbigpe3ZhciBlPXRoaXMsdD10aGlzLnByb3BzLG49dC5zbW9vdGhTY3JvbGxpbmcsbz10LmlzRHJhZ2dpbmcscj10LnR5cGUsaT10LnNjcm9sbGJhclN0eWxlLGE9dC5jb250YWluZXJTdHlsZSxzPVwiaG9yaXpvbnRhbFwiPT09cix1PVwidmVydGljYWxcIj09PXIsZj10aGlzLmNyZWF0ZVNjcm9sbFN0eWxlcygpLHA9bj8oMCxoLm1vZGlmeU9ialZhbHVlcykoZixmdW5jdGlvbihlKXtyZXR1cm4oMCxkLnNwcmluZykoZSl9KTpmLHk9XCJzY3JvbGxiYXItY29udGFpbmVyIFwiKyhvP1wiYWN0aXZlXCI6XCJcIikrXCIgXCIrKHM/XCJob3Jpem9udGFsXCI6XCJcIikrXCIgXCIrKHU/XCJ2ZXJ0aWNhbFwiOlwiXCIpO3JldHVybiBjLmRlZmF1bHQuY3JlYXRlRWxlbWVudChkLk1vdGlvbix7c3R5bGU6cH0sZnVuY3Rpb24odCl7cmV0dXJuIGMuZGVmYXVsdC5jcmVhdGVFbGVtZW50KFwiZGl2XCIse2NsYXNzTmFtZTp5LHN0eWxlOmEsb25Nb3VzZURvd246ZS5oYW5kbGVTY3JvbGxCYXJDb250YWluZXJDbGljay5iaW5kKGUpLHJlZjpmdW5jdGlvbih0KXtyZXR1cm4gZS5zY3JvbGxiYXJDb250YWluZXI9dH19LGMuZGVmYXVsdC5jcmVhdGVFbGVtZW50KFwiZGl2XCIse2NsYXNzTmFtZTpcInNjcm9sbGJhclwiLHN0eWxlOmwoe30saSx0KSxvbk1vdXNlRG93bjplLmhhbmRsZU1vdXNlRG93bi5iaW5kKGUpfSkpfSl9fSx7a2V5OlwiaGFuZGxlU2Nyb2xsQmFyQ29udGFpbmVyQ2xpY2tcIix2YWx1ZTpmdW5jdGlvbihlKXtlLnByZXZlbnREZWZhdWx0KCk7dmFyIHQ9dGhpcy5jb21wdXRlTXVsdGlwbGllcigpLG49dGhpcy5pc1ZlcnRpY2FsKCk/ZS5jbGllbnRZOmUuY2xpZW50WCxvPXRoaXMuc2Nyb2xsYmFyQ29udGFpbmVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLHI9by50b3AsaT1vLmxlZnQsYT10aGlzLmlzVmVydGljYWwoKT9yOmksbD1uLWEscz10aGlzLnByb3BzLmNvbnRhaW5lclNpemUqdGhpcy5wcm9wcy5jb250YWluZXJTaXplL3RoaXMucHJvcHMucmVhbFNpemU7dGhpcy5zZXRTdGF0ZSh7aXNEcmFnZ2luZzohMCxsYXN0Q2xpZW50UG9zaXRpb246bn0pLHRoaXMucHJvcHMub25Qb3NpdGlvbkNoYW5nZSgobC1zLzIpL3QpfX0se2tleTpcImhhbmRsZU1vdXNlTW92ZUZvckhvcml6b250YWxcIix2YWx1ZTpmdW5jdGlvbihlKXt2YXIgdD10aGlzLmNvbXB1dGVNdWx0aXBsaWVyKCk7aWYodGhpcy5zdGF0ZS5pc0RyYWdnaW5nKXtlLnByZXZlbnREZWZhdWx0KCk7dmFyIG49dGhpcy5zdGF0ZS5sYXN0Q2xpZW50UG9zaXRpb24tZS5jbGllbnRYO3RoaXMuc2V0U3RhdGUoe2xhc3RDbGllbnRQb3NpdGlvbjplLmNsaWVudFh9KSx0aGlzLnByb3BzLm9uTW92ZSgwLG4vdCl9fX0se2tleTpcImhhbmRsZU1vdXNlTW92ZUZvclZlcnRpY2FsXCIsdmFsdWU6ZnVuY3Rpb24oZSl7dmFyIHQ9dGhpcy5jb21wdXRlTXVsdGlwbGllcigpO2lmKHRoaXMuc3RhdGUuaXNEcmFnZ2luZyl7ZS5wcmV2ZW50RGVmYXVsdCgpO3ZhciBuPXRoaXMuc3RhdGUubGFzdENsaWVudFBvc2l0aW9uLWUuY2xpZW50WTt0aGlzLnNldFN0YXRlKHtsYXN0Q2xpZW50UG9zaXRpb246ZS5jbGllbnRZfSksdGhpcy5wcm9wcy5vbk1vdmUobi90LDApfX19LHtrZXk6XCJoYW5kbGVNb3VzZURvd25cIix2YWx1ZTpmdW5jdGlvbihlKXtlLnByZXZlbnREZWZhdWx0KCksZS5zdG9wUHJvcGFnYXRpb24oKTt2YXIgdD10aGlzLmlzVmVydGljYWwoKT9lLmNsaWVudFk6ZS5jbGllbnRYO3RoaXMuc2V0U3RhdGUoe2lzRHJhZ2dpbmc6ITAsbGFzdENsaWVudFBvc2l0aW9uOnR9KSx0aGlzLnByb3BzLm9uRm9jdXMoKX19LHtrZXk6XCJoYW5kbGVNb3VzZVVwXCIsdmFsdWU6ZnVuY3Rpb24oZSl7dGhpcy5zdGF0ZS5pc0RyYWdnaW5nJiYoZS5wcmV2ZW50RGVmYXVsdCgpLHRoaXMuc2V0U3RhdGUoe2lzRHJhZ2dpbmc6ITF9KSl9fSx7a2V5OlwiY3JlYXRlU2Nyb2xsU3R5bGVzXCIsdmFsdWU6ZnVuY3Rpb24oKXtyZXR1cm5cInZlcnRpY2FsXCI9PT10aGlzLnByb3BzLnR5cGU/e2hlaWdodDp0aGlzLnN0YXRlLnNjcm9sbFNpemUsbWFyZ2luVG9wOnRoaXMuc3RhdGUucG9zaXRpb259Ont3aWR0aDp0aGlzLnN0YXRlLnNjcm9sbFNpemUsbWFyZ2luTGVmdDp0aGlzLnN0YXRlLnBvc2l0aW9ufX19LHtrZXk6XCJjb21wdXRlTXVsdGlwbGllclwiLHZhbHVlOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMucHJvcHMuY29udGFpbmVyU2l6ZS90aGlzLnByb3BzLnJlYWxTaXplfX0se2tleTpcImlzVmVydGljYWxcIix2YWx1ZTpmdW5jdGlvbigpe3JldHVyblwidmVydGljYWxcIj09PXRoaXMucHJvcHMudHlwZX19XSksdH0oYy5kZWZhdWx0LkNvbXBvbmVudCk7eS5wcm9wVHlwZXM9e29uTW92ZTpwLmRlZmF1bHQuZnVuYyxvblBvc2l0aW9uQ2hhbmdlOnAuZGVmYXVsdC5mdW5jLG9uRm9jdXM6cC5kZWZhdWx0LmZ1bmMscmVhbFNpemU6cC5kZWZhdWx0Lm51bWJlcixjb250YWluZXJTaXplOnAuZGVmYXVsdC5udW1iZXIscG9zaXRpb246cC5kZWZhdWx0Lm51bWJlcixjb250YWluZXJTdHlsZTpwLmRlZmF1bHQub2JqZWN0LHNjcm9sbGJhclN0eWxlOnAuZGVmYXVsdC5vYmplY3QsdHlwZTpwLmRlZmF1bHQub25lT2YoW1widmVydGljYWxcIixcImhvcml6b250YWxcIl0pLG93bmVyRG9jdW1lbnQ6cC5kZWZhdWx0LmFueSxzbW9vdGhTY3JvbGxpbmc6cC5kZWZhdWx0LmJvb2wsbWluU2Nyb2xsU2l6ZTpwLmRlZmF1bHQubnVtYmVyfSx5LmRlZmF1bHRQcm9wcz17dHlwZTpcInZlcnRpY2FsXCIsc21vb3RoU2Nyb2xsaW5nOiExfSx0LmRlZmF1bHQ9eX0sZnVuY3Rpb24oZSx0KXt2YXIgbj1mdW5jdGlvbihlLHQsbil7cmV0dXJuIG49d2luZG93LmdldENvbXB1dGVkU3R5bGUsKG4/bihlKTplLmN1cnJlbnRTdHlsZSlbdC5yZXBsYWNlKC8tKFxcdykvZ2ksZnVuY3Rpb24oZSx0KXtyZXR1cm4gdC50b1VwcGVyQ2FzZSgpfSldfTtlLmV4cG9ydHM9bn0sZnVuY3Rpb24oZSx0LG4pe3Q9ZS5leHBvcnRzPW4oMTcpKCksdC5wdXNoKFtlLmlkLFwiLnNjcm9sbGFyZWEtY29udGVudHttYXJnaW46MDtwYWRkaW5nOjA7b3ZlcmZsb3c6aGlkZGVuO3Bvc2l0aW9uOnJlbGF0aXZlfS5zY3JvbGxhcmVhLWNvbnRlbnQ6Zm9jdXN7b3V0bGluZTowfS5zY3JvbGxhcmVhe3Bvc2l0aW9uOnJlbGF0aXZlO292ZXJmbG93OmhpZGRlbn0uc2Nyb2xsYXJlYSAuc2Nyb2xsYmFyLWNvbnRhaW5lcntwb3NpdGlvbjphYnNvbHV0ZTtiYWNrZ3JvdW5kOm5vbmU7b3BhY2l0eTouMTt6LWluZGV4Ojk5OTk7LXdlYmtpdC10cmFuc2l0aW9uOmFsbCAuNHM7dHJhbnNpdGlvbjphbGwgLjRzfS5zY3JvbGxhcmVhIC5zY3JvbGxiYXItY29udGFpbmVyLmhvcml6b250YWx7d2lkdGg6MTAwJTtoZWlnaHQ6MTBweDtsZWZ0OjA7Ym90dG9tOjB9LnNjcm9sbGFyZWEgLnNjcm9sbGJhci1jb250YWluZXIuaG9yaXpvbnRhbCAuc2Nyb2xsYmFye3dpZHRoOjIwcHg7aGVpZ2h0OjhweDtiYWNrZ3JvdW5kOiMwMDA7bWFyZ2luLXRvcDoxcHh9LnNjcm9sbGFyZWEgLnNjcm9sbGJhci1jb250YWluZXIudmVydGljYWx7d2lkdGg6MTBweDtoZWlnaHQ6MTAwJTtyaWdodDowO3RvcDowfS5zY3JvbGxhcmVhIC5zY3JvbGxiYXItY29udGFpbmVyLnZlcnRpY2FsIC5zY3JvbGxiYXJ7d2lkdGg6OHB4O2hlaWdodDoyMHB4O2JhY2tncm91bmQ6IzAwMDttYXJnaW4tbGVmdDoxcHh9LnNjcm9sbGFyZWEgLnNjcm9sbGJhci1jb250YWluZXIuYWN0aXZlLC5zY3JvbGxhcmVhIC5zY3JvbGxiYXItY29udGFpbmVyOmhvdmVye2JhY2tncm91bmQ6Z3JheTtvcGFjaXR5Oi42IWltcG9ydGFudH0uc2Nyb2xsYXJlYTpob3ZlciAuc2Nyb2xsYmFyLWNvbnRhaW5lcntvcGFjaXR5Oi4zfVwiLFwiXCJdKX0sZnVuY3Rpb24oZSx0KXtlLmV4cG9ydHM9ZnVuY3Rpb24oKXt2YXIgZT1bXTtyZXR1cm4gZS50b1N0cmluZz1mdW5jdGlvbigpe2Zvcih2YXIgZT1bXSx0PTA7dDx0aGlzLmxlbmd0aDt0Kyspe3ZhciBuPXRoaXNbdF07blsyXT9lLnB1c2goXCJAbWVkaWEgXCIrblsyXStcIntcIituWzFdK1wifVwiKTplLnB1c2goblsxXSl9cmV0dXJuIGUuam9pbihcIlwiKX0sZS5pPWZ1bmN0aW9uKHQsbil7XCJzdHJpbmdcIj09dHlwZW9mIHQmJih0PVtbbnVsbCx0LFwiXCJdXSk7Zm9yKHZhciBvPXt9LHI9MDtyPHRoaXMubGVuZ3RoO3IrKyl7dmFyIGk9dGhpc1tyXVswXTtcIm51bWJlclwiPT10eXBlb2YgaSYmKG9baV09ITApfWZvcihyPTA7cjx0Lmxlbmd0aDtyKyspe3ZhciBhPXRbcl07XCJudW1iZXJcIj09dHlwZW9mIGFbMF0mJm9bYVswXV18fChuJiYhYVsyXT9hWzJdPW46biYmKGFbMl09XCIoXCIrYVsyXStcIikgYW5kIChcIituK1wiKVwiKSxlLnB1c2goYSkpfX0sZX19LGZ1bmN0aW9uKGUsdCxuKXtmdW5jdGlvbiBvKGUpe3ZhciB0PXIoZSxcImxpbmUtaGVpZ2h0XCIpLG49cGFyc2VGbG9hdCh0LDEwKTtpZih0PT09bitcIlwiKXt2YXIgbz1lLnN0eWxlLmxpbmVIZWlnaHQ7ZS5zdHlsZS5saW5lSGVpZ2h0PXQrXCJlbVwiLHQ9cihlLFwibGluZS1oZWlnaHRcIiksbj1wYXJzZUZsb2F0KHQsMTApLG8/ZS5zdHlsZS5saW5lSGVpZ2h0PW86ZGVsZXRlIGUuc3R5bGUubGluZUhlaWdodH1pZih0LmluZGV4T2YoXCJwdFwiKSE9PS0xPyhuKj00LG4vPTMpOnQuaW5kZXhPZihcIm1tXCIpIT09LTE/KG4qPTk2LG4vPTI1LjQpOnQuaW5kZXhPZihcImNtXCIpIT09LTE/KG4qPTk2LG4vPTIuNTQpOnQuaW5kZXhPZihcImluXCIpIT09LTE/bio9OTY6dC5pbmRleE9mKFwicGNcIikhPT0tMSYmKG4qPTE2KSxuPU1hdGgucm91bmQobiksXCJub3JtYWxcIj09PXQpe3ZhciBpPWUubm9kZU5hbWUsYT1kb2N1bWVudC5jcmVhdGVFbGVtZW50KGkpO2EuaW5uZXJIVE1MPVwiJm5ic3A7XCI7dmFyIGw9cihlLFwiZm9udC1zaXplXCIpO2Euc3R5bGUuZm9udFNpemU9bDt2YXIgcz1kb2N1bWVudC5ib2R5O3MuYXBwZW5kQ2hpbGQoYSk7dmFyIHU9YS5vZmZzZXRIZWlnaHQ7bj11LHMucmVtb3ZlQ2hpbGQoYSl9cmV0dXJuIG59dmFyIHI9bigxNSk7ZS5leHBvcnRzPW99LGZ1bmN0aW9uKGUsdCxuKXtcInVzZSBzdHJpY3RcIjt2YXIgbz1uKDIxKSxyPW4oMjIpLGk9bigyMCk7ZS5leHBvcnRzPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gZShlLHQsbixvLGEsbCl7bCE9PWkmJnIoITEsXCJDYWxsaW5nIFByb3BUeXBlcyB2YWxpZGF0b3JzIGRpcmVjdGx5IGlzIG5vdCBzdXBwb3J0ZWQgYnkgdGhlIGBwcm9wLXR5cGVzYCBwYWNrYWdlLiBVc2UgUHJvcFR5cGVzLmNoZWNrUHJvcFR5cGVzKCkgdG8gY2FsbCB0aGVtLiBSZWFkIG1vcmUgYXQgaHR0cDovL2ZiLm1lL3VzZS1jaGVjay1wcm9wLXR5cGVzXCIpfWZ1bmN0aW9uIHQoKXtyZXR1cm4gZX1lLmlzUmVxdWlyZWQ9ZTt2YXIgbj17YXJyYXk6ZSxib29sOmUsZnVuYzplLG51bWJlcjplLG9iamVjdDplLHN0cmluZzplLHN5bWJvbDplLGFueTplLGFycmF5T2Y6dCxlbGVtZW50OmUsaW5zdGFuY2VPZjp0LG5vZGU6ZSxvYmplY3RPZjp0LG9uZU9mOnQsb25lT2ZUeXBlOnQsc2hhcGU6dCxleGFjdDp0fTtyZXR1cm4gbi5jaGVja1Byb3BUeXBlcz1vLG4uUHJvcFR5cGVzPW4sbn19LGZ1bmN0aW9uKGUsdCl7XCJ1c2Ugc3RyaWN0XCI7dmFyIG49XCJTRUNSRVRfRE9fTk9UX1BBU1NfVEhJU19PUl9ZT1VfV0lMTF9CRV9GSVJFRFwiO2UuZXhwb3J0cz1ufSxmdW5jdGlvbihlLHQpe1widXNlIHN0cmljdFwiO2Z1bmN0aW9uIG4oZSl7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIGV9fXZhciBvPWZ1bmN0aW9uKCl7fTtvLnRoYXRSZXR1cm5zPW4sby50aGF0UmV0dXJuc0ZhbHNlPW4oITEpLG8udGhhdFJldHVybnNUcnVlPW4oITApLG8udGhhdFJldHVybnNOdWxsPW4obnVsbCksby50aGF0UmV0dXJuc1RoaXM9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpc30sby50aGF0UmV0dXJuc0FyZ3VtZW50PWZ1bmN0aW9uKGUpe3JldHVybiBlfSxlLmV4cG9ydHM9b30sZnVuY3Rpb24oZSx0LG4pe1widXNlIHN0cmljdFwiO2Z1bmN0aW9uIG8oZSx0LG4sbyxpLGEsbCxzKXtpZihyKHQpLCFlKXt2YXIgdTtpZih2b2lkIDA9PT10KXU9bmV3IEVycm9yKFwiTWluaWZpZWQgZXhjZXB0aW9uIG9jY3VycmVkOyB1c2UgdGhlIG5vbi1taW5pZmllZCBkZXYgZW52aXJvbm1lbnQgZm9yIHRoZSBmdWxsIGVycm9yIG1lc3NhZ2UgYW5kIGFkZGl0aW9uYWwgaGVscGZ1bCB3YXJuaW5ncy5cIik7ZWxzZXt2YXIgYz1bbixvLGksYSxsLHNdLGY9MDt1PW5ldyBFcnJvcih0LnJlcGxhY2UoLyVzL2csZnVuY3Rpb24oKXtyZXR1cm4gY1tmKytdfSkpLHUubmFtZT1cIkludmFyaWFudCBWaW9sYXRpb25cIn10aHJvdyB1LmZyYW1lc1RvUG9wPTEsdX19dmFyIHI9ZnVuY3Rpb24oZSl7fTtlLmV4cG9ydHM9b30sZnVuY3Rpb24oZSx0LG4peyhmdW5jdGlvbih0KXsoZnVuY3Rpb24oKXt2YXIgbixvLHIsaSxhLGw7XCJ1bmRlZmluZWRcIiE9dHlwZW9mIHBlcmZvcm1hbmNlJiZudWxsIT09cGVyZm9ybWFuY2UmJnBlcmZvcm1hbmNlLm5vdz9lLmV4cG9ydHM9ZnVuY3Rpb24oKXtyZXR1cm4gcGVyZm9ybWFuY2Uubm93KCl9OlwidW5kZWZpbmVkXCIhPXR5cGVvZiB0JiZudWxsIT09dCYmdC5ocnRpbWU/KGUuZXhwb3J0cz1mdW5jdGlvbigpe3JldHVybihuKCktYSkvMWU2fSxvPXQuaHJ0aW1lLG49ZnVuY3Rpb24oKXt2YXIgZTtyZXR1cm4gZT1vKCksMWU5KmVbMF0rZVsxXX0saT1uKCksbD0xZTkqdC51cHRpbWUoKSxhPWktbCk6RGF0ZS5ub3c/KGUuZXhwb3J0cz1mdW5jdGlvbigpe3JldHVybiBEYXRlLm5vdygpLXJ9LHI9RGF0ZS5ub3coKSk6KGUuZXhwb3J0cz1mdW5jdGlvbigpe3JldHVybihuZXcgRGF0ZSkuZ2V0VGltZSgpLXJ9LHI9KG5ldyBEYXRlKS5nZXRUaW1lKCkpfSkuY2FsbCh0aGlzKX0pLmNhbGwodCxuKDEwKSl9LGZ1bmN0aW9uKGUsdCxuKXtcInVzZSBzdHJpY3RcIjtmdW5jdGlvbiBvKGUpe3JldHVybiBlJiZlLl9fZXNNb2R1bGU/ZTp7ZGVmYXVsdDplfX1mdW5jdGlvbiByKGUsdCl7aWYoIShlIGluc3RhbmNlb2YgdCkpdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvblwiKX1mdW5jdGlvbiBpKGUsdCl7aWYoXCJmdW5jdGlvblwiIT10eXBlb2YgdCYmbnVsbCE9PXQpdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uLCBub3QgXCIrdHlwZW9mIHQpO2UucHJvdG90eXBlPU9iamVjdC5jcmVhdGUodCYmdC5wcm90b3R5cGUse2NvbnN0cnVjdG9yOnt2YWx1ZTplLGVudW1lcmFibGU6ITEsd3JpdGFibGU6ITAsY29uZmlndXJhYmxlOiEwfX0pLHQmJihPYmplY3Quc2V0UHJvdG90eXBlT2Y/T2JqZWN0LnNldFByb3RvdHlwZU9mKGUsdCk6ZS5fX3Byb3RvX189dCl9dC5fX2VzTW9kdWxlPSEwO3ZhciBhPU9iamVjdC5hc3NpZ258fGZ1bmN0aW9uKGUpe2Zvcih2YXIgdD0xO3Q8YXJndW1lbnRzLmxlbmd0aDt0Kyspe3ZhciBuPWFyZ3VtZW50c1t0XTtmb3IodmFyIG8gaW4gbilPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobixvKSYmKGVbb109bltvXSl9cmV0dXJuIGV9LGw9ZnVuY3Rpb24oKXtmdW5jdGlvbiBlKGUsdCl7Zm9yKHZhciBuPTA7bjx0Lmxlbmd0aDtuKyspe3ZhciBvPXRbbl07by5lbnVtZXJhYmxlPW8uZW51bWVyYWJsZXx8ITEsby5jb25maWd1cmFibGU9ITAsXCJ2YWx1ZVwiaW4gbyYmKG8ud3JpdGFibGU9ITApLE9iamVjdC5kZWZpbmVQcm9wZXJ0eShlLG8ua2V5LG8pfX1yZXR1cm4gZnVuY3Rpb24odCxuLG8pe3JldHVybiBuJiZlKHQucHJvdG90eXBlLG4pLG8mJmUodCxvKSx0fX0oKSxzPW4oNiksdT1vKHMpLGM9bigzKSxmPW8oYykscD1uKDgpLGQ9byhwKSxoPW4oNCkseT1vKGgpLHY9big1KSxtPW8odiksYj1uKDcpLFM9byhiKSxnPW4oMSksdz1vKGcpLFA9bigyKSxUPW8oUCksaz0xZTMvNjAsTz1mdW5jdGlvbihlKXtmdW5jdGlvbiB0KG4pe3ZhciBvPXRoaXM7cih0aGlzLHQpLGUuY2FsbCh0aGlzLG4pLHRoaXMud2FzQW5pbWF0aW5nPSExLHRoaXMuYW5pbWF0aW9uSUQ9bnVsbCx0aGlzLnByZXZUaW1lPTAsdGhpcy5hY2N1bXVsYXRlZFRpbWU9MCx0aGlzLnVucmVhZFByb3BTdHlsZT1udWxsLHRoaXMuY2xlYXJVbnJlYWRQcm9wU3R5bGU9ZnVuY3Rpb24oZSl7dmFyIHQ9ITEsbj1vLnN0YXRlLHI9bi5jdXJyZW50U3R5bGUsaT1uLmN1cnJlbnRWZWxvY2l0eSxsPW4ubGFzdElkZWFsU3R5bGUscz1uLmxhc3RJZGVhbFZlbG9jaXR5O2Zvcih2YXIgdSBpbiBlKWlmKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChlLHUpKXt2YXIgYz1lW3VdO1wibnVtYmVyXCI9PXR5cGVvZiBjJiYodHx8KHQ9ITAscj1hKHt9LHIpLGk9YSh7fSxpKSxsPWEoe30sbCkscz1hKHt9LHMpKSxyW3VdPWMsaVt1XT0wLGxbdV09YyxzW3VdPTApfXQmJm8uc2V0U3RhdGUoe2N1cnJlbnRTdHlsZTpyLGN1cnJlbnRWZWxvY2l0eTppLGxhc3RJZGVhbFN0eWxlOmwsbGFzdElkZWFsVmVsb2NpdHk6c30pfSx0aGlzLnN0YXJ0QW5pbWF0aW9uSWZOZWNlc3Nhcnk9ZnVuY3Rpb24oKXtvLmFuaW1hdGlvbklEPW0uZGVmYXVsdChmdW5jdGlvbihlKXt2YXIgdD1vLnByb3BzLnN0eWxlO2lmKFMuZGVmYXVsdChvLnN0YXRlLmN1cnJlbnRTdHlsZSx0LG8uc3RhdGUuY3VycmVudFZlbG9jaXR5KSlyZXR1cm4gby53YXNBbmltYXRpbmcmJm8ucHJvcHMub25SZXN0JiZvLnByb3BzLm9uUmVzdCgpLG8uYW5pbWF0aW9uSUQ9bnVsbCxvLndhc0FuaW1hdGluZz0hMSx2b2lkKG8uYWNjdW11bGF0ZWRUaW1lPTApO28ud2FzQW5pbWF0aW5nPSEwO3ZhciBuPWV8fHkuZGVmYXVsdCgpLHI9bi1vLnByZXZUaW1lO2lmKG8ucHJldlRpbWU9bixvLmFjY3VtdWxhdGVkVGltZT1vLmFjY3VtdWxhdGVkVGltZStyLG8uYWNjdW11bGF0ZWRUaW1lPjEwKmsmJihvLmFjY3VtdWxhdGVkVGltZT0wKSwwPT09by5hY2N1bXVsYXRlZFRpbWUpcmV0dXJuIG8uYW5pbWF0aW9uSUQ9bnVsbCx2b2lkIG8uc3RhcnRBbmltYXRpb25JZk5lY2Vzc2FyeSgpO3ZhciBpPShvLmFjY3VtdWxhdGVkVGltZS1NYXRoLmZsb29yKG8uYWNjdW11bGF0ZWRUaW1lL2spKmspL2ssYT1NYXRoLmZsb29yKG8uYWNjdW11bGF0ZWRUaW1lL2spLGw9e30scz17fSx1PXt9LGM9e307Zm9yKHZhciBmIGluIHQpaWYoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHQsZikpe3ZhciBwPXRbZl07aWYoXCJudW1iZXJcIj09dHlwZW9mIHApdVtmXT1wLGNbZl09MCxsW2ZdPXAsc1tmXT0wO2Vsc2V7Zm9yKHZhciBoPW8uc3RhdGUubGFzdElkZWFsU3R5bGVbZl0sdj1vLnN0YXRlLmxhc3RJZGVhbFZlbG9jaXR5W2ZdLG09MDttPGE7bSsrKXt2YXIgYj1kLmRlZmF1bHQoay8xZTMsaCx2LHAudmFsLHAuc3RpZmZuZXNzLHAuZGFtcGluZyxwLnByZWNpc2lvbik7aD1iWzBdLHY9YlsxXX12YXIgZz1kLmRlZmF1bHQoay8xZTMsaCx2LHAudmFsLHAuc3RpZmZuZXNzLHAuZGFtcGluZyxwLnByZWNpc2lvbiksdz1nWzBdLFA9Z1sxXTt1W2ZdPWgrKHctaCkqaSxjW2ZdPXYrKFAtdikqaSxsW2ZdPWgsc1tmXT12fX1vLmFuaW1hdGlvbklEPW51bGwsby5hY2N1bXVsYXRlZFRpbWUtPWEqayxvLnNldFN0YXRlKHtjdXJyZW50U3R5bGU6dSxjdXJyZW50VmVsb2NpdHk6YyxsYXN0SWRlYWxTdHlsZTpsLGxhc3RJZGVhbFZlbG9jaXR5OnN9KSxvLnVucmVhZFByb3BTdHlsZT1udWxsLG8uc3RhcnRBbmltYXRpb25JZk5lY2Vzc2FyeSgpfSl9LHRoaXMuc3RhdGU9dGhpcy5kZWZhdWx0U3RhdGUoKX1yZXR1cm4gaSh0LGUpLGwodCxudWxsLFt7a2V5OlwicHJvcFR5cGVzXCIsdmFsdWU6e2RlZmF1bHRTdHlsZTpULmRlZmF1bHQub2JqZWN0T2YoVC5kZWZhdWx0Lm51bWJlciksc3R5bGU6VC5kZWZhdWx0Lm9iamVjdE9mKFQuZGVmYXVsdC5vbmVPZlR5cGUoW1QuZGVmYXVsdC5udW1iZXIsVC5kZWZhdWx0Lm9iamVjdF0pKS5pc1JlcXVpcmVkLGNoaWxkcmVuOlQuZGVmYXVsdC5mdW5jLmlzUmVxdWlyZWQsb25SZXN0OlQuZGVmYXVsdC5mdW5jfSxlbnVtZXJhYmxlOiEwfV0pLHQucHJvdG90eXBlLmRlZmF1bHRTdGF0ZT1mdW5jdGlvbigpe3ZhciBlPXRoaXMucHJvcHMsdD1lLmRlZmF1bHRTdHlsZSxuPWUuc3R5bGUsbz10fHxmLmRlZmF1bHQobikscj11LmRlZmF1bHQobyk7cmV0dXJue2N1cnJlbnRTdHlsZTpvLGN1cnJlbnRWZWxvY2l0eTpyLGxhc3RJZGVhbFN0eWxlOm8sbGFzdElkZWFsVmVsb2NpdHk6cn19LHQucHJvdG90eXBlLmNvbXBvbmVudERpZE1vdW50PWZ1bmN0aW9uKCl7dGhpcy5wcmV2VGltZT15LmRlZmF1bHQoKSx0aGlzLnN0YXJ0QW5pbWF0aW9uSWZOZWNlc3NhcnkoKX0sdC5wcm90b3R5cGUuY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcz1mdW5jdGlvbihlKXtudWxsIT10aGlzLnVucmVhZFByb3BTdHlsZSYmdGhpcy5jbGVhclVucmVhZFByb3BTdHlsZSh0aGlzLnVucmVhZFByb3BTdHlsZSksdGhpcy51bnJlYWRQcm9wU3R5bGU9ZS5zdHlsZSxudWxsPT10aGlzLmFuaW1hdGlvbklEJiYodGhpcy5wcmV2VGltZT15LmRlZmF1bHQoKSx0aGlzLnN0YXJ0QW5pbWF0aW9uSWZOZWNlc3NhcnkoKSl9LHQucHJvdG90eXBlLmNvbXBvbmVudFdpbGxVbm1vdW50PWZ1bmN0aW9uKCl7bnVsbCE9dGhpcy5hbmltYXRpb25JRCYmKG0uZGVmYXVsdC5jYW5jZWwodGhpcy5hbmltYXRpb25JRCksdGhpcy5hbmltYXRpb25JRD1udWxsKX0sdC5wcm90b3R5cGUucmVuZGVyPWZ1bmN0aW9uKCl7dmFyIGU9dGhpcy5wcm9wcy5jaGlsZHJlbih0aGlzLnN0YXRlLmN1cnJlbnRTdHlsZSk7cmV0dXJuIGUmJncuZGVmYXVsdC5DaGlsZHJlbi5vbmx5KGUpfSx0fSh3LmRlZmF1bHQuQ29tcG9uZW50KTt0LmRlZmF1bHQ9TyxlLmV4cG9ydHM9dC5kZWZhdWx0fSxmdW5jdGlvbihlLHQsbil7XCJ1c2Ugc3RyaWN0XCI7ZnVuY3Rpb24gbyhlKXtyZXR1cm4gZSYmZS5fX2VzTW9kdWxlP2U6e2RlZmF1bHQ6ZX19ZnVuY3Rpb24gcihlLHQpe2lmKCEoZSBpbnN0YW5jZW9mIHQpKXRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIil9ZnVuY3Rpb24gaShlLHQpe2lmKFwiZnVuY3Rpb25cIiE9dHlwZW9mIHQmJm51bGwhPT10KXRocm93IG5ldyBUeXBlRXJyb3IoXCJTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90IFwiK3R5cGVvZiB0KTtlLnByb3RvdHlwZT1PYmplY3QuY3JlYXRlKHQmJnQucHJvdG90eXBlLHtjb25zdHJ1Y3Rvcjp7dmFsdWU6ZSxlbnVtZXJhYmxlOiExLHdyaXRhYmxlOiEwLGNvbmZpZ3VyYWJsZTohMH19KSx0JiYoT2JqZWN0LnNldFByb3RvdHlwZU9mP09iamVjdC5zZXRQcm90b3R5cGVPZihlLHQpOmUuX19wcm90b19fPXQpfWZ1bmN0aW9uIGEoZSx0LG4pe2Zvcih2YXIgbz0wO288ZS5sZW5ndGg7bysrKWlmKCFnLmRlZmF1bHQoZVtvXSx0W29dLG5bb10pKXJldHVybiExO3JldHVybiEwfXQuX19lc01vZHVsZT0hMDt2YXIgbD1PYmplY3QuYXNzaWdufHxmdW5jdGlvbihlKXtmb3IodmFyIHQ9MTt0PGFyZ3VtZW50cy5sZW5ndGg7dCsrKXt2YXIgbj1hcmd1bWVudHNbdF07Zm9yKHZhciBvIGluIG4pT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG4sbykmJihlW29dPW5bb10pfXJldHVybiBlfSxzPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gZShlLHQpe2Zvcih2YXIgbj0wO248dC5sZW5ndGg7bisrKXt2YXIgbz10W25dO28uZW51bWVyYWJsZT1vLmVudW1lcmFibGV8fCExLG8uY29uZmlndXJhYmxlPSEwLFwidmFsdWVcImluIG8mJihvLndyaXRhYmxlPSEwKSxPYmplY3QuZGVmaW5lUHJvcGVydHkoZSxvLmtleSxvKX19cmV0dXJuIGZ1bmN0aW9uKHQsbixvKXtyZXR1cm4gbiYmZSh0LnByb3RvdHlwZSxuKSxvJiZlKHQsbyksdH19KCksdT1uKDYpLGM9byh1KSxmPW4oMykscD1vKGYpLGQ9big4KSxoPW8oZCkseT1uKDQpLHY9byh5KSxtPW4oNSksYj1vKG0pLFM9big3KSxnPW8oUyksdz1uKDEpLFA9byh3KSxUPW4oMiksaz1vKFQpLE89MWUzLzYwLE09ZnVuY3Rpb24oZSl7ZnVuY3Rpb24gdChuKXt2YXIgbz10aGlzO3IodGhpcyx0KSxlLmNhbGwodGhpcyxuKSx0aGlzLmFuaW1hdGlvbklEPW51bGwsdGhpcy5wcmV2VGltZT0wLHRoaXMuYWNjdW11bGF0ZWRUaW1lPTAsdGhpcy51bnJlYWRQcm9wU3R5bGVzPW51bGwsdGhpcy5jbGVhclVucmVhZFByb3BTdHlsZT1mdW5jdGlvbihlKXtmb3IodmFyIHQ9by5zdGF0ZSxuPXQuY3VycmVudFN0eWxlcyxyPXQuY3VycmVudFZlbG9jaXRpZXMsaT10Lmxhc3RJZGVhbFN0eWxlcyxhPXQubGFzdElkZWFsVmVsb2NpdGllcyxzPSExLHU9MDt1PGUubGVuZ3RoO3UrKyl7dmFyIGM9ZVt1XSxmPSExO2Zvcih2YXIgcCBpbiBjKWlmKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChjLHApKXt2YXIgZD1jW3BdO1wibnVtYmVyXCI9PXR5cGVvZiBkJiYoZnx8KGY9ITAscz0hMCxuW3VdPWwoe30sblt1XSksclt1XT1sKHt9LHJbdV0pLGlbdV09bCh7fSxpW3VdKSxhW3VdPWwoe30sYVt1XSkpLG5bdV1bcF09ZCxyW3VdW3BdPTAsaVt1XVtwXT1kLGFbdV1bcF09MCl9fXMmJm8uc2V0U3RhdGUoe2N1cnJlbnRTdHlsZXM6bixjdXJyZW50VmVsb2NpdGllczpyLGxhc3RJZGVhbFN0eWxlczppLGxhc3RJZGVhbFZlbG9jaXRpZXM6YX0pfSx0aGlzLnN0YXJ0QW5pbWF0aW9uSWZOZWNlc3Nhcnk9ZnVuY3Rpb24oKXtvLmFuaW1hdGlvbklEPWIuZGVmYXVsdChmdW5jdGlvbihlKXtcbnZhciB0PW8ucHJvcHMuc3R5bGVzKG8uc3RhdGUubGFzdElkZWFsU3R5bGVzKTtpZihhKG8uc3RhdGUuY3VycmVudFN0eWxlcyx0LG8uc3RhdGUuY3VycmVudFZlbG9jaXRpZXMpKXJldHVybiBvLmFuaW1hdGlvbklEPW51bGwsdm9pZChvLmFjY3VtdWxhdGVkVGltZT0wKTt2YXIgbj1lfHx2LmRlZmF1bHQoKSxyPW4tby5wcmV2VGltZTtpZihvLnByZXZUaW1lPW4sby5hY2N1bXVsYXRlZFRpbWU9by5hY2N1bXVsYXRlZFRpbWUrcixvLmFjY3VtdWxhdGVkVGltZT4xMCpPJiYoby5hY2N1bXVsYXRlZFRpbWU9MCksMD09PW8uYWNjdW11bGF0ZWRUaW1lKXJldHVybiBvLmFuaW1hdGlvbklEPW51bGwsdm9pZCBvLnN0YXJ0QW5pbWF0aW9uSWZOZWNlc3NhcnkoKTtmb3IodmFyIGk9KG8uYWNjdW11bGF0ZWRUaW1lLU1hdGguZmxvb3Ioby5hY2N1bXVsYXRlZFRpbWUvTykqTykvTyxsPU1hdGguZmxvb3Ioby5hY2N1bXVsYXRlZFRpbWUvTykscz1bXSx1PVtdLGM9W10sZj1bXSxwPTA7cDx0Lmxlbmd0aDtwKyspe3ZhciBkPXRbcF0seT17fSxtPXt9LGI9e30sUz17fTtmb3IodmFyIGcgaW4gZClpZihPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoZCxnKSl7dmFyIHc9ZFtnXTtpZihcIm51bWJlclwiPT10eXBlb2Ygdyl5W2ddPXcsbVtnXT0wLGJbZ109dyxTW2ddPTA7ZWxzZXtmb3IodmFyIFA9by5zdGF0ZS5sYXN0SWRlYWxTdHlsZXNbcF1bZ10sVD1vLnN0YXRlLmxhc3RJZGVhbFZlbG9jaXRpZXNbcF1bZ10saz0wO2s8bDtrKyspe3ZhciBNPWguZGVmYXVsdChPLzFlMyxQLFQsdy52YWwsdy5zdGlmZm5lc3Msdy5kYW1waW5nLHcucHJlY2lzaW9uKTtQPU1bMF0sVD1NWzFdfXZhciB4PWguZGVmYXVsdChPLzFlMyxQLFQsdy52YWwsdy5zdGlmZm5lc3Msdy5kYW1waW5nLHcucHJlY2lzaW9uKSxJPXhbMF0sRD14WzFdO3lbZ109UCsoSS1QKSppLG1bZ109VCsoRC1UKSppLGJbZ109UCxTW2ddPVR9fWNbcF09eSxmW3BdPW0sc1twXT1iLHVbcF09U31vLmFuaW1hdGlvbklEPW51bGwsby5hY2N1bXVsYXRlZFRpbWUtPWwqTyxvLnNldFN0YXRlKHtjdXJyZW50U3R5bGVzOmMsY3VycmVudFZlbG9jaXRpZXM6ZixsYXN0SWRlYWxTdHlsZXM6cyxsYXN0SWRlYWxWZWxvY2l0aWVzOnV9KSxvLnVucmVhZFByb3BTdHlsZXM9bnVsbCxvLnN0YXJ0QW5pbWF0aW9uSWZOZWNlc3NhcnkoKX0pfSx0aGlzLnN0YXRlPXRoaXMuZGVmYXVsdFN0YXRlKCl9cmV0dXJuIGkodCxlKSxzKHQsbnVsbCxbe2tleTpcInByb3BUeXBlc1wiLHZhbHVlOntkZWZhdWx0U3R5bGVzOmsuZGVmYXVsdC5hcnJheU9mKGsuZGVmYXVsdC5vYmplY3RPZihrLmRlZmF1bHQubnVtYmVyKSksc3R5bGVzOmsuZGVmYXVsdC5mdW5jLmlzUmVxdWlyZWQsY2hpbGRyZW46ay5kZWZhdWx0LmZ1bmMuaXNSZXF1aXJlZH0sZW51bWVyYWJsZTohMH1dKSx0LnByb3RvdHlwZS5kZWZhdWx0U3RhdGU9ZnVuY3Rpb24oKXt2YXIgZT10aGlzLnByb3BzLHQ9ZS5kZWZhdWx0U3R5bGVzLG49ZS5zdHlsZXMsbz10fHxuKCkubWFwKHAuZGVmYXVsdCkscj1vLm1hcChmdW5jdGlvbihlKXtyZXR1cm4gYy5kZWZhdWx0KGUpfSk7cmV0dXJue2N1cnJlbnRTdHlsZXM6byxjdXJyZW50VmVsb2NpdGllczpyLGxhc3RJZGVhbFN0eWxlczpvLGxhc3RJZGVhbFZlbG9jaXRpZXM6cn19LHQucHJvdG90eXBlLmNvbXBvbmVudERpZE1vdW50PWZ1bmN0aW9uKCl7dGhpcy5wcmV2VGltZT12LmRlZmF1bHQoKSx0aGlzLnN0YXJ0QW5pbWF0aW9uSWZOZWNlc3NhcnkoKX0sdC5wcm90b3R5cGUuY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcz1mdW5jdGlvbihlKXtudWxsIT10aGlzLnVucmVhZFByb3BTdHlsZXMmJnRoaXMuY2xlYXJVbnJlYWRQcm9wU3R5bGUodGhpcy51bnJlYWRQcm9wU3R5bGVzKSx0aGlzLnVucmVhZFByb3BTdHlsZXM9ZS5zdHlsZXModGhpcy5zdGF0ZS5sYXN0SWRlYWxTdHlsZXMpLG51bGw9PXRoaXMuYW5pbWF0aW9uSUQmJih0aGlzLnByZXZUaW1lPXYuZGVmYXVsdCgpLHRoaXMuc3RhcnRBbmltYXRpb25JZk5lY2Vzc2FyeSgpKX0sdC5wcm90b3R5cGUuY29tcG9uZW50V2lsbFVubW91bnQ9ZnVuY3Rpb24oKXtudWxsIT10aGlzLmFuaW1hdGlvbklEJiYoYi5kZWZhdWx0LmNhbmNlbCh0aGlzLmFuaW1hdGlvbklEKSx0aGlzLmFuaW1hdGlvbklEPW51bGwpfSx0LnByb3RvdHlwZS5yZW5kZXI9ZnVuY3Rpb24oKXt2YXIgZT10aGlzLnByb3BzLmNoaWxkcmVuKHRoaXMuc3RhdGUuY3VycmVudFN0eWxlcyk7cmV0dXJuIGUmJlAuZGVmYXVsdC5DaGlsZHJlbi5vbmx5KGUpfSx0fShQLmRlZmF1bHQuQ29tcG9uZW50KTt0LmRlZmF1bHQ9TSxlLmV4cG9ydHM9dC5kZWZhdWx0fSxmdW5jdGlvbihlLHQsbil7XCJ1c2Ugc3RyaWN0XCI7ZnVuY3Rpb24gbyhlKXtyZXR1cm4gZSYmZS5fX2VzTW9kdWxlP2U6e2RlZmF1bHQ6ZX19ZnVuY3Rpb24gcihlLHQpe2lmKCEoZSBpbnN0YW5jZW9mIHQpKXRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIil9ZnVuY3Rpb24gaShlLHQpe2lmKFwiZnVuY3Rpb25cIiE9dHlwZW9mIHQmJm51bGwhPT10KXRocm93IG5ldyBUeXBlRXJyb3IoXCJTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90IFwiK3R5cGVvZiB0KTtlLnByb3RvdHlwZT1PYmplY3QuY3JlYXRlKHQmJnQucHJvdG90eXBlLHtjb25zdHJ1Y3Rvcjp7dmFsdWU6ZSxlbnVtZXJhYmxlOiExLHdyaXRhYmxlOiEwLGNvbmZpZ3VyYWJsZTohMH19KSx0JiYoT2JqZWN0LnNldFByb3RvdHlwZU9mP09iamVjdC5zZXRQcm90b3R5cGVPZihlLHQpOmUuX19wcm90b19fPXQpfWZ1bmN0aW9uIGEoZSx0LG4pe3ZhciBvPXQ7cmV0dXJuIG51bGw9PW8/ZS5tYXAoZnVuY3Rpb24oZSx0KXtyZXR1cm57a2V5OmUua2V5LGRhdGE6ZS5kYXRhLHN0eWxlOm5bdF19fSk6ZS5tYXAoZnVuY3Rpb24oZSx0KXtmb3IodmFyIHI9MDtyPG8ubGVuZ3RoO3IrKylpZihvW3JdLmtleT09PWUua2V5KXJldHVybntrZXk6b1tyXS5rZXksZGF0YTpvW3JdLmRhdGEsc3R5bGU6blt0XX07cmV0dXJue2tleTplLmtleSxkYXRhOmUuZGF0YSxzdHlsZTpuW3RdfX0pfWZ1bmN0aW9uIGwoZSx0LG4sbyl7aWYoby5sZW5ndGghPT10Lmxlbmd0aClyZXR1cm4hMTtmb3IodmFyIHI9MDtyPG8ubGVuZ3RoO3IrKylpZihvW3JdLmtleSE9PXRbcl0ua2V5KXJldHVybiExO2Zvcih2YXIgcj0wO3I8by5sZW5ndGg7cisrKWlmKCFrLmRlZmF1bHQoZVtyXSx0W3JdLnN0eWxlLG5bcl0pKXJldHVybiExO3JldHVybiEwfWZ1bmN0aW9uIHMoZSx0LG4sbyxyLGksYSxsLHMpe2Zvcih2YXIgdT1iLmRlZmF1bHQobyxyLGZ1bmN0aW9uKGUsbyl7dmFyIHI9dChvKTtyZXR1cm4gbnVsbD09cj8obih7a2V5Om8ua2V5LGRhdGE6by5kYXRhfSksbnVsbCk6ay5kZWZhdWx0KGlbZV0scixhW2VdKT8obih7a2V5Om8ua2V5LGRhdGE6by5kYXRhfSksbnVsbCk6e2tleTpvLmtleSxkYXRhOm8uZGF0YSxzdHlsZTpyfX0pLGM9W10sZj1bXSxkPVtdLGg9W10seT0wO3k8dS5sZW5ndGg7eSsrKXtmb3IodmFyIHY9dVt5XSxtPW51bGwsUz0wO1M8by5sZW5ndGg7UysrKWlmKG9bU10ua2V5PT09di5rZXkpe209UzticmVha31pZihudWxsPT1tKXt2YXIgZz1lKHYpO2NbeV09ZyxkW3ldPWc7dmFyIHc9cC5kZWZhdWx0KHYuc3R5bGUpO2ZbeV09dyxoW3ldPXd9ZWxzZSBjW3ldPWlbbV0sZFt5XT1sW21dLGZbeV09YVttXSxoW3ldPXNbbV19cmV0dXJuW3UsYyxmLGQsaF19dC5fX2VzTW9kdWxlPSEwO3ZhciB1PU9iamVjdC5hc3NpZ258fGZ1bmN0aW9uKGUpe2Zvcih2YXIgdD0xO3Q8YXJndW1lbnRzLmxlbmd0aDt0Kyspe3ZhciBuPWFyZ3VtZW50c1t0XTtmb3IodmFyIG8gaW4gbilPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobixvKSYmKGVbb109bltvXSl9cmV0dXJuIGV9LGM9ZnVuY3Rpb24oKXtmdW5jdGlvbiBlKGUsdCl7Zm9yKHZhciBuPTA7bjx0Lmxlbmd0aDtuKyspe3ZhciBvPXRbbl07by5lbnVtZXJhYmxlPW8uZW51bWVyYWJsZXx8ITEsby5jb25maWd1cmFibGU9ITAsXCJ2YWx1ZVwiaW4gbyYmKG8ud3JpdGFibGU9ITApLE9iamVjdC5kZWZpbmVQcm9wZXJ0eShlLG8ua2V5LG8pfX1yZXR1cm4gZnVuY3Rpb24odCxuLG8pe3JldHVybiBuJiZlKHQucHJvdG90eXBlLG4pLG8mJmUodCxvKSx0fX0oKSxmPW4oNikscD1vKGYpLGQ9bigzKSxoPW8oZCkseT1uKDgpLHY9byh5KSxtPW4oMjcpLGI9byhtKSxTPW4oNCksZz1vKFMpLHc9big1KSxQPW8odyksVD1uKDcpLGs9byhUKSxPPW4oMSksTT1vKE8pLHg9bigyKSxJPW8oeCksRD0xZTMvNjAsXz1mdW5jdGlvbihlKXtmdW5jdGlvbiB0KG4pe3ZhciBvPXRoaXM7cih0aGlzLHQpLGUuY2FsbCh0aGlzLG4pLHRoaXMudW5tb3VudGluZz0hMSx0aGlzLmFuaW1hdGlvbklEPW51bGwsdGhpcy5wcmV2VGltZT0wLHRoaXMuYWNjdW11bGF0ZWRUaW1lPTAsdGhpcy51bnJlYWRQcm9wU3R5bGVzPW51bGwsdGhpcy5jbGVhclVucmVhZFByb3BTdHlsZT1mdW5jdGlvbihlKXtmb3IodmFyIHQ9cyhvLnByb3BzLndpbGxFbnRlcixvLnByb3BzLndpbGxMZWF2ZSxvLnByb3BzLmRpZExlYXZlLG8uc3RhdGUubWVyZ2VkUHJvcHNTdHlsZXMsZSxvLnN0YXRlLmN1cnJlbnRTdHlsZXMsby5zdGF0ZS5jdXJyZW50VmVsb2NpdGllcyxvLnN0YXRlLmxhc3RJZGVhbFN0eWxlcyxvLnN0YXRlLmxhc3RJZGVhbFZlbG9jaXRpZXMpLG49dFswXSxyPXRbMV0saT10WzJdLGE9dFszXSxsPXRbNF0sYz0wO2M8ZS5sZW5ndGg7YysrKXt2YXIgZj1lW2NdLnN0eWxlLHA9ITE7Zm9yKHZhciBkIGluIGYpaWYoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGYsZCkpe3ZhciBoPWZbZF07XCJudW1iZXJcIj09dHlwZW9mIGgmJihwfHwocD0hMCxyW2NdPXUoe30scltjXSksaVtjXT11KHt9LGlbY10pLGFbY109dSh7fSxhW2NdKSxsW2NdPXUoe30sbFtjXSksbltjXT17a2V5Om5bY10ua2V5LGRhdGE6bltjXS5kYXRhLHN0eWxlOnUoe30sbltjXS5zdHlsZSl9KSxyW2NdW2RdPWgsaVtjXVtkXT0wLGFbY11bZF09aCxsW2NdW2RdPTAsbltjXS5zdHlsZVtkXT1oKX19by5zZXRTdGF0ZSh7Y3VycmVudFN0eWxlczpyLGN1cnJlbnRWZWxvY2l0aWVzOmksbWVyZ2VkUHJvcHNTdHlsZXM6bixsYXN0SWRlYWxTdHlsZXM6YSxsYXN0SWRlYWxWZWxvY2l0aWVzOmx9KX0sdGhpcy5zdGFydEFuaW1hdGlvbklmTmVjZXNzYXJ5PWZ1bmN0aW9uKCl7by51bm1vdW50aW5nfHwoby5hbmltYXRpb25JRD1QLmRlZmF1bHQoZnVuY3Rpb24oZSl7aWYoIW8udW5tb3VudGluZyl7dmFyIHQ9by5wcm9wcy5zdHlsZXMsbj1cImZ1bmN0aW9uXCI9PXR5cGVvZiB0P3QoYShvLnN0YXRlLm1lcmdlZFByb3BzU3R5bGVzLG8udW5yZWFkUHJvcFN0eWxlcyxvLnN0YXRlLmxhc3RJZGVhbFN0eWxlcykpOnQ7aWYobChvLnN0YXRlLmN1cnJlbnRTdHlsZXMsbixvLnN0YXRlLmN1cnJlbnRWZWxvY2l0aWVzLG8uc3RhdGUubWVyZ2VkUHJvcHNTdHlsZXMpKXJldHVybiBvLmFuaW1hdGlvbklEPW51bGwsdm9pZChvLmFjY3VtdWxhdGVkVGltZT0wKTt2YXIgcj1lfHxnLmRlZmF1bHQoKSxpPXItby5wcmV2VGltZTtpZihvLnByZXZUaW1lPXIsby5hY2N1bXVsYXRlZFRpbWU9by5hY2N1bXVsYXRlZFRpbWUraSxvLmFjY3VtdWxhdGVkVGltZT4xMCpEJiYoby5hY2N1bXVsYXRlZFRpbWU9MCksMD09PW8uYWNjdW11bGF0ZWRUaW1lKXJldHVybiBvLmFuaW1hdGlvbklEPW51bGwsdm9pZCBvLnN0YXJ0QW5pbWF0aW9uSWZOZWNlc3NhcnkoKTtmb3IodmFyIHU9KG8uYWNjdW11bGF0ZWRUaW1lLU1hdGguZmxvb3Ioby5hY2N1bXVsYXRlZFRpbWUvRCkqRCkvRCxjPU1hdGguZmxvb3Ioby5hY2N1bXVsYXRlZFRpbWUvRCksZj1zKG8ucHJvcHMud2lsbEVudGVyLG8ucHJvcHMud2lsbExlYXZlLG8ucHJvcHMuZGlkTGVhdmUsby5zdGF0ZS5tZXJnZWRQcm9wc1N0eWxlcyxuLG8uc3RhdGUuY3VycmVudFN0eWxlcyxvLnN0YXRlLmN1cnJlbnRWZWxvY2l0aWVzLG8uc3RhdGUubGFzdElkZWFsU3R5bGVzLG8uc3RhdGUubGFzdElkZWFsVmVsb2NpdGllcykscD1mWzBdLGQ9ZlsxXSxoPWZbMl0seT1mWzNdLG09Zls0XSxiPTA7YjxwLmxlbmd0aDtiKyspe3ZhciBTPXBbYl0uc3R5bGUsdz17fSxQPXt9LFQ9e30saz17fTtmb3IodmFyIE8gaW4gUylpZihPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoUyxPKSl7dmFyIE09U1tPXTtpZihcIm51bWJlclwiPT10eXBlb2YgTSl3W09dPU0sUFtPXT0wLFRbT109TSxrW09dPTA7ZWxzZXtmb3IodmFyIHg9eVtiXVtPXSxJPW1bYl1bT10sXz0wO188YztfKyspe3ZhciBqPXYuZGVmYXVsdChELzFlMyx4LEksTS52YWwsTS5zdGlmZm5lc3MsTS5kYW1waW5nLE0ucHJlY2lzaW9uKTt4PWpbMF0sST1qWzFdfXZhciBDPXYuZGVmYXVsdChELzFlMyx4LEksTS52YWwsTS5zdGlmZm5lc3MsTS5kYW1waW5nLE0ucHJlY2lzaW9uKSx6PUNbMF0sRT1DWzFdO3dbT109eCsoei14KSp1LFBbT109SSsoRS1JKSp1LFRbT109eCxrW09dPUl9fXlbYl09VCxtW2JdPWssZFtiXT13LGhbYl09UH1vLmFuaW1hdGlvbklEPW51bGwsby5hY2N1bXVsYXRlZFRpbWUtPWMqRCxvLnNldFN0YXRlKHtjdXJyZW50U3R5bGVzOmQsY3VycmVudFZlbG9jaXRpZXM6aCxsYXN0SWRlYWxTdHlsZXM6eSxsYXN0SWRlYWxWZWxvY2l0aWVzOm0sbWVyZ2VkUHJvcHNTdHlsZXM6cH0pLG8udW5yZWFkUHJvcFN0eWxlcz1udWxsLG8uc3RhcnRBbmltYXRpb25JZk5lY2Vzc2FyeSgpfX0pKX0sdGhpcy5zdGF0ZT10aGlzLmRlZmF1bHRTdGF0ZSgpfXJldHVybiBpKHQsZSksYyh0LG51bGwsW3trZXk6XCJwcm9wVHlwZXNcIix2YWx1ZTp7ZGVmYXVsdFN0eWxlczpJLmRlZmF1bHQuYXJyYXlPZihJLmRlZmF1bHQuc2hhcGUoe2tleTpJLmRlZmF1bHQuc3RyaW5nLmlzUmVxdWlyZWQsZGF0YTpJLmRlZmF1bHQuYW55LHN0eWxlOkkuZGVmYXVsdC5vYmplY3RPZihJLmRlZmF1bHQubnVtYmVyKS5pc1JlcXVpcmVkfSkpLHN0eWxlczpJLmRlZmF1bHQub25lT2ZUeXBlKFtJLmRlZmF1bHQuZnVuYyxJLmRlZmF1bHQuYXJyYXlPZihJLmRlZmF1bHQuc2hhcGUoe2tleTpJLmRlZmF1bHQuc3RyaW5nLmlzUmVxdWlyZWQsZGF0YTpJLmRlZmF1bHQuYW55LHN0eWxlOkkuZGVmYXVsdC5vYmplY3RPZihJLmRlZmF1bHQub25lT2ZUeXBlKFtJLmRlZmF1bHQubnVtYmVyLEkuZGVmYXVsdC5vYmplY3RdKSkuaXNSZXF1aXJlZH0pKV0pLmlzUmVxdWlyZWQsY2hpbGRyZW46SS5kZWZhdWx0LmZ1bmMuaXNSZXF1aXJlZCx3aWxsRW50ZXI6SS5kZWZhdWx0LmZ1bmMsd2lsbExlYXZlOkkuZGVmYXVsdC5mdW5jLGRpZExlYXZlOkkuZGVmYXVsdC5mdW5jfSxlbnVtZXJhYmxlOiEwfSx7a2V5OlwiZGVmYXVsdFByb3BzXCIsdmFsdWU6e3dpbGxFbnRlcjpmdW5jdGlvbihlKXtyZXR1cm4gaC5kZWZhdWx0KGUuc3R5bGUpfSx3aWxsTGVhdmU6ZnVuY3Rpb24oKXtyZXR1cm4gbnVsbH0sZGlkTGVhdmU6ZnVuY3Rpb24oKXt9fSxlbnVtZXJhYmxlOiEwfV0pLHQucHJvdG90eXBlLmRlZmF1bHRTdGF0ZT1mdW5jdGlvbigpe3ZhciBlPXRoaXMucHJvcHMsdD1lLmRlZmF1bHRTdHlsZXMsbj1lLnN0eWxlcyxvPWUud2lsbEVudGVyLHI9ZS53aWxsTGVhdmUsaT1lLmRpZExlYXZlLGE9XCJmdW5jdGlvblwiPT10eXBlb2Ygbj9uKHQpOm4sbD12b2lkIDA7bD1udWxsPT10P2E6dC5tYXAoZnVuY3Rpb24oZSl7Zm9yKHZhciB0PTA7dDxhLmxlbmd0aDt0KyspaWYoYVt0XS5rZXk9PT1lLmtleSlyZXR1cm4gYVt0XTtyZXR1cm4gZX0pO3ZhciB1PW51bGw9PXQ/YS5tYXAoZnVuY3Rpb24oZSl7cmV0dXJuIGguZGVmYXVsdChlLnN0eWxlKX0pOnQubWFwKGZ1bmN0aW9uKGUpe3JldHVybiBoLmRlZmF1bHQoZS5zdHlsZSl9KSxjPW51bGw9PXQ/YS5tYXAoZnVuY3Rpb24oZSl7cmV0dXJuIHAuZGVmYXVsdChlLnN0eWxlKX0pOnQubWFwKGZ1bmN0aW9uKGUpe3JldHVybiBwLmRlZmF1bHQoZS5zdHlsZSl9KSxmPXMobyxyLGksbCxhLHUsYyx1LGMpLGQ9ZlswXSx5PWZbMV0sdj1mWzJdLG09ZlszXSxiPWZbNF07cmV0dXJue2N1cnJlbnRTdHlsZXM6eSxjdXJyZW50VmVsb2NpdGllczp2LGxhc3RJZGVhbFN0eWxlczptLGxhc3RJZGVhbFZlbG9jaXRpZXM6YixtZXJnZWRQcm9wc1N0eWxlczpkfX0sdC5wcm90b3R5cGUuY29tcG9uZW50RGlkTW91bnQ9ZnVuY3Rpb24oKXt0aGlzLnByZXZUaW1lPWcuZGVmYXVsdCgpLHRoaXMuc3RhcnRBbmltYXRpb25JZk5lY2Vzc2FyeSgpfSx0LnByb3RvdHlwZS5jb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzPWZ1bmN0aW9uKGUpe3RoaXMudW5yZWFkUHJvcFN0eWxlcyYmdGhpcy5jbGVhclVucmVhZFByb3BTdHlsZSh0aGlzLnVucmVhZFByb3BTdHlsZXMpO3ZhciB0PWUuc3R5bGVzO1wiZnVuY3Rpb25cIj09dHlwZW9mIHQ/dGhpcy51bnJlYWRQcm9wU3R5bGVzPXQoYSh0aGlzLnN0YXRlLm1lcmdlZFByb3BzU3R5bGVzLHRoaXMudW5yZWFkUHJvcFN0eWxlcyx0aGlzLnN0YXRlLmxhc3RJZGVhbFN0eWxlcykpOnRoaXMudW5yZWFkUHJvcFN0eWxlcz10LG51bGw9PXRoaXMuYW5pbWF0aW9uSUQmJih0aGlzLnByZXZUaW1lPWcuZGVmYXVsdCgpLHRoaXMuc3RhcnRBbmltYXRpb25JZk5lY2Vzc2FyeSgpKX0sdC5wcm90b3R5cGUuY29tcG9uZW50V2lsbFVubW91bnQ9ZnVuY3Rpb24oKXt0aGlzLnVubW91bnRpbmc9ITAsbnVsbCE9dGhpcy5hbmltYXRpb25JRCYmKFAuZGVmYXVsdC5jYW5jZWwodGhpcy5hbmltYXRpb25JRCksdGhpcy5hbmltYXRpb25JRD1udWxsKX0sdC5wcm90b3R5cGUucmVuZGVyPWZ1bmN0aW9uKCl7dmFyIGU9YSh0aGlzLnN0YXRlLm1lcmdlZFByb3BzU3R5bGVzLHRoaXMudW5yZWFkUHJvcFN0eWxlcyx0aGlzLnN0YXRlLmN1cnJlbnRTdHlsZXMpLHQ9dGhpcy5wcm9wcy5jaGlsZHJlbihlKTtyZXR1cm4gdCYmTS5kZWZhdWx0LkNoaWxkcmVuLm9ubHkodCl9LHR9KE0uZGVmYXVsdC5Db21wb25lbnQpO3QuZGVmYXVsdD1fLGUuZXhwb3J0cz10LmRlZmF1bHR9LGZ1bmN0aW9uKGUsdCl7XCJ1c2Ugc3RyaWN0XCI7ZnVuY3Rpb24gbihlLHQsbil7Zm9yKHZhciBvPXt9LHI9MDtyPGUubGVuZ3RoO3IrKylvW2Vbcl0ua2V5XT1yO2Zvcih2YXIgaT17fSxyPTA7cjx0Lmxlbmd0aDtyKyspaVt0W3JdLmtleV09cjtmb3IodmFyIGE9W10scj0wO3I8dC5sZW5ndGg7cisrKWFbcl09dFtyXTtmb3IodmFyIHI9MDtyPGUubGVuZ3RoO3IrKylpZighT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGksZVtyXS5rZXkpKXt2YXIgbD1uKHIsZVtyXSk7bnVsbCE9bCYmYS5wdXNoKGwpfXJldHVybiBhLnNvcnQoZnVuY3Rpb24oZSxuKXt2YXIgcj1pW2Uua2V5XSxhPWlbbi5rZXldLGw9b1tlLmtleV0scz1vW24ua2V5XTtpZihudWxsIT1yJiZudWxsIT1hKXJldHVybiBpW2Uua2V5XS1pW24ua2V5XTtpZihudWxsIT1sJiZudWxsIT1zKXJldHVybiBvW2Uua2V5XS1vW24ua2V5XTtpZihudWxsIT1yKXtmb3IodmFyIHU9MDt1PHQubGVuZ3RoO3UrKyl7dmFyIGM9dFt1XS5rZXk7aWYoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG8sYykpe2lmKHI8aVtjXSYmcz5vW2NdKXJldHVybi0xO2lmKHI+aVtjXSYmczxvW2NdKXJldHVybiAxfX1yZXR1cm4gMX1mb3IodmFyIHU9MDt1PHQubGVuZ3RoO3UrKyl7dmFyIGM9dFt1XS5rZXk7aWYoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG8sYykpe2lmKGE8aVtjXSYmbD5vW2NdKXJldHVybiAxO2lmKGE+aVtjXSYmbDxvW2NdKXJldHVybi0xfX1yZXR1cm4tMX0pfXQuX19lc01vZHVsZT0hMCx0LmRlZmF1bHQ9bixlLmV4cG9ydHM9dC5kZWZhdWx0fSxmdW5jdGlvbihlLHQsbil7XCJ1c2Ugc3RyaWN0XCI7ZnVuY3Rpb24gbygpe310Ll9fZXNNb2R1bGU9ITAsdC5kZWZhdWx0PW87ZS5leHBvcnRzPXQuZGVmYXVsdH0sZnVuY3Rpb24oZSx0LG4pe1widXNlIHN0cmljdFwiO2Z1bmN0aW9uIG8oZSl7cmV0dXJuIGUmJmUuX19lc01vZHVsZT9lOntkZWZhdWx0OmV9fWZ1bmN0aW9uIHIoZSx0KXtyZXR1cm4gaSh7fSxzLHQse3ZhbDplfSl9dC5fX2VzTW9kdWxlPSEwO3ZhciBpPU9iamVjdC5hc3NpZ258fGZ1bmN0aW9uKGUpe2Zvcih2YXIgdD0xO3Q8YXJndW1lbnRzLmxlbmd0aDt0Kyspe3ZhciBuPWFyZ3VtZW50c1t0XTtmb3IodmFyIG8gaW4gbilPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobixvKSYmKGVbb109bltvXSl9cmV0dXJuIGV9O3QuZGVmYXVsdD1yO3ZhciBhPW4oMTEpLGw9byhhKSxzPWkoe30sbC5kZWZhdWx0Lm5vV29iYmxlLHtwcmVjaXNpb246LjAxfSk7ZS5leHBvcnRzPXQuZGVmYXVsdH0sZnVuY3Rpb24oZSx0LG4pe2Z1bmN0aW9uIG8oZSx0KXtmb3IodmFyIG49MDtuPGUubGVuZ3RoO24rKyl7dmFyIG89ZVtuXSxyPWRbby5pZF07aWYocil7ci5yZWZzKys7Zm9yKHZhciBpPTA7aTxyLnBhcnRzLmxlbmd0aDtpKyspci5wYXJ0c1tpXShvLnBhcnRzW2ldKTtmb3IoO2k8by5wYXJ0cy5sZW5ndGg7aSsrKXIucGFydHMucHVzaCh1KG8ucGFydHNbaV0sdCkpfWVsc2V7Zm9yKHZhciBhPVtdLGk9MDtpPG8ucGFydHMubGVuZ3RoO2krKylhLnB1c2godShvLnBhcnRzW2ldLHQpKTtkW28uaWRdPXtpZDpvLmlkLHJlZnM6MSxwYXJ0czphfX19fWZ1bmN0aW9uIHIoZSl7Zm9yKHZhciB0PVtdLG49e30sbz0wO288ZS5sZW5ndGg7bysrKXt2YXIgcj1lW29dLGk9clswXSxhPXJbMV0sbD1yWzJdLHM9clszXSx1PXtjc3M6YSxtZWRpYTpsLHNvdXJjZU1hcDpzfTtuW2ldP25baV0ucGFydHMucHVzaCh1KTp0LnB1c2gobltpXT17aWQ6aSxwYXJ0czpbdV19KX1yZXR1cm4gdH1mdW5jdGlvbiBpKGUsdCl7dmFyIG49digpLG89U1tTLmxlbmd0aC0xXTtpZihcInRvcFwiPT09ZS5pbnNlcnRBdClvP28ubmV4dFNpYmxpbmc/bi5pbnNlcnRCZWZvcmUodCxvLm5leHRTaWJsaW5nKTpuLmFwcGVuZENoaWxkKHQpOm4uaW5zZXJ0QmVmb3JlKHQsbi5maXJzdENoaWxkKSxTLnB1c2godCk7ZWxzZXtpZihcImJvdHRvbVwiIT09ZS5pbnNlcnRBdCl0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIHZhbHVlIGZvciBwYXJhbWV0ZXIgJ2luc2VydEF0Jy4gTXVzdCBiZSAndG9wJyBvciAnYm90dG9tJy5cIik7bi5hcHBlbmRDaGlsZCh0KX19ZnVuY3Rpb24gYShlKXtlLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoZSk7dmFyIHQ9Uy5pbmRleE9mKGUpO3Q+PTAmJlMuc3BsaWNlKHQsMSl9ZnVuY3Rpb24gbChlKXt2YXIgdD1kb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic3R5bGVcIik7cmV0dXJuIHQudHlwZT1cInRleHQvY3NzXCIsaShlLHQpLHR9ZnVuY3Rpb24gcyhlKXt2YXIgdD1kb2N1bWVudC5jcmVhdGVFbGVtZW50KFwibGlua1wiKTtyZXR1cm4gdC5yZWw9XCJzdHlsZXNoZWV0XCIsaShlLHQpLHR9ZnVuY3Rpb24gdShlLHQpe3ZhciBuLG8scjtpZih0LnNpbmdsZXRvbil7dmFyIGk9YisrO249bXx8KG09bCh0KSksbz1jLmJpbmQobnVsbCxuLGksITEpLHI9Yy5iaW5kKG51bGwsbixpLCEwKX1lbHNlIGUuc291cmNlTWFwJiZcImZ1bmN0aW9uXCI9PXR5cGVvZiBVUkwmJlwiZnVuY3Rpb25cIj09dHlwZW9mIFVSTC5jcmVhdGVPYmplY3RVUkwmJlwiZnVuY3Rpb25cIj09dHlwZW9mIFVSTC5yZXZva2VPYmplY3RVUkwmJlwiZnVuY3Rpb25cIj09dHlwZW9mIEJsb2ImJlwiZnVuY3Rpb25cIj09dHlwZW9mIGJ0b2E/KG49cyh0KSxvPXAuYmluZChudWxsLG4pLHI9ZnVuY3Rpb24oKXthKG4pLG4uaHJlZiYmVVJMLnJldm9rZU9iamVjdFVSTChuLmhyZWYpfSk6KG49bCh0KSxvPWYuYmluZChudWxsLG4pLHI9ZnVuY3Rpb24oKXthKG4pfSk7cmV0dXJuIG8oZSksZnVuY3Rpb24odCl7aWYodCl7aWYodC5jc3M9PT1lLmNzcyYmdC5tZWRpYT09PWUubWVkaWEmJnQuc291cmNlTWFwPT09ZS5zb3VyY2VNYXApcmV0dXJuO28oZT10KX1lbHNlIHIoKX19ZnVuY3Rpb24gYyhlLHQsbixvKXt2YXIgcj1uP1wiXCI6by5jc3M7aWYoZS5zdHlsZVNoZWV0KWUuc3R5bGVTaGVldC5jc3NUZXh0PWcodCxyKTtlbHNle3ZhciBpPWRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHIpLGE9ZS5jaGlsZE5vZGVzO2FbdF0mJmUucmVtb3ZlQ2hpbGQoYVt0XSksYS5sZW5ndGg/ZS5pbnNlcnRCZWZvcmUoaSxhW3RdKTplLmFwcGVuZENoaWxkKGkpfX1mdW5jdGlvbiBmKGUsdCl7dmFyIG49dC5jc3Msbz10Lm1lZGlhO2lmKG8mJmUuc2V0QXR0cmlidXRlKFwibWVkaWFcIixvKSxlLnN0eWxlU2hlZXQpZS5zdHlsZVNoZWV0LmNzc1RleHQ9bjtlbHNle2Zvcig7ZS5maXJzdENoaWxkOyllLnJlbW92ZUNoaWxkKGUuZmlyc3RDaGlsZCk7ZS5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShuKSl9fWZ1bmN0aW9uIHAoZSx0KXt2YXIgbj10LmNzcyxvPXQuc291cmNlTWFwO28mJihuKz1cIlxcbi8qIyBzb3VyY2VNYXBwaW5nVVJMPWRhdGE6YXBwbGljYXRpb24vanNvbjtiYXNlNjQsXCIrYnRvYSh1bmVzY2FwZShlbmNvZGVVUklDb21wb25lbnQoSlNPTi5zdHJpbmdpZnkobykpKSkrXCIgKi9cIik7dmFyIHI9bmV3IEJsb2IoW25dLHt0eXBlOlwidGV4dC9jc3NcIn0pLGk9ZS5ocmVmO2UuaHJlZj1VUkwuY3JlYXRlT2JqZWN0VVJMKHIpLGkmJlVSTC5yZXZva2VPYmplY3RVUkwoaSl9dmFyIGQ9e30saD1mdW5jdGlvbihlKXt2YXIgdDtyZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm5cInVuZGVmaW5lZFwiPT10eXBlb2YgdCYmKHQ9ZS5hcHBseSh0aGlzLGFyZ3VtZW50cykpLHR9fSx5PWgoZnVuY3Rpb24oKXtyZXR1cm4vbXNpZSBbNi05XVxcYi8udGVzdCh3aW5kb3cubmF2aWdhdG9yLnVzZXJBZ2VudC50b0xvd2VyQ2FzZSgpKX0pLHY9aChmdW5jdGlvbigpe3JldHVybiBkb2N1bWVudC5oZWFkfHxkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZShcImhlYWRcIilbMF19KSxtPW51bGwsYj0wLFM9W107ZS5leHBvcnRzPWZ1bmN0aW9uKGUsdCl7dD10fHx7fSxcInVuZGVmaW5lZFwiPT10eXBlb2YgdC5zaW5nbGV0b24mJih0LnNpbmdsZXRvbj15KCkpLFwidW5kZWZpbmVkXCI9PXR5cGVvZiB0Lmluc2VydEF0JiYodC5pbnNlcnRBdD1cImJvdHRvbVwiKTt2YXIgbj1yKGUpO3JldHVybiBvKG4sdCksZnVuY3Rpb24oZSl7Zm9yKHZhciBpPVtdLGE9MDthPG4ubGVuZ3RoO2ErKyl7dmFyIGw9blthXSxzPWRbbC5pZF07cy5yZWZzLS0saS5wdXNoKHMpfWlmKGUpe3ZhciB1PXIoZSk7byh1LHQpfWZvcih2YXIgYT0wO2E8aS5sZW5ndGg7YSsrKXt2YXIgcz1pW2FdO2lmKDA9PT1zLnJlZnMpe2Zvcih2YXIgYz0wO2M8cy5wYXJ0cy5sZW5ndGg7YysrKXMucGFydHNbY10oKTtkZWxldGUgZFtzLmlkXX19fX07dmFyIGc9ZnVuY3Rpb24oKXt2YXIgZT1bXTtyZXR1cm4gZnVuY3Rpb24odCxuKXtyZXR1cm4gZVt0XT1uLGUuZmlsdGVyKEJvb2xlYW4pLmpvaW4oXCJcXG5cIil9fSgpfSxmdW5jdGlvbihlLHQsbil7dmFyIG89bigxNik7XCJzdHJpbmdcIj09dHlwZW9mIG8mJihvPVtbZS5pZCxvLFwiXCJdXSk7bigzMCkobyx7fSk7by5sb2NhbHMmJihlLmV4cG9ydHM9by5sb2NhbHMpfV0pfSk7IiwiLypcbiAqIENvcHlyaWdodCAyMDA3LTIwMTcgQ2hhcmxlcyBkdSBKZXUgLSBBYnN0cml1bSBTQVMgPHRlYW0gKGF0KSBweWQuaW8+XG4gKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBQeWRpby5cbiAqXG4gKiBQeWRpbyBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFB5ZGlvIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIFB5ZGlvLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuICpcbiAqIFRoZSBsYXRlc3QgY29kZSBjYW4gYmUgZm91bmQgYXQgPGh0dHBzOi8vcHlkaW8uY29tPi5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfZXh0ZW5kcyA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gKHRhcmdldCkgeyBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgeyB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldOyBmb3IgKHZhciBrZXkgaW4gc291cmNlKSB7IGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoc291cmNlLCBrZXkpKSB7IHRhcmdldFtrZXldID0gc291cmNlW2tleV07IH0gfSB9IHJldHVybiB0YXJnZXQ7IH07XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7ICdkZWZhdWx0Jzogb2JqIH07IH1cblxudmFyIF9TdG9yZSA9IHJlcXVpcmUoJy4vU3RvcmUnKTtcblxudmFyIF9TdG9yZTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9TdG9yZSk7XG5cbnZhciBfR3JpZEJ1aWxkZXIgPSByZXF1aXJlKCcuL0dyaWRCdWlsZGVyJyk7XG5cbnZhciBfR3JpZEJ1aWxkZXIyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfR3JpZEJ1aWxkZXIpO1xuXG4vKipcbiAqIEF1dG9tYXRpYyBsYXlvdXQgZm9yIHByZXNlbnRpbmcgZHJhZ2dhYmxlIGNhcmRzIHRvIHVzZXJzLiBVc2VkIGZvciB1c2VyIGFuZCBhZG1pbiBkYXNoYm9hcmQuXG4gKi9cbnZhciBSZWFjdCA9IHJlcXVpcmUoJ3JlYWN0Jyk7XG52YXIgUHlkaW8gPSByZXF1aXJlKCdweWRpbycpO1xuXG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKCdyZWFjdC1ncmlkLWxheW91dCcpO1xuXG52YXIgUmVzcG9uc2l2ZSA9IF9yZXF1aXJlLlJlc3BvbnNpdmU7XG52YXIgV2lkdGhQcm92aWRlciA9IF9yZXF1aXJlLldpZHRoUHJvdmlkZXI7XG5cbnZhciBfUHlkaW8kcmVxdWlyZUxpYiA9IFB5ZGlvLnJlcXVpcmVMaWIoJ2Jvb3QnKTtcblxudmFyIFB5ZGlvQ29udGV4dENvbnN1bWVyID0gX1B5ZGlvJHJlcXVpcmVMaWIuUHlkaW9Db250ZXh0Q29uc3VtZXI7XG52YXIgQ2FyZHNHcmlkID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuICAgIGRpc3BsYXlOYW1lOiAnQ2FyZHNHcmlkJyxcblxuICAgIC8qKlxuICAgICAqIFNhdmUgbGF5b3V0cyBpbiB0aGUgdXNlcnMgcHJlZmVyZW5jZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7b2JqZWN0fSBhbGxMYXlvdXRzIFJlc3BvbnNpdmUgbGF5b3V0cyBwYXNzZWQgZm9yIHNhdmluZ1xuICAgICAqL1xuICAgIHNhdmVGdWxsTGF5b3V0czogZnVuY3Rpb24gc2F2ZUZ1bGxMYXlvdXRzKGFsbExheW91dHMpIHtcbiAgICAgICAgdmFyIHNhdmVkUHJlZiA9IHRoaXMucHJvcHMuc3RvcmUuZ2V0VXNlclByZWZlcmVuY2UoJ0xheW91dCcpO1xuICAgICAgICAvLyBDb21wYXJlIEpTT04gdmVyc2lvbnMgdG8gYXZvaWQgc2F2aW5nIHVubmVjZXNzYXJ5IGNoYW5nZXNcbiAgICAgICAgaWYgKHNhdmVkUHJlZiAmJiB0aGlzLnByZXZpb3VzTGF5b3V0ICYmIHRoaXMucHJldmlvdXNMYXlvdXQgPT0gSlNPTi5zdHJpbmdpZnkoYWxsTGF5b3V0cykpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnByZXZpb3VzTGF5b3V0ID0gSlNPTi5zdHJpbmdpZnkoYWxsTGF5b3V0cyk7XG4gICAgICAgIHRoaXMucHJvcHMuc3RvcmUuc2F2ZVVzZXJQcmVmZXJlbmNlKCdMYXlvdXQnLCBhbGxMYXlvdXRzKTtcbiAgICB9LFxuXG4gICAgb25MYXlvdXRDaGFuZ2U6IGZ1bmN0aW9uIG9uTGF5b3V0Q2hhbmdlKGN1cnJlbnRMYXlvdXQsIGFsbExheW91dHMpIHtcbiAgICAgICAgaWYgKHRoaXMuX2Jsb2NrTGF5b3V0U2F2ZSkgcmV0dXJuO1xuICAgICAgICB0aGlzLnNhdmVGdWxsTGF5b3V0cyhhbGxMYXlvdXRzKTtcbiAgICB9LFxuXG4gICAgY29tcG9uZW50V2lsbFVubW91bnQ6IGZ1bmN0aW9uIGNvbXBvbmVudFdpbGxVbm1vdW50KCkge1xuICAgICAgICB0aGlzLnByb3BzLnN0b3JlLnN0b3BPYnNlcnZpbmcoXCJjYXJkc1wiLCB0aGlzLl9zdG9yZU9ic2VydmVyKTtcbiAgICB9LFxuXG4gICAgY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wczogZnVuY3Rpb24gY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyhuZXh0UHJvcHMpIHtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMgJiYgbmV4dFByb3BzLmVkaXRNb2RlICE9PSB0aGlzLnByb3BzLmVkaXRNb2RlKSB7XG4gICAgICAgICAgICBPYmplY3Qua2V5cyh0aGlzLnJlZnMpLmZvckVhY2goKGZ1bmN0aW9uIChrKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZWZzW2tdLnRvZ2dsZUVkaXRNb2RlKG5leHRQcm9wcy5lZGl0TW9kZSk7XG4gICAgICAgICAgICB9KS5iaW5kKHRoaXMpKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBzaG91bGRDb21wb25lbnRVcGRhdGU6IGZ1bmN0aW9uIHNob3VsZENvbXBvbmVudFVwZGF0ZShuZXh0UHJvcHMsIG5leHRTdGF0ZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZm9yY2VVcGRhdGUgfHwgZmFsc2U7XG4gICAgfSxcblxuICAgIGdldEluaXRpYWxTdGF0ZTogZnVuY3Rpb24gZ2V0SW5pdGlhbFN0YXRlKCkge1xuICAgICAgICB0aGlzLl9zdG9yZU9ic2VydmVyID0gKGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgICAgICAgICB0aGlzLl9mb3JjZVVwZGF0ZSA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgICAgICBjYXJkczogdGhpcy5wcm9wcy5zdG9yZS5nZXRDYXJkcygpXG4gICAgICAgICAgICB9LCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgX3RoaXMuX2ZvcmNlVXBkYXRlID0gZmFsc2U7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSkuYmluZCh0aGlzKTtcbiAgICAgICAgdGhpcy5wcm9wcy5zdG9yZS5vYnNlcnZlKFwiY2FyZHNcIiwgdGhpcy5fc3RvcmVPYnNlcnZlcik7XG4gICAgICAgIHJldHVybiB7IGNhcmRzOiB0aGlzLnByb3BzLnN0b3JlLmdldENhcmRzKCkgfTtcbiAgICB9LFxuXG4gICAgcmVtb3ZlQ2FyZDogZnVuY3Rpb24gcmVtb3ZlQ2FyZChpdGVtS2V5KSB7XG4gICAgICAgIHRoaXMucHJvcHMucmVtb3ZlQ2FyZChpdGVtS2V5KTtcbiAgICB9LFxuXG4gICAgYnVpbGRDYXJkczogZnVuY3Rpb24gYnVpbGRDYXJkcyhjYXJkcykge1xuXG4gICAgICAgIHZhciBpbmRleCA9IDA7XG4gICAgICAgIHZhciBsYXlvdXRzID0geyBsZzogW10sIG1kOiBbXSwgc206IFtdLCB4czogW10sIHh4czogW10gfTtcbiAgICAgICAgdmFyIGl0ZW1zID0gW107XG4gICAgICAgIHZhciBhZGRpdGlvbmFsTmFtZXNwYWNlcyA9IFtdO1xuICAgICAgICB2YXIgcmFuZCA9IE1hdGgucmFuZG9tKCk7XG4gICAgICAgIHZhciBzYXZlZExheW91dHMgPSB0aGlzLnByb3BzLnN0b3JlLmdldFVzZXJQcmVmZXJlbmNlKCdMYXlvdXQnKTtcbiAgICAgICAgdmFyIGJ1aWxkTGF5b3V0ID0gZnVuY3Rpb24gYnVpbGRMYXlvdXQoY2xhc3NPYmplY3QsIGl0ZW1LZXksIGl0ZW0sIHgsIHkpIHtcbiAgICAgICAgICAgIHZhciBsYXlvdXQgPSBjbGFzc09iamVjdC5nZXRHcmlkTGF5b3V0KHgsIHkpO1xuICAgICAgICAgICAgbGF5b3V0WydoYW5kbGUnXSA9ICdoNCc7XG4gICAgICAgICAgICBpZiAoaXRlbVsnZ3JpZEhhbmRsZSddKSB7XG4gICAgICAgICAgICAgICAgbGF5b3V0WydoYW5kbGUnXSA9IGl0ZW1bJ2dyaWRIYW5kbGUnXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxheW91dFsnaSddID0gaXRlbUtleTtcbiAgICAgICAgICAgIHJldHVybiBsYXlvdXQ7XG4gICAgICAgIH07XG4gICAgICAgIGNhcmRzLm1hcCgoZnVuY3Rpb24gKGl0ZW0pIHtcblxuICAgICAgICAgICAgdmFyIHBhcnRzID0gaXRlbS5jb21wb25lbnRDbGFzcy5zcGxpdChcIi5cIik7XG4gICAgICAgICAgICB2YXIgY2xhc3NOUyA9IHBhcnRzWzBdO1xuICAgICAgICAgICAgdmFyIGNsYXNzTmFtZSA9IHBhcnRzWzFdO1xuICAgICAgICAgICAgdmFyIGNsYXNzT2JqZWN0O1xuICAgICAgICAgICAgaWYgKGdsb2JhbFtjbGFzc05TXSAmJiBnbG9iYWxbY2xhc3NOU11bY2xhc3NOYW1lXSkge1xuICAgICAgICAgICAgICAgIGNsYXNzT2JqZWN0ID0gZ2xvYmFsW2NsYXNzTlNdW2NsYXNzTmFtZV07XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmICghZ2xvYmFsW2NsYXNzTlNdKSB7XG4gICAgICAgICAgICAgICAgICAgIGFkZGl0aW9uYWxOYW1lc3BhY2VzLnB1c2goY2xhc3NOUyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBwcm9wcyA9IF9leHRlbmRzKHt9LCBpdGVtLnByb3BzKTtcbiAgICAgICAgICAgIHZhciBpdGVtS2V5ID0gcHJvcHNbJ2tleSddID0gaXRlbVsnaWQnXSB8fCAnaXRlbV8nICsgaW5kZXg7XG4gICAgICAgICAgICBwcm9wcy5yZWYgPSBpdGVtS2V5O1xuICAgICAgICAgICAgcHJvcHMucHlkaW8gPSB0aGlzLnByb3BzLnB5ZGlvO1xuICAgICAgICAgICAgcHJvcHMub25DbG9zZUFjdGlvbiA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZW1vdmVDYXJkKGl0ZW1LZXkpO1xuICAgICAgICAgICAgfSkuYmluZCh0aGlzKTtcbiAgICAgICAgICAgIHByb3BzLnByZWZlcmVuY2VzUHJvdmlkZXIgPSB0aGlzLnByb3BzLnN0b3JlO1xuICAgICAgICAgICAgdmFyIGRlZmF1bHRYID0gMCxcbiAgICAgICAgICAgICAgICBkZWZhdWx0WSA9IDA7XG4gICAgICAgICAgICBpZiAoaXRlbS5kZWZhdWx0UG9zaXRpb24pIHtcbiAgICAgICAgICAgICAgICBkZWZhdWx0WCA9IGl0ZW0uZGVmYXVsdFBvc2l0aW9uLng7XG4gICAgICAgICAgICAgICAgZGVmYXVsdFkgPSBpdGVtLmRlZmF1bHRQb3NpdGlvbi55O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIGRlZmF1bHRMYXlvdXQgPSBidWlsZExheW91dChjbGFzc09iamVjdCwgaXRlbUtleSwgaXRlbSwgZGVmYXVsdFgsIGRlZmF1bHRZKTtcblxuICAgICAgICAgICAgZm9yICh2YXIgYnJlYWtwb2ludCBpbiBsYXlvdXRzKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFsYXlvdXRzLmhhc093blByb3BlcnR5KGJyZWFrcG9pbnQpKSBjb250aW51ZTtcbiAgICAgICAgICAgICAgICB2YXIgYnJlYWtMYXlvdXQgPSBsYXlvdXRzW2JyZWFrcG9pbnRdO1xuICAgICAgICAgICAgICAgIC8vIEZpbmQgY29ycmVzcG9uZGluZyBlbGVtZW50IGluIHByZWZlcmVuY2VcbiAgICAgICAgICAgICAgICB2YXIgZXhpc3Rpbmc7XG4gICAgICAgICAgICAgICAgaWYgKHNhdmVkTGF5b3V0cyAmJiBzYXZlZExheW91dHNbYnJlYWtwb2ludF0pIHtcbiAgICAgICAgICAgICAgICAgICAgc2F2ZWRMYXlvdXRzW2JyZWFrcG9pbnRdLm1hcChmdW5jdGlvbiAoZ3JpZERhdGEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChncmlkRGF0YVsnaSddID09IGl0ZW1LZXkgJiYgZ3JpZERhdGFbJ2gnXSA9PSBkZWZhdWx0TGF5b3V0WydoJ10pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBleGlzdGluZyA9IGdyaWREYXRhO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGV4aXN0aW5nKSB7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrTGF5b3V0LnB1c2goZXhpc3RpbmcpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaXRlbS5kZWZhdWx0TGF5b3V0cyAmJiBpdGVtLmRlZmF1bHRMYXlvdXRzW2JyZWFrcG9pbnRdKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBjcnRMYXlvdXQgPSBidWlsZExheW91dChjbGFzc09iamVjdCwgaXRlbUtleSwgaXRlbSwgaXRlbS5kZWZhdWx0TGF5b3V0c1ticmVha3BvaW50XS54LCBpdGVtLmRlZmF1bHRMYXlvdXRzW2JyZWFrcG9pbnRdLnkpO1xuICAgICAgICAgICAgICAgICAgICBicmVha0xheW91dC5wdXNoKGNydExheW91dCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWtMYXlvdXQucHVzaChkZWZhdWx0TGF5b3V0KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpbmRleCsrO1xuICAgICAgICAgICAgaXRlbXMucHVzaChSZWFjdC5jcmVhdGVFbGVtZW50KGNsYXNzT2JqZWN0LCBwcm9wcykpO1xuICAgICAgICB9KS5iaW5kKHRoaXMpKTtcblxuICAgICAgICBpZiAoYWRkaXRpb25hbE5hbWVzcGFjZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICB0aGlzLl9ibG9ja0xheW91dFNhdmUgPSB0cnVlO1xuICAgICAgICAgICAgUmVzb3VyY2VzTWFuYWdlci5sb2FkQ2xhc3Nlc0FuZEFwcGx5KGFkZGl0aW9uYWxOYW1lc3BhY2VzLCAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBhZGRpdGlvbmFsTmFtZXNwYWNlc0xvYWRlZDogYWRkaXRpb25hbE5hbWVzcGFjZXMgfSwgKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fYmxvY2tMYXlvdXRTYXZlID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgfSkuYmluZCh0aGlzKSk7XG4gICAgICAgICAgICB9KS5iaW5kKHRoaXMpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geyBjYXJkczogaXRlbXMsIGxheW91dHM6IGxheW91dHMgfTtcbiAgICB9LFxuXG4gICAgcmVuZGVyOiBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgICAgIHZhciBfYnVpbGRDYXJkcyA9IHRoaXMuYnVpbGRDYXJkcyh0aGlzLnN0YXRlLmNhcmRzKTtcblxuICAgICAgICB2YXIgY2FyZHMgPSBfYnVpbGRDYXJkcy5jYXJkcztcbiAgICAgICAgdmFyIGxheW91dHMgPSBfYnVpbGRDYXJkcy5sYXlvdXRzO1xuXG4gICAgICAgIHZhciBSZXNwb25zaXZlR3JpZExheW91dCA9IFdpZHRoUHJvdmlkZXIoUmVzcG9uc2l2ZSk7XG4gICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgUmVzcG9uc2l2ZUdyaWRMYXlvdXQsXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lOiAnZGFzaGJvYXJkLWxheW91dCcsXG4gICAgICAgICAgICAgICAgY29sczogdGhpcy5wcm9wcy5jb2xzIHx8IHsgbGc6IDEwLCBtZDogOCwgc206IDgsIHhzOiA0LCB4eHM6IDIgfSxcbiAgICAgICAgICAgICAgICBsYXlvdXRzOiBsYXlvdXRzLFxuICAgICAgICAgICAgICAgIHJvd0hlaWdodDogNSxcbiAgICAgICAgICAgICAgICBvbkxheW91dENoYW5nZTogdGhpcy5vbkxheW91dENoYW5nZSxcbiAgICAgICAgICAgICAgICBpc0RyYWdnYWJsZTogIXRoaXMucHJvcHMuZGlzYWJsZURyYWcsXG4gICAgICAgICAgICAgICAgc3R5bGU6IHRoaXMucHJvcHMuc3R5bGUsXG4gICAgICAgICAgICAgICAgYXV0b1NpemU6IGZhbHNlXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgY2FyZHNcbiAgICAgICAgKTtcbiAgICB9XG5cbn0pO1xuXG52YXIgRHluYW1pY0dyaWQgPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG4gICAgZGlzcGxheU5hbWU6ICdEeW5hbWljR3JpZCcsXG5cbiAgICBwcm9wVHlwZXM6IHtcbiAgICAgICAgc3RvcmVOYW1lc3BhY2U6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcuaXNSZXF1aXJlZCxcbiAgICAgICAgYnVpbGRlck5hbWVzcGFjZXM6IFJlYWN0LlByb3BUeXBlcy5hcnJheSxcbiAgICAgICAgZGVmYXVsdENhcmRzOiBSZWFjdC5Qcm9wVHlwZXMuYXJyYXksXG4gICAgICAgIHB5ZGlvOiBSZWFjdC5Qcm9wVHlwZXMuaW5zdGFuY2VPZihQeWRpbyksXG4gICAgICAgIGRpc2FibGVEcmFnOiBSZWFjdC5Qcm9wVHlwZXMuYm9vbFxuICAgIH0sXG5cbiAgICByZW1vdmVDYXJkOiBmdW5jdGlvbiByZW1vdmVDYXJkKGNhcmRJZCkge1xuXG4gICAgICAgIHRoaXMuc3RhdGUuc3RvcmUucmVtb3ZlQ2FyZChjYXJkSWQpO1xuICAgIH0sXG5cbiAgICBhZGRDYXJkOiBmdW5jdGlvbiBhZGRDYXJkKGNhcmREZWZpbml0aW9uKSB7XG5cbiAgICAgICAgdGhpcy5zdGF0ZS5zdG9yZS5hZGRDYXJkKGNhcmREZWZpbml0aW9uKTtcbiAgICB9LFxuXG4gICAgcmVzZXRDYXJkc0FuZExheW91dDogZnVuY3Rpb24gcmVzZXRDYXJkc0FuZExheW91dCgpIHtcbiAgICAgICAgdGhpcy5zdGF0ZS5zdG9yZS5zYXZlVXNlclByZWZlcmVuY2UoJ0xheW91dCcsIG51bGwpO1xuICAgICAgICB0aGlzLnN0YXRlLnN0b3JlLnNldENhcmRzKHRoaXMucHJvcHMuZGVmYXVsdENhcmRzKTtcbiAgICB9LFxuXG4gICAgZ2V0SW5pdGlhbFN0YXRlOiBmdW5jdGlvbiBnZXRJbml0aWFsU3RhdGUoKSB7XG4gICAgICAgIHZhciBzdG9yZSA9IG5ldyBfU3RvcmUyWydkZWZhdWx0J10odGhpcy5wcm9wcy5zdG9yZU5hbWVzcGFjZSwgdGhpcy5wcm9wcy5kZWZhdWx0Q2FyZHMsIHRoaXMucHJvcHMucHlkaW8pO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgZWRpdE1vZGU6IGZhbHNlLFxuICAgICAgICAgICAgc3RvcmU6IHN0b3JlXG4gICAgICAgIH07XG4gICAgfSxcblxuICAgIHRvZ2dsZUVkaXRNb2RlOiBmdW5jdGlvbiB0b2dnbGVFZGl0TW9kZSgpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGVkaXRNb2RlOiAhdGhpcy5zdGF0ZS5lZGl0TW9kZSB9KTtcbiAgICB9LFxuXG4gICAgcmVuZGVyOiBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgICAgIHZhciBfdGhpczIgPSB0aGlzO1xuXG4gICAgICAgIHZhciBtb25pdG9yV2lkZ2V0RWRpdGluZyA9IChmdW5jdGlvbiAoc3RhdHVzKSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgd2lkZ2V0RWRpdGluZzogc3RhdHVzIH0pO1xuICAgICAgICB9KS5iaW5kKHRoaXMpO1xuXG4gICAgICAgIHZhciBidWlsZGVyID0gdW5kZWZpbmVkO1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5idWlsZGVyTmFtZXNwYWNlcyAmJiB0aGlzLnN0YXRlLmVkaXRNb2RlKSB7XG4gICAgICAgICAgICBidWlsZGVyID0gUmVhY3QuY3JlYXRlRWxlbWVudChfR3JpZEJ1aWxkZXIyWydkZWZhdWx0J10sIHtcbiAgICAgICAgICAgICAgICBjbGFzc05hbWU6ICdhZG1pbi1oZWxwZXItcGFuZWwnLFxuICAgICAgICAgICAgICAgIG5hbWVzcGFjZXM6IHRoaXMucHJvcHMuYnVpbGRlck5hbWVzcGFjZXMsXG4gICAgICAgICAgICAgICAgb25DcmVhdGVDYXJkOiB0aGlzLmFkZENhcmQsXG4gICAgICAgICAgICAgICAgb25SZXNldExheW91dDogdGhpcy5yZXNldENhcmRzQW5kTGF5b3V0LFxuICAgICAgICAgICAgICAgIG9uRWRpdFN0YXR1c0NoYW5nZTogbW9uaXRvcldpZGdldEVkaXRpbmcsXG4gICAgICAgICAgICAgICAgZ2V0TWVzc2FnZTogZnVuY3Rpb24gKGlkKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBucyA9IGFyZ3VtZW50cy5sZW5ndGggPD0gMSB8fCBhcmd1bWVudHNbMV0gPT09IHVuZGVmaW5lZCA/ICdhanhwX2FkbWluJyA6IGFyZ3VtZW50c1sxXTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIF90aGlzMi5wcm9wcy5nZXRNZXNzYWdlKGlkLCBucyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHByb3BTdHlsZSA9IHRoaXMucHJvcHMuc3R5bGUgfHwge307XG4gICAgICAgIHZhciByZ2xTdHlsZSA9IHRoaXMucHJvcHMucmdsU3R5bGUgfHwge307XG4gICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICB7IHN0eWxlOiBfZXh0ZW5kcyh7fSwgdGhpcy5wcm9wcy5zdHlsZSwgeyB3aWR0aDogJzEwMCUnLCBmbGV4OiAnMScgfSksIGNsYXNzTmFtZTogdGhpcy5zdGF0ZS5lZGl0TW9kZSA/IFwiYnVpbGRlci1vcGVuXCIgOiBcIlwiIH0sXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgIHsgc3R5bGU6IHsgcG9zaXRpb246ICdhYnNvbHV0ZScsIGJvdHRvbTogMzAsIHJpZ2h0OiAxOCwgekluZGV4OiAxMSB9IH0sXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChNYXRlcmlhbFVJLkZsb2F0aW5nQWN0aW9uQnV0dG9uLCB7XG4gICAgICAgICAgICAgICAgICAgIHRvb2x0aXA6IHRoaXMucHJvcHMuZ2V0TWVzc2FnZSgnaG9tZS40OScpLFxuICAgICAgICAgICAgICAgICAgICBvbkNsaWNrOiB0aGlzLnRvZ2dsZUVkaXRNb2RlLFxuICAgICAgICAgICAgICAgICAgICBpY29uQ2xhc3NOYW1lOiB0aGlzLnN0YXRlLmVkaXRNb2RlID8gXCJpY29uLW9rXCIgOiBcIm1kaSBtZGktcGVuY2lsXCIsXG4gICAgICAgICAgICAgICAgICAgIG1pbmk6IHRoaXMuc3RhdGUuZWRpdE1vZGUsXG4gICAgICAgICAgICAgICAgICAgIGRpc2FibGVkOiB0aGlzLnN0YXRlLmVkaXRNb2RlICYmIHRoaXMuc3RhdGUud2lkZ2V0RWRpdGluZ1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICApLFxuICAgICAgICAgICAgYnVpbGRlcixcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6ICdob21lLWRhc2hib2FyZCcsIHN0eWxlOiB7IGhlaWdodDogJzEwMCUnIH0gfSxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KENhcmRzR3JpZCwge1xuICAgICAgICAgICAgICAgICAgICBkaXNhYmxlRHJhZzogdGhpcy5wcm9wcy5kaXNhYmxlRHJhZyxcbiAgICAgICAgICAgICAgICAgICAgY29sczogdGhpcy5wcm9wcy5jb2xzLFxuICAgICAgICAgICAgICAgICAgICBzdG9yZTogdGhpcy5zdGF0ZS5zdG9yZSxcbiAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHJnbFN0eWxlLFxuICAgICAgICAgICAgICAgICAgICBweWRpbzogdGhpcy5wcm9wcy5weWRpbyxcbiAgICAgICAgICAgICAgICAgICAgZWRpdE1vZGU6IHRoaXMuc3RhdGUuZWRpdE1vZGUsXG4gICAgICAgICAgICAgICAgICAgIHJlbW92ZUNhcmQ6IHRoaXMucmVtb3ZlQ2FyZFxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgfVxuXG59KTtcblxuZXhwb3J0c1snZGVmYXVsdCddID0gRHluYW1pY0dyaWQgPSBQeWRpb0NvbnRleHRDb25zdW1lcihEeW5hbWljR3JpZCk7XG5leHBvcnRzWydkZWZhdWx0J10gPSBEeW5hbWljR3JpZDtcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDA3LTIwMTcgQ2hhcmxlcyBkdSBKZXUgLSBBYnN0cml1bSBTQVMgPHRlYW0gKGF0KSBweWQuaW8+XG4gKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBQeWRpby5cbiAqXG4gKiBQeWRpbyBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFB5ZGlvIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIFB5ZGlvLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuICpcbiAqIFRoZSBsYXRlc3QgY29kZSBjYW4gYmUgZm91bmQgYXQgPGh0dHBzOi8vcHlkaW8uY29tPi5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfZXh0ZW5kcyA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gKHRhcmdldCkgeyBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgeyB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldOyBmb3IgKHZhciBrZXkgaW4gc291cmNlKSB7IGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoc291cmNlLCBrZXkpKSB7IHRhcmdldFtrZXldID0gc291cmNlW2tleV07IH0gfSB9IHJldHVybiB0YXJnZXQ7IH07XG5cbnZhciBSZWFjdCA9IHJlcXVpcmUoJ3JlYWN0Jyk7XG52YXIgUHlkaW8gPSByZXF1aXJlKCdweWRpbycpO1xuXG52YXIgX1B5ZGlvJHJlcXVpcmVMaWIgPSBQeWRpby5yZXF1aXJlTGliKCdib290Jyk7XG5cbnZhciBQeWRpb0NvbnRleHRDb25zdW1lciA9IF9QeWRpbyRyZXF1aXJlTGliLlB5ZGlvQ29udGV4dENvbnN1bWVyO1xudmFyIEFzeW5jQ29tcG9uZW50ID0gX1B5ZGlvJHJlcXVpcmVMaWIuQXN5bmNDb21wb25lbnQ7XG5cbnZhciBHcmlkQnVpbGRlciA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcbiAgICBkaXNwbGF5TmFtZTogJ0dyaWRCdWlsZGVyJyxcblxuICAgIHByb3BUeXBlczoge1xuICAgICAgICBuYW1lc3BhY2VzOiBSZWFjdC5Qcm9wVHlwZXMuYXJyYXksXG4gICAgICAgIG9uQ3JlYXRlQ2FyZDogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsXG4gICAgICAgIG9uRWRpdFN0YXR1c0NoYW5nZTogUmVhY3QuUHJvcFR5cGVzLmZ1bmNcbiAgICB9LFxuXG4gICAgZ2V0SW5pdGlhbFN0YXRlOiBmdW5jdGlvbiBnZXRJbml0aWFsU3RhdGUoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzZWxlY3RlZEluZGV4OiAwLFxuICAgICAgICAgICAgYXZhaWxhYmxlV2lkZ2V0czogdGhpcy5saXN0QXZhaWxhYmxlV2lkZ2V0cygpXG4gICAgICAgIH07XG4gICAgfSxcblxuICAgIGxpc3RBdmFpbGFibGVXaWRnZXRzOiBmdW5jdGlvbiBsaXN0QXZhaWxhYmxlV2lkZ2V0cygpIHtcbiAgICAgICAgdmFyIHNlY29uZFBhc3MgPSBhcmd1bWVudHMubGVuZ3RoIDw9IDAgfHwgYXJndW1lbnRzWzBdID09PSB1bmRlZmluZWQgPyBmYWxzZSA6IGFyZ3VtZW50c1swXTtcblxuICAgICAgICB2YXIgd2lkZ2V0cyA9IFtdO1xuICAgICAgICB2YXIgYWRkaXRpb25hbE5hbWVzcGFjZXMgPSBbXTtcbiAgICAgICAgdGhpcy5wcm9wcy5uYW1lc3BhY2VzLm1hcChmdW5jdGlvbiAobnMpIHtcbiAgICAgICAgICAgIGlmICghZ2xvYmFsW25zXSkge1xuICAgICAgICAgICAgICAgIGFkZGl0aW9uYWxOYW1lc3BhY2VzLnB1c2gobnMpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvciAodmFyIGsgaW4gZ2xvYmFsW25zXSkge1xuICAgICAgICAgICAgICAgIGlmIChnbG9iYWxbbnNdLmhhc093blByb3BlcnR5KGspKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciB3aWRnZXRDbGFzcyA9IGdsb2JhbFtuc11ba107XG4gICAgICAgICAgICAgICAgICAgIGlmICh3aWRnZXRDbGFzcy5oYXNCdWlsZGVyRmllbGRzICYmIHdpZGdldENsYXNzLmhhc0J1aWxkZXJGaWVsZHMoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgd2lkZ2V0cy5wdXNoKHsgcmVhY3RDbGFzczogd2lkZ2V0Q2xhc3MsIGZ1bGxOYW1lOiBucyArICcuJyArIHdpZGdldENsYXNzLmRpc3BsYXlOYW1lIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKGFkZGl0aW9uYWxOYW1lc3BhY2VzLmxlbmd0aCAmJiAhc2Vjb25kUGFzcykge1xuICAgICAgICAgICAgUmVzb3VyY2VzTWFuYWdlci5sb2FkQ2xhc3Nlc0FuZEFwcGx5KGFkZGl0aW9uYWxOYW1lc3BhY2VzLCAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgICAgICAgICBhdmFpbGFibGVXaWRnZXRzOiB0aGlzLmxpc3RBdmFpbGFibGVXaWRnZXRzKHRydWUpXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KS5iaW5kKHRoaXMpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gd2lkZ2V0cztcbiAgICB9LFxuXG4gICAgb25Ecm9wRG93bkNoYW5nZTogZnVuY3Rpb24gb25Ecm9wRG93bkNoYW5nZShldmVudCwgaW5kZXgsIGl0ZW0pIHtcbiAgICAgICAgdmFyIGRlZmF1bHRWYWx1ZXMgPSB7fTtcbiAgICAgICAgaWYgKGluZGV4ICE9IDApIHtcbiAgICAgICAgICAgIGl0ZW0ucGF5bG9hZFsncmVhY3RDbGFzcyddLmdldEJ1aWxkZXJGaWVsZHMoKS5tYXAoZnVuY3Rpb24gKGYpIHtcbiAgICAgICAgICAgICAgICBpZiAoZlsnZGVmYXVsdCddKSBkZWZhdWx0VmFsdWVzW2YubmFtZV0gPSBmWydkZWZhdWx0J107XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5wcm9wcy5vbkVkaXRTdGF0dXNDaGFuZ2UpIHtcbiAgICAgICAgICAgIHRoaXMucHJvcHMub25FZGl0U3RhdHVzQ2hhbmdlKGluZGV4ICE9IDApO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgc2VsZWN0ZWRJbmRleDogaW5kZXgsXG4gICAgICAgICAgICBzZWxlY3RlZFdpZGdldDogaXRlbS5wYXlsb2FkLFxuICAgICAgICAgICAgY3VycmVudEZvcm1WYWx1ZXM6IGRlZmF1bHRWYWx1ZXNcbiAgICAgICAgfSk7XG4gICAgfSxcblxuICAgIGNhbmNlbDogZnVuY3Rpb24gY2FuY2VsKCkge1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5vbkVkaXRTdGF0dXNDaGFuZ2UpIHtcbiAgICAgICAgICAgIHRoaXMucHJvcHMub25FZGl0U3RhdHVzQ2hhbmdlKGZhbHNlKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNldFN0YXRlKHsgc2VsZWN0ZWRJbmRleDogMCB9KTtcbiAgICB9LFxuXG4gICAgb25Gb3JtVmFsdWVDaGFuZ2U6IGZ1bmN0aW9uIG9uRm9ybVZhbHVlQ2hhbmdlKG5ld1ZhbHVlcykge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgY3VycmVudEZvcm1WYWx1ZXM6IG5ld1ZhbHVlcyB9KTtcbiAgICB9LFxuXG4gICAgb25Gb3JtU3VibWl0OiBmdW5jdGlvbiBvbkZvcm1TdWJtaXQoKSB7XG4gICAgICAgIHZhciB2YWx1ZXMgPSB0aGlzLnN0YXRlLmN1cnJlbnRGb3JtVmFsdWVzO1xuICAgICAgICB2YXIgc2VsZWN0ZWRXaWRnZXQgPSB0aGlzLnN0YXRlLnNlbGVjdGVkV2lkZ2V0O1xuICAgICAgICB2YXIgdGl0bGUgPSB2YWx1ZXMudGl0bGUgPyB2YWx1ZXMudGl0bGUgOiB2YWx1ZXMubGVnZW5kO1xuICAgICAgICBpZiAoIXRpdGxlKSB0aXRsZSA9IHRoaXMuc3RhdGUuc2VsZWN0ZWRXaWRnZXRbJ3JlYWN0Q2xhc3MnXS5idWlsZGVyRGlzcGxheU5hbWU7XG4gICAgICAgIHRoaXMucHJvcHMub25DcmVhdGVDYXJkKHtcbiAgICAgICAgICAgIGNvbXBvbmVudENsYXNzOiBzZWxlY3RlZFdpZGdldC5mdWxsTmFtZSxcbiAgICAgICAgICAgIHRpdGxlOiB0aXRsZSxcbiAgICAgICAgICAgIHByb3BzOiB2YWx1ZXNcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuY2FuY2VsKCk7XG4gICAgfSxcblxuICAgIHJlc2V0TGF5b3V0OiBmdW5jdGlvbiByZXNldExheW91dCgpIHtcbiAgICAgICAgaWYgKHdpbmRvdy5jb25maXJtKHRoaXMucHJvcHMuZ2V0TWVzc2FnZSgnaG9tZS41MScpKSkge1xuICAgICAgICAgICAgdGhpcy5wcm9wcy5vblJlc2V0TGF5b3V0KCk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgcmVuZGVyOiBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgICAgIHZhciBnZXRNZXNzYWdlID0gdGhpcy5wcm9wcy5nZXRNZXNzYWdlO1xuXG4gICAgICAgIHZhciBzZWxlY3Rvckl0ZW1zID0gW3sgcGF5bG9hZDogMCwgdGV4dDogZ2V0TWVzc2FnZSgnaG9tZS41MCcpIH1dLmNvbmNhdCh0aGlzLnN0YXRlLmF2YWlsYWJsZVdpZGdldHMubWFwKGZ1bmN0aW9uICh3LCBpbmRleCkge1xuICAgICAgICAgICAgcmV0dXJuIHsgcGF5bG9hZDogdywgdGV4dDogd1sncmVhY3RDbGFzcyddLmJ1aWxkZXJEaXNwbGF5TmFtZSB9O1xuICAgICAgICB9KSk7XG5cbiAgICAgICAgdmFyIHNlbGVjdG9yID0gUmVhY3QuY3JlYXRlRWxlbWVudChSZWFjdE1VSS5Ecm9wRG93bk1lbnUsIHtcbiAgICAgICAgICAgIG1lbnVJdGVtczogc2VsZWN0b3JJdGVtcyxcbiAgICAgICAgICAgIG9uQ2hhbmdlOiB0aGlzLm9uRHJvcERvd25DaGFuZ2UsXG4gICAgICAgICAgICBzZWxlY3RlZEluZGV4OiB0aGlzLnN0YXRlLnNlbGVjdGVkSW5kZXgsXG4gICAgICAgICAgICBhdXRvV2lkdGg6IGZhbHNlLFxuICAgICAgICAgICAgY2xhc3NOYW1lOiAnd2lkZ2V0LXR5cGUtc2VsZWN0b3InXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHZhciBmb3JtLCBhZGQ7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlLnNlbGVjdGVkSW5kZXggIT0gMCkge1xuICAgICAgICAgICAgdmFyIGZpZWxkcyA9IHRoaXMuc3RhdGUuc2VsZWN0ZWRXaWRnZXRbJ3JlYWN0Q2xhc3MnXS5nZXRCdWlsZGVyRmllbGRzKCk7XG4gICAgICAgICAgICB2YXIgZGVmYXVsdFZhbHVlcyA9IHt9O1xuICAgICAgICAgICAgZmllbGRzLm1hcChmdW5jdGlvbiAoZikge1xuICAgICAgICAgICAgICAgIGlmIChmWydkZWZhdWx0J10pIGRlZmF1bHRWYWx1ZXNbZi5uYW1lXSA9IGZbJ2RlZmF1bHQnXTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUuY3VycmVudEZvcm1WYWx1ZXMpIHtcbiAgICAgICAgICAgICAgICBkZWZhdWx0VmFsdWVzID0gTGFuZ1V0aWxzLm1lcmdlT2JqZWN0c1JlY3Vyc2l2ZShkZWZhdWx0VmFsdWVzLCB0aGlzLnN0YXRlLmN1cnJlbnRGb3JtVmFsdWVzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvcm0gPSBSZWFjdC5jcmVhdGVFbGVtZW50KEFzeW5jQ29tcG9uZW50LCB7XG4gICAgICAgICAgICAgICAgbmFtZXNwYWNlOiAnUHlkaW9Gb3JtJyxcbiAgICAgICAgICAgICAgICBjb21wb25lbnROYW1lOiAnRm9ybVBhbmVsJyxcbiAgICAgICAgICAgICAgICBwYXJhbWV0ZXJzOiBmaWVsZHMsXG4gICAgICAgICAgICAgICAgZGVwdGg6IC0xLFxuICAgICAgICAgICAgICAgIHZhbHVlczogZGVmYXVsdFZhbHVlcyxcbiAgICAgICAgICAgICAgICBvbkNoYW5nZTogdGhpcy5vbkZvcm1WYWx1ZUNoYW5nZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBhZGQgPSBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgIHsgc3R5bGU6IHsgdGV4dEFsaWduOiAnY2VudGVyJywgcGFkZGluZ0JvdHRvbTogMTAwIH0gfSxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFJlYWN0TVVJLlJhaXNlZEJ1dHRvbiwgeyBsYWJlbDogZ2V0TWVzc2FnZSgnaG9tZS41MicpLCBvbkNsaWNrOiB0aGlzLm9uRm9ybVN1Ym1pdCB9KSxcbiAgICAgICAgICAgICAgICAnwqAnLFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoUmVhY3RNVUkuUmFpc2VkQnV0dG9uLCB7IGxhYmVsOiBnZXRNZXNzYWdlKCc1NCcsICcnKSwgb25DbGljazogdGhpcy5jYW5jZWwgfSlcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgIFJlYWN0TVVJLlBhcGVyLFxuICAgICAgICAgICAgX2V4dGVuZHMoe30sIHRoaXMucHJvcHMsIHtcbiAgICAgICAgICAgICAgICB6RGVwdGg6IDMgfSksXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICdoMycsXG4gICAgICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgICAgICBnZXRNZXNzYWdlKCdob21lLjUzJylcbiAgICAgICAgICAgICksXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAnbGVnZW5kJyB9LFxuICAgICAgICAgICAgICAgIGdldE1lc3NhZ2UoJ2hvbWUuNTQnKSxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KCdicicsIG51bGwpLFxuICAgICAgICAgICAgICAgIGdldE1lc3NhZ2UoJ2hvbWUuNTUnKVxuICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIHNlbGVjdG9yLFxuICAgICAgICAgICAgZm9ybSxcbiAgICAgICAgICAgIGFkZCxcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgeyBzdHlsZTogeyBwb3NpdGlvbjogJ2Fic29sdXRlJywgYm90dG9tOiAzMCwgbGVmdDogMTAgfSB9LFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoUmVhY3RNVUkuRmxhdEJ1dHRvbiwgeyBkaXNhYmxlZDogdGhpcy5zdGF0ZS5zZWxlY3RlZEluZGV4ICE9IDAsIGxhYmVsOiBnZXRNZXNzYWdlKCdob21lLjU2JyksIHNlY29uZGFyeTogdHJ1ZSwgb25DbGljazogdGhpcy5yZXNldExheW91dCB9KVxuICAgICAgICAgICAgKVxuICAgICAgICApO1xuICAgIH1cblxufSk7XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IEdyaWRCdWlsZGVyID0gUHlkaW9Db250ZXh0Q29uc3VtZXIoR3JpZEJ1aWxkZXIpO1xuZXhwb3J0c1snZGVmYXVsdCddID0gR3JpZEJ1aWxkZXI7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTtcbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDE3IENoYXJsZXMgZHUgSmV1IC0gQWJzdHJpdW0gU0FTIDx0ZWFtIChhdCkgcHlkLmlvPlxuICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgUHlkaW8uXG4gKlxuICogUHlkaW8gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBQeWRpbyBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCBQeWRpby4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAqXG4gKiBUaGUgbGF0ZXN0IGNvZGUgY2FuIGJlIGZvdW5kIGF0IDxodHRwczovL3B5ZGlvLmNvbT4uXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG52YXIgX2V4dGVuZHMgPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uICh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTsgZm9yICh2YXIga2V5IGluIHNvdXJjZSkgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkgeyB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldOyB9IH0gfSByZXR1cm4gdGFyZ2V0OyB9O1xuXG5leHBvcnRzWydkZWZhdWx0J10gPSB7XG5cbiAgICBwcm9wVHlwZXM6IHtcbiAgICAgICAgc2hvd0Nsb3NlQWN0aW9uOiBSZWFjdC5Qcm9wVHlwZXMuYm9vbCxcbiAgICAgICAgb25DbG9zZUFjdGlvbjogUmVhY3QuUHJvcFR5cGVzLmZ1bmNcbiAgICB9LFxuXG4gICAgZm9jdXNJdGVtOiBmdW5jdGlvbiBmb2N1c0l0ZW0oKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBmb2N1czogdHJ1ZSB9KTtcbiAgICB9LFxuXG4gICAgYmx1ckl0ZW06IGZ1bmN0aW9uIGJsdXJJdGVtKCkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgZm9jdXM6IGZhbHNlIH0pO1xuICAgIH0sXG5cbiAgICBtZXJnZVN0eWxlV2l0aEZvY3VzOiBmdW5jdGlvbiBtZXJnZVN0eWxlV2l0aEZvY3VzKCkge1xuICAgICAgICByZXR1cm4gX2V4dGVuZHMoe30sIHRoaXMucHJvcHMuc3R5bGUsIHsgekluZGV4OiB0aGlzLnN0YXRlLmZvY3VzID8gMSA6IG51bGwgfSk7XG4gICAgfSxcblxuICAgIGdldEluaXRpYWxTYXRlOiBmdW5jdGlvbiBnZXRJbml0aWFsU2F0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHsgZm9jdXM6IGZhbHNlLCBzaG93Q2xvc2VBY3Rpb246IGZhbHNlIH07XG4gICAgfSxcblxuICAgIHRvZ2dsZUVkaXRNb2RlOiBmdW5jdGlvbiB0b2dnbGVFZGl0TW9kZSgpIHtcbiAgICAgICAgdmFyIHZhbHVlID0gYXJndW1lbnRzLmxlbmd0aCA8PSAwIHx8IGFyZ3VtZW50c1swXSA9PT0gdW5kZWZpbmVkID8gdW5kZWZpbmVkIDogYXJndW1lbnRzWzBdO1xuXG4gICAgICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgc2hvd0Nsb3NlQWN0aW9uOiAhKHRoaXMuc3RhdGUgJiYgdGhpcy5zdGF0ZS5zaG93Q2xvc2VBY3Rpb24pIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNob3dDbG9zZUFjdGlvbjogdmFsdWUgfSk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgZ2V0Q2xvc2VCdXR0b246IGZ1bmN0aW9uIGdldENsb3NlQnV0dG9uKCkge1xuICAgICAgICBpZiAodGhpcy5zdGF0ZSAmJiB0aGlzLnN0YXRlLnNob3dDbG9zZUFjdGlvbikge1xuICAgICAgICAgICAgdmFyIGNsb3NlQWN0aW9uID0gdGhpcy5wcm9wcy5vbkNsb3NlQWN0aW9uIHx8IGZ1bmN0aW9uICgpIHt9O1xuICAgICAgICAgICAgdmFyIG92ZXJsYXlTdHlsZSA9IHtcbiAgICAgICAgICAgICAgICBwb3NpdGlvbjogJ2Fic29sdXRlJyxcbiAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6ICdyZ2JhKDAsMCwwLDAuNTMpJyxcbiAgICAgICAgICAgICAgICB6SW5kZXg6IDEwLFxuICAgICAgICAgICAgICAgIHRvcDogMCxcbiAgICAgICAgICAgICAgICBsZWZ0OiAwLFxuICAgICAgICAgICAgICAgIGJvdHRvbTogMCxcbiAgICAgICAgICAgICAgICByaWdodDogMCxcbiAgICAgICAgICAgICAgICBkaXNwbGF5OiAnZmxleCcsXG4gICAgICAgICAgICAgICAgYWxpZ25JdGVtczogJ2NlbnRlcicsXG4gICAgICAgICAgICAgICAganVzdGlmeUNvbnRlbnQ6ICdjZW50ZXInXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgeyBzdHlsZTogb3ZlcmxheVN0eWxlIH0sXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChNYXRlcmlhbFVJLkZsYXRCdXR0b24sIHtcbiAgICAgICAgICAgICAgICAgICAgbGFiZWw6IHB5ZGlvLk1lc3NhZ2VIYXNoWydhanhwX2FkbWluLmhvbWUuNDgnXSxcbiAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lOiAnY2FyZC1jbG9zZS1idXR0b24nLFxuICAgICAgICAgICAgICAgICAgICBvblRvdWNoVGFwOiBjbG9zZUFjdGlvbixcbiAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHsgY29sb3I6ICd3aGl0ZScgfVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgc3RhdGljczoge1xuICAgICAgICBnZXRHcmlkTGF5b3V0OiBmdW5jdGlvbiBnZXRHcmlkTGF5b3V0KHgsIHkpIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgeDogeCB8fCAwLFxuICAgICAgICAgICAgICAgIHk6IHkgfHwgMCxcbiAgICAgICAgICAgICAgICB3OiB0aGlzLmdyaWRXaWR0aCB8fCA0LFxuICAgICAgICAgICAgICAgIGg6IHRoaXMuZ3JpZEhlaWdodCB8fCAxMixcbiAgICAgICAgICAgICAgICBpc1Jlc2l6YWJsZTogZmFsc2VcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0sXG4gICAgICAgIGhhc0J1aWxkZXJGaWVsZHM6IGZ1bmN0aW9uIGhhc0J1aWxkZXJGaWVsZHMoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5idWlsZGVyRmllbGRzID8gdHJ1ZSA6IGZhbHNlO1xuICAgICAgICB9LFxuICAgICAgICBnZXRCdWlsZGVyRmllbGRzOiBmdW5jdGlvbiBnZXRCdWlsZGVyRmllbGRzKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuYnVpbGRlckZpZWxkcztcbiAgICAgICAgfVxuICAgIH1cblxufTtcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDA3LTIwMTcgQ2hhcmxlcyBkdSBKZXUgLSBBYnN0cml1bSBTQVMgPHRlYW0gKGF0KSBweWQuaW8+XG4gKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBQeWRpby5cbiAqXG4gKiBQeWRpbyBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFB5ZGlvIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIFB5ZGlvLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuICpcbiAqIFRoZSBsYXRlc3QgY29kZSBjYW4gYmUgZm91bmQgYXQgPGh0dHBzOi8vcHlkaW8uY29tPi5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uJyk7IH0gfVxuXG5mdW5jdGlvbiBfaW5oZXJpdHMoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSAnZnVuY3Rpb24nICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCAnICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfVxuXG52YXIgU3RvcmUgPSAoZnVuY3Rpb24gKF9PYnNlcnZhYmxlKSB7XG4gICAgX2luaGVyaXRzKFN0b3JlLCBfT2JzZXJ2YWJsZSk7XG5cbiAgICAvKipcbiAgICAgKiBJbml0IGEgY2FyZCBzdG9yZVxuICAgICAqIEBwYXJhbSBwcmVmTmFtZXNwYWNlIE5hbWVzcGFjZSBmb3IgZ2V0dGluZy9zZXR0aW5nIHVzZXIgcHJlZmVyZW5jZXNcbiAgICAgKiBAcGFyYW0gZGVmYXVsdENhcmRzIEFycmF5IG9mIGNhcmRzIHRvIGJlIGRpc3BsYXllZCBieSBkZWZhdWx0XG4gICAgICovXG5cbiAgICBmdW5jdGlvbiBTdG9yZShwcmVmTmFtZXNwYWNlLCBkZWZhdWx0Q2FyZHMsIHB5ZGlvT2JqZWN0KSB7XG4gICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBTdG9yZSk7XG5cbiAgICAgICAgX09ic2VydmFibGUuY2FsbCh0aGlzKTtcbiAgICAgICAgdGhpcy5fbmFtZXNwYWNlID0gcHJlZk5hbWVzcGFjZTtcbiAgICAgICAgdGhpcy5fcHlkaW8gPSBweWRpb09iamVjdDtcbiAgICAgICAgdGhpcy5fY2FyZHMgPSB0aGlzLmdldFVzZXJQcmVmZXJlbmNlKFwiQ2FyZHNcIik7XG4gICAgICAgIGlmICghdGhpcy5fY2FyZHMpIHtcbiAgICAgICAgICAgIHRoaXMuX2NhcmRzID0gZGVmYXVsdENhcmRzO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgU3RvcmUucHJvdG90eXBlLmdldFVzZXJQcmVmZXJlbmNlID0gZnVuY3Rpb24gZ2V0VXNlclByZWZlcmVuY2UocHJlZk5hbWUpIHtcbiAgICAgICAgdmFyIHByZWZLZXkgPSB0aGlzLl9uYW1lc3BhY2UgKyBwcmVmTmFtZTtcbiAgICAgICAgdmFyIGd1aVByZWZzID0gdGhpcy5fcHlkaW8udXNlci5nZXRQcmVmZXJlbmNlKCdndWlfcHJlZmVyZW5jZXMnLCB0cnVlKTtcbiAgICAgICAgaWYgKGd1aVByZWZzICYmIGd1aVByZWZzW3ByZWZLZXldKSB7XG4gICAgICAgICAgICByZXR1cm4gZ3VpUHJlZnNbcHJlZktleV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBTdG9yZS5wcm90b3R5cGUuc2F2ZVVzZXJQcmVmZXJlbmNlID0gZnVuY3Rpb24gc2F2ZVVzZXJQcmVmZXJlbmNlKHByZWZOYW1lLCBwcmVmVmFsdWUpIHtcbiAgICAgICAgdmFyIHByZWZLZXkgPSB0aGlzLl9uYW1lc3BhY2UgKyBwcmVmTmFtZTtcbiAgICAgICAgdmFyIGd1aVByZWZzID0gdGhpcy5fcHlkaW8udXNlci5nZXRQcmVmZXJlbmNlKCdndWlfcHJlZmVyZW5jZXMnLCB0cnVlKTtcbiAgICAgICAgaWYgKCFndWlQcmVmcykgZ3VpUHJlZnMgPSB7fTtcbiAgICAgICAgZ3VpUHJlZnNbcHJlZktleV0gPSBwcmVmVmFsdWU7XG4gICAgICAgIHRoaXMuX3B5ZGlvLnVzZXIuc2V0UHJlZmVyZW5jZSgnZ3VpX3ByZWZlcmVuY2VzJywgZ3VpUHJlZnMsIHRydWUpO1xuICAgICAgICB0aGlzLl9weWRpby51c2VyLnNhdmVQcmVmZXJlbmNlKCdndWlfcHJlZmVyZW5jZXMnKTtcbiAgICB9O1xuXG4gICAgU3RvcmUucHJvdG90eXBlLnNhdmVDYXJkcyA9IGZ1bmN0aW9uIHNhdmVDYXJkcyhjYXJkcykge1xuICAgICAgICB0aGlzLnNhdmVVc2VyUHJlZmVyZW5jZSgnQ2FyZHMnLCBjYXJkcyk7XG4gICAgfTtcblxuICAgIFN0b3JlLnByb3RvdHlwZS5yZXNldENhcmRzID0gZnVuY3Rpb24gcmVzZXRDYXJkcygpIHtcbiAgICAgICAgdGhpcy5zYXZlVXNlclByZWZlcmVuY2UoJ0NhcmRzJywgbnVsbCk7XG4gICAgfTtcblxuICAgIFN0b3JlLnByb3RvdHlwZS5zZXRDYXJkcyA9IGZ1bmN0aW9uIHNldENhcmRzKG5ld0NhcmRzKSB7XG4gICAgICAgIHRoaXMuX2NhcmRzID0gbmV3Q2FyZHM7XG4gICAgICAgIHRoaXMubm90aWZ5KFwiY2FyZHNcIiwgdGhpcy5fY2FyZHMpO1xuICAgICAgICB0aGlzLnNhdmVDYXJkcyhuZXdDYXJkcyk7XG4gICAgfTtcblxuICAgIFN0b3JlLnByb3RvdHlwZS5nZXRDYXJkcyA9IGZ1bmN0aW9uIGdldENhcmRzKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY2FyZHM7XG4gICAgfTtcblxuICAgIFN0b3JlLnByb3RvdHlwZS5yZW1vdmVDYXJkID0gZnVuY3Rpb24gcmVtb3ZlQ2FyZChjYXJkSWQpIHtcbiAgICAgICAgdmFyIGluZGV4ID0gLTE7XG4gICAgICAgIHZhciBjdXJyZW50Q2FyZHMgPSB0aGlzLmdldENhcmRzKCk7XG4gICAgICAgIGN1cnJlbnRDYXJkcy5tYXAoZnVuY3Rpb24gKGNhcmQsIGFycmF5SW5kZXgpIHtcbiAgICAgICAgICAgIGlmIChjYXJkLmlkID09IGNhcmRJZCkgaW5kZXggPSBhcnJheUluZGV4O1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKGluZGV4ID09IC0xKSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ0NhcmQgSUQgbm90IGZvdW5kLCB0aGlzIGlzIHN0cmFuZ2UuJywgY2FyZElkKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgbmV3Q2FyZHM7XG4gICAgICAgIGlmIChpbmRleCA9PSAwKSBuZXdDYXJkcyA9IGN1cnJlbnRDYXJkcy5zbGljZSgxKTtlbHNlIGlmIChpbmRleCA9PSBjdXJyZW50Q2FyZHMubGVuZ3RoIC0gMSkgbmV3Q2FyZHMgPSBjdXJyZW50Q2FyZHMuc2xpY2UoMCwgLTEpO2Vsc2UgbmV3Q2FyZHMgPSBjdXJyZW50Q2FyZHMuc2xpY2UoMCwgaW5kZXgpLmNvbmNhdChjdXJyZW50Q2FyZHMuc2xpY2UoaW5kZXggKyAxKSk7XG4gICAgICAgIHRoaXMuc2V0Q2FyZHMobmV3Q2FyZHMpO1xuICAgIH07XG5cbiAgICBTdG9yZS5wcm90b3R5cGUuY3JlYXRlQ2FyZElkID0gZnVuY3Rpb24gY3JlYXRlQ2FyZElkKGNhcmREZWZpbml0aW9uKSB7XG4gICAgICAgIHZhciByYW5kb21pemUgPSBhcmd1bWVudHMubGVuZ3RoIDw9IDEgfHwgYXJndW1lbnRzWzFdID09PSB1bmRlZmluZWQgPyBmYWxzZSA6IGFyZ3VtZW50c1sxXTtcblxuICAgICAgICB2YXIgaWQgPSBMYW5nVXRpbHMuY29tcHV0ZVN0cmluZ1NsdWcoY2FyZERlZmluaXRpb25bJ3RpdGxlJ10pO1xuICAgICAgICBpZiAocmFuZG9taXplKSB7XG4gICAgICAgICAgICBpZCArPSAnLScgKyBNYXRoLnJvdW5kKE1hdGgucmFuZG9tKCkgKiAxMDAgKyAxMCk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGFscmVhZHlFeGlzdHMgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5fY2FyZHMubWFwKChmdW5jdGlvbiAoY2FyZCkge1xuICAgICAgICAgICAgaWYgKGNhcmQuaWQgPT0gaWQpIGFscmVhZHlFeGlzdHMgPSB0cnVlO1xuICAgICAgICB9KS5iaW5kKHRoaXMpKTtcbiAgICAgICAgaWYgKGFscmVhZHlFeGlzdHMpIHtcbiAgICAgICAgICAgIGlkID0gdGhpcy5jcmVhdGVDYXJkSWQoY2FyZERlZmluaXRpb24sIHRydWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpZDtcbiAgICB9O1xuXG4gICAgU3RvcmUucHJvdG90eXBlLmFkZENhcmQgPSBmdW5jdGlvbiBhZGRDYXJkKGNhcmREZWZpbml0aW9uKSB7XG4gICAgICAgIC8vY29uc29sZS5sb2coY2FyZERlZmluaXRpb24pO1xuXG4gICAgICAgIGNhcmREZWZpbml0aW9uWydpZCddID0gdGhpcy5jcmVhdGVDYXJkSWQoY2FyZERlZmluaXRpb24pO1xuICAgICAgICB0aGlzLnNldENhcmRzKHRoaXMuX2NhcmRzLmNvbmNhdChbY2FyZERlZmluaXRpb25dKSk7XG4gICAgfTtcblxuICAgIHJldHVybiBTdG9yZTtcbn0pKE9ic2VydmFibGUpO1xuXG5leHBvcnRzWydkZWZhdWx0J10gPSBTdG9yZTtcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDA3LTIwMTcgQ2hhcmxlcyBkdSBKZXUgLSBBYnN0cml1bSBTQVMgPHRlYW0gKGF0KSBweWQuaW8+XG4gKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBQeWRpby5cbiAqXG4gKiBQeWRpbyBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFB5ZGlvIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIFB5ZGlvLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuICpcbiAqIFRoZSBsYXRlc3QgY29kZSBjYW4gYmUgZm91bmQgYXQgPGh0dHBzOi8vcHlkaW8uY29tPi5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfZXh0ZW5kcyA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gKHRhcmdldCkgeyBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgeyB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldOyBmb3IgKHZhciBrZXkgaW4gc291cmNlKSB7IGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoc291cmNlLCBrZXkpKSB7IHRhcmdldFtrZXldID0gc291cmNlW2tleV07IH0gfSB9IHJldHVybiB0YXJnZXQ7IH07XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uJyk7IH0gfVxuXG5mdW5jdGlvbiBfaW5oZXJpdHMoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSAnZnVuY3Rpb24nICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCAnICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfVxuXG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKCdyZWFjdCcpO1xuXG52YXIgQ29tcG9uZW50ID0gX3JlcXVpcmUuQ29tcG9uZW50O1xudmFyIFByb3BUeXBlcyA9IF9yZXF1aXJlLlByb3BUeXBlcztcblxudmFyIF9yZXF1aXJlMiA9IHJlcXVpcmUoJ21hdGVyaWFsLXVpJyk7XG5cbnZhciBGbGF0QnV0dG9uID0gX3JlcXVpcmUyLkZsYXRCdXR0b247XG5cbnZhciBfcmVxdWlyZTMgPSByZXF1aXJlKCdtYXRlcmlhbC11aS9zdHlsZXMnKTtcblxudmFyIG11aVRoZW1lYWJsZSA9IF9yZXF1aXJlMy5tdWlUaGVtZWFibGU7XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IGZ1bmN0aW9uIChQeWRpb0NvbXBvbmVudCwgZGlzcGxheU5hbWUpIHtcbiAgICB2YXIgZ3JpZERpbWVuc2lvbiA9IGFyZ3VtZW50cy5sZW5ndGggPD0gMiB8fCBhcmd1bWVudHNbMl0gPT09IHVuZGVmaW5lZCA/IHsgZ3JpZFdpZHRoOiA0LCBncmlkSGVpZ2h0OiAxMiB9IDogYXJndW1lbnRzWzJdO1xuICAgIHZhciBidWlsZGVyRmllbGRzID0gYXJndW1lbnRzLmxlbmd0aCA8PSAzIHx8IGFyZ3VtZW50c1szXSA9PT0gdW5kZWZpbmVkID8gdW5kZWZpbmVkIDogYXJndW1lbnRzWzNdO1xuXG4gICAgdmFyIG9yaWdpbmFsRGlzcGxheU5hbWUgPSBQeWRpb0NvbXBvbmVudC5kaXNwbGF5TmFtZSB8fCBQeWRpb0NvbXBvbmVudC5uYW1lO1xuICAgIFB5ZGlvQ29tcG9uZW50ID0gbXVpVGhlbWVhYmxlKCkoUHlkaW9Db21wb25lbnQpO1xuXG4gICAgdmFyIEdyaWRJdGVtID0gKGZ1bmN0aW9uIChfQ29tcG9uZW50KSB7XG4gICAgICAgIF9pbmhlcml0cyhHcmlkSXRlbSwgX0NvbXBvbmVudCk7XG5cbiAgICAgICAgZnVuY3Rpb24gR3JpZEl0ZW0ocHJvcHMsIGNvbnRleHQpIHtcbiAgICAgICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBHcmlkSXRlbSk7XG5cbiAgICAgICAgICAgIF9Db21wb25lbnQuY2FsbCh0aGlzLCBwcm9wcywgY29udGV4dCk7XG4gICAgICAgICAgICB0aGlzLnN0YXRlID0geyBmb2N1czogZmFsc2UsIHNob3dDbG9zZUFjdGlvbjogZmFsc2UgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIEdyaWRJdGVtLnByb3RvdHlwZS5mb2N1c0l0ZW0gPSBmdW5jdGlvbiBmb2N1c0l0ZW0oKSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgZm9jdXM6IHRydWUgfSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgR3JpZEl0ZW0ucHJvdG90eXBlLmJsdXJJdGVtID0gZnVuY3Rpb24gYmx1ckl0ZW0oKSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgZm9jdXM6IGZhbHNlIH0pO1xuICAgICAgICB9O1xuXG4gICAgICAgIEdyaWRJdGVtLnByb3RvdHlwZS5tZXJnZVN0eWxlV2l0aEZvY3VzID0gZnVuY3Rpb24gbWVyZ2VTdHlsZVdpdGhGb2N1cygpIHtcbiAgICAgICAgICAgIHJldHVybiBfZXh0ZW5kcyh7fSwgdGhpcy5wcm9wcy5zdHlsZSwgeyB6SW5kZXg6IHRoaXMuc3RhdGUuZm9jdXMgPyAxIDogbnVsbCB9KTtcbiAgICAgICAgfTtcblxuICAgICAgICBHcmlkSXRlbS5wcm90b3R5cGUudG9nZ2xlRWRpdE1vZGUgPSBmdW5jdGlvbiB0b2dnbGVFZGl0TW9kZSgpIHtcbiAgICAgICAgICAgIHZhciB2YWx1ZSA9IGFyZ3VtZW50cy5sZW5ndGggPD0gMCB8fCBhcmd1bWVudHNbMF0gPT09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6IGFyZ3VtZW50c1swXTtcblxuICAgICAgICAgICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgc2hvd0Nsb3NlQWN0aW9uOiAhKHRoaXMuc3RhdGUgJiYgdGhpcy5zdGF0ZS5zaG93Q2xvc2VBY3Rpb24pIH0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgc2hvd0Nsb3NlQWN0aW9uOiB2YWx1ZSB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICBHcmlkSXRlbS5wcm90b3R5cGUuZ2V0Q2xvc2VCdXR0b24gPSBmdW5jdGlvbiBnZXRDbG9zZUJ1dHRvbigpIHtcbiAgICAgICAgICAgIHZhciBjbG9zZUFjdGlvbiA9IHRoaXMucHJvcHMub25DbG9zZUFjdGlvbiB8fCBmdW5jdGlvbiAoKSB7fTtcbiAgICAgICAgICAgIHZhciBvdmVybGF5U3R5bGUgPSB7XG4gICAgICAgICAgICAgICAgcG9zaXRpb246ICdhYnNvbHV0ZScsXG4gICAgICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yOiAncmdiYSgwLDAsMCwwLjUzKScsXG4gICAgICAgICAgICAgICAgekluZGV4OiAxMCxcbiAgICAgICAgICAgICAgICB0b3A6IDAsXG4gICAgICAgICAgICAgICAgbGVmdDogMCxcbiAgICAgICAgICAgICAgICBib3R0b206IDAsXG4gICAgICAgICAgICAgICAgcmlnaHQ6IDAsXG4gICAgICAgICAgICAgICAgZGlzcGxheTogJ2ZsZXgnLFxuICAgICAgICAgICAgICAgIGFsaWduSXRlbXM6ICdjZW50ZXInLFxuICAgICAgICAgICAgICAgIGp1c3RpZnlDb250ZW50OiAnY2VudGVyJ1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgIHsgc3R5bGU6IG92ZXJsYXlTdHlsZSB9LFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoRmxhdEJ1dHRvbiwge1xuICAgICAgICAgICAgICAgICAgICBsYWJlbDogdGhpcy5wcm9wcy5weWRpby5NZXNzYWdlSGFzaFsnYWp4cF9hZG1pbi5ob21lLjQ4J10sXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogJ2NhcmQtY2xvc2UtYnV0dG9uJyxcbiAgICAgICAgICAgICAgICAgICAgb25Ub3VjaFRhcDogY2xvc2VBY3Rpb24sXG4gICAgICAgICAgICAgICAgICAgIHN0eWxlOiB7IGNvbG9yOiAnd2hpdGUnIH1cbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfTtcblxuICAgICAgICBHcmlkSXRlbS5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgICAgICAgdmFyIHByb3BzID0gX2V4dGVuZHMoe30sIHRoaXMucHJvcHMsIHtcbiAgICAgICAgICAgICAgICBzdHlsZTogdGhpcy5tZXJnZVN0eWxlV2l0aEZvY3VzKCksXG4gICAgICAgICAgICAgICAgY2xvc2VCdXR0b246IHRoaXMuc3RhdGUuc2hvd0Nsb3NlQWN0aW9uID8gdGhpcy5nZXRDbG9zZUJ1dHRvbigpIDogbnVsbCxcbiAgICAgICAgICAgICAgICBvbkZvY3VzSXRlbTogdGhpcy5mb2N1c0l0ZW0uYmluZCh0aGlzKSxcbiAgICAgICAgICAgICAgICBvbkJsdXJJdGVtOiB0aGlzLmJsdXJJdGVtLmJpbmQodGhpcylcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoUHlkaW9Db21wb25lbnQsIHByb3BzKTtcbiAgICAgICAgfTtcblxuICAgICAgICByZXR1cm4gR3JpZEl0ZW07XG4gICAgfSkoQ29tcG9uZW50KTtcblxuICAgIEdyaWRJdGVtLnByb3BUeXBlcyA9IHtcbiAgICAgICAgb25DbG9zZUFjdGlvbjogUHJvcFR5cGVzLmZ1bmNcbiAgICB9O1xuXG4gICAgR3JpZEl0ZW0uZGlzcGxheU5hbWUgPSBvcmlnaW5hbERpc3BsYXlOYW1lO1xuICAgIEdyaWRJdGVtLmJ1aWxkZXJEaXNwbGF5TmFtZSA9IGRpc3BsYXlOYW1lO1xuXG4gICAgR3JpZEl0ZW0uZ2V0R3JpZExheW91dCA9IGZ1bmN0aW9uICh4LCB5KSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB4OiB4IHx8IDAsXG4gICAgICAgICAgICB5OiB5IHx8IDAsXG4gICAgICAgICAgICB3OiBncmlkRGltZW5zaW9uLmdyaWRXaWR0aCB8fCA0LFxuICAgICAgICAgICAgaDogZ3JpZERpbWVuc2lvbi5ncmlkSGVpZ2h0IHx8IDEyLFxuICAgICAgICAgICAgaXNSZXNpemFibGU6IGZhbHNlXG4gICAgICAgIH07XG4gICAgfTtcblxuICAgIEdyaWRJdGVtLmhhc0J1aWxkZXJGaWVsZHMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBidWlsZGVyRmllbGRzICE9PSB1bmRlZmluZWQ7XG4gICAgfTtcbiAgICBHcmlkSXRlbS5nZXRCdWlsZGVyRmllbGRzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gYnVpbGRlckZpZWxkcztcbiAgICB9O1xuXG4gICAgcmV0dXJuIEdyaWRJdGVtO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMDctMjAxNyBDaGFybGVzIGR1IEpldSAtIEFic3RyaXVtIFNBUyA8dGVhbSAoYXQpIHB5ZC5pbz5cbiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIFB5ZGlvLlxuICpcbiAqIFB5ZGlvIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3JcbiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogUHlkaW8gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggUHlkaW8uICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gKlxuICogVGhlIGxhdGVzdCBjb2RlIGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9weWRpby5jb20+LlxuICovXG5cbi8qKlxuICogVHdvIGNvbHVtbnMgbGF5b3V0IHVzZWQgZm9yIFdvcmtzcGFjZXMgYW5kIFBsdWdpbnMgZWRpdG9yc1xuICovXG4ndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG52YXIgUGFwZXJFZGl0b3JMYXlvdXQgPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG4gICAgZGlzcGxheU5hbWU6ICdQYXBlckVkaXRvckxheW91dCcsXG5cbiAgICBwcm9wVHlwZXM6IHtcbiAgICAgICAgdGl0bGU6IFJlYWN0LlByb3BUeXBlcy5hbnksXG4gICAgICAgIHRpdGxlQWN0aW9uQmFyOiBSZWFjdC5Qcm9wVHlwZXMuYW55LFxuICAgICAgICBsZWZ0TmF2OiBSZWFjdC5Qcm9wVHlwZXMuYW55LFxuICAgICAgICBjb250ZW50RmlsbDogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXG4gICAgICAgIGNsYXNzTmFtZTogUmVhY3QuUHJvcFR5cGVzLnN0cmluZ1xuICAgIH0sXG5cbiAgICB0b2dnbGVNZW51OiBmdW5jdGlvbiB0b2dnbGVNZW51KCkge1xuICAgICAgICB2YXIgY3J0TGVmdE9wZW4gPSB0aGlzLnN0YXRlICYmIHRoaXMuc3RhdGUuZm9yY2VMZWZ0T3BlbjtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGZvcmNlTGVmdE9wZW46ICFjcnRMZWZ0T3BlbiB9KTtcbiAgICB9LFxuXG4gICAgcmVuZGVyOiBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICB7IGNsYXNzTmFtZTogXCJwYXBlci1lZGl0b3ItY29udGVudCBsYXlvdXQtZmlsbCB2ZXJ0aWNhbC1sYXlvdXRcIiArICh0aGlzLnByb3BzLmNsYXNzTmFtZSA/ICcgJyArIHRoaXMucHJvcHMuY2xhc3NOYW1lIDogJycpIH0sXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAncGFwZXItZWRpdG9yLXRpdGxlJyB9LFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICdoMicsXG4gICAgICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucHJvcHMudGl0bGUsXG4gICAgICAgICAgICAgICAgICAgICcgJyxcbiAgICAgICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6ICdsZWZ0LXBpY2tlci10b2dnbGUnIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFJlYWN0TVVJLkljb25CdXR0b24sIHsgaWNvbkNsYXNzTmFtZTogJ2ljb24tY2FyZXQtZG93bicsIG9uQ2xpY2s6IHRoaXMudG9nZ2xlTWVudSB9KVxuICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6ICd0aXRsZS1iYXInIH0sXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucHJvcHMudGl0bGVBY3Rpb25CYXJcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICApLFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ2xheW91dC1maWxsIG1haW4tbGF5b3V0LW5hdi10by1zdGFjaycgfSxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6IFwicGFwZXItZWRpdG9yLWxlZnRcIiArICh0aGlzLnN0YXRlICYmIHRoaXMuc3RhdGUuZm9yY2VMZWZ0T3BlbiA/ICcgcGlja2VyLW9wZW4nIDogJycpLCBvbkNsaWNrOiB0aGlzLnRvZ2dsZU1lbnUgfSxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5sZWZ0TmF2XG4gICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6IFwibGF5b3V0LWZpbGwgcGFwZXItZWRpdG9yLXJpZ2h0XCIgKyAodGhpcy5wcm9wcy5jb250ZW50RmlsbCA/ICcgdmVydGljYWwtbGF5b3V0JyA6ICcnKSwgc3R5bGU6IHRoaXMucHJvcHMuY29udGVudEZpbGwgPyB7fSA6IHsgb3ZlcmZsb3dZOiAnYXV0bycgfSB9LFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnByb3BzLmNoaWxkcmVuXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKVxuICAgICAgICApO1xuICAgIH1cbn0pO1xuLyoqXG4gKiBOYXZpZ2F0aW9uIHN1YmhlYWRlciB1c2VkIGJ5IFBhcGVyRWRpdG9yTGF5b3V0XG4gKi9cbnZhciBQYXBlckVkaXRvck5hdkhlYWRlciA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcbiAgICBkaXNwbGF5TmFtZTogJ1BhcGVyRWRpdG9yTmF2SGVhZGVyJyxcblxuICAgIHByb3BUeXBlczoge1xuICAgICAgICBsYWJlbDogUmVhY3QuUHJvcFR5cGVzLnN0cmluZ1xuICAgIH0sXG5cbiAgICByZW5kZXI6IGZ1bmN0aW9uIHJlbmRlcigpIHtcblxuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgeyBjbGFzc05hbWU6ICdtdWktc3ViaGVhZGVyJyB9LFxuICAgICAgICAgICAgdGhpcy5wcm9wcy5jaGlsZHJlbixcbiAgICAgICAgICAgIHRoaXMucHJvcHMubGFiZWxcbiAgICAgICAgKTtcbiAgICB9XG5cbn0pO1xuLyoqXG4gKiBOYXZpZ2F0aW9uIGVudHJ5IHVzZWQgYnkgUGFwZXJFZGl0b3JMYXlvdXQuXG4gKi9cbnZhciBQYXBlckVkaXRvck5hdkVudHJ5ID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuICAgIGRpc3BsYXlOYW1lOiAnUGFwZXJFZGl0b3JOYXZFbnRyeScsXG5cbiAgICBwcm9wVHlwZXM6IHtcbiAgICAgICAga2V5TmFtZTogUmVhY3QuUHJvcFR5cGVzLnN0cmluZy5pc1JlcXVpcmVkLFxuICAgICAgICBvbkNsaWNrOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYy5pc1JlcXVpcmVkLFxuICAgICAgICBsYWJlbDogUmVhY3QuUHJvcFR5cGVzLnN0cmluZyxcbiAgICAgICAgc2VsZWN0ZWRLZXk6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcsXG4gICAgICAgIGlzTGFzdDogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXG4gICAgICAgIC8vIERyb3AgRG93biBEYXRhXG4gICAgICAgIGRyb3BEb3duOiBSZWFjdC5Qcm9wVHlwZXMuYm9vbCxcbiAgICAgICAgZHJvcERvd25EYXRhOiBSZWFjdC5Qcm9wVHlwZXMub2JqZWN0LFxuICAgICAgICBkcm9wRG93bkNoYW5nZTogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsXG4gICAgICAgIGRyb3BEb3duRGVmYXVsdEl0ZW1zOiBSZWFjdC5Qcm9wVHlwZXMuYXJyYXlcbiAgICB9LFxuXG4gICAgb25DbGljazogZnVuY3Rpb24gb25DbGljaygpIHtcbiAgICAgICAgdGhpcy5wcm9wcy5vbkNsaWNrKHRoaXMucHJvcHMua2V5TmFtZSk7XG4gICAgfSxcblxuICAgIGNhcHR1cmVEcm9wRG93bkNsaWNrOiBmdW5jdGlvbiBjYXB0dXJlRHJvcERvd25DbGljaygpIHtcbiAgICAgICAgaWYgKHRoaXMucHJldmVudENsaWNrKSB7XG4gICAgICAgICAgICB0aGlzLnByZXZlbnRDbGljayA9IGZhbHNlO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucHJvcHMub25DbGljayh0aGlzLnByb3BzLmtleU5hbWUpO1xuICAgIH0sXG5cbiAgICBkcm9wRG93bkNoYW5nZTogZnVuY3Rpb24gZHJvcERvd25DaGFuZ2UoZXZlbnQsIGluZGV4LCBpdGVtKSB7XG4gICAgICAgIHRoaXMucHJldmVudENsaWNrID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5wcm9wcy5kcm9wRG93bkNoYW5nZShpdGVtKTtcbiAgICB9LFxuXG4gICAgcmVuZGVyOiBmdW5jdGlvbiByZW5kZXIoKSB7XG5cbiAgICAgICAgaWYgKCF0aGlzLnByb3BzLmRyb3BEb3duIHx8ICF0aGlzLnByb3BzLmRyb3BEb3duRGF0YSkge1xuICAgICAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU6ICdtZW51LWVudHJ5JyArICh0aGlzLnByb3BzLmtleU5hbWUgPT0gdGhpcy5wcm9wcy5zZWxlY3RlZEtleSA/ICcgbWVudS1lbnRyeS1zZWxlY3RlZCcgOiAnJykgKyAodGhpcy5wcm9wcy5pc0xhc3QgPyAnIGxhc3QnIDogJycpLFxuICAgICAgICAgICAgICAgICAgICBvbkNsaWNrOiB0aGlzLm9uQ2xpY2sgfSxcbiAgICAgICAgICAgICAgICB0aGlzLnByb3BzLmNoaWxkcmVuLFxuICAgICAgICAgICAgICAgIHRoaXMucHJvcHMubGFiZWxcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBkcm9wRG93biAmIGRyb3BEb3duRGF0YSBhcmUgbG9hZGVkXG4gICAgICAgIHZhciBtZW51SXRlbXNUcGwgPSBbeyB0ZXh0OiB0aGlzLnByb3BzLmxhYmVsLCBwYXlsb2FkOiAnLTEnIH1dO1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5kcm9wRG93bkRlZmF1bHRJdGVtcykge1xuICAgICAgICAgICAgbWVudUl0ZW1zVHBsID0gbWVudUl0ZW1zVHBsLmNvbmNhdCh0aGlzLnByb3BzLmRyb3BEb3duRGVmYXVsdEl0ZW1zKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnByb3BzLmRyb3BEb3duRGF0YS5mb3JFYWNoKGZ1bmN0aW9uICh2LCBrKSB7XG4gICAgICAgICAgICBtZW51SXRlbXNUcGwucHVzaCh7IHRleHQ6IHYubGFiZWwsIHBheWxvYWQ6IHYgfSk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgeyBvbkNsaWNrOiB0aGlzLmNhcHR1cmVEcm9wRG93bkNsaWNrLCBjbGFzc05hbWU6ICdtZW51LWVudHJ5LWRyb3Bkb3duJyArICh0aGlzLnByb3BzLmtleU5hbWUgPT0gdGhpcy5wcm9wcy5zZWxlY3RlZEtleSA/ICcgbWVudS1lbnRyeS1zZWxlY3RlZCcgOiAnJykgKyAodGhpcy5wcm9wcy5pc0xhc3QgPyAnIGxhc3QnIDogJycpIH0sXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFJlYWN0TVVJLkRyb3BEb3duTWVudSwge1xuICAgICAgICAgICAgICAgIG1lbnVJdGVtczogbWVudUl0ZW1zVHBsLFxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogJ2Ryb3Bkb3duLWZ1bGwtd2lkdGgnLFxuICAgICAgICAgICAgICAgIHN0eWxlOiB7IHdpZHRoOiAyNTYgfSxcbiAgICAgICAgICAgICAgICBhdXRvV2lkdGg6IGZhbHNlLFxuICAgICAgICAgICAgICAgIG9uQ2hhbmdlOiB0aGlzLmRyb3BEb3duQ2hhbmdlXG4gICAgICAgICAgICB9KVxuICAgICAgICApO1xuICAgIH1cbn0pO1xuXG5leHBvcnRzLlBhcGVyRWRpdG9yTGF5b3V0ID0gUGFwZXJFZGl0b3JMYXlvdXQ7XG5leHBvcnRzLlBhcGVyRWRpdG9yTmF2RW50cnkgPSBQYXBlckVkaXRvck5hdkVudHJ5O1xuZXhwb3J0cy5QYXBlckVkaXRvck5hdkhlYWRlciA9IFBhcGVyRWRpdG9yTmF2SGVhZGVyO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDA3LTIwMTcgQ2hhcmxlcyBkdSBKZXUgLSBBYnN0cml1bSBTQVMgPHRlYW0gKGF0KSBweWQuaW8+XG4gKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBQeWRpby5cbiAqXG4gKiBQeWRpbyBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFB5ZGlvIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIFB5ZGlvLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuICpcbiAqIFRoZSBsYXRlc3QgY29kZSBjYW4gYmUgZm91bmQgYXQgPGh0dHBzOi8vcHlkaW8uY29tPi5cbiAqL1xuXG5cInVzZSBzdHJpY3RcIjtcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKFwiQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uXCIpOyB9IH1cblxuZnVuY3Rpb24gX2luaGVyaXRzKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7IGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gXCJmdW5jdGlvblwiICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlN1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uLCBub3QgXCIgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5zZXRQcm90b3R5cGVPZihzdWJDbGFzcywgc3VwZXJDbGFzcykgOiBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9XG5cbnZhciBwcm9wVHlwZXMgPSB7XG4gICAgbm9kZTogUmVhY3QuUHJvcFR5cGVzLmluc3RhbmNlT2YoQWp4cE5vZGUpLmlzUmVxdWlyZWQsXG4gICAgcmVnaXN0cnk6IFJlYWN0LlByb3BUeXBlcy5pbnN0YW5jZU9mKFJlZ2lzdHJ5KS5pc1JlcXVpcmVkLFxuICAgIGVkaXRvckRhdGE6IFJlYWN0LlByb3BUeXBlcy5vYmplY3QuaXNSZXF1aXJlZCxcbiAgICBpY29uOiBSZWFjdC5Qcm9wVHlwZXMuYm9vbFxufTtcblxudmFyIGRlZmF1bHRQcm9wcyA9IHtcbiAgICBpY29uOiBmYWxzZVxufTtcblxudmFyIFJlYWN0RWRpdG9yT3BlbmVyID0gKGZ1bmN0aW9uIChfUmVhY3QkQ29tcG9uZW50KSB7XG4gICAgX2luaGVyaXRzKFJlYWN0RWRpdG9yT3BlbmVyLCBfUmVhY3QkQ29tcG9uZW50KTtcblxuICAgIGZ1bmN0aW9uIFJlYWN0RWRpdG9yT3BlbmVyKHByb3BzKSB7XG4gICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBSZWFjdEVkaXRvck9wZW5lcik7XG5cbiAgICAgICAgX1JlYWN0JENvbXBvbmVudC5jYWxsKHRoaXMsIHByb3BzKTtcblxuICAgICAgICB2YXIgbm9kZSA9IHByb3BzLm5vZGU7XG4gICAgICAgIHZhciBlZGl0b3JEYXRhID0gcHJvcHMuZWRpdG9yRGF0YTtcblxuICAgICAgICB0aGlzLnN0YXRlID0ge1xuICAgICAgICAgICAgcmVhZHk6IGZhbHNlXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgUmVhY3RFZGl0b3JPcGVuZXIucHJvdG90eXBlLmNvbXBvbmVudERpZE1vdW50ID0gZnVuY3Rpb24gY29tcG9uZW50RGlkTW91bnQoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICAgICAgdmFyIF9wcm9wcyA9IHRoaXMucHJvcHM7XG4gICAgICAgIHZhciBlZGl0b3JEYXRhID0gX3Byb3BzLmVkaXRvckRhdGE7XG4gICAgICAgIHZhciByZWdpc3RyeSA9IF9wcm9wcy5yZWdpc3RyeTtcblxuICAgICAgICByZWdpc3RyeS5sb2FkRWRpdG9yUmVzb3VyY2VzKGVkaXRvckRhdGEucmVzb3VyY2VzTWFuYWdlciwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIF90aGlzLnNldFN0YXRlKHsgcmVhZHk6IHRydWUgfSk7XG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICBSZWFjdEVkaXRvck9wZW5lci5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgICB2YXIgZWRpdG9yRGF0YSA9IHRoaXMucHJvcHMuZWRpdG9yRGF0YTtcbiAgICAgICAgdmFyIHJlYWR5ID0gdGhpcy5zdGF0ZS5yZWFkeTtcblxuICAgICAgICBpZiAoIXJlYWR5KSByZXR1cm4gbnVsbDtcblxuICAgICAgICB2YXIgRWRpdG9yQ2xhc3MgPSBudWxsO1xuICAgICAgICBpZiAoIShFZGl0b3JDbGFzcyA9IEZ1bmNVdGlscy5nZXRGdW5jdGlvbkJ5TmFtZShlZGl0b3JEYXRhLmVkaXRvckNsYXNzLCB3aW5kb3cpKSkge1xuICAgICAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgXCJkaXZcIixcbiAgICAgICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgICAgIFwiQ2Fubm90IGZpbmQgZWRpdG9yIGNvbXBvbmVudCAoXCIgKyBlZGl0b3JEYXRhLmVkaXRvckNsYXNzICsgXCIpIVwiXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gR2V0dGluZyBIT0Mgb2YgdGhlIGNsYXNzXG4gICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KEVkaXRvckNsYXNzLkVkaXRvciwgdGhpcy5wcm9wcyk7XG4gICAgfTtcblxuICAgIHJldHVybiBSZWFjdEVkaXRvck9wZW5lcjtcbn0pKFJlYWN0LkNvbXBvbmVudCk7XG5cblJlYWN0RWRpdG9yT3BlbmVyLnByb3BUeXBlcyA9IHByb3BUeXBlcztcblJlYWN0RWRpdG9yT3BlbmVyLmRlZmF1bHRQcm9wcyA9IGRlZmF1bHRQcm9wcztcblxuZXhwb3J0c1tcImRlZmF1bHRcIl0gPSBSZWFjdEVkaXRvck9wZW5lcjtcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1tcImRlZmF1bHRcIl07XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMDctMjAxNyBDaGFybGVzIGR1IEpldSAtIEFic3RyaXVtIFNBUyA8dGVhbSAoYXQpIHB5ZC5pbz5cbiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIFB5ZGlvLlxuICpcbiAqIFB5ZGlvIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3JcbiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogUHlkaW8gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggUHlkaW8uICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gKlxuICogVGhlIGxhdGVzdCBjb2RlIGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9weWRpby5jb20+LlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxudmFyIF9leHRlbmRzID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiAodGFyZ2V0KSB7IGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7IHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV07IGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHsgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHsgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTsgfSB9IH0gcmV0dXJuIHRhcmdldDsgfTtcblxuZXhwb3J0c1snZGVmYXVsdCddID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuICAgIGRpc3BsYXlOYW1lOiAnQ2xpcGJvYXJkVGV4dEZpZWxkJyxcblxuICAgIHByb3BUeXBlczoge1xuICAgICAgICBmbG9hdGluZ0xhYmVsVGV4dDogUmVhY3QuUHJvcFR5cGVzLnN0cmluZyxcblxuICAgICAgICBpbnB1dFZhbHVlOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLFxuICAgICAgICBpbnB1dENsYXNzTmFtZTogUmVhY3QuUHJvcFR5cGVzLnN0cmluZyxcbiAgICAgICAgZ2V0TWVzc2FnZTogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsXG4gICAgICAgIGlucHV0Q29weU1lc3NhZ2U6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmdcbiAgICB9LFxuXG4gICAgZ2V0SW5pdGlhbFN0YXRlOiBmdW5jdGlvbiBnZXRJbml0aWFsU3RhdGUoKSB7XG4gICAgICAgIHJldHVybiB7IGNvcHlNZXNzYWdlOiBudWxsIH07XG4gICAgfSxcblxuICAgIGNvbXBvbmVudERpZE1vdW50OiBmdW5jdGlvbiBjb21wb25lbnREaWRNb3VudCgpIHtcbiAgICAgICAgdGhpcy5hdHRhY2hDbGlwYm9hcmQoKTtcbiAgICB9LFxuICAgIGNvbXBvbmVudERpZFVwZGF0ZTogZnVuY3Rpb24gY29tcG9uZW50RGlkVXBkYXRlKCkge1xuICAgICAgICB0aGlzLmF0dGFjaENsaXBib2FyZCgpO1xuICAgIH0sXG5cbiAgICBhdHRhY2hDbGlwYm9hcmQ6IGZ1bmN0aW9uIGF0dGFjaENsaXBib2FyZCgpIHtcbiAgICAgICAgaWYgKHRoaXMuX2NsaXApIHtcbiAgICAgICAgICAgIHRoaXMuX2NsaXAuZGVzdHJveSgpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghdGhpcy5yZWZzWydjb3B5LWJ1dHRvbiddKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fY2xpcCA9IG5ldyBDbGlwYm9hcmQodGhpcy5yZWZzWydjb3B5LWJ1dHRvbiddLCB7XG4gICAgICAgICAgICB0ZXh0OiAoZnVuY3Rpb24gKHRyaWdnZXIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5wcm9wcy5pbnB1dFZhbHVlO1xuICAgICAgICAgICAgfSkuYmluZCh0aGlzKVxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5fY2xpcC5vbignc3VjY2VzcycsIChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgY29weU1lc3NhZ2U6IHRoaXMucHJvcHMuZ2V0TWVzc2FnZSh0aGlzLnByb3BzLmlucHV0Q29weU1lc3NhZ2UgfHwgJzE5MicpIH0sIHRoaXMuY2xlYXJDb3B5TWVzc2FnZSk7XG4gICAgICAgIH0pLmJpbmQodGhpcykpO1xuICAgICAgICB0aGlzLl9jbGlwLm9uKCdlcnJvcicsIChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgY29weU1lc3NhZ2U7XG4gICAgICAgICAgICBpZiAoZ2xvYmFsLm5hdmlnYXRvci5wbGF0Zm9ybS5pbmRleE9mKFwiTWFjXCIpID09PSAwKSB7XG4gICAgICAgICAgICAgICAgY29weU1lc3NhZ2UgPSB0aGlzLnByb3BzLmdldE1lc3NhZ2UoJzE0NCcpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb3B5TWVzc2FnZSA9IHRoaXMucHJvcHMuZ2V0TWVzc2FnZSgnMTQzJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnJlZnNbJ2lucHV0J10uZm9jdXMoKTtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBjb3B5TWVzc2FnZTogY29weU1lc3NhZ2UgfSwgdGhpcy5jbGVhckNvcHlNZXNzYWdlKTtcbiAgICAgICAgfSkuYmluZCh0aGlzKSk7XG4gICAgfSxcblxuICAgIGNsZWFyQ29weU1lc3NhZ2U6IGZ1bmN0aW9uIGNsZWFyQ29weU1lc3NhZ2UoKSB7XG4gICAgICAgIGdsb2JhbC5zZXRUaW1lb3V0KChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgY29weU1lc3NhZ2U6ICcnIH0pO1xuICAgICAgICB9KS5iaW5kKHRoaXMpLCAzMDAwKTtcbiAgICB9LFxuXG4gICAgcmVuZGVyOiBmdW5jdGlvbiByZW5kZXIoKSB7XG5cbiAgICAgICAgdmFyIHNlbGVjdCA9IGZ1bmN0aW9uIHNlbGVjdChlKSB7XG4gICAgICAgICAgICBlLmN1cnJlbnRUYXJnZXQuc2VsZWN0KCk7XG4gICAgICAgIH07XG5cbiAgICAgICAgdmFyIGNvcHlNZXNzYWdlID0gbnVsbDtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUuY29weU1lc3NhZ2UpIHtcbiAgICAgICAgICAgIHZhciBzZXRIdG1sID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4geyBfX2h0bWw6IHRoaXMuc3RhdGUuY29weU1lc3NhZ2UgfTtcbiAgICAgICAgICAgIH0pLmJpbmQodGhpcyk7XG4gICAgICAgICAgICBjb3B5TWVzc2FnZSA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoJ2RpdicsIHsgc3R5bGU6IHsgY29sb3I6ICdyZ2JhKDAsMCwwLDAuMjMpJyB9LCBjbGFzc05hbWU6ICdjb3B5LW1lc3NhZ2UnLCBkYW5nZXJvdXNseVNldElubmVySFRNTDogc2V0SHRtbCgpIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGJ1dHRvblN0eWxlID0gX2V4dGVuZHMoe1xuICAgICAgICAgICAgcG9zaXRpb246ICdhYnNvbHV0ZScsXG4gICAgICAgICAgICByaWdodDogLTgsXG4gICAgICAgICAgICBib3R0b206IDEzLFxuICAgICAgICAgICAgZm9udFNpemU6IDE1LFxuICAgICAgICAgICAgY29sb3I6IHRoaXMucHJvcHMuYnV0dG9uQ29sb3IgfHwgJ3JnYmEoMCwgMTUwLCAxMzYsIDAuNTIpJyxcbiAgICAgICAgICAgIGhlaWdodDogMjYsXG4gICAgICAgICAgICB3aWR0aDogMjYsXG4gICAgICAgICAgICBsaW5lSGVpZ2h0OiAnMjhweCcsXG4gICAgICAgICAgICB0ZXh0QWxpZ246ICdjZW50ZXInLFxuICAgICAgICAgICAgY3Vyc29yOiAncG9pbnRlcicsXG4gICAgICAgICAgICBib3JkZXJSYWRpdXM6ICc1MCUnXG4gICAgICAgIH0sIHRoaXMucHJvcHMuYnV0dG9uU3R5bGUpO1xuXG4gICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICB7IHN0eWxlOiB7IHBvc2l0aW9uOiAncmVsYXRpdmUnIH0gfSxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KE1hdGVyaWFsVUkuVGV4dEZpZWxkLCB7XG4gICAgICAgICAgICAgICAgICAgIGZ1bGxXaWR0aDogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgcmVmOiAnaW5wdXQnLFxuICAgICAgICAgICAgICAgICAgICBmbG9hdGluZ0xhYmVsVGV4dDogdGhpcy5wcm9wcy5mbG9hdGluZ0xhYmVsVGV4dCxcbiAgICAgICAgICAgICAgICAgICAgZmxvYXRpbmdMYWJlbFN0eWxlOiB7IHdoaXRlU3BhY2U6ICdub3dyYXAnIH0sXG4gICAgICAgICAgICAgICAgICAgIHVuZGVybGluZVNob3c6IHRoaXMucHJvcHMudW5kZXJsaW5lU2hvdyxcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdFZhbHVlOiB0aGlzLnByb3BzLmlucHV0VmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogdGhpcy5wcm9wcy5pbnB1dENsYXNzTmFtZSxcbiAgICAgICAgICAgICAgICAgICAgbXVsdGlMaW5lOiB0aGlzLnByb3BzLm11bHRpTGluZSxcbiAgICAgICAgICAgICAgICAgICAgcm93czogdGhpcy5wcm9wcy5yb3dzLFxuICAgICAgICAgICAgICAgICAgICByb3dzTWF4OiB0aGlzLnByb3BzLnJvd3NNYXgsXG4gICAgICAgICAgICAgICAgICAgIHJlYWRPbmx5OiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBvbkNsaWNrOiBzZWxlY3QsXG4gICAgICAgICAgICAgICAgICAgIHN0eWxlOiB7IG1hcmdpblRvcDogLTEwLCB3aWR0aDogJzkyJScsIGZvbnRTaXplOiAxNCB9XG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudCgnc3BhbicsIHsgcmVmOiAnY29weS1idXR0b24nLCBzdHlsZTogYnV0dG9uU3R5bGUsIHRpdGxlOiB0aGlzLnByb3BzLmdldE1lc3NhZ2UoJzE5MScpLCBjbGFzc05hbWU6ICdjb3B5LWJ1dHRvbiBtZGkgbWRpLWNvbnRlbnQtY29weScgfSlcbiAgICAgICAgICAgICksXG4gICAgICAgICAgICBjb3B5TWVzc2FnZVxuICAgICAgICApO1xuICAgIH1cblxufSk7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTtcbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDE3IENoYXJsZXMgZHUgSmV1IC0gQWJzdHJpdW0gU0FTIDx0ZWFtIChhdCkgcHlkLmlvPlxuICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgUHlkaW8uXG4gKlxuICogUHlkaW8gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBQeWRpbyBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCBQeWRpby4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAqXG4gKiBUaGUgbGF0ZXN0IGNvZGUgY2FuIGJlIGZvdW5kIGF0IDxodHRwczovL3B5ZGlvLmNvbT4uXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuZXhwb3J0c1snZGVmYXVsdCddID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuICAgIGRpc3BsYXlOYW1lOiAnTGFiZWxXaXRoVGlwJyxcblxuICAgIHByb3BUeXBlczoge1xuICAgICAgICBsYWJlbDogUmVhY3QuUHJvcFR5cGVzLnN0cmluZyxcbiAgICAgICAgbGFiZWxFbGVtZW50OiBSZWFjdC5Qcm9wVHlwZXMub2JqZWN0LFxuICAgICAgICB0b29sdGlwOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLFxuICAgICAgICB0b29sdGlwQ2xhc3NOYW1lOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLFxuICAgICAgICBjbGFzc05hbWU6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcsXG4gICAgICAgIHN0eWxlOiBSZWFjdC5Qcm9wVHlwZXMub2JqZWN0XG4gICAgfSxcblxuICAgIGdldEluaXRpYWxTdGF0ZTogZnVuY3Rpb24gZ2V0SW5pdGlhbFN0YXRlKCkge1xuICAgICAgICByZXR1cm4geyBzaG93OiBmYWxzZSB9O1xuICAgIH0sXG5cbiAgICBzaG93OiBmdW5jdGlvbiBzaG93KCkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgc2hvdzogdHJ1ZSB9KTtcbiAgICB9LFxuICAgIGhpZGU6IGZ1bmN0aW9uIGhpZGUoKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBzaG93OiBmYWxzZSB9KTtcbiAgICB9LFxuXG4gICAgcmVuZGVyOiBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgICAgIGlmICh0aGlzLnByb3BzLnRvb2x0aXApIHtcbiAgICAgICAgICAgIHZhciB0b29sdGlwU3R5bGUgPSB7fTtcbiAgICAgICAgICAgIGlmICh0aGlzLnByb3BzLmxhYmVsIHx8IHRoaXMucHJvcHMubGFiZWxFbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUuc2hvdykge1xuICAgICAgICAgICAgICAgICAgICB0b29sdGlwU3R5bGUgPSB7IGJvdHRvbTogLTEwLCB0b3A6ICdpbmhlcml0JyB9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdG9vbHRpcFN0eWxlID0geyBwb3NpdGlvbjogJ3JlbGF0aXZlJyB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIGxhYmVsID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgaWYgKHRoaXMucHJvcHMubGFiZWwpIHtcbiAgICAgICAgICAgICAgICBsYWJlbCA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICdzcGFuJyxcbiAgICAgICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6ICdlbGxpcHNpcy1sYWJlbCcgfSxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5sYWJlbFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMucHJvcHMubGFiZWxFbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgbGFiZWwgPSB0aGlzLnByb3BzLmxhYmVsRWxlbWVudDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBzdHlsZSA9IHRoaXMucHJvcHMuc3R5bGUgfHwgeyBwb3NpdGlvbjogJ3JlbGF0aXZlJyB9O1xuXG4gICAgICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAnc3BhbicsXG4gICAgICAgICAgICAgICAgeyBvbk1vdXNlRW50ZXI6IHRoaXMuc2hvdywgb25Nb3VzZUxlYXZlOiB0aGlzLmhpZGUsIHN0eWxlOiBzdHlsZSwgY2xhc3NOYW1lOiB0aGlzLnByb3BzLmNsYXNzTmFtZSB9LFxuICAgICAgICAgICAgICAgIGxhYmVsLFxuICAgICAgICAgICAgICAgIHRoaXMucHJvcHMuY2hpbGRyZW4sXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChSZWFjdE1VSS5Ub29sdGlwLCB7IGxhYmVsOiB0aGlzLnByb3BzLnRvb2x0aXAsIHN0eWxlOiB0b29sdGlwU3R5bGUsIGNsYXNzTmFtZTogdGhpcy5wcm9wcy50b29sdGlwQ2xhc3NOYW1lLCBzaG93OiB0aGlzLnN0YXRlLnNob3cgfSlcbiAgICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAodGhpcy5wcm9wcy5sYWJlbCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICAnc3BhbicsXG4gICAgICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucHJvcHMubGFiZWxcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLnByb3BzLmxhYmVsRWxlbWVudCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnByb3BzLmxhYmVsRWxlbWVudDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICdzcGFuJyxcbiAgICAgICAgICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5jaGlsZHJlblxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbn0pO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMDctMjAxNyBDaGFybGVzIGR1IEpldSAtIEFic3RyaXVtIFNBUyA8dGVhbSAoYXQpIHB5ZC5pbz5cbiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIFB5ZGlvLlxuICpcbiAqIFB5ZGlvIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3JcbiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogUHlkaW8gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggUHlkaW8uICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gKlxuICogVGhlIGxhdGVzdCBjb2RlIGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9weWRpby5jb20+LlxuICovXG5cbi8qKlxuICogU2ltcGxlIE11aVBhcGVyIHdpdGggYSBmaWd1cmUgYW5kIGEgbGVnZW5kXG4gKi9cbid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcbiAgICBkaXNwbGF5TmFtZTogJ1NpbXBsZUZpZ3VyZUJhZGdlJyxcblxuICAgIHByb3BUeXBlczoge1xuICAgICAgICBjb2xvckluZGljYXRvcjogUmVhY3QuUHJvcFR5cGVzLnN0cmluZyxcbiAgICAgICAgZmlndXJlOiBSZWFjdC5Qcm9wVHlwZXMubnVtYmVyLmlzUmVxdWlyZWQsXG4gICAgICAgIGxlZ2VuZDogUmVhY3QuUHJvcFR5cGVzLnN0cmluZ1xuICAgIH0sXG5cbiAgICBnZXREZWZhdWx0UHJvcHM6IGZ1bmN0aW9uIGdldERlZmF1bHRQcm9wcygpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNvbG9ySW5kaWNhdG9yOiAnJ1xuICAgICAgICB9O1xuICAgIH0sXG5cbiAgICByZW5kZXI6IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICBSZWFjdE1VSS5QYXBlcixcbiAgICAgICAgICAgIHsgc3R5bGU6IHsgZGlzcGxheTogJ2lubGluZS1ibG9jaycsIG1hcmdpbkxlZnQ6IDE2IH0gfSxcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6ICdmaWd1cmUtYmFkZ2UnLCBzdHlsZTogdGhpcy5wcm9wcy5jb2xvckluZGljYXRvciA/IHsgYm9yZGVyTGVmdENvbG9yOiB0aGlzLnByb3BzLmNvbG9ySW5kaWNhdG9yIH0gOiB7fSB9LFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ2ZpZ3VyZScgfSxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5maWd1cmVcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ2xlZ2VuZCcgfSxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5sZWdlbmRcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgfVxufSk7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTtcbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDE3IENoYXJsZXMgZHUgSmV1IC0gQWJzdHJpdW0gU0FTIDx0ZWFtIChhdCkgcHlkLmlvPlxuICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgUHlkaW8uXG4gKlxuICogUHlkaW8gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBQeWRpbyBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCBQeWRpby4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAqXG4gKiBUaGUgbGF0ZXN0IGNvZGUgY2FuIGJlIGZvdW5kIGF0IDxodHRwczovL3B5ZGlvLmNvbT4uXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyAnZGVmYXVsdCc6IG9iaiB9OyB9XG5cbnZhciBfbGlzdFNvcnRhYmxlTGlzdCA9IHJlcXVpcmUoJy4vbGlzdC9Tb3J0YWJsZUxpc3QnKTtcblxudmFyIF9saXN0U29ydGFibGVMaXN0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2xpc3RTb3J0YWJsZUxpc3QpO1xuXG52YXIgX2xpc3RTaW1wbGVMaXN0ID0gcmVxdWlyZSgnLi9saXN0L1NpbXBsZUxpc3QnKTtcblxudmFyIF9saXN0U2ltcGxlTGlzdDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9saXN0U2ltcGxlTGlzdCk7XG5cbnZhciBfbGlzdE5vZGVMaXN0Q3VzdG9tUHJvdmlkZXIgPSByZXF1aXJlKCcuL2xpc3QvTm9kZUxpc3RDdXN0b21Qcm92aWRlcicpO1xuXG52YXIgX2xpc3ROb2RlTGlzdEN1c3RvbVByb3ZpZGVyMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2xpc3ROb2RlTGlzdEN1c3RvbVByb3ZpZGVyKTtcblxudmFyIF9saXN0TGlzdEVudHJ5ID0gcmVxdWlyZSgnLi9saXN0L0xpc3RFbnRyeScpO1xuXG52YXIgX2xpc3RMaXN0UGFnaW5hdG9yID0gcmVxdWlyZSgnLi9saXN0L0xpc3RQYWdpbmF0b3InKTtcblxudmFyIF9saXN0TGlzdFBhZ2luYXRvcjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9saXN0TGlzdFBhZ2luYXRvcik7XG5cbnZhciBfdmlld3NUcmVlVmlldyA9IHJlcXVpcmUoJy4vdmlld3MvVHJlZVZpZXcnKTtcblxudmFyIF9lbGVtZW50c0xhYmVsV2l0aFRpcCA9IHJlcXVpcmUoJy4vZWxlbWVudHMvTGFiZWxXaXRoVGlwJyk7XG5cbnZhciBfZWxlbWVudHNMYWJlbFdpdGhUaXAyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfZWxlbWVudHNMYWJlbFdpdGhUaXApO1xuXG52YXIgX2VsZW1lbnRzU2ltcGxlRmlndXJlQmFkZ2UgPSByZXF1aXJlKCcuL2VsZW1lbnRzL1NpbXBsZUZpZ3VyZUJhZGdlJyk7XG5cbnZhciBfZWxlbWVudHNTaW1wbGVGaWd1cmVCYWRnZTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9lbGVtZW50c1NpbXBsZUZpZ3VyZUJhZGdlKTtcblxudmFyIF92aWV3c1NlYXJjaEJveCA9IHJlcXVpcmUoJy4vdmlld3MvU2VhcmNoQm94Jyk7XG5cbnZhciBfdmlld3NTZWFyY2hCb3gyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfdmlld3NTZWFyY2hCb3gpO1xuXG52YXIgX2VsZW1lbnRzQ2xpcGJvYXJkVGV4dEZpZWxkID0gcmVxdWlyZSgnLi9lbGVtZW50cy9DbGlwYm9hcmRUZXh0RmllbGQnKTtcblxudmFyIF9lbGVtZW50c0NsaXBib2FyZFRleHRGaWVsZDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9lbGVtZW50c0NsaXBib2FyZFRleHRGaWVsZCk7XG5cbnZhciBfdmlld3NFbXB0eVN0YXRlVmlldyA9IHJlcXVpcmUoJy4vdmlld3MvRW1wdHlTdGF0ZVZpZXcnKTtcblxudmFyIF92aWV3c0VtcHR5U3RhdGVWaWV3MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3ZpZXdzRW1wdHlTdGF0ZVZpZXcpO1xuXG52YXIgX3ZpZXdzTW9kYWxBcHBCYXIgPSByZXF1aXJlKCcuL3ZpZXdzL01vZGFsQXBwQmFyJyk7XG5cbnZhciBfdmlld3NNb2RhbEFwcEJhcjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF92aWV3c01vZGFsQXBwQmFyKTtcblxudmFyIF9lZGl0b3JSZWFjdEVkaXRvck9wZW5lciA9IHJlcXVpcmUoJy4vZWRpdG9yL1JlYWN0RWRpdG9yT3BlbmVyJyk7XG5cbnZhciBfZWRpdG9yUmVhY3RFZGl0b3JPcGVuZXIyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfZWRpdG9yUmVhY3RFZGl0b3JPcGVuZXIpO1xuXG52YXIgX2VkaXRvclBhcGVyRWRpdG9yID0gcmVxdWlyZSgnLi9lZGl0b3IvUGFwZXJFZGl0b3InKTtcblxudmFyIF9keW5hbWljR3JpZER5bmFtaWNHcmlkID0gcmVxdWlyZSgnLi9keW5hbWljLWdyaWQvRHluYW1pY0dyaWQnKTtcblxudmFyIF9keW5hbWljR3JpZER5bmFtaWNHcmlkMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2R5bmFtaWNHcmlkRHluYW1pY0dyaWQpO1xuXG52YXIgX2R5bmFtaWNHcmlkU3RvcmUgPSByZXF1aXJlKCcuL2R5bmFtaWMtZ3JpZC9TdG9yZScpO1xuXG52YXIgX2R5bmFtaWNHcmlkU3RvcmUyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfZHluYW1pY0dyaWRTdG9yZSk7XG5cbnZhciBfZHluYW1pY0dyaWRHcmlkSXRlbU1peGluID0gcmVxdWlyZSgnLi9keW5hbWljLWdyaWQvR3JpZEl0ZW1NaXhpbicpO1xuXG52YXIgX2R5bmFtaWNHcmlkR3JpZEl0ZW1NaXhpbjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9keW5hbWljR3JpZEdyaWRJdGVtTWl4aW4pO1xuXG52YXIgX2R5bmFtaWNHcmlkQXNHcmlkSXRlbSA9IHJlcXVpcmUoJy4vZHluYW1pYy1ncmlkL2FzR3JpZEl0ZW0nKTtcblxudmFyIF9keW5hbWljR3JpZEFzR3JpZEl0ZW0yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfZHluYW1pY0dyaWRBc0dyaWRJdGVtKTtcblxudmFyIF91dGlsRE5EID0gcmVxdWlyZSgnLi91dGlsL0RORCcpO1xuXG52YXIgX3VzZXJzQXZhdGFyVXNlckF2YXRhciA9IHJlcXVpcmUoJy4vdXNlcnMvYXZhdGFyL1VzZXJBdmF0YXInKTtcblxudmFyIF91c2Vyc0F2YXRhclVzZXJBdmF0YXIyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfdXNlcnNBdmF0YXJVc2VyQXZhdGFyKTtcblxudmFyIF91c2Vyc1VzZXJzQ29tcGxldGVyID0gcmVxdWlyZSgnLi91c2Vycy9Vc2Vyc0NvbXBsZXRlcicpO1xuXG52YXIgX3VzZXJzVXNlcnNDb21wbGV0ZXIyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfdXNlcnNVc2Vyc0NvbXBsZXRlcik7XG5cbnZhciBfdXNlcnNUZWFtQ3JlYXRpb25Gb3JtID0gcmVxdWlyZSgnLi91c2Vycy9UZWFtQ3JlYXRpb25Gb3JtJyk7XG5cbnZhciBfdXNlcnNUZWFtQ3JlYXRpb25Gb3JtMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3VzZXJzVGVhbUNyZWF0aW9uRm9ybSk7XG5cbnZhciBfbWVudUJ1dHRvbk1lbnUgPSByZXF1aXJlKCcuL21lbnUvQnV0dG9uTWVudScpO1xuXG52YXIgX21lbnVCdXR0b25NZW51MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX21lbnVCdXR0b25NZW51KTtcblxudmFyIF9tZW51Q29udGV4dE1lbnUgPSByZXF1aXJlKCcuL21lbnUvQ29udGV4dE1lbnUnKTtcblxudmFyIF9tZW51Q29udGV4dE1lbnUyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfbWVudUNvbnRleHRNZW51KTtcblxudmFyIF9tZW51SWNvbkJ1dHRvbk1lbnUgPSByZXF1aXJlKCcuL21lbnUvSWNvbkJ1dHRvbk1lbnUnKTtcblxudmFyIF9tZW51SWNvbkJ1dHRvbk1lbnUyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfbWVudUljb25CdXR0b25NZW51KTtcblxudmFyIF9tZW51VG9vbGJhciA9IHJlcXVpcmUoJy4vbWVudS9Ub29sYmFyJyk7XG5cbnZhciBfbWVudVRvb2xiYXIyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfbWVudVRvb2xiYXIpO1xuXG52YXIgX3VzZXJzQWRkcmVzc2Jvb2tBZGRyZXNzQm9vayA9IHJlcXVpcmUoJy4vdXNlcnMvYWRkcmVzc2Jvb2svQWRkcmVzc0Jvb2snKTtcblxudmFyIF91c2Vyc0FkZHJlc3Nib29rQWRkcmVzc0Jvb2syID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfdXNlcnNBZGRyZXNzYm9va0FkZHJlc3NCb29rKTtcblxudmFyIFB5ZGlvQ29tcG9uZW50cyA9IHtcblxuICAgIFNvcnRhYmxlTGlzdDogX2xpc3RTb3J0YWJsZUxpc3QyWydkZWZhdWx0J10sXG4gICAgU2ltcGxlTGlzdDogX2xpc3RTaW1wbGVMaXN0MlsnZGVmYXVsdCddLFxuICAgIE5vZGVMaXN0Q3VzdG9tUHJvdmlkZXI6IF9saXN0Tm9kZUxpc3RDdXN0b21Qcm92aWRlcjJbJ2RlZmF1bHQnXSxcbiAgICBMaXN0RW50cnk6IF9saXN0TGlzdEVudHJ5Lkxpc3RFbnRyeSxcbiAgICBMaXN0UGFnaW5hdG9yOiBfbGlzdExpc3RQYWdpbmF0b3IyWydkZWZhdWx0J10sXG5cbiAgICBUcmVlVmlldzogX3ZpZXdzVHJlZVZpZXcuVHJlZVZpZXcsXG4gICAgRE5EVHJlZVZpZXc6IF92aWV3c1RyZWVWaWV3LkRORFRyZWVWaWV3LFxuICAgIEZvbGRlcnNUcmVlOiBfdmlld3NUcmVlVmlldy5Gb2xkZXJzVHJlZSxcbiAgICBDbGlwYm9hcmRUZXh0RmllbGQ6IF9lbGVtZW50c0NsaXBib2FyZFRleHRGaWVsZDJbJ2RlZmF1bHQnXSxcbiAgICBMYWJlbFdpdGhUaXA6IF9lbGVtZW50c0xhYmVsV2l0aFRpcDJbJ2RlZmF1bHQnXSxcbiAgICBFbXB0eVN0YXRlVmlldzogX3ZpZXdzRW1wdHlTdGF0ZVZpZXcyWydkZWZhdWx0J10sXG4gICAgU2ltcGxlRmlndXJlQmFkZ2U6IF9lbGVtZW50c1NpbXBsZUZpZ3VyZUJhZGdlMlsnZGVmYXVsdCddLFxuICAgIFNlYXJjaEJveDogX3ZpZXdzU2VhcmNoQm94MlsnZGVmYXVsdCddLFxuICAgIE1vZGFsQXBwQmFyOiBfdmlld3NNb2RhbEFwcEJhcjJbJ2RlZmF1bHQnXSxcblxuICAgIFJlYWN0RWRpdG9yT3BlbmVyOiBfZWRpdG9yUmVhY3RFZGl0b3JPcGVuZXIyWydkZWZhdWx0J10sXG4gICAgUGFwZXJFZGl0b3JMYXlvdXQ6IF9lZGl0b3JQYXBlckVkaXRvci5QYXBlckVkaXRvckxheW91dCxcbiAgICBQYXBlckVkaXRvck5hdkVudHJ5OiBfZWRpdG9yUGFwZXJFZGl0b3IuUGFwZXJFZGl0b3JOYXZFbnRyeSxcbiAgICBQYXBlckVkaXRvck5hdkhlYWRlcjogX2VkaXRvclBhcGVyRWRpdG9yLlBhcGVyRWRpdG9yTmF2SGVhZGVyLFxuXG4gICAgRHluYW1pY0dyaWQ6IF9keW5hbWljR3JpZER5bmFtaWNHcmlkMlsnZGVmYXVsdCddLFxuICAgIER5bmFtaWNHcmlkSXRlbU1peGluOiBfZHluYW1pY0dyaWRHcmlkSXRlbU1peGluMlsnZGVmYXVsdCddLFxuICAgIGFzR3JpZEl0ZW06IF9keW5hbWljR3JpZEFzR3JpZEl0ZW0yWydkZWZhdWx0J10sXG4gICAgRHluYW1pY0dyaWRTdG9yZTogX2R5bmFtaWNHcmlkU3RvcmUyWydkZWZhdWx0J10sXG5cbiAgICBETkQ6IHtcbiAgICAgICAgVHlwZXM6IF91dGlsRE5ELlR5cGVzLCBjb2xsZWN0OiBfdXRpbERORC5jb2xsZWN0LCBjb2xsZWN0RHJvcDogX3V0aWxETkQuY29sbGVjdERyb3AsIG5vZGVEcmFnU291cmNlOiBfdXRpbERORC5ub2RlRHJhZ1NvdXJjZSwgbm9kZURyb3BUYXJnZXQ6IF91dGlsRE5ELm5vZGVEcm9wVGFyZ2V0LCBETkRBY3Rpb25QYXJhbWV0ZXI6IF91dGlsRE5ELkROREFjdGlvblBhcmFtZXRlclxuICAgIH0sXG4gICAgRE5EQWN0aW9uUGFyYW1ldGVyOiBfdXRpbERORC5ETkRBY3Rpb25QYXJhbWV0ZXIsXG5cbiAgICBVc2VyQXZhdGFyOiBfdXNlcnNBdmF0YXJVc2VyQXZhdGFyMlsnZGVmYXVsdCddLFxuICAgIFVzZXJzQ29tcGxldGVyOiBfdXNlcnNVc2Vyc0NvbXBsZXRlcjJbJ2RlZmF1bHQnXSxcbiAgICBUZWFtQ3JlYXRpb25Gb3JtOiBfdXNlcnNUZWFtQ3JlYXRpb25Gb3JtMlsnZGVmYXVsdCddLFxuICAgIEFkZHJlc3NCb29rOiBfdXNlcnNBZGRyZXNzYm9va0FkZHJlc3NCb29rMlsnZGVmYXVsdCddLFxuXG4gICAgQ29udGV4dE1lbnU6IF9tZW51Q29udGV4dE1lbnUyWydkZWZhdWx0J10sXG4gICAgVG9vbGJhcjogX21lbnVUb29sYmFyMlsnZGVmYXVsdCddLFxuICAgIEJ1dHRvbk1lbnU6IF9tZW51QnV0dG9uTWVudTJbJ2RlZmF1bHQnXSxcbiAgICBJY29uQnV0dG9uTWVudTogX21lbnVJY29uQnV0dG9uTWVudTJbJ2RlZmF1bHQnXVxufTtcblxuZXhwb3J0c1snZGVmYXVsdCddID0gUHlkaW9Db21wb25lbnRzO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMDctMjAxNyBDaGFybGVzIGR1IEpldSAtIEFic3RyaXVtIFNBUyA8dGVhbSAoYXQpIHB5ZC5pbz5cbiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIFB5ZGlvLlxuICpcbiAqIFB5ZGlvIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3JcbiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogUHlkaW8gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggUHlkaW8uICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gKlxuICogVGhlIGxhdGVzdCBjb2RlIGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9weWRpby5jb20+LlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxudmFyIF9leHRlbmRzID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiAodGFyZ2V0KSB7IGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7IHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV07IGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHsgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHsgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTsgfSB9IH0gcmV0dXJuIHRhcmdldDsgfTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgJ2RlZmF1bHQnOiBvYmogfTsgfVxuXG52YXIgX3JlYWN0ID0gcmVxdWlyZSgncmVhY3QnKTtcblxudmFyIF9yZWFjdDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9yZWFjdCk7XG5cbnZhciBfTGlzdEVudHJ5Tm9kZUxpc3RlbmVyTWl4aW4gPSByZXF1aXJlKCcuL0xpc3RFbnRyeU5vZGVMaXN0ZW5lck1peGluJyk7XG5cbnZhciBfTGlzdEVudHJ5Tm9kZUxpc3RlbmVyTWl4aW4yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfTGlzdEVudHJ5Tm9kZUxpc3RlbmVyTWl4aW4pO1xuXG52YXIgX0lubGluZUVkaXRvciA9IHJlcXVpcmUoJy4vSW5saW5lRWRpdG9yJyk7XG5cbnZhciBfSW5saW5lRWRpdG9yMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX0lubGluZUVkaXRvcik7XG5cbnZhciBfTGlzdEVudHJ5ID0gcmVxdWlyZSgnLi9MaXN0RW50cnknKTtcblxudmFyIF9tYXRlcmlhbFVpID0gcmVxdWlyZSgnbWF0ZXJpYWwtdWknKTtcblxuLyoqXG4gKiBDYWxsYmFjayBiYXNlZCBtYXRlcmlhbCBsaXN0IGVudHJ5IHdpdGggY3VzdG9tIGljb24gcmVuZGVyLCBmaXJzdExpbmUsIHNlY29uZExpbmUsIGV0Yy5cbiAqL1xuZXhwb3J0c1snZGVmYXVsdCddID0gX3JlYWN0MlsnZGVmYXVsdCddLmNyZWF0ZUNsYXNzKHtcbiAgICBkaXNwbGF5TmFtZTogJ0NvbmZpZ3VyYWJsZUxpc3RFbnRyeScsXG5cbiAgICBtaXhpbnM6IFtfTGlzdEVudHJ5Tm9kZUxpc3RlbmVyTWl4aW4yWydkZWZhdWx0J11dLFxuXG4gICAgcHJvcFR5cGVzOiB7XG4gICAgICAgIG5vZGU6IF9yZWFjdDJbJ2RlZmF1bHQnXS5Qcm9wVHlwZXMuaW5zdGFuY2VPZihBanhwTm9kZSksXG4gICAgICAgIC8vIFNFRSBBTFNPIExpc3RFbnRyeSBQUk9QU1xuICAgICAgICByZW5kZXJJY29uOiBfcmVhY3QyWydkZWZhdWx0J10uUHJvcFR5cGVzLmZ1bmMsXG4gICAgICAgIHJlbmRlckZpcnN0TGluZTogX3JlYWN0MlsnZGVmYXVsdCddLlByb3BUeXBlcy5mdW5jLFxuICAgICAgICByZW5kZXJTZWNvbmRMaW5lOiBfcmVhY3QyWydkZWZhdWx0J10uUHJvcFR5cGVzLmZ1bmMsXG4gICAgICAgIHJlbmRlclRoaXJkTGluZTogX3JlYWN0MlsnZGVmYXVsdCddLlByb3BUeXBlcy5mdW5jLFxuICAgICAgICByZW5kZXJBY3Rpb25zOiBfcmVhY3QyWydkZWZhdWx0J10uUHJvcFR5cGVzLmZ1bmMsXG4gICAgICAgIHN0eWxlOiBfcmVhY3QyWydkZWZhdWx0J10uUHJvcFR5cGVzLm9iamVjdFxuICAgIH0sXG5cbiAgICByZW5kZXI6IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgICAgICB2YXIgaWNvbiA9IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGZpcnN0TGluZSA9IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIHNlY29uZExpbmUgPSB1bmRlZmluZWQsXG4gICAgICAgICAgICB0aGlyZExpbmUgPSB1bmRlZmluZWQsXG4gICAgICAgICAgICBzdHlsZSA9IHRoaXMucHJvcHMuc3R5bGUgfHwge307XG4gICAgICAgIGlmICh0aGlzLnByb3BzLnJlbmRlckljb24pIHtcbiAgICAgICAgICAgIGljb24gPSB0aGlzLnByb3BzLnJlbmRlckljb24odGhpcy5wcm9wcy5ub2RlLCB0aGlzLnByb3BzKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHZhciBub2RlID0gdGhpcy5wcm9wcy5ub2RlO1xuICAgICAgICAgICAgdmFyIGljb25DbGFzcyA9IG5vZGUuZ2V0TWV0YWRhdGEoKS5nZXQoXCJpY29uX2NsYXNzXCIpID8gbm9kZS5nZXRNZXRhZGF0YSgpLmdldChcImljb25fY2xhc3NcIikgOiBub2RlLmlzTGVhZigpID8gXCJpY29uLWZpbGUtYWx0XCIgOiBcImljb24tZm9sZGVyLWNsb3NlXCI7XG4gICAgICAgICAgICBpY29uID0gX3JlYWN0MlsnZGVmYXVsdCddLmNyZWF0ZUVsZW1lbnQoX21hdGVyaWFsVWkuRm9udEljb24sIHsgY2xhc3NOYW1lOiBpY29uQ2xhc3MgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5wcm9wcy5yZW5kZXJGaXJzdExpbmUpIHtcbiAgICAgICAgICAgIGZpcnN0TGluZSA9IHRoaXMucHJvcHMucmVuZGVyRmlyc3RMaW5lKHRoaXMucHJvcHMubm9kZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmaXJzdExpbmUgPSB0aGlzLnByb3BzLm5vZGUuZ2V0TGFiZWwoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5zdGF0ZSAmJiB0aGlzLnN0YXRlLmlubGluZUVkaXRpb24pIHtcbiAgICAgICAgICAgIGZpcnN0TGluZSA9IF9yZWFjdDJbJ2RlZmF1bHQnXS5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICdzcGFuJyxcbiAgICAgICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgICAgIF9yZWFjdDJbJ2RlZmF1bHQnXS5jcmVhdGVFbGVtZW50KF9JbmxpbmVFZGl0b3IyWydkZWZhdWx0J10sIHtcbiAgICAgICAgICAgICAgICAgICAgbm9kZTogdGhpcy5wcm9wcy5ub2RlLFxuICAgICAgICAgICAgICAgICAgICBvbkNsb3NlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBfdGhpcy5zZXRTdGF0ZSh7IGlubGluZUVkaXRpb246IGZhbHNlIH0pO1xuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBjYWxsYmFjazogdGhpcy5zdGF0ZS5pbmxpbmVFZGl0aW9uQ2FsbGJhY2tcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICBmaXJzdExpbmVcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBzdHlsZS5wb3NpdGlvbiA9ICdyZWxhdGl2ZSc7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMucHJvcHMucmVuZGVyU2Vjb25kTGluZSkge1xuICAgICAgICAgICAgc2Vjb25kTGluZSA9IHRoaXMucHJvcHMucmVuZGVyU2Vjb25kTGluZSh0aGlzLnByb3BzLm5vZGUpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnByb3BzLnJlbmRlclRoaXJkTGluZSkge1xuICAgICAgICAgICAgdGhpcmRMaW5lID0gdGhpcy5wcm9wcy5yZW5kZXJUaGlyZExpbmUodGhpcy5wcm9wcy5ub2RlKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgYWN0aW9ucyA9IHRoaXMucHJvcHMuYWN0aW9ucztcbiAgICAgICAgaWYgKHRoaXMucHJvcHMucmVuZGVyQWN0aW9ucykge1xuICAgICAgICAgICAgYWN0aW9ucyA9IHRoaXMucHJvcHMucmVuZGVyQWN0aW9ucyh0aGlzLnByb3BzLm5vZGUpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIF9yZWFjdDJbJ2RlZmF1bHQnXS5jcmVhdGVFbGVtZW50KF9MaXN0RW50cnkuRHJhZ0Ryb3BMaXN0RW50cnksIF9leHRlbmRzKHt9LCB0aGlzLnByb3BzLCB7XG4gICAgICAgICAgICBpY29uQ2VsbDogaWNvbixcbiAgICAgICAgICAgIGZpcnN0TGluZTogZmlyc3RMaW5lLFxuICAgICAgICAgICAgc2Vjb25kTGluZTogc2Vjb25kTGluZSxcbiAgICAgICAgICAgIHRoaXJkTGluZTogdGhpcmRMaW5lLFxuICAgICAgICAgICAgYWN0aW9uczogYWN0aW9ucyxcbiAgICAgICAgICAgIHN0eWxlOiBzdHlsZVxuICAgICAgICB9KSk7XG4gICAgfVxuXG59KTtcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDA3LTIwMTcgQ2hhcmxlcyBkdSBKZXUgLSBBYnN0cml1bSBTQVMgPHRlYW0gKGF0KSBweWQuaW8+XG4gKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBQeWRpby5cbiAqXG4gKiBQeWRpbyBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFB5ZGlvIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIFB5ZGlvLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuICpcbiAqIFRoZSBsYXRlc3QgY29kZSBjYW4gYmUgZm91bmQgYXQgPGh0dHBzOi8vcHlkaW8uY29tPi5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG52YXIgUmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpO1xudmFyIFB5ZGlvID0gcmVxdWlyZSgncHlkaW8nKTtcbnZhciBBanhwTm9kZSA9IHJlcXVpcmUoJ3B5ZGlvL21vZGVsL25vZGUnKTtcblxudmFyIF9QeWRpbyRyZXF1aXJlTGliID0gUHlkaW8ucmVxdWlyZUxpYignYm9vdCcpO1xuXG52YXIgUHlkaW9Db250ZXh0Q29uc3VtZXIgPSBfUHlkaW8kcmVxdWlyZUxpYi5QeWRpb0NvbnRleHRDb25zdW1lcjtcblxudmFyIF9yZXF1aXJlID0gcmVxdWlyZSgnbWF0ZXJpYWwtdWknKTtcblxudmFyIFBhcGVyID0gX3JlcXVpcmUuUGFwZXI7XG52YXIgVGV4dEZpZWxkID0gX3JlcXVpcmUuVGV4dEZpZWxkO1xudmFyIEZsYXRCdXR0b24gPSBfcmVxdWlyZS5GbGF0QnV0dG9uO1xuXG52YXIgSW5saW5lRWRpdG9yID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuICAgIGRpc3BsYXlOYW1lOiAnSW5saW5lRWRpdG9yJyxcblxuICAgIHByb3BUeXBlczoge1xuICAgICAgICBub2RlOiBSZWFjdC5Qcm9wVHlwZXMuaW5zdGFuY2VPZihBanhwTm9kZSksXG4gICAgICAgIGNhbGxiYWNrOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgICAgICAgb25DbG9zZTogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsXG4gICAgICAgIGRldGFjaGVkOiBSZWFjdC5Qcm9wVHlwZXMuYm9vbFxuICAgIH0sXG5cbiAgICBzdWJtaXQ6IGZ1bmN0aW9uIHN1Ym1pdCgpIHtcbiAgICAgICAgaWYgKCF0aGlzLnN0YXRlIHx8ICF0aGlzLnN0YXRlLnZhbHVlIHx8IHRoaXMuc3RhdGUudmFsdWUgPT09IHRoaXMucHJvcHMubm9kZS5nZXRMYWJlbCgpKSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgZXJyb3JTdHJpbmc6ICdQbGVhc2UgdXNlIGEgZGlmZmVyZW50IHZhbHVlIGZvciByZW5hbWluZyEnIH0pO1xuICAgICAgICAgICAgdGhpcy5wcm9wcy5nZXRQeWRpbygpLmRpc3BsYXlNZXNzYWdlKCdFUlJPUicsICdQbGVhc2UgdXNlIGEgZGlmZmVyZW50IHZhbHVlIGZvciByZW5hbWluZyEnKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMucHJvcHMuY2FsbGJhY2sodGhpcy5zdGF0ZS52YWx1ZSk7XG4gICAgICAgICAgICB0aGlzLnByb3BzLm9uQ2xvc2UoKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBjb21wb25lbnREaWRNb3VudDogZnVuY3Rpb24gY29tcG9uZW50RGlkTW91bnQoKSB7XG4gICAgICAgIHRoaXMucmVmcy50ZXh0LmZvY3VzKCk7XG4gICAgfSxcblxuICAgIGNhdGNoQ2xpY2tzOiBmdW5jdGlvbiBjYXRjaENsaWNrcyhlKSB7XG4gICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgfSxcblxuICAgIG9uS2V5RG93bjogZnVuY3Rpb24gb25LZXlEb3duKGUpIHtcbiAgICAgICAgaWYgKGUua2V5ID09PSAnRW50ZXInKSB7XG4gICAgICAgICAgICB0aGlzLnN1Ym1pdCgpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBlcnJvclN0cmluZzogJycgfSk7XG4gICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgUGFwZXIsXG4gICAgICAgICAgICB7IGNsYXNzTmFtZTogXCJpbmxpbmUtZWRpdG9yXCIgKyAodGhpcy5wcm9wcy5kZXRhY2hlZCA/IFwiIGRldGFjaGVkXCIgOiBcIlwiKSwgc3R5bGU6IHsgcGFkZGluZzogOCB9LCB6RGVwdGg6IDIgfSxcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoVGV4dEZpZWxkLCB7XG4gICAgICAgICAgICAgICAgcmVmOiAndGV4dCcsXG4gICAgICAgICAgICAgICAgZGVmYXVsdFZhbHVlOiB0aGlzLnByb3BzLm5vZGUuZ2V0TGFiZWwoKSxcbiAgICAgICAgICAgICAgICBvbkNoYW5nZTogZnVuY3Rpb24gKGUsIHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzLnNldFN0YXRlKHsgdmFsdWU6IHZhbHVlIH0pO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgb25DbGljazogdGhpc1snY2F0Y2gnXSwgb25Eb3VibGVDbGljazogdGhpcy5jYXRjaENsaWNrcyxcbiAgICAgICAgICAgICAgICB0YWJJbmRleDogJzAnLCBvbktleURvd246IHRoaXMub25LZXlEb3duLFxuICAgICAgICAgICAgICAgIGVycm9yVGV4dDogdGhpcy5zdGF0ZSA/IHRoaXMuc3RhdGUuZXJyb3JTdHJpbmcgOiBudWxsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgeyBzdHlsZTogeyB0ZXh0QWxpZ246ICdyaWdodCcsIHBhZGRpbmdUb3A6IDggfSB9LFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoRmxhdEJ1dHRvbiwgeyBsYWJlbDogJ0NhbmNlbCcsIG9uQ2xpY2s6IHRoaXMucHJvcHMub25DbG9zZSB9KSxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KEZsYXRCdXR0b24sIHsgbGFiZWw6ICdTdWJtaXQnLCBvbkNsaWNrOiB0aGlzLnN1Ym1pdCB9KVxuICAgICAgICAgICAgKVxuICAgICAgICApO1xuICAgIH1cblxufSk7XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IElubGluZUVkaXRvciA9IFB5ZGlvQ29udGV4dENvbnN1bWVyKElubGluZUVkaXRvcik7XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IElubGluZUVkaXRvcjtcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDA3LTIwMTcgQ2hhcmxlcyBkdSBKZXUgLSBBYnN0cml1bSBTQVMgPHRlYW0gKGF0KSBweWQuaW8+XG4gKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBQeWRpby5cbiAqXG4gKiBQeWRpbyBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFB5ZGlvIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIFB5ZGlvLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuICpcbiAqIFRoZSBsYXRlc3QgY29kZSBjYW4gYmUgZm91bmQgYXQgPGh0dHBzOi8vcHlkaW8uY29tPi5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfZXh0ZW5kcyA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gKHRhcmdldCkgeyBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgeyB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldOyBmb3IgKHZhciBrZXkgaW4gc291cmNlKSB7IGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoc291cmNlLCBrZXkpKSB7IHRhcmdldFtrZXldID0gc291cmNlW2tleV07IH0gfSB9IHJldHVybiB0YXJnZXQ7IH07XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7ICdkZWZhdWx0Jzogb2JqIH07IH1cblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24nKTsgfSB9XG5cbmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09ICdmdW5jdGlvbicgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90ICcgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5zZXRQcm90b3R5cGVPZihzdWJDbGFzcywgc3VwZXJDbGFzcykgOiBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9XG5cbnZhciBfcmVhY3REb20gPSByZXF1aXJlKCdyZWFjdC1kb20nKTtcblxudmFyIF9yZWFjdERvbTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9yZWFjdERvbSk7XG5cbnZhciBfdXRpbERORCA9IHJlcXVpcmUoJy4uL3V0aWwvRE5EJyk7XG5cbnZhciBfcmVhY3REbmQgPSByZXF1aXJlKCdyZWFjdC1kbmQnKTtcblxudmFyIF9tYXRlcmlhbFVpID0gcmVxdWlyZSgnbWF0ZXJpYWwtdWknKTtcblxudmFyIF9tYXRlcmlhbFVpU3R5bGVzID0gcmVxdWlyZSgnbWF0ZXJpYWwtdWkvc3R5bGVzJyk7XG5cbnZhciBfY29sb3IgPSByZXF1aXJlKCdjb2xvcicpO1xuXG52YXIgX2NvbG9yMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2NvbG9yKTtcblxuLyoqXG4gKiBNYXRlcmlhbCBMaXN0IEVudHJ5XG4gKi9cblxudmFyIExpc3RFbnRyeSA9IChmdW5jdGlvbiAoX1JlYWN0JENvbXBvbmVudCkge1xuICAgIF9pbmhlcml0cyhMaXN0RW50cnksIF9SZWFjdCRDb21wb25lbnQpO1xuXG4gICAgZnVuY3Rpb24gTGlzdEVudHJ5KCkge1xuICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgTGlzdEVudHJ5KTtcblxuICAgICAgICBfUmVhY3QkQ29tcG9uZW50LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfVxuXG4gICAgTGlzdEVudHJ5LnByb3RvdHlwZS5vbkNsaWNrID0gZnVuY3Rpb24gb25DbGljayhldmVudCkge1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5zaG93U2VsZWN0b3IpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnByb3BzLnNlbGVjdG9yRGlzYWJsZWQpIHJldHVybjtcbiAgICAgICAgICAgIHRoaXMucHJvcHMub25TZWxlY3QodGhpcy5wcm9wcy5ub2RlLCBldmVudCk7XG4gICAgICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5wcm9wcy5vbkNsaWNrKSB7XG4gICAgICAgICAgICB0aGlzLnByb3BzLm9uQ2xpY2sodGhpcy5wcm9wcy5ub2RlLCBldmVudCk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgTGlzdEVudHJ5LnByb3RvdHlwZS5vbkRvdWJsZUNsaWNrID0gZnVuY3Rpb24gb25Eb3VibGVDbGljayhldmVudCkge1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5vbkRvdWJsZUNsaWNrKSB7XG4gICAgICAgICAgICB0aGlzLnByb3BzLm9uRG91YmxlQ2xpY2sodGhpcy5wcm9wcy5ub2RlLCBldmVudCk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgTGlzdEVudHJ5LnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICAgICAgdmFyIHNlbGVjdG9yID0gdW5kZWZpbmVkLFxuICAgICAgICAgICAgaWNvbiA9IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGFkZGl0aW9uYWxDbGFzc05hbWUgPSB1bmRlZmluZWQ7XG5cbiAgICAgICAgdmFyIF9wcm9wcyA9IHRoaXMucHJvcHM7XG4gICAgICAgIHZhciBub2RlID0gX3Byb3BzLm5vZGU7XG4gICAgICAgIHZhciBzaG93U2VsZWN0b3IgPSBfcHJvcHMuc2hvd1NlbGVjdG9yO1xuICAgICAgICB2YXIgc2VsZWN0ZWQgPSBfcHJvcHMuc2VsZWN0ZWQ7XG4gICAgICAgIHZhciBzZWxlY3RvckRpc2FibGVkID0gX3Byb3BzLnNlbGVjdG9yRGlzYWJsZWQ7XG4gICAgICAgIHZhciBmaXJzdExpbmUgPSBfcHJvcHMuZmlyc3RMaW5lO1xuICAgICAgICB2YXIgc2Vjb25kTGluZSA9IF9wcm9wcy5zZWNvbmRMaW5lO1xuICAgICAgICB2YXIgdGhpcmRMaW5lID0gX3Byb3BzLnRoaXJkTGluZTtcbiAgICAgICAgdmFyIHN0eWxlID0gX3Byb3BzLnN0eWxlO1xuICAgICAgICB2YXIgYWN0aW9ucyA9IF9wcm9wcy5hY3Rpb25zO1xuICAgICAgICB2YXIgaWNvbkNlbGwgPSBfcHJvcHMuaWNvbkNlbGw7XG4gICAgICAgIHZhciBtYWluSWNvbiA9IF9wcm9wcy5tYWluSWNvbjtcbiAgICAgICAgdmFyIGNsYXNzTmFtZSA9IF9wcm9wcy5jbGFzc05hbWU7XG4gICAgICAgIHZhciBjYW5Ecm9wID0gX3Byb3BzLmNhbkRyb3A7XG4gICAgICAgIHZhciBpc092ZXIgPSBfcHJvcHMuaXNPdmVyO1xuICAgICAgICB2YXIgY29ubmVjdERyYWdTb3VyY2UgPSBfcHJvcHMuY29ubmVjdERyYWdTb3VyY2U7XG4gICAgICAgIHZhciBjb25uZWN0RHJvcFRhcmdldCA9IF9wcm9wcy5jb25uZWN0RHJvcFRhcmdldDtcblxuICAgICAgICB2YXIgbWFpbkNsYXNzZXMgPSBbJ21hdGVyaWFsLWxpc3QtZW50cnknLCAnbWF0ZXJpYWwtbGlzdC1lbnRyeS0nICsgKHRoaXJkTGluZSA/IDMgOiBzZWNvbmRMaW5lID8gMiA6IDEpICsgJy1saW5lcyddO1xuICAgICAgICBpZiAoY2xhc3NOYW1lKSBtYWluQ2xhc3Nlcy5wdXNoKGNsYXNzTmFtZSk7XG5cbiAgICAgICAgaWYgKHNob3dTZWxlY3Rvcikge1xuICAgICAgICAgICAgc2VsZWN0b3IgPSBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAnbWF0ZXJpYWwtbGlzdC1zZWxlY3RvcicgfSxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KF9tYXRlcmlhbFVpLkNoZWNrYm94LCB7IGNoZWNrZWQ6IHNlbGVjdGVkLCByZWY6ICdzZWxlY3RvcicsIGRpc2FibGVkOiBzZWxlY3RvckRpc2FibGVkIH0pXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGljb25DZWxsKSB7XG4gICAgICAgICAgICBpY29uID0gdGhpcy5wcm9wcy5pY29uQ2VsbDtcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLnByb3BzLm1haW5JY29uKSB7XG4gICAgICAgICAgICBpY29uID0gUmVhY3QuY3JlYXRlRWxlbWVudChfbWF0ZXJpYWxVaS5Gb250SWNvbiwgeyBjbGFzc05hbWU6IFwibXVpLWZvbnQtaWNvbiBcIiArIHRoaXMucHJvcHMubWFpbkljb24sIHN0eWxlOiB7IGZvbnRTaXplOiAxOCAvKiwgY29sb3I6IFwiI0ZGRkZGRlwiKi8gfSB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjYW5Ecm9wICYmIGlzT3Zlcikge1xuICAgICAgICAgICAgbWFpbkNsYXNzZXMucHVzaCgnZHJvcHBhYmxlLWFjdGl2ZScpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG5vZGUpIHtcbiAgICAgICAgICAgIG1haW5DbGFzc2VzLnB1c2goJ2xpc3RlbnRyeScgKyBub2RlLmdldFBhdGgoKS5yZXBsYWNlKC9cXC8vZywgJ18nKSk7XG4gICAgICAgICAgICBtYWluQ2xhc3Nlcy5wdXNoKCdhanhwX25vZGVfJyArIChub2RlLmlzTGVhZigpID8gJ2xlYWYnIDogJ2NvbGxlY3Rpb24nKSk7XG4gICAgICAgICAgICBpZiAobm9kZS5nZXRBanhwTWltZSgpKSB7XG4gICAgICAgICAgICAgICAgbWFpbkNsYXNzZXMucHVzaCgnYWp4cF9taW1lXycgKyBub2RlLmdldEFqeHBNaW1lKCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGFkZGl0aW9uYWxTdHlsZSA9IHtcbiAgICAgICAgICAgIC8qdHJhbnNpdGlvbjonYmFja2dyb3VuZC1jb2xvciAyNTBtcyBjdWJpYy1iZXppZXIoMC4yMywgMSwgMC4zMiwgMSkgMG1zLCBjb2xvciAyNTBtcyBjdWJpYy1iZXppZXIoMC4yMywgMSwgMC4zMiwgMSkgMG1zJyovXG4gICAgICAgIH07XG4gICAgICAgIGlmICh0aGlzLnN0YXRlICYmIHRoaXMuc3RhdGUuaG92ZXIgJiYgIXRoaXMucHJvcHMubm9Ib3Zlcikge1xuICAgICAgICAgICAgYWRkaXRpb25hbFN0eWxlID0gX2V4dGVuZHMoe30sIGFkZGl0aW9uYWxTdHlsZSwge1xuICAgICAgICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogJ3JnYmEoMCwwLDAsMC4wNSknLFxuICAgICAgICAgICAgICAgIGJvcmRlckJvdHRvbTogJzFweCBzb2xpZCB0cmFuc3BhcmVudCdcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzZWxlY3RlZCkge1xuICAgICAgICAgICAgdmFyIHNlbGVjdGlvbkNvbG9yID0gdGhpcy5wcm9wcy5tdWlUaGVtZS5wYWxldHRlLmFjY2VudDJDb2xvcjtcbiAgICAgICAgICAgIHZhciBzZWxlY3Rpb25Db2xvckRhcmsgPSBfY29sb3IyWydkZWZhdWx0J10oc2VsZWN0aW9uQ29sb3IpLmRhcmsoKTtcbiAgICAgICAgICAgIGFkZGl0aW9uYWxTdHlsZSA9IF9leHRlbmRzKHt9LCBhZGRpdGlvbmFsU3R5bGUsIHtcbiAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IHNlbGVjdGlvbkNvbG9yLFxuICAgICAgICAgICAgICAgIGNvbG9yOiBzZWxlY3Rpb25Db2xvckRhcmsgPyAnd2hpdGUnIDogJ3JnYmEoMCwwLDAsLjg3KSdcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgbWFpbkNsYXNzZXMucHVzaCgnc2VsZWN0ZWQnKTtcbiAgICAgICAgICAgIG1haW5DbGFzc2VzLnB1c2goJ3NlbGVjdGVkLScgKyAoc2VsZWN0aW9uQ29sb3JEYXJrID8gJ2RhcmsnIDogJ2xpZ2h0JykpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICBDb250ZXh0TWVudVdyYXBwZXIsXG4gICAgICAgICAgICBfZXh0ZW5kcyh7fSwgdGhpcy5wcm9wcywge1xuICAgICAgICAgICAgICAgIHJlZjogZnVuY3Rpb24gKGluc3RhbmNlKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBub2RlID0gX3JlYWN0RG9tMlsnZGVmYXVsdCddLmZpbmRET01Ob2RlKGluc3RhbmNlKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBjb25uZWN0RHJvcFRhcmdldCA9PT0gJ2Z1bmN0aW9uJykgY29ubmVjdERyb3BUYXJnZXQobm9kZSk7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgY29ubmVjdERyYWdTb3VyY2UgPT09ICdmdW5jdGlvbicpIGNvbm5lY3REcmFnU291cmNlKG5vZGUpO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgb25DbGljazogdGhpcy5vbkNsaWNrLmJpbmQodGhpcyksXG4gICAgICAgICAgICAgICAgb25Eb3VibGVDbGljazogc2hvd1NlbGVjdG9yID8gbnVsbCA6IHRoaXMub25Eb3VibGVDbGljay5iaW5kKHRoaXMpLFxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogbWFpbkNsYXNzZXMuam9pbignICcpLFxuICAgICAgICAgICAgICAgIG9uTW91c2VPdmVyOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzLnNldFN0YXRlKHsgaG92ZXI6IHRydWUgfSk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBvbk1vdXNlT3V0OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzLnNldFN0YXRlKHsgaG92ZXI6IGZhbHNlIH0pO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgc3R5bGU6IF9leHRlbmRzKHt9LCBzdHlsZSwgYWRkaXRpb25hbFN0eWxlKSB9KSxcbiAgICAgICAgICAgIHNlbGVjdG9yLFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogXCJtYXRlcmlhbC1saXN0LWljb25cIiArIChtYWluSWNvbiB8fCBpY29uQ2VsbCA/IFwiXCIgOiBcIiBtYXRlcmlhbC1saXN0LWljb24tbm9uZVwiKSB9LFxuICAgICAgICAgICAgICAgIGljb25cbiAgICAgICAgICAgICksXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAnbWF0ZXJpYWwtbGlzdC10ZXh0JyB9LFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgICAgICB7IGtleTogJ2xpbmUtMScsIGNsYXNzTmFtZTogJ21hdGVyaWFsLWxpc3QtbGluZS0xJyB9LFxuICAgICAgICAgICAgICAgICAgICBmaXJzdExpbmVcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgICAgICB7IGtleTogJ2xpbmUtMicsIGNsYXNzTmFtZTogJ21hdGVyaWFsLWxpc3QtbGluZS0yJyB9LFxuICAgICAgICAgICAgICAgICAgICBzZWNvbmRMaW5lXG4gICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICAgICAgeyBrZXk6ICdsaW5lLTMnLCBjbGFzc05hbWU6ICdtYXRlcmlhbC1saXN0LWxpbmUtMycgfSxcbiAgICAgICAgICAgICAgICAgICAgdGhpcmRMaW5lXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6ICdtYXRlcmlhbC1saXN0LWFjdGlvbnMnIH0sXG4gICAgICAgICAgICAgICAgYWN0aW9uc1xuICAgICAgICAgICAgKVxuICAgICAgICApO1xuICAgIH07XG5cbiAgICByZXR1cm4gTGlzdEVudHJ5O1xufSkoUmVhY3QuQ29tcG9uZW50KTtcblxudmFyIENvbnRleHRNZW51V3JhcHBlciA9IGZ1bmN0aW9uIENvbnRleHRNZW51V3JhcHBlcihwcm9wcykge1xuICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KCdkaXYnLCBwcm9wcyk7XG59O1xuQ29udGV4dE1lbnVXcmFwcGVyID0gUHlkaW9IT0NzLndpdGhDb250ZXh0TWVudShDb250ZXh0TWVudVdyYXBwZXIpO1xuXG5MaXN0RW50cnkucHJvcFR5cGVzID0ge1xuICAgIHNob3dTZWxlY3RvcjogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXG4gICAgc2VsZWN0ZWQ6IFJlYWN0LlByb3BUeXBlcy5ib29sLFxuICAgIHNlbGVjdG9yRGlzYWJsZWQ6IFJlYWN0LlByb3BUeXBlcy5ib29sLFxuICAgIG9uU2VsZWN0OiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgICBvbkNsaWNrOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgICBpY29uQ2VsbDogUmVhY3QuUHJvcFR5cGVzLmVsZW1lbnQsXG4gICAgbWFpbkljb246IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcsXG4gICAgZmlyc3RMaW5lOiBSZWFjdC5Qcm9wVHlwZXMubm9kZSxcbiAgICBzZWNvbmRMaW5lOiBSZWFjdC5Qcm9wVHlwZXMubm9kZSxcbiAgICB0aGlyZExpbmU6IFJlYWN0LlByb3BUeXBlcy5ub2RlLFxuICAgIGFjdGlvbnM6IFJlYWN0LlByb3BUeXBlcy5lbGVtZW50LFxuICAgIGFjdGl2ZURyb3BwYWJsZTogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXG4gICAgY2xhc3NOYW1lOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLFxuICAgIHN0eWxlOiBSZWFjdC5Qcm9wVHlwZXMub2JqZWN0LFxuICAgIG5vSG92ZXI6IFJlYWN0LlByb3BUeXBlcy5ib29sXG59O1xuXG5leHBvcnRzLkxpc3RFbnRyeSA9IExpc3RFbnRyeSA9IF9tYXRlcmlhbFVpU3R5bGVzLm11aVRoZW1lYWJsZSgpKExpc3RFbnRyeSk7XG5cbnZhciBEcmFnRHJvcExpc3RFbnRyeSA9IF9yZWFjdERuZC5mbG93KF9yZWFjdERuZC5EcmFnU291cmNlKF91dGlsRE5ELlR5cGVzLk5PREVfUFJPVklERVIsIF91dGlsRE5ELm5vZGVEcmFnU291cmNlLCBfdXRpbERORC5jb2xsZWN0KSwgX3JlYWN0RG5kLkRyb3BUYXJnZXQoX3V0aWxETkQuVHlwZXMuTk9ERV9QUk9WSURFUiwgX3V0aWxETkQubm9kZURyb3BUYXJnZXQsIF91dGlsRE5ELmNvbGxlY3REcm9wKSkoTGlzdEVudHJ5KTtcblxuZXhwb3J0cy5EcmFnRHJvcExpc3RFbnRyeSA9IERyYWdEcm9wTGlzdEVudHJ5O1xuZXhwb3J0cy5MaXN0RW50cnkgPSBMaXN0RW50cnk7XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMDctMjAxNyBDaGFybGVzIGR1IEpldSAtIEFic3RyaXVtIFNBUyA8dGVhbSAoYXQpIHB5ZC5pbz5cbiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIFB5ZGlvLlxuICpcbiAqIFB5ZGlvIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3JcbiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogUHlkaW8gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggUHlkaW8uICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gKlxuICogVGhlIGxhdGVzdCBjb2RlIGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9weWRpby5jb20+LlxuICovXG5cblwidXNlIHN0cmljdFwiO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuZXhwb3J0c1tcImRlZmF1bHRcIl0gPSB7XG5cbiAgICBhdHRhY2g6IGZ1bmN0aW9uIGF0dGFjaChub2RlKSB7XG4gICAgICAgIHRoaXMuX25vZGVMaXN0ZW5lciA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuaXNNb3VudGVkKCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRldGFjaChub2RlKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmZvcmNlVXBkYXRlKCk7XG4gICAgICAgIH0pLmJpbmQodGhpcyk7XG4gICAgICAgIHRoaXMuX2FjdGlvbkxpc3RlbmVyID0gKGZ1bmN0aW9uIChldmVudE1lbW8pIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5pc01vdW50ZWQoKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZGV0YWNoKG5vZGUpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChldmVudE1lbW8gJiYgZXZlbnRNZW1vLnR5cGUgPT09ICdwcm9tcHQtcmVuYW1lJyAmJiBldmVudE1lbW8uY2FsbGJhY2spIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgaW5saW5lRWRpdGlvbjogdHJ1ZSwgaW5saW5lRWRpdGlvbkNhbGxiYWNrOiBldmVudE1lbW8uY2FsbGJhY2sgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSkuYmluZCh0aGlzKTtcbiAgICAgICAgbm9kZS5vYnNlcnZlKFwibm9kZV9yZXBsYWNlZFwiLCB0aGlzLl9ub2RlTGlzdGVuZXIpO1xuICAgICAgICBub2RlLm9ic2VydmUoXCJub2RlX2FjdGlvblwiLCB0aGlzLl9hY3Rpb25MaXN0ZW5lcik7XG4gICAgfSxcblxuICAgIGRldGFjaDogZnVuY3Rpb24gZGV0YWNoKG5vZGUpIHtcbiAgICAgICAgaWYgKHRoaXMuX25vZGVMaXN0ZW5lcikge1xuICAgICAgICAgICAgbm9kZS5zdG9wT2JzZXJ2aW5nKFwibm9kZV9yZXBsYWNlZFwiLCB0aGlzLl9ub2RlTGlzdGVuZXIpO1xuICAgICAgICAgICAgbm9kZS5zdG9wT2JzZXJ2aW5nKFwibm9kZV9hY3Rpb25cIiwgdGhpcy5fYWN0aW9uTGlzdGVuZXIpO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIGNvbXBvbmVudERpZE1vdW50OiBmdW5jdGlvbiBjb21wb25lbnREaWRNb3VudCgpIHtcbiAgICAgICAgdGhpcy5hdHRhY2godGhpcy5wcm9wcy5ub2RlKTtcbiAgICB9LFxuXG4gICAgY29tcG9uZW50V2lsbFVubW91bnQ6IGZ1bmN0aW9uIGNvbXBvbmVudFdpbGxVbm1vdW50KCkge1xuICAgICAgICB0aGlzLmRldGFjaCh0aGlzLnByb3BzLm5vZGUpO1xuICAgIH1cblxufTtcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1tcImRlZmF1bHRcIl07XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMDctMjAxNyBDaGFybGVzIGR1IEpldSAtIEFic3RyaXVtIFNBUyA8dGVhbSAoYXQpIHB5ZC5pbz5cbiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIFB5ZGlvLlxuICpcbiAqIFB5ZGlvIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3JcbiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogUHlkaW8gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggUHlkaW8uICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gKlxuICogVGhlIGxhdGVzdCBjb2RlIGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9weWRpby5jb20+LlxuICovXG5cblwidXNlIHN0cmljdFwiO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBcImRlZmF1bHRcIjogb2JqIH07IH1cblxudmFyIF91dGlsTWVzc2FnZXNDb25zdW1lck1peGluID0gcmVxdWlyZSgnLi4vdXRpbC9NZXNzYWdlc0NvbnN1bWVyTWl4aW4nKTtcblxudmFyIF91dGlsTWVzc2FnZXNDb25zdW1lck1peGluMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3V0aWxNZXNzYWdlc0NvbnN1bWVyTWl4aW4pO1xuXG4vKipcbiAqIFBhZ2luYXRpb24gY29tcG9uZW50IHJlYWRpbmcgbWV0YWRhdGEgXCJwYWdpbmF0aW9uRGF0YVwiIGZyb20gY3VycmVudCBub2RlLlxuICovXG5leHBvcnRzW1wiZGVmYXVsdFwiXSA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcbiAgICBkaXNwbGF5TmFtZTogXCJMaXN0UGFnaW5hdG9yXCIsXG5cbiAgICBtaXhpbnM6IFtfdXRpbE1lc3NhZ2VzQ29uc3VtZXJNaXhpbjJbXCJkZWZhdWx0XCJdXSxcblxuICAgIHByb3BUeXBlczoge1xuICAgICAgICBkYXRhTW9kZWw6IFJlYWN0LlByb3BUeXBlcy5pbnN0YW5jZU9mKFB5ZGlvRGF0YU1vZGVsKS5pc1JlcXVpcmVkLFxuICAgICAgICBub2RlOiBSZWFjdC5Qcm9wVHlwZXMuaW5zdGFuY2VPZihBanhwTm9kZSlcbiAgICB9LFxuXG4gICAgY29tcG9uZW50RGlkTW91bnQ6IGZ1bmN0aW9uIGNvbXBvbmVudERpZE1vdW50KCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgICAgIGlmICghdGhpcy5wcm9wcy5ub2RlKSB7XG4gICAgICAgICAgICAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHZhciBkbSA9IF90aGlzLnByb3BzLmRhdGFNb2RlbDtcbiAgICAgICAgICAgICAgICBfdGhpcy5fZG1PYnNlcnZlciA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBub2RlOiBkbS5nZXRDb250ZXh0Tm9kZSgpIH0pO1xuICAgICAgICAgICAgICAgIH0pLmJpbmQoX3RoaXMpO1xuICAgICAgICAgICAgICAgIGRtLm9ic2VydmUoXCJjb250ZXh0X2NoYW5nZWRcIiwgX3RoaXMuX2RtT2JzZXJ2ZXIpO1xuICAgICAgICAgICAgICAgIF90aGlzLnNldFN0YXRlKHsgbm9kZTogZG0uZ2V0Q29udGV4dE5vZGUoKSB9KTtcbiAgICAgICAgICAgIH0pKCk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgY29tcG9uZW50V2lsbFVubW91bnQ6IGZ1bmN0aW9uIGNvbXBvbmVudFdpbGxVbm1vdW50KCkge1xuICAgICAgICBpZiAodGhpcy5fZG1PYnNlcnZlcikge1xuICAgICAgICAgICAgdGhpcy5wcm9wcy5kYXRhTW9kZWwuc3RvcE9ic2VydmluZyhcImNvbnRleHRfY2hhbmdlZFwiLCB0aGlzLl9kbU9ic2VydmVyKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBnZXRJbml0aWFsU3RhdGU6IGZ1bmN0aW9uIGdldEluaXRpYWxTdGF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHsgbm9kZTogdGhpcy5wcm9wcy5ub2RlIH07XG4gICAgfSxcblxuICAgIGNoYW5nZVBhZ2U6IGZ1bmN0aW9uIGNoYW5nZVBhZ2UoZXZlbnQpIHtcbiAgICAgICAgdGhpcy5zdGF0ZS5ub2RlLmdldE1ldGFkYXRhKCkuZ2V0KFwicGFnaW5hdGlvbkRhdGFcIikuc2V0KFwibmV3X3BhZ2VcIiwgZXZlbnQuY3VycmVudFRhcmdldC5nZXRBdHRyaWJ1dGUoJ2RhdGEtcGFnZScpKTtcbiAgICAgICAgdGhpcy5wcm9wcy5kYXRhTW9kZWwucmVxdWlyZUNvbnRleHRDaGFuZ2UodGhpcy5zdGF0ZS5ub2RlKTtcbiAgICB9LFxuXG4gICAgb25NZW51Q2hhbmdlOiBmdW5jdGlvbiBvbk1lbnVDaGFuZ2UoZXZlbnQsIGluZGV4LCBpdGVtKSB7XG4gICAgICAgIHRoaXMuc3RhdGUubm9kZS5nZXRNZXRhZGF0YSgpLmdldChcInBhZ2luYXRpb25EYXRhXCIpLnNldChcIm5ld19wYWdlXCIsIGl0ZW0ucGF5bG9hZCk7XG4gICAgICAgIHRoaXMucHJvcHMuZGF0YU1vZGVsLnJlcXVpcmVDb250ZXh0Q2hhbmdlKHRoaXMuc3RhdGUubm9kZSk7XG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgICBpZiAoIXRoaXMuc3RhdGUubm9kZSB8fCAhdGhpcy5zdGF0ZS5ub2RlLmdldE1ldGFkYXRhKCkuZ2V0KFwicGFnaW5hdGlvbkRhdGFcIikpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgICAgIHZhciBwRGF0YSA9IHRoaXMuc3RhdGUubm9kZS5nZXRNZXRhZGF0YSgpLmdldChcInBhZ2luYXRpb25EYXRhXCIpO1xuICAgICAgICB2YXIgY3VycmVudCA9IHBhcnNlSW50KHBEYXRhLmdldChcImN1cnJlbnRcIikpO1xuICAgICAgICB2YXIgdG90YWwgPSBwYXJzZUludChwRGF0YS5nZXQoXCJ0b3RhbFwiKSk7XG4gICAgICAgIHZhciBwYWdlcyA9IFtdLFxuICAgICAgICAgICAgbmV4dCxcbiAgICAgICAgICAgIGxhc3QsXG4gICAgICAgICAgICBwcmV2aW91cyxcbiAgICAgICAgICAgIGZpcnN0O1xuICAgICAgICB2YXIgcGFnZVdvcmQgPSB0aGlzLmNvbnRleHQuZ2V0TWVzc2FnZSA/IHRoaXMuY29udGV4dC5nZXRNZXNzYWdlKCczMzEnLCAnJykgOiB0aGlzLnByb3BzLmdldE1lc3NhZ2UoJzMzMScsICcnKTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPD0gdG90YWw7IGkrKykge1xuICAgICAgICAgICAgcGFnZXMucHVzaCh7IHBheWxvYWQ6IGksIHRleHQ6IHBhZ2VXb3JkICsgJyAnICsgaSArIChpID09IGN1cnJlbnQgPyAnIC8gJyArIHRvdGFsIDogJycpIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwYWdlcy5sZW5ndGggPD0gMSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHNlcCA9IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMudG9vbGJhckRpc3BsYXkpIHtcbiAgICAgICAgICAgIGlmIChjdXJyZW50ID4gMSkgcHJldmlvdXMgPSBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgIFwic3BhblwiLFxuICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiBcInRvb2xiYXJzLWJ1dHRvbi1tZW51XCIgfSxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFJlYWN0TVVJLkljb25CdXR0b24sIHsgb25DbGljazogdGhpcy5jaGFuZ2VQYWdlLCBcImRhdGEtcGFnZVwiOiBjdXJyZW50IC0gMSwgaWNvbkNsYXNzTmFtZTogXCJpY29uLWNhcmV0LWxlZnRcIiB9KVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGlmIChjdXJyZW50IDwgdG90YWwpIG5leHQgPSBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgIFwic3BhblwiLFxuICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiBcInRvb2xiYXJzLWJ1dHRvbi1tZW51XCIgfSxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFJlYWN0TVVJLkljb25CdXR0b24sIHsgb25DbGljazogdGhpcy5jaGFuZ2VQYWdlLCBcImRhdGEtcGFnZVwiOiBjdXJyZW50ICsgMSwgaWNvbkNsYXNzTmFtZTogXCJpY29uLWNhcmV0LXJpZ2h0XCIgfSlcbiAgICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoY3VycmVudCA+IDEpIHByZXZpb3VzID0gUmVhY3QuY3JlYXRlRWxlbWVudChSZWFjdE1VSS5Gb250SWNvbiwgeyBvbkNsaWNrOiB0aGlzLmNoYW5nZVBhZ2UsIFwiZGF0YS1wYWdlXCI6IGN1cnJlbnQgLSAxLCBjbGFzc05hbWU6IFwiaWNvbi1hbmdsZS1sZWZ0XCIgfSk7XG4gICAgICAgICAgICBpZiAoY3VycmVudCA8IHRvdGFsKSBuZXh0ID0gUmVhY3QuY3JlYXRlRWxlbWVudChSZWFjdE1VSS5Gb250SWNvbiwgeyBvbkNsaWNrOiB0aGlzLmNoYW5nZVBhZ2UsIFwiZGF0YS1wYWdlXCI6IGN1cnJlbnQgKyAxLCBjbGFzc05hbWU6IFwiaWNvbi1hbmdsZS1yaWdodFwiIH0pO1xuICAgICAgICAgICAgc2VwID0gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICBcInNwYW5cIixcbiAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogXCJtdWktdG9vbGJhci1zZXBhcmF0b3JcIiB9LFxuICAgICAgICAgICAgICAgIFwiwqBcIlxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgIFwic3BhblwiLFxuICAgICAgICAgICAgeyBpZDogdGhpcy5wcm9wcy5pZCwgc3R5bGU6IHRoaXMucHJvcHMuc3R5bGUgfSxcbiAgICAgICAgICAgIGZpcnN0LFxuICAgICAgICAgICAgcHJldmlvdXMsXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFJlYWN0TVVJLkRyb3BEb3duTWVudSwgeyBvbkNoYW5nZTogdGhpcy5vbk1lbnVDaGFuZ2UsIG1lbnVJdGVtczogcGFnZXMsIHNlbGVjdGVkSW5kZXg6IGN1cnJlbnQgLSAxIH0pLFxuICAgICAgICAgICAgbmV4dCxcbiAgICAgICAgICAgIGxhc3QsXG4gICAgICAgICAgICBzZXBcbiAgICAgICAgKTtcbiAgICB9XG5cbn0pO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzW1wiZGVmYXVsdFwiXTtcbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDE3IENoYXJsZXMgZHUgSmV1IC0gQWJzdHJpdW0gU0FTIDx0ZWFtIChhdCkgcHlkLmlvPlxuICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgUHlkaW8uXG4gKlxuICogUHlkaW8gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBQeWRpbyBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCBQeWRpby4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAqXG4gKiBUaGUgbGF0ZXN0IGNvZGUgY2FuIGJlIGZvdW5kIGF0IDxodHRwczovL3B5ZGlvLmNvbT4uXG4gKi9cblxuXCJ1c2Ugc3RyaWN0XCI7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfZXh0ZW5kcyA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gKHRhcmdldCkgeyBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgeyB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldOyBmb3IgKHZhciBrZXkgaW4gc291cmNlKSB7IGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoc291cmNlLCBrZXkpKSB7IHRhcmdldFtrZXldID0gc291cmNlW2tleV07IH0gfSB9IHJldHVybiB0YXJnZXQ7IH07XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IFwiZGVmYXVsdFwiOiBvYmogfTsgfVxuXG52YXIgX1NpbXBsZUxpc3QgPSByZXF1aXJlKCcuL1NpbXBsZUxpc3QnKTtcblxudmFyIF9TaW1wbGVMaXN0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1NpbXBsZUxpc3QpO1xuXG4vKipcbiAqIFNpbXBsZSB0byB1c2UgbGlzdCBjb21wb25lbnQgZW5jYXBzdWxhdGVkIHdpdGggaXRzIG93biBxdWVyeSBtZWNoYW5pc21cbiAqIHVzaW5nIGEgc2V0IG9mIHByb3BlcnRpZXMgZm9yIHRoZSByZW1vdGUgbm9kZSBwcm92aWRlci5cbiAqL1xuZXhwb3J0c1tcImRlZmF1bHRcIl0gPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG4gICAgZGlzcGxheU5hbWU6IFwiTm9kZUxpc3RDdXN0b21Qcm92aWRlclwiLFxuXG4gICAgcHJvcFR5cGVzOiB7XG4gICAgICAgIG5vZGVQcm92aWRlclByb3BlcnRpZXM6IFJlYWN0LlByb3BUeXBlcy5vYmplY3QsXG4gICAgICAgIHByZXNldERhdGFNb2RlbDogUmVhY3QuUHJvcFR5cGVzLmluc3RhbmNlT2YoUHlkaW9EYXRhTW9kZWwpLFxuICAgICAgICBhdXRvUmVmcmVzaDogUmVhY3QuUHJvcFR5cGVzLm51bWJlcixcbiAgICAgICAgYWN0aW9uQmFyR3JvdXBzOiBSZWFjdC5Qcm9wVHlwZXMuYXJyYXksXG4gICAgICAgIGhlaWdodEF1dG9XaXRoTWF4OiBSZWFjdC5Qcm9wVHlwZXMubnVtYmVyLFxuICAgICAgICBlbGVtZW50SGVpZ2h0OiBSZWFjdC5Qcm9wVHlwZXMubnVtYmVyLmlzUmVxdWlyZWQsXG4gICAgICAgIG5vZGVDbGlja2VkOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgICAgICAgcmVsb2FkT25TZXJ2ZXJNZXNzYWdlOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLFxuICAgICAgICBlbnRyeVJlbmRlckFzQ2FyZDogUmVhY3QuUHJvcFR5cGVzLmZ1bmNcbiAgICB9LFxuXG4gICAgcmVsb2FkOiBmdW5jdGlvbiByZWxvYWQoKSB7XG4gICAgICAgIGlmICh0aGlzLnJlZnMubGlzdCAmJiB0aGlzLmlzTW91bnRlZCgpKSB7XG4gICAgICAgICAgICB0aGlzLnJlZnMubGlzdC5yZWxvYWQoKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBjb21wb25lbnRXaWxsVW5tb3VudDogZnVuY3Rpb24gY29tcG9uZW50V2lsbFVubW91bnQoKSB7XG4gICAgICAgIGlmICh0aGlzLl9zbU9icykge1xuICAgICAgICAgICAgdGhpcy5wcm9wcy5weWRpby5zdG9wT2JzZXJ2aW5nKFwic2VydmVyX21lc3NhZ2VcIiwgdGhpcy5fc21PYnMpO1xuICAgICAgICAgICAgdGhpcy5wcm9wcy5weWRpby5zdG9wT2JzZXJ2aW5nKFwic2VydmVyX21lc3NhZ2U6XCIgKyB0aGlzLnByb3BzLnJlbG9hZE9uU2VydmVyTWVzc2FnZSwgdGhpcy5yZWxvYWQpO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIGNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHM6IGZ1bmN0aW9uIGNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMobmV4dFByb3BzKSB7XG4gICAgICAgIGlmICh0aGlzLnByb3BzLm5vZGVQcm92aWRlclByb3BlcnRpZXMgJiYgdGhpcy5wcm9wcy5ub2RlUHJvdmlkZXJQcm9wZXJ0aWVzICE9PSBuZXh0UHJvcHMubm9kZVByb3ZpZGVyUHJvcGVydGllcykge1xuICAgICAgICAgICAgdmFyIF9zdGF0ZSA9IHRoaXMuc3RhdGU7XG4gICAgICAgICAgICB2YXIgZGF0YU1vZGVsID0gX3N0YXRlLmRhdGFNb2RlbDtcbiAgICAgICAgICAgIHZhciBub2RlID0gX3N0YXRlLm5vZGU7XG5cbiAgICAgICAgICAgIHZhciBwcm92aWRlciA9IG5ldyBSZW1vdGVOb2RlUHJvdmlkZXIobmV4dFByb3BzLm5vZGVQcm92aWRlclByb3BlcnRpZXMpO1xuICAgICAgICAgICAgZGF0YU1vZGVsLnNldEFqeHBOb2RlUHJvdmlkZXIocHJvdmlkZXIpO1xuICAgICAgICAgICAgbm9kZS51cGRhdGVQcm92aWRlcihwcm92aWRlcik7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgZGF0YU1vZGVsOiBkYXRhTW9kZWwsIG5vZGU6IG5vZGUgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5wcm9wcy5wcmVzZXREYXRhTW9kZWwgIT09IG5leHRQcm9wcy5wcmVzZXREYXRhTW9kZWwpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgICAgIGRhdGFNb2RlbDogbmV4dFByb3BzLnByZXNldERhdGFNb2RlbCxcbiAgICAgICAgICAgICAgICBub2RlOiBuZXh0UHJvcHMucHJlc2V0RGF0YU1vZGVsLmdldFJvb3ROb2RlKClcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIGdldEluaXRpYWxTdGF0ZTogZnVuY3Rpb24gZ2V0SW5pdGlhbFN0YXRlKCkge1xuXG4gICAgICAgIHZhciBkYXRhTW9kZWwgPSB1bmRlZmluZWQ7XG4gICAgICAgIGlmICh0aGlzLnByb3BzLnByZXNldERhdGFNb2RlbCkge1xuICAgICAgICAgICAgZGF0YU1vZGVsID0gdGhpcy5wcm9wcy5wcmVzZXREYXRhTW9kZWw7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBkYXRhTW9kZWwgPSBQeWRpb0RhdGFNb2RlbC5SZW1vdGVEYXRhTW9kZWxGYWN0b3J5KHRoaXMucHJvcHMubm9kZVByb3ZpZGVyUHJvcGVydGllcyk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHJvb3ROb2RlID0gZGF0YU1vZGVsLmdldFJvb3ROb2RlKCk7XG4gICAgICAgIGlmICh0aGlzLnByb3BzLm5vZGVDbGlja2VkKSB7XG4gICAgICAgICAgICAvLyBsZWFmXG4gICAgICAgICAgICB0aGlzLm9wZW5FZGl0b3IgPSAoZnVuY3Rpb24gKG5vZGUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnByb3BzLm5vZGVDbGlja2VkKG5vZGUpO1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH0pLmJpbmQodGhpcyk7XG4gICAgICAgICAgICAvLyBkaXJcbiAgICAgICAgICAgIGRhdGFNb2RlbC5vYnNlcnZlKFwic2VsZWN0aW9uX2NoYW5nZWRcIiwgKGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICAgICAgICAgIHZhciBzZWxlY3RlZE5vZGVzID0gZXZlbnQubWVtby5nZXRTZWxlY3RlZE5vZGVzKCk7XG4gICAgICAgICAgICAgICAgaWYgKHNlbGVjdGVkTm9kZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucHJvcHMubm9kZUNsaWNrZWQoc2VsZWN0ZWROb2Rlc1swXSk7XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50Lm1lbW8uc2V0U2VsZWN0ZWROb2RlcyhbXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSkuYmluZCh0aGlzKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMucHJvcHMucmVsb2FkT25TZXJ2ZXJNZXNzYWdlICYmIHRoaXMucHJvcHMucHlkaW8pIHtcbiAgICAgICAgICAgIHRoaXMuX3NtT2JzID0gKGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICAgICAgICAgIGlmIChYTUxVdGlscy5YUGF0aFNlbGVjdFNpbmdsZU5vZGUoZXZlbnQsIHRoaXMucHJvcHMucmVsb2FkT25TZXJ2ZXJNZXNzYWdlKSkgdGhpcy5yZWxvYWQoKTtcbiAgICAgICAgICAgIH0pLmJpbmQodGhpcyk7XG4gICAgICAgICAgICB0aGlzLnByb3BzLnB5ZGlvLm9ic2VydmUoXCJzZXJ2ZXJfbWVzc2FnZVwiLCB0aGlzLl9zbU9icyk7XG4gICAgICAgICAgICB0aGlzLnByb3BzLnB5ZGlvLm9ic2VydmUoXCJzZXJ2ZXJfbWVzc2FnZTpcIiArIHRoaXMucHJvcHMucmVsb2FkT25TZXJ2ZXJNZXNzYWdlLCB0aGlzLnJlbG9hZCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsgbm9kZTogcm9vdE5vZGUsIGRhdGFNb2RlbDogZGF0YU1vZGVsIH07XG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgICB2YXIgbGVnZW5kO1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5sZWdlbmQpIHtcbiAgICAgICAgICAgIGxlZ2VuZCA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgXCJkaXZcIixcbiAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogXCJzdWJ0aXRsZVwiIH0sXG4gICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5sZWdlbmRcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICBcImRpdlwiLFxuICAgICAgICAgICAgeyBjbGFzc05hbWU6IHRoaXMucHJvcHMuaGVpZ2h0QXV0b1dpdGhNYXggPyBcIlwiIDogXCJsYXlvdXQtZmlsbCB2ZXJ0aWNhbC1sYXlvdXRcIiB9LFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChfU2ltcGxlTGlzdDJbXCJkZWZhdWx0XCJdLCBfZXh0ZW5kcyh7fSwgdGhpcy5wcm9wcywge1xuICAgICAgICAgICAgICAgIG9wZW5FZGl0b3I6IHRoaXMub3BlbkVkaXRvcixcbiAgICAgICAgICAgICAgICByZWY6IFwibGlzdFwiLFxuICAgICAgICAgICAgICAgIHN0eWxlOiBPYmplY3QuYXNzaWduKHsgaGVpZ2h0OiAnMTAwJScgfSwgdGhpcy5wcm9wcy5zdHlsZSB8fCB7fSksXG4gICAgICAgICAgICAgICAgbm9kZTogdGhpcy5zdGF0ZS5ub2RlLFxuICAgICAgICAgICAgICAgIGRhdGFNb2RlbDogdGhpcy5zdGF0ZS5kYXRhTW9kZWwsXG4gICAgICAgICAgICAgICAgYWN0aW9uQmFyR3JvdXBzOiB0aGlzLnByb3BzLmFjdGlvbkJhckdyb3VwcyxcbiAgICAgICAgICAgICAgICBza2lwUGFyZW50TmF2aWdhdGlvbjogdHJ1ZSxcbiAgICAgICAgICAgICAgICBvYnNlcnZlTm9kZVJlbG9hZDogdHJ1ZVxuICAgICAgICAgICAgfSkpXG4gICAgICAgICk7XG4gICAgfVxuXG59KTtcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1tcImRlZmF1bHRcIl07XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMDctMjAxNyBDaGFybGVzIGR1IEpldSAtIEFic3RyaXVtIFNBUyA8dGVhbSAoYXQpIHB5ZC5pbz5cbiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIFB5ZGlvLlxuICpcbiAqIFB5ZGlvIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3JcbiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogUHlkaW8gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggUHlkaW8uICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gKlxuICogVGhlIGxhdGVzdCBjb2RlIGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9weWRpby5jb20+LlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxudmFyIF9leHRlbmRzID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiAodGFyZ2V0KSB7IGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7IHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV07IGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHsgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHsgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTsgfSB9IH0gcmV0dXJuIHRhcmdldDsgfTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgJ2RlZmF1bHQnOiBvYmogfTsgfVxuXG52YXIgX3JlYWN0U2Nyb2xsYmFyID0gcmVxdWlyZSgncmVhY3Qtc2Nyb2xsYmFyJyk7XG5cbnZhciBfcmVhY3RTY3JvbGxiYXIyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfcmVhY3RTY3JvbGxiYXIpO1xuXG52YXIgX3V0aWxNZXNzYWdlc0NvbnN1bWVyTWl4aW4gPSByZXF1aXJlKCcuLi91dGlsL01lc3NhZ2VzQ29uc3VtZXJNaXhpbicpO1xuXG52YXIgX3V0aWxNZXNzYWdlc0NvbnN1bWVyTWl4aW4yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfdXRpbE1lc3NhZ2VzQ29uc3VtZXJNaXhpbik7XG5cbnZhciBfTGlzdEVudHJ5ID0gcmVxdWlyZSgnLi9MaXN0RW50cnknKTtcblxudmFyIF9UYWJsZUxpc3RFbnRyeSA9IHJlcXVpcmUoJy4vVGFibGVMaXN0RW50cnknKTtcblxudmFyIF9UYWJsZUxpc3RFbnRyeTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9UYWJsZUxpc3RFbnRyeSk7XG5cbnZhciBfVGFibGVMaXN0SGVhZGVyID0gcmVxdWlyZSgnLi9UYWJsZUxpc3RIZWFkZXInKTtcblxudmFyIF9UYWJsZUxpc3RIZWFkZXIyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfVGFibGVMaXN0SGVhZGVyKTtcblxudmFyIF9Db25maWd1cmFibGVMaXN0RW50cnkgPSByZXF1aXJlKCcuL0NvbmZpZ3VyYWJsZUxpc3RFbnRyeScpO1xuXG52YXIgX0NvbmZpZ3VyYWJsZUxpc3RFbnRyeTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9Db25maWd1cmFibGVMaXN0RW50cnkpO1xuXG52YXIgX1NvcnRDb2x1bW5zID0gcmVxdWlyZSgnLi9Tb3J0Q29sdW1ucycpO1xuXG52YXIgX1NvcnRDb2x1bW5zMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1NvcnRDb2x1bW5zKTtcblxudmFyIF9MaXN0UGFnaW5hdG9yID0gcmVxdWlyZSgnLi9MaXN0UGFnaW5hdG9yJyk7XG5cbnZhciBfTGlzdFBhZ2luYXRvcjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9MaXN0UGFnaW5hdG9yKTtcblxudmFyIF92aWV3c1NpbXBsZVJlYWN0QWN0aW9uQmFyID0gcmVxdWlyZSgnLi4vdmlld3MvU2ltcGxlUmVhY3RBY3Rpb25CYXInKTtcblxudmFyIF92aWV3c1NpbXBsZVJlYWN0QWN0aW9uQmFyMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3ZpZXdzU2ltcGxlUmVhY3RBY3Rpb25CYXIpO1xuXG52YXIgX0lubGluZUVkaXRvciA9IHJlcXVpcmUoJy4vSW5saW5lRWRpdG9yJyk7XG5cbnZhciBfSW5saW5lRWRpdG9yMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX0lubGluZUVkaXRvcik7XG5cbnZhciBfdmlld3NFbXB0eVN0YXRlVmlldyA9IHJlcXVpcmUoJy4uL3ZpZXdzL0VtcHR5U3RhdGVWaWV3Jyk7XG5cbnZhciBfdmlld3NFbXB0eVN0YXRlVmlldzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF92aWV3c0VtcHR5U3RhdGVWaWV3KTtcblxudmFyIFJlYWN0ID0gcmVxdWlyZSgncmVhY3QnKTtcbnZhciBJbmZpbml0ZSA9IHJlcXVpcmUoJ3JlYWN0LWluZmluaXRlJyk7XG5cbnZhciBET01VdGlscyA9IHJlcXVpcmUoJ3B5ZGlvL3V0aWwvZG9tJyk7XG52YXIgTGFuZ1V0aWxzID0gcmVxdWlyZSgncHlkaW8vdXRpbC9sYW5nJyk7XG52YXIgUHlkaW9EYXRhTW9kZWwgPSByZXF1aXJlKCdweWRpby9tb2RlbC9kYXRhLW1vZGVsJyk7XG52YXIgUGVyaW9kaWNhbEV4ZWN1dGVyID0gcmVxdWlyZSgncHlkaW8vdXRpbC9wZXJpb2RpY2FsLWV4ZWN1dGVyJyk7XG5cbi8qKlxuICogR2VuZXJpYyBMaXN0IGNvbXBvbmVudCwgdXNpbmcgSW5maW5pdGUgZm9yIGNlbGwgdmlydHVhbGl6YXRpb24sIHBhZ2luYXRpb24sIHZhcmlvdXNcbiAqIGRpc3BsYXlzLCBldGMuLi4gSXQgcHJvdmlkZXMgbWFueSBob29rcyBmb3IgcmVuZGVyaW5nIGNlbGxzIG9uLWRlbWFuZC5cbiAqL1xudmFyIFNpbXBsZUxpc3QgPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG4gICAgZGlzcGxheU5hbWU6ICdTaW1wbGVMaXN0JyxcblxuICAgIG1peGluczogW191dGlsTWVzc2FnZXNDb25zdW1lck1peGluMlsnZGVmYXVsdCddXSxcblxuICAgIHByb3BUeXBlczoge1xuICAgICAgICBpbmZpbml0ZVNsaWNlQ291bnQ6IFJlYWN0LlByb3BUeXBlcy5udW1iZXIsXG4gICAgICAgIGZpbHRlck5vZGVzOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgICAgICAgY3VzdG9tVG9vbGJhcjogUmVhY3QuUHJvcFR5cGVzLm9iamVjdCxcbiAgICAgICAgdGFibGVLZXlzOiBSZWFjdC5Qcm9wVHlwZXMub2JqZWN0LFxuICAgICAgICBhdXRvUmVmcmVzaDogUmVhY3QuUHJvcFR5cGVzLm51bWJlcixcbiAgICAgICAgcmVsb2FkQXRDdXJzb3I6IFJlYWN0LlByb3BUeXBlcy5ib29sLFxuICAgICAgICBjbGVhclNlbGVjdGlvbk9uUmVsb2FkOiBSZWFjdC5Qcm9wVHlwZXMuYm9vbCxcbiAgICAgICAgaGVpZ2h0QXV0b1dpdGhNYXg6IFJlYWN0LlByb3BUeXBlcy5udW1iZXIsXG4gICAgICAgIGNvbnRhaW5lckhlaWdodDogUmVhY3QuUHJvcFR5cGVzLm51bWJlcixcbiAgICAgICAgb2JzZXJ2ZU5vZGVSZWxvYWQ6IFJlYWN0LlByb3BUeXBlcy5ib29sLFxuICAgICAgICBkZWZhdWx0R3JvdXBCeTogUmVhY3QuUHJvcFR5cGVzLnN0cmluZyxcbiAgICAgICAgZGVmYXVsdEdyb3VwQnlMYWJlbDogUmVhY3QuUHJvcFR5cGVzLnN0cmluZyxcbiAgICAgICAgZGVmYXVsdFNvcnRpbmdJbmZvOiBSZWFjdC5Qcm9wVHlwZXMub2JqZWN0LFxuXG4gICAgICAgIHNraXBQYXJlbnROYXZpZ2F0aW9uOiBSZWFjdC5Qcm9wVHlwZXMuYm9vbCxcbiAgICAgICAgc2tpcEludGVybmFsRGF0YU1vZGVsOiBSZWFjdC5Qcm9wVHlwZXMuYm9vbCxcbiAgICAgICAgZGVsYXlJbml0aWFsTG9hZDogUmVhY3QuUHJvcFR5cGVzLm51bWJlcixcblxuICAgICAgICBlbnRyeUVuYWJsZVNlbGVjdG9yOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgICAgICAgcmVuZGVyQ3VzdG9tRW50cnk6IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgICAgICBlbnRyeVJlbmRlckljb246IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgICAgICBlbnRyeVJlbmRlckFjdGlvbnM6IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgICAgICBlbnRyeVJlbmRlckZpcnN0TGluZTogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsXG4gICAgICAgIGVudHJ5UmVuZGVyU2Vjb25kTGluZTogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsXG4gICAgICAgIGVudHJ5UmVuZGVyVGhpcmRMaW5lOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgICAgICAgZW50cnlIYW5kbGVDbGlja3M6IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgICAgICBoaWRlVG9vbGJhcjogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXG4gICAgICAgIGNvbXB1dGVBY3Rpb25zRm9yTm9kZTogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXG4gICAgICAgIG11bHRpcGxlQWN0aW9uczogUmVhY3QuUHJvcFR5cGVzLmFycmF5LFxuXG4gICAgICAgIG9wZW5FZGl0b3I6IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgICAgICBvcGVuQ29sbGVjdGlvbjogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsXG5cbiAgICAgICAgZWxlbWVudFN0eWxlOiBSZWFjdC5Qcm9wVHlwZXMub2JqZWN0LFxuICAgICAgICBwYXNzU2Nyb2xsaW5nU3RhdGVUb0NoaWxkcmVuOiBSZWFjdC5Qcm9wVHlwZXMuYm9vbCxcbiAgICAgICAgZWxlbWVudEhlaWdodDogUmVhY3QuUHJvcFR5cGVzLm9uZU9mVHlwZShbUmVhY3QuUHJvcFR5cGVzLm51bWJlciwgUmVhY3QuUHJvcFR5cGVzLm9iamVjdF0pLmlzUmVxdWlyZWRcblxuICAgIH0sXG5cbiAgICBzdGF0aWNzOiB7XG4gICAgICAgIEhFSUdIVF9PTkVfTElORTogNTAsXG4gICAgICAgIEhFSUdIVF9UV09fTElORVM6IDczLFxuICAgICAgICBDTElDS19UWVBFX1NJTVBMRTogJ3NpbXBsZScsXG4gICAgICAgIENMSUNLX1RZUEVfRE9VQkxFOiAnZG91YmxlJyxcbiAgICAgICAgUEFSRU5UX0ZPTERFUl9JQ09OOiAnbWRpIG1kaS1jaGV2cm9uLWxlZnQnXG4gICAgfSxcblxuICAgIGdldERlZmF1bHRQcm9wczogZnVuY3Rpb24gZ2V0RGVmYXVsdFByb3BzKCkge1xuICAgICAgICByZXR1cm4geyBpbmZpbml0ZVNsaWNlQ291bnQ6IDMwLCBjbGVhclNlbGVjdGlvbk9uUmVsb2FkOiB0cnVlIH07XG4gICAgfSxcblxuICAgIGNsaWNrUm93OiBmdW5jdGlvbiBjbGlja1JvdyhncmlkUm93LCBldmVudCkge1xuICAgICAgICB2YXIgbm9kZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKGdyaWRSb3cucHJvcHMpIHtcbiAgICAgICAgICAgIG5vZGUgPSBncmlkUm93LnByb3BzLmRhdGEubm9kZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG5vZGUgPSBncmlkUm93O1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnByb3BzLmVudHJ5SGFuZGxlQ2xpY2tzKSB7XG4gICAgICAgICAgICB0aGlzLnByb3BzLmVudHJ5SGFuZGxlQ2xpY2tzKG5vZGUsIFNpbXBsZUxpc3QuQ0xJQ0tfVFlQRV9TSU1QTEUsIGV2ZW50KTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAobm9kZS5pc0xlYWYoKSAmJiB0aGlzLnByb3BzLm9wZW5FZGl0b3IpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnByb3BzLm9wZW5FZGl0b3Iobm9kZSkgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIHVuaXF1ZVNlbGVjdGlvbiA9IG5ldyBNYXAoKTtcbiAgICAgICAgICAgIHVuaXF1ZVNlbGVjdGlvbi5zZXQobm9kZSwgdHJ1ZSk7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgc2VsZWN0aW9uOiB1bmlxdWVTZWxlY3Rpb24gfSwgdGhpcy5yZWJ1aWxkTG9hZGVkRWxlbWVudHMpO1xuICAgICAgICB9IGVsc2UgaWYgKCFub2RlLmlzTGVhZigpKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5wcm9wcy5vcGVuQ29sbGVjdGlvbikge1xuICAgICAgICAgICAgICAgIHRoaXMucHJvcHMub3BlbkNvbGxlY3Rpb24obm9kZSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMucHJvcHMuZGF0YU1vZGVsLnNldFNlbGVjdGVkTm9kZXMoW25vZGVdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBkb3VibGVDbGlja1JvdzogZnVuY3Rpb24gZG91YmxlQ2xpY2tSb3coZ3JpZFJvdywgZXZlbnQpIHtcbiAgICAgICAgdmFyIG5vZGUgPSB1bmRlZmluZWQ7XG4gICAgICAgIGlmIChncmlkUm93LnByb3BzKSB7XG4gICAgICAgICAgICBub2RlID0gZ3JpZFJvdy5wcm9wcy5kYXRhLm5vZGU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBub2RlID0gZ3JpZFJvdztcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5wcm9wcy5lbnRyeUhhbmRsZUNsaWNrcykge1xuICAgICAgICAgICAgdGhpcy5wcm9wcy5lbnRyeUhhbmRsZUNsaWNrcyhub2RlLCBTaW1wbGVMaXN0LkNMSUNLX1RZUEVfRE9VQkxFLCBldmVudCk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgb25Db2x1bW5Tb3J0OiBmdW5jdGlvbiBvbkNvbHVtblNvcnQoY29sdW1uKSB7XG4gICAgICAgIHZhciBzdGF0ZVNldENhbGxiYWNrID0gYXJndW1lbnRzLmxlbmd0aCA8PSAxIHx8IGFyZ3VtZW50c1sxXSA9PT0gdW5kZWZpbmVkID8gbnVsbCA6IGFyZ3VtZW50c1sxXTtcblxuICAgICAgICB2YXIgcGFnaW5hdGlvbiA9IHRoaXMucHJvcHMubm9kZS5nZXRNZXRhZGF0YSgpLmdldCgncGFnaW5hdGlvbkRhdGEnKTtcbiAgICAgICAgaWYgKHBhZ2luYXRpb24gJiYgcGFnaW5hdGlvbi5nZXQoJ3RvdGFsJykgPiAxICYmIHBhZ2luYXRpb24uZ2V0KCdyZW1vdGVfb3JkZXInKSkge1xuXG4gICAgICAgICAgICB2YXIgZGlyID0gJ2FzYyc7XG4gICAgICAgICAgICBpZiAodGhpcy5wcm9wcy5ub2RlLmdldE1ldGFkYXRhKCkuZ2V0KCdwYWdpbmF0aW9uRGF0YScpLmdldCgnY3VycmVudE9yZGVyRGlyJykpIHtcbiAgICAgICAgICAgICAgICBkaXIgPSB0aGlzLnByb3BzLm5vZGUuZ2V0TWV0YWRhdGEoKS5nZXQoJ3BhZ2luYXRpb25EYXRhJykuZ2V0KCdjdXJyZW50T3JkZXJEaXInKSA9PT0gJ2FzYycgPyAnZGVzYycgOiAnYXNjJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBvcmRlckRhdGEgPSBuZXcgTWFwKCk7XG4gICAgICAgICAgICBvcmRlckRhdGEuc2V0KCdvcmRlcl9jb2x1bW4nLCBjb2x1bW5bJ3JlbW90ZVNvcnRBdHRyaWJ1dGUnXSA/IGNvbHVtbi5yZW1vdGVTb3J0QXR0cmlidXRlIDogY29sdW1uLm5hbWUpO1xuICAgICAgICAgICAgb3JkZXJEYXRhLnNldCgnb3JkZXJfZGlyZWN0aW9uJywgZGlyKTtcbiAgICAgICAgICAgIHRoaXMucHJvcHMubm9kZS5nZXRNZXRhZGF0YSgpLnNldChcInJlbW90ZV9vcmRlclwiLCBvcmRlckRhdGEpO1xuICAgICAgICAgICAgdGhpcy5wcm9wcy5kYXRhTW9kZWwucmVxdWlyZUNvbnRleHRDaGFuZ2UodGhpcy5wcm9wcy5ub2RlLCB0cnVlKTtcbiAgICAgICAgfSBlbHNlIHtcblxuICAgICAgICAgICAgdmFyIGF0dCA9IGNvbHVtblsnc29ydEF0dHJpYnV0ZSddID8gY29sdW1uWydzb3J0QXR0cmlidXRlJ10gOiBjb2x1bW4ubmFtZTtcbiAgICAgICAgICAgIHZhciBzb3J0aW5nSW5mbyA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIHZhciBfc3RhdGUkc29ydGluZ0luZm8gPSB0aGlzLnN0YXRlLnNvcnRpbmdJbmZvO1xuICAgICAgICAgICAgdmFyIGF0dHJpYnV0ZSA9IF9zdGF0ZSRzb3J0aW5nSW5mby5hdHRyaWJ1dGU7XG4gICAgICAgICAgICB2YXIgZGlyZWN0aW9uID0gX3N0YXRlJHNvcnRpbmdJbmZvLmRpcmVjdGlvbjtcblxuICAgICAgICAgICAgaWYgKGF0dHJpYnV0ZSA9PT0gYXR0ICYmIGRpcmVjdGlvbikge1xuICAgICAgICAgICAgICAgIGlmIChkaXJlY3Rpb24gPT09ICdhc2MnKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFN3aXRjaCBkaXJlY3Rpb25cbiAgICAgICAgICAgICAgICAgICAgc29ydGluZ0luZm8gPSB7IGF0dHJpYnV0ZTogYXR0LCBzb3J0VHlwZTogY29sdW1uLnNvcnRUeXBlLCBkaXJlY3Rpb246ICdkZXNjJyB9O1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFJlc2V0IHNvcnRpbmdcbiAgICAgICAgICAgICAgICAgICAgc29ydGluZ0luZm8gPSB0aGlzLnByb3BzLmRlZmF1bHRTb3J0aW5nSW5mbyB8fCB7fTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHNvcnRpbmdJbmZvID0geyBhdHRyaWJ1dGU6IGF0dCwgc29ydFR5cGU6IGNvbHVtbi5zb3J0VHlwZSwgZGlyZWN0aW9uOiAnYXNjJyB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNvcnRpbmdJbmZvOiBzb3J0aW5nSW5mbyB9LCAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHRoaXMucmVidWlsZExvYWRlZEVsZW1lbnRzKCk7XG4gICAgICAgICAgICAgICAgaWYgKHN0YXRlU2V0Q2FsbGJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgc3RhdGVTZXRDYWxsYmFjaygpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pLmJpbmQodGhpcykpO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIGNvbXB1dGVTZWxlY3Rpb25Gcm9tQ3VycmVudFBsdXNUYXJnZXROb2RlOiBmdW5jdGlvbiBjb21wdXRlU2VsZWN0aW9uRnJvbUN1cnJlbnRQbHVzVGFyZ2V0Tm9kZShjdXJyZW50U2VsZWN0aW9uLCB0YXJnZXROb2RlKSB7XG5cbiAgICAgICAgdmFyIGN1cnJlbnRJbmRleFN0YXJ0ID0gdW5kZWZpbmVkLFxuICAgICAgICAgICAgY3VycmVudEluZGV4RW5kID0gdW5kZWZpbmVkLFxuICAgICAgICAgICAgbm9kZUJlZm9yZSA9IGZhbHNlO1xuICAgICAgICBpZiAoIXRoaXMuaW5kZXhlZEVsZW1lbnRzKSB7XG4gICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGZpcnN0U2VsZWN0ZWQgPSBjdXJyZW50U2VsZWN0aW9uWzBdO1xuICAgICAgICB2YXIgbGFzdFNlbGVjdGVkID0gY3VycmVudFNlbGVjdGlvbltjdXJyZW50U2VsZWN0aW9uLmxlbmd0aCAtIDFdO1xuICAgICAgICB2YXIgbmV3U2VsZWN0aW9uID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5pbmRleGVkRWxlbWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmIChjdXJyZW50SW5kZXhTdGFydCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgbmV3U2VsZWN0aW9uLnB1c2godGhpcy5pbmRleGVkRWxlbWVudHNbaV0ubm9kZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5pbmRleGVkRWxlbWVudHNbaV0ubm9kZSA9PT0gdGFyZ2V0Tm9kZSkge1xuICAgICAgICAgICAgICAgIGlmIChjdXJyZW50SW5kZXhTdGFydCAhPT0gdW5kZWZpbmVkICYmIGN1cnJlbnRJbmRleEVuZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRJbmRleEVuZCA9IGk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjdXJyZW50SW5kZXhTdGFydCA9IGk7XG4gICAgICAgICAgICAgICAgbm9kZUJlZm9yZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgbmV3U2VsZWN0aW9uLnB1c2godGhpcy5pbmRleGVkRWxlbWVudHNbaV0ubm9kZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5pbmRleGVkRWxlbWVudHNbaV0ubm9kZSA9PT0gZmlyc3RTZWxlY3RlZCAmJiBjdXJyZW50SW5kZXhTdGFydCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgY3VycmVudEluZGV4U3RhcnQgPSBpO1xuICAgICAgICAgICAgICAgIG5ld1NlbGVjdGlvbi5wdXNoKHRoaXMuaW5kZXhlZEVsZW1lbnRzW2ldLm5vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuaW5kZXhlZEVsZW1lbnRzW2ldLm5vZGUgPT09IGxhc3RTZWxlY3RlZCAmJiBub2RlQmVmb3JlKSB7XG4gICAgICAgICAgICAgICAgY3VycmVudEluZGV4RW5kID0gaTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3U2VsZWN0aW9uO1xuICAgIH0sXG5cbiAgICBvbktleURvd246IGZ1bmN0aW9uIG9uS2V5RG93bihlKSB7XG4gICAgICAgIHZhciBjdXJyZW50SW5kZXhTdGFydCA9IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGN1cnJlbnRJbmRleEVuZCA9IHVuZGVmaW5lZDtcbiAgICAgICAgdmFyIGNvbnRleHRIb2xkZXIgPSB3aW5kb3cucHlkaW8uZ2V0Q29udGV4dEhvbGRlcigpO1xuICAgICAgICB2YXIgZWxlbWVudHNQZXJMaW5lID0gdGhpcy5wcm9wcy5lbGVtZW50c1BlckxpbmUgfHwgMTtcbiAgICAgICAgdmFyIHNoaWZ0S2V5ID0gZS5zaGlmdEtleTtcbiAgICAgICAgdmFyIGtleSA9IGUua2V5O1xuXG4gICAgICAgIGlmIChjb250ZXh0SG9sZGVyLmlzRW1wdHkoKSB8fCAhdGhpcy5pbmRleGVkRWxlbWVudHMpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgZG93bktleXMgPSBbJ0Fycm93RG93bicsICdBcnJvd1JpZ2h0JywgJ1BhZ2VEb3duJywgJ0VuZCddO1xuXG4gICAgICAgIHZhciBwb3NpdGlvbiA9IHNoaWZ0S2V5ICYmIGRvd25LZXlzLmluZGV4T2Yoa2V5KSA+IC0xID8gJ2ZpcnN0JyA6ICdsYXN0JztcbiAgICAgICAgdmFyIGN1cnJlbnRTZWxlY3Rpb24gPSBjb250ZXh0SG9sZGVyLmdldFNlbGVjdGVkTm9kZXMoKTtcblxuICAgICAgICB2YXIgZmlyc3RTZWxlY3RlZCA9IGN1cnJlbnRTZWxlY3Rpb25bMF07XG4gICAgICAgIHZhciBsYXN0U2VsZWN0ZWQgPSBjdXJyZW50U2VsZWN0aW9uW2N1cnJlbnRTZWxlY3Rpb24ubGVuZ3RoIC0gMV07XG5cbiAgICAgICAgaWYgKGtleSA9PT0gJ0VudGVyJykge1xuICAgICAgICAgICAgdGhpcy5kb3VibGVDbGlja1JvdyhmaXJzdFNlbGVjdGVkKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoa2V5ID09PSAnRGVsZXRlJyAmJiBnbG9iYWwucHlkaW8uQ29udHJvbGxlci5maXJlQWN0aW9uQnlLZXkoJ2tleV9kZWxldGUnKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmluZGV4ZWRFbGVtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgaWYgKHRoaXMuaW5kZXhlZEVsZW1lbnRzW2ldLm5vZGUgPT09IGZpcnN0U2VsZWN0ZWQpIHtcbiAgICAgICAgICAgICAgICBjdXJyZW50SW5kZXhTdGFydCA9IGk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5pbmRleGVkRWxlbWVudHNbaV0ubm9kZSA9PT0gbGFzdFNlbGVjdGVkKSB7XG4gICAgICAgICAgICAgICAgY3VycmVudEluZGV4RW5kID0gaTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB2YXIgc2VsZWN0aW9uSW5kZXggPSB1bmRlZmluZWQ7XG4gICAgICAgIHZhciBtYXhJbmRleCA9IHRoaXMuaW5kZXhlZEVsZW1lbnRzLmxlbmd0aCAtIDE7XG4gICAgICAgIHZhciBpbmNyZW1lbnQgPSBrZXkgPT09ICdQYWdlRG93bicgfHwga2V5ID09PSAnUGFnZVVwJyA/IDEwIDogMTtcbiAgICAgICAgaWYgKGtleSA9PT0gJ0Fycm93RG93bicgfHwga2V5ID09PSAnUGFnZURvd24nKSB7XG4gICAgICAgICAgICBzZWxlY3Rpb25JbmRleCA9IE1hdGgubWluKGN1cnJlbnRJbmRleEVuZCArIGVsZW1lbnRzUGVyTGluZSAqIGluY3JlbWVudCwgbWF4SW5kZXgpO1xuICAgICAgICB9IGVsc2UgaWYgKGtleSA9PT0gJ0Fycm93VXAnIHx8IGtleSA9PT0gJ1BhZ2VVcCcpIHtcbiAgICAgICAgICAgIHNlbGVjdGlvbkluZGV4ID0gTWF0aC5tYXgoY3VycmVudEluZGV4U3RhcnQgLSBlbGVtZW50c1BlckxpbmUgKiBpbmNyZW1lbnQsIDApO1xuICAgICAgICB9IGVsc2UgaWYgKGtleSA9PT0gJ0hvbWUnKSB7XG4gICAgICAgICAgICBzZWxlY3Rpb25JbmRleCA9IDA7XG4gICAgICAgIH0gZWxzZSBpZiAoa2V5ID09PSAnRW5kJykge1xuICAgICAgICAgICAgc2VsZWN0aW9uSW5kZXggPSBtYXhJbmRleDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZWxlbWVudHNQZXJMaW5lID4gMSkge1xuICAgICAgICAgICAgaWYgKGtleSA9PT0gJ0Fycm93UmlnaHQnKSB7XG4gICAgICAgICAgICAgICAgc2VsZWN0aW9uSW5kZXggPSBjdXJyZW50SW5kZXhFbmQgKyAxO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChrZXkgPT09ICdBcnJvd0xlZnQnKSB7XG4gICAgICAgICAgICAgICAgc2VsZWN0aW9uSW5kZXggPSBjdXJyZW50SW5kZXhTdGFydCAtIDE7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoc2hpZnRLZXkgJiYgc2VsZWN0aW9uSW5kZXggIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdmFyIG1pbiA9IE1hdGgubWluKGN1cnJlbnRJbmRleFN0YXJ0LCBjdXJyZW50SW5kZXhFbmQsIHNlbGVjdGlvbkluZGV4KTtcbiAgICAgICAgICAgIHZhciBtYXggPSBNYXRoLm1heChjdXJyZW50SW5kZXhTdGFydCwgY3VycmVudEluZGV4RW5kLCBzZWxlY3Rpb25JbmRleCk7XG4gICAgICAgICAgICBpZiAobWluICE9PSBtYXgpIHtcbiAgICAgICAgICAgICAgICB2YXIgc2VsZWN0aW9uID0gW107XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IG1pbjsgaSA8IG1heCArIDE7IGkrKykge1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5pbmRleGVkRWxlbWVudHNbaV0pIHNlbGVjdGlvbi5wdXNoKHRoaXMuaW5kZXhlZEVsZW1lbnRzW2ldLm5vZGUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb250ZXh0SG9sZGVyLnNldFNlbGVjdGVkTm9kZXMoc2VsZWN0aW9uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLmluZGV4ZWRFbGVtZW50c1tzZWxlY3Rpb25JbmRleF0gJiYgdGhpcy5pbmRleGVkRWxlbWVudHNbc2VsZWN0aW9uSW5kZXhdLm5vZGUpIHtcbiAgICAgICAgICAgIGNvbnRleHRIb2xkZXIuc2V0U2VsZWN0ZWROb2RlcyhbdGhpcy5pbmRleGVkRWxlbWVudHNbc2VsZWN0aW9uSW5kZXhdLm5vZGVdKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBnZXRJbml0aWFsU3RhdGU6IGZ1bmN0aW9uIGdldEluaXRpYWxTdGF0ZSgpIHtcbiAgICAgICAgdGhpcy5hY3Rpb25zQ2FjaGUgPSB7IG11bHRpcGxlOiBuZXcgTWFwKCkgfTtcbiAgICAgICAgaWYgKCF0aGlzLnByb3BzLnNraXBJbnRlcm5hbERhdGFNb2RlbCkge1xuICAgICAgICAgICAgdGhpcy5kbSA9IG5ldyBQeWRpb0RhdGFNb2RlbCgpO1xuICAgICAgICAgICAgdGhpcy5kbS5zZXRSb290Tm9kZSh0aGlzLnByb3BzLmRhdGFNb2RlbC5nZXRDb250ZXh0Tm9kZSgpKTtcbiAgICAgICAgICAgIHRoaXMuZG0uc2V0Q29udGV4dE5vZGUodGhpcy5wcm9wcy5kYXRhTW9kZWwuZ2V0Q29udGV4dE5vZGUoKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmRtID0gdGhpcy5wcm9wcy5kYXRhTW9kZWw7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHNvcnRpbmdJbmZvID0gdGhpcy5wcm9wcy5kZWZhdWx0U29ydGluZ0luZm8gfHwgbnVsbDtcbiAgICAgICAgdmFyIHN0YXRlID0ge1xuICAgICAgICAgICAgbG9hZGVkOiB0aGlzLnByb3BzLm5vZGUuaXNMb2FkZWQoKSxcbiAgICAgICAgICAgIGxvYWRpbmc6ICF0aGlzLnByb3BzLm5vZGUuaXNMb2FkZWQoKSxcbiAgICAgICAgICAgIHNob3dTZWxlY3RvcjogZmFsc2UsXG4gICAgICAgICAgICBlbGVtZW50czogdGhpcy5wcm9wcy5ub2RlLmlzTG9hZGVkKCkgPyB0aGlzLmJ1aWxkRWxlbWVudHMoc29ydGluZ0luZm8sIDAsIHRoaXMucHJvcHMuaW5maW5pdGVTbGljZUNvdW50KSA6IFtdLFxuICAgICAgICAgICAgY29udGFpbmVySGVpZ2h0OiB0aGlzLnByb3BzLmNvbnRhaW5lckhlaWdodCA/IHRoaXMucHJvcHMuY29udGFpbmVySGVpZ2h0IDogdGhpcy5wcm9wcy5oZWlnaHRBdXRvV2l0aE1heCA/IDAgOiA1MDAsXG4gICAgICAgICAgICBzb3J0aW5nSW5mbzogc29ydGluZ0luZm9cbiAgICAgICAgfTtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMuZWxlbWVudEhlaWdodCBpbnN0YW5jZW9mIE9iamVjdCkge1xuICAgICAgICAgICAgc3RhdGUuZWxlbWVudEhlaWdodCA9IHRoaXMuY29tcHV0ZUVsZW1lbnRIZWlnaHRSZXNwb25zaXZlKCk7XG4gICAgICAgIH1cbiAgICAgICAgc3RhdGUuaW5maW5pdGVMb2FkQmVnaW5Cb3R0b21PZmZzZXQgPSAyMDA7XG4gICAgICAgIHJldHVybiBzdGF0ZTtcbiAgICB9LFxuXG4gICAgY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wczogZnVuY3Rpb24gY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyhuZXh0UHJvcHMpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgICAgICB0aGlzLmluZGV4ZWRFbGVtZW50cyA9IG51bGw7XG4gICAgICAgIHZhciBjdXJyZW50TGVuZ3RoID0gTWF0aC5tYXgodGhpcy5zdGF0ZS5lbGVtZW50cy5sZW5ndGgsIG5leHRQcm9wcy5pbmZpbml0ZVNsaWNlQ291bnQpO1xuICAgICAgICB2YXIgc29ydGluZ0luZm8gPSB0aGlzLnN0YXRlLnNvcnRpbmdJbmZvIHx8IG5leHRQcm9wcy5kZWZhdWx0U29ydGluZ0luZm8gfHwgbnVsbDtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICBsb2FkZWQ6IG5leHRQcm9wcy5ub2RlLmlzTG9hZGVkKCksXG4gICAgICAgICAgICBsb2FkaW5nOiAhbmV4dFByb3BzLm5vZGUuaXNMb2FkZWQoKSxcbiAgICAgICAgICAgIHNob3dTZWxlY3RvcjogZmFsc2UsXG4gICAgICAgICAgICBlbGVtZW50czogbmV4dFByb3BzLm5vZGUuaXNMb2FkZWQoKSA/IHRoaXMuYnVpbGRFbGVtZW50cyhzb3J0aW5nSW5mbywgMCwgY3VycmVudExlbmd0aCwgbmV4dFByb3BzLm5vZGUpIDogW10sXG4gICAgICAgICAgICBpbmZpbml0ZUxvYWRCZWdpbkJvdHRvbU9mZnNldDogMjAwLFxuICAgICAgICAgICAgc29ydGluZ0luZm86IHNvcnRpbmdJbmZvXG4gICAgICAgIH0sIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmIChuZXh0UHJvcHMubm9kZS5pc0xvYWRlZCgpKSBfdGhpcy51cGRhdGVJbmZpbml0ZUNvbnRhaW5lckhlaWdodCgpO1xuICAgICAgICB9KTtcbiAgICAgICAgaWYgKCFuZXh0UHJvcHMuYXV0b1JlZnJlc2ggJiYgdGhpcy5yZWZyZXNoSW50ZXJ2YWwpIHtcbiAgICAgICAgICAgIHdpbmRvdy5jbGVhckludGVydmFsKHRoaXMucmVmcmVzaEludGVydmFsKTtcbiAgICAgICAgICAgIHRoaXMucmVmcmVzaEludGVydmFsID0gbnVsbDtcbiAgICAgICAgfSBlbHNlIGlmIChuZXh0UHJvcHMuYXV0b1JlZnJlc2ggJiYgIXRoaXMucmVmcmVzaEludGVydmFsKSB7XG4gICAgICAgICAgICB0aGlzLnJlZnJlc2hJbnRlcnZhbCA9IHdpbmRvdy5zZXRJbnRlcnZhbCh0aGlzLnJlbG9hZCwgbmV4dFByb3BzLmF1dG9SZWZyZXNoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnBhdGNoSW5maW5pdGVHcmlkKG5leHRQcm9wcy5lbGVtZW50c1BlckxpbmUpO1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5ub2RlICYmIG5leHRQcm9wcy5ub2RlICE9PSB0aGlzLnByb3BzLm5vZGUpIHtcbiAgICAgICAgICAgIHRoaXMub2JzZXJ2ZU5vZGVDaGlsZHJlbih0aGlzLnByb3BzLm5vZGUsIHRydWUpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl9tYW51YWxTY3JvbGxQZSkge1xuICAgICAgICAgICAgdGhpcy5fbWFudWFsU2Nyb2xsUGUuc3RvcCgpO1xuICAgICAgICAgICAgdGhpcy5fbWFudWFsU2Nyb2xsUGUgPSBudWxsO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIG9ic2VydmVOb2RlQ2hpbGRyZW46IGZ1bmN0aW9uIG9ic2VydmVOb2RlQ2hpbGRyZW4obm9kZSkge1xuICAgICAgICB2YXIgc3RvcCA9IGFyZ3VtZW50cy5sZW5ndGggPD0gMSB8fCBhcmd1bWVudHNbMV0gPT09IHVuZGVmaW5lZCA/IGZhbHNlIDogYXJndW1lbnRzWzFdO1xuXG4gICAgICAgIGlmIChzdG9wICYmICF0aGlzLl9jaGlsZHJlbk9ic2VydmVyKSByZXR1cm47XG5cbiAgICAgICAgaWYgKCF0aGlzLl9jaGlsZHJlbk9ic2VydmVyKSB7XG4gICAgICAgICAgICB0aGlzLl9jaGlsZHJlbk9ic2VydmVyID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmluZGV4ZWRFbGVtZW50cyA9IG51bGw7XG4gICAgICAgICAgICAgICAgdGhpcy5yZWJ1aWxkTG9hZGVkRWxlbWVudHMoKTtcbiAgICAgICAgICAgIH0pLmJpbmQodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF0aGlzLl9jaGlsZHJlbkFjdGlvbnNPYnNlcnZlcikge1xuICAgICAgICAgICAgdGhpcy5fY2hpbGRyZW5BY3Rpb25zT2JzZXJ2ZXIgPSAoZnVuY3Rpb24gKGV2ZW50TWVtbykge1xuICAgICAgICAgICAgICAgIGlmIChldmVudE1lbW8udHlwZSA9PT0gJ3Byb21wdC1yZW5hbWUnKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBpbmxpbmVFZGl0aW9uRm9yTm9kZTogZXZlbnRNZW1vLmNoaWxkLCBpbmxpbmVFZGl0aW9uQ2FsbGJhY2s6IGV2ZW50TWVtby5jYWxsYmFjayB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KS5iaW5kKHRoaXMpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzdG9wKSB7XG4gICAgICAgICAgICBub2RlLnN0b3BPYnNlcnZpbmcoXCJjaGlsZF9hZGRlZFwiLCB0aGlzLl9jaGlsZHJlbk9ic2VydmVyKTtcbiAgICAgICAgICAgIG5vZGUuc3RvcE9ic2VydmluZyhcImNoaWxkX3JlbW92ZWRcIiwgdGhpcy5fY2hpbGRyZW5PYnNlcnZlcik7XG4gICAgICAgICAgICBub2RlLnN0b3BPYnNlcnZpbmcoXCJjaGlsZF9ub2RlX2FjdGlvblwiLCB0aGlzLl9jaGlsZHJlbkFjdGlvbnNPYnNlcnZlcik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBub2RlLm9ic2VydmUoXCJjaGlsZF9hZGRlZFwiLCB0aGlzLl9jaGlsZHJlbk9ic2VydmVyKTtcbiAgICAgICAgICAgIG5vZGUub2JzZXJ2ZShcImNoaWxkX3JlbW92ZWRcIiwgdGhpcy5fY2hpbGRyZW5PYnNlcnZlcik7XG4gICAgICAgICAgICBub2RlLm9ic2VydmUoXCJjaGlsZF9ub2RlX2FjdGlvblwiLCB0aGlzLl9jaGlsZHJlbkFjdGlvbnNPYnNlcnZlcik7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgX2xvYWROb2RlSWZOb3RMb2FkZWQ6IGZ1bmN0aW9uIF9sb2FkTm9kZUlmTm90TG9hZGVkKCkge1xuICAgICAgICB2YXIgbm9kZSA9IHRoaXMucHJvcHMubm9kZTtcblxuICAgICAgICBpZiAoIW5vZGUuaXNMb2FkZWQoKSkge1xuICAgICAgICAgICAgbm9kZS5vYnNlcnZlT25jZShcImxvYWRlZFwiLCAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGlmICghdGhpcy5pc01vdW50ZWQoKSkgcmV0dXJuO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnByb3BzLm5vZGUgPT09IG5vZGUpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vYnNlcnZlTm9kZUNoaWxkcmVuKG5vZGUpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxvYWRlZDogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGxvYWRpbmc6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudHM6IHRoaXMuYnVpbGRFbGVtZW50cyh0aGlzLnN0YXRlLnNvcnRpbmdJbmZvLCAwLCB0aGlzLnByb3BzLmluZmluaXRlU2xpY2VDb3VudClcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnByb3BzLmhlaWdodEF1dG9XaXRoTWF4KSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlSW5maW5pdGVDb250YWluZXJIZWlnaHQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KS5iaW5kKHRoaXMpKTtcbiAgICAgICAgICAgIG5vZGUubG9hZCgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5vYnNlcnZlTm9kZUNoaWxkcmVuKG5vZGUpO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIF9sb2FkaW5nTGlzdGVuZXI6IGZ1bmN0aW9uIF9sb2FkaW5nTGlzdGVuZXIoKSB7XG4gICAgICAgIHRoaXMub2JzZXJ2ZU5vZGVDaGlsZHJlbih0aGlzLnByb3BzLm5vZGUsIHRydWUpO1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgbG9hZGVkOiBmYWxzZSwgbG9hZGluZzogdHJ1ZSB9KTtcbiAgICAgICAgdGhpcy5pbmRleGVkRWxlbWVudHMgPSBudWxsO1xuICAgIH0sXG4gICAgX2xvYWRlZExpc3RlbmVyOiBmdW5jdGlvbiBfbG9hZGVkTGlzdGVuZXIoKSB7XG4gICAgICAgIHZhciBjdXJyZW50TGVuZ3RoID0gTWF0aC5tYXgodGhpcy5zdGF0ZS5lbGVtZW50cy5sZW5ndGgsIHRoaXMucHJvcHMuaW5maW5pdGVTbGljZUNvdW50KTtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICBsb2FkaW5nOiBmYWxzZSxcbiAgICAgICAgICAgIGVsZW1lbnRzOiB0aGlzLmJ1aWxkRWxlbWVudHModGhpcy5zdGF0ZS5zb3J0aW5nSW5mbywgMCwgY3VycmVudExlbmd0aCwgdGhpcy5wcm9wcy5ub2RlKVxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMuaGVpZ2h0QXV0b1dpdGhNYXgpIHtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlSW5maW5pdGVDb250YWluZXJIZWlnaHQoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm9ic2VydmVOb2RlQ2hpbGRyZW4odGhpcy5wcm9wcy5ub2RlKTtcbiAgICB9LFxuXG4gICAgcmVsb2FkOiBmdW5jdGlvbiByZWxvYWQoKSB7XG4gICAgICAgIGlmICh0aGlzLnByb3BzLnJlbG9hZEF0Q3Vyc29yICYmIHRoaXMuX2N1cnJlbnRDdXJzb3IpIHtcbiAgICAgICAgICAgIHRoaXMubG9hZFN0YXJ0aW5nQXRDdXJzb3IoKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5wcm9wcy5jbGVhclNlbGVjdGlvbk9uUmVsb2FkKSB7XG4gICAgICAgICAgICB0aGlzLnByb3BzLmRhdGFNb2RlbC5zZXRTZWxlY3RlZE5vZGVzKFtdKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9sb2FkaW5nTGlzdGVuZXIoKTtcbiAgICAgICAgdGhpcy5wcm9wcy5ub2RlLm9ic2VydmVPbmNlKFwibG9hZGVkXCIsIHRoaXMuX2xvYWRlZExpc3RlbmVyKTtcbiAgICAgICAgdGhpcy5wcm9wcy5ub2RlLnJlbG9hZCgpO1xuICAgIH0sXG5cbiAgICBsb2FkU3RhcnRpbmdBdEN1cnNvcjogZnVuY3Rpb24gbG9hZFN0YXJ0aW5nQXRDdXJzb3IoKSB7XG4gICAgICAgIHRoaXMuX2xvYWRpbmdMaXN0ZW5lcigpO1xuICAgICAgICB2YXIgbm9kZSA9IHRoaXMucHJvcHMubm9kZTtcbiAgICAgICAgdmFyIGNhY2hlZENoaWxkcmVuID0gbm9kZS5nZXRDaGlsZHJlbigpO1xuICAgICAgICB2YXIgbmV3Q2hpbGRyZW4gPSBbXTtcbiAgICAgICAgbm9kZS5vYnNlcnZlT25jZShcImxvYWRlZFwiLCAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIHJlb3JkZXJlZENoaWxkcmVuID0gbmV3IE1hcCgpO1xuICAgICAgICAgICAgbmV3Q2hpbGRyZW4ubWFwKGZ1bmN0aW9uIChjKSB7XG4gICAgICAgICAgICAgICAgcmVvcmRlcmVkQ2hpbGRyZW4uc2V0KGMuZ2V0UGF0aCgpLCBjKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgY2FjaGVkQ2hpbGRyZW4uZm9yRWFjaChmdW5jdGlvbiAoYykge1xuICAgICAgICAgICAgICAgIHJlb3JkZXJlZENoaWxkcmVuLnNldChjLmdldFBhdGgoKSwgYyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIG5vZGUuX2NoaWxkcmVuID0gcmVvcmRlcmVkQ2hpbGRyZW47XG4gICAgICAgICAgICB0aGlzLl9sb2FkZWRMaXN0ZW5lcigpO1xuICAgICAgICB9KS5iaW5kKHRoaXMpKTtcbiAgICAgICAgbm9kZS5zZXRMb2FkZWQoZmFsc2UpO1xuICAgICAgICBub2RlLm9ic2VydmUoXCJjaGlsZF9hZGRlZFwiLCBmdW5jdGlvbiAobmV3Q2hpbGQpIHtcbiAgICAgICAgICAgIG5ld0NoaWxkcmVuLnB1c2gobm9kZS5fY2hpbGRyZW4uZ2V0KG5ld0NoaWxkKSk7XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLnByb3BzLm5vZGUubG9hZChudWxsLCB7IGN1cnNvcjogdGhpcy5fY3VycmVudEN1cnNvciB9KTtcbiAgICB9LFxuXG4gICAgd2lyZVJlbG9hZExpc3RlbmVyczogZnVuY3Rpb24gd2lyZVJlbG9hZExpc3RlbmVycygpIHtcbiAgICAgICAgdGhpcy53cmFwcGVkTG9hZGluZyA9IHRoaXMuX2xvYWRpbmdMaXN0ZW5lcjtcbiAgICAgICAgdGhpcy53cmFwcGVkTG9hZGVkID0gdGhpcy5fbG9hZGVkTGlzdGVuZXI7XG4gICAgICAgIHRoaXMucHJvcHMubm9kZS5vYnNlcnZlKFwibG9hZGluZ1wiLCB0aGlzLndyYXBwZWRMb2FkaW5nKTtcbiAgICAgICAgdGhpcy5wcm9wcy5ub2RlLm9ic2VydmUoXCJsb2FkZWRcIiwgdGhpcy53cmFwcGVkTG9hZGVkKTtcbiAgICB9LFxuICAgIHN0b3BSZWxvYWRMaXN0ZW5lcnM6IGZ1bmN0aW9uIHN0b3BSZWxvYWRMaXN0ZW5lcnMoKSB7XG4gICAgICAgIHRoaXMucHJvcHMubm9kZS5zdG9wT2JzZXJ2aW5nKFwibG9hZGluZ1wiLCB0aGlzLndyYXBwZWRMb2FkaW5nKTtcbiAgICAgICAgdGhpcy5wcm9wcy5ub2RlLnN0b3BPYnNlcnZpbmcoXCJsb2FkZWRcIiwgdGhpcy53cmFwcGVkTG9hZGVkKTtcbiAgICB9LFxuXG4gICAgdG9nZ2xlU2VsZWN0b3I6IGZ1bmN0aW9uIHRvZ2dsZVNlbGVjdG9yKCkge1xuICAgICAgICAvLyBGb3JjZSByZWJ1aWxkIGVsZW1lbnRzXG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgc2hvd1NlbGVjdG9yOiAhdGhpcy5zdGF0ZS5zaG93U2VsZWN0b3IsXG4gICAgICAgICAgICBzZWxlY3Rpb246IG5ldyBNYXAoKVxuICAgICAgICB9LCB0aGlzLnJlYnVpbGRMb2FkZWRFbGVtZW50cyk7XG4gICAgfSxcblxuICAgIHRvZ2dsZVNlbGVjdGlvbjogZnVuY3Rpb24gdG9nZ2xlU2VsZWN0aW9uKG5vZGUpIHtcbiAgICAgICAgdmFyIHNlbGVjdGlvbiA9IHRoaXMuc3RhdGUuc2VsZWN0aW9uIHx8IG5ldyBNYXAoKTtcbiAgICAgICAgaWYgKHNlbGVjdGlvbi5nZXQobm9kZSkpIHNlbGVjdGlvblsnZGVsZXRlJ10obm9kZSk7ZWxzZSBzZWxlY3Rpb24uc2V0KG5vZGUsIHRydWUpO1xuICAgICAgICBpZiAodGhpcy5yZWZzLmFsbF9zZWxlY3RvcikgdGhpcy5yZWZzLmFsbF9zZWxlY3Rvci5zZXRDaGVja2VkKGZhbHNlKTtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICBzZWxlY3Rpb246IHNlbGVjdGlvblxuICAgICAgICB9LCB0aGlzLnJlYnVpbGRMb2FkZWRFbGVtZW50cyk7XG4gICAgfSxcblxuICAgIHNlbGVjdEFsbDogZnVuY3Rpb24gc2VsZWN0QWxsKCkge1xuICAgICAgICB2YXIgX3RoaXMyID0gdGhpcztcblxuICAgICAgICBpZiAodGhpcy5yZWZzLmFsbF9zZWxlY3RvciAmJiAhdGhpcy5yZWZzLmFsbF9zZWxlY3Rvci5pc0NoZWNrZWQoKSkge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNlbGVjdGlvbjogbmV3IE1hcCgpIH0sIHRoaXMucmVidWlsZExvYWRlZEVsZW1lbnRzKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdmFyIHNlbGVjdGlvbiA9IG5ldyBNYXAoKTtcbiAgICAgICAgICAgICAgICBfdGhpczIucHJvcHMubm9kZS5nZXRDaGlsZHJlbigpLmZvckVhY2goKGZ1bmN0aW9uIChjaGlsZCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5wcm9wcy5maWx0ZXJOb2RlcyAmJiAhdGhpcy5wcm9wcy5maWx0ZXJOb2RlcyhjaGlsZCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoY2hpbGQuaXNMZWFmKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdGlvbi5zZXQoY2hpbGQsIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSkuYmluZChfdGhpczIpKTtcbiAgICAgICAgICAgICAgICBpZiAoX3RoaXMyLnJlZnMuYWxsX3NlbGVjdG9yKSBfdGhpczIucmVmcy5hbGxfc2VsZWN0b3Iuc2V0Q2hlY2tlZCh0cnVlKTtcbiAgICAgICAgICAgICAgICBfdGhpczIuc2V0U3RhdGUoeyBzZWxlY3Rpb246IHNlbGVjdGlvbiB9LCBfdGhpczIucmVidWlsZExvYWRlZEVsZW1lbnRzKTtcbiAgICAgICAgICAgIH0pKCk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgYXBwbHlNdWx0aXBsZUFjdGlvbjogZnVuY3Rpb24gYXBwbHlNdWx0aXBsZUFjdGlvbihldikge1xuICAgICAgICBpZiAoIXRoaXMuc3RhdGUuc2VsZWN0aW9uIHx8ICF0aGlzLnN0YXRlLnNlbGVjdGlvbi5zaXplKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGFjdGlvbk5hbWUgPSBldi5jdXJyZW50VGFyZ2V0LmdldEF0dHJpYnV0ZSgnZGF0YS1hY3Rpb24nKTtcbiAgICAgICAgdmFyIGRtID0gdGhpcy5kbSB8fCBuZXcgUHlkaW9EYXRhTW9kZWwoKTtcbiAgICAgICAgZG0uc2V0Q29udGV4dE5vZGUodGhpcy5wcm9wcy5ub2RlKTtcbiAgICAgICAgdmFyIHNlbE5vZGVzID0gW107XG4gICAgICAgIHRoaXMuc3RhdGUuc2VsZWN0aW9uLmZvckVhY2goZnVuY3Rpb24gKHYsIG5vZGUpIHtcbiAgICAgICAgICAgIHNlbE5vZGVzLnB1c2gobm9kZSk7XG4gICAgICAgIH0pO1xuICAgICAgICBkbS5zZXRTZWxlY3RlZE5vZGVzKHNlbE5vZGVzKTtcbiAgICAgICAgdmFyIGEgPSB0aGlzLnByb3BzLnB5ZGlvLkNvbnRyb2xsZXIuZ2V0QWN0aW9uQnlOYW1lKGFjdGlvbk5hbWUpO1xuICAgICAgICBhLmZpcmVDb250ZXh0Q2hhbmdlKGRtLCB0cnVlLCB0aGlzLnByb3BzLnB5ZGlvLnVzZXIpO1xuICAgICAgICBhLmFwcGx5KFtkbV0pO1xuXG4gICAgICAgIGV2LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICBldi5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH0sXG5cbiAgICBnZXRBY3Rpb25zRm9yTm9kZTogZnVuY3Rpb24gZ2V0QWN0aW9uc0Zvck5vZGUoZG0sIG5vZGUpIHtcbiAgICAgICAgaWYgKCF0aGlzLnByb3BzLmNvbXB1dGVBY3Rpb25zRm9yTm9kZSkge1xuICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICB9XG4gICAgICAgIHZhciBjYWNoZUtleSA9IG5vZGUuaXNMZWFmKCkgPyAnZmlsZS0nICsgbm9kZS5nZXRBanhwTWltZSgpIDogJ2ZvbGRlcic7XG4gICAgICAgIHZhciBzZWxlY3Rpb25UeXBlID0gbm9kZS5pc0xlYWYoKSA/ICdmaWxlJyA6ICdkaXInO1xuICAgICAgICB2YXIgbm9kZUFjdGlvbnMgPSBbXTtcbiAgICAgICAgaWYgKHRoaXMuYWN0aW9uc0NhY2hlW2NhY2hlS2V5XSkge1xuICAgICAgICAgICAgbm9kZUFjdGlvbnMgPSB0aGlzLmFjdGlvbnNDYWNoZVtjYWNoZUtleV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBkbS5zZXRTZWxlY3RlZE5vZGVzKFtub2RlXSk7XG4gICAgICAgICAgICB3aW5kb3cucHlkaW8uQ29udHJvbGxlci5hY3Rpb25zLmZvckVhY2goKGZ1bmN0aW9uIChhKSB7XG4gICAgICAgICAgICAgICAgYS5maXJlQ29udGV4dENoYW5nZShkbSwgdHJ1ZSwgd2luZG93LnB5ZGlvLnVzZXIpO1xuICAgICAgICAgICAgICAgIGlmIChhLmNvbnRleHQuc2VsZWN0aW9uICYmIGEuY29udGV4dC5hY3Rpb25CYXIgJiYgYS5zZWxlY3Rpb25Db250ZXh0W3NlbGVjdGlvblR5cGVdICYmICFhLmRlbnkgJiYgYS5vcHRpb25zLmljb25fY2xhc3MgJiYgKCF0aGlzLnByb3BzLmFjdGlvbkJhckdyb3VwcyB8fCB0aGlzLnByb3BzLmFjdGlvbkJhckdyb3Vwcy5pbmRleE9mKGEuY29udGV4dC5hY3Rpb25CYXJHcm91cCkgIT09IC0xKSAmJiAoIWEuc2VsZWN0aW9uQ29udGV4dC5hbGxvd2VkTWltZXMubGVuZ3RoIHx8IGEuc2VsZWN0aW9uQ29udGV4dC5hbGxvd2VkTWltZXMuaW5kZXhPZihub2RlLmdldEFqeHBNaW1lKCkpICE9PSAtMSkpIHtcbiAgICAgICAgICAgICAgICAgICAgbm9kZUFjdGlvbnMucHVzaChhKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG5vZGUuaXNMZWFmKCkgJiYgYS5zZWxlY3Rpb25Db250ZXh0LnVuaXF1ZSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYWN0aW9uc0NhY2hlLm11bHRpcGxlLnNldChhLm9wdGlvbnMubmFtZSwgYSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KS5iaW5kKHRoaXMpKTtcbiAgICAgICAgICAgIHRoaXMuYWN0aW9uc0NhY2hlW2NhY2hlS2V5XSA9IG5vZGVBY3Rpb25zO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBub2RlQWN0aW9ucztcbiAgICB9LFxuXG4gICAgdXBkYXRlSW5maW5pdGVDb250YWluZXJIZWlnaHQ6IGZ1bmN0aW9uIHVwZGF0ZUluZmluaXRlQ29udGFpbmVySGVpZ2h0KCkge1xuICAgICAgICB2YXIgcmV0cmllcyA9IGFyZ3VtZW50cy5sZW5ndGggPD0gMCB8fCBhcmd1bWVudHNbMF0gPT09IHVuZGVmaW5lZCA/IGZhbHNlIDogYXJndW1lbnRzWzBdO1xuXG4gICAgICAgIGlmICh0aGlzLnByb3BzLmNvbnRhaW5lckhlaWdodCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMucHJvcHMuY29udGFpbmVySGVpZ2h0O1xuICAgICAgICB9XG4gICAgICAgIGlmICghdGhpcy5yZWZzLmluZmluaXRlUGFyZW50KSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGNvbnRhaW5lckhlaWdodCA9IHRoaXMucmVmcy5pbmZpbml0ZVBhcmVudC5jbGllbnRIZWlnaHQ7XG4gICAgICAgIGlmICh0aGlzLnByb3BzLmhlaWdodEF1dG9XaXRoTWF4KSB7XG4gICAgICAgICAgICB2YXIgbnVtYmVyID0gdGhpcy5pbmRleGVkRWxlbWVudHMgPyB0aGlzLmluZGV4ZWRFbGVtZW50cy5sZW5ndGggOiB0aGlzLnByb3BzLm5vZGUuZ2V0Q2hpbGRyZW4oKS5zaXplO1xuICAgICAgICAgICAgdmFyIGVsZW1lbnRIZWlnaHQgPSB0aGlzLnN0YXRlLmVsZW1lbnRIZWlnaHQgPyB0aGlzLnN0YXRlLmVsZW1lbnRIZWlnaHQgOiB0aGlzLnByb3BzLmVsZW1lbnRIZWlnaHQ7XG4gICAgICAgICAgICBjb250YWluZXJIZWlnaHQgPSBNYXRoLm1pbihudW1iZXIgKiBlbGVtZW50SGVpZ2h0LCB0aGlzLnByb3BzLmhlaWdodEF1dG9XaXRoTWF4KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWNvbnRhaW5lckhlaWdodCAmJiAhcmV0cmllcykge1xuICAgICAgICAgICAgZ2xvYmFsLnNldFRpbWVvdXQoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZUluZmluaXRlQ29udGFpbmVySGVpZ2h0KHRydWUpO1xuICAgICAgICAgICAgfSkuYmluZCh0aGlzKSwgNTApO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBjb250YWluZXJIZWlnaHQ6IGNvbnRhaW5lckhlaWdodCB9KTtcbiAgICB9LFxuXG4gICAgY29tcHV0ZUVsZW1lbnRIZWlnaHRSZXNwb25zaXZlOiBmdW5jdGlvbiBjb21wdXRlRWxlbWVudEhlaWdodFJlc3BvbnNpdmUoKSB7XG4gICAgICAgIHZhciBicmVha3MgPSB0aGlzLnByb3BzLmVsZW1lbnRIZWlnaHQ7XG4gICAgICAgIGlmICghKGJyZWFrcyBpbnN0YW5jZW9mIE9iamVjdCkpIHtcbiAgICAgICAgICAgIGJyZWFrcyA9IHtcbiAgICAgICAgICAgICAgICBcIm1pbi13aWR0aDo0ODBweFwiOiB0aGlzLnByb3BzLmVsZW1lbnRIZWlnaHQsXG4gICAgICAgICAgICAgICAgXCJtYXgtd2lkdGg6NDgwcHhcIjogT2JqZWN0LmtleXModGhpcy5wcm9wcy50YWJsZUtleXMpLmxlbmd0aCAqIDI0ICsgMzNcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHdpbmRvdy5tYXRjaE1lZGlhKSB7XG4gICAgICAgICAgICBmb3IgKHZhciBrIGluIGJyZWFrcykge1xuICAgICAgICAgICAgICAgIGlmIChicmVha3MuaGFzT3duUHJvcGVydHkoaykgJiYgd2luZG93Lm1hdGNoTWVkaWEoJygnICsgayArICcpJykubWF0Y2hlcykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYnJlYWtzW2tdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHZhciB3aWR0aCA9IERPTVV0aWxzLmdldFZpZXdwb3J0V2lkdGgoKTtcbiAgICAgICAgICAgIGlmICh3aWR0aCA8IDQ4MCkgcmV0dXJuIGJyZWFrc1tcIm1heC13aWR0aDo0ODBweFwiXTtlbHNlIHJldHVybiBicmVha3NbXCJtYXgtd2lkdGg6NDgwcHhcIl07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIDUwO1xuICAgIH0sXG5cbiAgICB1cGRhdGVFbGVtZW50SGVpZ2h0UmVzcG9uc2l2ZTogZnVuY3Rpb24gdXBkYXRlRWxlbWVudEhlaWdodFJlc3BvbnNpdmUoKSB7XG4gICAgICAgIHZhciBuZXdIID0gdGhpcy5jb21wdXRlRWxlbWVudEhlaWdodFJlc3BvbnNpdmUoKTtcbiAgICAgICAgaWYgKCF0aGlzLnN0YXRlIHx8ICF0aGlzLnN0YXRlLmVsZW1lbnRIZWlnaHQgfHwgdGhpcy5zdGF0ZS5lbGVtZW50SGVpZ2h0ICE9IG5ld0gpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBlbGVtZW50SGVpZ2h0OiBuZXdIIH0sIChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMucHJvcHMuaGVpZ2h0QXV0b1dpdGhNYXgpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy51cGRhdGVJbmZpbml0ZUNvbnRhaW5lckhlaWdodCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pLmJpbmQodGhpcykpO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIHBhdGNoSW5maW5pdGVHcmlkOiBmdW5jdGlvbiBwYXRjaEluZmluaXRlR3JpZChlbHMpIHtcbiAgICAgICAgaWYgKHRoaXMucmVmcy5pbmZpbml0ZSAmJiBlbHMgPiAxKSB7XG4gICAgICAgICAgICB0aGlzLnJlZnMuaW5maW5pdGUuc3RhdGUuaW5maW5pdGVDb21wdXRlci5fX3Byb3RvX18uZ2V0RGlzcGxheUluZGV4U3RhcnQgPSBmdW5jdGlvbiAod2luZG93VG9wKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGVscyAqIE1hdGguZmxvb3Iod2luZG93VG9wIC8gdGhpcy5oZWlnaHREYXRhIC8gZWxzKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB0aGlzLnJlZnMuaW5maW5pdGUuc3RhdGUuaW5maW5pdGVDb21wdXRlci5fX3Byb3RvX18uZ2V0RGlzcGxheUluZGV4RW5kID0gZnVuY3Rpb24gKHdpbmRvd0JvdHRvbSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBlbHMgKiBNYXRoLmNlaWwod2luZG93Qm90dG9tIC8gdGhpcy5oZWlnaHREYXRhIC8gZWxzKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgY29tcG9uZW50RGlkTW91bnQ6IGZ1bmN0aW9uIGNvbXBvbmVudERpZE1vdW50KCkge1xuICAgICAgICB2YXIgX3RoaXMzID0gdGhpcztcblxuICAgICAgICBpZiAodGhpcy5wcm9wcy5kZWxheUluaXRpYWxMb2FkKSB7XG4gICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBfdGhpczMuX2xvYWROb2RlSWZOb3RMb2FkZWQoKTtcbiAgICAgICAgICAgIH0sIHRoaXMucHJvcHMuZGVsYXlJbml0aWFsTG9hZCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9sb2FkTm9kZUlmTm90TG9hZGVkKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5wYXRjaEluZmluaXRlR3JpZCh0aGlzLnByb3BzLmVsZW1lbnRzUGVyTGluZSk7XG4gICAgICAgIGlmICh0aGlzLnJlZnMuaW5maW5pdGVQYXJlbnQpIHtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlSW5maW5pdGVDb250YWluZXJIZWlnaHQoKTtcbiAgICAgICAgICAgIGlmICghdGhpcy5wcm9wcy5oZWlnaHRBdXRvV2l0aE1heCAmJiAhdGhpcy5wcm9wcy5leHRlcm5hbFJlc2l6ZSkge1xuICAgICAgICAgICAgICAgIGlmICh3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcikge1xuICAgICAgICAgICAgICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncmVzaXplJywgdGhpcy51cGRhdGVJbmZpbml0ZUNvbnRhaW5lckhlaWdodCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgd2luZG93LmF0dGFjaEV2ZW50KCdvbnJlc2l6ZScsIHRoaXMudXBkYXRlSW5maW5pdGVDb250YWluZXJIZWlnaHQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5wcm9wcy5hdXRvUmVmcmVzaCkge1xuICAgICAgICAgICAgdGhpcy5yZWZyZXNoSW50ZXJ2YWwgPSB3aW5kb3cuc2V0SW50ZXJ2YWwodGhpcy5yZWxvYWQsIHRoaXMucHJvcHMuYXV0b1JlZnJlc2gpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnByb3BzLm9ic2VydmVOb2RlUmVsb2FkKSB7XG4gICAgICAgICAgICB0aGlzLndpcmVSZWxvYWRMaXN0ZW5lcnMoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5wcm9wcy5lbGVtZW50SGVpZ2h0IGluc3RhbmNlb2YgT2JqZWN0IHx8IHRoaXMucHJvcHMudGFibGVLZXlzKSB7XG4gICAgICAgICAgICBpZiAod2luZG93LmFkZEV2ZW50TGlzdGVuZXIpIHtcbiAgICAgICAgICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncmVzaXplJywgdGhpcy51cGRhdGVFbGVtZW50SGVpZ2h0UmVzcG9uc2l2ZSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHdpbmRvdy5hdHRhY2hFdmVudCgnb25yZXNpemUnLCB0aGlzLnVwZGF0ZUVsZW1lbnRIZWlnaHRSZXNwb25zaXZlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMudXBkYXRlRWxlbWVudEhlaWdodFJlc3BvbnNpdmUoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnByb3BzLmRhdGFNb2RlbC5vYnNlcnZlKCdzZWxlY3Rpb25fY2hhbmdlZCcsIChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgX3RoaXM0ID0gdGhpcztcblxuICAgICAgICAgICAgaWYgKCF0aGlzLmlzTW91bnRlZCgpKSByZXR1cm47XG4gICAgICAgICAgICB2YXIgc2VsZWN0aW9uID0gbmV3IE1hcCgpO1xuICAgICAgICAgICAgdmFyIHNlbGVjdGVkTm9kZXMgPSB0aGlzLnByb3BzLmRhdGFNb2RlbC5nZXRTZWxlY3RlZE5vZGVzKCk7XG4gICAgICAgICAgICBzZWxlY3RlZE5vZGVzLm1hcChmdW5jdGlvbiAobikge1xuICAgICAgICAgICAgICAgIHNlbGVjdGlvbi5zZXQobiwgdHJ1ZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBzZWxlY3Rpb246IHNlbGVjdGlvbiB9LCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgX3RoaXM0LnJlYnVpbGRMb2FkZWRFbGVtZW50cygpO1xuICAgICAgICAgICAgICAgIGlmIChzZWxlY3RlZE5vZGVzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgICAgICAgICBfdGhpczQuc2Nyb2xsVG9WaWV3KHNlbGVjdGVkTm9kZXNbMF0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KS5iaW5kKHRoaXMpKTtcbiAgICB9LFxuXG4gICAgY29tcG9uZW50V2lsbFVubW91bnQ6IGZ1bmN0aW9uIGNvbXBvbmVudFdpbGxVbm1vdW50KCkge1xuICAgICAgICBpZiAoIXRoaXMucHJvcHMuaGVpZ2h0QXV0b1dpdGhNYXgpIHtcbiAgICAgICAgICAgIGlmICh3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcikge1xuICAgICAgICAgICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdyZXNpemUnLCB0aGlzLnVwZGF0ZUluZmluaXRlQ29udGFpbmVySGVpZ2h0KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgd2luZG93LmRldGFjaEV2ZW50KCdvbnJlc2l6ZScsIHRoaXMudXBkYXRlSW5maW5pdGVDb250YWluZXJIZWlnaHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnByb3BzLmVsZW1lbnRIZWlnaHQgaW5zdGFuY2VvZiBPYmplY3QgfHwgdGhpcy5wcm9wcy50YWJsZUtleXMpIHtcbiAgICAgICAgICAgIGlmICh3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcikge1xuICAgICAgICAgICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdyZXNpemUnLCB0aGlzLnVwZGF0ZUVsZW1lbnRIZWlnaHRSZXNwb25zaXZlKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgd2luZG93LmRldGFjaEV2ZW50KCdyZXNpemUnLCB0aGlzLnVwZGF0ZUVsZW1lbnRIZWlnaHRSZXNwb25zaXZlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5yZWZyZXNoSW50ZXJ2YWwpIHtcbiAgICAgICAgICAgIHdpbmRvdy5jbGVhckludGVydmFsKHRoaXMucmVmcmVzaEludGVydmFsKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5wcm9wcy5vYnNlcnZlTm9kZVJlbG9hZCkge1xuICAgICAgICAgICAgdGhpcy5zdG9wUmVsb2FkTGlzdGVuZXJzKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMucHJvcHMubm9kZSkge1xuICAgICAgICAgICAgdGhpcy5vYnNlcnZlTm9kZUNoaWxkcmVuKHRoaXMucHJvcHMubm9kZSwgdHJ1ZSk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgY29tcG9uZW50RGlkVXBkYXRlOiBmdW5jdGlvbiBjb21wb25lbnREaWRVcGRhdGUocHJldlByb3BzLCBwcmV2U3RhdGUpIHtcbiAgICAgICAgaWYgKHByZXZQcm9wcy5ub2RlICYmIHRoaXMucHJvcHMubm9kZSAmJiBwcmV2UHJvcHMubm9kZS5nZXRQYXRoKCkgPT09IHRoaXMucHJvcHMubm9kZS5nZXRQYXRoKCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9sb2FkTm9kZUlmTm90TG9hZGVkKCk7XG4gICAgfSxcblxuICAgIG9uU2Nyb2xsOiBmdW5jdGlvbiBvblNjcm9sbChzY3JvbGxUb3ApIHtcblxuICAgICAgICBpZiAoIXRoaXMucHJvcHMucGFzc1Njcm9sbGluZ1N0YXRlVG9DaGlsZHJlbikge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIC8vIE1haW50YWlucyBhIHNlcmllcyBvZiB0aW1lb3V0cyB0byBzZXQgdGhpcy5zdGF0ZS5pc1Njcm9sbGluZ1xuICAgICAgICAvLyB0byBiZSB0cnVlIHdoZW4gdGhlIGVsZW1lbnQgaXMgc2Nyb2xsaW5nLlxuXG4gICAgICAgIGlmICh0aGlzLnN0YXRlLnNjcm9sbFRpbWVvdXQpIHtcbiAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aGlzLnN0YXRlLnNjcm9sbFRpbWVvdXQpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHRoYXQgPSB0aGlzLFxuICAgICAgICAgICAgc2Nyb2xsVGltZW91dCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdGhhdC5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgICAgaXNTY3JvbGxpbmc6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHNjcm9sbFRpbWVvdXQ6IHVuZGVmaW5lZFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0sIDE1MCk7XG5cbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICBpc1Njcm9sbGluZzogdHJ1ZSxcbiAgICAgICAgICAgIHNjcm9sbFRpbWVvdXQ6IHNjcm9sbFRpbWVvdXRcbiAgICAgICAgfSk7XG4gICAgfSxcblxuICAgIHNjcm9sbFRvTGFzdDogZnVuY3Rpb24gc2Nyb2xsVG9MYXN0KCkge1xuICAgICAgICBpZiAodGhpcy5pbmRleGVkRWxlbWVudHMgJiYgdGhpcy5pbmRleGVkRWxlbWVudHNbdGhpcy5pbmRleGVkRWxlbWVudHMubGVuZ3RoIC0gMV0ubm9kZSkge1xuICAgICAgICAgICAgdGhpcy5zY3JvbGxUb1ZpZXcodGhpcy5pbmRleGVkRWxlbWVudHNbdGhpcy5pbmRleGVkRWxlbWVudHMubGVuZ3RoIC0gMV0ubm9kZSk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgc2Nyb2xsVG9WaWV3OiBmdW5jdGlvbiBzY3JvbGxUb1ZpZXcobm9kZSkge1xuICAgICAgICB2YXIgX3RoaXM1ID0gdGhpcztcblxuICAgICAgICBpZiAoIXRoaXMuaW5kZXhlZEVsZW1lbnRzIHx8ICF0aGlzLnJlZnMuaW5maW5pdGUgfHwgIXRoaXMucmVmcy5pbmZpbml0ZS5zY3JvbGxhYmxlKSByZXR1cm47XG4gICAgICAgIHZhciBzY3JvbGxhYmxlID0gdGhpcy5yZWZzLmluZmluaXRlLnNjcm9sbGFibGU7XG4gICAgICAgIHZhciB2aXNpYmxlRnJhbWUgPSB7XG4gICAgICAgICAgICB0b3A6IHNjcm9sbGFibGUuc2Nyb2xsVG9wICsgdGhpcy5wcm9wcy5lbGVtZW50SGVpZ2h0IC8gMixcbiAgICAgICAgICAgIGJvdHRvbTogc2Nyb2xsYWJsZS5zY3JvbGxUb3AgKyB0aGlzLnN0YXRlLmNvbnRhaW5lckhlaWdodCAtIHRoaXMucHJvcHMuZWxlbWVudEhlaWdodCAvIDJcbiAgICAgICAgfTtcbiAgICAgICAgdmFyIHJlYWxNYXhTY3JvbGxUb3AgPSB0aGlzLmluZGV4ZWRFbGVtZW50cy5sZW5ndGggKiB0aGlzLnByb3BzLmVsZW1lbnRIZWlnaHQgLSB0aGlzLnN0YXRlLmNvbnRhaW5lckhlaWdodDtcblxuICAgICAgICB2YXIgcG9zaXRpb24gPSAtMTtcbiAgICAgICAgdGhpcy5pbmRleGVkRWxlbWVudHMuZm9yRWFjaChmdW5jdGlvbiAoZSwgaykge1xuICAgICAgICAgICAgaWYgKGUubm9kZSAmJiBlLm5vZGUgPT09IG5vZGUpIHBvc2l0aW9uID0gaztcbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChwb3NpdGlvbiA9PT0gLTEpIHJldHVybjtcbiAgICAgICAgdmFyIGVsZW1lbnRIZWlnaHQgPSB0aGlzLnByb3BzLmVsZW1lbnRIZWlnaHQ7XG4gICAgICAgIHZhciBzY3JvbGxUYXJnZXQgPSBwb3NpdGlvbiAqIGVsZW1lbnRIZWlnaHQ7XG5cbiAgICAgICAgaWYgKHNjcm9sbFRhcmdldCA+IHZpc2libGVGcmFtZS50b3AgJiYgc2Nyb2xsVGFyZ2V0IDwgdmlzaWJsZUZyYW1lLmJvdHRvbSkge1xuICAgICAgICAgICAgLy8gYWxyZWFkeSB2aXNpYmxlO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9IGVsc2UgaWYgKHNjcm9sbFRhcmdldCA+PSB2aXNpYmxlRnJhbWUuYm90dG9tKSB7XG4gICAgICAgICAgICBzY3JvbGxUYXJnZXQgLT0gdGhpcy5zdGF0ZS5jb250YWluZXJIZWlnaHQgLSBlbGVtZW50SGVpZ2h0ICogMjtcbiAgICAgICAgfVxuICAgICAgICBzY3JvbGxUYXJnZXQgPSBNYXRoLm1pbihzY3JvbGxUYXJnZXQsIHJlYWxNYXhTY3JvbGxUb3ApO1xuICAgICAgICBzY3JvbGxhYmxlLnNjcm9sbFRvcCA9IHNjcm9sbFRhcmdldDtcbiAgICAgICAgaWYgKHRoaXMuX21hbnVhbFNjcm9sbFBlKSB0aGlzLl9tYW51YWxTY3JvbGxQZS5zdG9wKCk7XG4gICAgICAgIGlmIChzY3JvbGxhYmxlLnNjcm9sbEhlaWdodCA8IHNjcm9sbFRhcmdldCkge1xuICAgICAgICAgICAgdGhpcy5fbWFudWFsU2Nyb2xsUGUgPSBuZXcgUGVyaW9kaWNhbEV4ZWN1dGVyKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBzY3JvbGxhYmxlLnNjcm9sbFRvcCA9IHNjcm9sbFRhcmdldDtcbiAgICAgICAgICAgICAgICBpZiAoc2Nyb2xsYWJsZS5zY3JvbGxIZWlnaHQgPj0gc2Nyb2xsVGFyZ2V0KSB7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzNS5fbWFudWFsU2Nyb2xsUGUuc3RvcCgpO1xuICAgICAgICAgICAgICAgICAgICBfdGhpczUuX21hbnVhbFNjcm9sbFBlID0gbnVsbDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LCAuMjUpO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIGJ1aWxkRWxlbWVudHNGcm9tTm9kZUVudHJpZXM6IGZ1bmN0aW9uIGJ1aWxkRWxlbWVudHNGcm9tTm9kZUVudHJpZXMobm9kZUVudHJpZXMsIHNob3dTZWxlY3Rvcikge1xuXG4gICAgICAgIHZhciBjb21wb25lbnRzID0gW10sXG4gICAgICAgICAgICBpbmRleCA9IDA7XG4gICAgICAgIHZhciBub2RlRW50cmllc0xlbmd0aCA9IG5vZGVFbnRyaWVzLmxlbmd0aDtcbiAgICAgICAgbm9kZUVudHJpZXMuZm9yRWFjaCgoZnVuY3Rpb24gKGVudHJ5KSB7XG4gICAgICAgICAgICB2YXIgZGF0YSA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIGlmIChlbnRyeS5wYXJlbnQpIHtcbiAgICAgICAgICAgICAgICBkYXRhID0ge1xuICAgICAgICAgICAgICAgICAgICBub2RlOiBlbnRyeS5ub2RlLFxuICAgICAgICAgICAgICAgICAgICBrZXk6IGVudHJ5Lm5vZGUuZ2V0UGF0aCgpLFxuICAgICAgICAgICAgICAgICAgICBpZDogZW50cnkubm9kZS5nZXRQYXRoKCksXG4gICAgICAgICAgICAgICAgICAgIG1haW5JY29uOiBTaW1wbGVMaXN0LlBBUkVOVF9GT0xERVJfSUNPTixcbiAgICAgICAgICAgICAgICAgICAgZmlyc3RMaW5lOiBcIi4uXCIsXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogXCJsaXN0LXBhcmVudC1ub2RlXCIsXG4gICAgICAgICAgICAgICAgICAgIHNlY29uZExpbmU6IHRoaXMuY29udGV4dC5nZXRNZXNzYWdlKCdyZWFjdC4xJyksXG4gICAgICAgICAgICAgICAgICAgIG9uQ2xpY2s6IHRoaXMuY2xpY2tSb3csXG4gICAgICAgICAgICAgICAgICAgIG9uRG91YmxlQ2xpY2s6IHRoaXMuZG91YmxlQ2xpY2tSb3csXG4gICAgICAgICAgICAgICAgICAgIHNob3dTZWxlY3RvcjogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdG9yRGlzYWJsZWQ6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIG5vSG92ZXI6IGZhbHNlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5wcm9wcy5lbnRyeVJlbmRlclBhcmVudEljb24gJiYgIXRoaXMucHJvcHMudGFibGVLZXlzKSB7XG4gICAgICAgICAgICAgICAgICAgIGRhdGFbJ2ljb25DZWxsJ10gPSB0aGlzLnByb3BzLmVudHJ5UmVuZGVyUGFyZW50SWNvbihlbnRyeS5ub2RlLCBlbnRyeSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZGF0YVsnbWFpbkljb24nXSA9IFNpbXBsZUxpc3QuUEFSRU5UX0ZPTERFUl9JQ09OO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5wcm9wcy5lbGVtZW50U3R5bGUpIHtcbiAgICAgICAgICAgICAgICAgICAgZGF0YVsnc3R5bGUnXSA9IHRoaXMucHJvcHMuZWxlbWVudFN0eWxlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5wcm9wcy5wYXNzU2Nyb2xsaW5nU3RhdGVUb0NoaWxkcmVuKSB7XG4gICAgICAgICAgICAgICAgICAgIGRhdGFbJ3BhcmVudElzU2Nyb2xsaW5nJ10gPSB0aGlzLnN0YXRlLmlzU2Nyb2xsaW5nO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb21wb25lbnRzLnB1c2goUmVhY3QuY3JlYXRlRWxlbWVudChfTGlzdEVudHJ5Lkxpc3RFbnRyeSwgZGF0YSkpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChlbnRyeS5ncm91cEhlYWRlcikge1xuICAgICAgICAgICAgICAgIHZhciBpZCA9IGVudHJ5Lmdyb3VwSGVhZGVyLFxuICAgICAgICAgICAgICAgICAgICBmaXJzdExpbmUgPSBlbnRyeS5ncm91cEhlYWRlckxhYmVsO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnByb3BzLmVudHJ5UmVuZGVyR3JvdXBIZWFkZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgZmlyc3RMaW5lID0gdGhpcy5wcm9wcy5lbnRyeVJlbmRlckdyb3VwSGVhZGVyKGlkLCBmaXJzdExpbmUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBkYXRhID0ge1xuICAgICAgICAgICAgICAgICAgICBub2RlOiBudWxsLFxuICAgICAgICAgICAgICAgICAgICBrZXk6IGVudHJ5Lmdyb3VwSGVhZGVyLFxuICAgICAgICAgICAgICAgICAgICBpZDogaWQsXG4gICAgICAgICAgICAgICAgICAgIG1haW5JY29uOiBudWxsLFxuICAgICAgICAgICAgICAgICAgICBmaXJzdExpbmU6IGZpcnN0TGluZSxcbiAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lOiAnbGlzdC1ncm91cC1oZWFkZXInLFxuICAgICAgICAgICAgICAgICAgICBvbkNsaWNrOiBudWxsLFxuICAgICAgICAgICAgICAgICAgICBzaG93U2VsZWN0b3I6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBzZWxlY3RvckRpc2FibGVkOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBub0hvdmVyOiB0cnVlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5wcm9wcy5wYXNzU2Nyb2xsaW5nU3RhdGVUb0NoaWxkcmVuKSB7XG4gICAgICAgICAgICAgICAgICAgIGRhdGFbJ3BhcmVudElzU2Nyb2xsaW5nJ10gPSB0aGlzLnN0YXRlLmlzU2Nyb2xsaW5nO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb21wb25lbnRzLnB1c2goUmVhY3QuY3JlYXRlRWxlbWVudChfTGlzdEVudHJ5Lkxpc3RFbnRyeSwgZGF0YSkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBkYXRhID0ge1xuICAgICAgICAgICAgICAgICAgICBub2RlOiBlbnRyeS5ub2RlLFxuICAgICAgICAgICAgICAgICAgICBvbkNsaWNrOiB0aGlzLmNsaWNrUm93LFxuICAgICAgICAgICAgICAgICAgICBvbkRvdWJsZUNsaWNrOiB0aGlzLmRvdWJsZUNsaWNrUm93LFxuICAgICAgICAgICAgICAgICAgICBvblNlbGVjdDogdGhpcy50b2dnbGVTZWxlY3Rpb24sXG4gICAgICAgICAgICAgICAgICAgIGtleTogZW50cnkubm9kZS5nZXRQYXRoKCksXG4gICAgICAgICAgICAgICAgICAgIGlkOiBlbnRyeS5ub2RlLmdldFBhdGgoKSxcbiAgICAgICAgICAgICAgICAgICAgcmVuZGVySWNvbjogdGhpcy5wcm9wcy5lbnRyeVJlbmRlckljb24sXG4gICAgICAgICAgICAgICAgICAgIHJlbmRlckZpcnN0TGluZTogdGhpcy5wcm9wcy5lbnRyeVJlbmRlckZpcnN0TGluZSxcbiAgICAgICAgICAgICAgICAgICAgcmVuZGVyU2Vjb25kTGluZTogdGhpcy5wcm9wcy5lbnRyeVJlbmRlclNlY29uZExpbmUsXG4gICAgICAgICAgICAgICAgICAgIHJlbmRlclRoaXJkTGluZTogdGhpcy5wcm9wcy5lbnRyeVJlbmRlclRoaXJkTGluZSxcbiAgICAgICAgICAgICAgICAgICAgcmVuZGVyQWN0aW9uczogdGhpcy5wcm9wcy5lbnRyeVJlbmRlckFjdGlvbnMsXG4gICAgICAgICAgICAgICAgICAgIHNob3dTZWxlY3Rvcjogc2hvd1NlbGVjdG9yLFxuICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZDogdGhpcy5zdGF0ZSAmJiB0aGlzLnN0YXRlLnNlbGVjdGlvbiA/IHRoaXMuc3RhdGUuc2VsZWN0aW9uLmdldChlbnRyeS5ub2RlKSA6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBhY3Rpb25zOiBSZWFjdC5jcmVhdGVFbGVtZW50KF92aWV3c1NpbXBsZVJlYWN0QWN0aW9uQmFyMlsnZGVmYXVsdCddLCB7IG5vZGU6IGVudHJ5Lm5vZGUsIGFjdGlvbnM6IGVudHJ5LmFjdGlvbnMsIGRhdGFNb2RlbDogdGhpcy5kbSB9KSxcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0b3JEaXNhYmxlZDogISh0aGlzLnByb3BzLmVudHJ5RW5hYmxlU2VsZWN0b3IgPyB0aGlzLnByb3BzLmVudHJ5RW5hYmxlU2VsZWN0b3IoZW50cnkubm9kZSkgOiBlbnRyeS5ub2RlLmlzTGVhZigpKVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgZGF0YVsnaXNGaXJzdCddID0gaW5kZXggPT09IDA7XG4gICAgICAgICAgICAgICAgZGF0YVsnaXNMYXN0J10gPSBpbmRleCA9PT0gbm9kZUVudHJpZXNMZW5ndGggLSAxO1xuICAgICAgICAgICAgICAgIGluZGV4Kys7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMucHJvcHMuZWxlbWVudFN0eWxlKSB7XG4gICAgICAgICAgICAgICAgICAgIGRhdGFbJ3N0eWxlJ10gPSB0aGlzLnByb3BzLmVsZW1lbnRTdHlsZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMucHJvcHMucGFzc1Njcm9sbGluZ1N0YXRlVG9DaGlsZHJlbikge1xuICAgICAgICAgICAgICAgICAgICBkYXRhWydwYXJlbnRJc1Njcm9sbGluZyddID0gdGhpcy5zdGF0ZS5pc1Njcm9sbGluZztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMucHJvcHMucmVuZGVyQ3VzdG9tRW50cnkpIHtcblxuICAgICAgICAgICAgICAgICAgICBjb21wb25lbnRzLnB1c2godGhpcy5wcm9wcy5yZW5kZXJDdXN0b21FbnRyeShkYXRhKSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLnByb3BzLnRhYmxlS2V5cykge1xuXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnByb3BzLmRlZmF1bHRHcm91cEJ5KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhWyd0YWJsZUtleXMnXSA9IExhbmdVdGlscy5kZWVwQ29weSh0aGlzLnByb3BzLnRhYmxlS2V5cyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgZGF0YVsndGFibGVLZXlzJ11bdGhpcy5wcm9wcy5kZWZhdWx0R3JvdXBCeV07XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhWyd0YWJsZUtleXMnXSA9IHRoaXMucHJvcHMudGFibGVLZXlzO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudHMucHVzaChSZWFjdC5jcmVhdGVFbGVtZW50KF9UYWJsZUxpc3RFbnRyeTJbJ2RlZmF1bHQnXSwgZGF0YSkpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50cy5wdXNoKFJlYWN0LmNyZWF0ZUVsZW1lbnQoX0NvbmZpZ3VyYWJsZUxpc3RFbnRyeTJbJ2RlZmF1bHQnXSwgZGF0YSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSkuYmluZCh0aGlzKSk7XG5cbiAgICAgICAgcmV0dXJuIGNvbXBvbmVudHM7XG4gICAgfSxcblxuICAgIGJ1aWxkRWxlbWVudHM6IGZ1bmN0aW9uIGJ1aWxkRWxlbWVudHMoc29ydGluZ0luZm8sIHN0YXJ0LCBlbmQsIG5vZGUsIHNob3dTZWxlY3Rvcikge1xuICAgICAgICB2YXIgX3RoaXM2ID0gdGhpcztcblxuICAgICAgICB2YXIgdGhlTm9kZSA9IHRoaXMucHJvcHMubm9kZTtcbiAgICAgICAgaWYgKG5vZGUpIHRoZU5vZGUgPSBub2RlO1xuICAgICAgICB2YXIgdGhlU2hvd1NlbGVjdG9yID0gdGhpcy5zdGF0ZSAmJiB0aGlzLnN0YXRlLnNob3dTZWxlY3RvcjtcbiAgICAgICAgaWYgKHNob3dTZWxlY3RvciAhPT0gdW5kZWZpbmVkKSB0aGVTaG93U2VsZWN0b3IgPSBzaG93U2VsZWN0b3I7XG5cbiAgICAgICAgaWYgKCF0aGlzLmluZGV4ZWRFbGVtZW50cyB8fCB0aGlzLmluZGV4ZWRFbGVtZW50cy5sZW5ndGggIT09IHRoZU5vZGUuZ2V0Q2hpbGRyZW4oKS5zaXplKSB7XG4gICAgICAgICAgICAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIF90aGlzNi5pbmRleGVkRWxlbWVudHMgPSBbXTtcbiAgICAgICAgICAgICAgICB2YXIgZ3JvdXBCeSA9IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICAgICAgZ3JvdXBCeUxhYmVsID0gdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgICAgICBncm91cHMgPSB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgICAgIGdyb3VwS2V5cyA9IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICAgICAgZ3JvdXBMYWJlbHMgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgaWYgKF90aGlzNi5wcm9wcy5kZWZhdWx0R3JvdXBCeSkge1xuICAgICAgICAgICAgICAgICAgICBncm91cEJ5ID0gX3RoaXM2LnByb3BzLmRlZmF1bHRHcm91cEJ5O1xuICAgICAgICAgICAgICAgICAgICBncm91cEJ5TGFiZWwgPSBfdGhpczYucHJvcHMuZ3JvdXBCeUxhYmVsIHx8IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICBncm91cHMgPSB7fSwgZ3JvdXBLZXlzID0gW10sIGdyb3VwTGFiZWxzID0ge307XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKCFfdGhpczYucHJvcHMuc2tpcFBhcmVudE5hdmlnYXRpb24gJiYgdGhlTm9kZS5nZXRQYXJlbnQoKSAmJiAoX3RoaXM2LnByb3BzLmRhdGFNb2RlbC5nZXRDb250ZXh0Tm9kZSgpICE9PSB0aGVOb2RlIHx8IF90aGlzNi5wcm9wcy5za2lwSW50ZXJuYWxEYXRhTW9kZWwpKSB7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzNi5pbmRleGVkRWxlbWVudHMucHVzaCh7IG5vZGU6IHRoZU5vZGUuZ2V0UGFyZW50KCksIHBhcmVudDogdHJ1ZSwgYWN0aW9uczogbnVsbCB9KTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0aGVOb2RlLmdldENoaWxkcmVuKCkuZm9yRWFjaCgoZnVuY3Rpb24gKGNoaWxkKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChjaGlsZC5nZXRNZXRhZGF0YSgpLmhhcygnY3Vyc29yJykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjaGlsZEN1cnNvciA9IHBhcnNlSW50KGNoaWxkLmdldE1ldGFkYXRhKCkuZ2V0KCdjdXJzb3InKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9jdXJyZW50Q3Vyc29yID0gTWF0aC5tYXgodGhpcy5fY3VycmVudEN1cnNvciA/IHRoaXMuX2N1cnJlbnRDdXJzb3IgOiAwLCBjaGlsZEN1cnNvcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMucHJvcHMuZmlsdGVyTm9kZXMgJiYgIXRoaXMucHJvcHMuZmlsdGVyTm9kZXMoY2hpbGQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgdmFyIG5vZGVBY3Rpb25zID0gdGhpcy5nZXRBY3Rpb25zRm9yTm9kZSh0aGlzLmRtLCBjaGlsZCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChncm91cEJ5KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgZ3JvdXBWYWx1ZSA9IGNoaWxkLmdldE1ldGFkYXRhKCkuZ2V0KGdyb3VwQnkpIHx8ICdOL0EnO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFncm91cHNbZ3JvdXBWYWx1ZV0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBncm91cHNbZ3JvdXBWYWx1ZV0gPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBncm91cEtleXMucHVzaChncm91cFZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChncm91cEJ5TGFiZWwgJiYgY2hpbGQuZ2V0TWV0YWRhdGEoKS5oYXMoZ3JvdXBCeUxhYmVsKSAmJiAhZ3JvdXBMYWJlbHNbZ3JvdXBWYWx1ZV0pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBncm91cExhYmVsc1tncm91cFZhbHVlXSA9IGNoaWxkLmdldE1ldGFkYXRhKCkuZ2V0KGdyb3VwQnlMYWJlbCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBncm91cHNbZ3JvdXBWYWx1ZV0ucHVzaCh7IG5vZGU6IGNoaWxkLCBwYXJlbnQ6IGZhbHNlLCBhY3Rpb25zOiBub2RlQWN0aW9ucyB9KTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaW5kZXhlZEVsZW1lbnRzLnB1c2goeyBub2RlOiBjaGlsZCwgcGFyZW50OiBmYWxzZSwgYWN0aW9uczogbm9kZUFjdGlvbnMgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KS5iaW5kKF90aGlzNikpO1xuXG4gICAgICAgICAgICAgICAgaWYgKGdyb3VwQnkpIHtcbiAgICAgICAgICAgICAgICAgICAgZ3JvdXBLZXlzID0gZ3JvdXBLZXlzLnNvcnQoKTtcbiAgICAgICAgICAgICAgICAgICAgZ3JvdXBLZXlzLm1hcCgoZnVuY3Rpb24gKGspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBsYWJlbCA9IGs7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZ3JvdXBMYWJlbHNba10pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbCA9IGdyb3VwTGFiZWxzW2tdO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLnByb3BzLnJlbmRlckdyb3VwTGFiZWxzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWwgPSB0aGlzLnByb3BzLnJlbmRlckdyb3VwTGFiZWxzKGdyb3VwQnksIGspO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pbmRleGVkRWxlbWVudHMucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZTogbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBncm91cEhlYWRlcjogayxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBncm91cEhlYWRlckxhYmVsOiBsYWJlbCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnQ6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjdGlvbnM6IG51bGxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pbmRleGVkRWxlbWVudHMgPSB0aGlzLmluZGV4ZWRFbGVtZW50cy5jb25jYXQoZ3JvdXBzW2tdKTtcbiAgICAgICAgICAgICAgICAgICAgfSkuYmluZChfdGhpczYpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHNvcnRpbmdJbmZvICYmICF0aGlzLnJlbW90ZVNvcnRpbmdJbmZvKCkpIHtcbiAgICAgICAgICAgIChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdmFyIGF0dHJpYnV0ZSA9IHNvcnRpbmdJbmZvLmF0dHJpYnV0ZTtcbiAgICAgICAgICAgICAgICB2YXIgZGlyZWN0aW9uID0gc29ydGluZ0luZm8uZGlyZWN0aW9uO1xuICAgICAgICAgICAgICAgIHZhciBzb3J0VHlwZSA9IHNvcnRpbmdJbmZvLnNvcnRUeXBlO1xuXG4gICAgICAgICAgICAgICAgdmFyIHNvcnRGdW5jdGlvbiA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICBpZiAoc29ydFR5cGUgPT09ICdmaWxlLW5hdHVyYWwnKSB7XG4gICAgICAgICAgICAgICAgICAgIHNvcnRGdW5jdGlvbiA9IGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYS5wYXJlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYi5wYXJlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBub2RlQSA9IGEubm9kZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBub2RlQiA9IGIubm9kZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJlY3ljbGUgYWx3YXlzIGxhc3RcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChub2RlQS5pc1JlY3ljbGUoKSkgcmV0dXJuIDE7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAobm9kZUIuaXNSZWN5Y2xlKCkpIHJldHVybiAtMTtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEZvbGRlcnMgZmlyc3RcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBhTGVhZiA9IG5vZGVBLmlzTGVhZigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGJMZWFmID0gbm9kZUIuaXNMZWFmKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVzID0gYUxlYWYgJiYgIWJMZWFmID8gMSA6ICFhTGVhZiAmJiBiTGVhZiA/IC0xIDogMDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXMgIT09IDApIHJldHVybiByZXM7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXMgPSBub2RlQS5nZXRMYWJlbCgpLmxvY2FsZUNvbXBhcmUobm9kZUIuZ2V0TGFiZWwoKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzO1xuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHNvcnRGdW5jdGlvbiA9IGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYS5wYXJlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgYU1ldGEgPSBhLm5vZGUuZ2V0TWV0YWRhdGEoKS5nZXQoYXR0cmlidXRlKSB8fCBcIlwiO1xuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGJNZXRhID0gYi5ub2RlLmdldE1ldGFkYXRhKCkuZ2V0KGF0dHJpYnV0ZSkgfHwgXCJcIjtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciByZXMgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc29ydFR5cGUgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYU1ldGEgPSBwYXJzZUZsb2F0KGFNZXRhKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBiTWV0YSA9IHBhcnNlRmxvYXQoYk1ldGEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcyA9IGRpcmVjdGlvbiA9PT0gJ2FzYycgPyBhTWV0YSAtIGJNZXRhIDogYk1ldGEgLSBhTWV0YTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoc29ydFR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzID0gZGlyZWN0aW9uID09PSAnYXNjJyA/IGFNZXRhLmxvY2FsZUNvbXBhcmUoYk1ldGEpIDogYk1ldGEubG9jYWxlQ29tcGFyZShhTWV0YSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVzID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUmVzb3J0IGJ5IGxhYmVsIHRvIG1ha2UgaXQgc3RhYmxlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGxhYkNvbXAgPSBhLm5vZGUuZ2V0TGFiZWwoKS5sb2NhbGVDb21wYXJlKGIubm9kZS5nZXRMYWJlbCgpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXMgPSBkaXJlY3Rpb24gPT09ICdhc2MnID8gbGFiQ29tcCA6IC1sYWJDb21wO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlcztcbiAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgX3RoaXM2LmluZGV4ZWRFbGVtZW50cy5zb3J0KHNvcnRGdW5jdGlvbik7XG4gICAgICAgICAgICB9KSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMucHJvcHMuZWxlbWVudFBlckxpbmUgPiAxKSB7XG4gICAgICAgICAgICBlbmQgPSBlbmQgKiB0aGlzLnByb3BzLmVsZW1lbnRQZXJMaW5lO1xuICAgICAgICAgICAgc3RhcnQgPSBzdGFydCAqIHRoaXMucHJvcHMuZWxlbWVudFBlckxpbmU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuaW5kZXhlZEVsZW1lbnRzLnNsaWNlKHN0YXJ0LCBlbmQpO1xuICAgIH0sXG5cbiAgICByZWJ1aWxkTG9hZGVkRWxlbWVudHM6IGZ1bmN0aW9uIHJlYnVpbGRMb2FkZWRFbGVtZW50cygpIHtcbiAgICAgICAgdmFyIG5ld0VsZW1lbnRzID0gdGhpcy5idWlsZEVsZW1lbnRzKHRoaXMuc3RhdGUuc29ydGluZ0luZm8sIDAsIE1hdGgubWF4KHRoaXMuc3RhdGUuZWxlbWVudHMubGVuZ3RoLCB0aGlzLnByb3BzLmluZmluaXRlU2xpY2VDb3VudCkpO1xuICAgICAgICB2YXIgaW5maW5pdGVMb2FkQmVnaW5Cb3R0b21PZmZzZXQgPSBuZXdFbGVtZW50cy5sZW5ndGggPyAyMDAgOiAwO1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIGVsZW1lbnRzOiBuZXdFbGVtZW50cyxcbiAgICAgICAgICAgIGluZmluaXRlTG9hZEJlZ2luQm90dG9tT2Zmc2V0OiBpbmZpbml0ZUxvYWRCZWdpbkJvdHRvbU9mZnNldFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy51cGRhdGVJbmZpbml0ZUNvbnRhaW5lckhlaWdodCgpO1xuICAgIH0sXG5cbiAgICBoYW5kbGVJbmZpbml0ZUxvYWQ6IGZ1bmN0aW9uIGhhbmRsZUluZmluaXRlTG9hZCgpIHtcbiAgICAgICAgdmFyIGVsZW1MZW5ndGggPSB0aGlzLnN0YXRlLmVsZW1lbnRzLmxlbmd0aDtcbiAgICAgICAgdmFyIG5ld0VsZW1lbnRzID0gdGhpcy5idWlsZEVsZW1lbnRzKHRoaXMuc3RhdGUuc29ydGluZ0luZm8sIGVsZW1MZW5ndGgsIGVsZW1MZW5ndGggKyB0aGlzLnByb3BzLmluZmluaXRlU2xpY2VDb3VudCk7XG4gICAgICAgIHZhciBpbmZpbml0ZUxvYWRCZWdpbkJvdHRvbU9mZnNldCA9IG5ld0VsZW1lbnRzLmxlbmd0aCA/IDIwMCA6IDA7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgaXNJbmZpbml0ZUxvYWRpbmc6IGZhbHNlLFxuICAgICAgICAgICAgZWxlbWVudHM6IHRoaXMuc3RhdGUuZWxlbWVudHMuY29uY2F0KG5ld0VsZW1lbnRzKSxcbiAgICAgICAgICAgIGluZmluaXRlTG9hZEJlZ2luQm90dG9tT2Zmc2V0OiBpbmZpbml0ZUxvYWRCZWdpbkJvdHRvbU9mZnNldFxuICAgICAgICB9KTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogRXh0cmFjdCByZW1vdGUgc29ydGluZyBpbmZvIGZyb20gY3VycmVudCBub2RlIG1ldGFkYXRhXG4gICAgICovXG4gICAgcmVtb3RlU29ydGluZ0luZm86IGZ1bmN0aW9uIHJlbW90ZVNvcnRpbmdJbmZvKCkge1xuICAgICAgICB2YXIgbWV0YSA9IHRoaXMucHJvcHMubm9kZS5nZXRNZXRhZGF0YSgpLmdldCgncGFnaW5hdGlvbkRhdGEnKTtcbiAgICAgICAgaWYgKG1ldGEgJiYgbWV0YS5nZXQoJ3RvdGFsJykgPiAxICYmIG1ldGEuaGFzKCdyZW1vdGVfb3JkZXInKSkge1xuICAgICAgICAgICAgdmFyIGNvbCA9IG1ldGEuZ2V0KCdjdXJyZW50T3JkZXJDb2wnKTtcbiAgICAgICAgICAgIHZhciBkaXIgPSBtZXRhLmdldCgnY3VycmVudE9yZGVyRGlyJyk7XG4gICAgICAgICAgICBpZiAoY29sICYmIGRpcikge1xuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgIHJlbW90ZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlOiBjb2wsXG4gICAgICAgICAgICAgICAgICAgIGRpcmVjdGlvbjogZGlyXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9LFxuXG4gICAgcmVuZGVyVG9vbGJhcjogZnVuY3Rpb24gcmVuZGVyVG9vbGJhcigpIHtcbiAgICAgICAgdmFyIF90aGlzNyA9IHRoaXM7XG5cbiAgICAgICAgdmFyIHJpZ2h0QnV0dG9ucyA9IFtSZWFjdC5jcmVhdGVFbGVtZW50KFJlYWN0TVVJLkZvbnRJY29uLCB7XG4gICAgICAgICAgICBrZXk6IDEsXG4gICAgICAgICAgICB0b29sdGlwOiAnUmVsb2FkJyxcbiAgICAgICAgICAgIGNsYXNzTmFtZTogXCJpY29uLXJlZnJlc2hcIiArICh0aGlzLnN0YXRlLmxvYWRpbmcgPyBcIiByb3RhdGluZ1wiIDogXCJcIiksXG4gICAgICAgICAgICBvbkNsaWNrOiB0aGlzLnJlbG9hZFxuICAgICAgICB9KV07XG4gICAgICAgIHZhciBpID0gMjtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMuc29ydEtleXMpIHtcblxuICAgICAgICAgICAgdmFyIHNvcnRpbmdJbmZvID0gdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgIHJlbW90ZVNvcnRpbmdJbmZvID0gdGhpcy5yZW1vdGVTb3J0aW5nSW5mbygpO1xuICAgICAgICAgICAgaWYgKHJlbW90ZVNvcnRpbmdJbmZvKSB7XG4gICAgICAgICAgICAgICAgc29ydGluZ0luZm8gPSByZW1vdGVTb3J0aW5nSW5mbztcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgc29ydGluZ0luZm8gPSB0aGlzLnN0YXRlID8gdGhpcy5zdGF0ZS5zb3J0aW5nSW5mbyA6IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByaWdodEJ1dHRvbnMucHVzaChSZWFjdC5jcmVhdGVFbGVtZW50KF9Tb3J0Q29sdW1uczJbJ2RlZmF1bHQnXSwge1xuICAgICAgICAgICAgICAgIGtleTogaSxcbiAgICAgICAgICAgICAgICBkaXNwbGF5TW9kZTogJ21lbnUnLFxuICAgICAgICAgICAgICAgIHRhYmxlS2V5czogdGhpcy5wcm9wcy5zb3J0S2V5cyxcbiAgICAgICAgICAgICAgICBjb2x1bW5DbGlja2VkOiB0aGlzLm9uQ29sdW1uU29ydCxcbiAgICAgICAgICAgICAgICBzb3J0aW5nSW5mbzogc29ydGluZ0luZm9cbiAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIGkrKztcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5wcm9wcy5hZGRpdGlvbmFsQWN0aW9ucykge1xuICAgICAgICAgICAgcmlnaHRCdXR0b25zLnB1c2godGhpcy5wcm9wcy5hZGRpdGlvbmFsQWN0aW9ucyk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgbGVmdFRvb2xiYXIgPSB1bmRlZmluZWQsXG4gICAgICAgICAgICBwYWdpbmF0b3IgPSB1bmRlZmluZWQ7XG4gICAgICAgIGlmICh0aGlzLnByb3BzLm5vZGUuZ2V0TWV0YWRhdGEoKS5nZXQoXCJwYWdpbmF0aW9uRGF0YVwiKSAmJiB0aGlzLnByb3BzLm5vZGUuZ2V0TWV0YWRhdGEoKS5nZXQoXCJwYWdpbmF0aW9uRGF0YVwiKS5nZXQoJ3RvdGFsJykgPiAxKSB7XG4gICAgICAgICAgICBwYWdpbmF0b3IgPSBSZWFjdC5jcmVhdGVFbGVtZW50KF9MaXN0UGFnaW5hdG9yMlsnZGVmYXVsdCddLCB7IGRhdGFNb2RlbDogdGhpcy5kbSwgbm9kZTogdGhpcy5wcm9wcy5ub2RlIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMucHJvcHMubGlzdFRpdGxlKSB7XG4gICAgICAgICAgICBsZWZ0VG9vbGJhciA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgUmVhY3RNVUkuVG9vbGJhckdyb3VwLFxuICAgICAgICAgICAgICAgIHsga2V5OiAwLCBmbG9hdDogJ2xlZnQnIH0sXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgICAgIHsgY2xhc3NOYW1lOiAnbGlzdC10aXRsZScgfSxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5saXN0VGl0bGVcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMucHJvcHMuc2VhcmNoUmVzdWx0RGF0YSkge1xuXG4gICAgICAgICAgICBsZWZ0VG9vbGJhciA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgUmVhY3RNVUkuVG9vbGJhckdyb3VwLFxuICAgICAgICAgICAgICAgIHsga2V5OiAwLCBmbG9hdDogJ2xlZnQnIH0sXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgICAgJ2gyJyxcbiAgICAgICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6ICdzZWFyY2gtcmVzdWx0cy10aXRsZScgfSxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb250ZXh0LmdldE1lc3NhZ2UoJ3JlYWN0LjMnKS5yZXBsYWNlKCclcycsIHRoaXMucHJvcHMuc2VhcmNoUmVzdWx0RGF0YS50ZXJtKVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICByaWdodEJ1dHRvbnMgPSBSZWFjdC5jcmVhdGVFbGVtZW50KFJlYWN0TVVJLlJhaXNlZEJ1dHRvbiwgeyBrZXk6IDEsIGxhYmVsOiB0aGlzLmNvbnRleHQuZ2V0TWVzc2FnZSgncmVhY3QuNCcpLCBwcmltYXJ5OiB0cnVlLCBvbkNsaWNrOiB0aGlzLnByb3BzLnNlYXJjaFJlc3VsdERhdGEudG9nZ2xlU3RhdGUgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5hY3Rpb25zQ2FjaGUubXVsdGlwbGUuc2l6ZSB8fCB0aGlzLnByb3BzLm11bHRpcGxlQWN0aW9ucykge1xuICAgICAgICAgICAgdmFyIGJ1bGtMYWJlbCA9IHRoaXMuY29udGV4dC5nZXRNZXNzYWdlKCdyZWFjdC4yJyk7XG4gICAgICAgICAgICBpZiAodGhpcy5zdGF0ZS5zZWxlY3Rpb24gJiYgdGhpcy5zdGF0ZS5zaG93U2VsZWN0b3IpIHtcbiAgICAgICAgICAgICAgICBidWxrTGFiZWwgKz0gXCIgKFwiICsgdGhpcy5zdGF0ZS5zZWxlY3Rpb24uc2l6ZSArIFwiKVwiO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGVmdFRvb2xiYXIgPSBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgIFJlYWN0TVVJLlRvb2xiYXJHcm91cCxcbiAgICAgICAgICAgICAgICB7IGtleTogMCwgZmxvYXQ6ICdsZWZ0JywgY2xhc3NOYW1lOiAnaGlkZS1vbi12ZXJ0aWNhbC1sYXlvdXQnIH0sXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChSZWFjdE1VSS5DaGVja2JveCwgeyByZWY6ICdhbGxfc2VsZWN0b3InLCBvbkNsaWNrOiB0aGlzLnNlbGVjdEFsbCB9KSxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFJlYWN0TVVJLkZsYXRCdXR0b24sIHsgbGFiZWw6IGJ1bGtMYWJlbCwgb25DbGljazogdGhpcy50b2dnbGVTZWxlY3RvciB9KVxuICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUuc2hvd1NlbGVjdG9yKSB7XG4gICAgICAgICAgICAgICAgKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgcmlnaHRCdXR0b25zID0gW107XG4gICAgICAgICAgICAgICAgICAgIHZhciBpbmRleCA9IDA7XG4gICAgICAgICAgICAgICAgICAgIHZhciBhY3Rpb25zID0gX3RoaXM3LnByb3BzLm11bHRpcGxlQWN0aW9ucyB8fCBfdGhpczcuYWN0aW9uc0NhY2hlLm11bHRpcGxlO1xuICAgICAgICAgICAgICAgICAgICBhY3Rpb25zLmZvckVhY2goKGZ1bmN0aW9uIChhKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByaWdodEJ1dHRvbnMucHVzaChSZWFjdC5jcmVhdGVFbGVtZW50KFJlYWN0TVVJLlJhaXNlZEJ1dHRvbiwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleTogaW5kZXgsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWw6IGEub3B0aW9ucy50ZXh0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdkYXRhLWFjdGlvbic6IGEub3B0aW9ucy5uYW1lLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uQ2xpY2s6IHRoaXMuYXBwbHlNdWx0aXBsZUFjdGlvbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmltYXJ5OiB0cnVlIH0pKTtcbiAgICAgICAgICAgICAgICAgICAgfSkuYmluZChfdGhpczcpKTtcbiAgICAgICAgICAgICAgICAgICAgcmlnaHRCdXR0b25zID0gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgICAgICAgICdzcGFuJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgICAgICAgICByaWdodEJ1dHRvbnNcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9KSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICBSZWFjdE1VSS5Ub29sYmFyLFxuICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgIGxlZnRUb29sYmFyLFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICBSZWFjdE1VSS5Ub29sYmFyR3JvdXAsXG4gICAgICAgICAgICAgICAgeyBrZXk6IDEsIGZsb2F0OiAncmlnaHQnIH0sXG4gICAgICAgICAgICAgICAgcGFnaW5hdG9yLFxuICAgICAgICAgICAgICAgIHJpZ2h0QnV0dG9uc1xuICAgICAgICAgICAgKVxuICAgICAgICApO1xuICAgIH0sXG5cbiAgICByZW5kZXI6IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgICAgdmFyIF90aGlzOCA9IHRoaXM7XG5cbiAgICAgICAgdmFyIGNvbnRhaW5lckNsYXNzZXMgPSBcIm1hdGVyaWFsLWxpc3QgdmVydGljYWwtbGF5b3V0IGxheW91dC1maWxsXCI7XG4gICAgICAgIGlmICh0aGlzLnByb3BzLmNsYXNzTmFtZSkge1xuICAgICAgICAgICAgY29udGFpbmVyQ2xhc3NlcyArPSBcIiBcIiArIHRoaXMucHJvcHMuY2xhc3NOYW1lO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnN0YXRlLnNob3dTZWxlY3Rvcikge1xuICAgICAgICAgICAgY29udGFpbmVyQ2xhc3NlcyArPSBcIiBsaXN0LXNob3ctc2VsZWN0b3JzXCI7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMucHJvcHMudGFibGVLZXlzKSB7XG4gICAgICAgICAgICBjb250YWluZXJDbGFzc2VzICs9IFwiIHRhYmxlLW1vZGVcIjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgdG9vbGJhciA9IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMudGFibGVLZXlzKSB7XG4gICAgICAgICAgICB2YXIgdGFibGVLZXlzID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgaWYgKHRoaXMucHJvcHMuZGVmYXVsdEdyb3VwQnkpIHtcbiAgICAgICAgICAgICAgICB0YWJsZUtleXMgPSBMYW5nVXRpbHMuZGVlcENvcHkodGhpcy5wcm9wcy50YWJsZUtleXMpO1xuICAgICAgICAgICAgICAgIGRlbGV0ZSB0YWJsZUtleXNbdGhpcy5wcm9wcy5kZWZhdWx0R3JvdXBCeV07XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRhYmxlS2V5cyA9IHRoaXMucHJvcHMudGFibGVLZXlzO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIHNvcnRpbmdJbmZvID0gdW5kZWZpbmVkLFxuICAgICAgICAgICAgICAgIHJlbW90ZVNvcnRpbmdJbmZvID0gdGhpcy5yZW1vdGVTb3J0aW5nSW5mbygpO1xuICAgICAgICAgICAgaWYgKHJlbW90ZVNvcnRpbmdJbmZvKSB7XG4gICAgICAgICAgICAgICAgc29ydGluZ0luZm8gPSByZW1vdGVTb3J0aW5nSW5mbztcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgc29ydGluZ0luZm8gPSB0aGlzLnN0YXRlID8gdGhpcy5zdGF0ZS5zb3J0aW5nSW5mbyA6IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0b29sYmFyID0gUmVhY3QuY3JlYXRlRWxlbWVudChfVGFibGVMaXN0SGVhZGVyMlsnZGVmYXVsdCddLCB7XG4gICAgICAgICAgICAgICAgdGFibGVLZXlzOiB0YWJsZUtleXMsXG4gICAgICAgICAgICAgICAgbG9hZGluZzogdGhpcy5zdGF0ZS5sb2FkaW5nLFxuICAgICAgICAgICAgICAgIHJlbG9hZDogdGhpcy5yZWxvYWQsXG4gICAgICAgICAgICAgICAgcmVmOiAnbG9hZGluZ19pbmRpY2F0b3InLFxuICAgICAgICAgICAgICAgIGRtOiB0aGlzLnByb3BzLmRhdGFNb2RlbCxcbiAgICAgICAgICAgICAgICBub2RlOiB0aGlzLnByb3BzLm5vZGUsXG4gICAgICAgICAgICAgICAgYWRkaXRpb25hbEFjdGlvbnM6IHRoaXMucHJvcHMuYWRkaXRpb25hbEFjdGlvbnMsXG4gICAgICAgICAgICAgICAgb25IZWFkZXJDbGljazogdGhpcy5vbkNvbHVtblNvcnQsXG4gICAgICAgICAgICAgICAgc29ydGluZ0luZm86IHNvcnRpbmdJbmZvXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRvb2xiYXIgPSB0aGlzLnByb3BzLmN1c3RvbVRvb2xiYXIgPyB0aGlzLnByb3BzLmN1c3RvbVRvb2xiYXIgOiAhdGhpcy5wcm9wcy5oaWRlVG9vbGJhciA/IHRoaXMucmVuZGVyVG9vbGJhcigpIDogbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBpbmxpbmVFZGl0b3IgPSB1bmRlZmluZWQ7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlLmlubGluZUVkaXRpb25Gb3JOb2RlKSB7XG4gICAgICAgICAgICBpbmxpbmVFZGl0b3IgPSBSZWFjdC5jcmVhdGVFbGVtZW50KF9JbmxpbmVFZGl0b3IyWydkZWZhdWx0J10sIHtcbiAgICAgICAgICAgICAgICBkZXRhY2hlZDogdHJ1ZSxcbiAgICAgICAgICAgICAgICBub2RlOiB0aGlzLnN0YXRlLmlubGluZUVkaXRpb25Gb3JOb2RlLFxuICAgICAgICAgICAgICAgIGNhbGxiYWNrOiB0aGlzLnN0YXRlLmlubGluZUVkaXRpb25DYWxsYmFjayxcbiAgICAgICAgICAgICAgICBvbkNsb3NlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzOC5zZXRTdGF0ZSh7IGlubGluZUVkaXRpb25Gb3JOb2RlOiBudWxsIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGVtcHR5U3RhdGUgPSB1bmRlZmluZWQ7XG4gICAgICAgIHZhciBfcHJvcHMgPSB0aGlzLnByb3BzO1xuICAgICAgICB2YXIgZW1wdHlTdGF0ZVByb3BzID0gX3Byb3BzLmVtcHR5U3RhdGVQcm9wcztcbiAgICAgICAgdmFyIG5vZGUgPSBfcHJvcHMubm9kZTtcblxuICAgICAgICBpZiAoZW1wdHlTdGF0ZVByb3BzICYmIHRoaXMucHJvcHMubm9kZS5pc0xvYWRlZCgpICYmICF0aGlzLnByb3BzLm5vZGUuaXNMb2FkaW5nKCkgJiYgKCF0aGlzLnN0YXRlLmVsZW1lbnRzLmxlbmd0aCB8fCB0aGlzLnN0YXRlLmVsZW1lbnRzLmxlbmd0aCA9PT0gMSAmJiB0aGlzLnN0YXRlLmVsZW1lbnRzWzBdLnBhcmVudCkpIHtcblxuICAgICAgICAgICAgdmFyIGFjdGlvblByb3BzID0ge307XG4gICAgICAgICAgICBpZiAodGhpcy5zdGF0ZS5lbGVtZW50cy5sZW5ndGggPT09IDEgJiYgdGhpcy5zdGF0ZS5lbGVtZW50c1swXS5wYXJlbnQpIHtcbiAgICAgICAgICAgICAgICAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgcGFyZW50Tm9kZSA9IF90aGlzOC5zdGF0ZS5lbGVtZW50c1swXS5ub2RlO1xuICAgICAgICAgICAgICAgICAgICBhY3Rpb25Qcm9wcyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFjdGlvbkxhYmVsSWQ6ICdyZWFjdC4xJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGFjdGlvbkljb25DbGFzc05hbWU6IFNpbXBsZUxpc3QuUEFSRU5UX0ZPTERFUl9JQ09OLFxuICAgICAgICAgICAgICAgICAgICAgICAgYWN0aW9uQ2FsbGJhY2s6IGZ1bmN0aW9uIGFjdGlvbkNhbGxiYWNrKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3RoaXM4LnByb3BzLmVudHJ5SGFuZGxlQ2xpY2tzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzOC5wcm9wcy5lbnRyeUhhbmRsZUNsaWNrcyhwYXJlbnROb2RlLCBTaW1wbGVMaXN0LkNMSUNLX1RZUEVfRE9VQkxFLCBlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfSkoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVtcHR5U3RhdGUgPSBSZWFjdC5jcmVhdGVFbGVtZW50KF92aWV3c0VtcHR5U3RhdGVWaWV3MlsnZGVmYXVsdCddLCBfZXh0ZW5kcyh7fSwgZW1wdHlTdGF0ZVByb3BzLCBhY3Rpb25Qcm9wcykpO1xuICAgICAgICB9IGVsc2UgaWYgKGVtcHR5U3RhdGVQcm9wcyAmJiBlbXB0eVN0YXRlUHJvcHMuY2hlY2tFbXB0eVN0YXRlICYmIGVtcHR5U3RhdGVQcm9wcy5jaGVja0VtcHR5U3RhdGUodGhpcy5wcm9wcy5ub2RlKSkge1xuXG4gICAgICAgICAgICBlbXB0eVN0YXRlID0gUmVhY3QuY3JlYXRlRWxlbWVudChfdmlld3NFbXB0eVN0YXRlVmlldzJbJ2RlZmF1bHQnXSwgZW1wdHlTdGF0ZVByb3BzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBlbGVtZW50cyA9IHRoaXMuYnVpbGRFbGVtZW50c0Zyb21Ob2RlRW50cmllcyh0aGlzLnN0YXRlLmVsZW1lbnRzLCB0aGlzLnN0YXRlLnNob3dTZWxlY3Rvcik7XG5cbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgIHsgY2xhc3NOYW1lOiBjb250YWluZXJDbGFzc2VzLCBvbkNvbnRleHRNZW51OiB0aGlzLmNvbnRleHRNZW51UmVzcG9uZGVyLCB0YWJJbmRleDogJzAnLCBvbktleURvd246IHRoaXMub25LZXlEb3duLCBzdHlsZTogdGhpcy5wcm9wcy5zdHlsZSB9LFxuICAgICAgICAgICAgdG9vbGJhcixcbiAgICAgICAgICAgIGlubGluZUVkaXRvcixcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6IHRoaXMucHJvcHMuaGVpZ2h0QXV0b1dpdGhNYXggPyBcImluZmluaXRlLXBhcmVudC1zbW9vdGgtaGVpZ2h0XCIgOiBlbXB0eVN0YXRlID8gXCJsYXlvdXQtZmlsbCB2ZXJ0aWNhbF9sYXlvdXRcIiA6IFwibGF5b3V0LWZpbGxcIiwgcmVmOiAnaW5maW5pdGVQYXJlbnQnIH0sXG4gICAgICAgICAgICAgICAgIWVtcHR5U3RhdGUgJiYgIXRoaXMucHJvcHMudmVydGljYWxTY3JvbGxlciAmJiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICBJbmZpbml0ZSxcbiAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudEhlaWdodDogdGhpcy5zdGF0ZS5lbGVtZW50SGVpZ2h0ID8gdGhpcy5zdGF0ZS5lbGVtZW50SGVpZ2h0IDogdGhpcy5wcm9wcy5lbGVtZW50SGVpZ2h0LFxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGFpbmVySGVpZ2h0OiB0aGlzLnN0YXRlLmNvbnRhaW5lckhlaWdodCA/IHRoaXMuc3RhdGUuY29udGFpbmVySGVpZ2h0IDogMSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGluZmluaXRlTG9hZEJlZ2luRWRnZU9mZnNldDogdGhpcy5zdGF0ZS5pbmZpbml0ZUxvYWRCZWdpbkJvdHRvbU9mZnNldCxcbiAgICAgICAgICAgICAgICAgICAgICAgIG9uSW5maW5pdGVMb2FkOiB0aGlzLmhhbmRsZUluZmluaXRlTG9hZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZVNjcm9sbDogdGhpcy5vblNjcm9sbCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlZjogJ2luZmluaXRlJ1xuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBlbGVtZW50c1xuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgIWVtcHR5U3RhdGUgJiYgdGhpcy5wcm9wcy52ZXJ0aWNhbFNjcm9sbGVyICYmIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgIF9yZWFjdFNjcm9sbGJhcjJbJ2RlZmF1bHQnXSxcbiAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3BlZWQ6IDAuOCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGhvcml6b250YWxTY3JvbGw6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHsgaGVpZ2h0OiB0aGlzLnN0YXRlLmNvbnRhaW5lckhlaWdodCB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgdmVydGljYWxTY3JvbGxiYXJTdHlsZTogeyBib3JkZXJSYWRpdXM6IDEwLCB3aWR0aDogNiB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgdmVydGljYWxDb250YWluZXJTdHlsZTogeyB3aWR0aDogOCB9XG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50c1xuICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICBlbXB0eVN0YXRlXG4gICAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgfVxuXG59KTtcblxuZXhwb3J0c1snZGVmYXVsdCddID0gU2ltcGxlTGlzdDtcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDA3LTIwMTcgQ2hhcmxlcyBkdSBKZXUgLSBBYnN0cml1bSBTQVMgPHRlYW0gKGF0KSBweWQuaW8+XG4gKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBQeWRpby5cbiAqXG4gKiBQeWRpbyBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFB5ZGlvIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIFB5ZGlvLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuICpcbiAqIFRoZSBsYXRlc3QgY29kZSBjYW4gYmUgZm91bmQgYXQgPGh0dHBzOi8vcHlkaW8uY29tPi5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7ICdkZWZhdWx0Jzogb2JqIH07IH1cblxudmFyIF9tZW51SWNvbkJ1dHRvbk1lbnUgPSByZXF1aXJlKCcuLi9tZW51L0ljb25CdXR0b25NZW51Jyk7XG5cbnZhciBfbWVudUljb25CdXR0b25NZW51MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX21lbnVJY29uQnV0dG9uTWVudSk7XG5cbnZhciBSZWFjdCA9IHJlcXVpcmUoJ3JlYWN0Jyk7XG52YXIgUHlkaW8gPSByZXF1aXJlKCdweWRpbycpO1xuXG52YXIgX1B5ZGlvJHJlcXVpcmVMaWIgPSBQeWRpby5yZXF1aXJlTGliKCdib290Jyk7XG5cbnZhciBQeWRpb0NvbnRleHRDb25zdW1lciA9IF9QeWRpbyRyZXF1aXJlTGliLlB5ZGlvQ29udGV4dENvbnN1bWVyO1xuXG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKCdtYXRlcmlhbC11aS1sZWdhY3knKTtcblxudmFyIFRvb2xiYXJHcm91cCA9IF9yZXF1aXJlLlRvb2xiYXJHcm91cDtcblxudmFyIFNvcnRDb2x1bW5zID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuICAgIGRpc3BsYXlOYW1lOiAnU29ydENvbHVtbnMnLFxuXG4gICAgcHJvcFR5cGVzOiB7XG4gICAgICAgIHRhYmxlS2V5czogUmVhY3QuUHJvcFR5cGVzLm9iamVjdC5pc1JlcXVpcmVkLFxuICAgICAgICBjb2x1bW5DbGlja2VkOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgICAgICAgc29ydGluZ0luZm86IFJlYWN0LlByb3BUeXBlcy5vYmplY3QsXG4gICAgICAgIGRpc3BsYXlNb2RlOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nXG4gICAgfSxcblxuICAgIG9uTWVudUNsaWNrZWQ6IGZ1bmN0aW9uIG9uTWVudUNsaWNrZWQob2JqZWN0KSB7XG4gICAgICAgIHRoaXMucHJvcHMuY29sdW1uQ2xpY2tlZChvYmplY3QucGF5bG9hZCk7XG4gICAgfSxcblxuICAgIG9uSGVhZGVyQ2xpY2s6IGZ1bmN0aW9uIG9uSGVhZGVyQ2xpY2soa2V5LCBjYWxsYmFjaykge1xuICAgICAgICB2YXIgZGF0YSA9IHRoaXMucHJvcHMudGFibGVLZXlzW2tleV07XG4gICAgICAgIGlmIChkYXRhICYmIGRhdGFbJ3NvcnRUeXBlJ10gJiYgdGhpcy5wcm9wcy5jb2x1bW5DbGlja2VkKSB7XG4gICAgICAgICAgICBkYXRhWyduYW1lJ10gPSBrZXk7XG4gICAgICAgICAgICB0aGlzLnByb3BzLmNvbHVtbkNsaWNrZWQoZGF0YSwgY2FsbGJhY2spO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIGdldENvbHVtbnNJdGVtczogZnVuY3Rpb24gZ2V0Q29sdW1uc0l0ZW1zKGRpc3BsYXlNb2RlKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICAgICAgdmFyIGNvbnRyb2xsZXIgPSBhcmd1bWVudHMubGVuZ3RoIDw9IDEgfHwgYXJndW1lbnRzWzFdID09PSB1bmRlZmluZWQgPyBudWxsIDogYXJndW1lbnRzWzFdO1xuXG4gICAgICAgIHZhciBpdGVtcyA9IFtdO1xuICAgICAgICB2YXIgX2NhbGxiYWNrID0gZnVuY3Rpb24gX2NhbGxiYWNrKCkge1xuICAgICAgICAgICAgaWYgKGNvbnRyb2xsZXIpIHtcbiAgICAgICAgICAgICAgICBjb250cm9sbGVyLm5vdGlmeSgnYWN0aW9uc19yZWZyZXNoZWQnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICB2YXIgX2xvb3AgPSBmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgICAgICBpZiAoIV90aGlzLnByb3BzLnRhYmxlS2V5cy5oYXNPd25Qcm9wZXJ0eShrZXkpKSByZXR1cm4gJ2NvbnRpbnVlJztcbiAgICAgICAgICAgIHZhciBkYXRhID0gX3RoaXMucHJvcHMudGFibGVLZXlzW2tleV07XG4gICAgICAgICAgICB2YXIgc3R5bGUgPSBkYXRhWyd3aWR0aCddID8geyB3aWR0aDogZGF0YVsnd2lkdGgnXSB9IDogbnVsbDtcbiAgICAgICAgICAgIHZhciBpY29uID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgdmFyIGNsYXNzTmFtZSA9ICdjZWxsIGhlYWRlcl9jZWxsIGNlbGwtJyArIGtleTtcbiAgICAgICAgICAgIGlmIChkYXRhWydzb3J0VHlwZSddKSB7XG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lICs9ICcgc29ydGFibGUnO1xuICAgICAgICAgICAgICAgIGlmIChfdGhpcy5wcm9wcy5zb3J0aW5nSW5mbyAmJiAoX3RoaXMucHJvcHMuc29ydGluZ0luZm8uYXR0cmlidXRlID09PSBrZXkgfHwgX3RoaXMucHJvcHMuc29ydGluZ0luZm8uYXR0cmlidXRlID09PSBkYXRhWydzb3J0QXR0cmlidXRlJ10gfHwgX3RoaXMucHJvcHMuc29ydGluZ0luZm8uYXR0cmlidXRlID09PSBkYXRhWydyZW1vdGVTb3J0QXR0cmlidXRlJ10pKSB7XG4gICAgICAgICAgICAgICAgICAgIGljb24gPSBfdGhpcy5wcm9wcy5zb3J0aW5nSW5mby5kaXJlY3Rpb24gPT09ICdhc2MnID8gJ21kaSBtZGktYXJyb3ctdXAnIDogJ21kaSBtZGktYXJyb3ctZG93bic7XG4gICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZSArPSAnIGFjdGl2ZS1zb3J0LScgKyBfdGhpcy5wcm9wcy5zb3J0aW5nSW5mby5kaXJlY3Rpb247XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGRpc3BsYXlNb2RlID09PSAnbWVudScpIHtcbiAgICAgICAgICAgICAgICBkYXRhWyduYW1lJ10gPSBrZXk7XG4gICAgICAgICAgICAgICAgaXRlbXMucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgIHBheWxvYWQ6IGRhdGEsXG4gICAgICAgICAgICAgICAgICAgIHRleHQ6IGRhdGFbJ2xhYmVsJ10sXG4gICAgICAgICAgICAgICAgICAgIGljb25DbGFzc05hbWU6IGljb25cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoZGlzcGxheU1vZGUgPT09ICdtZW51X2RhdGEnKSB7XG4gICAgICAgICAgICAgICAgaXRlbXMucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgIG5hbWU6IGRhdGFbJ2xhYmVsJ10sXG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrOiBmdW5jdGlvbiBjYWxsYmFjaygpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzLm9uSGVhZGVyQ2xpY2soa2V5LCBfY2FsbGJhY2spO1xuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBpY29uX2NsYXNzOiBpY29uIHx8ICdfX0lOU0VUX18nXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGl0ZW1zLnB1c2goUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgICAgJ3NwYW4nLFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBrZXk6IGtleSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogY2xhc3NOYW1lLFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHN0eWxlLFxuICAgICAgICAgICAgICAgICAgICAgICAgb25DbGljazogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzLm9uSGVhZGVyQ2xpY2soa2V5LCBfY2FsbGJhY2spO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBkYXRhWydsYWJlbCddXG4gICAgICAgICAgICAgICAgKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgZm9yICh2YXIga2V5IGluIHRoaXMucHJvcHMudGFibGVLZXlzKSB7XG4gICAgICAgICAgICB2YXIgX3JldCA9IF9sb29wKGtleSk7XG5cbiAgICAgICAgICAgIGlmIChfcmV0ID09PSAnY29udGludWUnKSBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gaXRlbXM7XG4gICAgfSxcblxuICAgIGJ1aWxkU29ydGluZ01lbnVJdGVtczogZnVuY3Rpb24gYnVpbGRTb3J0aW5nTWVudUl0ZW1zKGNvbnRyb2xsZXIpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0Q29sdW1uc0l0ZW1zKCdtZW51X2RhdGEnLCBjb250cm9sbGVyKTtcbiAgICB9LFxuXG4gICAgY29tcG9uZW50RGlkTW91bnQ6IGZ1bmN0aW9uIGNvbXBvbmVudERpZE1vdW50KCkge1xuXG4gICAgICAgIHZhciBzb3J0QWN0aW9uID0gbmV3IEFjdGlvbih7XG4gICAgICAgICAgICBuYW1lOiAnc29ydF9hY3Rpb24nLFxuICAgICAgICAgICAgaWNvbl9jbGFzczogJ21kaSBtZGktc29ydC1kZXNjZW5kaW5nJyxcbiAgICAgICAgICAgIHRleHRfaWQ6IDQ1MCxcbiAgICAgICAgICAgIHRpdGxlX2lkOiA0NTAsXG4gICAgICAgICAgICB0ZXh0OiB0aGlzLnByb3BzLmdldE1lc3NhZ2UoNDUwKSxcbiAgICAgICAgICAgIHRpdGxlOiB0aGlzLnByb3BzLmdldE1lc3NhZ2UoNDUwKSxcbiAgICAgICAgICAgIGhhc0FjY2Vzc0tleTogZmFsc2UsXG4gICAgICAgICAgICBzdWJNZW51OiB0cnVlLFxuICAgICAgICAgICAgc3ViTWVudVVwZGF0ZUltYWdlOiB0cnVlXG4gICAgICAgIH0sIHtcbiAgICAgICAgICAgIHNlbGVjdGlvbjogZmFsc2UsXG4gICAgICAgICAgICBkaXI6IHRydWUsXG4gICAgICAgICAgICBhY3Rpb25CYXI6IHRydWUsXG4gICAgICAgICAgICBhY3Rpb25CYXJHcm91cDogJ2Rpc3BsYXlfdG9vbGJhcicsXG4gICAgICAgICAgICBjb250ZXh0TWVudTogZmFsc2UsXG4gICAgICAgICAgICBpbmZvUGFuZWw6IGZhbHNlXG4gICAgICAgIH0sIHt9LCB7fSwge1xuICAgICAgICAgICAgZHluYW1pY0J1aWxkZXI6IHRoaXMuYnVpbGRTb3J0aW5nTWVudUl0ZW1zXG4gICAgICAgIH0pO1xuICAgICAgICB2YXIgYnV0dG9ucyA9IG5ldyBNYXAoKTtcbiAgICAgICAgYnV0dG9ucy5zZXQoJ3NvcnRfYWN0aW9uJywgc29ydEFjdGlvbik7XG4gICAgICAgIHRoaXMucHJvcHMucHlkaW8uZ2V0Q29udHJvbGxlcigpLnVwZGF0ZUd1aUFjdGlvbnMoYnV0dG9ucyk7XG4gICAgfSxcblxuICAgIGNvbXBvbmVudFdpbGxVbm1vdW50OiBmdW5jdGlvbiBjb21wb25lbnRXaWxsVW5tb3VudCgpIHtcbiAgICAgICAgdGhpcy5wcm9wcy5weWRpby5nZXRDb250cm9sbGVyKCkuZGVsZXRlRnJvbUd1aUFjdGlvbnMoJ3NvcnRfYWN0aW9uJyk7XG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5kaXNwbGF5TW9kZSA9PT0gJ21lbnUnKSB7XG4gICAgICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChfbWVudUljb25CdXR0b25NZW51MlsnZGVmYXVsdCddLCB7IGJ1dHRvblRpdGxlOiAnU29ydCBieS4uLicsIGJ1dHRvbkNsYXNzTmFtZTogJ21kaSBtZGktc29ydC1kZXNjZW5kaW5nJywgbWVudUl0ZW1zOiB0aGlzLmdldENvbHVtbnNJdGVtcygnbWVudScsIHRoaXMucHJvcHMucHlkaW8uZ2V0Q29udHJvbGxlcigpKSwgb25NZW51Q2xpY2tlZDogdGhpcy5vbk1lbnVDbGlja2VkIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgVG9vbGJhckdyb3VwLFxuICAgICAgICAgICAgICAgIHsgZmxvYXQ6ICdsZWZ0JyB9LFxuICAgICAgICAgICAgICAgIHRoaXMuZ2V0Q29sdW1uc0l0ZW1zKCdoZWFkZXInLCB0aGlzLnByb3BzLnB5ZGlvLmdldENvbnRyb2xsZXIoKSlcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICB9XG59KTtcblxuZXhwb3J0c1snZGVmYXVsdCddID0gU29ydENvbHVtbnMgPSBQeWRpb0NvbnRleHRDb25zdW1lcihTb3J0Q29sdW1ucyk7XG5leHBvcnRzWydkZWZhdWx0J10gPSBTb3J0Q29sdW1ucztcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDA3LTIwMTcgQ2hhcmxlcyBkdSBKZXUgLSBBYnN0cml1bSBTQVMgPHRlYW0gKGF0KSBweWQuaW8+XG4gKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBQeWRpby5cbiAqXG4gKiBQeWRpbyBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFB5ZGlvIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIFB5ZGlvLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuICpcbiAqIFRoZSBsYXRlc3QgY29kZSBjYW4gYmUgZm91bmQgYXQgPGh0dHBzOi8vcHlkaW8uY29tPi5cbiAqL1xuXG5cInVzZSBzdHJpY3RcIjtcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxudmFyIF91dGlsRE5EID0gcmVxdWlyZSgnLi4vdXRpbC9ETkQnKTtcblxuLyoqKioqKioqKioqKioqKioqKioqKioqKioqKi9cbi8qIFJFQUNUIERORCBTT1JUQUJMRSBMSVNUXG4gLyoqKioqKioqKioqKioqKioqKioqKioqKioqL1xuLyoqXG4gKiBTcGVjaWZpZXMgdGhlIGRyYWcgc291cmNlIGNvbnRyYWN0LlxuICogT25seSBgYmVnaW5EcmFnYCBmdW5jdGlvbiBpcyByZXF1aXJlZC5cbiAqL1xudmFyIHNvcnRhYmxlSXRlbVNvdXJjZSA9IHtcbiAgICBiZWdpbkRyYWc6IGZ1bmN0aW9uIGJlZ2luRHJhZyhwcm9wcykge1xuICAgICAgICAvLyBSZXR1cm4gdGhlIGRhdGEgZGVzY3JpYmluZyB0aGUgZHJhZ2dlZCBpdGVtXG4gICAgICAgIHJldHVybiB7IGlkOiBwcm9wcy5pZCB9O1xuICAgIH0sXG4gICAgZW5kRHJhZzogZnVuY3Rpb24gZW5kRHJhZyhwcm9wcykge1xuICAgICAgICBwcm9wcy5lbmRTd2l0Y2hpbmcoKTtcbiAgICB9XG59O1xuXG52YXIgc29ydGFibGVJdGVtVGFyZ2V0ID0ge1xuXG4gICAgaG92ZXI6IGZ1bmN0aW9uIGhvdmVyKHByb3BzLCBtb25pdG9yKSB7XG4gICAgICAgIHZhciBkcmFnZ2VkSWQgPSBtb25pdG9yLmdldEl0ZW0oKS5pZDtcbiAgICAgICAgaWYgKGRyYWdnZWRJZCAhPT0gcHJvcHMuaWQpIHtcbiAgICAgICAgICAgIHByb3BzLnN3aXRjaEl0ZW1zKGRyYWdnZWRJZCwgcHJvcHMuaWQpO1xuICAgICAgICB9XG4gICAgfVxuXG59O1xuXG52YXIgc29ydGFibGVJdGVtID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuICAgIGRpc3BsYXlOYW1lOiBcInNvcnRhYmxlSXRlbVwiLFxuXG4gICAgcHJvcFR5cGVzOiB7XG4gICAgICAgIGNvbm5lY3REcmFnU291cmNlOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYy5pc1JlcXVpcmVkLFxuICAgICAgICBjb25uZWN0RHJvcFRhcmdldDogUmVhY3QuUHJvcFR5cGVzLmZ1bmMuaXNSZXF1aXJlZCxcbiAgICAgICAgaXNEcmFnZ2luZzogUmVhY3QuUHJvcFR5cGVzLmJvb2wuaXNSZXF1aXJlZCxcbiAgICAgICAgaWQ6IFJlYWN0LlByb3BUeXBlcy5hbnkuaXNSZXF1aXJlZCxcbiAgICAgICAgbGFiZWw6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcuaXNSZXF1aXJlZCxcbiAgICAgICAgc3dpdGNoSXRlbXM6IFJlYWN0LlByb3BUeXBlcy5mdW5jLmlzUmVxdWlyZWQsXG4gICAgICAgIHJlbW92YWJsZTogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXG4gICAgICAgIG9uUmVtb3ZlOiBSZWFjdC5Qcm9wVHlwZXMuZnVuY1xuICAgIH0sXG5cbiAgICByZW1vdmVDbGlja2VkOiBmdW5jdGlvbiByZW1vdmVDbGlja2VkKCkge1xuICAgICAgICB0aGlzLnByb3BzLm9uUmVtb3ZlKHRoaXMucHJvcHMuaWQpO1xuICAgIH0sXG5cbiAgICByZW5kZXI6IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgICAgLy8gWW91ciBjb21wb25lbnQgcmVjZWl2ZXMgaXRzIG93biBwcm9wcyBhcyB1c3VhbFxuICAgICAgICB2YXIgaWQgPSB0aGlzLnByb3BzLmlkO1xuXG4gICAgICAgIC8vIFRoZXNlIHR3byBwcm9wcyBhcmUgaW5qZWN0ZWQgYnkgUmVhY3QgRG5ELFxuICAgICAgICAvLyBhcyBkZWZpbmVkIGJ5IHlvdXIgYGNvbGxlY3RgIGZ1bmN0aW9uIGFib3ZlOlxuICAgICAgICB2YXIgaXNEcmFnZ2luZyA9IHRoaXMucHJvcHMuaXNEcmFnZ2luZztcbiAgICAgICAgdmFyIGNvbm5lY3REcmFnU291cmNlID0gdGhpcy5wcm9wcy5jb25uZWN0RHJhZ1NvdXJjZTtcbiAgICAgICAgdmFyIGNvbm5lY3REcm9wVGFyZ2V0ID0gdGhpcy5wcm9wcy5jb25uZWN0RHJvcFRhcmdldDtcblxuICAgICAgICB2YXIgcmVtb3ZlO1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5yZW1vdmFibGUpIHtcbiAgICAgICAgICAgIHJlbW92ZSA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJzcGFuXCIsIHsgY2xhc3NOYW1lOiBcImJ1dHRvbiBtZGkgbWRpLWNsb3NlXCIsIG9uQ2xpY2s6IHRoaXMucmVtb3ZlQ2xpY2tlZCB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgIFJlYWN0TVVJLlBhcGVyLFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHJlZjogZnVuY3Rpb24gKGluc3RhbmNlKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbm5lY3REcm9wVGFyZ2V0KFJlYWN0RE9NLmZpbmRET01Ob2RlKGluc3RhbmNlKSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbm5lY3REcmFnU291cmNlKFJlYWN0RE9NLmZpbmRET01Ob2RlKGluc3RhbmNlKSk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB6RGVwdGg6IDEsXG4gICAgICAgICAgICAgICAgc3R5bGU6IHsgb3BhY2l0eTogaXNEcmFnZ2luZyA/IDAgOiAxIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgIFwiZGl2XCIsXG4gICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6IHRoaXMucHJvcHMuY2xhc3NOYW1lIH0sXG4gICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5sYWJlbCxcbiAgICAgICAgICAgICAgICByZW1vdmVcbiAgICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICB9XG59KTtcblxudmFyIE5vbkRyYWdnYWJsZUxpc3RJdGVtID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuICAgIGRpc3BsYXlOYW1lOiBcIk5vbkRyYWdnYWJsZUxpc3RJdGVtXCIsXG5cbiAgICByZW5kZXI6IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgICAgdmFyIHJlbW92ZTtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMucmVtb3ZhYmxlKSB7XG4gICAgICAgICAgICByZW1vdmUgPSBSZWFjdC5jcmVhdGVFbGVtZW50KFwic3BhblwiLCB7IGNsYXNzTmFtZTogXCJidXR0b24gbWRpIG1kaS1jbG9zZVwiLCBvbkNsaWNrOiB0aGlzLnJlbW92ZUNsaWNrZWQgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICBSZWFjdE1VSS5QYXBlcixcbiAgICAgICAgICAgIHsgekRlcHRoOiAxIH0sXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgIFwiZGl2XCIsXG4gICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6IHRoaXMucHJvcHMuY2xhc3NOYW1lIH0sXG4gICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5sYWJlbCxcbiAgICAgICAgICAgICAgICByZW1vdmVcbiAgICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICB9XG59KTtcblxudmFyIERyYWdnYWJsZUxpc3RJdGVtO1xuaWYgKHdpbmRvdy5SZWFjdERORCkge1xuICAgIERyYWdnYWJsZUxpc3RJdGVtID0gUmVhY3RETkQuZmxvdyhSZWFjdERORC5EcmFnU291cmNlKF91dGlsRE5ELlR5cGVzLlNPUlRBQkxFX0xJU1RfSVRFTSwgc29ydGFibGVJdGVtU291cmNlLCBfdXRpbERORC5jb2xsZWN0KSwgUmVhY3RETkQuRHJvcFRhcmdldChfdXRpbERORC5UeXBlcy5TT1JUQUJMRV9MSVNUX0lURU0sIHNvcnRhYmxlSXRlbVRhcmdldCwgX3V0aWxETkQuY29sbGVjdERyb3ApKShzb3J0YWJsZUl0ZW0pO1xufSBlbHNlIHtcbiAgICBEcmFnZ2FibGVMaXN0SXRlbSA9IE5vbkRyYWdnYWJsZUxpc3RJdGVtO1xufVxuXG52YXIgU29ydGFibGVMaXN0ID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuICAgIGRpc3BsYXlOYW1lOiBcIlNvcnRhYmxlTGlzdFwiLFxuXG4gICAgcHJvcFR5cGVzOiB7XG4gICAgICAgIHZhbHVlczogUmVhY3QuUHJvcFR5cGVzLmFycmF5LmlzUmVxdWlyZWQsXG4gICAgICAgIG9uT3JkZXJVcGRhdGVkOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgICAgICAgcmVtb3ZhYmxlOiBSZWFjdC5Qcm9wVHlwZXMuYm9vbCxcbiAgICAgICAgb25SZW1vdmU6IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgICAgICBjbGFzc05hbWU6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcsXG4gICAgICAgIGl0ZW1DbGFzc05hbWU6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmdcbiAgICB9LFxuXG4gICAgZ2V0SW5pdGlhbFN0YXRlOiBmdW5jdGlvbiBnZXRJbml0aWFsU3RhdGUoKSB7XG4gICAgICAgIHJldHVybiB7IHZhbHVlczogdGhpcy5wcm9wcy52YWx1ZXMgfTtcbiAgICB9LFxuICAgIGNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHM6IGZ1bmN0aW9uIGNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMocHJvcHMpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHZhbHVlczogcHJvcHMudmFsdWVzLCBzd2l0Y2hEYXRhOiBudWxsIH0pO1xuICAgIH0sXG5cbiAgICBmaW5kSXRlbUluZGV4OiBmdW5jdGlvbiBmaW5kSXRlbUluZGV4KGl0ZW1JZCwgZGF0YSkge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGRhdGEubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmIChkYXRhW2ldWydwYXlsb2FkJ10gPT0gaXRlbUlkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgc3dpdGNoSXRlbXM6IGZ1bmN0aW9uIHN3aXRjaEl0ZW1zKG9sZElkLCBuZXdJZCkge1xuICAgICAgICB2YXIgb2xkSW5kZXggPSB0aGlzLmZpbmRJdGVtSW5kZXgob2xkSWQsIHRoaXMuc3RhdGUudmFsdWVzKTtcbiAgICAgICAgdmFyIG9sZEl0ZW0gPSB0aGlzLnN0YXRlLnZhbHVlc1tvbGRJbmRleF07XG4gICAgICAgIHZhciBuZXdJbmRleCA9IHRoaXMuZmluZEl0ZW1JbmRleChuZXdJZCwgdGhpcy5zdGF0ZS52YWx1ZXMpO1xuICAgICAgICB2YXIgbmV3SXRlbSA9IHRoaXMuc3RhdGUudmFsdWVzW25ld0luZGV4XTtcblxuICAgICAgICB2YXIgY3VycmVudFZhbHVlcyA9IHRoaXMuc3RhdGUudmFsdWVzLnNsaWNlKCk7XG4gICAgICAgIGN1cnJlbnRWYWx1ZXNbb2xkSW5kZXhdID0gbmV3SXRlbTtcbiAgICAgICAgY3VycmVudFZhbHVlc1tuZXdJbmRleF0gPSBvbGRJdGVtO1xuXG4gICAgICAgIC8vIENoZWNrIHRoYXQgaXQgZGlkIG5vdCBjb21lIGJhY2sgdG8gb3JpZ2luYWwgc3RhdGVcbiAgICAgICAgdmFyIG9sZFByZXZpb3VzID0gdGhpcy5maW5kSXRlbUluZGV4KG9sZElkLCB0aGlzLnByb3BzLnZhbHVlcyk7XG4gICAgICAgIHZhciBuZXdQcmV2aW91cyA9IHRoaXMuZmluZEl0ZW1JbmRleChuZXdJZCwgdGhpcy5wcm9wcy52YWx1ZXMpO1xuICAgICAgICBpZiAob2xkUHJldmlvdXMgPT0gbmV3SW5kZXggJiYgbmV3UHJldmlvdXMgPT0gb2xkSW5kZXgpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyB2YWx1ZXM6IGN1cnJlbnRWYWx1ZXMsIHN3aXRjaERhdGE6IG51bGwgfSk7XG4gICAgICAgICAgICAvL2NvbnNvbGUubG9nKFwibm8gbW9yZSBtb3Zlc1wiKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgdmFsdWVzOiBjdXJyZW50VmFsdWVzLCBzd2l0Y2hEYXRhOiB7IG9sZElkOiBvbGRJZCwgbmV3SWQ6IG5ld0lkIH0gfSk7XG4gICAgICAgICAgICAgICAgLy9jb25zb2xlLmxvZyh7b2xkSWQ6b2xkSW5kZXgsIG5ld0lkOm5ld0luZGV4fSk7XG4gICAgICAgICAgICB9XG4gICAgfSxcblxuICAgIGVuZFN3aXRjaGluZzogZnVuY3Rpb24gZW5kU3dpdGNoaW5nKCkge1xuICAgICAgICBpZiAodGhpcy5zdGF0ZS5zd2l0Y2hEYXRhKSB7XG4gICAgICAgICAgICAvLyBDaGVjayB0aGF0IGl0IGRpZCBub3QgY29tZSBiYWNrIHRvIG9yaWdpbmFsIHN0YXRlXG4gICAgICAgICAgICBpZiAodGhpcy5wcm9wcy5vbk9yZGVyVXBkYXRlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMucHJvcHMub25PcmRlclVwZGF0ZWQodGhpcy5zdGF0ZS5zd2l0Y2hEYXRhLm9sZElkLCB0aGlzLnN0YXRlLnN3aXRjaERhdGEubmV3SWQsIHRoaXMuc3RhdGUudmFsdWVzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNldFN0YXRlKHsgc3dpdGNoRGF0YTogbnVsbCB9KTtcbiAgICB9LFxuXG4gICAgcmVuZGVyOiBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgICAgIHZhciBzd2l0Y2hJdGVtcyA9IHRoaXMuc3dpdGNoSXRlbXM7XG4gICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgXCJkaXZcIixcbiAgICAgICAgICAgIHsgY2xhc3NOYW1lOiB0aGlzLnByb3BzLmNsYXNzTmFtZSB9LFxuICAgICAgICAgICAgdGhpcy5zdGF0ZS52YWx1ZXMubWFwKChmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KERyYWdnYWJsZUxpc3RJdGVtLCB7XG4gICAgICAgICAgICAgICAgICAgIGlkOiBpdGVtLnBheWxvYWQsXG4gICAgICAgICAgICAgICAgICAgIGtleTogaXRlbS5wYXlsb2FkLFxuICAgICAgICAgICAgICAgICAgICBsYWJlbDogaXRlbS50ZXh0LFxuICAgICAgICAgICAgICAgICAgICBzd2l0Y2hJdGVtczogc3dpdGNoSXRlbXMsXG4gICAgICAgICAgICAgICAgICAgIGVuZFN3aXRjaGluZzogdGhpcy5lbmRTd2l0Y2hpbmcsXG4gICAgICAgICAgICAgICAgICAgIHJlbW92YWJsZTogdGhpcy5wcm9wcy5yZW1vdmFibGUsXG4gICAgICAgICAgICAgICAgICAgIG9uUmVtb3ZlOiB0aGlzLnByb3BzLm9uUmVtb3ZlLFxuICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU6IHRoaXMucHJvcHMuaXRlbUNsYXNzTmFtZVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSkuYmluZCh0aGlzKSlcbiAgICAgICAgKTtcbiAgICB9XG59KTtcblxuZXhwb3J0c1tcImRlZmF1bHRcIl0gPSBTb3J0YWJsZUxpc3Q7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbXCJkZWZhdWx0XCJdO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDA3LTIwMTcgQ2hhcmxlcyBkdSBKZXUgLSBBYnN0cml1bSBTQVMgPHRlYW0gKGF0KSBweWQuaW8+XG4gKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBQeWRpby5cbiAqXG4gKiBQeWRpbyBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFB5ZGlvIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIFB5ZGlvLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuICpcbiAqIFRoZSBsYXRlc3QgY29kZSBjYW4gYmUgZm91bmQgYXQgPGh0dHBzOi8vcHlkaW8uY29tPi5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfZXh0ZW5kcyA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gKHRhcmdldCkgeyBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgeyB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldOyBmb3IgKHZhciBrZXkgaW4gc291cmNlKSB7IGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoc291cmNlLCBrZXkpKSB7IHRhcmdldFtrZXldID0gc291cmNlW2tleV07IH0gfSB9IHJldHVybiB0YXJnZXQ7IH07XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7ICdkZWZhdWx0Jzogb2JqIH07IH1cblxudmFyIF9MaXN0RW50cnlOb2RlTGlzdGVuZXJNaXhpbiA9IHJlcXVpcmUoJy4vTGlzdEVudHJ5Tm9kZUxpc3RlbmVyTWl4aW4nKTtcblxudmFyIF9MaXN0RW50cnlOb2RlTGlzdGVuZXJNaXhpbjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9MaXN0RW50cnlOb2RlTGlzdGVuZXJNaXhpbik7XG5cbnZhciBfTGlzdEVudHJ5ID0gcmVxdWlyZSgnLi9MaXN0RW50cnknKTtcblxudmFyIF9JbmxpbmVFZGl0b3IgPSByZXF1aXJlKCcuL0lubGluZUVkaXRvcicpO1xuXG52YXIgX0lubGluZUVkaXRvcjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9JbmxpbmVFZGl0b3IpO1xuXG4vKipcbiAqIFNwZWNpZmljIGxpc3QgZW50cnkgcmVuZGVyZWQgYXMgYSB0YWJsZSByb3cuIE5vdCBhIHJlYWwgdGFibGUsIENTUyB1c2VkLlxuICovXG5leHBvcnRzWydkZWZhdWx0J10gPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG4gICAgZGlzcGxheU5hbWU6ICdUYWJsZUxpc3RFbnRyeScsXG5cbiAgICBtaXhpbnM6IFtfTGlzdEVudHJ5Tm9kZUxpc3RlbmVyTWl4aW4yWydkZWZhdWx0J11dLFxuXG4gICAgcHJvcFR5cGVzOiB7XG4gICAgICAgIG5vZGU6IFJlYWN0LlByb3BUeXBlcy5pbnN0YW5jZU9mKEFqeHBOb2RlKSxcbiAgICAgICAgdGFibGVLZXlzOiBSZWFjdC5Qcm9wVHlwZXMub2JqZWN0LmlzUmVxdWlyZWQsXG4gICAgICAgIHJlbmRlckFjdGlvbnM6IFJlYWN0LlByb3BUeXBlcy5mdW5jXG4gICAgICAgIC8vIFNlZSBhbHNvIExpc3RFbnRyeSBub2Rlc1xuICAgIH0sXG5cbiAgICByZW5kZXI6IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgICAgICB2YXIgYWN0aW9ucyA9IHRoaXMucHJvcHMuYWN0aW9ucztcbiAgICAgICAgaWYgKHRoaXMucHJvcHMucmVuZGVyQWN0aW9ucykge1xuICAgICAgICAgICAgYWN0aW9ucyA9IHRoaXMucHJvcHMucmVuZGVyQWN0aW9ucyh0aGlzLnByb3BzLm5vZGUpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGNlbGxzID0gW107XG4gICAgICAgIHZhciBmaXJzdEtleSA9IHRydWU7XG4gICAgICAgIHZhciBtZXRhID0gdGhpcy5wcm9wcy5ub2RlLmdldE1ldGFkYXRhKCk7XG4gICAgICAgIGZvciAodmFyIGtleSBpbiB0aGlzLnByb3BzLnRhYmxlS2V5cykge1xuICAgICAgICAgICAgaWYgKCF0aGlzLnByb3BzLnRhYmxlS2V5cy5oYXNPd25Qcm9wZXJ0eShrZXkpKSBjb250aW51ZTtcblxuICAgICAgICAgICAgdmFyIGRhdGEgPSB0aGlzLnByb3BzLnRhYmxlS2V5c1trZXldO1xuICAgICAgICAgICAgdmFyIHN0eWxlID0gZGF0YVsnd2lkdGgnXSA/IHsgd2lkdGg6IGRhdGFbJ3dpZHRoJ10gfSA6IG51bGw7XG4gICAgICAgICAgICB2YXIgdmFsdWUgPSB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgcmF3VmFsdWUgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICBpZiAoZGF0YS5yZW5kZXJDZWxsKSB7XG4gICAgICAgICAgICAgICAgZGF0YVsnbmFtZSddID0ga2V5O1xuICAgICAgICAgICAgICAgIHZhbHVlID0gZGF0YS5yZW5kZXJDZWxsKHRoaXMucHJvcHMubm9kZSwgZGF0YSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGtleSA9PT0gJ2FqeHBfbW9kaWZ0aW1lJyAmJiBtZXRhLmdldCgnYWp4cF9yZWxhdGl2ZXRpbWUnKSkge1xuICAgICAgICAgICAgICAgIHZhbHVlID0gbWV0YS5nZXQoJ2FqeHBfcmVsYXRpdmV0aW1lJyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHZhbHVlID0gbWV0YS5nZXQoa2V5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJhd1ZhbHVlID0gbWV0YS5nZXQoa2V5KTtcbiAgICAgICAgICAgIHZhciBpbmxpbmVFZGl0b3IgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICBpZiAodGhpcy5zdGF0ZSAmJiB0aGlzLnN0YXRlLmlubGluZUVkaXRpb24gJiYgZmlyc3RLZXkpIHtcbiAgICAgICAgICAgICAgICBpbmxpbmVFZGl0b3IgPSBSZWFjdC5jcmVhdGVFbGVtZW50KF9JbmxpbmVFZGl0b3IyWydkZWZhdWx0J10sIHtcbiAgICAgICAgICAgICAgICAgICAgbm9kZTogdGhpcy5wcm9wcy5ub2RlLFxuICAgICAgICAgICAgICAgICAgICBvbkNsb3NlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBfdGhpcy5zZXRTdGF0ZSh7IGlubGluZUVkaXRpb246IGZhbHNlIH0pO1xuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBjYWxsYmFjazogdGhpcy5zdGF0ZS5pbmxpbmVFZGl0aW9uQ2FsbGJhY2tcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB2YXIgX3N0eWxlID0gdGhpcy5wcm9wcy5zdHlsZSB8fCB7fTtcbiAgICAgICAgICAgICAgICBfc3R5bGUucG9zaXRpb24gPSAncmVsYXRpdmUnO1xuICAgICAgICAgICAgICAgIHRoaXMucHJvcHMuc3R5bGUgPSBfc3R5bGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjZWxscy5wdXNoKFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgJ3NwYW4nLFxuICAgICAgICAgICAgICAgIHsga2V5OiBrZXksIGNsYXNzTmFtZTogJ2NlbGwgY2VsbC0nICsga2V5LCB0aXRsZTogcmF3VmFsdWUsIHN0eWxlOiBzdHlsZSwgJ2RhdGEtbGFiZWwnOiBkYXRhWydsYWJlbCddIH0sXG4gICAgICAgICAgICAgICAgaW5saW5lRWRpdG9yLFxuICAgICAgICAgICAgICAgIHZhbHVlXG4gICAgICAgICAgICApKTtcbiAgICAgICAgICAgIGZpcnN0S2V5ID0gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChfTGlzdEVudHJ5LkRyYWdEcm9wTGlzdEVudHJ5LCBfZXh0ZW5kcyh7fSwgdGhpcy5wcm9wcywge1xuICAgICAgICAgICAgaWNvbkNlbGw6IG51bGwsXG4gICAgICAgICAgICBmaXJzdExpbmU6IGNlbGxzLFxuICAgICAgICAgICAgYWN0aW9uczogYWN0aW9uc1xuICAgICAgICB9KSk7XG4gICAgfVxuXG59KTtcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDA3LTIwMTcgQ2hhcmxlcyBkdSBKZXUgLSBBYnN0cml1bSBTQVMgPHRlYW0gKGF0KSBweWQuaW8+XG4gKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBQeWRpby5cbiAqXG4gKiBQeWRpbyBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFB5ZGlvIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIFB5ZGlvLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuICpcbiAqIFRoZSBsYXRlc3QgY29kZSBjYW4gYmUgZm91bmQgYXQgPGh0dHBzOi8vcHlkaW8uY29tPi5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfZXh0ZW5kcyA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gKHRhcmdldCkgeyBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgeyB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldOyBmb3IgKHZhciBrZXkgaW4gc291cmNlKSB7IGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoc291cmNlLCBrZXkpKSB7IHRhcmdldFtrZXldID0gc291cmNlW2tleV07IH0gfSB9IHJldHVybiB0YXJnZXQ7IH07XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7ICdkZWZhdWx0Jzogb2JqIH07IH1cblxudmFyIF91dGlsTWVzc2FnZXNDb25zdW1lck1peGluID0gcmVxdWlyZSgnLi4vdXRpbC9NZXNzYWdlc0NvbnN1bWVyTWl4aW4nKTtcblxudmFyIF91dGlsTWVzc2FnZXNDb25zdW1lck1peGluMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3V0aWxNZXNzYWdlc0NvbnN1bWVyTWl4aW4pO1xuXG52YXIgX1NvcnRDb2x1bW5zID0gcmVxdWlyZSgnLi9Tb3J0Q29sdW1ucycpO1xuXG52YXIgX1NvcnRDb2x1bW5zMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1NvcnRDb2x1bW5zKTtcblxudmFyIF9MaXN0UGFnaW5hdG9yID0gcmVxdWlyZSgnLi9MaXN0UGFnaW5hdG9yJyk7XG5cbnZhciBfTGlzdFBhZ2luYXRvcjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9MaXN0UGFnaW5hdG9yKTtcblxuLyoqXG4gKiBTcGVjaWZpYyBoZWFkZXIgZm9yIFRhYmxlIGxheW91dCwgcmVhZGluZyBtZXRhZGF0YSBmcm9tIG5vZGUgYW5kIHVzaW5nIGtleXNcbiAqL1xuZXhwb3J0c1snZGVmYXVsdCddID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuICAgIGRpc3BsYXlOYW1lOiAnVGFibGVMaXN0SGVhZGVyJyxcblxuICAgIG1peGluczogW191dGlsTWVzc2FnZXNDb25zdW1lck1peGluMlsnZGVmYXVsdCddXSxcblxuICAgIHByb3BUeXBlczoge1xuICAgICAgICB0YWJsZUtleXM6IFJlYWN0LlByb3BUeXBlcy5vYmplY3QuaXNSZXF1aXJlZCxcbiAgICAgICAgbG9hZGluZzogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXG4gICAgICAgIHJlbG9hZDogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsXG4gICAgICAgIGRtOiBSZWFjdC5Qcm9wVHlwZXMuaW5zdGFuY2VPZihQeWRpb0RhdGFNb2RlbCksXG4gICAgICAgIG5vZGU6IFJlYWN0LlByb3BUeXBlcy5pbnN0YW5jZU9mKEFqeHBOb2RlKSxcbiAgICAgICAgb25IZWFkZXJDbGljazogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsXG4gICAgICAgIHNvcnRpbmdJbmZvOiBSZWFjdC5Qcm9wVHlwZXMub2JqZWN0XG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgICB2YXIgaGVhZGVycyA9IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIHBhZ2luYXRvciA9IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMubm9kZS5nZXRNZXRhZGF0YSgpLmdldChcInBhZ2luYXRpb25EYXRhXCIpICYmIHRoaXMucHJvcHMubm9kZS5nZXRNZXRhZGF0YSgpLmdldChcInBhZ2luYXRpb25EYXRhXCIpLmdldCgndG90YWwnKSA+IDEpIHtcbiAgICAgICAgICAgIHBhZ2luYXRvciA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoX0xpc3RQYWdpbmF0b3IyWydkZWZhdWx0J10sIHsgZGF0YU1vZGVsOiB0aGlzLnByb3BzLmRtLCBub2RlOiB0aGlzLnByb3BzLm5vZGUgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICBSZWFjdE1VSS5Ub29sYmFyLFxuICAgICAgICAgICAgeyBjbGFzc05hbWU6ICd0b29sYmFyVGFibGVIZWFkZXInIH0sXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KF9Tb3J0Q29sdW1uczJbJ2RlZmF1bHQnXSwgX2V4dGVuZHMoeyBkaXNwbGF5TW9kZTogJ3RhYmxlSGVhZGVyJyB9LCB0aGlzLnByb3BzLCB7IGNvbHVtbkNsaWNrZWQ6IHRoaXMucHJvcHMub25IZWFkZXJDbGljayB9KSksXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgIFJlYWN0TVVJLlRvb2xiYXJHcm91cCxcbiAgICAgICAgICAgICAgICB7IGZsb2F0OiAncmlnaHQnIH0sXG4gICAgICAgICAgICAgICAgcGFnaW5hdG9yLFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoUmVhY3RNVUkuRm9udEljb24sIHtcbiAgICAgICAgICAgICAgICAgICAga2V5OiAxLFxuICAgICAgICAgICAgICAgICAgICB0b29sdGlwOiB0aGlzLmNvbnRleHQuZ2V0TWVzc2FnZSgnMTQ5JywgJycpLFxuICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU6IFwiaWNvbi1yZWZyZXNoXCIgKyAodGhpcy5wcm9wcy5sb2FkaW5nID8gXCIgcm90YXRpbmdcIiA6IFwiXCIpLFxuICAgICAgICAgICAgICAgICAgICBvbkNsaWNrOiB0aGlzLnByb3BzLnJlbG9hZFxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgIHRoaXMucHJvcHMuYWRkaXRpb25hbEFjdGlvbnNcbiAgICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICB9XG59KTtcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDA3LTIwMTcgQ2hhcmxlcyBkdSBKZXUgLSBBYnN0cml1bSBTQVMgPHRlYW0gKGF0KSBweWQuaW8+XG4gKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBQeWRpby5cbiAqXG4gKiBQeWRpbyBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFB5ZGlvIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIFB5ZGlvLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuICpcbiAqIFRoZSBsYXRlc3QgY29kZSBjYW4gYmUgZm91bmQgYXQgPGh0dHBzOi8vcHlkaW8uY29tPi5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfZXh0ZW5kcyA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gKHRhcmdldCkgeyBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgeyB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldOyBmb3IgKHZhciBrZXkgaW4gc291cmNlKSB7IGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoc291cmNlLCBrZXkpKSB7IHRhcmdldFtrZXldID0gc291cmNlW2tleV07IH0gfSB9IHJldHVybiB0YXJnZXQ7IH07XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7ICdkZWZhdWx0Jzogb2JqIH07IH1cblxudmFyIF9VdGlscyA9IHJlcXVpcmUoJy4vVXRpbHMnKTtcblxudmFyIF9VdGlsczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9VdGlscyk7XG5cbnZhciBfTWVudUl0ZW1zQ29uc3VtZXIgPSByZXF1aXJlKCcuL01lbnVJdGVtc0NvbnN1bWVyJyk7XG5cbnZhciBfTWVudUl0ZW1zQ29uc3VtZXIyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfTWVudUl0ZW1zQ29uc3VtZXIpO1xuXG52YXIgUmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpO1xudmFyIFJlYWN0RE9NID0gcmVxdWlyZSgncmVhY3QtZG9tJyk7XG5cbnZhciBfcmVxdWlyZSA9IHJlcXVpcmUoJ21hdGVyaWFsLXVpJyk7XG5cbnZhciBNZW51ID0gX3JlcXVpcmUuTWVudTtcblxudmFyIENvbnRyb2xsZXIgPSByZXF1aXJlKCdweWRpby9tb2RlbC9jb250cm9sbGVyJyk7XG5cbnZhciBCdXR0b25NZW51ID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuICAgIGRpc3BsYXlOYW1lOiAnQnV0dG9uTWVudScsXG5cbiAgICBwcm9wVHlwZXM6IHtcbiAgICAgICAgYnV0dG9uVGl0bGU6IFJlYWN0LlByb3BUeXBlcy5vbmVPZlR5cGUoW1JlYWN0LlByb3BUeXBlcy5zdHJpbmcsIFJlYWN0LlByb3BUeXBlcy5vYmplY3RdKS5pc1JlcXVpcmVkLFxuICAgICAgICBtZW51SXRlbXM6IFJlYWN0LlByb3BUeXBlcy5hcnJheS5pc1JlcXVpcmVkLFxuICAgICAgICBjbGFzc05hbWU6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcsXG4gICAgICAgIHJhaXNlZDogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXG4gICAgICAgIGRpcmVjdGlvbjogUmVhY3QuUHJvcFR5cGVzLm9uZU9mKFsnbGVmdCcsICdyaWdodCddKVxuICAgIH0sXG5cbiAgICBjb21wb25lbnREaWRNb3VudDogZnVuY3Rpb24gY29tcG9uZW50RGlkTW91bnQoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICAgICAgaWYgKHRoaXMucHJvcHMub3Blbk9uRXZlbnQpIHtcbiAgICAgICAgICAgIHRoaXMucHJvcHMucHlkaW8ub2JzZXJ2ZSh0aGlzLnByb3BzLm9wZW5PbkV2ZW50LCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgX3RoaXMuc2hvd01lbnUoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIGdldEluaXRpYWxTdGF0ZTogZnVuY3Rpb24gZ2V0SW5pdGlhbFN0YXRlKCkge1xuICAgICAgICByZXR1cm4geyBzaG93TWVudTogZmFsc2UgfTtcbiAgICB9LFxuXG4gICAgc2hvd01lbnU6IGZ1bmN0aW9uIHNob3dNZW51KGV2ZW50KSB7XG4gICAgICAgIHZhciBhbmNob3IgPSB1bmRlZmluZWQ7XG4gICAgICAgIGlmIChldmVudCkge1xuICAgICAgICAgICAgYW5jaG9yID0gZXZlbnQuY3VycmVudFRhcmdldDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGFuY2hvciA9IHRoaXMuX2J1dHRvbkRPTTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIHNob3dNZW51OiB0cnVlLFxuICAgICAgICAgICAgYW5jaG9yOiBhbmNob3JcbiAgICAgICAgfSk7XG4gICAgfSxcblxuICAgIG1lbnVDbGlja2VkOiBmdW5jdGlvbiBtZW51Q2xpY2tlZChldmVudCwgaW5kZXgsIG9iamVjdCkge1xuICAgICAgICAvL29iamVjdC5wYXlsb2FkKCk7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBzaG93TWVudTogZmFsc2UgfSk7XG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgICB2YXIgX3RoaXMyID0gdGhpcztcblxuICAgICAgICB2YXIgbGFiZWwgPSBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgJ3NwYW4nLFxuICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgIHRoaXMucHJvcHMuYnV0dG9uVGl0bGUsXG4gICAgICAgICAgICAnICcsXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KCdzcGFuJywgeyBjbGFzc05hbWU6ICdpY29uLWNhcmV0LWRvd24nIH0pXG4gICAgICAgICk7XG4gICAgICAgIHZhciBidXR0b24gPSB1bmRlZmluZWQ7XG4gICAgICAgIHZhciBwcm9wcyA9IHtcbiAgICAgICAgICAgIHByaW1hcnk6IHRoaXMucHJvcHMucHJpbWFyeSxcbiAgICAgICAgICAgIHNlY29uZGFyeTogdGhpcy5wcm9wcy5zZWNvbmRhcnksXG4gICAgICAgICAgICBkaXNhYmxlZDogdGhpcy5wcm9wcy5kaXNhYmVsZCxcbiAgICAgICAgICAgIGxhYmVsOiBsYWJlbCxcbiAgICAgICAgICAgIG9uVG91Y2hUYXA6IHRoaXMuc2hvd01lbnUsXG4gICAgICAgICAgICBvbkNsaWNrOiBmdW5jdGlvbiBvbkNsaWNrKGUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgdmFyIG1lbnVJdGVtcyA9IHRoaXMucHJvcHMubWVudUl0ZW1zO1xuICAgICAgICB2YXIgX3N0YXRlID0gdGhpcy5zdGF0ZTtcbiAgICAgICAgdmFyIHNob3dNZW51ID0gX3N0YXRlLnNob3dNZW51O1xuICAgICAgICB2YXIgYW5jaG9yID0gX3N0YXRlLmFuY2hvcjtcblxuICAgICAgICBpZiAobWVudUl0ZW1zLmxlbmd0aCkge1xuICAgICAgICAgICAgaWYgKHRoaXMucHJvcHMucmFpc2VkKSB7XG4gICAgICAgICAgICAgICAgYnV0dG9uID0gUmVhY3QuY3JlYXRlRWxlbWVudChNYXRlcmlhbFVJLlJhaXNlZEJ1dHRvbiwgX2V4dGVuZHMoe30sIHByb3BzLCB7IHN0eWxlOiB0aGlzLnByb3BzLmJ1dHRvblN0eWxlLCBsYWJlbFN0eWxlOiB0aGlzLnByb3BzLmJ1dHRvbkxhYmVsU3R5bGUsIHJlZjogZnVuY3Rpb24gKGIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzMi5fYnV0dG9uRE9NID0gUmVhY3RET00uZmluZERPTU5vZGUoYik7XG4gICAgICAgICAgICAgICAgICAgIH0gfSkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBidXR0b24gPSBSZWFjdC5jcmVhdGVFbGVtZW50KE1hdGVyaWFsVUkuRmxhdEJ1dHRvbiwgX2V4dGVuZHMoe30sIHByb3BzLCB7IHN0eWxlOiB0aGlzLnByb3BzLmJ1dHRvblN0eWxlLCBsYWJlbFN0eWxlOiB0aGlzLnByb3BzLmJ1dHRvbkxhYmVsU3R5bGUsIHJlZjogZnVuY3Rpb24gKGIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzMi5fYnV0dG9uRE9NID0gUmVhY3RET00uZmluZERPTU5vZGUoYik7XG4gICAgICAgICAgICAgICAgICAgIH0gfSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgJ3NwYW4nLFxuICAgICAgICAgICAgeyBpZDogdGhpcy5wcm9wcy5pZCwgY2xhc3NOYW1lOiB0aGlzLnByb3BzLmNsYXNzTmFtZSB9LFxuICAgICAgICAgICAgYnV0dG9uLFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICBNYXRlcmlhbFVJLlBvcG92ZXIsXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU6ICdtZW51UG9wb3ZlcicsXG4gICAgICAgICAgICAgICAgICAgIG9wZW46IHNob3dNZW51LFxuICAgICAgICAgICAgICAgICAgICBhbmNob3JFbDogYW5jaG9yLFxuICAgICAgICAgICAgICAgICAgICBhbmNob3JPcmlnaW46IHsgaG9yaXpvbnRhbDogdGhpcy5wcm9wcy5kaXJlY3Rpb24gfHwgJ2xlZnQnLCB2ZXJ0aWNhbDogJ2JvdHRvbScgfSxcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0T3JpZ2luOiB7IGhvcml6b250YWw6IHRoaXMucHJvcHMuZGlyZWN0aW9uIHx8ICdsZWZ0JywgdmVydGljYWw6ICd0b3AnIH0sXG4gICAgICAgICAgICAgICAgICAgIG9uUmVxdWVzdENsb3NlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBfdGhpczIuc2V0U3RhdGUoeyBzaG93TWVudTogZmFsc2UgfSk7XG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHN0eWxlOiB7IG1hcmdpblRvcDogMSB9LFxuICAgICAgICAgICAgICAgICAgICB1c2VMYXllckZvckNsaWNrQXdheTogZmFsc2VcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIF9VdGlsczJbJ2RlZmF1bHQnXS5pdGVtc1RvTWVudShtZW51SXRlbXMsIHRoaXMubWVudUNsaWNrZWQpXG4gICAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgfVxuXG59KTtcblxuZXhwb3J0c1snZGVmYXVsdCddID0gX01lbnVJdGVtc0NvbnN1bWVyMlsnZGVmYXVsdCddKEJ1dHRvbk1lbnUpO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMDctMjAxNyBDaGFybGVzIGR1IEpldSAtIEFic3RyaXVtIFNBUyA8dGVhbSAoYXQpIHB5ZC5pbz5cbiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIFB5ZGlvLlxuICpcbiAqIFB5ZGlvIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3JcbiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogUHlkaW8gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggUHlkaW8uICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gKlxuICogVGhlIGxhdGVzdCBjb2RlIGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9weWRpby5jb20+LlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgJ2RlZmF1bHQnOiBvYmogfTsgfVxuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbicpOyB9IH1cblxuZnVuY3Rpb24gX2luaGVyaXRzKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7IGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gJ2Z1bmN0aW9uJyAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ1N1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uLCBub3QgJyArIHR5cGVvZiBzdXBlckNsYXNzKTsgfSBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHsgY29uc3RydWN0b3I6IHsgdmFsdWU6IHN1YkNsYXNzLCBlbnVtZXJhYmxlOiBmYWxzZSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IH0pOyBpZiAoc3VwZXJDbGFzcykgT2JqZWN0LnNldFByb3RvdHlwZU9mID8gT2JqZWN0LnNldFByb3RvdHlwZU9mKHN1YkNsYXNzLCBzdXBlckNsYXNzKSA6IHN1YkNsYXNzLl9fcHJvdG9fXyA9IHN1cGVyQ2xhc3M7IH1cblxudmFyIF9weWRpb01vZGVsQ29udGV4dE1lbnUgPSByZXF1aXJlKCdweWRpby9tb2RlbC9jb250ZXh0LW1lbnUnKTtcblxudmFyIF9weWRpb01vZGVsQ29udGV4dE1lbnUyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfcHlkaW9Nb2RlbENvbnRleHRNZW51KTtcblxudmFyIF9VdGlscyA9IHJlcXVpcmUoJy4vVXRpbHMnKTtcblxudmFyIF9VdGlsczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9VdGlscyk7XG5cbnZhciBfUG9wdXBNZW51ID0gcmVxdWlyZSgnLi9Qb3B1cE1lbnUnKTtcblxudmFyIF9Qb3B1cE1lbnUyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfUG9wdXBNZW51KTtcblxudmFyIF9yZXF1aXJlID0gcmVxdWlyZSgncmVhY3QnKTtcblxudmFyIENvbXBvbmVudCA9IF9yZXF1aXJlLkNvbXBvbmVudDtcblxudmFyIGRpbXMgPSB7XG4gICAgTUVOVV9JVEVNX0hFSUdIVDogMzIsIC8vNDggaWYgbm90IGRpc3BsYXk6Y29tcGFjdFxuICAgIE1FTlVfU0VQX0hFSUdIVDogMTYsXG4gICAgTUVOVV9WRVJUSUNBTF9QQURESU5HOiA4LFxuICAgIE1FTlVfV0lEVEg6IDI1MCxcbiAgICBPRkZTRVRfVkVSVElDQUw6IDgsXG4gICAgT0ZGU0VUX0hPUklaT05UQUw6IDhcbn07XG5cbnZhciBDb250ZXh0TWVudSA9IChmdW5jdGlvbiAoX0NvbXBvbmVudCkge1xuICAgIF9pbmhlcml0cyhDb250ZXh0TWVudSwgX0NvbXBvbmVudCk7XG5cbiAgICBmdW5jdGlvbiBDb250ZXh0TWVudSgpIHtcbiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIENvbnRleHRNZW51KTtcblxuICAgICAgICBfQ29tcG9uZW50LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfVxuXG4gICAgQ29udGV4dE1lbnUucHJvdG90eXBlLm1vZGVsT3BlbiA9IGZ1bmN0aW9uIG1vZGVsT3Blbihub2RlKSB7XG4gICAgICAgIHZhciBwb3NpdGlvbiA9IF9weWRpb01vZGVsQ29udGV4dE1lbnUyWydkZWZhdWx0J10uZ2V0SW5zdGFuY2UoKS5nZXRQb3NpdGlvbigpO1xuICAgICAgICB2YXIgaXRlbXMgPSB1bmRlZmluZWQ7XG4gICAgICAgIGlmIChub2RlKSB7XG4gICAgICAgICAgICB2YXIgZG0gPSBweWRpby5nZXRDb250ZXh0SG9sZGVyKCk7XG4gICAgICAgICAgICBpZiAoZG0uZ2V0U2VsZWN0ZWROb2RlcygpLmluZGV4T2Yobm9kZSkgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5vcGVuTWVudSgnc2VsZWN0aW9uQ29udGV4dCcsIHBvc2l0aW9uKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcHlkaW8ub2JzZXJ2ZU9uY2UoXCJhY3Rpb25zX3JlZnJlc2hlZFwiLCAoZnVuY3Rpb24gKGRhdGFNb2RlbCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm9wZW5NZW51KCdzZWxlY3Rpb25Db250ZXh0JywgcG9zaXRpb24pO1xuICAgICAgICAgICAgICAgIH0pLmJpbmQodGhpcykpO1xuICAgICAgICAgICAgICAgIGRtLnNldFNlbGVjdGVkTm9kZXMoW25vZGVdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMub3Blbk1lbnUoJ2dlbmVyaWNDb250ZXh0JywgcG9zaXRpb24pO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIENvbnRleHRNZW51LnByb3RvdHlwZS5vcGVuTWVudSA9IGZ1bmN0aW9uIG9wZW5NZW51KGNvbnRleHQsIHBvc2l0aW9uKSB7XG4gICAgICAgIHZhciBpdGVtcyA9IHRoaXMuY29tcHV0ZU1lbnVJdGVtcyhjb250ZXh0KTtcbiAgICAgICAgdGhpcy5faXRlbXMgPSBpdGVtcztcbiAgICAgICAgdmFyIG1vYmlsZSA9IHRoaXMucHJvcHMucHlkaW8uVUkuTU9CSUxFX0VYVEVOU0lPTlM7XG4gICAgICAgIGlmICghbW9iaWxlKSB7XG4gICAgICAgICAgICBwb3NpdGlvbiA9IHRoaXMuY29tcHV0ZVZpc2libGVQb3NpdGlvbihwb3NpdGlvbiwgaXRlbXMpO1xuICAgICAgICAgICAgdGhpcy5yZWZzWydtZW51J10uc2hvd01lbnUoe1xuICAgICAgICAgICAgICAgIHRvcDogcG9zaXRpb24ueSxcbiAgICAgICAgICAgICAgICBsZWZ0OiBwb3NpdGlvbi54XG4gICAgICAgICAgICB9LCBpdGVtcyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnJlZnNbJ21lbnUnXS5zaG93TWVudSh7XG4gICAgICAgICAgICAgICAgYm90dG9tOiAwLFxuICAgICAgICAgICAgICAgIGxlZnQ6IDAsXG4gICAgICAgICAgICAgICAgcmlnaHQ6IDAsXG4gICAgICAgICAgICAgICAgaGVpZ2h0OiAyMDAsXG4gICAgICAgICAgICAgICAgekluZGV4OiAxMDAwMCxcbiAgICAgICAgICAgICAgICBvdmVyZmxvd1k6ICdhdXRvJ1xuICAgICAgICAgICAgfSwgaXRlbXMpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIENvbnRleHRNZW51LnByb3RvdHlwZS5jb21wdXRlTWVudUl0ZW1zID0gZnVuY3Rpb24gY29tcHV0ZU1lbnVJdGVtcyhjb250ZXh0KSB7XG4gICAgICAgIHZhciBhY3Rpb25zID0gdGhpcy5wcm9wcy5weWRpby5Db250cm9sbGVyLmdldENvbnRleHRBY3Rpb25zKGNvbnRleHQsIFsnaW5saW5lJywgJ2luZm9fcGFuZWwnLCAnaW5mb19wYW5lbF9zaGFyZSddKTtcbiAgICAgICAgcmV0dXJuIF9VdGlsczJbJ2RlZmF1bHQnXS5weWRpb0FjdGlvbnNUb0l0ZW1zKGFjdGlvbnMpO1xuICAgIH07XG5cbiAgICBDb250ZXh0TWVudS5wcm90b3R5cGUuY29tcHV0ZVZpc2libGVQb3NpdGlvbiA9IGZ1bmN0aW9uIGNvbXB1dGVWaXNpYmxlUG9zaXRpb24ocG9zaXRpb24sIGl0ZW1zKSB7XG4gICAgICAgIHZhciBtZW51SGVpZ2h0ID0gZGltcy5NRU5VX1ZFUlRJQ0FMX1BBRERJTkcgKiAyO1xuICAgICAgICBpdGVtcy5tYXAoZnVuY3Rpb24gKGl0KSB7XG4gICAgICAgICAgICBpZiAoaXQuc2VwYXJhdG9yKSBtZW51SGVpZ2h0ICs9IGRpbXMuTUVOVV9TRVBfSEVJR0hUO2Vsc2UgbWVudUhlaWdodCArPSBkaW1zLk1FTlVfSVRFTV9IRUlHSFQ7XG4gICAgICAgIH0pO1xuICAgICAgICB2YXIgbWVudVdpZHRoID0gZGltcy5NRU5VX1dJRFRIO1xuICAgICAgICB2YXIgd2luZG93VyA9IE1hdGgubWF4KGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRXaWR0aCwgd2luZG93LmlubmVyV2lkdGggfHwgMCk7XG4gICAgICAgIHZhciB3aW5kb3dIID0gTWF0aC5tYXgoZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudEhlaWdodCwgd2luZG93LmlubmVySGVpZ2h0IHx8IDApO1xuICAgICAgICBpZiAocG9zaXRpb24ueCArIG1lbnVXaWR0aCA+IHdpbmRvd1cpIHtcbiAgICAgICAgICAgIHBvc2l0aW9uLnggPSBNYXRoLm1heChwb3NpdGlvbi54IC0gbWVudVdpZHRoLCAxMCkgLSBkaW1zLk9GRlNFVF9IT1JJWk9OVEFMO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcG9zaXRpb24ueCArPSBkaW1zLk9GRlNFVF9IT1JJWk9OVEFMO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwb3NpdGlvbi55ICsgbWVudUhlaWdodCA+IHdpbmRvd0gpIHtcbiAgICAgICAgICAgIHBvc2l0aW9uLnkgPSBNYXRoLm1heChwb3NpdGlvbi55IC0gbWVudUhlaWdodCwgMTApIC0gZGltcy5PRkZTRVRfVkVSVElDQUw7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwb3NpdGlvbi55ICs9IGRpbXMuT0ZGU0VUX1ZFUlRJQ0FMO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBwb3NpdGlvbjtcbiAgICB9O1xuXG4gICAgQ29udGV4dE1lbnUucHJvdG90eXBlLmNvbXBvbmVudERpZE1vdW50ID0gZnVuY3Rpb24gY29tcG9uZW50RGlkTW91bnQoKSB7XG4gICAgICAgIHRoaXMuX21vZGVsT3BlbiA9IHRoaXMubW9kZWxPcGVuLmJpbmQodGhpcyk7XG4gICAgICAgIF9weWRpb01vZGVsQ29udGV4dE1lbnUyWydkZWZhdWx0J10uZ2V0SW5zdGFuY2UoKS5vYnNlcnZlKFwib3BlblwiLCB0aGlzLl9tb2RlbE9wZW4pO1xuICAgIH07XG5cbiAgICBDb250ZXh0TWVudS5wcm90b3R5cGUuY29tcG9uZW50V2lsbFVubW91bnQgPSBmdW5jdGlvbiBjb21wb25lbnRXaWxsVW5tb3VudCgpIHtcbiAgICAgICAgX3B5ZGlvTW9kZWxDb250ZXh0TWVudTJbJ2RlZmF1bHQnXS5nZXRJbnN0YW5jZSgpLnN0b3BPYnNlcnZpbmcoXCJvcGVuXCIsIHRoaXMuX21vZGVsT3Blbik7XG4gICAgfTtcblxuICAgIENvbnRleHRNZW51LnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgICAgIHZhciBtb2JpbGUgPSB0aGlzLnByb3BzLnB5ZGlvLlVJLk1PQklMRV9FWFRFTlNJT05TO1xuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChfUG9wdXBNZW51MlsnZGVmYXVsdCddLCB7XG4gICAgICAgICAgICByZWY6ICdtZW51JyxcbiAgICAgICAgICAgIG1lbnVJdGVtczogdGhpcy5faXRlbXMgfHwgW10sXG4gICAgICAgICAgICBvbk1lbnVDbG9zZWQ6IHRoaXMucHJvcHMub25NZW51Q2xvc2VkLFxuICAgICAgICAgICAgbWVudVByb3BzOiBtb2JpbGUgPyB7IHdpZHRoOiA2MDAsIGF1dG9XaWR0aDogZmFsc2UsIGRlc2t0b3A6IGZhbHNlIH0gOiB7fSxcbiAgICAgICAgICAgIHpEZXB0aDogbW9iaWxlID8gMiA6IDFcbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIHJldHVybiBDb250ZXh0TWVudTtcbn0pKENvbXBvbmVudCk7XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IENvbnRleHRNZW51O1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMDctMjAxNyBDaGFybGVzIGR1IEpldSAtIEFic3RyaXVtIFNBUyA8dGVhbSAoYXQpIHB5ZC5pbz5cbiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIFB5ZGlvLlxuICpcbiAqIFB5ZGlvIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3JcbiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogUHlkaW8gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggUHlkaW8uICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gKlxuICogVGhlIGxhdGVzdCBjb2RlIGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9weWRpby5jb20+LlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgJ2RlZmF1bHQnOiBvYmogfTsgfVxuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbicpOyB9IH1cblxuZnVuY3Rpb24gX2luaGVyaXRzKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7IGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gJ2Z1bmN0aW9uJyAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ1N1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uLCBub3QgJyArIHR5cGVvZiBzdXBlckNsYXNzKTsgfSBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHsgY29uc3RydWN0b3I6IHsgdmFsdWU6IHN1YkNsYXNzLCBlbnVtZXJhYmxlOiBmYWxzZSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IH0pOyBpZiAoc3VwZXJDbGFzcykgT2JqZWN0LnNldFByb3RvdHlwZU9mID8gT2JqZWN0LnNldFByb3RvdHlwZU9mKHN1YkNsYXNzLCBzdXBlckNsYXNzKSA6IHN1YkNsYXNzLl9fcHJvdG9fXyA9IHN1cGVyQ2xhc3M7IH1cblxudmFyIF9VdGlscyA9IHJlcXVpcmUoJy4vVXRpbHMnKTtcblxudmFyIF9VdGlsczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9VdGlscyk7XG5cbnZhciBfTWVudUl0ZW1zQ29uc3VtZXIgPSByZXF1aXJlKCcuL01lbnVJdGVtc0NvbnN1bWVyJyk7XG5cbnZhciBfTWVudUl0ZW1zQ29uc3VtZXIyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfTWVudUl0ZW1zQ29uc3VtZXIpO1xuXG52YXIgUmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpO1xuXG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKCdtYXRlcmlhbC11aScpO1xuXG52YXIgSWNvbkJ1dHRvbiA9IF9yZXF1aXJlLkljb25CdXR0b247XG52YXIgUG9wb3ZlciA9IF9yZXF1aXJlLlBvcG92ZXI7XG5cbnZhciBJY29uQnV0dG9uTWVudSA9IChmdW5jdGlvbiAoX1JlYWN0JENvbXBvbmVudCkge1xuICAgIF9pbmhlcml0cyhJY29uQnV0dG9uTWVudSwgX1JlYWN0JENvbXBvbmVudCk7XG5cbiAgICBmdW5jdGlvbiBJY29uQnV0dG9uTWVudShwcm9wcywgY29udGV4dCkge1xuICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgSWNvbkJ1dHRvbk1lbnUpO1xuXG4gICAgICAgIF9SZWFjdCRDb21wb25lbnQuY2FsbCh0aGlzLCBwcm9wcywgY29udGV4dCk7XG4gICAgICAgIHRoaXMuc3RhdGUgPSB7IHNob3dNZW51OiBmYWxzZSB9O1xuICAgIH1cblxuICAgIEljb25CdXR0b25NZW51LnByb3RvdHlwZS5zaG93TWVudSA9IGZ1bmN0aW9uIHNob3dNZW51KGV2ZW50KSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgc2hvd01lbnU6IHRydWUsXG4gICAgICAgICAgICBhbmNob3I6IGV2ZW50LmN1cnJlbnRUYXJnZXRcbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIEljb25CdXR0b25NZW51LnByb3RvdHlwZS5jbG9zZU1lbnUgPSBmdW5jdGlvbiBjbG9zZU1lbnUoZXZlbnQsIGluZGV4LCBtZW51SXRlbSkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgc2hvd01lbnU6IGZhbHNlIH0pO1xuICAgIH07XG5cbiAgICBJY29uQnV0dG9uTWVudS5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgJ3NwYW4nLFxuICAgICAgICAgICAgeyBjbGFzc05hbWU6IFwidG9vbGJhcnMtYnV0dG9uLW1lbnUgXCIgKyAodGhpcy5wcm9wcy5jbGFzc05hbWUgPyB0aGlzLnByb3BzLmNsYXNzTmFtZSA6ICcnKSB9LFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChJY29uQnV0dG9uLCB7XG4gICAgICAgICAgICAgICAgcmVmOiAnbWVudUJ1dHRvbicsXG4gICAgICAgICAgICAgICAgdG9vbHRpcDogdGhpcy5wcm9wcy5idXR0b25UaXRsZSxcbiAgICAgICAgICAgICAgICBpY29uQ2xhc3NOYW1lOiB0aGlzLnByb3BzLmJ1dHRvbkNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgICBvblRvdWNoVGFwOiB0aGlzLnNob3dNZW51LmJpbmQodGhpcyksXG4gICAgICAgICAgICAgICAgaWNvblN0eWxlOiB0aGlzLnByb3BzLmJ1dHRvblN0eWxlXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgUG9wb3ZlcixcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIG9wZW46IHRoaXMuc3RhdGUuc2hvd01lbnUsXG4gICAgICAgICAgICAgICAgICAgIGFuY2hvckVsOiB0aGlzLnN0YXRlLmFuY2hvcixcbiAgICAgICAgICAgICAgICAgICAgYW5jaG9yT3JpZ2luOiB7IGhvcml6b250YWw6IHRoaXMucHJvcHMucG9wb3ZlckRpcmVjdGlvbiB8fCAncmlnaHQnLCB2ZXJ0aWNhbDogdGhpcy5wcm9wcy5wb3BvdmVyVGFyZ2V0UG9zaXRpb24gfHwgJ2JvdHRvbScgfSxcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0T3JpZ2luOiB7IGhvcml6b250YWw6IHRoaXMucHJvcHMucG9wb3ZlckRpcmVjdGlvbiB8fCAncmlnaHQnLCB2ZXJ0aWNhbDogJ3RvcCcgfSxcbiAgICAgICAgICAgICAgICAgICAgb25SZXF1ZXN0Q2xvc2U6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzLnNldFN0YXRlKHsgc2hvd01lbnU6IGZhbHNlIH0pO1xuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB1c2VMYXllckZvckNsaWNrQXdheTogZmFsc2VcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIF9VdGlsczJbJ2RlZmF1bHQnXS5pdGVtc1RvTWVudSh0aGlzLnByb3BzLm1lbnVJdGVtcywgdGhpcy5jbG9zZU1lbnUuYmluZCh0aGlzKSwgZmFsc2UsIHRoaXMucHJvcHMubWVudVByb3BzIHx8IHVuZGVmaW5lZClcbiAgICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIEljb25CdXR0b25NZW51O1xufSkoUmVhY3QuQ29tcG9uZW50KTtcblxuSWNvbkJ1dHRvbk1lbnUucHJvcFR5cGVzID0ge1xuICAgIGJ1dHRvblRpdGxlOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLmlzUmVxdWlyZWQsXG4gICAgYnV0dG9uQ2xhc3NOYW1lOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLmlzUmVxdWlyZWQsXG4gICAgY2xhc3NOYW1lOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLFxuICAgIHBvcG92ZXJEaXJlY3Rpb246IFJlYWN0LlByb3BUeXBlcy5vbmVPZihbJ3JpZ2h0JywgJ2xlZnQnXSksXG4gICAgcG9wb3ZlclBvc2l0aW9uOiBSZWFjdC5Qcm9wVHlwZXMub25lT2YoWyd0b3AnLCAnYm90dG9tJ10pLFxuICAgIG1lbnVQcm9wczogUmVhY3QuUHJvcFR5cGVzLm9iamVjdCxcbiAgICBtZW51SXRlbXM6IFJlYWN0LlByb3BUeXBlcy5hcnJheS5pc1JlcXVpcmVkXG59O1xuXG5leHBvcnRzWydkZWZhdWx0J10gPSBfTWVudUl0ZW1zQ29uc3VtZXIyWydkZWZhdWx0J10oSWNvbkJ1dHRvbk1lbnUpO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMDctMjAxNyBDaGFybGVzIGR1IEpldSAtIEFic3RyaXVtIFNBUyA8dGVhbSAoYXQpIHB5ZC5pbz5cbiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIFB5ZGlvLlxuICpcbiAqIFB5ZGlvIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3JcbiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogUHlkaW8gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggUHlkaW8uICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gKlxuICogVGhlIGxhdGVzdCBjb2RlIGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9weWRpby5jb20+LlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24nKTsgfSB9XG5cbmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09ICdmdW5jdGlvbicgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90ICcgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5zZXRQcm90b3R5cGVPZihzdWJDbGFzcywgc3VwZXJDbGFzcykgOiBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9XG5cbnZhciBSZWFjdCA9IHJlcXVpcmUoJ3JlYWN0Jyk7XG5cbnZhciBfcmVxdWlyZSA9IHJlcXVpcmUoJ21hdGVyaWFsLXVpJyk7XG5cbnZhciBJY29uQnV0dG9uID0gX3JlcXVpcmUuSWNvbkJ1dHRvbjtcbnZhciBQb3BvdmVyID0gX3JlcXVpcmUuUG9wb3ZlcjtcblxudmFyIEljb25CdXR0b25Qb3BvdmVyID0gKGZ1bmN0aW9uIChfUmVhY3QkQ29tcG9uZW50KSB7XG4gICAgX2luaGVyaXRzKEljb25CdXR0b25Qb3BvdmVyLCBfUmVhY3QkQ29tcG9uZW50KTtcblxuICAgIGZ1bmN0aW9uIEljb25CdXR0b25Qb3BvdmVyKHByb3BzLCBjb250ZXh0KSB7XG4gICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBJY29uQnV0dG9uUG9wb3Zlcik7XG5cbiAgICAgICAgX1JlYWN0JENvbXBvbmVudC5jYWxsKHRoaXMsIHByb3BzLCBjb250ZXh0KTtcbiAgICAgICAgdGhpcy5zdGF0ZSA9IHsgc2hvd1BvcG92ZXI6IGZhbHNlIH07XG4gICAgfVxuXG4gICAgSWNvbkJ1dHRvblBvcG92ZXIucHJvdG90eXBlLnNob3dQb3BvdmVyID0gZnVuY3Rpb24gc2hvd1BvcG92ZXIoZXZlbnQpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICBzaG93UG9wb3ZlcjogdHJ1ZSxcbiAgICAgICAgICAgIGFuY2hvcjogZXZlbnQuY3VycmVudFRhcmdldFxuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgSWNvbkJ1dHRvblBvcG92ZXIucHJvdG90eXBlLnJlbmRlciA9IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICdzcGFuJyxcbiAgICAgICAgICAgIHsgY2xhc3NOYW1lOiBcInRvb2xiYXJzLWJ1dHRvbi1tZW51IFwiICsgKHRoaXMucHJvcHMuY2xhc3NOYW1lID8gdGhpcy5wcm9wcy5jbGFzc05hbWUgOiAnJykgfSxcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoSWNvbkJ1dHRvbiwge1xuICAgICAgICAgICAgICAgIHJlZjogJ21lbnVCdXR0b24nLFxuICAgICAgICAgICAgICAgIHRvb2x0aXA6IHRoaXMucHJvcHMuYnV0dG9uVGl0bGUsXG4gICAgICAgICAgICAgICAgaWNvbkNsYXNzTmFtZTogdGhpcy5wcm9wcy5idXR0b25DbGFzc05hbWUsXG4gICAgICAgICAgICAgICAgb25Ub3VjaFRhcDogdGhpcy5zaG93UG9wb3Zlci5iaW5kKHRoaXMpLFxuICAgICAgICAgICAgICAgIGljb25TdHlsZTogdGhpcy5wcm9wcy5idXR0b25TdHlsZVxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgIFBvcG92ZXIsXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBvcGVuOiB0aGlzLnN0YXRlLnNob3dQb3BvdmVyLFxuICAgICAgICAgICAgICAgICAgICBhbmNob3JFbDogdGhpcy5zdGF0ZS5hbmNob3IsXG4gICAgICAgICAgICAgICAgICAgIGFuY2hvck9yaWdpbjogeyBob3Jpem9udGFsOiB0aGlzLnByb3BzLmRpcmVjdGlvbiB8fCAncmlnaHQnLCB2ZXJ0aWNhbDogJ2JvdHRvbScgfSxcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0T3JpZ2luOiB7IGhvcml6b250YWw6IHRoaXMucHJvcHMuZGlyZWN0aW9uIHx8ICdyaWdodCcsIHZlcnRpY2FsOiAndG9wJyB9LFxuICAgICAgICAgICAgICAgICAgICBvblJlcXVlc3RDbG9zZTogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMuc2V0U3RhdGUoeyBzaG93UG9wb3ZlcjogZmFsc2UgfSk7XG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHVzZUxheWVyRm9yQ2xpY2tBd2F5OiBmYWxzZVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5wb3BvdmVyQ29udGVudFxuICAgICAgICAgICAgKVxuICAgICAgICApO1xuICAgIH07XG5cbiAgICByZXR1cm4gSWNvbkJ1dHRvblBvcG92ZXI7XG59KShSZWFjdC5Db21wb25lbnQpO1xuXG5JY29uQnV0dG9uUG9wb3Zlci5wcm9wVHlwZXMgPSB7XG4gICAgYnV0dG9uVGl0bGU6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcuaXNSZXF1aXJlZCxcbiAgICBidXR0b25DbGFzc05hbWU6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcuaXNSZXF1aXJlZCxcbiAgICBjbGFzc05hbWU6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcsXG4gICAgZGlyZWN0aW9uOiBSZWFjdC5Qcm9wVHlwZXMub25lT2YoWydyaWdodCcsICdsZWZ0J10pLFxuICAgIHBvcG92ZXJDb250ZW50OiBSZWFjdC5Qcm9wVHlwZXMub2JqZWN0LmlzUmVxdWlyZWRcbn07XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IEljb25CdXR0b25Qb3BvdmVyO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMDctMjAxNyBDaGFybGVzIGR1IEpldSAtIEFic3RyaXVtIFNBUyA8dGVhbSAoYXQpIHB5ZC5pbz5cbiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIFB5ZGlvLlxuICpcbiAqIFB5ZGlvIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3JcbiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogUHlkaW8gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggUHlkaW8uICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gKlxuICogVGhlIGxhdGVzdCBjb2RlIGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9weWRpby5jb20+LlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxudmFyIF9leHRlbmRzID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiAodGFyZ2V0KSB7IGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7IHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV07IGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHsgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHsgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTsgfSB9IH0gcmV0dXJuIHRhcmdldDsgfTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgJ2RlZmF1bHQnOiBvYmogfTsgfVxuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbicpOyB9IH1cblxuZnVuY3Rpb24gX2luaGVyaXRzKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7IGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gJ2Z1bmN0aW9uJyAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ1N1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uLCBub3QgJyArIHR5cGVvZiBzdXBlckNsYXNzKTsgfSBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHsgY29uc3RydWN0b3I6IHsgdmFsdWU6IHN1YkNsYXNzLCBlbnVtZXJhYmxlOiBmYWxzZSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IH0pOyBpZiAoc3VwZXJDbGFzcykgT2JqZWN0LnNldFByb3RvdHlwZU9mID8gT2JqZWN0LnNldFByb3RvdHlwZU9mKHN1YkNsYXNzLCBzdXBlckNsYXNzKSA6IHN1YkNsYXNzLl9fcHJvdG9fXyA9IHN1cGVyQ2xhc3M7IH1cblxudmFyIF9VdGlscyA9IHJlcXVpcmUoJy4vVXRpbHMnKTtcblxudmFyIF9VdGlsczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9VdGlscyk7XG5cbnZhciBSZWFjdCA9IHJlcXVpcmUoJ3JlYWN0Jyk7XG52YXIgQ29udHJvbGxlciA9IHJlcXVpcmUoJ3B5ZGlvL21vZGVsL2NvbnRyb2xsZXInKTtcblxuZXhwb3J0c1snZGVmYXVsdCddID0gZnVuY3Rpb24gKENvbXBvbmVudCkge1xuICAgIHZhciBXcmFwcGVkID0gKGZ1bmN0aW9uIChfUmVhY3QkQ29tcG9uZW50KSB7XG4gICAgICAgIF9pbmhlcml0cyhXcmFwcGVkLCBfUmVhY3QkQ29tcG9uZW50KTtcblxuICAgICAgICBmdW5jdGlvbiBXcmFwcGVkKHByb3BzLCBjb250ZXh0KSB7XG4gICAgICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgV3JhcHBlZCk7XG5cbiAgICAgICAgICAgIF9SZWFjdCRDb21wb25lbnQuY2FsbCh0aGlzLCBwcm9wcywgY29udGV4dCk7XG4gICAgICAgICAgICB0aGlzLnN0YXRlID0ge1xuICAgICAgICAgICAgICAgIG1lbnVJdGVtczogdGhpcy5wcm9wcy5tZW51SXRlbXMgfHwgW11cbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgICBXcmFwcGVkLnByb3RvdHlwZS5jb21wb25lbnREaWRNb3VudCA9IGZ1bmN0aW9uIGNvbXBvbmVudERpZE1vdW50KCkge1xuICAgICAgICAgICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgICAgICAgICAgaWYgKHRoaXMucHJvcHMuY29udHJvbGxlciAmJiAhdGhpcy5wcm9wcy5tZW51SXRlbXMpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9vYnNlcnZlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGFjdGlvbnMgPSBfdGhpcy5wcm9wcy5jb250cm9sbGVyLmdldENvbnRleHRBY3Rpb25zKCdnZW5lcmljQ29udGV4dCcsIG51bGwsIF90aGlzLnByb3BzLnRvb2xiYXJzKTtcbiAgICAgICAgICAgICAgICAgICAgdmFyIG1lbnVJdGVtcyA9IF9VdGlsczJbJ2RlZmF1bHQnXS5weWRpb0FjdGlvbnNUb0l0ZW1zKGFjdGlvbnMpO1xuICAgICAgICAgICAgICAgICAgICBfdGhpcy5zZXRTdGF0ZSh7IG1lbnVJdGVtczogbWVudUl0ZW1zIH0pO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMucHJvcHMuY29udHJvbGxlciA9PT0gdGhpcy5wcm9wcy5weWRpby5Db250cm9sbGVyKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucHJvcHMucHlkaW8ub2JzZXJ2ZShcImFjdGlvbnNfcmVmcmVzaGVkXCIsIHRoaXMuX29ic2VydmVyKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnByb3BzLmNvbnRyb2xsZXIub2JzZXJ2ZShcImFjdGlvbnNfcmVmcmVzaGVkXCIsIHRoaXMuX29ic2VydmVyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5fb2JzZXJ2ZXIoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICBXcmFwcGVkLnByb3RvdHlwZS5jb21wb25lbnRXaWxsVW5tb3VudCA9IGZ1bmN0aW9uIGNvbXBvbmVudFdpbGxVbm1vdW50KCkge1xuICAgICAgICAgICAgaWYgKHRoaXMuX29ic2VydmVyKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMucHJvcHMuY29udHJvbGxlciA9PT0gdGhpcy5wcm9wcy5weWRpby5Db250cm9sbGVyKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucHJvcHMucHlkaW8uc3RvcE9ic2VydmluZyhcImFjdGlvbnNfcmVmcmVzaGVkXCIsIHRoaXMuX29ic2VydmVyKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnByb3BzLmNvbnRyb2xsZXIuc3RvcE9ic2VydmluZyhcImFjdGlvbnNfcmVmcmVzaGVkXCIsIHRoaXMuX29ic2VydmVyKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgV3JhcHBlZC5wcm90b3R5cGUuY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyA9IGZ1bmN0aW9uIGNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMobmV4dFByb3BzKSB7XG4gICAgICAgICAgICBpZiAobmV4dFByb3BzLm1lbnVJdGVtcyAmJiBuZXh0UHJvcHMubWVudUl0ZW1zICE9PSB0aGlzLnByb3BzLm1lbnVJdGVtcykge1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBtZW51SXRlbXM6IG5leHRQcm9wcy5tZW51SXRlbXMgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgV3JhcHBlZC5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoQ29tcG9uZW50LCBfZXh0ZW5kcyh7fSwgdGhpcy5wcm9wcywgeyBtZW51SXRlbXM6IHRoaXMuc3RhdGUubWVudUl0ZW1zIH0pKTtcbiAgICAgICAgfTtcblxuICAgICAgICByZXR1cm4gV3JhcHBlZDtcbiAgICB9KShSZWFjdC5Db21wb25lbnQpO1xuXG4gICAgV3JhcHBlZC5wcm9wVHlwZXMgPSB7XG4gICAgICAgIG1lbnVJdGVtczogUmVhY3QuUHJvcFR5cGVzLmFycmF5LFxuICAgICAgICB0b29sYmFyczogUmVhY3QuUHJvcFR5cGVzLmFycmF5LFxuICAgICAgICBjb250cm9sbGVyOiBSZWFjdC5Qcm9wVHlwZXMuaW5zdGFuY2VPZihDb250cm9sbGVyKSxcbiAgICAgICAgcHlkaW86IFJlYWN0LlByb3BUeXBlcy5pbnN0YW5jZU9mKFB5ZGlvKVxuICAgIH07XG5cbiAgICByZXR1cm4gV3JhcHBlZDtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDA3LTIwMTcgQ2hhcmxlcyBkdSBKZXUgLSBBYnN0cml1bSBTQVMgPHRlYW0gKGF0KSBweWQuaW8+XG4gKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBQeWRpby5cbiAqXG4gKiBQeWRpbyBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFB5ZGlvIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIFB5ZGlvLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuICpcbiAqIFRoZSBsYXRlc3QgY29kZSBjYW4gYmUgZm91bmQgYXQgPGh0dHBzOi8vcHlkaW8uY29tPi5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfZXh0ZW5kcyA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gKHRhcmdldCkgeyBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgeyB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldOyBmb3IgKHZhciBrZXkgaW4gc291cmNlKSB7IGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoc291cmNlLCBrZXkpKSB7IHRhcmdldFtrZXldID0gc291cmNlW2tleV07IH0gfSB9IHJldHVybiB0YXJnZXQ7IH07XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7ICdkZWZhdWx0Jzogb2JqIH07IH1cblxudmFyIF9VdGlscyA9IHJlcXVpcmUoJy4vVXRpbHMnKTtcblxudmFyIF9VdGlsczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9VdGlscyk7XG5cbnZhciBSZWFjdCA9IHJlcXVpcmUoJ3JlYWN0Jyk7XG52YXIgUmVhY3RET00gPSByZXF1aXJlKCdyZWFjdC1kb20nKTtcblxudmFyIF9yZXF1aXJlID0gcmVxdWlyZSgnbWF0ZXJpYWwtdWknKTtcblxudmFyIE1lbnUgPSBfcmVxdWlyZS5NZW51O1xudmFyIFBhcGVyID0gX3JlcXVpcmUuUGFwZXI7XG5leHBvcnRzWydkZWZhdWx0J10gPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG4gICAgZGlzcGxheU5hbWU6ICdQb3B1cE1lbnUnLFxuXG4gICAgcHJvcFR5cGVzOiB7XG4gICAgICAgIG1lbnVJdGVtczogUmVhY3QuUHJvcFR5cGVzLmFycmF5LmlzUmVxdWlyZWQsXG4gICAgICAgIG9uRXh0ZXJuYWxDbGlja0NoZWNrRWxlbWVudHM6IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgICAgICBjbGFzc05hbWU6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcsXG4gICAgICAgIHN0eWxlOiBSZWFjdC5Qcm9wVHlwZXMub2JqZWN0LFxuICAgICAgICBvbk1lbnVDbG9zZWQ6IFJlYWN0LlByb3BUeXBlcy5mdW5jXG4gICAgfSxcblxuICAgIGdldEluaXRpYWxTdGF0ZTogZnVuY3Rpb24gZ2V0SW5pdGlhbFN0YXRlKCkge1xuICAgICAgICByZXR1cm4geyBzaG93TWVudTogZmFsc2UsIG1lbnVJdGVtczogdGhpcy5wcm9wcy5tZW51SXRlbXMgfTtcbiAgICB9LFxuICAgIHNob3dNZW51OiBmdW5jdGlvbiBzaG93TWVudSgpIHtcbiAgICAgICAgdmFyIHN0eWxlID0gYXJndW1lbnRzLmxlbmd0aCA8PSAwIHx8IGFyZ3VtZW50c1swXSA9PT0gdW5kZWZpbmVkID8gbnVsbCA6IGFyZ3VtZW50c1swXTtcbiAgICAgICAgdmFyIG1lbnVJdGVtcyA9IGFyZ3VtZW50cy5sZW5ndGggPD0gMSB8fCBhcmd1bWVudHNbMV0gPT09IHVuZGVmaW5lZCA/IG51bGwgOiBhcmd1bWVudHNbMV07XG5cbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICBzaG93TWVudTogdHJ1ZSxcbiAgICAgICAgICAgIHN0eWxlOiBzdHlsZSxcbiAgICAgICAgICAgIG1lbnVJdGVtczogbWVudUl0ZW1zID8gbWVudUl0ZW1zIDogdGhpcy5zdGF0ZS5tZW51SXRlbXNcbiAgICAgICAgfSk7XG4gICAgfSxcbiAgICBoaWRlTWVudTogZnVuY3Rpb24gaGlkZU1lbnUoZXZlbnQpIHtcbiAgICAgICAgaWYgKCFldmVudCkge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNob3dNZW51OiBmYWxzZSB9KTtcbiAgICAgICAgICAgIGlmICh0aGlzLnByb3BzLm9uTWVudUNsb3NlZCkgdGhpcy5wcm9wcy5vbk1lbnVDbG9zZWQoKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICAvLyBGaXJlZm94IHRyaWdnZXIgYSBjbGljayBldmVudCB3aGVuIHlvdSBtb3VzZSB1cCBvbiBjb250ZXh0bWVudSBldmVudFxuICAgICAgICBpZiAodHlwZW9mIGV2ZW50ICE9PSAndW5kZWZpbmVkJyAmJiBldmVudC5idXR0b24gPT09IDIgJiYgZXZlbnQudHlwZSAhPT0gJ2NvbnRleHRtZW51Jykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHZhciBub2RlID0gUmVhY3RET00uZmluZERPTU5vZGUodGhpcy5yZWZzLm1lbnVDb250YWluZXIpO1xuICAgICAgICBpZiAobm9kZS5jb250YWlucyhldmVudC50YXJnZXQpIHx8IG5vZGUgPT09IGV2ZW50LnRhcmdldCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNob3dNZW51OiBmYWxzZSB9KTtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMub25NZW51Q2xvc2VkKSB0aGlzLnByb3BzLm9uTWVudUNsb3NlZCgpO1xuICAgIH0sXG4gICAgY29tcG9uZW50RGlkTW91bnQ6IGZ1bmN0aW9uIGNvbXBvbmVudERpZE1vdW50KCkge1xuICAgICAgICB0aGlzLl9vYnNlcnZlciA9IHRoaXMuaGlkZU1lbnU7XG4gICAgfSxcbiAgICBjb21wb25lbnRXaWxsVW5tb3VudDogZnVuY3Rpb24gY29tcG9uZW50V2lsbFVubW91bnQoKSB7XG4gICAgICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5fb2JzZXJ2ZXIsIGZhbHNlKTtcbiAgICB9LFxuICAgIGNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHM6IGZ1bmN0aW9uIGNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMobmV4dFByb3BzKSB7XG4gICAgICAgIGlmIChuZXh0UHJvcHMubWVudUl0ZW1zKSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgbWVudUl0ZW1zOiBuZXh0UHJvcHMubWVudUl0ZW1zIH0pO1xuICAgICAgICB9XG4gICAgfSxcbiAgICBjb21wb25lbnREaWRVcGRhdGU6IGZ1bmN0aW9uIGNvbXBvbmVudERpZFVwZGF0ZShwcmV2UHJvcHMsIG5leHRQcm9wcykge1xuICAgICAgICBpZiAodGhpcy5zdGF0ZS5zaG93TWVudSkge1xuICAgICAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCB0aGlzLl9vYnNlcnZlciwgZmFsc2UpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignY2xpY2snLCB0aGlzLl9vYnNlcnZlciwgZmFsc2UpO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIG1lbnVDbGlja2VkOiBmdW5jdGlvbiBtZW51Q2xpY2tlZChldmVudCwgaW5kZXgsIG1lbnVJdGVtKSB7XG4gICAgICAgIHRoaXMuaGlkZU1lbnUoKTtcbiAgICB9LFxuXG4gICAgcmVuZGVyOiBmdW5jdGlvbiByZW5kZXIoKSB7XG5cbiAgICAgICAgdmFyIHN0eWxlID0gdGhpcy5zdGF0ZS5zdHlsZSB8fCB7fTtcbiAgICAgICAgc3R5bGUgPSBfZXh0ZW5kcyh7fSwgc3R5bGUsIHsgekluZGV4OiAxMDAwIH0pO1xuICAgICAgICB2YXIgbWVudSA9IF9VdGlsczJbJ2RlZmF1bHQnXS5pdGVtc1RvTWVudSh0aGlzLnN0YXRlLm1lbnVJdGVtcywgdGhpcy5tZW51Q2xpY2tlZCwgZmFsc2UsIF9leHRlbmRzKHsgZGVza3RvcDogdHJ1ZSwgZGlzcGxheTogJ3JpZ2h0Jywgd2lkdGg6IDI1MCB9LCB0aGlzLnByb3BzLm1lbnVQcm9wcykpO1xuICAgICAgICBpZiAodGhpcy5zdGF0ZS5zaG93TWVudSkge1xuICAgICAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgUGFwZXIsXG4gICAgICAgICAgICAgICAgeyB6RGVwdGg6IHRoaXMucHJvcHMuekRlcHRoIHx8IDEsIHJlZjogJ21lbnVDb250YWluZXInLCBjbGFzc05hbWU6ICdtZW51LXBvc2l0aW9uZXInLCBzdHlsZTogc3R5bGUgfSxcbiAgICAgICAgICAgICAgICBtZW51XG4gICAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICB9XG5cbn0pO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMDctMjAxNyBDaGFybGVzIGR1IEpldSAtIEFic3RyaXVtIFNBUyA8dGVhbSAoYXQpIHB5ZC5pbz5cbiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIFB5ZGlvLlxuICpcbiAqIFB5ZGlvIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3JcbiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogUHlkaW8gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggUHlkaW8uICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gKlxuICogVGhlIGxhdGVzdCBjb2RlIGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9weWRpby5jb20+LlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgJ2RlZmF1bHQnOiBvYmogfTsgfVxuXG52YXIgX1V0aWxzID0gcmVxdWlyZSgnLi9VdGlscycpO1xuXG52YXIgX1V0aWxzMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1V0aWxzKTtcblxudmFyIF9JY29uQnV0dG9uTWVudSA9IHJlcXVpcmUoJy4vSWNvbkJ1dHRvbk1lbnUnKTtcblxudmFyIF9JY29uQnV0dG9uTWVudTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9JY29uQnV0dG9uTWVudSk7XG5cbnZhciBfQnV0dG9uTWVudSA9IHJlcXVpcmUoJy4vQnV0dG9uTWVudScpO1xuXG52YXIgX0J1dHRvbk1lbnUyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfQnV0dG9uTWVudSk7XG5cbnZhciBfSWNvbkJ1dHRvblBvcG92ZXIgPSByZXF1aXJlKCcuL0ljb25CdXR0b25Qb3BvdmVyJyk7XG5cbnZhciBfSWNvbkJ1dHRvblBvcG92ZXIyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfSWNvbkJ1dHRvblBvcG92ZXIpO1xuXG4oZnVuY3Rpb24gKGdsb2JhbCkge1xuICAgIGV4cG9ydHNbJ2RlZmF1bHQnXSA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcbiAgICAgICAgZGlzcGxheU5hbWU6ICdUb29sYmFyJyxcblxuICAgICAgICBwcm9wVHlwZXM6IHtcbiAgICAgICAgICAgIHRvb2xiYXJzOiBSZWFjdC5Qcm9wVHlwZXMuYXJyYXksXG4gICAgICAgICAgICBncm91cE90aGVyTGlzdDogUmVhY3QuUHJvcFR5cGVzLmFycmF5LFxuICAgICAgICAgICAgcmVuZGVyaW5nVHlwZTogUmVhY3QuUHJvcFR5cGVzLnN0cmluZyxcbiAgICAgICAgICAgIGNvbnRyb2xsZXI6IFJlYWN0LlByb3BUeXBlcy5pbnN0YW5jZU9mKENvbnRyb2xsZXIpLFxuICAgICAgICAgICAgdG9vbGJhclN0eWxlOiBSZWFjdC5Qcm9wVHlwZXMub2JqZWN0LFxuICAgICAgICAgICAgYnV0dG9uU3R5bGU6IFJlYWN0LlByb3BUeXBlcy5vYmplY3RcbiAgICAgICAgfSxcblxuICAgICAgICBjb21wb25lbnREaWRNb3VudDogZnVuY3Rpb24gY29tcG9uZW50RGlkTW91bnQoKSB7XG4gICAgICAgICAgICB0aGlzLl9vYnNlcnZlciA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLmlzTW91bnRlZCgpKSByZXR1cm47XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgICAgICAgIGdyb3VwczogdGhpcy5wcm9wcy5jb250cm9sbGVyLmdldFRvb2xiYXJzQWN0aW9ucyh0aGlzLnByb3BzLnRvb2xiYXJzLCB0aGlzLnByb3BzLmdyb3VwT3RoZXJMaXN0KVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSkuYmluZCh0aGlzKTtcbiAgICAgICAgICAgIGlmICh0aGlzLnByb3BzLmNvbnRyb2xsZXIgPT09IHB5ZGlvLkNvbnRyb2xsZXIpIHtcbiAgICAgICAgICAgICAgICBweWRpby5vYnNlcnZlKFwiYWN0aW9uc19yZWZyZXNoZWRcIiwgdGhpcy5fb2JzZXJ2ZXIpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnByb3BzLmNvbnRyb2xsZXIub2JzZXJ2ZShcImFjdGlvbnNfcmVmcmVzaGVkXCIsIHRoaXMuX29ic2VydmVyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICBjb21wb25lbnRXaWxsVW5tb3VudDogZnVuY3Rpb24gY29tcG9uZW50V2lsbFVubW91bnQoKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5wcm9wcy5jb250cm9sbGVyID09PSBweWRpby5Db250cm9sbGVyKSB7XG4gICAgICAgICAgICAgICAgcHlkaW8uc3RvcE9ic2VydmluZyhcImFjdGlvbnNfcmVmcmVzaGVkXCIsIHRoaXMuX29ic2VydmVyKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5jb250cm9sbGVyLnN0b3BPYnNlcnZpbmcoXCJhY3Rpb25zX3JlZnJlc2hlZFwiLCB0aGlzLl9vYnNlcnZlcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG5cbiAgICAgICAgY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wczogZnVuY3Rpb24gY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyhuZXh0UHJvcHMpIHtcbiAgICAgICAgICAgIGlmIChuZXh0UHJvcHMudG9vbGJhcnMgIT09IHRoaXMucHJvcHMudG9vbGJhcnMpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgICAgICAgICAgZ3JvdXBzOiB0aGlzLnByb3BzLmNvbnRyb2xsZXIuZ2V0VG9vbGJhcnNBY3Rpb25zKG5leHRQcm9wcy50b29sYmFycywgbmV4dFByb3BzLmdyb3VwT3RoZXJMaXN0KVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuXG4gICAgICAgIGdldEluaXRpYWxTdGF0ZTogZnVuY3Rpb24gZ2V0SW5pdGlhbFN0YXRlKCkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBncm91cHM6IHRoaXMucHJvcHMuY29udHJvbGxlci5nZXRUb29sYmFyc0FjdGlvbnModGhpcy5wcm9wcy50b29sYmFycywgdGhpcy5wcm9wcy5ncm91cE90aGVyTGlzdClcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0sXG5cbiAgICAgICAgZ2V0RGVmYXVsdFByb3BzOiBmdW5jdGlvbiBnZXREZWZhdWx0UHJvcHMoKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGNvbnRyb2xsZXI6IGdsb2JhbC5weWRpby5Db250cm9sbGVyLFxuICAgICAgICAgICAgICAgIHJlbmRlcmluZ1R5cGU6ICdidXR0b24nLFxuICAgICAgICAgICAgICAgIGdyb3VwT3RoZXJMaXN0OiBbXVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSxcblxuICAgICAgICByZW5kZXI6IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgICAgICAgIHZhciBncm91cHMgPSB0aGlzLnN0YXRlLmdyb3VwcztcbiAgICAgICAgICAgIHZhciBhY3Rpb25zID0gW107XG4gICAgICAgICAgICB2YXIgX3Byb3BzID0gdGhpcy5wcm9wcztcbiAgICAgICAgICAgIHZhciB0b29sYmFycyA9IF9wcm9wcy50b29sYmFycztcbiAgICAgICAgICAgIHZhciByZW5kZXJpbmdUeXBlID0gX3Byb3BzLnJlbmRlcmluZ1R5cGU7XG4gICAgICAgICAgICB2YXIgZ3JvdXBPdGhlckxpc3QgPSBfcHJvcHMuZ3JvdXBPdGhlckxpc3Q7XG4gICAgICAgICAgICB2YXIgYnV0dG9uU3R5bGUgPSBfcHJvcHMuYnV0dG9uU3R5bGU7XG4gICAgICAgICAgICB2YXIgdG9vbHRpcFBvc2l0aW9uID0gX3Byb3BzLnRvb2x0aXBQb3NpdGlvbjtcbiAgICAgICAgICAgIHZhciBjb250cm9sbGVyID0gX3Byb3BzLmNvbnRyb2xsZXI7XG5cbiAgICAgICAgICAgIHZhciBhbGxUb29sYmFycyA9IFtdLmNvbmNhdCh0b29sYmFycyk7XG4gICAgICAgICAgICBpZiAoZ3JvdXBPdGhlckxpc3QubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgYWxsVG9vbGJhcnMgPSBhbGxUb29sYmFycy5jb25jYXQoWydNT1JFX0FDVElPTiddKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGFsbFRvb2xiYXJzLm1hcChmdW5jdGlvbiAoYmFyTmFtZSkge1xuICAgICAgICAgICAgICAgIGlmICghZ3JvdXBzLmhhcyhiYXJOYW1lKSkgcmV0dXJuO1xuICAgICAgICAgICAgICAgIGdyb3Vwcy5nZXQoYmFyTmFtZSkubWFwKGZ1bmN0aW9uIChhY3Rpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGFjdGlvbi5kZW55KSByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIHZhciBtZW51SXRlbXMgPSB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBwb3BvdmVyQ29udGVudCA9IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lbnVUaXRsZSA9IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lbnVJY29uID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgICAgICB2YXIgYWN0aW9uTmFtZSA9IGFjdGlvbi5vcHRpb25zLm5hbWU7XG5cbiAgICAgICAgICAgICAgICAgICAgbWVudVRpdGxlID0gYWN0aW9uLm9wdGlvbnMudGV4dDtcbiAgICAgICAgICAgICAgICAgICAgbWVudUljb24gPSBhY3Rpb24ub3B0aW9ucy5pY29uX2NsYXNzO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChiYXJOYW1lID09PSAnTU9SRV9BQ1RJT04nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBzdWJJdGVtcyA9IGFjdGlvbi5zdWJNZW51SXRlbXMuZHluYW1pY0l0ZW1zO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpdGVtcyA9IFtdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1Ykl0ZW1zLm1hcChmdW5jdGlvbiAob2JqKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvYmouc2VwYXJhdG9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpdGVtcy5wdXNoKG9iaik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAob2JqLmFjdGlvbklkICYmICFvYmouYWN0aW9uSWQuZGVueSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlbXMucHVzaChvYmouYWN0aW9uSWQuZ2V0TWVudURhdGEoKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZW51SXRlbXMgPSBfVXRpbHMyWydkZWZhdWx0J10ucHlkaW9BY3Rpb25zVG9JdGVtcyhpdGVtcyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9KSgpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGFjdGlvbi5zdWJNZW51SXRlbXMuc3RhdGljSXRlbXMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lbnVJdGVtcyA9IF9VdGlsczJbJ2RlZmF1bHQnXS5weWRpb0FjdGlvbnNUb0l0ZW1zKGFjdGlvbi5zdWJNZW51SXRlbXMuc3RhdGljSXRlbXMpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGFjdGlvbi5zdWJNZW51SXRlbXMuZHluYW1pY0J1aWxkZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lbnVJdGVtcyA9IF9VdGlsczJbJ2RlZmF1bHQnXS5weWRpb0FjdGlvbnNUb0l0ZW1zKGFjdGlvbi5zdWJNZW51SXRlbXMuZHluYW1pY0J1aWxkZXIoY29udHJvbGxlcikpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGFjdGlvbi5zdWJNZW51SXRlbXMucG9wb3ZlckNvbnRlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBvcG92ZXJDb250ZW50ID0gYWN0aW9uLnN1Yk1lbnVJdGVtcy5wb3BvdmVyQ29udGVudDtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHt9XG4gICAgICAgICAgICAgICAgICAgIHZhciBpZCA9ICdhY3Rpb24tJyArIGFjdGlvbi5vcHRpb25zLm5hbWU7XG4gICAgICAgICAgICAgICAgICAgIGlmIChyZW5kZXJpbmdUeXBlID09PSAnYnV0dG9uLWljb24nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZW51VGl0bGUgPSBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzcGFuJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ2J1dHRvbi1pY29uJyB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nLCB7IGNsYXNzTmFtZTogXCJidXR0b24taWNvbi1pY29uIFwiICsgbWVudUljb24gfSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3NwYW4nLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ2J1dHRvbi1pY29uLWxhYmVsJyB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZW51VGl0bGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChtZW51SXRlbXMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZW5kZXJpbmdUeXBlID09PSAnYnV0dG9uJyB8fCByZW5kZXJpbmdUeXBlID09PSAnYnV0dG9uLWljb24nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWN0aW9ucy5wdXNoKFJlYWN0LmNyZWF0ZUVsZW1lbnQoX0J1dHRvbk1lbnUyWydkZWZhdWx0J10sIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5OiBhY3Rpb25OYW1lLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU6IGlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidXR0b25UaXRsZTogbWVudVRpdGxlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZW51SXRlbXM6IG1lbnVJdGVtcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnV0dG9uTGFiZWxTdHlsZTogYnV0dG9uU3R5bGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjdGlvbnMucHVzaChSZWFjdC5jcmVhdGVFbGVtZW50KF9JY29uQnV0dG9uTWVudTJbJ2RlZmF1bHQnXSwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXk6IGFjdGlvbk5hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogaWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uTWVudUNsaWNrZWQ6IGZ1bmN0aW9uIChvYmplY3QpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC5wYXlsb2FkKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1dHRvbkNsYXNzTmFtZTogbWVudUljb24sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1dHRvblRpdGxlOiBtZW51VGl0bGUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lbnVJdGVtczogbWVudUl0ZW1zLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidXR0b25TdHlsZTogYnV0dG9uU3R5bGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocG9wb3ZlckNvbnRlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFjdGlvbnMucHVzaChSZWFjdC5jcmVhdGVFbGVtZW50KF9JY29uQnV0dG9uUG9wb3ZlcjJbJ2RlZmF1bHQnXSwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleTogYWN0aW9uTmFtZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU6IGlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1dHRvbkNsYXNzTmFtZTogbWVudUljb24sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnV0dG9uVGl0bGU6IG1lbnVUaXRsZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBidXR0b25TdHlsZTogYnV0dG9uU3R5bGUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9wb3ZlckNvbnRlbnQ6IHBvcG92ZXJDb250ZW50XG4gICAgICAgICAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgY2xpY2sgPSBmdW5jdGlvbiBjbGljayhzeW50aEV2ZW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWN0aW9uLmFwcGx5KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlbmRlcmluZ1R5cGUgPT09ICdidXR0b24taWNvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY3Rpb25zLnB1c2goUmVhY3QuY3JlYXRlRWxlbWVudChSZWFjdE1VSS5GbGF0QnV0dG9uLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleTogYWN0aW9uTmFtZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lOiBpZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25Ub3VjaFRhcDogY2xpY2ssXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsOiBtZW51VGl0bGUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsU3R5bGU6IGJ1dHRvblN0eWxlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChyZW5kZXJpbmdUeXBlID09PSAnYnV0dG9uJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjdGlvbnMucHVzaChSZWFjdC5jcmVhdGVFbGVtZW50KE1hdGVyaWFsVUkuRmxhdEJ1dHRvbiwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXk6IGFjdGlvbk5hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogaWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uVG91Y2hUYXA6IGNsaWNrLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbDogbWVudVRpdGxlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbFN0eWxlOiBidXR0b25TdHlsZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWN0aW9ucy5wdXNoKFJlYWN0LmNyZWF0ZUVsZW1lbnQoTWF0ZXJpYWxVSS5JY29uQnV0dG9uLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleTogYWN0aW9uTmFtZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWNvbkNsYXNzTmFtZTogbWVudUljb24gKyAnICcgKyBpZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWNvblN0eWxlOiBidXR0b25TdHlsZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25Ub3VjaFRhcDogY2xpY2ssXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvb2x0aXA6IG1lbnVUaXRsZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9vbHRpcFBvc2l0aW9uOiB0b29sdGlwUG9zaXRpb25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdmFyIGNOYW1lID0gdGhpcy5wcm9wcy5jbGFzc05hbWUgPyB0aGlzLnByb3BzLmNsYXNzTmFtZSA6ICcnO1xuICAgICAgICAgICAgY05hbWUgKz0gJyAnICsgJ3Rvb2xiYXInO1xuICAgICAgICAgICAgaWYgKCFhY3Rpb25zLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGNOYW1lICs9ICcgZW1wdHktdG9vbGJhcic7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogY05hbWUsIHN0eWxlOiB0aGlzLnByb3BzLnRvb2xiYXJTdHlsZSwgaWQ6IHRoaXMucHJvcHMuaWQgfSxcbiAgICAgICAgICAgICAgICBhY3Rpb25zXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICB9KTtcbn0pKHdpbmRvdyk7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTtcbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDE3IENoYXJsZXMgZHUgSmV1IC0gQWJzdHJpdW0gU0FTIDx0ZWFtIChhdCkgcHlkLmlvPlxuICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgUHlkaW8uXG4gKlxuICogUHlkaW8gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBQeWRpbyBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCBQeWRpby4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAqXG4gKiBUaGUgbGF0ZXN0IGNvZGUgY2FuIGJlIGZvdW5kIGF0IDxodHRwczovL3B5ZGlvLmNvbT4uXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG52YXIgX2V4dGVuZHMgPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uICh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTsgZm9yICh2YXIga2V5IGluIHNvdXJjZSkgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkgeyB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldOyB9IH0gfSByZXR1cm4gdGFyZ2V0OyB9O1xuXG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKCdtYXRlcmlhbC11aScpO1xuXG52YXIgRGl2aWRlciA9IF9yZXF1aXJlLkRpdmlkZXI7XG52YXIgTWVudSA9IF9yZXF1aXJlLk1lbnU7XG52YXIgTWVudUl0ZW0gPSBfcmVxdWlyZS5NZW51SXRlbTtcbnZhciBGb250SWNvbiA9IF9yZXF1aXJlLkZvbnRJY29uO1xuXG5mdW5jdGlvbiBweWRpb0FjdGlvbnNUb0l0ZW1zKCkge1xuICAgIHZhciBhY3Rpb25zID0gYXJndW1lbnRzLmxlbmd0aCA8PSAwIHx8IGFyZ3VtZW50c1swXSA9PT0gdW5kZWZpbmVkID8gW10gOiBhcmd1bWVudHNbMF07XG5cbiAgICB2YXIgaXRlbXMgPSBbXTtcbiAgICB2YXIgbGFzdElzU2VwYXJhdG9yID0gZmFsc2U7XG4gICAgYWN0aW9ucy5tYXAoKGZ1bmN0aW9uIChhY3Rpb24sIGluZGV4KSB7XG4gICAgICAgIGlmIChhY3Rpb24uc2VwYXJhdG9yKSB7XG4gICAgICAgICAgICBpZiAobGFzdElzU2VwYXJhdG9yKSByZXR1cm47XG4gICAgICAgICAgICBpdGVtcy5wdXNoKGFjdGlvbik7XG4gICAgICAgICAgICBsYXN0SXNTZXBhcmF0b3IgPSB0cnVlO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGxhc3RJc1NlcGFyYXRvciA9IGZhbHNlO1xuICAgICAgICB2YXIgbGFiZWwgPSBhY3Rpb24ucmF3X25hbWUgPyBhY3Rpb24ucmF3X25hbWUgOiBhY3Rpb24ubmFtZTtcbiAgICAgICAgdmFyIGljb25DbGFzcyA9IGFjdGlvbi5pY29uX2NsYXNzO1xuICAgICAgICB2YXIgcGF5bG9hZCA9IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKGFjdGlvbi5zdWJNZW51KSB7XG4gICAgICAgICAgICB2YXIgc3ViSXRlbXMgPSBhY3Rpb24uc3ViTWVudUJlZm9yZVNob3cgPyBweWRpb0FjdGlvbnNUb0l0ZW1zKGFjdGlvbi5zdWJNZW51QmVmb3JlU2hvdygpKSA6IGFjdGlvbi5zdWJNZW51O1xuICAgICAgICAgICAgaXRlbXMucHVzaCh7XG4gICAgICAgICAgICAgICAgdGV4dDogbGFiZWwsXG4gICAgICAgICAgICAgICAgaWNvbkNsYXNzTmFtZTogaWNvbkNsYXNzLFxuICAgICAgICAgICAgICAgIHN1Ykl0ZW1zOiBzdWJJdGVtc1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpdGVtcy5wdXNoKHtcbiAgICAgICAgICAgICAgICB0ZXh0OiBsYWJlbCxcbiAgICAgICAgICAgICAgICBpY29uQ2xhc3NOYW1lOiBpY29uQ2xhc3MsXG4gICAgICAgICAgICAgICAgcGF5bG9hZDogYWN0aW9uLmNhbGxiYWNrXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH0pLmJpbmQodGhpcykpO1xuICAgIGlmIChsYXN0SXNTZXBhcmF0b3IpIHtcbiAgICAgICAgaXRlbXMgPSBpdGVtcy5zbGljZSgwLCBpdGVtcy5sZW5ndGggLSAxKTtcbiAgICB9XG4gICAgaWYgKGl0ZW1zLmxlbmd0aCAmJiBpdGVtc1swXSAmJiBpdGVtc1swXS5zZXBhcmF0b3IpIHtcbiAgICAgICAgaXRlbXMuc2hpZnQoKTtcbiAgICB9XG4gICAgcmV0dXJuIGl0ZW1zO1xufVxuXG5mdW5jdGlvbiBpdGVtc1RvTWVudShpdGVtcywgY2xvc2VNZW51Q2FsbGJhY2spIHtcbiAgICB2YXIgc3ViSXRlbXNPbmx5ID0gYXJndW1lbnRzLmxlbmd0aCA8PSAyIHx8IGFyZ3VtZW50c1syXSA9PT0gdW5kZWZpbmVkID8gZmFsc2UgOiBhcmd1bWVudHNbMl07XG4gICAgdmFyIG1lbnVQcm9wcyA9IGFyZ3VtZW50cy5sZW5ndGggPD0gMyB8fCBhcmd1bWVudHNbM10gPT09IHVuZGVmaW5lZCA/IHt9IDogYXJndW1lbnRzWzNdO1xuXG4gICAgbWVudVByb3BzID0gX2V4dGVuZHMoe1xuICAgICAgICBkaXNwbGF5OiAnbm9ybWFsJyxcbiAgICAgICAgd2lkdGg6IDIxNixcbiAgICAgICAgZGVza3RvcDogdHJ1ZSxcbiAgICAgICAgYXV0b1dpZHRoOiBmYWxzZVxuICAgIH0sIG1lbnVQcm9wcyk7XG5cbiAgICB2YXIgbWVudUl0ZW1zID0gaXRlbXMubWFwKGZ1bmN0aW9uIChpdGVtLCBpbmRleCkge1xuXG4gICAgICAgIGlmIChpdGVtLnNlcGFyYXRvcikgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoRGl2aWRlciwgeyBrZXk6IFwiZGl2aWRlclwiICsgaW5kZXggfSk7XG5cbiAgICAgICAgdmFyIHN1Ykl0ZW1zID0gdW5kZWZpbmVkLFxuICAgICAgICAgICAgcGF5bG9hZCA9IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKGl0ZW0uc3ViSXRlbXMpIHtcbiAgICAgICAgICAgIHN1Ykl0ZW1zID0gaXRlbXNUb01lbnUoaXRlbS5zdWJJdGVtcywgY2xvc2VNZW51Q2FsbGJhY2ssIHRydWUpO1xuICAgICAgICB9IGVsc2UgaWYgKGl0ZW0ucGF5bG9hZCkge1xuICAgICAgICAgICAgcGF5bG9hZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBpdGVtLnBheWxvYWQoKTtcbiAgICAgICAgICAgICAgICBjbG9zZU1lbnVDYWxsYmFjaygpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBsZWZ0SWNvbiA9IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIHJpZ2h0SWNvbiA9IHVuZGVmaW5lZDtcbiAgICAgICAgdmFyIGljb25DbGFzc05hbWUgPSBpdGVtLmljb25DbGFzc05hbWU7dmFyIGluc2V0ID0gZmFsc2U7XG4gICAgICAgIGlmIChpY29uQ2xhc3NOYW1lID09PSAnX19JTlNFVF9fJykge1xuICAgICAgICAgICAgaWNvbkNsYXNzTmFtZSA9ICcnO1xuICAgICAgICAgICAgaW5zZXQgPSB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG1lbnVQcm9wcy5kaXNwbGF5ID09PSAnbm9ybWFsJykge1xuICAgICAgICAgICAgbGVmdEljb24gPSBpY29uQ2xhc3NOYW1lID8gUmVhY3QuY3JlYXRlRWxlbWVudChGb250SWNvbiwgeyBjbGFzc05hbWU6IGl0ZW0uaWNvbkNsYXNzTmFtZSArICcgbWVudS1pY29ucycsIHN0eWxlOiB7IGZvbnRTaXplOiAxNiwgcGFkZGluZzogNSB9IH0pIDogbnVsbDtcbiAgICAgICAgfSBlbHNlIGlmIChtZW51UHJvcHMuZGlzcGxheSA9PT0gJ3JpZ2h0Jykge1xuICAgICAgICAgICAgcmlnaHRJY29uID0gaWNvbkNsYXNzTmFtZSA/IFJlYWN0LmNyZWF0ZUVsZW1lbnQoRm9udEljb24sIHsgY2xhc3NOYW1lOiBpdGVtLmljb25DbGFzc05hbWUgKyAnIG1lbnUtaWNvbnMnLCBzdHlsZTogeyBmb250U2l6ZTogMTYsIHBhZGRpbmc6IDUgfSB9KSA6IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgcmlnaHRJY29uID0gc3ViSXRlbXMgJiYgc3ViSXRlbXMubGVuZ3RoID8gUmVhY3QuY3JlYXRlRWxlbWVudChGb250SWNvbiwgeyBjbGFzc05hbWU6ICdtZGkgbWRpLW1lbnUtcmlnaHQgbWVudS1pY29ucycgfSkgOiByaWdodEljb247XG5cbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoTWVudUl0ZW0sIHtcbiAgICAgICAgICAgIGtleTogaXRlbS50ZXh0LFxuICAgICAgICAgICAgcHJpbWFyeVRleHQ6IGl0ZW0udGV4dCxcbiAgICAgICAgICAgIGluc2V0Q2hpbGRyZW46IGluc2V0LFxuICAgICAgICAgICAgbGVmdEljb246IGxlZnRJY29uLFxuICAgICAgICAgICAgcmlnaHRJY29uOiByaWdodEljb24sXG4gICAgICAgICAgICBvblRvdWNoVGFwOiBwYXlsb2FkLFxuICAgICAgICAgICAgbWVudUl0ZW1zOiBzdWJJdGVtc1xuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgIGlmIChzdWJJdGVtc09ubHkpIHtcbiAgICAgICAgcmV0dXJuIG1lbnVJdGVtcztcbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgIE1lbnUsXG4gICAgICAgICAgICBtZW51UHJvcHMsXG4gICAgICAgICAgICBtZW51SXRlbXNcbiAgICAgICAgKTtcbiAgICB9XG59XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IHsgcHlkaW9BY3Rpb25zVG9JdGVtczogcHlkaW9BY3Rpb25zVG9JdGVtcywgaXRlbXNUb01lbnU6IGl0ZW1zVG9NZW51IH07XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTtcbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDE3IENoYXJsZXMgZHUgSmV1IC0gQWJzdHJpdW0gU0FTIDx0ZWFtIChhdCkgcHlkLmlvPlxuICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgUHlkaW8uXG4gKlxuICogUHlkaW8gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBQeWRpbyBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCBQeWRpby4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAqXG4gKiBUaGUgbGF0ZXN0IGNvZGUgY2FuIGJlIGZvdW5kIGF0IDxodHRwczovL3B5ZGlvLmNvbT4uXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbicpOyB9IH1cblxuZnVuY3Rpb24gX2luaGVyaXRzKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7IGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gJ2Z1bmN0aW9uJyAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ1N1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uLCBub3QgJyArIHR5cGVvZiBzdXBlckNsYXNzKTsgfSBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHsgY29uc3RydWN0b3I6IHsgdmFsdWU6IHN1YkNsYXNzLCBlbnVtZXJhYmxlOiBmYWxzZSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IH0pOyBpZiAoc3VwZXJDbGFzcykgT2JqZWN0LnNldFByb3RvdHlwZU9mID8gT2JqZWN0LnNldFByb3RvdHlwZU9mKHN1YkNsYXNzLCBzdXBlckNsYXNzKSA6IHN1YkNsYXNzLl9fcHJvdG9fXyA9IHN1cGVyQ2xhc3M7IH1cblxudmFyIF9yZXF1aXJlID0gcmVxdWlyZSgncmVhY3QnKTtcblxudmFyIENvbXBvbmVudCA9IF9yZXF1aXJlLkNvbXBvbmVudDtcbnZhciBQcm9wVHlwZXMgPSBfcmVxdWlyZS5Qcm9wVHlwZXM7XG5cbnZhciBfcmVxdWlyZTIgPSByZXF1aXJlKCdtYXRlcmlhbC11aScpO1xuXG52YXIgVGV4dEZpZWxkID0gX3JlcXVpcmUyLlRleHRGaWVsZDtcbnZhciBGbGF0QnV0dG9uID0gX3JlcXVpcmUyLkZsYXRCdXR0b247XG5cbnZhciBfcmVxdWlyZSRyZXF1aXJlTGliID0gcmVxdWlyZSgncHlkaW8nKS5yZXF1aXJlTGliKCdib290Jyk7XG5cbnZhciBQeWRpb0NvbnRleHRDb25zdW1lciA9IF9yZXF1aXJlJHJlcXVpcmVMaWIuUHlkaW9Db250ZXh0Q29uc3VtZXI7XG5cbi8qKlxuICogU2ltcGxlIGZvcm0gZm9yIGNyZWF0aW5nIGEgdGVhbVxuICovXG5cbnZhciBUZWFtQ3JlYXRpb25Gb3JtID0gKGZ1bmN0aW9uIChfQ29tcG9uZW50KSB7XG4gICAgX2luaGVyaXRzKFRlYW1DcmVhdGlvbkZvcm0sIF9Db21wb25lbnQpO1xuXG4gICAgVGVhbUNyZWF0aW9uRm9ybS51cGRhdGVUZWFtVXNlcnMgPSBmdW5jdGlvbiB1cGRhdGVUZWFtVXNlcnModGVhbSwgb3BlcmF0aW9uLCB1c2VycywgY2FsbGJhY2spIHtcbiAgICAgICAgdmFyIHRlYW1JZCA9IHRlYW0uaWQucmVwbGFjZSgnL0FKWFBfVEVBTS8nLCAnJyk7XG4gICAgICAgIHZhciBjbGVhclVzZXJDYWNoZSA9IGZ1bmN0aW9uIGNsZWFyVXNlckNhY2hlKHVJZCkge1xuICAgICAgICAgICAgTWV0YUNhY2hlU2VydmljZS5nZXRJbnN0YW5jZSgpLmRlbGV0ZUtleSgndXNlcl9wdWJsaWNfZGF0YS1yaWNoJywgdUlkKTtcbiAgICAgICAgfTtcbiAgICAgICAgaWYgKG9wZXJhdGlvbiA9PT0gJ2FkZCcpIHtcbiAgICAgICAgICAgIHVzZXJzLmZvckVhY2goZnVuY3Rpb24gKHVzZXIpIHtcbiAgICAgICAgICAgICAgICB2YXIgdXNlcklkID0gdXNlci5nZXRJZCA/IHVzZXIuZ2V0SWQoKSA6IHVzZXIuaWQ7XG4gICAgICAgICAgICAgICAgUHlkaW9Vc2Vycy5DbGllbnQuYWRkVXNlclRvVGVhbSh0ZWFtSWQsIHVzZXJJZCwgY2FsbGJhY2spO1xuICAgICAgICAgICAgICAgIGNsZWFyVXNlckNhY2hlKHVzZXJJZCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIGlmIChvcGVyYXRpb24gPT09ICdkZWxldGUnKSB7XG4gICAgICAgICAgICB1c2Vycy5mb3JFYWNoKGZ1bmN0aW9uICh1c2VyKSB7XG4gICAgICAgICAgICAgICAgdmFyIHVzZXJJZCA9IHVzZXIuZ2V0SWQgPyB1c2VyLmdldElkKCkgOiB1c2VyLmlkO1xuICAgICAgICAgICAgICAgIFB5ZGlvVXNlcnMuQ2xpZW50LnJlbW92ZVVzZXJGcm9tVGVhbSh0ZWFtSWQsIHVzZXJJZCwgY2FsbGJhY2spO1xuICAgICAgICAgICAgICAgIGNsZWFyVXNlckNhY2hlKHVzZXJJZCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIGlmIChvcGVyYXRpb24gPT09ICdjcmVhdGUnKSB7XG4gICAgICAgICAgICBQeWRpb1VzZXJzLkNsaWVudC5zYXZlU2VsZWN0aW9uQXNUZWFtKHRlYW1JZCwgdXNlcnMsIGNhbGxiYWNrKTtcbiAgICAgICAgICAgIHVzZXJzLmZvckVhY2goZnVuY3Rpb24gKHVzZXIpIHtcbiAgICAgICAgICAgICAgICBjbGVhclVzZXJDYWNoZSh1c2VyLmdldElkID8gdXNlci5nZXRJZCgpIDogdXNlci5pZCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBmdW5jdGlvbiBUZWFtQ3JlYXRpb25Gb3JtKHByb3BzLCBjb250ZXh0KSB7XG4gICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBUZWFtQ3JlYXRpb25Gb3JtKTtcblxuICAgICAgICBfQ29tcG9uZW50LmNhbGwodGhpcywgcHJvcHMsIGNvbnRleHQpO1xuICAgICAgICB0aGlzLnN0YXRlID0geyB2YWx1ZTogJycgfTtcbiAgICB9XG5cbiAgICBUZWFtQ3JlYXRpb25Gb3JtLnByb3RvdHlwZS5vbkNoYW5nZSA9IGZ1bmN0aW9uIG9uQ2hhbmdlKGUsIHZhbHVlKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyB2YWx1ZTogdmFsdWUgfSk7XG4gICAgfTtcblxuICAgIFRlYW1DcmVhdGlvbkZvcm0ucHJvdG90eXBlLnN1Ym1pdENyZWF0aW9uRm9ybSA9IGZ1bmN0aW9uIHN1Ym1pdENyZWF0aW9uRm9ybSgpIHtcbiAgICAgICAgdmFyIHZhbHVlID0gdGhpcy5zdGF0ZS52YWx1ZTtcbiAgICAgICAgVGVhbUNyZWF0aW9uRm9ybS51cGRhdGVUZWFtVXNlcnMoeyBpZDogdmFsdWUgfSwgJ2NyZWF0ZScsIFtdLCB0aGlzLnByb3BzLm9uVGVhbUNyZWF0ZWQpO1xuICAgIH07XG5cbiAgICBUZWFtQ3JlYXRpb25Gb3JtLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgICAgIHZhciBnZXRNZXNzYWdlID0gdGhpcy5wcm9wcy5nZXRNZXNzYWdlO1xuXG4gICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICB7IHN0eWxlOiB7IHBhZGRpbmc6IDIwIH0gfSxcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgICAgICBnZXRNZXNzYWdlKDU5MSlcbiAgICAgICAgICAgICksXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFRleHRGaWVsZCwgeyBmbG9hdGluZ0xhYmVsVGV4dDogZ2V0TWVzc2FnZSg1NzgpLCB2YWx1ZTogdGhpcy5zdGF0ZS52YWx1ZSwgb25DaGFuZ2U6IHRoaXMub25DaGFuZ2UuYmluZCh0aGlzKSwgZnVsbFdpZHRoOiB0cnVlIH0pLFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgICAgICB7IHN0eWxlOiB7IHRleHRBbGlnbjogJ3JpZ2h0JywgcGFkZGluZ1RvcDogMTAgfSB9LFxuICAgICAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KEZsYXRCdXR0b24sIHsgbGFiZWw6IGdldE1lc3NhZ2UoNDkpLCBvblRvdWNoVGFwOiB0aGlzLnByb3BzLm9uQ2FuY2VsLmJpbmQodGhpcykgfSksXG4gICAgICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoRmxhdEJ1dHRvbiwgeyBsYWJlbDogZ2V0TWVzc2FnZSg1NzkpLCBzZWNvbmRhcnk6IHRydWUsIG9uVG91Y2hUYXA6IHRoaXMuc3VibWl0Q3JlYXRpb25Gb3JtLmJpbmQodGhpcykgfSlcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgfTtcblxuICAgIHJldHVybiBUZWFtQ3JlYXRpb25Gb3JtO1xufSkoQ29tcG9uZW50KTtcblxuVGVhbUNyZWF0aW9uRm9ybS5wcm9wVHlwZXMgPSB7XG4gICAgLyoqXG4gICAgICogQ2FsbGJhY2sgdHJpZ2dlcmVkIGFmdGVyIHRlYW0gY3JlYXRpb24gc3VjY2VlZGVkXG4gICAgICovXG4gICAgb25UZWFtQ3JlYXRlZDogUHJvcFR5cGVzLmZ1bmMuaXNSZXF1aXJlZCxcbiAgICAvKipcbiAgICAgKiBSZXF1ZXN0IG1vZGFsIGNsb3NlXG4gICAgICovXG4gICAgb25DYW5jZWw6IFByb3BUeXBlcy5mdW5jLmlzUmVxdWlyZWRcbn07XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IFRlYW1DcmVhdGlvbkZvcm0gPSBQeWRpb0NvbnRleHRDb25zdW1lcihUZWFtQ3JlYXRpb25Gb3JtKTtcblxuZXhwb3J0c1snZGVmYXVsdCddID0gVGVhbUNyZWF0aW9uRm9ybTtcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDA3LTIwMTcgQ2hhcmxlcyBkdSBKZXUgLSBBYnN0cml1bSBTQVMgPHRlYW0gKGF0KSBweWQuaW8+XG4gKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBQeWRpby5cbiAqXG4gKiBQeWRpbyBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFB5ZGlvIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIFB5ZGlvLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuICpcbiAqIFRoZSBsYXRlc3QgY29kZSBjYW4gYmUgZm91bmQgYXQgPGh0dHBzOi8vcHlkaW8uY29tPi5cbiAqL1xuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyAnZGVmYXVsdCc6IG9iaiB9OyB9XG5cbnZhciBfYWRkcmVzc2Jvb2tBZGRyZXNzQm9vayA9IHJlcXVpcmUoJy4vYWRkcmVzc2Jvb2svQWRkcmVzc0Jvb2snKTtcblxudmFyIF9hZGRyZXNzYm9va0FkZHJlc3NCb29rMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2FkZHJlc3Nib29rQWRkcmVzc0Jvb2spO1xuXG52YXIgX3JlcXVpcmUkcmVxdWlyZUxpYiA9IHJlcXVpcmUoJ3B5ZGlvL2h0dHAvcmVzb3VyY2VzLW1hbmFnZXInKS5yZXF1aXJlTGliKCdib290Jyk7XG5cbnZhciBBc3luY0NvbXBvbmVudCA9IF9yZXF1aXJlJHJlcXVpcmVMaWIuQXN5bmNDb21wb25lbnQ7XG5cbnZhciBfcmVxdWlyZSA9IHJlcXVpcmUoJ21hdGVyaWFsLXVpJyk7XG5cbnZhciBUZXh0RmllbGQgPSBfcmVxdWlyZS5UZXh0RmllbGQ7XG52YXIgQXV0b0NvbXBsZXRlID0gX3JlcXVpcmUuQXV0b0NvbXBsZXRlO1xudmFyIFJlZnJlc2hJbmRpY2F0b3IgPSBfcmVxdWlyZS5SZWZyZXNoSW5kaWNhdG9yO1xudmFyIEljb25CdXR0b24gPSBfcmVxdWlyZS5JY29uQnV0dG9uO1xudmFyIFBvcG92ZXIgPSBfcmVxdWlyZS5Qb3BvdmVyO1xuXG52YXIgUmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpO1xudmFyIEZ1bmNVdGlscyA9IHJlcXVpcmUoJ3B5ZGlvL3V0aWwvZnVuYycpO1xuXG4vKipcbiAqIFJlYWR5IHRvIHVzZSBhdXRvY29tcGxldGUgZmllbGQgdGhhdCB3aWxsIGxvYWQgdXNlcnMvZ3JvdXBzL3JvbGVzIGZyb21cbiAqIHRoZSBzZXJ2ZXIgKHVzaW5nIHVzZXJfbGlzdF9hdXRob3JpemVkX3VzZXJzIEFQSSkuXG4gKiBVc2VkIGZvciBzaGFyaW5nLCBhZGRyZXNzYm9va3MsIHNlbmQgZW1haWwsIGV0Yy5cbiAqXG4gKiBDYW4gYWxzbyBvcGVuIGEgXCJzZWxlY3Rvci1zdHlsZVwiIGFkcmVzcyBib29rLlxuICovXG52YXIgVXNlcnNMb2FkZXIgPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG4gICAgZGlzcGxheU5hbWU6ICdVc2Vyc0xvYWRlcicsXG5cbiAgICBwcm9wVHlwZXM6IHtcblxuICAgICAgICAvKipcbiAgICAgICAgICogTWV0aG9kIGNhbGxlZCB0byByZW5kZXIgYSBjb21tcG9uZW50LCB0YWtpbmcgYSBVc2VyT2JqZWN0IGFzIGlucHV0XG4gICAgICAgICAqL1xuICAgICAgICByZW5kZXJTdWdnZXN0aW9uOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYy5pc1JlcXVpcmVkLFxuICAgICAgICAvKipcbiAgICAgICAgICogQ2FsbGJhY2sgd2hlbiBhIHZhbHVlIGlzIGZpbmFsbHkgc2VsZWN0ZWRcbiAgICAgICAgICovXG4gICAgICAgIG9uVmFsdWVTZWxlY3RlZDogUmVhY3QuUHJvcFR5cGVzLmZ1bmMuaXNSZXF1aXJlZCxcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEZsb2F0aW5nIExhYmVsIFRleHQgZGlzcGxheWVkIG9uIHRoZSBmaWVsZFxuICAgICAgICAgKi9cbiAgICAgICAgZmllbGRMYWJlbDogUmVhY3QuUHJvcFR5cGVzLnN0cmluZy5pc1JlcXVpcmVkLFxuICAgICAgICAvKipcbiAgICAgICAgICogQXJyYXkgb2YgdmFsdWVzIHRvIGlnbm9yZVxuICAgICAgICAgKi9cbiAgICAgICAgZXhjbHVkZXM6IFJlYWN0LlByb3BUeXBlcy5hcnJheS5pc1JlcXVpcmVkLFxuICAgICAgICAvKipcbiAgICAgICAgICogRGlzcGxheSBvbmx5IHVzZXJzLCBubyBncm91cHMgbm9yIHJvbGVzXG4gICAgICAgICAqL1xuICAgICAgICB1c2Vyc09ubHk6IFJlYWN0LlByb3BUeXBlcy5ib29sLFxuICAgICAgICAvKipcbiAgICAgICAgICogRGlzcGxheSB1c2VycyBmcm9tIGxvY2FsIGRpcmVjdG9yeSBhbmQvb3IgZnJvbSByZW1vdGUuXG4gICAgICAgICAqL1xuICAgICAgICB1c2Vyc0Zyb206IFJlYWN0LlByb3BUeXBlcy5vbmVPZihbJ2xvY2FsJywgJ3JlbW90ZScsICdhbnknXSksXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBEbyBub3QgcHJvcG9zZSBhIFwiQ3JlYXRlIHVzZXJcIiBvcHRpb25cbiAgICAgICAgICovXG4gICAgICAgIGV4aXN0aW5nT25seTogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBbGxvdyBmcmVlIHR5cGluZ1xuICAgICAgICAgKi9cbiAgICAgICAgZnJlZVZhbHVlQWxsb3dlZDogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBXaWxsIGJlIHBhc3NlZCB0byB0aGUgcm9vdCBjb21wb25lbnRcbiAgICAgICAgICovXG4gICAgICAgIGNsYXNzTmFtZTogUmVhY3QuUHJvcFR5cGVzLnN0cmluZ1xuICAgIH0sXG5cbiAgICBnZXRJbml0aWFsU3RhdGU6IGZ1bmN0aW9uIGdldEluaXRpYWxTdGF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGRhdGFTb3VyY2U6IFtdLFxuICAgICAgICAgICAgbG9hZGluZzogZmFsc2UsXG4gICAgICAgICAgICBzZWFyY2hUZXh0OiAnJyxcbiAgICAgICAgICAgIG1pbkNoYXJzOiBwYXJzZUludChnbG9iYWwucHlkaW8uZ2V0UGx1Z2luQ29uZmlncyhcImNvcmUuY29uZlwiKS5nZXQoXCJVU0VSU19MSVNUX0NPTVBMRVRFX01JTl9DSEFSU1wiKSlcbiAgICAgICAgfTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogTG9hZHMgdmFsdWVzIGZyb20gc2VydmVyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGlucHV0IEN1cnJlbnRseSBzZWFyY2hlZCB0ZXh0XG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgQ2FsbGVkIHdpdGggdGhlIHZhbHVlc1xuICAgICAqL1xuICAgIHN1Z2dlc3Rpb25Mb2FkZXI6IGZ1bmN0aW9uIHN1Z2dlc3Rpb25Mb2FkZXIoaW5wdXQsIGNhbGxiYWNrKSB7XG4gICAgICAgIHZhciBleGNsdWRlcyA9IHRoaXMucHJvcHMuZXhjbHVkZXM7XG4gICAgICAgIHZhciBkaXNhbGxvd1RlbXBvcmFyeSA9IHRoaXMucHJvcHMuZXhpc3RpbmdPbmx5ICYmICF0aGlzLnByb3BzLmZyZWVWYWx1ZUFsbG93ZWQ7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBsb2FkaW5nOiB0aGlzLnN0YXRlLmxvYWRpbmcgKyAxIH0pO1xuICAgICAgICBQeWRpb1VzZXJzLkNsaWVudC5hdXRob3JpemVkVXNlcnNTdGFydGluZ1dpdGgoaW5wdXQsIChmdW5jdGlvbiAodXNlcnMpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBsb2FkaW5nOiB0aGlzLnN0YXRlLmxvYWRpbmcgLSAxIH0pO1xuICAgICAgICAgICAgaWYgKGRpc2FsbG93VGVtcG9yYXJ5KSB7XG4gICAgICAgICAgICAgICAgdXNlcnMgPSB1c2Vycy5maWx0ZXIoZnVuY3Rpb24gKHVzZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICF1c2VyLmdldFRlbXBvcmFyeSgpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGV4Y2x1ZGVzICYmIGV4Y2x1ZGVzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHVzZXJzID0gdXNlcnMuZmlsdGVyKGZ1bmN0aW9uICh1c2VyKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBleGNsdWRlcy5pbmRleE9mKHVzZXIuZ2V0SWQoKSkgPT0gLTE7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYWxsYmFjayh1c2Vycyk7XG4gICAgICAgIH0pLmJpbmQodGhpcyksIHRoaXMucHJvcHMudXNlcnNPbmx5LCB0aGlzLnByb3BzLmV4aXN0aW5nT25seSk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIENhbGxlZCB3aGVuIHRoZSBmaWVsZCBpcyB1cGRhdGVkXG4gICAgICogQHBhcmFtIHZhbHVlXG4gICAgICovXG4gICAgdGV4dEZpZWxkVXBkYXRlOiBmdW5jdGlvbiB0ZXh0RmllbGRVcGRhdGUodmFsdWUpIHtcblxuICAgICAgICB0aGlzLnNldFN0YXRlKHsgc2VhcmNoVGV4dDogdmFsdWUgfSk7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlLm1pbkNoYXJzICYmIHZhbHVlICYmIHZhbHVlLmxlbmd0aCA8IHRoaXMuc3RhdGUubWluQ2hhcnMpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmxvYWRCdWZmZXJlZCh2YWx1ZSwgMzUwKTtcbiAgICB9LFxuXG4gICAgZ2V0UGVuZGluZ1NlYXJjaFRleHQ6IGZ1bmN0aW9uIGdldFBlbmRpbmdTZWFyY2hUZXh0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5zdGF0ZS5zZWFyY2hUZXh0IHx8IGZhbHNlO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBEZWJvdW5jZWQgY2FsbCBmb3IgcmVuZGVyaW5nIHNlYXJjaFxuICAgICAqIEBwYXJhbSB2YWx1ZSB7c3RyaW5nfVxuICAgICAqIEBwYXJhbSB0aW1lb3V0IHtpbnR9XG4gICAgICovXG4gICAgbG9hZEJ1ZmZlcmVkOiBmdW5jdGlvbiBsb2FkQnVmZmVyZWQodmFsdWUsIHRpbWVvdXQpIHtcblxuICAgICAgICBpZiAoIXZhbHVlICYmIHRoaXMuX2VtcHR5VmFsdWVMaXN0KSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgZGF0YVNvdXJjZTogdGhpcy5fZW1wdHlWYWx1ZUxpc3QgfSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgRnVuY1V0aWxzLmJ1ZmZlckNhbGxiYWNrKCdyZW1vdGVfdXNlcnNfc2VhcmNoJywgdGltZW91dCwgKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBsb2FkaW5nOiB0cnVlIH0pO1xuICAgICAgICAgICAgdGhpcy5zdWdnZXN0aW9uTG9hZGVyKHZhbHVlLCAoZnVuY3Rpb24gKHVzZXJzKSB7XG4gICAgICAgICAgICAgICAgdmFyIGNydFZhbHVlRm91bmQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICB2YXIgdmFsdWVzID0gdXNlcnMubWFwKChmdW5jdGlvbiAodXNlck9iamVjdCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgY29tcG9uZW50ID0gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgICAgICAgIE1hdGVyaWFsVUkuTWVudUl0ZW0sXG4gICAgICAgICAgICAgICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5yZW5kZXJTdWdnZXN0aW9uKHVzZXJPYmplY3QpXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB1c2VyT2JqZWN0OiB1c2VyT2JqZWN0LFxuICAgICAgICAgICAgICAgICAgICAgICAgdGV4dDogdXNlck9iamVjdC5nZXRFeHRlbmRlZExhYmVsKCksXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogY29tcG9uZW50XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfSkuYmluZCh0aGlzKSk7XG4gICAgICAgICAgICAgICAgaWYgKCF2YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9lbXB0eVZhbHVlTGlzdCA9IHZhbHVlcztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGRhdGFTb3VyY2U6IHZhbHVlcywgbG9hZGluZzogZmFsc2UgfSk7XG4gICAgICAgICAgICB9KS5iaW5kKHRoaXMpKTtcbiAgICAgICAgfSkuYmluZCh0aGlzKSk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIENhbGxlZCB3aGVuIHVzZXIgc2VsZWN0cyBhIHZhbHVlIGZyb20gdGhlIGxpc3RcbiAgICAgKiBAcGFyYW0gdmFsdWVcbiAgICAgKiBAcGFyYW0gaW5kZXhcbiAgICAgKi9cbiAgICBvbkNvbXBsZXRlclJlcXVlc3Q6IGZ1bmN0aW9uIG9uQ29tcGxldGVyUmVxdWVzdCh2YWx1ZSwgaW5kZXgpIHtcblxuICAgICAgICBpZiAoaW5kZXggPT09IC0xKSB7XG4gICAgICAgICAgICB0aGlzLnN0YXRlLmRhdGFTb3VyY2UubWFwKGZ1bmN0aW9uIChlbnRyeSkge1xuICAgICAgICAgICAgICAgIGlmIChlbnRyeS50ZXh0ID09PSB2YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IGVudHJ5O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKHZhbHVlICYmICF2YWx1ZS51c2VyT2JqZWN0ICYmIHRoaXMucHJvcHMuZnJlZVZhbHVlQWxsb3dlZCkge1xuICAgICAgICAgICAgICAgIHZhciBmYWtlID0gbmV3IFB5ZGlvVXNlcnMuVXNlcih2YWx1ZSwgdmFsdWUsICd1c2VyJywgbnVsbCwgbnVsbCwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5vblZhbHVlU2VsZWN0ZWQoZmFrZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNlYXJjaFRleHQ6ICcnLCBkYXRhU291cmNlOiBbXSB9KTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHZhbHVlICYmIHZhbHVlLnVzZXJPYmplY3QpIHtcbiAgICAgICAgICAgIHZhciBvYmplY3QgPSB2YWx1ZS51c2VyT2JqZWN0O1xuICAgICAgICAgICAgaWYgKG9iamVjdC5nZXRUZW1wb3JhcnkoKSkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnByb3BzLmZyZWVWYWx1ZUFsbG93ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5vblZhbHVlU2VsZWN0ZWQob2JqZWN0KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgY3JlYXRlVXNlcjogb2JqZWN0LmdldExhYmVsKCkgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnByb3BzLm9uVmFsdWVTZWxlY3RlZChvYmplY3QpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNlYXJjaFRleHQ6ICcnLCBkYXRhU291cmNlOiBbXSB9KTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBUcmlnZ2VycyBvblZhbHVlU2VsZWN0ZWQgcHJvcHMgY2FsbGJhY2tcbiAgICAgKiBAcGFyYW0ge1B5ZGlvLlVzZXJ9IG5ld1VzZXJcbiAgICAgKi9cbiAgICBvblVzZXJDcmVhdGVkOiBmdW5jdGlvbiBvblVzZXJDcmVhdGVkKG5ld1VzZXIpIHtcbiAgICAgICAgdGhpcy5wcm9wcy5vblZhbHVlU2VsZWN0ZWQobmV3VXNlcik7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBjcmVhdGVVc2VyOiBudWxsIH0pO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBDbG9zZSB1c2VyIGNyZWF0aW9uIGZvcm1cbiAgICAgKi9cbiAgICBvbkNyZWF0aW9uQ2FuY2VsbGVkOiBmdW5jdGlvbiBvbkNyZWF0aW9uQ2FuY2VsbGVkKCkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgY3JlYXRlVXNlcjogbnVsbCB9KTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogT3BlbiBhZGRyZXNzIGJvb2sgaW5zaWRlIGEgUG9wb3ZlclxuICAgICAqIEBwYXJhbSBldmVudFxuICAgICAqL1xuICAgIG9wZW5BZGRyZXNzQm9vazogZnVuY3Rpb24gb3BlbkFkZHJlc3NCb29rKGV2ZW50KSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgYWRkcmVzc0Jvb2tPcGVuOiB0cnVlLFxuICAgICAgICAgICAgYWRkcmVzc0Jvb2tBbmNob3I6IGV2ZW50LmN1cnJlbnRUYXJnZXRcbiAgICAgICAgfSk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIENsb3NlIGFkZHJlc3MgYm9vayBwb3BvdmVyXG4gICAgICovXG4gICAgY2xvc2VBZGRyZXNzQm9vazogZnVuY3Rpb24gY2xvc2VBZGRyZXNzQm9vaygpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGFkZHJlc3NCb29rT3BlbjogZmFsc2UgfSk7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFRyaWdnZXJlZCB3aGVuIHVzZXIgY2xpY2tzIG9uIGFuIGVudHJ5IGZyb20gYWRyZXNzIGJvb2suXG4gICAgICogQHBhcmFtIGl0ZW1cbiAgICAgKi9cbiAgICBvbkFkZHJlc3NCb29rSXRlbVNlbGVjdGVkOiBmdW5jdGlvbiBvbkFkZHJlc3NCb29rSXRlbVNlbGVjdGVkKGl0ZW0pIHtcbiAgICAgICAgdGhpcy5wcm9wcy5vblZhbHVlU2VsZWN0ZWQoaXRlbSk7XG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgICAgIHZhciBfc3RhdGUgPSB0aGlzLnN0YXRlO1xuICAgICAgICB2YXIgZGF0YVNvdXJjZSA9IF9zdGF0ZS5kYXRhU291cmNlO1xuICAgICAgICB2YXIgY3JlYXRlVXNlciA9IF9zdGF0ZS5jcmVhdGVVc2VyO1xuXG4gICAgICAgIHZhciBjb250YWluZXJTdHlsZSA9IHsgcG9zaXRpb246ICdyZWxhdGl2ZScsIG92ZXJmbG93OiAndmlzaWJsZScgfTtcblxuICAgICAgICAvKlxuICAgICAgICBpZihjcmVhdGVVc2VyKXtcbiAgICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9e2NvbnRhaW5lclN0eWxlfT5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBzdHlsZT17e3Bvc2l0aW9uOiAnYWJzb2x1dGUnLCB0b3A6IDczLCBsZWZ0OiAwLCByaWdodDogMCwgekluZGV4OiAxMH19PlxuICAgICAgICAgICAgICAgICAgICAgICAgPEFzeW5jQ29tcG9uZW50XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlPXtcIlB5ZGlvRm9ybVwifVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudE5hbWU9e1wiVXNlckNyZWF0aW9uRm9ybVwifVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdVc2VyTmFtZT17dGhpcy5zdGF0ZS5jcmVhdGVVc2VyfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uVXNlckNyZWF0ZWQ9e3RoaXMub25Vc2VyQ3JlYXRlZH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbkNhbmNlbD17dGhpcy5vbkNyZWF0aW9uQ2FuY2VsbGVkfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHB5ZGlvPXt0aGlzLnByb3BzLnB5ZGlvfVxuICAgICAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICApO1xuICAgICAgICAgfVxuICAgICAgICAqL1xuXG4gICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICB7IHN0eWxlOiBjb250YWluZXJTdHlsZSwgcmVmOiBmdW5jdGlvbiAoZWwpIHtcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMuX3BvcG92ZXJBbmNob3IgPSBlbDtcbiAgICAgICAgICAgICAgICB9IH0sXG4gICAgICAgICAgICAhY3JlYXRlVXNlciAmJiBSZWFjdC5jcmVhdGVFbGVtZW50KEF1dG9Db21wbGV0ZSwge1xuICAgICAgICAgICAgICAgIGZpbHRlcjogTWF0ZXJpYWxVSS5BdXRvQ29tcGxldGUubm9GaWx0ZXIsXG4gICAgICAgICAgICAgICAgZGF0YVNvdXJjZTogZGF0YVNvdXJjZSxcbiAgICAgICAgICAgICAgICBzZWFyY2hUZXh0OiB0aGlzLnN0YXRlLnNlYXJjaFRleHQsXG4gICAgICAgICAgICAgICAgb25VcGRhdGVJbnB1dDogdGhpcy50ZXh0RmllbGRVcGRhdGUsXG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lOiB0aGlzLnByb3BzLmNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgICBvcGVuT25Gb2N1czogdHJ1ZSxcbiAgICAgICAgICAgICAgICBmbG9hdGluZ0xhYmVsVGV4dDogdGhpcy5wcm9wcy5maWVsZExhYmVsLFxuICAgICAgICAgICAgICAgIHVuZGVybGluZVNob3c6ICF0aGlzLnByb3BzLnVuZGVybGluZUhpZGUsXG4gICAgICAgICAgICAgICAgZnVsbFdpZHRoOiB0cnVlLFxuICAgICAgICAgICAgICAgIG9uTmV3UmVxdWVzdDogdGhpcy5vbkNvbXBsZXRlclJlcXVlc3QsXG4gICAgICAgICAgICAgICAgbGlzdFN0eWxlOiB7IG1heEhlaWdodDogMzUwLCBvdmVyZmxvd1k6ICdhdXRvJyB9LFxuICAgICAgICAgICAgICAgIG9uRm9jdXM6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMubG9hZEJ1ZmZlcmVkKF90aGlzLnN0YXRlLnNlYXJjaFRleHQsIDEwMCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBjcmVhdGVVc2VyICYmIFJlYWN0LmNyZWF0ZUVsZW1lbnQoVGV4dEZpZWxkLCB7XG4gICAgICAgICAgICAgICAgZmxvYXRpbmdMYWJlbFRleHQ6IHRoaXMucHJvcHMuZmllbGRMYWJlbCxcbiAgICAgICAgICAgICAgICB2YWx1ZTogZ2xvYmFsLnB5ZGlvLk1lc3NhZ2VIYXNoWzQ4NV0gKyAnICgnICsgdGhpcy5zdGF0ZS5jcmVhdGVVc2VyICsgJyknLFxuICAgICAgICAgICAgICAgIGRpc2FibGVkOiB0cnVlLFxuICAgICAgICAgICAgICAgIGZ1bGxXaWR0aDogdHJ1ZSxcbiAgICAgICAgICAgICAgICB1bmRlcmxpbmVTaG93OiAhdGhpcy5wcm9wcy51bmRlcmxpbmVIaWRlXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICFjcmVhdGVVc2VyICYmIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgeyBzdHlsZTogeyBwb3NpdGlvbjogJ2Fic29sdXRlJywgcmlnaHQ6IDQsIGJvdHRvbTogMTQsIGhlaWdodDogMjAsIHdpZHRoOiAyMCB9IH0sXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChSZWZyZXNoSW5kaWNhdG9yLCB7XG4gICAgICAgICAgICAgICAgICAgIHNpemU6IDIwLFxuICAgICAgICAgICAgICAgICAgICBsZWZ0OiAwLFxuICAgICAgICAgICAgICAgICAgICB0b3A6IDAsXG4gICAgICAgICAgICAgICAgICAgIHN0YXR1czogdGhpcy5zdGF0ZS5sb2FkaW5nID8gJ2xvYWRpbmcnIDogJ2hpZGUnXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICksXG4gICAgICAgICAgICB0aGlzLnByb3BzLnNob3dBZGRyZXNzQm9vayAmJiAhY3JlYXRlVXNlciAmJiBSZWFjdC5jcmVhdGVFbGVtZW50KF9hZGRyZXNzYm9va0FkZHJlc3NCb29rMlsnZGVmYXVsdCddLCB7XG4gICAgICAgICAgICAgICAgbW9kZTogJ3BvcG92ZXInLFxuICAgICAgICAgICAgICAgIHB5ZGlvOiB0aGlzLnByb3BzLnB5ZGlvLFxuICAgICAgICAgICAgICAgIGxvYWRlclN0eWxlOiB7IHdpZHRoOiAzMjAsIGhlaWdodDogNDIwIH0sXG4gICAgICAgICAgICAgICAgb25JdGVtU2VsZWN0ZWQ6IHRoaXMub25BZGRyZXNzQm9va0l0ZW1TZWxlY3RlZCxcbiAgICAgICAgICAgICAgICB1c2Vyc0Zyb206IHRoaXMucHJvcHMudXNlcnNGcm9tLFxuICAgICAgICAgICAgICAgIGRpc2FibGVTZWFyY2g6IHRydWVcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICBQb3BvdmVyLFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgb3BlbjogY3JlYXRlVXNlcixcbiAgICAgICAgICAgICAgICAgICAgYW5jaG9yRWw6IHRoaXMuX3BvcG92ZXJBbmNob3IsXG4gICAgICAgICAgICAgICAgICAgIGFuY2hvck9yaWdpbjogeyBob3Jpem9udGFsOiAnbGVmdCcsIHZlcnRpY2FsOiAnYm90dG9tJyB9LFxuICAgICAgICAgICAgICAgICAgICB0YXJnZXRPcmlnaW46IHsgaG9yaXpvbnRhbDogJ2xlZnQnLCB2ZXJ0aWNhbDogJ3RvcCcgfSxcbiAgICAgICAgICAgICAgICAgICAgb25SZXF1ZXN0Q2xvc2U6IHRoaXMub25DcmVhdGlvbkNhbmNlbGxlZCxcbiAgICAgICAgICAgICAgICAgICAgY2FuQXV0b1Bvc2l0aW9uOiBmYWxzZVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgY3JlYXRlVXNlciAmJiBSZWFjdC5jcmVhdGVFbGVtZW50KEFzeW5jQ29tcG9uZW50LCB7XG4gICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZTogXCJQeWRpb0Zvcm1cIixcbiAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50TmFtZTogXCJVc2VyQ3JlYXRpb25Gb3JtXCIsXG5cbiAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHsgd2lkdGg6IDM1MCwgaGVpZ2h0OiAzMjAgfSxcbiAgICAgICAgICAgICAgICAgICAgbmV3VXNlck5hbWU6IHRoaXMuc3RhdGUuY3JlYXRlVXNlcixcbiAgICAgICAgICAgICAgICAgICAgb25Vc2VyQ3JlYXRlZDogdGhpcy5vblVzZXJDcmVhdGVkLFxuICAgICAgICAgICAgICAgICAgICBvbkNhbmNlbDogdGhpcy5vbkNyZWF0aW9uQ2FuY2VsbGVkLFxuICAgICAgICAgICAgICAgICAgICBweWRpbzogdGhpcy5wcm9wcy5weWRpb1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgfVxuXG59KTtcblxuZXhwb3J0c1snZGVmYXVsdCddID0gVXNlcnNMb2FkZXI7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTtcbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDE3IENoYXJsZXMgZHUgSmV1IC0gQWJzdHJpdW0gU0FTIDx0ZWFtIChhdCkgcHlkLmlvPlxuICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgUHlkaW8uXG4gKlxuICogUHlkaW8gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBQeWRpbyBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCBQeWRpby4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAqXG4gKiBUaGUgbGF0ZXN0IGNvZGUgY2FuIGJlIGZvdW5kIGF0IDxodHRwczovL3B5ZGlvLmNvbT4uXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG52YXIgX2V4dGVuZHMgPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uICh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTsgZm9yICh2YXIga2V5IGluIHNvdXJjZSkgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkgeyB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldOyB9IH0gfSByZXR1cm4gdGFyZ2V0OyB9O1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyAnZGVmYXVsdCc6IG9iaiB9OyB9XG5cbnZhciBfTmVzdGVkTGlzdEl0ZW0gPSByZXF1aXJlKCcuL05lc3RlZExpc3RJdGVtJyk7XG5cbnZhciBfTmVzdGVkTGlzdEl0ZW0yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfTmVzdGVkTGlzdEl0ZW0pO1xuXG52YXIgX1VzZXJzTGlzdCA9IHJlcXVpcmUoJy4vVXNlcnNMaXN0Jyk7XG5cbnZhciBfVXNlcnNMaXN0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1VzZXJzTGlzdCk7XG5cbnZhciBfUmlnaHRQYW5lbENhcmQgPSByZXF1aXJlKCcuL1JpZ2h0UGFuZWxDYXJkJyk7XG5cbnZhciBfUmlnaHRQYW5lbENhcmQyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfUmlnaHRQYW5lbENhcmQpO1xuXG52YXIgX1NlYXJjaFBhbmVsID0gcmVxdWlyZSgnLi9TZWFyY2hQYW5lbCcpO1xuXG52YXIgX1NlYXJjaFBhbmVsMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1NlYXJjaFBhbmVsKTtcblxudmFyIF9Mb2FkZXJzID0gcmVxdWlyZSgnLi9Mb2FkZXJzJyk7XG5cbnZhciBfTG9hZGVyczIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9Mb2FkZXJzKTtcblxudmFyIF9UZWFtQ3JlYXRpb25Gb3JtID0gcmVxdWlyZSgnLi4vVGVhbUNyZWF0aW9uRm9ybScpO1xuXG52YXIgX1RlYW1DcmVhdGlvbkZvcm0yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfVGVhbUNyZWF0aW9uRm9ybSk7XG5cbnZhciBSZWFjdCA9IHJlcXVpcmUoJ3JlYWN0Jyk7XG52YXIgUHlkaW8gPSByZXF1aXJlKCdweWRpbycpO1xuXG52YXIgX1B5ZGlvJHJlcXVpcmVMaWIgPSBQeWRpby5yZXF1aXJlTGliKCdib290Jyk7XG5cbnZhciBBc3luY0NvbXBvbmVudCA9IF9QeWRpbyRyZXF1aXJlTGliLkFzeW5jQ29tcG9uZW50O1xudmFyIFB5ZGlvQ29udGV4dENvbnN1bWVyID0gX1B5ZGlvJHJlcXVpcmVMaWIuUHlkaW9Db250ZXh0Q29uc3VtZXI7XG5cbnZhciBfcmVxdWlyZSA9IHJlcXVpcmUoJ21hdGVyaWFsLXVpJyk7XG5cbnZhciBQb3BvdmVyID0gX3JlcXVpcmUuUG9wb3ZlcjtcbnZhciBJY29uQnV0dG9uID0gX3JlcXVpcmUuSWNvbkJ1dHRvbjtcblxudmFyIF9yZXF1aXJlMiA9IHJlcXVpcmUoJ21hdGVyaWFsLXVpL3N0eWxlcycpO1xuXG52YXIgbXVpVGhlbWVhYmxlID0gX3JlcXVpcmUyLm11aVRoZW1lYWJsZTtcbnZhciBjb2xvcnMgPSBfcmVxdWlyZTIuY29sb3JzO1xuXG4vKipcbiAqIEhpZ2ggbGV2ZWwgY29tcG9uZW50IHRvIGJyb3dzZSB1c2VycywgZ3JvdXBzIGFuZCB0ZWFtcywgZWl0aGVyIGluIGEgbGFyZ2UgZm9ybWF0IChtb2RlPSdib29rJykgb3IgYSBtb3JlIGNvbXBhY3RcbiAqIGZvcm1hdCAobW9kZT0nc2VsZWN0b3InfCdwb3BvdmVyJykuXG4gKiBBZGRyZXNzIGJvb2sgYWxsb3dzIHRvIGNyZWF0ZSBleHRlcm5hbCB1c2VycywgdGVhbXMsIGFuZCBhbHNvIHRvIGJyb3dzZSB0cnVzdGVkIHNlcnZlciBkaXJlY3RvcmllcyBpZiBGZWRlcmF0ZWQgU2hhcmluZ1xuICogaXMgYWN0aXZlLlxuICovXG52YXIgQWRkcmVzc0Jvb2sgPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG4gICAgZGlzcGxheU5hbWU6ICdBZGRyZXNzQm9vaycsXG5cbiAgICBwcm9wVHlwZXM6IHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIE1haW4gaW5zdGFuY2Ugb2YgcHlkaW9cbiAgICAgICAgICovXG4gICAgICAgIHB5ZGlvOiBSZWFjdC5Qcm9wVHlwZXMuaW5zdGFuY2VPZihQeWRpbyksXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBEaXNwbGF5IG1vZGUsIGVpdGhlciBsYXJnZSAoYm9vaykgb3Igc21hbGwgcGlja2VyICgnc2VsZWN0b3InLCAncG9wb3ZlcicpLlxuICAgICAgICAgKi9cbiAgICAgICAgbW9kZTogUmVhY3QuUHJvcFR5cGVzLm9uZU9mKFsnYm9vaycsICdzZWxlY3RvcicsICdwb3BvdmVyJ10pLmlzUmVxdWlyZWQsXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDYWxsYmFjayB0cmlnZ2VyZWQgaW4gJ3NlbGVjdG9yJyBtb2RlIHdoZW5ldmVyIGFuIGl0ZW0gaXMgY2xpY2tlZC5cbiAgICAgICAgICovXG4gICAgICAgIG9uSXRlbVNlbGVjdGVkOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgICAgICAgLyoqXG4gICAgICAgICAqIERpc3BsYXkgdXNlcnMgb25seSwgbm8gdGVhbXMgb3IgZ3JvdXBzXG4gICAgICAgICAqL1xuICAgICAgICB1c2Vyc09ubHk6IFJlYWN0LlByb3BUeXBlcy5ib29sLFxuICAgICAgICAvKipcbiAgICAgICAgICogQ2hvb3NlIHZhcmlvdXMgdXNlciBzb3VyY2VzLCBlaXRoZXIgdGhlIGxvY2FsIGRpcmVjdG9yeSBvciByZW1vdGUgKCA9IHRydXN0ZWQgKSBzZXJ2ZXJzLlxuICAgICAgICAgKi9cbiAgICAgICAgdXNlcnNGcm9tOiBSZWFjdC5Qcm9wVHlwZXMub25lT2YoWydsb2NhbCcsICdyZW1vdGUnLCAnYW55J10pLFxuICAgICAgICAvKipcbiAgICAgICAgICogRGlzYWJsZSB0aGUgc2VhcmNoIGVuZ2luZVxuICAgICAgICAgKi9cbiAgICAgICAgZGlzYWJsZVNlYXJjaDogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGVtZSBvYmplY3QgcGFzc2VkIGJ5IG11aVRoZW1lYWJsZSgpIHdyYXBwZXJcbiAgICAgICAgICovXG4gICAgICAgIG11aVRoZW1lOiBSZWFjdC5Qcm9wVHlwZXMub2JqZWN0LFxuICAgICAgICAvKipcbiAgICAgICAgICogV2lsbCBiZSBwYXNzZWQgdG8gdGhlIFBvcG92ZXIgb2JqZWN0XG4gICAgICAgICAqL1xuICAgICAgICBwb3BvdmVyU3R5bGU6IFJlYWN0LlByb3BUeXBlcy5vYmplY3QsXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBVc2VkIGFzIGEgYnV0dG9uIHRvIG9wZW4gdGhlIHNlbGVjdG9yIGluIGEgcG9wb3ZlclxuICAgICAgICAgKi9cbiAgICAgICAgcG9wb3ZlckJ1dHRvbjogUmVhY3QuUHJvcFR5cGVzLm9iamVjdCxcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFdpbGwgYmUgcGFzc2VkIHRvIHRoZSBQb3BvdmVyIGNvbnRhaW5lciBvYmplY3RcbiAgICAgICAgICovXG4gICAgICAgIHBvcG92ZXJDb250YWluZXJTdHlsZTogUmVhY3QuUHJvcFR5cGVzLm9iamVjdCxcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFdpbGwgYmUgcGFzc2VkIHRvIHRoZSBQb3BvdmVyIEljb24gQnV0dG9uLlxuICAgICAgICAgKi9cbiAgICAgICAgcG9wb3Zlckljb25CdXR0b25TdHlsZTogUmVhY3QuUHJvcFR5cGVzLm9iamVjdFxuICAgIH0sXG5cbiAgICBnZXREZWZhdWx0UHJvcHM6IGZ1bmN0aW9uIGdldERlZmF1bHRQcm9wcygpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIG1vZGU6ICdib29rJyxcbiAgICAgICAgICAgIHVzZXJzT25seTogZmFsc2UsXG4gICAgICAgICAgICB1c2Vyc0Zyb206ICdhbnknLFxuICAgICAgICAgICAgdGVhbXNPbmx5OiBmYWxzZSxcbiAgICAgICAgICAgIGRpc2FibGVTZWFyY2g6IGZhbHNlXG4gICAgICAgIH07XG4gICAgfSxcblxuICAgIGdldEluaXRpYWxTdGF0ZTogZnVuY3Rpb24gZ2V0SW5pdGlhbFN0YXRlKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgICAgIHZhciBfcHJvcHMgPSB0aGlzLnByb3BzO1xuICAgICAgICB2YXIgcHlkaW8gPSBfcHJvcHMucHlkaW87XG4gICAgICAgIHZhciBtb2RlID0gX3Byb3BzLm1vZGU7XG4gICAgICAgIHZhciB1c2Vyc09ubHkgPSBfcHJvcHMudXNlcnNPbmx5O1xuICAgICAgICB2YXIgdXNlcnNGcm9tID0gX3Byb3BzLnVzZXJzRnJvbTtcbiAgICAgICAgdmFyIHRlYW1zT25seSA9IF9wcm9wcy50ZWFtc09ubHk7XG4gICAgICAgIHZhciBkaXNhYmxlU2VhcmNoID0gX3Byb3BzLmRpc2FibGVTZWFyY2g7XG5cbiAgICAgICAgdmFyIGdldE1lc3NhZ2UgPSBmdW5jdGlvbiBnZXRNZXNzYWdlKGlkKSB7XG4gICAgICAgICAgICByZXR1cm4gX3RoaXMucHJvcHMuZ2V0TWVzc2FnZShpZCwgJycpO1xuICAgICAgICB9O1xuICAgICAgICB2YXIgY29uZkNvbmZpZ3MgPSBweWRpby5nZXRQbHVnaW5Db25maWdzKCdjb3JlLmNvbmYnKTtcblxuICAgICAgICB2YXIgcm9vdCA9IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKHRlYW1zT25seSkge1xuICAgICAgICAgICAgcm9vdCA9IHtcbiAgICAgICAgICAgICAgICBpZDogJ3RlYW1zJyxcbiAgICAgICAgICAgICAgICBsYWJlbDogZ2V0TWVzc2FnZSg1NjgpLFxuICAgICAgICAgICAgICAgIGNoaWxkcmVuTG9hZGVyOiBfTG9hZGVyczJbJ2RlZmF1bHQnXS5sb2FkVGVhbXMsXG4gICAgICAgICAgICAgICAgX3BhcmVudDogbnVsbCxcbiAgICAgICAgICAgICAgICBfbm90U2VsZWN0YWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBhY3Rpb25zOiB7XG4gICAgICAgICAgICAgICAgICAgIHR5cGU6ICd0ZWFtcycsXG4gICAgICAgICAgICAgICAgICAgIGNyZWF0ZTogJysgJyArIGdldE1lc3NhZ2UoNTY5KSxcbiAgICAgICAgICAgICAgICAgICAgcmVtb3ZlOiBnZXRNZXNzYWdlKDU3MCksXG4gICAgICAgICAgICAgICAgICAgIG11bHRpcGxlOiB0cnVlXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgcm9vdDogcm9vdCxcbiAgICAgICAgICAgICAgICBzZWxlY3RlZEl0ZW06IHJvb3QsXG4gICAgICAgICAgICAgICAgbG9hZGluZzogZmFsc2UsXG4gICAgICAgICAgICAgICAgcmlnaHRQYW5lSXRlbTogbnVsbFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJvb3QgPSB7XG4gICAgICAgICAgICBpZDogJ3Jvb3QnLFxuICAgICAgICAgICAgbGFiZWw6IGdldE1lc3NhZ2UoNTkyKSxcbiAgICAgICAgICAgIHR5cGU6ICdyb290JyxcbiAgICAgICAgICAgIGNvbGxlY3Rpb25zOiBbXVxuICAgICAgICB9O1xuICAgICAgICBpZiAodXNlcnNGcm9tICE9PSAncmVtb3RlJykge1xuICAgICAgICAgICAgaWYgKGNvbmZDb25maWdzLmdldCgnVVNFUl9DUkVBVEVfVVNFUlMnKSkge1xuICAgICAgICAgICAgICAgIHJvb3QuY29sbGVjdGlvbnMucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgIGlkOiAnZXh0JyxcbiAgICAgICAgICAgICAgICAgICAgbGFiZWw6IGdldE1lc3NhZ2UoNTkzKSxcbiAgICAgICAgICAgICAgICAgICAgLy9pY29uOidtZGkgbWRpLWFjY291bnQtbmV0d29yaycsXG4gICAgICAgICAgICAgICAgICAgIGl0ZW1zTG9hZGVyOiBfTG9hZGVyczJbJ2RlZmF1bHQnXS5sb2FkRXh0ZXJuYWxVc2VycyxcbiAgICAgICAgICAgICAgICAgICAgX3BhcmVudDogcm9vdCxcbiAgICAgICAgICAgICAgICAgICAgX25vdFNlbGVjdGFibGU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIGFjdGlvbnM6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICd1c2VycycsXG4gICAgICAgICAgICAgICAgICAgICAgICBjcmVhdGU6ICcrICcgKyBnZXRNZXNzYWdlKDQ4NCksXG4gICAgICAgICAgICAgICAgICAgICAgICByZW1vdmU6IGdldE1lc3NhZ2UoNTgyKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG11bHRpcGxlOiB0cnVlXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghdXNlcnNPbmx5KSB7XG4gICAgICAgICAgICAgICAgcm9vdC5jb2xsZWN0aW9ucy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgaWQ6ICd0ZWFtcycsXG4gICAgICAgICAgICAgICAgICAgIGxhYmVsOiBnZXRNZXNzYWdlKDU2OCksXG4gICAgICAgICAgICAgICAgICAgIC8vaWNvbjogJ21kaSBtZGktYWNjb3VudC1tdWx0aXBsZScsXG4gICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuTG9hZGVyOiBfTG9hZGVyczJbJ2RlZmF1bHQnXS5sb2FkVGVhbXMsXG4gICAgICAgICAgICAgICAgICAgIF9wYXJlbnQ6IHJvb3QsXG4gICAgICAgICAgICAgICAgICAgIF9ub3RTZWxlY3RhYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBhY3Rpb25zOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAndGVhbXMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlOiAnKyAnICsgZ2V0TWVzc2FnZSg1NjkpLFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlOiBnZXRNZXNzYWdlKDU3MCksXG4gICAgICAgICAgICAgICAgICAgICAgICBtdWx0aXBsZTogdHJ1ZVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoY29uZkNvbmZpZ3MuZ2V0KCdBTExPV19DUk9TU1VTRVJTX1NIQVJJTkcnKSkge1xuICAgICAgICAgICAgICAgIHZhciBncm91cE9yVXNlcnMgPSBjb25mQ29uZmlncy5nZXQoJ0FERFJFU1NCT09LX0dST1VQX09SX1VTRVJTJyk7XG4gICAgICAgICAgICAgICAgaWYgKGdyb3VwT3JVc2VycyAmJiBncm91cE9yVXNlcnMuZ3JvdXBfc3dpdGNoX3ZhbHVlKSBncm91cE9yVXNlcnMgPSBncm91cE9yVXNlcnMuZ3JvdXBfc3dpdGNoX3ZhbHVlO2Vsc2UgZ3JvdXBPclVzZXJzID0gJ2JvdGgnO1xuXG4gICAgICAgICAgICAgICAgaWYgKGdyb3VwT3JVc2VycyA9PT0gJ3NlYXJjaCcpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFkaXNhYmxlU2VhcmNoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByb290LmNvbGxlY3Rpb25zLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlkOiAnc2VhcmNoJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbDogZ2V0TWVzc2FnZSg1ODMpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vaWNvbjonbWRpIG1kaS1hY2NvdW50LXNlYXJjaCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ3NlYXJjaCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3BhcmVudDogcm9vdCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfbm90U2VsZWN0YWJsZTogdHJ1ZVxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByb290LmNvbGxlY3Rpb25zLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgaWQ6ICdBSlhQX0dSUF8vJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsOiBnZXRNZXNzYWdlKDU4NCksXG4gICAgICAgICAgICAgICAgICAgICAgICAvL2ljb246J21kaSBtZGktYWNjb3VudC1ib3gnLFxuICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW5Mb2FkZXI6IGdyb3VwT3JVc2VycyA9PT0gJ2JvdGgnIHx8IGdyb3VwT3JVc2VycyA9PT0gJ2dyb3VwcycgPyBfTG9hZGVyczJbJ2RlZmF1bHQnXS5sb2FkR3JvdXBzIDogbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW1zTG9hZGVyOiBncm91cE9yVXNlcnMgPT09ICdib3RoJyB8fCBncm91cE9yVXNlcnMgPT09ICd1c2VycycgPyBfTG9hZGVyczJbJ2RlZmF1bHQnXS5sb2FkR3JvdXBVc2VycyA6IG51bGwsXG4gICAgICAgICAgICAgICAgICAgICAgICBfcGFyZW50OiByb290LFxuICAgICAgICAgICAgICAgICAgICAgICAgX25vdFNlbGVjdGFibGU6IHRydWVcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdmFyIG9jc1JlbW90ZXMgPSBweWRpby5nZXRQbHVnaW5Db25maWdzKCdjb3JlLm9jcycpLmdldCgnVFJVU1RFRF9TRVJWRVJTJyk7XG4gICAgICAgIGlmIChvY3NSZW1vdGVzICYmICF1c2Vyc09ubHkgJiYgdXNlcnNGcm9tICE9PSAnbG9jYWwnKSB7XG4gICAgICAgICAgICB2YXIgcmVtb3RlcyA9IEpTT04ucGFyc2Uob2NzUmVtb3Rlcyk7XG4gICAgICAgICAgICB2YXIgcmVtb3Rlc05vZGVzID0ge1xuICAgICAgICAgICAgICAgIGlkOiAncmVtb3RlcycsXG4gICAgICAgICAgICAgICAgbGFiZWw6IGdldE1lc3NhZ2UoNTk0KSxcbiAgICAgICAgICAgICAgICAvL2ljb246J21kaSBtZGktc2VydmVyJyxcbiAgICAgICAgICAgICAgICBjb2xsZWN0aW9uczogW10sXG4gICAgICAgICAgICAgICAgX3BhcmVudDogcm9vdCxcbiAgICAgICAgICAgICAgICBfbm90U2VsZWN0YWJsZTogdHJ1ZVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGZvciAodmFyIGsgaW4gcmVtb3Rlcykge1xuICAgICAgICAgICAgICAgIGlmICghcmVtb3Rlcy5oYXNPd25Qcm9wZXJ0eShrKSkgY29udGludWU7XG4gICAgICAgICAgICAgICAgcmVtb3Rlc05vZGVzLmNvbGxlY3Rpb25zLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICBpZDogayxcbiAgICAgICAgICAgICAgICAgICAgbGFiZWw6IHJlbW90ZXNba10sXG4gICAgICAgICAgICAgICAgICAgIGljb246ICdtZGkgbWRpLXNlcnZlci1uZXR3b3JrJyxcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogJ3JlbW90ZScsXG4gICAgICAgICAgICAgICAgICAgIF9wYXJlbnQ6IHJlbW90ZXNOb2RlcyxcbiAgICAgICAgICAgICAgICAgICAgX25vdFNlbGVjdGFibGU6IHRydWVcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChyZW1vdGVzTm9kZXMuY29sbGVjdGlvbnMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgcm9vdC5jb2xsZWN0aW9ucy5wdXNoKHJlbW90ZXNOb2Rlcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcm9vdDogcm9vdCxcbiAgICAgICAgICAgIHNlbGVjdGVkSXRlbTogbW9kZSA9PT0gJ3NlbGVjdG9yJyA/IHJvb3QgOiByb290LmNvbGxlY3Rpb25zWzBdLFxuICAgICAgICAgICAgbG9hZGluZzogZmFsc2UsXG4gICAgICAgICAgICByaWdodFBhbmVJdGVtOiBudWxsXG4gICAgICAgIH07XG4gICAgfSxcblxuICAgIGNvbXBvbmVudERpZE1vdW50OiBmdW5jdGlvbiBjb21wb25lbnREaWRNb3VudCgpIHtcbiAgICAgICAgdGhpcy5zdGF0ZS5zZWxlY3RlZEl0ZW0gJiYgdGhpcy5vbkZvbGRlckNsaWNrZWQodGhpcy5zdGF0ZS5zZWxlY3RlZEl0ZW0pO1xuICAgIH0sXG5cbiAgICBvbkZvbGRlckNsaWNrZWQ6IGZ1bmN0aW9uIG9uRm9sZGVyQ2xpY2tlZChpdGVtKSB7XG4gICAgICAgIHZhciBfdGhpczIgPSB0aGlzO1xuXG4gICAgICAgIHZhciBjYWxsYmFjayA9IGFyZ3VtZW50cy5sZW5ndGggPD0gMSB8fCBhcmd1bWVudHNbMV0gPT09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6IGFyZ3VtZW50c1sxXTtcblxuICAgICAgICAvLyBTcGVjaWFsIGNhc2UgZm9yIHRlYW1zXG4gICAgICAgIGlmIChpdGVtLnR5cGUgPT09ICdncm91cCcgJiYgaXRlbS5pZC5pbmRleE9mKCcvQUpYUF9URUFNLycpID09PSAwKSB7XG4gICAgICAgICAgICB0aGlzLm9uVXNlckxpc3RJdGVtQ2xpY2tlZChpdGVtKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNldFN0YXRlKHsgbG9hZGluZzogdHJ1ZSB9KTtcblxuICAgICAgICBfTG9hZGVyczJbJ2RlZmF1bHQnXS5jaGlsZHJlbkFzUHJvbWlzZShpdGVtLCBmYWxzZSkudGhlbihmdW5jdGlvbiAoY2hpbGRyZW4pIHtcbiAgICAgICAgICAgIF9Mb2FkZXJzMlsnZGVmYXVsdCddLmNoaWxkcmVuQXNQcm9taXNlKGl0ZW0sIHRydWUpLnRoZW4oZnVuY3Rpb24gKGNoaWxkcmVuKSB7XG4gICAgICAgICAgICAgICAgX3RoaXMyLnNldFN0YXRlKHsgc2VsZWN0ZWRJdGVtOiBpdGVtLCBsb2FkaW5nOiBmYWxzZSB9LCBjYWxsYmFjayk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfSxcblxuICAgIG9uVXNlckxpc3RJdGVtQ2xpY2tlZDogZnVuY3Rpb24gb25Vc2VyTGlzdEl0ZW1DbGlja2VkKGl0ZW0pIHtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMub25JdGVtU2VsZWN0ZWQpIHtcbiAgICAgICAgICAgIHZhciB1T2JqZWN0ID0gbmV3IFB5ZGlvVXNlcnMuVXNlcihpdGVtLmlkLCBpdGVtLmxhYmVsLCBpdGVtLnR5cGUsIGl0ZW0uZ3JvdXAsIGl0ZW0uYXZhdGFyLCBpdGVtLnRlbXBvcmFyeSwgaXRlbS5leHRlcm5hbCk7XG4gICAgICAgICAgICBpZiAoaXRlbS50cnVzdGVkX3NlcnZlcl9pZCkge1xuICAgICAgICAgICAgICAgIHVPYmplY3QudHJ1c3RlZFNlcnZlcklkID0gaXRlbS50cnVzdGVkX3NlcnZlcl9pZDtcbiAgICAgICAgICAgICAgICB1T2JqZWN0LnRydXN0ZWRTZXJ2ZXJMYWJlbCA9IGl0ZW0udHJ1c3RlZF9zZXJ2ZXJfbGFiZWw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnByb3BzLm9uSXRlbVNlbGVjdGVkKHVPYmplY3QpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHJpZ2h0UGFuZUl0ZW06IGl0ZW0gfSk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgb25DcmVhdGVBY3Rpb246IGZ1bmN0aW9uIG9uQ3JlYXRlQWN0aW9uKGl0ZW0pIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGNyZWF0ZURpYWxvZ0l0ZW06IGl0ZW0gfSk7XG4gICAgfSxcblxuICAgIGNsb3NlQ3JlYXRlRGlhbG9nQW5kUmVsb2FkOiBmdW5jdGlvbiBjbG9zZUNyZWF0ZURpYWxvZ0FuZFJlbG9hZCgpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGNyZWF0ZURpYWxvZ0l0ZW06IG51bGwgfSk7XG4gICAgICAgIHRoaXMucmVsb2FkQ3VycmVudE5vZGUoKTtcbiAgICB9LFxuXG4gICAgb25DYXJkVXBkYXRlQWN0aW9uOiBmdW5jdGlvbiBvbkNhcmRVcGRhdGVBY3Rpb24oaXRlbSkge1xuICAgICAgICBpZiAoaXRlbS5fcGFyZW50ICYmIGl0ZW0uX3BhcmVudCA9PT0gdGhpcy5zdGF0ZS5zZWxlY3RlZEl0ZW0pIHtcbiAgICAgICAgICAgIHRoaXMucmVsb2FkQ3VycmVudE5vZGUoKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBvbkRlbGV0ZUFjdGlvbjogZnVuY3Rpb24gb25EZWxldGVBY3Rpb24ocGFyZW50SXRlbSwgc2VsZWN0aW9uKSB7XG4gICAgICAgIGlmICghY29uZmlybSh0aGlzLnByb3BzLmdldE1lc3NhZ2UoMjc4KSkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBzd2l0Y2ggKHBhcmVudEl0ZW0uYWN0aW9ucy50eXBlKSB7XG4gICAgICAgICAgICBjYXNlICd1c2Vycyc6XG4gICAgICAgICAgICAgICAgc2VsZWN0aW9uLmZvckVhY2goKGZ1bmN0aW9uICh1c2VyKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlLnJpZ2h0UGFuZUl0ZW0gPT09IHVzZXIpIHRoaXMuc2V0U3RhdGUoeyByaWdodFBhbmVJdGVtOiBudWxsIH0pO1xuICAgICAgICAgICAgICAgICAgICBQeWRpb1VzZXJzLkNsaWVudC5kZWxldGVVc2VyKHVzZXIuaWQsIHRoaXMucmVsb2FkQ3VycmVudE5vZGUuYmluZCh0aGlzKSk7XG4gICAgICAgICAgICAgICAgfSkuYmluZCh0aGlzKSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICd0ZWFtcyc6XG4gICAgICAgICAgICAgICAgc2VsZWN0aW9uLmZvckVhY2goKGZ1bmN0aW9uICh0ZWFtKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlLnJpZ2h0UGFuZUl0ZW0gPT09IHRlYW0pIHRoaXMuc2V0U3RhdGUoeyByaWdodFBhbmVJdGVtOiBudWxsIH0pO1xuICAgICAgICAgICAgICAgICAgICBQeWRpb1VzZXJzLkNsaWVudC5kZWxldGVUZWFtKHRlYW0uaWQucmVwbGFjZSgnL0FKWFBfVEVBTS8nLCAnJyksIHRoaXMucmVsb2FkQ3VycmVudE5vZGUuYmluZCh0aGlzKSk7XG4gICAgICAgICAgICAgICAgfSkuYmluZCh0aGlzKSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICd0ZWFtJzpcbiAgICAgICAgICAgICAgICBfVGVhbUNyZWF0aW9uRm9ybTJbJ2RlZmF1bHQnXS51cGRhdGVUZWFtVXNlcnMocGFyZW50SXRlbSwgJ2RlbGV0ZScsIHNlbGVjdGlvbiwgdGhpcy5yZWxvYWRDdXJyZW50Tm9kZS5iaW5kKHRoaXMpKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgb3BlblBvcG92ZXI6IGZ1bmN0aW9uIG9wZW5Qb3BvdmVyKGV2ZW50KSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgcG9wb3Zlck9wZW46IHRydWUsXG4gICAgICAgICAgICBwb3BvdmVyQW5jaG9yOiBldmVudC5jdXJyZW50VGFyZ2V0XG4gICAgICAgIH0pO1xuICAgIH0sXG5cbiAgICBjbG9zZVBvcG92ZXI6IGZ1bmN0aW9uIGNsb3NlUG9wb3ZlcigpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHBvcG92ZXJPcGVuOiBmYWxzZSB9KTtcbiAgICB9LFxuXG4gICAgcmVsb2FkQ3VycmVudE5vZGU6IGZ1bmN0aW9uIHJlbG9hZEN1cnJlbnROb2RlKCkge1xuICAgICAgICB2YXIgX3RoaXMzID0gdGhpcztcblxuICAgICAgICB0aGlzLnN0YXRlLnNlbGVjdGVkSXRlbS5sZWFmTG9hZGVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMuc3RhdGUuc2VsZWN0ZWRJdGVtLmNvbGxlY3Rpb25zTG9hZGVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMub25Gb2xkZXJDbGlja2VkKHRoaXMuc3RhdGUuc2VsZWN0ZWRJdGVtLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpZiAoX3RoaXMzLnN0YXRlLnJpZ2h0UGFuZUl0ZW0pIHtcbiAgICAgICAgICAgICAgICAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgclBhbmVJZCA9IF90aGlzMy5zdGF0ZS5yaWdodFBhbmVJdGVtLmlkO1xuICAgICAgICAgICAgICAgICAgICB2YXIgZm91bmRJdGVtID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGxlYWZzID0gX3RoaXMzLnN0YXRlLnNlbGVjdGVkSXRlbS5sZWFmcyB8fCBbXTtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNvbGxlY3Rpb25zID0gX3RoaXMzLnN0YXRlLnNlbGVjdGVkSXRlbS5jb2xsZWN0aW9ucyB8fCBbXTtcbiAgICAgICAgICAgICAgICAgICAgW10uY29uY2F0KGxlYWZzLCBjb2xsZWN0aW9ucykuZm9yRWFjaChmdW5jdGlvbiAobGVhZikge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxlYWYuaWQgPT09IHJQYW5lSWQpIGZvdW5kSXRlbSA9IGxlYWY7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBfdGhpczMuc2V0U3RhdGUoeyByaWdodFBhbmVJdGVtOiBmb3VuZEl0ZW0gfSk7XG4gICAgICAgICAgICAgICAgfSkoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfSxcblxuICAgIHJlbG9hZEN1cnJlbnRBdFBhZ2U6IGZ1bmN0aW9uIHJlbG9hZEN1cnJlbnRBdFBhZ2UobGV0dGVyT3JSYW5nZSkge1xuICAgICAgICB0aGlzLnN0YXRlLnNlbGVjdGVkSXRlbS5sZWFmTG9hZGVkID0gZmFsc2U7XG4gICAgICAgIHRoaXMuc3RhdGUuc2VsZWN0ZWRJdGVtLmNvbGxlY3Rpb25zTG9hZGVkID0gZmFsc2U7XG4gICAgICAgIGlmIChsZXR0ZXJPclJhbmdlID09PSAtMSkge1xuICAgICAgICAgICAgdGhpcy5zdGF0ZS5zZWxlY3RlZEl0ZW0uY3VycmVudFBhcmFtcyA9IG51bGw7XG4gICAgICAgIH0gZWxzZSBpZiAobGV0dGVyT3JSYW5nZS5pbmRleE9mKCctJykgIT09IC0xKSB7XG4gICAgICAgICAgICB0aGlzLnN0YXRlLnNlbGVjdGVkSXRlbS5yYW5nZSA9IGxldHRlck9yUmFuZ2U7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnN0YXRlLnNlbGVjdGVkSXRlbS5yYW5nZSA9IG51bGw7XG4gICAgICAgICAgICB0aGlzLnN0YXRlLnNlbGVjdGVkSXRlbS5jdXJyZW50UGFyYW1zID0geyBhbHBoYV9wYWdlczogJ3RydWUnLCB2YWx1ZTogbGV0dGVyT3JSYW5nZSB9O1xuICAgICAgICB9XG4gICAgICAgIHRoaXMub25Gb2xkZXJDbGlja2VkKHRoaXMuc3RhdGUuc2VsZWN0ZWRJdGVtKTtcbiAgICB9LFxuXG4gICAgcmVsb2FkQ3VycmVudFdpdGhTZWFyY2g6IGZ1bmN0aW9uIHJlbG9hZEN1cnJlbnRXaXRoU2VhcmNoKHZhbHVlKSB7XG4gICAgICAgIGlmICghdmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMucmVsb2FkQ3VycmVudEF0UGFnZSgtMSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zdGF0ZS5zZWxlY3RlZEl0ZW0ubGVhZkxvYWRlZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLnN0YXRlLnNlbGVjdGVkSXRlbS5jb2xsZWN0aW9uc0xvYWRlZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLnN0YXRlLnNlbGVjdGVkSXRlbS5jdXJyZW50UGFyYW1zID0geyBoYXNfc2VhcmNoOiB0cnVlLCB2YWx1ZTogdmFsdWUsIGV4aXN0aW5nX29ubHk6IHRydWUgfTtcbiAgICAgICAgdGhpcy5vbkZvbGRlckNsaWNrZWQodGhpcy5zdGF0ZS5zZWxlY3RlZEl0ZW0pO1xuICAgIH0sXG5cbiAgICByZW5kZXI6IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgICAgdmFyIF90aGlzNCA9IHRoaXM7XG5cbiAgICAgICAgdmFyIF9wcm9wczIgPSB0aGlzLnByb3BzO1xuICAgICAgICB2YXIgbW9kZSA9IF9wcm9wczIubW9kZTtcbiAgICAgICAgdmFyIG11aVRoZW1lID0gX3Byb3BzMi5tdWlUaGVtZTtcbiAgICAgICAgdmFyIGdldE1lc3NhZ2UgPSBfcHJvcHMyLmdldE1lc3NhZ2U7XG5cbiAgICAgICAgaWYgKG1vZGUgPT09ICdwb3BvdmVyJykge1xuXG4gICAgICAgICAgICB2YXIgcG9wb3ZlclN0eWxlID0gdGhpcy5wcm9wcy5wb3BvdmVyU3R5bGUgfHwge307XG4gICAgICAgICAgICB2YXIgcG9wb3ZlckNvbnRhaW5lclN0eWxlID0gdGhpcy5wcm9wcy5wb3BvdmVyQ29udGFpbmVyU3R5bGUgfHwge307XG4gICAgICAgICAgICB2YXIgaWNvbkJ1dHRvblN0eWxlID0gdGhpcy5wcm9wcy5wb3BvdmVySWNvbkJ1dHRvblN0eWxlIHx8IHt9O1xuICAgICAgICAgICAgdmFyIGljb25CdXR0b24gPSBSZWFjdC5jcmVhdGVFbGVtZW50KEljb25CdXR0b24sIHtcbiAgICAgICAgICAgICAgICBzdHlsZTogX2V4dGVuZHMoeyBwb3NpdGlvbjogJ2Fic29sdXRlJywgcGFkZGluZzogMTUsIHpJbmRleDogMTAwLCByaWdodDogMCwgdG9wOiAyNSwgZGlzcGxheTogdGhpcy5zdGF0ZS5sb2FkaW5nID8gJ25vbmUnIDogJ2luaXRpYWwnIH0sIGljb25CdXR0b25TdHlsZSksXG4gICAgICAgICAgICAgICAgaWNvblN0eWxlOiB7IGZvbnRTaXplOiAxOSwgY29sb3I6ICdyZ2JhKDAsMCwwLDAuNiknIH0sXG4gICAgICAgICAgICAgICAgaWNvbkNsYXNzTmFtZTogJ21kaSBtZGktYm9vay1vcGVuLXZhcmlhbnQnLFxuICAgICAgICAgICAgICAgIG9uVG91Y2hUYXA6IHRoaXMub3BlblBvcG92ZXJcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKHRoaXMucHJvcHMucG9wb3ZlckJ1dHRvbikge1xuICAgICAgICAgICAgICAgIGljb25CdXR0b24gPSBSZWFjdC5jcmVhdGVFbGVtZW50KHRoaXMucHJvcHMucG9wb3ZlckJ1dHRvbi50eXBlLCBfZXh0ZW5kcyh7fSwgdGhpcy5wcm9wcy5wb3BvdmVyQnV0dG9uLnByb3BzLCB7IG9uVG91Y2hUYXA6IHRoaXMub3BlblBvcG92ZXIgfSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgJ3NwYW4nLFxuICAgICAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICAgICAgaWNvbkJ1dHRvbixcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICBQb3BvdmVyLFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvcGVuOiB0aGlzLnN0YXRlLnBvcG92ZXJPcGVuLFxuICAgICAgICAgICAgICAgICAgICAgICAgYW5jaG9yRWw6IHRoaXMuc3RhdGUucG9wb3ZlckFuY2hvcixcbiAgICAgICAgICAgICAgICAgICAgICAgIGFuY2hvck9yaWdpbjogeyBob3Jpem9udGFsOiAncmlnaHQnLCB2ZXJ0aWNhbDogJ3RvcCcgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldE9yaWdpbjogeyBob3Jpem9udGFsOiAnbGVmdCcsIHZlcnRpY2FsOiAndG9wJyB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgb25SZXF1ZXN0Q2xvc2U6IHRoaXMuY2xvc2VQb3BvdmVyLFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IF9leHRlbmRzKHsgbWFyZ2luTGVmdDogMjAgfSwgcG9wb3ZlclN0eWxlKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHpEZXB0aDogMlxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgICAgICAgICB7IHN0eWxlOiBfZXh0ZW5kcyh7IHdpZHRoOiAzMjAsIGhlaWdodDogNDIwIH0sIHBvcG92ZXJDb250YWluZXJTdHlsZSkgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoQWRkcmVzc0Jvb2ssIF9leHRlbmRzKHt9LCB0aGlzLnByb3BzLCB7IG1vZGU6ICdzZWxlY3RvcicgfSkpXG4gICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIF9zdGF0ZSA9IHRoaXMuc3RhdGU7XG4gICAgICAgIHZhciBzZWxlY3RlZEl0ZW0gPSBfc3RhdGUuc2VsZWN0ZWRJdGVtO1xuICAgICAgICB2YXIgcm9vdCA9IF9zdGF0ZS5yb290O1xuICAgICAgICB2YXIgcmlnaHRQYW5lSXRlbSA9IF9zdGF0ZS5yaWdodFBhbmVJdGVtO1xuICAgICAgICB2YXIgY3JlYXRlRGlhbG9nSXRlbSA9IF9zdGF0ZS5jcmVhdGVEaWFsb2dJdGVtO1xuXG4gICAgICAgIHZhciBsZWZ0Q29sdW1uU3R5bGUgPSB7XG4gICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IGNvbG9ycy5ncmV5MTAwLFxuICAgICAgICAgICAgd2lkdGg6IDI1NixcbiAgICAgICAgICAgIG92ZXJmbG93WTogJ2F1dG8nLFxuICAgICAgICAgICAgb3ZlcmZsb3dYOiAnaGlkZGVuJ1xuICAgICAgICB9O1xuICAgICAgICB2YXIgY2VudGVyQ29tcG9uZW50ID0gdW5kZWZpbmVkLFxuICAgICAgICAgICAgcmlnaHRQYW5lbCA9IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGxlZnRQYW5lbCA9IHVuZGVmaW5lZDtcblxuICAgICAgICBpZiAoc2VsZWN0ZWRJdGVtLmlkID09PSAnc2VhcmNoJykge1xuXG4gICAgICAgICAgICBjZW50ZXJDb21wb25lbnQgPSBSZWFjdC5jcmVhdGVFbGVtZW50KF9TZWFyY2hQYW5lbDJbJ2RlZmF1bHQnXSwge1xuICAgICAgICAgICAgICAgIGl0ZW06IHNlbGVjdGVkSXRlbSxcbiAgICAgICAgICAgICAgICB0aXRsZTogZ2V0TWVzc2FnZSg1ODMsICcnKSxcbiAgICAgICAgICAgICAgICBzZWFyY2hMYWJlbDogZ2V0TWVzc2FnZSg1OTUsICcnKSxcbiAgICAgICAgICAgICAgICBvbkl0ZW1DbGlja2VkOiB0aGlzLm9uVXNlckxpc3RJdGVtQ2xpY2tlZCxcbiAgICAgICAgICAgICAgICBvbkZvbGRlckNsaWNrZWQ6IHRoaXMub25Gb2xkZXJDbGlja2VkLFxuICAgICAgICAgICAgICAgIG1vZGU6IG1vZGVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2UgaWYgKHNlbGVjdGVkSXRlbS50eXBlID09PSAncmVtb3RlJykge1xuXG4gICAgICAgICAgICBjZW50ZXJDb21wb25lbnQgPSBSZWFjdC5jcmVhdGVFbGVtZW50KF9TZWFyY2hQYW5lbDJbJ2RlZmF1bHQnXSwge1xuICAgICAgICAgICAgICAgIGl0ZW06IHNlbGVjdGVkSXRlbSxcbiAgICAgICAgICAgICAgICBwYXJhbXM6IHsgdHJ1c3RlZF9zZXJ2ZXJfaWQ6IHNlbGVjdGVkSXRlbS5pZCB9LFxuICAgICAgICAgICAgICAgIHNlYXJjaExhYmVsOiBnZXRNZXNzYWdlKDU5NSwgJycpLFxuICAgICAgICAgICAgICAgIHRpdGxlOiBnZXRNZXNzYWdlKDU5NiwgJycpLnJlcGxhY2UoJyVzJywgc2VsZWN0ZWRJdGVtLmxhYmVsKSxcbiAgICAgICAgICAgICAgICBvbkl0ZW1DbGlja2VkOiB0aGlzLm9uVXNlckxpc3RJdGVtQ2xpY2tlZCxcbiAgICAgICAgICAgICAgICBvbkZvbGRlckNsaWNrZWQ6IHRoaXMub25Gb2xkZXJDbGlja2VkLFxuICAgICAgICAgICAgICAgIG1vZGU6IG1vZGVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgICB2YXIgZW1wdHlTdGF0ZVByaW1hcnkgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICB2YXIgZW1wdHlTdGF0ZVNlY29uZGFyeSA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIHZhciBvdGhlclByb3BzID0ge307XG4gICAgICAgICAgICBpZiAoc2VsZWN0ZWRJdGVtLmlkID09PSAndGVhbXMnKSB7XG4gICAgICAgICAgICAgICAgZW1wdHlTdGF0ZVByaW1hcnkgPSBnZXRNZXNzYWdlKDU3MSwgJycpO1xuICAgICAgICAgICAgICAgIGVtcHR5U3RhdGVTZWNvbmRhcnkgPSBnZXRNZXNzYWdlKDU3MiwgJycpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChzZWxlY3RlZEl0ZW0uaWQgPT09ICdleHQnKSB7XG4gICAgICAgICAgICAgICAgZW1wdHlTdGF0ZVByaW1hcnkgPSBnZXRNZXNzYWdlKDU4NSwgJycpO1xuICAgICAgICAgICAgICAgIGVtcHR5U3RhdGVTZWNvbmRhcnkgPSBnZXRNZXNzYWdlKDU4NiwgJycpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChzZWxlY3RlZEl0ZW0uaWQuaW5kZXhPZignQUpYUF9HUlBfLycpID09PSAwKSB7XG4gICAgICAgICAgICAgICAgb3RoZXJQcm9wcyA9IHtcbiAgICAgICAgICAgICAgICAgICAgc2hvd1N1YmhlYWRlcnM6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIHBhZ2luYXRvclR5cGU6ICEoc2VsZWN0ZWRJdGVtLmN1cnJlbnRQYXJhbXMgJiYgc2VsZWN0ZWRJdGVtLmN1cnJlbnRQYXJhbXMuaGFzX3NlYXJjaCkgJiYgJ2FscGhhJyxcbiAgICAgICAgICAgICAgICAgICAgcGFnaW5hdG9yQ2FsbGJhY2s6IHRoaXMucmVsb2FkQ3VycmVudEF0UGFnZS5iaW5kKHRoaXMpLFxuICAgICAgICAgICAgICAgICAgICBlbmFibGVTZWFyY2g6ICF0aGlzLnByb3BzLmRpc2FibGVTZWFyY2gsXG4gICAgICAgICAgICAgICAgICAgIHNlYXJjaExhYmVsOiBnZXRNZXNzYWdlKDU5NSwgJycpLFxuICAgICAgICAgICAgICAgICAgICBvblNlYXJjaDogdGhpcy5yZWxvYWRDdXJyZW50V2l0aFNlYXJjaC5iaW5kKHRoaXMpXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY2VudGVyQ29tcG9uZW50ID0gUmVhY3QuY3JlYXRlRWxlbWVudChfVXNlcnNMaXN0MlsnZGVmYXVsdCddLCBfZXh0ZW5kcyh7XG4gICAgICAgICAgICAgICAgaXRlbTogc2VsZWN0ZWRJdGVtLFxuICAgICAgICAgICAgICAgIG9uSXRlbUNsaWNrZWQ6IHRoaXMub25Vc2VyTGlzdEl0ZW1DbGlja2VkLFxuICAgICAgICAgICAgICAgIG9uRm9sZGVyQ2xpY2tlZDogdGhpcy5vbkZvbGRlckNsaWNrZWQsXG4gICAgICAgICAgICAgICAgb25DcmVhdGVBY3Rpb246IHRoaXMub25DcmVhdGVBY3Rpb24sXG4gICAgICAgICAgICAgICAgb25EZWxldGVBY3Rpb246IHRoaXMub25EZWxldGVBY3Rpb24sXG4gICAgICAgICAgICAgICAgbG9hZGluZzogdGhpcy5zdGF0ZS5sb2FkaW5nLFxuICAgICAgICAgICAgICAgIG1vZGU6IG1vZGUsXG4gICAgICAgICAgICAgICAgZW1wdHlTdGF0ZVByaW1hcnlUZXh0OiBlbXB0eVN0YXRlUHJpbWFyeSxcbiAgICAgICAgICAgICAgICBlbXB0eVN0YXRlU2Vjb25kYXJ5VGV4dDogZW1wdHlTdGF0ZVNlY29uZGFyeSxcbiAgICAgICAgICAgICAgICBvblRvdWNoVGFwOiB0aGlzLnN0YXRlLnJpZ2h0UGFuZUl0ZW0gPyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzNC5zZXRTdGF0ZSh7IHJpZ2h0UGFuZUl0ZW06IG51bGwgfSk7XG4gICAgICAgICAgICAgICAgfSA6IG51bGxcbiAgICAgICAgICAgIH0sIG90aGVyUHJvcHMpKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgcmlnaHRQYW5lbFN0eWxlID0gX2V4dGVuZHMoe30sIGxlZnRDb2x1bW5TdHlsZSwgeyB0cmFuc2Zvcm1PcmlnaW46ICdyaWdodCcsIGJhY2tncm91bmRDb2xvcjogJ3doaXRlJyB9KTtcbiAgICAgICAgaWYgKCFyaWdodFBhbmVJdGVtKSB7XG4gICAgICAgICAgICByaWdodFBhbmVsU3R5bGUgPSBfZXh0ZW5kcyh7fSwgcmlnaHRQYW5lbFN0eWxlLCB7IHRyYW5zZm9ybTogJ3RyYW5zbGF0ZVgoMjU2cHgpJywgd2lkdGg6IDAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmlnaHRQYW5lbCA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoX1JpZ2h0UGFuZWxDYXJkMlsnZGVmYXVsdCddLCB7XG4gICAgICAgICAgICBweWRpbzogdGhpcy5wcm9wcy5weWRpbyxcbiAgICAgICAgICAgIG9uUmVxdWVzdENsb3NlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgX3RoaXM0LnNldFN0YXRlKHsgcmlnaHRQYW5lSXRlbTogbnVsbCB9KTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzdHlsZTogcmlnaHRQYW5lbFN0eWxlLFxuICAgICAgICAgICAgb25DcmVhdGVBY3Rpb246IHRoaXMub25DcmVhdGVBY3Rpb24sXG4gICAgICAgICAgICBvbkRlbGV0ZUFjdGlvbjogdGhpcy5vbkRlbGV0ZUFjdGlvbixcbiAgICAgICAgICAgIG9uVXBkYXRlQWN0aW9uOiB0aGlzLm9uQ2FyZFVwZGF0ZUFjdGlvbixcbiAgICAgICAgICAgIGl0ZW06IHJpZ2h0UGFuZUl0ZW0gfSk7XG4gICAgICAgIGlmIChtb2RlID09PSAnYm9vaycpIHtcbiAgICAgICAgICAgIGxlZnRQYW5lbCA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgTWF0ZXJpYWxVSS5QYXBlcixcbiAgICAgICAgICAgICAgICB7IHpEZXB0aDogMCwgc3R5bGU6IF9leHRlbmRzKHt9LCBsZWZ0Q29sdW1uU3R5bGUsIHsgekluZGV4OiAyIH0pIH0sXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgICAgTWF0ZXJpYWxVSS5MaXN0LFxuICAgICAgICAgICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgICAgICAgICByb290LmNvbGxlY3Rpb25zLm1hcCgoZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KF9OZXN0ZWRMaXN0SXRlbTJbJ2RlZmF1bHQnXSwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleTogZS5pZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZDogc2VsZWN0ZWRJdGVtLmlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5lc3RlZExldmVsOiAwLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVudHJ5OiBlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uVG91Y2hUYXA6IHRoaXMub25Gb2xkZXJDbGlja2VkXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfSkuYmluZCh0aGlzKSlcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGRpYWxvZ1RpdGxlID0gdW5kZWZpbmVkLFxuICAgICAgICAgICAgZGlhbG9nQ29udGVudCA9IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKGNyZWF0ZURpYWxvZ0l0ZW0pIHtcbiAgICAgICAgICAgIGlmIChjcmVhdGVEaWFsb2dJdGVtLmFjdGlvbnMudHlwZSA9PT0gJ3VzZXJzJykge1xuICAgICAgICAgICAgICAgIGRpYWxvZ1RpdGxlID0gZ2V0TWVzc2FnZSg0ODQsICcnKTtcbiAgICAgICAgICAgICAgICBkaWFsb2dDb250ZW50ID0gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgICAgIHsgc3R5bGU6IHsgaGVpZ2h0OiA1MDAgfSB9LFxuICAgICAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KEFzeW5jQ29tcG9uZW50LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBuYW1lc3BhY2U6ICdQeWRpb0Zvcm0nLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50TmFtZTogJ1VzZXJDcmVhdGlvbkZvcm0nLFxuICAgICAgICAgICAgICAgICAgICAgICAgekRlcHRoOiAwLFxuICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHsgaGVpZ2h0OiA1MDAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1VzZXJOYW1lOiBcIlwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgb25Vc2VyQ3JlYXRlZDogdGhpcy5jbG9zZUNyZWF0ZURpYWxvZ0FuZFJlbG9hZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIG9uQ2FuY2VsOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXM0LnNldFN0YXRlKHsgY3JlYXRlRGlhbG9nSXRlbTogbnVsbCB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICBweWRpbzogdGhpcy5wcm9wcy5weWRpb1xuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNyZWF0ZURpYWxvZ0l0ZW0uYWN0aW9ucy50eXBlID09PSAndGVhbXMnKSB7XG4gICAgICAgICAgICAgICAgZGlhbG9nVGl0bGUgPSBnZXRNZXNzYWdlKDU2OSwgJycpO1xuICAgICAgICAgICAgICAgIGRpYWxvZ0NvbnRlbnQgPSBSZWFjdC5jcmVhdGVFbGVtZW50KF9UZWFtQ3JlYXRpb25Gb3JtMlsnZGVmYXVsdCddLCB7XG4gICAgICAgICAgICAgICAgICAgIG9uVGVhbUNyZWF0ZWQ6IHRoaXMuY2xvc2VDcmVhdGVEaWFsb2dBbmRSZWxvYWQsXG4gICAgICAgICAgICAgICAgICAgIG9uQ2FuY2VsOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBfdGhpczQuc2V0U3RhdGUoeyBjcmVhdGVEaWFsb2dJdGVtOiBudWxsIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNyZWF0ZURpYWxvZ0l0ZW0uYWN0aW9ucy50eXBlID09PSAndGVhbScpIHtcbiAgICAgICAgICAgICAgICB2YXIgc2VsZWN0VXNlciA9IGZ1bmN0aW9uIHNlbGVjdFVzZXIoaXRlbSkge1xuICAgICAgICAgICAgICAgICAgICBfVGVhbUNyZWF0aW9uRm9ybTJbJ2RlZmF1bHQnXS51cGRhdGVUZWFtVXNlcnMoY3JlYXRlRGlhbG9nSXRlbSwgJ2FkZCcsIFtpdGVtXSwgX3RoaXM0LnJlbG9hZEN1cnJlbnROb2RlLmJpbmQoX3RoaXM0KSk7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBkaWFsb2dUaXRsZSA9IG51bGw7XG4gICAgICAgICAgICAgICAgZGlhbG9nQ29udGVudCA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoQWRkcmVzc0Jvb2ssIHtcbiAgICAgICAgICAgICAgICAgICAgcHlkaW86IHRoaXMucHJvcHMucHlkaW8sXG4gICAgICAgICAgICAgICAgICAgIG1vZGU6ICdzZWxlY3RvcicsXG4gICAgICAgICAgICAgICAgICAgIHVzZXJzT25seTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgZGlzYWJsZVNlYXJjaDogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgb25JdGVtU2VsZWN0ZWQ6IHNlbGVjdFVzZXJcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBzdHlsZSA9IHRoaXMucHJvcHMuc3R5bGUgfHwge307XG4gICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICB7IHN0eWxlOiBfZXh0ZW5kcyh7IGRpc3BsYXk6ICdmbGV4JywgaGVpZ2h0OiBtb2RlID09PSAnc2VsZWN0b3InID8gNDIwIDogNDUwIH0sIHN0eWxlKSB9LFxuICAgICAgICAgICAgbGVmdFBhbmVsLFxuICAgICAgICAgICAgY2VudGVyQ29tcG9uZW50LFxuICAgICAgICAgICAgcmlnaHRQYW5lbCxcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgTWF0ZXJpYWxVSS5EaWFsb2csXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjb250ZW50U3R5bGU6IHsgd2lkdGg6IDM4MCwgbWluV2lkdGg6IDM4MCwgbWF4V2lkdGg6IDM4MCwgcGFkZGluZzogMCB9LFxuICAgICAgICAgICAgICAgICAgICBib2R5U3R5bGU6IHsgcGFkZGluZzogMCB9LFxuICAgICAgICAgICAgICAgICAgICB0aXRsZTogUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgICAgICAgICAgeyBzdHlsZTogeyBwYWRkaW5nOiAyMCB9IH0sXG4gICAgICAgICAgICAgICAgICAgICAgICBkaWFsb2dUaXRsZVxuICAgICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgICAgICBhY3Rpb25zOiBudWxsLFxuICAgICAgICAgICAgICAgICAgICBtb2RhbDogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIG9wZW46IGNyZWF0ZURpYWxvZ0l0ZW0gPyB0cnVlIDogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIG9uUmVxdWVzdENsb3NlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBfdGhpczQuc2V0U3RhdGUoeyBjcmVhdGVEaWFsb2dJdGVtOiBudWxsIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBkaWFsb2dDb250ZW50XG4gICAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgfVxuXG59KTtcblxuZXhwb3J0c1snZGVmYXVsdCddID0gQWRkcmVzc0Jvb2sgPSBQeWRpb0NvbnRleHRDb25zdW1lcihBZGRyZXNzQm9vayk7XG5leHBvcnRzWydkZWZhdWx0J10gPSBBZGRyZXNzQm9vayA9IG11aVRoZW1lYWJsZSgpKEFkZHJlc3NCb29rKTtcbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IEFkZHJlc3NCb29rO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMDctMjAxNyBDaGFybGVzIGR1IEpldSAtIEFic3RyaXVtIFNBUyA8dGVhbSAoYXQpIHB5ZC5pbz5cbiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIFB5ZGlvLlxuICpcbiAqIFB5ZGlvIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3JcbiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogUHlkaW8gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggUHlkaW8uICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gKlxuICogVGhlIGxhdGVzdCBjb2RlIGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9weWRpby5jb20+LlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxudmFyIF9leHRlbmRzID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiAodGFyZ2V0KSB7IGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7IHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV07IGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHsgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHsgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTsgfSB9IH0gcmV0dXJuIHRhcmdldDsgfTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgJ2RlZmF1bHQnOiBvYmogfTsgfVxuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbicpOyB9IH1cblxuZnVuY3Rpb24gX2luaGVyaXRzKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7IGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gJ2Z1bmN0aW9uJyAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ1N1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uLCBub3QgJyArIHR5cGVvZiBzdXBlckNsYXNzKTsgfSBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHsgY29uc3RydWN0b3I6IHsgdmFsdWU6IHN1YkNsYXNzLCBlbnVtZXJhYmxlOiBmYWxzZSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IH0pOyBpZiAoc3VwZXJDbGFzcykgT2JqZWN0LnNldFByb3RvdHlwZU9mID8gT2JqZWN0LnNldFByb3RvdHlwZU9mKHN1YkNsYXNzLCBzdXBlckNsYXNzKSA6IHN1YkNsYXNzLl9fcHJvdG9fXyA9IHN1cGVyQ2xhc3M7IH1cblxudmFyIF9yZWFjdCA9IHJlcXVpcmUoJ3JlYWN0Jyk7XG5cbnZhciBfbWF0ZXJpYWxVaVN0eWxlcyA9IHJlcXVpcmUoJ21hdGVyaWFsLXVpL3N0eWxlcycpO1xuXG52YXIgX3B5ZGlvID0gcmVxdWlyZSgncHlkaW8nKTtcblxudmFyIF9weWRpbzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9weWRpbyk7XG5cbnZhciBfbWF0ZXJpYWxVaSA9IHJlcXVpcmUoJ21hdGVyaWFsLXVpJyk7XG5cbi8qKlxuICogQWxwaGFiZXQgYW5kIHBhZ2VzIGdlbmVyYXRvciB0byBnaXZlIGEgZmlyc3QtbGV0dGVyLWJhc2VkIHBhZ2luYXRpb25cbiAqL1xuXG52YXIgX1B5ZGlvJHJlcXVpcmVMaWIgPSBfcHlkaW8yWydkZWZhdWx0J10ucmVxdWlyZUxpYignYm9vdCcpO1xuXG52YXIgUHlkaW9Db250ZXh0Q29uc3VtZXIgPSBfUHlkaW8kcmVxdWlyZUxpYi5QeWRpb0NvbnRleHRDb25zdW1lcjtcblxudmFyIEFscGhhUGFnaW5hdG9yID0gKGZ1bmN0aW9uIChfQ29tcG9uZW50KSB7XG4gICAgX2luaGVyaXRzKEFscGhhUGFnaW5hdG9yLCBfQ29tcG9uZW50KTtcblxuICAgIGZ1bmN0aW9uIEFscGhhUGFnaW5hdG9yKCkge1xuICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgQWxwaGFQYWdpbmF0b3IpO1xuXG4gICAgICAgIF9Db21wb25lbnQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG5cbiAgICBBbHBoYVBhZ2luYXRvci5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gcmVuZGVyKCkge1xuXG4gICAgICAgIHZhciBsZXR0ZXJzID0gJ2FiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OScuc3BsaXQoJycpO1xuICAgICAgICBsZXR0ZXJzID0gWy0xXS5jb25jYXQobGV0dGVycyk7XG4gICAgICAgIHZhciBfcHJvcHMgPSB0aGlzLnByb3BzO1xuICAgICAgICB2YXIgaXRlbSA9IF9wcm9wcy5pdGVtO1xuICAgICAgICB2YXIgcGFnaW5hdG9yQ2FsbGJhY2sgPSBfcHJvcHMucGFnaW5hdG9yQ2FsbGJhY2s7XG4gICAgICAgIHZhciBzdHlsZSA9IF9wcm9wcy5zdHlsZTtcbiAgICAgICAgdmFyIGdldE1lc3NhZ2UgPSBfcHJvcHMuZ2V0TWVzc2FnZTtcblxuICAgICAgICB2YXIgcGFnaW5hdG9yID0gdW5kZWZpbmVkO1xuICAgICAgICBpZiAoaXRlbS5wYWdpbmF0aW9uKSB7XG4gICAgICAgICAgICAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHZhciBfaXRlbSRwYWdpbmF0aW9uID0gaXRlbS5wYWdpbmF0aW9uO1xuICAgICAgICAgICAgICAgIHZhciBzdGFydCA9IF9pdGVtJHBhZ2luYXRpb24uc3RhcnQ7XG4gICAgICAgICAgICAgICAgdmFyIGVuZCA9IF9pdGVtJHBhZ2luYXRpb24uZW5kO1xuICAgICAgICAgICAgICAgIHZhciBtYXggPSBfaXRlbSRwYWdpbmF0aW9uLm1heDtcbiAgICAgICAgICAgICAgICB2YXIgaW50ZXJ2YWwgPSBfaXRlbSRwYWdpbmF0aW9uLmludGVydmFsO1xuXG4gICAgICAgICAgICAgICAgdmFyIHRvdGFsX3BhZ2VzID0gTWF0aC5jZWlsKG1heCAvIGludGVydmFsKTtcbiAgICAgICAgICAgICAgICB2YXIgY3VycmVudCA9IE1hdGguY2VpbChzdGFydCAvIGludGVydmFsKTtcbiAgICAgICAgICAgICAgICB2YXIgcGFnZXMgPSBbXTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRvdGFsX3BhZ2VzOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgcGFnZXMucHVzaChpKTtcbiAgICAgICAgICAgICAgICB9cGFnaW5hdG9yID0gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgICAgX21hdGVyaWFsVWkuU2VsZWN0RmllbGQsXG4gICAgICAgICAgICAgICAgICAgIHsgZmxvYXRpbmdMYWJlbFRleHQ6IGdldE1lc3NhZ2UoMzMxKSwgc3R5bGU6IHsgd2lkdGg6IDYwIH0sIGZ1bGxXaWR0aDogdHJ1ZSwgdmFsdWU6IGN1cnJlbnQsIG9uQ2hhbmdlOiBmdW5jdGlvbiAoZSwgaSwgdikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhZ2luYXRvckNhbGxiYWNrKHYgKiBpbnRlcnZhbCArICctJyArICh2ICsgMSkgKiBpbnRlcnZhbCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9IH0sXG4gICAgICAgICAgICAgICAgICAgIHBhZ2VzLm1hcChmdW5jdGlvbiAocCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoX21hdGVyaWFsVWkuTWVudUl0ZW0sIHsgdmFsdWU6IHAsIGtleTogcCwgcHJpbWFyeVRleHQ6IHAgKyAxIH0pO1xuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9KSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGN1cnJlbnRQYWdlID0gaXRlbS5jdXJyZW50UGFyYW1zICYmIGl0ZW0uY3VycmVudFBhcmFtcy5hbHBoYV9wYWdlcyAmJiBpdGVtLmN1cnJlbnRQYXJhbXMudmFsdWUgfHwgLTE7XG5cbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgIHsgc3R5bGU6IF9leHRlbmRzKHt9LCBzdHlsZSwgeyBkaXNwbGF5OiAnZmxleCcsIHBhZGRpbmdSaWdodDogOCwgYWxpZ25JdGVtczogJ2NlbnRlcicgfSkgfSxcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgeyBzdHlsZTogeyBmbGV4OiAxIH0gfSxcbiAgICAgICAgICAgICAgICBnZXRNZXNzYWdlKDI0OSwgJycpXG4gICAgICAgICAgICApLFxuICAgICAgICAgICAgcGFnaW5hdG9yLFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICBfbWF0ZXJpYWxVaS5TZWxlY3RGaWVsZCxcbiAgICAgICAgICAgICAgICB7IGZsb2F0aW5nTGFiZWxUZXh0OiBnZXRNZXNzYWdlKDYyNSksIHN0eWxlOiB7IHdpZHRoOiA2MCwgbWFyZ2luTGVmdDogMjAgfSwgZnVsbFdpZHRoOiB0cnVlLCB2YWx1ZTogY3VycmVudFBhZ2UsIG9uQ2hhbmdlOiBmdW5jdGlvbiAoZSwgaSwgdikge1xuICAgICAgICAgICAgICAgICAgICAgICAgcGFnaW5hdG9yQ2FsbGJhY2sodik7XG4gICAgICAgICAgICAgICAgICAgIH0gfSxcbiAgICAgICAgICAgICAgICBsZXR0ZXJzLm1hcChmdW5jdGlvbiAobCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChfbWF0ZXJpYWxVaS5NZW51SXRlbSwgeyB2YWx1ZTogbCwga2V5OiBsLCBwcmltYXJ5VGV4dDogbCA9PT0gLTEgPyBnZXRNZXNzYWdlKDU5NywgJycpIDogbCB9KTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgKVxuICAgICAgICApO1xuICAgIH07XG5cbiAgICByZXR1cm4gQWxwaGFQYWdpbmF0b3I7XG59KShfcmVhY3QuQ29tcG9uZW50KTtcblxuQWxwaGFQYWdpbmF0b3IucHJvcFR5cGVzID0ge1xuICAgIC8qKlxuICAgICAqIEN1cnJlbnRseSBzZWxlY3RlZCBJdGVtXG4gICAgICovXG4gICAgaXRlbTogX3JlYWN0LlByb3BUeXBlcy5vYmplY3QsXG4gICAgLyoqXG4gICAgICogV2hlbiBhIGxldHRlciBpcyBjbGlja2VkLCBmdW5jdGlvbihsZXR0ZXIpXG4gICAgICovXG4gICAgcGFnaW5hdG9yQ2FsbGJhY2s6IF9yZWFjdC5Qcm9wVHlwZXMuZnVuYy5pc1JlcXVpcmVkLFxuICAgIC8qKlxuICAgICAqIE1haW4gaW5zdGFuY2Ugb2YgcHlkaW9cbiAgICAgKi9cbiAgICBweWRpbzogX3JlYWN0LlByb3BUeXBlcy5pbnN0YW5jZU9mKF9weWRpbzJbJ2RlZmF1bHQnXSksXG4gICAgLyoqXG4gICAgICogRGlzcGxheSBtb2RlLCBlaXRoZXIgbGFyZ2UgKGJvb2spIG9yIHNtYWxsIHBpY2tlciAoJ3NlbGVjdG9yJywgJ3BvcG92ZXInKS5cbiAgICAgKi9cbiAgICBtb2RlOiBfcmVhY3QuUHJvcFR5cGVzLm9uZU9mKFsnYm9vaycsICdzZWxlY3RvcicsICdwb3BvdmVyJ10pLmlzUmVxdWlyZWRcbn07XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IEFscGhhUGFnaW5hdG9yID0gUHlkaW9Db250ZXh0Q29uc3VtZXIoQWxwaGFQYWdpbmF0b3IpO1xuZXhwb3J0c1snZGVmYXVsdCddID0gQWxwaGFQYWdpbmF0b3IgPSBfbWF0ZXJpYWxVaVN0eWxlcy5tdWlUaGVtZWFibGUoKShBbHBoYVBhZ2luYXRvcik7XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IEFscGhhUGFnaW5hdG9yO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMDctMjAxNyBDaGFybGVzIGR1IEpldSAtIEFic3RyaXVtIFNBUyA8dGVhbSAoYXQpIHB5ZC5pbz5cbiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIFB5ZGlvLlxuICpcbiAqIFB5ZGlvIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3JcbiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogUHlkaW8gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggUHlkaW8uICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gKlxuICogVGhlIGxhdGVzdCBjb2RlIGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9weWRpby5jb20+LlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxudmFyIF9leHRlbmRzID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiAodGFyZ2V0KSB7IGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7IHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV07IGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHsgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHsgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTsgfSB9IH0gcmV0dXJuIHRhcmdldDsgfTtcblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24nKTsgfSB9XG5cbnZhciBMb2FkZXJzID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBMb2FkZXJzKCkge1xuICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgTG9hZGVycyk7XG4gICAgfVxuXG4gICAgTG9hZGVycy5jaGlsZHJlbkFzUHJvbWlzZSA9IGZ1bmN0aW9uIGNoaWxkcmVuQXNQcm9taXNlKGl0ZW0pIHtcbiAgICAgICAgdmFyIGxlYWYgPSBhcmd1bWVudHMubGVuZ3RoIDw9IDEgfHwgYXJndW1lbnRzWzFdID09PSB1bmRlZmluZWQgPyBmYWxzZSA6IGFyZ3VtZW50c1sxXTtcbiAgICAgICAgdmFyIGNoaWxkcmVuTG9hZGVyID0gaXRlbS5jaGlsZHJlbkxvYWRlcjtcbiAgICAgICAgdmFyIGl0ZW1zTG9hZGVyID0gaXRlbS5pdGVtc0xvYWRlcjtcbiAgICAgICAgdmFyIGxlYWZMb2FkZWQgPSBpdGVtLmxlYWZMb2FkZWQ7XG4gICAgICAgIHZhciBjb2xsZWN0aW9uc0xvYWRlZCA9IGl0ZW0uY29sbGVjdGlvbnNMb2FkZWQ7XG4gICAgICAgIHZhciBsZWFmcyA9IGl0ZW0ubGVhZnM7XG4gICAgICAgIHZhciBjb2xsZWN0aW9ucyA9IGl0ZW0uY29sbGVjdGlvbnM7XG5cbiAgICAgICAgdmFyIGxvYWRlciA9IGxlYWYgPyBpdGVtc0xvYWRlciA6IGNoaWxkcmVuTG9hZGVyO1xuICAgICAgICB2YXIgbG9hZGVkID0gbGVhZiA/IGxlYWZMb2FkZWQgOiBjb2xsZWN0aW9uc0xvYWRlZDtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgICAgICAgIGlmICghbG9hZGVkICYmIGxvYWRlcikge1xuICAgICAgICAgICAgICAgIGxvYWRlcihpdGVtLCBmdW5jdGlvbiAobmV3Q2hpbGRyZW4pIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGxlYWYpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW0ubGVhZnMgPSBuZXdDaGlsZHJlbjtcbiAgICAgICAgICAgICAgICAgICAgICAgIGl0ZW0ubGVhZkxvYWRlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpdGVtLmNvbGxlY3Rpb25zID0gbmV3Q2hpbGRyZW47XG4gICAgICAgICAgICAgICAgICAgICAgICBpdGVtLmNvbGxlY3Rpb25zTG9hZGVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKG5ld0NoaWxkcmVuKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdmFyIHJlcyA9IChsZWFmID8gbGVhZnMgOiBjb2xsZWN0aW9ucykgfHwgW107XG4gICAgICAgICAgICAgICAgcmVzb2x2ZShyZXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgTG9hZGVycy5saXN0VXNlcnMgPSBmdW5jdGlvbiBsaXN0VXNlcnMocGFyYW1zLCBjYWxsYmFjaykge1xuICAgICAgICB2YXIgcGFyZW50ID0gYXJndW1lbnRzLmxlbmd0aCA8PSAyIHx8IGFyZ3VtZW50c1syXSA9PT0gdW5kZWZpbmVkID8gbnVsbCA6IGFyZ3VtZW50c1syXTtcblxuICAgICAgICB2YXIgYmFzZVBhcmFtcyA9IHsgZ2V0X2FjdGlvbjogJ3VzZXJfbGlzdF9hdXRob3JpemVkX3VzZXJzJywgZm9ybWF0OiAnanNvbicgfTtcbiAgICAgICAgYmFzZVBhcmFtcyA9IF9leHRlbmRzKHt9LCBiYXNlUGFyYW1zLCBwYXJhbXMpO1xuICAgICAgICB2YXIgY2IgPSBjYWxsYmFjaztcbiAgICAgICAgaWYgKHBhcmVudCkge1xuICAgICAgICAgICAgaWYgKHBhcmVudC5yYW5nZSkge1xuICAgICAgICAgICAgICAgIGJhc2VQYXJhbXNbJ3JhbmdlJ10gPSBwYXJlbnQucmFuZ2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYiA9IGZ1bmN0aW9uIChjaGlsZHJlbikge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKGNoaWxkcmVuLm1hcChmdW5jdGlvbiAoYykge1xuICAgICAgICAgICAgICAgICAgICBjLl9wYXJlbnQgPSBwYXJlbnQ7cmV0dXJuIGM7XG4gICAgICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBQeWRpb0FwaS5nZXRDbGllbnQoKS5yZXF1ZXN0KGJhc2VQYXJhbXMsIGZ1bmN0aW9uICh0cmFuc3BvcnQpIHtcbiAgICAgICAgICAgIGNiKHRyYW5zcG9ydC5yZXNwb25zZUpTT04pO1xuICAgICAgICAgICAgdmFyIGNSYW5nZSA9IHRyYW5zcG9ydC5yZXNwb25zZU9iamVjdC5oZWFkZXJzLmdldCgnQ29udGVudC1SYW5nZScpO1xuICAgICAgICAgICAgdmFyIGFSYW5nZSA9IHRyYW5zcG9ydC5yZXNwb25zZU9iamVjdC5oZWFkZXJzLmdldCgnQWNjZXB0LVJhbmdlJyk7XG4gICAgICAgICAgICBpZiAoY1JhbmdlICYmIGFSYW5nZSAmJiBwYXJlbnQpIHtcbiAgICAgICAgICAgICAgICB2YXIgX2FSYW5nZSRzcGxpdCA9IGFSYW5nZS5zcGxpdCgnICcpO1xuXG4gICAgICAgICAgICAgICAgdmFyIHR5cGUgPSBfYVJhbmdlJHNwbGl0WzBdO1xuICAgICAgICAgICAgICAgIHZhciBpbnRlcnZhbCA9IF9hUmFuZ2Ukc3BsaXRbMV07XG5cbiAgICAgICAgICAgICAgICB2YXIgX2NSYW5nZSRzcGxpdCA9IGNSYW5nZS5zcGxpdCgnLycpO1xuXG4gICAgICAgICAgICAgICAgdmFyIHJhbmdlID0gX2NSYW5nZSRzcGxpdFswXTtcbiAgICAgICAgICAgICAgICB2YXIgbWF4ID0gX2NSYW5nZSRzcGxpdFsxXTtcblxuICAgICAgICAgICAgICAgIHZhciBfcmFuZ2Ukc3BsaXQgPSByYW5nZS5zcGxpdCgnLScpO1xuXG4gICAgICAgICAgICAgICAgdmFyIHN0YXJ0ID0gX3JhbmdlJHNwbGl0WzBdO1xuICAgICAgICAgICAgICAgIHZhciBlbmQgPSBfcmFuZ2Ukc3BsaXRbMV07XG5cbiAgICAgICAgICAgICAgICBwYXJlbnQucGFnaW5hdGlvbiA9IHtcbiAgICAgICAgICAgICAgICAgICAgc3RhcnQ6IHBhcnNlSW50KHN0YXJ0KSxcbiAgICAgICAgICAgICAgICAgICAgZW5kOiBwYXJzZUludChlbmQpLFxuICAgICAgICAgICAgICAgICAgICBtYXg6IHBhcnNlSW50KG1heCksXG4gICAgICAgICAgICAgICAgICAgIGludGVydmFsOiBwYXJzZUludChpbnRlcnZhbClcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgTG9hZGVycy5sb2FkVGVhbXMgPSBmdW5jdGlvbiBsb2FkVGVhbXMoZW50cnksIGNhbGxiYWNrKSB7XG4gICAgICAgIHZhciB3cmFwcGVkID0gZnVuY3Rpb24gd3JhcHBlZChjaGlsZHJlbikge1xuICAgICAgICAgICAgY2hpbGRyZW4ubWFwKGZ1bmN0aW9uIChjaGlsZCkge1xuICAgICAgICAgICAgICAgIGNoaWxkLmljb24gPSAnbWRpIG1kaS1hY2NvdW50LW11bHRpcGxlJztcbiAgICAgICAgICAgICAgICBjaGlsZC5pdGVtc0xvYWRlciA9IExvYWRlcnMubG9hZFRlYW1Vc2VycztcbiAgICAgICAgICAgICAgICBjaGlsZC5hY3Rpb25zID0ge1xuICAgICAgICAgICAgICAgICAgICB0eXBlOiAndGVhbScsXG4gICAgICAgICAgICAgICAgICAgIGNyZWF0ZTogJzU3MycsXG4gICAgICAgICAgICAgICAgICAgIHJlbW92ZTogJzU3NCcsXG4gICAgICAgICAgICAgICAgICAgIG11bHRpcGxlOiB0cnVlXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBjaGlsZC5fbm90U2VsZWN0YWJsZSA9IHRydWU7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNhbGxiYWNrKGNoaWxkcmVuKTtcbiAgICAgICAgfTtcbiAgICAgICAgTG9hZGVycy5saXN0VXNlcnMoeyBmaWx0ZXJfdmFsdWU6IDggfSwgd3JhcHBlZCwgZW50cnkpO1xuICAgIH07XG5cbiAgICBMb2FkZXJzLmxvYWRHcm91cHMgPSBmdW5jdGlvbiBsb2FkR3JvdXBzKGVudHJ5LCBjYWxsYmFjaykge1xuICAgICAgICB2YXIgd3JhcHBlZCA9IGZ1bmN0aW9uIHdyYXBwZWQoY2hpbGRyZW4pIHtcbiAgICAgICAgICAgIGNoaWxkcmVuLm1hcChmdW5jdGlvbiAoY2hpbGQpIHtcbiAgICAgICAgICAgICAgICBjaGlsZC5pY29uID0gJ21kaSBtZGktYWNjb3VudC1tdWx0aXBsZSc7XG4gICAgICAgICAgICAgICAgY2hpbGQuY2hpbGRyZW5Mb2FkZXIgPSBlbnRyeS5jaGlsZHJlbkxvYWRlciA/IExvYWRlcnMubG9hZEdyb3VwcyA6IG51bGw7XG4gICAgICAgICAgICAgICAgY2hpbGQuaXRlbXNMb2FkZXIgPSBlbnRyeS5pdGVtc0xvYWRlciA/IExvYWRlcnMubG9hZEdyb3VwVXNlcnMgOiBudWxsO1xuICAgICAgICAgICAgICAgIGlmIChlbnRyeS5jdXJyZW50UGFyYW1zICYmIGVudHJ5LmN1cnJlbnRQYXJhbXMuYWxwaGFfcGFnZXMpIHtcbiAgICAgICAgICAgICAgICAgICAgY2hpbGQuY3VycmVudFBhcmFtcyA9IF9leHRlbmRzKHt9LCBlbnRyeS5jdXJyZW50UGFyYW1zKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNhbGxiYWNrKGNoaWxkcmVuKTtcbiAgICAgICAgfTtcbiAgICAgICAgdmFyIHBhdGggPSBlbnRyeS5pZC5yZXBsYWNlKCdBSlhQX0dSUF8nLCAnJyk7XG4gICAgICAgIHZhciBwYXJhbXMgPSB7IGZpbHRlcl92YWx1ZTogNCwgZ3JvdXBfcGF0aDogcGF0aCB9O1xuICAgICAgICBpZiAoZW50cnkuY3VycmVudFBhcmFtcyAmJiAhZW50cnkuY3VycmVudFBhcmFtcy5hbHBoYV9wYWdlcykge1xuICAgICAgICAgICAgcGFyYW1zID0gX2V4dGVuZHMoe30sIHBhcmFtcywgZW50cnkuY3VycmVudFBhcmFtcyk7XG4gICAgICAgIH1cbiAgICAgICAgTG9hZGVycy5saXN0VXNlcnMocGFyYW1zLCB3cmFwcGVkLCBlbnRyeSk7XG4gICAgfTtcblxuICAgIExvYWRlcnMubG9hZEV4dGVybmFsVXNlcnMgPSBmdW5jdGlvbiBsb2FkRXh0ZXJuYWxVc2VycyhlbnRyeSwgY2FsbGJhY2spIHtcbiAgICAgICAgTG9hZGVycy5saXN0VXNlcnMoeyBmaWx0ZXJfdmFsdWU6IDIgfSwgY2FsbGJhY2ssIGVudHJ5KTtcbiAgICB9O1xuXG4gICAgTG9hZGVycy5sb2FkR3JvdXBVc2VycyA9IGZ1bmN0aW9uIGxvYWRHcm91cFVzZXJzKGVudHJ5LCBjYWxsYmFjaykge1xuICAgICAgICB2YXIgcGF0aCA9IGVudHJ5LmlkLnJlcGxhY2UoJ0FKWFBfR1JQXycsICcnKTtcbiAgICAgICAgdmFyIHBhcmFtcyA9IHsgZmlsdGVyX3ZhbHVlOiAxLCBncm91cF9wYXRoOiBwYXRoIH07XG4gICAgICAgIGlmIChlbnRyeS5jdXJyZW50UGFyYW1zKSB7XG4gICAgICAgICAgICBwYXJhbXMgPSBfZXh0ZW5kcyh7fSwgcGFyYW1zLCBlbnRyeS5jdXJyZW50UGFyYW1zKTtcbiAgICAgICAgfVxuICAgICAgICBMb2FkZXJzLmxpc3RVc2VycyhwYXJhbXMsIGNhbGxiYWNrLCBlbnRyeSk7XG4gICAgfTtcblxuICAgIExvYWRlcnMubG9hZFRlYW1Vc2VycyA9IGZ1bmN0aW9uIGxvYWRUZWFtVXNlcnMoZW50cnksIGNhbGxiYWNrKSB7XG4gICAgICAgIExvYWRlcnMubGlzdFVzZXJzKHsgZmlsdGVyX3ZhbHVlOiAzLCBncm91cF9wYXRoOiBlbnRyeS5pZCB9LCBjYWxsYmFjaywgZW50cnkpO1xuICAgIH07XG5cbiAgICByZXR1cm4gTG9hZGVycztcbn0pKCk7XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IExvYWRlcnM7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTtcbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDE3IENoYXJsZXMgZHUgSmV1IC0gQWJzdHJpdW0gU0FTIDx0ZWFtIChhdCkgcHlkLmlvPlxuICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgUHlkaW8uXG4gKlxuICogUHlkaW8gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBQeWRpbyBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCBQeWRpby4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAqXG4gKiBUaGUgbGF0ZXN0IGNvZGUgY2FuIGJlIGZvdW5kIGF0IDxodHRwczovL3B5ZGlvLmNvbT4uXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbicpOyB9IH1cblxuZnVuY3Rpb24gX2luaGVyaXRzKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7IGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gJ2Z1bmN0aW9uJyAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ1N1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uLCBub3QgJyArIHR5cGVvZiBzdXBlckNsYXNzKTsgfSBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHsgY29uc3RydWN0b3I6IHsgdmFsdWU6IHN1YkNsYXNzLCBlbnVtZXJhYmxlOiBmYWxzZSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IH0pOyBpZiAoc3VwZXJDbGFzcykgT2JqZWN0LnNldFByb3RvdHlwZU9mID8gT2JqZWN0LnNldFByb3RvdHlwZU9mKHN1YkNsYXNzLCBzdXBlckNsYXNzKSA6IHN1YkNsYXNzLl9fcHJvdG9fXyA9IHN1cGVyQ2xhc3M7IH1cblxudmFyIF9yZXF1aXJlID0gcmVxdWlyZSgncmVhY3QnKTtcblxudmFyIENvbXBvbmVudCA9IF9yZXF1aXJlLkNvbXBvbmVudDtcbnZhciBQcm9wVHlwZXMgPSBfcmVxdWlyZS5Qcm9wVHlwZXM7XG5cbi8qKlxuICogTGVmdCBwYW5lbCBvZiB0aGUgYWRkcmVzcyBib29rXG4gKiBEaXNwbGF5IHRyZWV2aWV3IGhpZXJhcmNoeSBvZiB1c2VycywgdGVhbXMsIGdyb3Vwcy5cbiAqL1xuXG52YXIgTmVzdGVkTGlzdEl0ZW0gPSAoZnVuY3Rpb24gKF9Db21wb25lbnQpIHtcbiAgICBfaW5oZXJpdHMoTmVzdGVkTGlzdEl0ZW0sIF9Db21wb25lbnQpO1xuXG4gICAgZnVuY3Rpb24gTmVzdGVkTGlzdEl0ZW0oKSB7XG4gICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBOZXN0ZWRMaXN0SXRlbSk7XG5cbiAgICAgICAgX0NvbXBvbmVudC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRyaWdnZXJzIHRoaXMucHJvcHMub25Ub3VjaFRhcFxuICAgICAqL1xuXG4gICAgTmVzdGVkTGlzdEl0ZW0ucHJvdG90eXBlLm9uVG91Y2hUYXAgPSBmdW5jdGlvbiBvblRvdWNoVGFwKCkge1xuICAgICAgICB0aGlzLnByb3BzLm9uVG91Y2hUYXAodGhpcy5wcm9wcy5lbnRyeSk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFJlY3Vyc2l2ZWx5IGJ1aWxkIG90aGVyIE5lc3RlZExpc3RJdGVtXG4gICAgICogQHBhcmFtIGRhdGFcbiAgICAgKi9cblxuICAgIE5lc3RlZExpc3RJdGVtLnByb3RvdHlwZS5idWlsZE5lc3RlZEl0ZW1zID0gZnVuY3Rpb24gYnVpbGROZXN0ZWRJdGVtcyhkYXRhKSB7XG4gICAgICAgIHJldHVybiBkYXRhLm1hcCgoZnVuY3Rpb24gKGVudHJ5KSB7XG4gICAgICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChOZXN0ZWRMaXN0SXRlbSwge1xuICAgICAgICAgICAgICAgIG5lc3RlZExldmVsOiB0aGlzLnByb3BzLm5lc3RlZExldmVsICsgMSxcbiAgICAgICAgICAgICAgICBlbnRyeTogZW50cnksXG4gICAgICAgICAgICAgICAgb25Ub3VjaFRhcDogdGhpcy5wcm9wcy5vblRvdWNoVGFwLFxuICAgICAgICAgICAgICAgIHNlbGVjdGVkOiB0aGlzLnByb3BzLnNlbGVjdGVkXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSkuYmluZCh0aGlzKSk7XG4gICAgfTtcblxuICAgIE5lc3RlZExpc3RJdGVtLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgICAgIHZhciBfcHJvcHMkZW50cnkgPSB0aGlzLnByb3BzLmVudHJ5O1xuICAgICAgICB2YXIgaWQgPSBfcHJvcHMkZW50cnkuaWQ7XG4gICAgICAgIHZhciBsYWJlbCA9IF9wcm9wcyRlbnRyeS5sYWJlbDtcbiAgICAgICAgdmFyIGljb24gPSBfcHJvcHMkZW50cnkuaWNvbjtcbiAgICAgICAgdmFyIHNlbGVjdGVkID0gX3Byb3BzJGVudHJ5LnNlbGVjdGVkO1xuXG4gICAgICAgIHZhciBjaGlsZHJlbiA9IHRoaXMucHJvcHMuZW50cnkuY29sbGVjdGlvbnMgfHwgW107XG4gICAgICAgIHZhciBuZXN0ZWQgPSB0aGlzLmJ1aWxkTmVzdGVkSXRlbXMoY2hpbGRyZW4pO1xuICAgICAgICB2YXIgZm9udEljb24gPSB1bmRlZmluZWQ7XG4gICAgICAgIGlmIChpY29uKSB7XG4gICAgICAgICAgICBmb250SWNvbiA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoTWF0ZXJpYWxVSS5Gb250SWNvbiwgeyBjbGFzc05hbWU6IGljb24gfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoTWF0ZXJpYWxVSS5MaXN0SXRlbSwge1xuICAgICAgICAgICAgbmVzdGVkTGV2ZWw6IHRoaXMucHJvcHMubmVzdGVkTGV2ZWwsXG4gICAgICAgICAgICBrZXk6IGlkLFxuICAgICAgICAgICAgcHJpbWFyeVRleHQ6IGxhYmVsLFxuICAgICAgICAgICAgb25Ub3VjaFRhcDogdGhpcy5vblRvdWNoVGFwLmJpbmQodGhpcyksXG4gICAgICAgICAgICBuZXN0ZWRJdGVtczogbmVzdGVkLFxuICAgICAgICAgICAgaW5pdGlhbGx5T3BlbjogdHJ1ZSxcbiAgICAgICAgICAgIGxlZnRJY29uOiBmYWxzZSAmJiBmb250SWNvbixcbiAgICAgICAgICAgIGlubmVyRGl2U3R5bGU6IHsgZm9udFdlaWdodDogdGhpcy5wcm9wcy5zZWxlY3RlZCA9PT0gdGhpcy5wcm9wcy5lbnRyeS5pZCA/IDUwMCA6IDQwMCB9XG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICByZXR1cm4gTmVzdGVkTGlzdEl0ZW07XG59KShDb21wb25lbnQpO1xuXG5OZXN0ZWRMaXN0SXRlbS5wcm9wVHlwZXMgPSB7XG4gICAgLyoqXG4gICAgICogS2VlcHMgdHJhY2sgb2YgdGhlIGN1cnJlbnQgZGVwdGggbGV2ZWxcbiAgICAgKi9cbiAgICBuZXN0ZWRMZXZlbDogUHJvcFR5cGVzLm51bWJlcixcbiAgICAvKipcbiAgICAgKiBDdXJyZW50bHkgc2VsZWN0ZWQgbm9kZSBpZFxuICAgICAqL1xuICAgIHNlbGVjdGVkOiBQcm9wVHlwZXMuc3RyaW5nLFxuICAgIC8qKlxuICAgICAqIENhbGxiYWNrIHRyaWdnZXJlZCB3aGVuIGFuIGVudHJ5IGlzIHNlbGVjdGVkXG4gICAgICovXG4gICAgb25Ub3VjaFRhcDogUHJvcFR5cGVzLmZ1bmNcbn07XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IE5lc3RlZExpc3RJdGVtO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMDctMjAxNyBDaGFybGVzIGR1IEpldSAtIEFic3RyaXVtIFNBUyA8dGVhbSAoYXQpIHB5ZC5pbz5cbiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIFB5ZGlvLlxuICpcbiAqIFB5ZGlvIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3JcbiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogUHlkaW8gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggUHlkaW8uICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gKlxuICogVGhlIGxhdGVzdCBjb2RlIGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9weWRpby5jb20+LlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxudmFyIF9leHRlbmRzID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiAodGFyZ2V0KSB7IGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7IHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV07IGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHsgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHsgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTsgfSB9IH0gcmV0dXJuIHRhcmdldDsgfTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgJ2RlZmF1bHQnOiBvYmogfTsgfVxuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbicpOyB9IH1cblxuZnVuY3Rpb24gX2luaGVyaXRzKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7IGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gJ2Z1bmN0aW9uJyAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ1N1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uLCBub3QgJyArIHR5cGVvZiBzdXBlckNsYXNzKTsgfSBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHsgY29uc3RydWN0b3I6IHsgdmFsdWU6IHN1YkNsYXNzLCBlbnVtZXJhYmxlOiBmYWxzZSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IH0pOyBpZiAoc3VwZXJDbGFzcykgT2JqZWN0LnNldFByb3RvdHlwZU9mID8gT2JqZWN0LnNldFByb3RvdHlwZU9mKHN1YkNsYXNzLCBzdXBlckNsYXNzKSA6IHN1YkNsYXNzLl9fcHJvdG9fXyA9IHN1cGVyQ2xhc3M7IH1cblxudmFyIF9UZWFtQ2FyZCA9IHJlcXVpcmUoJy4vVGVhbUNhcmQnKTtcblxudmFyIF9UZWFtQ2FyZDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9UZWFtQ2FyZCk7XG5cbnZhciBfVXNlckNhcmQgPSByZXF1aXJlKCcuL1VzZXJDYXJkJyk7XG5cbnZhciBfVXNlckNhcmQyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfVXNlckNhcmQpO1xuXG52YXIgUmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpO1xuXG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKCdtYXRlcmlhbC11aScpO1xuXG52YXIgUGFwZXIgPSBfcmVxdWlyZS5QYXBlcjtcblxuLyoqXG4gKiBDb250YWluZXIgZm9yIFVzZXJDYXJkIG9yIFRlYW1DYXJkXG4gKi9cblxudmFyIFJpZ2h0UGFuZWxDYXJkID0gKGZ1bmN0aW9uIChfUmVhY3QkQ29tcG9uZW50KSB7XG4gIF9pbmhlcml0cyhSaWdodFBhbmVsQ2FyZCwgX1JlYWN0JENvbXBvbmVudCk7XG5cbiAgZnVuY3Rpb24gUmlnaHRQYW5lbENhcmQoKSB7XG4gICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFJpZ2h0UGFuZWxDYXJkKTtcblxuICAgIF9SZWFjdCRDb21wb25lbnQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgfVxuXG4gIFJpZ2h0UGFuZWxDYXJkLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiByZW5kZXIoKSB7XG5cbiAgICB2YXIgY29udGVudCA9IHVuZGVmaW5lZDtcbiAgICB2YXIgaXRlbSA9IHRoaXMucHJvcHMuaXRlbSB8fCB7fTtcbiAgICBpZiAoaXRlbS50eXBlID09PSAndXNlcicpIHtcbiAgICAgIGNvbnRlbnQgPSBSZWFjdC5jcmVhdGVFbGVtZW50KF9Vc2VyQ2FyZDJbJ2RlZmF1bHQnXSwgdGhpcy5wcm9wcyk7XG4gICAgfSBlbHNlIGlmIChpdGVtLnR5cGUgPT09ICdncm91cCcgJiYgaXRlbS5pZC5pbmRleE9mKCcvQUpYUF9URUFNLycpID09PSAwKSB7XG4gICAgICBjb250ZW50ID0gUmVhY3QuY3JlYXRlRWxlbWVudChfVGVhbUNhcmQyWydkZWZhdWx0J10sIHRoaXMucHJvcHMpO1xuICAgIH1cblxuICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgUGFwZXIsXG4gICAgICB7IHpEZXB0aDogMiwgc3R5bGU6IF9leHRlbmRzKHsgcG9zaXRpb246ICdyZWxhdGl2ZScgfSwgdGhpcy5wcm9wcy5zdHlsZSkgfSxcbiAgICAgIGNvbnRlbnRcbiAgICApO1xuICB9O1xuXG4gIHJldHVybiBSaWdodFBhbmVsQ2FyZDtcbn0pKFJlYWN0LkNvbXBvbmVudCk7XG5cblJpZ2h0UGFuZWxDYXJkLnByb3BUeXBlcyA9IHtcbiAgLyoqXG4gICAqIFB5ZGlvIGluc3RhbmNlXG4gICAqL1xuICBweWRpbzogUmVhY3QuUHJvcFR5cGVzLmluc3RhbmNlT2YoUHlkaW8pLFxuICAvKipcbiAgICogU2VsZWN0ZWQgaXRlbVxuICAgKi9cbiAgaXRlbTogUmVhY3QuUHJvcFR5cGVzLm9iamVjdCxcbiAgLyoqXG4gICAqIEFwcGxpZXMgdG8gcm9vdCBjb250YWluZXJcbiAgICovXG4gIHN0eWxlOiBSZWFjdC5Qcm9wVHlwZXMub2JqZWN0LFxuICAvKipcbiAgICogRm9yd2FyZGVkIHRvIGNoaWxkXG4gICAqL1xuICBvblJlcXVlc3RDbG9zZTogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsXG4gIC8qKlxuICAgKiBGb3J3YXJkZWQgdG8gY2hpbGRcbiAgICovXG4gIG9uRGVsZXRlQWN0aW9uOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgLyoqXG4gICAqIEZvcndhcmRlZCB0byBjaGlsZFxuICAgKi9cbiAgb25VcGRhdGVBY3Rpb246IFJlYWN0LlByb3BUeXBlcy5mdW5jXG59O1xuXG5leHBvcnRzWydkZWZhdWx0J10gPSBSaWdodFBhbmVsQ2FyZDtcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDA3LTIwMTcgQ2hhcmxlcyBkdSBKZXUgLSBBYnN0cml1bSBTQVMgPHRlYW0gKGF0KSBweWQuaW8+XG4gKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBQeWRpby5cbiAqXG4gKiBQeWRpbyBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFB5ZGlvIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIFB5ZGlvLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuICpcbiAqIFRoZSBsYXRlc3QgY29kZSBjYW4gYmUgZm91bmQgYXQgPGh0dHBzOi8vcHlkaW8uY29tPi5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfZXh0ZW5kcyA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gKHRhcmdldCkgeyBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgeyB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldOyBmb3IgKHZhciBrZXkgaW4gc291cmNlKSB7IGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoc291cmNlLCBrZXkpKSB7IHRhcmdldFtrZXldID0gc291cmNlW2tleV07IH0gfSB9IHJldHVybiB0YXJnZXQ7IH07XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uJyk7IH0gfVxuXG5mdW5jdGlvbiBfaW5oZXJpdHMoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSAnZnVuY3Rpb24nICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCAnICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfVxuXG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKCdyZWFjdCcpO1xuXG52YXIgQ29tcG9uZW50ID0gX3JlcXVpcmUuQ29tcG9uZW50O1xudmFyIFByb3BUeXBlcyA9IF9yZXF1aXJlLlByb3BUeXBlcztcblxuLyoqXG4gKiBSZWFkeSB0byB1c2UgRm9ybSArIFJlc3VsdCBMaXN0IGZvciBzZWFyY2ggdXNlcnNcbiAqL1xuXG52YXIgU2VhcmNoRm9ybSA9IChmdW5jdGlvbiAoX0NvbXBvbmVudCkge1xuICAgIF9pbmhlcml0cyhTZWFyY2hGb3JtLCBfQ29tcG9uZW50KTtcblxuICAgIGZ1bmN0aW9uIFNlYXJjaEZvcm0ocHJvcHMsIGNvbnRleHQpIHtcbiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFNlYXJjaEZvcm0pO1xuXG4gICAgICAgIF9Db21wb25lbnQuY2FsbCh0aGlzLCBwcm9wcy5jb250ZXh0KTtcbiAgICAgICAgdGhpcy5zdGF0ZSA9IHsgdmFsdWU6ICcnIH07XG4gICAgfVxuXG4gICAgU2VhcmNoRm9ybS5wcm90b3R5cGUuc2VhcmNoID0gZnVuY3Rpb24gc2VhcmNoKCkge1xuICAgICAgICB0aGlzLnByb3BzLm9uU2VhcmNoKHRoaXMuc3RhdGUudmFsdWUpO1xuICAgIH07XG5cbiAgICBTZWFyY2hGb3JtLnByb3RvdHlwZS5vbkNoYW5nZSA9IGZ1bmN0aW9uIG9uQ2hhbmdlKGV2ZW50LCB2YWx1ZSkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgdmFsdWU6IHZhbHVlIH0pO1xuICAgICAgICBGdW5jVXRpbHMuYnVmZmVyQ2FsbGJhY2soJ3NlYXJjaF91c2Vyc19saXN0JywgMzAwLCB0aGlzLnNlYXJjaC5iaW5kKHRoaXMpKTtcbiAgICB9O1xuXG4gICAgU2VhcmNoRm9ybS5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gcmVuZGVyKCkge1xuXG4gICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICB7IHN0eWxlOiBfZXh0ZW5kcyh7IG1pbldpZHRoOiAzMjAgfSwgdGhpcy5wcm9wcy5zdHlsZSkgfSxcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoTWF0ZXJpYWxVSS5UZXh0RmllbGQsIHtcbiAgICAgICAgICAgICAgICBmdWxsV2lkdGg6IHRydWUsXG4gICAgICAgICAgICAgICAgdmFsdWU6IHRoaXMuc3RhdGUudmFsdWUsXG4gICAgICAgICAgICAgICAgb25DaGFuZ2U6IHRoaXMub25DaGFuZ2UuYmluZCh0aGlzKSxcbiAgICAgICAgICAgICAgICBoaW50VGV4dDogdGhpcy5wcm9wcy5zZWFyY2hMYWJlbFxuICAgICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIFNlYXJjaEZvcm07XG59KShDb21wb25lbnQpO1xuXG5TZWFyY2hGb3JtLnByb3BUeXBlcyA9IHtcbiAgICAvKipcbiAgICAgKiBMYWJlbCBkaXNwbGF5ZWQgaW4gdGhlIHNlYXJjaCBmaWVsZFxuICAgICAqL1xuICAgIHNlYXJjaExhYmVsOiBQcm9wVHlwZXMuc3RyaW5nLmlzUmVxdWlyZWQsXG4gICAgLyoqXG4gICAgICogQ2FsbGJhY2sgdHJpZ2dlcmVkIHRvIHNlYXJjaFxuICAgICAqL1xuICAgIG9uU2VhcmNoOiBQcm9wVHlwZXMuZnVuYy5pc1JlcXVpcmVkLFxuICAgIC8qKlxuICAgICAqIFdpbGwgYmUgYXBwZW5kZWQgdG8gdGhlIHJvb3QgZWxlbWVudFxuICAgICAqL1xuICAgIHN0eWxlOiBQcm9wVHlwZXMub2JqZWN0XG59O1xuXG5leHBvcnRzWydkZWZhdWx0J10gPSBTZWFyY2hGb3JtO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMDctMjAxNyBDaGFybGVzIGR1IEpldSAtIEFic3RyaXVtIFNBUyA8dGVhbSAoYXQpIHB5ZC5pbz5cbiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIFB5ZGlvLlxuICpcbiAqIFB5ZGlvIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3JcbiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogUHlkaW8gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggUHlkaW8uICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gKlxuICogVGhlIGxhdGVzdCBjb2RlIGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9weWRpby5jb20+LlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxudmFyIF9leHRlbmRzID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiAodGFyZ2V0KSB7IGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7IHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV07IGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHsgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHsgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTsgfSB9IH0gcmV0dXJuIHRhcmdldDsgfTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgJ2RlZmF1bHQnOiBvYmogfTsgfVxuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbicpOyB9IH1cblxuZnVuY3Rpb24gX2luaGVyaXRzKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7IGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gJ2Z1bmN0aW9uJyAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ1N1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uLCBub3QgJyArIHR5cGVvZiBzdXBlckNsYXNzKTsgfSBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHsgY29uc3RydWN0b3I6IHsgdmFsdWU6IHN1YkNsYXNzLCBlbnVtZXJhYmxlOiBmYWxzZSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IH0pOyBpZiAoc3VwZXJDbGFzcykgT2JqZWN0LnNldFByb3RvdHlwZU9mID8gT2JqZWN0LnNldFByb3RvdHlwZU9mKHN1YkNsYXNzLCBzdXBlckNsYXNzKSA6IHN1YkNsYXNzLl9fcHJvdG9fXyA9IHN1cGVyQ2xhc3M7IH1cblxudmFyIF9TZWFyY2hGb3JtID0gcmVxdWlyZSgnLi9TZWFyY2hGb3JtJyk7XG5cbnZhciBfU2VhcmNoRm9ybTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9TZWFyY2hGb3JtKTtcblxudmFyIF9Vc2Vyc0xpc3QgPSByZXF1aXJlKCcuL1VzZXJzTGlzdCcpO1xuXG52YXIgX1VzZXJzTGlzdDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9Vc2Vyc0xpc3QpO1xuXG52YXIgX0xvYWRlcnMgPSByZXF1aXJlKCcuL0xvYWRlcnMnKTtcblxudmFyIF9Mb2FkZXJzMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX0xvYWRlcnMpO1xuXG4vKipcbiAqIFJlYWR5IHRvIHVzZSBGb3JtICsgUmVzdWx0IExpc3QgZm9yIHNlYXJjaCB1c2Vyc1xuICovXG5cbnZhciBfcmVxdWlyZSA9IHJlcXVpcmUoJ3JlYWN0Jyk7XG5cbnZhciBDb21wb25lbnQgPSBfcmVxdWlyZS5Db21wb25lbnQ7XG52YXIgUHJvcFR5cGVzID0gX3JlcXVpcmUuUHJvcFR5cGVzO1xuXG52YXIgX3JlcXVpcmUkcmVxdWlyZUxpYiA9IHJlcXVpcmUoJ3B5ZGlvJykucmVxdWlyZUxpYignYm9vdCcpO1xuXG52YXIgUHlkaW9Db250ZXh0Q29uc3VtZXIgPSBfcmVxdWlyZSRyZXF1aXJlTGliLlB5ZGlvQ29udGV4dENvbnN1bWVyO1xuXG52YXIgU2VhcmNoUGFuZWwgPSAoZnVuY3Rpb24gKF9Db21wb25lbnQpIHtcbiAgICBfaW5oZXJpdHMoU2VhcmNoUGFuZWwsIF9Db21wb25lbnQpO1xuXG4gICAgZnVuY3Rpb24gU2VhcmNoUGFuZWwocHJvcHMsIGNvbnRleHQpIHtcbiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFNlYXJjaFBhbmVsKTtcblxuICAgICAgICBfQ29tcG9uZW50LmNhbGwodGhpcywgcHJvcHMuY29udGV4dCk7XG4gICAgICAgIHRoaXMuc3RhdGUgPSB7IGl0ZW1zOiBbXSB9O1xuICAgIH1cblxuICAgIFNlYXJjaFBhbmVsLnByb3RvdHlwZS5vblNlYXJjaCA9IGZ1bmN0aW9uIG9uU2VhcmNoKHZhbHVlKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICAgICAgaWYgKCF2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGl0ZW1zOiBbXSB9KTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgcGFyYW1zID0geyB2YWx1ZTogdmFsdWUsIGV4aXN0aW5nX29ubHk6ICd0cnVlJyB9O1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5wYXJhbXMpIHtcbiAgICAgICAgICAgIHBhcmFtcyA9IF9leHRlbmRzKHt9LCBwYXJhbXMsIHRoaXMucHJvcHMucGFyYW1zKTtcbiAgICAgICAgfVxuICAgICAgICBfTG9hZGVyczJbJ2RlZmF1bHQnXS5saXN0VXNlcnMocGFyYW1zLCBmdW5jdGlvbiAoY2hpbGRyZW4pIHtcbiAgICAgICAgICAgIF90aGlzLnNldFN0YXRlKHsgaXRlbXM6IGNoaWxkcmVuIH0pO1xuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgU2VhcmNoUGFuZWwucHJvdG90eXBlLnJlbmRlciA9IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgICAgdmFyIF90aGlzMiA9IHRoaXM7XG5cbiAgICAgICAgdmFyIF9wcm9wcyA9IHRoaXMucHJvcHM7XG4gICAgICAgIHZhciBtb2RlID0gX3Byb3BzLm1vZGU7XG4gICAgICAgIHZhciBpdGVtID0gX3Byb3BzLml0ZW07XG4gICAgICAgIHZhciBnZXRNZXNzYWdlID0gX3Byb3BzLmdldE1lc3NhZ2U7XG5cbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgIHsgc3R5bGU6IHsgZmxleDogMSwgZGlzcGxheTogJ2ZsZXgnLCBmbGV4RGlyZWN0aW9uOiAnY29sdW1uJyB9IH0sXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgIHsgc3R5bGU6IHsgcGFkZGluZzogMTAsIGhlaWdodDogNTYsIGJhY2tncm91bmRDb2xvcjogdGhpcy5zdGF0ZS5zZWxlY3QgPyBhY3RpdmVUYmFyQ29sb3IgOiAnI2ZhZmFmYScsIGRpc3BsYXk6ICdmbGV4JywgYWxpZ25JdGVtczogJ2NlbnRlcicsIHRyYW5zaXRpb246IERPTVV0aWxzLmdldEJlemllcnNUcmFuc2l0aW9uKCkgfSB9LFxuICAgICAgICAgICAgICAgIG1vZGUgPT09IFwic2VsZWN0b3JcIiAmJiBpdGVtLl9wYXJlbnQgJiYgUmVhY3QuY3JlYXRlRWxlbWVudChNYXRlcmlhbFVJLkljb25CdXR0b24sIHsgaWNvbkNsYXNzTmFtZTogJ21kaSBtZGktY2hldnJvbi1sZWZ0Jywgb25Ub3VjaFRhcDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMyLnByb3BzLm9uRm9sZGVyQ2xpY2tlZChpdGVtLl9wYXJlbnQpO1xuICAgICAgICAgICAgICAgICAgICB9IH0pLFxuICAgICAgICAgICAgICAgIG1vZGUgPT09ICdib29rJyAmJiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICAgICAgeyBzdHlsZTogeyBmb250U2l6ZTogMjAsIGNvbG9yOiAncmdiYSgwLDAsMCwwLjg3KScsIGZsZXg6IDEgfSB9LFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnByb3BzLnRpdGxlXG4gICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KF9TZWFyY2hGb3JtMlsnZGVmYXVsdCddLCB7IHN0eWxlOiBtb2RlID09PSAnYm9vaycgPyB7IG1pbldpZHRoOiAzMjAgfSA6IHsgZmxleDogMSB9LCBzZWFyY2hMYWJlbDogdGhpcy5wcm9wcy5zZWFyY2hMYWJlbCwgb25TZWFyY2g6IHRoaXMub25TZWFyY2guYmluZCh0aGlzKSB9KVxuICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoX1VzZXJzTGlzdDJbJ2RlZmF1bHQnXSwge1xuICAgICAgICAgICAgICAgIG1vZGU6IHRoaXMucHJvcHMubW9kZSxcbiAgICAgICAgICAgICAgICBvbkl0ZW1DbGlja2VkOiB0aGlzLnByb3BzLm9uSXRlbUNsaWNrZWQsXG4gICAgICAgICAgICAgICAgaXRlbTogeyBsZWFmczogdGhpcy5zdGF0ZS5pdGVtcyB9LFxuICAgICAgICAgICAgICAgIG5vVG9vbGJhcjogdHJ1ZSxcbiAgICAgICAgICAgICAgICBlbXB0eVN0YXRlUHJpbWFyeVRleHQ6IGdldE1lc3NhZ2UoNTg3LCAnJyksXG4gICAgICAgICAgICAgICAgZW1wdHlTdGF0ZVNlY29uZGFyeVRleHQ6IGdldE1lc3NhZ2UoNTg4LCAnJylcbiAgICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgfTtcblxuICAgIHJldHVybiBTZWFyY2hQYW5lbDtcbn0pKENvbXBvbmVudCk7XG5cblNlYXJjaFBhbmVsLnByb3BUeXBlcyA9IHtcbiAgICAvKipcbiAgICAgKiBPcHRpb25hbCBwYXJhbWV0ZXJzIGFkZGVkIHRvIGxpc3RVc2VycygpIHJlcXVlc3RcbiAgICAgKi9cbiAgICBwYXJhbXM6IFByb3BUeXBlcy5vYmplY3QsXG4gICAgLyoqXG4gICAgICogTGFiZWwgZGlzcGxheWVkIGluIHRoZSB0b29sYmFyXG4gICAgICovXG4gICAgc2VhcmNoTGFiZWw6IFByb3BUeXBlcy5zdHJpbmcsXG4gICAgLyoqXG4gICAgICogQ2FsbGJhY2sgdHJpZ2dlcmVkIHdoZW4gYSBzZWFyY2ggcmVzdWx0IGlzIGNsaWNrZWRcbiAgICAgKi9cbiAgICBvbkl0ZW1DbGlja2VkOiBQcm9wVHlwZXMuZnVuYyxcbiAgICAvKipcbiAgICAgKiBDdXJyZW50bHkgc2VsZWN0ZWQgaXRlbSwgcmVxdWlyZWQgZm9yIG5hdmlnYXRpb25cbiAgICAgKi9cbiAgICBpdGVtOiBQcm9wVHlwZXMub2JqZWN0LFxuICAgIC8qKlxuICAgICAqIENhbGxiYWNrIHRyaWdnZXJlZCBpZiB0aGUgcmVzdWx0IGlzIGEgY29sbGVjdGlvblxuICAgICAqL1xuICAgIG9uRm9sZGVyQ2xpY2tlZDogUHJvcFR5cGVzLmZ1bmNcbn07XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IFNlYXJjaFBhbmVsID0gUHlkaW9Db250ZXh0Q29uc3VtZXIoU2VhcmNoUGFuZWwpO1xuZXhwb3J0c1snZGVmYXVsdCddID0gU2VhcmNoUGFuZWw7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTtcbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDE3IENoYXJsZXMgZHUgSmV1IC0gQWJzdHJpdW0gU0FTIDx0ZWFtIChhdCkgcHlkLmlvPlxuICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgUHlkaW8uXG4gKlxuICogUHlkaW8gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBQeWRpbyBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCBQeWRpby4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAqXG4gKiBUaGUgbGF0ZXN0IGNvZGUgY2FuIGJlIGZvdW5kIGF0IDxodHRwczovL3B5ZGlvLmNvbT4uXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG52YXIgX2V4dGVuZHMgPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uICh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTsgZm9yICh2YXIga2V5IGluIHNvdXJjZSkgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkgeyB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldOyB9IH0gfSByZXR1cm4gdGFyZ2V0OyB9O1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyAnZGVmYXVsdCc6IG9iaiB9OyB9XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uJyk7IH0gfVxuXG5mdW5jdGlvbiBfaW5oZXJpdHMoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSAnZnVuY3Rpb24nICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCAnICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfVxuXG52YXIgX1VzZXJzTGlzdCA9IHJlcXVpcmUoJy4vVXNlcnNMaXN0Jyk7XG5cbnZhciBfVXNlcnNMaXN0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX1VzZXJzTGlzdCk7XG5cbnZhciBfTG9hZGVycyA9IHJlcXVpcmUoJy4vTG9hZGVycycpO1xuXG52YXIgX0xvYWRlcnMyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfTG9hZGVycyk7XG5cbnZhciBfYXZhdGFyQWN0aW9uc1BhbmVsID0gcmVxdWlyZSgnLi4vYXZhdGFyL0FjdGlvbnNQYW5lbCcpO1xuXG52YXIgX2F2YXRhckFjdGlvbnNQYW5lbDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9hdmF0YXJBY3Rpb25zUGFuZWwpO1xuXG52YXIgUmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpO1xuXG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKCdtYXRlcmlhbC11aScpO1xuXG52YXIgVGV4dEZpZWxkID0gX3JlcXVpcmUuVGV4dEZpZWxkO1xudmFyIEZsYXRCdXR0b24gPSBfcmVxdWlyZS5GbGF0QnV0dG9uO1xudmFyIENhcmRUaXRsZSA9IF9yZXF1aXJlLkNhcmRUaXRsZTtcbnZhciBEaXZpZGVyID0gX3JlcXVpcmUuRGl2aWRlcjtcblxudmFyIF9yZXF1aXJlJHJlcXVpcmVMaWIgPSByZXF1aXJlKCdweWRpbycpLnJlcXVpcmVMaWIoJ2Jvb3QnKTtcblxudmFyIFB5ZGlvQ29udGV4dENvbnN1bWVyID0gX3JlcXVpcmUkcmVxdWlyZUxpYi5QeWRpb0NvbnRleHRDb25zdW1lcjtcblxuLyoqXG4gKiBEaXNwbGF5IGluZm8gYWJvdXQgYSBUZWFtIGluc2lkZSBhIHBvcG92ZXItYWJsZSBjYXJkXG4gKi9cblxudmFyIFRlYW1DYXJkID0gKGZ1bmN0aW9uIChfUmVhY3QkQ29tcG9uZW50KSB7XG4gICAgX2luaGVyaXRzKFRlYW1DYXJkLCBfUmVhY3QkQ29tcG9uZW50KTtcblxuICAgIGZ1bmN0aW9uIFRlYW1DYXJkKHByb3BzLCBjb250ZXh0KSB7XG4gICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBUZWFtQ2FyZCk7XG5cbiAgICAgICAgX1JlYWN0JENvbXBvbmVudC5jYWxsKHRoaXMsIHByb3BzLCBjb250ZXh0KTtcbiAgICAgICAgdGhpcy5zdGF0ZSA9IHsgbGFiZWw6IHRoaXMucHJvcHMuaXRlbS5sYWJlbCB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFVzZSBsb2FkZXIgdG8gZ2V0IHRlYW0gcGFydGljaXBhbnRzXG4gICAgICogQHBhcmFtIGl0ZW1cbiAgICAgKi9cblxuICAgIFRlYW1DYXJkLnByb3RvdHlwZS5sb2FkTWVtYmVycyA9IGZ1bmN0aW9uIGxvYWRNZW1iZXJzKGl0ZW0pIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgICAgICB0aGlzLnNldFN0YXRlKHsgbG9hZGluZzogdHJ1ZSB9KTtcbiAgICAgICAgX0xvYWRlcnMyWydkZWZhdWx0J10uY2hpbGRyZW5Bc1Byb21pc2UoaXRlbSwgZmFsc2UpLnRoZW4oZnVuY3Rpb24gKGNoaWxkcmVuKSB7XG4gICAgICAgICAgICBfTG9hZGVyczJbJ2RlZmF1bHQnXS5jaGlsZHJlbkFzUHJvbWlzZShpdGVtLCB0cnVlKS50aGVuKGZ1bmN0aW9uIChjaGlsZHJlbikge1xuICAgICAgICAgICAgICAgIF90aGlzLnNldFN0YXRlKHsgbWVtYmVyczogaXRlbS5sZWFmcywgbG9hZGluZzogZmFsc2UgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIFRlYW1DYXJkLnByb3RvdHlwZS5jb21wb25lbnRXaWxsTW91bnQgPSBmdW5jdGlvbiBjb21wb25lbnRXaWxsTW91bnQoKSB7XG4gICAgICAgIHRoaXMubG9hZE1lbWJlcnModGhpcy5wcm9wcy5pdGVtKTtcbiAgICB9O1xuXG4gICAgVGVhbUNhcmQucHJvdG90eXBlLmNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMgPSBmdW5jdGlvbiBjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzKG5leHRQcm9wcykge1xuICAgICAgICB0aGlzLmxvYWRNZW1iZXJzKG5leHRQcm9wcy5pdGVtKTtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGxhYmVsOiBuZXh0UHJvcHMuaXRlbS5sYWJlbCB9KTtcbiAgICB9O1xuXG4gICAgVGVhbUNhcmQucHJvdG90eXBlLm9uTGFiZWxDaGFuZ2UgPSBmdW5jdGlvbiBvbkxhYmVsQ2hhbmdlKGUsIHZhbHVlKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBsYWJlbDogdmFsdWUgfSk7XG4gICAgfTtcblxuICAgIFRlYW1DYXJkLnByb3RvdHlwZS51cGRhdGVMYWJlbCA9IGZ1bmN0aW9uIHVwZGF0ZUxhYmVsKCkge1xuICAgICAgICB2YXIgX3RoaXMyID0gdGhpcztcblxuICAgICAgICBpZiAodGhpcy5zdGF0ZS5sYWJlbCAhPT0gdGhpcy5wcm9wcy5pdGVtLmxhYmVsKSB7XG4gICAgICAgICAgICBQeWRpb1VzZXJzLkNsaWVudC51cGRhdGVUZWFtTGFiZWwodGhpcy5wcm9wcy5pdGVtLmlkLnJlcGxhY2UoJy9BSlhQX1RFQU0vJywgJycpLCB0aGlzLnN0YXRlLmxhYmVsLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgX3RoaXMyLnByb3BzLm9uVXBkYXRlQWN0aW9uKF90aGlzMi5wcm9wcy5pdGVtKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBlZGl0TW9kZTogZmFsc2UgfSk7XG4gICAgfTtcblxuICAgIFRlYW1DYXJkLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgICAgIHZhciBfdGhpczMgPSB0aGlzO1xuXG4gICAgICAgIHZhciBfcHJvcHMgPSB0aGlzLnByb3BzO1xuICAgICAgICB2YXIgaXRlbSA9IF9wcm9wcy5pdGVtO1xuICAgICAgICB2YXIgb25EZWxldGVBY3Rpb24gPSBfcHJvcHMub25EZWxldGVBY3Rpb247XG4gICAgICAgIHZhciBvbkNyZWF0ZUFjdGlvbiA9IF9wcm9wcy5vbkNyZWF0ZUFjdGlvbjtcbiAgICAgICAgdmFyIGdldE1lc3NhZ2UgPSBfcHJvcHMuZ2V0TWVzc2FnZTtcblxuICAgICAgICB2YXIgZWRpdFByb3BzID0ge1xuICAgICAgICAgICAgdGVhbTogaXRlbSxcbiAgICAgICAgICAgIHVzZXJFZGl0YWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIG9uRGVsZXRlQWN0aW9uOiBmdW5jdGlvbiBvbkRlbGV0ZUFjdGlvbigpIHtcbiAgICAgICAgICAgICAgICBfdGhpczMucHJvcHMub25EZWxldGVBY3Rpb24oaXRlbS5fcGFyZW50LCBbaXRlbV0pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG9uRWRpdEFjdGlvbjogZnVuY3Rpb24gb25FZGl0QWN0aW9uKCkge1xuICAgICAgICAgICAgICAgIF90aGlzMy5zZXRTdGF0ZSh7IGVkaXRNb2RlOiAhX3RoaXMzLnN0YXRlLmVkaXRNb2RlIH0pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJlbG9hZEFjdGlvbjogZnVuY3Rpb24gcmVsb2FkQWN0aW9uKCkge1xuICAgICAgICAgICAgICAgIF90aGlzMy5wcm9wcy5vblVwZGF0ZUFjdGlvbihpdGVtKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICB2YXIgdGl0bGUgPSB1bmRlZmluZWQ7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlLmVkaXRNb2RlKSB7XG4gICAgICAgICAgICB0aXRsZSA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgeyBzdHlsZTogeyBkaXNwbGF5OiAnZmxleCcsIGFsaWduSXRlbXM6ICdjZW50ZXInLCBtYXJnaW46IDE2IH0gfSxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFRleHRGaWVsZCwgeyBzdHlsZTogeyBmbGV4OiAxLCBmb250U2l6ZTogMjQgfSwgZnVsbFdpZHRoOiB0cnVlLCBkaXNhYmxlZDogZmFsc2UsIHVuZGVybGluZVNob3c6IGZhbHNlLCB2YWx1ZTogdGhpcy5zdGF0ZS5sYWJlbCwgb25DaGFuZ2U6IHRoaXMub25MYWJlbENoYW5nZS5iaW5kKHRoaXMpIH0pLFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoRmxhdEJ1dHRvbiwgeyBzZWNvbmRhcnk6IHRydWUsIGxhYmVsOiBnZXRNZXNzYWdlKDQ4KSwgb25Ub3VjaFRhcDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMzLnVwZGF0ZUxhYmVsKCk7XG4gICAgICAgICAgICAgICAgICAgIH0gfSlcbiAgICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aXRsZSA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoQ2FyZFRpdGxlLCB7IHRpdGxlOiB0aGlzLnN0YXRlLmxhYmVsLCBzdWJ0aXRsZTogaXRlbS5sZWFmcyAmJiBpdGVtLmxlYWZzLmxlbmd0aCA/IGdldE1lc3NhZ2UoNTc2KS5yZXBsYWNlKCclcycsIGl0ZW0ubGVhZnMubGVuZ3RoKSA6IGdldE1lc3NhZ2UoNTc3KSB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgIHRpdGxlLFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChfYXZhdGFyQWN0aW9uc1BhbmVsMlsnZGVmYXVsdCddLCBfZXh0ZW5kcyh7fSwgdGhpcy5wcm9wcywgZWRpdFByb3BzKSksXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KERpdmlkZXIsIG51bGwpLFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChfVXNlcnNMaXN0MlsnZGVmYXVsdCddLCB7IHN1YkhlYWRlcjogZ2V0TWVzc2FnZSg1NzUpLCBvbkl0ZW1DbGlja2VkOiBmdW5jdGlvbiAoKSB7fSwgaXRlbTogaXRlbSwgbW9kZTogJ2lubmVyJywgb25EZWxldGVBY3Rpb246IG9uRGVsZXRlQWN0aW9uIH0pXG4gICAgICAgICk7XG4gICAgfTtcblxuICAgIHJldHVybiBUZWFtQ2FyZDtcbn0pKFJlYWN0LkNvbXBvbmVudCk7XG5cblRlYW1DYXJkLnByb3BUeXBlcyA9IHtcbiAgICAvKipcbiAgICAgKiBQeWRpbyBpbnN0YW5jZVxuICAgICAqL1xuICAgIHB5ZGlvOiBSZWFjdC5Qcm9wVHlwZXMuaW5zdGFuY2VPZihQeWRpbyksXG4gICAgLyoqXG4gICAgICogVGVhbSBkYXRhIG9iamVjdFxuICAgICAqL1xuICAgIGl0ZW06IFJlYWN0LlByb3BUeXBlcy5vYmplY3QsXG4gICAgLyoqXG4gICAgICogQXBwbGllZCB0byByb290IGNvbnRhaW5lclxuICAgICAqL1xuICAgIHN0eWxlOiBSZWFjdC5Qcm9wVHlwZXMub2JqZWN0LFxuICAgIC8qKlxuICAgICAqIENhbGxlZCB0byBkaXNtaXNzIHRoZSBwb3BvdmVyXG4gICAgICovXG4gICAgb25SZXF1ZXN0Q2xvc2U6IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgIC8qKlxuICAgICAqIERlbGV0ZSBjdXJyZW50IHRlYW1cbiAgICAgKi9cbiAgICBvbkRlbGV0ZUFjdGlvbjogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsXG4gICAgLyoqXG4gICAgICogVXBkYXRlIGN1cnJlbnQgdGVhbVxuICAgICAqL1xuICAgIG9uVXBkYXRlQWN0aW9uOiBSZWFjdC5Qcm9wVHlwZXMuZnVuY1xufTtcblxuZXhwb3J0c1snZGVmYXVsdCddID0gVGVhbUNhcmQgPSBQeWRpb0NvbnRleHRDb25zdW1lcihUZWFtQ2FyZCk7XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IFRlYW1DYXJkO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMDctMjAxNyBDaGFybGVzIGR1IEpldSAtIEFic3RyaXVtIFNBUyA8dGVhbSAoYXQpIHB5ZC5pbz5cbiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIFB5ZGlvLlxuICpcbiAqIFB5ZGlvIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3JcbiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogUHlkaW8gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggUHlkaW8uICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gKlxuICogVGhlIGxhdGVzdCBjb2RlIGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9weWRpby5jb20+LlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxudmFyIF9leHRlbmRzID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiAodGFyZ2V0KSB7IGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7IHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV07IGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHsgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHsgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTsgfSB9IH0gcmV0dXJuIHRhcmdldDsgfTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgJ2RlZmF1bHQnOiBvYmogfTsgfVxuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbicpOyB9IH1cblxuZnVuY3Rpb24gX2luaGVyaXRzKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7IGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gJ2Z1bmN0aW9uJyAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ1N1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uLCBub3QgJyArIHR5cGVvZiBzdXBlckNsYXNzKTsgfSBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHsgY29uc3RydWN0b3I6IHsgdmFsdWU6IHN1YkNsYXNzLCBlbnVtZXJhYmxlOiBmYWxzZSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IH0pOyBpZiAoc3VwZXJDbGFzcykgT2JqZWN0LnNldFByb3RvdHlwZU9mID8gT2JqZWN0LnNldFByb3RvdHlwZU9mKHN1YkNsYXNzLCBzdXBlckNsYXNzKSA6IHN1YkNsYXNzLl9fcHJvdG9fXyA9IHN1cGVyQ2xhc3M7IH1cblxudmFyIF9hdmF0YXJVc2VyQXZhdGFyID0gcmVxdWlyZSgnLi4vYXZhdGFyL1VzZXJBdmF0YXInKTtcblxudmFyIF9hdmF0YXJVc2VyQXZhdGFyMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2F2YXRhclVzZXJBdmF0YXIpO1xuXG52YXIgUmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpO1xuXG52YXIgX3JlcXVpcmUkcmVxdWlyZUxpYiA9IHJlcXVpcmUoJ3B5ZGlvJykucmVxdWlyZUxpYignYm9vdCcpO1xuXG52YXIgQXN5bmNDb21wb25lbnQgPSBfcmVxdWlyZSRyZXF1aXJlTGliLkFzeW5jQ29tcG9uZW50O1xuXG4vKipcbiAqIENhcmQgcHJlc2VudGF0aW9uIG9mIGEgdXNlci4gUmVsaWVzIG9uIHRoZSBVc2VyQXZhdGFyIG9iamVjdCxcbiAqIHBsdXMgdGhlIFB5ZGlvRm9ybS5Vc2VyQ3JlYXRpb25Gb3JtIHdoZW4gaW4gZWRpdCBtb2RlLlxuICovXG5cbnZhciBVc2VyQ2FyZCA9IChmdW5jdGlvbiAoX1JlYWN0JENvbXBvbmVudCkge1xuICAgIF9pbmhlcml0cyhVc2VyQ2FyZCwgX1JlYWN0JENvbXBvbmVudCk7XG5cbiAgICBmdW5jdGlvbiBVc2VyQ2FyZChwcm9wcywgY29udGV4dCkge1xuICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgVXNlckNhcmQpO1xuXG4gICAgICAgIF9SZWFjdCRDb21wb25lbnQuY2FsbCh0aGlzLCBwcm9wcywgY29udGV4dCk7XG4gICAgICAgIHRoaXMuc3RhdGUgPSB7IGVkaXRGb3JtOiBmYWxzZSB9O1xuICAgIH1cblxuICAgIFVzZXJDYXJkLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICAgICAgdmFyIGl0ZW0gPSB0aGlzLnByb3BzLml0ZW07XG5cbiAgICAgICAgdmFyIGVkaXRhYmxlUHJvcHMgPSB7fSxcbiAgICAgICAgICAgIGVkaXRGb3JtID0gdW5kZWZpbmVkO1xuICAgICAgICBpZiAoaXRlbS5fcGFyZW50ICYmIGl0ZW0uX3BhcmVudC5pZCA9PT0gJ2V4dCcpIHtcbiAgICAgICAgICAgIGVkaXRhYmxlUHJvcHMgPSB7XG4gICAgICAgICAgICAgICAgdXNlckVkaXRhYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgIG9uRGVsZXRlQWN0aW9uOiBmdW5jdGlvbiBvbkRlbGV0ZUFjdGlvbigpIHtcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMucHJvcHMub25EZWxldGVBY3Rpb24oaXRlbS5fcGFyZW50LCBbaXRlbV0pO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgb25FZGl0QWN0aW9uOiBmdW5jdGlvbiBvbkVkaXRBY3Rpb24oKSB7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzLnNldFN0YXRlKHsgZWRpdEZvcm06IHRydWUgfSk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICByZWxvYWRBY3Rpb246IGZ1bmN0aW9uIHJlbG9hZEFjdGlvbigpIHtcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMucHJvcHMub25VcGRhdGVBY3Rpb24oaXRlbSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLnN0YXRlLmVkaXRGb3JtKSB7XG4gICAgICAgICAgICBlZGl0Rm9ybSA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoQXN5bmNDb21wb25lbnQsIHtcbiAgICAgICAgICAgICAgICBuYW1lc3BhY2U6ICdQeWRpb0Zvcm0nLFxuICAgICAgICAgICAgICAgIGNvbXBvbmVudE5hbWU6ICdVc2VyQ3JlYXRpb25Gb3JtJyxcbiAgICAgICAgICAgICAgICBweWRpbzogdGhpcy5wcm9wcy5weWRpbyxcbiAgICAgICAgICAgICAgICB6RGVwdGg6IDAsXG4gICAgICAgICAgICAgICAgc3R5bGU6IHsgaGVpZ2h0OiA1MDAgfSxcbiAgICAgICAgICAgICAgICBuZXdVc2VyTmFtZTogaXRlbS5pZCxcbiAgICAgICAgICAgICAgICBlZGl0TW9kZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICB1c2VyRGF0YTogaXRlbSxcbiAgICAgICAgICAgICAgICBvblVzZXJDcmVhdGVkOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzLnByb3BzLm9uVXBkYXRlQWN0aW9uKGl0ZW0pO190aGlzLnNldFN0YXRlKHsgZWRpdEZvcm06IGZhbHNlIH0pO1xuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgb25DYW5jZWw6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMuc2V0U3RhdGUoeyBlZGl0Rm9ybTogZmFsc2UgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgX2F2YXRhclVzZXJBdmF0YXIyWydkZWZhdWx0J10sXG4gICAgICAgICAgICAgICAgX2V4dGVuZHMoe1xuICAgICAgICAgICAgICAgICAgICB1c2VySWQ6IHRoaXMucHJvcHMuaXRlbS5pZCxcbiAgICAgICAgICAgICAgICAgICAgcmljaENhcmQ6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIHB5ZGlvOiB0aGlzLnByb3BzLnB5ZGlvLFxuICAgICAgICAgICAgICAgICAgICBjYXJkU2l6ZTogdGhpcy5wcm9wcy5zdHlsZS53aWR0aFxuICAgICAgICAgICAgICAgIH0sIGVkaXRhYmxlUHJvcHMpLFxuICAgICAgICAgICAgICAgIGVkaXRGb3JtXG4gICAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgfTtcblxuICAgIHJldHVybiBVc2VyQ2FyZDtcbn0pKFJlYWN0LkNvbXBvbmVudCk7XG5cblVzZXJDYXJkLnByb3BUeXBlcyA9IHtcbiAgICAvKipcbiAgICAgKiBQeWRpbyBpbnN0YW5jZVxuICAgICAqL1xuICAgIHB5ZGlvOiBSZWFjdC5Qcm9wVHlwZXMuaW5zdGFuY2VPZihQeWRpbyksXG4gICAgLyoqXG4gICAgICogVGVhbSBkYXRhIG9iamVjdFxuICAgICAqL1xuICAgIGl0ZW06IFJlYWN0LlByb3BUeXBlcy5vYmplY3QsXG4gICAgLyoqXG4gICAgICogQXBwbGllZCB0byByb290IGNvbnRhaW5lclxuICAgICAqL1xuICAgIHN0eWxlOiBSZWFjdC5Qcm9wVHlwZXMub2JqZWN0LFxuICAgIC8qKlxuICAgICAqIENhbGxlZCB0byBkaXNtaXNzIHRoZSBwb3BvdmVyXG4gICAgICovXG4gICAgb25SZXF1ZXN0Q2xvc2U6IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgIC8qKlxuICAgICAqIERlbGV0ZSBjdXJyZW50IHRlYW1cbiAgICAgKi9cbiAgICBvbkRlbGV0ZUFjdGlvbjogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsXG4gICAgLyoqXG4gICAgICogVXBkYXRlIGN1cnJlbnQgdGVhbVxuICAgICAqL1xuICAgIG9uVXBkYXRlQWN0aW9uOiBSZWFjdC5Qcm9wVHlwZXMuZnVuY1xufTtcblxuZXhwb3J0c1snZGVmYXVsdCddID0gVXNlckNhcmQ7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTtcbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDE3IENoYXJsZXMgZHUgSmV1IC0gQWJzdHJpdW0gU0FTIDx0ZWFtIChhdCkgcHlkLmlvPlxuICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgUHlkaW8uXG4gKlxuICogUHlkaW8gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBQeWRpbyBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCBQeWRpby4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAqXG4gKiBUaGUgbGF0ZXN0IGNvZGUgY2FuIGJlIGZvdW5kIGF0IDxodHRwczovL3B5ZGlvLmNvbT4uXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG52YXIgX2V4dGVuZHMgPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uICh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTsgZm9yICh2YXIga2V5IGluIHNvdXJjZSkgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkgeyB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldOyB9IH0gfSByZXR1cm4gdGFyZ2V0OyB9O1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyAnZGVmYXVsdCc6IG9iaiB9OyB9XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uJyk7IH0gfVxuXG5mdW5jdGlvbiBfaW5oZXJpdHMoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSAnZnVuY3Rpb24nICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCAnICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfVxuXG52YXIgX2F2YXRhclVzZXJBdmF0YXIgPSByZXF1aXJlKCcuLi9hdmF0YXIvVXNlckF2YXRhcicpO1xuXG52YXIgX2F2YXRhclVzZXJBdmF0YXIyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYXZhdGFyVXNlckF2YXRhcik7XG5cbnZhciBfdmlld3NFbXB0eVN0YXRlVmlldyA9IHJlcXVpcmUoJy4uLy4uL3ZpZXdzL0VtcHR5U3RhdGVWaWV3Jyk7XG5cbnZhciBfdmlld3NFbXB0eVN0YXRlVmlldzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF92aWV3c0VtcHR5U3RhdGVWaWV3KTtcblxudmFyIF9BbHBoYVBhZ2luYXRvciA9IHJlcXVpcmUoJy4vQWxwaGFQYWdpbmF0b3InKTtcblxudmFyIF9BbHBoYVBhZ2luYXRvcjIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9BbHBoYVBhZ2luYXRvcik7XG5cbnZhciBfU2VhcmNoRm9ybSA9IHJlcXVpcmUoJy4vU2VhcmNoRm9ybScpO1xuXG52YXIgX1NlYXJjaEZvcm0yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfU2VhcmNoRm9ybSk7XG5cbnZhciBfcmVxdWlyZSA9IHJlcXVpcmUoJ21hdGVyaWFsLXVpJyk7XG5cbnZhciBJY29uQnV0dG9uID0gX3JlcXVpcmUuSWNvbkJ1dHRvbjtcbnZhciBDaGVja2JveCA9IF9yZXF1aXJlLkNoZWNrYm94O1xudmFyIEZsYXRCdXR0b24gPSBfcmVxdWlyZS5GbGF0QnV0dG9uO1xudmFyIFJhaXNlZEJ1dHRvbiA9IF9yZXF1aXJlLlJhaXNlZEJ1dHRvbjtcbnZhciBMaXN0SXRlbSA9IF9yZXF1aXJlLkxpc3RJdGVtO1xudmFyIEZvbnRJY29uID0gX3JlcXVpcmUuRm9udEljb247XG52YXIgQXZhdGFyID0gX3JlcXVpcmUuQXZhdGFyO1xudmFyIERpdmlkZXIgPSBfcmVxdWlyZS5EaXZpZGVyO1xudmFyIFN1YmhlYWRlciA9IF9yZXF1aXJlLlN1YmhlYWRlcjtcbnZhciBMaXN0ID0gX3JlcXVpcmUuTGlzdDtcblxudmFyIF9yZXF1aXJlMiA9IHJlcXVpcmUoJ21hdGVyaWFsLXVpL3N0eWxlcycpO1xuXG52YXIgbXVpVGhlbWVhYmxlID0gX3JlcXVpcmUyLm11aVRoZW1lYWJsZTtcblxudmFyIF9yZXF1aXJlJHJlcXVpcmVMaWIgPSByZXF1aXJlKCdweWRpbycpLnJlcXVpcmVMaWIoJ2Jvb3QnKTtcblxudmFyIExvYWRlciA9IF9yZXF1aXJlJHJlcXVpcmVMaWIuTG9hZGVyO1xudmFyIFB5ZGlvQ29udGV4dENvbnN1bWVyID0gX3JlcXVpcmUkcmVxdWlyZUxpYi5QeWRpb0NvbnRleHRDb25zdW1lcjtcblxudmFyIFVzZXJzTGlzdCA9IChmdW5jdGlvbiAoX1JlYWN0JENvbXBvbmVudCkge1xuICAgIF9pbmhlcml0cyhVc2Vyc0xpc3QsIF9SZWFjdCRDb21wb25lbnQpO1xuXG4gICAgZnVuY3Rpb24gVXNlcnNMaXN0KHByb3BzLCBjb250ZXh0KSB7XG4gICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBVc2Vyc0xpc3QpO1xuXG4gICAgICAgIF9SZWFjdCRDb21wb25lbnQuY2FsbCh0aGlzLCBwcm9wcywgY29udGV4dCk7XG4gICAgICAgIHRoaXMuc3RhdGUgPSB7IHNlbGVjdDogZmFsc2UsIHNlbGVjdGlvbjogW10gfTtcbiAgICB9XG5cbiAgICBVc2Vyc0xpc3QucHJvdG90eXBlLnJlbmRlciA9IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgICAgICB2YXIgX3Byb3BzID0gdGhpcy5wcm9wcztcbiAgICAgICAgdmFyIGl0ZW0gPSBfcHJvcHMuaXRlbTtcbiAgICAgICAgdmFyIG1vZGUgPSBfcHJvcHMubW9kZTtcbiAgICAgICAgdmFyIHBhZ2luYXRvclR5cGUgPSBfcHJvcHMucGFnaW5hdG9yVHlwZTtcbiAgICAgICAgdmFyIGxvYWRpbmcgPSBfcHJvcHMubG9hZGluZztcbiAgICAgICAgdmFyIGVuYWJsZVNlYXJjaCA9IF9wcm9wcy5lbmFibGVTZWFyY2g7XG4gICAgICAgIHZhciBzaG93U3ViaGVhZGVycyA9IF9wcm9wcy5zaG93U3ViaGVhZGVycztcbiAgICAgICAgdmFyIGdldE1lc3NhZ2UgPSBfcHJvcHMuZ2V0TWVzc2FnZTtcblxuICAgICAgICB2YXIgZm9sZGVycyA9IGl0ZW0uY29sbGVjdGlvbnMgfHwgW107XG4gICAgICAgIHZhciBsZWFmcyA9IGl0ZW0ubGVhZnMgfHwgW107XG4gICAgICAgIHZhciBmb2xkZXJzU3ViSGVhZGVyID0gZm9sZGVycy5sZW5ndGggJiYgKGxlYWZzLmxlbmd0aCB8fCBzaG93U3ViaGVhZGVycykgPyBbeyBzdWJoZWFkZXI6IGdldE1lc3NhZ2UoJzUzMicpIH1dIDogW107XG4gICAgICAgIHZhciB1c2Vyc1N1YkhlYWRlciA9IFtdO1xuICAgICAgICBpZiAoKHNob3dTdWJoZWFkZXJzIHx8IHBhZ2luYXRvclR5cGUpICYmIGxlYWZzLmxlbmd0aCkge1xuICAgICAgICAgICAgdXNlcnNTdWJIZWFkZXIgPSBbeyBzdWJoZWFkZXI6IHBhZ2luYXRvclR5cGUgPyBSZWFjdC5jcmVhdGVFbGVtZW50KF9BbHBoYVBhZ2luYXRvcjJbJ2RlZmF1bHQnXSwgX2V4dGVuZHMoe30sIHRoaXMucHJvcHMsIHsgc3R5bGU6IHsgbGluZUhlaWdodDogJzIwcHgnLCBwYWRkaW5nOiAnMTRweCAwJyB9IH0pKSA6IGdldE1lc3NhZ2UoJzI0OScpIH1dO1xuICAgICAgICB9XG4gICAgICAgIHZhciBpdGVtcyA9IFtdLmNvbmNhdChmb2xkZXJzU3ViSGVhZGVyLCBmb2xkZXJzLCB1c2Vyc1N1YkhlYWRlciwgbGVhZnMpO1xuICAgICAgICB2YXIgdG90YWwgPSBpdGVtcy5sZW5ndGg7XG4gICAgICAgIHZhciBlbGVtZW50cyA9IFtdO1xuICAgICAgICB2YXIgdG9nZ2xlU2VsZWN0ID0gZnVuY3Rpb24gdG9nZ2xlU2VsZWN0KCkge1xuICAgICAgICAgICAgX3RoaXMuc2V0U3RhdGUoeyBzZWxlY3Q6ICFfdGhpcy5zdGF0ZS5zZWxlY3QsIHNlbGVjdGlvbjogW10gfSk7XG4gICAgICAgIH07XG4gICAgICAgIHZhciBjcmVhdGVBY3Rpb24gPSBmdW5jdGlvbiBjcmVhdGVBY3Rpb24oKSB7XG4gICAgICAgICAgICBfdGhpcy5wcm9wcy5vbkNyZWF0ZUFjdGlvbihpdGVtKTtcbiAgICAgICAgfTtcbiAgICAgICAgdmFyIGRlbGV0ZUFjdGlvbiA9IGZ1bmN0aW9uIGRlbGV0ZUFjdGlvbigpIHtcbiAgICAgICAgICAgIF90aGlzLnByb3BzLm9uRGVsZXRlQWN0aW9uKGl0ZW0sIF90aGlzLnN0YXRlLnNlbGVjdGlvbik7X3RoaXMuc2V0U3RhdGUoeyBzZWxlY3Q6IGZhbHNlLCBzZWxlY3Rpb246IFtdIH0pO1xuICAgICAgICB9O1xuXG4gICAgICAgIHZhciBhY3RpdmVUYmFyQ29sb3IgPSB0aGlzLnByb3BzLm11aVRoZW1lLnBhbGV0dGUuYWNjZW50MkNvbG9yO1xuICAgICAgICB2YXIgdG9vbGJhciA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgIHsgc3R5bGU6IHsgcGFkZGluZzogMTAsIGhlaWdodDogNTYsIGJhY2tncm91bmRDb2xvcjogdGhpcy5zdGF0ZS5zZWxlY3QgPyBhY3RpdmVUYmFyQ29sb3IgOiAnI2ZhZmFmYScsIGRpc3BsYXk6ICdmbGV4JywgYWxpZ25JdGVtczogJ2NlbnRlcicsIHRyYW5zaXRpb246IERPTVV0aWxzLmdldEJlemllcnNUcmFuc2l0aW9uKCkgfSB9LFxuICAgICAgICAgICAgbW9kZSA9PT0gXCJzZWxlY3RvclwiICYmIGl0ZW0uX3BhcmVudCAmJiBSZWFjdC5jcmVhdGVFbGVtZW50KEljb25CdXR0b24sIHsgaWNvbkNsYXNzTmFtZTogJ21kaSBtZGktY2hldnJvbi1sZWZ0Jywgb25Ub3VjaFRhcDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICBfdGhpcy5wcm9wcy5vbkZvbGRlckNsaWNrZWQoaXRlbS5fcGFyZW50KTtcbiAgICAgICAgICAgICAgICB9IH0pLFxuICAgICAgICAgICAgbW9kZSA9PT0gJ2Jvb2snICYmIHRvdGFsID4gMCAmJiBpdGVtLmFjdGlvbnMgJiYgaXRlbS5hY3Rpb25zLm11bHRpcGxlICYmIFJlYWN0LmNyZWF0ZUVsZW1lbnQoQ2hlY2tib3gsIHsgc3R5bGU6IHsgd2lkdGg6ICdpbml0aWFsJywgbWFyZ2luTGVmdDogdGhpcy5zdGF0ZS5zZWxlY3QgPyA3IDogMTQgfSwgY2hlY2tlZDogdGhpcy5zdGF0ZS5zZWxlY3QsIG9uQ2hlY2s6IHRvZ2dsZVNlbGVjdCB9KSxcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgeyBzdHlsZTogeyBmbGV4OiAxLCBmb250U2l6ZTogMjAsIGNvbG9yOiB0aGlzLnN0YXRlLnNlbGVjdCA/ICd3aGl0ZScgOiAncmdiYSgwLDAsMCwwLjg3KScgfSB9LFxuICAgICAgICAgICAgICAgIGl0ZW0ubGFiZWxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgICBtb2RlID09PSAnYm9vaycgJiYgaXRlbS5hY3Rpb25zICYmIGl0ZW0uYWN0aW9ucy5jcmVhdGUgJiYgIXRoaXMuc3RhdGUuc2VsZWN0ICYmIFJlYWN0LmNyZWF0ZUVsZW1lbnQoRmxhdEJ1dHRvbiwgeyBzZWNvbmRhcnk6IHRydWUsIGxhYmVsOiBnZXRNZXNzYWdlKGl0ZW0uYWN0aW9ucy5jcmVhdGUpLCBvblRvdWNoVGFwOiBjcmVhdGVBY3Rpb24gfSksXG4gICAgICAgICAgICBtb2RlID09PSAnYm9vaycgJiYgaXRlbS5hY3Rpb25zICYmIGl0ZW0uYWN0aW9ucy5yZW1vdmUgJiYgdGhpcy5zdGF0ZS5zZWxlY3QgJiYgUmVhY3QuY3JlYXRlRWxlbWVudChSYWlzZWRCdXR0b24sIHsgc2Vjb25kYXJ5OiB0cnVlLCBsYWJlbDogZ2V0TWVzc2FnZShpdGVtLmFjdGlvbnMucmVtb3ZlKSwgZGlzYWJsZWQ6ICF0aGlzLnN0YXRlLnNlbGVjdGlvbi5sZW5ndGgsIG9uVG91Y2hUYXA6IGRlbGV0ZUFjdGlvbiB9KSxcbiAgICAgICAgICAgIGVuYWJsZVNlYXJjaCAmJiBSZWFjdC5jcmVhdGVFbGVtZW50KF9TZWFyY2hGb3JtMlsnZGVmYXVsdCddLCB7IHNlYXJjaExhYmVsOiB0aGlzLnByb3BzLnNlYXJjaExhYmVsLCBvblNlYXJjaDogdGhpcy5wcm9wcy5vblNlYXJjaCwgc3R5bGU6IHsgZmxleDogMSwgbWluV2lkdGg6IDIwMCB9IH0pXG4gICAgICAgICk7XG4gICAgICAgIC8vIFBBUkVOVCBOT0RFXG4gICAgICAgIGlmIChpdGVtLl9wYXJlbnQgJiYgbW9kZSA9PT0gJ2Jvb2snICYmIGl0ZW0uX3BhcmVudC5fcGFyZW50KSB7XG4gICAgICAgICAgICBlbGVtZW50cy5wdXNoKFJlYWN0LmNyZWF0ZUVsZW1lbnQoTGlzdEl0ZW0sIHtcbiAgICAgICAgICAgICAgICBrZXk6ICdfX3BhcmVudF9fJyxcbiAgICAgICAgICAgICAgICBwcmltYXJ5VGV4dDogXCIuLlwiLFxuICAgICAgICAgICAgICAgIG9uVG91Y2hUYXA6IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7X3RoaXMucHJvcHMub25Gb2xkZXJDbGlja2VkKGl0ZW0uX3BhcmVudCk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBsZWZ0QXZhdGFyOiBSZWFjdC5jcmVhdGVFbGVtZW50KEF2YXRhciwgeyBpY29uOiBSZWFjdC5jcmVhdGVFbGVtZW50KEZvbnRJY29uLCB7IGNsYXNzTmFtZTogJ21kaSBtZGktYXJyb3ctdXAnIH0pIH0pXG4gICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICBpZiAodG90YWwpIHtcbiAgICAgICAgICAgICAgICBlbGVtZW50cy5wdXNoKFJlYWN0LmNyZWF0ZUVsZW1lbnQoRGl2aWRlciwgeyBpbnNldDogdHJ1ZSwga2V5OiAncGFyZW50LWRpdmlkZXInIH0pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBJVEVNU1xuICAgICAgICBpdGVtcy5mb3JFYWNoKChmdW5jdGlvbiAoaXRlbSwgaW5kZXgpIHtcbiAgICAgICAgICAgIHZhciBfdGhpczIgPSB0aGlzO1xuXG4gICAgICAgICAgICBpZiAoaXRlbS5zdWJoZWFkZXIpIHtcbiAgICAgICAgICAgICAgICBlbGVtZW50cy5wdXNoKFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgIFN1YmhlYWRlcixcbiAgICAgICAgICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgaXRlbS5zdWJoZWFkZXJcbiAgICAgICAgICAgICAgICApKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgZm9udEljb24gPSBSZWFjdC5jcmVhdGVFbGVtZW50KF9hdmF0YXJVc2VyQXZhdGFyMlsnZGVmYXVsdCddLCB7IGF2YXRhclNpemU6IDM2LCBweWRpbzogdGhpcy5wcm9wcy5weWRpbyB8fCBweWRpbyxcbiAgICAgICAgICAgICAgICB1c2VySWQ6IGl0ZW0uaWQsXG4gICAgICAgICAgICAgICAgdXNlckxhYmVsOiBpdGVtLmxhYmVsLFxuICAgICAgICAgICAgICAgIGF2YXRhcjogaXRlbS5hdmF0YXIsXG4gICAgICAgICAgICAgICAgaWNvbjogaXRlbS5pY29uLFxuICAgICAgICAgICAgICAgIGF2YXRhck9ubHk6IHRydWUsXG4gICAgICAgICAgICAgICAgdXNlRGVmYXVsdEF2YXRhcjogdHJ1ZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB2YXIgcmlnaHRJY29uQnV0dG9uID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgdmFyIHRvdWNoVGFwID0gZnVuY3Rpb24gdG91Y2hUYXAoZSkge1xuICAgICAgICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7X3RoaXMyLnByb3BzLm9uSXRlbUNsaWNrZWQoaXRlbSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaWYgKGZvbGRlcnMuaW5kZXhPZihpdGVtKSA+IC0xICYmIHRoaXMucHJvcHMub25Gb2xkZXJDbGlja2VkKSB7XG4gICAgICAgICAgICAgICAgdG91Y2hUYXAgPSBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO190aGlzMi5wcm9wcy5vbkZvbGRlckNsaWNrZWQoaXRlbSk7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBpZiAobW9kZSA9PT0gJ3NlbGVjdG9yJyAmJiAhaXRlbS5fbm90U2VsZWN0YWJsZSkge1xuICAgICAgICAgICAgICAgICAgICByaWdodEljb25CdXR0b24gPSBSZWFjdC5jcmVhdGVFbGVtZW50KEljb25CdXR0b24sIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGljb25DbGFzc05hbWU6IFwibWRpIG1kaS1hY2NvdW50LW11bHRpcGxlLXBsdXNcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvb2x0aXA6IFwiU2VsZWN0IHRoaXMgZ3JvdXBcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvb2x0aXBQb3NpdGlvbjogJ2JvdHRvbS1sZWZ0JyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG9uVG91Y2hUYXA6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfdGhpczIucHJvcHMub25JdGVtQ2xpY2tlZChpdGVtKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIGlmIChtb2RlID09PSAnaW5uZXInICYmIHRoaXMucHJvcHMub25EZWxldGVBY3Rpb24pIHtcbiAgICAgICAgICAgICAgICByaWdodEljb25CdXR0b24gPSBSZWFjdC5jcmVhdGVFbGVtZW50KEljb25CdXR0b24sIHtcbiAgICAgICAgICAgICAgICAgICAgaWNvbkNsYXNzTmFtZTogXCJtZGkgbWRpLWRlbGV0ZVwiLFxuICAgICAgICAgICAgICAgICAgICB0b29sdGlwOiBnZXRNZXNzYWdlKDI1NyksXG4gICAgICAgICAgICAgICAgICAgIHRvb2x0aXBQb3NpdGlvbjogJ2JvdHRvbS1sZWZ0JyxcbiAgICAgICAgICAgICAgICAgICAgaWNvblN0eWxlOiB7IGNvbG9yOiAncmdiYSgwLDAsMCwwLjEzKScsIGhvdmVyQ29sb3I6ICdyZ2JhKDAsMCwwLDAuNTMpJyB9LFxuICAgICAgICAgICAgICAgICAgICBvblRvdWNoVGFwOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBfdGhpczIucHJvcHMub25EZWxldGVBY3Rpb24oX3RoaXMyLnByb3BzLml0ZW0sIFtpdGVtXSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBzZWxlY3QgPSBmdW5jdGlvbiBzZWxlY3QoZSwgY2hlY2tlZCkge1xuICAgICAgICAgICAgICAgIGlmIChjaGVja2VkKSB7XG4gICAgICAgICAgICAgICAgICAgIF90aGlzMi5zZXRTdGF0ZSh7IHNlbGVjdGlvbjogW10uY29uY2F0KF90aGlzMi5zdGF0ZS5zZWxlY3Rpb24sIFtpdGVtXSkgfSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHN0YXRlU2VsID0gX3RoaXMyLnN0YXRlLnNlbGVjdGlvbjtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNlbGVjdGlvbiA9IFtdLmNvbmNhdChzdGF0ZVNlbC5zbGljZSgwLCBzdGF0ZVNlbC5pbmRleE9mKGl0ZW0pKSwgc3RhdGVTZWwuc2xpY2Uoc3RhdGVTZWwuaW5kZXhPZihpdGVtKSArIDEpKTtcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMyLnNldFN0YXRlKHsgc2VsZWN0aW9uOiBzZWxlY3Rpb24gfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGVsZW1lbnRzLnB1c2goUmVhY3QuY3JlYXRlRWxlbWVudChMaXN0SXRlbSwge1xuICAgICAgICAgICAgICAgIGtleTogaXRlbS5pZCxcbiAgICAgICAgICAgICAgICBwcmltYXJ5VGV4dDogaXRlbS5sYWJlbCxcbiAgICAgICAgICAgICAgICBvblRvdWNoVGFwOiB0b3VjaFRhcCxcbiAgICAgICAgICAgICAgICBkaXNhYmxlZDogbW9kZSA9PT0gJ2lubmVyJyxcbiAgICAgICAgICAgICAgICBsZWZ0QXZhdGFyOiAhdGhpcy5zdGF0ZS5zZWxlY3QgJiYgZm9udEljb24sXG4gICAgICAgICAgICAgICAgcmlnaHRJY29uQnV0dG9uOiByaWdodEljb25CdXR0b24sXG4gICAgICAgICAgICAgICAgbGVmdENoZWNrYm94OiB0aGlzLnN0YXRlLnNlbGVjdCAmJiBSZWFjdC5jcmVhdGVFbGVtZW50KENoZWNrYm94LCB7IGNoZWNrZWQ6IHRoaXMuc3RhdGUuc2VsZWN0aW9uLmluZGV4T2YoaXRlbSkgPiAtMSwgb25DaGVjazogc2VsZWN0IH0pXG4gICAgICAgICAgICB9KSk7XG4gICAgICAgICAgICBpZiAobW9kZSAhPT0gJ2lubmVyJyAmJiBpbmRleCA8IHRvdGFsIC0gMSkge1xuICAgICAgICAgICAgICAgIGVsZW1lbnRzLnB1c2goUmVhY3QuY3JlYXRlRWxlbWVudChEaXZpZGVyLCB7IGluc2V0OiB0cnVlLCBrZXk6IGl0ZW0uaWQgKyAnLWRpdmlkZXInIH0pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSkuYmluZCh0aGlzKSk7XG5cbiAgICAgICAgdmFyIGVtcHR5U3RhdGUgPSB1bmRlZmluZWQ7XG4gICAgICAgIGlmICghZWxlbWVudHMubGVuZ3RoKSB7XG4gICAgICAgICAgICB2YXIgZW1wdHlTdGF0ZVByb3BzID0ge1xuICAgICAgICAgICAgICAgIHN0eWxlOiB7IGJhY2tncm91bmRDb2xvcjogJ3JnYigyNTAsIDI1MCwgMjUwKScgfSxcbiAgICAgICAgICAgICAgICBpY29uQ2xhc3NOYW1lOiAnbWRpIG1kaS1hY2NvdW50LW9mZicsXG4gICAgICAgICAgICAgICAgcHJpbWFyeVRleHRJZDogdGhpcy5wcm9wcy5lbXB0eVN0YXRlUHJpbWFyeVRleHQgfHwgZ2V0TWVzc2FnZSg2MjkpLFxuICAgICAgICAgICAgICAgIHNlY29uZGFyeVRleHRJZDogbW9kZSA9PT0gJ2Jvb2snID8gdGhpcy5wcm9wcy5lbXB0eVN0YXRlU2Vjb25kYXJ5VGV4dCB8fCBudWxsIDogbnVsbFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGlmIChtb2RlID09PSAnYm9vaycgJiYgaXRlbS5hY3Rpb25zICYmIGl0ZW0uYWN0aW9ucy5jcmVhdGUpIHtcbiAgICAgICAgICAgICAgICBlbXB0eVN0YXRlUHJvcHMgPSBfZXh0ZW5kcyh7fSwgZW1wdHlTdGF0ZVByb3BzLCB7XG4gICAgICAgICAgICAgICAgICAgIGFjdGlvbkxhYmVsSWQ6IGdldE1lc3NhZ2UoaXRlbS5hY3Rpb25zLmNyZWF0ZSksXG4gICAgICAgICAgICAgICAgICAgIGFjdGlvbkNhbGxiYWNrOiBjcmVhdGVBY3Rpb25cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVtcHR5U3RhdGUgPSBSZWFjdC5jcmVhdGVFbGVtZW50KF92aWV3c0VtcHR5U3RhdGVWaWV3MlsnZGVmYXVsdCddLCBlbXB0eVN0YXRlUHJvcHMpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgIHsgc3R5bGU6IHsgZmxleDogMSwgZmxleERpcmVjdGlvbjogJ2NvbHVtbicsIGRpc3BsYXk6ICdmbGV4JyB9LCBvblRvdWNoVGFwOiB0aGlzLnByb3BzLm9uVG91Y2hUYXAgfSxcbiAgICAgICAgICAgIG1vZGUgIT09ICdpbm5lcicgJiYgLyooIWVtcHR5U3RhdGUgfHwgbW9kZSAhPT0gJ2Jvb2snKSAmJiovIXRoaXMucHJvcHMubm9Ub29sYmFyICYmIHRvb2xiYXIsXG4gICAgICAgICAgICAhZW1wdHlTdGF0ZSAmJiAhbG9hZGluZyAmJiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgIExpc3QsXG4gICAgICAgICAgICAgICAgeyBzdHlsZTogeyBmbGV4OiAxLCBvdmVyZmxvd1k6IG1vZGUgIT09ICdpbm5lcicgPyAnYXV0bycgOiAnaW5pdGlhbCcgfSB9LFxuICAgICAgICAgICAgICAgIHRoaXMucHJvcHMuc3ViSGVhZGVyICYmIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgIFN1YmhlYWRlcixcbiAgICAgICAgICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5zdWJIZWFkZXJcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgIGVsZW1lbnRzXG4gICAgICAgICAgICApLFxuICAgICAgICAgICAgbG9hZGluZyAmJiBSZWFjdC5jcmVhdGVFbGVtZW50KExvYWRlciwgeyBzdHlsZTogeyBmbGV4OiAxIH0gfSksXG4gICAgICAgICAgICAhbG9hZGluZyAmJiBlbXB0eVN0YXRlXG4gICAgICAgICk7XG4gICAgfTtcblxuICAgIHJldHVybiBVc2Vyc0xpc3Q7XG59KShSZWFjdC5Db21wb25lbnQpO1xuXG5Vc2Vyc0xpc3QucHJvcFR5cGVzID0ge1xuICAgIGl0ZW06IFJlYWN0LlByb3BUeXBlcy5vYmplY3QsXG4gICAgb25DcmVhdGVBY3Rpb246IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgIG9uRGVsZXRlQWN0aW9uOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgICBvbkl0ZW1DbGlja2VkOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgICBvbkZvbGRlckNsaWNrZWQ6IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgIG1vZGU6IFJlYWN0LlByb3BUeXBlcy5vbmVPZihbJ2Jvb2snLCAnc2VsZWN0b3InLCAnaW5uZXInXSlcbn07XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IFVzZXJzTGlzdCA9IFB5ZGlvQ29udGV4dENvbnN1bWVyKFVzZXJzTGlzdCk7XG5leHBvcnRzWydkZWZhdWx0J10gPSBVc2Vyc0xpc3QgPSBtdWlUaGVtZWFibGUoKShVc2Vyc0xpc3QpO1xuXG5leHBvcnRzWydkZWZhdWx0J10gPSBVc2Vyc0xpc3Q7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTtcbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDE3IENoYXJsZXMgZHUgSmV1IC0gQWJzdHJpdW0gU0FTIDx0ZWFtIChhdCkgcHlkLmlvPlxuICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgUHlkaW8uXG4gKlxuICogUHlkaW8gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBQeWRpbyBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCBQeWRpby4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAqXG4gKiBUaGUgbGF0ZXN0IGNvZGUgY2FuIGJlIGZvdW5kIGF0IDxodHRwczovL3B5ZGlvLmNvbT4uXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyAnZGVmYXVsdCc6IG9iaiB9OyB9XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uJyk7IH0gfVxuXG5mdW5jdGlvbiBfaW5oZXJpdHMoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSAnZnVuY3Rpb24nICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCAnICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfVxuXG52YXIgX2FkZHJlc3Nib29rQWRkcmVzc0Jvb2sgPSByZXF1aXJlKCcuLi9hZGRyZXNzYm9vay9BZGRyZXNzQm9vaycpO1xuXG52YXIgX2FkZHJlc3Nib29rQWRkcmVzc0Jvb2syID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYWRkcmVzc2Jvb2tBZGRyZXNzQm9vayk7XG5cbnZhciBSZWFjdCA9IHJlcXVpcmUoJ3JlYWN0Jyk7XG5cbnZhciBfcmVxdWlyZSA9IHJlcXVpcmUoJ3B5ZGlvL2h0dHAvdXNlcnMtYXBpJyk7XG5cbnZhciBVc2Vyc0FwaSA9IF9yZXF1aXJlLlVzZXJzQXBpO1xuXG52YXIgUmVzb3VyY2VzTWFuYWdlciA9IHJlcXVpcmUoJ3B5ZGlvL2h0dHAvcmVzb3VyY2VzLW1hbmFnZXInKTtcblxudmFyIF9yZXF1aXJlMiA9IHJlcXVpcmUoJ21hdGVyaWFsLXVpJyk7XG5cbnZhciBJY29uQnV0dG9uID0gX3JlcXVpcmUyLkljb25CdXR0b247XG52YXIgUG9wb3ZlciA9IF9yZXF1aXJlMi5Qb3BvdmVyO1xuXG52YXIgX3JlcXVpcmUzID0gcmVxdWlyZSgnbWF0ZXJpYWwtdWkvc3R5bGVzJyk7XG5cbnZhciBtdWlUaGVtZWFibGUgPSBfcmVxdWlyZTMubXVpVGhlbWVhYmxlO1xuXG52YXIgX3JlcXVpcmUkcmVxdWlyZUxpYiA9IHJlcXVpcmUoJ3B5ZGlvJykucmVxdWlyZUxpYignYm9vdCcpO1xuXG52YXIgUHlkaW9Db250ZXh0Q29uc3VtZXIgPSBfcmVxdWlyZSRyZXF1aXJlTGliLlB5ZGlvQ29udGV4dENvbnN1bWVyO1xudmFyIEFzeW5jQ29tcG9uZW50ID0gX3JlcXVpcmUkcmVxdWlyZUxpYi5Bc3luY0NvbXBvbmVudDtcblxudmFyIEFjdGlvbnNQYW5lbCA9IChmdW5jdGlvbiAoX1JlYWN0JENvbXBvbmVudCkge1xuICAgIF9pbmhlcml0cyhBY3Rpb25zUGFuZWwsIF9SZWFjdCRDb21wb25lbnQpO1xuXG4gICAgZnVuY3Rpb24gQWN0aW9uc1BhbmVsKHByb3BzLCBjb250ZXh0KSB7XG4gICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBBY3Rpb25zUGFuZWwpO1xuXG4gICAgICAgIF9SZWFjdCRDb21wb25lbnQuY2FsbCh0aGlzLCBwcm9wcywgY29udGV4dCk7XG4gICAgICAgIHRoaXMuc3RhdGUgPSB7IHNob3dQaWNrZXI6IGZhbHNlLCBwaWNrZXJBbmNob3I6IG51bGwsIHNob3dNYWlsZXI6IGZhbHNlLCBtYWlsZXJBbmNob3I6IG51bGwgfTtcbiAgICB9XG5cbiAgICBBY3Rpb25zUGFuZWwucHJvdG90eXBlLm9uVGVhbVNlbGVjdGVkID0gZnVuY3Rpb24gb25UZWFtU2VsZWN0ZWQoaXRlbSkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsgc2hvd1BpY2tlcjogZmFsc2UgfSk7XG4gICAgICAgIGlmIChpdGVtLmdldFR5cGUoKSA9PT0gJ2dyb3VwJyAmJiBpdGVtLmdldElkKCkuaW5kZXhPZignL0FKWFBfVEVBTS8nKSA9PT0gMCkge1xuICAgICAgICAgICAgVXNlcnNBcGkuYWRkVXNlclRvVGVhbShpdGVtLmdldElkKCkucmVwbGFjZSgnL0FKWFBfVEVBTS8nLCAnJyksIHRoaXMucHJvcHMudXNlcklkLCB0aGlzLnByb3BzLnJlbG9hZEFjdGlvbik7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgQWN0aW9uc1BhbmVsLnByb3RvdHlwZS5vblVzZXJTZWxlY3RlZCA9IGZ1bmN0aW9uIG9uVXNlclNlbGVjdGVkKGl0ZW0pIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNob3dQaWNrZXI6IGZhbHNlIH0pO1xuICAgICAgICBVc2Vyc0FwaS5hZGRVc2VyVG9UZWFtKHRoaXMucHJvcHMudGVhbS5pZCwgaXRlbS5nZXRJZCgpLCB0aGlzLnByb3BzLnJlbG9hZEFjdGlvbik7XG4gICAgfTtcblxuICAgIEFjdGlvbnNQYW5lbC5wcm90b3R5cGUub3BlblBpY2tlciA9IGZ1bmN0aW9uIG9wZW5QaWNrZXIoZXZlbnQpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNob3dQaWNrZXI6IHRydWUsIHBpY2tlckFuY2hvcjogZXZlbnQuY3VycmVudFRhcmdldCB9KTtcbiAgICB9O1xuXG4gICAgQWN0aW9uc1BhbmVsLnByb3RvdHlwZS5vcGVuTWFpbGVyID0gZnVuY3Rpb24gb3Blbk1haWxlcihldmVudCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgICAgIHZhciB0YXJnZXQgPSBldmVudC5jdXJyZW50VGFyZ2V0O1xuICAgICAgICBSZXNvdXJjZXNNYW5hZ2VyLmxvYWRDbGFzc2VzQW5kQXBwbHkoWydQeWRpb01haWxlciddLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBfdGhpcy5zZXRTdGF0ZSh7IG1haWxlckxpYkxvYWRlZDogdHJ1ZSB9LCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgX3RoaXMuc2V0U3RhdGUoeyBzaG93TWFpbGVyOiB0cnVlLCBtYWlsZXJBbmNob3I6IHRhcmdldCB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgQWN0aW9uc1BhbmVsLnByb3RvdHlwZS5jb21wb25lbnREaWRVcGRhdGUgPSBmdW5jdGlvbiBjb21wb25lbnREaWRVcGRhdGUocHJldlByb3BzLCBwcmV2U3RhdGUpIHtcbiAgICAgICAgaWYgKCF0aGlzLnByb3BzLmxvY2tPblN1YlBvcG92ZXJPcGVuKSByZXR1cm47XG4gICAgICAgIGlmICgodGhpcy5zdGF0ZS5zaG93UGlja2VyIHx8IHRoaXMuc3RhdGUuc2hvd01haWxlcikgJiYgIShwcmV2U3RhdGUuc2hvd1BpY2tlciB8fCBwcmV2U3RhdGUuc2hvd01haWxlcikpIHtcbiAgICAgICAgICAgIHRoaXMucHJvcHMubG9ja09uU3ViUG9wb3Zlck9wZW4odHJ1ZSk7XG4gICAgICAgIH0gZWxzZSBpZiAoISh0aGlzLnN0YXRlLnNob3dQaWNrZXIgfHwgdGhpcy5zdGF0ZS5zaG93TWFpbGVyKSAmJiAocHJldlN0YXRlLnNob3dQaWNrZXIgfHwgcHJldlN0YXRlLnNob3dNYWlsZXIpKSB7XG4gICAgICAgICAgICB0aGlzLnByb3BzLmxvY2tPblN1YlBvcG92ZXJPcGVuKGZhbHNlKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBBY3Rpb25zUGFuZWwucHJvdG90eXBlLnJlbmRlciA9IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgICAgdmFyIF90aGlzMiA9IHRoaXM7XG5cbiAgICAgICAgdmFyIF9wcm9wcyA9IHRoaXMucHJvcHM7XG4gICAgICAgIHZhciBnZXRNZXNzYWdlID0gX3Byb3BzLmdldE1lc3NhZ2U7XG4gICAgICAgIHZhciBtdWlUaGVtZSA9IF9wcm9wcy5tdWlUaGVtZTtcbiAgICAgICAgdmFyIHRlYW0gPSBfcHJvcHMudGVhbTtcbiAgICAgICAgdmFyIHVzZXIgPSBfcHJvcHMudXNlcjtcbiAgICAgICAgdmFyIHVzZXJFZGl0YWJsZSA9IF9wcm9wcy51c2VyRWRpdGFibGU7XG5cbiAgICAgICAgdmFyIHN0eWxlcyA9IHtcbiAgICAgICAgICAgIGJ1dHRvbjoge1xuICAgICAgICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogbXVpVGhlbWUucGFsZXR0ZS5hY2NlbnQyQ29sb3IsXG4gICAgICAgICAgICAgICAgYm9yZGVyUmFkaXVzOiAnNTAlJyxcbiAgICAgICAgICAgICAgICBtYXJnaW46ICcwIDRweCcsXG4gICAgICAgICAgICAgICAgd2lkdGg6IDQ0LFxuICAgICAgICAgICAgICAgIGhlaWdodDogNDQsXG4gICAgICAgICAgICAgICAgcGFkZGluZzogMTBcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBpY29uOiB7XG4gICAgICAgICAgICAgICAgY29sb3I6ICd3aGl0ZSdcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgdmFyIG1haWxlciA9IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIHVzZXJtYWlscyA9IHt9O1xuICAgICAgICB2YXIgYWN0aW9ucyA9IFtdO1xuICAgICAgICBpZiAodXNlciAmJiB1c2VyLmhhc0VtYWlsKSB7XG4gICAgICAgICAgICBhY3Rpb25zLnB1c2goeyBrZXk6ICdtZXNzYWdlJywgbGFiZWw6IGdldE1lc3NhZ2UoNTk4KSwgaWNvbjogJ2VtYWlsJywgY2FsbGJhY2s6IHRoaXMub3Blbk1haWxlci5iaW5kKHRoaXMpIH0pO1xuICAgICAgICAgICAgdXNlcm1haWxzW3RoaXMucHJvcHMudXNlci5pZF0gPSBQeWRpb1VzZXJzLlVzZXIuZnJvbU9iamVjdCh0aGlzLnByb3BzLnVzZXIpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0ZWFtKSB7XG4gICAgICAgICAgICBhY3Rpb25zLnB1c2goeyBrZXk6ICd1c2VycycsIGxhYmVsOiBnZXRNZXNzYWdlKDU5OSksIGljb246ICdhY2NvdW50LW11bHRpcGxlLXBsdXMnLCBjYWxsYmFjazogdGhpcy5vcGVuUGlja2VyLmJpbmQodGhpcykgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhY3Rpb25zLnB1c2goeyBrZXk6ICd0ZWFtcycsIGxhYmVsOiBnZXRNZXNzYWdlKDU3MyksIGljb246ICdhY2NvdW50LW11bHRpcGxlLXBsdXMnLCBjYWxsYmFjazogdGhpcy5vcGVuUGlja2VyLmJpbmQodGhpcykgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHVzZXJFZGl0YWJsZSkge1xuICAgICAgICAgICAgYWN0aW9ucy5wdXNoKHsga2V5OiAnZWRpdCcsIGxhYmVsOiB0aGlzLnByb3BzLnRlYW0gPyBnZXRNZXNzYWdlKDU4MCkgOiBnZXRNZXNzYWdlKDYwMCksIGljb246ICdwZW5jaWwnLCBjYWxsYmFjazogdGhpcy5wcm9wcy5vbkVkaXRBY3Rpb24gfSk7XG4gICAgICAgICAgICBhY3Rpb25zLnB1c2goeyBrZXk6ICdkZWxldGUnLCBsYWJlbDogdGhpcy5wcm9wcy50ZWFtID8gZ2V0TWVzc2FnZSg1NzApIDogZ2V0TWVzc2FnZSg1ODIpLCBpY29uOiAnZGVsZXRlJywgY2FsbGJhY2s6IHRoaXMucHJvcHMub25EZWxldGVBY3Rpb24gfSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgeyBzdHlsZTogeyB0ZXh0QWxpZ246ICdjZW50ZXInLCBtYXJnaW5Cb3R0b206IDE2IH0gfSxcbiAgICAgICAgICAgIGFjdGlvbnMubWFwKGZ1bmN0aW9uIChhKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoSWNvbkJ1dHRvbiwge1xuICAgICAgICAgICAgICAgICAgICBrZXk6IGEua2V5LFxuICAgICAgICAgICAgICAgICAgICBzdHlsZTogc3R5bGVzLmJ1dHRvbixcbiAgICAgICAgICAgICAgICAgICAgaWNvblN0eWxlOiBzdHlsZXMuaWNvbixcbiAgICAgICAgICAgICAgICAgICAgdG9vbHRpcDogYS5sYWJlbCxcbiAgICAgICAgICAgICAgICAgICAgaWNvbkNsYXNzTmFtZTogXCJtZGkgbWRpLVwiICsgYS5pY29uLFxuICAgICAgICAgICAgICAgICAgICBvblRvdWNoVGFwOiBhLmNhbGxiYWNrXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgUG9wb3ZlcixcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIG9wZW46IHRoaXMuc3RhdGUuc2hvd1BpY2tlcixcbiAgICAgICAgICAgICAgICAgICAgYW5jaG9yRWw6IHRoaXMuc3RhdGUucGlja2VyQW5jaG9yLFxuICAgICAgICAgICAgICAgICAgICBhbmNob3JPcmlnaW46IHsgaG9yaXpvbnRhbDogJ3JpZ2h0JywgdmVydGljYWw6ICd0b3AnIH0sXG4gICAgICAgICAgICAgICAgICAgIHRhcmdldE9yaWdpbjogeyBob3Jpem9udGFsOiAncmlnaHQnLCB2ZXJ0aWNhbDogJ3RvcCcgfSxcbiAgICAgICAgICAgICAgICAgICAgb25SZXF1ZXN0Q2xvc2U6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzMi5zZXRTdGF0ZSh7IHNob3dQaWNrZXI6IGZhbHNlIH0pO1xuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB1c2VMYXllckZvckNsaWNrQXdheTogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIHN0eWxlOiB7IHpJbmRleDogMjIwMCB9XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICAgICAgeyBzdHlsZTogeyB3aWR0aDogMjU2LCBoZWlnaHQ6IDMyMCB9IH0sXG4gICAgICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoX2FkZHJlc3Nib29rQWRkcmVzc0Jvb2syWydkZWZhdWx0J10sIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG1vZGU6ICdzZWxlY3RvcicsXG4gICAgICAgICAgICAgICAgICAgICAgICBweWRpbzogdGhpcy5wcm9wcy5weWRpbyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGxvYWRlclN0eWxlOiB7IHdpZHRoOiAzMjAsIGhlaWdodDogNDIwIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICBvbkl0ZW1TZWxlY3RlZDogdGhpcy5wcm9wcy50ZWFtID8gdGhpcy5vblVzZXJTZWxlY3RlZC5iaW5kKHRoaXMpIDogdGhpcy5vblRlYW1TZWxlY3RlZC5iaW5kKHRoaXMpLFxuICAgICAgICAgICAgICAgICAgICAgICAgdGVhbXNPbmx5OiB0aGlzLnByb3BzLnRlYW0gPyBmYWxzZSA6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICB1c2Vyc09ubHk6IHRoaXMucHJvcHMudGVhbSA/IHRydWUgOiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICksXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgIFBvcG92ZXIsXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBvcGVuOiB0aGlzLnN0YXRlLnNob3dNYWlsZXIsXG4gICAgICAgICAgICAgICAgICAgIGFuY2hvckVsOiB0aGlzLnN0YXRlLm1haWxlckFuY2hvcixcbiAgICAgICAgICAgICAgICAgICAgYW5jaG9yT3JpZ2luOiB7IGhvcml6b250YWw6ICdyaWdodCcsIHZlcnRpY2FsOiAndG9wJyB9LFxuICAgICAgICAgICAgICAgICAgICB0YXJnZXRPcmlnaW46IHsgaG9yaXpvbnRhbDogJ3JpZ2h0JywgdmVydGljYWw6ICd0b3AnIH0sXG4gICAgICAgICAgICAgICAgICAgIHVzZUxheWVyRm9yQ2xpY2tBd2F5OiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgc3R5bGU6IHsgekluZGV4OiAyMjAwIH1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgICAgICB7IHN0eWxlOiB7IHdpZHRoOiAyNTYsIGhlaWdodDogMzIwIH0gfSxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0ZS5tYWlsZXJMaWJMb2FkZWQgJiYgUmVhY3QuY3JlYXRlRWxlbWVudChBc3luY0NvbXBvbmVudCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlOiAnUHlkaW9NYWlsZXInLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50TmFtZTogJ1BhbmUnLFxuICAgICAgICAgICAgICAgICAgICAgICAgekRlcHRoOiAwLFxuICAgICAgICAgICAgICAgICAgICAgICAgcGFuZWxUaXRsZTogZ2V0TWVzc2FnZSg1OTgpLFxuICAgICAgICAgICAgICAgICAgICAgICAgdW5pcXVlVXNlclN0eWxlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgdXNlcnM6IHVzZXJtYWlscyxcbiAgICAgICAgICAgICAgICAgICAgICAgIG9uRGlzbWlzczogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzMi5zZXRTdGF0ZSh7IHNob3dNYWlsZXI6IGZhbHNlIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG9uRmllbGRGb2N1czogdGhpcy5wcm9wcy5vdGhlclBvcG92ZXJNb3VzZU92ZXJcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgfTtcblxuICAgIHJldHVybiBBY3Rpb25zUGFuZWw7XG59KShSZWFjdC5Db21wb25lbnQpO1xuXG5BY3Rpb25zUGFuZWwucHJvcFR5cGVzID0ge1xuXG4gICAgLyoqXG4gICAgICogVXNlciBkYXRhLCBwcm9wcyBtdXN0IHBhc3MgYXQgbGVhc3Qgb25lIG9mICd1c2VyJyBvciAndGVhbSdcbiAgICAgKi9cbiAgICB1c2VyOiBSZWFjdC5Qcm9wVHlwZXMub2JqZWN0LFxuICAgIC8qKlxuICAgICAqIFRlYW0gZGF0YSwgcHJvcHMgbXVzdCBwYXNzIGF0IGxlYXN0IG9uZSBvZiAndXNlcicgb3IgJ3RlYW0nXG4gICAgICovXG4gICAgdGVhbTogUmVhY3QuUHJvcFR5cGVzLm9iamVjdCxcbiAgICAvKipcbiAgICAgKiBGb3IgdXNlcnMsIHdoZXRoZXIgaXQgaXMgZWRpdGFibGUgb3Igbm90XG4gICAgICovXG4gICAgdXNlckVkaXRhYmxlOiBSZWFjdC5Qcm9wVHlwZXMub2JqZWN0XG5cbn07XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IEFjdGlvbnNQYW5lbCA9IFB5ZGlvQ29udGV4dENvbnN1bWVyKEFjdGlvbnNQYW5lbCk7XG5leHBvcnRzWydkZWZhdWx0J10gPSBBY3Rpb25zUGFuZWwgPSBtdWlUaGVtZWFibGUoKShBY3Rpb25zUGFuZWwpO1xuXG5leHBvcnRzWydkZWZhdWx0J10gPSBBY3Rpb25zUGFuZWw7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTtcbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDE3IENoYXJsZXMgZHUgSmV1IC0gQWJzdHJpdW0gU0FTIDx0ZWFtIChhdCkgcHlkLmlvPlxuICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgUHlkaW8uXG4gKlxuICogUHlkaW8gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBQeWRpbyBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCBQeWRpby4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAqXG4gKiBUaGUgbGF0ZXN0IGNvZGUgY2FuIGJlIGZvdW5kIGF0IDxodHRwczovL3B5ZGlvLmNvbT4uXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyAnZGVmYXVsdCc6IG9iaiB9OyB9XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uJyk7IH0gfVxuXG5mdW5jdGlvbiBfaW5oZXJpdHMoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIHsgaWYgKHR5cGVvZiBzdXBlckNsYXNzICE9PSAnZnVuY3Rpb24nICYmIHN1cGVyQ2xhc3MgIT09IG51bGwpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignU3VwZXIgZXhwcmVzc2lvbiBtdXN0IGVpdGhlciBiZSBudWxsIG9yIGEgZnVuY3Rpb24sIG5vdCAnICsgdHlwZW9mIHN1cGVyQ2xhc3MpOyB9IHN1YkNsYXNzLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDbGFzcyAmJiBzdXBlckNsYXNzLnByb3RvdHlwZSwgeyBjb25zdHJ1Y3RvcjogeyB2YWx1ZTogc3ViQ2xhc3MsIGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogdHJ1ZSwgY29uZmlndXJhYmxlOiB0cnVlIH0gfSk7IGlmIChzdXBlckNsYXNzKSBPYmplY3Quc2V0UHJvdG90eXBlT2YgPyBPYmplY3Quc2V0UHJvdG90eXBlT2Yoc3ViQ2xhc3MsIHN1cGVyQ2xhc3MpIDogc3ViQ2xhc3MuX19wcm90b19fID0gc3VwZXJDbGFzczsgfVxuXG52YXIgX2FkZHJlc3Nib29rVXNlcnNMaXN0ID0gcmVxdWlyZSgnLi4vYWRkcmVzc2Jvb2svVXNlcnNMaXN0Jyk7XG5cbnZhciBfYWRkcmVzc2Jvb2tVc2Vyc0xpc3QyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfYWRkcmVzc2Jvb2tVc2Vyc0xpc3QpO1xuXG52YXIgX3JlcXVpcmUgPSByZXF1aXJlKCdyZWFjdCcpO1xuXG52YXIgQ29tcG9uZW50ID0gX3JlcXVpcmUuQ29tcG9uZW50O1xudmFyIFByb3BUeXBlcyA9IF9yZXF1aXJlLlByb3BUeXBlcztcblxudmFyIF9yZXF1aXJlMiA9IHJlcXVpcmUoJ21hdGVyaWFsLXVpJyk7XG5cbnZhciBEaXZpZGVyID0gX3JlcXVpcmUyLkRpdmlkZXI7XG5cbnZhciBfcmVxdWlyZTMgPSByZXF1aXJlKCdweWRpby9odHRwL3VzZXJzLWFwaScpO1xuXG52YXIgVXNlcnNBcGkgPSBfcmVxdWlyZTMuVXNlcnNBcGk7XG5cbnZhciBfcmVxdWlyZSRyZXF1aXJlTGliID0gcmVxdWlyZSgncHlkaW8nKS5yZXF1aXJlTGliKCdib290Jyk7XG5cbnZhciBQeWRpb0NvbnRleHRDb25zdW1lciA9IF9yZXF1aXJlJHJlcXVpcmVMaWIuUHlkaW9Db250ZXh0Q29uc3VtZXI7XG5cbi8qKlxuICogRGlzcGxheSBpbmZvcm1hdGlvbiBhYm91dCB1c2VyIG9yIHRlYW0gcmVsYXRpb25zXG4gKi9cblxudmFyIEdyYXBoUGFuZWwgPSAoZnVuY3Rpb24gKF9Db21wb25lbnQpIHtcbiAgICBfaW5oZXJpdHMoR3JhcGhQYW5lbCwgX0NvbXBvbmVudCk7XG5cbiAgICBmdW5jdGlvbiBHcmFwaFBhbmVsKCkge1xuICAgICAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgR3JhcGhQYW5lbCk7XG5cbiAgICAgICAgX0NvbXBvbmVudC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIH1cblxuICAgIEdyYXBoUGFuZWwucHJvdG90eXBlLnJlbmRlciA9IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgICAgdmFyIF9wcm9wcyA9IHRoaXMucHJvcHM7XG4gICAgICAgIHZhciBncmFwaCA9IF9wcm9wcy5ncmFwaDtcbiAgICAgICAgdmFyIHVzZXJMYWJlbCA9IF9wcm9wcy51c2VyTGFiZWw7XG4gICAgICAgIHZhciBweWRpbyA9IF9wcm9wcy5weWRpbztcbiAgICAgICAgdmFyIGdldE1lc3NhZ2UgPSBfcHJvcHMuZ2V0TWVzc2FnZTtcblxuICAgICAgICB2YXIgZWxlbWVudHMgPSBbXTtcbiAgICAgICAgaWYgKGdyYXBoLnRlYW1zICYmIGdyYXBoLnRlYW1zLmxlbmd0aCkge1xuICAgICAgICAgICAgdmFyIG9uRGVsZXRlQWN0aW9uID0gKGZ1bmN0aW9uIChwYXJlbnRJdGVtLCB0ZWFtKSB7XG4gICAgICAgICAgICAgICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgICAgICAgICAgICAgIFVzZXJzQXBpLnJlbW92ZVVzZXJGcm9tVGVhbSh0ZWFtWzBdLmlkLCB0aGlzLnByb3BzLnVzZXJJZCwgZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZS5tZXNzYWdlKSBweWRpby5VSS5kaXNwbGF5TWVzc2FnZSgnU1VDQ0VTUycsIHJlc3BvbnNlLm1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgICAgICBfdGhpcy5wcm9wcy5yZWxvYWRBY3Rpb24oKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pLmJpbmQodGhpcyk7XG4gICAgICAgICAgICBlbGVtZW50cy5wdXNoKFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgeyBrZXk6ICd0ZWFtcycgfSxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KERpdmlkZXIsIG51bGwpLFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoX2FkZHJlc3Nib29rVXNlcnNMaXN0MlsnZGVmYXVsdCddLCB7IHN1YkhlYWRlcjogZ2V0TWVzc2FnZSg1ODEpLnJlcGxhY2UoJyVzJywgZ3JhcGgudGVhbXMubGVuZ3RoKSwgb25JdGVtQ2xpY2tlZDogZnVuY3Rpb24gKCkge30sIGl0ZW06IHsgbGVhZnM6IGdyYXBoLnRlYW1zIH0sIG1vZGU6ICdpbm5lcicsIG9uRGVsZXRlQWN0aW9uOiBvbkRlbGV0ZUFjdGlvbiB9KVxuICAgICAgICAgICAgKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGdyYXBoLnNvdXJjZSAmJiBPYmplY3Qua2V5cyhncmFwaC5zb3VyY2UpLmxlbmd0aCkge1xuICAgICAgICAgICAgZWxlbWVudHMucHVzaChSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgIHsga2V5OiAnc291cmNlJyB9LFxuICAgICAgICAgICAgICAgIGVsZW1lbnRzLmxlbmd0aCA/IFJlYWN0LmNyZWF0ZUVsZW1lbnQoRGl2aWRlciwgbnVsbCkgOiBudWxsLFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgICAgICB7IHN0eWxlOiB7IHBhZGRpbmc6IDE2IH0gfSxcbiAgICAgICAgICAgICAgICAgICAgZ2V0TWVzc2FnZSg2MDEpLnJlcGxhY2UoJyUxJywgdXNlckxhYmVsKS5yZXBsYWNlKCclMicsIE9iamVjdC5rZXlzKGdyYXBoLnNvdXJjZSkubGVuZ3RoKVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICkpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChncmFwaC50YXJnZXQgJiYgT2JqZWN0LmtleXMoZ3JhcGgudGFyZ2V0KS5sZW5ndGgpIHtcbiAgICAgICAgICAgIGVsZW1lbnRzLnB1c2goUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICB7IGtleTogJ3RhcmdldCcgfSxcbiAgICAgICAgICAgICAgICBlbGVtZW50cy5sZW5ndGggPyBSZWFjdC5jcmVhdGVFbGVtZW50KERpdmlkZXIsIG51bGwpIDogbnVsbCxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICAgICAgeyBzdHlsZTogeyBwYWRkaW5nOiAxNiB9IH0sXG4gICAgICAgICAgICAgICAgICAgIGdldE1lc3NhZ2UoNjAyKS5yZXBsYWNlKCclMScsIHVzZXJMYWJlbCkucmVwbGFjZSgnJTInLCBPYmplY3Qua2V5cyhncmFwaC50YXJnZXQpLmxlbmd0aClcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICApKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgIGVsZW1lbnRzXG4gICAgICAgICk7XG4gICAgfTtcblxuICAgIHJldHVybiBHcmFwaFBhbmVsO1xufSkoQ29tcG9uZW50KTtcblxuZXhwb3J0c1snZGVmYXVsdCddID0gR3JhcGhQYW5lbCA9IFB5ZGlvQ29udGV4dENvbnN1bWVyKEdyYXBoUGFuZWwpO1xuZXhwb3J0c1snZGVmYXVsdCddID0gR3JhcGhQYW5lbDtcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1snZGVmYXVsdCddO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDA3LTIwMTcgQ2hhcmxlcyBkdSBKZXUgLSBBYnN0cml1bSBTQVMgPHRlYW0gKGF0KSBweWQuaW8+XG4gKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBQeWRpby5cbiAqXG4gKiBQeWRpbyBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFB5ZGlvIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIFB5ZGlvLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuICpcbiAqIFRoZSBsYXRlc3QgY29kZSBjYW4gYmUgZm91bmQgYXQgPGh0dHBzOi8vcHlkaW8uY29tPi5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5cbnZhciBfZXh0ZW5kcyA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gKHRhcmdldCkgeyBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgeyB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldOyBmb3IgKHZhciBrZXkgaW4gc291cmNlKSB7IGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoc291cmNlLCBrZXkpKSB7IHRhcmdldFtrZXldID0gc291cmNlW2tleV07IH0gfSB9IHJldHVybiB0YXJnZXQ7IH07XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7ICdkZWZhdWx0Jzogb2JqIH07IH1cblxuZnVuY3Rpb24gX2NsYXNzQ2FsbENoZWNrKGluc3RhbmNlLCBDb25zdHJ1Y3RvcikgeyBpZiAoIShpbnN0YW5jZSBpbnN0YW5jZW9mIENvbnN0cnVjdG9yKSkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb24nKTsgfSB9XG5cbmZ1bmN0aW9uIF9pbmhlcml0cyhzdWJDbGFzcywgc3VwZXJDbGFzcykgeyBpZiAodHlwZW9mIHN1cGVyQ2xhc3MgIT09ICdmdW5jdGlvbicgJiYgc3VwZXJDbGFzcyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgVHlwZUVycm9yKCdTdXBlciBleHByZXNzaW9uIG11c3QgZWl0aGVyIGJlIG51bGwgb3IgYSBmdW5jdGlvbiwgbm90ICcgKyB0eXBlb2Ygc3VwZXJDbGFzcyk7IH0gc3ViQ2xhc3MucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckNsYXNzICYmIHN1cGVyQ2xhc3MucHJvdG90eXBlLCB7IGNvbnN0cnVjdG9yOiB7IHZhbHVlOiBzdWJDbGFzcywgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlLCBjb25maWd1cmFibGU6IHRydWUgfSB9KTsgaWYgKHN1cGVyQ2xhc3MpIE9iamVjdC5zZXRQcm90b3R5cGVPZiA/IE9iamVjdC5zZXRQcm90b3R5cGVPZihzdWJDbGFzcywgc3VwZXJDbGFzcykgOiBzdWJDbGFzcy5fX3Byb3RvX18gPSBzdXBlckNsYXNzOyB9XG5cbnZhciBfR3JhcGhQYW5lbCA9IHJlcXVpcmUoJy4vR3JhcGhQYW5lbCcpO1xuXG52YXIgX0dyYXBoUGFuZWwyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfR3JhcGhQYW5lbCk7XG5cbnZhciBfQWN0aW9uc1BhbmVsID0gcmVxdWlyZSgnLi9BY3Rpb25zUGFuZWwnKTtcblxudmFyIF9BY3Rpb25zUGFuZWwyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfQWN0aW9uc1BhbmVsKTtcblxudmFyIGRlYm91bmNlID0gcmVxdWlyZSgnbG9kYXNoLmRlYm91bmNlJyk7XG52YXIgUmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpO1xudmFyIENvbG9yID0gcmVxdWlyZSgnY29sb3InKTtcblxudmFyIF9yZXF1aXJlID0gcmVxdWlyZSgnbWF0ZXJpYWwtdWknKTtcblxudmFyIEZvbnRJY29uID0gX3JlcXVpcmUuRm9udEljb247XG52YXIgUG9wb3ZlciA9IF9yZXF1aXJlLlBvcG92ZXI7XG52YXIgUGFwZXIgPSBfcmVxdWlyZS5QYXBlcjtcbnZhciBBdmF0YXIgPSBfcmVxdWlyZS5BdmF0YXI7XG52YXIgQ2FyZFRpdGxlID0gX3JlcXVpcmUuQ2FyZFRpdGxlO1xuXG52YXIgX3JlcXVpcmUyID0gcmVxdWlyZSgnbWF0ZXJpYWwtdWkvc3R5bGVzJyk7XG5cbnZhciBtdWlUaGVtZWFibGUgPSBfcmVxdWlyZTIubXVpVGhlbWVhYmxlO1xuXG52YXIgTWV0YUNhY2hlU2VydmljZSA9IHJlcXVpcmUoJ3B5ZGlvL2h0dHAvbWV0YS1jYWNoZS1zZXJ2aWNlJyk7XG52YXIgUHlkaW9BcGkgPSByZXF1aXJlKCdweWRpby9odHRwL2FwaScpO1xuXG4vKipcbiAqIEdlbmVyaWMgY29tcG9uZW50IGZvciBkaXNwbGF5IGEgdXNlciBhbmQgaGVyIGF2YXRhciAoZmlyc3QgbGV0dGVycyBvciBwaG90bylcbiAqL1xuXG52YXIgVXNlckF2YXRhciA9IChmdW5jdGlvbiAoX1JlYWN0JENvbXBvbmVudCkge1xuICAgIF9pbmhlcml0cyhVc2VyQXZhdGFyLCBfUmVhY3QkQ29tcG9uZW50KTtcblxuICAgIGZ1bmN0aW9uIFVzZXJBdmF0YXIocHJvcHMsIGNvbnRleHQpIHtcbiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFVzZXJBdmF0YXIpO1xuXG4gICAgICAgIF9SZWFjdCRDb21wb25lbnQuY2FsbCh0aGlzLCBwcm9wcywgY29udGV4dCk7XG4gICAgICAgIHRoaXMuc3RhdGUgPSB7XG4gICAgICAgICAgICB1c2VyOiBudWxsLFxuICAgICAgICAgICAgYXZhdGFyOiBudWxsLFxuICAgICAgICAgICAgZ3JhcGg6IG51bGxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBVc2VyQXZhdGFyLnByb3RvdHlwZS5jb21wb25lbnREaWRNb3VudCA9IGZ1bmN0aW9uIGNvbXBvbmVudERpZE1vdW50KCkge1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5weWRpby51c2VyICYmIHRoaXMucHJvcHMucHlkaW8udXNlci5pZCA9PT0gdGhpcy5wcm9wcy51c2VySWQpIHtcbiAgICAgICAgICAgIHRoaXMubG9hZExvY2FsRGF0YSgpO1xuICAgICAgICAgICAgaWYgKCF0aGlzLl91c2VyTG9nZ2VkT2JzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fdXNlckxvZ2dlZE9icyA9IHRoaXMubG9hZExvY2FsRGF0YS5iaW5kKHRoaXMpO1xuICAgICAgICAgICAgICAgIHRoaXMucHJvcHMucHlkaW8ub2JzZXJ2ZSgndXNlcl9sb2dnZWQnLCB0aGlzLl91c2VyTG9nZ2VkT2JzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLnByb3BzLnVzZXJUeXBlID09PSAndXNlcicpIHtcbiAgICAgICAgICAgIHRoaXMuY2FjaGUgPSBNZXRhQ2FjaGVTZXJ2aWNlLmdldEluc3RhbmNlKCk7XG4gICAgICAgICAgICB0aGlzLmNhY2hlLnJlZ2lzdGVyTWV0YVN0cmVhbSgndXNlcl9wdWJsaWNfZGF0YScsICdFWFBJUkFUSU9OX01BTlVBTF9UUklHR0VSJyk7XG4gICAgICAgICAgICB0aGlzLmNhY2hlLnJlZ2lzdGVyTWV0YVN0cmVhbSgndXNlcl9wdWJsaWNfZGF0YS1yaWNoJywgJ0VYUElSQVRJT05fTUFOVUFMX1RSSUdHRVInKTtcbiAgICAgICAgICAgIHRoaXMubG9hZFB1YmxpY0RhdGEodGhpcy5wcm9wcy51c2VySWQpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIFVzZXJBdmF0YXIucHJvdG90eXBlLmNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMgPSBmdW5jdGlvbiBjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzKG5leHRQcm9wcykge1xuICAgICAgICBpZiAoIXRoaXMucHJvcHMudXNlcklkIHx8IHRoaXMucHJvcHMudXNlcklkICE9PSBuZXh0UHJvcHMudXNlcklkKSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgbGFiZWw6IG5leHRQcm9wcy51c2VySWQgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMucHJvcHMucHlkaW8gJiYgdGhpcy5wcm9wcy5weWRpby51c2VyICYmIHRoaXMucHJvcHMucHlkaW8udXNlci5pZCA9PT0gbmV4dFByb3BzLnVzZXJJZCkge1xuICAgICAgICAgICAgdGhpcy5sb2FkTG9jYWxEYXRhKCk7XG4gICAgICAgICAgICBpZiAoIXRoaXMuX3VzZXJMb2dnZWRPYnMpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl91c2VyTG9nZ2VkT2JzID0gdGhpcy5sb2FkTG9jYWxEYXRhLmJpbmQodGhpcyk7XG4gICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5weWRpby5vYnNlcnZlKCd1c2VyX2xvZ2dlZCcsIHRoaXMuX3VzZXJMb2dnZWRPYnMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKHRoaXMuX3VzZXJMb2dnZWRPYnMpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnByb3BzLnB5ZGlvLnN0b3BPYnNlcnZpbmcoJ3VzZXJfbG9nZ2VkJywgdGhpcy5fdXNlckxvZ2dlZE9icyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmNhY2hlID0gTWV0YUNhY2hlU2VydmljZS5nZXRJbnN0YW5jZSgpO1xuICAgICAgICAgICAgdGhpcy5jYWNoZS5yZWdpc3Rlck1ldGFTdHJlYW0oJ3VzZXJfcHVibGljX2RhdGEnLCAnRVhQSVJBVElPTl9NQU5VQUxfVFJJR0dFUicpO1xuICAgICAgICAgICAgdGhpcy5jYWNoZS5yZWdpc3Rlck1ldGFTdHJlYW0oJ3VzZXJfcHVibGljX2RhdGEtcmljaCcsICdFWFBJUkFUSU9OX01BTlVBTF9UUklHR0VSJyk7XG4gICAgICAgICAgICB0aGlzLmxvYWRQdWJsaWNEYXRhKG5leHRQcm9wcy51c2VySWQpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIFVzZXJBdmF0YXIucHJvdG90eXBlLmNvbXBvbmVudFdpbGxVbm1vdW50ID0gZnVuY3Rpb24gY29tcG9uZW50V2lsbFVubW91bnQoKSB7XG4gICAgICAgIGlmICh0aGlzLl91c2VyTG9nZ2VkT2JzKSB7XG4gICAgICAgICAgICB0aGlzLnByb3BzLnB5ZGlvLnN0b3BPYnNlcnZpbmcoJ3VzZXJfbG9nZ2VkJywgdGhpcy5fdXNlckxvZ2dlZE9icyk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgVXNlckF2YXRhci5wcm90b3R5cGUubG9hZExvY2FsRGF0YSA9IGZ1bmN0aW9uIGxvYWRMb2NhbERhdGEoKSB7XG4gICAgICAgIHZhciBweWRpbyA9IHRoaXMucHJvcHMucHlkaW87XG5cbiAgICAgICAgaWYgKCFweWRpby51c2VyKSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgbGFiZWw6ICcnLCBhdmF0YXI6IG51bGwgfSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHVzZXJOYW1lID0gcHlkaW8udXNlci5nZXRQcmVmZXJlbmNlKCdVU0VSX0RJU1BMQVlfTkFNRScpIHx8IHB5ZGlvLnVzZXIuaWQ7XG4gICAgICAgIHZhciBhdmF0YXJJZCA9IHB5ZGlvLnVzZXIuZ2V0UHJlZmVyZW5jZSgnYXZhdGFyJyk7XG4gICAgICAgIHZhciBhdmF0YXJVcmwgPSBQeWRpb0FwaS5nZXRDbGllbnQoKS5idWlsZFVzZXJBdmF0YXJVcmwocHlkaW8udXNlci5pZCwgYXZhdGFySWQpO1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIGxhYmVsOiB1c2VyTmFtZSxcbiAgICAgICAgICAgIGF2YXRhcjogYXZhdGFyVXJsXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoIWF2YXRhclVybCkge1xuICAgICAgICAgICAgdGhpcy5sb2FkRnJvbUV4dGVybmFsUHJvdmlkZXIoKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBVc2VyQXZhdGFyLnByb3RvdHlwZS5sb2FkUHVibGljRGF0YSA9IGZ1bmN0aW9uIGxvYWRQdWJsaWNEYXRhKHVzZXJJZCkge1xuXG4gICAgICAgIHZhciBuYW1lc3BhY2UgPSB0aGlzLnByb3BzLnJpY2hDYXJkID8gJ3VzZXJfcHVibGljX2RhdGEtcmljaCcgOiAndXNlcl9wdWJsaWNfZGF0YSc7XG4gICAgICAgIGlmICh0aGlzLmNhY2hlLmhhc0tleShuYW1lc3BhY2UsIHVzZXJJZCkpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUodGhpcy5jYWNoZS5nZXRCeUtleShuYW1lc3BhY2UsIHVzZXJJZCkpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIFB5ZGlvQXBpLmdldENsaWVudCgpLnJlcXVlc3Qoe1xuICAgICAgICAgICAgZ2V0X2FjdGlvbjogJ3VzZXJfcHVibGljX2RhdGEnLFxuICAgICAgICAgICAgdXNlcl9pZDogdXNlcklkLFxuICAgICAgICAgICAgZ3JhcGg6IHRoaXMucHJvcHMucmljaENhcmQgPyAndHJ1ZScgOiAnZmFsc2UnXG4gICAgICAgIH0sIChmdW5jdGlvbiAodHJhbnNwb3J0KSB7XG4gICAgICAgICAgICB2YXIgZGF0YSA9IHRyYW5zcG9ydC5yZXNwb25zZUpTT047XG4gICAgICAgICAgICBpZiAoIWRhdGEgfHwgZGF0YS5lcnJvcikge1xuICAgICAgICAgICAgICAgIHRoaXMuY2FjaGUuc2V0S2V5KG5hbWVzcGFjZSwgdXNlcklkLCB7fSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIHVzZXIgPSBkYXRhLnVzZXI7XG4gICAgICAgICAgICB2YXIgZ3JhcGggPSBkYXRhLmdyYXBoO1xuXG4gICAgICAgICAgICB2YXIgYXZhdGFyVXJsID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgdmFyIGF2YXRhcklkID0gdXNlci5hdmF0YXIgfHwgbnVsbDtcbiAgICAgICAgICAgIHZhciBsYWJlbCA9IHVzZXIubGFiZWwgfHwgdXNlcklkO1xuICAgICAgICAgICAgaWYgKCF1c2VyLmF2YXRhcikge1xuICAgICAgICAgICAgICAgIHRoaXMubG9hZEZyb21FeHRlcm5hbFByb3ZpZGVyKCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGF2YXRhclVybCA9IFB5ZGlvQXBpLmdldENsaWVudCgpLmJ1aWxkVXNlckF2YXRhclVybCh1c2VySWQsIGF2YXRhcklkKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuY2FjaGUuc2V0S2V5KG5hbWVzcGFjZSwgdXNlcklkLCB7XG4gICAgICAgICAgICAgICAgdXNlcjogdXNlcixcbiAgICAgICAgICAgICAgICBncmFwaDogZ3JhcGgsXG4gICAgICAgICAgICAgICAgYXZhdGFyOiBhdmF0YXJVcmxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICAgICAgdXNlcjogdXNlcixcbiAgICAgICAgICAgICAgICBncmFwaDogZ3JhcGgsXG4gICAgICAgICAgICAgICAgYXZhdGFyOiBhdmF0YXJVcmxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KS5iaW5kKHRoaXMpKTtcbiAgICB9O1xuXG4gICAgVXNlckF2YXRhci5wcm90b3R5cGUubG9hZEZyb21FeHRlcm5hbFByb3ZpZGVyID0gZnVuY3Rpb24gbG9hZEZyb21FeHRlcm5hbFByb3ZpZGVyKCkge1xuICAgICAgICBpZiAoIXRoaXMucHJvcHMucHlkaW8uZ2V0UGx1Z2luQ29uZmlncyhcImFqeHBfcGx1Z2luW0BpZD0nYWN0aW9uLmF2YXRhciddXCIpLmdldChcIkFWQVRBUl9QUk9WSURFUlwiKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHZhciBuYW1lc3BhY2UgPSB0aGlzLnByb3BzLnJpY2hDYXJkID8gJ3VzZXJfcHVibGljX2RhdGEtcmljaCcgOiAndXNlcl9wdWJsaWNfZGF0YSc7XG4gICAgICAgIFB5ZGlvQXBpLmdldENsaWVudCgpLnJlcXVlc3Qoe1xuICAgICAgICAgICAgZ2V0X2FjdGlvbjogJ2dldF9hdmF0YXJfdXJsJyxcbiAgICAgICAgICAgIHVzZXJpZDogdGhpcy5wcm9wcy51c2VySWRcbiAgICAgICAgfSwgKGZ1bmN0aW9uICh0cmFuc3BvcnQpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBhdmF0YXI6IHRyYW5zcG9ydC5yZXNwb25zZVRleHQgfSk7XG4gICAgICAgIH0pLmJpbmQodGhpcykpO1xuICAgIH07XG5cbiAgICBVc2VyQXZhdGFyLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbiByZW5kZXIoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICAgICAgdmFyIF9zdGF0ZSA9IHRoaXMuc3RhdGU7XG4gICAgICAgIHZhciB1c2VyID0gX3N0YXRlLnVzZXI7XG4gICAgICAgIHZhciBhdmF0YXIgPSBfc3RhdGUuYXZhdGFyO1xuICAgICAgICB2YXIgZ3JhcGggPSBfc3RhdGUuZ3JhcGg7XG4gICAgICAgIHZhciBfcHJvcHMgPSB0aGlzLnByb3BzO1xuICAgICAgICB2YXIgcHlkaW8gPSBfcHJvcHMucHlkaW87XG4gICAgICAgIHZhciB1c2VySWQgPSBfcHJvcHMudXNlcklkO1xuICAgICAgICB2YXIgdXNlclR5cGUgPSBfcHJvcHMudXNlclR5cGU7XG4gICAgICAgIHZhciBpY29uID0gX3Byb3BzLmljb247XG4gICAgICAgIHZhciBzdHlsZSA9IF9wcm9wcy5zdHlsZTtcbiAgICAgICAgdmFyIGxhYmVsU3R5bGUgPSBfcHJvcHMubGFiZWxTdHlsZTtcbiAgICAgICAgdmFyIGF2YXRhclN0eWxlID0gX3Byb3BzLmF2YXRhclN0eWxlO1xuICAgICAgICB2YXIgYXZhdGFyU2l6ZSA9IF9wcm9wcy5hdmF0YXJTaXplO1xuICAgICAgICB2YXIgY2xhc3NOYW1lID0gX3Byb3BzLmNsYXNzTmFtZTtcbiAgICAgICAgdmFyIGF2YXRhckNsYXNzTmFtZSA9IF9wcm9wcy5hdmF0YXJDbGFzc05hbWU7XG4gICAgICAgIHZhciBsYWJlbENsYXNzTmFtZSA9IF9wcm9wcy5sYWJlbENsYXNzTmFtZTtcbiAgICAgICAgdmFyIGRpc3BsYXlMYWJlbCA9IF9wcm9wcy5kaXNwbGF5TGFiZWw7XG4gICAgICAgIHZhciBkaXNwbGF5QXZhdGFyID0gX3Byb3BzLmRpc3BsYXlBdmF0YXI7XG4gICAgICAgIHZhciB1c2VEZWZhdWx0QXZhdGFyID0gX3Byb3BzLnVzZURlZmF1bHRBdmF0YXI7XG4gICAgICAgIHZhciByaWNoQ2FyZCA9IF9wcm9wcy5yaWNoQ2FyZDtcbiAgICAgICAgdmFyIGNhcmRTaXplID0gX3Byb3BzLmNhcmRTaXplO1xuICAgICAgICB2YXIgbXVpVGhlbWUgPSBfcHJvcHMubXVpVGhlbWU7XG4gICAgICAgIHZhciBsYWJlbCA9IHRoaXMuc3RhdGUubGFiZWw7XG5cbiAgICAgICAgdmFyIHVzZXJUeXBlTGFiZWwgPSB1bmRlZmluZWQ7XG4gICAgICAgIGlmICh1c2VyKSB7XG4gICAgICAgICAgICBsYWJlbCA9IHVzZXIubGFiZWw7XG4gICAgICAgIH0gZWxzZSBpZiAoIWxhYmVsKSB7XG4gICAgICAgICAgICBsYWJlbCA9IHRoaXMucHJvcHMudXNlckxhYmVsIHx8IHRoaXMucHJvcHMudXNlcklkO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGF2YXRhckNvbnRlbnQgPSB1bmRlZmluZWQsXG4gICAgICAgICAgICBhdmF0YXJDb2xvciA9IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGF2YXRhckljb24gPSB1bmRlZmluZWQ7XG4gICAgICAgIGlmIChyaWNoQ2FyZCkge1xuICAgICAgICAgICAgZGlzcGxheUF2YXRhciA9IHVzZURlZmF1bHRBdmF0YXIgPSBkaXNwbGF5TGFiZWwgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChkaXNwbGF5QXZhdGFyICYmICFhdmF0YXIgJiYgbGFiZWwgJiYgKCFkaXNwbGF5TGFiZWwgfHwgdXNlRGVmYXVsdEF2YXRhcikpIHtcbiAgICAgICAgICAgIHZhciBhdmF0YXJzQ29sb3IgPSBtdWlUaGVtZS5wYWxldHRlLmF2YXRhcnNDb2xvcjtcbiAgICAgICAgICAgIGlmICh1c2VyVHlwZSA9PT0gJ2dyb3VwJyB8fCB1c2VyVHlwZSA9PT0gJ3RlYW0nIHx8IHVzZXJJZC5pbmRleE9mKCdBSlhQX0dSUF8vJykgPT09IDAgfHwgdXNlcklkLmluZGV4T2YoJy9BSlhQX1RFQU0vJykgPT09IDApIHtcbiAgICAgICAgICAgICAgICBhdmF0YXJzQ29sb3IgPSBDb2xvcihhdmF0YXJzQ29sb3IpLmRhcmtlbigwLjIpLnRvU3RyaW5nKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgaWNvbkNsYXNzTmFtZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIHN3aXRjaCAodXNlclR5cGUpIHtcbiAgICAgICAgICAgICAgICBjYXNlICdncm91cCc6XG4gICAgICAgICAgICAgICAgICAgIGljb25DbGFzc05hbWUgPSAnbWRpIG1kaS1hY2NvdW50LW11bHRpcGxlJztcbiAgICAgICAgICAgICAgICAgICAgdXNlclR5cGVMYWJlbCA9ICcyODknO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlICd0ZWFtJzpcbiAgICAgICAgICAgICAgICAgICAgaWNvbkNsYXNzTmFtZSA9ICdtZGkgbWRpLWFjY291bnQtbXVsdGlwbGUtb3V0bGluZSc7XG4gICAgICAgICAgICAgICAgICAgIHVzZXJUeXBlTGFiZWwgPSAnNjAzJztcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAncmVtb3RlJzpcbiAgICAgICAgICAgICAgICAgICAgaWNvbkNsYXNzTmFtZSA9ICdtZGkgbWRpLWFjY291bnQtbmV0d29yayc7XG4gICAgICAgICAgICAgICAgICAgIHVzZXJUeXBlTGFiZWwgPSAnNjA0JztcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgaWNvbkNsYXNzTmFtZSA9ICdtZGkgbWRpLWFjY291bnQnO1xuICAgICAgICAgICAgICAgICAgICB1c2VyVHlwZUxhYmVsID0gdXNlciA/IHVzZXIuZXh0ZXJuYWwgPyAnNTg5JyA6ICc1OTAnIDogJzI4OCc7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGljb24pIGljb25DbGFzc05hbWUgPSBpY29uO1xuICAgICAgICAgICAgaWYgKHVzZXJUeXBlTGFiZWwpIHVzZXJUeXBlTGFiZWwgPSBweWRpby5NZXNzYWdlSGFzaFt1c2VyVHlwZUxhYmVsXTtcbiAgICAgICAgICAgIGlmIChyaWNoQ2FyZCkge1xuICAgICAgICAgICAgICAgIGF2YXRhckljb24gPSBSZWFjdC5jcmVhdGVFbGVtZW50KEZvbnRJY29uLCB7IGNsYXNzTmFtZTogaWNvbkNsYXNzTmFtZSwgc3R5bGU6IHsgY29sb3I6IGF2YXRhcnNDb2xvciB9IH0pO1xuICAgICAgICAgICAgICAgIGF2YXRhckNvbG9yID0gJyNmNWY1ZjUnO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBhdmF0YXJDb2xvciA9IGF2YXRhcnNDb2xvcjtcbiAgICAgICAgICAgICAgICBpZiAoaWNvbkNsYXNzTmFtZSkge1xuICAgICAgICAgICAgICAgICAgICBhdmF0YXJJY29uID0gUmVhY3QuY3JlYXRlRWxlbWVudChGb250SWNvbiwgeyBjbGFzc05hbWU6IGljb25DbGFzc05hbWUgfSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgYXZhdGFyQ29udGVudCA9IGxhYmVsLnNwbGl0KCcgJykubWFwKGZ1bmN0aW9uICh3b3JkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gd29yZFswXTtcbiAgICAgICAgICAgICAgICAgICAgfSkuam9pbignJykuc3Vic3RyaW5nKDAsIDIpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoYXZhdGFyQ29udGVudC5sZW5ndGggPCAyKSBhdmF0YXJDb250ZW50ID0gbGFiZWwuc3Vic3RyaW5nKDAsIDIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB2YXIgcmVsb2FkQWN0aW9uID0gdW5kZWZpbmVkLFxuICAgICAgICAgICAgb25FZGl0QWN0aW9uID0gdW5kZWZpbmVkLFxuICAgICAgICAgICAgb25Nb3VzZU92ZXIgPSB1bmRlZmluZWQsXG4gICAgICAgICAgICBvbk1vdXNlT3V0ID0gdW5kZWZpbmVkLFxuICAgICAgICAgICAgcG9wb3ZlciA9IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKHJpY2hDYXJkKSB7XG4gICAgICAgICAgICAoZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICAgICAgZGlzcGxheUF2YXRhciA9IHRydWU7XG4gICAgICAgICAgICAgICAgc3R5bGUgPSBfZXh0ZW5kcyh7fSwgc3R5bGUsIHsgZmxleERpcmVjdGlvbjogJ2NvbHVtbicgfSk7XG4gICAgICAgICAgICAgICAgYXZhdGFyU2l6ZSA9IGNhcmRTaXplID8gY2FyZFNpemUgOiAnMTAwJSc7XG4gICAgICAgICAgICAgICAgYXZhdGFyU3R5bGUgPSB7IGJvcmRlclJhZGl1czogMCB9O1xuICAgICAgICAgICAgICAgIHZhciBsb2NhbFJlbG9hZCA9IGZ1bmN0aW9uIGxvY2FsUmVsb2FkKCkge1xuICAgICAgICAgICAgICAgICAgICBNZXRhQ2FjaGVTZXJ2aWNlLmdldEluc3RhbmNlKCkuZGVsZXRlS2V5KCd1c2VyX3B1YmxpY19kYXRhLXJpY2gnLCBfdGhpcy5wcm9wcy51c2VySWQpO1xuICAgICAgICAgICAgICAgICAgICBfdGhpcy5sb2FkUHVibGljRGF0YShfdGhpcy5wcm9wcy51c2VySWQpO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgcmVsb2FkQWN0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICBsb2NhbFJlbG9hZCgpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoX3RoaXMucHJvcHMucmVsb2FkQWN0aW9uKSBfdGhpcy5wcm9wcy5yZWxvYWRBY3Rpb24oKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIG9uRWRpdEFjdGlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgbG9jYWxSZWxvYWQoKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKF90aGlzLnByb3BzLm9uRWRpdEFjdGlvbikgX3RoaXMucHJvcHMub25FZGl0QWN0aW9uKCk7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH0pKCk7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5wcm9wcy5yaWNoT25Ib3Zlcikge1xuICAgICAgICAgICAgKGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgICAgIG9uTW91c2VPdXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghX3RoaXMubG9ja2VkQnlTdWJQb3BvdmVyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBfdGhpcy5zZXRTdGF0ZSh7IHNob3dQb3BvdmVyOiBmYWxzZSB9KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgb25Nb3VzZU91dCA9IGRlYm91bmNlKG9uTW91c2VPdXQsIDM1MCk7XG4gICAgICAgICAgICAgICAgb25Nb3VzZU92ZXIgPSBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgICAgICAgICBfdGhpcy5zZXRTdGF0ZSh7IHNob3dQb3BvdmVyOiB0cnVlLCBwb3BvdmVyQW5jaG9yOiBlLmN1cnJlbnRUYXJnZXQgfSk7XG4gICAgICAgICAgICAgICAgICAgIG9uTW91c2VPdXQuY2FuY2VsKCk7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB2YXIgb25Nb3VzZU92ZXJJbm5lciA9IGZ1bmN0aW9uIG9uTW91c2VPdmVySW5uZXIoZSkge1xuICAgICAgICAgICAgICAgICAgICBfdGhpcy5zZXRTdGF0ZSh7IHNob3dQb3BvdmVyOiB0cnVlIH0pO1xuICAgICAgICAgICAgICAgICAgICBvbk1vdXNlT3V0LmNhbmNlbCgpO1xuICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICB2YXIgbG9ja09uU3ViUG9wb3Zlck9wZW4gPSBmdW5jdGlvbiBsb2NrT25TdWJQb3BvdmVyT3BlbihzdGF0dXMpIHtcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMubG9ja2VkQnlTdWJQb3BvdmVyID0gc3RhdHVzO1xuICAgICAgICAgICAgICAgICAgICBvbk1vdXNlT3ZlcklubmVyKCk7XG4gICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgIHBvcG92ZXIgPSBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICBQb3BvdmVyLFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvcGVuOiBfdGhpcy5zdGF0ZS5zaG93UG9wb3ZlcixcbiAgICAgICAgICAgICAgICAgICAgICAgIGFuY2hvckVsOiBfdGhpcy5zdGF0ZS5wb3BvdmVyQW5jaG9yLFxuICAgICAgICAgICAgICAgICAgICAgICAgb25SZXF1ZXN0Q2xvc2U6IGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVhc29uICE9PSAnY2xpY2tBd2F5JyB8fCAhX3RoaXMubG9ja2VkQnlTdWJQb3BvdmVyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzLnNldFN0YXRlKHsgc2hvd1BvcG92ZXI6IGZhbHNlIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICBhbmNob3JPcmlnaW46IHsgaG9yaXpvbnRhbDogXCJsZWZ0XCIsIHZlcnRpY2FsOiBcImNlbnRlclwiIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRPcmlnaW46IHsgaG9yaXpvbnRhbDogXCJyaWdodFwiLCB2ZXJ0aWNhbDogXCJjZW50ZXJcIiB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgdXNlTGF5ZXJGb3JDbGlja0F3YXk6IGZhbHNlXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICAgICBQYXBlcixcbiAgICAgICAgICAgICAgICAgICAgICAgIHsgekRlcHRoOiAyLCBzdHlsZTogeyB3aWR0aDogMjIwLCBoZWlnaHQ6IDMyMCwgb3ZlcmZsb3dZOiAnYXV0bycgfSwgb25Nb3VzZU92ZXI6IG9uTW91c2VPdmVySW5uZXIsIG9uTW91c2VPdXQ6IG9uTW91c2VPdXQgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoVXNlckF2YXRhciwgX2V4dGVuZHMoe30sIF90aGlzLnByb3BzLCB7IHJpY2hDYXJkOiB0cnVlLCByaWNoT25Ib3ZlcjogZmFsc2UsIGNhcmRTaXplOiAyMjAsIGxvY2tPblN1YlBvcG92ZXJPcGVuOiBsb2NrT25TdWJQb3BvdmVyT3BlbiB9KSlcbiAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9KSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGF2YXRhckNvbXBvbmVudCA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICBBdmF0YXIsXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgc3JjOiBhdmF0YXIsXG4gICAgICAgICAgICAgICAgaWNvbjogYXZhdGFySWNvbixcbiAgICAgICAgICAgICAgICBzaXplOiBhdmF0YXJTaXplLFxuICAgICAgICAgICAgICAgIHN0eWxlOiB0aGlzLnByb3BzLmF2YXRhck9ubHkgPyB0aGlzLnByb3BzLnN0eWxlIDogYXZhdGFyU3R5bGUsXG4gICAgICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yOiBhdmF0YXJDb2xvclxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGF2YXRhckNvbnRlbnRcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAodGhpcy5wcm9wcy5hdmF0YXJPbmx5KSB7XG4gICAgICAgICAgICByZXR1cm4gYXZhdGFyQ29tcG9uZW50O1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgIHsgY2xhc3NOYW1lOiBjbGFzc05hbWUsIHN0eWxlOiBzdHlsZSwgb25Nb3VzZU92ZXI6IG9uTW91c2VPdmVyLCBvbk1vdXNlT3V0OiBvbk1vdXNlT3V0IH0sXG4gICAgICAgICAgICBkaXNwbGF5QXZhdGFyICYmIChhdmF0YXIgfHwgYXZhdGFyQ29udGVudCB8fCBhdmF0YXJJY29uKSAmJiBhdmF0YXJDb21wb25lbnQsXG4gICAgICAgICAgICBkaXNwbGF5TGFiZWwgJiYgIXJpY2hDYXJkICYmIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU6IGxhYmVsQ2xhc3NOYW1lLFxuICAgICAgICAgICAgICAgICAgICBzdHlsZTogbGFiZWxTdHlsZSB9LFxuICAgICAgICAgICAgICAgIGxhYmVsXG4gICAgICAgICAgICApLFxuICAgICAgICAgICAgZGlzcGxheUxhYmVsICYmIHJpY2hDYXJkICYmIFJlYWN0LmNyZWF0ZUVsZW1lbnQoQ2FyZFRpdGxlLCB7IHN0eWxlOiB7IHRleHRBbGlnbjogJ2NlbnRlcicgfSwgdGl0bGU6IGxhYmVsLCBzdWJ0aXRsZTogdXNlclR5cGVMYWJlbCB9KSxcbiAgICAgICAgICAgIHJpY2hDYXJkICYmIHVzZXIgJiYgUmVhY3QuY3JlYXRlRWxlbWVudChfQWN0aW9uc1BhbmVsMlsnZGVmYXVsdCddLCBfZXh0ZW5kcyh7fSwgdGhpcy5zdGF0ZSwgdGhpcy5wcm9wcywgeyByZWxvYWRBY3Rpb246IHJlbG9hZEFjdGlvbiwgb25FZGl0QWN0aW9uOiBvbkVkaXRBY3Rpb24gfSkpLFxuICAgICAgICAgICAgZ3JhcGggJiYgUmVhY3QuY3JlYXRlRWxlbWVudChfR3JhcGhQYW5lbDJbJ2RlZmF1bHQnXSwgX2V4dGVuZHMoeyBncmFwaDogZ3JhcGggfSwgdGhpcy5wcm9wcywgeyB1c2VyTGFiZWw6IGxhYmVsLCByZWxvYWRBY3Rpb246IHJlbG9hZEFjdGlvbiwgb25FZGl0QWN0aW9uOiBvbkVkaXRBY3Rpb24gfSkpLFxuICAgICAgICAgICAgdGhpcy5wcm9wcy5jaGlsZHJlbixcbiAgICAgICAgICAgIHBvcG92ZXJcbiAgICAgICAgKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIFVzZXJBdmF0YXI7XG59KShSZWFjdC5Db21wb25lbnQpO1xuXG5Vc2VyQXZhdGFyLnByb3BUeXBlcyA9IHtcbiAgICAvKipcbiAgICAgKiBJZCBvZiB0aGUgdXNlciB0byBiZSBsb2FkZWRcbiAgICAgKi9cbiAgICB1c2VySWQ6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcuaXNSZXF1aXJlZCxcbiAgICAvKipcbiAgICAgKiBQeWRpbyBpbnN0YW5jZVxuICAgICAqL1xuICAgIHB5ZGlvOiBSZWFjdC5Qcm9wVHlwZXMuaW5zdGFuY2VPZihQeWRpbyksXG4gICAgLyoqXG4gICAgICogTGFiZWwgb2YgdGhlIHVzZXIsIGlmIHdlIGFscmVhZHkgaGF2ZSBpdCAob3RoZXJ3aXNlIHdpbGwgYmUgbG9hZGVkKVxuICAgICAqL1xuICAgIHVzZXJMYWJlbDogUmVhY3QuUHJvcFR5cGVzLnN0cmluZyxcbiAgICAvKipcbiAgICAgKiBUeXBlIG9mIHVzZXJcbiAgICAgKi9cbiAgICB1c2VyVHlwZTogUmVhY3QuUHJvcFR5cGVzLm9uZU9mKFsndXNlcicsICdncm91cCcsICdyZW1vdGUnLCAndGVhbSddKSxcbiAgICAvKipcbiAgICAgKiBJY29uIHRvIGJlIGRpc3BsYXllZCBpbiBhdmF0YXJcbiAgICAgKi9cbiAgICBpY29uOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLFxuICAgIC8qKlxuICAgICAqIERpc3BsYXkgYSByaWNoIGNhcmQgb3IgYSBzaW1wbGUgYXZhdGFyK2xhYmVsIGNoaXBcbiAgICAgKi9cbiAgICByaWNoQ2FyZDogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXG4gICAgLyoqXG4gICAgICogSWYgbm90IHJpY2gsIGRpc3BsYXkgYSByaWNoIGNhcmQgYXMgcG9wb3ZlciBvbiBtb3VzZW92ZXJcbiAgICAgKi9cbiAgICByaWNoT25Ib3ZlcjogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXG5cbiAgICAvKipcbiAgICAgKiBBZGQgZWRpdCBhY3Rpb24gdG8gdGhlIGNhcmRcbiAgICAgKi9cbiAgICB1c2VyRWRpdGFibGU6IFJlYWN0LlByb3BUeXBlcy5ib29sLFxuICAgIC8qKlxuICAgICAqIFRyaWdnZXJlZCBhZnRlciBzdWNjZXNzZnVsIGVkaXRpb25cbiAgICAgKi9cbiAgICBvbkVkaXRBY3Rpb246IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgIC8qKlxuICAgICAqIFRyaWdnZXJlZCBhZnRlciBkZWxldGlvblxuICAgICAqL1xuICAgIG9uRGVsZXRlQWN0aW9uOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgICAvKipcbiAgICAgKiBUcmlnZ2VyZWQgaWYgYSByZWxvYWQgaXMgcmVxdWlyZWRcbiAgICAgKi9cbiAgICByZWxvYWRBY3Rpb246IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuXG4gICAgLyoqXG4gICAgICogRGlzcGxheSBsYWJlbCBlbGVtZW50IG9yIG5vdFxuICAgICAqL1xuICAgIGRpc3BsYXlMYWJlbDogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXG4gICAgLyoqXG4gICAgICogRGlzcGxheSBhdmF0YXIgZWxlbWVudCBvciBub3RcbiAgICAgKi9cbiAgICBkaXNwbGF5QXZhdGFyOiBSZWFjdC5Qcm9wVHlwZXMuYm9vbCxcbiAgICAvKipcbiAgICAgKiBEaXNwbGF5IG9ubHkgYXZhdGFyXG4gICAgICovXG4gICAgYXZhdGFyT25seTogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXG4gICAgLyoqXG4gICAgICogVXNlIGRlZmF1bHQgYXZhdGFyXG4gICAgICovXG4gICAgdXNlRGVmYXVsdEF2YXRhcjogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXG4gICAgLyoqXG4gICAgICogQXZhdGFyIHNpemUsIDQwcHggYnkgZGVmYXVsdFxuICAgICAqL1xuICAgIGF2YXRhclNpemU6IFJlYWN0LlByb3BUeXBlcy5udW1iZXIsXG5cbiAgICAvKipcbiAgICAgKiBBZGQgY2xhc3MgbmFtZSB0byByb290IGVsZW1lbnRcbiAgICAgKi9cbiAgICBjbGFzc05hbWU6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcsXG4gICAgLyoqXG4gICAgICogQWRkIGNsYXNzIG5hbWUgdG8gbGFiZWwgZWxlbWVudFxuICAgICAqL1xuICAgIGxhYmVsQ2xhc3NOYW1lOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLFxuICAgIC8qKlxuICAgICAqIEFkZCBjbGFzcyBuYW1lIHRvIGF2YXRhciBlbGVtZW50XG4gICAgICovXG4gICAgYXZhdGFyQ2xhc3NOYW1lOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLFxuICAgIC8qKlxuICAgICAqIEFkZCBzdHlsZSB0byByb290IGVsZW1lbnRcbiAgICAgKi9cbiAgICBzdHlsZTogUmVhY3QuUHJvcFR5cGVzLm9iamVjdCxcbiAgICAvKipcbiAgICAgKiBBZGQgc3R5bGUgdG8gbGFiZWwgZWxlbWVudFxuICAgICAqL1xuICAgIGxhYmVsU3R5bGU6IFJlYWN0LlByb3BUeXBlcy5vYmplY3QsXG4gICAgLyoqXG4gICAgICogQWRkIHN0eWxlIHRvIGF2YXRhciBlbGVtZW50XG4gICAgICovXG4gICAgYXZhdGFyU3R5bGU6IFJlYWN0LlByb3BUeXBlcy5vYmplY3Rcbn07XG5cblVzZXJBdmF0YXIuZGVmYXVsdFByb3BzID0ge1xuICAgIGRpc3BsYXlMYWJlbDogdHJ1ZSxcbiAgICBkaXNwbGF5QXZhdGFyOiB0cnVlLFxuICAgIGF2YXRhclNpemU6IDQwLFxuICAgIHVzZXJUeXBlOiAndXNlcicsXG4gICAgY2xhc3NOYW1lOiAndXNlci1hdmF0YXItd2lkZ2V0JyxcbiAgICBhdmF0YXJDbGFzc05hbWU6ICd1c2VyLWF2YXRhcicsXG4gICAgbGFiZWxDbGFzc05hbWU6ICd1c2VyLWxhYmVsJ1xufTtcblxuZXhwb3J0c1snZGVmYXVsdCddID0gVXNlckF2YXRhciA9IG11aVRoZW1lYWJsZSgpKFVzZXJBdmF0YXIpO1xuXG5leHBvcnRzWydkZWZhdWx0J10gPSBVc2VyQXZhdGFyO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMDctMjAxNyBDaGFybGVzIGR1IEpldSAtIEFic3RyaXVtIFNBUyA8dGVhbSAoYXQpIHB5ZC5pbz5cbiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIFB5ZGlvLlxuICpcbiAqIFB5ZGlvIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3JcbiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogUHlkaW8gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggUHlkaW8uICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gKlxuICogVGhlIGxhdGVzdCBjb2RlIGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9weWRpby5jb20+LlxuICovXG5cblwidXNlIHN0cmljdFwiO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfVxuXG52YXIgRnVuY1V0aWxzID0gcmVxdWlyZShcInB5ZGlvL3V0aWwvZnVuY1wiKTtcbnZhciBSZXNvdXJjZXNNYW5hZ2VyID0gcmVxdWlyZShcInB5ZGlvL2h0dHAvcmVzb3VyY2VzLW1hbmFnZXJcIik7XG5cbi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovXG4vKiBSRUFDVCBETkQgR0VORVJJQyBDT01QT05FTlRTXG4gLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cbnZhciBUeXBlcyA9IHtcbiAgICBOT0RFX1BST1ZJREVSOiAnbm9kZScsXG4gICAgU09SVEFCTEVfTElTVF9JVEVNOiAnc29ydGFibGUtbGlzdC1pdGVtJ1xufTtcblxuLyoqXG4gKiBTcGVjaWZpZXMgd2hpY2ggcHJvcHMgdG8gaW5qZWN0IGludG8geW91ciBjb21wb25lbnQuXG4gKi9cbmZ1bmN0aW9uIGNvbGxlY3QoY29ubmVjdCwgbW9uaXRvcikge1xuICAgIHJldHVybiB7XG4gICAgICAgIGNvbm5lY3REcmFnU291cmNlOiBjb25uZWN0LmRyYWdTb3VyY2UoKSxcbiAgICAgICAgaXNEcmFnZ2luZzogbW9uaXRvci5pc0RyYWdnaW5nKClcbiAgICB9O1xufVxuXG5mdW5jdGlvbiBjb2xsZWN0RHJvcChjb25uZWN0LCBtb25pdG9yKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgY29ubmVjdERyb3BUYXJnZXQ6IGNvbm5lY3QuZHJvcFRhcmdldCgpLFxuICAgICAgICBjYW5Ecm9wOiBtb25pdG9yLmNhbkRyb3AoKSxcbiAgICAgICAgaXNPdmVyOiBtb25pdG9yLmlzT3ZlcigpLFxuICAgICAgICBpc092ZXJDdXJyZW50OiBtb25pdG9yLmlzT3Zlcih7IHNoYWxsb3c6IHRydWUgfSlcbiAgICB9O1xufVxuXG52YXIgRE5EQWN0aW9uUGFyYW1ldGVyID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBETkRBY3Rpb25QYXJhbWV0ZXIoc291cmNlLCB0YXJnZXQsIHN0ZXApIHtcbiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIEROREFjdGlvblBhcmFtZXRlcik7XG5cbiAgICAgICAgdGhpcy5fc291cmNlID0gc291cmNlO1xuICAgICAgICB0aGlzLl90YXJnZXQgPSB0YXJnZXQ7XG4gICAgICAgIHRoaXMuX3N0ZXAgPSBzdGVwO1xuICAgIH1cblxuICAgIEROREFjdGlvblBhcmFtZXRlci5wcm90b3R5cGUuZ2V0U291cmNlID0gZnVuY3Rpb24gZ2V0U291cmNlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fc291cmNlO1xuICAgIH07XG5cbiAgICBETkRBY3Rpb25QYXJhbWV0ZXIucHJvdG90eXBlLmdldFRhcmdldCA9IGZ1bmN0aW9uIGdldFRhcmdldCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3RhcmdldDtcbiAgICB9O1xuXG4gICAgRE5EQWN0aW9uUGFyYW1ldGVyLnByb3RvdHlwZS5nZXRTdGVwID0gZnVuY3Rpb24gZ2V0U3RlcCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3N0ZXA7XG4gICAgfTtcblxuICAgIHJldHVybiBETkRBY3Rpb25QYXJhbWV0ZXI7XG59KSgpO1xuXG5ETkRBY3Rpb25QYXJhbWV0ZXIuU1RFUF9CRUdJTl9EUkFHID0gJ2JlZ2luRHJhZyc7XG5ETkRBY3Rpb25QYXJhbWV0ZXIuU1RFUF9FTkRfRFJBRyA9ICdlbmREcmFnJztcbkROREFjdGlvblBhcmFtZXRlci5TVEVQX0NBTl9EUk9QID0gJ2NhbkRyb3AnO1xuRE5EQWN0aW9uUGFyYW1ldGVyLlNURVBfSE9WRVJfRFJPUCA9ICdob3Zlcic7XG5cbnZhciBhcHBseUROREFjdGlvbiA9IGZ1bmN0aW9uIGFwcGx5RE5EQWN0aW9uKHNvdXJjZSwgdGFyZ2V0LCBzdGVwKSB7XG4gICAgdmFyIENvbnRyb2xsZXIgPSB3aW5kb3cucHlkaW8uQ29udHJvbGxlcjtcblxuICAgIHZhciBkbmQgPSBDb250cm9sbGVyLmRlZmF1bHRBY3Rpb25zLmdldChcImRyYWduZHJvcFwiKTtcbiAgICBpZiAoZG5kKSB7XG4gICAgICAgIHZhciBkbmRBY3Rpb24gPSBDb250cm9sbGVyLmdldEFjdGlvbkJ5TmFtZShkbmQpO1xuICAgICAgICBkbmRBY3Rpb24uZW5hYmxlKCk7XG4gICAgICAgIHZhciBwYXJhbXMgPSBuZXcgRE5EQWN0aW9uUGFyYW1ldGVyKHNvdXJjZSwgdGFyZ2V0LCBzdGVwKTtcbiAgICAgICAgdmFyIGNoZWNrTW9kdWxlID0gZG5kQWN0aW9uLm9wdGlvbnMuZHJhZ25kcm9wQ2hlY2tNb2R1bGU7XG4gICAgICAgIGlmIChzdGVwID09PSBETkRBY3Rpb25QYXJhbWV0ZXIuU1RFUF9DQU5fRFJPUCAmJiBjaGVja01vZHVsZSkge1xuICAgICAgICAgICAgaWYgKCFGdW5jVXRpbHMuZ2V0RnVuY3Rpb25CeU5hbWUoY2hlY2tNb2R1bGUsIHdpbmRvdykpIHtcbiAgICAgICAgICAgICAgICBSZXNvdXJjZXNNYW5hZ2VyLmRldGVjdE1vZHVsZVRvTG9hZEFuZEFwcGx5KGNoZWNrTW9kdWxlLCBmdW5jdGlvbiAoKSB7fSk7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW5ub3QgZmluZCB0ZXN0IG1vZHVsZSwgdHJ5aW5nIHRvIGxvYWQgaXQnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIEZ1bmNVdGlscy5leGVjdXRlRnVuY3Rpb25CeU5hbWUoZG5kQWN0aW9uLm9wdGlvbnMuZHJhZ25kcm9wQ2hlY2tNb2R1bGUsIHdpbmRvdywgQ29udHJvbGxlciwgcGFyYW1zKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGRuZEFjdGlvbi5hcHBseShwYXJhbXMpO1xuICAgICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyBETkQgQWN0aW9ucyBhdmFpbGFibGUnKTtcbiAgICB9XG59O1xuXG4vKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cbi8qIFJFQUNUIERORCBEUkFHL0RST1AgTk9ERVNcbiAvKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG52YXIgbm9kZURyYWdTb3VyY2UgPSB7XG4gICAgYmVnaW5EcmFnOiBmdW5jdGlvbiBiZWdpbkRyYWcocHJvcHMpIHtcbiAgICAgICAgLy8gUmV0dXJuIHRoZSBkYXRhIGRlc2NyaWJpbmcgdGhlIGRyYWdnZWQgaXRlbVxuICAgICAgICByZXR1cm4geyBub2RlOiBwcm9wcy5ub2RlIH07XG4gICAgfSxcblxuICAgIGVuZERyYWc6IGZ1bmN0aW9uIGVuZERyYWcocHJvcHMsIG1vbml0b3IsIGNvbXBvbmVudCkge1xuICAgICAgICBpZiAoIW1vbml0b3IuZGlkRHJvcCgpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGl0ZW0gPSBtb25pdG9yLmdldEl0ZW0oKTtcbiAgICAgICAgdmFyIGRyb3BSZXN1bHQgPSBtb25pdG9yLmdldERyb3BSZXN1bHQoKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGFwcGx5RE5EQWN0aW9uKGl0ZW0ubm9kZSwgZHJvcFJlc3VsdC5ub2RlLCBETkRBY3Rpb25QYXJhbWV0ZXIuU1RFUF9FTkRfRFJBRyk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHt9XG4gICAgfVxufTtcblxudmFyIG5vZGVEcm9wVGFyZ2V0ID0ge1xuXG4gICAgaG92ZXI6IGZ1bmN0aW9uIGhvdmVyKHByb3BzLCBtb25pdG9yKSB7fSxcblxuICAgIGNhbkRyb3A6IGZ1bmN0aW9uIGNhbkRyb3AocHJvcHMsIG1vbml0b3IpIHtcblxuICAgICAgICB2YXIgc291cmNlID0gbW9uaXRvci5nZXRJdGVtKCkubm9kZTtcbiAgICAgICAgdmFyIHRhcmdldCA9IHByb3BzLm5vZGU7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGFwcGx5RE5EQWN0aW9uKHNvdXJjZSwgdGFyZ2V0LCBETkRBY3Rpb25QYXJhbWV0ZXIuU1RFUF9DQU5fRFJPUCk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9LFxuXG4gICAgZHJvcDogZnVuY3Rpb24gZHJvcChwcm9wcywgbW9uaXRvcikge1xuICAgICAgICB2YXIgaGFzRHJvcHBlZE9uQ2hpbGQgPSBtb25pdG9yLmRpZERyb3AoKTtcbiAgICAgICAgaWYgKGhhc0Ryb3BwZWRPbkNoaWxkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsgbm9kZTogcHJvcHMubm9kZSB9O1xuICAgIH1cblxufTtcblxuZXhwb3J0cy5UeXBlcyA9IFR5cGVzO1xuZXhwb3J0cy5jb2xsZWN0ID0gY29sbGVjdDtcbmV4cG9ydHMuY29sbGVjdERyb3AgPSBjb2xsZWN0RHJvcDtcbmV4cG9ydHMubm9kZURyYWdTb3VyY2UgPSBub2RlRHJhZ1NvdXJjZTtcbmV4cG9ydHMubm9kZURyb3BUYXJnZXQgPSBub2RlRHJvcFRhcmdldDtcbmV4cG9ydHMuRE5EQWN0aW9uUGFyYW1ldGVyID0gRE5EQWN0aW9uUGFyYW1ldGVyO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDA3LTIwMTcgQ2hhcmxlcyBkdSBKZXUgLSBBYnN0cml1bSBTQVMgPHRlYW0gKGF0KSBweWQuaW8+XG4gKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBQeWRpby5cbiAqXG4gKiBQeWRpbyBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5XG4gKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFB5ZGlvIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsXG4gKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZlxuICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZVxuICogR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIFB5ZGlvLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuICpcbiAqIFRoZSBsYXRlc3QgY29kZSBjYW4gYmUgZm91bmQgYXQgPGh0dHBzOi8vcHlkaW8uY29tPi5cbiAqL1xuXG5cInVzZSBzdHJpY3RcIjtcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcbmV4cG9ydHNbXCJkZWZhdWx0XCJdID0ge1xuICAgIGNvbnRleHRUeXBlczoge1xuICAgICAgICBtZXNzYWdlczogUmVhY3QuUHJvcFR5cGVzLm9iamVjdCxcbiAgICAgICAgZ2V0TWVzc2FnZTogUmVhY3QuUHJvcFR5cGVzLmZ1bmNcbiAgICB9XG59O1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzW1wiZGVmYXVsdFwiXTtcbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDE3IENoYXJsZXMgZHUgSmV1IC0gQWJzdHJpdW0gU0FTIDx0ZWFtIChhdCkgcHlkLmlvPlxuICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgUHlkaW8uXG4gKlxuICogUHlkaW8gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBQeWRpbyBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCBQeWRpby4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAqXG4gKiBUaGUgbGF0ZXN0IGNvZGUgY2FuIGJlIGZvdW5kIGF0IDxodHRwczovL3B5ZGlvLmNvbT4uXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG52YXIgX2V4dGVuZHMgPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uICh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTsgZm9yICh2YXIga2V5IGluIHNvdXJjZSkgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkgeyB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldOyB9IH0gfSByZXR1cm4gdGFyZ2V0OyB9O1xuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbicpOyB9IH1cblxuZnVuY3Rpb24gX2luaGVyaXRzKHN1YkNsYXNzLCBzdXBlckNsYXNzKSB7IGlmICh0eXBlb2Ygc3VwZXJDbGFzcyAhPT0gJ2Z1bmN0aW9uJyAmJiBzdXBlckNsYXNzICE9PSBudWxsKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ1N1cGVyIGV4cHJlc3Npb24gbXVzdCBlaXRoZXIgYmUgbnVsbCBvciBhIGZ1bmN0aW9uLCBub3QgJyArIHR5cGVvZiBzdXBlckNsYXNzKTsgfSBzdWJDbGFzcy5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ2xhc3MgJiYgc3VwZXJDbGFzcy5wcm90b3R5cGUsIHsgY29uc3RydWN0b3I6IHsgdmFsdWU6IHN1YkNsYXNzLCBlbnVtZXJhYmxlOiBmYWxzZSwgd3JpdGFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSB9IH0pOyBpZiAoc3VwZXJDbGFzcykgT2JqZWN0LnNldFByb3RvdHlwZU9mID8gT2JqZWN0LnNldFByb3RvdHlwZU9mKHN1YkNsYXNzLCBzdXBlckNsYXNzKSA6IHN1YkNsYXNzLl9fcHJvdG9fXyA9IHN1cGVyQ2xhc3M7IH1cblxudmFyIF9yZXF1aXJlID0gcmVxdWlyZSgncmVhY3QnKTtcblxudmFyIENvbXBvbmVudCA9IF9yZXF1aXJlLkNvbXBvbmVudDtcbnZhciBQcm9wVHlwZXMgPSBfcmVxdWlyZS5Qcm9wVHlwZXM7XG5cbnZhciBfcmVxdWlyZTIgPSByZXF1aXJlKCdtYXRlcmlhbC11aScpO1xuXG52YXIgRmxhdEJ1dHRvbiA9IF9yZXF1aXJlMi5GbGF0QnV0dG9uO1xudmFyIEZvbnRJY29uID0gX3JlcXVpcmUyLkZvbnRJY29uO1xuXG52YXIgX3JlcXVpcmUzID0gcmVxdWlyZSgnbWF0ZXJpYWwtdWkvc3R5bGVzJyk7XG5cbnZhciBtdWlUaGVtZWFibGUgPSBfcmVxdWlyZTMubXVpVGhlbWVhYmxlO1xuXG52YXIgQ29sb3IgPSByZXF1aXJlKCdjb2xvcicpO1xudmFyIFB5ZGlvID0gcmVxdWlyZSgncHlkaW8nKTtcblxudmFyIF9QeWRpbyRyZXF1aXJlTGliID0gUHlkaW8ucmVxdWlyZUxpYignYm9vdCcpO1xuXG52YXIgUHlkaW9Db250ZXh0Q29uc3VtZXIgPSBfUHlkaW8kcmVxdWlyZUxpYi5QeWRpb0NvbnRleHRDb25zdW1lcjtcblxudmFyIEVtcHR5U3RhdGVWaWV3ID0gKGZ1bmN0aW9uIChfQ29tcG9uZW50KSB7XG4gICAgX2luaGVyaXRzKEVtcHR5U3RhdGVWaWV3LCBfQ29tcG9uZW50KTtcblxuICAgIGZ1bmN0aW9uIEVtcHR5U3RhdGVWaWV3KHByb3BzLCBjb250ZXh0KSB7XG4gICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBFbXB0eVN0YXRlVmlldyk7XG5cbiAgICAgICAgX0NvbXBvbmVudC5jYWxsKHRoaXMsIHByb3BzLCBjb250ZXh0KTtcbiAgICB9XG5cbiAgICBFbXB0eVN0YXRlVmlldy5wcm90b3R5cGUucmVuZGVyID0gZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgICB2YXIgX3Byb3BzID0gdGhpcy5wcm9wcztcbiAgICAgICAgdmFyIHN0eWxlID0gX3Byb3BzLnN0eWxlO1xuICAgICAgICB2YXIgaWNvbkNsYXNzTmFtZSA9IF9wcm9wcy5pY29uQ2xhc3NOYW1lO1xuICAgICAgICB2YXIgcHJpbWFyeVRleHRJZCA9IF9wcm9wcy5wcmltYXJ5VGV4dElkO1xuICAgICAgICB2YXIgc2Vjb25kYXJ5VGV4dElkID0gX3Byb3BzLnNlY29uZGFyeVRleHRJZDtcbiAgICAgICAgdmFyIGFjdGlvbkxhYmVsSWQgPSBfcHJvcHMuYWN0aW9uTGFiZWxJZDtcbiAgICAgICAgdmFyIGFjdGlvbkNhbGxiYWNrID0gX3Byb3BzLmFjdGlvbkNhbGxiYWNrO1xuICAgICAgICB2YXIgYWN0aW9uU3R5bGUgPSBfcHJvcHMuYWN0aW9uU3R5bGU7XG4gICAgICAgIHZhciBhY3Rpb25JY29uQ2xhc3NOYW1lID0gX3Byb3BzLmFjdGlvbkljb25DbGFzc05hbWU7XG4gICAgICAgIHZhciBnZXRNZXNzYWdlID0gX3Byb3BzLmdldE1lc3NhZ2U7XG5cbiAgICAgICAgdmFyIG1haW5Db2xvciA9IENvbG9yKHRoaXMucHJvcHMubXVpVGhlbWUucGFsZXR0ZS5wcmltYXJ5MUNvbG9yKTtcblxuICAgICAgICB2YXIgc3R5bGVzID0ge1xuICAgICAgICAgICAgY29udGFpbmVyOiBfZXh0ZW5kcyh7XG4gICAgICAgICAgICAgICAgZGlzcGxheTogJ2ZsZXgnLFxuICAgICAgICAgICAgICAgIGFsaWduSXRlbXM6ICdjZW50ZXInLFxuICAgICAgICAgICAgICAgIGp1c3RpZnlDb250ZW50OiAnY2VudGVyJyxcbiAgICAgICAgICAgICAgICBoZWlnaHQ6ICcxMDAlJyxcbiAgICAgICAgICAgICAgICB3aWR0aDogJzEwMCUnLFxuICAgICAgICAgICAgICAgIGZsZXg6IDEsXG4gICAgICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yOiBtYWluQ29sb3IubGlnaHRuZXNzKDk3KS5yZ2IoKS50b1N0cmluZygpXG4gICAgICAgICAgICB9LCBzdHlsZSksXG4gICAgICAgICAgICBjZW50ZXJlZDoge1xuICAgICAgICAgICAgICAgIG1heFdpZHRoOiAyODAsXG4gICAgICAgICAgICAgICAgdGV4dEFsaWduOiAnY2VudGVyJyxcbiAgICAgICAgICAgICAgICBjb2xvcjogbWFpbkNvbG9yLmZhZGUoMC42KS50b1N0cmluZygpXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgaWNvbjoge1xuICAgICAgICAgICAgICAgIGZvbnRTaXplOiAxMDBcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBwcmltYXJ5VGV4dDoge1xuICAgICAgICAgICAgICAgIGZvbnRTaXplOiAxNixcbiAgICAgICAgICAgICAgICBmb250V2VpZ2h0OiA1MDBcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzZWNvbmRhcnlUZXh0OiB7XG4gICAgICAgICAgICAgICAgbWFyZ2luVG9wOiAyMCxcbiAgICAgICAgICAgICAgICBmb250U2l6ZTogMTNcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBidXR0b25Db250YWluZXI6IHtcbiAgICAgICAgICAgICAgICBtYXJnaW5Ub3A6IDEwMCxcbiAgICAgICAgICAgICAgICB0ZXh0QWxpZ246ICdjZW50ZXInXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYnV0dG9uU3R5bGU6IHtcbiAgICAgICAgICAgICAgICBjb2xvcjogdGhpcy5wcm9wcy5tdWlUaGVtZS5wYWxldHRlLmFjY2VudDJDb2xvclxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICB2YXIgYnV0dG9uSWNvbiA9IGFjdGlvbkljb25DbGFzc05hbWUgPyBSZWFjdC5jcmVhdGVFbGVtZW50KEZvbnRJY29uLCB7IGNsYXNzTmFtZTogYWN0aW9uSWNvbkNsYXNzTmFtZSB9KSA6IG51bGw7XG4gICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICB7IHN0eWxlOiBzdHlsZXMuY29udGFpbmVyIH0sXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgIHsgc3R5bGU6IHN0eWxlcy5jZW50ZXJlZCB9LFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoJ2RpdicsIHsgY2xhc3NOYW1lOiBpY29uQ2xhc3NOYW1lLCBzdHlsZTogc3R5bGVzLmljb24gfSksXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgICAgIHsgc3R5bGU6IHN0eWxlcy5wcmltYXJ5VGV4dCB9LFxuICAgICAgICAgICAgICAgICAgICBnZXRNZXNzYWdlKHByaW1hcnlUZXh0SWQpXG4gICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICBzZWNvbmRhcnlUZXh0SWQgJiYgUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgICAgIHsgc3R5bGU6IHN0eWxlcy5zZWNvbmRhcnlUZXh0IH0sXG4gICAgICAgICAgICAgICAgICAgIGdldE1lc3NhZ2Uoc2Vjb25kYXJ5VGV4dElkKVxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgYWN0aW9uTGFiZWxJZCAmJiBhY3Rpb25DYWxsYmFjayAmJiBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICAgICAgeyBzdHlsZTogX2V4dGVuZHMoe30sIHN0eWxlcy5idXR0b25Db250YWluZXIsIGFjdGlvblN0eWxlKSB9LFxuICAgICAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KEZsYXRCdXR0b24sIHsgc3R5bGU6IHN0eWxlcy5idXR0b25TdHlsZSwgbGFiZWw6IGdldE1lc3NhZ2UoYWN0aW9uTGFiZWxJZCksIG9uVG91Y2hUYXA6IGFjdGlvbkNhbGxiYWNrLCBpY29uOiBidXR0b25JY29uIH0pXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKVxuICAgICAgICApO1xuICAgIH07XG5cbiAgICByZXR1cm4gRW1wdHlTdGF0ZVZpZXc7XG59KShDb21wb25lbnQpO1xuXG5FbXB0eVN0YXRlVmlldy5wcm9wVHlwZXMgPSB7XG5cbiAgICBweWRpbzogUHJvcFR5cGVzLmluc3RhbmNlT2YoUHlkaW8pLmlzUmVxdWlyZWQsXG4gICAgaWNvbkNsYXNzTmFtZTogUHJvcFR5cGVzLnN0cmluZy5pc1JlcXVpcmVkLFxuICAgIHByaW1hcnlUZXh0SWQ6IFByb3BUeXBlcy5zdHJpbmcuaXNSZXF1aXJlZCxcblxuICAgIHNlY29uZGFyeVRleHRJZDogUHJvcFR5cGVzLnN0cmluZyxcbiAgICBhY3Rpb25MYWJlbElkOiBQcm9wVHlwZXMuc3RyaW5nLFxuICAgIGFjdGlvbkNhbGxiYWNrOiBQcm9wVHlwZXMuZnVuYyxcbiAgICBhY3Rpb25TdHlsZTogUHJvcFR5cGVzLm9iamVjdCxcblxuICAgIHN0eWxlOiBQcm9wVHlwZXMub2JqZWN0LFxuICAgIGdldE1lc3NhZ2U6IFByb3BUeXBlcy5mdW5jXG5cbn07XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IEVtcHR5U3RhdGVWaWV3ID0gUHlkaW9Db250ZXh0Q29uc3VtZXIoRW1wdHlTdGF0ZVZpZXcpO1xuZXhwb3J0c1snZGVmYXVsdCddID0gRW1wdHlTdGF0ZVZpZXcgPSBtdWlUaGVtZWFibGUoKShFbXB0eVN0YXRlVmlldyk7XG5cbmV4cG9ydHNbJ2RlZmF1bHQnXSA9IEVtcHR5U3RhdGVWaWV3O1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMDctMjAxNyBDaGFybGVzIGR1IEpldSAtIEFic3RyaXVtIFNBUyA8dGVhbSAoYXQpIHB5ZC5pbz5cbiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIFB5ZGlvLlxuICpcbiAqIFB5ZGlvIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3JcbiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogUHlkaW8gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggUHlkaW8uICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gKlxuICogVGhlIGxhdGVzdCBjb2RlIGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9weWRpby5jb20+LlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxudmFyIF9leHRlbmRzID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiAodGFyZ2V0KSB7IGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7IHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV07IGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHsgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHsgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTsgfSB9IH0gcmV0dXJuIHRhcmdldDsgfTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgJ2RlZmF1bHQnOiBvYmogfTsgfVxuXG5mdW5jdGlvbiBfb2JqZWN0V2l0aG91dFByb3BlcnRpZXMob2JqLCBrZXlzKSB7IHZhciB0YXJnZXQgPSB7fTsgZm9yICh2YXIgaSBpbiBvYmopIHsgaWYgKGtleXMuaW5kZXhPZihpKSA+PSAwKSBjb250aW51ZTsgaWYgKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBpKSkgY29udGludWU7IHRhcmdldFtpXSA9IG9ialtpXTsgfSByZXR1cm4gdGFyZ2V0OyB9XG5cbnZhciBfcmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpO1xuXG52YXIgX3JlYWN0MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3JlYWN0KTtcblxudmFyIF9tYXRlcmlhbFVpID0gcmVxdWlyZSgnbWF0ZXJpYWwtdWknKTtcblxudmFyIE1vZGFsQXBwQmFyID0gZnVuY3Rpb24gTW9kYWxBcHBCYXIocHJvcHMpIHtcbiAgICB2YXIgc3R5bGUgPSBwcm9wcy5zdHlsZTtcbiAgICB2YXIgdGl0bGVTdHlsZSA9IHByb3BzLnRpdGxlU3R5bGU7XG4gICAgdmFyIGljb25TdHlsZVJpZ2h0ID0gcHJvcHMuaWNvblN0eWxlUmlnaHQ7XG4gICAgdmFyIGljb25TdHlsZUxlZnQgPSBwcm9wcy5pY29uU3R5bGVMZWZ0O1xuXG4gICAgdmFyIG90aGVyUHJvcHMgPSBfb2JqZWN0V2l0aG91dFByb3BlcnRpZXMocHJvcHMsIFsnc3R5bGUnLCAndGl0bGVTdHlsZScsICdpY29uU3R5bGVSaWdodCcsICdpY29uU3R5bGVMZWZ0J10pO1xuXG4gICAgdmFyIHN0eWxlcyA9IHtcbiAgICAgICAgc3R5bGU6IF9leHRlbmRzKHtcbiAgICAgICAgICAgIGZsZXhTaHJpbms6IDBcbiAgICAgICAgfSwgc3R5bGUpLFxuICAgICAgICB0aXRsZVN0eWxlOiBfZXh0ZW5kcyh7XG4gICAgICAgICAgICBsaW5lSGVpZ2h0OiAnNTZweCcsXG4gICAgICAgICAgICBoZWlnaHQ6IDU2LFxuICAgICAgICAgICAgbWFyZ2luTGVmdDogLThcbiAgICAgICAgfSwgdGl0bGVTdHlsZSksXG4gICAgICAgIGljb25TdHlsZVJpZ2h0OiBfZXh0ZW5kcyh7XG4gICAgICAgICAgICBtYXJnaW5Ub3A6IDRcbiAgICAgICAgfSwgaWNvblN0eWxlUmlnaHQpLFxuICAgICAgICBpY29uU3R5bGVMZWZ0OiBfZXh0ZW5kcyh7XG4gICAgICAgICAgICBtYXJnaW5Ub3A6IDRcbiAgICAgICAgfSwgaWNvblN0eWxlTGVmdClcbiAgICB9O1xuXG4gICAgcmV0dXJuIF9yZWFjdDJbJ2RlZmF1bHQnXS5jcmVhdGVFbGVtZW50KF9tYXRlcmlhbFVpLkFwcEJhciwgX2V4dGVuZHMoe30sIG90aGVyUHJvcHMsIHN0eWxlcykpO1xufTtcblxuZXhwb3J0c1snZGVmYXVsdCddID0gTW9kYWxBcHBCYXI7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTtcbi8qYm9yZGVyUmFkaXVzOiAnMnB4IDJweCAwIDAnLCovXG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMDctMjAxNyBDaGFybGVzIGR1IEpldSAtIEFic3RyaXVtIFNBUyA8dGVhbSAoYXQpIHB5ZC5pbz5cbiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIFB5ZGlvLlxuICpcbiAqIFB5ZGlvIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3JcbiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogUHlkaW8gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggUHlkaW8uICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gKlxuICogVGhlIGxhdGVzdCBjb2RlIGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9weWRpby5jb20+LlxuICovXG5cbi8qKlxuICogU2VhcmNoIGlucHV0IGJ1aWxkaW5nIGEgc2V0IG9mIHF1ZXJ5IHBhcmFtZXRlcnMgYW5kIGNhbGxpbmdcbiAqIHRoZSBjYWxsYmFja3MgdG8gZGlzcGxheSAvIGhpZGUgcmVzdWx0c1xuICovXG4ndXNlIHN0cmljdCc7XG5cbmV4cG9ydHMuX19lc01vZHVsZSA9IHRydWU7XG5leHBvcnRzWydkZWZhdWx0J10gPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG4gICAgZGlzcGxheU5hbWU6ICdTZWFyY2hCb3gnLFxuXG4gICAgcHJvcFR5cGVzOiB7XG4gICAgICAgIC8vIFJlcXVpcmVkXG4gICAgICAgIHBhcmFtZXRlcnM6IFJlYWN0LlByb3BUeXBlcy5vYmplY3QuaXNSZXF1aXJlZCxcbiAgICAgICAgcXVlcnlQYXJhbWV0ZXJOYW1lOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLmlzUmVxdWlyZWQsXG4gICAgICAgIC8vIE90aGVyXG4gICAgICAgIHRleHRMYWJlbDogUmVhY3QuUHJvcFR5cGVzLnN0cmluZyxcbiAgICAgICAgZGlzcGxheVJlc3VsdHM6IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgICAgICBoaWRlUmVzdWx0czogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsXG4gICAgICAgIGRpc3BsYXlSZXN1bHRzU3RhdGU6IFJlYWN0LlByb3BUeXBlcy5ib29sLFxuICAgICAgICBsaW1pdDogUmVhY3QuUHJvcFR5cGVzLm51bWJlclxuICAgIH0sXG5cbiAgICBnZXRJbml0aWFsU3RhdGU6IGZ1bmN0aW9uIGdldEluaXRpYWxTdGF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGRpc3BsYXlSZXN1bHQ6IHRoaXMucHJvcHMuZGlzcGxheVJlc3VsdHNTdGF0ZSA/IHRydWUgOiBmYWxzZVxuICAgICAgICB9O1xuICAgIH0sXG5cbiAgICBnZXREZWZhdWx0UHJvcHM6IGZ1bmN0aW9uIGdldERlZmF1bHRQcm9wcygpIHtcbiAgICAgICAgdmFyIGRtID0gbmV3IFB5ZGlvRGF0YU1vZGVsKCk7XG4gICAgICAgIGRtLnNldFJvb3ROb2RlKG5ldyBBanhwTm9kZSgpKTtcbiAgICAgICAgcmV0dXJuIHsgZGF0YU1vZGVsOiBkbSB9O1xuICAgIH0sXG5cbiAgICBkaXNwbGF5UmVzdWx0c1N0YXRlOiBmdW5jdGlvbiBkaXNwbGF5UmVzdWx0c1N0YXRlKCkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIGRpc3BsYXlSZXN1bHQ6IHRydWVcbiAgICAgICAgfSk7XG4gICAgfSxcblxuICAgIGhpZGVSZXN1bHRzU3RhdGU6IGZ1bmN0aW9uIGhpZGVSZXN1bHRzU3RhdGUoKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgZGlzcGxheVJlc3VsdDogZmFsc2VcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMucHJvcHMuaGlkZVJlc3VsdHMoKTtcbiAgICB9LFxuXG4gICAgb25DbGlja1NlYXJjaDogZnVuY3Rpb24gb25DbGlja1NlYXJjaCgpIHtcbiAgICAgICAgdmFyIHZhbHVlID0gdGhpcy5yZWZzLnF1ZXJ5LmdldFZhbHVlKCk7XG4gICAgICAgIHZhciBkbSA9IHRoaXMucHJvcHMuZGF0YU1vZGVsO1xuICAgICAgICB2YXIgcGFyYW1zID0gdGhpcy5wcm9wcy5wYXJhbWV0ZXJzO1xuICAgICAgICBwYXJhbXNbdGhpcy5wcm9wcy5xdWVyeVBhcmFtZXRlck5hbWVdID0gdmFsdWU7XG4gICAgICAgIHBhcmFtc1snbGltaXQnXSA9IHRoaXMucHJvcHMubGltaXQgfHwgMTAwO1xuICAgICAgICBkbS5nZXRSb290Tm9kZSgpLnNldENoaWxkcmVuKFtdKTtcbiAgICAgICAgUHlkaW9BcGkuZ2V0Q2xpZW50KCkucmVxdWVzdChwYXJhbXMsIChmdW5jdGlvbiAodHJhbnNwb3J0KSB7XG4gICAgICAgICAgICB2YXIgcmVtb3RlTm9kZVByb3ZpZGVyID0gbmV3IFJlbW90ZU5vZGVQcm92aWRlcih7fSk7XG4gICAgICAgICAgICByZW1vdGVOb2RlUHJvdmlkZXIucGFyc2VOb2RlcyhkbS5nZXRSb290Tm9kZSgpLCB0cmFuc3BvcnQpO1xuICAgICAgICAgICAgZG0uZ2V0Um9vdE5vZGUoKS5zZXRMb2FkZWQodHJ1ZSk7XG4gICAgICAgICAgICB0aGlzLmRpc3BsYXlSZXN1bHRzU3RhdGUoKTtcbiAgICAgICAgICAgIHRoaXMucHJvcHMuZGlzcGxheVJlc3VsdHModmFsdWUsIGRtKTtcbiAgICAgICAgfSkuYmluZCh0aGlzKSk7XG4gICAgfSxcblxuICAgIGtleURvd246IGZ1bmN0aW9uIGtleURvd24oZXZlbnQpIHtcbiAgICAgICAgaWYgKGV2ZW50LmtleSA9PSAnRW50ZXInKSB7XG4gICAgICAgICAgICB0aGlzLm9uQ2xpY2tTZWFyY2goKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICByZW5kZXI6IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgIHsgY2xhc3NOYW1lOiB0aGlzLnByb3BzLmNsYXNzTmFtZSA/IHRoaXMucHJvcHMuY2xhc3NOYW1lIDogJycgfSxcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgeyBzdHlsZTogeyBwYWRkaW5nVG9wOiAyMiwgZmxvYXQ6ICdyaWdodCcsIG9wYWNpdHk6IDAuMyB9IH0sXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChSZWFjdE1VSS5JY29uQnV0dG9uLCB7XG4gICAgICAgICAgICAgICAgICAgIHJlZjogJ2J1dHRvbicsXG4gICAgICAgICAgICAgICAgICAgIG9uQ2xpY2s6IHRoaXMub25DbGlja1NlYXJjaCxcbiAgICAgICAgICAgICAgICAgICAgaWNvbkNsYXNzTmFtZTogJ2ljb24tc2VhcmNoJyxcbiAgICAgICAgICAgICAgICAgICAgdG9vbHRpcDogJ1NlYXJjaCdcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgJ2RpdicsXG4gICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6ICdzZWFyY2hib3gtaW5wdXQtZmlsbCcsIHN0eWxlOiB7IHdpZHRoOiAyMjAsIGZsb2F0OiAncmlnaHQnIH0gfSxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFJlYWN0TVVJLlRleHRGaWVsZCwgeyByZWY6ICdxdWVyeScsIG9uS2V5RG93bjogdGhpcy5rZXlEb3duLCBmbG9hdGluZ0xhYmVsVGV4dDogdGhpcy5wcm9wcy50ZXh0TGFiZWwgfSlcbiAgICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICB9XG5cbn0pO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMDctMjAxNyBDaGFybGVzIGR1IEpldSAtIEFic3RyaXVtIFNBUyA8dGVhbSAoYXQpIHB5ZC5pbz5cbiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIFB5ZGlvLlxuICpcbiAqIFB5ZGlvIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3JcbiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogUHlkaW8gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggUHlkaW8uICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gKlxuICogVGhlIGxhdGVzdCBjb2RlIGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9weWRpby5jb20+LlxuICovXG5cbi8qKlxuICogR2V0IGluZm8gZnJvbSBQeWRpbyBjb250cm9sbGVyIGFuIGJ1aWxkIGFuXG4gKiBhY3Rpb24gYmFyIHdpdGggYWN0aXZlIGFjdGlvbnMuXG4gKiBUQkNcbiAqL1xuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuZXhwb3J0c1snZGVmYXVsdCddID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuICAgIGRpc3BsYXlOYW1lOiAnU2ltcGxlUmVhY3RBY3Rpb25CYXInLFxuXG4gICAgcHJvcFR5cGVzOiB7XG4gICAgICAgIGRhdGFNb2RlbDogUmVhY3QuUHJvcFR5cGVzLmluc3RhbmNlT2YoUHlkaW9EYXRhTW9kZWwpLmlzUmVxdWlyZWQsXG4gICAgICAgIG5vZGU6IFJlYWN0LlByb3BUeXBlcy5pbnN0YW5jZU9mKEFqeHBOb2RlKS5pc1JlcXVpcmVkLFxuICAgICAgICBhY3Rpb25zOiBSZWFjdC5Qcm9wVHlwZXMuYXJyYXlcbiAgICB9LFxuXG4gICAgY2xpY2tBY3Rpb246IGZ1bmN0aW9uIGNsaWNrQWN0aW9uKGV2ZW50KSB7XG4gICAgICAgIHZhciBhY3Rpb25OYW1lID0gZXZlbnQuY3VycmVudFRhcmdldC5nZXRBdHRyaWJ1dGUoXCJkYXRhLWFjdGlvblwiKTtcbiAgICAgICAgdGhpcy5wcm9wcy5kYXRhTW9kZWwuc2V0U2VsZWN0ZWROb2RlcyhbdGhpcy5wcm9wcy5ub2RlXSk7XG4gICAgICAgIHZhciBhID0gd2luZG93LnB5ZGlvLkNvbnRyb2xsZXIuZ2V0QWN0aW9uQnlOYW1lKGFjdGlvbk5hbWUpO1xuICAgICAgICBhLmZpcmVDb250ZXh0Q2hhbmdlKHRoaXMucHJvcHMuZGF0YU1vZGVsLCB0cnVlLCB3aW5kb3cucHlkaW8udXNlcik7XG4gICAgICAgIC8vYS5maXJlU2VsZWN0aW9uQ2hhbmdlKHRoaXMucHJvcHMuZGF0YU1vZGVsKTtcbiAgICAgICAgYS5hcHBseShbdGhpcy5wcm9wcy5kYXRhTW9kZWxdKTtcbiAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgICB2YXIgYWN0aW9ucyA9IHRoaXMucHJvcHMuYWN0aW9ucy5tYXAoKGZ1bmN0aW9uIChhKSB7XG4gICAgICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudCgnZGl2Jywge1xuICAgICAgICAgICAgICAgIGtleTogYS5vcHRpb25zLm5hbWUsXG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lOiBhLm9wdGlvbnMuaWNvbl9jbGFzcyArICcgbWF0ZXJpYWwtbGlzdC1hY3Rpb24taW5saW5lJyB8fCAnJyxcbiAgICAgICAgICAgICAgICB0aXRsZTogYS5vcHRpb25zLnRpdGxlLFxuICAgICAgICAgICAgICAgICdkYXRhLWFjdGlvbic6IGEub3B0aW9ucy5uYW1lLFxuICAgICAgICAgICAgICAgIG9uQ2xpY2s6IHRoaXMuY2xpY2tBY3Rpb24gfSk7XG4gICAgICAgIH0pLmJpbmQodGhpcykpO1xuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICdzcGFuJyxcbiAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICBhY3Rpb25zXG4gICAgICAgICk7XG4gICAgfVxufSk7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTtcbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDE3IENoYXJsZXMgZHUgSmV1IC0gQWJzdHJpdW0gU0FTIDx0ZWFtIChhdCkgcHlkLmlvPlxuICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgUHlkaW8uXG4gKlxuICogUHlkaW8gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBQeWRpbyBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCBQeWRpby4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAqXG4gKiBUaGUgbGF0ZXN0IGNvZGUgY2FuIGJlIGZvdW5kIGF0IDxodHRwczovL3B5ZGlvLmNvbT4uXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG52YXIgX2V4dGVuZHMgPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uICh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTsgZm9yICh2YXIga2V5IGluIHNvdXJjZSkgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkgeyB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldOyB9IH0gfSByZXR1cm4gdGFyZ2V0OyB9O1xuXG52YXIgX3V0aWxETkQgPSByZXF1aXJlKCcuLi91dGlsL0RORCcpO1xuXG52YXIgUmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpO1xuXG52YXIgX1B5ZGlvJHJlcXVpcmVMaWIgPSBQeWRpby5yZXF1aXJlTGliKCdob2MnKTtcblxudmFyIHdpdGhDb250ZXh0TWVudSA9IF9QeWRpbyRyZXF1aXJlTGliLndpdGhDb250ZXh0TWVudTtcblxudmFyIENvbnRleHRNZW51V3JhcHBlciA9IGZ1bmN0aW9uIENvbnRleHRNZW51V3JhcHBlcihwcm9wcykge1xuICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KCdkaXYnLCBwcm9wcyk7XG59O1xuQ29udGV4dE1lbnVXcmFwcGVyID0gd2l0aENvbnRleHRNZW51KENvbnRleHRNZW51V3JhcHBlcik7XG5cbi8qKlxuICogVHJlZSBOb2RlXG4gKi9cbnZhciBTaW1wbGVUcmVlTm9kZSA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcbiAgICBkaXNwbGF5TmFtZTogJ1NpbXBsZVRyZWVOb2RlJyxcblxuICAgIHByb3BUeXBlczoge1xuICAgICAgICBjb2xsYXBzZTogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXG4gICAgICAgIGZvcmNlRXhwYW5kOiBSZWFjdC5Qcm9wVHlwZXMuYm9vbCxcbiAgICAgICAgY2hpbGRyZW5Pbmx5OiBSZWFjdC5Qcm9wVHlwZXMuYm9vbCxcbiAgICAgICAgZGVwdGg6IFJlYWN0LlByb3BUeXBlcy5udW1iZXIsXG4gICAgICAgIG9uTm9kZVNlbGVjdDogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsXG4gICAgICAgIG5vZGU6IFJlYWN0LlByb3BUeXBlcy5pbnN0YW5jZU9mKEFqeHBOb2RlKSxcbiAgICAgICAgZGF0YU1vZGVsOiBSZWFjdC5Qcm9wVHlwZXMuaW5zdGFuY2VPZihQeWRpb0RhdGFNb2RlbCksXG4gICAgICAgIGZvcmNlTGFiZWw6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcsXG4gICAgICAgIC8vIE9wdGlvbmFsIGN1cnJlbnRseSBzZWxlY3RlZCBkZXRlY3Rpb25cbiAgICAgICAgbm9kZUlzU2VsZWN0ZWQ6IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgICAgICAvLyBPcHRpb25hbCBjaGVja2JveGVzXG4gICAgICAgIGNoZWNrYm94ZXM6IFJlYWN0LlByb3BUeXBlcy5hcnJheSxcbiAgICAgICAgY2hlY2tib3hlc1ZhbHVlczogUmVhY3QuUHJvcFR5cGVzLm9iamVjdCxcbiAgICAgICAgY2hlY2tib3hlc0NvbXB1dGVTdGF0dXM6IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgICAgICBvbkNoZWNrYm94Q2hlY2s6IFJlYWN0LlByb3BUeXBlcy5mdW5jXG4gICAgfSxcblxuICAgIGdldERlZmF1bHRQcm9wczogZnVuY3Rpb24gZ2V0RGVmYXVsdFByb3BzKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY29sbGFwc2U6IGZhbHNlLFxuICAgICAgICAgICAgY2hpbGRyZW5Pbmx5OiBmYWxzZSxcbiAgICAgICAgICAgIGRlcHRoOiAwLFxuICAgICAgICAgICAgb25Ob2RlU2VsZWN0OiBmdW5jdGlvbiBvbk5vZGVTZWxlY3Qobm9kZSkge31cbiAgICAgICAgfTtcbiAgICB9LFxuXG4gICAgbGlzdGVuVG9Ob2RlOiBmdW5jdGlvbiBsaXN0ZW5Ub05vZGUobm9kZSkge1xuICAgICAgICB0aGlzLl9jaGlsZHJlbkxpc3RlbmVyID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5pc01vdW50ZWQoKSkgcmV0dXJuO1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGNoaWxkcmVuOiB0aGlzLl9ub2RlVG9DaGlsZHJlbihub2RlKSB9KTtcbiAgICAgICAgfSkuYmluZCh0aGlzKTtcbiAgICAgICAgdGhpcy5fbm9kZUxpc3RlbmVyID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5pc01vdW50ZWQoKSkgcmV0dXJuO1xuICAgICAgICAgICAgdGhpcy5mb3JjZVVwZGF0ZSgpO1xuICAgICAgICB9KS5iaW5kKHRoaXMpO1xuICAgICAgICBub2RlLm9ic2VydmUoXCJjaGlsZF9hZGRlZFwiLCB0aGlzLl9jaGlsZHJlbkxpc3RlbmVyKTtcbiAgICAgICAgbm9kZS5vYnNlcnZlKFwiY2hpbGRfcmVtb3ZlZFwiLCB0aGlzLl9jaGlsZHJlbkxpc3RlbmVyKTtcbiAgICAgICAgbm9kZS5vYnNlcnZlKFwibm9kZV9yZXBsYWNlZFwiLCB0aGlzLl9ub2RlTGlzdGVuZXIpO1xuICAgIH0sXG5cbiAgICBzdG9wTGlzdGVuaW5nOiBmdW5jdGlvbiBzdG9wTGlzdGVuaW5nKG5vZGUpIHtcbiAgICAgICAgbm9kZS5zdG9wT2JzZXJ2aW5nKFwiY2hpbGRfYWRkZWRcIiwgdGhpcy5fY2hpbGRyZW5MaXN0ZW5lcik7XG4gICAgICAgIG5vZGUuc3RvcE9ic2VydmluZyhcImNoaWxkX3JlbW92ZWRcIiwgdGhpcy5fY2hpbGRyZW5MaXN0ZW5lcik7XG4gICAgICAgIG5vZGUuc3RvcE9ic2VydmluZyhcIm5vZGVfcmVwbGFjZWRcIiwgdGhpcy5fbm9kZUxpc3RlbmVyKTtcbiAgICB9LFxuXG4gICAgY29tcG9uZW50RGlkTW91bnQ6IGZ1bmN0aW9uIGNvbXBvbmVudERpZE1vdW50KCkge1xuICAgICAgICB0aGlzLmxpc3RlblRvTm9kZSh0aGlzLnByb3BzLm5vZGUpO1xuICAgIH0sXG5cbiAgICBjb21wb25lbnRXaWxsVW5tb3VudDogZnVuY3Rpb24gY29tcG9uZW50V2lsbFVubW91bnQoKSB7XG4gICAgICAgIHRoaXMuc3RvcExpc3RlbmluZyh0aGlzLnByb3BzLm5vZGUpO1xuICAgIH0sXG5cbiAgICBjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzOiBmdW5jdGlvbiBjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzKG5leHRQcm9wcykge1xuICAgICAgICB2YXIgb2xkTm9kZSA9IHRoaXMucHJvcHMubm9kZTtcbiAgICAgICAgdmFyIG5ld05vZGUgPSBuZXh0UHJvcHMubm9kZTtcbiAgICAgICAgaWYgKG5ld05vZGUgPT0gb2xkTm9kZSAmJiBuZXdOb2RlLmdldE1ldGFkYXRhKCkuZ2V0KFwicGFnaW5hdGlvbkRhdGFcIikpIHtcbiAgICAgICAgICAgIHZhciByZW1hcGVkQ2hpbGRyZW4gPSB0aGlzLnN0YXRlLmNoaWxkcmVuLm1hcChmdW5jdGlvbiAoYykge1xuICAgICAgICAgICAgICAgIGMuc2V0UGFyZW50KG5ld05vZGUpO3JldHVybiBjO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB2YXIgcmVtYXBlZFBhdGhlcyA9IHRoaXMuc3RhdGUuY2hpbGRyZW4ubWFwKGZ1bmN0aW9uIChjKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGMuZ2V0UGF0aCgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB2YXIgbmV3Q2hpbGRyZW4gPSB0aGlzLl9ub2RlVG9DaGlsZHJlbihuZXdOb2RlKTtcbiAgICAgICAgICAgIG5ld0NoaWxkcmVuLmZvckVhY2goZnVuY3Rpb24gKG5jKSB7XG4gICAgICAgICAgICAgICAgaWYgKHJlbWFwZWRQYXRoZXMuaW5kZXhPZihuYy5nZXRQYXRoKCkpID09PSAtMSkge1xuICAgICAgICAgICAgICAgICAgICByZW1hcGVkQ2hpbGRyZW4ucHVzaChuYyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgY2hpbGRyZW46IHJlbWFwZWRDaGlsZHJlbiB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBjaGlsZHJlbjogdGhpcy5fbm9kZVRvQ2hpbGRyZW4obmV3Tm9kZSkgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG5ld05vZGUgIT09IG9sZE5vZGUpIHtcbiAgICAgICAgICAgIHRoaXMuc3RvcExpc3RlbmluZyhvbGROb2RlKTtcbiAgICAgICAgICAgIHRoaXMubGlzdGVuVG9Ob2RlKG5ld05vZGUpO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIGdldEluaXRpYWxTdGF0ZTogZnVuY3Rpb24gZ2V0SW5pdGlhbFN0YXRlKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc2hvd0NoaWxkcmVuOiAhdGhpcy5wcm9wcy5jb2xsYXBzZSB8fCB0aGlzLnByb3BzLmZvcmNlRXhwYW5kLFxuICAgICAgICAgICAgY2hpbGRyZW46IHRoaXMuX25vZGVUb0NoaWxkcmVuKHRoaXMucHJvcHMubm9kZSlcbiAgICAgICAgfTtcbiAgICB9LFxuXG4gICAgX25vZGVUb0NoaWxkcmVuOiBmdW5jdGlvbiBfbm9kZVRvQ2hpbGRyZW4oKSB7XG4gICAgICAgIHZhciBjaGlsZHJlbiA9IFtdO1xuICAgICAgICB0aGlzLnByb3BzLm5vZGUuZ2V0Q2hpbGRyZW4oKS5mb3JFYWNoKGZ1bmN0aW9uIChjKSB7XG4gICAgICAgICAgICBpZiAoIWMuaXNMZWFmKCkgfHwgYy5nZXRBanhwTWltZSgpID09PSAnYWp4cF9icm93c2FibGVfYXJjaGl2ZScpIGNoaWxkcmVuLnB1c2goYyk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gY2hpbGRyZW47XG4gICAgfSxcblxuICAgIG9uTm9kZVNlbGVjdDogZnVuY3Rpb24gb25Ob2RlU2VsZWN0KGV2KSB7XG4gICAgICAgIGlmICh0aGlzLnByb3BzLm9uTm9kZVNlbGVjdCkge1xuICAgICAgICAgICAgdGhpcy5wcm9wcy5vbk5vZGVTZWxlY3QodGhpcy5wcm9wcy5ub2RlKTtcbiAgICAgICAgfVxuICAgICAgICBldi5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBldi5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB9LFxuICAgIG9uQ2hpbGREaXNwbGF5VG9nZ2xlOiBmdW5jdGlvbiBvbkNoaWxkRGlzcGxheVRvZ2dsZShldikge1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5ub2RlLmdldENoaWxkcmVuKCkuc2l6ZSkge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNob3dDaGlsZHJlbjogIXRoaXMuc3RhdGUuc2hvd0NoaWxkcmVuIH0pO1xuICAgICAgICB9XG4gICAgICAgIGV2LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGV2LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH0sXG4gICAgbm9kZUlzU2VsZWN0ZWQ6IGZ1bmN0aW9uIG5vZGVJc1NlbGVjdGVkKG4pIHtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMubm9kZUlzU2VsZWN0ZWQpIHJldHVybiB0aGlzLnByb3BzLm5vZGVJc1NlbGVjdGVkKG4pO2Vsc2UgcmV0dXJuIHRoaXMucHJvcHMuZGF0YU1vZGVsLmdldFNlbGVjdGVkTm9kZXMoKS5pbmRleE9mKG4pICE9PSAtMTtcbiAgICB9LFxuICAgIHJlbmRlcjogZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgICAgIHZhciBfcHJvcHMgPSB0aGlzLnByb3BzO1xuICAgICAgICB2YXIgbm9kZSA9IF9wcm9wcy5ub2RlO1xuICAgICAgICB2YXIgY2hpbGRyZW5Pbmx5ID0gX3Byb3BzLmNoaWxkcmVuT25seTtcbiAgICAgICAgdmFyIGNhbkRyb3AgPSBfcHJvcHMuY2FuRHJvcDtcbiAgICAgICAgdmFyIGlzT3ZlckN1cnJlbnQgPSBfcHJvcHMuaXNPdmVyQ3VycmVudDtcbiAgICAgICAgdmFyIGNoZWNrYm94ZXMgPSBfcHJvcHMuY2hlY2tib3hlcztcbiAgICAgICAgdmFyIGNoZWNrYm94ZXNDb21wdXRlU3RhdHVzID0gX3Byb3BzLmNoZWNrYm94ZXNDb21wdXRlU3RhdHVzO1xuICAgICAgICB2YXIgY2hlY2tib3hlc1ZhbHVlcyA9IF9wcm9wcy5jaGVja2JveGVzVmFsdWVzO1xuICAgICAgICB2YXIgb25DaGVja2JveENoZWNrID0gX3Byb3BzLm9uQ2hlY2tib3hDaGVjaztcbiAgICAgICAgdmFyIGRlcHRoID0gX3Byb3BzLmRlcHRoO1xuICAgICAgICB2YXIgZm9yY2VFeHBhbmQgPSBfcHJvcHMuZm9yY2VFeHBhbmQ7XG4gICAgICAgIHZhciBzZWxlY3RlZEl0ZW1TdHlsZSA9IF9wcm9wcy5zZWxlY3RlZEl0ZW1TdHlsZTtcbiAgICAgICAgdmFyIGdldEl0ZW1TdHlsZSA9IF9wcm9wcy5nZXRJdGVtU3R5bGU7XG4gICAgICAgIHZhciBmb3JjZUxhYmVsID0gX3Byb3BzLmZvcmNlTGFiZWw7XG5cbiAgICAgICAgdmFyIGhhc0ZvbGRlckNoaWxkcmVucyA9IHRoaXMuc3RhdGUuY2hpbGRyZW4ubGVuZ3RoID8gdHJ1ZSA6IGZhbHNlO1xuICAgICAgICB2YXIgaGFzQ2hpbGRyZW47XG4gICAgICAgIGlmIChoYXNGb2xkZXJDaGlsZHJlbnMpIHtcbiAgICAgICAgICAgIGhhc0NoaWxkcmVuID0gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICAnc3BhbicsXG4gICAgICAgICAgICAgICAgeyBvbkNsaWNrOiB0aGlzLm9uQ2hpbGREaXNwbGF5VG9nZ2xlIH0sXG4gICAgICAgICAgICAgICAgdGhpcy5zdGF0ZS5zaG93Q2hpbGRyZW4gfHwgZm9yY2VFeHBhbmQgPyBSZWFjdC5jcmVhdGVFbGVtZW50KCdzcGFuJywgeyBjbGFzc05hbWU6ICd0cmVlLWljb24gaWNvbi1hbmdsZS1kb3duJyB9KSA6IFJlYWN0LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nLCB7IGNsYXNzTmFtZTogJ3RyZWUtaWNvbiBpY29uLWFuZ2xlLXJpZ2h0JyB9KVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHZhciBjbmFtZSA9IFwidHJlZS1pY29uIGljb24tYW5nbGUtcmlnaHRcIjtcbiAgICAgICAgICAgIGlmIChub2RlLmlzTG9hZGVkKCkpIHtcbiAgICAgICAgICAgICAgICBjbmFtZSArPSBcIiBuby1mb2xkZXItY2hpbGRyZW5cIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGhhc0NoaWxkcmVuID0gUmVhY3QuY3JlYXRlRWxlbWVudCgnc3BhbicsIHsgY2xhc3NOYW1lOiBjbmFtZSB9KTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgaXNTZWxlY3RlZCA9IHRoaXMubm9kZUlzU2VsZWN0ZWQobm9kZSkgPyAnbXVpLW1lbnUtaXRlbSBtdWktaXMtc2VsZWN0ZWQnIDogJ211aS1tZW51LWl0ZW0nO1xuICAgICAgICB2YXIgc2VsZkxhYmVsO1xuICAgICAgICBpZiAoIWNoaWxkcmVuT25seSkge1xuICAgICAgICAgICAgaWYgKGNhbkRyb3AgJiYgaXNPdmVyQ3VycmVudCkge1xuICAgICAgICAgICAgICAgIGlzU2VsZWN0ZWQgKz0gJyBkcm9wcGFibGUtYWN0aXZlJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBib3hlcztcbiAgICAgICAgICAgIGlmIChjaGVja2JveGVzKSB7XG4gICAgICAgICAgICAgICAgdmFyIHZhbHVlcyA9IHt9LFxuICAgICAgICAgICAgICAgICAgICBpbmhlcml0ZWQgPSBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgZGlzYWJsZWQgPSB7fSxcbiAgICAgICAgICAgICAgICAgICAgYWRkaXRpb25hbENsYXNzTmFtZSA9ICcnO1xuICAgICAgICAgICAgICAgIGlmIChjaGVja2JveGVzQ29tcHV0ZVN0YXR1cykge1xuICAgICAgICAgICAgICAgICAgICB2YXIgc3RhdHVzID0gY2hlY2tib3hlc0NvbXB1dGVTdGF0dXMobm9kZSk7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlcyA9IHN0YXR1cy5WQUxVRVM7XG4gICAgICAgICAgICAgICAgICAgIGluaGVyaXRlZCA9IHN0YXR1cy5JTkhFUklURUQ7XG4gICAgICAgICAgICAgICAgICAgIGRpc2FibGVkID0gc3RhdHVzLkRJU0FCTEVEO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdHVzLkNMQVNTTkFNRSkgYWRkaXRpb25hbENsYXNzTmFtZSA9ICcgJyArIHN0YXR1cy5DTEFTU05BTUU7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjaGVja2JveGVzVmFsdWVzICYmIGNoZWNrYm94ZXNWYWx1ZXNbbm9kZS5nZXRQYXRoKCldKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhbHVlcyA9IGNoZWNrYm94ZXNWYWx1ZXNbbm9kZS5nZXRQYXRoKCldO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB2YXIgdmFsdWVDbGFzc2VzID0gW107XG4gICAgICAgICAgICAgICAgYm94ZXMgPSBjaGVja2JveGVzLm1hcCgoZnVuY3Rpb24gKGMpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHNlbGVjdGVkID0gdmFsdWVzW2NdICE9PSB1bmRlZmluZWQgPyB2YWx1ZXNbY10gOiBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNsaWNrID0gKGZ1bmN0aW9uIChldmVudCwgdmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9uQ2hlY2tib3hDaGVjayhub2RlLCBjLCB2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH0pLmJpbmQodGhpcyk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzZWxlY3RlZCkgdmFsdWVDbGFzc2VzLnB1c2goYyk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFJlYWN0TVVJLkNoZWNrYm94LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiBjLFxuICAgICAgICAgICAgICAgICAgICAgICAga2V5OiBjICsgXCItXCIgKyAoc2VsZWN0ZWQgPyBcInRydWVcIiA6IFwiZmFsc2VcIiksXG4gICAgICAgICAgICAgICAgICAgICAgICBjaGVja2VkOiBzZWxlY3RlZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIG9uQ2hlY2s6IGNsaWNrLFxuICAgICAgICAgICAgICAgICAgICAgICAgZGlzYWJsZWQ6IGRpc2FibGVkW2NdLFxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lOiBcImNib3gtXCIgKyBjXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH0pLmJpbmQodGhpcykpO1xuICAgICAgICAgICAgICAgIGlzU2VsZWN0ZWQgKz0gaW5oZXJpdGVkID8gXCIgaW5oZXJpdGVkIFwiIDogXCJcIjtcbiAgICAgICAgICAgICAgICBpc1NlbGVjdGVkICs9IHZhbHVlQ2xhc3Nlcy5sZW5ndGggPyBcIiBjaGVja2JveC12YWx1ZXMtXCIgKyB2YWx1ZUNsYXNzZXMuam9pbignLScpIDogXCIgY2hlY2tib3gtdmFsdWVzLWVtcHR5XCI7XG4gICAgICAgICAgICAgICAgYm94ZXMgPSBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICAgICAnZGl2JyxcbiAgICAgICAgICAgICAgICAgICAgeyBjbGFzc05hbWU6IFwidHJlZS1jaGVja2JveGVzXCIgKyBhZGRpdGlvbmFsQ2xhc3NOYW1lIH0sXG4gICAgICAgICAgICAgICAgICAgIGJveGVzXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBpdGVtU3R5bGUgPSB7IHBhZGRpbmdMZWZ0OiBkZXB0aCAqIDIwIH07XG4gICAgICAgICAgICBpZiAodGhpcy5ub2RlSXNTZWxlY3RlZChub2RlKSAmJiBzZWxlY3RlZEl0ZW1TdHlsZSkge1xuICAgICAgICAgICAgICAgIGl0ZW1TdHlsZSA9IF9leHRlbmRzKHt9LCBpdGVtU3R5bGUsIHNlbGVjdGVkSXRlbVN0eWxlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChnZXRJdGVtU3R5bGUpIHtcbiAgICAgICAgICAgICAgICBpdGVtU3R5bGUgPSBfZXh0ZW5kcyh7fSwgaXRlbVN0eWxlLCBnZXRJdGVtU3R5bGUobm9kZSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIGljb24gPSAnbWRpIG1kaS1mb2xkZXInO1xuICAgICAgICAgICAgdmFyIGFqeHBNaW1lID0gbm9kZS5nZXRBanhwTWltZSgpO1xuICAgICAgICAgICAgaWYgKGFqeHBNaW1lID09PSAnYWp4cF9icm93c2FibGVfYXJjaGl2ZScpIHtcbiAgICAgICAgICAgICAgICBpY29uID0gJ21kaSBtZGktYXJjaGl2ZSc7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGFqeHBNaW1lID09PSAnYWp4cF9yZWN5Y2xlJykge1xuICAgICAgICAgICAgICAgIGljb24gPSAnbWRpIG1kaS1kZWxldGUnO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc2VsZkxhYmVsID0gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICAgICBDb250ZXh0TWVudVdyYXBwZXIsXG4gICAgICAgICAgICAgICAgeyBub2RlOiBub2RlLCBjbGFzc05hbWU6ICd0cmVlLWl0ZW0gJyArIGlzU2VsZWN0ZWQgKyAoYm94ZXMgPyAnIGhhcy1jaGVja2JveGVzJyA6ICcnKSwgc3R5bGU6IGl0ZW1TdHlsZSB9LFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAgICAgICAgICdkaXYnLFxuICAgICAgICAgICAgICAgICAgICB7IGNsYXNzTmFtZTogJ3RyZWUtaXRlbS1sYWJlbCcsIG9uQ2xpY2s6IHRoaXMub25Ob2RlU2VsZWN0LCB0aXRsZTogbm9kZS5nZXRMYWJlbCgpLFxuICAgICAgICAgICAgICAgICAgICAgICAgJ2RhdGEtaWQnOiBub2RlLmdldFBhdGgoKSB9LFxuICAgICAgICAgICAgICAgICAgICBoYXNDaGlsZHJlbixcbiAgICAgICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudCgnc3BhbicsIHsgY2xhc3NOYW1lOiBcInRyZWUtaWNvbiBcIiArIGljb24gfSksXG4gICAgICAgICAgICAgICAgICAgIGZvcmNlTGFiZWwgPyBmb3JjZUxhYmVsIDogbm9kZS5nZXRMYWJlbCgpXG4gICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICBib3hlc1xuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBjaGlsZHJlbiA9IFtdO1xuICAgICAgICB2YXIgY29ubmVjdG9yID0gZnVuY3Rpb24gY29ubmVjdG9yKGluc3RhbmNlKSB7XG4gICAgICAgICAgICByZXR1cm4gaW5zdGFuY2U7XG4gICAgICAgIH07XG4gICAgICAgIHZhciBkcmFnZ2FibGUgPSBmYWxzZTtcbiAgICAgICAgaWYgKHdpbmRvdy5SZWFjdERORCAmJiB0aGlzLnByb3BzLmNvbm5lY3REcm9wVGFyZ2V0ICYmIHRoaXMucHJvcHMuY29ubmVjdERyYWdTb3VyY2UpIHtcbiAgICAgICAgICAgIChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdmFyIGNvbm5lY3REcmFnU291cmNlID0gX3RoaXMucHJvcHMuY29ubmVjdERyYWdTb3VyY2U7XG4gICAgICAgICAgICAgICAgdmFyIGNvbm5lY3REcm9wVGFyZ2V0ID0gX3RoaXMucHJvcHMuY29ubmVjdERyb3BUYXJnZXQ7XG4gICAgICAgICAgICAgICAgY29ubmVjdG9yID0gZnVuY3Rpb24gKGluc3RhbmNlKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbm5lY3REcmFnU291cmNlKFJlYWN0RE9NLmZpbmRET01Ob2RlKGluc3RhbmNlKSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbm5lY3REcm9wVGFyZ2V0KFJlYWN0RE9NLmZpbmRET01Ob2RlKGluc3RhbmNlKSk7XG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBkcmFnZ2FibGUgPSB0cnVlO1xuICAgICAgICAgICAgfSkoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLnN0YXRlLnNob3dDaGlsZHJlbiB8fCBmb3JjZUV4cGFuZCkge1xuICAgICAgICAgICAgY2hpbGRyZW4gPSB0aGlzLnN0YXRlLmNoaWxkcmVuLm1hcCgoZnVuY3Rpb24gKGNoaWxkKSB7XG4gICAgICAgICAgICAgICAgdmFyIHByb3BzID0gX2V4dGVuZHMoe30sIHRoaXMucHJvcHMsIHtcbiAgICAgICAgICAgICAgICAgICAgZm9yY2VMYWJlbDogbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW5Pbmx5OiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAga2V5OiBjaGlsZC5nZXRQYXRoKCksXG4gICAgICAgICAgICAgICAgICAgIG5vZGU6IGNoaWxkLFxuICAgICAgICAgICAgICAgICAgICBkZXB0aDogZGVwdGggKyAxXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoZHJhZ2dhYmxlID8gRHJhZ0Ryb3BUcmVlTm9kZSA6IFNpbXBsZVRyZWVOb2RlLCBwcm9wcyk7XG4gICAgICAgICAgICB9KS5iaW5kKHRoaXMpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICdsaScsXG4gICAgICAgICAgICB7IHJlZjogY29ubmVjdG9yLCBjbGFzc05hbWU6IFwidHJlZW5vZGVcIiArIG5vZGUuZ2V0UGF0aCgpLnJlcGxhY2UoL1xcLy9nLCAnXycpIH0sXG4gICAgICAgICAgICBzZWxmTGFiZWwsXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFxuICAgICAgICAgICAgICAgICd1bCcsXG4gICAgICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgICAgICBjaGlsZHJlblxuICAgICAgICAgICAgKVxuICAgICAgICApO1xuICAgIH1cbn0pO1xuXG52YXIgRHJhZ0Ryb3BUcmVlTm9kZTtcbmlmICh3aW5kb3cuUmVhY3RETkQpIHtcbiAgICBEcmFnRHJvcFRyZWVOb2RlID0gUmVhY3RETkQuZmxvdyhSZWFjdERORC5EcmFnU291cmNlKF91dGlsRE5ELlR5cGVzLk5PREVfUFJPVklERVIsIF91dGlsRE5ELm5vZGVEcmFnU291cmNlLCBfdXRpbERORC5jb2xsZWN0KSwgUmVhY3RETkQuRHJvcFRhcmdldChfdXRpbERORC5UeXBlcy5OT0RFX1BST1ZJREVSLCBfdXRpbERORC5ub2RlRHJvcFRhcmdldCwgX3V0aWxETkQuY29sbGVjdERyb3ApKShTaW1wbGVUcmVlTm9kZSk7XG59IGVsc2Uge1xuICAgIERyYWdEcm9wVHJlZU5vZGUgPSBTaW1wbGVUcmVlTm9kZTtcbn1cblxuLyoqXG4gKiBTaW1wbGUgb3BlbmFibGUgLyBsb2FkYWJsZSB0cmVlIHRha2luZyBBanhwTm9kZSBhcyBpbnB1dHNcbiAqL1xudmFyIERORFRyZWVWaWV3ID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuICAgIGRpc3BsYXlOYW1lOiAnRE5EVHJlZVZpZXcnLFxuXG4gICAgcHJvcFR5cGVzOiB7XG4gICAgICAgIHNob3dSb290OiBSZWFjdC5Qcm9wVHlwZXMuYm9vbCxcbiAgICAgICAgcm9vdExhYmVsOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLFxuICAgICAgICBvbk5vZGVTZWxlY3Q6IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgICAgICBub2RlOiBSZWFjdC5Qcm9wVHlwZXMuaW5zdGFuY2VPZihBanhwTm9kZSkuaXNSZXF1aXJlZCxcbiAgICAgICAgZGF0YU1vZGVsOiBSZWFjdC5Qcm9wVHlwZXMuaW5zdGFuY2VPZihQeWRpb0RhdGFNb2RlbCkuaXNSZXF1aXJlZCxcbiAgICAgICAgc2VsZWN0YWJsZTogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXG4gICAgICAgIHNlbGVjdGFibGVNdWx0aXBsZTogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXG4gICAgICAgIGluaXRpYWxTZWxlY3Rpb25Nb2RlbDogUmVhY3QuUHJvcFR5cGVzLmFycmF5LFxuICAgICAgICBvblNlbGVjdGlvbkNoYW5nZTogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsXG4gICAgICAgIGZvcmNlRXhwYW5kOiBSZWFjdC5Qcm9wVHlwZXMuYm9vbCxcbiAgICAgICAgLy8gT3B0aW9uYWwgY3VycmVudGx5IHNlbGVjdGVkIGRldGVjdGlvblxuICAgICAgICBub2RlSXNTZWxlY3RlZDogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsXG4gICAgICAgIC8vIE9wdGlvbmFsIGNoZWNrYm94ZXNcbiAgICAgICAgY2hlY2tib3hlczogUmVhY3QuUHJvcFR5cGVzLmFycmF5LFxuICAgICAgICBjaGVja2JveGVzVmFsdWVzOiBSZWFjdC5Qcm9wVHlwZXMub2JqZWN0LFxuICAgICAgICBjaGVja2JveGVzQ29tcHV0ZVN0YXR1czogUmVhY3QuUHJvcFR5cGVzLmZ1bmMsXG4gICAgICAgIG9uQ2hlY2tib3hDaGVjazogUmVhY3QuUHJvcFR5cGVzLmZ1bmNcbiAgICB9LFxuXG4gICAgZ2V0RGVmYXVsdFByb3BzOiBmdW5jdGlvbiBnZXREZWZhdWx0UHJvcHMoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzaG93Um9vdDogdHJ1ZSxcbiAgICAgICAgICAgIG9uTm9kZVNlbGVjdDogdGhpcy5vbk5vZGVTZWxlY3RcbiAgICAgICAgfTtcbiAgICB9LFxuXG4gICAgb25Ob2RlU2VsZWN0OiBmdW5jdGlvbiBvbk5vZGVTZWxlY3Qobm9kZSkge1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5vbk5vZGVTZWxlY3QpIHtcbiAgICAgICAgICAgIHRoaXMucHJvcHMub25Ob2RlU2VsZWN0KG5vZGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5wcm9wcy5kYXRhTW9kZWwuc2V0U2VsZWN0ZWROb2Rlcyhbbm9kZV0pO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcbiAgICAgICAgICAgICd1bCcsXG4gICAgICAgICAgICB7IGNsYXNzTmFtZTogdGhpcy5wcm9wcy5jbGFzc05hbWUgfSxcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoRHJhZ0Ryb3BUcmVlTm9kZSwge1xuICAgICAgICAgICAgICAgIGNoaWxkcmVuT25seTogIXRoaXMucHJvcHMuc2hvd1Jvb3QsXG4gICAgICAgICAgICAgICAgZm9yY2VFeHBhbmQ6IHRoaXMucHJvcHMuZm9yY2VFeHBhbmQsXG4gICAgICAgICAgICAgICAgbm9kZTogdGhpcy5wcm9wcy5ub2RlID8gdGhpcy5wcm9wcy5ub2RlIDogdGhpcy5wcm9wcy5kYXRhTW9kZWwuZ2V0Um9vdE5vZGUoKSxcbiAgICAgICAgICAgICAgICBkYXRhTW9kZWw6IHRoaXMucHJvcHMuZGF0YU1vZGVsLFxuICAgICAgICAgICAgICAgIG9uTm9kZVNlbGVjdDogdGhpcy5vbk5vZGVTZWxlY3QsXG4gICAgICAgICAgICAgICAgbm9kZUlzU2VsZWN0ZWQ6IHRoaXMucHJvcHMubm9kZUlzU2VsZWN0ZWQsXG4gICAgICAgICAgICAgICAgZm9yY2VMYWJlbDogdGhpcy5wcm9wcy5yb290TGFiZWwsXG4gICAgICAgICAgICAgICAgY2hlY2tib3hlczogdGhpcy5wcm9wcy5jaGVja2JveGVzLFxuICAgICAgICAgICAgICAgIGNoZWNrYm94ZXNWYWx1ZXM6IHRoaXMucHJvcHMuY2hlY2tib3hlc1ZhbHVlcyxcbiAgICAgICAgICAgICAgICBjaGVja2JveGVzQ29tcHV0ZVN0YXR1czogdGhpcy5wcm9wcy5jaGVja2JveGVzQ29tcHV0ZVN0YXR1cyxcbiAgICAgICAgICAgICAgICBvbkNoZWNrYm94Q2hlY2s6IHRoaXMucHJvcHMub25DaGVja2JveENoZWNrLFxuICAgICAgICAgICAgICAgIHNlbGVjdGVkSXRlbVN0eWxlOiB0aGlzLnByb3BzLnNlbGVjdGVkSXRlbVN0eWxlLFxuICAgICAgICAgICAgICAgIGdldEl0ZW1TdHlsZTogdGhpcy5wcm9wcy5nZXRJdGVtU3R5bGVcbiAgICAgICAgICAgIH0pXG4gICAgICAgICk7XG4gICAgfVxufSk7XG5cbnZhciBUcmVlVmlldyA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcbiAgICBkaXNwbGF5TmFtZTogJ1RyZWVWaWV3JyxcblxuICAgIHByb3BUeXBlczoge1xuICAgICAgICBzaG93Um9vdDogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXG4gICAgICAgIHJvb3RMYWJlbDogUmVhY3QuUHJvcFR5cGVzLnN0cmluZyxcbiAgICAgICAgb25Ob2RlU2VsZWN0OiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgICAgICAgbm9kZTogUmVhY3QuUHJvcFR5cGVzLmluc3RhbmNlT2YoQWp4cE5vZGUpLmlzUmVxdWlyZWQsXG4gICAgICAgIGRhdGFNb2RlbDogUmVhY3QuUHJvcFR5cGVzLmluc3RhbmNlT2YoUHlkaW9EYXRhTW9kZWwpLmlzUmVxdWlyZWQsXG4gICAgICAgIHNlbGVjdGFibGU6IFJlYWN0LlByb3BUeXBlcy5ib29sLFxuICAgICAgICBzZWxlY3RhYmxlTXVsdGlwbGU6IFJlYWN0LlByb3BUeXBlcy5ib29sLFxuICAgICAgICBpbml0aWFsU2VsZWN0aW9uTW9kZWw6IFJlYWN0LlByb3BUeXBlcy5hcnJheSxcbiAgICAgICAgb25TZWxlY3Rpb25DaGFuZ2U6IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgICAgICBmb3JjZUV4cGFuZDogUmVhY3QuUHJvcFR5cGVzLmJvb2wsXG4gICAgICAgIC8vIE9wdGlvbmFsIGN1cnJlbnRseSBzZWxlY3RlZCBkZXRlY3Rpb25cbiAgICAgICAgbm9kZUlzU2VsZWN0ZWQ6IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgICAgICAvLyBPcHRpb25hbCBjaGVja2JveGVzXG4gICAgICAgIGNoZWNrYm94ZXM6IFJlYWN0LlByb3BUeXBlcy5hcnJheSxcbiAgICAgICAgY2hlY2tib3hlc1ZhbHVlczogUmVhY3QuUHJvcFR5cGVzLm9iamVjdCxcbiAgICAgICAgY2hlY2tib3hlc0NvbXB1dGVTdGF0dXM6IFJlYWN0LlByb3BUeXBlcy5mdW5jLFxuICAgICAgICBvbkNoZWNrYm94Q2hlY2s6IFJlYWN0LlByb3BUeXBlcy5mdW5jXG4gICAgfSxcblxuICAgIGdldERlZmF1bHRQcm9wczogZnVuY3Rpb24gZ2V0RGVmYXVsdFByb3BzKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc2hvd1Jvb3Q6IHRydWUsXG4gICAgICAgICAgICBvbk5vZGVTZWxlY3Q6IHRoaXMub25Ob2RlU2VsZWN0XG4gICAgICAgIH07XG4gICAgfSxcblxuICAgIG9uTm9kZVNlbGVjdDogZnVuY3Rpb24gb25Ob2RlU2VsZWN0KG5vZGUpIHtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMub25Ob2RlU2VsZWN0KSB7XG4gICAgICAgICAgICB0aGlzLnByb3BzLm9uTm9kZVNlbGVjdChub2RlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMucHJvcHMuZGF0YU1vZGVsLnNldFNlbGVjdGVkTm9kZXMoW25vZGVdKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICByZW5kZXI6IGZ1bmN0aW9uIHJlbmRlcigpIHtcbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXG4gICAgICAgICAgICAndWwnLFxuICAgICAgICAgICAgeyBjbGFzc05hbWU6IHRoaXMucHJvcHMuY2xhc3NOYW1lIH0sXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFNpbXBsZVRyZWVOb2RlLCB7XG4gICAgICAgICAgICAgICAgY2hpbGRyZW5Pbmx5OiAhdGhpcy5wcm9wcy5zaG93Um9vdCxcbiAgICAgICAgICAgICAgICBmb3JjZUV4cGFuZDogdGhpcy5wcm9wcy5mb3JjZUV4cGFuZCxcbiAgICAgICAgICAgICAgICBub2RlOiB0aGlzLnByb3BzLm5vZGUgPyB0aGlzLnByb3BzLm5vZGUgOiB0aGlzLnByb3BzLmRhdGFNb2RlbC5nZXRSb290Tm9kZSgpLFxuICAgICAgICAgICAgICAgIGRhdGFNb2RlbDogdGhpcy5wcm9wcy5kYXRhTW9kZWwsXG4gICAgICAgICAgICAgICAgb25Ob2RlU2VsZWN0OiB0aGlzLm9uTm9kZVNlbGVjdCxcbiAgICAgICAgICAgICAgICBub2RlSXNTZWxlY3RlZDogdGhpcy5wcm9wcy5ub2RlSXNTZWxlY3RlZCxcbiAgICAgICAgICAgICAgICBmb3JjZUxhYmVsOiB0aGlzLnByb3BzLnJvb3RMYWJlbCxcbiAgICAgICAgICAgICAgICBjaGVja2JveGVzOiB0aGlzLnByb3BzLmNoZWNrYm94ZXMsXG4gICAgICAgICAgICAgICAgY2hlY2tib3hlc1ZhbHVlczogdGhpcy5wcm9wcy5jaGVja2JveGVzVmFsdWVzLFxuICAgICAgICAgICAgICAgIGNoZWNrYm94ZXNDb21wdXRlU3RhdHVzOiB0aGlzLnByb3BzLmNoZWNrYm94ZXNDb21wdXRlU3RhdHVzLFxuICAgICAgICAgICAgICAgIG9uQ2hlY2tib3hDaGVjazogdGhpcy5wcm9wcy5vbkNoZWNrYm94Q2hlY2ssXG4gICAgICAgICAgICAgICAgc2VsZWN0ZWRJdGVtU3R5bGU6IHRoaXMucHJvcHMuc2VsZWN0ZWRJdGVtU3R5bGUsXG4gICAgICAgICAgICAgICAgZ2V0SXRlbVN0eWxlOiB0aGlzLnByb3BzLmdldEl0ZW1TdHlsZVxuICAgICAgICAgICAgfSlcbiAgICAgICAgKTtcbiAgICB9XG5cbn0pO1xuXG52YXIgRm9sZGVyc1RyZWUgPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG4gICAgZGlzcGxheU5hbWU6ICdGb2xkZXJzVHJlZScsXG5cbiAgICBwcm9wVHlwZXM6IHtcbiAgICAgICAgcHlkaW86IFJlYWN0LlByb3BUeXBlcy5pbnN0YW5jZU9mKFB5ZGlvKS5pc1JlcXVpcmVkLFxuICAgICAgICBkYXRhTW9kZWw6IFJlYWN0LlByb3BUeXBlcy5pbnN0YW5jZU9mKFB5ZGlvRGF0YU1vZGVsKS5pc1JlcXVpcmVkLFxuICAgICAgICBjbGFzc05hbWU6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcsXG4gICAgICAgIG9uTm9kZVNlbGVjdGVkOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYyxcbiAgICAgICAgZHJhZ2dhYmxlOiBSZWFjdC5Qcm9wVHlwZXMuYm9vbFxuICAgIH0sXG5cbiAgICBub2RlT2JzZXJ2ZXI6IGZ1bmN0aW9uIG5vZGVPYnNlcnZlcigpIHtcbiAgICAgICAgdmFyIHIgPSB0aGlzLnByb3BzLmRhdGFNb2RlbC5nZXRSb290Tm9kZSgpO1xuICAgICAgICBpZiAoIXIuaXNMb2FkZWQoKSkge1xuICAgICAgICAgICAgci5vYnNlcnZlT25jZShcImxvYWRlZFwiLCAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZm9yY2VVcGRhdGUoKTtcbiAgICAgICAgICAgIH0pLmJpbmQodGhpcykpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5mb3JjZVVwZGF0ZSgpO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIGNvbXBvbmVudERpZE1vdW50OiBmdW5jdGlvbiBjb21wb25lbnREaWRNb3VudCgpIHtcbiAgICAgICAgdmFyIGRtID0gdGhpcy5wcm9wcy5kYXRhTW9kZWw7XG4gICAgICAgIHRoaXMuX2RtT2JzID0gdGhpcy5ub2RlT2JzZXJ2ZXI7XG4gICAgICAgIGRtLm9ic2VydmUoXCJjb250ZXh0X2NoYW5nZWRcIiwgdGhpcy5fZG1PYnMpO1xuICAgICAgICBkbS5vYnNlcnZlKFwicm9vdF9ub2RlX2NoYW5nZWRcIiwgdGhpcy5fZG1PYnMpO1xuICAgICAgICB0aGlzLm5vZGVPYnNlcnZlcigpO1xuICAgIH0sXG5cbiAgICBjb21wb25lbnRXaWxsVW5tb3VudDogZnVuY3Rpb24gY29tcG9uZW50V2lsbFVubW91bnQoKSB7XG4gICAgICAgIGlmICh0aGlzLl9kbU9icykge1xuICAgICAgICAgICAgdmFyIGRtID0gdGhpcy5wcm9wcy5kYXRhTW9kZWw7XG4gICAgICAgICAgICBkbS5zdG9wT2JzZXJ2aW5nKFwiY29udGV4dF9jaGFuZ2VkXCIsIHRoaXMuX2RtT2JzKTtcbiAgICAgICAgICAgIGRtLnN0b3BPYnNlcnZpbmcoXCJyb290X25vZGVfY2hhbmdlZFwiLCB0aGlzLl9kbU9icyk7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgdHJlZU5vZGVTZWxlY3RlZDogZnVuY3Rpb24gdHJlZU5vZGVTZWxlY3RlZChuKSB7XG4gICAgICAgIGlmICh0aGlzLnByb3BzLm9uTm9kZVNlbGVjdGVkKSB7XG4gICAgICAgICAgICB0aGlzLnByb3BzLm9uTm9kZVNlbGVjdGVkKG4pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5wcm9wcy5kYXRhTW9kZWwucmVxdWlyZUNvbnRleHRDaGFuZ2Uobik7XG4gICAgICAgIH1cbiAgICB9LFxuXG4gICAgbm9kZUlzU2VsZWN0ZWQ6IGZ1bmN0aW9uIG5vZGVJc1NlbGVjdGVkKG4pIHtcbiAgICAgICAgcmV0dXJuIG4gPT09IHRoaXMucHJvcHMuZGF0YU1vZGVsLmdldENvbnRleHROb2RlKCk7XG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gcmVuZGVyKCkge1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5kcmFnZ2FibGUpIHtcbiAgICAgICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFB5ZGlvQ29tcG9uZW50cy5ETkRUcmVlVmlldywge1xuICAgICAgICAgICAgICAgIG9uTm9kZVNlbGVjdDogdGhpcy50cmVlTm9kZVNlbGVjdGVkLFxuICAgICAgICAgICAgICAgIG5vZGVJc1NlbGVjdGVkOiB0aGlzLm5vZGVJc1NlbGVjdGVkLFxuICAgICAgICAgICAgICAgIGRhdGFNb2RlbDogdGhpcy5wcm9wcy5kYXRhTW9kZWwsXG4gICAgICAgICAgICAgICAgbm9kZTogdGhpcy5wcm9wcy5kYXRhTW9kZWwuZ2V0Um9vdE5vZGUoKSxcbiAgICAgICAgICAgICAgICBzaG93Um9vdDogdGhpcy5wcm9wcy5zaG93Um9vdCA/IHRydWUgOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBzZWxlY3RlZEl0ZW1TdHlsZTogdGhpcy5wcm9wcy5zZWxlY3RlZEl0ZW1TdHlsZSxcbiAgICAgICAgICAgICAgICBnZXRJdGVtU3R5bGU6IHRoaXMucHJvcHMuZ2V0SXRlbVN0eWxlLFxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogXCJmb2xkZXJzLXRyZWVcIiArICh0aGlzLnByb3BzLmNsYXNzTmFtZSA/ICcgJyArIHRoaXMucHJvcHMuY2xhc3NOYW1lIDogJycpXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFB5ZGlvQ29tcG9uZW50cy5UcmVlVmlldywge1xuICAgICAgICAgICAgICAgIG9uTm9kZVNlbGVjdDogdGhpcy50cmVlTm9kZVNlbGVjdGVkLFxuICAgICAgICAgICAgICAgIG5vZGVJc1NlbGVjdGVkOiB0aGlzLm5vZGVJc1NlbGVjdGVkLFxuICAgICAgICAgICAgICAgIGRhdGFNb2RlbDogdGhpcy5wcm9wcy5kYXRhTW9kZWwsXG4gICAgICAgICAgICAgICAgbm9kZTogdGhpcy5wcm9wcy5kYXRhTW9kZWwuZ2V0Um9vdE5vZGUoKSxcbiAgICAgICAgICAgICAgICBzZWxlY3RlZEl0ZW1TdHlsZTogdGhpcy5wcm9wcy5zZWxlY3RlZEl0ZW1TdHlsZSxcbiAgICAgICAgICAgICAgICBnZXRJdGVtU3R5bGU6IHRoaXMucHJvcHMuZ2V0SXRlbVN0eWxlLFxuICAgICAgICAgICAgICAgIHNob3dSb290OiB0aGlzLnByb3BzLnNob3dSb290ID8gdHJ1ZSA6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogXCJmb2xkZXJzLXRyZWVcIiArICh0aGlzLnByb3BzLmNsYXNzTmFtZSA/ICcgJyArIHRoaXMucHJvcHMuY2xhc3NOYW1lIDogJycpXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxufSk7XG5cbmV4cG9ydHMuVHJlZVZpZXcgPSBUcmVlVmlldztcbmV4cG9ydHMuRE5EVHJlZVZpZXcgPSBETkRUcmVlVmlldztcbmV4cG9ydHMuRm9sZGVyc1RyZWUgPSBGb2xkZXJzVHJlZTtcbiJdfQ==