(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 0) { content = "Request Content Size: " + toputils.formatSize(flow.request.contentLength); } else { content = React.createElement("div", {className: "alert alert-info"}, "No Content"); } //TODO: Styling return ( React.createElement("section", null, React.createElement("div", {className: "first-line"}, first_line ), React.createElement(Headers, {message: flow.request}), React.createElement("hr", null), content ) ); } }); var FlowDetailResponse = React.createClass({displayName: "FlowDetailResponse", render: function () { var flow = this.props.flow; var first_line = [ "HTTP/" + flow.response.httpversion.join("."), flow.response.code, flow.response.msg ].join(" "); var content = null; if (flow.response.contentLength > 0) { content = "Response Content Size: " + toputils.formatSize(flow.response.contentLength); } else { content = React.createElement("div", {className: "alert alert-info"}, "No Content"); } //TODO: Styling return ( React.createElement("section", null, React.createElement("div", {className: "first-line"}, first_line ), React.createElement(Headers, {message: flow.response}), React.createElement("hr", null), content ) ); } }); var FlowDetailError = React.createClass({displayName: "FlowDetailError", render: function () { var flow = this.props.flow; return ( React.createElement("section", null, React.createElement("div", {className: "alert alert-warning"}, flow.error.msg, React.createElement("div", null, React.createElement("small", null, toputils.formatTimeStamp(flow.error.timestamp) ) ) ) ) ); } }); var TimeStamp = React.createClass({displayName: "TimeStamp", render: function () { if (!this.props.t) { //should be return null, but that triggers a React bug. return React.createElement("tr", null); } var ts = toputils.formatTimeStamp(this.props.t); var delta; if (this.props.deltaTo) { delta = toputils.formatTimeDelta(1000 * (this.props.t - this.props.deltaTo)); delta = React.createElement("span", {className: "text-muted"}, "(" + delta + ")"); } else { delta = null; } return React.createElement("tr", null, React.createElement("td", null, this.props.title + ":"), React.createElement("td", null, ts, " ", delta) ); } }); var ConnectionInfo = React.createClass({displayName: "ConnectionInfo", render: function () { var conn = this.props.conn; var address = conn.address.address.join(":"); var sni = React.createElement("tr", {key: "sni"}); //should be null, but that triggers a React bug. if (conn.sni) { sni = React.createElement("tr", {key: "sni"}, React.createElement("td", null, React.createElement("abbr", {title: "TLS Server Name Indication"}, "TLS SNI:") ), React.createElement("td", null, conn.sni) ); } return ( React.createElement("table", {className: "connection-table"}, React.createElement("tbody", null, React.createElement("tr", {key: "address"}, React.createElement("td", null, "Address:"), React.createElement("td", null, address) ), sni ) ) ); } }); var CertificateInfo = React.createClass({displayName: "CertificateInfo", render: function () { //TODO: We should fetch human-readable certificate representation // from the server var flow = this.props.flow; var client_conn = flow.client_conn; var server_conn = flow.server_conn; var preStyle = {maxHeight: 100}; return ( React.createElement("div", null, client_conn.cert ? React.createElement("h4", null, "Client Certificate") : null, client_conn.cert ? React.createElement("pre", {style: preStyle}, client_conn.cert) : null, server_conn.cert ? React.createElement("h4", null, "Server Certificate") : null, server_conn.cert ? React.createElement("pre", {style: preStyle}, server_conn.cert) : null ) ); } }); var Timing = React.createClass({displayName: "Timing", render: function () { var flow = this.props.flow; var sc = flow.server_conn; var cc = flow.client_conn; var req = flow.request; var resp = flow.response; var timestamps = [ { title: "Server conn. initiated", t: sc.timestamp_start, deltaTo: req.timestamp_start }, { title: "Server conn. TCP handshake", t: sc.timestamp_tcp_setup, deltaTo: req.timestamp_start }, { title: "Server conn. SSL handshake", t: sc.timestamp_ssl_setup, deltaTo: req.timestamp_start }, { title: "Client conn. established", t: cc.timestamp_start, deltaTo: req.timestamp_start }, { title: "Client conn. SSL handshake", t: cc.timestamp_ssl_setup, deltaTo: req.timestamp_start }, { title: "First request byte", t: req.timestamp_start, }, { title: "Request complete", t: req.timestamp_end, deltaTo: req.timestamp_start } ]; if (flow.response) { timestamps.push( { title: "First response byte", t: resp.timestamp_start, deltaTo: req.timestamp_start }, { title: "Response complete", t: resp.timestamp_end, deltaTo: req.timestamp_start } ); } //Add unique key for each row. timestamps.forEach(function (e) { e.key = e.title; }); timestamps = _.sortBy(timestamps, 't'); var rows = timestamps.map(function (e) { return React.createElement(TimeStamp, React.__spread({}, e)); }); return ( React.createElement("div", null, React.createElement("h4", null, "Timing"), React.createElement("table", {className: "timing-table"}, React.createElement("tbody", null, rows ) ) ) ); } }); var FlowDetailConnectionInfo = React.createClass({displayName: "FlowDetailConnectionInfo", render: function () { var flow = this.props.flow; var client_conn = flow.client_conn; var server_conn = flow.server_conn; return ( React.createElement("section", null, React.createElement("h4", null, "Client Connection"), React.createElement(ConnectionInfo, {conn: client_conn}), React.createElement("h4", null, "Server Connection"), React.createElement(ConnectionInfo, {conn: server_conn}), React.createElement(CertificateInfo, {flow: flow}), React.createElement(Timing, {flow: flow}) ) ); } }); var allTabs = { request: FlowDetailRequest, response: FlowDetailResponse, error: FlowDetailError, details: FlowDetailConnectionInfo }; var FlowDetail = React.createClass({displayName: "FlowDetail", mixins: [utils.StickyHeadMixin, utils.Navigation, utils.State], getTabs: function (flow) { var tabs = []; ["request", "response", "error"].forEach(function (e) { if (flow[e]) { tabs.push(e); } }); tabs.push("details"); return tabs; }, nextTab: function (i) { var tabs = this.getTabs(this.props.flow); var currentIndex = tabs.indexOf(this.getParams().detailTab); // JS modulo operator doesn't correct negative numbers, make sure that we are positive. var nextIndex = (currentIndex + i + tabs.length) % tabs.length; this.selectTab(tabs[nextIndex]); }, selectTab: function (panel) { this.replaceWith( "flow", { flowId: this.getParams().flowId, detailTab: panel } ); }, render: function () { var flow = this.props.flow; var tabs = this.getTabs(flow); var active = this.getParams().detailTab; if (!_.contains(tabs, active)) { if (active === "response" && flow.error) { active = "error"; } else if (active === "error" && flow.response) { active = "response"; } else { active = tabs[0]; } this.selectTab(active); } var Tab = allTabs[active]; return ( React.createElement("div", {className: "flow-detail", onScroll: this.adjustHead}, React.createElement(FlowDetailNav, {ref: "head", flow: flow, tabs: tabs, active: active, selectTab: this.selectTab}), React.createElement(Tab, {flow: flow}) ) ); } }); module.exports = { FlowDetail: FlowDetail }; },{"../actions.js":1,"../flow/utils.js":16,"../utils.js":19,"./utils.js":11,"lodash":"lodash","react":"react"}],5:[function(require,module,exports){ var React = require("react"); var flowutils = require("../flow/utils.js"); var utils = require("../utils.js"); var TLSColumn = React.createClass({displayName: "TLSColumn", statics: { renderTitle: function () { return React.createElement("th", {key: "tls", className: "col-tls"}); } }, render: function () { var flow = this.props.flow; var ssl = (flow.request.scheme == "https"); var classes; if (ssl) { classes = "col-tls col-tls-https"; } else { classes = "col-tls col-tls-http"; } return React.createElement("td", {className: classes}); } }); var IconColumn = React.createClass({displayName: "IconColumn", statics: { renderTitle: function () { return React.createElement("th", {key: "icon", className: "col-icon"}); } }, render: function () { var flow = this.props.flow; var icon; if (flow.response) { var contentType = flowutils.ResponseUtils.getContentType(flow.response); //TODO: We should assign a type to the flow somewhere else. if (flow.response.code == 304) { icon = "resource-icon-not-modified"; } else if (300 <= flow.response.code && flow.response.code < 400) { icon = "resource-icon-redirect"; } else if (contentType && contentType.indexOf("image") >= 0) { icon = "resource-icon-image"; } else if (contentType && contentType.indexOf("javascript") >= 0) { icon = "resource-icon-js"; } else if (contentType && contentType.indexOf("css") >= 0) { icon = "resource-icon-css"; } else if (contentType && contentType.indexOf("html") >= 0) { icon = "resource-icon-document"; } } if (!icon) { icon = "resource-icon-plain"; } icon += " resource-icon"; return React.createElement("td", {className: "col-icon"}, React.createElement("div", {className: icon}) ); } }); var PathColumn = React.createClass({displayName: "PathColumn", statics: { renderTitle: function () { return React.createElement("th", {key: "path", className: "col-path"}, "Path"); } }, render: function () { var flow = this.props.flow; return React.createElement("td", {className: "col-path"}, flow.request.is_replay ? React.createElement("i", {className: "fa fa-fw fa-repeat pull-right"}) : null, flow.intercepted ? React.createElement("i", {className: "fa fa-fw fa-pause pull-right"}) : null, flow.request.scheme + "://" + flow.request.host + flow.request.path ); } }); var MethodColumn = React.createClass({displayName: "MethodColumn", statics: { renderTitle: function () { return React.createElement("th", {key: "method", className: "col-method"}, "Method"); } }, render: function () { var flow = this.props.flow; return React.createElement("td", {className: "col-method"}, flow.request.method); } }); var StatusColumn = React.createClass({displayName: "StatusColumn", statics: { renderTitle: function () { return React.createElement("th", {key: "status", className: "col-status"}, "Status"); } }, render: function () { var flow = this.props.flow; var status; if (flow.response) { status = flow.response.code; } else { status = null; } return React.createElement("td", {className: "col-status"}, status); } }); var SizeColumn = React.createClass({displayName: "SizeColumn", statics: { renderTitle: function () { return React.createElement("th", {key: "size", className: "col-size"}, "Size"); } }, render: function () { var flow = this.props.flow; var total = flow.request.contentLength; if (flow.response) { total += flow.response.contentLength || 0; } var size = utils.formatSize(total); return React.createElement("td", {className: "col-size"}, size); } }); var TimeColumn = React.createClass({displayName: "TimeColumn", statics: { renderTitle: function () { return React.createElement("th", {key: "time", className: "col-time"}, "Time"); } }, render: function () { var flow = this.props.flow; var time; if (flow.response) { time = utils.formatTimeDelta(1000 * (flow.response.timestamp_end - flow.request.timestamp_start)); } else { time = "..."; } return React.createElement("td", {className: "col-time"}, time); } }); var all_columns = [ TLSColumn, IconColumn, PathColumn, MethodColumn, StatusColumn, SizeColumn, TimeColumn]; module.exports = all_columns; },{"../flow/utils.js":16,"../utils.js":19,"react":"react"}],6:[function(require,module,exports){ var React = require("react"); var utils = require("./utils.js"); var VirtualScrollMixin = require("./virtualscroll.js"); var flowtable_columns = require("./flowtable-columns.js"); var FlowRow = React.createClass({displayName: "FlowRow", render: function () { var flow = this.props.flow; var columns = this.props.columns.map(function (Column) { return React.createElement(Column, {key: Column.displayName, flow: flow}); }.bind(this)); var className = ""; if (this.props.selected) { className += " selected"; } if (this.props.highlighted) { className += " highlighted"; } if (flow.intercepted) { className += " intercepted"; } if (flow.request) { className += " has-request"; } if (flow.response) { className += " has-response"; } return ( React.createElement("tr", {className: className, onClick: this.props.selectFlow.bind(null, flow)}, columns )); }, shouldComponentUpdate: function (nextProps) { return true; // Further optimization could be done here // by calling forceUpdate on flow updates, selection changes and column changes. //return ( //(this.props.columns.length !== nextProps.columns.length) || //(this.props.selected !== nextProps.selected) //); } }); var FlowTableHead = React.createClass({displayName: "FlowTableHead", render: function () { var columns = this.props.columns.map(function (column) { return column.renderTitle(); }.bind(this)); return React.createElement("thead", null, React.createElement("tr", null, columns) ); } }); var ROW_HEIGHT = 32; var FlowTable = React.createClass({displayName: "FlowTable", mixins: [utils.StickyHeadMixin, utils.AutoScrollMixin, VirtualScrollMixin], getInitialState: function () { return { columns: flowtable_columns }; }, componentWillMount: function () { if (this.props.view) { this.props.view.addListener("add update remove recalculate", this.onChange); } }, componentWillReceiveProps: function (nextProps) { if (nextProps.view !== this.props.view) { if (this.props.view) { this.props.view.removeListener("add update remove recalculate"); } nextProps.view.addListener("add update remove recalculate", this.onChange); } }, getDefaultProps: function () { return { rowHeight: ROW_HEIGHT }; }, onScrollFlowTable: function () { this.adjustHead(); this.onScroll(); }, onChange: function () { this.forceUpdate(); }, scrollIntoView: function (flow) { this.scrollRowIntoView( this.props.view.index(flow), this.refs.body.getDOMNode().offsetTop ); }, renderRow: function (flow) { var selected = (flow === this.props.selected); var highlighted = ( this.props.view._highlight && this.props.view._highlight[flow.id] ); return React.createElement(FlowRow, {key: flow.id, ref: flow.id, flow: flow, columns: this.state.columns, selected: selected, highlighted: highlighted, selectFlow: this.props.selectFlow} ); }, render: function () { //console.log("render flowtable", this.state.start, this.state.stop, this.props.selected); var flows = this.props.view ? this.props.view.list : []; var rows = this.renderRows(flows); return ( React.createElement("div", {className: "flow-table", onScroll: this.onScrollFlowTable}, React.createElement("table", null, React.createElement(FlowTableHead, {ref: "head", columns: this.state.columns}), React.createElement("tbody", {ref: "body"}, this.getPlaceholderTop(flows.length), rows, this.getPlaceholderBottom(flows.length) ) ) ) ); } }); module.exports = FlowTable; },{"./flowtable-columns.js":5,"./utils.js":11,"./virtualscroll.js":12,"react":"react"}],7:[function(require,module,exports){ var React = require("react"); var Footer = React.createClass({displayName: "Footer", render: function () { var mode = this.props.settings.mode; var intercept = this.props.settings.intercept; return ( React.createElement("footer", null, mode != "regular" ? React.createElement("span", {className: "label label-success"}, mode, " mode") : null, " ", intercept ? React.createElement("span", {className: "label label-success"}, "Intercept: ", intercept) : null ) ); } }); module.exports = Footer; },{"react":"react"}],8:[function(require,module,exports){ var React = require("react"); var $ = require("jquery"); var utils = require("./utils.js"); var FilterDocs = React.createClass({displayName: "FilterDocs", statics: { xhr: false, doc: false }, componentWillMount: function () { if (!FilterDocs.doc) { FilterDocs.xhr = $.getJSON("/filter-help").done(function (doc) { FilterDocs.doc = doc; FilterDocs.xhr = false; }); } if (FilterDocs.xhr) { FilterDocs.xhr.done(function () { this.forceUpdate(); }.bind(this)); } }, render: function () { if (!FilterDocs.doc) { return React.createElement("i", {className: "fa fa-spinner fa-spin"}); } else { var commands = FilterDocs.doc.commands.map(function (c) { return React.createElement("tr", null, React.createElement("td", null, c[0].replace(" ", '\u00a0')), React.createElement("td", null, c[1]) ); }); commands.push(React.createElement("tr", null, React.createElement("td", {colSpan: "2"}, React.createElement("a", {href: "https://mitmproxy.org/doc/features/filters.html", target: "_blank"}, React.createElement("i", {className: "fa fa-external-link"}), "  mitmproxy docs") ) )); return React.createElement("table", {className: "table table-condensed"}, React.createElement("tbody", null, commands) ); } } }); var FilterInput = React.createClass({displayName: "FilterInput", getInitialState: function () { // Consider both focus and mouseover for showing/hiding the tooltip, // because onBlur of the input is triggered before the click on the tooltip // finalized, hiding the tooltip just as the user clicks on it. return { value: this.props.value, focus: false, mousefocus: false }; }, componentWillReceiveProps: function (nextProps) { this.setState({value: nextProps.value}); }, onChange: function (e) { var nextValue = e.target.value; this.setState({ value: nextValue }); // Only propagate valid filters upwards. if (this.isValid(nextValue)) { this.props.onChange(nextValue); } }, isValid: function (filt) { try { Filt.parse(filt || this.state.value); return true; } catch (e) { return false; } }, getDesc: function () { var desc; try { desc = Filt.parse(this.state.value).desc; } catch (e) { desc = "" + e; } if (desc !== "true") { return desc; } else { return ( React.createElement(FilterDocs, null) ); } }, onFocus: function () { this.setState({focus: true}); }, onBlur: function () { this.setState({focus: false}); }, onMouseEnter: function () { this.setState({mousefocus: true}); }, onMouseLeave: function () { this.setState({mousefocus: false}); }, onKeyDown: function (e) { if (e.keyCode === Key.ESC || e.keyCode === Key.ENTER) { this.blur(); // If closed using ESC/ENTER, hide the tooltip. this.setState({mousefocus: false}); } }, blur: function () { this.refs.input.getDOMNode().blur(); }, focus: function () { this.refs.input.getDOMNode().select(); }, render: function () { var isValid = this.isValid(); var icon = "fa fa-fw fa-" + this.props.type; var groupClassName = "filter-input input-group" + (isValid ? "" : " has-error"); var popover; if (this.state.focus || this.state.mousefocus) { popover = ( React.createElement("div", {className: "popover bottom", onMouseEnter: this.onMouseEnter, onMouseLeave: this.onMouseLeave}, React.createElement("div", {className: "arrow"}), React.createElement("div", {className: "popover-content"}, this.getDesc() ) ) ); } return ( React.createElement("div", {className: groupClassName}, React.createElement("span", {className: "input-group-addon"}, React.createElement("i", {className: icon, style: {color: this.props.color}}) ), React.createElement("input", {type: "text", placeholder: this.props.placeholder, className: "form-control", ref: "input", onChange: this.onChange, onFocus: this.onFocus, onBlur: this.onBlur, onKeyDown: this.onKeyDown, value: this.state.value}), popover ) ); } }); var MainMenu = React.createClass({displayName: "MainMenu", mixins: [utils.Navigation, utils.State], statics: { title: "Start", route: "flows" }, onFilterChange: function (val) { var d = {}; d[Query.FILTER] = val; this.setQuery(d); }, onHighlightChange: function (val) { var d = {}; d[Query.HIGHLIGHT] = val; this.setQuery(d); }, onInterceptChange: function (val) { SettingsActions.update({intercept: val}); }, render: function () { var filter = this.getQuery()[Query.FILTER] || ""; var highlight = this.getQuery()[Query.HIGHLIGHT] || ""; var intercept = this.props.settings.intercept || ""; return ( React.createElement("div", null, React.createElement("div", {className: "menu-row"}, React.createElement(FilterInput, { placeholder: "Filter", type: "filter", color: "black", value: filter, onChange: this.onFilterChange}), React.createElement(FilterInput, { placeholder: "Highlight", type: "tag", color: "hsl(48, 100%, 50%)", value: highlight, onChange: this.onHighlightChange}), React.createElement(FilterInput, { placeholder: "Intercept", type: "pause", color: "hsl(208, 56%, 53%)", value: intercept, onChange: this.onInterceptChange}) ), React.createElement("div", {className: "clearfix"}) ) ); } }); var ViewMenu = React.createClass({displayName: "ViewMenu", statics: { title: "View", route: "flows" }, mixins: [utils.Navigation, utils.State], toggleEventLog: function () { var d = {}; if (this.getQuery()[Query.SHOW_EVENTLOG]) { d[Query.SHOW_EVENTLOG] = undefined; } else { d[Query.SHOW_EVENTLOG] = "t"; // any non-false value will do it, keep it short } this.setQuery(d); }, render: function () { var showEventLog = this.getQuery()[Query.SHOW_EVENTLOG]; return ( React.createElement("div", null, React.createElement("button", { className: "btn " + (showEventLog ? "btn-primary" : "btn-default"), onClick: this.toggleEventLog}, React.createElement("i", {className: "fa fa-database"}), " Show Eventlog" ), React.createElement("span", null, " ") ) ); } }); var ReportsMenu = React.createClass({displayName: "ReportsMenu", statics: { title: "Visualization", route: "reports" }, render: function () { return React.createElement("div", null, "Reports Menu"); } }); var FileMenu = React.createClass({displayName: "FileMenu", getInitialState: function () { return { showFileMenu: false }; }, handleFileClick: function (e) { e.preventDefault(); if (!this.state.showFileMenu) { var close = function () { this.setState({showFileMenu: false}); document.removeEventListener("click", close); }.bind(this); document.addEventListener("click", close); this.setState({ showFileMenu: true }); } }, handleNewClick: function (e) { e.preventDefault(); if (confirm("Delete all flows?")) { FlowActions.clear(); } }, handleOpenClick: function (e) { e.preventDefault(); console.error("unimplemented: handleOpenClick"); }, handleSaveClick: function (e) { e.preventDefault(); console.error("unimplemented: handleSaveClick"); }, handleShutdownClick: function (e) { e.preventDefault(); console.error("unimplemented: handleShutdownClick"); }, render: function () { var fileMenuClass = "dropdown pull-left" + (this.state.showFileMenu ? " open" : ""); return ( React.createElement("div", {className: fileMenuClass}, React.createElement("a", {href: "#", className: "special", onClick: this.handleFileClick}, " File "), React.createElement("ul", {className: "dropdown-menu", role: "menu"}, React.createElement("li", null, React.createElement("a", {href: "#", onClick: this.handleNewClick}, React.createElement("i", {className: "fa fa-fw fa-file"}), "New" ) ), React.createElement("li", {role: "presentation", className: "divider"}), React.createElement("li", null, React.createElement("a", {href: "http://mitm.it/", target: "_blank"}, React.createElement("i", {className: "fa fa-fw fa-external-link"}), "Install Certificates..." ) ) /*
  • Open
  • Save
  • Shutdown
  • */ ) ) ); } }); var header_entries = [MainMenu, ViewMenu /*, ReportsMenu */]; var Header = React.createClass({displayName: "Header", mixins: [utils.Navigation], getInitialState: function () { return { active: header_entries[0] }; }, handleClick: function (active, e) { e.preventDefault(); this.replaceWith(active.route); this.setState({active: active}); }, render: function () { var header = header_entries.map(function (entry, i) { var classes = React.addons.classSet({ active: entry == this.state.active }); return ( React.createElement("a", {key: i, href: "#", className: classes, onClick: this.handleClick.bind(this, entry) }, entry.title ) ); }.bind(this)); return ( React.createElement("header", null, React.createElement("div", {className: "title-bar"}, "mitmproxy ", this.props.settings.version ), React.createElement("nav", {className: "nav-tabs nav-tabs-lg"}, React.createElement(FileMenu, null), header ), React.createElement("div", {className: "menu"}, React.createElement(this.state.active, {settings: this.props.settings}) ) ) ); } }); module.exports = { Header: Header } },{"./utils.js":11,"jquery":"jquery","react":"react"}],9:[function(require,module,exports){ var React = require("react"); var utils = require("./utils.js"); var toputils = require("../utils.js"); var views = require("../store/view.js"); var Filt = require("../filt/filt.js"); FlowTable = require("./flowtable.js"); var flowdetail = require("./flowdetail.js"); var MainView = React.createClass({displayName: "MainView", mixins: [utils.Navigation, utils.State], getInitialState: function () { this.onQueryChange(Query.FILTER, function () { this.state.view.recalculate(this.getViewFilt(), this.getViewSort()); }.bind(this)); this.onQueryChange(Query.HIGHLIGHT, function () { this.state.view.recalculate(this.getViewFilt(), this.getViewSort()); }.bind(this)); return { flows: [] }; }, getViewFilt: function () { try { var filt = Filt.parse(this.getQuery()[Query.FILTER] || ""); var highlightStr = this.getQuery()[Query.HIGHLIGHT]; var highlight = highlightStr ? Filt.parse(highlightStr) : false; } catch (e) { console.error("Error when processing filter: " + e); } return function filter_and_highlight(flow) { if (!this._highlight) { this._highlight = {}; } this._highlight[flow.id] = highlight && highlight(flow); return filt(flow); }; }, getViewSort: function () { }, componentWillReceiveProps: function (nextProps) { if (nextProps.flowStore !== this.props.flowStore) { this.closeView(); this.openView(nextProps.flowStore); } }, openView: function (store) { var view = new views.StoreView(store, this.getViewFilt(), this.getViewSort()); this.setState({ view: view }); view.addListener("recalculate", this.onRecalculate); view.addListener("add update remove", this.onUpdate); view.addListener("remove", this.onRemove); }, onRecalculate: function () { this.forceUpdate(); var selected = this.getSelected(); if (selected) { this.refs.flowTable.scrollIntoView(selected); } }, onUpdate: function (flow) { if (flow.id === this.getParams().flowId) { this.forceUpdate(); } }, onRemove: function (flow_id, index) { if (flow_id === this.getParams().flowId) { var flow_to_select = this.state.view.list[Math.min(index, this.state.view.list.length -1)]; this.selectFlow(flow_to_select); } }, closeView: function () { this.state.view.close(); }, componentWillMount: function () { this.openView(this.props.flowStore); }, componentWillUnmount: function () { this.closeView(); }, selectFlow: function (flow) { if (flow) { this.replaceWith( "flow", { flowId: flow.id, detailTab: this.getParams().detailTab || "request" } ); this.refs.flowTable.scrollIntoView(flow); } else { this.replaceWith("flows", {}); } }, selectFlowRelative: function (shift) { var flows = this.state.view.list; var index; if (!this.getParams().flowId) { if (shift > 0) { index = flows.length - 1; } else { index = 0; } } else { var currFlowId = this.getParams().flowId; var i = flows.length; while (i--) { if (flows[i].id === currFlowId) { index = i; break; } } index = Math.min( Math.max(0, index + shift), flows.length - 1); } this.selectFlow(flows[index]); }, onKeyDown: function (e) { var flow = this.getSelected(); if (e.ctrlKey) { return; } switch (e.keyCode) { case toputils.Key.K: case toputils.Key.UP: this.selectFlowRelative(-1); break; case toputils.Key.J: case toputils.Key.DOWN: this.selectFlowRelative(+1); break; case toputils.Key.SPACE: case toputils.Key.PAGE_DOWN: this.selectFlowRelative(+10); break; case toputils.Key.PAGE_UP: this.selectFlowRelative(-10); break; case toputils.Key.END: this.selectFlowRelative(+1e10); break; case toputils.Key.HOME: this.selectFlowRelative(-1e10); break; case toputils.Key.ESC: this.selectFlow(null); break; case toputils.Key.H: case toputils.Key.LEFT: if (this.refs.flowDetails) { this.refs.flowDetails.nextTab(-1); } break; case toputils.Key.L: case toputils.Key.TAB: case toputils.Key.RIGHT: if (this.refs.flowDetails) { this.refs.flowDetails.nextTab(+1); } break; case toputils.Key.C: if (e.shiftKey) { FlowActions.clear(); } break; case toputils.Key.D: if (flow) { if (e.shiftKey) { FlowActions.duplicate(flow); } else { FlowActions.delete(flow); } } break; case toputils.Key.A: if (e.shiftKey) { FlowActions.accept_all(); } else if (flow && flow.intercepted) { FlowActions.accept(flow); } break; case toputils.Key.R: if (!e.shiftKey && flow) { FlowActions.replay(flow); } break; case toputils.Key.V: if(e.shiftKey && flow && flow.modified) { FlowActions.revert(flow); } break; default: console.debug("keydown", e.keyCode); return; } e.preventDefault(); }, getSelected: function () { return this.props.flowStore.get(this.getParams().flowId); }, render: function () { var selected = this.getSelected(); var details; if (selected) { details = [ React.createElement(utils.Splitter, {key: "splitter"}), React.createElement(flowdetail.FlowDetail, {key: "flowDetails", ref: "flowDetails", flow: selected}) ]; } else { details = null; } return ( React.createElement("div", {className: "main-view", onKeyDown: this.onKeyDown, tabIndex: "0"}, React.createElement(FlowTable, {ref: "flowTable", view: this.state.view, selectFlow: this.selectFlow, selected: selected}), details ) ); } }); module.exports = MainView; },{"../filt/filt.js":15,"../store/view.js":18,"../utils.js":19,"./flowdetail.js":4,"./flowtable.js":6,"./utils.js":11,"react":"react"}],10:[function(require,module,exports){ var React = require("react"); var ReactRouter = require("react-router"); var _ = require("lodash"); var utils = require("./utils.js"); var MainView = require("./mainview.js"); var Footer = require("./footer.js"); var header = require("./header.js"); var EventLog = require("./eventlog.js"); var store = require("../store/store.js"); //TODO: Move out of here, just a stub. var Reports = React.createClass({displayName: "Reports", render: function () { return React.createElement("div", null, "ReportEditor"); } }); var ProxyAppMain = React.createClass({displayName: "ProxyAppMain", mixins: [utils.State], getInitialState: function () { var eventStore = new store.EventLogStore(); var flowStore = new store.FlowStore(); var settings = new store.SettingsStore(); // Default Settings before fetch _.extend(settings.dict,{ }); return { settings: settings, flowStore: flowStore, eventStore: eventStore }; }, componentDidMount: function () { this.state.settings.addListener("recalculate", this.onSettingsChange); window.app = this; }, componentWillUnmount: function () { this.state.settings.removeListener("recalculate", this.onSettingsChange); }, onSettingsChange: function(){ this.setState({ settings: this.state.settings }); }, render: function () { var eventlog; if (this.getQuery()[Query.SHOW_EVENTLOG]) { eventlog = [ React.createElement(utils.Splitter, {key: "splitter", axis: "y"}), React.createElement(EventLog, {key: "eventlog", eventStore: this.state.eventStore}) ]; } else { eventlog = null; } return ( React.createElement("div", {id: "container"}, React.createElement(header.Header, {settings: this.state.settings.dict}), React.createElement(RouteHandler, {settings: this.state.settings.dict, flowStore: this.state.flowStore}), eventlog, React.createElement(Footer, {settings: this.state.settings.dict}) ) ); } }); var Route = ReactRouter.Route; var RouteHandler = ReactRouter.RouteHandler; var Redirect = ReactRouter.Redirect; var DefaultRoute = ReactRouter.DefaultRoute; var NotFoundRoute = ReactRouter.NotFoundRoute; var routes = ( React.createElement(Route, {path: "/", handler: ProxyAppMain}, React.createElement(Route, {name: "flows", path: "flows", handler: MainView}), React.createElement(Route, {name: "flow", path: "flows/:flowId/:detailTab", handler: MainView}), React.createElement(Route, {name: "reports", handler: Reports}), React.createElement(Redirect, {path: "/", to: "flows"}) ) ); module.exports = { routes: routes }; },{"../store/store.js":17,"./eventlog.js":3,"./footer.js":7,"./header.js":8,"./mainview.js":9,"./utils.js":11,"lodash":"lodash","react":"react","react-router":"react-router"}],11:[function(require,module,exports){ var React = require("react"); var ReactRouter = require("react-router"); var _ = require("lodash"); //React utils. For other utilities, see ../utils.js // http://blog.vjeux.com/2013/javascript/scroll-position-with-react.html (also contains inverse example) var AutoScrollMixin = { componentWillUpdate: function () { var node = this.getDOMNode(); this._shouldScrollBottom = ( node.scrollTop !== 0 && node.scrollTop + node.clientHeight === node.scrollHeight ); }, componentDidUpdate: function () { if (this._shouldScrollBottom) { var node = this.getDOMNode(); node.scrollTop = node.scrollHeight; } }, }; var StickyHeadMixin = { adjustHead: function () { // Abusing CSS transforms to set the element // referenced as head into some kind of position:sticky. var head = this.refs.head.getDOMNode(); head.style.transform = "translate(0," + this.getDOMNode().scrollTop + "px)"; } }; var Navigation = _.extend({}, ReactRouter.Navigation, { setQuery: function (dict) { var q = this.context.getCurrentQuery(); for(var i in dict){ if(dict.hasOwnProperty(i)){ q[i] = dict[i] || undefined; //falsey values shall be removed. } } q._ = "_"; // workaround for https://github.com/rackt/react-router/pull/599 this.replaceWith(this.context.getCurrentPath(), this.context.getCurrentParams(), q); }, replaceWith: function(routeNameOrPath, params, query) { if(routeNameOrPath === undefined){ routeNameOrPath = this.context.getCurrentPath(); } if(params === undefined){ params = this.context.getCurrentParams(); } if(query === undefined){ query = this.context.getCurrentQuery(); } ReactRouter.Navigation.replaceWith.call(this, routeNameOrPath, params, query); } }); _.extend(Navigation.contextTypes, ReactRouter.State.contextTypes); var State = _.extend({}, ReactRouter.State, { getInitialState: function () { this._query = this.context.getCurrentQuery(); this._queryWatches = []; return null; }, onQueryChange: function (key, callback) { this._queryWatches.push({ key: key, callback: callback }); }, componentWillReceiveProps: function (nextProps, nextState) { var q = this.context.getCurrentQuery(); for (var i = 0; i < this._queryWatches.length; i++) { var watch = this._queryWatches[i]; if (this._query[watch.key] !== q[watch.key]) { watch.callback(this._query[watch.key], q[watch.key], watch.key); } } this._query = q; } }); var Splitter = React.createClass({displayName: "Splitter", getDefaultProps: function () { return { axis: "x" }; }, getInitialState: function () { return { applied: false, startX: false, startY: false }; }, onMouseDown: function (e) { this.setState({ startX: e.pageX, startY: e.pageY }); window.addEventListener("mousemove", this.onMouseMove); window.addEventListener("mouseup", this.onMouseUp); // Occasionally, only a dragEnd event is triggered, but no mouseUp. window.addEventListener("dragend", this.onDragEnd); }, onDragEnd: function () { this.getDOMNode().style.transform = ""; window.removeEventListener("dragend", this.onDragEnd); window.removeEventListener("mouseup", this.onMouseUp); window.removeEventListener("mousemove", this.onMouseMove); }, onMouseUp: function (e) { this.onDragEnd(); var node = this.getDOMNode(); var prev = node.previousElementSibling; var next = node.nextElementSibling; var dX = e.pageX - this.state.startX; var dY = e.pageY - this.state.startY; var flexBasis; if (this.props.axis === "x") { flexBasis = prev.offsetWidth + dX; } else { flexBasis = prev.offsetHeight + dY; } prev.style.flex = "0 0 " + Math.max(0, flexBasis) + "px"; next.style.flex = "1 1 auto"; this.setState({ applied: true }); this.onResize(); }, onMouseMove: function (e) { var dX = 0, dY = 0; if (this.props.axis === "x") { dX = e.pageX - this.state.startX; } else { dY = e.pageY - this.state.startY; } this.getDOMNode().style.transform = "translate(" + dX + "px," + dY + "px)"; }, onResize: function () { // Trigger a global resize event. This notifies components that employ virtual scrolling // that their viewport may have changed. window.setTimeout(function () { window.dispatchEvent(new CustomEvent("resize")); }, 1); }, reset: function (willUnmount) { if (!this.state.applied) { return; } var node = this.getDOMNode(); var prev = node.previousElementSibling; var next = node.nextElementSibling; prev.style.flex = ""; next.style.flex = ""; if (!willUnmount) { this.setState({ applied: false }); } this.onResize(); }, componentWillUnmount: function () { this.reset(true); }, render: function () { var className = "splitter"; if (this.props.axis === "x") { className += " splitter-x"; } else { className += " splitter-y"; } return ( React.createElement("div", {className: className}, React.createElement("div", {onMouseDown: this.onMouseDown, draggable: "true"}) ) ); } }); module.exports = { State: State, Navigation: Navigation, StickyHeadMixin: StickyHeadMixin, AutoScrollMixin: AutoScrollMixin, Splitter: Splitter } },{"lodash":"lodash","react":"react","react-router":"react-router"}],12:[function(require,module,exports){ var React = require("react"); var VirtualScrollMixin = { getInitialState: function () { return { start: 0, stop: 0 }; }, componentWillMount: function () { if (!this.props.rowHeight) { console.warn("VirtualScrollMixin: No rowHeight specified", this); } }, getPlaceholderTop: function (total) { var Tag = this.props.placeholderTagName || "tr"; // When a large trunk of elements is removed from the button, start may be far off the viewport. // To make this issue less severe, limit the top placeholder to the total number of rows. var style = { height: Math.min(this.state.start, total) * this.props.rowHeight }; var spacer = React.createElement(Tag, {key: "placeholder-top", style: style}); if (this.state.start % 2 === 1) { // fix even/odd rows return [spacer, React.createElement(Tag, {key: "placeholder-top-2"})]; } else { return spacer; } }, getPlaceholderBottom: function (total) { var Tag = this.props.placeholderTagName || "tr"; var style = { height: Math.max(0, total - this.state.stop) * this.props.rowHeight }; return React.createElement(Tag, {key: "placeholder-bottom", style: style}); }, componentDidMount: function () { this.onScroll(); window.addEventListener('resize', this.onScroll); }, componentWillUnmount: function(){ window.removeEventListener('resize', this.onScroll); }, onScroll: function () { var viewport = this.getDOMNode(); var top = viewport.scrollTop; var height = viewport.offsetHeight; var start = Math.floor(top / this.props.rowHeight); var stop = start + Math.ceil(height / (this.props.rowHeightMin || this.props.rowHeight)); this.setState({ start: start, stop: stop }); }, renderRows: function (elems) { var rows = []; var max = Math.min(elems.length, this.state.stop); for (var i = this.state.start; i < max; i++) { var elem = elems[i]; rows.push(this.renderRow(elem)); } return rows; }, scrollRowIntoView: function (index, head_height) { var row_top = (index * this.props.rowHeight) + head_height; var row_bottom = row_top + this.props.rowHeight; var viewport = this.getDOMNode(); var viewport_top = viewport.scrollTop; var viewport_bottom = viewport_top + viewport.offsetHeight; // Account for pinned thead if (row_top - head_height < viewport_top) { viewport.scrollTop = row_top - head_height; } else if (row_bottom > viewport_bottom) { viewport.scrollTop = row_bottom - viewport.offsetHeight; } }, }; module.exports = VirtualScrollMixin; },{"react":"react"}],13:[function(require,module,exports){ var actions = require("./actions.js"); function Connection(url) { if (url[0] === "/") { url = location.origin.replace("http", "ws") + url; } var ws = new WebSocket(url); ws.onopen = function () { actions.ConnectionActions.open(); }; ws.onmessage = function (message) { var m = JSON.parse(message.data); AppDispatcher.dispatchServerAction(m); }; ws.onerror = function () { actions.ConnectionActions.error(); EventLogActions.add_event("WebSocket connection error."); }; ws.onclose = function () { actions.ConnectionActions.close(); EventLogActions.add_event("WebSocket connection closed."); }; return ws; } module.exports = Connection; },{"./actions.js":1}],14:[function(require,module,exports){ const PayloadSources = { VIEW: "view", SERVER: "server" }; function Dispatcher() { this.callbacks = []; } Dispatcher.prototype.register = function (callback) { this.callbacks.push(callback); }; Dispatcher.prototype.unregister = function (callback) { var index = this.callbacks.indexOf(callback); if (index >= 0) { this.callbacks.splice(index, 1); } }; Dispatcher.prototype.dispatch = function (payload) { console.debug("dispatch", payload); for (var i = 0; i < this.callbacks.length; i++) { this.callbacks[i](payload); } }; AppDispatcher = new Dispatcher(); AppDispatcher.dispatchViewAction = function (action) { action.source = PayloadSources.VIEW; this.dispatch(action); }; AppDispatcher.dispatchServerAction = function (action) { action.source = PayloadSources.SERVER; this.dispatch(action); }; module.exports = { AppDispatcher: AppDispatcher }; },{}],15:[function(require,module,exports){ /* jshint ignore:start */ Filt = (function() { /* * Generated by PEG.js 0.8.0. * * http://pegjs.majda.cz/ */ function peg$subclass(child, parent) { function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); } function SyntaxError(message, expected, found, offset, line, column) { this.message = message; this.expected = expected; this.found = found; this.offset = offset; this.line = line; this.column = column; this.name = "SyntaxError"; } peg$subclass(SyntaxError, Error); function parse(input) { var options = arguments.length > 1 ? arguments[1] : {}, peg$FAILED = {}, peg$startRuleFunctions = { start: peg$parsestart }, peg$startRuleFunction = peg$parsestart, peg$c0 = { type: "other", description: "filter expression" }, peg$c1 = peg$FAILED, peg$c2 = function(orExpr) { return orExpr; }, peg$c3 = [], peg$c4 = function() {return trueFilter; }, peg$c5 = { type: "other", description: "whitespace" }, peg$c6 = /^[ \t\n\r]/, peg$c7 = { type: "class", value: "[ \\t\\n\\r]", description: "[ \\t\\n\\r]" }, peg$c8 = { type: "other", description: "control character" }, peg$c9 = /^[|&!()~"]/, peg$c10 = { type: "class", value: "[|&!()~\"]", description: "[|&!()~\"]" }, peg$c11 = { type: "other", description: "optional whitespace" }, peg$c12 = "|", peg$c13 = { type: "literal", value: "|", description: "\"|\"" }, peg$c14 = function(first, second) { return or(first, second); }, peg$c15 = "&", peg$c16 = { type: "literal", value: "&", description: "\"&\"" }, peg$c17 = function(first, second) { return and(first, second); }, peg$c18 = "!", peg$c19 = { type: "literal", value: "!", description: "\"!\"" }, peg$c20 = function(expr) { return not(expr); }, peg$c21 = "(", peg$c22 = { type: "literal", value: "(", description: "\"(\"" }, peg$c23 = ")", peg$c24 = { type: "literal", value: ")", description: "\")\"" }, peg$c25 = function(expr) { return binding(expr); }, peg$c26 = "~a", peg$c27 = { type: "literal", value: "~a", description: "\"~a\"" }, peg$c28 = function() { return assetFilter; }, peg$c29 = "~e", peg$c30 = { type: "literal", value: "~e", description: "\"~e\"" }, peg$c31 = function() { return errorFilter; }, peg$c32 = "~q", peg$c33 = { type: "literal", value: "~q", description: "\"~q\"" }, peg$c34 = function() { return noResponseFilter; }, peg$c35 = "~s", peg$c36 = { type: "literal", value: "~s", description: "\"~s\"" }, peg$c37 = function() { return responseFilter; }, peg$c38 = "true", peg$c39 = { type: "literal", value: "true", description: "\"true\"" }, peg$c40 = function() { return trueFilter; }, peg$c41 = "false", peg$c42 = { type: "literal", value: "false", description: "\"false\"" }, peg$c43 = function() { return falseFilter; }, peg$c44 = "~c", peg$c45 = { type: "literal", value: "~c", description: "\"~c\"" }, peg$c46 = function(s) { return responseCode(s); }, peg$c47 = "~d", peg$c48 = { type: "literal", value: "~d", description: "\"~d\"" }, peg$c49 = function(s) { return domain(s); }, peg$c50 = "~h", peg$c51 = { type: "literal", value: "~h", description: "\"~h\"" }, peg$c52 = function(s) { return header(s); }, peg$c53 = "~hq", peg$c54 = { type: "literal", value: "~hq", description: "\"~hq\"" }, peg$c55 = function(s) { return requestHeader(s); }, peg$c56 = "~hs", peg$c57 = { type: "literal", value: "~hs", description: "\"~hs\"" }, peg$c58 = function(s) { return responseHeader(s); }, peg$c59 = "~m", peg$c60 = { type: "literal", value: "~m", description: "\"~m\"" }, peg$c61 = function(s) { return method(s); }, peg$c62 = "~t", peg$c63 = { type: "literal", value: "~t", description: "\"~t\"" }, peg$c64 = function(s) { return contentType(s); }, peg$c65 = "~tq", peg$c66 = { type: "literal", value: "~tq", description: "\"~tq\"" }, peg$c67 = function(s) { return requestContentType(s); }, peg$c68 = "~ts", peg$c69 = { type: "literal", value: "~ts", description: "\"~ts\"" }, peg$c70 = function(s) { return responseContentType(s); }, peg$c71 = "~u", peg$c72 = { type: "literal", value: "~u", description: "\"~u\"" }, peg$c73 = function(s) { return url(s); }, peg$c74 = { type: "other", description: "integer" }, peg$c75 = null, peg$c76 = /^['"]/, peg$c77 = { type: "class", value: "['\"]", description: "['\"]" }, peg$c78 = /^[0-9]/, peg$c79 = { type: "class", value: "[0-9]", description: "[0-9]" }, peg$c80 = function(digits) { return parseInt(digits.join(""), 10); }, peg$c81 = { type: "other", description: "string" }, peg$c82 = "\"", peg$c83 = { type: "literal", value: "\"", description: "\"\\\"\"" }, peg$c84 = function(chars) { return chars.join(""); }, peg$c85 = "'", peg$c86 = { type: "literal", value: "'", description: "\"'\"" }, peg$c87 = void 0, peg$c88 = /^["\\]/, peg$c89 = { type: "class", value: "[\"\\\\]", description: "[\"\\\\]" }, peg$c90 = { type: "any", description: "any character" }, peg$c91 = function(char) { return char; }, peg$c92 = "\\", peg$c93 = { type: "literal", value: "\\", description: "\"\\\\\"" }, peg$c94 = /^['\\]/, peg$c95 = { type: "class", value: "['\\\\]", description: "['\\\\]" }, peg$c96 = /^['"\\]/, peg$c97 = { type: "class", value: "['\"\\\\]", description: "['\"\\\\]" }, peg$c98 = "n", peg$c99 = { type: "literal", value: "n", description: "\"n\"" }, peg$c100 = function() { return "\n"; }, peg$c101 = "r", peg$c102 = { type: "literal", value: "r", description: "\"r\"" }, peg$c103 = function() { return "\r"; }, peg$c104 = "t", peg$c105 = { type: "literal", value: "t", description: "\"t\"" }, peg$c106 = function() { return "\t"; }, peg$currPos = 0, peg$reportedPos = 0, peg$cachedPos = 0, peg$cachedPosDetails = { line: 1, column: 1, seenCR: false }, peg$maxFailPos = 0, peg$maxFailExpected = [], peg$silentFails = 0, peg$result; if ("startRule" in options) { if (!(options.startRule in peg$startRuleFunctions)) { throw new Error("Can't start parsing from rule \"" + options.startRule + "\"."); } peg$startRuleFunction = peg$startRuleFunctions[options.startRule]; } function text() { return input.substring(peg$reportedPos, peg$currPos); } function offset() { return peg$reportedPos; } function line() { return peg$computePosDetails(peg$reportedPos).line; } function column() { return peg$computePosDetails(peg$reportedPos).column; } function expected(description) { throw peg$buildException( null, [{ type: "other", description: description }], peg$reportedPos ); } function error(message) { throw peg$buildException(message, null, peg$reportedPos); } function peg$computePosDetails(pos) { function advance(details, startPos, endPos) { var p, ch; for (p = startPos; p < endPos; p++) { ch = input.charAt(p); if (ch === "\n") { if (!details.seenCR) { details.line++; } details.column = 1; details.seenCR = false; } else if (ch === "\r" || ch === "\u2028" || ch === "\u2029") { details.line++; details.column = 1; details.seenCR = true; } else { details.column++; details.seenCR = false; } } } if (peg$cachedPos !== pos) { if (peg$cachedPos > pos) { peg$cachedPos = 0; peg$cachedPosDetails = { line: 1, column: 1, seenCR: false }; } advance(peg$cachedPosDetails, peg$cachedPos, pos); peg$cachedPos = pos; } return peg$cachedPosDetails; } function peg$fail(expected) { if (peg$currPos < peg$maxFailPos) { return; } if (peg$currPos > peg$maxFailPos) { peg$maxFailPos = peg$currPos; peg$maxFailExpected = []; } peg$maxFailExpected.push(expected); } function peg$buildException(message, expected, pos) { function cleanupExpected(expected) { var i = 1; expected.sort(function(a, b) { if (a.description < b.description) { return -1; } else if (a.description > b.description) { return 1; } else { return 0; } }); while (i < expected.length) { if (expected[i - 1] === expected[i]) { expected.splice(i, 1); } else { i++; } } } function buildMessage(expected, found) { function stringEscape(s) { function hex(ch) { return ch.charCodeAt(0).toString(16).toUpperCase(); } return s .replace(/\\/g, '\\\\') .replace(/"/g, '\\"') .replace(/\x08/g, '\\b') .replace(/\t/g, '\\t') .replace(/\n/g, '\\n') .replace(/\f/g, '\\f') .replace(/\r/g, '\\r') .replace(/[\x00-\x07\x0B\x0E\x0F]/g, function(ch) { return '\\x0' + hex(ch); }) .replace(/[\x10-\x1F\x80-\xFF]/g, function(ch) { return '\\x' + hex(ch); }) .replace(/[\u0180-\u0FFF]/g, function(ch) { return '\\u0' + hex(ch); }) .replace(/[\u1080-\uFFFF]/g, function(ch) { return '\\u' + hex(ch); }); } var expectedDescs = new Array(expected.length), expectedDesc, foundDesc, i; for (i = 0; i < expected.length; i++) { expectedDescs[i] = expected[i].description; } expectedDesc = expected.length > 1 ? expectedDescs.slice(0, -1).join(", ") + " or " + expectedDescs[expected.length - 1] : expectedDescs[0]; foundDesc = found ? "\"" + stringEscape(found) + "\"" : "end of input"; return "Expected " + expectedDesc + " but " + foundDesc + " found."; } var posDetails = peg$computePosDetails(pos), found = pos < input.length ? input.charAt(pos) : null; if (expected !== null) { cleanupExpected(expected); } return new SyntaxError( message !== null ? message : buildMessage(expected, found), expected, found, pos, posDetails.line, posDetails.column ); } function peg$parsestart() { var s0, s1, s2, s3; peg$silentFails++; s0 = peg$currPos; s1 = peg$parse__(); if (s1 !== peg$FAILED) { s2 = peg$parseOrExpr(); if (s2 !== peg$FAILED) { s3 = peg$parse__(); if (s3 !== peg$FAILED) { peg$reportedPos = s0; s1 = peg$c2(s2); s0 = s1; } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } if (s0 === peg$FAILED) { s0 = peg$currPos; s1 = []; if (s1 !== peg$FAILED) { peg$reportedPos = s0; s1 = peg$c4(); } s0 = s1; } peg$silentFails--; if (s0 === peg$FAILED) { s1 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$c0); } } return s0; } function peg$parsews() { var s0, s1; peg$silentFails++; if (peg$c6.test(input.charAt(peg$currPos))) { s0 = input.charAt(peg$currPos); peg$currPos++; } else { s0 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$c7); } } peg$silentFails--; if (s0 === peg$FAILED) { s1 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$c5); } } return s0; } function peg$parsecc() { var s0, s1; peg$silentFails++; if (peg$c9.test(input.charAt(peg$currPos))) { s0 = input.charAt(peg$currPos); peg$currPos++; } else { s0 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$c10); } } peg$silentFails--; if (s0 === peg$FAILED) { s1 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$c8); } } return s0; } function peg$parse__() { var s0, s1; peg$silentFails++; s0 = []; s1 = peg$parsews(); while (s1 !== peg$FAILED) { s0.push(s1); s1 = peg$parsews(); } peg$silentFails--; if (s0 === peg$FAILED) { s1 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$c11); } } return s0; } function peg$parseOrExpr() { var s0, s1, s2, s3, s4, s5; s0 = peg$currPos; s1 = peg$parseAndExpr(); if (s1 !== peg$FAILED) { s2 = peg$parse__(); if (s2 !== peg$FAILED) { if (input.charCodeAt(peg$currPos) === 124) { s3 = peg$c12; peg$currPos++; } else { s3 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$c13); } } if (s3 !== peg$FAILED) { s4 = peg$parse__(); if (s4 !== peg$FAILED) { s5 = peg$parseOrExpr(); if (s5 !== peg$FAILED) { peg$reportedPos = s0; s1 = peg$c14(s1, s5); s0 = s1; } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } if (s0 === peg$FAILED) { s0 = peg$parseAndExpr(); } return s0; } function peg$parseAndExpr() { var s0, s1, s2, s3, s4, s5; s0 = peg$currPos; s1 = peg$parseNotExpr(); if (s1 !== peg$FAILED) { s2 = peg$parse__(); if (s2 !== peg$FAILED) { if (input.charCodeAt(peg$currPos) === 38) { s3 = peg$c15; peg$currPos++; } else { s3 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$c16); } } if (s3 !== peg$FAILED) { s4 = peg$parse__(); if (s4 !== peg$FAILED) { s5 = peg$parseAndExpr(); if (s5 !== peg$FAILED) { peg$reportedPos = s0; s1 = peg$c17(s1, s5); s0 = s1; } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } if (s0 === peg$FAILED) { s0 = peg$currPos; s1 = peg$parseNotExpr(); if (s1 !== peg$FAILED) { s2 = []; s3 = peg$parsews(); if (s3 !== peg$FAILED) { while (s3 !== peg$FAILED) { s2.push(s3); s3 = peg$parsews(); } } else { s2 = peg$c1; } if (s2 !== peg$FAILED) { s3 = peg$parseAndExpr(); if (s3 !== peg$FAILED) { peg$reportedPos = s0; s1 = peg$c17(s1, s3); s0 = s1; } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } if (s0 === peg$FAILED) { s0 = peg$parseNotExpr(); } } return s0; } function peg$parseNotExpr() { var s0, s1, s2, s3; s0 = peg$currPos; if (input.charCodeAt(peg$currPos) === 33) { s1 = peg$c18; peg$currPos++; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$c19); } } if (s1 !== peg$FAILED) { s2 = peg$parse__(); if (s2 !== peg$FAILED) { s3 = peg$parseNotExpr(); if (s3 !== peg$FAILED) { peg$reportedPos = s0; s1 = peg$c20(s3); s0 = s1; } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } if (s0 === peg$FAILED) { s0 = peg$parseBindingExpr(); } return s0; } function peg$parseBindingExpr() { var s0, s1, s2, s3, s4, s5; s0 = peg$currPos; if (input.charCodeAt(peg$currPos) === 40) { s1 = peg$c21; peg$currPos++; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$c22); } } if (s1 !== peg$FAILED) { s2 = peg$parse__(); if (s2 !== peg$FAILED) { s3 = peg$parseOrExpr(); if (s3 !== peg$FAILED) { s4 = peg$parse__(); if (s4 !== peg$FAILED) { if (input.charCodeAt(peg$currPos) === 41) { s5 = peg$c23; peg$currPos++; } else { s5 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$c24); } } if (s5 !== peg$FAILED) { peg$reportedPos = s0; s1 = peg$c25(s3); s0 = s1; } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } if (s0 === peg$FAILED) { s0 = peg$parseExpr(); } return s0; } function peg$parseExpr() { var s0; s0 = peg$parseNullaryExpr(); if (s0 === peg$FAILED) { s0 = peg$parseUnaryExpr(); } return s0; } function peg$parseNullaryExpr() { var s0, s1; s0 = peg$parseBooleanLiteral(); if (s0 === peg$FAILED) { s0 = peg$currPos; if (input.substr(peg$currPos, 2) === peg$c26) { s1 = peg$c26; peg$currPos += 2; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$c27); } } if (s1 !== peg$FAILED) { peg$reportedPos = s0; s1 = peg$c28(); } s0 = s1; if (s0 === peg$FAILED) { s0 = peg$currPos; if (input.substr(peg$currPos, 2) === peg$c29) { s1 = peg$c29; peg$currPos += 2; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$c30); } } if (s1 !== peg$FAILED) { peg$reportedPos = s0; s1 = peg$c31(); } s0 = s1; if (s0 === peg$FAILED) { s0 = peg$currPos; if (input.substr(peg$currPos, 2) === peg$c32) { s1 = peg$c32; peg$currPos += 2; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$c33); } } if (s1 !== peg$FAILED) { peg$reportedPos = s0; s1 = peg$c34(); } s0 = s1; if (s0 === peg$FAILED) { s0 = peg$currPos; if (input.substr(peg$currPos, 2) === peg$c35) { s1 = peg$c35; peg$currPos += 2; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$c36); } } if (s1 !== peg$FAILED) { peg$reportedPos = s0; s1 = peg$c37(); } s0 = s1; } } } } return s0; } function peg$parseBooleanLiteral() { var s0, s1; s0 = peg$currPos; if (input.substr(peg$currPos, 4) === peg$c38) { s1 = peg$c38; peg$currPos += 4; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$c39); } } if (s1 !== peg$FAILED) { peg$reportedPos = s0; s1 = peg$c40(); } s0 = s1; if (s0 === peg$FAILED) { s0 = peg$currPos; if (input.substr(peg$currPos, 5) === peg$c41) { s1 = peg$c41; peg$currPos += 5; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$c42); } } if (s1 !== peg$FAILED) { peg$reportedPos = s0; s1 = peg$c43(); } s0 = s1; } return s0; } function peg$parseUnaryExpr() { var s0, s1, s2, s3; s0 = peg$currPos; if (input.substr(peg$currPos, 2) === peg$c44) { s1 = peg$c44; peg$currPos += 2; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$c45); } } if (s1 !== peg$FAILED) { s2 = []; s3 = peg$parsews(); if (s3 !== peg$FAILED) { while (s3 !== peg$FAILED) { s2.push(s3); s3 = peg$parsews(); } } else { s2 = peg$c1; } if (s2 !== peg$FAILED) { s3 = peg$parseIntegerLiteral(); if (s3 !== peg$FAILED) { peg$reportedPos = s0; s1 = peg$c46(s3); s0 = s1; } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } if (s0 === peg$FAILED) { s0 = peg$currPos; if (input.substr(peg$currPos, 2) === peg$c47) { s1 = peg$c47; peg$currPos += 2; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$c48); } } if (s1 !== peg$FAILED) { s2 = []; s3 = peg$parsews(); if (s3 !== peg$FAILED) { while (s3 !== peg$FAILED) { s2.push(s3); s3 = peg$parsews(); } } else { s2 = peg$c1; } if (s2 !== peg$FAILED) { s3 = peg$parseStringLiteral(); if (s3 !== peg$FAILED) { peg$reportedPos = s0; s1 = peg$c49(s3); s0 = s1; } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } if (s0 === peg$FAILED) { s0 = peg$currPos; if (input.substr(peg$currPos, 2) === peg$c50) { s1 = peg$c50; peg$currPos += 2; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$c51); } } if (s1 !== peg$FAILED) { s2 = []; s3 = peg$parsews(); if (s3 !== peg$FAILED) { while (s3 !== peg$FAILED) { s2.push(s3); s3 = peg$parsews(); } } else { s2 = peg$c1; } if (s2 !== peg$FAILED) { s3 = peg$parseStringLiteral(); if (s3 !== peg$FAILED) { peg$reportedPos = s0; s1 = peg$c52(s3); s0 = s1; } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } if (s0 === peg$FAILED) { s0 = peg$currPos; if (input.substr(peg$currPos, 3) === peg$c53) { s1 = peg$c53; peg$currPos += 3; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$c54); } } if (s1 !== peg$FAILED) { s2 = []; s3 = peg$parsews(); if (s3 !== peg$FAILED) { while (s3 !== peg$FAILED) { s2.push(s3); s3 = peg$parsews(); } } else { s2 = peg$c1; } if (s2 !== peg$FAILED) { s3 = peg$parseStringLiteral(); if (s3 !== peg$FAILED) { peg$reportedPos = s0; s1 = peg$c55(s3); s0 = s1; } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } if (s0 === peg$FAILED) { s0 = peg$currPos; if (input.substr(peg$currPos, 3) === peg$c56) { s1 = peg$c56; peg$currPos += 3; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$c57); } } if (s1 !== peg$FAILED) { s2 = []; s3 = peg$parsews(); if (s3 !== peg$FAILED) { while (s3 !== peg$FAILED) { s2.push(s3); s3 = peg$parsews(); } } else { s2 = peg$c1; } if (s2 !== peg$FAILED) { s3 = peg$parseStringLiteral(); if (s3 !== peg$FAILED) { peg$reportedPos = s0; s1 = peg$c58(s3); s0 = s1; } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } if (s0 === peg$FAILED) { s0 = peg$currPos; if (input.substr(peg$currPos, 2) === peg$c59) { s1 = peg$c59; peg$currPos += 2; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$c60); } } if (s1 !== peg$FAILED) { s2 = []; s3 = peg$parsews(); if (s3 !== peg$FAILED) { while (s3 !== peg$FAILED) { s2.push(s3); s3 = peg$parsews(); } } else { s2 = peg$c1; } if (s2 !== peg$FAILED) { s3 = peg$parseStringLiteral(); if (s3 !== peg$FAILED) { peg$reportedPos = s0; s1 = peg$c61(s3); s0 = s1; } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } if (s0 === peg$FAILED) { s0 = peg$currPos; if (input.substr(peg$currPos, 2) === peg$c62) { s1 = peg$c62; peg$currPos += 2; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$c63); } } if (s1 !== peg$FAILED) { s2 = []; s3 = peg$parsews(); if (s3 !== peg$FAILED) { while (s3 !== peg$FAILED) { s2.push(s3); s3 = peg$parsews(); } } else { s2 = peg$c1; } if (s2 !== peg$FAILED) { s3 = peg$parseStringLiteral(); if (s3 !== peg$FAILED) { peg$reportedPos = s0; s1 = peg$c64(s3); s0 = s1; } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } if (s0 === peg$FAILED) { s0 = peg$currPos; if (input.substr(peg$currPos, 3) === peg$c65) { s1 = peg$c65; peg$currPos += 3; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$c66); } } if (s1 !== peg$FAILED) { s2 = []; s3 = peg$parsews(); if (s3 !== peg$FAILED) { while (s3 !== peg$FAILED) { s2.push(s3); s3 = peg$parsews(); } } else { s2 = peg$c1; } if (s2 !== peg$FAILED) { s3 = peg$parseStringLiteral(); if (s3 !== peg$FAILED) { peg$reportedPos = s0; s1 = peg$c67(s3); s0 = s1; } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } if (s0 === peg$FAILED) { s0 = peg$currPos; if (input.substr(peg$currPos, 3) === peg$c68) { s1 = peg$c68; peg$currPos += 3; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$c69); } } if (s1 !== peg$FAILED) { s2 = []; s3 = peg$parsews(); if (s3 !== peg$FAILED) { while (s3 !== peg$FAILED) { s2.push(s3); s3 = peg$parsews(); } } else { s2 = peg$c1; } if (s2 !== peg$FAILED) { s3 = peg$parseStringLiteral(); if (s3 !== peg$FAILED) { peg$reportedPos = s0; s1 = peg$c70(s3); s0 = s1; } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } if (s0 === peg$FAILED) { s0 = peg$currPos; if (input.substr(peg$currPos, 2) === peg$c71) { s1 = peg$c71; peg$currPos += 2; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$c72); } } if (s1 !== peg$FAILED) { s2 = []; s3 = peg$parsews(); if (s3 !== peg$FAILED) { while (s3 !== peg$FAILED) { s2.push(s3); s3 = peg$parsews(); } } else { s2 = peg$c1; } if (s2 !== peg$FAILED) { s3 = peg$parseStringLiteral(); if (s3 !== peg$FAILED) { peg$reportedPos = s0; s1 = peg$c73(s3); s0 = s1; } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } if (s0 === peg$FAILED) { s0 = peg$currPos; s1 = peg$parseStringLiteral(); if (s1 !== peg$FAILED) { peg$reportedPos = s0; s1 = peg$c73(s1); } s0 = s1; } } } } } } } } } } return s0; } function peg$parseIntegerLiteral() { var s0, s1, s2, s3; peg$silentFails++; s0 = peg$currPos; if (peg$c76.test(input.charAt(peg$currPos))) { s1 = input.charAt(peg$currPos); peg$currPos++; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$c77); } } if (s1 === peg$FAILED) { s1 = peg$c75; } if (s1 !== peg$FAILED) { s2 = []; if (peg$c78.test(input.charAt(peg$currPos))) { s3 = input.charAt(peg$currPos); peg$currPos++; } else { s3 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$c79); } } if (s3 !== peg$FAILED) { while (s3 !== peg$FAILED) { s2.push(s3); if (peg$c78.test(input.charAt(peg$currPos))) { s3 = input.charAt(peg$currPos); peg$currPos++; } else { s3 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$c79); } } } } else { s2 = peg$c1; } if (s2 !== peg$FAILED) { if (peg$c76.test(input.charAt(peg$currPos))) { s3 = input.charAt(peg$currPos); peg$currPos++; } else { s3 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$c77); } } if (s3 === peg$FAILED) { s3 = peg$c75; } if (s3 !== peg$FAILED) { peg$reportedPos = s0; s1 = peg$c80(s2); s0 = s1; } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } peg$silentFails--; if (s0 === peg$FAILED) { s1 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$c74); } } return s0; } function peg$parseStringLiteral() { var s0, s1, s2, s3; peg$silentFails++; s0 = peg$currPos; if (input.charCodeAt(peg$currPos) === 34) { s1 = peg$c82; peg$currPos++; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$c83); } } if (s1 !== peg$FAILED) { s2 = []; s3 = peg$parseDoubleStringChar(); while (s3 !== peg$FAILED) { s2.push(s3); s3 = peg$parseDoubleStringChar(); } if (s2 !== peg$FAILED) { if (input.charCodeAt(peg$currPos) === 34) { s3 = peg$c82; peg$currPos++; } else { s3 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$c83); } } if (s3 !== peg$FAILED) { peg$reportedPos = s0; s1 = peg$c84(s2); s0 = s1; } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } if (s0 === peg$FAILED) { s0 = peg$currPos; if (input.charCodeAt(peg$currPos) === 39) { s1 = peg$c85; peg$currPos++; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$c86); } } if (s1 !== peg$FAILED) { s2 = []; s3 = peg$parseSingleStringChar(); while (s3 !== peg$FAILED) { s2.push(s3); s3 = peg$parseSingleStringChar(); } if (s2 !== peg$FAILED) { if (input.charCodeAt(peg$currPos) === 39) { s3 = peg$c85; peg$currPos++; } else { s3 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$c86); } } if (s3 !== peg$FAILED) { peg$reportedPos = s0; s1 = peg$c84(s2); s0 = s1; } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } if (s0 === peg$FAILED) { s0 = peg$currPos; s1 = peg$currPos; peg$silentFails++; s2 = peg$parsecc(); peg$silentFails--; if (s2 === peg$FAILED) { s1 = peg$c87; } else { peg$currPos = s1; s1 = peg$c1; } if (s1 !== peg$FAILED) { s2 = []; s3 = peg$parseUnquotedStringChar(); if (s3 !== peg$FAILED) { while (s3 !== peg$FAILED) { s2.push(s3); s3 = peg$parseUnquotedStringChar(); } } else { s2 = peg$c1; } if (s2 !== peg$FAILED) { peg$reportedPos = s0; s1 = peg$c84(s2); s0 = s1; } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } } } peg$silentFails--; if (s0 === peg$FAILED) { s1 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$c81); } } return s0; } function peg$parseDoubleStringChar() { var s0, s1, s2; s0 = peg$currPos; s1 = peg$currPos; peg$silentFails++; if (peg$c88.test(input.charAt(peg$currPos))) { s2 = input.charAt(peg$currPos); peg$currPos++; } else { s2 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$c89); } } peg$silentFails--; if (s2 === peg$FAILED) { s1 = peg$c87; } else { peg$currPos = s1; s1 = peg$c1; } if (s1 !== peg$FAILED) { if (input.length > peg$currPos) { s2 = input.charAt(peg$currPos); peg$currPos++; } else { s2 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$c90); } } if (s2 !== peg$FAILED) { peg$reportedPos = s0; s1 = peg$c91(s2); s0 = s1; } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } if (s0 === peg$FAILED) { s0 = peg$currPos; if (input.charCodeAt(peg$currPos) === 92) { s1 = peg$c92; peg$currPos++; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$c93); } } if (s1 !== peg$FAILED) { s2 = peg$parseEscapeSequence(); if (s2 !== peg$FAILED) { peg$reportedPos = s0; s1 = peg$c91(s2); s0 = s1; } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } } return s0; } function peg$parseSingleStringChar() { var s0, s1, s2; s0 = peg$currPos; s1 = peg$currPos; peg$silentFails++; if (peg$c94.test(input.charAt(peg$currPos))) { s2 = input.charAt(peg$currPos); peg$currPos++; } else { s2 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$c95); } } peg$silentFails--; if (s2 === peg$FAILED) { s1 = peg$c87; } else { peg$currPos = s1; s1 = peg$c1; } if (s1 !== peg$FAILED) { if (input.length > peg$currPos) { s2 = input.charAt(peg$currPos); peg$currPos++; } else { s2 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$c90); } } if (s2 !== peg$FAILED) { peg$reportedPos = s0; s1 = peg$c91(s2); s0 = s1; } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } if (s0 === peg$FAILED) { s0 = peg$currPos; if (input.charCodeAt(peg$currPos) === 92) { s1 = peg$c92; peg$currPos++; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$c93); } } if (s1 !== peg$FAILED) { s2 = peg$parseEscapeSequence(); if (s2 !== peg$FAILED) { peg$reportedPos = s0; s1 = peg$c91(s2); s0 = s1; } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } } return s0; } function peg$parseUnquotedStringChar() { var s0, s1, s2; s0 = peg$currPos; s1 = peg$currPos; peg$silentFails++; s2 = peg$parsews(); peg$silentFails--; if (s2 === peg$FAILED) { s1 = peg$c87; } else { peg$currPos = s1; s1 = peg$c1; } if (s1 !== peg$FAILED) { if (input.length > peg$currPos) { s2 = input.charAt(peg$currPos); peg$currPos++; } else { s2 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$c90); } } if (s2 !== peg$FAILED) { peg$reportedPos = s0; s1 = peg$c91(s2); s0 = s1; } else { peg$currPos = s0; s0 = peg$c1; } } else { peg$currPos = s0; s0 = peg$c1; } return s0; } function peg$parseEscapeSequence() { var s0, s1; if (peg$c96.test(input.charAt(peg$currPos))) { s0 = input.charAt(peg$currPos); peg$currPos++; } else { s0 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$c97); } } if (s0 === peg$FAILED) { s0 = peg$currPos; if (input.charCodeAt(peg$currPos) === 110) { s1 = peg$c98; peg$currPos++; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$c99); } } if (s1 !== peg$FAILED) { peg$reportedPos = s0; s1 = peg$c100(); } s0 = s1; if (s0 === peg$FAILED) { s0 = peg$currPos; if (input.charCodeAt(peg$currPos) === 114) { s1 = peg$c101; peg$currPos++; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$c102); } } if (s1 !== peg$FAILED) { peg$reportedPos = s0; s1 = peg$c103(); } s0 = s1; if (s0 === peg$FAILED) { s0 = peg$currPos; if (input.charCodeAt(peg$currPos) === 116) { s1 = peg$c104; peg$currPos++; } else { s1 = peg$FAILED; if (peg$silentFails === 0) { peg$fail(peg$c105); } } if (s1 !== peg$FAILED) { peg$reportedPos = s0; s1 = peg$c106(); } s0 = s1; } } } return s0; } function or(first, second) { // Add explicit function names to ease debugging. function orFilter() { return first.apply(this, arguments) || second.apply(this, arguments); } orFilter.desc = first.desc + " or " + second.desc; return orFilter; } function and(first, second) { function andFilter() { return first.apply(this, arguments) && second.apply(this, arguments); } andFilter.desc = first.desc + " and " + second.desc; return andFilter; } function not(expr) { function notFilter() { return !expr.apply(this, arguments); } notFilter.desc = "not " + expr.desc; return notFilter; } function binding(expr) { function bindingFilter() { return expr.apply(this, arguments); } bindingFilter.desc = "(" + expr.desc + ")"; return bindingFilter; } function trueFilter(flow) { return true; } trueFilter.desc = "true"; function falseFilter(flow) { return false; } falseFilter.desc = "false"; var ASSET_TYPES = [ new RegExp("text/javascript"), new RegExp("application/x-javascript"), new RegExp("application/javascript"), new RegExp("text/css"), new RegExp("image/.*"), new RegExp("application/x-shockwave-flash") ]; function assetFilter(flow) { if (flow.response) { var ct = ResponseUtils.getContentType(flow.response); var i = ASSET_TYPES.length; while (i--) { if (ASSET_TYPES[i].test(ct)) { return true; } } } return false; } assetFilter.desc = "is asset"; function responseCode(code){ function responseCodeFilter(flow){ return flow.response && flow.response.code === code; } responseCodeFilter.desc = "resp. code is " + code; return responseCodeFilter; } function domain(regex){ regex = new RegExp(regex, "i"); function domainFilter(flow){ return flow.request && regex.test(flow.request.host); } domainFilter.desc = "domain matches " + regex; return domainFilter; } function errorFilter(flow){ return !!flow.error; } errorFilter.desc = "has error"; function header(regex){ regex = new RegExp(regex, "i"); function headerFilter(flow){ return ( (flow.request && RequestUtils.match_header(flow.request, regex)) || (flow.response && ResponseUtils.match_header(flow.response, regex)) ); } headerFilter.desc = "header matches " + regex; return headerFilter; } function requestHeader(regex){ regex = new RegExp(regex, "i"); function requestHeaderFilter(flow){ return (flow.request && RequestUtils.match_header(flow.request, regex)); } requestHeaderFilter.desc = "req. header matches " + regex; return requestHeaderFilter; } function responseHeader(regex){ regex = new RegExp(regex, "i"); function responseHeaderFilter(flow){ return (flow.response && ResponseUtils.match_header(flow.response, regex)); } responseHeaderFilter.desc = "resp. header matches " + regex; return responseHeaderFilter; } function method(regex){ regex = new RegExp(regex, "i"); function methodFilter(flow){ return flow.request && regex.test(flow.request.method); } methodFilter.desc = "method matches " + regex; return methodFilter; } function noResponseFilter(flow){ return flow.request && !flow.response; } noResponseFilter.desc = "has no response"; function responseFilter(flow){ return !!flow.response; } responseFilter.desc = "has response"; function contentType(regex){ regex = new RegExp(regex, "i"); function contentTypeFilter(flow){ return ( (flow.request && regex.test(RequestUtils.getContentType(flow.request))) || (flow.response && regex.test(ResponseUtils.getContentType(flow.response))) ); } contentTypeFilter.desc = "content type matches " + regex; return contentTypeFilter; } function requestContentType(regex){ regex = new RegExp(regex, "i"); function requestContentTypeFilter(flow){ return flow.request && regex.test(RequestUtils.getContentType(flow.request)); } requestContentTypeFilter.desc = "req. content type matches " + regex; return requestContentTypeFilter; } function responseContentType(regex){ regex = new RegExp(regex, "i"); function responseContentTypeFilter(flow){ return flow.response && regex.test(ResponseUtils.getContentType(flow.response)); } responseContentTypeFilter.desc = "resp. content type matches " + regex; return responseContentTypeFilter; } function url(regex){ regex = new RegExp(regex, "i"); function urlFilter(flow){ return flow.request && regex.test(RequestUtils.pretty_url(flow.request)); } urlFilter.desc = "url matches " + regex; return urlFilter; } peg$result = peg$startRuleFunction(); if (peg$result !== peg$FAILED && peg$currPos === input.length) { return peg$result; } else { if (peg$result !== peg$FAILED && peg$currPos < input.length) { peg$fail({ type: "end", description: "end of input" }); } throw peg$buildException(null, peg$maxFailExpected, peg$maxFailPos); } } return { SyntaxError: SyntaxError, parse: parse }; })(); /* jshint ignore:end */ module.exports = Filt; },{}],16:[function(require,module,exports){ var _ = require("lodash"); var _MessageUtils = { getContentType: function (message) { return this.get_first_header(message, /^Content-Type$/i); }, get_first_header: function (message, regex) { //FIXME: Cache Invalidation. if (!message._headerLookups) Object.defineProperty(message, "_headerLookups", { value: {}, configurable: false, enumerable: false, writable: false }); if (!(regex in message._headerLookups)) { var header; for (var i = 0; i < message.headers.length; i++) { if (!!message.headers[i][0].match(regex)) { header = message.headers[i]; break; } } message._headerLookups[regex] = header ? header[1] : undefined; } return message._headerLookups[regex]; }, match_header: function (message, regex) { var headers = message.headers; var i = headers.length; while (i--) { if (regex.test(headers[i].join(" "))) { return headers[i]; } } return false; } }; var defaultPorts = { "http": 80, "https": 443 }; var RequestUtils = _.extend(_MessageUtils, { pretty_host: function (request) { //FIXME: Add hostheader return request.host; }, pretty_url: function (request) { var port = ""; if (defaultPorts[request.scheme] !== request.port) { port = ":" + request.port; } return request.scheme + "://" + this.pretty_host(request) + port + request.path; } }); var ResponseUtils = _.extend(_MessageUtils, {}); module.exports = { ResponseUtils: ResponseUtils, RequestUtils: RequestUtils } },{"lodash":"lodash"}],17:[function(require,module,exports){ var _ = require("lodash"); var $ = require("jquery"); var utils = require("../utils.js"); var actions = require("../actions.js"); var dispatcher = require("../dispatcher.js"); function ListStore() { utils.EventEmitter.call(this); this.reset(); } _.extend(ListStore.prototype, utils.EventEmitter.prototype, { add: function (elem) { if (elem.id in this._pos_map) { return; } this._pos_map[elem.id] = this.list.length; this.list.push(elem); this.emit("add", elem); }, update: function (elem) { if (!(elem.id in this._pos_map)) { return; } this.list[this._pos_map[elem.id]] = elem; this.emit("update", elem); }, remove: function (elem_id) { if (!(elem_id in this._pos_map)) { return; } this.list.splice(this._pos_map[elem_id], 1); this._build_map(); this.emit("remove", elem_id); }, reset: function (elems) { this.list = elems || []; this._build_map(); this.emit("recalculate"); }, _build_map: function () { this._pos_map = {}; for (var i = 0; i < this.list.length; i++) { var elem = this.list[i]; this._pos_map[elem.id] = i; } }, get: function (elem_id) { return this.list[this._pos_map[elem_id]]; }, index: function (elem_id) { return this._pos_map[elem_id]; } }); function DictStore() { utils.EventEmitter.call(this); this.reset(); } _.extend(DictStore.prototype, utils.EventEmitter.prototype, { update: function (dict) { _.merge(this.dict, dict); this.emit("recalculate"); }, reset: function (dict) { this.dict = dict || {}; this.emit("recalculate"); } }); function LiveStoreMixin(type) { this.type = type; this._updates_before_fetch = undefined; this._fetchxhr = false; this.handle = this.handle.bind(this); dispatcher.AppDispatcher.register(this.handle); // Avoid double-fetch on startup. if (!(window.ws && window.ws.readyState === WebSocket.CONNECTING)) { this.fetch(); } } _.extend(LiveStoreMixin.prototype, { handle: function (event) { if (event.type === actions.ActionTypes.CONNECTION_OPEN) { return this.fetch(); } if (event.type === this.type) { if (event.cmd === actions.StoreCmds.RESET) { this.fetch(event.data); } else if (this._updates_before_fetch) { console.log("defer update", event); this._updates_before_fetch.push(event); } else { this[event.cmd](event.data); } } }, close: function () { dispatcher.AppDispatcher.unregister(this.handle); }, fetch: function (data) { console.log("fetch " + this.type); if (this._fetchxhr) { this._fetchxhr.abort(); } this._updates_before_fetch = []; // (JS: empty array is true) if (data) { this.handle_fetch(data); } else { this._fetchxhr = $.getJSON("/" + this.type) .done(function (message) { this.handle_fetch(message.data); }.bind(this)) .fail(function () { EventLogActions.add_event("Could not fetch " + this.type); }.bind(this)); } }, handle_fetch: function (data) { this._fetchxhr = false; console.log(this.type + " fetched.", this._updates_before_fetch); this.reset(data); var updates = this._updates_before_fetch; this._updates_before_fetch = false; for (var i = 0; i < updates.length; i++) { this.handle(updates[i]); } }, }); function LiveListStore(type) { ListStore.call(this); LiveStoreMixin.call(this, type); } _.extend(LiveListStore.prototype, ListStore.prototype, LiveStoreMixin.prototype); function LiveDictStore(type) { DictStore.call(this); LiveStoreMixin.call(this, type); } _.extend(LiveDictStore.prototype, DictStore.prototype, LiveStoreMixin.prototype); function FlowStore() { return new LiveListStore(actions.ActionTypes.FLOW_STORE); } function SettingsStore() { return new LiveDictStore(actions.ActionTypes.SETTINGS_STORE); } function EventLogStore() { LiveListStore.call(this, actions.ActionTypes.EVENT_STORE); } _.extend(EventLogStore.prototype, LiveListStore.prototype, { fetch: function(){ LiveListStore.prototype.fetch.apply(this, arguments); // Make sure to display updates even if fetching all events failed. // This way, we can send "fetch failed" log messages to the log. if(this._fetchxhr){ this._fetchxhr.fail(function(){ this.handle_fetch(null); }.bind(this)); } } }); module.exports = { EventLogStore: EventLogStore, SettingsStore: SettingsStore, FlowStore: FlowStore }; },{"../actions.js":1,"../dispatcher.js":14,"../utils.js":19,"jquery":"jquery","lodash":"lodash"}],18:[function(require,module,exports){ var _ = require("lodash"); var utils = require("../utils.js"); function SortByStoreOrder(elem) { return this.store.index(elem.id); } var default_sort = SortByStoreOrder; var default_filt = function(elem){ return true; }; function StoreView(store, filt, sortfun) { utils.EventEmitter.call(this); filt = filt || default_filt; sortfun = sortfun || default_sort; this.store = store; this.add = this.add.bind(this); this.update = this.update.bind(this); this.remove = this.remove.bind(this); this.recalculate = this.recalculate.bind(this); this.store.addListener("add", this.add); this.store.addListener("update", this.update); this.store.addListener("remove", this.remove); this.store.addListener("recalculate", this.recalculate); this.recalculate(filt, sortfun); } _.extend(StoreView.prototype, utils.EventEmitter.prototype, { close: function () { this.store.removeListener("add", this.add); this.store.removeListener("update", this.update); this.store.removeListener("remove", this.remove); this.store.removeListener("recalculate", this.recalculate); }, recalculate: function (filt, sortfun) { if (filt) { this.filt = filt.bind(this); } if (sortfun) { this.sortfun = sortfun.bind(this); } this.list = this.store.list.filter(this.filt); this.list.sort(function (a, b) { return this.sortfun(a) - this.sortfun(b); }.bind(this)); this.emit("recalculate"); }, index: function (elem) { return _.sortedIndex(this.list, elem, this.sortfun); }, add: function (elem) { if (this.filt(elem)) { var idx = this.index(elem); if (idx === this.list.length) { //happens often, .push is way faster. this.list.push(elem); } else { this.list.splice(idx, 0, elem); } this.emit("add", elem, idx); } }, update: function (elem) { var idx; var i = this.list.length; // Search from the back, we usually update the latest entries. while (i--) { if (this.list[i].id === elem.id) { idx = i; break; } } if (idx === -1) { //not contained in list this.add(elem); } else if (!this.filt(elem)) { this.remove(elem.id); } else { if (this.sortfun(this.list[idx]) !== this.sortfun(elem)) { //sortpos has changed this.remove(this.list[idx]); this.add(elem); } else { this.list[idx] = elem; this.emit("update", elem, idx); } } }, remove: function (elem_id) { var idx = this.list.length; while (idx--) { if (this.list[idx].id === elem_id) { this.list.splice(idx, 1); this.emit("remove", elem_id, idx); break; } } } }); module.exports = { StoreView: StoreView }; },{"../utils.js":19,"lodash":"lodash"}],19:[function(require,module,exports){ var $ = require("jquery"); var Key = { UP: 38, DOWN: 40, PAGE_UP: 33, PAGE_DOWN: 34, HOME: 36, END: 35, LEFT: 37, RIGHT: 39, ENTER: 13, ESC: 27, TAB: 9, SPACE: 32, BACKSPACE: 8, }; // Add A-Z for (var i = 65; i <= 90; i++) { Key[String.fromCharCode(i)] = i; } var formatSize = function (bytes) { var size = bytes; var prefix = ["B", "KB", "MB", "GB", "TB"]; var i = 0; while (Math.abs(size) >= 1024 && i < prefix.length - 1) { i++; size = size / 1024; } return (Math.floor(size * 100) / 100.0).toFixed(2) + prefix[i]; }; var formatTimeDelta = function (milliseconds) { var time = milliseconds; var prefix = ["ms", "s", "min", "h"]; var div = [1000, 60, 60]; var i = 0; while (Math.abs(time) >= div[i] && i < div.length) { time = time / div[i]; i++; } return Math.round(time) + prefix[i]; }; var formatTimeStamp = function (seconds) { var ts = (new Date(seconds * 1000)).toISOString(); return ts.replace("T", " ").replace("Z", ""); }; function EventEmitter() { this.listeners = {}; } EventEmitter.prototype.emit = function (event) { if (!(event in this.listeners)) { return; } var args = Array.prototype.slice.call(arguments, 1); this.listeners[event].forEach(function (listener) { listener.apply(this, args); }.bind(this)); }; EventEmitter.prototype.addListener = function (events, f) { events.split(" ").forEach(function (event) { this.listeners[event] = this.listeners[event] || []; this.listeners[event].push(f); }.bind(this)); }; EventEmitter.prototype.removeListener = function (events, f) { if (!(events in this.listeners)) { return false; } events.split(" ").forEach(function (event) { var index = this.listeners[event].indexOf(f); if (index >= 0) { this.listeners[event].splice(index, 1); } }.bind(this)); }; function getCookie(name) { var r = document.cookie.match("\\b" + name + "=([^;]*)\\b"); return r ? r[1] : undefined; } var xsrf = $.param({_xsrf: getCookie("_xsrf")}); //Tornado XSRF Protection. $.ajaxPrefilter(function (options) { if (["post", "put", "delete"].indexOf(options.type.toLowerCase()) >= 0 && options.url[0] === "/") { if (options.data) { options.data += ("&" + xsrf); } else { options.data = xsrf; } } }); // Log AJAX Errors $(document).ajaxError(function (event, jqXHR, ajaxSettings, thrownError) { var message = jqXHR.responseText; console.error(message, arguments); EventLogActions.add_event(thrownError + ": " + message); window.alert(message); }); module.exports = { EventEmitter: EventEmitter, formatSize: formatSize, formatTimeDelta: formatTimeDelta, formatTimeStamp: formatTimeStamp, Key: Key }; },{"jquery":"jquery"}]},{},[2]) //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJzcmMvanMvYWN0aW9ucy5qcyIsInNyYy9qcy9hcHAuanMiLCJzcmMvanMvY29tcG9uZW50cy9ldmVudGxvZy5qcyIsInNyYy9qcy9jb21wb25lbnRzL2Zsb3dkZXRhaWwuanMiLCJzcmMvanMvY29tcG9uZW50cy9mbG93dGFibGUtY29sdW1ucy5qcyIsInNyYy9qcy9jb21wb25lbnRzL2Zsb3d0YWJsZS5qcyIsInNyYy9qcy9jb21wb25lbnRzL2Zvb3Rlci5qcyIsInNyYy9qcy9jb21wb25lbnRzL2hlYWRlci5qcyIsInNyYy9qcy9jb21wb25lbnRzL21haW52aWV3LmpzIiwic3JjL2pzL2NvbXBvbmVudHMvcHJveHlhcHAuanMiLCJzcmMvanMvY29tcG9uZW50cy91dGlscy5qcyIsInNyYy9qcy9jb21wb25lbnRzL3ZpcnR1YWxzY3JvbGwuanMiLCJzcmMvanMvY29ubmVjdGlvbi5qcyIsInNyYy9qcy9kaXNwYXRjaGVyLmpzIiwic3JjL2pzL2ZpbHQvZmlsdC5qcyIsInNyYy9qcy9mbG93L3V0aWxzLmpzIiwic3JjL2pzL3N0b3JlL3N0b3JlLmpzIiwic3JjL2pzL3N0b3JlL3ZpZXcuanMiLCJzcmMvanMvdXRpbHMuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlZQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeElBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcFlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeE9BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbk1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNodkRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25MQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyBmLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pIiwidmFyICQgPSByZXF1aXJlKFwianF1ZXJ5XCIpO1xuXG52YXIgQWN0aW9uVHlwZXMgPSB7XG4gICAgLy8gQ29ubmVjdGlvblxuICAgIENPTk5FQ1RJT05fT1BFTjogXCJjb25uZWN0aW9uX29wZW5cIixcbiAgICBDT05ORUNUSU9OX0NMT1NFOiBcImNvbm5lY3Rpb25fY2xvc2VcIixcbiAgICBDT05ORUNUSU9OX0VSUk9SOiBcImNvbm5lY3Rpb25fZXJyb3JcIixcblxuICAgIC8vIFN0b3Jlc1xuICAgIFNFVFRJTkdTX1NUT1JFOiBcInNldHRpbmdzXCIsXG4gICAgRVZFTlRfU1RPUkU6IFwiZXZlbnRzXCIsXG4gICAgRkxPV19TVE9SRTogXCJmbG93c1wiLFxufTtcblxudmFyIFN0b3JlQ21kcyA9IHtcbiAgICBBREQ6IFwiYWRkXCIsXG4gICAgVVBEQVRFOiBcInVwZGF0ZVwiLFxuICAgIFJFTU9WRTogXCJyZW1vdmVcIixcbiAgICBSRVNFVDogXCJyZXNldFwiXG59O1xuXG52YXIgQ29ubmVjdGlvbkFjdGlvbnMgPSB7XG4gICAgb3BlbjogZnVuY3Rpb24gKCkge1xuICAgICAgICBBcHBEaXNwYXRjaGVyLmRpc3BhdGNoVmlld0FjdGlvbih7XG4gICAgICAgICAgICB0eXBlOiBBY3Rpb25UeXBlcy5DT05ORUNUSU9OX09QRU5cbiAgICAgICAgfSk7XG4gICAgfSxcbiAgICBjbG9zZTogZnVuY3Rpb24gKCkge1xuICAgICAgICBBcHBEaXNwYXRjaGVyLmRpc3BhdGNoVmlld0FjdGlvbih7XG4gICAgICAgICAgICB0eXBlOiBBY3Rpb25UeXBlcy5DT05ORUNUSU9OX0NMT1NFXG4gICAgICAgIH0pO1xuICAgIH0sXG4gICAgZXJyb3I6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgQXBwRGlzcGF0Y2hlci5kaXNwYXRjaFZpZXdBY3Rpb24oe1xuICAgICAgICAgICAgdHlwZTogQWN0aW9uVHlwZXMuQ09OTkVDVElPTl9FUlJPUlxuICAgICAgICB9KTtcbiAgICB9XG59O1xuXG52YXIgU2V0dGluZ3NBY3Rpb25zID0ge1xuICAgIHVwZGF0ZTogZnVuY3Rpb24gKHNldHRpbmdzKSB7XG5cbiAgICAgICAgJC5hamF4KHtcbiAgICAgICAgICAgIHR5cGU6IFwiUFVUXCIsXG4gICAgICAgICAgICB1cmw6IFwiL3NldHRpbmdzXCIsXG4gICAgICAgICAgICBkYXRhOiBzZXR0aW5nc1xuICAgICAgICB9KTtcblxuICAgICAgICAvKlxuICAgICAgICAvL0ZhY2Vib29rIEZsdXg6IFdlIGRvIGFuIG9wdGltaXN0aWMgdXBkYXRlIG9uIHRoZSBjbGllbnQgYWxyZWFkeS5cbiAgICAgICAgQXBwRGlzcGF0Y2hlci5kaXNwYXRjaFZpZXdBY3Rpb24oe1xuICAgICAgICAgICAgdHlwZTogQWN0aW9uVHlwZXMuU0VUVElOR1NfU1RPUkUsXG4gICAgICAgICAgICBjbWQ6IFN0b3JlQ21kcy5VUERBVEUsXG4gICAgICAgICAgICBkYXRhOiBzZXR0aW5nc1xuICAgICAgICB9KTtcbiAgICAgICAgKi9cbiAgICB9XG59O1xuXG52YXIgRXZlbnRMb2dBY3Rpb25zX2V2ZW50X2lkID0gMDtcbnZhciBFdmVudExvZ0FjdGlvbnMgPSB7XG4gICAgYWRkX2V2ZW50OiBmdW5jdGlvbiAobWVzc2FnZSkge1xuICAgICAgICBBcHBEaXNwYXRjaGVyLmRpc3BhdGNoVmlld0FjdGlvbih7XG4gICAgICAgICAgICB0eXBlOiBBY3Rpb25UeXBlcy5FVkVOVF9TVE9SRSxcbiAgICAgICAgICAgIGNtZDogU3RvcmVDbWRzLkFERCxcbiAgICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICAgICAgICAgICAgICAgIGxldmVsOiBcIndlYlwiLFxuICAgICAgICAgICAgICAgIGlkOiBcInZpZXdBY3Rpb24tXCIgKyBFdmVudExvZ0FjdGlvbnNfZXZlbnRfaWQrK1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG59O1xuXG52YXIgRmxvd0FjdGlvbnMgPSB7XG4gICAgYWNjZXB0OiBmdW5jdGlvbiAoZmxvdykge1xuICAgICAgICAkLnBvc3QoXCIvZmxvd3MvXCIgKyBmbG93LmlkICsgXCIvYWNjZXB0XCIpO1xuICAgIH0sXG4gICAgYWNjZXB0X2FsbDogZnVuY3Rpb24oKXtcbiAgICAgICAgJC5wb3N0KFwiL2Zsb3dzL2FjY2VwdFwiKTtcbiAgICB9LFxuICAgIFwiZGVsZXRlXCI6IGZ1bmN0aW9uKGZsb3cpe1xuICAgICAgICAkLmFqYXgoe1xuICAgICAgICAgICAgdHlwZTpcIkRFTEVURVwiLFxuICAgICAgICAgICAgdXJsOiBcIi9mbG93cy9cIiArIGZsb3cuaWRcbiAgICAgICAgfSk7XG4gICAgfSxcbiAgICBkdXBsaWNhdGU6IGZ1bmN0aW9uKGZsb3cpe1xuICAgICAgICAkLnBvc3QoXCIvZmxvd3MvXCIgKyBmbG93LmlkICsgXCIvZHVwbGljYXRlXCIpO1xuICAgIH0sXG4gICAgcmVwbGF5OiBmdW5jdGlvbihmbG93KXtcbiAgICAgICAgJC5wb3N0KFwiL2Zsb3dzL1wiICsgZmxvdy5pZCArIFwiL3JlcGxheVwiKTtcbiAgICB9LFxuICAgIHJldmVydDogZnVuY3Rpb24oZmxvdyl7XG4gICAgICAgICQucG9zdChcIi9mbG93cy9cIiArIGZsb3cuaWQgKyBcIi9yZXZlcnRcIik7XG4gICAgfSxcbiAgICB1cGRhdGU6IGZ1bmN0aW9uIChmbG93KSB7XG4gICAgICAgIEFwcERpc3BhdGNoZXIuZGlzcGF0Y2hWaWV3QWN0aW9uKHtcbiAgICAgICAgICAgIHR5cGU6IEFjdGlvblR5cGVzLkZMT1dfU1RPUkUsXG4gICAgICAgICAgICBjbWQ6IFN0b3JlQ21kcy5VUERBVEUsXG4gICAgICAgICAgICBkYXRhOiBmbG93XG4gICAgICAgIH0pO1xuICAgIH0sXG4gICAgY2xlYXI6IGZ1bmN0aW9uKCl7XG4gICAgICAgICQucG9zdChcIi9jbGVhclwiKTtcbiAgICB9XG59O1xuXG5RdWVyeSA9IHtcbiAgICBGSUxURVI6IFwiZlwiLFxuICAgIEhJR0hMSUdIVDogXCJoXCIsXG4gICAgU0hPV19FVkVOVExPRzogXCJlXCJcbn07XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICAgIEFjdGlvblR5cGVzOiBBY3Rpb25UeXBlcyxcbiAgICBDb25uZWN0aW9uQWN0aW9uczogQ29ubmVjdGlvbkFjdGlvbnMsXG4gICAgRmxvd0FjdGlvbnM6IEZsb3dBY3Rpb25zLFxuICAgIFN0b3JlQ21kczogU3RvcmVDbWRzXG5cblxufTsiLCJcbnZhciBSZWFjdCA9IHJlcXVpcmUoXCJyZWFjdFwiKTtcbnZhciBSZWFjdFJvdXRlciA9IHJlcXVpcmUoXCJyZWFjdC1yb3V0ZXJcIik7XG52YXIgJCA9IHJlcXVpcmUoXCJqcXVlcnlcIik7XG5cbnZhciBDb25uZWN0aW9uID0gcmVxdWlyZShcIi4vY29ubmVjdGlvblwiKTtcbnZhciBwcm94eWFwcCA9IHJlcXVpcmUoXCIuL2NvbXBvbmVudHMvcHJveHlhcHAuanNcIik7XG5cbiQoZnVuY3Rpb24gKCkge1xuICAgIHdpbmRvdy53cyA9IG5ldyBDb25uZWN0aW9uKFwiL3VwZGF0ZXNcIik7XG5cbiAgICBSZWFjdFJvdXRlci5ydW4ocHJveHlhcHAucm91dGVzLCBmdW5jdGlvbiAoSGFuZGxlcikge1xuICAgICAgICBSZWFjdC5yZW5kZXIoUmVhY3QuY3JlYXRlRWxlbWVudChIYW5kbGVyLCBudWxsKSwgZG9jdW1lbnQuYm9keSk7XG4gICAgfSk7XG59KTsiLCJ2YXIgUmVhY3QgPSByZXF1aXJlKFwicmVhY3RcIik7XG52YXIgdXRpbHMgPSByZXF1aXJlKFwiLi91dGlscy5qc1wiKTtcbnZhciBWaXJ0dWFsU2Nyb2xsTWl4aW4gPSByZXF1aXJlKFwiLi92aXJ0dWFsc2Nyb2xsLmpzXCIpO1xudmFyIHZpZXdzID0gcmVxdWlyZShcIi4uL3N0b3JlL3ZpZXcuanNcIik7XG5cbnZhciBMb2dNZXNzYWdlID0gUmVhY3QuY3JlYXRlQ2xhc3Moe2Rpc3BsYXlOYW1lOiBcIkxvZ01lc3NhZ2VcIixcbiAgICByZW5kZXI6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGVudHJ5ID0gdGhpcy5wcm9wcy5lbnRyeTtcbiAgICAgICAgdmFyIGluZGljYXRvcjtcbiAgICAgICAgc3dpdGNoIChlbnRyeS5sZXZlbCkge1xuICAgICAgICAgICAgY2FzZSBcIndlYlwiOlxuICAgICAgICAgICAgICAgIGluZGljYXRvciA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJpXCIsIHtjbGFzc05hbWU6IFwiZmEgZmEtZncgZmEtaHRtbDVcIn0pO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBcImRlYnVnXCI6XG4gICAgICAgICAgICAgICAgaW5kaWNhdG9yID0gUmVhY3QuY3JlYXRlRWxlbWVudChcImlcIiwge2NsYXNzTmFtZTogXCJmYSBmYS1mdyBmYS1idWdcIn0pO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBpbmRpY2F0b3IgPSBSZWFjdC5jcmVhdGVFbGVtZW50KFwiaVwiLCB7Y2xhc3NOYW1lOiBcImZhIGZhLWZ3IGZhLWluZm9cIn0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFwiZGl2XCIsIG51bGwsIFxuICAgICAgICAgICAgICAgIGluZGljYXRvciwgXCIgXCIsIGVudHJ5Lm1lc3NhZ2VcbiAgICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICB9LFxuICAgIHNob3VsZENvbXBvbmVudFVwZGF0ZTogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7IC8vIGxvZyBlbnRyaWVzIGFyZSBpbW11dGFibGUuXG4gICAgfVxufSk7XG5cbnZhciBFdmVudExvZ0NvbnRlbnRzID0gUmVhY3QuY3JlYXRlQ2xhc3Moe2Rpc3BsYXlOYW1lOiBcIkV2ZW50TG9nQ29udGVudHNcIixcbiAgICBtaXhpbnM6IFt1dGlscy5BdXRvU2Nyb2xsTWl4aW4sIFZpcnR1YWxTY3JvbGxNaXhpbl0sXG4gICAgZ2V0SW5pdGlhbFN0YXRlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBsb2c6IFtdXG4gICAgICAgIH07XG4gICAgfSxcbiAgICBjb21wb25lbnRXaWxsTW91bnQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5vcGVuVmlldyh0aGlzLnByb3BzLmV2ZW50U3RvcmUpO1xuICAgIH0sXG4gICAgY29tcG9uZW50V2lsbFVubW91bnQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5jbG9zZVZpZXcoKTtcbiAgICB9LFxuICAgIG9wZW5WaWV3OiBmdW5jdGlvbiAoc3RvcmUpIHtcbiAgICAgICAgdmFyIHZpZXcgPSBuZXcgdmlld3MuU3RvcmVWaWV3KHN0b3JlLCBmdW5jdGlvbiAoZW50cnkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnByb3BzLmZpbHRlcltlbnRyeS5sZXZlbF07XG4gICAgICAgIH0uYmluZCh0aGlzKSk7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgdmlldzogdmlld1xuICAgICAgICB9KTtcblxuICAgICAgICB2aWV3LmFkZExpc3RlbmVyKFwiYWRkIHJlY2FsY3VsYXRlXCIsIHRoaXMub25FdmVudExvZ0NoYW5nZSk7XG4gICAgfSxcbiAgICBjbG9zZVZpZXc6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5zdGF0ZS52aWV3LmNsb3NlKCk7XG4gICAgfSxcbiAgICBvbkV2ZW50TG9nQ2hhbmdlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgbG9nOiB0aGlzLnN0YXRlLnZpZXcubGlzdFxuICAgICAgICB9KTtcbiAgICB9LFxuICAgIGNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHM6IGZ1bmN0aW9uIChuZXh0UHJvcHMpIHtcbiAgICAgICAgaWYgKG5leHRQcm9wcy5maWx0ZXIgIT09IHRoaXMucHJvcHMuZmlsdGVyKSB7XG4gICAgICAgICAgICB0aGlzLnByb3BzLmZpbHRlciA9IG5leHRQcm9wcy5maWx0ZXI7IC8vIERpcnR5OiBNYWtlIHN1cmUgdGhhdCB2aWV3IGZpbHRlciBzZWVzIHRoZSB1cGRhdGUuXG4gICAgICAgICAgICB0aGlzLnN0YXRlLnZpZXcucmVjYWxjdWxhdGUoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobmV4dFByb3BzLmV2ZW50U3RvcmUgIT09IHRoaXMucHJvcHMuZXZlbnRTdG9yZSkge1xuICAgICAgICAgICAgdGhpcy5jbG9zZVZpZXcoKTtcbiAgICAgICAgICAgIHRoaXMub3BlblZpZXcobmV4dFByb3BzLmV2ZW50U3RvcmUpO1xuICAgICAgICB9XG4gICAgfSxcbiAgICBnZXREZWZhdWx0UHJvcHM6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHJvd0hlaWdodDogNDUsXG4gICAgICAgICAgICByb3dIZWlnaHRNaW46IDE1LFxuICAgICAgICAgICAgcGxhY2Vob2xkZXJUYWdOYW1lOiBcImRpdlwiXG4gICAgICAgIH07XG4gICAgfSxcbiAgICByZW5kZXJSb3c6IGZ1bmN0aW9uIChlbGVtKSB7XG4gICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KExvZ01lc3NhZ2UsIHtrZXk6IGVsZW0uaWQsIGVudHJ5OiBlbGVtfSk7XG4gICAgfSxcbiAgICByZW5kZXI6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHJvd3MgPSB0aGlzLnJlbmRlclJvd3ModGhpcy5zdGF0ZS5sb2cpO1xuXG4gICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFwicHJlXCIsIHtvblNjcm9sbDogdGhpcy5vblNjcm9sbH0sIFxuICAgICAgICAgICAgIHRoaXMuZ2V0UGxhY2Vob2xkZXJUb3AodGhpcy5zdGF0ZS5sb2cubGVuZ3RoKSwgXG4gICAgICAgICAgICByb3dzLCBcbiAgICAgICAgICAgICB0aGlzLmdldFBsYWNlaG9sZGVyQm90dG9tKHRoaXMuc3RhdGUubG9nLmxlbmd0aCkgXG4gICAgICAgICk7XG4gICAgfVxufSk7XG5cbnZhciBUb2dnbGVGaWx0ZXIgPSBSZWFjdC5jcmVhdGVDbGFzcyh7ZGlzcGxheU5hbWU6IFwiVG9nZ2xlRmlsdGVyXCIsXG4gICAgdG9nZ2xlOiBmdW5jdGlvbiAoZSkge1xuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIHJldHVybiB0aGlzLnByb3BzLnRvZ2dsZUxldmVsKHRoaXMucHJvcHMubmFtZSk7XG4gICAgfSxcbiAgICByZW5kZXI6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGNsYXNzTmFtZSA9IFwibGFiZWwgXCI7XG4gICAgICAgIGlmICh0aGlzLnByb3BzLmFjdGl2ZSkge1xuICAgICAgICAgICAgY2xhc3NOYW1lICs9IFwibGFiZWwtcHJpbWFyeVwiO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY2xhc3NOYW1lICs9IFwibGFiZWwtZGVmYXVsdFwiO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFwiYVwiLCB7XG4gICAgICAgICAgICAgICAgaHJlZjogXCIjXCIsIFxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogY2xhc3NOYW1lLCBcbiAgICAgICAgICAgICAgICBvbkNsaWNrOiB0aGlzLnRvZ2dsZX0sIFxuICAgICAgICAgICAgICAgIHRoaXMucHJvcHMubmFtZVxuICAgICAgICAgICAgKVxuICAgICAgICApO1xuICAgIH1cbn0pO1xuXG52YXIgRXZlbnRMb2cgPSBSZWFjdC5jcmVhdGVDbGFzcyh7ZGlzcGxheU5hbWU6IFwiRXZlbnRMb2dcIixcbiAgICBnZXRJbml0aWFsU3RhdGU6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGZpbHRlcjoge1xuICAgICAgICAgICAgICAgIFwiZGVidWdcIjogZmFsc2UsXG4gICAgICAgICAgICAgICAgXCJpbmZvXCI6IHRydWUsXG4gICAgICAgICAgICAgICAgXCJ3ZWJcIjogdHJ1ZVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH0sXG4gICAgY2xvc2U6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGQgPSB7fTtcbiAgICAgICAgZFtRdWVyeS5TSE9XX0VWRU5UTE9HXSA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5zZXRRdWVyeShkKTtcbiAgICB9LFxuICAgIHRvZ2dsZUxldmVsOiBmdW5jdGlvbiAobGV2ZWwpIHtcbiAgICAgICAgdmFyIGZpbHRlciA9IF8uZXh0ZW5kKHt9LCB0aGlzLnN0YXRlLmZpbHRlcik7XG4gICAgICAgIGZpbHRlcltsZXZlbF0gPSAhZmlsdGVyW2xldmVsXTtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7ZmlsdGVyOiBmaWx0ZXJ9KTtcbiAgICB9LFxuICAgIHJlbmRlcjogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcImRpdlwiLCB7Y2xhc3NOYW1lOiBcImV2ZW50bG9nXCJ9LCBcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFwiZGl2XCIsIG51bGwsIFxuICAgICAgICAgICAgICAgICAgICBcIkV2ZW50bG9nXCIsIFxuICAgICAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFwiZGl2XCIsIHtjbGFzc05hbWU6IFwicHVsbC1yaWdodFwifSwgXG4gICAgICAgICAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFRvZ2dsZUZpbHRlciwge25hbWU6IFwiZGVidWdcIiwgYWN0aXZlOiB0aGlzLnN0YXRlLmZpbHRlci5kZWJ1ZywgdG9nZ2xlTGV2ZWw6IHRoaXMudG9nZ2xlTGV2ZWx9KSwgXG4gICAgICAgICAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFRvZ2dsZUZpbHRlciwge25hbWU6IFwiaW5mb1wiLCBhY3RpdmU6IHRoaXMuc3RhdGUuZmlsdGVyLmluZm8sIHRvZ2dsZUxldmVsOiB0aGlzLnRvZ2dsZUxldmVsfSksIFxuICAgICAgICAgICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChUb2dnbGVGaWx0ZXIsIHtuYW1lOiBcIndlYlwiLCBhY3RpdmU6IHRoaXMuc3RhdGUuZmlsdGVyLndlYiwgdG9nZ2xlTGV2ZWw6IHRoaXMudG9nZ2xlTGV2ZWx9KSwgXG4gICAgICAgICAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFwiaVwiLCB7b25DbGljazogdGhpcy5jbG9zZSwgY2xhc3NOYW1lOiBcImZhIGZhLWNsb3NlXCJ9KVxuICAgICAgICAgICAgICAgICAgICApXG5cbiAgICAgICAgICAgICAgICApLCBcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KEV2ZW50TG9nQ29udGVudHMsIHtmaWx0ZXI6IHRoaXMuc3RhdGUuZmlsdGVyLCBldmVudFN0b3JlOiB0aGlzLnByb3BzLmV2ZW50U3RvcmV9KVxuICAgICAgICAgICAgKVxuICAgICAgICApO1xuICAgIH1cbn0pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IEV2ZW50TG9nOyIsInZhciBSZWFjdCA9IHJlcXVpcmUoXCJyZWFjdFwiKTtcbnZhciBfID0gcmVxdWlyZShcImxvZGFzaFwiKTtcblxudmFyIHV0aWxzID0gcmVxdWlyZShcIi4vdXRpbHMuanNcIik7XG52YXIgYWN0aW9ucyA9IHJlcXVpcmUoXCIuLi9hY3Rpb25zLmpzXCIpO1xudmFyIGZsb3d1dGlscyA9IHJlcXVpcmUoXCIuLi9mbG93L3V0aWxzLmpzXCIpO1xudmFyIHRvcHV0aWxzID0gcmVxdWlyZShcIi4uL3V0aWxzLmpzXCIpO1xuXG52YXIgTmF2QWN0aW9uID0gUmVhY3QuY3JlYXRlQ2xhc3Moe2Rpc3BsYXlOYW1lOiBcIk5hdkFjdGlvblwiLFxuICAgIG9uQ2xpY2s6IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgdGhpcy5wcm9wcy5vbkNsaWNrKCk7XG4gICAgfSxcbiAgICByZW5kZXI6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJhXCIsIHt0aXRsZTogdGhpcy5wcm9wcy50aXRsZSwgXG4gICAgICAgICAgICAgICAgaHJlZjogXCIjXCIsIFxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogXCJuYXYtYWN0aW9uXCIsIFxuICAgICAgICAgICAgICAgIG9uQ2xpY2s6IHRoaXMub25DbGlja30sIFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJpXCIsIHtjbGFzc05hbWU6IFwiZmEgZmEtZncgXCIgKyB0aGlzLnByb3BzLmljb259KVxuICAgICAgICAgICAgKVxuICAgICAgICApO1xuICAgIH1cbn0pO1xuXG52YXIgRmxvd0RldGFpbE5hdiA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtkaXNwbGF5TmFtZTogXCJGbG93RGV0YWlsTmF2XCIsXG4gICAgcmVuZGVyOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBmbG93ID0gdGhpcy5wcm9wcy5mbG93O1xuXG4gICAgICAgIHZhciB0YWJzID0gdGhpcy5wcm9wcy50YWJzLm1hcChmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgdmFyIHN0ciA9IGUuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBlLnNsaWNlKDEpO1xuICAgICAgICAgICAgdmFyIGNsYXNzTmFtZSA9IHRoaXMucHJvcHMuYWN0aXZlID09PSBlID8gXCJhY3RpdmVcIiA6IFwiXCI7XG4gICAgICAgICAgICB2YXIgb25DbGljayA9IGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICAgICAgICAgIHRoaXMucHJvcHMuc2VsZWN0VGFiKGUpO1xuICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICB9LmJpbmQodGhpcyk7XG4gICAgICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcImFcIiwge2tleTogZSwgXG4gICAgICAgICAgICAgICAgaHJlZjogXCIjXCIsIFxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZTogY2xhc3NOYW1lLCBcbiAgICAgICAgICAgICAgICBvbkNsaWNrOiBvbkNsaWNrfSwgc3RyKTtcbiAgICAgICAgfS5iaW5kKHRoaXMpKTtcblxuICAgICAgICB2YXIgYWNjZXB0QnV0dG9uID0gbnVsbDtcbiAgICAgICAgaWYoZmxvdy5pbnRlcmNlcHRlZCl7XG4gICAgICAgICAgICBhY2NlcHRCdXR0b24gPSBSZWFjdC5jcmVhdGVFbGVtZW50KE5hdkFjdGlvbiwge3RpdGxlOiBcIlthXWNjZXB0IGludGVyY2VwdGVkIGZsb3dcIiwgaWNvbjogXCJmYS1wbGF5XCIsIG9uQ2xpY2s6IGFjdGlvbnMuRmxvd0FjdGlvbnMuYWNjZXB0LmJpbmQobnVsbCwgZmxvdyl9KTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgcmV2ZXJ0QnV0dG9uID0gbnVsbDtcbiAgICAgICAgaWYoZmxvdy5tb2RpZmllZCl7XG4gICAgICAgICAgICByZXZlcnRCdXR0b24gPSBSZWFjdC5jcmVhdGVFbGVtZW50KE5hdkFjdGlvbiwge3RpdGxlOiBcInJldmVydCBjaGFuZ2VzIHRvIGZsb3cgW1ZdXCIsIGljb246IFwiZmEtaGlzdG9yeVwiLCBvbkNsaWNrOiBhY3Rpb25zLkZsb3dBY3Rpb25zLnJldmVydC5iaW5kKG51bGwsIGZsb3cpfSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcIm5hdlwiLCB7cmVmOiBcImhlYWRcIiwgY2xhc3NOYW1lOiBcIm5hdi10YWJzIG5hdi10YWJzLXNtXCJ9LCBcbiAgICAgICAgICAgICAgICB0YWJzLCBcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KE5hdkFjdGlvbiwge3RpdGxlOiBcIltkXWVsZXRlIGZsb3dcIiwgaWNvbjogXCJmYS10cmFzaFwiLCBvbkNsaWNrOiBhY3Rpb25zLkZsb3dBY3Rpb25zLmRlbGV0ZS5iaW5kKG51bGwsIGZsb3cpfSksIFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoTmF2QWN0aW9uLCB7dGl0bGU6IFwiW0RddXBsaWNhdGUgZmxvd1wiLCBpY29uOiBcImZhLWNvcHlcIiwgb25DbGljazogYWN0aW9ucy5GbG93QWN0aW9ucy5kdXBsaWNhdGUuYmluZChudWxsLCBmbG93KX0pLCBcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KE5hdkFjdGlvbiwge2Rpc2FibGVkOiB0cnVlLCB0aXRsZTogXCJbcl1lcGxheSBmbG93XCIsIGljb246IFwiZmEtcmVwZWF0XCIsIG9uQ2xpY2s6IGFjdGlvbnMuRmxvd0FjdGlvbnMucmVwbGF5LmJpbmQobnVsbCwgZmxvdyl9KSwgXG4gICAgICAgICAgICAgICAgYWNjZXB0QnV0dG9uLCBcbiAgICAgICAgICAgICAgICByZXZlcnRCdXR0b25cbiAgICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICB9XG59KTtcblxudmFyIEhlYWRlcnMgPSBSZWFjdC5jcmVhdGVDbGFzcyh7ZGlzcGxheU5hbWU6IFwiSGVhZGVyc1wiLFxuICAgIHJlbmRlcjogZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcm93cyA9IHRoaXMucHJvcHMubWVzc2FnZS5oZWFkZXJzLm1hcChmdW5jdGlvbiAoaGVhZGVyLCBpKSB7XG4gICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJ0clwiLCB7a2V5OiBpfSwgXG4gICAgICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJ0ZFwiLCB7Y2xhc3NOYW1lOiBcImhlYWRlci1uYW1lXCJ9LCBoZWFkZXJbMF0gKyBcIjpcIiksIFxuICAgICAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFwidGRcIiwge2NsYXNzTmFtZTogXCJoZWFkZXItdmFsdWVcIn0sIGhlYWRlclsxXSlcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICApO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJ0YWJsZVwiLCB7Y2xhc3NOYW1lOiBcImhlYWRlci10YWJsZVwifSwgXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcInRib2R5XCIsIG51bGwsIFxuICAgICAgICAgICAgICAgICAgICByb3dzXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKVxuICAgICAgICApO1xuICAgIH1cbn0pO1xuXG52YXIgRmxvd0RldGFpbFJlcXVlc3QgPSBSZWFjdC5jcmVhdGVDbGFzcyh7ZGlzcGxheU5hbWU6IFwiRmxvd0RldGFpbFJlcXVlc3RcIixcbiAgICByZW5kZXI6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGZsb3cgPSB0aGlzLnByb3BzLmZsb3c7XG4gICAgICAgIHZhciBmaXJzdF9saW5lID0gW1xuICAgICAgICAgICAgZmxvdy5yZXF1ZXN0Lm1ldGhvZCxcbiAgICAgICAgICAgIGZsb3d1dGlscy5SZXF1ZXN0VXRpbHMucHJldHR5X3VybChmbG93LnJlcXVlc3QpLFxuICAgICAgICAgICAgXCJIVFRQL1wiICsgZmxvdy5yZXF1ZXN0Lmh0dHB2ZXJzaW9uLmpvaW4oXCIuXCIpXG4gICAgICAgIF0uam9pbihcIiBcIik7XG4gICAgICAgIHZhciBjb250ZW50ID0gbnVsbDtcbiAgICAgICAgaWYgKGZsb3cucmVxdWVzdC5jb250ZW50TGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgY29udGVudCA9IFwiUmVxdWVzdCBDb250ZW50IFNpemU6IFwiICsgdG9wdXRpbHMuZm9ybWF0U2l6ZShmbG93LnJlcXVlc3QuY29udGVudExlbmd0aCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb250ZW50ID0gUmVhY3QuY3JlYXRlRWxlbWVudChcImRpdlwiLCB7Y2xhc3NOYW1lOiBcImFsZXJ0IGFsZXJ0LWluZm9cIn0sIFwiTm8gQ29udGVudFwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vVE9ETzogU3R5bGluZ1xuXG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFwic2VjdGlvblwiLCBudWxsLCBcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFwiZGl2XCIsIHtjbGFzc05hbWU6IFwiZmlyc3QtbGluZVwifSwgZmlyc3RfbGluZSApLCBcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KEhlYWRlcnMsIHttZXNzYWdlOiBmbG93LnJlcXVlc3R9KSwgXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcImhyXCIsIG51bGwpLCBcbiAgICAgICAgICAgICAgICBjb250ZW50XG4gICAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgfVxufSk7XG5cbnZhciBGbG93RGV0YWlsUmVzcG9uc2UgPSBSZWFjdC5jcmVhdGVDbGFzcyh7ZGlzcGxheU5hbWU6IFwiRmxvd0RldGFpbFJlc3BvbnNlXCIsXG4gICAgcmVuZGVyOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBmbG93ID0gdGhpcy5wcm9wcy5mbG93O1xuICAgICAgICB2YXIgZmlyc3RfbGluZSA9IFtcbiAgICAgICAgICAgIFwiSFRUUC9cIiArIGZsb3cucmVzcG9uc2UuaHR0cHZlcnNpb24uam9pbihcIi5cIiksXG4gICAgICAgICAgICBmbG93LnJlc3BvbnNlLmNvZGUsXG4gICAgICAgICAgICBmbG93LnJlc3BvbnNlLm1zZ1xuICAgICAgICBdLmpvaW4oXCIgXCIpO1xuICAgICAgICB2YXIgY29udGVudCA9IG51bGw7XG4gICAgICAgIGlmIChmbG93LnJlc3BvbnNlLmNvbnRlbnRMZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBjb250ZW50ID0gXCJSZXNwb25zZSBDb250ZW50IFNpemU6IFwiICsgdG9wdXRpbHMuZm9ybWF0U2l6ZShmbG93LnJlc3BvbnNlLmNvbnRlbnRMZW5ndGgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29udGVudCA9IFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwge2NsYXNzTmFtZTogXCJhbGVydCBhbGVydC1pbmZvXCJ9LCBcIk5vIENvbnRlbnRcIik7XG4gICAgICAgIH1cblxuICAgICAgICAvL1RPRE86IFN0eWxpbmdcblxuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcInNlY3Rpb25cIiwgbnVsbCwgXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcImRpdlwiLCB7Y2xhc3NOYW1lOiBcImZpcnN0LWxpbmVcIn0sIGZpcnN0X2xpbmUgKSwgXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChIZWFkZXJzLCB7bWVzc2FnZTogZmxvdy5yZXNwb25zZX0pLCBcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFwiaHJcIiwgbnVsbCksIFxuICAgICAgICAgICAgICAgIGNvbnRlbnRcbiAgICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICB9XG59KTtcblxudmFyIEZsb3dEZXRhaWxFcnJvciA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtkaXNwbGF5TmFtZTogXCJGbG93RGV0YWlsRXJyb3JcIixcbiAgICByZW5kZXI6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGZsb3cgPSB0aGlzLnByb3BzLmZsb3c7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFwic2VjdGlvblwiLCBudWxsLCBcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFwiZGl2XCIsIHtjbGFzc05hbWU6IFwiYWxlcnQgYWxlcnQtd2FybmluZ1wifSwgXG4gICAgICAgICAgICAgICAgZmxvdy5lcnJvci5tc2csIFxuICAgICAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFwiZGl2XCIsIG51bGwsIFxuICAgICAgICAgICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcInNtYWxsXCIsIG51bGwsICB0b3B1dGlscy5mb3JtYXRUaW1lU3RhbXAoZmxvdy5lcnJvci50aW1lc3RhbXApIClcbiAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICB9XG59KTtcblxudmFyIFRpbWVTdGFtcCA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtkaXNwbGF5TmFtZTogXCJUaW1lU3RhbXBcIixcbiAgICByZW5kZXI6IGZ1bmN0aW9uICgpIHtcblxuICAgICAgICBpZiAoIXRoaXMucHJvcHMudCkge1xuICAgICAgICAgICAgLy9zaG91bGQgYmUgcmV0dXJuIG51bGwsIGJ1dCB0aGF0IHRyaWdnZXJzIGEgUmVhY3QgYnVnLlxuICAgICAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJ0clwiLCBudWxsKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciB0cyA9IHRvcHV0aWxzLmZvcm1hdFRpbWVTdGFtcCh0aGlzLnByb3BzLnQpO1xuXG4gICAgICAgIHZhciBkZWx0YTtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMuZGVsdGFUbykge1xuICAgICAgICAgICAgZGVsdGEgPSB0b3B1dGlscy5mb3JtYXRUaW1lRGVsdGEoMTAwMCAqICh0aGlzLnByb3BzLnQgLSB0aGlzLnByb3BzLmRlbHRhVG8pKTtcbiAgICAgICAgICAgIGRlbHRhID0gUmVhY3QuY3JlYXRlRWxlbWVudChcInNwYW5cIiwge2NsYXNzTmFtZTogXCJ0ZXh0LW11dGVkXCJ9LCBcIihcIiArIGRlbHRhICsgXCIpXCIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZGVsdGEgPSBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJ0clwiLCBudWxsLCBcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJ0ZFwiLCBudWxsLCB0aGlzLnByb3BzLnRpdGxlICsgXCI6XCIpLCBcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJ0ZFwiLCBudWxsLCB0cywgXCIgXCIsIGRlbHRhKVxuICAgICAgICApO1xuICAgIH1cbn0pO1xuXG52YXIgQ29ubmVjdGlvbkluZm8gPSBSZWFjdC5jcmVhdGVDbGFzcyh7ZGlzcGxheU5hbWU6IFwiQ29ubmVjdGlvbkluZm9cIixcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgY29ubiA9IHRoaXMucHJvcHMuY29ubjtcbiAgICAgICAgdmFyIGFkZHJlc3MgPSBjb25uLmFkZHJlc3MuYWRkcmVzcy5qb2luKFwiOlwiKTtcblxuICAgICAgICB2YXIgc25pID0gUmVhY3QuY3JlYXRlRWxlbWVudChcInRyXCIsIHtrZXk6IFwic25pXCJ9KTsgLy9zaG91bGQgYmUgbnVsbCwgYnV0IHRoYXQgdHJpZ2dlcnMgYSBSZWFjdCBidWcuXG4gICAgICAgIGlmIChjb25uLnNuaSkge1xuICAgICAgICAgICAgc25pID0gUmVhY3QuY3JlYXRlRWxlbWVudChcInRyXCIsIHtrZXk6IFwic25pXCJ9LCBcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFwidGRcIiwgbnVsbCwgXG4gICAgICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJhYmJyXCIsIHt0aXRsZTogXCJUTFMgU2VydmVyIE5hbWUgSW5kaWNhdGlvblwifSwgXCJUTFMgU05JOlwiKVxuICAgICAgICAgICAgICAgICksIFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJ0ZFwiLCBudWxsLCBjb25uLnNuaSlcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJ0YWJsZVwiLCB7Y2xhc3NOYW1lOiBcImNvbm5lY3Rpb24tdGFibGVcIn0sIFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJ0Ym9keVwiLCBudWxsLCBcbiAgICAgICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcInRyXCIsIHtrZXk6IFwiYWRkcmVzc1wifSwgXG4gICAgICAgICAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFwidGRcIiwgbnVsbCwgXCJBZGRyZXNzOlwiKSwgXG4gICAgICAgICAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFwidGRcIiwgbnVsbCwgYWRkcmVzcylcbiAgICAgICAgICAgICAgICAgICAgKSwgXG4gICAgICAgICAgICAgICAgICAgIHNuaVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICB9XG59KTtcblxudmFyIENlcnRpZmljYXRlSW5mbyA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtkaXNwbGF5TmFtZTogXCJDZXJ0aWZpY2F0ZUluZm9cIixcbiAgICByZW5kZXI6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy9UT0RPOiBXZSBzaG91bGQgZmV0Y2ggaHVtYW4tcmVhZGFibGUgY2VydGlmaWNhdGUgcmVwcmVzZW50YXRpb25cbiAgICAgICAgLy8gZnJvbSB0aGUgc2VydmVyXG4gICAgICAgIHZhciBmbG93ID0gdGhpcy5wcm9wcy5mbG93O1xuICAgICAgICB2YXIgY2xpZW50X2Nvbm4gPSBmbG93LmNsaWVudF9jb25uO1xuICAgICAgICB2YXIgc2VydmVyX2Nvbm4gPSBmbG93LnNlcnZlcl9jb25uO1xuXG4gICAgICAgIHZhciBwcmVTdHlsZSA9IHttYXhIZWlnaHQ6IDEwMH07XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFwiZGl2XCIsIG51bGwsIFxuICAgICAgICAgICAgY2xpZW50X2Nvbm4uY2VydCA/IFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJoNFwiLCBudWxsLCBcIkNsaWVudCBDZXJ0aWZpY2F0ZVwiKSA6IG51bGwsIFxuICAgICAgICAgICAgY2xpZW50X2Nvbm4uY2VydCA/IFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJwcmVcIiwge3N0eWxlOiBwcmVTdHlsZX0sIGNsaWVudF9jb25uLmNlcnQpIDogbnVsbCwgXG5cbiAgICAgICAgICAgIHNlcnZlcl9jb25uLmNlcnQgPyBSZWFjdC5jcmVhdGVFbGVtZW50KFwiaDRcIiwgbnVsbCwgXCJTZXJ2ZXIgQ2VydGlmaWNhdGVcIikgOiBudWxsLCBcbiAgICAgICAgICAgIHNlcnZlcl9jb25uLmNlcnQgPyBSZWFjdC5jcmVhdGVFbGVtZW50KFwicHJlXCIsIHtzdHlsZTogcHJlU3R5bGV9LCBzZXJ2ZXJfY29ubi5jZXJ0KSA6IG51bGxcbiAgICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICB9XG59KTtcblxudmFyIFRpbWluZyA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtkaXNwbGF5TmFtZTogXCJUaW1pbmdcIixcbiAgICByZW5kZXI6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGZsb3cgPSB0aGlzLnByb3BzLmZsb3c7XG4gICAgICAgIHZhciBzYyA9IGZsb3cuc2VydmVyX2Nvbm47XG4gICAgICAgIHZhciBjYyA9IGZsb3cuY2xpZW50X2Nvbm47XG4gICAgICAgIHZhciByZXEgPSBmbG93LnJlcXVlc3Q7XG4gICAgICAgIHZhciByZXNwID0gZmxvdy5yZXNwb25zZTtcblxuICAgICAgICB2YXIgdGltZXN0YW1wcyA9IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0aXRsZTogXCJTZXJ2ZXIgY29ubi4gaW5pdGlhdGVkXCIsXG4gICAgICAgICAgICAgICAgdDogc2MudGltZXN0YW1wX3N0YXJ0LFxuICAgICAgICAgICAgICAgIGRlbHRhVG86IHJlcS50aW1lc3RhbXBfc3RhcnRcbiAgICAgICAgICAgIH0sIHtcbiAgICAgICAgICAgICAgICB0aXRsZTogXCJTZXJ2ZXIgY29ubi4gVENQIGhhbmRzaGFrZVwiLFxuICAgICAgICAgICAgICAgIHQ6IHNjLnRpbWVzdGFtcF90Y3Bfc2V0dXAsXG4gICAgICAgICAgICAgICAgZGVsdGFUbzogcmVxLnRpbWVzdGFtcF9zdGFydFxuICAgICAgICAgICAgfSwge1xuICAgICAgICAgICAgICAgIHRpdGxlOiBcIlNlcnZlciBjb25uLiBTU0wgaGFuZHNoYWtlXCIsXG4gICAgICAgICAgICAgICAgdDogc2MudGltZXN0YW1wX3NzbF9zZXR1cCxcbiAgICAgICAgICAgICAgICBkZWx0YVRvOiByZXEudGltZXN0YW1wX3N0YXJ0XG4gICAgICAgICAgICB9LCB7XG4gICAgICAgICAgICAgICAgdGl0bGU6IFwiQ2xpZW50IGNvbm4uIGVzdGFibGlzaGVkXCIsXG4gICAgICAgICAgICAgICAgdDogY2MudGltZXN0YW1wX3N0YXJ0LFxuICAgICAgICAgICAgICAgIGRlbHRhVG86IHJlcS50aW1lc3RhbXBfc3RhcnRcbiAgICAgICAgICAgIH0sIHtcbiAgICAgICAgICAgICAgICB0aXRsZTogXCJDbGllbnQgY29ubi4gU1NMIGhhbmRzaGFrZVwiLFxuICAgICAgICAgICAgICAgIHQ6IGNjLnRpbWVzdGFtcF9zc2xfc2V0dXAsXG4gICAgICAgICAgICAgICAgZGVsdGFUbzogcmVxLnRpbWVzdGFtcF9zdGFydFxuICAgICAgICAgICAgfSwge1xuICAgICAgICAgICAgICAgIHRpdGxlOiBcIkZpcnN0IHJlcXVlc3QgYnl0ZVwiLFxuICAgICAgICAgICAgICAgIHQ6IHJlcS50aW1lc3RhbXBfc3RhcnQsXG4gICAgICAgICAgICB9LCB7XG4gICAgICAgICAgICAgICAgdGl0bGU6IFwiUmVxdWVzdCBjb21wbGV0ZVwiLFxuICAgICAgICAgICAgICAgIHQ6IHJlcS50aW1lc3RhbXBfZW5kLFxuICAgICAgICAgICAgICAgIGRlbHRhVG86IHJlcS50aW1lc3RhbXBfc3RhcnRcbiAgICAgICAgICAgIH1cbiAgICAgICAgXTtcblxuICAgICAgICBpZiAoZmxvdy5yZXNwb25zZSkge1xuICAgICAgICAgICAgdGltZXN0YW1wcy5wdXNoKFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgdGl0bGU6IFwiRmlyc3QgcmVzcG9uc2UgYnl0ZVwiLFxuICAgICAgICAgICAgICAgICAgICB0OiByZXNwLnRpbWVzdGFtcF9zdGFydCxcbiAgICAgICAgICAgICAgICAgICAgZGVsdGFUbzogcmVxLnRpbWVzdGFtcF9zdGFydFxuICAgICAgICAgICAgICAgIH0sIHtcbiAgICAgICAgICAgICAgICAgICAgdGl0bGU6IFwiUmVzcG9uc2UgY29tcGxldGVcIixcbiAgICAgICAgICAgICAgICAgICAgdDogcmVzcC50aW1lc3RhbXBfZW5kLFxuICAgICAgICAgICAgICAgICAgICBkZWx0YVRvOiByZXEudGltZXN0YW1wX3N0YXJ0XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vQWRkIHVuaXF1ZSBrZXkgZm9yIGVhY2ggcm93LlxuICAgICAgICB0aW1lc3RhbXBzLmZvckVhY2goZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgIGUua2V5ID0gZS50aXRsZTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGltZXN0YW1wcyA9IF8uc29ydEJ5KHRpbWVzdGFtcHMsICd0Jyk7XG5cbiAgICAgICAgdmFyIHJvd3MgPSB0aW1lc3RhbXBzLm1hcChmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoVGltZVN0YW1wLCBSZWFjdC5fX3NwcmVhZCh7fSwgIGUpKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwgbnVsbCwgXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcImg0XCIsIG51bGwsIFwiVGltaW5nXCIpLCBcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFwidGFibGVcIiwge2NsYXNzTmFtZTogXCJ0aW1pbmctdGFibGVcIn0sIFxuICAgICAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFwidGJvZHlcIiwgbnVsbCwgXG4gICAgICAgICAgICAgICAgICAgIHJvd3NcbiAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICB9XG59KTtcblxudmFyIEZsb3dEZXRhaWxDb25uZWN0aW9uSW5mbyA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtkaXNwbGF5TmFtZTogXCJGbG93RGV0YWlsQ29ubmVjdGlvbkluZm9cIixcbiAgICByZW5kZXI6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGZsb3cgPSB0aGlzLnByb3BzLmZsb3c7XG4gICAgICAgIHZhciBjbGllbnRfY29ubiA9IGZsb3cuY2xpZW50X2Nvbm47XG4gICAgICAgIHZhciBzZXJ2ZXJfY29ubiA9IGZsb3cuc2VydmVyX2Nvbm47XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFwic2VjdGlvblwiLCBudWxsLCBcblxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJoNFwiLCBudWxsLCBcIkNsaWVudCBDb25uZWN0aW9uXCIpLCBcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KENvbm5lY3Rpb25JbmZvLCB7Y29ubjogY2xpZW50X2Nvbm59KSwgXG5cbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFwiaDRcIiwgbnVsbCwgXCJTZXJ2ZXIgQ29ubmVjdGlvblwiKSwgXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChDb25uZWN0aW9uSW5mbywge2Nvbm46IHNlcnZlcl9jb25ufSksIFxuXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChDZXJ0aWZpY2F0ZUluZm8sIHtmbG93OiBmbG93fSksIFxuXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChUaW1pbmcsIHtmbG93OiBmbG93fSlcblxuICAgICAgICAgICAgKVxuICAgICAgICApO1xuICAgIH1cbn0pO1xuXG52YXIgYWxsVGFicyA9IHtcbiAgICByZXF1ZXN0OiBGbG93RGV0YWlsUmVxdWVzdCxcbiAgICByZXNwb25zZTogRmxvd0RldGFpbFJlc3BvbnNlLFxuICAgIGVycm9yOiBGbG93RGV0YWlsRXJyb3IsXG4gICAgZGV0YWlsczogRmxvd0RldGFpbENvbm5lY3Rpb25JbmZvXG59O1xuXG52YXIgRmxvd0RldGFpbCA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtkaXNwbGF5TmFtZTogXCJGbG93RGV0YWlsXCIsXG4gICAgbWl4aW5zOiBbdXRpbHMuU3RpY2t5SGVhZE1peGluLCB1dGlscy5OYXZpZ2F0aW9uLCB1dGlscy5TdGF0ZV0sXG4gICAgZ2V0VGFiczogZnVuY3Rpb24gKGZsb3cpIHtcbiAgICAgICAgdmFyIHRhYnMgPSBbXTtcbiAgICAgICAgW1wicmVxdWVzdFwiLCBcInJlc3BvbnNlXCIsIFwiZXJyb3JcIl0uZm9yRWFjaChmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgaWYgKGZsb3dbZV0pIHtcbiAgICAgICAgICAgICAgICB0YWJzLnB1c2goZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICB0YWJzLnB1c2goXCJkZXRhaWxzXCIpO1xuICAgICAgICByZXR1cm4gdGFicztcbiAgICB9LFxuICAgIG5leHRUYWI6IGZ1bmN0aW9uIChpKSB7XG4gICAgICAgIHZhciB0YWJzID0gdGhpcy5nZXRUYWJzKHRoaXMucHJvcHMuZmxvdyk7XG4gICAgICAgIHZhciBjdXJyZW50SW5kZXggPSB0YWJzLmluZGV4T2YodGhpcy5nZXRQYXJhbXMoKS5kZXRhaWxUYWIpO1xuICAgICAgICAvLyBKUyBtb2R1bG8gb3BlcmF0b3IgZG9lc24ndCBjb3JyZWN0IG5lZ2F0aXZlIG51bWJlcnMsIG1ha2Ugc3VyZSB0aGF0IHdlIGFyZSBwb3NpdGl2ZS5cbiAgICAgICAgdmFyIG5leHRJbmRleCA9IChjdXJyZW50SW5kZXggKyBpICsgdGFicy5sZW5ndGgpICUgdGFicy5sZW5ndGg7XG4gICAgICAgIHRoaXMuc2VsZWN0VGFiKHRhYnNbbmV4dEluZGV4XSk7XG4gICAgfSxcbiAgICBzZWxlY3RUYWI6IGZ1bmN0aW9uIChwYW5lbCkge1xuICAgICAgICB0aGlzLnJlcGxhY2VXaXRoKFxuICAgICAgICAgICAgXCJmbG93XCIsXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgZmxvd0lkOiB0aGlzLmdldFBhcmFtcygpLmZsb3dJZCxcbiAgICAgICAgICAgICAgICBkZXRhaWxUYWI6IHBhbmVsXG4gICAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgfSxcbiAgICByZW5kZXI6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGZsb3cgPSB0aGlzLnByb3BzLmZsb3c7XG4gICAgICAgIHZhciB0YWJzID0gdGhpcy5nZXRUYWJzKGZsb3cpO1xuICAgICAgICB2YXIgYWN0aXZlID0gdGhpcy5nZXRQYXJhbXMoKS5kZXRhaWxUYWI7XG5cbiAgICAgICAgaWYgKCFfLmNvbnRhaW5zKHRhYnMsIGFjdGl2ZSkpIHtcbiAgICAgICAgICAgIGlmIChhY3RpdmUgPT09IFwicmVzcG9uc2VcIiAmJiBmbG93LmVycm9yKSB7XG4gICAgICAgICAgICAgICAgYWN0aXZlID0gXCJlcnJvclwiO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChhY3RpdmUgPT09IFwiZXJyb3JcIiAmJiBmbG93LnJlc3BvbnNlKSB7XG4gICAgICAgICAgICAgICAgYWN0aXZlID0gXCJyZXNwb25zZVwiO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBhY3RpdmUgPSB0YWJzWzBdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5zZWxlY3RUYWIoYWN0aXZlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBUYWIgPSBhbGxUYWJzW2FjdGl2ZV07XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFwiZGl2XCIsIHtjbGFzc05hbWU6IFwiZmxvdy1kZXRhaWxcIiwgb25TY3JvbGw6IHRoaXMuYWRqdXN0SGVhZH0sIFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoRmxvd0RldGFpbE5hdiwge3JlZjogXCJoZWFkXCIsIFxuICAgICAgICAgICAgICAgICAgICBmbG93OiBmbG93LCBcbiAgICAgICAgICAgICAgICAgICAgdGFiczogdGFicywgXG4gICAgICAgICAgICAgICAgICAgIGFjdGl2ZTogYWN0aXZlLCBcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0VGFiOiB0aGlzLnNlbGVjdFRhYn0pLCBcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFRhYiwge2Zsb3c6IGZsb3d9KVxuICAgICAgICAgICAgKVxuICAgICAgICApO1xuICAgIH1cbn0pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgICBGbG93RGV0YWlsOiBGbG93RGV0YWlsXG59OyIsInZhciBSZWFjdCA9IHJlcXVpcmUoXCJyZWFjdFwiKTtcbnZhciBmbG93dXRpbHMgPSByZXF1aXJlKFwiLi4vZmxvdy91dGlscy5qc1wiKTtcbnZhciB1dGlscyA9IHJlcXVpcmUoXCIuLi91dGlscy5qc1wiKTtcblxudmFyIFRMU0NvbHVtbiA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtkaXNwbGF5TmFtZTogXCJUTFNDb2x1bW5cIixcbiAgICBzdGF0aWNzOiB7XG4gICAgICAgIHJlbmRlclRpdGxlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcInRoXCIsIHtrZXk6IFwidGxzXCIsIGNsYXNzTmFtZTogXCJjb2wtdGxzXCJ9KTtcbiAgICAgICAgfVxuICAgIH0sXG4gICAgcmVuZGVyOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBmbG93ID0gdGhpcy5wcm9wcy5mbG93O1xuICAgICAgICB2YXIgc3NsID0gKGZsb3cucmVxdWVzdC5zY2hlbWUgPT0gXCJodHRwc1wiKTtcbiAgICAgICAgdmFyIGNsYXNzZXM7XG4gICAgICAgIGlmIChzc2wpIHtcbiAgICAgICAgICAgIGNsYXNzZXMgPSBcImNvbC10bHMgY29sLXRscy1odHRwc1wiO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY2xhc3NlcyA9IFwiY29sLXRscyBjb2wtdGxzLWh0dHBcIjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcInRkXCIsIHtjbGFzc05hbWU6IGNsYXNzZXN9KTtcbiAgICB9XG59KTtcblxuXG52YXIgSWNvbkNvbHVtbiA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtkaXNwbGF5TmFtZTogXCJJY29uQ29sdW1uXCIsXG4gICAgc3RhdGljczoge1xuICAgICAgICByZW5kZXJUaXRsZTogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJ0aFwiLCB7a2V5OiBcImljb25cIiwgY2xhc3NOYW1lOiBcImNvbC1pY29uXCJ9KTtcbiAgICAgICAgfVxuICAgIH0sXG4gICAgcmVuZGVyOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBmbG93ID0gdGhpcy5wcm9wcy5mbG93O1xuXG4gICAgICAgIHZhciBpY29uO1xuICAgICAgICBpZiAoZmxvdy5yZXNwb25zZSkge1xuICAgICAgICAgICAgdmFyIGNvbnRlbnRUeXBlID0gZmxvd3V0aWxzLlJlc3BvbnNlVXRpbHMuZ2V0Q29udGVudFR5cGUoZmxvdy5yZXNwb25zZSk7XG5cbiAgICAgICAgICAgIC8vVE9ETzogV2Ugc2hvdWxkIGFzc2lnbiBhIHR5cGUgdG8gdGhlIGZsb3cgc29tZXdoZXJlIGVsc2UuXG4gICAgICAgICAgICBpZiAoZmxvdy5yZXNwb25zZS5jb2RlID09IDMwNCkge1xuICAgICAgICAgICAgICAgIGljb24gPSBcInJlc291cmNlLWljb24tbm90LW1vZGlmaWVkXCI7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKDMwMCA8PSBmbG93LnJlc3BvbnNlLmNvZGUgJiYgZmxvdy5yZXNwb25zZS5jb2RlIDwgNDAwKSB7XG4gICAgICAgICAgICAgICAgaWNvbiA9IFwicmVzb3VyY2UtaWNvbi1yZWRpcmVjdFwiO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChjb250ZW50VHlwZSAmJiBjb250ZW50VHlwZS5pbmRleE9mKFwiaW1hZ2VcIikgPj0gMCkge1xuICAgICAgICAgICAgICAgIGljb24gPSBcInJlc291cmNlLWljb24taW1hZ2VcIjtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoY29udGVudFR5cGUgJiYgY29udGVudFR5cGUuaW5kZXhPZihcImphdmFzY3JpcHRcIikgPj0gMCkge1xuICAgICAgICAgICAgICAgIGljb24gPSBcInJlc291cmNlLWljb24tanNcIjtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoY29udGVudFR5cGUgJiYgY29udGVudFR5cGUuaW5kZXhPZihcImNzc1wiKSA+PSAwKSB7XG4gICAgICAgICAgICAgICAgaWNvbiA9IFwicmVzb3VyY2UtaWNvbi1jc3NcIjtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoY29udGVudFR5cGUgJiYgY29udGVudFR5cGUuaW5kZXhPZihcImh0bWxcIikgPj0gMCkge1xuICAgICAgICAgICAgICAgIGljb24gPSBcInJlc291cmNlLWljb24tZG9jdW1lbnRcIjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoIWljb24pIHtcbiAgICAgICAgICAgIGljb24gPSBcInJlc291cmNlLWljb24tcGxhaW5cIjtcbiAgICAgICAgfVxuXG5cbiAgICAgICAgaWNvbiArPSBcIiByZXNvdXJjZS1pY29uXCI7XG4gICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFwidGRcIiwge2NsYXNzTmFtZTogXCJjb2wtaWNvblwifSwgXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFwiZGl2XCIsIHtjbGFzc05hbWU6IGljb259KVxuICAgICAgICApO1xuICAgIH1cbn0pO1xuXG52YXIgUGF0aENvbHVtbiA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtkaXNwbGF5TmFtZTogXCJQYXRoQ29sdW1uXCIsXG4gICAgc3RhdGljczoge1xuICAgICAgICByZW5kZXJUaXRsZTogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJ0aFwiLCB7a2V5OiBcInBhdGhcIiwgY2xhc3NOYW1lOiBcImNvbC1wYXRoXCJ9LCBcIlBhdGhcIik7XG4gICAgICAgIH1cbiAgICB9LFxuICAgIHJlbmRlcjogZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgZmxvdyA9IHRoaXMucHJvcHMuZmxvdztcbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJ0ZFwiLCB7Y2xhc3NOYW1lOiBcImNvbC1wYXRoXCJ9LCBcbiAgICAgICAgICAgIGZsb3cucmVxdWVzdC5pc19yZXBsYXkgPyBSZWFjdC5jcmVhdGVFbGVtZW50KFwiaVwiLCB7Y2xhc3NOYW1lOiBcImZhIGZhLWZ3IGZhLXJlcGVhdCBwdWxsLXJpZ2h0XCJ9KSA6IG51bGwsIFxuICAgICAgICAgICAgZmxvdy5pbnRlcmNlcHRlZCA/IFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJpXCIsIHtjbGFzc05hbWU6IFwiZmEgZmEtZncgZmEtcGF1c2UgcHVsbC1yaWdodFwifSkgOiBudWxsLCBcbiAgICAgICAgICAgIGZsb3cucmVxdWVzdC5zY2hlbWUgKyBcIjovL1wiICsgZmxvdy5yZXF1ZXN0Lmhvc3QgKyBmbG93LnJlcXVlc3QucGF0aFxuICAgICAgICApO1xuICAgIH1cbn0pO1xuXG5cbnZhciBNZXRob2RDb2x1bW4gPSBSZWFjdC5jcmVhdGVDbGFzcyh7ZGlzcGxheU5hbWU6IFwiTWV0aG9kQ29sdW1uXCIsXG4gICAgc3RhdGljczoge1xuICAgICAgICByZW5kZXJUaXRsZTogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJ0aFwiLCB7a2V5OiBcIm1ldGhvZFwiLCBjbGFzc05hbWU6IFwiY29sLW1ldGhvZFwifSwgXCJNZXRob2RcIik7XG4gICAgICAgIH1cbiAgICB9LFxuICAgIHJlbmRlcjogZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgZmxvdyA9IHRoaXMucHJvcHMuZmxvdztcbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJ0ZFwiLCB7Y2xhc3NOYW1lOiBcImNvbC1tZXRob2RcIn0sIGZsb3cucmVxdWVzdC5tZXRob2QpO1xuICAgIH1cbn0pO1xuXG5cbnZhciBTdGF0dXNDb2x1bW4gPSBSZWFjdC5jcmVhdGVDbGFzcyh7ZGlzcGxheU5hbWU6IFwiU3RhdHVzQ29sdW1uXCIsXG4gICAgc3RhdGljczoge1xuICAgICAgICByZW5kZXJUaXRsZTogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJ0aFwiLCB7a2V5OiBcInN0YXR1c1wiLCBjbGFzc05hbWU6IFwiY29sLXN0YXR1c1wifSwgXCJTdGF0dXNcIik7XG4gICAgICAgIH1cbiAgICB9LFxuICAgIHJlbmRlcjogZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgZmxvdyA9IHRoaXMucHJvcHMuZmxvdztcbiAgICAgICAgdmFyIHN0YXR1cztcbiAgICAgICAgaWYgKGZsb3cucmVzcG9uc2UpIHtcbiAgICAgICAgICAgIHN0YXR1cyA9IGZsb3cucmVzcG9uc2UuY29kZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHN0YXR1cyA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJ0ZFwiLCB7Y2xhc3NOYW1lOiBcImNvbC1zdGF0dXNcIn0sIHN0YXR1cyk7XG4gICAgfVxufSk7XG5cblxudmFyIFNpemVDb2x1bW4gPSBSZWFjdC5jcmVhdGVDbGFzcyh7ZGlzcGxheU5hbWU6IFwiU2l6ZUNvbHVtblwiLFxuICAgIHN0YXRpY3M6IHtcbiAgICAgICAgcmVuZGVyVGl0bGU6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFwidGhcIiwge2tleTogXCJzaXplXCIsIGNsYXNzTmFtZTogXCJjb2wtc2l6ZVwifSwgXCJTaXplXCIpO1xuICAgICAgICB9XG4gICAgfSxcbiAgICByZW5kZXI6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGZsb3cgPSB0aGlzLnByb3BzLmZsb3c7XG5cbiAgICAgICAgdmFyIHRvdGFsID0gZmxvdy5yZXF1ZXN0LmNvbnRlbnRMZW5ndGg7XG4gICAgICAgIGlmIChmbG93LnJlc3BvbnNlKSB7XG4gICAgICAgICAgICB0b3RhbCArPSBmbG93LnJlc3BvbnNlLmNvbnRlbnRMZW5ndGggfHwgMDtcbiAgICAgICAgfVxuICAgICAgICB2YXIgc2l6ZSA9IHV0aWxzLmZvcm1hdFNpemUodG90YWwpO1xuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcInRkXCIsIHtjbGFzc05hbWU6IFwiY29sLXNpemVcIn0sIHNpemUpO1xuICAgIH1cbn0pO1xuXG5cbnZhciBUaW1lQ29sdW1uID0gUmVhY3QuY3JlYXRlQ2xhc3Moe2Rpc3BsYXlOYW1lOiBcIlRpbWVDb2x1bW5cIixcbiAgICBzdGF0aWNzOiB7XG4gICAgICAgIHJlbmRlclRpdGxlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcInRoXCIsIHtrZXk6IFwidGltZVwiLCBjbGFzc05hbWU6IFwiY29sLXRpbWVcIn0sIFwiVGltZVwiKTtcbiAgICAgICAgfVxuICAgIH0sXG4gICAgcmVuZGVyOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBmbG93ID0gdGhpcy5wcm9wcy5mbG93O1xuICAgICAgICB2YXIgdGltZTtcbiAgICAgICAgaWYgKGZsb3cucmVzcG9uc2UpIHtcbiAgICAgICAgICAgIHRpbWUgPSB1dGlscy5mb3JtYXRUaW1lRGVsdGEoMTAwMCAqIChmbG93LnJlc3BvbnNlLnRpbWVzdGFtcF9lbmQgLSBmbG93LnJlcXVlc3QudGltZXN0YW1wX3N0YXJ0KSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aW1lID0gXCIuLi5cIjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcInRkXCIsIHtjbGFzc05hbWU6IFwiY29sLXRpbWVcIn0sIHRpbWUpO1xuICAgIH1cbn0pO1xuXG5cbnZhciBhbGxfY29sdW1ucyA9IFtcbiAgICBUTFNDb2x1bW4sXG4gICAgSWNvbkNvbHVtbixcbiAgICBQYXRoQ29sdW1uLFxuICAgIE1ldGhvZENvbHVtbixcbiAgICBTdGF0dXNDb2x1bW4sXG4gICAgU2l6ZUNvbHVtbixcbiAgICBUaW1lQ29sdW1uXTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IGFsbF9jb2x1bW5zO1xuXG5cbiIsInZhciBSZWFjdCA9IHJlcXVpcmUoXCJyZWFjdFwiKTtcbnZhciB1dGlscyA9IHJlcXVpcmUoXCIuL3V0aWxzLmpzXCIpO1xudmFyIFZpcnR1YWxTY3JvbGxNaXhpbiA9IHJlcXVpcmUoXCIuL3ZpcnR1YWxzY3JvbGwuanNcIik7XG52YXIgZmxvd3RhYmxlX2NvbHVtbnMgPSByZXF1aXJlKFwiLi9mbG93dGFibGUtY29sdW1ucy5qc1wiKTtcblxudmFyIEZsb3dSb3cgPSBSZWFjdC5jcmVhdGVDbGFzcyh7ZGlzcGxheU5hbWU6IFwiRmxvd1Jvd1wiLFxuICAgIHJlbmRlcjogZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgZmxvdyA9IHRoaXMucHJvcHMuZmxvdztcbiAgICAgICAgdmFyIGNvbHVtbnMgPSB0aGlzLnByb3BzLmNvbHVtbnMubWFwKGZ1bmN0aW9uIChDb2x1bW4pIHtcbiAgICAgICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KENvbHVtbiwge2tleTogQ29sdW1uLmRpc3BsYXlOYW1lLCBmbG93OiBmbG93fSk7XG4gICAgICAgIH0uYmluZCh0aGlzKSk7XG4gICAgICAgIHZhciBjbGFzc05hbWUgPSBcIlwiO1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5zZWxlY3RlZCkge1xuICAgICAgICAgICAgY2xhc3NOYW1lICs9IFwiIHNlbGVjdGVkXCI7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMucHJvcHMuaGlnaGxpZ2h0ZWQpIHtcbiAgICAgICAgICAgIGNsYXNzTmFtZSArPSBcIiBoaWdobGlnaHRlZFwiO1xuICAgICAgICB9XG4gICAgICAgIGlmIChmbG93LmludGVyY2VwdGVkKSB7XG4gICAgICAgICAgICBjbGFzc05hbWUgKz0gXCIgaW50ZXJjZXB0ZWRcIjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZmxvdy5yZXF1ZXN0KSB7XG4gICAgICAgICAgICBjbGFzc05hbWUgKz0gXCIgaGFzLXJlcXVlc3RcIjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZmxvdy5yZXNwb25zZSkge1xuICAgICAgICAgICAgY2xhc3NOYW1lICs9IFwiIGhhcy1yZXNwb25zZVwiO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJ0clwiLCB7Y2xhc3NOYW1lOiBjbGFzc05hbWUsIG9uQ2xpY2s6IHRoaXMucHJvcHMuc2VsZWN0Rmxvdy5iaW5kKG51bGwsIGZsb3cpfSwgXG4gICAgICAgICAgICAgICAgY29sdW1uc1xuICAgICAgICAgICAgKSk7XG4gICAgfSxcbiAgICBzaG91bGRDb21wb25lbnRVcGRhdGU6IGZ1bmN0aW9uIChuZXh0UHJvcHMpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIC8vIEZ1cnRoZXIgb3B0aW1pemF0aW9uIGNvdWxkIGJlIGRvbmUgaGVyZVxuICAgICAgICAvLyBieSBjYWxsaW5nIGZvcmNlVXBkYXRlIG9uIGZsb3cgdXBkYXRlcywgc2VsZWN0aW9uIGNoYW5nZXMgYW5kIGNvbHVtbiBjaGFuZ2VzLlxuICAgICAgICAvL3JldHVybiAoXG4gICAgICAgIC8vKHRoaXMucHJvcHMuY29sdW1ucy5sZW5ndGggIT09IG5leHRQcm9wcy5jb2x1bW5zLmxlbmd0aCkgfHxcbiAgICAgICAgLy8odGhpcy5wcm9wcy5zZWxlY3RlZCAhPT0gbmV4dFByb3BzLnNlbGVjdGVkKVxuICAgICAgICAvLyk7XG4gICAgfVxufSk7XG5cbnZhciBGbG93VGFibGVIZWFkID0gUmVhY3QuY3JlYXRlQ2xhc3Moe2Rpc3BsYXlOYW1lOiBcIkZsb3dUYWJsZUhlYWRcIixcbiAgICByZW5kZXI6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGNvbHVtbnMgPSB0aGlzLnByb3BzLmNvbHVtbnMubWFwKGZ1bmN0aW9uIChjb2x1bW4pIHtcbiAgICAgICAgICAgIHJldHVybiBjb2x1bW4ucmVuZGVyVGl0bGUoKTtcbiAgICAgICAgfS5iaW5kKHRoaXMpKTtcbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJ0aGVhZFwiLCBudWxsLCBcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJ0clwiLCBudWxsLCBjb2x1bW5zKVxuICAgICAgICApO1xuICAgIH1cbn0pO1xuXG5cbnZhciBST1dfSEVJR0hUID0gMzI7XG5cbnZhciBGbG93VGFibGUgPSBSZWFjdC5jcmVhdGVDbGFzcyh7ZGlzcGxheU5hbWU6IFwiRmxvd1RhYmxlXCIsXG4gICAgbWl4aW5zOiBbdXRpbHMuU3RpY2t5SGVhZE1peGluLCB1dGlscy5BdXRvU2Nyb2xsTWl4aW4sIFZpcnR1YWxTY3JvbGxNaXhpbl0sXG4gICAgZ2V0SW5pdGlhbFN0YXRlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBjb2x1bW5zOiBmbG93dGFibGVfY29sdW1uc1xuICAgICAgICB9O1xuICAgIH0sXG4gICAgY29tcG9uZW50V2lsbE1vdW50OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLnByb3BzLnZpZXcpIHtcbiAgICAgICAgICAgIHRoaXMucHJvcHMudmlldy5hZGRMaXN0ZW5lcihcImFkZCB1cGRhdGUgcmVtb3ZlIHJlY2FsY3VsYXRlXCIsIHRoaXMub25DaGFuZ2UpO1xuICAgICAgICB9XG4gICAgfSxcbiAgICBjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzOiBmdW5jdGlvbiAobmV4dFByb3BzKSB7XG4gICAgICAgIGlmIChuZXh0UHJvcHMudmlldyAhPT0gdGhpcy5wcm9wcy52aWV3KSB7XG4gICAgICAgICAgICBpZiAodGhpcy5wcm9wcy52aWV3KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5wcm9wcy52aWV3LnJlbW92ZUxpc3RlbmVyKFwiYWRkIHVwZGF0ZSByZW1vdmUgcmVjYWxjdWxhdGVcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBuZXh0UHJvcHMudmlldy5hZGRMaXN0ZW5lcihcImFkZCB1cGRhdGUgcmVtb3ZlIHJlY2FsY3VsYXRlXCIsIHRoaXMub25DaGFuZ2UpO1xuICAgICAgICB9XG4gICAgfSxcbiAgICBnZXREZWZhdWx0UHJvcHM6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHJvd0hlaWdodDogUk9XX0hFSUdIVFxuICAgICAgICB9O1xuICAgIH0sXG4gICAgb25TY3JvbGxGbG93VGFibGU6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5hZGp1c3RIZWFkKCk7XG4gICAgICAgIHRoaXMub25TY3JvbGwoKTtcbiAgICB9LFxuICAgIG9uQ2hhbmdlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuZm9yY2VVcGRhdGUoKTtcbiAgICB9LFxuICAgIHNjcm9sbEludG9WaWV3OiBmdW5jdGlvbiAoZmxvdykge1xuICAgICAgICB0aGlzLnNjcm9sbFJvd0ludG9WaWV3KFxuICAgICAgICAgICAgdGhpcy5wcm9wcy52aWV3LmluZGV4KGZsb3cpLFxuICAgICAgICAgICAgdGhpcy5yZWZzLmJvZHkuZ2V0RE9NTm9kZSgpLm9mZnNldFRvcFxuICAgICAgICApO1xuICAgIH0sXG4gICAgcmVuZGVyUm93OiBmdW5jdGlvbiAoZmxvdykge1xuICAgICAgICB2YXIgc2VsZWN0ZWQgPSAoZmxvdyA9PT0gdGhpcy5wcm9wcy5zZWxlY3RlZCk7XG4gICAgICAgIHZhciBoaWdobGlnaHRlZCA9XG4gICAgICAgICAgICAoXG4gICAgICAgICAgICB0aGlzLnByb3BzLnZpZXcuX2hpZ2hsaWdodCAmJlxuICAgICAgICAgICAgdGhpcy5wcm9wcy52aWV3Ll9oaWdobGlnaHRbZmxvdy5pZF1cbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoRmxvd1Jvdywge2tleTogZmxvdy5pZCwgXG4gICAgICAgICAgICByZWY6IGZsb3cuaWQsIFxuICAgICAgICAgICAgZmxvdzogZmxvdywgXG4gICAgICAgICAgICBjb2x1bW5zOiB0aGlzLnN0YXRlLmNvbHVtbnMsIFxuICAgICAgICAgICAgc2VsZWN0ZWQ6IHNlbGVjdGVkLCBcbiAgICAgICAgICAgIGhpZ2hsaWdodGVkOiBoaWdobGlnaHRlZCwgXG4gICAgICAgICAgICBzZWxlY3RGbG93OiB0aGlzLnByb3BzLnNlbGVjdEZsb3d9XG4gICAgICAgICk7XG4gICAgfSxcbiAgICByZW5kZXI6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy9jb25zb2xlLmxvZyhcInJlbmRlciBmbG93dGFibGVcIiwgdGhpcy5zdGF0ZS5zdGFydCwgdGhpcy5zdGF0ZS5zdG9wLCB0aGlzLnByb3BzLnNlbGVjdGVkKTtcbiAgICAgICAgdmFyIGZsb3dzID0gdGhpcy5wcm9wcy52aWV3ID8gdGhpcy5wcm9wcy52aWV3Lmxpc3QgOiBbXTtcblxuICAgICAgICB2YXIgcm93cyA9IHRoaXMucmVuZGVyUm93cyhmbG93cyk7XG5cbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwge2NsYXNzTmFtZTogXCJmbG93LXRhYmxlXCIsIG9uU2Nyb2xsOiB0aGlzLm9uU2Nyb2xsRmxvd1RhYmxlfSwgXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcInRhYmxlXCIsIG51bGwsIFxuICAgICAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KEZsb3dUYWJsZUhlYWQsIHtyZWY6IFwiaGVhZFwiLCBcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbHVtbnM6IHRoaXMuc3RhdGUuY29sdW1uc30pLCBcbiAgICAgICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcInRib2R5XCIsIHtyZWY6IFwiYm9keVwifSwgXG4gICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5nZXRQbGFjZWhvbGRlclRvcChmbG93cy5sZW5ndGgpLCBcbiAgICAgICAgICAgICAgICAgICAgICAgIHJvd3MsIFxuICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZ2V0UGxhY2Vob2xkZXJCb3R0b20oZmxvd3MubGVuZ3RoKSBcbiAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICB9XG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSBGbG93VGFibGU7XG4iLCJ2YXIgUmVhY3QgPSByZXF1aXJlKFwicmVhY3RcIik7XG5cbnZhciBGb290ZXIgPSBSZWFjdC5jcmVhdGVDbGFzcyh7ZGlzcGxheU5hbWU6IFwiRm9vdGVyXCIsXG4gICAgcmVuZGVyOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBtb2RlID0gdGhpcy5wcm9wcy5zZXR0aW5ncy5tb2RlO1xuICAgICAgICB2YXIgaW50ZXJjZXB0ID0gdGhpcy5wcm9wcy5zZXR0aW5ncy5pbnRlcmNlcHQ7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFwiZm9vdGVyXCIsIG51bGwsIFxuICAgICAgICAgICAgICAgIG1vZGUgIT0gXCJyZWd1bGFyXCIgPyBSZWFjdC5jcmVhdGVFbGVtZW50KFwic3BhblwiLCB7Y2xhc3NOYW1lOiBcImxhYmVsIGxhYmVsLXN1Y2Nlc3NcIn0sIG1vZGUsIFwiIG1vZGVcIikgOiBudWxsLCBcbiAgICAgICAgICAgICAgICBcIsKgXCIsIFxuICAgICAgICAgICAgICAgIGludGVyY2VwdCA/IFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJzcGFuXCIsIHtjbGFzc05hbWU6IFwibGFiZWwgbGFiZWwtc3VjY2Vzc1wifSwgXCJJbnRlcmNlcHQ6IFwiLCBpbnRlcmNlcHQpIDogbnVsbFxuICAgICAgICAgICAgKVxuICAgICAgICApO1xuICAgIH1cbn0pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IEZvb3RlcjsiLCJ2YXIgUmVhY3QgPSByZXF1aXJlKFwicmVhY3RcIik7XG52YXIgJCA9IHJlcXVpcmUoXCJqcXVlcnlcIik7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoXCIuL3V0aWxzLmpzXCIpO1xuXG52YXIgRmlsdGVyRG9jcyA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtkaXNwbGF5TmFtZTogXCJGaWx0ZXJEb2NzXCIsXG4gICAgc3RhdGljczoge1xuICAgICAgICB4aHI6IGZhbHNlLFxuICAgICAgICBkb2M6IGZhbHNlXG4gICAgfSxcbiAgICBjb21wb25lbnRXaWxsTW91bnQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKCFGaWx0ZXJEb2NzLmRvYykge1xuICAgICAgICAgICAgRmlsdGVyRG9jcy54aHIgPSAkLmdldEpTT04oXCIvZmlsdGVyLWhlbHBcIikuZG9uZShmdW5jdGlvbiAoZG9jKSB7XG4gICAgICAgICAgICAgICAgRmlsdGVyRG9jcy5kb2MgPSBkb2M7XG4gICAgICAgICAgICAgICAgRmlsdGVyRG9jcy54aHIgPSBmYWxzZTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChGaWx0ZXJEb2NzLnhocikge1xuICAgICAgICAgICAgRmlsdGVyRG9jcy54aHIuZG9uZShmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5mb3JjZVVwZGF0ZSgpO1xuICAgICAgICAgICAgfS5iaW5kKHRoaXMpKTtcbiAgICAgICAgfVxuICAgIH0sXG4gICAgcmVuZGVyOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICghRmlsdGVyRG9jcy5kb2MpIHtcbiAgICAgICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFwiaVwiLCB7Y2xhc3NOYW1lOiBcImZhIGZhLXNwaW5uZXIgZmEtc3BpblwifSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2YXIgY29tbWFuZHMgPSBGaWx0ZXJEb2NzLmRvYy5jb21tYW5kcy5tYXAoZnVuY3Rpb24gKGMpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcInRyXCIsIG51bGwsIFxuICAgICAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFwidGRcIiwgbnVsbCwgY1swXS5yZXBsYWNlKFwiIFwiLCAnXFx1MDBhMCcpKSwgXG4gICAgICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJ0ZFwiLCBudWxsLCBjWzFdKVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNvbW1hbmRzLnB1c2goUmVhY3QuY3JlYXRlRWxlbWVudChcInRyXCIsIG51bGwsIFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJ0ZFwiLCB7Y29sU3BhbjogXCIyXCJ9LCBcbiAgICAgICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcImFcIiwge2hyZWY6IFwiaHR0cHM6Ly9taXRtcHJveHkub3JnL2RvYy9mZWF0dXJlcy9maWx0ZXJzLmh0bWxcIiwgXG4gICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXQ6IFwiX2JsYW5rXCJ9LCBcbiAgICAgICAgICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJpXCIsIHtjbGFzc05hbWU6IFwiZmEgZmEtZXh0ZXJuYWwtbGlua1wifSksIFxuICAgICAgICAgICAgICAgICAgICBcIsKgIG1pdG1wcm94eSBkb2NzXCIpXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKSk7XG4gICAgICAgICAgICByZXR1cm4gUmVhY3QuY3JlYXRlRWxlbWVudChcInRhYmxlXCIsIHtjbGFzc05hbWU6IFwidGFibGUgdGFibGUtY29uZGVuc2VkXCJ9LCBcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFwidGJvZHlcIiwgbnVsbCwgY29tbWFuZHMpXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgfVxufSk7XG52YXIgRmlsdGVySW5wdXQgPSBSZWFjdC5jcmVhdGVDbGFzcyh7ZGlzcGxheU5hbWU6IFwiRmlsdGVySW5wdXRcIixcbiAgICBnZXRJbml0aWFsU3RhdGU6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgLy8gQ29uc2lkZXIgYm90aCBmb2N1cyBhbmQgbW91c2VvdmVyIGZvciBzaG93aW5nL2hpZGluZyB0aGUgdG9vbHRpcCxcbiAgICAgICAgLy8gYmVjYXVzZSBvbkJsdXIgb2YgdGhlIGlucHV0IGlzIHRyaWdnZXJlZCBiZWZvcmUgdGhlIGNsaWNrIG9uIHRoZSB0b29sdGlwXG4gICAgICAgIC8vIGZpbmFsaXplZCwgaGlkaW5nIHRoZSB0b29sdGlwIGp1c3QgYXMgdGhlIHVzZXIgY2xpY2tzIG9uIGl0LlxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdmFsdWU6IHRoaXMucHJvcHMudmFsdWUsXG4gICAgICAgICAgICBmb2N1czogZmFsc2UsXG4gICAgICAgICAgICBtb3VzZWZvY3VzOiBmYWxzZVxuICAgICAgICB9O1xuICAgIH0sXG4gICAgY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wczogZnVuY3Rpb24gKG5leHRQcm9wcykge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHt2YWx1ZTogbmV4dFByb3BzLnZhbHVlfSk7XG4gICAgfSxcbiAgICBvbkNoYW5nZTogZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgdmFyIG5leHRWYWx1ZSA9IGUudGFyZ2V0LnZhbHVlO1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIHZhbHVlOiBuZXh0VmFsdWVcbiAgICAgICAgfSk7XG4gICAgICAgIC8vIE9ubHkgcHJvcGFnYXRlIHZhbGlkIGZpbHRlcnMgdXB3YXJkcy5cbiAgICAgICAgaWYgKHRoaXMuaXNWYWxpZChuZXh0VmFsdWUpKSB7XG4gICAgICAgICAgICB0aGlzLnByb3BzLm9uQ2hhbmdlKG5leHRWYWx1ZSk7XG4gICAgICAgIH1cbiAgICB9LFxuICAgIGlzVmFsaWQ6IGZ1bmN0aW9uIChmaWx0KSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBGaWx0LnBhcnNlKGZpbHQgfHwgdGhpcy5zdGF0ZS52YWx1ZSk7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfSxcbiAgICBnZXREZXNjOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBkZXNjO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgZGVzYyA9IEZpbHQucGFyc2UodGhpcy5zdGF0ZS52YWx1ZSkuZGVzYztcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgZGVzYyA9IFwiXCIgKyBlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChkZXNjICE9PSBcInRydWVcIikge1xuICAgICAgICAgICAgcmV0dXJuIGRlc2M7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoRmlsdGVyRG9jcywgbnVsbClcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICB9LFxuICAgIG9uRm9jdXM6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7Zm9jdXM6IHRydWV9KTtcbiAgICB9LFxuICAgIG9uQmx1cjogZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtmb2N1czogZmFsc2V9KTtcbiAgICB9LFxuICAgIG9uTW91c2VFbnRlcjogZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHttb3VzZWZvY3VzOiB0cnVlfSk7XG4gICAgfSxcbiAgICBvbk1vdXNlTGVhdmU6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7bW91c2Vmb2N1czogZmFsc2V9KTtcbiAgICB9LFxuICAgIG9uS2V5RG93bjogZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgaWYgKGUua2V5Q29kZSA9PT0gS2V5LkVTQyB8fCBlLmtleUNvZGUgPT09IEtleS5FTlRFUikge1xuICAgICAgICAgICAgdGhpcy5ibHVyKCk7XG4gICAgICAgICAgICAvLyBJZiBjbG9zZWQgdXNpbmcgRVNDL0VOVEVSLCBoaWRlIHRoZSB0b29sdGlwLlxuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7bW91c2Vmb2N1czogZmFsc2V9KTtcbiAgICAgICAgfVxuICAgIH0sXG4gICAgYmx1cjogZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnJlZnMuaW5wdXQuZ2V0RE9NTm9kZSgpLmJsdXIoKTtcbiAgICB9LFxuICAgIGZvY3VzOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMucmVmcy5pbnB1dC5nZXRET01Ob2RlKCkuc2VsZWN0KCk7XG4gICAgfSxcbiAgICByZW5kZXI6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGlzVmFsaWQgPSB0aGlzLmlzVmFsaWQoKTtcbiAgICAgICAgdmFyIGljb24gPSBcImZhIGZhLWZ3IGZhLVwiICsgdGhpcy5wcm9wcy50eXBlO1xuICAgICAgICB2YXIgZ3JvdXBDbGFzc05hbWUgPSBcImZpbHRlci1pbnB1dCBpbnB1dC1ncm91cFwiICsgKGlzVmFsaWQgPyBcIlwiIDogXCIgaGFzLWVycm9yXCIpO1xuXG4gICAgICAgIHZhciBwb3BvdmVyO1xuICAgICAgICBpZiAodGhpcy5zdGF0ZS5mb2N1cyB8fCB0aGlzLnN0YXRlLm1vdXNlZm9jdXMpIHtcbiAgICAgICAgICAgIHBvcG92ZXIgPSAoXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcImRpdlwiLCB7Y2xhc3NOYW1lOiBcInBvcG92ZXIgYm90dG9tXCIsIG9uTW91c2VFbnRlcjogdGhpcy5vbk1vdXNlRW50ZXIsIG9uTW91c2VMZWF2ZTogdGhpcy5vbk1vdXNlTGVhdmV9LCBcbiAgICAgICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcImRpdlwiLCB7Y2xhc3NOYW1lOiBcImFycm93XCJ9KSwgXG4gICAgICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwge2NsYXNzTmFtZTogXCJwb3BvdmVyLWNvbnRlbnRcIn0sIFxuICAgICAgICAgICAgICAgICAgICB0aGlzLmdldERlc2MoKVxuICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFwiZGl2XCIsIHtjbGFzc05hbWU6IGdyb3VwQ2xhc3NOYW1lfSwgXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcInNwYW5cIiwge2NsYXNzTmFtZTogXCJpbnB1dC1ncm91cC1hZGRvblwifSwgXG4gICAgICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJpXCIsIHtjbGFzc05hbWU6IGljb24sIHN0eWxlOiB7Y29sb3I6IHRoaXMucHJvcHMuY29sb3J9fSlcbiAgICAgICAgICAgICAgICApLCBcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFwiaW5wdXRcIiwge3R5cGU6IFwidGV4dFwiLCBwbGFjZWhvbGRlcjogdGhpcy5wcm9wcy5wbGFjZWhvbGRlciwgY2xhc3NOYW1lOiBcImZvcm0tY29udHJvbFwiLCBcbiAgICAgICAgICAgICAgICAgICAgcmVmOiBcImlucHV0XCIsIFxuICAgICAgICAgICAgICAgICAgICBvbkNoYW5nZTogdGhpcy5vbkNoYW5nZSwgXG4gICAgICAgICAgICAgICAgICAgIG9uRm9jdXM6IHRoaXMub25Gb2N1cywgXG4gICAgICAgICAgICAgICAgICAgIG9uQmx1cjogdGhpcy5vbkJsdXIsIFxuICAgICAgICAgICAgICAgICAgICBvbktleURvd246IHRoaXMub25LZXlEb3duLCBcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU6IHRoaXMuc3RhdGUudmFsdWV9KSwgXG4gICAgICAgICAgICAgICAgcG9wb3ZlclxuICAgICAgICAgICAgKVxuICAgICAgICApO1xuICAgIH1cbn0pO1xuXG52YXIgTWFpbk1lbnUgPSBSZWFjdC5jcmVhdGVDbGFzcyh7ZGlzcGxheU5hbWU6IFwiTWFpbk1lbnVcIixcbiAgICBtaXhpbnM6IFt1dGlscy5OYXZpZ2F0aW9uLCB1dGlscy5TdGF0ZV0sXG4gICAgc3RhdGljczoge1xuICAgICAgICB0aXRsZTogXCJTdGFydFwiLFxuICAgICAgICByb3V0ZTogXCJmbG93c1wiXG4gICAgfSxcbiAgICBvbkZpbHRlckNoYW5nZTogZnVuY3Rpb24gKHZhbCkge1xuICAgICAgICB2YXIgZCA9IHt9O1xuICAgICAgICBkW1F1ZXJ5LkZJTFRFUl0gPSB2YWw7XG4gICAgICAgIHRoaXMuc2V0UXVlcnkoZCk7XG4gICAgfSxcbiAgICBvbkhpZ2hsaWdodENoYW5nZTogZnVuY3Rpb24gKHZhbCkge1xuICAgICAgICB2YXIgZCA9IHt9O1xuICAgICAgICBkW1F1ZXJ5LkhJR0hMSUdIVF0gPSB2YWw7XG4gICAgICAgIHRoaXMuc2V0UXVlcnkoZCk7XG4gICAgfSxcbiAgICBvbkludGVyY2VwdENoYW5nZTogZnVuY3Rpb24gKHZhbCkge1xuICAgICAgICBTZXR0aW5nc0FjdGlvbnMudXBkYXRlKHtpbnRlcmNlcHQ6IHZhbH0pO1xuICAgIH0sXG4gICAgcmVuZGVyOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBmaWx0ZXIgPSB0aGlzLmdldFF1ZXJ5KClbUXVlcnkuRklMVEVSXSB8fCBcIlwiO1xuICAgICAgICB2YXIgaGlnaGxpZ2h0ID0gdGhpcy5nZXRRdWVyeSgpW1F1ZXJ5LkhJR0hMSUdIVF0gfHwgXCJcIjtcbiAgICAgICAgdmFyIGludGVyY2VwdCA9IHRoaXMucHJvcHMuc2V0dGluZ3MuaW50ZXJjZXB0IHx8IFwiXCI7XG5cbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwgbnVsbCwgXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcImRpdlwiLCB7Y2xhc3NOYW1lOiBcIm1lbnUtcm93XCJ9LCBcbiAgICAgICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChGaWx0ZXJJbnB1dCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI6IFwiRmlsdGVyXCIsIFxuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogXCJmaWx0ZXJcIiwgXG4gICAgICAgICAgICAgICAgICAgICAgICBjb2xvcjogXCJibGFja1wiLCBcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlOiBmaWx0ZXIsIFxuICAgICAgICAgICAgICAgICAgICAgICAgb25DaGFuZ2U6IHRoaXMub25GaWx0ZXJDaGFuZ2V9KSwgXG4gICAgICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoRmlsdGVySW5wdXQsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyOiBcIkhpZ2hsaWdodFwiLCBcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6IFwidGFnXCIsIFxuICAgICAgICAgICAgICAgICAgICAgICAgY29sb3I6IFwiaHNsKDQ4LCAxMDAlLCA1MCUpXCIsIFxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IGhpZ2hsaWdodCwgXG4gICAgICAgICAgICAgICAgICAgICAgICBvbkNoYW5nZTogdGhpcy5vbkhpZ2hsaWdodENoYW5nZX0pLCBcbiAgICAgICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChGaWx0ZXJJbnB1dCwge1xuICAgICAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI6IFwiSW50ZXJjZXB0XCIsIFxuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogXCJwYXVzZVwiLCBcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yOiBcImhzbCgyMDgsIDU2JSwgNTMlKVwiLCBcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlOiBpbnRlcmNlcHQsIFxuICAgICAgICAgICAgICAgICAgICAgICAgb25DaGFuZ2U6IHRoaXMub25JbnRlcmNlcHRDaGFuZ2V9KVxuICAgICAgICAgICAgICAgICksIFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwge2NsYXNzTmFtZTogXCJjbGVhcmZpeFwifSlcbiAgICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICB9XG59KTtcblxuXG52YXIgVmlld01lbnUgPSBSZWFjdC5jcmVhdGVDbGFzcyh7ZGlzcGxheU5hbWU6IFwiVmlld01lbnVcIixcbiAgICBzdGF0aWNzOiB7XG4gICAgICAgIHRpdGxlOiBcIlZpZXdcIixcbiAgICAgICAgcm91dGU6IFwiZmxvd3NcIlxuICAgIH0sXG4gICAgbWl4aW5zOiBbdXRpbHMuTmF2aWdhdGlvbiwgdXRpbHMuU3RhdGVdLFxuICAgIHRvZ2dsZUV2ZW50TG9nOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBkID0ge307XG5cbiAgICAgICAgaWYgKHRoaXMuZ2V0UXVlcnkoKVtRdWVyeS5TSE9XX0VWRU5UTE9HXSkge1xuICAgICAgICAgICAgZFtRdWVyeS5TSE9XX0VWRU5UTE9HXSA9IHVuZGVmaW5lZDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGRbUXVlcnkuU0hPV19FVkVOVExPR10gPSBcInRcIjsgLy8gYW55IG5vbi1mYWxzZSB2YWx1ZSB3aWxsIGRvIGl0LCBrZWVwIGl0IHNob3J0XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnNldFF1ZXJ5KGQpO1xuICAgIH0sXG4gICAgcmVuZGVyOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBzaG93RXZlbnRMb2cgPSB0aGlzLmdldFF1ZXJ5KClbUXVlcnkuU0hPV19FVkVOVExPR107XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFwiZGl2XCIsIG51bGwsIFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJidXR0b25cIiwge1xuICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU6IFwiYnRuIFwiICsgKHNob3dFdmVudExvZyA/IFwiYnRuLXByaW1hcnlcIiA6IFwiYnRuLWRlZmF1bHRcIiksIFxuICAgICAgICAgICAgICAgICAgICBvbkNsaWNrOiB0aGlzLnRvZ2dsZUV2ZW50TG9nfSwgXG4gICAgICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJpXCIsIHtjbGFzc05hbWU6IFwiZmEgZmEtZGF0YWJhc2VcIn0pLCBcbiAgICAgICAgICAgICAgICBcIsKgU2hvdyBFdmVudGxvZ1wiXG4gICAgICAgICAgICAgICAgKSwgXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcInNwYW5cIiwgbnVsbCwgXCIgXCIpXG4gICAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgfVxufSk7XG5cblxudmFyIFJlcG9ydHNNZW51ID0gUmVhY3QuY3JlYXRlQ2xhc3Moe2Rpc3BsYXlOYW1lOiBcIlJlcG9ydHNNZW51XCIsXG4gICAgc3RhdGljczoge1xuICAgICAgICB0aXRsZTogXCJWaXN1YWxpemF0aW9uXCIsXG4gICAgICAgIHJvdXRlOiBcInJlcG9ydHNcIlxuICAgIH0sXG4gICAgcmVuZGVyOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFwiZGl2XCIsIG51bGwsIFwiUmVwb3J0cyBNZW51XCIpO1xuICAgIH1cbn0pO1xuXG52YXIgRmlsZU1lbnUgPSBSZWFjdC5jcmVhdGVDbGFzcyh7ZGlzcGxheU5hbWU6IFwiRmlsZU1lbnVcIixcbiAgICBnZXRJbml0aWFsU3RhdGU6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHNob3dGaWxlTWVudTogZmFsc2VcbiAgICAgICAgfTtcbiAgICB9LFxuICAgIGhhbmRsZUZpbGVDbGljazogZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBpZiAoIXRoaXMuc3RhdGUuc2hvd0ZpbGVNZW51KSB7XG4gICAgICAgICAgICB2YXIgY2xvc2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7c2hvd0ZpbGVNZW51OiBmYWxzZX0pO1xuICAgICAgICAgICAgICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJjbGlja1wiLCBjbG9zZSk7XG4gICAgICAgICAgICB9LmJpbmQodGhpcyk7XG4gICAgICAgICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIiwgY2xvc2UpO1xuXG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgICAgICBzaG93RmlsZU1lbnU6IHRydWVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfSxcbiAgICBoYW5kbGVOZXdDbGljazogZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBpZiAoY29uZmlybShcIkRlbGV0ZSBhbGwgZmxvd3M/XCIpKSB7XG4gICAgICAgICAgICBGbG93QWN0aW9ucy5jbGVhcigpO1xuICAgICAgICB9XG4gICAgfSxcbiAgICBoYW5kbGVPcGVuQ2xpY2s6IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgY29uc29sZS5lcnJvcihcInVuaW1wbGVtZW50ZWQ6IGhhbmRsZU9wZW5DbGlja1wiKTtcbiAgICB9LFxuICAgIGhhbmRsZVNhdmVDbGljazogZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBjb25zb2xlLmVycm9yKFwidW5pbXBsZW1lbnRlZDogaGFuZGxlU2F2ZUNsaWNrXCIpO1xuICAgIH0sXG4gICAgaGFuZGxlU2h1dGRvd25DbGljazogZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBjb25zb2xlLmVycm9yKFwidW5pbXBsZW1lbnRlZDogaGFuZGxlU2h1dGRvd25DbGlja1wiKTtcbiAgICB9LFxuICAgIHJlbmRlcjogZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgZmlsZU1lbnVDbGFzcyA9IFwiZHJvcGRvd24gcHVsbC1sZWZ0XCIgKyAodGhpcy5zdGF0ZS5zaG93RmlsZU1lbnUgPyBcIiBvcGVuXCIgOiBcIlwiKTtcblxuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcImRpdlwiLCB7Y2xhc3NOYW1lOiBmaWxlTWVudUNsYXNzfSwgXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcImFcIiwge2hyZWY6IFwiI1wiLCBjbGFzc05hbWU6IFwic3BlY2lhbFwiLCBvbkNsaWNrOiB0aGlzLmhhbmRsZUZpbGVDbGlja30sIFwiIEZpbGUgXCIpLCBcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFwidWxcIiwge2NsYXNzTmFtZTogXCJkcm9wZG93bi1tZW51XCIsIHJvbGU6IFwibWVudVwifSwgXG4gICAgICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJsaVwiLCBudWxsLCBcbiAgICAgICAgICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJhXCIsIHtocmVmOiBcIiNcIiwgb25DbGljazogdGhpcy5oYW5kbGVOZXdDbGlja30sIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJpXCIsIHtjbGFzc05hbWU6IFwiZmEgZmEtZncgZmEtZmlsZVwifSksIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiTmV3XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgKSwgXG4gICAgICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJsaVwiLCB7cm9sZTogXCJwcmVzZW50YXRpb25cIiwgY2xhc3NOYW1lOiBcImRpdmlkZXJcIn0pLCBcbiAgICAgICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcImxpXCIsIG51bGwsIFxuICAgICAgICAgICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcImFcIiwge2hyZWY6IFwiaHR0cDovL21pdG0uaXQvXCIsIHRhcmdldDogXCJfYmxhbmtcIn0sIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJpXCIsIHtjbGFzc05hbWU6IFwiZmEgZmEtZncgZmEtZXh0ZXJuYWwtbGlua1wifSksIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiSW5zdGFsbCBDZXJ0aWZpY2F0ZXMuLi5cIlxuICAgICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgLypcbiAgICAgICAgICAgICAgICAgPGxpPlxuICAgICAgICAgICAgICAgICA8YSBocmVmPVwiI1wiIG9uQ2xpY2s9e3RoaXMuaGFuZGxlT3BlbkNsaWNrfT5cbiAgICAgICAgICAgICAgICAgPGkgY2xhc3NOYW1lPVwiZmEgZmEtZncgZmEtZm9sZGVyLW9wZW5cIj48L2k+XG4gICAgICAgICAgICAgICAgIE9wZW5cbiAgICAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICAgICA8L2xpPlxuICAgICAgICAgICAgICAgICA8bGk+XG4gICAgICAgICAgICAgICAgIDxhIGhyZWY9XCIjXCIgb25DbGljaz17dGhpcy5oYW5kbGVTYXZlQ2xpY2t9PlxuICAgICAgICAgICAgICAgICA8aSBjbGFzc05hbWU9XCJmYSBmYS1mdyBmYS1zYXZlXCI+PC9pPlxuICAgICAgICAgICAgICAgICBTYXZlXG4gICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICAgICAgICAgPGxpIHJvbGU9XCJwcmVzZW50YXRpb25cIiBjbGFzc05hbWU9XCJkaXZpZGVyXCI+PC9saT5cbiAgICAgICAgICAgICAgICAgPGxpPlxuICAgICAgICAgICAgICAgICA8YSBocmVmPVwiI1wiIG9uQ2xpY2s9e3RoaXMuaGFuZGxlU2h1dGRvd25DbGlja30+XG4gICAgICAgICAgICAgICAgIDxpIGNsYXNzTmFtZT1cImZhIGZhLWZ3IGZhLXBsdWdcIj48L2k+XG4gICAgICAgICAgICAgICAgIFNodXRkb3duXG4gICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICAgICAgICAgKi9cbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgfVxufSk7XG5cblxudmFyIGhlYWRlcl9lbnRyaWVzID0gW01haW5NZW51LCBWaWV3TWVudSAvKiwgUmVwb3J0c01lbnUgKi9dO1xuXG5cbnZhciBIZWFkZXIgPSBSZWFjdC5jcmVhdGVDbGFzcyh7ZGlzcGxheU5hbWU6IFwiSGVhZGVyXCIsXG4gICAgbWl4aW5zOiBbdXRpbHMuTmF2aWdhdGlvbl0sXG4gICAgZ2V0SW5pdGlhbFN0YXRlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBhY3RpdmU6IGhlYWRlcl9lbnRyaWVzWzBdXG4gICAgICAgIH07XG4gICAgfSxcbiAgICBoYW5kbGVDbGljazogZnVuY3Rpb24gKGFjdGl2ZSwgZSkge1xuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIHRoaXMucmVwbGFjZVdpdGgoYWN0aXZlLnJvdXRlKTtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7YWN0aXZlOiBhY3RpdmV9KTtcbiAgICB9LFxuICAgIHJlbmRlcjogZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgaGVhZGVyID0gaGVhZGVyX2VudHJpZXMubWFwKGZ1bmN0aW9uIChlbnRyeSwgaSkge1xuICAgICAgICAgICAgdmFyIGNsYXNzZXMgPSBSZWFjdC5hZGRvbnMuY2xhc3NTZXQoe1xuICAgICAgICAgICAgICAgIGFjdGl2ZTogZW50cnkgPT0gdGhpcy5zdGF0ZS5hY3RpdmVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFwiYVwiLCB7a2V5OiBpLCBcbiAgICAgICAgICAgICAgICAgICAgaHJlZjogXCIjXCIsIFxuICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU6IGNsYXNzZXMsIFxuICAgICAgICAgICAgICAgICAgICBvbkNsaWNrOiB0aGlzLmhhbmRsZUNsaWNrLmJpbmQodGhpcywgZW50cnkpXG4gICAgICAgICAgICAgICAgfSwgXG4gICAgICAgICAgICAgICAgICAgICBlbnRyeS50aXRsZVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICk7XG4gICAgICAgIH0uYmluZCh0aGlzKSk7XG5cbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJoZWFkZXJcIiwgbnVsbCwgXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcImRpdlwiLCB7Y2xhc3NOYW1lOiBcInRpdGxlLWJhclwifSwgXG4gICAgICAgICAgICAgICAgICAgIFwibWl0bXByb3h5IFwiLCAgdGhpcy5wcm9wcy5zZXR0aW5ncy52ZXJzaW9uXG4gICAgICAgICAgICAgICAgKSwgXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcIm5hdlwiLCB7Y2xhc3NOYW1lOiBcIm5hdi10YWJzIG5hdi10YWJzLWxnXCJ9LCBcbiAgICAgICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChGaWxlTWVudSwgbnVsbCksIFxuICAgICAgICAgICAgICAgICAgICBoZWFkZXJcbiAgICAgICAgICAgICAgICApLCBcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFwiZGl2XCIsIHtjbGFzc05hbWU6IFwibWVudVwifSwgXG4gICAgICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQodGhpcy5zdGF0ZS5hY3RpdmUsIHtzZXR0aW5nczogdGhpcy5wcm9wcy5zZXR0aW5nc30pXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgKVxuICAgICAgICApO1xuICAgIH1cbn0pO1xuXG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICAgIEhlYWRlcjogSGVhZGVyXG59IiwidmFyIFJlYWN0ID0gcmVxdWlyZShcInJlYWN0XCIpO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKFwiLi91dGlscy5qc1wiKTtcbnZhciB0b3B1dGlscyA9IHJlcXVpcmUoXCIuLi91dGlscy5qc1wiKTtcbnZhciB2aWV3cyA9IHJlcXVpcmUoXCIuLi9zdG9yZS92aWV3LmpzXCIpO1xudmFyIEZpbHQgPSByZXF1aXJlKFwiLi4vZmlsdC9maWx0LmpzXCIpO1xuRmxvd1RhYmxlID0gcmVxdWlyZShcIi4vZmxvd3RhYmxlLmpzXCIpO1xudmFyIGZsb3dkZXRhaWwgPSByZXF1aXJlKFwiLi9mbG93ZGV0YWlsLmpzXCIpO1xuXG5cbnZhciBNYWluVmlldyA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtkaXNwbGF5TmFtZTogXCJNYWluVmlld1wiLFxuICAgIG1peGluczogW3V0aWxzLk5hdmlnYXRpb24sIHV0aWxzLlN0YXRlXSxcbiAgICBnZXRJbml0aWFsU3RhdGU6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5vblF1ZXJ5Q2hhbmdlKFF1ZXJ5LkZJTFRFUiwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdGhpcy5zdGF0ZS52aWV3LnJlY2FsY3VsYXRlKHRoaXMuZ2V0Vmlld0ZpbHQoKSwgdGhpcy5nZXRWaWV3U29ydCgpKTtcbiAgICAgICAgfS5iaW5kKHRoaXMpKTtcbiAgICAgICAgdGhpcy5vblF1ZXJ5Q2hhbmdlKFF1ZXJ5LkhJR0hMSUdIVCwgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdGhpcy5zdGF0ZS52aWV3LnJlY2FsY3VsYXRlKHRoaXMuZ2V0Vmlld0ZpbHQoKSwgdGhpcy5nZXRWaWV3U29ydCgpKTtcbiAgICAgICAgfS5iaW5kKHRoaXMpKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGZsb3dzOiBbXVxuICAgICAgICB9O1xuICAgIH0sXG4gICAgZ2V0Vmlld0ZpbHQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHZhciBmaWx0ID0gRmlsdC5wYXJzZSh0aGlzLmdldFF1ZXJ5KClbUXVlcnkuRklMVEVSXSB8fCBcIlwiKTtcbiAgICAgICAgICAgIHZhciBoaWdobGlnaHRTdHIgPSB0aGlzLmdldFF1ZXJ5KClbUXVlcnkuSElHSExJR0hUXTtcbiAgICAgICAgICAgIHZhciBoaWdobGlnaHQgPSBoaWdobGlnaHRTdHIgPyBGaWx0LnBhcnNlKGhpZ2hsaWdodFN0cikgOiBmYWxzZTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yIHdoZW4gcHJvY2Vzc2luZyBmaWx0ZXI6IFwiICsgZSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZnVuY3Rpb24gZmlsdGVyX2FuZF9oaWdobGlnaHQoZmxvdykge1xuICAgICAgICAgICAgaWYgKCF0aGlzLl9oaWdobGlnaHQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9oaWdobGlnaHQgPSB7fTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuX2hpZ2hsaWdodFtmbG93LmlkXSA9IGhpZ2hsaWdodCAmJiBoaWdobGlnaHQoZmxvdyk7XG4gICAgICAgICAgICByZXR1cm4gZmlsdChmbG93KTtcbiAgICAgICAgfTtcbiAgICB9LFxuICAgIGdldFZpZXdTb3J0OiBmdW5jdGlvbiAoKSB7XG4gICAgfSxcbiAgICBjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzOiBmdW5jdGlvbiAobmV4dFByb3BzKSB7XG4gICAgICAgIGlmIChuZXh0UHJvcHMuZmxvd1N0b3JlICE9PSB0aGlzLnByb3BzLmZsb3dTdG9yZSkge1xuICAgICAgICAgICAgdGhpcy5jbG9zZVZpZXcoKTtcbiAgICAgICAgICAgIHRoaXMub3BlblZpZXcobmV4dFByb3BzLmZsb3dTdG9yZSk7XG4gICAgICAgIH1cbiAgICB9LFxuICAgIG9wZW5WaWV3OiBmdW5jdGlvbiAoc3RvcmUpIHtcbiAgICAgICAgdmFyIHZpZXcgPSBuZXcgdmlld3MuU3RvcmVWaWV3KHN0b3JlLCB0aGlzLmdldFZpZXdGaWx0KCksIHRoaXMuZ2V0Vmlld1NvcnQoKSk7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgdmlldzogdmlld1xuICAgICAgICB9KTtcblxuICAgICAgICB2aWV3LmFkZExpc3RlbmVyKFwicmVjYWxjdWxhdGVcIiwgdGhpcy5vblJlY2FsY3VsYXRlKTtcbiAgICAgICAgdmlldy5hZGRMaXN0ZW5lcihcImFkZCB1cGRhdGUgcmVtb3ZlXCIsIHRoaXMub25VcGRhdGUpO1xuICAgICAgICB2aWV3LmFkZExpc3RlbmVyKFwicmVtb3ZlXCIsIHRoaXMub25SZW1vdmUpO1xuICAgIH0sXG4gICAgb25SZWNhbGN1bGF0ZTogZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmZvcmNlVXBkYXRlKCk7XG4gICAgICAgIHZhciBzZWxlY3RlZCA9IHRoaXMuZ2V0U2VsZWN0ZWQoKTtcbiAgICAgICAgaWYgKHNlbGVjdGVkKSB7XG4gICAgICAgICAgICB0aGlzLnJlZnMuZmxvd1RhYmxlLnNjcm9sbEludG9WaWV3KHNlbGVjdGVkKTtcbiAgICAgICAgfVxuICAgIH0sXG4gICAgb25VcGRhdGU6IGZ1bmN0aW9uIChmbG93KSB7XG4gICAgICAgIGlmIChmbG93LmlkID09PSB0aGlzLmdldFBhcmFtcygpLmZsb3dJZCkge1xuICAgICAgICAgICAgdGhpcy5mb3JjZVVwZGF0ZSgpO1xuICAgICAgICB9XG4gICAgfSxcbiAgICBvblJlbW92ZTogZnVuY3Rpb24gKGZsb3dfaWQsIGluZGV4KSB7XG4gICAgICAgIGlmIChmbG93X2lkID09PSB0aGlzLmdldFBhcmFtcygpLmZsb3dJZCkge1xuICAgICAgICAgICAgdmFyIGZsb3dfdG9fc2VsZWN0ID0gdGhpcy5zdGF0ZS52aWV3Lmxpc3RbTWF0aC5taW4oaW5kZXgsIHRoaXMuc3RhdGUudmlldy5saXN0Lmxlbmd0aCAtMSldO1xuICAgICAgICAgICAgdGhpcy5zZWxlY3RGbG93KGZsb3dfdG9fc2VsZWN0KTtcbiAgICAgICAgfVxuICAgIH0sXG4gICAgY2xvc2VWaWV3OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuc3RhdGUudmlldy5jbG9zZSgpO1xuICAgIH0sXG4gICAgY29tcG9uZW50V2lsbE1vdW50OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMub3BlblZpZXcodGhpcy5wcm9wcy5mbG93U3RvcmUpO1xuICAgIH0sXG4gICAgY29tcG9uZW50V2lsbFVubW91bnQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5jbG9zZVZpZXcoKTtcbiAgICB9LFxuICAgIHNlbGVjdEZsb3c6IGZ1bmN0aW9uIChmbG93KSB7XG4gICAgICAgIGlmIChmbG93KSB7XG4gICAgICAgICAgICB0aGlzLnJlcGxhY2VXaXRoKFxuICAgICAgICAgICAgICAgIFwiZmxvd1wiLFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgZmxvd0lkOiBmbG93LmlkLFxuICAgICAgICAgICAgICAgICAgICBkZXRhaWxUYWI6IHRoaXMuZ2V0UGFyYW1zKCkuZGV0YWlsVGFiIHx8IFwicmVxdWVzdFwiXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHRoaXMucmVmcy5mbG93VGFibGUuc2Nyb2xsSW50b1ZpZXcoZmxvdyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnJlcGxhY2VXaXRoKFwiZmxvd3NcIiwge30pO1xuICAgICAgICB9XG4gICAgfSxcbiAgICBzZWxlY3RGbG93UmVsYXRpdmU6IGZ1bmN0aW9uIChzaGlmdCkge1xuICAgICAgICB2YXIgZmxvd3MgPSB0aGlzLnN0YXRlLnZpZXcubGlzdDtcbiAgICAgICAgdmFyIGluZGV4O1xuICAgICAgICBpZiAoIXRoaXMuZ2V0UGFyYW1zKCkuZmxvd0lkKSB7XG4gICAgICAgICAgICBpZiAoc2hpZnQgPiAwKSB7XG4gICAgICAgICAgICAgICAgaW5kZXggPSBmbG93cy5sZW5ndGggLSAxO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBpbmRleCA9IDA7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2YXIgY3VyckZsb3dJZCA9IHRoaXMuZ2V0UGFyYW1zKCkuZmxvd0lkO1xuICAgICAgICAgICAgdmFyIGkgPSBmbG93cy5sZW5ndGg7XG4gICAgICAgICAgICB3aGlsZSAoaS0tKSB7XG4gICAgICAgICAgICAgICAgaWYgKGZsb3dzW2ldLmlkID09PSBjdXJyRmxvd0lkKSB7XG4gICAgICAgICAgICAgICAgICAgIGluZGV4ID0gaTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaW5kZXggPSBNYXRoLm1pbihcbiAgICAgICAgICAgICAgICBNYXRoLm1heCgwLCBpbmRleCArIHNoaWZ0KSxcbiAgICAgICAgICAgICAgICBmbG93cy5sZW5ndGggLSAxKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNlbGVjdEZsb3coZmxvd3NbaW5kZXhdKTtcbiAgICB9LFxuICAgIG9uS2V5RG93bjogZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgdmFyIGZsb3cgPSB0aGlzLmdldFNlbGVjdGVkKCk7XG4gICAgICAgIGlmIChlLmN0cmxLZXkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBzd2l0Y2ggKGUua2V5Q29kZSkge1xuICAgICAgICAgICAgY2FzZSB0b3B1dGlscy5LZXkuSzpcbiAgICAgICAgICAgIGNhc2UgdG9wdXRpbHMuS2V5LlVQOlxuICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0Rmxvd1JlbGF0aXZlKC0xKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgdG9wdXRpbHMuS2V5Lko6XG4gICAgICAgICAgICBjYXNlIHRvcHV0aWxzLktleS5ET1dOOlxuICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0Rmxvd1JlbGF0aXZlKCsxKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgdG9wdXRpbHMuS2V5LlNQQUNFOlxuICAgICAgICAgICAgY2FzZSB0b3B1dGlscy5LZXkuUEFHRV9ET1dOOlxuICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0Rmxvd1JlbGF0aXZlKCsxMCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIHRvcHV0aWxzLktleS5QQUdFX1VQOlxuICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0Rmxvd1JlbGF0aXZlKC0xMCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIHRvcHV0aWxzLktleS5FTkQ6XG4gICAgICAgICAgICAgICAgdGhpcy5zZWxlY3RGbG93UmVsYXRpdmUoKzFlMTApO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSB0b3B1dGlscy5LZXkuSE9NRTpcbiAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdEZsb3dSZWxhdGl2ZSgtMWUxMCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIHRvcHV0aWxzLktleS5FU0M6XG4gICAgICAgICAgICAgICAgdGhpcy5zZWxlY3RGbG93KG51bGwpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSB0b3B1dGlscy5LZXkuSDpcbiAgICAgICAgICAgIGNhc2UgdG9wdXRpbHMuS2V5LkxFRlQ6XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMucmVmcy5mbG93RGV0YWlscykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnJlZnMuZmxvd0RldGFpbHMubmV4dFRhYigtMSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSB0b3B1dGlscy5LZXkuTDpcbiAgICAgICAgICAgIGNhc2UgdG9wdXRpbHMuS2V5LlRBQjpcbiAgICAgICAgICAgIGNhc2UgdG9wdXRpbHMuS2V5LlJJR0hUOlxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnJlZnMuZmxvd0RldGFpbHMpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5yZWZzLmZsb3dEZXRhaWxzLm5leHRUYWIoKzEpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgdG9wdXRpbHMuS2V5LkM6XG4gICAgICAgICAgICAgICAgaWYgKGUuc2hpZnRLZXkpIHtcbiAgICAgICAgICAgICAgICAgICAgRmxvd0FjdGlvbnMuY2xlYXIoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIHRvcHV0aWxzLktleS5EOlxuICAgICAgICAgICAgICAgIGlmIChmbG93KSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChlLnNoaWZ0S2V5KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBGbG93QWN0aW9ucy5kdXBsaWNhdGUoZmxvdyk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBGbG93QWN0aW9ucy5kZWxldGUoZmxvdyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIHRvcHV0aWxzLktleS5BOlxuICAgICAgICAgICAgICAgIGlmIChlLnNoaWZ0S2V5KSB7XG4gICAgICAgICAgICAgICAgICAgIEZsb3dBY3Rpb25zLmFjY2VwdF9hbGwoKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGZsb3cgJiYgZmxvdy5pbnRlcmNlcHRlZCkge1xuICAgICAgICAgICAgICAgICAgICBGbG93QWN0aW9ucy5hY2NlcHQoZmxvdyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSB0b3B1dGlscy5LZXkuUjpcbiAgICAgICAgICAgICAgICBpZiAoIWUuc2hpZnRLZXkgJiYgZmxvdykge1xuICAgICAgICAgICAgICAgICAgICBGbG93QWN0aW9ucy5yZXBsYXkoZmxvdyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSB0b3B1dGlscy5LZXkuVjpcbiAgICAgICAgICAgICAgICBpZihlLnNoaWZ0S2V5ICYmIGZsb3cgJiYgZmxvdy5tb2RpZmllZCkge1xuICAgICAgICAgICAgICAgICAgICBGbG93QWN0aW9ucy5yZXZlcnQoZmxvdyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICBjb25zb2xlLmRlYnVnKFwia2V5ZG93blwiLCBlLmtleUNvZGUpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgfSxcbiAgICBnZXRTZWxlY3RlZDogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5wcm9wcy5mbG93U3RvcmUuZ2V0KHRoaXMuZ2V0UGFyYW1zKCkuZmxvd0lkKTtcbiAgICB9LFxuICAgIHJlbmRlcjogZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgc2VsZWN0ZWQgPSB0aGlzLmdldFNlbGVjdGVkKCk7XG5cbiAgICAgICAgdmFyIGRldGFpbHM7XG4gICAgICAgIGlmIChzZWxlY3RlZCkge1xuICAgICAgICAgICAgZGV0YWlscyA9IFtcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KHV0aWxzLlNwbGl0dGVyLCB7a2V5OiBcInNwbGl0dGVyXCJ9KSxcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KGZsb3dkZXRhaWwuRmxvd0RldGFpbCwge2tleTogXCJmbG93RGV0YWlsc1wiLCByZWY6IFwiZmxvd0RldGFpbHNcIiwgZmxvdzogc2VsZWN0ZWR9KVxuICAgICAgICAgICAgXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGRldGFpbHMgPSBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwge2NsYXNzTmFtZTogXCJtYWluLXZpZXdcIiwgb25LZXlEb3duOiB0aGlzLm9uS2V5RG93biwgdGFiSW5kZXg6IFwiMFwifSwgXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChGbG93VGFibGUsIHtyZWY6IFwiZmxvd1RhYmxlXCIsIFxuICAgICAgICAgICAgICAgICAgICB2aWV3OiB0aGlzLnN0YXRlLnZpZXcsIFxuICAgICAgICAgICAgICAgICAgICBzZWxlY3RGbG93OiB0aGlzLnNlbGVjdEZsb3csIFxuICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZDogc2VsZWN0ZWR9KSwgXG4gICAgICAgICAgICAgICAgZGV0YWlsc1xuICAgICAgICAgICAgKVxuICAgICAgICApO1xuICAgIH1cbn0pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IE1haW5WaWV3O1xuIiwidmFyIFJlYWN0ID0gcmVxdWlyZShcInJlYWN0XCIpO1xudmFyIFJlYWN0Um91dGVyID0gcmVxdWlyZShcInJlYWN0LXJvdXRlclwiKTtcbnZhciBfID0gcmVxdWlyZShcImxvZGFzaFwiKTtcblxudmFyIHV0aWxzID0gcmVxdWlyZShcIi4vdXRpbHMuanNcIik7XG52YXIgTWFpblZpZXcgPSByZXF1aXJlKFwiLi9tYWludmlldy5qc1wiKTtcbnZhciBGb290ZXIgPSByZXF1aXJlKFwiLi9mb290ZXIuanNcIik7XG52YXIgaGVhZGVyID0gcmVxdWlyZShcIi4vaGVhZGVyLmpzXCIpO1xudmFyIEV2ZW50TG9nID0gcmVxdWlyZShcIi4vZXZlbnRsb2cuanNcIik7XG52YXIgc3RvcmUgPSByZXF1aXJlKFwiLi4vc3RvcmUvc3RvcmUuanNcIik7XG5cblxuLy9UT0RPOiBNb3ZlIG91dCBvZiBoZXJlLCBqdXN0IGEgc3R1Yi5cbnZhciBSZXBvcnRzID0gUmVhY3QuY3JlYXRlQ2xhc3Moe2Rpc3BsYXlOYW1lOiBcIlJlcG9ydHNcIixcbiAgICByZW5kZXI6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIFJlYWN0LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwgbnVsbCwgXCJSZXBvcnRFZGl0b3JcIik7XG4gICAgfVxufSk7XG5cblxudmFyIFByb3h5QXBwTWFpbiA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtkaXNwbGF5TmFtZTogXCJQcm94eUFwcE1haW5cIixcbiAgICBtaXhpbnM6IFt1dGlscy5TdGF0ZV0sXG4gICAgZ2V0SW5pdGlhbFN0YXRlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBldmVudFN0b3JlID0gbmV3IHN0b3JlLkV2ZW50TG9nU3RvcmUoKTtcbiAgICAgICAgdmFyIGZsb3dTdG9yZSA9IG5ldyBzdG9yZS5GbG93U3RvcmUoKTtcbiAgICAgICAgdmFyIHNldHRpbmdzID0gbmV3IHN0b3JlLlNldHRpbmdzU3RvcmUoKTtcblxuICAgICAgICAvLyBEZWZhdWx0IFNldHRpbmdzIGJlZm9yZSBmZXRjaFxuICAgICAgICBfLmV4dGVuZChzZXR0aW5ncy5kaWN0LHtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzZXR0aW5nczogc2V0dGluZ3MsXG4gICAgICAgICAgICBmbG93U3RvcmU6IGZsb3dTdG9yZSxcbiAgICAgICAgICAgIGV2ZW50U3RvcmU6IGV2ZW50U3RvcmVcbiAgICAgICAgfTtcbiAgICB9LFxuICAgIGNvbXBvbmVudERpZE1vdW50OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuc3RhdGUuc2V0dGluZ3MuYWRkTGlzdGVuZXIoXCJyZWNhbGN1bGF0ZVwiLCB0aGlzLm9uU2V0dGluZ3NDaGFuZ2UpO1xuICAgICAgICB3aW5kb3cuYXBwID0gdGhpcztcbiAgICB9LFxuICAgIGNvbXBvbmVudFdpbGxVbm1vdW50OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuc3RhdGUuc2V0dGluZ3MucmVtb3ZlTGlzdGVuZXIoXCJyZWNhbGN1bGF0ZVwiLCB0aGlzLm9uU2V0dGluZ3NDaGFuZ2UpO1xuICAgIH0sXG4gICAgb25TZXR0aW5nc0NoYW5nZTogZnVuY3Rpb24oKXtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICBzZXR0aW5nczogdGhpcy5zdGF0ZS5zZXR0aW5nc1xuICAgICAgICB9KTtcbiAgICB9LFxuICAgIHJlbmRlcjogZnVuY3Rpb24gKCkge1xuXG4gICAgICAgIHZhciBldmVudGxvZztcbiAgICAgICAgaWYgKHRoaXMuZ2V0UXVlcnkoKVtRdWVyeS5TSE9XX0VWRU5UTE9HXSkge1xuICAgICAgICAgICAgZXZlbnRsb2cgPSBbXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudCh1dGlscy5TcGxpdHRlciwge2tleTogXCJzcGxpdHRlclwiLCBheGlzOiBcInlcIn0pLFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoRXZlbnRMb2csIHtrZXk6IFwiZXZlbnRsb2dcIiwgZXZlbnRTdG9yZTogdGhpcy5zdGF0ZS5ldmVudFN0b3JlfSlcbiAgICAgICAgICAgIF07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBldmVudGxvZyA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcImRpdlwiLCB7aWQ6IFwiY29udGFpbmVyXCJ9LCBcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KGhlYWRlci5IZWFkZXIsIHtzZXR0aW5nczogdGhpcy5zdGF0ZS5zZXR0aW5ncy5kaWN0fSksIFxuICAgICAgICAgICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoUm91dGVIYW5kbGVyLCB7c2V0dGluZ3M6IHRoaXMuc3RhdGUuc2V0dGluZ3MuZGljdCwgZmxvd1N0b3JlOiB0aGlzLnN0YXRlLmZsb3dTdG9yZX0pLCBcbiAgICAgICAgICAgICAgICBldmVudGxvZywgXG4gICAgICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChGb290ZXIsIHtzZXR0aW5nczogdGhpcy5zdGF0ZS5zZXR0aW5ncy5kaWN0fSlcbiAgICAgICAgICAgIClcbiAgICAgICAgKTtcbiAgICB9XG59KTtcblxuXG52YXIgUm91dGUgPSBSZWFjdFJvdXRlci5Sb3V0ZTtcbnZhciBSb3V0ZUhhbmRsZXIgPSBSZWFjdFJvdXRlci5Sb3V0ZUhhbmRsZXI7XG52YXIgUmVkaXJlY3QgPSBSZWFjdFJvdXRlci5SZWRpcmVjdDtcbnZhciBEZWZhdWx0Um91dGUgPSBSZWFjdFJvdXRlci5EZWZhdWx0Um91dGU7XG52YXIgTm90Rm91bmRSb3V0ZSA9IFJlYWN0Um91dGVyLk5vdEZvdW5kUm91dGU7XG5cblxudmFyIHJvdXRlcyA9IChcbiAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFJvdXRlLCB7cGF0aDogXCIvXCIsIGhhbmRsZXI6IFByb3h5QXBwTWFpbn0sIFxuICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFJvdXRlLCB7bmFtZTogXCJmbG93c1wiLCBwYXRoOiBcImZsb3dzXCIsIGhhbmRsZXI6IE1haW5WaWV3fSksIFxuICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFJvdXRlLCB7bmFtZTogXCJmbG93XCIsIHBhdGg6IFwiZmxvd3MvOmZsb3dJZC86ZGV0YWlsVGFiXCIsIGhhbmRsZXI6IE1haW5WaWV3fSksIFxuICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFJvdXRlLCB7bmFtZTogXCJyZXBvcnRzXCIsIGhhbmRsZXI6IFJlcG9ydHN9KSwgXG4gICAgICAgIFJlYWN0LmNyZWF0ZUVsZW1lbnQoUmVkaXJlY3QsIHtwYXRoOiBcIi9cIiwgdG86IFwiZmxvd3NcIn0pXG4gICAgKVxuKTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gICAgcm91dGVzOiByb3V0ZXNcbn07XG5cbiIsInZhciBSZWFjdCA9IHJlcXVpcmUoXCJyZWFjdFwiKTtcbnZhciBSZWFjdFJvdXRlciA9IHJlcXVpcmUoXCJyZWFjdC1yb3V0ZXJcIik7XG52YXIgXyA9IHJlcXVpcmUoXCJsb2Rhc2hcIik7XG5cbi8vUmVhY3QgdXRpbHMuIEZvciBvdGhlciB1dGlsaXRpZXMsIHNlZSAuLi91dGlscy5qc1xuXG4vLyBodHRwOi8vYmxvZy52amV1eC5jb20vMjAxMy9qYXZhc2NyaXB0L3Njcm9sbC1wb3NpdGlvbi13aXRoLXJlYWN0Lmh0bWwgKGFsc28gY29udGFpbnMgaW52ZXJzZSBleGFtcGxlKVxudmFyIEF1dG9TY3JvbGxNaXhpbiA9IHtcbiAgICBjb21wb25lbnRXaWxsVXBkYXRlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBub2RlID0gdGhpcy5nZXRET01Ob2RlKCk7XG4gICAgICAgIHRoaXMuX3Nob3VsZFNjcm9sbEJvdHRvbSA9IChcbiAgICAgICAgICAgIG5vZGUuc2Nyb2xsVG9wICE9PSAwICYmXG4gICAgICAgICAgICBub2RlLnNjcm9sbFRvcCArIG5vZGUuY2xpZW50SGVpZ2h0ID09PSBub2RlLnNjcm9sbEhlaWdodFxuICAgICAgICApO1xuICAgIH0sXG4gICAgY29tcG9uZW50RGlkVXBkYXRlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLl9zaG91bGRTY3JvbGxCb3R0b20pIHtcbiAgICAgICAgICAgIHZhciBub2RlID0gdGhpcy5nZXRET01Ob2RlKCk7XG4gICAgICAgICAgICBub2RlLnNjcm9sbFRvcCA9IG5vZGUuc2Nyb2xsSGVpZ2h0O1xuICAgICAgICB9XG4gICAgfSxcbn07XG5cblxudmFyIFN0aWNreUhlYWRNaXhpbiA9IHtcbiAgICBhZGp1c3RIZWFkOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIEFidXNpbmcgQ1NTIHRyYW5zZm9ybXMgdG8gc2V0IHRoZSBlbGVtZW50XG4gICAgICAgIC8vIHJlZmVyZW5jZWQgYXMgaGVhZCBpbnRvIHNvbWUga2luZCBvZiBwb3NpdGlvbjpzdGlja3kuXG4gICAgICAgIHZhciBoZWFkID0gdGhpcy5yZWZzLmhlYWQuZ2V0RE9NTm9kZSgpO1xuICAgICAgICBoZWFkLnN0eWxlLnRyYW5zZm9ybSA9IFwidHJhbnNsYXRlKDAsXCIgKyB0aGlzLmdldERPTU5vZGUoKS5zY3JvbGxUb3AgKyBcInB4KVwiO1xuICAgIH1cbn07XG5cblxudmFyIE5hdmlnYXRpb24gPSBfLmV4dGVuZCh7fSwgUmVhY3RSb3V0ZXIuTmF2aWdhdGlvbiwge1xuICAgIHNldFF1ZXJ5OiBmdW5jdGlvbiAoZGljdCkge1xuICAgICAgICB2YXIgcSA9IHRoaXMuY29udGV4dC5nZXRDdXJyZW50UXVlcnkoKTtcbiAgICAgICAgZm9yKHZhciBpIGluIGRpY3Qpe1xuICAgICAgICAgICAgaWYoZGljdC5oYXNPd25Qcm9wZXJ0eShpKSl7XG4gICAgICAgICAgICAgICAgcVtpXSA9IGRpY3RbaV0gfHwgdW5kZWZpbmVkOyAvL2ZhbHNleSB2YWx1ZXMgc2hhbGwgYmUgcmVtb3ZlZC5cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBxLl8gPSBcIl9cIjsgLy8gd29ya2Fyb3VuZCBmb3IgaHR0cHM6Ly9naXRodWIuY29tL3JhY2t0L3JlYWN0LXJvdXRlci9wdWxsLzU5OVxuICAgICAgICB0aGlzLnJlcGxhY2VXaXRoKHRoaXMuY29udGV4dC5nZXRDdXJyZW50UGF0aCgpLCB0aGlzLmNvbnRleHQuZ2V0Q3VycmVudFBhcmFtcygpLCBxKTtcbiAgICB9LFxuICAgIHJlcGxhY2VXaXRoOiBmdW5jdGlvbihyb3V0ZU5hbWVPclBhdGgsIHBhcmFtcywgcXVlcnkpIHtcbiAgICAgICAgaWYocm91dGVOYW1lT3JQYXRoID09PSB1bmRlZmluZWQpe1xuICAgICAgICAgICAgcm91dGVOYW1lT3JQYXRoID0gdGhpcy5jb250ZXh0LmdldEN1cnJlbnRQYXRoKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYocGFyYW1zID09PSB1bmRlZmluZWQpe1xuICAgICAgICAgICAgcGFyYW1zID0gdGhpcy5jb250ZXh0LmdldEN1cnJlbnRQYXJhbXMoKTtcbiAgICAgICAgfVxuICAgICAgICBpZihxdWVyeSA9PT0gdW5kZWZpbmVkKXtcbiAgICAgICAgICAgIHF1ZXJ5ID0gdGhpcy5jb250ZXh0LmdldEN1cnJlbnRRdWVyeSgpO1xuICAgICAgICB9XG4gICAgICAgIFJlYWN0Um91dGVyLk5hdmlnYXRpb24ucmVwbGFjZVdpdGguY2FsbCh0aGlzLCByb3V0ZU5hbWVPclBhdGgsIHBhcmFtcywgcXVlcnkpO1xuICAgIH1cbn0pO1xuXy5leHRlbmQoTmF2aWdhdGlvbi5jb250ZXh0VHlwZXMsIFJlYWN0Um91dGVyLlN0YXRlLmNvbnRleHRUeXBlcyk7XG5cbnZhciBTdGF0ZSA9IF8uZXh0ZW5kKHt9LCBSZWFjdFJvdXRlci5TdGF0ZSwge1xuICAgIGdldEluaXRpYWxTdGF0ZTogZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLl9xdWVyeSA9IHRoaXMuY29udGV4dC5nZXRDdXJyZW50UXVlcnkoKTtcbiAgICAgICAgdGhpcy5fcXVlcnlXYXRjaGVzID0gW107XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH0sXG4gICAgb25RdWVyeUNoYW5nZTogZnVuY3Rpb24gKGtleSwgY2FsbGJhY2spIHtcbiAgICAgICAgdGhpcy5fcXVlcnlXYXRjaGVzLnB1c2goe1xuICAgICAgICAgICAga2V5OiBrZXksXG4gICAgICAgICAgICBjYWxsYmFjazogY2FsbGJhY2tcbiAgICAgICAgfSk7XG4gICAgfSxcbiAgICBjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzOiBmdW5jdGlvbiAobmV4dFByb3BzLCBuZXh0U3RhdGUpIHtcbiAgICAgICAgdmFyIHEgPSB0aGlzLmNvbnRleHQuZ2V0Q3VycmVudFF1ZXJ5KCk7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5fcXVlcnlXYXRjaGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB2YXIgd2F0Y2ggPSB0aGlzLl9xdWVyeVdhdGNoZXNbaV07XG4gICAgICAgICAgICBpZiAodGhpcy5fcXVlcnlbd2F0Y2gua2V5XSAhPT0gcVt3YXRjaC5rZXldKSB7XG4gICAgICAgICAgICAgICAgd2F0Y2guY2FsbGJhY2sodGhpcy5fcXVlcnlbd2F0Y2gua2V5XSwgcVt3YXRjaC5rZXldLCB3YXRjaC5rZXkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3F1ZXJ5ID0gcTtcbiAgICB9XG59KTtcblxudmFyIFNwbGl0dGVyID0gUmVhY3QuY3JlYXRlQ2xhc3Moe2Rpc3BsYXlOYW1lOiBcIlNwbGl0dGVyXCIsXG4gICAgZ2V0RGVmYXVsdFByb3BzOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBheGlzOiBcInhcIlxuICAgICAgICB9O1xuICAgIH0sXG4gICAgZ2V0SW5pdGlhbFN0YXRlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBhcHBsaWVkOiBmYWxzZSxcbiAgICAgICAgICAgIHN0YXJ0WDogZmFsc2UsXG4gICAgICAgICAgICBzdGFydFk6IGZhbHNlXG4gICAgICAgIH07XG4gICAgfSxcbiAgICBvbk1vdXNlRG93bjogZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICBzdGFydFg6IGUucGFnZVgsXG4gICAgICAgICAgICBzdGFydFk6IGUucGFnZVlcbiAgICAgICAgfSk7XG4gICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwibW91c2Vtb3ZlXCIsIHRoaXMub25Nb3VzZU1vdmUpO1xuICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcihcIm1vdXNldXBcIiwgdGhpcy5vbk1vdXNlVXApO1xuICAgICAgICAvLyBPY2Nhc2lvbmFsbHksIG9ubHkgYSBkcmFnRW5kIGV2ZW50IGlzIHRyaWdnZXJlZCwgYnV0IG5vIG1vdXNlVXAuXG4gICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwiZHJhZ2VuZFwiLCB0aGlzLm9uRHJhZ0VuZCk7XG4gICAgfSxcbiAgICBvbkRyYWdFbmQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5nZXRET01Ob2RlKCkuc3R5bGUudHJhbnNmb3JtID0gXCJcIjtcbiAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJkcmFnZW5kXCIsIHRoaXMub25EcmFnRW5kKTtcbiAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJtb3VzZXVwXCIsIHRoaXMub25Nb3VzZVVwKTtcbiAgICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJtb3VzZW1vdmVcIiwgdGhpcy5vbk1vdXNlTW92ZSk7XG4gICAgfSxcbiAgICBvbk1vdXNlVXA6IGZ1bmN0aW9uIChlKSB7XG4gICAgICAgIHRoaXMub25EcmFnRW5kKCk7XG5cbiAgICAgICAgdmFyIG5vZGUgPSB0aGlzLmdldERPTU5vZGUoKTtcbiAgICAgICAgdmFyIHByZXYgPSBub2RlLnByZXZpb3VzRWxlbWVudFNpYmxpbmc7XG4gICAgICAgIHZhciBuZXh0ID0gbm9kZS5uZXh0RWxlbWVudFNpYmxpbmc7XG5cbiAgICAgICAgdmFyIGRYID0gZS5wYWdlWCAtIHRoaXMuc3RhdGUuc3RhcnRYO1xuICAgICAgICB2YXIgZFkgPSBlLnBhZ2VZIC0gdGhpcy5zdGF0ZS5zdGFydFk7XG4gICAgICAgIHZhciBmbGV4QmFzaXM7XG4gICAgICAgIGlmICh0aGlzLnByb3BzLmF4aXMgPT09IFwieFwiKSB7XG4gICAgICAgICAgICBmbGV4QmFzaXMgPSBwcmV2Lm9mZnNldFdpZHRoICsgZFg7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmbGV4QmFzaXMgPSBwcmV2Lm9mZnNldEhlaWdodCArIGRZO1xuICAgICAgICB9XG5cbiAgICAgICAgcHJldi5zdHlsZS5mbGV4ID0gXCIwIDAgXCIgKyBNYXRoLm1heCgwLCBmbGV4QmFzaXMpICsgXCJweFwiO1xuICAgICAgICBuZXh0LnN0eWxlLmZsZXggPSBcIjEgMSBhdXRvXCI7XG5cbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICBhcHBsaWVkOiB0cnVlXG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLm9uUmVzaXplKCk7XG4gICAgfSxcbiAgICBvbk1vdXNlTW92ZTogZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgdmFyIGRYID0gMCwgZFkgPSAwO1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5heGlzID09PSBcInhcIikge1xuICAgICAgICAgICAgZFggPSBlLnBhZ2VYIC0gdGhpcy5zdGF0ZS5zdGFydFg7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBkWSA9IGUucGFnZVkgLSB0aGlzLnN0YXRlLnN0YXJ0WTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmdldERPTU5vZGUoKS5zdHlsZS50cmFuc2Zvcm0gPSBcInRyYW5zbGF0ZShcIiArIGRYICsgXCJweCxcIiArIGRZICsgXCJweClcIjtcbiAgICB9LFxuICAgIG9uUmVzaXplOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIC8vIFRyaWdnZXIgYSBnbG9iYWwgcmVzaXplIGV2ZW50LiBUaGlzIG5vdGlmaWVzIGNvbXBvbmVudHMgdGhhdCBlbXBsb3kgdmlydHVhbCBzY3JvbGxpbmdcbiAgICAgICAgLy8gdGhhdCB0aGVpciB2aWV3cG9ydCBtYXkgaGF2ZSBjaGFuZ2VkLlxuICAgICAgICB3aW5kb3cuc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB3aW5kb3cuZGlzcGF0Y2hFdmVudChuZXcgQ3VzdG9tRXZlbnQoXCJyZXNpemVcIikpO1xuICAgICAgICB9LCAxKTtcbiAgICB9LFxuICAgIHJlc2V0OiBmdW5jdGlvbiAod2lsbFVubW91bnQpIHtcbiAgICAgICAgaWYgKCF0aGlzLnN0YXRlLmFwcGxpZWQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgbm9kZSA9IHRoaXMuZ2V0RE9NTm9kZSgpO1xuICAgICAgICB2YXIgcHJldiA9IG5vZGUucHJldmlvdXNFbGVtZW50U2libGluZztcbiAgICAgICAgdmFyIG5leHQgPSBub2RlLm5leHRFbGVtZW50U2libGluZztcblxuICAgICAgICBwcmV2LnN0eWxlLmZsZXggPSBcIlwiO1xuICAgICAgICBuZXh0LnN0eWxlLmZsZXggPSBcIlwiO1xuXG4gICAgICAgIGlmICghd2lsbFVubW91bnQpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgICAgIGFwcGxpZWQ6IGZhbHNlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm9uUmVzaXplKCk7XG4gICAgfSxcbiAgICBjb21wb25lbnRXaWxsVW5tb3VudDogZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLnJlc2V0KHRydWUpO1xuICAgIH0sXG4gICAgcmVuZGVyOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBjbGFzc05hbWUgPSBcInNwbGl0dGVyXCI7XG4gICAgICAgIGlmICh0aGlzLnByb3BzLmF4aXMgPT09IFwieFwiKSB7XG4gICAgICAgICAgICBjbGFzc05hbWUgKz0gXCIgc3BsaXR0ZXIteFwiO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY2xhc3NOYW1lICs9IFwiIHNwbGl0dGVyLXlcIjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgUmVhY3QuY3JlYXRlRWxlbWVudChcImRpdlwiLCB7Y2xhc3NOYW1lOiBjbGFzc05hbWV9LCBcbiAgICAgICAgICAgICAgICBSZWFjdC5jcmVhdGVFbGVtZW50KFwiZGl2XCIsIHtvbk1vdXNlRG93bjogdGhpcy5vbk1vdXNlRG93biwgZHJhZ2dhYmxlOiBcInRydWVcIn0pXG4gICAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgfVxufSk7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICAgIFN0YXRlOiBTdGF0ZSxcbiAgICBOYXZpZ2F0aW9uOiBOYXZpZ2F0aW9uLFxuICAgIFN0aWNreUhlYWRNaXhpbjogU3RpY2t5SGVhZE1peGluLFxuICAgIEF1dG9TY3JvbGxNaXhpbjogQXV0b1Njcm9sbE1peGluLFxuICAgIFNwbGl0dGVyOiBTcGxpdHRlclxufSIsInZhciBSZWFjdCA9IHJlcXVpcmUoXCJyZWFjdFwiKTtcblxudmFyIFZpcnR1YWxTY3JvbGxNaXhpbiA9IHtcbiAgICBnZXRJbml0aWFsU3RhdGU6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN0YXJ0OiAwLFxuICAgICAgICAgICAgc3RvcDogMFxuICAgICAgICB9O1xuICAgIH0sXG4gICAgY29tcG9uZW50V2lsbE1vdW50OiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICghdGhpcy5wcm9wcy5yb3dIZWlnaHQpIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihcIlZpcnR1YWxTY3JvbGxNaXhpbjogTm8gcm93SGVpZ2h0IHNwZWNpZmllZFwiLCB0aGlzKTtcbiAgICAgICAgfVxuICAgIH0sXG4gICAgZ2V0UGxhY2Vob2xkZXJUb3A6IGZ1bmN0aW9uICh0b3RhbCkge1xuICAgICAgICB2YXIgVGFnID0gdGhpcy5wcm9wcy5wbGFjZWhvbGRlclRhZ05hbWUgfHwgXCJ0clwiO1xuICAgICAgICAvLyBXaGVuIGEgbGFyZ2UgdHJ1bmsgb2YgZWxlbWVudHMgaXMgcmVtb3ZlZCBmcm9tIHRoZSBidXR0b24sIHN0YXJ0IG1heSBiZSBmYXIgb2ZmIHRoZSB2aWV3cG9ydC5cbiAgICAgICAgLy8gVG8gbWFrZSB0aGlzIGlzc3VlIGxlc3Mgc2V2ZXJlLCBsaW1pdCB0aGUgdG9wIHBsYWNlaG9sZGVyIHRvIHRoZSB0b3RhbCBudW1iZXIgb2Ygcm93cy5cbiAgICAgICAgdmFyIHN0eWxlID0ge1xuICAgICAgICAgICAgaGVpZ2h0OiBNYXRoLm1pbih0aGlzLnN0YXRlLnN0YXJ0LCB0b3RhbCkgKiB0aGlzLnByb3BzLnJvd0hlaWdodFxuICAgICAgICB9O1xuICAgICAgICB2YXIgc3BhY2VyID0gUmVhY3QuY3JlYXRlRWxlbWVudChUYWcsIHtrZXk6IFwicGxhY2Vob2xkZXItdG9wXCIsIHN0eWxlOiBzdHlsZX0pO1xuXG4gICAgICAgIGlmICh0aGlzLnN0YXRlLnN0YXJ0ICUgMiA9PT0gMSkge1xuICAgICAgICAgICAgLy8gZml4IGV2ZW4vb2RkIHJvd3NcbiAgICAgICAgICAgIHJldHVybiBbc3BhY2VyLCBSZWFjdC5jcmVhdGVFbGVtZW50KFRhZywge2tleTogXCJwbGFjZWhvbGRlci10b3AtMlwifSldO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHNwYWNlcjtcbiAgICAgICAgfVxuICAgIH0sXG4gICAgZ2V0UGxhY2Vob2xkZXJCb3R0b206IGZ1bmN0aW9uICh0b3RhbCkge1xuICAgICAgICB2YXIgVGFnID0gdGhpcy5wcm9wcy5wbGFjZWhvbGRlclRhZ05hbWUgfHwgXCJ0clwiO1xuICAgICAgICB2YXIgc3R5bGUgPSB7XG4gICAgICAgICAgICBoZWlnaHQ6IE1hdGgubWF4KDAsIHRvdGFsIC0gdGhpcy5zdGF0ZS5zdG9wKSAqIHRoaXMucHJvcHMucm93SGVpZ2h0XG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBSZWFjdC5jcmVhdGVFbGVtZW50KFRhZywge2tleTogXCJwbGFjZWhvbGRlci1ib3R0b21cIiwgc3R5bGU6IHN0eWxlfSk7XG4gICAgfSxcbiAgICBjb21wb25lbnREaWRNb3VudDogZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLm9uU2Nyb2xsKCk7XG4gICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdyZXNpemUnLCB0aGlzLm9uU2Nyb2xsKTtcbiAgICB9LFxuICAgIGNvbXBvbmVudFdpbGxVbm1vdW50OiBmdW5jdGlvbigpe1xuICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcigncmVzaXplJywgdGhpcy5vblNjcm9sbCk7XG4gICAgfSxcbiAgICBvblNjcm9sbDogZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgdmlld3BvcnQgPSB0aGlzLmdldERPTU5vZGUoKTtcbiAgICAgICAgdmFyIHRvcCA9IHZpZXdwb3J0LnNjcm9sbFRvcDtcbiAgICAgICAgdmFyIGhlaWdodCA9IHZpZXdwb3J0Lm9mZnNldEhlaWdodDtcbiAgICAgICAgdmFyIHN0YXJ0ID0gTWF0aC5mbG9vcih0b3AgLyB0aGlzLnByb3BzLnJvd0hlaWdodCk7XG4gICAgICAgIHZhciBzdG9wID0gc3RhcnQgKyBNYXRoLmNlaWwoaGVpZ2h0IC8gKHRoaXMucHJvcHMucm93SGVpZ2h0TWluIHx8IHRoaXMucHJvcHMucm93SGVpZ2h0KSk7XG5cbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICBzdGFydDogc3RhcnQsXG4gICAgICAgICAgICBzdG9wOiBzdG9wXG4gICAgICAgIH0pO1xuICAgIH0sXG4gICAgcmVuZGVyUm93czogZnVuY3Rpb24gKGVsZW1zKSB7XG4gICAgICAgIHZhciByb3dzID0gW107XG4gICAgICAgIHZhciBtYXggPSBNYXRoLm1pbihlbGVtcy5sZW5ndGgsIHRoaXMuc3RhdGUuc3RvcCk7XG5cbiAgICAgICAgZm9yICh2YXIgaSA9IHRoaXMuc3RhdGUuc3RhcnQ7IGkgPCBtYXg7IGkrKykge1xuICAgICAgICAgICAgdmFyIGVsZW0gPSBlbGVtc1tpXTtcbiAgICAgICAgICAgIHJvd3MucHVzaCh0aGlzLnJlbmRlclJvdyhlbGVtKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJvd3M7XG4gICAgfSxcbiAgICBzY3JvbGxSb3dJbnRvVmlldzogZnVuY3Rpb24gKGluZGV4LCBoZWFkX2hlaWdodCkge1xuXG4gICAgICAgIHZhciByb3dfdG9wID0gKGluZGV4ICogdGhpcy5wcm9wcy5yb3dIZWlnaHQpICsgaGVhZF9oZWlnaHQ7XG4gICAgICAgIHZhciByb3dfYm90dG9tID0gcm93X3RvcCArIHRoaXMucHJvcHMucm93SGVpZ2h0O1xuXG4gICAgICAgIHZhciB2aWV3cG9ydCA9IHRoaXMuZ2V0RE9NTm9kZSgpO1xuICAgICAgICB2YXIgdmlld3BvcnRfdG9wID0gdmlld3BvcnQuc2Nyb2xsVG9wO1xuICAgICAgICB2YXIgdmlld3BvcnRfYm90dG9tID0gdmlld3BvcnRfdG9wICsgdmlld3BvcnQub2Zmc2V0SGVpZ2h0O1xuXG4gICAgICAgIC8vIEFjY291bnQgZm9yIHBpbm5lZCB0aGVhZFxuICAgICAgICBpZiAocm93X3RvcCAtIGhlYWRfaGVpZ2h0IDwgdmlld3BvcnRfdG9wKSB7XG4gICAgICAgICAgICB2aWV3cG9ydC5zY3JvbGxUb3AgPSByb3dfdG9wIC0gaGVhZF9oZWlnaHQ7XG4gICAgICAgIH0gZWxzZSBpZiAocm93X2JvdHRvbSA+IHZpZXdwb3J0X2JvdHRvbSkge1xuICAgICAgICAgICAgdmlld3BvcnQuc2Nyb2xsVG9wID0gcm93X2JvdHRvbSAtIHZpZXdwb3J0Lm9mZnNldEhlaWdodDtcbiAgICAgICAgfVxuICAgIH0sXG59O1xuXG5tb2R1bGUuZXhwb3J0cyAgPSBWaXJ0dWFsU2Nyb2xsTWl4aW47IiwiXG52YXIgYWN0aW9ucyA9IHJlcXVpcmUoXCIuL2FjdGlvbnMuanNcIik7XG5cbmZ1bmN0aW9uIENvbm5lY3Rpb24odXJsKSB7XG4gICAgaWYgKHVybFswXSA9PT0gXCIvXCIpIHtcbiAgICAgICAgdXJsID0gbG9jYXRpb24ub3JpZ2luLnJlcGxhY2UoXCJodHRwXCIsIFwid3NcIikgKyB1cmw7XG4gICAgfVxuXG4gICAgdmFyIHdzID0gbmV3IFdlYlNvY2tldCh1cmwpO1xuICAgIHdzLm9ub3BlbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgYWN0aW9ucy5Db25uZWN0aW9uQWN0aW9ucy5vcGVuKCk7XG4gICAgfTtcbiAgICB3cy5vbm1lc3NhZ2UgPSBmdW5jdGlvbiAobWVzc2FnZSkge1xuICAgICAgICB2YXIgbSA9IEpTT04ucGFyc2UobWVzc2FnZS5kYXRhKTtcbiAgICAgICAgQXBwRGlzcGF0Y2hlci5kaXNwYXRjaFNlcnZlckFjdGlvbihtKTtcbiAgICB9O1xuICAgIHdzLm9uZXJyb3IgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGFjdGlvbnMuQ29ubmVjdGlvbkFjdGlvbnMuZXJyb3IoKTtcbiAgICAgICAgRXZlbnRMb2dBY3Rpb25zLmFkZF9ldmVudChcIldlYlNvY2tldCBjb25uZWN0aW9uIGVycm9yLlwiKTtcbiAgICB9O1xuICAgIHdzLm9uY2xvc2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGFjdGlvbnMuQ29ubmVjdGlvbkFjdGlvbnMuY2xvc2UoKTtcbiAgICAgICAgRXZlbnRMb2dBY3Rpb25zLmFkZF9ldmVudChcIldlYlNvY2tldCBjb25uZWN0aW9uIGNsb3NlZC5cIik7XG4gICAgfTtcbiAgICByZXR1cm4gd3M7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gQ29ubmVjdGlvbjsiLCJjb25zdCBQYXlsb2FkU291cmNlcyA9IHtcbiAgICBWSUVXOiBcInZpZXdcIixcbiAgICBTRVJWRVI6IFwic2VydmVyXCJcbn07XG5cblxuZnVuY3Rpb24gRGlzcGF0Y2hlcigpIHtcbiAgICB0aGlzLmNhbGxiYWNrcyA9IFtdO1xufVxuRGlzcGF0Y2hlci5wcm90b3R5cGUucmVnaXN0ZXIgPSBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICB0aGlzLmNhbGxiYWNrcy5wdXNoKGNhbGxiYWNrKTtcbn07XG5EaXNwYXRjaGVyLnByb3RvdHlwZS51bnJlZ2lzdGVyID0gZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gICAgdmFyIGluZGV4ID0gdGhpcy5jYWxsYmFja3MuaW5kZXhPZihjYWxsYmFjayk7XG4gICAgaWYgKGluZGV4ID49IDApIHtcbiAgICAgICAgdGhpcy5jYWxsYmFja3Muc3BsaWNlKGluZGV4LCAxKTtcbiAgICB9XG59O1xuRGlzcGF0Y2hlci5wcm90b3R5cGUuZGlzcGF0Y2ggPSBmdW5jdGlvbiAocGF5bG9hZCkge1xuICAgIGNvbnNvbGUuZGVidWcoXCJkaXNwYXRjaFwiLCBwYXlsb2FkKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuY2FsbGJhY2tzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHRoaXMuY2FsbGJhY2tzW2ldKHBheWxvYWQpO1xuICAgIH1cbn07XG5cblxuQXBwRGlzcGF0Y2hlciA9IG5ldyBEaXNwYXRjaGVyKCk7XG5BcHBEaXNwYXRjaGVyLmRpc3BhdGNoVmlld0FjdGlvbiA9IGZ1bmN0aW9uIChhY3Rpb24pIHtcbiAgICBhY3Rpb24uc291cmNlID0gUGF5bG9hZFNvdXJjZXMuVklFVztcbiAgICB0aGlzLmRpc3BhdGNoKGFjdGlvbik7XG59O1xuQXBwRGlzcGF0Y2hlci5kaXNwYXRjaFNlcnZlckFjdGlvbiA9IGZ1bmN0aW9uIChhY3Rpb24pIHtcbiAgICBhY3Rpb24uc291cmNlID0gUGF5bG9hZFNvdXJjZXMuU0VSVkVSO1xuICAgIHRoaXMuZGlzcGF0Y2goYWN0aW9uKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICAgIEFwcERpc3BhdGNoZXI6IEFwcERpc3BhdGNoZXJcbn07IiwiLyoganNoaW50IGlnbm9yZTpzdGFydCAqL1xuRmlsdCA9IChmdW5jdGlvbigpIHtcbiAgLypcbiAgICogR2VuZXJhdGVkIGJ5IFBFRy5qcyAwLjguMC5cbiAgICpcbiAgICogaHR0cDovL3BlZ2pzLm1hamRhLmN6L1xuICAgKi9cblxuICBmdW5jdGlvbiBwZWckc3ViY2xhc3MoY2hpbGQsIHBhcmVudCkge1xuICAgIGZ1bmN0aW9uIGN0b3IoKSB7IHRoaXMuY29uc3RydWN0b3IgPSBjaGlsZDsgfVxuICAgIGN0b3IucHJvdG90eXBlID0gcGFyZW50LnByb3RvdHlwZTtcbiAgICBjaGlsZC5wcm90b3R5cGUgPSBuZXcgY3RvcigpO1xuICB9XG5cbiAgZnVuY3Rpb24gU3ludGF4RXJyb3IobWVzc2FnZSwgZXhwZWN0ZWQsIGZvdW5kLCBvZmZzZXQsIGxpbmUsIGNvbHVtbikge1xuICAgIHRoaXMubWVzc2FnZSAgPSBtZXNzYWdlO1xuICAgIHRoaXMuZXhwZWN0ZWQgPSBleHBlY3RlZDtcbiAgICB0aGlzLmZvdW5kICAgID0gZm91bmQ7XG4gICAgdGhpcy5vZmZzZXQgICA9IG9mZnNldDtcbiAgICB0aGlzLmxpbmUgICAgID0gbGluZTtcbiAgICB0aGlzLmNvbHVtbiAgID0gY29sdW1uO1xuXG4gICAgdGhpcy5uYW1lICAgICA9IFwiU3ludGF4RXJyb3JcIjtcbiAgfVxuXG4gIHBlZyRzdWJjbGFzcyhTeW50YXhFcnJvciwgRXJyb3IpO1xuXG4gIGZ1bmN0aW9uIHBhcnNlKGlucHV0KSB7XG4gICAgdmFyIG9wdGlvbnMgPSBhcmd1bWVudHMubGVuZ3RoID4gMSA/IGFyZ3VtZW50c1sxXSA6IHt9LFxuXG4gICAgICAgIHBlZyRGQUlMRUQgPSB7fSxcblxuICAgICAgICBwZWckc3RhcnRSdWxlRnVuY3Rpb25zID0geyBzdGFydDogcGVnJHBhcnNlc3RhcnQgfSxcbiAgICAgICAgcGVnJHN0YXJ0UnVsZUZ1bmN0aW9uICA9IHBlZyRwYXJzZXN0YXJ0LFxuXG4gICAgICAgIHBlZyRjMCA9IHsgdHlwZTogXCJvdGhlclwiLCBkZXNjcmlwdGlvbjogXCJmaWx0ZXIgZXhwcmVzc2lvblwiIH0sXG4gICAgICAgIHBlZyRjMSA9IHBlZyRGQUlMRUQsXG4gICAgICAgIHBlZyRjMiA9IGZ1bmN0aW9uKG9yRXhwcikgeyByZXR1cm4gb3JFeHByOyB9LFxuICAgICAgICBwZWckYzMgPSBbXSxcbiAgICAgICAgcGVnJGM0ID0gZnVuY3Rpb24oKSB7cmV0dXJuIHRydWVGaWx0ZXI7IH0sXG4gICAgICAgIHBlZyRjNSA9IHsgdHlwZTogXCJvdGhlclwiLCBkZXNjcmlwdGlvbjogXCJ3aGl0ZXNwYWNlXCIgfSxcbiAgICAgICAgcGVnJGM2ID0gL15bIFxcdFxcblxccl0vLFxuICAgICAgICBwZWckYzcgPSB7IHR5cGU6IFwiY2xhc3NcIiwgdmFsdWU6IFwiWyBcXFxcdFxcXFxuXFxcXHJdXCIsIGRlc2NyaXB0aW9uOiBcIlsgXFxcXHRcXFxcblxcXFxyXVwiIH0sXG4gICAgICAgIHBlZyRjOCA9IHsgdHlwZTogXCJvdGhlclwiLCBkZXNjcmlwdGlvbjogXCJjb250cm9sIGNoYXJhY3RlclwiIH0sXG4gICAgICAgIHBlZyRjOSA9IC9eW3wmISgpflwiXS8sXG4gICAgICAgIHBlZyRjMTAgPSB7IHR5cGU6IFwiY2xhc3NcIiwgdmFsdWU6IFwiW3wmISgpflxcXCJdXCIsIGRlc2NyaXB0aW9uOiBcIlt8JiEoKX5cXFwiXVwiIH0sXG4gICAgICAgIHBlZyRjMTEgPSB7IHR5cGU6IFwib3RoZXJcIiwgZGVzY3JpcHRpb246IFwib3B0aW9uYWwgd2hpdGVzcGFjZVwiIH0sXG4gICAgICAgIHBlZyRjMTIgPSBcInxcIixcbiAgICAgICAgcGVnJGMxMyA9IHsgdHlwZTogXCJsaXRlcmFsXCIsIHZhbHVlOiBcInxcIiwgZGVzY3JpcHRpb246IFwiXFxcInxcXFwiXCIgfSxcbiAgICAgICAgcGVnJGMxNCA9IGZ1bmN0aW9uKGZpcnN0LCBzZWNvbmQpIHsgcmV0dXJuIG9yKGZpcnN0LCBzZWNvbmQpOyB9LFxuICAgICAgICBwZWckYzE1ID0gXCImXCIsXG4gICAgICAgIHBlZyRjMTYgPSB7IHR5cGU6IFwibGl0ZXJhbFwiLCB2YWx1ZTogXCImXCIsIGRlc2NyaXB0aW9uOiBcIlxcXCImXFxcIlwiIH0sXG4gICAgICAgIHBlZyRjMTcgPSBmdW5jdGlvbihmaXJzdCwgc2Vjb25kKSB7IHJldHVybiBhbmQoZmlyc3QsIHNlY29uZCk7IH0sXG4gICAgICAgIHBlZyRjMTggPSBcIiFcIixcbiAgICAgICAgcGVnJGMxOSA9IHsgdHlwZTogXCJsaXRlcmFsXCIsIHZhbHVlOiBcIiFcIiwgZGVzY3JpcHRpb246IFwiXFxcIiFcXFwiXCIgfSxcbiAgICAgICAgcGVnJGMyMCA9IGZ1bmN0aW9uKGV4cHIpIHsgcmV0dXJuIG5vdChleHByKTsgfSxcbiAgICAgICAgcGVnJGMyMSA9IFwiKFwiLFxuICAgICAgICBwZWckYzIyID0geyB0eXBlOiBcImxpdGVyYWxcIiwgdmFsdWU6IFwiKFwiLCBkZXNjcmlwdGlvbjogXCJcXFwiKFxcXCJcIiB9LFxuICAgICAgICBwZWckYzIzID0gXCIpXCIsXG4gICAgICAgIHBlZyRjMjQgPSB7IHR5cGU6IFwibGl0ZXJhbFwiLCB2YWx1ZTogXCIpXCIsIGRlc2NyaXB0aW9uOiBcIlxcXCIpXFxcIlwiIH0sXG4gICAgICAgIHBlZyRjMjUgPSBmdW5jdGlvbihleHByKSB7IHJldHVybiBiaW5kaW5nKGV4cHIpOyB9LFxuICAgICAgICBwZWckYzI2ID0gXCJ+YVwiLFxuICAgICAgICBwZWckYzI3ID0geyB0eXBlOiBcImxpdGVyYWxcIiwgdmFsdWU6IFwifmFcIiwgZGVzY3JpcHRpb246IFwiXFxcIn5hXFxcIlwiIH0sXG4gICAgICAgIHBlZyRjMjggPSBmdW5jdGlvbigpIHsgcmV0dXJuIGFzc2V0RmlsdGVyOyB9LFxuICAgICAgICBwZWckYzI5ID0gXCJ+ZVwiLFxuICAgICAgICBwZWckYzMwID0geyB0eXBlOiBcImxpdGVyYWxcIiwgdmFsdWU6IFwifmVcIiwgZGVzY3JpcHRpb246IFwiXFxcIn5lXFxcIlwiIH0sXG4gICAgICAgIHBlZyRjMzEgPSBmdW5jdGlvbigpIHsgcmV0dXJuIGVycm9yRmlsdGVyOyB9LFxuICAgICAgICBwZWckYzMyID0gXCJ+cVwiLFxuICAgICAgICBwZWckYzMzID0geyB0eXBlOiBcImxpdGVyYWxcIiwgdmFsdWU6IFwifnFcIiwgZGVzY3JpcHRpb246IFwiXFxcIn5xXFxcIlwiIH0sXG4gICAgICAgIHBlZyRjMzQgPSBmdW5jdGlvbigpIHsgcmV0dXJuIG5vUmVzcG9uc2VGaWx0ZXI7IH0sXG4gICAgICAgIHBlZyRjMzUgPSBcIn5zXCIsXG4gICAgICAgIHBlZyRjMzYgPSB7IHR5cGU6IFwibGl0ZXJhbFwiLCB2YWx1ZTogXCJ+c1wiLCBkZXNjcmlwdGlvbjogXCJcXFwifnNcXFwiXCIgfSxcbiAgICAgICAgcGVnJGMzNyA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gcmVzcG9uc2VGaWx0ZXI7IH0sXG4gICAgICAgIHBlZyRjMzggPSBcInRydWVcIixcbiAgICAgICAgcGVnJGMzOSA9IHsgdHlwZTogXCJsaXRlcmFsXCIsIHZhbHVlOiBcInRydWVcIiwgZGVzY3JpcHRpb246IFwiXFxcInRydWVcXFwiXCIgfSxcbiAgICAgICAgcGVnJGM0MCA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gdHJ1ZUZpbHRlcjsgfSxcbiAgICAgICAgcGVnJGM0MSA9IFwiZmFsc2VcIixcbiAgICAgICAgcGVnJGM0MiA9IHsgdHlwZTogXCJsaXRlcmFsXCIsIHZhbHVlOiBcImZhbHNlXCIsIGRlc2NyaXB0aW9uOiBcIlxcXCJmYWxzZVxcXCJcIiB9LFxuICAgICAgICBwZWckYzQzID0gZnVuY3Rpb24oKSB7IHJldHVybiBmYWxzZUZpbHRlcjsgfSxcbiAgICAgICAgcGVnJGM0NCA9IFwifmNcIixcbiAgICAgICAgcGVnJGM0NSA9IHsgdHlwZTogXCJsaXRlcmFsXCIsIHZhbHVlOiBcIn5jXCIsIGRlc2NyaXB0aW9uOiBcIlxcXCJ+Y1xcXCJcIiB9LFxuICAgICAgICBwZWckYzQ2ID0gZnVuY3Rpb24ocykgeyByZXR1cm4gcmVzcG9uc2VDb2RlKHMpOyB9LFxuICAgICAgICBwZWckYzQ3ID0gXCJ+ZFwiLFxuICAgICAgICBwZWckYzQ4ID0geyB0eXBlOiBcImxpdGVyYWxcIiwgdmFsdWU6IFwifmRcIiwgZGVzY3JpcHRpb246IFwiXFxcIn5kXFxcIlwiIH0sXG4gICAgICAgIHBlZyRjNDkgPSBmdW5jdGlvbihzKSB7IHJldHVybiBkb21haW4ocyk7IH0sXG4gICAgICAgIHBlZyRjNTAgPSBcIn5oXCIsXG4gICAgICAgIHBlZyRjNTEgPSB7IHR5cGU6IFwibGl0ZXJhbFwiLCB2YWx1ZTogXCJ+aFwiLCBkZXNjcmlwdGlvbjogXCJcXFwifmhcXFwiXCIgfSxcbiAgICAgICAgcGVnJGM1MiA9IGZ1bmN0aW9uKHMpIHsgcmV0dXJuIGhlYWRlcihzKTsgfSxcbiAgICAgICAgcGVnJGM1MyA9IFwifmhxXCIsXG4gICAgICAgIHBlZyRjNTQgPSB7IHR5cGU6IFwibGl0ZXJhbFwiLCB2YWx1ZTogXCJ+aHFcIiwgZGVzY3JpcHRpb246IFwiXFxcIn5ocVxcXCJcIiB9LFxuICAgICAgICBwZWckYzU1ID0gZnVuY3Rpb24ocykgeyByZXR1cm4gcmVxdWVzdEhlYWRlcihzKTsgfSxcbiAgICAgICAgcGVnJGM1NiA9IFwifmhzXCIsXG4gICAgICAgIHBlZyRjNTcgPSB7IHR5cGU6IFwibGl0ZXJhbFwiLCB2YWx1ZTogXCJ+aHNcIiwgZGVzY3JpcHRpb246IFwiXFxcIn5oc1xcXCJcIiB9LFxuICAgICAgICBwZWckYzU4ID0gZnVuY3Rpb24ocykgeyByZXR1cm4gcmVzcG9uc2VIZWFkZXIocyk7IH0sXG4gICAgICAgIHBlZyRjNTkgPSBcIn5tXCIsXG4gICAgICAgIHBlZyRjNjAgPSB7IHR5cGU6IFwibGl0ZXJhbFwiLCB2YWx1ZTogXCJ+bVwiLCBkZXNjcmlwdGlvbjogXCJcXFwifm1cXFwiXCIgfSxcbiAgICAgICAgcGVnJGM2MSA9IGZ1bmN0aW9uKHMpIHsgcmV0dXJuIG1ldGhvZChzKTsgfSxcbiAgICAgICAgcGVnJGM2MiA9IFwifnRcIixcbiAgICAgICAgcGVnJGM2MyA9IHsgdHlwZTogXCJsaXRlcmFsXCIsIHZhbHVlOiBcIn50XCIsIGRlc2NyaXB0aW9uOiBcIlxcXCJ+dFxcXCJcIiB9LFxuICAgICAgICBwZWckYzY0ID0gZnVuY3Rpb24ocykgeyByZXR1cm4gY29udGVudFR5cGUocyk7IH0sXG4gICAgICAgIHBlZyRjNjUgPSBcIn50cVwiLFxuICAgICAgICBwZWckYzY2ID0geyB0eXBlOiBcImxpdGVyYWxcIiwgdmFsdWU6IFwifnRxXCIsIGRlc2NyaXB0aW9uOiBcIlxcXCJ+dHFcXFwiXCIgfSxcbiAgICAgICAgcGVnJGM2NyA9IGZ1bmN0aW9uKHMpIHsgcmV0dXJuIHJlcXVlc3RDb250ZW50VHlwZShzKTsgfSxcbiAgICAgICAgcGVnJGM2OCA9IFwifnRzXCIsXG4gICAgICAgIHBlZyRjNjkgPSB7IHR5cGU6IFwibGl0ZXJhbFwiLCB2YWx1ZTogXCJ+dHNcIiwgZGVzY3JpcHRpb246IFwiXFxcIn50c1xcXCJcIiB9LFxuICAgICAgICBwZWckYzcwID0gZnVuY3Rpb24ocykgeyByZXR1cm4gcmVzcG9uc2VDb250ZW50VHlwZShzKTsgfSxcbiAgICAgICAgcGVnJGM3MSA9IFwifnVcIixcbiAgICAgICAgcGVnJGM3MiA9IHsgdHlwZTogXCJsaXRlcmFsXCIsIHZhbHVlOiBcIn51XCIsIGRlc2NyaXB0aW9uOiBcIlxcXCJ+dVxcXCJcIiB9LFxuICAgICAgICBwZWckYzczID0gZnVuY3Rpb24ocykgeyByZXR1cm4gdXJsKHMpOyB9LFxuICAgICAgICBwZWckYzc0ID0geyB0eXBlOiBcIm90aGVyXCIsIGRlc2NyaXB0aW9uOiBcImludGVnZXJcIiB9LFxuICAgICAgICBwZWckYzc1ID0gbnVsbCxcbiAgICAgICAgcGVnJGM3NiA9IC9eWydcIl0vLFxuICAgICAgICBwZWckYzc3ID0geyB0eXBlOiBcImNsYXNzXCIsIHZhbHVlOiBcIlsnXFxcIl1cIiwgZGVzY3JpcHRpb246IFwiWydcXFwiXVwiIH0sXG4gICAgICAgIHBlZyRjNzggPSAvXlswLTldLyxcbiAgICAgICAgcGVnJGM3OSA9IHsgdHlwZTogXCJjbGFzc1wiLCB2YWx1ZTogXCJbMC05XVwiLCBkZXNjcmlwdGlvbjogXCJbMC05XVwiIH0sXG4gICAgICAgIHBlZyRjODAgPSBmdW5jdGlvbihkaWdpdHMpIHsgcmV0dXJuIHBhcnNlSW50KGRpZ2l0cy5qb2luKFwiXCIpLCAxMCk7IH0sXG4gICAgICAgIHBlZyRjODEgPSB7IHR5cGU6IFwib3RoZXJcIiwgZGVzY3JpcHRpb246IFwic3RyaW5nXCIgfSxcbiAgICAgICAgcGVnJGM4MiA9IFwiXFxcIlwiLFxuICAgICAgICBwZWckYzgzID0geyB0eXBlOiBcImxpdGVyYWxcIiwgdmFsdWU6IFwiXFxcIlwiLCBkZXNjcmlwdGlvbjogXCJcXFwiXFxcXFxcXCJcXFwiXCIgfSxcbiAgICAgICAgcGVnJGM4NCA9IGZ1bmN0aW9uKGNoYXJzKSB7IHJldHVybiBjaGFycy5qb2luKFwiXCIpOyB9LFxuICAgICAgICBwZWckYzg1ID0gXCInXCIsXG4gICAgICAgIHBlZyRjODYgPSB7IHR5cGU6IFwibGl0ZXJhbFwiLCB2YWx1ZTogXCInXCIsIGRlc2NyaXB0aW9uOiBcIlxcXCInXFxcIlwiIH0sXG4gICAgICAgIHBlZyRjODcgPSB2b2lkIDAsXG4gICAgICAgIHBlZyRjODggPSAvXltcIlxcXFxdLyxcbiAgICAgICAgcGVnJGM4OSA9IHsgdHlwZTogXCJjbGFzc1wiLCB2YWx1ZTogXCJbXFxcIlxcXFxcXFxcXVwiLCBkZXNjcmlwdGlvbjogXCJbXFxcIlxcXFxcXFxcXVwiIH0sXG4gICAgICAgIHBlZyRjOTAgPSB7IHR5cGU6IFwiYW55XCIsIGRlc2NyaXB0aW9uOiBcImFueSBjaGFyYWN0ZXJcIiB9LFxuICAgICAgICBwZWckYzkxID0gZnVuY3Rpb24oY2hhcikgeyByZXR1cm4gY2hhcjsgfSxcbiAgICAgICAgcGVnJGM5MiA9IFwiXFxcXFwiLFxuICAgICAgICBwZWckYzkzID0geyB0eXBlOiBcImxpdGVyYWxcIiwgdmFsdWU6IFwiXFxcXFwiLCBkZXNjcmlwdGlvbjogXCJcXFwiXFxcXFxcXFxcXFwiXCIgfSxcbiAgICAgICAgcGVnJGM5NCA9IC9eWydcXFxcXS8sXG4gICAgICAgIHBlZyRjOTUgPSB7IHR5cGU6IFwiY2xhc3NcIiwgdmFsdWU6IFwiWydcXFxcXFxcXF1cIiwgZGVzY3JpcHRpb246IFwiWydcXFxcXFxcXF1cIiB9LFxuICAgICAgICBwZWckYzk2ID0gL15bJ1wiXFxcXF0vLFxuICAgICAgICBwZWckYzk3ID0geyB0eXBlOiBcImNsYXNzXCIsIHZhbHVlOiBcIlsnXFxcIlxcXFxcXFxcXVwiLCBkZXNjcmlwdGlvbjogXCJbJ1xcXCJcXFxcXFxcXF1cIiB9LFxuICAgICAgICBwZWckYzk4ID0gXCJuXCIsXG4gICAgICAgIHBlZyRjOTkgPSB7IHR5cGU6IFwibGl0ZXJhbFwiLCB2YWx1ZTogXCJuXCIsIGRlc2NyaXB0aW9uOiBcIlxcXCJuXFxcIlwiIH0sXG4gICAgICAgIHBlZyRjMTAwID0gZnVuY3Rpb24oKSB7IHJldHVybiBcIlxcblwiOyB9LFxuICAgICAgICBwZWckYzEwMSA9IFwiclwiLFxuICAgICAgICBwZWckYzEwMiA9IHsgdHlwZTogXCJsaXRlcmFsXCIsIHZhbHVlOiBcInJcIiwgZGVzY3JpcHRpb246IFwiXFxcInJcXFwiXCIgfSxcbiAgICAgICAgcGVnJGMxMDMgPSBmdW5jdGlvbigpIHsgcmV0dXJuIFwiXFxyXCI7IH0sXG4gICAgICAgIHBlZyRjMTA0ID0gXCJ0XCIsXG4gICAgICAgIHBlZyRjMTA1ID0geyB0eXBlOiBcImxpdGVyYWxcIiwgdmFsdWU6IFwidFwiLCBkZXNjcmlwdGlvbjogXCJcXFwidFxcXCJcIiB9LFxuICAgICAgICBwZWckYzEwNiA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gXCJcXHRcIjsgfSxcblxuICAgICAgICBwZWckY3VyclBvcyAgICAgICAgICA9IDAsXG4gICAgICAgIHBlZyRyZXBvcnRlZFBvcyAgICAgID0gMCxcbiAgICAgICAgcGVnJGNhY2hlZFBvcyAgICAgICAgPSAwLFxuICAgICAgICBwZWckY2FjaGVkUG9zRGV0YWlscyA9IHsgbGluZTogMSwgY29sdW1uOiAxLCBzZWVuQ1I6IGZhbHNlIH0sXG4gICAgICAgIHBlZyRtYXhGYWlsUG9zICAgICAgID0gMCxcbiAgICAgICAgcGVnJG1heEZhaWxFeHBlY3RlZCAgPSBbXSxcbiAgICAgICAgcGVnJHNpbGVudEZhaWxzICAgICAgPSAwLFxuXG4gICAgICAgIHBlZyRyZXN1bHQ7XG5cbiAgICBpZiAoXCJzdGFydFJ1bGVcIiBpbiBvcHRpb25zKSB7XG4gICAgICBpZiAoIShvcHRpb25zLnN0YXJ0UnVsZSBpbiBwZWckc3RhcnRSdWxlRnVuY3Rpb25zKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW4ndCBzdGFydCBwYXJzaW5nIGZyb20gcnVsZSBcXFwiXCIgKyBvcHRpb25zLnN0YXJ0UnVsZSArIFwiXFxcIi5cIik7XG4gICAgICB9XG5cbiAgICAgIHBlZyRzdGFydFJ1bGVGdW5jdGlvbiA9IHBlZyRzdGFydFJ1bGVGdW5jdGlvbnNbb3B0aW9ucy5zdGFydFJ1bGVdO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHRleHQoKSB7XG4gICAgICByZXR1cm4gaW5wdXQuc3Vic3RyaW5nKHBlZyRyZXBvcnRlZFBvcywgcGVnJGN1cnJQb3MpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIG9mZnNldCgpIHtcbiAgICAgIHJldHVybiBwZWckcmVwb3J0ZWRQb3M7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbGluZSgpIHtcbiAgICAgIHJldHVybiBwZWckY29tcHV0ZVBvc0RldGFpbHMocGVnJHJlcG9ydGVkUG9zKS5saW5lO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNvbHVtbigpIHtcbiAgICAgIHJldHVybiBwZWckY29tcHV0ZVBvc0RldGFpbHMocGVnJHJlcG9ydGVkUG9zKS5jb2x1bW47XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZXhwZWN0ZWQoZGVzY3JpcHRpb24pIHtcbiAgICAgIHRocm93IHBlZyRidWlsZEV4Y2VwdGlvbihcbiAgICAgICAgbnVsbCxcbiAgICAgICAgW3sgdHlwZTogXCJvdGhlclwiLCBkZXNjcmlwdGlvbjogZGVzY3JpcHRpb24gfV0sXG4gICAgICAgIHBlZyRyZXBvcnRlZFBvc1xuICAgICAgKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBlcnJvcihtZXNzYWdlKSB7XG4gICAgICB0aHJvdyBwZWckYnVpbGRFeGNlcHRpb24obWVzc2FnZSwgbnVsbCwgcGVnJHJlcG9ydGVkUG9zKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwZWckY29tcHV0ZVBvc0RldGFpbHMocG9zKSB7XG4gICAgICBmdW5jdGlvbiBhZHZhbmNlKGRldGFpbHMsIHN0YXJ0UG9zLCBlbmRQb3MpIHtcbiAgICAgICAgdmFyIHAsIGNoO1xuXG4gICAgICAgIGZvciAocCA9IHN0YXJ0UG9zOyBwIDwgZW5kUG9zOyBwKyspIHtcbiAgICAgICAgICBjaCA9IGlucHV0LmNoYXJBdChwKTtcbiAgICAgICAgICBpZiAoY2ggPT09IFwiXFxuXCIpIHtcbiAgICAgICAgICAgIGlmICghZGV0YWlscy5zZWVuQ1IpIHsgZGV0YWlscy5saW5lKys7IH1cbiAgICAgICAgICAgIGRldGFpbHMuY29sdW1uID0gMTtcbiAgICAgICAgICAgIGRldGFpbHMuc2VlbkNSID0gZmFsc2U7XG4gICAgICAgICAgfSBlbHNlIGlmIChjaCA9PT0gXCJcXHJcIiB8fCBjaCA9PT0gXCJcXHUyMDI4XCIgfHwgY2ggPT09IFwiXFx1MjAyOVwiKSB7XG4gICAgICAgICAgICBkZXRhaWxzLmxpbmUrKztcbiAgICAgICAgICAgIGRldGFpbHMuY29sdW1uID0gMTtcbiAgICAgICAgICAgIGRldGFpbHMuc2VlbkNSID0gdHJ1ZTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZGV0YWlscy5jb2x1bW4rKztcbiAgICAgICAgICAgIGRldGFpbHMuc2VlbkNSID0gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChwZWckY2FjaGVkUG9zICE9PSBwb3MpIHtcbiAgICAgICAgaWYgKHBlZyRjYWNoZWRQb3MgPiBwb3MpIHtcbiAgICAgICAgICBwZWckY2FjaGVkUG9zID0gMDtcbiAgICAgICAgICBwZWckY2FjaGVkUG9zRGV0YWlscyA9IHsgbGluZTogMSwgY29sdW1uOiAxLCBzZWVuQ1I6IGZhbHNlIH07XG4gICAgICAgIH1cbiAgICAgICAgYWR2YW5jZShwZWckY2FjaGVkUG9zRGV0YWlscywgcGVnJGNhY2hlZFBvcywgcG9zKTtcbiAgICAgICAgcGVnJGNhY2hlZFBvcyA9IHBvcztcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHBlZyRjYWNoZWRQb3NEZXRhaWxzO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHBlZyRmYWlsKGV4cGVjdGVkKSB7XG4gICAgICBpZiAocGVnJGN1cnJQb3MgPCBwZWckbWF4RmFpbFBvcykgeyByZXR1cm47IH1cblxuICAgICAgaWYgKHBlZyRjdXJyUG9zID4gcGVnJG1heEZhaWxQb3MpIHtcbiAgICAgICAgcGVnJG1heEZhaWxQb3MgPSBwZWckY3VyclBvcztcbiAgICAgICAgcGVnJG1heEZhaWxFeHBlY3RlZCA9IFtdO1xuICAgICAgfVxuXG4gICAgICBwZWckbWF4RmFpbEV4cGVjdGVkLnB1c2goZXhwZWN0ZWQpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHBlZyRidWlsZEV4Y2VwdGlvbihtZXNzYWdlLCBleHBlY3RlZCwgcG9zKSB7XG4gICAgICBmdW5jdGlvbiBjbGVhbnVwRXhwZWN0ZWQoZXhwZWN0ZWQpIHtcbiAgICAgICAgdmFyIGkgPSAxO1xuXG4gICAgICAgIGV4cGVjdGVkLnNvcnQoZnVuY3Rpb24oYSwgYikge1xuICAgICAgICAgIGlmIChhLmRlc2NyaXB0aW9uIDwgYi5kZXNjcmlwdGlvbikge1xuICAgICAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgICAgIH0gZWxzZSBpZiAoYS5kZXNjcmlwdGlvbiA+IGIuZGVzY3JpcHRpb24pIHtcbiAgICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHdoaWxlIChpIDwgZXhwZWN0ZWQubGVuZ3RoKSB7XG4gICAgICAgICAgaWYgKGV4cGVjdGVkW2kgLSAxXSA9PT0gZXhwZWN0ZWRbaV0pIHtcbiAgICAgICAgICAgIGV4cGVjdGVkLnNwbGljZShpLCAxKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaSsrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBmdW5jdGlvbiBidWlsZE1lc3NhZ2UoZXhwZWN0ZWQsIGZvdW5kKSB7XG4gICAgICAgIGZ1bmN0aW9uIHN0cmluZ0VzY2FwZShzKSB7XG4gICAgICAgICAgZnVuY3Rpb24gaGV4KGNoKSB7IHJldHVybiBjaC5jaGFyQ29kZUF0KDApLnRvU3RyaW5nKDE2KS50b1VwcGVyQ2FzZSgpOyB9XG5cbiAgICAgICAgICByZXR1cm4gc1xuICAgICAgICAgICAgLnJlcGxhY2UoL1xcXFwvZywgICAnXFxcXFxcXFwnKVxuICAgICAgICAgICAgLnJlcGxhY2UoL1wiL2csICAgICdcXFxcXCInKVxuICAgICAgICAgICAgLnJlcGxhY2UoL1xceDA4L2csICdcXFxcYicpXG4gICAgICAgICAgICAucmVwbGFjZSgvXFx0L2csICAgJ1xcXFx0JylcbiAgICAgICAgICAgIC5yZXBsYWNlKC9cXG4vZywgICAnXFxcXG4nKVxuICAgICAgICAgICAgLnJlcGxhY2UoL1xcZi9nLCAgICdcXFxcZicpXG4gICAgICAgICAgICAucmVwbGFjZSgvXFxyL2csICAgJ1xcXFxyJylcbiAgICAgICAgICAgIC5yZXBsYWNlKC9bXFx4MDAtXFx4MDdcXHgwQlxceDBFXFx4MEZdL2csIGZ1bmN0aW9uKGNoKSB7IHJldHVybiAnXFxcXHgwJyArIGhleChjaCk7IH0pXG4gICAgICAgICAgICAucmVwbGFjZSgvW1xceDEwLVxceDFGXFx4ODAtXFx4RkZdL2csICAgIGZ1bmN0aW9uKGNoKSB7IHJldHVybiAnXFxcXHgnICArIGhleChjaCk7IH0pXG4gICAgICAgICAgICAucmVwbGFjZSgvW1xcdTAxODAtXFx1MEZGRl0vZywgICAgICAgICBmdW5jdGlvbihjaCkgeyByZXR1cm4gJ1xcXFx1MCcgKyBoZXgoY2gpOyB9KVxuICAgICAgICAgICAgLnJlcGxhY2UoL1tcXHUxMDgwLVxcdUZGRkZdL2csICAgICAgICAgZnVuY3Rpb24oY2gpIHsgcmV0dXJuICdcXFxcdScgICsgaGV4KGNoKTsgfSk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgZXhwZWN0ZWREZXNjcyA9IG5ldyBBcnJheShleHBlY3RlZC5sZW5ndGgpLFxuICAgICAgICAgICAgZXhwZWN0ZWREZXNjLCBmb3VuZERlc2MsIGk7XG5cbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGV4cGVjdGVkLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgZXhwZWN0ZWREZXNjc1tpXSA9IGV4cGVjdGVkW2ldLmRlc2NyaXB0aW9uO1xuICAgICAgICB9XG5cbiAgICAgICAgZXhwZWN0ZWREZXNjID0gZXhwZWN0ZWQubGVuZ3RoID4gMVxuICAgICAgICAgID8gZXhwZWN0ZWREZXNjcy5zbGljZSgwLCAtMSkuam9pbihcIiwgXCIpXG4gICAgICAgICAgICAgICsgXCIgb3IgXCJcbiAgICAgICAgICAgICAgKyBleHBlY3RlZERlc2NzW2V4cGVjdGVkLmxlbmd0aCAtIDFdXG4gICAgICAgICAgOiBleHBlY3RlZERlc2NzWzBdO1xuXG4gICAgICAgIGZvdW5kRGVzYyA9IGZvdW5kID8gXCJcXFwiXCIgKyBzdHJpbmdFc2NhcGUoZm91bmQpICsgXCJcXFwiXCIgOiBcImVuZCBvZiBpbnB1dFwiO1xuXG4gICAgICAgIHJldHVybiBcIkV4cGVjdGVkIFwiICsgZXhwZWN0ZWREZXNjICsgXCIgYnV0IFwiICsgZm91bmREZXNjICsgXCIgZm91bmQuXCI7XG4gICAgICB9XG5cbiAgICAgIHZhciBwb3NEZXRhaWxzID0gcGVnJGNvbXB1dGVQb3NEZXRhaWxzKHBvcyksXG4gICAgICAgICAgZm91bmQgICAgICA9IHBvcyA8IGlucHV0Lmxlbmd0aCA/IGlucHV0LmNoYXJBdChwb3MpIDogbnVsbDtcblxuICAgICAgaWYgKGV4cGVjdGVkICE9PSBudWxsKSB7XG4gICAgICAgIGNsZWFudXBFeHBlY3RlZChleHBlY3RlZCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBuZXcgU3ludGF4RXJyb3IoXG4gICAgICAgIG1lc3NhZ2UgIT09IG51bGwgPyBtZXNzYWdlIDogYnVpbGRNZXNzYWdlKGV4cGVjdGVkLCBmb3VuZCksXG4gICAgICAgIGV4cGVjdGVkLFxuICAgICAgICBmb3VuZCxcbiAgICAgICAgcG9zLFxuICAgICAgICBwb3NEZXRhaWxzLmxpbmUsXG4gICAgICAgIHBvc0RldGFpbHMuY29sdW1uXG4gICAgICApO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHBlZyRwYXJzZXN0YXJ0KCkge1xuICAgICAgdmFyIHMwLCBzMSwgczIsIHMzO1xuXG4gICAgICBwZWckc2lsZW50RmFpbHMrKztcbiAgICAgIHMwID0gcGVnJGN1cnJQb3M7XG4gICAgICBzMSA9IHBlZyRwYXJzZV9fKCk7XG4gICAgICBpZiAoczEgIT09IHBlZyRGQUlMRUQpIHtcbiAgICAgICAgczIgPSBwZWckcGFyc2VPckV4cHIoKTtcbiAgICAgICAgaWYgKHMyICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgczMgPSBwZWckcGFyc2VfXygpO1xuICAgICAgICAgIGlmIChzMyAhPT0gcGVnJEZBSUxFRCkge1xuICAgICAgICAgICAgcGVnJHJlcG9ydGVkUG9zID0gczA7XG4gICAgICAgICAgICBzMSA9IHBlZyRjMihzMik7XG4gICAgICAgICAgICBzMCA9IHMxO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwZWckY3VyclBvcyA9IHMwO1xuICAgICAgICAgICAgczAgPSBwZWckYzE7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHBlZyRjdXJyUG9zID0gczA7XG4gICAgICAgICAgczAgPSBwZWckYzE7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHBlZyRjdXJyUG9zID0gczA7XG4gICAgICAgIHMwID0gcGVnJGMxO1xuICAgICAgfVxuICAgICAgaWYgKHMwID09PSBwZWckRkFJTEVEKSB7XG4gICAgICAgIHMwID0gcGVnJGN1cnJQb3M7XG4gICAgICAgIHMxID0gW107XG4gICAgICAgIGlmIChzMSAhPT0gcGVnJEZBSUxFRCkge1xuICAgICAgICAgIHBlZyRyZXBvcnRlZFBvcyA9IHMwO1xuICAgICAgICAgIHMxID0gcGVnJGM0KCk7XG4gICAgICAgIH1cbiAgICAgICAgczAgPSBzMTtcbiAgICAgIH1cbiAgICAgIHBlZyRzaWxlbnRGYWlscy0tO1xuICAgICAgaWYgKHMwID09PSBwZWckRkFJTEVEKSB7XG4gICAgICAgIHMxID0gcGVnJEZBSUxFRDtcbiAgICAgICAgaWYgKHBlZyRzaWxlbnRGYWlscyA9PT0gMCkgeyBwZWckZmFpbChwZWckYzApOyB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBzMDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwZWckcGFyc2V3cygpIHtcbiAgICAgIHZhciBzMCwgczE7XG5cbiAgICAgIHBlZyRzaWxlbnRGYWlscysrO1xuICAgICAgaWYgKHBlZyRjNi50ZXN0KGlucHV0LmNoYXJBdChwZWckY3VyclBvcykpKSB7XG4gICAgICAgIHMwID0gaW5wdXQuY2hhckF0KHBlZyRjdXJyUG9zKTtcbiAgICAgICAgcGVnJGN1cnJQb3MrKztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHMwID0gcGVnJEZBSUxFRDtcbiAgICAgICAgaWYgKHBlZyRzaWxlbnRGYWlscyA9PT0gMCkgeyBwZWckZmFpbChwZWckYzcpOyB9XG4gICAgICB9XG4gICAgICBwZWckc2lsZW50RmFpbHMtLTtcbiAgICAgIGlmIChzMCA9PT0gcGVnJEZBSUxFRCkge1xuICAgICAgICBzMSA9IHBlZyRGQUlMRUQ7XG4gICAgICAgIGlmIChwZWckc2lsZW50RmFpbHMgPT09IDApIHsgcGVnJGZhaWwocGVnJGM1KTsgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gczA7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcGVnJHBhcnNlY2MoKSB7XG4gICAgICB2YXIgczAsIHMxO1xuXG4gICAgICBwZWckc2lsZW50RmFpbHMrKztcbiAgICAgIGlmIChwZWckYzkudGVzdChpbnB1dC5jaGFyQXQocGVnJGN1cnJQb3MpKSkge1xuICAgICAgICBzMCA9IGlucHV0LmNoYXJBdChwZWckY3VyclBvcyk7XG4gICAgICAgIHBlZyRjdXJyUG9zKys7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzMCA9IHBlZyRGQUlMRUQ7XG4gICAgICAgIGlmIChwZWckc2lsZW50RmFpbHMgPT09IDApIHsgcGVnJGZhaWwocGVnJGMxMCk7IH1cbiAgICAgIH1cbiAgICAgIHBlZyRzaWxlbnRGYWlscy0tO1xuICAgICAgaWYgKHMwID09PSBwZWckRkFJTEVEKSB7XG4gICAgICAgIHMxID0gcGVnJEZBSUxFRDtcbiAgICAgICAgaWYgKHBlZyRzaWxlbnRGYWlscyA9PT0gMCkgeyBwZWckZmFpbChwZWckYzgpOyB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBzMDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwZWckcGFyc2VfXygpIHtcbiAgICAgIHZhciBzMCwgczE7XG5cbiAgICAgIHBlZyRzaWxlbnRGYWlscysrO1xuICAgICAgczAgPSBbXTtcbiAgICAgIHMxID0gcGVnJHBhcnNld3MoKTtcbiAgICAgIHdoaWxlIChzMSAhPT0gcGVnJEZBSUxFRCkge1xuICAgICAgICBzMC5wdXNoKHMxKTtcbiAgICAgICAgczEgPSBwZWckcGFyc2V3cygpO1xuICAgICAgfVxuICAgICAgcGVnJHNpbGVudEZhaWxzLS07XG4gICAgICBpZiAoczAgPT09IHBlZyRGQUlMRUQpIHtcbiAgICAgICAgczEgPSBwZWckRkFJTEVEO1xuICAgICAgICBpZiAocGVnJHNpbGVudEZhaWxzID09PSAwKSB7IHBlZyRmYWlsKHBlZyRjMTEpOyB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBzMDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwZWckcGFyc2VPckV4cHIoKSB7XG4gICAgICB2YXIgczAsIHMxLCBzMiwgczMsIHM0LCBzNTtcblxuICAgICAgczAgPSBwZWckY3VyclBvcztcbiAgICAgIHMxID0gcGVnJHBhcnNlQW5kRXhwcigpO1xuICAgICAgaWYgKHMxICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgIHMyID0gcGVnJHBhcnNlX18oKTtcbiAgICAgICAgaWYgKHMyICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgaWYgKGlucHV0LmNoYXJDb2RlQXQocGVnJGN1cnJQb3MpID09PSAxMjQpIHtcbiAgICAgICAgICAgIHMzID0gcGVnJGMxMjtcbiAgICAgICAgICAgIHBlZyRjdXJyUG9zKys7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHMzID0gcGVnJEZBSUxFRDtcbiAgICAgICAgICAgIGlmIChwZWckc2lsZW50RmFpbHMgPT09IDApIHsgcGVnJGZhaWwocGVnJGMxMyk7IH1cbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHMzICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgICBzNCA9IHBlZyRwYXJzZV9fKCk7XG4gICAgICAgICAgICBpZiAoczQgIT09IHBlZyRGQUlMRUQpIHtcbiAgICAgICAgICAgICAgczUgPSBwZWckcGFyc2VPckV4cHIoKTtcbiAgICAgICAgICAgICAgaWYgKHM1ICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgICAgICAgcGVnJHJlcG9ydGVkUG9zID0gczA7XG4gICAgICAgICAgICAgICAgczEgPSBwZWckYzE0KHMxLCBzNSk7XG4gICAgICAgICAgICAgICAgczAgPSBzMTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBwZWckY3VyclBvcyA9IHMwO1xuICAgICAgICAgICAgICAgIHMwID0gcGVnJGMxO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBwZWckY3VyclBvcyA9IHMwO1xuICAgICAgICAgICAgICBzMCA9IHBlZyRjMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcGVnJGN1cnJQb3MgPSBzMDtcbiAgICAgICAgICAgIHMwID0gcGVnJGMxO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBwZWckY3VyclBvcyA9IHMwO1xuICAgICAgICAgIHMwID0gcGVnJGMxO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwZWckY3VyclBvcyA9IHMwO1xuICAgICAgICBzMCA9IHBlZyRjMTtcbiAgICAgIH1cbiAgICAgIGlmIChzMCA9PT0gcGVnJEZBSUxFRCkge1xuICAgICAgICBzMCA9IHBlZyRwYXJzZUFuZEV4cHIoKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHMwO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHBlZyRwYXJzZUFuZEV4cHIoKSB7XG4gICAgICB2YXIgczAsIHMxLCBzMiwgczMsIHM0LCBzNTtcblxuICAgICAgczAgPSBwZWckY3VyclBvcztcbiAgICAgIHMxID0gcGVnJHBhcnNlTm90RXhwcigpO1xuICAgICAgaWYgKHMxICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgIHMyID0gcGVnJHBhcnNlX18oKTtcbiAgICAgICAgaWYgKHMyICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgaWYgKGlucHV0LmNoYXJDb2RlQXQocGVnJGN1cnJQb3MpID09PSAzOCkge1xuICAgICAgICAgICAgczMgPSBwZWckYzE1O1xuICAgICAgICAgICAgcGVnJGN1cnJQb3MrKztcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgczMgPSBwZWckRkFJTEVEO1xuICAgICAgICAgICAgaWYgKHBlZyRzaWxlbnRGYWlscyA9PT0gMCkgeyBwZWckZmFpbChwZWckYzE2KTsgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoczMgIT09IHBlZyRGQUlMRUQpIHtcbiAgICAgICAgICAgIHM0ID0gcGVnJHBhcnNlX18oKTtcbiAgICAgICAgICAgIGlmIChzNCAhPT0gcGVnJEZBSUxFRCkge1xuICAgICAgICAgICAgICBzNSA9IHBlZyRwYXJzZUFuZEV4cHIoKTtcbiAgICAgICAgICAgICAgaWYgKHM1ICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgICAgICAgcGVnJHJlcG9ydGVkUG9zID0gczA7XG4gICAgICAgICAgICAgICAgczEgPSBwZWckYzE3KHMxLCBzNSk7XG4gICAgICAgICAgICAgICAgczAgPSBzMTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBwZWckY3VyclBvcyA9IHMwO1xuICAgICAgICAgICAgICAgIHMwID0gcGVnJGMxO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBwZWckY3VyclBvcyA9IHMwO1xuICAgICAgICAgICAgICBzMCA9IHBlZyRjMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcGVnJGN1cnJQb3MgPSBzMDtcbiAgICAgICAgICAgIHMwID0gcGVnJGMxO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBwZWckY3VyclBvcyA9IHMwO1xuICAgICAgICAgIHMwID0gcGVnJGMxO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwZWckY3VyclBvcyA9IHMwO1xuICAgICAgICBzMCA9IHBlZyRjMTtcbiAgICAgIH1cbiAgICAgIGlmIChzMCA9PT0gcGVnJEZBSUxFRCkge1xuICAgICAgICBzMCA9IHBlZyRjdXJyUG9zO1xuICAgICAgICBzMSA9IHBlZyRwYXJzZU5vdEV4cHIoKTtcbiAgICAgICAgaWYgKHMxICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgczIgPSBbXTtcbiAgICAgICAgICBzMyA9IHBlZyRwYXJzZXdzKCk7XG4gICAgICAgICAgaWYgKHMzICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgICB3aGlsZSAoczMgIT09IHBlZyRGQUlMRUQpIHtcbiAgICAgICAgICAgICAgczIucHVzaChzMyk7XG4gICAgICAgICAgICAgIHMzID0gcGVnJHBhcnNld3MoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgczIgPSBwZWckYzE7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChzMiAhPT0gcGVnJEZBSUxFRCkge1xuICAgICAgICAgICAgczMgPSBwZWckcGFyc2VBbmRFeHByKCk7XG4gICAgICAgICAgICBpZiAoczMgIT09IHBlZyRGQUlMRUQpIHtcbiAgICAgICAgICAgICAgcGVnJHJlcG9ydGVkUG9zID0gczA7XG4gICAgICAgICAgICAgIHMxID0gcGVnJGMxNyhzMSwgczMpO1xuICAgICAgICAgICAgICBzMCA9IHMxO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgcGVnJGN1cnJQb3MgPSBzMDtcbiAgICAgICAgICAgICAgczAgPSBwZWckYzE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHBlZyRjdXJyUG9zID0gczA7XG4gICAgICAgICAgICBzMCA9IHBlZyRjMTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcGVnJGN1cnJQb3MgPSBzMDtcbiAgICAgICAgICBzMCA9IHBlZyRjMTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoczAgPT09IHBlZyRGQUlMRUQpIHtcbiAgICAgICAgICBzMCA9IHBlZyRwYXJzZU5vdEV4cHIoKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gczA7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcGVnJHBhcnNlTm90RXhwcigpIHtcbiAgICAgIHZhciBzMCwgczEsIHMyLCBzMztcblxuICAgICAgczAgPSBwZWckY3VyclBvcztcbiAgICAgIGlmIChpbnB1dC5jaGFyQ29kZUF0KHBlZyRjdXJyUG9zKSA9PT0gMzMpIHtcbiAgICAgICAgczEgPSBwZWckYzE4O1xuICAgICAgICBwZWckY3VyclBvcysrO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgczEgPSBwZWckRkFJTEVEO1xuICAgICAgICBpZiAocGVnJHNpbGVudEZhaWxzID09PSAwKSB7IHBlZyRmYWlsKHBlZyRjMTkpOyB9XG4gICAgICB9XG4gICAgICBpZiAoczEgIT09IHBlZyRGQUlMRUQpIHtcbiAgICAgICAgczIgPSBwZWckcGFyc2VfXygpO1xuICAgICAgICBpZiAoczIgIT09IHBlZyRGQUlMRUQpIHtcbiAgICAgICAgICBzMyA9IHBlZyRwYXJzZU5vdEV4cHIoKTtcbiAgICAgICAgICBpZiAoczMgIT09IHBlZyRGQUlMRUQpIHtcbiAgICAgICAgICAgIHBlZyRyZXBvcnRlZFBvcyA9IHMwO1xuICAgICAgICAgICAgczEgPSBwZWckYzIwKHMzKTtcbiAgICAgICAgICAgIHMwID0gczE7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHBlZyRjdXJyUG9zID0gczA7XG4gICAgICAgICAgICBzMCA9IHBlZyRjMTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcGVnJGN1cnJQb3MgPSBzMDtcbiAgICAgICAgICBzMCA9IHBlZyRjMTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcGVnJGN1cnJQb3MgPSBzMDtcbiAgICAgICAgczAgPSBwZWckYzE7XG4gICAgICB9XG4gICAgICBpZiAoczAgPT09IHBlZyRGQUlMRUQpIHtcbiAgICAgICAgczAgPSBwZWckcGFyc2VCaW5kaW5nRXhwcigpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gczA7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcGVnJHBhcnNlQmluZGluZ0V4cHIoKSB7XG4gICAgICB2YXIgczAsIHMxLCBzMiwgczMsIHM0LCBzNTtcblxuICAgICAgczAgPSBwZWckY3VyclBvcztcbiAgICAgIGlmIChpbnB1dC5jaGFyQ29kZUF0KHBlZyRjdXJyUG9zKSA9PT0gNDApIHtcbiAgICAgICAgczEgPSBwZWckYzIxO1xuICAgICAgICBwZWckY3VyclBvcysrO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgczEgPSBwZWckRkFJTEVEO1xuICAgICAgICBpZiAocGVnJHNpbGVudEZhaWxzID09PSAwKSB7IHBlZyRmYWlsKHBlZyRjMjIpOyB9XG4gICAgICB9XG4gICAgICBpZiAoczEgIT09IHBlZyRGQUlMRUQpIHtcbiAgICAgICAgczIgPSBwZWckcGFyc2VfXygpO1xuICAgICAgICBpZiAoczIgIT09IHBlZyRGQUlMRUQpIHtcbiAgICAgICAgICBzMyA9IHBlZyRwYXJzZU9yRXhwcigpO1xuICAgICAgICAgIGlmIChzMyAhPT0gcGVnJEZBSUxFRCkge1xuICAgICAgICAgICAgczQgPSBwZWckcGFyc2VfXygpO1xuICAgICAgICAgICAgaWYgKHM0ICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgICAgIGlmIChpbnB1dC5jaGFyQ29kZUF0KHBlZyRjdXJyUG9zKSA9PT0gNDEpIHtcbiAgICAgICAgICAgICAgICBzNSA9IHBlZyRjMjM7XG4gICAgICAgICAgICAgICAgcGVnJGN1cnJQb3MrKztcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzNSA9IHBlZyRGQUlMRUQ7XG4gICAgICAgICAgICAgICAgaWYgKHBlZyRzaWxlbnRGYWlscyA9PT0gMCkgeyBwZWckZmFpbChwZWckYzI0KTsgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGlmIChzNSAhPT0gcGVnJEZBSUxFRCkge1xuICAgICAgICAgICAgICAgIHBlZyRyZXBvcnRlZFBvcyA9IHMwO1xuICAgICAgICAgICAgICAgIHMxID0gcGVnJGMyNShzMyk7XG4gICAgICAgICAgICAgICAgczAgPSBzMTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBwZWckY3VyclBvcyA9IHMwO1xuICAgICAgICAgICAgICAgIHMwID0gcGVnJGMxO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBwZWckY3VyclBvcyA9IHMwO1xuICAgICAgICAgICAgICBzMCA9IHBlZyRjMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcGVnJGN1cnJQb3MgPSBzMDtcbiAgICAgICAgICAgIHMwID0gcGVnJGMxO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBwZWckY3VyclBvcyA9IHMwO1xuICAgICAgICAgIHMwID0gcGVnJGMxO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwZWckY3VyclBvcyA9IHMwO1xuICAgICAgICBzMCA9IHBlZyRjMTtcbiAgICAgIH1cbiAgICAgIGlmIChzMCA9PT0gcGVnJEZBSUxFRCkge1xuICAgICAgICBzMCA9IHBlZyRwYXJzZUV4cHIoKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHMwO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHBlZyRwYXJzZUV4cHIoKSB7XG4gICAgICB2YXIgczA7XG5cbiAgICAgIHMwID0gcGVnJHBhcnNlTnVsbGFyeUV4cHIoKTtcbiAgICAgIGlmIChzMCA9PT0gcGVnJEZBSUxFRCkge1xuICAgICAgICBzMCA9IHBlZyRwYXJzZVVuYXJ5RXhwcigpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gczA7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcGVnJHBhcnNlTnVsbGFyeUV4cHIoKSB7XG4gICAgICB2YXIgczAsIHMxO1xuXG4gICAgICBzMCA9IHBlZyRwYXJzZUJvb2xlYW5MaXRlcmFsKCk7XG4gICAgICBpZiAoczAgPT09IHBlZyRGQUlMRUQpIHtcbiAgICAgICAgczAgPSBwZWckY3VyclBvcztcbiAgICAgICAgaWYgKGlucHV0LnN1YnN0cihwZWckY3VyclBvcywgMikgPT09IHBlZyRjMjYpIHtcbiAgICAgICAgICBzMSA9IHBlZyRjMjY7XG4gICAgICAgICAgcGVnJGN1cnJQb3MgKz0gMjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzMSA9IHBlZyRGQUlMRUQ7XG4gICAgICAgICAgaWYgKHBlZyRzaWxlbnRGYWlscyA9PT0gMCkgeyBwZWckZmFpbChwZWckYzI3KTsgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChzMSAhPT0gcGVnJEZBSUxFRCkge1xuICAgICAgICAgIHBlZyRyZXBvcnRlZFBvcyA9IHMwO1xuICAgICAgICAgIHMxID0gcGVnJGMyOCgpO1xuICAgICAgICB9XG4gICAgICAgIHMwID0gczE7XG4gICAgICAgIGlmIChzMCA9PT0gcGVnJEZBSUxFRCkge1xuICAgICAgICAgIHMwID0gcGVnJGN1cnJQb3M7XG4gICAgICAgICAgaWYgKGlucHV0LnN1YnN0cihwZWckY3VyclBvcywgMikgPT09IHBlZyRjMjkpIHtcbiAgICAgICAgICAgIHMxID0gcGVnJGMyOTtcbiAgICAgICAgICAgIHBlZyRjdXJyUG9zICs9IDI7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHMxID0gcGVnJEZBSUxFRDtcbiAgICAgICAgICAgIGlmIChwZWckc2lsZW50RmFpbHMgPT09IDApIHsgcGVnJGZhaWwocGVnJGMzMCk7IH1cbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHMxICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgICBwZWckcmVwb3J0ZWRQb3MgPSBzMDtcbiAgICAgICAgICAgIHMxID0gcGVnJGMzMSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBzMCA9IHMxO1xuICAgICAgICAgIGlmIChzMCA9PT0gcGVnJEZBSUxFRCkge1xuICAgICAgICAgICAgczAgPSBwZWckY3VyclBvcztcbiAgICAgICAgICAgIGlmIChpbnB1dC5zdWJzdHIocGVnJGN1cnJQb3MsIDIpID09PSBwZWckYzMyKSB7XG4gICAgICAgICAgICAgIHMxID0gcGVnJGMzMjtcbiAgICAgICAgICAgICAgcGVnJGN1cnJQb3MgKz0gMjtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHMxID0gcGVnJEZBSUxFRDtcbiAgICAgICAgICAgICAgaWYgKHBlZyRzaWxlbnRGYWlscyA9PT0gMCkgeyBwZWckZmFpbChwZWckYzMzKTsgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHMxICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgICAgIHBlZyRyZXBvcnRlZFBvcyA9IHMwO1xuICAgICAgICAgICAgICBzMSA9IHBlZyRjMzQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHMwID0gczE7XG4gICAgICAgICAgICBpZiAoczAgPT09IHBlZyRGQUlMRUQpIHtcbiAgICAgICAgICAgICAgczAgPSBwZWckY3VyclBvcztcbiAgICAgICAgICAgICAgaWYgKGlucHV0LnN1YnN0cihwZWckY3VyclBvcywgMikgPT09IHBlZyRjMzUpIHtcbiAgICAgICAgICAgICAgICBzMSA9IHBlZyRjMzU7XG4gICAgICAgICAgICAgICAgcGVnJGN1cnJQb3MgKz0gMjtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzMSA9IHBlZyRGQUlMRUQ7XG4gICAgICAgICAgICAgICAgaWYgKHBlZyRzaWxlbnRGYWlscyA9PT0gMCkgeyBwZWckZmFpbChwZWckYzM2KTsgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGlmIChzMSAhPT0gcGVnJEZBSUxFRCkge1xuICAgICAgICAgICAgICAgIHBlZyRyZXBvcnRlZFBvcyA9IHMwO1xuICAgICAgICAgICAgICAgIHMxID0gcGVnJGMzNygpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHMwID0gczE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBzMDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwZWckcGFyc2VCb29sZWFuTGl0ZXJhbCgpIHtcbiAgICAgIHZhciBzMCwgczE7XG5cbiAgICAgIHMwID0gcGVnJGN1cnJQb3M7XG4gICAgICBpZiAoaW5wdXQuc3Vic3RyKHBlZyRjdXJyUG9zLCA0KSA9PT0gcGVnJGMzOCkge1xuICAgICAgICBzMSA9IHBlZyRjMzg7XG4gICAgICAgIHBlZyRjdXJyUG9zICs9IDQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzMSA9IHBlZyRGQUlMRUQ7XG4gICAgICAgIGlmIChwZWckc2lsZW50RmFpbHMgPT09IDApIHsgcGVnJGZhaWwocGVnJGMzOSk7IH1cbiAgICAgIH1cbiAgICAgIGlmIChzMSAhPT0gcGVnJEZBSUxFRCkge1xuICAgICAgICBwZWckcmVwb3J0ZWRQb3MgPSBzMDtcbiAgICAgICAgczEgPSBwZWckYzQwKCk7XG4gICAgICB9XG4gICAgICBzMCA9IHMxO1xuICAgICAgaWYgKHMwID09PSBwZWckRkFJTEVEKSB7XG4gICAgICAgIHMwID0gcGVnJGN1cnJQb3M7XG4gICAgICAgIGlmIChpbnB1dC5zdWJzdHIocGVnJGN1cnJQb3MsIDUpID09PSBwZWckYzQxKSB7XG4gICAgICAgICAgczEgPSBwZWckYzQxO1xuICAgICAgICAgIHBlZyRjdXJyUG9zICs9IDU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgczEgPSBwZWckRkFJTEVEO1xuICAgICAgICAgIGlmIChwZWckc2lsZW50RmFpbHMgPT09IDApIHsgcGVnJGZhaWwocGVnJGM0Mik7IH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoczEgIT09IHBlZyRGQUlMRUQpIHtcbiAgICAgICAgICBwZWckcmVwb3J0ZWRQb3MgPSBzMDtcbiAgICAgICAgICBzMSA9IHBlZyRjNDMoKTtcbiAgICAgICAgfVxuICAgICAgICBzMCA9IHMxO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gczA7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcGVnJHBhcnNlVW5hcnlFeHByKCkge1xuICAgICAgdmFyIHMwLCBzMSwgczIsIHMzO1xuXG4gICAgICBzMCA9IHBlZyRjdXJyUG9zO1xuICAgICAgaWYgKGlucHV0LnN1YnN0cihwZWckY3VyclBvcywgMikgPT09IHBlZyRjNDQpIHtcbiAgICAgICAgczEgPSBwZWckYzQ0O1xuICAgICAgICBwZWckY3VyclBvcyArPSAyO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgczEgPSBwZWckRkFJTEVEO1xuICAgICAgICBpZiAocGVnJHNpbGVudEZhaWxzID09PSAwKSB7IHBlZyRmYWlsKHBlZyRjNDUpOyB9XG4gICAgICB9XG4gICAgICBpZiAoczEgIT09IHBlZyRGQUlMRUQpIHtcbiAgICAgICAgczIgPSBbXTtcbiAgICAgICAgczMgPSBwZWckcGFyc2V3cygpO1xuICAgICAgICBpZiAoczMgIT09IHBlZyRGQUlMRUQpIHtcbiAgICAgICAgICB3aGlsZSAoczMgIT09IHBlZyRGQUlMRUQpIHtcbiAgICAgICAgICAgIHMyLnB1c2goczMpO1xuICAgICAgICAgICAgczMgPSBwZWckcGFyc2V3cygpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzMiA9IHBlZyRjMTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoczIgIT09IHBlZyRGQUlMRUQpIHtcbiAgICAgICAgICBzMyA9IHBlZyRwYXJzZUludGVnZXJMaXRlcmFsKCk7XG4gICAgICAgICAgaWYgKHMzICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgICBwZWckcmVwb3J0ZWRQb3MgPSBzMDtcbiAgICAgICAgICAgIHMxID0gcGVnJGM0NihzMyk7XG4gICAgICAgICAgICBzMCA9IHMxO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwZWckY3VyclBvcyA9IHMwO1xuICAgICAgICAgICAgczAgPSBwZWckYzE7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHBlZyRjdXJyUG9zID0gczA7XG4gICAgICAgICAgczAgPSBwZWckYzE7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHBlZyRjdXJyUG9zID0gczA7XG4gICAgICAgIHMwID0gcGVnJGMxO1xuICAgICAgfVxuICAgICAgaWYgKHMwID09PSBwZWckRkFJTEVEKSB7XG4gICAgICAgIHMwID0gcGVnJGN1cnJQb3M7XG4gICAgICAgIGlmIChpbnB1dC5zdWJzdHIocGVnJGN1cnJQb3MsIDIpID09PSBwZWckYzQ3KSB7XG4gICAgICAgICAgczEgPSBwZWckYzQ3O1xuICAgICAgICAgIHBlZyRjdXJyUG9zICs9IDI7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgczEgPSBwZWckRkFJTEVEO1xuICAgICAgICAgIGlmIChwZWckc2lsZW50RmFpbHMgPT09IDApIHsgcGVnJGZhaWwocGVnJGM0OCk7IH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoczEgIT09IHBlZyRGQUlMRUQpIHtcbiAgICAgICAgICBzMiA9IFtdO1xuICAgICAgICAgIHMzID0gcGVnJHBhcnNld3MoKTtcbiAgICAgICAgICBpZiAoczMgIT09IHBlZyRGQUlMRUQpIHtcbiAgICAgICAgICAgIHdoaWxlIChzMyAhPT0gcGVnJEZBSUxFRCkge1xuICAgICAgICAgICAgICBzMi5wdXNoKHMzKTtcbiAgICAgICAgICAgICAgczMgPSBwZWckcGFyc2V3cygpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzMiA9IHBlZyRjMTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHMyICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgICBzMyA9IHBlZyRwYXJzZVN0cmluZ0xpdGVyYWwoKTtcbiAgICAgICAgICAgIGlmIChzMyAhPT0gcGVnJEZBSUxFRCkge1xuICAgICAgICAgICAgICBwZWckcmVwb3J0ZWRQb3MgPSBzMDtcbiAgICAgICAgICAgICAgczEgPSBwZWckYzQ5KHMzKTtcbiAgICAgICAgICAgICAgczAgPSBzMTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHBlZyRjdXJyUG9zID0gczA7XG4gICAgICAgICAgICAgIHMwID0gcGVnJGMxO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwZWckY3VyclBvcyA9IHMwO1xuICAgICAgICAgICAgczAgPSBwZWckYzE7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHBlZyRjdXJyUG9zID0gczA7XG4gICAgICAgICAgczAgPSBwZWckYzE7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHMwID09PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgczAgPSBwZWckY3VyclBvcztcbiAgICAgICAgICBpZiAoaW5wdXQuc3Vic3RyKHBlZyRjdXJyUG9zLCAyKSA9PT0gcGVnJGM1MCkge1xuICAgICAgICAgICAgczEgPSBwZWckYzUwO1xuICAgICAgICAgICAgcGVnJGN1cnJQb3MgKz0gMjtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgczEgPSBwZWckRkFJTEVEO1xuICAgICAgICAgICAgaWYgKHBlZyRzaWxlbnRGYWlscyA9PT0gMCkgeyBwZWckZmFpbChwZWckYzUxKTsgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoczEgIT09IHBlZyRGQUlMRUQpIHtcbiAgICAgICAgICAgIHMyID0gW107XG4gICAgICAgICAgICBzMyA9IHBlZyRwYXJzZXdzKCk7XG4gICAgICAgICAgICBpZiAoczMgIT09IHBlZyRGQUlMRUQpIHtcbiAgICAgICAgICAgICAgd2hpbGUgKHMzICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgICAgICAgczIucHVzaChzMyk7XG4gICAgICAgICAgICAgICAgczMgPSBwZWckcGFyc2V3cygpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBzMiA9IHBlZyRjMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChzMiAhPT0gcGVnJEZBSUxFRCkge1xuICAgICAgICAgICAgICBzMyA9IHBlZyRwYXJzZVN0cmluZ0xpdGVyYWwoKTtcbiAgICAgICAgICAgICAgaWYgKHMzICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgICAgICAgcGVnJHJlcG9ydGVkUG9zID0gczA7XG4gICAgICAgICAgICAgICAgczEgPSBwZWckYzUyKHMzKTtcbiAgICAgICAgICAgICAgICBzMCA9IHMxO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHBlZyRjdXJyUG9zID0gczA7XG4gICAgICAgICAgICAgICAgczAgPSBwZWckYzE7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHBlZyRjdXJyUG9zID0gczA7XG4gICAgICAgICAgICAgIHMwID0gcGVnJGMxO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwZWckY3VyclBvcyA9IHMwO1xuICAgICAgICAgICAgczAgPSBwZWckYzE7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChzMCA9PT0gcGVnJEZBSUxFRCkge1xuICAgICAgICAgICAgczAgPSBwZWckY3VyclBvcztcbiAgICAgICAgICAgIGlmIChpbnB1dC5zdWJzdHIocGVnJGN1cnJQb3MsIDMpID09PSBwZWckYzUzKSB7XG4gICAgICAgICAgICAgIHMxID0gcGVnJGM1MztcbiAgICAgICAgICAgICAgcGVnJGN1cnJQb3MgKz0gMztcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHMxID0gcGVnJEZBSUxFRDtcbiAgICAgICAgICAgICAgaWYgKHBlZyRzaWxlbnRGYWlscyA9PT0gMCkgeyBwZWckZmFpbChwZWckYzU0KTsgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHMxICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgICAgIHMyID0gW107XG4gICAgICAgICAgICAgIHMzID0gcGVnJHBhcnNld3MoKTtcbiAgICAgICAgICAgICAgaWYgKHMzICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgICAgICAgd2hpbGUgKHMzICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgICAgICAgICBzMi5wdXNoKHMzKTtcbiAgICAgICAgICAgICAgICAgIHMzID0gcGVnJHBhcnNld3MoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgczIgPSBwZWckYzE7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaWYgKHMyICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgICAgICAgczMgPSBwZWckcGFyc2VTdHJpbmdMaXRlcmFsKCk7XG4gICAgICAgICAgICAgICAgaWYgKHMzICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgICAgICAgICBwZWckcmVwb3J0ZWRQb3MgPSBzMDtcbiAgICAgICAgICAgICAgICAgIHMxID0gcGVnJGM1NShzMyk7XG4gICAgICAgICAgICAgICAgICBzMCA9IHMxO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICBwZWckY3VyclBvcyA9IHMwO1xuICAgICAgICAgICAgICAgICAgczAgPSBwZWckYzE7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHBlZyRjdXJyUG9zID0gczA7XG4gICAgICAgICAgICAgICAgczAgPSBwZWckYzE7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHBlZyRjdXJyUG9zID0gczA7XG4gICAgICAgICAgICAgIHMwID0gcGVnJGMxO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHMwID09PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgICAgIHMwID0gcGVnJGN1cnJQb3M7XG4gICAgICAgICAgICAgIGlmIChpbnB1dC5zdWJzdHIocGVnJGN1cnJQb3MsIDMpID09PSBwZWckYzU2KSB7XG4gICAgICAgICAgICAgICAgczEgPSBwZWckYzU2O1xuICAgICAgICAgICAgICAgIHBlZyRjdXJyUG9zICs9IDM7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgczEgPSBwZWckRkFJTEVEO1xuICAgICAgICAgICAgICAgIGlmIChwZWckc2lsZW50RmFpbHMgPT09IDApIHsgcGVnJGZhaWwocGVnJGM1Nyk7IH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBpZiAoczEgIT09IHBlZyRGQUlMRUQpIHtcbiAgICAgICAgICAgICAgICBzMiA9IFtdO1xuICAgICAgICAgICAgICAgIHMzID0gcGVnJHBhcnNld3MoKTtcbiAgICAgICAgICAgICAgICBpZiAoczMgIT09IHBlZyRGQUlMRUQpIHtcbiAgICAgICAgICAgICAgICAgIHdoaWxlIChzMyAhPT0gcGVnJEZBSUxFRCkge1xuICAgICAgICAgICAgICAgICAgICBzMi5wdXNoKHMzKTtcbiAgICAgICAgICAgICAgICAgICAgczMgPSBwZWckcGFyc2V3cygpO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICBzMiA9IHBlZyRjMTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHMyICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgICAgICAgICBzMyA9IHBlZyRwYXJzZVN0cmluZ0xpdGVyYWwoKTtcbiAgICAgICAgICAgICAgICAgIGlmIChzMyAhPT0gcGVnJEZBSUxFRCkge1xuICAgICAgICAgICAgICAgICAgICBwZWckcmVwb3J0ZWRQb3MgPSBzMDtcbiAgICAgICAgICAgICAgICAgICAgczEgPSBwZWckYzU4KHMzKTtcbiAgICAgICAgICAgICAgICAgICAgczAgPSBzMTtcbiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHBlZyRjdXJyUG9zID0gczA7XG4gICAgICAgICAgICAgICAgICAgIHMwID0gcGVnJGMxO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICBwZWckY3VyclBvcyA9IHMwO1xuICAgICAgICAgICAgICAgICAgczAgPSBwZWckYzE7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHBlZyRjdXJyUG9zID0gczA7XG4gICAgICAgICAgICAgICAgczAgPSBwZWckYzE7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaWYgKHMwID09PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgICAgICAgczAgPSBwZWckY3VyclBvcztcbiAgICAgICAgICAgICAgICBpZiAoaW5wdXQuc3Vic3RyKHBlZyRjdXJyUG9zLCAyKSA9PT0gcGVnJGM1OSkge1xuICAgICAgICAgICAgICAgICAgczEgPSBwZWckYzU5O1xuICAgICAgICAgICAgICAgICAgcGVnJGN1cnJQb3MgKz0gMjtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgczEgPSBwZWckRkFJTEVEO1xuICAgICAgICAgICAgICAgICAgaWYgKHBlZyRzaWxlbnRGYWlscyA9PT0gMCkgeyBwZWckZmFpbChwZWckYzYwKTsgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoczEgIT09IHBlZyRGQUlMRUQpIHtcbiAgICAgICAgICAgICAgICAgIHMyID0gW107XG4gICAgICAgICAgICAgICAgICBzMyA9IHBlZyRwYXJzZXdzKCk7XG4gICAgICAgICAgICAgICAgICBpZiAoczMgIT09IHBlZyRGQUlMRUQpIHtcbiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHMzICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgICAgICAgICAgICAgczIucHVzaChzMyk7XG4gICAgICAgICAgICAgICAgICAgICAgczMgPSBwZWckcGFyc2V3cygpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBzMiA9IHBlZyRjMTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIGlmIChzMiAhPT0gcGVnJEZBSUxFRCkge1xuICAgICAgICAgICAgICAgICAgICBzMyA9IHBlZyRwYXJzZVN0cmluZ0xpdGVyYWwoKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHMzICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgICAgICAgICAgICAgcGVnJHJlcG9ydGVkUG9zID0gczA7XG4gICAgICAgICAgICAgICAgICAgICAgczEgPSBwZWckYzYxKHMzKTtcbiAgICAgICAgICAgICAgICAgICAgICBzMCA9IHMxO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgIHBlZyRjdXJyUG9zID0gczA7XG4gICAgICAgICAgICAgICAgICAgICAgczAgPSBwZWckYzE7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHBlZyRjdXJyUG9zID0gczA7XG4gICAgICAgICAgICAgICAgICAgIHMwID0gcGVnJGMxO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICBwZWckY3VyclBvcyA9IHMwO1xuICAgICAgICAgICAgICAgICAgczAgPSBwZWckYzE7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChzMCA9PT0gcGVnJEZBSUxFRCkge1xuICAgICAgICAgICAgICAgICAgczAgPSBwZWckY3VyclBvcztcbiAgICAgICAgICAgICAgICAgIGlmIChpbnB1dC5zdWJzdHIocGVnJGN1cnJQb3MsIDIpID09PSBwZWckYzYyKSB7XG4gICAgICAgICAgICAgICAgICAgIHMxID0gcGVnJGM2MjtcbiAgICAgICAgICAgICAgICAgICAgcGVnJGN1cnJQb3MgKz0gMjtcbiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHMxID0gcGVnJEZBSUxFRDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHBlZyRzaWxlbnRGYWlscyA9PT0gMCkgeyBwZWckZmFpbChwZWckYzYzKTsgfVxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgaWYgKHMxICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgICAgICAgICAgIHMyID0gW107XG4gICAgICAgICAgICAgICAgICAgIHMzID0gcGVnJHBhcnNld3MoKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHMzICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHMzICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzMi5wdXNoKHMzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHMzID0gcGVnJHBhcnNld3MoKTtcbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgczIgPSBwZWckYzE7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKHMyICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgICAgICAgICAgICAgczMgPSBwZWckcGFyc2VTdHJpbmdMaXRlcmFsKCk7XG4gICAgICAgICAgICAgICAgICAgICAgaWYgKHMzICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwZWckcmVwb3J0ZWRQb3MgPSBzMDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHMxID0gcGVnJGM2NChzMyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBzMCA9IHMxO1xuICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwZWckY3VyclBvcyA9IHMwO1xuICAgICAgICAgICAgICAgICAgICAgICAgczAgPSBwZWckYzE7XG4gICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgIHBlZyRjdXJyUG9zID0gczA7XG4gICAgICAgICAgICAgICAgICAgICAgczAgPSBwZWckYzE7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHBlZyRjdXJyUG9zID0gczA7XG4gICAgICAgICAgICAgICAgICAgIHMwID0gcGVnJGMxO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgaWYgKHMwID09PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgICAgICAgICAgIHMwID0gcGVnJGN1cnJQb3M7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpbnB1dC5zdWJzdHIocGVnJGN1cnJQb3MsIDMpID09PSBwZWckYzY1KSB7XG4gICAgICAgICAgICAgICAgICAgICAgczEgPSBwZWckYzY1O1xuICAgICAgICAgICAgICAgICAgICAgIHBlZyRjdXJyUG9zICs9IDM7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgczEgPSBwZWckRkFJTEVEO1xuICAgICAgICAgICAgICAgICAgICAgIGlmIChwZWckc2lsZW50RmFpbHMgPT09IDApIHsgcGVnJGZhaWwocGVnJGM2Nik7IH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAoczEgIT09IHBlZyRGQUlMRUQpIHtcbiAgICAgICAgICAgICAgICAgICAgICBzMiA9IFtdO1xuICAgICAgICAgICAgICAgICAgICAgIHMzID0gcGVnJHBhcnNld3MoKTtcbiAgICAgICAgICAgICAgICAgICAgICBpZiAoczMgIT09IHBlZyRGQUlMRUQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChzMyAhPT0gcGVnJEZBSUxFRCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICBzMi5wdXNoKHMzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgczMgPSBwZWckcGFyc2V3cygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzMiA9IHBlZyRjMTtcbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgaWYgKHMyICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzMyA9IHBlZyRwYXJzZVN0cmluZ0xpdGVyYWwoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzMyAhPT0gcGVnJEZBSUxFRCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICBwZWckcmVwb3J0ZWRQb3MgPSBzMDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgczEgPSBwZWckYzY3KHMzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgczAgPSBzMTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHBlZyRjdXJyUG9zID0gczA7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHMwID0gcGVnJGMxO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwZWckY3VyclBvcyA9IHMwO1xuICAgICAgICAgICAgICAgICAgICAgICAgczAgPSBwZWckYzE7XG4gICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgIHBlZyRjdXJyUG9zID0gczA7XG4gICAgICAgICAgICAgICAgICAgICAgczAgPSBwZWckYzE7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgaWYgKHMwID09PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgICAgICAgICAgICAgczAgPSBwZWckY3VyclBvcztcbiAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5wdXQuc3Vic3RyKHBlZyRjdXJyUG9zLCAzKSA9PT0gcGVnJGM2OCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgczEgPSBwZWckYzY4O1xuICAgICAgICAgICAgICAgICAgICAgICAgcGVnJGN1cnJQb3MgKz0gMztcbiAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgczEgPSBwZWckRkFJTEVEO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBlZyRzaWxlbnRGYWlscyA9PT0gMCkgeyBwZWckZmFpbChwZWckYzY5KTsgfVxuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICBpZiAoczEgIT09IHBlZyRGQUlMRUQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHMyID0gW107XG4gICAgICAgICAgICAgICAgICAgICAgICBzMyA9IHBlZyRwYXJzZXdzKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoczMgIT09IHBlZyRGQUlMRUQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHMzICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgczIucHVzaChzMyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgczMgPSBwZWckcGFyc2V3cygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICBzMiA9IHBlZyRjMTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzMiAhPT0gcGVnJEZBSUxFRCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICBzMyA9IHBlZyRwYXJzZVN0cmluZ0xpdGVyYWwoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHMzICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGVnJHJlcG9ydGVkUG9zID0gczA7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgczEgPSBwZWckYzcwKHMzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzMCA9IHMxO1xuICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBlZyRjdXJyUG9zID0gczA7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgczAgPSBwZWckYzE7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHBlZyRjdXJyUG9zID0gczA7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHMwID0gcGVnJGMxO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwZWckY3VyclBvcyA9IHMwO1xuICAgICAgICAgICAgICAgICAgICAgICAgczAgPSBwZWckYzE7XG4gICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgIGlmIChzMCA9PT0gcGVnJEZBSUxFRCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgczAgPSBwZWckY3VyclBvcztcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbnB1dC5zdWJzdHIocGVnJGN1cnJQb3MsIDIpID09PSBwZWckYzcxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHMxID0gcGVnJGM3MTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcGVnJGN1cnJQb3MgKz0gMjtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHMxID0gcGVnJEZBSUxFRDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBlZyRzaWxlbnRGYWlscyA9PT0gMCkgeyBwZWckZmFpbChwZWckYzcyKTsgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHMxICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHMyID0gW107XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHMzID0gcGVnJHBhcnNld3MoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHMzICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHMzICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzMi5wdXNoKHMzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMzID0gcGVnJHBhcnNld3MoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgczIgPSBwZWckYzE7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHMyICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgczMgPSBwZWckcGFyc2VTdHJpbmdMaXRlcmFsKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHMzICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZWckcmVwb3J0ZWRQb3MgPSBzMDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMxID0gcGVnJGM3MyhzMyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzMCA9IHMxO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZWckY3VyclBvcyA9IHMwO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgczAgPSBwZWckYzE7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBlZyRjdXJyUG9zID0gczA7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgczAgPSBwZWckYzE7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHBlZyRjdXJyUG9zID0gczA7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHMwID0gcGVnJGMxO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHMwID09PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHMwID0gcGVnJGN1cnJQb3M7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHMxID0gcGVnJHBhcnNlU3RyaW5nTGl0ZXJhbCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoczEgIT09IHBlZyRGQUlMRUQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZWckcmVwb3J0ZWRQb3MgPSBzMDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzMSA9IHBlZyRjNzMoczEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHMwID0gczE7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBzMDtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwZWckcGFyc2VJbnRlZ2VyTGl0ZXJhbCgpIHtcbiAgICAgIHZhciBzMCwgczEsIHMyLCBzMztcblxuICAgICAgcGVnJHNpbGVudEZhaWxzKys7XG4gICAgICBzMCA9IHBlZyRjdXJyUG9zO1xuICAgICAgaWYgKHBlZyRjNzYudGVzdChpbnB1dC5jaGFyQXQocGVnJGN1cnJQb3MpKSkge1xuICAgICAgICBzMSA9IGlucHV0LmNoYXJBdChwZWckY3VyclBvcyk7XG4gICAgICAgIHBlZyRjdXJyUG9zKys7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzMSA9IHBlZyRGQUlMRUQ7XG4gICAgICAgIGlmIChwZWckc2lsZW50RmFpbHMgPT09IDApIHsgcGVnJGZhaWwocGVnJGM3Nyk7IH1cbiAgICAgIH1cbiAgICAgIGlmIChzMSA9PT0gcGVnJEZBSUxFRCkge1xuICAgICAgICBzMSA9IHBlZyRjNzU7XG4gICAgICB9XG4gICAgICBpZiAoczEgIT09IHBlZyRGQUlMRUQpIHtcbiAgICAgICAgczIgPSBbXTtcbiAgICAgICAgaWYgKHBlZyRjNzgudGVzdChpbnB1dC5jaGFyQXQocGVnJGN1cnJQb3MpKSkge1xuICAgICAgICAgIHMzID0gaW5wdXQuY2hhckF0KHBlZyRjdXJyUG9zKTtcbiAgICAgICAgICBwZWckY3VyclBvcysrO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHMzID0gcGVnJEZBSUxFRDtcbiAgICAgICAgICBpZiAocGVnJHNpbGVudEZhaWxzID09PSAwKSB7IHBlZyRmYWlsKHBlZyRjNzkpOyB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHMzICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgd2hpbGUgKHMzICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgICBzMi5wdXNoKHMzKTtcbiAgICAgICAgICAgIGlmIChwZWckYzc4LnRlc3QoaW5wdXQuY2hhckF0KHBlZyRjdXJyUG9zKSkpIHtcbiAgICAgICAgICAgICAgczMgPSBpbnB1dC5jaGFyQXQocGVnJGN1cnJQb3MpO1xuICAgICAgICAgICAgICBwZWckY3VyclBvcysrO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgczMgPSBwZWckRkFJTEVEO1xuICAgICAgICAgICAgICBpZiAocGVnJHNpbGVudEZhaWxzID09PSAwKSB7IHBlZyRmYWlsKHBlZyRjNzkpOyB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHMyID0gcGVnJGMxO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzMiAhPT0gcGVnJEZBSUxFRCkge1xuICAgICAgICAgIGlmIChwZWckYzc2LnRlc3QoaW5wdXQuY2hhckF0KHBlZyRjdXJyUG9zKSkpIHtcbiAgICAgICAgICAgIHMzID0gaW5wdXQuY2hhckF0KHBlZyRjdXJyUG9zKTtcbiAgICAgICAgICAgIHBlZyRjdXJyUG9zKys7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHMzID0gcGVnJEZBSUxFRDtcbiAgICAgICAgICAgIGlmIChwZWckc2lsZW50RmFpbHMgPT09IDApIHsgcGVnJGZhaWwocGVnJGM3Nyk7IH1cbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHMzID09PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgICBzMyA9IHBlZyRjNzU7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChzMyAhPT0gcGVnJEZBSUxFRCkge1xuICAgICAgICAgICAgcGVnJHJlcG9ydGVkUG9zID0gczA7XG4gICAgICAgICAgICBzMSA9IHBlZyRjODAoczIpO1xuICAgICAgICAgICAgczAgPSBzMTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcGVnJGN1cnJQb3MgPSBzMDtcbiAgICAgICAgICAgIHMwID0gcGVnJGMxO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBwZWckY3VyclBvcyA9IHMwO1xuICAgICAgICAgIHMwID0gcGVnJGMxO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwZWckY3VyclBvcyA9IHMwO1xuICAgICAgICBzMCA9IHBlZyRjMTtcbiAgICAgIH1cbiAgICAgIHBlZyRzaWxlbnRGYWlscy0tO1xuICAgICAgaWYgKHMwID09PSBwZWckRkFJTEVEKSB7XG4gICAgICAgIHMxID0gcGVnJEZBSUxFRDtcbiAgICAgICAgaWYgKHBlZyRzaWxlbnRGYWlscyA9PT0gMCkgeyBwZWckZmFpbChwZWckYzc0KTsgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gczA7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcGVnJHBhcnNlU3RyaW5nTGl0ZXJhbCgpIHtcbiAgICAgIHZhciBzMCwgczEsIHMyLCBzMztcblxuICAgICAgcGVnJHNpbGVudEZhaWxzKys7XG4gICAgICBzMCA9IHBlZyRjdXJyUG9zO1xuICAgICAgaWYgKGlucHV0LmNoYXJDb2RlQXQocGVnJGN1cnJQb3MpID09PSAzNCkge1xuICAgICAgICBzMSA9IHBlZyRjODI7XG4gICAgICAgIHBlZyRjdXJyUG9zKys7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzMSA9IHBlZyRGQUlMRUQ7XG4gICAgICAgIGlmIChwZWckc2lsZW50RmFpbHMgPT09IDApIHsgcGVnJGZhaWwocGVnJGM4Myk7IH1cbiAgICAgIH1cbiAgICAgIGlmIChzMSAhPT0gcGVnJEZBSUxFRCkge1xuICAgICAgICBzMiA9IFtdO1xuICAgICAgICBzMyA9IHBlZyRwYXJzZURvdWJsZVN0cmluZ0NoYXIoKTtcbiAgICAgICAgd2hpbGUgKHMzICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgczIucHVzaChzMyk7XG4gICAgICAgICAgczMgPSBwZWckcGFyc2VEb3VibGVTdHJpbmdDaGFyKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHMyICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgaWYgKGlucHV0LmNoYXJDb2RlQXQocGVnJGN1cnJQb3MpID09PSAzNCkge1xuICAgICAgICAgICAgczMgPSBwZWckYzgyO1xuICAgICAgICAgICAgcGVnJGN1cnJQb3MrKztcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgczMgPSBwZWckRkFJTEVEO1xuICAgICAgICAgICAgaWYgKHBlZyRzaWxlbnRGYWlscyA9PT0gMCkgeyBwZWckZmFpbChwZWckYzgzKTsgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoczMgIT09IHBlZyRGQUlMRUQpIHtcbiAgICAgICAgICAgIHBlZyRyZXBvcnRlZFBvcyA9IHMwO1xuICAgICAgICAgICAgczEgPSBwZWckYzg0KHMyKTtcbiAgICAgICAgICAgIHMwID0gczE7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHBlZyRjdXJyUG9zID0gczA7XG4gICAgICAgICAgICBzMCA9IHBlZyRjMTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcGVnJGN1cnJQb3MgPSBzMDtcbiAgICAgICAgICBzMCA9IHBlZyRjMTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcGVnJGN1cnJQb3MgPSBzMDtcbiAgICAgICAgczAgPSBwZWckYzE7XG4gICAgICB9XG4gICAgICBpZiAoczAgPT09IHBlZyRGQUlMRUQpIHtcbiAgICAgICAgczAgPSBwZWckY3VyclBvcztcbiAgICAgICAgaWYgKGlucHV0LmNoYXJDb2RlQXQocGVnJGN1cnJQb3MpID09PSAzOSkge1xuICAgICAgICAgIHMxID0gcGVnJGM4NTtcbiAgICAgICAgICBwZWckY3VyclBvcysrO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHMxID0gcGVnJEZBSUxFRDtcbiAgICAgICAgICBpZiAocGVnJHNpbGVudEZhaWxzID09PSAwKSB7IHBlZyRmYWlsKHBlZyRjODYpOyB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHMxICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgczIgPSBbXTtcbiAgICAgICAgICBzMyA9IHBlZyRwYXJzZVNpbmdsZVN0cmluZ0NoYXIoKTtcbiAgICAgICAgICB3aGlsZSAoczMgIT09IHBlZyRGQUlMRUQpIHtcbiAgICAgICAgICAgIHMyLnB1c2goczMpO1xuICAgICAgICAgICAgczMgPSBwZWckcGFyc2VTaW5nbGVTdHJpbmdDaGFyKCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChzMiAhPT0gcGVnJEZBSUxFRCkge1xuICAgICAgICAgICAgaWYgKGlucHV0LmNoYXJDb2RlQXQocGVnJGN1cnJQb3MpID09PSAzOSkge1xuICAgICAgICAgICAgICBzMyA9IHBlZyRjODU7XG4gICAgICAgICAgICAgIHBlZyRjdXJyUG9zKys7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBzMyA9IHBlZyRGQUlMRUQ7XG4gICAgICAgICAgICAgIGlmIChwZWckc2lsZW50RmFpbHMgPT09IDApIHsgcGVnJGZhaWwocGVnJGM4Nik7IH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChzMyAhPT0gcGVnJEZBSUxFRCkge1xuICAgICAgICAgICAgICBwZWckcmVwb3J0ZWRQb3MgPSBzMDtcbiAgICAgICAgICAgICAgczEgPSBwZWckYzg0KHMyKTtcbiAgICAgICAgICAgICAgczAgPSBzMTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHBlZyRjdXJyUG9zID0gczA7XG4gICAgICAgICAgICAgIHMwID0gcGVnJGMxO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwZWckY3VyclBvcyA9IHMwO1xuICAgICAgICAgICAgczAgPSBwZWckYzE7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHBlZyRjdXJyUG9zID0gczA7XG4gICAgICAgICAgczAgPSBwZWckYzE7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHMwID09PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgczAgPSBwZWckY3VyclBvcztcbiAgICAgICAgICBzMSA9IHBlZyRjdXJyUG9zO1xuICAgICAgICAgIHBlZyRzaWxlbnRGYWlscysrO1xuICAgICAgICAgIHMyID0gcGVnJHBhcnNlY2MoKTtcbiAgICAgICAgICBwZWckc2lsZW50RmFpbHMtLTtcbiAgICAgICAgICBpZiAoczIgPT09IHBlZyRGQUlMRUQpIHtcbiAgICAgICAgICAgIHMxID0gcGVnJGM4NztcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcGVnJGN1cnJQb3MgPSBzMTtcbiAgICAgICAgICAgIHMxID0gcGVnJGMxO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoczEgIT09IHBlZyRGQUlMRUQpIHtcbiAgICAgICAgICAgIHMyID0gW107XG4gICAgICAgICAgICBzMyA9IHBlZyRwYXJzZVVucXVvdGVkU3RyaW5nQ2hhcigpO1xuICAgICAgICAgICAgaWYgKHMzICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgICAgIHdoaWxlIChzMyAhPT0gcGVnJEZBSUxFRCkge1xuICAgICAgICAgICAgICAgIHMyLnB1c2goczMpO1xuICAgICAgICAgICAgICAgIHMzID0gcGVnJHBhcnNlVW5xdW90ZWRTdHJpbmdDaGFyKCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHMyID0gcGVnJGMxO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHMyICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgICAgIHBlZyRyZXBvcnRlZFBvcyA9IHMwO1xuICAgICAgICAgICAgICBzMSA9IHBlZyRjODQoczIpO1xuICAgICAgICAgICAgICBzMCA9IHMxO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgcGVnJGN1cnJQb3MgPSBzMDtcbiAgICAgICAgICAgICAgczAgPSBwZWckYzE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHBlZyRjdXJyUG9zID0gczA7XG4gICAgICAgICAgICBzMCA9IHBlZyRjMTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHBlZyRzaWxlbnRGYWlscy0tO1xuICAgICAgaWYgKHMwID09PSBwZWckRkFJTEVEKSB7XG4gICAgICAgIHMxID0gcGVnJEZBSUxFRDtcbiAgICAgICAgaWYgKHBlZyRzaWxlbnRGYWlscyA9PT0gMCkgeyBwZWckZmFpbChwZWckYzgxKTsgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gczA7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcGVnJHBhcnNlRG91YmxlU3RyaW5nQ2hhcigpIHtcbiAgICAgIHZhciBzMCwgczEsIHMyO1xuXG4gICAgICBzMCA9IHBlZyRjdXJyUG9zO1xuICAgICAgczEgPSBwZWckY3VyclBvcztcbiAgICAgIHBlZyRzaWxlbnRGYWlscysrO1xuICAgICAgaWYgKHBlZyRjODgudGVzdChpbnB1dC5jaGFyQXQocGVnJGN1cnJQb3MpKSkge1xuICAgICAgICBzMiA9IGlucHV0LmNoYXJBdChwZWckY3VyclBvcyk7XG4gICAgICAgIHBlZyRjdXJyUG9zKys7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzMiA9IHBlZyRGQUlMRUQ7XG4gICAgICAgIGlmIChwZWckc2lsZW50RmFpbHMgPT09IDApIHsgcGVnJGZhaWwocGVnJGM4OSk7IH1cbiAgICAgIH1cbiAgICAgIHBlZyRzaWxlbnRGYWlscy0tO1xuICAgICAgaWYgKHMyID09PSBwZWckRkFJTEVEKSB7XG4gICAgICAgIHMxID0gcGVnJGM4NztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHBlZyRjdXJyUG9zID0gczE7XG4gICAgICAgIHMxID0gcGVnJGMxO1xuICAgICAgfVxuICAgICAgaWYgKHMxICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgIGlmIChpbnB1dC5sZW5ndGggPiBwZWckY3VyclBvcykge1xuICAgICAgICAgIHMyID0gaW5wdXQuY2hhckF0KHBlZyRjdXJyUG9zKTtcbiAgICAgICAgICBwZWckY3VyclBvcysrO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHMyID0gcGVnJEZBSUxFRDtcbiAgICAgICAgICBpZiAocGVnJHNpbGVudEZhaWxzID09PSAwKSB7IHBlZyRmYWlsKHBlZyRjOTApOyB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHMyICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgcGVnJHJlcG9ydGVkUG9zID0gczA7XG4gICAgICAgICAgczEgPSBwZWckYzkxKHMyKTtcbiAgICAgICAgICBzMCA9IHMxO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHBlZyRjdXJyUG9zID0gczA7XG4gICAgICAgICAgczAgPSBwZWckYzE7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHBlZyRjdXJyUG9zID0gczA7XG4gICAgICAgIHMwID0gcGVnJGMxO1xuICAgICAgfVxuICAgICAgaWYgKHMwID09PSBwZWckRkFJTEVEKSB7XG4gICAgICAgIHMwID0gcGVnJGN1cnJQb3M7XG4gICAgICAgIGlmIChpbnB1dC5jaGFyQ29kZUF0KHBlZyRjdXJyUG9zKSA9PT0gOTIpIHtcbiAgICAgICAgICBzMSA9IHBlZyRjOTI7XG4gICAgICAgICAgcGVnJGN1cnJQb3MrKztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzMSA9IHBlZyRGQUlMRUQ7XG4gICAgICAgICAgaWYgKHBlZyRzaWxlbnRGYWlscyA9PT0gMCkgeyBwZWckZmFpbChwZWckYzkzKTsgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChzMSAhPT0gcGVnJEZBSUxFRCkge1xuICAgICAgICAgIHMyID0gcGVnJHBhcnNlRXNjYXBlU2VxdWVuY2UoKTtcbiAgICAgICAgICBpZiAoczIgIT09IHBlZyRGQUlMRUQpIHtcbiAgICAgICAgICAgIHBlZyRyZXBvcnRlZFBvcyA9IHMwO1xuICAgICAgICAgICAgczEgPSBwZWckYzkxKHMyKTtcbiAgICAgICAgICAgIHMwID0gczE7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHBlZyRjdXJyUG9zID0gczA7XG4gICAgICAgICAgICBzMCA9IHBlZyRjMTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcGVnJGN1cnJQb3MgPSBzMDtcbiAgICAgICAgICBzMCA9IHBlZyRjMTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gczA7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcGVnJHBhcnNlU2luZ2xlU3RyaW5nQ2hhcigpIHtcbiAgICAgIHZhciBzMCwgczEsIHMyO1xuXG4gICAgICBzMCA9IHBlZyRjdXJyUG9zO1xuICAgICAgczEgPSBwZWckY3VyclBvcztcbiAgICAgIHBlZyRzaWxlbnRGYWlscysrO1xuICAgICAgaWYgKHBlZyRjOTQudGVzdChpbnB1dC5jaGFyQXQocGVnJGN1cnJQb3MpKSkge1xuICAgICAgICBzMiA9IGlucHV0LmNoYXJBdChwZWckY3VyclBvcyk7XG4gICAgICAgIHBlZyRjdXJyUG9zKys7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzMiA9IHBlZyRGQUlMRUQ7XG4gICAgICAgIGlmIChwZWckc2lsZW50RmFpbHMgPT09IDApIHsgcGVnJGZhaWwocGVnJGM5NSk7IH1cbiAgICAgIH1cbiAgICAgIHBlZyRzaWxlbnRGYWlscy0tO1xuICAgICAgaWYgKHMyID09PSBwZWckRkFJTEVEKSB7XG4gICAgICAgIHMxID0gcGVnJGM4NztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHBlZyRjdXJyUG9zID0gczE7XG4gICAgICAgIHMxID0gcGVnJGMxO1xuICAgICAgfVxuICAgICAgaWYgKHMxICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgIGlmIChpbnB1dC5sZW5ndGggPiBwZWckY3VyclBvcykge1xuICAgICAgICAgIHMyID0gaW5wdXQuY2hhckF0KHBlZyRjdXJyUG9zKTtcbiAgICAgICAgICBwZWckY3VyclBvcysrO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHMyID0gcGVnJEZBSUxFRDtcbiAgICAgICAgICBpZiAocGVnJHNpbGVudEZhaWxzID09PSAwKSB7IHBlZyRmYWlsKHBlZyRjOTApOyB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHMyICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgcGVnJHJlcG9ydGVkUG9zID0gczA7XG4gICAgICAgICAgczEgPSBwZWckYzkxKHMyKTtcbiAgICAgICAgICBzMCA9IHMxO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHBlZyRjdXJyUG9zID0gczA7XG4gICAgICAgICAgczAgPSBwZWckYzE7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHBlZyRjdXJyUG9zID0gczA7XG4gICAgICAgIHMwID0gcGVnJGMxO1xuICAgICAgfVxuICAgICAgaWYgKHMwID09PSBwZWckRkFJTEVEKSB7XG4gICAgICAgIHMwID0gcGVnJGN1cnJQb3M7XG4gICAgICAgIGlmIChpbnB1dC5jaGFyQ29kZUF0KHBlZyRjdXJyUG9zKSA9PT0gOTIpIHtcbiAgICAgICAgICBzMSA9IHBlZyRjOTI7XG4gICAgICAgICAgcGVnJGN1cnJQb3MrKztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzMSA9IHBlZyRGQUlMRUQ7XG4gICAgICAgICAgaWYgKHBlZyRzaWxlbnRGYWlscyA9PT0gMCkgeyBwZWckZmFpbChwZWckYzkzKTsgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChzMSAhPT0gcGVnJEZBSUxFRCkge1xuICAgICAgICAgIHMyID0gcGVnJHBhcnNlRXNjYXBlU2VxdWVuY2UoKTtcbiAgICAgICAgICBpZiAoczIgIT09IHBlZyRGQUlMRUQpIHtcbiAgICAgICAgICAgIHBlZyRyZXBvcnRlZFBvcyA9IHMwO1xuICAgICAgICAgICAgczEgPSBwZWckYzkxKHMyKTtcbiAgICAgICAgICAgIHMwID0gczE7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHBlZyRjdXJyUG9zID0gczA7XG4gICAgICAgICAgICBzMCA9IHBlZyRjMTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcGVnJGN1cnJQb3MgPSBzMDtcbiAgICAgICAgICBzMCA9IHBlZyRjMTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gczA7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcGVnJHBhcnNlVW5xdW90ZWRTdHJpbmdDaGFyKCkge1xuICAgICAgdmFyIHMwLCBzMSwgczI7XG5cbiAgICAgIHMwID0gcGVnJGN1cnJQb3M7XG4gICAgICBzMSA9IHBlZyRjdXJyUG9zO1xuICAgICAgcGVnJHNpbGVudEZhaWxzKys7XG4gICAgICBzMiA9IHBlZyRwYXJzZXdzKCk7XG4gICAgICBwZWckc2lsZW50RmFpbHMtLTtcbiAgICAgIGlmIChzMiA9PT0gcGVnJEZBSUxFRCkge1xuICAgICAgICBzMSA9IHBlZyRjODc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwZWckY3VyclBvcyA9IHMxO1xuICAgICAgICBzMSA9IHBlZyRjMTtcbiAgICAgIH1cbiAgICAgIGlmIChzMSAhPT0gcGVnJEZBSUxFRCkge1xuICAgICAgICBpZiAoaW5wdXQubGVuZ3RoID4gcGVnJGN1cnJQb3MpIHtcbiAgICAgICAgICBzMiA9IGlucHV0LmNoYXJBdChwZWckY3VyclBvcyk7XG4gICAgICAgICAgcGVnJGN1cnJQb3MrKztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzMiA9IHBlZyRGQUlMRUQ7XG4gICAgICAgICAgaWYgKHBlZyRzaWxlbnRGYWlscyA9PT0gMCkgeyBwZWckZmFpbChwZWckYzkwKTsgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChzMiAhPT0gcGVnJEZBSUxFRCkge1xuICAgICAgICAgIHBlZyRyZXBvcnRlZFBvcyA9IHMwO1xuICAgICAgICAgIHMxID0gcGVnJGM5MShzMik7XG4gICAgICAgICAgczAgPSBzMTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBwZWckY3VyclBvcyA9IHMwO1xuICAgICAgICAgIHMwID0gcGVnJGMxO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwZWckY3VyclBvcyA9IHMwO1xuICAgICAgICBzMCA9IHBlZyRjMTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHMwO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHBlZyRwYXJzZUVzY2FwZVNlcXVlbmNlKCkge1xuICAgICAgdmFyIHMwLCBzMTtcblxuICAgICAgaWYgKHBlZyRjOTYudGVzdChpbnB1dC5jaGFyQXQocGVnJGN1cnJQb3MpKSkge1xuICAgICAgICBzMCA9IGlucHV0LmNoYXJBdChwZWckY3VyclBvcyk7XG4gICAgICAgIHBlZyRjdXJyUG9zKys7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzMCA9IHBlZyRGQUlMRUQ7XG4gICAgICAgIGlmIChwZWckc2lsZW50RmFpbHMgPT09IDApIHsgcGVnJGZhaWwocGVnJGM5Nyk7IH1cbiAgICAgIH1cbiAgICAgIGlmIChzMCA9PT0gcGVnJEZBSUxFRCkge1xuICAgICAgICBzMCA9IHBlZyRjdXJyUG9zO1xuICAgICAgICBpZiAoaW5wdXQuY2hhckNvZGVBdChwZWckY3VyclBvcykgPT09IDExMCkge1xuICAgICAgICAgIHMxID0gcGVnJGM5ODtcbiAgICAgICAgICBwZWckY3VyclBvcysrO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHMxID0gcGVnJEZBSUxFRDtcbiAgICAgICAgICBpZiAocGVnJHNpbGVudEZhaWxzID09PSAwKSB7IHBlZyRmYWlsKHBlZyRjOTkpOyB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHMxICE9PSBwZWckRkFJTEVEKSB7XG4gICAgICAgICAgcGVnJHJlcG9ydGVkUG9zID0gczA7XG4gICAgICAgICAgczEgPSBwZWckYzEwMCgpO1xuICAgICAgICB9XG4gICAgICAgIHMwID0gczE7XG4gICAgICAgIGlmIChzMCA9PT0gcGVnJEZBSUxFRCkge1xuICAgICAgICAgIHMwID0gcGVnJGN1cnJQb3M7XG4gICAgICAgICAgaWYgKGlucHV0LmNoYXJDb2RlQXQocGVnJGN1cnJQb3MpID09PSAxMTQpIHtcbiAgICAgICAgICAgIHMxID0gcGVnJGMxMDE7XG4gICAgICAgICAgICBwZWckY3VyclBvcysrO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzMSA9IHBlZyRGQUlMRUQ7XG4gICAgICAgICAgICBpZiAocGVnJHNpbGVudEZhaWxzID09PSAwKSB7IHBlZyRmYWlsKHBlZyRjMTAyKTsgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoczEgIT09IHBlZyRGQUlMRUQpIHtcbiAgICAgICAgICAgIHBlZyRyZXBvcnRlZFBvcyA9IHMwO1xuICAgICAgICAgICAgczEgPSBwZWckYzEwMygpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBzMCA9IHMxO1xuICAgICAgICAgIGlmIChzMCA9PT0gcGVnJEZBSUxFRCkge1xuICAgICAgICAgICAgczAgPSBwZWckY3VyclBvcztcbiAgICAgICAgICAgIGlmIChpbnB1dC5jaGFyQ29kZUF0KHBlZyRjdXJyUG9zKSA9PT0gMTE2KSB7XG4gICAgICAgICAgICAgIHMxID0gcGVnJGMxMDQ7XG4gICAgICAgICAgICAgIHBlZyRjdXJyUG9zKys7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBzMSA9IHBlZyRGQUlMRUQ7XG4gICAgICAgICAgICAgIGlmIChwZWckc2lsZW50RmFpbHMgPT09IDApIHsgcGVnJGZhaWwocGVnJGMxMDUpOyB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoczEgIT09IHBlZyRGQUlMRUQpIHtcbiAgICAgICAgICAgICAgcGVnJHJlcG9ydGVkUG9zID0gczA7XG4gICAgICAgICAgICAgIHMxID0gcGVnJGMxMDYoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHMwID0gczE7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBzMDtcbiAgICB9XG5cblxuICAgIGZ1bmN0aW9uIG9yKGZpcnN0LCBzZWNvbmQpIHtcbiAgICAgICAgLy8gQWRkIGV4cGxpY2l0IGZ1bmN0aW9uIG5hbWVzIHRvIGVhc2UgZGVidWdnaW5nLlxuICAgICAgICBmdW5jdGlvbiBvckZpbHRlcigpIHtcbiAgICAgICAgICAgIHJldHVybiBmaXJzdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHNlY29uZC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICB9XG4gICAgICAgIG9yRmlsdGVyLmRlc2MgPSBmaXJzdC5kZXNjICsgXCIgb3IgXCIgKyBzZWNvbmQuZGVzYztcbiAgICAgICAgcmV0dXJuIG9yRmlsdGVyO1xuICAgIH1cbiAgICBmdW5jdGlvbiBhbmQoZmlyc3QsIHNlY29uZCkge1xuICAgICAgICBmdW5jdGlvbiBhbmRGaWx0ZXIoKSB7XG4gICAgICAgICAgICByZXR1cm4gZmlyc3QuYXBwbHkodGhpcywgYXJndW1lbnRzKSAmJiBzZWNvbmQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgfVxuICAgICAgICBhbmRGaWx0ZXIuZGVzYyA9IGZpcnN0LmRlc2MgKyBcIiBhbmQgXCIgKyBzZWNvbmQuZGVzYztcbiAgICAgICAgcmV0dXJuIGFuZEZpbHRlcjtcbiAgICB9XG4gICAgZnVuY3Rpb24gbm90KGV4cHIpIHtcbiAgICAgICAgZnVuY3Rpb24gbm90RmlsdGVyKCkge1xuICAgICAgICAgICAgcmV0dXJuICFleHByLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgIH1cbiAgICAgICAgbm90RmlsdGVyLmRlc2MgPSBcIm5vdCBcIiArIGV4cHIuZGVzYztcbiAgICAgICAgcmV0dXJuIG5vdEZpbHRlcjtcbiAgICB9XG4gICAgZnVuY3Rpb24gYmluZGluZyhleHByKSB7XG4gICAgICAgIGZ1bmN0aW9uIGJpbmRpbmdGaWx0ZXIoKSB7XG4gICAgICAgICAgICByZXR1cm4gZXhwci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICB9XG4gICAgICAgIGJpbmRpbmdGaWx0ZXIuZGVzYyA9IFwiKFwiICsgZXhwci5kZXNjICsgXCIpXCI7XG4gICAgICAgIHJldHVybiBiaW5kaW5nRmlsdGVyO1xuICAgIH1cbiAgICBmdW5jdGlvbiB0cnVlRmlsdGVyKGZsb3cpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHRydWVGaWx0ZXIuZGVzYyA9IFwidHJ1ZVwiO1xuICAgIGZ1bmN0aW9uIGZhbHNlRmlsdGVyKGZsb3cpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBmYWxzZUZpbHRlci5kZXNjID0gXCJmYWxzZVwiO1xuXG4gICAgdmFyIEFTU0VUX1RZUEVTID0gW1xuICAgICAgICBuZXcgUmVnRXhwKFwidGV4dC9qYXZhc2NyaXB0XCIpLFxuICAgICAgICBuZXcgUmVnRXhwKFwiYXBwbGljYXRpb24veC1qYXZhc2NyaXB0XCIpLFxuICAgICAgICBuZXcgUmVnRXhwKFwiYXBwbGljYXRpb24vamF2YXNjcmlwdFwiKSxcbiAgICAgICAgbmV3IFJlZ0V4cChcInRleHQvY3NzXCIpLFxuICAgICAgICBuZXcgUmVnRXhwKFwiaW1hZ2UvLipcIiksXG4gICAgICAgIG5ldyBSZWdFeHAoXCJhcHBsaWNhdGlvbi94LXNob2Nrd2F2ZS1mbGFzaFwiKVxuICAgIF07XG4gICAgZnVuY3Rpb24gYXNzZXRGaWx0ZXIoZmxvdykge1xuICAgICAgICBpZiAoZmxvdy5yZXNwb25zZSkge1xuICAgICAgICAgICAgdmFyIGN0ID0gUmVzcG9uc2VVdGlscy5nZXRDb250ZW50VHlwZShmbG93LnJlc3BvbnNlKTtcbiAgICAgICAgICAgIHZhciBpID0gQVNTRVRfVFlQRVMubGVuZ3RoO1xuICAgICAgICAgICAgd2hpbGUgKGktLSkge1xuICAgICAgICAgICAgICAgIGlmIChBU1NFVF9UWVBFU1tpXS50ZXN0KGN0KSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBhc3NldEZpbHRlci5kZXNjID0gXCJpcyBhc3NldFwiO1xuICAgIGZ1bmN0aW9uIHJlc3BvbnNlQ29kZShjb2RlKXtcbiAgICAgICAgZnVuY3Rpb24gcmVzcG9uc2VDb2RlRmlsdGVyKGZsb3cpe1xuICAgICAgICAgICAgcmV0dXJuIGZsb3cucmVzcG9uc2UgJiYgZmxvdy5yZXNwb25zZS5jb2RlID09PSBjb2RlO1xuICAgICAgICB9XG4gICAgICAgIHJlc3BvbnNlQ29kZUZpbHRlci5kZXNjID0gXCJyZXNwLiBjb2RlIGlzIFwiICsgY29kZTtcbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlQ29kZUZpbHRlcjtcbiAgICB9XG4gICAgZnVuY3Rpb24gZG9tYWluKHJlZ2V4KXtcbiAgICAgICAgcmVnZXggPSBuZXcgUmVnRXhwKHJlZ2V4LCBcImlcIik7XG4gICAgICAgIGZ1bmN0aW9uIGRvbWFpbkZpbHRlcihmbG93KXtcbiAgICAgICAgICAgIHJldHVybiBmbG93LnJlcXVlc3QgJiYgcmVnZXgudGVzdChmbG93LnJlcXVlc3QuaG9zdCk7XG4gICAgICAgIH1cbiAgICAgICAgZG9tYWluRmlsdGVyLmRlc2MgPSBcImRvbWFpbiBtYXRjaGVzIFwiICsgcmVnZXg7XG4gICAgICAgIHJldHVybiBkb21haW5GaWx0ZXI7XG4gICAgfVxuICAgIGZ1bmN0aW9uIGVycm9yRmlsdGVyKGZsb3cpe1xuICAgICAgICByZXR1cm4gISFmbG93LmVycm9yO1xuICAgIH1cbiAgICBlcnJvckZpbHRlci5kZXNjID0gXCJoYXMgZXJyb3JcIjtcbiAgICBmdW5jdGlvbiBoZWFkZXIocmVnZXgpe1xuICAgICAgICByZWdleCA9IG5ldyBSZWdFeHAocmVnZXgsIFwiaVwiKTtcbiAgICAgICAgZnVuY3Rpb24gaGVhZGVyRmlsdGVyKGZsb3cpe1xuICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgICAoZmxvdy5yZXF1ZXN0ICYmIFJlcXVlc3RVdGlscy5tYXRjaF9oZWFkZXIoZmxvdy5yZXF1ZXN0LCByZWdleCkpXG4gICAgICAgICAgICAgICAgfHxcbiAgICAgICAgICAgICAgICAoZmxvdy5yZXNwb25zZSAmJiBSZXNwb25zZVV0aWxzLm1hdGNoX2hlYWRlcihmbG93LnJlc3BvbnNlLCByZWdleCkpXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIGhlYWRlckZpbHRlci5kZXNjID0gXCJoZWFkZXIgbWF0Y2hlcyBcIiArIHJlZ2V4O1xuICAgICAgICByZXR1cm4gaGVhZGVyRmlsdGVyO1xuICAgIH1cbiAgICBmdW5jdGlvbiByZXF1ZXN0SGVhZGVyKHJlZ2V4KXtcbiAgICAgICAgcmVnZXggPSBuZXcgUmVnRXhwKHJlZ2V4LCBcImlcIik7XG4gICAgICAgIGZ1bmN0aW9uIHJlcXVlc3RIZWFkZXJGaWx0ZXIoZmxvdyl7XG4gICAgICAgICAgICByZXR1cm4gKGZsb3cucmVxdWVzdCAmJiBSZXF1ZXN0VXRpbHMubWF0Y2hfaGVhZGVyKGZsb3cucmVxdWVzdCwgcmVnZXgpKTtcbiAgICAgICAgfVxuICAgICAgICByZXF1ZXN0SGVhZGVyRmlsdGVyLmRlc2MgPSBcInJlcS4gaGVhZGVyIG1hdGNoZXMgXCIgKyByZWdleDtcbiAgICAgICAgcmV0dXJuIHJlcXVlc3RIZWFkZXJGaWx0ZXI7XG4gICAgfVxuICAgIGZ1bmN0aW9uIHJlc3BvbnNlSGVhZGVyKHJlZ2V4KXtcbiAgICAgICAgcmVnZXggPSBuZXcgUmVnRXhwKHJlZ2V4LCBcImlcIik7XG4gICAgICAgIGZ1bmN0aW9uIHJlc3BvbnNlSGVhZGVyRmlsdGVyKGZsb3cpe1xuICAgICAgICAgICAgcmV0dXJuIChmbG93LnJlc3BvbnNlICYmIFJlc3BvbnNlVXRpbHMubWF0Y2hfaGVhZGVyKGZsb3cucmVzcG9uc2UsIHJlZ2V4KSk7XG4gICAgICAgIH1cbiAgICAgICAgcmVzcG9uc2VIZWFkZXJGaWx0ZXIuZGVzYyA9IFwicmVzcC4gaGVhZGVyIG1hdGNoZXMgXCIgKyByZWdleDtcbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlSGVhZGVyRmlsdGVyO1xuICAgIH1cbiAgICBmdW5jdGlvbiBtZXRob2QocmVnZXgpe1xuICAgICAgICByZWdleCA9IG5ldyBSZWdFeHAocmVnZXgsIFwiaVwiKTtcbiAgICAgICAgZnVuY3Rpb24gbWV0aG9kRmlsdGVyKGZsb3cpe1xuICAgICAgICAgICAgcmV0dXJuIGZsb3cucmVxdWVzdCAmJiByZWdleC50ZXN0KGZsb3cucmVxdWVzdC5tZXRob2QpO1xuICAgICAgICB9XG4gICAgICAgIG1ldGhvZEZpbHRlci5kZXNjID0gXCJtZXRob2QgbWF0Y2hlcyBcIiArIHJlZ2V4O1xuICAgICAgICByZXR1cm4gbWV0aG9kRmlsdGVyO1xuICAgIH1cbiAgICBmdW5jdGlvbiBub1Jlc3BvbnNlRmlsdGVyKGZsb3cpe1xuICAgICAgICByZXR1cm4gZmxvdy5yZXF1ZXN0ICYmICFmbG93LnJlc3BvbnNlO1xuICAgIH1cbiAgICBub1Jlc3BvbnNlRmlsdGVyLmRlc2MgPSBcImhhcyBubyByZXNwb25zZVwiO1xuICAgIGZ1bmN0aW9uIHJlc3BvbnNlRmlsdGVyKGZsb3cpe1xuICAgICAgICByZXR1cm4gISFmbG93LnJlc3BvbnNlO1xuICAgIH1cbiAgICByZXNwb25zZUZpbHRlci5kZXNjID0gXCJoYXMgcmVzcG9uc2VcIjtcblxuICAgIGZ1bmN0aW9uIGNvbnRlbnRUeXBlKHJlZ2V4KXtcbiAgICAgICAgcmVnZXggPSBuZXcgUmVnRXhwKHJlZ2V4LCBcImlcIik7XG4gICAgICAgIGZ1bmN0aW9uIGNvbnRlbnRUeXBlRmlsdGVyKGZsb3cpe1xuICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgICAoZmxvdy5yZXF1ZXN0ICYmIHJlZ2V4LnRlc3QoUmVxdWVzdFV0aWxzLmdldENvbnRlbnRUeXBlKGZsb3cucmVxdWVzdCkpKVxuICAgICAgICAgICAgICAgIHx8XG4gICAgICAgICAgICAgICAgKGZsb3cucmVzcG9uc2UgJiYgcmVnZXgudGVzdChSZXNwb25zZVV0aWxzLmdldENvbnRlbnRUeXBlKGZsb3cucmVzcG9uc2UpKSlcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgY29udGVudFR5cGVGaWx0ZXIuZGVzYyA9IFwiY29udGVudCB0eXBlIG1hdGNoZXMgXCIgKyByZWdleDtcbiAgICAgICAgcmV0dXJuIGNvbnRlbnRUeXBlRmlsdGVyO1xuICAgIH1cbiAgICBmdW5jdGlvbiByZXF1ZXN0Q29udGVudFR5cGUocmVnZXgpe1xuICAgICAgICByZWdleCA9IG5ldyBSZWdFeHAocmVnZXgsIFwiaVwiKTtcbiAgICAgICAgZnVuY3Rpb24gcmVxdWVzdENvbnRlbnRUeXBlRmlsdGVyKGZsb3cpe1xuICAgICAgICAgICAgcmV0dXJuIGZsb3cucmVxdWVzdCAmJiByZWdleC50ZXN0KFJlcXVlc3RVdGlscy5nZXRDb250ZW50VHlwZShmbG93LnJlcXVlc3QpKTtcbiAgICAgICAgfVxuICAgICAgICByZXF1ZXN0Q29udGVudFR5cGVGaWx0ZXIuZGVzYyA9IFwicmVxLiBjb250ZW50IHR5cGUgbWF0Y2hlcyBcIiArIHJlZ2V4O1xuICAgICAgICByZXR1cm4gcmVxdWVzdENvbnRlbnRUeXBlRmlsdGVyO1xuICAgIH1cbiAgICBmdW5jdGlvbiByZXNwb25zZUNvbnRlbnRUeXBlKHJlZ2V4KXtcbiAgICAgICAgcmVnZXggPSBuZXcgUmVnRXhwKHJlZ2V4LCBcImlcIik7XG4gICAgICAgIGZ1bmN0aW9uIHJlc3BvbnNlQ29udGVudFR5cGVGaWx0ZXIoZmxvdyl7XG4gICAgICAgICAgICByZXR1cm4gZmxvdy5yZXNwb25zZSAmJiByZWdleC50ZXN0KFJlc3BvbnNlVXRpbHMuZ2V0Q29udGVudFR5cGUoZmxvdy5yZXNwb25zZSkpO1xuICAgICAgICB9XG4gICAgICAgIHJlc3BvbnNlQ29udGVudFR5cGVGaWx0ZXIuZGVzYyA9IFwicmVzcC4gY29udGVudCB0eXBlIG1hdGNoZXMgXCIgKyByZWdleDtcbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlQ29udGVudFR5cGVGaWx0ZXI7XG4gICAgfVxuICAgIGZ1bmN0aW9uIHVybChyZWdleCl7XG4gICAgICAgIHJlZ2V4ID0gbmV3IFJlZ0V4cChyZWdleCwgXCJpXCIpO1xuICAgICAgICBmdW5jdGlvbiB1cmxGaWx0ZXIoZmxvdyl7XG4gICAgICAgICAgICByZXR1cm4gZmxvdy5yZXF1ZXN0ICYmIHJlZ2V4LnRlc3QoUmVxdWVzdFV0aWxzLnByZXR0eV91cmwoZmxvdy5yZXF1ZXN0KSk7XG4gICAgICAgIH1cbiAgICAgICAgdXJsRmlsdGVyLmRlc2MgPSBcInVybCBtYXRjaGVzIFwiICsgcmVnZXg7XG4gICAgICAgIHJldHVybiB1cmxGaWx0ZXI7XG4gICAgfVxuXG5cbiAgICBwZWckcmVzdWx0ID0gcGVnJHN0YXJ0UnVsZUZ1bmN0aW9uKCk7XG5cbiAgICBpZiAocGVnJHJlc3VsdCAhPT0gcGVnJEZBSUxFRCAmJiBwZWckY3VyclBvcyA9PT0gaW5wdXQubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gcGVnJHJlc3VsdDtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHBlZyRyZXN1bHQgIT09IHBlZyRGQUlMRUQgJiYgcGVnJGN1cnJQb3MgPCBpbnB1dC5sZW5ndGgpIHtcbiAgICAgICAgcGVnJGZhaWwoeyB0eXBlOiBcImVuZFwiLCBkZXNjcmlwdGlvbjogXCJlbmQgb2YgaW5wdXRcIiB9KTtcbiAgICAgIH1cblxuICAgICAgdGhyb3cgcGVnJGJ1aWxkRXhjZXB0aW9uKG51bGwsIHBlZyRtYXhGYWlsRXhwZWN0ZWQsIHBlZyRtYXhGYWlsUG9zKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4ge1xuICAgIFN5bnRheEVycm9yOiBTeW50YXhFcnJvcixcbiAgICBwYXJzZTogICAgICAgcGFyc2VcbiAgfTtcbn0pKCk7XG4vKiBqc2hpbnQgaWdub3JlOmVuZCAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IEZpbHQ7XG4iLCJ2YXIgXyA9IHJlcXVpcmUoXCJsb2Rhc2hcIik7XG5cbnZhciBfTWVzc2FnZVV0aWxzID0ge1xuICAgIGdldENvbnRlbnRUeXBlOiBmdW5jdGlvbiAobWVzc2FnZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRfZmlyc3RfaGVhZGVyKG1lc3NhZ2UsIC9eQ29udGVudC1UeXBlJC9pKTtcbiAgICB9LFxuICAgIGdldF9maXJzdF9oZWFkZXI6IGZ1bmN0aW9uIChtZXNzYWdlLCByZWdleCkge1xuICAgICAgICAvL0ZJWE1FOiBDYWNoZSBJbnZhbGlkYXRpb24uXG4gICAgICAgIGlmICghbWVzc2FnZS5faGVhZGVyTG9va3VwcylcbiAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShtZXNzYWdlLCBcIl9oZWFkZXJMb29rdXBzXCIsIHtcbiAgICAgICAgICAgICAgICB2YWx1ZToge30sXG4gICAgICAgICAgICAgICAgY29uZmlndXJhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICB3cml0YWJsZTogZmFsc2VcbiAgICAgICAgICAgIH0pO1xuICAgICAgICBpZiAoIShyZWdleCBpbiBtZXNzYWdlLl9oZWFkZXJMb29rdXBzKSkge1xuICAgICAgICAgICAgdmFyIGhlYWRlcjtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWVzc2FnZS5oZWFkZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKCEhbWVzc2FnZS5oZWFkZXJzW2ldWzBdLm1hdGNoKHJlZ2V4KSkge1xuICAgICAgICAgICAgICAgICAgICBoZWFkZXIgPSBtZXNzYWdlLmhlYWRlcnNbaV07XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG1lc3NhZ2UuX2hlYWRlckxvb2t1cHNbcmVnZXhdID0gaGVhZGVyID8gaGVhZGVyWzFdIDogdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBtZXNzYWdlLl9oZWFkZXJMb29rdXBzW3JlZ2V4XTtcbiAgICB9LFxuICAgIG1hdGNoX2hlYWRlcjogZnVuY3Rpb24gKG1lc3NhZ2UsIHJlZ2V4KSB7XG4gICAgICAgIHZhciBoZWFkZXJzID0gbWVzc2FnZS5oZWFkZXJzO1xuICAgICAgICB2YXIgaSA9IGhlYWRlcnMubGVuZ3RoO1xuICAgICAgICB3aGlsZSAoaS0tKSB7XG4gICAgICAgICAgICBpZiAocmVnZXgudGVzdChoZWFkZXJzW2ldLmpvaW4oXCIgXCIpKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBoZWFkZXJzW2ldO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG59O1xuXG52YXIgZGVmYXVsdFBvcnRzID0ge1xuICAgIFwiaHR0cFwiOiA4MCxcbiAgICBcImh0dHBzXCI6IDQ0M1xufTtcblxudmFyIFJlcXVlc3RVdGlscyA9IF8uZXh0ZW5kKF9NZXNzYWdlVXRpbHMsIHtcbiAgICBwcmV0dHlfaG9zdDogZnVuY3Rpb24gKHJlcXVlc3QpIHtcbiAgICAgICAgLy9GSVhNRTogQWRkIGhvc3RoZWFkZXJcbiAgICAgICAgcmV0dXJuIHJlcXVlc3QuaG9zdDtcbiAgICB9LFxuICAgIHByZXR0eV91cmw6IGZ1bmN0aW9uIChyZXF1ZXN0KSB7XG4gICAgICAgIHZhciBwb3J0ID0gXCJcIjtcbiAgICAgICAgaWYgKGRlZmF1bHRQb3J0c1tyZXF1ZXN0LnNjaGVtZV0gIT09IHJlcXVlc3QucG9ydCkge1xuICAgICAgICAgICAgcG9ydCA9IFwiOlwiICsgcmVxdWVzdC5wb3J0O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXF1ZXN0LnNjaGVtZSArIFwiOi8vXCIgKyB0aGlzLnByZXR0eV9ob3N0KHJlcXVlc3QpICsgcG9ydCArIHJlcXVlc3QucGF0aDtcbiAgICB9XG59KTtcblxudmFyIFJlc3BvbnNlVXRpbHMgPSBfLmV4dGVuZChfTWVzc2FnZVV0aWxzLCB7fSk7XG5cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gICAgUmVzcG9uc2VVdGlsczogUmVzcG9uc2VVdGlscyxcbiAgICBSZXF1ZXN0VXRpbHM6IFJlcXVlc3RVdGlsc1xuXG59IiwiXG52YXIgXyA9IHJlcXVpcmUoXCJsb2Rhc2hcIik7XG52YXIgJCA9IHJlcXVpcmUoXCJqcXVlcnlcIik7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoXCIuLi91dGlscy5qc1wiKTtcbnZhciBhY3Rpb25zID0gcmVxdWlyZShcIi4uL2FjdGlvbnMuanNcIik7XG52YXIgZGlzcGF0Y2hlciA9IHJlcXVpcmUoXCIuLi9kaXNwYXRjaGVyLmpzXCIpO1xuXG5cbmZ1bmN0aW9uIExpc3RTdG9yZSgpIHtcbiAgICB1dGlscy5FdmVudEVtaXR0ZXIuY2FsbCh0aGlzKTtcbiAgICB0aGlzLnJlc2V0KCk7XG59XG5fLmV4dGVuZChMaXN0U3RvcmUucHJvdG90eXBlLCB1dGlscy5FdmVudEVtaXR0ZXIucHJvdG90eXBlLCB7XG4gICAgYWRkOiBmdW5jdGlvbiAoZWxlbSkge1xuICAgICAgICBpZiAoZWxlbS5pZCBpbiB0aGlzLl9wb3NfbWFwKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fcG9zX21hcFtlbGVtLmlkXSA9IHRoaXMubGlzdC5sZW5ndGg7XG4gICAgICAgIHRoaXMubGlzdC5wdXNoKGVsZW0pO1xuICAgICAgICB0aGlzLmVtaXQoXCJhZGRcIiwgZWxlbSk7XG4gICAgfSxcbiAgICB1cGRhdGU6IGZ1bmN0aW9uIChlbGVtKSB7XG4gICAgICAgIGlmICghKGVsZW0uaWQgaW4gdGhpcy5fcG9zX21hcCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmxpc3RbdGhpcy5fcG9zX21hcFtlbGVtLmlkXV0gPSBlbGVtO1xuICAgICAgICB0aGlzLmVtaXQoXCJ1cGRhdGVcIiwgZWxlbSk7XG4gICAgfSxcbiAgICByZW1vdmU6IGZ1bmN0aW9uIChlbGVtX2lkKSB7XG4gICAgICAgIGlmICghKGVsZW1faWQgaW4gdGhpcy5fcG9zX21hcCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmxpc3Quc3BsaWNlKHRoaXMuX3Bvc19tYXBbZWxlbV9pZF0sIDEpO1xuICAgICAgICB0aGlzLl9idWlsZF9tYXAoKTtcbiAgICAgICAgdGhpcy5lbWl0KFwicmVtb3ZlXCIsIGVsZW1faWQpO1xuICAgIH0sXG4gICAgcmVzZXQ6IGZ1bmN0aW9uIChlbGVtcykge1xuICAgICAgICB0aGlzLmxpc3QgPSBlbGVtcyB8fCBbXTtcbiAgICAgICAgdGhpcy5fYnVpbGRfbWFwKCk7XG4gICAgICAgIHRoaXMuZW1pdChcInJlY2FsY3VsYXRlXCIpO1xuICAgIH0sXG4gICAgX2J1aWxkX21hcDogZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLl9wb3NfbWFwID0ge307XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5saXN0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB2YXIgZWxlbSA9IHRoaXMubGlzdFtpXTtcbiAgICAgICAgICAgIHRoaXMuX3Bvc19tYXBbZWxlbS5pZF0gPSBpO1xuICAgICAgICB9XG4gICAgfSxcbiAgICBnZXQ6IGZ1bmN0aW9uIChlbGVtX2lkKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmxpc3RbdGhpcy5fcG9zX21hcFtlbGVtX2lkXV07XG4gICAgfSxcbiAgICBpbmRleDogZnVuY3Rpb24gKGVsZW1faWQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Bvc19tYXBbZWxlbV9pZF07XG4gICAgfVxufSk7XG5cblxuZnVuY3Rpb24gRGljdFN0b3JlKCkge1xuICAgIHV0aWxzLkV2ZW50RW1pdHRlci5jYWxsKHRoaXMpO1xuICAgIHRoaXMucmVzZXQoKTtcbn1cbl8uZXh0ZW5kKERpY3RTdG9yZS5wcm90b3R5cGUsIHV0aWxzLkV2ZW50RW1pdHRlci5wcm90b3R5cGUsIHtcbiAgICB1cGRhdGU6IGZ1bmN0aW9uIChkaWN0KSB7XG4gICAgICAgIF8ubWVyZ2UodGhpcy5kaWN0LCBkaWN0KTtcbiAgICAgICAgdGhpcy5lbWl0KFwicmVjYWxjdWxhdGVcIik7XG4gICAgfSxcbiAgICByZXNldDogZnVuY3Rpb24gKGRpY3QpIHtcbiAgICAgICAgdGhpcy5kaWN0ID0gZGljdCB8fCB7fTtcbiAgICAgICAgdGhpcy5lbWl0KFwicmVjYWxjdWxhdGVcIik7XG4gICAgfVxufSk7XG5cbmZ1bmN0aW9uIExpdmVTdG9yZU1peGluKHR5cGUpIHtcbiAgICB0aGlzLnR5cGUgPSB0eXBlO1xuXG4gICAgdGhpcy5fdXBkYXRlc19iZWZvcmVfZmV0Y2ggPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5fZmV0Y2h4aHIgPSBmYWxzZTtcblxuICAgIHRoaXMuaGFuZGxlID0gdGhpcy5oYW5kbGUuYmluZCh0aGlzKTtcbiAgICBkaXNwYXRjaGVyLkFwcERpc3BhdGNoZXIucmVnaXN0ZXIodGhpcy5oYW5kbGUpO1xuXG4gICAgLy8gQXZvaWQgZG91YmxlLWZldGNoIG9uIHN0YXJ0dXAuXG4gICAgaWYgKCEod2luZG93LndzICYmIHdpbmRvdy53cy5yZWFkeVN0YXRlID09PSBXZWJTb2NrZXQuQ09OTkVDVElORykpIHtcbiAgICAgICAgdGhpcy5mZXRjaCgpO1xuICAgIH1cbn1cbl8uZXh0ZW5kKExpdmVTdG9yZU1peGluLnByb3RvdHlwZSwge1xuICAgIGhhbmRsZTogZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgIGlmIChldmVudC50eXBlID09PSBhY3Rpb25zLkFjdGlvblR5cGVzLkNPTk5FQ1RJT05fT1BFTikge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZmV0Y2goKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZXZlbnQudHlwZSA9PT0gdGhpcy50eXBlKSB7XG4gICAgICAgICAgICBpZiAoZXZlbnQuY21kID09PSBhY3Rpb25zLlN0b3JlQ21kcy5SRVNFVCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZmV0Y2goZXZlbnQuZGF0YSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuX3VwZGF0ZXNfYmVmb3JlX2ZldGNoKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCJkZWZlciB1cGRhdGVcIiwgZXZlbnQpO1xuICAgICAgICAgICAgICAgIHRoaXMuX3VwZGF0ZXNfYmVmb3JlX2ZldGNoLnB1c2goZXZlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzW2V2ZW50LmNtZF0oZXZlbnQuZGF0YSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9LFxuICAgIGNsb3NlOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGRpc3BhdGNoZXIuQXBwRGlzcGF0Y2hlci51bnJlZ2lzdGVyKHRoaXMuaGFuZGxlKTtcbiAgICB9LFxuICAgIGZldGNoOiBmdW5jdGlvbiAoZGF0YSkge1xuICAgICAgICBjb25zb2xlLmxvZyhcImZldGNoIFwiICsgdGhpcy50eXBlKTtcbiAgICAgICAgaWYgKHRoaXMuX2ZldGNoeGhyKSB7XG4gICAgICAgICAgICB0aGlzLl9mZXRjaHhoci5hYm9ydCgpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3VwZGF0ZXNfYmVmb3JlX2ZldGNoID0gW107IC8vIChKUzogZW1wdHkgYXJyYXkgaXMgdHJ1ZSlcbiAgICAgICAgaWYgKGRhdGEpIHtcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlX2ZldGNoKGRhdGEpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fZmV0Y2h4aHIgPSAkLmdldEpTT04oXCIvXCIgKyB0aGlzLnR5cGUpXG4gICAgICAgICAgICAgICAgLmRvbmUoZnVuY3Rpb24gKG1lc3NhZ2UpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5oYW5kbGVfZmV0Y2gobWVzc2FnZS5kYXRhKTtcbiAgICAgICAgICAgICAgICB9LmJpbmQodGhpcykpXG4gICAgICAgICAgICAgICAgLmZhaWwoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICBFdmVudExvZ0FjdGlvbnMuYWRkX2V2ZW50KFwiQ291bGQgbm90IGZldGNoIFwiICsgdGhpcy50eXBlKTtcbiAgICAgICAgICAgICAgICB9LmJpbmQodGhpcykpO1xuICAgICAgICB9XG4gICAgfSxcbiAgICBoYW5kbGVfZmV0Y2g6IGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgIHRoaXMuX2ZldGNoeGhyID0gZmFsc2U7XG4gICAgICAgIGNvbnNvbGUubG9nKHRoaXMudHlwZSArIFwiIGZldGNoZWQuXCIsIHRoaXMuX3VwZGF0ZXNfYmVmb3JlX2ZldGNoKTtcbiAgICAgICAgdGhpcy5yZXNldChkYXRhKTtcbiAgICAgICAgdmFyIHVwZGF0ZXMgPSB0aGlzLl91cGRhdGVzX2JlZm9yZV9mZXRjaDtcbiAgICAgICAgdGhpcy5fdXBkYXRlc19iZWZvcmVfZmV0Y2ggPSBmYWxzZTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB1cGRhdGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB0aGlzLmhhbmRsZSh1cGRhdGVzW2ldKTtcbiAgICAgICAgfVxuICAgIH0sXG59KTtcblxuZnVuY3Rpb24gTGl2ZUxpc3RTdG9yZSh0eXBlKSB7XG4gICAgTGlzdFN0b3JlLmNhbGwodGhpcyk7XG4gICAgTGl2ZVN0b3JlTWl4aW4uY2FsbCh0aGlzLCB0eXBlKTtcbn1cbl8uZXh0ZW5kKExpdmVMaXN0U3RvcmUucHJvdG90eXBlLCBMaXN0U3RvcmUucHJvdG90eXBlLCBMaXZlU3RvcmVNaXhpbi5wcm90b3R5cGUpO1xuXG5mdW5jdGlvbiBMaXZlRGljdFN0b3JlKHR5cGUpIHtcbiAgICBEaWN0U3RvcmUuY2FsbCh0aGlzKTtcbiAgICBMaXZlU3RvcmVNaXhpbi5jYWxsKHRoaXMsIHR5cGUpO1xufVxuXy5leHRlbmQoTGl2ZURpY3RTdG9yZS5wcm90b3R5cGUsIERpY3RTdG9yZS5wcm90b3R5cGUsIExpdmVTdG9yZU1peGluLnByb3RvdHlwZSk7XG5cblxuZnVuY3Rpb24gRmxvd1N0b3JlKCkge1xuICAgIHJldHVybiBuZXcgTGl2ZUxpc3RTdG9yZShhY3Rpb25zLkFjdGlvblR5cGVzLkZMT1dfU1RPUkUpO1xufVxuXG5mdW5jdGlvbiBTZXR0aW5nc1N0b3JlKCkge1xuICAgIHJldHVybiBuZXcgTGl2ZURpY3RTdG9yZShhY3Rpb25zLkFjdGlvblR5cGVzLlNFVFRJTkdTX1NUT1JFKTtcbn1cblxuZnVuY3Rpb24gRXZlbnRMb2dTdG9yZSgpIHtcbiAgICBMaXZlTGlzdFN0b3JlLmNhbGwodGhpcywgYWN0aW9ucy5BY3Rpb25UeXBlcy5FVkVOVF9TVE9SRSk7XG59XG5fLmV4dGVuZChFdmVudExvZ1N0b3JlLnByb3RvdHlwZSwgTGl2ZUxpc3RTdG9yZS5wcm90b3R5cGUsIHtcbiAgICBmZXRjaDogZnVuY3Rpb24oKXtcbiAgICAgICAgTGl2ZUxpc3RTdG9yZS5wcm90b3R5cGUuZmV0Y2guYXBwbHkodGhpcywgYXJndW1lbnRzKTtcblxuICAgICAgICAvLyBNYWtlIHN1cmUgdG8gZGlzcGxheSB1cGRhdGVzIGV2ZW4gaWYgZmV0Y2hpbmcgYWxsIGV2ZW50cyBmYWlsZWQuXG4gICAgICAgIC8vIFRoaXMgd2F5LCB3ZSBjYW4gc2VuZCBcImZldGNoIGZhaWxlZFwiIGxvZyBtZXNzYWdlcyB0byB0aGUgbG9nLlxuICAgICAgICBpZih0aGlzLl9mZXRjaHhocil7XG4gICAgICAgICAgICB0aGlzLl9mZXRjaHhoci5mYWlsKGZ1bmN0aW9uKCl7XG4gICAgICAgICAgICAgICAgdGhpcy5oYW5kbGVfZmV0Y2gobnVsbCk7XG4gICAgICAgICAgICB9LmJpbmQodGhpcykpO1xuICAgICAgICB9XG4gICAgfVxufSk7XG5cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gICAgRXZlbnRMb2dTdG9yZTogRXZlbnRMb2dTdG9yZSxcbiAgICBTZXR0aW5nc1N0b3JlOiBTZXR0aW5nc1N0b3JlLFxuICAgIEZsb3dTdG9yZTogRmxvd1N0b3JlXG59OyIsInZhciBfID0gcmVxdWlyZShcImxvZGFzaFwiKTtcblxudmFyIHV0aWxzID0gcmVxdWlyZShcIi4uL3V0aWxzLmpzXCIpO1xuXG5mdW5jdGlvbiBTb3J0QnlTdG9yZU9yZGVyKGVsZW0pIHtcbiAgICByZXR1cm4gdGhpcy5zdG9yZS5pbmRleChlbGVtLmlkKTtcbn1cblxudmFyIGRlZmF1bHRfc29ydCA9IFNvcnRCeVN0b3JlT3JkZXI7XG52YXIgZGVmYXVsdF9maWx0ID0gZnVuY3Rpb24oZWxlbSl7XG4gICAgcmV0dXJuIHRydWU7XG59O1xuXG5mdW5jdGlvbiBTdG9yZVZpZXcoc3RvcmUsIGZpbHQsIHNvcnRmdW4pIHtcbiAgICB1dGlscy5FdmVudEVtaXR0ZXIuY2FsbCh0aGlzKTtcbiAgICBmaWx0ID0gZmlsdCB8fCBkZWZhdWx0X2ZpbHQ7XG4gICAgc29ydGZ1biA9IHNvcnRmdW4gfHwgZGVmYXVsdF9zb3J0O1xuXG4gICAgdGhpcy5zdG9yZSA9IHN0b3JlO1xuXG4gICAgdGhpcy5hZGQgPSB0aGlzLmFkZC5iaW5kKHRoaXMpO1xuICAgIHRoaXMudXBkYXRlID0gdGhpcy51cGRhdGUuYmluZCh0aGlzKTtcbiAgICB0aGlzLnJlbW92ZSA9IHRoaXMucmVtb3ZlLmJpbmQodGhpcyk7XG4gICAgdGhpcy5yZWNhbGN1bGF0ZSA9IHRoaXMucmVjYWxjdWxhdGUuYmluZCh0aGlzKTtcbiAgICB0aGlzLnN0b3JlLmFkZExpc3RlbmVyKFwiYWRkXCIsIHRoaXMuYWRkKTtcbiAgICB0aGlzLnN0b3JlLmFkZExpc3RlbmVyKFwidXBkYXRlXCIsIHRoaXMudXBkYXRlKTtcbiAgICB0aGlzLnN0b3JlLmFkZExpc3RlbmVyKFwicmVtb3ZlXCIsIHRoaXMucmVtb3ZlKTtcbiAgICB0aGlzLnN0b3JlLmFkZExpc3RlbmVyKFwicmVjYWxjdWxhdGVcIiwgdGhpcy5yZWNhbGN1bGF0ZSk7XG5cbiAgICB0aGlzLnJlY2FsY3VsYXRlKGZpbHQsIHNvcnRmdW4pO1xufVxuXG5fLmV4dGVuZChTdG9yZVZpZXcucHJvdG90eXBlLCB1dGlscy5FdmVudEVtaXR0ZXIucHJvdG90eXBlLCB7XG4gICAgY2xvc2U6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5zdG9yZS5yZW1vdmVMaXN0ZW5lcihcImFkZFwiLCB0aGlzLmFkZCk7XG4gICAgICAgIHRoaXMuc3RvcmUucmVtb3ZlTGlzdGVuZXIoXCJ1cGRhdGVcIiwgdGhpcy51cGRhdGUpO1xuICAgICAgICB0aGlzLnN0b3JlLnJlbW92ZUxpc3RlbmVyKFwicmVtb3ZlXCIsIHRoaXMucmVtb3ZlKTtcbiAgICAgICAgdGhpcy5zdG9yZS5yZW1vdmVMaXN0ZW5lcihcInJlY2FsY3VsYXRlXCIsIHRoaXMucmVjYWxjdWxhdGUpO1xuICAgICAgICB9LFxuICAgICAgICByZWNhbGN1bGF0ZTogZnVuY3Rpb24gKGZpbHQsIHNvcnRmdW4pIHtcbiAgICAgICAgaWYgKGZpbHQpIHtcbiAgICAgICAgICAgIHRoaXMuZmlsdCA9IGZpbHQuYmluZCh0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc29ydGZ1bikge1xuICAgICAgICAgICAgdGhpcy5zb3J0ZnVuID0gc29ydGZ1bi5iaW5kKHRoaXMpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5saXN0ID0gdGhpcy5zdG9yZS5saXN0LmZpbHRlcih0aGlzLmZpbHQpO1xuICAgICAgICB0aGlzLmxpc3Quc29ydChmdW5jdGlvbiAoYSwgYikge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuc29ydGZ1bihhKSAtIHRoaXMuc29ydGZ1bihiKTtcbiAgICAgICAgfS5iaW5kKHRoaXMpKTtcbiAgICAgICAgdGhpcy5lbWl0KFwicmVjYWxjdWxhdGVcIik7XG4gICAgfSxcbiAgICBpbmRleDogZnVuY3Rpb24gKGVsZW0pIHtcbiAgICAgICAgcmV0dXJuIF8uc29ydGVkSW5kZXgodGhpcy5saXN0LCBlbGVtLCB0aGlzLnNvcnRmdW4pO1xuICAgIH0sXG4gICAgYWRkOiBmdW5jdGlvbiAoZWxlbSkge1xuICAgICAgICBpZiAodGhpcy5maWx0KGVsZW0pKSB7XG4gICAgICAgICAgICB2YXIgaWR4ID0gdGhpcy5pbmRleChlbGVtKTtcbiAgICAgICAgICAgIGlmIChpZHggPT09IHRoaXMubGlzdC5sZW5ndGgpIHsgLy9oYXBwZW5zIG9mdGVuLCAucHVzaCBpcyB3YXkgZmFzdGVyLlxuICAgICAgICAgICAgICAgIHRoaXMubGlzdC5wdXNoKGVsZW0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmxpc3Quc3BsaWNlKGlkeCwgMCwgZWxlbSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmVtaXQoXCJhZGRcIiwgZWxlbSwgaWR4KTtcbiAgICAgICAgfVxuICAgIH0sXG4gICAgdXBkYXRlOiBmdW5jdGlvbiAoZWxlbSkge1xuICAgICAgICB2YXIgaWR4O1xuICAgICAgICB2YXIgaSA9IHRoaXMubGlzdC5sZW5ndGg7XG4gICAgICAgIC8vIFNlYXJjaCBmcm9tIHRoZSBiYWNrLCB3ZSB1c3VhbGx5IHVwZGF0ZSB0aGUgbGF0ZXN0IGVudHJpZXMuXG4gICAgICAgIHdoaWxlIChpLS0pIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmxpc3RbaV0uaWQgPT09IGVsZW0uaWQpIHtcbiAgICAgICAgICAgICAgICBpZHggPSBpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGlkeCA9PT0gLTEpIHsgLy9ub3QgY29udGFpbmVkIGluIGxpc3RcbiAgICAgICAgICAgIHRoaXMuYWRkKGVsZW0pO1xuICAgICAgICB9IGVsc2UgaWYgKCF0aGlzLmZpbHQoZWxlbSkpIHtcbiAgICAgICAgICAgIHRoaXMucmVtb3ZlKGVsZW0uaWQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKHRoaXMuc29ydGZ1bih0aGlzLmxpc3RbaWR4XSkgIT09IHRoaXMuc29ydGZ1bihlbGVtKSkgeyAvL3NvcnRwb3MgaGFzIGNoYW5nZWRcbiAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZSh0aGlzLmxpc3RbaWR4XSk7XG4gICAgICAgICAgICAgICAgdGhpcy5hZGQoZWxlbSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMubGlzdFtpZHhdID0gZWxlbTtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXQoXCJ1cGRhdGVcIiwgZWxlbSwgaWR4KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0sXG4gICAgcmVtb3ZlOiBmdW5jdGlvbiAoZWxlbV9pZCkge1xuICAgICAgICB2YXIgaWR4ID0gdGhpcy5saXN0Lmxlbmd0aDtcbiAgICAgICAgd2hpbGUgKGlkeC0tKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5saXN0W2lkeF0uaWQgPT09IGVsZW1faWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmxpc3Quc3BsaWNlKGlkeCwgMSk7XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0KFwicmVtb3ZlXCIsIGVsZW1faWQsIGlkeCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gICAgU3RvcmVWaWV3OiBTdG9yZVZpZXdcbn07IiwidmFyICQgPSByZXF1aXJlKFwianF1ZXJ5XCIpO1xuXG5cbnZhciBLZXkgPSB7XG4gICAgVVA6IDM4LFxuICAgIERPV046IDQwLFxuICAgIFBBR0VfVVA6IDMzLFxuICAgIFBBR0VfRE9XTjogMzQsXG4gICAgSE9NRTogMzYsXG4gICAgRU5EOiAzNSxcbiAgICBMRUZUOiAzNyxcbiAgICBSSUdIVDogMzksXG4gICAgRU5URVI6IDEzLFxuICAgIEVTQzogMjcsXG4gICAgVEFCOiA5LFxuICAgIFNQQUNFOiAzMixcbiAgICBCQUNLU1BBQ0U6IDgsXG59O1xuLy8gQWRkIEEtWlxuZm9yICh2YXIgaSA9IDY1OyBpIDw9IDkwOyBpKyspIHtcbiAgICBLZXlbU3RyaW5nLmZyb21DaGFyQ29kZShpKV0gPSBpO1xufVxuXG5cbnZhciBmb3JtYXRTaXplID0gZnVuY3Rpb24gKGJ5dGVzKSB7XG4gICAgdmFyIHNpemUgPSBieXRlcztcbiAgICB2YXIgcHJlZml4ID0gW1wiQlwiLCBcIktCXCIsIFwiTUJcIiwgXCJHQlwiLCBcIlRCXCJdO1xuICAgIHZhciBpID0gMDtcbiAgICB3aGlsZSAoTWF0aC5hYnMoc2l6ZSkgPj0gMTAyNCAmJiBpIDwgcHJlZml4Lmxlbmd0aCAtIDEpIHtcbiAgICAgICAgaSsrO1xuICAgICAgICBzaXplID0gc2l6ZSAvIDEwMjQ7XG4gICAgfVxuICAgIHJldHVybiAoTWF0aC5mbG9vcihzaXplICogMTAwKSAvIDEwMC4wKS50b0ZpeGVkKDIpICsgcHJlZml4W2ldO1xufTtcblxuXG52YXIgZm9ybWF0VGltZURlbHRhID0gZnVuY3Rpb24gKG1pbGxpc2Vjb25kcykge1xuICAgIHZhciB0aW1lID0gbWlsbGlzZWNvbmRzO1xuICAgIHZhciBwcmVmaXggPSBbXCJtc1wiLCBcInNcIiwgXCJtaW5cIiwgXCJoXCJdO1xuICAgIHZhciBkaXYgPSBbMTAwMCwgNjAsIDYwXTtcbiAgICB2YXIgaSA9IDA7XG4gICAgd2hpbGUgKE1hdGguYWJzKHRpbWUpID49IGRpdltpXSAmJiBpIDwgZGl2Lmxlbmd0aCkge1xuICAgICAgICB0aW1lID0gdGltZSAvIGRpdltpXTtcbiAgICAgICAgaSsrO1xuICAgIH1cbiAgICByZXR1cm4gTWF0aC5yb3VuZCh0aW1lKSArIHByZWZpeFtpXTtcbn07XG5cblxudmFyIGZvcm1hdFRpbWVTdGFtcCA9IGZ1bmN0aW9uIChzZWNvbmRzKSB7XG4gICAgdmFyIHRzID0gKG5ldyBEYXRlKHNlY29uZHMgKiAxMDAwKSkudG9JU09TdHJpbmcoKTtcbiAgICByZXR1cm4gdHMucmVwbGFjZShcIlRcIiwgXCIgXCIpLnJlcGxhY2UoXCJaXCIsIFwiXCIpO1xufTtcblxuXG5mdW5jdGlvbiBFdmVudEVtaXR0ZXIoKSB7XG4gICAgdGhpcy5saXN0ZW5lcnMgPSB7fTtcbn1cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uIChldmVudCkge1xuICAgIGlmICghKGV2ZW50IGluIHRoaXMubGlzdGVuZXJzKSkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICB0aGlzLmxpc3RlbmVyc1tldmVudF0uZm9yRWFjaChmdW5jdGlvbiAobGlzdGVuZXIpIHtcbiAgICAgICAgbGlzdGVuZXIuYXBwbHkodGhpcywgYXJncyk7XG4gICAgfS5iaW5kKHRoaXMpKTtcbn07XG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyID0gZnVuY3Rpb24gKGV2ZW50cywgZikge1xuICAgIGV2ZW50cy5zcGxpdChcIiBcIikuZm9yRWFjaChmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgdGhpcy5saXN0ZW5lcnNbZXZlbnRdID0gdGhpcy5saXN0ZW5lcnNbZXZlbnRdIHx8IFtdO1xuICAgICAgICB0aGlzLmxpc3RlbmVyc1tldmVudF0ucHVzaChmKTtcbiAgICB9LmJpbmQodGhpcykpO1xufTtcbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucmVtb3ZlTGlzdGVuZXIgPSBmdW5jdGlvbiAoZXZlbnRzLCBmKSB7XG4gICAgaWYgKCEoZXZlbnRzIGluIHRoaXMubGlzdGVuZXJzKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGV2ZW50cy5zcGxpdChcIiBcIikuZm9yRWFjaChmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgdmFyIGluZGV4ID0gdGhpcy5saXN0ZW5lcnNbZXZlbnRdLmluZGV4T2YoZik7XG4gICAgICAgIGlmIChpbmRleCA+PSAwKSB7XG4gICAgICAgICAgICB0aGlzLmxpc3RlbmVyc1tldmVudF0uc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgfVxuICAgIH0uYmluZCh0aGlzKSk7XG59O1xuXG5cbmZ1bmN0aW9uIGdldENvb2tpZShuYW1lKSB7XG4gICAgdmFyIHIgPSBkb2N1bWVudC5jb29raWUubWF0Y2goXCJcXFxcYlwiICsgbmFtZSArIFwiPShbXjtdKilcXFxcYlwiKTtcbiAgICByZXR1cm4gciA/IHJbMV0gOiB1bmRlZmluZWQ7XG59XG52YXIgeHNyZiA9ICQucGFyYW0oe194c3JmOiBnZXRDb29raWUoXCJfeHNyZlwiKX0pO1xuXG4vL1Rvcm5hZG8gWFNSRiBQcm90ZWN0aW9uLlxuJC5hamF4UHJlZmlsdGVyKGZ1bmN0aW9uIChvcHRpb25zKSB7XG4gICAgaWYgKFtcInBvc3RcIiwgXCJwdXRcIiwgXCJkZWxldGVcIl0uaW5kZXhPZihvcHRpb25zLnR5cGUudG9Mb3dlckNhc2UoKSkgPj0gMCAmJiBvcHRpb25zLnVybFswXSA9PT0gXCIvXCIpIHtcbiAgICAgICAgaWYgKG9wdGlvbnMuZGF0YSkge1xuICAgICAgICAgICAgb3B0aW9ucy5kYXRhICs9IChcIiZcIiArIHhzcmYpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgb3B0aW9ucy5kYXRhID0geHNyZjtcbiAgICAgICAgfVxuICAgIH1cbn0pO1xuLy8gTG9nIEFKQVggRXJyb3JzXG4kKGRvY3VtZW50KS5hamF4RXJyb3IoZnVuY3Rpb24gKGV2ZW50LCBqcVhIUiwgYWpheFNldHRpbmdzLCB0aHJvd25FcnJvcikge1xuICAgIHZhciBtZXNzYWdlID0ganFYSFIucmVzcG9uc2VUZXh0O1xuICAgIGNvbnNvbGUuZXJyb3IobWVzc2FnZSwgYXJndW1lbnRzKTtcbiAgICBFdmVudExvZ0FjdGlvbnMuYWRkX2V2ZW50KHRocm93bkVycm9yICsgXCI6IFwiICsgbWVzc2FnZSk7XG4gICAgd2luZG93LmFsZXJ0KG1lc3NhZ2UpO1xufSk7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICAgIEV2ZW50RW1pdHRlcjogRXZlbnRFbWl0dGVyLFxuICAgIGZvcm1hdFNpemU6IGZvcm1hdFNpemUsXG4gICAgZm9ybWF0VGltZURlbHRhOiBmb3JtYXRUaW1lRGVsdGEsXG4gICAgZm9ybWF0VGltZVN0YW1wOiBmb3JtYXRUaW1lU3RhbXAsXG4gICAgS2V5OiBLZXlcbn07Il19