/* * ATTENTION: An "eval-source-map" devtool has been used. * This devtool is neither made for production nor for readable output files. * It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools. * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/) * or disable the default devtool with "devtool: false". * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/). */ (function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if(typeof define === 'function' && define.amd) define([], factory); else { var a = factory(); for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i]; } })(self, function() { return /******/ (function() { // webpackBootstrap /******/ "use strict"; /******/ var __webpack_modules__ = ({ /***/ "./libs/fullcalendar/fullcalendar.js": /*!*******************************************!*\ !*** ./libs/fullcalendar/fullcalendar.js ***! \*******************************************/ /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"Calendar\": function() { return /* reexport safe */ _fullcalendar_core__WEBPACK_IMPORTED_MODULE_0__.Calendar; },\n/* harmony export */ \"dayGridPlugin\": function() { return /* reexport safe */ _fullcalendar_daygrid__WEBPACK_IMPORTED_MODULE_1__[\"default\"]; },\n/* harmony export */ \"interactionPlugin\": function() { return /* reexport safe */ _fullcalendar_interaction__WEBPACK_IMPORTED_MODULE_2__[\"default\"]; },\n/* harmony export */ \"listPlugin\": function() { return /* reexport safe */ _fullcalendar_list__WEBPACK_IMPORTED_MODULE_3__[\"default\"]; },\n/* harmony export */ \"timegridPlugin\": function() { return /* reexport safe */ _fullcalendar_timegrid__WEBPACK_IMPORTED_MODULE_4__[\"default\"]; }\n/* harmony export */ });\n/* harmony import */ var _fullcalendar_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @fullcalendar/core */ \"./node_modules/@fullcalendar/core/index.esm.js\");\n/* harmony import */ var _fullcalendar_daygrid__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @fullcalendar/daygrid */ \"./node_modules/@fullcalendar/daygrid/index.esm.js\");\n/* harmony import */ var _fullcalendar_interaction__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @fullcalendar/interaction */ \"./node_modules/@fullcalendar/interaction/index.esm.js\");\n/* harmony import */ var _fullcalendar_list__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @fullcalendar/list */ \"./node_modules/@fullcalendar/list/index.esm.js\");\n/* harmony import */ var _fullcalendar_timegrid__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @fullcalendar/timegrid */ \"./node_modules/@fullcalendar/timegrid/index.esm.js\");\n\n\n\n\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9saWJzL2Z1bGxjYWxlbmRhci9mdWxsY2FsZW5kYXIuanMuanMiLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7OztBQUE4QztBQUNJO0FBQ1E7QUFDZDtBQUNRIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vVnVleHkvLi9saWJzL2Z1bGxjYWxlbmRhci9mdWxsY2FsZW5kYXIuanM/MzEwMSJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDYWxlbmRhciB9IGZyb20gJ0BmdWxsY2FsZW5kYXIvY29yZSc7XHJcbmltcG9ydCBkYXlHcmlkUGx1Z2luIGZyb20gJ0BmdWxsY2FsZW5kYXIvZGF5Z3JpZCc7XHJcbmltcG9ydCBpbnRlcmFjdGlvblBsdWdpbiBmcm9tICdAZnVsbGNhbGVuZGFyL2ludGVyYWN0aW9uJztcclxuaW1wb3J0IGxpc3RQbHVnaW4gZnJvbSAnQGZ1bGxjYWxlbmRhci9saXN0JztcclxuaW1wb3J0IHRpbWVncmlkUGx1Z2luIGZyb20gJ0BmdWxsY2FsZW5kYXIvdGltZWdyaWQnO1xyXG5cclxuZXhwb3J0IHsgQ2FsZW5kYXIsIGRheUdyaWRQbHVnaW4sIGludGVyYWN0aW9uUGx1Z2luLCBsaXN0UGx1Z2luLCB0aW1lZ3JpZFBsdWdpbiB9O1xyXG4iXSwibmFtZXMiOlsiQ2FsZW5kYXIiLCJkYXlHcmlkUGx1Z2luIiwiaW50ZXJhY3Rpb25QbHVnaW4iLCJsaXN0UGx1Z2luIiwidGltZWdyaWRQbHVnaW4iXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./libs/fullcalendar/fullcalendar.js\n"); /***/ }), /***/ "./node_modules/preact/compat/dist/compat.module.js": /*!**********************************************************!*\ !*** ./node_modules/preact/compat/dist/compat.module.js ***! \**********************************************************/ /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"Children\": function() { return /* binding */ O; },\n/* harmony export */ \"Component\": function() { return /* reexport safe */ preact__WEBPACK_IMPORTED_MODULE_0__.Component; },\n/* harmony export */ \"Fragment\": function() { return /* reexport safe */ preact__WEBPACK_IMPORTED_MODULE_0__.Fragment; },\n/* harmony export */ \"PureComponent\": function() { return /* binding */ w; },\n/* harmony export */ \"StrictMode\": function() { return /* binding */ vn; },\n/* harmony export */ \"Suspense\": function() { return /* binding */ D; },\n/* harmony export */ \"SuspenseList\": function() { return /* binding */ V; },\n/* harmony export */ \"__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED\": function() { return /* binding */ rn; },\n/* harmony export */ \"cloneElement\": function() { return /* binding */ cn; },\n/* harmony export */ \"createContext\": function() { return /* reexport safe */ preact__WEBPACK_IMPORTED_MODULE_0__.createContext; },\n/* harmony export */ \"createElement\": function() { return /* reexport safe */ preact__WEBPACK_IMPORTED_MODULE_0__.createElement; },\n/* harmony export */ \"createFactory\": function() { return /* binding */ on; },\n/* harmony export */ \"createPortal\": function() { return /* binding */ j; },\n/* harmony export */ \"createRef\": function() { return /* reexport safe */ preact__WEBPACK_IMPORTED_MODULE_0__.createRef; },\n/* harmony export */ \"default\": function() { return /* binding */ bn; },\n/* harmony export */ \"findDOMNode\": function() { return /* binding */ an; },\n/* harmony export */ \"flushSync\": function() { return /* binding */ hn; },\n/* harmony export */ \"forwardRef\": function() { return /* binding */ k; },\n/* harmony export */ \"hydrate\": function() { return /* binding */ q; },\n/* harmony export */ \"isValidElement\": function() { return /* binding */ ln; },\n/* harmony export */ \"lazy\": function() { return /* binding */ M; },\n/* harmony export */ \"memo\": function() { return /* binding */ R; },\n/* harmony export */ \"render\": function() { return /* binding */ Y; },\n/* harmony export */ \"startTransition\": function() { return /* binding */ dn; },\n/* harmony export */ \"unmountComponentAtNode\": function() { return /* binding */ fn; },\n/* harmony export */ \"unstable_batchedUpdates\": function() { return /* binding */ sn; },\n/* harmony export */ \"useCallback\": function() { return /* reexport safe */ preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useCallback; },\n/* harmony export */ \"useContext\": function() { return /* reexport safe */ preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useContext; },\n/* harmony export */ \"useDebugValue\": function() { return /* reexport safe */ preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useDebugValue; },\n/* harmony export */ \"useDeferredValue\": function() { return /* binding */ pn; },\n/* harmony export */ \"useEffect\": function() { return /* reexport safe */ preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useEffect; },\n/* harmony export */ \"useErrorBoundary\": function() { return /* reexport safe */ preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useErrorBoundary; },\n/* harmony export */ \"useId\": function() { return /* reexport safe */ preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useId; },\n/* harmony export */ \"useImperativeHandle\": function() { return /* reexport safe */ preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useImperativeHandle; },\n/* harmony export */ \"useInsertionEffect\": function() { return /* binding */ yn; },\n/* harmony export */ \"useLayoutEffect\": function() { return /* reexport safe */ preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useLayoutEffect; },\n/* harmony export */ \"useMemo\": function() { return /* reexport safe */ preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useMemo; },\n/* harmony export */ \"useReducer\": function() { return /* reexport safe */ preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useReducer; },\n/* harmony export */ \"useRef\": function() { return /* reexport safe */ preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useRef; },\n/* harmony export */ \"useState\": function() { return /* reexport safe */ preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useState; },\n/* harmony export */ \"useSyncExternalStore\": function() { return /* binding */ _n; },\n/* harmony export */ \"useTransition\": function() { return /* binding */ mn; },\n/* harmony export */ \"version\": function() { return /* binding */ un; }\n/* harmony export */ });\n/* harmony import */ var preact__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! preact */ \"./node_modules/preact/dist/preact.module.js\");\n/* harmony import */ var preact_hooks__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! preact/hooks */ \"./node_modules/preact/hooks/dist/hooks.module.js\");\nfunction g(n,t){for(var e in t)n[e]=t[e];return n}function C(n,t){for(var e in n)if(\"__source\"!==e&&!(e in t))return!0;for(var r in t)if(\"__source\"!==r&&n[r]!==t[r])return!0;return!1}function E(n,t){return n===t&&(0!==n||1/n==1/t)||n!=n&&t!=t}function w(n){this.props=n}function R(n,e){function r(n){var t=this.props.ref,r=t==n.ref;return!r&&t&&(t.call?t(null):t.current=null),e?!e(this.props,n)||!r:C(this.props,n)}function u(e){return this.shouldComponentUpdate=r,(0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(n,e)}return u.displayName=\"Memo(\"+(n.displayName||n.name)+\")\",u.prototype.isReactComponent=!0,u.__f=!0,u}(w.prototype=new preact__WEBPACK_IMPORTED_MODULE_0__.Component).isPureReactComponent=!0,w.prototype.shouldComponentUpdate=function(n,t){return C(this.props,n)||C(this.state,t)};var x=preact__WEBPACK_IMPORTED_MODULE_0__.options.__b;preact__WEBPACK_IMPORTED_MODULE_0__.options.__b=function(n){n.type&&n.type.__f&&n.ref&&(n.props.ref=n.ref,n.ref=null),x&&x(n)};var N=\"undefined\"!=typeof Symbol&&Symbol.for&&Symbol.for(\"react.forward_ref\")||3911;function k(n){function t(t){var e=g({},t);return delete e.ref,n(e,t.ref||null)}return t.$$typeof=N,t.render=t,t.prototype.isReactComponent=t.__f=!0,t.displayName=\"ForwardRef(\"+(n.displayName||n.name)+\")\",t}var A=function(n,t){return null==n?null:(0,preact__WEBPACK_IMPORTED_MODULE_0__.toChildArray)((0,preact__WEBPACK_IMPORTED_MODULE_0__.toChildArray)(n).map(t))},O={map:A,forEach:A,count:function(n){return n?(0,preact__WEBPACK_IMPORTED_MODULE_0__.toChildArray)(n).length:0},only:function(n){var t=(0,preact__WEBPACK_IMPORTED_MODULE_0__.toChildArray)(n);if(1!==t.length)throw\"Children.only\";return t[0]},toArray:preact__WEBPACK_IMPORTED_MODULE_0__.toChildArray},T=preact__WEBPACK_IMPORTED_MODULE_0__.options.__e;preact__WEBPACK_IMPORTED_MODULE_0__.options.__e=function(n,t,e,r){if(n.then)for(var u,o=t;o=o.__;)if((u=o.__c)&&u.__c)return null==t.__e&&(t.__e=e.__e,t.__k=e.__k),u.__c(n,t);T(n,t,e,r)};var I=preact__WEBPACK_IMPORTED_MODULE_0__.options.unmount;function L(n,t,e){return n&&(n.__c&&n.__c.__H&&(n.__c.__H.__.forEach(function(n){\"function\"==typeof n.__c&&n.__c()}),n.__c.__H=null),null!=(n=g({},n)).__c&&(n.__c.__P===e&&(n.__c.__P=t),n.__c=null),n.__k=n.__k&&n.__k.map(function(n){return L(n,t,e)})),n}function U(n,t,e){return n&&(n.__v=null,n.__k=n.__k&&n.__k.map(function(n){return U(n,t,e)}),n.__c&&n.__c.__P===t&&(n.__e&&e.insertBefore(n.__e,n.__d),n.__c.__e=!0,n.__c.__P=e)),n}function D(){this.__u=0,this.t=null,this.__b=null}function F(n){var t=n.__.__c;return t&&t.__a&&t.__a(n)}function M(n){var e,r,u;function o(o){if(e||(e=n()).then(function(n){r=n.default||n},function(n){u=n}),u)throw u;if(!r)throw e;return (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(r,o)}return o.displayName=\"Lazy\",o.__f=!0,o}function V(){this.u=null,this.o=null}preact__WEBPACK_IMPORTED_MODULE_0__.options.unmount=function(n){var t=n.__c;t&&t.__R&&t.__R(),t&&!0===n.__h&&(n.type=null),I&&I(n)},(D.prototype=new preact__WEBPACK_IMPORTED_MODULE_0__.Component).__c=function(n,t){var e=t.__c,r=this;null==r.t&&(r.t=[]),r.t.push(e);var u=F(r.__v),o=!1,i=function(){o||(o=!0,e.__R=null,u?u(l):l())};e.__R=i;var l=function(){if(!--r.__u){if(r.state.__a){var n=r.state.__a;r.__v.__k[0]=U(n,n.__c.__P,n.__c.__O)}var t;for(r.setState({__a:r.__b=null});t=r.t.pop();)t.forceUpdate()}},c=!0===t.__h;r.__u++||c||r.setState({__a:r.__b=r.__v.__k[0]}),n.then(i,i)},D.prototype.componentWillUnmount=function(){this.t=[]},D.prototype.render=function(n,e){if(this.__b){if(this.__v.__k){var r=document.createElement(\"div\"),o=this.__v.__k[0].__c;this.__v.__k[0]=L(this.__b,r,o.__O=o.__P)}this.__b=null}var i=e.__a&&(0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(preact__WEBPACK_IMPORTED_MODULE_0__.Fragment,null,n.fallback);return i&&(i.__h=null),[(0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(preact__WEBPACK_IMPORTED_MODULE_0__.Fragment,null,e.__a?null:n.children),i]};var W=function(n,t,e){if(++e[1]===e[0]&&n.o.delete(t),n.props.revealOrder&&(\"t\"!==n.props.revealOrder[0]||!n.o.size))for(e=n.u;e;){for(;e.length>3;)e.pop()();if(e[1]>>1,1),e.i.removeChild(n)}}),(0,preact__WEBPACK_IMPORTED_MODULE_0__.render)((0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(P,{context:e.context},n.__v),e.l)):e.l&&e.componentWillUnmount()}function j(n,e){var r=(0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)($,{__v:n,i:e});return r.containerInfo=e,r}(V.prototype=new preact__WEBPACK_IMPORTED_MODULE_0__.Component).__a=function(n){var t=this,e=F(t.__v),r=t.o.get(n);return r[0]++,function(u){var o=function(){t.props.revealOrder?(r.push(u),W(t,n,r)):u()};e?e(o):o()}},V.prototype.render=function(n){this.u=null,this.o=new Map;var t=(0,preact__WEBPACK_IMPORTED_MODULE_0__.toChildArray)(n.children);n.revealOrder&&\"b\"===n.revealOrder[0]&&t.reverse();for(var e=t.length;e--;)this.o.set(t[e],this.u=[1,0,this.u]);return n.children},V.prototype.componentDidUpdate=V.prototype.componentDidMount=function(){var n=this;this.o.forEach(function(t,e){W(n,e,t)})};var z=\"undefined\"!=typeof Symbol&&Symbol.for&&Symbol.for(\"react.element\")||60103,B=/^(?:accent|alignment|arabic|baseline|cap|clip(?!PathU)|color|dominant|fill|flood|font|glyph(?!R)|horiz|image|letter|lighting|marker(?!H|W|U)|overline|paint|pointer|shape|stop|strikethrough|stroke|text(?!L)|transform|underline|unicode|units|v|vector|vert|word|writing|x(?!C))[A-Z]/,H=\"undefined\"!=typeof document,Z=function(n){return(\"undefined\"!=typeof Symbol&&\"symbol\"==typeof Symbol()?/fil|che|rad/i:/fil|che|ra/i).test(n)};function Y(n,t,e){return null==t.__k&&(t.textContent=\"\"),(0,preact__WEBPACK_IMPORTED_MODULE_0__.render)(n,t),\"function\"==typeof e&&e(),n?n.__c:null}function q(n,t,e){return (0,preact__WEBPACK_IMPORTED_MODULE_0__.hydrate)(n,t),\"function\"==typeof e&&e(),n?n.__c:null}preact__WEBPACK_IMPORTED_MODULE_0__.Component.prototype.isReactComponent={},[\"componentWillMount\",\"componentWillReceiveProps\",\"componentWillUpdate\"].forEach(function(t){Object.defineProperty(preact__WEBPACK_IMPORTED_MODULE_0__.Component.prototype,t,{configurable:!0,get:function(){return this[\"UNSAFE_\"+t]},set:function(n){Object.defineProperty(this,t,{configurable:!0,writable:!0,value:n})}})});var G=preact__WEBPACK_IMPORTED_MODULE_0__.options.event;function J(){}function K(){return this.cancelBubble}function Q(){return this.defaultPrevented}preact__WEBPACK_IMPORTED_MODULE_0__.options.event=function(n){return G&&(n=G(n)),n.persist=J,n.isPropagationStopped=K,n.isDefaultPrevented=Q,n.nativeEvent=n};var X,nn={configurable:!0,get:function(){return this.class}},tn=preact__WEBPACK_IMPORTED_MODULE_0__.options.vnode;preact__WEBPACK_IMPORTED_MODULE_0__.options.vnode=function(n){var t=n.type,e=n.props,u=e;if(\"string\"==typeof t){var o=-1===t.indexOf(\"-\");for(var i in u={},e){var l=e[i];H&&\"children\"===i&&\"noscript\"===t||\"value\"===i&&\"defaultValue\"in e&&null==l||(\"defaultValue\"===i&&\"value\"in e&&null==e.value?i=\"value\":\"download\"===i&&!0===l?l=\"\":/ondoubleclick/i.test(i)?i=\"ondblclick\":/^onchange(textarea|input)/i.test(i+t)&&!Z(e.type)?i=\"oninput\":/^onfocus$/i.test(i)?i=\"onfocusin\":/^onblur$/i.test(i)?i=\"onfocusout\":/^on(Ani|Tra|Tou|BeforeInp|Compo)/.test(i)?i=i.toLowerCase():o&&B.test(i)?i=i.replace(/[A-Z0-9]/g,\"-$&\").toLowerCase():null===l&&(l=void 0),/^oninput$/i.test(i)&&(i=i.toLowerCase(),u[i]&&(i=\"oninputCapture\")),u[i]=l)}\"select\"==t&&u.multiple&&Array.isArray(u.value)&&(u.value=(0,preact__WEBPACK_IMPORTED_MODULE_0__.toChildArray)(e.children).forEach(function(n){n.props.selected=-1!=u.value.indexOf(n.props.value)})),\"select\"==t&&null!=u.defaultValue&&(u.value=(0,preact__WEBPACK_IMPORTED_MODULE_0__.toChildArray)(e.children).forEach(function(n){n.props.selected=u.multiple?-1!=u.defaultValue.indexOf(n.props.value):u.defaultValue==n.props.value})),n.props=u,e.class!=e.className&&(nn.enumerable=\"className\"in e,null!=e.className&&(u.class=e.className),Object.defineProperty(u,\"className\",nn))}n.$$typeof=z,tn&&tn(n)};var en=preact__WEBPACK_IMPORTED_MODULE_0__.options.__r;preact__WEBPACK_IMPORTED_MODULE_0__.options.__r=function(n){en&&en(n),X=n.__c};var rn={ReactCurrentDispatcher:{current:{readContext:function(n){return X.__n[n.__c].props.value}}}},un=\"17.0.2\";function on(n){return preact__WEBPACK_IMPORTED_MODULE_0__.createElement.bind(null,n)}function ln(n){return!!n&&n.$$typeof===z}function cn(n){return ln(n)?preact__WEBPACK_IMPORTED_MODULE_0__.cloneElement.apply(null,arguments):n}function fn(n){return!!n.__k&&((0,preact__WEBPACK_IMPORTED_MODULE_0__.render)(null,n),!0)}function an(n){return n&&(n.base||1===n.nodeType&&n)||null}var sn=function(n,t){return n(t)},hn=function(n,t){return n(t)},vn=preact__WEBPACK_IMPORTED_MODULE_0__.Fragment;function dn(n){n()}function pn(n){return n}function mn(){return[!1,dn]}var yn=preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useLayoutEffect;function _n(n,t){var e=t(),r=(0,preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useState)({h:{__:e,v:t}}),u=r[0].h,o=r[1];return (0,preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useLayoutEffect)(function(){u.__=e,u.v=t,E(u.__,t())||o({h:u})},[n,e,t]),(0,preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useEffect)(function(){return E(u.__,u.v())||o({h:u}),n(function(){E(u.__,u.v())||o({h:u})})},[n]),e}var bn={useState:preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useState,useId:preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useId,useReducer:preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useReducer,useEffect:preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useEffect,useLayoutEffect:preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useLayoutEffect,useInsertionEffect:yn,useTransition:mn,useDeferredValue:pn,useSyncExternalStore:_n,startTransition:dn,useRef:preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useRef,useImperativeHandle:preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useImperativeHandle,useMemo:preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useMemo,useCallback:preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useCallback,useContext:preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useContext,useDebugValue:preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useDebugValue,version:\"17.0.2\",Children:O,render:Y,hydrate:q,unmountComponentAtNode:fn,createPortal:j,createElement:preact__WEBPACK_IMPORTED_MODULE_0__.createElement,createContext:preact__WEBPACK_IMPORTED_MODULE_0__.createContext,createFactory:on,cloneElement:cn,createRef:preact__WEBPACK_IMPORTED_MODULE_0__.createRef,Fragment:preact__WEBPACK_IMPORTED_MODULE_0__.Fragment,isValidElement:ln,findDOMNode:an,Component:preact__WEBPACK_IMPORTED_MODULE_0__.Component,PureComponent:w,memo:R,forwardRef:k,flushSync:hn,unstable_batchedUpdates:sn,StrictMode:vn,Suspense:D,SuspenseList:V,lazy:M,__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED:rn};\n//# sourceMappingURL=compat.module.js.map\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvcHJlYWN0L2NvbXBhdC9kaXN0L2NvbXBhdC5tb2R1bGUuanMuanMiLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQW9lLGdCQUFnQix5QkFBeUIsU0FBUyxnQkFBZ0IscURBQXFELHVEQUF1RCxTQUFTLGdCQUFnQiw0Q0FBNEMsY0FBYyxhQUFhLGdCQUFnQixjQUFjLGdDQUFnQyxvRkFBb0YsY0FBYyxvQ0FBb0MscURBQUMsTUFBTSxvR0FBb0csaUJBQWlCLDZDQUFDLDBFQUEwRSx5Q0FBeUMsTUFBTSwrQ0FBSyxDQUFDLCtDQUFLLGFBQWEsbUVBQW1FLG9GQUFvRixjQUFjLGNBQWMsVUFBVSxJQUFJLHFDQUFxQywrSEFBK0gsb0JBQW9CLG9CQUFvQixvREFBQyxDQUFDLG9EQUFDLFlBQVksSUFBSSxrQ0FBa0MsU0FBUyxvREFBQyxhQUFhLGtCQUFrQixNQUFNLG9EQUFDLElBQUkscUNBQXFDLFlBQVksU0FBUyxnREFBQyxDQUFDLEdBQUcsK0NBQUssQ0FBQywrQ0FBSyxtQkFBbUIsd0JBQXdCLE9BQU8sOEVBQThFLFlBQVksTUFBTSxtREFBUyxDQUFDLGtCQUFrQiwrREFBK0Qsa0NBQWtDLCtCQUErQix1RkFBdUYsZ0JBQWdCLEtBQUssa0JBQWtCLHlEQUF5RCxnQkFBZ0IseUZBQXlGLGFBQWEscUNBQXFDLGNBQWMsZUFBZSwwQkFBMEIsY0FBYyxVQUFVLGNBQWMsK0JBQStCLGVBQWUsYUFBYSxJQUFJLFlBQVksY0FBYyxPQUFPLHFEQUFDLE1BQU0sdUNBQXVDLGFBQWEsd0JBQXdCLG1EQUFTLGFBQWEsWUFBWSx1REFBdUQsa0JBQWtCLDZDQUFDLG9CQUFvQixtQkFBbUIsZ0NBQWdDLGlDQUFpQyxpQ0FBaUMsUUFBUSxpQkFBaUIsYUFBYSxnQkFBZ0Isa0JBQWtCLHNDQUFzQyxNQUFNLGdCQUFnQixlQUFlLEVBQUUsWUFBWSxrQkFBa0IsY0FBYyx3QkFBd0IsdUJBQXVCLGNBQWMsNkNBQTZDLFVBQVUsa0NBQWtDLGFBQWEsaUJBQWlCLDBEQUEwRCwwQ0FBMEMsY0FBYyxhQUFhLHFEQUFDLENBQUMsNENBQUMsa0JBQWtCLHdCQUF3QixxREFBQyxDQUFDLDRDQUFDLGlDQUFpQyxzQkFBc0IseUdBQXlHLEVBQUUsRUFBRSxLQUFLLFdBQVcsV0FBVyxtQkFBbUIsYUFBYSxjQUFjLHVDQUF1QyxpQkFBaUIsWUFBWSxjQUFjLGlCQUFpQixrQ0FBa0MsOENBQUMsNkJBQTZCLGdFQUFnRSw4REFBOEQsMkNBQTJDLDRCQUE0QiwyQ0FBMkMseUJBQXlCLDZFQUE2RSxFQUFFLDhDQUFDLENBQUMscURBQUMsSUFBSSxrQkFBa0IsNENBQTRDLGdCQUFnQixNQUFNLHFEQUFDLElBQUksVUFBVSxFQUFFLDJCQUEyQixpQkFBaUIsNkNBQUMsa0JBQWtCLG1DQUFtQywwQkFBMEIsaUJBQWlCLDhDQUE4QyxZQUFZLGdDQUFnQywyQkFBMkIsTUFBTSxvREFBQyxhQUFhLG1EQUFtRCxtQkFBbUIsSUFBSSxzQ0FBc0Msa0JBQWtCLHlFQUF5RSxXQUFXLDZCQUE2QixTQUFTLEdBQUcsMFpBQTBaLG9HQUFvRyxrQkFBa0IsdUNBQXVDLDhDQUFDLDZDQUE2QyxrQkFBa0IsT0FBTywrQ0FBQyw2Q0FBNkMsd0VBQTRCLEdBQUcsOEZBQThGLHNCQUFzQix1REFBVyxJQUFJLCtCQUErQix5QkFBeUIsaUJBQWlCLDhCQUE4QixvQ0FBb0MsR0FBRyxFQUFFLEVBQUUsTUFBTSxpREFBTyxDQUFDLGNBQWMsYUFBYSx5QkFBeUIsYUFBYSw2QkFBNkIsaURBQU8sYUFBYSxnR0FBZ0csVUFBVSwrQkFBK0IsbUJBQW1CLElBQUksaURBQU8sQ0FBQyxpREFBTyxhQUFhLDJCQUEyQix1QkFBdUIsMEJBQTBCLGlCQUFpQixJQUFJLFdBQVcseWlCQUF5aUIsMERBQTBELG9EQUFDLGlDQUFpQyxvREFBb0QsK0NBQStDLG9EQUFDLGlDQUFpQyxvR0FBb0csb0pBQW9KLHdCQUF3QixPQUFPLCtDQUFLLENBQUMsK0NBQUssYUFBYSxtQkFBbUIsUUFBUSx3QkFBd0IsU0FBUyx3QkFBd0IsbUNBQW1DLGFBQWEsZUFBZSxPQUFPLHNEQUFNLFNBQVMsZUFBZSwwQkFBMEIsZUFBZSxhQUFhLHNEQUFPLG1CQUFtQixlQUFlLGdCQUFnQiw4Q0FBQyxhQUFhLGVBQWUsNENBQTRDLHFCQUFxQixZQUFZLGtCQUFrQixZQUFZLElBQUksNENBQUMsQ0FBQyxlQUFlLElBQUksZUFBZSxTQUFTLGNBQWMsY0FBYyxPQUFPLHlEQUFDLENBQUMsaUJBQWlCLFlBQVksc0RBQUMsRUFBRSxHQUFHLFVBQVUsa0JBQWtCLE9BQU8sNkRBQUMsWUFBWSw2QkFBNkIsSUFBSSxFQUFFLFVBQVUsdURBQUMsWUFBWSx5QkFBeUIsSUFBSSxlQUFlLGtCQUFrQixJQUFJLEVBQUUsRUFBRSxRQUFRLFFBQVEsU0FBUyxrREFBQyxPQUFPLCtDQUFDLFlBQVksb0RBQUMsV0FBVyxtREFBQyxpQkFBaUIseURBQUMsOEdBQThHLGdEQUFDLHFCQUFxQiw2REFBQyxTQUFTLGlEQUFDLGFBQWEscURBQUMsWUFBWSxvREFBQyxlQUFlLHVEQUFDLHVHQUF1RyxpREFBQyxlQUFlLGlEQUFDLDRDQUE0Qyw2Q0FBQyxVQUFVLDRDQUFDLDRDQUE0Qyw2Q0FBQyxtTEFBK3JCO0FBQ2xsUyIsInNvdXJjZXMiOlsid2VicGFjazovL1Z1ZXh5Ly4vbm9kZV9tb2R1bGVzL3ByZWFjdC9jb21wYXQvZGlzdC9jb21wYXQubW9kdWxlLmpzPzE1ZDEiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0e0NvbXBvbmVudCBhcyBuLGNyZWF0ZUVsZW1lbnQgYXMgdCxvcHRpb25zIGFzIGUsdG9DaGlsZEFycmF5IGFzIHIsRnJhZ21lbnQgYXMgdSxyZW5kZXIgYXMgbyxoeWRyYXRlIGFzIGksY3JlYXRlQ29udGV4dCBhcyBsLGNyZWF0ZVJlZiBhcyBjLGNsb25lRWxlbWVudCBhcyBmfWZyb21cInByZWFjdFwiO2V4cG9ydHtDb21wb25lbnQsRnJhZ21lbnQsY3JlYXRlQ29udGV4dCxjcmVhdGVFbGVtZW50LGNyZWF0ZVJlZn1mcm9tXCJwcmVhY3RcIjtpbXBvcnR7dXNlU3RhdGUgYXMgYSx1c2VJZCBhcyBzLHVzZVJlZHVjZXIgYXMgaCx1c2VFZmZlY3QgYXMgdix1c2VMYXlvdXRFZmZlY3QgYXMgZCx1c2VSZWYgYXMgcCx1c2VJbXBlcmF0aXZlSGFuZGxlIGFzIG0sdXNlTWVtbyBhcyB5LHVzZUNhbGxiYWNrIGFzIF8sdXNlQ29udGV4dCBhcyBiLHVzZURlYnVnVmFsdWUgYXMgU31mcm9tXCJwcmVhY3QvaG9va3NcIjtleHBvcnQqZnJvbVwicHJlYWN0L2hvb2tzXCI7ZnVuY3Rpb24gZyhuLHQpe2Zvcih2YXIgZSBpbiB0KW5bZV09dFtlXTtyZXR1cm4gbn1mdW5jdGlvbiBDKG4sdCl7Zm9yKHZhciBlIGluIG4paWYoXCJfX3NvdXJjZVwiIT09ZSYmIShlIGluIHQpKXJldHVybiEwO2Zvcih2YXIgciBpbiB0KWlmKFwiX19zb3VyY2VcIiE9PXImJm5bcl0hPT10W3JdKXJldHVybiEwO3JldHVybiExfWZ1bmN0aW9uIEUobix0KXtyZXR1cm4gbj09PXQmJigwIT09bnx8MS9uPT0xL3QpfHxuIT1uJiZ0IT10fWZ1bmN0aW9uIHcobil7dGhpcy5wcm9wcz1ufWZ1bmN0aW9uIFIobixlKXtmdW5jdGlvbiByKG4pe3ZhciB0PXRoaXMucHJvcHMucmVmLHI9dD09bi5yZWY7cmV0dXJuIXImJnQmJih0LmNhbGw/dChudWxsKTp0LmN1cnJlbnQ9bnVsbCksZT8hZSh0aGlzLnByb3BzLG4pfHwhcjpDKHRoaXMucHJvcHMsbil9ZnVuY3Rpb24gdShlKXtyZXR1cm4gdGhpcy5zaG91bGRDb21wb25lbnRVcGRhdGU9cix0KG4sZSl9cmV0dXJuIHUuZGlzcGxheU5hbWU9XCJNZW1vKFwiKyhuLmRpc3BsYXlOYW1lfHxuLm5hbWUpK1wiKVwiLHUucHJvdG90eXBlLmlzUmVhY3RDb21wb25lbnQ9ITAsdS5fX2Y9ITAsdX0ody5wcm90b3R5cGU9bmV3IG4pLmlzUHVyZVJlYWN0Q29tcG9uZW50PSEwLHcucHJvdG90eXBlLnNob3VsZENvbXBvbmVudFVwZGF0ZT1mdW5jdGlvbihuLHQpe3JldHVybiBDKHRoaXMucHJvcHMsbil8fEModGhpcy5zdGF0ZSx0KX07dmFyIHg9ZS5fX2I7ZS5fX2I9ZnVuY3Rpb24obil7bi50eXBlJiZuLnR5cGUuX19mJiZuLnJlZiYmKG4ucHJvcHMucmVmPW4ucmVmLG4ucmVmPW51bGwpLHgmJngobil9O3ZhciBOPVwidW5kZWZpbmVkXCIhPXR5cGVvZiBTeW1ib2wmJlN5bWJvbC5mb3ImJlN5bWJvbC5mb3IoXCJyZWFjdC5mb3J3YXJkX3JlZlwiKXx8MzkxMTtmdW5jdGlvbiBrKG4pe2Z1bmN0aW9uIHQodCl7dmFyIGU9Zyh7fSx0KTtyZXR1cm4gZGVsZXRlIGUucmVmLG4oZSx0LnJlZnx8bnVsbCl9cmV0dXJuIHQuJCR0eXBlb2Y9Tix0LnJlbmRlcj10LHQucHJvdG90eXBlLmlzUmVhY3RDb21wb25lbnQ9dC5fX2Y9ITAsdC5kaXNwbGF5TmFtZT1cIkZvcndhcmRSZWYoXCIrKG4uZGlzcGxheU5hbWV8fG4ubmFtZSkrXCIpXCIsdH12YXIgQT1mdW5jdGlvbihuLHQpe3JldHVybiBudWxsPT1uP251bGw6cihyKG4pLm1hcCh0KSl9LE89e21hcDpBLGZvckVhY2g6QSxjb3VudDpmdW5jdGlvbihuKXtyZXR1cm4gbj9yKG4pLmxlbmd0aDowfSxvbmx5OmZ1bmN0aW9uKG4pe3ZhciB0PXIobik7aWYoMSE9PXQubGVuZ3RoKXRocm93XCJDaGlsZHJlbi5vbmx5XCI7cmV0dXJuIHRbMF19LHRvQXJyYXk6cn0sVD1lLl9fZTtlLl9fZT1mdW5jdGlvbihuLHQsZSxyKXtpZihuLnRoZW4pZm9yKHZhciB1LG89dDtvPW8uX187KWlmKCh1PW8uX19jKSYmdS5fX2MpcmV0dXJuIG51bGw9PXQuX19lJiYodC5fX2U9ZS5fX2UsdC5fX2s9ZS5fX2spLHUuX19jKG4sdCk7VChuLHQsZSxyKX07dmFyIEk9ZS51bm1vdW50O2Z1bmN0aW9uIEwobix0LGUpe3JldHVybiBuJiYobi5fX2MmJm4uX19jLl9fSCYmKG4uX19jLl9fSC5fXy5mb3JFYWNoKGZ1bmN0aW9uKG4pe1wiZnVuY3Rpb25cIj09dHlwZW9mIG4uX19jJiZuLl9fYygpfSksbi5fX2MuX19IPW51bGwpLG51bGwhPShuPWcoe30sbikpLl9fYyYmKG4uX19jLl9fUD09PWUmJihuLl9fYy5fX1A9dCksbi5fX2M9bnVsbCksbi5fX2s9bi5fX2smJm4uX19rLm1hcChmdW5jdGlvbihuKXtyZXR1cm4gTChuLHQsZSl9KSksbn1mdW5jdGlvbiBVKG4sdCxlKXtyZXR1cm4gbiYmKG4uX192PW51bGwsbi5fX2s9bi5fX2smJm4uX19rLm1hcChmdW5jdGlvbihuKXtyZXR1cm4gVShuLHQsZSl9KSxuLl9fYyYmbi5fX2MuX19QPT09dCYmKG4uX19lJiZlLmluc2VydEJlZm9yZShuLl9fZSxuLl9fZCksbi5fX2MuX19lPSEwLG4uX19jLl9fUD1lKSksbn1mdW5jdGlvbiBEKCl7dGhpcy5fX3U9MCx0aGlzLnQ9bnVsbCx0aGlzLl9fYj1udWxsfWZ1bmN0aW9uIEYobil7dmFyIHQ9bi5fXy5fX2M7cmV0dXJuIHQmJnQuX19hJiZ0Ll9fYShuKX1mdW5jdGlvbiBNKG4pe3ZhciBlLHIsdTtmdW5jdGlvbiBvKG8pe2lmKGV8fChlPW4oKSkudGhlbihmdW5jdGlvbihuKXtyPW4uZGVmYXVsdHx8bn0sZnVuY3Rpb24obil7dT1ufSksdSl0aHJvdyB1O2lmKCFyKXRocm93IGU7cmV0dXJuIHQocixvKX1yZXR1cm4gby5kaXNwbGF5TmFtZT1cIkxhenlcIixvLl9fZj0hMCxvfWZ1bmN0aW9uIFYoKXt0aGlzLnU9bnVsbCx0aGlzLm89bnVsbH1lLnVubW91bnQ9ZnVuY3Rpb24obil7dmFyIHQ9bi5fX2M7dCYmdC5fX1ImJnQuX19SKCksdCYmITA9PT1uLl9faCYmKG4udHlwZT1udWxsKSxJJiZJKG4pfSwoRC5wcm90b3R5cGU9bmV3IG4pLl9fYz1mdW5jdGlvbihuLHQpe3ZhciBlPXQuX19jLHI9dGhpcztudWxsPT1yLnQmJihyLnQ9W10pLHIudC5wdXNoKGUpO3ZhciB1PUYoci5fX3YpLG89ITEsaT1mdW5jdGlvbigpe298fChvPSEwLGUuX19SPW51bGwsdT91KGwpOmwoKSl9O2UuX19SPWk7dmFyIGw9ZnVuY3Rpb24oKXtpZighLS1yLl9fdSl7aWYoci5zdGF0ZS5fX2Epe3ZhciBuPXIuc3RhdGUuX19hO3IuX192Ll9fa1swXT1VKG4sbi5fX2MuX19QLG4uX19jLl9fTyl9dmFyIHQ7Zm9yKHIuc2V0U3RhdGUoe19fYTpyLl9fYj1udWxsfSk7dD1yLnQucG9wKCk7KXQuZm9yY2VVcGRhdGUoKX19LGM9ITA9PT10Ll9faDtyLl9fdSsrfHxjfHxyLnNldFN0YXRlKHtfX2E6ci5fX2I9ci5fX3YuX19rWzBdfSksbi50aGVuKGksaSl9LEQucHJvdG90eXBlLmNvbXBvbmVudFdpbGxVbm1vdW50PWZ1bmN0aW9uKCl7dGhpcy50PVtdfSxELnByb3RvdHlwZS5yZW5kZXI9ZnVuY3Rpb24obixlKXtpZih0aGlzLl9fYil7aWYodGhpcy5fX3YuX19rKXt2YXIgcj1kb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpLG89dGhpcy5fX3YuX19rWzBdLl9fYzt0aGlzLl9fdi5fX2tbMF09TCh0aGlzLl9fYixyLG8uX19PPW8uX19QKX10aGlzLl9fYj1udWxsfXZhciBpPWUuX19hJiZ0KHUsbnVsbCxuLmZhbGxiYWNrKTtyZXR1cm4gaSYmKGkuX19oPW51bGwpLFt0KHUsbnVsbCxlLl9fYT9udWxsOm4uY2hpbGRyZW4pLGldfTt2YXIgVz1mdW5jdGlvbihuLHQsZSl7aWYoKytlWzFdPT09ZVswXSYmbi5vLmRlbGV0ZSh0KSxuLnByb3BzLnJldmVhbE9yZGVyJiYoXCJ0XCIhPT1uLnByb3BzLnJldmVhbE9yZGVyWzBdfHwhbi5vLnNpemUpKWZvcihlPW4udTtlOyl7Zm9yKDtlLmxlbmd0aD4zOyllLnBvcCgpKCk7aWYoZVsxXTxlWzBdKWJyZWFrO24udT1lPWVbMl19fTtmdW5jdGlvbiBQKG4pe3JldHVybiB0aGlzLmdldENoaWxkQ29udGV4dD1mdW5jdGlvbigpe3JldHVybiBuLmNvbnRleHR9LG4uY2hpbGRyZW59ZnVuY3Rpb24gJChuKXt2YXIgZT10aGlzLHI9bi5pO2UuY29tcG9uZW50V2lsbFVubW91bnQ9ZnVuY3Rpb24oKXtvKG51bGwsZS5sKSxlLmw9bnVsbCxlLmk9bnVsbH0sZS5pJiZlLmkhPT1yJiZlLmNvbXBvbmVudFdpbGxVbm1vdW50KCksbi5fX3Y/KGUubHx8KGUuaT1yLGUubD17bm9kZVR5cGU6MSxwYXJlbnROb2RlOnIsY2hpbGROb2RlczpbXSxhcHBlbmRDaGlsZDpmdW5jdGlvbihuKXt0aGlzLmNoaWxkTm9kZXMucHVzaChuKSxlLmkuYXBwZW5kQ2hpbGQobil9LGluc2VydEJlZm9yZTpmdW5jdGlvbihuLHQpe3RoaXMuY2hpbGROb2Rlcy5wdXNoKG4pLGUuaS5hcHBlbmRDaGlsZChuKX0scmVtb3ZlQ2hpbGQ6ZnVuY3Rpb24obil7dGhpcy5jaGlsZE5vZGVzLnNwbGljZSh0aGlzLmNoaWxkTm9kZXMuaW5kZXhPZihuKT4+PjEsMSksZS5pLnJlbW92ZUNoaWxkKG4pfX0pLG8odChQLHtjb250ZXh0OmUuY29udGV4dH0sbi5fX3YpLGUubCkpOmUubCYmZS5jb21wb25lbnRXaWxsVW5tb3VudCgpfWZ1bmN0aW9uIGoobixlKXt2YXIgcj10KCQse19fdjpuLGk6ZX0pO3JldHVybiByLmNvbnRhaW5lckluZm89ZSxyfShWLnByb3RvdHlwZT1uZXcgbikuX19hPWZ1bmN0aW9uKG4pe3ZhciB0PXRoaXMsZT1GKHQuX192KSxyPXQuby5nZXQobik7cmV0dXJuIHJbMF0rKyxmdW5jdGlvbih1KXt2YXIgbz1mdW5jdGlvbigpe3QucHJvcHMucmV2ZWFsT3JkZXI/KHIucHVzaCh1KSxXKHQsbixyKSk6dSgpfTtlP2Uobyk6bygpfX0sVi5wcm90b3R5cGUucmVuZGVyPWZ1bmN0aW9uKG4pe3RoaXMudT1udWxsLHRoaXMubz1uZXcgTWFwO3ZhciB0PXIobi5jaGlsZHJlbik7bi5yZXZlYWxPcmRlciYmXCJiXCI9PT1uLnJldmVhbE9yZGVyWzBdJiZ0LnJldmVyc2UoKTtmb3IodmFyIGU9dC5sZW5ndGg7ZS0tOyl0aGlzLm8uc2V0KHRbZV0sdGhpcy51PVsxLDAsdGhpcy51XSk7cmV0dXJuIG4uY2hpbGRyZW59LFYucHJvdG90eXBlLmNvbXBvbmVudERpZFVwZGF0ZT1WLnByb3RvdHlwZS5jb21wb25lbnREaWRNb3VudD1mdW5jdGlvbigpe3ZhciBuPXRoaXM7dGhpcy5vLmZvckVhY2goZnVuY3Rpb24odCxlKXtXKG4sZSx0KX0pfTt2YXIgej1cInVuZGVmaW5lZFwiIT10eXBlb2YgU3ltYm9sJiZTeW1ib2wuZm9yJiZTeW1ib2wuZm9yKFwicmVhY3QuZWxlbWVudFwiKXx8NjAxMDMsQj0vXig/OmFjY2VudHxhbGlnbm1lbnR8YXJhYmljfGJhc2VsaW5lfGNhcHxjbGlwKD8hUGF0aFUpfGNvbG9yfGRvbWluYW50fGZpbGx8Zmxvb2R8Zm9udHxnbHlwaCg/IVIpfGhvcml6fGltYWdlfGxldHRlcnxsaWdodGluZ3xtYXJrZXIoPyFIfFd8VSl8b3ZlcmxpbmV8cGFpbnR8cG9pbnRlcnxzaGFwZXxzdG9wfHN0cmlrZXRocm91Z2h8c3Ryb2tlfHRleHQoPyFMKXx0cmFuc2Zvcm18dW5kZXJsaW5lfHVuaWNvZGV8dW5pdHN8dnx2ZWN0b3J8dmVydHx3b3JkfHdyaXRpbmd8eCg/IUMpKVtBLVpdLyxIPVwidW5kZWZpbmVkXCIhPXR5cGVvZiBkb2N1bWVudCxaPWZ1bmN0aW9uKG4pe3JldHVybihcInVuZGVmaW5lZFwiIT10eXBlb2YgU3ltYm9sJiZcInN5bWJvbFwiPT10eXBlb2YgU3ltYm9sKCk/L2ZpbHxjaGV8cmFkL2k6L2ZpbHxjaGV8cmEvaSkudGVzdChuKX07ZnVuY3Rpb24gWShuLHQsZSl7cmV0dXJuIG51bGw9PXQuX19rJiYodC50ZXh0Q29udGVudD1cIlwiKSxvKG4sdCksXCJmdW5jdGlvblwiPT10eXBlb2YgZSYmZSgpLG4/bi5fX2M6bnVsbH1mdW5jdGlvbiBxKG4sdCxlKXtyZXR1cm4gaShuLHQpLFwiZnVuY3Rpb25cIj09dHlwZW9mIGUmJmUoKSxuP24uX19jOm51bGx9bi5wcm90b3R5cGUuaXNSZWFjdENvbXBvbmVudD17fSxbXCJjb21wb25lbnRXaWxsTW91bnRcIixcImNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHNcIixcImNvbXBvbmVudFdpbGxVcGRhdGVcIl0uZm9yRWFjaChmdW5jdGlvbih0KXtPYmplY3QuZGVmaW5lUHJvcGVydHkobi5wcm90b3R5cGUsdCx7Y29uZmlndXJhYmxlOiEwLGdldDpmdW5jdGlvbigpe3JldHVybiB0aGlzW1wiVU5TQUZFX1wiK3RdfSxzZXQ6ZnVuY3Rpb24obil7T2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsdCx7Y29uZmlndXJhYmxlOiEwLHdyaXRhYmxlOiEwLHZhbHVlOm59KX19KX0pO3ZhciBHPWUuZXZlbnQ7ZnVuY3Rpb24gSigpe31mdW5jdGlvbiBLKCl7cmV0dXJuIHRoaXMuY2FuY2VsQnViYmxlfWZ1bmN0aW9uIFEoKXtyZXR1cm4gdGhpcy5kZWZhdWx0UHJldmVudGVkfWUuZXZlbnQ9ZnVuY3Rpb24obil7cmV0dXJuIEcmJihuPUcobikpLG4ucGVyc2lzdD1KLG4uaXNQcm9wYWdhdGlvblN0b3BwZWQ9SyxuLmlzRGVmYXVsdFByZXZlbnRlZD1RLG4ubmF0aXZlRXZlbnQ9bn07dmFyIFgsbm49e2NvbmZpZ3VyYWJsZTohMCxnZXQ6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5jbGFzc319LHRuPWUudm5vZGU7ZS52bm9kZT1mdW5jdGlvbihuKXt2YXIgdD1uLnR5cGUsZT1uLnByb3BzLHU9ZTtpZihcInN0cmluZ1wiPT10eXBlb2YgdCl7dmFyIG89LTE9PT10LmluZGV4T2YoXCItXCIpO2Zvcih2YXIgaSBpbiB1PXt9LGUpe3ZhciBsPWVbaV07SCYmXCJjaGlsZHJlblwiPT09aSYmXCJub3NjcmlwdFwiPT09dHx8XCJ2YWx1ZVwiPT09aSYmXCJkZWZhdWx0VmFsdWVcImluIGUmJm51bGw9PWx8fChcImRlZmF1bHRWYWx1ZVwiPT09aSYmXCJ2YWx1ZVwiaW4gZSYmbnVsbD09ZS52YWx1ZT9pPVwidmFsdWVcIjpcImRvd25sb2FkXCI9PT1pJiYhMD09PWw/bD1cIlwiOi9vbmRvdWJsZWNsaWNrL2kudGVzdChpKT9pPVwib25kYmxjbGlja1wiOi9eb25jaGFuZ2UodGV4dGFyZWF8aW5wdXQpL2kudGVzdChpK3QpJiYhWihlLnR5cGUpP2k9XCJvbmlucHV0XCI6L15vbmZvY3VzJC9pLnRlc3QoaSk/aT1cIm9uZm9jdXNpblwiOi9eb25ibHVyJC9pLnRlc3QoaSk/aT1cIm9uZm9jdXNvdXRcIjovXm9uKEFuaXxUcmF8VG91fEJlZm9yZUlucHxDb21wbykvLnRlc3QoaSk/aT1pLnRvTG93ZXJDYXNlKCk6byYmQi50ZXN0KGkpP2k9aS5yZXBsYWNlKC9bQS1aMC05XS9nLFwiLSQmXCIpLnRvTG93ZXJDYXNlKCk6bnVsbD09PWwmJihsPXZvaWQgMCksL15vbmlucHV0JC9pLnRlc3QoaSkmJihpPWkudG9Mb3dlckNhc2UoKSx1W2ldJiYoaT1cIm9uaW5wdXRDYXB0dXJlXCIpKSx1W2ldPWwpfVwic2VsZWN0XCI9PXQmJnUubXVsdGlwbGUmJkFycmF5LmlzQXJyYXkodS52YWx1ZSkmJih1LnZhbHVlPXIoZS5jaGlsZHJlbikuZm9yRWFjaChmdW5jdGlvbihuKXtuLnByb3BzLnNlbGVjdGVkPS0xIT11LnZhbHVlLmluZGV4T2Yobi5wcm9wcy52YWx1ZSl9KSksXCJzZWxlY3RcIj09dCYmbnVsbCE9dS5kZWZhdWx0VmFsdWUmJih1LnZhbHVlPXIoZS5jaGlsZHJlbikuZm9yRWFjaChmdW5jdGlvbihuKXtuLnByb3BzLnNlbGVjdGVkPXUubXVsdGlwbGU/LTEhPXUuZGVmYXVsdFZhbHVlLmluZGV4T2Yobi5wcm9wcy52YWx1ZSk6dS5kZWZhdWx0VmFsdWU9PW4ucHJvcHMudmFsdWV9KSksbi5wcm9wcz11LGUuY2xhc3MhPWUuY2xhc3NOYW1lJiYobm4uZW51bWVyYWJsZT1cImNsYXNzTmFtZVwiaW4gZSxudWxsIT1lLmNsYXNzTmFtZSYmKHUuY2xhc3M9ZS5jbGFzc05hbWUpLE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh1LFwiY2xhc3NOYW1lXCIsbm4pKX1uLiQkdHlwZW9mPXosdG4mJnRuKG4pfTt2YXIgZW49ZS5fX3I7ZS5fX3I9ZnVuY3Rpb24obil7ZW4mJmVuKG4pLFg9bi5fX2N9O3ZhciBybj17UmVhY3RDdXJyZW50RGlzcGF0Y2hlcjp7Y3VycmVudDp7cmVhZENvbnRleHQ6ZnVuY3Rpb24obil7cmV0dXJuIFguX19uW24uX19jXS5wcm9wcy52YWx1ZX19fX0sdW49XCIxNy4wLjJcIjtmdW5jdGlvbiBvbihuKXtyZXR1cm4gdC5iaW5kKG51bGwsbil9ZnVuY3Rpb24gbG4obil7cmV0dXJuISFuJiZuLiQkdHlwZW9mPT09en1mdW5jdGlvbiBjbihuKXtyZXR1cm4gbG4obik/Zi5hcHBseShudWxsLGFyZ3VtZW50cyk6bn1mdW5jdGlvbiBmbihuKXtyZXR1cm4hIW4uX19rJiYobyhudWxsLG4pLCEwKX1mdW5jdGlvbiBhbihuKXtyZXR1cm4gbiYmKG4uYmFzZXx8MT09PW4ubm9kZVR5cGUmJm4pfHxudWxsfXZhciBzbj1mdW5jdGlvbihuLHQpe3JldHVybiBuKHQpfSxobj1mdW5jdGlvbihuLHQpe3JldHVybiBuKHQpfSx2bj11O2Z1bmN0aW9uIGRuKG4pe24oKX1mdW5jdGlvbiBwbihuKXtyZXR1cm4gbn1mdW5jdGlvbiBtbigpe3JldHVyblshMSxkbl19dmFyIHluPWQ7ZnVuY3Rpb24gX24obix0KXt2YXIgZT10KCkscj1hKHtoOntfXzplLHY6dH19KSx1PXJbMF0uaCxvPXJbMV07cmV0dXJuIGQoZnVuY3Rpb24oKXt1Ll9fPWUsdS52PXQsRSh1Ll9fLHQoKSl8fG8oe2g6dX0pfSxbbixlLHRdKSx2KGZ1bmN0aW9uKCl7cmV0dXJuIEUodS5fXyx1LnYoKSl8fG8oe2g6dX0pLG4oZnVuY3Rpb24oKXtFKHUuX18sdS52KCkpfHxvKHtoOnV9KX0pfSxbbl0pLGV9dmFyIGJuPXt1c2VTdGF0ZTphLHVzZUlkOnMsdXNlUmVkdWNlcjpoLHVzZUVmZmVjdDp2LHVzZUxheW91dEVmZmVjdDpkLHVzZUluc2VydGlvbkVmZmVjdDp5bix1c2VUcmFuc2l0aW9uOm1uLHVzZURlZmVycmVkVmFsdWU6cG4sdXNlU3luY0V4dGVybmFsU3RvcmU6X24sc3RhcnRUcmFuc2l0aW9uOmRuLHVzZVJlZjpwLHVzZUltcGVyYXRpdmVIYW5kbGU6bSx1c2VNZW1vOnksdXNlQ2FsbGJhY2s6Xyx1c2VDb250ZXh0OmIsdXNlRGVidWdWYWx1ZTpTLHZlcnNpb246XCIxNy4wLjJcIixDaGlsZHJlbjpPLHJlbmRlcjpZLGh5ZHJhdGU6cSx1bm1vdW50Q29tcG9uZW50QXROb2RlOmZuLGNyZWF0ZVBvcnRhbDpqLGNyZWF0ZUVsZW1lbnQ6dCxjcmVhdGVDb250ZXh0OmwsY3JlYXRlRmFjdG9yeTpvbixjbG9uZUVsZW1lbnQ6Y24sY3JlYXRlUmVmOmMsRnJhZ21lbnQ6dSxpc1ZhbGlkRWxlbWVudDpsbixmaW5kRE9NTm9kZTphbixDb21wb25lbnQ6bixQdXJlQ29tcG9uZW50OncsbWVtbzpSLGZvcndhcmRSZWY6ayxmbHVzaFN5bmM6aG4sdW5zdGFibGVfYmF0Y2hlZFVwZGF0ZXM6c24sU3RyaWN0TW9kZTp2bixTdXNwZW5zZTpELFN1c3BlbnNlTGlzdDpWLGxhenk6TSxfX1NFQ1JFVF9JTlRFUk5BTFNfRE9fTk9UX1VTRV9PUl9ZT1VfV0lMTF9CRV9GSVJFRDpybn07ZXhwb3J0e08gYXMgQ2hpbGRyZW4sdyBhcyBQdXJlQ29tcG9uZW50LHZuIGFzIFN0cmljdE1vZGUsRCBhcyBTdXNwZW5zZSxWIGFzIFN1c3BlbnNlTGlzdCxybiBhcyBfX1NFQ1JFVF9JTlRFUk5BTFNfRE9fTk9UX1VTRV9PUl9ZT1VfV0lMTF9CRV9GSVJFRCxjbiBhcyBjbG9uZUVsZW1lbnQsb24gYXMgY3JlYXRlRmFjdG9yeSxqIGFzIGNyZWF0ZVBvcnRhbCxibiBhcyBkZWZhdWx0LGFuIGFzIGZpbmRET01Ob2RlLGhuIGFzIGZsdXNoU3luYyxrIGFzIGZvcndhcmRSZWYscSBhcyBoeWRyYXRlLGxuIGFzIGlzVmFsaWRFbGVtZW50LE0gYXMgbGF6eSxSIGFzIG1lbW8sWSBhcyByZW5kZXIsZG4gYXMgc3RhcnRUcmFuc2l0aW9uLGZuIGFzIHVubW91bnRDb21wb25lbnRBdE5vZGUsc24gYXMgdW5zdGFibGVfYmF0Y2hlZFVwZGF0ZXMscG4gYXMgdXNlRGVmZXJyZWRWYWx1ZSx5biBhcyB1c2VJbnNlcnRpb25FZmZlY3QsX24gYXMgdXNlU3luY0V4dGVybmFsU3RvcmUsbW4gYXMgdXNlVHJhbnNpdGlvbix1biBhcyB2ZXJzaW9ufTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNvbXBhdC5tb2R1bGUuanMubWFwXG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/preact/compat/dist/compat.module.js\n"); /***/ }), /***/ "./node_modules/preact/dist/preact.module.js": /*!***************************************************!*\ !*** ./node_modules/preact/dist/preact.module.js ***! \***************************************************/ /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"Component\": function() { return /* binding */ d; },\n/* harmony export */ \"Fragment\": function() { return /* binding */ p; },\n/* harmony export */ \"cloneElement\": function() { return /* binding */ q; },\n/* harmony export */ \"createContext\": function() { return /* binding */ B; },\n/* harmony export */ \"createElement\": function() { return /* binding */ h; },\n/* harmony export */ \"createRef\": function() { return /* binding */ y; },\n/* harmony export */ \"h\": function() { return /* binding */ h; },\n/* harmony export */ \"hydrate\": function() { return /* binding */ S; },\n/* harmony export */ \"isValidElement\": function() { return /* binding */ i; },\n/* harmony export */ \"options\": function() { return /* binding */ l; },\n/* harmony export */ \"render\": function() { return /* binding */ P; },\n/* harmony export */ \"toChildArray\": function() { return /* binding */ x; }\n/* harmony export */ });\nvar n,l,u,i,t,o,r,f={},e=[],c=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;function s(n,l){for(var u in l)n[u]=l[u];return n}function a(n){var l=n.parentNode;l&&l.removeChild(n)}function h(l,u,i){var t,o,r,f={};for(r in u)\"key\"==r?t=u[r]:\"ref\"==r?o=u[r]:f[r]=u[r];if(arguments.length>2&&(f.children=arguments.length>3?n.call(arguments,2):i),\"function\"==typeof l&&null!=l.defaultProps)for(r in l.defaultProps)void 0===f[r]&&(f[r]=l.defaultProps[r]);return v(l,f,t,o,null)}function v(n,i,t,o,r){var f={type:n,props:i,key:t,ref:o,__k:null,__:null,__b:0,__e:null,__d:void 0,__c:null,__h:null,constructor:void 0,__v:null==r?++u:r};return null==r&&null!=l.vnode&&l.vnode(f),f}function y(){return{current:null}}function p(n){return n.children}function d(n,l){this.props=n,this.context=l}function _(n,l){if(null==l)return n.__?_(n.__,n.__.__k.indexOf(n)+1):null;for(var u;l0?v(k.type,k.props,k.key,k.ref?k.ref:null,k.__v):k)){if(k.__=u,k.__b=u.__b+1,null===(d=x[h])||d&&k.key==d.key&&k.type===d.type)x[h]=void 0;else for(y=0;y2&&(f.children=arguments.length>3?n.call(arguments,2):i),v(l.type,f,t||l.key,o||l.ref,null)}function B(n,l){var u={__c:l=\"__cC\"+r++,__:n,Consumer:function(n,l){return n.children(l)},Provider:function(n){var u,i;return this.getChildContext||(u=[],(i={})[l]=this,this.getChildContext=function(){return i},this.shouldComponentUpdate=function(n){this.props.value!==n.value&&u.some(b)},this.sub=function(n){u.push(n);var l=n.componentWillUnmount;n.componentWillUnmount=function(){u.splice(u.indexOf(n),1),l&&l.call(n)}}),n.children}};return u.Provider.__=u.Consumer.contextType=u}n=e.slice,l={__e:function(n,l,u,i){for(var t,o,r;l=l.__;)if((t=l.__c)&&!t.__)try{if((o=t.constructor)&&null!=o.getDerivedStateFromError&&(t.setState(o.getDerivedStateFromError(n)),r=t.__d),null!=t.componentDidCatch&&(t.componentDidCatch(n,i||{}),r=t.__d),r)return t.__E=t}catch(l){n=l}throw n}},u=0,i=function(n){return null!=n&&void 0===n.constructor},d.prototype.setState=function(n,l){var u;u=null!=this.__s&&this.__s!==this.state?this.__s:this.__s=s({},this.state),\"function\"==typeof n&&(n=n(s({},u),this.props)),n&&s(u,n),null!=n&&this.__v&&(l&&this._sb.push(l),b(this))},d.prototype.forceUpdate=function(n){this.__v&&(this.__e=!0,n&&this.__h.push(n),b(this))},d.prototype.render=p,t=[],g.__r=0,r=0;\n//# sourceMappingURL=preact.module.js.map\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvcHJlYWN0L2Rpc3QvcHJlYWN0Lm1vZHVsZS5qcy5qcyIsIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7QUFBQSxzQkFBc0IsNEVBQTRFLGdCQUFnQix5QkFBeUIsU0FBUyxjQUFjLG1CQUFtQixvQkFBb0Isa0JBQWtCLGVBQWUscURBQXFELHdMQUF3TCx1QkFBdUIsc0JBQXNCLE9BQU8sOEhBQThILDRDQUE0QyxhQUFhLE9BQU8sY0FBYyxjQUFjLGtCQUFrQixnQkFBZ0IsNEJBQTRCLGdCQUFnQiwwREFBMEQsVUFBVSxlQUFlLG9EQUFvRCwwQ0FBMEMsY0FBYyxRQUFRLGdDQUFnQyw4QkFBOEIsZUFBZSx3Q0FBd0MsdUJBQXVCLE1BQU0sYUFBYSxjQUFjLDZHQUE2RyxhQUFhLFVBQVUsZUFBZSx3QkFBd0IsMkJBQTJCLDBCQUEwQixnQkFBZ0Isb0RBQW9ELCtIQUErSCxFQUFFLGdDQUFnQywyQ0FBMkMsaUJBQWlCLFdBQVcseUtBQXlLLFdBQVcsNEVBQTRFLHNGQUFzRixhQUFhLElBQUksS0FBSyw0Q0FBNEMsWUFBWSxNQUFNLE9BQU8sb1NBQW9TLGdCQUFnQixJQUFJLDBCQUEwQixhQUFhLFdBQVcsMEJBQTBCLGtCQUFrQixzQkFBc0IsY0FBYywrRUFBK0UsU0FBUyxnQkFBZ0Isa0ZBQWtGLE9BQU8sZUFBZSx3QkFBd0IsVUFBVSx1Q0FBdUMsaUdBQWlHLEtBQUssWUFBWSw4QkFBOEIscUJBQXFCLHdCQUF3QixrQ0FBa0Msc0JBQXNCLE1BQU0saUVBQWlFLDhIQUE4SCxrQkFBa0IscUZBQXFGLHNCQUFzQixNQUFNLHlEQUF5RCxLQUFLLHNGQUFzRixrREFBa0Qsd0lBQXdJLGlGQUFpRix1Q0FBdUMsMERBQTBELHVGQUF1RixrQkFBa0IsUUFBUSxVQUFVLHNHQUFzRyxjQUFjLHdDQUF3QyxjQUFjLHdDQUF3Qyw4QkFBOEIsMkNBQTJDLHNDQUFzQyxzRUFBc0UsSUFBSSwyQkFBMkIseVBBQXlQLCtJQUErSSw2TkFBNk4sS0FBSywrTUFBK00sZ0hBQWdILFlBQVksTUFBTSxlQUFlLHlCQUF5QixpQ0FBaUMsUUFBUSxnSEFBZ0gsNEJBQTRCLEVBQUUsMEZBQTBGLDZFQUE2RSxlQUFlLHlCQUF5QixTQUFTLFFBQVEscUVBQXFFLHFCQUFxQixnREFBZ0QsaVJBQWlSLG1GQUFtRixtQkFBbUIsU0FBUyxnRkFBZ0YsZ0JBQWdCLHFDQUFxQyxJQUFJLG9DQUFvQyxVQUFVLEVBQUUsU0FBUyxnQkFBZ0IsRUFBRSw0QkFBNEIsMkNBQTJDLGtDQUFrQyxXQUFXLDhFQUE4RSxjQUFjLE1BQU0sWUFBWSw4Q0FBOEMsMkdBQTJHLDZDQUE2QyxLQUFLLHNHQUFzRyxtQkFBbUIsS0FBSyxzQkFBc0Isa0RBQWtELDRGQUE0RiwyQkFBMkIsc0lBQXNJLElBQUkscUJBQXFCLG9OQUFvTixTQUFTLGtCQUFrQixJQUFJLHNDQUFzQyxTQUFTLFlBQVksa0JBQWtCLFFBQVEsbUdBQW1HLDhCQUE4Qix5QkFBeUIsU0FBUyxXQUFXLCtCQUErQixtQkFBbUIsV0FBVyxpREFBaUQsaURBQWlELGtCQUFrQiw2QkFBNkIsa0JBQWtCLFVBQVUsMk9BQTJPLGdCQUFnQixTQUFTLGtCQUFrQixnQkFBZ0IsVUFBVSxxREFBcUQsb0hBQW9ILGdCQUFnQixPQUFPLDZDQUE2QyxxQkFBcUIsc0JBQXNCLFFBQVEsd0NBQXdDLDBDQUEwQyxTQUFTLHdDQUF3QyxzQ0FBc0Msc0JBQXNCLFVBQVUsNkJBQTZCLGtDQUFrQyx1Q0FBdUMsZUFBZSw4Q0FBOEMsYUFBYSxzQkFBc0IsY0FBYyxPQUFPLHlCQUF5QixtS0FBbUssNEJBQTRCLFNBQVMsSUFBSSxTQUFTLG1CQUFtQix1Q0FBdUMsb0NBQW9DLE1BQU0sOERBQThELDRDQUE0Qyw0RUFBNEUscUNBQXFDLG9EQUFvRCx1Q0FBaU87QUFDNTRUIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vVnVleHkvLi9ub2RlX21vZHVsZXMvcHJlYWN0L2Rpc3QvcHJlYWN0Lm1vZHVsZS5qcz9kYTY1Il0sInNvdXJjZXNDb250ZW50IjpbInZhciBuLGwsdSxpLHQsbyxyLGY9e30sZT1bXSxjPS9hY2l0fGV4KD86c3xnfG58cHwkKXxycGh8Z3JpZHxvd3N8bW5jfG50d3xpbmVbY2hdfHpvb3xeb3JkfGl0ZXJhL2k7ZnVuY3Rpb24gcyhuLGwpe2Zvcih2YXIgdSBpbiBsKW5bdV09bFt1XTtyZXR1cm4gbn1mdW5jdGlvbiBhKG4pe3ZhciBsPW4ucGFyZW50Tm9kZTtsJiZsLnJlbW92ZUNoaWxkKG4pfWZ1bmN0aW9uIGgobCx1LGkpe3ZhciB0LG8scixmPXt9O2ZvcihyIGluIHUpXCJrZXlcIj09cj90PXVbcl06XCJyZWZcIj09cj9vPXVbcl06ZltyXT11W3JdO2lmKGFyZ3VtZW50cy5sZW5ndGg+MiYmKGYuY2hpbGRyZW49YXJndW1lbnRzLmxlbmd0aD4zP24uY2FsbChhcmd1bWVudHMsMik6aSksXCJmdW5jdGlvblwiPT10eXBlb2YgbCYmbnVsbCE9bC5kZWZhdWx0UHJvcHMpZm9yKHIgaW4gbC5kZWZhdWx0UHJvcHMpdm9pZCAwPT09ZltyXSYmKGZbcl09bC5kZWZhdWx0UHJvcHNbcl0pO3JldHVybiB2KGwsZix0LG8sbnVsbCl9ZnVuY3Rpb24gdihuLGksdCxvLHIpe3ZhciBmPXt0eXBlOm4scHJvcHM6aSxrZXk6dCxyZWY6byxfX2s6bnVsbCxfXzpudWxsLF9fYjowLF9fZTpudWxsLF9fZDp2b2lkIDAsX19jOm51bGwsX19oOm51bGwsY29uc3RydWN0b3I6dm9pZCAwLF9fdjpudWxsPT1yPysrdTpyfTtyZXR1cm4gbnVsbD09ciYmbnVsbCE9bC52bm9kZSYmbC52bm9kZShmKSxmfWZ1bmN0aW9uIHkoKXtyZXR1cm57Y3VycmVudDpudWxsfX1mdW5jdGlvbiBwKG4pe3JldHVybiBuLmNoaWxkcmVufWZ1bmN0aW9uIGQobixsKXt0aGlzLnByb3BzPW4sdGhpcy5jb250ZXh0PWx9ZnVuY3Rpb24gXyhuLGwpe2lmKG51bGw9PWwpcmV0dXJuIG4uX18/XyhuLl9fLG4uX18uX19rLmluZGV4T2YobikrMSk6bnVsbDtmb3IodmFyIHU7bDxuLl9fay5sZW5ndGg7bCsrKWlmKG51bGwhPSh1PW4uX19rW2xdKSYmbnVsbCE9dS5fX2UpcmV0dXJuIHUuX19lO3JldHVyblwiZnVuY3Rpb25cIj09dHlwZW9mIG4udHlwZT9fKG4pOm51bGx9ZnVuY3Rpb24gayhuKXt2YXIgbCx1O2lmKG51bGwhPShuPW4uX18pJiZudWxsIT1uLl9fYyl7Zm9yKG4uX19lPW4uX19jLmJhc2U9bnVsbCxsPTA7bDxuLl9fay5sZW5ndGg7bCsrKWlmKG51bGwhPSh1PW4uX19rW2xdKSYmbnVsbCE9dS5fX2Upe24uX19lPW4uX19jLmJhc2U9dS5fX2U7YnJlYWt9cmV0dXJuIGsobil9fWZ1bmN0aW9uIGIobil7KCFuLl9fZCYmKG4uX19kPSEwKSYmdC5wdXNoKG4pJiYhZy5fX3IrK3x8byE9PWwuZGVib3VuY2VSZW5kZXJpbmcpJiYoKG89bC5kZWJvdW5jZVJlbmRlcmluZyl8fHNldFRpbWVvdXQpKGcpfWZ1bmN0aW9uIGcoKXtmb3IodmFyIG47Zy5fX3I9dC5sZW5ndGg7KW49dC5zb3J0KGZ1bmN0aW9uKG4sbCl7cmV0dXJuIG4uX192Ll9fYi1sLl9fdi5fX2J9KSx0PVtdLG4uc29tZShmdW5jdGlvbihuKXt2YXIgbCx1LGksdCxvLHI7bi5fX2QmJihvPSh0PShsPW4pLl9fdikuX19lLChyPWwuX19QKSYmKHU9W10sKGk9cyh7fSx0KSkuX192PXQuX192KzEsaihyLHQsaSxsLl9fbix2b2lkIDAhPT1yLm93bmVyU1ZHRWxlbWVudCxudWxsIT10Ll9faD9bb106bnVsbCx1LG51bGw9PW8/Xyh0KTpvLHQuX19oKSx6KHUsdCksdC5fX2UhPW8mJmsodCkpKX0pfWZ1bmN0aW9uIHcobixsLHUsaSx0LG8scixjLHMsYSl7dmFyIGgseSxkLGssYixnLHcseD1pJiZpLl9fa3x8ZSxDPXgubGVuZ3RoO2Zvcih1Ll9faz1bXSxoPTA7aDxsLmxlbmd0aDtoKyspaWYobnVsbCE9KGs9dS5fX2tbaF09bnVsbD09KGs9bFtoXSl8fFwiYm9vbGVhblwiPT10eXBlb2Ygaz9udWxsOlwic3RyaW5nXCI9PXR5cGVvZiBrfHxcIm51bWJlclwiPT10eXBlb2Yga3x8XCJiaWdpbnRcIj09dHlwZW9mIGs/dihudWxsLGssbnVsbCxudWxsLGspOkFycmF5LmlzQXJyYXkoayk/dihwLHtjaGlsZHJlbjprfSxudWxsLG51bGwsbnVsbCk6ay5fX2I+MD92KGsudHlwZSxrLnByb3BzLGsua2V5LGsucmVmP2sucmVmOm51bGwsay5fX3YpOmspKXtpZihrLl9fPXUsay5fX2I9dS5fX2IrMSxudWxsPT09KGQ9eFtoXSl8fGQmJmsua2V5PT1kLmtleSYmay50eXBlPT09ZC50eXBlKXhbaF09dm9pZCAwO2Vsc2UgZm9yKHk9MDt5PEM7eSsrKXtpZigoZD14W3ldKSYmay5rZXk9PWQua2V5JiZrLnR5cGU9PT1kLnR5cGUpe3hbeV09dm9pZCAwO2JyZWFrfWQ9bnVsbH1qKG4sayxkPWR8fGYsdCxvLHIsYyxzLGEpLGI9ay5fX2UsKHk9ay5yZWYpJiZkLnJlZiE9eSYmKHd8fCh3PVtdKSxkLnJlZiYmdy5wdXNoKGQucmVmLG51bGwsayksdy5wdXNoKHksay5fX2N8fGIsaykpLG51bGwhPWI/KG51bGw9PWcmJihnPWIpLFwiZnVuY3Rpb25cIj09dHlwZW9mIGsudHlwZSYmay5fX2s9PT1kLl9faz9rLl9fZD1zPW0oayxzLG4pOnM9QShuLGssZCx4LGIscyksXCJmdW5jdGlvblwiPT10eXBlb2YgdS50eXBlJiYodS5fX2Q9cykpOnMmJmQuX19lPT1zJiZzLnBhcmVudE5vZGUhPW4mJihzPV8oZCkpfWZvcih1Ll9fZT1nLGg9QztoLS07KW51bGwhPXhbaF0mJk4oeFtoXSx4W2hdKTtpZih3KWZvcihoPTA7aDx3Lmxlbmd0aDtoKyspTSh3W2hdLHdbKytoXSx3WysraF0pfWZ1bmN0aW9uIG0obixsLHUpe2Zvcih2YXIgaSx0PW4uX19rLG89MDt0JiZvPHQubGVuZ3RoO28rKykoaT10W29dKSYmKGkuX189bixsPVwiZnVuY3Rpb25cIj09dHlwZW9mIGkudHlwZT9tKGksbCx1KTpBKHUsaSxpLHQsaS5fX2UsbCkpO3JldHVybiBsfWZ1bmN0aW9uIHgobixsKXtyZXR1cm4gbD1sfHxbXSxudWxsPT1ufHxcImJvb2xlYW5cIj09dHlwZW9mIG58fChBcnJheS5pc0FycmF5KG4pP24uc29tZShmdW5jdGlvbihuKXt4KG4sbCl9KTpsLnB1c2gobikpLGx9ZnVuY3Rpb24gQShuLGwsdSxpLHQsbyl7dmFyIHIsZixlO2lmKHZvaWQgMCE9PWwuX19kKXI9bC5fX2QsbC5fX2Q9dm9pZCAwO2Vsc2UgaWYobnVsbD09dXx8dCE9b3x8bnVsbD09dC5wYXJlbnROb2RlKW46aWYobnVsbD09b3x8by5wYXJlbnROb2RlIT09biluLmFwcGVuZENoaWxkKHQpLHI9bnVsbDtlbHNle2ZvcihmPW8sZT0wOyhmPWYubmV4dFNpYmxpbmcpJiZlPGkubGVuZ3RoO2UrPTEpaWYoZj09dClicmVhayBuO24uaW5zZXJ0QmVmb3JlKHQsbykscj1vfXJldHVybiB2b2lkIDAhPT1yP3I6dC5uZXh0U2libGluZ31mdW5jdGlvbiBDKG4sbCx1LGksdCl7dmFyIG87Zm9yKG8gaW4gdSlcImNoaWxkcmVuXCI9PT1vfHxcImtleVwiPT09b3x8byBpbiBsfHxIKG4sbyxudWxsLHVbb10saSk7Zm9yKG8gaW4gbCl0JiZcImZ1bmN0aW9uXCIhPXR5cGVvZiBsW29dfHxcImNoaWxkcmVuXCI9PT1vfHxcImtleVwiPT09b3x8XCJ2YWx1ZVwiPT09b3x8XCJjaGVja2VkXCI9PT1vfHx1W29dPT09bFtvXXx8SChuLG8sbFtvXSx1W29dLGkpfWZ1bmN0aW9uICQobixsLHUpe1wiLVwiPT09bFswXT9uLnNldFByb3BlcnR5KGwsdSk6bltsXT1udWxsPT11P1wiXCI6XCJudW1iZXJcIiE9dHlwZW9mIHV8fGMudGVzdChsKT91OnUrXCJweFwifWZ1bmN0aW9uIEgobixsLHUsaSx0KXt2YXIgbztuOmlmKFwic3R5bGVcIj09PWwpaWYoXCJzdHJpbmdcIj09dHlwZW9mIHUpbi5zdHlsZS5jc3NUZXh0PXU7ZWxzZXtpZihcInN0cmluZ1wiPT10eXBlb2YgaSYmKG4uc3R5bGUuY3NzVGV4dD1pPVwiXCIpLGkpZm9yKGwgaW4gaSl1JiZsIGluIHV8fCQobi5zdHlsZSxsLFwiXCIpO2lmKHUpZm9yKGwgaW4gdSlpJiZ1W2xdPT09aVtsXXx8JChuLnN0eWxlLGwsdVtsXSl9ZWxzZSBpZihcIm9cIj09PWxbMF0mJlwiblwiPT09bFsxXSlvPWwhPT0obD1sLnJlcGxhY2UoL0NhcHR1cmUkLyxcIlwiKSksbD1sLnRvTG93ZXJDYXNlKClpbiBuP2wudG9Mb3dlckNhc2UoKS5zbGljZSgyKTpsLnNsaWNlKDIpLG4ubHx8KG4ubD17fSksbi5sW2wrb109dSx1P2l8fG4uYWRkRXZlbnRMaXN0ZW5lcihsLG8/VDpJLG8pOm4ucmVtb3ZlRXZlbnRMaXN0ZW5lcihsLG8/VDpJLG8pO2Vsc2UgaWYoXCJkYW5nZXJvdXNseVNldElubmVySFRNTFwiIT09bCl7aWYodClsPWwucmVwbGFjZSgveGxpbmsoSHw6aCkvLFwiaFwiKS5yZXBsYWNlKC9zTmFtZSQvLFwic1wiKTtlbHNlIGlmKFwiaHJlZlwiIT09bCYmXCJsaXN0XCIhPT1sJiZcImZvcm1cIiE9PWwmJlwidGFiSW5kZXhcIiE9PWwmJlwiZG93bmxvYWRcIiE9PWwmJmwgaW4gbil0cnl7bltsXT1udWxsPT11P1wiXCI6dTticmVhayBufWNhdGNoKG4pe31cImZ1bmN0aW9uXCI9PXR5cGVvZiB1fHwobnVsbD09dXx8ITE9PT11JiYtMT09bC5pbmRleE9mKFwiLVwiKT9uLnJlbW92ZUF0dHJpYnV0ZShsKTpuLnNldEF0dHJpYnV0ZShsLHUpKX19ZnVuY3Rpb24gSShuKXt0aGlzLmxbbi50eXBlKyExXShsLmV2ZW50P2wuZXZlbnQobik6bil9ZnVuY3Rpb24gVChuKXt0aGlzLmxbbi50eXBlKyEwXShsLmV2ZW50P2wuZXZlbnQobik6bil9ZnVuY3Rpb24gaihuLHUsaSx0LG8scixmLGUsYyl7dmFyIGEsaCx2LHksXyxrLGIsZyxtLHgsQSxDLCQsSCxJLFQ9dS50eXBlO2lmKHZvaWQgMCE9PXUuY29uc3RydWN0b3IpcmV0dXJuIG51bGw7bnVsbCE9aS5fX2gmJihjPWkuX19oLGU9dS5fX2U9aS5fX2UsdS5fX2g9bnVsbCxyPVtlXSksKGE9bC5fX2IpJiZhKHUpO3RyeXtuOmlmKFwiZnVuY3Rpb25cIj09dHlwZW9mIFQpe2lmKGc9dS5wcm9wcyxtPShhPVQuY29udGV4dFR5cGUpJiZ0W2EuX19jXSx4PWE/bT9tLnByb3BzLnZhbHVlOmEuX186dCxpLl9fYz9iPShoPXUuX19jPWkuX19jKS5fXz1oLl9fRTooXCJwcm90b3R5cGVcImluIFQmJlQucHJvdG90eXBlLnJlbmRlcj91Ll9fYz1oPW5ldyBUKGcseCk6KHUuX19jPWg9bmV3IGQoZyx4KSxoLmNvbnN0cnVjdG9yPVQsaC5yZW5kZXI9TyksbSYmbS5zdWIoaCksaC5wcm9wcz1nLGguc3RhdGV8fChoLnN0YXRlPXt9KSxoLmNvbnRleHQ9eCxoLl9fbj10LHY9aC5fX2Q9ITAsaC5fX2g9W10saC5fc2I9W10pLG51bGw9PWguX19zJiYoaC5fX3M9aC5zdGF0ZSksbnVsbCE9VC5nZXREZXJpdmVkU3RhdGVGcm9tUHJvcHMmJihoLl9fcz09aC5zdGF0ZSYmKGguX19zPXMoe30saC5fX3MpKSxzKGguX19zLFQuZ2V0RGVyaXZlZFN0YXRlRnJvbVByb3BzKGcsaC5fX3MpKSkseT1oLnByb3BzLF89aC5zdGF0ZSx2KW51bGw9PVQuZ2V0RGVyaXZlZFN0YXRlRnJvbVByb3BzJiZudWxsIT1oLmNvbXBvbmVudFdpbGxNb3VudCYmaC5jb21wb25lbnRXaWxsTW91bnQoKSxudWxsIT1oLmNvbXBvbmVudERpZE1vdW50JiZoLl9faC5wdXNoKGguY29tcG9uZW50RGlkTW91bnQpO2Vsc2V7aWYobnVsbD09VC5nZXREZXJpdmVkU3RhdGVGcm9tUHJvcHMmJmchPT15JiZudWxsIT1oLmNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMmJmguY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyhnLHgpLCFoLl9fZSYmbnVsbCE9aC5zaG91bGRDb21wb25lbnRVcGRhdGUmJiExPT09aC5zaG91bGRDb21wb25lbnRVcGRhdGUoZyxoLl9fcyx4KXx8dS5fX3Y9PT1pLl9fdil7Zm9yKGgucHJvcHM9ZyxoLnN0YXRlPWguX19zLHUuX192IT09aS5fX3YmJihoLl9fZD0hMSksaC5fX3Y9dSx1Ll9fZT1pLl9fZSx1Ll9faz1pLl9fayx1Ll9fay5mb3JFYWNoKGZ1bmN0aW9uKG4pe24mJihuLl9fPXUpfSksQT0wO0E8aC5fc2IubGVuZ3RoO0ErKyloLl9faC5wdXNoKGguX3NiW0FdKTtoLl9zYj1bXSxoLl9faC5sZW5ndGgmJmYucHVzaChoKTticmVhayBufW51bGwhPWguY29tcG9uZW50V2lsbFVwZGF0ZSYmaC5jb21wb25lbnRXaWxsVXBkYXRlKGcsaC5fX3MseCksbnVsbCE9aC5jb21wb25lbnREaWRVcGRhdGUmJmguX19oLnB1c2goZnVuY3Rpb24oKXtoLmNvbXBvbmVudERpZFVwZGF0ZSh5LF8sayl9KX1pZihoLmNvbnRleHQ9eCxoLnByb3BzPWcsaC5fX3Y9dSxoLl9fUD1uLEM9bC5fX3IsJD0wLFwicHJvdG90eXBlXCJpbiBUJiZULnByb3RvdHlwZS5yZW5kZXIpe2ZvcihoLnN0YXRlPWguX19zLGguX19kPSExLEMmJkModSksYT1oLnJlbmRlcihoLnByb3BzLGguc3RhdGUsaC5jb250ZXh0KSxIPTA7SDxoLl9zYi5sZW5ndGg7SCsrKWguX19oLnB1c2goaC5fc2JbSF0pO2guX3NiPVtdfWVsc2UgZG97aC5fX2Q9ITEsQyYmQyh1KSxhPWgucmVuZGVyKGgucHJvcHMsaC5zdGF0ZSxoLmNvbnRleHQpLGguc3RhdGU9aC5fX3N9d2hpbGUoaC5fX2QmJisrJDwyNSk7aC5zdGF0ZT1oLl9fcyxudWxsIT1oLmdldENoaWxkQ29udGV4dCYmKHQ9cyhzKHt9LHQpLGguZ2V0Q2hpbGRDb250ZXh0KCkpKSx2fHxudWxsPT1oLmdldFNuYXBzaG90QmVmb3JlVXBkYXRlfHwoaz1oLmdldFNuYXBzaG90QmVmb3JlVXBkYXRlKHksXykpLEk9bnVsbCE9YSYmYS50eXBlPT09cCYmbnVsbD09YS5rZXk/YS5wcm9wcy5jaGlsZHJlbjphLHcobixBcnJheS5pc0FycmF5KEkpP0k6W0ldLHUsaSx0LG8scixmLGUsYyksaC5iYXNlPXUuX19lLHUuX19oPW51bGwsaC5fX2gubGVuZ3RoJiZmLnB1c2goaCksYiYmKGguX19FPWguX189bnVsbCksaC5fX2U9ITF9ZWxzZSBudWxsPT1yJiZ1Ll9fdj09PWkuX192Pyh1Ll9faz1pLl9fayx1Ll9fZT1pLl9fZSk6dS5fX2U9TChpLl9fZSx1LGksdCxvLHIsZixjKTsoYT1sLmRpZmZlZCkmJmEodSl9Y2F0Y2gobil7dS5fX3Y9bnVsbCwoY3x8bnVsbCE9cikmJih1Ll9fZT1lLHUuX19oPSEhYyxyW3IuaW5kZXhPZihlKV09bnVsbCksbC5fX2Uobix1LGkpfX1mdW5jdGlvbiB6KG4sdSl7bC5fX2MmJmwuX19jKHUsbiksbi5zb21lKGZ1bmN0aW9uKHUpe3RyeXtuPXUuX19oLHUuX19oPVtdLG4uc29tZShmdW5jdGlvbihuKXtuLmNhbGwodSl9KX1jYXRjaChuKXtsLl9fZShuLHUuX192KX19KX1mdW5jdGlvbiBMKGwsdSxpLHQsbyxyLGUsYyl7dmFyIHMsaCx2LHk9aS5wcm9wcyxwPXUucHJvcHMsZD11LnR5cGUsaz0wO2lmKFwic3ZnXCI9PT1kJiYobz0hMCksbnVsbCE9cilmb3IoO2s8ci5sZW5ndGg7aysrKWlmKChzPXJba10pJiZcInNldEF0dHJpYnV0ZVwiaW4gcz09ISFkJiYoZD9zLmxvY2FsTmFtZT09PWQ6Mz09PXMubm9kZVR5cGUpKXtsPXMscltrXT1udWxsO2JyZWFrfWlmKG51bGw9PWwpe2lmKG51bGw9PT1kKXJldHVybiBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShwKTtsPW8/ZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKFwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIixkKTpkb2N1bWVudC5jcmVhdGVFbGVtZW50KGQscC5pcyYmcCkscj1udWxsLGM9ITF9aWYobnVsbD09PWQpeT09PXB8fGMmJmwuZGF0YT09PXB8fChsLmRhdGE9cCk7ZWxzZXtpZihyPXImJm4uY2FsbChsLmNoaWxkTm9kZXMpLGg9KHk9aS5wcm9wc3x8ZikuZGFuZ2Vyb3VzbHlTZXRJbm5lckhUTUwsdj1wLmRhbmdlcm91c2x5U2V0SW5uZXJIVE1MLCFjKXtpZihudWxsIT1yKWZvcih5PXt9LGs9MDtrPGwuYXR0cmlidXRlcy5sZW5ndGg7aysrKXlbbC5hdHRyaWJ1dGVzW2tdLm5hbWVdPWwuYXR0cmlidXRlc1trXS52YWx1ZTsodnx8aCkmJih2JiYoaCYmdi5fX2h0bWw9PWguX19odG1sfHx2Ll9faHRtbD09PWwuaW5uZXJIVE1MKXx8KGwuaW5uZXJIVE1MPXYmJnYuX19odG1sfHxcIlwiKSl9aWYoQyhsLHAseSxvLGMpLHYpdS5fX2s9W107ZWxzZSBpZihrPXUucHJvcHMuY2hpbGRyZW4sdyhsLEFycmF5LmlzQXJyYXkoayk/azpba10sdSxpLHQsbyYmXCJmb3JlaWduT2JqZWN0XCIhPT1kLHIsZSxyP3JbMF06aS5fX2smJl8oaSwwKSxjKSxudWxsIT1yKWZvcihrPXIubGVuZ3RoO2stLTspbnVsbCE9cltrXSYmYShyW2tdKTtjfHwoXCJ2YWx1ZVwiaW4gcCYmdm9pZCAwIT09KGs9cC52YWx1ZSkmJihrIT09bC52YWx1ZXx8XCJwcm9ncmVzc1wiPT09ZCYmIWt8fFwib3B0aW9uXCI9PT1kJiZrIT09eS52YWx1ZSkmJkgobCxcInZhbHVlXCIsayx5LnZhbHVlLCExKSxcImNoZWNrZWRcImluIHAmJnZvaWQgMCE9PShrPXAuY2hlY2tlZCkmJmshPT1sLmNoZWNrZWQmJkgobCxcImNoZWNrZWRcIixrLHkuY2hlY2tlZCwhMSkpfXJldHVybiBsfWZ1bmN0aW9uIE0obix1LGkpe3RyeXtcImZ1bmN0aW9uXCI9PXR5cGVvZiBuP24odSk6bi5jdXJyZW50PXV9Y2F0Y2gobil7bC5fX2UobixpKX19ZnVuY3Rpb24gTihuLHUsaSl7dmFyIHQsbztpZihsLnVubW91bnQmJmwudW5tb3VudChuKSwodD1uLnJlZikmJih0LmN1cnJlbnQmJnQuY3VycmVudCE9PW4uX19lfHxNKHQsbnVsbCx1KSksbnVsbCE9KHQ9bi5fX2MpKXtpZih0LmNvbXBvbmVudFdpbGxVbm1vdW50KXRyeXt0LmNvbXBvbmVudFdpbGxVbm1vdW50KCl9Y2F0Y2gobil7bC5fX2Uobix1KX10LmJhc2U9dC5fX1A9bnVsbCxuLl9fYz12b2lkIDB9aWYodD1uLl9faylmb3Iobz0wO288dC5sZW5ndGg7bysrKXRbb10mJk4odFtvXSx1LGl8fFwiZnVuY3Rpb25cIiE9dHlwZW9mIG4udHlwZSk7aXx8bnVsbD09bi5fX2V8fGEobi5fX2UpLG4uX189bi5fX2U9bi5fX2Q9dm9pZCAwfWZ1bmN0aW9uIE8obixsLHUpe3JldHVybiB0aGlzLmNvbnN0cnVjdG9yKG4sdSl9ZnVuY3Rpb24gUCh1LGksdCl7dmFyIG8scixlO2wuX18mJmwuX18odSxpKSxyPShvPVwiZnVuY3Rpb25cIj09dHlwZW9mIHQpP251bGw6dCYmdC5fX2t8fGkuX19rLGU9W10saihpLHU9KCFvJiZ0fHxpKS5fX2s9aChwLG51bGwsW3VdKSxyfHxmLGYsdm9pZCAwIT09aS5vd25lclNWR0VsZW1lbnQsIW8mJnQ/W3RdOnI/bnVsbDppLmZpcnN0Q2hpbGQ/bi5jYWxsKGkuY2hpbGROb2Rlcyk6bnVsbCxlLCFvJiZ0P3Q6cj9yLl9fZTppLmZpcnN0Q2hpbGQsbykseihlLHUpfWZ1bmN0aW9uIFMobixsKXtQKG4sbCxTKX1mdW5jdGlvbiBxKGwsdSxpKXt2YXIgdCxvLHIsZj1zKHt9LGwucHJvcHMpO2ZvcihyIGluIHUpXCJrZXlcIj09cj90PXVbcl06XCJyZWZcIj09cj9vPXVbcl06ZltyXT11W3JdO3JldHVybiBhcmd1bWVudHMubGVuZ3RoPjImJihmLmNoaWxkcmVuPWFyZ3VtZW50cy5sZW5ndGg+Mz9uLmNhbGwoYXJndW1lbnRzLDIpOmkpLHYobC50eXBlLGYsdHx8bC5rZXksb3x8bC5yZWYsbnVsbCl9ZnVuY3Rpb24gQihuLGwpe3ZhciB1PXtfX2M6bD1cIl9fY0NcIityKyssX186bixDb25zdW1lcjpmdW5jdGlvbihuLGwpe3JldHVybiBuLmNoaWxkcmVuKGwpfSxQcm92aWRlcjpmdW5jdGlvbihuKXt2YXIgdSxpO3JldHVybiB0aGlzLmdldENoaWxkQ29udGV4dHx8KHU9W10sKGk9e30pW2xdPXRoaXMsdGhpcy5nZXRDaGlsZENvbnRleHQ9ZnVuY3Rpb24oKXtyZXR1cm4gaX0sdGhpcy5zaG91bGRDb21wb25lbnRVcGRhdGU9ZnVuY3Rpb24obil7dGhpcy5wcm9wcy52YWx1ZSE9PW4udmFsdWUmJnUuc29tZShiKX0sdGhpcy5zdWI9ZnVuY3Rpb24obil7dS5wdXNoKG4pO3ZhciBsPW4uY29tcG9uZW50V2lsbFVubW91bnQ7bi5jb21wb25lbnRXaWxsVW5tb3VudD1mdW5jdGlvbigpe3Uuc3BsaWNlKHUuaW5kZXhPZihuKSwxKSxsJiZsLmNhbGwobil9fSksbi5jaGlsZHJlbn19O3JldHVybiB1LlByb3ZpZGVyLl9fPXUuQ29uc3VtZXIuY29udGV4dFR5cGU9dX1uPWUuc2xpY2UsbD17X19lOmZ1bmN0aW9uKG4sbCx1LGkpe2Zvcih2YXIgdCxvLHI7bD1sLl9fOylpZigodD1sLl9fYykmJiF0Ll9fKXRyeXtpZigobz10LmNvbnN0cnVjdG9yKSYmbnVsbCE9by5nZXREZXJpdmVkU3RhdGVGcm9tRXJyb3ImJih0LnNldFN0YXRlKG8uZ2V0RGVyaXZlZFN0YXRlRnJvbUVycm9yKG4pKSxyPXQuX19kKSxudWxsIT10LmNvbXBvbmVudERpZENhdGNoJiYodC5jb21wb25lbnREaWRDYXRjaChuLGl8fHt9KSxyPXQuX19kKSxyKXJldHVybiB0Ll9fRT10fWNhdGNoKGwpe249bH10aHJvdyBufX0sdT0wLGk9ZnVuY3Rpb24obil7cmV0dXJuIG51bGwhPW4mJnZvaWQgMD09PW4uY29uc3RydWN0b3J9LGQucHJvdG90eXBlLnNldFN0YXRlPWZ1bmN0aW9uKG4sbCl7dmFyIHU7dT1udWxsIT10aGlzLl9fcyYmdGhpcy5fX3MhPT10aGlzLnN0YXRlP3RoaXMuX19zOnRoaXMuX19zPXMoe30sdGhpcy5zdGF0ZSksXCJmdW5jdGlvblwiPT10eXBlb2YgbiYmKG49bihzKHt9LHUpLHRoaXMucHJvcHMpKSxuJiZzKHUsbiksbnVsbCE9biYmdGhpcy5fX3YmJihsJiZ0aGlzLl9zYi5wdXNoKGwpLGIodGhpcykpfSxkLnByb3RvdHlwZS5mb3JjZVVwZGF0ZT1mdW5jdGlvbihuKXt0aGlzLl9fdiYmKHRoaXMuX19lPSEwLG4mJnRoaXMuX19oLnB1c2gobiksYih0aGlzKSl9LGQucHJvdG90eXBlLnJlbmRlcj1wLHQ9W10sZy5fX3I9MCxyPTA7ZXhwb3J0e2QgYXMgQ29tcG9uZW50LHAgYXMgRnJhZ21lbnQscSBhcyBjbG9uZUVsZW1lbnQsQiBhcyBjcmVhdGVDb250ZXh0LGggYXMgY3JlYXRlRWxlbWVudCx5IGFzIGNyZWF0ZVJlZixoLFMgYXMgaHlkcmF0ZSxpIGFzIGlzVmFsaWRFbGVtZW50LGwgYXMgb3B0aW9ucyxQIGFzIHJlbmRlcix4IGFzIHRvQ2hpbGRBcnJheX07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1wcmVhY3QubW9kdWxlLmpzLm1hcFxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/preact/dist/preact.module.js\n"); /***/ }), /***/ "./node_modules/preact/hooks/dist/hooks.module.js": /*!********************************************************!*\ !*** ./node_modules/preact/hooks/dist/hooks.module.js ***! \********************************************************/ /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"useCallback\": function() { return /* binding */ T; },\n/* harmony export */ \"useContext\": function() { return /* binding */ q; },\n/* harmony export */ \"useDebugValue\": function() { return /* binding */ x; },\n/* harmony export */ \"useEffect\": function() { return /* binding */ h; },\n/* harmony export */ \"useErrorBoundary\": function() { return /* binding */ P; },\n/* harmony export */ \"useId\": function() { return /* binding */ V; },\n/* harmony export */ \"useImperativeHandle\": function() { return /* binding */ A; },\n/* harmony export */ \"useLayoutEffect\": function() { return /* binding */ s; },\n/* harmony export */ \"useMemo\": function() { return /* binding */ F; },\n/* harmony export */ \"useReducer\": function() { return /* binding */ y; },\n/* harmony export */ \"useRef\": function() { return /* binding */ _; },\n/* harmony export */ \"useState\": function() { return /* binding */ p; }\n/* harmony export */ });\n/* harmony import */ var preact__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! preact */ \"./node_modules/preact/dist/preact.module.js\");\nvar t,r,u,i,o=0,f=[],c=[],e=preact__WEBPACK_IMPORTED_MODULE_0__.options.__b,a=preact__WEBPACK_IMPORTED_MODULE_0__.options.__r,v=preact__WEBPACK_IMPORTED_MODULE_0__.options.diffed,l=preact__WEBPACK_IMPORTED_MODULE_0__.options.__c,m=preact__WEBPACK_IMPORTED_MODULE_0__.options.unmount;function d(t,u){preact__WEBPACK_IMPORTED_MODULE_0__.options.__h&&preact__WEBPACK_IMPORTED_MODULE_0__.options.__h(r,t,o||u),o=0;var i=r.__H||(r.__H={__:[],__h:[]});return t>=i.__.length&&i.__.push({__V:c}),i.__[t]}function p(n){return o=1,y(B,n)}function y(n,u,i){var o=d(t++,2);if(o.t=n,!o.__c&&(o.__=[i?i(u):B(void 0,u),function(n){var t=o.__N?o.__N[0]:o.__[0],r=o.t(t,n);t!==r&&(o.__N=[r,o.__[1]],o.__c.setState({}))}],o.__c=r,!r.u)){r.u=!0;var f=r.shouldComponentUpdate;r.shouldComponentUpdate=function(n,t,r){if(!o.__c.__H)return!0;var u=o.__c.__H.__.filter(function(n){return n.__c});if(u.every(function(n){return!n.__N}))return!f||f.call(this,n,t,r);var i=!1;return u.forEach(function(n){if(n.__N){var t=n.__[0];n.__=n.__N,n.__N=void 0,t!==n.__[0]&&(i=!0)}}),!(!i&&o.__c.props===n)&&(!f||f.call(this,n,t,r))}}return o.__N||o.__}function h(u,i){var o=d(t++,3);!preact__WEBPACK_IMPORTED_MODULE_0__.options.__s&&z(o.__H,i)&&(o.__=u,o.i=i,r.__H.__h.push(o))}function s(u,i){var o=d(t++,4);!preact__WEBPACK_IMPORTED_MODULE_0__.options.__s&&z(o.__H,i)&&(o.__=u,o.i=i,r.__h.push(o))}function _(n){return o=5,F(function(){return{current:n}},[])}function A(n,t,r){o=6,s(function(){return\"function\"==typeof n?(n(t()),function(){return n(null)}):n?(n.current=t(),function(){return n.current=null}):void 0},null==r?r:r.concat(n))}function F(n,r){var u=d(t++,7);return z(u.__H,r)?(u.__V=n(),u.i=r,u.__h=n,u.__V):u.__}function T(n,t){return o=8,F(function(){return n},t)}function q(n){var u=r.context[n.__c],i=d(t++,9);return i.c=n,u?(null==i.__&&(i.__=!0,u.sub(r)),u.props.value):n.__}function x(t,r){preact__WEBPACK_IMPORTED_MODULE_0__.options.useDebugValue&&preact__WEBPACK_IMPORTED_MODULE_0__.options.useDebugValue(r?r(t):t)}function P(n){var u=d(t++,10),i=p();return u.__=n,r.componentDidCatch||(r.componentDidCatch=function(n,t){u.__&&u.__(n,t),i[1](n)}),[i[0],function(){i[1](void 0)}]}function V(){var n=d(t++,11);if(!n.__){for(var u=r.__v;null!==u&&!u.__m&&null!==u.__;)u=u.__;var i=u.__m||(u.__m=[0,0]);n.__=\"P\"+i[0]+\"-\"+i[1]++}return n.__}function b(){for(var t;t=f.shift();)if(t.__P&&t.__H)try{t.__H.__h.forEach(k),t.__H.__h.forEach(w),t.__H.__h=[]}catch(r){t.__H.__h=[],preact__WEBPACK_IMPORTED_MODULE_0__.options.__e(r,t.__v)}}preact__WEBPACK_IMPORTED_MODULE_0__.options.__b=function(n){r=null,e&&e(n)},preact__WEBPACK_IMPORTED_MODULE_0__.options.__r=function(n){a&&a(n),t=0;var i=(r=n.__c).__H;i&&(u===r?(i.__h=[],r.__h=[],i.__.forEach(function(n){n.__N&&(n.__=n.__N),n.__V=c,n.__N=n.i=void 0})):(i.__h.forEach(k),i.__h.forEach(w),i.__h=[])),u=r},preact__WEBPACK_IMPORTED_MODULE_0__.options.diffed=function(t){v&&v(t);var o=t.__c;o&&o.__H&&(o.__H.__h.length&&(1!==f.push(o)&&i===preact__WEBPACK_IMPORTED_MODULE_0__.options.requestAnimationFrame||((i=preact__WEBPACK_IMPORTED_MODULE_0__.options.requestAnimationFrame)||j)(b)),o.__H.__.forEach(function(n){n.i&&(n.__H=n.i),n.__V!==c&&(n.__=n.__V),n.i=void 0,n.__V=c})),u=r=null},preact__WEBPACK_IMPORTED_MODULE_0__.options.__c=function(t,r){r.some(function(t){try{t.__h.forEach(k),t.__h=t.__h.filter(function(n){return!n.__||w(n)})}catch(u){r.some(function(n){n.__h&&(n.__h=[])}),r=[],preact__WEBPACK_IMPORTED_MODULE_0__.options.__e(u,t.__v)}}),l&&l(t,r)},preact__WEBPACK_IMPORTED_MODULE_0__.options.unmount=function(t){m&&m(t);var r,u=t.__c;u&&u.__H&&(u.__H.__.forEach(function(n){try{k(n)}catch(n){r=n}}),u.__H=void 0,r&&preact__WEBPACK_IMPORTED_MODULE_0__.options.__e(r,u.__v))};var g=\"function\"==typeof requestAnimationFrame;function j(n){var t,r=function(){clearTimeout(u),g&&cancelAnimationFrame(t),setTimeout(n)},u=setTimeout(r,100);g&&(t=requestAnimationFrame(r))}function k(n){var t=r,u=n.__c;\"function\"==typeof u&&(n.__c=void 0,u()),r=t}function w(n){var t=r;n.__c=n.__(),r=t}function z(n,t){return!n||n.length!==t.length||t.some(function(t,r){return t!==n[r]})}function B(n,t){return\"function\"==typeof t?t(n):t}\n//# sourceMappingURL=hooks.module.js.map\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvcHJlYWN0L2hvb2tzL2Rpc3QvaG9va3MubW9kdWxlLmpzLmpzIiwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBaUMsNEJBQTRCLCtDQUFLLEdBQUcsK0NBQUssR0FBRyxrREFBUSxHQUFHLCtDQUFLLEdBQUcsbURBQVMsQ0FBQyxnQkFBZ0IsK0NBQUssRUFBRSwrQ0FBSyxlQUFlLHFCQUFxQixhQUFhLEVBQUUsa0NBQWtDLE1BQU0sVUFBVSxjQUFjLGtCQUFrQixrQkFBa0IsZUFBZSx1REFBdUQsd0NBQXdDLDJDQUEyQyxHQUFHLGlCQUFpQixPQUFPLDhCQUE4Qix3Q0FBd0MsdUJBQXVCLHNDQUFzQyxhQUFhLEVBQUUsdUJBQXVCLGFBQWEsK0JBQStCLFNBQVMsNkJBQTZCLFVBQVUsY0FBYyw2Q0FBNkMsb0RBQW9ELG1CQUFtQixnQkFBZ0IsZUFBZSxDQUFDLCtDQUFLLCtDQUErQyxnQkFBZ0IsZUFBZSxDQUFDLCtDQUFLLDJDQUEyQyxjQUFjLHdCQUF3QixPQUFPLFdBQVcsS0FBSyxrQkFBa0IsaUJBQWlCLDhDQUE4QyxlQUFlLDhCQUE4QixzQkFBc0IsU0FBUyx3QkFBd0IsZ0JBQWdCLGVBQWUsdURBQXVELGdCQUFnQix3QkFBd0IsU0FBUyxJQUFJLGNBQWMsa0NBQWtDLG1FQUFtRSxnQkFBZ0IseURBQWUsRUFBRSx5REFBZSxXQUFXLGNBQWMsc0JBQXNCLHNFQUFzRSx3QkFBd0IsbUJBQW1CLGFBQWEsRUFBRSxhQUFhLGdCQUFnQixVQUFVLGdCQUFnQiw4QkFBOEIsUUFBUSwyQkFBMkIseUJBQXlCLFlBQVksYUFBYSxVQUFVLFlBQVkscUJBQXFCLHVEQUF1RCxTQUFTLGFBQWEsK0NBQUssV0FBVywrQ0FBSyxhQUFhLGVBQWUsQ0FBQywrQ0FBSyxhQUFhLFlBQVksb0JBQW9CLHNEQUFzRCw2Q0FBNkMscURBQXFELENBQUMsa0RBQVEsYUFBYSxRQUFRLFlBQVksaURBQWlELGlFQUF1QixNQUFNLGlFQUF1Qix1Q0FBdUMsNERBQTRELFlBQVksQ0FBQywrQ0FBSyxlQUFlLG1CQUFtQixJQUFJLGdEQUFnRCxrQkFBa0IsRUFBRSxTQUFTLG1CQUFtQixrQkFBa0IsT0FBTywrQ0FBSyxXQUFXLFlBQVksQ0FBQyxtREFBUyxhQUFhLFFBQVEsY0FBYyx3Q0FBd0MsSUFBSSxLQUFLLFNBQVMsS0FBSyxrQkFBa0IsK0NBQUssWUFBWSwrQ0FBK0MsY0FBYyxtQkFBbUIseURBQXlELHFCQUFxQixnQ0FBZ0MsY0FBYyxnQkFBZ0IsNkNBQTZDLGNBQWMsUUFBUSxpQkFBaUIsZ0JBQWdCLG9EQUFvRCxnQkFBZ0IsRUFBRSxnQkFBZ0Isa0NBQW1QO0FBQ2g4RyIsInNvdXJjZXMiOlsid2VicGFjazovL1Z1ZXh5Ly4vbm9kZV9tb2R1bGVzL3ByZWFjdC9ob29rcy9kaXN0L2hvb2tzLm1vZHVsZS5qcz8zMGVjIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydHtvcHRpb25zIGFzIG59ZnJvbVwicHJlYWN0XCI7dmFyIHQscix1LGksbz0wLGY9W10sYz1bXSxlPW4uX19iLGE9bi5fX3Isdj1uLmRpZmZlZCxsPW4uX19jLG09bi51bm1vdW50O2Z1bmN0aW9uIGQodCx1KXtuLl9faCYmbi5fX2gocix0LG98fHUpLG89MDt2YXIgaT1yLl9fSHx8KHIuX19IPXtfXzpbXSxfX2g6W119KTtyZXR1cm4gdD49aS5fXy5sZW5ndGgmJmkuX18ucHVzaCh7X19WOmN9KSxpLl9fW3RdfWZ1bmN0aW9uIHAobil7cmV0dXJuIG89MSx5KEIsbil9ZnVuY3Rpb24geShuLHUsaSl7dmFyIG89ZCh0KyssMik7aWYoby50PW4sIW8uX19jJiYoby5fXz1baT9pKHUpOkIodm9pZCAwLHUpLGZ1bmN0aW9uKG4pe3ZhciB0PW8uX19OP28uX19OWzBdOm8uX19bMF0scj1vLnQodCxuKTt0IT09ciYmKG8uX19OPVtyLG8uX19bMV1dLG8uX19jLnNldFN0YXRlKHt9KSl9XSxvLl9fYz1yLCFyLnUpKXtyLnU9ITA7dmFyIGY9ci5zaG91bGRDb21wb25lbnRVcGRhdGU7ci5zaG91bGRDb21wb25lbnRVcGRhdGU9ZnVuY3Rpb24obix0LHIpe2lmKCFvLl9fYy5fX0gpcmV0dXJuITA7dmFyIHU9by5fX2MuX19ILl9fLmZpbHRlcihmdW5jdGlvbihuKXtyZXR1cm4gbi5fX2N9KTtpZih1LmV2ZXJ5KGZ1bmN0aW9uKG4pe3JldHVybiFuLl9fTn0pKXJldHVybiFmfHxmLmNhbGwodGhpcyxuLHQscik7dmFyIGk9ITE7cmV0dXJuIHUuZm9yRWFjaChmdW5jdGlvbihuKXtpZihuLl9fTil7dmFyIHQ9bi5fX1swXTtuLl9fPW4uX19OLG4uX19OPXZvaWQgMCx0IT09bi5fX1swXSYmKGk9ITApfX0pLCEoIWkmJm8uX19jLnByb3BzPT09bikmJighZnx8Zi5jYWxsKHRoaXMsbix0LHIpKX19cmV0dXJuIG8uX19OfHxvLl9ffWZ1bmN0aW9uIGgodSxpKXt2YXIgbz1kKHQrKywzKTshbi5fX3MmJnooby5fX0gsaSkmJihvLl9fPXUsby5pPWksci5fX0guX19oLnB1c2gobykpfWZ1bmN0aW9uIHModSxpKXt2YXIgbz1kKHQrKyw0KTshbi5fX3MmJnooby5fX0gsaSkmJihvLl9fPXUsby5pPWksci5fX2gucHVzaChvKSl9ZnVuY3Rpb24gXyhuKXtyZXR1cm4gbz01LEYoZnVuY3Rpb24oKXtyZXR1cm57Y3VycmVudDpufX0sW10pfWZ1bmN0aW9uIEEobix0LHIpe289NixzKGZ1bmN0aW9uKCl7cmV0dXJuXCJmdW5jdGlvblwiPT10eXBlb2Ygbj8obih0KCkpLGZ1bmN0aW9uKCl7cmV0dXJuIG4obnVsbCl9KTpuPyhuLmN1cnJlbnQ9dCgpLGZ1bmN0aW9uKCl7cmV0dXJuIG4uY3VycmVudD1udWxsfSk6dm9pZCAwfSxudWxsPT1yP3I6ci5jb25jYXQobikpfWZ1bmN0aW9uIEYobixyKXt2YXIgdT1kKHQrKyw3KTtyZXR1cm4geih1Ll9fSCxyKT8odS5fX1Y9bigpLHUuaT1yLHUuX19oPW4sdS5fX1YpOnUuX199ZnVuY3Rpb24gVChuLHQpe3JldHVybiBvPTgsRihmdW5jdGlvbigpe3JldHVybiBufSx0KX1mdW5jdGlvbiBxKG4pe3ZhciB1PXIuY29udGV4dFtuLl9fY10saT1kKHQrKyw5KTtyZXR1cm4gaS5jPW4sdT8obnVsbD09aS5fXyYmKGkuX189ITAsdS5zdWIocikpLHUucHJvcHMudmFsdWUpOm4uX199ZnVuY3Rpb24geCh0LHIpe24udXNlRGVidWdWYWx1ZSYmbi51c2VEZWJ1Z1ZhbHVlKHI/cih0KTp0KX1mdW5jdGlvbiBQKG4pe3ZhciB1PWQodCsrLDEwKSxpPXAoKTtyZXR1cm4gdS5fXz1uLHIuY29tcG9uZW50RGlkQ2F0Y2h8fChyLmNvbXBvbmVudERpZENhdGNoPWZ1bmN0aW9uKG4sdCl7dS5fXyYmdS5fXyhuLHQpLGlbMV0obil9KSxbaVswXSxmdW5jdGlvbigpe2lbMV0odm9pZCAwKX1dfWZ1bmN0aW9uIFYoKXt2YXIgbj1kKHQrKywxMSk7aWYoIW4uX18pe2Zvcih2YXIgdT1yLl9fdjtudWxsIT09dSYmIXUuX19tJiZudWxsIT09dS5fXzspdT11Ll9fO3ZhciBpPXUuX19tfHwodS5fX209WzAsMF0pO24uX189XCJQXCIraVswXStcIi1cIitpWzFdKyt9cmV0dXJuIG4uX199ZnVuY3Rpb24gYigpe2Zvcih2YXIgdDt0PWYuc2hpZnQoKTspaWYodC5fX1AmJnQuX19IKXRyeXt0Ll9fSC5fX2guZm9yRWFjaChrKSx0Ll9fSC5fX2guZm9yRWFjaCh3KSx0Ll9fSC5fX2g9W119Y2F0Y2gocil7dC5fX0guX19oPVtdLG4uX19lKHIsdC5fX3YpfX1uLl9fYj1mdW5jdGlvbihuKXtyPW51bGwsZSYmZShuKX0sbi5fX3I9ZnVuY3Rpb24obil7YSYmYShuKSx0PTA7dmFyIGk9KHI9bi5fX2MpLl9fSDtpJiYodT09PXI/KGkuX19oPVtdLHIuX19oPVtdLGkuX18uZm9yRWFjaChmdW5jdGlvbihuKXtuLl9fTiYmKG4uX189bi5fX04pLG4uX19WPWMsbi5fX049bi5pPXZvaWQgMH0pKTooaS5fX2guZm9yRWFjaChrKSxpLl9faC5mb3JFYWNoKHcpLGkuX19oPVtdKSksdT1yfSxuLmRpZmZlZD1mdW5jdGlvbih0KXt2JiZ2KHQpO3ZhciBvPXQuX19jO28mJm8uX19IJiYoby5fX0guX19oLmxlbmd0aCYmKDEhPT1mLnB1c2gobykmJmk9PT1uLnJlcXVlc3RBbmltYXRpb25GcmFtZXx8KChpPW4ucmVxdWVzdEFuaW1hdGlvbkZyYW1lKXx8aikoYikpLG8uX19ILl9fLmZvckVhY2goZnVuY3Rpb24obil7bi5pJiYobi5fX0g9bi5pKSxuLl9fViE9PWMmJihuLl9fPW4uX19WKSxuLmk9dm9pZCAwLG4uX19WPWN9KSksdT1yPW51bGx9LG4uX19jPWZ1bmN0aW9uKHQscil7ci5zb21lKGZ1bmN0aW9uKHQpe3RyeXt0Ll9faC5mb3JFYWNoKGspLHQuX19oPXQuX19oLmZpbHRlcihmdW5jdGlvbihuKXtyZXR1cm4hbi5fX3x8dyhuKX0pfWNhdGNoKHUpe3Iuc29tZShmdW5jdGlvbihuKXtuLl9faCYmKG4uX19oPVtdKX0pLHI9W10sbi5fX2UodSx0Ll9fdil9fSksbCYmbCh0LHIpfSxuLnVubW91bnQ9ZnVuY3Rpb24odCl7bSYmbSh0KTt2YXIgcix1PXQuX19jO3UmJnUuX19IJiYodS5fX0guX18uZm9yRWFjaChmdW5jdGlvbihuKXt0cnl7ayhuKX1jYXRjaChuKXtyPW59fSksdS5fX0g9dm9pZCAwLHImJm4uX19lKHIsdS5fX3YpKX07dmFyIGc9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWVzdEFuaW1hdGlvbkZyYW1lO2Z1bmN0aW9uIGoobil7dmFyIHQscj1mdW5jdGlvbigpe2NsZWFyVGltZW91dCh1KSxnJiZjYW5jZWxBbmltYXRpb25GcmFtZSh0KSxzZXRUaW1lb3V0KG4pfSx1PXNldFRpbWVvdXQociwxMDApO2cmJih0PXJlcXVlc3RBbmltYXRpb25GcmFtZShyKSl9ZnVuY3Rpb24gayhuKXt2YXIgdD1yLHU9bi5fX2M7XCJmdW5jdGlvblwiPT10eXBlb2YgdSYmKG4uX19jPXZvaWQgMCx1KCkpLHI9dH1mdW5jdGlvbiB3KG4pe3ZhciB0PXI7bi5fX2M9bi5fXygpLHI9dH1mdW5jdGlvbiB6KG4sdCl7cmV0dXJuIW58fG4ubGVuZ3RoIT09dC5sZW5ndGh8fHQuc29tZShmdW5jdGlvbih0LHIpe3JldHVybiB0IT09bltyXX0pfWZ1bmN0aW9uIEIobix0KXtyZXR1cm5cImZ1bmN0aW9uXCI9PXR5cGVvZiB0P3Qobik6dH1leHBvcnR7VCBhcyB1c2VDYWxsYmFjayxxIGFzIHVzZUNvbnRleHQseCBhcyB1c2VEZWJ1Z1ZhbHVlLGggYXMgdXNlRWZmZWN0LFAgYXMgdXNlRXJyb3JCb3VuZGFyeSxWIGFzIHVzZUlkLEEgYXMgdXNlSW1wZXJhdGl2ZUhhbmRsZSxzIGFzIHVzZUxheW91dEVmZmVjdCxGIGFzIHVzZU1lbW8seSBhcyB1c2VSZWR1Y2VyLF8gYXMgdXNlUmVmLHAgYXMgdXNlU3RhdGV9O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aG9va3MubW9kdWxlLmpzLm1hcFxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/preact/hooks/dist/hooks.module.js\n"); /***/ }), /***/ "./node_modules/@fullcalendar/core/index.esm.js": /*!******************************************************!*\ !*** ./node_modules/@fullcalendar/core/index.esm.js ***! \******************************************************/ /***/ (function(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) { eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"Calendar\": function() { return /* binding */ Calendar; },\n/* harmony export */ \"JsonRequestError\": function() { return /* reexport safe */ _internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.ag; },\n/* harmony export */ \"createPlugin\": function() { return /* binding */ createPlugin; },\n/* harmony export */ \"formatDate\": function() { return /* binding */ formatDate; },\n/* harmony export */ \"formatRange\": function() { return /* binding */ formatRange; },\n/* harmony export */ \"globalLocales\": function() { return /* binding */ globalLocales; },\n/* harmony export */ \"globalPlugins\": function() { return /* binding */ globalPlugins; },\n/* harmony export */ \"sliceEvents\": function() { return /* binding */ sliceEvents; },\n/* harmony export */ \"version\": function() { return /* binding */ version; }\n/* harmony export */ });\n/* harmony import */ var _internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./internal-common.esm.js */ \"./node_modules/@fullcalendar/core/internal-common.esm.js\");\n/* harmony import */ var preact__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! preact */ \"./node_modules/preact/dist/preact.module.js\");\n/* harmony import */ var preact_compat__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! preact/compat */ \"./node_modules/preact/compat/dist/compat.module.js\");\n\n\n\n\n\nvar css_248z = \":root{--fc-small-font-size:.85em;--fc-page-bg-color:#fff;--fc-neutral-bg-color:hsla(0,0%,82%,.3);--fc-neutral-text-color:grey;--fc-border-color:#ddd;--fc-button-text-color:#fff;--fc-button-bg-color:#2c3e50;--fc-button-border-color:#2c3e50;--fc-button-hover-bg-color:#1e2b37;--fc-button-hover-border-color:#1a252f;--fc-button-active-bg-color:#1a252f;--fc-button-active-border-color:#151e27;--fc-event-bg-color:#3788d8;--fc-event-border-color:#3788d8;--fc-event-text-color:#fff;--fc-event-selected-overlay-color:rgba(0,0,0,.25);--fc-more-link-bg-color:#d0d0d0;--fc-more-link-text-color:inherit;--fc-event-resizer-thickness:8px;--fc-event-resizer-dot-total-width:8px;--fc-event-resizer-dot-border-width:1px;--fc-non-business-color:hsla(0,0%,84%,.3);--fc-bg-event-color:#8fdf82;--fc-bg-event-opacity:0.3;--fc-highlight-color:rgba(188,232,241,.3);--fc-today-bg-color:rgba(255,220,40,.15);--fc-now-indicator-color:red}.fc-not-allowed,.fc-not-allowed .fc-event{cursor:not-allowed}.fc-unselectable{-webkit-touch-callout:none;-webkit-tap-highlight-color:rgba(0,0,0,0);-webkit-user-select:none;-moz-user-select:none;user-select:none}.fc{display:flex;flex-direction:column;font-size:1em}.fc,.fc *,.fc :after,.fc :before{box-sizing:border-box}.fc table{border-collapse:collapse;border-spacing:0;font-size:1em}.fc th{text-align:center}.fc td,.fc th{padding:0;vertical-align:top}.fc a[data-navlink]{cursor:pointer}.fc a[data-navlink]:hover{text-decoration:underline}.fc-direction-ltr{direction:ltr;text-align:left}.fc-direction-rtl{direction:rtl;text-align:right}.fc-theme-standard td,.fc-theme-standard th{border:1px solid var(--fc-border-color)}.fc-liquid-hack td,.fc-liquid-hack th{position:relative}@font-face{font-family:fcicons;font-style:normal;font-weight:400;src:url(\\\"data:application/x-font-ttf;charset=utf-8;base64,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\\\") format(\\\"truetype\\\")}.fc-icon{speak:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;display:inline-block;font-family:fcicons!important;font-style:normal;font-variant:normal;font-weight:400;height:1em;line-height:1;text-align:center;text-transform:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:1em}.fc-icon-chevron-left:before{content:\\\"\\\\e900\\\"}.fc-icon-chevron-right:before{content:\\\"\\\\e901\\\"}.fc-icon-chevrons-left:before{content:\\\"\\\\e902\\\"}.fc-icon-chevrons-right:before{content:\\\"\\\\e903\\\"}.fc-icon-minus-square:before{content:\\\"\\\\e904\\\"}.fc-icon-plus-square:before{content:\\\"\\\\e905\\\"}.fc-icon-x:before{content:\\\"\\\\e906\\\"}.fc .fc-button{border-radius:0;font-family:inherit;font-size:inherit;line-height:inherit;margin:0;overflow:visible;text-transform:none}.fc .fc-button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}.fc .fc-button{-webkit-appearance:button}.fc .fc-button:not(:disabled){cursor:pointer}.fc .fc-button::-moz-focus-inner{border-style:none;padding:0}.fc .fc-button{background-color:transparent;border:1px solid transparent;border-radius:.25em;display:inline-block;font-size:1em;font-weight:400;line-height:1.5;padding:.4em .65em;text-align:center;-webkit-user-select:none;-moz-user-select:none;user-select:none;vertical-align:middle}.fc .fc-button:hover{text-decoration:none}.fc .fc-button:focus{box-shadow:0 0 0 .2rem rgba(44,62,80,.25);outline:0}.fc .fc-button:disabled{opacity:.65}.fc .fc-button-primary{background-color:var(--fc-button-bg-color);border-color:var(--fc-button-border-color);color:var(--fc-button-text-color)}.fc .fc-button-primary:hover{background-color:var(--fc-button-hover-bg-color);border-color:var(--fc-button-hover-border-color);color:var(--fc-button-text-color)}.fc .fc-button-primary:disabled{background-color:var(--fc-button-bg-color);border-color:var(--fc-button-border-color);color:var(--fc-button-text-color)}.fc .fc-button-primary:focus{box-shadow:0 0 0 .2rem rgba(76,91,106,.5)}.fc .fc-button-primary:not(:disabled).fc-button-active,.fc .fc-button-primary:not(:disabled):active{background-color:var(--fc-button-active-bg-color);border-color:var(--fc-button-active-border-color);color:var(--fc-button-text-color)}.fc .fc-button-primary:not(:disabled).fc-button-active:focus,.fc .fc-button-primary:not(:disabled):active:focus{box-shadow:0 0 0 .2rem rgba(76,91,106,.5)}.fc .fc-button .fc-icon{font-size:1.5em;vertical-align:middle}.fc .fc-button-group{display:inline-flex;position:relative;vertical-align:middle}.fc .fc-button-group>.fc-button{flex:1 1 auto;position:relative}.fc .fc-button-group>.fc-button.fc-button-active,.fc .fc-button-group>.fc-button:active,.fc .fc-button-group>.fc-button:focus,.fc .fc-button-group>.fc-button:hover{z-index:1}.fc-direction-ltr .fc-button-group>.fc-button:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0;margin-left:-1px}.fc-direction-ltr .fc-button-group>.fc-button:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.fc-direction-rtl .fc-button-group>.fc-button:not(:first-child){border-bottom-right-radius:0;border-top-right-radius:0;margin-right:-1px}.fc-direction-rtl .fc-button-group>.fc-button:not(:last-child){border-bottom-left-radius:0;border-top-left-radius:0}.fc .fc-toolbar{align-items:center;display:flex;justify-content:space-between}.fc .fc-toolbar.fc-header-toolbar{margin-bottom:1.5em}.fc .fc-toolbar.fc-footer-toolbar{margin-top:1.5em}.fc .fc-toolbar-title{font-size:1.75em;margin:0}.fc-direction-ltr .fc-toolbar>*>:not(:first-child){margin-left:.75em}.fc-direction-rtl .fc-toolbar>*>:not(:first-child){margin-right:.75em}.fc-direction-rtl .fc-toolbar-ltr{flex-direction:row-reverse}.fc .fc-scroller{-webkit-overflow-scrolling:touch;position:relative}.fc .fc-scroller-liquid{height:100%}.fc .fc-scroller-liquid-absolute{bottom:0;left:0;position:absolute;right:0;top:0}.fc .fc-scroller-harness{direction:ltr;overflow:hidden;position:relative}.fc .fc-scroller-harness-liquid{height:100%}.fc-direction-rtl .fc-scroller-harness>.fc-scroller{direction:rtl}.fc-theme-standard .fc-scrollgrid{border:1px solid var(--fc-border-color)}.fc .fc-scrollgrid,.fc .fc-scrollgrid table{table-layout:fixed;width:100%}.fc .fc-scrollgrid table{border-left-style:hidden;border-right-style:hidden;border-top-style:hidden}.fc .fc-scrollgrid{border-bottom-width:0;border-collapse:separate;border-right-width:0}.fc .fc-scrollgrid-liquid{height:100%}.fc .fc-scrollgrid-section,.fc .fc-scrollgrid-section table,.fc .fc-scrollgrid-section>td{height:1px}.fc .fc-scrollgrid-section-liquid>td{height:100%}.fc .fc-scrollgrid-section>*{border-left-width:0;border-top-width:0}.fc .fc-scrollgrid-section-footer>*,.fc .fc-scrollgrid-section-header>*{border-bottom-width:0}.fc .fc-scrollgrid-section-body table,.fc .fc-scrollgrid-section-footer table{border-bottom-style:hidden}.fc .fc-scrollgrid-section-sticky>*{background:var(--fc-page-bg-color);position:sticky;z-index:3}.fc .fc-scrollgrid-section-header.fc-scrollgrid-section-sticky>*{top:0}.fc .fc-scrollgrid-section-footer.fc-scrollgrid-section-sticky>*{bottom:0}.fc .fc-scrollgrid-sticky-shim{height:1px;margin-bottom:-1px}.fc-sticky{position:sticky}.fc .fc-view-harness{flex-grow:1;position:relative}.fc .fc-view-harness-active>.fc-view{bottom:0;left:0;position:absolute;right:0;top:0}.fc .fc-col-header-cell-cushion{display:inline-block;padding:2px 4px}.fc .fc-bg-event,.fc .fc-highlight,.fc .fc-non-business{bottom:0;left:0;position:absolute;right:0;top:0}.fc .fc-non-business{background:var(--fc-non-business-color)}.fc .fc-bg-event{background:var(--fc-bg-event-color);opacity:var(--fc-bg-event-opacity)}.fc .fc-bg-event .fc-event-title{font-size:var(--fc-small-font-size);font-style:italic;margin:.5em}.fc .fc-highlight{background:var(--fc-highlight-color)}.fc .fc-cell-shaded,.fc .fc-day-disabled{background:var(--fc-neutral-bg-color)}a.fc-event,a.fc-event:hover{text-decoration:none}.fc-event.fc-event-draggable,.fc-event[href]{cursor:pointer}.fc-event .fc-event-main{position:relative;z-index:2}.fc-event-dragging:not(.fc-event-selected){opacity:.75}.fc-event-dragging.fc-event-selected{box-shadow:0 2px 7px rgba(0,0,0,.3)}.fc-event .fc-event-resizer{display:none;position:absolute;z-index:4}.fc-event-selected .fc-event-resizer,.fc-event:hover .fc-event-resizer{display:block}.fc-event-selected .fc-event-resizer{background:var(--fc-page-bg-color);border-color:inherit;border-radius:calc(var(--fc-event-resizer-dot-total-width)/2);border-style:solid;border-width:var(--fc-event-resizer-dot-border-width);height:var(--fc-event-resizer-dot-total-width);width:var(--fc-event-resizer-dot-total-width)}.fc-event-selected .fc-event-resizer:before{bottom:-20px;content:\\\"\\\";left:-20px;position:absolute;right:-20px;top:-20px}.fc-event-selected,.fc-event:focus{box-shadow:0 2px 5px rgba(0,0,0,.2)}.fc-event-selected:before,.fc-event:focus:before{bottom:0;content:\\\"\\\";left:0;position:absolute;right:0;top:0;z-index:3}.fc-event-selected:after,.fc-event:focus:after{background:var(--fc-event-selected-overlay-color);bottom:-1px;content:\\\"\\\";left:-1px;position:absolute;right:-1px;top:-1px;z-index:1}.fc-h-event{background-color:var(--fc-event-bg-color);border:1px solid var(--fc-event-border-color);display:block}.fc-h-event .fc-event-main{color:var(--fc-event-text-color)}.fc-h-event .fc-event-main-frame{display:flex}.fc-h-event .fc-event-time{max-width:100%;overflow:hidden}.fc-h-event .fc-event-title-container{flex-grow:1;flex-shrink:1;min-width:0}.fc-h-event .fc-event-title{display:inline-block;left:0;max-width:100%;overflow:hidden;right:0;vertical-align:top}.fc-h-event.fc-event-selected:before{bottom:-10px;top:-10px}.fc-direction-ltr .fc-daygrid-block-event:not(.fc-event-start),.fc-direction-rtl .fc-daygrid-block-event:not(.fc-event-end){border-bottom-left-radius:0;border-left-width:0;border-top-left-radius:0}.fc-direction-ltr .fc-daygrid-block-event:not(.fc-event-end),.fc-direction-rtl .fc-daygrid-block-event:not(.fc-event-start){border-bottom-right-radius:0;border-right-width:0;border-top-right-radius:0}.fc-h-event:not(.fc-event-selected) .fc-event-resizer{bottom:0;top:0;width:var(--fc-event-resizer-thickness)}.fc-direction-ltr .fc-h-event:not(.fc-event-selected) .fc-event-resizer-start,.fc-direction-rtl .fc-h-event:not(.fc-event-selected) .fc-event-resizer-end{cursor:w-resize;left:calc(var(--fc-event-resizer-thickness)*-.5)}.fc-direction-ltr .fc-h-event:not(.fc-event-selected) .fc-event-resizer-end,.fc-direction-rtl .fc-h-event:not(.fc-event-selected) .fc-event-resizer-start{cursor:e-resize;right:calc(var(--fc-event-resizer-thickness)*-.5)}.fc-h-event.fc-event-selected .fc-event-resizer{margin-top:calc(var(--fc-event-resizer-dot-total-width)*-.5);top:50%}.fc-direction-ltr .fc-h-event.fc-event-selected .fc-event-resizer-start,.fc-direction-rtl .fc-h-event.fc-event-selected .fc-event-resizer-end{left:calc(var(--fc-event-resizer-dot-total-width)*-.5)}.fc-direction-ltr .fc-h-event.fc-event-selected .fc-event-resizer-end,.fc-direction-rtl .fc-h-event.fc-event-selected .fc-event-resizer-start{right:calc(var(--fc-event-resizer-dot-total-width)*-.5)}.fc .fc-popover{box-shadow:0 2px 6px rgba(0,0,0,.15);position:absolute;z-index:9999}.fc .fc-popover-header{align-items:center;display:flex;flex-direction:row;justify-content:space-between;padding:3px 4px}.fc .fc-popover-title{margin:0 2px}.fc .fc-popover-close{cursor:pointer;font-size:1.1em;opacity:.65}.fc-theme-standard .fc-popover{background:var(--fc-page-bg-color);border:1px solid var(--fc-border-color)}.fc-theme-standard .fc-popover-header{background:var(--fc-neutral-bg-color)}\";\n(0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.i)(css_248z);\n\nconst globalLocales = [];\n\nconst MINIMAL_RAW_EN_LOCALE = {\n code: 'en',\n week: {\n dow: 0,\n doy: 4, // 4 days need to be within the year to be considered the first week\n },\n direction: 'ltr',\n buttonText: {\n prev: 'prev',\n next: 'next',\n prevYear: 'prev year',\n nextYear: 'next year',\n year: 'year',\n today: 'today',\n month: 'month',\n week: 'week',\n day: 'day',\n list: 'list',\n },\n weekText: 'W',\n weekTextLong: 'Week',\n closeHint: 'Close',\n timeHint: 'Time',\n eventHint: 'Event',\n allDayText: 'all-day',\n moreLinkText: 'more',\n noEventsText: 'No events to display',\n};\nconst RAW_EN_LOCALE = Object.assign(Object.assign({}, MINIMAL_RAW_EN_LOCALE), { \n // Includes things we don't want other locales to inherit,\n // things that derive from other translatable strings.\n buttonHints: {\n prev: 'Previous $0',\n next: 'Next $0',\n today(buttonText, unit) {\n return (unit === 'day')\n ? 'Today'\n : `This ${buttonText}`;\n },\n }, viewHint: '$0 view', navLinkHint: 'Go to $0', moreLinkHint(eventCnt) {\n return `Show ${eventCnt} more event${eventCnt === 1 ? '' : 's'}`;\n } });\nfunction organizeRawLocales(explicitRawLocales) {\n let defaultCode = explicitRawLocales.length > 0 ? explicitRawLocales[0].code : 'en';\n let allRawLocales = globalLocales.concat(explicitRawLocales);\n let rawLocaleMap = {\n en: RAW_EN_LOCALE,\n };\n for (let rawLocale of allRawLocales) {\n rawLocaleMap[rawLocale.code] = rawLocale;\n }\n return {\n map: rawLocaleMap,\n defaultCode,\n };\n}\nfunction buildLocale(inputSingular, available) {\n if (typeof inputSingular === 'object' && !Array.isArray(inputSingular)) {\n return parseLocale(inputSingular.code, [inputSingular.code], inputSingular);\n }\n return queryLocale(inputSingular, available);\n}\nfunction queryLocale(codeArg, available) {\n let codes = [].concat(codeArg || []); // will convert to array\n let raw = queryRawLocale(codes, available) || RAW_EN_LOCALE;\n return parseLocale(codeArg, codes, raw);\n}\nfunction queryRawLocale(codes, available) {\n for (let i = 0; i < codes.length; i += 1) {\n let parts = codes[i].toLocaleLowerCase().split('-');\n for (let j = parts.length; j > 0; j -= 1) {\n let simpleId = parts.slice(0, j).join('-');\n if (available[simpleId]) {\n return available[simpleId];\n }\n }\n }\n return null;\n}\nfunction parseLocale(codeArg, codes, raw) {\n let merged = (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.m)([MINIMAL_RAW_EN_LOCALE, raw], ['buttonText']);\n delete merged.code; // don't want this part of the options\n let { week } = merged;\n delete merged.week;\n return {\n codeArg,\n codes,\n week,\n simpleNumberFormat: new Intl.NumberFormat(codeArg),\n options: merged,\n };\n}\n\n// TODO: easier way to add new hooks? need to update a million things\nfunction createPlugin(input) {\n return {\n id: (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.g)(),\n name: input.name,\n premiumReleaseDate: input.premiumReleaseDate ? new Date(input.premiumReleaseDate) : undefined,\n deps: input.deps || [],\n reducers: input.reducers || [],\n isLoadingFuncs: input.isLoadingFuncs || [],\n contextInit: [].concat(input.contextInit || []),\n eventRefiners: input.eventRefiners || {},\n eventDefMemberAdders: input.eventDefMemberAdders || [],\n eventSourceRefiners: input.eventSourceRefiners || {},\n isDraggableTransformers: input.isDraggableTransformers || [],\n eventDragMutationMassagers: input.eventDragMutationMassagers || [],\n eventDefMutationAppliers: input.eventDefMutationAppliers || [],\n dateSelectionTransformers: input.dateSelectionTransformers || [],\n datePointTransforms: input.datePointTransforms || [],\n dateSpanTransforms: input.dateSpanTransforms || [],\n views: input.views || {},\n viewPropsTransformers: input.viewPropsTransformers || [],\n isPropsValid: input.isPropsValid || null,\n externalDefTransforms: input.externalDefTransforms || [],\n viewContainerAppends: input.viewContainerAppends || [],\n eventDropTransformers: input.eventDropTransformers || [],\n componentInteractions: input.componentInteractions || [],\n calendarInteractions: input.calendarInteractions || [],\n themeClasses: input.themeClasses || {},\n eventSourceDefs: input.eventSourceDefs || [],\n cmdFormatter: input.cmdFormatter,\n recurringTypes: input.recurringTypes || [],\n namedTimeZonedImpl: input.namedTimeZonedImpl,\n initialView: input.initialView || '',\n elementDraggingImpl: input.elementDraggingImpl,\n optionChangeHandlers: input.optionChangeHandlers || {},\n scrollGridImpl: input.scrollGridImpl || null,\n listenerRefiners: input.listenerRefiners || {},\n optionRefiners: input.optionRefiners || {},\n propSetHandlers: input.propSetHandlers || {},\n };\n}\nfunction buildPluginHooks(pluginDefs, globalDefs) {\n let currentPluginIds = {};\n let hooks = {\n premiumReleaseDate: undefined,\n reducers: [],\n isLoadingFuncs: [],\n contextInit: [],\n eventRefiners: {},\n eventDefMemberAdders: [],\n eventSourceRefiners: {},\n isDraggableTransformers: [],\n eventDragMutationMassagers: [],\n eventDefMutationAppliers: [],\n dateSelectionTransformers: [],\n datePointTransforms: [],\n dateSpanTransforms: [],\n views: {},\n viewPropsTransformers: [],\n isPropsValid: null,\n externalDefTransforms: [],\n viewContainerAppends: [],\n eventDropTransformers: [],\n componentInteractions: [],\n calendarInteractions: [],\n themeClasses: {},\n eventSourceDefs: [],\n cmdFormatter: null,\n recurringTypes: [],\n namedTimeZonedImpl: null,\n initialView: '',\n elementDraggingImpl: null,\n optionChangeHandlers: {},\n scrollGridImpl: null,\n listenerRefiners: {},\n optionRefiners: {},\n propSetHandlers: {},\n };\n function addDefs(defs) {\n for (let def of defs) {\n const pluginName = def.name;\n const currentId = currentPluginIds[pluginName];\n if (currentId === undefined) {\n currentPluginIds[pluginName] = def.id;\n addDefs(def.deps);\n hooks = combineHooks(hooks, def);\n }\n else if (currentId !== def.id) {\n // different ID than the one already added\n console.warn(`Duplicate plugin '${pluginName}'`);\n }\n }\n }\n if (pluginDefs) {\n addDefs(pluginDefs);\n }\n addDefs(globalDefs);\n return hooks;\n}\nfunction buildBuildPluginHooks() {\n let currentOverrideDefs = [];\n let currentGlobalDefs = [];\n let currentHooks;\n return (overrideDefs, globalDefs) => {\n if (!currentHooks || !(0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.a)(overrideDefs, currentOverrideDefs) || !(0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.a)(globalDefs, currentGlobalDefs)) {\n currentHooks = buildPluginHooks(overrideDefs, globalDefs);\n }\n currentOverrideDefs = overrideDefs;\n currentGlobalDefs = globalDefs;\n return currentHooks;\n };\n}\nfunction combineHooks(hooks0, hooks1) {\n return {\n premiumReleaseDate: compareOptionalDates(hooks0.premiumReleaseDate, hooks1.premiumReleaseDate),\n reducers: hooks0.reducers.concat(hooks1.reducers),\n isLoadingFuncs: hooks0.isLoadingFuncs.concat(hooks1.isLoadingFuncs),\n contextInit: hooks0.contextInit.concat(hooks1.contextInit),\n eventRefiners: Object.assign(Object.assign({}, hooks0.eventRefiners), hooks1.eventRefiners),\n eventDefMemberAdders: hooks0.eventDefMemberAdders.concat(hooks1.eventDefMemberAdders),\n eventSourceRefiners: Object.assign(Object.assign({}, hooks0.eventSourceRefiners), hooks1.eventSourceRefiners),\n isDraggableTransformers: hooks0.isDraggableTransformers.concat(hooks1.isDraggableTransformers),\n eventDragMutationMassagers: hooks0.eventDragMutationMassagers.concat(hooks1.eventDragMutationMassagers),\n eventDefMutationAppliers: hooks0.eventDefMutationAppliers.concat(hooks1.eventDefMutationAppliers),\n dateSelectionTransformers: hooks0.dateSelectionTransformers.concat(hooks1.dateSelectionTransformers),\n datePointTransforms: hooks0.datePointTransforms.concat(hooks1.datePointTransforms),\n dateSpanTransforms: hooks0.dateSpanTransforms.concat(hooks1.dateSpanTransforms),\n views: Object.assign(Object.assign({}, hooks0.views), hooks1.views),\n viewPropsTransformers: hooks0.viewPropsTransformers.concat(hooks1.viewPropsTransformers),\n isPropsValid: hooks1.isPropsValid || hooks0.isPropsValid,\n externalDefTransforms: hooks0.externalDefTransforms.concat(hooks1.externalDefTransforms),\n viewContainerAppends: hooks0.viewContainerAppends.concat(hooks1.viewContainerAppends),\n eventDropTransformers: hooks0.eventDropTransformers.concat(hooks1.eventDropTransformers),\n calendarInteractions: hooks0.calendarInteractions.concat(hooks1.calendarInteractions),\n componentInteractions: hooks0.componentInteractions.concat(hooks1.componentInteractions),\n themeClasses: Object.assign(Object.assign({}, hooks0.themeClasses), hooks1.themeClasses),\n eventSourceDefs: hooks0.eventSourceDefs.concat(hooks1.eventSourceDefs),\n cmdFormatter: hooks1.cmdFormatter || hooks0.cmdFormatter,\n recurringTypes: hooks0.recurringTypes.concat(hooks1.recurringTypes),\n namedTimeZonedImpl: hooks1.namedTimeZonedImpl || hooks0.namedTimeZonedImpl,\n initialView: hooks0.initialView || hooks1.initialView,\n elementDraggingImpl: hooks0.elementDraggingImpl || hooks1.elementDraggingImpl,\n optionChangeHandlers: Object.assign(Object.assign({}, hooks0.optionChangeHandlers), hooks1.optionChangeHandlers),\n scrollGridImpl: hooks1.scrollGridImpl || hooks0.scrollGridImpl,\n listenerRefiners: Object.assign(Object.assign({}, hooks0.listenerRefiners), hooks1.listenerRefiners),\n optionRefiners: Object.assign(Object.assign({}, hooks0.optionRefiners), hooks1.optionRefiners),\n propSetHandlers: Object.assign(Object.assign({}, hooks0.propSetHandlers), hooks1.propSetHandlers),\n };\n}\nfunction compareOptionalDates(date0, date1) {\n if (date0 === undefined) {\n return date1;\n }\n if (date1 === undefined) {\n return date0;\n }\n return new Date(Math.max(date0.valueOf(), date1.valueOf()));\n}\n\nclass StandardTheme extends _internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.T {\n}\nStandardTheme.prototype.classes = {\n root: 'fc-theme-standard',\n tableCellShaded: 'fc-cell-shaded',\n buttonGroup: 'fc-button-group',\n button: 'fc-button fc-button-primary',\n buttonActive: 'fc-button-active',\n};\nStandardTheme.prototype.baseIconClass = 'fc-icon';\nStandardTheme.prototype.iconClasses = {\n close: 'fc-icon-x',\n prev: 'fc-icon-chevron-left',\n next: 'fc-icon-chevron-right',\n prevYear: 'fc-icon-chevrons-left',\n nextYear: 'fc-icon-chevrons-right',\n};\nStandardTheme.prototype.rtlIconClasses = {\n prev: 'fc-icon-chevron-right',\n next: 'fc-icon-chevron-left',\n prevYear: 'fc-icon-chevrons-right',\n nextYear: 'fc-icon-chevrons-left',\n};\nStandardTheme.prototype.iconOverrideOption = 'buttonIcons'; // TODO: make TS-friendly\nStandardTheme.prototype.iconOverrideCustomButtonOption = 'icon';\nStandardTheme.prototype.iconOverridePrefix = 'fc-icon-';\n\nfunction compileViewDefs(defaultConfigs, overrideConfigs) {\n let hash = {};\n let viewType;\n for (viewType in defaultConfigs) {\n ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs);\n }\n for (viewType in overrideConfigs) {\n ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs);\n }\n return hash;\n}\nfunction ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs) {\n if (hash[viewType]) {\n return hash[viewType];\n }\n let viewDef = buildViewDef(viewType, hash, defaultConfigs, overrideConfigs);\n if (viewDef) {\n hash[viewType] = viewDef;\n }\n return viewDef;\n}\nfunction buildViewDef(viewType, hash, defaultConfigs, overrideConfigs) {\n let defaultConfig = defaultConfigs[viewType];\n let overrideConfig = overrideConfigs[viewType];\n let queryProp = (name) => ((defaultConfig && defaultConfig[name] !== null) ? defaultConfig[name] :\n ((overrideConfig && overrideConfig[name] !== null) ? overrideConfig[name] : null));\n let theComponent = queryProp('component');\n let superType = queryProp('superType');\n let superDef = null;\n if (superType) {\n if (superType === viewType) {\n throw new Error('Can\\'t have a custom view type that references itself');\n }\n superDef = ensureViewDef(superType, hash, defaultConfigs, overrideConfigs);\n }\n if (!theComponent && superDef) {\n theComponent = superDef.component;\n }\n if (!theComponent) {\n return null; // don't throw a warning, might be settings for a single-unit view\n }\n return {\n type: viewType,\n component: theComponent,\n defaults: Object.assign(Object.assign({}, (superDef ? superDef.defaults : {})), (defaultConfig ? defaultConfig.rawOptions : {})),\n overrides: Object.assign(Object.assign({}, (superDef ? superDef.overrides : {})), (overrideConfig ? overrideConfig.rawOptions : {})),\n };\n}\n\nfunction parseViewConfigs(inputs) {\n return (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.b)(inputs, parseViewConfig);\n}\nfunction parseViewConfig(input) {\n let rawOptions = typeof input === 'function' ?\n { component: input } :\n input;\n let { component } = rawOptions;\n if (rawOptions.content) {\n component = createViewHookComponent(rawOptions);\n // TODO: remove content/classNames/didMount/etc from options?\n }\n return {\n superType: rawOptions.type,\n component: component,\n rawOptions, // includes type and component too :(\n };\n}\nfunction createViewHookComponent(options) {\n return (viewProps) => ((0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.V.Consumer, null, (context) => ((0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.C, { elTag: \"div\", elClasses: (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.c)(context.viewSpec), renderProps: Object.assign(Object.assign({}, viewProps), { nextDayThreshold: context.options.nextDayThreshold }), generatorName: undefined, generator: options.content, classNameGenerator: options.classNames, didMount: options.didMount, willUnmount: options.willUnmount }))));\n}\n\nfunction buildViewSpecs(defaultInputs, optionOverrides, dynamicOptionOverrides, localeDefaults) {\n let defaultConfigs = parseViewConfigs(defaultInputs);\n let overrideConfigs = parseViewConfigs(optionOverrides.views);\n let viewDefs = compileViewDefs(defaultConfigs, overrideConfigs);\n return (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.b)(viewDefs, (viewDef) => buildViewSpec(viewDef, overrideConfigs, optionOverrides, dynamicOptionOverrides, localeDefaults));\n}\nfunction buildViewSpec(viewDef, overrideConfigs, optionOverrides, dynamicOptionOverrides, localeDefaults) {\n let durationInput = viewDef.overrides.duration ||\n viewDef.defaults.duration ||\n dynamicOptionOverrides.duration ||\n optionOverrides.duration;\n let duration = null;\n let durationUnit = '';\n let singleUnit = '';\n let singleUnitOverrides = {};\n if (durationInput) {\n duration = createDurationCached(durationInput);\n if (duration) { // valid?\n let denom = (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.d)(duration);\n durationUnit = denom.unit;\n if (denom.value === 1) {\n singleUnit = durationUnit;\n singleUnitOverrides = overrideConfigs[durationUnit] ? overrideConfigs[durationUnit].rawOptions : {};\n }\n }\n }\n let queryButtonText = (optionsSubset) => {\n let buttonTextMap = optionsSubset.buttonText || {};\n let buttonTextKey = viewDef.defaults.buttonTextKey;\n if (buttonTextKey != null && buttonTextMap[buttonTextKey] != null) {\n return buttonTextMap[buttonTextKey];\n }\n if (buttonTextMap[viewDef.type] != null) {\n return buttonTextMap[viewDef.type];\n }\n if (buttonTextMap[singleUnit] != null) {\n return buttonTextMap[singleUnit];\n }\n return null;\n };\n let queryButtonTitle = (optionsSubset) => {\n let buttonHints = optionsSubset.buttonHints || {};\n let buttonKey = viewDef.defaults.buttonTextKey; // use same key as text\n if (buttonKey != null && buttonHints[buttonKey] != null) {\n return buttonHints[buttonKey];\n }\n if (buttonHints[viewDef.type] != null) {\n return buttonHints[viewDef.type];\n }\n if (buttonHints[singleUnit] != null) {\n return buttonHints[singleUnit];\n }\n return null;\n };\n return {\n type: viewDef.type,\n component: viewDef.component,\n duration,\n durationUnit,\n singleUnit,\n optionDefaults: viewDef.defaults,\n optionOverrides: Object.assign(Object.assign({}, singleUnitOverrides), viewDef.overrides),\n buttonTextOverride: queryButtonText(dynamicOptionOverrides) ||\n queryButtonText(optionOverrides) || // constructor-specified buttonText lookup hash takes precedence\n viewDef.overrides.buttonText,\n buttonTextDefault: queryButtonText(localeDefaults) ||\n viewDef.defaults.buttonText ||\n queryButtonText(_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.B) ||\n viewDef.type,\n // not DRY\n buttonTitleOverride: queryButtonTitle(dynamicOptionOverrides) ||\n queryButtonTitle(optionOverrides) ||\n viewDef.overrides.buttonHint,\n buttonTitleDefault: queryButtonTitle(localeDefaults) ||\n viewDef.defaults.buttonHint ||\n queryButtonTitle(_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.B),\n // will eventually fall back to buttonText\n };\n}\n// hack to get memoization working\nlet durationInputMap = {};\nfunction createDurationCached(durationInput) {\n let json = JSON.stringify(durationInput);\n let res = durationInputMap[json];\n if (res === undefined) {\n res = (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.e)(durationInput);\n durationInputMap[json] = res;\n }\n return res;\n}\n\nfunction reduceViewType(viewType, action) {\n switch (action.type) {\n case 'CHANGE_VIEW_TYPE':\n viewType = action.viewType;\n }\n return viewType;\n}\n\nfunction reduceDynamicOptionOverrides(dynamicOptionOverrides, action) {\n switch (action.type) {\n case 'SET_OPTION':\n return Object.assign(Object.assign({}, dynamicOptionOverrides), { [action.optionName]: action.rawOptionValue });\n default:\n return dynamicOptionOverrides;\n }\n}\n\nfunction reduceDateProfile(currentDateProfile, action, currentDate, dateProfileGenerator) {\n let dp;\n switch (action.type) {\n case 'CHANGE_VIEW_TYPE':\n return dateProfileGenerator.build(action.dateMarker || currentDate);\n case 'CHANGE_DATE':\n return dateProfileGenerator.build(action.dateMarker);\n case 'PREV':\n dp = dateProfileGenerator.buildPrev(currentDateProfile, currentDate);\n if (dp.isValid) {\n return dp;\n }\n break;\n case 'NEXT':\n dp = dateProfileGenerator.buildNext(currentDateProfile, currentDate);\n if (dp.isValid) {\n return dp;\n }\n break;\n }\n return currentDateProfile;\n}\n\nfunction initEventSources(calendarOptions, dateProfile, context) {\n let activeRange = dateProfile ? dateProfile.activeRange : null;\n return addSources({}, parseInitialSources(calendarOptions, context), activeRange, context);\n}\nfunction reduceEventSources(eventSources, action, dateProfile, context) {\n let activeRange = dateProfile ? dateProfile.activeRange : null; // need this check?\n switch (action.type) {\n case 'ADD_EVENT_SOURCES': // already parsed\n return addSources(eventSources, action.sources, activeRange, context);\n case 'REMOVE_EVENT_SOURCE':\n return removeSource(eventSources, action.sourceId);\n case 'PREV': // TODO: how do we track all actions that affect dateProfile :(\n case 'NEXT':\n case 'CHANGE_DATE':\n case 'CHANGE_VIEW_TYPE':\n if (dateProfile) {\n return fetchDirtySources(eventSources, activeRange, context);\n }\n return eventSources;\n case 'FETCH_EVENT_SOURCES':\n return fetchSourcesByIds(eventSources, action.sourceIds ? // why no type?\n (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.f)(action.sourceIds) :\n excludeStaticSources(eventSources, context), activeRange, action.isRefetch || false, context);\n case 'RECEIVE_EVENTS':\n case 'RECEIVE_EVENT_ERROR':\n return receiveResponse(eventSources, action.sourceId, action.fetchId, action.fetchRange);\n case 'REMOVE_ALL_EVENT_SOURCES':\n return {};\n default:\n return eventSources;\n }\n}\nfunction reduceEventSourcesNewTimeZone(eventSources, dateProfile, context) {\n let activeRange = dateProfile ? dateProfile.activeRange : null; // need this check?\n return fetchSourcesByIds(eventSources, excludeStaticSources(eventSources, context), activeRange, true, context);\n}\nfunction computeEventSourcesLoading(eventSources) {\n for (let sourceId in eventSources) {\n if (eventSources[sourceId].isFetching) {\n return true;\n }\n }\n return false;\n}\nfunction addSources(eventSourceHash, sources, fetchRange, context) {\n let hash = {};\n for (let source of sources) {\n hash[source.sourceId] = source;\n }\n if (fetchRange) {\n hash = fetchDirtySources(hash, fetchRange, context);\n }\n return Object.assign(Object.assign({}, eventSourceHash), hash);\n}\nfunction removeSource(eventSourceHash, sourceId) {\n return (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.h)(eventSourceHash, (eventSource) => eventSource.sourceId !== sourceId);\n}\nfunction fetchDirtySources(sourceHash, fetchRange, context) {\n return fetchSourcesByIds(sourceHash, (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.h)(sourceHash, (eventSource) => isSourceDirty(eventSource, fetchRange, context)), fetchRange, false, context);\n}\nfunction isSourceDirty(eventSource, fetchRange, context) {\n if (!doesSourceNeedRange(eventSource, context)) {\n return !eventSource.latestFetchId;\n }\n return !context.options.lazyFetching ||\n !eventSource.fetchRange ||\n eventSource.isFetching || // always cancel outdated in-progress fetches\n fetchRange.start < eventSource.fetchRange.start ||\n fetchRange.end > eventSource.fetchRange.end;\n}\nfunction fetchSourcesByIds(prevSources, sourceIdHash, fetchRange, isRefetch, context) {\n let nextSources = {};\n for (let sourceId in prevSources) {\n let source = prevSources[sourceId];\n if (sourceIdHash[sourceId]) {\n nextSources[sourceId] = fetchSource(source, fetchRange, isRefetch, context);\n }\n else {\n nextSources[sourceId] = source;\n }\n }\n return nextSources;\n}\nfunction fetchSource(eventSource, fetchRange, isRefetch, context) {\n let { options, calendarApi } = context;\n let sourceDef = context.pluginHooks.eventSourceDefs[eventSource.sourceDefId];\n let fetchId = (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.g)();\n sourceDef.fetch({\n eventSource,\n range: fetchRange,\n isRefetch,\n context,\n }, (res) => {\n let { rawEvents } = res;\n if (options.eventSourceSuccess) {\n rawEvents = options.eventSourceSuccess.call(calendarApi, rawEvents, res.response) || rawEvents;\n }\n if (eventSource.success) {\n rawEvents = eventSource.success.call(calendarApi, rawEvents, res.response) || rawEvents;\n }\n context.dispatch({\n type: 'RECEIVE_EVENTS',\n sourceId: eventSource.sourceId,\n fetchId,\n fetchRange,\n rawEvents,\n });\n }, (error) => {\n let errorHandled = false;\n if (options.eventSourceFailure) {\n options.eventSourceFailure.call(calendarApi, error);\n errorHandled = true;\n }\n if (eventSource.failure) {\n eventSource.failure(error);\n errorHandled = true;\n }\n if (!errorHandled) {\n console.warn(error.message, error);\n }\n context.dispatch({\n type: 'RECEIVE_EVENT_ERROR',\n sourceId: eventSource.sourceId,\n fetchId,\n fetchRange,\n error,\n });\n });\n return Object.assign(Object.assign({}, eventSource), { isFetching: true, latestFetchId: fetchId });\n}\nfunction receiveResponse(sourceHash, sourceId, fetchId, fetchRange) {\n let eventSource = sourceHash[sourceId];\n if (eventSource && // not already removed\n fetchId === eventSource.latestFetchId) {\n return Object.assign(Object.assign({}, sourceHash), { [sourceId]: Object.assign(Object.assign({}, eventSource), { isFetching: false, fetchRange }) });\n }\n return sourceHash;\n}\nfunction excludeStaticSources(eventSources, context) {\n return (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.h)(eventSources, (eventSource) => doesSourceNeedRange(eventSource, context));\n}\nfunction parseInitialSources(rawOptions, context) {\n let refiners = (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.j)(context);\n let rawSources = [].concat(rawOptions.eventSources || []);\n let sources = []; // parsed\n if (rawOptions.initialEvents) {\n rawSources.unshift(rawOptions.initialEvents);\n }\n if (rawOptions.events) {\n rawSources.unshift(rawOptions.events);\n }\n for (let rawSource of rawSources) {\n let source = (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.p)(rawSource, context, refiners);\n if (source) {\n sources.push(source);\n }\n }\n return sources;\n}\nfunction doesSourceNeedRange(eventSource, context) {\n let defs = context.pluginHooks.eventSourceDefs;\n return !defs[eventSource.sourceDefId].ignoreRange;\n}\n\nfunction reduceDateSelection(currentSelection, action) {\n switch (action.type) {\n case 'UNSELECT_DATES':\n return null;\n case 'SELECT_DATES':\n return action.selection;\n default:\n return currentSelection;\n }\n}\n\nfunction reduceSelectedEvent(currentInstanceId, action) {\n switch (action.type) {\n case 'UNSELECT_EVENT':\n return '';\n case 'SELECT_EVENT':\n return action.eventInstanceId;\n default:\n return currentInstanceId;\n }\n}\n\nfunction reduceEventDrag(currentDrag, action) {\n let newDrag;\n switch (action.type) {\n case 'UNSET_EVENT_DRAG':\n return null;\n case 'SET_EVENT_DRAG':\n newDrag = action.state;\n return {\n affectedEvents: newDrag.affectedEvents,\n mutatedEvents: newDrag.mutatedEvents,\n isEvent: newDrag.isEvent,\n };\n default:\n return currentDrag;\n }\n}\n\nfunction reduceEventResize(currentResize, action) {\n let newResize;\n switch (action.type) {\n case 'UNSET_EVENT_RESIZE':\n return null;\n case 'SET_EVENT_RESIZE':\n newResize = action.state;\n return {\n affectedEvents: newResize.affectedEvents,\n mutatedEvents: newResize.mutatedEvents,\n isEvent: newResize.isEvent,\n };\n default:\n return currentResize;\n }\n}\n\nfunction parseToolbars(calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi) {\n let header = calendarOptions.headerToolbar ? parseToolbar(calendarOptions.headerToolbar, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi) : null;\n let footer = calendarOptions.footerToolbar ? parseToolbar(calendarOptions.footerToolbar, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi) : null;\n return { header, footer };\n}\nfunction parseToolbar(sectionStrHash, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi) {\n let sectionWidgets = {};\n let viewsWithButtons = [];\n let hasTitle = false;\n for (let sectionName in sectionStrHash) {\n let sectionStr = sectionStrHash[sectionName];\n let sectionRes = parseSection(sectionStr, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi);\n sectionWidgets[sectionName] = sectionRes.widgets;\n viewsWithButtons.push(...sectionRes.viewsWithButtons);\n hasTitle = hasTitle || sectionRes.hasTitle;\n }\n return { sectionWidgets, viewsWithButtons, hasTitle };\n}\n/*\nBAD: querying icons and text here. should be done at render time\n*/\nfunction parseSection(sectionStr, calendarOptions, // defaults+overrides, then refined\ncalendarOptionOverrides, // overrides only!, unrefined :(\ntheme, viewSpecs, calendarApi) {\n let isRtl = calendarOptions.direction === 'rtl';\n let calendarCustomButtons = calendarOptions.customButtons || {};\n let calendarButtonTextOverrides = calendarOptionOverrides.buttonText || {};\n let calendarButtonText = calendarOptions.buttonText || {};\n let calendarButtonHintOverrides = calendarOptionOverrides.buttonHints || {};\n let calendarButtonHints = calendarOptions.buttonHints || {};\n let sectionSubstrs = sectionStr ? sectionStr.split(' ') : [];\n let viewsWithButtons = [];\n let hasTitle = false;\n let widgets = sectionSubstrs.map((buttonGroupStr) => (buttonGroupStr.split(',').map((buttonName) => {\n if (buttonName === 'title') {\n hasTitle = true;\n return { buttonName };\n }\n let customButtonProps;\n let viewSpec;\n let buttonClick;\n let buttonIcon; // only one of these will be set\n let buttonText; // \"\n let buttonHint;\n // ^ for the title=\"\" attribute, for accessibility\n if ((customButtonProps = calendarCustomButtons[buttonName])) {\n buttonClick = (ev) => {\n if (customButtonProps.click) {\n customButtonProps.click.call(ev.target, ev, ev.target); // TODO: use Calendar this context?\n }\n };\n (buttonIcon = theme.getCustomButtonIconClass(customButtonProps)) ||\n (buttonIcon = theme.getIconClass(buttonName, isRtl)) ||\n (buttonText = customButtonProps.text);\n buttonHint = customButtonProps.hint || customButtonProps.text;\n }\n else if ((viewSpec = viewSpecs[buttonName])) {\n viewsWithButtons.push(buttonName);\n buttonClick = () => {\n calendarApi.changeView(buttonName);\n };\n (buttonText = viewSpec.buttonTextOverride) ||\n (buttonIcon = theme.getIconClass(buttonName, isRtl)) ||\n (buttonText = viewSpec.buttonTextDefault);\n let textFallback = viewSpec.buttonTextOverride ||\n viewSpec.buttonTextDefault;\n buttonHint = (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.k)(viewSpec.buttonTitleOverride ||\n viewSpec.buttonTitleDefault ||\n calendarOptions.viewHint, [textFallback, buttonName], // view-name = buttonName\n textFallback);\n }\n else if (calendarApi[buttonName]) { // a calendarApi method\n buttonClick = () => {\n calendarApi[buttonName]();\n };\n (buttonText = calendarButtonTextOverrides[buttonName]) ||\n (buttonIcon = theme.getIconClass(buttonName, isRtl)) ||\n (buttonText = calendarButtonText[buttonName]); // everything else is considered default\n if (buttonName === 'prevYear' || buttonName === 'nextYear') {\n let prevOrNext = buttonName === 'prevYear' ? 'prev' : 'next';\n buttonHint = (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.k)(calendarButtonHintOverrides[prevOrNext] ||\n calendarButtonHints[prevOrNext], [\n calendarButtonText.year || 'year',\n 'year',\n ], calendarButtonText[buttonName]);\n }\n else {\n buttonHint = (navUnit) => (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.k)(calendarButtonHintOverrides[buttonName] ||\n calendarButtonHints[buttonName], [\n calendarButtonText[navUnit] || navUnit,\n navUnit,\n ], calendarButtonText[buttonName]);\n }\n }\n return { buttonName, buttonClick, buttonIcon, buttonText, buttonHint };\n })));\n return { widgets, viewsWithButtons, hasTitle };\n}\n\n// always represents the current view. otherwise, it'd need to change value every time date changes\nclass ViewImpl {\n constructor(type, getCurrentData, dateEnv) {\n this.type = type;\n this.getCurrentData = getCurrentData;\n this.dateEnv = dateEnv;\n }\n get calendar() {\n return this.getCurrentData().calendarApi;\n }\n get title() {\n return this.getCurrentData().viewTitle;\n }\n get activeStart() {\n return this.dateEnv.toDate(this.getCurrentData().dateProfile.activeRange.start);\n }\n get activeEnd() {\n return this.dateEnv.toDate(this.getCurrentData().dateProfile.activeRange.end);\n }\n get currentStart() {\n return this.dateEnv.toDate(this.getCurrentData().dateProfile.currentRange.start);\n }\n get currentEnd() {\n return this.dateEnv.toDate(this.getCurrentData().dateProfile.currentRange.end);\n }\n getOption(name) {\n return this.getCurrentData().options[name]; // are the view-specific options\n }\n}\n\nlet eventSourceDef$2 = {\n ignoreRange: true,\n parseMeta(refined) {\n if (Array.isArray(refined.events)) {\n return refined.events;\n }\n return null;\n },\n fetch(arg, successCallback) {\n successCallback({\n rawEvents: arg.eventSource.meta,\n });\n },\n};\nconst arrayEventSourcePlugin = createPlugin({\n name: 'array-event-source',\n eventSourceDefs: [eventSourceDef$2],\n});\n\nlet eventSourceDef$1 = {\n parseMeta(refined) {\n if (typeof refined.events === 'function') {\n return refined.events;\n }\n return null;\n },\n fetch(arg, successCallback, errorCallback) {\n const { dateEnv } = arg.context;\n const func = arg.eventSource.meta;\n (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.u)(func.bind(null, (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.l)(arg.range, dateEnv)), (rawEvents) => successCallback({ rawEvents }), errorCallback);\n },\n};\nconst funcEventSourcePlugin = createPlugin({\n name: 'func-event-source',\n eventSourceDefs: [eventSourceDef$1],\n});\n\nconst JSON_FEED_EVENT_SOURCE_REFINERS = {\n method: String,\n extraParams: _internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.n,\n startParam: String,\n endParam: String,\n timeZoneParam: String,\n};\n\nlet eventSourceDef = {\n parseMeta(refined) {\n if (refined.url && (refined.format === 'json' || !refined.format)) {\n return {\n url: refined.url,\n format: 'json',\n method: (refined.method || 'GET').toUpperCase(),\n extraParams: refined.extraParams,\n startParam: refined.startParam,\n endParam: refined.endParam,\n timeZoneParam: refined.timeZoneParam,\n };\n }\n return null;\n },\n fetch(arg, successCallback, errorCallback) {\n const { meta } = arg.eventSource;\n const requestParams = buildRequestParams(meta, arg.range, arg.context);\n (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.r)(meta.method, meta.url, requestParams).then(([rawEvents, response]) => {\n successCallback({ rawEvents, response });\n }, errorCallback);\n },\n};\nconst jsonFeedEventSourcePlugin = createPlugin({\n name: 'json-event-source',\n eventSourceRefiners: JSON_FEED_EVENT_SOURCE_REFINERS,\n eventSourceDefs: [eventSourceDef],\n});\nfunction buildRequestParams(meta, range, context) {\n let { dateEnv, options } = context;\n let startParam;\n let endParam;\n let timeZoneParam;\n let customRequestParams;\n let params = {};\n startParam = meta.startParam;\n if (startParam == null) {\n startParam = options.startParam;\n }\n endParam = meta.endParam;\n if (endParam == null) {\n endParam = options.endParam;\n }\n timeZoneParam = meta.timeZoneParam;\n if (timeZoneParam == null) {\n timeZoneParam = options.timeZoneParam;\n }\n // retrieve any outbound GET/POST data from the options\n if (typeof meta.extraParams === 'function') {\n // supplied as a function that returns a key/value object\n customRequestParams = meta.extraParams();\n }\n else {\n // probably supplied as a straight key/value object\n customRequestParams = meta.extraParams || {};\n }\n Object.assign(params, customRequestParams);\n params[startParam] = dateEnv.formatIso(range.start);\n params[endParam] = dateEnv.formatIso(range.end);\n if (dateEnv.timeZone !== 'local') {\n params[timeZoneParam] = dateEnv.timeZone;\n }\n return params;\n}\n\nconst SIMPLE_RECURRING_REFINERS = {\n daysOfWeek: _internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.n,\n startTime: _internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.e,\n endTime: _internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.e,\n duration: _internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.e,\n startRecur: _internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.n,\n endRecur: _internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.n,\n};\n\nlet recurring = {\n parse(refined, dateEnv) {\n if (refined.daysOfWeek || refined.startTime || refined.endTime || refined.startRecur || refined.endRecur) {\n let recurringData = {\n daysOfWeek: refined.daysOfWeek || null,\n startTime: refined.startTime || null,\n endTime: refined.endTime || null,\n startRecur: refined.startRecur ? dateEnv.createMarker(refined.startRecur) : null,\n endRecur: refined.endRecur ? dateEnv.createMarker(refined.endRecur) : null,\n };\n let duration;\n if (refined.duration) {\n duration = refined.duration;\n }\n if (!duration && refined.startTime && refined.endTime) {\n duration = (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.s)(refined.endTime, refined.startTime);\n }\n return {\n allDayGuess: Boolean(!refined.startTime && !refined.endTime),\n duration,\n typeData: recurringData, // doesn't need endTime anymore but oh well\n };\n }\n return null;\n },\n expand(typeData, framingRange, dateEnv) {\n let clippedFramingRange = (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.o)(framingRange, { start: typeData.startRecur, end: typeData.endRecur });\n if (clippedFramingRange) {\n return expandRanges(typeData.daysOfWeek, typeData.startTime, clippedFramingRange, dateEnv);\n }\n return [];\n },\n};\nconst simpleRecurringEventsPlugin = createPlugin({\n name: 'simple-recurring-event',\n recurringTypes: [recurring],\n eventRefiners: SIMPLE_RECURRING_REFINERS,\n});\nfunction expandRanges(daysOfWeek, startTime, framingRange, dateEnv) {\n let dowHash = daysOfWeek ? (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.f)(daysOfWeek) : null;\n let dayMarker = (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.q)(framingRange.start);\n let endMarker = framingRange.end;\n let instanceStarts = [];\n while (dayMarker < endMarker) {\n let instanceStart;\n // if everyday, or this particular day-of-week\n if (!dowHash || dowHash[dayMarker.getUTCDay()]) {\n if (startTime) {\n instanceStart = dateEnv.add(dayMarker, startTime);\n }\n else {\n instanceStart = dayMarker;\n }\n instanceStarts.push(instanceStart);\n }\n dayMarker = (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.t)(dayMarker, 1);\n }\n return instanceStarts;\n}\n\nconst changeHandlerPlugin = createPlugin({\n name: 'change-handler',\n optionChangeHandlers: {\n events(events, context) {\n handleEventSources([events], context);\n },\n eventSources: handleEventSources,\n },\n});\n/*\nBUG: if `event` was supplied, all previously-given `eventSources` will be wiped out\n*/\nfunction handleEventSources(inputs, context) {\n let unfoundSources = (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.v)(context.getCurrentData().eventSources);\n let newInputs = [];\n for (let input of inputs) {\n let inputFound = false;\n for (let i = 0; i < unfoundSources.length; i += 1) {\n if (unfoundSources[i]._raw === input) {\n unfoundSources.splice(i, 1); // delete\n inputFound = true;\n break;\n }\n }\n if (!inputFound) {\n newInputs.push(input);\n }\n }\n for (let unfoundSource of unfoundSources) {\n context.dispatch({\n type: 'REMOVE_EVENT_SOURCE',\n sourceId: unfoundSource.sourceId,\n });\n }\n for (let newInput of newInputs) {\n context.calendarApi.addEventSource(newInput);\n }\n}\n\nfunction handleDateProfile(dateProfile, context) {\n context.emitter.trigger('datesSet', Object.assign(Object.assign({}, (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.l)(dateProfile.activeRange, context.dateEnv)), { view: context.viewApi }));\n}\n\nfunction handleEventStore(eventStore, context) {\n let { emitter } = context;\n if (emitter.hasHandlers('eventsSet')) {\n emitter.trigger('eventsSet', (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.w)(eventStore, context));\n }\n}\n\n/*\nthis array is exposed on the root namespace so that UMD plugins can add to it.\nsee the rollup-bundles script.\n*/\nconst globalPlugins = [\n arrayEventSourcePlugin,\n funcEventSourcePlugin,\n jsonFeedEventSourcePlugin,\n simpleRecurringEventsPlugin,\n changeHandlerPlugin,\n createPlugin({\n name: 'misc',\n isLoadingFuncs: [\n (state) => computeEventSourcesLoading(state.eventSources),\n ],\n propSetHandlers: {\n dateProfile: handleDateProfile,\n eventStore: handleEventStore,\n },\n }),\n];\n\nclass TaskRunner {\n constructor(runTaskOption, drainedOption) {\n this.runTaskOption = runTaskOption;\n this.drainedOption = drainedOption;\n this.queue = [];\n this.delayedRunner = new _internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.D(this.drain.bind(this));\n }\n request(task, delay) {\n this.queue.push(task);\n this.delayedRunner.request(delay);\n }\n pause(scope) {\n this.delayedRunner.pause(scope);\n }\n resume(scope, force) {\n this.delayedRunner.resume(scope, force);\n }\n drain() {\n let { queue } = this;\n while (queue.length) {\n let completedTasks = [];\n let task;\n while ((task = queue.shift())) {\n this.runTask(task);\n completedTasks.push(task);\n }\n this.drained(completedTasks);\n } // keep going, in case new tasks were added in the drained handler\n }\n runTask(task) {\n if (this.runTaskOption) {\n this.runTaskOption(task);\n }\n }\n drained(completedTasks) {\n if (this.drainedOption) {\n this.drainedOption(completedTasks);\n }\n }\n}\n\n// Computes what the title at the top of the calendarApi should be for this view\nfunction buildTitle(dateProfile, viewOptions, dateEnv) {\n let range;\n // for views that span a large unit of time, show the proper interval, ignoring stray days before and after\n if (/^(year|month)$/.test(dateProfile.currentRangeUnit)) {\n range = dateProfile.currentRange;\n }\n else { // for day units or smaller, use the actual day range\n range = dateProfile.activeRange;\n }\n return dateEnv.formatRange(range.start, range.end, (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.x)(viewOptions.titleFormat || buildTitleFormat(dateProfile)), {\n isEndExclusive: dateProfile.isRangeAllDay,\n defaultSeparator: viewOptions.titleRangeSeparator,\n });\n}\n// Generates the format string that should be used to generate the title for the current date range.\n// Attempts to compute the most appropriate format if not explicitly specified with `titleFormat`.\nfunction buildTitleFormat(dateProfile) {\n let { currentRangeUnit } = dateProfile;\n if (currentRangeUnit === 'year') {\n return { year: 'numeric' };\n }\n if (currentRangeUnit === 'month') {\n return { year: 'numeric', month: 'long' }; // like \"September 2014\"\n }\n let days = (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.y)(dateProfile.currentRange.start, dateProfile.currentRange.end);\n if (days !== null && days > 1) {\n // multi-day range. shorter, like \"Sep 9 - 10 2014\"\n return { year: 'numeric', month: 'short', day: 'numeric' };\n }\n // one day. longer, like \"September 9 2014\"\n return { year: 'numeric', month: 'long', day: 'numeric' };\n}\n\n// in future refactor, do the redux-style function(state=initial) for initial-state\n// also, whatever is happening in constructor, have it happen in action queue too\nclass CalendarDataManager {\n constructor(props) {\n this.computeOptionsData = (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.z)(this._computeOptionsData);\n this.computeCurrentViewData = (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.z)(this._computeCurrentViewData);\n this.organizeRawLocales = (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.z)(organizeRawLocales);\n this.buildLocale = (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.z)(buildLocale);\n this.buildPluginHooks = buildBuildPluginHooks();\n this.buildDateEnv = (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.z)(buildDateEnv$1);\n this.buildTheme = (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.z)(buildTheme);\n this.parseToolbars = (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.z)(parseToolbars);\n this.buildViewSpecs = (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.z)(buildViewSpecs);\n this.buildDateProfileGenerator = (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.A)(buildDateProfileGenerator);\n this.buildViewApi = (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.z)(buildViewApi);\n this.buildViewUiProps = (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.A)(buildViewUiProps);\n this.buildEventUiBySource = (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.z)(buildEventUiBySource, _internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.E);\n this.buildEventUiBases = (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.z)(buildEventUiBases);\n this.parseContextBusinessHours = (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.A)(parseContextBusinessHours);\n this.buildTitle = (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.z)(buildTitle);\n this.emitter = new _internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.F();\n this.actionRunner = new TaskRunner(this._handleAction.bind(this), this.updateData.bind(this));\n this.currentCalendarOptionsInput = {};\n this.currentCalendarOptionsRefined = {};\n this.currentViewOptionsInput = {};\n this.currentViewOptionsRefined = {};\n this.currentCalendarOptionsRefiners = {};\n this.getCurrentData = () => this.data;\n this.dispatch = (action) => {\n this.actionRunner.request(action); // protects against recursive calls to _handleAction\n };\n this.props = props;\n this.actionRunner.pause();\n let dynamicOptionOverrides = {};\n let optionsData = this.computeOptionsData(props.optionOverrides, dynamicOptionOverrides, props.calendarApi);\n let currentViewType = optionsData.calendarOptions.initialView || optionsData.pluginHooks.initialView;\n let currentViewData = this.computeCurrentViewData(currentViewType, optionsData, props.optionOverrides, dynamicOptionOverrides);\n // wire things up\n // TODO: not DRY\n props.calendarApi.currentDataManager = this;\n this.emitter.setThisContext(props.calendarApi);\n this.emitter.setOptions(currentViewData.options);\n let currentDate = (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.G)(optionsData.calendarOptions, optionsData.dateEnv);\n let dateProfile = currentViewData.dateProfileGenerator.build(currentDate);\n if (!(0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.H)(dateProfile.activeRange, currentDate)) {\n currentDate = dateProfile.currentRange.start;\n }\n let calendarContext = {\n dateEnv: optionsData.dateEnv,\n options: optionsData.calendarOptions,\n pluginHooks: optionsData.pluginHooks,\n calendarApi: props.calendarApi,\n dispatch: this.dispatch,\n emitter: this.emitter,\n getCurrentData: this.getCurrentData,\n };\n // needs to be after setThisContext\n for (let callback of optionsData.pluginHooks.contextInit) {\n callback(calendarContext);\n }\n // NOT DRY\n let eventSources = initEventSources(optionsData.calendarOptions, dateProfile, calendarContext);\n let initialState = {\n dynamicOptionOverrides,\n currentViewType,\n currentDate,\n dateProfile,\n businessHours: this.parseContextBusinessHours(calendarContext),\n eventSources,\n eventUiBases: {},\n eventStore: (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.I)(),\n renderableEventStore: (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.I)(),\n dateSelection: null,\n eventSelection: '',\n eventDrag: null,\n eventResize: null,\n selectionConfig: this.buildViewUiProps(calendarContext).selectionConfig,\n };\n let contextAndState = Object.assign(Object.assign({}, calendarContext), initialState);\n for (let reducer of optionsData.pluginHooks.reducers) {\n Object.assign(initialState, reducer(null, null, contextAndState));\n }\n if (computeIsLoading(initialState, calendarContext)) {\n this.emitter.trigger('loading', true); // NOT DRY\n }\n this.state = initialState;\n this.updateData();\n this.actionRunner.resume();\n }\n resetOptions(optionOverrides, append) {\n let { props } = this;\n props.optionOverrides = append\n ? Object.assign(Object.assign({}, props.optionOverrides), optionOverrides) : optionOverrides;\n this.actionRunner.request({\n type: 'NOTHING',\n });\n }\n _handleAction(action) {\n let { props, state, emitter } = this;\n let dynamicOptionOverrides = reduceDynamicOptionOverrides(state.dynamicOptionOverrides, action);\n let optionsData = this.computeOptionsData(props.optionOverrides, dynamicOptionOverrides, props.calendarApi);\n let currentViewType = reduceViewType(state.currentViewType, action);\n let currentViewData = this.computeCurrentViewData(currentViewType, optionsData, props.optionOverrides, dynamicOptionOverrides);\n // wire things up\n // TODO: not DRY\n props.calendarApi.currentDataManager = this;\n emitter.setThisContext(props.calendarApi);\n emitter.setOptions(currentViewData.options);\n let calendarContext = {\n dateEnv: optionsData.dateEnv,\n options: optionsData.calendarOptions,\n pluginHooks: optionsData.pluginHooks,\n calendarApi: props.calendarApi,\n dispatch: this.dispatch,\n emitter,\n getCurrentData: this.getCurrentData,\n };\n let { currentDate, dateProfile } = state;\n if (this.data && this.data.dateProfileGenerator !== currentViewData.dateProfileGenerator) { // hack\n dateProfile = currentViewData.dateProfileGenerator.build(currentDate);\n }\n currentDate = (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.J)(currentDate, action);\n dateProfile = reduceDateProfile(dateProfile, action, currentDate, currentViewData.dateProfileGenerator);\n if (action.type === 'PREV' || // TODO: move this logic into DateProfileGenerator\n action.type === 'NEXT' || // \"\n !(0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.H)(dateProfile.currentRange, currentDate)) {\n currentDate = dateProfile.currentRange.start;\n }\n let eventSources = reduceEventSources(state.eventSources, action, dateProfile, calendarContext);\n let eventStore = (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.K)(state.eventStore, action, eventSources, dateProfile, calendarContext);\n let isEventsLoading = computeEventSourcesLoading(eventSources); // BAD. also called in this func in computeIsLoading\n let renderableEventStore = (isEventsLoading && !currentViewData.options.progressiveEventRendering) ?\n (state.renderableEventStore || eventStore) : // try from previous state\n eventStore;\n let { eventUiSingleBase, selectionConfig } = this.buildViewUiProps(calendarContext); // will memoize obj\n let eventUiBySource = this.buildEventUiBySource(eventSources);\n let eventUiBases = this.buildEventUiBases(renderableEventStore.defs, eventUiSingleBase, eventUiBySource);\n let newState = {\n dynamicOptionOverrides,\n currentViewType,\n currentDate,\n dateProfile,\n eventSources,\n eventStore,\n renderableEventStore,\n selectionConfig,\n eventUiBases,\n businessHours: this.parseContextBusinessHours(calendarContext),\n dateSelection: reduceDateSelection(state.dateSelection, action),\n eventSelection: reduceSelectedEvent(state.eventSelection, action),\n eventDrag: reduceEventDrag(state.eventDrag, action),\n eventResize: reduceEventResize(state.eventResize, action),\n };\n let contextAndState = Object.assign(Object.assign({}, calendarContext), newState);\n for (let reducer of optionsData.pluginHooks.reducers) {\n Object.assign(newState, reducer(state, action, contextAndState)); // give the OLD state, for old value\n }\n let wasLoading = computeIsLoading(state, calendarContext);\n let isLoading = computeIsLoading(newState, calendarContext);\n // TODO: use propSetHandlers in plugin system\n if (!wasLoading && isLoading) {\n emitter.trigger('loading', true);\n }\n else if (wasLoading && !isLoading) {\n emitter.trigger('loading', false);\n }\n this.state = newState;\n if (props.onAction) {\n props.onAction(action);\n }\n }\n updateData() {\n let { props, state } = this;\n let oldData = this.data;\n let optionsData = this.computeOptionsData(props.optionOverrides, state.dynamicOptionOverrides, props.calendarApi);\n let currentViewData = this.computeCurrentViewData(state.currentViewType, optionsData, props.optionOverrides, state.dynamicOptionOverrides);\n let data = this.data = Object.assign(Object.assign(Object.assign({ viewTitle: this.buildTitle(state.dateProfile, currentViewData.options, optionsData.dateEnv), calendarApi: props.calendarApi, dispatch: this.dispatch, emitter: this.emitter, getCurrentData: this.getCurrentData }, optionsData), currentViewData), state);\n let changeHandlers = optionsData.pluginHooks.optionChangeHandlers;\n let oldCalendarOptions = oldData && oldData.calendarOptions;\n let newCalendarOptions = optionsData.calendarOptions;\n if (oldCalendarOptions && oldCalendarOptions !== newCalendarOptions) {\n if (oldCalendarOptions.timeZone !== newCalendarOptions.timeZone) {\n // hack\n state.eventSources = data.eventSources = reduceEventSourcesNewTimeZone(data.eventSources, state.dateProfile, data);\n state.eventStore = data.eventStore = (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.L)(data.eventStore, oldData.dateEnv, data.dateEnv);\n }\n for (let optionName in changeHandlers) {\n if (oldCalendarOptions[optionName] !== newCalendarOptions[optionName]) {\n changeHandlers[optionName](newCalendarOptions[optionName], data);\n }\n }\n }\n if (props.onData) {\n props.onData(data);\n }\n }\n _computeOptionsData(optionOverrides, dynamicOptionOverrides, calendarApi) {\n // TODO: blacklist options that are handled by optionChangeHandlers\n let { refinedOptions, pluginHooks, localeDefaults, availableLocaleData, extra, } = this.processRawCalendarOptions(optionOverrides, dynamicOptionOverrides);\n warnUnknownOptions(extra);\n let dateEnv = this.buildDateEnv(refinedOptions.timeZone, refinedOptions.locale, refinedOptions.weekNumberCalculation, refinedOptions.firstDay, refinedOptions.weekText, pluginHooks, availableLocaleData, refinedOptions.defaultRangeSeparator);\n let viewSpecs = this.buildViewSpecs(pluginHooks.views, optionOverrides, dynamicOptionOverrides, localeDefaults);\n let theme = this.buildTheme(refinedOptions, pluginHooks);\n let toolbarConfig = this.parseToolbars(refinedOptions, optionOverrides, theme, viewSpecs, calendarApi);\n return {\n calendarOptions: refinedOptions,\n pluginHooks,\n dateEnv,\n viewSpecs,\n theme,\n toolbarConfig,\n localeDefaults,\n availableRawLocales: availableLocaleData.map,\n };\n }\n // always called from behind a memoizer\n processRawCalendarOptions(optionOverrides, dynamicOptionOverrides) {\n let { locales, locale } = (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.M)([\n _internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.B,\n optionOverrides,\n dynamicOptionOverrides,\n ]);\n let availableLocaleData = this.organizeRawLocales(locales);\n let availableRawLocales = availableLocaleData.map;\n let localeDefaults = this.buildLocale(locale || availableLocaleData.defaultCode, availableRawLocales).options;\n let pluginHooks = this.buildPluginHooks(optionOverrides.plugins || [], globalPlugins);\n let refiners = this.currentCalendarOptionsRefiners = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, _internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.N), _internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.O), _internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.P), pluginHooks.listenerRefiners), pluginHooks.optionRefiners);\n let extra = {};\n let raw = (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.M)([\n _internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.B,\n localeDefaults,\n optionOverrides,\n dynamicOptionOverrides,\n ]);\n let refined = {};\n let currentRaw = this.currentCalendarOptionsInput;\n let currentRefined = this.currentCalendarOptionsRefined;\n let anyChanges = false;\n for (let optionName in raw) {\n if (optionName !== 'plugins') { // because plugins is special-cased\n if (raw[optionName] === currentRaw[optionName] ||\n (_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.Q[optionName] &&\n (optionName in currentRaw) &&\n _internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.Q[optionName](currentRaw[optionName], raw[optionName]))) {\n refined[optionName] = currentRefined[optionName];\n }\n else if (refiners[optionName]) {\n refined[optionName] = refiners[optionName](raw[optionName]);\n anyChanges = true;\n }\n else {\n extra[optionName] = currentRaw[optionName];\n }\n }\n }\n if (anyChanges) {\n this.currentCalendarOptionsInput = raw;\n this.currentCalendarOptionsRefined = refined;\n }\n return {\n rawOptions: this.currentCalendarOptionsInput,\n refinedOptions: this.currentCalendarOptionsRefined,\n pluginHooks,\n availableLocaleData,\n localeDefaults,\n extra,\n };\n }\n _computeCurrentViewData(viewType, optionsData, optionOverrides, dynamicOptionOverrides) {\n let viewSpec = optionsData.viewSpecs[viewType];\n if (!viewSpec) {\n throw new Error(`viewType \"${viewType}\" is not available. Please make sure you've loaded all neccessary plugins`);\n }\n let { refinedOptions, extra } = this.processRawViewOptions(viewSpec, optionsData.pluginHooks, optionsData.localeDefaults, optionOverrides, dynamicOptionOverrides);\n warnUnknownOptions(extra);\n let dateProfileGenerator = this.buildDateProfileGenerator({\n dateProfileGeneratorClass: viewSpec.optionDefaults.dateProfileGeneratorClass,\n duration: viewSpec.duration,\n durationUnit: viewSpec.durationUnit,\n usesMinMaxTime: viewSpec.optionDefaults.usesMinMaxTime,\n dateEnv: optionsData.dateEnv,\n calendarApi: this.props.calendarApi,\n slotMinTime: refinedOptions.slotMinTime,\n slotMaxTime: refinedOptions.slotMaxTime,\n showNonCurrentDates: refinedOptions.showNonCurrentDates,\n dayCount: refinedOptions.dayCount,\n dateAlignment: refinedOptions.dateAlignment,\n dateIncrement: refinedOptions.dateIncrement,\n hiddenDays: refinedOptions.hiddenDays,\n weekends: refinedOptions.weekends,\n nowInput: refinedOptions.now,\n validRangeInput: refinedOptions.validRange,\n visibleRangeInput: refinedOptions.visibleRange,\n monthMode: refinedOptions.monthMode,\n fixedWeekCount: refinedOptions.fixedWeekCount,\n });\n let viewApi = this.buildViewApi(viewType, this.getCurrentData, optionsData.dateEnv);\n return { viewSpec, options: refinedOptions, dateProfileGenerator, viewApi };\n }\n processRawViewOptions(viewSpec, pluginHooks, localeDefaults, optionOverrides, dynamicOptionOverrides) {\n let raw = (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.M)([\n _internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.B,\n viewSpec.optionDefaults,\n localeDefaults,\n optionOverrides,\n viewSpec.optionOverrides,\n dynamicOptionOverrides,\n ]);\n let refiners = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, _internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.N), _internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.O), _internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.P), _internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.R), pluginHooks.listenerRefiners), pluginHooks.optionRefiners);\n let refined = {};\n let currentRaw = this.currentViewOptionsInput;\n let currentRefined = this.currentViewOptionsRefined;\n let anyChanges = false;\n let extra = {};\n for (let optionName in raw) {\n if (raw[optionName] === currentRaw[optionName] ||\n (_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.Q[optionName] &&\n _internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.Q[optionName](raw[optionName], currentRaw[optionName]))) {\n refined[optionName] = currentRefined[optionName];\n }\n else {\n if (raw[optionName] === this.currentCalendarOptionsInput[optionName] ||\n (_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.Q[optionName] &&\n _internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.Q[optionName](raw[optionName], this.currentCalendarOptionsInput[optionName]))) {\n if (optionName in this.currentCalendarOptionsRefined) { // might be an \"extra\" prop\n refined[optionName] = this.currentCalendarOptionsRefined[optionName];\n }\n }\n else if (refiners[optionName]) {\n refined[optionName] = refiners[optionName](raw[optionName]);\n }\n else {\n extra[optionName] = raw[optionName];\n }\n anyChanges = true;\n }\n }\n if (anyChanges) {\n this.currentViewOptionsInput = raw;\n this.currentViewOptionsRefined = refined;\n }\n return {\n rawOptions: this.currentViewOptionsInput,\n refinedOptions: this.currentViewOptionsRefined,\n extra,\n };\n }\n}\nfunction buildDateEnv$1(timeZone, explicitLocale, weekNumberCalculation, firstDay, weekText, pluginHooks, availableLocaleData, defaultSeparator) {\n let locale = buildLocale(explicitLocale || availableLocaleData.defaultCode, availableLocaleData.map);\n return new _internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.S({\n calendarSystem: 'gregory',\n timeZone,\n namedTimeZoneImpl: pluginHooks.namedTimeZonedImpl,\n locale,\n weekNumberCalculation,\n firstDay,\n weekText,\n cmdFormatter: pluginHooks.cmdFormatter,\n defaultSeparator,\n });\n}\nfunction buildTheme(options, pluginHooks) {\n let ThemeClass = pluginHooks.themeClasses[options.themeSystem] || StandardTheme;\n return new ThemeClass(options);\n}\nfunction buildDateProfileGenerator(props) {\n let DateProfileGeneratorClass = props.dateProfileGeneratorClass || _internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.U;\n return new DateProfileGeneratorClass(props);\n}\nfunction buildViewApi(type, getCurrentData, dateEnv) {\n return new ViewImpl(type, getCurrentData, dateEnv);\n}\nfunction buildEventUiBySource(eventSources) {\n return (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.b)(eventSources, (eventSource) => eventSource.ui);\n}\nfunction buildEventUiBases(eventDefs, eventUiSingleBase, eventUiBySource) {\n let eventUiBases = { '': eventUiSingleBase };\n for (let defId in eventDefs) {\n let def = eventDefs[defId];\n if (def.sourceId && eventUiBySource[def.sourceId]) {\n eventUiBases[defId] = eventUiBySource[def.sourceId];\n }\n }\n return eventUiBases;\n}\nfunction buildViewUiProps(calendarContext) {\n let { options } = calendarContext;\n return {\n eventUiSingleBase: (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.W)({\n display: options.eventDisplay,\n editable: options.editable,\n startEditable: options.eventStartEditable,\n durationEditable: options.eventDurationEditable,\n constraint: options.eventConstraint,\n overlap: typeof options.eventOverlap === 'boolean' ? options.eventOverlap : undefined,\n allow: options.eventAllow,\n backgroundColor: options.eventBackgroundColor,\n borderColor: options.eventBorderColor,\n textColor: options.eventTextColor,\n color: options.eventColor,\n // classNames: options.eventClassNames // render hook will handle this\n }, calendarContext),\n selectionConfig: (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.W)({\n constraint: options.selectConstraint,\n overlap: typeof options.selectOverlap === 'boolean' ? options.selectOverlap : undefined,\n allow: options.selectAllow,\n }, calendarContext),\n };\n}\nfunction computeIsLoading(state, context) {\n for (let isLoadingFunc of context.pluginHooks.isLoadingFuncs) {\n if (isLoadingFunc(state)) {\n return true;\n }\n }\n return false;\n}\nfunction parseContextBusinessHours(calendarContext) {\n return (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.X)(calendarContext.options.businessHours, calendarContext);\n}\nfunction warnUnknownOptions(options, viewName) {\n for (let optionName in options) {\n console.warn(`Unknown option '${optionName}'` +\n (viewName ? ` for view '${viewName}'` : ''));\n }\n}\n\nclass ToolbarSection extends _internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.Y {\n render() {\n let children = this.props.widgetGroups.map((widgetGroup) => this.renderWidgetGroup(widgetGroup));\n return (0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)('div', { className: 'fc-toolbar-chunk' }, ...children);\n }\n renderWidgetGroup(widgetGroup) {\n let { props } = this;\n let { theme } = this.context;\n let children = [];\n let isOnlyButtons = true;\n for (let widget of widgetGroup) {\n let { buttonName, buttonClick, buttonText, buttonIcon, buttonHint } = widget;\n if (buttonName === 'title') {\n isOnlyButtons = false;\n children.push((0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"h2\", { className: \"fc-toolbar-title\", id: props.titleId }, props.title));\n }\n else {\n let isPressed = buttonName === props.activeButton;\n let isDisabled = (!props.isTodayEnabled && buttonName === 'today') ||\n (!props.isPrevEnabled && buttonName === 'prev') ||\n (!props.isNextEnabled && buttonName === 'next');\n let buttonClasses = [`fc-${buttonName}-button`, theme.getClass('button')];\n if (isPressed) {\n buttonClasses.push(theme.getClass('buttonActive'));\n }\n children.push((0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"button\", { type: \"button\", title: typeof buttonHint === 'function' ? buttonHint(props.navUnit) : buttonHint, disabled: isDisabled, \"aria-pressed\": isPressed, className: buttonClasses.join(' '), onClick: buttonClick }, buttonText || (buttonIcon ? (0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"span\", { className: buttonIcon }) : '')));\n }\n }\n if (children.length > 1) {\n let groupClassName = (isOnlyButtons && theme.getClass('buttonGroup')) || '';\n return (0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)('div', { className: groupClassName }, ...children);\n }\n return children[0];\n }\n}\n\nclass Toolbar extends _internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.Y {\n render() {\n let { model, extraClassName } = this.props;\n let forceLtr = false;\n let startContent;\n let endContent;\n let sectionWidgets = model.sectionWidgets;\n let centerContent = sectionWidgets.center;\n if (sectionWidgets.left) {\n forceLtr = true;\n startContent = sectionWidgets.left;\n }\n else {\n startContent = sectionWidgets.start;\n }\n if (sectionWidgets.right) {\n forceLtr = true;\n endContent = sectionWidgets.right;\n }\n else {\n endContent = sectionWidgets.end;\n }\n let classNames = [\n extraClassName || '',\n 'fc-toolbar',\n forceLtr ? 'fc-toolbar-ltr' : '',\n ];\n return ((0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"div\", { className: classNames.join(' ') },\n this.renderSection('start', startContent || []),\n this.renderSection('center', centerContent || []),\n this.renderSection('end', endContent || [])));\n }\n renderSection(key, widgetGroups) {\n let { props } = this;\n return ((0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(ToolbarSection, { key: key, widgetGroups: widgetGroups, title: props.title, navUnit: props.navUnit, activeButton: props.activeButton, isTodayEnabled: props.isTodayEnabled, isPrevEnabled: props.isPrevEnabled, isNextEnabled: props.isNextEnabled, titleId: props.titleId }));\n }\n}\n\n// TODO: do function component?\nclass ViewContainer extends _internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.Y {\n constructor() {\n super(...arguments);\n this.state = {\n availableWidth: null,\n };\n this.handleEl = (el) => {\n this.el = el;\n (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.Z)(this.props.elRef, el);\n this.updateAvailableWidth();\n };\n this.handleResize = () => {\n this.updateAvailableWidth();\n };\n }\n render() {\n let { props, state } = this;\n let { aspectRatio } = props;\n let classNames = [\n 'fc-view-harness',\n (aspectRatio || props.liquid || props.height)\n ? 'fc-view-harness-active' // harness controls the height\n : 'fc-view-harness-passive', // let the view do the height\n ];\n let height = '';\n let paddingBottom = '';\n if (aspectRatio) {\n if (state.availableWidth !== null) {\n height = state.availableWidth / aspectRatio;\n }\n else {\n // while waiting to know availableWidth, we can't set height to *zero*\n // because will cause lots of unnecessary scrollbars within scrollgrid.\n // BETTER: don't start rendering ANYTHING yet until we know container width\n // NOTE: why not always use paddingBottom? Causes height oscillation (issue 5606)\n paddingBottom = `${(1 / aspectRatio) * 100}%`;\n }\n }\n else {\n height = props.height || '';\n }\n return ((0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"div\", { \"aria-labelledby\": props.labeledById, ref: this.handleEl, className: classNames.join(' '), style: { height, paddingBottom } }, props.children));\n }\n componentDidMount() {\n this.context.addResizeHandler(this.handleResize);\n }\n componentWillUnmount() {\n this.context.removeResizeHandler(this.handleResize);\n }\n updateAvailableWidth() {\n if (this.el && // needed. but why?\n this.props.aspectRatio // aspectRatio is the only height setting that needs availableWidth\n ) {\n this.setState({ availableWidth: this.el.offsetWidth });\n }\n }\n}\n\n/*\nDetects when the user clicks on an event within a DateComponent\n*/\nclass EventClicking extends _internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__._ {\n constructor(settings) {\n super(settings);\n this.handleSegClick = (ev, segEl) => {\n let { component } = this;\n let { context } = component;\n let seg = (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.$)(segEl);\n if (seg && // might be the
surrounding the more link\n component.isValidSegDownEl(ev.target)) {\n // our way to simulate a link click for elements that can't be tags\n // grab before trigger fired in case trigger trashes DOM thru rerendering\n let hasUrlContainer = (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.a0)(ev.target, '.fc-event-forced-url');\n let url = hasUrlContainer ? hasUrlContainer.querySelector('a[href]').href : '';\n context.emitter.trigger('eventClick', {\n el: segEl,\n event: new _internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.a1(component.context, seg.eventRange.def, seg.eventRange.instance),\n jsEvent: ev,\n view: context.viewApi,\n });\n if (url && !ev.defaultPrevented) {\n window.location.href = url;\n }\n }\n };\n this.destroy = (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.a2)(settings.el, 'click', '.fc-event', // on both fg and bg events\n this.handleSegClick);\n }\n}\n\n/*\nTriggers events and adds/removes core classNames when the user's pointer\nenters/leaves event-elements of a component.\n*/\nclass EventHovering extends _internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__._ {\n constructor(settings) {\n super(settings);\n // for simulating an eventMouseLeave when the event el is destroyed while mouse is over it\n this.handleEventElRemove = (el) => {\n if (el === this.currentSegEl) {\n this.handleSegLeave(null, this.currentSegEl);\n }\n };\n this.handleSegEnter = (ev, segEl) => {\n if ((0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.$)(segEl)) { // TODO: better way to make sure not hovering over more+ link or its wrapper\n this.currentSegEl = segEl;\n this.triggerEvent('eventMouseEnter', ev, segEl);\n }\n };\n this.handleSegLeave = (ev, segEl) => {\n if (this.currentSegEl) {\n this.currentSegEl = null;\n this.triggerEvent('eventMouseLeave', ev, segEl);\n }\n };\n this.removeHoverListeners = (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.a3)(settings.el, '.fc-event', // on both fg and bg events\n this.handleSegEnter, this.handleSegLeave);\n }\n destroy() {\n this.removeHoverListeners();\n }\n triggerEvent(publicEvName, ev, segEl) {\n let { component } = this;\n let { context } = component;\n let seg = (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.$)(segEl);\n if (!ev || component.isValidSegDownEl(ev.target)) {\n context.emitter.trigger(publicEvName, {\n el: segEl,\n event: new _internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.a1(context, seg.eventRange.def, seg.eventRange.instance),\n jsEvent: ev,\n view: context.viewApi,\n });\n }\n }\n}\n\nclass CalendarContent extends _internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.a4 {\n constructor() {\n super(...arguments);\n this.buildViewContext = (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.z)(_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.a5);\n this.buildViewPropTransformers = (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.z)(buildViewPropTransformers);\n this.buildToolbarProps = (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.z)(buildToolbarProps);\n this.headerRef = (0,preact__WEBPACK_IMPORTED_MODULE_1__.createRef)();\n this.footerRef = (0,preact__WEBPACK_IMPORTED_MODULE_1__.createRef)();\n this.interactionsStore = {};\n // eslint-disable-next-line\n this.state = {\n viewLabelId: (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.a6)(),\n };\n // Component Registration\n // -----------------------------------------------------------------------------------------------------------------\n this.registerInteractiveComponent = (component, settingsInput) => {\n let settings = (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.a7)(component, settingsInput);\n let DEFAULT_INTERACTIONS = [\n EventClicking,\n EventHovering,\n ];\n let interactionClasses = DEFAULT_INTERACTIONS.concat(this.props.pluginHooks.componentInteractions);\n let interactions = interactionClasses.map((TheInteractionClass) => new TheInteractionClass(settings));\n this.interactionsStore[component.uid] = interactions;\n _internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.a8[component.uid] = settings;\n };\n this.unregisterInteractiveComponent = (component) => {\n let listeners = this.interactionsStore[component.uid];\n if (listeners) {\n for (let listener of listeners) {\n listener.destroy();\n }\n delete this.interactionsStore[component.uid];\n }\n delete _internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.a8[component.uid];\n };\n // Resizing\n // -----------------------------------------------------------------------------------------------------------------\n this.resizeRunner = new _internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.D(() => {\n this.props.emitter.trigger('_resize', true); // should window resizes be considered \"forced\" ?\n this.props.emitter.trigger('windowResize', { view: this.props.viewApi });\n });\n this.handleWindowResize = (ev) => {\n let { options } = this.props;\n if (options.handleWindowResize &&\n ev.target === window // avoid jqui events\n ) {\n this.resizeRunner.request(options.windowResizeDelay);\n }\n };\n }\n /*\n renders INSIDE of an outer div\n */\n render() {\n let { props } = this;\n let { toolbarConfig, options } = props;\n let toolbarProps = this.buildToolbarProps(props.viewSpec, props.dateProfile, props.dateProfileGenerator, props.currentDate, (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.a9)(props.options.now, props.dateEnv), // TODO: use NowTimer????\n props.viewTitle);\n let viewVGrow = false;\n let viewHeight = '';\n let viewAspectRatio;\n if (props.isHeightAuto || props.forPrint) {\n viewHeight = '';\n }\n else if (options.height != null) {\n viewVGrow = true;\n }\n else if (options.contentHeight != null) {\n viewHeight = options.contentHeight;\n }\n else {\n viewAspectRatio = Math.max(options.aspectRatio, 0.5); // prevent from getting too tall\n }\n let viewContext = this.buildViewContext(props.viewSpec, props.viewApi, props.options, props.dateProfileGenerator, props.dateEnv, props.theme, props.pluginHooks, props.dispatch, props.getCurrentData, props.emitter, props.calendarApi, this.registerInteractiveComponent, this.unregisterInteractiveComponent);\n let viewLabelId = (toolbarConfig.header && toolbarConfig.header.hasTitle)\n ? this.state.viewLabelId\n : '';\n return ((0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.V.Provider, { value: viewContext },\n toolbarConfig.header && ((0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(Toolbar, Object.assign({ ref: this.headerRef, extraClassName: \"fc-header-toolbar\", model: toolbarConfig.header, titleId: viewLabelId }, toolbarProps))),\n (0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(ViewContainer, { liquid: viewVGrow, height: viewHeight, aspectRatio: viewAspectRatio, labeledById: viewLabelId },\n this.renderView(props),\n this.buildAppendContent()),\n toolbarConfig.footer && ((0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(Toolbar, Object.assign({ ref: this.footerRef, extraClassName: \"fc-footer-toolbar\", model: toolbarConfig.footer, titleId: \"\" }, toolbarProps)))));\n }\n componentDidMount() {\n let { props } = this;\n this.calendarInteractions = props.pluginHooks.calendarInteractions\n .map((CalendarInteractionClass) => new CalendarInteractionClass(props));\n window.addEventListener('resize', this.handleWindowResize);\n let { propSetHandlers } = props.pluginHooks;\n for (let propName in propSetHandlers) {\n propSetHandlers[propName](props[propName], props);\n }\n }\n componentDidUpdate(prevProps) {\n let { props } = this;\n let { propSetHandlers } = props.pluginHooks;\n for (let propName in propSetHandlers) {\n if (props[propName] !== prevProps[propName]) {\n propSetHandlers[propName](props[propName], props);\n }\n }\n }\n componentWillUnmount() {\n window.removeEventListener('resize', this.handleWindowResize);\n this.resizeRunner.clear();\n for (let interaction of this.calendarInteractions) {\n interaction.destroy();\n }\n this.props.emitter.trigger('_unmount');\n }\n buildAppendContent() {\n let { props } = this;\n let children = props.pluginHooks.viewContainerAppends.map((buildAppendContent) => buildAppendContent(props));\n return (0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(preact__WEBPACK_IMPORTED_MODULE_1__.Fragment, {}, ...children);\n }\n renderView(props) {\n let { pluginHooks } = props;\n let { viewSpec } = props;\n let viewProps = {\n dateProfile: props.dateProfile,\n businessHours: props.businessHours,\n eventStore: props.renderableEventStore,\n eventUiBases: props.eventUiBases,\n dateSelection: props.dateSelection,\n eventSelection: props.eventSelection,\n eventDrag: props.eventDrag,\n eventResize: props.eventResize,\n isHeightAuto: props.isHeightAuto,\n forPrint: props.forPrint,\n };\n let transformers = this.buildViewPropTransformers(pluginHooks.viewPropsTransformers);\n for (let transformer of transformers) {\n Object.assign(viewProps, transformer.transform(viewProps, props));\n }\n let ViewComponent = viewSpec.component;\n return ((0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(ViewComponent, Object.assign({}, viewProps)));\n }\n}\nfunction buildToolbarProps(viewSpec, dateProfile, dateProfileGenerator, currentDate, now, title) {\n // don't force any date-profiles to valid date profiles (the `false`) so that we can tell if it's invalid\n let todayInfo = dateProfileGenerator.build(now, undefined, false); // TODO: need `undefined` or else INFINITE LOOP for some reason\n let prevInfo = dateProfileGenerator.buildPrev(dateProfile, currentDate, false);\n let nextInfo = dateProfileGenerator.buildNext(dateProfile, currentDate, false);\n return {\n title,\n activeButton: viewSpec.type,\n navUnit: viewSpec.singleUnit,\n isTodayEnabled: todayInfo.isValid && !(0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.H)(dateProfile.currentRange, now),\n isPrevEnabled: prevInfo.isValid,\n isNextEnabled: nextInfo.isValid,\n };\n}\n// Plugin\n// -----------------------------------------------------------------------------------------------------------------\nfunction buildViewPropTransformers(theClasses) {\n return theClasses.map((TheClass) => new TheClass());\n}\n\nclass Calendar extends _internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.aa {\n constructor(el, optionOverrides = {}) {\n super();\n this.isRendering = false;\n this.isRendered = false;\n this.currentClassNames = [];\n this.customContentRenderId = 0;\n this.handleAction = (action) => {\n // actions we know we want to render immediately\n switch (action.type) {\n case 'SET_EVENT_DRAG':\n case 'SET_EVENT_RESIZE':\n this.renderRunner.tryDrain();\n }\n };\n this.handleData = (data) => {\n this.currentData = data;\n this.renderRunner.request(data.calendarOptions.rerenderDelay);\n };\n this.handleRenderRequest = () => {\n if (this.isRendering) {\n this.isRendered = true;\n let { currentData } = this;\n (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.ab)(() => {\n (0,preact__WEBPACK_IMPORTED_MODULE_1__.render)((0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.ac, { options: currentData.calendarOptions, theme: currentData.theme, emitter: currentData.emitter }, (classNames, height, isHeightAuto, forPrint) => {\n this.setClassNames(classNames);\n this.setHeight(height);\n return ((0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.ad.Provider, { value: this.customContentRenderId },\n (0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(CalendarContent, Object.assign({ isHeightAuto: isHeightAuto, forPrint: forPrint }, currentData))));\n }), this.el);\n });\n }\n else if (this.isRendered) {\n this.isRendered = false;\n (0,preact__WEBPACK_IMPORTED_MODULE_1__.render)(null, this.el);\n this.setClassNames([]);\n this.setHeight('');\n }\n };\n this.el = el;\n this.renderRunner = new _internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.D(this.handleRenderRequest);\n new CalendarDataManager({\n optionOverrides,\n calendarApi: this,\n onAction: this.handleAction,\n onData: this.handleData,\n });\n }\n render() {\n let wasRendering = this.isRendering;\n if (!wasRendering) {\n this.isRendering = true;\n }\n else {\n this.customContentRenderId += 1;\n }\n this.renderRunner.request();\n if (wasRendering) {\n this.updateSize();\n }\n }\n destroy() {\n if (this.isRendering) {\n this.isRendering = false;\n this.renderRunner.request();\n }\n }\n updateSize() {\n (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.ab)(() => {\n super.updateSize();\n });\n }\n batchRendering(func) {\n this.renderRunner.pause('batchRendering');\n func();\n this.renderRunner.resume('batchRendering');\n }\n pauseRendering() {\n this.renderRunner.pause('pauseRendering');\n }\n resumeRendering() {\n this.renderRunner.resume('pauseRendering', true);\n }\n resetOptions(optionOverrides, append) {\n this.currentDataManager.resetOptions(optionOverrides, append);\n }\n setClassNames(classNames) {\n if (!(0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.a)(classNames, this.currentClassNames)) {\n let { classList } = this.el;\n for (let className of this.currentClassNames) {\n classList.remove(className);\n }\n for (let className of classNames) {\n classList.add(className);\n }\n this.currentClassNames = classNames;\n }\n }\n setHeight(height) {\n (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.ae)(this.el, 'height', height);\n }\n}\n\nfunction formatDate(dateInput, options = {}) {\n let dateEnv = buildDateEnv(options);\n let formatter = (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.x)(options);\n let dateMeta = dateEnv.createMarkerMeta(dateInput);\n if (!dateMeta) { // TODO: warning?\n return '';\n }\n return dateEnv.format(dateMeta.marker, formatter, {\n forcedTzo: dateMeta.forcedTzo,\n });\n}\nfunction formatRange(startInput, endInput, options) {\n let dateEnv = buildDateEnv(typeof options === 'object' && options ? options : {}); // pass in if non-null object\n let formatter = (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.x)(options);\n let startMeta = dateEnv.createMarkerMeta(startInput);\n let endMeta = dateEnv.createMarkerMeta(endInput);\n if (!startMeta || !endMeta) { // TODO: warning?\n return '';\n }\n return dateEnv.formatRange(startMeta.marker, endMeta.marker, formatter, {\n forcedStartTzo: startMeta.forcedTzo,\n forcedEndTzo: endMeta.forcedTzo,\n isEndExclusive: options.isEndExclusive,\n defaultSeparator: _internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.B.defaultRangeSeparator,\n });\n}\n// TODO: more DRY and optimized\nfunction buildDateEnv(settings) {\n let locale = buildLocale(settings.locale || 'en', organizeRawLocales([]).map); // TODO: don't hardcode 'en' everywhere\n return new _internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.S(Object.assign(Object.assign({ timeZone: _internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.B.timeZone, calendarSystem: 'gregory' }, settings), { locale }));\n}\n\n// HELPERS\n/*\nif nextDayThreshold is specified, slicing is done in an all-day fashion.\nyou can get nextDayThreshold from context.nextDayThreshold\n*/\nfunction sliceEvents(props, allDay) {\n return (0,_internal_common_esm_js__WEBPACK_IMPORTED_MODULE_0__.af)(props.eventStore, props.eventUiBases, props.dateProfile.activeRange, allDay ? props.nextDayThreshold : null).fg;\n}\n\nconst version = '6.0.3';\n\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvQGZ1bGxjYWxlbmRhci9jb3JlL2luZGV4LmVzbS5qcy5qcyIsIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7QUFBZ2lEO0FBQzk5QztBQUNFO0FBQzdDOztBQUV2QixzQkFBc0IsMkJBQTJCLHdCQUF3Qix3Q0FBd0MsNkJBQTZCLHVCQUF1Qiw0QkFBNEIsNkJBQTZCLGlDQUFpQyxtQ0FBbUMsdUNBQXVDLG9DQUFvQyx3Q0FBd0MsNEJBQTRCLGdDQUFnQywyQkFBMkIsa0RBQWtELGdDQUFnQyxrQ0FBa0MsaUNBQWlDLHVDQUF1Qyx3Q0FBd0MsMENBQTBDLDRCQUE0QiwwQkFBMEIsMENBQTBDLHlDQUF5Qyw2QkFBNkIsMENBQTBDLG1CQUFtQixpQkFBaUIsMkJBQTJCLDBDQUEwQyx5QkFBeUIsc0JBQXNCLGlCQUFpQixJQUFJLGFBQWEsc0JBQXNCLGNBQWMsaUNBQWlDLHNCQUFzQixVQUFVLHlCQUF5QixpQkFBaUIsY0FBYyxPQUFPLGtCQUFrQixjQUFjLFVBQVUsbUJBQW1CLG9CQUFvQixlQUFlLDBCQUEwQiwwQkFBMEIsa0JBQWtCLGNBQWMsZ0JBQWdCLGtCQUFrQixjQUFjLGlCQUFpQiw0Q0FBNEMsd0NBQXdDLHNDQUFzQyxrQkFBa0IsV0FBVyxvQkFBb0Isa0JBQWtCLGdCQUFnQixzQ0FBc0MsY0FBYyw0akdBQTRqRyxTQUFTLFdBQVcsbUNBQW1DLGtDQUFrQyxxQkFBcUIsOEJBQThCLGtCQUFrQixvQkFBb0IsZ0JBQWdCLFdBQVcsY0FBYyxrQkFBa0Isb0JBQW9CLHlCQUF5QixzQkFBc0IsaUJBQWlCLFVBQVUsNkJBQTZCLG1CQUFtQiw4QkFBOEIsbUJBQW1CLDhCQUE4QixtQkFBbUIsK0JBQStCLG1CQUFtQiw2QkFBNkIsbUJBQW1CLDRCQUE0QixtQkFBbUIsa0JBQWtCLG1CQUFtQixlQUFlLGdCQUFnQixvQkFBb0Isa0JBQWtCLG9CQUFvQixTQUFTLGlCQUFpQixvQkFBb0IscUJBQXFCLG1CQUFtQiwwQ0FBMEMsZUFBZSwwQkFB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Q0Esb0JBQW9CLDBEQUFlO0FBQ25DO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxvRkFBb0YsR0FBRztBQUN2RixvQkFBb0IsMERBQWU7QUFDbkM7QUFDQTtBQUNBLGtDQUFrQztBQUNsQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwQkFBMEIsNEVBQTBDO0FBQ3BFLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxtRkFBbUY7QUFDbkYsZUFBZSxzREFBTywrQkFBK0IsVUFBVSwrREFBNkIsNkJBQTZCLGVBQWUsUUFBUTtBQUNoSjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLDJEQUFlO0FBQzFCOztBQUVBOztBQUUrRyIsInNvdXJjZXMiOlsid2VicGFjazovL1Z1ZXh5Ly4vbm9kZV9tb2R1bGVzL0BmdWxsY2FsZW5kYXIvY29yZS9pbmRleC5lc20uanM/ZDc5NCJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBpIGFzIGluamVjdFN0eWxlcywgbSBhcyBtZXJnZVByb3BzLCBnIGFzIGd1aWQsIGEgYXMgaXNBcnJheXNFcXVhbCwgVCBhcyBUaGVtZSwgYiBhcyBtYXBIYXNoLCBWIGFzIFZpZXdDb250ZXh0VHlwZSwgQyBhcyBDb250ZW50Q29udGFpbmVyLCBjIGFzIGJ1aWxkVmlld0NsYXNzTmFtZXMsIGQgYXMgZ3JlYXRlc3REdXJhdGlvbkRlbm9taW5hdG9yLCBlIGFzIGNyZWF0ZUR1cmF0aW9uLCBCIGFzIEJBU0VfT1BUSU9OX0RFRkFVTFRTLCBmIGFzIGFycmF5VG9IYXNoLCBoIGFzIGZpbHRlckhhc2gsIGogYXMgYnVpbGRFdmVudFNvdXJjZVJlZmluZXJzLCBwIGFzIHBhcnNlRXZlbnRTb3VyY2UsIGsgYXMgZm9ybWF0V2l0aE9yZGluYWxzLCB1IGFzIHVucHJvbWlzaWZ5LCBsIGFzIGJ1aWxkUmFuZ2VBcGlXaXRoVGltZVpvbmUsIG4gYXMgaWRlbnRpdHksIHIgYXMgcmVxdWVzdEpzb24sIHMgYXMgc3VidHJhY3REdXJhdGlvbnMsIG8gYXMgaW50ZXJzZWN0UmFuZ2VzLCBxIGFzIHN0YXJ0T2ZEYXksIHQgYXMgYWRkRGF5cywgdiBhcyBoYXNoVmFsdWVzVG9BcnJheSwgdyBhcyBidWlsZEV2ZW50QXBpcywgRCBhcyBEZWxheWVkUnVubmVyLCB4IGFzIGNyZWF0ZUZvcm1hdHRlciwgeSBhcyBkaWZmV2hvbGVEYXlzLCB6IGFzIG1lbW9pemUsIEEgYXMgbWVtb2l6ZU9iakFyZywgRSBhcyBpc1Byb3BzRXF1YWwsIEYgYXMgRW1pdHRlciwgRyBhcyBnZXRJbml0aWFsRGF0ZSwgSCBhcyByYW5nZUNvbnRhaW5zTWFya2VyLCBJIGFzIGNyZWF0ZUVtcHR5RXZlbnRTdG9yZSwgSiBhcyByZWR1Y2VDdXJyZW50RGF0ZSwgSyBhcyByZWR1Y2VFdmVudFN0b3JlLCBMIGFzIHJlem9uZUV2ZW50U3RvcmVEYXRlcywgTSBhcyBtZXJnZVJhd09wdGlvbnMsIE4gYXMgQkFTRV9PUFRJT05fUkVGSU5FUlMsIE8gYXMgQ0FMRU5EQVJfTElTVEVORVJfUkVGSU5FUlMsIFAgYXMgQ0FMRU5EQVJfT1BUSU9OX1JFRklORVJTLCBRIGFzIENPTVBMRVhfT1BUSU9OX0NPTVBBUkFUT1JTLCBSIGFzIFZJRVdfT1BUSU9OX1JFRklORVJTLCBTIGFzIERhdGVFbnYsIFUgYXMgRGF0ZVByb2ZpbGVHZW5lcmF0b3IsIFcgYXMgY3JlYXRlRXZlbnRVaSwgWCBhcyBwYXJzZUJ1c2luZXNzSG91cnMsIFkgYXMgQmFzZUNvbXBvbmVudCwgWiBhcyBzZXRSZWYsIF8gYXMgSW50ZXJhY3Rpb24sICQgYXMgZ2V0RWxTZWcsIGEwIGFzIGVsZW1lbnRDbG9zZXN0LCBhMSBhcyBFdmVudEltcGwsIGEyIGFzIGxpc3RlbkJ5U2VsZWN0b3IsIGEzIGFzIGxpc3RlblRvSG92ZXJCeVNlbGVjdG9yLCBhNCBhcyBQdXJlQ29tcG9uZW50LCBhNSBhcyBidWlsZFZpZXdDb250ZXh0LCBhNiBhcyBnZXRVbmlxdWVEb21JZCwgYTcgYXMgcGFyc2VJbnRlcmFjdGlvblNldHRpbmdzLCBhOCBhcyBpbnRlcmFjdGlvblNldHRpbmdzU3RvcmUsIGE5IGFzIGdldE5vdywgYWEgYXMgQ2FsZW5kYXJJbXBsLCBhYiBhcyBmbHVzaFN5bmMsIGFjIGFzIENhbGVuZGFyUm9vdCwgYWQgYXMgUmVuZGVySWQsIGFlIGFzIGFwcGx5U3R5bGVQcm9wLCBhZiBhcyBzbGljZUV2ZW50U3RvcmUgfSBmcm9tICcuL2ludGVybmFsLWNvbW1vbi5lc20uanMnO1xuZXhwb3J0IHsgYWcgYXMgSnNvblJlcXVlc3RFcnJvciB9IGZyb20gJy4vaW50ZXJuYWwtY29tbW9uLmVzbS5qcyc7XG5pbXBvcnQgeyBjcmVhdGVFbGVtZW50LCBjcmVhdGVSZWYsIEZyYWdtZW50LCByZW5kZXIgfSBmcm9tICdwcmVhY3QnO1xuaW1wb3J0ICdwcmVhY3QvY29tcGF0JztcblxudmFyIGNzc18yNDh6ID0gXCI6cm9vdHstLWZjLXNtYWxsLWZvbnQtc2l6ZTouODVlbTstLWZjLXBhZ2UtYmctY29sb3I6I2ZmZjstLWZjLW5ldXRyYWwtYmctY29sb3I6aHNsYSgwLDAlLDgyJSwuMyk7LS1mYy1uZXV0cmFsLXRleHQtY29sb3I6Z3JleTstLWZjLWJvcmRlci1jb2xvcjojZGRkOy0tZmMtYnV0dG9uLXRleHQtY29sb3I6I2ZmZjstLWZjLWJ1dHRvbi1iZy1jb2xvcjojMmMzZTUwOy0tZmMtYnV0dG9uLWJvcmRlci1jb2xvcjojMmMzZTUwOy0tZmMtYnV0dG9uLWhvdmVyLWJnLWNvbG9yOiMxZTJiMzc7LS1mYy1idXR0b24taG92ZXItYm9yZGVyLWNvbG9yOiMxYTI1MmY7LS1mYy1idXR0b24tYWN0aXZlLWJnLWNvbG9yOiMxYTI1MmY7LS1mYy1idXR0b24tYWN0aXZlLWJvcmRlci1jb2xvcjojMTUxZTI3Oy0tZmMtZXZlbnQtYmctY29sb3I6IzM3ODhkODstLWZjLWV2ZW50LWJvcmRlci1jb2xvcjojMzc4OGQ4Oy0tZmMtZXZlbnQtdGV4dC1jb2xvcjojZmZmOy0tZmMtZXZlbnQtc2VsZWN0ZWQtb3ZlcmxheS1jb2xvcjpyZ2JhKDAsMCwwLC4yNSk7LS1mYy1tb3JlLWxpbmstYmctY29sb3I6I2QwZDBkMDstLWZjLW1vcmUtbGluay10ZXh0LWNvbG9yOmluaGVyaXQ7LS1mYy1ldmVudC1yZXNpemVyLXRoaWNrbmVzczo4cHg7LS1mYy1ldmVudC1yZXNpemVyLWRvdC10b3RhbC13aWR0aDo4cHg7LS1mYy1ldmVudC1yZXNpemVyLWRvdC1ib3JkZXItd2lkdGg6MXB4Oy0tZmMtbm9uLWJ1c2luZXNzLWNvbG9yOmhzbGEoMCwwJSw4NCUsLjMpOy0tZmMtYmctZXZlbnQtY29sb3I6IzhmZGY4MjstLWZjLWJnLWV2ZW50LW9wYWNpdHk6MC4zOy0tZmMtaGlnaGxpZ2h0LWNvbG9yOnJnYmEoMTg4LDIzMiwyNDEsLjMpOy0tZmMtdG9kYXktYmctY29sb3I6cmdiYSgyNTUsMjIwLDQwLC4xNSk7LS1mYy1ub3ctaW5kaWNhdG9yLWNvbG9yOnJlZH0uZmMtbm90LWFsbG93ZWQsLmZjLW5vdC1hbGxvd2VkIC5mYy1ldmVudHtjdXJzb3I6bm90LWFsbG93ZWR9LmZjLXVuc2VsZWN0YWJsZXstd2Via2l0LXRvdWNoLWNhbGxvdXQ6bm9uZTstd2Via2l0LXRhcC1oaWdobGlnaHQtY29sb3I6cmdiYSgwLDAsMCwwKTstd2Via2l0LXVzZXItc2VsZWN0Om5vbmU7LW1vei11c2VyLXNlbGVjdDpub25lO3VzZXItc2VsZWN0Om5vbmV9LmZje2Rpc3BsYXk6ZmxleDtmbGV4LWRpcmVjdGlvbjpjb2x1bW47Zm9udC1zaXplOjFlbX0uZmMsLmZjICosLmZjIDphZnRlciwuZmMgOmJlZm9yZXtib3gtc2l6aW5nOmJvcmRlci1ib3h9LmZjIHRhYmxle2JvcmRlci1jb2xsYXBzZTpjb2xsYXBzZTtib3JkZXItc3BhY2luZzowO2ZvbnQtc2l6ZToxZW19LmZjIHRoe3RleHQtYWxpZ246Y2VudGVyfS5mYyB0ZCwuZmMgdGh7cGFkZGluZzowO3ZlcnRpY2FsLWFsaWduOnRvcH0uZmMgYVtkYXRhLW5hdmxpbmtde2N1cnNvcjpwb2ludGVyfS5mYyBhW2RhdGEtbmF2bGlua106aG92ZXJ7dGV4dC1kZWNvcmF0aW9uOnVuZGVybGluZX0uZmMtZGlyZWN0aW9uLWx0cntkaXJlY3Rpb246bHRyO3RleHQtYWxpZ246bGVmdH0uZmMtZGlyZWN0aW9uLXJ0bHtkaXJlY3Rpb246cnRsO3RleHQtYWxpZ246cmlnaHR9LmZjLXRoZW1lLXN0YW5kYXJkIHRkLC5mYy10aGVtZS1zdGFuZGFyZCB0aHtib3JkZXI6MXB4IHNvbGlkIHZhcigtLWZjLWJvcmRlci1jb2xvcil9LmZjLWxpcXVpZC1oYWNrIHRkLC5mYy1saXF1aWQtaGFjayB0aHtwb3NpdGlvbjpyZWxhdGl2ZX1AZm9udC1mYWNle2ZvbnQtZmFtaWx5OmZjaWNvbnM7Zm9udC1zdHlsZTpub3JtYWw7Zm9udC13ZWlnaHQ6NDAwO3NyYzp1cmwoXFxcImRhdGE6YXBwbGljYXRpb24veC1mb250LXR0ZjtjaGFyc2V0PXV0Zi04O2Jhc2U2NCxBQUVBQUFBTEFJQUFBd0F3VDFNdk1nOFNCZkFBQUFDOEFBQUFZR050WVhBWFZ0S05BQUFCSEFBQUFGUm5ZWE53QUFBQUVBQUFBWEFBQUFBSVoyeDVaZ1l5ZHhJQUFBRjRBQUFGTkdobFlXUVVKN2NJQUFBR3JBQUFBRFpvYUdWaEIyMER6QUFBQnVRQUFBQWthRzEwZUNJQUJoUUFBQWNJQUFBQUxHeHZZMkVENEFVNkFBQUhOQUFBQUJodFlYaHdBQThBakFBQUIwd0FBQUFnYm1GdFpYc3I2OTBBQUFkc0FBQUJobkJ2YzNRQUF3QUFBQUFJOUFBQUFDQUFBd1BBQVpBQUJRQUFBcGtDekFBQUFJOENtUUxNQUFBQjZ3QXpBUWtBQUFBQUFBQUFBQUFBQUFBQUFBQUJFQUFBQUFBQUFBQUFBQUFBQUFBQUFBQkFBQURwQmdQQS84QUFRQVBBQUVBQUFBQUJBQUFBQUFBQUFBQUFBQUFnQUFBQUFBQURBQUFBQXdBQUFCd0FBUUFEQUFBQUhBQURBQUVBQUFBY0FBUUFPQUFBQUFvQUNBQUNBQUlBQVFBZzZRYi8vZi8vQUFBQUFBQWc2UUQvL2YvL0FBSC80eGNFQUFNQUFRQUFBQUFBQUFBQUFBQUFBUUFCLy84QUR3QUJBQUFBQUFBQUFBQUFBZ0FBTnprQkFBQUFBQUVBQUFBQUFBQUFBQUFDQUFBM09RRUFBQUFBQVFBQUFBQUFBQUFBQUFJQUFEYzVBUUFBQUFBQkFXSUFqUUtlQXNrQUV3QUFKU2MzTmpRbkppSUhBUVlVRndFV01qYzJOQ2NDbnVMaURRME1KQXovQUEwTkFRQU1KQXdORGNuaTRnd2pEUXdNL3dBTkl3ei9BQTBORENNTkFBQUFBUUZpQUkwQ25nTEpBQk1BQUNVQk5qUW5BU1lpQndZVUh3RUhCaFFYRmpJM0FaNEJBQTBOL3dBTUpBd05EZUxpRFEwTUpBeU5BUUFNSXcwQkFBd01EU01NNHVJTkl3d05EUUFBQUFJQTRnQzNBeDRDbmdBVEFDY0FBQ1VuTnpZMEp5WWlEd0VHRkI4QkZqSTNOalFuSVNjM05qUW5KaUlQQVFZVUh3RVdNamMyTkNjQjg3ZTNEUTBNSXczVkRRM1ZEU01NRFEwQks3ZTNEUTBNSkF6VkRRM1ZEQ1FNRFEzenVMY01KQXdORGRVTkl3eldEQXdOSXd5NHR3d2tEQTBOMVEwakROWU1EQTBqREFBQUFnRGlBTGNESGdLZUFCTUFKd0FBSlRjMk5DOEJKaUlIQmhRZkFRY0dGQmNXTWpjaE56WTBMd0VtSWdjR0ZCOEJCd1lVRnhZeU53SkoxUTBOMVEwakRBME50N2NORFF3akRmN1YxUTBOMVF3a0RBME50N2NORFF3a0RMZldEQ01OMVEwTkRDUU10N2dNSXcwTUROWU1JdzNWRFEwTUpBeTN1QXdqRFF3TUFBQURBRlVBQUFPckExVUFNd0JvQUhjQUFCTWlCZ2NPQVFjT0FRY09BUlVSRkJZWEhnRVhIZ0VYSGdFeklUSTJOejRCTno0Qk56NEJOUkUwSmljdUFTY3VBU2N1QVNNRklUSVdGeDRCRng0QkZ4NEJGUkVVQmdjT0FRY09BUWNPQVNNaElpWW5MZ0VuTGdFbkxnRTFFVFEyTno0Qk56NEJOejRCTXhNaE1qWTFOQ1lqSVNJR0ZSUVdNOVVOR0F3TEZRa0pEZ1VGQlFVRkJRNEpDUlVMREJnTkFsWU5HQXdMRlFrSkRnVUZCUVVGQlE0SkNSVUxEQmdOL2FvQ1ZnUUlCQVFIQXdNRkFRSUJBUUlCQlFNREJ3UUVDQVQ5cWdRSUJBUUhBd01GQVFJQkFRSUJCUU1EQndRRUNBU0FBVllSR1JrUi9xb1JHUmtSQTFVRkJBVU9DUWtWREFzWkRmMnJEUmtMREJVSkNBNEZCUVVGQlFVT0NRZ1ZEQXNaRFFKVkRSa0xEQlVKQ1E0RkJBVlZBZ0VDQlFNQ0J3UUVDQVg5cXdRSkF3UUhBd01GQVFJQ0FnSUJCUU1EQndRRENRUUNWUVVJQkFRSEFnTUZBZ0VDL29BWkVoRVpHUkVTR1FBQUFBQURBRlVBQUFPckExVUFNd0JvQUlrQUFCTWlCZ2NPQVFjT0FRY09BUlVSRkJZWEhnRVhIZ0VYSGdFeklUSTJOejRCTno0Qk56NEJOUkUwSmljdUFTY3VBU2N1QVNNRklUSVdGeDRCRng0QkZ4NEJGUkVVQmdjT0FRY09BUWNPQVNNaElpWW5MZ0VuTGdFbkxnRTFFVFEyTno0Qk56NEJOejRCTXhNekZSUVdNekkyUFFFek1qWTFOQ1lyQVRVMEppTWlCaDBCSXlJR0ZSUVdNOVVOR0F3TEZRa0pEZ1VGQlFVRkJRNEpDUlVMREJnTkFsWU5HQXdMRlFrSkRnVUZCUVVGQlE0SkNSVUxEQmdOL2FvQ1ZnUUlCQVFIQXdNRkFRSUJBUUlCQlFNREJ3UUVDQVQ5cWdRSUJBUUhBd01GQVFJQkFRSUJCUU1EQndRRUNBU0FnQmtTRWhtQUVSa1pFWUFaRWhJWmdCRVpHUkVEVlFVRUJRNEpDUlVNQ3hrTi9hc05HUXNNRlFrSURnVUZCUVVGQlE0SkNCVU1DeGtOQWxVTkdRc01GUWtKRGdVRUJWVUNBUUlGQXdJSEJBUUlCZjJyQkFrREJBY0RBd1VCQWdJQ0FnRUZBd01IQkFNSkJBSlZCUWdFQkFjQ0F3VUNBUUwrZ0lBU0dSa1NnQmtTRVJtQUVoa1pFb0FaRVJJWkFBQUJBT0lBalFNZUFza0FJQUFBRXhjSEJoUVhGakkvQVJjV01qYzJOQzhCTnpZMEp5WWlEd0VuSmlJSEJoUVg0dUxpRFEwTUpBemk0Z3drREEwTjR1SU5EUXdrRE9MaURDUU1EUTBDamVMaURTTU1EUTNoNFEwTkRDTU40dUlNSXcwTURPTGlEQXdOSXd3QUFBQUJBQUFBQVFBQWE1bjB5MThQUFBVQUN3UUFBQUFBQU5pdk9Wc0FBQUFBMks4NVd3QUFBQUFEcXdOVkFBQUFDQUFDQUFBQUFBQUFBQUVBQUFQQS84QUFBQVFBQUFBQUFBT3JBQUVBQUFBQUFBQUFBQUFBQUFBQUFBQUxCQUFBQUFBQUFBQUFBQUFBQWdBQUFBUUFBV0lFQUFGaUJBQUE0Z1FBQU9JRUFBQlZCQUFBVlFRQUFPSUFBQUFBQUFvQUZBQWVBRVFBYWdDcUFPb0JuZ0prQXBvQUFRQUFBQXNBaWdBREFBQUFBQUFDQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUE0QXJnQUJBQUFBQUFBQkFBY0FBQUFCQUFBQUFBQUNBQWNBWUFBQkFBQUFBQUFEQUFjQU5nQUJBQUFBQUFBRUFBY0FkUUFCQUFBQUFBQUZBQXNBRlFBQkFBQUFBQUFHQUFjQVN3QUJBQUFBQUFBS0FCb0FpZ0FEQUFFRUNRQUJBQTRBQndBREFBRUVDUUFDQUE0QVp3QURBQUVFQ1FBREFBNEFQUUFEQUFFRUNRQUVBQTRBZkFBREFBRUVDUUFGQUJZQUlBQURBQUVFQ1FBR0FBNEFVZ0FEQUFFRUNRQUtBRFFBcEdaamFXTnZibk1BWmdCakFHa0FZd0J2QUc0QWMxWmxjbk5wYjI0Z01TNHdBRllBWlFCeUFITUFhUUJ2QUc0QUlBQXhBQzRBTUdaamFXTnZibk1BWmdCakFHa0FZd0J2QUc0QWMyWmphV052Ym5NQVpnQmpBR2tBWXdCdkFHNEFjMUpsWjNWc1lYSUFVZ0JsQUdjQWRRQnNBR0VBY21aamFXTnZibk1BWmdCakFHa0FZd0J2QUc0QWMwWnZiblFnWjJWdVpYSmhkR1ZrSUdKNUlFbGpiMDF2YjI0dUFFWUFid0J1QUhRQUlBQm5BR1VBYmdCbEFISUFZUUIwQUdVQVpBQWdBR0lBZVFBZ0FFa0FZd0J2QUUwQWJ3QnZBRzRBTGdBQUFBTUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUE9XFxcIikgZm9ybWF0KFxcXCJ0cnVldHlwZVxcXCIpfS5mYy1pY29ue3NwZWFrOm5vbmU7LXdlYmtpdC1mb250LXNtb290aGluZzphbnRpYWxpYXNlZDstbW96LW9zeC1mb250LXNtb290aGluZzpncmF5c2NhbGU7ZGlzcGxheTppbmxpbmUtYmxvY2s7Zm9udC1mYW1pbHk6ZmNpY29ucyFpbXBvcnRhbnQ7Zm9udC1zdHlsZTpub3JtYWw7Zm9udC12YXJpYW50Om5vcm1hbDtmb250LXdlaWdodDo0MDA7aGVpZ2h0OjFlbTtsaW5lLWhlaWdodDoxO3RleHQtYWxpZ246Y2VudGVyO3RleHQtdHJhbnNmb3JtOm5vbmU7LXdlYmtpdC11c2VyLXNlbGVjdDpub25lOy1tb3otdXNlci1zZWxlY3Q6bm9uZTt1c2VyLXNlbGVjdDpub25lO3dpZHRoOjFlbX0uZmMtaWNvbi1jaGV2cm9uLWxlZnQ6YmVmb3Jle2NvbnRlbnQ6XFxcIlxcXFxlOTAwXFxcIn0uZmMtaWNvbi1jaGV2cm9uLXJpZ2h0OmJlZm9yZXtjb250ZW50OlxcXCJcXFxcZTkwMVxcXCJ9LmZjLWljb24tY2hldnJvbnMtbGVmdDpiZWZvcmV7Y29udGVudDpcXFwiXFxcXGU5MDJcXFwifS5mYy1pY29uLWNoZXZyb25zLXJpZ2h0OmJlZm9yZXtjb250ZW50OlxcXCJcXFxcZTkwM1xcXCJ9LmZjLWljb24tbWludXMtc3F1YXJlOmJlZm9yZXtjb250ZW50OlxcXCJcXFxcZTkwNFxcXCJ9LmZjLWljb24tcGx1cy1zcXVhcmU6YmVmb3Jle2NvbnRlbnQ6XFxcIlxcXFxlOTA1XFxcIn0uZmMtaWNvbi14OmJlZm9yZXtjb250ZW50OlxcXCJcXFxcZTkwNlxcXCJ9LmZjIC5mYy1idXR0b257Ym9yZGVyLXJhZGl1czowO2ZvbnQtZmFtaWx5OmluaGVyaXQ7Zm9udC1zaXplOmluaGVyaXQ7bGluZS1oZWlnaHQ6aW5oZXJpdDttYXJnaW46MDtvdmVyZmxvdzp2aXNpYmxlO3RleHQtdHJhbnNmb3JtOm5vbmV9LmZjIC5mYy1idXR0b246Zm9jdXN7b3V0bGluZToxcHggZG90dGVkO291dGxpbmU6NXB4IGF1dG8gLXdlYmtpdC1mb2N1cy1yaW5nLWNvbG9yfS5mYyAuZmMtYnV0dG9uey13ZWJraXQtYXBwZWFyYW5jZTpidXR0b259LmZjIC5mYy1idXR0b246bm90KDpkaXNhYmxlZCl7Y3Vyc29yOnBvaW50ZXJ9LmZjIC5mYy1idXR0b246Oi1tb3otZm9jdXMtaW5uZXJ7Ym9yZGVyLXN0eWxlOm5vbmU7cGFkZGluZzowfS5mYyAuZmMtYnV0dG9ue2JhY2tncm91bmQtY29sb3I6dHJhbnNwYXJlbnQ7Ym9yZGVyOjFweCBzb2xpZCB0cmFuc3BhcmVudDtib3JkZXItcmFkaXVzOi4yNWVtO2Rpc3BsYXk6aW5saW5lLWJsb2NrO2ZvbnQtc2l6ZToxZW07Zm9udC13ZWlnaHQ6NDAwO2xpbmUtaGVpZ2h0OjEuNTtwYWRkaW5nOi40ZW0gLjY1ZW07dGV4dC1hbGlnbjpjZW50ZXI7LXdlYmtpdC11c2VyLXNlbGVjdDpub25lOy1tb3otdXNlci1zZWxlY3Q6bm9uZTt1c2VyLXNlbGVjdDpub25lO3ZlcnRpY2FsLWFsaWduOm1pZGRsZX0uZmMgLmZjLWJ1dHRvbjpob3Zlcnt0ZXh0LWRlY29yYXRpb246bm9uZX0uZmMgLmZjLWJ1dHRvbjpmb2N1c3tib3gtc2hhZG93OjAgMCAwIC4ycmVtIHJnYmEoNDQsNjIsODAsLjI1KTtvdXRsaW5lOjB9LmZjIC5mYy1idXR0b246ZGlzYWJsZWR7b3BhY2l0eTouNjV9LmZjIC5mYy1idXR0b24tcHJpbWFyeXtiYWNrZ3JvdW5kLWNvbG9yOnZhcigtLWZjLWJ1dHRvbi1iZy1jb2xvcik7Ym9yZGVyLWNvbG9yOnZhcigtLWZjLWJ1dHRvbi1ib3JkZXItY29sb3IpO2NvbG9yOnZhcigtLWZjLWJ1dHRvbi10ZXh0LWNvbG9yKX0uZmMgLmZjLWJ1dHRvbi1wcmltYXJ5OmhvdmVye2JhY2tncm91bmQtY29sb3I6dmFyKC0tZmMtYnV0dG9uLWhvdmVyLWJnLWNvbG9yKTtib3JkZXItY29sb3I6dmFyKC0tZmMtYnV0dG9uLWhvdmVyLWJvcmRlci1jb2xvcik7Y29sb3I6dmFyKC0tZmMtYnV0dG9uLXRleHQtY29sb3IpfS5mYyAuZmMtYnV0dG9uLXByaW1hcnk6ZGlzYWJsZWR7YmFja2dyb3VuZC1jb2xvcjp2YXIoLS1mYy1idXR0b24tYmctY29sb3IpO2JvcmRlci1jb2xvcjp2YXIoLS1mYy1idXR0b24tYm9yZGVyLWNvbG9yKTtjb2xvcjp2YXIoLS1mYy1idXR0b24tdGV4dC1jb2xvcil9LmZjIC5mYy1idXR0b24tcHJpbWFyeTpmb2N1c3tib3gtc2hhZG93OjAgMCAwIC4ycmVtIHJnYmEoNzYsOTEsMTA2LC41KX0uZmMgLmZjLWJ1dHRvbi1wcmltYXJ5Om5vdCg6ZGlzYWJsZWQpLmZjLWJ1dHRvbi1hY3RpdmUsLmZjIC5mYy1idXR0b24tcHJpbWFyeTpub3QoOmRpc2FibGVkKTphY3RpdmV7YmFja2dyb3VuZC1jb2xvcjp2YXIoLS1mYy1idXR0b24tYWN0aXZlLWJnLWNvbG9yKTtib3JkZXItY29sb3I6dmFyKC0tZmMtYnV0dG9uLWFjdGl2ZS1ib3JkZXItY29sb3IpO2NvbG9yOnZhcigtLWZjLWJ1dHRvbi10ZXh0LWNvbG9yKX0uZmMgLmZjLWJ1dHRvbi1wcmltYXJ5Om5vdCg6ZGlzYWJsZWQpLmZjLWJ1dHRvbi1hY3RpdmU6Zm9jdXMsLmZjIC5mYy1idXR0b24tcHJpbWFyeTpub3QoOmRpc2FibGVkKTphY3RpdmU6Zm9jdXN7Ym94LXNoYWRvdzowIDAgMCAuMnJlbSByZ2JhKDc2LDkxLDEwNiwuNSl9LmZjIC5mYy1idXR0b24gLmZjLWljb257Zm9udC1zaXplOjEuNWVtO3ZlcnRpY2FsLWFsaWduOm1pZGRsZX0uZmMgLmZjLWJ1dHRvbi1ncm91cHtkaXNwbGF5OmlubGluZS1mbGV4O3Bvc2l0aW9uOnJlbGF0aXZlO3ZlcnRpY2FsLWFsaWduOm1pZGRsZX0uZmMgLmZjLWJ1dHRvbi1ncm91cD4uZmMtYnV0dG9ue2ZsZXg6MSAxIGF1dG87cG9zaXRpb246cmVsYXRpdmV9LmZjIC5mYy1idXR0b24tZ3JvdXA+LmZjLWJ1dHRvbi5mYy1idXR0b24tYWN0aXZlLC5mYyAuZmMtYnV0dG9uLWdyb3VwPi5mYy1idXR0b246YWN0aXZlLC5mYyAuZmMtYnV0dG9uLWdyb3VwPi5mYy1idXR0b246Zm9jdXMsLmZjIC5mYy1idXR0b24tZ3JvdXA+LmZjLWJ1dHRvbjpob3Zlcnt6LWluZGV4OjF9LmZjLWRpcmVjdGlvbi1sdHIgLmZjLWJ1dHRvbi1ncm91cD4uZmMtYnV0dG9uOm5vdCg6Zmlyc3QtY2hpbGQpe2JvcmRlci1ib3R0b20tbGVmdC1yYWRpdXM6MDtib3JkZXItdG9wLWxlZnQtcmFkaXVzOjA7bWFyZ2luLWxlZnQ6LTFweH0uZmMtZGlyZWN0aW9uLWx0ciAuZmMtYnV0dG9uLWdyb3VwPi5mYy1idXR0b246bm90KDpsYXN0LWNoaWxkKXtib3JkZXItYm90dG9tLXJpZ2h0LXJhZGl1czowO2JvcmRlci10b3AtcmlnaHQtcmFkaXVzOjB9LmZjLWRpcmVjdGlvbi1ydGwgLmZjLWJ1dHRvbi1ncm91cD4uZmMtYnV0dG9uOm5vdCg6Zmlyc3QtY2hpbGQpe2JvcmRlci1ib3R0b20tcmlnaHQtcmFkaXVzOjA7Ym9yZGVyLXRvcC1yaWdodC1yYWRpdXM6MDttYXJnaW4tcmlnaHQ6LTFweH0uZmMtZGlyZWN0aW9uLXJ0bCAuZmMtYnV0dG9uLWdyb3VwPi5mYy1idXR0b246bm90KDpsYXN0LWNoaWxkKXtib3JkZXItYm90dG9tLWxlZnQtcmFkaXVzOjA7Ym9yZGVyLXRvcC1sZWZ0LXJhZGl1czowfS5mYyAuZmMtdG9vbGJhcnthbGlnbi1pdGVtczpjZW50ZXI7ZGlzcGxheTpmbGV4O2p1c3RpZnktY29udGVudDpzcGFjZS1iZXR3ZWVufS5mYyAuZmMtdG9vbGJhci5mYy1oZWFkZXItdG9vbGJhcnttYXJnaW4tYm90dG9tOjEuNWVtfS5mYyAuZmMtdG9vbGJhci5mYy1mb290ZXItdG9vbGJhcnttYXJnaW4tdG9wOjEuNWVtfS5mYyAuZmMtdG9vbGJhci10aXRsZXtmb250LXNpemU6MS43NWVtO21hcmdpbjowfS5mYy1kaXJlY3Rpb24tbHRyIC5mYy10b29sYmFyPio+Om5vdCg6Zmlyc3QtY2hpbGQpe21hcmdpbi1sZWZ0Oi43NWVtfS5mYy1kaXJlY3Rpb24tcnRsIC5mYy10b29sYmFyPio+Om5vdCg6Zmlyc3QtY2hpbGQpe21hcmdpbi1yaWdodDouNzVlbX0uZmMtZGlyZWN0aW9uLXJ0bCAuZmMtdG9vbGJhci1sdHJ7ZmxleC1kaXJlY3Rpb246cm93LXJldmVyc2V9LmZjIC5mYy1zY3JvbGxlcnstd2Via2l0LW92ZXJmbG93LXNjcm9sbGluZzp0b3VjaDtwb3NpdGlvbjpyZWxhdGl2ZX0uZmMgLmZjLXNjcm9sbGVyLWxpcXVpZHtoZWlnaHQ6MTAwJX0uZmMgLmZjLXNjcm9sbGVyLWxpcXVpZC1hYnNvbHV0ZXtib3R0b206MDtsZWZ0OjA7cG9zaXRpb246YWJzb2x1dGU7cmlnaHQ6MDt0b3A6MH0uZmMgLmZjLXNjcm9sbGVyLWhhcm5lc3N7ZGlyZWN0aW9uOmx0cjtvdmVyZmxvdzpoaWRkZW47cG9zaXRpb246cmVsYXRpdmV9LmZjIC5mYy1zY3JvbGxlci1oYXJuZXNzLWxpcXVpZHtoZWlnaHQ6MTAwJX0uZmMtZGlyZWN0aW9uLXJ0bCAuZmMtc2Nyb2xsZXItaGFybmVzcz4uZmMtc2Nyb2xsZXJ7ZGlyZWN0aW9uOnJ0bH0uZmMtdGhlbWUtc3RhbmRhcmQgLmZjLXNjcm9sbGdyaWR7Ym9yZGVyOjFweCBzb2xpZCB2YXIoLS1mYy1ib3JkZXItY29sb3IpfS5mYyAuZmMtc2Nyb2xsZ3JpZCwuZmMgLmZjLXNjcm9sbGdyaWQgdGFibGV7dGFibGUtbGF5b3V0OmZpeGVkO3dpZHRoOjEwMCV9LmZjIC5mYy1zY3JvbGxncmlkIHRhYmxle2JvcmRlci1sZWZ0LXN0eWxlOmhpZGRlbjtib3JkZXItcmlnaHQtc3R5bGU6aGlkZGVuO2JvcmRlci10b3Atc3R5bGU6aGlkZGVufS5mYyAuZmMtc2Nyb2xsZ3JpZHtib3JkZXItYm90dG9tLXdpZHRoOjA7Ym9yZGVyLWNvbGxhcHNlOnNlcGFyYXRlO2JvcmRlci1yaWdodC13aWR0aDowfS5mYyAuZmMtc2Nyb2xsZ3JpZC1saXF1aWR7aGVpZ2h0OjEwMCV9LmZjIC5mYy1zY3JvbGxncmlkLXNlY3Rpb24sLmZjIC5mYy1zY3JvbGxncmlkLXNlY3Rpb24gdGFibGUsLmZjIC5mYy1zY3JvbGxncmlkLXNlY3Rpb24+dGR7aGVpZ2h0OjFweH0uZmMgLmZjLXNjcm9sbGdyaWQtc2VjdGlvbi1saXF1aWQ+dGR7aGVpZ2h0OjEwMCV9LmZjIC5mYy1zY3JvbGxncmlkLXNlY3Rpb24+Kntib3JkZXItbGVmdC13aWR0aDowO2JvcmRlci10b3Atd2lkdGg6MH0uZmMgLmZjLXNjcm9sbGdyaWQtc2VjdGlvbi1mb290ZXI+KiwuZmMgLmZjLXNjcm9sbGdyaWQtc2VjdGlvbi1oZWFkZXI+Kntib3JkZXItYm90dG9tLXdpZHRoOjB9LmZjIC5mYy1zY3JvbGxncmlkLXNlY3Rpb24tYm9keSB0YWJsZSwuZmMgLmZjLXNjcm9sbGdyaWQtc2VjdGlvbi1mb290ZXIgdGFibGV7Ym9yZGVyLWJvdHRvbS1zdHlsZTpoaWRkZW59LmZjIC5mYy1zY3JvbGxncmlkLXNlY3Rpb24tc3RpY2t5Pip7YmFja2dyb3VuZDp2YXIoLS1mYy1wYWdlLWJnLWNvbG9yKTtwb3NpdGlvbjpzdGlja3k7ei1pbmRleDozfS5mYyAuZmMtc2Nyb2xsZ3JpZC1zZWN0aW9uLWhlYWRlci5mYy1zY3JvbGxncmlkLXNlY3Rpb24tc3RpY2t5Pip7dG9wOjB9LmZjIC5mYy1zY3JvbGxncmlkLXNlY3Rpb24tZm9vdGVyLmZjLXNjcm9sbGdyaWQtc2VjdGlvbi1zdGlja3k+Kntib3R0b206MH0uZmMgLmZjLXNjcm9sbGdyaWQtc3RpY2t5LXNoaW17aGVpZ2h0OjFweDttYXJnaW4tYm90dG9tOi0xcHh9LmZjLXN0aWNreXtwb3NpdGlvbjpzdGlja3l9LmZjIC5mYy12aWV3LWhhcm5lc3N7ZmxleC1ncm93OjE7cG9zaXRpb246cmVsYXRpdmV9LmZjIC5mYy12aWV3LWhhcm5lc3MtYWN0aXZlPi5mYy12aWV3e2JvdHRvbTowO2xlZnQ6MDtwb3NpdGlvbjphYnNvbHV0ZTtyaWdodDowO3RvcDowfS5mYyAuZmMtY29sLWhlYWRlci1jZWxsLWN1c2hpb257ZGlzcGxheTppbmxpbmUtYmxvY2s7cGFkZGluZzoycHggNHB4fS5mYyAuZmMtYmctZXZlbnQsLmZjIC5mYy1oaWdobGlnaHQsLmZjIC5mYy1ub24tYnVzaW5lc3N7Ym90dG9tOjA7bGVmdDowO3Bvc2l0aW9uOmFic29sdXRlO3JpZ2h0OjA7dG9wOjB9LmZjIC5mYy1ub24tYnVzaW5lc3N7YmFja2dyb3VuZDp2YXIoLS1mYy1ub24tYnVzaW5lc3MtY29sb3IpfS5mYyAuZmMtYmctZXZlbnR7YmFja2dyb3VuZDp2YXIoLS1mYy1iZy1ldmVudC1jb2xvcik7b3BhY2l0eTp2YXIoLS1mYy1iZy1ldmVudC1vcGFjaXR5KX0uZmMgLmZjLWJnLWV2ZW50IC5mYy1ldmVudC10aXRsZXtmb250LXNpemU6dmFyKC0tZmMtc21hbGwtZm9udC1zaXplKTtmb250LXN0eWxlOml0YWxpYzttYXJnaW46LjVlbX0uZmMgLmZjLWhpZ2hsaWdodHtiYWNrZ3JvdW5kOnZhcigtLWZjLWhpZ2hsaWdodC1jb2xvcil9LmZjIC5mYy1jZWxsLXNoYWRlZCwuZmMgLmZjLWRheS1kaXNhYmxlZHtiYWNrZ3JvdW5kOnZhcigtLWZjLW5ldXRyYWwtYmctY29sb3IpfWEuZmMtZXZlbnQsYS5mYy1ldmVudDpob3Zlcnt0ZXh0LWRlY29yYXRpb246bm9uZX0uZmMtZXZlbnQuZmMtZXZlbnQtZHJhZ2dhYmxlLC5mYy1ldmVudFtocmVmXXtjdXJzb3I6cG9pbnRlcn0uZmMtZXZlbnQgLmZjLWV2ZW50LW1haW57cG9zaXRpb246cmVsYXRpdmU7ei1pbmRleDoyfS5mYy1ldmVudC1kcmFnZ2luZzpub3QoLmZjLWV2ZW50LXNlbGVjdGVkKXtvcGFjaXR5Oi43NX0uZmMtZXZlbnQtZHJhZ2dpbmcuZmMtZXZlbnQtc2VsZWN0ZWR7Ym94LXNoYWRvdzowIDJweCA3cHggcmdiYSgwLDAsMCwuMyl9LmZjLWV2ZW50IC5mYy1ldmVudC1yZXNpemVye2Rpc3BsYXk6bm9uZTtwb3NpdGlvbjphYnNvbHV0ZTt6LWluZGV4OjR9LmZjLWV2ZW50LXNlbGVjdGVkIC5mYy1ldmVudC1yZXNpemVyLC5mYy1ldmVudDpob3ZlciAuZmMtZXZlbnQtcmVzaXplcntkaXNwbGF5OmJsb2NrfS5mYy1ldmVudC1zZWxlY3RlZCAuZmMtZXZlbnQtcmVzaXplcntiYWNrZ3JvdW5kOnZhcigtLWZjLXBhZ2UtYmctY29sb3IpO2JvcmRlci1jb2xvcjppbmhlcml0O2JvcmRlci1yYWRpdXM6Y2FsYyh2YXIoLS1mYy1ldmVudC1yZXNpemVyLWRvdC10b3RhbC13aWR0aCkvMik7Ym9yZGVyLXN0eWxlOnNvbGlkO2JvcmRlci13aWR0aDp2YXIoLS1mYy1ldmVudC1yZXNpemVyLWRvdC1ib3JkZXItd2lkdGgpO2hlaWdodDp2YXIoLS1mYy1ldmVudC1yZXNpemVyLWRvdC10b3RhbC13aWR0aCk7d2lkdGg6dmFyKC0tZmMtZXZlbnQtcmVzaXplci1kb3QtdG90YWwtd2lkdGgpfS5mYy1ldmVudC1zZWxlY3RlZCAuZmMtZXZlbnQtcmVzaXplcjpiZWZvcmV7Ym90dG9tOi0yMHB4O2NvbnRlbnQ6XFxcIlxcXCI7bGVmdDotMjBweDtwb3NpdGlvbjphYnNvbHV0ZTtyaWdodDotMjBweDt0b3A6LTIwcHh9LmZjLWV2ZW50LXNlbGVjdGVkLC5mYy1ldmVudDpmb2N1c3tib3gtc2hhZG93OjAgMnB4IDVweCByZ2JhKDAsMCwwLC4yKX0uZmMtZXZlbnQtc2VsZWN0ZWQ6YmVmb3JlLC5mYy1ldmVudDpmb2N1czpiZWZvcmV7Ym90dG9tOjA7Y29udGVudDpcXFwiXFxcIjtsZWZ0OjA7cG9zaXRpb246YWJzb2x1dGU7cmlnaHQ6MDt0b3A6MDt6LWluZGV4OjN9LmZjLWV2ZW50LXNlbGVjdGVkOmFmdGVyLC5mYy1ldmVudDpmb2N1czphZnRlcntiYWNrZ3JvdW5kOnZhcigtLWZjLWV2ZW50LXNlbGVjdGVkLW92ZXJsYXktY29sb3IpO2JvdHRvbTotMXB4O2NvbnRlbnQ6XFxcIlxcXCI7bGVmdDotMXB4O3Bvc2l0aW9uOmFic29sdXRlO3JpZ2h0Oi0xcHg7dG9wOi0xcHg7ei1pbmRleDoxfS5mYy1oLWV2ZW50e2JhY2tncm91bmQtY29sb3I6dmFyKC0tZmMtZXZlbnQtYmctY29sb3IpO2JvcmRlcjoxcHggc29saWQgdmFyKC0tZmMtZXZlbnQtYm9yZGVyLWNvbG9yKTtkaXNwbGF5OmJsb2NrfS5mYy1oLWV2ZW50IC5mYy1ldmVudC1tYWlue2NvbG9yOnZhcigtLWZjLWV2ZW50LXRleHQtY29sb3IpfS5mYy1oLWV2ZW50IC5mYy1ldmVudC1tYWluLWZyYW1le2Rpc3BsYXk6ZmxleH0uZmMtaC1ldmVudCAuZmMtZXZlbnQtdGltZXttYXgtd2lkdGg6MTAwJTtvdmVyZmxvdzpoaWRkZW59LmZjLWgtZXZlbnQgLmZjLWV2ZW50LXRpdGxlLWNvbnRhaW5lcntmbGV4LWdyb3c6MTtmbGV4LXNocmluazoxO21pbi13aWR0aDowfS5mYy1oLWV2ZW50IC5mYy1ldmVudC10aXRsZXtkaXNwbGF5OmlubGluZS1ibG9jaztsZWZ0OjA7bWF4LXdpZHRoOjEwMCU7b3ZlcmZsb3c6aGlkZGVuO3JpZ2h0OjA7dmVydGljYWwtYWxpZ246dG9wfS5mYy1oLWV2ZW50LmZjLWV2ZW50LXNlbGVjdGVkOmJlZm9yZXtib3R0b206LTEwcHg7dG9wOi0xMHB4fS5mYy1kaXJlY3Rpb24tbHRyIC5mYy1kYXlncmlkLWJsb2NrLWV2ZW50Om5vdCguZmMtZXZlbnQtc3RhcnQpLC5mYy1kaXJlY3Rpb24tcnRsIC5mYy1kYXlncmlkLWJsb2NrLWV2ZW50Om5vdCguZmMtZXZlbnQtZW5kKXtib3JkZXItYm90dG9tLWxlZnQtcmFkaXVzOjA7Ym9yZGVyLWxlZnQtd2lkdGg6MDtib3JkZXItdG9wLWxlZnQtcmFkaXVzOjB9LmZjLWRpcmVjdGlvbi1sdHIgLmZjLWRheWdyaWQtYmxvY2stZXZlbnQ6bm90KC5mYy1ldmVudC1lbmQpLC5mYy1kaXJlY3Rpb24tcnRsIC5mYy1kYXlncmlkLWJsb2NrLWV2ZW50Om5vdCguZmMtZXZlbnQtc3RhcnQpe2JvcmRlci1ib3R0b20tcmlnaHQtcmFkaXVzOjA7Ym9yZGVyLXJpZ2h0LXdpZHRoOjA7Ym9yZGVyLXRvcC1yaWdodC1yYWRpdXM6MH0uZmMtaC1ldmVudDpub3QoLmZjLWV2ZW50LXNlbGVjdGVkKSAuZmMtZXZlbnQtcmVzaXplcntib3R0b206MDt0b3A6MDt3aWR0aDp2YXIoLS1mYy1ldmVudC1yZXNpemVyLXRoaWNrbmVzcyl9LmZjLWRpcmVjdGlvbi1sdHIgLmZjLWgtZXZlbnQ6bm90KC5mYy1ldmVudC1zZWxlY3RlZCkgLmZjLWV2ZW50LXJlc2l6ZXItc3RhcnQsLmZjLWRpcmVjdGlvbi1ydGwgLmZjLWgtZXZlbnQ6bm90KC5mYy1ldmVudC1zZWxlY3RlZCkgLmZjLWV2ZW50LXJlc2l6ZXItZW5ke2N1cnNvcjp3LXJlc2l6ZTtsZWZ0OmNhbGModmFyKC0tZmMtZXZlbnQtcmVzaXplci10aGlja25lc3MpKi0uNSl9LmZjLWRpcmVjdGlvbi1sdHIgLmZjLWgtZXZlbnQ6bm90KC5mYy1ldmVudC1zZWxlY3RlZCkgLmZjLWV2ZW50LXJlc2l6ZXItZW5kLC5mYy1kaXJlY3Rpb24tcnRsIC5mYy1oLWV2ZW50Om5vdCguZmMtZXZlbnQtc2VsZWN0ZWQpIC5mYy1ldmVudC1yZXNpemVyLXN0YXJ0e2N1cnNvcjplLXJlc2l6ZTtyaWdodDpjYWxjKHZhcigtLWZjLWV2ZW50LXJlc2l6ZXItdGhpY2tuZXNzKSotLjUpfS5mYy1oLWV2ZW50LmZjLWV2ZW50LXNlbGVjdGVkIC5mYy1ldmVudC1yZXNpemVye21hcmdpbi10b3A6Y2FsYyh2YXIoLS1mYy1ldmVudC1yZXNpemVyLWRvdC10b3RhbC13aWR0aCkqLS41KTt0b3A6NTAlfS5mYy1kaXJlY3Rpb24tbHRyIC5mYy1oLWV2ZW50LmZjLWV2ZW50LXNlbGVjdGVkIC5mYy1ldmVudC1yZXNpemVyLXN0YXJ0LC5mYy1kaXJlY3Rpb24tcnRsIC5mYy1oLWV2ZW50LmZjLWV2ZW50LXNlbGVjdGVkIC5mYy1ldmVudC1yZXNpemVyLWVuZHtsZWZ0OmNhbGModmFyKC0tZmMtZXZlbnQtcmVzaXplci1kb3QtdG90YWwtd2lkdGgpKi0uNSl9LmZjLWRpcmVjdGlvbi1sdHIgLmZjLWgtZXZlbnQuZmMtZXZlbnQtc2VsZWN0ZWQgLmZjLWV2ZW50LXJlc2l6ZXItZW5kLC5mYy1kaXJlY3Rpb24tcnRsIC5mYy1oLWV2ZW50LmZjLWV2ZW50LXNlbGVjdGVkIC5mYy1ldmVudC1yZXNpemVyLXN0YXJ0e3JpZ2h0OmNhbGModmFyKC0tZmMtZXZlbnQtcmVzaXplci1kb3QtdG90YWwtd2lkdGgpKi0uNSl9LmZjIC5mYy1wb3BvdmVye2JveC1zaGFkb3c6MCAycHggNnB4IHJnYmEoMCwwLDAsLjE1KTtwb3NpdGlvbjphYnNvbHV0ZTt6LWluZGV4Ojk5OTl9LmZjIC5mYy1wb3BvdmVyLWhlYWRlcnthbGlnbi1pdGVtczpjZW50ZXI7ZGlzcGxheTpmbGV4O2ZsZXgtZGlyZWN0aW9uOnJvdztqdXN0aWZ5LWNvbnRlbnQ6c3BhY2UtYmV0d2VlbjtwYWRkaW5nOjNweCA0cHh9LmZjIC5mYy1wb3BvdmVyLXRpdGxle21hcmdpbjowIDJweH0uZmMgLmZjLXBvcG92ZXItY2xvc2V7Y3Vyc29yOnBvaW50ZXI7Zm9udC1zaXplOjEuMWVtO29wYWNpdHk6LjY1fS5mYy10aGVtZS1zdGFuZGFyZCAuZmMtcG9wb3ZlcntiYWNrZ3JvdW5kOnZhcigtLWZjLXBhZ2UtYmctY29sb3IpO2JvcmRlcjoxcHggc29saWQgdmFyKC0tZmMtYm9yZGVyLWNvbG9yKX0uZmMtdGhlbWUtc3RhbmRhcmQgLmZjLXBvcG92ZXItaGVhZGVye2JhY2tncm91bmQ6dmFyKC0tZmMtbmV1dHJhbC1iZy1jb2xvcil9XCI7XG5pbmplY3RTdHlsZXMoY3NzXzI0OHopO1xuXG5jb25zdCBnbG9iYWxMb2NhbGVzID0gW107XG5cbmNvbnN0IE1JTklNQUxfUkFXX0VOX0xPQ0FMRSA9IHtcbiAgICBjb2RlOiAnZW4nLFxuICAgIHdlZWs6IHtcbiAgICAgICAgZG93OiAwLFxuICAgICAgICBkb3k6IDQsIC8vIDQgZGF5cyBuZWVkIHRvIGJlIHdpdGhpbiB0aGUgeWVhciB0byBiZSBjb25zaWRlcmVkIHRoZSBmaXJzdCB3ZWVrXG4gICAgfSxcbiAgICBkaXJlY3Rpb246ICdsdHInLFxuICAgIGJ1dHRvblRleHQ6IHtcbiAgICAgICAgcHJldjogJ3ByZXYnLFxuICAgICAgICBuZXh0OiAnbmV4dCcsXG4gICAgICAgIHByZXZZZWFyOiAncHJldiB5ZWFyJyxcbiAgICAgICAgbmV4dFllYXI6ICduZXh0IHllYXInLFxuICAgICAgICB5ZWFyOiAneWVhcicsXG4gICAgICAgIHRvZGF5OiAndG9kYXknLFxuICAgICAgICBtb250aDogJ21vbnRoJyxcbiAgICAgICAgd2VlazogJ3dlZWsnLFxuICAgICAgICBkYXk6ICdkYXknLFxuICAgICAgICBsaXN0OiAnbGlzdCcsXG4gICAgfSxcbiAgICB3ZWVrVGV4dDogJ1cnLFxuICAgIHdlZWtUZXh0TG9uZzogJ1dlZWsnLFxuICAgIGNsb3NlSGludDogJ0Nsb3NlJyxcbiAgICB0aW1lSGludDogJ1RpbWUnLFxuICAgIGV2ZW50SGludDogJ0V2ZW50JyxcbiAgICBhbGxEYXlUZXh0OiAnYWxsLWRheScsXG4gICAgbW9yZUxpbmtUZXh0OiAnbW9yZScsXG4gICAgbm9FdmVudHNUZXh0OiAnTm8gZXZlbnRzIHRvIGRpc3BsYXknLFxufTtcbmNvbnN0IFJBV19FTl9MT0NBTEUgPSBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sIE1JTklNQUxfUkFXX0VOX0xPQ0FMRSksIHsgXG4gICAgLy8gSW5jbHVkZXMgdGhpbmdzIHdlIGRvbid0IHdhbnQgb3RoZXIgbG9jYWxlcyB0byBpbmhlcml0LFxuICAgIC8vIHRoaW5ncyB0aGF0IGRlcml2ZSBmcm9tIG90aGVyIHRyYW5zbGF0YWJsZSBzdHJpbmdzLlxuICAgIGJ1dHRvbkhpbnRzOiB7XG4gICAgICAgIHByZXY6ICdQcmV2aW91cyAkMCcsXG4gICAgICAgIG5leHQ6ICdOZXh0ICQwJyxcbiAgICAgICAgdG9kYXkoYnV0dG9uVGV4dCwgdW5pdCkge1xuICAgICAgICAgICAgcmV0dXJuICh1bml0ID09PSAnZGF5JylcbiAgICAgICAgICAgICAgICA/ICdUb2RheSdcbiAgICAgICAgICAgICAgICA6IGBUaGlzICR7YnV0dG9uVGV4dH1gO1xuICAgICAgICB9LFxuICAgIH0sIHZpZXdIaW50OiAnJDAgdmlldycsIG5hdkxpbmtIaW50OiAnR28gdG8gJDAnLCBtb3JlTGlua0hpbnQoZXZlbnRDbnQpIHtcbiAgICAgICAgcmV0dXJuIGBTaG93ICR7ZXZlbnRDbnR9IG1vcmUgZXZlbnQke2V2ZW50Q250ID09PSAxID8gJycgOiAncyd9YDtcbiAgICB9IH0pO1xuZnVuY3Rpb24gb3JnYW5pemVSYXdMb2NhbGVzKGV4cGxpY2l0UmF3TG9jYWxlcykge1xuICAgIGxldCBkZWZhdWx0Q29kZSA9IGV4cGxpY2l0UmF3TG9jYWxlcy5sZW5ndGggPiAwID8gZXhwbGljaXRSYXdMb2NhbGVzWzBdLmNvZGUgOiAnZW4nO1xuICAgIGxldCBhbGxSYXdMb2NhbGVzID0gZ2xvYmFsTG9jYWxlcy5jb25jYXQoZXhwbGljaXRSYXdMb2NhbGVzKTtcbiAgICBsZXQgcmF3TG9jYWxlTWFwID0ge1xuICAgICAgICBlbjogUkFXX0VOX0xPQ0FMRSxcbiAgICB9O1xuICAgIGZvciAobGV0IHJhd0xvY2FsZSBvZiBhbGxSYXdMb2NhbGVzKSB7XG4gICAgICAgIHJhd0xvY2FsZU1hcFtyYXdMb2NhbGUuY29kZV0gPSByYXdMb2NhbGU7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICAgIG1hcDogcmF3TG9jYWxlTWFwLFxuICAgICAgICBkZWZhdWx0Q29kZSxcbiAgICB9O1xufVxuZnVuY3Rpb24gYnVpbGRMb2NhbGUoaW5wdXRTaW5ndWxhciwgYXZhaWxhYmxlKSB7XG4gICAgaWYgKHR5cGVvZiBpbnB1dFNpbmd1bGFyID09PSAnb2JqZWN0JyAmJiAhQXJyYXkuaXNBcnJheShpbnB1dFNpbmd1bGFyKSkge1xuICAgICAgICByZXR1cm4gcGFyc2VMb2NhbGUoaW5wdXRTaW5ndWxhci5jb2RlLCBbaW5wdXRTaW5ndWxhci5jb2RlXSwgaW5wdXRTaW5ndWxhcik7XG4gICAgfVxuICAgIHJldHVybiBxdWVyeUxvY2FsZShpbnB1dFNpbmd1bGFyLCBhdmFpbGFibGUpO1xufVxuZnVuY3Rpb24gcXVlcnlMb2NhbGUoY29kZUFyZywgYXZhaWxhYmxlKSB7XG4gICAgbGV0IGNvZGVzID0gW10uY29uY2F0KGNvZGVBcmcgfHwgW10pOyAvLyB3aWxsIGNvbnZlcnQgdG8gYXJyYXlcbiAgICBsZXQgcmF3ID0gcXVlcnlSYXdMb2NhbGUoY29kZXMsIGF2YWlsYWJsZSkgfHwgUkFXX0VOX0xPQ0FMRTtcbiAgICByZXR1cm4gcGFyc2VMb2NhbGUoY29kZUFyZywgY29kZXMsIHJhdyk7XG59XG5mdW5jdGlvbiBxdWVyeVJhd0xvY2FsZShjb2RlcywgYXZhaWxhYmxlKSB7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb2Rlcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICBsZXQgcGFydHMgPSBjb2Rlc1tpXS50b0xvY2FsZUxvd2VyQ2FzZSgpLnNwbGl0KCctJyk7XG4gICAgICAgIGZvciAobGV0IGogPSBwYXJ0cy5sZW5ndGg7IGogPiAwOyBqIC09IDEpIHtcbiAgICAgICAgICAgIGxldCBzaW1wbGVJZCA9IHBhcnRzLnNsaWNlKDAsIGopLmpvaW4oJy0nKTtcbiAgICAgICAgICAgIGlmIChhdmFpbGFibGVbc2ltcGxlSWRdKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGF2YWlsYWJsZVtzaW1wbGVJZF07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG59XG5mdW5jdGlvbiBwYXJzZUxvY2FsZShjb2RlQXJnLCBjb2RlcywgcmF3KSB7XG4gICAgbGV0IG1lcmdlZCA9IG1lcmdlUHJvcHMoW01JTklNQUxfUkFXX0VOX0xPQ0FMRSwgcmF3XSwgWydidXR0b25UZXh0J10pO1xuICAgIGRlbGV0ZSBtZXJnZWQuY29kZTsgLy8gZG9uJ3Qgd2FudCB0aGlzIHBhcnQgb2YgdGhlIG9wdGlvbnNcbiAgICBsZXQgeyB3ZWVrIH0gPSBtZXJnZWQ7XG4gICAgZGVsZXRlIG1lcmdlZC53ZWVrO1xuICAgIHJldHVybiB7XG4gICAgICAgIGNvZGVBcmcsXG4gICAgICAgIGNvZGVzLFxuICAgICAgICB3ZWVrLFxuICAgICAgICBzaW1wbGVOdW1iZXJGb3JtYXQ6IG5ldyBJbnRsLk51bWJlckZvcm1hdChjb2RlQXJnKSxcbiAgICAgICAgb3B0aW9uczogbWVyZ2VkLFxuICAgIH07XG59XG5cbi8vIFRPRE86IGVhc2llciB3YXkgdG8gYWRkIG5ldyBob29rcz8gbmVlZCB0byB1cGRhdGUgYSBtaWxsaW9uIHRoaW5nc1xuZnVuY3Rpb24gY3JlYXRlUGx1Z2luKGlucHV0KSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgaWQ6IGd1aWQoKSxcbiAgICAgICAgbmFtZTogaW5wdXQubmFtZSxcbiAgICAgICAgcHJlbWl1bVJlbGVhc2VEYXRlOiBpbnB1dC5wcmVtaXVtUmVsZWFzZURhdGUgPyBuZXcgRGF0ZShpbnB1dC5wcmVtaXVtUmVsZWFzZURhdGUpIDogdW5kZWZpbmVkLFxuICAgICAgICBkZXBzOiBpbnB1dC5kZXBzIHx8IFtdLFxuICAgICAgICByZWR1Y2VyczogaW5wdXQucmVkdWNlcnMgfHwgW10sXG4gICAgICAgIGlzTG9hZGluZ0Z1bmNzOiBpbnB1dC5pc0xvYWRpbmdGdW5jcyB8fCBbXSxcbiAgICAgICAgY29udGV4dEluaXQ6IFtdLmNvbmNhdChpbnB1dC5jb250ZXh0SW5pdCB8fCBbXSksXG4gICAgICAgIGV2ZW50UmVmaW5lcnM6IGlucHV0LmV2ZW50UmVmaW5lcnMgfHwge30sXG4gICAgICAgIGV2ZW50RGVmTWVtYmVyQWRkZXJzOiBpbnB1dC5ldmVudERlZk1lbWJlckFkZGVycyB8fCBbXSxcbiAgICAgICAgZXZlbnRTb3VyY2VSZWZpbmVyczogaW5wdXQuZXZlbnRTb3VyY2VSZWZpbmVycyB8fCB7fSxcbiAgICAgICAgaXNEcmFnZ2FibGVUcmFuc2Zvcm1lcnM6IGlucHV0LmlzRHJhZ2dhYmxlVHJhbnNmb3JtZXJzIHx8IFtdLFxuICAgICAgICBldmVudERyYWdNdXRhdGlvbk1hc3NhZ2VyczogaW5wdXQuZXZlbnREcmFnTXV0YXRpb25NYXNzYWdlcnMgfHwgW10sXG4gICAgICAgIGV2ZW50RGVmTXV0YXRpb25BcHBsaWVyczogaW5wdXQuZXZlbnREZWZNdXRhdGlvbkFwcGxpZXJzIHx8IFtdLFxuICAgICAgICBkYXRlU2VsZWN0aW9uVHJhbnNmb3JtZXJzOiBpbnB1dC5kYXRlU2VsZWN0aW9uVHJhbnNmb3JtZXJzIHx8IFtdLFxuICAgICAgICBkYXRlUG9pbnRUcmFuc2Zvcm1zOiBpbnB1dC5kYXRlUG9pbnRUcmFuc2Zvcm1zIHx8IFtdLFxuICAgICAgICBkYXRlU3BhblRyYW5zZm9ybXM6IGlucHV0LmRhdGVTcGFuVHJhbnNmb3JtcyB8fCBbXSxcbiAgICAgICAgdmlld3M6IGlucHV0LnZpZXdzIHx8IHt9LFxuICAgICAgICB2aWV3UHJvcHNUcmFuc2Zvcm1lcnM6IGlucHV0LnZpZXdQcm9wc1RyYW5zZm9ybWVycyB8fCBbXSxcbiAgICAgICAgaXNQcm9wc1ZhbGlkOiBpbnB1dC5pc1Byb3BzVmFsaWQgfHwgbnVsbCxcbiAgICAgICAgZXh0ZXJuYWxEZWZUcmFuc2Zvcm1zOiBpbnB1dC5leHRlcm5hbERlZlRyYW5zZm9ybXMgfHwgW10sXG4gICAgICAgIHZpZXdDb250YWluZXJBcHBlbmRzOiBpbnB1dC52aWV3Q29udGFpbmVyQXBwZW5kcyB8fCBbXSxcbiAgICAgICAgZXZlbnREcm9wVHJhbnNmb3JtZXJzOiBpbnB1dC5ldmVudERyb3BUcmFuc2Zvcm1lcnMgfHwgW10sXG4gICAgICAgIGNvbXBvbmVudEludGVyYWN0aW9uczogaW5wdXQuY29tcG9uZW50SW50ZXJhY3Rpb25zIHx8IFtdLFxuICAgICAgICBjYWxlbmRhckludGVyYWN0aW9uczogaW5wdXQuY2FsZW5kYXJJbnRlcmFjdGlvbnMgfHwgW10sXG4gICAgICAgIHRoZW1lQ2xhc3NlczogaW5wdXQudGhlbWVDbGFzc2VzIHx8IHt9LFxuICAgICAgICBldmVudFNvdXJjZURlZnM6IGlucHV0LmV2ZW50U291cmNlRGVmcyB8fCBbXSxcbiAgICAgICAgY21kRm9ybWF0dGVyOiBpbnB1dC5jbWRGb3JtYXR0ZXIsXG4gICAgICAgIHJlY3VycmluZ1R5cGVzOiBpbnB1dC5yZWN1cnJpbmdUeXBlcyB8fCBbXSxcbiAgICAgICAgbmFtZWRUaW1lWm9uZWRJbXBsOiBpbnB1dC5uYW1lZFRpbWVab25lZEltcGwsXG4gICAgICAgIGluaXRpYWxWaWV3OiBpbnB1dC5pbml0aWFsVmlldyB8fCAnJyxcbiAgICAgICAgZWxlbWVudERyYWdnaW5nSW1wbDogaW5wdXQuZWxlbWVudERyYWdnaW5nSW1wbCxcbiAgICAgICAgb3B0aW9uQ2hhbmdlSGFuZGxlcnM6IGlucHV0Lm9wdGlvbkNoYW5nZUhhbmRsZXJzIHx8IHt9LFxuICAgICAgICBzY3JvbGxHcmlkSW1wbDogaW5wdXQuc2Nyb2xsR3JpZEltcGwgfHwgbnVsbCxcbiAgICAgICAgbGlzdGVuZXJSZWZpbmVyczogaW5wdXQubGlzdGVuZXJSZWZpbmVycyB8fCB7fSxcbiAgICAgICAgb3B0aW9uUmVmaW5lcnM6IGlucHV0Lm9wdGlvblJlZmluZXJzIHx8IHt9LFxuICAgICAgICBwcm9wU2V0SGFuZGxlcnM6IGlucHV0LnByb3BTZXRIYW5kbGVycyB8fCB7fSxcbiAgICB9O1xufVxuZnVuY3Rpb24gYnVpbGRQbHVnaW5Ib29rcyhwbHVnaW5EZWZzLCBnbG9iYWxEZWZzKSB7XG4gICAgbGV0IGN1cnJlbnRQbHVnaW5JZHMgPSB7fTtcbiAgICBsZXQgaG9va3MgPSB7XG4gICAgICAgIHByZW1pdW1SZWxlYXNlRGF0ZTogdW5kZWZpbmVkLFxuICAgICAgICByZWR1Y2VyczogW10sXG4gICAgICAgIGlzTG9hZGluZ0Z1bmNzOiBbXSxcbiAgICAgICAgY29udGV4dEluaXQ6IFtdLFxuICAgICAgICBldmVudFJlZmluZXJzOiB7fSxcbiAgICAgICAgZXZlbnREZWZNZW1iZXJBZGRlcnM6IFtdLFxuICAgICAgICBldmVudFNvdXJjZVJlZmluZXJzOiB7fSxcbiAgICAgICAgaXNEcmFnZ2FibGVUcmFuc2Zvcm1lcnM6IFtdLFxuICAgICAgICBldmVudERyYWdNdXRhdGlvbk1hc3NhZ2VyczogW10sXG4gICAgICAgIGV2ZW50RGVmTXV0YXRpb25BcHBsaWVyczogW10sXG4gICAgICAgIGRhdGVTZWxlY3Rpb25UcmFuc2Zvcm1lcnM6IFtdLFxuICAgICAgICBkYXRlUG9pbnRUcmFuc2Zvcm1zOiBbXSxcbiAgICAgICAgZGF0ZVNwYW5UcmFuc2Zvcm1zOiBbXSxcbiAgICAgICAgdmlld3M6IHt9LFxuICAgICAgICB2aWV3UHJvcHNUcmFuc2Zvcm1lcnM6IFtdLFxuICAgICAgICBpc1Byb3BzVmFsaWQ6IG51bGwsXG4gICAgICAgIGV4dGVybmFsRGVmVHJhbnNmb3JtczogW10sXG4gICAgICAgIHZpZXdDb250YWluZXJBcHBlbmRzOiBbXSxcbiAgICAgICAgZXZlbnREcm9wVHJhbnNmb3JtZXJzOiBbXSxcbiAgICAgICAgY29tcG9uZW50SW50ZXJhY3Rpb25zOiBbXSxcbiAgICAgICAgY2FsZW5kYXJJbnRlcmFjdGlvbnM6IFtdLFxuICAgICAgICB0aGVtZUNsYXNzZXM6IHt9LFxuICAgICAgICBldmVudFNvdXJjZURlZnM6IFtdLFxuICAgICAgICBjbWRGb3JtYXR0ZXI6IG51bGwsXG4gICAgICAgIHJlY3VycmluZ1R5cGVzOiBbXSxcbiAgICAgICAgbmFtZWRUaW1lWm9uZWRJbXBsOiBudWxsLFxuICAgICAgICBpbml0aWFsVmlldzogJycsXG4gICAgICAgIGVsZW1lbnREcmFnZ2luZ0ltcGw6IG51bGwsXG4gICAgICAgIG9wdGlvbkNoYW5nZUhhbmRsZXJzOiB7fSxcbiAgICAgICAgc2Nyb2xsR3JpZEltcGw6IG51bGwsXG4gICAgICAgIGxpc3RlbmVyUmVmaW5lcnM6IHt9LFxuICAgICAgICBvcHRpb25SZWZpbmVyczoge30sXG4gICAgICAgIHByb3BTZXRIYW5kbGVyczoge30sXG4gICAgfTtcbiAgICBmdW5jdGlvbiBhZGREZWZzKGRlZnMpIHtcbiAgICAgICAgZm9yIChsZXQgZGVmIG9mIGRlZnMpIHtcbiAgICAgICAgICAgIGNvbnN0IHBsdWdpbk5hbWUgPSBkZWYubmFtZTtcbiAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRJZCA9IGN1cnJlbnRQbHVnaW5JZHNbcGx1Z2luTmFtZV07XG4gICAgICAgICAgICBpZiAoY3VycmVudElkID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBjdXJyZW50UGx1Z2luSWRzW3BsdWdpbk5hbWVdID0gZGVmLmlkO1xuICAgICAgICAgICAgICAgIGFkZERlZnMoZGVmLmRlcHMpO1xuICAgICAgICAgICAgICAgIGhvb2tzID0gY29tYmluZUhvb2tzKGhvb2tzLCBkZWYpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoY3VycmVudElkICE9PSBkZWYuaWQpIHtcbiAgICAgICAgICAgICAgICAvLyBkaWZmZXJlbnQgSUQgdGhhbiB0aGUgb25lIGFscmVhZHkgYWRkZWRcbiAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oYER1cGxpY2F0ZSBwbHVnaW4gJyR7cGx1Z2luTmFtZX0nYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKHBsdWdpbkRlZnMpIHtcbiAgICAgICAgYWRkRGVmcyhwbHVnaW5EZWZzKTtcbiAgICB9XG4gICAgYWRkRGVmcyhnbG9iYWxEZWZzKTtcbiAgICByZXR1cm4gaG9va3M7XG59XG5mdW5jdGlvbiBidWlsZEJ1aWxkUGx1Z2luSG9va3MoKSB7XG4gICAgbGV0IGN1cnJlbnRPdmVycmlkZURlZnMgPSBbXTtcbiAgICBsZXQgY3VycmVudEdsb2JhbERlZnMgPSBbXTtcbiAgICBsZXQgY3VycmVudEhvb2tzO1xuICAgIHJldHVybiAob3ZlcnJpZGVEZWZzLCBnbG9iYWxEZWZzKSA9PiB7XG4gICAgICAgIGlmICghY3VycmVudEhvb2tzIHx8ICFpc0FycmF5c0VxdWFsKG92ZXJyaWRlRGVmcywgY3VycmVudE92ZXJyaWRlRGVmcykgfHwgIWlzQXJyYXlzRXF1YWwoZ2xvYmFsRGVmcywgY3VycmVudEdsb2JhbERlZnMpKSB7XG4gICAgICAgICAgICBjdXJyZW50SG9va3MgPSBidWlsZFBsdWdpbkhvb2tzKG92ZXJyaWRlRGVmcywgZ2xvYmFsRGVmcyk7XG4gICAgICAgIH1cbiAgICAgICAgY3VycmVudE92ZXJyaWRlRGVmcyA9IG92ZXJyaWRlRGVmcztcbiAgICAgICAgY3VycmVudEdsb2JhbERlZnMgPSBnbG9iYWxEZWZzO1xuICAgICAgICByZXR1cm4gY3VycmVudEhvb2tzO1xuICAgIH07XG59XG5mdW5jdGlvbiBjb21iaW5lSG9va3MoaG9va3MwLCBob29rczEpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBwcmVtaXVtUmVsZWFzZURhdGU6IGNvbXBhcmVPcHRpb25hbERhdGVzKGhvb2tzMC5wcmVtaXVtUmVsZWFzZURhdGUsIGhvb2tzMS5wcmVtaXVtUmVsZWFzZURhdGUpLFxuICAgICAgICByZWR1Y2VyczogaG9va3MwLnJlZHVjZXJzLmNvbmNhdChob29rczEucmVkdWNlcnMpLFxuICAgICAgICBpc0xvYWRpbmdGdW5jczogaG9va3MwLmlzTG9hZGluZ0Z1bmNzLmNvbmNhdChob29rczEuaXNMb2FkaW5nRnVuY3MpLFxuICAgICAgICBjb250ZXh0SW5pdDogaG9va3MwLmNvbnRleHRJbml0LmNvbmNhdChob29rczEuY29udGV4dEluaXQpLFxuICAgICAgICBldmVudFJlZmluZXJzOiBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sIGhvb2tzMC5ldmVudFJlZmluZXJzKSwgaG9va3MxLmV2ZW50UmVmaW5lcnMpLFxuICAgICAgICBldmVudERlZk1lbWJlckFkZGVyczogaG9va3MwLmV2ZW50RGVmTWVtYmVyQWRkZXJzLmNvbmNhdChob29rczEuZXZlbnREZWZNZW1iZXJBZGRlcnMpLFxuICAgICAgICBldmVudFNvdXJjZVJlZmluZXJzOiBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sIGhvb2tzMC5ldmVudFNvdXJjZVJlZmluZXJzKSwgaG9va3MxLmV2ZW50U291cmNlUmVmaW5lcnMpLFxuICAgICAgICBpc0RyYWdnYWJsZVRyYW5zZm9ybWVyczogaG9va3MwLmlzRHJhZ2dhYmxlVHJhbnNmb3JtZXJzLmNvbmNhdChob29rczEuaXNEcmFnZ2FibGVUcmFuc2Zvcm1lcnMpLFxuICAgICAgICBldmVudERyYWdNdXRhdGlvbk1hc3NhZ2VyczogaG9va3MwLmV2ZW50RHJhZ011dGF0aW9uTWFzc2FnZXJzLmNvbmNhdChob29rczEuZXZlbnREcmFnTXV0YXRpb25NYXNzYWdlcnMpLFxuICAgICAgICBldmVudERlZk11dGF0aW9uQXBwbGllcnM6IGhvb2tzMC5ldmVudERlZk11dGF0aW9uQXBwbGllcnMuY29uY2F0KGhvb2tzMS5ldmVudERlZk11dGF0aW9uQXBwbGllcnMpLFxuICAgICAgICBkYXRlU2VsZWN0aW9uVHJhbnNmb3JtZXJzOiBob29rczAuZGF0ZVNlbGVjdGlvblRyYW5zZm9ybWVycy5jb25jYXQoaG9va3MxLmRhdGVTZWxlY3Rpb25UcmFuc2Zvcm1lcnMpLFxuICAgICAgICBkYXRlUG9pbnRUcmFuc2Zvcm1zOiBob29rczAuZGF0ZVBvaW50VHJhbnNmb3Jtcy5jb25jYXQoaG9va3MxLmRhdGVQb2ludFRyYW5zZm9ybXMpLFxuICAgICAgICBkYXRlU3BhblRyYW5zZm9ybXM6IGhvb2tzMC5kYXRlU3BhblRyYW5zZm9ybXMuY29uY2F0KGhvb2tzMS5kYXRlU3BhblRyYW5zZm9ybXMpLFxuICAgICAgICB2aWV3czogT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCBob29rczAudmlld3MpLCBob29rczEudmlld3MpLFxuICAgICAgICB2aWV3UHJvcHNUcmFuc2Zvcm1lcnM6IGhvb2tzMC52aWV3UHJvcHNUcmFuc2Zvcm1lcnMuY29uY2F0KGhvb2tzMS52aWV3UHJvcHNUcmFuc2Zvcm1lcnMpLFxuICAgICAgICBpc1Byb3BzVmFsaWQ6IGhvb2tzMS5pc1Byb3BzVmFsaWQgfHwgaG9va3MwLmlzUHJvcHNWYWxpZCxcbiAgICAgICAgZXh0ZXJuYWxEZWZUcmFuc2Zvcm1zOiBob29rczAuZXh0ZXJuYWxEZWZUcmFuc2Zvcm1zLmNvbmNhdChob29rczEuZXh0ZXJuYWxEZWZUcmFuc2Zvcm1zKSxcbiAgICAgICAgdmlld0NvbnRhaW5lckFwcGVuZHM6IGhvb2tzMC52aWV3Q29udGFpbmVyQXBwZW5kcy5jb25jYXQoaG9va3MxLnZpZXdDb250YWluZXJBcHBlbmRzKSxcbiAgICAgICAgZXZlbnREcm9wVHJhbnNmb3JtZXJzOiBob29rczAuZXZlbnREcm9wVHJhbnNmb3JtZXJzLmNvbmNhdChob29rczEuZXZlbnREcm9wVHJhbnNmb3JtZXJzKSxcbiAgICAgICAgY2FsZW5kYXJJbnRlcmFjdGlvbnM6IGhvb2tzMC5jYWxlbmRhckludGVyYWN0aW9ucy5jb25jYXQoaG9va3MxLmNhbGVuZGFySW50ZXJhY3Rpb25zKSxcbiAgICAgICAgY29tcG9uZW50SW50ZXJhY3Rpb25zOiBob29rczAuY29tcG9uZW50SW50ZXJhY3Rpb25zLmNvbmNhdChob29rczEuY29tcG9uZW50SW50ZXJhY3Rpb25zKSxcbiAgICAgICAgdGhlbWVDbGFzc2VzOiBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sIGhvb2tzMC50aGVtZUNsYXNzZXMpLCBob29rczEudGhlbWVDbGFzc2VzKSxcbiAgICAgICAgZXZlbnRTb3VyY2VEZWZzOiBob29rczAuZXZlbnRTb3VyY2VEZWZzLmNvbmNhdChob29rczEuZXZlbnRTb3VyY2VEZWZzKSxcbiAgICAgICAgY21kRm9ybWF0dGVyOiBob29rczEuY21kRm9ybWF0dGVyIHx8IGhvb2tzMC5jbWRGb3JtYXR0ZXIsXG4gICAgICAgIHJlY3VycmluZ1R5cGVzOiBob29rczAucmVjdXJyaW5nVHlwZXMuY29uY2F0KGhvb2tzMS5yZWN1cnJpbmdUeXBlcyksXG4gICAgICAgIG5hbWVkVGltZVpvbmVkSW1wbDogaG9va3MxLm5hbWVkVGltZVpvbmVkSW1wbCB8fCBob29rczAubmFtZWRUaW1lWm9uZWRJbXBsLFxuICAgICAgICBpbml0aWFsVmlldzogaG9va3MwLmluaXRpYWxWaWV3IHx8IGhvb2tzMS5pbml0aWFsVmlldyxcbiAgICAgICAgZWxlbWVudERyYWdnaW5nSW1wbDogaG9va3MwLmVsZW1lbnREcmFnZ2luZ0ltcGwgfHwgaG9va3MxLmVsZW1lbnREcmFnZ2luZ0ltcGwsXG4gICAgICAgIG9wdGlvbkNoYW5nZUhhbmRsZXJzOiBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sIGhvb2tzMC5vcHRpb25DaGFuZ2VIYW5kbGVycyksIGhvb2tzMS5vcHRpb25DaGFuZ2VIYW5kbGVycyksXG4gICAgICAgIHNjcm9sbEdyaWRJbXBsOiBob29rczEuc2Nyb2xsR3JpZEltcGwgfHwgaG9va3MwLnNjcm9sbEdyaWRJbXBsLFxuICAgICAgICBsaXN0ZW5lclJlZmluZXJzOiBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sIGhvb2tzMC5saXN0ZW5lclJlZmluZXJzKSwgaG9va3MxLmxpc3RlbmVyUmVmaW5lcnMpLFxuICAgICAgICBvcHRpb25SZWZpbmVyczogT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCBob29rczAub3B0aW9uUmVmaW5lcnMpLCBob29rczEub3B0aW9uUmVmaW5lcnMpLFxuICAgICAgICBwcm9wU2V0SGFuZGxlcnM6IE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgaG9va3MwLnByb3BTZXRIYW5kbGVycyksIGhvb2tzMS5wcm9wU2V0SGFuZGxlcnMpLFxuICAgIH07XG59XG5mdW5jdGlvbiBjb21wYXJlT3B0aW9uYWxEYXRlcyhkYXRlMCwgZGF0ZTEpIHtcbiAgICBpZiAoZGF0ZTAgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gZGF0ZTE7XG4gICAgfVxuICAgIGlmIChkYXRlMSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBkYXRlMDtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBEYXRlKE1hdGgubWF4KGRhdGUwLnZhbHVlT2YoKSwgZGF0ZTEudmFsdWVPZigpKSk7XG59XG5cbmNsYXNzIFN0YW5kYXJkVGhlbWUgZXh0ZW5kcyBUaGVtZSB7XG59XG5TdGFuZGFyZFRoZW1lLnByb3RvdHlwZS5jbGFzc2VzID0ge1xuICAgIHJvb3Q6ICdmYy10aGVtZS1zdGFuZGFyZCcsXG4gICAgdGFibGVDZWxsU2hhZGVkOiAnZmMtY2VsbC1zaGFkZWQnLFxuICAgIGJ1dHRvbkdyb3VwOiAnZmMtYnV0dG9uLWdyb3VwJyxcbiAgICBidXR0b246ICdmYy1idXR0b24gZmMtYnV0dG9uLXByaW1hcnknLFxuICAgIGJ1dHRvbkFjdGl2ZTogJ2ZjLWJ1dHRvbi1hY3RpdmUnLFxufTtcblN0YW5kYXJkVGhlbWUucHJvdG90eXBlLmJhc2VJY29uQ2xhc3MgPSAnZmMtaWNvbic7XG5TdGFuZGFyZFRoZW1lLnByb3RvdHlwZS5pY29uQ2xhc3NlcyA9IHtcbiAgICBjbG9zZTogJ2ZjLWljb24teCcsXG4gICAgcHJldjogJ2ZjLWljb24tY2hldnJvbi1sZWZ0JyxcbiAgICBuZXh0OiAnZmMtaWNvbi1jaGV2cm9uLXJpZ2h0JyxcbiAgICBwcmV2WWVhcjogJ2ZjLWljb24tY2hldnJvbnMtbGVmdCcsXG4gICAgbmV4dFllYXI6ICdmYy1pY29uLWNoZXZyb25zLXJpZ2h0Jyxcbn07XG5TdGFuZGFyZFRoZW1lLnByb3RvdHlwZS5ydGxJY29uQ2xhc3NlcyA9IHtcbiAgICBwcmV2OiAnZmMtaWNvbi1jaGV2cm9uLXJpZ2h0JyxcbiAgICBuZXh0OiAnZmMtaWNvbi1jaGV2cm9uLWxlZnQnLFxuICAgIHByZXZZZWFyOiAnZmMtaWNvbi1jaGV2cm9ucy1yaWdodCcsXG4gICAgbmV4dFllYXI6ICdmYy1pY29uLWNoZXZyb25zLWxlZnQnLFxufTtcblN0YW5kYXJkVGhlbWUucHJvdG90eXBlLmljb25PdmVycmlkZU9wdGlvbiA9ICdidXR0b25JY29ucyc7IC8vIFRPRE86IG1ha2UgVFMtZnJpZW5kbHlcblN0YW5kYXJkVGhlbWUucHJvdG90eXBlLmljb25PdmVycmlkZUN1c3RvbUJ1dHRvbk9wdGlvbiA9ICdpY29uJztcblN0YW5kYXJkVGhlbWUucHJvdG90eXBlLmljb25PdmVycmlkZVByZWZpeCA9ICdmYy1pY29uLSc7XG5cbmZ1bmN0aW9uIGNvbXBpbGVWaWV3RGVmcyhkZWZhdWx0Q29uZmlncywgb3ZlcnJpZGVDb25maWdzKSB7XG4gICAgbGV0IGhhc2ggPSB7fTtcbiAgICBsZXQgdmlld1R5cGU7XG4gICAgZm9yICh2aWV3VHlwZSBpbiBkZWZhdWx0Q29uZmlncykge1xuICAgICAgICBlbnN1cmVWaWV3RGVmKHZpZXdUeXBlLCBoYXNoLCBkZWZhdWx0Q29uZmlncywgb3ZlcnJpZGVDb25maWdzKTtcbiAgICB9XG4gICAgZm9yICh2aWV3VHlwZSBpbiBvdmVycmlkZUNvbmZpZ3MpIHtcbiAgICAgICAgZW5zdXJlVmlld0RlZih2aWV3VHlwZSwgaGFzaCwgZGVmYXVsdENvbmZpZ3MsIG92ZXJyaWRlQ29uZmlncyk7XG4gICAgfVxuICAgIHJldHVybiBoYXNoO1xufVxuZnVuY3Rpb24gZW5zdXJlVmlld0RlZih2aWV3VHlwZSwgaGFzaCwgZGVmYXVsdENvbmZpZ3MsIG92ZXJyaWRlQ29uZmlncykge1xuICAgIGlmIChoYXNoW3ZpZXdUeXBlXSkge1xuICAgICAgICByZXR1cm4gaGFzaFt2aWV3VHlwZV07XG4gICAgfVxuICAgIGxldCB2aWV3RGVmID0gYnVpbGRWaWV3RGVmKHZpZXdUeXBlLCBoYXNoLCBkZWZhdWx0Q29uZmlncywgb3ZlcnJpZGVDb25maWdzKTtcbiAgICBpZiAodmlld0RlZikge1xuICAgICAgICBoYXNoW3ZpZXdUeXBlXSA9IHZpZXdEZWY7XG4gICAgfVxuICAgIHJldHVybiB2aWV3RGVmO1xufVxuZnVuY3Rpb24gYnVpbGRWaWV3RGVmKHZpZXdUeXBlLCBoYXNoLCBkZWZhdWx0Q29uZmlncywgb3ZlcnJpZGVDb25maWdzKSB7XG4gICAgbGV0IGRlZmF1bHRDb25maWcgPSBkZWZhdWx0Q29uZmlnc1t2aWV3VHlwZV07XG4gICAgbGV0IG92ZXJyaWRlQ29uZmlnID0gb3ZlcnJpZGVDb25maWdzW3ZpZXdUeXBlXTtcbiAgICBsZXQgcXVlcnlQcm9wID0gKG5hbWUpID0+ICgoZGVmYXVsdENvbmZpZyAmJiBkZWZhdWx0Q29uZmlnW25hbWVdICE9PSBudWxsKSA/IGRlZmF1bHRDb25maWdbbmFtZV0gOlxuICAgICAgICAoKG92ZXJyaWRlQ29uZmlnICYmIG92ZXJyaWRlQ29uZmlnW25hbWVdICE9PSBudWxsKSA/IG92ZXJyaWRlQ29uZmlnW25hbWVdIDogbnVsbCkpO1xuICAgIGxldCB0aGVDb21wb25lbnQgPSBxdWVyeVByb3AoJ2NvbXBvbmVudCcpO1xuICAgIGxldCBzdXBlclR5cGUgPSBxdWVyeVByb3AoJ3N1cGVyVHlwZScpO1xuICAgIGxldCBzdXBlckRlZiA9IG51bGw7XG4gICAgaWYgKHN1cGVyVHlwZSkge1xuICAgICAgICBpZiAoc3VwZXJUeXBlID09PSB2aWV3VHlwZSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW5cXCd0IGhhdmUgYSBjdXN0b20gdmlldyB0eXBlIHRoYXQgcmVmZXJlbmNlcyBpdHNlbGYnKTtcbiAgICAgICAgfVxuICAgICAgICBzdXBlckRlZiA9IGVuc3VyZVZpZXdEZWYoc3VwZXJUeXBlLCBoYXNoLCBkZWZhdWx0Q29uZmlncywgb3ZlcnJpZGVDb25maWdzKTtcbiAgICB9XG4gICAgaWYgKCF0aGVDb21wb25lbnQgJiYgc3VwZXJEZWYpIHtcbiAgICAgICAgdGhlQ29tcG9uZW50ID0gc3VwZXJEZWYuY29tcG9uZW50O1xuICAgIH1cbiAgICBpZiAoIXRoZUNvbXBvbmVudCkge1xuICAgICAgICByZXR1cm4gbnVsbDsgLy8gZG9uJ3QgdGhyb3cgYSB3YXJuaW5nLCBtaWdodCBiZSBzZXR0aW5ncyBmb3IgYSBzaW5nbGUtdW5pdCB2aWV3XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6IHZpZXdUeXBlLFxuICAgICAgICBjb21wb25lbnQ6IHRoZUNvbXBvbmVudCxcbiAgICAgICAgZGVmYXVsdHM6IE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgKHN1cGVyRGVmID8gc3VwZXJEZWYuZGVmYXVsdHMgOiB7fSkpLCAoZGVmYXVsdENvbmZpZyA/IGRlZmF1bHRDb25maWcucmF3T3B0aW9ucyA6IHt9KSksXG4gICAgICAgIG92ZXJyaWRlczogT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCAoc3VwZXJEZWYgPyBzdXBlckRlZi5vdmVycmlkZXMgOiB7fSkpLCAob3ZlcnJpZGVDb25maWcgPyBvdmVycmlkZUNvbmZpZy5yYXdPcHRpb25zIDoge30pKSxcbiAgICB9O1xufVxuXG5mdW5jdGlvbiBwYXJzZVZpZXdDb25maWdzKGlucHV0cykge1xuICAgIHJldHVybiBtYXBIYXNoKGlucHV0cywgcGFyc2VWaWV3Q29uZmlnKTtcbn1cbmZ1bmN0aW9uIHBhcnNlVmlld0NvbmZpZyhpbnB1dCkge1xuICAgIGxldCByYXdPcHRpb25zID0gdHlwZW9mIGlucHV0ID09PSAnZnVuY3Rpb24nID9cbiAgICAgICAgeyBjb21wb25lbnQ6IGlucHV0IH0gOlxuICAgICAgICBpbnB1dDtcbiAgICBsZXQgeyBjb21wb25lbnQgfSA9IHJhd09wdGlvbnM7XG4gICAgaWYgKHJhd09wdGlvbnMuY29udGVudCkge1xuICAgICAgICBjb21wb25lbnQgPSBjcmVhdGVWaWV3SG9va0NvbXBvbmVudChyYXdPcHRpb25zKTtcbiAgICAgICAgLy8gVE9ETzogcmVtb3ZlIGNvbnRlbnQvY2xhc3NOYW1lcy9kaWRNb3VudC9ldGMgZnJvbSBvcHRpb25zP1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICBzdXBlclR5cGU6IHJhd09wdGlvbnMudHlwZSxcbiAgICAgICAgY29tcG9uZW50OiBjb21wb25lbnQsXG4gICAgICAgIHJhd09wdGlvbnMsIC8vIGluY2x1ZGVzIHR5cGUgYW5kIGNvbXBvbmVudCB0b28gOihcbiAgICB9O1xufVxuZnVuY3Rpb24gY3JlYXRlVmlld0hvb2tDb21wb25lbnQob3B0aW9ucykge1xuICAgIHJldHVybiAodmlld1Byb3BzKSA9PiAoY3JlYXRlRWxlbWVudChWaWV3Q29udGV4dFR5cGUuQ29uc3VtZXIsIG51bGwsIChjb250ZXh0KSA9PiAoY3JlYXRlRWxlbWVudChDb250ZW50Q29udGFpbmVyLCB7IGVsVGFnOiBcImRpdlwiLCBlbENsYXNzZXM6IGJ1aWxkVmlld0NsYXNzTmFtZXMoY29udGV4dC52aWV3U3BlYyksIHJlbmRlclByb3BzOiBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sIHZpZXdQcm9wcyksIHsgbmV4dERheVRocmVzaG9sZDogY29udGV4dC5vcHRpb25zLm5leHREYXlUaHJlc2hvbGQgfSksIGdlbmVyYXRvck5hbWU6IHVuZGVmaW5lZCwgZ2VuZXJhdG9yOiBvcHRpb25zLmNvbnRlbnQsIGNsYXNzTmFtZUdlbmVyYXRvcjogb3B0aW9ucy5jbGFzc05hbWVzLCBkaWRNb3VudDogb3B0aW9ucy5kaWRNb3VudCwgd2lsbFVubW91bnQ6IG9wdGlvbnMud2lsbFVubW91bnQgfSkpKSk7XG59XG5cbmZ1bmN0aW9uIGJ1aWxkVmlld1NwZWNzKGRlZmF1bHRJbnB1dHMsIG9wdGlvbk92ZXJyaWRlcywgZHluYW1pY09wdGlvbk92ZXJyaWRlcywgbG9jYWxlRGVmYXVsdHMpIHtcbiAgICBsZXQgZGVmYXVsdENvbmZpZ3MgPSBwYXJzZVZpZXdDb25maWdzKGRlZmF1bHRJbnB1dHMpO1xuICAgIGxldCBvdmVycmlkZUNvbmZpZ3MgPSBwYXJzZVZpZXdDb25maWdzKG9wdGlvbk92ZXJyaWRlcy52aWV3cyk7XG4gICAgbGV0IHZpZXdEZWZzID0gY29tcGlsZVZpZXdEZWZzKGRlZmF1bHRDb25maWdzLCBvdmVycmlkZUNvbmZpZ3MpO1xuICAgIHJldHVybiBtYXBIYXNoKHZpZXdEZWZzLCAodmlld0RlZikgPT4gYnVpbGRWaWV3U3BlYyh2aWV3RGVmLCBvdmVycmlkZUNvbmZpZ3MsIG9wdGlvbk92ZXJyaWRlcywgZHluYW1pY09wdGlvbk92ZXJyaWRlcywgbG9jYWxlRGVmYXVsdHMpKTtcbn1cbmZ1bmN0aW9uIGJ1aWxkVmlld1NwZWModmlld0RlZiwgb3ZlcnJpZGVDb25maWdzLCBvcHRpb25PdmVycmlkZXMsIGR5bmFtaWNPcHRpb25PdmVycmlkZXMsIGxvY2FsZURlZmF1bHRzKSB7XG4gICAgbGV0IGR1cmF0aW9uSW5wdXQgPSB2aWV3RGVmLm92ZXJyaWRlcy5kdXJhdGlvbiB8fFxuICAgICAgICB2aWV3RGVmLmRlZmF1bHRzLmR1cmF0aW9uIHx8XG4gICAgICAgIGR5bmFtaWNPcHRpb25PdmVycmlkZXMuZHVyYXRpb24gfHxcbiAgICAgICAgb3B0aW9uT3ZlcnJpZGVzLmR1cmF0aW9uO1xuICAgIGxldCBkdXJhdGlvbiA9IG51bGw7XG4gICAgbGV0IGR1cmF0aW9uVW5pdCA9ICcnO1xuICAgIGxldCBzaW5nbGVVbml0ID0gJyc7XG4gICAgbGV0IHNpbmdsZVVuaXRPdmVycmlkZXMgPSB7fTtcbiAgICBpZiAoZHVyYXRpb25JbnB1dCkge1xuICAgICAgICBkdXJhdGlvbiA9IGNyZWF0ZUR1cmF0aW9uQ2FjaGVkKGR1cmF0aW9uSW5wdXQpO1xuICAgICAgICBpZiAoZHVyYXRpb24pIHsgLy8gdmFsaWQ/XG4gICAgICAgICAgICBsZXQgZGVub20gPSBncmVhdGVzdER1cmF0aW9uRGVub21pbmF0b3IoZHVyYXRpb24pO1xuICAgICAgICAgICAgZHVyYXRpb25Vbml0ID0gZGVub20udW5pdDtcbiAgICAgICAgICAgIGlmIChkZW5vbS52YWx1ZSA9PT0gMSkge1xuICAgICAgICAgICAgICAgIHNpbmdsZVVuaXQgPSBkdXJhdGlvblVuaXQ7XG4gICAgICAgICAgICAgICAgc2luZ2xlVW5pdE92ZXJyaWRlcyA9IG92ZXJyaWRlQ29uZmlnc1tkdXJhdGlvblVuaXRdID8gb3ZlcnJpZGVDb25maWdzW2R1cmF0aW9uVW5pdF0ucmF3T3B0aW9ucyA6IHt9O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIGxldCBxdWVyeUJ1dHRvblRleHQgPSAob3B0aW9uc1N1YnNldCkgPT4ge1xuICAgICAgICBsZXQgYnV0dG9uVGV4dE1hcCA9IG9wdGlvbnNTdWJzZXQuYnV0dG9uVGV4dCB8fCB7fTtcbiAgICAgICAgbGV0IGJ1dHRvblRleHRLZXkgPSB2aWV3RGVmLmRlZmF1bHRzLmJ1dHRvblRleHRLZXk7XG4gICAgICAgIGlmIChidXR0b25UZXh0S2V5ICE9IG51bGwgJiYgYnV0dG9uVGV4dE1hcFtidXR0b25UZXh0S2V5XSAhPSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gYnV0dG9uVGV4dE1hcFtidXR0b25UZXh0S2V5XTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoYnV0dG9uVGV4dE1hcFt2aWV3RGVmLnR5cGVdICE9IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBidXR0b25UZXh0TWFwW3ZpZXdEZWYudHlwZV07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGJ1dHRvblRleHRNYXBbc2luZ2xlVW5pdF0gIT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIGJ1dHRvblRleHRNYXBbc2luZ2xlVW5pdF07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcbiAgICBsZXQgcXVlcnlCdXR0b25UaXRsZSA9IChvcHRpb25zU3Vic2V0KSA9PiB7XG4gICAgICAgIGxldCBidXR0b25IaW50cyA9IG9wdGlvbnNTdWJzZXQuYnV0dG9uSGludHMgfHwge307XG4gICAgICAgIGxldCBidXR0b25LZXkgPSB2aWV3RGVmLmRlZmF1bHRzLmJ1dHRvblRleHRLZXk7IC8vIHVzZSBzYW1lIGtleSBhcyB0ZXh0XG4gICAgICAgIGlmIChidXR0b25LZXkgIT0gbnVsbCAmJiBidXR0b25IaW50c1tidXR0b25LZXldICE9IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBidXR0b25IaW50c1tidXR0b25LZXldO1xuICAgICAgICB9XG4gICAgICAgIGlmIChidXR0b25IaW50c1t2aWV3RGVmLnR5cGVdICE9IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiBidXR0b25IaW50c1t2aWV3RGVmLnR5cGVdO1xuICAgICAgICB9XG4gICAgICAgIGlmIChidXR0b25IaW50c1tzaW5nbGVVbml0XSAhPSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gYnV0dG9uSGludHNbc2luZ2xlVW5pdF07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfTtcbiAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiB2aWV3RGVmLnR5cGUsXG4gICAgICAgIGNvbXBvbmVudDogdmlld0RlZi5jb21wb25lbnQsXG4gICAgICAgIGR1cmF0aW9uLFxuICAgICAgICBkdXJhdGlvblVuaXQsXG4gICAgICAgIHNpbmdsZVVuaXQsXG4gICAgICAgIG9wdGlvbkRlZmF1bHRzOiB2aWV3RGVmLmRlZmF1bHRzLFxuICAgICAgICBvcHRpb25PdmVycmlkZXM6IE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgc2luZ2xlVW5pdE92ZXJyaWRlcyksIHZpZXdEZWYub3ZlcnJpZGVzKSxcbiAgICAgICAgYnV0dG9uVGV4dE92ZXJyaWRlOiBxdWVyeUJ1dHRvblRleHQoZHluYW1pY09wdGlvbk92ZXJyaWRlcykgfHxcbiAgICAgICAgICAgIHF1ZXJ5QnV0dG9uVGV4dChvcHRpb25PdmVycmlkZXMpIHx8IC8vIGNvbnN0cnVjdG9yLXNwZWNpZmllZCBidXR0b25UZXh0IGxvb2t1cCBoYXNoIHRha2VzIHByZWNlZGVuY2VcbiAgICAgICAgICAgIHZpZXdEZWYub3ZlcnJpZGVzLmJ1dHRvblRleHQsXG4gICAgICAgIGJ1dHRvblRleHREZWZhdWx0OiBxdWVyeUJ1dHRvblRleHQobG9jYWxlRGVmYXVsdHMpIHx8XG4gICAgICAgICAgICB2aWV3RGVmLmRlZmF1bHRzLmJ1dHRvblRleHQgfHxcbiAgICAgICAgICAgIHF1ZXJ5QnV0dG9uVGV4dChCQVNFX09QVElPTl9ERUZBVUxUUykgfHxcbiAgICAgICAgICAgIHZpZXdEZWYudHlwZSxcbiAgICAgICAgLy8gbm90IERSWVxuICAgICAgICBidXR0b25UaXRsZU92ZXJyaWRlOiBxdWVyeUJ1dHRvblRpdGxlKGR5bmFtaWNPcHRpb25PdmVycmlkZXMpIHx8XG4gICAgICAgICAgICBxdWVyeUJ1dHRvblRpdGxlKG9wdGlvbk92ZXJyaWRlcykgfHxcbiAgICAgICAgICAgIHZpZXdEZWYub3ZlcnJpZGVzLmJ1dHRvbkhpbnQsXG4gICAgICAgIGJ1dHRvblRpdGxlRGVmYXVsdDogcXVlcnlCdXR0b25UaXRsZShsb2NhbGVEZWZhdWx0cykgfHxcbiAgICAgICAgICAgIHZpZXdEZWYuZGVmYXVsdHMuYnV0dG9uSGludCB8fFxuICAgICAgICAgICAgcXVlcnlCdXR0b25UaXRsZShCQVNFX09QVElPTl9ERUZBVUxUUyksXG4gICAgICAgIC8vIHdpbGwgZXZlbnR1YWxseSBmYWxsIGJhY2sgdG8gYnV0dG9uVGV4dFxuICAgIH07XG59XG4vLyBoYWNrIHRvIGdldCBtZW1vaXphdGlvbiB3b3JraW5nXG5sZXQgZHVyYXRpb25JbnB1dE1hcCA9IHt9O1xuZnVuY3Rpb24gY3JlYXRlRHVyYXRpb25DYWNoZWQoZHVyYXRpb25JbnB1dCkge1xuICAgIGxldCBqc29uID0gSlNPTi5zdHJpbmdpZnkoZHVyYXRpb25JbnB1dCk7XG4gICAgbGV0IHJlcyA9IGR1cmF0aW9uSW5wdXRNYXBbanNvbl07XG4gICAgaWYgKHJlcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJlcyA9IGNyZWF0ZUR1cmF0aW9uKGR1cmF0aW9uSW5wdXQpO1xuICAgICAgICBkdXJhdGlvbklucHV0TWFwW2pzb25dID0gcmVzO1xuICAgIH1cbiAgICByZXR1cm4gcmVzO1xufVxuXG5mdW5jdGlvbiByZWR1Y2VWaWV3VHlwZSh2aWV3VHlwZSwgYWN0aW9uKSB7XG4gICAgc3dpdGNoIChhY3Rpb24udHlwZSkge1xuICAgICAgICBjYXNlICdDSEFOR0VfVklFV19UWVBFJzpcbiAgICAgICAgICAgIHZpZXdUeXBlID0gYWN0aW9uLnZpZXdUeXBlO1xuICAgIH1cbiAgICByZXR1cm4gdmlld1R5cGU7XG59XG5cbmZ1bmN0aW9uIHJlZHVjZUR5bmFtaWNPcHRpb25PdmVycmlkZXMoZHluYW1pY09wdGlvbk92ZXJyaWRlcywgYWN0aW9uKSB7XG4gICAgc3dpdGNoIChhY3Rpb24udHlwZSkge1xuICAgICAgICBjYXNlICdTRVRfT1BUSU9OJzpcbiAgICAgICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sIGR5bmFtaWNPcHRpb25PdmVycmlkZXMpLCB7IFthY3Rpb24ub3B0aW9uTmFtZV06IGFjdGlvbi5yYXdPcHRpb25WYWx1ZSB9KTtcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHJldHVybiBkeW5hbWljT3B0aW9uT3ZlcnJpZGVzO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gcmVkdWNlRGF0ZVByb2ZpbGUoY3VycmVudERhdGVQcm9maWxlLCBhY3Rpb24sIGN1cnJlbnREYXRlLCBkYXRlUHJvZmlsZUdlbmVyYXRvcikge1xuICAgIGxldCBkcDtcbiAgICBzd2l0Y2ggKGFjdGlvbi50eXBlKSB7XG4gICAgICAgIGNhc2UgJ0NIQU5HRV9WSUVXX1RZUEUnOlxuICAgICAgICAgICAgcmV0dXJuIGRhdGVQcm9maWxlR2VuZXJhdG9yLmJ1aWxkKGFjdGlvbi5kYXRlTWFya2VyIHx8IGN1cnJlbnREYXRlKTtcbiAgICAgICAgY2FzZSAnQ0hBTkdFX0RBVEUnOlxuICAgICAgICAgICAgcmV0dXJuIGRhdGVQcm9maWxlR2VuZXJhdG9yLmJ1aWxkKGFjdGlvbi5kYXRlTWFya2VyKTtcbiAgICAgICAgY2FzZSAnUFJFVic6XG4gICAgICAgICAgICBkcCA9IGRhdGVQcm9maWxlR2VuZXJhdG9yLmJ1aWxkUHJldihjdXJyZW50RGF0ZVByb2ZpbGUsIGN1cnJlbnREYXRlKTtcbiAgICAgICAgICAgIGlmIChkcC5pc1ZhbGlkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGRwO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ05FWFQnOlxuICAgICAgICAgICAgZHAgPSBkYXRlUHJvZmlsZUdlbmVyYXRvci5idWlsZE5leHQoY3VycmVudERhdGVQcm9maWxlLCBjdXJyZW50RGF0ZSk7XG4gICAgICAgICAgICBpZiAoZHAuaXNWYWxpZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBkcDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrO1xuICAgIH1cbiAgICByZXR1cm4gY3VycmVudERhdGVQcm9maWxlO1xufVxuXG5mdW5jdGlvbiBpbml0RXZlbnRTb3VyY2VzKGNhbGVuZGFyT3B0aW9ucywgZGF0ZVByb2ZpbGUsIGNvbnRleHQpIHtcbiAgICBsZXQgYWN0aXZlUmFuZ2UgPSBkYXRlUHJvZmlsZSA/IGRhdGVQcm9maWxlLmFjdGl2ZVJhbmdlIDogbnVsbDtcbiAgICByZXR1cm4gYWRkU291cmNlcyh7fSwgcGFyc2VJbml0aWFsU291cmNlcyhjYWxlbmRhck9wdGlvbnMsIGNvbnRleHQpLCBhY3RpdmVSYW5nZSwgY29udGV4dCk7XG59XG5mdW5jdGlvbiByZWR1Y2VFdmVudFNvdXJjZXMoZXZlbnRTb3VyY2VzLCBhY3Rpb24sIGRhdGVQcm9maWxlLCBjb250ZXh0KSB7XG4gICAgbGV0IGFjdGl2ZVJhbmdlID0gZGF0ZVByb2ZpbGUgPyBkYXRlUHJvZmlsZS5hY3RpdmVSYW5nZSA6IG51bGw7IC8vIG5lZWQgdGhpcyBjaGVjaz9cbiAgICBzd2l0Y2ggKGFjdGlvbi50eXBlKSB7XG4gICAgICAgIGNhc2UgJ0FERF9FVkVOVF9TT1VSQ0VTJzogLy8gYWxyZWFkeSBwYXJzZWRcbiAgICAgICAgICAgIHJldHVybiBhZGRTb3VyY2VzKGV2ZW50U291cmNlcywgYWN0aW9uLnNvdXJjZXMsIGFjdGl2ZVJhbmdlLCBjb250ZXh0KTtcbiAgICAgICAgY2FzZSAnUkVNT1ZFX0VWRU5UX1NPVVJDRSc6XG4gICAgICAgICAgICByZXR1cm4gcmVtb3ZlU291cmNlKGV2ZW50U291cmNlcywgYWN0aW9uLnNvdXJjZUlkKTtcbiAgICAgICAgY2FzZSAnUFJFVic6IC8vIFRPRE86IGhvdyBkbyB3ZSB0cmFjayBhbGwgYWN0aW9ucyB0aGF0IGFmZmVjdCBkYXRlUHJvZmlsZSA6KFxuICAgICAgICBjYXNlICdORVhUJzpcbiAgICAgICAgY2FzZSAnQ0hBTkdFX0RBVEUnOlxuICAgICAgICBjYXNlICdDSEFOR0VfVklFV19UWVBFJzpcbiAgICAgICAgICAgIGlmIChkYXRlUHJvZmlsZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmZXRjaERpcnR5U291cmNlcyhldmVudFNvdXJjZXMsIGFjdGl2ZVJhbmdlLCBjb250ZXh0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBldmVudFNvdXJjZXM7XG4gICAgICAgIGNhc2UgJ0ZFVENIX0VWRU5UX1NPVVJDRVMnOlxuICAgICAgICAgICAgcmV0dXJuIGZldGNoU291cmNlc0J5SWRzKGV2ZW50U291cmNlcywgYWN0aW9uLnNvdXJjZUlkcyA/IC8vIHdoeSBubyB0eXBlP1xuICAgICAgICAgICAgICAgIGFycmF5VG9IYXNoKGFjdGlvbi5zb3VyY2VJZHMpIDpcbiAgICAgICAgICAgICAgICBleGNsdWRlU3RhdGljU291cmNlcyhldmVudFNvdXJjZXMsIGNvbnRleHQpLCBhY3RpdmVSYW5nZSwgYWN0aW9uLmlzUmVmZXRjaCB8fCBmYWxzZSwgY29udGV4dCk7XG4gICAgICAgIGNhc2UgJ1JFQ0VJVkVfRVZFTlRTJzpcbiAgICAgICAgY2FzZSAnUkVDRUlWRV9FVkVOVF9FUlJPUic6XG4gICAgICAgICAgICByZXR1cm4gcmVjZWl2ZVJlc3BvbnNlKGV2ZW50U291cmNlcywgYWN0aW9uLnNvdXJjZUlkLCBhY3Rpb24uZmV0Y2hJZCwgYWN0aW9uLmZldGNoUmFuZ2UpO1xuICAgICAgICBjYXNlICdSRU1PVkVfQUxMX0VWRU5UX1NPVVJDRVMnOlxuICAgICAgICAgICAgcmV0dXJuIHt9O1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgcmV0dXJuIGV2ZW50U291cmNlcztcbiAgICB9XG59XG5mdW5jdGlvbiByZWR1Y2VFdmVudFNvdXJjZXNOZXdUaW1lWm9uZShldmVudFNvdXJjZXMsIGRhdGVQcm9maWxlLCBjb250ZXh0KSB7XG4gICAgbGV0IGFjdGl2ZVJhbmdlID0gZGF0ZVByb2ZpbGUgPyBkYXRlUHJvZmlsZS5hY3RpdmVSYW5nZSA6IG51bGw7IC8vIG5lZWQgdGhpcyBjaGVjaz9cbiAgICByZXR1cm4gZmV0Y2hTb3VyY2VzQnlJZHMoZXZlbnRTb3VyY2VzLCBleGNsdWRlU3RhdGljU291cmNlcyhldmVudFNvdXJjZXMsIGNvbnRleHQpLCBhY3RpdmVSYW5nZSwgdHJ1ZSwgY29udGV4dCk7XG59XG5mdW5jdGlvbiBjb21wdXRlRXZlbnRTb3VyY2VzTG9hZGluZyhldmVudFNvdXJjZXMpIHtcbiAgICBmb3IgKGxldCBzb3VyY2VJZCBpbiBldmVudFNvdXJjZXMpIHtcbiAgICAgICAgaWYgKGV2ZW50U291cmNlc1tzb3VyY2VJZF0uaXNGZXRjaGluZykge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuZnVuY3Rpb24gYWRkU291cmNlcyhldmVudFNvdXJjZUhhc2gsIHNvdXJjZXMsIGZldGNoUmFuZ2UsIGNvbnRleHQpIHtcbiAgICBsZXQgaGFzaCA9IHt9O1xuICAgIGZvciAobGV0IHNvdXJjZSBvZiBzb3VyY2VzKSB7XG4gICAgICAgIGhhc2hbc291cmNlLnNvdXJjZUlkXSA9IHNvdXJjZTtcbiAgICB9XG4gICAgaWYgKGZldGNoUmFuZ2UpIHtcbiAgICAgICAgaGFzaCA9IGZldGNoRGlydHlTb3VyY2VzKGhhc2gsIGZldGNoUmFuZ2UsIGNvbnRleHQpO1xuICAgIH1cbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCBldmVudFNvdXJjZUhhc2gpLCBoYXNoKTtcbn1cbmZ1bmN0aW9uIHJlbW92ZVNvdXJjZShldmVudFNvdXJjZUhhc2gsIHNvdXJjZUlkKSB7XG4gICAgcmV0dXJuIGZpbHRlckhhc2goZXZlbnRTb3VyY2VIYXNoLCAoZXZlbnRTb3VyY2UpID0+IGV2ZW50U291cmNlLnNvdXJjZUlkICE9PSBzb3VyY2VJZCk7XG59XG5mdW5jdGlvbiBmZXRjaERpcnR5U291cmNlcyhzb3VyY2VIYXNoLCBmZXRjaFJhbmdlLCBjb250ZXh0KSB7XG4gICAgcmV0dXJuIGZldGNoU291cmNlc0J5SWRzKHNvdXJjZUhhc2gsIGZpbHRlckhhc2goc291cmNlSGFzaCwgKGV2ZW50U291cmNlKSA9PiBpc1NvdXJjZURpcnR5KGV2ZW50U291cmNlLCBmZXRjaFJhbmdlLCBjb250ZXh0KSksIGZldGNoUmFuZ2UsIGZhbHNlLCBjb250ZXh0KTtcbn1cbmZ1bmN0aW9uIGlzU291cmNlRGlydHkoZXZlbnRTb3VyY2UsIGZldGNoUmFuZ2UsIGNvbnRleHQpIHtcbiAgICBpZiAoIWRvZXNTb3VyY2VOZWVkUmFuZ2UoZXZlbnRTb3VyY2UsIGNvbnRleHQpKSB7XG4gICAgICAgIHJldHVybiAhZXZlbnRTb3VyY2UubGF0ZXN0RmV0Y2hJZDtcbiAgICB9XG4gICAgcmV0dXJuICFjb250ZXh0Lm9wdGlvbnMubGF6eUZldGNoaW5nIHx8XG4gICAgICAgICFldmVudFNvdXJjZS5mZXRjaFJhbmdlIHx8XG4gICAgICAgIGV2ZW50U291cmNlLmlzRmV0Y2hpbmcgfHwgLy8gYWx3YXlzIGNhbmNlbCBvdXRkYXRlZCBpbi1wcm9ncmVzcyBmZXRjaGVzXG4gICAgICAgIGZldGNoUmFuZ2Uuc3RhcnQgPCBldmVudFNvdXJjZS5mZXRjaFJhbmdlLnN0YXJ0IHx8XG4gICAgICAgIGZldGNoUmFuZ2UuZW5kID4gZXZlbnRTb3VyY2UuZmV0Y2hSYW5nZS5lbmQ7XG59XG5mdW5jdGlvbiBmZXRjaFNvdXJjZXNCeUlkcyhwcmV2U291cmNlcywgc291cmNlSWRIYXNoLCBmZXRjaFJhbmdlLCBpc1JlZmV0Y2gsIGNvbnRleHQpIHtcbiAgICBsZXQgbmV4dFNvdXJjZXMgPSB7fTtcbiAgICBmb3IgKGxldCBzb3VyY2VJZCBpbiBwcmV2U291cmNlcykge1xuICAgICAgICBsZXQgc291cmNlID0gcHJldlNvdXJjZXNbc291cmNlSWRdO1xuICAgICAgICBpZiAoc291cmNlSWRIYXNoW3NvdXJjZUlkXSkge1xuICAgICAgICAgICAgbmV4dFNvdXJjZXNbc291cmNlSWRdID0gZmV0Y2hTb3VyY2Uoc291cmNlLCBmZXRjaFJhbmdlLCBpc1JlZmV0Y2gsIGNvbnRleHQpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgbmV4dFNvdXJjZXNbc291cmNlSWRdID0gc291cmNlO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBuZXh0U291cmNlcztcbn1cbmZ1bmN0aW9uIGZldGNoU291cmNlKGV2ZW50U291cmNlLCBmZXRjaFJhbmdlLCBpc1JlZmV0Y2gsIGNvbnRleHQpIHtcbiAgICBsZXQgeyBvcHRpb25zLCBjYWxlbmRhckFwaSB9ID0gY29udGV4dDtcbiAgICBsZXQgc291cmNlRGVmID0gY29udGV4dC5wbHVnaW5Ib29rcy5ldmVudFNvdXJjZURlZnNbZXZlbnRTb3VyY2Uuc291cmNlRGVmSWRdO1xuICAgIGxldCBmZXRjaElkID0gZ3VpZCgpO1xuICAgIHNvdXJjZURlZi5mZXRjaCh7XG4gICAgICAgIGV2ZW50U291cmNlLFxuICAgICAgICByYW5nZTogZmV0Y2hSYW5nZSxcbiAgICAgICAgaXNSZWZldGNoLFxuICAgICAgICBjb250ZXh0LFxuICAgIH0sIChyZXMpID0+IHtcbiAgICAgICAgbGV0IHsgcmF3RXZlbnRzIH0gPSByZXM7XG4gICAgICAgIGlmIChvcHRpb25zLmV2ZW50U291cmNlU3VjY2Vzcykge1xuICAgICAgICAgICAgcmF3RXZlbnRzID0gb3B0aW9ucy5ldmVudFNvdXJjZVN1Y2Nlc3MuY2FsbChjYWxlbmRhckFwaSwgcmF3RXZlbnRzLCByZXMucmVzcG9uc2UpIHx8IHJhd0V2ZW50cztcbiAgICAgICAgfVxuICAgICAgICBpZiAoZXZlbnRTb3VyY2Uuc3VjY2Vzcykge1xuICAgICAgICAgICAgcmF3RXZlbnRzID0gZXZlbnRTb3VyY2Uuc3VjY2Vzcy5jYWxsKGNhbGVuZGFyQXBpLCByYXdFdmVudHMsIHJlcy5yZXNwb25zZSkgfHwgcmF3RXZlbnRzO1xuICAgICAgICB9XG4gICAgICAgIGNvbnRleHQuZGlzcGF0Y2goe1xuICAgICAgICAgICAgdHlwZTogJ1JFQ0VJVkVfRVZFTlRTJyxcbiAgICAgICAgICAgIHNvdXJjZUlkOiBldmVudFNvdXJjZS5zb3VyY2VJZCxcbiAgICAgICAgICAgIGZldGNoSWQsXG4gICAgICAgICAgICBmZXRjaFJhbmdlLFxuICAgICAgICAgICAgcmF3RXZlbnRzLFxuICAgICAgICB9KTtcbiAgICB9LCAoZXJyb3IpID0+IHtcbiAgICAgICAgbGV0IGVycm9ySGFuZGxlZCA9IGZhbHNlO1xuICAgICAgICBpZiAob3B0aW9ucy5ldmVudFNvdXJjZUZhaWx1cmUpIHtcbiAgICAgICAgICAgIG9wdGlvbnMuZXZlbnRTb3VyY2VGYWlsdXJlLmNhbGwoY2FsZW5kYXJBcGksIGVycm9yKTtcbiAgICAgICAgICAgIGVycm9ySGFuZGxlZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGV2ZW50U291cmNlLmZhaWx1cmUpIHtcbiAgICAgICAgICAgIGV2ZW50U291cmNlLmZhaWx1cmUoZXJyb3IpO1xuICAgICAgICAgICAgZXJyb3JIYW5kbGVkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWVycm9ySGFuZGxlZCkge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKGVycm9yLm1lc3NhZ2UsIGVycm9yKTtcbiAgICAgICAgfVxuICAgICAgICBjb250ZXh0LmRpc3BhdGNoKHtcbiAgICAgICAgICAgIHR5cGU6ICdSRUNFSVZFX0VWRU5UX0VSUk9SJyxcbiAgICAgICAgICAgIHNvdXJjZUlkOiBldmVudFNvdXJjZS5zb3VyY2VJZCxcbiAgICAgICAgICAgIGZldGNoSWQsXG4gICAgICAgICAgICBmZXRjaFJhbmdlLFxuICAgICAgICAgICAgZXJyb3IsXG4gICAgICAgIH0pO1xuICAgIH0pO1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sIGV2ZW50U291cmNlKSwgeyBpc0ZldGNoaW5nOiB0cnVlLCBsYXRlc3RGZXRjaElkOiBmZXRjaElkIH0pO1xufVxuZnVuY3Rpb24gcmVjZWl2ZVJlc3BvbnNlKHNvdXJjZUhhc2gsIHNvdXJjZUlkLCBmZXRjaElkLCBmZXRjaFJhbmdlKSB7XG4gICAgbGV0IGV2ZW50U291cmNlID0gc291cmNlSGFzaFtzb3VyY2VJZF07XG4gICAgaWYgKGV2ZW50U291cmNlICYmIC8vIG5vdCBhbHJlYWR5IHJlbW92ZWRcbiAgICAgICAgZmV0Y2hJZCA9PT0gZXZlbnRTb3VyY2UubGF0ZXN0RmV0Y2hJZCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCBzb3VyY2VIYXNoKSwgeyBbc291cmNlSWRdOiBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sIGV2ZW50U291cmNlKSwgeyBpc0ZldGNoaW5nOiBmYWxzZSwgZmV0Y2hSYW5nZSB9KSB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHNvdXJjZUhhc2g7XG59XG5mdW5jdGlvbiBleGNsdWRlU3RhdGljU291cmNlcyhldmVudFNvdXJjZXMsIGNvbnRleHQpIHtcbiAgICByZXR1cm4gZmlsdGVySGFzaChldmVudFNvdXJjZXMsIChldmVudFNvdXJjZSkgPT4gZG9lc1NvdXJjZU5lZWRSYW5nZShldmVudFNvdXJjZSwgY29udGV4dCkpO1xufVxuZnVuY3Rpb24gcGFyc2VJbml0aWFsU291cmNlcyhyYXdPcHRpb25zLCBjb250ZXh0KSB7XG4gICAgbGV0IHJlZmluZXJzID0gYnVpbGRFdmVudFNvdXJjZVJlZmluZXJzKGNvbnRleHQpO1xuICAgIGxldCByYXdTb3VyY2VzID0gW10uY29uY2F0KHJhd09wdGlvbnMuZXZlbnRTb3VyY2VzIHx8IFtdKTtcbiAgICBsZXQgc291cmNlcyA9IFtdOyAvLyBwYXJzZWRcbiAgICBpZiAocmF3T3B0aW9ucy5pbml0aWFsRXZlbnRzKSB7XG4gICAgICAgIHJhd1NvdXJjZXMudW5zaGlmdChyYXdPcHRpb25zLmluaXRpYWxFdmVudHMpO1xuICAgIH1cbiAgICBpZiAocmF3T3B0aW9ucy5ldmVudHMpIHtcbiAgICAgICAgcmF3U291cmNlcy51bnNoaWZ0KHJhd09wdGlvbnMuZXZlbnRzKTtcbiAgICB9XG4gICAgZm9yIChsZXQgcmF3U291cmNlIG9mIHJhd1NvdXJjZXMpIHtcbiAgICAgICAgbGV0IHNvdXJjZSA9IHBhcnNlRXZlbnRTb3VyY2UocmF3U291cmNlLCBjb250ZXh0LCByZWZpbmVycyk7XG4gICAgICAgIGlmIChzb3VyY2UpIHtcbiAgICAgICAgICAgIHNvdXJjZXMucHVzaChzb3VyY2UpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBzb3VyY2VzO1xufVxuZnVuY3Rpb24gZG9lc1NvdXJjZU5lZWRSYW5nZShldmVudFNvdXJjZSwgY29udGV4dCkge1xuICAgIGxldCBkZWZzID0gY29udGV4dC5wbHVnaW5Ib29rcy5ldmVudFNvdXJjZURlZnM7XG4gICAgcmV0dXJuICFkZWZzW2V2ZW50U291cmNlLnNvdXJjZURlZklkXS5pZ25vcmVSYW5nZTtcbn1cblxuZnVuY3Rpb24gcmVkdWNlRGF0ZVNlbGVjdGlvbihjdXJyZW50U2VsZWN0aW9uLCBhY3Rpb24pIHtcbiAgICBzd2l0Y2ggKGFjdGlvbi50eXBlKSB7XG4gICAgICAgIGNhc2UgJ1VOU0VMRUNUX0RBVEVTJzpcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICBjYXNlICdTRUxFQ1RfREFURVMnOlxuICAgICAgICAgICAgcmV0dXJuIGFjdGlvbi5zZWxlY3Rpb247XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZXR1cm4gY3VycmVudFNlbGVjdGlvbjtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIHJlZHVjZVNlbGVjdGVkRXZlbnQoY3VycmVudEluc3RhbmNlSWQsIGFjdGlvbikge1xuICAgIHN3aXRjaCAoYWN0aW9uLnR5cGUpIHtcbiAgICAgICAgY2FzZSAnVU5TRUxFQ1RfRVZFTlQnOlxuICAgICAgICAgICAgcmV0dXJuICcnO1xuICAgICAgICBjYXNlICdTRUxFQ1RfRVZFTlQnOlxuICAgICAgICAgICAgcmV0dXJuIGFjdGlvbi5ldmVudEluc3RhbmNlSWQ7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZXR1cm4gY3VycmVudEluc3RhbmNlSWQ7XG4gICAgfVxufVxuXG5mdW5jdGlvbiByZWR1Y2VFdmVudERyYWcoY3VycmVudERyYWcsIGFjdGlvbikge1xuICAgIGxldCBuZXdEcmFnO1xuICAgIHN3aXRjaCAoYWN0aW9uLnR5cGUpIHtcbiAgICAgICAgY2FzZSAnVU5TRVRfRVZFTlRfRFJBRyc6XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgY2FzZSAnU0VUX0VWRU5UX0RSQUcnOlxuICAgICAgICAgICAgbmV3RHJhZyA9IGFjdGlvbi5zdGF0ZTtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgYWZmZWN0ZWRFdmVudHM6IG5ld0RyYWcuYWZmZWN0ZWRFdmVudHMsXG4gICAgICAgICAgICAgICAgbXV0YXRlZEV2ZW50czogbmV3RHJhZy5tdXRhdGVkRXZlbnRzLFxuICAgICAgICAgICAgICAgIGlzRXZlbnQ6IG5ld0RyYWcuaXNFdmVudCxcbiAgICAgICAgICAgIH07XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZXR1cm4gY3VycmVudERyYWc7XG4gICAgfVxufVxuXG5mdW5jdGlvbiByZWR1Y2VFdmVudFJlc2l6ZShjdXJyZW50UmVzaXplLCBhY3Rpb24pIHtcbiAgICBsZXQgbmV3UmVzaXplO1xuICAgIHN3aXRjaCAoYWN0aW9uLnR5cGUpIHtcbiAgICAgICAgY2FzZSAnVU5TRVRfRVZFTlRfUkVTSVpFJzpcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICBjYXNlICdTRVRfRVZFTlRfUkVTSVpFJzpcbiAgICAgICAgICAgIG5ld1Jlc2l6ZSA9IGFjdGlvbi5zdGF0ZTtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgYWZmZWN0ZWRFdmVudHM6IG5ld1Jlc2l6ZS5hZmZlY3RlZEV2ZW50cyxcbiAgICAgICAgICAgICAgICBtdXRhdGVkRXZlbnRzOiBuZXdSZXNpemUubXV0YXRlZEV2ZW50cyxcbiAgICAgICAgICAgICAgICBpc0V2ZW50OiBuZXdSZXNpemUuaXNFdmVudCxcbiAgICAgICAgICAgIH07XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZXR1cm4gY3VycmVudFJlc2l6ZTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIHBhcnNlVG9vbGJhcnMoY2FsZW5kYXJPcHRpb25zLCBjYWxlbmRhck9wdGlvbk92ZXJyaWRlcywgdGhlbWUsIHZpZXdTcGVjcywgY2FsZW5kYXJBcGkpIHtcbiAgICBsZXQgaGVhZGVyID0gY2FsZW5kYXJPcHRpb25zLmhlYWRlclRvb2xiYXIgPyBwYXJzZVRvb2xiYXIoY2FsZW5kYXJPcHRpb25zLmhlYWRlclRvb2xiYXIsIGNhbGVuZGFyT3B0aW9ucywgY2FsZW5kYXJPcHRpb25PdmVycmlkZXMsIHRoZW1lLCB2aWV3U3BlY3MsIGNhbGVuZGFyQXBpKSA6IG51bGw7XG4gICAgbGV0IGZvb3RlciA9IGNhbGVuZGFyT3B0aW9ucy5mb290ZXJUb29sYmFyID8gcGFyc2VUb29sYmFyKGNhbGVuZGFyT3B0aW9ucy5mb290ZXJUb29sYmFyLCBjYWxlbmRhck9wdGlvbnMsIGNhbGVuZGFyT3B0aW9uT3ZlcnJpZGVzLCB0aGVtZSwgdmlld1NwZWNzLCBjYWxlbmRhckFwaSkgOiBudWxsO1xuICAgIHJldHVybiB7IGhlYWRlciwgZm9vdGVyIH07XG59XG5mdW5jdGlvbiBwYXJzZVRvb2xiYXIoc2VjdGlvblN0ckhhc2gsIGNhbGVuZGFyT3B0aW9ucywgY2FsZW5kYXJPcHRpb25PdmVycmlkZXMsIHRoZW1lLCB2aWV3U3BlY3MsIGNhbGVuZGFyQXBpKSB7XG4gICAgbGV0IHNlY3Rpb25XaWRnZXRzID0ge307XG4gICAgbGV0IHZpZXdzV2l0aEJ1dHRvbnMgPSBbXTtcbiAgICBsZXQgaGFzVGl0bGUgPSBmYWxzZTtcbiAgICBmb3IgKGxldCBzZWN0aW9uTmFtZSBpbiBzZWN0aW9uU3RySGFzaCkge1xuICAgICAgICBsZXQgc2VjdGlvblN0ciA9IHNlY3Rpb25TdHJIYXNoW3NlY3Rpb25OYW1lXTtcbiAgICAgICAgbGV0IHNlY3Rpb25SZXMgPSBwYXJzZVNlY3Rpb24oc2VjdGlvblN0ciwgY2FsZW5kYXJPcHRpb25zLCBjYWxlbmRhck9wdGlvbk92ZXJyaWRlcywgdGhlbWUsIHZpZXdTcGVjcywgY2FsZW5kYXJBcGkpO1xuICAgICAgICBzZWN0aW9uV2lkZ2V0c1tzZWN0aW9uTmFtZV0gPSBzZWN0aW9uUmVzLndpZGdldHM7XG4gICAgICAgIHZpZXdzV2l0aEJ1dHRvbnMucHVzaCguLi5zZWN0aW9uUmVzLnZpZXdzV2l0aEJ1dHRvbnMpO1xuICAgICAgICBoYXNUaXRsZSA9IGhhc1RpdGxlIHx8IHNlY3Rpb25SZXMuaGFzVGl0bGU7XG4gICAgfVxuICAgIHJldHVybiB7IHNlY3Rpb25XaWRnZXRzLCB2aWV3c1dpdGhCdXR0b25zLCBoYXNUaXRsZSB9O1xufVxuLypcbkJBRDogcXVlcnlpbmcgaWNvbnMgYW5kIHRleHQgaGVyZS4gc2hvdWxkIGJlIGRvbmUgYXQgcmVuZGVyIHRpbWVcbiovXG5mdW5jdGlvbiBwYXJzZVNlY3Rpb24oc2VjdGlvblN0ciwgY2FsZW5kYXJPcHRpb25zLCAvLyBkZWZhdWx0cytvdmVycmlkZXMsIHRoZW4gcmVmaW5lZFxuY2FsZW5kYXJPcHRpb25PdmVycmlkZXMsIC8vIG92ZXJyaWRlcyBvbmx5ISwgdW5yZWZpbmVkIDooXG50aGVtZSwgdmlld1NwZWNzLCBjYWxlbmRhckFwaSkge1xuICAgIGxldCBpc1J0bCA9IGNhbGVuZGFyT3B0aW9ucy5kaXJlY3Rpb24gPT09ICdydGwnO1xuICAgIGxldCBjYWxlbmRhckN1c3RvbUJ1dHRvbnMgPSBjYWxlbmRhck9wdGlvbnMuY3VzdG9tQnV0dG9ucyB8fCB7fTtcbiAgICBsZXQgY2FsZW5kYXJCdXR0b25UZXh0T3ZlcnJpZGVzID0gY2FsZW5kYXJPcHRpb25PdmVycmlkZXMuYnV0dG9uVGV4dCB8fCB7fTtcbiAgICBsZXQgY2FsZW5kYXJCdXR0b25UZXh0ID0gY2FsZW5kYXJPcHRpb25zLmJ1dHRvblRleHQgfHwge307XG4gICAgbGV0IGNhbGVuZGFyQnV0dG9uSGludE92ZXJyaWRlcyA9IGNhbGVuZGFyT3B0aW9uT3ZlcnJpZGVzLmJ1dHRvbkhpbnRzIHx8IHt9O1xuICAgIGxldCBjYWxlbmRhckJ1dHRvbkhpbnRzID0gY2FsZW5kYXJPcHRpb25zLmJ1dHRvbkhpbnRzIHx8IHt9O1xuICAgIGxldCBzZWN0aW9uU3Vic3RycyA9IHNlY3Rpb25TdHIgPyBzZWN0aW9uU3RyLnNwbGl0KCcgJykgOiBbXTtcbiAgICBsZXQgdmlld3NXaXRoQnV0dG9ucyA9IFtdO1xuICAgIGxldCBoYXNUaXRsZSA9IGZhbHNlO1xuICAgIGxldCB3aWRnZXRzID0gc2VjdGlvblN1YnN0cnMubWFwKChidXR0b25Hcm91cFN0cikgPT4gKGJ1dHRvbkdyb3VwU3RyLnNwbGl0KCcsJykubWFwKChidXR0b25OYW1lKSA9PiB7XG4gICAgICAgIGlmIChidXR0b25OYW1lID09PSAndGl0bGUnKSB7XG4gICAgICAgICAgICBoYXNUaXRsZSA9IHRydWU7XG4gICAgICAgICAgICByZXR1cm4geyBidXR0b25OYW1lIH07XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGN1c3RvbUJ1dHRvblByb3BzO1xuICAgICAgICBsZXQgdmlld1NwZWM7XG4gICAgICAgIGxldCBidXR0b25DbGljaztcbiAgICAgICAgbGV0IGJ1dHRvbkljb247IC8vIG9ubHkgb25lIG9mIHRoZXNlIHdpbGwgYmUgc2V0XG4gICAgICAgIGxldCBidXR0b25UZXh0OyAvLyBcIlxuICAgICAgICBsZXQgYnV0dG9uSGludDtcbiAgICAgICAgLy8gXiBmb3IgdGhlIHRpdGxlPVwiXCIgYXR0cmlidXRlLCBmb3IgYWNjZXNzaWJpbGl0eVxuICAgICAgICBpZiAoKGN1c3RvbUJ1dHRvblByb3BzID0gY2FsZW5kYXJDdXN0b21CdXR0b25zW2J1dHRvbk5hbWVdKSkge1xuICAgICAgICAgICAgYnV0dG9uQ2xpY2sgPSAoZXYpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoY3VzdG9tQnV0dG9uUHJvcHMuY2xpY2spIHtcbiAgICAgICAgICAgICAgICAgICAgY3VzdG9tQnV0dG9uUHJvcHMuY2xpY2suY2FsbChldi50YXJnZXQsIGV2LCBldi50YXJnZXQpOyAvLyBUT0RPOiB1c2UgQ2FsZW5kYXIgdGhpcyBjb250ZXh0P1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICAoYnV0dG9uSWNvbiA9IHRoZW1lLmdldEN1c3RvbUJ1dHRvbkljb25DbGFzcyhjdXN0b21CdXR0b25Qcm9wcykpIHx8XG4gICAgICAgICAgICAgICAgKGJ1dHRvbkljb24gPSB0aGVtZS5nZXRJY29uQ2xhc3MoYnV0dG9uTmFtZSwgaXNSdGwpKSB8fFxuICAgICAgICAgICAgICAgIChidXR0b25UZXh0ID0gY3VzdG9tQnV0dG9uUHJvcHMudGV4dCk7XG4gICAgICAgICAgICBidXR0b25IaW50ID0gY3VzdG9tQnV0dG9uUHJvcHMuaGludCB8fCBjdXN0b21CdXR0b25Qcm9wcy50ZXh0O1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKCh2aWV3U3BlYyA9IHZpZXdTcGVjc1tidXR0b25OYW1lXSkpIHtcbiAgICAgICAgICAgIHZpZXdzV2l0aEJ1dHRvbnMucHVzaChidXR0b25OYW1lKTtcbiAgICAgICAgICAgIGJ1dHRvbkNsaWNrID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNhbGVuZGFyQXBpLmNoYW5nZVZpZXcoYnV0dG9uTmFtZSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgKGJ1dHRvblRleHQgPSB2aWV3U3BlYy5idXR0b25UZXh0T3ZlcnJpZGUpIHx8XG4gICAgICAgICAgICAgICAgKGJ1dHRvbkljb24gPSB0aGVtZS5nZXRJY29uQ2xhc3MoYnV0dG9uTmFtZSwgaXNSdGwpKSB8fFxuICAgICAgICAgICAgICAgIChidXR0b25UZXh0ID0gdmlld1NwZWMuYnV0dG9uVGV4dERlZmF1bHQpO1xuICAgICAgICAgICAgbGV0IHRleHRGYWxsYmFjayA9IHZpZXdTcGVjLmJ1dHRvblRleHRPdmVycmlkZSB8fFxuICAgICAgICAgICAgICAgIHZpZXdTcGVjLmJ1dHRvblRleHREZWZhdWx0O1xuICAgICAgICAgICAgYnV0dG9uSGludCA9IGZvcm1hdFdpdGhPcmRpbmFscyh2aWV3U3BlYy5idXR0b25UaXRsZU92ZXJyaWRlIHx8XG4gICAgICAgICAgICAgICAgdmlld1NwZWMuYnV0dG9uVGl0bGVEZWZhdWx0IHx8XG4gICAgICAgICAgICAgICAgY2FsZW5kYXJPcHRpb25zLnZpZXdIaW50LCBbdGV4dEZhbGxiYWNrLCBidXR0b25OYW1lXSwgLy8gdmlldy1uYW1lID0gYnV0dG9uTmFtZVxuICAgICAgICAgICAgdGV4dEZhbGxiYWNrKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChjYWxlbmRhckFwaVtidXR0b25OYW1lXSkgeyAvLyBhIGNhbGVuZGFyQXBpIG1ldGhvZFxuICAgICAgICAgICAgYnV0dG9uQ2xpY2sgPSAoKSA9PiB7XG4gICAgICAgICAgICAgICAgY2FsZW5kYXJBcGlbYnV0dG9uTmFtZV0oKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICAoYnV0dG9uVGV4dCA9IGNhbGVuZGFyQnV0dG9uVGV4dE92ZXJyaWRlc1tidXR0b25OYW1lXSkgfHxcbiAgICAgICAgICAgICAgICAoYnV0dG9uSWNvbiA9IHRoZW1lLmdldEljb25DbGFzcyhidXR0b25OYW1lLCBpc1J0bCkpIHx8XG4gICAgICAgICAgICAgICAgKGJ1dHRvblRleHQgPSBjYWxlbmRhckJ1dHRvblRleHRbYnV0dG9uTmFtZV0pOyAvLyBldmVyeXRoaW5nIGVsc2UgaXMgY29uc2lkZXJlZCBkZWZhdWx0XG4gICAgICAgICAgICBpZiAoYnV0dG9uTmFtZSA9PT0gJ3ByZXZZZWFyJyB8fCBidXR0b25OYW1lID09PSAnbmV4dFllYXInKSB7XG4gICAgICAgICAgICAgICAgbGV0IHByZXZPck5leHQgPSBidXR0b25OYW1lID09PSAncHJldlllYXInID8gJ3ByZXYnIDogJ25leHQnO1xuICAgICAgICAgICAgICAgIGJ1dHRvbkhpbnQgPSBmb3JtYXRXaXRoT3JkaW5hbHMoY2FsZW5kYXJCdXR0b25IaW50T3ZlcnJpZGVzW3ByZXZPck5leHRdIHx8XG4gICAgICAgICAgICAgICAgICAgIGNhbGVuZGFyQnV0dG9uSGludHNbcHJldk9yTmV4dF0sIFtcbiAgICAgICAgICAgICAgICAgICAgY2FsZW5kYXJCdXR0b25UZXh0LnllYXIgfHwgJ3llYXInLFxuICAgICAgICAgICAgICAgICAgICAneWVhcicsXG4gICAgICAgICAgICAgICAgXSwgY2FsZW5kYXJCdXR0b25UZXh0W2J1dHRvbk5hbWVdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGJ1dHRvbkhpbnQgPSAobmF2VW5pdCkgPT4gZm9ybWF0V2l0aE9yZGluYWxzKGNhbGVuZGFyQnV0dG9uSGludE92ZXJyaWRlc1tidXR0b25OYW1lXSB8fFxuICAgICAgICAgICAgICAgICAgICBjYWxlbmRhckJ1dHRvbkhpbnRzW2J1dHRvbk5hbWVdLCBbXG4gICAgICAgICAgICAgICAgICAgIGNhbGVuZGFyQnV0dG9uVGV4dFtuYXZVbml0XSB8fCBuYXZVbml0LFxuICAgICAgICAgICAgICAgICAgICBuYXZVbml0LFxuICAgICAgICAgICAgICAgIF0sIGNhbGVuZGFyQnV0dG9uVGV4dFtidXR0b25OYW1lXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsgYnV0dG9uTmFtZSwgYnV0dG9uQ2xpY2ssIGJ1dHRvbkljb24sIGJ1dHRvblRleHQsIGJ1dHRvbkhpbnQgfTtcbiAgICB9KSkpO1xuICAgIHJldHVybiB7IHdpZGdldHMsIHZpZXdzV2l0aEJ1dHRvbnMsIGhhc1RpdGxlIH07XG59XG5cbi8vIGFsd2F5cyByZXByZXNlbnRzIHRoZSBjdXJyZW50IHZpZXcuIG90aGVyd2lzZSwgaXQnZCBuZWVkIHRvIGNoYW5nZSB2YWx1ZSBldmVyeSB0aW1lIGRhdGUgY2hhbmdlc1xuY2xhc3MgVmlld0ltcGwge1xuICAgIGNvbnN0cnVjdG9yKHR5cGUsIGdldEN1cnJlbnREYXRhLCBkYXRlRW52KSB7XG4gICAgICAgIHRoaXMudHlwZSA9IHR5cGU7XG4gICAgICAgIHRoaXMuZ2V0Q3VycmVudERhdGEgPSBnZXRDdXJyZW50RGF0YTtcbiAgICAgICAgdGhpcy5kYXRlRW52ID0gZGF0ZUVudjtcbiAgICB9XG4gICAgZ2V0IGNhbGVuZGFyKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRDdXJyZW50RGF0YSgpLmNhbGVuZGFyQXBpO1xuICAgIH1cbiAgICBnZXQgdGl0bGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldEN1cnJlbnREYXRhKCkudmlld1RpdGxlO1xuICAgIH1cbiAgICBnZXQgYWN0aXZlU3RhcnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmRhdGVFbnYudG9EYXRlKHRoaXMuZ2V0Q3VycmVudERhdGEoKS5kYXRlUHJvZmlsZS5hY3RpdmVSYW5nZS5zdGFydCk7XG4gICAgfVxuICAgIGdldCBhY3RpdmVFbmQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmRhdGVFbnYudG9EYXRlKHRoaXMuZ2V0Q3VycmVudERhdGEoKS5kYXRlUHJvZmlsZS5hY3RpdmVSYW5nZS5lbmQpO1xuICAgIH1cbiAgICBnZXQgY3VycmVudFN0YXJ0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5kYXRlRW52LnRvRGF0ZSh0aGlzLmdldEN1cnJlbnREYXRhKCkuZGF0ZVByb2ZpbGUuY3VycmVudFJhbmdlLnN0YXJ0KTtcbiAgICB9XG4gICAgZ2V0IGN1cnJlbnRFbmQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmRhdGVFbnYudG9EYXRlKHRoaXMuZ2V0Q3VycmVudERhdGEoKS5kYXRlUHJvZmlsZS5jdXJyZW50UmFuZ2UuZW5kKTtcbiAgICB9XG4gICAgZ2V0T3B0aW9uKG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0Q3VycmVudERhdGEoKS5vcHRpb25zW25hbWVdOyAvLyBhcmUgdGhlIHZpZXctc3BlY2lmaWMgb3B0aW9uc1xuICAgIH1cbn1cblxubGV0IGV2ZW50U291cmNlRGVmJDIgPSB7XG4gICAgaWdub3JlUmFuZ2U6IHRydWUsXG4gICAgcGFyc2VNZXRhKHJlZmluZWQpIHtcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkocmVmaW5lZC5ldmVudHMpKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVmaW5lZC5ldmVudHM7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfSxcbiAgICBmZXRjaChhcmcsIHN1Y2Nlc3NDYWxsYmFjaykge1xuICAgICAgICBzdWNjZXNzQ2FsbGJhY2soe1xuICAgICAgICAgICAgcmF3RXZlbnRzOiBhcmcuZXZlbnRTb3VyY2UubWV0YSxcbiAgICAgICAgfSk7XG4gICAgfSxcbn07XG5jb25zdCBhcnJheUV2ZW50U291cmNlUGx1Z2luID0gY3JlYXRlUGx1Z2luKHtcbiAgICBuYW1lOiAnYXJyYXktZXZlbnQtc291cmNlJyxcbiAgICBldmVudFNvdXJjZURlZnM6IFtldmVudFNvdXJjZURlZiQyXSxcbn0pO1xuXG5sZXQgZXZlbnRTb3VyY2VEZWYkMSA9IHtcbiAgICBwYXJzZU1ldGEocmVmaW5lZCkge1xuICAgICAgICBpZiAodHlwZW9mIHJlZmluZWQuZXZlbnRzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVmaW5lZC5ldmVudHM7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfSxcbiAgICBmZXRjaChhcmcsIHN1Y2Nlc3NDYWxsYmFjaywgZXJyb3JDYWxsYmFjaykge1xuICAgICAgICBjb25zdCB7IGRhdGVFbnYgfSA9IGFyZy5jb250ZXh0O1xuICAgICAgICBjb25zdCBmdW5jID0gYXJnLmV2ZW50U291cmNlLm1ldGE7XG4gICAgICAgIHVucHJvbWlzaWZ5KGZ1bmMuYmluZChudWxsLCBidWlsZFJhbmdlQXBpV2l0aFRpbWVab25lKGFyZy5yYW5nZSwgZGF0ZUVudikpLCAocmF3RXZlbnRzKSA9PiBzdWNjZXNzQ2FsbGJhY2soeyByYXdFdmVudHMgfSksIGVycm9yQ2FsbGJhY2spO1xuICAgIH0sXG59O1xuY29uc3QgZnVuY0V2ZW50U291cmNlUGx1Z2luID0gY3JlYXRlUGx1Z2luKHtcbiAgICBuYW1lOiAnZnVuYy1ldmVudC1zb3VyY2UnLFxuICAgIGV2ZW50U291cmNlRGVmczogW2V2ZW50U291cmNlRGVmJDFdLFxufSk7XG5cbmNvbnN0IEpTT05fRkVFRF9FVkVOVF9TT1VSQ0VfUkVGSU5FUlMgPSB7XG4gICAgbWV0aG9kOiBTdHJpbmcsXG4gICAgZXh0cmFQYXJhbXM6IGlkZW50aXR5LFxuICAgIHN0YXJ0UGFyYW06IFN0cmluZyxcbiAgICBlbmRQYXJhbTogU3RyaW5nLFxuICAgIHRpbWVab25lUGFyYW06IFN0cmluZyxcbn07XG5cbmxldCBldmVudFNvdXJjZURlZiA9IHtcbiAgICBwYXJzZU1ldGEocmVmaW5lZCkge1xuICAgICAgICBpZiAocmVmaW5lZC51cmwgJiYgKHJlZmluZWQuZm9ybWF0ID09PSAnanNvbicgfHwgIXJlZmluZWQuZm9ybWF0KSkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICB1cmw6IHJlZmluZWQudXJsLFxuICAgICAgICAgICAgICAgIGZvcm1hdDogJ2pzb24nLFxuICAgICAgICAgICAgICAgIG1ldGhvZDogKHJlZmluZWQubWV0aG9kIHx8ICdHRVQnKS50b1VwcGVyQ2FzZSgpLFxuICAgICAgICAgICAgICAgIGV4dHJhUGFyYW1zOiByZWZpbmVkLmV4dHJhUGFyYW1zLFxuICAgICAgICAgICAgICAgIHN0YXJ0UGFyYW06IHJlZmluZWQuc3RhcnRQYXJhbSxcbiAgICAgICAgICAgICAgICBlbmRQYXJhbTogcmVmaW5lZC5lbmRQYXJhbSxcbiAgICAgICAgICAgICAgICB0aW1lWm9uZVBhcmFtOiByZWZpbmVkLnRpbWVab25lUGFyYW0sXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH0sXG4gICAgZmV0Y2goYXJnLCBzdWNjZXNzQ2FsbGJhY2ssIGVycm9yQ2FsbGJhY2spIHtcbiAgICAgICAgY29uc3QgeyBtZXRhIH0gPSBhcmcuZXZlbnRTb3VyY2U7XG4gICAgICAgIGNvbnN0IHJlcXVlc3RQYXJhbXMgPSBidWlsZFJlcXVlc3RQYXJhbXMobWV0YSwgYXJnLnJhbmdlLCBhcmcuY29udGV4dCk7XG4gICAgICAgIHJlcXVlc3RKc29uKG1ldGEubWV0aG9kLCBtZXRhLnVybCwgcmVxdWVzdFBhcmFtcykudGhlbigoW3Jhd0V2ZW50cywgcmVzcG9uc2VdKSA9PiB7XG4gICAgICAgICAgICBzdWNjZXNzQ2FsbGJhY2soeyByYXdFdmVudHMsIHJlc3BvbnNlIH0pO1xuICAgICAgICB9LCBlcnJvckNhbGxiYWNrKTtcbiAgICB9LFxufTtcbmNvbnN0IGpzb25GZWVkRXZlbnRTb3VyY2VQbHVnaW4gPSBjcmVhdGVQbHVnaW4oe1xuICAgIG5hbWU6ICdqc29uLWV2ZW50LXNvdXJjZScsXG4gICAgZXZlbnRTb3VyY2VSZWZpbmVyczogSlNPTl9GRUVEX0VWRU5UX1NPVVJDRV9SRUZJTkVSUyxcbiAgICBldmVudFNvdXJjZURlZnM6IFtldmVudFNvdXJjZURlZl0sXG59KTtcbmZ1bmN0aW9uIGJ1aWxkUmVxdWVzdFBhcmFtcyhtZXRhLCByYW5nZSwgY29udGV4dCkge1xuICAgIGxldCB7IGRhdGVFbnYsIG9wdGlvbnMgfSA9IGNvbnRleHQ7XG4gICAgbGV0IHN0YXJ0UGFyYW07XG4gICAgbGV0IGVuZFBhcmFtO1xuICAgIGxldCB0aW1lWm9uZVBhcmFtO1xuICAgIGxldCBjdXN0b21SZXF1ZXN0UGFyYW1zO1xuICAgIGxldCBwYXJhbXMgPSB7fTtcbiAgICBzdGFydFBhcmFtID0gbWV0YS5zdGFydFBhcmFtO1xuICAgIGlmIChzdGFydFBhcmFtID09IG51bGwpIHtcbiAgICAgICAgc3RhcnRQYXJhbSA9IG9wdGlvbnMuc3RhcnRQYXJhbTtcbiAgICB9XG4gICAgZW5kUGFyYW0gPSBtZXRhLmVuZFBhcmFtO1xuICAgIGlmIChlbmRQYXJhbSA9PSBudWxsKSB7XG4gICAgICAgIGVuZFBhcmFtID0gb3B0aW9ucy5lbmRQYXJhbTtcbiAgICB9XG4gICAgdGltZVpvbmVQYXJhbSA9IG1ldGEudGltZVpvbmVQYXJhbTtcbiAgICBpZiAodGltZVpvbmVQYXJhbSA9PSBudWxsKSB7XG4gICAgICAgIHRpbWVab25lUGFyYW0gPSBvcHRpb25zLnRpbWVab25lUGFyYW07XG4gICAgfVxuICAgIC8vIHJldHJpZXZlIGFueSBvdXRib3VuZCBHRVQvUE9TVCBkYXRhIGZyb20gdGhlIG9wdGlvbnNcbiAgICBpZiAodHlwZW9mIG1ldGEuZXh0cmFQYXJhbXMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgLy8gc3VwcGxpZWQgYXMgYSBmdW5jdGlvbiB0aGF0IHJldHVybnMgYSBrZXkvdmFsdWUgb2JqZWN0XG4gICAgICAgIGN1c3RvbVJlcXVlc3RQYXJhbXMgPSBtZXRhLmV4dHJhUGFyYW1zKCk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICAvLyBwcm9iYWJseSBzdXBwbGllZCBhcyBhIHN0cmFpZ2h0IGtleS92YWx1ZSBvYmplY3RcbiAgICAgICAgY3VzdG9tUmVxdWVzdFBhcmFtcyA9IG1ldGEuZXh0cmFQYXJhbXMgfHwge307XG4gICAgfVxuICAgIE9iamVjdC5hc3NpZ24ocGFyYW1zLCBjdXN0b21SZXF1ZXN0UGFyYW1zKTtcbiAgICBwYXJhbXNbc3RhcnRQYXJhbV0gPSBkYXRlRW52LmZvcm1hdElzbyhyYW5nZS5zdGFydCk7XG4gICAgcGFyYW1zW2VuZFBhcmFtXSA9IGRhdGVFbnYuZm9ybWF0SXNvKHJhbmdlLmVuZCk7XG4gICAgaWYgKGRhdGVFbnYudGltZVpvbmUgIT09ICdsb2NhbCcpIHtcbiAgICAgICAgcGFyYW1zW3RpbWVab25lUGFyYW1dID0gZGF0ZUVudi50aW1lWm9uZTtcbiAgICB9XG4gICAgcmV0dXJuIHBhcmFtcztcbn1cblxuY29uc3QgU0lNUExFX1JFQ1VSUklOR19SRUZJTkVSUyA9IHtcbiAgICBkYXlzT2ZXZWVrOiBpZGVudGl0eSxcbiAgICBzdGFydFRpbWU6IGNyZWF0ZUR1cmF0aW9uLFxuICAgIGVuZFRpbWU6IGNyZWF0ZUR1cmF0aW9uLFxuICAgIGR1cmF0aW9uOiBjcmVhdGVEdXJhdGlvbixcbiAgICBzdGFydFJlY3VyOiBpZGVudGl0eSxcbiAgICBlbmRSZWN1cjogaWRlbnRpdHksXG59O1xuXG5sZXQgcmVjdXJyaW5nID0ge1xuICAgIHBhcnNlKHJlZmluZWQsIGRhdGVFbnYpIHtcbiAgICAgICAgaWYgKHJlZmluZWQuZGF5c09mV2VlayB8fCByZWZpbmVkLnN0YXJ0VGltZSB8fCByZWZpbmVkLmVuZFRpbWUgfHwgcmVmaW5lZC5zdGFydFJlY3VyIHx8IHJlZmluZWQuZW5kUmVjdXIpIHtcbiAgICAgICAgICAgIGxldCByZWN1cnJpbmdEYXRhID0ge1xuICAgICAgICAgICAgICAgIGRheXNPZldlZWs6IHJlZmluZWQuZGF5c09mV2VlayB8fCBudWxsLFxuICAgICAgICAgICAgICAgIHN0YXJ0VGltZTogcmVmaW5lZC5zdGFydFRpbWUgfHwgbnVsbCxcbiAgICAgICAgICAgICAgICBlbmRUaW1lOiByZWZpbmVkLmVuZFRpbWUgfHwgbnVsbCxcbiAgICAgICAgICAgICAgICBzdGFydFJlY3VyOiByZWZpbmVkLnN0YXJ0UmVjdXIgPyBkYXRlRW52LmNyZWF0ZU1hcmtlcihyZWZpbmVkLnN0YXJ0UmVjdXIpIDogbnVsbCxcbiAgICAgICAgICAgICAgICBlbmRSZWN1cjogcmVmaW5lZC5lbmRSZWN1ciA/IGRhdGVFbnYuY3JlYXRlTWFya2VyKHJlZmluZWQuZW5kUmVjdXIpIDogbnVsbCxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBsZXQgZHVyYXRpb247XG4gICAgICAgICAgICBpZiAocmVmaW5lZC5kdXJhdGlvbikge1xuICAgICAgICAgICAgICAgIGR1cmF0aW9uID0gcmVmaW5lZC5kdXJhdGlvbjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghZHVyYXRpb24gJiYgcmVmaW5lZC5zdGFydFRpbWUgJiYgcmVmaW5lZC5lbmRUaW1lKSB7XG4gICAgICAgICAgICAgICAgZHVyYXRpb24gPSBzdWJ0cmFjdER1cmF0aW9ucyhyZWZpbmVkLmVuZFRpbWUsIHJlZmluZWQuc3RhcnRUaW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgYWxsRGF5R3Vlc3M6IEJvb2xlYW4oIXJlZmluZWQuc3RhcnRUaW1lICYmICFyZWZpbmVkLmVuZFRpbWUpLFxuICAgICAgICAgICAgICAgIGR1cmF0aW9uLFxuICAgICAgICAgICAgICAgIHR5cGVEYXRhOiByZWN1cnJpbmdEYXRhLCAvLyBkb2Vzbid0IG5lZWQgZW5kVGltZSBhbnltb3JlIGJ1dCBvaCB3ZWxsXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH0sXG4gICAgZXhwYW5kKHR5cGVEYXRhLCBmcmFtaW5nUmFuZ2UsIGRhdGVFbnYpIHtcbiAgICAgICAgbGV0IGNsaXBwZWRGcmFtaW5nUmFuZ2UgPSBpbnRlcnNlY3RSYW5nZXMoZnJhbWluZ1JhbmdlLCB7IHN0YXJ0OiB0eXBlRGF0YS5zdGFydFJlY3VyLCBlbmQ6IHR5cGVEYXRhLmVuZFJlY3VyIH0pO1xuICAgICAgICBpZiAoY2xpcHBlZEZyYW1pbmdSYW5nZSkge1xuICAgICAgICAgICAgcmV0dXJuIGV4cGFuZFJhbmdlcyh0eXBlRGF0YS5kYXlzT2ZXZWVrLCB0eXBlRGF0YS5zdGFydFRpbWUsIGNsaXBwZWRGcmFtaW5nUmFuZ2UsIGRhdGVFbnYpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBbXTtcbiAgICB9LFxufTtcbmNvbnN0IHNpbXBsZVJlY3VycmluZ0V2ZW50c1BsdWdpbiA9IGNyZWF0ZVBsdWdpbih7XG4gICAgbmFtZTogJ3NpbXBsZS1yZWN1cnJpbmctZXZlbnQnLFxuICAgIHJlY3VycmluZ1R5cGVzOiBbcmVjdXJyaW5nXSxcbiAgICBldmVudFJlZmluZXJzOiBTSU1QTEVfUkVDVVJSSU5HX1JFRklORVJTLFxufSk7XG5mdW5jdGlvbiBleHBhbmRSYW5nZXMoZGF5c09mV2Vlaywgc3RhcnRUaW1lLCBmcmFtaW5nUmFuZ2UsIGRhdGVFbnYpIHtcbiAgICBsZXQgZG93SGFzaCA9IGRheXNPZldlZWsgPyBhcnJheVRvSGFzaChkYXlzT2ZXZWVrKSA6IG51bGw7XG4gICAgbGV0IGRheU1hcmtlciA9IHN0YXJ0T2ZEYXkoZnJhbWluZ1JhbmdlLnN0YXJ0KTtcbiAgICBsZXQgZW5kTWFya2VyID0gZnJhbWluZ1JhbmdlLmVuZDtcbiAgICBsZXQgaW5zdGFuY2VTdGFydHMgPSBbXTtcbiAgICB3aGlsZSAoZGF5TWFya2VyIDwgZW5kTWFya2VyKSB7XG4gICAgICAgIGxldCBpbnN0YW5jZVN0YXJ0O1xuICAgICAgICAvLyBpZiBldmVyeWRheSwgb3IgdGhpcyBwYXJ0aWN1bGFyIGRheS1vZi13ZWVrXG4gICAgICAgIGlmICghZG93SGFzaCB8fCBkb3dIYXNoW2RheU1hcmtlci5nZXRVVENEYXkoKV0pIHtcbiAgICAgICAgICAgIGlmIChzdGFydFRpbWUpIHtcbiAgICAgICAgICAgICAgICBpbnN0YW5jZVN0YXJ0ID0gZGF0ZUVudi5hZGQoZGF5TWFya2VyLCBzdGFydFRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgaW5zdGFuY2VTdGFydCA9IGRheU1hcmtlcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGluc3RhbmNlU3RhcnRzLnB1c2goaW5zdGFuY2VTdGFydCk7XG4gICAgICAgIH1cbiAgICAgICAgZGF5TWFya2VyID0gYWRkRGF5cyhkYXlNYXJrZXIsIDEpO1xuICAgIH1cbiAgICByZXR1cm4gaW5zdGFuY2VTdGFydHM7XG59XG5cbmNvbnN0IGNoYW5nZUhhbmRsZXJQbHVnaW4gPSBjcmVhdGVQbHVnaW4oe1xuICAgIG5hbWU6ICdjaGFuZ2UtaGFuZGxlcicsXG4gICAgb3B0aW9uQ2hhbmdlSGFuZGxlcnM6IHtcbiAgICAgICAgZXZlbnRzKGV2ZW50cywgY29udGV4dCkge1xuICAgICAgICAgICAgaGFuZGxlRXZlbnRTb3VyY2VzKFtldmVudHNdLCBjb250ZXh0KTtcbiAgICAgICAgfSxcbiAgICAgICAgZXZlbnRTb3VyY2VzOiBoYW5kbGVFdmVudFNvdXJjZXMsXG4gICAgfSxcbn0pO1xuLypcbkJVRzogaWYgYGV2ZW50YCB3YXMgc3VwcGxpZWQsIGFsbCBwcmV2aW91c2x5LWdpdmVuIGBldmVudFNvdXJjZXNgIHdpbGwgYmUgd2lwZWQgb3V0XG4qL1xuZnVuY3Rpb24gaGFuZGxlRXZlbnRTb3VyY2VzKGlucHV0cywgY29udGV4dCkge1xuICAgIGxldCB1bmZvdW5kU291cmNlcyA9IGhhc2hWYWx1ZXNUb0FycmF5KGNvbnRleHQuZ2V0Q3VycmVudERhdGEoKS5ldmVudFNvdXJjZXMpO1xuICAgIGxldCBuZXdJbnB1dHMgPSBbXTtcbiAgICBmb3IgKGxldCBpbnB1dCBvZiBpbnB1dHMpIHtcbiAgICAgICAgbGV0IGlucHV0Rm91bmQgPSBmYWxzZTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB1bmZvdW5kU291cmNlcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgaWYgKHVuZm91bmRTb3VyY2VzW2ldLl9yYXcgPT09IGlucHV0KSB7XG4gICAgICAgICAgICAgICAgdW5mb3VuZFNvdXJjZXMuc3BsaWNlKGksIDEpOyAvLyBkZWxldGVcbiAgICAgICAgICAgICAgICBpbnB1dEZvdW5kID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoIWlucHV0Rm91bmQpIHtcbiAgICAgICAgICAgIG5ld0lucHV0cy5wdXNoKGlucHV0KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBmb3IgKGxldCB1bmZvdW5kU291cmNlIG9mIHVuZm91bmRTb3VyY2VzKSB7XG4gICAgICAgIGNvbnRleHQuZGlzcGF0Y2goe1xuICAgICAgICAgICAgdHlwZTogJ1JFTU9WRV9FVkVOVF9TT1VSQ0UnLFxuICAgICAgICAgICAgc291cmNlSWQ6IHVuZm91bmRTb3VyY2Uuc291cmNlSWQsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBmb3IgKGxldCBuZXdJbnB1dCBvZiBuZXdJbnB1dHMpIHtcbiAgICAgICAgY29udGV4dC5jYWxlbmRhckFwaS5hZGRFdmVudFNvdXJjZShuZXdJbnB1dCk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBoYW5kbGVEYXRlUHJvZmlsZShkYXRlUHJvZmlsZSwgY29udGV4dCkge1xuICAgIGNvbnRleHQuZW1pdHRlci50cmlnZ2VyKCdkYXRlc1NldCcsIE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgYnVpbGRSYW5nZUFwaVdpdGhUaW1lWm9uZShkYXRlUHJvZmlsZS5hY3RpdmVSYW5nZSwgY29udGV4dC5kYXRlRW52KSksIHsgdmlldzogY29udGV4dC52aWV3QXBpIH0pKTtcbn1cblxuZnVuY3Rpb24gaGFuZGxlRXZlbnRTdG9yZShldmVudFN0b3JlLCBjb250ZXh0KSB7XG4gICAgbGV0IHsgZW1pdHRlciB9ID0gY29udGV4dDtcbiAgICBpZiAoZW1pdHRlci5oYXNIYW5kbGVycygnZXZlbnRzU2V0JykpIHtcbiAgICAgICAgZW1pdHRlci50cmlnZ2VyKCdldmVudHNTZXQnLCBidWlsZEV2ZW50QXBpcyhldmVudFN0b3JlLCBjb250ZXh0KSk7XG4gICAgfVxufVxuXG4vKlxudGhpcyBhcnJheSBpcyBleHBvc2VkIG9uIHRoZSByb290IG5hbWVzcGFjZSBzbyB0aGF0IFVNRCBwbHVnaW5zIGNhbiBhZGQgdG8gaXQuXG5zZWUgdGhlIHJvbGx1cC1idW5kbGVzIHNjcmlwdC5cbiovXG5jb25zdCBnbG9iYWxQbHVnaW5zID0gW1xuICAgIGFycmF5RXZlbnRTb3VyY2VQbHVnaW4sXG4gICAgZnVuY0V2ZW50U291cmNlUGx1Z2luLFxuICAgIGpzb25GZWVkRXZlbnRTb3VyY2VQbHVnaW4sXG4gICAgc2ltcGxlUmVjdXJyaW5nRXZlbnRzUGx1Z2luLFxuICAgIGNoYW5nZUhhbmRsZXJQbHVnaW4sXG4gICAgY3JlYXRlUGx1Z2luKHtcbiAgICAgICAgbmFtZTogJ21pc2MnLFxuICAgICAgICBpc0xvYWRpbmdGdW5jczogW1xuICAgICAgICAgICAgKHN0YXRlKSA9PiBjb21wdXRlRXZlbnRTb3VyY2VzTG9hZGluZyhzdGF0ZS5ldmVudFNvdXJjZXMpLFxuICAgICAgICBdLFxuICAgICAgICBwcm9wU2V0SGFuZGxlcnM6IHtcbiAgICAgICAgICAgIGRhdGVQcm9maWxlOiBoYW5kbGVEYXRlUHJvZmlsZSxcbiAgICAgICAgICAgIGV2ZW50U3RvcmU6IGhhbmRsZUV2ZW50U3RvcmUsXG4gICAgICAgIH0sXG4gICAgfSksXG5dO1xuXG5jbGFzcyBUYXNrUnVubmVyIHtcbiAgICBjb25zdHJ1Y3RvcihydW5UYXNrT3B0aW9uLCBkcmFpbmVkT3B0aW9uKSB7XG4gICAgICAgIHRoaXMucnVuVGFza09wdGlvbiA9IHJ1blRhc2tPcHRpb247XG4gICAgICAgIHRoaXMuZHJhaW5lZE9wdGlvbiA9IGRyYWluZWRPcHRpb247XG4gICAgICAgIHRoaXMucXVldWUgPSBbXTtcbiAgICAgICAgdGhpcy5kZWxheWVkUnVubmVyID0gbmV3IERlbGF5ZWRSdW5uZXIodGhpcy5kcmFpbi5iaW5kKHRoaXMpKTtcbiAgICB9XG4gICAgcmVxdWVzdCh0YXNrLCBkZWxheSkge1xuICAgICAgICB0aGlzLnF1ZXVlLnB1c2godGFzayk7XG4gICAgICAgIHRoaXMuZGVsYXllZFJ1bm5lci5yZXF1ZXN0KGRlbGF5KTtcbiAgICB9XG4gICAgcGF1c2Uoc2NvcGUpIHtcbiAgICAgICAgdGhpcy5kZWxheWVkUnVubmVyLnBhdXNlKHNjb3BlKTtcbiAgICB9XG4gICAgcmVzdW1lKHNjb3BlLCBmb3JjZSkge1xuICAgICAgICB0aGlzLmRlbGF5ZWRSdW5uZXIucmVzdW1lKHNjb3BlLCBmb3JjZSk7XG4gICAgfVxuICAgIGRyYWluKCkge1xuICAgICAgICBsZXQgeyBxdWV1ZSB9ID0gdGhpcztcbiAgICAgICAgd2hpbGUgKHF1ZXVlLmxlbmd0aCkge1xuICAgICAgICAgICAgbGV0IGNvbXBsZXRlZFRhc2tzID0gW107XG4gICAgICAgICAgICBsZXQgdGFzaztcbiAgICAgICAgICAgIHdoaWxlICgodGFzayA9IHF1ZXVlLnNoaWZ0KCkpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5ydW5UYXNrKHRhc2spO1xuICAgICAgICAgICAgICAgIGNvbXBsZXRlZFRhc2tzLnB1c2godGFzayk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmRyYWluZWQoY29tcGxldGVkVGFza3MpO1xuICAgICAgICB9IC8vIGtlZXAgZ29pbmcsIGluIGNhc2UgbmV3IHRhc2tzIHdlcmUgYWRkZWQgaW4gdGhlIGRyYWluZWQgaGFuZGxlclxuICAgIH1cbiAgICBydW5UYXNrKHRhc2spIHtcbiAgICAgICAgaWYgKHRoaXMucnVuVGFza09wdGlvbikge1xuICAgICAgICAgICAgdGhpcy5ydW5UYXNrT3B0aW9uKHRhc2spO1xuICAgICAgICB9XG4gICAgfVxuICAgIGRyYWluZWQoY29tcGxldGVkVGFza3MpIHtcbiAgICAgICAgaWYgKHRoaXMuZHJhaW5lZE9wdGlvbikge1xuICAgICAgICAgICAgdGhpcy5kcmFpbmVkT3B0aW9uKGNvbXBsZXRlZFRhc2tzKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuLy8gQ29tcHV0ZXMgd2hhdCB0aGUgdGl0bGUgYXQgdGhlIHRvcCBvZiB0aGUgY2FsZW5kYXJBcGkgc2hvdWxkIGJlIGZvciB0aGlzIHZpZXdcbmZ1bmN0aW9uIGJ1aWxkVGl0bGUoZGF0ZVByb2ZpbGUsIHZpZXdPcHRpb25zLCBkYXRlRW52KSB7XG4gICAgbGV0IHJhbmdlO1xuICAgIC8vIGZvciB2aWV3cyB0aGF0IHNwYW4gYSBsYXJnZSB1bml0IG9mIHRpbWUsIHNob3cgdGhlIHByb3BlciBpbnRlcnZhbCwgaWdub3Jpbmcgc3RyYXkgZGF5cyBiZWZvcmUgYW5kIGFmdGVyXG4gICAgaWYgKC9eKHllYXJ8bW9udGgpJC8udGVzdChkYXRlUHJvZmlsZS5jdXJyZW50UmFuZ2VVbml0KSkge1xuICAgICAgICByYW5nZSA9IGRhdGVQcm9maWxlLmN1cnJlbnRSYW5nZTtcbiAgICB9XG4gICAgZWxzZSB7IC8vIGZvciBkYXkgdW5pdHMgb3Igc21hbGxlciwgdXNlIHRoZSBhY3R1YWwgZGF5IHJhbmdlXG4gICAgICAgIHJhbmdlID0gZGF0ZVByb2ZpbGUuYWN0aXZlUmFuZ2U7XG4gICAgfVxuICAgIHJldHVybiBkYXRlRW52LmZvcm1hdFJhbmdlKHJhbmdlLnN0YXJ0LCByYW5nZS5lbmQsIGNyZWF0ZUZvcm1hdHRlcih2aWV3T3B0aW9ucy50aXRsZUZvcm1hdCB8fCBidWlsZFRpdGxlRm9ybWF0KGRhdGVQcm9maWxlKSksIHtcbiAgICAgICAgaXNFbmRFeGNsdXNpdmU6IGRhdGVQcm9maWxlLmlzUmFuZ2VBbGxEYXksXG4gICAgICAgIGRlZmF1bHRTZXBhcmF0b3I6IHZpZXdPcHRpb25zLnRpdGxlUmFuZ2VTZXBhcmF0b3IsXG4gICAgfSk7XG59XG4vLyBHZW5lcmF0ZXMgdGhlIGZvcm1hdCBzdHJpbmcgdGhhdCBzaG91bGQgYmUgdXNlZCB0byBnZW5lcmF0ZSB0aGUgdGl0bGUgZm9yIHRoZSBjdXJyZW50IGRhdGUgcmFuZ2UuXG4vLyBBdHRlbXB0cyB0byBjb21wdXRlIHRoZSBtb3N0IGFwcHJvcHJpYXRlIGZvcm1hdCBpZiBub3QgZXhwbGljaXRseSBzcGVjaWZpZWQgd2l0aCBgdGl0bGVGb3JtYXRgLlxuZnVuY3Rpb24gYnVpbGRUaXRsZUZvcm1hdChkYXRlUHJvZmlsZSkge1xuICAgIGxldCB7IGN1cnJlbnRSYW5nZVVuaXQgfSA9IGRhdGVQcm9maWxlO1xuICAgIGlmIChjdXJyZW50UmFuZ2VVbml0ID09PSAneWVhcicpIHtcbiAgICAgICAgcmV0dXJuIHsgeWVhcjogJ251bWVyaWMnIH07XG4gICAgfVxuICAgIGlmIChjdXJyZW50UmFuZ2VVbml0ID09PSAnbW9udGgnKSB7XG4gICAgICAgIHJldHVybiB7IHllYXI6ICdudW1lcmljJywgbW9udGg6ICdsb25nJyB9OyAvLyBsaWtlIFwiU2VwdGVtYmVyIDIwMTRcIlxuICAgIH1cbiAgICBsZXQgZGF5cyA9IGRpZmZXaG9sZURheXMoZGF0ZVByb2ZpbGUuY3VycmVudFJhbmdlLnN0YXJ0LCBkYXRlUHJvZmlsZS5jdXJyZW50UmFuZ2UuZW5kKTtcbiAgICBpZiAoZGF5cyAhPT0gbnVsbCAmJiBkYXlzID4gMSkge1xuICAgICAgICAvLyBtdWx0aS1kYXkgcmFuZ2UuIHNob3J0ZXIsIGxpa2UgXCJTZXAgOSAtIDEwIDIwMTRcIlxuICAgICAgICByZXR1cm4geyB5ZWFyOiAnbnVtZXJpYycsIG1vbnRoOiAnc2hvcnQnLCBkYXk6ICdudW1lcmljJyB9O1xuICAgIH1cbiAgICAvLyBvbmUgZGF5LiBsb25nZXIsIGxpa2UgXCJTZXB0ZW1iZXIgOSAyMDE0XCJcbiAgICByZXR1cm4geyB5ZWFyOiAnbnVtZXJpYycsIG1vbnRoOiAnbG9uZycsIGRheTogJ251bWVyaWMnIH07XG59XG5cbi8vIGluIGZ1dHVyZSByZWZhY3RvciwgZG8gdGhlIHJlZHV4LXN0eWxlIGZ1bmN0aW9uKHN0YXRlPWluaXRpYWwpIGZvciBpbml0aWFsLXN0YXRlXG4vLyBhbHNvLCB3aGF0ZXZlciBpcyBoYXBwZW5pbmcgaW4gY29uc3RydWN0b3IsIGhhdmUgaXQgaGFwcGVuIGluIGFjdGlvbiBxdWV1ZSB0b29cbmNsYXNzIENhbGVuZGFyRGF0YU1hbmFnZXIge1xuICAgIGNvbnN0cnVjdG9yKHByb3BzKSB7XG4gICAgICAgIHRoaXMuY29tcHV0ZU9wdGlvbnNEYXRhID0gbWVtb2l6ZSh0aGlzLl9jb21wdXRlT3B0aW9uc0RhdGEpO1xuICAgICAgICB0aGlzLmNvbXB1dGVDdXJyZW50Vmlld0RhdGEgPSBtZW1vaXplKHRoaXMuX2NvbXB1dGVDdXJyZW50Vmlld0RhdGEpO1xuICAgICAgICB0aGlzLm9yZ2FuaXplUmF3TG9jYWxlcyA9IG1lbW9pemUob3JnYW5pemVSYXdMb2NhbGVzKTtcbiAgICAgICAgdGhpcy5idWlsZExvY2FsZSA9IG1lbW9pemUoYnVpbGRMb2NhbGUpO1xuICAgICAgICB0aGlzLmJ1aWxkUGx1Z2luSG9va3MgPSBidWlsZEJ1aWxkUGx1Z2luSG9va3MoKTtcbiAgICAgICAgdGhpcy5idWlsZERhdGVFbnYgPSBtZW1vaXplKGJ1aWxkRGF0ZUVudiQxKTtcbiAgICAgICAgdGhpcy5idWlsZFRoZW1lID0gbWVtb2l6ZShidWlsZFRoZW1lKTtcbiAgICAgICAgdGhpcy5wYXJzZVRvb2xiYXJzID0gbWVtb2l6ZShwYXJzZVRvb2xiYXJzKTtcbiAgICAgICAgdGhpcy5idWlsZFZpZXdTcGVjcyA9IG1lbW9pemUoYnVpbGRWaWV3U3BlY3MpO1xuICAgICAgICB0aGlzLmJ1aWxkRGF0ZVByb2ZpbGVHZW5lcmF0b3IgPSBtZW1vaXplT2JqQXJnKGJ1aWxkRGF0ZVByb2ZpbGVHZW5lcmF0b3IpO1xuICAgICAgICB0aGlzLmJ1aWxkVmlld0FwaSA9IG1lbW9pemUoYnVpbGRWaWV3QXBpKTtcbiAgICAgICAgdGhpcy5idWlsZFZpZXdVaVByb3BzID0gbWVtb2l6ZU9iakFyZyhidWlsZFZpZXdVaVByb3BzKTtcbiAgICAgICAgdGhpcy5idWlsZEV2ZW50VWlCeVNvdXJjZSA9IG1lbW9pemUoYnVpbGRFdmVudFVpQnlTb3VyY2UsIGlzUHJvcHNFcXVhbCk7XG4gICAgICAgIHRoaXMuYnVpbGRFdmVudFVpQmFzZXMgPSBtZW1vaXplKGJ1aWxkRXZlbnRVaUJhc2VzKTtcbiAgICAgICAgdGhpcy5wYXJzZUNvbnRleHRCdXNpbmVzc0hvdXJzID0gbWVtb2l6ZU9iakFyZyhwYXJzZUNvbnRleHRCdXNpbmVzc0hvdXJzKTtcbiAgICAgICAgdGhpcy5idWlsZFRpdGxlID0gbWVtb2l6ZShidWlsZFRpdGxlKTtcbiAgICAgICAgdGhpcy5lbWl0dGVyID0gbmV3IEVtaXR0ZXIoKTtcbiAgICAgICAgdGhpcy5hY3Rpb25SdW5uZXIgPSBuZXcgVGFza1J1bm5lcih0aGlzLl9oYW5kbGVBY3Rpb24uYmluZCh0aGlzKSwgdGhpcy51cGRhdGVEYXRhLmJpbmQodGhpcykpO1xuICAgICAgICB0aGlzLmN1cnJlbnRDYWxlbmRhck9wdGlvbnNJbnB1dCA9IHt9O1xuICAgICAgICB0aGlzLmN1cnJlbnRDYWxlbmRhck9wdGlvbnNSZWZpbmVkID0ge307XG4gICAgICAgIHRoaXMuY3VycmVudFZpZXdPcHRpb25zSW5wdXQgPSB7fTtcbiAgICAgICAgdGhpcy5jdXJyZW50Vmlld09wdGlvbnNSZWZpbmVkID0ge307XG4gICAgICAgIHRoaXMuY3VycmVudENhbGVuZGFyT3B0aW9uc1JlZmluZXJzID0ge307XG4gICAgICAgIHRoaXMuZ2V0Q3VycmVudERhdGEgPSAoKSA9PiB0aGlzLmRhdGE7XG4gICAgICAgIHRoaXMuZGlzcGF0Y2ggPSAoYWN0aW9uKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmFjdGlvblJ1bm5lci5yZXF1ZXN0KGFjdGlvbik7IC8vIHByb3RlY3RzIGFnYWluc3QgcmVjdXJzaXZlIGNhbGxzIHRvIF9oYW5kbGVBY3Rpb25cbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5wcm9wcyA9IHByb3BzO1xuICAgICAgICB0aGlzLmFjdGlvblJ1bm5lci5wYXVzZSgpO1xuICAgICAgICBsZXQgZHluYW1pY09wdGlvbk92ZXJyaWRlcyA9IHt9O1xuICAgICAgICBsZXQgb3B0aW9uc0RhdGEgPSB0aGlzLmNvbXB1dGVPcHRpb25zRGF0YShwcm9wcy5vcHRpb25PdmVycmlkZXMsIGR5bmFtaWNPcHRpb25PdmVycmlkZXMsIHByb3BzLmNhbGVuZGFyQXBpKTtcbiAgICAgICAgbGV0IGN1cnJlbnRWaWV3VHlwZSA9IG9wdGlvbnNEYXRhLmNhbGVuZGFyT3B0aW9ucy5pbml0aWFsVmlldyB8fCBvcHRpb25zRGF0YS5wbHVnaW5Ib29rcy5pbml0aWFsVmlldztcbiAgICAgICAgbGV0IGN1cnJlbnRWaWV3RGF0YSA9IHRoaXMuY29tcHV0ZUN1cnJlbnRWaWV3RGF0YShjdXJyZW50Vmlld1R5cGUsIG9wdGlvbnNEYXRhLCBwcm9wcy5vcHRpb25PdmVycmlkZXMsIGR5bmFtaWNPcHRpb25PdmVycmlkZXMpO1xuICAgICAgICAvLyB3aXJlIHRoaW5ncyB1cFxuICAgICAgICAvLyBUT0RPOiBub3QgRFJZXG4gICAgICAgIHByb3BzLmNhbGVuZGFyQXBpLmN1cnJlbnREYXRhTWFuYWdlciA9IHRoaXM7XG4gICAgICAgIHRoaXMuZW1pdHRlci5zZXRUaGlzQ29udGV4dChwcm9wcy5jYWxlbmRhckFwaSk7XG4gICAgICAgIHRoaXMuZW1pdHRlci5zZXRPcHRpb25zKGN1cnJlbnRWaWV3RGF0YS5vcHRpb25zKTtcbiAgICAgICAgbGV0IGN1cnJlbnREYXRlID0gZ2V0SW5pdGlhbERhdGUob3B0aW9uc0RhdGEuY2FsZW5kYXJPcHRpb25zLCBvcHRpb25zRGF0YS5kYXRlRW52KTtcbiAgICAgICAgbGV0IGRhdGVQcm9maWxlID0gY3VycmVudFZpZXdEYXRhLmRhdGVQcm9maWxlR2VuZXJhdG9yLmJ1aWxkKGN1cnJlbnREYXRlKTtcbiAgICAgICAgaWYgKCFyYW5nZUNvbnRhaW5zTWFya2VyKGRhdGVQcm9maWxlLmFjdGl2ZVJhbmdlLCBjdXJyZW50RGF0ZSkpIHtcbiAgICAgICAgICAgIGN1cnJlbnREYXRlID0gZGF0ZVByb2ZpbGUuY3VycmVudFJhbmdlLnN0YXJ0O1xuICAgICAgICB9XG4gICAgICAgIGxldCBjYWxlbmRhckNvbnRleHQgPSB7XG4gICAgICAgICAgICBkYXRlRW52OiBvcHRpb25zRGF0YS5kYXRlRW52LFxuICAgICAgICAgICAgb3B0aW9uczogb3B0aW9uc0RhdGEuY2FsZW5kYXJPcHRpb25zLFxuICAgICAgICAgICAgcGx1Z2luSG9va3M6IG9wdGlvbnNEYXRhLnBsdWdpbkhvb2tzLFxuICAgICAgICAgICAgY2FsZW5kYXJBcGk6IHByb3BzLmNhbGVuZGFyQXBpLFxuICAgICAgICAgICAgZGlzcGF0Y2g6IHRoaXMuZGlzcGF0Y2gsXG4gICAgICAgICAgICBlbWl0dGVyOiB0aGlzLmVtaXR0ZXIsXG4gICAgICAgICAgICBnZXRDdXJyZW50RGF0YTogdGhpcy5nZXRDdXJyZW50RGF0YSxcbiAgICAgICAgfTtcbiAgICAgICAgLy8gbmVlZHMgdG8gYmUgYWZ0ZXIgc2V0VGhpc0NvbnRleHRcbiAgICAgICAgZm9yIChsZXQgY2FsbGJhY2sgb2Ygb3B0aW9uc0RhdGEucGx1Z2luSG9va3MuY29udGV4dEluaXQpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKGNhbGVuZGFyQ29udGV4dCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gTk9UIERSWVxuICAgICAgICBsZXQgZXZlbnRTb3VyY2VzID0gaW5pdEV2ZW50U291cmNlcyhvcHRpb25zRGF0YS5jYWxlbmRhck9wdGlvbnMsIGRhdGVQcm9maWxlLCBjYWxlbmRhckNvbnRleHQpO1xuICAgICAgICBsZXQgaW5pdGlhbFN0YXRlID0ge1xuICAgICAgICAgICAgZHluYW1pY09wdGlvbk92ZXJyaWRlcyxcbiAgICAgICAgICAgIGN1cnJlbnRWaWV3VHlwZSxcbiAgICAgICAgICAgIGN1cnJlbnREYXRlLFxuICAgICAgICAgICAgZGF0ZVByb2ZpbGUsXG4gICAgICAgICAgICBidXNpbmVzc0hvdXJzOiB0aGlzLnBhcnNlQ29udGV4dEJ1c2luZXNzSG91cnMoY2FsZW5kYXJDb250ZXh0KSxcbiAgICAgICAgICAgIGV2ZW50U291cmNlcyxcbiAgICAgICAgICAgIGV2ZW50VWlCYXNlczoge30sXG4gICAgICAgICAgICBldmVudFN0b3JlOiBjcmVhdGVFbXB0eUV2ZW50U3RvcmUoKSxcbiAgICAgICAgICAgIHJlbmRlcmFibGVFdmVudFN0b3JlOiBjcmVhdGVFbXB0eUV2ZW50U3RvcmUoKSxcbiAgICAgICAgICAgIGRhdGVTZWxlY3Rpb246IG51bGwsXG4gICAgICAgICAgICBldmVudFNlbGVjdGlvbjogJycsXG4gICAgICAgICAgICBldmVudERyYWc6IG51bGwsXG4gICAgICAgICAgICBldmVudFJlc2l6ZTogbnVsbCxcbiAgICAgICAgICAgIHNlbGVjdGlvbkNvbmZpZzogdGhpcy5idWlsZFZpZXdVaVByb3BzKGNhbGVuZGFyQ29udGV4dCkuc2VsZWN0aW9uQ29uZmlnLFxuICAgICAgICB9O1xuICAgICAgICBsZXQgY29udGV4dEFuZFN0YXRlID0gT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCBjYWxlbmRhckNvbnRleHQpLCBpbml0aWFsU3RhdGUpO1xuICAgICAgICBmb3IgKGxldCByZWR1Y2VyIG9mIG9wdGlvbnNEYXRhLnBsdWdpbkhvb2tzLnJlZHVjZXJzKSB7XG4gICAgICAgICAgICBPYmplY3QuYXNzaWduKGluaXRpYWxTdGF0ZSwgcmVkdWNlcihudWxsLCBudWxsLCBjb250ZXh0QW5kU3RhdGUpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY29tcHV0ZUlzTG9hZGluZyhpbml0aWFsU3RhdGUsIGNhbGVuZGFyQ29udGV4dCkpIHtcbiAgICAgICAgICAgIHRoaXMuZW1pdHRlci50cmlnZ2VyKCdsb2FkaW5nJywgdHJ1ZSk7IC8vIE5PVCBEUllcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnN0YXRlID0gaW5pdGlhbFN0YXRlO1xuICAgICAgICB0aGlzLnVwZGF0ZURhdGEoKTtcbiAgICAgICAgdGhpcy5hY3Rpb25SdW5uZXIucmVzdW1lKCk7XG4gICAgfVxuICAgIHJlc2V0T3B0aW9ucyhvcHRpb25PdmVycmlkZXMsIGFwcGVuZCkge1xuICAgICAgICBsZXQgeyBwcm9wcyB9ID0gdGhpcztcbiAgICAgICAgcHJvcHMub3B0aW9uT3ZlcnJpZGVzID0gYXBwZW5kXG4gICAgICAgICAgICA/IE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgcHJvcHMub3B0aW9uT3ZlcnJpZGVzKSwgb3B0aW9uT3ZlcnJpZGVzKSA6IG9wdGlvbk92ZXJyaWRlcztcbiAgICAgICAgdGhpcy5hY3Rpb25SdW5uZXIucmVxdWVzdCh7XG4gICAgICAgICAgICB0eXBlOiAnTk9USElORycsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBfaGFuZGxlQWN0aW9uKGFjdGlvbikge1xuICAgICAgICBsZXQgeyBwcm9wcywgc3RhdGUsIGVtaXR0ZXIgfSA9IHRoaXM7XG4gICAgICAgIGxldCBkeW5hbWljT3B0aW9uT3ZlcnJpZGVzID0gcmVkdWNlRHluYW1pY09wdGlvbk92ZXJyaWRlcyhzdGF0ZS5keW5hbWljT3B0aW9uT3ZlcnJpZGVzLCBhY3Rpb24pO1xuICAgICAgICBsZXQgb3B0aW9uc0RhdGEgPSB0aGlzLmNvbXB1dGVPcHRpb25zRGF0YShwcm9wcy5vcHRpb25PdmVycmlkZXMsIGR5bmFtaWNPcHRpb25PdmVycmlkZXMsIHByb3BzLmNhbGVuZGFyQXBpKTtcbiAgICAgICAgbGV0IGN1cnJlbnRWaWV3VHlwZSA9IHJlZHVjZVZpZXdUeXBlKHN0YXRlLmN1cnJlbnRWaWV3VHlwZSwgYWN0aW9uKTtcbiAgICAgICAgbGV0IGN1cnJlbnRWaWV3RGF0YSA9IHRoaXMuY29tcHV0ZUN1cnJlbnRWaWV3RGF0YShjdXJyZW50Vmlld1R5cGUsIG9wdGlvbnNEYXRhLCBwcm9wcy5vcHRpb25PdmVycmlkZXMsIGR5bmFtaWNPcHRpb25PdmVycmlkZXMpO1xuICAgICAgICAvLyB3aXJlIHRoaW5ncyB1cFxuICAgICAgICAvLyBUT0RPOiBub3QgRFJZXG4gICAgICAgIHByb3BzLmNhbGVuZGFyQXBpLmN1cnJlbnREYXRhTWFuYWdlciA9IHRoaXM7XG4gICAgICAgIGVtaXR0ZXIuc2V0VGhpc0NvbnRleHQocHJvcHMuY2FsZW5kYXJBcGkpO1xuICAgICAgICBlbWl0dGVyLnNldE9wdGlvbnMoY3VycmVudFZpZXdEYXRhLm9wdGlvbnMpO1xuICAgICAgICBsZXQgY2FsZW5kYXJDb250ZXh0ID0ge1xuICAgICAgICAgICAgZGF0ZUVudjogb3B0aW9uc0RhdGEuZGF0ZUVudixcbiAgICAgICAgICAgIG9wdGlvbnM6IG9wdGlvbnNEYXRhLmNhbGVuZGFyT3B0aW9ucyxcbiAgICAgICAgICAgIHBsdWdpbkhvb2tzOiBvcHRpb25zRGF0YS5wbHVnaW5Ib29rcyxcbiAgICAgICAgICAgIGNhbGVuZGFyQXBpOiBwcm9wcy5jYWxlbmRhckFwaSxcbiAgICAgICAgICAgIGRpc3BhdGNoOiB0aGlzLmRpc3BhdGNoLFxuICAgICAgICAgICAgZW1pdHRlcixcbiAgICAgICAgICAgIGdldEN1cnJlbnREYXRhOiB0aGlzLmdldEN1cnJlbnREYXRhLFxuICAgICAgICB9O1xuICAgICAgICBsZXQgeyBjdXJyZW50RGF0ZSwgZGF0ZVByb2ZpbGUgfSA9IHN0YXRlO1xuICAgICAgICBpZiAodGhpcy5kYXRhICYmIHRoaXMuZGF0YS5kYXRlUHJvZmlsZUdlbmVyYXRvciAhPT0gY3VycmVudFZpZXdEYXRhLmRhdGVQcm9maWxlR2VuZXJhdG9yKSB7IC8vIGhhY2tcbiAgICAgICAgICAgIGRhdGVQcm9maWxlID0gY3VycmVudFZpZXdEYXRhLmRhdGVQcm9maWxlR2VuZXJhdG9yLmJ1aWxkKGN1cnJlbnREYXRlKTtcbiAgICAgICAgfVxuICAgICAgICBjdXJyZW50RGF0ZSA9IHJlZHVjZUN1cnJlbnREYXRlKGN1cnJlbnREYXRlLCBhY3Rpb24pO1xuICAgICAgICBkYXRlUHJvZmlsZSA9IHJlZHVjZURhdGVQcm9maWxlKGRhdGVQcm9maWxlLCBhY3Rpb24sIGN1cnJlbnREYXRlLCBjdXJyZW50Vmlld0RhdGEuZGF0ZVByb2ZpbGVHZW5lcmF0b3IpO1xuICAgICAgICBpZiAoYWN0aW9uLnR5cGUgPT09ICdQUkVWJyB8fCAvLyBUT0RPOiBtb3ZlIHRoaXMgbG9naWMgaW50byBEYXRlUHJvZmlsZUdlbmVyYXRvclxuICAgICAgICAgICAgYWN0aW9uLnR5cGUgPT09ICdORVhUJyB8fCAvLyBcIlxuICAgICAgICAgICAgIXJhbmdlQ29udGFpbnNNYXJrZXIoZGF0ZVByb2ZpbGUuY3VycmVudFJhbmdlLCBjdXJyZW50RGF0ZSkpIHtcbiAgICAgICAgICAgIGN1cnJlbnREYXRlID0gZGF0ZVByb2ZpbGUuY3VycmVudFJhbmdlLnN0YXJ0O1xuICAgICAgICB9XG4gICAgICAgIGxldCBldmVudFNvdXJjZXMgPSByZWR1Y2VFdmVudFNvdXJjZXMoc3RhdGUuZXZlbnRTb3VyY2VzLCBhY3Rpb24sIGRhdGVQcm9maWxlLCBjYWxlbmRhckNvbnRleHQpO1xuICAgICAgICBsZXQgZXZlbnRTdG9yZSA9IHJlZHVjZUV2ZW50U3RvcmUoc3RhdGUuZXZlbnRTdG9yZSwgYWN0aW9uLCBldmVudFNvdXJjZXMsIGRhdGVQcm9maWxlLCBjYWxlbmRhckNvbnRleHQpO1xuICAgICAgICBsZXQgaXNFdmVudHNMb2FkaW5nID0gY29tcHV0ZUV2ZW50U291cmNlc0xvYWRpbmcoZXZlbnRTb3VyY2VzKTsgLy8gQkFELiBhbHNvIGNhbGxlZCBpbiB0aGlzIGZ1bmMgaW4gY29tcHV0ZUlzTG9hZGluZ1xuICAgICAgICBsZXQgcmVuZGVyYWJsZUV2ZW50U3RvcmUgPSAoaXNFdmVudHNMb2FkaW5nICYmICFjdXJyZW50Vmlld0RhdGEub3B0aW9ucy5wcm9ncmVzc2l2ZUV2ZW50UmVuZGVyaW5nKSA/XG4gICAgICAgICAgICAoc3RhdGUucmVuZGVyYWJsZUV2ZW50U3RvcmUgfHwgZXZlbnRTdG9yZSkgOiAvLyB0cnkgZnJvbSBwcmV2aW91cyBzdGF0ZVxuICAgICAgICAgICAgZXZlbnRTdG9yZTtcbiAgICAgICAgbGV0IHsgZXZlbnRVaVNpbmdsZUJhc2UsIHNlbGVjdGlvbkNvbmZpZyB9ID0gdGhpcy5idWlsZFZpZXdVaVByb3BzKGNhbGVuZGFyQ29udGV4dCk7IC8vIHdpbGwgbWVtb2l6ZSBvYmpcbiAgICAgICAgbGV0IGV2ZW50VWlCeVNvdXJjZSA9IHRoaXMuYnVpbGRFdmVudFVpQnlTb3VyY2UoZXZlbnRTb3VyY2VzKTtcbiAgICAgICAgbGV0IGV2ZW50VWlCYXNlcyA9IHRoaXMuYnVpbGRFdmVudFVpQmFzZXMocmVuZGVyYWJsZUV2ZW50U3RvcmUuZGVmcywgZXZlbnRVaVNpbmdsZUJhc2UsIGV2ZW50VWlCeVNvdXJjZSk7XG4gICAgICAgIGxldCBuZXdTdGF0ZSA9IHtcbiAgICAgICAgICAgIGR5bmFtaWNPcHRpb25PdmVycmlkZXMsXG4gICAgICAgICAgICBjdXJyZW50Vmlld1R5cGUsXG4gICAgICAgICAgICBjdXJyZW50RGF0ZSxcbiAgICAgICAgICAgIGRhdGVQcm9maWxlLFxuICAgICAgICAgICAgZXZlbnRTb3VyY2VzLFxuICAgICAgICAgICAgZXZlbnRTdG9yZSxcbiAgICAgICAgICAgIHJlbmRlcmFibGVFdmVudFN0b3JlLFxuICAgICAgICAgICAgc2VsZWN0aW9uQ29uZmlnLFxuICAgICAgICAgICAgZXZlbnRVaUJhc2VzLFxuICAgICAgICAgICAgYnVzaW5lc3NIb3VyczogdGhpcy5wYXJzZUNvbnRleHRCdXNpbmVzc0hvdXJzKGNhbGVuZGFyQ29udGV4dCksXG4gICAgICAgICAgICBkYXRlU2VsZWN0aW9uOiByZWR1Y2VEYXRlU2VsZWN0aW9uKHN0YXRlLmRhdGVTZWxlY3Rpb24sIGFjdGlvbiksXG4gICAgICAgICAgICBldmVudFNlbGVjdGlvbjogcmVkdWNlU2VsZWN0ZWRFdmVudChzdGF0ZS5ldmVudFNlbGVjdGlvbiwgYWN0aW9uKSxcbiAgICAgICAgICAgIGV2ZW50RHJhZzogcmVkdWNlRXZlbnREcmFnKHN0YXRlLmV2ZW50RHJhZywgYWN0aW9uKSxcbiAgICAgICAgICAgIGV2ZW50UmVzaXplOiByZWR1Y2VFdmVudFJlc2l6ZShzdGF0ZS5ldmVudFJlc2l6ZSwgYWN0aW9uKSxcbiAgICAgICAgfTtcbiAgICAgICAgbGV0IGNvbnRleHRBbmRTdGF0ZSA9IE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgY2FsZW5kYXJDb250ZXh0KSwgbmV3U3RhdGUpO1xuICAgICAgICBmb3IgKGxldCByZWR1Y2VyIG9mIG9wdGlvbnNEYXRhLnBsdWdpbkhvb2tzLnJlZHVjZXJzKSB7XG4gICAgICAgICAgICBPYmplY3QuYXNzaWduKG5ld1N0YXRlLCByZWR1Y2VyKHN0YXRlLCBhY3Rpb24sIGNvbnRleHRBbmRTdGF0ZSkpOyAvLyBnaXZlIHRoZSBPTEQgc3RhdGUsIGZvciBvbGQgdmFsdWVcbiAgICAgICAgfVxuICAgICAgICBsZXQgd2FzTG9hZGluZyA9IGNvbXB1dGVJc0xvYWRpbmcoc3RhdGUsIGNhbGVuZGFyQ29udGV4dCk7XG4gICAgICAgIGxldCBpc0xvYWRpbmcgPSBjb21wdXRlSXNMb2FkaW5nKG5ld1N0YXRlLCBjYWxlbmRhckNvbnRleHQpO1xuICAgICAgICAvLyBUT0RPOiB1c2UgcHJvcFNldEhhbmRsZXJzIGluIHBsdWdpbiBzeXN0ZW1cbiAgICAgICAgaWYgKCF3YXNMb2FkaW5nICYmIGlzTG9hZGluZykge1xuICAgICAgICAgICAgZW1pdHRlci50cmlnZ2VyKCdsb2FkaW5nJywgdHJ1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAod2FzTG9hZGluZyAmJiAhaXNMb2FkaW5nKSB7XG4gICAgICAgICAgICBlbWl0dGVyLnRyaWdnZXIoJ2xvYWRpbmcnLCBmYWxzZSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zdGF0ZSA9IG5ld1N0YXRlO1xuICAgICAgICBpZiAocHJvcHMub25BY3Rpb24pIHtcbiAgICAgICAgICAgIHByb3BzLm9uQWN0aW9uKGFjdGlvbik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgdXBkYXRlRGF0YSgpIHtcbiAgICAgICAgbGV0IHsgcHJvcHMsIHN0YXRlIH0gPSB0aGlzO1xuICAgICAgICBsZXQgb2xkRGF0YSA9IHRoaXMuZGF0YTtcbiAgICAgICAgbGV0IG9wdGlvbnNEYXRhID0gdGhpcy5jb21wdXRlT3B0aW9uc0RhdGEocHJvcHMub3B0aW9uT3ZlcnJpZGVzLCBzdGF0ZS5keW5hbWljT3B0aW9uT3ZlcnJpZGVzLCBwcm9wcy5jYWxlbmRhckFwaSk7XG4gICAgICAgIGxldCBjdXJyZW50Vmlld0RhdGEgPSB0aGlzLmNvbXB1dGVDdXJyZW50Vmlld0RhdGEoc3RhdGUuY3VycmVudFZpZXdUeXBlLCBvcHRpb25zRGF0YSwgcHJvcHMub3B0aW9uT3ZlcnJpZGVzLCBzdGF0ZS5keW5hbWljT3B0aW9uT3ZlcnJpZGVzKTtcbiAgICAgICAgbGV0IGRhdGEgPSB0aGlzLmRhdGEgPSBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7IHZpZXdUaXRsZTogdGhpcy5idWlsZFRpdGxlKHN0YXRlLmRhdGVQcm9maWxlLCBjdXJyZW50Vmlld0RhdGEub3B0aW9ucywgb3B0aW9uc0RhdGEuZGF0ZUVudiksIGNhbGVuZGFyQXBpOiBwcm9wcy5jYWxlbmRhckFwaSwgZGlzcGF0Y2g6IHRoaXMuZGlzcGF0Y2gsIGVtaXR0ZXI6IHRoaXMuZW1pdHRlciwgZ2V0Q3VycmVudERhdGE6IHRoaXMuZ2V0Q3VycmVudERhdGEgfSwgb3B0aW9uc0RhdGEpLCBjdXJyZW50Vmlld0RhdGEpLCBzdGF0ZSk7XG4gICAgICAgIGxldCBjaGFuZ2VIYW5kbGVycyA9IG9wdGlvbnNEYXRhLnBsdWdpbkhvb2tzLm9wdGlvbkNoYW5nZUhhbmRsZXJzO1xuICAgICAgICBsZXQgb2xkQ2FsZW5kYXJPcHRpb25zID0gb2xkRGF0YSAmJiBvbGREYXRhLmNhbGVuZGFyT3B0aW9ucztcbiAgICAgICAgbGV0IG5ld0NhbGVuZGFyT3B0aW9ucyA9IG9wdGlvbnNEYXRhLmNhbGVuZGFyT3B0aW9ucztcbiAgICAgICAgaWYgKG9sZENhbGVuZGFyT3B0aW9ucyAmJiBvbGRDYWxlbmRhck9wdGlvbnMgIT09IG5ld0NhbGVuZGFyT3B0aW9ucykge1xuICAgICAgICAgICAgaWYgKG9sZENhbGVuZGFyT3B0aW9ucy50aW1lWm9uZSAhPT0gbmV3Q2FsZW5kYXJPcHRpb25zLnRpbWVab25lKSB7XG4gICAgICAgICAgICAgICAgLy8gaGFja1xuICAgICAgICAgICAgICAgIHN0YXRlLmV2ZW50U291cmNlcyA9IGRhdGEuZXZlbnRTb3VyY2VzID0gcmVkdWNlRXZlbnRTb3VyY2VzTmV3VGltZVpvbmUoZGF0YS5ldmVudFNvdXJjZXMsIHN0YXRlLmRhdGVQcm9maWxlLCBkYXRhKTtcbiAgICAgICAgICAgICAgICBzdGF0ZS5ldmVudFN0b3JlID0gZGF0YS5ldmVudFN0b3JlID0gcmV6b25lRXZlbnRTdG9yZURhdGVzKGRhdGEuZXZlbnRTdG9yZSwgb2xkRGF0YS5kYXRlRW52LCBkYXRhLmRhdGVFbnYpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZm9yIChsZXQgb3B0aW9uTmFtZSBpbiBjaGFuZ2VIYW5kbGVycykge1xuICAgICAgICAgICAgICAgIGlmIChvbGRDYWxlbmRhck9wdGlvbnNbb3B0aW9uTmFtZV0gIT09IG5ld0NhbGVuZGFyT3B0aW9uc1tvcHRpb25OYW1lXSkge1xuICAgICAgICAgICAgICAgICAgICBjaGFuZ2VIYW5kbGVyc1tvcHRpb25OYW1lXShuZXdDYWxlbmRhck9wdGlvbnNbb3B0aW9uTmFtZV0sIGRhdGEpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAocHJvcHMub25EYXRhKSB7XG4gICAgICAgICAgICBwcm9wcy5vbkRhdGEoZGF0YSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgX2NvbXB1dGVPcHRpb25zRGF0YShvcHRpb25PdmVycmlkZXMsIGR5bmFtaWNPcHRpb25PdmVycmlkZXMsIGNhbGVuZGFyQXBpKSB7XG4gICAgICAgIC8vIFRPRE86IGJsYWNrbGlzdCBvcHRpb25zIHRoYXQgYXJlIGhhbmRsZWQgYnkgb3B0aW9uQ2hhbmdlSGFuZGxlcnNcbiAgICAgICAgbGV0IHsgcmVmaW5lZE9wdGlvbnMsIHBsdWdpbkhvb2tzLCBsb2NhbGVEZWZhdWx0cywgYXZhaWxhYmxlTG9jYWxlRGF0YSwgZXh0cmEsIH0gPSB0aGlzLnByb2Nlc3NSYXdDYWxlbmRhck9wdGlvbnMob3B0aW9uT3ZlcnJpZGVzLCBkeW5hbWljT3B0aW9uT3ZlcnJpZGVzKTtcbiAgICAgICAgd2FyblVua25vd25PcHRpb25zKGV4dHJhKTtcbiAgICAgICAgbGV0IGRhdGVFbnYgPSB0aGlzLmJ1aWxkRGF0ZUVudihyZWZpbmVkT3B0aW9ucy50aW1lWm9uZSwgcmVmaW5lZE9wdGlvbnMubG9jYWxlLCByZWZpbmVkT3B0aW9ucy53ZWVrTnVtYmVyQ2FsY3VsYXRpb24sIHJlZmluZWRPcHRpb25zLmZpcnN0RGF5LCByZWZpbmVkT3B0aW9ucy53ZWVrVGV4dCwgcGx1Z2luSG9va3MsIGF2YWlsYWJsZUxvY2FsZURhdGEsIHJlZmluZWRPcHRpb25zLmRlZmF1bHRSYW5nZVNlcGFyYXRvcik7XG4gICAgICAgIGxldCB2aWV3U3BlY3MgPSB0aGlzLmJ1aWxkVmlld1NwZWNzKHBsdWdpbkhvb2tzLnZpZXdzLCBvcHRpb25PdmVycmlkZXMsIGR5bmFtaWNPcHRpb25PdmVycmlkZXMsIGxvY2FsZURlZmF1bHRzKTtcbiAgICAgICAgbGV0IHRoZW1lID0gdGhpcy5idWlsZFRoZW1lKHJlZmluZWRPcHRpb25zLCBwbHVnaW5Ib29rcyk7XG4gICAgICAgIGxldCB0b29sYmFyQ29uZmlnID0gdGhpcy5wYXJzZVRvb2xiYXJzKHJlZmluZWRPcHRpb25zLCBvcHRpb25PdmVycmlkZXMsIHRoZW1lLCB2aWV3U3BlY3MsIGNhbGVuZGFyQXBpKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNhbGVuZGFyT3B0aW9uczogcmVmaW5lZE9wdGlvbnMsXG4gICAgICAgICAgICBwbHVnaW5Ib29rcyxcbiAgICAgICAgICAgIGRhdGVFbnYsXG4gICAgICAgICAgICB2aWV3U3BlY3MsXG4gICAgICAgICAgICB0aGVtZSxcbiAgICAgICAgICAgIHRvb2xiYXJDb25maWcsXG4gICAgICAgICAgICBsb2NhbGVEZWZhdWx0cyxcbiAgICAgICAgICAgIGF2YWlsYWJsZVJhd0xvY2FsZXM6IGF2YWlsYWJsZUxvY2FsZURhdGEubWFwLFxuICAgICAgICB9O1xuICAgIH1cbiAgICAvLyBhbHdheXMgY2FsbGVkIGZyb20gYmVoaW5kIGEgbWVtb2l6ZXJcbiAgICBwcm9jZXNzUmF3Q2FsZW5kYXJPcHRpb25zKG9wdGlvbk92ZXJyaWRlcywgZHluYW1pY09wdGlvbk92ZXJyaWRlcykge1xuICAgICAgICBsZXQgeyBsb2NhbGVzLCBsb2NhbGUgfSA9IG1lcmdlUmF3T3B0aW9ucyhbXG4gICAgICAgICAgICBCQVNFX09QVElPTl9ERUZBVUxUUyxcbiAgICAgICAgICAgIG9wdGlvbk92ZXJyaWRlcyxcbiAgICAgICAgICAgIGR5bmFtaWNPcHRpb25PdmVycmlkZXMsXG4gICAgICAgIF0pO1xuICAgICAgICBsZXQgYXZhaWxhYmxlTG9jYWxlRGF0YSA9IHRoaXMub3JnYW5pemVSYXdMb2NhbGVzKGxvY2FsZXMpO1xuICAgICAgICBsZXQgYXZhaWxhYmxlUmF3TG9jYWxlcyA9IGF2YWlsYWJsZUxvY2FsZURhdGEubWFwO1xuICAgICAgICBsZXQgbG9jYWxlRGVmYXVsdHMgPSB0aGlzLmJ1aWxkTG9jYWxlKGxvY2FsZSB8fCBhdmFpbGFibGVMb2NhbGVEYXRhLmRlZmF1bHRDb2RlLCBhdmFpbGFibGVSYXdMb2NhbGVzKS5vcHRpb25zO1xuICAgICAgICBsZXQgcGx1Z2luSG9va3MgPSB0aGlzLmJ1aWxkUGx1Z2luSG9va3Mob3B0aW9uT3ZlcnJpZGVzLnBsdWdpbnMgfHwgW10sIGdsb2JhbFBsdWdpbnMpO1xuICAgICAgICBsZXQgcmVmaW5lcnMgPSB0aGlzLmN1cnJlbnRDYWxlbmRhck9wdGlvbnNSZWZpbmVycyA9IE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgQkFTRV9PUFRJT05fUkVGSU5FUlMpLCBDQUxFTkRBUl9MSVNURU5FUl9SRUZJTkVSUyksIENBTEVOREFSX09QVElPTl9SRUZJTkVSUyksIHBsdWdpbkhvb2tzLmxpc3RlbmVyUmVmaW5lcnMpLCBwbHVnaW5Ib29rcy5vcHRpb25SZWZpbmVycyk7XG4gICAgICAgIGxldCBleHRyYSA9IHt9O1xuICAgICAgICBsZXQgcmF3ID0gbWVyZ2VSYXdPcHRpb25zKFtcbiAgICAgICAgICAgIEJBU0VfT1BUSU9OX0RFRkFVTFRTLFxuICAgICAgICAgICAgbG9jYWxlRGVmYXVsdHMsXG4gICAgICAgICAgICBvcHRpb25PdmVycmlkZXMsXG4gICAgICAgICAgICBkeW5hbWljT3B0aW9uT3ZlcnJpZGVzLFxuICAgICAgICBdKTtcbiAgICAgICAgbGV0IHJlZmluZWQgPSB7fTtcbiAgICAgICAgbGV0IGN1cnJlbnRSYXcgPSB0aGlzLmN1cnJlbnRDYWxlbmRhck9wdGlvbnNJbnB1dDtcbiAgICAgICAgbGV0IGN1cnJlbnRSZWZpbmVkID0gdGhpcy5jdXJyZW50Q2FsZW5kYXJPcHRpb25zUmVmaW5lZDtcbiAgICAgICAgbGV0IGFueUNoYW5nZXMgPSBmYWxzZTtcbiAgICAgICAgZm9yIChsZXQgb3B0aW9uTmFtZSBpbiByYXcpIHtcbiAgICAgICAgICAgIGlmIChvcHRpb25OYW1lICE9PSAncGx1Z2lucycpIHsgLy8gYmVjYXVzZSBwbHVnaW5zIGlzIHNwZWNpYWwtY2FzZWRcbiAgICAgICAgICAgICAgICBpZiAocmF3W29wdGlvbk5hbWVdID09PSBjdXJyZW50UmF3W29wdGlvbk5hbWVdIHx8XG4gICAgICAgICAgICAgICAgICAgIChDT01QTEVYX09QVElPTl9DT01QQVJBVE9SU1tvcHRpb25OYW1lXSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgKG9wdGlvbk5hbWUgaW4gY3VycmVudFJhdykgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIENPTVBMRVhfT1BUSU9OX0NPTVBBUkFUT1JTW29wdGlvbk5hbWVdKGN1cnJlbnRSYXdbb3B0aW9uTmFtZV0sIHJhd1tvcHRpb25OYW1lXSkpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlZmluZWRbb3B0aW9uTmFtZV0gPSBjdXJyZW50UmVmaW5lZFtvcHRpb25OYW1lXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAocmVmaW5lcnNbb3B0aW9uTmFtZV0pIHtcbiAgICAgICAgICAgICAgICAgICAgcmVmaW5lZFtvcHRpb25OYW1lXSA9IHJlZmluZXJzW29wdGlvbk5hbWVdKHJhd1tvcHRpb25OYW1lXSk7XG4gICAgICAgICAgICAgICAgICAgIGFueUNoYW5nZXMgPSB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZXh0cmFbb3B0aW9uTmFtZV0gPSBjdXJyZW50UmF3W29wdGlvbk5hbWVdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoYW55Q2hhbmdlcykge1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50Q2FsZW5kYXJPcHRpb25zSW5wdXQgPSByYXc7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRDYWxlbmRhck9wdGlvbnNSZWZpbmVkID0gcmVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcmF3T3B0aW9uczogdGhpcy5jdXJyZW50Q2FsZW5kYXJPcHRpb25zSW5wdXQsXG4gICAgICAgICAgICByZWZpbmVkT3B0aW9uczogdGhpcy5jdXJyZW50Q2FsZW5kYXJPcHRpb25zUmVmaW5lZCxcbiAgICAgICAgICAgIHBsdWdpbkhvb2tzLFxuICAgICAgICAgICAgYXZhaWxhYmxlTG9jYWxlRGF0YSxcbiAgICAgICAgICAgIGxvY2FsZURlZmF1bHRzLFxuICAgICAgICAgICAgZXh0cmEsXG4gICAgICAgIH07XG4gICAgfVxuICAgIF9jb21wdXRlQ3VycmVudFZpZXdEYXRhKHZpZXdUeXBlLCBvcHRpb25zRGF0YSwgb3B0aW9uT3ZlcnJpZGVzLCBkeW5hbWljT3B0aW9uT3ZlcnJpZGVzKSB7XG4gICAgICAgIGxldCB2aWV3U3BlYyA9IG9wdGlvbnNEYXRhLnZpZXdTcGVjc1t2aWV3VHlwZV07XG4gICAgICAgIGlmICghdmlld1NwZWMpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgdmlld1R5cGUgXCIke3ZpZXdUeXBlfVwiIGlzIG5vdCBhdmFpbGFibGUuIFBsZWFzZSBtYWtlIHN1cmUgeW91J3ZlIGxvYWRlZCBhbGwgbmVjY2Vzc2FyeSBwbHVnaW5zYCk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHsgcmVmaW5lZE9wdGlvbnMsIGV4dHJhIH0gPSB0aGlzLnByb2Nlc3NSYXdWaWV3T3B0aW9ucyh2aWV3U3BlYywgb3B0aW9uc0RhdGEucGx1Z2luSG9va3MsIG9wdGlvbnNEYXRhLmxvY2FsZURlZmF1bHRzLCBvcHRpb25PdmVycmlkZXMsIGR5bmFtaWNPcHRpb25PdmVycmlkZXMpO1xuICAgICAgICB3YXJuVW5rbm93bk9wdGlvbnMoZXh0cmEpO1xuICAgICAgICBsZXQgZGF0ZVByb2ZpbGVHZW5lcmF0b3IgPSB0aGlzLmJ1aWxkRGF0ZVByb2ZpbGVHZW5lcmF0b3Ioe1xuICAgICAgICAgICAgZGF0ZVByb2ZpbGVHZW5lcmF0b3JDbGFzczogdmlld1NwZWMub3B0aW9uRGVmYXVsdHMuZGF0ZVByb2ZpbGVHZW5lcmF0b3JDbGFzcyxcbiAgICAgICAgICAgIGR1cmF0aW9uOiB2aWV3U3BlYy5kdXJhdGlvbixcbiAgICAgICAgICAgIGR1cmF0aW9uVW5pdDogdmlld1NwZWMuZHVyYXRpb25Vbml0LFxuICAgICAgICAgICAgdXNlc01pbk1heFRpbWU6IHZpZXdTcGVjLm9wdGlvbkRlZmF1bHRzLnVzZXNNaW5NYXhUaW1lLFxuICAgICAgICAgICAgZGF0ZUVudjogb3B0aW9uc0RhdGEuZGF0ZUVudixcbiAgICAgICAgICAgIGNhbGVuZGFyQXBpOiB0aGlzLnByb3BzLmNhbGVuZGFyQXBpLFxuICAgICAgICAgICAgc2xvdE1pblRpbWU6IHJlZmluZWRPcHRpb25zLnNsb3RNaW5UaW1lLFxuICAgICAgICAgICAgc2xvdE1heFRpbWU6IHJlZmluZWRPcHRpb25zLnNsb3RNYXhUaW1lLFxuICAgICAgICAgICAgc2hvd05vbkN1cnJlbnREYXRlczogcmVmaW5lZE9wdGlvbnMuc2hvd05vbkN1cnJlbnREYXRlcyxcbiAgICAgICAgICAgIGRheUNvdW50OiByZWZpbmVkT3B0aW9ucy5kYXlDb3VudCxcbiAgICAgICAgICAgIGRhdGVBbGlnbm1lbnQ6IHJlZmluZWRPcHRpb25zLmRhdGVBbGlnbm1lbnQsXG4gICAgICAgICAgICBkYXRlSW5jcmVtZW50OiByZWZpbmVkT3B0aW9ucy5kYXRlSW5jcmVtZW50LFxuICAgICAgICAgICAgaGlkZGVuRGF5czogcmVmaW5lZE9wdGlvbnMuaGlkZGVuRGF5cyxcbiAgICAgICAgICAgIHdlZWtlbmRzOiByZWZpbmVkT3B0aW9ucy53ZWVrZW5kcyxcbiAgICAgICAgICAgIG5vd0lucHV0OiByZWZpbmVkT3B0aW9ucy5ub3csXG4gICAgICAgICAgICB2YWxpZFJhbmdlSW5wdXQ6IHJlZmluZWRPcHRpb25zLnZhbGlkUmFuZ2UsXG4gICAgICAgICAgICB2aXNpYmxlUmFuZ2VJbnB1dDogcmVmaW5lZE9wdGlvbnMudmlzaWJsZVJhbmdlLFxuICAgICAgICAgICAgbW9udGhNb2RlOiByZWZpbmVkT3B0aW9ucy5tb250aE1vZGUsXG4gICAgICAgICAgICBmaXhlZFdlZWtDb3VudDogcmVmaW5lZE9wdGlvbnMuZml4ZWRXZWVrQ291bnQsXG4gICAgICAgIH0pO1xuICAgICAgICBsZXQgdmlld0FwaSA9IHRoaXMuYnVpbGRWaWV3QXBpKHZpZXdUeXBlLCB0aGlzLmdldEN1cnJlbnREYXRhLCBvcHRpb25zRGF0YS5kYXRlRW52KTtcbiAgICAgICAgcmV0dXJuIHsgdmlld1NwZWMsIG9wdGlvbnM6IHJlZmluZWRPcHRpb25zLCBkYXRlUHJvZmlsZUdlbmVyYXRvciwgdmlld0FwaSB9O1xuICAgIH1cbiAgICBwcm9jZXNzUmF3Vmlld09wdGlvbnModmlld1NwZWMsIHBsdWdpbkhvb2tzLCBsb2NhbGVEZWZhdWx0cywgb3B0aW9uT3ZlcnJpZGVzLCBkeW5hbWljT3B0aW9uT3ZlcnJpZGVzKSB7XG4gICAgICAgIGxldCByYXcgPSBtZXJnZVJhd09wdGlvbnMoW1xuICAgICAgICAgICAgQkFTRV9PUFRJT05fREVGQVVMVFMsXG4gICAgICAgICAgICB2aWV3U3BlYy5vcHRpb25EZWZhdWx0cyxcbiAgICAgICAgICAgIGxvY2FsZURlZmF1bHRzLFxuICAgICAgICAgICAgb3B0aW9uT3ZlcnJpZGVzLFxuICAgICAgICAgICAgdmlld1NwZWMub3B0aW9uT3ZlcnJpZGVzLFxuICAgICAgICAgICAgZHluYW1pY09wdGlvbk92ZXJyaWRlcyxcbiAgICAgICAgXSk7XG4gICAgICAgIGxldCByZWZpbmVycyA9IE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCBCQVNFX09QVElPTl9SRUZJTkVSUyksIENBTEVOREFSX0xJU1RFTkVSX1JFRklORVJTKSwgQ0FMRU5EQVJfT1BUSU9OX1JFRklORVJTKSwgVklFV19PUFRJT05fUkVGSU5FUlMpLCBwbHVnaW5Ib29rcy5saXN0ZW5lclJlZmluZXJzKSwgcGx1Z2luSG9va3Mub3B0aW9uUmVmaW5lcnMpO1xuICAgICAgICBsZXQgcmVmaW5lZCA9IHt9O1xuICAgICAgICBsZXQgY3VycmVudFJhdyA9IHRoaXMuY3VycmVudFZpZXdPcHRpb25zSW5wdXQ7XG4gICAgICAgIGxldCBjdXJyZW50UmVmaW5lZCA9IHRoaXMuY3VycmVudFZpZXdPcHRpb25zUmVmaW5lZDtcbiAgICAgICAgbGV0IGFueUNoYW5nZXMgPSBmYWxzZTtcbiAgICAgICAgbGV0IGV4dHJhID0ge307XG4gICAgICAgIGZvciAobGV0IG9wdGlvbk5hbWUgaW4gcmF3KSB7XG4gICAgICAgICAgICBpZiAocmF3W29wdGlvbk5hbWVdID09PSBjdXJyZW50UmF3W29wdGlvbk5hbWVdIHx8XG4gICAgICAgICAgICAgICAgKENPTVBMRVhfT1BUSU9OX0NPTVBBUkFUT1JTW29wdGlvbk5hbWVdICYmXG4gICAgICAgICAgICAgICAgICAgIENPTVBMRVhfT1BUSU9OX0NPTVBBUkFUT1JTW29wdGlvbk5hbWVdKHJhd1tvcHRpb25OYW1lXSwgY3VycmVudFJhd1tvcHRpb25OYW1lXSkpKSB7XG4gICAgICAgICAgICAgICAgcmVmaW5lZFtvcHRpb25OYW1lXSA9IGN1cnJlbnRSZWZpbmVkW29wdGlvbk5hbWVdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKHJhd1tvcHRpb25OYW1lXSA9PT0gdGhpcy5jdXJyZW50Q2FsZW5kYXJPcHRpb25zSW5wdXRbb3B0aW9uTmFtZV0gfHxcbiAgICAgICAgICAgICAgICAgICAgKENPTVBMRVhfT1BUSU9OX0NPTVBBUkFUT1JTW29wdGlvbk5hbWVdICYmXG4gICAgICAgICAgICAgICAgICAgICAgICBDT01QTEVYX09QVElPTl9DT01QQVJBVE9SU1tvcHRpb25OYW1lXShyYXdbb3B0aW9uTmFtZV0sIHRoaXMuY3VycmVudENhbGVuZGFyT3B0aW9uc0lucHV0W29wdGlvbk5hbWVdKSkpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbk5hbWUgaW4gdGhpcy5jdXJyZW50Q2FsZW5kYXJPcHRpb25zUmVmaW5lZCkgeyAvLyBtaWdodCBiZSBhbiBcImV4dHJhXCIgcHJvcFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVmaW5lZFtvcHRpb25OYW1lXSA9IHRoaXMuY3VycmVudENhbGVuZGFyT3B0aW9uc1JlZmluZWRbb3B0aW9uTmFtZV07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAocmVmaW5lcnNbb3B0aW9uTmFtZV0pIHtcbiAgICAgICAgICAgICAgICAgICAgcmVmaW5lZFtvcHRpb25OYW1lXSA9IHJlZmluZXJzW29wdGlvbk5hbWVdKHJhd1tvcHRpb25OYW1lXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBleHRyYVtvcHRpb25OYW1lXSA9IHJhd1tvcHRpb25OYW1lXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYW55Q2hhbmdlcyA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGFueUNoYW5nZXMpIHtcbiAgICAgICAgICAgIHRoaXMuY3VycmVudFZpZXdPcHRpb25zSW5wdXQgPSByYXc7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRWaWV3T3B0aW9uc1JlZmluZWQgPSByZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByYXdPcHRpb25zOiB0aGlzLmN1cnJlbnRWaWV3T3B0aW9uc0lucHV0LFxuICAgICAgICAgICAgcmVmaW5lZE9wdGlvbnM6IHRoaXMuY3VycmVudFZpZXdPcHRpb25zUmVmaW5lZCxcbiAgICAgICAgICAgIGV4dHJhLFxuICAgICAgICB9O1xuICAgIH1cbn1cbmZ1bmN0aW9uIGJ1aWxkRGF0ZUVudiQxKHRpbWVab25lLCBleHBsaWNpdExvY2FsZSwgd2Vla051bWJlckNhbGN1bGF0aW9uLCBmaXJzdERheSwgd2Vla1RleHQsIHBsdWdpbkhvb2tzLCBhdmFpbGFibGVMb2NhbGVEYXRhLCBkZWZhdWx0U2VwYXJhdG9yKSB7XG4gICAgbGV0IGxvY2FsZSA9IGJ1aWxkTG9jYWxlKGV4cGxpY2l0TG9jYWxlIHx8IGF2YWlsYWJsZUxvY2FsZURhdGEuZGVmYXVsdENvZGUsIGF2YWlsYWJsZUxvY2FsZURhdGEubWFwKTtcbiAgICByZXR1cm4gbmV3IERhdGVFbnYoe1xuICAgICAgICBjYWxlbmRhclN5c3RlbTogJ2dyZWdvcnknLFxuICAgICAgICB0aW1lWm9uZSxcbiAgICAgICAgbmFtZWRUaW1lWm9uZUltcGw6IHBsdWdpbkhvb2tzLm5hbWVkVGltZVpvbmVkSW1wbCxcbiAgICAgICAgbG9jYWxlLFxuICAgICAgICB3ZWVrTnVtYmVyQ2FsY3VsYXRpb24sXG4gICAgICAgIGZpcnN0RGF5LFxuICAgICAgICB3ZWVrVGV4dCxcbiAgICAgICAgY21kRm9ybWF0dGVyOiBwbHVnaW5Ib29rcy5jbWRGb3JtYXR0ZXIsXG4gICAgICAgIGRlZmF1bHRTZXBhcmF0b3IsXG4gICAgfSk7XG59XG5mdW5jdGlvbiBidWlsZFRoZW1lKG9wdGlvbnMsIHBsdWdpbkhvb2tzKSB7XG4gICAgbGV0IFRoZW1lQ2xhc3MgPSBwbHVnaW5Ib29rcy50aGVtZUNsYXNzZXNbb3B0aW9ucy50aGVtZVN5c3RlbV0gfHwgU3RhbmRhcmRUaGVtZTtcbiAgICByZXR1cm4gbmV3IFRoZW1lQ2xhc3Mob3B0aW9ucyk7XG59XG5mdW5jdGlvbiBidWlsZERhdGVQcm9maWxlR2VuZXJhdG9yKHByb3BzKSB7XG4gICAgbGV0IERhdGVQcm9maWxlR2VuZXJhdG9yQ2xhc3MgPSBwcm9wcy5kYXRlUHJvZmlsZUdlbmVyYXRvckNsYXNzIHx8IERhdGVQcm9maWxlR2VuZXJhdG9yO1xuICAgIHJldHVybiBuZXcgRGF0ZVByb2ZpbGVHZW5lcmF0b3JDbGFzcyhwcm9wcyk7XG59XG5mdW5jdGlvbiBidWlsZFZpZXdBcGkodHlwZSwgZ2V0Q3VycmVudERhdGEsIGRhdGVFbnYpIHtcbiAgICByZXR1cm4gbmV3IFZpZXdJbXBsKHR5cGUsIGdldEN1cnJlbnREYXRhLCBkYXRlRW52KTtcbn1cbmZ1bmN0aW9uIGJ1aWxkRXZlbnRVaUJ5U291cmNlKGV2ZW50U291cmNlcykge1xuICAgIHJldHVybiBtYXBIYXNoKGV2ZW50U291cmNlcywgKGV2ZW50U291cmNlKSA9PiBldmVudFNvdXJjZS51aSk7XG59XG5mdW5jdGlvbiBidWlsZEV2ZW50VWlCYXNlcyhldmVudERlZnMsIGV2ZW50VWlTaW5nbGVCYXNlLCBldmVudFVpQnlTb3VyY2UpIHtcbiAgICBsZXQgZXZlbnRVaUJhc2VzID0geyAnJzogZXZlbnRVaVNpbmdsZUJhc2UgfTtcbiAgICBmb3IgKGxldCBkZWZJZCBpbiBldmVudERlZnMpIHtcbiAgICAgICAgbGV0IGRlZiA9IGV2ZW50RGVmc1tkZWZJZF07XG4gICAgICAgIGlmIChkZWYuc291cmNlSWQgJiYgZXZlbnRVaUJ5U291cmNlW2RlZi5zb3VyY2VJZF0pIHtcbiAgICAgICAgICAgIGV2ZW50VWlCYXNlc1tkZWZJZF0gPSBldmVudFVpQnlTb3VyY2VbZGVmLnNvdXJjZUlkXTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZXZlbnRVaUJhc2VzO1xufVxuZnVuY3Rpb24gYnVpbGRWaWV3VWlQcm9wcyhjYWxlbmRhckNvbnRleHQpIHtcbiAgICBsZXQgeyBvcHRpb25zIH0gPSBjYWxlbmRhckNvbnRleHQ7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgZXZlbnRVaVNpbmdsZUJhc2U6IGNyZWF0ZUV2ZW50VWkoe1xuICAgICAgICAgICAgZGlzcGxheTogb3B0aW9ucy5ldmVudERpc3BsYXksXG4gICAgICAgICAgICBlZGl0YWJsZTogb3B0aW9ucy5lZGl0YWJsZSxcbiAgICAgICAgICAgIHN0YXJ0RWRpdGFibGU6IG9wdGlvbnMuZXZlbnRTdGFydEVkaXRhYmxlLFxuICAgICAgICAgICAgZHVyYXRpb25FZGl0YWJsZTogb3B0aW9ucy5ldmVudER1cmF0aW9uRWRpdGFibGUsXG4gICAgICAgICAgICBjb25zdHJhaW50OiBvcHRpb25zLmV2ZW50Q29uc3RyYWludCxcbiAgICAgICAgICAgIG92ZXJsYXA6IHR5cGVvZiBvcHRpb25zLmV2ZW50T3ZlcmxhcCA9PT0gJ2Jvb2xlYW4nID8gb3B0aW9ucy5ldmVudE92ZXJsYXAgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBhbGxvdzogb3B0aW9ucy5ldmVudEFsbG93LFxuICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yOiBvcHRpb25zLmV2ZW50QmFja2dyb3VuZENvbG9yLFxuICAgICAgICAgICAgYm9yZGVyQ29sb3I6IG9wdGlvbnMuZXZlbnRCb3JkZXJDb2xvcixcbiAgICAgICAgICAgIHRleHRDb2xvcjogb3B0aW9ucy5ldmVudFRleHRDb2xvcixcbiAgICAgICAgICAgIGNvbG9yOiBvcHRpb25zLmV2ZW50Q29sb3IsXG4gICAgICAgICAgICAvLyBjbGFzc05hbWVzOiBvcHRpb25zLmV2ZW50Q2xhc3NOYW1lcyAvLyByZW5kZXIgaG9vayB3aWxsIGhhbmRsZSB0aGlzXG4gICAgICAgIH0sIGNhbGVuZGFyQ29udGV4dCksXG4gICAgICAgIHNlbGVjdGlvbkNvbmZpZzogY3JlYXRlRXZlbnRVaSh7XG4gICAgICAgICAgICBjb25zdHJhaW50OiBvcHRpb25zLnNlbGVjdENvbnN0cmFpbnQsXG4gICAgICAgICAgICBvdmVybGFwOiB0eXBlb2Ygb3B0aW9ucy5zZWxlY3RPdmVybGFwID09PSAnYm9vbGVhbicgPyBvcHRpb25zLnNlbGVjdE92ZXJsYXAgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBhbGxvdzogb3B0aW9ucy5zZWxlY3RBbGxvdyxcbiAgICAgICAgfSwgY2FsZW5kYXJDb250ZXh0KSxcbiAgICB9O1xufVxuZnVuY3Rpb24gY29tcHV0ZUlzTG9hZGluZyhzdGF0ZSwgY29udGV4dCkge1xuICAgIGZvciAobGV0IGlzTG9hZGluZ0Z1bmMgb2YgY29udGV4dC5wbHVnaW5Ib29rcy5pc0xvYWRpbmdGdW5jcykge1xuICAgICAgICBpZiAoaXNMb2FkaW5nRnVuYyhzdGF0ZSkpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn1cbmZ1bmN0aW9uIHBhcnNlQ29udGV4dEJ1c2luZXNzSG91cnMoY2FsZW5kYXJDb250ZXh0KSB7XG4gICAgcmV0dXJuIHBhcnNlQnVzaW5lc3NIb3VycyhjYWxlbmRhckNvbnRleHQub3B0aW9ucy5idXNpbmVzc0hvdXJzLCBjYWxlbmRhckNvbnRleHQpO1xufVxuZnVuY3Rpb24gd2FyblVua25vd25PcHRpb25zKG9wdGlvbnMsIHZpZXdOYW1lKSB7XG4gICAgZm9yIChsZXQgb3B0aW9uTmFtZSBpbiBvcHRpb25zKSB7XG4gICAgICAgIGNvbnNvbGUud2FybihgVW5rbm93biBvcHRpb24gJyR7b3B0aW9uTmFtZX0nYCArXG4gICAgICAgICAgICAodmlld05hbWUgPyBgIGZvciB2aWV3ICcke3ZpZXdOYW1lfSdgIDogJycpKTtcbiAgICB9XG59XG5cbmNsYXNzIFRvb2xiYXJTZWN0aW9uIGV4dGVuZHMgQmFzZUNvbXBvbmVudCB7XG4gICAgcmVuZGVyKCkge1xuICAgICAgICBsZXQgY2hpbGRyZW4gPSB0aGlzLnByb3BzLndpZGdldEdyb3Vwcy5tYXAoKHdpZGdldEdyb3VwKSA9PiB0aGlzLnJlbmRlcldpZGdldEdyb3VwKHdpZGdldEdyb3VwKSk7XG4gICAgICAgIHJldHVybiBjcmVhdGVFbGVtZW50KCdkaXYnLCB7IGNsYXNzTmFtZTogJ2ZjLXRvb2xiYXItY2h1bmsnIH0sIC4uLmNoaWxkcmVuKTtcbiAgICB9XG4gICAgcmVuZGVyV2lkZ2V0R3JvdXAod2lkZ2V0R3JvdXApIHtcbiAgICAgICAgbGV0IHsgcHJvcHMgfSA9IHRoaXM7XG4gICAgICAgIGxldCB7IHRoZW1lIH0gPSB0aGlzLmNvbnRleHQ7XG4gICAgICAgIGxldCBjaGlsZHJlbiA9IFtdO1xuICAgICAgICBsZXQgaXNPbmx5QnV0dG9ucyA9IHRydWU7XG4gICAgICAgIGZvciAobGV0IHdpZGdldCBvZiB3aWRnZXRHcm91cCkge1xuICAgICAgICAgICAgbGV0IHsgYnV0dG9uTmFtZSwgYnV0dG9uQ2xpY2ssIGJ1dHRvblRleHQsIGJ1dHRvbkljb24sIGJ1dHRvbkhpbnQgfSA9IHdpZGdldDtcbiAgICAgICAgICAgIGlmIChidXR0b25OYW1lID09PSAndGl0bGUnKSB7XG4gICAgICAgICAgICAgICAgaXNPbmx5QnV0dG9ucyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIGNoaWxkcmVuLnB1c2goY3JlYXRlRWxlbWVudChcImgyXCIsIHsgY2xhc3NOYW1lOiBcImZjLXRvb2xiYXItdGl0bGVcIiwgaWQ6IHByb3BzLnRpdGxlSWQgfSwgcHJvcHMudGl0bGUpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGxldCBpc1ByZXNzZWQgPSBidXR0b25OYW1lID09PSBwcm9wcy5hY3RpdmVCdXR0b247XG4gICAgICAgICAgICAgICAgbGV0IGlzRGlzYWJsZWQgPSAoIXByb3BzLmlzVG9kYXlFbmFibGVkICYmIGJ1dHRvbk5hbWUgPT09ICd0b2RheScpIHx8XG4gICAgICAgICAgICAgICAgICAgICghcHJvcHMuaXNQcmV2RW5hYmxlZCAmJiBidXR0b25OYW1lID09PSAncHJldicpIHx8XG4gICAgICAgICAgICAgICAgICAgICghcHJvcHMuaXNOZXh0RW5hYmxlZCAmJiBidXR0b25OYW1lID09PSAnbmV4dCcpO1xuICAgICAgICAgICAgICAgIGxldCBidXR0b25DbGFzc2VzID0gW2BmYy0ke2J1dHRvbk5hbWV9LWJ1dHRvbmAsIHRoZW1lLmdldENsYXNzKCdidXR0b24nKV07XG4gICAgICAgICAgICAgICAgaWYgKGlzUHJlc3NlZCkge1xuICAgICAgICAgICAgICAgICAgICBidXR0b25DbGFzc2VzLnB1c2godGhlbWUuZ2V0Q2xhc3MoJ2J1dHRvbkFjdGl2ZScpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2hpbGRyZW4ucHVzaChjcmVhdGVFbGVtZW50KFwiYnV0dG9uXCIsIHsgdHlwZTogXCJidXR0b25cIiwgdGl0bGU6IHR5cGVvZiBidXR0b25IaW50ID09PSAnZnVuY3Rpb24nID8gYnV0dG9uSGludChwcm9wcy5uYXZVbml0KSA6IGJ1dHRvbkhpbnQsIGRpc2FibGVkOiBpc0Rpc2FibGVkLCBcImFyaWEtcHJlc3NlZFwiOiBpc1ByZXNzZWQsIGNsYXNzTmFtZTogYnV0dG9uQ2xhc3Nlcy5qb2luKCcgJyksIG9uQ2xpY2s6IGJ1dHRvbkNsaWNrIH0sIGJ1dHRvblRleHQgfHwgKGJ1dHRvbkljb24gPyBjcmVhdGVFbGVtZW50KFwic3BhblwiLCB7IGNsYXNzTmFtZTogYnV0dG9uSWNvbiB9KSA6ICcnKSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChjaGlsZHJlbi5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICBsZXQgZ3JvdXBDbGFzc05hbWUgPSAoaXNPbmx5QnV0dG9ucyAmJiB0aGVtZS5nZXRDbGFzcygnYnV0dG9uR3JvdXAnKSkgfHwgJyc7XG4gICAgICAgICAgICByZXR1cm4gY3JlYXRlRWxlbWVudCgnZGl2JywgeyBjbGFzc05hbWU6IGdyb3VwQ2xhc3NOYW1lIH0sIC4uLmNoaWxkcmVuKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY2hpbGRyZW5bMF07XG4gICAgfVxufVxuXG5jbGFzcyBUb29sYmFyIGV4dGVuZHMgQmFzZUNvbXBvbmVudCB7XG4gICAgcmVuZGVyKCkge1xuICAgICAgICBsZXQgeyBtb2RlbCwgZXh0cmFDbGFzc05hbWUgfSA9IHRoaXMucHJvcHM7XG4gICAgICAgIGxldCBmb3JjZUx0ciA9IGZhbHNlO1xuICAgICAgICBsZXQgc3RhcnRDb250ZW50O1xuICAgICAgICBsZXQgZW5kQ29udGVudDtcbiAgICAgICAgbGV0IHNlY3Rpb25XaWRnZXRzID0gbW9kZWwuc2VjdGlvbldpZGdldHM7XG4gICAgICAgIGxldCBjZW50ZXJDb250ZW50ID0gc2VjdGlvbldpZGdldHMuY2VudGVyO1xuICAgICAgICBpZiAoc2VjdGlvbldpZGdldHMubGVmdCkge1xuICAgICAgICAgICAgZm9yY2VMdHIgPSB0cnVlO1xuICAgICAgICAgICAgc3RhcnRDb250ZW50ID0gc2VjdGlvbldpZGdldHMubGVmdDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHN0YXJ0Q29udGVudCA9IHNlY3Rpb25XaWRnZXRzLnN0YXJ0O1xuICAgICAgICB9XG4gICAgICAgIGlmIChzZWN0aW9uV2lkZ2V0cy5yaWdodCkge1xuICAgICAgICAgICAgZm9yY2VMdHIgPSB0cnVlO1xuICAgICAgICAgICAgZW5kQ29udGVudCA9IHNlY3Rpb25XaWRnZXRzLnJpZ2h0O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZW5kQ29udGVudCA9IHNlY3Rpb25XaWRnZXRzLmVuZDtcbiAgICAgICAgfVxuICAgICAgICBsZXQgY2xhc3NOYW1lcyA9IFtcbiAgICAgICAgICAgIGV4dHJhQ2xhc3NOYW1lIHx8ICcnLFxuICAgICAgICAgICAgJ2ZjLXRvb2xiYXInLFxuICAgICAgICAgICAgZm9yY2VMdHIgPyAnZmMtdG9vbGJhci1sdHInIDogJycsXG4gICAgICAgIF07XG4gICAgICAgIHJldHVybiAoY3JlYXRlRWxlbWVudChcImRpdlwiLCB7IGNsYXNzTmFtZTogY2xhc3NOYW1lcy5qb2luKCcgJykgfSxcbiAgICAgICAgICAgIHRoaXMucmVuZGVyU2VjdGlvbignc3RhcnQnLCBzdGFydENvbnRlbnQgfHwgW10pLFxuICAgICAgICAgICAgdGhpcy5yZW5kZXJTZWN0aW9uKCdjZW50ZXInLCBjZW50ZXJDb250ZW50IHx8IFtdKSxcbiAgICAgICAgICAgIHRoaXMucmVuZGVyU2VjdGlvbignZW5kJywgZW5kQ29udGVudCB8fCBbXSkpKTtcbiAgICB9XG4gICAgcmVuZGVyU2VjdGlvbihrZXksIHdpZGdldEdyb3Vwcykge1xuICAgICAgICBsZXQgeyBwcm9wcyB9ID0gdGhpcztcbiAgICAgICAgcmV0dXJuIChjcmVhdGVFbGVtZW50KFRvb2xiYXJTZWN0aW9uLCB7IGtleToga2V5LCB3aWRnZXRHcm91cHM6IHdpZGdldEdyb3VwcywgdGl0bGU6IHByb3BzLnRpdGxlLCBuYXZVbml0OiBwcm9wcy5uYXZVbml0LCBhY3RpdmVCdXR0b246IHByb3BzLmFjdGl2ZUJ1dHRvbiwgaXNUb2RheUVuYWJsZWQ6IHByb3BzLmlzVG9kYXlFbmFibGVkLCBpc1ByZXZFbmFibGVkOiBwcm9wcy5pc1ByZXZFbmFibGVkLCBpc05leHRFbmFibGVkOiBwcm9wcy5pc05leHRFbmFibGVkLCB0aXRsZUlkOiBwcm9wcy50aXRsZUlkIH0pKTtcbiAgICB9XG59XG5cbi8vIFRPRE86IGRvIGZ1bmN0aW9uIGNvbXBvbmVudD9cbmNsYXNzIFZpZXdDb250YWluZXIgZXh0ZW5kcyBCYXNlQ29tcG9uZW50IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgICAgICAgIGF2YWlsYWJsZVdpZHRoOiBudWxsLFxuICAgICAgICB9O1xuICAgICAgICB0aGlzLmhhbmRsZUVsID0gKGVsKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmVsID0gZWw7XG4gICAgICAgICAgICBzZXRSZWYodGhpcy5wcm9wcy5lbFJlZiwgZWwpO1xuICAgICAgICAgICAgdGhpcy51cGRhdGVBdmFpbGFibGVXaWR0aCgpO1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLmhhbmRsZVJlc2l6ZSA9ICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlQXZhaWxhYmxlV2lkdGgoKTtcbiAgICAgICAgfTtcbiAgICB9XG4gICAgcmVuZGVyKCkge1xuICAgICAgICBsZXQgeyBwcm9wcywgc3RhdGUgfSA9IHRoaXM7XG4gICAgICAgIGxldCB7IGFzcGVjdFJhdGlvIH0gPSBwcm9wcztcbiAgICAgICAgbGV0IGNsYXNzTmFtZXMgPSBbXG4gICAgICAgICAgICAnZmMtdmlldy1oYXJuZXNzJyxcbiAgICAgICAgICAgIChhc3BlY3RSYXRpbyB8fCBwcm9wcy5saXF1aWQgfHwgcHJvcHMuaGVpZ2h0KVxuICAgICAgICAgICAgICAgID8gJ2ZjLXZpZXctaGFybmVzcy1hY3RpdmUnIC8vIGhhcm5lc3MgY29udHJvbHMgdGhlIGhlaWdodFxuICAgICAgICAgICAgICAgIDogJ2ZjLXZpZXctaGFybmVzcy1wYXNzaXZlJywgLy8gbGV0IHRoZSB2aWV3IGRvIHRoZSBoZWlnaHRcbiAgICAgICAgXTtcbiAgICAgICAgbGV0IGhlaWdodCA9ICcnO1xuICAgICAgICBsZXQgcGFkZGluZ0JvdHRvbSA9ICcnO1xuICAgICAgICBpZiAoYXNwZWN0UmF0aW8pIHtcbiAgICAgICAgICAgIGlmIChzdGF0ZS5hdmFpbGFibGVXaWR0aCAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGhlaWdodCA9IHN0YXRlLmF2YWlsYWJsZVdpZHRoIC8gYXNwZWN0UmF0aW87XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyB3aGlsZSB3YWl0aW5nIHRvIGtub3cgYXZhaWxhYmxlV2lkdGgsIHdlIGNhbid0IHNldCBoZWlnaHQgdG8gKnplcm8qXG4gICAgICAgICAgICAgICAgLy8gYmVjYXVzZSB3aWxsIGNhdXNlIGxvdHMgb2YgdW5uZWNlc3Nhcnkgc2Nyb2xsYmFycyB3aXRoaW4gc2Nyb2xsZ3JpZC5cbiAgICAgICAgICAgICAgICAvLyBCRVRURVI6IGRvbid0IHN0YXJ0IHJlbmRlcmluZyBBTllUSElORyB5ZXQgdW50aWwgd2Uga25vdyBjb250YWluZXIgd2lkdGhcbiAgICAgICAgICAgICAgICAvLyBOT1RFOiB3aHkgbm90IGFsd2F5cyB1c2UgcGFkZGluZ0JvdHRvbT8gQ2F1c2VzIGhlaWdodCBvc2NpbGxhdGlvbiAoaXNzdWUgNTYwNilcbiAgICAgICAgICAgICAgICBwYWRkaW5nQm90dG9tID0gYCR7KDEgLyBhc3BlY3RSYXRpbykgKiAxMDB9JWA7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBoZWlnaHQgPSBwcm9wcy5oZWlnaHQgfHwgJyc7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIChjcmVhdGVFbGVtZW50KFwiZGl2XCIsIHsgXCJhcmlhLWxhYmVsbGVkYnlcIjogcHJvcHMubGFiZWxlZEJ5SWQsIHJlZjogdGhpcy5oYW5kbGVFbCwgY2xhc3NOYW1lOiBjbGFzc05hbWVzLmpvaW4oJyAnKSwgc3R5bGU6IHsgaGVpZ2h0LCBwYWRkaW5nQm90dG9tIH0gfSwgcHJvcHMuY2hpbGRyZW4pKTtcbiAgICB9XG4gICAgY29tcG9uZW50RGlkTW91bnQoKSB7XG4gICAgICAgIHRoaXMuY29udGV4dC5hZGRSZXNpemVIYW5kbGVyKHRoaXMuaGFuZGxlUmVzaXplKTtcbiAgICB9XG4gICAgY29tcG9uZW50V2lsbFVubW91bnQoKSB7XG4gICAgICAgIHRoaXMuY29udGV4dC5yZW1vdmVSZXNpemVIYW5kbGVyKHRoaXMuaGFuZGxlUmVzaXplKTtcbiAgICB9XG4gICAgdXBkYXRlQXZhaWxhYmxlV2lkdGgoKSB7XG4gICAgICAgIGlmICh0aGlzLmVsICYmIC8vIG5lZWRlZC4gYnV0IHdoeT9cbiAgICAgICAgICAgIHRoaXMucHJvcHMuYXNwZWN0UmF0aW8gLy8gYXNwZWN0UmF0aW8gaXMgdGhlIG9ubHkgaGVpZ2h0IHNldHRpbmcgdGhhdCBuZWVkcyBhdmFpbGFibGVXaWR0aFxuICAgICAgICApIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBhdmFpbGFibGVXaWR0aDogdGhpcy5lbC5vZmZzZXRXaWR0aCB9KTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuLypcbkRldGVjdHMgd2hlbiB0aGUgdXNlciBjbGlja3Mgb24gYW4gZXZlbnQgd2l0aGluIGEgRGF0ZUNvbXBvbmVudFxuKi9cbmNsYXNzIEV2ZW50Q2xpY2tpbmcgZXh0ZW5kcyBJbnRlcmFjdGlvbiB7XG4gICAgY29uc3RydWN0b3Ioc2V0dGluZ3MpIHtcbiAgICAgICAgc3VwZXIoc2V0dGluZ3MpO1xuICAgICAgICB0aGlzLmhhbmRsZVNlZ0NsaWNrID0gKGV2LCBzZWdFbCkgPT4ge1xuICAgICAgICAgICAgbGV0IHsgY29tcG9uZW50IH0gPSB0aGlzO1xuICAgICAgICAgICAgbGV0IHsgY29udGV4dCB9ID0gY29tcG9uZW50O1xuICAgICAgICAgICAgbGV0IHNlZyA9IGdldEVsU2VnKHNlZ0VsKTtcbiAgICAgICAgICAgIGlmIChzZWcgJiYgLy8gbWlnaHQgYmUgdGhlIDxkaXY+IHN1cnJvdW5kaW5nIHRoZSBtb3JlIGxpbmtcbiAgICAgICAgICAgICAgICBjb21wb25lbnQuaXNWYWxpZFNlZ0Rvd25FbChldi50YXJnZXQpKSB7XG4gICAgICAgICAgICAgICAgLy8gb3VyIHdheSB0byBzaW11bGF0ZSBhIGxpbmsgY2xpY2sgZm9yIGVsZW1lbnRzIHRoYXQgY2FuJ3QgYmUgPGE+IHRhZ3NcbiAgICAgICAgICAgICAgICAvLyBncmFiIGJlZm9yZSB0cmlnZ2VyIGZpcmVkIGluIGNhc2UgdHJpZ2dlciB0cmFzaGVzIERPTSB0aHJ1IHJlcmVuZGVyaW5nXG4gICAgICAgICAgICAgICAgbGV0IGhhc1VybENvbnRhaW5lciA9IGVsZW1lbnRDbG9zZXN0KGV2LnRhcmdldCwgJy5mYy1ldmVudC1mb3JjZWQtdXJsJyk7XG4gICAgICAgICAgICAgICAgbGV0IHVybCA9IGhhc1VybENvbnRhaW5lciA/IGhhc1VybENvbnRhaW5lci5xdWVyeVNlbGVjdG9yKCdhW2hyZWZdJykuaHJlZiA6ICcnO1xuICAgICAgICAgICAgICAgIGNvbnRleHQuZW1pdHRlci50cmlnZ2VyKCdldmVudENsaWNrJywge1xuICAgICAgICAgICAgICAgICAgICBlbDogc2VnRWwsXG4gICAgICAgICAgICAgICAgICAgIGV2ZW50OiBuZXcgRXZlbnRJbXBsKGNvbXBvbmVudC5jb250ZXh0LCBzZWcuZXZlbnRSYW5nZS5kZWYsIHNlZy5ldmVudFJhbmdlLmluc3RhbmNlKSxcbiAgICAgICAgICAgICAgICAgICAganNFdmVudDogZXYsXG4gICAgICAgICAgICAgICAgICAgIHZpZXc6IGNvbnRleHQudmlld0FwaSxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBpZiAodXJsICYmICFldi5kZWZhdWx0UHJldmVudGVkKSB7XG4gICAgICAgICAgICAgICAgICAgIHdpbmRvdy5sb2NhdGlvbi5ocmVmID0gdXJsO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5kZXN0cm95ID0gbGlzdGVuQnlTZWxlY3RvcihzZXR0aW5ncy5lbCwgJ2NsaWNrJywgJy5mYy1ldmVudCcsIC8vIG9uIGJvdGggZmcgYW5kIGJnIGV2ZW50c1xuICAgICAgICB0aGlzLmhhbmRsZVNlZ0NsaWNrKTtcbiAgICB9XG59XG5cbi8qXG5UcmlnZ2VycyBldmVudHMgYW5kIGFkZHMvcmVtb3ZlcyBjb3JlIGNsYXNzTmFtZXMgd2hlbiB0aGUgdXNlcidzIHBvaW50ZXJcbmVudGVycy9sZWF2ZXMgZXZlbnQtZWxlbWVudHMgb2YgYSBjb21wb25lbnQuXG4qL1xuY2xhc3MgRXZlbnRIb3ZlcmluZyBleHRlbmRzIEludGVyYWN0aW9uIHtcbiAgICBjb25zdHJ1Y3RvcihzZXR0aW5ncykge1xuICAgICAgICBzdXBlcihzZXR0aW5ncyk7XG4gICAgICAgIC8vIGZvciBzaW11bGF0aW5nIGFuIGV2ZW50TW91c2VMZWF2ZSB3aGVuIHRoZSBldmVudCBlbCBpcyBkZXN0cm95ZWQgd2hpbGUgbW91c2UgaXMgb3ZlciBpdFxuICAgICAgICB0aGlzLmhhbmRsZUV2ZW50RWxSZW1vdmUgPSAoZWwpID0+IHtcbiAgICAgICAgICAgIGlmIChlbCA9PT0gdGhpcy5jdXJyZW50U2VnRWwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmhhbmRsZVNlZ0xlYXZlKG51bGwsIHRoaXMuY3VycmVudFNlZ0VsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5oYW5kbGVTZWdFbnRlciA9IChldiwgc2VnRWwpID0+IHtcbiAgICAgICAgICAgIGlmIChnZXRFbFNlZyhzZWdFbCkpIHsgLy8gVE9ETzogYmV0dGVyIHdheSB0byBtYWtlIHN1cmUgbm90IGhvdmVyaW5nIG92ZXIgbW9yZSsgbGluayBvciBpdHMgd3JhcHBlclxuICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudFNlZ0VsID0gc2VnRWw7XG4gICAgICAgICAgICAgICAgdGhpcy50cmlnZ2VyRXZlbnQoJ2V2ZW50TW91c2VFbnRlcicsIGV2LCBzZWdFbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuaGFuZGxlU2VnTGVhdmUgPSAoZXYsIHNlZ0VsKSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5jdXJyZW50U2VnRWwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRTZWdFbCA9IG51bGw7XG4gICAgICAgICAgICAgICAgdGhpcy50cmlnZ2VyRXZlbnQoJ2V2ZW50TW91c2VMZWF2ZScsIGV2LCBzZWdFbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMucmVtb3ZlSG92ZXJMaXN0ZW5lcnMgPSBsaXN0ZW5Ub0hvdmVyQnlTZWxlY3RvcihzZXR0aW5ncy5lbCwgJy5mYy1ldmVudCcsIC8vIG9uIGJvdGggZmcgYW5kIGJnIGV2ZW50c1xuICAgICAgICB0aGlzLmhhbmRsZVNlZ0VudGVyLCB0aGlzLmhhbmRsZVNlZ0xlYXZlKTtcbiAgICB9XG4gICAgZGVzdHJveSgpIHtcbiAgICAgICAgdGhpcy5yZW1vdmVIb3Zlckxpc3RlbmVycygpO1xuICAgIH1cbiAgICB0cmlnZ2VyRXZlbnQocHVibGljRXZOYW1lLCBldiwgc2VnRWwpIHtcbiAgICAgICAgbGV0IHsgY29tcG9uZW50IH0gPSB0aGlzO1xuICAgICAgICBsZXQgeyBjb250ZXh0IH0gPSBjb21wb25lbnQ7XG4gICAgICAgIGxldCBzZWcgPSBnZXRFbFNlZyhzZWdFbCk7XG4gICAgICAgIGlmICghZXYgfHwgY29tcG9uZW50LmlzVmFsaWRTZWdEb3duRWwoZXYudGFyZ2V0KSkge1xuICAgICAgICAgICAgY29udGV4dC5lbWl0dGVyLnRyaWdnZXIocHVibGljRXZOYW1lLCB7XG4gICAgICAgICAgICAgICAgZWw6IHNlZ0VsLFxuICAgICAgICAgICAgICAgIGV2ZW50OiBuZXcgRXZlbnRJbXBsKGNvbnRleHQsIHNlZy5ldmVudFJhbmdlLmRlZiwgc2VnLmV2ZW50UmFuZ2UuaW5zdGFuY2UpLFxuICAgICAgICAgICAgICAgIGpzRXZlbnQ6IGV2LFxuICAgICAgICAgICAgICAgIHZpZXc6IGNvbnRleHQudmlld0FwaSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5jbGFzcyBDYWxlbmRhckNvbnRlbnQgZXh0ZW5kcyBQdXJlQ29tcG9uZW50IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5idWlsZFZpZXdDb250ZXh0ID0gbWVtb2l6ZShidWlsZFZpZXdDb250ZXh0KTtcbiAgICAgICAgdGhpcy5idWlsZFZpZXdQcm9wVHJhbnNmb3JtZXJzID0gbWVtb2l6ZShidWlsZFZpZXdQcm9wVHJhbnNmb3JtZXJzKTtcbiAgICAgICAgdGhpcy5idWlsZFRvb2xiYXJQcm9wcyA9IG1lbW9pemUoYnVpbGRUb29sYmFyUHJvcHMpO1xuICAgICAgICB0aGlzLmhlYWRlclJlZiA9IGNyZWF0ZVJlZigpO1xuICAgICAgICB0aGlzLmZvb3RlclJlZiA9IGNyZWF0ZVJlZigpO1xuICAgICAgICB0aGlzLmludGVyYWN0aW9uc1N0b3JlID0ge307XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuICAgICAgICB0aGlzLnN0YXRlID0ge1xuICAgICAgICAgICAgdmlld0xhYmVsSWQ6IGdldFVuaXF1ZURvbUlkKCksXG4gICAgICAgIH07XG4gICAgICAgIC8vIENvbXBvbmVudCBSZWdpc3RyYXRpb25cbiAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgdGhpcy5yZWdpc3RlckludGVyYWN0aXZlQ29tcG9uZW50ID0gKGNvbXBvbmVudCwgc2V0dGluZ3NJbnB1dCkgPT4ge1xuICAgICAgICAgICAgbGV0IHNldHRpbmdzID0gcGFyc2VJbnRlcmFjdGlvblNldHRpbmdzKGNvbXBvbmVudCwgc2V0dGluZ3NJbnB1dCk7XG4gICAgICAgICAgICBsZXQgREVGQVVMVF9JTlRFUkFDVElPTlMgPSBbXG4gICAgICAgICAgICAgICAgRXZlbnRDbGlja2luZyxcbiAgICAgICAgICAgICAgICBFdmVudEhvdmVyaW5nLFxuICAgICAgICAgICAgXTtcbiAgICAgICAgICAgIGxldCBpbnRlcmFjdGlvbkNsYXNzZXMgPSBERUZBVUxUX0lOVEVSQUNUSU9OUy5jb25jYXQodGhpcy5wcm9wcy5wbHVnaW5Ib29rcy5jb21wb25lbnRJbnRlcmFjdGlvbnMpO1xuICAgICAgICAgICAgbGV0IGludGVyYWN0aW9ucyA9IGludGVyYWN0aW9uQ2xhc3Nlcy5tYXAoKFRoZUludGVyYWN0aW9uQ2xhc3MpID0+IG5ldyBUaGVJbnRlcmFjdGlvbkNsYXNzKHNldHRpbmdzKSk7XG4gICAgICAgICAgICB0aGlzLmludGVyYWN0aW9uc1N0b3JlW2NvbXBvbmVudC51aWRdID0gaW50ZXJhY3Rpb25zO1xuICAgICAgICAgICAgaW50ZXJhY3Rpb25TZXR0aW5nc1N0b3JlW2NvbXBvbmVudC51aWRdID0gc2V0dGluZ3M7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMudW5yZWdpc3RlckludGVyYWN0aXZlQ29tcG9uZW50ID0gKGNvbXBvbmVudCkgPT4ge1xuICAgICAgICAgICAgbGV0IGxpc3RlbmVycyA9IHRoaXMuaW50ZXJhY3Rpb25zU3RvcmVbY29tcG9uZW50LnVpZF07XG4gICAgICAgICAgICBpZiAobGlzdGVuZXJzKSB7XG4gICAgICAgICAgICAgICAgZm9yIChsZXQgbGlzdGVuZXIgb2YgbGlzdGVuZXJzKSB7XG4gICAgICAgICAgICAgICAgICAgIGxpc3RlbmVyLmRlc3Ryb3koKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuaW50ZXJhY3Rpb25zU3RvcmVbY29tcG9uZW50LnVpZF07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkZWxldGUgaW50ZXJhY3Rpb25TZXR0aW5nc1N0b3JlW2NvbXBvbmVudC51aWRdO1xuICAgICAgICB9O1xuICAgICAgICAvLyBSZXNpemluZ1xuICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICB0aGlzLnJlc2l6ZVJ1bm5lciA9IG5ldyBEZWxheWVkUnVubmVyKCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMucHJvcHMuZW1pdHRlci50cmlnZ2VyKCdfcmVzaXplJywgdHJ1ZSk7IC8vIHNob3VsZCB3aW5kb3cgcmVzaXplcyBiZSBjb25zaWRlcmVkIFwiZm9yY2VkXCIgP1xuICAgICAgICAgICAgdGhpcy5wcm9wcy5lbWl0dGVyLnRyaWdnZXIoJ3dpbmRvd1Jlc2l6ZScsIHsgdmlldzogdGhpcy5wcm9wcy52aWV3QXBpIH0pO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5oYW5kbGVXaW5kb3dSZXNpemUgPSAoZXYpID0+IHtcbiAgICAgICAgICAgIGxldCB7IG9wdGlvbnMgfSA9IHRoaXMucHJvcHM7XG4gICAgICAgICAgICBpZiAob3B0aW9ucy5oYW5kbGVXaW5kb3dSZXNpemUgJiZcbiAgICAgICAgICAgICAgICBldi50YXJnZXQgPT09IHdpbmRvdyAvLyBhdm9pZCBqcXVpIGV2ZW50c1xuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5yZXNpemVSdW5uZXIucmVxdWVzdChvcHRpb25zLndpbmRvd1Jlc2l6ZURlbGF5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9XG4gICAgLypcbiAgICByZW5kZXJzIElOU0lERSBvZiBhbiBvdXRlciBkaXZcbiAgICAqL1xuICAgIHJlbmRlcigpIHtcbiAgICAgICAgbGV0IHsgcHJvcHMgfSA9IHRoaXM7XG4gICAgICAgIGxldCB7IHRvb2xiYXJDb25maWcsIG9wdGlvbnMgfSA9IHByb3BzO1xuICAgICAgICBsZXQgdG9vbGJhclByb3BzID0gdGhpcy5idWlsZFRvb2xiYXJQcm9wcyhwcm9wcy52aWV3U3BlYywgcHJvcHMuZGF0ZVByb2ZpbGUsIHByb3BzLmRhdGVQcm9maWxlR2VuZXJhdG9yLCBwcm9wcy5jdXJyZW50RGF0ZSwgZ2V0Tm93KHByb3BzLm9wdGlvbnMubm93LCBwcm9wcy5kYXRlRW52KSwgLy8gVE9ETzogdXNlIE5vd1RpbWVyPz8/P1xuICAgICAgICBwcm9wcy52aWV3VGl0bGUpO1xuICAgICAgICBsZXQgdmlld1ZHcm93ID0gZmFsc2U7XG4gICAgICAgIGxldCB2aWV3SGVpZ2h0ID0gJyc7XG4gICAgICAgIGxldCB2aWV3QXNwZWN0UmF0aW87XG4gICAgICAgIGlmIChwcm9wcy5pc0hlaWdodEF1dG8gfHwgcHJvcHMuZm9yUHJpbnQpIHtcbiAgICAgICAgICAgIHZpZXdIZWlnaHQgPSAnJztcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChvcHRpb25zLmhlaWdodCAhPSBudWxsKSB7XG4gICAgICAgICAgICB2aWV3Vkdyb3cgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKG9wdGlvbnMuY29udGVudEhlaWdodCAhPSBudWxsKSB7XG4gICAgICAgICAgICB2aWV3SGVpZ2h0ID0gb3B0aW9ucy5jb250ZW50SGVpZ2h0O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdmlld0FzcGVjdFJhdGlvID0gTWF0aC5tYXgob3B0aW9ucy5hc3BlY3RSYXRpbywgMC41KTsgLy8gcHJldmVudCBmcm9tIGdldHRpbmcgdG9vIHRhbGxcbiAgICAgICAgfVxuICAgICAgICBsZXQgdmlld0NvbnRleHQgPSB0aGlzLmJ1aWxkVmlld0NvbnRleHQocHJvcHMudmlld1NwZWMsIHByb3BzLnZpZXdBcGksIHByb3BzLm9wdGlvbnMsIHByb3BzLmRhdGVQcm9maWxlR2VuZXJhdG9yLCBwcm9wcy5kYXRlRW52LCBwcm9wcy50aGVtZSwgcHJvcHMucGx1Z2luSG9va3MsIHByb3BzLmRpc3BhdGNoLCBwcm9wcy5nZXRDdXJyZW50RGF0YSwgcHJvcHMuZW1pdHRlciwgcHJvcHMuY2FsZW5kYXJBcGksIHRoaXMucmVnaXN0ZXJJbnRlcmFjdGl2ZUNvbXBvbmVudCwgdGhpcy51bnJlZ2lzdGVySW50ZXJhY3RpdmVDb21wb25lbnQpO1xuICAgICAgICBsZXQgdmlld0xhYmVsSWQgPSAodG9vbGJhckNvbmZpZy5oZWFkZXIgJiYgdG9vbGJhckNvbmZpZy5oZWFkZXIuaGFzVGl0bGUpXG4gICAgICAgICAgICA/IHRoaXMuc3RhdGUudmlld0xhYmVsSWRcbiAgICAgICAgICAgIDogJyc7XG4gICAgICAgIHJldHVybiAoY3JlYXRlRWxlbWVudChWaWV3Q29udGV4dFR5cGUuUHJvdmlkZXIsIHsgdmFsdWU6IHZpZXdDb250ZXh0IH0sXG4gICAgICAgICAgICB0b29sYmFyQ29uZmlnLmhlYWRlciAmJiAoY3JlYXRlRWxlbWVudChUb29sYmFyLCBPYmplY3QuYXNzaWduKHsgcmVmOiB0aGlzLmhlYWRlclJlZiwgZXh0cmFDbGFzc05hbWU6IFwiZmMtaGVhZGVyLXRvb2xiYXJcIiwgbW9kZWw6IHRvb2xiYXJDb25maWcuaGVhZGVyLCB0aXRsZUlkOiB2aWV3TGFiZWxJZCB9LCB0b29sYmFyUHJvcHMpKSksXG4gICAgICAgICAgICBjcmVhdGVFbGVtZW50KFZpZXdDb250YWluZXIsIHsgbGlxdWlkOiB2aWV3Vkdyb3csIGhlaWdodDogdmlld0hlaWdodCwgYXNwZWN0UmF0aW86IHZpZXdBc3BlY3RSYXRpbywgbGFiZWxlZEJ5SWQ6IHZpZXdMYWJlbElkIH0sXG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJWaWV3KHByb3BzKSxcbiAgICAgICAgICAgICAgICB0aGlzLmJ1aWxkQXBwZW5kQ29udGVudCgpKSxcbiAgICAgICAgICAgIHRvb2xiYXJDb25maWcuZm9vdGVyICYmIChjcmVhdGVFbGVtZW50KFRvb2xiYXIsIE9iamVjdC5hc3NpZ24oeyByZWY6IHRoaXMuZm9vdGVyUmVmLCBleHRyYUNsYXNzTmFtZTogXCJmYy1mb290ZXItdG9vbGJhclwiLCBtb2RlbDogdG9vbGJhckNvbmZpZy5mb290ZXIsIHRpdGxlSWQ6IFwiXCIgfSwgdG9vbGJhclByb3BzKSkpKSk7XG4gICAgfVxuICAgIGNvbXBvbmVudERpZE1vdW50KCkge1xuICAgICAgICBsZXQgeyBwcm9wcyB9ID0gdGhpcztcbiAgICAgICAgdGhpcy5jYWxlbmRhckludGVyYWN0aW9ucyA9IHByb3BzLnBsdWdpbkhvb2tzLmNhbGVuZGFySW50ZXJhY3Rpb25zXG4gICAgICAgICAgICAubWFwKChDYWxlbmRhckludGVyYWN0aW9uQ2xhc3MpID0+IG5ldyBDYWxlbmRhckludGVyYWN0aW9uQ2xhc3MocHJvcHMpKTtcbiAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsIHRoaXMuaGFuZGxlV2luZG93UmVzaXplKTtcbiAgICAgICAgbGV0IHsgcHJvcFNldEhhbmRsZXJzIH0gPSBwcm9wcy5wbHVnaW5Ib29rcztcbiAgICAgICAgZm9yIChsZXQgcHJvcE5hbWUgaW4gcHJvcFNldEhhbmRsZXJzKSB7XG4gICAgICAgICAgICBwcm9wU2V0SGFuZGxlcnNbcHJvcE5hbWVdKHByb3BzW3Byb3BOYW1lXSwgcHJvcHMpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGNvbXBvbmVudERpZFVwZGF0ZShwcmV2UHJvcHMpIHtcbiAgICAgICAgbGV0IHsgcHJvcHMgfSA9IHRoaXM7XG4gICAgICAgIGxldCB7IHByb3BTZXRIYW5kbGVycyB9ID0gcHJvcHMucGx1Z2luSG9va3M7XG4gICAgICAgIGZvciAobGV0IHByb3BOYW1lIGluIHByb3BTZXRIYW5kbGVycykge1xuICAgICAgICAgICAgaWYgKHByb3BzW3Byb3BOYW1lXSAhPT0gcHJldlByb3BzW3Byb3BOYW1lXSkge1xuICAgICAgICAgICAgICAgIHByb3BTZXRIYW5kbGVyc1twcm9wTmFtZV0ocHJvcHNbcHJvcE5hbWVdLCBwcm9wcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgY29tcG9uZW50V2lsbFVubW91bnQoKSB7XG4gICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdyZXNpemUnLCB0aGlzLmhhbmRsZVdpbmRvd1Jlc2l6ZSk7XG4gICAgICAgIHRoaXMucmVzaXplUnVubmVyLmNsZWFyKCk7XG4gICAgICAgIGZvciAobGV0IGludGVyYWN0aW9uIG9mIHRoaXMuY2FsZW5kYXJJbnRlcmFjdGlvbnMpIHtcbiAgICAgICAgICAgIGludGVyYWN0aW9uLmRlc3Ryb3koKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnByb3BzLmVtaXR0ZXIudHJpZ2dlcignX3VubW91bnQnKTtcbiAgICB9XG4gICAgYnVpbGRBcHBlbmRDb250ZW50KCkge1xuICAgICAgICBsZXQgeyBwcm9wcyB9ID0gdGhpcztcbiAgICAgICAgbGV0IGNoaWxkcmVuID0gcHJvcHMucGx1Z2luSG9va3Mudmlld0NvbnRhaW5lckFwcGVuZHMubWFwKChidWlsZEFwcGVuZENvbnRlbnQpID0+IGJ1aWxkQXBwZW5kQ29udGVudChwcm9wcykpO1xuICAgICAgICByZXR1cm4gY3JlYXRlRWxlbWVudChGcmFnbWVudCwge30sIC4uLmNoaWxkcmVuKTtcbiAgICB9XG4gICAgcmVuZGVyVmlldyhwcm9wcykge1xuICAgICAgICBsZXQgeyBwbHVnaW5Ib29rcyB9ID0gcHJvcHM7XG4gICAgICAgIGxldCB7IHZpZXdTcGVjIH0gPSBwcm9wcztcbiAgICAgICAgbGV0IHZpZXdQcm9wcyA9IHtcbiAgICAgICAgICAgIGRhdGVQcm9maWxlOiBwcm9wcy5kYXRlUHJvZmlsZSxcbiAgICAgICAgICAgIGJ1c2luZXNzSG91cnM6IHByb3BzLmJ1c2luZXNzSG91cnMsXG4gICAgICAgICAgICBldmVudFN0b3JlOiBwcm9wcy5yZW5kZXJhYmxlRXZlbnRTdG9yZSxcbiAgICAgICAgICAgIGV2ZW50VWlCYXNlczogcHJvcHMuZXZlbnRVaUJhc2VzLFxuICAgICAgICAgICAgZGF0ZVNlbGVjdGlvbjogcHJvcHMuZGF0ZVNlbGVjdGlvbixcbiAgICAgICAgICAgIGV2ZW50U2VsZWN0aW9uOiBwcm9wcy5ldmVudFNlbGVjdGlvbixcbiAgICAgICAgICAgIGV2ZW50RHJhZzogcHJvcHMuZXZlbnREcmFnLFxuICAgICAgICAgICAgZXZlbnRSZXNpemU6IHByb3BzLmV2ZW50UmVzaXplLFxuICAgICAgICAgICAgaXNIZWlnaHRBdXRvOiBwcm9wcy5pc0hlaWdodEF1dG8sXG4gICAgICAgICAgICBmb3JQcmludDogcHJvcHMuZm9yUHJpbnQsXG4gICAgICAgIH07XG4gICAgICAgIGxldCB0cmFuc2Zvcm1lcnMgPSB0aGlzLmJ1aWxkVmlld1Byb3BUcmFuc2Zvcm1lcnMocGx1Z2luSG9va3Mudmlld1Byb3BzVHJhbnNmb3JtZXJzKTtcbiAgICAgICAgZm9yIChsZXQgdHJhbnNmb3JtZXIgb2YgdHJhbnNmb3JtZXJzKSB7XG4gICAgICAgICAgICBPYmplY3QuYXNzaWduKHZpZXdQcm9wcywgdHJhbnNmb3JtZXIudHJhbnNmb3JtKHZpZXdQcm9wcywgcHJvcHMpKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgVmlld0NvbXBvbmVudCA9IHZpZXdTcGVjLmNvbXBvbmVudDtcbiAgICAgICAgcmV0dXJuIChjcmVhdGVFbGVtZW50KFZpZXdDb21wb25lbnQsIE9iamVjdC5hc3NpZ24oe30sIHZpZXdQcm9wcykpKTtcbiAgICB9XG59XG5mdW5jdGlvbiBidWlsZFRvb2xiYXJQcm9wcyh2aWV3U3BlYywgZGF0ZVByb2ZpbGUsIGRhdGVQcm9maWxlR2VuZXJhdG9yLCBjdXJyZW50RGF0ZSwgbm93LCB0aXRsZSkge1xuICAgIC8vIGRvbid0IGZvcmNlIGFueSBkYXRlLXByb2ZpbGVzIHRvIHZhbGlkIGRhdGUgcHJvZmlsZXMgKHRoZSBgZmFsc2VgKSBzbyB0aGF0IHdlIGNhbiB0ZWxsIGlmIGl0J3MgaW52YWxpZFxuICAgIGxldCB0b2RheUluZm8gPSBkYXRlUHJvZmlsZUdlbmVyYXRvci5idWlsZChub3csIHVuZGVmaW5lZCwgZmFsc2UpOyAvLyBUT0RPOiBuZWVkIGB1bmRlZmluZWRgIG9yIGVsc2UgSU5GSU5JVEUgTE9PUCBmb3Igc29tZSByZWFzb25cbiAgICBsZXQgcHJldkluZm8gPSBkYXRlUHJvZmlsZUdlbmVyYXRvci5idWlsZFByZXYoZGF0ZVByb2ZpbGUsIGN1cnJlbnREYXRlLCBmYWxzZSk7XG4gICAgbGV0IG5leHRJbmZvID0gZGF0ZVByb2ZpbGVHZW5lcmF0b3IuYnVpbGROZXh0KGRhdGVQcm9maWxlLCBjdXJyZW50RGF0ZSwgZmFsc2UpO1xuICAgIHJldHVybiB7XG4gICAgICAgIHRpdGxlLFxuICAgICAgICBhY3RpdmVCdXR0b246IHZpZXdTcGVjLnR5cGUsXG4gICAgICAgIG5hdlVuaXQ6IHZpZXdTcGVjLnNpbmdsZVVuaXQsXG4gICAgICAgIGlzVG9kYXlFbmFibGVkOiB0b2RheUluZm8uaXNWYWxpZCAmJiAhcmFuZ2VDb250YWluc01hcmtlcihkYXRlUHJvZmlsZS5jdXJyZW50UmFuZ2UsIG5vdyksXG4gICAgICAgIGlzUHJldkVuYWJsZWQ6IHByZXZJbmZvLmlzVmFsaWQsXG4gICAgICAgIGlzTmV4dEVuYWJsZWQ6IG5leHRJbmZvLmlzVmFsaWQsXG4gICAgfTtcbn1cbi8vIFBsdWdpblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbmZ1bmN0aW9uIGJ1aWxkVmlld1Byb3BUcmFuc2Zvcm1lcnModGhlQ2xhc3Nlcykge1xuICAgIHJldHVybiB0aGVDbGFzc2VzLm1hcCgoVGhlQ2xhc3MpID0+IG5ldyBUaGVDbGFzcygpKTtcbn1cblxuY2xhc3MgQ2FsZW5kYXIgZXh0ZW5kcyBDYWxlbmRhckltcGwge1xuICAgIGNvbnN0cnVjdG9yKGVsLCBvcHRpb25PdmVycmlkZXMgPSB7fSkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICB0aGlzLmlzUmVuZGVyaW5nID0gZmFsc2U7XG4gICAgICAgIHRoaXMuaXNSZW5kZXJlZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLmN1cnJlbnRDbGFzc05hbWVzID0gW107XG4gICAgICAgIHRoaXMuY3VzdG9tQ29udGVudFJlbmRlcklkID0gMDtcbiAgICAgICAgdGhpcy5oYW5kbGVBY3Rpb24gPSAoYWN0aW9uKSA9PiB7XG4gICAgICAgICAgICAvLyBhY3Rpb25zIHdlIGtub3cgd2Ugd2FudCB0byByZW5kZXIgaW1tZWRpYXRlbHlcbiAgICAgICAgICAgIHN3aXRjaCAoYWN0aW9uLnR5cGUpIHtcbiAgICAgICAgICAgICAgICBjYXNlICdTRVRfRVZFTlRfRFJBRyc6XG4gICAgICAgICAgICAgICAgY2FzZSAnU0VUX0VWRU5UX1JFU0laRSc6XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyUnVubmVyLnRyeURyYWluKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuaGFuZGxlRGF0YSA9IChkYXRhKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnREYXRhID0gZGF0YTtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyUnVubmVyLnJlcXVlc3QoZGF0YS5jYWxlbmRhck9wdGlvbnMucmVyZW5kZXJEZWxheSk7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuaGFuZGxlUmVuZGVyUmVxdWVzdCA9ICgpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLmlzUmVuZGVyaW5nKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pc1JlbmRlcmVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBsZXQgeyBjdXJyZW50RGF0YSB9ID0gdGhpcztcbiAgICAgICAgICAgICAgICBmbHVzaFN5bmMoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZW5kZXIoY3JlYXRlRWxlbWVudChDYWxlbmRhclJvb3QsIHsgb3B0aW9uczogY3VycmVudERhdGEuY2FsZW5kYXJPcHRpb25zLCB0aGVtZTogY3VycmVudERhdGEudGhlbWUsIGVtaXR0ZXI6IGN1cnJlbnREYXRhLmVtaXR0ZXIgfSwgKGNsYXNzTmFtZXMsIGhlaWdodCwgaXNIZWlnaHRBdXRvLCBmb3JQcmludCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRDbGFzc05hbWVzKGNsYXNzTmFtZXMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRIZWlnaHQoaGVpZ2h0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoY3JlYXRlRWxlbWVudChSZW5kZXJJZC5Qcm92aWRlciwgeyB2YWx1ZTogdGhpcy5jdXN0b21Db250ZW50UmVuZGVySWQgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjcmVhdGVFbGVtZW50KENhbGVuZGFyQ29udGVudCwgT2JqZWN0LmFzc2lnbih7IGlzSGVpZ2h0QXV0bzogaXNIZWlnaHRBdXRvLCBmb3JQcmludDogZm9yUHJpbnQgfSwgY3VycmVudERhdGEpKSkpO1xuICAgICAgICAgICAgICAgICAgICB9KSwgdGhpcy5lbCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICh0aGlzLmlzUmVuZGVyZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmlzUmVuZGVyZWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICByZW5kZXIobnVsbCwgdGhpcy5lbCk7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRDbGFzc05hbWVzKFtdKTtcbiAgICAgICAgICAgICAgICB0aGlzLnNldEhlaWdodCgnJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuZWwgPSBlbDtcbiAgICAgICAgdGhpcy5yZW5kZXJSdW5uZXIgPSBuZXcgRGVsYXllZFJ1bm5lcih0aGlzLmhhbmRsZVJlbmRlclJlcXVlc3QpO1xuICAgICAgICBuZXcgQ2FsZW5kYXJEYXRhTWFuYWdlcih7XG4gICAgICAgICAgICBvcHRpb25PdmVycmlkZXMsXG4gICAgICAgICAgICBjYWxlbmRhckFwaTogdGhpcyxcbiAgICAgICAgICAgIG9uQWN0aW9uOiB0aGlzLmhhbmRsZUFjdGlvbixcbiAgICAgICAgICAgIG9uRGF0YTogdGhpcy5oYW5kbGVEYXRhLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgcmVuZGVyKCkge1xuICAgICAgICBsZXQgd2FzUmVuZGVyaW5nID0gdGhpcy5pc1JlbmRlcmluZztcbiAgICAgICAgaWYgKCF3YXNSZW5kZXJpbmcpIHtcbiAgICAgICAgICAgIHRoaXMuaXNSZW5kZXJpbmcgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5jdXN0b21Db250ZW50UmVuZGVySWQgKz0gMTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnJlbmRlclJ1bm5lci5yZXF1ZXN0KCk7XG4gICAgICAgIGlmICh3YXNSZW5kZXJpbmcpIHtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlU2l6ZSgpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGRlc3Ryb3koKSB7XG4gICAgICAgIGlmICh0aGlzLmlzUmVuZGVyaW5nKSB7XG4gICAgICAgICAgICB0aGlzLmlzUmVuZGVyaW5nID0gZmFsc2U7XG4gICAgICAgICAgICB0aGlzLnJlbmRlclJ1bm5lci5yZXF1ZXN0KCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgdXBkYXRlU2l6ZSgpIHtcbiAgICAgICAgZmx1c2hTeW5jKCgpID0+IHtcbiAgICAgICAgICAgIHN1cGVyLnVwZGF0ZVNpemUoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGJhdGNoUmVuZGVyaW5nKGZ1bmMpIHtcbiAgICAgICAgdGhpcy5yZW5kZXJSdW5uZXIucGF1c2UoJ2JhdGNoUmVuZGVyaW5nJyk7XG4gICAgICAgIGZ1bmMoKTtcbiAgICAgICAgdGhpcy5yZW5kZXJSdW5uZXIucmVzdW1lKCdiYXRjaFJlbmRlcmluZycpO1xuICAgIH1cbiAgICBwYXVzZVJlbmRlcmluZygpIHtcbiAgICAgICAgdGhpcy5yZW5kZXJSdW5uZXIucGF1c2UoJ3BhdXNlUmVuZGVyaW5nJyk7XG4gICAgfVxuICAgIHJlc3VtZVJlbmRlcmluZygpIHtcbiAgICAgICAgdGhpcy5yZW5kZXJSdW5uZXIucmVzdW1lKCdwYXVzZVJlbmRlcmluZycsIHRydWUpO1xuICAgIH1cbiAgICByZXNldE9wdGlvbnMob3B0aW9uT3ZlcnJpZGVzLCBhcHBlbmQpIHtcbiAgICAgICAgdGhpcy5jdXJyZW50RGF0YU1hbmFnZXIucmVzZXRPcHRpb25zKG9wdGlvbk92ZXJyaWRlcywgYXBwZW5kKTtcbiAgICB9XG4gICAgc2V0Q2xhc3NOYW1lcyhjbGFzc05hbWVzKSB7XG4gICAgICAgIGlmICghaXNBcnJheXNFcXVhbChjbGFzc05hbWVzLCB0aGlzLmN1cnJlbnRDbGFzc05hbWVzKSkge1xuICAgICAgICAgICAgbGV0IHsgY2xhc3NMaXN0IH0gPSB0aGlzLmVsO1xuICAgICAgICAgICAgZm9yIChsZXQgY2xhc3NOYW1lIG9mIHRoaXMuY3VycmVudENsYXNzTmFtZXMpIHtcbiAgICAgICAgICAgICAgICBjbGFzc0xpc3QucmVtb3ZlKGNsYXNzTmFtZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmb3IgKGxldCBjbGFzc05hbWUgb2YgY2xhc3NOYW1lcykge1xuICAgICAgICAgICAgICAgIGNsYXNzTGlzdC5hZGQoY2xhc3NOYW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuY3VycmVudENsYXNzTmFtZXMgPSBjbGFzc05hbWVzO1xuICAgICAgICB9XG4gICAgfVxuICAgIHNldEhlaWdodChoZWlnaHQpIHtcbiAgICAgICAgYXBwbHlTdHlsZVByb3AodGhpcy5lbCwgJ2hlaWdodCcsIGhlaWdodCk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBmb3JtYXREYXRlKGRhdGVJbnB1dCwgb3B0aW9ucyA9IHt9KSB7XG4gICAgbGV0IGRhdGVFbnYgPSBidWlsZERhdGVFbnYob3B0aW9ucyk7XG4gICAgbGV0IGZvcm1hdHRlciA9IGNyZWF0ZUZvcm1hdHRlcihvcHRpb25zKTtcbiAgICBsZXQgZGF0ZU1ldGEgPSBkYXRlRW52LmNyZWF0ZU1hcmtlck1ldGEoZGF0ZUlucHV0KTtcbiAgICBpZiAoIWRhdGVNZXRhKSB7IC8vIFRPRE86IHdhcm5pbmc/XG4gICAgICAgIHJldHVybiAnJztcbiAgICB9XG4gICAgcmV0dXJuIGRhdGVFbnYuZm9ybWF0KGRhdGVNZXRhLm1hcmtlciwgZm9ybWF0dGVyLCB7XG4gICAgICAgIGZvcmNlZFR6bzogZGF0ZU1ldGEuZm9yY2VkVHpvLFxuICAgIH0pO1xufVxuZnVuY3Rpb24gZm9ybWF0UmFuZ2Uoc3RhcnRJbnB1dCwgZW5kSW5wdXQsIG9wdGlvbnMpIHtcbiAgICBsZXQgZGF0ZUVudiA9IGJ1aWxkRGF0ZUVudih0eXBlb2Ygb3B0aW9ucyA9PT0gJ29iamVjdCcgJiYgb3B0aW9ucyA/IG9wdGlvbnMgOiB7fSk7IC8vIHBhc3MgaW4gaWYgbm9uLW51bGwgb2JqZWN0XG4gICAgbGV0IGZvcm1hdHRlciA9IGNyZWF0ZUZvcm1hdHRlcihvcHRpb25zKTtcbiAgICBsZXQgc3RhcnRNZXRhID0gZGF0ZUVudi5jcmVhdGVNYXJrZXJNZXRhKHN0YXJ0SW5wdXQpO1xuICAgIGxldCBlbmRNZXRhID0gZGF0ZUVudi5jcmVhdGVNYXJrZXJNZXRhKGVuZElucHV0KTtcbiAgICBpZiAoIXN0YXJ0TWV0YSB8fCAhZW5kTWV0YSkgeyAvLyBUT0RPOiB3YXJuaW5nP1xuICAgICAgICByZXR1cm4gJyc7XG4gICAgfVxuICAgIHJldHVybiBkYXRlRW52LmZvcm1hdFJhbmdlKHN0YXJ0TWV0YS5tYXJrZXIsIGVuZE1ldGEubWFya2VyLCBmb3JtYXR0ZXIsIHtcbiAgICAgICAgZm9yY2VkU3RhcnRUem86IHN0YXJ0TWV0YS5mb3JjZWRUem8sXG4gICAgICAgIGZvcmNlZEVuZFR6bzogZW5kTWV0YS5mb3JjZWRUem8sXG4gICAgICAgIGlzRW5kRXhjbHVzaXZlOiBvcHRpb25zLmlzRW5kRXhjbHVzaXZlLFxuICAgICAgICBkZWZhdWx0U2VwYXJhdG9yOiBCQVNFX09QVElPTl9ERUZBVUxUUy5kZWZhdWx0UmFuZ2VTZXBhcmF0b3IsXG4gICAgfSk7XG59XG4vLyBUT0RPOiBtb3JlIERSWSBhbmQgb3B0aW1pemVkXG5mdW5jdGlvbiBidWlsZERhdGVFbnYoc2V0dGluZ3MpIHtcbiAgICBsZXQgbG9jYWxlID0gYnVpbGRMb2NhbGUoc2V0dGluZ3MubG9jYWxlIHx8ICdlbicsIG9yZ2FuaXplUmF3TG9jYWxlcyhbXSkubWFwKTsgLy8gVE9ETzogZG9uJ3QgaGFyZGNvZGUgJ2VuJyBldmVyeXdoZXJlXG4gICAgcmV0dXJuIG5ldyBEYXRlRW52KE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7IHRpbWVab25lOiBCQVNFX09QVElPTl9ERUZBVUxUUy50aW1lWm9uZSwgY2FsZW5kYXJTeXN0ZW06ICdncmVnb3J5JyB9LCBzZXR0aW5ncyksIHsgbG9jYWxlIH0pKTtcbn1cblxuLy8gSEVMUEVSU1xuLypcbmlmIG5leHREYXlUaHJlc2hvbGQgaXMgc3BlY2lmaWVkLCBzbGljaW5nIGlzIGRvbmUgaW4gYW4gYWxsLWRheSBmYXNoaW9uLlxueW91IGNhbiBnZXQgbmV4dERheVRocmVzaG9sZCBmcm9tIGNvbnRleHQubmV4dERheVRocmVzaG9sZFxuKi9cbmZ1bmN0aW9uIHNsaWNlRXZlbnRzKHByb3BzLCBhbGxEYXkpIHtcbiAgICByZXR1cm4gc2xpY2VFdmVudFN0b3JlKHByb3BzLmV2ZW50U3RvcmUsIHByb3BzLmV2ZW50VWlCYXNlcywgcHJvcHMuZGF0ZVByb2ZpbGUuYWN0aXZlUmFuZ2UsIGFsbERheSA/IHByb3BzLm5leHREYXlUaHJlc2hvbGQgOiBudWxsKS5mZztcbn1cblxuY29uc3QgdmVyc2lvbiA9ICc2LjAuMyc7XG5cbmV4cG9ydCB7IENhbGVuZGFyLCBjcmVhdGVQbHVnaW4sIGZvcm1hdERhdGUsIGZvcm1hdFJhbmdlLCBnbG9iYWxMb2NhbGVzLCBnbG9iYWxQbHVnaW5zLCBzbGljZUV2ZW50cywgdmVyc2lvbiB9O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/@fullcalendar/core/index.esm.js\n"); /***/ }), /***/ "./node_modules/@fullcalendar/core/internal-common.esm.js": /*!****************************************************************!*\ !*** ./node_modules/@fullcalendar/core/internal-common.esm.js ***! \****************************************************************/ /***/ (function(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) { eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"$\": function() { return /* binding */ getElSeg; },\n/* harmony export */ \"A\": function() { return /* binding */ memoizeObjArg; },\n/* harmony export */ \"B\": function() { return /* binding */ BASE_OPTION_DEFAULTS; },\n/* harmony export */ \"C\": function() { return /* binding */ ContentContainer; },\n/* harmony export */ \"D\": function() { return /* binding */ DelayedRunner; },\n/* harmony export */ \"E\": function() { return /* binding */ isPropsEqual; },\n/* harmony export */ \"F\": function() { return /* binding */ Emitter; },\n/* harmony export */ \"G\": function() { return /* binding */ getInitialDate; },\n/* harmony export */ \"H\": function() { return /* binding */ rangeContainsMarker; },\n/* harmony export */ \"I\": function() { return /* binding */ createEmptyEventStore; },\n/* harmony export */ \"J\": function() { return /* binding */ reduceCurrentDate; },\n/* harmony export */ \"K\": function() { return /* binding */ reduceEventStore; },\n/* harmony export */ \"L\": function() { return /* binding */ rezoneEventStoreDates; },\n/* harmony export */ \"M\": function() { return /* binding */ mergeRawOptions; },\n/* harmony export */ \"N\": function() { return /* binding */ BASE_OPTION_REFINERS; },\n/* harmony export */ \"O\": function() { return /* binding */ CALENDAR_LISTENER_REFINERS; },\n/* harmony export */ \"P\": function() { return /* binding */ CALENDAR_OPTION_REFINERS; },\n/* harmony export */ \"Q\": function() { return /* binding */ COMPLEX_OPTION_COMPARATORS; },\n/* harmony export */ \"R\": function() { return /* binding */ VIEW_OPTION_REFINERS; },\n/* harmony export */ \"S\": function() { return /* binding */ DateEnv; },\n/* harmony export */ \"T\": function() { return /* binding */ Theme; },\n/* harmony export */ \"U\": function() { return /* binding */ DateProfileGenerator; },\n/* harmony export */ \"V\": function() { return /* binding */ ViewContextType; },\n/* harmony export */ \"W\": function() { return /* binding */ createEventUi; },\n/* harmony export */ \"X\": function() { return /* binding */ parseBusinessHours; },\n/* harmony export */ \"Y\": function() { return /* binding */ BaseComponent; },\n/* harmony export */ \"Z\": function() { return /* binding */ setRef; },\n/* harmony export */ \"_\": function() { return /* binding */ Interaction; },\n/* harmony export */ \"a\": function() { return /* binding */ isArraysEqual; },\n/* harmony export */ \"a$\": function() { return /* binding */ getDateMeta; },\n/* harmony export */ \"a0\": function() { return /* binding */ elementClosest; },\n/* harmony export */ \"a1\": function() { return /* binding */ EventImpl; },\n/* harmony export */ \"a2\": function() { return /* binding */ listenBySelector; },\n/* harmony export */ \"a3\": function() { return /* binding */ listenToHoverBySelector; },\n/* harmony export */ \"a4\": function() { return /* binding */ PureComponent; },\n/* harmony export */ \"a5\": function() { return /* binding */ buildViewContext; },\n/* harmony export */ \"a6\": function() { return /* binding */ getUniqueDomId; },\n/* harmony export */ \"a7\": function() { return /* binding */ parseInteractionSettings; },\n/* harmony export */ \"a8\": function() { return /* binding */ interactionSettingsStore; },\n/* harmony export */ \"a9\": function() { return /* binding */ getNow; },\n/* harmony export */ \"aA\": function() { return /* binding */ diffDates; },\n/* harmony export */ \"aB\": function() { return /* binding */ removeExact; },\n/* harmony export */ \"aC\": function() { return /* binding */ memoizeArraylike; },\n/* harmony export */ \"aD\": function() { return /* binding */ memoizeHashlike; },\n/* harmony export */ \"aE\": function() { return /* binding */ intersectRects; },\n/* harmony export */ \"aF\": function() { return /* binding */ pointInsideRect; },\n/* harmony export */ \"aG\": function() { return /* binding */ constrainPoint; },\n/* harmony export */ \"aH\": function() { return /* binding */ getRectCenter; },\n/* harmony export */ \"aI\": function() { return /* binding */ diffPoints; },\n/* harmony export */ \"aJ\": function() { return /* binding */ translateRect; },\n/* harmony export */ \"aK\": function() { return /* binding */ compareObjs; },\n/* harmony export */ \"aL\": function() { return /* binding */ collectFromHash; },\n/* harmony export */ \"aM\": function() { return /* binding */ findElements; },\n/* harmony export */ \"aN\": function() { return /* binding */ findDirectChildren; },\n/* harmony export */ \"aO\": function() { return /* binding */ removeElement; },\n/* harmony export */ \"aP\": function() { return /* binding */ applyStyle; },\n/* harmony export */ \"aQ\": function() { return /* binding */ elementMatches; },\n/* harmony export */ \"aR\": function() { return /* binding */ getElRoot; },\n/* harmony export */ \"aS\": function() { return /* binding */ getEventTargetViaRoot; },\n/* harmony export */ \"aT\": function() { return /* binding */ parseClassNames; },\n/* harmony export */ \"aU\": function() { return /* binding */ getCanVGrowWithinCell; },\n/* harmony export */ \"aV\": function() { return /* binding */ mergeEventStores; },\n/* harmony export */ \"aW\": function() { return /* binding */ getRelevantEvents; },\n/* harmony export */ \"aX\": function() { return /* binding */ eventTupleToStore; },\n/* harmony export */ \"aY\": function() { return /* binding */ combineEventUis; },\n/* harmony export */ \"aZ\": function() { return /* binding */ Splitter; },\n/* harmony export */ \"a_\": function() { return /* binding */ getDayClassNames; },\n/* harmony export */ \"aa\": function() { return /* binding */ CalendarImpl; },\n/* harmony export */ \"ab\": function() { return /* binding */ flushSync; },\n/* harmony export */ \"ac\": function() { return /* binding */ CalendarRoot; },\n/* harmony export */ \"ad\": function() { return /* binding */ RenderId; },\n/* harmony export */ \"ae\": function() { return /* binding */ applyStyleProp; },\n/* harmony export */ \"af\": function() { return /* binding */ sliceEventStore; },\n/* harmony export */ \"ag\": function() { return /* binding */ JsonRequestError; },\n/* harmony export */ \"ah\": function() { return /* binding */ createContext; },\n/* harmony export */ \"ai\": function() { return /* binding */ refineProps; },\n/* harmony export */ \"aj\": function() { return /* binding */ createEventInstance; },\n/* harmony export */ \"ak\": function() { return /* binding */ parseEventDef; },\n/* harmony export */ \"al\": function() { return /* binding */ refineEventDef; },\n/* harmony export */ \"am\": function() { return /* binding */ padStart; },\n/* harmony export */ \"an\": function() { return /* binding */ isInt; },\n/* harmony export */ \"ao\": function() { return /* binding */ parseFieldSpecs; },\n/* harmony export */ \"ap\": function() { return /* binding */ compareByFieldSpecs; },\n/* harmony export */ \"aq\": function() { return /* binding */ flexibleCompare; },\n/* harmony export */ \"ar\": function() { return /* binding */ preventSelection; },\n/* harmony export */ \"as\": function() { return /* binding */ allowSelection; },\n/* harmony export */ \"at\": function() { return /* binding */ preventContextMenu; },\n/* harmony export */ \"au\": function() { return /* binding */ allowContextMenu; },\n/* harmony export */ \"av\": function() { return /* binding */ compareNumbers; },\n/* harmony export */ \"aw\": function() { return /* binding */ enableCursor; },\n/* harmony export */ \"ax\": function() { return /* binding */ disableCursor; },\n/* harmony export */ \"ay\": function() { return /* binding */ computeVisibleDayRange; },\n/* harmony export */ \"az\": function() { return /* binding */ isMultiDayRange; },\n/* harmony export */ \"b\": function() { return /* binding */ mapHash; },\n/* harmony export */ \"b$\": function() { return /* binding */ SimpleScrollGrid; },\n/* harmony export */ \"b0\": function() { return /* binding */ getSlotClassNames; },\n/* harmony export */ \"b1\": function() { return /* binding */ buildNavLinkAttrs; },\n/* harmony export */ \"b2\": function() { return /* binding */ preventDefault; },\n/* harmony export */ \"b3\": function() { return /* binding */ whenTransitionDone; },\n/* harmony export */ \"b4\": function() { return /* binding */ computeInnerRect; },\n/* harmony export */ \"b5\": function() { return /* binding */ computeEdges; },\n/* harmony export */ \"b6\": function() { return /* binding */ getClippingParents; },\n/* harmony export */ \"b7\": function() { return /* binding */ computeRect; },\n/* harmony export */ \"b8\": function() { return /* binding */ rangesEqual; },\n/* harmony export */ \"b9\": function() { return /* binding */ rangesIntersect; },\n/* harmony export */ \"bA\": function() { return /* binding */ SegHierarchy; },\n/* harmony export */ \"bB\": function() { return /* binding */ buildEntryKey; },\n/* harmony export */ \"bC\": function() { return /* binding */ getEntrySpanEnd; },\n/* harmony export */ \"bD\": function() { return /* binding */ binarySearch; },\n/* harmony export */ \"bE\": function() { return /* binding */ groupIntersectingEntries; },\n/* harmony export */ \"bF\": function() { return /* binding */ intersectSpans; },\n/* harmony export */ \"bG\": function() { return /* binding */ interactionSettingsToStore; },\n/* harmony export */ \"bH\": function() { return /* binding */ ElementDragging; },\n/* harmony export */ \"bI\": function() { return /* binding */ config; },\n/* harmony export */ \"bJ\": function() { return /* binding */ parseDragMeta; },\n/* harmony export */ \"bK\": function() { return /* binding */ DayHeader; },\n/* harmony export */ \"bL\": function() { return /* binding */ computeFallbackHeaderFormat; },\n/* harmony export */ \"bM\": function() { return /* binding */ TableDateCell; },\n/* harmony export */ \"bN\": function() { return /* binding */ TableDowCell; },\n/* harmony export */ \"bO\": function() { return /* binding */ DaySeriesModel; },\n/* harmony export */ \"bP\": function() { return /* binding */ hasBgRendering; },\n/* harmony export */ \"bQ\": function() { return /* binding */ buildSegTimeText; },\n/* harmony export */ \"bR\": function() { return /* binding */ sortEventSegs; },\n/* harmony export */ \"bS\": function() { return /* binding */ getSegMeta; },\n/* harmony export */ \"bT\": function() { return /* binding */ buildEventRangeKey; },\n/* harmony export */ \"bU\": function() { return /* binding */ getSegAnchorAttrs; },\n/* harmony export */ \"bV\": function() { return /* binding */ DayTableModel; },\n/* harmony export */ \"bW\": function() { return /* binding */ Slicer; },\n/* harmony export */ \"bX\": function() { return /* binding */ applyMutationToEventStore; },\n/* harmony export */ \"bY\": function() { return /* binding */ isPropsValid; },\n/* harmony export */ \"bZ\": function() { return /* binding */ isInteractionValid; },\n/* harmony export */ \"b_\": function() { return /* binding */ isDateSelectionValid; },\n/* harmony export */ \"ba\": function() { return /* binding */ rangeContainsRange; },\n/* harmony export */ \"bb\": function() { return /* binding */ PositionCache; },\n/* harmony export */ \"bc\": function() { return /* binding */ ScrollController; },\n/* harmony export */ \"bd\": function() { return /* binding */ ElementScrollController; },\n/* harmony export */ \"be\": function() { return /* binding */ WindowScrollController; },\n/* harmony export */ \"bf\": function() { return /* binding */ DateComponent; },\n/* harmony export */ \"bg\": function() { return /* binding */ isDateSpansEqual; },\n/* harmony export */ \"bh\": function() { return /* binding */ addMs; },\n/* harmony export */ \"bi\": function() { return /* binding */ addWeeks; },\n/* harmony export */ \"bj\": function() { return /* binding */ diffWeeks; },\n/* harmony export */ \"bk\": function() { return /* binding */ diffWholeWeeks; },\n/* harmony export */ \"bl\": function() { return /* binding */ diffDayAndTime; },\n/* harmony export */ \"bm\": function() { return /* binding */ diffDays; },\n/* harmony export */ \"bn\": function() { return /* binding */ isValidDate; },\n/* harmony export */ \"bo\": function() { return /* binding */ asCleanDays; },\n/* harmony export */ \"bp\": function() { return /* binding */ multiplyDuration; },\n/* harmony export */ \"bq\": function() { return /* binding */ addDurations; },\n/* harmony export */ \"br\": function() { return /* binding */ asRoughMinutes; },\n/* harmony export */ \"bs\": function() { return /* binding */ asRoughSeconds; },\n/* harmony export */ \"bt\": function() { return /* binding */ asRoughMs; },\n/* harmony export */ \"bu\": function() { return /* binding */ wholeDivideDurations; },\n/* harmony export */ \"bv\": function() { return /* binding */ formatIsoTimeString; },\n/* harmony export */ \"bw\": function() { return /* binding */ formatDayString; },\n/* harmony export */ \"bx\": function() { return /* binding */ buildIsoString; },\n/* harmony export */ \"by\": function() { return /* binding */ NamedTimeZoneImpl; },\n/* harmony export */ \"bz\": function() { return /* binding */ parse; },\n/* harmony export */ \"c\": function() { return /* binding */ buildViewClassNames; },\n/* harmony export */ \"c0\": function() { return /* binding */ hasShrinkWidth; },\n/* harmony export */ \"c1\": function() { return /* binding */ renderMicroColGroup; },\n/* harmony export */ \"c2\": function() { return /* binding */ getScrollGridClassNames; },\n/* harmony export */ \"c3\": function() { return /* binding */ getSectionClassNames; },\n/* harmony export */ \"c4\": function() { return /* binding */ getSectionHasLiquidHeight; },\n/* harmony export */ \"c5\": function() { return /* binding */ getAllowYScrolling; },\n/* harmony export */ \"c6\": function() { return /* binding */ renderChunkContent; },\n/* harmony export */ \"c7\": function() { return /* binding */ computeShrinkWidth; },\n/* harmony export */ \"c8\": function() { return /* binding */ sanitizeShrinkWidth; },\n/* harmony export */ \"c9\": function() { return /* binding */ isColPropsEqual; },\n/* harmony export */ \"ca\": function() { return /* binding */ renderScrollShim; },\n/* harmony export */ \"cb\": function() { return /* binding */ getStickyFooterScrollbar; },\n/* harmony export */ \"cc\": function() { return /* binding */ getStickyHeaderDates; },\n/* harmony export */ \"cd\": function() { return /* binding */ Scroller; },\n/* harmony export */ \"ce\": function() { return /* binding */ getScrollbarWidths; },\n/* harmony export */ \"cf\": function() { return /* binding */ RefMap; },\n/* harmony export */ \"cg\": function() { return /* binding */ getIsRtlScrollbarOnLeft; },\n/* harmony export */ \"ch\": function() { return /* binding */ NowTimer; },\n/* harmony export */ \"ci\": function() { return /* binding */ ScrollResponder; },\n/* harmony export */ \"cj\": function() { return /* binding */ StandardEvent; },\n/* harmony export */ \"ck\": function() { return /* binding */ NowIndicatorContainer; },\n/* harmony export */ \"cl\": function() { return /* binding */ DayCellContainer; },\n/* harmony export */ \"cm\": function() { return /* binding */ hasCustomDayCellContent; },\n/* harmony export */ \"cn\": function() { return /* binding */ EventContainer; },\n/* harmony export */ \"co\": function() { return /* binding */ renderFill; },\n/* harmony export */ \"cp\": function() { return /* binding */ BgEvent; },\n/* harmony export */ \"cq\": function() { return /* binding */ WeekNumberContainer; },\n/* harmony export */ \"cr\": function() { return /* binding */ MoreLinkContainer; },\n/* harmony export */ \"cs\": function() { return /* binding */ computeEarliestSegStart; },\n/* harmony export */ \"ct\": function() { return /* binding */ ViewContainer; },\n/* harmony export */ \"cu\": function() { return /* binding */ triggerDateSelect; },\n/* harmony export */ \"cv\": function() { return /* binding */ getDefaultEventEnd; },\n/* harmony export */ \"cw\": function() { return /* binding */ buildElAttrs; },\n/* harmony export */ \"cx\": function() { return /* binding */ CustomRenderingStore; },\n/* harmony export */ \"d\": function() { return /* binding */ greatestDurationDenominator; },\n/* harmony export */ \"e\": function() { return /* binding */ createDuration; },\n/* harmony export */ \"f\": function() { return /* binding */ arrayToHash; },\n/* harmony export */ \"g\": function() { return /* binding */ guid; },\n/* harmony export */ \"h\": function() { return /* binding */ filterHash; },\n/* harmony export */ \"i\": function() { return /* binding */ injectStyles; },\n/* harmony export */ \"j\": function() { return /* binding */ buildEventSourceRefiners; },\n/* harmony export */ \"k\": function() { return /* binding */ formatWithOrdinals; },\n/* harmony export */ \"l\": function() { return /* binding */ buildRangeApiWithTimeZone; },\n/* harmony export */ \"m\": function() { return /* binding */ mergeProps; },\n/* harmony export */ \"n\": function() { return /* binding */ identity; },\n/* harmony export */ \"o\": function() { return /* binding */ intersectRanges; },\n/* harmony export */ \"p\": function() { return /* binding */ parseEventSource; },\n/* harmony export */ \"q\": function() { return /* binding */ startOfDay; },\n/* harmony export */ \"r\": function() { return /* binding */ requestJson; },\n/* harmony export */ \"s\": function() { return /* binding */ subtractDurations; },\n/* harmony export */ \"t\": function() { return /* binding */ addDays; },\n/* harmony export */ \"u\": function() { return /* binding */ unpromisify; },\n/* harmony export */ \"v\": function() { return /* binding */ hashValuesToArray; },\n/* harmony export */ \"w\": function() { return /* binding */ buildEventApis; },\n/* harmony export */ \"x\": function() { return /* binding */ createFormatter; },\n/* harmony export */ \"y\": function() { return /* binding */ diffWholeDays; },\n/* harmony export */ \"z\": function() { return /* binding */ memoize; }\n/* harmony export */ });\n/* harmony import */ var preact__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! preact */ \"./node_modules/preact/dist/preact.module.js\");\n/* harmony import */ var preact_compat__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! preact/compat */ \"./node_modules/preact/compat/dist/compat.module.js\");\n\n\n\n\nfunction removeElement(el) {\n if (el.parentNode) {\n el.parentNode.removeChild(el);\n }\n}\n// Querying\n// ----------------------------------------------------------------------------------------------------------------\nfunction elementClosest(el, selector) {\n if (el.closest) {\n return el.closest(selector);\n // really bad fallback for IE\n // from https://developer.mozilla.org/en-US/docs/Web/API/Element/closest\n }\n if (!document.documentElement.contains(el)) {\n return null;\n }\n do {\n if (elementMatches(el, selector)) {\n return el;\n }\n el = (el.parentElement || el.parentNode);\n } while (el !== null && el.nodeType === 1);\n return null;\n}\nfunction elementMatches(el, selector) {\n let method = el.matches || el.matchesSelector || el.msMatchesSelector;\n return method.call(el, selector);\n}\n// accepts multiple subject els\n// returns a real array. good for methods like forEach\n// TODO: accept the document\nfunction findElements(container, selector) {\n let containers = container instanceof HTMLElement ? [container] : container;\n let allMatches = [];\n for (let i = 0; i < containers.length; i += 1) {\n let matches = containers[i].querySelectorAll(selector);\n for (let j = 0; j < matches.length; j += 1) {\n allMatches.push(matches[j]);\n }\n }\n return allMatches;\n}\n// accepts multiple subject els\n// only queries direct child elements // TODO: rename to findDirectChildren!\nfunction findDirectChildren(parent, selector) {\n let parents = parent instanceof HTMLElement ? [parent] : parent;\n let allMatches = [];\n for (let i = 0; i < parents.length; i += 1) {\n let childNodes = parents[i].children; // only ever elements\n for (let j = 0; j < childNodes.length; j += 1) {\n let childNode = childNodes[j];\n if (!selector || elementMatches(childNode, selector)) {\n allMatches.push(childNode);\n }\n }\n }\n return allMatches;\n}\n// Style\n// ----------------------------------------------------------------------------------------------------------------\nconst PIXEL_PROP_RE = /(top|left|right|bottom|width|height)$/i;\nfunction applyStyle(el, props) {\n for (let propName in props) {\n applyStyleProp(el, propName, props[propName]);\n }\n}\nfunction applyStyleProp(el, name, val) {\n if (val == null) {\n el.style[name] = '';\n }\n else if (typeof val === 'number' && PIXEL_PROP_RE.test(name)) {\n el.style[name] = `${val}px`;\n }\n else {\n el.style[name] = val;\n }\n}\n// Event Handling\n// ----------------------------------------------------------------------------------------------------------------\n// if intercepting bubbled events at the document/window/body level,\n// and want to see originating element (the 'target'), use this util instead\n// of `ev.target` because it goes within web-component boundaries.\nfunction getEventTargetViaRoot(ev) {\n var _a, _b;\n return (_b = (_a = ev.composedPath) === null || _a === void 0 ? void 0 : _a.call(ev)[0]) !== null && _b !== void 0 ? _b : ev.target;\n}\n// Shadow DOM consuderations\n// ----------------------------------------------------------------------------------------------------------------\nfunction getElRoot(el) {\n return el.getRootNode ? el.getRootNode() : document;\n}\n// Unique ID for DOM attribute\nlet guid$1 = 0;\nfunction getUniqueDomId() {\n guid$1 += 1;\n return 'fc-dom-' + guid$1;\n}\n\n// Stops a mouse/touch event from doing it's native browser action\nfunction preventDefault(ev) {\n ev.preventDefault();\n}\n// Event Delegation\n// ----------------------------------------------------------------------------------------------------------------\nfunction buildDelegationHandler(selector, handler) {\n return (ev) => {\n let matchedChild = elementClosest(ev.target, selector);\n if (matchedChild) {\n handler.call(matchedChild, ev, matchedChild);\n }\n };\n}\nfunction listenBySelector(container, eventType, selector, handler) {\n let attachedHandler = buildDelegationHandler(selector, handler);\n container.addEventListener(eventType, attachedHandler);\n return () => {\n container.removeEventListener(eventType, attachedHandler);\n };\n}\nfunction listenToHoverBySelector(container, selector, onMouseEnter, onMouseLeave) {\n let currentMatchedChild;\n return listenBySelector(container, 'mouseover', selector, (mouseOverEv, matchedChild) => {\n if (matchedChild !== currentMatchedChild) {\n currentMatchedChild = matchedChild;\n onMouseEnter(mouseOverEv, matchedChild);\n let realOnMouseLeave = (mouseLeaveEv) => {\n currentMatchedChild = null;\n onMouseLeave(mouseLeaveEv, matchedChild);\n matchedChild.removeEventListener('mouseleave', realOnMouseLeave);\n };\n // listen to the next mouseleave, and then unattach\n matchedChild.addEventListener('mouseleave', realOnMouseLeave);\n }\n });\n}\n// Animation\n// ----------------------------------------------------------------------------------------------------------------\nconst transitionEventNames = [\n 'webkitTransitionEnd',\n 'otransitionend',\n 'oTransitionEnd',\n 'msTransitionEnd',\n 'transitionend',\n];\n// triggered only when the next single subsequent transition finishes\nfunction whenTransitionDone(el, callback) {\n let realCallback = (ev) => {\n callback(ev);\n transitionEventNames.forEach((eventName) => {\n el.removeEventListener(eventName, realCallback);\n });\n };\n transitionEventNames.forEach((eventName) => {\n el.addEventListener(eventName, realCallback); // cross-browser way to determine when the transition finishes\n });\n}\n// ARIA workarounds\n// ----------------------------------------------------------------------------------------------------------------\nfunction createAriaClickAttrs(handler) {\n return Object.assign({ onClick: handler }, createAriaKeyboardAttrs(handler));\n}\nfunction createAriaKeyboardAttrs(handler) {\n return {\n tabIndex: 0,\n onKeyDown(ev) {\n if (ev.key === 'Enter' || ev.key === ' ') {\n handler(ev);\n ev.preventDefault(); // if space, don't scroll down page\n }\n },\n };\n}\n\nlet guidNumber = 0;\nfunction guid() {\n guidNumber += 1;\n return String(guidNumber);\n}\n/* FullCalendar-specific DOM Utilities\n----------------------------------------------------------------------------------------------------------------------*/\n// Make the mouse cursor express that an event is not allowed in the current area\nfunction disableCursor() {\n document.body.classList.add('fc-not-allowed');\n}\n// Returns the mouse cursor to its original look\nfunction enableCursor() {\n document.body.classList.remove('fc-not-allowed');\n}\n/* Selection\n----------------------------------------------------------------------------------------------------------------------*/\nfunction preventSelection(el) {\n el.classList.add('fc-unselectable');\n el.addEventListener('selectstart', preventDefault);\n}\nfunction allowSelection(el) {\n el.classList.remove('fc-unselectable');\n el.removeEventListener('selectstart', preventDefault);\n}\n/* Context Menu\n----------------------------------------------------------------------------------------------------------------------*/\nfunction preventContextMenu(el) {\n el.addEventListener('contextmenu', preventDefault);\n}\nfunction allowContextMenu(el) {\n el.removeEventListener('contextmenu', preventDefault);\n}\nfunction parseFieldSpecs(input) {\n let specs = [];\n let tokens = [];\n let i;\n let token;\n if (typeof input === 'string') {\n tokens = input.split(/\\s*,\\s*/);\n }\n else if (typeof input === 'function') {\n tokens = [input];\n }\n else if (Array.isArray(input)) {\n tokens = input;\n }\n for (i = 0; i < tokens.length; i += 1) {\n token = tokens[i];\n if (typeof token === 'string') {\n specs.push(token.charAt(0) === '-' ?\n { field: token.substring(1), order: -1 } :\n { field: token, order: 1 });\n }\n else if (typeof token === 'function') {\n specs.push({ func: token });\n }\n }\n return specs;\n}\nfunction compareByFieldSpecs(obj0, obj1, fieldSpecs) {\n let i;\n let cmp;\n for (i = 0; i < fieldSpecs.length; i += 1) {\n cmp = compareByFieldSpec(obj0, obj1, fieldSpecs[i]);\n if (cmp) {\n return cmp;\n }\n }\n return 0;\n}\nfunction compareByFieldSpec(obj0, obj1, fieldSpec) {\n if (fieldSpec.func) {\n return fieldSpec.func(obj0, obj1);\n }\n return flexibleCompare(obj0[fieldSpec.field], obj1[fieldSpec.field])\n * (fieldSpec.order || 1);\n}\nfunction flexibleCompare(a, b) {\n if (!a && !b) {\n return 0;\n }\n if (b == null) {\n return -1;\n }\n if (a == null) {\n return 1;\n }\n if (typeof a === 'string' || typeof b === 'string') {\n return String(a).localeCompare(String(b));\n }\n return a - b;\n}\n/* String Utilities\n----------------------------------------------------------------------------------------------------------------------*/\nfunction padStart(val, len) {\n let s = String(val);\n return '000'.substr(0, len - s.length) + s;\n}\nfunction formatWithOrdinals(formatter, args, fallbackText) {\n if (typeof formatter === 'function') {\n return formatter(...args);\n }\n if (typeof formatter === 'string') { // non-blank string\n return args.reduce((str, arg, index) => (str.replace('$' + index, arg || '')), formatter);\n }\n return fallbackText;\n}\n/* Number Utilities\n----------------------------------------------------------------------------------------------------------------------*/\nfunction compareNumbers(a, b) {\n return a - b;\n}\nfunction isInt(n) {\n return n % 1 === 0;\n}\n/* FC-specific DOM dimension stuff\n----------------------------------------------------------------------------------------------------------------------*/\nfunction computeSmallestCellWidth(cellEl) {\n let allWidthEl = cellEl.querySelector('.fc-scrollgrid-shrink-frame');\n let contentWidthEl = cellEl.querySelector('.fc-scrollgrid-shrink-cushion');\n if (!allWidthEl) {\n throw new Error('needs fc-scrollgrid-shrink-frame className'); // TODO: use const\n }\n if (!contentWidthEl) {\n throw new Error('needs fc-scrollgrid-shrink-cushion className');\n }\n return cellEl.getBoundingClientRect().width - allWidthEl.getBoundingClientRect().width + // the cell padding+border\n contentWidthEl.getBoundingClientRect().width;\n}\n\nconst INTERNAL_UNITS = ['years', 'months', 'days', 'milliseconds'];\nconst PARSE_RE = /^(-?)(?:(\\d+)\\.)?(\\d+):(\\d\\d)(?::(\\d\\d)(?:\\.(\\d\\d\\d))?)?/;\n// Parsing and Creation\nfunction createDuration(input, unit) {\n if (typeof input === 'string') {\n return parseString(input);\n }\n if (typeof input === 'object' && input) { // non-null object\n return parseObject(input);\n }\n if (typeof input === 'number') {\n return parseObject({ [unit || 'milliseconds']: input });\n }\n return null;\n}\nfunction parseString(s) {\n let m = PARSE_RE.exec(s);\n if (m) {\n let sign = m[1] ? -1 : 1;\n return {\n years: 0,\n months: 0,\n days: sign * (m[2] ? parseInt(m[2], 10) : 0),\n milliseconds: sign * ((m[3] ? parseInt(m[3], 10) : 0) * 60 * 60 * 1000 + // hours\n (m[4] ? parseInt(m[4], 10) : 0) * 60 * 1000 + // minutes\n (m[5] ? parseInt(m[5], 10) : 0) * 1000 + // seconds\n (m[6] ? parseInt(m[6], 10) : 0) // ms\n ),\n };\n }\n return null;\n}\nfunction parseObject(obj) {\n let duration = {\n years: obj.years || obj.year || 0,\n months: obj.months || obj.month || 0,\n days: obj.days || obj.day || 0,\n milliseconds: (obj.hours || obj.hour || 0) * 60 * 60 * 1000 + // hours\n (obj.minutes || obj.minute || 0) * 60 * 1000 + // minutes\n (obj.seconds || obj.second || 0) * 1000 + // seconds\n (obj.milliseconds || obj.millisecond || obj.ms || 0), // ms\n };\n let weeks = obj.weeks || obj.week;\n if (weeks) {\n duration.days += weeks * 7;\n duration.specifiedWeeks = true;\n }\n return duration;\n}\n// Equality\nfunction durationsEqual(d0, d1) {\n return d0.years === d1.years &&\n d0.months === d1.months &&\n d0.days === d1.days &&\n d0.milliseconds === d1.milliseconds;\n}\nfunction asCleanDays(dur) {\n if (!dur.years && !dur.months && !dur.milliseconds) {\n return dur.days;\n }\n return 0;\n}\n// Simple Math\nfunction addDurations(d0, d1) {\n return {\n years: d0.years + d1.years,\n months: d0.months + d1.months,\n days: d0.days + d1.days,\n milliseconds: d0.milliseconds + d1.milliseconds,\n };\n}\nfunction subtractDurations(d1, d0) {\n return {\n years: d1.years - d0.years,\n months: d1.months - d0.months,\n days: d1.days - d0.days,\n milliseconds: d1.milliseconds - d0.milliseconds,\n };\n}\nfunction multiplyDuration(d, n) {\n return {\n years: d.years * n,\n months: d.months * n,\n days: d.days * n,\n milliseconds: d.milliseconds * n,\n };\n}\n// Conversions\n// \"Rough\" because they are based on average-case Gregorian months/years\nfunction asRoughYears(dur) {\n return asRoughDays(dur) / 365;\n}\nfunction asRoughMonths(dur) {\n return asRoughDays(dur) / 30;\n}\nfunction asRoughDays(dur) {\n return asRoughMs(dur) / 864e5;\n}\nfunction asRoughMinutes(dur) {\n return asRoughMs(dur) / (1000 * 60);\n}\nfunction asRoughSeconds(dur) {\n return asRoughMs(dur) / 1000;\n}\nfunction asRoughMs(dur) {\n return dur.years * (365 * 864e5) +\n dur.months * (30 * 864e5) +\n dur.days * 864e5 +\n dur.milliseconds;\n}\n// Advanced Math\nfunction wholeDivideDurations(numerator, denominator) {\n let res = null;\n for (let i = 0; i < INTERNAL_UNITS.length; i += 1) {\n let unit = INTERNAL_UNITS[i];\n if (denominator[unit]) {\n let localRes = numerator[unit] / denominator[unit];\n if (!isInt(localRes) || (res !== null && res !== localRes)) {\n return null;\n }\n res = localRes;\n }\n else if (numerator[unit]) {\n // needs to divide by something but can't!\n return null;\n }\n }\n return res;\n}\nfunction greatestDurationDenominator(dur) {\n let ms = dur.milliseconds;\n if (ms) {\n if (ms % 1000 !== 0) {\n return { unit: 'millisecond', value: ms };\n }\n if (ms % (1000 * 60) !== 0) {\n return { unit: 'second', value: ms / 1000 };\n }\n if (ms % (1000 * 60 * 60) !== 0) {\n return { unit: 'minute', value: ms / (1000 * 60) };\n }\n if (ms) {\n return { unit: 'hour', value: ms / (1000 * 60 * 60) };\n }\n }\n if (dur.days) {\n if (dur.specifiedWeeks && dur.days % 7 === 0) {\n return { unit: 'week', value: dur.days / 7 };\n }\n return { unit: 'day', value: dur.days };\n }\n if (dur.months) {\n return { unit: 'month', value: dur.months };\n }\n if (dur.years) {\n return { unit: 'year', value: dur.years };\n }\n return { unit: 'millisecond', value: 0 };\n}\n\nconst { hasOwnProperty } = Object.prototype;\n// Merges an array of objects into a single object.\n// The second argument allows for an array of property names who's object values will be merged together.\nfunction mergeProps(propObjs, complexPropsMap) {\n let dest = {};\n if (complexPropsMap) {\n for (let name in complexPropsMap) {\n let complexObjs = [];\n // collect the trailing object values, stopping when a non-object is discovered\n for (let i = propObjs.length - 1; i >= 0; i -= 1) {\n let val = propObjs[i][name];\n if (typeof val === 'object' && val) { // non-null object\n complexObjs.unshift(val);\n }\n else if (val !== undefined) {\n dest[name] = val; // if there were no objects, this value will be used\n break;\n }\n }\n // if the trailing values were objects, use the merged value\n if (complexObjs.length) {\n dest[name] = mergeProps(complexObjs);\n }\n }\n }\n // copy values into the destination, going from last to first\n for (let i = propObjs.length - 1; i >= 0; i -= 1) {\n let props = propObjs[i];\n for (let name in props) {\n if (!(name in dest)) { // if already assigned by previous props or complex props, don't reassign\n dest[name] = props[name];\n }\n }\n }\n return dest;\n}\nfunction filterHash(hash, func) {\n let filtered = {};\n for (let key in hash) {\n if (func(hash[key], key)) {\n filtered[key] = hash[key];\n }\n }\n return filtered;\n}\nfunction mapHash(hash, func) {\n let newHash = {};\n for (let key in hash) {\n newHash[key] = func(hash[key], key);\n }\n return newHash;\n}\nfunction arrayToHash(a) {\n let hash = {};\n for (let item of a) {\n hash[item] = true;\n }\n return hash;\n}\n// TODO: reassess browser support\n// https://caniuse.com/?search=object.values\nfunction hashValuesToArray(obj) {\n let a = [];\n for (let key in obj) {\n a.push(obj[key]);\n }\n return a;\n}\nfunction isPropsEqual(obj0, obj1) {\n if (obj0 === obj1) {\n return true;\n }\n for (let key in obj0) {\n if (hasOwnProperty.call(obj0, key)) {\n if (!(key in obj1)) {\n return false;\n }\n }\n }\n for (let key in obj1) {\n if (hasOwnProperty.call(obj1, key)) {\n if (obj0[key] !== obj1[key]) {\n return false;\n }\n }\n }\n return true;\n}\nconst HANDLER_RE = /^on[A-Z]/;\nfunction isNonHandlerPropsEqual(obj0, obj1) {\n const keys = getUnequalProps(obj0, obj1);\n for (let key of keys) {\n if (!HANDLER_RE.test(key)) {\n return false;\n }\n }\n return true;\n}\nfunction getUnequalProps(obj0, obj1) {\n let keys = [];\n for (let key in obj0) {\n if (hasOwnProperty.call(obj0, key)) {\n if (!(key in obj1)) {\n keys.push(key);\n }\n }\n }\n for (let key in obj1) {\n if (hasOwnProperty.call(obj1, key)) {\n if (obj0[key] !== obj1[key]) {\n keys.push(key);\n }\n }\n }\n return keys;\n}\nfunction compareObjs(oldProps, newProps, equalityFuncs = {}) {\n if (oldProps === newProps) {\n return true;\n }\n for (let key in newProps) {\n if (key in oldProps && isObjValsEqual(oldProps[key], newProps[key], equalityFuncs[key])) ;\n else {\n return false;\n }\n }\n // check for props that were omitted in the new\n for (let key in oldProps) {\n if (!(key in newProps)) {\n return false;\n }\n }\n return true;\n}\n/*\nassumed \"true\" equality for handler names like \"onReceiveSomething\"\n*/\nfunction isObjValsEqual(val0, val1, comparator) {\n if (val0 === val1 || comparator === true) {\n return true;\n }\n if (comparator) {\n return comparator(val0, val1);\n }\n return false;\n}\nfunction collectFromHash(hash, startIndex = 0, endIndex, step = 1) {\n let res = [];\n if (endIndex == null) {\n endIndex = Object.keys(hash).length;\n }\n for (let i = startIndex; i < endIndex; i += step) {\n let val = hash[i];\n if (val !== undefined) { // will disregard undefined for sparse arrays\n res.push(val);\n }\n }\n return res;\n}\n\nconst DAY_IDS = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'];\n// Adding\nfunction addWeeks(m, n) {\n let a = dateToUtcArray(m);\n a[2] += n * 7;\n return arrayToUtcDate(a);\n}\nfunction addDays(m, n) {\n let a = dateToUtcArray(m);\n a[2] += n;\n return arrayToUtcDate(a);\n}\nfunction addMs(m, n) {\n let a = dateToUtcArray(m);\n a[6] += n;\n return arrayToUtcDate(a);\n}\n// Diffing (all return floats)\n// TODO: why not use ranges?\nfunction diffWeeks(m0, m1) {\n return diffDays(m0, m1) / 7;\n}\nfunction diffDays(m0, m1) {\n return (m1.valueOf() - m0.valueOf()) / (1000 * 60 * 60 * 24);\n}\nfunction diffHours(m0, m1) {\n return (m1.valueOf() - m0.valueOf()) / (1000 * 60 * 60);\n}\nfunction diffMinutes(m0, m1) {\n return (m1.valueOf() - m0.valueOf()) / (1000 * 60);\n}\nfunction diffSeconds(m0, m1) {\n return (m1.valueOf() - m0.valueOf()) / 1000;\n}\nfunction diffDayAndTime(m0, m1) {\n let m0day = startOfDay(m0);\n let m1day = startOfDay(m1);\n return {\n years: 0,\n months: 0,\n days: Math.round(diffDays(m0day, m1day)),\n milliseconds: (m1.valueOf() - m1day.valueOf()) - (m0.valueOf() - m0day.valueOf()),\n };\n}\n// Diffing Whole Units\nfunction diffWholeWeeks(m0, m1) {\n let d = diffWholeDays(m0, m1);\n if (d !== null && d % 7 === 0) {\n return d / 7;\n }\n return null;\n}\nfunction diffWholeDays(m0, m1) {\n if (timeAsMs(m0) === timeAsMs(m1)) {\n return Math.round(diffDays(m0, m1));\n }\n return null;\n}\n// Start-Of\nfunction startOfDay(m) {\n return arrayToUtcDate([\n m.getUTCFullYear(),\n m.getUTCMonth(),\n m.getUTCDate(),\n ]);\n}\nfunction startOfHour(m) {\n return arrayToUtcDate([\n m.getUTCFullYear(),\n m.getUTCMonth(),\n m.getUTCDate(),\n m.getUTCHours(),\n ]);\n}\nfunction startOfMinute(m) {\n return arrayToUtcDate([\n m.getUTCFullYear(),\n m.getUTCMonth(),\n m.getUTCDate(),\n m.getUTCHours(),\n m.getUTCMinutes(),\n ]);\n}\nfunction startOfSecond(m) {\n return arrayToUtcDate([\n m.getUTCFullYear(),\n m.getUTCMonth(),\n m.getUTCDate(),\n m.getUTCHours(),\n m.getUTCMinutes(),\n m.getUTCSeconds(),\n ]);\n}\n// Week Computation\nfunction weekOfYear(marker, dow, doy) {\n let y = marker.getUTCFullYear();\n let w = weekOfGivenYear(marker, y, dow, doy);\n if (w < 1) {\n return weekOfGivenYear(marker, y - 1, dow, doy);\n }\n let nextW = weekOfGivenYear(marker, y + 1, dow, doy);\n if (nextW >= 1) {\n return Math.min(w, nextW);\n }\n return w;\n}\nfunction weekOfGivenYear(marker, year, dow, doy) {\n let firstWeekStart = arrayToUtcDate([year, 0, 1 + firstWeekOffset(year, dow, doy)]);\n let dayStart = startOfDay(marker);\n let days = Math.round(diffDays(firstWeekStart, dayStart));\n return Math.floor(days / 7) + 1; // zero-indexed\n}\n// start-of-first-week - start-of-year\nfunction firstWeekOffset(year, dow, doy) {\n // first-week day -- which january is always in the first week (4 for iso, 1 for other)\n let fwd = 7 + dow - doy;\n // first-week day local weekday -- which local weekday is fwd\n let fwdlw = (7 + arrayToUtcDate([year, 0, fwd]).getUTCDay() - dow) % 7;\n return -fwdlw + fwd - 1;\n}\n// Array Conversion\nfunction dateToLocalArray(date) {\n return [\n date.getFullYear(),\n date.getMonth(),\n date.getDate(),\n date.getHours(),\n date.getMinutes(),\n date.getSeconds(),\n date.getMilliseconds(),\n ];\n}\nfunction arrayToLocalDate(a) {\n return new Date(a[0], a[1] || 0, a[2] == null ? 1 : a[2], // day of month\n a[3] || 0, a[4] || 0, a[5] || 0);\n}\nfunction dateToUtcArray(date) {\n return [\n date.getUTCFullYear(),\n date.getUTCMonth(),\n date.getUTCDate(),\n date.getUTCHours(),\n date.getUTCMinutes(),\n date.getUTCSeconds(),\n date.getUTCMilliseconds(),\n ];\n}\nfunction arrayToUtcDate(a) {\n // according to web standards (and Safari), a month index is required.\n // massage if only given a year.\n if (a.length === 1) {\n a = a.concat([0]);\n }\n return new Date(Date.UTC(...a));\n}\n// Other Utils\nfunction isValidDate(m) {\n return !isNaN(m.valueOf());\n}\nfunction timeAsMs(m) {\n return m.getUTCHours() * 1000 * 60 * 60 +\n m.getUTCMinutes() * 1000 * 60 +\n m.getUTCSeconds() * 1000 +\n m.getUTCMilliseconds();\n}\n\n// timeZoneOffset is in minutes\nfunction buildIsoString(marker, timeZoneOffset, stripZeroTime = false) {\n let s = marker.toISOString();\n s = s.replace('.000', '');\n if (stripZeroTime) {\n s = s.replace('T00:00:00Z', '');\n }\n if (s.length > 10) { // time part wasn't stripped, can add timezone info\n if (timeZoneOffset == null) {\n s = s.replace('Z', '');\n }\n else if (timeZoneOffset !== 0) {\n s = s.replace('Z', formatTimeZoneOffset(timeZoneOffset, true));\n }\n // otherwise, its UTC-0 and we want to keep the Z\n }\n return s;\n}\n// formats the date, but with no time part\n// TODO: somehow merge with buildIsoString and stripZeroTime\n// TODO: rename. omit \"string\"\nfunction formatDayString(marker) {\n return marker.toISOString().replace(/T.*$/, '');\n}\n// TODO: use Date::toISOString and use everything after the T?\nfunction formatIsoTimeString(marker) {\n return padStart(marker.getUTCHours(), 2) + ':' +\n padStart(marker.getUTCMinutes(), 2) + ':' +\n padStart(marker.getUTCSeconds(), 2);\n}\nfunction formatTimeZoneOffset(minutes, doIso = false) {\n let sign = minutes < 0 ? '-' : '+';\n let abs = Math.abs(minutes);\n let hours = Math.floor(abs / 60);\n let mins = Math.round(abs % 60);\n if (doIso) {\n return `${sign + padStart(hours, 2)}:${padStart(mins, 2)}`;\n }\n return `GMT${sign}${hours}${mins ? `:${padStart(mins, 2)}` : ''}`;\n}\n\n// TODO: new util arrayify?\nfunction removeExact(array, exactVal) {\n let removeCnt = 0;\n let i = 0;\n while (i < array.length) {\n if (array[i] === exactVal) {\n array.splice(i, 1);\n removeCnt += 1;\n }\n else {\n i += 1;\n }\n }\n return removeCnt;\n}\nfunction isArraysEqual(a0, a1, equalityFunc) {\n if (a0 === a1) {\n return true;\n }\n let len = a0.length;\n let i;\n if (len !== a1.length) { // not array? or not same length?\n return false;\n }\n for (i = 0; i < len; i += 1) {\n if (!(equalityFunc ? equalityFunc(a0[i], a1[i]) : a0[i] === a1[i])) {\n return false;\n }\n }\n return true;\n}\n\nfunction memoize(workerFunc, resEquality, teardownFunc) {\n let currentArgs;\n let currentRes;\n return function (...newArgs) {\n if (!currentArgs) {\n currentRes = workerFunc.apply(this, newArgs);\n }\n else if (!isArraysEqual(currentArgs, newArgs)) {\n if (teardownFunc) {\n teardownFunc(currentRes);\n }\n let res = workerFunc.apply(this, newArgs);\n if (!resEquality || !resEquality(res, currentRes)) {\n currentRes = res;\n }\n }\n currentArgs = newArgs;\n return currentRes;\n };\n}\nfunction memoizeObjArg(workerFunc, resEquality, teardownFunc) {\n let currentArg;\n let currentRes;\n return (newArg) => {\n if (!currentArg) {\n currentRes = workerFunc.call(this, newArg);\n }\n else if (!isPropsEqual(currentArg, newArg)) {\n if (teardownFunc) {\n teardownFunc(currentRes);\n }\n let res = workerFunc.call(this, newArg);\n if (!resEquality || !resEquality(res, currentRes)) {\n currentRes = res;\n }\n }\n currentArg = newArg;\n return currentRes;\n };\n}\nfunction memoizeArraylike(// used at all?\nworkerFunc, resEquality, teardownFunc) {\n let currentArgSets = [];\n let currentResults = [];\n return (newArgSets) => {\n let currentLen = currentArgSets.length;\n let newLen = newArgSets.length;\n let i = 0;\n for (; i < currentLen; i += 1) {\n if (!newArgSets[i]) { // one of the old sets no longer exists\n if (teardownFunc) {\n teardownFunc(currentResults[i]);\n }\n }\n else if (!isArraysEqual(currentArgSets[i], newArgSets[i])) {\n if (teardownFunc) {\n teardownFunc(currentResults[i]);\n }\n let res = workerFunc.apply(this, newArgSets[i]);\n if (!resEquality || !resEquality(res, currentResults[i])) {\n currentResults[i] = res;\n }\n }\n }\n for (; i < newLen; i += 1) {\n currentResults[i] = workerFunc.apply(this, newArgSets[i]);\n }\n currentArgSets = newArgSets;\n currentResults.splice(newLen); // remove excess\n return currentResults;\n };\n}\nfunction memoizeHashlike(workerFunc, resEquality, teardownFunc) {\n let currentArgHash = {};\n let currentResHash = {};\n return (newArgHash) => {\n let newResHash = {};\n for (let key in newArgHash) {\n if (!currentResHash[key]) {\n newResHash[key] = workerFunc.apply(this, newArgHash[key]);\n }\n else if (!isArraysEqual(currentArgHash[key], newArgHash[key])) {\n if (teardownFunc) {\n teardownFunc(currentResHash[key]);\n }\n let res = workerFunc.apply(this, newArgHash[key]);\n newResHash[key] = (resEquality && resEquality(res, currentResHash[key]))\n ? currentResHash[key]\n : res;\n }\n else {\n newResHash[key] = currentResHash[key];\n }\n }\n currentArgHash = newArgHash;\n currentResHash = newResHash;\n return newResHash;\n };\n}\n\nconst EXTENDED_SETTINGS_AND_SEVERITIES = {\n week: 3,\n separator: 0,\n omitZeroMinute: 0,\n meridiem: 0,\n omitCommas: 0,\n};\nconst STANDARD_DATE_PROP_SEVERITIES = {\n timeZoneName: 7,\n era: 6,\n year: 5,\n month: 4,\n day: 2,\n weekday: 2,\n hour: 1,\n minute: 1,\n second: 1,\n};\nconst MERIDIEM_RE = /\\s*([ap])\\.?m\\.?/i; // eats up leading spaces too\nconst COMMA_RE = /,/g; // we need re for globalness\nconst MULTI_SPACE_RE = /\\s+/g;\nconst LTR_RE = /\\u200e/g; // control character\nconst UTC_RE = /UTC|GMT/;\nclass NativeFormatter {\n constructor(formatSettings) {\n let standardDateProps = {};\n let extendedSettings = {};\n let severity = 0;\n for (let name in formatSettings) {\n if (name in EXTENDED_SETTINGS_AND_SEVERITIES) {\n extendedSettings[name] = formatSettings[name];\n severity = Math.max(EXTENDED_SETTINGS_AND_SEVERITIES[name], severity);\n }\n else {\n standardDateProps[name] = formatSettings[name];\n if (name in STANDARD_DATE_PROP_SEVERITIES) { // TODO: what about hour12? no severity\n severity = Math.max(STANDARD_DATE_PROP_SEVERITIES[name], severity);\n }\n }\n }\n this.standardDateProps = standardDateProps;\n this.extendedSettings = extendedSettings;\n this.severity = severity;\n this.buildFormattingFunc = memoize(buildFormattingFunc);\n }\n format(date, context) {\n return this.buildFormattingFunc(this.standardDateProps, this.extendedSettings, context)(date);\n }\n formatRange(start, end, context, betterDefaultSeparator) {\n let { standardDateProps, extendedSettings } = this;\n let diffSeverity = computeMarkerDiffSeverity(start.marker, end.marker, context.calendarSystem);\n if (!diffSeverity) {\n return this.format(start, context);\n }\n let biggestUnitForPartial = diffSeverity;\n if (biggestUnitForPartial > 1 && // the two dates are different in a way that's larger scale than time\n (standardDateProps.year === 'numeric' || standardDateProps.year === '2-digit') &&\n (standardDateProps.month === 'numeric' || standardDateProps.month === '2-digit') &&\n (standardDateProps.day === 'numeric' || standardDateProps.day === '2-digit')) {\n biggestUnitForPartial = 1; // make it look like the dates are only different in terms of time\n }\n let full0 = this.format(start, context);\n let full1 = this.format(end, context);\n if (full0 === full1) {\n return full0;\n }\n let partialDateProps = computePartialFormattingOptions(standardDateProps, biggestUnitForPartial);\n let partialFormattingFunc = buildFormattingFunc(partialDateProps, extendedSettings, context);\n let partial0 = partialFormattingFunc(start);\n let partial1 = partialFormattingFunc(end);\n let insertion = findCommonInsertion(full0, partial0, full1, partial1);\n let separator = extendedSettings.separator || betterDefaultSeparator || context.defaultSeparator || '';\n if (insertion) {\n return insertion.before + partial0 + separator + partial1 + insertion.after;\n }\n return full0 + separator + full1;\n }\n getLargestUnit() {\n switch (this.severity) {\n case 7:\n case 6:\n case 5:\n return 'year';\n case 4:\n return 'month';\n case 3:\n return 'week';\n case 2:\n return 'day';\n default:\n return 'time'; // really?\n }\n }\n}\nfunction buildFormattingFunc(standardDateProps, extendedSettings, context) {\n let standardDatePropCnt = Object.keys(standardDateProps).length;\n if (standardDatePropCnt === 1 && standardDateProps.timeZoneName === 'short') {\n return (date) => (formatTimeZoneOffset(date.timeZoneOffset));\n }\n if (standardDatePropCnt === 0 && extendedSettings.week) {\n return (date) => (formatWeekNumber(context.computeWeekNumber(date.marker), context.weekText, context.weekTextLong, context.locale, extendedSettings.week));\n }\n return buildNativeFormattingFunc(standardDateProps, extendedSettings, context);\n}\nfunction buildNativeFormattingFunc(standardDateProps, extendedSettings, context) {\n standardDateProps = Object.assign({}, standardDateProps); // copy\n extendedSettings = Object.assign({}, extendedSettings); // copy\n sanitizeSettings(standardDateProps, extendedSettings);\n standardDateProps.timeZone = 'UTC'; // we leverage the only guaranteed timeZone for our UTC markers\n let normalFormat = new Intl.DateTimeFormat(context.locale.codes, standardDateProps);\n let zeroFormat; // needed?\n if (extendedSettings.omitZeroMinute) {\n let zeroProps = Object.assign({}, standardDateProps);\n delete zeroProps.minute; // seconds and ms were already considered in sanitizeSettings\n zeroFormat = new Intl.DateTimeFormat(context.locale.codes, zeroProps);\n }\n return (date) => {\n let { marker } = date;\n let format;\n if (zeroFormat && !marker.getUTCMinutes()) {\n format = zeroFormat;\n }\n else {\n format = normalFormat;\n }\n let s = format.format(marker);\n return postProcess(s, date, standardDateProps, extendedSettings, context);\n };\n}\nfunction sanitizeSettings(standardDateProps, extendedSettings) {\n // deal with a browser inconsistency where formatting the timezone\n // requires that the hour/minute be present.\n if (standardDateProps.timeZoneName) {\n if (!standardDateProps.hour) {\n standardDateProps.hour = '2-digit';\n }\n if (!standardDateProps.minute) {\n standardDateProps.minute = '2-digit';\n }\n }\n // only support short timezone names\n if (standardDateProps.timeZoneName === 'long') {\n standardDateProps.timeZoneName = 'short';\n }\n // if requesting to display seconds, MUST display minutes\n if (extendedSettings.omitZeroMinute && (standardDateProps.second || standardDateProps.millisecond)) {\n delete extendedSettings.omitZeroMinute;\n }\n}\nfunction postProcess(s, date, standardDateProps, extendedSettings, context) {\n s = s.replace(LTR_RE, ''); // remove left-to-right control chars. do first. good for other regexes\n if (standardDateProps.timeZoneName === 'short') {\n s = injectTzoStr(s, (context.timeZone === 'UTC' || date.timeZoneOffset == null) ?\n 'UTC' : // important to normalize for IE, which does \"GMT\"\n formatTimeZoneOffset(date.timeZoneOffset));\n }\n if (extendedSettings.omitCommas) {\n s = s.replace(COMMA_RE, '').trim();\n }\n if (extendedSettings.omitZeroMinute) {\n s = s.replace(':00', ''); // zeroFormat doesn't always achieve this\n }\n // ^ do anything that might create adjacent spaces before this point,\n // because MERIDIEM_RE likes to eat up loading spaces\n if (extendedSettings.meridiem === false) {\n s = s.replace(MERIDIEM_RE, '').trim();\n }\n else if (extendedSettings.meridiem === 'narrow') { // a/p\n s = s.replace(MERIDIEM_RE, (m0, m1) => m1.toLocaleLowerCase());\n }\n else if (extendedSettings.meridiem === 'short') { // am/pm\n s = s.replace(MERIDIEM_RE, (m0, m1) => `${m1.toLocaleLowerCase()}m`);\n }\n else if (extendedSettings.meridiem === 'lowercase') { // other meridiem transformers already converted to lowercase\n s = s.replace(MERIDIEM_RE, (m0) => m0.toLocaleLowerCase());\n }\n s = s.replace(MULTI_SPACE_RE, ' ');\n s = s.trim();\n return s;\n}\nfunction injectTzoStr(s, tzoStr) {\n let replaced = false;\n s = s.replace(UTC_RE, () => {\n replaced = true;\n return tzoStr;\n });\n // IE11 doesn't include UTC/GMT in the original string, so append to end\n if (!replaced) {\n s += ` ${tzoStr}`;\n }\n return s;\n}\nfunction formatWeekNumber(num, weekText, weekTextLong, locale, display) {\n let parts = [];\n if (display === 'long') {\n parts.push(weekTextLong);\n }\n else if (display === 'short' || display === 'narrow') {\n parts.push(weekText);\n }\n if (display === 'long' || display === 'short') {\n parts.push(' ');\n }\n parts.push(locale.simpleNumberFormat.format(num));\n if (locale.options.direction === 'rtl') { // TODO: use control characters instead?\n parts.reverse();\n }\n return parts.join('');\n}\n// Range Formatting Utils\n// 0 = exactly the same\n// 1 = different by time\n// and bigger\nfunction computeMarkerDiffSeverity(d0, d1, ca) {\n if (ca.getMarkerYear(d0) !== ca.getMarkerYear(d1)) {\n return 5;\n }\n if (ca.getMarkerMonth(d0) !== ca.getMarkerMonth(d1)) {\n return 4;\n }\n if (ca.getMarkerDay(d0) !== ca.getMarkerDay(d1)) {\n return 2;\n }\n if (timeAsMs(d0) !== timeAsMs(d1)) {\n return 1;\n }\n return 0;\n}\nfunction computePartialFormattingOptions(options, biggestUnit) {\n let partialOptions = {};\n for (let name in options) {\n if (!(name in STANDARD_DATE_PROP_SEVERITIES) || // not a date part prop (like timeZone)\n STANDARD_DATE_PROP_SEVERITIES[name] <= biggestUnit) {\n partialOptions[name] = options[name];\n }\n }\n return partialOptions;\n}\nfunction findCommonInsertion(full0, partial0, full1, partial1) {\n let i0 = 0;\n while (i0 < full0.length) {\n let found0 = full0.indexOf(partial0, i0);\n if (found0 === -1) {\n break;\n }\n let before0 = full0.substr(0, found0);\n i0 = found0 + partial0.length;\n let after0 = full0.substr(i0);\n let i1 = 0;\n while (i1 < full1.length) {\n let found1 = full1.indexOf(partial1, i1);\n if (found1 === -1) {\n break;\n }\n let before1 = full1.substr(0, found1);\n i1 = found1 + partial1.length;\n let after1 = full1.substr(i1);\n if (before0 === before1 && after0 === after1) {\n return {\n before: before0,\n after: after0,\n };\n }\n }\n }\n return null;\n}\n\nfunction expandZonedMarker(dateInfo, calendarSystem) {\n let a = calendarSystem.markerToArray(dateInfo.marker);\n return {\n marker: dateInfo.marker,\n timeZoneOffset: dateInfo.timeZoneOffset,\n array: a,\n year: a[0],\n month: a[1],\n day: a[2],\n hour: a[3],\n minute: a[4],\n second: a[5],\n millisecond: a[6],\n };\n}\n\nfunction createVerboseFormattingArg(start, end, context, betterDefaultSeparator) {\n let startInfo = expandZonedMarker(start, context.calendarSystem);\n let endInfo = end ? expandZonedMarker(end, context.calendarSystem) : null;\n return {\n date: startInfo,\n start: startInfo,\n end: endInfo,\n timeZone: context.timeZone,\n localeCodes: context.locale.codes,\n defaultSeparator: betterDefaultSeparator || context.defaultSeparator,\n };\n}\n\n/*\nTODO: fix the terminology of \"formatter\" vs \"formatting func\"\n*/\n/*\nAt the time of instantiation, this object does not know which cmd-formatting system it will use.\nIt receives this at the time of formatting, as a setting.\n*/\nclass CmdFormatter {\n constructor(cmdStr) {\n this.cmdStr = cmdStr;\n }\n format(date, context, betterDefaultSeparator) {\n return context.cmdFormatter(this.cmdStr, createVerboseFormattingArg(date, null, context, betterDefaultSeparator));\n }\n formatRange(start, end, context, betterDefaultSeparator) {\n return context.cmdFormatter(this.cmdStr, createVerboseFormattingArg(start, end, context, betterDefaultSeparator));\n }\n}\n\nclass FuncFormatter {\n constructor(func) {\n this.func = func;\n }\n format(date, context, betterDefaultSeparator) {\n return this.func(createVerboseFormattingArg(date, null, context, betterDefaultSeparator));\n }\n formatRange(start, end, context, betterDefaultSeparator) {\n return this.func(createVerboseFormattingArg(start, end, context, betterDefaultSeparator));\n }\n}\n\nfunction createFormatter(input) {\n if (typeof input === 'object' && input) { // non-null object\n return new NativeFormatter(input);\n }\n if (typeof input === 'string') {\n return new CmdFormatter(input);\n }\n if (typeof input === 'function') {\n return new FuncFormatter(input);\n }\n return null;\n}\n\n// base options\n// ------------\nconst BASE_OPTION_REFINERS = {\n navLinkDayClick: identity,\n navLinkWeekClick: identity,\n duration: createDuration,\n bootstrapFontAwesome: identity,\n buttonIcons: identity,\n customButtons: identity,\n defaultAllDayEventDuration: createDuration,\n defaultTimedEventDuration: createDuration,\n nextDayThreshold: createDuration,\n scrollTime: createDuration,\n scrollTimeReset: Boolean,\n slotMinTime: createDuration,\n slotMaxTime: createDuration,\n dayPopoverFormat: createFormatter,\n slotDuration: createDuration,\n snapDuration: createDuration,\n headerToolbar: identity,\n footerToolbar: identity,\n defaultRangeSeparator: String,\n titleRangeSeparator: String,\n forceEventDuration: Boolean,\n dayHeaders: Boolean,\n dayHeaderFormat: createFormatter,\n dayHeaderClassNames: identity,\n dayHeaderContent: identity,\n dayHeaderDidMount: identity,\n dayHeaderWillUnmount: identity,\n dayCellClassNames: identity,\n dayCellContent: identity,\n dayCellDidMount: identity,\n dayCellWillUnmount: identity,\n initialView: String,\n aspectRatio: Number,\n weekends: Boolean,\n weekNumberCalculation: identity,\n weekNumbers: Boolean,\n weekNumberClassNames: identity,\n weekNumberContent: identity,\n weekNumberDidMount: identity,\n weekNumberWillUnmount: identity,\n editable: Boolean,\n viewClassNames: identity,\n viewDidMount: identity,\n viewWillUnmount: identity,\n nowIndicator: Boolean,\n nowIndicatorClassNames: identity,\n nowIndicatorContent: identity,\n nowIndicatorDidMount: identity,\n nowIndicatorWillUnmount: identity,\n showNonCurrentDates: Boolean,\n lazyFetching: Boolean,\n startParam: String,\n endParam: String,\n timeZoneParam: String,\n timeZone: String,\n locales: identity,\n locale: identity,\n themeSystem: String,\n dragRevertDuration: Number,\n dragScroll: Boolean,\n allDayMaintainDuration: Boolean,\n unselectAuto: Boolean,\n dropAccept: identity,\n eventOrder: parseFieldSpecs,\n eventOrderStrict: Boolean,\n handleWindowResize: Boolean,\n windowResizeDelay: Number,\n longPressDelay: Number,\n eventDragMinDistance: Number,\n expandRows: Boolean,\n height: identity,\n contentHeight: identity,\n direction: String,\n weekNumberFormat: createFormatter,\n eventResizableFromStart: Boolean,\n displayEventTime: Boolean,\n displayEventEnd: Boolean,\n weekText: String,\n weekTextLong: String,\n progressiveEventRendering: Boolean,\n businessHours: identity,\n initialDate: identity,\n now: identity,\n eventDataTransform: identity,\n stickyHeaderDates: identity,\n stickyFooterScrollbar: identity,\n viewHeight: identity,\n defaultAllDay: Boolean,\n eventSourceFailure: identity,\n eventSourceSuccess: identity,\n eventDisplay: String,\n eventStartEditable: Boolean,\n eventDurationEditable: Boolean,\n eventOverlap: identity,\n eventConstraint: identity,\n eventAllow: identity,\n eventBackgroundColor: String,\n eventBorderColor: String,\n eventTextColor: String,\n eventColor: String,\n eventClassNames: identity,\n eventContent: identity,\n eventDidMount: identity,\n eventWillUnmount: identity,\n selectConstraint: identity,\n selectOverlap: identity,\n selectAllow: identity,\n droppable: Boolean,\n unselectCancel: String,\n slotLabelFormat: identity,\n slotLaneClassNames: identity,\n slotLaneContent: identity,\n slotLaneDidMount: identity,\n slotLaneWillUnmount: identity,\n slotLabelClassNames: identity,\n slotLabelContent: identity,\n slotLabelDidMount: identity,\n slotLabelWillUnmount: identity,\n dayMaxEvents: identity,\n dayMaxEventRows: identity,\n dayMinWidth: Number,\n slotLabelInterval: createDuration,\n allDayText: String,\n allDayClassNames: identity,\n allDayContent: identity,\n allDayDidMount: identity,\n allDayWillUnmount: identity,\n slotMinWidth: Number,\n navLinks: Boolean,\n eventTimeFormat: createFormatter,\n rerenderDelay: Number,\n moreLinkText: identity,\n moreLinkHint: identity,\n selectMinDistance: Number,\n selectable: Boolean,\n selectLongPressDelay: Number,\n eventLongPressDelay: Number,\n selectMirror: Boolean,\n eventMaxStack: Number,\n eventMinHeight: Number,\n eventMinWidth: Number,\n eventShortHeight: Number,\n slotEventOverlap: Boolean,\n plugins: identity,\n firstDay: Number,\n dayCount: Number,\n dateAlignment: String,\n dateIncrement: createDuration,\n hiddenDays: identity,\n monthMode: Boolean,\n fixedWeekCount: Boolean,\n validRange: identity,\n visibleRange: identity,\n titleFormat: identity,\n eventInteractive: Boolean,\n // only used by list-view, but languages define the value, so we need it in base options\n noEventsText: String,\n viewHint: identity,\n navLinkHint: identity,\n closeHint: String,\n timeHint: String,\n eventHint: String,\n moreLinkClick: identity,\n moreLinkClassNames: identity,\n moreLinkContent: identity,\n moreLinkDidMount: identity,\n moreLinkWillUnmount: identity,\n // for connectors\n // (can't be part of plugin system b/c must be provided at runtime)\n handleCustomRendering: identity,\n customRenderingMetaMap: identity,\n customRenderingReplacesEl: Boolean,\n};\n// do NOT give a type here. need `typeof BASE_OPTION_DEFAULTS` to give real results.\n// raw values.\nconst BASE_OPTION_DEFAULTS = {\n eventDisplay: 'auto',\n defaultRangeSeparator: ' - ',\n titleRangeSeparator: ' \\u2013 ',\n defaultTimedEventDuration: '01:00:00',\n defaultAllDayEventDuration: { day: 1 },\n forceEventDuration: false,\n nextDayThreshold: '00:00:00',\n dayHeaders: true,\n initialView: '',\n aspectRatio: 1.35,\n headerToolbar: {\n start: 'title',\n center: '',\n end: 'today prev,next',\n },\n weekends: true,\n weekNumbers: false,\n weekNumberCalculation: 'local',\n editable: false,\n nowIndicator: false,\n scrollTime: '06:00:00',\n scrollTimeReset: true,\n slotMinTime: '00:00:00',\n slotMaxTime: '24:00:00',\n showNonCurrentDates: true,\n lazyFetching: true,\n startParam: 'start',\n endParam: 'end',\n timeZoneParam: 'timeZone',\n timeZone: 'local',\n locales: [],\n locale: '',\n themeSystem: 'standard',\n dragRevertDuration: 500,\n dragScroll: true,\n allDayMaintainDuration: false,\n unselectAuto: true,\n dropAccept: '*',\n eventOrder: 'start,-duration,allDay,title',\n dayPopoverFormat: { month: 'long', day: 'numeric', year: 'numeric' },\n handleWindowResize: true,\n windowResizeDelay: 100,\n longPressDelay: 1000,\n eventDragMinDistance: 5,\n expandRows: false,\n navLinks: false,\n selectable: false,\n eventMinHeight: 15,\n eventMinWidth: 30,\n eventShortHeight: 30,\n};\n// calendar listeners\n// ------------------\nconst CALENDAR_LISTENER_REFINERS = {\n datesSet: identity,\n eventsSet: identity,\n eventAdd: identity,\n eventChange: identity,\n eventRemove: identity,\n windowResize: identity,\n eventClick: identity,\n eventMouseEnter: identity,\n eventMouseLeave: identity,\n select: identity,\n unselect: identity,\n loading: identity,\n // internal\n _unmount: identity,\n _beforeprint: identity,\n _afterprint: identity,\n _noEventDrop: identity,\n _noEventResize: identity,\n _resize: identity,\n _scrollRequest: identity,\n};\n// calendar-specific options\n// -------------------------\nconst CALENDAR_OPTION_REFINERS = {\n buttonText: identity,\n buttonHints: identity,\n views: identity,\n plugins: identity,\n initialEvents: identity,\n events: identity,\n eventSources: identity,\n};\nconst COMPLEX_OPTION_COMPARATORS = {\n headerToolbar: isMaybeObjectsEqual,\n footerToolbar: isMaybeObjectsEqual,\n buttonText: isMaybeObjectsEqual,\n buttonHints: isMaybeObjectsEqual,\n buttonIcons: isMaybeObjectsEqual,\n dateIncrement: isMaybeObjectsEqual,\n};\nfunction isMaybeObjectsEqual(a, b) {\n if (typeof a === 'object' && typeof b === 'object' && a && b) { // both non-null objects\n return isPropsEqual(a, b);\n }\n return a === b;\n}\n// view-specific options\n// ---------------------\nconst VIEW_OPTION_REFINERS = {\n type: String,\n component: identity,\n buttonText: String,\n buttonTextKey: String,\n dateProfileGeneratorClass: identity,\n usesMinMaxTime: Boolean,\n classNames: identity,\n content: identity,\n didMount: identity,\n willUnmount: identity,\n};\n// util funcs\n// ----------------------------------------------------------------------------------------------------\nfunction mergeRawOptions(optionSets) {\n return mergeProps(optionSets, COMPLEX_OPTION_COMPARATORS);\n}\nfunction refineProps(input, refiners) {\n let refined = {};\n let extra = {};\n for (let propName in refiners) {\n if (propName in input) {\n refined[propName] = refiners[propName](input[propName]);\n }\n }\n for (let propName in input) {\n if (!(propName in refiners)) {\n extra[propName] = input[propName];\n }\n }\n return { refined, extra };\n}\nfunction identity(raw) {\n return raw;\n}\n\nfunction createEventInstance(defId, range, forcedStartTzo, forcedEndTzo) {\n return {\n instanceId: guid(),\n defId,\n range,\n forcedStartTzo: forcedStartTzo == null ? null : forcedStartTzo,\n forcedEndTzo: forcedEndTzo == null ? null : forcedEndTzo,\n };\n}\n\nfunction parseRecurring(refined, defaultAllDay, dateEnv, recurringTypes) {\n for (let i = 0; i < recurringTypes.length; i += 1) {\n let parsed = recurringTypes[i].parse(refined, dateEnv);\n if (parsed) {\n let { allDay } = refined;\n if (allDay == null) {\n allDay = defaultAllDay;\n if (allDay == null) {\n allDay = parsed.allDayGuess;\n if (allDay == null) {\n allDay = false;\n }\n }\n }\n return {\n allDay,\n duration: parsed.duration,\n typeData: parsed.typeData,\n typeId: i,\n };\n }\n }\n return null;\n}\nfunction expandRecurring(eventStore, framingRange, context) {\n let { dateEnv, pluginHooks, options } = context;\n let { defs, instances } = eventStore;\n // remove existing recurring instances\n // TODO: bad. always expand events as a second step\n instances = filterHash(instances, (instance) => !defs[instance.defId].recurringDef);\n for (let defId in defs) {\n let def = defs[defId];\n if (def.recurringDef) {\n let { duration } = def.recurringDef;\n if (!duration) {\n duration = def.allDay ?\n options.defaultAllDayEventDuration :\n options.defaultTimedEventDuration;\n }\n let starts = expandRecurringRanges(def, duration, framingRange, dateEnv, pluginHooks.recurringTypes);\n for (let start of starts) {\n let instance = createEventInstance(defId, {\n start,\n end: dateEnv.add(start, duration),\n });\n instances[instance.instanceId] = instance;\n }\n }\n }\n return { defs, instances };\n}\n/*\nEvent MUST have a recurringDef\n*/\nfunction expandRecurringRanges(eventDef, duration, framingRange, dateEnv, recurringTypes) {\n let typeDef = recurringTypes[eventDef.recurringDef.typeId];\n let markers = typeDef.expand(eventDef.recurringDef.typeData, {\n start: dateEnv.subtract(framingRange.start, duration),\n end: framingRange.end,\n }, dateEnv);\n // the recurrence plugins don't guarantee that all-day events are start-of-day, so we have to\n if (eventDef.allDay) {\n markers = markers.map(startOfDay);\n }\n return markers;\n}\n\nfunction parseEvents(rawEvents, eventSource, context, allowOpenRange) {\n let eventStore = createEmptyEventStore();\n let eventRefiners = buildEventRefiners(context);\n for (let rawEvent of rawEvents) {\n let tuple = parseEvent(rawEvent, eventSource, context, allowOpenRange, eventRefiners);\n if (tuple) {\n eventTupleToStore(tuple, eventStore);\n }\n }\n return eventStore;\n}\nfunction eventTupleToStore(tuple, eventStore = createEmptyEventStore()) {\n eventStore.defs[tuple.def.defId] = tuple.def;\n if (tuple.instance) {\n eventStore.instances[tuple.instance.instanceId] = tuple.instance;\n }\n return eventStore;\n}\n// retrieves events that have the same groupId as the instance specified by `instanceId`\n// or they are the same as the instance.\n// why might instanceId not be in the store? an event from another calendar?\nfunction getRelevantEvents(eventStore, instanceId) {\n let instance = eventStore.instances[instanceId];\n if (instance) {\n let def = eventStore.defs[instance.defId];\n // get events/instances with same group\n let newStore = filterEventStoreDefs(eventStore, (lookDef) => isEventDefsGrouped(def, lookDef));\n // add the original\n // TODO: wish we could use eventTupleToStore or something like it\n newStore.defs[def.defId] = def;\n newStore.instances[instance.instanceId] = instance;\n return newStore;\n }\n return createEmptyEventStore();\n}\nfunction isEventDefsGrouped(def0, def1) {\n return Boolean(def0.groupId && def0.groupId === def1.groupId);\n}\nfunction createEmptyEventStore() {\n return { defs: {}, instances: {} };\n}\nfunction mergeEventStores(store0, store1) {\n return {\n defs: Object.assign(Object.assign({}, store0.defs), store1.defs),\n instances: Object.assign(Object.assign({}, store0.instances), store1.instances),\n };\n}\nfunction filterEventStoreDefs(eventStore, filterFunc) {\n let defs = filterHash(eventStore.defs, filterFunc);\n let instances = filterHash(eventStore.instances, (instance) => (defs[instance.defId] // still exists?\n ));\n return { defs, instances };\n}\nfunction excludeSubEventStore(master, sub) {\n let { defs, instances } = master;\n let filteredDefs = {};\n let filteredInstances = {};\n for (let defId in defs) {\n if (!sub.defs[defId]) { // not explicitly excluded\n filteredDefs[defId] = defs[defId];\n }\n }\n for (let instanceId in instances) {\n if (!sub.instances[instanceId] && // not explicitly excluded\n filteredDefs[instances[instanceId].defId] // def wasn't filtered away\n ) {\n filteredInstances[instanceId] = instances[instanceId];\n }\n }\n return {\n defs: filteredDefs,\n instances: filteredInstances,\n };\n}\n\nfunction normalizeConstraint(input, context) {\n if (Array.isArray(input)) {\n return parseEvents(input, null, context, true); // allowOpenRange=true\n }\n if (typeof input === 'object' && input) { // non-null object\n return parseEvents([input], null, context, true); // allowOpenRange=true\n }\n if (input != null) {\n return String(input);\n }\n return null;\n}\n\nfunction parseClassNames(raw) {\n if (Array.isArray(raw)) {\n return raw;\n }\n if (typeof raw === 'string') {\n return raw.split(/\\s+/);\n }\n return [];\n}\n\n// TODO: better called \"EventSettings\" or \"EventConfig\"\n// TODO: move this file into structs\n// TODO: separate constraint/overlap/allow, because selection uses only that, not other props\nconst EVENT_UI_REFINERS = {\n display: String,\n editable: Boolean,\n startEditable: Boolean,\n durationEditable: Boolean,\n constraint: identity,\n overlap: identity,\n allow: identity,\n className: parseClassNames,\n classNames: parseClassNames,\n color: String,\n backgroundColor: String,\n borderColor: String,\n textColor: String,\n};\nconst EMPTY_EVENT_UI = {\n display: null,\n startEditable: null,\n durationEditable: null,\n constraints: [],\n overlap: null,\n allows: [],\n backgroundColor: '',\n borderColor: '',\n textColor: '',\n classNames: [],\n};\nfunction createEventUi(refined, context) {\n let constraint = normalizeConstraint(refined.constraint, context);\n return {\n display: refined.display || null,\n startEditable: refined.startEditable != null ? refined.startEditable : refined.editable,\n durationEditable: refined.durationEditable != null ? refined.durationEditable : refined.editable,\n constraints: constraint != null ? [constraint] : [],\n overlap: refined.overlap != null ? refined.overlap : null,\n allows: refined.allow != null ? [refined.allow] : [],\n backgroundColor: refined.backgroundColor || refined.color || '',\n borderColor: refined.borderColor || refined.color || '',\n textColor: refined.textColor || '',\n classNames: (refined.className || []).concat(refined.classNames || []), // join singular and plural\n };\n}\n// TODO: prevent against problems with <2 args!\nfunction combineEventUis(uis) {\n return uis.reduce(combineTwoEventUis, EMPTY_EVENT_UI);\n}\nfunction combineTwoEventUis(item0, item1) {\n return {\n display: item1.display != null ? item1.display : item0.display,\n startEditable: item1.startEditable != null ? item1.startEditable : item0.startEditable,\n durationEditable: item1.durationEditable != null ? item1.durationEditable : item0.durationEditable,\n constraints: item0.constraints.concat(item1.constraints),\n overlap: typeof item1.overlap === 'boolean' ? item1.overlap : item0.overlap,\n allows: item0.allows.concat(item1.allows),\n backgroundColor: item1.backgroundColor || item0.backgroundColor,\n borderColor: item1.borderColor || item0.borderColor,\n textColor: item1.textColor || item0.textColor,\n classNames: item0.classNames.concat(item1.classNames),\n };\n}\n\nconst EVENT_NON_DATE_REFINERS = {\n id: String,\n groupId: String,\n title: String,\n url: String,\n interactive: Boolean,\n};\nconst EVENT_DATE_REFINERS = {\n start: identity,\n end: identity,\n date: identity,\n allDay: Boolean,\n};\nconst EVENT_REFINERS = Object.assign(Object.assign(Object.assign({}, EVENT_NON_DATE_REFINERS), EVENT_DATE_REFINERS), { extendedProps: identity });\nfunction parseEvent(raw, eventSource, context, allowOpenRange, refiners = buildEventRefiners(context)) {\n let { refined, extra } = refineEventDef(raw, context, refiners);\n let defaultAllDay = computeIsDefaultAllDay(eventSource, context);\n let recurringRes = parseRecurring(refined, defaultAllDay, context.dateEnv, context.pluginHooks.recurringTypes);\n if (recurringRes) {\n let def = parseEventDef(refined, extra, eventSource ? eventSource.sourceId : '', recurringRes.allDay, Boolean(recurringRes.duration), context);\n def.recurringDef = {\n typeId: recurringRes.typeId,\n typeData: recurringRes.typeData,\n duration: recurringRes.duration,\n };\n return { def, instance: null };\n }\n let singleRes = parseSingle(refined, defaultAllDay, context, allowOpenRange);\n if (singleRes) {\n let def = parseEventDef(refined, extra, eventSource ? eventSource.sourceId : '', singleRes.allDay, singleRes.hasEnd, context);\n let instance = createEventInstance(def.defId, singleRes.range, singleRes.forcedStartTzo, singleRes.forcedEndTzo);\n return { def, instance };\n }\n return null;\n}\nfunction refineEventDef(raw, context, refiners = buildEventRefiners(context)) {\n return refineProps(raw, refiners);\n}\nfunction buildEventRefiners(context) {\n return Object.assign(Object.assign(Object.assign({}, EVENT_UI_REFINERS), EVENT_REFINERS), context.pluginHooks.eventRefiners);\n}\n/*\nWill NOT populate extendedProps with the leftover properties.\nWill NOT populate date-related props.\n*/\nfunction parseEventDef(refined, extra, sourceId, allDay, hasEnd, context) {\n let def = {\n title: refined.title || '',\n groupId: refined.groupId || '',\n publicId: refined.id || '',\n url: refined.url || '',\n recurringDef: null,\n defId: guid(),\n sourceId,\n allDay,\n hasEnd,\n interactive: refined.interactive,\n ui: createEventUi(refined, context),\n extendedProps: Object.assign(Object.assign({}, (refined.extendedProps || {})), extra),\n };\n for (let memberAdder of context.pluginHooks.eventDefMemberAdders) {\n Object.assign(def, memberAdder(refined));\n }\n // help out EventImpl from having user modify props\n Object.freeze(def.ui.classNames);\n Object.freeze(def.extendedProps);\n return def;\n}\nfunction parseSingle(refined, defaultAllDay, context, allowOpenRange) {\n let { allDay } = refined;\n let startMeta;\n let startMarker = null;\n let hasEnd = false;\n let endMeta;\n let endMarker = null;\n let startInput = refined.start != null ? refined.start : refined.date;\n startMeta = context.dateEnv.createMarkerMeta(startInput);\n if (startMeta) {\n startMarker = startMeta.marker;\n }\n else if (!allowOpenRange) {\n return null;\n }\n if (refined.end != null) {\n endMeta = context.dateEnv.createMarkerMeta(refined.end);\n }\n if (allDay == null) {\n if (defaultAllDay != null) {\n allDay = defaultAllDay;\n }\n else {\n // fall back to the date props LAST\n allDay = (!startMeta || startMeta.isTimeUnspecified) &&\n (!endMeta || endMeta.isTimeUnspecified);\n }\n }\n if (allDay && startMarker) {\n startMarker = startOfDay(startMarker);\n }\n if (endMeta) {\n endMarker = endMeta.marker;\n if (allDay) {\n endMarker = startOfDay(endMarker);\n }\n if (startMarker && endMarker <= startMarker) {\n endMarker = null;\n }\n }\n if (endMarker) {\n hasEnd = true;\n }\n else if (!allowOpenRange) {\n hasEnd = context.options.forceEventDuration || false;\n endMarker = context.dateEnv.add(startMarker, allDay ?\n context.options.defaultAllDayEventDuration :\n context.options.defaultTimedEventDuration);\n }\n return {\n allDay,\n hasEnd,\n range: { start: startMarker, end: endMarker },\n forcedStartTzo: startMeta ? startMeta.forcedTzo : null,\n forcedEndTzo: endMeta ? endMeta.forcedTzo : null,\n };\n}\nfunction computeIsDefaultAllDay(eventSource, context) {\n let res = null;\n if (eventSource) {\n res = eventSource.defaultAllDay;\n }\n if (res == null) {\n res = context.options.defaultAllDay;\n }\n return res;\n}\n\nconst DEF_DEFAULTS = {\n startTime: '09:00',\n endTime: '17:00',\n daysOfWeek: [1, 2, 3, 4, 5],\n display: 'inverse-background',\n classNames: 'fc-non-business',\n groupId: '_businessHours', // so multiple defs get grouped\n};\n/*\nTODO: pass around as EventDefHash!!!\n*/\nfunction parseBusinessHours(input, context) {\n return parseEvents(refineInputs(input), null, context);\n}\nfunction refineInputs(input) {\n let rawDefs;\n if (input === true) {\n rawDefs = [{}]; // will get DEF_DEFAULTS verbatim\n }\n else if (Array.isArray(input)) {\n // if specifying an array, every sub-definition NEEDS a day-of-week\n rawDefs = input.filter((rawDef) => rawDef.daysOfWeek);\n }\n else if (typeof input === 'object' && input) { // non-null object\n rawDefs = [input];\n }\n else { // is probably false\n rawDefs = [];\n }\n rawDefs = rawDefs.map((rawDef) => (Object.assign(Object.assign({}, DEF_DEFAULTS), rawDef)));\n return rawDefs;\n}\n\n/* Date stuff that doesn't belong in datelib core\n----------------------------------------------------------------------------------------------------------------------*/\n// given a timed range, computes an all-day range that has the same exact duration,\n// but whose start time is aligned with the start of the day.\nfunction computeAlignedDayRange(timedRange) {\n let dayCnt = Math.floor(diffDays(timedRange.start, timedRange.end)) || 1;\n let start = startOfDay(timedRange.start);\n let end = addDays(start, dayCnt);\n return { start, end };\n}\n// given a timed range, computes an all-day range based on how for the end date bleeds into the next day\n// TODO: give nextDayThreshold a default arg\nfunction computeVisibleDayRange(timedRange, nextDayThreshold = createDuration(0)) {\n let startDay = null;\n let endDay = null;\n if (timedRange.end) {\n endDay = startOfDay(timedRange.end);\n let endTimeMS = timedRange.end.valueOf() - endDay.valueOf(); // # of milliseconds into `endDay`\n // If the end time is actually inclusively part of the next day and is equal to or\n // beyond the next day threshold, adjust the end to be the exclusive end of `endDay`.\n // Otherwise, leaving it as inclusive will cause it to exclude `endDay`.\n if (endTimeMS && endTimeMS >= asRoughMs(nextDayThreshold)) {\n endDay = addDays(endDay, 1);\n }\n }\n if (timedRange.start) {\n startDay = startOfDay(timedRange.start); // the beginning of the day the range starts\n // If end is within `startDay` but not past nextDayThreshold, assign the default duration of one day.\n if (endDay && endDay <= startDay) {\n endDay = addDays(startDay, 1);\n }\n }\n return { start: startDay, end: endDay };\n}\n// spans from one day into another?\nfunction isMultiDayRange(range) {\n let visibleRange = computeVisibleDayRange(range);\n return diffDays(visibleRange.start, visibleRange.end) > 1;\n}\nfunction diffDates(date0, date1, dateEnv, largeUnit) {\n if (largeUnit === 'year') {\n return createDuration(dateEnv.diffWholeYears(date0, date1), 'year');\n }\n if (largeUnit === 'month') {\n return createDuration(dateEnv.diffWholeMonths(date0, date1), 'month');\n }\n return diffDayAndTime(date0, date1); // returns a duration\n}\n\nfunction pointInsideRect(point, rect) {\n return point.left >= rect.left &&\n point.left < rect.right &&\n point.top >= rect.top &&\n point.top < rect.bottom;\n}\n// Returns a new rectangle that is the intersection of the two rectangles. If they don't intersect, returns false\nfunction intersectRects(rect1, rect2) {\n let res = {\n left: Math.max(rect1.left, rect2.left),\n right: Math.min(rect1.right, rect2.right),\n top: Math.max(rect1.top, rect2.top),\n bottom: Math.min(rect1.bottom, rect2.bottom),\n };\n if (res.left < res.right && res.top < res.bottom) {\n return res;\n }\n return false;\n}\nfunction translateRect(rect, deltaX, deltaY) {\n return {\n left: rect.left + deltaX,\n right: rect.right + deltaX,\n top: rect.top + deltaY,\n bottom: rect.bottom + deltaY,\n };\n}\n// Returns a new point that will have been moved to reside within the given rectangle\nfunction constrainPoint(point, rect) {\n return {\n left: Math.min(Math.max(point.left, rect.left), rect.right),\n top: Math.min(Math.max(point.top, rect.top), rect.bottom),\n };\n}\n// Returns a point that is the center of the given rectangle\nfunction getRectCenter(rect) {\n return {\n left: (rect.left + rect.right) / 2,\n top: (rect.top + rect.bottom) / 2,\n };\n}\n// Subtracts point2's coordinates from point1's coordinates, returning a delta\nfunction diffPoints(point1, point2) {\n return {\n left: point1.left - point2.left,\n top: point1.top - point2.top,\n };\n}\n\nlet canVGrowWithinCell;\nfunction getCanVGrowWithinCell() {\n if (canVGrowWithinCell == null) {\n canVGrowWithinCell = computeCanVGrowWithinCell();\n }\n return canVGrowWithinCell;\n}\nfunction computeCanVGrowWithinCell() {\n // for SSR, because this function is call immediately at top-level\n // TODO: just make this logic execute top-level, immediately, instead of doing lazily\n if (typeof document === 'undefined') {\n return true;\n }\n let el = document.createElement('div');\n el.style.position = 'absolute';\n el.style.top = '0px';\n el.style.left = '0px';\n el.innerHTML = '
';\n el.querySelector('table').style.height = '100px';\n el.querySelector('div').style.height = '100%';\n document.body.appendChild(el);\n let div = el.querySelector('div');\n let possible = div.offsetHeight > 0;\n document.body.removeChild(el);\n return possible;\n}\n\nconst EMPTY_EVENT_STORE = createEmptyEventStore(); // for purecomponents. TODO: keep elsewhere\nclass Splitter {\n constructor() {\n this.getKeysForEventDefs = memoize(this._getKeysForEventDefs);\n this.splitDateSelection = memoize(this._splitDateSpan);\n this.splitEventStore = memoize(this._splitEventStore);\n this.splitIndividualUi = memoize(this._splitIndividualUi);\n this.splitEventDrag = memoize(this._splitInteraction);\n this.splitEventResize = memoize(this._splitInteraction);\n this.eventUiBuilders = {}; // TODO: typescript protection\n }\n splitProps(props) {\n let keyInfos = this.getKeyInfo(props);\n let defKeys = this.getKeysForEventDefs(props.eventStore);\n let dateSelections = this.splitDateSelection(props.dateSelection);\n let individualUi = this.splitIndividualUi(props.eventUiBases, defKeys); // the individual *bases*\n let eventStores = this.splitEventStore(props.eventStore, defKeys);\n let eventDrags = this.splitEventDrag(props.eventDrag);\n let eventResizes = this.splitEventResize(props.eventResize);\n let splitProps = {};\n this.eventUiBuilders = mapHash(keyInfos, (info, key) => this.eventUiBuilders[key] || memoize(buildEventUiForKey));\n for (let key in keyInfos) {\n let keyInfo = keyInfos[key];\n let eventStore = eventStores[key] || EMPTY_EVENT_STORE;\n let buildEventUi = this.eventUiBuilders[key];\n splitProps[key] = {\n businessHours: keyInfo.businessHours || props.businessHours,\n dateSelection: dateSelections[key] || null,\n eventStore,\n eventUiBases: buildEventUi(props.eventUiBases[''], keyInfo.ui, individualUi[key]),\n eventSelection: eventStore.instances[props.eventSelection] ? props.eventSelection : '',\n eventDrag: eventDrags[key] || null,\n eventResize: eventResizes[key] || null,\n };\n }\n return splitProps;\n }\n _splitDateSpan(dateSpan) {\n let dateSpans = {};\n if (dateSpan) {\n let keys = this.getKeysForDateSpan(dateSpan);\n for (let key of keys) {\n dateSpans[key] = dateSpan;\n }\n }\n return dateSpans;\n }\n _getKeysForEventDefs(eventStore) {\n return mapHash(eventStore.defs, (eventDef) => this.getKeysForEventDef(eventDef));\n }\n _splitEventStore(eventStore, defKeys) {\n let { defs, instances } = eventStore;\n let splitStores = {};\n for (let defId in defs) {\n for (let key of defKeys[defId]) {\n if (!splitStores[key]) {\n splitStores[key] = createEmptyEventStore();\n }\n splitStores[key].defs[defId] = defs[defId];\n }\n }\n for (let instanceId in instances) {\n let instance = instances[instanceId];\n for (let key of defKeys[instance.defId]) {\n if (splitStores[key]) { // must have already been created\n splitStores[key].instances[instanceId] = instance;\n }\n }\n }\n return splitStores;\n }\n _splitIndividualUi(eventUiBases, defKeys) {\n let splitHashes = {};\n for (let defId in eventUiBases) {\n if (defId) { // not the '' key\n for (let key of defKeys[defId]) {\n if (!splitHashes[key]) {\n splitHashes[key] = {};\n }\n splitHashes[key][defId] = eventUiBases[defId];\n }\n }\n }\n return splitHashes;\n }\n _splitInteraction(interaction) {\n let splitStates = {};\n if (interaction) {\n let affectedStores = this._splitEventStore(interaction.affectedEvents, this._getKeysForEventDefs(interaction.affectedEvents));\n // can't rely on defKeys because event data is mutated\n let mutatedKeysByDefId = this._getKeysForEventDefs(interaction.mutatedEvents);\n let mutatedStores = this._splitEventStore(interaction.mutatedEvents, mutatedKeysByDefId);\n let populate = (key) => {\n if (!splitStates[key]) {\n splitStates[key] = {\n affectedEvents: affectedStores[key] || EMPTY_EVENT_STORE,\n mutatedEvents: mutatedStores[key] || EMPTY_EVENT_STORE,\n isEvent: interaction.isEvent,\n };\n }\n };\n for (let key in affectedStores) {\n populate(key);\n }\n for (let key in mutatedStores) {\n populate(key);\n }\n }\n return splitStates;\n }\n}\nfunction buildEventUiForKey(allUi, eventUiForKey, individualUi) {\n let baseParts = [];\n if (allUi) {\n baseParts.push(allUi);\n }\n if (eventUiForKey) {\n baseParts.push(eventUiForKey);\n }\n let stuff = {\n '': combineEventUis(baseParts),\n };\n if (individualUi) {\n Object.assign(stuff, individualUi);\n }\n return stuff;\n}\n\nfunction parseRange(input, dateEnv) {\n let start = null;\n let end = null;\n if (input.start) {\n start = dateEnv.createMarker(input.start);\n }\n if (input.end) {\n end = dateEnv.createMarker(input.end);\n }\n if (!start && !end) {\n return null;\n }\n if (start && end && end < start) {\n return null;\n }\n return { start, end };\n}\n// SIDE-EFFECT: will mutate ranges.\n// Will return a new array result.\nfunction invertRanges(ranges, constraintRange) {\n let invertedRanges = [];\n let { start } = constraintRange; // the end of the previous range. the start of the new range\n let i;\n let dateRange;\n // ranges need to be in order. required for our date-walking algorithm\n ranges.sort(compareRanges);\n for (i = 0; i < ranges.length; i += 1) {\n dateRange = ranges[i];\n // add the span of time before the event (if there is any)\n if (dateRange.start > start) { // compare millisecond time (skip any ambig logic)\n invertedRanges.push({ start, end: dateRange.start });\n }\n if (dateRange.end > start) {\n start = dateRange.end;\n }\n }\n // add the span of time after the last event (if there is any)\n if (start < constraintRange.end) { // compare millisecond time (skip any ambig logic)\n invertedRanges.push({ start, end: constraintRange.end });\n }\n return invertedRanges;\n}\nfunction compareRanges(range0, range1) {\n return range0.start.valueOf() - range1.start.valueOf(); // earlier ranges go first\n}\nfunction intersectRanges(range0, range1) {\n let { start, end } = range0;\n let newRange = null;\n if (range1.start !== null) {\n if (start === null) {\n start = range1.start;\n }\n else {\n start = new Date(Math.max(start.valueOf(), range1.start.valueOf()));\n }\n }\n if (range1.end != null) {\n if (end === null) {\n end = range1.end;\n }\n else {\n end = new Date(Math.min(end.valueOf(), range1.end.valueOf()));\n }\n }\n if (start === null || end === null || start < end) {\n newRange = { start, end };\n }\n return newRange;\n}\nfunction rangesEqual(range0, range1) {\n return (range0.start === null ? null : range0.start.valueOf()) === (range1.start === null ? null : range1.start.valueOf()) &&\n (range0.end === null ? null : range0.end.valueOf()) === (range1.end === null ? null : range1.end.valueOf());\n}\nfunction rangesIntersect(range0, range1) {\n return (range0.end === null || range1.start === null || range0.end > range1.start) &&\n (range0.start === null || range1.end === null || range0.start < range1.end);\n}\nfunction rangeContainsRange(outerRange, innerRange) {\n return (outerRange.start === null || (innerRange.start !== null && innerRange.start >= outerRange.start)) &&\n (outerRange.end === null || (innerRange.end !== null && innerRange.end <= outerRange.end));\n}\nfunction rangeContainsMarker(range, date) {\n return (range.start === null || date >= range.start) &&\n (range.end === null || date < range.end);\n}\n// If the given date is not within the given range, move it inside.\n// (If it's past the end, make it one millisecond before the end).\nfunction constrainMarkerToRange(date, range) {\n if (range.start != null && date < range.start) {\n return range.start;\n }\n if (range.end != null && date >= range.end) {\n return new Date(range.end.valueOf() - 1);\n }\n return date;\n}\n\nfunction getDateMeta(date, todayRange, nowDate, dateProfile) {\n return {\n dow: date.getUTCDay(),\n isDisabled: Boolean(dateProfile && !rangeContainsMarker(dateProfile.activeRange, date)),\n isOther: Boolean(dateProfile && !rangeContainsMarker(dateProfile.currentRange, date)),\n isToday: Boolean(todayRange && rangeContainsMarker(todayRange, date)),\n isPast: Boolean(nowDate ? (date < nowDate) : todayRange ? (date < todayRange.start) : false),\n isFuture: Boolean(nowDate ? (date > nowDate) : todayRange ? (date >= todayRange.end) : false),\n };\n}\nfunction getDayClassNames(meta, theme) {\n let classNames = [\n 'fc-day',\n `fc-day-${DAY_IDS[meta.dow]}`,\n ];\n if (meta.isDisabled) {\n classNames.push('fc-day-disabled');\n }\n else {\n if (meta.isToday) {\n classNames.push('fc-day-today');\n classNames.push(theme.getClass('today'));\n }\n if (meta.isPast) {\n classNames.push('fc-day-past');\n }\n if (meta.isFuture) {\n classNames.push('fc-day-future');\n }\n if (meta.isOther) {\n classNames.push('fc-day-other');\n }\n }\n return classNames;\n}\nfunction getSlotClassNames(meta, theme) {\n let classNames = [\n 'fc-slot',\n `fc-slot-${DAY_IDS[meta.dow]}`,\n ];\n if (meta.isDisabled) {\n classNames.push('fc-slot-disabled');\n }\n else {\n if (meta.isToday) {\n classNames.push('fc-slot-today');\n classNames.push(theme.getClass('today'));\n }\n if (meta.isPast) {\n classNames.push('fc-slot-past');\n }\n if (meta.isFuture) {\n classNames.push('fc-slot-future');\n }\n }\n return classNames;\n}\n\nconst DAY_FORMAT = createFormatter({ year: 'numeric', month: 'long', day: 'numeric' });\nconst WEEK_FORMAT = createFormatter({ week: 'long' });\nfunction buildNavLinkAttrs(context, dateMarker, viewType = 'day', isTabbable = true) {\n const { dateEnv, options, calendarApi } = context;\n let dateStr = dateEnv.format(dateMarker, viewType === 'week' ? WEEK_FORMAT : DAY_FORMAT);\n if (options.navLinks) {\n let zonedDate = dateEnv.toDate(dateMarker);\n const handleInteraction = (ev) => {\n let customAction = viewType === 'day' ? options.navLinkDayClick :\n viewType === 'week' ? options.navLinkWeekClick : null;\n if (typeof customAction === 'function') {\n customAction.call(calendarApi, dateEnv.toDate(dateMarker), ev);\n }\n else {\n if (typeof customAction === 'string') {\n viewType = customAction;\n }\n calendarApi.zoomTo(dateMarker, viewType);\n }\n };\n return Object.assign({ title: formatWithOrdinals(options.navLinkHint, [dateStr, zonedDate], dateStr), 'data-navlink': '' }, (isTabbable\n ? createAriaClickAttrs(handleInteraction)\n : { onClick: handleInteraction }));\n }\n return { 'aria-label': dateStr };\n}\n\nlet _isRtlScrollbarOnLeft = null;\nfunction getIsRtlScrollbarOnLeft() {\n if (_isRtlScrollbarOnLeft === null) {\n _isRtlScrollbarOnLeft = computeIsRtlScrollbarOnLeft();\n }\n return _isRtlScrollbarOnLeft;\n}\nfunction computeIsRtlScrollbarOnLeft() {\n let outerEl = document.createElement('div');\n applyStyle(outerEl, {\n position: 'absolute',\n top: -1000,\n left: 0,\n border: 0,\n padding: 0,\n overflow: 'scroll',\n direction: 'rtl',\n });\n outerEl.innerHTML = '
';\n document.body.appendChild(outerEl);\n let innerEl = outerEl.firstChild;\n let res = innerEl.getBoundingClientRect().left > outerEl.getBoundingClientRect().left;\n removeElement(outerEl);\n return res;\n}\n\nlet _scrollbarWidths;\nfunction getScrollbarWidths() {\n if (!_scrollbarWidths) {\n _scrollbarWidths = computeScrollbarWidths();\n }\n return _scrollbarWidths;\n}\nfunction computeScrollbarWidths() {\n let el = document.createElement('div');\n el.style.overflow = 'scroll';\n el.style.position = 'absolute';\n el.style.top = '-9999px';\n el.style.left = '-9999px';\n document.body.appendChild(el);\n let res = computeScrollbarWidthsForEl(el);\n document.body.removeChild(el);\n return res;\n}\n// WARNING: will include border\nfunction computeScrollbarWidthsForEl(el) {\n return {\n x: el.offsetHeight - el.clientHeight,\n y: el.offsetWidth - el.clientWidth,\n };\n}\n\nfunction computeEdges(el, getPadding = false) {\n let computedStyle = window.getComputedStyle(el);\n let borderLeft = parseInt(computedStyle.borderLeftWidth, 10) || 0;\n let borderRight = parseInt(computedStyle.borderRightWidth, 10) || 0;\n let borderTop = parseInt(computedStyle.borderTopWidth, 10) || 0;\n let borderBottom = parseInt(computedStyle.borderBottomWidth, 10) || 0;\n let badScrollbarWidths = computeScrollbarWidthsForEl(el); // includes border!\n let scrollbarLeftRight = badScrollbarWidths.y - borderLeft - borderRight;\n let scrollbarBottom = badScrollbarWidths.x - borderTop - borderBottom;\n let res = {\n borderLeft,\n borderRight,\n borderTop,\n borderBottom,\n scrollbarBottom,\n scrollbarLeft: 0,\n scrollbarRight: 0,\n };\n if (getIsRtlScrollbarOnLeft() && computedStyle.direction === 'rtl') { // is the scrollbar on the left side?\n res.scrollbarLeft = scrollbarLeftRight;\n }\n else {\n res.scrollbarRight = scrollbarLeftRight;\n }\n if (getPadding) {\n res.paddingLeft = parseInt(computedStyle.paddingLeft, 10) || 0;\n res.paddingRight = parseInt(computedStyle.paddingRight, 10) || 0;\n res.paddingTop = parseInt(computedStyle.paddingTop, 10) || 0;\n res.paddingBottom = parseInt(computedStyle.paddingBottom, 10) || 0;\n }\n return res;\n}\nfunction computeInnerRect(el, goWithinPadding = false, doFromWindowViewport) {\n let outerRect = doFromWindowViewport ? el.getBoundingClientRect() : computeRect(el);\n let edges = computeEdges(el, goWithinPadding);\n let res = {\n left: outerRect.left + edges.borderLeft + edges.scrollbarLeft,\n right: outerRect.right - edges.borderRight - edges.scrollbarRight,\n top: outerRect.top + edges.borderTop,\n bottom: outerRect.bottom - edges.borderBottom - edges.scrollbarBottom,\n };\n if (goWithinPadding) {\n res.left += edges.paddingLeft;\n res.right -= edges.paddingRight;\n res.top += edges.paddingTop;\n res.bottom -= edges.paddingBottom;\n }\n return res;\n}\nfunction computeRect(el) {\n let rect = el.getBoundingClientRect();\n return {\n left: rect.left + window.pageXOffset,\n top: rect.top + window.pageYOffset,\n right: rect.right + window.pageXOffset,\n bottom: rect.bottom + window.pageYOffset,\n };\n}\nfunction computeClippedClientRect(el) {\n let clippingParents = getClippingParents(el);\n let rect = el.getBoundingClientRect();\n for (let clippingParent of clippingParents) {\n let intersection = intersectRects(rect, clippingParent.getBoundingClientRect());\n if (intersection) {\n rect = intersection;\n }\n else {\n return null;\n }\n }\n return rect;\n}\n// does not return window\nfunction getClippingParents(el) {\n let parents = [];\n while (el instanceof HTMLElement) { // will stop when gets to document or null\n let computedStyle = window.getComputedStyle(el);\n if (computedStyle.position === 'fixed') {\n break;\n }\n if ((/(auto|scroll)/).test(computedStyle.overflow + computedStyle.overflowY + computedStyle.overflowX)) {\n parents.push(el);\n }\n el = el.parentNode;\n }\n return parents;\n}\n\n/*\ngiven a function that resolves a result asynchronously.\nthe function can either call passed-in success and failure callbacks,\nor it can return a promise.\nif you need to pass additional params to func, bind them first.\n*/\nfunction unpromisify(func, normalizedSuccessCallback, normalizedFailureCallback) {\n // guard against success/failure callbacks being called more than once\n // and guard against a promise AND callback being used together.\n let isResolved = false;\n let wrappedSuccess = function (res) {\n if (!isResolved) {\n isResolved = true;\n normalizedSuccessCallback(res);\n }\n };\n let wrappedFailure = function (error) {\n if (!isResolved) {\n isResolved = true;\n normalizedFailureCallback(error);\n }\n };\n let res = func(wrappedSuccess, wrappedFailure);\n if (res && typeof res.then === 'function') {\n res.then(wrappedSuccess, wrappedFailure);\n }\n}\n\nclass Emitter {\n constructor() {\n this.handlers = {};\n this.thisContext = null;\n }\n setThisContext(thisContext) {\n this.thisContext = thisContext;\n }\n setOptions(options) {\n this.options = options;\n }\n on(type, handler) {\n addToHash(this.handlers, type, handler);\n }\n off(type, handler) {\n removeFromHash(this.handlers, type, handler);\n }\n trigger(type, ...args) {\n let attachedHandlers = this.handlers[type] || [];\n let optionHandler = this.options && this.options[type];\n let handlers = [].concat(optionHandler || [], attachedHandlers);\n for (let handler of handlers) {\n handler.apply(this.thisContext, args);\n }\n }\n hasHandlers(type) {\n return Boolean((this.handlers[type] && this.handlers[type].length) ||\n (this.options && this.options[type]));\n }\n}\nfunction addToHash(hash, type, handler) {\n (hash[type] || (hash[type] = []))\n .push(handler);\n}\nfunction removeFromHash(hash, type, handler) {\n if (handler) {\n if (hash[type]) {\n hash[type] = hash[type].filter((func) => func !== handler);\n }\n }\n else {\n delete hash[type]; // remove all handler funcs for this type\n }\n}\n\n/*\nRecords offset information for a set of elements, relative to an origin element.\nCan record the left/right OR the top/bottom OR both.\nProvides methods for querying the cache by position.\n*/\nclass PositionCache {\n constructor(originEl, els, isHorizontal, isVertical) {\n this.els = els;\n let originClientRect = this.originClientRect = originEl.getBoundingClientRect(); // relative to viewport top-left\n if (isHorizontal) {\n this.buildElHorizontals(originClientRect.left);\n }\n if (isVertical) {\n this.buildElVerticals(originClientRect.top);\n }\n }\n // Populates the left/right internal coordinate arrays\n buildElHorizontals(originClientLeft) {\n let lefts = [];\n let rights = [];\n for (let el of this.els) {\n let rect = el.getBoundingClientRect();\n lefts.push(rect.left - originClientLeft);\n rights.push(rect.right - originClientLeft);\n }\n this.lefts = lefts;\n this.rights = rights;\n }\n // Populates the top/bottom internal coordinate arrays\n buildElVerticals(originClientTop) {\n let tops = [];\n let bottoms = [];\n for (let el of this.els) {\n let rect = el.getBoundingClientRect();\n tops.push(rect.top - originClientTop);\n bottoms.push(rect.bottom - originClientTop);\n }\n this.tops = tops;\n this.bottoms = bottoms;\n }\n // Given a left offset (from document left), returns the index of the el that it horizontally intersects.\n // If no intersection is made, returns undefined.\n leftToIndex(leftPosition) {\n let { lefts, rights } = this;\n let len = lefts.length;\n let i;\n for (i = 0; i < len; i += 1) {\n if (leftPosition >= lefts[i] && leftPosition < rights[i]) {\n return i;\n }\n }\n return undefined; // TODO: better\n }\n // Given a top offset (from document top), returns the index of the el that it vertically intersects.\n // If no intersection is made, returns undefined.\n topToIndex(topPosition) {\n let { tops, bottoms } = this;\n let len = tops.length;\n let i;\n for (i = 0; i < len; i += 1) {\n if (topPosition >= tops[i] && topPosition < bottoms[i]) {\n return i;\n }\n }\n return undefined; // TODO: better\n }\n // Gets the width of the element at the given index\n getWidth(leftIndex) {\n return this.rights[leftIndex] - this.lefts[leftIndex];\n }\n // Gets the height of the element at the given index\n getHeight(topIndex) {\n return this.bottoms[topIndex] - this.tops[topIndex];\n }\n similarTo(otherCache) {\n return similarNumArrays(this.tops || [], otherCache.tops || []) &&\n similarNumArrays(this.bottoms || [], otherCache.bottoms || []) &&\n similarNumArrays(this.lefts || [], otherCache.lefts || []) &&\n similarNumArrays(this.rights || [], otherCache.rights || []);\n }\n}\nfunction similarNumArrays(a, b) {\n const len = a.length;\n if (len !== b.length) {\n return false;\n }\n for (let i = 0; i < len; i++) {\n if (Math.round(a[i]) !== Math.round(b[i])) {\n return false;\n }\n }\n return true;\n}\n\n/* eslint max-classes-per-file: \"off\" */\n/*\nAn object for getting/setting scroll-related information for an element.\nInternally, this is done very differently for window versus DOM element,\nso this object serves as a common interface.\n*/\nclass ScrollController {\n getMaxScrollTop() {\n return this.getScrollHeight() - this.getClientHeight();\n }\n getMaxScrollLeft() {\n return this.getScrollWidth() - this.getClientWidth();\n }\n canScrollVertically() {\n return this.getMaxScrollTop() > 0;\n }\n canScrollHorizontally() {\n return this.getMaxScrollLeft() > 0;\n }\n canScrollUp() {\n return this.getScrollTop() > 0;\n }\n canScrollDown() {\n return this.getScrollTop() < this.getMaxScrollTop();\n }\n canScrollLeft() {\n return this.getScrollLeft() > 0;\n }\n canScrollRight() {\n return this.getScrollLeft() < this.getMaxScrollLeft();\n }\n}\nclass ElementScrollController extends ScrollController {\n constructor(el) {\n super();\n this.el = el;\n }\n getScrollTop() {\n return this.el.scrollTop;\n }\n getScrollLeft() {\n return this.el.scrollLeft;\n }\n setScrollTop(top) {\n this.el.scrollTop = top;\n }\n setScrollLeft(left) {\n this.el.scrollLeft = left;\n }\n getScrollWidth() {\n return this.el.scrollWidth;\n }\n getScrollHeight() {\n return this.el.scrollHeight;\n }\n getClientHeight() {\n return this.el.clientHeight;\n }\n getClientWidth() {\n return this.el.clientWidth;\n }\n}\nclass WindowScrollController extends ScrollController {\n getScrollTop() {\n return window.pageYOffset;\n }\n getScrollLeft() {\n return window.pageXOffset;\n }\n setScrollTop(n) {\n window.scroll(window.pageXOffset, n);\n }\n setScrollLeft(n) {\n window.scroll(n, window.pageYOffset);\n }\n getScrollWidth() {\n return document.documentElement.scrollWidth;\n }\n getScrollHeight() {\n return document.documentElement.scrollHeight;\n }\n getClientHeight() {\n return document.documentElement.clientHeight;\n }\n getClientWidth() {\n return document.documentElement.clientWidth;\n }\n}\n\nclass Theme {\n constructor(calendarOptions) {\n if (this.iconOverrideOption) {\n this.setIconOverride(calendarOptions[this.iconOverrideOption]);\n }\n }\n setIconOverride(iconOverrideHash) {\n let iconClassesCopy;\n let buttonName;\n if (typeof iconOverrideHash === 'object' && iconOverrideHash) { // non-null object\n iconClassesCopy = Object.assign({}, this.iconClasses);\n for (buttonName in iconOverrideHash) {\n iconClassesCopy[buttonName] = this.applyIconOverridePrefix(iconOverrideHash[buttonName]);\n }\n this.iconClasses = iconClassesCopy;\n }\n else if (iconOverrideHash === false) {\n this.iconClasses = {};\n }\n }\n applyIconOverridePrefix(className) {\n let prefix = this.iconOverridePrefix;\n if (prefix && className.indexOf(prefix) !== 0) { // if not already present\n className = prefix + className;\n }\n return className;\n }\n getClass(key) {\n return this.classes[key] || '';\n }\n getIconClass(buttonName, isRtl) {\n let className;\n if (isRtl && this.rtlIconClasses) {\n className = this.rtlIconClasses[buttonName] || this.iconClasses[buttonName];\n }\n else {\n className = this.iconClasses[buttonName];\n }\n if (className) {\n return `${this.baseIconClass} ${className}`;\n }\n return '';\n }\n getCustomButtonIconClass(customButtonProps) {\n let className;\n if (this.iconOverrideCustomButtonOption) {\n className = customButtonProps[this.iconOverrideCustomButtonOption];\n if (className) {\n return `${this.baseIconClass} ${this.applyIconOverridePrefix(className)}`;\n }\n }\n return '';\n }\n}\nTheme.prototype.classes = {};\nTheme.prototype.iconClasses = {};\nTheme.prototype.baseIconClass = '';\nTheme.prototype.iconOverridePrefix = '';\n\n/*\nNOTE: this can be a public API, especially createElement for hooks.\nSee examples/typescript-scheduler/src/index.ts\n*/\nfunction flushSync(runBeforeFlush) {\n runBeforeFlush();\n let oldDebounceRendering = preact__WEBPACK_IMPORTED_MODULE_0__.options.debounceRendering; // orig\n let callbackQ = [];\n function execCallbackSync(callback) {\n callbackQ.push(callback);\n }\n preact__WEBPACK_IMPORTED_MODULE_0__.options.debounceRendering = execCallbackSync;\n preact__WEBPACK_IMPORTED_MODULE_0__.render(preact__WEBPACK_IMPORTED_MODULE_0__.createElement(FakeComponent, {}), document.createElement('div'));\n while (callbackQ.length) {\n callbackQ.shift()();\n }\n preact__WEBPACK_IMPORTED_MODULE_0__.options.debounceRendering = oldDebounceRendering;\n}\nclass FakeComponent extends preact__WEBPACK_IMPORTED_MODULE_0__.Component {\n render() { return preact__WEBPACK_IMPORTED_MODULE_0__.createElement('div', {}); }\n componentDidMount() { this.setState({}); }\n}\n// TODO: use preact/compat instead?\nfunction createContext(defaultValue) {\n let ContextType = preact__WEBPACK_IMPORTED_MODULE_0__.createContext(defaultValue);\n let origProvider = ContextType.Provider;\n ContextType.Provider = function () {\n let isNew = !this.getChildContext;\n let children = origProvider.apply(this, arguments); // eslint-disable-line prefer-rest-params\n if (isNew) {\n let subs = [];\n this.shouldComponentUpdate = (_props) => {\n if (this.props.value !== _props.value) {\n subs.forEach((c) => {\n c.context = _props.value;\n c.forceUpdate();\n });\n }\n };\n this.sub = (c) => {\n subs.push(c);\n let old = c.componentWillUnmount;\n c.componentWillUnmount = () => {\n subs.splice(subs.indexOf(c), 1);\n old && old.call(c);\n };\n };\n }\n return children;\n };\n return ContextType;\n}\n\nclass ScrollResponder {\n constructor(execFunc, emitter, scrollTime, scrollTimeReset) {\n this.execFunc = execFunc;\n this.emitter = emitter;\n this.scrollTime = scrollTime;\n this.scrollTimeReset = scrollTimeReset;\n this.handleScrollRequest = (request) => {\n this.queuedRequest = Object.assign({}, this.queuedRequest || {}, request);\n this.drain();\n };\n emitter.on('_scrollRequest', this.handleScrollRequest);\n this.fireInitialScroll();\n }\n detach() {\n this.emitter.off('_scrollRequest', this.handleScrollRequest);\n }\n update(isDatesNew) {\n if (isDatesNew && this.scrollTimeReset) {\n this.fireInitialScroll(); // will drain\n }\n else {\n this.drain();\n }\n }\n fireInitialScroll() {\n this.handleScrollRequest({\n time: this.scrollTime,\n });\n }\n drain() {\n if (this.queuedRequest && this.execFunc(this.queuedRequest)) {\n this.queuedRequest = null;\n }\n }\n}\n\nconst ViewContextType = createContext({}); // for Components\nfunction buildViewContext(viewSpec, viewApi, viewOptions, dateProfileGenerator, dateEnv, theme, pluginHooks, dispatch, getCurrentData, emitter, calendarApi, registerInteractiveComponent, unregisterInteractiveComponent) {\n return {\n dateEnv,\n options: viewOptions,\n pluginHooks,\n emitter,\n dispatch,\n getCurrentData,\n calendarApi,\n viewSpec,\n viewApi,\n dateProfileGenerator,\n theme,\n isRtl: viewOptions.direction === 'rtl',\n addResizeHandler(handler) {\n emitter.on('_resize', handler);\n },\n removeResizeHandler(handler) {\n emitter.off('_resize', handler);\n },\n createScrollResponder(execFunc) {\n return new ScrollResponder(execFunc, emitter, createDuration(viewOptions.scrollTime), viewOptions.scrollTimeReset);\n },\n registerInteractiveComponent,\n unregisterInteractiveComponent,\n };\n}\n\n/* eslint max-classes-per-file: off */\nclass PureComponent extends preact__WEBPACK_IMPORTED_MODULE_0__.Component {\n shouldComponentUpdate(nextProps, nextState) {\n if (this.debug) {\n // eslint-disable-next-line no-console\n console.log(getUnequalProps(nextProps, this.props), getUnequalProps(nextState, this.state));\n }\n return !compareObjs(this.props, nextProps, this.propEquality) ||\n !compareObjs(this.state, nextState, this.stateEquality);\n }\n // HACK for freakin' React StrictMode\n safeSetState(newState) {\n if (!compareObjs(this.state, Object.assign(Object.assign({}, this.state), newState), this.stateEquality)) {\n this.setState(newState);\n }\n }\n}\nPureComponent.addPropsEquality = addPropsEquality;\nPureComponent.addStateEquality = addStateEquality;\nPureComponent.contextType = ViewContextType;\nPureComponent.prototype.propEquality = {};\nPureComponent.prototype.stateEquality = {};\nclass BaseComponent extends PureComponent {\n}\nBaseComponent.contextType = ViewContextType;\nfunction addPropsEquality(propEquality) {\n let hash = Object.create(this.prototype.propEquality);\n Object.assign(hash, propEquality);\n this.prototype.propEquality = hash;\n}\nfunction addStateEquality(stateEquality) {\n let hash = Object.create(this.prototype.stateEquality);\n Object.assign(hash, stateEquality);\n this.prototype.stateEquality = hash;\n}\n// use other one\nfunction setRef(ref, current) {\n if (typeof ref === 'function') {\n ref(current);\n }\n else if (ref) {\n // see https://github.com/facebook/react/issues/13029\n ref.current = current;\n }\n}\n\n/*\nan INTERACTABLE date component\n\nPURPOSES:\n- hook up to fg, fill, and mirror renderers\n- interface for dragging and hits\n*/\nclass DateComponent extends BaseComponent {\n constructor() {\n super(...arguments);\n this.uid = guid();\n }\n // Hit System\n // -----------------------------------------------------------------------------------------------------------------\n prepareHits() {\n }\n queryHit(positionLeft, positionTop, elWidth, elHeight) {\n return null; // this should be abstract\n }\n // Pointer Interaction Utils\n // -----------------------------------------------------------------------------------------------------------------\n isValidSegDownEl(el) {\n return !this.props.eventDrag && // HACK\n !this.props.eventResize && // HACK\n !elementClosest(el, '.fc-event-mirror');\n }\n isValidDateDownEl(el) {\n return !elementClosest(el, '.fc-event:not(.fc-bg-event)') &&\n !elementClosest(el, '.fc-more-link') && // a \"more..\" link\n !elementClosest(el, 'a[data-navlink]') && // a clickable nav link\n !elementClosest(el, '.fc-popover'); // hack\n }\n}\n\nfunction reduceCurrentDate(currentDate, action) {\n switch (action.type) {\n case 'CHANGE_DATE':\n return action.dateMarker;\n default:\n return currentDate;\n }\n}\nfunction getInitialDate(options, dateEnv) {\n let initialDateInput = options.initialDate;\n // compute the initial ambig-timezone date\n if (initialDateInput != null) {\n return dateEnv.createMarker(initialDateInput);\n }\n return getNow(options.now, dateEnv); // getNow already returns unzoned\n}\nfunction getNow(nowInput, dateEnv) {\n if (typeof nowInput === 'function') {\n nowInput = nowInput();\n }\n if (nowInput == null) {\n return dateEnv.createNowMarker();\n }\n return dateEnv.createMarker(nowInput);\n}\n\nclass DateProfileGenerator {\n constructor(props) {\n this.props = props;\n this.nowDate = getNow(props.nowInput, props.dateEnv);\n this.initHiddenDays();\n }\n /* Date Range Computation\n ------------------------------------------------------------------------------------------------------------------*/\n // Builds a structure with info about what the dates/ranges will be for the \"prev\" view.\n buildPrev(currentDateProfile, currentDate, forceToValid) {\n let { dateEnv } = this.props;\n let prevDate = dateEnv.subtract(dateEnv.startOf(currentDate, currentDateProfile.currentRangeUnit), // important for start-of-month\n currentDateProfile.dateIncrement);\n return this.build(prevDate, -1, forceToValid);\n }\n // Builds a structure with info about what the dates/ranges will be for the \"next\" view.\n buildNext(currentDateProfile, currentDate, forceToValid) {\n let { dateEnv } = this.props;\n let nextDate = dateEnv.add(dateEnv.startOf(currentDate, currentDateProfile.currentRangeUnit), // important for start-of-month\n currentDateProfile.dateIncrement);\n return this.build(nextDate, 1, forceToValid);\n }\n // Builds a structure holding dates/ranges for rendering around the given date.\n // Optional direction param indicates whether the date is being incremented/decremented\n // from its previous value. decremented = -1, incremented = 1 (default).\n build(currentDate, direction, forceToValid = true) {\n let { props } = this;\n let validRange;\n let currentInfo;\n let isRangeAllDay;\n let renderRange;\n let activeRange;\n let isValid;\n validRange = this.buildValidRange();\n validRange = this.trimHiddenDays(validRange);\n if (forceToValid) {\n currentDate = constrainMarkerToRange(currentDate, validRange);\n }\n currentInfo = this.buildCurrentRangeInfo(currentDate, direction);\n isRangeAllDay = /^(year|month|week|day)$/.test(currentInfo.unit);\n renderRange = this.buildRenderRange(this.trimHiddenDays(currentInfo.range), currentInfo.unit, isRangeAllDay);\n renderRange = this.trimHiddenDays(renderRange);\n activeRange = renderRange;\n if (!props.showNonCurrentDates) {\n activeRange = intersectRanges(activeRange, currentInfo.range);\n }\n activeRange = this.adjustActiveRange(activeRange);\n activeRange = intersectRanges(activeRange, validRange); // might return null\n // it's invalid if the originally requested date is not contained,\n // or if the range is completely outside of the valid range.\n isValid = rangesIntersect(currentInfo.range, validRange);\n return {\n // constraint for where prev/next operations can go and where events can be dragged/resized to.\n // an object with optional start and end properties.\n validRange,\n // range the view is formally responsible for.\n // for example, a month view might have 1st-31st, excluding padded dates\n currentRange: currentInfo.range,\n // name of largest unit being displayed, like \"month\" or \"week\"\n currentRangeUnit: currentInfo.unit,\n isRangeAllDay,\n // dates that display events and accept drag-n-drop\n // will be `null` if no dates accept events\n activeRange,\n // date range with a rendered skeleton\n // includes not-active days that need some sort of DOM\n renderRange,\n // Duration object that denotes the first visible time of any given day\n slotMinTime: props.slotMinTime,\n // Duration object that denotes the exclusive visible end time of any given day\n slotMaxTime: props.slotMaxTime,\n isValid,\n // how far the current date will move for a prev/next operation\n dateIncrement: this.buildDateIncrement(currentInfo.duration),\n // pass a fallback (might be null) ^\n };\n }\n // Builds an object with optional start/end properties.\n // Indicates the minimum/maximum dates to display.\n // not responsible for trimming hidden days.\n buildValidRange() {\n let input = this.props.validRangeInput;\n let simpleInput = typeof input === 'function'\n ? input.call(this.props.calendarApi, this.nowDate)\n : input;\n return this.refineRange(simpleInput) ||\n { start: null, end: null }; // completely open-ended\n }\n // Builds a structure with info about the \"current\" range, the range that is\n // highlighted as being the current month for example.\n // See build() for a description of `direction`.\n // Guaranteed to have `range` and `unit` properties. `duration` is optional.\n buildCurrentRangeInfo(date, direction) {\n let { props } = this;\n let duration = null;\n let unit = null;\n let range = null;\n let dayCount;\n if (props.duration) {\n duration = props.duration;\n unit = props.durationUnit;\n range = this.buildRangeFromDuration(date, direction, duration, unit);\n }\n else if ((dayCount = this.props.dayCount)) {\n unit = 'day';\n range = this.buildRangeFromDayCount(date, direction, dayCount);\n }\n else if ((range = this.buildCustomVisibleRange(date))) {\n unit = props.dateEnv.greatestWholeUnit(range.start, range.end).unit;\n }\n else {\n duration = this.getFallbackDuration();\n unit = greatestDurationDenominator(duration).unit;\n range = this.buildRangeFromDuration(date, direction, duration, unit);\n }\n return { duration, unit, range };\n }\n getFallbackDuration() {\n return createDuration({ day: 1 });\n }\n // Returns a new activeRange to have time values (un-ambiguate)\n // slotMinTime or slotMaxTime causes the range to expand.\n adjustActiveRange(range) {\n let { dateEnv, usesMinMaxTime, slotMinTime, slotMaxTime } = this.props;\n let { start, end } = range;\n if (usesMinMaxTime) {\n // expand active range if slotMinTime is negative (why not when positive?)\n if (asRoughDays(slotMinTime) < 0) {\n start = startOfDay(start); // necessary?\n start = dateEnv.add(start, slotMinTime);\n }\n // expand active range if slotMaxTime is beyond one day (why not when negative?)\n if (asRoughDays(slotMaxTime) > 1) {\n end = startOfDay(end); // necessary?\n end = addDays(end, -1);\n end = dateEnv.add(end, slotMaxTime);\n }\n }\n return { start, end };\n }\n // Builds the \"current\" range when it is specified as an explicit duration.\n // `unit` is the already-computed greatestDurationDenominator unit of duration.\n buildRangeFromDuration(date, direction, duration, unit) {\n let { dateEnv, dateAlignment } = this.props;\n let start;\n let end;\n let res;\n // compute what the alignment should be\n if (!dateAlignment) {\n let { dateIncrement } = this.props;\n if (dateIncrement) {\n // use the smaller of the two units\n if (asRoughMs(dateIncrement) < asRoughMs(duration)) {\n dateAlignment = greatestDurationDenominator(dateIncrement).unit;\n }\n else {\n dateAlignment = unit;\n }\n }\n else {\n dateAlignment = unit;\n }\n }\n // if the view displays a single day or smaller\n if (asRoughDays(duration) <= 1) {\n if (this.isHiddenDay(start)) {\n start = this.skipHiddenDays(start, direction);\n start = startOfDay(start);\n }\n }\n function computeRes() {\n start = dateEnv.startOf(date, dateAlignment);\n end = dateEnv.add(start, duration);\n res = { start, end };\n }\n computeRes();\n // if range is completely enveloped by hidden days, go past the hidden days\n if (!this.trimHiddenDays(res)) {\n date = this.skipHiddenDays(date, direction);\n computeRes();\n }\n return res;\n }\n // Builds the \"current\" range when a dayCount is specified.\n buildRangeFromDayCount(date, direction, dayCount) {\n let { dateEnv, dateAlignment } = this.props;\n let runningCount = 0;\n let start = date;\n let end;\n if (dateAlignment) {\n start = dateEnv.startOf(start, dateAlignment);\n }\n start = startOfDay(start);\n start = this.skipHiddenDays(start, direction);\n end = start;\n do {\n end = addDays(end, 1);\n if (!this.isHiddenDay(end)) {\n runningCount += 1;\n }\n } while (runningCount < dayCount);\n return { start, end };\n }\n // Builds a normalized range object for the \"visible\" range,\n // which is a way to define the currentRange and activeRange at the same time.\n buildCustomVisibleRange(date) {\n let { props } = this;\n let input = props.visibleRangeInput;\n let simpleInput = typeof input === 'function'\n ? input.call(props.calendarApi, props.dateEnv.toDate(date))\n : input;\n let range = this.refineRange(simpleInput);\n if (range && (range.start == null || range.end == null)) {\n return null;\n }\n return range;\n }\n // Computes the range that will represent the element/cells for *rendering*,\n // but which may have voided days/times.\n // not responsible for trimming hidden days.\n buildRenderRange(currentRange, currentRangeUnit, isRangeAllDay) {\n return currentRange;\n }\n // Compute the duration value that should be added/substracted to the current date\n // when a prev/next operation happens.\n buildDateIncrement(fallback) {\n let { dateIncrement } = this.props;\n let customAlignment;\n if (dateIncrement) {\n return dateIncrement;\n }\n if ((customAlignment = this.props.dateAlignment)) {\n return createDuration(1, customAlignment);\n }\n if (fallback) {\n return fallback;\n }\n return createDuration({ days: 1 });\n }\n refineRange(rangeInput) {\n if (rangeInput) {\n let range = parseRange(rangeInput, this.props.dateEnv);\n if (range) {\n range = computeVisibleDayRange(range);\n }\n return range;\n }\n return null;\n }\n /* Hidden Days\n ------------------------------------------------------------------------------------------------------------------*/\n // Initializes internal variables related to calculating hidden days-of-week\n initHiddenDays() {\n let hiddenDays = this.props.hiddenDays || []; // array of day-of-week indices that are hidden\n let isHiddenDayHash = []; // is the day-of-week hidden? (hash with day-of-week-index -> bool)\n let dayCnt = 0;\n let i;\n if (this.props.weekends === false) {\n hiddenDays.push(0, 6); // 0=sunday, 6=saturday\n }\n for (i = 0; i < 7; i += 1) {\n if (!(isHiddenDayHash[i] = hiddenDays.indexOf(i) !== -1)) {\n dayCnt += 1;\n }\n }\n if (!dayCnt) {\n throw new Error('invalid hiddenDays'); // all days were hidden? bad.\n }\n this.isHiddenDayHash = isHiddenDayHash;\n }\n // Remove days from the beginning and end of the range that are computed as hidden.\n // If the whole range is trimmed off, returns null\n trimHiddenDays(range) {\n let { start, end } = range;\n if (start) {\n start = this.skipHiddenDays(start);\n }\n if (end) {\n end = this.skipHiddenDays(end, -1, true);\n }\n if (start == null || end == null || start < end) {\n return { start, end };\n }\n return null;\n }\n // Is the current day hidden?\n // `day` is a day-of-week index (0-6), or a Date (used for UTC)\n isHiddenDay(day) {\n if (day instanceof Date) {\n day = day.getUTCDay();\n }\n return this.isHiddenDayHash[day];\n }\n // Incrementing the current day until it is no longer a hidden day, returning a copy.\n // DOES NOT CONSIDER validRange!\n // If the initial value of `date` is not a hidden day, don't do anything.\n // Pass `isExclusive` as `true` if you are dealing with an end date.\n // `inc` defaults to `1` (increment one day forward each time)\n skipHiddenDays(date, inc = 1, isExclusive = false) {\n while (this.isHiddenDayHash[(date.getUTCDay() + (isExclusive ? inc : 0) + 7) % 7]) {\n date = addDays(date, inc);\n }\n return date;\n }\n}\n\nfunction triggerDateSelect(selection, pev, context) {\n context.emitter.trigger('select', Object.assign(Object.assign({}, buildDateSpanApiWithContext(selection, context)), { jsEvent: pev ? pev.origEvent : null, view: context.viewApi || context.calendarApi.view }));\n}\nfunction triggerDateUnselect(pev, context) {\n context.emitter.trigger('unselect', {\n jsEvent: pev ? pev.origEvent : null,\n view: context.viewApi || context.calendarApi.view,\n });\n}\nfunction buildDateSpanApiWithContext(dateSpan, context) {\n let props = {};\n for (let transform of context.pluginHooks.dateSpanTransforms) {\n Object.assign(props, transform(dateSpan, context));\n }\n Object.assign(props, buildDateSpanApi(dateSpan, context.dateEnv));\n return props;\n}\n// Given an event's allDay status and start date, return what its fallback end date should be.\n// TODO: rename to computeDefaultEventEnd\nfunction getDefaultEventEnd(allDay, marker, context) {\n let { dateEnv, options } = context;\n let end = marker;\n if (allDay) {\n end = startOfDay(end);\n end = dateEnv.add(end, options.defaultAllDayEventDuration);\n }\n else {\n end = dateEnv.add(end, options.defaultTimedEventDuration);\n }\n return end;\n}\n\n// applies the mutation to ALL defs/instances within the event store\nfunction applyMutationToEventStore(eventStore, eventConfigBase, mutation, context) {\n let eventConfigs = compileEventUis(eventStore.defs, eventConfigBase);\n let dest = createEmptyEventStore();\n for (let defId in eventStore.defs) {\n let def = eventStore.defs[defId];\n dest.defs[defId] = applyMutationToEventDef(def, eventConfigs[defId], mutation, context);\n }\n for (let instanceId in eventStore.instances) {\n let instance = eventStore.instances[instanceId];\n let def = dest.defs[instance.defId]; // important to grab the newly modified def\n dest.instances[instanceId] = applyMutationToEventInstance(instance, def, eventConfigs[instance.defId], mutation, context);\n }\n return dest;\n}\nfunction applyMutationToEventDef(eventDef, eventConfig, mutation, context) {\n let standardProps = mutation.standardProps || {};\n // if hasEnd has not been specified, guess a good value based on deltas.\n // if duration will change, there's no way the default duration will persist,\n // and thus, we need to mark the event as having a real end\n if (standardProps.hasEnd == null &&\n eventConfig.durationEditable &&\n (mutation.startDelta || mutation.endDelta)) {\n standardProps.hasEnd = true; // TODO: is this mutation okay?\n }\n let copy = Object.assign(Object.assign(Object.assign({}, eventDef), standardProps), { ui: Object.assign(Object.assign({}, eventDef.ui), standardProps.ui) });\n if (mutation.extendedProps) {\n copy.extendedProps = Object.assign(Object.assign({}, copy.extendedProps), mutation.extendedProps);\n }\n for (let applier of context.pluginHooks.eventDefMutationAppliers) {\n applier(copy, mutation, context);\n }\n if (!copy.hasEnd && context.options.forceEventDuration) {\n copy.hasEnd = true;\n }\n return copy;\n}\nfunction applyMutationToEventInstance(eventInstance, eventDef, // must first be modified by applyMutationToEventDef\neventConfig, mutation, context) {\n let { dateEnv } = context;\n let forceAllDay = mutation.standardProps && mutation.standardProps.allDay === true;\n let clearEnd = mutation.standardProps && mutation.standardProps.hasEnd === false;\n let copy = Object.assign({}, eventInstance);\n if (forceAllDay) {\n copy.range = computeAlignedDayRange(copy.range);\n }\n if (mutation.datesDelta && eventConfig.startEditable) {\n copy.range = {\n start: dateEnv.add(copy.range.start, mutation.datesDelta),\n end: dateEnv.add(copy.range.end, mutation.datesDelta),\n };\n }\n if (mutation.startDelta && eventConfig.durationEditable) {\n copy.range = {\n start: dateEnv.add(copy.range.start, mutation.startDelta),\n end: copy.range.end,\n };\n }\n if (mutation.endDelta && eventConfig.durationEditable) {\n copy.range = {\n start: copy.range.start,\n end: dateEnv.add(copy.range.end, mutation.endDelta),\n };\n }\n if (clearEnd) {\n copy.range = {\n start: copy.range.start,\n end: getDefaultEventEnd(eventDef.allDay, copy.range.start, context),\n };\n }\n // in case event was all-day but the supplied deltas were not\n // better util for this?\n if (eventDef.allDay) {\n copy.range = {\n start: startOfDay(copy.range.start),\n end: startOfDay(copy.range.end),\n };\n }\n // handle invalid durations\n if (copy.range.end < copy.range.start) {\n copy.range.end = getDefaultEventEnd(eventDef.allDay, copy.range.start, context);\n }\n return copy;\n}\n\nclass EventSourceImpl {\n constructor(context, internalEventSource) {\n this.context = context;\n this.internalEventSource = internalEventSource;\n }\n remove() {\n this.context.dispatch({\n type: 'REMOVE_EVENT_SOURCE',\n sourceId: this.internalEventSource.sourceId,\n });\n }\n refetch() {\n this.context.dispatch({\n type: 'FETCH_EVENT_SOURCES',\n sourceIds: [this.internalEventSource.sourceId],\n isRefetch: true,\n });\n }\n get id() {\n return this.internalEventSource.publicId;\n }\n get url() {\n return this.internalEventSource.meta.url;\n }\n get format() {\n return this.internalEventSource.meta.format; // TODO: bad. not guaranteed\n }\n}\n\nclass EventImpl {\n // instance will be null if expressing a recurring event that has no current instances,\n // OR if trying to validate an incoming external event that has no dates assigned\n constructor(context, def, instance) {\n this._context = context;\n this._def = def;\n this._instance = instance || null;\n }\n /*\n TODO: make event struct more responsible for this\n */\n setProp(name, val) {\n if (name in EVENT_DATE_REFINERS) {\n console.warn('Could not set date-related prop \\'name\\'. Use one of the date-related methods instead.');\n // TODO: make proper aliasing system?\n }\n else if (name === 'id') {\n val = EVENT_NON_DATE_REFINERS[name](val);\n this.mutate({\n standardProps: { publicId: val }, // hardcoded internal name\n });\n }\n else if (name in EVENT_NON_DATE_REFINERS) {\n val = EVENT_NON_DATE_REFINERS[name](val);\n this.mutate({\n standardProps: { [name]: val },\n });\n }\n else if (name in EVENT_UI_REFINERS) {\n let ui = EVENT_UI_REFINERS[name](val);\n if (name === 'color') {\n ui = { backgroundColor: val, borderColor: val };\n }\n else if (name === 'editable') {\n ui = { startEditable: val, durationEditable: val };\n }\n else {\n ui = { [name]: val };\n }\n this.mutate({\n standardProps: { ui },\n });\n }\n else {\n console.warn(`Could not set prop '${name}'. Use setExtendedProp instead.`);\n }\n }\n setExtendedProp(name, val) {\n this.mutate({\n extendedProps: { [name]: val },\n });\n }\n setStart(startInput, options = {}) {\n let { dateEnv } = this._context;\n let start = dateEnv.createMarker(startInput);\n if (start && this._instance) { // TODO: warning if parsed bad\n let instanceRange = this._instance.range;\n let startDelta = diffDates(instanceRange.start, start, dateEnv, options.granularity); // what if parsed bad!?\n if (options.maintainDuration) {\n this.mutate({ datesDelta: startDelta });\n }\n else {\n this.mutate({ startDelta });\n }\n }\n }\n setEnd(endInput, options = {}) {\n let { dateEnv } = this._context;\n let end;\n if (endInput != null) {\n end = dateEnv.createMarker(endInput);\n if (!end) {\n return; // TODO: warning if parsed bad\n }\n }\n if (this._instance) {\n if (end) {\n let endDelta = diffDates(this._instance.range.end, end, dateEnv, options.granularity);\n this.mutate({ endDelta });\n }\n else {\n this.mutate({ standardProps: { hasEnd: false } });\n }\n }\n }\n setDates(startInput, endInput, options = {}) {\n let { dateEnv } = this._context;\n let standardProps = { allDay: options.allDay };\n let start = dateEnv.createMarker(startInput);\n let end;\n if (!start) {\n return; // TODO: warning if parsed bad\n }\n if (endInput != null) {\n end = dateEnv.createMarker(endInput);\n if (!end) { // TODO: warning if parsed bad\n return;\n }\n }\n if (this._instance) {\n let instanceRange = this._instance.range;\n // when computing the diff for an event being converted to all-day,\n // compute diff off of the all-day values the way event-mutation does.\n if (options.allDay === true) {\n instanceRange = computeAlignedDayRange(instanceRange);\n }\n let startDelta = diffDates(instanceRange.start, start, dateEnv, options.granularity);\n if (end) {\n let endDelta = diffDates(instanceRange.end, end, dateEnv, options.granularity);\n if (durationsEqual(startDelta, endDelta)) {\n this.mutate({ datesDelta: startDelta, standardProps });\n }\n else {\n this.mutate({ startDelta, endDelta, standardProps });\n }\n }\n else { // means \"clear the end\"\n standardProps.hasEnd = false;\n this.mutate({ datesDelta: startDelta, standardProps });\n }\n }\n }\n moveStart(deltaInput) {\n let delta = createDuration(deltaInput);\n if (delta) { // TODO: warning if parsed bad\n this.mutate({ startDelta: delta });\n }\n }\n moveEnd(deltaInput) {\n let delta = createDuration(deltaInput);\n if (delta) { // TODO: warning if parsed bad\n this.mutate({ endDelta: delta });\n }\n }\n moveDates(deltaInput) {\n let delta = createDuration(deltaInput);\n if (delta) { // TODO: warning if parsed bad\n this.mutate({ datesDelta: delta });\n }\n }\n setAllDay(allDay, options = {}) {\n let standardProps = { allDay };\n let { maintainDuration } = options;\n if (maintainDuration == null) {\n maintainDuration = this._context.options.allDayMaintainDuration;\n }\n if (this._def.allDay !== allDay) {\n standardProps.hasEnd = maintainDuration;\n }\n this.mutate({ standardProps });\n }\n formatRange(formatInput) {\n let { dateEnv } = this._context;\n let instance = this._instance;\n let formatter = createFormatter(formatInput);\n if (this._def.hasEnd) {\n return dateEnv.formatRange(instance.range.start, instance.range.end, formatter, {\n forcedStartTzo: instance.forcedStartTzo,\n forcedEndTzo: instance.forcedEndTzo,\n });\n }\n return dateEnv.format(instance.range.start, formatter, {\n forcedTzo: instance.forcedStartTzo,\n });\n }\n mutate(mutation) {\n let instance = this._instance;\n if (instance) {\n let def = this._def;\n let context = this._context;\n let { eventStore } = context.getCurrentData();\n let relevantEvents = getRelevantEvents(eventStore, instance.instanceId);\n let eventConfigBase = {\n '': {\n display: '',\n startEditable: true,\n durationEditable: true,\n constraints: [],\n overlap: null,\n allows: [],\n backgroundColor: '',\n borderColor: '',\n textColor: '',\n classNames: [],\n },\n };\n relevantEvents = applyMutationToEventStore(relevantEvents, eventConfigBase, mutation, context);\n let oldEvent = new EventImpl(context, def, instance); // snapshot\n this._def = relevantEvents.defs[def.defId];\n this._instance = relevantEvents.instances[instance.instanceId];\n context.dispatch({\n type: 'MERGE_EVENTS',\n eventStore: relevantEvents,\n });\n context.emitter.trigger('eventChange', {\n oldEvent,\n event: this,\n relatedEvents: buildEventApis(relevantEvents, context, instance),\n revert() {\n context.dispatch({\n type: 'RESET_EVENTS',\n eventStore, // the ORIGINAL store\n });\n },\n });\n }\n }\n remove() {\n let context = this._context;\n let asStore = eventApiToStore(this);\n context.dispatch({\n type: 'REMOVE_EVENTS',\n eventStore: asStore,\n });\n context.emitter.trigger('eventRemove', {\n event: this,\n relatedEvents: [],\n revert() {\n context.dispatch({\n type: 'MERGE_EVENTS',\n eventStore: asStore,\n });\n },\n });\n }\n get source() {\n let { sourceId } = this._def;\n if (sourceId) {\n return new EventSourceImpl(this._context, this._context.getCurrentData().eventSources[sourceId]);\n }\n return null;\n }\n get start() {\n return this._instance ?\n this._context.dateEnv.toDate(this._instance.range.start) :\n null;\n }\n get end() {\n return (this._instance && this._def.hasEnd) ?\n this._context.dateEnv.toDate(this._instance.range.end) :\n null;\n }\n get startStr() {\n let instance = this._instance;\n if (instance) {\n return this._context.dateEnv.formatIso(instance.range.start, {\n omitTime: this._def.allDay,\n forcedTzo: instance.forcedStartTzo,\n });\n }\n return '';\n }\n get endStr() {\n let instance = this._instance;\n if (instance && this._def.hasEnd) {\n return this._context.dateEnv.formatIso(instance.range.end, {\n omitTime: this._def.allDay,\n forcedTzo: instance.forcedEndTzo,\n });\n }\n return '';\n }\n // computable props that all access the def\n // TODO: find a TypeScript-compatible way to do this at scale\n get id() { return this._def.publicId; }\n get groupId() { return this._def.groupId; }\n get allDay() { return this._def.allDay; }\n get title() { return this._def.title; }\n get url() { return this._def.url; }\n get display() { return this._def.ui.display || 'auto'; } // bad. just normalize the type earlier\n get startEditable() { return this._def.ui.startEditable; }\n get durationEditable() { return this._def.ui.durationEditable; }\n get constraint() { return this._def.ui.constraints[0] || null; }\n get overlap() { return this._def.ui.overlap; }\n get allow() { return this._def.ui.allows[0] || null; }\n get backgroundColor() { return this._def.ui.backgroundColor; }\n get borderColor() { return this._def.ui.borderColor; }\n get textColor() { return this._def.ui.textColor; }\n // NOTE: user can't modify these because Object.freeze was called in event-def parsing\n get classNames() { return this._def.ui.classNames; }\n get extendedProps() { return this._def.extendedProps; }\n toPlainObject(settings = {}) {\n let def = this._def;\n let { ui } = def;\n let { startStr, endStr } = this;\n let res = {};\n if (def.title) {\n res.title = def.title;\n }\n if (startStr) {\n res.start = startStr;\n }\n if (endStr) {\n res.end = endStr;\n }\n if (def.publicId) {\n res.id = def.publicId;\n }\n if (def.groupId) {\n res.groupId = def.groupId;\n }\n if (def.url) {\n res.url = def.url;\n }\n if (ui.display && ui.display !== 'auto') {\n res.display = ui.display;\n }\n // TODO: what about recurring-event properties???\n // TODO: include startEditable/durationEditable/constraint/overlap/allow\n if (settings.collapseColor && ui.backgroundColor && ui.backgroundColor === ui.borderColor) {\n res.color = ui.backgroundColor;\n }\n else {\n if (ui.backgroundColor) {\n res.backgroundColor = ui.backgroundColor;\n }\n if (ui.borderColor) {\n res.borderColor = ui.borderColor;\n }\n }\n if (ui.textColor) {\n res.textColor = ui.textColor;\n }\n if (ui.classNames.length) {\n res.classNames = ui.classNames;\n }\n if (Object.keys(def.extendedProps).length) {\n if (settings.collapseExtendedProps) {\n Object.assign(res, def.extendedProps);\n }\n else {\n res.extendedProps = def.extendedProps;\n }\n }\n return res;\n }\n toJSON() {\n return this.toPlainObject();\n }\n}\nfunction eventApiToStore(eventApi) {\n let def = eventApi._def;\n let instance = eventApi._instance;\n return {\n defs: { [def.defId]: def },\n instances: instance\n ? { [instance.instanceId]: instance }\n : {},\n };\n}\nfunction buildEventApis(eventStore, context, excludeInstance) {\n let { defs, instances } = eventStore;\n let eventApis = [];\n let excludeInstanceId = excludeInstance ? excludeInstance.instanceId : '';\n for (let id in instances) {\n let instance = instances[id];\n let def = defs[instance.defId];\n if (instance.instanceId !== excludeInstanceId) {\n eventApis.push(new EventImpl(context, def, instance));\n }\n }\n return eventApis;\n}\n\n/*\nSpecifying nextDayThreshold signals that all-day ranges should be sliced.\n*/\nfunction sliceEventStore(eventStore, eventUiBases, framingRange, nextDayThreshold) {\n let inverseBgByGroupId = {};\n let inverseBgByDefId = {};\n let defByGroupId = {};\n let bgRanges = [];\n let fgRanges = [];\n let eventUis = compileEventUis(eventStore.defs, eventUiBases);\n for (let defId in eventStore.defs) {\n let def = eventStore.defs[defId];\n let ui = eventUis[def.defId];\n if (ui.display === 'inverse-background') {\n if (def.groupId) {\n inverseBgByGroupId[def.groupId] = [];\n if (!defByGroupId[def.groupId]) {\n defByGroupId[def.groupId] = def;\n }\n }\n else {\n inverseBgByDefId[defId] = [];\n }\n }\n }\n for (let instanceId in eventStore.instances) {\n let instance = eventStore.instances[instanceId];\n let def = eventStore.defs[instance.defId];\n let ui = eventUis[def.defId];\n let origRange = instance.range;\n let normalRange = (!def.allDay && nextDayThreshold) ?\n computeVisibleDayRange(origRange, nextDayThreshold) :\n origRange;\n let slicedRange = intersectRanges(normalRange, framingRange);\n if (slicedRange) {\n if (ui.display === 'inverse-background') {\n if (def.groupId) {\n inverseBgByGroupId[def.groupId].push(slicedRange);\n }\n else {\n inverseBgByDefId[instance.defId].push(slicedRange);\n }\n }\n else if (ui.display !== 'none') {\n (ui.display === 'background' ? bgRanges : fgRanges).push({\n def,\n ui,\n instance,\n range: slicedRange,\n isStart: normalRange.start && normalRange.start.valueOf() === slicedRange.start.valueOf(),\n isEnd: normalRange.end && normalRange.end.valueOf() === slicedRange.end.valueOf(),\n });\n }\n }\n }\n for (let groupId in inverseBgByGroupId) { // BY GROUP\n let ranges = inverseBgByGroupId[groupId];\n let invertedRanges = invertRanges(ranges, framingRange);\n for (let invertedRange of invertedRanges) {\n let def = defByGroupId[groupId];\n let ui = eventUis[def.defId];\n bgRanges.push({\n def,\n ui,\n instance: null,\n range: invertedRange,\n isStart: false,\n isEnd: false,\n });\n }\n }\n for (let defId in inverseBgByDefId) {\n let ranges = inverseBgByDefId[defId];\n let invertedRanges = invertRanges(ranges, framingRange);\n for (let invertedRange of invertedRanges) {\n bgRanges.push({\n def: eventStore.defs[defId],\n ui: eventUis[defId],\n instance: null,\n range: invertedRange,\n isStart: false,\n isEnd: false,\n });\n }\n }\n return { bg: bgRanges, fg: fgRanges };\n}\nfunction hasBgRendering(def) {\n return def.ui.display === 'background' || def.ui.display === 'inverse-background';\n}\nfunction setElSeg(el, seg) {\n el.fcSeg = seg;\n}\nfunction getElSeg(el) {\n return el.fcSeg ||\n el.parentNode.fcSeg || // for the harness\n null;\n}\n// event ui computation\nfunction compileEventUis(eventDefs, eventUiBases) {\n return mapHash(eventDefs, (eventDef) => compileEventUi(eventDef, eventUiBases));\n}\nfunction compileEventUi(eventDef, eventUiBases) {\n let uis = [];\n if (eventUiBases['']) {\n uis.push(eventUiBases['']);\n }\n if (eventUiBases[eventDef.defId]) {\n uis.push(eventUiBases[eventDef.defId]);\n }\n uis.push(eventDef.ui);\n return combineEventUis(uis);\n}\nfunction sortEventSegs(segs, eventOrderSpecs) {\n let objs = segs.map(buildSegCompareObj);\n objs.sort((obj0, obj1) => compareByFieldSpecs(obj0, obj1, eventOrderSpecs));\n return objs.map((c) => c._seg);\n}\n// returns a object with all primitive props that can be compared\nfunction buildSegCompareObj(seg) {\n let { eventRange } = seg;\n let eventDef = eventRange.def;\n let range = eventRange.instance ? eventRange.instance.range : eventRange.range;\n let start = range.start ? range.start.valueOf() : 0; // TODO: better support for open-range events\n let end = range.end ? range.end.valueOf() : 0; // \"\n return Object.assign(Object.assign(Object.assign({}, eventDef.extendedProps), eventDef), { id: eventDef.publicId, start,\n end, duration: end - start, allDay: Number(eventDef.allDay), _seg: seg });\n}\nfunction computeSegDraggable(seg, context) {\n let { pluginHooks } = context;\n let transformers = pluginHooks.isDraggableTransformers;\n let { def, ui } = seg.eventRange;\n let val = ui.startEditable;\n for (let transformer of transformers) {\n val = transformer(val, def, ui, context);\n }\n return val;\n}\nfunction computeSegStartResizable(seg, context) {\n return seg.isStart && seg.eventRange.ui.durationEditable && context.options.eventResizableFromStart;\n}\nfunction computeSegEndResizable(seg, context) {\n return seg.isEnd && seg.eventRange.ui.durationEditable;\n}\nfunction buildSegTimeText(seg, timeFormat, context, defaultDisplayEventTime, // defaults to true\ndefaultDisplayEventEnd, // defaults to true\nstartOverride, endOverride) {\n let { dateEnv, options } = context;\n let { displayEventTime, displayEventEnd } = options;\n let eventDef = seg.eventRange.def;\n let eventInstance = seg.eventRange.instance;\n if (displayEventTime == null) {\n displayEventTime = defaultDisplayEventTime !== false;\n }\n if (displayEventEnd == null) {\n displayEventEnd = defaultDisplayEventEnd !== false;\n }\n let wholeEventStart = eventInstance.range.start;\n let wholeEventEnd = eventInstance.range.end;\n let segStart = startOverride || seg.start || seg.eventRange.range.start;\n let segEnd = endOverride || seg.end || seg.eventRange.range.end;\n let isStartDay = startOfDay(wholeEventStart).valueOf() === startOfDay(segStart).valueOf();\n let isEndDay = startOfDay(addMs(wholeEventEnd, -1)).valueOf() === startOfDay(addMs(segEnd, -1)).valueOf();\n if (displayEventTime && !eventDef.allDay && (isStartDay || isEndDay)) {\n segStart = isStartDay ? wholeEventStart : segStart;\n segEnd = isEndDay ? wholeEventEnd : segEnd;\n if (displayEventEnd && eventDef.hasEnd) {\n return dateEnv.formatRange(segStart, segEnd, timeFormat, {\n forcedStartTzo: startOverride ? null : eventInstance.forcedStartTzo,\n forcedEndTzo: endOverride ? null : eventInstance.forcedEndTzo,\n });\n }\n return dateEnv.format(segStart, timeFormat, {\n forcedTzo: startOverride ? null : eventInstance.forcedStartTzo, // nooooo, same\n });\n }\n return '';\n}\nfunction getSegMeta(seg, todayRange, nowDate) {\n let segRange = seg.eventRange.range;\n return {\n isPast: segRange.end < (nowDate || todayRange.start),\n isFuture: segRange.start >= (nowDate || todayRange.end),\n isToday: todayRange && rangeContainsMarker(todayRange, segRange.start),\n };\n}\nfunction getEventClassNames(props) {\n let classNames = ['fc-event'];\n if (props.isMirror) {\n classNames.push('fc-event-mirror');\n }\n if (props.isDraggable) {\n classNames.push('fc-event-draggable');\n }\n if (props.isStartResizable || props.isEndResizable) {\n classNames.push('fc-event-resizable');\n }\n if (props.isDragging) {\n classNames.push('fc-event-dragging');\n }\n if (props.isResizing) {\n classNames.push('fc-event-resizing');\n }\n if (props.isSelected) {\n classNames.push('fc-event-selected');\n }\n if (props.isStart) {\n classNames.push('fc-event-start');\n }\n if (props.isEnd) {\n classNames.push('fc-event-end');\n }\n if (props.isPast) {\n classNames.push('fc-event-past');\n }\n if (props.isToday) {\n classNames.push('fc-event-today');\n }\n if (props.isFuture) {\n classNames.push('fc-event-future');\n }\n return classNames;\n}\nfunction buildEventRangeKey(eventRange) {\n return eventRange.instance\n ? eventRange.instance.instanceId\n : `${eventRange.def.defId}:${eventRange.range.start.toISOString()}`;\n // inverse-background events don't have specific instances. TODO: better solution\n}\nfunction getSegAnchorAttrs(seg, context) {\n let { def, instance } = seg.eventRange;\n let { url } = def;\n if (url) {\n return { href: url };\n }\n let { emitter, options } = context;\n let { eventInteractive } = options;\n if (eventInteractive == null) {\n eventInteractive = def.interactive;\n if (eventInteractive == null) {\n eventInteractive = Boolean(emitter.hasHandlers('eventClick'));\n }\n }\n // mock what happens in EventClicking\n if (eventInteractive) {\n // only attach keyboard-related handlers because click handler is already done in EventClicking\n return createAriaKeyboardAttrs((ev) => {\n emitter.trigger('eventClick', {\n el: ev.target,\n event: new EventImpl(context, def, instance),\n jsEvent: ev,\n view: context.viewApi,\n });\n });\n }\n return {};\n}\n\nconst STANDARD_PROPS = {\n start: identity,\n end: identity,\n allDay: Boolean,\n};\nfunction parseDateSpan(raw, dateEnv, defaultDuration) {\n let span = parseOpenDateSpan(raw, dateEnv);\n let { range } = span;\n if (!range.start) {\n return null;\n }\n if (!range.end) {\n if (defaultDuration == null) {\n return null;\n }\n range.end = dateEnv.add(range.start, defaultDuration);\n }\n return span;\n}\n/*\nTODO: somehow combine with parseRange?\nWill return null if the start/end props were present but parsed invalidly.\n*/\nfunction parseOpenDateSpan(raw, dateEnv) {\n let { refined: standardProps, extra } = refineProps(raw, STANDARD_PROPS);\n let startMeta = standardProps.start ? dateEnv.createMarkerMeta(standardProps.start) : null;\n let endMeta = standardProps.end ? dateEnv.createMarkerMeta(standardProps.end) : null;\n let { allDay } = standardProps;\n if (allDay == null) {\n allDay = (startMeta && startMeta.isTimeUnspecified) &&\n (!endMeta || endMeta.isTimeUnspecified);\n }\n return Object.assign({ range: {\n start: startMeta ? startMeta.marker : null,\n end: endMeta ? endMeta.marker : null,\n }, allDay }, extra);\n}\nfunction isDateSpansEqual(span0, span1) {\n return rangesEqual(span0.range, span1.range) &&\n span0.allDay === span1.allDay &&\n isSpanPropsEqual(span0, span1);\n}\n// the NON-DATE-RELATED props\nfunction isSpanPropsEqual(span0, span1) {\n for (let propName in span1) {\n if (propName !== 'range' && propName !== 'allDay') {\n if (span0[propName] !== span1[propName]) {\n return false;\n }\n }\n }\n // are there any props that span0 has that span1 DOESN'T have?\n // both have range/allDay, so no need to special-case.\n for (let propName in span0) {\n if (!(propName in span1)) {\n return false;\n }\n }\n return true;\n}\nfunction buildDateSpanApi(span, dateEnv) {\n return Object.assign(Object.assign({}, buildRangeApi(span.range, dateEnv, span.allDay)), { allDay: span.allDay });\n}\nfunction buildRangeApiWithTimeZone(range, dateEnv, omitTime) {\n return Object.assign(Object.assign({}, buildRangeApi(range, dateEnv, omitTime)), { timeZone: dateEnv.timeZone });\n}\nfunction buildRangeApi(range, dateEnv, omitTime) {\n return {\n start: dateEnv.toDate(range.start),\n end: dateEnv.toDate(range.end),\n startStr: dateEnv.formatIso(range.start, { omitTime }),\n endStr: dateEnv.formatIso(range.end, { omitTime }),\n };\n}\nfunction fabricateEventRange(dateSpan, eventUiBases, context) {\n let res = refineEventDef({ editable: false }, context);\n let def = parseEventDef(res.refined, res.extra, '', // sourceId\n dateSpan.allDay, true, // hasEnd\n context);\n return {\n def,\n ui: compileEventUi(def, eventUiBases),\n instance: createEventInstance(def.defId, dateSpan.range),\n range: dateSpan.range,\n isStart: true,\n isEnd: true,\n };\n}\n\nlet calendarSystemClassMap = {};\nfunction registerCalendarSystem(name, theClass) {\n calendarSystemClassMap[name] = theClass;\n}\nfunction createCalendarSystem(name) {\n return new calendarSystemClassMap[name]();\n}\nclass GregorianCalendarSystem {\n getMarkerYear(d) {\n return d.getUTCFullYear();\n }\n getMarkerMonth(d) {\n return d.getUTCMonth();\n }\n getMarkerDay(d) {\n return d.getUTCDate();\n }\n arrayToMarker(arr) {\n return arrayToUtcDate(arr);\n }\n markerToArray(marker) {\n return dateToUtcArray(marker);\n }\n}\nregisterCalendarSystem('gregory', GregorianCalendarSystem);\n\nconst ISO_RE = /^\\s*(\\d{4})(-?(\\d{2})(-?(\\d{2})([T ](\\d{2}):?(\\d{2})(:?(\\d{2})(\\.(\\d+))?)?(Z|(([-+])(\\d{2})(:?(\\d{2}))?))?)?)?)?$/;\nfunction parse(str) {\n let m = ISO_RE.exec(str);\n if (m) {\n let marker = new Date(Date.UTC(Number(m[1]), m[3] ? Number(m[3]) - 1 : 0, Number(m[5] || 1), Number(m[7] || 0), Number(m[8] || 0), Number(m[10] || 0), m[12] ? Number(`0.${m[12]}`) * 1000 : 0));\n if (isValidDate(marker)) {\n let timeZoneOffset = null;\n if (m[13]) {\n timeZoneOffset = (m[15] === '-' ? -1 : 1) * (Number(m[16] || 0) * 60 +\n Number(m[18] || 0));\n }\n return {\n marker,\n isTimeUnspecified: !m[6],\n timeZoneOffset,\n };\n }\n }\n return null;\n}\n\nclass DateEnv {\n constructor(settings) {\n let timeZone = this.timeZone = settings.timeZone;\n let isNamedTimeZone = timeZone !== 'local' && timeZone !== 'UTC';\n if (settings.namedTimeZoneImpl && isNamedTimeZone) {\n this.namedTimeZoneImpl = new settings.namedTimeZoneImpl(timeZone);\n }\n this.canComputeOffset = Boolean(!isNamedTimeZone || this.namedTimeZoneImpl);\n this.calendarSystem = createCalendarSystem(settings.calendarSystem);\n this.locale = settings.locale;\n this.weekDow = settings.locale.week.dow;\n this.weekDoy = settings.locale.week.doy;\n if (settings.weekNumberCalculation === 'ISO') {\n this.weekDow = 1;\n this.weekDoy = 4;\n }\n if (typeof settings.firstDay === 'number') {\n this.weekDow = settings.firstDay;\n }\n if (typeof settings.weekNumberCalculation === 'function') {\n this.weekNumberFunc = settings.weekNumberCalculation;\n }\n this.weekText = settings.weekText != null ? settings.weekText : settings.locale.options.weekText;\n this.weekTextLong = (settings.weekTextLong != null ? settings.weekTextLong : settings.locale.options.weekTextLong) || this.weekText;\n this.cmdFormatter = settings.cmdFormatter;\n this.defaultSeparator = settings.defaultSeparator;\n }\n // Creating / Parsing\n createMarker(input) {\n let meta = this.createMarkerMeta(input);\n if (meta === null) {\n return null;\n }\n return meta.marker;\n }\n createNowMarker() {\n if (this.canComputeOffset) {\n return this.timestampToMarker(new Date().valueOf());\n }\n // if we can't compute the current date val for a timezone,\n // better to give the current local date vals than UTC\n return arrayToUtcDate(dateToLocalArray(new Date()));\n }\n createMarkerMeta(input) {\n if (typeof input === 'string') {\n return this.parse(input);\n }\n let marker = null;\n if (typeof input === 'number') {\n marker = this.timestampToMarker(input);\n }\n else if (input instanceof Date) {\n input = input.valueOf();\n if (!isNaN(input)) {\n marker = this.timestampToMarker(input);\n }\n }\n else if (Array.isArray(input)) {\n marker = arrayToUtcDate(input);\n }\n if (marker === null || !isValidDate(marker)) {\n return null;\n }\n return { marker, isTimeUnspecified: false, forcedTzo: null };\n }\n parse(s) {\n let parts = parse(s);\n if (parts === null) {\n return null;\n }\n let { marker } = parts;\n let forcedTzo = null;\n if (parts.timeZoneOffset !== null) {\n if (this.canComputeOffset) {\n marker = this.timestampToMarker(marker.valueOf() - parts.timeZoneOffset * 60 * 1000);\n }\n else {\n forcedTzo = parts.timeZoneOffset;\n }\n }\n return { marker, isTimeUnspecified: parts.isTimeUnspecified, forcedTzo };\n }\n // Accessors\n getYear(marker) {\n return this.calendarSystem.getMarkerYear(marker);\n }\n getMonth(marker) {\n return this.calendarSystem.getMarkerMonth(marker);\n }\n // Adding / Subtracting\n add(marker, dur) {\n let a = this.calendarSystem.markerToArray(marker);\n a[0] += dur.years;\n a[1] += dur.months;\n a[2] += dur.days;\n a[6] += dur.milliseconds;\n return this.calendarSystem.arrayToMarker(a);\n }\n subtract(marker, dur) {\n let a = this.calendarSystem.markerToArray(marker);\n a[0] -= dur.years;\n a[1] -= dur.months;\n a[2] -= dur.days;\n a[6] -= dur.milliseconds;\n return this.calendarSystem.arrayToMarker(a);\n }\n addYears(marker, n) {\n let a = this.calendarSystem.markerToArray(marker);\n a[0] += n;\n return this.calendarSystem.arrayToMarker(a);\n }\n addMonths(marker, n) {\n let a = this.calendarSystem.markerToArray(marker);\n a[1] += n;\n return this.calendarSystem.arrayToMarker(a);\n }\n // Diffing Whole Units\n diffWholeYears(m0, m1) {\n let { calendarSystem } = this;\n if (timeAsMs(m0) === timeAsMs(m1) &&\n calendarSystem.getMarkerDay(m0) === calendarSystem.getMarkerDay(m1) &&\n calendarSystem.getMarkerMonth(m0) === calendarSystem.getMarkerMonth(m1)) {\n return calendarSystem.getMarkerYear(m1) - calendarSystem.getMarkerYear(m0);\n }\n return null;\n }\n diffWholeMonths(m0, m1) {\n let { calendarSystem } = this;\n if (timeAsMs(m0) === timeAsMs(m1) &&\n calendarSystem.getMarkerDay(m0) === calendarSystem.getMarkerDay(m1)) {\n return (calendarSystem.getMarkerMonth(m1) - calendarSystem.getMarkerMonth(m0)) +\n (calendarSystem.getMarkerYear(m1) - calendarSystem.getMarkerYear(m0)) * 12;\n }\n return null;\n }\n // Range / Duration\n greatestWholeUnit(m0, m1) {\n let n = this.diffWholeYears(m0, m1);\n if (n !== null) {\n return { unit: 'year', value: n };\n }\n n = this.diffWholeMonths(m0, m1);\n if (n !== null) {\n return { unit: 'month', value: n };\n }\n n = diffWholeWeeks(m0, m1);\n if (n !== null) {\n return { unit: 'week', value: n };\n }\n n = diffWholeDays(m0, m1);\n if (n !== null) {\n return { unit: 'day', value: n };\n }\n n = diffHours(m0, m1);\n if (isInt(n)) {\n return { unit: 'hour', value: n };\n }\n n = diffMinutes(m0, m1);\n if (isInt(n)) {\n return { unit: 'minute', value: n };\n }\n n = diffSeconds(m0, m1);\n if (isInt(n)) {\n return { unit: 'second', value: n };\n }\n return { unit: 'millisecond', value: m1.valueOf() - m0.valueOf() };\n }\n countDurationsBetween(m0, m1, d) {\n // TODO: can use greatestWholeUnit\n let diff;\n if (d.years) {\n diff = this.diffWholeYears(m0, m1);\n if (diff !== null) {\n return diff / asRoughYears(d);\n }\n }\n if (d.months) {\n diff = this.diffWholeMonths(m0, m1);\n if (diff !== null) {\n return diff / asRoughMonths(d);\n }\n }\n if (d.days) {\n diff = diffWholeDays(m0, m1);\n if (diff !== null) {\n return diff / asRoughDays(d);\n }\n }\n return (m1.valueOf() - m0.valueOf()) / asRoughMs(d);\n }\n // Start-Of\n // these DON'T return zoned-dates. only UTC start-of dates\n startOf(m, unit) {\n if (unit === 'year') {\n return this.startOfYear(m);\n }\n if (unit === 'month') {\n return this.startOfMonth(m);\n }\n if (unit === 'week') {\n return this.startOfWeek(m);\n }\n if (unit === 'day') {\n return startOfDay(m);\n }\n if (unit === 'hour') {\n return startOfHour(m);\n }\n if (unit === 'minute') {\n return startOfMinute(m);\n }\n if (unit === 'second') {\n return startOfSecond(m);\n }\n return null;\n }\n startOfYear(m) {\n return this.calendarSystem.arrayToMarker([\n this.calendarSystem.getMarkerYear(m),\n ]);\n }\n startOfMonth(m) {\n return this.calendarSystem.arrayToMarker([\n this.calendarSystem.getMarkerYear(m),\n this.calendarSystem.getMarkerMonth(m),\n ]);\n }\n startOfWeek(m) {\n return this.calendarSystem.arrayToMarker([\n this.calendarSystem.getMarkerYear(m),\n this.calendarSystem.getMarkerMonth(m),\n m.getUTCDate() - ((m.getUTCDay() - this.weekDow + 7) % 7),\n ]);\n }\n // Week Number\n computeWeekNumber(marker) {\n if (this.weekNumberFunc) {\n return this.weekNumberFunc(this.toDate(marker));\n }\n return weekOfYear(marker, this.weekDow, this.weekDoy);\n }\n // TODO: choke on timeZoneName: long\n format(marker, formatter, dateOptions = {}) {\n return formatter.format({\n marker,\n timeZoneOffset: dateOptions.forcedTzo != null ?\n dateOptions.forcedTzo :\n this.offsetForMarker(marker),\n }, this);\n }\n formatRange(start, end, formatter, dateOptions = {}) {\n if (dateOptions.isEndExclusive) {\n end = addMs(end, -1);\n }\n return formatter.formatRange({\n marker: start,\n timeZoneOffset: dateOptions.forcedStartTzo != null ?\n dateOptions.forcedStartTzo :\n this.offsetForMarker(start),\n }, {\n marker: end,\n timeZoneOffset: dateOptions.forcedEndTzo != null ?\n dateOptions.forcedEndTzo :\n this.offsetForMarker(end),\n }, this, dateOptions.defaultSeparator);\n }\n /*\n DUMB: the omitTime arg is dumb. if we omit the time, we want to omit the timezone offset. and if we do that,\n might as well use buildIsoString or some other util directly\n */\n formatIso(marker, extraOptions = {}) {\n let timeZoneOffset = null;\n if (!extraOptions.omitTimeZoneOffset) {\n if (extraOptions.forcedTzo != null) {\n timeZoneOffset = extraOptions.forcedTzo;\n }\n else {\n timeZoneOffset = this.offsetForMarker(marker);\n }\n }\n return buildIsoString(marker, timeZoneOffset, extraOptions.omitTime);\n }\n // TimeZone\n timestampToMarker(ms) {\n if (this.timeZone === 'local') {\n return arrayToUtcDate(dateToLocalArray(new Date(ms)));\n }\n if (this.timeZone === 'UTC' || !this.namedTimeZoneImpl) {\n return new Date(ms);\n }\n return arrayToUtcDate(this.namedTimeZoneImpl.timestampToArray(ms));\n }\n offsetForMarker(m) {\n if (this.timeZone === 'local') {\n return -arrayToLocalDate(dateToUtcArray(m)).getTimezoneOffset(); // convert \"inverse\" offset to \"normal\" offset\n }\n if (this.timeZone === 'UTC') {\n return 0;\n }\n if (this.namedTimeZoneImpl) {\n return this.namedTimeZoneImpl.offsetForArray(dateToUtcArray(m));\n }\n return null;\n }\n // Conversion\n toDate(m, forcedTzo) {\n if (this.timeZone === 'local') {\n return arrayToLocalDate(dateToUtcArray(m));\n }\n if (this.timeZone === 'UTC') {\n return new Date(m.valueOf()); // make sure it's a copy\n }\n if (!this.namedTimeZoneImpl) {\n return new Date(m.valueOf() - (forcedTzo || 0));\n }\n return new Date(m.valueOf() -\n this.namedTimeZoneImpl.offsetForArray(dateToUtcArray(m)) * 1000 * 60);\n }\n}\n\nclass NamedTimeZoneImpl {\n constructor(timeZoneName) {\n this.timeZoneName = timeZoneName;\n }\n}\n\nclass SegHierarchy {\n constructor() {\n // settings\n this.strictOrder = false;\n this.allowReslicing = false;\n this.maxCoord = -1; // -1 means no max\n this.maxStackCnt = -1; // -1 means no max\n this.levelCoords = []; // ordered\n this.entriesByLevel = []; // parallel with levelCoords\n this.stackCnts = {}; // TODO: use better technique!?\n }\n addSegs(inputs) {\n let hiddenEntries = [];\n for (let input of inputs) {\n this.insertEntry(input, hiddenEntries);\n }\n return hiddenEntries;\n }\n insertEntry(entry, hiddenEntries) {\n let insertion = this.findInsertion(entry);\n if (this.isInsertionValid(insertion, entry)) {\n this.insertEntryAt(entry, insertion);\n return 1;\n }\n return this.handleInvalidInsertion(insertion, entry, hiddenEntries);\n }\n isInsertionValid(insertion, entry) {\n return (this.maxCoord === -1 || insertion.levelCoord + entry.thickness <= this.maxCoord) &&\n (this.maxStackCnt === -1 || insertion.stackCnt < this.maxStackCnt);\n }\n // returns number of new entries inserted\n handleInvalidInsertion(insertion, entry, hiddenEntries) {\n if (this.allowReslicing && insertion.touchingEntry) {\n return this.splitEntry(entry, insertion.touchingEntry, hiddenEntries);\n }\n hiddenEntries.push(entry);\n return 0;\n }\n splitEntry(entry, barrier, hiddenEntries) {\n let partCnt = 0;\n let splitHiddenEntries = [];\n let entrySpan = entry.span;\n let barrierSpan = barrier.span;\n if (entrySpan.start < barrierSpan.start) {\n partCnt += this.insertEntry({\n index: entry.index,\n thickness: entry.thickness,\n span: { start: entrySpan.start, end: barrierSpan.start },\n }, splitHiddenEntries);\n }\n if (entrySpan.end > barrierSpan.end) {\n partCnt += this.insertEntry({\n index: entry.index,\n thickness: entry.thickness,\n span: { start: barrierSpan.end, end: entrySpan.end },\n }, splitHiddenEntries);\n }\n if (partCnt) {\n hiddenEntries.push({\n index: entry.index,\n thickness: entry.thickness,\n span: intersectSpans(barrierSpan, entrySpan), // guaranteed to intersect\n }, ...splitHiddenEntries);\n return partCnt;\n }\n hiddenEntries.push(entry);\n return 0;\n }\n insertEntryAt(entry, insertion) {\n let { entriesByLevel, levelCoords } = this;\n if (insertion.lateral === -1) {\n // create a new level\n insertAt(levelCoords, insertion.level, insertion.levelCoord);\n insertAt(entriesByLevel, insertion.level, [entry]);\n }\n else {\n // insert into existing level\n insertAt(entriesByLevel[insertion.level], insertion.lateral, entry);\n }\n this.stackCnts[buildEntryKey(entry)] = insertion.stackCnt;\n }\n findInsertion(newEntry) {\n let { levelCoords, entriesByLevel, strictOrder, stackCnts } = this;\n let levelCnt = levelCoords.length;\n let candidateCoord = 0;\n let touchingLevel = -1;\n let touchingLateral = -1;\n let touchingEntry = null;\n let stackCnt = 0;\n for (let trackingLevel = 0; trackingLevel < levelCnt; trackingLevel += 1) {\n let trackingCoord = levelCoords[trackingLevel];\n // if the current level is past the placed entry, we have found a good empty space and can stop.\n // if strictOrder, keep finding more lateral intersections.\n if (!strictOrder && trackingCoord >= candidateCoord + newEntry.thickness) {\n break;\n }\n let trackingEntries = entriesByLevel[trackingLevel];\n let trackingEntry;\n let searchRes = binarySearch(trackingEntries, newEntry.span.start, getEntrySpanEnd); // find first entry after newEntry's end\n let lateralIndex = searchRes[0] + searchRes[1]; // if exact match (which doesn't collide), go to next one\n while ( // loop through entries that horizontally intersect\n (trackingEntry = trackingEntries[lateralIndex]) && // but not past the whole entry list\n trackingEntry.span.start < newEntry.span.end // and not entirely past newEntry\n ) {\n let trackingEntryBottom = trackingCoord + trackingEntry.thickness;\n // intersects into the top of the candidate?\n if (trackingEntryBottom > candidateCoord) {\n candidateCoord = trackingEntryBottom;\n touchingEntry = trackingEntry;\n touchingLevel = trackingLevel;\n touchingLateral = lateralIndex;\n }\n // butts up against top of candidate? (will happen if just intersected as well)\n if (trackingEntryBottom === candidateCoord) {\n // accumulate the highest possible stackCnt of the trackingEntries that butt up\n stackCnt = Math.max(stackCnt, stackCnts[buildEntryKey(trackingEntry)] + 1);\n }\n lateralIndex += 1;\n }\n }\n // the destination level will be after touchingEntry's level. find it\n let destLevel = 0;\n if (touchingEntry) {\n destLevel = touchingLevel + 1;\n while (destLevel < levelCnt && levelCoords[destLevel] < candidateCoord) {\n destLevel += 1;\n }\n }\n // if adding to an existing level, find where to insert\n let destLateral = -1;\n if (destLevel < levelCnt && levelCoords[destLevel] === candidateCoord) {\n destLateral = binarySearch(entriesByLevel[destLevel], newEntry.span.end, getEntrySpanEnd)[0];\n }\n return {\n touchingLevel,\n touchingLateral,\n touchingEntry,\n stackCnt,\n levelCoord: candidateCoord,\n level: destLevel,\n lateral: destLateral,\n };\n }\n // sorted by levelCoord (lowest to highest)\n toRects() {\n let { entriesByLevel, levelCoords } = this;\n let levelCnt = entriesByLevel.length;\n let rects = [];\n for (let level = 0; level < levelCnt; level += 1) {\n let entries = entriesByLevel[level];\n let levelCoord = levelCoords[level];\n for (let entry of entries) {\n rects.push(Object.assign(Object.assign({}, entry), { levelCoord }));\n }\n }\n return rects;\n }\n}\nfunction getEntrySpanEnd(entry) {\n return entry.span.end;\n}\nfunction buildEntryKey(entry) {\n return entry.index + ':' + entry.span.start;\n}\n// returns groups with entries sorted by input order\nfunction groupIntersectingEntries(entries) {\n let merges = [];\n for (let entry of entries) {\n let filteredMerges = [];\n let hungryMerge = {\n span: entry.span,\n entries: [entry],\n };\n for (let merge of merges) {\n if (intersectSpans(merge.span, hungryMerge.span)) {\n hungryMerge = {\n entries: merge.entries.concat(hungryMerge.entries),\n span: joinSpans(merge.span, hungryMerge.span),\n };\n }\n else {\n filteredMerges.push(merge);\n }\n }\n filteredMerges.push(hungryMerge);\n merges = filteredMerges;\n }\n return merges;\n}\nfunction joinSpans(span0, span1) {\n return {\n start: Math.min(span0.start, span1.start),\n end: Math.max(span0.end, span1.end),\n };\n}\nfunction intersectSpans(span0, span1) {\n let start = Math.max(span0.start, span1.start);\n let end = Math.min(span0.end, span1.end);\n if (start < end) {\n return { start, end };\n }\n return null;\n}\n// general util\n// ---------------------------------------------------------------------------------------------------------------------\nfunction insertAt(arr, index, item) {\n arr.splice(index, 0, item);\n}\nfunction binarySearch(a, searchVal, getItemVal) {\n let startIndex = 0;\n let endIndex = a.length; // exclusive\n if (!endIndex || searchVal < getItemVal(a[startIndex])) { // no items OR before first item\n return [0, 0];\n }\n if (searchVal > getItemVal(a[endIndex - 1])) { // after last item\n return [endIndex, 0];\n }\n while (startIndex < endIndex) {\n let middleIndex = Math.floor(startIndex + (endIndex - startIndex) / 2);\n let middleVal = getItemVal(a[middleIndex]);\n if (searchVal < middleVal) {\n endIndex = middleIndex;\n }\n else if (searchVal > middleVal) {\n startIndex = middleIndex + 1;\n }\n else { // equal!\n return [middleIndex, 1];\n }\n }\n return [startIndex, 0];\n}\n\nclass Interaction {\n constructor(settings) {\n this.component = settings.component;\n this.isHitComboAllowed = settings.isHitComboAllowed || null;\n }\n destroy() {\n }\n}\nfunction parseInteractionSettings(component, input) {\n return {\n component,\n el: input.el,\n useEventCenter: input.useEventCenter != null ? input.useEventCenter : true,\n isHitComboAllowed: input.isHitComboAllowed || null,\n };\n}\nfunction interactionSettingsToStore(settings) {\n return {\n [settings.component.uid]: settings,\n };\n}\n// global state\nconst interactionSettingsStore = {};\n\n/*\nAn abstraction for a dragging interaction originating on an event.\nDoes higher-level things than PointerDragger, such as possibly:\n- a \"mirror\" that moves with the pointer\n- a minimum number of pixels or other criteria for a true drag to begin\n\nsubclasses must emit:\n- pointerdown\n- dragstart\n- dragmove\n- pointerup\n- dragend\n*/\nclass ElementDragging {\n constructor(el, selector) {\n this.emitter = new Emitter();\n }\n destroy() {\n }\n setMirrorIsVisible(bool) {\n // optional if subclass doesn't want to support a mirror\n }\n setMirrorNeedsRevert(bool) {\n // optional if subclass doesn't want to support a mirror\n }\n setAutoScrollEnabled(bool) {\n // optional\n }\n}\n\n// TODO: get rid of this in favor of options system,\n// tho it's really easy to access this globally rather than pass thru options.\nconst config = {};\n\n/*\nInformation about what will happen when an external element is dragged-and-dropped\nonto a calendar. Contains information for creating an event.\n*/\nconst DRAG_META_REFINERS = {\n startTime: createDuration,\n duration: createDuration,\n create: Boolean,\n sourceId: String,\n};\nfunction parseDragMeta(raw) {\n let { refined, extra } = refineProps(raw, DRAG_META_REFINERS);\n return {\n startTime: refined.startTime || null,\n duration: refined.duration || null,\n create: refined.create != null ? refined.create : true,\n sourceId: refined.sourceId,\n leftoverProps: extra,\n };\n}\n\nclass CalendarRoot extends BaseComponent {\n constructor() {\n super(...arguments);\n this.state = {\n forPrint: false,\n };\n this.handleBeforePrint = () => {\n this.setState({ forPrint: true });\n };\n this.handleAfterPrint = () => {\n this.setState({ forPrint: false });\n };\n }\n render() {\n let { props } = this;\n let { options } = props;\n let { forPrint } = this.state;\n let isHeightAuto = forPrint || options.height === 'auto' || options.contentHeight === 'auto';\n let height = (!isHeightAuto && options.height != null) ? options.height : '';\n let classNames = [\n 'fc',\n forPrint ? 'fc-media-print' : 'fc-media-screen',\n `fc-direction-${options.direction}`,\n props.theme.getClass('root'),\n ];\n if (!getCanVGrowWithinCell()) {\n classNames.push('fc-liquid-hack');\n }\n return props.children(classNames, height, isHeightAuto, forPrint);\n }\n componentDidMount() {\n let { emitter } = this.props;\n emitter.on('_beforeprint', this.handleBeforePrint);\n emitter.on('_afterprint', this.handleAfterPrint);\n }\n componentWillUnmount() {\n let { emitter } = this.props;\n emitter.off('_beforeprint', this.handleBeforePrint);\n emitter.off('_afterprint', this.handleAfterPrint);\n }\n}\n\n// Computes a default column header formatting string if `colFormat` is not explicitly defined\nfunction computeFallbackHeaderFormat(datesRepDistinctDays, dayCnt) {\n // if more than one week row, or if there are a lot of columns with not much space,\n // put just the day numbers will be in each cell\n if (!datesRepDistinctDays || dayCnt > 10) {\n return createFormatter({ weekday: 'short' }); // \"Sat\"\n }\n if (dayCnt > 1) {\n return createFormatter({ weekday: 'short', month: 'numeric', day: 'numeric', omitCommas: true }); // \"Sat 11/12\"\n }\n return createFormatter({ weekday: 'long' }); // \"Saturday\"\n}\n\nconst CLASS_NAME = 'fc-col-header-cell'; // do the cushion too? no\nfunction renderInner$1(renderProps) {\n return renderProps.text;\n}\n\nclass ContentInjector extends BaseComponent {\n constructor() {\n super(...arguments);\n this.id = guid();\n this.currentDomNodes = [];\n this.queuedDomNodes = [];\n this.handleEl = (el) => {\n if (this.props.elRef) {\n setRef(this.props.elRef, el);\n }\n };\n }\n render() {\n const { props, context } = this;\n const { options } = context;\n const { generator, renderProps } = props;\n const attrs = buildElAttrs(props);\n let innerContent;\n let queuedDomNodes = [];\n if (hasCustomRenderingHandler(props.generatorName, options)) {\n if (options.customRenderingReplacesEl) {\n delete attrs.elRef; // because handleEl will be used\n }\n }\n else {\n const customContent = typeof generator === 'function' ?\n generator(renderProps, preact__WEBPACK_IMPORTED_MODULE_0__.createElement) :\n generator;\n if (typeof customContent === 'string' ||\n (0,preact__WEBPACK_IMPORTED_MODULE_0__.isValidElement)(customContent) ||\n Array.isArray(customContent)) {\n innerContent = customContent;\n }\n else if (typeof customContent === 'object') {\n if ('html' in customContent) {\n attrs.dangerouslySetInnerHTML = { __html: customContent.html };\n }\n else if ('domNodes' in customContent) {\n queuedDomNodes = Array.prototype.slice.call(customContent.domNodes);\n }\n }\n }\n this.queuedDomNodes = queuedDomNodes;\n return (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(props.elTag, attrs, innerContent);\n }\n componentDidMount() {\n this.applyQueueudDomNodes();\n this.triggerCustomRendering(true);\n }\n componentDidUpdate() {\n this.applyQueueudDomNodes();\n this.triggerCustomRendering(true);\n }\n componentWillUnmount() {\n this.triggerCustomRendering(false); // TODO: different API for removal?\n }\n triggerCustomRendering(isActive) {\n const { props, context } = this;\n const { handleCustomRendering, customRenderingMetaMap } = context.options;\n if (handleCustomRendering) {\n const customRenderingMeta = customRenderingMetaMap === null || customRenderingMetaMap === void 0 ? void 0 : customRenderingMetaMap[props.generatorName];\n if (customRenderingMeta) {\n handleCustomRendering(Object.assign({ id: this.id, isActive, containerEl: this.base, reportNewContainerEl: this.handleEl, generatorMeta: customRenderingMeta }, props));\n }\n }\n }\n applyQueueudDomNodes() {\n const { queuedDomNodes, currentDomNodes } = this;\n const el = this.base;\n if (!isArraysEqual(queuedDomNodes, currentDomNodes)) {\n currentDomNodes.forEach(removeElement);\n for (let newNode of queuedDomNodes) {\n el.appendChild(newNode);\n }\n this.currentDomNodes = queuedDomNodes;\n }\n }\n}\nContentInjector.addPropsEquality({\n elClasses: isArraysEqual,\n elStyle: isPropsEqual,\n elAttrs: isNonHandlerPropsEqual,\n renderProps: isPropsEqual,\n});\n// Util\nfunction hasCustomRenderingHandler(generatorName, options) {\n var _a;\n return Boolean(options.handleCustomRendering &&\n generatorName &&\n ((_a = options.customRenderingMetaMap) === null || _a === void 0 ? void 0 : _a[generatorName]));\n}\nfunction buildElAttrs(props, extraClassNames) {\n const attrs = Object.assign(Object.assign({}, props.elAttrs), { ref: props.elRef });\n if (props.elClasses || extraClassNames) {\n attrs.className = (props.elClasses || [])\n .concat(extraClassNames || [])\n .concat(attrs.className || [])\n .filter(Boolean)\n .join(' ');\n }\n if (props.elStyle) {\n attrs.style = props.elStyle;\n }\n return attrs;\n}\n\nconst RenderId = createContext(0);\n\nclass ContentContainer extends preact__WEBPACK_IMPORTED_MODULE_0__.Component {\n constructor() {\n super(...arguments);\n this.InnerContent = InnerContentInjector.bind(undefined, this);\n }\n render() {\n const { props } = this;\n const generatedClassNames = generateClassNames(props.classNameGenerator, props.renderProps);\n if (props.children) {\n const elAttrs = buildElAttrs(props, generatedClassNames);\n const children = props.children(this.InnerContent, props.renderProps, elAttrs);\n if (props.elTag) {\n return (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(props.elTag, elAttrs, children);\n }\n else {\n return children;\n }\n }\n else {\n return (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)((ContentInjector), Object.assign(Object.assign({}, props), { elTag: props.elTag || 'div', elClasses: (props.elClasses || []).concat(generatedClassNames), renderId: this.context }));\n }\n }\n componentDidMount() {\n var _a, _b;\n (_b = (_a = this.props).didMount) === null || _b === void 0 ? void 0 : _b.call(_a, Object.assign(Object.assign({}, this.props.renderProps), { el: this.base }));\n }\n componentWillUnmount() {\n var _a, _b;\n (_b = (_a = this.props).willUnmount) === null || _b === void 0 ? void 0 : _b.call(_a, Object.assign(Object.assign({}, this.props.renderProps), { el: this.base }));\n }\n}\nContentContainer.contextType = RenderId;\nfunction InnerContentInjector(containerComponent, props) {\n const parentProps = containerComponent.props;\n return (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)((ContentInjector), Object.assign({ renderProps: parentProps.renderProps, generatorName: parentProps.generatorName, generator: parentProps.generator, renderId: containerComponent.context }, props));\n}\n// Utils\nfunction generateClassNames(classNameGenerator, renderProps) {\n const classNames = typeof classNameGenerator === 'function' ?\n classNameGenerator(renderProps) :\n classNameGenerator || [];\n return typeof classNames === 'string' ? [classNames] : classNames;\n}\n\n// BAD name for this class now. used in the Header\nclass TableDateCell extends BaseComponent {\n render() {\n let { dateEnv, options, theme, viewApi } = this.context;\n let { props } = this;\n let { date, dateProfile } = props;\n let dayMeta = getDateMeta(date, props.todayRange, null, dateProfile);\n let classNames = [CLASS_NAME].concat(getDayClassNames(dayMeta, theme));\n let text = dateEnv.format(date, props.dayHeaderFormat);\n // if colCnt is 1, we are already in a day-view and don't need a navlink\n let navLinkAttrs = (!dayMeta.isDisabled && props.colCnt > 1)\n ? buildNavLinkAttrs(this.context, date)\n : {};\n let renderProps = Object.assign(Object.assign(Object.assign({ date: dateEnv.toDate(date), view: viewApi }, props.extraRenderProps), { text }), dayMeta);\n return ((0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(ContentContainer, { elTag: \"th\", elClasses: classNames, elAttrs: Object.assign({ role: 'columnheader', colSpan: props.colSpan, 'data-date': !dayMeta.isDisabled ? formatDayString(date) : undefined }, props.extraDataAttrs), renderProps: renderProps, generatorName: \"dayHeaderContent\", generator: options.dayHeaderContent || renderInner$1, classNameGenerator: options.dayHeaderClassNames, didMount: options.dayHeaderDidMount, willUnmount: options.dayHeaderWillUnmount }, (InnerContainer) => ((0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(\"div\", { className: \"fc-scrollgrid-sync-inner\" }, !dayMeta.isDisabled && ((0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(InnerContainer, { elTag: \"a\", elAttrs: navLinkAttrs, elClasses: [\n 'fc-col-header-cell-cushion',\n props.isSticky && 'fc-sticky',\n ] }))))));\n }\n}\n\nconst WEEKDAY_FORMAT = createFormatter({ weekday: 'long' });\nclass TableDowCell extends BaseComponent {\n render() {\n let { props } = this;\n let { dateEnv, theme, viewApi, options } = this.context;\n let date = addDays(new Date(259200000), props.dow); // start with Sun, 04 Jan 1970 00:00:00 GMT\n let dateMeta = {\n dow: props.dow,\n isDisabled: false,\n isFuture: false,\n isPast: false,\n isToday: false,\n isOther: false,\n };\n let text = dateEnv.format(date, props.dayHeaderFormat);\n let renderProps = Object.assign(Object.assign(Object.assign(Object.assign({ // TODO: make this public?\n date }, dateMeta), { view: viewApi }), props.extraRenderProps), { text });\n return ((0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(ContentContainer, { elTag: \"th\", elClasses: [\n CLASS_NAME,\n ...getDayClassNames(dateMeta, theme),\n ...(props.extraClassNames || []),\n ], elAttrs: Object.assign({ role: 'columnheader', colSpan: props.colSpan }, props.extraDataAttrs), renderProps: renderProps, generatorName: \"dayHeaderContent\", generator: options.dayHeaderContent || renderInner$1, classNameGenerator: options.dayHeaderClassNames, didMount: options.dayHeaderDidMount, willUnmount: options.dayHeaderWillUnmount }, (InnerContent) => ((0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(\"div\", { className: \"fc-scrollgrid-sync-inner\" },\n (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(InnerContent, { elTag: \"a\", elClasses: [\n 'fc-col-header-cell-cushion',\n props.isSticky && 'fc-sticky',\n ], elAttrs: {\n 'aria-label': dateEnv.format(date, WEEKDAY_FORMAT),\n } })))));\n }\n}\n\nclass NowTimer extends preact__WEBPACK_IMPORTED_MODULE_0__.Component {\n constructor(props, context) {\n super(props, context);\n this.initialNowDate = getNow(context.options.now, context.dateEnv);\n this.initialNowQueriedMs = new Date().valueOf();\n this.state = this.computeTiming().currentState;\n }\n render() {\n let { props, state } = this;\n return props.children(state.nowDate, state.todayRange);\n }\n componentDidMount() {\n this.setTimeout();\n }\n componentDidUpdate(prevProps) {\n if (prevProps.unit !== this.props.unit) {\n this.clearTimeout();\n this.setTimeout();\n }\n }\n componentWillUnmount() {\n this.clearTimeout();\n }\n computeTiming() {\n let { props, context } = this;\n let unroundedNow = addMs(this.initialNowDate, new Date().valueOf() - this.initialNowQueriedMs);\n let currentUnitStart = context.dateEnv.startOf(unroundedNow, props.unit);\n let nextUnitStart = context.dateEnv.add(currentUnitStart, createDuration(1, props.unit));\n let waitMs = nextUnitStart.valueOf() - unroundedNow.valueOf();\n // there is a max setTimeout ms value (https://stackoverflow.com/a/3468650/96342)\n // ensure no longer than a day\n waitMs = Math.min(1000 * 60 * 60 * 24, waitMs);\n return {\n currentState: { nowDate: currentUnitStart, todayRange: buildDayRange(currentUnitStart) },\n nextState: { nowDate: nextUnitStart, todayRange: buildDayRange(nextUnitStart) },\n waitMs,\n };\n }\n setTimeout() {\n let { nextState, waitMs } = this.computeTiming();\n this.timeoutId = setTimeout(() => {\n this.setState(nextState, () => {\n this.setTimeout();\n });\n }, waitMs);\n }\n clearTimeout() {\n if (this.timeoutId) {\n clearTimeout(this.timeoutId);\n }\n }\n}\nNowTimer.contextType = ViewContextType;\nfunction buildDayRange(date) {\n let start = startOfDay(date);\n let end = addDays(start, 1);\n return { start, end };\n}\n\nclass DayHeader extends BaseComponent {\n constructor() {\n super(...arguments);\n this.createDayHeaderFormatter = memoize(createDayHeaderFormatter);\n }\n render() {\n let { context } = this;\n let { dates, dateProfile, datesRepDistinctDays, renderIntro } = this.props;\n let dayHeaderFormat = this.createDayHeaderFormatter(context.options.dayHeaderFormat, datesRepDistinctDays, dates.length);\n return ((0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(NowTimer, { unit: \"day\" }, (nowDate, todayRange) => ((0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(\"tr\", { role: \"row\" },\n renderIntro && renderIntro('day'),\n dates.map((date) => (datesRepDistinctDays ? ((0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(TableDateCell, { key: date.toISOString(), date: date, dateProfile: dateProfile, todayRange: todayRange, colCnt: dates.length, dayHeaderFormat: dayHeaderFormat })) : ((0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(TableDowCell, { key: date.getUTCDay(), dow: date.getUTCDay(), dayHeaderFormat: dayHeaderFormat }))))))));\n }\n}\nfunction createDayHeaderFormatter(explicitFormat, datesRepDistinctDays, dateCnt) {\n return explicitFormat || computeFallbackHeaderFormat(datesRepDistinctDays, dateCnt);\n}\n\nclass DaySeriesModel {\n constructor(range, dateProfileGenerator) {\n let date = range.start;\n let { end } = range;\n let indices = [];\n let dates = [];\n let dayIndex = -1;\n while (date < end) { // loop each day from start to end\n if (dateProfileGenerator.isHiddenDay(date)) {\n indices.push(dayIndex + 0.5); // mark that it's between indices\n }\n else {\n dayIndex += 1;\n indices.push(dayIndex);\n dates.push(date);\n }\n date = addDays(date, 1);\n }\n this.dates = dates;\n this.indices = indices;\n this.cnt = dates.length;\n }\n sliceRange(range) {\n let firstIndex = this.getDateDayIndex(range.start); // inclusive first index\n let lastIndex = this.getDateDayIndex(addDays(range.end, -1)); // inclusive last index\n let clippedFirstIndex = Math.max(0, firstIndex);\n let clippedLastIndex = Math.min(this.cnt - 1, lastIndex);\n // deal with in-between indices\n clippedFirstIndex = Math.ceil(clippedFirstIndex); // in-between starts round to next cell\n clippedLastIndex = Math.floor(clippedLastIndex); // in-between ends round to prev cell\n if (clippedFirstIndex <= clippedLastIndex) {\n return {\n firstIndex: clippedFirstIndex,\n lastIndex: clippedLastIndex,\n isStart: firstIndex === clippedFirstIndex,\n isEnd: lastIndex === clippedLastIndex,\n };\n }\n return null;\n }\n // Given a date, returns its chronolocial cell-index from the first cell of the grid.\n // If the date lies between cells (because of hiddenDays), returns a floating-point value between offsets.\n // If before the first offset, returns a negative number.\n // If after the last offset, returns an offset past the last cell offset.\n // Only works for *start* dates of cells. Will not work for exclusive end dates for cells.\n getDateDayIndex(date) {\n let { indices } = this;\n let dayOffset = Math.floor(diffDays(this.dates[0], date));\n if (dayOffset < 0) {\n return indices[0] - 1;\n }\n if (dayOffset >= indices.length) {\n return indices[indices.length - 1] + 1;\n }\n return indices[dayOffset];\n }\n}\n\nclass DayTableModel {\n constructor(daySeries, breakOnWeeks) {\n let { dates } = daySeries;\n let daysPerRow;\n let firstDay;\n let rowCnt;\n if (breakOnWeeks) {\n // count columns until the day-of-week repeats\n firstDay = dates[0].getUTCDay();\n for (daysPerRow = 1; daysPerRow < dates.length; daysPerRow += 1) {\n if (dates[daysPerRow].getUTCDay() === firstDay) {\n break;\n }\n }\n rowCnt = Math.ceil(dates.length / daysPerRow);\n }\n else {\n rowCnt = 1;\n daysPerRow = dates.length;\n }\n this.rowCnt = rowCnt;\n this.colCnt = daysPerRow;\n this.daySeries = daySeries;\n this.cells = this.buildCells();\n this.headerDates = this.buildHeaderDates();\n }\n buildCells() {\n let rows = [];\n for (let row = 0; row < this.rowCnt; row += 1) {\n let cells = [];\n for (let col = 0; col < this.colCnt; col += 1) {\n cells.push(this.buildCell(row, col));\n }\n rows.push(cells);\n }\n return rows;\n }\n buildCell(row, col) {\n let date = this.daySeries.dates[row * this.colCnt + col];\n return {\n key: date.toISOString(),\n date,\n };\n }\n buildHeaderDates() {\n let dates = [];\n for (let col = 0; col < this.colCnt; col += 1) {\n dates.push(this.cells[0][col].date);\n }\n return dates;\n }\n sliceRange(range) {\n let { colCnt } = this;\n let seriesSeg = this.daySeries.sliceRange(range);\n let segs = [];\n if (seriesSeg) {\n let { firstIndex, lastIndex } = seriesSeg;\n let index = firstIndex;\n while (index <= lastIndex) {\n let row = Math.floor(index / colCnt);\n let nextIndex = Math.min((row + 1) * colCnt, lastIndex + 1);\n segs.push({\n row,\n firstCol: index % colCnt,\n lastCol: (nextIndex - 1) % colCnt,\n isStart: seriesSeg.isStart && index === firstIndex,\n isEnd: seriesSeg.isEnd && (nextIndex - 1) === lastIndex,\n });\n index = nextIndex;\n }\n }\n return segs;\n }\n}\n\nclass Slicer {\n constructor() {\n this.sliceBusinessHours = memoize(this._sliceBusinessHours);\n this.sliceDateSelection = memoize(this._sliceDateSpan);\n this.sliceEventStore = memoize(this._sliceEventStore);\n this.sliceEventDrag = memoize(this._sliceInteraction);\n this.sliceEventResize = memoize(this._sliceInteraction);\n this.forceDayIfListItem = false; // hack\n }\n sliceProps(props, dateProfile, nextDayThreshold, context, ...extraArgs) {\n let { eventUiBases } = props;\n let eventSegs = this.sliceEventStore(props.eventStore, eventUiBases, dateProfile, nextDayThreshold, ...extraArgs);\n return {\n dateSelectionSegs: this.sliceDateSelection(props.dateSelection, eventUiBases, context, ...extraArgs),\n businessHourSegs: this.sliceBusinessHours(props.businessHours, dateProfile, nextDayThreshold, context, ...extraArgs),\n fgEventSegs: eventSegs.fg,\n bgEventSegs: eventSegs.bg,\n eventDrag: this.sliceEventDrag(props.eventDrag, eventUiBases, dateProfile, nextDayThreshold, ...extraArgs),\n eventResize: this.sliceEventResize(props.eventResize, eventUiBases, dateProfile, nextDayThreshold, ...extraArgs),\n eventSelection: props.eventSelection,\n }; // TODO: give interactionSegs?\n }\n sliceNowDate(// does not memoize\n date, context, ...extraArgs) {\n return this._sliceDateSpan({ range: { start: date, end: addMs(date, 1) }, allDay: false }, // add 1 ms, protect against null range\n {}, context, ...extraArgs);\n }\n _sliceBusinessHours(businessHours, dateProfile, nextDayThreshold, context, ...extraArgs) {\n if (!businessHours) {\n return [];\n }\n return this._sliceEventStore(expandRecurring(businessHours, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), context), {}, dateProfile, nextDayThreshold, ...extraArgs).bg;\n }\n _sliceEventStore(eventStore, eventUiBases, dateProfile, nextDayThreshold, ...extraArgs) {\n if (eventStore) {\n let rangeRes = sliceEventStore(eventStore, eventUiBases, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), nextDayThreshold);\n return {\n bg: this.sliceEventRanges(rangeRes.bg, extraArgs),\n fg: this.sliceEventRanges(rangeRes.fg, extraArgs),\n };\n }\n return { bg: [], fg: [] };\n }\n _sliceInteraction(interaction, eventUiBases, dateProfile, nextDayThreshold, ...extraArgs) {\n if (!interaction) {\n return null;\n }\n let rangeRes = sliceEventStore(interaction.mutatedEvents, eventUiBases, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), nextDayThreshold);\n return {\n segs: this.sliceEventRanges(rangeRes.fg, extraArgs),\n affectedInstances: interaction.affectedEvents.instances,\n isEvent: interaction.isEvent,\n };\n }\n _sliceDateSpan(dateSpan, eventUiBases, context, ...extraArgs) {\n if (!dateSpan) {\n return [];\n }\n let eventRange = fabricateEventRange(dateSpan, eventUiBases, context);\n let segs = this.sliceRange(dateSpan.range, ...extraArgs);\n for (let seg of segs) {\n seg.eventRange = eventRange;\n }\n return segs;\n }\n /*\n \"complete\" seg means it has component and eventRange\n */\n sliceEventRanges(eventRanges, extraArgs) {\n let segs = [];\n for (let eventRange of eventRanges) {\n segs.push(...this.sliceEventRange(eventRange, extraArgs));\n }\n return segs;\n }\n /*\n \"complete\" seg means it has component and eventRange\n */\n sliceEventRange(eventRange, extraArgs) {\n let dateRange = eventRange.range;\n // hack to make multi-day events that are being force-displayed as list-items to take up only one day\n if (this.forceDayIfListItem && eventRange.ui.display === 'list-item') {\n dateRange = {\n start: dateRange.start,\n end: addDays(dateRange.start, 1),\n };\n }\n let segs = this.sliceRange(dateRange, ...extraArgs);\n for (let seg of segs) {\n seg.eventRange = eventRange;\n seg.isStart = eventRange.isStart && seg.isStart;\n seg.isEnd = eventRange.isEnd && seg.isEnd;\n }\n return segs;\n }\n}\n/*\nfor incorporating slotMinTime/slotMaxTime if appropriate\nTODO: should be part of DateProfile!\nTimelineDateProfile already does this btw\n*/\nfunction computeActiveRange(dateProfile, isComponentAllDay) {\n let range = dateProfile.activeRange;\n if (isComponentAllDay) {\n return range;\n }\n return {\n start: addMs(range.start, dateProfile.slotMinTime.milliseconds),\n end: addMs(range.end, dateProfile.slotMaxTime.milliseconds - 864e5), // 864e5 = ms in a day\n };\n}\n\nfunction reduceEventStore(eventStore, action, eventSources, dateProfile, context) {\n switch (action.type) {\n case 'RECEIVE_EVENTS': // raw\n return receiveRawEvents(eventStore, eventSources[action.sourceId], action.fetchId, action.fetchRange, action.rawEvents, context);\n case 'ADD_EVENTS': // already parsed, but not expanded\n return addEvent(eventStore, action.eventStore, // new ones\n dateProfile ? dateProfile.activeRange : null, context);\n case 'RESET_EVENTS':\n return action.eventStore;\n case 'MERGE_EVENTS': // already parsed and expanded\n return mergeEventStores(eventStore, action.eventStore);\n case 'PREV': // TODO: how do we track all actions that affect dateProfile :(\n case 'NEXT':\n case 'CHANGE_DATE':\n case 'CHANGE_VIEW_TYPE':\n if (dateProfile) {\n return expandRecurring(eventStore, dateProfile.activeRange, context);\n }\n return eventStore;\n case 'REMOVE_EVENTS':\n return excludeSubEventStore(eventStore, action.eventStore);\n case 'REMOVE_EVENT_SOURCE':\n return excludeEventsBySourceId(eventStore, action.sourceId);\n case 'REMOVE_ALL_EVENT_SOURCES':\n return filterEventStoreDefs(eventStore, (eventDef) => (!eventDef.sourceId // only keep events with no source id\n ));\n case 'REMOVE_ALL_EVENTS':\n return createEmptyEventStore();\n default:\n return eventStore;\n }\n}\nfunction receiveRawEvents(eventStore, eventSource, fetchId, fetchRange, rawEvents, context) {\n if (eventSource && // not already removed\n fetchId === eventSource.latestFetchId // TODO: wish this logic was always in event-sources\n ) {\n let subset = parseEvents(transformRawEvents(rawEvents, eventSource, context), eventSource, context);\n if (fetchRange) {\n subset = expandRecurring(subset, fetchRange, context);\n }\n return mergeEventStores(excludeEventsBySourceId(eventStore, eventSource.sourceId), subset);\n }\n return eventStore;\n}\nfunction transformRawEvents(rawEvents, eventSource, context) {\n let calEachTransform = context.options.eventDataTransform;\n let sourceEachTransform = eventSource ? eventSource.eventDataTransform : null;\n if (sourceEachTransform) {\n rawEvents = transformEachRawEvent(rawEvents, sourceEachTransform);\n }\n if (calEachTransform) {\n rawEvents = transformEachRawEvent(rawEvents, calEachTransform);\n }\n return rawEvents;\n}\nfunction transformEachRawEvent(rawEvents, func) {\n let refinedEvents;\n if (!func) {\n refinedEvents = rawEvents;\n }\n else {\n refinedEvents = [];\n for (let rawEvent of rawEvents) {\n let refinedEvent = func(rawEvent);\n if (refinedEvent) {\n refinedEvents.push(refinedEvent);\n }\n else if (refinedEvent == null) {\n refinedEvents.push(rawEvent);\n } // if a different falsy value, do nothing\n }\n }\n return refinedEvents;\n}\nfunction addEvent(eventStore, subset, expandRange, context) {\n if (expandRange) {\n subset = expandRecurring(subset, expandRange, context);\n }\n return mergeEventStores(eventStore, subset);\n}\nfunction rezoneEventStoreDates(eventStore, oldDateEnv, newDateEnv) {\n let { defs } = eventStore;\n let instances = mapHash(eventStore.instances, (instance) => {\n let def = defs[instance.defId];\n if (def.allDay || def.recurringDef) {\n return instance; // isn't dependent on timezone\n }\n return Object.assign(Object.assign({}, instance), { range: {\n start: newDateEnv.createMarker(oldDateEnv.toDate(instance.range.start, instance.forcedStartTzo)),\n end: newDateEnv.createMarker(oldDateEnv.toDate(instance.range.end, instance.forcedEndTzo)),\n }, forcedStartTzo: newDateEnv.canComputeOffset ? null : instance.forcedStartTzo, forcedEndTzo: newDateEnv.canComputeOffset ? null : instance.forcedEndTzo });\n });\n return { defs, instances };\n}\nfunction excludeEventsBySourceId(eventStore, sourceId) {\n return filterEventStoreDefs(eventStore, (eventDef) => eventDef.sourceId !== sourceId);\n}\n// QUESTION: why not just return instances? do a general object-property-exclusion util\nfunction excludeInstances(eventStore, removals) {\n return {\n defs: eventStore.defs,\n instances: filterHash(eventStore.instances, (instance) => !removals[instance.instanceId]),\n };\n}\n\n// high-level segmenting-aware tester functions\n// ------------------------------------------------------------------------------------------------------------------------\nfunction isInteractionValid(interaction, dateProfile, context) {\n let { instances } = interaction.mutatedEvents;\n for (let instanceId in instances) {\n if (!rangeContainsRange(dateProfile.validRange, instances[instanceId].range)) {\n return false;\n }\n }\n return isNewPropsValid({ eventDrag: interaction }, context); // HACK: the eventDrag props is used for ALL interactions\n}\nfunction isDateSelectionValid(dateSelection, dateProfile, context) {\n if (!rangeContainsRange(dateProfile.validRange, dateSelection.range)) {\n return false;\n }\n return isNewPropsValid({ dateSelection }, context);\n}\nfunction isNewPropsValid(newProps, context) {\n let calendarState = context.getCurrentData();\n let props = Object.assign({ businessHours: calendarState.businessHours, dateSelection: '', eventStore: calendarState.eventStore, eventUiBases: calendarState.eventUiBases, eventSelection: '', eventDrag: null, eventResize: null }, newProps);\n return (context.pluginHooks.isPropsValid || isPropsValid)(props, context);\n}\nfunction isPropsValid(state, context, dateSpanMeta = {}, filterConfig) {\n if (state.eventDrag && !isInteractionPropsValid(state, context, dateSpanMeta, filterConfig)) {\n return false;\n }\n if (state.dateSelection && !isDateSelectionPropsValid(state, context, dateSpanMeta, filterConfig)) {\n return false;\n }\n return true;\n}\n// Moving Event Validation\n// ------------------------------------------------------------------------------------------------------------------------\nfunction isInteractionPropsValid(state, context, dateSpanMeta, filterConfig) {\n let currentState = context.getCurrentData();\n let interaction = state.eventDrag; // HACK: the eventDrag props is used for ALL interactions\n let subjectEventStore = interaction.mutatedEvents;\n let subjectDefs = subjectEventStore.defs;\n let subjectInstances = subjectEventStore.instances;\n let subjectConfigs = compileEventUis(subjectDefs, interaction.isEvent ?\n state.eventUiBases :\n { '': currentState.selectionConfig });\n if (filterConfig) {\n subjectConfigs = mapHash(subjectConfigs, filterConfig);\n }\n // exclude the subject events. TODO: exclude defs too?\n let otherEventStore = excludeInstances(state.eventStore, interaction.affectedEvents.instances);\n let otherDefs = otherEventStore.defs;\n let otherInstances = otherEventStore.instances;\n let otherConfigs = compileEventUis(otherDefs, state.eventUiBases);\n for (let subjectInstanceId in subjectInstances) {\n let subjectInstance = subjectInstances[subjectInstanceId];\n let subjectRange = subjectInstance.range;\n let subjectConfig = subjectConfigs[subjectInstance.defId];\n let subjectDef = subjectDefs[subjectInstance.defId];\n // constraint\n if (!allConstraintsPass(subjectConfig.constraints, subjectRange, otherEventStore, state.businessHours, context)) {\n return false;\n }\n // overlap\n let { eventOverlap } = context.options;\n let eventOverlapFunc = typeof eventOverlap === 'function' ? eventOverlap : null;\n for (let otherInstanceId in otherInstances) {\n let otherInstance = otherInstances[otherInstanceId];\n // intersect! evaluate\n if (rangesIntersect(subjectRange, otherInstance.range)) {\n let otherOverlap = otherConfigs[otherInstance.defId].overlap;\n // consider the other event's overlap. only do this if the subject event is a \"real\" event\n if (otherOverlap === false && interaction.isEvent) {\n return false;\n }\n if (subjectConfig.overlap === false) {\n return false;\n }\n if (eventOverlapFunc && !eventOverlapFunc(new EventImpl(context, otherDefs[otherInstance.defId], otherInstance), // still event\n new EventImpl(context, subjectDef, subjectInstance))) {\n return false;\n }\n }\n }\n // allow (a function)\n let calendarEventStore = currentState.eventStore; // need global-to-calendar, not local to component (splittable)state\n for (let subjectAllow of subjectConfig.allows) {\n let subjectDateSpan = Object.assign(Object.assign({}, dateSpanMeta), { range: subjectInstance.range, allDay: subjectDef.allDay });\n let origDef = calendarEventStore.defs[subjectDef.defId];\n let origInstance = calendarEventStore.instances[subjectInstanceId];\n let eventApi;\n if (origDef) { // was previously in the calendar\n eventApi = new EventImpl(context, origDef, origInstance);\n }\n else { // was an external event\n eventApi = new EventImpl(context, subjectDef); // no instance, because had no dates\n }\n if (!subjectAllow(buildDateSpanApiWithContext(subjectDateSpan, context), eventApi)) {\n return false;\n }\n }\n }\n return true;\n}\n// Date Selection Validation\n// ------------------------------------------------------------------------------------------------------------------------\nfunction isDateSelectionPropsValid(state, context, dateSpanMeta, filterConfig) {\n let relevantEventStore = state.eventStore;\n let relevantDefs = relevantEventStore.defs;\n let relevantInstances = relevantEventStore.instances;\n let selection = state.dateSelection;\n let selectionRange = selection.range;\n let { selectionConfig } = context.getCurrentData();\n if (filterConfig) {\n selectionConfig = filterConfig(selectionConfig);\n }\n // constraint\n if (!allConstraintsPass(selectionConfig.constraints, selectionRange, relevantEventStore, state.businessHours, context)) {\n return false;\n }\n // overlap\n let { selectOverlap } = context.options;\n let selectOverlapFunc = typeof selectOverlap === 'function' ? selectOverlap : null;\n for (let relevantInstanceId in relevantInstances) {\n let relevantInstance = relevantInstances[relevantInstanceId];\n // intersect! evaluate\n if (rangesIntersect(selectionRange, relevantInstance.range)) {\n if (selectionConfig.overlap === false) {\n return false;\n }\n if (selectOverlapFunc && !selectOverlapFunc(new EventImpl(context, relevantDefs[relevantInstance.defId], relevantInstance), null)) {\n return false;\n }\n }\n }\n // allow (a function)\n for (let selectionAllow of selectionConfig.allows) {\n let fullDateSpan = Object.assign(Object.assign({}, dateSpanMeta), selection);\n if (!selectionAllow(buildDateSpanApiWithContext(fullDateSpan, context), null)) {\n return false;\n }\n }\n return true;\n}\n// Constraint Utils\n// ------------------------------------------------------------------------------------------------------------------------\nfunction allConstraintsPass(constraints, subjectRange, otherEventStore, businessHoursUnexpanded, context) {\n for (let constraint of constraints) {\n if (!anyRangesContainRange(constraintToRanges(constraint, subjectRange, otherEventStore, businessHoursUnexpanded, context), subjectRange)) {\n return false;\n }\n }\n return true;\n}\nfunction constraintToRanges(constraint, subjectRange, // for expanding a recurring constraint, or expanding business hours\notherEventStore, // for if constraint is an even group ID\nbusinessHoursUnexpanded, // for if constraint is 'businessHours'\ncontext) {\n if (constraint === 'businessHours') {\n return eventStoreToRanges(expandRecurring(businessHoursUnexpanded, subjectRange, context));\n }\n if (typeof constraint === 'string') { // an group ID\n return eventStoreToRanges(filterEventStoreDefs(otherEventStore, (eventDef) => eventDef.groupId === constraint));\n }\n if (typeof constraint === 'object' && constraint) { // non-null object\n return eventStoreToRanges(expandRecurring(constraint, subjectRange, context));\n }\n return []; // if it's false\n}\n// TODO: move to event-store file?\nfunction eventStoreToRanges(eventStore) {\n let { instances } = eventStore;\n let ranges = [];\n for (let instanceId in instances) {\n ranges.push(instances[instanceId].range);\n }\n return ranges;\n}\n// TODO: move to geom file?\nfunction anyRangesContainRange(outerRanges, innerRange) {\n for (let outerRange of outerRanges) {\n if (rangeContainsRange(outerRange, innerRange)) {\n return true;\n }\n }\n return false;\n}\n\nclass JsonRequestError extends Error {\n constructor(message, response) {\n super(message);\n this.response = response;\n }\n}\nfunction requestJson(method, url, params) {\n method = method.toUpperCase();\n const fetchOptions = {\n method,\n };\n if (method === 'GET') {\n url += (url.indexOf('?') === -1 ? '?' : '&') +\n new URLSearchParams(params);\n }\n else {\n fetchOptions.body = new URLSearchParams(params);\n fetchOptions.headers = {\n 'Content-Type': 'application/x-www-form-urlencoded',\n };\n }\n return fetch(url, fetchOptions).then((fetchRes) => {\n if (fetchRes.ok) {\n return fetchRes.json().then((parsedResponse) => {\n return [parsedResponse, fetchRes];\n }, () => {\n throw new JsonRequestError('Failure parsing JSON', fetchRes);\n });\n }\n else {\n throw new JsonRequestError('Request failed', fetchRes);\n }\n });\n}\n\nclass DelayedRunner {\n constructor(drainedOption) {\n this.drainedOption = drainedOption;\n this.isRunning = false;\n this.isDirty = false;\n this.pauseDepths = {};\n this.timeoutId = 0;\n }\n request(delay) {\n this.isDirty = true;\n if (!this.isPaused()) {\n this.clearTimeout();\n if (delay == null) {\n this.tryDrain();\n }\n else {\n this.timeoutId = setTimeout(// NOT OPTIMAL! TODO: look at debounce\n this.tryDrain.bind(this), delay);\n }\n }\n }\n pause(scope = '') {\n let { pauseDepths } = this;\n pauseDepths[scope] = (pauseDepths[scope] || 0) + 1;\n this.clearTimeout();\n }\n resume(scope = '', force) {\n let { pauseDepths } = this;\n if (scope in pauseDepths) {\n if (force) {\n delete pauseDepths[scope];\n }\n else {\n pauseDepths[scope] -= 1;\n let depth = pauseDepths[scope];\n if (depth <= 0) {\n delete pauseDepths[scope];\n }\n }\n this.tryDrain();\n }\n }\n isPaused() {\n return Object.keys(this.pauseDepths).length;\n }\n tryDrain() {\n if (!this.isRunning && !this.isPaused()) {\n this.isRunning = true;\n while (this.isDirty) {\n this.isDirty = false;\n this.drained(); // might set isDirty to true again\n }\n this.isRunning = false;\n }\n }\n clear() {\n this.clearTimeout();\n this.isDirty = false;\n this.pauseDepths = {};\n }\n clearTimeout() {\n if (this.timeoutId) {\n clearTimeout(this.timeoutId);\n this.timeoutId = 0;\n }\n }\n drained() {\n if (this.drainedOption) {\n this.drainedOption();\n }\n }\n}\n\nconst VISIBLE_HIDDEN_RE = /^(visible|hidden)$/;\nclass Scroller extends BaseComponent {\n constructor() {\n super(...arguments);\n this.handleEl = (el) => {\n this.el = el;\n setRef(this.props.elRef, el);\n };\n }\n render() {\n let { props } = this;\n let { liquid, liquidIsAbsolute } = props;\n let isAbsolute = liquid && liquidIsAbsolute;\n let className = ['fc-scroller'];\n if (liquid) {\n if (liquidIsAbsolute) {\n className.push('fc-scroller-liquid-absolute');\n }\n else {\n className.push('fc-scroller-liquid');\n }\n }\n return ((0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(\"div\", { ref: this.handleEl, className: className.join(' '), style: {\n overflowX: props.overflowX,\n overflowY: props.overflowY,\n left: (isAbsolute && -(props.overcomeLeft || 0)) || '',\n right: (isAbsolute && -(props.overcomeRight || 0)) || '',\n bottom: (isAbsolute && -(props.overcomeBottom || 0)) || '',\n marginLeft: (!isAbsolute && -(props.overcomeLeft || 0)) || '',\n marginRight: (!isAbsolute && -(props.overcomeRight || 0)) || '',\n marginBottom: (!isAbsolute && -(props.overcomeBottom || 0)) || '',\n maxHeight: props.maxHeight || '',\n } }, props.children));\n }\n needsXScrolling() {\n if (VISIBLE_HIDDEN_RE.test(this.props.overflowX)) {\n return false;\n }\n // testing scrollWidth>clientWidth is unreliable cross-browser when pixel heights aren't integers.\n // much more reliable to see if children are taller than the scroller, even tho doesn't account for\n // inner-child margins and absolute positioning\n let { el } = this;\n let realClientWidth = this.el.getBoundingClientRect().width - this.getYScrollbarWidth();\n let { children } = el;\n for (let i = 0; i < children.length; i += 1) {\n let childEl = children[i];\n if (childEl.getBoundingClientRect().width > realClientWidth) {\n return true;\n }\n }\n return false;\n }\n needsYScrolling() {\n if (VISIBLE_HIDDEN_RE.test(this.props.overflowY)) {\n return false;\n }\n // testing scrollHeight>clientHeight is unreliable cross-browser when pixel heights aren't integers.\n // much more reliable to see if children are taller than the scroller, even tho doesn't account for\n // inner-child margins and absolute positioning\n let { el } = this;\n let realClientHeight = this.el.getBoundingClientRect().height - this.getXScrollbarWidth();\n let { children } = el;\n for (let i = 0; i < children.length; i += 1) {\n let childEl = children[i];\n if (childEl.getBoundingClientRect().height > realClientHeight) {\n return true;\n }\n }\n return false;\n }\n getXScrollbarWidth() {\n if (VISIBLE_HIDDEN_RE.test(this.props.overflowX)) {\n return 0;\n }\n return this.el.offsetHeight - this.el.clientHeight; // only works because we guarantee no borders. TODO: add to CSS with important?\n }\n getYScrollbarWidth() {\n if (VISIBLE_HIDDEN_RE.test(this.props.overflowY)) {\n return 0;\n }\n return this.el.offsetWidth - this.el.clientWidth; // only works because we guarantee no borders. TODO: add to CSS with important?\n }\n}\n\n/*\nTODO: somehow infer OtherArgs from masterCallback?\nTODO: infer RefType from masterCallback if provided\n*/\nclass RefMap {\n constructor(masterCallback) {\n this.masterCallback = masterCallback;\n this.currentMap = {};\n this.depths = {};\n this.callbackMap = {};\n this.handleValue = (val, key) => {\n let { depths, currentMap } = this;\n let removed = false;\n let added = false;\n if (val !== null) {\n // for bug... ACTUALLY: can probably do away with this now that callers don't share numeric indices anymore\n removed = (key in currentMap);\n currentMap[key] = val;\n depths[key] = (depths[key] || 0) + 1;\n added = true;\n }\n else {\n depths[key] -= 1;\n if (!depths[key]) {\n delete currentMap[key];\n delete this.callbackMap[key];\n removed = true;\n }\n }\n if (this.masterCallback) {\n if (removed) {\n this.masterCallback(null, String(key));\n }\n if (added) {\n this.masterCallback(val, String(key));\n }\n }\n };\n }\n createRef(key) {\n let refCallback = this.callbackMap[key];\n if (!refCallback) {\n refCallback = this.callbackMap[key] = (val) => {\n this.handleValue(val, String(key));\n };\n }\n return refCallback;\n }\n // TODO: check callers that don't care about order. should use getAll instead\n // NOTE: this method has become less valuable now that we are encouraged to map order by some other index\n // TODO: provide ONE array-export function, buildArray, which fails on non-numeric indexes. caller can manipulate and \"collect\"\n collect(startIndex, endIndex, step) {\n return collectFromHash(this.currentMap, startIndex, endIndex, step);\n }\n getAll() {\n return hashValuesToArray(this.currentMap);\n }\n}\n\nfunction computeShrinkWidth(chunkEls) {\n let shrinkCells = findElements(chunkEls, '.fc-scrollgrid-shrink');\n let largestWidth = 0;\n for (let shrinkCell of shrinkCells) {\n largestWidth = Math.max(largestWidth, computeSmallestCellWidth(shrinkCell));\n }\n return Math.ceil(largestWidth); // elements work best with integers. round up to ensure contents fits\n}\nfunction getSectionHasLiquidHeight(props, sectionConfig) {\n return props.liquid && sectionConfig.liquid; // does the section do liquid-height? (need to have whole scrollgrid liquid-height as well)\n}\nfunction getAllowYScrolling(props, sectionConfig) {\n return sectionConfig.maxHeight != null || // if its possible for the height to max out, we might need scrollbars\n getSectionHasLiquidHeight(props, sectionConfig); // if the section is liquid height, it might condense enough to require scrollbars\n}\n// TODO: ONLY use `arg`. force out internal function to use same API\nfunction renderChunkContent(sectionConfig, chunkConfig, arg, isHeader) {\n let { expandRows } = arg;\n let content = typeof chunkConfig.content === 'function' ?\n chunkConfig.content(arg) :\n (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)('table', {\n role: 'presentation',\n className: [\n chunkConfig.tableClassName,\n sectionConfig.syncRowHeights ? 'fc-scrollgrid-sync-table' : '',\n ].join(' '),\n style: {\n minWidth: arg.tableMinWidth,\n width: arg.clientWidth,\n height: expandRows ? arg.clientHeight : '', // css `height` on a
serves as a min-height\n },\n }, arg.tableColGroupNode, (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(isHeader ? 'thead' : 'tbody', {\n role: 'presentation',\n }, typeof chunkConfig.rowContent === 'function'\n ? chunkConfig.rowContent(arg)\n : chunkConfig.rowContent));\n return content;\n}\nfunction isColPropsEqual(cols0, cols1) {\n return isArraysEqual(cols0, cols1, isPropsEqual);\n}\nfunction renderMicroColGroup(cols, shrinkWidth) {\n let colNodes = [];\n /*\n for ColProps with spans, it would have been great to make a single \n HOWEVER, Chrome was getting messing up distributing the width to elements makes Chrome behave.\n */\n for (let colProps of cols) {\n let span = colProps.span || 1;\n for (let i = 0; i < span; i += 1) {\n colNodes.push((0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(\"col\", { style: {\n width: colProps.width === 'shrink' ? sanitizeShrinkWidth(shrinkWidth) : (colProps.width || ''),\n minWidth: colProps.minWidth || '',\n } }));\n }\n }\n return (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)('colgroup', {}, ...colNodes);\n}\nfunction sanitizeShrinkWidth(shrinkWidth) {\n /* why 4? if we do 0, it will kill any border, which are needed for computeSmallestCellWidth\n 4 accounts for 2 2-pixel borders. TODO: better solution? */\n return shrinkWidth == null ? 4 : shrinkWidth;\n}\nfunction hasShrinkWidth(cols) {\n for (let col of cols) {\n if (col.width === 'shrink') {\n return true;\n }\n }\n return false;\n}\nfunction getScrollGridClassNames(liquid, context) {\n let classNames = [\n 'fc-scrollgrid',\n context.theme.getClass('table'),\n ];\n if (liquid) {\n classNames.push('fc-scrollgrid-liquid');\n }\n return classNames;\n}\nfunction getSectionClassNames(sectionConfig, wholeTableVGrow) {\n let classNames = [\n 'fc-scrollgrid-section',\n `fc-scrollgrid-section-${sectionConfig.type}`,\n sectionConfig.className, // used?\n ];\n if (wholeTableVGrow && sectionConfig.liquid && sectionConfig.maxHeight == null) {\n classNames.push('fc-scrollgrid-section-liquid');\n }\n if (sectionConfig.isSticky) {\n classNames.push('fc-scrollgrid-section-sticky');\n }\n return classNames;\n}\nfunction renderScrollShim(arg) {\n return ((0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(\"div\", { className: \"fc-scrollgrid-sticky-shim\", style: {\n width: arg.clientWidth,\n minWidth: arg.tableMinWidth,\n } }));\n}\nfunction getStickyHeaderDates(options) {\n let { stickyHeaderDates } = options;\n if (stickyHeaderDates == null || stickyHeaderDates === 'auto') {\n stickyHeaderDates = options.height === 'auto' || options.viewHeight === 'auto';\n }\n return stickyHeaderDates;\n}\nfunction getStickyFooterScrollbar(options) {\n let { stickyFooterScrollbar } = options;\n if (stickyFooterScrollbar == null || stickyFooterScrollbar === 'auto') {\n stickyFooterScrollbar = options.height === 'auto' || options.viewHeight === 'auto';\n }\n return stickyFooterScrollbar;\n}\n\nclass SimpleScrollGrid extends BaseComponent {\n constructor() {\n super(...arguments);\n this.processCols = memoize((a) => a, isColPropsEqual); // so we get same `cols` props every time\n // yucky to memoize VNodes, but much more efficient for consumers\n this.renderMicroColGroup = memoize(renderMicroColGroup);\n this.scrollerRefs = new RefMap();\n this.scrollerElRefs = new RefMap(this._handleScrollerEl.bind(this));\n this.state = {\n shrinkWidth: null,\n forceYScrollbars: false,\n scrollerClientWidths: {},\n scrollerClientHeights: {},\n };\n // TODO: can do a really simple print-view. dont need to join rows\n this.handleSizing = () => {\n this.safeSetState(Object.assign({ shrinkWidth: this.computeShrinkWidth() }, this.computeScrollerDims()));\n };\n }\n render() {\n let { props, state, context } = this;\n let sectionConfigs = props.sections || [];\n let cols = this.processCols(props.cols);\n let microColGroupNode = this.renderMicroColGroup(cols, state.shrinkWidth);\n let classNames = getScrollGridClassNames(props.liquid, context);\n if (props.collapsibleWidth) {\n classNames.push('fc-scrollgrid-collapsible');\n }\n // TODO: make DRY\n let configCnt = sectionConfigs.length;\n let configI = 0;\n let currentConfig;\n let headSectionNodes = [];\n let bodySectionNodes = [];\n let footSectionNodes = [];\n while (configI < configCnt && (currentConfig = sectionConfigs[configI]).type === 'header') {\n headSectionNodes.push(this.renderSection(currentConfig, microColGroupNode, true));\n configI += 1;\n }\n while (configI < configCnt && (currentConfig = sectionConfigs[configI]).type === 'body') {\n bodySectionNodes.push(this.renderSection(currentConfig, microColGroupNode, false));\n configI += 1;\n }\n while (configI < configCnt && (currentConfig = sectionConfigs[configI]).type === 'footer') {\n footSectionNodes.push(this.renderSection(currentConfig, microColGroupNode, true));\n configI += 1;\n }\n // firefox bug: when setting height on table and there is a thead or tfoot,\n // the necessary height:100% on the liquid-height body section forces the *whole* table to be taller. (bug #5524)\n // use getCanVGrowWithinCell as a way to detect table-stupid firefox.\n // if so, use a simpler dom structure, jam everything into a lone tbody.\n let isBuggy = !getCanVGrowWithinCell();\n const roleAttrs = { role: 'rowgroup' };\n return (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)('table', {\n role: 'grid',\n className: classNames.join(' '),\n style: { height: props.height },\n }, Boolean(!isBuggy && headSectionNodes.length) && (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)('thead', roleAttrs, ...headSectionNodes), Boolean(!isBuggy && bodySectionNodes.length) && (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)('tbody', roleAttrs, ...bodySectionNodes), Boolean(!isBuggy && footSectionNodes.length) && (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)('tfoot', roleAttrs, ...footSectionNodes), isBuggy && (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)('tbody', roleAttrs, ...headSectionNodes, ...bodySectionNodes, ...footSectionNodes));\n }\n renderSection(sectionConfig, microColGroupNode, isHeader) {\n if ('outerContent' in sectionConfig) {\n return ((0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(preact__WEBPACK_IMPORTED_MODULE_0__.Fragment, { key: sectionConfig.key }, sectionConfig.outerContent));\n }\n return ((0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(\"tr\", { key: sectionConfig.key, role: \"presentation\", className: getSectionClassNames(sectionConfig, this.props.liquid).join(' ') }, this.renderChunkTd(sectionConfig, microColGroupNode, sectionConfig.chunk, isHeader)));\n }\n renderChunkTd(sectionConfig, microColGroupNode, chunkConfig, isHeader) {\n if ('outerContent' in chunkConfig) {\n return chunkConfig.outerContent;\n }\n let { props } = this;\n let { forceYScrollbars, scrollerClientWidths, scrollerClientHeights } = this.state;\n let needsYScrolling = getAllowYScrolling(props, sectionConfig); // TODO: do lazily. do in section config?\n let isLiquid = getSectionHasLiquidHeight(props, sectionConfig);\n // for `!props.liquid` - is WHOLE scrollgrid natural height?\n // TODO: do same thing in advanced scrollgrid? prolly not b/c always has horizontal scrollbars\n let overflowY = !props.liquid ? 'visible' :\n forceYScrollbars ? 'scroll' :\n !needsYScrolling ? 'hidden' :\n 'auto';\n let sectionKey = sectionConfig.key;\n let content = renderChunkContent(sectionConfig, chunkConfig, {\n tableColGroupNode: microColGroupNode,\n tableMinWidth: '',\n clientWidth: (!props.collapsibleWidth && scrollerClientWidths[sectionKey] !== undefined) ? scrollerClientWidths[sectionKey] : null,\n clientHeight: scrollerClientHeights[sectionKey] !== undefined ? scrollerClientHeights[sectionKey] : null,\n expandRows: sectionConfig.expandRows,\n syncRowHeights: false,\n rowSyncHeights: [],\n reportRowHeightChange: () => { },\n }, isHeader);\n return (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(isHeader ? 'th' : 'td', {\n ref: chunkConfig.elRef,\n role: 'presentation',\n }, (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(\"div\", { className: `fc-scroller-harness${isLiquid ? ' fc-scroller-harness-liquid' : ''}` },\n (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(Scroller, { ref: this.scrollerRefs.createRef(sectionKey), elRef: this.scrollerElRefs.createRef(sectionKey), overflowY: overflowY, overflowX: !props.liquid ? 'visible' : 'hidden' /* natural height? */, maxHeight: sectionConfig.maxHeight, liquid: isLiquid, liquidIsAbsolute // because its within a harness\n : true }, content)));\n }\n _handleScrollerEl(scrollerEl, key) {\n let section = getSectionByKey(this.props.sections, key);\n if (section) {\n setRef(section.chunk.scrollerElRef, scrollerEl);\n }\n }\n componentDidMount() {\n this.handleSizing();\n this.context.addResizeHandler(this.handleSizing);\n }\n componentDidUpdate() {\n // TODO: need better solution when state contains non-sizing things\n this.handleSizing();\n }\n componentWillUnmount() {\n this.context.removeResizeHandler(this.handleSizing);\n }\n computeShrinkWidth() {\n return hasShrinkWidth(this.props.cols)\n ? computeShrinkWidth(this.scrollerElRefs.getAll())\n : 0;\n }\n computeScrollerDims() {\n let scrollbarWidth = getScrollbarWidths();\n let { scrollerRefs, scrollerElRefs } = this;\n let forceYScrollbars = false;\n let scrollerClientWidths = {};\n let scrollerClientHeights = {};\n for (let sectionKey in scrollerRefs.currentMap) {\n let scroller = scrollerRefs.currentMap[sectionKey];\n if (scroller && scroller.needsYScrolling()) {\n forceYScrollbars = true;\n break;\n }\n }\n for (let section of this.props.sections) {\n let sectionKey = section.key;\n let scrollerEl = scrollerElRefs.currentMap[sectionKey];\n if (scrollerEl) {\n let harnessEl = scrollerEl.parentNode; // TODO: weird way to get this. need harness b/c doesn't include table borders\n scrollerClientWidths[sectionKey] = Math.floor(harnessEl.getBoundingClientRect().width - (forceYScrollbars\n ? scrollbarWidth.y // use global because scroller might not have scrollbars yet but will need them in future\n : 0));\n scrollerClientHeights[sectionKey] = Math.floor(harnessEl.getBoundingClientRect().height);\n }\n }\n return { forceYScrollbars, scrollerClientWidths, scrollerClientHeights };\n }\n}\nSimpleScrollGrid.addStateEquality({\n scrollerClientWidths: isPropsEqual,\n scrollerClientHeights: isPropsEqual,\n});\nfunction getSectionByKey(sections, key) {\n for (let section of sections) {\n if (section.key === key) {\n return section;\n }\n }\n return null;\n}\n\nclass EventContainer extends BaseComponent {\n constructor() {\n super(...arguments);\n this.handleEl = (el) => {\n this.el = el;\n if (el) {\n setElSeg(el, this.props.seg);\n }\n };\n }\n render() {\n const { props, context } = this;\n const { options } = context;\n const { seg } = props;\n const { eventRange } = seg;\n const { ui } = eventRange;\n const renderProps = {\n event: new EventImpl(context, eventRange.def, eventRange.instance),\n view: context.viewApi,\n timeText: props.timeText,\n textColor: ui.textColor,\n backgroundColor: ui.backgroundColor,\n borderColor: ui.borderColor,\n isDraggable: !props.disableDragging && computeSegDraggable(seg, context),\n isStartResizable: !props.disableResizing && computeSegStartResizable(seg, context),\n isEndResizable: !props.disableResizing && computeSegEndResizable(seg),\n isMirror: Boolean(props.isDragging || props.isResizing || props.isDateSelecting),\n isStart: Boolean(seg.isStart),\n isEnd: Boolean(seg.isEnd),\n isPast: Boolean(props.isPast),\n isFuture: Boolean(props.isFuture),\n isToday: Boolean(props.isToday),\n isSelected: Boolean(props.isSelected),\n isDragging: Boolean(props.isDragging),\n isResizing: Boolean(props.isResizing),\n };\n return ((0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(ContentContainer, Object.assign({}, props /* contains children */, { elRef: this.handleEl, elClasses: [\n ...getEventClassNames(renderProps),\n ...seg.eventRange.ui.classNames,\n ...(props.elClasses || []),\n ], renderProps: renderProps, generatorName: \"eventContent\", generator: options.eventContent || props.defaultGenerator, classNameGenerator: options.eventClassNames, didMount: options.eventDidMount, willUnmount: options.eventWillUnmount })));\n }\n componentDidUpdate(prevProps) {\n if (this.el && this.props.seg !== prevProps.seg) {\n setElSeg(this.el, this.props.seg);\n }\n }\n}\n\n// should not be a purecomponent\nclass StandardEvent extends BaseComponent {\n render() {\n let { props, context } = this;\n let { options } = context;\n let { seg } = props;\n let { ui } = seg.eventRange;\n let timeFormat = options.eventTimeFormat || props.defaultTimeFormat;\n let timeText = buildSegTimeText(seg, timeFormat, context, props.defaultDisplayEventTime, props.defaultDisplayEventEnd);\n return ((0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(EventContainer, Object.assign({}, props /* includes elRef */, { elTag: \"a\", elStyle: {\n borderColor: ui.borderColor,\n backgroundColor: ui.backgroundColor,\n }, elAttrs: getSegAnchorAttrs(seg, context), defaultGenerator: renderInnerContent$1, timeText: timeText }), (InnerContent, eventContentArg) => ((0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(preact__WEBPACK_IMPORTED_MODULE_0__.Fragment, null,\n (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(InnerContent, { elTag: \"div\", elClasses: ['fc-event-main'], elStyle: { color: eventContentArg.textColor } }),\n Boolean(eventContentArg.isStartResizable) && ((0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(\"div\", { className: \"fc-event-resizer fc-event-resizer-start\" })),\n Boolean(eventContentArg.isEndResizable) && ((0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(\"div\", { className: \"fc-event-resizer fc-event-resizer-end\" }))))));\n }\n}\nfunction renderInnerContent$1(innerProps) {\n return ((0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(\"div\", { className: \"fc-event-main-frame\" },\n innerProps.timeText && ((0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(\"div\", { className: \"fc-event-time\" }, innerProps.timeText)),\n (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(\"div\", { className: \"fc-event-title-container\" },\n (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(\"div\", { className: \"fc-event-title fc-sticky\" }, innerProps.event.title || (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(preact__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, \"\\u00A0\")))));\n}\n\nconst NowIndicatorContainer = (props) => ((0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(ViewContextType.Consumer, null, (context) => {\n let { options } = context;\n let renderProps = {\n isAxis: props.isAxis,\n date: context.dateEnv.toDate(props.date),\n view: context.viewApi,\n };\n return ((0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(ContentContainer, Object.assign({}, props /* includes children */, { elTag: props.elTag || 'div', renderProps: renderProps, generatorName: \"nowIndicatorContent\", generator: options.nowIndicatorContent, classNameGenerator: options.nowIndicatorClassNames, didMount: options.nowIndicatorDidMount, willUnmount: options.nowIndicatorWillUnmount })));\n}));\n\nconst DAY_NUM_FORMAT = createFormatter({ day: 'numeric' });\nclass DayCellContainer extends BaseComponent {\n constructor() {\n super(...arguments);\n this.refineRenderProps = memoizeObjArg(refineRenderProps);\n }\n render() {\n let { props, context } = this;\n let { options } = context;\n let renderProps = this.refineRenderProps({\n date: props.date,\n dateProfile: props.dateProfile,\n todayRange: props.todayRange,\n showDayNumber: props.showDayNumber,\n extraRenderProps: props.extraRenderProps,\n viewApi: context.viewApi,\n dateEnv: context.dateEnv,\n });\n return ((0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(ContentContainer, Object.assign({}, props /* includes children */, { elClasses: [\n ...getDayClassNames(renderProps, context.theme),\n ...(props.elClasses || []),\n ], elAttrs: Object.assign(Object.assign({}, props.elAttrs), (renderProps.isDisabled ? {} : { 'data-date': formatDayString(props.date) })), renderProps: renderProps, generatorName: \"dayCellContent\", generator: options.dayCellContent || props.defaultGenerator, classNameGenerator: \n // don't use custom classNames if disabled\n renderProps.isDisabled ? undefined : options.dayCellClassNames, didMount: options.dayCellDidMount, willUnmount: options.dayCellWillUnmount })));\n }\n}\nfunction hasCustomDayCellContent(options) {\n return Boolean(options.dayCellContent || hasCustomRenderingHandler('dayCellContent', options));\n}\nfunction refineRenderProps(raw) {\n let { date, dateEnv } = raw;\n let dayMeta = getDateMeta(date, raw.todayRange, null, raw.dateProfile);\n return Object.assign(Object.assign(Object.assign({ date: dateEnv.toDate(date), view: raw.viewApi }, dayMeta), { dayNumberText: raw.showDayNumber ? dateEnv.format(date, DAY_NUM_FORMAT) : '' }), raw.extraRenderProps);\n}\n\nclass BgEvent extends BaseComponent {\n render() {\n let { props } = this;\n let { seg } = props;\n return ((0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(EventContainer, { elTag: \"div\", elClasses: ['fc-bg-event'], elStyle: { backgroundColor: seg.eventRange.ui.backgroundColor }, defaultGenerator: renderInnerContent, seg: seg, timeText: \"\", isDragging: false, isResizing: false, isDateSelecting: false, isSelected: false, isPast: props.isPast, isFuture: props.isFuture, isToday: props.isToday, disableDragging: true, disableResizing: true }));\n }\n}\nfunction renderInnerContent(props) {\n let { title } = props.event;\n return title && ((0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(\"div\", { className: \"fc-event-title\" }, props.event.title));\n}\nfunction renderFill(fillType) {\n return ((0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(\"div\", { className: `fc-${fillType}` }));\n}\n\nconst WeekNumberContainer = (props) => ((0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(ViewContextType.Consumer, null, (context) => {\n let { dateEnv, options } = context;\n let { date } = props;\n let format = options.weekNumberFormat || props.defaultFormat;\n let num = dateEnv.computeWeekNumber(date); // TODO: somehow use for formatting as well?\n let text = dateEnv.format(date, format);\n let renderProps = { num, text, date };\n return ((0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(ContentContainer // why isn't WeekNumberContentArg being auto-detected?\n , Object.assign({}, props /* includes children */, { renderProps: renderProps, generatorName: \"weekNumberContent\", generator: options.weekNumberContent || renderInner, classNameGenerator: options.weekNumberClassNames, didMount: options.weekNumberDidMount, willUnmount: options.weekNumberWillUnmount })));\n}));\nfunction renderInner(innerProps) {\n return innerProps.text;\n}\n\nconst PADDING_FROM_VIEWPORT = 10;\nclass Popover extends BaseComponent {\n constructor() {\n super(...arguments);\n this.state = {\n titleId: getUniqueDomId(),\n };\n this.handleRootEl = (el) => {\n this.rootEl = el;\n if (this.props.elRef) {\n setRef(this.props.elRef, el);\n }\n };\n // Triggered when the user clicks *anywhere* in the document, for the autoHide feature\n this.handleDocumentMouseDown = (ev) => {\n // only hide the popover if the click happened outside the popover\n const target = getEventTargetViaRoot(ev);\n if (!this.rootEl.contains(target)) {\n this.handleCloseClick();\n }\n };\n this.handleDocumentKeyDown = (ev) => {\n if (ev.key === 'Escape') {\n this.handleCloseClick();\n }\n };\n this.handleCloseClick = () => {\n let { onClose } = this.props;\n if (onClose) {\n onClose();\n }\n };\n }\n render() {\n let { theme, options } = this.context;\n let { props, state } = this;\n let classNames = [\n 'fc-popover',\n theme.getClass('popover'),\n ].concat(props.extraClassNames || []);\n return (0,preact_compat__WEBPACK_IMPORTED_MODULE_1__.createPortal)((0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(\"div\", Object.assign({}, props.extraAttrs, { id: props.id, className: classNames.join(' '), \"aria-labelledby\": state.titleId, ref: this.handleRootEl }),\n (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(\"div\", { className: 'fc-popover-header ' + theme.getClass('popoverHeader') },\n (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(\"span\", { className: \"fc-popover-title\", id: state.titleId }, props.title),\n (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(\"span\", { className: 'fc-popover-close ' + theme.getIconClass('close'), title: options.closeHint, onClick: this.handleCloseClick })),\n (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(\"div\", { className: 'fc-popover-body ' + theme.getClass('popoverContent') }, props.children)), props.parentEl);\n }\n componentDidMount() {\n document.addEventListener('mousedown', this.handleDocumentMouseDown);\n document.addEventListener('keydown', this.handleDocumentKeyDown);\n this.updateSize();\n }\n componentWillUnmount() {\n document.removeEventListener('mousedown', this.handleDocumentMouseDown);\n document.removeEventListener('keydown', this.handleDocumentKeyDown);\n }\n updateSize() {\n let { isRtl } = this.context;\n let { alignmentEl, alignGridTop } = this.props;\n let { rootEl } = this;\n let alignmentRect = computeClippedClientRect(alignmentEl);\n if (alignmentRect) {\n let popoverDims = rootEl.getBoundingClientRect();\n // position relative to viewport\n let popoverTop = alignGridTop\n ? elementClosest(alignmentEl, '.fc-scrollgrid').getBoundingClientRect().top\n : alignmentRect.top;\n let popoverLeft = isRtl ? alignmentRect.right - popoverDims.width : alignmentRect.left;\n // constrain\n popoverTop = Math.max(popoverTop, PADDING_FROM_VIEWPORT);\n popoverLeft = Math.min(popoverLeft, document.documentElement.clientWidth - PADDING_FROM_VIEWPORT - popoverDims.width);\n popoverLeft = Math.max(popoverLeft, PADDING_FROM_VIEWPORT);\n let origin = rootEl.offsetParent.getBoundingClientRect();\n applyStyle(rootEl, {\n top: popoverTop - origin.top,\n left: popoverLeft - origin.left,\n });\n }\n }\n}\n\nclass MorePopover extends DateComponent {\n constructor() {\n super(...arguments);\n this.handleRootEl = (rootEl) => {\n this.rootEl = rootEl;\n if (rootEl) {\n this.context.registerInteractiveComponent(this, {\n el: rootEl,\n useEventCenter: false,\n });\n }\n else {\n this.context.unregisterInteractiveComponent(this);\n }\n };\n }\n render() {\n let { options, dateEnv } = this.context;\n let { props } = this;\n let { startDate, todayRange, dateProfile } = props;\n let title = dateEnv.format(startDate, options.dayPopoverFormat);\n return ((0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(DayCellContainer, { elRef: this.handleRootEl, date: startDate, dateProfile: dateProfile, todayRange: todayRange }, (InnerContent, renderProps, elAttrs) => ((0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(Popover, { elRef: elAttrs.ref, id: props.id, title: title, extraClassNames: ['fc-more-popover'].concat(elAttrs.className || []), extraAttrs: elAttrs /* TODO: make these time-based when not whole-day? */, parentEl: props.parentEl, alignmentEl: props.alignmentEl, alignGridTop: props.alignGridTop, onClose: props.onClose },\n hasCustomDayCellContent(options) && ((0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(InnerContent, { elTag: \"div\", elClasses: ['fc-more-popover-misc'] })),\n props.children))));\n }\n queryHit(positionLeft, positionTop, elWidth, elHeight) {\n let { rootEl, props } = this;\n if (positionLeft >= 0 && positionLeft < elWidth &&\n positionTop >= 0 && positionTop < elHeight) {\n return {\n dateProfile: props.dateProfile,\n dateSpan: Object.assign({ allDay: true, range: {\n start: props.startDate,\n end: props.endDate,\n } }, props.extraDateSpan),\n dayEl: rootEl,\n rect: {\n left: 0,\n top: 0,\n right: elWidth,\n bottom: elHeight,\n },\n layer: 1, // important when comparing with hits from other components\n };\n }\n return null;\n }\n}\n\nclass MoreLinkContainer extends BaseComponent {\n constructor() {\n super(...arguments);\n this.state = {\n isPopoverOpen: false,\n popoverId: getUniqueDomId(),\n };\n this.handleLinkEl = (linkEl) => {\n this.linkEl = linkEl;\n if (this.props.elRef) {\n setRef(this.props.elRef, linkEl);\n }\n };\n this.handleClick = (ev) => {\n let { props, context } = this;\n let { moreLinkClick } = context.options;\n let date = computeRange(props).start;\n function buildPublicSeg(seg) {\n let { def, instance, range } = seg.eventRange;\n return {\n event: new EventImpl(context, def, instance),\n start: context.dateEnv.toDate(range.start),\n end: context.dateEnv.toDate(range.end),\n isStart: seg.isStart,\n isEnd: seg.isEnd,\n };\n }\n if (typeof moreLinkClick === 'function') {\n moreLinkClick = moreLinkClick({\n date,\n allDay: Boolean(props.allDayDate),\n allSegs: props.allSegs.map(buildPublicSeg),\n hiddenSegs: props.hiddenSegs.map(buildPublicSeg),\n jsEvent: ev,\n view: context.viewApi,\n });\n }\n if (!moreLinkClick || moreLinkClick === 'popover') {\n this.setState({ isPopoverOpen: true });\n }\n else if (typeof moreLinkClick === 'string') { // a view name\n context.calendarApi.zoomTo(date, moreLinkClick);\n }\n };\n this.handlePopoverClose = () => {\n this.setState({ isPopoverOpen: false });\n };\n }\n render() {\n let { props, state } = this;\n return ((0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(ViewContextType.Consumer, null, (context) => {\n let { viewApi, options, calendarApi } = context;\n let { moreLinkText } = options;\n let { moreCnt } = props;\n let range = computeRange(props);\n let text = typeof moreLinkText === 'function' // TODO: eventually use formatWithOrdinals\n ? moreLinkText.call(calendarApi, moreCnt)\n : `+${moreCnt} ${moreLinkText}`;\n let hint = formatWithOrdinals(options.moreLinkHint, [moreCnt], text);\n let renderProps = {\n num: moreCnt,\n shortText: `+${moreCnt}`,\n text,\n view: viewApi,\n };\n return ((0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(preact__WEBPACK_IMPORTED_MODULE_0__.Fragment, null,\n Boolean(props.moreCnt) && ((0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(ContentContainer, { elTag: props.elTag || 'a', elRef: this.handleLinkEl, elClasses: [\n ...(props.elClasses || []),\n 'fc-more-link',\n ], elStyle: props.elStyle, elAttrs: Object.assign(Object.assign(Object.assign({}, props.elAttrs), createAriaClickAttrs(this.handleClick)), { title: hint, 'aria-expanded': state.isPopoverOpen, 'aria-controls': state.isPopoverOpen ? state.popoverId : '' }), renderProps: renderProps, generatorName: \"moreLinkContent\", generator: options.moreLinkContent || props.defaultGenerator || renderMoreLinkInner, classNameGenerator: options.moreLinkClassNames, didMount: options.moreLinkDidMount, willUnmount: options.moreLinkWillUnmount }, props.children)),\n state.isPopoverOpen && ((0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(MorePopover, { id: state.popoverId, startDate: range.start, endDate: range.end, dateProfile: props.dateProfile, todayRange: props.todayRange, extraDateSpan: props.extraDateSpan, parentEl: this.parentEl, alignmentEl: props.alignmentElRef ?\n props.alignmentElRef.current :\n this.linkEl, alignGridTop: props.alignGridTop, onClose: this.handlePopoverClose }, props.popoverContent()))));\n }));\n }\n componentDidMount() {\n this.updateParentEl();\n }\n componentDidUpdate() {\n this.updateParentEl();\n }\n updateParentEl() {\n if (this.linkEl) {\n this.parentEl = elementClosest(this.linkEl, '.fc-view-harness');\n }\n }\n}\nfunction renderMoreLinkInner(props) {\n return props.text;\n}\nfunction computeRange(props) {\n if (props.allDayDate) {\n return {\n start: props.allDayDate,\n end: addDays(props.allDayDate, 1),\n };\n }\n let { hiddenSegs } = props;\n return {\n start: computeEarliestSegStart(hiddenSegs),\n end: computeLatestSegEnd(hiddenSegs),\n };\n}\nfunction computeEarliestSegStart(segs) {\n return segs.reduce(pickEarliestStart).eventRange.range.start;\n}\nfunction pickEarliestStart(seg0, seg1) {\n return seg0.eventRange.range.start < seg1.eventRange.range.start ? seg0 : seg1;\n}\nfunction computeLatestSegEnd(segs) {\n return segs.reduce(pickLatestEnd).eventRange.range.end;\n}\nfunction pickLatestEnd(seg0, seg1) {\n return seg0.eventRange.range.end > seg1.eventRange.range.end ? seg0 : seg1;\n}\n\nclass ViewContainer extends BaseComponent {\n render() {\n let { props, context } = this;\n let { options } = context;\n let renderProps = { view: context.viewApi };\n return ((0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(ContentContainer, Object.assign({}, props, { elTag: props.elTag || 'div', elClasses: [\n ...buildViewClassNames(props.viewSpec),\n ...(props.elClasses || []),\n ], renderProps: renderProps, classNameGenerator: options.viewClassNames, generatorName: undefined, generator: undefined, didMount: options.viewDidMount, willUnmount: options.viewWillUnmount }), () => props.children));\n }\n}\nfunction buildViewClassNames(viewSpec) {\n return [\n `fc-${viewSpec.type}-view`,\n 'fc-view',\n ];\n}\n\nfunction injectStyles(css) {\n if (!css || typeof document === 'undefined') {\n return;\n }\n const head = document.head || document.getElementsByTagName('head')[0];\n const style = document.createElement('style');\n style.type = 'text/css';\n head.appendChild(style);\n if (style.styleSheet) {\n style.styleSheet.cssText = css;\n }\n else {\n style.appendChild(document.createTextNode(css));\n }\n}\n\nconst EVENT_SOURCE_REFINERS = {\n id: String,\n defaultAllDay: Boolean,\n url: String,\n format: String,\n events: identity,\n eventDataTransform: identity,\n // for any network-related sources\n success: identity,\n failure: identity,\n};\nfunction parseEventSource(raw, context, refiners = buildEventSourceRefiners(context)) {\n let rawObj;\n if (typeof raw === 'string') {\n rawObj = { url: raw };\n }\n else if (typeof raw === 'function' || Array.isArray(raw)) {\n rawObj = { events: raw };\n }\n else if (typeof raw === 'object' && raw) { // not null\n rawObj = raw;\n }\n if (rawObj) {\n let { refined, extra } = refineProps(rawObj, refiners);\n let metaRes = buildEventSourceMeta(refined, context);\n if (metaRes) {\n return {\n _raw: raw,\n isFetching: false,\n latestFetchId: '',\n fetchRange: null,\n defaultAllDay: refined.defaultAllDay,\n eventDataTransform: refined.eventDataTransform,\n success: refined.success,\n failure: refined.failure,\n publicId: refined.id || '',\n sourceId: guid(),\n sourceDefId: metaRes.sourceDefId,\n meta: metaRes.meta,\n ui: createEventUi(refined, context),\n extendedProps: extra,\n };\n }\n }\n return null;\n}\nfunction buildEventSourceRefiners(context) {\n return Object.assign(Object.assign(Object.assign({}, EVENT_UI_REFINERS), EVENT_SOURCE_REFINERS), context.pluginHooks.eventSourceRefiners);\n}\nfunction buildEventSourceMeta(raw, context) {\n let defs = context.pluginHooks.eventSourceDefs;\n for (let i = defs.length - 1; i >= 0; i -= 1) { // later-added plugins take precedence\n let def = defs[i];\n let meta = def.parseMeta(raw);\n if (meta) {\n return { sourceDefId: i, meta };\n }\n }\n return null;\n}\n\nclass CalendarImpl {\n getCurrentData() {\n return this.currentDataManager.getCurrentData();\n }\n dispatch(action) {\n this.currentDataManager.dispatch(action);\n }\n get view() { return this.getCurrentData().viewApi; }\n batchRendering(callback) {\n callback();\n }\n updateSize() {\n this.trigger('_resize', true);\n }\n // Options\n // -----------------------------------------------------------------------------------------------------------------\n setOption(name, val) {\n this.dispatch({\n type: 'SET_OPTION',\n optionName: name,\n rawOptionValue: val,\n });\n }\n getOption(name) {\n return this.currentDataManager.currentCalendarOptionsInput[name];\n }\n getAvailableLocaleCodes() {\n return Object.keys(this.getCurrentData().availableRawLocales);\n }\n // Trigger\n // -----------------------------------------------------------------------------------------------------------------\n on(handlerName, handler) {\n let { currentDataManager } = this;\n if (currentDataManager.currentCalendarOptionsRefiners[handlerName]) {\n currentDataManager.emitter.on(handlerName, handler);\n }\n else {\n console.warn(`Unknown listener name '${handlerName}'`);\n }\n }\n off(handlerName, handler) {\n this.currentDataManager.emitter.off(handlerName, handler);\n }\n // not meant for public use\n trigger(handlerName, ...args) {\n this.currentDataManager.emitter.trigger(handlerName, ...args);\n }\n // View\n // -----------------------------------------------------------------------------------------------------------------\n changeView(viewType, dateOrRange) {\n this.batchRendering(() => {\n this.unselect();\n if (dateOrRange) {\n if (dateOrRange.start && dateOrRange.end) { // a range\n this.dispatch({\n type: 'CHANGE_VIEW_TYPE',\n viewType,\n });\n this.dispatch({\n type: 'SET_OPTION',\n optionName: 'visibleRange',\n rawOptionValue: dateOrRange,\n });\n }\n else {\n let { dateEnv } = this.getCurrentData();\n this.dispatch({\n type: 'CHANGE_VIEW_TYPE',\n viewType,\n dateMarker: dateEnv.createMarker(dateOrRange),\n });\n }\n }\n else {\n this.dispatch({\n type: 'CHANGE_VIEW_TYPE',\n viewType,\n });\n }\n });\n }\n // Forces navigation to a view for the given date.\n // `viewType` can be a specific view name or a generic one like \"week\" or \"day\".\n // needs to change\n zoomTo(dateMarker, viewType) {\n let state = this.getCurrentData();\n let spec;\n viewType = viewType || 'day'; // day is default zoom\n spec = state.viewSpecs[viewType] || this.getUnitViewSpec(viewType);\n this.unselect();\n if (spec) {\n this.dispatch({\n type: 'CHANGE_VIEW_TYPE',\n viewType: spec.type,\n dateMarker,\n });\n }\n else {\n this.dispatch({\n type: 'CHANGE_DATE',\n dateMarker,\n });\n }\n }\n // Given a duration singular unit, like \"week\" or \"day\", finds a matching view spec.\n // Preference is given to views that have corresponding buttons.\n getUnitViewSpec(unit) {\n let { viewSpecs, toolbarConfig } = this.getCurrentData();\n let viewTypes = [].concat(toolbarConfig.header ? toolbarConfig.header.viewsWithButtons : [], toolbarConfig.footer ? toolbarConfig.footer.viewsWithButtons : []);\n let i;\n let spec;\n for (let viewType in viewSpecs) {\n viewTypes.push(viewType);\n }\n for (i = 0; i < viewTypes.length; i += 1) {\n spec = viewSpecs[viewTypes[i]];\n if (spec) {\n if (spec.singleUnit === unit) {\n return spec;\n }\n }\n }\n return null;\n }\n // Current Date\n // -----------------------------------------------------------------------------------------------------------------\n prev() {\n this.unselect();\n this.dispatch({ type: 'PREV' });\n }\n next() {\n this.unselect();\n this.dispatch({ type: 'NEXT' });\n }\n prevYear() {\n let state = this.getCurrentData();\n this.unselect();\n this.dispatch({\n type: 'CHANGE_DATE',\n dateMarker: state.dateEnv.addYears(state.currentDate, -1),\n });\n }\n nextYear() {\n let state = this.getCurrentData();\n this.unselect();\n this.dispatch({\n type: 'CHANGE_DATE',\n dateMarker: state.dateEnv.addYears(state.currentDate, 1),\n });\n }\n today() {\n let state = this.getCurrentData();\n this.unselect();\n this.dispatch({\n type: 'CHANGE_DATE',\n dateMarker: getNow(state.calendarOptions.now, state.dateEnv),\n });\n }\n gotoDate(zonedDateInput) {\n let state = this.getCurrentData();\n this.unselect();\n this.dispatch({\n type: 'CHANGE_DATE',\n dateMarker: state.dateEnv.createMarker(zonedDateInput),\n });\n }\n incrementDate(deltaInput) {\n let state = this.getCurrentData();\n let delta = createDuration(deltaInput);\n if (delta) { // else, warn about invalid input?\n this.unselect();\n this.dispatch({\n type: 'CHANGE_DATE',\n dateMarker: state.dateEnv.add(state.currentDate, delta),\n });\n }\n }\n getDate() {\n let state = this.getCurrentData();\n return state.dateEnv.toDate(state.currentDate);\n }\n // Date Formatting Utils\n // -----------------------------------------------------------------------------------------------------------------\n formatDate(d, formatter) {\n let { dateEnv } = this.getCurrentData();\n return dateEnv.format(dateEnv.createMarker(d), createFormatter(formatter));\n }\n // `settings` is for formatter AND isEndExclusive\n formatRange(d0, d1, settings) {\n let { dateEnv } = this.getCurrentData();\n return dateEnv.formatRange(dateEnv.createMarker(d0), dateEnv.createMarker(d1), createFormatter(settings), settings);\n }\n formatIso(d, omitTime) {\n let { dateEnv } = this.getCurrentData();\n return dateEnv.formatIso(dateEnv.createMarker(d), { omitTime });\n }\n // Date Selection / Event Selection / DayClick\n // -----------------------------------------------------------------------------------------------------------------\n select(dateOrObj, endDate) {\n let selectionInput;\n if (endDate == null) {\n if (dateOrObj.start != null) {\n selectionInput = dateOrObj;\n }\n else {\n selectionInput = {\n start: dateOrObj,\n end: null,\n };\n }\n }\n else {\n selectionInput = {\n start: dateOrObj,\n end: endDate,\n };\n }\n let state = this.getCurrentData();\n let selection = parseDateSpan(selectionInput, state.dateEnv, createDuration({ days: 1 }));\n if (selection) { // throw parse error otherwise?\n this.dispatch({ type: 'SELECT_DATES', selection });\n triggerDateSelect(selection, null, state);\n }\n }\n unselect(pev) {\n let state = this.getCurrentData();\n if (state.dateSelection) {\n this.dispatch({ type: 'UNSELECT_DATES' });\n triggerDateUnselect(pev, state);\n }\n }\n // Public Events API\n // -----------------------------------------------------------------------------------------------------------------\n addEvent(eventInput, sourceInput) {\n if (eventInput instanceof EventImpl) {\n let def = eventInput._def;\n let instance = eventInput._instance;\n let currentData = this.getCurrentData();\n // not already present? don't want to add an old snapshot\n if (!currentData.eventStore.defs[def.defId]) {\n this.dispatch({\n type: 'ADD_EVENTS',\n eventStore: eventTupleToStore({ def, instance }), // TODO: better util for two args?\n });\n this.triggerEventAdd(eventInput);\n }\n return eventInput;\n }\n let state = this.getCurrentData();\n let eventSource;\n if (sourceInput instanceof EventSourceImpl) {\n eventSource = sourceInput.internalEventSource;\n }\n else if (typeof sourceInput === 'boolean') {\n if (sourceInput) { // true. part of the first event source\n [eventSource] = hashValuesToArray(state.eventSources);\n }\n }\n else if (sourceInput != null) { // an ID. accepts a number too\n let sourceApi = this.getEventSourceById(sourceInput); // TODO: use an internal function\n if (!sourceApi) {\n console.warn(`Could not find an event source with ID \"${sourceInput}\"`); // TODO: test\n return null;\n }\n eventSource = sourceApi.internalEventSource;\n }\n let tuple = parseEvent(eventInput, eventSource, state, false);\n if (tuple) {\n let newEventApi = new EventImpl(state, tuple.def, tuple.def.recurringDef ? null : tuple.instance);\n this.dispatch({\n type: 'ADD_EVENTS',\n eventStore: eventTupleToStore(tuple),\n });\n this.triggerEventAdd(newEventApi);\n return newEventApi;\n }\n return null;\n }\n triggerEventAdd(eventApi) {\n let { emitter } = this.getCurrentData();\n emitter.trigger('eventAdd', {\n event: eventApi,\n relatedEvents: [],\n revert: () => {\n this.dispatch({\n type: 'REMOVE_EVENTS',\n eventStore: eventApiToStore(eventApi),\n });\n },\n });\n }\n // TODO: optimize\n getEventById(id) {\n let state = this.getCurrentData();\n let { defs, instances } = state.eventStore;\n id = String(id);\n for (let defId in defs) {\n let def = defs[defId];\n if (def.publicId === id) {\n if (def.recurringDef) {\n return new EventImpl(state, def, null);\n }\n for (let instanceId in instances) {\n let instance = instances[instanceId];\n if (instance.defId === def.defId) {\n return new EventImpl(state, def, instance);\n }\n }\n }\n }\n return null;\n }\n getEvents() {\n let currentData = this.getCurrentData();\n return buildEventApis(currentData.eventStore, currentData);\n }\n removeAllEvents() {\n this.dispatch({ type: 'REMOVE_ALL_EVENTS' });\n }\n // Public Event Sources API\n // -----------------------------------------------------------------------------------------------------------------\n getEventSources() {\n let state = this.getCurrentData();\n let sourceHash = state.eventSources;\n let sourceApis = [];\n for (let internalId in sourceHash) {\n sourceApis.push(new EventSourceImpl(state, sourceHash[internalId]));\n }\n return sourceApis;\n }\n getEventSourceById(id) {\n let state = this.getCurrentData();\n let sourceHash = state.eventSources;\n id = String(id);\n for (let sourceId in sourceHash) {\n if (sourceHash[sourceId].publicId === id) {\n return new EventSourceImpl(state, sourceHash[sourceId]);\n }\n }\n return null;\n }\n addEventSource(sourceInput) {\n let state = this.getCurrentData();\n if (sourceInput instanceof EventSourceImpl) {\n // not already present? don't want to add an old snapshot\n if (!state.eventSources[sourceInput.internalEventSource.sourceId]) {\n this.dispatch({\n type: 'ADD_EVENT_SOURCES',\n sources: [sourceInput.internalEventSource],\n });\n }\n return sourceInput;\n }\n let eventSource = parseEventSource(sourceInput, state);\n if (eventSource) { // TODO: error otherwise?\n this.dispatch({ type: 'ADD_EVENT_SOURCES', sources: [eventSource] });\n return new EventSourceImpl(state, eventSource);\n }\n return null;\n }\n removeAllEventSources() {\n this.dispatch({ type: 'REMOVE_ALL_EVENT_SOURCES' });\n }\n refetchEvents() {\n this.dispatch({ type: 'FETCH_EVENT_SOURCES', isRefetch: true });\n }\n // Scroll\n // -----------------------------------------------------------------------------------------------------------------\n scrollToTime(timeInput) {\n let time = createDuration(timeInput);\n if (time) {\n this.trigger('_scrollRequest', { time });\n }\n }\n}\n\nclass Store {\n constructor() {\n this.handlers = [];\n }\n set(value) {\n this.currentValue = value;\n for (let handler of this.handlers) {\n handler(value);\n }\n }\n subscribe(handler) {\n this.handlers.push(handler);\n if (this.currentValue !== undefined) {\n handler(this.currentValue);\n }\n }\n}\n\n/*\nSubscribers will get a LIST of CustomRenderings\n*/\nclass CustomRenderingStore extends Store {\n constructor() {\n super(...arguments);\n this.map = new Map();\n }\n // for consistent order\n handle(customRendering) {\n const { map } = this;\n let updated = false;\n if (customRendering.isActive) {\n map.set(customRendering.id, customRendering);\n updated = true;\n }\n else if (map.has(customRendering.id)) {\n map.delete(customRendering.id);\n updated = true;\n }\n if (updated) {\n this.set(map);\n }\n }\n}\n\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvQGZ1bGxjYWxlbmRhci9jb3JlL2ludGVybmFsLWNvbW1vbi5lc20uanMuanMiLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBaUM7QUFDMkM7QUFDL0I7O0FBRTdDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0IsdUJBQXVCO0FBQzNDO0FBQ0Esd0JBQXdCLG9CQUFvQjtBQUM1QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9CQUFvQixvQkFBb0I7QUFDeEMsOENBQThDO0FBQzlDLHdCQUF3Qix1QkFBdUI7QUFDL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCLElBQUk7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0Esc0RBQXNEO0FBQ3RELEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJCQUEyQixrQkFBa0I7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQ0FBcUM7QUFDckM7QUFDQSxTQUFTO0FBQ1Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLG1CQUFtQjtBQUNuQztBQUNBO0FBQ0E7QUFDQSxrQkFBa0IsdUNBQXVDO0FBQ3pELGtCQUFrQix3QkFBd0I7QUFDMUM7QUFDQTtBQUNBLHlCQUF5QixhQUFhO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLHVCQUF1QjtBQUN2QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5Q0FBeUM7QUFDekM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUVBQXVFO0FBQ3ZFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsOENBQThDO0FBQzlDO0FBQ0E7QUFDQTtBQUNBLDZCQUE2QixpQ0FBaUM7QUFDOUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9CQUFvQiwyQkFBMkI7QUFDL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0EsYUFBYTtBQUNiOztBQUVBLFFBQVEsaUJBQWlCO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw4Q0FBOEMsUUFBUTtBQUN0RDtBQUNBLHNEQUFzRDtBQUN0RDtBQUNBO0FBQ0E7QUFDQSxzQ0FBc0M7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQ0FBc0MsUUFBUTtBQUM5QztBQUNBO0FBQ0EsbUNBQW1DO0FBQ25DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyREFBMkQ7QUFDM0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIsY0FBYztBQUMzQztBQUNBLGlDQUFpQztBQUNqQztBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQ0FBcUM7QUFDckM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FB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Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsOENBQThDO0FBQzlDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtDQUFrQyxRQUFRO0FBQzFDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsZ0RBQWdEO0FBQ3hFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Es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QTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx3Q0FBd0M7QUFDeEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJCQUEyQjtBQUMzQjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5RkFBeUY7QUFDekY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLGdCQUFnQjtBQUM5QjtBQUNBO0FBQ0Esb0JBQW9CLFNBQVM7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwQkFBMEI7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLGdCQUFnQjtBQUM5QjtBQUNBO0FBQ0Esb0JBQW9CLFNBQVM7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwQkFBMEI7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLFNBQVM7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdFQUF3RTtBQUN4RSw4Q0FBOEM7QUFDOUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlEQUF5RDtBQUN6RDtBQUNB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cmNlcyI6WyJ3ZWJwYWNrOi8vVnVleHkvLi9ub2RlX21vZHVsZXMvQGZ1bGxjYWxlbmRhci9jb3JlL2ludGVybmFsLWNvbW1vbi5lc20uanM/MTYzNiJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBwcmVhY3QgZnJvbSAncHJlYWN0JztcbmltcG9ydCB7IENvbXBvbmVudCwgY3JlYXRlRWxlbWVudCwgaXNWYWxpZEVsZW1lbnQsIEZyYWdtZW50IH0gZnJvbSAncHJlYWN0JztcbmltcG9ydCB7IGNyZWF0ZVBvcnRhbCB9IGZyb20gJ3ByZWFjdC9jb21wYXQnO1xuXG5mdW5jdGlvbiByZW1vdmVFbGVtZW50KGVsKSB7XG4gICAgaWYgKGVsLnBhcmVudE5vZGUpIHtcbiAgICAgICAgZWwucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChlbCk7XG4gICAgfVxufVxuLy8gUXVlcnlpbmdcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbmZ1bmN0aW9uIGVsZW1lbnRDbG9zZXN0KGVsLCBzZWxlY3Rvcikge1xuICAgIGlmIChlbC5jbG9zZXN0KSB7XG4gICAgICAgIHJldHVybiBlbC5jbG9zZXN0KHNlbGVjdG9yKTtcbiAgICAgICAgLy8gcmVhbGx5IGJhZCBmYWxsYmFjayBmb3IgSUVcbiAgICAgICAgLy8gZnJvbSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvRWxlbWVudC9jbG9zZXN0XG4gICAgfVxuICAgIGlmICghZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNvbnRhaW5zKGVsKSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgZG8ge1xuICAgICAgICBpZiAoZWxlbWVudE1hdGNoZXMoZWwsIHNlbGVjdG9yKSkge1xuICAgICAgICAgICAgcmV0dXJuIGVsO1xuICAgICAgICB9XG4gICAgICAgIGVsID0gKGVsLnBhcmVudEVsZW1lbnQgfHwgZWwucGFyZW50Tm9kZSk7XG4gICAgfSB3aGlsZSAoZWwgIT09IG51bGwgJiYgZWwubm9kZVR5cGUgPT09IDEpO1xuICAgIHJldHVybiBudWxsO1xufVxuZnVuY3Rpb24gZWxlbWVudE1hdGNoZXMoZWwsIHNlbGVjdG9yKSB7XG4gICAgbGV0IG1ldGhvZCA9IGVsLm1hdGNoZXMgfHwgZWwubWF0Y2hlc1NlbGVjdG9yIHx8IGVsLm1zTWF0Y2hlc1NlbGVjdG9yO1xuICAgIHJldHVybiBtZXRob2QuY2FsbChlbCwgc2VsZWN0b3IpO1xufVxuLy8gYWNjZXB0cyBtdWx0aXBsZSBzdWJqZWN0IGVsc1xuLy8gcmV0dXJucyBhIHJlYWwgYXJyYXkuIGdvb2QgZm9yIG1ldGhvZHMgbGlrZSBmb3JFYWNoXG4vLyBUT0RPOiBhY2NlcHQgdGhlIGRvY3VtZW50XG5mdW5jdGlvbiBmaW5kRWxlbWVudHMoY29udGFpbmVyLCBzZWxlY3Rvcikge1xuICAgIGxldCBjb250YWluZXJzID0gY29udGFpbmVyIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQgPyBbY29udGFpbmVyXSA6IGNvbnRhaW5lcjtcbiAgICBsZXQgYWxsTWF0Y2hlcyA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY29udGFpbmVycy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICBsZXQgbWF0Y2hlcyA9IGNvbnRhaW5lcnNbaV0ucXVlcnlTZWxlY3RvckFsbChzZWxlY3Rvcik7XG4gICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgbWF0Y2hlcy5sZW5ndGg7IGogKz0gMSkge1xuICAgICAgICAgICAgYWxsTWF0Y2hlcy5wdXNoKG1hdGNoZXNbal0pO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBhbGxNYXRjaGVzO1xufVxuLy8gYWNjZXB0cyBtdWx0aXBsZSBzdWJqZWN0IGVsc1xuLy8gb25seSBxdWVyaWVzIGRpcmVjdCBjaGlsZCBlbGVtZW50cyAvLyBUT0RPOiByZW5hbWUgdG8gZmluZERpcmVjdENoaWxkcmVuIVxuZnVuY3Rpb24gZmluZERpcmVjdENoaWxkcmVuKHBhcmVudCwgc2VsZWN0b3IpIHtcbiAgICBsZXQgcGFyZW50cyA9IHBhcmVudCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50ID8gW3BhcmVudF0gOiBwYXJlbnQ7XG4gICAgbGV0IGFsbE1hdGNoZXMgPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBhcmVudHMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgbGV0IGNoaWxkTm9kZXMgPSBwYXJlbnRzW2ldLmNoaWxkcmVuOyAvLyBvbmx5IGV2ZXIgZWxlbWVudHNcbiAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBjaGlsZE5vZGVzLmxlbmd0aDsgaiArPSAxKSB7XG4gICAgICAgICAgICBsZXQgY2hpbGROb2RlID0gY2hpbGROb2Rlc1tqXTtcbiAgICAgICAgICAgIGlmICghc2VsZWN0b3IgfHwgZWxlbWVudE1hdGNoZXMoY2hpbGROb2RlLCBzZWxlY3RvcikpIHtcbiAgICAgICAgICAgICAgICBhbGxNYXRjaGVzLnB1c2goY2hpbGROb2RlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gYWxsTWF0Y2hlcztcbn1cbi8vIFN0eWxlXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5jb25zdCBQSVhFTF9QUk9QX1JFID0gLyh0b3B8bGVmdHxyaWdodHxib3R0b218d2lkdGh8aGVpZ2h0KSQvaTtcbmZ1bmN0aW9uIGFwcGx5U3R5bGUoZWwsIHByb3BzKSB7XG4gICAgZm9yIChsZXQgcHJvcE5hbWUgaW4gcHJvcHMpIHtcbiAgICAgICAgYXBwbHlTdHlsZVByb3AoZWwsIHByb3BOYW1lLCBwcm9wc1twcm9wTmFtZV0pO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGFwcGx5U3R5bGVQcm9wKGVsLCBuYW1lLCB2YWwpIHtcbiAgICBpZiAodmFsID09IG51bGwpIHtcbiAgICAgICAgZWwuc3R5bGVbbmFtZV0gPSAnJztcbiAgICB9XG4gICAgZWxzZSBpZiAodHlwZW9mIHZhbCA9PT0gJ251bWJlcicgJiYgUElYRUxfUFJPUF9SRS50ZXN0KG5hbWUpKSB7XG4gICAgICAgIGVsLnN0eWxlW25hbWVdID0gYCR7dmFsfXB4YDtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGVsLnN0eWxlW25hbWVdID0gdmFsO1xuICAgIH1cbn1cbi8vIEV2ZW50IEhhbmRsaW5nXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBpZiBpbnRlcmNlcHRpbmcgYnViYmxlZCBldmVudHMgYXQgdGhlIGRvY3VtZW50L3dpbmRvdy9ib2R5IGxldmVsLFxuLy8gYW5kIHdhbnQgdG8gc2VlIG9yaWdpbmF0aW5nIGVsZW1lbnQgKHRoZSAndGFyZ2V0JyksIHVzZSB0aGlzIHV0aWwgaW5zdGVhZFxuLy8gb2YgYGV2LnRhcmdldGAgYmVjYXVzZSBpdCBnb2VzIHdpdGhpbiB3ZWItY29tcG9uZW50IGJvdW5kYXJpZXMuXG5mdW5jdGlvbiBnZXRFdmVudFRhcmdldFZpYVJvb3QoZXYpIHtcbiAgICB2YXIgX2EsIF9iO1xuICAgIHJldHVybiAoX2IgPSAoX2EgPSBldi5jb21wb3NlZFBhdGgpID09PSBudWxsIHx8IF9hID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYS5jYWxsKGV2KVswXSkgIT09IG51bGwgJiYgX2IgIT09IHZvaWQgMCA/IF9iIDogZXYudGFyZ2V0O1xufVxuLy8gU2hhZG93IERPTSBjb25zdWRlcmF0aW9uc1xuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuZnVuY3Rpb24gZ2V0RWxSb290KGVsKSB7XG4gICAgcmV0dXJuIGVsLmdldFJvb3ROb2RlID8gZWwuZ2V0Um9vdE5vZGUoKSA6IGRvY3VtZW50O1xufVxuLy8gVW5pcXVlIElEIGZvciBET00gYXR0cmlidXRlXG5sZXQgZ3VpZCQxID0gMDtcbmZ1bmN0aW9uIGdldFVuaXF1ZURvbUlkKCkge1xuICAgIGd1aWQkMSArPSAxO1xuICAgIHJldHVybiAnZmMtZG9tLScgKyBndWlkJDE7XG59XG5cbi8vIFN0b3BzIGEgbW91c2UvdG91Y2ggZXZlbnQgZnJvbSBkb2luZyBpdCdzIG5hdGl2ZSBicm93c2VyIGFjdGlvblxuZnVuY3Rpb24gcHJldmVudERlZmF1bHQoZXYpIHtcbiAgICBldi5wcmV2ZW50RGVmYXVsdCgpO1xufVxuLy8gRXZlbnQgRGVsZWdhdGlvblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuZnVuY3Rpb24gYnVpbGREZWxlZ2F0aW9uSGFuZGxlcihzZWxlY3RvciwgaGFuZGxlcikge1xuICAgIHJldHVybiAoZXYpID0+IHtcbiAgICAgICAgbGV0IG1hdGNoZWRDaGlsZCA9IGVsZW1lbnRDbG9zZXN0KGV2LnRhcmdldCwgc2VsZWN0b3IpO1xuICAgICAgICBpZiAobWF0Y2hlZENoaWxkKSB7XG4gICAgICAgICAgICBoYW5kbGVyLmNhbGwobWF0Y2hlZENoaWxkLCBldiwgbWF0Y2hlZENoaWxkKTtcbiAgICAgICAgfVxuICAgIH07XG59XG5mdW5jdGlvbiBsaXN0ZW5CeVNlbGVjdG9yKGNvbnRhaW5lciwgZXZlbnRUeXBlLCBzZWxlY3RvciwgaGFuZGxlcikge1xuICAgIGxldCBhdHRhY2hlZEhhbmRsZXIgPSBidWlsZERlbGVnYXRpb25IYW5kbGVyKHNlbGVjdG9yLCBoYW5kbGVyKTtcbiAgICBjb250YWluZXIuYWRkRXZlbnRMaXN0ZW5lcihldmVudFR5cGUsIGF0dGFjaGVkSGFuZGxlcik7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgY29udGFpbmVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoZXZlbnRUeXBlLCBhdHRhY2hlZEhhbmRsZXIpO1xuICAgIH07XG59XG5mdW5jdGlvbiBsaXN0ZW5Ub0hvdmVyQnlTZWxlY3Rvcihjb250YWluZXIsIHNlbGVjdG9yLCBvbk1vdXNlRW50ZXIsIG9uTW91c2VMZWF2ZSkge1xuICAgIGxldCBjdXJyZW50TWF0Y2hlZENoaWxkO1xuICAgIHJldHVybiBsaXN0ZW5CeVNlbGVjdG9yKGNvbnRhaW5lciwgJ21vdXNlb3ZlcicsIHNlbGVjdG9yLCAobW91c2VPdmVyRXYsIG1hdGNoZWRDaGlsZCkgPT4ge1xuICAgICAgICBpZiAobWF0Y2hlZENoaWxkICE9PSBjdXJyZW50TWF0Y2hlZENoaWxkKSB7XG4gICAgICAgICAgICBjdXJyZW50TWF0Y2hlZENoaWxkID0gbWF0Y2hlZENoaWxkO1xuICAgICAgICAgICAgb25Nb3VzZUVudGVyKG1vdXNlT3ZlckV2LCBtYXRjaGVkQ2hpbGQpO1xuICAgICAgICAgICAgbGV0IHJlYWxPbk1vdXNlTGVhdmUgPSAobW91c2VMZWF2ZUV2KSA9PiB7XG4gICAgICAgICAgICAgICAgY3VycmVudE1hdGNoZWRDaGlsZCA9IG51bGw7XG4gICAgICAgICAgICAgICAgb25Nb3VzZUxlYXZlKG1vdXNlTGVhdmVFdiwgbWF0Y2hlZENoaWxkKTtcbiAgICAgICAgICAgICAgICBtYXRjaGVkQ2hpbGQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2VsZWF2ZScsIHJlYWxPbk1vdXNlTGVhdmUpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIC8vIGxpc3RlbiB0byB0aGUgbmV4dCBtb3VzZWxlYXZlLCBhbmQgdGhlbiB1bmF0dGFjaFxuICAgICAgICAgICAgbWF0Y2hlZENoaWxkLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbGVhdmUnLCByZWFsT25Nb3VzZUxlYXZlKTtcbiAgICAgICAgfVxuICAgIH0pO1xufVxuLy8gQW5pbWF0aW9uXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5jb25zdCB0cmFuc2l0aW9uRXZlbnROYW1lcyA9IFtcbiAgICAnd2Via2l0VHJhbnNpdGlvbkVuZCcsXG4gICAgJ290cmFuc2l0aW9uZW5kJyxcbiAgICAnb1RyYW5zaXRpb25FbmQnLFxuICAgICdtc1RyYW5zaXRpb25FbmQnLFxuICAgICd0cmFuc2l0aW9uZW5kJyxcbl07XG4vLyB0cmlnZ2VyZWQgb25seSB3aGVuIHRoZSBuZXh0IHNpbmdsZSBzdWJzZXF1ZW50IHRyYW5zaXRpb24gZmluaXNoZXNcbmZ1bmN0aW9uIHdoZW5UcmFuc2l0aW9uRG9uZShlbCwgY2FsbGJhY2spIHtcbiAgICBsZXQgcmVhbENhbGxiYWNrID0gKGV2KSA9PiB7XG4gICAgICAgIGNhbGxiYWNrKGV2KTtcbiAgICAgICAgdHJhbnNpdGlvbkV2ZW50TmFtZXMuZm9yRWFjaCgoZXZlbnROYW1lKSA9PiB7XG4gICAgICAgICAgICBlbC5yZW1vdmVFdmVudExpc3RlbmVyKGV2ZW50TmFtZSwgcmVhbENhbGxiYWNrKTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICB0cmFuc2l0aW9uRXZlbnROYW1lcy5mb3JFYWNoKChldmVudE5hbWUpID0+IHtcbiAgICAgICAgZWwuYWRkRXZlbnRMaXN0ZW5lcihldmVudE5hbWUsIHJlYWxDYWxsYmFjayk7IC8vIGNyb3NzLWJyb3dzZXIgd2F5IHRvIGRldGVybWluZSB3aGVuIHRoZSB0cmFuc2l0aW9uIGZpbmlzaGVzXG4gICAgfSk7XG59XG4vLyBBUklBIHdvcmthcm91bmRzXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5mdW5jdGlvbiBjcmVhdGVBcmlhQ2xpY2tBdHRycyhoYW5kbGVyKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oeyBvbkNsaWNrOiBoYW5kbGVyIH0sIGNyZWF0ZUFyaWFLZXlib2FyZEF0dHJzKGhhbmRsZXIpKTtcbn1cbmZ1bmN0aW9uIGNyZWF0ZUFyaWFLZXlib2FyZEF0dHJzKGhhbmRsZXIpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICB0YWJJbmRleDogMCxcbiAgICAgICAgb25LZXlEb3duKGV2KSB7XG4gICAgICAgICAgICBpZiAoZXYua2V5ID09PSAnRW50ZXInIHx8IGV2LmtleSA9PT0gJyAnKSB7XG4gICAgICAgICAgICAgICAgaGFuZGxlcihldik7XG4gICAgICAgICAgICAgICAgZXYucHJldmVudERlZmF1bHQoKTsgLy8gaWYgc3BhY2UsIGRvbid0IHNjcm9sbCBkb3duIHBhZ2VcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICB9O1xufVxuXG5sZXQgZ3VpZE51bWJlciA9IDA7XG5mdW5jdGlvbiBndWlkKCkge1xuICAgIGd1aWROdW1iZXIgKz0gMTtcbiAgICByZXR1cm4gU3RyaW5nKGd1aWROdW1iZXIpO1xufVxuLyogRnVsbENhbGVuZGFyLXNwZWNpZmljIERPTSBVdGlsaXRpZXNcbi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuLy8gTWFrZSB0aGUgbW91c2UgY3Vyc29yIGV4cHJlc3MgdGhhdCBhbiBldmVudCBpcyBub3QgYWxsb3dlZCBpbiB0aGUgY3VycmVudCBhcmVhXG5mdW5jdGlvbiBkaXNhYmxlQ3Vyc29yKCkge1xuICAgIGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LmFkZCgnZmMtbm90LWFsbG93ZWQnKTtcbn1cbi8vIFJldHVybnMgdGhlIG1vdXNlIGN1cnNvciB0byBpdHMgb3JpZ2luYWwgbG9va1xuZnVuY3Rpb24gZW5hYmxlQ3Vyc29yKCkge1xuICAgIGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LnJlbW92ZSgnZmMtbm90LWFsbG93ZWQnKTtcbn1cbi8qIFNlbGVjdGlvblxuLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5mdW5jdGlvbiBwcmV2ZW50U2VsZWN0aW9uKGVsKSB7XG4gICAgZWwuY2xhc3NMaXN0LmFkZCgnZmMtdW5zZWxlY3RhYmxlJyk7XG4gICAgZWwuYWRkRXZlbnRMaXN0ZW5lcignc2VsZWN0c3RhcnQnLCBwcmV2ZW50RGVmYXVsdCk7XG59XG5mdW5jdGlvbiBhbGxvd1NlbGVjdGlvbihlbCkge1xuICAgIGVsLmNsYXNzTGlzdC5yZW1vdmUoJ2ZjLXVuc2VsZWN0YWJsZScpO1xuICAgIGVsLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3NlbGVjdHN0YXJ0JywgcHJldmVudERlZmF1bHQpO1xufVxuLyogQ29udGV4dCBNZW51XG4tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cbmZ1bmN0aW9uIHByZXZlbnRDb250ZXh0TWVudShlbCkge1xuICAgIGVsLmFkZEV2ZW50TGlzdGVuZXIoJ2NvbnRleHRtZW51JywgcHJldmVudERlZmF1bHQpO1xufVxuZnVuY3Rpb24gYWxsb3dDb250ZXh0TWVudShlbCkge1xuICAgIGVsLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NvbnRleHRtZW51JywgcHJldmVudERlZmF1bHQpO1xufVxuZnVuY3Rpb24gcGFyc2VGaWVsZFNwZWNzKGlucHV0KSB7XG4gICAgbGV0IHNwZWNzID0gW107XG4gICAgbGV0IHRva2VucyA9IFtdO1xuICAgIGxldCBpO1xuICAgIGxldCB0b2tlbjtcbiAgICBpZiAodHlwZW9mIGlucHV0ID09PSAnc3RyaW5nJykge1xuICAgICAgICB0b2tlbnMgPSBpbnB1dC5zcGxpdCgvXFxzKixcXHMqLyk7XG4gICAgfVxuICAgIGVsc2UgaWYgKHR5cGVvZiBpbnB1dCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB0b2tlbnMgPSBbaW5wdXRdO1xuICAgIH1cbiAgICBlbHNlIGlmIChBcnJheS5pc0FycmF5KGlucHV0KSkge1xuICAgICAgICB0b2tlbnMgPSBpbnB1dDtcbiAgICB9XG4gICAgZm9yIChpID0gMDsgaSA8IHRva2Vucy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICB0b2tlbiA9IHRva2Vuc1tpXTtcbiAgICAgICAgaWYgKHR5cGVvZiB0b2tlbiA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHNwZWNzLnB1c2godG9rZW4uY2hhckF0KDApID09PSAnLScgP1xuICAgICAgICAgICAgICAgIHsgZmllbGQ6IHRva2VuLnN1YnN0cmluZygxKSwgb3JkZXI6IC0xIH0gOlxuICAgICAgICAgICAgICAgIHsgZmllbGQ6IHRva2VuLCBvcmRlcjogMSB9KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0eXBlb2YgdG9rZW4gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHNwZWNzLnB1c2goeyBmdW5jOiB0b2tlbiB9KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gc3BlY3M7XG59XG5mdW5jdGlvbiBjb21wYXJlQnlGaWVsZFNwZWNzKG9iajAsIG9iajEsIGZpZWxkU3BlY3MpIHtcbiAgICBsZXQgaTtcbiAgICBsZXQgY21wO1xuICAgIGZvciAoaSA9IDA7IGkgPCBmaWVsZFNwZWNzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgIGNtcCA9IGNvbXBhcmVCeUZpZWxkU3BlYyhvYmowLCBvYmoxLCBmaWVsZFNwZWNzW2ldKTtcbiAgICAgICAgaWYgKGNtcCkge1xuICAgICAgICAgICAgcmV0dXJuIGNtcDtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gMDtcbn1cbmZ1bmN0aW9uIGNvbXBhcmVCeUZpZWxkU3BlYyhvYmowLCBvYmoxLCBmaWVsZFNwZWMpIHtcbiAgICBpZiAoZmllbGRTcGVjLmZ1bmMpIHtcbiAgICAgICAgcmV0dXJuIGZpZWxkU3BlYy5mdW5jKG9iajAsIG9iajEpO1xuICAgIH1cbiAgICByZXR1cm4gZmxleGlibGVDb21wYXJlKG9iajBbZmllbGRTcGVjLmZpZWxkXSwgb2JqMVtmaWVsZFNwZWMuZmllbGRdKVxuICAgICAgICAqIChmaWVsZFNwZWMub3JkZXIgfHwgMSk7XG59XG5mdW5jdGlvbiBmbGV4aWJsZUNvbXBhcmUoYSwgYikge1xuICAgIGlmICghYSAmJiAhYikge1xuICAgICAgICByZXR1cm4gMDtcbiAgICB9XG4gICAgaWYgKGIgPT0gbnVsbCkge1xuICAgICAgICByZXR1cm4gLTE7XG4gICAgfVxuICAgIGlmIChhID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIDE7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgYSA9PT0gJ3N0cmluZycgfHwgdHlwZW9mIGIgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJldHVybiBTdHJpbmcoYSkubG9jYWxlQ29tcGFyZShTdHJpbmcoYikpO1xuICAgIH1cbiAgICByZXR1cm4gYSAtIGI7XG59XG4vKiBTdHJpbmcgVXRpbGl0aWVzXG4tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cbmZ1bmN0aW9uIHBhZFN0YXJ0KHZhbCwgbGVuKSB7XG4gICAgbGV0IHMgPSBTdHJpbmcodmFsKTtcbiAgICByZXR1cm4gJzAwMCcuc3Vic3RyKDAsIGxlbiAtIHMubGVuZ3RoKSArIHM7XG59XG5mdW5jdGlvbiBmb3JtYXRXaXRoT3JkaW5hbHMoZm9ybWF0dGVyLCBhcmdzLCBmYWxsYmFja1RleHQpIHtcbiAgICBpZiAodHlwZW9mIGZvcm1hdHRlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICByZXR1cm4gZm9ybWF0dGVyKC4uLmFyZ3MpO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIGZvcm1hdHRlciA9PT0gJ3N0cmluZycpIHsgLy8gbm9uLWJsYW5rIHN0cmluZ1xuICAgICAgICByZXR1cm4gYXJncy5yZWR1Y2UoKHN0ciwgYXJnLCBpbmRleCkgPT4gKHN0ci5yZXBsYWNlKCckJyArIGluZGV4LCBhcmcgfHwgJycpKSwgZm9ybWF0dGVyKTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbGxiYWNrVGV4dDtcbn1cbi8qIE51bWJlciBVdGlsaXRpZXNcbi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuZnVuY3Rpb24gY29tcGFyZU51bWJlcnMoYSwgYikge1xuICAgIHJldHVybiBhIC0gYjtcbn1cbmZ1bmN0aW9uIGlzSW50KG4pIHtcbiAgICByZXR1cm4gbiAlIDEgPT09IDA7XG59XG4vKiBGQy1zcGVjaWZpYyBET00gZGltZW5zaW9uIHN0dWZmXG4tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cbmZ1bmN0aW9uIGNvbXB1dGVTbWFsbGVzdENlbGxXaWR0aChjZWxsRWwpIHtcbiAgICBsZXQgYWxsV2lkdGhFbCA9IGNlbGxFbC5xdWVyeVNlbGVjdG9yKCcuZmMtc2Nyb2xsZ3JpZC1zaHJpbmstZnJhbWUnKTtcbiAgICBsZXQgY29udGVudFdpZHRoRWwgPSBjZWxsRWwucXVlcnlTZWxlY3RvcignLmZjLXNjcm9sbGdyaWQtc2hyaW5rLWN1c2hpb24nKTtcbiAgICBpZiAoIWFsbFdpZHRoRWwpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCduZWVkcyBmYy1zY3JvbGxncmlkLXNocmluay1mcmFtZSBjbGFzc05hbWUnKTsgLy8gVE9ETzogdXNlIGNvbnN0XG4gICAgfVxuICAgIGlmICghY29udGVudFdpZHRoRWwpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCduZWVkcyBmYy1zY3JvbGxncmlkLXNocmluay1jdXNoaW9uIGNsYXNzTmFtZScpO1xuICAgIH1cbiAgICByZXR1cm4gY2VsbEVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLndpZHRoIC0gYWxsV2lkdGhFbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS53aWR0aCArIC8vIHRoZSBjZWxsIHBhZGRpbmcrYm9yZGVyXG4gICAgICAgIGNvbnRlbnRXaWR0aEVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLndpZHRoO1xufVxuXG5jb25zdCBJTlRFUk5BTF9VTklUUyA9IFsneWVhcnMnLCAnbW9udGhzJywgJ2RheXMnLCAnbWlsbGlzZWNvbmRzJ107XG5jb25zdCBQQVJTRV9SRSA9IC9eKC0/KSg/OihcXGQrKVxcLik/KFxcZCspOihcXGRcXGQpKD86OihcXGRcXGQpKD86XFwuKFxcZFxcZFxcZCkpPyk/Lztcbi8vIFBhcnNpbmcgYW5kIENyZWF0aW9uXG5mdW5jdGlvbiBjcmVhdGVEdXJhdGlvbihpbnB1dCwgdW5pdCkge1xuICAgIGlmICh0eXBlb2YgaW5wdXQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJldHVybiBwYXJzZVN0cmluZyhpbnB1dCk7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgaW5wdXQgPT09ICdvYmplY3QnICYmIGlucHV0KSB7IC8vIG5vbi1udWxsIG9iamVjdFxuICAgICAgICByZXR1cm4gcGFyc2VPYmplY3QoaW5wdXQpO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIGlucHV0ID09PSAnbnVtYmVyJykge1xuICAgICAgICByZXR1cm4gcGFyc2VPYmplY3QoeyBbdW5pdCB8fCAnbWlsbGlzZWNvbmRzJ106IGlucHV0IH0pO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbn1cbmZ1bmN0aW9uIHBhcnNlU3RyaW5nKHMpIHtcbiAgICBsZXQgbSA9IFBBUlNFX1JFLmV4ZWMocyk7XG4gICAgaWYgKG0pIHtcbiAgICAgICAgbGV0IHNpZ24gPSBtWzFdID8gLTEgOiAxO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgeWVhcnM6IDAsXG4gICAgICAgICAgICBtb250aHM6IDAsXG4gICAgICAgICAgICBkYXlzOiBzaWduICogKG1bMl0gPyBwYXJzZUludChtWzJdLCAxMCkgOiAwKSxcbiAgICAgICAgICAgIG1pbGxpc2Vjb25kczogc2lnbiAqICgobVszXSA/IHBhcnNlSW50KG1bM10sIDEwKSA6IDApICogNjAgKiA2MCAqIDEwMDAgKyAvLyBob3Vyc1xuICAgICAgICAgICAgICAgIChtWzRdID8gcGFyc2VJbnQobVs0XSwgMTApIDogMCkgKiA2MCAqIDEwMDAgKyAvLyBtaW51dGVzXG4gICAgICAgICAgICAgICAgKG1bNV0gPyBwYXJzZUludChtWzVdLCAxMCkgOiAwKSAqIDEwMDAgKyAvLyBzZWNvbmRzXG4gICAgICAgICAgICAgICAgKG1bNl0gPyBwYXJzZUludChtWzZdLCAxMCkgOiAwKSAvLyBtc1xuICAgICAgICAgICAgKSxcbiAgICAgICAgfTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG59XG5mdW5jdGlvbiBwYXJzZU9iamVjdChvYmopIHtcbiAgICBsZXQgZHVyYXRpb24gPSB7XG4gICAgICAgIHllYXJzOiBvYmoueWVhcnMgfHwgb2JqLnllYXIgfHwgMCxcbiAgICAgICAgbW9udGhzOiBvYmoubW9udGhzIHx8IG9iai5tb250aCB8fCAwLFxuICAgICAgICBkYXlzOiBvYmouZGF5cyB8fCBvYmouZGF5IHx8IDAsXG4gICAgICAgIG1pbGxpc2Vjb25kczogKG9iai5ob3VycyB8fCBvYmouaG91ciB8fCAwKSAqIDYwICogNjAgKiAxMDAwICsgLy8gaG91cnNcbiAgICAgICAgICAgIChvYmoubWludXRlcyB8fCBvYmoubWludXRlIHx8IDApICogNjAgKiAxMDAwICsgLy8gbWludXRlc1xuICAgICAgICAgICAgKG9iai5zZWNvbmRzIHx8IG9iai5zZWNvbmQgfHwgMCkgKiAxMDAwICsgLy8gc2Vjb25kc1xuICAgICAgICAgICAgKG9iai5taWxsaXNlY29uZHMgfHwgb2JqLm1pbGxpc2Vjb25kIHx8IG9iai5tcyB8fCAwKSwgLy8gbXNcbiAgICB9O1xuICAgIGxldCB3ZWVrcyA9IG9iai53ZWVrcyB8fCBvYmoud2VlaztcbiAgICBpZiAod2Vla3MpIHtcbiAgICAgICAgZHVyYXRpb24uZGF5cyArPSB3ZWVrcyAqIDc7XG4gICAgICAgIGR1cmF0aW9uLnNwZWNpZmllZFdlZWtzID0gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGR1cmF0aW9uO1xufVxuLy8gRXF1YWxpdHlcbmZ1bmN0aW9uIGR1cmF0aW9uc0VxdWFsKGQwLCBkMSkge1xuICAgIHJldHVybiBkMC55ZWFycyA9PT0gZDEueWVhcnMgJiZcbiAgICAgICAgZDAubW9udGhzID09PSBkMS5tb250aHMgJiZcbiAgICAgICAgZDAuZGF5cyA9PT0gZDEuZGF5cyAmJlxuICAgICAgICBkMC5taWxsaXNlY29uZHMgPT09IGQxLm1pbGxpc2Vjb25kcztcbn1cbmZ1bmN0aW9uIGFzQ2xlYW5EYXlzKGR1cikge1xuICAgIGlmICghZHVyLnllYXJzICYmICFkdXIubW9udGhzICYmICFkdXIubWlsbGlzZWNvbmRzKSB7XG4gICAgICAgIHJldHVybiBkdXIuZGF5cztcbiAgICB9XG4gICAgcmV0dXJuIDA7XG59XG4vLyBTaW1wbGUgTWF0aFxuZnVuY3Rpb24gYWRkRHVyYXRpb25zKGQwLCBkMSkge1xuICAgIHJldHVybiB7XG4gICAgICAgIHllYXJzOiBkMC55ZWFycyArIGQxLnllYXJzLFxuICAgICAgICBtb250aHM6IGQwLm1vbnRocyArIGQxLm1vbnRocyxcbiAgICAgICAgZGF5czogZDAuZGF5cyArIGQxLmRheXMsXG4gICAgICAgIG1pbGxpc2Vjb25kczogZDAubWlsbGlzZWNvbmRzICsgZDEubWlsbGlzZWNvbmRzLFxuICAgIH07XG59XG5mdW5jdGlvbiBzdWJ0cmFjdER1cmF0aW9ucyhkMSwgZDApIHtcbiAgICByZXR1cm4ge1xuICAgICAgICB5ZWFyczogZDEueWVhcnMgLSBkMC55ZWFycyxcbiAgICAgICAgbW9udGhzOiBkMS5tb250aHMgLSBkMC5tb250aHMsXG4gICAgICAgIGRheXM6IGQxLmRheXMgLSBkMC5kYXlzLFxuICAgICAgICBtaWxsaXNlY29uZHM6IGQxLm1pbGxpc2Vjb25kcyAtIGQwLm1pbGxpc2Vjb25kcyxcbiAgICB9O1xufVxuZnVuY3Rpb24gbXVsdGlwbHlEdXJhdGlvbihkLCBuKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgeWVhcnM6IGQueWVhcnMgKiBuLFxuICAgICAgICBtb250aHM6IGQubW9udGhzICogbixcbiAgICAgICAgZGF5czogZC5kYXlzICogbixcbiAgICAgICAgbWlsbGlzZWNvbmRzOiBkLm1pbGxpc2Vjb25kcyAqIG4sXG4gICAgfTtcbn1cbi8vIENvbnZlcnNpb25zXG4vLyBcIlJvdWdoXCIgYmVjYXVzZSB0aGV5IGFyZSBiYXNlZCBvbiBhdmVyYWdlLWNhc2UgR3JlZ29yaWFuIG1vbnRocy95ZWFyc1xuZnVuY3Rpb24gYXNSb3VnaFllYXJzKGR1cikge1xuICAgIHJldHVybiBhc1JvdWdoRGF5cyhkdXIpIC8gMzY1O1xufVxuZnVuY3Rpb24gYXNSb3VnaE1vbnRocyhkdXIpIHtcbiAgICByZXR1cm4gYXNSb3VnaERheXMoZHVyKSAvIDMwO1xufVxuZnVuY3Rpb24gYXNSb3VnaERheXMoZHVyKSB7XG4gICAgcmV0dXJuIGFzUm91Z2hNcyhkdXIpIC8gODY0ZTU7XG59XG5mdW5jdGlvbiBhc1JvdWdoTWludXRlcyhkdXIpIHtcbiAgICByZXR1cm4gYXNSb3VnaE1zKGR1cikgLyAoMTAwMCAqIDYwKTtcbn1cbmZ1bmN0aW9uIGFzUm91Z2hTZWNvbmRzKGR1cikge1xuICAgIHJldHVybiBhc1JvdWdoTXMoZHVyKSAvIDEwMDA7XG59XG5mdW5jdGlvbiBhc1JvdWdoTXMoZHVyKSB7XG4gICAgcmV0dXJuIGR1ci55ZWFycyAqICgzNjUgKiA4NjRlNSkgK1xuICAgICAgICBkdXIubW9udGhzICogKDMwICogODY0ZTUpICtcbiAgICAgICAgZHVyLmRheXMgKiA4NjRlNSArXG4gICAgICAgIGR1ci5taWxsaXNlY29uZHM7XG59XG4vLyBBZHZhbmNlZCBNYXRoXG5mdW5jdGlvbiB3aG9sZURpdmlkZUR1cmF0aW9ucyhudW1lcmF0b3IsIGRlbm9taW5hdG9yKSB7XG4gICAgbGV0IHJlcyA9IG51bGw7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBJTlRFUk5BTF9VTklUUy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICBsZXQgdW5pdCA9IElOVEVSTkFMX1VOSVRTW2ldO1xuICAgICAgICBpZiAoZGVub21pbmF0b3JbdW5pdF0pIHtcbiAgICAgICAgICAgIGxldCBsb2NhbFJlcyA9IG51bWVyYXRvclt1bml0XSAvIGRlbm9taW5hdG9yW3VuaXRdO1xuICAgICAgICAgICAgaWYgKCFpc0ludChsb2NhbFJlcykgfHwgKHJlcyAhPT0gbnVsbCAmJiByZXMgIT09IGxvY2FsUmVzKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVzID0gbG9jYWxSZXM7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAobnVtZXJhdG9yW3VuaXRdKSB7XG4gICAgICAgICAgICAvLyBuZWVkcyB0byBkaXZpZGUgYnkgc29tZXRoaW5nIGJ1dCBjYW4ndCFcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXM7XG59XG5mdW5jdGlvbiBncmVhdGVzdER1cmF0aW9uRGVub21pbmF0b3IoZHVyKSB7XG4gICAgbGV0IG1zID0gZHVyLm1pbGxpc2Vjb25kcztcbiAgICBpZiAobXMpIHtcbiAgICAgICAgaWYgKG1zICUgMTAwMCAhPT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIHsgdW5pdDogJ21pbGxpc2Vjb25kJywgdmFsdWU6IG1zIH07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1zICUgKDEwMDAgKiA2MCkgIT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiB7IHVuaXQ6ICdzZWNvbmQnLCB2YWx1ZTogbXMgLyAxMDAwIH07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1zICUgKDEwMDAgKiA2MCAqIDYwKSAhPT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIHsgdW5pdDogJ21pbnV0ZScsIHZhbHVlOiBtcyAvICgxMDAwICogNjApIH07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1zKSB7XG4gICAgICAgICAgICByZXR1cm4geyB1bml0OiAnaG91cicsIHZhbHVlOiBtcyAvICgxMDAwICogNjAgKiA2MCkgfTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAoZHVyLmRheXMpIHtcbiAgICAgICAgaWYgKGR1ci5zcGVjaWZpZWRXZWVrcyAmJiBkdXIuZGF5cyAlIDcgPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiB7IHVuaXQ6ICd3ZWVrJywgdmFsdWU6IGR1ci5kYXlzIC8gNyB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7IHVuaXQ6ICdkYXknLCB2YWx1ZTogZHVyLmRheXMgfTtcbiAgICB9XG4gICAgaWYgKGR1ci5tb250aHMpIHtcbiAgICAgICAgcmV0dXJuIHsgdW5pdDogJ21vbnRoJywgdmFsdWU6IGR1ci5tb250aHMgfTtcbiAgICB9XG4gICAgaWYgKGR1ci55ZWFycykge1xuICAgICAgICByZXR1cm4geyB1bml0OiAneWVhcicsIHZhbHVlOiBkdXIueWVhcnMgfTtcbiAgICB9XG4gICAgcmV0dXJuIHsgdW5pdDogJ21pbGxpc2Vjb25kJywgdmFsdWU6IDAgfTtcbn1cblxuY29uc3QgeyBoYXNPd25Qcm9wZXJ0eSB9ID0gT2JqZWN0LnByb3RvdHlwZTtcbi8vIE1lcmdlcyBhbiBhcnJheSBvZiBvYmplY3RzIGludG8gYSBzaW5nbGUgb2JqZWN0LlxuLy8gVGhlIHNlY29uZCBhcmd1bWVudCBhbGxvd3MgZm9yIGFuIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzIHdobydzIG9iamVjdCB2YWx1ZXMgd2lsbCBiZSBtZXJnZWQgdG9nZXRoZXIuXG5mdW5jdGlvbiBtZXJnZVByb3BzKHByb3BPYmpzLCBjb21wbGV4UHJvcHNNYXApIHtcbiAgICBsZXQgZGVzdCA9IHt9O1xuICAgIGlmIChjb21wbGV4UHJvcHNNYXApIHtcbiAgICAgICAgZm9yIChsZXQgbmFtZSBpbiBjb21wbGV4UHJvcHNNYXApIHtcbiAgICAgICAgICAgIGxldCBjb21wbGV4T2JqcyA9IFtdO1xuICAgICAgICAgICAgLy8gY29sbGVjdCB0aGUgdHJhaWxpbmcgb2JqZWN0IHZhbHVlcywgc3RvcHBpbmcgd2hlbiBhIG5vbi1vYmplY3QgaXMgZGlzY292ZXJlZFxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IHByb3BPYmpzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaSAtPSAxKSB7XG4gICAgICAgICAgICAgICAgbGV0IHZhbCA9IHByb3BPYmpzW2ldW25hbWVdO1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsID09PSAnb2JqZWN0JyAmJiB2YWwpIHsgLy8gbm9uLW51bGwgb2JqZWN0XG4gICAgICAgICAgICAgICAgICAgIGNvbXBsZXhPYmpzLnVuc2hpZnQodmFsKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAodmFsICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgZGVzdFtuYW1lXSA9IHZhbDsgLy8gaWYgdGhlcmUgd2VyZSBubyBvYmplY3RzLCB0aGlzIHZhbHVlIHdpbGwgYmUgdXNlZFxuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBpZiB0aGUgdHJhaWxpbmcgdmFsdWVzIHdlcmUgb2JqZWN0cywgdXNlIHRoZSBtZXJnZWQgdmFsdWVcbiAgICAgICAgICAgIGlmIChjb21wbGV4T2Jqcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBkZXN0W25hbWVdID0gbWVyZ2VQcm9wcyhjb21wbGV4T2Jqcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgLy8gY29weSB2YWx1ZXMgaW50byB0aGUgZGVzdGluYXRpb24sIGdvaW5nIGZyb20gbGFzdCB0byBmaXJzdFxuICAgIGZvciAobGV0IGkgPSBwcm9wT2Jqcy5sZW5ndGggLSAxOyBpID49IDA7IGkgLT0gMSkge1xuICAgICAgICBsZXQgcHJvcHMgPSBwcm9wT2Jqc1tpXTtcbiAgICAgICAgZm9yIChsZXQgbmFtZSBpbiBwcm9wcykge1xuICAgICAgICAgICAgaWYgKCEobmFtZSBpbiBkZXN0KSkgeyAvLyBpZiBhbHJlYWR5IGFzc2lnbmVkIGJ5IHByZXZpb3VzIHByb3BzIG9yIGNvbXBsZXggcHJvcHMsIGRvbid0IHJlYXNzaWduXG4gICAgICAgICAgICAgICAgZGVzdFtuYW1lXSA9IHByb3BzW25hbWVdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBkZXN0O1xufVxuZnVuY3Rpb24gZmlsdGVySGFzaChoYXNoLCBmdW5jKSB7XG4gICAgbGV0IGZpbHRlcmVkID0ge307XG4gICAgZm9yIChsZXQga2V5IGluIGhhc2gpIHtcbiAgICAgICAgaWYgKGZ1bmMoaGFzaFtrZXldLCBrZXkpKSB7XG4gICAgICAgICAgICBmaWx0ZXJlZFtrZXldID0gaGFzaFtrZXldO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmaWx0ZXJlZDtcbn1cbmZ1bmN0aW9uIG1hcEhhc2goaGFzaCwgZnVuYykge1xuICAgIGxldCBuZXdIYXNoID0ge307XG4gICAgZm9yIChsZXQga2V5IGluIGhhc2gpIHtcbiAgICAgICAgbmV3SGFzaFtrZXldID0gZnVuYyhoYXNoW2tleV0sIGtleSk7XG4gICAgfVxuICAgIHJldHVybiBuZXdIYXNoO1xufVxuZnVuY3Rpb24gYXJyYXlUb0hhc2goYSkge1xuICAgIGxldCBoYXNoID0ge307XG4gICAgZm9yIChsZXQgaXRlbSBvZiBhKSB7XG4gICAgICAgIGhhc2hbaXRlbV0gPSB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gaGFzaDtcbn1cbi8vIFRPRE86IHJlYXNzZXNzIGJyb3dzZXIgc3VwcG9ydFxuLy8gaHR0cHM6Ly9jYW5pdXNlLmNvbS8/c2VhcmNoPW9iamVjdC52YWx1ZXNcbmZ1bmN0aW9uIGhhc2hWYWx1ZXNUb0FycmF5KG9iaikge1xuICAgIGxldCBhID0gW107XG4gICAgZm9yIChsZXQga2V5IGluIG9iaikge1xuICAgICAgICBhLnB1c2gob2JqW2tleV0pO1xuICAgIH1cbiAgICByZXR1cm4gYTtcbn1cbmZ1bmN0aW9uIGlzUHJvcHNFcXVhbChvYmowLCBvYmoxKSB7XG4gICAgaWYgKG9iajAgPT09IG9iajEpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGZvciAobGV0IGtleSBpbiBvYmowKSB7XG4gICAgICAgIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iajAsIGtleSkpIHtcbiAgICAgICAgICAgIGlmICghKGtleSBpbiBvYmoxKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICBmb3IgKGxldCBrZXkgaW4gb2JqMSkge1xuICAgICAgICBpZiAoaGFzT3duUHJvcGVydHkuY2FsbChvYmoxLCBrZXkpKSB7XG4gICAgICAgICAgICBpZiAob2JqMFtrZXldICE9PSBvYmoxW2tleV0pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG5jb25zdCBIQU5ETEVSX1JFID0gL15vbltBLVpdLztcbmZ1bmN0aW9uIGlzTm9uSGFuZGxlclByb3BzRXF1YWwob2JqMCwgb2JqMSkge1xuICAgIGNvbnN0IGtleXMgPSBnZXRVbmVxdWFsUHJvcHMob2JqMCwgb2JqMSk7XG4gICAgZm9yIChsZXQga2V5IG9mIGtleXMpIHtcbiAgICAgICAgaWYgKCFIQU5ETEVSX1JFLnRlc3Qoa2V5KSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufVxuZnVuY3Rpb24gZ2V0VW5lcXVhbFByb3BzKG9iajAsIG9iajEpIHtcbiAgICBsZXQga2V5cyA9IFtdO1xuICAgIGZvciAobGV0IGtleSBpbiBvYmowKSB7XG4gICAgICAgIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iajAsIGtleSkpIHtcbiAgICAgICAgICAgIGlmICghKGtleSBpbiBvYmoxKSkge1xuICAgICAgICAgICAgICAgIGtleXMucHVzaChrZXkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIGZvciAobGV0IGtleSBpbiBvYmoxKSB7XG4gICAgICAgIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iajEsIGtleSkpIHtcbiAgICAgICAgICAgIGlmIChvYmowW2tleV0gIT09IG9iajFba2V5XSkge1xuICAgICAgICAgICAgICAgIGtleXMucHVzaChrZXkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBrZXlzO1xufVxuZnVuY3Rpb24gY29tcGFyZU9ianMob2xkUHJvcHMsIG5ld1Byb3BzLCBlcXVhbGl0eUZ1bmNzID0ge30pIHtcbiAgICBpZiAob2xkUHJvcHMgPT09IG5ld1Byb3BzKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBmb3IgKGxldCBrZXkgaW4gbmV3UHJvcHMpIHtcbiAgICAgICAgaWYgKGtleSBpbiBvbGRQcm9wcyAmJiBpc09ialZhbHNFcXVhbChvbGRQcm9wc1trZXldLCBuZXdQcm9wc1trZXldLCBlcXVhbGl0eUZ1bmNzW2tleV0pKSA7XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8vIGNoZWNrIGZvciBwcm9wcyB0aGF0IHdlcmUgb21pdHRlZCBpbiB0aGUgbmV3XG4gICAgZm9yIChsZXQga2V5IGluIG9sZFByb3BzKSB7XG4gICAgICAgIGlmICghKGtleSBpbiBuZXdQcm9wcykpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn1cbi8qXG5hc3N1bWVkIFwidHJ1ZVwiIGVxdWFsaXR5IGZvciBoYW5kbGVyIG5hbWVzIGxpa2UgXCJvblJlY2VpdmVTb21ldGhpbmdcIlxuKi9cbmZ1bmN0aW9uIGlzT2JqVmFsc0VxdWFsKHZhbDAsIHZhbDEsIGNvbXBhcmF0b3IpIHtcbiAgICBpZiAodmFsMCA9PT0gdmFsMSB8fCBjb21wYXJhdG9yID09PSB0cnVlKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBpZiAoY29tcGFyYXRvcikge1xuICAgICAgICByZXR1cm4gY29tcGFyYXRvcih2YWwwLCB2YWwxKTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuZnVuY3Rpb24gY29sbGVjdEZyb21IYXNoKGhhc2gsIHN0YXJ0SW5kZXggPSAwLCBlbmRJbmRleCwgc3RlcCA9IDEpIHtcbiAgICBsZXQgcmVzID0gW107XG4gICAgaWYgKGVuZEluZGV4ID09IG51bGwpIHtcbiAgICAgICAgZW5kSW5kZXggPSBPYmplY3Qua2V5cyhoYXNoKS5sZW5ndGg7XG4gICAgfVxuICAgIGZvciAobGV0IGkgPSBzdGFydEluZGV4OyBpIDwgZW5kSW5kZXg7IGkgKz0gc3RlcCkge1xuICAgICAgICBsZXQgdmFsID0gaGFzaFtpXTtcbiAgICAgICAgaWYgKHZhbCAhPT0gdW5kZWZpbmVkKSB7IC8vIHdpbGwgZGlzcmVnYXJkIHVuZGVmaW5lZCBmb3Igc3BhcnNlIGFycmF5c1xuICAgICAgICAgICAgcmVzLnB1c2godmFsKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzO1xufVxuXG5jb25zdCBEQVlfSURTID0gWydzdW4nLCAnbW9uJywgJ3R1ZScsICd3ZWQnLCAndGh1JywgJ2ZyaScsICdzYXQnXTtcbi8vIEFkZGluZ1xuZnVuY3Rpb24gYWRkV2Vla3MobSwgbikge1xuICAgIGxldCBhID0gZGF0ZVRvVXRjQXJyYXkobSk7XG4gICAgYVsyXSArPSBuICogNztcbiAgICByZXR1cm4gYXJyYXlUb1V0Y0RhdGUoYSk7XG59XG5mdW5jdGlvbiBhZGREYXlzKG0sIG4pIHtcbiAgICBsZXQgYSA9IGRhdGVUb1V0Y0FycmF5KG0pO1xuICAgIGFbMl0gKz0gbjtcbiAgICByZXR1cm4gYXJyYXlUb1V0Y0RhdGUoYSk7XG59XG5mdW5jdGlvbiBhZGRNcyhtLCBuKSB7XG4gICAgbGV0IGEgPSBkYXRlVG9VdGNBcnJheShtKTtcbiAgICBhWzZdICs9IG47XG4gICAgcmV0dXJuIGFycmF5VG9VdGNEYXRlKGEpO1xufVxuLy8gRGlmZmluZyAoYWxsIHJldHVybiBmbG9hdHMpXG4vLyBUT0RPOiB3aHkgbm90IHVzZSByYW5nZXM/XG5mdW5jdGlvbiBkaWZmV2Vla3MobTAsIG0xKSB7XG4gICAgcmV0dXJuIGRpZmZEYXlzKG0wLCBtMSkgLyA3O1xufVxuZnVuY3Rpb24gZGlmZkRheXMobTAsIG0xKSB7XG4gICAgcmV0dXJuIChtMS52YWx1ZU9mKCkgLSBtMC52YWx1ZU9mKCkpIC8gKDEwMDAgKiA2MCAqIDYwICogMjQpO1xufVxuZnVuY3Rpb24gZGlmZkhvdXJzKG0wLCBtMSkge1xuICAgIHJldHVybiAobTEudmFsdWVPZigpIC0gbTAudmFsdWVPZigpKSAvICgxMDAwICogNjAgKiA2MCk7XG59XG5mdW5jdGlvbiBkaWZmTWludXRlcyhtMCwgbTEpIHtcbiAgICByZXR1cm4gKG0xLnZhbHVlT2YoKSAtIG0wLnZhbHVlT2YoKSkgLyAoMTAwMCAqIDYwKTtcbn1cbmZ1bmN0aW9uIGRpZmZTZWNvbmRzKG0wLCBtMSkge1xuICAgIHJldHVybiAobTEudmFsdWVPZigpIC0gbTAudmFsdWVPZigpKSAvIDEwMDA7XG59XG5mdW5jdGlvbiBkaWZmRGF5QW5kVGltZShtMCwgbTEpIHtcbiAgICBsZXQgbTBkYXkgPSBzdGFydE9mRGF5KG0wKTtcbiAgICBsZXQgbTFkYXkgPSBzdGFydE9mRGF5KG0xKTtcbiAgICByZXR1cm4ge1xuICAgICAgICB5ZWFyczogMCxcbiAgICAgICAgbW9udGhzOiAwLFxuICAgICAgICBkYXlzOiBNYXRoLnJvdW5kKGRpZmZEYXlzKG0wZGF5LCBtMWRheSkpLFxuICAgICAgICBtaWxsaXNlY29uZHM6IChtMS52YWx1ZU9mKCkgLSBtMWRheS52YWx1ZU9mKCkpIC0gKG0wLnZhbHVlT2YoKSAtIG0wZGF5LnZhbHVlT2YoKSksXG4gICAgfTtcbn1cbi8vIERpZmZpbmcgV2hvbGUgVW5pdHNcbmZ1bmN0aW9uIGRpZmZXaG9sZVdlZWtzKG0wLCBtMSkge1xuICAgIGxldCBkID0gZGlmZldob2xlRGF5cyhtMCwgbTEpO1xuICAgIGlmIChkICE9PSBudWxsICYmIGQgJSA3ID09PSAwKSB7XG4gICAgICAgIHJldHVybiBkIC8gNztcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG59XG5mdW5jdGlvbiBkaWZmV2hvbGVEYXlzKG0wLCBtMSkge1xuICAgIGlmICh0aW1lQXNNcyhtMCkgPT09IHRpbWVBc01zKG0xKSkge1xuICAgICAgICByZXR1cm4gTWF0aC5yb3VuZChkaWZmRGF5cyhtMCwgbTEpKTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG59XG4vLyBTdGFydC1PZlxuZnVuY3Rpb24gc3RhcnRPZkRheShtKSB7XG4gICAgcmV0dXJuIGFycmF5VG9VdGNEYXRlKFtcbiAgICAgICAgbS5nZXRVVENGdWxsWWVhcigpLFxuICAgICAgICBtLmdldFVUQ01vbnRoKCksXG4gICAgICAgIG0uZ2V0VVRDRGF0ZSgpLFxuICAgIF0pO1xufVxuZnVuY3Rpb24gc3RhcnRPZkhvdXIobSkge1xuICAgIHJldHVybiBhcnJheVRvVXRjRGF0ZShbXG4gICAgICAgIG0uZ2V0VVRDRnVsbFllYXIoKSxcbiAgICAgICAgbS5nZXRVVENNb250aCgpLFxuICAgICAgICBtLmdldFVUQ0RhdGUoKSxcbiAgICAgICAgbS5nZXRVVENIb3VycygpLFxuICAgIF0pO1xufVxuZnVuY3Rpb24gc3RhcnRPZk1pbnV0ZShtKSB7XG4gICAgcmV0dXJuIGFycmF5VG9VdGNEYXRlKFtcbiAgICAgICAgbS5nZXRVVENGdWxsWWVhcigpLFxuICAgICAgICBtLmdldFVUQ01vbnRoKCksXG4gICAgICAgIG0uZ2V0VVRDRGF0ZSgpLFxuICAgICAgICBtLmdldFVUQ0hvdXJzKCksXG4gICAgICAgIG0uZ2V0VVRDTWludXRlcygpLFxuICAgIF0pO1xufVxuZnVuY3Rpb24gc3RhcnRPZlNlY29uZChtKSB7XG4gICAgcmV0dXJuIGFycmF5VG9VdGNEYXRlKFtcbiAgICAgICAgbS5nZXRVVENGdWxsWWVhcigpLFxuICAgICAgICBtLmdldFVUQ01vbnRoKCksXG4gICAgICAgIG0uZ2V0VVRDRGF0ZSgpLFxuICAgICAgICBtLmdldFVUQ0hvdXJzKCksXG4gICAgICAgIG0uZ2V0VVRDTWludXRlcygpLFxuICAgICAgICBtLmdldFVUQ1NlY29uZHMoKSxcbiAgICBdKTtcbn1cbi8vIFdlZWsgQ29tcHV0YXRpb25cbmZ1bmN0aW9uIHdlZWtPZlllYXIobWFya2VyLCBkb3csIGRveSkge1xuICAgIGxldCB5ID0gbWFya2VyLmdldFVUQ0Z1bGxZZWFyKCk7XG4gICAgbGV0IHcgPSB3ZWVrT2ZHaXZlblllYXIobWFya2VyLCB5LCBkb3csIGRveSk7XG4gICAgaWYgKHcgPCAxKSB7XG4gICAgICAgIHJldHVybiB3ZWVrT2ZHaXZlblllYXIobWFya2VyLCB5IC0gMSwgZG93LCBkb3kpO1xuICAgIH1cbiAgICBsZXQgbmV4dFcgPSB3ZWVrT2ZHaXZlblllYXIobWFya2VyLCB5ICsgMSwgZG93LCBkb3kpO1xuICAgIGlmIChuZXh0VyA+PSAxKSB7XG4gICAgICAgIHJldHVybiBNYXRoLm1pbih3LCBuZXh0Vyk7XG4gICAgfVxuICAgIHJldHVybiB3O1xufVxuZnVuY3Rpb24gd2Vla09mR2l2ZW5ZZWFyKG1hcmtlciwgeWVhciwgZG93LCBkb3kpIHtcbiAgICBsZXQgZmlyc3RXZWVrU3RhcnQgPSBhcnJheVRvVXRjRGF0ZShbeWVhciwgMCwgMSArIGZpcnN0V2Vla09mZnNldCh5ZWFyLCBkb3csIGRveSldKTtcbiAgICBsZXQgZGF5U3RhcnQgPSBzdGFydE9mRGF5KG1hcmtlcik7XG4gICAgbGV0IGRheXMgPSBNYXRoLnJvdW5kKGRpZmZEYXlzKGZpcnN0V2Vla1N0YXJ0LCBkYXlTdGFydCkpO1xuICAgIHJldHVybiBNYXRoLmZsb29yKGRheXMgLyA3KSArIDE7IC8vIHplcm8taW5kZXhlZFxufVxuLy8gc3RhcnQtb2YtZmlyc3Qtd2VlayAtIHN0YXJ0LW9mLXllYXJcbmZ1bmN0aW9uIGZpcnN0V2Vla09mZnNldCh5ZWFyLCBkb3csIGRveSkge1xuICAgIC8vIGZpcnN0LXdlZWsgZGF5IC0tIHdoaWNoIGphbnVhcnkgaXMgYWx3YXlzIGluIHRoZSBmaXJzdCB3ZWVrICg0IGZvciBpc28sIDEgZm9yIG90aGVyKVxuICAgIGxldCBmd2QgPSA3ICsgZG93IC0gZG95O1xuICAgIC8vIGZpcnN0LXdlZWsgZGF5IGxvY2FsIHdlZWtkYXkgLS0gd2hpY2ggbG9jYWwgd2Vla2RheSBpcyBmd2RcbiAgICBsZXQgZndkbHcgPSAoNyArIGFycmF5VG9VdGNEYXRlKFt5ZWFyLCAwLCBmd2RdKS5nZXRVVENEYXkoKSAtIGRvdykgJSA3O1xuICAgIHJldHVybiAtZndkbHcgKyBmd2QgLSAxO1xufVxuLy8gQXJyYXkgQ29udmVyc2lvblxuZnVuY3Rpb24gZGF0ZVRvTG9jYWxBcnJheShkYXRlKSB7XG4gICAgcmV0dXJuIFtcbiAgICAgICAgZGF0ZS5nZXRGdWxsWWVhcigpLFxuICAgICAgICBkYXRlLmdldE1vbnRoKCksXG4gICAgICAgIGRhdGUuZ2V0RGF0ZSgpLFxuICAgICAgICBkYXRlLmdldEhvdXJzKCksXG4gICAgICAgIGRhdGUuZ2V0TWludXRlcygpLFxuICAgICAgICBkYXRlLmdldFNlY29uZHMoKSxcbiAgICAgICAgZGF0ZS5nZXRNaWxsaXNlY29uZHMoKSxcbiAgICBdO1xufVxuZnVuY3Rpb24gYXJyYXlUb0xvY2FsRGF0ZShhKSB7XG4gICAgcmV0dXJuIG5ldyBEYXRlKGFbMF0sIGFbMV0gfHwgMCwgYVsyXSA9PSBudWxsID8gMSA6IGFbMl0sIC8vIGRheSBvZiBtb250aFxuICAgIGFbM10gfHwgMCwgYVs0XSB8fCAwLCBhWzVdIHx8IDApO1xufVxuZnVuY3Rpb24gZGF0ZVRvVXRjQXJyYXkoZGF0ZSkge1xuICAgIHJldHVybiBbXG4gICAgICAgIGRhdGUuZ2V0VVRDRnVsbFllYXIoKSxcbiAgICAgICAgZGF0ZS5nZXRVVENNb250aCgpLFxuICAgICAgICBkYXRlLmdldFVUQ0RhdGUoKSxcbiAgICAgICAgZGF0ZS5nZXRVVENIb3VycygpLFxuICAgICAgICBkYXRlLmdldFVUQ01pbnV0ZXMoKSxcbiAgICAgICAgZGF0ZS5nZXRVVENTZWNvbmRzKCksXG4gICAgICAgIGRhdGUuZ2V0VVRDTWlsbGlzZWNvbmRzKCksXG4gICAgXTtcbn1cbmZ1bmN0aW9uIGFycmF5VG9VdGNEYXRlKGEpIHtcbiAgICAvLyBhY2NvcmRpbmcgdG8gd2ViIHN0YW5kYXJkcyAoYW5kIFNhZmFyaSksIGEgbW9udGggaW5kZXggaXMgcmVxdWlyZWQuXG4gICAgLy8gbWFzc2FnZSBpZiBvbmx5IGdpdmVuIGEgeWVhci5cbiAgICBpZiAoYS5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgYSA9IGEuY29uY2F0KFswXSk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgRGF0ZShEYXRlLlVUQyguLi5hKSk7XG59XG4vLyBPdGhlciBVdGlsc1xuZnVuY3Rpb24gaXNWYWxpZERhdGUobSkge1xuICAgIHJldHVybiAhaXNOYU4obS52YWx1ZU9mKCkpO1xufVxuZnVuY3Rpb24gdGltZUFzTXMobSkge1xuICAgIHJldHVybiBtLmdldFVUQ0hvdXJzKCkgKiAxMDAwICogNjAgKiA2MCArXG4gICAgICAgIG0uZ2V0VVRDTWludXRlcygpICogMTAwMCAqIDYwICtcbiAgICAgICAgbS5nZXRVVENTZWNvbmRzKCkgKiAxMDAwICtcbiAgICAgICAgbS5nZXRVVENNaWxsaXNlY29uZHMoKTtcbn1cblxuLy8gdGltZVpvbmVPZmZzZXQgaXMgaW4gbWludXRlc1xuZnVuY3Rpb24gYnVpbGRJc29TdHJpbmcobWFya2VyLCB0aW1lWm9uZU9mZnNldCwgc3RyaXBaZXJvVGltZSA9IGZhbHNlKSB7XG4gICAgbGV0IHMgPSBtYXJrZXIudG9JU09TdHJpbmcoKTtcbiAgICBzID0gcy5yZXBsYWNlKCcuMDAwJywgJycpO1xuICAgIGlmIChzdHJpcFplcm9UaW1lKSB7XG4gICAgICAgIHMgPSBzLnJlcGxhY2UoJ1QwMDowMDowMFonLCAnJyk7XG4gICAgfVxuICAgIGlmIChzLmxlbmd0aCA+IDEwKSB7IC8vIHRpbWUgcGFydCB3YXNuJ3Qgc3RyaXBwZWQsIGNhbiBhZGQgdGltZXpvbmUgaW5mb1xuICAgICAgICBpZiAodGltZVpvbmVPZmZzZXQgPT0gbnVsbCkge1xuICAgICAgICAgICAgcyA9IHMucmVwbGFjZSgnWicsICcnKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0aW1lWm9uZU9mZnNldCAhPT0gMCkge1xuICAgICAgICAgICAgcyA9IHMucmVwbGFjZSgnWicsIGZvcm1hdFRpbWVab25lT2Zmc2V0KHRpbWVab25lT2Zmc2V0LCB0cnVlKSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gb3RoZXJ3aXNlLCBpdHMgVVRDLTAgYW5kIHdlIHdhbnQgdG8ga2VlcCB0aGUgWlxuICAgIH1cbiAgICByZXR1cm4gcztcbn1cbi8vIGZvcm1hdHMgdGhlIGRhdGUsIGJ1dCB3aXRoIG5vIHRpbWUgcGFydFxuLy8gVE9ETzogc29tZWhvdyBtZXJnZSB3aXRoIGJ1aWxkSXNvU3RyaW5nIGFuZCBzdHJpcFplcm9UaW1lXG4vLyBUT0RPOiByZW5hbWUuIG9taXQgXCJzdHJpbmdcIlxuZnVuY3Rpb24gZm9ybWF0RGF5U3RyaW5nKG1hcmtlcikge1xuICAgIHJldHVybiBtYXJrZXIudG9JU09TdHJpbmcoKS5yZXBsYWNlKC9ULiokLywgJycpO1xufVxuLy8gVE9ETzogdXNlIERhdGU6OnRvSVNPU3RyaW5nIGFuZCB1c2UgZXZlcnl0aGluZyBhZnRlciB0aGUgVD9cbmZ1bmN0aW9uIGZvcm1hdElzb1RpbWVTdHJpbmcobWFya2VyKSB7XG4gICAgcmV0dXJuIHBhZFN0YXJ0KG1hcmtlci5nZXRVVENIb3VycygpLCAyKSArICc6JyArXG4gICAgICAgIHBhZFN0YXJ0KG1hcmtlci5nZXRVVENNaW51dGVzKCksIDIpICsgJzonICtcbiAgICAgICAgcGFkU3RhcnQobWFya2VyLmdldFVUQ1NlY29uZHMoKSwgMik7XG59XG5mdW5jdGlvbiBmb3JtYXRUaW1lWm9uZU9mZnNldChtaW51dGVzLCBkb0lzbyA9IGZhbHNlKSB7XG4gICAgbGV0IHNpZ24gPSBtaW51dGVzIDwgMCA/ICctJyA6ICcrJztcbiAgICBsZXQgYWJzID0gTWF0aC5hYnMobWludXRlcyk7XG4gICAgbGV0IGhvdXJzID0gTWF0aC5mbG9vcihhYnMgLyA2MCk7XG4gICAgbGV0IG1pbnMgPSBNYXRoLnJvdW5kKGFicyAlIDYwKTtcbiAgICBpZiAoZG9Jc28pIHtcbiAgICAgICAgcmV0dXJuIGAke3NpZ24gKyBwYWRTdGFydChob3VycywgMil9OiR7cGFkU3RhcnQobWlucywgMil9YDtcbiAgICB9XG4gICAgcmV0dXJuIGBHTVQke3NpZ259JHtob3Vyc30ke21pbnMgPyBgOiR7cGFkU3RhcnQobWlucywgMil9YCA6ICcnfWA7XG59XG5cbi8vIFRPRE86IG5ldyB1dGlsIGFycmF5aWZ5P1xuZnVuY3Rpb24gcmVtb3ZlRXhhY3QoYXJyYXksIGV4YWN0VmFsKSB7XG4gICAgbGV0IHJlbW92ZUNudCA9IDA7XG4gICAgbGV0IGkgPSAwO1xuICAgIHdoaWxlIChpIDwgYXJyYXkubGVuZ3RoKSB7XG4gICAgICAgIGlmIChhcnJheVtpXSA9PT0gZXhhY3RWYWwpIHtcbiAgICAgICAgICAgIGFycmF5LnNwbGljZShpLCAxKTtcbiAgICAgICAgICAgIHJlbW92ZUNudCArPSAxO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgaSArPSAxO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZW1vdmVDbnQ7XG59XG5mdW5jdGlvbiBpc0FycmF5c0VxdWFsKGEwLCBhMSwgZXF1YWxpdHlGdW5jKSB7XG4gICAgaWYgKGEwID09PSBhMSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgbGV0IGxlbiA9IGEwLmxlbmd0aDtcbiAgICBsZXQgaTtcbiAgICBpZiAobGVuICE9PSBhMS5sZW5ndGgpIHsgLy8gbm90IGFycmF5PyBvciBub3Qgc2FtZSBsZW5ndGg/XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSArPSAxKSB7XG4gICAgICAgIGlmICghKGVxdWFsaXR5RnVuYyA/IGVxdWFsaXR5RnVuYyhhMFtpXSwgYTFbaV0pIDogYTBbaV0gPT09IGExW2ldKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBtZW1vaXplKHdvcmtlckZ1bmMsIHJlc0VxdWFsaXR5LCB0ZWFyZG93bkZ1bmMpIHtcbiAgICBsZXQgY3VycmVudEFyZ3M7XG4gICAgbGV0IGN1cnJlbnRSZXM7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICguLi5uZXdBcmdzKSB7XG4gICAgICAgIGlmICghY3VycmVudEFyZ3MpIHtcbiAgICAgICAgICAgIGN1cnJlbnRSZXMgPSB3b3JrZXJGdW5jLmFwcGx5KHRoaXMsIG5ld0FyZ3MpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKCFpc0FycmF5c0VxdWFsKGN1cnJlbnRBcmdzLCBuZXdBcmdzKSkge1xuICAgICAgICAgICAgaWYgKHRlYXJkb3duRnVuYykge1xuICAgICAgICAgICAgICAgIHRlYXJkb3duRnVuYyhjdXJyZW50UmVzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxldCByZXMgPSB3b3JrZXJGdW5jLmFwcGx5KHRoaXMsIG5ld0FyZ3MpO1xuICAgICAgICAgICAgaWYgKCFyZXNFcXVhbGl0eSB8fCAhcmVzRXF1YWxpdHkocmVzLCBjdXJyZW50UmVzKSkge1xuICAgICAgICAgICAgICAgIGN1cnJlbnRSZXMgPSByZXM7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY3VycmVudEFyZ3MgPSBuZXdBcmdzO1xuICAgICAgICByZXR1cm4gY3VycmVudFJlcztcbiAgICB9O1xufVxuZnVuY3Rpb24gbWVtb2l6ZU9iakFyZyh3b3JrZXJGdW5jLCByZXNFcXVhbGl0eSwgdGVhcmRvd25GdW5jKSB7XG4gICAgbGV0IGN1cnJlbnRBcmc7XG4gICAgbGV0IGN1cnJlbnRSZXM7XG4gICAgcmV0dXJuIChuZXdBcmcpID0+IHtcbiAgICAgICAgaWYgKCFjdXJyZW50QXJnKSB7XG4gICAgICAgICAgICBjdXJyZW50UmVzID0gd29ya2VyRnVuYy5jYWxsKHRoaXMsIG5ld0FyZyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoIWlzUHJvcHNFcXVhbChjdXJyZW50QXJnLCBuZXdBcmcpKSB7XG4gICAgICAgICAgICBpZiAodGVhcmRvd25GdW5jKSB7XG4gICAgICAgICAgICAgICAgdGVhcmRvd25GdW5jKGN1cnJlbnRSZXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGV0IHJlcyA9IHdvcmtlckZ1bmMuY2FsbCh0aGlzLCBuZXdBcmcpO1xuICAgICAgICAgICAgaWYgKCFyZXNFcXVhbGl0eSB8fCAhcmVzRXF1YWxpdHkocmVzLCBjdXJyZW50UmVzKSkge1xuICAgICAgICAgICAgICAgIGN1cnJlbnRSZXMgPSByZXM7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY3VycmVudEFyZyA9IG5ld0FyZztcbiAgICAgICAgcmV0dXJuIGN1cnJlbnRSZXM7XG4gICAgfTtcbn1cbmZ1bmN0aW9uIG1lbW9pemVBcnJheWxpa2UoLy8gdXNlZCBhdCBhbGw/XG53b3JrZXJGdW5jLCByZXNFcXVhbGl0eSwgdGVhcmRvd25GdW5jKSB7XG4gICAgbGV0IGN1cnJlbnRBcmdTZXRzID0gW107XG4gICAgbGV0IGN1cnJlbnRSZXN1bHRzID0gW107XG4gICAgcmV0dXJuIChuZXdBcmdTZXRzKSA9PiB7XG4gICAgICAgIGxldCBjdXJyZW50TGVuID0gY3VycmVudEFyZ1NldHMubGVuZ3RoO1xuICAgICAgICBsZXQgbmV3TGVuID0gbmV3QXJnU2V0cy5sZW5ndGg7XG4gICAgICAgIGxldCBpID0gMDtcbiAgICAgICAgZm9yICg7IGkgPCBjdXJyZW50TGVuOyBpICs9IDEpIHtcbiAgICAgICAgICAgIGlmICghbmV3QXJnU2V0c1tpXSkgeyAvLyBvbmUgb2YgdGhlIG9sZCBzZXRzIG5vIGxvbmdlciBleGlzdHNcbiAgICAgICAgICAgICAgICBpZiAodGVhcmRvd25GdW5jKSB7XG4gICAgICAgICAgICAgICAgICAgIHRlYXJkb3duRnVuYyhjdXJyZW50UmVzdWx0c1tpXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoIWlzQXJyYXlzRXF1YWwoY3VycmVudEFyZ1NldHNbaV0sIG5ld0FyZ1NldHNbaV0pKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRlYXJkb3duRnVuYykge1xuICAgICAgICAgICAgICAgICAgICB0ZWFyZG93bkZ1bmMoY3VycmVudFJlc3VsdHNbaV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsZXQgcmVzID0gd29ya2VyRnVuYy5hcHBseSh0aGlzLCBuZXdBcmdTZXRzW2ldKTtcbiAgICAgICAgICAgICAgICBpZiAoIXJlc0VxdWFsaXR5IHx8ICFyZXNFcXVhbGl0eShyZXMsIGN1cnJlbnRSZXN1bHRzW2ldKSkge1xuICAgICAgICAgICAgICAgICAgICBjdXJyZW50UmVzdWx0c1tpXSA9IHJlcztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZm9yICg7IGkgPCBuZXdMZW47IGkgKz0gMSkge1xuICAgICAgICAgICAgY3VycmVudFJlc3VsdHNbaV0gPSB3b3JrZXJGdW5jLmFwcGx5KHRoaXMsIG5ld0FyZ1NldHNbaV0pO1xuICAgICAgICB9XG4gICAgICAgIGN1cnJlbnRBcmdTZXRzID0gbmV3QXJnU2V0cztcbiAgICAgICAgY3VycmVudFJlc3VsdHMuc3BsaWNlKG5ld0xlbik7IC8vIHJlbW92ZSBleGNlc3NcbiAgICAgICAgcmV0dXJuIGN1cnJlbnRSZXN1bHRzO1xuICAgIH07XG59XG5mdW5jdGlvbiBtZW1vaXplSGFzaGxpa2Uod29ya2VyRnVuYywgcmVzRXF1YWxpdHksIHRlYXJkb3duRnVuYykge1xuICAgIGxldCBjdXJyZW50QXJnSGFzaCA9IHt9O1xuICAgIGxldCBjdXJyZW50UmVzSGFzaCA9IHt9O1xuICAgIHJldHVybiAobmV3QXJnSGFzaCkgPT4ge1xuICAgICAgICBsZXQgbmV3UmVzSGFzaCA9IHt9O1xuICAgICAgICBmb3IgKGxldCBrZXkgaW4gbmV3QXJnSGFzaCkge1xuICAgICAgICAgICAgaWYgKCFjdXJyZW50UmVzSGFzaFtrZXldKSB7XG4gICAgICAgICAgICAgICAgbmV3UmVzSGFzaFtrZXldID0gd29ya2VyRnVuYy5hcHBseSh0aGlzLCBuZXdBcmdIYXNoW2tleV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoIWlzQXJyYXlzRXF1YWwoY3VycmVudEFyZ0hhc2hba2V5XSwgbmV3QXJnSGFzaFtrZXldKSkge1xuICAgICAgICAgICAgICAgIGlmICh0ZWFyZG93bkZ1bmMpIHtcbiAgICAgICAgICAgICAgICAgICAgdGVhcmRvd25GdW5jKGN1cnJlbnRSZXNIYXNoW2tleV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBsZXQgcmVzID0gd29ya2VyRnVuYy5hcHBseSh0aGlzLCBuZXdBcmdIYXNoW2tleV0pO1xuICAgICAgICAgICAgICAgIG5ld1Jlc0hhc2hba2V5XSA9IChyZXNFcXVhbGl0eSAmJiByZXNFcXVhbGl0eShyZXMsIGN1cnJlbnRSZXNIYXNoW2tleV0pKVxuICAgICAgICAgICAgICAgICAgICA/IGN1cnJlbnRSZXNIYXNoW2tleV1cbiAgICAgICAgICAgICAgICAgICAgOiByZXM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBuZXdSZXNIYXNoW2tleV0gPSBjdXJyZW50UmVzSGFzaFtrZXldO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGN1cnJlbnRBcmdIYXNoID0gbmV3QXJnSGFzaDtcbiAgICAgICAgY3VycmVudFJlc0hhc2ggPSBuZXdSZXNIYXNoO1xuICAgICAgICByZXR1cm4gbmV3UmVzSGFzaDtcbiAgICB9O1xufVxuXG5jb25zdCBFWFRFTkRFRF9TRVRUSU5HU19BTkRfU0VWRVJJVElFUyA9IHtcbiAgICB3ZWVrOiAzLFxuICAgIHNlcGFyYXRvcjogMCxcbiAgICBvbWl0WmVyb01pbnV0ZTogMCxcbiAgICBtZXJpZGllbTogMCxcbiAgICBvbWl0Q29tbWFzOiAwLFxufTtcbmNvbnN0IFNUQU5EQVJEX0RBVEVfUFJPUF9TRVZFUklUSUVTID0ge1xuICAgIHRpbWVab25lTmFtZTogNyxcbiAgICBlcmE6IDYsXG4gICAgeWVhcjogNSxcbiAgICBtb250aDogNCxcbiAgICBkYXk6IDIsXG4gICAgd2Vla2RheTogMixcbiAgICBob3VyOiAxLFxuICAgIG1pbnV0ZTogMSxcbiAgICBzZWNvbmQ6IDEsXG59O1xuY29uc3QgTUVSSURJRU1fUkUgPSAvXFxzKihbYXBdKVxcLj9tXFwuPy9pOyAvLyBlYXRzIHVwIGxlYWRpbmcgc3BhY2VzIHRvb1xuY29uc3QgQ09NTUFfUkUgPSAvLC9nOyAvLyB3ZSBuZWVkIHJlIGZvciBnbG9iYWxuZXNzXG5jb25zdCBNVUxUSV9TUEFDRV9SRSA9IC9cXHMrL2c7XG5jb25zdCBMVFJfUkUgPSAvXFx1MjAwZS9nOyAvLyBjb250cm9sIGNoYXJhY3RlclxuY29uc3QgVVRDX1JFID0gL1VUQ3xHTVQvO1xuY2xhc3MgTmF0aXZlRm9ybWF0dGVyIHtcbiAgICBjb25zdHJ1Y3Rvcihmb3JtYXRTZXR0aW5ncykge1xuICAgICAgICBsZXQgc3RhbmRhcmREYXRlUHJvcHMgPSB7fTtcbiAgICAgICAgbGV0IGV4dGVuZGVkU2V0dGluZ3MgPSB7fTtcbiAgICAgICAgbGV0IHNldmVyaXR5ID0gMDtcbiAgICAgICAgZm9yIChsZXQgbmFtZSBpbiBmb3JtYXRTZXR0aW5ncykge1xuICAgICAgICAgICAgaWYgKG5hbWUgaW4gRVhURU5ERURfU0VUVElOR1NfQU5EX1NFVkVSSVRJRVMpIHtcbiAgICAgICAgICAgICAgICBleHRlbmRlZFNldHRpbmdzW25hbWVdID0gZm9ybWF0U2V0dGluZ3NbbmFtZV07XG4gICAgICAgICAgICAgICAgc2V2ZXJpdHkgPSBNYXRoLm1heChFWFRFTkRFRF9TRVRUSU5HU19BTkRfU0VWRVJJVElFU1tuYW1lXSwgc2V2ZXJpdHkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgc3RhbmRhcmREYXRlUHJvcHNbbmFtZV0gPSBmb3JtYXRTZXR0aW5nc1tuYW1lXTtcbiAgICAgICAgICAgICAgICBpZiAobmFtZSBpbiBTVEFOREFSRF9EQVRFX1BST1BfU0VWRVJJVElFUykgeyAvLyBUT0RPOiB3aGF0IGFib3V0IGhvdXIxMj8gbm8gc2V2ZXJpdHlcbiAgICAgICAgICAgICAgICAgICAgc2V2ZXJpdHkgPSBNYXRoLm1heChTVEFOREFSRF9EQVRFX1BST1BfU0VWRVJJVElFU1tuYW1lXSwgc2V2ZXJpdHkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLnN0YW5kYXJkRGF0ZVByb3BzID0gc3RhbmRhcmREYXRlUHJvcHM7XG4gICAgICAgIHRoaXMuZXh0ZW5kZWRTZXR0aW5ncyA9IGV4dGVuZGVkU2V0dGluZ3M7XG4gICAgICAgIHRoaXMuc2V2ZXJpdHkgPSBzZXZlcml0eTtcbiAgICAgICAgdGhpcy5idWlsZEZvcm1hdHRpbmdGdW5jID0gbWVtb2l6ZShidWlsZEZvcm1hdHRpbmdGdW5jKTtcbiAgICB9XG4gICAgZm9ybWF0KGRhdGUsIGNvbnRleHQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYnVpbGRGb3JtYXR0aW5nRnVuYyh0aGlzLnN0YW5kYXJkRGF0ZVByb3BzLCB0aGlzLmV4dGVuZGVkU2V0dGluZ3MsIGNvbnRleHQpKGRhdGUpO1xuICAgIH1cbiAgICBmb3JtYXRSYW5nZShzdGFydCwgZW5kLCBjb250ZXh0LCBiZXR0ZXJEZWZhdWx0U2VwYXJhdG9yKSB7XG4gICAgICAgIGxldCB7IHN0YW5kYXJkRGF0ZVByb3BzLCBleHRlbmRlZFNldHRpbmdzIH0gPSB0aGlzO1xuICAgICAgICBsZXQgZGlmZlNldmVyaXR5ID0gY29tcHV0ZU1hcmtlckRpZmZTZXZlcml0eShzdGFydC5tYXJrZXIsIGVuZC5tYXJrZXIsIGNvbnRleHQuY2FsZW5kYXJTeXN0ZW0pO1xuICAgICAgICBpZiAoIWRpZmZTZXZlcml0eSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZm9ybWF0KHN0YXJ0LCBjb250ZXh0KTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgYmlnZ2VzdFVuaXRGb3JQYXJ0aWFsID0gZGlmZlNldmVyaXR5O1xuICAgICAgICBpZiAoYmlnZ2VzdFVuaXRGb3JQYXJ0aWFsID4gMSAmJiAvLyB0aGUgdHdvIGRhdGVzIGFyZSBkaWZmZXJlbnQgaW4gYSB3YXkgdGhhdCdzIGxhcmdlciBzY2FsZSB0aGFuIHRpbWVcbiAgICAgICAgICAgIChzdGFuZGFyZERhdGVQcm9wcy55ZWFyID09PSAnbnVtZXJpYycgfHwgc3RhbmRhcmREYXRlUHJvcHMueWVhciA9PT0gJzItZGlnaXQnKSAmJlxuICAgICAgICAgICAgKHN0YW5kYXJkRGF0ZVByb3BzLm1vbnRoID09PSAnbnVtZXJpYycgfHwgc3RhbmRhcmREYXRlUHJvcHMubW9udGggPT09ICcyLWRpZ2l0JykgJiZcbiAgICAgICAgICAgIChzdGFuZGFyZERhdGVQcm9wcy5kYXkgPT09ICdudW1lcmljJyB8fCBzdGFuZGFyZERhdGVQcm9wcy5kYXkgPT09ICcyLWRpZ2l0JykpIHtcbiAgICAgICAgICAgIGJpZ2dlc3RVbml0Rm9yUGFydGlhbCA9IDE7IC8vIG1ha2UgaXQgbG9vayBsaWtlIHRoZSBkYXRlcyBhcmUgb25seSBkaWZmZXJlbnQgaW4gdGVybXMgb2YgdGltZVxuICAgICAgICB9XG4gICAgICAgIGxldCBmdWxsMCA9IHRoaXMuZm9ybWF0KHN0YXJ0LCBjb250ZXh0KTtcbiAgICAgICAgbGV0IGZ1bGwxID0gdGhpcy5mb3JtYXQoZW5kLCBjb250ZXh0KTtcbiAgICAgICAgaWYgKGZ1bGwwID09PSBmdWxsMSkge1xuICAgICAgICAgICAgcmV0dXJuIGZ1bGwwO1xuICAgICAgICB9XG4gICAgICAgIGxldCBwYXJ0aWFsRGF0ZVByb3BzID0gY29tcHV0ZVBhcnRpYWxGb3JtYXR0aW5nT3B0aW9ucyhzdGFuZGFyZERhdGVQcm9wcywgYmlnZ2VzdFVuaXRGb3JQYXJ0aWFsKTtcbiAgICAgICAgbGV0IHBhcnRpYWxGb3JtYXR0aW5nRnVuYyA9IGJ1aWxkRm9ybWF0dGluZ0Z1bmMocGFydGlhbERhdGVQcm9wcywgZXh0ZW5kZWRTZXR0aW5ncywgY29udGV4dCk7XG4gICAgICAgIGxldCBwYXJ0aWFsMCA9IHBhcnRpYWxGb3JtYXR0aW5nRnVuYyhzdGFydCk7XG4gICAgICAgIGxldCBwYXJ0aWFsMSA9IHBhcnRpYWxGb3JtYXR0aW5nRnVuYyhlbmQpO1xuICAgICAgICBsZXQgaW5zZXJ0aW9uID0gZmluZENvbW1vbkluc2VydGlvbihmdWxsMCwgcGFydGlhbDAsIGZ1bGwxLCBwYXJ0aWFsMSk7XG4gICAgICAgIGxldCBzZXBhcmF0b3IgPSBleHRlbmRlZFNldHRpbmdzLnNlcGFyYXRvciB8fCBiZXR0ZXJEZWZhdWx0U2VwYXJhdG9yIHx8IGNvbnRleHQuZGVmYXVsdFNlcGFyYXRvciB8fCAnJztcbiAgICAgICAgaWYgKGluc2VydGlvbikge1xuICAgICAgICAgICAgcmV0dXJuIGluc2VydGlvbi5iZWZvcmUgKyBwYXJ0aWFsMCArIHNlcGFyYXRvciArIHBhcnRpYWwxICsgaW5zZXJ0aW9uLmFmdGVyO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmdWxsMCArIHNlcGFyYXRvciArIGZ1bGwxO1xuICAgIH1cbiAgICBnZXRMYXJnZXN0VW5pdCgpIHtcbiAgICAgICAgc3dpdGNoICh0aGlzLnNldmVyaXR5KSB7XG4gICAgICAgICAgICBjYXNlIDc6XG4gICAgICAgICAgICBjYXNlIDY6XG4gICAgICAgICAgICBjYXNlIDU6XG4gICAgICAgICAgICAgICAgcmV0dXJuICd5ZWFyJztcbiAgICAgICAgICAgIGNhc2UgNDpcbiAgICAgICAgICAgICAgICByZXR1cm4gJ21vbnRoJztcbiAgICAgICAgICAgIGNhc2UgMzpcbiAgICAgICAgICAgICAgICByZXR1cm4gJ3dlZWsnO1xuICAgICAgICAgICAgY2FzZSAyOlxuICAgICAgICAgICAgICAgIHJldHVybiAnZGF5JztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuICd0aW1lJzsgLy8gcmVhbGx5P1xuICAgICAgICB9XG4gICAgfVxufVxuZnVuY3Rpb24gYnVpbGRGb3JtYXR0aW5nRnVuYyhzdGFuZGFyZERhdGVQcm9wcywgZXh0ZW5kZWRTZXR0aW5ncywgY29udGV4dCkge1xuICAgIGxldCBzdGFuZGFyZERhdGVQcm9wQ250ID0gT2JqZWN0LmtleXMoc3RhbmRhcmREYXRlUHJvcHMpLmxlbmd0aDtcbiAgICBpZiAoc3RhbmRhcmREYXRlUHJvcENudCA9PT0gMSAmJiBzdGFuZGFyZERhdGVQcm9wcy50aW1lWm9uZU5hbWUgPT09ICdzaG9ydCcpIHtcbiAgICAgICAgcmV0dXJuIChkYXRlKSA9PiAoZm9ybWF0VGltZVpvbmVPZmZzZXQoZGF0ZS50aW1lWm9uZU9mZnNldCkpO1xuICAgIH1cbiAgICBpZiAoc3RhbmRhcmREYXRlUHJvcENudCA9PT0gMCAmJiBleHRlbmRlZFNldHRpbmdzLndlZWspIHtcbiAgICAgICAgcmV0dXJuIChkYXRlKSA9PiAoZm9ybWF0V2Vla051bWJlcihjb250ZXh0LmNvbXB1dGVXZWVrTnVtYmVyKGRhdGUubWFya2VyKSwgY29udGV4dC53ZWVrVGV4dCwgY29udGV4dC53ZWVrVGV4dExvbmcsIGNvbnRleHQubG9jYWxlLCBleHRlbmRlZFNldHRpbmdzLndlZWspKTtcbiAgICB9XG4gICAgcmV0dXJuIGJ1aWxkTmF0aXZlRm9ybWF0dGluZ0Z1bmMoc3RhbmRhcmREYXRlUHJvcHMsIGV4dGVuZGVkU2V0dGluZ3MsIGNvbnRleHQpO1xufVxuZnVuY3Rpb24gYnVpbGROYXRpdmVGb3JtYXR0aW5nRnVuYyhzdGFuZGFyZERhdGVQcm9wcywgZXh0ZW5kZWRTZXR0aW5ncywgY29udGV4dCkge1xuICAgIHN0YW5kYXJkRGF0ZVByb3BzID0gT2JqZWN0LmFzc2lnbih7fSwgc3RhbmRhcmREYXRlUHJvcHMpOyAvLyBjb3B5XG4gICAgZXh0ZW5kZWRTZXR0aW5ncyA9IE9iamVjdC5hc3NpZ24oe30sIGV4dGVuZGVkU2V0dGluZ3MpOyAvLyBjb3B5XG4gICAgc2FuaXRpemVTZXR0aW5ncyhzdGFuZGFyZERhdGVQcm9wcywgZXh0ZW5kZWRTZXR0aW5ncyk7XG4gICAgc3RhbmRhcmREYXRlUHJvcHMudGltZVpvbmUgPSAnVVRDJzsgLy8gd2UgbGV2ZXJhZ2UgdGhlIG9ubHkgZ3VhcmFudGVlZCB0aW1lWm9uZSBmb3Igb3VyIFVUQyBtYXJrZXJzXG4gICAgbGV0IG5vcm1hbEZvcm1hdCA9IG5ldyBJbnRsLkRhdGVUaW1lRm9ybWF0KGNvbnRleHQubG9jYWxlLmNvZGVzLCBzdGFuZGFyZERhdGVQcm9wcyk7XG4gICAgbGV0IHplcm9Gb3JtYXQ7IC8vIG5lZWRlZD9cbiAgICBpZiAoZXh0ZW5kZWRTZXR0aW5ncy5vbWl0WmVyb01pbnV0ZSkge1xuICAgICAgICBsZXQgemVyb1Byb3BzID0gT2JqZWN0LmFzc2lnbih7fSwgc3RhbmRhcmREYXRlUHJvcHMpO1xuICAgICAgICBkZWxldGUgemVyb1Byb3BzLm1pbnV0ZTsgLy8gc2Vjb25kcyBhbmQgbXMgd2VyZSBhbHJlYWR5IGNvbnNpZGVyZWQgaW4gc2FuaXRpemVTZXR0aW5nc1xuICAgICAgICB6ZXJvRm9ybWF0ID0gbmV3IEludGwuRGF0ZVRpbWVGb3JtYXQoY29udGV4dC5sb2NhbGUuY29kZXMsIHplcm9Qcm9wcyk7XG4gICAgfVxuICAgIHJldHVybiAoZGF0ZSkgPT4ge1xuICAgICAgICBsZXQgeyBtYXJrZXIgfSA9IGRhdGU7XG4gICAgICAgIGxldCBmb3JtYXQ7XG4gICAgICAgIGlmICh6ZXJvRm9ybWF0ICYmICFtYXJrZXIuZ2V0VVRDTWludXRlcygpKSB7XG4gICAgICAgICAgICBmb3JtYXQgPSB6ZXJvRm9ybWF0O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZm9ybWF0ID0gbm9ybWFsRm9ybWF0O1xuICAgICAgICB9XG4gICAgICAgIGxldCBzID0gZm9ybWF0LmZvcm1hdChtYXJrZXIpO1xuICAgICAgICByZXR1cm4gcG9zdFByb2Nlc3MocywgZGF0ZSwgc3RhbmRhcmREYXRlUHJvcHMsIGV4dGVuZGVkU2V0dGluZ3MsIGNvbnRleHQpO1xuICAgIH07XG59XG5mdW5jdGlvbiBzYW5pdGl6ZVNldHRpbmdzKHN0YW5kYXJkRGF0ZVByb3BzLCBleHRlbmRlZFNldHRpbmdzKSB7XG4gICAgLy8gZGVhbCB3aXRoIGEgYnJvd3NlciBpbmNvbnNpc3RlbmN5IHdoZXJlIGZvcm1hdHRpbmcgdGhlIHRpbWV6b25lXG4gICAgLy8gcmVxdWlyZXMgdGhhdCB0aGUgaG91ci9taW51dGUgYmUgcHJlc2VudC5cbiAgICBpZiAoc3RhbmRhcmREYXRlUHJvcHMudGltZVpvbmVOYW1lKSB7XG4gICAgICAgIGlmICghc3RhbmRhcmREYXRlUHJvcHMuaG91cikge1xuICAgICAgICAgICAgc3RhbmRhcmREYXRlUHJvcHMuaG91ciA9ICcyLWRpZ2l0JztcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXN0YW5kYXJkRGF0ZVByb3BzLm1pbnV0ZSkge1xuICAgICAgICAgICAgc3RhbmRhcmREYXRlUHJvcHMubWludXRlID0gJzItZGlnaXQnO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8vIG9ubHkgc3VwcG9ydCBzaG9ydCB0aW1lem9uZSBuYW1lc1xuICAgIGlmIChzdGFuZGFyZERhdGVQcm9wcy50aW1lWm9uZU5hbWUgPT09ICdsb25nJykge1xuICAgICAgICBzdGFuZGFyZERhdGVQcm9wcy50aW1lWm9uZU5hbWUgPSAnc2hvcnQnO1xuICAgIH1cbiAgICAvLyBpZiByZXF1ZXN0aW5nIHRvIGRpc3BsYXkgc2Vjb25kcywgTVVTVCBkaXNwbGF5IG1pbnV0ZXNcbiAgICBpZiAoZXh0ZW5kZWRTZXR0aW5ncy5vbWl0WmVyb01pbnV0ZSAmJiAoc3RhbmRhcmREYXRlUHJvcHMuc2Vjb25kIHx8IHN0YW5kYXJkRGF0ZVByb3BzLm1pbGxpc2Vjb25kKSkge1xuICAgICAgICBkZWxldGUgZXh0ZW5kZWRTZXR0aW5ncy5vbWl0WmVyb01pbnV0ZTtcbiAgICB9XG59XG5mdW5jdGlvbiBwb3N0UHJvY2VzcyhzLCBkYXRlLCBzdGFuZGFyZERhdGVQcm9wcywgZXh0ZW5kZWRTZXR0aW5ncywgY29udGV4dCkge1xuICAgIHMgPSBzLnJlcGxhY2UoTFRSX1JFLCAnJyk7IC8vIHJlbW92ZSBsZWZ0LXRvLXJpZ2h0IGNvbnRyb2wgY2hhcnMuIGRvIGZpcnN0LiBnb29kIGZvciBvdGhlciByZWdleGVzXG4gICAgaWYgKHN0YW5kYXJkRGF0ZVByb3BzLnRpbWVab25lTmFtZSA9PT0gJ3Nob3J0Jykge1xuICAgICAgICBzID0gaW5qZWN0VHpvU3RyKHMsIChjb250ZXh0LnRpbWVab25lID09PSAnVVRDJyB8fCBkYXRlLnRpbWVab25lT2Zmc2V0ID09IG51bGwpID9cbiAgICAgICAgICAgICdVVEMnIDogLy8gaW1wb3J0YW50IHRvIG5vcm1hbGl6ZSBmb3IgSUUsIHdoaWNoIGRvZXMgXCJHTVRcIlxuICAgICAgICAgICAgZm9ybWF0VGltZVpvbmVPZmZzZXQoZGF0ZS50aW1lWm9uZU9mZnNldCkpO1xuICAgIH1cbiAgICBpZiAoZXh0ZW5kZWRTZXR0aW5ncy5vbWl0Q29tbWFzKSB7XG4gICAgICAgIHMgPSBzLnJlcGxhY2UoQ09NTUFfUkUsICcnKS50cmltKCk7XG4gICAgfVxuICAgIGlmIChleHRlbmRlZFNldHRpbmdzLm9taXRaZXJvTWludXRlKSB7XG4gICAgICAgIHMgPSBzLnJlcGxhY2UoJzowMCcsICcnKTsgLy8gemVyb0Zvcm1hdCBkb2Vzbid0IGFsd2F5cyBhY2hpZXZlIHRoaXNcbiAgICB9XG4gICAgLy8gXiBkbyBhbnl0aGluZyB0aGF0IG1pZ2h0IGNyZWF0ZSBhZGphY2VudCBzcGFjZXMgYmVmb3JlIHRoaXMgcG9pbnQsXG4gICAgLy8gYmVjYXVzZSBNRVJJRElFTV9SRSBsaWtlcyB0byBlYXQgdXAgbG9hZGluZyBzcGFjZXNcbiAgICBpZiAoZXh0ZW5kZWRTZXR0aW5ncy5tZXJpZGllbSA9PT0gZmFsc2UpIHtcbiAgICAgICAgcyA9IHMucmVwbGFjZShNRVJJRElFTV9SRSwgJycpLnRyaW0oKTtcbiAgICB9XG4gICAgZWxzZSBpZiAoZXh0ZW5kZWRTZXR0aW5ncy5tZXJpZGllbSA9PT0gJ25hcnJvdycpIHsgLy8gYS9wXG4gICAgICAgIHMgPSBzLnJlcGxhY2UoTUVSSURJRU1fUkUsIChtMCwgbTEpID0+IG0xLnRvTG9jYWxlTG93ZXJDYXNlKCkpO1xuICAgIH1cbiAgICBlbHNlIGlmIChleHRlbmRlZFNldHRpbmdzLm1lcmlkaWVtID09PSAnc2hvcnQnKSB7IC8vIGFtL3BtXG4gICAgICAgIHMgPSBzLnJlcGxhY2UoTUVSSURJRU1fUkUsIChtMCwgbTEpID0+IGAke20xLnRvTG9jYWxlTG93ZXJDYXNlKCl9bWApO1xuICAgIH1cbiAgICBlbHNlIGlmIChleHRlbmRlZFNldHRpbmdzLm1lcmlkaWVtID09PSAnbG93ZXJjYXNlJykgeyAvLyBvdGhlciBtZXJpZGllbSB0cmFuc2Zvcm1lcnMgYWxyZWFkeSBjb252ZXJ0ZWQgdG8gbG93ZXJjYXNlXG4gICAgICAgIHMgPSBzLnJlcGxhY2UoTUVSSURJRU1fUkUsIChtMCkgPT4gbTAudG9Mb2NhbGVMb3dlckNhc2UoKSk7XG4gICAgfVxuICAgIHMgPSBzLnJlcGxhY2UoTVVMVElfU1BBQ0VfUkUsICcgJyk7XG4gICAgcyA9IHMudHJpbSgpO1xuICAgIHJldHVybiBzO1xufVxuZnVuY3Rpb24gaW5qZWN0VHpvU3RyKHMsIHR6b1N0cikge1xuICAgIGxldCByZXBsYWNlZCA9IGZhbHNlO1xuICAgIHMgPSBzLnJlcGxhY2UoVVRDX1JFLCAoKSA9PiB7XG4gICAgICAgIHJlcGxhY2VkID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIHR6b1N0cjtcbiAgICB9KTtcbiAgICAvLyBJRTExIGRvZXNuJ3QgaW5jbHVkZSBVVEMvR01UIGluIHRoZSBvcmlnaW5hbCBzdHJpbmcsIHNvIGFwcGVuZCB0byBlbmRcbiAgICBpZiAoIXJlcGxhY2VkKSB7XG4gICAgICAgIHMgKz0gYCAke3R6b1N0cn1gO1xuICAgIH1cbiAgICByZXR1cm4gcztcbn1cbmZ1bmN0aW9uIGZvcm1hdFdlZWtOdW1iZXIobnVtLCB3ZWVrVGV4dCwgd2Vla1RleHRMb25nLCBsb2NhbGUsIGRpc3BsYXkpIHtcbiAgICBsZXQgcGFydHMgPSBbXTtcbiAgICBpZiAoZGlzcGxheSA9PT0gJ2xvbmcnKSB7XG4gICAgICAgIHBhcnRzLnB1c2god2Vla1RleHRMb25nKTtcbiAgICB9XG4gICAgZWxzZSBpZiAoZGlzcGxheSA9PT0gJ3Nob3J0JyB8fCBkaXNwbGF5ID09PSAnbmFycm93Jykge1xuICAgICAgICBwYXJ0cy5wdXNoKHdlZWtUZXh0KTtcbiAgICB9XG4gICAgaWYgKGRpc3BsYXkgPT09ICdsb25nJyB8fCBkaXNwbGF5ID09PSAnc2hvcnQnKSB7XG4gICAgICAgIHBhcnRzLnB1c2goJyAnKTtcbiAgICB9XG4gICAgcGFydHMucHVzaChsb2NhbGUuc2ltcGxlTnVtYmVyRm9ybWF0LmZvcm1hdChudW0pKTtcbiAgICBpZiAobG9jYWxlLm9wdGlvbnMuZGlyZWN0aW9uID09PSAncnRsJykgeyAvLyBUT0RPOiB1c2UgY29udHJvbCBjaGFyYWN0ZXJzIGluc3RlYWQ/XG4gICAgICAgIHBhcnRzLnJldmVyc2UoKTtcbiAgICB9XG4gICAgcmV0dXJuIHBhcnRzLmpvaW4oJycpO1xufVxuLy8gUmFuZ2UgRm9ybWF0dGluZyBVdGlsc1xuLy8gMCA9IGV4YWN0bHkgdGhlIHNhbWVcbi8vIDEgPSBkaWZmZXJlbnQgYnkgdGltZVxuLy8gYW5kIGJpZ2dlclxuZnVuY3Rpb24gY29tcHV0ZU1hcmtlckRpZmZTZXZlcml0eShkMCwgZDEsIGNhKSB7XG4gICAgaWYgKGNhLmdldE1hcmtlclllYXIoZDApICE9PSBjYS5nZXRNYXJrZXJZZWFyKGQxKSkge1xuICAgICAgICByZXR1cm4gNTtcbiAgICB9XG4gICAgaWYgKGNhLmdldE1hcmtlck1vbnRoKGQwKSAhPT0gY2EuZ2V0TWFya2VyTW9udGgoZDEpKSB7XG4gICAgICAgIHJldHVybiA0O1xuICAgIH1cbiAgICBpZiAoY2EuZ2V0TWFya2VyRGF5KGQwKSAhPT0gY2EuZ2V0TWFya2VyRGF5KGQxKSkge1xuICAgICAgICByZXR1cm4gMjtcbiAgICB9XG4gICAgaWYgKHRpbWVBc01zKGQwKSAhPT0gdGltZUFzTXMoZDEpKSB7XG4gICAgICAgIHJldHVybiAxO1xuICAgIH1cbiAgICByZXR1cm4gMDtcbn1cbmZ1bmN0aW9uIGNvbXB1dGVQYXJ0aWFsRm9ybWF0dGluZ09wdGlvbnMob3B0aW9ucywgYmlnZ2VzdFVuaXQpIHtcbiAgICBsZXQgcGFydGlhbE9wdGlvbnMgPSB7fTtcbiAgICBmb3IgKGxldCBuYW1lIGluIG9wdGlvbnMpIHtcbiAgICAgICAgaWYgKCEobmFtZSBpbiBTVEFOREFSRF9EQVRFX1BST1BfU0VWRVJJVElFUykgfHwgLy8gbm90IGEgZGF0ZSBwYXJ0IHByb3AgKGxpa2UgdGltZVpvbmUpXG4gICAgICAgICAgICBTVEFOREFSRF9EQVRFX1BST1BfU0VWRVJJVElFU1tuYW1lXSA8PSBiaWdnZXN0VW5pdCkge1xuICAgICAgICAgICAgcGFydGlhbE9wdGlvbnNbbmFtZV0gPSBvcHRpb25zW25hbWVdO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBwYXJ0aWFsT3B0aW9ucztcbn1cbmZ1bmN0aW9uIGZpbmRDb21tb25JbnNlcnRpb24oZnVsbDAsIHBhcnRpYWwwLCBmdWxsMSwgcGFydGlhbDEpIHtcbiAgICBsZXQgaTAgPSAwO1xuICAgIHdoaWxlIChpMCA8IGZ1bGwwLmxlbmd0aCkge1xuICAgICAgICBsZXQgZm91bmQwID0gZnVsbDAuaW5kZXhPZihwYXJ0aWFsMCwgaTApO1xuICAgICAgICBpZiAoZm91bmQwID09PSAtMSkge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGJlZm9yZTAgPSBmdWxsMC5zdWJzdHIoMCwgZm91bmQwKTtcbiAgICAgICAgaTAgPSBmb3VuZDAgKyBwYXJ0aWFsMC5sZW5ndGg7XG4gICAgICAgIGxldCBhZnRlcjAgPSBmdWxsMC5zdWJzdHIoaTApO1xuICAgICAgICBsZXQgaTEgPSAwO1xuICAgICAgICB3aGlsZSAoaTEgPCBmdWxsMS5sZW5ndGgpIHtcbiAgICAgICAgICAgIGxldCBmb3VuZDEgPSBmdWxsMS5pbmRleE9mKHBhcnRpYWwxLCBpMSk7XG4gICAgICAgICAgICBpZiAoZm91bmQxID09PSAtMSkge1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGV0IGJlZm9yZTEgPSBmdWxsMS5zdWJzdHIoMCwgZm91bmQxKTtcbiAgICAgICAgICAgIGkxID0gZm91bmQxICsgcGFydGlhbDEubGVuZ3RoO1xuICAgICAgICAgICAgbGV0IGFmdGVyMSA9IGZ1bGwxLnN1YnN0cihpMSk7XG4gICAgICAgICAgICBpZiAoYmVmb3JlMCA9PT0gYmVmb3JlMSAmJiBhZnRlcjAgPT09IGFmdGVyMSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgIGJlZm9yZTogYmVmb3JlMCxcbiAgICAgICAgICAgICAgICAgICAgYWZ0ZXI6IGFmdGVyMCxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xufVxuXG5mdW5jdGlvbiBleHBhbmRab25lZE1hcmtlcihkYXRlSW5mbywgY2FsZW5kYXJTeXN0ZW0pIHtcbiAgICBsZXQgYSA9IGNhbGVuZGFyU3lzdGVtLm1hcmtlclRvQXJyYXkoZGF0ZUluZm8ubWFya2VyKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBtYXJrZXI6IGRhdGVJbmZvLm1hcmtlcixcbiAgICAgICAgdGltZVpvbmVPZmZzZXQ6IGRhdGVJbmZvLnRpbWVab25lT2Zmc2V0LFxuICAgICAgICBhcnJheTogYSxcbiAgICAgICAgeWVhcjogYVswXSxcbiAgICAgICAgbW9udGg6IGFbMV0sXG4gICAgICAgIGRheTogYVsyXSxcbiAgICAgICAgaG91cjogYVszXSxcbiAgICAgICAgbWludXRlOiBhWzRdLFxuICAgICAgICBzZWNvbmQ6IGFbNV0sXG4gICAgICAgIG1pbGxpc2Vjb25kOiBhWzZdLFxuICAgIH07XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVZlcmJvc2VGb3JtYXR0aW5nQXJnKHN0YXJ0LCBlbmQsIGNvbnRleHQsIGJldHRlckRlZmF1bHRTZXBhcmF0b3IpIHtcbiAgICBsZXQgc3RhcnRJbmZvID0gZXhwYW5kWm9uZWRNYXJrZXIoc3RhcnQsIGNvbnRleHQuY2FsZW5kYXJTeXN0ZW0pO1xuICAgIGxldCBlbmRJbmZvID0gZW5kID8gZXhwYW5kWm9uZWRNYXJrZXIoZW5kLCBjb250ZXh0LmNhbGVuZGFyU3lzdGVtKSA6IG51bGw7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgZGF0ZTogc3RhcnRJbmZvLFxuICAgICAgICBzdGFydDogc3RhcnRJbmZvLFxuICAgICAgICBlbmQ6IGVuZEluZm8sXG4gICAgICAgIHRpbWVab25lOiBjb250ZXh0LnRpbWVab25lLFxuICAgICAgICBsb2NhbGVDb2RlczogY29udGV4dC5sb2NhbGUuY29kZXMsXG4gICAgICAgIGRlZmF1bHRTZXBhcmF0b3I6IGJldHRlckRlZmF1bHRTZXBhcmF0b3IgfHwgY29udGV4dC5kZWZhdWx0U2VwYXJhdG9yLFxuICAgIH07XG59XG5cbi8qXG5UT0RPOiBmaXggdGhlIHRlcm1pbm9sb2d5IG9mIFwiZm9ybWF0dGVyXCIgdnMgXCJmb3JtYXR0aW5nIGZ1bmNcIlxuKi9cbi8qXG5BdCB0aGUgdGltZSBvZiBpbnN0YW50aWF0aW9uLCB0aGlzIG9iamVjdCBkb2VzIG5vdCBrbm93IHdoaWNoIGNtZC1mb3JtYXR0aW5nIHN5c3RlbSBpdCB3aWxsIHVzZS5cbkl0IHJlY2VpdmVzIHRoaXMgYXQgdGhlIHRpbWUgb2YgZm9ybWF0dGluZywgYXMgYSBzZXR0aW5nLlxuKi9cbmNsYXNzIENtZEZvcm1hdHRlciB7XG4gICAgY29uc3RydWN0b3IoY21kU3RyKSB7XG4gICAgICAgIHRoaXMuY21kU3RyID0gY21kU3RyO1xuICAgIH1cbiAgICBmb3JtYXQoZGF0ZSwgY29udGV4dCwgYmV0dGVyRGVmYXVsdFNlcGFyYXRvcikge1xuICAgICAgICByZXR1cm4gY29udGV4dC5jbWRGb3JtYXR0ZXIodGhpcy5jbWRTdHIsIGNyZWF0ZVZlcmJvc2VGb3JtYXR0aW5nQXJnKGRhdGUsIG51bGwsIGNvbnRleHQsIGJldHRlckRlZmF1bHRTZXBhcmF0b3IpKTtcbiAgICB9XG4gICAgZm9ybWF0UmFuZ2Uoc3RhcnQsIGVuZCwgY29udGV4dCwgYmV0dGVyRGVmYXVsdFNlcGFyYXRvcikge1xuICAgICAgICByZXR1cm4gY29udGV4dC5jbWRGb3JtYXR0ZXIodGhpcy5jbWRTdHIsIGNyZWF0ZVZlcmJvc2VGb3JtYXR0aW5nQXJnKHN0YXJ0LCBlbmQsIGNvbnRleHQsIGJldHRlckRlZmF1bHRTZXBhcmF0b3IpKTtcbiAgICB9XG59XG5cbmNsYXNzIEZ1bmNGb3JtYXR0ZXIge1xuICAgIGNvbnN0cnVjdG9yKGZ1bmMpIHtcbiAgICAgICAgdGhpcy5mdW5jID0gZnVuYztcbiAgICB9XG4gICAgZm9ybWF0KGRhdGUsIGNvbnRleHQsIGJldHRlckRlZmF1bHRTZXBhcmF0b3IpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZnVuYyhjcmVhdGVWZXJib3NlRm9ybWF0dGluZ0FyZyhkYXRlLCBudWxsLCBjb250ZXh0LCBiZXR0ZXJEZWZhdWx0U2VwYXJhdG9yKSk7XG4gICAgfVxuICAgIGZvcm1hdFJhbmdlKHN0YXJ0LCBlbmQsIGNvbnRleHQsIGJldHRlckRlZmF1bHRTZXBhcmF0b3IpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZnVuYyhjcmVhdGVWZXJib3NlRm9ybWF0dGluZ0FyZyhzdGFydCwgZW5kLCBjb250ZXh0LCBiZXR0ZXJEZWZhdWx0U2VwYXJhdG9yKSk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBjcmVhdGVGb3JtYXR0ZXIoaW5wdXQpIHtcbiAgICBpZiAodHlwZW9mIGlucHV0ID09PSAnb2JqZWN0JyAmJiBpbnB1dCkgeyAvLyBub24tbnVsbCBvYmplY3RcbiAgICAgICAgcmV0dXJuIG5ldyBOYXRpdmVGb3JtYXR0ZXIoaW5wdXQpO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIGlucHV0ID09PSAnc3RyaW5nJykge1xuICAgICAgICByZXR1cm4gbmV3IENtZEZvcm1hdHRlcihpbnB1dCk7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgaW5wdXQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBGdW5jRm9ybWF0dGVyKGlucHV0KTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG59XG5cbi8vIGJhc2Ugb3B0aW9uc1xuLy8gLS0tLS0tLS0tLS0tXG5jb25zdCBCQVNFX09QVElPTl9SRUZJTkVSUyA9IHtcbiAgICBuYXZMaW5rRGF5Q2xpY2s6IGlkZW50aXR5LFxuICAgIG5hdkxpbmtXZWVrQ2xpY2s6IGlkZW50aXR5LFxuICAgIGR1cmF0aW9uOiBjcmVhdGVEdXJhdGlvbixcbiAgICBib290c3RyYXBGb250QXdlc29tZTogaWRlbnRpdHksXG4gICAgYnV0dG9uSWNvbnM6IGlkZW50aXR5LFxuICAgIGN1c3RvbUJ1dHRvbnM6IGlkZW50aXR5LFxuICAgIGRlZmF1bHRBbGxEYXlFdmVudER1cmF0aW9uOiBjcmVhdGVEdXJhdGlvbixcbiAgICBkZWZhdWx0VGltZWRFdmVudER1cmF0aW9uOiBjcmVhdGVEdXJhdGlvbixcbiAgICBuZXh0RGF5VGhyZXNob2xkOiBjcmVhdGVEdXJhdGlvbixcbiAgICBzY3JvbGxUaW1lOiBjcmVhdGVEdXJhdGlvbixcbiAgICBzY3JvbGxUaW1lUmVzZXQ6IEJvb2xlYW4sXG4gICAgc2xvdE1pblRpbWU6IGNyZWF0ZUR1cmF0aW9uLFxuICAgIHNsb3RNYXhUaW1lOiBjcmVhdGVEdXJhdGlvbixcbiAgICBkYXlQb3BvdmVyRm9ybWF0OiBjcmVhdGVGb3JtYXR0ZXIsXG4gICAgc2xvdER1cmF0aW9uOiBjcmVhdGVEdXJhdGlvbixcbiAgICBzbmFwRHVyYXRpb246IGNyZWF0ZUR1cmF0aW9uLFxuICAgIGhlYWRlclRvb2xiYXI6IGlkZW50aXR5LFxuICAgIGZvb3RlclRvb2xiYXI6IGlkZW50aXR5LFxuICAgIGRlZmF1bHRSYW5nZVNlcGFyYXRvcjogU3RyaW5nLFxuICAgIHRpdGxlUmFuZ2VTZXBhcmF0b3I6IFN0cmluZyxcbiAgICBmb3JjZUV2ZW50RHVyYXRpb246IEJvb2xlYW4sXG4gICAgZGF5SGVhZGVyczogQm9vbGVhbixcbiAgICBkYXlIZWFkZXJGb3JtYXQ6IGNyZWF0ZUZvcm1hdHRlcixcbiAgICBkYXlIZWFkZXJDbGFzc05hbWVzOiBpZGVudGl0eSxcbiAgICBkYXlIZWFkZXJDb250ZW50OiBpZGVudGl0eSxcbiAgICBkYXlIZWFkZXJEaWRNb3VudDogaWRlbnRpdHksXG4gICAgZGF5SGVhZGVyV2lsbFVubW91bnQ6IGlkZW50aXR5LFxuICAgIGRheUNlbGxDbGFzc05hbWVzOiBpZGVudGl0eSxcbiAgICBkYXlDZWxsQ29udGVudDogaWRlbnRpdHksXG4gICAgZGF5Q2VsbERpZE1vdW50OiBpZGVudGl0eSxcbiAgICBkYXlDZWxsV2lsbFVubW91bnQ6IGlkZW50aXR5LFxuICAgIGluaXRpYWxWaWV3OiBTdHJpbmcsXG4gICAgYXNwZWN0UmF0aW86IE51bWJlcixcbiAgICB3ZWVrZW5kczogQm9vbGVhbixcbiAgICB3ZWVrTnVtYmVyQ2FsY3VsYXRpb246IGlkZW50aXR5LFxuICAgIHdlZWtOdW1iZXJzOiBCb29sZWFuLFxuICAgIHdlZWtOdW1iZXJDbGFzc05hbWVzOiBpZGVudGl0eSxcbiAgICB3ZWVrTnVtYmVyQ29udGVudDogaWRlbnRpdHksXG4gICAgd2Vla051bWJlckRpZE1vdW50OiBpZGVudGl0eSxcbiAgICB3ZWVrTnVtYmVyV2lsbFVubW91bnQ6IGlkZW50aXR5LFxuICAgIGVkaXRhYmxlOiBCb29sZWFuLFxuICAgIHZpZXdDbGFzc05hbWVzOiBpZGVudGl0eSxcbiAgICB2aWV3RGlkTW91bnQ6IGlkZW50aXR5LFxuICAgIHZpZXdXaWxsVW5tb3VudDogaWRlbnRpdHksXG4gICAgbm93SW5kaWNhdG9yOiBCb29sZWFuLFxuICAgIG5vd0luZGljYXRvckNsYXNzTmFtZXM6IGlkZW50aXR5LFxuICAgIG5vd0luZGljYXRvckNvbnRlbnQ6IGlkZW50aXR5LFxuICAgIG5vd0luZGljYXRvckRpZE1vdW50OiBpZGVudGl0eSxcbiAgICBub3dJbmRpY2F0b3JXaWxsVW5tb3VudDogaWRlbnRpdHksXG4gICAgc2hvd05vbkN1cnJlbnREYXRlczogQm9vbGVhbixcbiAgICBsYXp5RmV0Y2hpbmc6IEJvb2xlYW4sXG4gICAgc3RhcnRQYXJhbTogU3RyaW5nLFxuICAgIGVuZFBhcmFtOiBTdHJpbmcsXG4gICAgdGltZVpvbmVQYXJhbTogU3RyaW5nLFxuICAgIHRpbWVab25lOiBTdHJpbmcsXG4gICAgbG9jYWxlczogaWRlbnRpdHksXG4gICAgbG9jYWxlOiBpZGVudGl0eSxcbiAgICB0aGVtZVN5c3RlbTogU3RyaW5nLFxuICAgIGRyYWdSZXZlcnREdXJhdGlvbjogTnVtYmVyLFxuICAgIGRyYWdTY3JvbGw6IEJvb2xlYW4sXG4gICAgYWxsRGF5TWFpbnRhaW5EdXJhdGlvbjogQm9vbGVhbixcbiAgICB1bnNlbGVjdEF1dG86IEJvb2xlYW4sXG4gICAgZHJvcEFjY2VwdDogaWRlbnRpdHksXG4gICAgZXZlbnRPcmRlcjogcGFyc2VGaWVsZFNwZWNzLFxuICAgIGV2ZW50T3JkZXJTdHJpY3Q6IEJvb2xlYW4sXG4gICAgaGFuZGxlV2luZG93UmVzaXplOiBCb29sZWFuLFxuICAgIHdpbmRvd1Jlc2l6ZURlbGF5OiBOdW1iZXIsXG4gICAgbG9uZ1ByZXNzRGVsYXk6IE51bWJlcixcbiAgICBldmVudERyYWdNaW5EaXN0YW5jZTogTnVtYmVyLFxuICAgIGV4cGFuZFJvd3M6IEJvb2xlYW4sXG4gICAgaGVpZ2h0OiBpZGVudGl0eSxcbiAgICBjb250ZW50SGVpZ2h0OiBpZGVudGl0eSxcbiAgICBkaXJlY3Rpb246IFN0cmluZyxcbiAgICB3ZWVrTnVtYmVyRm9ybWF0OiBjcmVhdGVGb3JtYXR0ZXIsXG4gICAgZXZlbnRSZXNpemFibGVGcm9tU3RhcnQ6IEJvb2xlYW4sXG4gICAgZGlzcGxheUV2ZW50VGltZTogQm9vbGVhbixcbiAgICBkaXNwbGF5RXZlbnRFbmQ6IEJvb2xlYW4sXG4gICAgd2Vla1RleHQ6IFN0cmluZyxcbiAgICB3ZWVrVGV4dExvbmc6IFN0cmluZyxcbiAgICBwcm9ncmVzc2l2ZUV2ZW50UmVuZGVyaW5nOiBCb29sZWFuLFxuICAgIGJ1c2luZXNzSG91cnM6IGlkZW50aXR5LFxuICAgIGluaXRpYWxEYXRlOiBpZGVudGl0eSxcbiAgICBub3c6IGlkZW50aXR5LFxuICAgIGV2ZW50RGF0YVRyYW5zZm9ybTogaWRlbnRpdHksXG4gICAgc3RpY2t5SGVhZGVyRGF0ZXM6IGlkZW50aXR5LFxuICAgIHN0aWNreUZvb3RlclNjcm9sbGJhcjogaWRlbnRpdHksXG4gICAgdmlld0hlaWdodDogaWRlbnRpdHksXG4gICAgZGVmYXVsdEFsbERheTogQm9vbGVhbixcbiAgICBldmVudFNvdXJjZUZhaWx1cmU6IGlkZW50aXR5LFxuICAgIGV2ZW50U291cmNlU3VjY2VzczogaWRlbnRpdHksXG4gICAgZXZlbnREaXNwbGF5OiBTdHJpbmcsXG4gICAgZXZlbnRTdGFydEVkaXRhYmxlOiBCb29sZWFuLFxuICAgIGV2ZW50RHVyYXRpb25FZGl0YWJsZTogQm9vbGVhbixcbiAgICBldmVudE92ZXJsYXA6IGlkZW50aXR5LFxuICAgIGV2ZW50Q29uc3RyYWludDogaWRlbnRpdHksXG4gICAgZXZlbnRBbGxvdzogaWRlbnRpdHksXG4gICAgZXZlbnRCYWNrZ3JvdW5kQ29sb3I6IFN0cmluZyxcbiAgICBldmVudEJvcmRlckNvbG9yOiBTdHJpbmcsXG4gICAgZXZlbnRUZXh0Q29sb3I6IFN0cmluZyxcbiAgICBldmVudENvbG9yOiBTdHJpbmcsXG4gICAgZXZlbnRDbGFzc05hbWVzOiBpZGVudGl0eSxcbiAgICBldmVudENvbnRlbnQ6IGlkZW50aXR5LFxuICAgIGV2ZW50RGlkTW91bnQ6IGlkZW50aXR5LFxuICAgIGV2ZW50V2lsbFVubW91bnQ6IGlkZW50aXR5LFxuICAgIHNlbGVjdENvbnN0cmFpbnQ6IGlkZW50aXR5LFxuICAgIHNlbGVjdE92ZXJsYXA6IGlkZW50aXR5LFxuICAgIHNlbGVjdEFsbG93OiBpZGVudGl0eSxcbiAgICBkcm9wcGFibGU6IEJvb2xlYW4sXG4gICAgdW5zZWxlY3RDYW5jZWw6IFN0cmluZyxcbiAgICBzbG90TGFiZWxGb3JtYXQ6IGlkZW50aXR5LFxuICAgIHNsb3RMYW5lQ2xhc3NOYW1lczogaWRlbnRpdHksXG4gICAgc2xvdExhbmVDb250ZW50OiBpZGVudGl0eSxcbiAgICBzbG90TGFuZURpZE1vdW50OiBpZGVudGl0eSxcbiAgICBzbG90TGFuZVdpbGxVbm1vdW50OiBpZGVudGl0eSxcbiAgICBzbG90TGFiZWxDbGFzc05hbWVzOiBpZGVudGl0eSxcbiAgICBzbG90TGFiZWxDb250ZW50OiBpZGVudGl0eSxcbiAgICBzbG90TGFiZWxEaWRNb3VudDogaWRlbnRpdHksXG4gICAgc2xvdExhYmVsV2lsbFVubW91bnQ6IGlkZW50aXR5LFxuICAgIGRheU1heEV2ZW50czogaWRlbnRpdHksXG4gICAgZGF5TWF4RXZlbnRSb3dzOiBpZGVudGl0eSxcbiAgICBkYXlNaW5XaWR0aDogTnVtYmVyLFxuICAgIHNsb3RMYWJlbEludGVydmFsOiBjcmVhdGVEdXJhdGlvbixcbiAgICBhbGxEYXlUZXh0OiBTdHJpbmcsXG4gICAgYWxsRGF5Q2xhc3NOYW1lczogaWRlbnRpdHksXG4gICAgYWxsRGF5Q29udGVudDogaWRlbnRpdHksXG4gICAgYWxsRGF5RGlkTW91bnQ6IGlkZW50aXR5LFxuICAgIGFsbERheVdpbGxVbm1vdW50OiBpZGVudGl0eSxcbiAgICBzbG90TWluV2lkdGg6IE51bWJlcixcbiAgICBuYXZMaW5rczogQm9vbGVhbixcbiAgICBldmVudFRpbWVGb3JtYXQ6IGNyZWF0ZUZvcm1hdHRlcixcbiAgICByZXJlbmRlckRlbGF5OiBOdW1iZXIsXG4gICAgbW9yZUxpbmtUZXh0OiBpZGVudGl0eSxcbiAgICBtb3JlTGlua0hpbnQ6IGlkZW50aXR5LFxuICAgIHNlbGVjdE1pbkRpc3RhbmNlOiBOdW1iZXIsXG4gICAgc2VsZWN0YWJsZTogQm9vbGVhbixcbiAgICBzZWxlY3RMb25nUHJlc3NEZWxheTogTnVtYmVyLFxuICAgIGV2ZW50TG9uZ1ByZXNzRGVsYXk6IE51bWJlcixcbiAgICBzZWxlY3RNaXJyb3I6IEJvb2xlYW4sXG4gICAgZXZlbnRNYXhTdGFjazogTnVtYmVyLFxuICAgIGV2ZW50TWluSGVpZ2h0OiBOdW1iZXIsXG4gICAgZXZlbnRNaW5XaWR0aDogTnVtYmVyLFxuICAgIGV2ZW50U2hvcnRIZWlnaHQ6IE51bWJlcixcbiAgICBzbG90RXZlbnRPdmVybGFwOiBCb29sZWFuLFxuICAgIHBsdWdpbnM6IGlkZW50aXR5LFxuICAgIGZpcnN0RGF5OiBOdW1iZXIsXG4gICAgZGF5Q291bnQ6IE51bWJlcixcbiAgICBkYXRlQWxpZ25tZW50OiBTdHJpbmcsXG4gICAgZGF0ZUluY3JlbWVudDogY3JlYXRlRHVyYXRpb24sXG4gICAgaGlkZGVuRGF5czogaWRlbnRpdHksXG4gICAgbW9udGhNb2RlOiBCb29sZWFuLFxuICAgIGZpeGVkV2Vla0NvdW50OiBCb29sZWFuLFxuICAgIHZhbGlkUmFuZ2U6IGlkZW50aXR5LFxuICAgIHZpc2libGVSYW5nZTogaWRlbnRpdHksXG4gICAgdGl0bGVGb3JtYXQ6IGlkZW50aXR5LFxuICAgIGV2ZW50SW50ZXJhY3RpdmU6IEJvb2xlYW4sXG4gICAgLy8gb25seSB1c2VkIGJ5IGxpc3QtdmlldywgYnV0IGxhbmd1YWdlcyBkZWZpbmUgdGhlIHZhbHVlLCBzbyB3ZSBuZWVkIGl0IGluIGJhc2Ugb3B0aW9uc1xuICAgIG5vRXZlbnRzVGV4dDogU3RyaW5nLFxuICAgIHZpZXdIaW50OiBpZGVudGl0eSxcbiAgICBuYXZMaW5rSGludDogaWRlbnRpdHksXG4gICAgY2xvc2VIaW50OiBTdHJpbmcsXG4gICAgdGltZUhpbnQ6IFN0cmluZyxcbiAgICBldmVudEhpbnQ6IFN0cmluZyxcbiAgICBtb3JlTGlua0NsaWNrOiBpZGVudGl0eSxcbiAgICBtb3JlTGlua0NsYXNzTmFtZXM6IGlkZW50aXR5LFxuICAgIG1vcmVMaW5rQ29udGVudDogaWRlbnRpdHksXG4gICAgbW9yZUxpbmtEaWRNb3VudDogaWRlbnRpdHksXG4gICAgbW9yZUxpbmtXaWxsVW5tb3VudDogaWRlbnRpdHksXG4gICAgLy8gZm9yIGNvbm5lY3RvcnNcbiAgICAvLyAoY2FuJ3QgYmUgcGFydCBvZiBwbHVnaW4gc3lzdGVtIGIvYyBtdXN0IGJlIHByb3ZpZGVkIGF0IHJ1bnRpbWUpXG4gICAgaGFuZGxlQ3VzdG9tUmVuZGVyaW5nOiBpZGVudGl0eSxcbiAgICBjdXN0b21SZW5kZXJpbmdNZXRhTWFwOiBpZGVudGl0eSxcbiAgICBjdXN0b21SZW5kZXJpbmdSZXBsYWNlc0VsOiBCb29sZWFuLFxufTtcbi8vIGRvIE5PVCBnaXZlIGEgdHlwZSBoZXJlLiBuZWVkIGB0eXBlb2YgQkFTRV9PUFRJT05fREVGQVVMVFNgIHRvIGdpdmUgcmVhbCByZXN1bHRzLlxuLy8gcmF3IHZhbHVlcy5cbmNvbnN0IEJBU0VfT1BUSU9OX0RFRkFVTFRTID0ge1xuICAgIGV2ZW50RGlzcGxheTogJ2F1dG8nLFxuICAgIGRlZmF1bHRSYW5nZVNlcGFyYXRvcjogJyAtICcsXG4gICAgdGl0bGVSYW5nZVNlcGFyYXRvcjogJyBcXHUyMDEzICcsXG4gICAgZGVmYXVsdFRpbWVkRXZlbnREdXJhdGlvbjogJzAxOjAwOjAwJyxcbiAgICBkZWZhdWx0QWxsRGF5RXZlbnREdXJhdGlvbjogeyBkYXk6IDEgfSxcbiAgICBmb3JjZUV2ZW50RHVyYXRpb246IGZhbHNlLFxuICAgIG5leHREYXlUaHJlc2hvbGQ6ICcwMDowMDowMCcsXG4gICAgZGF5SGVhZGVyczogdHJ1ZSxcbiAgICBpbml0aWFsVmlldzogJycsXG4gICAgYXNwZWN0UmF0aW86IDEuMzUsXG4gICAgaGVhZGVyVG9vbGJhcjoge1xuICAgICAgICBzdGFydDogJ3RpdGxlJyxcbiAgICAgICAgY2VudGVyOiAnJyxcbiAgICAgICAgZW5kOiAndG9kYXkgcHJldixuZXh0JyxcbiAgICB9LFxuICAgIHdlZWtlbmRzOiB0cnVlLFxuICAgIHdlZWtOdW1iZXJzOiBmYWxzZSxcbiAgICB3ZWVrTnVtYmVyQ2FsY3VsYXRpb246ICdsb2NhbCcsXG4gICAgZWRpdGFibGU6IGZhbHNlLFxuICAgIG5vd0luZGljYXRvcjogZmFsc2UsXG4gICAgc2Nyb2xsVGltZTogJzA2OjAwOjAwJyxcbiAgICBzY3JvbGxUaW1lUmVzZXQ6IHRydWUsXG4gICAgc2xvdE1pblRpbWU6ICcwMDowMDowMCcsXG4gICAgc2xvdE1heFRpbWU6ICcyNDowMDowMCcsXG4gICAgc2hvd05vbkN1cnJlbnREYXRlczogdHJ1ZSxcbiAgICBsYXp5RmV0Y2hpbmc6IHRydWUsXG4gICAgc3RhcnRQYXJhbTogJ3N0YXJ0JyxcbiAgICBlbmRQYXJhbTogJ2VuZCcsXG4gICAgdGltZVpvbmVQYXJhbTogJ3RpbWVab25lJyxcbiAgICB0aW1lWm9uZTogJ2xvY2FsJyxcbiAgICBsb2NhbGVzOiBbXSxcbiAgICBsb2NhbGU6ICcnLFxuICAgIHRoZW1lU3lzdGVtOiAnc3RhbmRhcmQnLFxuICAgIGRyYWdSZXZlcnREdXJhdGlvbjogNTAwLFxuICAgIGRyYWdTY3JvbGw6IHRydWUsXG4gICAgYWxsRGF5TWFpbnRhaW5EdXJhdGlvbjogZmFsc2UsXG4gICAgdW5zZWxlY3RBdXRvOiB0cnVlLFxuICAgIGRyb3BBY2NlcHQ6ICcqJyxcbiAgICBldmVudE9yZGVyOiAnc3RhcnQsLWR1cmF0aW9uLGFsbERheSx0aXRsZScsXG4gICAgZGF5UG9wb3ZlckZvcm1hdDogeyBtb250aDogJ2xvbmcnLCBkYXk6ICdudW1lcmljJywgeWVhcjogJ251bWVyaWMnIH0sXG4gICAgaGFuZGxlV2luZG93UmVzaXplOiB0cnVlLFxuICAgIHdpbmRvd1Jlc2l6ZURlbGF5OiAxMDAsXG4gICAgbG9uZ1ByZXNzRGVsYXk6IDEwMDAsXG4gICAgZXZlbnREcmFnTWluRGlzdGFuY2U6IDUsXG4gICAgZXhwYW5kUm93czogZmFsc2UsXG4gICAgbmF2TGlua3M6IGZhbHNlLFxuICAgIHNlbGVjdGFibGU6IGZhbHNlLFxuICAgIGV2ZW50TWluSGVpZ2h0OiAxNSxcbiAgICBldmVudE1pbldpZHRoOiAzMCxcbiAgICBldmVudFNob3J0SGVpZ2h0OiAzMCxcbn07XG4vLyBjYWxlbmRhciBsaXN0ZW5lcnNcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLVxuY29uc3QgQ0FMRU5EQVJfTElTVEVORVJfUkVGSU5FUlMgPSB7XG4gICAgZGF0ZXNTZXQ6IGlkZW50aXR5LFxuICAgIGV2ZW50c1NldDogaWRlbnRpdHksXG4gICAgZXZlbnRBZGQ6IGlkZW50aXR5LFxuICAgIGV2ZW50Q2hhbmdlOiBpZGVudGl0eSxcbiAgICBldmVudFJlbW92ZTogaWRlbnRpdHksXG4gICAgd2luZG93UmVzaXplOiBpZGVudGl0eSxcbiAgICBldmVudENsaWNrOiBpZGVudGl0eSxcbiAgICBldmVudE1vdXNlRW50ZXI6IGlkZW50aXR5LFxuICAgIGV2ZW50TW91c2VMZWF2ZTogaWRlbnRpdHksXG4gICAgc2VsZWN0OiBpZGVudGl0eSxcbiAgICB1bnNlbGVjdDogaWRlbnRpdHksXG4gICAgbG9hZGluZzogaWRlbnRpdHksXG4gICAgLy8gaW50ZXJuYWxcbiAgICBfdW5tb3VudDogaWRlbnRpdHksXG4gICAgX2JlZm9yZXByaW50OiBpZGVudGl0eSxcbiAgICBfYWZ0ZXJwcmludDogaWRlbnRpdHksXG4gICAgX25vRXZlbnREcm9wOiBpZGVudGl0eSxcbiAgICBfbm9FdmVudFJlc2l6ZTogaWRlbnRpdHksXG4gICAgX3Jlc2l6ZTogaWRlbnRpdHksXG4gICAgX3Njcm9sbFJlcXVlc3Q6IGlkZW50aXR5LFxufTtcbi8vIGNhbGVuZGFyLXNwZWNpZmljIG9wdGlvbnNcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbmNvbnN0IENBTEVOREFSX09QVElPTl9SRUZJTkVSUyA9IHtcbiAgICBidXR0b25UZXh0OiBpZGVudGl0eSxcbiAgICBidXR0b25IaW50czogaWRlbnRpdHksXG4gICAgdmlld3M6IGlkZW50aXR5LFxuICAgIHBsdWdpbnM6IGlkZW50aXR5LFxuICAgIGluaXRpYWxFdmVudHM6IGlkZW50aXR5LFxuICAgIGV2ZW50czogaWRlbnRpdHksXG4gICAgZXZlbnRTb3VyY2VzOiBpZGVudGl0eSxcbn07XG5jb25zdCBDT01QTEVYX09QVElPTl9DT01QQVJBVE9SUyA9IHtcbiAgICBoZWFkZXJUb29sYmFyOiBpc01heWJlT2JqZWN0c0VxdWFsLFxuICAgIGZvb3RlclRvb2xiYXI6IGlzTWF5YmVPYmplY3RzRXF1YWwsXG4gICAgYnV0dG9uVGV4dDogaXNNYXliZU9iamVjdHNFcXVhbCxcbiAgICBidXR0b25IaW50czogaXNNYXliZU9iamVjdHNFcXVhbCxcbiAgICBidXR0b25JY29uczogaXNNYXliZU9iamVjdHNFcXVhbCxcbiAgICBkYXRlSW5jcmVtZW50OiBpc01heWJlT2JqZWN0c0VxdWFsLFxufTtcbmZ1bmN0aW9uIGlzTWF5YmVPYmplY3RzRXF1YWwoYSwgYikge1xuICAgIGlmICh0eXBlb2YgYSA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIGIgPT09ICdvYmplY3QnICYmIGEgJiYgYikgeyAvLyBib3RoIG5vbi1udWxsIG9iamVjdHNcbiAgICAgICAgcmV0dXJuIGlzUHJvcHNFcXVhbChhLCBiKTtcbiAgICB9XG4gICAgcmV0dXJuIGEgPT09IGI7XG59XG4vLyB2aWV3LXNwZWNpZmljIG9wdGlvbnNcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuY29uc3QgVklFV19PUFRJT05fUkVGSU5FUlMgPSB7XG4gICAgdHlwZTogU3RyaW5nLFxuICAgIGNvbXBvbmVudDogaWRlbnRpdHksXG4gICAgYnV0dG9uVGV4dDogU3RyaW5nLFxuICAgIGJ1dHRvblRleHRLZXk6IFN0cmluZyxcbiAgICBkYXRlUHJvZmlsZUdlbmVyYXRvckNsYXNzOiBpZGVudGl0eSxcbiAgICB1c2VzTWluTWF4VGltZTogQm9vbGVhbixcbiAgICBjbGFzc05hbWVzOiBpZGVudGl0eSxcbiAgICBjb250ZW50OiBpZGVudGl0eSxcbiAgICBkaWRNb3VudDogaWRlbnRpdHksXG4gICAgd2lsbFVubW91bnQ6IGlkZW50aXR5LFxufTtcbi8vIHV0aWwgZnVuY3Ncbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbmZ1bmN0aW9uIG1lcmdlUmF3T3B0aW9ucyhvcHRpb25TZXRzKSB7XG4gICAgcmV0dXJuIG1lcmdlUHJvcHMob3B0aW9uU2V0cywgQ09NUExFWF9PUFRJT05fQ09NUEFSQVRPUlMpO1xufVxuZnVuY3Rpb24gcmVmaW5lUHJvcHMoaW5wdXQsIHJlZmluZXJzKSB7XG4gICAgbGV0IHJlZmluZWQgPSB7fTtcbiAgICBsZXQgZXh0cmEgPSB7fTtcbiAgICBmb3IgKGxldCBwcm9wTmFtZSBpbiByZWZpbmVycykge1xuICAgICAgICBpZiAocHJvcE5hbWUgaW4gaW5wdXQpIHtcbiAgICAgICAgICAgIHJlZmluZWRbcHJvcE5hbWVdID0gcmVmaW5lcnNbcHJvcE5hbWVdKGlucHV0W3Byb3BOYW1lXSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZm9yIChsZXQgcHJvcE5hbWUgaW4gaW5wdXQpIHtcbiAgICAgICAgaWYgKCEocHJvcE5hbWUgaW4gcmVmaW5lcnMpKSB7XG4gICAgICAgICAgICBleHRyYVtwcm9wTmFtZV0gPSBpbnB1dFtwcm9wTmFtZV07XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHsgcmVmaW5lZCwgZXh0cmEgfTtcbn1cbmZ1bmN0aW9uIGlkZW50aXR5KHJhdykge1xuICAgIHJldHVybiByYXc7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUV2ZW50SW5zdGFuY2UoZGVmSWQsIHJhbmdlLCBmb3JjZWRTdGFydFR6bywgZm9yY2VkRW5kVHpvKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgaW5zdGFuY2VJZDogZ3VpZCgpLFxuICAgICAgICBkZWZJZCxcbiAgICAgICAgcmFuZ2UsXG4gICAgICAgIGZvcmNlZFN0YXJ0VHpvOiBmb3JjZWRTdGFydFR6byA9PSBudWxsID8gbnVsbCA6IGZvcmNlZFN0YXJ0VHpvLFxuICAgICAgICBmb3JjZWRFbmRUem86IGZvcmNlZEVuZFR6byA9PSBudWxsID8gbnVsbCA6IGZvcmNlZEVuZFR6byxcbiAgICB9O1xufVxuXG5mdW5jdGlvbiBwYXJzZVJlY3VycmluZyhyZWZpbmVkLCBkZWZhdWx0QWxsRGF5LCBkYXRlRW52LCByZWN1cnJpbmdUeXBlcykge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmVjdXJyaW5nVHlwZXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgbGV0IHBhcnNlZCA9IHJlY3VycmluZ1R5cGVzW2ldLnBhcnNlKHJlZmluZWQsIGRhdGVFbnYpO1xuICAgICAgICBpZiAocGFyc2VkKSB7XG4gICAgICAgICAgICBsZXQgeyBhbGxEYXkgfSA9IHJlZmluZWQ7XG4gICAgICAgICAgICBpZiAoYWxsRGF5ID09IG51bGwpIHtcbiAgICAgICAgICAgICAgICBhbGxEYXkgPSBkZWZhdWx0QWxsRGF5O1xuICAgICAgICAgICAgICAgIGlmIChhbGxEYXkgPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICBhbGxEYXkgPSBwYXJzZWQuYWxsRGF5R3Vlc3M7XG4gICAgICAgICAgICAgICAgICAgIGlmIChhbGxEYXkgPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYWxsRGF5ID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGFsbERheSxcbiAgICAgICAgICAgICAgICBkdXJhdGlvbjogcGFyc2VkLmR1cmF0aW9uLFxuICAgICAgICAgICAgICAgIHR5cGVEYXRhOiBwYXJzZWQudHlwZURhdGEsXG4gICAgICAgICAgICAgICAgdHlwZUlkOiBpLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbn1cbmZ1bmN0aW9uIGV4cGFuZFJlY3VycmluZyhldmVudFN0b3JlLCBmcmFtaW5nUmFuZ2UsIGNvbnRleHQpIHtcbiAgICBsZXQgeyBkYXRlRW52LCBwbHVnaW5Ib29rcywgb3B0aW9ucyB9ID0gY29udGV4dDtcbiAgICBsZXQgeyBkZWZzLCBpbnN0YW5jZXMgfSA9IGV2ZW50U3RvcmU7XG4gICAgLy8gcmVtb3ZlIGV4aXN0aW5nIHJlY3VycmluZyBpbnN0YW5jZXNcbiAgICAvLyBUT0RPOiBiYWQuIGFsd2F5cyBleHBhbmQgZXZlbnRzIGFzIGEgc2Vjb25kIHN0ZXBcbiAgICBpbnN0YW5jZXMgPSBmaWx0ZXJIYXNoKGluc3RhbmNlcywgKGluc3RhbmNlKSA9PiAhZGVmc1tpbnN0YW5jZS5kZWZJZF0ucmVjdXJyaW5nRGVmKTtcbiAgICBmb3IgKGxldCBkZWZJZCBpbiBkZWZzKSB7XG4gICAgICAgIGxldCBkZWYgPSBkZWZzW2RlZklkXTtcbiAgICAgICAgaWYgKGRlZi5yZWN1cnJpbmdEZWYpIHtcbiAgICAgICAgICAgIGxldCB7IGR1cmF0aW9uIH0gPSBkZWYucmVjdXJyaW5nRGVmO1xuICAgICAgICAgICAgaWYgKCFkdXJhdGlvbikge1xuICAgICAgICAgICAgICAgIGR1cmF0aW9uID0gZGVmLmFsbERheSA/XG4gICAgICAgICAgICAgICAgICAgIG9wdGlvbnMuZGVmYXVsdEFsbERheUV2ZW50RHVyYXRpb24gOlxuICAgICAgICAgICAgICAgICAgICBvcHRpb25zLmRlZmF1bHRUaW1lZEV2ZW50RHVyYXRpb247XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsZXQgc3RhcnRzID0gZXhwYW5kUmVjdXJyaW5nUmFuZ2VzKGRlZiwgZHVyYXRpb24sIGZyYW1pbmdSYW5nZSwgZGF0ZUVudiwgcGx1Z2luSG9va3MucmVjdXJyaW5nVHlwZXMpO1xuICAgICAgICAgICAgZm9yIChsZXQgc3RhcnQgb2Ygc3RhcnRzKSB7XG4gICAgICAgICAgICAgICAgbGV0IGluc3RhbmNlID0gY3JlYXRlRXZlbnRJbnN0YW5jZShkZWZJZCwge1xuICAgICAgICAgICAgICAgICAgICBzdGFydCxcbiAgICAgICAgICAgICAgICAgICAgZW5kOiBkYXRlRW52LmFkZChzdGFydCwgZHVyYXRpb24pLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGluc3RhbmNlc1tpbnN0YW5jZS5pbnN0YW5jZUlkXSA9IGluc3RhbmNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB7IGRlZnMsIGluc3RhbmNlcyB9O1xufVxuLypcbkV2ZW50IE1VU1QgaGF2ZSBhIHJlY3VycmluZ0RlZlxuKi9cbmZ1bmN0aW9uIGV4cGFuZFJlY3VycmluZ1JhbmdlcyhldmVudERlZiwgZHVyYXRpb24sIGZyYW1pbmdSYW5nZSwgZGF0ZUVudiwgcmVjdXJyaW5nVHlwZXMpIHtcbiAgICBsZXQgdHlwZURlZiA9IHJlY3VycmluZ1R5cGVzW2V2ZW50RGVmLnJlY3VycmluZ0RlZi50eXBlSWRdO1xuICAgIGxldCBtYXJrZXJzID0gdHlwZURlZi5leHBhbmQoZXZlbnREZWYucmVjdXJyaW5nRGVmLnR5cGVEYXRhLCB7XG4gICAgICAgIHN0YXJ0OiBkYXRlRW52LnN1YnRyYWN0KGZyYW1pbmdSYW5nZS5zdGFydCwgZHVyYXRpb24pLFxuICAgICAgICBlbmQ6IGZyYW1pbmdSYW5nZS5lbmQsXG4gICAgfSwgZGF0ZUVudik7XG4gICAgLy8gdGhlIHJlY3VycmVuY2UgcGx1Z2lucyBkb24ndCBndWFyYW50ZWUgdGhhdCBhbGwtZGF5IGV2ZW50cyBhcmUgc3RhcnQtb2YtZGF5LCBzbyB3ZSBoYXZlIHRvXG4gICAgaWYgKGV2ZW50RGVmLmFsbERheSkge1xuICAgICAgICBtYXJrZXJzID0gbWFya2Vycy5tYXAoc3RhcnRPZkRheSk7XG4gICAgfVxuICAgIHJldHVybiBtYXJrZXJzO1xufVxuXG5mdW5jdGlvbiBwYXJzZUV2ZW50cyhyYXdFdmVudHMsIGV2ZW50U291cmNlLCBjb250ZXh0LCBhbGxvd09wZW5SYW5nZSkge1xuICAgIGxldCBldmVudFN0b3JlID0gY3JlYXRlRW1wdHlFdmVudFN0b3JlKCk7XG4gICAgbGV0IGV2ZW50UmVmaW5lcnMgPSBidWlsZEV2ZW50UmVmaW5lcnMoY29udGV4dCk7XG4gICAgZm9yIChsZXQgcmF3RXZlbnQgb2YgcmF3RXZlbnRzKSB7XG4gICAgICAgIGxldCB0dXBsZSA9IHBhcnNlRXZlbnQocmF3RXZlbnQsIGV2ZW50U291cmNlLCBjb250ZXh0LCBhbGxvd09wZW5SYW5nZSwgZXZlbnRSZWZpbmVycyk7XG4gICAgICAgIGlmICh0dXBsZSkge1xuICAgICAgICAgICAgZXZlbnRUdXBsZVRvU3RvcmUodHVwbGUsIGV2ZW50U3RvcmUpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBldmVudFN0b3JlO1xufVxuZnVuY3Rpb24gZXZlbnRUdXBsZVRvU3RvcmUodHVwbGUsIGV2ZW50U3RvcmUgPSBjcmVhdGVFbXB0eUV2ZW50U3RvcmUoKSkge1xuICAgIGV2ZW50U3RvcmUuZGVmc1t0dXBsZS5kZWYuZGVmSWRdID0gdHVwbGUuZGVmO1xuICAgIGlmICh0dXBsZS5pbnN0YW5jZSkge1xuICAgICAgICBldmVudFN0b3JlLmluc3RhbmNlc1t0dXBsZS5pbnN0YW5jZS5pbnN0YW5jZUlkXSA9IHR1cGxlLmluc3RhbmNlO1xuICAgIH1cbiAgICByZXR1cm4gZXZlbnRTdG9yZTtcbn1cbi8vIHJldHJpZXZlcyBldmVudHMgdGhhdCBoYXZlIHRoZSBzYW1lIGdyb3VwSWQgYXMgdGhlIGluc3RhbmNlIHNwZWNpZmllZCBieSBgaW5zdGFuY2VJZGBcbi8vIG9yIHRoZXkgYXJlIHRoZSBzYW1lIGFzIHRoZSBpbnN0YW5jZS5cbi8vIHdoeSBtaWdodCBpbnN0YW5jZUlkIG5vdCBiZSBpbiB0aGUgc3RvcmU/IGFuIGV2ZW50IGZyb20gYW5vdGhlciBjYWxlbmRhcj9cbmZ1bmN0aW9uIGdldFJlbGV2YW50RXZlbnRzKGV2ZW50U3RvcmUsIGluc3RhbmNlSWQpIHtcbiAgICBsZXQgaW5zdGFuY2UgPSBldmVudFN0b3JlLmluc3RhbmNlc1tpbnN0YW5jZUlkXTtcbiAgICBpZiAoaW5zdGFuY2UpIHtcbiAgICAgICAgbGV0IGRlZiA9IGV2ZW50U3RvcmUuZGVmc1tpbnN0YW5jZS5kZWZJZF07XG4gICAgICAgIC8vIGdldCBldmVudHMvaW5zdGFuY2VzIHdpdGggc2FtZSBncm91cFxuICAgICAgICBsZXQgbmV3U3RvcmUgPSBmaWx0ZXJFdmVudFN0b3JlRGVmcyhldmVudFN0b3JlLCAobG9va0RlZikgPT4gaXNFdmVudERlZnNHcm91cGVkKGRlZiwgbG9va0RlZikpO1xuICAgICAgICAvLyBhZGQgdGhlIG9yaWdpbmFsXG4gICAgICAgIC8vIFRPRE86IHdpc2ggd2UgY291bGQgdXNlIGV2ZW50VHVwbGVUb1N0b3JlIG9yIHNvbWV0aGluZyBsaWtlIGl0XG4gICAgICAgIG5ld1N0b3JlLmRlZnNbZGVmLmRlZklkXSA9IGRlZjtcbiAgICAgICAgbmV3U3RvcmUuaW5zdGFuY2VzW2luc3RhbmNlLmluc3RhbmNlSWRdID0gaW5zdGFuY2U7XG4gICAgICAgIHJldHVybiBuZXdTdG9yZTtcbiAgICB9XG4gICAgcmV0dXJuIGNyZWF0ZUVtcHR5RXZlbnRTdG9yZSgpO1xufVxuZnVuY3Rpb24gaXNFdmVudERlZnNHcm91cGVkKGRlZjAsIGRlZjEpIHtcbiAgICByZXR1cm4gQm9vbGVhbihkZWYwLmdyb3VwSWQgJiYgZGVmMC5ncm91cElkID09PSBkZWYxLmdyb3VwSWQpO1xufVxuZnVuY3Rpb24gY3JlYXRlRW1wdHlFdmVudFN0b3JlKCkge1xuICAgIHJldHVybiB7IGRlZnM6IHt9LCBpbnN0YW5jZXM6IHt9IH07XG59XG5mdW5jdGlvbiBtZXJnZUV2ZW50U3RvcmVzKHN0b3JlMCwgc3RvcmUxKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgZGVmczogT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCBzdG9yZTAuZGVmcyksIHN0b3JlMS5kZWZzKSxcbiAgICAgICAgaW5zdGFuY2VzOiBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sIHN0b3JlMC5pbnN0YW5jZXMpLCBzdG9yZTEuaW5zdGFuY2VzKSxcbiAgICB9O1xufVxuZnVuY3Rpb24gZmlsdGVyRXZlbnRTdG9yZURlZnMoZXZlbnRTdG9yZSwgZmlsdGVyRnVuYykge1xuICAgIGxldCBkZWZzID0gZmlsdGVySGFzaChldmVudFN0b3JlLmRlZnMsIGZpbHRlckZ1bmMpO1xuICAgIGxldCBpbnN0YW5jZXMgPSBmaWx0ZXJIYXNoKGV2ZW50U3RvcmUuaW5zdGFuY2VzLCAoaW5zdGFuY2UpID0+IChkZWZzW2luc3RhbmNlLmRlZklkXSAvLyBzdGlsbCBleGlzdHM/XG4gICAgKSk7XG4gICAgcmV0dXJuIHsgZGVmcywgaW5zdGFuY2VzIH07XG59XG5mdW5jdGlvbiBleGNsdWRlU3ViRXZlbnRTdG9yZShtYXN0ZXIsIHN1Yikge1xuICAgIGxldCB7IGRlZnMsIGluc3RhbmNlcyB9ID0gbWFzdGVyO1xuICAgIGxldCBmaWx0ZXJlZERlZnMgPSB7fTtcbiAgICBsZXQgZmlsdGVyZWRJbnN0YW5jZXMgPSB7fTtcbiAgICBmb3IgKGxldCBkZWZJZCBpbiBkZWZzKSB7XG4gICAgICAgIGlmICghc3ViLmRlZnNbZGVmSWRdKSB7IC8vIG5vdCBleHBsaWNpdGx5IGV4Y2x1ZGVkXG4gICAgICAgICAgICBmaWx0ZXJlZERlZnNbZGVmSWRdID0gZGVmc1tkZWZJZF07XG4gICAgICAgIH1cbiAgICB9XG4gICAgZm9yIChsZXQgaW5zdGFuY2VJZCBpbiBpbnN0YW5jZXMpIHtcbiAgICAgICAgaWYgKCFzdWIuaW5zdGFuY2VzW2luc3RhbmNlSWRdICYmIC8vIG5vdCBleHBsaWNpdGx5IGV4Y2x1ZGVkXG4gICAgICAgICAgICBmaWx0ZXJlZERlZnNbaW5zdGFuY2VzW2luc3RhbmNlSWRdLmRlZklkXSAvLyBkZWYgd2Fzbid0IGZpbHRlcmVkIGF3YXlcbiAgICAgICAgKSB7XG4gICAgICAgICAgICBmaWx0ZXJlZEluc3RhbmNlc1tpbnN0YW5jZUlkXSA9IGluc3RhbmNlc1tpbnN0YW5jZUlkXTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICBkZWZzOiBmaWx0ZXJlZERlZnMsXG4gICAgICAgIGluc3RhbmNlczogZmlsdGVyZWRJbnN0YW5jZXMsXG4gICAgfTtcbn1cblxuZnVuY3Rpb24gbm9ybWFsaXplQ29uc3RyYWludChpbnB1dCwgY29udGV4dCkge1xuICAgIGlmIChBcnJheS5pc0FycmF5KGlucHV0KSkge1xuICAgICAgICByZXR1cm4gcGFyc2VFdmVudHMoaW5wdXQsIG51bGwsIGNvbnRleHQsIHRydWUpOyAvLyBhbGxvd09wZW5SYW5nZT10cnVlXG4gICAgfVxuICAgIGlmICh0eXBlb2YgaW5wdXQgPT09ICdvYmplY3QnICYmIGlucHV0KSB7IC8vIG5vbi1udWxsIG9iamVjdFxuICAgICAgICByZXR1cm4gcGFyc2VFdmVudHMoW2lucHV0XSwgbnVsbCwgY29udGV4dCwgdHJ1ZSk7IC8vIGFsbG93T3BlblJhbmdlPXRydWVcbiAgICB9XG4gICAgaWYgKGlucHV0ICE9IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIFN0cmluZyhpbnB1dCk7XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xufVxuXG5mdW5jdGlvbiBwYXJzZUNsYXNzTmFtZXMocmF3KSB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkocmF3KSkge1xuICAgICAgICByZXR1cm4gcmF3O1xuICAgIH1cbiAgICBpZiAodHlwZW9mIHJhdyA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgcmV0dXJuIHJhdy5zcGxpdCgvXFxzKy8pO1xuICAgIH1cbiAgICByZXR1cm4gW107XG59XG5cbi8vIFRPRE86IGJldHRlciBjYWxsZWQgXCJFdmVudFNldHRpbmdzXCIgb3IgXCJFdmVudENvbmZpZ1wiXG4vLyBUT0RPOiBtb3ZlIHRoaXMgZmlsZSBpbnRvIHN0cnVjdHNcbi8vIFRPRE86IHNlcGFyYXRlIGNvbnN0cmFpbnQvb3ZlcmxhcC9hbGxvdywgYmVjYXVzZSBzZWxlY3Rpb24gdXNlcyBvbmx5IHRoYXQsIG5vdCBvdGhlciBwcm9wc1xuY29uc3QgRVZFTlRfVUlfUkVGSU5FUlMgPSB7XG4gICAgZGlzcGxheTogU3RyaW5nLFxuICAgIGVkaXRhYmxlOiBCb29sZWFuLFxuICAgIHN0YXJ0RWRpdGFibGU6IEJvb2xlYW4sXG4gICAgZHVyYXRpb25FZGl0YWJsZTogQm9vbGVhbixcbiAgICBjb25zdHJhaW50OiBpZGVudGl0eSxcbiAgICBvdmVybGFwOiBpZGVudGl0eSxcbiAgICBhbGxvdzogaWRlbnRpdHksXG4gICAgY2xhc3NOYW1lOiBwYXJzZUNsYXNzTmFtZXMsXG4gICAgY2xhc3NOYW1lczogcGFyc2VDbGFzc05hbWVzLFxuICAgIGNvbG9yOiBTdHJpbmcsXG4gICAgYmFja2dyb3VuZENvbG9yOiBTdHJpbmcsXG4gICAgYm9yZGVyQ29sb3I6IFN0cmluZyxcbiAgICB0ZXh0Q29sb3I6IFN0cmluZyxcbn07XG5jb25zdCBFTVBUWV9FVkVOVF9VSSA9IHtcbiAgICBkaXNwbGF5OiBudWxsLFxuICAgIHN0YXJ0RWRpdGFibGU6IG51bGwsXG4gICAgZHVyYXRpb25FZGl0YWJsZTogbnVsbCxcbiAgICBjb25zdHJhaW50czogW10sXG4gICAgb3ZlcmxhcDogbnVsbCxcbiAgICBhbGxvd3M6IFtdLFxuICAgIGJhY2tncm91bmRDb2xvcjogJycsXG4gICAgYm9yZGVyQ29sb3I6ICcnLFxuICAgIHRleHRDb2xvcjogJycsXG4gICAgY2xhc3NOYW1lczogW10sXG59O1xuZnVuY3Rpb24gY3JlYXRlRXZlbnRVaShyZWZpbmVkLCBjb250ZXh0KSB7XG4gICAgbGV0IGNvbnN0cmFpbnQgPSBub3JtYWxpemVDb25zdHJhaW50KHJlZmluZWQuY29uc3RyYWludCwgY29udGV4dCk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgZGlzcGxheTogcmVmaW5lZC5kaXNwbGF5IHx8IG51bGwsXG4gICAgICAgIHN0YXJ0RWRpdGFibGU6IHJlZmluZWQuc3RhcnRFZGl0YWJsZSAhPSBudWxsID8gcmVmaW5lZC5zdGFydEVkaXRhYmxlIDogcmVmaW5lZC5lZGl0YWJsZSxcbiAgICAgICAgZHVyYXRpb25FZGl0YWJsZTogcmVmaW5lZC5kdXJhdGlvbkVkaXRhYmxlICE9IG51bGwgPyByZWZpbmVkLmR1cmF0aW9uRWRpdGFibGUgOiByZWZpbmVkLmVkaXRhYmxlLFxuICAgICAgICBjb25zdHJhaW50czogY29uc3RyYWludCAhPSBudWxsID8gW2NvbnN0cmFpbnRdIDogW10sXG4gICAgICAgIG92ZXJsYXA6IHJlZmluZWQub3ZlcmxhcCAhPSBudWxsID8gcmVmaW5lZC5vdmVybGFwIDogbnVsbCxcbiAgICAgICAgYWxsb3dzOiByZWZpbmVkLmFsbG93ICE9IG51bGwgPyBbcmVmaW5lZC5hbGxvd10gOiBbXSxcbiAgICAgICAgYmFja2dyb3VuZENvbG9yOiByZWZpbmVkLmJhY2tncm91bmRDb2xvciB8fCByZWZpbmVkLmNvbG9yIHx8ICcnLFxuICAgICAgICBib3JkZXJDb2xvcjogcmVmaW5lZC5ib3JkZXJDb2xvciB8fCByZWZpbmVkLmNvbG9yIHx8ICcnLFxuICAgICAgICB0ZXh0Q29sb3I6IHJlZmluZWQudGV4dENvbG9yIHx8ICcnLFxuICAgICAgICBjbGFzc05hbWVzOiAocmVmaW5lZC5jbGFzc05hbWUgfHwgW10pLmNvbmNhdChyZWZpbmVkLmNsYXNzTmFtZXMgfHwgW10pLCAvLyBqb2luIHNpbmd1bGFyIGFuZCBwbHVyYWxcbiAgICB9O1xufVxuLy8gVE9ETzogcHJldmVudCBhZ2FpbnN0IHByb2JsZW1zIHdpdGggPDIgYXJncyFcbmZ1bmN0aW9uIGNvbWJpbmVFdmVudFVpcyh1aXMpIHtcbiAgICByZXR1cm4gdWlzLnJlZHVjZShjb21iaW5lVHdvRXZlbnRVaXMsIEVNUFRZX0VWRU5UX1VJKTtcbn1cbmZ1bmN0aW9uIGNvbWJpbmVUd29FdmVudFVpcyhpdGVtMCwgaXRlbTEpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBkaXNwbGF5OiBpdGVtMS5kaXNwbGF5ICE9IG51bGwgPyBpdGVtMS5kaXNwbGF5IDogaXRlbTAuZGlzcGxheSxcbiAgICAgICAgc3RhcnRFZGl0YWJsZTogaXRlbTEuc3RhcnRFZGl0YWJsZSAhPSBudWxsID8gaXRlbTEuc3RhcnRFZGl0YWJsZSA6IGl0ZW0wLnN0YXJ0RWRpdGFibGUsXG4gICAgICAgIGR1cmF0aW9uRWRpdGFibGU6IGl0ZW0xLmR1cmF0aW9uRWRpdGFibGUgIT0gbnVsbCA/IGl0ZW0xLmR1cmF0aW9uRWRpdGFibGUgOiBpdGVtMC5kdXJhdGlvbkVkaXRhYmxlLFxuICAgICAgICBjb25zdHJhaW50czogaXRlbTAuY29uc3RyYWludHMuY29uY2F0KGl0ZW0xLmNvbnN0cmFpbnRzKSxcbiAgICAgICAgb3ZlcmxhcDogdHlwZW9mIGl0ZW0xLm92ZXJsYXAgPT09ICdib29sZWFuJyA/IGl0ZW0xLm92ZXJsYXAgOiBpdGVtMC5vdmVybGFwLFxuICAgICAgICBhbGxvd3M6IGl0ZW0wLmFsbG93cy5jb25jYXQoaXRlbTEuYWxsb3dzKSxcbiAgICAgICAgYmFja2dyb3VuZENvbG9yOiBpdGVtMS5iYWNrZ3JvdW5kQ29sb3IgfHwgaXRlbTAuYmFja2dyb3VuZENvbG9yLFxuICAgICAgICBib3JkZXJDb2xvcjogaXRlbTEuYm9yZGVyQ29sb3IgfHwgaXRlbTAuYm9yZGVyQ29sb3IsXG4gICAgICAgIHRleHRDb2xvcjogaXRlbTEudGV4dENvbG9yIHx8IGl0ZW0wLnRleHRDb2xvcixcbiAgICAgICAgY2xhc3NOYW1lczogaXRlbTAuY2xhc3NOYW1lcy5jb25jYXQoaXRlbTEuY2xhc3NOYW1lcyksXG4gICAgfTtcbn1cblxuY29uc3QgRVZFTlRfTk9OX0RBVEVfUkVGSU5FUlMgPSB7XG4gICAgaWQ6IFN0cmluZyxcbiAgICBncm91cElkOiBTdHJpbmcsXG4gICAgdGl0bGU6IFN0cmluZyxcbiAgICB1cmw6IFN0cmluZyxcbiAgICBpbnRlcmFjdGl2ZTogQm9vbGVhbixcbn07XG5jb25zdCBFVkVOVF9EQVRFX1JFRklORVJTID0ge1xuICAgIHN0YXJ0OiBpZGVudGl0eSxcbiAgICBlbmQ6IGlkZW50aXR5LFxuICAgIGRhdGU6IGlkZW50aXR5LFxuICAgIGFsbERheTogQm9vbGVhbixcbn07XG5jb25zdCBFVkVOVF9SRUZJTkVSUyA9IE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCBFVkVOVF9OT05fREFURV9SRUZJTkVSUyksIEVWRU5UX0RBVEVfUkVGSU5FUlMpLCB7IGV4dGVuZGVkUHJvcHM6IGlkZW50aXR5IH0pO1xuZnVuY3Rpb24gcGFyc2VFdmVudChyYXcsIGV2ZW50U291cmNlLCBjb250ZXh0LCBhbGxvd09wZW5SYW5nZSwgcmVmaW5lcnMgPSBidWlsZEV2ZW50UmVmaW5lcnMoY29udGV4dCkpIHtcbiAgICBsZXQgeyByZWZpbmVkLCBleHRyYSB9ID0gcmVmaW5lRXZlbnREZWYocmF3LCBjb250ZXh0LCByZWZpbmVycyk7XG4gICAgbGV0IGRlZmF1bHRBbGxEYXkgPSBjb21wdXRlSXNEZWZhdWx0QWxsRGF5KGV2ZW50U291cmNlLCBjb250ZXh0KTtcbiAgICBsZXQgcmVjdXJyaW5nUmVzID0gcGFyc2VSZWN1cnJpbmcocmVmaW5lZCwgZGVmYXVsdEFsbERheSwgY29udGV4dC5kYXRlRW52LCBjb250ZXh0LnBsdWdpbkhvb2tzLnJlY3VycmluZ1R5cGVzKTtcbiAgICBpZiAocmVjdXJyaW5nUmVzKSB7XG4gICAgICAgIGxldCBkZWYgPSBwYXJzZUV2ZW50RGVmKHJlZmluZWQsIGV4dHJhLCBldmVudFNvdXJjZSA/IGV2ZW50U291cmNlLnNvdXJjZUlkIDogJycsIHJlY3VycmluZ1Jlcy5hbGxEYXksIEJvb2xlYW4ocmVjdXJyaW5nUmVzLmR1cmF0aW9uKSwgY29udGV4dCk7XG4gICAgICAgIGRlZi5yZWN1cnJpbmdEZWYgPSB7XG4gICAgICAgICAgICB0eXBlSWQ6IHJlY3VycmluZ1Jlcy50eXBlSWQsXG4gICAgICAgICAgICB0eXBlRGF0YTogcmVjdXJyaW5nUmVzLnR5cGVEYXRhLFxuICAgICAgICAgICAgZHVyYXRpb246IHJlY3VycmluZ1Jlcy5kdXJhdGlvbixcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHsgZGVmLCBpbnN0YW5jZTogbnVsbCB9O1xuICAgIH1cbiAgICBsZXQgc2luZ2xlUmVzID0gcGFyc2VTaW5nbGUocmVmaW5lZCwgZGVmYXVsdEFsbERheSwgY29udGV4dCwgYWxsb3dPcGVuUmFuZ2UpO1xuICAgIGlmIChzaW5nbGVSZXMpIHtcbiAgICAgICAgbGV0IGRlZiA9IHBhcnNlRXZlbnREZWYocmVmaW5lZCwgZXh0cmEsIGV2ZW50U291cmNlID8gZXZlbnRTb3VyY2Uuc291cmNlSWQgOiAnJywgc2luZ2xlUmVzLmFsbERheSwgc2luZ2xlUmVzLmhhc0VuZCwgY29udGV4dCk7XG4gICAgICAgIGxldCBpbnN0YW5jZSA9IGNyZWF0ZUV2ZW50SW5zdGFuY2UoZGVmLmRlZklkLCBzaW5nbGVSZXMucmFuZ2UsIHNpbmdsZVJlcy5mb3JjZWRTdGFydFR6bywgc2luZ2xlUmVzLmZvcmNlZEVuZFR6byk7XG4gICAgICAgIHJldHVybiB7IGRlZiwgaW5zdGFuY2UgfTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG59XG5mdW5jdGlvbiByZWZpbmVFdmVudERlZihyYXcsIGNvbnRleHQsIHJlZmluZXJzID0gYnVpbGRFdmVudFJlZmluZXJzKGNvbnRleHQpKSB7XG4gICAgcmV0dXJuIHJlZmluZVByb3BzKHJhdywgcmVmaW5lcnMpO1xufVxuZnVuY3Rpb24gYnVpbGRFdmVudFJlZmluZXJzKGNvbnRleHQpIHtcbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sIEVWRU5UX1VJX1JFRklORVJTKSwgRVZFTlRfUkVGSU5FUlMpLCBjb250ZXh0LnBsdWdpbkhvb2tzLmV2ZW50UmVmaW5lcnMpO1xufVxuLypcbldpbGwgTk9UIHBvcHVsYXRlIGV4dGVuZGVkUHJvcHMgd2l0aCB0aGUgbGVmdG92ZXIgcHJvcGVydGllcy5cbldpbGwgTk9UIHBvcHVsYXRlIGRhdGUtcmVsYXRlZCBwcm9wcy5cbiovXG5mdW5jdGlvbiBwYXJzZUV2ZW50RGVmKHJlZmluZWQsIGV4dHJhLCBzb3VyY2VJZCwgYWxsRGF5LCBoYXNFbmQsIGNvbnRleHQpIHtcbiAgICBsZXQgZGVmID0ge1xuICAgICAgICB0aXRsZTogcmVmaW5lZC50aXRsZSB8fCAnJyxcbiAgICAgICAgZ3JvdXBJZDogcmVmaW5lZC5ncm91cElkIHx8ICcnLFxuICAgICAgICBwdWJsaWNJZDogcmVmaW5lZC5pZCB8fCAnJyxcbiAgICAgICAgdXJsOiByZWZpbmVkLnVybCB8fCAnJyxcbiAgICAgICAgcmVjdXJyaW5nRGVmOiBudWxsLFxuICAgICAgICBkZWZJZDogZ3VpZCgpLFxuICAgICAgICBzb3VyY2VJZCxcbiAgICAgICAgYWxsRGF5LFxuICAgICAgICBoYXNFbmQsXG4gICAgICAgIGludGVyYWN0aXZlOiByZWZpbmVkLmludGVyYWN0aXZlLFxuICAgICAgICB1aTogY3JlYXRlRXZlbnRVaShyZWZpbmVkLCBjb250ZXh0KSxcbiAgICAgICAgZXh0ZW5kZWRQcm9wczogT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCAocmVmaW5lZC5leHRlbmRlZFByb3BzIHx8IHt9KSksIGV4dHJhKSxcbiAgICB9O1xuICAgIGZvciAobGV0IG1lbWJlckFkZGVyIG9mIGNvbnRleHQucGx1Z2luSG9va3MuZXZlbnREZWZNZW1iZXJBZGRlcnMpIHtcbiAgICAgICAgT2JqZWN0LmFzc2lnbihkZWYsIG1lbWJlckFkZGVyKHJlZmluZWQpKTtcbiAgICB9XG4gICAgLy8gaGVscCBvdXQgRXZlbnRJbXBsIGZyb20gaGF2aW5nIHVzZXIgbW9kaWZ5IHByb3BzXG4gICAgT2JqZWN0LmZyZWV6ZShkZWYudWkuY2xhc3NOYW1lcyk7XG4gICAgT2JqZWN0LmZyZWV6ZShkZWYuZXh0ZW5kZWRQcm9wcyk7XG4gICAgcmV0dXJuIGRlZjtcbn1cbmZ1bmN0aW9uIHBhcnNlU2luZ2xlKHJlZmluZWQsIGRlZmF1bHRBbGxEYXksIGNvbnRleHQsIGFsbG93T3BlblJhbmdlKSB7XG4gICAgbGV0IHsgYWxsRGF5IH0gPSByZWZpbmVkO1xuICAgIGxldCBzdGFydE1ldGE7XG4gICAgbGV0IHN0YXJ0TWFya2VyID0gbnVsbDtcbiAgICBsZXQgaGFzRW5kID0gZmFsc2U7XG4gICAgbGV0IGVuZE1ldGE7XG4gICAgbGV0IGVuZE1hcmtlciA9IG51bGw7XG4gICAgbGV0IHN0YXJ0SW5wdXQgPSByZWZpbmVkLnN0YXJ0ICE9IG51bGwgPyByZWZpbmVkLnN0YXJ0IDogcmVmaW5lZC5kYXRlO1xuICAgIHN0YXJ0TWV0YSA9IGNvbnRleHQuZGF0ZUVudi5jcmVhdGVNYXJrZXJNZXRhKHN0YXJ0SW5wdXQpO1xuICAgIGlmIChzdGFydE1ldGEpIHtcbiAgICAgICAgc3RhcnRNYXJrZXIgPSBzdGFydE1ldGEubWFya2VyO1xuICAgIH1cbiAgICBlbHNlIGlmICghYWxsb3dPcGVuUmFuZ2UpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGlmIChyZWZpbmVkLmVuZCAhPSBudWxsKSB7XG4gICAgICAgIGVuZE1ldGEgPSBjb250ZXh0LmRhdGVFbnYuY3JlYXRlTWFya2VyTWV0YShyZWZpbmVkLmVuZCk7XG4gICAgfVxuICAgIGlmIChhbGxEYXkgPT0gbnVsbCkge1xuICAgICAgICBpZiAoZGVmYXVsdEFsbERheSAhPSBudWxsKSB7XG4gICAgICAgICAgICBhbGxEYXkgPSBkZWZhdWx0QWxsRGF5O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gZmFsbCBiYWNrIHRvIHRoZSBkYXRlIHByb3BzIExBU1RcbiAgICAgICAgICAgIGFsbERheSA9ICghc3RhcnRNZXRhIHx8IHN0YXJ0TWV0YS5pc1RpbWVVbnNwZWNpZmllZCkgJiZcbiAgICAgICAgICAgICAgICAoIWVuZE1ldGEgfHwgZW5kTWV0YS5pc1RpbWVVbnNwZWNpZmllZCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKGFsbERheSAmJiBzdGFydE1hcmtlcikge1xuICAgICAgICBzdGFydE1hcmtlciA9IHN0YXJ0T2ZEYXkoc3RhcnRNYXJrZXIpO1xuICAgIH1cbiAgICBpZiAoZW5kTWV0YSkge1xuICAgICAgICBlbmRNYXJrZXIgPSBlbmRNZXRhLm1hcmtlcjtcbiAgICAgICAgaWYgKGFsbERheSkge1xuICAgICAgICAgICAgZW5kTWFya2VyID0gc3RhcnRPZkRheShlbmRNYXJrZXIpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzdGFydE1hcmtlciAmJiBlbmRNYXJrZXIgPD0gc3RhcnRNYXJrZXIpIHtcbiAgICAgICAgICAgIGVuZE1hcmtlciA9IG51bGw7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKGVuZE1hcmtlcikge1xuICAgICAgICBoYXNFbmQgPSB0cnVlO1xuICAgIH1cbiAgICBlbHNlIGlmICghYWxsb3dPcGVuUmFuZ2UpIHtcbiAgICAgICAgaGFzRW5kID0gY29udGV4dC5vcHRpb25zLmZvcmNlRXZlbnREdXJhdGlvbiB8fCBmYWxzZTtcbiAgICAgICAgZW5kTWFya2VyID0gY29udGV4dC5kYXRlRW52LmFkZChzdGFydE1hcmtlciwgYWxsRGF5ID9cbiAgICAgICAgICAgIGNvbnRleHQub3B0aW9ucy5kZWZhdWx0QWxsRGF5RXZlbnREdXJhdGlvbiA6XG4gICAgICAgICAgICBjb250ZXh0Lm9wdGlvbnMuZGVmYXVsdFRpbWVkRXZlbnREdXJhdGlvbik7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICAgIGFsbERheSxcbiAgICAgICAgaGFzRW5kLFxuICAgICAgICByYW5nZTogeyBzdGFydDogc3RhcnRNYXJrZXIsIGVuZDogZW5kTWFya2VyIH0sXG4gICAgICAgIGZvcmNlZFN0YXJ0VHpvOiBzdGFydE1ldGEgPyBzdGFydE1ldGEuZm9yY2VkVHpvIDogbnVsbCxcbiAgICAgICAgZm9yY2VkRW5kVHpvOiBlbmRNZXRhID8gZW5kTWV0YS5mb3JjZWRUem8gOiBudWxsLFxuICAgIH07XG59XG5mdW5jdGlvbiBjb21wdXRlSXNEZWZhdWx0QWxsRGF5KGV2ZW50U291cmNlLCBjb250ZXh0KSB7XG4gICAgbGV0IHJlcyA9IG51bGw7XG4gICAgaWYgKGV2ZW50U291cmNlKSB7XG4gICAgICAgIHJlcyA9IGV2ZW50U291cmNlLmRlZmF1bHRBbGxEYXk7XG4gICAgfVxuICAgIGlmIChyZXMgPT0gbnVsbCkge1xuICAgICAgICByZXMgPSBjb250ZXh0Lm9wdGlvbnMuZGVmYXVsdEFsbERheTtcbiAgICB9XG4gICAgcmV0dXJuIHJlcztcbn1cblxuY29uc3QgREVGX0RFRkFVTFRTID0ge1xuICAgIHN0YXJ0VGltZTogJzA5OjAwJyxcbiAgICBlbmRUaW1lOiAnMTc6MDAnLFxuICAgIGRheXNPZldlZWs6IFsxLCAyLCAzLCA0LCA1XSxcbiAgICBkaXNwbGF5OiAnaW52ZXJzZS1iYWNrZ3JvdW5kJyxcbiAgICBjbGFzc05hbWVzOiAnZmMtbm9uLWJ1c2luZXNzJyxcbiAgICBncm91cElkOiAnX2J1c2luZXNzSG91cnMnLCAvLyBzbyBtdWx0aXBsZSBkZWZzIGdldCBncm91cGVkXG59O1xuLypcblRPRE86IHBhc3MgYXJvdW5kIGFzIEV2ZW50RGVmSGFzaCEhIVxuKi9cbmZ1bmN0aW9uIHBhcnNlQnVzaW5lc3NIb3VycyhpbnB1dCwgY29udGV4dCkge1xuICAgIHJldHVybiBwYXJzZUV2ZW50cyhyZWZpbmVJbnB1dHMoaW5wdXQpLCBudWxsLCBjb250ZXh0KTtcbn1cbmZ1bmN0aW9uIHJlZmluZUlucHV0cyhpbnB1dCkge1xuICAgIGxldCByYXdEZWZzO1xuICAgIGlmIChpbnB1dCA9PT0gdHJ1ZSkge1xuICAgICAgICByYXdEZWZzID0gW3t9XTsgLy8gd2lsbCBnZXQgREVGX0RFRkFVTFRTIHZlcmJhdGltXG4gICAgfVxuICAgIGVsc2UgaWYgKEFycmF5LmlzQXJyYXkoaW5wdXQpKSB7XG4gICAgICAgIC8vIGlmIHNwZWNpZnlpbmcgYW4gYXJyYXksIGV2ZXJ5IHN1Yi1kZWZpbml0aW9uIE5FRURTIGEgZGF5LW9mLXdlZWtcbiAgICAgICAgcmF3RGVmcyA9IGlucHV0LmZpbHRlcigocmF3RGVmKSA9PiByYXdEZWYuZGF5c09mV2Vlayk7XG4gICAgfVxuICAgIGVsc2UgaWYgKHR5cGVvZiBpbnB1dCA9PT0gJ29iamVjdCcgJiYgaW5wdXQpIHsgLy8gbm9uLW51bGwgb2JqZWN0XG4gICAgICAgIHJhd0RlZnMgPSBbaW5wdXRdO1xuICAgIH1cbiAgICBlbHNlIHsgLy8gaXMgcHJvYmFibHkgZmFsc2VcbiAgICAgICAgcmF3RGVmcyA9IFtdO1xuICAgIH1cbiAgICByYXdEZWZzID0gcmF3RGVmcy5tYXAoKHJhd0RlZikgPT4gKE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgREVGX0RFRkFVTFRTKSwgcmF3RGVmKSkpO1xuICAgIHJldHVybiByYXdEZWZzO1xufVxuXG4vKiBEYXRlIHN0dWZmIHRoYXQgZG9lc24ndCBiZWxvbmcgaW4gZGF0ZWxpYiBjb3JlXG4tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cbi8vIGdpdmVuIGEgdGltZWQgcmFuZ2UsIGNvbXB1dGVzIGFuIGFsbC1kYXkgcmFuZ2UgdGhhdCBoYXMgdGhlIHNhbWUgZXhhY3QgZHVyYXRpb24sXG4vLyBidXQgd2hvc2Ugc3RhcnQgdGltZSBpcyBhbGlnbmVkIHdpdGggdGhlIHN0YXJ0IG9mIHRoZSBkYXkuXG5mdW5jdGlvbiBjb21wdXRlQWxpZ25lZERheVJhbmdlKHRpbWVkUmFuZ2UpIHtcbiAgICBsZXQgZGF5Q250ID0gTWF0aC5mbG9vcihkaWZmRGF5cyh0aW1lZFJhbmdlLnN0YXJ0LCB0aW1lZFJhbmdlLmVuZCkpIHx8IDE7XG4gICAgbGV0IHN0YXJ0ID0gc3RhcnRPZkRheSh0aW1lZFJhbmdlLnN0YXJ0KTtcbiAgICBsZXQgZW5kID0gYWRkRGF5cyhzdGFydCwgZGF5Q250KTtcbiAgICByZXR1cm4geyBzdGFydCwgZW5kIH07XG59XG4vLyBnaXZlbiBhIHRpbWVkIHJhbmdlLCBjb21wdXRlcyBhbiBhbGwtZGF5IHJhbmdlIGJhc2VkIG9uIGhvdyBmb3IgdGhlIGVuZCBkYXRlIGJsZWVkcyBpbnRvIHRoZSBuZXh0IGRheVxuLy8gVE9ETzogZ2l2ZSBuZXh0RGF5VGhyZXNob2xkIGEgZGVmYXVsdCBhcmdcbmZ1bmN0aW9uIGNvbXB1dGVWaXNpYmxlRGF5UmFuZ2UodGltZWRSYW5nZSwgbmV4dERheVRocmVzaG9sZCA9IGNyZWF0ZUR1cmF0aW9uKDApKSB7XG4gICAgbGV0IHN0YXJ0RGF5ID0gbnVsbDtcbiAgICBsZXQgZW5kRGF5ID0gbnVsbDtcbiAgICBpZiAodGltZWRSYW5nZS5lbmQpIHtcbiAgICAgICAgZW5kRGF5ID0gc3RhcnRPZkRheSh0aW1lZFJhbmdlLmVuZCk7XG4gICAgICAgIGxldCBlbmRUaW1lTVMgPSB0aW1lZFJhbmdlLmVuZC52YWx1ZU9mKCkgLSBlbmREYXkudmFsdWVPZigpOyAvLyAjIG9mIG1pbGxpc2Vjb25kcyBpbnRvIGBlbmREYXlgXG4gICAgICAgIC8vIElmIHRoZSBlbmQgdGltZSBpcyBhY3R1YWxseSBpbmNsdXNpdmVseSBwYXJ0IG9mIHRoZSBuZXh0IGRheSBhbmQgaXMgZXF1YWwgdG8gb3JcbiAgICAgICAgLy8gYmV5b25kIHRoZSBuZXh0IGRheSB0aHJlc2hvbGQsIGFkanVzdCB0aGUgZW5kIHRvIGJlIHRoZSBleGNsdXNpdmUgZW5kIG9mIGBlbmREYXlgLlxuICAgICAgICAvLyBPdGhlcndpc2UsIGxlYXZpbmcgaXQgYXMgaW5jbHVzaXZlIHdpbGwgY2F1c2UgaXQgdG8gZXhjbHVkZSBgZW5kRGF5YC5cbiAgICAgICAgaWYgKGVuZFRpbWVNUyAmJiBlbmRUaW1lTVMgPj0gYXNSb3VnaE1zKG5leHREYXlUaHJlc2hvbGQpKSB7XG4gICAgICAgICAgICBlbmREYXkgPSBhZGREYXlzKGVuZERheSwgMSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKHRpbWVkUmFuZ2Uuc3RhcnQpIHtcbiAgICAgICAgc3RhcnREYXkgPSBzdGFydE9mRGF5KHRpbWVkUmFuZ2Uuc3RhcnQpOyAvLyB0aGUgYmVnaW5uaW5nIG9mIHRoZSBkYXkgdGhlIHJhbmdlIHN0YXJ0c1xuICAgICAgICAvLyBJZiBlbmQgaXMgd2l0aGluIGBzdGFydERheWAgYnV0IG5vdCBwYXN0IG5leHREYXlUaHJlc2hvbGQsIGFzc2lnbiB0aGUgZGVmYXVsdCBkdXJhdGlvbiBvZiBvbmUgZGF5LlxuICAgICAgICBpZiAoZW5kRGF5ICYmIGVuZERheSA8PSBzdGFydERheSkge1xuICAgICAgICAgICAgZW5kRGF5ID0gYWRkRGF5cyhzdGFydERheSwgMSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHsgc3RhcnQ6IHN0YXJ0RGF5LCBlbmQ6IGVuZERheSB9O1xufVxuLy8gc3BhbnMgZnJvbSBvbmUgZGF5IGludG8gYW5vdGhlcj9cbmZ1bmN0aW9uIGlzTXVsdGlEYXlSYW5nZShyYW5nZSkge1xuICAgIGxldCB2aXNpYmxlUmFuZ2UgPSBjb21wdXRlVmlzaWJsZURheVJhbmdlKHJhbmdlKTtcbiAgICByZXR1cm4gZGlmZkRheXModmlzaWJsZVJhbmdlLnN0YXJ0LCB2aXNpYmxlUmFuZ2UuZW5kKSA+IDE7XG59XG5mdW5jdGlvbiBkaWZmRGF0ZXMoZGF0ZTAsIGRhdGUxLCBkYXRlRW52LCBsYXJnZVVuaXQpIHtcbiAgICBpZiAobGFyZ2VVbml0ID09PSAneWVhcicpIHtcbiAgICAgICAgcmV0dXJuIGNyZWF0ZUR1cmF0aW9uKGRhdGVFbnYuZGlmZldob2xlWWVhcnMoZGF0ZTAsIGRhdGUxKSwgJ3llYXInKTtcbiAgICB9XG4gICAgaWYgKGxhcmdlVW5pdCA9PT0gJ21vbnRoJykge1xuICAgICAgICByZXR1cm4gY3JlYXRlRHVyYXRpb24oZGF0ZUVudi5kaWZmV2hvbGVNb250aHMoZGF0ZTAsIGRhdGUxKSwgJ21vbnRoJyk7XG4gICAgfVxuICAgIHJldHVybiBkaWZmRGF5QW5kVGltZShkYXRlMCwgZGF0ZTEpOyAvLyByZXR1cm5zIGEgZHVyYXRpb25cbn1cblxuZnVuY3Rpb24gcG9pbnRJbnNpZGVSZWN0KHBvaW50LCByZWN0KSB7XG4gICAgcmV0dXJuIHBvaW50LmxlZnQgPj0gcmVjdC5sZWZ0ICYmXG4gICAgICAgIHBvaW50LmxlZnQgPCByZWN0LnJpZ2h0ICYmXG4gICAgICAgIHBvaW50LnRvcCA+PSByZWN0LnRvcCAmJlxuICAgICAgICBwb2ludC50b3AgPCByZWN0LmJvdHRvbTtcbn1cbi8vIFJldHVybnMgYSBuZXcgcmVjdGFuZ2xlIHRoYXQgaXMgdGhlIGludGVyc2VjdGlvbiBvZiB0aGUgdHdvIHJlY3RhbmdsZXMuIElmIHRoZXkgZG9uJ3QgaW50ZXJzZWN0LCByZXR1cm5zIGZhbHNlXG5mdW5jdGlvbiBpbnRlcnNlY3RSZWN0cyhyZWN0MSwgcmVjdDIpIHtcbiAgICBsZXQgcmVzID0ge1xuICAgICAgICBsZWZ0OiBNYXRoLm1heChyZWN0MS5sZWZ0LCByZWN0Mi5sZWZ0KSxcbiAgICAgICAgcmlnaHQ6IE1hdGgubWluKHJlY3QxLnJpZ2h0LCByZWN0Mi5yaWdodCksXG4gICAgICAgIHRvcDogTWF0aC5tYXgocmVjdDEudG9wLCByZWN0Mi50b3ApLFxuICAgICAgICBib3R0b206IE1hdGgubWluKHJlY3QxLmJvdHRvbSwgcmVjdDIuYm90dG9tKSxcbiAgICB9O1xuICAgIGlmIChyZXMubGVmdCA8IHJlcy5yaWdodCAmJiByZXMudG9wIDwgcmVzLmJvdHRvbSkge1xuICAgICAgICByZXR1cm4gcmVzO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59XG5mdW5jdGlvbiB0cmFuc2xhdGVSZWN0KHJlY3QsIGRlbHRhWCwgZGVsdGFZKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbGVmdDogcmVjdC5sZWZ0ICsgZGVsdGFYLFxuICAgICAgICByaWdodDogcmVjdC5yaWdodCArIGRlbHRhWCxcbiAgICAgICAgdG9wOiByZWN0LnRvcCArIGRlbHRhWSxcbiAgICAgICAgYm90dG9tOiByZWN0LmJvdHRvbSArIGRlbHRhWSxcbiAgICB9O1xufVxuLy8gUmV0dXJucyBhIG5ldyBwb2ludCB0aGF0IHdpbGwgaGF2ZSBiZWVuIG1vdmVkIHRvIHJlc2lkZSB3aXRoaW4gdGhlIGdpdmVuIHJlY3RhbmdsZVxuZnVuY3Rpb24gY29uc3RyYWluUG9pbnQocG9pbnQsIHJlY3QpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBsZWZ0OiBNYXRoLm1pbihNYXRoLm1heChwb2ludC5sZWZ0LCByZWN0LmxlZnQpLCByZWN0LnJpZ2h0KSxcbiAgICAgICAgdG9wOiBNYXRoLm1pbihNYXRoLm1heChwb2ludC50b3AsIHJlY3QudG9wKSwgcmVjdC5ib3R0b20pLFxuICAgIH07XG59XG4vLyBSZXR1cm5zIGEgcG9pbnQgdGhhdCBpcyB0aGUgY2VudGVyIG9mIHRoZSBnaXZlbiByZWN0YW5nbGVcbmZ1bmN0aW9uIGdldFJlY3RDZW50ZXIocmVjdCkge1xuICAgIHJldHVybiB7XG4gICAgICAgIGxlZnQ6IChyZWN0LmxlZnQgKyByZWN0LnJpZ2h0KSAvIDIsXG4gICAgICAgIHRvcDogKHJlY3QudG9wICsgcmVjdC5ib3R0b20pIC8gMixcbiAgICB9O1xufVxuLy8gU3VidHJhY3RzIHBvaW50MidzIGNvb3JkaW5hdGVzIGZyb20gcG9pbnQxJ3MgY29vcmRpbmF0ZXMsIHJldHVybmluZyBhIGRlbHRhXG5mdW5jdGlvbiBkaWZmUG9pbnRzKHBvaW50MSwgcG9pbnQyKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgbGVmdDogcG9pbnQxLmxlZnQgLSBwb2ludDIubGVmdCxcbiAgICAgICAgdG9wOiBwb2ludDEudG9wIC0gcG9pbnQyLnRvcCxcbiAgICB9O1xufVxuXG5sZXQgY2FuVkdyb3dXaXRoaW5DZWxsO1xuZnVuY3Rpb24gZ2V0Q2FuVkdyb3dXaXRoaW5DZWxsKCkge1xuICAgIGlmIChjYW5WR3Jvd1dpdGhpbkNlbGwgPT0gbnVsbCkge1xuICAgICAgICBjYW5WR3Jvd1dpdGhpbkNlbGwgPSBjb21wdXRlQ2FuVkdyb3dXaXRoaW5DZWxsKCk7XG4gICAgfVxuICAgIHJldHVybiBjYW5WR3Jvd1dpdGhpbkNlbGw7XG59XG5mdW5jdGlvbiBjb21wdXRlQ2FuVkdyb3dXaXRoaW5DZWxsKCkge1xuICAgIC8vIGZvciBTU1IsIGJlY2F1c2UgdGhpcyBmdW5jdGlvbiBpcyBjYWxsIGltbWVkaWF0ZWx5IGF0IHRvcC1sZXZlbFxuICAgIC8vIFRPRE86IGp1c3QgbWFrZSB0aGlzIGxvZ2ljIGV4ZWN1dGUgdG9wLWxldmVsLCBpbW1lZGlhdGVseSwgaW5zdGVhZCBvZiBkb2luZyBsYXppbHlcbiAgICBpZiAodHlwZW9mIGRvY3VtZW50ID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgbGV0IGVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgZWwuc3R5bGUucG9zaXRpb24gPSAnYWJzb2x1dGUnO1xuICAgIGVsLnN0eWxlLnRvcCA9ICcwcHgnO1xuICAgIGVsLnN0eWxlLmxlZnQgPSAnMHB4JztcbiAgICBlbC5pbm5lckhUTUwgPSAnPHRhYmxlPjx0cj48dGQ+PGRpdj48L2Rpdj48L3RkPjwvdHI+PC90YWJsZT4nO1xuICAgIGVsLnF1ZXJ5U2VsZWN0b3IoJ3RhYmxlJykuc3R5bGUuaGVpZ2h0ID0gJzEwMHB4JztcbiAgICBlbC5xdWVyeVNlbGVjdG9yKCdkaXYnKS5zdHlsZS5oZWlnaHQgPSAnMTAwJSc7XG4gICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChlbCk7XG4gICAgbGV0IGRpdiA9IGVsLnF1ZXJ5U2VsZWN0b3IoJ2RpdicpO1xuICAgIGxldCBwb3NzaWJsZSA9IGRpdi5vZmZzZXRIZWlnaHQgPiAwO1xuICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQoZWwpO1xuICAgIHJldHVybiBwb3NzaWJsZTtcbn1cblxuY29uc3QgRU1QVFlfRVZFTlRfU1RPUkUgPSBjcmVhdGVFbXB0eUV2ZW50U3RvcmUoKTsgLy8gZm9yIHB1cmVjb21wb25lbnRzLiBUT0RPOiBrZWVwIGVsc2V3aGVyZVxuY2xhc3MgU3BsaXR0ZXIge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLmdldEtleXNGb3JFdmVudERlZnMgPSBtZW1vaXplKHRoaXMuX2dldEtleXNGb3JFdmVudERlZnMpO1xuICAgICAgICB0aGlzLnNwbGl0RGF0ZVNlbGVjdGlvbiA9IG1lbW9pemUodGhpcy5fc3BsaXREYXRlU3Bhbik7XG4gICAgICAgIHRoaXMuc3BsaXRFdmVudFN0b3JlID0gbWVtb2l6ZSh0aGlzLl9zcGxpdEV2ZW50U3RvcmUpO1xuICAgICAgICB0aGlzLnNwbGl0SW5kaXZpZHVhbFVpID0gbWVtb2l6ZSh0aGlzLl9zcGxpdEluZGl2aWR1YWxVaSk7XG4gICAgICAgIHRoaXMuc3BsaXRFdmVudERyYWcgPSBtZW1vaXplKHRoaXMuX3NwbGl0SW50ZXJhY3Rpb24pO1xuICAgICAgICB0aGlzLnNwbGl0RXZlbnRSZXNpemUgPSBtZW1vaXplKHRoaXMuX3NwbGl0SW50ZXJhY3Rpb24pO1xuICAgICAgICB0aGlzLmV2ZW50VWlCdWlsZGVycyA9IHt9OyAvLyBUT0RPOiB0eXBlc2NyaXB0IHByb3RlY3Rpb25cbiAgICB9XG4gICAgc3BsaXRQcm9wcyhwcm9wcykge1xuICAgICAgICBsZXQga2V5SW5mb3MgPSB0aGlzLmdldEtleUluZm8ocHJvcHMpO1xuICAgICAgICBsZXQgZGVmS2V5cyA9IHRoaXMuZ2V0S2V5c0ZvckV2ZW50RGVmcyhwcm9wcy5ldmVudFN0b3JlKTtcbiAgICAgICAgbGV0IGRhdGVTZWxlY3Rpb25zID0gdGhpcy5zcGxpdERhdGVTZWxlY3Rpb24ocHJvcHMuZGF0ZVNlbGVjdGlvbik7XG4gICAgICAgIGxldCBpbmRpdmlkdWFsVWkgPSB0aGlzLnNwbGl0SW5kaXZpZHVhbFVpKHByb3BzLmV2ZW50VWlCYXNlcywgZGVmS2V5cyk7IC8vIHRoZSBpbmRpdmlkdWFsICpiYXNlcypcbiAgICAgICAgbGV0IGV2ZW50U3RvcmVzID0gdGhpcy5zcGxpdEV2ZW50U3RvcmUocHJvcHMuZXZlbnRTdG9yZSwgZGVmS2V5cyk7XG4gICAgICAgIGxldCBldmVudERyYWdzID0gdGhpcy5zcGxpdEV2ZW50RHJhZyhwcm9wcy5ldmVudERyYWcpO1xuICAgICAgICBsZXQgZXZlbnRSZXNpemVzID0gdGhpcy5zcGxpdEV2ZW50UmVzaXplKHByb3BzLmV2ZW50UmVzaXplKTtcbiAgICAgICAgbGV0IHNwbGl0UHJvcHMgPSB7fTtcbiAgICAgICAgdGhpcy5ldmVudFVpQnVpbGRlcnMgPSBtYXBIYXNoKGtleUluZm9zLCAoaW5mbywga2V5KSA9PiB0aGlzLmV2ZW50VWlCdWlsZGVyc1trZXldIHx8IG1lbW9pemUoYnVpbGRFdmVudFVpRm9yS2V5KSk7XG4gICAgICAgIGZvciAobGV0IGtleSBpbiBrZXlJbmZvcykge1xuICAgICAgICAgICAgbGV0IGtleUluZm8gPSBrZXlJbmZvc1trZXldO1xuICAgICAgICAgICAgbGV0IGV2ZW50U3RvcmUgPSBldmVudFN0b3Jlc1trZXldIHx8IEVNUFRZX0VWRU5UX1NUT1JFO1xuICAgICAgICAgICAgbGV0IGJ1aWxkRXZlbnRVaSA9IHRoaXMuZXZlbnRVaUJ1aWxkZXJzW2tleV07XG4gICAgICAgICAgICBzcGxpdFByb3BzW2tleV0gPSB7XG4gICAgICAgICAgICAgICAgYnVzaW5lc3NIb3Vyczoga2V5SW5mby5idXNpbmVzc0hvdXJzIHx8IHByb3BzLmJ1c2luZXNzSG91cnMsXG4gICAgICAgICAgICAgICAgZGF0ZVNlbGVjdGlvbjogZGF0ZVNlbGVjdGlvbnNba2V5XSB8fCBudWxsLFxuICAgICAgICAgICAgICAgIGV2ZW50U3RvcmUsXG4gICAgICAgICAgICAgICAgZXZlbnRVaUJhc2VzOiBidWlsZEV2ZW50VWkocHJvcHMuZXZlbnRVaUJhc2VzWycnXSwga2V5SW5mby51aSwgaW5kaXZpZHVhbFVpW2tleV0pLFxuICAgICAgICAgICAgICAgIGV2ZW50U2VsZWN0aW9uOiBldmVudFN0b3JlLmluc3RhbmNlc1twcm9wcy5ldmVudFNlbGVjdGlvbl0gPyBwcm9wcy5ldmVudFNlbGVjdGlvbiA6ICcnLFxuICAgICAgICAgICAgICAgIGV2ZW50RHJhZzogZXZlbnREcmFnc1trZXldIHx8IG51bGwsXG4gICAgICAgICAgICAgICAgZXZlbnRSZXNpemU6IGV2ZW50UmVzaXplc1trZXldIHx8IG51bGwsXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzcGxpdFByb3BzO1xuICAgIH1cbiAgICBfc3BsaXREYXRlU3BhbihkYXRlU3Bhbikge1xuICAgICAgICBsZXQgZGF0ZVNwYW5zID0ge307XG4gICAgICAgIGlmIChkYXRlU3Bhbikge1xuICAgICAgICAgICAgbGV0IGtleXMgPSB0aGlzLmdldEtleXNGb3JEYXRlU3BhbihkYXRlU3Bhbik7XG4gICAgICAgICAgICBmb3IgKGxldCBrZXkgb2Yga2V5cykge1xuICAgICAgICAgICAgICAgIGRhdGVTcGFuc1trZXldID0gZGF0ZVNwYW47XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGRhdGVTcGFucztcbiAgICB9XG4gICAgX2dldEtleXNGb3JFdmVudERlZnMoZXZlbnRTdG9yZSkge1xuICAgICAgICByZXR1cm4gbWFwSGFzaChldmVudFN0b3JlLmRlZnMsIChldmVudERlZikgPT4gdGhpcy5nZXRLZXlzRm9yRXZlbnREZWYoZXZlbnREZWYpKTtcbiAgICB9XG4gICAgX3NwbGl0RXZlbnRTdG9yZShldmVudFN0b3JlLCBkZWZLZXlzKSB7XG4gICAgICAgIGxldCB7IGRlZnMsIGluc3RhbmNlcyB9ID0gZXZlbnRTdG9yZTtcbiAgICAgICAgbGV0IHNwbGl0U3RvcmVzID0ge307XG4gICAgICAgIGZvciAobGV0IGRlZklkIGluIGRlZnMpIHtcbiAgICAgICAgICAgIGZvciAobGV0IGtleSBvZiBkZWZLZXlzW2RlZklkXSkge1xuICAgICAgICAgICAgICAgIGlmICghc3BsaXRTdG9yZXNba2V5XSkge1xuICAgICAgICAgICAgICAgICAgICBzcGxpdFN0b3Jlc1trZXldID0gY3JlYXRlRW1wdHlFdmVudFN0b3JlKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHNwbGl0U3RvcmVzW2tleV0uZGVmc1tkZWZJZF0gPSBkZWZzW2RlZklkXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBmb3IgKGxldCBpbnN0YW5jZUlkIGluIGluc3RhbmNlcykge1xuICAgICAgICAgICAgbGV0IGluc3RhbmNlID0gaW5zdGFuY2VzW2luc3RhbmNlSWRdO1xuICAgICAgICAgICAgZm9yIChsZXQga2V5IG9mIGRlZktleXNbaW5zdGFuY2UuZGVmSWRdKSB7XG4gICAgICAgICAgICAgICAgaWYgKHNwbGl0U3RvcmVzW2tleV0pIHsgLy8gbXVzdCBoYXZlIGFscmVhZHkgYmVlbiBjcmVhdGVkXG4gICAgICAgICAgICAgICAgICAgIHNwbGl0U3RvcmVzW2tleV0uaW5zdGFuY2VzW2luc3RhbmNlSWRdID0gaW5zdGFuY2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzcGxpdFN0b3JlcztcbiAgICB9XG4gICAgX3NwbGl0SW5kaXZpZHVhbFVpKGV2ZW50VWlCYXNlcywgZGVmS2V5cykge1xuICAgICAgICBsZXQgc3BsaXRIYXNoZXMgPSB7fTtcbiAgICAgICAgZm9yIChsZXQgZGVmSWQgaW4gZXZlbnRVaUJhc2VzKSB7XG4gICAgICAgICAgICBpZiAoZGVmSWQpIHsgLy8gbm90IHRoZSAnJyBrZXlcbiAgICAgICAgICAgICAgICBmb3IgKGxldCBrZXkgb2YgZGVmS2V5c1tkZWZJZF0pIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFzcGxpdEhhc2hlc1trZXldKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzcGxpdEhhc2hlc1trZXldID0ge307XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgc3BsaXRIYXNoZXNba2V5XVtkZWZJZF0gPSBldmVudFVpQmFzZXNbZGVmSWRdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc3BsaXRIYXNoZXM7XG4gICAgfVxuICAgIF9zcGxpdEludGVyYWN0aW9uKGludGVyYWN0aW9uKSB7XG4gICAgICAgIGxldCBzcGxpdFN0YXRlcyA9IHt9O1xuICAgICAgICBpZiAoaW50ZXJhY3Rpb24pIHtcbiAgICAgICAgICAgIGxldCBhZmZlY3RlZFN0b3JlcyA9IHRoaXMuX3NwbGl0RXZlbnRTdG9yZShpbnRlcmFjdGlvbi5hZmZlY3RlZEV2ZW50cywgdGhpcy5fZ2V0S2V5c0ZvckV2ZW50RGVmcyhpbnRlcmFjdGlvbi5hZmZlY3RlZEV2ZW50cykpO1xuICAgICAgICAgICAgLy8gY2FuJ3QgcmVseSBvbiBkZWZLZXlzIGJlY2F1c2UgZXZlbnQgZGF0YSBpcyBtdXRhdGVkXG4gICAgICAgICAgICBsZXQgbXV0YXRlZEtleXNCeURlZklkID0gdGhpcy5fZ2V0S2V5c0ZvckV2ZW50RGVmcyhpbnRlcmFjdGlvbi5tdXRhdGVkRXZlbnRzKTtcbiAgICAgICAgICAgIGxldCBtdXRhdGVkU3RvcmVzID0gdGhpcy5fc3BsaXRFdmVudFN0b3JlKGludGVyYWN0aW9uLm11dGF0ZWRFdmVudHMsIG11dGF0ZWRLZXlzQnlEZWZJZCk7XG4gICAgICAgICAgICBsZXQgcG9wdWxhdGUgPSAoa2V5KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKCFzcGxpdFN0YXRlc1trZXldKSB7XG4gICAgICAgICAgICAgICAgICAgIHNwbGl0U3RhdGVzW2tleV0gPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhZmZlY3RlZEV2ZW50czogYWZmZWN0ZWRTdG9yZXNba2V5XSB8fCBFTVBUWV9FVkVOVF9TVE9SRSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG11dGF0ZWRFdmVudHM6IG11dGF0ZWRTdG9yZXNba2V5XSB8fCBFTVBUWV9FVkVOVF9TVE9SRSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGlzRXZlbnQ6IGludGVyYWN0aW9uLmlzRXZlbnQsXG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGZvciAobGV0IGtleSBpbiBhZmZlY3RlZFN0b3Jlcykge1xuICAgICAgICAgICAgICAgIHBvcHVsYXRlKGtleSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmb3IgKGxldCBrZXkgaW4gbXV0YXRlZFN0b3Jlcykge1xuICAgICAgICAgICAgICAgIHBvcHVsYXRlKGtleSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHNwbGl0U3RhdGVzO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGJ1aWxkRXZlbnRVaUZvcktleShhbGxVaSwgZXZlbnRVaUZvcktleSwgaW5kaXZpZHVhbFVpKSB7XG4gICAgbGV0IGJhc2VQYXJ0cyA9IFtdO1xuICAgIGlmIChhbGxVaSkge1xuICAgICAgICBiYXNlUGFydHMucHVzaChhbGxVaSk7XG4gICAgfVxuICAgIGlmIChldmVudFVpRm9yS2V5KSB7XG4gICAgICAgIGJhc2VQYXJ0cy5wdXNoKGV2ZW50VWlGb3JLZXkpO1xuICAgIH1cbiAgICBsZXQgc3R1ZmYgPSB7XG4gICAgICAgICcnOiBjb21iaW5lRXZlbnRVaXMoYmFzZVBhcnRzKSxcbiAgICB9O1xuICAgIGlmIChpbmRpdmlkdWFsVWkpIHtcbiAgICAgICAgT2JqZWN0LmFzc2lnbihzdHVmZiwgaW5kaXZpZHVhbFVpKTtcbiAgICB9XG4gICAgcmV0dXJuIHN0dWZmO1xufVxuXG5mdW5jdGlvbiBwYXJzZVJhbmdlKGlucHV0LCBkYXRlRW52KSB7XG4gICAgbGV0IHN0YXJ0ID0gbnVsbDtcbiAgICBsZXQgZW5kID0gbnVsbDtcbiAgICBpZiAoaW5wdXQuc3RhcnQpIHtcbiAgICAgICAgc3RhcnQgPSBkYXRlRW52LmNyZWF0ZU1hcmtlcihpbnB1dC5zdGFydCk7XG4gICAgfVxuICAgIGlmIChpbnB1dC5lbmQpIHtcbiAgICAgICAgZW5kID0gZGF0ZUVudi5jcmVhdGVNYXJrZXIoaW5wdXQuZW5kKTtcbiAgICB9XG4gICAgaWYgKCFzdGFydCAmJiAhZW5kKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBpZiAoc3RhcnQgJiYgZW5kICYmIGVuZCA8IHN0YXJ0KSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICByZXR1cm4geyBzdGFydCwgZW5kIH07XG59XG4vLyBTSURFLUVGRkVDVDogd2lsbCBtdXRhdGUgcmFuZ2VzLlxuLy8gV2lsbCByZXR1cm4gYSBuZXcgYXJyYXkgcmVzdWx0LlxuZnVuY3Rpb24gaW52ZXJ0UmFuZ2VzKHJhbmdlcywgY29uc3RyYWludFJhbmdlKSB7XG4gICAgbGV0IGludmVydGVkUmFuZ2VzID0gW107XG4gICAgbGV0IHsgc3RhcnQgfSA9IGNvbnN0cmFpbnRSYW5nZTsgLy8gdGhlIGVuZCBvZiB0aGUgcHJldmlvdXMgcmFuZ2UuIHRoZSBzdGFydCBvZiB0aGUgbmV3IHJhbmdlXG4gICAgbGV0IGk7XG4gICAgbGV0IGRhdGVSYW5nZTtcbiAgICAvLyByYW5nZXMgbmVlZCB0byBiZSBpbiBvcmRlci4gcmVxdWlyZWQgZm9yIG91ciBkYXRlLXdhbGtpbmcgYWxnb3JpdGhtXG4gICAgcmFuZ2VzLnNvcnQoY29tcGFyZVJhbmdlcyk7XG4gICAgZm9yIChpID0gMDsgaSA8IHJhbmdlcy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICBkYXRlUmFuZ2UgPSByYW5nZXNbaV07XG4gICAgICAgIC8vIGFkZCB0aGUgc3BhbiBvZiB0aW1lIGJlZm9yZSB0aGUgZXZlbnQgKGlmIHRoZXJlIGlzIGFueSlcbiAgICAgICAgaWYgKGRhdGVSYW5nZS5zdGFydCA+IHN0YXJ0KSB7IC8vIGNvbXBhcmUgbWlsbGlzZWNvbmQgdGltZSAoc2tpcCBhbnkgYW1iaWcgbG9naWMpXG4gICAgICAgICAgICBpbnZlcnRlZFJhbmdlcy5wdXNoKHsgc3RhcnQsIGVuZDogZGF0ZVJhbmdlLnN0YXJ0IH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChkYXRlUmFuZ2UuZW5kID4gc3RhcnQpIHtcbiAgICAgICAgICAgIHN0YXJ0ID0gZGF0ZVJhbmdlLmVuZDtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvLyBhZGQgdGhlIHNwYW4gb2YgdGltZSBhZnRlciB0aGUgbGFzdCBldmVudCAoaWYgdGhlcmUgaXMgYW55KVxuICAgIGlmIChzdGFydCA8IGNvbnN0cmFpbnRSYW5nZS5lbmQpIHsgLy8gY29tcGFyZSBtaWxsaXNlY29uZCB0aW1lIChza2lwIGFueSBhbWJpZyBsb2dpYylcbiAgICAgICAgaW52ZXJ0ZWRSYW5nZXMucHVzaCh7IHN0YXJ0LCBlbmQ6IGNvbnN0cmFpbnRSYW5nZS5lbmQgfSk7XG4gICAgfVxuICAgIHJldHVybiBpbnZlcnRlZFJhbmdlcztcbn1cbmZ1bmN0aW9uIGNvbXBhcmVSYW5nZXMocmFuZ2UwLCByYW5nZTEpIHtcbiAgICByZXR1cm4gcmFuZ2UwLnN0YXJ0LnZhbHVlT2YoKSAtIHJhbmdlMS5zdGFydC52YWx1ZU9mKCk7IC8vIGVhcmxpZXIgcmFuZ2VzIGdvIGZpcnN0XG59XG5mdW5jdGlvbiBpbnRlcnNlY3RSYW5nZXMocmFuZ2UwLCByYW5nZTEpIHtcbiAgICBsZXQgeyBzdGFydCwgZW5kIH0gPSByYW5nZTA7XG4gICAgbGV0IG5ld1JhbmdlID0gbnVsbDtcbiAgICBpZiAocmFuZ2UxLnN0YXJ0ICE9PSBudWxsKSB7XG4gICAgICAgIGlmIChzdGFydCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgc3RhcnQgPSByYW5nZTEuc3RhcnQ7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBzdGFydCA9IG5ldyBEYXRlKE1hdGgubWF4KHN0YXJ0LnZhbHVlT2YoKSwgcmFuZ2UxLnN0YXJ0LnZhbHVlT2YoKSkpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChyYW5nZTEuZW5kICE9IG51bGwpIHtcbiAgICAgICAgaWYgKGVuZCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgZW5kID0gcmFuZ2UxLmVuZDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGVuZCA9IG5ldyBEYXRlKE1hdGgubWluKGVuZC52YWx1ZU9mKCksIHJhbmdlMS5lbmQudmFsdWVPZigpKSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKHN0YXJ0ID09PSBudWxsIHx8IGVuZCA9PT0gbnVsbCB8fCBzdGFydCA8IGVuZCkge1xuICAgICAgICBuZXdSYW5nZSA9IHsgc3RhcnQsIGVuZCB9O1xuICAgIH1cbiAgICByZXR1cm4gbmV3UmFuZ2U7XG59XG5mdW5jdGlvbiByYW5nZXNFcXVhbChyYW5nZTAsIHJhbmdlMSkge1xuICAgIHJldHVybiAocmFuZ2UwLnN0YXJ0ID09PSBudWxsID8gbnVsbCA6IHJhbmdlMC5zdGFydC52YWx1ZU9mKCkpID09PSAocmFuZ2UxLnN0YXJ0ID09PSBudWxsID8gbnVsbCA6IHJhbmdlMS5zdGFydC52YWx1ZU9mKCkpICYmXG4gICAgICAgIChyYW5nZTAuZW5kID09PSBudWxsID8gbnVsbCA6IHJhbmdlMC5lbmQudmFsdWVPZigpKSA9PT0gKHJhbmdlMS5lbmQgPT09IG51bGwgPyBudWxsIDogcmFuZ2UxLmVuZC52YWx1ZU9mKCkpO1xufVxuZnVuY3Rpb24gcmFuZ2VzSW50ZXJzZWN0KHJhbmdlMCwgcmFuZ2UxKSB7XG4gICAgcmV0dXJuIChyYW5nZTAuZW5kID09PSBudWxsIHx8IHJhbmdlMS5zdGFydCA9PT0gbnVsbCB8fCByYW5nZTAuZW5kID4gcmFuZ2UxLnN0YXJ0KSAmJlxuICAgICAgICAocmFuZ2UwLnN0YXJ0ID09PSBudWxsIHx8IHJhbmdlMS5lbmQgPT09IG51bGwgfHwgcmFuZ2UwLnN0YXJ0IDwgcmFuZ2UxLmVuZCk7XG59XG5mdW5jdGlvbiByYW5nZUNvbnRhaW5zUmFuZ2Uob3V0ZXJSYW5nZSwgaW5uZXJSYW5nZSkge1xuICAgIHJldHVybiAob3V0ZXJSYW5nZS5zdGFydCA9PT0gbnVsbCB8fCAoaW5uZXJSYW5nZS5zdGFydCAhPT0gbnVsbCAmJiBpbm5lclJhbmdlLnN0YXJ0ID49IG91dGVyUmFuZ2Uuc3RhcnQpKSAmJlxuICAgICAgICAob3V0ZXJSYW5nZS5lbmQgPT09IG51bGwgfHwgKGlubmVyUmFuZ2UuZW5kICE9PSBudWxsICYmIGlubmVyUmFuZ2UuZW5kIDw9IG91dGVyUmFuZ2UuZW5kKSk7XG59XG5mdW5jdGlvbiByYW5nZUNvbnRhaW5zTWFya2VyKHJhbmdlLCBkYXRlKSB7XG4gICAgcmV0dXJuIChyYW5nZS5zdGFydCA9PT0gbnVsbCB8fCBkYXRlID49IHJhbmdlLnN0YXJ0KSAmJlxuICAgICAgICAocmFuZ2UuZW5kID09PSBudWxsIHx8IGRhdGUgPCByYW5nZS5lbmQpO1xufVxuLy8gSWYgdGhlIGdpdmVuIGRhdGUgaXMgbm90IHdpdGhpbiB0aGUgZ2l2ZW4gcmFuZ2UsIG1vdmUgaXQgaW5zaWRlLlxuLy8gKElmIGl0J3MgcGFzdCB0aGUgZW5kLCBtYWtlIGl0IG9uZSBtaWxsaXNlY29uZCBiZWZvcmUgdGhlIGVuZCkuXG5mdW5jdGlvbiBjb25zdHJhaW5NYXJrZXJUb1JhbmdlKGRhdGUsIHJhbmdlKSB7XG4gICAgaWYgKHJhbmdlLnN0YXJ0ICE9IG51bGwgJiYgZGF0ZSA8IHJhbmdlLnN0YXJ0KSB7XG4gICAgICAgIHJldHVybiByYW5nZS5zdGFydDtcbiAgICB9XG4gICAgaWYgKHJhbmdlLmVuZCAhPSBudWxsICYmIGRhdGUgPj0gcmFuZ2UuZW5kKSB7XG4gICAgICAgIHJldHVybiBuZXcgRGF0ZShyYW5nZS5lbmQudmFsdWVPZigpIC0gMSk7XG4gICAgfVxuICAgIHJldHVybiBkYXRlO1xufVxuXG5mdW5jdGlvbiBnZXREYXRlTWV0YShkYXRlLCB0b2RheVJhbmdlLCBub3dEYXRlLCBkYXRlUHJvZmlsZSkge1xuICAgIHJldHVybiB7XG4gICAgICAgIGRvdzogZGF0ZS5nZXRVVENEYXkoKSxcbiAgICAgICAgaXNEaXNhYmxlZDogQm9vbGVhbihkYXRlUHJvZmlsZSAmJiAhcmFuZ2VDb250YWluc01hcmtlcihkYXRlUHJvZmlsZS5hY3RpdmVSYW5nZSwgZGF0ZSkpLFxuICAgICAgICBpc090aGVyOiBCb29sZWFuKGRhdGVQcm9maWxlICYmICFyYW5nZUNvbnRhaW5zTWFya2VyKGRhdGVQcm9maWxlLmN1cnJlbnRSYW5nZSwgZGF0ZSkpLFxuICAgICAgICBpc1RvZGF5OiBCb29sZWFuKHRvZGF5UmFuZ2UgJiYgcmFuZ2VDb250YWluc01hcmtlcih0b2RheVJhbmdlLCBkYXRlKSksXG4gICAgICAgIGlzUGFzdDogQm9vbGVhbihub3dEYXRlID8gKGRhdGUgPCBub3dEYXRlKSA6IHRvZGF5UmFuZ2UgPyAoZGF0ZSA8IHRvZGF5UmFuZ2Uuc3RhcnQpIDogZmFsc2UpLFxuICAgICAgICBpc0Z1dHVyZTogQm9vbGVhbihub3dEYXRlID8gKGRhdGUgPiBub3dEYXRlKSA6IHRvZGF5UmFuZ2UgPyAoZGF0ZSA+PSB0b2RheVJhbmdlLmVuZCkgOiBmYWxzZSksXG4gICAgfTtcbn1cbmZ1bmN0aW9uIGdldERheUNsYXNzTmFtZXMobWV0YSwgdGhlbWUpIHtcbiAgICBsZXQgY2xhc3NOYW1lcyA9IFtcbiAgICAgICAgJ2ZjLWRheScsXG4gICAgICAgIGBmYy1kYXktJHtEQVlfSURTW21ldGEuZG93XX1gLFxuICAgIF07XG4gICAgaWYgKG1ldGEuaXNEaXNhYmxlZCkge1xuICAgICAgICBjbGFzc05hbWVzLnB1c2goJ2ZjLWRheS1kaXNhYmxlZCcpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgaWYgKG1ldGEuaXNUb2RheSkge1xuICAgICAgICAgICAgY2xhc3NOYW1lcy5wdXNoKCdmYy1kYXktdG9kYXknKTtcbiAgICAgICAgICAgIGNsYXNzTmFtZXMucHVzaCh0aGVtZS5nZXRDbGFzcygndG9kYXknKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1ldGEuaXNQYXN0KSB7XG4gICAgICAgICAgICBjbGFzc05hbWVzLnB1c2goJ2ZjLWRheS1wYXN0Jyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1ldGEuaXNGdXR1cmUpIHtcbiAgICAgICAgICAgIGNsYXNzTmFtZXMucHVzaCgnZmMtZGF5LWZ1dHVyZScpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChtZXRhLmlzT3RoZXIpIHtcbiAgICAgICAgICAgIGNsYXNzTmFtZXMucHVzaCgnZmMtZGF5LW90aGVyJyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGNsYXNzTmFtZXM7XG59XG5mdW5jdGlvbiBnZXRTbG90Q2xhc3NOYW1lcyhtZXRhLCB0aGVtZSkge1xuICAgIGxldCBjbGFzc05hbWVzID0gW1xuICAgICAgICAnZmMtc2xvdCcsXG4gICAgICAgIGBmYy1zbG90LSR7REFZX0lEU1ttZXRhLmRvd119YCxcbiAgICBdO1xuICAgIGlmIChtZXRhLmlzRGlzYWJsZWQpIHtcbiAgICAgICAgY2xhc3NOYW1lcy5wdXNoKCdmYy1zbG90LWRpc2FibGVkJyk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICBpZiAobWV0YS5pc1RvZGF5KSB7XG4gICAgICAgICAgICBjbGFzc05hbWVzLnB1c2goJ2ZjLXNsb3QtdG9kYXknKTtcbiAgICAgICAgICAgIGNsYXNzTmFtZXMucHVzaCh0aGVtZS5nZXRDbGFzcygndG9kYXknKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1ldGEuaXNQYXN0KSB7XG4gICAgICAgICAgICBjbGFzc05hbWVzLnB1c2goJ2ZjLXNsb3QtcGFzdCcpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChtZXRhLmlzRnV0dXJlKSB7XG4gICAgICAgICAgICBjbGFzc05hbWVzLnB1c2goJ2ZjLXNsb3QtZnV0dXJlJyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGNsYXNzTmFtZXM7XG59XG5cbmNvbnN0IERBWV9GT1JNQVQgPSBjcmVhdGVGb3JtYXR0ZXIoeyB5ZWFyOiAnbnVtZXJpYycsIG1vbnRoOiAnbG9uZycsIGRheTogJ251bWVyaWMnIH0pO1xuY29uc3QgV0VFS19GT1JNQVQgPSBjcmVhdGVGb3JtYXR0ZXIoeyB3ZWVrOiAnbG9uZycgfSk7XG5mdW5jdGlvbiBidWlsZE5hdkxpbmtBdHRycyhjb250ZXh0LCBkYXRlTWFya2VyLCB2aWV3VHlwZSA9ICdkYXknLCBpc1RhYmJhYmxlID0gdHJ1ZSkge1xuICAgIGNvbnN0IHsgZGF0ZUVudiwgb3B0aW9ucywgY2FsZW5kYXJBcGkgfSA9IGNvbnRleHQ7XG4gICAgbGV0IGRhdGVTdHIgPSBkYXRlRW52LmZvcm1hdChkYXRlTWFya2VyLCB2aWV3VHlwZSA9PT0gJ3dlZWsnID8gV0VFS19GT1JNQVQgOiBEQVlfRk9STUFUKTtcbiAgICBpZiAob3B0aW9ucy5uYXZMaW5rcykge1xuICAgICAgICBsZXQgem9uZWREYXRlID0gZGF0ZUVudi50b0RhdGUoZGF0ZU1hcmtlcik7XG4gICAgICAgIGNvbnN0IGhhbmRsZUludGVyYWN0aW9uID0gKGV2KSA9PiB7XG4gICAgICAgICAgICBsZXQgY3VzdG9tQWN0aW9uID0gdmlld1R5cGUgPT09ICdkYXknID8gb3B0aW9ucy5uYXZMaW5rRGF5Q2xpY2sgOlxuICAgICAgICAgICAgICAgIHZpZXdUeXBlID09PSAnd2VlaycgPyBvcHRpb25zLm5hdkxpbmtXZWVrQ2xpY2sgOiBudWxsO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBjdXN0b21BY3Rpb24gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICBjdXN0b21BY3Rpb24uY2FsbChjYWxlbmRhckFwaSwgZGF0ZUVudi50b0RhdGUoZGF0ZU1hcmtlciksIGV2KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgY3VzdG9tQWN0aW9uID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgICAgICB2aWV3VHlwZSA9IGN1c3RvbUFjdGlvbjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FsZW5kYXJBcGkuem9vbVRvKGRhdGVNYXJrZXIsIHZpZXdUeXBlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oeyB0aXRsZTogZm9ybWF0V2l0aE9yZGluYWxzKG9wdGlvbnMubmF2TGlua0hpbnQsIFtkYXRlU3RyLCB6b25lZERhdGVdLCBkYXRlU3RyKSwgJ2RhdGEtbmF2bGluayc6ICcnIH0sIChpc1RhYmJhYmxlXG4gICAgICAgICAgICA/IGNyZWF0ZUFyaWFDbGlja0F0dHJzKGhhbmRsZUludGVyYWN0aW9uKVxuICAgICAgICAgICAgOiB7IG9uQ2xpY2s6IGhhbmRsZUludGVyYWN0aW9uIH0pKTtcbiAgICB9XG4gICAgcmV0dXJuIHsgJ2FyaWEtbGFiZWwnOiBkYXRlU3RyIH07XG59XG5cbmxldCBfaXNSdGxTY3JvbGxiYXJPbkxlZnQgPSBudWxsO1xuZnVuY3Rpb24gZ2V0SXNSdGxTY3JvbGxiYXJPbkxlZnQoKSB7XG4gICAgaWYgKF9pc1J0bFNjcm9sbGJhck9uTGVmdCA9PT0gbnVsbCkge1xuICAgICAgICBfaXNSdGxTY3JvbGxiYXJPbkxlZnQgPSBjb21wdXRlSXNSdGxTY3JvbGxiYXJPbkxlZnQoKTtcbiAgICB9XG4gICAgcmV0dXJuIF9pc1J0bFNjcm9sbGJhck9uTGVmdDtcbn1cbmZ1bmN0aW9uIGNvbXB1dGVJc1J0bFNjcm9sbGJhck9uTGVmdCgpIHtcbiAgICBsZXQgb3V0ZXJFbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIGFwcGx5U3R5bGUob3V0ZXJFbCwge1xuICAgICAgICBwb3NpdGlvbjogJ2Fic29sdXRlJyxcbiAgICAgICAgdG9wOiAtMTAwMCxcbiAgICAgICAgbGVmdDogMCxcbiAgICAgICAgYm9yZGVyOiAwLFxuICAgICAgICBwYWRkaW5nOiAwLFxuICAgICAgICBvdmVyZmxvdzogJ3Njcm9sbCcsXG4gICAgICAgIGRpcmVjdGlvbjogJ3J0bCcsXG4gICAgfSk7XG4gICAgb3V0ZXJFbC5pbm5lckhUTUwgPSAnPGRpdj48L2Rpdj4nO1xuICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQob3V0ZXJFbCk7XG4gICAgbGV0IGlubmVyRWwgPSBvdXRlckVsLmZpcnN0Q2hpbGQ7XG4gICAgbGV0IHJlcyA9IGlubmVyRWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkubGVmdCA+IG91dGVyRWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkubGVmdDtcbiAgICByZW1vdmVFbGVtZW50KG91dGVyRWwpO1xuICAgIHJldHVybiByZXM7XG59XG5cbmxldCBfc2Nyb2xsYmFyV2lkdGhzO1xuZnVuY3Rpb24gZ2V0U2Nyb2xsYmFyV2lkdGhzKCkge1xuICAgIGlmICghX3Njcm9sbGJhcldpZHRocykge1xuICAgICAgICBfc2Nyb2xsYmFyV2lkdGhzID0gY29tcHV0ZVNjcm9sbGJhcldpZHRocygpO1xuICAgIH1cbiAgICByZXR1cm4gX3Njcm9sbGJhcldpZHRocztcbn1cbmZ1bmN0aW9uIGNvbXB1dGVTY3JvbGxiYXJXaWR0aHMoKSB7XG4gICAgbGV0IGVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgZWwuc3R5bGUub3ZlcmZsb3cgPSAnc2Nyb2xsJztcbiAgICBlbC5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7XG4gICAgZWwuc3R5bGUudG9wID0gJy05OTk5cHgnO1xuICAgIGVsLnN0eWxlLmxlZnQgPSAnLTk5OTlweCc7XG4gICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChlbCk7XG4gICAgbGV0IHJlcyA9IGNvbXB1dGVTY3JvbGxiYXJXaWR0aHNGb3JFbChlbCk7XG4gICAgZG9jdW1lbnQuYm9keS5yZW1vdmVDaGlsZChlbCk7XG4gICAgcmV0dXJuIHJlcztcbn1cbi8vIFdBUk5JTkc6IHdpbGwgaW5jbHVkZSBib3JkZXJcbmZ1bmN0aW9uIGNvbXB1dGVTY3JvbGxiYXJXaWR0aHNGb3JFbChlbCkge1xuICAgIHJldHVybiB7XG4gICAgICAgIHg6IGVsLm9mZnNldEhlaWdodCAtIGVsLmNsaWVudEhlaWdodCxcbiAgICAgICAgeTogZWwub2Zmc2V0V2lkdGggLSBlbC5jbGllbnRXaWR0aCxcbiAgICB9O1xufVxuXG5mdW5jdGlvbiBjb21wdXRlRWRnZXMoZWwsIGdldFBhZGRpbmcgPSBmYWxzZSkge1xuICAgIGxldCBjb21wdXRlZFN0eWxlID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUoZWwpO1xuICAgIGxldCBib3JkZXJMZWZ0ID0gcGFyc2VJbnQoY29tcHV0ZWRTdHlsZS5ib3JkZXJMZWZ0V2lkdGgsIDEwKSB8fCAwO1xuICAgIGxldCBib3JkZXJSaWdodCA9IHBhcnNlSW50KGNvbXB1dGVkU3R5bGUuYm9yZGVyUmlnaHRXaWR0aCwgMTApIHx8IDA7XG4gICAgbGV0IGJvcmRlclRvcCA9IHBhcnNlSW50KGNvbXB1dGVkU3R5bGUuYm9yZGVyVG9wV2lkdGgsIDEwKSB8fCAwO1xuICAgIGxldCBib3JkZXJCb3R0b20gPSBwYXJzZUludChjb21wdXRlZFN0eWxlLmJvcmRlckJvdHRvbVdpZHRoLCAxMCkgfHwgMDtcbiAgICBsZXQgYmFkU2Nyb2xsYmFyV2lkdGhzID0gY29tcHV0ZVNjcm9sbGJhcldpZHRoc0ZvckVsKGVsKTsgLy8gaW5jbHVkZXMgYm9yZGVyIVxuICAgIGxldCBzY3JvbGxiYXJMZWZ0UmlnaHQgPSBiYWRTY3JvbGxiYXJXaWR0aHMueSAtIGJvcmRlckxlZnQgLSBib3JkZXJSaWdodDtcbiAgICBsZXQgc2Nyb2xsYmFyQm90dG9tID0gYmFkU2Nyb2xsYmFyV2lkdGhzLnggLSBib3JkZXJUb3AgLSBib3JkZXJCb3R0b207XG4gICAgbGV0IHJlcyA9IHtcbiAgICAgICAgYm9yZGVyTGVmdCxcbiAgICAgICAgYm9yZGVyUmlnaHQsXG4gICAgICAgIGJvcmRlclRvcCxcbiAgICAgICAgYm9yZGVyQm90dG9tLFxuICAgICAgICBzY3JvbGxiYXJCb3R0b20sXG4gICAgICAgIHNjcm9sbGJhckxlZnQ6IDAsXG4gICAgICAgIHNjcm9sbGJhclJpZ2h0OiAwLFxuICAgIH07XG4gICAgaWYgKGdldElzUnRsU2Nyb2xsYmFyT25MZWZ0KCkgJiYgY29tcHV0ZWRTdHlsZS5kaXJlY3Rpb24gPT09ICdydGwnKSB7IC8vIGlzIHRoZSBzY3JvbGxiYXIgb24gdGhlIGxlZnQgc2lkZT9cbiAgICAgICAgcmVzLnNjcm9sbGJhckxlZnQgPSBzY3JvbGxiYXJMZWZ0UmlnaHQ7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICByZXMuc2Nyb2xsYmFyUmlnaHQgPSBzY3JvbGxiYXJMZWZ0UmlnaHQ7XG4gICAgfVxuICAgIGlmIChnZXRQYWRkaW5nKSB7XG4gICAgICAgIHJlcy5wYWRkaW5nTGVmdCA9IHBhcnNlSW50KGNvbXB1dGVkU3R5bGUucGFkZGluZ0xlZnQsIDEwKSB8fCAwO1xuICAgICAgICByZXMucGFkZGluZ1JpZ2h0ID0gcGFyc2VJbnQoY29tcHV0ZWRTdHlsZS5wYWRkaW5nUmlnaHQsIDEwKSB8fCAwO1xuICAgICAgICByZXMucGFkZGluZ1RvcCA9IHBhcnNlSW50KGNvbXB1dGVkU3R5bGUucGFkZGluZ1RvcCwgMTApIHx8IDA7XG4gICAgICAgIHJlcy5wYWRkaW5nQm90dG9tID0gcGFyc2VJbnQoY29tcHV0ZWRTdHlsZS5wYWRkaW5nQm90dG9tLCAxMCkgfHwgMDtcbiAgICB9XG4gICAgcmV0dXJuIHJlcztcbn1cbmZ1bmN0aW9uIGNvbXB1dGVJbm5lclJlY3QoZWwsIGdvV2l0aGluUGFkZGluZyA9IGZhbHNlLCBkb0Zyb21XaW5kb3dWaWV3cG9ydCkge1xuICAgIGxldCBvdXRlclJlY3QgPSBkb0Zyb21XaW5kb3dWaWV3cG9ydCA/IGVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpIDogY29tcHV0ZVJlY3QoZWwpO1xuICAgIGxldCBlZGdlcyA9IGNvbXB1dGVFZGdlcyhlbCwgZ29XaXRoaW5QYWRkaW5nKTtcbiAgICBsZXQgcmVzID0ge1xuICAgICAgICBsZWZ0OiBvdXRlclJlY3QubGVmdCArIGVkZ2VzLmJvcmRlckxlZnQgKyBlZGdlcy5zY3JvbGxiYXJMZWZ0LFxuICAgICAgICByaWdodDogb3V0ZXJSZWN0LnJpZ2h0IC0gZWRnZXMuYm9yZGVyUmlnaHQgLSBlZGdlcy5zY3JvbGxiYXJSaWdodCxcbiAgICAgICAgdG9wOiBvdXRlclJlY3QudG9wICsgZWRnZXMuYm9yZGVyVG9wLFxuICAgICAgICBib3R0b206IG91dGVyUmVjdC5ib3R0b20gLSBlZGdlcy5ib3JkZXJCb3R0b20gLSBlZGdlcy5zY3JvbGxiYXJCb3R0b20sXG4gICAgfTtcbiAgICBpZiAoZ29XaXRoaW5QYWRkaW5nKSB7XG4gICAgICAgIHJlcy5sZWZ0ICs9IGVkZ2VzLnBhZGRpbmdMZWZ0O1xuICAgICAgICByZXMucmlnaHQgLT0gZWRnZXMucGFkZGluZ1JpZ2h0O1xuICAgICAgICByZXMudG9wICs9IGVkZ2VzLnBhZGRpbmdUb3A7XG4gICAgICAgIHJlcy5ib3R0b20gLT0gZWRnZXMucGFkZGluZ0JvdHRvbTtcbiAgICB9XG4gICAgcmV0dXJuIHJlcztcbn1cbmZ1bmN0aW9uIGNvbXB1dGVSZWN0KGVsKSB7XG4gICAgbGV0IHJlY3QgPSBlbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBsZWZ0OiByZWN0LmxlZnQgKyB3aW5kb3cucGFnZVhPZmZzZXQsXG4gICAgICAgIHRvcDogcmVjdC50b3AgKyB3aW5kb3cucGFnZVlPZmZzZXQsXG4gICAgICAgIHJpZ2h0OiByZWN0LnJpZ2h0ICsgd2luZG93LnBhZ2VYT2Zmc2V0LFxuICAgICAgICBib3R0b206IHJlY3QuYm90dG9tICsgd2luZG93LnBhZ2VZT2Zmc2V0LFxuICAgIH07XG59XG5mdW5jdGlvbiBjb21wdXRlQ2xpcHBlZENsaWVudFJlY3QoZWwpIHtcbiAgICBsZXQgY2xpcHBpbmdQYXJlbnRzID0gZ2V0Q2xpcHBpbmdQYXJlbnRzKGVsKTtcbiAgICBsZXQgcmVjdCA9IGVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIGZvciAobGV0IGNsaXBwaW5nUGFyZW50IG9mIGNsaXBwaW5nUGFyZW50cykge1xuICAgICAgICBsZXQgaW50ZXJzZWN0aW9uID0gaW50ZXJzZWN0UmVjdHMocmVjdCwgY2xpcHBpbmdQYXJlbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkpO1xuICAgICAgICBpZiAoaW50ZXJzZWN0aW9uKSB7XG4gICAgICAgICAgICByZWN0ID0gaW50ZXJzZWN0aW9uO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlY3Q7XG59XG4vLyBkb2VzIG5vdCByZXR1cm4gd2luZG93XG5mdW5jdGlvbiBnZXRDbGlwcGluZ1BhcmVudHMoZWwpIHtcbiAgICBsZXQgcGFyZW50cyA9IFtdO1xuICAgIHdoaWxlIChlbCBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSB7IC8vIHdpbGwgc3RvcCB3aGVuIGdldHMgdG8gZG9jdW1lbnQgb3IgbnVsbFxuICAgICAgICBsZXQgY29tcHV0ZWRTdHlsZSA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGVsKTtcbiAgICAgICAgaWYgKGNvbXB1dGVkU3R5bGUucG9zaXRpb24gPT09ICdmaXhlZCcpIHtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGlmICgoLyhhdXRvfHNjcm9sbCkvKS50ZXN0KGNvbXB1dGVkU3R5bGUub3ZlcmZsb3cgKyBjb21wdXRlZFN0eWxlLm92ZXJmbG93WSArIGNvbXB1dGVkU3R5bGUub3ZlcmZsb3dYKSkge1xuICAgICAgICAgICAgcGFyZW50cy5wdXNoKGVsKTtcbiAgICAgICAgfVxuICAgICAgICBlbCA9IGVsLnBhcmVudE5vZGU7XG4gICAgfVxuICAgIHJldHVybiBwYXJlbnRzO1xufVxuXG4vKlxuZ2l2ZW4gYSBmdW5jdGlvbiB0aGF0IHJlc29sdmVzIGEgcmVzdWx0IGFzeW5jaHJvbm91c2x5LlxudGhlIGZ1bmN0aW9uIGNhbiBlaXRoZXIgY2FsbCBwYXNzZWQtaW4gc3VjY2VzcyBhbmQgZmFpbHVyZSBjYWxsYmFja3MsXG5vciBpdCBjYW4gcmV0dXJuIGEgcHJvbWlzZS5cbmlmIHlvdSBuZWVkIHRvIHBhc3MgYWRkaXRpb25hbCBwYXJhbXMgdG8gZnVuYywgYmluZCB0aGVtIGZpcnN0LlxuKi9cbmZ1bmN0aW9uIHVucHJvbWlzaWZ5KGZ1bmMsIG5vcm1hbGl6ZWRTdWNjZXNzQ2FsbGJhY2ssIG5vcm1hbGl6ZWRGYWlsdXJlQ2FsbGJhY2spIHtcbiAgICAvLyBndWFyZCBhZ2FpbnN0IHN1Y2Nlc3MvZmFpbHVyZSBjYWxsYmFja3MgYmVpbmcgY2FsbGVkIG1vcmUgdGhhbiBvbmNlXG4gICAgLy8gYW5kIGd1YXJkIGFnYWluc3QgYSBwcm9taXNlIEFORCBjYWxsYmFjayBiZWluZyB1c2VkIHRvZ2V0aGVyLlxuICAgIGxldCBpc1Jlc29sdmVkID0gZmFsc2U7XG4gICAgbGV0IHdyYXBwZWRTdWNjZXNzID0gZnVuY3Rpb24gKHJlcykge1xuICAgICAgICBpZiAoIWlzUmVzb2x2ZWQpIHtcbiAgICAgICAgICAgIGlzUmVzb2x2ZWQgPSB0cnVlO1xuICAgICAgICAgICAgbm9ybWFsaXplZFN1Y2Nlc3NDYWxsYmFjayhyZXMpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBsZXQgd3JhcHBlZEZhaWx1cmUgPSBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgaWYgKCFpc1Jlc29sdmVkKSB7XG4gICAgICAgICAgICBpc1Jlc29sdmVkID0gdHJ1ZTtcbiAgICAgICAgICAgIG5vcm1hbGl6ZWRGYWlsdXJlQ2FsbGJhY2soZXJyb3IpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBsZXQgcmVzID0gZnVuYyh3cmFwcGVkU3VjY2Vzcywgd3JhcHBlZEZhaWx1cmUpO1xuICAgIGlmIChyZXMgJiYgdHlwZW9mIHJlcy50aGVuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHJlcy50aGVuKHdyYXBwZWRTdWNjZXNzLCB3cmFwcGVkRmFpbHVyZSk7XG4gICAgfVxufVxuXG5jbGFzcyBFbWl0dGVyIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5oYW5kbGVycyA9IHt9O1xuICAgICAgICB0aGlzLnRoaXNDb250ZXh0ID0gbnVsbDtcbiAgICB9XG4gICAgc2V0VGhpc0NvbnRleHQodGhpc0NvbnRleHQpIHtcbiAgICAgICAgdGhpcy50aGlzQ29udGV4dCA9IHRoaXNDb250ZXh0O1xuICAgIH1cbiAgICBzZXRPcHRpb25zKG9wdGlvbnMpIHtcbiAgICAgICAgdGhpcy5vcHRpb25zID0gb3B0aW9ucztcbiAgICB9XG4gICAgb24odHlwZSwgaGFuZGxlcikge1xuICAgICAgICBhZGRUb0hhc2godGhpcy5oYW5kbGVycywgdHlwZSwgaGFuZGxlcik7XG4gICAgfVxuICAgIG9mZih0eXBlLCBoYW5kbGVyKSB7XG4gICAgICAgIHJlbW92ZUZyb21IYXNoKHRoaXMuaGFuZGxlcnMsIHR5cGUsIGhhbmRsZXIpO1xuICAgIH1cbiAgICB0cmlnZ2VyKHR5cGUsIC4uLmFyZ3MpIHtcbiAgICAgICAgbGV0IGF0dGFjaGVkSGFuZGxlcnMgPSB0aGlzLmhhbmRsZXJzW3R5cGVdIHx8IFtdO1xuICAgICAgICBsZXQgb3B0aW9uSGFuZGxlciA9IHRoaXMub3B0aW9ucyAmJiB0aGlzLm9wdGlvbnNbdHlwZV07XG4gICAgICAgIGxldCBoYW5kbGVycyA9IFtdLmNvbmNhdChvcHRpb25IYW5kbGVyIHx8IFtdLCBhdHRhY2hlZEhhbmRsZXJzKTtcbiAgICAgICAgZm9yIChsZXQgaGFuZGxlciBvZiBoYW5kbGVycykge1xuICAgICAgICAgICAgaGFuZGxlci5hcHBseSh0aGlzLnRoaXNDb250ZXh0LCBhcmdzKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBoYXNIYW5kbGVycyh0eXBlKSB7XG4gICAgICAgIHJldHVybiBCb29sZWFuKCh0aGlzLmhhbmRsZXJzW3R5cGVdICYmIHRoaXMuaGFuZGxlcnNbdHlwZV0ubGVuZ3RoKSB8fFxuICAgICAgICAgICAgKHRoaXMub3B0aW9ucyAmJiB0aGlzLm9wdGlvbnNbdHlwZV0pKTtcbiAgICB9XG59XG5mdW5jdGlvbiBhZGRUb0hhc2goaGFzaCwgdHlwZSwgaGFuZGxlcikge1xuICAgIChoYXNoW3R5cGVdIHx8IChoYXNoW3R5cGVdID0gW10pKVxuICAgICAgICAucHVzaChoYW5kbGVyKTtcbn1cbmZ1bmN0aW9uIHJlbW92ZUZyb21IYXNoKGhhc2gsIHR5cGUsIGhhbmRsZXIpIHtcbiAgICBpZiAoaGFuZGxlcikge1xuICAgICAgICBpZiAoaGFzaFt0eXBlXSkge1xuICAgICAgICAgICAgaGFzaFt0eXBlXSA9IGhhc2hbdHlwZV0uZmlsdGVyKChmdW5jKSA9PiBmdW5jICE9PSBoYW5kbGVyKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgZGVsZXRlIGhhc2hbdHlwZV07IC8vIHJlbW92ZSBhbGwgaGFuZGxlciBmdW5jcyBmb3IgdGhpcyB0eXBlXG4gICAgfVxufVxuXG4vKlxuUmVjb3JkcyBvZmZzZXQgaW5mb3JtYXRpb24gZm9yIGEgc2V0IG9mIGVsZW1lbnRzLCByZWxhdGl2ZSB0byBhbiBvcmlnaW4gZWxlbWVudC5cbkNhbiByZWNvcmQgdGhlIGxlZnQvcmlnaHQgT1IgdGhlIHRvcC9ib3R0b20gT1IgYm90aC5cblByb3ZpZGVzIG1ldGhvZHMgZm9yIHF1ZXJ5aW5nIHRoZSBjYWNoZSBieSBwb3NpdGlvbi5cbiovXG5jbGFzcyBQb3NpdGlvbkNhY2hlIHtcbiAgICBjb25zdHJ1Y3RvcihvcmlnaW5FbCwgZWxzLCBpc0hvcml6b250YWwsIGlzVmVydGljYWwpIHtcbiAgICAgICAgdGhpcy5lbHMgPSBlbHM7XG4gICAgICAgIGxldCBvcmlnaW5DbGllbnRSZWN0ID0gdGhpcy5vcmlnaW5DbGllbnRSZWN0ID0gb3JpZ2luRWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7IC8vIHJlbGF0aXZlIHRvIHZpZXdwb3J0IHRvcC1sZWZ0XG4gICAgICAgIGlmIChpc0hvcml6b250YWwpIHtcbiAgICAgICAgICAgIHRoaXMuYnVpbGRFbEhvcml6b250YWxzKG9yaWdpbkNsaWVudFJlY3QubGVmdCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzVmVydGljYWwpIHtcbiAgICAgICAgICAgIHRoaXMuYnVpbGRFbFZlcnRpY2FscyhvcmlnaW5DbGllbnRSZWN0LnRvcCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLy8gUG9wdWxhdGVzIHRoZSBsZWZ0L3JpZ2h0IGludGVybmFsIGNvb3JkaW5hdGUgYXJyYXlzXG4gICAgYnVpbGRFbEhvcml6b250YWxzKG9yaWdpbkNsaWVudExlZnQpIHtcbiAgICAgICAgbGV0IGxlZnRzID0gW107XG4gICAgICAgIGxldCByaWdodHMgPSBbXTtcbiAgICAgICAgZm9yIChsZXQgZWwgb2YgdGhpcy5lbHMpIHtcbiAgICAgICAgICAgIGxldCByZWN0ID0gZWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICAgICAgICBsZWZ0cy5wdXNoKHJlY3QubGVmdCAtIG9yaWdpbkNsaWVudExlZnQpO1xuICAgICAgICAgICAgcmlnaHRzLnB1c2gocmVjdC5yaWdodCAtIG9yaWdpbkNsaWVudExlZnQpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMubGVmdHMgPSBsZWZ0cztcbiAgICAgICAgdGhpcy5yaWdodHMgPSByaWdodHM7XG4gICAgfVxuICAgIC8vIFBvcHVsYXRlcyB0aGUgdG9wL2JvdHRvbSBpbnRlcm5hbCBjb29yZGluYXRlIGFycmF5c1xuICAgIGJ1aWxkRWxWZXJ0aWNhbHMob3JpZ2luQ2xpZW50VG9wKSB7XG4gICAgICAgIGxldCB0b3BzID0gW107XG4gICAgICAgIGxldCBib3R0b21zID0gW107XG4gICAgICAgIGZvciAobGV0IGVsIG9mIHRoaXMuZWxzKSB7XG4gICAgICAgICAgICBsZXQgcmVjdCA9IGVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgICAgICAgdG9wcy5wdXNoKHJlY3QudG9wIC0gb3JpZ2luQ2xpZW50VG9wKTtcbiAgICAgICAgICAgIGJvdHRvbXMucHVzaChyZWN0LmJvdHRvbSAtIG9yaWdpbkNsaWVudFRvcCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy50b3BzID0gdG9wcztcbiAgICAgICAgdGhpcy5ib3R0b21zID0gYm90dG9tcztcbiAgICB9XG4gICAgLy8gR2l2ZW4gYSBsZWZ0IG9mZnNldCAoZnJvbSBkb2N1bWVudCBsZWZ0KSwgcmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIGVsIHRoYXQgaXQgaG9yaXpvbnRhbGx5IGludGVyc2VjdHMuXG4gICAgLy8gSWYgbm8gaW50ZXJzZWN0aW9uIGlzIG1hZGUsIHJldHVybnMgdW5kZWZpbmVkLlxuICAgIGxlZnRUb0luZGV4KGxlZnRQb3NpdGlvbikge1xuICAgICAgICBsZXQgeyBsZWZ0cywgcmlnaHRzIH0gPSB0aGlzO1xuICAgICAgICBsZXQgbGVuID0gbGVmdHMubGVuZ3RoO1xuICAgICAgICBsZXQgaTtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSArPSAxKSB7XG4gICAgICAgICAgICBpZiAobGVmdFBvc2l0aW9uID49IGxlZnRzW2ldICYmIGxlZnRQb3NpdGlvbiA8IHJpZ2h0c1tpXSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7IC8vIFRPRE86IGJldHRlclxuICAgIH1cbiAgICAvLyBHaXZlbiBhIHRvcCBvZmZzZXQgKGZyb20gZG9jdW1lbnQgdG9wKSwgcmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIGVsIHRoYXQgaXQgdmVydGljYWxseSBpbnRlcnNlY3RzLlxuICAgIC8vIElmIG5vIGludGVyc2VjdGlvbiBpcyBtYWRlLCByZXR1cm5zIHVuZGVmaW5lZC5cbiAgICB0b3BUb0luZGV4KHRvcFBvc2l0aW9uKSB7XG4gICAgICAgIGxldCB7IHRvcHMsIGJvdHRvbXMgfSA9IHRoaXM7XG4gICAgICAgIGxldCBsZW4gPSB0b3BzLmxlbmd0aDtcbiAgICAgICAgbGV0IGk7XG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkgKz0gMSkge1xuICAgICAgICAgICAgaWYgKHRvcFBvc2l0aW9uID49IHRvcHNbaV0gJiYgdG9wUG9zaXRpb24gPCBib3R0b21zW2ldKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDsgLy8gVE9ETzogYmV0dGVyXG4gICAgfVxuICAgIC8vIEdldHMgdGhlIHdpZHRoIG9mIHRoZSBlbGVtZW50IGF0IHRoZSBnaXZlbiBpbmRleFxuICAgIGdldFdpZHRoKGxlZnRJbmRleCkge1xuICAgICAgICByZXR1cm4gdGhpcy5yaWdodHNbbGVmdEluZGV4XSAtIHRoaXMubGVmdHNbbGVmdEluZGV4XTtcbiAgICB9XG4gICAgLy8gR2V0cyB0aGUgaGVpZ2h0IG9mIHRoZSBlbGVtZW50IGF0IHRoZSBnaXZlbiBpbmRleFxuICAgIGdldEhlaWdodCh0b3BJbmRleCkge1xuICAgICAgICByZXR1cm4gdGhpcy5ib3R0b21zW3RvcEluZGV4XSAtIHRoaXMudG9wc1t0b3BJbmRleF07XG4gICAgfVxuICAgIHNpbWlsYXJUbyhvdGhlckNhY2hlKSB7XG4gICAgICAgIHJldHVybiBzaW1pbGFyTnVtQXJyYXlzKHRoaXMudG9wcyB8fCBbXSwgb3RoZXJDYWNoZS50b3BzIHx8IFtdKSAmJlxuICAgICAgICAgICAgc2ltaWxhck51bUFycmF5cyh0aGlzLmJvdHRvbXMgfHwgW10sIG90aGVyQ2FjaGUuYm90dG9tcyB8fCBbXSkgJiZcbiAgICAgICAgICAgIHNpbWlsYXJOdW1BcnJheXModGhpcy5sZWZ0cyB8fCBbXSwgb3RoZXJDYWNoZS5sZWZ0cyB8fCBbXSkgJiZcbiAgICAgICAgICAgIHNpbWlsYXJOdW1BcnJheXModGhpcy5yaWdodHMgfHwgW10sIG90aGVyQ2FjaGUucmlnaHRzIHx8IFtdKTtcbiAgICB9XG59XG5mdW5jdGlvbiBzaW1pbGFyTnVtQXJyYXlzKGEsIGIpIHtcbiAgICBjb25zdCBsZW4gPSBhLmxlbmd0aDtcbiAgICBpZiAobGVuICE9PSBiLmxlbmd0aCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgaWYgKE1hdGgucm91bmQoYVtpXSkgIT09IE1hdGgucm91bmQoYltpXSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn1cblxuLyogZXNsaW50IG1heC1jbGFzc2VzLXBlci1maWxlOiBcIm9mZlwiICovXG4vKlxuQW4gb2JqZWN0IGZvciBnZXR0aW5nL3NldHRpbmcgc2Nyb2xsLXJlbGF0ZWQgaW5mb3JtYXRpb24gZm9yIGFuIGVsZW1lbnQuXG5JbnRlcm5hbGx5LCB0aGlzIGlzIGRvbmUgdmVyeSBkaWZmZXJlbnRseSBmb3Igd2luZG93IHZlcnN1cyBET00gZWxlbWVudCxcbnNvIHRoaXMgb2JqZWN0IHNlcnZlcyBhcyBhIGNvbW1vbiBpbnRlcmZhY2UuXG4qL1xuY2xhc3MgU2Nyb2xsQ29udHJvbGxlciB7XG4gICAgZ2V0TWF4U2Nyb2xsVG9wKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRTY3JvbGxIZWlnaHQoKSAtIHRoaXMuZ2V0Q2xpZW50SGVpZ2h0KCk7XG4gICAgfVxuICAgIGdldE1heFNjcm9sbExlZnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFNjcm9sbFdpZHRoKCkgLSB0aGlzLmdldENsaWVudFdpZHRoKCk7XG4gICAgfVxuICAgIGNhblNjcm9sbFZlcnRpY2FsbHkoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldE1heFNjcm9sbFRvcCgpID4gMDtcbiAgICB9XG4gICAgY2FuU2Nyb2xsSG9yaXpvbnRhbGx5KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRNYXhTY3JvbGxMZWZ0KCkgPiAwO1xuICAgIH1cbiAgICBjYW5TY3JvbGxVcCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0U2Nyb2xsVG9wKCkgPiAwO1xuICAgIH1cbiAgICBjYW5TY3JvbGxEb3duKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRTY3JvbGxUb3AoKSA8IHRoaXMuZ2V0TWF4U2Nyb2xsVG9wKCk7XG4gICAgfVxuICAgIGNhblNjcm9sbExlZnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldFNjcm9sbExlZnQoKSA+IDA7XG4gICAgfVxuICAgIGNhblNjcm9sbFJpZ2h0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRTY3JvbGxMZWZ0KCkgPCB0aGlzLmdldE1heFNjcm9sbExlZnQoKTtcbiAgICB9XG59XG5jbGFzcyBFbGVtZW50U2Nyb2xsQ29udHJvbGxlciBleHRlbmRzIFNjcm9sbENvbnRyb2xsZXIge1xuICAgIGNvbnN0cnVjdG9yKGVsKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgICAgIHRoaXMuZWwgPSBlbDtcbiAgICB9XG4gICAgZ2V0U2Nyb2xsVG9wKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5lbC5zY3JvbGxUb3A7XG4gICAgfVxuICAgIGdldFNjcm9sbExlZnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVsLnNjcm9sbExlZnQ7XG4gICAgfVxuICAgIHNldFNjcm9sbFRvcCh0b3ApIHtcbiAgICAgICAgdGhpcy5lbC5zY3JvbGxUb3AgPSB0b3A7XG4gICAgfVxuICAgIHNldFNjcm9sbExlZnQobGVmdCkge1xuICAgICAgICB0aGlzLmVsLnNjcm9sbExlZnQgPSBsZWZ0O1xuICAgIH1cbiAgICBnZXRTY3JvbGxXaWR0aCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZWwuc2Nyb2xsV2lkdGg7XG4gICAgfVxuICAgIGdldFNjcm9sbEhlaWdodCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZWwuc2Nyb2xsSGVpZ2h0O1xuICAgIH1cbiAgICBnZXRDbGllbnRIZWlnaHQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVsLmNsaWVudEhlaWdodDtcbiAgICB9XG4gICAgZ2V0Q2xpZW50V2lkdGgoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVsLmNsaWVudFdpZHRoO1xuICAgIH1cbn1cbmNsYXNzIFdpbmRvd1Njcm9sbENvbnRyb2xsZXIgZXh0ZW5kcyBTY3JvbGxDb250cm9sbGVyIHtcbiAgICBnZXRTY3JvbGxUb3AoKSB7XG4gICAgICAgIHJldHVybiB3aW5kb3cucGFnZVlPZmZzZXQ7XG4gICAgfVxuICAgIGdldFNjcm9sbExlZnQoKSB7XG4gICAgICAgIHJldHVybiB3aW5kb3cucGFnZVhPZmZzZXQ7XG4gICAgfVxuICAgIHNldFNjcm9sbFRvcChuKSB7XG4gICAgICAgIHdpbmRvdy5zY3JvbGwod2luZG93LnBhZ2VYT2Zmc2V0LCBuKTtcbiAgICB9XG4gICAgc2V0U2Nyb2xsTGVmdChuKSB7XG4gICAgICAgIHdpbmRvdy5zY3JvbGwobiwgd2luZG93LnBhZ2VZT2Zmc2V0KTtcbiAgICB9XG4gICAgZ2V0U2Nyb2xsV2lkdGgoKSB7XG4gICAgICAgIHJldHVybiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc2Nyb2xsV2lkdGg7XG4gICAgfVxuICAgIGdldFNjcm9sbEhlaWdodCgpIHtcbiAgICAgICAgcmV0dXJuIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxIZWlnaHQ7XG4gICAgfVxuICAgIGdldENsaWVudEhlaWdodCgpIHtcbiAgICAgICAgcmV0dXJuIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRIZWlnaHQ7XG4gICAgfVxuICAgIGdldENsaWVudFdpZHRoKCkge1xuICAgICAgICByZXR1cm4gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudFdpZHRoO1xuICAgIH1cbn1cblxuY2xhc3MgVGhlbWUge1xuICAgIGNvbnN0cnVjdG9yKGNhbGVuZGFyT3B0aW9ucykge1xuICAgICAgICBpZiAodGhpcy5pY29uT3ZlcnJpZGVPcHRpb24pIHtcbiAgICAgICAgICAgIHRoaXMuc2V0SWNvbk92ZXJyaWRlKGNhbGVuZGFyT3B0aW9uc1t0aGlzLmljb25PdmVycmlkZU9wdGlvbl0pO1xuICAgICAgICB9XG4gICAgfVxuICAgIHNldEljb25PdmVycmlkZShpY29uT3ZlcnJpZGVIYXNoKSB7XG4gICAgICAgIGxldCBpY29uQ2xhc3Nlc0NvcHk7XG4gICAgICAgIGxldCBidXR0b25OYW1lO1xuICAgICAgICBpZiAodHlwZW9mIGljb25PdmVycmlkZUhhc2ggPT09ICdvYmplY3QnICYmIGljb25PdmVycmlkZUhhc2gpIHsgLy8gbm9uLW51bGwgb2JqZWN0XG4gICAgICAgICAgICBpY29uQ2xhc3Nlc0NvcHkgPSBPYmplY3QuYXNzaWduKHt9LCB0aGlzLmljb25DbGFzc2VzKTtcbiAgICAgICAgICAgIGZvciAoYnV0dG9uTmFtZSBpbiBpY29uT3ZlcnJpZGVIYXNoKSB7XG4gICAgICAgICAgICAgICAgaWNvbkNsYXNzZXNDb3B5W2J1dHRvbk5hbWVdID0gdGhpcy5hcHBseUljb25PdmVycmlkZVByZWZpeChpY29uT3ZlcnJpZGVIYXNoW2J1dHRvbk5hbWVdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuaWNvbkNsYXNzZXMgPSBpY29uQ2xhc3Nlc0NvcHk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoaWNvbk92ZXJyaWRlSGFzaCA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHRoaXMuaWNvbkNsYXNzZXMgPSB7fTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBhcHBseUljb25PdmVycmlkZVByZWZpeChjbGFzc05hbWUpIHtcbiAgICAgICAgbGV0IHByZWZpeCA9IHRoaXMuaWNvbk92ZXJyaWRlUHJlZml4O1xuICAgICAgICBpZiAocHJlZml4ICYmIGNsYXNzTmFtZS5pbmRleE9mKHByZWZpeCkgIT09IDApIHsgLy8gaWYgbm90IGFscmVhZHkgcHJlc2VudFxuICAgICAgICAgICAgY2xhc3NOYW1lID0gcHJlZml4ICsgY2xhc3NOYW1lO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjbGFzc05hbWU7XG4gICAgfVxuICAgIGdldENsYXNzKGtleSkge1xuICAgICAgICByZXR1cm4gdGhpcy5jbGFzc2VzW2tleV0gfHwgJyc7XG4gICAgfVxuICAgIGdldEljb25DbGFzcyhidXR0b25OYW1lLCBpc1J0bCkge1xuICAgICAgICBsZXQgY2xhc3NOYW1lO1xuICAgICAgICBpZiAoaXNSdGwgJiYgdGhpcy5ydGxJY29uQ2xhc3Nlcykge1xuICAgICAgICAgICAgY2xhc3NOYW1lID0gdGhpcy5ydGxJY29uQ2xhc3Nlc1tidXR0b25OYW1lXSB8fCB0aGlzLmljb25DbGFzc2VzW2J1dHRvbk5hbWVdO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY2xhc3NOYW1lID0gdGhpcy5pY29uQ2xhc3Nlc1tidXR0b25OYW1lXTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY2xhc3NOYW1lKSB7XG4gICAgICAgICAgICByZXR1cm4gYCR7dGhpcy5iYXNlSWNvbkNsYXNzfSAke2NsYXNzTmFtZX1gO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAnJztcbiAgICB9XG4gICAgZ2V0Q3VzdG9tQnV0dG9uSWNvbkNsYXNzKGN1c3RvbUJ1dHRvblByb3BzKSB7XG4gICAgICAgIGxldCBjbGFzc05hbWU7XG4gICAgICAgIGlmICh0aGlzLmljb25PdmVycmlkZUN1c3RvbUJ1dHRvbk9wdGlvbikge1xuICAgICAgICAgICAgY2xhc3NOYW1lID0gY3VzdG9tQnV0dG9uUHJvcHNbdGhpcy5pY29uT3ZlcnJpZGVDdXN0b21CdXR0b25PcHRpb25dO1xuICAgICAgICAgICAgaWYgKGNsYXNzTmFtZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBgJHt0aGlzLmJhc2VJY29uQ2xhc3N9ICR7dGhpcy5hcHBseUljb25PdmVycmlkZVByZWZpeChjbGFzc05hbWUpfWA7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuICcnO1xuICAgIH1cbn1cblRoZW1lLnByb3RvdHlwZS5jbGFzc2VzID0ge307XG5UaGVtZS5wcm90b3R5cGUuaWNvbkNsYXNzZXMgPSB7fTtcblRoZW1lLnByb3RvdHlwZS5iYXNlSWNvbkNsYXNzID0gJyc7XG5UaGVtZS5wcm90b3R5cGUuaWNvbk92ZXJyaWRlUHJlZml4ID0gJyc7XG5cbi8qXG5OT1RFOiB0aGlzIGNhbiBiZSBhIHB1YmxpYyBBUEksIGVzcGVjaWFsbHkgY3JlYXRlRWxlbWVudCBmb3IgaG9va3MuXG5TZWUgZXhhbXBsZXMvdHlwZXNjcmlwdC1zY2hlZHVsZXIvc3JjL2luZGV4LnRzXG4qL1xuZnVuY3Rpb24gZmx1c2hTeW5jKHJ1bkJlZm9yZUZsdXNoKSB7XG4gICAgcnVuQmVmb3JlRmx1c2goKTtcbiAgICBsZXQgb2xkRGVib3VuY2VSZW5kZXJpbmcgPSBwcmVhY3Qub3B0aW9ucy5kZWJvdW5jZVJlbmRlcmluZzsgLy8gb3JpZ1xuICAgIGxldCBjYWxsYmFja1EgPSBbXTtcbiAgICBmdW5jdGlvbiBleGVjQ2FsbGJhY2tTeW5jKGNhbGxiYWNrKSB7XG4gICAgICAgIGNhbGxiYWNrUS5wdXNoKGNhbGxiYWNrKTtcbiAgICB9XG4gICAgcHJlYWN0Lm9wdGlvbnMuZGVib3VuY2VSZW5kZXJpbmcgPSBleGVjQ2FsbGJhY2tTeW5jO1xuICAgIHByZWFjdC5yZW5kZXIocHJlYWN0LmNyZWF0ZUVsZW1lbnQoRmFrZUNvbXBvbmVudCwge30pLCBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKSk7XG4gICAgd2hpbGUgKGNhbGxiYWNrUS5sZW5ndGgpIHtcbiAgICAgICAgY2FsbGJhY2tRLnNoaWZ0KCkoKTtcbiAgICB9XG4gICAgcHJlYWN0Lm9wdGlvbnMuZGVib3VuY2VSZW5kZXJpbmcgPSBvbGREZWJvdW5jZVJlbmRlcmluZztcbn1cbmNsYXNzIEZha2VDb21wb25lbnQgZXh0ZW5kcyBwcmVhY3QuQ29tcG9uZW50IHtcbiAgICByZW5kZXIoKSB7IHJldHVybiBwcmVhY3QuY3JlYXRlRWxlbWVudCgnZGl2Jywge30pOyB9XG4gICAgY29tcG9uZW50RGlkTW91bnQoKSB7IHRoaXMuc2V0U3RhdGUoe30pOyB9XG59XG4vLyBUT0RPOiB1c2UgcHJlYWN0L2NvbXBhdCBpbnN0ZWFkP1xuZnVuY3Rpb24gY3JlYXRlQ29udGV4dChkZWZhdWx0VmFsdWUpIHtcbiAgICBsZXQgQ29udGV4dFR5cGUgPSBwcmVhY3QuY3JlYXRlQ29udGV4dChkZWZhdWx0VmFsdWUpO1xuICAgIGxldCBvcmlnUHJvdmlkZXIgPSBDb250ZXh0VHlwZS5Qcm92aWRlcjtcbiAgICBDb250ZXh0VHlwZS5Qcm92aWRlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbGV0IGlzTmV3ID0gIXRoaXMuZ2V0Q2hpbGRDb250ZXh0O1xuICAgICAgICBsZXQgY2hpbGRyZW4gPSBvcmlnUHJvdmlkZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBwcmVmZXItcmVzdC1wYXJhbXNcbiAgICAgICAgaWYgKGlzTmV3KSB7XG4gICAgICAgICAgICBsZXQgc3VicyA9IFtdO1xuICAgICAgICAgICAgdGhpcy5zaG91bGRDb21wb25lbnRVcGRhdGUgPSAoX3Byb3BzKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMucHJvcHMudmFsdWUgIT09IF9wcm9wcy52YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICBzdWJzLmZvckVhY2goKGMpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGMuY29udGV4dCA9IF9wcm9wcy52YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGMuZm9yY2VVcGRhdGUoKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHRoaXMuc3ViID0gKGMpID0+IHtcbiAgICAgICAgICAgICAgICBzdWJzLnB1c2goYyk7XG4gICAgICAgICAgICAgICAgbGV0IG9sZCA9IGMuY29tcG9uZW50V2lsbFVubW91bnQ7XG4gICAgICAgICAgICAgICAgYy5jb21wb25lbnRXaWxsVW5tb3VudCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgc3Vicy5zcGxpY2Uoc3Vicy5pbmRleE9mKGMpLCAxKTtcbiAgICAgICAgICAgICAgICAgICAgb2xkICYmIG9sZC5jYWxsKGMpO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjaGlsZHJlbjtcbiAgICB9O1xuICAgIHJldHVybiBDb250ZXh0VHlwZTtcbn1cblxuY2xhc3MgU2Nyb2xsUmVzcG9uZGVyIHtcbiAgICBjb25zdHJ1Y3RvcihleGVjRnVuYywgZW1pdHRlciwgc2Nyb2xsVGltZSwgc2Nyb2xsVGltZVJlc2V0KSB7XG4gICAgICAgIHRoaXMuZXhlY0Z1bmMgPSBleGVjRnVuYztcbiAgICAgICAgdGhpcy5lbWl0dGVyID0gZW1pdHRlcjtcbiAgICAgICAgdGhpcy5zY3JvbGxUaW1lID0gc2Nyb2xsVGltZTtcbiAgICAgICAgdGhpcy5zY3JvbGxUaW1lUmVzZXQgPSBzY3JvbGxUaW1lUmVzZXQ7XG4gICAgICAgIHRoaXMuaGFuZGxlU2Nyb2xsUmVxdWVzdCA9IChyZXF1ZXN0KSA9PiB7XG4gICAgICAgICAgICB0aGlzLnF1ZXVlZFJlcXVlc3QgPSBPYmplY3QuYXNzaWduKHt9LCB0aGlzLnF1ZXVlZFJlcXVlc3QgfHwge30sIHJlcXVlc3QpO1xuICAgICAgICAgICAgdGhpcy5kcmFpbigpO1xuICAgICAgICB9O1xuICAgICAgICBlbWl0dGVyLm9uKCdfc2Nyb2xsUmVxdWVzdCcsIHRoaXMuaGFuZGxlU2Nyb2xsUmVxdWVzdCk7XG4gICAgICAgIHRoaXMuZmlyZUluaXRpYWxTY3JvbGwoKTtcbiAgICB9XG4gICAgZGV0YWNoKCkge1xuICAgICAgICB0aGlzLmVtaXR0ZXIub2ZmKCdfc2Nyb2xsUmVxdWVzdCcsIHRoaXMuaGFuZGxlU2Nyb2xsUmVxdWVzdCk7XG4gICAgfVxuICAgIHVwZGF0ZShpc0RhdGVzTmV3KSB7XG4gICAgICAgIGlmIChpc0RhdGVzTmV3ICYmIHRoaXMuc2Nyb2xsVGltZVJlc2V0KSB7XG4gICAgICAgICAgICB0aGlzLmZpcmVJbml0aWFsU2Nyb2xsKCk7IC8vIHdpbGwgZHJhaW5cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZHJhaW4oKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBmaXJlSW5pdGlhbFNjcm9sbCgpIHtcbiAgICAgICAgdGhpcy5oYW5kbGVTY3JvbGxSZXF1ZXN0KHtcbiAgICAgICAgICAgIHRpbWU6IHRoaXMuc2Nyb2xsVGltZSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGRyYWluKCkge1xuICAgICAgICBpZiAodGhpcy5xdWV1ZWRSZXF1ZXN0ICYmIHRoaXMuZXhlY0Z1bmModGhpcy5xdWV1ZWRSZXF1ZXN0KSkge1xuICAgICAgICAgICAgdGhpcy5xdWV1ZWRSZXF1ZXN0ID0gbnVsbDtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuY29uc3QgVmlld0NvbnRleHRUeXBlID0gY3JlYXRlQ29udGV4dCh7fSk7IC8vIGZvciBDb21wb25lbnRzXG5mdW5jdGlvbiBidWlsZFZpZXdDb250ZXh0KHZpZXdTcGVjLCB2aWV3QXBpLCB2aWV3T3B0aW9ucywgZGF0ZVByb2ZpbGVHZW5lcmF0b3IsIGRhdGVFbnYsIHRoZW1lLCBwbHVnaW5Ib29rcywgZGlzcGF0Y2gsIGdldEN1cnJlbnREYXRhLCBlbWl0dGVyLCBjYWxlbmRhckFwaSwgcmVnaXN0ZXJJbnRlcmFjdGl2ZUNvbXBvbmVudCwgdW5yZWdpc3RlckludGVyYWN0aXZlQ29tcG9uZW50KSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgZGF0ZUVudixcbiAgICAgICAgb3B0aW9uczogdmlld09wdGlvbnMsXG4gICAgICAgIHBsdWdpbkhvb2tzLFxuICAgICAgICBlbWl0dGVyLFxuICAgICAgICBkaXNwYXRjaCxcbiAgICAgICAgZ2V0Q3VycmVudERhdGEsXG4gICAgICAgIGNhbGVuZGFyQXBpLFxuICAgICAgICB2aWV3U3BlYyxcbiAgICAgICAgdmlld0FwaSxcbiAgICAgICAgZGF0ZVByb2ZpbGVHZW5lcmF0b3IsXG4gICAgICAgIHRoZW1lLFxuICAgICAgICBpc1J0bDogdmlld09wdGlvbnMuZGlyZWN0aW9uID09PSAncnRsJyxcbiAgICAgICAgYWRkUmVzaXplSGFuZGxlcihoYW5kbGVyKSB7XG4gICAgICAgICAgICBlbWl0dGVyLm9uKCdfcmVzaXplJywgaGFuZGxlcik7XG4gICAgICAgIH0sXG4gICAgICAgIHJlbW92ZVJlc2l6ZUhhbmRsZXIoaGFuZGxlcikge1xuICAgICAgICAgICAgZW1pdHRlci5vZmYoJ19yZXNpemUnLCBoYW5kbGVyKTtcbiAgICAgICAgfSxcbiAgICAgICAgY3JlYXRlU2Nyb2xsUmVzcG9uZGVyKGV4ZWNGdW5jKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFNjcm9sbFJlc3BvbmRlcihleGVjRnVuYywgZW1pdHRlciwgY3JlYXRlRHVyYXRpb24odmlld09wdGlvbnMuc2Nyb2xsVGltZSksIHZpZXdPcHRpb25zLnNjcm9sbFRpbWVSZXNldCk7XG4gICAgICAgIH0sXG4gICAgICAgIHJlZ2lzdGVySW50ZXJhY3RpdmVDb21wb25lbnQsXG4gICAgICAgIHVucmVnaXN0ZXJJbnRlcmFjdGl2ZUNvbXBvbmVudCxcbiAgICB9O1xufVxuXG4vKiBlc2xpbnQgbWF4LWNsYXNzZXMtcGVyLWZpbGU6IG9mZiAqL1xuY2xhc3MgUHVyZUNvbXBvbmVudCBleHRlbmRzIENvbXBvbmVudCB7XG4gICAgc2hvdWxkQ29tcG9uZW50VXBkYXRlKG5leHRQcm9wcywgbmV4dFN0YXRlKSB7XG4gICAgICAgIGlmICh0aGlzLmRlYnVnKSB7XG4gICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICAgICAgICAgICAgY29uc29sZS5sb2coZ2V0VW5lcXVhbFByb3BzKG5leHRQcm9wcywgdGhpcy5wcm9wcyksIGdldFVuZXF1YWxQcm9wcyhuZXh0U3RhdGUsIHRoaXMuc3RhdGUpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gIWNvbXBhcmVPYmpzKHRoaXMucHJvcHMsIG5leHRQcm9wcywgdGhpcy5wcm9wRXF1YWxpdHkpIHx8XG4gICAgICAgICAgICAhY29tcGFyZU9ianModGhpcy5zdGF0ZSwgbmV4dFN0YXRlLCB0aGlzLnN0YXRlRXF1YWxpdHkpO1xuICAgIH1cbiAgICAvLyBIQUNLIGZvciBmcmVha2luJyBSZWFjdCBTdHJpY3RNb2RlXG4gICAgc2FmZVNldFN0YXRlKG5ld1N0YXRlKSB7XG4gICAgICAgIGlmICghY29tcGFyZU9ianModGhpcy5zdGF0ZSwgT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCB0aGlzLnN0YXRlKSwgbmV3U3RhdGUpLCB0aGlzLnN0YXRlRXF1YWxpdHkpKSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKG5ld1N0YXRlKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblB1cmVDb21wb25lbnQuYWRkUHJvcHNFcXVhbGl0eSA9IGFkZFByb3BzRXF1YWxpdHk7XG5QdXJlQ29tcG9uZW50LmFkZFN0YXRlRXF1YWxpdHkgPSBhZGRTdGF0ZUVxdWFsaXR5O1xuUHVyZUNvbXBvbmVudC5jb250ZXh0VHlwZSA9IFZpZXdDb250ZXh0VHlwZTtcblB1cmVDb21wb25lbnQucHJvdG90eXBlLnByb3BFcXVhbGl0eSA9IHt9O1xuUHVyZUNvbXBvbmVudC5wcm90b3R5cGUuc3RhdGVFcXVhbGl0eSA9IHt9O1xuY2xhc3MgQmFzZUNvbXBvbmVudCBleHRlbmRzIFB1cmVDb21wb25lbnQge1xufVxuQmFzZUNvbXBvbmVudC5jb250ZXh0VHlwZSA9IFZpZXdDb250ZXh0VHlwZTtcbmZ1bmN0aW9uIGFkZFByb3BzRXF1YWxpdHkocHJvcEVxdWFsaXR5KSB7XG4gICAgbGV0IGhhc2ggPSBPYmplY3QuY3JlYXRlKHRoaXMucHJvdG90eXBlLnByb3BFcXVhbGl0eSk7XG4gICAgT2JqZWN0LmFzc2lnbihoYXNoLCBwcm9wRXF1YWxpdHkpO1xuICAgIHRoaXMucHJvdG90eXBlLnByb3BFcXVhbGl0eSA9IGhhc2g7XG59XG5mdW5jdGlvbiBhZGRTdGF0ZUVxdWFsaXR5KHN0YXRlRXF1YWxpdHkpIHtcbiAgICBsZXQgaGFzaCA9IE9iamVjdC5jcmVhdGUodGhpcy5wcm90b3R5cGUuc3RhdGVFcXVhbGl0eSk7XG4gICAgT2JqZWN0LmFzc2lnbihoYXNoLCBzdGF0ZUVxdWFsaXR5KTtcbiAgICB0aGlzLnByb3RvdHlwZS5zdGF0ZUVxdWFsaXR5ID0gaGFzaDtcbn1cbi8vIHVzZSBvdGhlciBvbmVcbmZ1bmN0aW9uIHNldFJlZihyZWYsIGN1cnJlbnQpIHtcbiAgICBpZiAodHlwZW9mIHJlZiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICByZWYoY3VycmVudCk7XG4gICAgfVxuICAgIGVsc2UgaWYgKHJlZikge1xuICAgICAgICAvLyBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL3JlYWN0L2lzc3Vlcy8xMzAyOVxuICAgICAgICByZWYuY3VycmVudCA9IGN1cnJlbnQ7XG4gICAgfVxufVxuXG4vKlxuYW4gSU5URVJBQ1RBQkxFIGRhdGUgY29tcG9uZW50XG5cblBVUlBPU0VTOlxuLSBob29rIHVwIHRvIGZnLCBmaWxsLCBhbmQgbWlycm9yIHJlbmRlcmVyc1xuLSBpbnRlcmZhY2UgZm9yIGRyYWdnaW5nIGFuZCBoaXRzXG4qL1xuY2xhc3MgRGF0ZUNvbXBvbmVudCBleHRlbmRzIEJhc2VDb21wb25lbnQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLnVpZCA9IGd1aWQoKTtcbiAgICB9XG4gICAgLy8gSGl0IFN5c3RlbVxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgcHJlcGFyZUhpdHMoKSB7XG4gICAgfVxuICAgIHF1ZXJ5SGl0KHBvc2l0aW9uTGVmdCwgcG9zaXRpb25Ub3AsIGVsV2lkdGgsIGVsSGVpZ2h0KSB7XG4gICAgICAgIHJldHVybiBudWxsOyAvLyB0aGlzIHNob3VsZCBiZSBhYnN0cmFjdFxuICAgIH1cbiAgICAvLyBQb2ludGVyIEludGVyYWN0aW9uIFV0aWxzXG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICBpc1ZhbGlkU2VnRG93bkVsKGVsKSB7XG4gICAgICAgIHJldHVybiAhdGhpcy5wcm9wcy5ldmVudERyYWcgJiYgLy8gSEFDS1xuICAgICAgICAgICAgIXRoaXMucHJvcHMuZXZlbnRSZXNpemUgJiYgLy8gSEFDS1xuICAgICAgICAgICAgIWVsZW1lbnRDbG9zZXN0KGVsLCAnLmZjLWV2ZW50LW1pcnJvcicpO1xuICAgIH1cbiAgICBpc1ZhbGlkRGF0ZURvd25FbChlbCkge1xuICAgICAgICByZXR1cm4gIWVsZW1lbnRDbG9zZXN0KGVsLCAnLmZjLWV2ZW50Om5vdCguZmMtYmctZXZlbnQpJykgJiZcbiAgICAgICAgICAgICFlbGVtZW50Q2xvc2VzdChlbCwgJy5mYy1tb3JlLWxpbmsnKSAmJiAvLyBhIFwibW9yZS4uXCIgbGlua1xuICAgICAgICAgICAgIWVsZW1lbnRDbG9zZXN0KGVsLCAnYVtkYXRhLW5hdmxpbmtdJykgJiYgLy8gYSBjbGlja2FibGUgbmF2IGxpbmtcbiAgICAgICAgICAgICFlbGVtZW50Q2xvc2VzdChlbCwgJy5mYy1wb3BvdmVyJyk7IC8vIGhhY2tcbiAgICB9XG59XG5cbmZ1bmN0aW9uIHJlZHVjZUN1cnJlbnREYXRlKGN1cnJlbnREYXRlLCBhY3Rpb24pIHtcbiAgICBzd2l0Y2ggKGFjdGlvbi50eXBlKSB7XG4gICAgICAgIGNhc2UgJ0NIQU5HRV9EQVRFJzpcbiAgICAgICAgICAgIHJldHVybiBhY3Rpb24uZGF0ZU1hcmtlcjtcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIHJldHVybiBjdXJyZW50RGF0ZTtcbiAgICB9XG59XG5mdW5jdGlvbiBnZXRJbml0aWFsRGF0ZShvcHRpb25zLCBkYXRlRW52KSB7XG4gICAgbGV0IGluaXRpYWxEYXRlSW5wdXQgPSBvcHRpb25zLmluaXRpYWxEYXRlO1xuICAgIC8vIGNvbXB1dGUgdGhlIGluaXRpYWwgYW1iaWctdGltZXpvbmUgZGF0ZVxuICAgIGlmIChpbml0aWFsRGF0ZUlucHV0ICE9IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIGRhdGVFbnYuY3JlYXRlTWFya2VyKGluaXRpYWxEYXRlSW5wdXQpO1xuICAgIH1cbiAgICByZXR1cm4gZ2V0Tm93KG9wdGlvbnMubm93LCBkYXRlRW52KTsgLy8gZ2V0Tm93IGFscmVhZHkgcmV0dXJucyB1bnpvbmVkXG59XG5mdW5jdGlvbiBnZXROb3cobm93SW5wdXQsIGRhdGVFbnYpIHtcbiAgICBpZiAodHlwZW9mIG5vd0lucHV0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIG5vd0lucHV0ID0gbm93SW5wdXQoKTtcbiAgICB9XG4gICAgaWYgKG5vd0lucHV0ID09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIGRhdGVFbnYuY3JlYXRlTm93TWFya2VyKCk7XG4gICAgfVxuICAgIHJldHVybiBkYXRlRW52LmNyZWF0ZU1hcmtlcihub3dJbnB1dCk7XG59XG5cbmNsYXNzIERhdGVQcm9maWxlR2VuZXJhdG9yIHtcbiAgICBjb25zdHJ1Y3Rvcihwcm9wcykge1xuICAgICAgICB0aGlzLnByb3BzID0gcHJvcHM7XG4gICAgICAgIHRoaXMubm93RGF0ZSA9IGdldE5vdyhwcm9wcy5ub3dJbnB1dCwgcHJvcHMuZGF0ZUVudik7XG4gICAgICAgIHRoaXMuaW5pdEhpZGRlbkRheXMoKTtcbiAgICB9XG4gICAgLyogRGF0ZSBSYW5nZSBDb21wdXRhdGlvblxuICAgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG4gICAgLy8gQnVpbGRzIGEgc3RydWN0dXJlIHdpdGggaW5mbyBhYm91dCB3aGF0IHRoZSBkYXRlcy9yYW5nZXMgd2lsbCBiZSBmb3IgdGhlIFwicHJldlwiIHZpZXcuXG4gICAgYnVpbGRQcmV2KGN1cnJlbnREYXRlUHJvZmlsZSwgY3VycmVudERhdGUsIGZvcmNlVG9WYWxpZCkge1xuICAgICAgICBsZXQgeyBkYXRlRW52IH0gPSB0aGlzLnByb3BzO1xuICAgICAgICBsZXQgcHJldkRhdGUgPSBkYXRlRW52LnN1YnRyYWN0KGRhdGVFbnYuc3RhcnRPZihjdXJyZW50RGF0ZSwgY3VycmVudERhdGVQcm9maWxlLmN1cnJlbnRSYW5nZVVuaXQpLCAvLyBpbXBvcnRhbnQgZm9yIHN0YXJ0LW9mLW1vbnRoXG4gICAgICAgIGN1cnJlbnREYXRlUHJvZmlsZS5kYXRlSW5jcmVtZW50KTtcbiAgICAgICAgcmV0dXJuIHRoaXMuYnVpbGQocHJldkRhdGUsIC0xLCBmb3JjZVRvVmFsaWQpO1xuICAgIH1cbiAgICAvLyBCdWlsZHMgYSBzdHJ1Y3R1cmUgd2l0aCBpbmZvIGFib3V0IHdoYXQgdGhlIGRhdGVzL3JhbmdlcyB3aWxsIGJlIGZvciB0aGUgXCJuZXh0XCIgdmlldy5cbiAgICBidWlsZE5leHQoY3VycmVudERhdGVQcm9maWxlLCBjdXJyZW50RGF0ZSwgZm9yY2VUb1ZhbGlkKSB7XG4gICAgICAgIGxldCB7IGRhdGVFbnYgfSA9IHRoaXMucHJvcHM7XG4gICAgICAgIGxldCBuZXh0RGF0ZSA9IGRhdGVFbnYuYWRkKGRhdGVFbnYuc3RhcnRPZihjdXJyZW50RGF0ZSwgY3VycmVudERhdGVQcm9maWxlLmN1cnJlbnRSYW5nZVVuaXQpLCAvLyBpbXBvcnRhbnQgZm9yIHN0YXJ0LW9mLW1vbnRoXG4gICAgICAgIGN1cnJlbnREYXRlUHJvZmlsZS5kYXRlSW5jcmVtZW50KTtcbiAgICAgICAgcmV0dXJuIHRoaXMuYnVpbGQobmV4dERhdGUsIDEsIGZvcmNlVG9WYWxpZCk7XG4gICAgfVxuICAgIC8vIEJ1aWxkcyBhIHN0cnVjdHVyZSBob2xkaW5nIGRhdGVzL3JhbmdlcyBmb3IgcmVuZGVyaW5nIGFyb3VuZCB0aGUgZ2l2ZW4gZGF0ZS5cbiAgICAvLyBPcHRpb25hbCBkaXJlY3Rpb24gcGFyYW0gaW5kaWNhdGVzIHdoZXRoZXIgdGhlIGRhdGUgaXMgYmVpbmcgaW5jcmVtZW50ZWQvZGVjcmVtZW50ZWRcbiAgICAvLyBmcm9tIGl0cyBwcmV2aW91cyB2YWx1ZS4gZGVjcmVtZW50ZWQgPSAtMSwgaW5jcmVtZW50ZWQgPSAxIChkZWZhdWx0KS5cbiAgICBidWlsZChjdXJyZW50RGF0ZSwgZGlyZWN0aW9uLCBmb3JjZVRvVmFsaWQgPSB0cnVlKSB7XG4gICAgICAgIGxldCB7IHByb3BzIH0gPSB0aGlzO1xuICAgICAgICBsZXQgdmFsaWRSYW5nZTtcbiAgICAgICAgbGV0IGN1cnJlbnRJbmZvO1xuICAgICAgICBsZXQgaXNSYW5nZUFsbERheTtcbiAgICAgICAgbGV0IHJlbmRlclJhbmdlO1xuICAgICAgICBsZXQgYWN0aXZlUmFuZ2U7XG4gICAgICAgIGxldCBpc1ZhbGlkO1xuICAgICAgICB2YWxpZFJhbmdlID0gdGhpcy5idWlsZFZhbGlkUmFuZ2UoKTtcbiAgICAgICAgdmFsaWRSYW5nZSA9IHRoaXMudHJpbUhpZGRlbkRheXModmFsaWRSYW5nZSk7XG4gICAgICAgIGlmIChmb3JjZVRvVmFsaWQpIHtcbiAgICAgICAgICAgIGN1cnJlbnREYXRlID0gY29uc3RyYWluTWFya2VyVG9SYW5nZShjdXJyZW50RGF0ZSwgdmFsaWRSYW5nZSk7XG4gICAgICAgIH1cbiAgICAgICAgY3VycmVudEluZm8gPSB0aGlzLmJ1aWxkQ3VycmVudFJhbmdlSW5mbyhjdXJyZW50RGF0ZSwgZGlyZWN0aW9uKTtcbiAgICAgICAgaXNSYW5nZUFsbERheSA9IC9eKHllYXJ8bW9udGh8d2Vla3xkYXkpJC8udGVzdChjdXJyZW50SW5mby51bml0KTtcbiAgICAgICAgcmVuZGVyUmFuZ2UgPSB0aGlzLmJ1aWxkUmVuZGVyUmFuZ2UodGhpcy50cmltSGlkZGVuRGF5cyhjdXJyZW50SW5mby5yYW5nZSksIGN1cnJlbnRJbmZvLnVuaXQsIGlzUmFuZ2VBbGxEYXkpO1xuICAgICAgICByZW5kZXJSYW5nZSA9IHRoaXMudHJpbUhpZGRlbkRheXMocmVuZGVyUmFuZ2UpO1xuICAgICAgICBhY3RpdmVSYW5nZSA9IHJlbmRlclJhbmdlO1xuICAgICAgICBpZiAoIXByb3BzLnNob3dOb25DdXJyZW50RGF0ZXMpIHtcbiAgICAgICAgICAgIGFjdGl2ZVJhbmdlID0gaW50ZXJzZWN0UmFuZ2VzKGFjdGl2ZVJhbmdlLCBjdXJyZW50SW5mby5yYW5nZSk7XG4gICAgICAgIH1cbiAgICAgICAgYWN0aXZlUmFuZ2UgPSB0aGlzLmFkanVzdEFjdGl2ZVJhbmdlKGFjdGl2ZVJhbmdlKTtcbiAgICAgICAgYWN0aXZlUmFuZ2UgPSBpbnRlcnNlY3RSYW5nZXMoYWN0aXZlUmFuZ2UsIHZhbGlkUmFuZ2UpOyAvLyBtaWdodCByZXR1cm4gbnVsbFxuICAgICAgICAvLyBpdCdzIGludmFsaWQgaWYgdGhlIG9yaWdpbmFsbHkgcmVxdWVzdGVkIGRhdGUgaXMgbm90IGNvbnRhaW5lZCxcbiAgICAgICAgLy8gb3IgaWYgdGhlIHJhbmdlIGlzIGNvbXBsZXRlbHkgb3V0c2lkZSBvZiB0aGUgdmFsaWQgcmFuZ2UuXG4gICAgICAgIGlzVmFsaWQgPSByYW5nZXNJbnRlcnNlY3QoY3VycmVudEluZm8ucmFuZ2UsIHZhbGlkUmFuZ2UpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgLy8gY29uc3RyYWludCBmb3Igd2hlcmUgcHJldi9uZXh0IG9wZXJhdGlvbnMgY2FuIGdvIGFuZCB3aGVyZSBldmVudHMgY2FuIGJlIGRyYWdnZWQvcmVzaXplZCB0by5cbiAgICAgICAgICAgIC8vIGFuIG9iamVjdCB3aXRoIG9wdGlvbmFsIHN0YXJ0IGFuZCBlbmQgcHJvcGVydGllcy5cbiAgICAgICAgICAgIHZhbGlkUmFuZ2UsXG4gICAgICAgICAgICAvLyByYW5nZSB0aGUgdmlldyBpcyBmb3JtYWxseSByZXNwb25zaWJsZSBmb3IuXG4gICAgICAgICAgICAvLyBmb3IgZXhhbXBsZSwgYSBtb250aCB2aWV3IG1pZ2h0IGhhdmUgMXN0LTMxc3QsIGV4Y2x1ZGluZyBwYWRkZWQgZGF0ZXNcbiAgICAgICAgICAgIGN1cnJlbnRSYW5nZTogY3VycmVudEluZm8ucmFuZ2UsXG4gICAgICAgICAgICAvLyBuYW1lIG9mIGxhcmdlc3QgdW5pdCBiZWluZyBkaXNwbGF5ZWQsIGxpa2UgXCJtb250aFwiIG9yIFwid2Vla1wiXG4gICAgICAgICAgICBjdXJyZW50UmFuZ2VVbml0OiBjdXJyZW50SW5mby51bml0LFxuICAgICAgICAgICAgaXNSYW5nZUFsbERheSxcbiAgICAgICAgICAgIC8vIGRhdGVzIHRoYXQgZGlzcGxheSBldmVudHMgYW5kIGFjY2VwdCBkcmFnLW4tZHJvcFxuICAgICAgICAgICAgLy8gd2lsbCBiZSBgbnVsbGAgaWYgbm8gZGF0ZXMgYWNjZXB0IGV2ZW50c1xuICAgICAgICAgICAgYWN0aXZlUmFuZ2UsXG4gICAgICAgICAgICAvLyBkYXRlIHJhbmdlIHdpdGggYSByZW5kZXJlZCBza2VsZXRvblxuICAgICAgICAgICAgLy8gaW5jbHVkZXMgbm90LWFjdGl2ZSBkYXlzIHRoYXQgbmVlZCBzb21lIHNvcnQgb2YgRE9NXG4gICAgICAgICAgICByZW5kZXJSYW5nZSxcbiAgICAgICAgICAgIC8vIER1cmF0aW9uIG9iamVjdCB0aGF0IGRlbm90ZXMgdGhlIGZpcnN0IHZpc2libGUgdGltZSBvZiBhbnkgZ2l2ZW4gZGF5XG4gICAgICAgICAgICBzbG90TWluVGltZTogcHJvcHMuc2xvdE1pblRpbWUsXG4gICAgICAgICAgICAvLyBEdXJhdGlvbiBvYmplY3QgdGhhdCBkZW5vdGVzIHRoZSBleGNsdXNpdmUgdmlzaWJsZSBlbmQgdGltZSBvZiBhbnkgZ2l2ZW4gZGF5XG4gICAgICAgICAgICBzbG90TWF4VGltZTogcHJvcHMuc2xvdE1heFRpbWUsXG4gICAgICAgICAgICBpc1ZhbGlkLFxuICAgICAgICAgICAgLy8gaG93IGZhciB0aGUgY3VycmVudCBkYXRlIHdpbGwgbW92ZSBmb3IgYSBwcmV2L25leHQgb3BlcmF0aW9uXG4gICAgICAgICAgICBkYXRlSW5jcmVtZW50OiB0aGlzLmJ1aWxkRGF0ZUluY3JlbWVudChjdXJyZW50SW5mby5kdXJhdGlvbiksXG4gICAgICAgICAgICAvLyBwYXNzIGEgZmFsbGJhY2sgKG1pZ2h0IGJlIG51bGwpIF5cbiAgICAgICAgfTtcbiAgICB9XG4gICAgLy8gQnVpbGRzIGFuIG9iamVjdCB3aXRoIG9wdGlvbmFsIHN0YXJ0L2VuZCBwcm9wZXJ0aWVzLlxuICAgIC8vIEluZGljYXRlcyB0aGUgbWluaW11bS9tYXhpbXVtIGRhdGVzIHRvIGRpc3BsYXkuXG4gICAgLy8gbm90IHJlc3BvbnNpYmxlIGZvciB0cmltbWluZyBoaWRkZW4gZGF5cy5cbiAgICBidWlsZFZhbGlkUmFuZ2UoKSB7XG4gICAgICAgIGxldCBpbnB1dCA9IHRoaXMucHJvcHMudmFsaWRSYW5nZUlucHV0O1xuICAgICAgICBsZXQgc2ltcGxlSW5wdXQgPSB0eXBlb2YgaW5wdXQgPT09ICdmdW5jdGlvbidcbiAgICAgICAgICAgID8gaW5wdXQuY2FsbCh0aGlzLnByb3BzLmNhbGVuZGFyQXBpLCB0aGlzLm5vd0RhdGUpXG4gICAgICAgICAgICA6IGlucHV0O1xuICAgICAgICByZXR1cm4gdGhpcy5yZWZpbmVSYW5nZShzaW1wbGVJbnB1dCkgfHxcbiAgICAgICAgICAgIHsgc3RhcnQ6IG51bGwsIGVuZDogbnVsbCB9OyAvLyBjb21wbGV0ZWx5IG9wZW4tZW5kZWRcbiAgICB9XG4gICAgLy8gQnVpbGRzIGEgc3RydWN0dXJlIHdpdGggaW5mbyBhYm91dCB0aGUgXCJjdXJyZW50XCIgcmFuZ2UsIHRoZSByYW5nZSB0aGF0IGlzXG4gICAgLy8gaGlnaGxpZ2h0ZWQgYXMgYmVpbmcgdGhlIGN1cnJlbnQgbW9udGggZm9yIGV4YW1wbGUuXG4gICAgLy8gU2VlIGJ1aWxkKCkgZm9yIGEgZGVzY3JpcHRpb24gb2YgYGRpcmVjdGlvbmAuXG4gICAgLy8gR3VhcmFudGVlZCB0byBoYXZlIGByYW5nZWAgYW5kIGB1bml0YCBwcm9wZXJ0aWVzLiBgZHVyYXRpb25gIGlzIG9wdGlvbmFsLlxuICAgIGJ1aWxkQ3VycmVudFJhbmdlSW5mbyhkYXRlLCBkaXJlY3Rpb24pIHtcbiAgICAgICAgbGV0IHsgcHJvcHMgfSA9IHRoaXM7XG4gICAgICAgIGxldCBkdXJhdGlvbiA9IG51bGw7XG4gICAgICAgIGxldCB1bml0ID0gbnVsbDtcbiAgICAgICAgbGV0IHJhbmdlID0gbnVsbDtcbiAgICAgICAgbGV0IGRheUNvdW50O1xuICAgICAgICBpZiAocHJvcHMuZHVyYXRpb24pIHtcbiAgICAgICAgICAgIGR1cmF0aW9uID0gcHJvcHMuZHVyYXRpb247XG4gICAgICAgICAgICB1bml0ID0gcHJvcHMuZHVyYXRpb25Vbml0O1xuICAgICAgICAgICAgcmFuZ2UgPSB0aGlzLmJ1aWxkUmFuZ2VGcm9tRHVyYXRpb24oZGF0ZSwgZGlyZWN0aW9uLCBkdXJhdGlvbiwgdW5pdCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoKGRheUNvdW50ID0gdGhpcy5wcm9wcy5kYXlDb3VudCkpIHtcbiAgICAgICAgICAgIHVuaXQgPSAnZGF5JztcbiAgICAgICAgICAgIHJhbmdlID0gdGhpcy5idWlsZFJhbmdlRnJvbURheUNvdW50KGRhdGUsIGRpcmVjdGlvbiwgZGF5Q291bnQpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKChyYW5nZSA9IHRoaXMuYnVpbGRDdXN0b21WaXNpYmxlUmFuZ2UoZGF0ZSkpKSB7XG4gICAgICAgICAgICB1bml0ID0gcHJvcHMuZGF0ZUVudi5ncmVhdGVzdFdob2xlVW5pdChyYW5nZS5zdGFydCwgcmFuZ2UuZW5kKS51bml0O1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZHVyYXRpb24gPSB0aGlzLmdldEZhbGxiYWNrRHVyYXRpb24oKTtcbiAgICAgICAgICAgIHVuaXQgPSBncmVhdGVzdER1cmF0aW9uRGVub21pbmF0b3IoZHVyYXRpb24pLnVuaXQ7XG4gICAgICAgICAgICByYW5nZSA9IHRoaXMuYnVpbGRSYW5nZUZyb21EdXJhdGlvbihkYXRlLCBkaXJlY3Rpb24sIGR1cmF0aW9uLCB1bml0KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geyBkdXJhdGlvbiwgdW5pdCwgcmFuZ2UgfTtcbiAgICB9XG4gICAgZ2V0RmFsbGJhY2tEdXJhdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIGNyZWF0ZUR1cmF0aW9uKHsgZGF5OiAxIH0pO1xuICAgIH1cbiAgICAvLyBSZXR1cm5zIGEgbmV3IGFjdGl2ZVJhbmdlIHRvIGhhdmUgdGltZSB2YWx1ZXMgKHVuLWFtYmlndWF0ZSlcbiAgICAvLyBzbG90TWluVGltZSBvciBzbG90TWF4VGltZSBjYXVzZXMgdGhlIHJhbmdlIHRvIGV4cGFuZC5cbiAgICBhZGp1c3RBY3RpdmVSYW5nZShyYW5nZSkge1xuICAgICAgICBsZXQgeyBkYXRlRW52LCB1c2VzTWluTWF4VGltZSwgc2xvdE1pblRpbWUsIHNsb3RNYXhUaW1lIH0gPSB0aGlzLnByb3BzO1xuICAgICAgICBsZXQgeyBzdGFydCwgZW5kIH0gPSByYW5nZTtcbiAgICAgICAgaWYgKHVzZXNNaW5NYXhUaW1lKSB7XG4gICAgICAgICAgICAvLyBleHBhbmQgYWN0aXZlIHJhbmdlIGlmIHNsb3RNaW5UaW1lIGlzIG5lZ2F0aXZlICh3aHkgbm90IHdoZW4gcG9zaXRpdmU/KVxuICAgICAgICAgICAgaWYgKGFzUm91Z2hEYXlzKHNsb3RNaW5UaW1lKSA8IDApIHtcbiAgICAgICAgICAgICAgICBzdGFydCA9IHN0YXJ0T2ZEYXkoc3RhcnQpOyAvLyBuZWNlc3Nhcnk/XG4gICAgICAgICAgICAgICAgc3RhcnQgPSBkYXRlRW52LmFkZChzdGFydCwgc2xvdE1pblRpbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gZXhwYW5kIGFjdGl2ZSByYW5nZSBpZiBzbG90TWF4VGltZSBpcyBiZXlvbmQgb25lIGRheSAod2h5IG5vdCB3aGVuIG5lZ2F0aXZlPylcbiAgICAgICAgICAgIGlmIChhc1JvdWdoRGF5cyhzbG90TWF4VGltZSkgPiAxKSB7XG4gICAgICAgICAgICAgICAgZW5kID0gc3RhcnRPZkRheShlbmQpOyAvLyBuZWNlc3Nhcnk/XG4gICAgICAgICAgICAgICAgZW5kID0gYWRkRGF5cyhlbmQsIC0xKTtcbiAgICAgICAgICAgICAgICBlbmQgPSBkYXRlRW52LmFkZChlbmQsIHNsb3RNYXhUaW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geyBzdGFydCwgZW5kIH07XG4gICAgfVxuICAgIC8vIEJ1aWxkcyB0aGUgXCJjdXJyZW50XCIgcmFuZ2Ugd2hlbiBpdCBpcyBzcGVjaWZpZWQgYXMgYW4gZXhwbGljaXQgZHVyYXRpb24uXG4gICAgLy8gYHVuaXRgIGlzIHRoZSBhbHJlYWR5LWNvbXB1dGVkIGdyZWF0ZXN0RHVyYXRpb25EZW5vbWluYXRvciB1bml0IG9mIGR1cmF0aW9uLlxuICAgIGJ1aWxkUmFuZ2VGcm9tRHVyYXRpb24oZGF0ZSwgZGlyZWN0aW9uLCBkdXJhdGlvbiwgdW5pdCkge1xuICAgICAgICBsZXQgeyBkYXRlRW52LCBkYXRlQWxpZ25tZW50IH0gPSB0aGlzLnByb3BzO1xuICAgICAgICBsZXQgc3RhcnQ7XG4gICAgICAgIGxldCBlbmQ7XG4gICAgICAgIGxldCByZXM7XG4gICAgICAgIC8vIGNvbXB1dGUgd2hhdCB0aGUgYWxpZ25tZW50IHNob3VsZCBiZVxuICAgICAgICBpZiAoIWRhdGVBbGlnbm1lbnQpIHtcbiAgICAgICAgICAgIGxldCB7IGRhdGVJbmNyZW1lbnQgfSA9IHRoaXMucHJvcHM7XG4gICAgICAgICAgICBpZiAoZGF0ZUluY3JlbWVudCkge1xuICAgICAgICAgICAgICAgIC8vIHVzZSB0aGUgc21hbGxlciBvZiB0aGUgdHdvIHVuaXRzXG4gICAgICAgICAgICAgICAgaWYgKGFzUm91Z2hNcyhkYXRlSW5jcmVtZW50KSA8IGFzUm91Z2hNcyhkdXJhdGlvbikpIHtcbiAgICAgICAgICAgICAgICAgICAgZGF0ZUFsaWdubWVudCA9IGdyZWF0ZXN0RHVyYXRpb25EZW5vbWluYXRvcihkYXRlSW5jcmVtZW50KS51bml0O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZGF0ZUFsaWdubWVudCA9IHVuaXQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgZGF0ZUFsaWdubWVudCA9IHVuaXQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gaWYgdGhlIHZpZXcgZGlzcGxheXMgYSBzaW5nbGUgZGF5IG9yIHNtYWxsZXJcbiAgICAgICAgaWYgKGFzUm91Z2hEYXlzKGR1cmF0aW9uKSA8PSAxKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5pc0hpZGRlbkRheShzdGFydCkpIHtcbiAgICAgICAgICAgICAgICBzdGFydCA9IHRoaXMuc2tpcEhpZGRlbkRheXMoc3RhcnQsIGRpcmVjdGlvbik7XG4gICAgICAgICAgICAgICAgc3RhcnQgPSBzdGFydE9mRGF5KHN0YXJ0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiBjb21wdXRlUmVzKCkge1xuICAgICAgICAgICAgc3RhcnQgPSBkYXRlRW52LnN0YXJ0T2YoZGF0ZSwgZGF0ZUFsaWdubWVudCk7XG4gICAgICAgICAgICBlbmQgPSBkYXRlRW52LmFkZChzdGFydCwgZHVyYXRpb24pO1xuICAgICAgICAgICAgcmVzID0geyBzdGFydCwgZW5kIH07XG4gICAgICAgIH1cbiAgICAgICAgY29tcHV0ZVJlcygpO1xuICAgICAgICAvLyBpZiByYW5nZSBpcyBjb21wbGV0ZWx5IGVudmVsb3BlZCBieSBoaWRkZW4gZGF5cywgZ28gcGFzdCB0aGUgaGlkZGVuIGRheXNcbiAgICAgICAgaWYgKCF0aGlzLnRyaW1IaWRkZW5EYXlzKHJlcykpIHtcbiAgICAgICAgICAgIGRhdGUgPSB0aGlzLnNraXBIaWRkZW5EYXlzKGRhdGUsIGRpcmVjdGlvbik7XG4gICAgICAgICAgICBjb21wdXRlUmVzKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICB9XG4gICAgLy8gQnVpbGRzIHRoZSBcImN1cnJlbnRcIiByYW5nZSB3aGVuIGEgZGF5Q291bnQgaXMgc3BlY2lmaWVkLlxuICAgIGJ1aWxkUmFuZ2VGcm9tRGF5Q291bnQoZGF0ZSwgZGlyZWN0aW9uLCBkYXlDb3VudCkge1xuICAgICAgICBsZXQgeyBkYXRlRW52LCBkYXRlQWxpZ25tZW50IH0gPSB0aGlzLnByb3BzO1xuICAgICAgICBsZXQgcnVubmluZ0NvdW50ID0gMDtcbiAgICAgICAgbGV0IHN0YXJ0ID0gZGF0ZTtcbiAgICAgICAgbGV0IGVuZDtcbiAgICAgICAgaWYgKGRhdGVBbGlnbm1lbnQpIHtcbiAgICAgICAgICAgIHN0YXJ0ID0gZGF0ZUVudi5zdGFydE9mKHN0YXJ0LCBkYXRlQWxpZ25tZW50KTtcbiAgICAgICAgfVxuICAgICAgICBzdGFydCA9IHN0YXJ0T2ZEYXkoc3RhcnQpO1xuICAgICAgICBzdGFydCA9IHRoaXMuc2tpcEhpZGRlbkRheXMoc3RhcnQsIGRpcmVjdGlvbik7XG4gICAgICAgIGVuZCA9IHN0YXJ0O1xuICAgICAgICBkbyB7XG4gICAgICAgICAgICBlbmQgPSBhZGREYXlzKGVuZCwgMSk7XG4gICAgICAgICAgICBpZiAoIXRoaXMuaXNIaWRkZW5EYXkoZW5kKSkge1xuICAgICAgICAgICAgICAgIHJ1bm5pbmdDb3VudCArPSAxO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IHdoaWxlIChydW5uaW5nQ291bnQgPCBkYXlDb3VudCk7XG4gICAgICAgIHJldHVybiB7IHN0YXJ0LCBlbmQgfTtcbiAgICB9XG4gICAgLy8gQnVpbGRzIGEgbm9ybWFsaXplZCByYW5nZSBvYmplY3QgZm9yIHRoZSBcInZpc2libGVcIiByYW5nZSxcbiAgICAvLyB3aGljaCBpcyBhIHdheSB0byBkZWZpbmUgdGhlIGN1cnJlbnRSYW5nZSBhbmQgYWN0aXZlUmFuZ2UgYXQgdGhlIHNhbWUgdGltZS5cbiAgICBidWlsZEN1c3RvbVZpc2libGVSYW5nZShkYXRlKSB7XG4gICAgICAgIGxldCB7IHByb3BzIH0gPSB0aGlzO1xuICAgICAgICBsZXQgaW5wdXQgPSBwcm9wcy52aXNpYmxlUmFuZ2VJbnB1dDtcbiAgICAgICAgbGV0IHNpbXBsZUlucHV0ID0gdHlwZW9mIGlucHV0ID09PSAnZnVuY3Rpb24nXG4gICAgICAgICAgICA/IGlucHV0LmNhbGwocHJvcHMuY2FsZW5kYXJBcGksIHByb3BzLmRhdGVFbnYudG9EYXRlKGRhdGUpKVxuICAgICAgICAgICAgOiBpbnB1dDtcbiAgICAgICAgbGV0IHJhbmdlID0gdGhpcy5yZWZpbmVSYW5nZShzaW1wbGVJbnB1dCk7XG4gICAgICAgIGlmIChyYW5nZSAmJiAocmFuZ2Uuc3RhcnQgPT0gbnVsbCB8fCByYW5nZS5lbmQgPT0gbnVsbCkpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByYW5nZTtcbiAgICB9XG4gICAgLy8gQ29tcHV0ZXMgdGhlIHJhbmdlIHRoYXQgd2lsbCByZXByZXNlbnQgdGhlIGVsZW1lbnQvY2VsbHMgZm9yICpyZW5kZXJpbmcqLFxuICAgIC8vIGJ1dCB3aGljaCBtYXkgaGF2ZSB2b2lkZWQgZGF5cy90aW1lcy5cbiAgICAvLyBub3QgcmVzcG9uc2libGUgZm9yIHRyaW1taW5nIGhpZGRlbiBkYXlzLlxuICAgIGJ1aWxkUmVuZGVyUmFuZ2UoY3VycmVudFJhbmdlLCBjdXJyZW50UmFuZ2VVbml0LCBpc1JhbmdlQWxsRGF5KSB7XG4gICAgICAgIHJldHVybiBjdXJyZW50UmFuZ2U7XG4gICAgfVxuICAgIC8vIENvbXB1dGUgdGhlIGR1cmF0aW9uIHZhbHVlIHRoYXQgc2hvdWxkIGJlIGFkZGVkL3N1YnN0cmFjdGVkIHRvIHRoZSBjdXJyZW50IGRhdGVcbiAgICAvLyB3aGVuIGEgcHJldi9uZXh0IG9wZXJhdGlvbiBoYXBwZW5zLlxuICAgIGJ1aWxkRGF0ZUluY3JlbWVudChmYWxsYmFjaykge1xuICAgICAgICBsZXQgeyBkYXRlSW5jcmVtZW50IH0gPSB0aGlzLnByb3BzO1xuICAgICAgICBsZXQgY3VzdG9tQWxpZ25tZW50O1xuICAgICAgICBpZiAoZGF0ZUluY3JlbWVudCkge1xuICAgICAgICAgICAgcmV0dXJuIGRhdGVJbmNyZW1lbnQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKChjdXN0b21BbGlnbm1lbnQgPSB0aGlzLnByb3BzLmRhdGVBbGlnbm1lbnQpKSB7XG4gICAgICAgICAgICByZXR1cm4gY3JlYXRlRHVyYXRpb24oMSwgY3VzdG9tQWxpZ25tZW50KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZmFsbGJhY2spIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxsYmFjaztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY3JlYXRlRHVyYXRpb24oeyBkYXlzOiAxIH0pO1xuICAgIH1cbiAgICByZWZpbmVSYW5nZShyYW5nZUlucHV0KSB7XG4gICAgICAgIGlmIChyYW5nZUlucHV0KSB7XG4gICAgICAgICAgICBsZXQgcmFuZ2UgPSBwYXJzZVJhbmdlKHJhbmdlSW5wdXQsIHRoaXMucHJvcHMuZGF0ZUVudik7XG4gICAgICAgICAgICBpZiAocmFuZ2UpIHtcbiAgICAgICAgICAgICAgICByYW5nZSA9IGNvbXB1dGVWaXNpYmxlRGF5UmFuZ2UocmFuZ2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHJhbmdlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICAvKiBIaWRkZW4gRGF5c1xuICAgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG4gICAgLy8gSW5pdGlhbGl6ZXMgaW50ZXJuYWwgdmFyaWFibGVzIHJlbGF0ZWQgdG8gY2FsY3VsYXRpbmcgaGlkZGVuIGRheXMtb2Ytd2Vla1xuICAgIGluaXRIaWRkZW5EYXlzKCkge1xuICAgICAgICBsZXQgaGlkZGVuRGF5cyA9IHRoaXMucHJvcHMuaGlkZGVuRGF5cyB8fCBbXTsgLy8gYXJyYXkgb2YgZGF5LW9mLXdlZWsgaW5kaWNlcyB0aGF0IGFyZSBoaWRkZW5cbiAgICAgICAgbGV0IGlzSGlkZGVuRGF5SGFzaCA9IFtdOyAvLyBpcyB0aGUgZGF5LW9mLXdlZWsgaGlkZGVuPyAoaGFzaCB3aXRoIGRheS1vZi13ZWVrLWluZGV4IC0+IGJvb2wpXG4gICAgICAgIGxldCBkYXlDbnQgPSAwO1xuICAgICAgICBsZXQgaTtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMud2Vla2VuZHMgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICBoaWRkZW5EYXlzLnB1c2goMCwgNik7IC8vIDA9c3VuZGF5LCA2PXNhdHVyZGF5XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChpID0gMDsgaSA8IDc7IGkgKz0gMSkge1xuICAgICAgICAgICAgaWYgKCEoaXNIaWRkZW5EYXlIYXNoW2ldID0gaGlkZGVuRGF5cy5pbmRleE9mKGkpICE9PSAtMSkpIHtcbiAgICAgICAgICAgICAgICBkYXlDbnQgKz0gMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoIWRheUNudCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGhpZGRlbkRheXMnKTsgLy8gYWxsIGRheXMgd2VyZSBoaWRkZW4/IGJhZC5cbiAgICAgICAgfVxuICAgICAgICB0aGlzLmlzSGlkZGVuRGF5SGFzaCA9IGlzSGlkZGVuRGF5SGFzaDtcbiAgICB9XG4gICAgLy8gUmVtb3ZlIGRheXMgZnJvbSB0aGUgYmVnaW5uaW5nIGFuZCBlbmQgb2YgdGhlIHJhbmdlIHRoYXQgYXJlIGNvbXB1dGVkIGFzIGhpZGRlbi5cbiAgICAvLyBJZiB0aGUgd2hvbGUgcmFuZ2UgaXMgdHJpbW1lZCBvZmYsIHJldHVybnMgbnVsbFxuICAgIHRyaW1IaWRkZW5EYXlzKHJhbmdlKSB7XG4gICAgICAgIGxldCB7IHN0YXJ0LCBlbmQgfSA9IHJhbmdlO1xuICAgICAgICBpZiAoc3RhcnQpIHtcbiAgICAgICAgICAgIHN0YXJ0ID0gdGhpcy5za2lwSGlkZGVuRGF5cyhzdGFydCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGVuZCkge1xuICAgICAgICAgICAgZW5kID0gdGhpcy5za2lwSGlkZGVuRGF5cyhlbmQsIC0xLCB0cnVlKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc3RhcnQgPT0gbnVsbCB8fCBlbmQgPT0gbnVsbCB8fCBzdGFydCA8IGVuZCkge1xuICAgICAgICAgICAgcmV0dXJuIHsgc3RhcnQsIGVuZCB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICAvLyBJcyB0aGUgY3VycmVudCBkYXkgaGlkZGVuP1xuICAgIC8vIGBkYXlgIGlzIGEgZGF5LW9mLXdlZWsgaW5kZXggKDAtNiksIG9yIGEgRGF0ZSAodXNlZCBmb3IgVVRDKVxuICAgIGlzSGlkZGVuRGF5KGRheSkge1xuICAgICAgICBpZiAoZGF5IGluc3RhbmNlb2YgRGF0ZSkge1xuICAgICAgICAgICAgZGF5ID0gZGF5LmdldFVUQ0RheSgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmlzSGlkZGVuRGF5SGFzaFtkYXldO1xuICAgIH1cbiAgICAvLyBJbmNyZW1lbnRpbmcgdGhlIGN1cnJlbnQgZGF5IHVudGlsIGl0IGlzIG5vIGxvbmdlciBhIGhpZGRlbiBkYXksIHJldHVybmluZyBhIGNvcHkuXG4gICAgLy8gRE9FUyBOT1QgQ09OU0lERVIgdmFsaWRSYW5nZSFcbiAgICAvLyBJZiB0aGUgaW5pdGlhbCB2YWx1ZSBvZiBgZGF0ZWAgaXMgbm90IGEgaGlkZGVuIGRheSwgZG9uJ3QgZG8gYW55dGhpbmcuXG4gICAgLy8gUGFzcyBgaXNFeGNsdXNpdmVgIGFzIGB0cnVlYCBpZiB5b3UgYXJlIGRlYWxpbmcgd2l0aCBhbiBlbmQgZGF0ZS5cbiAgICAvLyBgaW5jYCBkZWZhdWx0cyB0byBgMWAgKGluY3JlbWVudCBvbmUgZGF5IGZvcndhcmQgZWFjaCB0aW1lKVxuICAgIHNraXBIaWRkZW5EYXlzKGRhdGUsIGluYyA9IDEsIGlzRXhjbHVzaXZlID0gZmFsc2UpIHtcbiAgICAgICAgd2hpbGUgKHRoaXMuaXNIaWRkZW5EYXlIYXNoWyhkYXRlLmdldFVUQ0RheSgpICsgKGlzRXhjbHVzaXZlID8gaW5jIDogMCkgKyA3KSAlIDddKSB7XG4gICAgICAgICAgICBkYXRlID0gYWRkRGF5cyhkYXRlLCBpbmMpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBkYXRlO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gdHJpZ2dlckRhdGVTZWxlY3Qoc2VsZWN0aW9uLCBwZXYsIGNvbnRleHQpIHtcbiAgICBjb250ZXh0LmVtaXR0ZXIudHJpZ2dlcignc2VsZWN0JywgT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCBidWlsZERhdGVTcGFuQXBpV2l0aENvbnRleHQoc2VsZWN0aW9uLCBjb250ZXh0KSksIHsganNFdmVudDogcGV2ID8gcGV2Lm9yaWdFdmVudCA6IG51bGwsIHZpZXc6IGNvbnRleHQudmlld0FwaSB8fCBjb250ZXh0LmNhbGVuZGFyQXBpLnZpZXcgfSkpO1xufVxuZnVuY3Rpb24gdHJpZ2dlckRhdGVVbnNlbGVjdChwZXYsIGNvbnRleHQpIHtcbiAgICBjb250ZXh0LmVtaXR0ZXIudHJpZ2dlcigndW5zZWxlY3QnLCB7XG4gICAgICAgIGpzRXZlbnQ6IHBldiA/IHBldi5vcmlnRXZlbnQgOiBudWxsLFxuICAgICAgICB2aWV3OiBjb250ZXh0LnZpZXdBcGkgfHwgY29udGV4dC5jYWxlbmRhckFwaS52aWV3LFxuICAgIH0pO1xufVxuZnVuY3Rpb24gYnVpbGREYXRlU3BhbkFwaVdpdGhDb250ZXh0KGRhdGVTcGFuLCBjb250ZXh0KSB7XG4gICAgbGV0IHByb3BzID0ge307XG4gICAgZm9yIChsZXQgdHJhbnNmb3JtIG9mIGNvbnRleHQucGx1Z2luSG9va3MuZGF0ZVNwYW5UcmFuc2Zvcm1zKSB7XG4gICAgICAgIE9iamVjdC5hc3NpZ24ocHJvcHMsIHRyYW5zZm9ybShkYXRlU3BhbiwgY29udGV4dCkpO1xuICAgIH1cbiAgICBPYmplY3QuYXNzaWduKHByb3BzLCBidWlsZERhdGVTcGFuQXBpKGRhdGVTcGFuLCBjb250ZXh0LmRhdGVFbnYpKTtcbiAgICByZXR1cm4gcHJvcHM7XG59XG4vLyBHaXZlbiBhbiBldmVudCdzIGFsbERheSBzdGF0dXMgYW5kIHN0YXJ0IGRhdGUsIHJldHVybiB3aGF0IGl0cyBmYWxsYmFjayBlbmQgZGF0ZSBzaG91bGQgYmUuXG4vLyBUT0RPOiByZW5hbWUgdG8gY29tcHV0ZURlZmF1bHRFdmVudEVuZFxuZnVuY3Rpb24gZ2V0RGVmYXVsdEV2ZW50RW5kKGFsbERheSwgbWFya2VyLCBjb250ZXh0KSB7XG4gICAgbGV0IHsgZGF0ZUVudiwgb3B0aW9ucyB9ID0gY29udGV4dDtcbiAgICBsZXQgZW5kID0gbWFya2VyO1xuICAgIGlmIChhbGxEYXkpIHtcbiAgICAgICAgZW5kID0gc3RhcnRPZkRheShlbmQpO1xuICAgICAgICBlbmQgPSBkYXRlRW52LmFkZChlbmQsIG9wdGlvbnMuZGVmYXVsdEFsbERheUV2ZW50RHVyYXRpb24pO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgZW5kID0gZGF0ZUVudi5hZGQoZW5kLCBvcHRpb25zLmRlZmF1bHRUaW1lZEV2ZW50RHVyYXRpb24pO1xuICAgIH1cbiAgICByZXR1cm4gZW5kO1xufVxuXG4vLyBhcHBsaWVzIHRoZSBtdXRhdGlvbiB0byBBTEwgZGVmcy9pbnN0YW5jZXMgd2l0aGluIHRoZSBldmVudCBzdG9yZVxuZnVuY3Rpb24gYXBwbHlNdXRhdGlvblRvRXZlbnRTdG9yZShldmVudFN0b3JlLCBldmVudENvbmZpZ0Jhc2UsIG11dGF0aW9uLCBjb250ZXh0KSB7XG4gICAgbGV0IGV2ZW50Q29uZmlncyA9IGNvbXBpbGVFdmVudFVpcyhldmVudFN0b3JlLmRlZnMsIGV2ZW50Q29uZmlnQmFzZSk7XG4gICAgbGV0IGRlc3QgPSBjcmVhdGVFbXB0eUV2ZW50U3RvcmUoKTtcbiAgICBmb3IgKGxldCBkZWZJZCBpbiBldmVudFN0b3JlLmRlZnMpIHtcbiAgICAgICAgbGV0IGRlZiA9IGV2ZW50U3RvcmUuZGVmc1tkZWZJZF07XG4gICAgICAgIGRlc3QuZGVmc1tkZWZJZF0gPSBhcHBseU11dGF0aW9uVG9FdmVudERlZihkZWYsIGV2ZW50Q29uZmlnc1tkZWZJZF0sIG11dGF0aW9uLCBjb250ZXh0KTtcbiAgICB9XG4gICAgZm9yIChsZXQgaW5zdGFuY2VJZCBpbiBldmVudFN0b3JlLmluc3RhbmNlcykge1xuICAgICAgICBsZXQgaW5zdGFuY2UgPSBldmVudFN0b3JlLmluc3RhbmNlc1tpbnN0YW5jZUlkXTtcbiAgICAgICAgbGV0IGRlZiA9IGRlc3QuZGVmc1tpbnN0YW5jZS5kZWZJZF07IC8vIGltcG9ydGFudCB0byBncmFiIHRoZSBuZXdseSBtb2RpZmllZCBkZWZcbiAgICAgICAgZGVzdC5pbnN0YW5jZXNbaW5zdGFuY2VJZF0gPSBhcHBseU11dGF0aW9uVG9FdmVudEluc3RhbmNlKGluc3RhbmNlLCBkZWYsIGV2ZW50Q29uZmlnc1tpbnN0YW5jZS5kZWZJZF0sIG11dGF0aW9uLCBjb250ZXh0KTtcbiAgICB9XG4gICAgcmV0dXJuIGRlc3Q7XG59XG5mdW5jdGlvbiBhcHBseU11dGF0aW9uVG9FdmVudERlZihldmVudERlZiwgZXZlbnRDb25maWcsIG11dGF0aW9uLCBjb250ZXh0KSB7XG4gICAgbGV0IHN0YW5kYXJkUHJvcHMgPSBtdXRhdGlvbi5zdGFuZGFyZFByb3BzIHx8IHt9O1xuICAgIC8vIGlmIGhhc0VuZCBoYXMgbm90IGJlZW4gc3BlY2lmaWVkLCBndWVzcyBhIGdvb2QgdmFsdWUgYmFzZWQgb24gZGVsdGFzLlxuICAgIC8vIGlmIGR1cmF0aW9uIHdpbGwgY2hhbmdlLCB0aGVyZSdzIG5vIHdheSB0aGUgZGVmYXVsdCBkdXJhdGlvbiB3aWxsIHBlcnNpc3QsXG4gICAgLy8gYW5kIHRodXMsIHdlIG5lZWQgdG8gbWFyayB0aGUgZXZlbnQgYXMgaGF2aW5nIGEgcmVhbCBlbmRcbiAgICBpZiAoc3RhbmRhcmRQcm9wcy5oYXNFbmQgPT0gbnVsbCAmJlxuICAgICAgICBldmVudENvbmZpZy5kdXJhdGlvbkVkaXRhYmxlICYmXG4gICAgICAgIChtdXRhdGlvbi5zdGFydERlbHRhIHx8IG11dGF0aW9uLmVuZERlbHRhKSkge1xuICAgICAgICBzdGFuZGFyZFByb3BzLmhhc0VuZCA9IHRydWU7IC8vIFRPRE86IGlzIHRoaXMgbXV0YXRpb24gb2theT9cbiAgICB9XG4gICAgbGV0IGNvcHkgPSBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgZXZlbnREZWYpLCBzdGFuZGFyZFByb3BzKSwgeyB1aTogT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCBldmVudERlZi51aSksIHN0YW5kYXJkUHJvcHMudWkpIH0pO1xuICAgIGlmIChtdXRhdGlvbi5leHRlbmRlZFByb3BzKSB7XG4gICAgICAgIGNvcHkuZXh0ZW5kZWRQcm9wcyA9IE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgY29weS5leHRlbmRlZFByb3BzKSwgbXV0YXRpb24uZXh0ZW5kZWRQcm9wcyk7XG4gICAgfVxuICAgIGZvciAobGV0IGFwcGxpZXIgb2YgY29udGV4dC5wbHVnaW5Ib29rcy5ldmVudERlZk11dGF0aW9uQXBwbGllcnMpIHtcbiAgICAgICAgYXBwbGllcihjb3B5LCBtdXRhdGlvbiwgY29udGV4dCk7XG4gICAgfVxuICAgIGlmICghY29weS5oYXNFbmQgJiYgY29udGV4dC5vcHRpb25zLmZvcmNlRXZlbnREdXJhdGlvbikge1xuICAgICAgICBjb3B5Lmhhc0VuZCA9IHRydWU7XG4gICAgfVxuICAgIHJldHVybiBjb3B5O1xufVxuZnVuY3Rpb24gYXBwbHlNdXRhdGlvblRvRXZlbnRJbnN0YW5jZShldmVudEluc3RhbmNlLCBldmVudERlZiwgLy8gbXVzdCBmaXJzdCBiZSBtb2RpZmllZCBieSBhcHBseU11dGF0aW9uVG9FdmVudERlZlxuZXZlbnRDb25maWcsIG11dGF0aW9uLCBjb250ZXh0KSB7XG4gICAgbGV0IHsgZGF0ZUVudiB9ID0gY29udGV4dDtcbiAgICBsZXQgZm9yY2VBbGxEYXkgPSBtdXRhdGlvbi5zdGFuZGFyZFByb3BzICYmIG11dGF0aW9uLnN0YW5kYXJkUHJvcHMuYWxsRGF5ID09PSB0cnVlO1xuICAgIGxldCBjbGVhckVuZCA9IG11dGF0aW9uLnN0YW5kYXJkUHJvcHMgJiYgbXV0YXRpb24uc3RhbmRhcmRQcm9wcy5oYXNFbmQgPT09IGZhbHNlO1xuICAgIGxldCBjb3B5ID0gT2JqZWN0LmFzc2lnbih7fSwgZXZlbnRJbnN0YW5jZSk7XG4gICAgaWYgKGZvcmNlQWxsRGF5KSB7XG4gICAgICAgIGNvcHkucmFuZ2UgPSBjb21wdXRlQWxpZ25lZERheVJhbmdlKGNvcHkucmFuZ2UpO1xuICAgIH1cbiAgICBpZiAobXV0YXRpb24uZGF0ZXNEZWx0YSAmJiBldmVudENvbmZpZy5zdGFydEVkaXRhYmxlKSB7XG4gICAgICAgIGNvcHkucmFuZ2UgPSB7XG4gICAgICAgICAgICBzdGFydDogZGF0ZUVudi5hZGQoY29weS5yYW5nZS5zdGFydCwgbXV0YXRpb24uZGF0ZXNEZWx0YSksXG4gICAgICAgICAgICBlbmQ6IGRhdGVFbnYuYWRkKGNvcHkucmFuZ2UuZW5kLCBtdXRhdGlvbi5kYXRlc0RlbHRhKSxcbiAgICAgICAgfTtcbiAgICB9XG4gICAgaWYgKG11dGF0aW9uLnN0YXJ0RGVsdGEgJiYgZXZlbnRDb25maWcuZHVyYXRpb25FZGl0YWJsZSkge1xuICAgICAgICBjb3B5LnJhbmdlID0ge1xuICAgICAgICAgICAgc3RhcnQ6IGRhdGVFbnYuYWRkKGNvcHkucmFuZ2Uuc3RhcnQsIG11dGF0aW9uLnN0YXJ0RGVsdGEpLFxuICAgICAgICAgICAgZW5kOiBjb3B5LnJhbmdlLmVuZCxcbiAgICAgICAgfTtcbiAgICB9XG4gICAgaWYgKG11dGF0aW9uLmVuZERlbHRhICYmIGV2ZW50Q29uZmlnLmR1cmF0aW9uRWRpdGFibGUpIHtcbiAgICAgICAgY29weS5yYW5nZSA9IHtcbiAgICAgICAgICAgIHN0YXJ0OiBjb3B5LnJhbmdlLnN0YXJ0LFxuICAgICAgICAgICAgZW5kOiBkYXRlRW52LmFkZChjb3B5LnJhbmdlLmVuZCwgbXV0YXRpb24uZW5kRGVsdGEpLFxuICAgICAgICB9O1xuICAgIH1cbiAgICBpZiAoY2xlYXJFbmQpIHtcbiAgICAgICAgY29weS5yYW5nZSA9IHtcbiAgICAgICAgICAgIHN0YXJ0OiBjb3B5LnJhbmdlLnN0YXJ0LFxuICAgICAgICAgICAgZW5kOiBnZXREZWZhdWx0RXZlbnRFbmQoZXZlbnREZWYuYWxsRGF5LCBjb3B5LnJhbmdlLnN0YXJ0LCBjb250ZXh0KSxcbiAgICAgICAgfTtcbiAgICB9XG4gICAgLy8gaW4gY2FzZSBldmVudCB3YXMgYWxsLWRheSBidXQgdGhlIHN1cHBsaWVkIGRlbHRhcyB3ZXJlIG5vdFxuICAgIC8vIGJldHRlciB1dGlsIGZvciB0aGlzP1xuICAgIGlmIChldmVudERlZi5hbGxEYXkpIHtcbiAgICAgICAgY29weS5yYW5nZSA9IHtcbiAgICAgICAgICAgIHN0YXJ0OiBzdGFydE9mRGF5KGNvcHkucmFuZ2Uuc3RhcnQpLFxuICAgICAgICAgICAgZW5kOiBzdGFydE9mRGF5KGNvcHkucmFuZ2UuZW5kKSxcbiAgICAgICAgfTtcbiAgICB9XG4gICAgLy8gaGFuZGxlIGludmFsaWQgZHVyYXRpb25zXG4gICAgaWYgKGNvcHkucmFuZ2UuZW5kIDwgY29weS5yYW5nZS5zdGFydCkge1xuICAgICAgICBjb3B5LnJhbmdlLmVuZCA9IGdldERlZmF1bHRFdmVudEVuZChldmVudERlZi5hbGxEYXksIGNvcHkucmFuZ2Uuc3RhcnQsIGNvbnRleHQpO1xuICAgIH1cbiAgICByZXR1cm4gY29weTtcbn1cblxuY2xhc3MgRXZlbnRTb3VyY2VJbXBsIHtcbiAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBpbnRlcm5hbEV2ZW50U291cmNlKSB7XG4gICAgICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQ7XG4gICAgICAgIHRoaXMuaW50ZXJuYWxFdmVudFNvdXJjZSA9IGludGVybmFsRXZlbnRTb3VyY2U7XG4gICAgfVxuICAgIHJlbW92ZSgpIHtcbiAgICAgICAgdGhpcy5jb250ZXh0LmRpc3BhdGNoKHtcbiAgICAgICAgICAgIHR5cGU6ICdSRU1PVkVfRVZFTlRfU09VUkNFJyxcbiAgICAgICAgICAgIHNvdXJjZUlkOiB0aGlzLmludGVybmFsRXZlbnRTb3VyY2Uuc291cmNlSWQsXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICByZWZldGNoKCkge1xuICAgICAgICB0aGlzLmNvbnRleHQuZGlzcGF0Y2goe1xuICAgICAgICAgICAgdHlwZTogJ0ZFVENIX0VWRU5UX1NPVVJDRVMnLFxuICAgICAgICAgICAgc291cmNlSWRzOiBbdGhpcy5pbnRlcm5hbEV2ZW50U291cmNlLnNvdXJjZUlkXSxcbiAgICAgICAgICAgIGlzUmVmZXRjaDogdHJ1ZSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGdldCBpZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaW50ZXJuYWxFdmVudFNvdXJjZS5wdWJsaWNJZDtcbiAgICB9XG4gICAgZ2V0IHVybCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaW50ZXJuYWxFdmVudFNvdXJjZS5tZXRhLnVybDtcbiAgICB9XG4gICAgZ2V0IGZvcm1hdCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaW50ZXJuYWxFdmVudFNvdXJjZS5tZXRhLmZvcm1hdDsgLy8gVE9ETzogYmFkLiBub3QgZ3VhcmFudGVlZFxuICAgIH1cbn1cblxuY2xhc3MgRXZlbnRJbXBsIHtcbiAgICAvLyBpbnN0YW5jZSB3aWxsIGJlIG51bGwgaWYgZXhwcmVzc2luZyBhIHJlY3VycmluZyBldmVudCB0aGF0IGhhcyBubyBjdXJyZW50IGluc3RhbmNlcyxcbiAgICAvLyBPUiBpZiB0cnlpbmcgdG8gdmFsaWRhdGUgYW4gaW5jb21pbmcgZXh0ZXJuYWwgZXZlbnQgdGhhdCBoYXMgbm8gZGF0ZXMgYXNzaWduZWRcbiAgICBjb25zdHJ1Y3Rvcihjb250ZXh0LCBkZWYsIGluc3RhbmNlKSB7XG4gICAgICAgIHRoaXMuX2NvbnRleHQgPSBjb250ZXh0O1xuICAgICAgICB0aGlzLl9kZWYgPSBkZWY7XG4gICAgICAgIHRoaXMuX2luc3RhbmNlID0gaW5zdGFuY2UgfHwgbnVsbDtcbiAgICB9XG4gICAgLypcbiAgICBUT0RPOiBtYWtlIGV2ZW50IHN0cnVjdCBtb3JlIHJlc3BvbnNpYmxlIGZvciB0aGlzXG4gICAgKi9cbiAgICBzZXRQcm9wKG5hbWUsIHZhbCkge1xuICAgICAgICBpZiAobmFtZSBpbiBFVkVOVF9EQVRFX1JFRklORVJTKSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ0NvdWxkIG5vdCBzZXQgZGF0ZS1yZWxhdGVkIHByb3AgXFwnbmFtZVxcJy4gVXNlIG9uZSBvZiB0aGUgZGF0ZS1yZWxhdGVkIG1ldGhvZHMgaW5zdGVhZC4nKTtcbiAgICAgICAgICAgIC8vIFRPRE86IG1ha2UgcHJvcGVyIGFsaWFzaW5nIHN5c3RlbT9cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChuYW1lID09PSAnaWQnKSB7XG4gICAgICAgICAgICB2YWwgPSBFVkVOVF9OT05fREFURV9SRUZJTkVSU1tuYW1lXSh2YWwpO1xuICAgICAgICAgICAgdGhpcy5tdXRhdGUoe1xuICAgICAgICAgICAgICAgIHN0YW5kYXJkUHJvcHM6IHsgcHVibGljSWQ6IHZhbCB9LCAvLyBoYXJkY29kZWQgaW50ZXJuYWwgbmFtZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAobmFtZSBpbiBFVkVOVF9OT05fREFURV9SRUZJTkVSUykge1xuICAgICAgICAgICAgdmFsID0gRVZFTlRfTk9OX0RBVEVfUkVGSU5FUlNbbmFtZV0odmFsKTtcbiAgICAgICAgICAgIHRoaXMubXV0YXRlKHtcbiAgICAgICAgICAgICAgICBzdGFuZGFyZFByb3BzOiB7IFtuYW1lXTogdmFsIH0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChuYW1lIGluIEVWRU5UX1VJX1JFRklORVJTKSB7XG4gICAgICAgICAgICBsZXQgdWkgPSBFVkVOVF9VSV9SRUZJTkVSU1tuYW1lXSh2YWwpO1xuICAgICAgICAgICAgaWYgKG5hbWUgPT09ICdjb2xvcicpIHtcbiAgICAgICAgICAgICAgICB1aSA9IHsgYmFja2dyb3VuZENvbG9yOiB2YWwsIGJvcmRlckNvbG9yOiB2YWwgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKG5hbWUgPT09ICdlZGl0YWJsZScpIHtcbiAgICAgICAgICAgICAgICB1aSA9IHsgc3RhcnRFZGl0YWJsZTogdmFsLCBkdXJhdGlvbkVkaXRhYmxlOiB2YWwgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHVpID0geyBbbmFtZV06IHZhbCB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5tdXRhdGUoe1xuICAgICAgICAgICAgICAgIHN0YW5kYXJkUHJvcHM6IHsgdWkgfSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKGBDb3VsZCBub3Qgc2V0IHByb3AgJyR7bmFtZX0nLiBVc2Ugc2V0RXh0ZW5kZWRQcm9wIGluc3RlYWQuYCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc2V0RXh0ZW5kZWRQcm9wKG5hbWUsIHZhbCkge1xuICAgICAgICB0aGlzLm11dGF0ZSh7XG4gICAgICAgICAgICBleHRlbmRlZFByb3BzOiB7IFtuYW1lXTogdmFsIH0sXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBzZXRTdGFydChzdGFydElucHV0LCBvcHRpb25zID0ge30pIHtcbiAgICAgICAgbGV0IHsgZGF0ZUVudiB9ID0gdGhpcy5fY29udGV4dDtcbiAgICAgICAgbGV0IHN0YXJ0ID0gZGF0ZUVudi5jcmVhdGVNYXJrZXIoc3RhcnRJbnB1dCk7XG4gICAgICAgIGlmIChzdGFydCAmJiB0aGlzLl9pbnN0YW5jZSkgeyAvLyBUT0RPOiB3YXJuaW5nIGlmIHBhcnNlZCBiYWRcbiAgICAgICAgICAgIGxldCBpbnN0YW5jZVJhbmdlID0gdGhpcy5faW5zdGFuY2UucmFuZ2U7XG4gICAgICAgICAgICBsZXQgc3RhcnREZWx0YSA9IGRpZmZEYXRlcyhpbnN0YW5jZVJhbmdlLnN0YXJ0LCBzdGFydCwgZGF0ZUVudiwgb3B0aW9ucy5ncmFudWxhcml0eSk7IC8vIHdoYXQgaWYgcGFyc2VkIGJhZCE/XG4gICAgICAgICAgICBpZiAob3B0aW9ucy5tYWludGFpbkR1cmF0aW9uKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5tdXRhdGUoeyBkYXRlc0RlbHRhOiBzdGFydERlbHRhIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5tdXRhdGUoeyBzdGFydERlbHRhIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIHNldEVuZChlbmRJbnB1dCwgb3B0aW9ucyA9IHt9KSB7XG4gICAgICAgIGxldCB7IGRhdGVFbnYgfSA9IHRoaXMuX2NvbnRleHQ7XG4gICAgICAgIGxldCBlbmQ7XG4gICAgICAgIGlmIChlbmRJbnB1dCAhPSBudWxsKSB7XG4gICAgICAgICAgICBlbmQgPSBkYXRlRW52LmNyZWF0ZU1hcmtlcihlbmRJbnB1dCk7XG4gICAgICAgICAgICBpZiAoIWVuZCkge1xuICAgICAgICAgICAgICAgIHJldHVybjsgLy8gVE9ETzogd2FybmluZyBpZiBwYXJzZWQgYmFkXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuX2luc3RhbmNlKSB7XG4gICAgICAgICAgICBpZiAoZW5kKSB7XG4gICAgICAgICAgICAgICAgbGV0IGVuZERlbHRhID0gZGlmZkRhdGVzKHRoaXMuX2luc3RhbmNlLnJhbmdlLmVuZCwgZW5kLCBkYXRlRW52LCBvcHRpb25zLmdyYW51bGFyaXR5KTtcbiAgICAgICAgICAgICAgICB0aGlzLm11dGF0ZSh7IGVuZERlbHRhIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5tdXRhdGUoeyBzdGFuZGFyZFByb3BzOiB7IGhhc0VuZDogZmFsc2UgfSB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICBzZXREYXRlcyhzdGFydElucHV0LCBlbmRJbnB1dCwgb3B0aW9ucyA9IHt9KSB7XG4gICAgICAgIGxldCB7IGRhdGVFbnYgfSA9IHRoaXMuX2NvbnRleHQ7XG4gICAgICAgIGxldCBzdGFuZGFyZFByb3BzID0geyBhbGxEYXk6IG9wdGlvbnMuYWxsRGF5IH07XG4gICAgICAgIGxldCBzdGFydCA9IGRhdGVFbnYuY3JlYXRlTWFya2VyKHN0YXJ0SW5wdXQpO1xuICAgICAgICBsZXQgZW5kO1xuICAgICAgICBpZiAoIXN0YXJ0KSB7XG4gICAgICAgICAgICByZXR1cm47IC8vIFRPRE86IHdhcm5pbmcgaWYgcGFyc2VkIGJhZFxuICAgICAgICB9XG4gICAgICAgIGlmIChlbmRJbnB1dCAhPSBudWxsKSB7XG4gICAgICAgICAgICBlbmQgPSBkYXRlRW52LmNyZWF0ZU1hcmtlcihlbmRJbnB1dCk7XG4gICAgICAgICAgICBpZiAoIWVuZCkgeyAvLyBUT0RPOiB3YXJuaW5nIGlmIHBhcnNlZCBiYWRcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuX2luc3RhbmNlKSB7XG4gICAgICAgICAgICBsZXQgaW5zdGFuY2VSYW5nZSA9IHRoaXMuX2luc3RhbmNlLnJhbmdlO1xuICAgICAgICAgICAgLy8gd2hlbiBjb21wdXRpbmcgdGhlIGRpZmYgZm9yIGFuIGV2ZW50IGJlaW5nIGNvbnZlcnRlZCB0byBhbGwtZGF5LFxuICAgICAgICAgICAgLy8gY29tcHV0ZSBkaWZmIG9mZiBvZiB0aGUgYWxsLWRheSB2YWx1ZXMgdGhlIHdheSBldmVudC1tdXRhdGlvbiBkb2VzLlxuICAgICAgICAgICAgaWYgKG9wdGlvbnMuYWxsRGF5ID09PSB0cnVlKSB7XG4gICAgICAgICAgICAgICAgaW5zdGFuY2VSYW5nZSA9IGNvbXB1dGVBbGlnbmVkRGF5UmFuZ2UoaW5zdGFuY2VSYW5nZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsZXQgc3RhcnREZWx0YSA9IGRpZmZEYXRlcyhpbnN0YW5jZVJhbmdlLnN0YXJ0LCBzdGFydCwgZGF0ZUVudiwgb3B0aW9ucy5ncmFudWxhcml0eSk7XG4gICAgICAgICAgICBpZiAoZW5kKSB7XG4gICAgICAgICAgICAgICAgbGV0IGVuZERlbHRhID0gZGlmZkRhdGVzKGluc3RhbmNlUmFuZ2UuZW5kLCBlbmQsIGRhdGVFbnYsIG9wdGlvbnMuZ3JhbnVsYXJpdHkpO1xuICAgICAgICAgICAgICAgIGlmIChkdXJhdGlvbnNFcXVhbChzdGFydERlbHRhLCBlbmREZWx0YSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5tdXRhdGUoeyBkYXRlc0RlbHRhOiBzdGFydERlbHRhLCBzdGFuZGFyZFByb3BzIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5tdXRhdGUoeyBzdGFydERlbHRhLCBlbmREZWx0YSwgc3RhbmRhcmRQcm9wcyB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHsgLy8gbWVhbnMgXCJjbGVhciB0aGUgZW5kXCJcbiAgICAgICAgICAgICAgICBzdGFuZGFyZFByb3BzLmhhc0VuZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHRoaXMubXV0YXRlKHsgZGF0ZXNEZWx0YTogc3RhcnREZWx0YSwgc3RhbmRhcmRQcm9wcyB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICBtb3ZlU3RhcnQoZGVsdGFJbnB1dCkge1xuICAgICAgICBsZXQgZGVsdGEgPSBjcmVhdGVEdXJhdGlvbihkZWx0YUlucHV0KTtcbiAgICAgICAgaWYgKGRlbHRhKSB7IC8vIFRPRE86IHdhcm5pbmcgaWYgcGFyc2VkIGJhZFxuICAgICAgICAgICAgdGhpcy5tdXRhdGUoeyBzdGFydERlbHRhOiBkZWx0YSB9KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBtb3ZlRW5kKGRlbHRhSW5wdXQpIHtcbiAgICAgICAgbGV0IGRlbHRhID0gY3JlYXRlRHVyYXRpb24oZGVsdGFJbnB1dCk7XG4gICAgICAgIGlmIChkZWx0YSkgeyAvLyBUT0RPOiB3YXJuaW5nIGlmIHBhcnNlZCBiYWRcbiAgICAgICAgICAgIHRoaXMubXV0YXRlKHsgZW5kRGVsdGE6IGRlbHRhIH0pO1xuICAgICAgICB9XG4gICAgfVxuICAgIG1vdmVEYXRlcyhkZWx0YUlucHV0KSB7XG4gICAgICAgIGxldCBkZWx0YSA9IGNyZWF0ZUR1cmF0aW9uKGRlbHRhSW5wdXQpO1xuICAgICAgICBpZiAoZGVsdGEpIHsgLy8gVE9ETzogd2FybmluZyBpZiBwYXJzZWQgYmFkXG4gICAgICAgICAgICB0aGlzLm11dGF0ZSh7IGRhdGVzRGVsdGE6IGRlbHRhIH0pO1xuICAgICAgICB9XG4gICAgfVxuICAgIHNldEFsbERheShhbGxEYXksIG9wdGlvbnMgPSB7fSkge1xuICAgICAgICBsZXQgc3RhbmRhcmRQcm9wcyA9IHsgYWxsRGF5IH07XG4gICAgICAgIGxldCB7IG1haW50YWluRHVyYXRpb24gfSA9IG9wdGlvbnM7XG4gICAgICAgIGlmIChtYWludGFpbkR1cmF0aW9uID09IG51bGwpIHtcbiAgICAgICAgICAgIG1haW50YWluRHVyYXRpb24gPSB0aGlzLl9jb250ZXh0Lm9wdGlvbnMuYWxsRGF5TWFpbnRhaW5EdXJhdGlvbjtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5fZGVmLmFsbERheSAhPT0gYWxsRGF5KSB7XG4gICAgICAgICAgICBzdGFuZGFyZFByb3BzLmhhc0VuZCA9IG1haW50YWluRHVyYXRpb247XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5tdXRhdGUoeyBzdGFuZGFyZFByb3BzIH0pO1xuICAgIH1cbiAgICBmb3JtYXRSYW5nZShmb3JtYXRJbnB1dCkge1xuICAgICAgICBsZXQgeyBkYXRlRW52IH0gPSB0aGlzLl9jb250ZXh0O1xuICAgICAgICBsZXQgaW5zdGFuY2UgPSB0aGlzLl9pbnN0YW5jZTtcbiAgICAgICAgbGV0IGZvcm1hdHRlciA9IGNyZWF0ZUZvcm1hdHRlcihmb3JtYXRJbnB1dCk7XG4gICAgICAgIGlmICh0aGlzLl9kZWYuaGFzRW5kKSB7XG4gICAgICAgICAgICByZXR1cm4gZGF0ZUVudi5mb3JtYXRSYW5nZShpbnN0YW5jZS5yYW5nZS5zdGFydCwgaW5zdGFuY2UucmFuZ2UuZW5kLCBmb3JtYXR0ZXIsIHtcbiAgICAgICAgICAgICAgICBmb3JjZWRTdGFydFR6bzogaW5zdGFuY2UuZm9yY2VkU3RhcnRUem8sXG4gICAgICAgICAgICAgICAgZm9yY2VkRW5kVHpvOiBpbnN0YW5jZS5mb3JjZWRFbmRUem8sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZGF0ZUVudi5mb3JtYXQoaW5zdGFuY2UucmFuZ2Uuc3RhcnQsIGZvcm1hdHRlciwge1xuICAgICAgICAgICAgZm9yY2VkVHpvOiBpbnN0YW5jZS5mb3JjZWRTdGFydFR6byxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIG11dGF0ZShtdXRhdGlvbikge1xuICAgICAgICBsZXQgaW5zdGFuY2UgPSB0aGlzLl9pbnN0YW5jZTtcbiAgICAgICAgaWYgKGluc3RhbmNlKSB7XG4gICAgICAgICAgICBsZXQgZGVmID0gdGhpcy5fZGVmO1xuICAgICAgICAgICAgbGV0IGNvbnRleHQgPSB0aGlzLl9jb250ZXh0O1xuICAgICAgICAgICAgbGV0IHsgZXZlbnRTdG9yZSB9ID0gY29udGV4dC5nZXRDdXJyZW50RGF0YSgpO1xuICAgICAgICAgICAgbGV0IHJlbGV2YW50RXZlbnRzID0gZ2V0UmVsZXZhbnRFdmVudHMoZXZlbnRTdG9yZSwgaW5zdGFuY2UuaW5zdGFuY2VJZCk7XG4gICAgICAgICAgICBsZXQgZXZlbnRDb25maWdCYXNlID0ge1xuICAgICAgICAgICAgICAgICcnOiB7XG4gICAgICAgICAgICAgICAgICAgIGRpc3BsYXk6ICcnLFxuICAgICAgICAgICAgICAgICAgICBzdGFydEVkaXRhYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBkdXJhdGlvbkVkaXRhYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBjb25zdHJhaW50czogW10sXG4gICAgICAgICAgICAgICAgICAgIG92ZXJsYXA6IG51bGwsXG4gICAgICAgICAgICAgICAgICAgIGFsbG93czogW10sXG4gICAgICAgICAgICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogJycsXG4gICAgICAgICAgICAgICAgICAgIGJvcmRlckNvbG9yOiAnJyxcbiAgICAgICAgICAgICAgICAgICAgdGV4dENvbG9yOiAnJyxcbiAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lczogW10sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICByZWxldmFudEV2ZW50cyA9IGFwcGx5TXV0YXRpb25Ub0V2ZW50U3RvcmUocmVsZXZhbnRFdmVudHMsIGV2ZW50Q29uZmlnQmFzZSwgbXV0YXRpb24sIGNvbnRleHQpO1xuICAgICAgICAgICAgbGV0IG9sZEV2ZW50ID0gbmV3IEV2ZW50SW1wbChjb250ZXh0LCBkZWYsIGluc3RhbmNlKTsgLy8gc25hcHNob3RcbiAgICAgICAgICAgIHRoaXMuX2RlZiA9IHJlbGV2YW50RXZlbnRzLmRlZnNbZGVmLmRlZklkXTtcbiAgICAgICAgICAgIHRoaXMuX2luc3RhbmNlID0gcmVsZXZhbnRFdmVudHMuaW5zdGFuY2VzW2luc3RhbmNlLmluc3RhbmNlSWRdO1xuICAgICAgICAgICAgY29udGV4dC5kaXNwYXRjaCh7XG4gICAgICAgICAgICAgICAgdHlwZTogJ01FUkdFX0VWRU5UUycsXG4gICAgICAgICAgICAgICAgZXZlbnRTdG9yZTogcmVsZXZhbnRFdmVudHMsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNvbnRleHQuZW1pdHRlci50cmlnZ2VyKCdldmVudENoYW5nZScsIHtcbiAgICAgICAgICAgICAgICBvbGRFdmVudCxcbiAgICAgICAgICAgICAgICBldmVudDogdGhpcyxcbiAgICAgICAgICAgICAgICByZWxhdGVkRXZlbnRzOiBidWlsZEV2ZW50QXBpcyhyZWxldmFudEV2ZW50cywgY29udGV4dCwgaW5zdGFuY2UpLFxuICAgICAgICAgICAgICAgIHJldmVydCgpIHtcbiAgICAgICAgICAgICAgICAgICAgY29udGV4dC5kaXNwYXRjaCh7XG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAnUkVTRVRfRVZFTlRTJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50U3RvcmUsIC8vIHRoZSBPUklHSU5BTCBzdG9yZVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmVtb3ZlKCkge1xuICAgICAgICBsZXQgY29udGV4dCA9IHRoaXMuX2NvbnRleHQ7XG4gICAgICAgIGxldCBhc1N0b3JlID0gZXZlbnRBcGlUb1N0b3JlKHRoaXMpO1xuICAgICAgICBjb250ZXh0LmRpc3BhdGNoKHtcbiAgICAgICAgICAgIHR5cGU6ICdSRU1PVkVfRVZFTlRTJyxcbiAgICAgICAgICAgIGV2ZW50U3RvcmU6IGFzU3RvcmUsXG4gICAgICAgIH0pO1xuICAgICAgICBjb250ZXh0LmVtaXR0ZXIudHJpZ2dlcignZXZlbnRSZW1vdmUnLCB7XG4gICAgICAgICAgICBldmVudDogdGhpcyxcbiAgICAgICAgICAgIHJlbGF0ZWRFdmVudHM6IFtdLFxuICAgICAgICAgICAgcmV2ZXJ0KCkge1xuICAgICAgICAgICAgICAgIGNvbnRleHQuZGlzcGF0Y2goe1xuICAgICAgICAgICAgICAgICAgICB0eXBlOiAnTUVSR0VfRVZFTlRTJyxcbiAgICAgICAgICAgICAgICAgICAgZXZlbnRTdG9yZTogYXNTdG9yZSxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBnZXQgc291cmNlKCkge1xuICAgICAgICBsZXQgeyBzb3VyY2VJZCB9ID0gdGhpcy5fZGVmO1xuICAgICAgICBpZiAoc291cmNlSWQpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgRXZlbnRTb3VyY2VJbXBsKHRoaXMuX2NvbnRleHQsIHRoaXMuX2NvbnRleHQuZ2V0Q3VycmVudERhdGEoKS5ldmVudFNvdXJjZXNbc291cmNlSWRdKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgZ2V0IHN0YXJ0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5faW5zdGFuY2UgP1xuICAgICAgICAgICAgdGhpcy5fY29udGV4dC5kYXRlRW52LnRvRGF0ZSh0aGlzLl9pbnN0YW5jZS5yYW5nZS5zdGFydCkgOlxuICAgICAgICAgICAgbnVsbDtcbiAgICB9XG4gICAgZ2V0IGVuZCgpIHtcbiAgICAgICAgcmV0dXJuICh0aGlzLl9pbnN0YW5jZSAmJiB0aGlzLl9kZWYuaGFzRW5kKSA/XG4gICAgICAgICAgICB0aGlzLl9jb250ZXh0LmRhdGVFbnYudG9EYXRlKHRoaXMuX2luc3RhbmNlLnJhbmdlLmVuZCkgOlxuICAgICAgICAgICAgbnVsbDtcbiAgICB9XG4gICAgZ2V0IHN0YXJ0U3RyKCkge1xuICAgICAgICBsZXQgaW5zdGFuY2UgPSB0aGlzLl9pbnN0YW5jZTtcbiAgICAgICAgaWYgKGluc3RhbmNlKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dC5kYXRlRW52LmZvcm1hdElzbyhpbnN0YW5jZS5yYW5nZS5zdGFydCwge1xuICAgICAgICAgICAgICAgIG9taXRUaW1lOiB0aGlzLl9kZWYuYWxsRGF5LFxuICAgICAgICAgICAgICAgIGZvcmNlZFR6bzogaW5zdGFuY2UuZm9yY2VkU3RhcnRUem8sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gJyc7XG4gICAgfVxuICAgIGdldCBlbmRTdHIoKSB7XG4gICAgICAgIGxldCBpbnN0YW5jZSA9IHRoaXMuX2luc3RhbmNlO1xuICAgICAgICBpZiAoaW5zdGFuY2UgJiYgdGhpcy5fZGVmLmhhc0VuZCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2NvbnRleHQuZGF0ZUVudi5mb3JtYXRJc28oaW5zdGFuY2UucmFuZ2UuZW5kLCB7XG4gICAgICAgICAgICAgICAgb21pdFRpbWU6IHRoaXMuX2RlZi5hbGxEYXksXG4gICAgICAgICAgICAgICAgZm9yY2VkVHpvOiBpbnN0YW5jZS5mb3JjZWRFbmRUem8sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gJyc7XG4gICAgfVxuICAgIC8vIGNvbXB1dGFibGUgcHJvcHMgdGhhdCBhbGwgYWNjZXNzIHRoZSBkZWZcbiAgICAvLyBUT0RPOiBmaW5kIGEgVHlwZVNjcmlwdC1jb21wYXRpYmxlIHdheSB0byBkbyB0aGlzIGF0IHNjYWxlXG4gICAgZ2V0IGlkKCkgeyByZXR1cm4gdGhpcy5fZGVmLnB1YmxpY0lkOyB9XG4gICAgZ2V0IGdyb3VwSWQoKSB7IHJldHVybiB0aGlzLl9kZWYuZ3JvdXBJZDsgfVxuICAgIGdldCBhbGxEYXkoKSB7IHJldHVybiB0aGlzLl9kZWYuYWxsRGF5OyB9XG4gICAgZ2V0IHRpdGxlKCkgeyByZXR1cm4gdGhpcy5fZGVmLnRpdGxlOyB9XG4gICAgZ2V0IHVybCgpIHsgcmV0dXJuIHRoaXMuX2RlZi51cmw7IH1cbiAgICBnZXQgZGlzcGxheSgpIHsgcmV0dXJuIHRoaXMuX2RlZi51aS5kaXNwbGF5IHx8ICdhdXRvJzsgfSAvLyBiYWQuIGp1c3Qgbm9ybWFsaXplIHRoZSB0eXBlIGVhcmxpZXJcbiAgICBnZXQgc3RhcnRFZGl0YWJsZSgpIHsgcmV0dXJuIHRoaXMuX2RlZi51aS5zdGFydEVkaXRhYmxlOyB9XG4gICAgZ2V0IGR1cmF0aW9uRWRpdGFibGUoKSB7IHJldHVybiB0aGlzLl9kZWYudWkuZHVyYXRpb25FZGl0YWJsZTsgfVxuICAgIGdldCBjb25zdHJhaW50KCkgeyByZXR1cm4gdGhpcy5fZGVmLnVpLmNvbnN0cmFpbnRzWzBdIHx8IG51bGw7IH1cbiAgICBnZXQgb3ZlcmxhcCgpIHsgcmV0dXJuIHRoaXMuX2RlZi51aS5vdmVybGFwOyB9XG4gICAgZ2V0IGFsbG93KCkgeyByZXR1cm4gdGhpcy5fZGVmLnVpLmFsbG93c1swXSB8fCBudWxsOyB9XG4gICAgZ2V0IGJhY2tncm91bmRDb2xvcigpIHsgcmV0dXJuIHRoaXMuX2RlZi51aS5iYWNrZ3JvdW5kQ29sb3I7IH1cbiAgICBnZXQgYm9yZGVyQ29sb3IoKSB7IHJldHVybiB0aGlzLl9kZWYudWkuYm9yZGVyQ29sb3I7IH1cbiAgICBnZXQgdGV4dENvbG9yKCkgeyByZXR1cm4gdGhpcy5fZGVmLnVpLnRleHRDb2xvcjsgfVxuICAgIC8vIE5PVEU6IHVzZXIgY2FuJ3QgbW9kaWZ5IHRoZXNlIGJlY2F1c2UgT2JqZWN0LmZyZWV6ZSB3YXMgY2FsbGVkIGluIGV2ZW50LWRlZiBwYXJzaW5nXG4gICAgZ2V0IGNsYXNzTmFtZXMoKSB7IHJldHVybiB0aGlzLl9kZWYudWkuY2xhc3NOYW1lczsgfVxuICAgIGdldCBleHRlbmRlZFByb3BzKCkgeyByZXR1cm4gdGhpcy5fZGVmLmV4dGVuZGVkUHJvcHM7IH1cbiAgICB0b1BsYWluT2JqZWN0KHNldHRpbmdzID0ge30pIHtcbiAgICAgICAgbGV0IGRlZiA9IHRoaXMuX2RlZjtcbiAgICAgICAgbGV0IHsgdWkgfSA9IGRlZjtcbiAgICAgICAgbGV0IHsgc3RhcnRTdHIsIGVuZFN0ciB9ID0gdGhpcztcbiAgICAgICAgbGV0IHJlcyA9IHt9O1xuICAgICAgICBpZiAoZGVmLnRpdGxlKSB7XG4gICAgICAgICAgICByZXMudGl0bGUgPSBkZWYudGl0bGU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHN0YXJ0U3RyKSB7XG4gICAgICAgICAgICByZXMuc3RhcnQgPSBzdGFydFN0cjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZW5kU3RyKSB7XG4gICAgICAgICAgICByZXMuZW5kID0gZW5kU3RyO1xuICAgICAgICB9XG4gICAgICAgIGlmIChkZWYucHVibGljSWQpIHtcbiAgICAgICAgICAgIHJlcy5pZCA9IGRlZi5wdWJsaWNJZDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZGVmLmdyb3VwSWQpIHtcbiAgICAgICAgICAgIHJlcy5ncm91cElkID0gZGVmLmdyb3VwSWQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGRlZi51cmwpIHtcbiAgICAgICAgICAgIHJlcy51cmwgPSBkZWYudXJsO1xuICAgICAgICB9XG4gICAgICAgIGlmICh1aS5kaXNwbGF5ICYmIHVpLmRpc3BsYXkgIT09ICdhdXRvJykge1xuICAgICAgICAgICAgcmVzLmRpc3BsYXkgPSB1aS5kaXNwbGF5O1xuICAgICAgICB9XG4gICAgICAgIC8vIFRPRE86IHdoYXQgYWJvdXQgcmVjdXJyaW5nLWV2ZW50IHByb3BlcnRpZXM/Pz9cbiAgICAgICAgLy8gVE9ETzogaW5jbHVkZSBzdGFydEVkaXRhYmxlL2R1cmF0aW9uRWRpdGFibGUvY29uc3RyYWludC9vdmVybGFwL2FsbG93XG4gICAgICAgIGlmIChzZXR0aW5ncy5jb2xsYXBzZUNvbG9yICYmIHVpLmJhY2tncm91bmRDb2xvciAmJiB1aS5iYWNrZ3JvdW5kQ29sb3IgPT09IHVpLmJvcmRlckNvbG9yKSB7XG4gICAgICAgICAgICByZXMuY29sb3IgPSB1aS5iYWNrZ3JvdW5kQ29sb3I7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBpZiAodWkuYmFja2dyb3VuZENvbG9yKSB7XG4gICAgICAgICAgICAgICAgcmVzLmJhY2tncm91bmRDb2xvciA9IHVpLmJhY2tncm91bmRDb2xvcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh1aS5ib3JkZXJDb2xvcikge1xuICAgICAgICAgICAgICAgIHJlcy5ib3JkZXJDb2xvciA9IHVpLmJvcmRlckNvbG9yO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh1aS50ZXh0Q29sb3IpIHtcbiAgICAgICAgICAgIHJlcy50ZXh0Q29sb3IgPSB1aS50ZXh0Q29sb3I7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHVpLmNsYXNzTmFtZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXMuY2xhc3NOYW1lcyA9IHVpLmNsYXNzTmFtZXM7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKE9iamVjdC5rZXlzKGRlZi5leHRlbmRlZFByb3BzKS5sZW5ndGgpIHtcbiAgICAgICAgICAgIGlmIChzZXR0aW5ncy5jb2xsYXBzZUV4dGVuZGVkUHJvcHMpIHtcbiAgICAgICAgICAgICAgICBPYmplY3QuYXNzaWduKHJlcywgZGVmLmV4dGVuZGVkUHJvcHMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVzLmV4dGVuZGVkUHJvcHMgPSBkZWYuZXh0ZW5kZWRQcm9wcztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzO1xuICAgIH1cbiAgICB0b0pTT04oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnRvUGxhaW5PYmplY3QoKTtcbiAgICB9XG59XG5mdW5jdGlvbiBldmVudEFwaVRvU3RvcmUoZXZlbnRBcGkpIHtcbiAgICBsZXQgZGVmID0gZXZlbnRBcGkuX2RlZjtcbiAgICBsZXQgaW5zdGFuY2UgPSBldmVudEFwaS5faW5zdGFuY2U7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgZGVmczogeyBbZGVmLmRlZklkXTogZGVmIH0sXG4gICAgICAgIGluc3RhbmNlczogaW5zdGFuY2VcbiAgICAgICAgICAgID8geyBbaW5zdGFuY2UuaW5zdGFuY2VJZF06IGluc3RhbmNlIH1cbiAgICAgICAgICAgIDoge30sXG4gICAgfTtcbn1cbmZ1bmN0aW9uIGJ1aWxkRXZlbnRBcGlzKGV2ZW50U3RvcmUsIGNvbnRleHQsIGV4Y2x1ZGVJbnN0YW5jZSkge1xuICAgIGxldCB7IGRlZnMsIGluc3RhbmNlcyB9ID0gZXZlbnRTdG9yZTtcbiAgICBsZXQgZXZlbnRBcGlzID0gW107XG4gICAgbGV0IGV4Y2x1ZGVJbnN0YW5jZUlkID0gZXhjbHVkZUluc3RhbmNlID8gZXhjbHVkZUluc3RhbmNlLmluc3RhbmNlSWQgOiAnJztcbiAgICBmb3IgKGxldCBpZCBpbiBpbnN0YW5jZXMpIHtcbiAgICAgICAgbGV0IGluc3RhbmNlID0gaW5zdGFuY2VzW2lkXTtcbiAgICAgICAgbGV0IGRlZiA9IGRlZnNbaW5zdGFuY2UuZGVmSWRdO1xuICAgICAgICBpZiAoaW5zdGFuY2UuaW5zdGFuY2VJZCAhPT0gZXhjbHVkZUluc3RhbmNlSWQpIHtcbiAgICAgICAgICAgIGV2ZW50QXBpcy5wdXNoKG5ldyBFdmVudEltcGwoY29udGV4dCwgZGVmLCBpbnN0YW5jZSkpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBldmVudEFwaXM7XG59XG5cbi8qXG5TcGVjaWZ5aW5nIG5leHREYXlUaHJlc2hvbGQgc2lnbmFscyB0aGF0IGFsbC1kYXkgcmFuZ2VzIHNob3VsZCBiZSBzbGljZWQuXG4qL1xuZnVuY3Rpb24gc2xpY2VFdmVudFN0b3JlKGV2ZW50U3RvcmUsIGV2ZW50VWlCYXNlcywgZnJhbWluZ1JhbmdlLCBuZXh0RGF5VGhyZXNob2xkKSB7XG4gICAgbGV0IGludmVyc2VCZ0J5R3JvdXBJZCA9IHt9O1xuICAgIGxldCBpbnZlcnNlQmdCeURlZklkID0ge307XG4gICAgbGV0IGRlZkJ5R3JvdXBJZCA9IHt9O1xuICAgIGxldCBiZ1JhbmdlcyA9IFtdO1xuICAgIGxldCBmZ1JhbmdlcyA9IFtdO1xuICAgIGxldCBldmVudFVpcyA9IGNvbXBpbGVFdmVudFVpcyhldmVudFN0b3JlLmRlZnMsIGV2ZW50VWlCYXNlcyk7XG4gICAgZm9yIChsZXQgZGVmSWQgaW4gZXZlbnRTdG9yZS5kZWZzKSB7XG4gICAgICAgIGxldCBkZWYgPSBldmVudFN0b3JlLmRlZnNbZGVmSWRdO1xuICAgICAgICBsZXQgdWkgPSBldmVudFVpc1tkZWYuZGVmSWRdO1xuICAgICAgICBpZiAodWkuZGlzcGxheSA9PT0gJ2ludmVyc2UtYmFja2dyb3VuZCcpIHtcbiAgICAgICAgICAgIGlmIChkZWYuZ3JvdXBJZCkge1xuICAgICAgICAgICAgICAgIGludmVyc2VCZ0J5R3JvdXBJZFtkZWYuZ3JvdXBJZF0gPSBbXTtcbiAgICAgICAgICAgICAgICBpZiAoIWRlZkJ5R3JvdXBJZFtkZWYuZ3JvdXBJZF0pIHtcbiAgICAgICAgICAgICAgICAgICAgZGVmQnlHcm91cElkW2RlZi5ncm91cElkXSA9IGRlZjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBpbnZlcnNlQmdCeURlZklkW2RlZklkXSA9IFtdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIGZvciAobGV0IGluc3RhbmNlSWQgaW4gZXZlbnRTdG9yZS5pbnN0YW5jZXMpIHtcbiAgICAgICAgbGV0IGluc3RhbmNlID0gZXZlbnRTdG9yZS5pbnN0YW5jZXNbaW5zdGFuY2VJZF07XG4gICAgICAgIGxldCBkZWYgPSBldmVudFN0b3JlLmRlZnNbaW5zdGFuY2UuZGVmSWRdO1xuICAgICAgICBsZXQgdWkgPSBldmVudFVpc1tkZWYuZGVmSWRdO1xuICAgICAgICBsZXQgb3JpZ1JhbmdlID0gaW5zdGFuY2UucmFuZ2U7XG4gICAgICAgIGxldCBub3JtYWxSYW5nZSA9ICghZGVmLmFsbERheSAmJiBuZXh0RGF5VGhyZXNob2xkKSA/XG4gICAgICAgICAgICBjb21wdXRlVmlzaWJsZURheVJhbmdlKG9yaWdSYW5nZSwgbmV4dERheVRocmVzaG9sZCkgOlxuICAgICAgICAgICAgb3JpZ1JhbmdlO1xuICAgICAgICBsZXQgc2xpY2VkUmFuZ2UgPSBpbnRlcnNlY3RSYW5nZXMobm9ybWFsUmFuZ2UsIGZyYW1pbmdSYW5nZSk7XG4gICAgICAgIGlmIChzbGljZWRSYW5nZSkge1xuICAgICAgICAgICAgaWYgKHVpLmRpc3BsYXkgPT09ICdpbnZlcnNlLWJhY2tncm91bmQnKSB7XG4gICAgICAgICAgICAgICAgaWYgKGRlZi5ncm91cElkKSB7XG4gICAgICAgICAgICAgICAgICAgIGludmVyc2VCZ0J5R3JvdXBJZFtkZWYuZ3JvdXBJZF0ucHVzaChzbGljZWRSYW5nZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBpbnZlcnNlQmdCeURlZklkW2luc3RhbmNlLmRlZklkXS5wdXNoKHNsaWNlZFJhbmdlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICh1aS5kaXNwbGF5ICE9PSAnbm9uZScpIHtcbiAgICAgICAgICAgICAgICAodWkuZGlzcGxheSA9PT0gJ2JhY2tncm91bmQnID8gYmdSYW5nZXMgOiBmZ1JhbmdlcykucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgIGRlZixcbiAgICAgICAgICAgICAgICAgICAgdWksXG4gICAgICAgICAgICAgICAgICAgIGluc3RhbmNlLFxuICAgICAgICAgICAgICAgICAgICByYW5nZTogc2xpY2VkUmFuZ2UsXG4gICAgICAgICAgICAgICAgICAgIGlzU3RhcnQ6IG5vcm1hbFJhbmdlLnN0YXJ0ICYmIG5vcm1hbFJhbmdlLnN0YXJ0LnZhbHVlT2YoKSA9PT0gc2xpY2VkUmFuZ2Uuc3RhcnQudmFsdWVPZigpLFxuICAgICAgICAgICAgICAgICAgICBpc0VuZDogbm9ybWFsUmFuZ2UuZW5kICYmIG5vcm1hbFJhbmdlLmVuZC52YWx1ZU9mKCkgPT09IHNsaWNlZFJhbmdlLmVuZC52YWx1ZU9mKCksXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgZm9yIChsZXQgZ3JvdXBJZCBpbiBpbnZlcnNlQmdCeUdyb3VwSWQpIHsgLy8gQlkgR1JPVVBcbiAgICAgICAgbGV0IHJhbmdlcyA9IGludmVyc2VCZ0J5R3JvdXBJZFtncm91cElkXTtcbiAgICAgICAgbGV0IGludmVydGVkUmFuZ2VzID0gaW52ZXJ0UmFuZ2VzKHJhbmdlcywgZnJhbWluZ1JhbmdlKTtcbiAgICAgICAgZm9yIChsZXQgaW52ZXJ0ZWRSYW5nZSBvZiBpbnZlcnRlZFJhbmdlcykge1xuICAgICAgICAgICAgbGV0IGRlZiA9IGRlZkJ5R3JvdXBJZFtncm91cElkXTtcbiAgICAgICAgICAgIGxldCB1aSA9IGV2ZW50VWlzW2RlZi5kZWZJZF07XG4gICAgICAgICAgICBiZ1Jhbmdlcy5wdXNoKHtcbiAgICAgICAgICAgICAgICBkZWYsXG4gICAgICAgICAgICAgICAgdWksXG4gICAgICAgICAgICAgICAgaW5zdGFuY2U6IG51bGwsXG4gICAgICAgICAgICAgICAgcmFuZ2U6IGludmVydGVkUmFuZ2UsXG4gICAgICAgICAgICAgICAgaXNTdGFydDogZmFsc2UsXG4gICAgICAgICAgICAgICAgaXNFbmQ6IGZhbHNlLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZm9yIChsZXQgZGVmSWQgaW4gaW52ZXJzZUJnQnlEZWZJZCkge1xuICAgICAgICBsZXQgcmFuZ2VzID0gaW52ZXJzZUJnQnlEZWZJZFtkZWZJZF07XG4gICAgICAgIGxldCBpbnZlcnRlZFJhbmdlcyA9IGludmVydFJhbmdlcyhyYW5nZXMsIGZyYW1pbmdSYW5nZSk7XG4gICAgICAgIGZvciAobGV0IGludmVydGVkUmFuZ2Ugb2YgaW52ZXJ0ZWRSYW5nZXMpIHtcbiAgICAgICAgICAgIGJnUmFuZ2VzLnB1c2goe1xuICAgICAgICAgICAgICAgIGRlZjogZXZlbnRTdG9yZS5kZWZzW2RlZklkXSxcbiAgICAgICAgICAgICAgICB1aTogZXZlbnRVaXNbZGVmSWRdLFxuICAgICAgICAgICAgICAgIGluc3RhbmNlOiBudWxsLFxuICAgICAgICAgICAgICAgIHJhbmdlOiBpbnZlcnRlZFJhbmdlLFxuICAgICAgICAgICAgICAgIGlzU3RhcnQ6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGlzRW5kOiBmYWxzZSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB7IGJnOiBiZ1JhbmdlcywgZmc6IGZnUmFuZ2VzIH07XG59XG5mdW5jdGlvbiBoYXNCZ1JlbmRlcmluZyhkZWYpIHtcbiAgICByZXR1cm4gZGVmLnVpLmRpc3BsYXkgPT09ICdiYWNrZ3JvdW5kJyB8fCBkZWYudWkuZGlzcGxheSA9PT0gJ2ludmVyc2UtYmFja2dyb3VuZCc7XG59XG5mdW5jdGlvbiBzZXRFbFNlZyhlbCwgc2VnKSB7XG4gICAgZWwuZmNTZWcgPSBzZWc7XG59XG5mdW5jdGlvbiBnZXRFbFNlZyhlbCkge1xuICAgIHJldHVybiBlbC5mY1NlZyB8fFxuICAgICAgICBlbC5wYXJlbnROb2RlLmZjU2VnIHx8IC8vIGZvciB0aGUgaGFybmVzc1xuICAgICAgICBudWxsO1xufVxuLy8gZXZlbnQgdWkgY29tcHV0YXRpb25cbmZ1bmN0aW9uIGNvbXBpbGVFdmVudFVpcyhldmVudERlZnMsIGV2ZW50VWlCYXNlcykge1xuICAgIHJldHVybiBtYXBIYXNoKGV2ZW50RGVmcywgKGV2ZW50RGVmKSA9PiBjb21waWxlRXZlbnRVaShldmVudERlZiwgZXZlbnRVaUJhc2VzKSk7XG59XG5mdW5jdGlvbiBjb21waWxlRXZlbnRVaShldmVudERlZiwgZXZlbnRVaUJhc2VzKSB7XG4gICAgbGV0IHVpcyA9IFtdO1xuICAgIGlmIChldmVudFVpQmFzZXNbJyddKSB7XG4gICAgICAgIHVpcy5wdXNoKGV2ZW50VWlCYXNlc1snJ10pO1xuICAgIH1cbiAgICBpZiAoZXZlbnRVaUJhc2VzW2V2ZW50RGVmLmRlZklkXSkge1xuICAgICAgICB1aXMucHVzaChldmVudFVpQmFzZXNbZXZlbnREZWYuZGVmSWRdKTtcbiAgICB9XG4gICAgdWlzLnB1c2goZXZlbnREZWYudWkpO1xuICAgIHJldHVybiBjb21iaW5lRXZlbnRVaXModWlzKTtcbn1cbmZ1bmN0aW9uIHNvcnRFdmVudFNlZ3Moc2VncywgZXZlbnRPcmRlclNwZWNzKSB7XG4gICAgbGV0IG9ianMgPSBzZWdzLm1hcChidWlsZFNlZ0NvbXBhcmVPYmopO1xuICAgIG9ianMuc29ydCgob2JqMCwgb2JqMSkgPT4gY29tcGFyZUJ5RmllbGRTcGVjcyhvYmowLCBvYmoxLCBldmVudE9yZGVyU3BlY3MpKTtcbiAgICByZXR1cm4gb2Jqcy5tYXAoKGMpID0+IGMuX3NlZyk7XG59XG4vLyByZXR1cm5zIGEgb2JqZWN0IHdpdGggYWxsIHByaW1pdGl2ZSBwcm9wcyB0aGF0IGNhbiBiZSBjb21wYXJlZFxuZnVuY3Rpb24gYnVpbGRTZWdDb21wYXJlT2JqKHNlZykge1xuICAgIGxldCB7IGV2ZW50UmFuZ2UgfSA9IHNlZztcbiAgICBsZXQgZXZlbnREZWYgPSBldmVudFJhbmdlLmRlZjtcbiAgICBsZXQgcmFuZ2UgPSBldmVudFJhbmdlLmluc3RhbmNlID8gZXZlbnRSYW5nZS5pbnN0YW5jZS5yYW5nZSA6IGV2ZW50UmFuZ2UucmFuZ2U7XG4gICAgbGV0IHN0YXJ0ID0gcmFuZ2Uuc3RhcnQgPyByYW5nZS5zdGFydC52YWx1ZU9mKCkgOiAwOyAvLyBUT0RPOiBiZXR0ZXIgc3VwcG9ydCBmb3Igb3Blbi1yYW5nZSBldmVudHNcbiAgICBsZXQgZW5kID0gcmFuZ2UuZW5kID8gcmFuZ2UuZW5kLnZhbHVlT2YoKSA6IDA7IC8vIFwiXG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCBldmVudERlZi5leHRlbmRlZFByb3BzKSwgZXZlbnREZWYpLCB7IGlkOiBldmVudERlZi5wdWJsaWNJZCwgc3RhcnQsXG4gICAgICAgIGVuZCwgZHVyYXRpb246IGVuZCAtIHN0YXJ0LCBhbGxEYXk6IE51bWJlcihldmVudERlZi5hbGxEYXkpLCBfc2VnOiBzZWcgfSk7XG59XG5mdW5jdGlvbiBjb21wdXRlU2VnRHJhZ2dhYmxlKHNlZywgY29udGV4dCkge1xuICAgIGxldCB7IHBsdWdpbkhvb2tzIH0gPSBjb250ZXh0O1xuICAgIGxldCB0cmFuc2Zvcm1lcnMgPSBwbHVnaW5Ib29rcy5pc0RyYWdnYWJsZVRyYW5zZm9ybWVycztcbiAgICBsZXQgeyBkZWYsIHVpIH0gPSBzZWcuZXZlbnRSYW5nZTtcbiAgICBsZXQgdmFsID0gdWkuc3RhcnRFZGl0YWJsZTtcbiAgICBmb3IgKGxldCB0cmFuc2Zvcm1lciBvZiB0cmFuc2Zvcm1lcnMpIHtcbiAgICAgICAgdmFsID0gdHJhbnNmb3JtZXIodmFsLCBkZWYsIHVpLCBjb250ZXh0KTtcbiAgICB9XG4gICAgcmV0dXJuIHZhbDtcbn1cbmZ1bmN0aW9uIGNvbXB1dGVTZWdTdGFydFJlc2l6YWJsZShzZWcsIGNvbnRleHQpIHtcbiAgICByZXR1cm4gc2VnLmlzU3RhcnQgJiYgc2VnLmV2ZW50UmFuZ2UudWkuZHVyYXRpb25FZGl0YWJsZSAmJiBjb250ZXh0Lm9wdGlvbnMuZXZlbnRSZXNpemFibGVGcm9tU3RhcnQ7XG59XG5mdW5jdGlvbiBjb21wdXRlU2VnRW5kUmVzaXphYmxlKHNlZywgY29udGV4dCkge1xuICAgIHJldHVybiBzZWcuaXNFbmQgJiYgc2VnLmV2ZW50UmFuZ2UudWkuZHVyYXRpb25FZGl0YWJsZTtcbn1cbmZ1bmN0aW9uIGJ1aWxkU2VnVGltZVRleHQoc2VnLCB0aW1lRm9ybWF0LCBjb250ZXh0LCBkZWZhdWx0RGlzcGxheUV2ZW50VGltZSwgLy8gZGVmYXVsdHMgdG8gdHJ1ZVxuZGVmYXVsdERpc3BsYXlFdmVudEVuZCwgLy8gZGVmYXVsdHMgdG8gdHJ1ZVxuc3RhcnRPdmVycmlkZSwgZW5kT3ZlcnJpZGUpIHtcbiAgICBsZXQgeyBkYXRlRW52LCBvcHRpb25zIH0gPSBjb250ZXh0O1xuICAgIGxldCB7IGRpc3BsYXlFdmVudFRpbWUsIGRpc3BsYXlFdmVudEVuZCB9ID0gb3B0aW9ucztcbiAgICBsZXQgZXZlbnREZWYgPSBzZWcuZXZlbnRSYW5nZS5kZWY7XG4gICAgbGV0IGV2ZW50SW5zdGFuY2UgPSBzZWcuZXZlbnRSYW5nZS5pbnN0YW5jZTtcbiAgICBpZiAoZGlzcGxheUV2ZW50VGltZSA9PSBudWxsKSB7XG4gICAgICAgIGRpc3BsYXlFdmVudFRpbWUgPSBkZWZhdWx0RGlzcGxheUV2ZW50VGltZSAhPT0gZmFsc2U7XG4gICAgfVxuICAgIGlmIChkaXNwbGF5RXZlbnRFbmQgPT0gbnVsbCkge1xuICAgICAgICBkaXNwbGF5RXZlbnRFbmQgPSBkZWZhdWx0RGlzcGxheUV2ZW50RW5kICE9PSBmYWxzZTtcbiAgICB9XG4gICAgbGV0IHdob2xlRXZlbnRTdGFydCA9IGV2ZW50SW5zdGFuY2UucmFuZ2Uuc3RhcnQ7XG4gICAgbGV0IHdob2xlRXZlbnRFbmQgPSBldmVudEluc3RhbmNlLnJhbmdlLmVuZDtcbiAgICBsZXQgc2VnU3RhcnQgPSBzdGFydE92ZXJyaWRlIHx8IHNlZy5zdGFydCB8fCBzZWcuZXZlbnRSYW5nZS5yYW5nZS5zdGFydDtcbiAgICBsZXQgc2VnRW5kID0gZW5kT3ZlcnJpZGUgfHwgc2VnLmVuZCB8fCBzZWcuZXZlbnRSYW5nZS5yYW5nZS5lbmQ7XG4gICAgbGV0IGlzU3RhcnREYXkgPSBzdGFydE9mRGF5KHdob2xlRXZlbnRTdGFydCkudmFsdWVPZigpID09PSBzdGFydE9mRGF5KHNlZ1N0YXJ0KS52YWx1ZU9mKCk7XG4gICAgbGV0IGlzRW5kRGF5ID0gc3RhcnRPZkRheShhZGRNcyh3aG9sZUV2ZW50RW5kLCAtMSkpLnZhbHVlT2YoKSA9PT0gc3RhcnRPZkRheShhZGRNcyhzZWdFbmQsIC0xKSkudmFsdWVPZigpO1xuICAgIGlmIChkaXNwbGF5RXZlbnRUaW1lICYmICFldmVudERlZi5hbGxEYXkgJiYgKGlzU3RhcnREYXkgfHwgaXNFbmREYXkpKSB7XG4gICAgICAgIHNlZ1N0YXJ0ID0gaXNTdGFydERheSA/IHdob2xlRXZlbnRTdGFydCA6IHNlZ1N0YXJ0O1xuICAgICAgICBzZWdFbmQgPSBpc0VuZERheSA/IHdob2xlRXZlbnRFbmQgOiBzZWdFbmQ7XG4gICAgICAgIGlmIChkaXNwbGF5RXZlbnRFbmQgJiYgZXZlbnREZWYuaGFzRW5kKSB7XG4gICAgICAgICAgICByZXR1cm4gZGF0ZUVudi5mb3JtYXRSYW5nZShzZWdTdGFydCwgc2VnRW5kLCB0aW1lRm9ybWF0LCB7XG4gICAgICAgICAgICAgICAgZm9yY2VkU3RhcnRUem86IHN0YXJ0T3ZlcnJpZGUgPyBudWxsIDogZXZlbnRJbnN0YW5jZS5mb3JjZWRTdGFydFR6byxcbiAgICAgICAgICAgICAgICBmb3JjZWRFbmRUem86IGVuZE92ZXJyaWRlID8gbnVsbCA6IGV2ZW50SW5zdGFuY2UuZm9yY2VkRW5kVHpvLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGRhdGVFbnYuZm9ybWF0KHNlZ1N0YXJ0LCB0aW1lRm9ybWF0LCB7XG4gICAgICAgICAgICBmb3JjZWRUem86IHN0YXJ0T3ZlcnJpZGUgPyBudWxsIDogZXZlbnRJbnN0YW5jZS5mb3JjZWRTdGFydFR6bywgLy8gbm9vb29vLCBzYW1lXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gJyc7XG59XG5mdW5jdGlvbiBnZXRTZWdNZXRhKHNlZywgdG9kYXlSYW5nZSwgbm93RGF0ZSkge1xuICAgIGxldCBzZWdSYW5nZSA9IHNlZy5ldmVudFJhbmdlLnJhbmdlO1xuICAgIHJldHVybiB7XG4gICAgICAgIGlzUGFzdDogc2VnUmFuZ2UuZW5kIDwgKG5vd0RhdGUgfHwgdG9kYXlSYW5nZS5zdGFydCksXG4gICAgICAgIGlzRnV0dXJlOiBzZWdSYW5nZS5zdGFydCA+PSAobm93RGF0ZSB8fCB0b2RheVJhbmdlLmVuZCksXG4gICAgICAgIGlzVG9kYXk6IHRvZGF5UmFuZ2UgJiYgcmFuZ2VDb250YWluc01hcmtlcih0b2RheVJhbmdlLCBzZWdSYW5nZS5zdGFydCksXG4gICAgfTtcbn1cbmZ1bmN0aW9uIGdldEV2ZW50Q2xhc3NOYW1lcyhwcm9wcykge1xuICAgIGxldCBjbGFzc05hbWVzID0gWydmYy1ldmVudCddO1xuICAgIGlmIChwcm9wcy5pc01pcnJvcikge1xuICAgICAgICBjbGFzc05hbWVzLnB1c2goJ2ZjLWV2ZW50LW1pcnJvcicpO1xuICAgIH1cbiAgICBpZiAocHJvcHMuaXNEcmFnZ2FibGUpIHtcbiAgICAgICAgY2xhc3NOYW1lcy5wdXNoKCdmYy1ldmVudC1kcmFnZ2FibGUnKTtcbiAgICB9XG4gICAgaWYgKHByb3BzLmlzU3RhcnRSZXNpemFibGUgfHwgcHJvcHMuaXNFbmRSZXNpemFibGUpIHtcbiAgICAgICAgY2xhc3NOYW1lcy5wdXNoKCdmYy1ldmVudC1yZXNpemFibGUnKTtcbiAgICB9XG4gICAgaWYgKHByb3BzLmlzRHJhZ2dpbmcpIHtcbiAgICAgICAgY2xhc3NOYW1lcy5wdXNoKCdmYy1ldmVudC1kcmFnZ2luZycpO1xuICAgIH1cbiAgICBpZiAocHJvcHMuaXNSZXNpemluZykge1xuICAgICAgICBjbGFzc05hbWVzLnB1c2goJ2ZjLWV2ZW50LXJlc2l6aW5nJyk7XG4gICAgfVxuICAgIGlmIChwcm9wcy5pc1NlbGVjdGVkKSB7XG4gICAgICAgIGNsYXNzTmFtZXMucHVzaCgnZmMtZXZlbnQtc2VsZWN0ZWQnKTtcbiAgICB9XG4gICAgaWYgKHByb3BzLmlzU3RhcnQpIHtcbiAgICAgICAgY2xhc3NOYW1lcy5wdXNoKCdmYy1ldmVudC1zdGFydCcpO1xuICAgIH1cbiAgICBpZiAocHJvcHMuaXNFbmQpIHtcbiAgICAgICAgY2xhc3NOYW1lcy5wdXNoKCdmYy1ldmVudC1lbmQnKTtcbiAgICB9XG4gICAgaWYgKHByb3BzLmlzUGFzdCkge1xuICAgICAgICBjbGFzc05hbWVzLnB1c2goJ2ZjLWV2ZW50LXBhc3QnKTtcbiAgICB9XG4gICAgaWYgKHByb3BzLmlzVG9kYXkpIHtcbiAgICAgICAgY2xhc3NOYW1lcy5wdXNoKCdmYy1ldmVudC10b2RheScpO1xuICAgIH1cbiAgICBpZiAocHJvcHMuaXNGdXR1cmUpIHtcbiAgICAgICAgY2xhc3NOYW1lcy5wdXNoKCdmYy1ldmVudC1mdXR1cmUnKTtcbiAgICB9XG4gICAgcmV0dXJuIGNsYXNzTmFtZXM7XG59XG5mdW5jdGlvbiBidWlsZEV2ZW50UmFuZ2VLZXkoZXZlbnRSYW5nZSkge1xuICAgIHJldHVybiBldmVudFJhbmdlLmluc3RhbmNlXG4gICAgICAgID8gZXZlbnRSYW5nZS5pbnN0YW5jZS5pbnN0YW5jZUlkXG4gICAgICAgIDogYCR7ZXZlbnRSYW5nZS5kZWYuZGVmSWR9OiR7ZXZlbnRSYW5nZS5yYW5nZS5zdGFydC50b0lTT1N0cmluZygpfWA7XG4gICAgLy8gaW52ZXJzZS1iYWNrZ3JvdW5kIGV2ZW50cyBkb24ndCBoYXZlIHNwZWNpZmljIGluc3RhbmNlcy4gVE9ETzogYmV0dGVyIHNvbHV0aW9uXG59XG5mdW5jdGlvbiBnZXRTZWdBbmNob3JBdHRycyhzZWcsIGNvbnRleHQpIHtcbiAgICBsZXQgeyBkZWYsIGluc3RhbmNlIH0gPSBzZWcuZXZlbnRSYW5nZTtcbiAgICBsZXQgeyB1cmwgfSA9IGRlZjtcbiAgICBpZiAodXJsKSB7XG4gICAgICAgIHJldHVybiB7IGhyZWY6IHVybCB9O1xuICAgIH1cbiAgICBsZXQgeyBlbWl0dGVyLCBvcHRpb25zIH0gPSBjb250ZXh0O1xuICAgIGxldCB7IGV2ZW50SW50ZXJhY3RpdmUgfSA9IG9wdGlvbnM7XG4gICAgaWYgKGV2ZW50SW50ZXJhY3RpdmUgPT0gbnVsbCkge1xuICAgICAgICBldmVudEludGVyYWN0aXZlID0gZGVmLmludGVyYWN0aXZlO1xuICAgICAgICBpZiAoZXZlbnRJbnRlcmFjdGl2ZSA9PSBudWxsKSB7XG4gICAgICAgICAgICBldmVudEludGVyYWN0aXZlID0gQm9vbGVhbihlbWl0dGVyLmhhc0hhbmRsZXJzKCdldmVudENsaWNrJykpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8vIG1vY2sgd2hhdCBoYXBwZW5zIGluIEV2ZW50Q2xpY2tpbmdcbiAgICBpZiAoZXZlbnRJbnRlcmFjdGl2ZSkge1xuICAgICAgICAvLyBvbmx5IGF0dGFjaCBrZXlib2FyZC1yZWxhdGVkIGhhbmRsZXJzIGJlY2F1c2UgY2xpY2sgaGFuZGxlciBpcyBhbHJlYWR5IGRvbmUgaW4gRXZlbnRDbGlja2luZ1xuICAgICAgICByZXR1cm4gY3JlYXRlQXJpYUtleWJvYXJkQXR0cnMoKGV2KSA9PiB7XG4gICAgICAgICAgICBlbWl0dGVyLnRyaWdnZXIoJ2V2ZW50Q2xpY2snLCB7XG4gICAgICAgICAgICAgICAgZWw6IGV2LnRhcmdldCxcbiAgICAgICAgICAgICAgICBldmVudDogbmV3IEV2ZW50SW1wbChjb250ZXh0LCBkZWYsIGluc3RhbmNlKSxcbiAgICAgICAgICAgICAgICBqc0V2ZW50OiBldixcbiAgICAgICAgICAgICAgICB2aWV3OiBjb250ZXh0LnZpZXdBcGksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiB7fTtcbn1cblxuY29uc3QgU1RBTkRBUkRfUFJPUFMgPSB7XG4gICAgc3RhcnQ6IGlkZW50aXR5LFxuICAgIGVuZDogaWRlbnRpdHksXG4gICAgYWxsRGF5OiBCb29sZWFuLFxufTtcbmZ1bmN0aW9uIHBhcnNlRGF0ZVNwYW4ocmF3LCBkYXRlRW52LCBkZWZhdWx0RHVyYXRpb24pIHtcbiAgICBsZXQgc3BhbiA9IHBhcnNlT3BlbkRhdGVTcGFuKHJhdywgZGF0ZUVudik7XG4gICAgbGV0IHsgcmFuZ2UgfSA9IHNwYW47XG4gICAgaWYgKCFyYW5nZS5zdGFydCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgaWYgKCFyYW5nZS5lbmQpIHtcbiAgICAgICAgaWYgKGRlZmF1bHREdXJhdGlvbiA9PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICByYW5nZS5lbmQgPSBkYXRlRW52LmFkZChyYW5nZS5zdGFydCwgZGVmYXVsdER1cmF0aW9uKTtcbiAgICB9XG4gICAgcmV0dXJuIHNwYW47XG59XG4vKlxuVE9ETzogc29tZWhvdyBjb21iaW5lIHdpdGggcGFyc2VSYW5nZT9cbldpbGwgcmV0dXJuIG51bGwgaWYgdGhlIHN0YXJ0L2VuZCBwcm9wcyB3ZXJlIHByZXNlbnQgYnV0IHBhcnNlZCBpbnZhbGlkbHkuXG4qL1xuZnVuY3Rpb24gcGFyc2VPcGVuRGF0ZVNwYW4ocmF3LCBkYXRlRW52KSB7XG4gICAgbGV0IHsgcmVmaW5lZDogc3RhbmRhcmRQcm9wcywgZXh0cmEgfSA9IHJlZmluZVByb3BzKHJhdywgU1RBTkRBUkRfUFJPUFMpO1xuICAgIGxldCBzdGFydE1ldGEgPSBzdGFuZGFyZFByb3BzLnN0YXJ0ID8gZGF0ZUVudi5jcmVhdGVNYXJrZXJNZXRhKHN0YW5kYXJkUHJvcHMuc3RhcnQpIDogbnVsbDtcbiAgICBsZXQgZW5kTWV0YSA9IHN0YW5kYXJkUHJvcHMuZW5kID8gZGF0ZUVudi5jcmVhdGVNYXJrZXJNZXRhKHN0YW5kYXJkUHJvcHMuZW5kKSA6IG51bGw7XG4gICAgbGV0IHsgYWxsRGF5IH0gPSBzdGFuZGFyZFByb3BzO1xuICAgIGlmIChhbGxEYXkgPT0gbnVsbCkge1xuICAgICAgICBhbGxEYXkgPSAoc3RhcnRNZXRhICYmIHN0YXJ0TWV0YS5pc1RpbWVVbnNwZWNpZmllZCkgJiZcbiAgICAgICAgICAgICghZW5kTWV0YSB8fCBlbmRNZXRhLmlzVGltZVVuc3BlY2lmaWVkKTtcbiAgICB9XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oeyByYW5nZToge1xuICAgICAgICAgICAgc3RhcnQ6IHN0YXJ0TWV0YSA/IHN0YXJ0TWV0YS5tYXJrZXIgOiBudWxsLFxuICAgICAgICAgICAgZW5kOiBlbmRNZXRhID8gZW5kTWV0YS5tYXJrZXIgOiBudWxsLFxuICAgICAgICB9LCBhbGxEYXkgfSwgZXh0cmEpO1xufVxuZnVuY3Rpb24gaXNEYXRlU3BhbnNFcXVhbChzcGFuMCwgc3BhbjEpIHtcbiAgICByZXR1cm4gcmFuZ2VzRXF1YWwoc3BhbjAucmFuZ2UsIHNwYW4xLnJhbmdlKSAmJlxuICAgICAgICBzcGFuMC5hbGxEYXkgPT09IHNwYW4xLmFsbERheSAmJlxuICAgICAgICBpc1NwYW5Qcm9wc0VxdWFsKHNwYW4wLCBzcGFuMSk7XG59XG4vLyB0aGUgTk9OLURBVEUtUkVMQVRFRCBwcm9wc1xuZnVuY3Rpb24gaXNTcGFuUHJvcHNFcXVhbChzcGFuMCwgc3BhbjEpIHtcbiAgICBmb3IgKGxldCBwcm9wTmFtZSBpbiBzcGFuMSkge1xuICAgICAgICBpZiAocHJvcE5hbWUgIT09ICdyYW5nZScgJiYgcHJvcE5hbWUgIT09ICdhbGxEYXknKSB7XG4gICAgICAgICAgICBpZiAoc3BhbjBbcHJvcE5hbWVdICE9PSBzcGFuMVtwcm9wTmFtZV0pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgLy8gYXJlIHRoZXJlIGFueSBwcm9wcyB0aGF0IHNwYW4wIGhhcyB0aGF0IHNwYW4xIERPRVNOJ1QgaGF2ZT9cbiAgICAvLyBib3RoIGhhdmUgcmFuZ2UvYWxsRGF5LCBzbyBubyBuZWVkIHRvIHNwZWNpYWwtY2FzZS5cbiAgICBmb3IgKGxldCBwcm9wTmFtZSBpbiBzcGFuMCkge1xuICAgICAgICBpZiAoIShwcm9wTmFtZSBpbiBzcGFuMSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn1cbmZ1bmN0aW9uIGJ1aWxkRGF0ZVNwYW5BcGkoc3BhbiwgZGF0ZUVudikge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sIGJ1aWxkUmFuZ2VBcGkoc3Bhbi5yYW5nZSwgZGF0ZUVudiwgc3Bhbi5hbGxEYXkpKSwgeyBhbGxEYXk6IHNwYW4uYWxsRGF5IH0pO1xufVxuZnVuY3Rpb24gYnVpbGRSYW5nZUFwaVdpdGhUaW1lWm9uZShyYW5nZSwgZGF0ZUVudiwgb21pdFRpbWUpIHtcbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCBidWlsZFJhbmdlQXBpKHJhbmdlLCBkYXRlRW52LCBvbWl0VGltZSkpLCB7IHRpbWVab25lOiBkYXRlRW52LnRpbWVab25lIH0pO1xufVxuZnVuY3Rpb24gYnVpbGRSYW5nZUFwaShyYW5nZSwgZGF0ZUVudiwgb21pdFRpbWUpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBzdGFydDogZGF0ZUVudi50b0RhdGUocmFuZ2Uuc3RhcnQpLFxuICAgICAgICBlbmQ6IGRhdGVFbnYudG9EYXRlKHJhbmdlLmVuZCksXG4gICAgICAgIHN0YXJ0U3RyOiBkYXRlRW52LmZvcm1hdElzbyhyYW5nZS5zdGFydCwgeyBvbWl0VGltZSB9KSxcbiAgICAgICAgZW5kU3RyOiBkYXRlRW52LmZvcm1hdElzbyhyYW5nZS5lbmQsIHsgb21pdFRpbWUgfSksXG4gICAgfTtcbn1cbmZ1bmN0aW9uIGZhYnJpY2F0ZUV2ZW50UmFuZ2UoZGF0ZVNwYW4sIGV2ZW50VWlCYXNlcywgY29udGV4dCkge1xuICAgIGxldCByZXMgPSByZWZpbmVFdmVudERlZih7IGVkaXRhYmxlOiBmYWxzZSB9LCBjb250ZXh0KTtcbiAgICBsZXQgZGVmID0gcGFyc2VFdmVudERlZihyZXMucmVmaW5lZCwgcmVzLmV4dHJhLCAnJywgLy8gc291cmNlSWRcbiAgICBkYXRlU3Bhbi5hbGxEYXksIHRydWUsIC8vIGhhc0VuZFxuICAgIGNvbnRleHQpO1xuICAgIHJldHVybiB7XG4gICAgICAgIGRlZixcbiAgICAgICAgdWk6IGNvbXBpbGVFdmVudFVpKGRlZiwgZXZlbnRVaUJhc2VzKSxcbiAgICAgICAgaW5zdGFuY2U6IGNyZWF0ZUV2ZW50SW5zdGFuY2UoZGVmLmRlZklkLCBkYXRlU3Bhbi5yYW5nZSksXG4gICAgICAgIHJhbmdlOiBkYXRlU3Bhbi5yYW5nZSxcbiAgICAgICAgaXNTdGFydDogdHJ1ZSxcbiAgICAgICAgaXNFbmQ6IHRydWUsXG4gICAgfTtcbn1cblxubGV0IGNhbGVuZGFyU3lzdGVtQ2xhc3NNYXAgPSB7fTtcbmZ1bmN0aW9uIHJlZ2lzdGVyQ2FsZW5kYXJTeXN0ZW0obmFtZSwgdGhlQ2xhc3MpIHtcbiAgICBjYWxlbmRhclN5c3RlbUNsYXNzTWFwW25hbWVdID0gdGhlQ2xhc3M7XG59XG5mdW5jdGlvbiBjcmVhdGVDYWxlbmRhclN5c3RlbShuYW1lKSB7XG4gICAgcmV0dXJuIG5ldyBjYWxlbmRhclN5c3RlbUNsYXNzTWFwW25hbWVdKCk7XG59XG5jbGFzcyBHcmVnb3JpYW5DYWxlbmRhclN5c3RlbSB7XG4gICAgZ2V0TWFya2VyWWVhcihkKSB7XG4gICAgICAgIHJldHVybiBkLmdldFVUQ0Z1bGxZZWFyKCk7XG4gICAgfVxuICAgIGdldE1hcmtlck1vbnRoKGQpIHtcbiAgICAgICAgcmV0dXJuIGQuZ2V0VVRDTW9udGgoKTtcbiAgICB9XG4gICAgZ2V0TWFya2VyRGF5KGQpIHtcbiAgICAgICAgcmV0dXJuIGQuZ2V0VVRDRGF0ZSgpO1xuICAgIH1cbiAgICBhcnJheVRvTWFya2VyKGFycikge1xuICAgICAgICByZXR1cm4gYXJyYXlUb1V0Y0RhdGUoYXJyKTtcbiAgICB9XG4gICAgbWFya2VyVG9BcnJheShtYXJrZXIpIHtcbiAgICAgICAgcmV0dXJuIGRhdGVUb1V0Y0FycmF5KG1hcmtlcik7XG4gICAgfVxufVxucmVnaXN0ZXJDYWxlbmRhclN5c3RlbSgnZ3JlZ29yeScsIEdyZWdvcmlhbkNhbGVuZGFyU3lzdGVtKTtcblxuY29uc3QgSVNPX1JFID0gL15cXHMqKFxcZHs0fSkoLT8oXFxkezJ9KSgtPyhcXGR7Mn0pKFtUIF0oXFxkezJ9KTo/KFxcZHsyfSkoOj8oXFxkezJ9KShcXC4oXFxkKykpPyk/KFp8KChbLStdKShcXGR7Mn0pKDo/KFxcZHsyfSkpPykpPyk/KT8pPyQvO1xuZnVuY3Rpb24gcGFyc2Uoc3RyKSB7XG4gICAgbGV0IG0gPSBJU09fUkUuZXhlYyhzdHIpO1xuICAgIGlmIChtKSB7XG4gICAgICAgIGxldCBtYXJrZXIgPSBuZXcgRGF0ZShEYXRlLlVUQyhOdW1iZXIobVsxXSksIG1bM10gPyBOdW1iZXIobVszXSkgLSAxIDogMCwgTnVtYmVyKG1bNV0gfHwgMSksIE51bWJlcihtWzddIHx8IDApLCBOdW1iZXIobVs4XSB8fCAwKSwgTnVtYmVyKG1bMTBdIHx8IDApLCBtWzEyXSA/IE51bWJlcihgMC4ke21bMTJdfWApICogMTAwMCA6IDApKTtcbiAgICAgICAgaWYgKGlzVmFsaWREYXRlKG1hcmtlcikpIHtcbiAgICAgICAgICAgIGxldCB0aW1lWm9uZU9mZnNldCA9IG51bGw7XG4gICAgICAgICAgICBpZiAobVsxM10pIHtcbiAgICAgICAgICAgICAgICB0aW1lWm9uZU9mZnNldCA9IChtWzE1XSA9PT0gJy0nID8gLTEgOiAxKSAqIChOdW1iZXIobVsxNl0gfHwgMCkgKiA2MCArXG4gICAgICAgICAgICAgICAgICAgIE51bWJlcihtWzE4XSB8fCAwKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIG1hcmtlcixcbiAgICAgICAgICAgICAgICBpc1RpbWVVbnNwZWNpZmllZDogIW1bNl0sXG4gICAgICAgICAgICAgICAgdGltZVpvbmVPZmZzZXQsXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xufVxuXG5jbGFzcyBEYXRlRW52IHtcbiAgICBjb25zdHJ1Y3RvcihzZXR0aW5ncykge1xuICAgICAgICBsZXQgdGltZVpvbmUgPSB0aGlzLnRpbWVab25lID0gc2V0dGluZ3MudGltZVpvbmU7XG4gICAgICAgIGxldCBpc05hbWVkVGltZVpvbmUgPSB0aW1lWm9uZSAhPT0gJ2xvY2FsJyAmJiB0aW1lWm9uZSAhPT0gJ1VUQyc7XG4gICAgICAgIGlmIChzZXR0aW5ncy5uYW1lZFRpbWVab25lSW1wbCAmJiBpc05hbWVkVGltZVpvbmUpIHtcbiAgICAgICAgICAgIHRoaXMubmFtZWRUaW1lWm9uZUltcGwgPSBuZXcgc2V0dGluZ3MubmFtZWRUaW1lWm9uZUltcGwodGltZVpvbmUpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY2FuQ29tcHV0ZU9mZnNldCA9IEJvb2xlYW4oIWlzTmFtZWRUaW1lWm9uZSB8fCB0aGlzLm5hbWVkVGltZVpvbmVJbXBsKTtcbiAgICAgICAgdGhpcy5jYWxlbmRhclN5c3RlbSA9IGNyZWF0ZUNhbGVuZGFyU3lzdGVtKHNldHRpbmdzLmNhbGVuZGFyU3lzdGVtKTtcbiAgICAgICAgdGhpcy5sb2NhbGUgPSBzZXR0aW5ncy5sb2NhbGU7XG4gICAgICAgIHRoaXMud2Vla0RvdyA9IHNldHRpbmdzLmxvY2FsZS53ZWVrLmRvdztcbiAgICAgICAgdGhpcy53ZWVrRG95ID0gc2V0dGluZ3MubG9jYWxlLndlZWsuZG95O1xuICAgICAgICBpZiAoc2V0dGluZ3Mud2Vla051bWJlckNhbGN1bGF0aW9uID09PSAnSVNPJykge1xuICAgICAgICAgICAgdGhpcy53ZWVrRG93ID0gMTtcbiAgICAgICAgICAgIHRoaXMud2Vla0RveSA9IDQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBzZXR0aW5ncy5maXJzdERheSA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgIHRoaXMud2Vla0RvdyA9IHNldHRpbmdzLmZpcnN0RGF5O1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2Ygc2V0dGluZ3Mud2Vla051bWJlckNhbGN1bGF0aW9uID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB0aGlzLndlZWtOdW1iZXJGdW5jID0gc2V0dGluZ3Mud2Vla051bWJlckNhbGN1bGF0aW9uO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMud2Vla1RleHQgPSBzZXR0aW5ncy53ZWVrVGV4dCAhPSBudWxsID8gc2V0dGluZ3Mud2Vla1RleHQgOiBzZXR0aW5ncy5sb2NhbGUub3B0aW9ucy53ZWVrVGV4dDtcbiAgICAgICAgdGhpcy53ZWVrVGV4dExvbmcgPSAoc2V0dGluZ3Mud2Vla1RleHRMb25nICE9IG51bGwgPyBzZXR0aW5ncy53ZWVrVGV4dExvbmcgOiBzZXR0aW5ncy5sb2NhbGUub3B0aW9ucy53ZWVrVGV4dExvbmcpIHx8IHRoaXMud2Vla1RleHQ7XG4gICAgICAgIHRoaXMuY21kRm9ybWF0dGVyID0gc2V0dGluZ3MuY21kRm9ybWF0dGVyO1xuICAgICAgICB0aGlzLmRlZmF1bHRTZXBhcmF0b3IgPSBzZXR0aW5ncy5kZWZhdWx0U2VwYXJhdG9yO1xuICAgIH1cbiAgICAvLyBDcmVhdGluZyAvIFBhcnNpbmdcbiAgICBjcmVhdGVNYXJrZXIoaW5wdXQpIHtcbiAgICAgICAgbGV0IG1ldGEgPSB0aGlzLmNyZWF0ZU1hcmtlck1ldGEoaW5wdXQpO1xuICAgICAgICBpZiAobWV0YSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1ldGEubWFya2VyO1xuICAgIH1cbiAgICBjcmVhdGVOb3dNYXJrZXIoKSB7XG4gICAgICAgIGlmICh0aGlzLmNhbkNvbXB1dGVPZmZzZXQpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnRpbWVzdGFtcFRvTWFya2VyKG5ldyBEYXRlKCkudmFsdWVPZigpKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBpZiB3ZSBjYW4ndCBjb21wdXRlIHRoZSBjdXJyZW50IGRhdGUgdmFsIGZvciBhIHRpbWV6b25lLFxuICAgICAgICAvLyBiZXR0ZXIgdG8gZ2l2ZSB0aGUgY3VycmVudCBsb2NhbCBkYXRlIHZhbHMgdGhhbiBVVENcbiAgICAgICAgcmV0dXJuIGFycmF5VG9VdGNEYXRlKGRhdGVUb0xvY2FsQXJyYXkobmV3IERhdGUoKSkpO1xuICAgIH1cbiAgICBjcmVhdGVNYXJrZXJNZXRhKGlucHV0KSB7XG4gICAgICAgIGlmICh0eXBlb2YgaW5wdXQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5wYXJzZShpbnB1dCk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IG1hcmtlciA9IG51bGw7XG4gICAgICAgIGlmICh0eXBlb2YgaW5wdXQgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICBtYXJrZXIgPSB0aGlzLnRpbWVzdGFtcFRvTWFya2VyKGlucHV0KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChpbnB1dCBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICAgICAgICAgIGlucHV0ID0gaW5wdXQudmFsdWVPZigpO1xuICAgICAgICAgICAgaWYgKCFpc05hTihpbnB1dCkpIHtcbiAgICAgICAgICAgICAgICBtYXJrZXIgPSB0aGlzLnRpbWVzdGFtcFRvTWFya2VyKGlucHV0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChBcnJheS5pc0FycmF5KGlucHV0KSkge1xuICAgICAgICAgICAgbWFya2VyID0gYXJyYXlUb1V0Y0RhdGUoaW5wdXQpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChtYXJrZXIgPT09IG51bGwgfHwgIWlzVmFsaWREYXRlKG1hcmtlcikpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7IG1hcmtlciwgaXNUaW1lVW5zcGVjaWZpZWQ6IGZhbHNlLCBmb3JjZWRUem86IG51bGwgfTtcbiAgICB9XG4gICAgcGFyc2Uocykge1xuICAgICAgICBsZXQgcGFydHMgPSBwYXJzZShzKTtcbiAgICAgICAgaWYgKHBhcnRzID09PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBsZXQgeyBtYXJrZXIgfSA9IHBhcnRzO1xuICAgICAgICBsZXQgZm9yY2VkVHpvID0gbnVsbDtcbiAgICAgICAgaWYgKHBhcnRzLnRpbWVab25lT2Zmc2V0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5jYW5Db21wdXRlT2Zmc2V0KSB7XG4gICAgICAgICAgICAgICAgbWFya2VyID0gdGhpcy50aW1lc3RhbXBUb01hcmtlcihtYXJrZXIudmFsdWVPZigpIC0gcGFydHMudGltZVpvbmVPZmZzZXQgKiA2MCAqIDEwMDApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgZm9yY2VkVHpvID0gcGFydHMudGltZVpvbmVPZmZzZXQ7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsgbWFya2VyLCBpc1RpbWVVbnNwZWNpZmllZDogcGFydHMuaXNUaW1lVW5zcGVjaWZpZWQsIGZvcmNlZFR6byB9O1xuICAgIH1cbiAgICAvLyBBY2Nlc3NvcnNcbiAgICBnZXRZZWFyKG1hcmtlcikge1xuICAgICAgICByZXR1cm4gdGhpcy5jYWxlbmRhclN5c3RlbS5nZXRNYXJrZXJZZWFyKG1hcmtlcik7XG4gICAgfVxuICAgIGdldE1vbnRoKG1hcmtlcikge1xuICAgICAgICByZXR1cm4gdGhpcy5jYWxlbmRhclN5c3RlbS5nZXRNYXJrZXJNb250aChtYXJrZXIpO1xuICAgIH1cbiAgICAvLyBBZGRpbmcgLyBTdWJ0cmFjdGluZ1xuICAgIGFkZChtYXJrZXIsIGR1cikge1xuICAgICAgICBsZXQgYSA9IHRoaXMuY2FsZW5kYXJTeXN0ZW0ubWFya2VyVG9BcnJheShtYXJrZXIpO1xuICAgICAgICBhWzBdICs9IGR1ci55ZWFycztcbiAgICAgICAgYVsxXSArPSBkdXIubW9udGhzO1xuICAgICAgICBhWzJdICs9IGR1ci5kYXlzO1xuICAgICAgICBhWzZdICs9IGR1ci5taWxsaXNlY29uZHM7XG4gICAgICAgIHJldHVybiB0aGlzLmNhbGVuZGFyU3lzdGVtLmFycmF5VG9NYXJrZXIoYSk7XG4gICAgfVxuICAgIHN1YnRyYWN0KG1hcmtlciwgZHVyKSB7XG4gICAgICAgIGxldCBhID0gdGhpcy5jYWxlbmRhclN5c3RlbS5tYXJrZXJUb0FycmF5KG1hcmtlcik7XG4gICAgICAgIGFbMF0gLT0gZHVyLnllYXJzO1xuICAgICAgICBhWzFdIC09IGR1ci5tb250aHM7XG4gICAgICAgIGFbMl0gLT0gZHVyLmRheXM7XG4gICAgICAgIGFbNl0gLT0gZHVyLm1pbGxpc2Vjb25kcztcbiAgICAgICAgcmV0dXJuIHRoaXMuY2FsZW5kYXJTeXN0ZW0uYXJyYXlUb01hcmtlcihhKTtcbiAgICB9XG4gICAgYWRkWWVhcnMobWFya2VyLCBuKSB7XG4gICAgICAgIGxldCBhID0gdGhpcy5jYWxlbmRhclN5c3RlbS5tYXJrZXJUb0FycmF5KG1hcmtlcik7XG4gICAgICAgIGFbMF0gKz0gbjtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2FsZW5kYXJTeXN0ZW0uYXJyYXlUb01hcmtlcihhKTtcbiAgICB9XG4gICAgYWRkTW9udGhzKG1hcmtlciwgbikge1xuICAgICAgICBsZXQgYSA9IHRoaXMuY2FsZW5kYXJTeXN0ZW0ubWFya2VyVG9BcnJheShtYXJrZXIpO1xuICAgICAgICBhWzFdICs9IG47XG4gICAgICAgIHJldHVybiB0aGlzLmNhbGVuZGFyU3lzdGVtLmFycmF5VG9NYXJrZXIoYSk7XG4gICAgfVxuICAgIC8vIERpZmZpbmcgV2hvbGUgVW5pdHNcbiAgICBkaWZmV2hvbGVZZWFycyhtMCwgbTEpIHtcbiAgICAgICAgbGV0IHsgY2FsZW5kYXJTeXN0ZW0gfSA9IHRoaXM7XG4gICAgICAgIGlmICh0aW1lQXNNcyhtMCkgPT09IHRpbWVBc01zKG0xKSAmJlxuICAgICAgICAgICAgY2FsZW5kYXJTeXN0ZW0uZ2V0TWFya2VyRGF5KG0wKSA9PT0gY2FsZW5kYXJTeXN0ZW0uZ2V0TWFya2VyRGF5KG0xKSAmJlxuICAgICAgICAgICAgY2FsZW5kYXJTeXN0ZW0uZ2V0TWFya2VyTW9udGgobTApID09PSBjYWxlbmRhclN5c3RlbS5nZXRNYXJrZXJNb250aChtMSkpIHtcbiAgICAgICAgICAgIHJldHVybiBjYWxlbmRhclN5c3RlbS5nZXRNYXJrZXJZZWFyKG0xKSAtIGNhbGVuZGFyU3lzdGVtLmdldE1hcmtlclllYXIobTApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBkaWZmV2hvbGVNb250aHMobTAsIG0xKSB7XG4gICAgICAgIGxldCB7IGNhbGVuZGFyU3lzdGVtIH0gPSB0aGlzO1xuICAgICAgICBpZiAodGltZUFzTXMobTApID09PSB0aW1lQXNNcyhtMSkgJiZcbiAgICAgICAgICAgIGNhbGVuZGFyU3lzdGVtLmdldE1hcmtlckRheShtMCkgPT09IGNhbGVuZGFyU3lzdGVtLmdldE1hcmtlckRheShtMSkpIHtcbiAgICAgICAgICAgIHJldHVybiAoY2FsZW5kYXJTeXN0ZW0uZ2V0TWFya2VyTW9udGgobTEpIC0gY2FsZW5kYXJTeXN0ZW0uZ2V0TWFya2VyTW9udGgobTApKSArXG4gICAgICAgICAgICAgICAgKGNhbGVuZGFyU3lzdGVtLmdldE1hcmtlclllYXIobTEpIC0gY2FsZW5kYXJTeXN0ZW0uZ2V0TWFya2VyWWVhcihtMCkpICogMTI7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIC8vIFJhbmdlIC8gRHVyYXRpb25cbiAgICBncmVhdGVzdFdob2xlVW5pdChtMCwgbTEpIHtcbiAgICAgICAgbGV0IG4gPSB0aGlzLmRpZmZXaG9sZVllYXJzKG0wLCBtMSk7XG4gICAgICAgIGlmIChuICE9PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4geyB1bml0OiAneWVhcicsIHZhbHVlOiBuIH07XG4gICAgICAgIH1cbiAgICAgICAgbiA9IHRoaXMuZGlmZldob2xlTW9udGhzKG0wLCBtMSk7XG4gICAgICAgIGlmIChuICE9PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4geyB1bml0OiAnbW9udGgnLCB2YWx1ZTogbiB9O1xuICAgICAgICB9XG4gICAgICAgIG4gPSBkaWZmV2hvbGVXZWVrcyhtMCwgbTEpO1xuICAgICAgICBpZiAobiAhPT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuIHsgdW5pdDogJ3dlZWsnLCB2YWx1ZTogbiB9O1xuICAgICAgICB9XG4gICAgICAgIG4gPSBkaWZmV2hvbGVEYXlzKG0wLCBtMSk7XG4gICAgICAgIGlmIChuICE9PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4geyB1bml0OiAnZGF5JywgdmFsdWU6IG4gfTtcbiAgICAgICAgfVxuICAgICAgICBuID0gZGlmZkhvdXJzKG0wLCBtMSk7XG4gICAgICAgIGlmIChpc0ludChuKSkge1xuICAgICAgICAgICAgcmV0dXJuIHsgdW5pdDogJ2hvdXInLCB2YWx1ZTogbiB9O1xuICAgICAgICB9XG4gICAgICAgIG4gPSBkaWZmTWludXRlcyhtMCwgbTEpO1xuICAgICAgICBpZiAoaXNJbnQobikpIHtcbiAgICAgICAgICAgIHJldHVybiB7IHVuaXQ6ICdtaW51dGUnLCB2YWx1ZTogbiB9O1xuICAgICAgICB9XG4gICAgICAgIG4gPSBkaWZmU2Vjb25kcyhtMCwgbTEpO1xuICAgICAgICBpZiAoaXNJbnQobikpIHtcbiAgICAgICAgICAgIHJldHVybiB7IHVuaXQ6ICdzZWNvbmQnLCB2YWx1ZTogbiB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7IHVuaXQ6ICdtaWxsaXNlY29uZCcsIHZhbHVlOiBtMS52YWx1ZU9mKCkgLSBtMC52YWx1ZU9mKCkgfTtcbiAgICB9XG4gICAgY291bnREdXJhdGlvbnNCZXR3ZWVuKG0wLCBtMSwgZCkge1xuICAgICAgICAvLyBUT0RPOiBjYW4gdXNlIGdyZWF0ZXN0V2hvbGVVbml0XG4gICAgICAgIGxldCBkaWZmO1xuICAgICAgICBpZiAoZC55ZWFycykge1xuICAgICAgICAgICAgZGlmZiA9IHRoaXMuZGlmZldob2xlWWVhcnMobTAsIG0xKTtcbiAgICAgICAgICAgIGlmIChkaWZmICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGRpZmYgLyBhc1JvdWdoWWVhcnMoZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGQubW9udGhzKSB7XG4gICAgICAgICAgICBkaWZmID0gdGhpcy5kaWZmV2hvbGVNb250aHMobTAsIG0xKTtcbiAgICAgICAgICAgIGlmIChkaWZmICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGRpZmYgLyBhc1JvdWdoTW9udGhzKGQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChkLmRheXMpIHtcbiAgICAgICAgICAgIGRpZmYgPSBkaWZmV2hvbGVEYXlzKG0wLCBtMSk7XG4gICAgICAgICAgICBpZiAoZGlmZiAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBkaWZmIC8gYXNSb3VnaERheXMoZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIChtMS52YWx1ZU9mKCkgLSBtMC52YWx1ZU9mKCkpIC8gYXNSb3VnaE1zKGQpO1xuICAgIH1cbiAgICAvLyBTdGFydC1PZlxuICAgIC8vIHRoZXNlIERPTidUIHJldHVybiB6b25lZC1kYXRlcy4gb25seSBVVEMgc3RhcnQtb2YgZGF0ZXNcbiAgICBzdGFydE9mKG0sIHVuaXQpIHtcbiAgICAgICAgaWYgKHVuaXQgPT09ICd5ZWFyJykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuc3RhcnRPZlllYXIobSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHVuaXQgPT09ICdtb250aCcpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnN0YXJ0T2ZNb250aChtKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodW5pdCA9PT0gJ3dlZWsnKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5zdGFydE9mV2VlayhtKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodW5pdCA9PT0gJ2RheScpIHtcbiAgICAgICAgICAgIHJldHVybiBzdGFydE9mRGF5KG0pO1xuICAgICAgICB9XG4gICAgICAgIGlmICh1bml0ID09PSAnaG91cicpIHtcbiAgICAgICAgICAgIHJldHVybiBzdGFydE9mSG91cihtKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodW5pdCA9PT0gJ21pbnV0ZScpIHtcbiAgICAgICAgICAgIHJldHVybiBzdGFydE9mTWludXRlKG0pO1xuICAgICAgICB9XG4gICAgICAgIGlmICh1bml0ID09PSAnc2Vjb25kJykge1xuICAgICAgICAgICAgcmV0dXJuIHN0YXJ0T2ZTZWNvbmQobSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIHN0YXJ0T2ZZZWFyKG0pIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2FsZW5kYXJTeXN0ZW0uYXJyYXlUb01hcmtlcihbXG4gICAgICAgICAgICB0aGlzLmNhbGVuZGFyU3lzdGVtLmdldE1hcmtlclllYXIobSksXG4gICAgICAgIF0pO1xuICAgIH1cbiAgICBzdGFydE9mTW9udGgobSkge1xuICAgICAgICByZXR1cm4gdGhpcy5jYWxlbmRhclN5c3RlbS5hcnJheVRvTWFya2VyKFtcbiAgICAgICAgICAgIHRoaXMuY2FsZW5kYXJTeXN0ZW0uZ2V0TWFya2VyWWVhcihtKSxcbiAgICAgICAgICAgIHRoaXMuY2FsZW5kYXJTeXN0ZW0uZ2V0TWFya2VyTW9udGgobSksXG4gICAgICAgIF0pO1xuICAgIH1cbiAgICBzdGFydE9mV2VlayhtKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNhbGVuZGFyU3lzdGVtLmFycmF5VG9NYXJrZXIoW1xuICAgICAgICAgICAgdGhpcy5jYWxlbmRhclN5c3RlbS5nZXRNYXJrZXJZZWFyKG0pLFxuICAgICAgICAgICAgdGhpcy5jYWxlbmRhclN5c3RlbS5nZXRNYXJrZXJNb250aChtKSxcbiAgICAgICAgICAgIG0uZ2V0VVRDRGF0ZSgpIC0gKChtLmdldFVUQ0RheSgpIC0gdGhpcy53ZWVrRG93ICsgNykgJSA3KSxcbiAgICAgICAgXSk7XG4gICAgfVxuICAgIC8vIFdlZWsgTnVtYmVyXG4gICAgY29tcHV0ZVdlZWtOdW1iZXIobWFya2VyKSB7XG4gICAgICAgIGlmICh0aGlzLndlZWtOdW1iZXJGdW5jKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy53ZWVrTnVtYmVyRnVuYyh0aGlzLnRvRGF0ZShtYXJrZXIpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gd2Vla09mWWVhcihtYXJrZXIsIHRoaXMud2Vla0RvdywgdGhpcy53ZWVrRG95KTtcbiAgICB9XG4gICAgLy8gVE9ETzogY2hva2Ugb24gdGltZVpvbmVOYW1lOiBsb25nXG4gICAgZm9ybWF0KG1hcmtlciwgZm9ybWF0dGVyLCBkYXRlT3B0aW9ucyA9IHt9KSB7XG4gICAgICAgIHJldHVybiBmb3JtYXR0ZXIuZm9ybWF0KHtcbiAgICAgICAgICAgIG1hcmtlcixcbiAgICAgICAgICAgIHRpbWVab25lT2Zmc2V0OiBkYXRlT3B0aW9ucy5mb3JjZWRUem8gIT0gbnVsbCA/XG4gICAgICAgICAgICAgICAgZGF0ZU9wdGlvbnMuZm9yY2VkVHpvIDpcbiAgICAgICAgICAgICAgICB0aGlzLm9mZnNldEZvck1hcmtlcihtYXJrZXIpLFxuICAgICAgICB9LCB0aGlzKTtcbiAgICB9XG4gICAgZm9ybWF0UmFuZ2Uoc3RhcnQsIGVuZCwgZm9ybWF0dGVyLCBkYXRlT3B0aW9ucyA9IHt9KSB7XG4gICAgICAgIGlmIChkYXRlT3B0aW9ucy5pc0VuZEV4Y2x1c2l2ZSkge1xuICAgICAgICAgICAgZW5kID0gYWRkTXMoZW5kLCAtMSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZvcm1hdHRlci5mb3JtYXRSYW5nZSh7XG4gICAgICAgICAgICBtYXJrZXI6IHN0YXJ0LFxuICAgICAgICAgICAgdGltZVpvbmVPZmZzZXQ6IGRhdGVPcHRpb25zLmZvcmNlZFN0YXJ0VHpvICE9IG51bGwgP1xuICAgICAgICAgICAgICAgIGRhdGVPcHRpb25zLmZvcmNlZFN0YXJ0VHpvIDpcbiAgICAgICAgICAgICAgICB0aGlzLm9mZnNldEZvck1hcmtlcihzdGFydCksXG4gICAgICAgIH0sIHtcbiAgICAgICAgICAgIG1hcmtlcjogZW5kLFxuICAgICAgICAgICAgdGltZVpvbmVPZmZzZXQ6IGRhdGVPcHRpb25zLmZvcmNlZEVuZFR6byAhPSBudWxsID9cbiAgICAgICAgICAgICAgICBkYXRlT3B0aW9ucy5mb3JjZWRFbmRUem8gOlxuICAgICAgICAgICAgICAgIHRoaXMub2Zmc2V0Rm9yTWFya2VyKGVuZCksXG4gICAgICAgIH0sIHRoaXMsIGRhdGVPcHRpb25zLmRlZmF1bHRTZXBhcmF0b3IpO1xuICAgIH1cbiAgICAvKlxuICAgIERVTUI6IHRoZSBvbWl0VGltZSBhcmcgaXMgZHVtYi4gaWYgd2Ugb21pdCB0aGUgdGltZSwgd2Ugd2FudCB0byBvbWl0IHRoZSB0aW1lem9uZSBvZmZzZXQuIGFuZCBpZiB3ZSBkbyB0aGF0LFxuICAgIG1pZ2h0IGFzIHdlbGwgdXNlIGJ1aWxkSXNvU3RyaW5nIG9yIHNvbWUgb3RoZXIgdXRpbCBkaXJlY3RseVxuICAgICovXG4gICAgZm9ybWF0SXNvKG1hcmtlciwgZXh0cmFPcHRpb25zID0ge30pIHtcbiAgICAgICAgbGV0IHRpbWVab25lT2Zmc2V0ID0gbnVsbDtcbiAgICAgICAgaWYgKCFleHRyYU9wdGlvbnMub21pdFRpbWVab25lT2Zmc2V0KSB7XG4gICAgICAgICAgICBpZiAoZXh0cmFPcHRpb25zLmZvcmNlZFR6byAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGltZVpvbmVPZmZzZXQgPSBleHRyYU9wdGlvbnMuZm9yY2VkVHpvO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGltZVpvbmVPZmZzZXQgPSB0aGlzLm9mZnNldEZvck1hcmtlcihtYXJrZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBidWlsZElzb1N0cmluZyhtYXJrZXIsIHRpbWVab25lT2Zmc2V0LCBleHRyYU9wdGlvbnMub21pdFRpbWUpO1xuICAgIH1cbiAgICAvLyBUaW1lWm9uZVxuICAgIHRpbWVzdGFtcFRvTWFya2VyKG1zKSB7XG4gICAgICAgIGlmICh0aGlzLnRpbWVab25lID09PSAnbG9jYWwnKSB7XG4gICAgICAgICAgICByZXR1cm4gYXJyYXlUb1V0Y0RhdGUoZGF0ZVRvTG9jYWxBcnJheShuZXcgRGF0ZShtcykpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy50aW1lWm9uZSA9PT0gJ1VUQycgfHwgIXRoaXMubmFtZWRUaW1lWm9uZUltcGwpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgRGF0ZShtcyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGFycmF5VG9VdGNEYXRlKHRoaXMubmFtZWRUaW1lWm9uZUltcGwudGltZXN0YW1wVG9BcnJheShtcykpO1xuICAgIH1cbiAgICBvZmZzZXRGb3JNYXJrZXIobSkge1xuICAgICAgICBpZiAodGhpcy50aW1lWm9uZSA9PT0gJ2xvY2FsJykge1xuICAgICAgICAgICAgcmV0dXJuIC1hcnJheVRvTG9jYWxEYXRlKGRhdGVUb1V0Y0FycmF5KG0pKS5nZXRUaW1lem9uZU9mZnNldCgpOyAvLyBjb252ZXJ0IFwiaW52ZXJzZVwiIG9mZnNldCB0byBcIm5vcm1hbFwiIG9mZnNldFxuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnRpbWVab25lID09PSAnVVRDJykge1xuICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMubmFtZWRUaW1lWm9uZUltcGwpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm5hbWVkVGltZVpvbmVJbXBsLm9mZnNldEZvckFycmF5KGRhdGVUb1V0Y0FycmF5KG0pKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgLy8gQ29udmVyc2lvblxuICAgIHRvRGF0ZShtLCBmb3JjZWRUem8pIHtcbiAgICAgICAgaWYgKHRoaXMudGltZVpvbmUgPT09ICdsb2NhbCcpIHtcbiAgICAgICAgICAgIHJldHVybiBhcnJheVRvTG9jYWxEYXRlKGRhdGVUb1V0Y0FycmF5KG0pKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy50aW1lWm9uZSA9PT0gJ1VUQycpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgRGF0ZShtLnZhbHVlT2YoKSk7IC8vIG1ha2Ugc3VyZSBpdCdzIGEgY29weVxuICAgICAgICB9XG4gICAgICAgIGlmICghdGhpcy5uYW1lZFRpbWVab25lSW1wbCkge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBEYXRlKG0udmFsdWVPZigpIC0gKGZvcmNlZFR6byB8fCAwKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBEYXRlKG0udmFsdWVPZigpIC1cbiAgICAgICAgICAgIHRoaXMubmFtZWRUaW1lWm9uZUltcGwub2Zmc2V0Rm9yQXJyYXkoZGF0ZVRvVXRjQXJyYXkobSkpICogMTAwMCAqIDYwKTtcbiAgICB9XG59XG5cbmNsYXNzIE5hbWVkVGltZVpvbmVJbXBsIHtcbiAgICBjb25zdHJ1Y3Rvcih0aW1lWm9uZU5hbWUpIHtcbiAgICAgICAgdGhpcy50aW1lWm9uZU5hbWUgPSB0aW1lWm9uZU5hbWU7XG4gICAgfVxufVxuXG5jbGFzcyBTZWdIaWVyYXJjaHkge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICAvLyBzZXR0aW5nc1xuICAgICAgICB0aGlzLnN0cmljdE9yZGVyID0gZmFsc2U7XG4gICAgICAgIHRoaXMuYWxsb3dSZXNsaWNpbmcgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5tYXhDb29yZCA9IC0xOyAvLyAtMSBtZWFucyBubyBtYXhcbiAgICAgICAgdGhpcy5tYXhTdGFja0NudCA9IC0xOyAvLyAtMSBtZWFucyBubyBtYXhcbiAgICAgICAgdGhpcy5sZXZlbENvb3JkcyA9IFtdOyAvLyBvcmRlcmVkXG4gICAgICAgIHRoaXMuZW50cmllc0J5TGV2ZWwgPSBbXTsgLy8gcGFyYWxsZWwgd2l0aCBsZXZlbENvb3Jkc1xuICAgICAgICB0aGlzLnN0YWNrQ250cyA9IHt9OyAvLyBUT0RPOiB1c2UgYmV0dGVyIHRlY2huaXF1ZSE/XG4gICAgfVxuICAgIGFkZFNlZ3MoaW5wdXRzKSB7XG4gICAgICAgIGxldCBoaWRkZW5FbnRyaWVzID0gW107XG4gICAgICAgIGZvciAobGV0IGlucHV0IG9mIGlucHV0cykge1xuICAgICAgICAgICAgdGhpcy5pbnNlcnRFbnRyeShpbnB1dCwgaGlkZGVuRW50cmllcyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGhpZGRlbkVudHJpZXM7XG4gICAgfVxuICAgIGluc2VydEVudHJ5KGVudHJ5LCBoaWRkZW5FbnRyaWVzKSB7XG4gICAgICAgIGxldCBpbnNlcnRpb24gPSB0aGlzLmZpbmRJbnNlcnRpb24oZW50cnkpO1xuICAgICAgICBpZiAodGhpcy5pc0luc2VydGlvblZhbGlkKGluc2VydGlvbiwgZW50cnkpKSB7XG4gICAgICAgICAgICB0aGlzLmluc2VydEVudHJ5QXQoZW50cnksIGluc2VydGlvbik7XG4gICAgICAgICAgICByZXR1cm4gMTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5oYW5kbGVJbnZhbGlkSW5zZXJ0aW9uKGluc2VydGlvbiwgZW50cnksIGhpZGRlbkVudHJpZXMpO1xuICAgIH1cbiAgICBpc0luc2VydGlvblZhbGlkKGluc2VydGlvbiwgZW50cnkpIHtcbiAgICAgICAgcmV0dXJuICh0aGlzLm1heENvb3JkID09PSAtMSB8fCBpbnNlcnRpb24ubGV2ZWxDb29yZCArIGVudHJ5LnRoaWNrbmVzcyA8PSB0aGlzLm1heENvb3JkKSAmJlxuICAgICAgICAgICAgKHRoaXMubWF4U3RhY2tDbnQgPT09IC0xIHx8IGluc2VydGlvbi5zdGFja0NudCA8IHRoaXMubWF4U3RhY2tDbnQpO1xuICAgIH1cbiAgICAvLyByZXR1cm5zIG51bWJlciBvZiBuZXcgZW50cmllcyBpbnNlcnRlZFxuICAgIGhhbmRsZUludmFsaWRJbnNlcnRpb24oaW5zZXJ0aW9uLCBlbnRyeSwgaGlkZGVuRW50cmllcykge1xuICAgICAgICBpZiAodGhpcy5hbGxvd1Jlc2xpY2luZyAmJiBpbnNlcnRpb24udG91Y2hpbmdFbnRyeSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuc3BsaXRFbnRyeShlbnRyeSwgaW5zZXJ0aW9uLnRvdWNoaW5nRW50cnksIGhpZGRlbkVudHJpZXMpO1xuICAgICAgICB9XG4gICAgICAgIGhpZGRlbkVudHJpZXMucHVzaChlbnRyeSk7XG4gICAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICBzcGxpdEVudHJ5KGVudHJ5LCBiYXJyaWVyLCBoaWRkZW5FbnRyaWVzKSB7XG4gICAgICAgIGxldCBwYXJ0Q250ID0gMDtcbiAgICAgICAgbGV0IHNwbGl0SGlkZGVuRW50cmllcyA9IFtdO1xuICAgICAgICBsZXQgZW50cnlTcGFuID0gZW50cnkuc3BhbjtcbiAgICAgICAgbGV0IGJhcnJpZXJTcGFuID0gYmFycmllci5zcGFuO1xuICAgICAgICBpZiAoZW50cnlTcGFuLnN0YXJ0IDwgYmFycmllclNwYW4uc3RhcnQpIHtcbiAgICAgICAgICAgIHBhcnRDbnQgKz0gdGhpcy5pbnNlcnRFbnRyeSh7XG4gICAgICAgICAgICAgICAgaW5kZXg6IGVudHJ5LmluZGV4LFxuICAgICAgICAgICAgICAgIHRoaWNrbmVzczogZW50cnkudGhpY2tuZXNzLFxuICAgICAgICAgICAgICAgIHNwYW46IHsgc3RhcnQ6IGVudHJ5U3Bhbi5zdGFydCwgZW5kOiBiYXJyaWVyU3Bhbi5zdGFydCB9LFxuICAgICAgICAgICAgfSwgc3BsaXRIaWRkZW5FbnRyaWVzKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZW50cnlTcGFuLmVuZCA+IGJhcnJpZXJTcGFuLmVuZCkge1xuICAgICAgICAgICAgcGFydENudCArPSB0aGlzLmluc2VydEVudHJ5KHtcbiAgICAgICAgICAgICAgICBpbmRleDogZW50cnkuaW5kZXgsXG4gICAgICAgICAgICAgICAgdGhpY2tuZXNzOiBlbnRyeS50aGlja25lc3MsXG4gICAgICAgICAgICAgICAgc3BhbjogeyBzdGFydDogYmFycmllclNwYW4uZW5kLCBlbmQ6IGVudHJ5U3Bhbi5lbmQgfSxcbiAgICAgICAgICAgIH0sIHNwbGl0SGlkZGVuRW50cmllcyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHBhcnRDbnQpIHtcbiAgICAgICAgICAgIGhpZGRlbkVudHJpZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgaW5kZXg6IGVudHJ5LmluZGV4LFxuICAgICAgICAgICAgICAgIHRoaWNrbmVzczogZW50cnkudGhpY2tuZXNzLFxuICAgICAgICAgICAgICAgIHNwYW46IGludGVyc2VjdFNwYW5zKGJhcnJpZXJTcGFuLCBlbnRyeVNwYW4pLCAvLyBndWFyYW50ZWVkIHRvIGludGVyc2VjdFxuICAgICAgICAgICAgfSwgLi4uc3BsaXRIaWRkZW5FbnRyaWVzKTtcbiAgICAgICAgICAgIHJldHVybiBwYXJ0Q250O1xuICAgICAgICB9XG4gICAgICAgIGhpZGRlbkVudHJpZXMucHVzaChlbnRyeSk7XG4gICAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICBpbnNlcnRFbnRyeUF0KGVudHJ5LCBpbnNlcnRpb24pIHtcbiAgICAgICAgbGV0IHsgZW50cmllc0J5TGV2ZWwsIGxldmVsQ29vcmRzIH0gPSB0aGlzO1xuICAgICAgICBpZiAoaW5zZXJ0aW9uLmxhdGVyYWwgPT09IC0xKSB7XG4gICAgICAgICAgICAvLyBjcmVhdGUgYSBuZXcgbGV2ZWxcbiAgICAgICAgICAgIGluc2VydEF0KGxldmVsQ29vcmRzLCBpbnNlcnRpb24ubGV2ZWwsIGluc2VydGlvbi5sZXZlbENvb3JkKTtcbiAgICAgICAgICAgIGluc2VydEF0KGVudHJpZXNCeUxldmVsLCBpbnNlcnRpb24ubGV2ZWwsIFtlbnRyeV0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gaW5zZXJ0IGludG8gZXhpc3RpbmcgbGV2ZWxcbiAgICAgICAgICAgIGluc2VydEF0KGVudHJpZXNCeUxldmVsW2luc2VydGlvbi5sZXZlbF0sIGluc2VydGlvbi5sYXRlcmFsLCBlbnRyeSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zdGFja0NudHNbYnVpbGRFbnRyeUtleShlbnRyeSldID0gaW5zZXJ0aW9uLnN0YWNrQ250O1xuICAgIH1cbiAgICBmaW5kSW5zZXJ0aW9uKG5ld0VudHJ5KSB7XG4gICAgICAgIGxldCB7IGxldmVsQ29vcmRzLCBlbnRyaWVzQnlMZXZlbCwgc3RyaWN0T3JkZXIsIHN0YWNrQ250cyB9ID0gdGhpcztcbiAgICAgICAgbGV0IGxldmVsQ250ID0gbGV2ZWxDb29yZHMubGVuZ3RoO1xuICAgICAgICBsZXQgY2FuZGlkYXRlQ29vcmQgPSAwO1xuICAgICAgICBsZXQgdG91Y2hpbmdMZXZlbCA9IC0xO1xuICAgICAgICBsZXQgdG91Y2hpbmdMYXRlcmFsID0gLTE7XG4gICAgICAgIGxldCB0b3VjaGluZ0VudHJ5ID0gbnVsbDtcbiAgICAgICAgbGV0IHN0YWNrQ250ID0gMDtcbiAgICAgICAgZm9yIChsZXQgdHJhY2tpbmdMZXZlbCA9IDA7IHRyYWNraW5nTGV2ZWwgPCBsZXZlbENudDsgdHJhY2tpbmdMZXZlbCArPSAxKSB7XG4gICAgICAgICAgICBsZXQgdHJhY2tpbmdDb29yZCA9IGxldmVsQ29vcmRzW3RyYWNraW5nTGV2ZWxdO1xuICAgICAgICAgICAgLy8gaWYgdGhlIGN1cnJlbnQgbGV2ZWwgaXMgcGFzdCB0aGUgcGxhY2VkIGVudHJ5LCB3ZSBoYXZlIGZvdW5kIGEgZ29vZCBlbXB0eSBzcGFjZSBhbmQgY2FuIHN0b3AuXG4gICAgICAgICAgICAvLyBpZiBzdHJpY3RPcmRlciwga2VlcCBmaW5kaW5nIG1vcmUgbGF0ZXJhbCBpbnRlcnNlY3Rpb25zLlxuICAgICAgICAgICAgaWYgKCFzdHJpY3RPcmRlciAmJiB0cmFja2luZ0Nvb3JkID49IGNhbmRpZGF0ZUNvb3JkICsgbmV3RW50cnkudGhpY2tuZXNzKSB7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsZXQgdHJhY2tpbmdFbnRyaWVzID0gZW50cmllc0J5TGV2ZWxbdHJhY2tpbmdMZXZlbF07XG4gICAgICAgICAgICBsZXQgdHJhY2tpbmdFbnRyeTtcbiAgICAgICAgICAgIGxldCBzZWFyY2hSZXMgPSBiaW5hcnlTZWFyY2godHJhY2tpbmdFbnRyaWVzLCBuZXdFbnRyeS5zcGFuLnN0YXJ0LCBnZXRFbnRyeVNwYW5FbmQpOyAvLyBmaW5kIGZpcnN0IGVudHJ5IGFmdGVyIG5ld0VudHJ5J3MgZW5kXG4gICAgICAgICAgICBsZXQgbGF0ZXJhbEluZGV4ID0gc2VhcmNoUmVzWzBdICsgc2VhcmNoUmVzWzFdOyAvLyBpZiBleGFjdCBtYXRjaCAod2hpY2ggZG9lc24ndCBjb2xsaWRlKSwgZ28gdG8gbmV4dCBvbmVcbiAgICAgICAgICAgIHdoaWxlICggLy8gbG9vcCB0aHJvdWdoIGVudHJpZXMgdGhhdCBob3Jpem9udGFsbHkgaW50ZXJzZWN0XG4gICAgICAgICAgICAodHJhY2tpbmdFbnRyeSA9IHRyYWNraW5nRW50cmllc1tsYXRlcmFsSW5kZXhdKSAmJiAvLyBidXQgbm90IHBhc3QgdGhlIHdob2xlIGVudHJ5IGxpc3RcbiAgICAgICAgICAgICAgICB0cmFja2luZ0VudHJ5LnNwYW4uc3RhcnQgPCBuZXdFbnRyeS5zcGFuLmVuZCAvLyBhbmQgbm90IGVudGlyZWx5IHBhc3QgbmV3RW50cnlcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIGxldCB0cmFja2luZ0VudHJ5Qm90dG9tID0gdHJhY2tpbmdDb29yZCArIHRyYWNraW5nRW50cnkudGhpY2tuZXNzO1xuICAgICAgICAgICAgICAgIC8vIGludGVyc2VjdHMgaW50byB0aGUgdG9wIG9mIHRoZSBjYW5kaWRhdGU/XG4gICAgICAgICAgICAgICAgaWYgKHRyYWNraW5nRW50cnlCb3R0b20gPiBjYW5kaWRhdGVDb29yZCkge1xuICAgICAgICAgICAgICAgICAgICBjYW5kaWRhdGVDb29yZCA9IHRyYWNraW5nRW50cnlCb3R0b207XG4gICAgICAgICAgICAgICAgICAgIHRvdWNoaW5nRW50cnkgPSB0cmFja2luZ0VudHJ5O1xuICAgICAgICAgICAgICAgICAgICB0b3VjaGluZ0xldmVsID0gdHJhY2tpbmdMZXZlbDtcbiAgICAgICAgICAgICAgICAgICAgdG91Y2hpbmdMYXRlcmFsID0gbGF0ZXJhbEluZGV4O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvLyBidXR0cyB1cCBhZ2FpbnN0IHRvcCBvZiBjYW5kaWRhdGU/ICh3aWxsIGhhcHBlbiBpZiBqdXN0IGludGVyc2VjdGVkIGFzIHdlbGwpXG4gICAgICAgICAgICAgICAgaWYgKHRyYWNraW5nRW50cnlCb3R0b20gPT09IGNhbmRpZGF0ZUNvb3JkKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGFjY3VtdWxhdGUgdGhlIGhpZ2hlc3QgcG9zc2libGUgc3RhY2tDbnQgb2YgdGhlIHRyYWNraW5nRW50cmllcyB0aGF0IGJ1dHQgdXBcbiAgICAgICAgICAgICAgICAgICAgc3RhY2tDbnQgPSBNYXRoLm1heChzdGFja0NudCwgc3RhY2tDbnRzW2J1aWxkRW50cnlLZXkodHJhY2tpbmdFbnRyeSldICsgMSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGxhdGVyYWxJbmRleCArPSAxO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIHRoZSBkZXN0aW5hdGlvbiBsZXZlbCB3aWxsIGJlIGFmdGVyIHRvdWNoaW5nRW50cnkncyBsZXZlbC4gZmluZCBpdFxuICAgICAgICBsZXQgZGVzdExldmVsID0gMDtcbiAgICAgICAgaWYgKHRvdWNoaW5nRW50cnkpIHtcbiAgICAgICAgICAgIGRlc3RMZXZlbCA9IHRvdWNoaW5nTGV2ZWwgKyAxO1xuICAgICAgICAgICAgd2hpbGUgKGRlc3RMZXZlbCA8IGxldmVsQ250ICYmIGxldmVsQ29vcmRzW2Rlc3RMZXZlbF0gPCBjYW5kaWRhdGVDb29yZCkge1xuICAgICAgICAgICAgICAgIGRlc3RMZXZlbCArPSAxO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIGlmIGFkZGluZyB0byBhbiBleGlzdGluZyBsZXZlbCwgZmluZCB3aGVyZSB0byBpbnNlcnRcbiAgICAgICAgbGV0IGRlc3RMYXRlcmFsID0gLTE7XG4gICAgICAgIGlmIChkZXN0TGV2ZWwgPCBsZXZlbENudCAmJiBsZXZlbENvb3Jkc1tkZXN0TGV2ZWxdID09PSBjYW5kaWRhdGVDb29yZCkge1xuICAgICAgICAgICAgZGVzdExhdGVyYWwgPSBiaW5hcnlTZWFyY2goZW50cmllc0J5TGV2ZWxbZGVzdExldmVsXSwgbmV3RW50cnkuc3Bhbi5lbmQsIGdldEVudHJ5U3BhbkVuZClbMF07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHRvdWNoaW5nTGV2ZWwsXG4gICAgICAgICAgICB0b3VjaGluZ0xhdGVyYWwsXG4gICAgICAgICAgICB0b3VjaGluZ0VudHJ5LFxuICAgICAgICAgICAgc3RhY2tDbnQsXG4gICAgICAgICAgICBsZXZlbENvb3JkOiBjYW5kaWRhdGVDb29yZCxcbiAgICAgICAgICAgIGxldmVsOiBkZXN0TGV2ZWwsXG4gICAgICAgICAgICBsYXRlcmFsOiBkZXN0TGF0ZXJhbCxcbiAgICAgICAgfTtcbiAgICB9XG4gICAgLy8gc29ydGVkIGJ5IGxldmVsQ29vcmQgKGxvd2VzdCB0byBoaWdoZXN0KVxuICAgIHRvUmVjdHMoKSB7XG4gICAgICAgIGxldCB7IGVudHJpZXNCeUxldmVsLCBsZXZlbENvb3JkcyB9ID0gdGhpcztcbiAgICAgICAgbGV0IGxldmVsQ250ID0gZW50cmllc0J5TGV2ZWwubGVuZ3RoO1xuICAgICAgICBsZXQgcmVjdHMgPSBbXTtcbiAgICAgICAgZm9yIChsZXQgbGV2ZWwgPSAwOyBsZXZlbCA8IGxldmVsQ250OyBsZXZlbCArPSAxKSB7XG4gICAgICAgICAgICBsZXQgZW50cmllcyA9IGVudHJpZXNCeUxldmVsW2xldmVsXTtcbiAgICAgICAgICAgIGxldCBsZXZlbENvb3JkID0gbGV2ZWxDb29yZHNbbGV2ZWxdO1xuICAgICAgICAgICAgZm9yIChsZXQgZW50cnkgb2YgZW50cmllcykge1xuICAgICAgICAgICAgICAgIHJlY3RzLnB1c2goT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCBlbnRyeSksIHsgbGV2ZWxDb29yZCB9KSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlY3RzO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGdldEVudHJ5U3BhbkVuZChlbnRyeSkge1xuICAgIHJldHVybiBlbnRyeS5zcGFuLmVuZDtcbn1cbmZ1bmN0aW9uIGJ1aWxkRW50cnlLZXkoZW50cnkpIHtcbiAgICByZXR1cm4gZW50cnkuaW5kZXggKyAnOicgKyBlbnRyeS5zcGFuLnN0YXJ0O1xufVxuLy8gcmV0dXJucyBncm91cHMgd2l0aCBlbnRyaWVzIHNvcnRlZCBieSBpbnB1dCBvcmRlclxuZnVuY3Rpb24gZ3JvdXBJbnRlcnNlY3RpbmdFbnRyaWVzKGVudHJpZXMpIHtcbiAgICBsZXQgbWVyZ2VzID0gW107XG4gICAgZm9yIChsZXQgZW50cnkgb2YgZW50cmllcykge1xuICAgICAgICBsZXQgZmlsdGVyZWRNZXJnZXMgPSBbXTtcbiAgICAgICAgbGV0IGh1bmdyeU1lcmdlID0ge1xuICAgICAgICAgICAgc3BhbjogZW50cnkuc3BhbixcbiAgICAgICAgICAgIGVudHJpZXM6IFtlbnRyeV0sXG4gICAgICAgIH07XG4gICAgICAgIGZvciAobGV0IG1lcmdlIG9mIG1lcmdlcykge1xuICAgICAgICAgICAgaWYgKGludGVyc2VjdFNwYW5zKG1lcmdlLnNwYW4sIGh1bmdyeU1lcmdlLnNwYW4pKSB7XG4gICAgICAgICAgICAgICAgaHVuZ3J5TWVyZ2UgPSB7XG4gICAgICAgICAgICAgICAgICAgIGVudHJpZXM6IG1lcmdlLmVudHJpZXMuY29uY2F0KGh1bmdyeU1lcmdlLmVudHJpZXMpLFxuICAgICAgICAgICAgICAgICAgICBzcGFuOiBqb2luU3BhbnMobWVyZ2Uuc3BhbiwgaHVuZ3J5TWVyZ2Uuc3BhbiksXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGZpbHRlcmVkTWVyZ2VzLnB1c2gobWVyZ2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGZpbHRlcmVkTWVyZ2VzLnB1c2goaHVuZ3J5TWVyZ2UpO1xuICAgICAgICBtZXJnZXMgPSBmaWx0ZXJlZE1lcmdlcztcbiAgICB9XG4gICAgcmV0dXJuIG1lcmdlcztcbn1cbmZ1bmN0aW9uIGpvaW5TcGFucyhzcGFuMCwgc3BhbjEpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBzdGFydDogTWF0aC5taW4oc3BhbjAuc3RhcnQsIHNwYW4xLnN0YXJ0KSxcbiAgICAgICAgZW5kOiBNYXRoLm1heChzcGFuMC5lbmQsIHNwYW4xLmVuZCksXG4gICAgfTtcbn1cbmZ1bmN0aW9uIGludGVyc2VjdFNwYW5zKHNwYW4wLCBzcGFuMSkge1xuICAgIGxldCBzdGFydCA9IE1hdGgubWF4KHNwYW4wLnN0YXJ0LCBzcGFuMS5zdGFydCk7XG4gICAgbGV0IGVuZCA9IE1hdGgubWluKHNwYW4wLmVuZCwgc3BhbjEuZW5kKTtcbiAgICBpZiAoc3RhcnQgPCBlbmQpIHtcbiAgICAgICAgcmV0dXJuIHsgc3RhcnQsIGVuZCB9O1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbn1cbi8vIGdlbmVyYWwgdXRpbFxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5mdW5jdGlvbiBpbnNlcnRBdChhcnIsIGluZGV4LCBpdGVtKSB7XG4gICAgYXJyLnNwbGljZShpbmRleCwgMCwgaXRlbSk7XG59XG5mdW5jdGlvbiBiaW5hcnlTZWFyY2goYSwgc2VhcmNoVmFsLCBnZXRJdGVtVmFsKSB7XG4gICAgbGV0IHN0YXJ0SW5kZXggPSAwO1xuICAgIGxldCBlbmRJbmRleCA9IGEubGVuZ3RoOyAvLyBleGNsdXNpdmVcbiAgICBpZiAoIWVuZEluZGV4IHx8IHNlYXJjaFZhbCA8IGdldEl0ZW1WYWwoYVtzdGFydEluZGV4XSkpIHsgLy8gbm8gaXRlbXMgT1IgYmVmb3JlIGZpcnN0IGl0ZW1cbiAgICAgICAgcmV0dXJuIFswLCAwXTtcbiAgICB9XG4gICAgaWYgKHNlYXJjaFZhbCA+IGdldEl0ZW1WYWwoYVtlbmRJbmRleCAtIDFdKSkgeyAvLyBhZnRlciBsYXN0IGl0ZW1cbiAgICAgICAgcmV0dXJuIFtlbmRJbmRleCwgMF07XG4gICAgfVxuICAgIHdoaWxlIChzdGFydEluZGV4IDwgZW5kSW5kZXgpIHtcbiAgICAgICAgbGV0IG1pZGRsZUluZGV4ID0gTWF0aC5mbG9vcihzdGFydEluZGV4ICsgKGVuZEluZGV4IC0gc3RhcnRJbmRleCkgLyAyKTtcbiAgICAgICAgbGV0IG1pZGRsZVZhbCA9IGdldEl0ZW1WYWwoYVttaWRkbGVJbmRleF0pO1xuICAgICAgICBpZiAoc2VhcmNoVmFsIDwgbWlkZGxlVmFsKSB7XG4gICAgICAgICAgICBlbmRJbmRleCA9IG1pZGRsZUluZGV4O1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHNlYXJjaFZhbCA+IG1pZGRsZVZhbCkge1xuICAgICAgICAgICAgc3RhcnRJbmRleCA9IG1pZGRsZUluZGV4ICsgMTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHsgLy8gZXF1YWwhXG4gICAgICAgICAgICByZXR1cm4gW21pZGRsZUluZGV4LCAxXTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gW3N0YXJ0SW5kZXgsIDBdO1xufVxuXG5jbGFzcyBJbnRlcmFjdGlvbiB7XG4gICAgY29uc3RydWN0b3Ioc2V0dGluZ3MpIHtcbiAgICAgICAgdGhpcy5jb21wb25lbnQgPSBzZXR0aW5ncy5jb21wb25lbnQ7XG4gICAgICAgIHRoaXMuaXNIaXRDb21ib0FsbG93ZWQgPSBzZXR0aW5ncy5pc0hpdENvbWJvQWxsb3dlZCB8fCBudWxsO1xuICAgIH1cbiAgICBkZXN0cm95KCkge1xuICAgIH1cbn1cbmZ1bmN0aW9uIHBhcnNlSW50ZXJhY3Rpb25TZXR0aW5ncyhjb21wb25lbnQsIGlucHV0KSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgY29tcG9uZW50LFxuICAgICAgICBlbDogaW5wdXQuZWwsXG4gICAgICAgIHVzZUV2ZW50Q2VudGVyOiBpbnB1dC51c2VFdmVudENlbnRlciAhPSBudWxsID8gaW5wdXQudXNlRXZlbnRDZW50ZXIgOiB0cnVlLFxuICAgICAgICBpc0hpdENvbWJvQWxsb3dlZDogaW5wdXQuaXNIaXRDb21ib0FsbG93ZWQgfHwgbnVsbCxcbiAgICB9O1xufVxuZnVuY3Rpb24gaW50ZXJhY3Rpb25TZXR0aW5nc1RvU3RvcmUoc2V0dGluZ3MpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBbc2V0dGluZ3MuY29tcG9uZW50LnVpZF06IHNldHRpbmdzLFxuICAgIH07XG59XG4vLyBnbG9iYWwgc3RhdGVcbmNvbnN0IGludGVyYWN0aW9uU2V0dGluZ3NTdG9yZSA9IHt9O1xuXG4vKlxuQW4gYWJzdHJhY3Rpb24gZm9yIGEgZHJhZ2dpbmcgaW50ZXJhY3Rpb24gb3JpZ2luYXRpbmcgb24gYW4gZXZlbnQuXG5Eb2VzIGhpZ2hlci1sZXZlbCB0aGluZ3MgdGhhbiBQb2ludGVyRHJhZ2dlciwgc3VjaCBhcyBwb3NzaWJseTpcbi0gYSBcIm1pcnJvclwiIHRoYXQgbW92ZXMgd2l0aCB0aGUgcG9pbnRlclxuLSBhIG1pbmltdW0gbnVtYmVyIG9mIHBpeGVscyBvciBvdGhlciBjcml0ZXJpYSBmb3IgYSB0cnVlIGRyYWcgdG8gYmVnaW5cblxuc3ViY2xhc3NlcyBtdXN0IGVtaXQ6XG4tIHBvaW50ZXJkb3duXG4tIGRyYWdzdGFydFxuLSBkcmFnbW92ZVxuLSBwb2ludGVydXBcbi0gZHJhZ2VuZFxuKi9cbmNsYXNzIEVsZW1lbnREcmFnZ2luZyB7XG4gICAgY29uc3RydWN0b3IoZWwsIHNlbGVjdG9yKSB7XG4gICAgICAgIHRoaXMuZW1pdHRlciA9IG5ldyBFbWl0dGVyKCk7XG4gICAgfVxuICAgIGRlc3Ryb3koKSB7XG4gICAgfVxuICAgIHNldE1pcnJvcklzVmlzaWJsZShib29sKSB7XG4gICAgICAgIC8vIG9wdGlvbmFsIGlmIHN1YmNsYXNzIGRvZXNuJ3Qgd2FudCB0byBzdXBwb3J0IGEgbWlycm9yXG4gICAgfVxuICAgIHNldE1pcnJvck5lZWRzUmV2ZXJ0KGJvb2wpIHtcbiAgICAgICAgLy8gb3B0aW9uYWwgaWYgc3ViY2xhc3MgZG9lc24ndCB3YW50IHRvIHN1cHBvcnQgYSBtaXJyb3JcbiAgICB9XG4gICAgc2V0QXV0b1Njcm9sbEVuYWJsZWQoYm9vbCkge1xuICAgICAgICAvLyBvcHRpb25hbFxuICAgIH1cbn1cblxuLy8gVE9ETzogZ2V0IHJpZCBvZiB0aGlzIGluIGZhdm9yIG9mIG9wdGlvbnMgc3lzdGVtLFxuLy8gdGhvIGl0J3MgcmVhbGx5IGVhc3kgdG8gYWNjZXNzIHRoaXMgZ2xvYmFsbHkgcmF0aGVyIHRoYW4gcGFzcyB0aHJ1IG9wdGlvbnMuXG5jb25zdCBjb25maWcgPSB7fTtcblxuLypcbkluZm9ybWF0aW9uIGFib3V0IHdoYXQgd2lsbCBoYXBwZW4gd2hlbiBhbiBleHRlcm5hbCBlbGVtZW50IGlzIGRyYWdnZWQtYW5kLWRyb3BwZWRcbm9udG8gYSBjYWxlbmRhci4gQ29udGFpbnMgaW5mb3JtYXRpb24gZm9yIGNyZWF0aW5nIGFuIGV2ZW50LlxuKi9cbmNvbnN0IERSQUdfTUVUQV9SRUZJTkVSUyA9IHtcbiAgICBzdGFydFRpbWU6IGNyZWF0ZUR1cmF0aW9uLFxuICAgIGR1cmF0aW9uOiBjcmVhdGVEdXJhdGlvbixcbiAgICBjcmVhdGU6IEJvb2xlYW4sXG4gICAgc291cmNlSWQ6IFN0cmluZyxcbn07XG5mdW5jdGlvbiBwYXJzZURyYWdNZXRhKHJhdykge1xuICAgIGxldCB7IHJlZmluZWQsIGV4dHJhIH0gPSByZWZpbmVQcm9wcyhyYXcsIERSQUdfTUVUQV9SRUZJTkVSUyk7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgc3RhcnRUaW1lOiByZWZpbmVkLnN0YXJ0VGltZSB8fCBudWxsLFxuICAgICAgICBkdXJhdGlvbjogcmVmaW5lZC5kdXJhdGlvbiB8fCBudWxsLFxuICAgICAgICBjcmVhdGU6IHJlZmluZWQuY3JlYXRlICE9IG51bGwgPyByZWZpbmVkLmNyZWF0ZSA6IHRydWUsXG4gICAgICAgIHNvdXJjZUlkOiByZWZpbmVkLnNvdXJjZUlkLFxuICAgICAgICBsZWZ0b3ZlclByb3BzOiBleHRyYSxcbiAgICB9O1xufVxuXG5jbGFzcyBDYWxlbmRhclJvb3QgZXh0ZW5kcyBCYXNlQ29tcG9uZW50IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgICAgICAgIGZvclByaW50OiBmYWxzZSxcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5oYW5kbGVCZWZvcmVQcmludCA9ICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBmb3JQcmludDogdHJ1ZSB9KTtcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5oYW5kbGVBZnRlclByaW50ID0gKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGZvclByaW50OiBmYWxzZSB9KTtcbiAgICAgICAgfTtcbiAgICB9XG4gICAgcmVuZGVyKCkge1xuICAgICAgICBsZXQgeyBwcm9wcyB9ID0gdGhpcztcbiAgICAgICAgbGV0IHsgb3B0aW9ucyB9ID0gcHJvcHM7XG4gICAgICAgIGxldCB7IGZvclByaW50IH0gPSB0aGlzLnN0YXRlO1xuICAgICAgICBsZXQgaXNIZWlnaHRBdXRvID0gZm9yUHJpbnQgfHwgb3B0aW9ucy5oZWlnaHQgPT09ICdhdXRvJyB8fCBvcHRpb25zLmNvbnRlbnRIZWlnaHQgPT09ICdhdXRvJztcbiAgICAgICAgbGV0IGhlaWdodCA9ICghaXNIZWlnaHRBdXRvICYmIG9wdGlvbnMuaGVpZ2h0ICE9IG51bGwpID8gb3B0aW9ucy5oZWlnaHQgOiAnJztcbiAgICAgICAgbGV0IGNsYXNzTmFtZXMgPSBbXG4gICAgICAgICAgICAnZmMnLFxuICAgICAgICAgICAgZm9yUHJpbnQgPyAnZmMtbWVkaWEtcHJpbnQnIDogJ2ZjLW1lZGlhLXNjcmVlbicsXG4gICAgICAgICAgICBgZmMtZGlyZWN0aW9uLSR7b3B0aW9ucy5kaXJlY3Rpb259YCxcbiAgICAgICAgICAgIHByb3BzLnRoZW1lLmdldENsYXNzKCdyb290JyksXG4gICAgICAgIF07XG4gICAgICAgIGlmICghZ2V0Q2FuVkdyb3dXaXRoaW5DZWxsKCkpIHtcbiAgICAgICAgICAgIGNsYXNzTmFtZXMucHVzaCgnZmMtbGlxdWlkLWhhY2snKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcHJvcHMuY2hpbGRyZW4oY2xhc3NOYW1lcywgaGVpZ2h0LCBpc0hlaWdodEF1dG8sIGZvclByaW50KTtcbiAgICB9XG4gICAgY29tcG9uZW50RGlkTW91bnQoKSB7XG4gICAgICAgIGxldCB7IGVtaXR0ZXIgfSA9IHRoaXMucHJvcHM7XG4gICAgICAgIGVtaXR0ZXIub24oJ19iZWZvcmVwcmludCcsIHRoaXMuaGFuZGxlQmVmb3JlUHJpbnQpO1xuICAgICAgICBlbWl0dGVyLm9uKCdfYWZ0ZXJwcmludCcsIHRoaXMuaGFuZGxlQWZ0ZXJQcmludCk7XG4gICAgfVxuICAgIGNvbXBvbmVudFdpbGxVbm1vdW50KCkge1xuICAgICAgICBsZXQgeyBlbWl0dGVyIH0gPSB0aGlzLnByb3BzO1xuICAgICAgICBlbWl0dGVyLm9mZignX2JlZm9yZXByaW50JywgdGhpcy5oYW5kbGVCZWZvcmVQcmludCk7XG4gICAgICAgIGVtaXR0ZXIub2ZmKCdfYWZ0ZXJwcmludCcsIHRoaXMuaGFuZGxlQWZ0ZXJQcmludCk7XG4gICAgfVxufVxuXG4vLyBDb21wdXRlcyBhIGRlZmF1bHQgY29sdW1uIGhlYWRlciBmb3JtYXR0aW5nIHN0cmluZyBpZiBgY29sRm9ybWF0YCBpcyBub3QgZXhwbGljaXRseSBkZWZpbmVkXG5mdW5jdGlvbiBjb21wdXRlRmFsbGJhY2tIZWFkZXJGb3JtYXQoZGF0ZXNSZXBEaXN0aW5jdERheXMsIGRheUNudCkge1xuICAgIC8vIGlmIG1vcmUgdGhhbiBvbmUgd2VlayByb3csIG9yIGlmIHRoZXJlIGFyZSBhIGxvdCBvZiBjb2x1bW5zIHdpdGggbm90IG11Y2ggc3BhY2UsXG4gICAgLy8gcHV0IGp1c3QgdGhlIGRheSBudW1iZXJzIHdpbGwgYmUgaW4gZWFjaCBjZWxsXG4gICAgaWYgKCFkYXRlc1JlcERpc3RpbmN0RGF5cyB8fCBkYXlDbnQgPiAxMCkge1xuICAgICAgICByZXR1cm4gY3JlYXRlRm9ybWF0dGVyKHsgd2Vla2RheTogJ3Nob3J0JyB9KTsgLy8gXCJTYXRcIlxuICAgIH1cbiAgICBpZiAoZGF5Q250ID4gMSkge1xuICAgICAgICByZXR1cm4gY3JlYXRlRm9ybWF0dGVyKHsgd2Vla2RheTogJ3Nob3J0JywgbW9udGg6ICdudW1lcmljJywgZGF5OiAnbnVtZXJpYycsIG9taXRDb21tYXM6IHRydWUgfSk7IC8vIFwiU2F0IDExLzEyXCJcbiAgICB9XG4gICAgcmV0dXJuIGNyZWF0ZUZvcm1hdHRlcih7IHdlZWtkYXk6ICdsb25nJyB9KTsgLy8gXCJTYXR1cmRheVwiXG59XG5cbmNvbnN0IENMQVNTX05BTUUgPSAnZmMtY29sLWhlYWRlci1jZWxsJzsgLy8gZG8gdGhlIGN1c2hpb24gdG9vPyBub1xuZnVuY3Rpb24gcmVuZGVySW5uZXIkMShyZW5kZXJQcm9wcykge1xuICAgIHJldHVybiByZW5kZXJQcm9wcy50ZXh0O1xufVxuXG5jbGFzcyBDb250ZW50SW5qZWN0b3IgZXh0ZW5kcyBCYXNlQ29tcG9uZW50IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5pZCA9IGd1aWQoKTtcbiAgICAgICAgdGhpcy5jdXJyZW50RG9tTm9kZXMgPSBbXTtcbiAgICAgICAgdGhpcy5xdWV1ZWREb21Ob2RlcyA9IFtdO1xuICAgICAgICB0aGlzLmhhbmRsZUVsID0gKGVsKSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5wcm9wcy5lbFJlZikge1xuICAgICAgICAgICAgICAgIHNldFJlZih0aGlzLnByb3BzLmVsUmVmLCBlbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgfVxuICAgIHJlbmRlcigpIHtcbiAgICAgICAgY29uc3QgeyBwcm9wcywgY29udGV4dCB9ID0gdGhpcztcbiAgICAgICAgY29uc3QgeyBvcHRpb25zIH0gPSBjb250ZXh0O1xuICAgICAgICBjb25zdCB7IGdlbmVyYXRvciwgcmVuZGVyUHJvcHMgfSA9IHByb3BzO1xuICAgICAgICBjb25zdCBhdHRycyA9IGJ1aWxkRWxBdHRycyhwcm9wcyk7XG4gICAgICAgIGxldCBpbm5lckNvbnRlbnQ7XG4gICAgICAgIGxldCBxdWV1ZWREb21Ob2RlcyA9IFtdO1xuICAgICAgICBpZiAoaGFzQ3VzdG9tUmVuZGVyaW5nSGFuZGxlcihwcm9wcy5nZW5lcmF0b3JOYW1lLCBvcHRpb25zKSkge1xuICAgICAgICAgICAgaWYgKG9wdGlvbnMuY3VzdG9tUmVuZGVyaW5nUmVwbGFjZXNFbCkge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSBhdHRycy5lbFJlZjsgLy8gYmVjYXVzZSBoYW5kbGVFbCB3aWxsIGJlIHVzZWRcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGN1c3RvbUNvbnRlbnQgPSB0eXBlb2YgZ2VuZXJhdG9yID09PSAnZnVuY3Rpb24nID9cbiAgICAgICAgICAgICAgICBnZW5lcmF0b3IocmVuZGVyUHJvcHMsIGNyZWF0ZUVsZW1lbnQpIDpcbiAgICAgICAgICAgICAgICBnZW5lcmF0b3I7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGN1c3RvbUNvbnRlbnQgPT09ICdzdHJpbmcnIHx8XG4gICAgICAgICAgICAgICAgaXNWYWxpZEVsZW1lbnQoY3VzdG9tQ29udGVudCkgfHxcbiAgICAgICAgICAgICAgICBBcnJheS5pc0FycmF5KGN1c3RvbUNvbnRlbnQpKSB7XG4gICAgICAgICAgICAgICAgaW5uZXJDb250ZW50ID0gY3VzdG9tQ29udGVudDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiBjdXN0b21Db250ZW50ID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgICAgIGlmICgnaHRtbCcgaW4gY3VzdG9tQ29udGVudCkge1xuICAgICAgICAgICAgICAgICAgICBhdHRycy5kYW5nZXJvdXNseVNldElubmVySFRNTCA9IHsgX19odG1sOiBjdXN0b21Db250ZW50Lmh0bWwgfTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoJ2RvbU5vZGVzJyBpbiBjdXN0b21Db250ZW50KSB7XG4gICAgICAgICAgICAgICAgICAgIHF1ZXVlZERvbU5vZGVzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoY3VzdG9tQ29udGVudC5kb21Ob2Rlcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHRoaXMucXVldWVkRG9tTm9kZXMgPSBxdWV1ZWREb21Ob2RlcztcbiAgICAgICAgcmV0dXJuIGNyZWF0ZUVsZW1lbnQocHJvcHMuZWxUYWcsIGF0dHJzLCBpbm5lckNvbnRlbnQpO1xuICAgIH1cbiAgICBjb21wb25lbnREaWRNb3VudCgpIHtcbiAgICAgICAgdGhpcy5hcHBseVF1ZXVldWREb21Ob2RlcygpO1xuICAgICAgICB0aGlzLnRyaWdnZXJDdXN0b21SZW5kZXJpbmcodHJ1ZSk7XG4gICAgfVxuICAgIGNvbXBvbmVudERpZFVwZGF0ZSgpIHtcbiAgICAgICAgdGhpcy5hcHBseVF1ZXVldWREb21Ob2RlcygpO1xuICAgICAgICB0aGlzLnRyaWdnZXJDdXN0b21SZW5kZXJpbmcodHJ1ZSk7XG4gICAgfVxuICAgIGNvbXBvbmVudFdpbGxVbm1vdW50KCkge1xuICAgICAgICB0aGlzLnRyaWdnZXJDdXN0b21SZW5kZXJpbmcoZmFsc2UpOyAvLyBUT0RPOiBkaWZmZXJlbnQgQVBJIGZvciByZW1vdmFsP1xuICAgIH1cbiAgICB0cmlnZ2VyQ3VzdG9tUmVuZGVyaW5nKGlzQWN0aXZlKSB7XG4gICAgICAgIGNvbnN0IHsgcHJvcHMsIGNvbnRleHQgfSA9IHRoaXM7XG4gICAgICAgIGNvbnN0IHsgaGFuZGxlQ3VzdG9tUmVuZGVyaW5nLCBjdXN0b21SZW5kZXJpbmdNZXRhTWFwIH0gPSBjb250ZXh0Lm9wdGlvbnM7XG4gICAgICAgIGlmIChoYW5kbGVDdXN0b21SZW5kZXJpbmcpIHtcbiAgICAgICAgICAgIGNvbnN0IGN1c3RvbVJlbmRlcmluZ01ldGEgPSBjdXN0b21SZW5kZXJpbmdNZXRhTWFwID09PSBudWxsIHx8IGN1c3RvbVJlbmRlcmluZ01ldGFNYXAgPT09IHZvaWQgMCA/IHZvaWQgMCA6IGN1c3RvbVJlbmRlcmluZ01ldGFNYXBbcHJvcHMuZ2VuZXJhdG9yTmFtZV07XG4gICAgICAgICAgICBpZiAoY3VzdG9tUmVuZGVyaW5nTWV0YSkge1xuICAgICAgICAgICAgICAgIGhhbmRsZUN1c3RvbVJlbmRlcmluZyhPYmplY3QuYXNzaWduKHsgaWQ6IHRoaXMuaWQsIGlzQWN0aXZlLCBjb250YWluZXJFbDogdGhpcy5iYXNlLCByZXBvcnROZXdDb250YWluZXJFbDogdGhpcy5oYW5kbGVFbCwgZ2VuZXJhdG9yTWV0YTogY3VzdG9tUmVuZGVyaW5nTWV0YSB9LCBwcm9wcykpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIGFwcGx5UXVldWV1ZERvbU5vZGVzKCkge1xuICAgICAgICBjb25zdCB7IHF1ZXVlZERvbU5vZGVzLCBjdXJyZW50RG9tTm9kZXMgfSA9IHRoaXM7XG4gICAgICAgIGNvbnN0IGVsID0gdGhpcy5iYXNlO1xuICAgICAgICBpZiAoIWlzQXJyYXlzRXF1YWwocXVldWVkRG9tTm9kZXMsIGN1cnJlbnREb21Ob2RlcykpIHtcbiAgICAgICAgICAgIGN1cnJlbnREb21Ob2Rlcy5mb3JFYWNoKHJlbW92ZUVsZW1lbnQpO1xuICAgICAgICAgICAgZm9yIChsZXQgbmV3Tm9kZSBvZiBxdWV1ZWREb21Ob2Rlcykge1xuICAgICAgICAgICAgICAgIGVsLmFwcGVuZENoaWxkKG5ld05vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5jdXJyZW50RG9tTm9kZXMgPSBxdWV1ZWREb21Ob2RlcztcbiAgICAgICAgfVxuICAgIH1cbn1cbkNvbnRlbnRJbmplY3Rvci5hZGRQcm9wc0VxdWFsaXR5KHtcbiAgICBlbENsYXNzZXM6IGlzQXJyYXlzRXF1YWwsXG4gICAgZWxTdHlsZTogaXNQcm9wc0VxdWFsLFxuICAgIGVsQXR0cnM6IGlzTm9uSGFuZGxlclByb3BzRXF1YWwsXG4gICAgcmVuZGVyUHJvcHM6IGlzUHJvcHNFcXVhbCxcbn0pO1xuLy8gVXRpbFxuZnVuY3Rpb24gaGFzQ3VzdG9tUmVuZGVyaW5nSGFuZGxlcihnZW5lcmF0b3JOYW1lLCBvcHRpb25zKSB7XG4gICAgdmFyIF9hO1xuICAgIHJldHVybiBCb29sZWFuKG9wdGlvbnMuaGFuZGxlQ3VzdG9tUmVuZGVyaW5nICYmXG4gICAgICAgIGdlbmVyYXRvck5hbWUgJiZcbiAgICAgICAgKChfYSA9IG9wdGlvbnMuY3VzdG9tUmVuZGVyaW5nTWV0YU1hcCkgPT09IG51bGwgfHwgX2EgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9hW2dlbmVyYXRvck5hbWVdKSk7XG59XG5mdW5jdGlvbiBidWlsZEVsQXR0cnMocHJvcHMsIGV4dHJhQ2xhc3NOYW1lcykge1xuICAgIGNvbnN0IGF0dHJzID0gT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCBwcm9wcy5lbEF0dHJzKSwgeyByZWY6IHByb3BzLmVsUmVmIH0pO1xuICAgIGlmIChwcm9wcy5lbENsYXNzZXMgfHwgZXh0cmFDbGFzc05hbWVzKSB7XG4gICAgICAgIGF0dHJzLmNsYXNzTmFtZSA9IChwcm9wcy5lbENsYXNzZXMgfHwgW10pXG4gICAgICAgICAgICAuY29uY2F0KGV4dHJhQ2xhc3NOYW1lcyB8fCBbXSlcbiAgICAgICAgICAgIC5jb25jYXQoYXR0cnMuY2xhc3NOYW1lIHx8IFtdKVxuICAgICAgICAgICAgLmZpbHRlcihCb29sZWFuKVxuICAgICAgICAgICAgLmpvaW4oJyAnKTtcbiAgICB9XG4gICAgaWYgKHByb3BzLmVsU3R5bGUpIHtcbiAgICAgICAgYXR0cnMuc3R5bGUgPSBwcm9wcy5lbFN0eWxlO1xuICAgIH1cbiAgICByZXR1cm4gYXR0cnM7XG59XG5cbmNvbnN0IFJlbmRlcklkID0gY3JlYXRlQ29udGV4dCgwKTtcblxuY2xhc3MgQ29udGVudENvbnRhaW5lciBleHRlbmRzIENvbXBvbmVudCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMuSW5uZXJDb250ZW50ID0gSW5uZXJDb250ZW50SW5qZWN0b3IuYmluZCh1bmRlZmluZWQsIHRoaXMpO1xuICAgIH1cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGNvbnN0IHsgcHJvcHMgfSA9IHRoaXM7XG4gICAgICAgIGNvbnN0IGdlbmVyYXRlZENsYXNzTmFtZXMgPSBnZW5lcmF0ZUNsYXNzTmFtZXMocHJvcHMuY2xhc3NOYW1lR2VuZXJhdG9yLCBwcm9wcy5yZW5kZXJQcm9wcyk7XG4gICAgICAgIGlmIChwcm9wcy5jaGlsZHJlbikge1xuICAgICAgICAgICAgY29uc3QgZWxBdHRycyA9IGJ1aWxkRWxBdHRycyhwcm9wcywgZ2VuZXJhdGVkQ2xhc3NOYW1lcyk7XG4gICAgICAgICAgICBjb25zdCBjaGlsZHJlbiA9IHByb3BzLmNoaWxkcmVuKHRoaXMuSW5uZXJDb250ZW50LCBwcm9wcy5yZW5kZXJQcm9wcywgZWxBdHRycyk7XG4gICAgICAgICAgICBpZiAocHJvcHMuZWxUYWcpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gY3JlYXRlRWxlbWVudChwcm9wcy5lbFRhZywgZWxBdHRycywgY2hpbGRyZW4pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNoaWxkcmVuO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGNyZWF0ZUVsZW1lbnQoKENvbnRlbnRJbmplY3RvciksIE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgcHJvcHMpLCB7IGVsVGFnOiBwcm9wcy5lbFRhZyB8fCAnZGl2JywgZWxDbGFzc2VzOiAocHJvcHMuZWxDbGFzc2VzIHx8IFtdKS5jb25jYXQoZ2VuZXJhdGVkQ2xhc3NOYW1lcyksIHJlbmRlcklkOiB0aGlzLmNvbnRleHQgfSkpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGNvbXBvbmVudERpZE1vdW50KCkge1xuICAgICAgICB2YXIgX2EsIF9iO1xuICAgICAgICAoX2IgPSAoX2EgPSB0aGlzLnByb3BzKS5kaWRNb3VudCkgPT09IG51bGwgfHwgX2IgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9iLmNhbGwoX2EsIE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgdGhpcy5wcm9wcy5yZW5kZXJQcm9wcyksIHsgZWw6IHRoaXMuYmFzZSB9KSk7XG4gICAgfVxuICAgIGNvbXBvbmVudFdpbGxVbm1vdW50KCkge1xuICAgICAgICB2YXIgX2EsIF9iO1xuICAgICAgICAoX2IgPSAoX2EgPSB0aGlzLnByb3BzKS53aWxsVW5tb3VudCkgPT09IG51bGwgfHwgX2IgPT09IHZvaWQgMCA/IHZvaWQgMCA6IF9iLmNhbGwoX2EsIE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgdGhpcy5wcm9wcy5yZW5kZXJQcm9wcyksIHsgZWw6IHRoaXMuYmFzZSB9KSk7XG4gICAgfVxufVxuQ29udGVudENvbnRhaW5lci5jb250ZXh0VHlwZSA9IFJlbmRlcklkO1xuZnVuY3Rpb24gSW5uZXJDb250ZW50SW5qZWN0b3IoY29udGFpbmVyQ29tcG9uZW50LCBwcm9wcykge1xuICAgIGNvbnN0IHBhcmVudFByb3BzID0gY29udGFpbmVyQ29tcG9uZW50LnByb3BzO1xuICAgIHJldHVybiBjcmVhdGVFbGVtZW50KChDb250ZW50SW5qZWN0b3IpLCBPYmplY3QuYXNzaWduKHsgcmVuZGVyUHJvcHM6IHBhcmVudFByb3BzLnJlbmRlclByb3BzLCBnZW5lcmF0b3JOYW1lOiBwYXJlbnRQcm9wcy5nZW5lcmF0b3JOYW1lLCBnZW5lcmF0b3I6IHBhcmVudFByb3BzLmdlbmVyYXRvciwgcmVuZGVySWQ6IGNvbnRhaW5lckNvbXBvbmVudC5jb250ZXh0IH0sIHByb3BzKSk7XG59XG4vLyBVdGlsc1xuZnVuY3Rpb24gZ2VuZXJhdGVDbGFzc05hbWVzKGNsYXNzTmFtZUdlbmVyYXRvciwgcmVuZGVyUHJvcHMpIHtcbiAgICBjb25zdCBjbGFzc05hbWVzID0gdHlwZW9mIGNsYXNzTmFtZUdlbmVyYXRvciA9PT0gJ2Z1bmN0aW9uJyA/XG4gICAgICAgIGNsYXNzTmFtZUdlbmVyYXRvcihyZW5kZXJQcm9wcykgOlxuICAgICAgICBjbGFzc05hbWVHZW5lcmF0b3IgfHwgW107XG4gICAgcmV0dXJuIHR5cGVvZiBjbGFzc05hbWVzID09PSAnc3RyaW5nJyA/IFtjbGFzc05hbWVzXSA6IGNsYXNzTmFtZXM7XG59XG5cbi8vIEJBRCBuYW1lIGZvciB0aGlzIGNsYXNzIG5vdy4gdXNlZCBpbiB0aGUgSGVhZGVyXG5jbGFzcyBUYWJsZURhdGVDZWxsIGV4dGVuZHMgQmFzZUNvbXBvbmVudCB7XG4gICAgcmVuZGVyKCkge1xuICAgICAgICBsZXQgeyBkYXRlRW52LCBvcHRpb25zLCB0aGVtZSwgdmlld0FwaSB9ID0gdGhpcy5jb250ZXh0O1xuICAgICAgICBsZXQgeyBwcm9wcyB9ID0gdGhpcztcbiAgICAgICAgbGV0IHsgZGF0ZSwgZGF0ZVByb2ZpbGUgfSA9IHByb3BzO1xuICAgICAgICBsZXQgZGF5TWV0YSA9IGdldERhdGVNZXRhKGRhdGUsIHByb3BzLnRvZGF5UmFuZ2UsIG51bGwsIGRhdGVQcm9maWxlKTtcbiAgICAgICAgbGV0IGNsYXNzTmFtZXMgPSBbQ0xBU1NfTkFNRV0uY29uY2F0KGdldERheUNsYXNzTmFtZXMoZGF5TWV0YSwgdGhlbWUpKTtcbiAgICAgICAgbGV0IHRleHQgPSBkYXRlRW52LmZvcm1hdChkYXRlLCBwcm9wcy5kYXlIZWFkZXJGb3JtYXQpO1xuICAgICAgICAvLyBpZiBjb2xDbnQgaXMgMSwgd2UgYXJlIGFscmVhZHkgaW4gYSBkYXktdmlldyBhbmQgZG9uJ3QgbmVlZCBhIG5hdmxpbmtcbiAgICAgICAgbGV0IG5hdkxpbmtBdHRycyA9ICghZGF5TWV0YS5pc0Rpc2FibGVkICYmIHByb3BzLmNvbENudCA+IDEpXG4gICAgICAgICAgICA/IGJ1aWxkTmF2TGlua0F0dHJzKHRoaXMuY29udGV4dCwgZGF0ZSlcbiAgICAgICAgICAgIDoge307XG4gICAgICAgIGxldCByZW5kZXJQcm9wcyA9IE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHsgZGF0ZTogZGF0ZUVudi50b0RhdGUoZGF0ZSksIHZpZXc6IHZpZXdBcGkgfSwgcHJvcHMuZXh0cmFSZW5kZXJQcm9wcyksIHsgdGV4dCB9KSwgZGF5TWV0YSk7XG4gICAgICAgIHJldHVybiAoY3JlYXRlRWxlbWVudChDb250ZW50Q29udGFpbmVyLCB7IGVsVGFnOiBcInRoXCIsIGVsQ2xhc3NlczogY2xhc3NOYW1lcywgZWxBdHRyczogT2JqZWN0LmFzc2lnbih7IHJvbGU6ICdjb2x1bW5oZWFkZXInLCBjb2xTcGFuOiBwcm9wcy5jb2xTcGFuLCAnZGF0YS1kYXRlJzogIWRheU1ldGEuaXNEaXNhYmxlZCA/IGZvcm1hdERheVN0cmluZyhkYXRlKSA6IHVuZGVmaW5lZCB9LCBwcm9wcy5leHRyYURhdGFBdHRycyksIHJlbmRlclByb3BzOiByZW5kZXJQcm9wcywgZ2VuZXJhdG9yTmFtZTogXCJkYXlIZWFkZXJDb250ZW50XCIsIGdlbmVyYXRvcjogb3B0aW9ucy5kYXlIZWFkZXJDb250ZW50IHx8IHJlbmRlcklubmVyJDEsIGNsYXNzTmFtZUdlbmVyYXRvcjogb3B0aW9ucy5kYXlIZWFkZXJDbGFzc05hbWVzLCBkaWRNb3VudDogb3B0aW9ucy5kYXlIZWFkZXJEaWRNb3VudCwgd2lsbFVubW91bnQ6IG9wdGlvbnMuZGF5SGVhZGVyV2lsbFVubW91bnQgfSwgKElubmVyQ29udGFpbmVyKSA9PiAoY3JlYXRlRWxlbWVudChcImRpdlwiLCB7IGNsYXNzTmFtZTogXCJmYy1zY3JvbGxncmlkLXN5bmMtaW5uZXJcIiB9LCAhZGF5TWV0YS5pc0Rpc2FibGVkICYmIChjcmVhdGVFbGVtZW50KElubmVyQ29udGFpbmVyLCB7IGVsVGFnOiBcImFcIiwgZWxBdHRyczogbmF2TGlua0F0dHJzLCBlbENsYXNzZXM6IFtcbiAgICAgICAgICAgICAgICAnZmMtY29sLWhlYWRlci1jZWxsLWN1c2hpb24nLFxuICAgICAgICAgICAgICAgIHByb3BzLmlzU3RpY2t5ICYmICdmYy1zdGlja3knLFxuICAgICAgICAgICAgXSB9KSkpKSkpO1xuICAgIH1cbn1cblxuY29uc3QgV0VFS0RBWV9GT1JNQVQgPSBjcmVhdGVGb3JtYXR0ZXIoeyB3ZWVrZGF5OiAnbG9uZycgfSk7XG5jbGFzcyBUYWJsZURvd0NlbGwgZXh0ZW5kcyBCYXNlQ29tcG9uZW50IHtcbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGxldCB7IHByb3BzIH0gPSB0aGlzO1xuICAgICAgICBsZXQgeyBkYXRlRW52LCB0aGVtZSwgdmlld0FwaSwgb3B0aW9ucyB9ID0gdGhpcy5jb250ZXh0O1xuICAgICAgICBsZXQgZGF0ZSA9IGFkZERheXMobmV3IERhdGUoMjU5MjAwMDAwKSwgcHJvcHMuZG93KTsgLy8gc3RhcnQgd2l0aCBTdW4sIDA0IEphbiAxOTcwIDAwOjAwOjAwIEdNVFxuICAgICAgICBsZXQgZGF0ZU1ldGEgPSB7XG4gICAgICAgICAgICBkb3c6IHByb3BzLmRvdyxcbiAgICAgICAgICAgIGlzRGlzYWJsZWQ6IGZhbHNlLFxuICAgICAgICAgICAgaXNGdXR1cmU6IGZhbHNlLFxuICAgICAgICAgICAgaXNQYXN0OiBmYWxzZSxcbiAgICAgICAgICAgIGlzVG9kYXk6IGZhbHNlLFxuICAgICAgICAgICAgaXNPdGhlcjogZmFsc2UsXG4gICAgICAgIH07XG4gICAgICAgIGxldCB0ZXh0ID0gZGF0ZUVudi5mb3JtYXQoZGF0ZSwgcHJvcHMuZGF5SGVhZGVyRm9ybWF0KTtcbiAgICAgICAgbGV0IHJlbmRlclByb3BzID0gT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7IC8vIFRPRE86IG1ha2UgdGhpcyBwdWJsaWM/XG4gICAgICAgICAgICBkYXRlIH0sIGRhdGVNZXRhKSwgeyB2aWV3OiB2aWV3QXBpIH0pLCBwcm9wcy5leHRyYVJlbmRlclByb3BzKSwgeyB0ZXh0IH0pO1xuICAgICAgICByZXR1cm4gKGNyZWF0ZUVsZW1lbnQoQ29udGVudENvbnRhaW5lciwgeyBlbFRhZzogXCJ0aFwiLCBlbENsYXNzZXM6IFtcbiAgICAgICAgICAgICAgICBDTEFTU19OQU1FLFxuICAgICAgICAgICAgICAgIC4uLmdldERheUNsYXNzTmFtZXMoZGF0ZU1ldGEsIHRoZW1lKSxcbiAgICAgICAgICAgICAgICAuLi4ocHJvcHMuZXh0cmFDbGFzc05hbWVzIHx8IFtdKSxcbiAgICAgICAgICAgIF0sIGVsQXR0cnM6IE9iamVjdC5hc3NpZ24oeyByb2xlOiAnY29sdW1uaGVhZGVyJywgY29sU3BhbjogcHJvcHMuY29sU3BhbiB9LCBwcm9wcy5leHRyYURhdGFBdHRycyksIHJlbmRlclByb3BzOiByZW5kZXJQcm9wcywgZ2VuZXJhdG9yTmFtZTogXCJkYXlIZWFkZXJDb250ZW50XCIsIGdlbmVyYXRvcjogb3B0aW9ucy5kYXlIZWFkZXJDb250ZW50IHx8IHJlbmRlcklubmVyJDEsIGNsYXNzTmFtZUdlbmVyYXRvcjogb3B0aW9ucy5kYXlIZWFkZXJDbGFzc05hbWVzLCBkaWRNb3VudDogb3B0aW9ucy5kYXlIZWFkZXJEaWRNb3VudCwgd2lsbFVubW91bnQ6IG9wdGlvbnMuZGF5SGVhZGVyV2lsbFVubW91bnQgfSwgKElubmVyQ29udGVudCkgPT4gKGNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwgeyBjbGFzc05hbWU6IFwiZmMtc2Nyb2xsZ3JpZC1zeW5jLWlubmVyXCIgfSxcbiAgICAgICAgICAgIGNyZWF0ZUVsZW1lbnQoSW5uZXJDb250ZW50LCB7IGVsVGFnOiBcImFcIiwgZWxDbGFzc2VzOiBbXG4gICAgICAgICAgICAgICAgICAgICdmYy1jb2wtaGVhZGVyLWNlbGwtY3VzaGlvbicsXG4gICAgICAgICAgICAgICAgICAgIHByb3BzLmlzU3RpY2t5ICYmICdmYy1zdGlja3knLFxuICAgICAgICAgICAgICAgIF0sIGVsQXR0cnM6IHtcbiAgICAgICAgICAgICAgICAgICAgJ2FyaWEtbGFiZWwnOiBkYXRlRW52LmZvcm1hdChkYXRlLCBXRUVLREFZX0ZPUk1BVCksXG4gICAgICAgICAgICAgICAgfSB9KSkpKSk7XG4gICAgfVxufVxuXG5jbGFzcyBOb3dUaW1lciBleHRlbmRzIENvbXBvbmVudCB7XG4gICAgY29uc3RydWN0b3IocHJvcHMsIGNvbnRleHQpIHtcbiAgICAgICAgc3VwZXIocHJvcHMsIGNvbnRleHQpO1xuICAgICAgICB0aGlzLmluaXRpYWxOb3dEYXRlID0gZ2V0Tm93KGNvbnRleHQub3B0aW9ucy5ub3csIGNvbnRleHQuZGF0ZUVudik7XG4gICAgICAgIHRoaXMuaW5pdGlhbE5vd1F1ZXJpZWRNcyA9IG5ldyBEYXRlKCkudmFsdWVPZigpO1xuICAgICAgICB0aGlzLnN0YXRlID0gdGhpcy5jb21wdXRlVGltaW5nKCkuY3VycmVudFN0YXRlO1xuICAgIH1cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGxldCB7IHByb3BzLCBzdGF0ZSB9ID0gdGhpcztcbiAgICAgICAgcmV0dXJuIHByb3BzLmNoaWxkcmVuKHN0YXRlLm5vd0RhdGUsIHN0YXRlLnRvZGF5UmFuZ2UpO1xuICAgIH1cbiAgICBjb21wb25lbnREaWRNb3VudCgpIHtcbiAgICAgICAgdGhpcy5zZXRUaW1lb3V0KCk7XG4gICAgfVxuICAgIGNvbXBvbmVudERpZFVwZGF0ZShwcmV2UHJvcHMpIHtcbiAgICAgICAgaWYgKHByZXZQcm9wcy51bml0ICE9PSB0aGlzLnByb3BzLnVuaXQpIHtcbiAgICAgICAgICAgIHRoaXMuY2xlYXJUaW1lb3V0KCk7XG4gICAgICAgICAgICB0aGlzLnNldFRpbWVvdXQoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBjb21wb25lbnRXaWxsVW5tb3VudCgpIHtcbiAgICAgICAgdGhpcy5jbGVhclRpbWVvdXQoKTtcbiAgICB9XG4gICAgY29tcHV0ZVRpbWluZygpIHtcbiAgICAgICAgbGV0IHsgcHJvcHMsIGNvbnRleHQgfSA9IHRoaXM7XG4gICAgICAgIGxldCB1bnJvdW5kZWROb3cgPSBhZGRNcyh0aGlzLmluaXRpYWxOb3dEYXRlLCBuZXcgRGF0ZSgpLnZhbHVlT2YoKSAtIHRoaXMuaW5pdGlhbE5vd1F1ZXJpZWRNcyk7XG4gICAgICAgIGxldCBjdXJyZW50VW5pdFN0YXJ0ID0gY29udGV4dC5kYXRlRW52LnN0YXJ0T2YodW5yb3VuZGVkTm93LCBwcm9wcy51bml0KTtcbiAgICAgICAgbGV0IG5leHRVbml0U3RhcnQgPSBjb250ZXh0LmRhdGVFbnYuYWRkKGN1cnJlbnRVbml0U3RhcnQsIGNyZWF0ZUR1cmF0aW9uKDEsIHByb3BzLnVuaXQpKTtcbiAgICAgICAgbGV0IHdhaXRNcyA9IG5leHRVbml0U3RhcnQudmFsdWVPZigpIC0gdW5yb3VuZGVkTm93LnZhbHVlT2YoKTtcbiAgICAgICAgLy8gdGhlcmUgaXMgYSBtYXggc2V0VGltZW91dCBtcyB2YWx1ZSAoaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9hLzM0Njg2NTAvOTYzNDIpXG4gICAgICAgIC8vIGVuc3VyZSBubyBsb25nZXIgdGhhbiBhIGRheVxuICAgICAgICB3YWl0TXMgPSBNYXRoLm1pbigxMDAwICogNjAgKiA2MCAqIDI0LCB3YWl0TXMpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgY3VycmVudFN0YXRlOiB7IG5vd0RhdGU6IGN1cnJlbnRVbml0U3RhcnQsIHRvZGF5UmFuZ2U6IGJ1aWxkRGF5UmFuZ2UoY3VycmVudFVuaXRTdGFydCkgfSxcbiAgICAgICAgICAgIG5leHRTdGF0ZTogeyBub3dEYXRlOiBuZXh0VW5pdFN0YXJ0LCB0b2RheVJhbmdlOiBidWlsZERheVJhbmdlKG5leHRVbml0U3RhcnQpIH0sXG4gICAgICAgICAgICB3YWl0TXMsXG4gICAgICAgIH07XG4gICAgfVxuICAgIHNldFRpbWVvdXQoKSB7XG4gICAgICAgIGxldCB7IG5leHRTdGF0ZSwgd2FpdE1zIH0gPSB0aGlzLmNvbXB1dGVUaW1pbmcoKTtcbiAgICAgICAgdGhpcy50aW1lb3V0SWQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUobmV4dFN0YXRlLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRUaW1lb3V0KCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSwgd2FpdE1zKTtcbiAgICB9XG4gICAgY2xlYXJUaW1lb3V0KCkge1xuICAgICAgICBpZiAodGhpcy50aW1lb3V0SWQpIHtcbiAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aGlzLnRpbWVvdXRJZCk7XG4gICAgICAgIH1cbiAgICB9XG59XG5Ob3dUaW1lci5jb250ZXh0VHlwZSA9IFZpZXdDb250ZXh0VHlwZTtcbmZ1bmN0aW9uIGJ1aWxkRGF5UmFuZ2UoZGF0ZSkge1xuICAgIGxldCBzdGFydCA9IHN0YXJ0T2ZEYXkoZGF0ZSk7XG4gICAgbGV0IGVuZCA9IGFkZERheXMoc3RhcnQsIDEpO1xuICAgIHJldHVybiB7IHN0YXJ0LCBlbmQgfTtcbn1cblxuY2xhc3MgRGF5SGVhZGVyIGV4dGVuZHMgQmFzZUNvbXBvbmVudCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMuY3JlYXRlRGF5SGVhZGVyRm9ybWF0dGVyID0gbWVtb2l6ZShjcmVhdGVEYXlIZWFkZXJGb3JtYXR0ZXIpO1xuICAgIH1cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGxldCB7IGNvbnRleHQgfSA9IHRoaXM7XG4gICAgICAgIGxldCB7IGRhdGVzLCBkYXRlUHJvZmlsZSwgZGF0ZXNSZXBEaXN0aW5jdERheXMsIHJlbmRlckludHJvIH0gPSB0aGlzLnByb3BzO1xuICAgICAgICBsZXQgZGF5SGVhZGVyRm9ybWF0ID0gdGhpcy5jcmVhdGVEYXlIZWFkZXJGb3JtYXR0ZXIoY29udGV4dC5vcHRpb25zLmRheUhlYWRlckZvcm1hdCwgZGF0ZXNSZXBEaXN0aW5jdERheXMsIGRhdGVzLmxlbmd0aCk7XG4gICAgICAgIHJldHVybiAoY3JlYXRlRWxlbWVudChOb3dUaW1lciwgeyB1bml0OiBcImRheVwiIH0sIChub3dEYXRlLCB0b2RheVJhbmdlKSA9PiAoY3JlYXRlRWxlbWVudChcInRyXCIsIHsgcm9sZTogXCJyb3dcIiB9LFxuICAgICAgICAgICAgcmVuZGVySW50cm8gJiYgcmVuZGVySW50cm8oJ2RheScpLFxuICAgICAgICAgICAgZGF0ZXMubWFwKChkYXRlKSA9PiAoZGF0ZXNSZXBEaXN0aW5jdERheXMgPyAoY3JlYXRlRWxlbWVudChUYWJsZURhdGVDZWxsLCB7IGtleTogZGF0ZS50b0lTT1N0cmluZygpLCBkYXRlOiBkYXRlLCBkYXRlUHJvZmlsZTogZGF0ZVByb2ZpbGUsIHRvZGF5UmFuZ2U6IHRvZGF5UmFuZ2UsIGNvbENudDogZGF0ZXMubGVuZ3RoLCBkYXlIZWFkZXJGb3JtYXQ6IGRheUhlYWRlckZvcm1hdCB9KSkgOiAoY3JlYXRlRWxlbWVudChUYWJsZURvd0NlbGwsIHsga2V5OiBkYXRlLmdldFVUQ0RheSgpLCBkb3c6IGRhdGUuZ2V0VVRDRGF5KCksIGRheUhlYWRlckZvcm1hdDogZGF5SGVhZGVyRm9ybWF0IH0pKSkpKSkpKTtcbiAgICB9XG59XG5mdW5jdGlvbiBjcmVhdGVEYXlIZWFkZXJGb3JtYXR0ZXIoZXhwbGljaXRGb3JtYXQsIGRhdGVzUmVwRGlzdGluY3REYXlzLCBkYXRlQ250KSB7XG4gICAgcmV0dXJuIGV4cGxpY2l0Rm9ybWF0IHx8IGNvbXB1dGVGYWxsYmFja0hlYWRlckZvcm1hdChkYXRlc1JlcERpc3RpbmN0RGF5cywgZGF0ZUNudCk7XG59XG5cbmNsYXNzIERheVNlcmllc01vZGVsIHtcbiAgICBjb25zdHJ1Y3RvcihyYW5nZSwgZGF0ZVByb2ZpbGVHZW5lcmF0b3IpIHtcbiAgICAgICAgbGV0IGRhdGUgPSByYW5nZS5zdGFydDtcbiAgICAgICAgbGV0IHsgZW5kIH0gPSByYW5nZTtcbiAgICAgICAgbGV0IGluZGljZXMgPSBbXTtcbiAgICAgICAgbGV0IGRhdGVzID0gW107XG4gICAgICAgIGxldCBkYXlJbmRleCA9IC0xO1xuICAgICAgICB3aGlsZSAoZGF0ZSA8IGVuZCkgeyAvLyBsb29wIGVhY2ggZGF5IGZyb20gc3RhcnQgdG8gZW5kXG4gICAgICAgICAgICBpZiAoZGF0ZVByb2ZpbGVHZW5lcmF0b3IuaXNIaWRkZW5EYXkoZGF0ZSkpIHtcbiAgICAgICAgICAgICAgICBpbmRpY2VzLnB1c2goZGF5SW5kZXggKyAwLjUpOyAvLyBtYXJrIHRoYXQgaXQncyBiZXR3ZWVuIGluZGljZXNcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGRheUluZGV4ICs9IDE7XG4gICAgICAgICAgICAgICAgaW5kaWNlcy5wdXNoKGRheUluZGV4KTtcbiAgICAgICAgICAgICAgICBkYXRlcy5wdXNoKGRhdGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGF0ZSA9IGFkZERheXMoZGF0ZSwgMSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5kYXRlcyA9IGRhdGVzO1xuICAgICAgICB0aGlzLmluZGljZXMgPSBpbmRpY2VzO1xuICAgICAgICB0aGlzLmNudCA9IGRhdGVzLmxlbmd0aDtcbiAgICB9XG4gICAgc2xpY2VSYW5nZShyYW5nZSkge1xuICAgICAgICBsZXQgZmlyc3RJbmRleCA9IHRoaXMuZ2V0RGF0ZURheUluZGV4KHJhbmdlLnN0YXJ0KTsgLy8gaW5jbHVzaXZlIGZpcnN0IGluZGV4XG4gICAgICAgIGxldCBsYXN0SW5kZXggPSB0aGlzLmdldERhdGVEYXlJbmRleChhZGREYXlzKHJhbmdlLmVuZCwgLTEpKTsgLy8gaW5jbHVzaXZlIGxhc3QgaW5kZXhcbiAgICAgICAgbGV0IGNsaXBwZWRGaXJzdEluZGV4ID0gTWF0aC5tYXgoMCwgZmlyc3RJbmRleCk7XG4gICAgICAgIGxldCBjbGlwcGVkTGFzdEluZGV4ID0gTWF0aC5taW4odGhpcy5jbnQgLSAxLCBsYXN0SW5kZXgpO1xuICAgICAgICAvLyBkZWFsIHdpdGggaW4tYmV0d2VlbiBpbmRpY2VzXG4gICAgICAgIGNsaXBwZWRGaXJzdEluZGV4ID0gTWF0aC5jZWlsKGNsaXBwZWRGaXJzdEluZGV4KTsgLy8gaW4tYmV0d2VlbiBzdGFydHMgcm91bmQgdG8gbmV4dCBjZWxsXG4gICAgICAgIGNsaXBwZWRMYXN0SW5kZXggPSBNYXRoLmZsb29yKGNsaXBwZWRMYXN0SW5kZXgpOyAvLyBpbi1iZXR3ZWVuIGVuZHMgcm91bmQgdG8gcHJldiBjZWxsXG4gICAgICAgIGlmIChjbGlwcGVkRmlyc3RJbmRleCA8PSBjbGlwcGVkTGFzdEluZGV4KSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGZpcnN0SW5kZXg6IGNsaXBwZWRGaXJzdEluZGV4LFxuICAgICAgICAgICAgICAgIGxhc3RJbmRleDogY2xpcHBlZExhc3RJbmRleCxcbiAgICAgICAgICAgICAgICBpc1N0YXJ0OiBmaXJzdEluZGV4ID09PSBjbGlwcGVkRmlyc3RJbmRleCxcbiAgICAgICAgICAgICAgICBpc0VuZDogbGFzdEluZGV4ID09PSBjbGlwcGVkTGFzdEluZGV4LFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgLy8gR2l2ZW4gYSBkYXRlLCByZXR1cm5zIGl0cyBjaHJvbm9sb2NpYWwgY2VsbC1pbmRleCBmcm9tIHRoZSBmaXJzdCBjZWxsIG9mIHRoZSBncmlkLlxuICAgIC8vIElmIHRoZSBkYXRlIGxpZXMgYmV0d2VlbiBjZWxscyAoYmVjYXVzZSBvZiBoaWRkZW5EYXlzKSwgcmV0dXJucyBhIGZsb2F0aW5nLXBvaW50IHZhbHVlIGJldHdlZW4gb2Zmc2V0cy5cbiAgICAvLyBJZiBiZWZvcmUgdGhlIGZpcnN0IG9mZnNldCwgcmV0dXJucyBhIG5lZ2F0aXZlIG51bWJlci5cbiAgICAvLyBJZiBhZnRlciB0aGUgbGFzdCBvZmZzZXQsIHJldHVybnMgYW4gb2Zmc2V0IHBhc3QgdGhlIGxhc3QgY2VsbCBvZmZzZXQuXG4gICAgLy8gT25seSB3b3JrcyBmb3IgKnN0YXJ0KiBkYXRlcyBvZiBjZWxscy4gV2lsbCBub3Qgd29yayBmb3IgZXhjbHVzaXZlIGVuZCBkYXRlcyBmb3IgY2VsbHMuXG4gICAgZ2V0RGF0ZURheUluZGV4KGRhdGUpIHtcbiAgICAgICAgbGV0IHsgaW5kaWNlcyB9ID0gdGhpcztcbiAgICAgICAgbGV0IGRheU9mZnNldCA9IE1hdGguZmxvb3IoZGlmZkRheXModGhpcy5kYXRlc1swXSwgZGF0ZSkpO1xuICAgICAgICBpZiAoZGF5T2Zmc2V0IDwgMCkge1xuICAgICAgICAgICAgcmV0dXJuIGluZGljZXNbMF0gLSAxO1xuICAgICAgICB9XG4gICAgICAgIGlmIChkYXlPZmZzZXQgPj0gaW5kaWNlcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHJldHVybiBpbmRpY2VzW2luZGljZXMubGVuZ3RoIC0gMV0gKyAxO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBpbmRpY2VzW2RheU9mZnNldF07XG4gICAgfVxufVxuXG5jbGFzcyBEYXlUYWJsZU1vZGVsIHtcbiAgICBjb25zdHJ1Y3RvcihkYXlTZXJpZXMsIGJyZWFrT25XZWVrcykge1xuICAgICAgICBsZXQgeyBkYXRlcyB9ID0gZGF5U2VyaWVzO1xuICAgICAgICBsZXQgZGF5c1BlclJvdztcbiAgICAgICAgbGV0IGZpcnN0RGF5O1xuICAgICAgICBsZXQgcm93Q250O1xuICAgICAgICBpZiAoYnJlYWtPbldlZWtzKSB7XG4gICAgICAgICAgICAvLyBjb3VudCBjb2x1bW5zIHVudGlsIHRoZSBkYXktb2Ytd2VlayByZXBlYXRzXG4gICAgICAgICAgICBmaXJzdERheSA9IGRhdGVzWzBdLmdldFVUQ0RheSgpO1xuICAgICAgICAgICAgZm9yIChkYXlzUGVyUm93ID0gMTsgZGF5c1BlclJvdyA8IGRhdGVzLmxlbmd0aDsgZGF5c1BlclJvdyArPSAxKSB7XG4gICAgICAgICAgICAgICAgaWYgKGRhdGVzW2RheXNQZXJSb3ddLmdldFVUQ0RheSgpID09PSBmaXJzdERheSkge1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByb3dDbnQgPSBNYXRoLmNlaWwoZGF0ZXMubGVuZ3RoIC8gZGF5c1BlclJvdyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByb3dDbnQgPSAxO1xuICAgICAgICAgICAgZGF5c1BlclJvdyA9IGRhdGVzLmxlbmd0aDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnJvd0NudCA9IHJvd0NudDtcbiAgICAgICAgdGhpcy5jb2xDbnQgPSBkYXlzUGVyUm93O1xuICAgICAgICB0aGlzLmRheVNlcmllcyA9IGRheVNlcmllcztcbiAgICAgICAgdGhpcy5jZWxscyA9IHRoaXMuYnVpbGRDZWxscygpO1xuICAgICAgICB0aGlzLmhlYWRlckRhdGVzID0gdGhpcy5idWlsZEhlYWRlckRhdGVzKCk7XG4gICAgfVxuICAgIGJ1aWxkQ2VsbHMoKSB7XG4gICAgICAgIGxldCByb3dzID0gW107XG4gICAgICAgIGZvciAobGV0IHJvdyA9IDA7IHJvdyA8IHRoaXMucm93Q250OyByb3cgKz0gMSkge1xuICAgICAgICAgICAgbGV0IGNlbGxzID0gW107XG4gICAgICAgICAgICBmb3IgKGxldCBjb2wgPSAwOyBjb2wgPCB0aGlzLmNvbENudDsgY29sICs9IDEpIHtcbiAgICAgICAgICAgICAgICBjZWxscy5wdXNoKHRoaXMuYnVpbGRDZWxsKHJvdywgY29sKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByb3dzLnB1c2goY2VsbHMpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByb3dzO1xuICAgIH1cbiAgICBidWlsZENlbGwocm93LCBjb2wpIHtcbiAgICAgICAgbGV0IGRhdGUgPSB0aGlzLmRheVNlcmllcy5kYXRlc1tyb3cgKiB0aGlzLmNvbENudCArIGNvbF07XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBrZXk6IGRhdGUudG9JU09TdHJpbmcoKSxcbiAgICAgICAgICAgIGRhdGUsXG4gICAgICAgIH07XG4gICAgfVxuICAgIGJ1aWxkSGVhZGVyRGF0ZXMoKSB7XG4gICAgICAgIGxldCBkYXRlcyA9IFtdO1xuICAgICAgICBmb3IgKGxldCBjb2wgPSAwOyBjb2wgPCB0aGlzLmNvbENudDsgY29sICs9IDEpIHtcbiAgICAgICAgICAgIGRhdGVzLnB1c2godGhpcy5jZWxsc1swXVtjb2xdLmRhdGUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBkYXRlcztcbiAgICB9XG4gICAgc2xpY2VSYW5nZShyYW5nZSkge1xuICAgICAgICBsZXQgeyBjb2xDbnQgfSA9IHRoaXM7XG4gICAgICAgIGxldCBzZXJpZXNTZWcgPSB0aGlzLmRheVNlcmllcy5zbGljZVJhbmdlKHJhbmdlKTtcbiAgICAgICAgbGV0IHNlZ3MgPSBbXTtcbiAgICAgICAgaWYgKHNlcmllc1NlZykge1xuICAgICAgICAgICAgbGV0IHsgZmlyc3RJbmRleCwgbGFzdEluZGV4IH0gPSBzZXJpZXNTZWc7XG4gICAgICAgICAgICBsZXQgaW5kZXggPSBmaXJzdEluZGV4O1xuICAgICAgICAgICAgd2hpbGUgKGluZGV4IDw9IGxhc3RJbmRleCkge1xuICAgICAgICAgICAgICAgIGxldCByb3cgPSBNYXRoLmZsb29yKGluZGV4IC8gY29sQ250KTtcbiAgICAgICAgICAgICAgICBsZXQgbmV4dEluZGV4ID0gTWF0aC5taW4oKHJvdyArIDEpICogY29sQ250LCBsYXN0SW5kZXggKyAxKTtcbiAgICAgICAgICAgICAgICBzZWdzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICByb3csXG4gICAgICAgICAgICAgICAgICAgIGZpcnN0Q29sOiBpbmRleCAlIGNvbENudCxcbiAgICAgICAgICAgICAgICAgICAgbGFzdENvbDogKG5leHRJbmRleCAtIDEpICUgY29sQ250LFxuICAgICAgICAgICAgICAgICAgICBpc1N0YXJ0OiBzZXJpZXNTZWcuaXNTdGFydCAmJiBpbmRleCA9PT0gZmlyc3RJbmRleCxcbiAgICAgICAgICAgICAgICAgICAgaXNFbmQ6IHNlcmllc1NlZy5pc0VuZCAmJiAobmV4dEluZGV4IC0gMSkgPT09IGxhc3RJbmRleCxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBpbmRleCA9IG5leHRJbmRleDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc2VncztcbiAgICB9XG59XG5cbmNsYXNzIFNsaWNlciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMuc2xpY2VCdXNpbmVzc0hvdXJzID0gbWVtb2l6ZSh0aGlzLl9zbGljZUJ1c2luZXNzSG91cnMpO1xuICAgICAgICB0aGlzLnNsaWNlRGF0ZVNlbGVjdGlvbiA9IG1lbW9pemUodGhpcy5fc2xpY2VEYXRlU3Bhbik7XG4gICAgICAgIHRoaXMuc2xpY2VFdmVudFN0b3JlID0gbWVtb2l6ZSh0aGlzLl9zbGljZUV2ZW50U3RvcmUpO1xuICAgICAgICB0aGlzLnNsaWNlRXZlbnREcmFnID0gbWVtb2l6ZSh0aGlzLl9zbGljZUludGVyYWN0aW9uKTtcbiAgICAgICAgdGhpcy5zbGljZUV2ZW50UmVzaXplID0gbWVtb2l6ZSh0aGlzLl9zbGljZUludGVyYWN0aW9uKTtcbiAgICAgICAgdGhpcy5mb3JjZURheUlmTGlzdEl0ZW0gPSBmYWxzZTsgLy8gaGFja1xuICAgIH1cbiAgICBzbGljZVByb3BzKHByb3BzLCBkYXRlUHJvZmlsZSwgbmV4dERheVRocmVzaG9sZCwgY29udGV4dCwgLi4uZXh0cmFBcmdzKSB7XG4gICAgICAgIGxldCB7IGV2ZW50VWlCYXNlcyB9ID0gcHJvcHM7XG4gICAgICAgIGxldCBldmVudFNlZ3MgPSB0aGlzLnNsaWNlRXZlbnRTdG9yZShwcm9wcy5ldmVudFN0b3JlLCBldmVudFVpQmFzZXMsIGRhdGVQcm9maWxlLCBuZXh0RGF5VGhyZXNob2xkLCAuLi5leHRyYUFyZ3MpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgZGF0ZVNlbGVjdGlvblNlZ3M6IHRoaXMuc2xpY2VEYXRlU2VsZWN0aW9uKHByb3BzLmRhdGVTZWxlY3Rpb24sIGV2ZW50VWlCYXNlcywgY29udGV4dCwgLi4uZXh0cmFBcmdzKSxcbiAgICAgICAgICAgIGJ1c2luZXNzSG91clNlZ3M6IHRoaXMuc2xpY2VCdXNpbmVzc0hvdXJzKHByb3BzLmJ1c2luZXNzSG91cnMsIGRhdGVQcm9maWxlLCBuZXh0RGF5VGhyZXNob2xkLCBjb250ZXh0LCAuLi5leHRyYUFyZ3MpLFxuICAgICAgICAgICAgZmdFdmVudFNlZ3M6IGV2ZW50U2Vncy5mZyxcbiAgICAgICAgICAgIGJnRXZlbnRTZWdzOiBldmVudFNlZ3MuYmcsXG4gICAgICAgICAgICBldmVudERyYWc6IHRoaXMuc2xpY2VFdmVudERyYWcocHJvcHMuZXZlbnREcmFnLCBldmVudFVpQmFzZXMsIGRhdGVQcm9maWxlLCBuZXh0RGF5VGhyZXNob2xkLCAuLi5leHRyYUFyZ3MpLFxuICAgICAgICAgICAgZXZlbnRSZXNpemU6IHRoaXMuc2xpY2VFdmVudFJlc2l6ZShwcm9wcy5ldmVudFJlc2l6ZSwgZXZlbnRVaUJhc2VzLCBkYXRlUHJvZmlsZSwgbmV4dERheVRocmVzaG9sZCwgLi4uZXh0cmFBcmdzKSxcbiAgICAgICAgICAgIGV2ZW50U2VsZWN0aW9uOiBwcm9wcy5ldmVudFNlbGVjdGlvbixcbiAgICAgICAgfTsgLy8gVE9ETzogZ2l2ZSBpbnRlcmFjdGlvblNlZ3M/XG4gICAgfVxuICAgIHNsaWNlTm93RGF0ZSgvLyBkb2VzIG5vdCBtZW1vaXplXG4gICAgZGF0ZSwgY29udGV4dCwgLi4uZXh0cmFBcmdzKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9zbGljZURhdGVTcGFuKHsgcmFuZ2U6IHsgc3RhcnQ6IGRhdGUsIGVuZDogYWRkTXMoZGF0ZSwgMSkgfSwgYWxsRGF5OiBmYWxzZSB9LCAvLyBhZGQgMSBtcywgcHJvdGVjdCBhZ2FpbnN0IG51bGwgcmFuZ2VcbiAgICAgICAge30sIGNvbnRleHQsIC4uLmV4dHJhQXJncyk7XG4gICAgfVxuICAgIF9zbGljZUJ1c2luZXNzSG91cnMoYnVzaW5lc3NIb3VycywgZGF0ZVByb2ZpbGUsIG5leHREYXlUaHJlc2hvbGQsIGNvbnRleHQsIC4uLmV4dHJhQXJncykge1xuICAgICAgICBpZiAoIWJ1c2luZXNzSG91cnMpIHtcbiAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fc2xpY2VFdmVudFN0b3JlKGV4cGFuZFJlY3VycmluZyhidXNpbmVzc0hvdXJzLCBjb21wdXRlQWN0aXZlUmFuZ2UoZGF0ZVByb2ZpbGUsIEJvb2xlYW4obmV4dERheVRocmVzaG9sZCkpLCBjb250ZXh0KSwge30sIGRhdGVQcm9maWxlLCBuZXh0RGF5VGhyZXNob2xkLCAuLi5leHRyYUFyZ3MpLmJnO1xuICAgIH1cbiAgICBfc2xpY2VFdmVudFN0b3JlKGV2ZW50U3RvcmUsIGV2ZW50VWlCYXNlcywgZGF0ZVByb2ZpbGUsIG5leHREYXlUaHJlc2hvbGQsIC4uLmV4dHJhQXJncykge1xuICAgICAgICBpZiAoZXZlbnRTdG9yZSkge1xuICAgICAgICAgICAgbGV0IHJhbmdlUmVzID0gc2xpY2VFdmVudFN0b3JlKGV2ZW50U3RvcmUsIGV2ZW50VWlCYXNlcywgY29tcHV0ZUFjdGl2ZVJhbmdlKGRhdGVQcm9maWxlLCBCb29sZWFuKG5leHREYXlUaHJlc2hvbGQpKSwgbmV4dERheVRocmVzaG9sZCk7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGJnOiB0aGlzLnNsaWNlRXZlbnRSYW5nZXMocmFuZ2VSZXMuYmcsIGV4dHJhQXJncyksXG4gICAgICAgICAgICAgICAgZmc6IHRoaXMuc2xpY2VFdmVudFJhbmdlcyhyYW5nZVJlcy5mZywgZXh0cmFBcmdzKSxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsgYmc6IFtdLCBmZzogW10gfTtcbiAgICB9XG4gICAgX3NsaWNlSW50ZXJhY3Rpb24oaW50ZXJhY3Rpb24sIGV2ZW50VWlCYXNlcywgZGF0ZVByb2ZpbGUsIG5leHREYXlUaHJlc2hvbGQsIC4uLmV4dHJhQXJncykge1xuICAgICAgICBpZiAoIWludGVyYWN0aW9uKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBsZXQgcmFuZ2VSZXMgPSBzbGljZUV2ZW50U3RvcmUoaW50ZXJhY3Rpb24ubXV0YXRlZEV2ZW50cywgZXZlbnRVaUJhc2VzLCBjb21wdXRlQWN0aXZlUmFuZ2UoZGF0ZVByb2ZpbGUsIEJvb2xlYW4obmV4dERheVRocmVzaG9sZCkpLCBuZXh0RGF5VGhyZXNob2xkKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHNlZ3M6IHRoaXMuc2xpY2VFdmVudFJhbmdlcyhyYW5nZVJlcy5mZywgZXh0cmFBcmdzKSxcbiAgICAgICAgICAgIGFmZmVjdGVkSW5zdGFuY2VzOiBpbnRlcmFjdGlvbi5hZmZlY3RlZEV2ZW50cy5pbnN0YW5jZXMsXG4gICAgICAgICAgICBpc0V2ZW50OiBpbnRlcmFjdGlvbi5pc0V2ZW50LFxuICAgICAgICB9O1xuICAgIH1cbiAgICBfc2xpY2VEYXRlU3BhbihkYXRlU3BhbiwgZXZlbnRVaUJhc2VzLCBjb250ZXh0LCAuLi5leHRyYUFyZ3MpIHtcbiAgICAgICAgaWYgKCFkYXRlU3Bhbikge1xuICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICB9XG4gICAgICAgIGxldCBldmVudFJhbmdlID0gZmFicmljYXRlRXZlbnRSYW5nZShkYXRlU3BhbiwgZXZlbnRVaUJhc2VzLCBjb250ZXh0KTtcbiAgICAgICAgbGV0IHNlZ3MgPSB0aGlzLnNsaWNlUmFuZ2UoZGF0ZVNwYW4ucmFuZ2UsIC4uLmV4dHJhQXJncyk7XG4gICAgICAgIGZvciAobGV0IHNlZyBvZiBzZWdzKSB7XG4gICAgICAgICAgICBzZWcuZXZlbnRSYW5nZSA9IGV2ZW50UmFuZ2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHNlZ3M7XG4gICAgfVxuICAgIC8qXG4gICAgXCJjb21wbGV0ZVwiIHNlZyBtZWFucyBpdCBoYXMgY29tcG9uZW50IGFuZCBldmVudFJhbmdlXG4gICAgKi9cbiAgICBzbGljZUV2ZW50UmFuZ2VzKGV2ZW50UmFuZ2VzLCBleHRyYUFyZ3MpIHtcbiAgICAgICAgbGV0IHNlZ3MgPSBbXTtcbiAgICAgICAgZm9yIChsZXQgZXZlbnRSYW5nZSBvZiBldmVudFJhbmdlcykge1xuICAgICAgICAgICAgc2Vncy5wdXNoKC4uLnRoaXMuc2xpY2VFdmVudFJhbmdlKGV2ZW50UmFuZ2UsIGV4dHJhQXJncykpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzZWdzO1xuICAgIH1cbiAgICAvKlxuICAgIFwiY29tcGxldGVcIiBzZWcgbWVhbnMgaXQgaGFzIGNvbXBvbmVudCBhbmQgZXZlbnRSYW5nZVxuICAgICovXG4gICAgc2xpY2VFdmVudFJhbmdlKGV2ZW50UmFuZ2UsIGV4dHJhQXJncykge1xuICAgICAgICBsZXQgZGF0ZVJhbmdlID0gZXZlbnRSYW5nZS5yYW5nZTtcbiAgICAgICAgLy8gaGFjayB0byBtYWtlIG11bHRpLWRheSBldmVudHMgdGhhdCBhcmUgYmVpbmcgZm9yY2UtZGlzcGxheWVkIGFzIGxpc3QtaXRlbXMgdG8gdGFrZSB1cCBvbmx5IG9uZSBkYXlcbiAgICAgICAgaWYgKHRoaXMuZm9yY2VEYXlJZkxpc3RJdGVtICYmIGV2ZW50UmFuZ2UudWkuZGlzcGxheSA9PT0gJ2xpc3QtaXRlbScpIHtcbiAgICAgICAgICAgIGRhdGVSYW5nZSA9IHtcbiAgICAgICAgICAgICAgICBzdGFydDogZGF0ZVJhbmdlLnN0YXJ0LFxuICAgICAgICAgICAgICAgIGVuZDogYWRkRGF5cyhkYXRlUmFuZ2Uuc3RhcnQsIDEpLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgc2VncyA9IHRoaXMuc2xpY2VSYW5nZShkYXRlUmFuZ2UsIC4uLmV4dHJhQXJncyk7XG4gICAgICAgIGZvciAobGV0IHNlZyBvZiBzZWdzKSB7XG4gICAgICAgICAgICBzZWcuZXZlbnRSYW5nZSA9IGV2ZW50UmFuZ2U7XG4gICAgICAgICAgICBzZWcuaXNTdGFydCA9IGV2ZW50UmFuZ2UuaXNTdGFydCAmJiBzZWcuaXNTdGFydDtcbiAgICAgICAgICAgIHNlZy5pc0VuZCA9IGV2ZW50UmFuZ2UuaXNFbmQgJiYgc2VnLmlzRW5kO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzZWdzO1xuICAgIH1cbn1cbi8qXG5mb3IgaW5jb3Jwb3JhdGluZyBzbG90TWluVGltZS9zbG90TWF4VGltZSBpZiBhcHByb3ByaWF0ZVxuVE9ETzogc2hvdWxkIGJlIHBhcnQgb2YgRGF0ZVByb2ZpbGUhXG5UaW1lbGluZURhdGVQcm9maWxlIGFscmVhZHkgZG9lcyB0aGlzIGJ0d1xuKi9cbmZ1bmN0aW9uIGNvbXB1dGVBY3RpdmVSYW5nZShkYXRlUHJvZmlsZSwgaXNDb21wb25lbnRBbGxEYXkpIHtcbiAgICBsZXQgcmFuZ2UgPSBkYXRlUHJvZmlsZS5hY3RpdmVSYW5nZTtcbiAgICBpZiAoaXNDb21wb25lbnRBbGxEYXkpIHtcbiAgICAgICAgcmV0dXJuIHJhbmdlO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgICBzdGFydDogYWRkTXMocmFuZ2Uuc3RhcnQsIGRhdGVQcm9maWxlLnNsb3RNaW5UaW1lLm1pbGxpc2Vjb25kcyksXG4gICAgICAgIGVuZDogYWRkTXMocmFuZ2UuZW5kLCBkYXRlUHJvZmlsZS5zbG90TWF4VGltZS5taWxsaXNlY29uZHMgLSA4NjRlNSksIC8vIDg2NGU1ID0gbXMgaW4gYSBkYXlcbiAgICB9O1xufVxuXG5mdW5jdGlvbiByZWR1Y2VFdmVudFN0b3JlKGV2ZW50U3RvcmUsIGFjdGlvbiwgZXZlbnRTb3VyY2VzLCBkYXRlUHJvZmlsZSwgY29udGV4dCkge1xuICAgIHN3aXRjaCAoYWN0aW9uLnR5cGUpIHtcbiAgICAgICAgY2FzZSAnUkVDRUlWRV9FVkVOVFMnOiAvLyByYXdcbiAgICAgICAgICAgIHJldHVybiByZWNlaXZlUmF3RXZlbnRzKGV2ZW50U3RvcmUsIGV2ZW50U291cmNlc1thY3Rpb24uc291cmNlSWRdLCBhY3Rpb24uZmV0Y2hJZCwgYWN0aW9uLmZldGNoUmFuZ2UsIGFjdGlvbi5yYXdFdmVudHMsIGNvbnRleHQpO1xuICAgICAgICBjYXNlICdBRERfRVZFTlRTJzogLy8gYWxyZWFkeSBwYXJzZWQsIGJ1dCBub3QgZXhwYW5kZWRcbiAgICAgICAgICAgIHJldHVybiBhZGRFdmVudChldmVudFN0b3JlLCBhY3Rpb24uZXZlbnRTdG9yZSwgLy8gbmV3IG9uZXNcbiAgICAgICAgICAgIGRhdGVQcm9maWxlID8gZGF0ZVByb2ZpbGUuYWN0aXZlUmFuZ2UgOiBudWxsLCBjb250ZXh0KTtcbiAgICAgICAgY2FzZSAnUkVTRVRfRVZFTlRTJzpcbiAgICAgICAgICAgIHJldHVybiBhY3Rpb24uZXZlbnRTdG9yZTtcbiAgICAgICAgY2FzZSAnTUVSR0VfRVZFTlRTJzogLy8gYWxyZWFkeSBwYXJzZWQgYW5kIGV4cGFuZGVkXG4gICAgICAgICAgICByZXR1cm4gbWVyZ2VFdmVudFN0b3JlcyhldmVudFN0b3JlLCBhY3Rpb24uZXZlbnRTdG9yZSk7XG4gICAgICAgIGNhc2UgJ1BSRVYnOiAvLyBUT0RPOiBob3cgZG8gd2UgdHJhY2sgYWxsIGFjdGlvbnMgdGhhdCBhZmZlY3QgZGF0ZVByb2ZpbGUgOihcbiAgICAgICAgY2FzZSAnTkVYVCc6XG4gICAgICAgIGNhc2UgJ0NIQU5HRV9EQVRFJzpcbiAgICAgICAgY2FzZSAnQ0hBTkdFX1ZJRVdfVFlQRSc6XG4gICAgICAgICAgICBpZiAoZGF0ZVByb2ZpbGUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZXhwYW5kUmVjdXJyaW5nKGV2ZW50U3RvcmUsIGRhdGVQcm9maWxlLmFjdGl2ZVJhbmdlLCBjb250ZXh0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBldmVudFN0b3JlO1xuICAgICAgICBjYXNlICdSRU1PVkVfRVZFTlRTJzpcbiAgICAgICAgICAgIHJldHVybiBleGNsdWRlU3ViRXZlbnRTdG9yZShldmVudFN0b3JlLCBhY3Rpb24uZXZlbnRTdG9yZSk7XG4gICAgICAgIGNhc2UgJ1JFTU9WRV9FVkVOVF9TT1VSQ0UnOlxuICAgICAgICAgICAgcmV0dXJuIGV4Y2x1ZGVFdmVudHNCeVNvdXJjZUlkKGV2ZW50U3RvcmUsIGFjdGlvbi5zb3VyY2VJZCk7XG4gICAgICAgIGNhc2UgJ1JFTU9WRV9BTExfRVZFTlRfU09VUkNFUyc6XG4gICAgICAgICAgICByZXR1cm4gZmlsdGVyRXZlbnRTdG9yZURlZnMoZXZlbnRTdG9yZSwgKGV2ZW50RGVmKSA9PiAoIWV2ZW50RGVmLnNvdXJjZUlkIC8vIG9ubHkga2VlcCBldmVudHMgd2l0aCBubyBzb3VyY2UgaWRcbiAgICAgICAgICAgICkpO1xuICAgICAgICBjYXNlICdSRU1PVkVfQUxMX0VWRU5UUyc6XG4gICAgICAgICAgICByZXR1cm4gY3JlYXRlRW1wdHlFdmVudFN0b3JlKCk7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICByZXR1cm4gZXZlbnRTdG9yZTtcbiAgICB9XG59XG5mdW5jdGlvbiByZWNlaXZlUmF3RXZlbnRzKGV2ZW50U3RvcmUsIGV2ZW50U291cmNlLCBmZXRjaElkLCBmZXRjaFJhbmdlLCByYXdFdmVudHMsIGNvbnRleHQpIHtcbiAgICBpZiAoZXZlbnRTb3VyY2UgJiYgLy8gbm90IGFscmVhZHkgcmVtb3ZlZFxuICAgICAgICBmZXRjaElkID09PSBldmVudFNvdXJjZS5sYXRlc3RGZXRjaElkIC8vIFRPRE86IHdpc2ggdGhpcyBsb2dpYyB3YXMgYWx3YXlzIGluIGV2ZW50LXNvdXJjZXNcbiAgICApIHtcbiAgICAgICAgbGV0IHN1YnNldCA9IHBhcnNlRXZlbnRzKHRyYW5zZm9ybVJhd0V2ZW50cyhyYXdFdmVudHMsIGV2ZW50U291cmNlLCBjb250ZXh0KSwgZXZlbnRTb3VyY2UsIGNvbnRleHQpO1xuICAgICAgICBpZiAoZmV0Y2hSYW5nZSkge1xuICAgICAgICAgICAgc3Vic2V0ID0gZXhwYW5kUmVjdXJyaW5nKHN1YnNldCwgZmV0Y2hSYW5nZSwgY29udGV4dCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG1lcmdlRXZlbnRTdG9yZXMoZXhjbHVkZUV2ZW50c0J5U291cmNlSWQoZXZlbnRTdG9yZSwgZXZlbnRTb3VyY2Uuc291cmNlSWQpLCBzdWJzZXQpO1xuICAgIH1cbiAgICByZXR1cm4gZXZlbnRTdG9yZTtcbn1cbmZ1bmN0aW9uIHRyYW5zZm9ybVJhd0V2ZW50cyhyYXdFdmVudHMsIGV2ZW50U291cmNlLCBjb250ZXh0KSB7XG4gICAgbGV0IGNhbEVhY2hUcmFuc2Zvcm0gPSBjb250ZXh0Lm9wdGlvbnMuZXZlbnREYXRhVHJhbnNmb3JtO1xuICAgIGxldCBzb3VyY2VFYWNoVHJhbnNmb3JtID0gZXZlbnRTb3VyY2UgPyBldmVudFNvdXJjZS5ldmVudERhdGFUcmFuc2Zvcm0gOiBudWxsO1xuICAgIGlmIChzb3VyY2VFYWNoVHJhbnNmb3JtKSB7XG4gICAgICAgIHJhd0V2ZW50cyA9IHRyYW5zZm9ybUVhY2hSYXdFdmVudChyYXdFdmVudHMsIHNvdXJjZUVhY2hUcmFuc2Zvcm0pO1xuICAgIH1cbiAgICBpZiAoY2FsRWFjaFRyYW5zZm9ybSkge1xuICAgICAgICByYXdFdmVudHMgPSB0cmFuc2Zvcm1FYWNoUmF3RXZlbnQocmF3RXZlbnRzLCBjYWxFYWNoVHJhbnNmb3JtKTtcbiAgICB9XG4gICAgcmV0dXJuIHJhd0V2ZW50cztcbn1cbmZ1bmN0aW9uIHRyYW5zZm9ybUVhY2hSYXdFdmVudChyYXdFdmVudHMsIGZ1bmMpIHtcbiAgICBsZXQgcmVmaW5lZEV2ZW50cztcbiAgICBpZiAoIWZ1bmMpIHtcbiAgICAgICAgcmVmaW5lZEV2ZW50cyA9IHJhd0V2ZW50cztcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHJlZmluZWRFdmVudHMgPSBbXTtcbiAgICAgICAgZm9yIChsZXQgcmF3RXZlbnQgb2YgcmF3RXZlbnRzKSB7XG4gICAgICAgICAgICBsZXQgcmVmaW5lZEV2ZW50ID0gZnVuYyhyYXdFdmVudCk7XG4gICAgICAgICAgICBpZiAocmVmaW5lZEV2ZW50KSB7XG4gICAgICAgICAgICAgICAgcmVmaW5lZEV2ZW50cy5wdXNoKHJlZmluZWRFdmVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChyZWZpbmVkRXZlbnQgPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHJlZmluZWRFdmVudHMucHVzaChyYXdFdmVudCk7XG4gICAgICAgICAgICB9IC8vIGlmIGEgZGlmZmVyZW50IGZhbHN5IHZhbHVlLCBkbyBub3RoaW5nXG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlZmluZWRFdmVudHM7XG59XG5mdW5jdGlvbiBhZGRFdmVudChldmVudFN0b3JlLCBzdWJzZXQsIGV4cGFuZFJhbmdlLCBjb250ZXh0KSB7XG4gICAgaWYgKGV4cGFuZFJhbmdlKSB7XG4gICAgICAgIHN1YnNldCA9IGV4cGFuZFJlY3VycmluZyhzdWJzZXQsIGV4cGFuZFJhbmdlLCBjb250ZXh0KTtcbiAgICB9XG4gICAgcmV0dXJuIG1lcmdlRXZlbnRTdG9yZXMoZXZlbnRTdG9yZSwgc3Vic2V0KTtcbn1cbmZ1bmN0aW9uIHJlem9uZUV2ZW50U3RvcmVEYXRlcyhldmVudFN0b3JlLCBvbGREYXRlRW52LCBuZXdEYXRlRW52KSB7XG4gICAgbGV0IHsgZGVmcyB9ID0gZXZlbnRTdG9yZTtcbiAgICBsZXQgaW5zdGFuY2VzID0gbWFwSGFzaChldmVudFN0b3JlLmluc3RhbmNlcywgKGluc3RhbmNlKSA9PiB7XG4gICAgICAgIGxldCBkZWYgPSBkZWZzW2luc3RhbmNlLmRlZklkXTtcbiAgICAgICAgaWYgKGRlZi5hbGxEYXkgfHwgZGVmLnJlY3VycmluZ0RlZikge1xuICAgICAgICAgICAgcmV0dXJuIGluc3RhbmNlOyAvLyBpc24ndCBkZXBlbmRlbnQgb24gdGltZXpvbmVcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCBpbnN0YW5jZSksIHsgcmFuZ2U6IHtcbiAgICAgICAgICAgICAgICBzdGFydDogbmV3RGF0ZUVudi5jcmVhdGVNYXJrZXIob2xkRGF0ZUVudi50b0RhdGUoaW5zdGFuY2UucmFuZ2Uuc3RhcnQsIGluc3RhbmNlLmZvcmNlZFN0YXJ0VHpvKSksXG4gICAgICAgICAgICAgICAgZW5kOiBuZXdEYXRlRW52LmNyZWF0ZU1hcmtlcihvbGREYXRlRW52LnRvRGF0ZShpbnN0YW5jZS5yYW5nZS5lbmQsIGluc3RhbmNlLmZvcmNlZEVuZFR6bykpLFxuICAgICAgICAgICAgfSwgZm9yY2VkU3RhcnRUem86IG5ld0RhdGVFbnYuY2FuQ29tcHV0ZU9mZnNldCA/IG51bGwgOiBpbnN0YW5jZS5mb3JjZWRTdGFydFR6bywgZm9yY2VkRW5kVHpvOiBuZXdEYXRlRW52LmNhbkNvbXB1dGVPZmZzZXQgPyBudWxsIDogaW5zdGFuY2UuZm9yY2VkRW5kVHpvIH0pO1xuICAgIH0pO1xuICAgIHJldHVybiB7IGRlZnMsIGluc3RhbmNlcyB9O1xufVxuZnVuY3Rpb24gZXhjbHVkZUV2ZW50c0J5U291cmNlSWQoZXZlbnRTdG9yZSwgc291cmNlSWQpIHtcbiAgICByZXR1cm4gZmlsdGVyRXZlbnRTdG9yZURlZnMoZXZlbnRTdG9yZSwgKGV2ZW50RGVmKSA9PiBldmVudERlZi5zb3VyY2VJZCAhPT0gc291cmNlSWQpO1xufVxuLy8gUVVFU1RJT046IHdoeSBub3QganVzdCByZXR1cm4gaW5zdGFuY2VzPyBkbyBhIGdlbmVyYWwgb2JqZWN0LXByb3BlcnR5LWV4Y2x1c2lvbiB1dGlsXG5mdW5jdGlvbiBleGNsdWRlSW5zdGFuY2VzKGV2ZW50U3RvcmUsIHJlbW92YWxzKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgZGVmczogZXZlbnRTdG9yZS5kZWZzLFxuICAgICAgICBpbnN0YW5jZXM6IGZpbHRlckhhc2goZXZlbnRTdG9yZS5pbnN0YW5jZXMsIChpbnN0YW5jZSkgPT4gIXJlbW92YWxzW2luc3RhbmNlLmluc3RhbmNlSWRdKSxcbiAgICB9O1xufVxuXG4vLyBoaWdoLWxldmVsIHNlZ21lbnRpbmctYXdhcmUgdGVzdGVyIGZ1bmN0aW9uc1xuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5mdW5jdGlvbiBpc0ludGVyYWN0aW9uVmFsaWQoaW50ZXJhY3Rpb24sIGRhdGVQcm9maWxlLCBjb250ZXh0KSB7XG4gICAgbGV0IHsgaW5zdGFuY2VzIH0gPSBpbnRlcmFjdGlvbi5tdXRhdGVkRXZlbnRzO1xuICAgIGZvciAobGV0IGluc3RhbmNlSWQgaW4gaW5zdGFuY2VzKSB7XG4gICAgICAgIGlmICghcmFuZ2VDb250YWluc1JhbmdlKGRhdGVQcm9maWxlLnZhbGlkUmFuZ2UsIGluc3RhbmNlc1tpbnN0YW5jZUlkXS5yYW5nZSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gaXNOZXdQcm9wc1ZhbGlkKHsgZXZlbnREcmFnOiBpbnRlcmFjdGlvbiB9LCBjb250ZXh0KTsgLy8gSEFDSzogdGhlIGV2ZW50RHJhZyBwcm9wcyBpcyB1c2VkIGZvciBBTEwgaW50ZXJhY3Rpb25zXG59XG5mdW5jdGlvbiBpc0RhdGVTZWxlY3Rpb25WYWxpZChkYXRlU2VsZWN0aW9uLCBkYXRlUHJvZmlsZSwgY29udGV4dCkge1xuICAgIGlmICghcmFuZ2VDb250YWluc1JhbmdlKGRhdGVQcm9maWxlLnZhbGlkUmFuZ2UsIGRhdGVTZWxlY3Rpb24ucmFuZ2UpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIGlzTmV3UHJvcHNWYWxpZCh7IGRhdGVTZWxlY3Rpb24gfSwgY29udGV4dCk7XG59XG5mdW5jdGlvbiBpc05ld1Byb3BzVmFsaWQobmV3UHJvcHMsIGNvbnRleHQpIHtcbiAgICBsZXQgY2FsZW5kYXJTdGF0ZSA9IGNvbnRleHQuZ2V0Q3VycmVudERhdGEoKTtcbiAgICBsZXQgcHJvcHMgPSBPYmplY3QuYXNzaWduKHsgYnVzaW5lc3NIb3VyczogY2FsZW5kYXJTdGF0ZS5idXNpbmVzc0hvdXJzLCBkYXRlU2VsZWN0aW9uOiAnJywgZXZlbnRTdG9yZTogY2FsZW5kYXJTdGF0ZS5ldmVudFN0b3JlLCBldmVudFVpQmFzZXM6IGNhbGVuZGFyU3RhdGUuZXZlbnRVaUJhc2VzLCBldmVudFNlbGVjdGlvbjogJycsIGV2ZW50RHJhZzogbnVsbCwgZXZlbnRSZXNpemU6IG51bGwgfSwgbmV3UHJvcHMpO1xuICAgIHJldHVybiAoY29udGV4dC5wbHVnaW5Ib29rcy5pc1Byb3BzVmFsaWQgfHwgaXNQcm9wc1ZhbGlkKShwcm9wcywgY29udGV4dCk7XG59XG5mdW5jdGlvbiBpc1Byb3BzVmFsaWQoc3RhdGUsIGNvbnRleHQsIGRhdGVTcGFuTWV0YSA9IHt9LCBmaWx0ZXJDb25maWcpIHtcbiAgICBpZiAoc3RhdGUuZXZlbnREcmFnICYmICFpc0ludGVyYWN0aW9uUHJvcHNWYWxpZChzdGF0ZSwgY29udGV4dCwgZGF0ZVNwYW5NZXRhLCBmaWx0ZXJDb25maWcpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKHN0YXRlLmRhdGVTZWxlY3Rpb24gJiYgIWlzRGF0ZVNlbGVjdGlvblByb3BzVmFsaWQoc3RhdGUsIGNvbnRleHQsIGRhdGVTcGFuTWV0YSwgZmlsdGVyQ29uZmlnKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufVxuLy8gTW92aW5nIEV2ZW50IFZhbGlkYXRpb25cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuZnVuY3Rpb24gaXNJbnRlcmFjdGlvblByb3BzVmFsaWQoc3RhdGUsIGNvbnRleHQsIGRhdGVTcGFuTWV0YSwgZmlsdGVyQ29uZmlnKSB7XG4gICAgbGV0IGN1cnJlbnRTdGF0ZSA9IGNvbnRleHQuZ2V0Q3VycmVudERhdGEoKTtcbiAgICBsZXQgaW50ZXJhY3Rpb24gPSBzdGF0ZS5ldmVudERyYWc7IC8vIEhBQ0s6IHRoZSBldmVudERyYWcgcHJvcHMgaXMgdXNlZCBmb3IgQUxMIGludGVyYWN0aW9uc1xuICAgIGxldCBzdWJqZWN0RXZlbnRTdG9yZSA9IGludGVyYWN0aW9uLm11dGF0ZWRFdmVudHM7XG4gICAgbGV0IHN1YmplY3REZWZzID0gc3ViamVjdEV2ZW50U3RvcmUuZGVmcztcbiAgICBsZXQgc3ViamVjdEluc3RhbmNlcyA9IHN1YmplY3RFdmVudFN0b3JlLmluc3RhbmNlcztcbiAgICBsZXQgc3ViamVjdENvbmZpZ3MgPSBjb21waWxlRXZlbnRVaXMoc3ViamVjdERlZnMsIGludGVyYWN0aW9uLmlzRXZlbnQgP1xuICAgICAgICBzdGF0ZS5ldmVudFVpQmFzZXMgOlxuICAgICAgICB7ICcnOiBjdXJyZW50U3RhdGUuc2VsZWN0aW9uQ29uZmlnIH0pO1xuICAgIGlmIChmaWx0ZXJDb25maWcpIHtcbiAgICAgICAgc3ViamVjdENvbmZpZ3MgPSBtYXBIYXNoKHN1YmplY3RDb25maWdzLCBmaWx0ZXJDb25maWcpO1xuICAgIH1cbiAgICAvLyBleGNsdWRlIHRoZSBzdWJqZWN0IGV2ZW50cy4gVE9ETzogZXhjbHVkZSBkZWZzIHRvbz9cbiAgICBsZXQgb3RoZXJFdmVudFN0b3JlID0gZXhjbHVkZUluc3RhbmNlcyhzdGF0ZS5ldmVudFN0b3JlLCBpbnRlcmFjdGlvbi5hZmZlY3RlZEV2ZW50cy5pbnN0YW5jZXMpO1xuICAgIGxldCBvdGhlckRlZnMgPSBvdGhlckV2ZW50U3RvcmUuZGVmcztcbiAgICBsZXQgb3RoZXJJbnN0YW5jZXMgPSBvdGhlckV2ZW50U3RvcmUuaW5zdGFuY2VzO1xuICAgIGxldCBvdGhlckNvbmZpZ3MgPSBjb21waWxlRXZlbnRVaXMob3RoZXJEZWZzLCBzdGF0ZS5ldmVudFVpQmFzZXMpO1xuICAgIGZvciAobGV0IHN1YmplY3RJbnN0YW5jZUlkIGluIHN1YmplY3RJbnN0YW5jZXMpIHtcbiAgICAgICAgbGV0IHN1YmplY3RJbnN0YW5jZSA9IHN1YmplY3RJbnN0YW5jZXNbc3ViamVjdEluc3RhbmNlSWRdO1xuICAgICAgICBsZXQgc3ViamVjdFJhbmdlID0gc3ViamVjdEluc3RhbmNlLnJhbmdlO1xuICAgICAgICBsZXQgc3ViamVjdENvbmZpZyA9IHN1YmplY3RDb25maWdzW3N1YmplY3RJbnN0YW5jZS5kZWZJZF07XG4gICAgICAgIGxldCBzdWJqZWN0RGVmID0gc3ViamVjdERlZnNbc3ViamVjdEluc3RhbmNlLmRlZklkXTtcbiAgICAgICAgLy8gY29uc3RyYWludFxuICAgICAgICBpZiAoIWFsbENvbnN0cmFpbnRzUGFzcyhzdWJqZWN0Q29uZmlnLmNvbnN0cmFpbnRzLCBzdWJqZWN0UmFuZ2UsIG90aGVyRXZlbnRTdG9yZSwgc3RhdGUuYnVzaW5lc3NIb3VycywgY29udGV4dCkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICAvLyBvdmVybGFwXG4gICAgICAgIGxldCB7IGV2ZW50T3ZlcmxhcCB9ID0gY29udGV4dC5vcHRpb25zO1xuICAgICAgICBsZXQgZXZlbnRPdmVybGFwRnVuYyA9IHR5cGVvZiBldmVudE92ZXJsYXAgPT09ICdmdW5jdGlvbicgPyBldmVudE92ZXJsYXAgOiBudWxsO1xuICAgICAgICBmb3IgKGxldCBvdGhlckluc3RhbmNlSWQgaW4gb3RoZXJJbnN0YW5jZXMpIHtcbiAgICAgICAgICAgIGxldCBvdGhlckluc3RhbmNlID0gb3RoZXJJbnN0YW5jZXNbb3RoZXJJbnN0YW5jZUlkXTtcbiAgICAgICAgICAgIC8vIGludGVyc2VjdCEgZXZhbHVhdGVcbiAgICAgICAgICAgIGlmIChyYW5nZXNJbnRlcnNlY3Qoc3ViamVjdFJhbmdlLCBvdGhlckluc3RhbmNlLnJhbmdlKSkge1xuICAgICAgICAgICAgICAgIGxldCBvdGhlck92ZXJsYXAgPSBvdGhlckNvbmZpZ3Nbb3RoZXJJbnN0YW5jZS5kZWZJZF0ub3ZlcmxhcDtcbiAgICAgICAgICAgICAgICAvLyBjb25zaWRlciB0aGUgb3RoZXIgZXZlbnQncyBvdmVybGFwLiBvbmx5IGRvIHRoaXMgaWYgdGhlIHN1YmplY3QgZXZlbnQgaXMgYSBcInJlYWxcIiBldmVudFxuICAgICAgICAgICAgICAgIGlmIChvdGhlck92ZXJsYXAgPT09IGZhbHNlICYmIGludGVyYWN0aW9uLmlzRXZlbnQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoc3ViamVjdENvbmZpZy5vdmVybGFwID09PSBmYWxzZSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChldmVudE92ZXJsYXBGdW5jICYmICFldmVudE92ZXJsYXBGdW5jKG5ldyBFdmVudEltcGwoY29udGV4dCwgb3RoZXJEZWZzW290aGVySW5zdGFuY2UuZGVmSWRdLCBvdGhlckluc3RhbmNlKSwgLy8gc3RpbGwgZXZlbnRcbiAgICAgICAgICAgICAgICBuZXcgRXZlbnRJbXBsKGNvbnRleHQsIHN1YmplY3REZWYsIHN1YmplY3RJbnN0YW5jZSkpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gYWxsb3cgKGEgZnVuY3Rpb24pXG4gICAgICAgIGxldCBjYWxlbmRhckV2ZW50U3RvcmUgPSBjdXJyZW50U3RhdGUuZXZlbnRTdG9yZTsgLy8gbmVlZCBnbG9iYWwtdG8tY2FsZW5kYXIsIG5vdCBsb2NhbCB0byBjb21wb25lbnQgKHNwbGl0dGFibGUpc3RhdGVcbiAgICAgICAgZm9yIChsZXQgc3ViamVjdEFsbG93IG9mIHN1YmplY3RDb25maWcuYWxsb3dzKSB7XG4gICAgICAgICAgICBsZXQgc3ViamVjdERhdGVTcGFuID0gT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCBkYXRlU3Bhbk1ldGEpLCB7IHJhbmdlOiBzdWJqZWN0SW5zdGFuY2UucmFuZ2UsIGFsbERheTogc3ViamVjdERlZi5hbGxEYXkgfSk7XG4gICAgICAgICAgICBsZXQgb3JpZ0RlZiA9IGNhbGVuZGFyRXZlbnRTdG9yZS5kZWZzW3N1YmplY3REZWYuZGVmSWRdO1xuICAgICAgICAgICAgbGV0IG9yaWdJbnN0YW5jZSA9IGNhbGVuZGFyRXZlbnRTdG9yZS5pbnN0YW5jZXNbc3ViamVjdEluc3RhbmNlSWRdO1xuICAgICAgICAgICAgbGV0IGV2ZW50QXBpO1xuICAgICAgICAgICAgaWYgKG9yaWdEZWYpIHsgLy8gd2FzIHByZXZpb3VzbHkgaW4gdGhlIGNhbGVuZGFyXG4gICAgICAgICAgICAgICAgZXZlbnRBcGkgPSBuZXcgRXZlbnRJbXBsKGNvbnRleHQsIG9yaWdEZWYsIG9yaWdJbnN0YW5jZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHsgLy8gd2FzIGFuIGV4dGVybmFsIGV2ZW50XG4gICAgICAgICAgICAgICAgZXZlbnRBcGkgPSBuZXcgRXZlbnRJbXBsKGNvbnRleHQsIHN1YmplY3REZWYpOyAvLyBubyBpbnN0YW5jZSwgYmVjYXVzZSBoYWQgbm8gZGF0ZXNcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghc3ViamVjdEFsbG93KGJ1aWxkRGF0ZVNwYW5BcGlXaXRoQ29udGV4dChzdWJqZWN0RGF0ZVNwYW4sIGNvbnRleHQpLCBldmVudEFwaSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG4vLyBEYXRlIFNlbGVjdGlvbiBWYWxpZGF0aW9uXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbmZ1bmN0aW9uIGlzRGF0ZVNlbGVjdGlvblByb3BzVmFsaWQoc3RhdGUsIGNvbnRleHQsIGRhdGVTcGFuTWV0YSwgZmlsdGVyQ29uZmlnKSB7XG4gICAgbGV0IHJlbGV2YW50RXZlbnRTdG9yZSA9IHN0YXRlLmV2ZW50U3RvcmU7XG4gICAgbGV0IHJlbGV2YW50RGVmcyA9IHJlbGV2YW50RXZlbnRTdG9yZS5kZWZzO1xuICAgIGxldCByZWxldmFudEluc3RhbmNlcyA9IHJlbGV2YW50RXZlbnRTdG9yZS5pbnN0YW5jZXM7XG4gICAgbGV0IHNlbGVjdGlvbiA9IHN0YXRlLmRhdGVTZWxlY3Rpb247XG4gICAgbGV0IHNlbGVjdGlvblJhbmdlID0gc2VsZWN0aW9uLnJhbmdlO1xuICAgIGxldCB7IHNlbGVjdGlvbkNvbmZpZyB9ID0gY29udGV4dC5nZXRDdXJyZW50RGF0YSgpO1xuICAgIGlmIChmaWx0ZXJDb25maWcpIHtcbiAgICAgICAgc2VsZWN0aW9uQ29uZmlnID0gZmlsdGVyQ29uZmlnKHNlbGVjdGlvbkNvbmZpZyk7XG4gICAgfVxuICAgIC8vIGNvbnN0cmFpbnRcbiAgICBpZiAoIWFsbENvbnN0cmFpbnRzUGFzcyhzZWxlY3Rpb25Db25maWcuY29uc3RyYWludHMsIHNlbGVjdGlvblJhbmdlLCByZWxldmFudEV2ZW50U3RvcmUsIHN0YXRlLmJ1c2luZXNzSG91cnMsIGNvbnRleHQpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgLy8gb3ZlcmxhcFxuICAgIGxldCB7IHNlbGVjdE92ZXJsYXAgfSA9IGNvbnRleHQub3B0aW9ucztcbiAgICBsZXQgc2VsZWN0T3ZlcmxhcEZ1bmMgPSB0eXBlb2Ygc2VsZWN0T3ZlcmxhcCA9PT0gJ2Z1bmN0aW9uJyA/IHNlbGVjdE92ZXJsYXAgOiBudWxsO1xuICAgIGZvciAobGV0IHJlbGV2YW50SW5zdGFuY2VJZCBpbiByZWxldmFudEluc3RhbmNlcykge1xuICAgICAgICBsZXQgcmVsZXZhbnRJbnN0YW5jZSA9IHJlbGV2YW50SW5zdGFuY2VzW3JlbGV2YW50SW5zdGFuY2VJZF07XG4gICAgICAgIC8vIGludGVyc2VjdCEgZXZhbHVhdGVcbiAgICAgICAgaWYgKHJhbmdlc0ludGVyc2VjdChzZWxlY3Rpb25SYW5nZSwgcmVsZXZhbnRJbnN0YW5jZS5yYW5nZSkpIHtcbiAgICAgICAgICAgIGlmIChzZWxlY3Rpb25Db25maWcub3ZlcmxhcCA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoc2VsZWN0T3ZlcmxhcEZ1bmMgJiYgIXNlbGVjdE92ZXJsYXBGdW5jKG5ldyBFdmVudEltcGwoY29udGV4dCwgcmVsZXZhbnREZWZzW3JlbGV2YW50SW5zdGFuY2UuZGVmSWRdLCByZWxldmFudEluc3RhbmNlKSwgbnVsbCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgLy8gYWxsb3cgKGEgZnVuY3Rpb24pXG4gICAgZm9yIChsZXQgc2VsZWN0aW9uQWxsb3cgb2Ygc2VsZWN0aW9uQ29uZmlnLmFsbG93cykge1xuICAgICAgICBsZXQgZnVsbERhdGVTcGFuID0gT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCBkYXRlU3Bhbk1ldGEpLCBzZWxlY3Rpb24pO1xuICAgICAgICBpZiAoIXNlbGVjdGlvbkFsbG93KGJ1aWxkRGF0ZVNwYW5BcGlXaXRoQ29udGV4dChmdWxsRGF0ZVNwYW4sIGNvbnRleHQpLCBudWxsKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufVxuLy8gQ29uc3RyYWludCBVdGlsc1xuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5mdW5jdGlvbiBhbGxDb25zdHJhaW50c1Bhc3MoY29uc3RyYWludHMsIHN1YmplY3RSYW5nZSwgb3RoZXJFdmVudFN0b3JlLCBidXNpbmVzc0hvdXJzVW5leHBhbmRlZCwgY29udGV4dCkge1xuICAgIGZvciAobGV0IGNvbnN0cmFpbnQgb2YgY29uc3RyYWludHMpIHtcbiAgICAgICAgaWYgKCFhbnlSYW5nZXNDb250YWluUmFuZ2UoY29uc3RyYWludFRvUmFuZ2VzKGNvbnN0cmFpbnQsIHN1YmplY3RSYW5nZSwgb3RoZXJFdmVudFN0b3JlLCBidXNpbmVzc0hvdXJzVW5leHBhbmRlZCwgY29udGV4dCksIHN1YmplY3RSYW5nZSkpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn1cbmZ1bmN0aW9uIGNvbnN0cmFpbnRUb1Jhbmdlcyhjb25zdHJhaW50LCBzdWJqZWN0UmFuZ2UsIC8vIGZvciBleHBhbmRpbmcgYSByZWN1cnJpbmcgY29uc3RyYWludCwgb3IgZXhwYW5kaW5nIGJ1c2luZXNzIGhvdXJzXG5vdGhlckV2ZW50U3RvcmUsIC8vIGZvciBpZiBjb25zdHJhaW50IGlzIGFuIGV2ZW4gZ3JvdXAgSURcbmJ1c2luZXNzSG91cnNVbmV4cGFuZGVkLCAvLyBmb3IgaWYgY29uc3RyYWludCBpcyAnYnVzaW5lc3NIb3VycydcbmNvbnRleHQpIHtcbiAgICBpZiAoY29uc3RyYWludCA9PT0gJ2J1c2luZXNzSG91cnMnKSB7XG4gICAgICAgIHJldHVybiBldmVudFN0b3JlVG9SYW5nZXMoZXhwYW5kUmVjdXJyaW5nKGJ1c2luZXNzSG91cnNVbmV4cGFuZGVkLCBzdWJqZWN0UmFuZ2UsIGNvbnRleHQpKTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBjb25zdHJhaW50ID09PSAnc3RyaW5nJykgeyAvLyBhbiBncm91cCBJRFxuICAgICAgICByZXR1cm4gZXZlbnRTdG9yZVRvUmFuZ2VzKGZpbHRlckV2ZW50U3RvcmVEZWZzKG90aGVyRXZlbnRTdG9yZSwgKGV2ZW50RGVmKSA9PiBldmVudERlZi5ncm91cElkID09PSBjb25zdHJhaW50KSk7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgY29uc3RyYWludCA9PT0gJ29iamVjdCcgJiYgY29uc3RyYWludCkgeyAvLyBub24tbnVsbCBvYmplY3RcbiAgICAgICAgcmV0dXJuIGV2ZW50U3RvcmVUb1JhbmdlcyhleHBhbmRSZWN1cnJpbmcoY29uc3RyYWludCwgc3ViamVjdFJhbmdlLCBjb250ZXh0KSk7XG4gICAgfVxuICAgIHJldHVybiBbXTsgLy8gaWYgaXQncyBmYWxzZVxufVxuLy8gVE9ETzogbW92ZSB0byBldmVudC1zdG9yZSBmaWxlP1xuZnVuY3Rpb24gZXZlbnRTdG9yZVRvUmFuZ2VzKGV2ZW50U3RvcmUpIHtcbiAgICBsZXQgeyBpbnN0YW5jZXMgfSA9IGV2ZW50U3RvcmU7XG4gICAgbGV0IHJhbmdlcyA9IFtdO1xuICAgIGZvciAobGV0IGluc3RhbmNlSWQgaW4gaW5zdGFuY2VzKSB7XG4gICAgICAgIHJhbmdlcy5wdXNoKGluc3RhbmNlc1tpbnN0YW5jZUlkXS5yYW5nZSk7XG4gICAgfVxuICAgIHJldHVybiByYW5nZXM7XG59XG4vLyBUT0RPOiBtb3ZlIHRvIGdlb20gZmlsZT9cbmZ1bmN0aW9uIGFueVJhbmdlc0NvbnRhaW5SYW5nZShvdXRlclJhbmdlcywgaW5uZXJSYW5nZSkge1xuICAgIGZvciAobGV0IG91dGVyUmFuZ2Ugb2Ygb3V0ZXJSYW5nZXMpIHtcbiAgICAgICAgaWYgKHJhbmdlQ29udGFpbnNSYW5nZShvdXRlclJhbmdlLCBpbm5lclJhbmdlKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuXG5jbGFzcyBKc29uUmVxdWVzdEVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICAgIGNvbnN0cnVjdG9yKG1lc3NhZ2UsIHJlc3BvbnNlKSB7XG4gICAgICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgICAgICB0aGlzLnJlc3BvbnNlID0gcmVzcG9uc2U7XG4gICAgfVxufVxuZnVuY3Rpb24gcmVxdWVzdEpzb24obWV0aG9kLCB1cmwsIHBhcmFtcykge1xuICAgIG1ldGhvZCA9IG1ldGhvZC50b1VwcGVyQ2FzZSgpO1xuICAgIGNvbnN0IGZldGNoT3B0aW9ucyA9IHtcbiAgICAgICAgbWV0aG9kLFxuICAgIH07XG4gICAgaWYgKG1ldGhvZCA9PT0gJ0dFVCcpIHtcbiAgICAgICAgdXJsICs9ICh1cmwuaW5kZXhPZignPycpID09PSAtMSA/ICc/JyA6ICcmJykgK1xuICAgICAgICAgICAgbmV3IFVSTFNlYXJjaFBhcmFtcyhwYXJhbXMpO1xuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgZmV0Y2hPcHRpb25zLmJvZHkgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKHBhcmFtcyk7XG4gICAgICAgIGZldGNoT3B0aW9ucy5oZWFkZXJzID0ge1xuICAgICAgICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnLFxuICAgICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4gZmV0Y2godXJsLCBmZXRjaE9wdGlvbnMpLnRoZW4oKGZldGNoUmVzKSA9PiB7XG4gICAgICAgIGlmIChmZXRjaFJlcy5vaykge1xuICAgICAgICAgICAgcmV0dXJuIGZldGNoUmVzLmpzb24oKS50aGVuKChwYXJzZWRSZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiBbcGFyc2VkUmVzcG9uc2UsIGZldGNoUmVzXTtcbiAgICAgICAgICAgIH0sICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgSnNvblJlcXVlc3RFcnJvcignRmFpbHVyZSBwYXJzaW5nIEpTT04nLCBmZXRjaFJlcyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBKc29uUmVxdWVzdEVycm9yKCdSZXF1ZXN0IGZhaWxlZCcsIGZldGNoUmVzKTtcbiAgICAgICAgfVxuICAgIH0pO1xufVxuXG5jbGFzcyBEZWxheWVkUnVubmVyIHtcbiAgICBjb25zdHJ1Y3RvcihkcmFpbmVkT3B0aW9uKSB7XG4gICAgICAgIHRoaXMuZHJhaW5lZE9wdGlvbiA9IGRyYWluZWRPcHRpb247XG4gICAgICAgIHRoaXMuaXNSdW5uaW5nID0gZmFsc2U7XG4gICAgICAgIHRoaXMuaXNEaXJ0eSA9IGZhbHNlO1xuICAgICAgICB0aGlzLnBhdXNlRGVwdGhzID0ge307XG4gICAgICAgIHRoaXMudGltZW91dElkID0gMDtcbiAgICB9XG4gICAgcmVxdWVzdChkZWxheSkge1xuICAgICAgICB0aGlzLmlzRGlydHkgPSB0cnVlO1xuICAgICAgICBpZiAoIXRoaXMuaXNQYXVzZWQoKSkge1xuICAgICAgICAgICAgdGhpcy5jbGVhclRpbWVvdXQoKTtcbiAgICAgICAgICAgIGlmIChkZWxheSA9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy50cnlEcmFpbigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy50aW1lb3V0SWQgPSBzZXRUaW1lb3V0KC8vIE5PVCBPUFRJTUFMISBUT0RPOiBsb29rIGF0IGRlYm91bmNlXG4gICAgICAgICAgICAgICAgdGhpcy50cnlEcmFpbi5iaW5kKHRoaXMpLCBkZWxheSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgcGF1c2Uoc2NvcGUgPSAnJykge1xuICAgICAgICBsZXQgeyBwYXVzZURlcHRocyB9ID0gdGhpcztcbiAgICAgICAgcGF1c2VEZXB0aHNbc2NvcGVdID0gKHBhdXNlRGVwdGhzW3Njb3BlXSB8fCAwKSArIDE7XG4gICAgICAgIHRoaXMuY2xlYXJUaW1lb3V0KCk7XG4gICAgfVxuICAgIHJlc3VtZShzY29wZSA9ICcnLCBmb3JjZSkge1xuICAgICAgICBsZXQgeyBwYXVzZURlcHRocyB9ID0gdGhpcztcbiAgICAgICAgaWYgKHNjb3BlIGluIHBhdXNlRGVwdGhzKSB7XG4gICAgICAgICAgICBpZiAoZm9yY2UpIHtcbiAgICAgICAgICAgICAgICBkZWxldGUgcGF1c2VEZXB0aHNbc2NvcGVdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgcGF1c2VEZXB0aHNbc2NvcGVdIC09IDE7XG4gICAgICAgICAgICAgICAgbGV0IGRlcHRoID0gcGF1c2VEZXB0aHNbc2NvcGVdO1xuICAgICAgICAgICAgICAgIGlmIChkZXB0aCA8PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBwYXVzZURlcHRoc1tzY29wZV07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy50cnlEcmFpbigpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlzUGF1c2VkKCkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmtleXModGhpcy5wYXVzZURlcHRocykubGVuZ3RoO1xuICAgIH1cbiAgICB0cnlEcmFpbigpIHtcbiAgICAgICAgaWYgKCF0aGlzLmlzUnVubmluZyAmJiAhdGhpcy5pc1BhdXNlZCgpKSB7XG4gICAgICAgICAgICB0aGlzLmlzUnVubmluZyA9IHRydWU7XG4gICAgICAgICAgICB3aGlsZSAodGhpcy5pc0RpcnR5KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pc0RpcnR5ID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgdGhpcy5kcmFpbmVkKCk7IC8vIG1pZ2h0IHNldCBpc0RpcnR5IHRvIHRydWUgYWdhaW5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuaXNSdW5uaW5nID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG4gICAgY2xlYXIoKSB7XG4gICAgICAgIHRoaXMuY2xlYXJUaW1lb3V0KCk7XG4gICAgICAgIHRoaXMuaXNEaXJ0eSA9IGZhbHNlO1xuICAgICAgICB0aGlzLnBhdXNlRGVwdGhzID0ge307XG4gICAgfVxuICAgIGNsZWFyVGltZW91dCgpIHtcbiAgICAgICAgaWYgKHRoaXMudGltZW91dElkKSB7XG4gICAgICAgICAgICBjbGVhclRpbWVvdXQodGhpcy50aW1lb3V0SWQpO1xuICAgICAgICAgICAgdGhpcy50aW1lb3V0SWQgPSAwO1xuICAgICAgICB9XG4gICAgfVxuICAgIGRyYWluZWQoKSB7XG4gICAgICAgIGlmICh0aGlzLmRyYWluZWRPcHRpb24pIHtcbiAgICAgICAgICAgIHRoaXMuZHJhaW5lZE9wdGlvbigpO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5jb25zdCBWSVNJQkxFX0hJRERFTl9SRSA9IC9eKHZpc2libGV8aGlkZGVuKSQvO1xuY2xhc3MgU2Nyb2xsZXIgZXh0ZW5kcyBCYXNlQ29tcG9uZW50IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5oYW5kbGVFbCA9IChlbCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5lbCA9IGVsO1xuICAgICAgICAgICAgc2V0UmVmKHRoaXMucHJvcHMuZWxSZWYsIGVsKTtcbiAgICAgICAgfTtcbiAgICB9XG4gICAgcmVuZGVyKCkge1xuICAgICAgICBsZXQgeyBwcm9wcyB9ID0gdGhpcztcbiAgICAgICAgbGV0IHsgbGlxdWlkLCBsaXF1aWRJc0Fic29sdXRlIH0gPSBwcm9wcztcbiAgICAgICAgbGV0IGlzQWJzb2x1dGUgPSBsaXF1aWQgJiYgbGlxdWlkSXNBYnNvbHV0ZTtcbiAgICAgICAgbGV0IGNsYXNzTmFtZSA9IFsnZmMtc2Nyb2xsZXInXTtcbiAgICAgICAgaWYgKGxpcXVpZCkge1xuICAgICAgICAgICAgaWYgKGxpcXVpZElzQWJzb2x1dGUpIHtcbiAgICAgICAgICAgICAgICBjbGFzc05hbWUucHVzaCgnZmMtc2Nyb2xsZXItbGlxdWlkLWFic29sdXRlJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBjbGFzc05hbWUucHVzaCgnZmMtc2Nyb2xsZXItbGlxdWlkJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIChjcmVhdGVFbGVtZW50KFwiZGl2XCIsIHsgcmVmOiB0aGlzLmhhbmRsZUVsLCBjbGFzc05hbWU6IGNsYXNzTmFtZS5qb2luKCcgJyksIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgb3ZlcmZsb3dYOiBwcm9wcy5vdmVyZmxvd1gsXG4gICAgICAgICAgICAgICAgb3ZlcmZsb3dZOiBwcm9wcy5vdmVyZmxvd1ksXG4gICAgICAgICAgICAgICAgbGVmdDogKGlzQWJzb2x1dGUgJiYgLShwcm9wcy5vdmVyY29tZUxlZnQgfHwgMCkpIHx8ICcnLFxuICAgICAgICAgICAgICAgIHJpZ2h0OiAoaXNBYnNvbHV0ZSAmJiAtKHByb3BzLm92ZXJjb21lUmlnaHQgfHwgMCkpIHx8ICcnLFxuICAgICAgICAgICAgICAgIGJvdHRvbTogKGlzQWJzb2x1dGUgJiYgLShwcm9wcy5vdmVyY29tZUJvdHRvbSB8fCAwKSkgfHwgJycsXG4gICAgICAgICAgICAgICAgbWFyZ2luTGVmdDogKCFpc0Fic29sdXRlICYmIC0ocHJvcHMub3ZlcmNvbWVMZWZ0IHx8IDApKSB8fCAnJyxcbiAgICAgICAgICAgICAgICBtYXJnaW5SaWdodDogKCFpc0Fic29sdXRlICYmIC0ocHJvcHMub3ZlcmNvbWVSaWdodCB8fCAwKSkgfHwgJycsXG4gICAgICAgICAgICAgICAgbWFyZ2luQm90dG9tOiAoIWlzQWJzb2x1dGUgJiYgLShwcm9wcy5vdmVyY29tZUJvdHRvbSB8fCAwKSkgfHwgJycsXG4gICAgICAgICAgICAgICAgbWF4SGVpZ2h0OiBwcm9wcy5tYXhIZWlnaHQgfHwgJycsXG4gICAgICAgICAgICB9IH0sIHByb3BzLmNoaWxkcmVuKSk7XG4gICAgfVxuICAgIG5lZWRzWFNjcm9sbGluZygpIHtcbiAgICAgICAgaWYgKFZJU0lCTEVfSElEREVOX1JFLnRlc3QodGhpcy5wcm9wcy5vdmVyZmxvd1gpKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgLy8gdGVzdGluZyBzY3JvbGxXaWR0aD5jbGllbnRXaWR0aCBpcyB1bnJlbGlhYmxlIGNyb3NzLWJyb3dzZXIgd2hlbiBwaXhlbCBoZWlnaHRzIGFyZW4ndCBpbnRlZ2Vycy5cbiAgICAgICAgLy8gbXVjaCBtb3JlIHJlbGlhYmxlIHRvIHNlZSBpZiBjaGlsZHJlbiBhcmUgdGFsbGVyIHRoYW4gdGhlIHNjcm9sbGVyLCBldmVuIHRobyBkb2Vzbid0IGFjY291bnQgZm9yXG4gICAgICAgIC8vIGlubmVyLWNoaWxkIG1hcmdpbnMgYW5kIGFic29sdXRlIHBvc2l0aW9uaW5nXG4gICAgICAgIGxldCB7IGVsIH0gPSB0aGlzO1xuICAgICAgICBsZXQgcmVhbENsaWVudFdpZHRoID0gdGhpcy5lbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS53aWR0aCAtIHRoaXMuZ2V0WVNjcm9sbGJhcldpZHRoKCk7XG4gICAgICAgIGxldCB7IGNoaWxkcmVuIH0gPSBlbDtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjaGlsZHJlbi5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICAgICAgbGV0IGNoaWxkRWwgPSBjaGlsZHJlbltpXTtcbiAgICAgICAgICAgIGlmIChjaGlsZEVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLndpZHRoID4gcmVhbENsaWVudFdpZHRoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBuZWVkc1lTY3JvbGxpbmcoKSB7XG4gICAgICAgIGlmIChWSVNJQkxFX0hJRERFTl9SRS50ZXN0KHRoaXMucHJvcHMub3ZlcmZsb3dZKSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIC8vIHRlc3Rpbmcgc2Nyb2xsSGVpZ2h0PmNsaWVudEhlaWdodCBpcyB1bnJlbGlhYmxlIGNyb3NzLWJyb3dzZXIgd2hlbiBwaXhlbCBoZWlnaHRzIGFyZW4ndCBpbnRlZ2Vycy5cbiAgICAgICAgLy8gbXVjaCBtb3JlIHJlbGlhYmxlIHRvIHNlZSBpZiBjaGlsZHJlbiBhcmUgdGFsbGVyIHRoYW4gdGhlIHNjcm9sbGVyLCBldmVuIHRobyBkb2Vzbid0IGFjY291bnQgZm9yXG4gICAgICAgIC8vIGlubmVyLWNoaWxkIG1hcmdpbnMgYW5kIGFic29sdXRlIHBvc2l0aW9uaW5nXG4gICAgICAgIGxldCB7IGVsIH0gPSB0aGlzO1xuICAgICAgICBsZXQgcmVhbENsaWVudEhlaWdodCA9IHRoaXMuZWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkuaGVpZ2h0IC0gdGhpcy5nZXRYU2Nyb2xsYmFyV2lkdGgoKTtcbiAgICAgICAgbGV0IHsgY2hpbGRyZW4gfSA9IGVsO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICBsZXQgY2hpbGRFbCA9IGNoaWxkcmVuW2ldO1xuICAgICAgICAgICAgaWYgKGNoaWxkRWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkuaGVpZ2h0ID4gcmVhbENsaWVudEhlaWdodCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgZ2V0WFNjcm9sbGJhcldpZHRoKCkge1xuICAgICAgICBpZiAoVklTSUJMRV9ISURERU5fUkUudGVzdCh0aGlzLnByb3BzLm92ZXJmbG93WCkpIHtcbiAgICAgICAgICAgIHJldHVybiAwO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmVsLm9mZnNldEhlaWdodCAtIHRoaXMuZWwuY2xpZW50SGVpZ2h0OyAvLyBvbmx5IHdvcmtzIGJlY2F1c2Ugd2UgZ3VhcmFudGVlIG5vIGJvcmRlcnMuIFRPRE86IGFkZCB0byBDU1Mgd2l0aCBpbXBvcnRhbnQ/XG4gICAgfVxuICAgIGdldFlTY3JvbGxiYXJXaWR0aCgpIHtcbiAgICAgICAgaWYgKFZJU0lCTEVfSElEREVOX1JFLnRlc3QodGhpcy5wcm9wcy5vdmVyZmxvd1kpKSB7XG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5lbC5vZmZzZXRXaWR0aCAtIHRoaXMuZWwuY2xpZW50V2lkdGg7IC8vIG9ubHkgd29ya3MgYmVjYXVzZSB3ZSBndWFyYW50ZWUgbm8gYm9yZGVycy4gVE9ETzogYWRkIHRvIENTUyB3aXRoIGltcG9ydGFudD9cbiAgICB9XG59XG5cbi8qXG5UT0RPOiBzb21laG93IGluZmVyIE90aGVyQXJncyBmcm9tIG1hc3RlckNhbGxiYWNrP1xuVE9ETzogaW5mZXIgUmVmVHlwZSBmcm9tIG1hc3RlckNhbGxiYWNrIGlmIHByb3ZpZGVkXG4qL1xuY2xhc3MgUmVmTWFwIHtcbiAgICBjb25zdHJ1Y3RvcihtYXN0ZXJDYWxsYmFjaykge1xuICAgICAgICB0aGlzLm1hc3RlckNhbGxiYWNrID0gbWFzdGVyQ2FsbGJhY2s7XG4gICAgICAgIHRoaXMuY3VycmVudE1hcCA9IHt9O1xuICAgICAgICB0aGlzLmRlcHRocyA9IHt9O1xuICAgICAgICB0aGlzLmNhbGxiYWNrTWFwID0ge307XG4gICAgICAgIHRoaXMuaGFuZGxlVmFsdWUgPSAodmFsLCBrZXkpID0+IHtcbiAgICAgICAgICAgIGxldCB7IGRlcHRocywgY3VycmVudE1hcCB9ID0gdGhpcztcbiAgICAgICAgICAgIGxldCByZW1vdmVkID0gZmFsc2U7XG4gICAgICAgICAgICBsZXQgYWRkZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGlmICh2YWwgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAvLyBmb3IgYnVnLi4uIEFDVFVBTExZOiBjYW4gcHJvYmFibHkgZG8gYXdheSB3aXRoIHRoaXMgbm93IHRoYXQgY2FsbGVycyBkb24ndCBzaGFyZSBudW1lcmljIGluZGljZXMgYW55bW9yZVxuICAgICAgICAgICAgICAgIHJlbW92ZWQgPSAoa2V5IGluIGN1cnJlbnRNYXApO1xuICAgICAgICAgICAgICAgIGN1cnJlbnRNYXBba2V5XSA9IHZhbDtcbiAgICAgICAgICAgICAgICBkZXB0aHNba2V5XSA9IChkZXB0aHNba2V5XSB8fCAwKSArIDE7XG4gICAgICAgICAgICAgICAgYWRkZWQgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgZGVwdGhzW2tleV0gLT0gMTtcbiAgICAgICAgICAgICAgICBpZiAoIWRlcHRoc1trZXldKSB7XG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBjdXJyZW50TWFwW2tleV07XG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSB0aGlzLmNhbGxiYWNrTWFwW2tleV07XG4gICAgICAgICAgICAgICAgICAgIHJlbW92ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLm1hc3RlckNhbGxiYWNrKSB7XG4gICAgICAgICAgICAgICAgaWYgKHJlbW92ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5tYXN0ZXJDYWxsYmFjayhudWxsLCBTdHJpbmcoa2V5KSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChhZGRlZCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm1hc3RlckNhbGxiYWNrKHZhbCwgU3RyaW5nKGtleSkpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9XG4gICAgY3JlYXRlUmVmKGtleSkge1xuICAgICAgICBsZXQgcmVmQ2FsbGJhY2sgPSB0aGlzLmNhbGxiYWNrTWFwW2tleV07XG4gICAgICAgIGlmICghcmVmQ2FsbGJhY2spIHtcbiAgICAgICAgICAgIHJlZkNhbGxiYWNrID0gdGhpcy5jYWxsYmFja01hcFtrZXldID0gKHZhbCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuaGFuZGxlVmFsdWUodmFsLCBTdHJpbmcoa2V5KSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZWZDYWxsYmFjaztcbiAgICB9XG4gICAgLy8gVE9ETzogY2hlY2sgY2FsbGVycyB0aGF0IGRvbid0IGNhcmUgYWJvdXQgb3JkZXIuIHNob3VsZCB1c2UgZ2V0QWxsIGluc3RlYWRcbiAgICAvLyBOT1RFOiB0aGlzIG1ldGhvZCBoYXMgYmVjb21lIGxlc3MgdmFsdWFibGUgbm93IHRoYXQgd2UgYXJlIGVuY291cmFnZWQgdG8gbWFwIG9yZGVyIGJ5IHNvbWUgb3RoZXIgaW5kZXhcbiAgICAvLyBUT0RPOiBwcm92aWRlIE9ORSBhcnJheS1leHBvcnQgZnVuY3Rpb24sIGJ1aWxkQXJyYXksIHdoaWNoIGZhaWxzIG9uIG5vbi1udW1lcmljIGluZGV4ZXMuIGNhbGxlciBjYW4gbWFuaXB1bGF0ZSBhbmQgXCJjb2xsZWN0XCJcbiAgICBjb2xsZWN0KHN0YXJ0SW5kZXgsIGVuZEluZGV4LCBzdGVwKSB7XG4gICAgICAgIHJldHVybiBjb2xsZWN0RnJvbUhhc2godGhpcy5jdXJyZW50TWFwLCBzdGFydEluZGV4LCBlbmRJbmRleCwgc3RlcCk7XG4gICAgfVxuICAgIGdldEFsbCgpIHtcbiAgICAgICAgcmV0dXJuIGhhc2hWYWx1ZXNUb0FycmF5KHRoaXMuY3VycmVudE1hcCk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBjb21wdXRlU2hyaW5rV2lkdGgoY2h1bmtFbHMpIHtcbiAgICBsZXQgc2hyaW5rQ2VsbHMgPSBmaW5kRWxlbWVudHMoY2h1bmtFbHMsICcuZmMtc2Nyb2xsZ3JpZC1zaHJpbmsnKTtcbiAgICBsZXQgbGFyZ2VzdFdpZHRoID0gMDtcbiAgICBmb3IgKGxldCBzaHJpbmtDZWxsIG9mIHNocmlua0NlbGxzKSB7XG4gICAgICAgIGxhcmdlc3RXaWR0aCA9IE1hdGgubWF4KGxhcmdlc3RXaWR0aCwgY29tcHV0ZVNtYWxsZXN0Q2VsbFdpZHRoKHNocmlua0NlbGwpKTtcbiAgICB9XG4gICAgcmV0dXJuIE1hdGguY2VpbChsYXJnZXN0V2lkdGgpOyAvLyA8dGFibGU+IGVsZW1lbnRzIHdvcmsgYmVzdCB3aXRoIGludGVnZXJzLiByb3VuZCB1cCB0byBlbnN1cmUgY29udGVudHMgZml0c1xufVxuZnVuY3Rpb24gZ2V0U2VjdGlvbkhhc0xpcXVpZEhlaWdodChwcm9wcywgc2VjdGlvbkNvbmZpZykge1xuICAgIHJldHVybiBwcm9wcy5saXF1aWQgJiYgc2VjdGlvbkNvbmZpZy5saXF1aWQ7IC8vIGRvZXMgdGhlIHNlY3Rpb24gZG8gbGlxdWlkLWhlaWdodD8gKG5lZWQgdG8gaGF2ZSB3aG9sZSBzY3JvbGxncmlkIGxpcXVpZC1oZWlnaHQgYXMgd2VsbClcbn1cbmZ1bmN0aW9uIGdldEFsbG93WVNjcm9sbGluZyhwcm9wcywgc2VjdGlvbkNvbmZpZykge1xuICAgIHJldHVybiBzZWN0aW9uQ29uZmlnLm1heEhlaWdodCAhPSBudWxsIHx8IC8vIGlmIGl0cyBwb3NzaWJsZSBmb3IgdGhlIGhlaWdodCB0byBtYXggb3V0LCB3ZSBtaWdodCBuZWVkIHNjcm9sbGJhcnNcbiAgICAgICAgZ2V0U2VjdGlvbkhhc0xpcXVpZEhlaWdodChwcm9wcywgc2VjdGlvbkNvbmZpZyk7IC8vIGlmIHRoZSBzZWN0aW9uIGlzIGxpcXVpZCBoZWlnaHQsIGl0IG1pZ2h0IGNvbmRlbnNlIGVub3VnaCB0byByZXF1aXJlIHNjcm9sbGJhcnNcbn1cbi8vIFRPRE86IE9OTFkgdXNlIGBhcmdgLiBmb3JjZSBvdXQgaW50ZXJuYWwgZnVuY3Rpb24gdG8gdXNlIHNhbWUgQVBJXG5mdW5jdGlvbiByZW5kZXJDaHVua0NvbnRlbnQoc2VjdGlvbkNvbmZpZywgY2h1bmtDb25maWcsIGFyZywgaXNIZWFkZXIpIHtcbiAgICBsZXQgeyBleHBhbmRSb3dzIH0gPSBhcmc7XG4gICAgbGV0IGNvbnRlbnQgPSB0eXBlb2YgY2h1bmtDb25maWcuY29udGVudCA9PT0gJ2Z1bmN0aW9uJyA/XG4gICAgICAgIGNodW5rQ29uZmlnLmNvbnRlbnQoYXJnKSA6XG4gICAgICAgIGNyZWF0ZUVsZW1lbnQoJ3RhYmxlJywge1xuICAgICAgICAgICAgcm9sZTogJ3ByZXNlbnRhdGlvbicsXG4gICAgICAgICAgICBjbGFzc05hbWU6IFtcbiAgICAgICAgICAgICAgICBjaHVua0NvbmZpZy50YWJsZUNsYXNzTmFtZSxcbiAgICAgICAgICAgICAgICBzZWN0aW9uQ29uZmlnLnN5bmNSb3dIZWlnaHRzID8gJ2ZjLXNjcm9sbGdyaWQtc3luYy10YWJsZScgOiAnJyxcbiAgICAgICAgICAgIF0uam9pbignICcpLFxuICAgICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICBtaW5XaWR0aDogYXJnLnRhYmxlTWluV2lkdGgsXG4gICAgICAgICAgICAgICAgd2lkdGg6IGFyZy5jbGllbnRXaWR0aCxcbiAgICAgICAgICAgICAgICBoZWlnaHQ6IGV4cGFuZFJvd3MgPyBhcmcuY2xpZW50SGVpZ2h0IDogJycsIC8vIGNzcyBgaGVpZ2h0YCBvbiBhIDx0YWJsZT4gc2VydmVzIGFzIGEgbWluLWhlaWdodFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSwgYXJnLnRhYmxlQ29sR3JvdXBOb2RlLCBjcmVhdGVFbGVtZW50KGlzSGVhZGVyID8gJ3RoZWFkJyA6ICd0Ym9keScsIHtcbiAgICAgICAgICAgIHJvbGU6ICdwcmVzZW50YXRpb24nLFxuICAgICAgICB9LCB0eXBlb2YgY2h1bmtDb25maWcucm93Q29udGVudCA9PT0gJ2Z1bmN0aW9uJ1xuICAgICAgICAgICAgPyBjaHVua0NvbmZpZy5yb3dDb250ZW50KGFyZylcbiAgICAgICAgICAgIDogY2h1bmtDb25maWcucm93Q29udGVudCkpO1xuICAgIHJldHVybiBjb250ZW50O1xufVxuZnVuY3Rpb24gaXNDb2xQcm9wc0VxdWFsKGNvbHMwLCBjb2xzMSkge1xuICAgIHJldHVybiBpc0FycmF5c0VxdWFsKGNvbHMwLCBjb2xzMSwgaXNQcm9wc0VxdWFsKTtcbn1cbmZ1bmN0aW9uIHJlbmRlck1pY3JvQ29sR3JvdXAoY29scywgc2hyaW5rV2lkdGgpIHtcbiAgICBsZXQgY29sTm9kZXMgPSBbXTtcbiAgICAvKlxuICAgIGZvciBDb2xQcm9wcyB3aXRoIHNwYW5zLCBpdCB3b3VsZCBoYXZlIGJlZW4gZ3JlYXQgdG8gbWFrZSBhIHNpbmdsZSA8Y29sIHNwYW49XCJcIj5cbiAgICBIT1dFVkVSLCBDaHJvbWUgd2FzIGdldHRpbmcgbWVzc2luZyB1cCBkaXN0cmlidXRpbmcgdGhlIHdpZHRoIHRvIDx0ZD4vPHRoPiBlbGVtZW50cyB3aXRoIGNvbHNwYW5zLlxuICAgIFNPTFVUSU9OOiBtYWtpbmcgaW5kaXZpZHVhbCA8Y29sPiBlbGVtZW50cyBtYWtlcyBDaHJvbWUgYmVoYXZlLlxuICAgICovXG4gICAgZm9yIChsZXQgY29sUHJvcHMgb2YgY29scykge1xuICAgICAgICBsZXQgc3BhbiA9IGNvbFByb3BzLnNwYW4gfHwgMTtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzcGFuOyBpICs9IDEpIHtcbiAgICAgICAgICAgIGNvbE5vZGVzLnB1c2goY3JlYXRlRWxlbWVudChcImNvbFwiLCB7IHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgIHdpZHRoOiBjb2xQcm9wcy53aWR0aCA9PT0gJ3NocmluaycgPyBzYW5pdGl6ZVNocmlua1dpZHRoKHNocmlua1dpZHRoKSA6IChjb2xQcm9wcy53aWR0aCB8fCAnJyksXG4gICAgICAgICAgICAgICAgICAgIG1pbldpZHRoOiBjb2xQcm9wcy5taW5XaWR0aCB8fCAnJyxcbiAgICAgICAgICAgICAgICB9IH0pKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gY3JlYXRlRWxlbWVudCgnY29sZ3JvdXAnLCB7fSwgLi4uY29sTm9kZXMpO1xufVxuZnVuY3Rpb24gc2FuaXRpemVTaHJpbmtXaWR0aChzaHJpbmtXaWR0aCkge1xuICAgIC8qIHdoeSA0PyBpZiB3ZSBkbyAwLCBpdCB3aWxsIGtpbGwgYW55IGJvcmRlciwgd2hpY2ggYXJlIG5lZWRlZCBmb3IgY29tcHV0ZVNtYWxsZXN0Q2VsbFdpZHRoXG4gICAgNCBhY2NvdW50cyBmb3IgMiAyLXBpeGVsIGJvcmRlcnMuIFRPRE86IGJldHRlciBzb2x1dGlvbj8gKi9cbiAgICByZXR1cm4gc2hyaW5rV2lkdGggPT0gbnVsbCA/IDQgOiBzaHJpbmtXaWR0aDtcbn1cbmZ1bmN0aW9uIGhhc1Nocmlua1dpZHRoKGNvbHMpIHtcbiAgICBmb3IgKGxldCBjb2wgb2YgY29scykge1xuICAgICAgICBpZiAoY29sLndpZHRoID09PSAnc2hyaW5rJykge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xufVxuZnVuY3Rpb24gZ2V0U2Nyb2xsR3JpZENsYXNzTmFtZXMobGlxdWlkLCBjb250ZXh0KSB7XG4gICAgbGV0IGNsYXNzTmFtZXMgPSBbXG4gICAgICAgICdmYy1zY3JvbGxncmlkJyxcbiAgICAgICAgY29udGV4dC50aGVtZS5nZXRDbGFzcygndGFibGUnKSxcbiAgICBdO1xuICAgIGlmIChsaXF1aWQpIHtcbiAgICAgICAgY2xhc3NOYW1lcy5wdXNoKCdmYy1zY3JvbGxncmlkLWxpcXVpZCcpO1xuICAgIH1cbiAgICByZXR1cm4gY2xhc3NOYW1lcztcbn1cbmZ1bmN0aW9uIGdldFNlY3Rpb25DbGFzc05hbWVzKHNlY3Rpb25Db25maWcsIHdob2xlVGFibGVWR3Jvdykge1xuICAgIGxldCBjbGFzc05hbWVzID0gW1xuICAgICAgICAnZmMtc2Nyb2xsZ3JpZC1zZWN0aW9uJyxcbiAgICAgICAgYGZjLXNjcm9sbGdyaWQtc2VjdGlvbi0ke3NlY3Rpb25Db25maWcudHlwZX1gLFxuICAgICAgICBzZWN0aW9uQ29uZmlnLmNsYXNzTmFtZSwgLy8gdXNlZD9cbiAgICBdO1xuICAgIGlmICh3aG9sZVRhYmxlVkdyb3cgJiYgc2VjdGlvbkNvbmZpZy5saXF1aWQgJiYgc2VjdGlvbkNvbmZpZy5tYXhIZWlnaHQgPT0gbnVsbCkge1xuICAgICAgICBjbGFzc05hbWVzLnB1c2goJ2ZjLXNjcm9sbGdyaWQtc2VjdGlvbi1saXF1aWQnKTtcbiAgICB9XG4gICAgaWYgKHNlY3Rpb25Db25maWcuaXNTdGlja3kpIHtcbiAgICAgICAgY2xhc3NOYW1lcy5wdXNoKCdmYy1zY3JvbGxncmlkLXNlY3Rpb24tc3RpY2t5Jyk7XG4gICAgfVxuICAgIHJldHVybiBjbGFzc05hbWVzO1xufVxuZnVuY3Rpb24gcmVuZGVyU2Nyb2xsU2hpbShhcmcpIHtcbiAgICByZXR1cm4gKGNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwgeyBjbGFzc05hbWU6IFwiZmMtc2Nyb2xsZ3JpZC1zdGlja3ktc2hpbVwiLCBzdHlsZToge1xuICAgICAgICAgICAgd2lkdGg6IGFyZy5jbGllbnRXaWR0aCxcbiAgICAgICAgICAgIG1pbldpZHRoOiBhcmcudGFibGVNaW5XaWR0aCxcbiAgICAgICAgfSB9KSk7XG59XG5mdW5jdGlvbiBnZXRTdGlja3lIZWFkZXJEYXRlcyhvcHRpb25zKSB7XG4gICAgbGV0IHsgc3RpY2t5SGVhZGVyRGF0ZXMgfSA9IG9wdGlvbnM7XG4gICAgaWYgKHN0aWNreUhlYWRlckRhdGVzID09IG51bGwgfHwgc3RpY2t5SGVhZGVyRGF0ZXMgPT09ICdhdXRvJykge1xuICAgICAgICBzdGlja3lIZWFkZXJEYXRlcyA9IG9wdGlvbnMuaGVpZ2h0ID09PSAnYXV0bycgfHwgb3B0aW9ucy52aWV3SGVpZ2h0ID09PSAnYXV0byc7XG4gICAgfVxuICAgIHJldHVybiBzdGlja3lIZWFkZXJEYXRlcztcbn1cbmZ1bmN0aW9uIGdldFN0aWNreUZvb3RlclNjcm9sbGJhcihvcHRpb25zKSB7XG4gICAgbGV0IHsgc3RpY2t5Rm9vdGVyU2Nyb2xsYmFyIH0gPSBvcHRpb25zO1xuICAgIGlmIChzdGlja3lGb290ZXJTY3JvbGxiYXIgPT0gbnVsbCB8fCBzdGlja3lGb290ZXJTY3JvbGxiYXIgPT09ICdhdXRvJykge1xuICAgICAgICBzdGlja3lGb290ZXJTY3JvbGxiYXIgPSBvcHRpb25zLmhlaWdodCA9PT0gJ2F1dG8nIHx8IG9wdGlvbnMudmlld0hlaWdodCA9PT0gJ2F1dG8nO1xuICAgIH1cbiAgICByZXR1cm4gc3RpY2t5Rm9vdGVyU2Nyb2xsYmFyO1xufVxuXG5jbGFzcyBTaW1wbGVTY3JvbGxHcmlkIGV4dGVuZHMgQmFzZUNvbXBvbmVudCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMucHJvY2Vzc0NvbHMgPSBtZW1vaXplKChhKSA9PiBhLCBpc0NvbFByb3BzRXF1YWwpOyAvLyBzbyB3ZSBnZXQgc2FtZSBgY29sc2AgcHJvcHMgZXZlcnkgdGltZVxuICAgICAgICAvLyB5dWNreSB0byBtZW1vaXplIFZOb2RlcywgYnV0IG11Y2ggbW9yZSBlZmZpY2llbnQgZm9yIGNvbnN1bWVyc1xuICAgICAgICB0aGlzLnJlbmRlck1pY3JvQ29sR3JvdXAgPSBtZW1vaXplKHJlbmRlck1pY3JvQ29sR3JvdXApO1xuICAgICAgICB0aGlzLnNjcm9sbGVyUmVmcyA9IG5ldyBSZWZNYXAoKTtcbiAgICAgICAgdGhpcy5zY3JvbGxlckVsUmVmcyA9IG5ldyBSZWZNYXAodGhpcy5faGFuZGxlU2Nyb2xsZXJFbC5iaW5kKHRoaXMpKTtcbiAgICAgICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgICAgICAgIHNocmlua1dpZHRoOiBudWxsLFxuICAgICAgICAgICAgZm9yY2VZU2Nyb2xsYmFyczogZmFsc2UsXG4gICAgICAgICAgICBzY3JvbGxlckNsaWVudFdpZHRoczoge30sXG4gICAgICAgICAgICBzY3JvbGxlckNsaWVudEhlaWdodHM6IHt9LFxuICAgICAgICB9O1xuICAgICAgICAvLyBUT0RPOiBjYW4gZG8gYSByZWFsbHkgc2ltcGxlIHByaW50LXZpZXcuIGRvbnQgbmVlZCB0byBqb2luIHJvd3NcbiAgICAgICAgdGhpcy5oYW5kbGVTaXppbmcgPSAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnNhZmVTZXRTdGF0ZShPYmplY3QuYXNzaWduKHsgc2hyaW5rV2lkdGg6IHRoaXMuY29tcHV0ZVNocmlua1dpZHRoKCkgfSwgdGhpcy5jb21wdXRlU2Nyb2xsZXJEaW1zKCkpKTtcbiAgICAgICAgfTtcbiAgICB9XG4gICAgcmVuZGVyKCkge1xuICAgICAgICBsZXQgeyBwcm9wcywgc3RhdGUsIGNvbnRleHQgfSA9IHRoaXM7XG4gICAgICAgIGxldCBzZWN0aW9uQ29uZmlncyA9IHByb3BzLnNlY3Rpb25zIHx8IFtdO1xuICAgICAgICBsZXQgY29scyA9IHRoaXMucHJvY2Vzc0NvbHMocHJvcHMuY29scyk7XG4gICAgICAgIGxldCBtaWNyb0NvbEdyb3VwTm9kZSA9IHRoaXMucmVuZGVyTWljcm9Db2xHcm91cChjb2xzLCBzdGF0ZS5zaHJpbmtXaWR0aCk7XG4gICAgICAgIGxldCBjbGFzc05hbWVzID0gZ2V0U2Nyb2xsR3JpZENsYXNzTmFtZXMocHJvcHMubGlxdWlkLCBjb250ZXh0KTtcbiAgICAgICAgaWYgKHByb3BzLmNvbGxhcHNpYmxlV2lkdGgpIHtcbiAgICAgICAgICAgIGNsYXNzTmFtZXMucHVzaCgnZmMtc2Nyb2xsZ3JpZC1jb2xsYXBzaWJsZScpO1xuICAgICAgICB9XG4gICAgICAgIC8vIFRPRE86IG1ha2UgRFJZXG4gICAgICAgIGxldCBjb25maWdDbnQgPSBzZWN0aW9uQ29uZmlncy5sZW5ndGg7XG4gICAgICAgIGxldCBjb25maWdJID0gMDtcbiAgICAgICAgbGV0IGN1cnJlbnRDb25maWc7XG4gICAgICAgIGxldCBoZWFkU2VjdGlvbk5vZGVzID0gW107XG4gICAgICAgIGxldCBib2R5U2VjdGlvbk5vZGVzID0gW107XG4gICAgICAgIGxldCBmb290U2VjdGlvbk5vZGVzID0gW107XG4gICAgICAgIHdoaWxlIChjb25maWdJIDwgY29uZmlnQ250ICYmIChjdXJyZW50Q29uZmlnID0gc2VjdGlvbkNvbmZpZ3NbY29uZmlnSV0pLnR5cGUgPT09ICdoZWFkZXInKSB7XG4gICAgICAgICAgICBoZWFkU2VjdGlvbk5vZGVzLnB1c2godGhpcy5yZW5kZXJTZWN0aW9uKGN1cnJlbnRDb25maWcsIG1pY3JvQ29sR3JvdXBOb2RlLCB0cnVlKSk7XG4gICAgICAgICAgICBjb25maWdJICs9IDE7XG4gICAgICAgIH1cbiAgICAgICAgd2hpbGUgKGNvbmZpZ0kgPCBjb25maWdDbnQgJiYgKGN1cnJlbnRDb25maWcgPSBzZWN0aW9uQ29uZmlnc1tjb25maWdJXSkudHlwZSA9PT0gJ2JvZHknKSB7XG4gICAgICAgICAgICBib2R5U2VjdGlvbk5vZGVzLnB1c2godGhpcy5yZW5kZXJTZWN0aW9uKGN1cnJlbnRDb25maWcsIG1pY3JvQ29sR3JvdXBOb2RlLCBmYWxzZSkpO1xuICAgICAgICAgICAgY29uZmlnSSArPSAxO1xuICAgICAgICB9XG4gICAgICAgIHdoaWxlIChjb25maWdJIDwgY29uZmlnQ250ICYmIChjdXJyZW50Q29uZmlnID0gc2VjdGlvbkNvbmZpZ3NbY29uZmlnSV0pLnR5cGUgPT09ICdmb290ZXInKSB7XG4gICAgICAgICAgICBmb290U2VjdGlvbk5vZGVzLnB1c2godGhpcy5yZW5kZXJTZWN0aW9uKGN1cnJlbnRDb25maWcsIG1pY3JvQ29sR3JvdXBOb2RlLCB0cnVlKSk7XG4gICAgICAgICAgICBjb25maWdJICs9IDE7XG4gICAgICAgIH1cbiAgICAgICAgLy8gZmlyZWZveCBidWc6IHdoZW4gc2V0dGluZyBoZWlnaHQgb24gdGFibGUgYW5kIHRoZXJlIGlzIGEgdGhlYWQgb3IgdGZvb3QsXG4gICAgICAgIC8vIHRoZSBuZWNlc3NhcnkgaGVpZ2h0OjEwMCUgb24gdGhlIGxpcXVpZC1oZWlnaHQgYm9keSBzZWN0aW9uIGZvcmNlcyB0aGUgKndob2xlKiB0YWJsZSB0byBiZSB0YWxsZXIuIChidWcgIzU1MjQpXG4gICAgICAgIC8vIHVzZSBnZXRDYW5WR3Jvd1dpdGhpbkNlbGwgYXMgYSB3YXkgdG8gZGV0ZWN0IHRhYmxlLXN0dXBpZCBmaXJlZm94LlxuICAgICAgICAvLyBpZiBzbywgdXNlIGEgc2ltcGxlciBkb20gc3RydWN0dXJlLCBqYW0gZXZlcnl0aGluZyBpbnRvIGEgbG9uZSB0Ym9keS5cbiAgICAgICAgbGV0IGlzQnVnZ3kgPSAhZ2V0Q2FuVkdyb3dXaXRoaW5DZWxsKCk7XG4gICAgICAgIGNvbnN0IHJvbGVBdHRycyA9IHsgcm9sZTogJ3Jvd2dyb3VwJyB9O1xuICAgICAgICByZXR1cm4gY3JlYXRlRWxlbWVudCgndGFibGUnLCB7XG4gICAgICAgICAgICByb2xlOiAnZ3JpZCcsXG4gICAgICAgICAgICBjbGFzc05hbWU6IGNsYXNzTmFtZXMuam9pbignICcpLFxuICAgICAgICAgICAgc3R5bGU6IHsgaGVpZ2h0OiBwcm9wcy5oZWlnaHQgfSxcbiAgICAgICAgfSwgQm9vbGVhbighaXNCdWdneSAmJiBoZWFkU2VjdGlvbk5vZGVzLmxlbmd0aCkgJiYgY3JlYXRlRWxlbWVudCgndGhlYWQnLCByb2xlQXR0cnMsIC4uLmhlYWRTZWN0aW9uTm9kZXMpLCBCb29sZWFuKCFpc0J1Z2d5ICYmIGJvZHlTZWN0aW9uTm9kZXMubGVuZ3RoKSAmJiBjcmVhdGVFbGVtZW50KCd0Ym9keScsIHJvbGVBdHRycywgLi4uYm9keVNlY3Rpb25Ob2RlcyksIEJvb2xlYW4oIWlzQnVnZ3kgJiYgZm9vdFNlY3Rpb25Ob2Rlcy5sZW5ndGgpICYmIGNyZWF0ZUVsZW1lbnQoJ3Rmb290Jywgcm9sZUF0dHJzLCAuLi5mb290U2VjdGlvbk5vZGVzKSwgaXNCdWdneSAmJiBjcmVhdGVFbGVtZW50KCd0Ym9keScsIHJvbGVBdHRycywgLi4uaGVhZFNlY3Rpb25Ob2RlcywgLi4uYm9keVNlY3Rpb25Ob2RlcywgLi4uZm9vdFNlY3Rpb25Ob2RlcykpO1xuICAgIH1cbiAgICByZW5kZXJTZWN0aW9uKHNlY3Rpb25Db25maWcsIG1pY3JvQ29sR3JvdXBOb2RlLCBpc0hlYWRlcikge1xuICAgICAgICBpZiAoJ291dGVyQ29udGVudCcgaW4gc2VjdGlvbkNvbmZpZykge1xuICAgICAgICAgICAgcmV0dXJuIChjcmVhdGVFbGVtZW50KEZyYWdtZW50LCB7IGtleTogc2VjdGlvbkNvbmZpZy5rZXkgfSwgc2VjdGlvbkNvbmZpZy5vdXRlckNvbnRlbnQpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gKGNyZWF0ZUVsZW1lbnQoXCJ0clwiLCB7IGtleTogc2VjdGlvbkNvbmZpZy5rZXksIHJvbGU6IFwicHJlc2VudGF0aW9uXCIsIGNsYXNzTmFtZTogZ2V0U2VjdGlvbkNsYXNzTmFtZXMoc2VjdGlvbkNvbmZpZywgdGhpcy5wcm9wcy5saXF1aWQpLmpvaW4oJyAnKSB9LCB0aGlzLnJlbmRlckNodW5rVGQoc2VjdGlvbkNvbmZpZywgbWljcm9Db2xHcm91cE5vZGUsIHNlY3Rpb25Db25maWcuY2h1bmssIGlzSGVhZGVyKSkpO1xuICAgIH1cbiAgICByZW5kZXJDaHVua1RkKHNlY3Rpb25Db25maWcsIG1pY3JvQ29sR3JvdXBOb2RlLCBjaHVua0NvbmZpZywgaXNIZWFkZXIpIHtcbiAgICAgICAgaWYgKCdvdXRlckNvbnRlbnQnIGluIGNodW5rQ29uZmlnKSB7XG4gICAgICAgICAgICByZXR1cm4gY2h1bmtDb25maWcub3V0ZXJDb250ZW50O1xuICAgICAgICB9XG4gICAgICAgIGxldCB7IHByb3BzIH0gPSB0aGlzO1xuICAgICAgICBsZXQgeyBmb3JjZVlTY3JvbGxiYXJzLCBzY3JvbGxlckNsaWVudFdpZHRocywgc2Nyb2xsZXJDbGllbnRIZWlnaHRzIH0gPSB0aGlzLnN0YXRlO1xuICAgICAgICBsZXQgbmVlZHNZU2Nyb2xsaW5nID0gZ2V0QWxsb3dZU2Nyb2xsaW5nKHByb3BzLCBzZWN0aW9uQ29uZmlnKTsgLy8gVE9ETzogZG8gbGF6aWx5LiBkbyBpbiBzZWN0aW9uIGNvbmZpZz9cbiAgICAgICAgbGV0IGlzTGlxdWlkID0gZ2V0U2VjdGlvbkhhc0xpcXVpZEhlaWdodChwcm9wcywgc2VjdGlvbkNvbmZpZyk7XG4gICAgICAgIC8vIGZvciBgIXByb3BzLmxpcXVpZGAgLSBpcyBXSE9MRSBzY3JvbGxncmlkIG5hdHVyYWwgaGVpZ2h0P1xuICAgICAgICAvLyBUT0RPOiBkbyBzYW1lIHRoaW5nIGluIGFkdmFuY2VkIHNjcm9sbGdyaWQ/IHByb2xseSBub3QgYi9jIGFsd2F5cyBoYXMgaG9yaXpvbnRhbCBzY3JvbGxiYXJzXG4gICAgICAgIGxldCBvdmVyZmxvd1kgPSAhcHJvcHMubGlxdWlkID8gJ3Zpc2libGUnIDpcbiAgICAgICAgICAgIGZvcmNlWVNjcm9sbGJhcnMgPyAnc2Nyb2xsJyA6XG4gICAgICAgICAgICAgICAgIW5lZWRzWVNjcm9sbGluZyA/ICdoaWRkZW4nIDpcbiAgICAgICAgICAgICAgICAgICAgJ2F1dG8nO1xuICAgICAgICBsZXQgc2VjdGlvbktleSA9IHNlY3Rpb25Db25maWcua2V5O1xuICAgICAgICBsZXQgY29udGVudCA9IHJlbmRlckNodW5rQ29udGVudChzZWN0aW9uQ29uZmlnLCBjaHVua0NvbmZpZywge1xuICAgICAgICAgICAgdGFibGVDb2xHcm91cE5vZGU6IG1pY3JvQ29sR3JvdXBOb2RlLFxuICAgICAgICAgICAgdGFibGVNaW5XaWR0aDogJycsXG4gICAgICAgICAgICBjbGllbnRXaWR0aDogKCFwcm9wcy5jb2xsYXBzaWJsZVdpZHRoICYmIHNjcm9sbGVyQ2xpZW50V2lkdGhzW3NlY3Rpb25LZXldICE9PSB1bmRlZmluZWQpID8gc2Nyb2xsZXJDbGllbnRXaWR0aHNbc2VjdGlvbktleV0gOiBudWxsLFxuICAgICAgICAgICAgY2xpZW50SGVpZ2h0OiBzY3JvbGxlckNsaWVudEhlaWdodHNbc2VjdGlvbktleV0gIT09IHVuZGVmaW5lZCA/IHNjcm9sbGVyQ2xpZW50SGVpZ2h0c1tzZWN0aW9uS2V5XSA6IG51bGwsXG4gICAgICAgICAgICBleHBhbmRSb3dzOiBzZWN0aW9uQ29uZmlnLmV4cGFuZFJvd3MsXG4gICAgICAgICAgICBzeW5jUm93SGVpZ2h0czogZmFsc2UsXG4gICAgICAgICAgICByb3dTeW5jSGVpZ2h0czogW10sXG4gICAgICAgICAgICByZXBvcnRSb3dIZWlnaHRDaGFuZ2U6ICgpID0+IHsgfSxcbiAgICAgICAgfSwgaXNIZWFkZXIpO1xuICAgICAgICByZXR1cm4gY3JlYXRlRWxlbWVudChpc0hlYWRlciA/ICd0aCcgOiAndGQnLCB7XG4gICAgICAgICAgICByZWY6IGNodW5rQ29uZmlnLmVsUmVmLFxuICAgICAgICAgICAgcm9sZTogJ3ByZXNlbnRhdGlvbicsXG4gICAgICAgIH0sIGNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwgeyBjbGFzc05hbWU6IGBmYy1zY3JvbGxlci1oYXJuZXNzJHtpc0xpcXVpZCA/ICcgZmMtc2Nyb2xsZXItaGFybmVzcy1saXF1aWQnIDogJyd9YCB9LFxuICAgICAgICAgICAgY3JlYXRlRWxlbWVudChTY3JvbGxlciwgeyByZWY6IHRoaXMuc2Nyb2xsZXJSZWZzLmNyZWF0ZVJlZihzZWN0aW9uS2V5KSwgZWxSZWY6IHRoaXMuc2Nyb2xsZXJFbFJlZnMuY3JlYXRlUmVmKHNlY3Rpb25LZXkpLCBvdmVyZmxvd1k6IG92ZXJmbG93WSwgb3ZlcmZsb3dYOiAhcHJvcHMubGlxdWlkID8gJ3Zpc2libGUnIDogJ2hpZGRlbicgLyogbmF0dXJhbCBoZWlnaHQ/ICovLCBtYXhIZWlnaHQ6IHNlY3Rpb25Db25maWcubWF4SGVpZ2h0LCBsaXF1aWQ6IGlzTGlxdWlkLCBsaXF1aWRJc0Fic29sdXRlIC8vIGJlY2F1c2UgaXRzIHdpdGhpbiBhIGhhcm5lc3NcbiAgICAgICAgICAgICAgICA6IHRydWUgfSwgY29udGVudCkpKTtcbiAgICB9XG4gICAgX2hhbmRsZVNjcm9sbGVyRWwoc2Nyb2xsZXJFbCwga2V5KSB7XG4gICAgICAgIGxldCBzZWN0aW9uID0gZ2V0U2VjdGlvbkJ5S2V5KHRoaXMucHJvcHMuc2VjdGlvbnMsIGtleSk7XG4gICAgICAgIGlmIChzZWN0aW9uKSB7XG4gICAgICAgICAgICBzZXRSZWYoc2VjdGlvbi5jaHVuay5zY3JvbGxlckVsUmVmLCBzY3JvbGxlckVsKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBjb21wb25lbnREaWRNb3VudCgpIHtcbiAgICAgICAgdGhpcy5oYW5kbGVTaXppbmcoKTtcbiAgICAgICAgdGhpcy5jb250ZXh0LmFkZFJlc2l6ZUhhbmRsZXIodGhpcy5oYW5kbGVTaXppbmcpO1xuICAgIH1cbiAgICBjb21wb25lbnREaWRVcGRhdGUoKSB7XG4gICAgICAgIC8vIFRPRE86IG5lZWQgYmV0dGVyIHNvbHV0aW9uIHdoZW4gc3RhdGUgY29udGFpbnMgbm9uLXNpemluZyB0aGluZ3NcbiAgICAgICAgdGhpcy5oYW5kbGVTaXppbmcoKTtcbiAgICB9XG4gICAgY29tcG9uZW50V2lsbFVubW91bnQoKSB7XG4gICAgICAgIHRoaXMuY29udGV4dC5yZW1vdmVSZXNpemVIYW5kbGVyKHRoaXMuaGFuZGxlU2l6aW5nKTtcbiAgICB9XG4gICAgY29tcHV0ZVNocmlua1dpZHRoKCkge1xuICAgICAgICByZXR1cm4gaGFzU2hyaW5rV2lkdGgodGhpcy5wcm9wcy5jb2xzKVxuICAgICAgICAgICAgPyBjb21wdXRlU2hyaW5rV2lkdGgodGhpcy5zY3JvbGxlckVsUmVmcy5nZXRBbGwoKSlcbiAgICAgICAgICAgIDogMDtcbiAgICB9XG4gICAgY29tcHV0ZVNjcm9sbGVyRGltcygpIHtcbiAgICAgICAgbGV0IHNjcm9sbGJhcldpZHRoID0gZ2V0U2Nyb2xsYmFyV2lkdGhzKCk7XG4gICAgICAgIGxldCB7IHNjcm9sbGVyUmVmcywgc2Nyb2xsZXJFbFJlZnMgfSA9IHRoaXM7XG4gICAgICAgIGxldCBmb3JjZVlTY3JvbGxiYXJzID0gZmFsc2U7XG4gICAgICAgIGxldCBzY3JvbGxlckNsaWVudFdpZHRocyA9IHt9O1xuICAgICAgICBsZXQgc2Nyb2xsZXJDbGllbnRIZWlnaHRzID0ge307XG4gICAgICAgIGZvciAobGV0IHNlY3Rpb25LZXkgaW4gc2Nyb2xsZXJSZWZzLmN1cnJlbnRNYXApIHtcbiAgICAgICAgICAgIGxldCBzY3JvbGxlciA9IHNjcm9sbGVyUmVmcy5jdXJyZW50TWFwW3NlY3Rpb25LZXldO1xuICAgICAgICAgICAgaWYgKHNjcm9sbGVyICYmIHNjcm9sbGVyLm5lZWRzWVNjcm9sbGluZygpKSB7XG4gICAgICAgICAgICAgICAgZm9yY2VZU2Nyb2xsYmFycyA9IHRydWU7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChsZXQgc2VjdGlvbiBvZiB0aGlzLnByb3BzLnNlY3Rpb25zKSB7XG4gICAgICAgICAgICBsZXQgc2VjdGlvbktleSA9IHNlY3Rpb24ua2V5O1xuICAgICAgICAgICAgbGV0IHNjcm9sbGVyRWwgPSBzY3JvbGxlckVsUmVmcy5jdXJyZW50TWFwW3NlY3Rpb25LZXldO1xuICAgICAgICAgICAgaWYgKHNjcm9sbGVyRWwpIHtcbiAgICAgICAgICAgICAgICBsZXQgaGFybmVzc0VsID0gc2Nyb2xsZXJFbC5wYXJlbnROb2RlOyAvLyBUT0RPOiB3ZWlyZCB3YXkgdG8gZ2V0IHRoaXMuIG5lZWQgaGFybmVzcyBiL2MgZG9lc24ndCBpbmNsdWRlIHRhYmxlIGJvcmRlcnNcbiAgICAgICAgICAgICAgICBzY3JvbGxlckNsaWVudFdpZHRoc1tzZWN0aW9uS2V5XSA9IE1hdGguZmxvb3IoaGFybmVzc0VsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLndpZHRoIC0gKGZvcmNlWVNjcm9sbGJhcnNcbiAgICAgICAgICAgICAgICAgICAgPyBzY3JvbGxiYXJXaWR0aC55IC8vIHVzZSBnbG9iYWwgYmVjYXVzZSBzY3JvbGxlciBtaWdodCBub3QgaGF2ZSBzY3JvbGxiYXJzIHlldCBidXQgd2lsbCBuZWVkIHRoZW0gaW4gZnV0dXJlXG4gICAgICAgICAgICAgICAgICAgIDogMCkpO1xuICAgICAgICAgICAgICAgIHNjcm9sbGVyQ2xpZW50SGVpZ2h0c1tzZWN0aW9uS2V5XSA9IE1hdGguZmxvb3IoaGFybmVzc0VsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLmhlaWdodCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsgZm9yY2VZU2Nyb2xsYmFycywgc2Nyb2xsZXJDbGllbnRXaWR0aHMsIHNjcm9sbGVyQ2xpZW50SGVpZ2h0cyB9O1xuICAgIH1cbn1cblNpbXBsZVNjcm9sbEdyaWQuYWRkU3RhdGVFcXVhbGl0eSh7XG4gICAgc2Nyb2xsZXJDbGllbnRXaWR0aHM6IGlzUHJvcHNFcXVhbCxcbiAgICBzY3JvbGxlckNsaWVudEhlaWdodHM6IGlzUHJvcHNFcXVhbCxcbn0pO1xuZnVuY3Rpb24gZ2V0U2VjdGlvbkJ5S2V5KHNlY3Rpb25zLCBrZXkpIHtcbiAgICBmb3IgKGxldCBzZWN0aW9uIG9mIHNlY3Rpb25zKSB7XG4gICAgICAgIGlmIChzZWN0aW9uLmtleSA9PT0ga2V5KSB7XG4gICAgICAgICAgICByZXR1cm4gc2VjdGlvbjtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbn1cblxuY2xhc3MgRXZlbnRDb250YWluZXIgZXh0ZW5kcyBCYXNlQ29tcG9uZW50IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5oYW5kbGVFbCA9IChlbCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5lbCA9IGVsO1xuICAgICAgICAgICAgaWYgKGVsKSB7XG4gICAgICAgICAgICAgICAgc2V0RWxTZWcoZWwsIHRoaXMucHJvcHMuc2VnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9XG4gICAgcmVuZGVyKCkge1xuICAgICAgICBjb25zdCB7IHByb3BzLCBjb250ZXh0IH0gPSB0aGlzO1xuICAgICAgICBjb25zdCB7IG9wdGlvbnMgfSA9IGNvbnRleHQ7XG4gICAgICAgIGNvbnN0IHsgc2VnIH0gPSBwcm9wcztcbiAgICAgICAgY29uc3QgeyBldmVudFJhbmdlIH0gPSBzZWc7XG4gICAgICAgIGNvbnN0IHsgdWkgfSA9IGV2ZW50UmFuZ2U7XG4gICAgICAgIGNvbnN0IHJlbmRlclByb3BzID0ge1xuICAgICAgICAgICAgZXZlbnQ6IG5ldyBFdmVudEltcGwoY29udGV4dCwgZXZlbnRSYW5nZS5kZWYsIGV2ZW50UmFuZ2UuaW5zdGFuY2UpLFxuICAgICAgICAgICAgdmlldzogY29udGV4dC52aWV3QXBpLFxuICAgICAgICAgICAgdGltZVRleHQ6IHByb3BzLnRpbWVUZXh0LFxuICAgICAgICAgICAgdGV4dENvbG9yOiB1aS50ZXh0Q29sb3IsXG4gICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IHVpLmJhY2tncm91bmRDb2xvcixcbiAgICAgICAgICAgIGJvcmRlckNvbG9yOiB1aS5ib3JkZXJDb2xvcixcbiAgICAgICAgICAgIGlzRHJhZ2dhYmxlOiAhcHJvcHMuZGlzYWJsZURyYWdnaW5nICYmIGNvbXB1dGVTZWdEcmFnZ2FibGUoc2VnLCBjb250ZXh0KSxcbiAgICAgICAgICAgIGlzU3RhcnRSZXNpemFibGU6ICFwcm9wcy5kaXNhYmxlUmVzaXppbmcgJiYgY29tcHV0ZVNlZ1N0YXJ0UmVzaXphYmxlKHNlZywgY29udGV4dCksXG4gICAgICAgICAgICBpc0VuZFJlc2l6YWJsZTogIXByb3BzLmRpc2FibGVSZXNpemluZyAmJiBjb21wdXRlU2VnRW5kUmVzaXphYmxlKHNlZyksXG4gICAgICAgICAgICBpc01pcnJvcjogQm9vbGVhbihwcm9wcy5pc0RyYWdnaW5nIHx8IHByb3BzLmlzUmVzaXppbmcgfHwgcHJvcHMuaXNEYXRlU2VsZWN0aW5nKSxcbiAgICAgICAgICAgIGlzU3RhcnQ6IEJvb2xlYW4oc2VnLmlzU3RhcnQpLFxuICAgICAgICAgICAgaXNFbmQ6IEJvb2xlYW4oc2VnLmlzRW5kKSxcbiAgICAgICAgICAgIGlzUGFzdDogQm9vbGVhbihwcm9wcy5pc1Bhc3QpLFxuICAgICAgICAgICAgaXNGdXR1cmU6IEJvb2xlYW4ocHJvcHMuaXNGdXR1cmUpLFxuICAgICAgICAgICAgaXNUb2RheTogQm9vbGVhbihwcm9wcy5pc1RvZGF5KSxcbiAgICAgICAgICAgIGlzU2VsZWN0ZWQ6IEJvb2xlYW4ocHJvcHMuaXNTZWxlY3RlZCksXG4gICAgICAgICAgICBpc0RyYWdnaW5nOiBCb29sZWFuKHByb3BzLmlzRHJhZ2dpbmcpLFxuICAgICAgICAgICAgaXNSZXNpemluZzogQm9vbGVhbihwcm9wcy5pc1Jlc2l6aW5nKSxcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIChjcmVhdGVFbGVtZW50KENvbnRlbnRDb250YWluZXIsIE9iamVjdC5hc3NpZ24oe30sIHByb3BzIC8qIGNvbnRhaW5zIGNoaWxkcmVuICovLCB7IGVsUmVmOiB0aGlzLmhhbmRsZUVsLCBlbENsYXNzZXM6IFtcbiAgICAgICAgICAgICAgICAuLi5nZXRFdmVudENsYXNzTmFtZXMocmVuZGVyUHJvcHMpLFxuICAgICAgICAgICAgICAgIC4uLnNlZy5ldmVudFJhbmdlLnVpLmNsYXNzTmFtZXMsXG4gICAgICAgICAgICAgICAgLi4uKHByb3BzLmVsQ2xhc3NlcyB8fCBbXSksXG4gICAgICAgICAgICBdLCByZW5kZXJQcm9wczogcmVuZGVyUHJvcHMsIGdlbmVyYXRvck5hbWU6IFwiZXZlbnRDb250ZW50XCIsIGdlbmVyYXRvcjogb3B0aW9ucy5ldmVudENvbnRlbnQgfHwgcHJvcHMuZGVmYXVsdEdlbmVyYXRvciwgY2xhc3NOYW1lR2VuZXJhdG9yOiBvcHRpb25zLmV2ZW50Q2xhc3NOYW1lcywgZGlkTW91bnQ6IG9wdGlvbnMuZXZlbnREaWRNb3VudCwgd2lsbFVubW91bnQ6IG9wdGlvbnMuZXZlbnRXaWxsVW5tb3VudCB9KSkpO1xuICAgIH1cbiAgICBjb21wb25lbnREaWRVcGRhdGUocHJldlByb3BzKSB7XG4gICAgICAgIGlmICh0aGlzLmVsICYmIHRoaXMucHJvcHMuc2VnICE9PSBwcmV2UHJvcHMuc2VnKSB7XG4gICAgICAgICAgICBzZXRFbFNlZyh0aGlzLmVsLCB0aGlzLnByb3BzLnNlZyk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbi8vIHNob3VsZCBub3QgYmUgYSBwdXJlY29tcG9uZW50XG5jbGFzcyBTdGFuZGFyZEV2ZW50IGV4dGVuZHMgQmFzZUNvbXBvbmVudCB7XG4gICAgcmVuZGVyKCkge1xuICAgICAgICBsZXQgeyBwcm9wcywgY29udGV4dCB9ID0gdGhpcztcbiAgICAgICAgbGV0IHsgb3B0aW9ucyB9ID0gY29udGV4dDtcbiAgICAgICAgbGV0IHsgc2VnIH0gPSBwcm9wcztcbiAgICAgICAgbGV0IHsgdWkgfSA9IHNlZy5ldmVudFJhbmdlO1xuICAgICAgICBsZXQgdGltZUZvcm1hdCA9IG9wdGlvbnMuZXZlbnRUaW1lRm9ybWF0IHx8IHByb3BzLmRlZmF1bHRUaW1lRm9ybWF0O1xuICAgICAgICBsZXQgdGltZVRleHQgPSBidWlsZFNlZ1RpbWVUZXh0KHNlZywgdGltZUZvcm1hdCwgY29udGV4dCwgcHJvcHMuZGVmYXVsdERpc3BsYXlFdmVudFRpbWUsIHByb3BzLmRlZmF1bHREaXNwbGF5RXZlbnRFbmQpO1xuICAgICAgICByZXR1cm4gKGNyZWF0ZUVsZW1lbnQoRXZlbnRDb250YWluZXIsIE9iamVjdC5hc3NpZ24oe30sIHByb3BzIC8qIGluY2x1ZGVzIGVsUmVmICovLCB7IGVsVGFnOiBcImFcIiwgZWxTdHlsZToge1xuICAgICAgICAgICAgICAgIGJvcmRlckNvbG9yOiB1aS5ib3JkZXJDb2xvcixcbiAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IHVpLmJhY2tncm91bmRDb2xvcixcbiAgICAgICAgICAgIH0sIGVsQXR0cnM6IGdldFNlZ0FuY2hvckF0dHJzKHNlZywgY29udGV4dCksIGRlZmF1bHRHZW5lcmF0b3I6IHJlbmRlcklubmVyQ29udGVudCQxLCB0aW1lVGV4dDogdGltZVRleHQgfSksIChJbm5lckNvbnRlbnQsIGV2ZW50Q29udGVudEFyZykgPT4gKGNyZWF0ZUVsZW1lbnQoRnJhZ21lbnQsIG51bGwsXG4gICAgICAgICAgICBjcmVhdGVFbGVtZW50KElubmVyQ29udGVudCwgeyBlbFRhZzogXCJkaXZcIiwgZWxDbGFzc2VzOiBbJ2ZjLWV2ZW50LW1haW4nXSwgZWxTdHlsZTogeyBjb2xvcjogZXZlbnRDb250ZW50QXJnLnRleHRDb2xvciB9IH0pLFxuICAgICAgICAgICAgQm9vbGVhbihldmVudENvbnRlbnRBcmcuaXNTdGFydFJlc2l6YWJsZSkgJiYgKGNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwgeyBjbGFzc05hbWU6IFwiZmMtZXZlbnQtcmVzaXplciBmYy1ldmVudC1yZXNpemVyLXN0YXJ0XCIgfSkpLFxuICAgICAgICAgICAgQm9vbGVhbihldmVudENvbnRlbnRBcmcuaXNFbmRSZXNpemFibGUpICYmIChjcmVhdGVFbGVtZW50KFwiZGl2XCIsIHsgY2xhc3NOYW1lOiBcImZjLWV2ZW50LXJlc2l6ZXIgZmMtZXZlbnQtcmVzaXplci1lbmRcIiB9KSkpKSkpO1xuICAgIH1cbn1cbmZ1bmN0aW9uIHJlbmRlcklubmVyQ29udGVudCQxKGlubmVyUHJvcHMpIHtcbiAgICByZXR1cm4gKGNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwgeyBjbGFzc05hbWU6IFwiZmMtZXZlbnQtbWFpbi1mcmFtZVwiIH0sXG4gICAgICAgIGlubmVyUHJvcHMudGltZVRleHQgJiYgKGNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwgeyBjbGFzc05hbWU6IFwiZmMtZXZlbnQtdGltZVwiIH0sIGlubmVyUHJvcHMudGltZVRleHQpKSxcbiAgICAgICAgY3JlYXRlRWxlbWVudChcImRpdlwiLCB7IGNsYXNzTmFtZTogXCJmYy1ldmVudC10aXRsZS1jb250YWluZXJcIiB9LFxuICAgICAgICAgICAgY3JlYXRlRWxlbWVudChcImRpdlwiLCB7IGNsYXNzTmFtZTogXCJmYy1ldmVudC10aXRsZSBmYy1zdGlja3lcIiB9LCBpbm5lclByb3BzLmV2ZW50LnRpdGxlIHx8IGNyZWF0ZUVsZW1lbnQoRnJhZ21lbnQsIG51bGwsIFwiXFx1MDBBMFwiKSkpKSk7XG59XG5cbmNvbnN0IE5vd0luZGljYXRvckNvbnRhaW5lciA9IChwcm9wcykgPT4gKGNyZWF0ZUVsZW1lbnQoVmlld0NvbnRleHRUeXBlLkNvbnN1bWVyLCBudWxsLCAoY29udGV4dCkgPT4ge1xuICAgIGxldCB7IG9wdGlvbnMgfSA9IGNvbnRleHQ7XG4gICAgbGV0IHJlbmRlclByb3BzID0ge1xuICAgICAgICBpc0F4aXM6IHByb3BzLmlzQXhpcyxcbiAgICAgICAgZGF0ZTogY29udGV4dC5kYXRlRW52LnRvRGF0ZShwcm9wcy5kYXRlKSxcbiAgICAgICAgdmlldzogY29udGV4dC52aWV3QXBpLFxuICAgIH07XG4gICAgcmV0dXJuIChjcmVhdGVFbGVtZW50KENvbnRlbnRDb250YWluZXIsIE9iamVjdC5hc3NpZ24oe30sIHByb3BzIC8qIGluY2x1ZGVzIGNoaWxkcmVuICovLCB7IGVsVGFnOiBwcm9wcy5lbFRhZyB8fCAnZGl2JywgcmVuZGVyUHJvcHM6IHJlbmRlclByb3BzLCBnZW5lcmF0b3JOYW1lOiBcIm5vd0luZGljYXRvckNvbnRlbnRcIiwgZ2VuZXJhdG9yOiBvcHRpb25zLm5vd0luZGljYXRvckNvbnRlbnQsIGNsYXNzTmFtZUdlbmVyYXRvcjogb3B0aW9ucy5ub3dJbmRpY2F0b3JDbGFzc05hbWVzLCBkaWRNb3VudDogb3B0aW9ucy5ub3dJbmRpY2F0b3JEaWRNb3VudCwgd2lsbFVubW91bnQ6IG9wdGlvbnMubm93SW5kaWNhdG9yV2lsbFVubW91bnQgfSkpKTtcbn0pKTtcblxuY29uc3QgREFZX05VTV9GT1JNQVQgPSBjcmVhdGVGb3JtYXR0ZXIoeyBkYXk6ICdudW1lcmljJyB9KTtcbmNsYXNzIERheUNlbGxDb250YWluZXIgZXh0ZW5kcyBCYXNlQ29tcG9uZW50IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5yZWZpbmVSZW5kZXJQcm9wcyA9IG1lbW9pemVPYmpBcmcocmVmaW5lUmVuZGVyUHJvcHMpO1xuICAgIH1cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGxldCB7IHByb3BzLCBjb250ZXh0IH0gPSB0aGlzO1xuICAgICAgICBsZXQgeyBvcHRpb25zIH0gPSBjb250ZXh0O1xuICAgICAgICBsZXQgcmVuZGVyUHJvcHMgPSB0aGlzLnJlZmluZVJlbmRlclByb3BzKHtcbiAgICAgICAgICAgIGRhdGU6IHByb3BzLmRhdGUsXG4gICAgICAgICAgICBkYXRlUHJvZmlsZTogcHJvcHMuZGF0ZVByb2ZpbGUsXG4gICAgICAgICAgICB0b2RheVJhbmdlOiBwcm9wcy50b2RheVJhbmdlLFxuICAgICAgICAgICAgc2hvd0RheU51bWJlcjogcHJvcHMuc2hvd0RheU51bWJlcixcbiAgICAgICAgICAgIGV4dHJhUmVuZGVyUHJvcHM6IHByb3BzLmV4dHJhUmVuZGVyUHJvcHMsXG4gICAgICAgICAgICB2aWV3QXBpOiBjb250ZXh0LnZpZXdBcGksXG4gICAgICAgICAgICBkYXRlRW52OiBjb250ZXh0LmRhdGVFbnYsXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gKGNyZWF0ZUVsZW1lbnQoQ29udGVudENvbnRhaW5lciwgT2JqZWN0LmFzc2lnbih7fSwgcHJvcHMgLyogaW5jbHVkZXMgY2hpbGRyZW4gKi8sIHsgZWxDbGFzc2VzOiBbXG4gICAgICAgICAgICAgICAgLi4uZ2V0RGF5Q2xhc3NOYW1lcyhyZW5kZXJQcm9wcywgY29udGV4dC50aGVtZSksXG4gICAgICAgICAgICAgICAgLi4uKHByb3BzLmVsQ2xhc3NlcyB8fCBbXSksXG4gICAgICAgICAgICBdLCBlbEF0dHJzOiBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sIHByb3BzLmVsQXR0cnMpLCAocmVuZGVyUHJvcHMuaXNEaXNhYmxlZCA/IHt9IDogeyAnZGF0YS1kYXRlJzogZm9ybWF0RGF5U3RyaW5nKHByb3BzLmRhdGUpIH0pKSwgcmVuZGVyUHJvcHM6IHJlbmRlclByb3BzLCBnZW5lcmF0b3JOYW1lOiBcImRheUNlbGxDb250ZW50XCIsIGdlbmVyYXRvcjogb3B0aW9ucy5kYXlDZWxsQ29udGVudCB8fCBwcm9wcy5kZWZhdWx0R2VuZXJhdG9yLCBjbGFzc05hbWVHZW5lcmF0b3I6IFxuICAgICAgICAgICAgLy8gZG9uJ3QgdXNlIGN1c3RvbSBjbGFzc05hbWVzIGlmIGRpc2FibGVkXG4gICAgICAgICAgICByZW5kZXJQcm9wcy5pc0Rpc2FibGVkID8gdW5kZWZpbmVkIDogb3B0aW9ucy5kYXlDZWxsQ2xhc3NOYW1lcywgZGlkTW91bnQ6IG9wdGlvbnMuZGF5Q2VsbERpZE1vdW50LCB3aWxsVW5tb3VudDogb3B0aW9ucy5kYXlDZWxsV2lsbFVubW91bnQgfSkpKTtcbiAgICB9XG59XG5mdW5jdGlvbiBoYXNDdXN0b21EYXlDZWxsQ29udGVudChvcHRpb25zKSB7XG4gICAgcmV0dXJuIEJvb2xlYW4ob3B0aW9ucy5kYXlDZWxsQ29udGVudCB8fCBoYXNDdXN0b21SZW5kZXJpbmdIYW5kbGVyKCdkYXlDZWxsQ29udGVudCcsIG9wdGlvbnMpKTtcbn1cbmZ1bmN0aW9uIHJlZmluZVJlbmRlclByb3BzKHJhdykge1xuICAgIGxldCB7IGRhdGUsIGRhdGVFbnYgfSA9IHJhdztcbiAgICBsZXQgZGF5TWV0YSA9IGdldERhdGVNZXRhKGRhdGUsIHJhdy50b2RheVJhbmdlLCBudWxsLCByYXcuZGF0ZVByb2ZpbGUpO1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7IGRhdGU6IGRhdGVFbnYudG9EYXRlKGRhdGUpLCB2aWV3OiByYXcudmlld0FwaSB9LCBkYXlNZXRhKSwgeyBkYXlOdW1iZXJUZXh0OiByYXcuc2hvd0RheU51bWJlciA/IGRhdGVFbnYuZm9ybWF0KGRhdGUsIERBWV9OVU1fRk9STUFUKSA6ICcnIH0pLCByYXcuZXh0cmFSZW5kZXJQcm9wcyk7XG59XG5cbmNsYXNzIEJnRXZlbnQgZXh0ZW5kcyBCYXNlQ29tcG9uZW50IHtcbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGxldCB7IHByb3BzIH0gPSB0aGlzO1xuICAgICAgICBsZXQgeyBzZWcgfSA9IHByb3BzO1xuICAgICAgICByZXR1cm4gKGNyZWF0ZUVsZW1lbnQoRXZlbnRDb250YWluZXIsIHsgZWxUYWc6IFwiZGl2XCIsIGVsQ2xhc3NlczogWydmYy1iZy1ldmVudCddLCBlbFN0eWxlOiB7IGJhY2tncm91bmRDb2xvcjogc2VnLmV2ZW50UmFuZ2UudWkuYmFja2dyb3VuZENvbG9yIH0sIGRlZmF1bHRHZW5lcmF0b3I6IHJlbmRlcklubmVyQ29udGVudCwgc2VnOiBzZWcsIHRpbWVUZXh0OiBcIlwiLCBpc0RyYWdnaW5nOiBmYWxzZSwgaXNSZXNpemluZzogZmFsc2UsIGlzRGF0ZVNlbGVjdGluZzogZmFsc2UsIGlzU2VsZWN0ZWQ6IGZhbHNlLCBpc1Bhc3Q6IHByb3BzLmlzUGFzdCwgaXNGdXR1cmU6IHByb3BzLmlzRnV0dXJlLCBpc1RvZGF5OiBwcm9wcy5pc1RvZGF5LCBkaXNhYmxlRHJhZ2dpbmc6IHRydWUsIGRpc2FibGVSZXNpemluZzogdHJ1ZSB9KSk7XG4gICAgfVxufVxuZnVuY3Rpb24gcmVuZGVySW5uZXJDb250ZW50KHByb3BzKSB7XG4gICAgbGV0IHsgdGl0bGUgfSA9IHByb3BzLmV2ZW50O1xuICAgIHJldHVybiB0aXRsZSAmJiAoY3JlYXRlRWxlbWVudChcImRpdlwiLCB7IGNsYXNzTmFtZTogXCJmYy1ldmVudC10aXRsZVwiIH0sIHByb3BzLmV2ZW50LnRpdGxlKSk7XG59XG5mdW5jdGlvbiByZW5kZXJGaWxsKGZpbGxUeXBlKSB7XG4gICAgcmV0dXJuIChjcmVhdGVFbGVtZW50KFwiZGl2XCIsIHsgY2xhc3NOYW1lOiBgZmMtJHtmaWxsVHlwZX1gIH0pKTtcbn1cblxuY29uc3QgV2Vla051bWJlckNvbnRhaW5lciA9IChwcm9wcykgPT4gKGNyZWF0ZUVsZW1lbnQoVmlld0NvbnRleHRUeXBlLkNvbnN1bWVyLCBudWxsLCAoY29udGV4dCkgPT4ge1xuICAgIGxldCB7IGRhdGVFbnYsIG9wdGlvbnMgfSA9IGNvbnRleHQ7XG4gICAgbGV0IHsgZGF0ZSB9ID0gcHJvcHM7XG4gICAgbGV0IGZvcm1hdCA9IG9wdGlvbnMud2Vla051bWJlckZvcm1hdCB8fCBwcm9wcy5kZWZhdWx0Rm9ybWF0O1xuICAgIGxldCBudW0gPSBkYXRlRW52LmNvbXB1dGVXZWVrTnVtYmVyKGRhdGUpOyAvLyBUT0RPOiBzb21laG93IHVzZSBmb3IgZm9ybWF0dGluZyBhcyB3ZWxsP1xuICAgIGxldCB0ZXh0ID0gZGF0ZUVudi5mb3JtYXQoZGF0ZSwgZm9ybWF0KTtcbiAgICBsZXQgcmVuZGVyUHJvcHMgPSB7IG51bSwgdGV4dCwgZGF0ZSB9O1xuICAgIHJldHVybiAoY3JlYXRlRWxlbWVudChDb250ZW50Q29udGFpbmVyIC8vIHdoeSBpc24ndCBXZWVrTnVtYmVyQ29udGVudEFyZyBiZWluZyBhdXRvLWRldGVjdGVkP1xuICAgICwgT2JqZWN0LmFzc2lnbih7fSwgcHJvcHMgLyogaW5jbHVkZXMgY2hpbGRyZW4gKi8sIHsgcmVuZGVyUHJvcHM6IHJlbmRlclByb3BzLCBnZW5lcmF0b3JOYW1lOiBcIndlZWtOdW1iZXJDb250ZW50XCIsIGdlbmVyYXRvcjogb3B0aW9ucy53ZWVrTnVtYmVyQ29udGVudCB8fCByZW5kZXJJbm5lciwgY2xhc3NOYW1lR2VuZXJhdG9yOiBvcHRpb25zLndlZWtOdW1iZXJDbGFzc05hbWVzLCBkaWRNb3VudDogb3B0aW9ucy53ZWVrTnVtYmVyRGlkTW91bnQsIHdpbGxVbm1vdW50OiBvcHRpb25zLndlZWtOdW1iZXJXaWxsVW5tb3VudCB9KSkpO1xufSkpO1xuZnVuY3Rpb24gcmVuZGVySW5uZXIoaW5uZXJQcm9wcykge1xuICAgIHJldHVybiBpbm5lclByb3BzLnRleHQ7XG59XG5cbmNvbnN0IFBBRERJTkdfRlJPTV9WSUVXUE9SVCA9IDEwO1xuY2xhc3MgUG9wb3ZlciBleHRlbmRzIEJhc2VDb21wb25lbnQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLnN0YXRlID0ge1xuICAgICAgICAgICAgdGl0bGVJZDogZ2V0VW5pcXVlRG9tSWQoKSxcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5oYW5kbGVSb290RWwgPSAoZWwpID0+IHtcbiAgICAgICAgICAgIHRoaXMucm9vdEVsID0gZWw7XG4gICAgICAgICAgICBpZiAodGhpcy5wcm9wcy5lbFJlZikge1xuICAgICAgICAgICAgICAgIHNldFJlZih0aGlzLnByb3BzLmVsUmVmLCBlbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIC8vIFRyaWdnZXJlZCB3aGVuIHRoZSB1c2VyIGNsaWNrcyAqYW55d2hlcmUqIGluIHRoZSBkb2N1bWVudCwgZm9yIHRoZSBhdXRvSGlkZSBmZWF0dXJlXG4gICAgICAgIHRoaXMuaGFuZGxlRG9jdW1lbnRNb3VzZURvd24gPSAoZXYpID0+IHtcbiAgICAgICAgICAgIC8vIG9ubHkgaGlkZSB0aGUgcG9wb3ZlciBpZiB0aGUgY2xpY2sgaGFwcGVuZWQgb3V0c2lkZSB0aGUgcG9wb3ZlclxuICAgICAgICAgICAgY29uc3QgdGFyZ2V0ID0gZ2V0RXZlbnRUYXJnZXRWaWFSb290KGV2KTtcbiAgICAgICAgICAgIGlmICghdGhpcy5yb290RWwuY29udGFpbnModGFyZ2V0KSkge1xuICAgICAgICAgICAgICAgIHRoaXMuaGFuZGxlQ2xvc2VDbGljaygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICB0aGlzLmhhbmRsZURvY3VtZW50S2V5RG93biA9IChldikgPT4ge1xuICAgICAgICAgICAgaWYgKGV2LmtleSA9PT0gJ0VzY2FwZScpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmhhbmRsZUNsb3NlQ2xpY2soKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5oYW5kbGVDbG9zZUNsaWNrID0gKCkgPT4ge1xuICAgICAgICAgICAgbGV0IHsgb25DbG9zZSB9ID0gdGhpcy5wcm9wcztcbiAgICAgICAgICAgIGlmIChvbkNsb3NlKSB7XG4gICAgICAgICAgICAgICAgb25DbG9zZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH1cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGxldCB7IHRoZW1lLCBvcHRpb25zIH0gPSB0aGlzLmNvbnRleHQ7XG4gICAgICAgIGxldCB7IHByb3BzLCBzdGF0ZSB9ID0gdGhpcztcbiAgICAgICAgbGV0IGNsYXNzTmFtZXMgPSBbXG4gICAgICAgICAgICAnZmMtcG9wb3ZlcicsXG4gICAgICAgICAgICB0aGVtZS5nZXRDbGFzcygncG9wb3ZlcicpLFxuICAgICAgICBdLmNvbmNhdChwcm9wcy5leHRyYUNsYXNzTmFtZXMgfHwgW10pO1xuICAgICAgICByZXR1cm4gY3JlYXRlUG9ydGFsKGNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwgT2JqZWN0LmFzc2lnbih7fSwgcHJvcHMuZXh0cmFBdHRycywgeyBpZDogcHJvcHMuaWQsIGNsYXNzTmFtZTogY2xhc3NOYW1lcy5qb2luKCcgJyksIFwiYXJpYS1sYWJlbGxlZGJ5XCI6IHN0YXRlLnRpdGxlSWQsIHJlZjogdGhpcy5oYW5kbGVSb290RWwgfSksXG4gICAgICAgICAgICBjcmVhdGVFbGVtZW50KFwiZGl2XCIsIHsgY2xhc3NOYW1lOiAnZmMtcG9wb3Zlci1oZWFkZXIgJyArIHRoZW1lLmdldENsYXNzKCdwb3BvdmVySGVhZGVyJykgfSxcbiAgICAgICAgICAgICAgICBjcmVhdGVFbGVtZW50KFwic3BhblwiLCB7IGNsYXNzTmFtZTogXCJmYy1wb3BvdmVyLXRpdGxlXCIsIGlkOiBzdGF0ZS50aXRsZUlkIH0sIHByb3BzLnRpdGxlKSxcbiAgICAgICAgICAgICAgICBjcmVhdGVFbGVtZW50KFwic3BhblwiLCB7IGNsYXNzTmFtZTogJ2ZjLXBvcG92ZXItY2xvc2UgJyArIHRoZW1lLmdldEljb25DbGFzcygnY2xvc2UnKSwgdGl0bGU6IG9wdGlvbnMuY2xvc2VIaW50LCBvbkNsaWNrOiB0aGlzLmhhbmRsZUNsb3NlQ2xpY2sgfSkpLFxuICAgICAgICAgICAgY3JlYXRlRWxlbWVudChcImRpdlwiLCB7IGNsYXNzTmFtZTogJ2ZjLXBvcG92ZXItYm9keSAnICsgdGhlbWUuZ2V0Q2xhc3MoJ3BvcG92ZXJDb250ZW50JykgfSwgcHJvcHMuY2hpbGRyZW4pKSwgcHJvcHMucGFyZW50RWwpO1xuICAgIH1cbiAgICBjb21wb25lbnREaWRNb3VudCgpIHtcbiAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgdGhpcy5oYW5kbGVEb2N1bWVudE1vdXNlRG93bik7XG4gICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCB0aGlzLmhhbmRsZURvY3VtZW50S2V5RG93bik7XG4gICAgICAgIHRoaXMudXBkYXRlU2l6ZSgpO1xuICAgIH1cbiAgICBjb21wb25lbnRXaWxsVW5tb3VudCgpIHtcbiAgICAgICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgdGhpcy5oYW5kbGVEb2N1bWVudE1vdXNlRG93bik7XG4gICAgICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCB0aGlzLmhhbmRsZURvY3VtZW50S2V5RG93bik7XG4gICAgfVxuICAgIHVwZGF0ZVNpemUoKSB7XG4gICAgICAgIGxldCB7IGlzUnRsIH0gPSB0aGlzLmNvbnRleHQ7XG4gICAgICAgIGxldCB7IGFsaWdubWVudEVsLCBhbGlnbkdyaWRUb3AgfSA9IHRoaXMucHJvcHM7XG4gICAgICAgIGxldCB7IHJvb3RFbCB9ID0gdGhpcztcbiAgICAgICAgbGV0IGFsaWdubWVudFJlY3QgPSBjb21wdXRlQ2xpcHBlZENsaWVudFJlY3QoYWxpZ25tZW50RWwpO1xuICAgICAgICBpZiAoYWxpZ25tZW50UmVjdCkge1xuICAgICAgICAgICAgbGV0IHBvcG92ZXJEaW1zID0gcm9vdEVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgICAgICAgLy8gcG9zaXRpb24gcmVsYXRpdmUgdG8gdmlld3BvcnRcbiAgICAgICAgICAgIGxldCBwb3BvdmVyVG9wID0gYWxpZ25HcmlkVG9wXG4gICAgICAgICAgICAgICAgPyBlbGVtZW50Q2xvc2VzdChhbGlnbm1lbnRFbCwgJy5mYy1zY3JvbGxncmlkJykuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkudG9wXG4gICAgICAgICAgICAgICAgOiBhbGlnbm1lbnRSZWN0LnRvcDtcbiAgICAgICAgICAgIGxldCBwb3BvdmVyTGVmdCA9IGlzUnRsID8gYWxpZ25tZW50UmVjdC5yaWdodCAtIHBvcG92ZXJEaW1zLndpZHRoIDogYWxpZ25tZW50UmVjdC5sZWZ0O1xuICAgICAgICAgICAgLy8gY29uc3RyYWluXG4gICAgICAgICAgICBwb3BvdmVyVG9wID0gTWF0aC5tYXgocG9wb3ZlclRvcCwgUEFERElOR19GUk9NX1ZJRVdQT1JUKTtcbiAgICAgICAgICAgIHBvcG92ZXJMZWZ0ID0gTWF0aC5taW4ocG9wb3ZlckxlZnQsIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRXaWR0aCAtIFBBRERJTkdfRlJPTV9WSUVXUE9SVCAtIHBvcG92ZXJEaW1zLndpZHRoKTtcbiAgICAgICAgICAgIHBvcG92ZXJMZWZ0ID0gTWF0aC5tYXgocG9wb3ZlckxlZnQsIFBBRERJTkdfRlJPTV9WSUVXUE9SVCk7XG4gICAgICAgICAgICBsZXQgb3JpZ2luID0gcm9vdEVsLm9mZnNldFBhcmVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgICAgICAgIGFwcGx5U3R5bGUocm9vdEVsLCB7XG4gICAgICAgICAgICAgICAgdG9wOiBwb3BvdmVyVG9wIC0gb3JpZ2luLnRvcCxcbiAgICAgICAgICAgICAgICBsZWZ0OiBwb3BvdmVyTGVmdCAtIG9yaWdpbi5sZWZ0LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmNsYXNzIE1vcmVQb3BvdmVyIGV4dGVuZHMgRGF0ZUNvbXBvbmVudCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMuaGFuZGxlUm9vdEVsID0gKHJvb3RFbCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5yb290RWwgPSByb290RWw7XG4gICAgICAgICAgICBpZiAocm9vdEVsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jb250ZXh0LnJlZ2lzdGVySW50ZXJhY3RpdmVDb21wb25lbnQodGhpcywge1xuICAgICAgICAgICAgICAgICAgICBlbDogcm9vdEVsLFxuICAgICAgICAgICAgICAgICAgICB1c2VFdmVudENlbnRlcjogZmFsc2UsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbnRleHQudW5yZWdpc3RlckludGVyYWN0aXZlQ29tcG9uZW50KHRoaXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH1cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGxldCB7IG9wdGlvbnMsIGRhdGVFbnYgfSA9IHRoaXMuY29udGV4dDtcbiAgICAgICAgbGV0IHsgcHJvcHMgfSA9IHRoaXM7XG4gICAgICAgIGxldCB7IHN0YXJ0RGF0ZSwgdG9kYXlSYW5nZSwgZGF0ZVByb2ZpbGUgfSA9IHByb3BzO1xuICAgICAgICBsZXQgdGl0bGUgPSBkYXRlRW52LmZvcm1hdChzdGFydERhdGUsIG9wdGlvbnMuZGF5UG9wb3ZlckZvcm1hdCk7XG4gICAgICAgIHJldHVybiAoY3JlYXRlRWxlbWVudChEYXlDZWxsQ29udGFpbmVyLCB7IGVsUmVmOiB0aGlzLmhhbmRsZVJvb3RFbCwgZGF0ZTogc3RhcnREYXRlLCBkYXRlUHJvZmlsZTogZGF0ZVByb2ZpbGUsIHRvZGF5UmFuZ2U6IHRvZGF5UmFuZ2UgfSwgKElubmVyQ29udGVudCwgcmVuZGVyUHJvcHMsIGVsQXR0cnMpID0+IChjcmVhdGVFbGVtZW50KFBvcG92ZXIsIHsgZWxSZWY6IGVsQXR0cnMucmVmLCBpZDogcHJvcHMuaWQsIHRpdGxlOiB0aXRsZSwgZXh0cmFDbGFzc05hbWVzOiBbJ2ZjLW1vcmUtcG9wb3ZlciddLmNvbmNhdChlbEF0dHJzLmNsYXNzTmFtZSB8fCBbXSksIGV4dHJhQXR0cnM6IGVsQXR0cnMgLyogVE9ETzogbWFrZSB0aGVzZSB0aW1lLWJhc2VkIHdoZW4gbm90IHdob2xlLWRheT8gKi8sIHBhcmVudEVsOiBwcm9wcy5wYXJlbnRFbCwgYWxpZ25tZW50RWw6IHByb3BzLmFsaWdubWVudEVsLCBhbGlnbkdyaWRUb3A6IHByb3BzLmFsaWduR3JpZFRvcCwgb25DbG9zZTogcHJvcHMub25DbG9zZSB9LFxuICAgICAgICAgICAgaGFzQ3VzdG9tRGF5Q2VsbENvbnRlbnQob3B0aW9ucykgJiYgKGNyZWF0ZUVsZW1lbnQoSW5uZXJDb250ZW50LCB7IGVsVGFnOiBcImRpdlwiLCBlbENsYXNzZXM6IFsnZmMtbW9yZS1wb3BvdmVyLW1pc2MnXSB9KSksXG4gICAgICAgICAgICBwcm9wcy5jaGlsZHJlbikpKSk7XG4gICAgfVxuICAgIHF1ZXJ5SGl0KHBvc2l0aW9uTGVmdCwgcG9zaXRpb25Ub3AsIGVsV2lkdGgsIGVsSGVpZ2h0KSB7XG4gICAgICAgIGxldCB7IHJvb3RFbCwgcHJvcHMgfSA9IHRoaXM7XG4gICAgICAgIGlmIChwb3NpdGlvbkxlZnQgPj0gMCAmJiBwb3NpdGlvbkxlZnQgPCBlbFdpZHRoICYmXG4gICAgICAgICAgICBwb3NpdGlvblRvcCA+PSAwICYmIHBvc2l0aW9uVG9wIDwgZWxIZWlnaHQpIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgZGF0ZVByb2ZpbGU6IHByb3BzLmRhdGVQcm9maWxlLFxuICAgICAgICAgICAgICAgIGRhdGVTcGFuOiBPYmplY3QuYXNzaWduKHsgYWxsRGF5OiB0cnVlLCByYW5nZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3RhcnQ6IHByb3BzLnN0YXJ0RGF0ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGVuZDogcHJvcHMuZW5kRGF0ZSxcbiAgICAgICAgICAgICAgICAgICAgfSB9LCBwcm9wcy5leHRyYURhdGVTcGFuKSxcbiAgICAgICAgICAgICAgICBkYXlFbDogcm9vdEVsLFxuICAgICAgICAgICAgICAgIHJlY3Q6IHtcbiAgICAgICAgICAgICAgICAgICAgbGVmdDogMCxcbiAgICAgICAgICAgICAgICAgICAgdG9wOiAwLFxuICAgICAgICAgICAgICAgICAgICByaWdodDogZWxXaWR0aCxcbiAgICAgICAgICAgICAgICAgICAgYm90dG9tOiBlbEhlaWdodCxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGxheWVyOiAxLCAvLyBpbXBvcnRhbnQgd2hlbiBjb21wYXJpbmcgd2l0aCBoaXRzIGZyb20gb3RoZXIgY29tcG9uZW50c1xuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG59XG5cbmNsYXNzIE1vcmVMaW5rQ29udGFpbmVyIGV4dGVuZHMgQmFzZUNvbXBvbmVudCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMuc3RhdGUgPSB7XG4gICAgICAgICAgICBpc1BvcG92ZXJPcGVuOiBmYWxzZSxcbiAgICAgICAgICAgIHBvcG92ZXJJZDogZ2V0VW5pcXVlRG9tSWQoKSxcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5oYW5kbGVMaW5rRWwgPSAobGlua0VsKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmxpbmtFbCA9IGxpbmtFbDtcbiAgICAgICAgICAgIGlmICh0aGlzLnByb3BzLmVsUmVmKSB7XG4gICAgICAgICAgICAgICAgc2V0UmVmKHRoaXMucHJvcHMuZWxSZWYsIGxpbmtFbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuaGFuZGxlQ2xpY2sgPSAoZXYpID0+IHtcbiAgICAgICAgICAgIGxldCB7IHByb3BzLCBjb250ZXh0IH0gPSB0aGlzO1xuICAgICAgICAgICAgbGV0IHsgbW9yZUxpbmtDbGljayB9ID0gY29udGV4dC5vcHRpb25zO1xuICAgICAgICAgICAgbGV0IGRhdGUgPSBjb21wdXRlUmFuZ2UocHJvcHMpLnN0YXJ0O1xuICAgICAgICAgICAgZnVuY3Rpb24gYnVpbGRQdWJsaWNTZWcoc2VnKSB7XG4gICAgICAgICAgICAgICAgbGV0IHsgZGVmLCBpbnN0YW5jZSwgcmFuZ2UgfSA9IHNlZy5ldmVudFJhbmdlO1xuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50OiBuZXcgRXZlbnRJbXBsKGNvbnRleHQsIGRlZiwgaW5zdGFuY2UpLFxuICAgICAgICAgICAgICAgICAgICBzdGFydDogY29udGV4dC5kYXRlRW52LnRvRGF0ZShyYW5nZS5zdGFydCksXG4gICAgICAgICAgICAgICAgICAgIGVuZDogY29udGV4dC5kYXRlRW52LnRvRGF0ZShyYW5nZS5lbmQpLFxuICAgICAgICAgICAgICAgICAgICBpc1N0YXJ0OiBzZWcuaXNTdGFydCxcbiAgICAgICAgICAgICAgICAgICAgaXNFbmQ6IHNlZy5pc0VuZCxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHR5cGVvZiBtb3JlTGlua0NsaWNrID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgbW9yZUxpbmtDbGljayA9IG1vcmVMaW5rQ2xpY2soe1xuICAgICAgICAgICAgICAgICAgICBkYXRlLFxuICAgICAgICAgICAgICAgICAgICBhbGxEYXk6IEJvb2xlYW4ocHJvcHMuYWxsRGF5RGF0ZSksXG4gICAgICAgICAgICAgICAgICAgIGFsbFNlZ3M6IHByb3BzLmFsbFNlZ3MubWFwKGJ1aWxkUHVibGljU2VnKSxcbiAgICAgICAgICAgICAgICAgICAgaGlkZGVuU2VnczogcHJvcHMuaGlkZGVuU2Vncy5tYXAoYnVpbGRQdWJsaWNTZWcpLFxuICAgICAgICAgICAgICAgICAgICBqc0V2ZW50OiBldixcbiAgICAgICAgICAgICAgICAgICAgdmlldzogY29udGV4dC52aWV3QXBpLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFtb3JlTGlua0NsaWNrIHx8IG1vcmVMaW5rQ2xpY2sgPT09ICdwb3BvdmVyJykge1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoeyBpc1BvcG92ZXJPcGVuOiB0cnVlIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAodHlwZW9mIG1vcmVMaW5rQ2xpY2sgPT09ICdzdHJpbmcnKSB7IC8vIGEgdmlldyBuYW1lXG4gICAgICAgICAgICAgICAgY29udGV4dC5jYWxlbmRhckFwaS56b29tVG8oZGF0ZSwgbW9yZUxpbmtDbGljayk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuaGFuZGxlUG9wb3ZlckNsb3NlID0gKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGlzUG9wb3Zlck9wZW46IGZhbHNlIH0pO1xuICAgICAgICB9O1xuICAgIH1cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGxldCB7IHByb3BzLCBzdGF0ZSB9ID0gdGhpcztcbiAgICAgICAgcmV0dXJuIChjcmVhdGVFbGVtZW50KFZpZXdDb250ZXh0VHlwZS5Db25zdW1lciwgbnVsbCwgKGNvbnRleHQpID0+IHtcbiAgICAgICAgICAgIGxldCB7IHZpZXdBcGksIG9wdGlvbnMsIGNhbGVuZGFyQXBpIH0gPSBjb250ZXh0O1xuICAgICAgICAgICAgbGV0IHsgbW9yZUxpbmtUZXh0IH0gPSBvcHRpb25zO1xuICAgICAgICAgICAgbGV0IHsgbW9yZUNudCB9ID0gcHJvcHM7XG4gICAgICAgICAgICBsZXQgcmFuZ2UgPSBjb21wdXRlUmFuZ2UocHJvcHMpO1xuICAgICAgICAgICAgbGV0IHRleHQgPSB0eXBlb2YgbW9yZUxpbmtUZXh0ID09PSAnZnVuY3Rpb24nIC8vIFRPRE86IGV2ZW50dWFsbHkgdXNlIGZvcm1hdFdpdGhPcmRpbmFsc1xuICAgICAgICAgICAgICAgID8gbW9yZUxpbmtUZXh0LmNhbGwoY2FsZW5kYXJBcGksIG1vcmVDbnQpXG4gICAgICAgICAgICAgICAgOiBgKyR7bW9yZUNudH0gJHttb3JlTGlua1RleHR9YDtcbiAgICAgICAgICAgIGxldCBoaW50ID0gZm9ybWF0V2l0aE9yZGluYWxzKG9wdGlvbnMubW9yZUxpbmtIaW50LCBbbW9yZUNudF0sIHRleHQpO1xuICAgICAgICAgICAgbGV0IHJlbmRlclByb3BzID0ge1xuICAgICAgICAgICAgICAgIG51bTogbW9yZUNudCxcbiAgICAgICAgICAgICAgICBzaG9ydFRleHQ6IGArJHttb3JlQ250fWAsXG4gICAgICAgICAgICAgICAgdGV4dCxcbiAgICAgICAgICAgICAgICB2aWV3OiB2aWV3QXBpLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHJldHVybiAoY3JlYXRlRWxlbWVudChGcmFnbWVudCwgbnVsbCxcbiAgICAgICAgICAgICAgICBCb29sZWFuKHByb3BzLm1vcmVDbnQpICYmIChjcmVhdGVFbGVtZW50KENvbnRlbnRDb250YWluZXIsIHsgZWxUYWc6IHByb3BzLmVsVGFnIHx8ICdhJywgZWxSZWY6IHRoaXMuaGFuZGxlTGlua0VsLCBlbENsYXNzZXM6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgIC4uLihwcm9wcy5lbENsYXNzZXMgfHwgW10pLFxuICAgICAgICAgICAgICAgICAgICAgICAgJ2ZjLW1vcmUtbGluaycsXG4gICAgICAgICAgICAgICAgICAgIF0sIGVsU3R5bGU6IHByb3BzLmVsU3R5bGUsIGVsQXR0cnM6IE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCBwcm9wcy5lbEF0dHJzKSwgY3JlYXRlQXJpYUNsaWNrQXR0cnModGhpcy5oYW5kbGVDbGljaykpLCB7IHRpdGxlOiBoaW50LCAnYXJpYS1leHBhbmRlZCc6IHN0YXRlLmlzUG9wb3Zlck9wZW4sICdhcmlhLWNvbnRyb2xzJzogc3RhdGUuaXNQb3BvdmVyT3BlbiA/IHN0YXRlLnBvcG92ZXJJZCA6ICcnIH0pLCByZW5kZXJQcm9wczogcmVuZGVyUHJvcHMsIGdlbmVyYXRvck5hbWU6IFwibW9yZUxpbmtDb250ZW50XCIsIGdlbmVyYXRvcjogb3B0aW9ucy5tb3JlTGlua0NvbnRlbnQgfHwgcHJvcHMuZGVmYXVsdEdlbmVyYXRvciB8fCByZW5kZXJNb3JlTGlua0lubmVyLCBjbGFzc05hbWVHZW5lcmF0b3I6IG9wdGlvbnMubW9yZUxpbmtDbGFzc05hbWVzLCBkaWRNb3VudDogb3B0aW9ucy5tb3JlTGlua0RpZE1vdW50LCB3aWxsVW5tb3VudDogb3B0aW9ucy5tb3JlTGlua1dpbGxVbm1vdW50IH0sIHByb3BzLmNoaWxkcmVuKSksXG4gICAgICAgICAgICAgICAgc3RhdGUuaXNQb3BvdmVyT3BlbiAmJiAoY3JlYXRlRWxlbWVudChNb3JlUG9wb3ZlciwgeyBpZDogc3RhdGUucG9wb3ZlcklkLCBzdGFydERhdGU6IHJhbmdlLnN0YXJ0LCBlbmREYXRlOiByYW5nZS5lbmQsIGRhdGVQcm9maWxlOiBwcm9wcy5kYXRlUHJvZmlsZSwgdG9kYXlSYW5nZTogcHJvcHMudG9kYXlSYW5nZSwgZXh0cmFEYXRlU3BhbjogcHJvcHMuZXh0cmFEYXRlU3BhbiwgcGFyZW50RWw6IHRoaXMucGFyZW50RWwsIGFsaWdubWVudEVsOiBwcm9wcy5hbGlnbm1lbnRFbFJlZiA/XG4gICAgICAgICAgICAgICAgICAgICAgICBwcm9wcy5hbGlnbm1lbnRFbFJlZi5jdXJyZW50IDpcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubGlua0VsLCBhbGlnbkdyaWRUb3A6IHByb3BzLmFsaWduR3JpZFRvcCwgb25DbG9zZTogdGhpcy5oYW5kbGVQb3BvdmVyQ2xvc2UgfSwgcHJvcHMucG9wb3ZlckNvbnRlbnQoKSkpKSk7XG4gICAgICAgIH0pKTtcbiAgICB9XG4gICAgY29tcG9uZW50RGlkTW91bnQoKSB7XG4gICAgICAgIHRoaXMudXBkYXRlUGFyZW50RWwoKTtcbiAgICB9XG4gICAgY29tcG9uZW50RGlkVXBkYXRlKCkge1xuICAgICAgICB0aGlzLnVwZGF0ZVBhcmVudEVsKCk7XG4gICAgfVxuICAgIHVwZGF0ZVBhcmVudEVsKCkge1xuICAgICAgICBpZiAodGhpcy5saW5rRWwpIHtcbiAgICAgICAgICAgIHRoaXMucGFyZW50RWwgPSBlbGVtZW50Q2xvc2VzdCh0aGlzLmxpbmtFbCwgJy5mYy12aWV3LWhhcm5lc3MnKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbmZ1bmN0aW9uIHJlbmRlck1vcmVMaW5rSW5uZXIocHJvcHMpIHtcbiAgICByZXR1cm4gcHJvcHMudGV4dDtcbn1cbmZ1bmN0aW9uIGNvbXB1dGVSYW5nZShwcm9wcykge1xuICAgIGlmIChwcm9wcy5hbGxEYXlEYXRlKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdGFydDogcHJvcHMuYWxsRGF5RGF0ZSxcbiAgICAgICAgICAgIGVuZDogYWRkRGF5cyhwcm9wcy5hbGxEYXlEYXRlLCAxKSxcbiAgICAgICAgfTtcbiAgICB9XG4gICAgbGV0IHsgaGlkZGVuU2VncyB9ID0gcHJvcHM7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgc3RhcnQ6IGNvbXB1dGVFYXJsaWVzdFNlZ1N0YXJ0KGhpZGRlblNlZ3MpLFxuICAgICAgICBlbmQ6IGNvbXB1dGVMYXRlc3RTZWdFbmQoaGlkZGVuU2VncyksXG4gICAgfTtcbn1cbmZ1bmN0aW9uIGNvbXB1dGVFYXJsaWVzdFNlZ1N0YXJ0KHNlZ3MpIHtcbiAgICByZXR1cm4gc2Vncy5yZWR1Y2UocGlja0VhcmxpZXN0U3RhcnQpLmV2ZW50UmFuZ2UucmFuZ2Uuc3RhcnQ7XG59XG5mdW5jdGlvbiBwaWNrRWFybGllc3RTdGFydChzZWcwLCBzZWcxKSB7XG4gICAgcmV0dXJuIHNlZzAuZXZlbnRSYW5nZS5yYW5nZS5zdGFydCA8IHNlZzEuZXZlbnRSYW5nZS5yYW5nZS5zdGFydCA/IHNlZzAgOiBzZWcxO1xufVxuZnVuY3Rpb24gY29tcHV0ZUxhdGVzdFNlZ0VuZChzZWdzKSB7XG4gICAgcmV0dXJuIHNlZ3MucmVkdWNlKHBpY2tMYXRlc3RFbmQpLmV2ZW50UmFuZ2UucmFuZ2UuZW5kO1xufVxuZnVuY3Rpb24gcGlja0xhdGVzdEVuZChzZWcwLCBzZWcxKSB7XG4gICAgcmV0dXJuIHNlZzAuZXZlbnRSYW5nZS5yYW5nZS5lbmQgPiBzZWcxLmV2ZW50UmFuZ2UucmFuZ2UuZW5kID8gc2VnMCA6IHNlZzE7XG59XG5cbmNsYXNzIFZpZXdDb250YWluZXIgZXh0ZW5kcyBCYXNlQ29tcG9uZW50IHtcbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGxldCB7IHByb3BzLCBjb250ZXh0IH0gPSB0aGlzO1xuICAgICAgICBsZXQgeyBvcHRpb25zIH0gPSBjb250ZXh0O1xuICAgICAgICBsZXQgcmVuZGVyUHJvcHMgPSB7IHZpZXc6IGNvbnRleHQudmlld0FwaSB9O1xuICAgICAgICByZXR1cm4gKGNyZWF0ZUVsZW1lbnQoQ29udGVudENvbnRhaW5lciwgT2JqZWN0LmFzc2lnbih7fSwgcHJvcHMsIHsgZWxUYWc6IHByb3BzLmVsVGFnIHx8ICdkaXYnLCBlbENsYXNzZXM6IFtcbiAgICAgICAgICAgICAgICAuLi5idWlsZFZpZXdDbGFzc05hbWVzKHByb3BzLnZpZXdTcGVjKSxcbiAgICAgICAgICAgICAgICAuLi4ocHJvcHMuZWxDbGFzc2VzIHx8IFtdKSxcbiAgICAgICAgICAgIF0sIHJlbmRlclByb3BzOiByZW5kZXJQcm9wcywgY2xhc3NOYW1lR2VuZXJhdG9yOiBvcHRpb25zLnZpZXdDbGFzc05hbWVzLCBnZW5lcmF0b3JOYW1lOiB1bmRlZmluZWQsIGdlbmVyYXRvcjogdW5kZWZpbmVkLCBkaWRNb3VudDogb3B0aW9ucy52aWV3RGlkTW91bnQsIHdpbGxVbm1vdW50OiBvcHRpb25zLnZpZXdXaWxsVW5tb3VudCB9KSwgKCkgPT4gcHJvcHMuY2hpbGRyZW4pKTtcbiAgICB9XG59XG5mdW5jdGlvbiBidWlsZFZpZXdDbGFzc05hbWVzKHZpZXdTcGVjKSB7XG4gICAgcmV0dXJuIFtcbiAgICAgICAgYGZjLSR7dmlld1NwZWMudHlwZX0tdmlld2AsXG4gICAgICAgICdmYy12aWV3JyxcbiAgICBdO1xufVxuXG5mdW5jdGlvbiBpbmplY3RTdHlsZXMoY3NzKSB7XG4gICAgaWYgKCFjc3MgfHwgdHlwZW9mIGRvY3VtZW50ID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGhlYWQgPSBkb2N1bWVudC5oZWFkIHx8IGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdoZWFkJylbMF07XG4gICAgY29uc3Qgc3R5bGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzdHlsZScpO1xuICAgIHN0eWxlLnR5cGUgPSAndGV4dC9jc3MnO1xuICAgIGhlYWQuYXBwZW5kQ2hpbGQoc3R5bGUpO1xuICAgIGlmIChzdHlsZS5zdHlsZVNoZWV0KSB7XG4gICAgICAgIHN0eWxlLnN0eWxlU2hlZXQuY3NzVGV4dCA9IGNzcztcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIHN0eWxlLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKGNzcykpO1xuICAgIH1cbn1cblxuY29uc3QgRVZFTlRfU09VUkNFX1JFRklORVJTID0ge1xuICAgIGlkOiBTdHJpbmcsXG4gICAgZGVmYXVsdEFsbERheTogQm9vbGVhbixcbiAgICB1cmw6IFN0cmluZyxcbiAgICBmb3JtYXQ6IFN0cmluZyxcbiAgICBldmVudHM6IGlkZW50aXR5LFxuICAgIGV2ZW50RGF0YVRyYW5zZm9ybTogaWRlbnRpdHksXG4gICAgLy8gZm9yIGFueSBuZXR3b3JrLXJlbGF0ZWQgc291cmNlc1xuICAgIHN1Y2Nlc3M6IGlkZW50aXR5LFxuICAgIGZhaWx1cmU6IGlkZW50aXR5LFxufTtcbmZ1bmN0aW9uIHBhcnNlRXZlbnRTb3VyY2UocmF3LCBjb250ZXh0LCByZWZpbmVycyA9IGJ1aWxkRXZlbnRTb3VyY2VSZWZpbmVycyhjb250ZXh0KSkge1xuICAgIGxldCByYXdPYmo7XG4gICAgaWYgKHR5cGVvZiByYXcgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJhd09iaiA9IHsgdXJsOiByYXcgfTtcbiAgICB9XG4gICAgZWxzZSBpZiAodHlwZW9mIHJhdyA9PT0gJ2Z1bmN0aW9uJyB8fCBBcnJheS5pc0FycmF5KHJhdykpIHtcbiAgICAgICAgcmF3T2JqID0geyBldmVudHM6IHJhdyB9O1xuICAgIH1cbiAgICBlbHNlIGlmICh0eXBlb2YgcmF3ID09PSAnb2JqZWN0JyAmJiByYXcpIHsgLy8gbm90IG51bGxcbiAgICAgICAgcmF3T2JqID0gcmF3O1xuICAgIH1cbiAgICBpZiAocmF3T2JqKSB7XG4gICAgICAgIGxldCB7IHJlZmluZWQsIGV4dHJhIH0gPSByZWZpbmVQcm9wcyhyYXdPYmosIHJlZmluZXJzKTtcbiAgICAgICAgbGV0IG1ldGFSZXMgPSBidWlsZEV2ZW50U291cmNlTWV0YShyZWZpbmVkLCBjb250ZXh0KTtcbiAgICAgICAgaWYgKG1ldGFSZXMpIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgX3JhdzogcmF3LFxuICAgICAgICAgICAgICAgIGlzRmV0Y2hpbmc6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGxhdGVzdEZldGNoSWQ6ICcnLFxuICAgICAgICAgICAgICAgIGZldGNoUmFuZ2U6IG51bGwsXG4gICAgICAgICAgICAgICAgZGVmYXVsdEFsbERheTogcmVmaW5lZC5kZWZhdWx0QWxsRGF5LFxuICAgICAgICAgICAgICAgIGV2ZW50RGF0YVRyYW5zZm9ybTogcmVmaW5lZC5ldmVudERhdGFUcmFuc2Zvcm0sXG4gICAgICAgICAgICAgICAgc3VjY2VzczogcmVmaW5lZC5zdWNjZXNzLFxuICAgICAgICAgICAgICAgIGZhaWx1cmU6IHJlZmluZWQuZmFpbHVyZSxcbiAgICAgICAgICAgICAgICBwdWJsaWNJZDogcmVmaW5lZC5pZCB8fCAnJyxcbiAgICAgICAgICAgICAgICBzb3VyY2VJZDogZ3VpZCgpLFxuICAgICAgICAgICAgICAgIHNvdXJjZURlZklkOiBtZXRhUmVzLnNvdXJjZURlZklkLFxuICAgICAgICAgICAgICAgIG1ldGE6IG1ldGFSZXMubWV0YSxcbiAgICAgICAgICAgICAgICB1aTogY3JlYXRlRXZlbnRVaShyZWZpbmVkLCBjb250ZXh0KSxcbiAgICAgICAgICAgICAgICBleHRlbmRlZFByb3BzOiBleHRyYSxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG59XG5mdW5jdGlvbiBidWlsZEV2ZW50U291cmNlUmVmaW5lcnMoY29udGV4dCkge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgRVZFTlRfVUlfUkVGSU5FUlMpLCBFVkVOVF9TT1VSQ0VfUkVGSU5FUlMpLCBjb250ZXh0LnBsdWdpbkhvb2tzLmV2ZW50U291cmNlUmVmaW5lcnMpO1xufVxuZnVuY3Rpb24gYnVpbGRFdmVudFNvdXJjZU1ldGEocmF3LCBjb250ZXh0KSB7XG4gICAgbGV0IGRlZnMgPSBjb250ZXh0LnBsdWdpbkhvb2tzLmV2ZW50U291cmNlRGVmcztcbiAgICBmb3IgKGxldCBpID0gZGVmcy5sZW5ndGggLSAxOyBpID49IDA7IGkgLT0gMSkgeyAvLyBsYXRlci1hZGRlZCBwbHVnaW5zIHRha2UgcHJlY2VkZW5jZVxuICAgICAgICBsZXQgZGVmID0gZGVmc1tpXTtcbiAgICAgICAgbGV0IG1ldGEgPSBkZWYucGFyc2VNZXRhKHJhdyk7XG4gICAgICAgIGlmIChtZXRhKSB7XG4gICAgICAgICAgICByZXR1cm4geyBzb3VyY2VEZWZJZDogaSwgbWV0YSB9O1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xufVxuXG5jbGFzcyBDYWxlbmRhckltcGwge1xuICAgIGdldEN1cnJlbnREYXRhKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jdXJyZW50RGF0YU1hbmFnZXIuZ2V0Q3VycmVudERhdGEoKTtcbiAgICB9XG4gICAgZGlzcGF0Y2goYWN0aW9uKSB7XG4gICAgICAgIHRoaXMuY3VycmVudERhdGFNYW5hZ2VyLmRpc3BhdGNoKGFjdGlvbik7XG4gICAgfVxuICAgIGdldCB2aWV3KCkgeyByZXR1cm4gdGhpcy5nZXRDdXJyZW50RGF0YSgpLnZpZXdBcGk7IH1cbiAgICBiYXRjaFJlbmRlcmluZyhjYWxsYmFjaykge1xuICAgICAgICBjYWxsYmFjaygpO1xuICAgIH1cbiAgICB1cGRhdGVTaXplKCkge1xuICAgICAgICB0aGlzLnRyaWdnZXIoJ19yZXNpemUnLCB0cnVlKTtcbiAgICB9XG4gICAgLy8gT3B0aW9uc1xuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgc2V0T3B0aW9uKG5hbWUsIHZhbCkge1xuICAgICAgICB0aGlzLmRpc3BhdGNoKHtcbiAgICAgICAgICAgIHR5cGU6ICdTRVRfT1BUSU9OJyxcbiAgICAgICAgICAgIG9wdGlvbk5hbWU6IG5hbWUsXG4gICAgICAgICAgICByYXdPcHRpb25WYWx1ZTogdmFsLFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZ2V0T3B0aW9uKG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY3VycmVudERhdGFNYW5hZ2VyLmN1cnJlbnRDYWxlbmRhck9wdGlvbnNJbnB1dFtuYW1lXTtcbiAgICB9XG4gICAgZ2V0QXZhaWxhYmxlTG9jYWxlQ29kZXMoKSB7XG4gICAgICAgIHJldHVybiBPYmplY3Qua2V5cyh0aGlzLmdldEN1cnJlbnREYXRhKCkuYXZhaWxhYmxlUmF3TG9jYWxlcyk7XG4gICAgfVxuICAgIC8vIFRyaWdnZXJcbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIG9uKGhhbmRsZXJOYW1lLCBoYW5kbGVyKSB7XG4gICAgICAgIGxldCB7IGN1cnJlbnREYXRhTWFuYWdlciB9ID0gdGhpcztcbiAgICAgICAgaWYgKGN1cnJlbnREYXRhTWFuYWdlci5jdXJyZW50Q2FsZW5kYXJPcHRpb25zUmVmaW5lcnNbaGFuZGxlck5hbWVdKSB7XG4gICAgICAgICAgICBjdXJyZW50RGF0YU1hbmFnZXIuZW1pdHRlci5vbihoYW5kbGVyTmFtZSwgaGFuZGxlcik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oYFVua25vd24gbGlzdGVuZXIgbmFtZSAnJHtoYW5kbGVyTmFtZX0nYCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgb2ZmKGhhbmRsZXJOYW1lLCBoYW5kbGVyKSB7XG4gICAgICAgIHRoaXMuY3VycmVudERhdGFNYW5hZ2VyLmVtaXR0ZXIub2ZmKGhhbmRsZXJOYW1lLCBoYW5kbGVyKTtcbiAgICB9XG4gICAgLy8gbm90IG1lYW50IGZvciBwdWJsaWMgdXNlXG4gICAgdHJpZ2dlcihoYW5kbGVyTmFtZSwgLi4uYXJncykge1xuICAgICAgICB0aGlzLmN1cnJlbnREYXRhTWFuYWdlci5lbWl0dGVyLnRyaWdnZXIoaGFuZGxlck5hbWUsIC4uLmFyZ3MpO1xuICAgIH1cbiAgICAvLyBWaWV3XG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICBjaGFuZ2VWaWV3KHZpZXdUeXBlLCBkYXRlT3JSYW5nZSkge1xuICAgICAgICB0aGlzLmJhdGNoUmVuZGVyaW5nKCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMudW5zZWxlY3QoKTtcbiAgICAgICAgICAgIGlmIChkYXRlT3JSYW5nZSkge1xuICAgICAgICAgICAgICAgIGlmIChkYXRlT3JSYW5nZS5zdGFydCAmJiBkYXRlT3JSYW5nZS5lbmQpIHsgLy8gYSByYW5nZVxuICAgICAgICAgICAgICAgICAgICB0aGlzLmRpc3BhdGNoKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdDSEFOR0VfVklFV19UWVBFJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHZpZXdUeXBlLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kaXNwYXRjaCh7XG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAnU0VUX09QVElPTicsXG4gICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25OYW1lOiAndmlzaWJsZVJhbmdlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJhd09wdGlvblZhbHVlOiBkYXRlT3JSYW5nZSxcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBsZXQgeyBkYXRlRW52IH0gPSB0aGlzLmdldEN1cnJlbnREYXRhKCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZGlzcGF0Y2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ0NIQU5HRV9WSUVXX1RZUEUnLFxuICAgICAgICAgICAgICAgICAgICAgICAgdmlld1R5cGUsXG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRlTWFya2VyOiBkYXRlRW52LmNyZWF0ZU1hcmtlcihkYXRlT3JSYW5nZSksXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuZGlzcGF0Y2goe1xuICAgICAgICAgICAgICAgICAgICB0eXBlOiAnQ0hBTkdFX1ZJRVdfVFlQRScsXG4gICAgICAgICAgICAgICAgICAgIHZpZXdUeXBlLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLy8gRm9yY2VzIG5hdmlnYXRpb24gdG8gYSB2aWV3IGZvciB0aGUgZ2l2ZW4gZGF0ZS5cbiAgICAvLyBgdmlld1R5cGVgIGNhbiBiZSBhIHNwZWNpZmljIHZpZXcgbmFtZSBvciBhIGdlbmVyaWMgb25lIGxpa2UgXCJ3ZWVrXCIgb3IgXCJkYXlcIi5cbiAgICAvLyBuZWVkcyB0byBjaGFuZ2VcbiAgICB6b29tVG8oZGF0ZU1hcmtlciwgdmlld1R5cGUpIHtcbiAgICAgICAgbGV0IHN0YXRlID0gdGhpcy5nZXRDdXJyZW50RGF0YSgpO1xuICAgICAgICBsZXQgc3BlYztcbiAgICAgICAgdmlld1R5cGUgPSB2aWV3VHlwZSB8fCAnZGF5JzsgLy8gZGF5IGlzIGRlZmF1bHQgem9vbVxuICAgICAgICBzcGVjID0gc3RhdGUudmlld1NwZWNzW3ZpZXdUeXBlXSB8fCB0aGlzLmdldFVuaXRWaWV3U3BlYyh2aWV3VHlwZSk7XG4gICAgICAgIHRoaXMudW5zZWxlY3QoKTtcbiAgICAgICAgaWYgKHNwZWMpIHtcbiAgICAgICAgICAgIHRoaXMuZGlzcGF0Y2goe1xuICAgICAgICAgICAgICAgIHR5cGU6ICdDSEFOR0VfVklFV19UWVBFJyxcbiAgICAgICAgICAgICAgICB2aWV3VHlwZTogc3BlYy50eXBlLFxuICAgICAgICAgICAgICAgIGRhdGVNYXJrZXIsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZGlzcGF0Y2goe1xuICAgICAgICAgICAgICAgIHR5cGU6ICdDSEFOR0VfREFURScsXG4gICAgICAgICAgICAgICAgZGF0ZU1hcmtlcixcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8vIEdpdmVuIGEgZHVyYXRpb24gc2luZ3VsYXIgdW5pdCwgbGlrZSBcIndlZWtcIiBvciBcImRheVwiLCBmaW5kcyBhIG1hdGNoaW5nIHZpZXcgc3BlYy5cbiAgICAvLyBQcmVmZXJlbmNlIGlzIGdpdmVuIHRvIHZpZXdzIHRoYXQgaGF2ZSBjb3JyZXNwb25kaW5nIGJ1dHRvbnMuXG4gICAgZ2V0VW5pdFZpZXdTcGVjKHVuaXQpIHtcbiAgICAgICAgbGV0IHsgdmlld1NwZWNzLCB0b29sYmFyQ29uZmlnIH0gPSB0aGlzLmdldEN1cnJlbnREYXRhKCk7XG4gICAgICAgIGxldCB2aWV3VHlwZXMgPSBbXS5jb25jYXQodG9vbGJhckNvbmZpZy5oZWFkZXIgPyB0b29sYmFyQ29uZmlnLmhlYWRlci52aWV3c1dpdGhCdXR0b25zIDogW10sIHRvb2xiYXJDb25maWcuZm9vdGVyID8gdG9vbGJhckNvbmZpZy5mb290ZXIudmlld3NXaXRoQnV0dG9ucyA6IFtdKTtcbiAgICAgICAgbGV0IGk7XG4gICAgICAgIGxldCBzcGVjO1xuICAgICAgICBmb3IgKGxldCB2aWV3VHlwZSBpbiB2aWV3U3BlY3MpIHtcbiAgICAgICAgICAgIHZpZXdUeXBlcy5wdXNoKHZpZXdUeXBlKTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgdmlld1R5cGVzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICBzcGVjID0gdmlld1NwZWNzW3ZpZXdUeXBlc1tpXV07XG4gICAgICAgICAgICBpZiAoc3BlYykge1xuICAgICAgICAgICAgICAgIGlmIChzcGVjLnNpbmdsZVVuaXQgPT09IHVuaXQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNwZWM7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICAvLyBDdXJyZW50IERhdGVcbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIHByZXYoKSB7XG4gICAgICAgIHRoaXMudW5zZWxlY3QoKTtcbiAgICAgICAgdGhpcy5kaXNwYXRjaCh7IHR5cGU6ICdQUkVWJyB9KTtcbiAgICB9XG4gICAgbmV4dCgpIHtcbiAgICAgICAgdGhpcy51bnNlbGVjdCgpO1xuICAgICAgICB0aGlzLmRpc3BhdGNoKHsgdHlwZTogJ05FWFQnIH0pO1xuICAgIH1cbiAgICBwcmV2WWVhcigpIHtcbiAgICAgICAgbGV0IHN0YXRlID0gdGhpcy5nZXRDdXJyZW50RGF0YSgpO1xuICAgICAgICB0aGlzLnVuc2VsZWN0KCk7XG4gICAgICAgIHRoaXMuZGlzcGF0Y2goe1xuICAgICAgICAgICAgdHlwZTogJ0NIQU5HRV9EQVRFJyxcbiAgICAgICAgICAgIGRhdGVNYXJrZXI6IHN0YXRlLmRhdGVFbnYuYWRkWWVhcnMoc3RhdGUuY3VycmVudERhdGUsIC0xKSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIG5leHRZZWFyKCkge1xuICAgICAgICBsZXQgc3RhdGUgPSB0aGlzLmdldEN1cnJlbnREYXRhKCk7XG4gICAgICAgIHRoaXMudW5zZWxlY3QoKTtcbiAgICAgICAgdGhpcy5kaXNwYXRjaCh7XG4gICAgICAgICAgICB0eXBlOiAnQ0hBTkdFX0RBVEUnLFxuICAgICAgICAgICAgZGF0ZU1hcmtlcjogc3RhdGUuZGF0ZUVudi5hZGRZZWFycyhzdGF0ZS5jdXJyZW50RGF0ZSwgMSksXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICB0b2RheSgpIHtcbiAgICAgICAgbGV0IHN0YXRlID0gdGhpcy5nZXRDdXJyZW50RGF0YSgpO1xuICAgICAgICB0aGlzLnVuc2VsZWN0KCk7XG4gICAgICAgIHRoaXMuZGlzcGF0Y2goe1xuICAgICAgICAgICAgdHlwZTogJ0NIQU5HRV9EQVRFJyxcbiAgICAgICAgICAgIGRhdGVNYXJrZXI6IGdldE5vdyhzdGF0ZS5jYWxlbmRhck9wdGlvbnMubm93LCBzdGF0ZS5kYXRlRW52KSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIGdvdG9EYXRlKHpvbmVkRGF0ZUlucHV0KSB7XG4gICAgICAgIGxldCBzdGF0ZSA9IHRoaXMuZ2V0Q3VycmVudERhdGEoKTtcbiAgICAgICAgdGhpcy51bnNlbGVjdCgpO1xuICAgICAgICB0aGlzLmRpc3BhdGNoKHtcbiAgICAgICAgICAgIHR5cGU6ICdDSEFOR0VfREFURScsXG4gICAgICAgICAgICBkYXRlTWFya2VyOiBzdGF0ZS5kYXRlRW52LmNyZWF0ZU1hcmtlcih6b25lZERhdGVJbnB1dCksXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBpbmNyZW1lbnREYXRlKGRlbHRhSW5wdXQpIHtcbiAgICAgICAgbGV0IHN0YXRlID0gdGhpcy5nZXRDdXJyZW50RGF0YSgpO1xuICAgICAgICBsZXQgZGVsdGEgPSBjcmVhdGVEdXJhdGlvbihkZWx0YUlucHV0KTtcbiAgICAgICAgaWYgKGRlbHRhKSB7IC8vIGVsc2UsIHdhcm4gYWJvdXQgaW52YWxpZCBpbnB1dD9cbiAgICAgICAgICAgIHRoaXMudW5zZWxlY3QoKTtcbiAgICAgICAgICAgIHRoaXMuZGlzcGF0Y2goe1xuICAgICAgICAgICAgICAgIHR5cGU6ICdDSEFOR0VfREFURScsXG4gICAgICAgICAgICAgICAgZGF0ZU1hcmtlcjogc3RhdGUuZGF0ZUVudi5hZGQoc3RhdGUuY3VycmVudERhdGUsIGRlbHRhKSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuICAgIGdldERhdGUoKSB7XG4gICAgICAgIGxldCBzdGF0ZSA9IHRoaXMuZ2V0Q3VycmVudERhdGEoKTtcbiAgICAgICAgcmV0dXJuIHN0YXRlLmRhdGVFbnYudG9EYXRlKHN0YXRlLmN1cnJlbnREYXRlKTtcbiAgICB9XG4gICAgLy8gRGF0ZSBGb3JtYXR0aW5nIFV0aWxzXG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICBmb3JtYXREYXRlKGQsIGZvcm1hdHRlcikge1xuICAgICAgICBsZXQgeyBkYXRlRW52IH0gPSB0aGlzLmdldEN1cnJlbnREYXRhKCk7XG4gICAgICAgIHJldHVybiBkYXRlRW52LmZvcm1hdChkYXRlRW52LmNyZWF0ZU1hcmtlcihkKSwgY3JlYXRlRm9ybWF0dGVyKGZvcm1hdHRlcikpO1xuICAgIH1cbiAgICAvLyBgc2V0dGluZ3NgIGlzIGZvciBmb3JtYXR0ZXIgQU5EIGlzRW5kRXhjbHVzaXZlXG4gICAgZm9ybWF0UmFuZ2UoZDAsIGQxLCBzZXR0aW5ncykge1xuICAgICAgICBsZXQgeyBkYXRlRW52IH0gPSB0aGlzLmdldEN1cnJlbnREYXRhKCk7XG4gICAgICAgIHJldHVybiBkYXRlRW52LmZvcm1hdFJhbmdlKGRhdGVFbnYuY3JlYXRlTWFya2VyKGQwKSwgZGF0ZUVudi5jcmVhdGVNYXJrZXIoZDEpLCBjcmVhdGVGb3JtYXR0ZXIoc2V0dGluZ3MpLCBzZXR0aW5ncyk7XG4gICAgfVxuICAgIGZvcm1hdElzbyhkLCBvbWl0VGltZSkge1xuICAgICAgICBsZXQgeyBkYXRlRW52IH0gPSB0aGlzLmdldEN1cnJlbnREYXRhKCk7XG4gICAgICAgIHJldHVybiBkYXRlRW52LmZvcm1hdElzbyhkYXRlRW52LmNyZWF0ZU1hcmtlcihkKSwgeyBvbWl0VGltZSB9KTtcbiAgICB9XG4gICAgLy8gRGF0ZSBTZWxlY3Rpb24gLyBFdmVudCBTZWxlY3Rpb24gLyBEYXlDbGlja1xuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgc2VsZWN0KGRhdGVPck9iaiwgZW5kRGF0ZSkge1xuICAgICAgICBsZXQgc2VsZWN0aW9uSW5wdXQ7XG4gICAgICAgIGlmIChlbmREYXRlID09IG51bGwpIHtcbiAgICAgICAgICAgIGlmIChkYXRlT3JPYmouc3RhcnQgIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHNlbGVjdGlvbklucHV0ID0gZGF0ZU9yT2JqO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgc2VsZWN0aW9uSW5wdXQgPSB7XG4gICAgICAgICAgICAgICAgICAgIHN0YXJ0OiBkYXRlT3JPYmosXG4gICAgICAgICAgICAgICAgICAgIGVuZDogbnVsbCxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgc2VsZWN0aW9uSW5wdXQgPSB7XG4gICAgICAgICAgICAgICAgc3RhcnQ6IGRhdGVPck9iaixcbiAgICAgICAgICAgICAgICBlbmQ6IGVuZERhdGUsXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGxldCBzdGF0ZSA9IHRoaXMuZ2V0Q3VycmVudERhdGEoKTtcbiAgICAgICAgbGV0IHNlbGVjdGlvbiA9IHBhcnNlRGF0ZVNwYW4oc2VsZWN0aW9uSW5wdXQsIHN0YXRlLmRhdGVFbnYsIGNyZWF0ZUR1cmF0aW9uKHsgZGF5czogMSB9KSk7XG4gICAgICAgIGlmIChzZWxlY3Rpb24pIHsgLy8gdGhyb3cgcGFyc2UgZXJyb3Igb3RoZXJ3aXNlP1xuICAgICAgICAgICAgdGhpcy5kaXNwYXRjaCh7IHR5cGU6ICdTRUxFQ1RfREFURVMnLCBzZWxlY3Rpb24gfSk7XG4gICAgICAgICAgICB0cmlnZ2VyRGF0ZVNlbGVjdChzZWxlY3Rpb24sIG51bGwsIHN0YXRlKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICB1bnNlbGVjdChwZXYpIHtcbiAgICAgICAgbGV0IHN0YXRlID0gdGhpcy5nZXRDdXJyZW50RGF0YSgpO1xuICAgICAgICBpZiAoc3RhdGUuZGF0ZVNlbGVjdGlvbikge1xuICAgICAgICAgICAgdGhpcy5kaXNwYXRjaCh7IHR5cGU6ICdVTlNFTEVDVF9EQVRFUycgfSk7XG4gICAgICAgICAgICB0cmlnZ2VyRGF0ZVVuc2VsZWN0KHBldiwgc3RhdGUpO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8vIFB1YmxpYyBFdmVudHMgQVBJXG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICBhZGRFdmVudChldmVudElucHV0LCBzb3VyY2VJbnB1dCkge1xuICAgICAgICBpZiAoZXZlbnRJbnB1dCBpbnN0YW5jZW9mIEV2ZW50SW1wbCkge1xuICAgICAgICAgICAgbGV0IGRlZiA9IGV2ZW50SW5wdXQuX2RlZjtcbiAgICAgICAgICAgIGxldCBpbnN0YW5jZSA9IGV2ZW50SW5wdXQuX2luc3RhbmNlO1xuICAgICAgICAgICAgbGV0IGN1cnJlbnREYXRhID0gdGhpcy5nZXRDdXJyZW50RGF0YSgpO1xuICAgICAgICAgICAgLy8gbm90IGFscmVhZHkgcHJlc2VudD8gZG9uJ3Qgd2FudCB0byBhZGQgYW4gb2xkIHNuYXBzaG90XG4gICAgICAgICAgICBpZiAoIWN1cnJlbnREYXRhLmV2ZW50U3RvcmUuZGVmc1tkZWYuZGVmSWRdKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5kaXNwYXRjaCh7XG4gICAgICAgICAgICAgICAgICAgIHR5cGU6ICdBRERfRVZFTlRTJyxcbiAgICAgICAgICAgICAgICAgICAgZXZlbnRTdG9yZTogZXZlbnRUdXBsZVRvU3RvcmUoeyBkZWYsIGluc3RhbmNlIH0pLCAvLyBUT0RPOiBiZXR0ZXIgdXRpbCBmb3IgdHdvIGFyZ3M/XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgdGhpcy50cmlnZ2VyRXZlbnRBZGQoZXZlbnRJbnB1dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZXZlbnRJbnB1dDtcbiAgICAgICAgfVxuICAgICAgICBsZXQgc3RhdGUgPSB0aGlzLmdldEN1cnJlbnREYXRhKCk7XG4gICAgICAgIGxldCBldmVudFNvdXJjZTtcbiAgICAgICAgaWYgKHNvdXJjZUlucHV0IGluc3RhbmNlb2YgRXZlbnRTb3VyY2VJbXBsKSB7XG4gICAgICAgICAgICBldmVudFNvdXJjZSA9IHNvdXJjZUlucHV0LmludGVybmFsRXZlbnRTb3VyY2U7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodHlwZW9mIHNvdXJjZUlucHV0ID09PSAnYm9vbGVhbicpIHtcbiAgICAgICAgICAgIGlmIChzb3VyY2VJbnB1dCkgeyAvLyB0cnVlLiBwYXJ0IG9mIHRoZSBmaXJzdCBldmVudCBzb3VyY2VcbiAgICAgICAgICAgICAgICBbZXZlbnRTb3VyY2VdID0gaGFzaFZhbHVlc1RvQXJyYXkoc3RhdGUuZXZlbnRTb3VyY2VzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChzb3VyY2VJbnB1dCAhPSBudWxsKSB7IC8vIGFuIElELiBhY2NlcHRzIGEgbnVtYmVyIHRvb1xuICAgICAgICAgICAgbGV0IHNvdXJjZUFwaSA9IHRoaXMuZ2V0RXZlbnRTb3VyY2VCeUlkKHNvdXJjZUlucHV0KTsgLy8gVE9ETzogdXNlIGFuIGludGVybmFsIGZ1bmN0aW9uXG4gICAgICAgICAgICBpZiAoIXNvdXJjZUFwaSkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihgQ291bGQgbm90IGZpbmQgYW4gZXZlbnQgc291cmNlIHdpdGggSUQgXCIke3NvdXJjZUlucHV0fVwiYCk7IC8vIFRPRE86IHRlc3RcbiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGV2ZW50U291cmNlID0gc291cmNlQXBpLmludGVybmFsRXZlbnRTb3VyY2U7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHR1cGxlID0gcGFyc2VFdmVudChldmVudElucHV0LCBldmVudFNvdXJjZSwgc3RhdGUsIGZhbHNlKTtcbiAgICAgICAgaWYgKHR1cGxlKSB7XG4gICAgICAgICAgICBsZXQgbmV3RXZlbnRBcGkgPSBuZXcgRXZlbnRJbXBsKHN0YXRlLCB0dXBsZS5kZWYsIHR1cGxlLmRlZi5yZWN1cnJpbmdEZWYgPyBudWxsIDogdHVwbGUuaW5zdGFuY2UpO1xuICAgICAgICAgICAgdGhpcy5kaXNwYXRjaCh7XG4gICAgICAgICAgICAgICAgdHlwZTogJ0FERF9FVkVOVFMnLFxuICAgICAgICAgICAgICAgIGV2ZW50U3RvcmU6IGV2ZW50VHVwbGVUb1N0b3JlKHR1cGxlKSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy50cmlnZ2VyRXZlbnRBZGQobmV3RXZlbnRBcGkpO1xuICAgICAgICAgICAgcmV0dXJuIG5ld0V2ZW50QXBpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICB0cmlnZ2VyRXZlbnRBZGQoZXZlbnRBcGkpIHtcbiAgICAgICAgbGV0IHsgZW1pdHRlciB9ID0gdGhpcy5nZXRDdXJyZW50RGF0YSgpO1xuICAgICAgICBlbWl0dGVyLnRyaWdnZXIoJ2V2ZW50QWRkJywge1xuICAgICAgICAgICAgZXZlbnQ6IGV2ZW50QXBpLFxuICAgICAgICAgICAgcmVsYXRlZEV2ZW50czogW10sXG4gICAgICAgICAgICByZXZlcnQ6ICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmRpc3BhdGNoKHtcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogJ1JFTU9WRV9FVkVOVFMnLFxuICAgICAgICAgICAgICAgICAgICBldmVudFN0b3JlOiBldmVudEFwaVRvU3RvcmUoZXZlbnRBcGkpLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIC8vIFRPRE86IG9wdGltaXplXG4gICAgZ2V0RXZlbnRCeUlkKGlkKSB7XG4gICAgICAgIGxldCBzdGF0ZSA9IHRoaXMuZ2V0Q3VycmVudERhdGEoKTtcbiAgICAgICAgbGV0IHsgZGVmcywgaW5zdGFuY2VzIH0gPSBzdGF0ZS5ldmVudFN0b3JlO1xuICAgICAgICBpZCA9IFN0cmluZyhpZCk7XG4gICAgICAgIGZvciAobGV0IGRlZklkIGluIGRlZnMpIHtcbiAgICAgICAgICAgIGxldCBkZWYgPSBkZWZzW2RlZklkXTtcbiAgICAgICAgICAgIGlmIChkZWYucHVibGljSWQgPT09IGlkKSB7XG4gICAgICAgICAgICAgICAgaWYgKGRlZi5yZWN1cnJpbmdEZWYpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBFdmVudEltcGwoc3RhdGUsIGRlZiwgbnVsbCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGZvciAobGV0IGluc3RhbmNlSWQgaW4gaW5zdGFuY2VzKSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCBpbnN0YW5jZSA9IGluc3RhbmNlc1tpbnN0YW5jZUlkXTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGluc3RhbmNlLmRlZklkID09PSBkZWYuZGVmSWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgRXZlbnRJbXBsKHN0YXRlLCBkZWYsIGluc3RhbmNlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgZ2V0RXZlbnRzKCkge1xuICAgICAgICBsZXQgY3VycmVudERhdGEgPSB0aGlzLmdldEN1cnJlbnREYXRhKCk7XG4gICAgICAgIHJldHVybiBidWlsZEV2ZW50QXBpcyhjdXJyZW50RGF0YS5ldmVudFN0b3JlLCBjdXJyZW50RGF0YSk7XG4gICAgfVxuICAgIHJlbW92ZUFsbEV2ZW50cygpIHtcbiAgICAgICAgdGhpcy5kaXNwYXRjaCh7IHR5cGU6ICdSRU1PVkVfQUxMX0VWRU5UUycgfSk7XG4gICAgfVxuICAgIC8vIFB1YmxpYyBFdmVudCBTb3VyY2VzIEFQSVxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgZ2V0RXZlbnRTb3VyY2VzKCkge1xuICAgICAgICBsZXQgc3RhdGUgPSB0aGlzLmdldEN1cnJlbnREYXRhKCk7XG4gICAgICAgIGxldCBzb3VyY2VIYXNoID0gc3RhdGUuZXZlbnRTb3VyY2VzO1xuICAgICAgICBsZXQgc291cmNlQXBpcyA9IFtdO1xuICAgICAgICBmb3IgKGxldCBpbnRlcm5hbElkIGluIHNvdXJjZUhhc2gpIHtcbiAgICAgICAgICAgIHNvdXJjZUFwaXMucHVzaChuZXcgRXZlbnRTb3VyY2VJbXBsKHN0YXRlLCBzb3VyY2VIYXNoW2ludGVybmFsSWRdKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHNvdXJjZUFwaXM7XG4gICAgfVxuICAgIGdldEV2ZW50U291cmNlQnlJZChpZCkge1xuICAgICAgICBsZXQgc3RhdGUgPSB0aGlzLmdldEN1cnJlbnREYXRhKCk7XG4gICAgICAgIGxldCBzb3VyY2VIYXNoID0gc3RhdGUuZXZlbnRTb3VyY2VzO1xuICAgICAgICBpZCA9IFN0cmluZyhpZCk7XG4gICAgICAgIGZvciAobGV0IHNvdXJjZUlkIGluIHNvdXJjZUhhc2gpIHtcbiAgICAgICAgICAgIGlmIChzb3VyY2VIYXNoW3NvdXJjZUlkXS5wdWJsaWNJZCA9PT0gaWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEV2ZW50U291cmNlSW1wbChzdGF0ZSwgc291cmNlSGFzaFtzb3VyY2VJZF0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBhZGRFdmVudFNvdXJjZShzb3VyY2VJbnB1dCkge1xuICAgICAgICBsZXQgc3RhdGUgPSB0aGlzLmdldEN1cnJlbnREYXRhKCk7XG4gICAgICAgIGlmIChzb3VyY2VJbnB1dCBpbnN0YW5jZW9mIEV2ZW50U291cmNlSW1wbCkge1xuICAgICAgICAgICAgLy8gbm90IGFscmVhZHkgcHJlc2VudD8gZG9uJ3Qgd2FudCB0byBhZGQgYW4gb2xkIHNuYXBzaG90XG4gICAgICAgICAgICBpZiAoIXN0YXRlLmV2ZW50U291cmNlc1tzb3VyY2VJbnB1dC5pbnRlcm5hbEV2ZW50U291cmNlLnNvdXJjZUlkXSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZGlzcGF0Y2goe1xuICAgICAgICAgICAgICAgICAgICB0eXBlOiAnQUREX0VWRU5UX1NPVVJDRVMnLFxuICAgICAgICAgICAgICAgICAgICBzb3VyY2VzOiBbc291cmNlSW5wdXQuaW50ZXJuYWxFdmVudFNvdXJjZV0sXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gc291cmNlSW5wdXQ7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGV2ZW50U291cmNlID0gcGFyc2VFdmVudFNvdXJjZShzb3VyY2VJbnB1dCwgc3RhdGUpO1xuICAgICAgICBpZiAoZXZlbnRTb3VyY2UpIHsgLy8gVE9ETzogZXJyb3Igb3RoZXJ3aXNlP1xuICAgICAgICAgICAgdGhpcy5kaXNwYXRjaCh7IHR5cGU6ICdBRERfRVZFTlRfU09VUkNFUycsIHNvdXJjZXM6IFtldmVudFNvdXJjZV0gfSk7XG4gICAgICAgICAgICByZXR1cm4gbmV3IEV2ZW50U291cmNlSW1wbChzdGF0ZSwgZXZlbnRTb3VyY2UpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICByZW1vdmVBbGxFdmVudFNvdXJjZXMoKSB7XG4gICAgICAgIHRoaXMuZGlzcGF0Y2goeyB0eXBlOiAnUkVNT1ZFX0FMTF9FVkVOVF9TT1VSQ0VTJyB9KTtcbiAgICB9XG4gICAgcmVmZXRjaEV2ZW50cygpIHtcbiAgICAgICAgdGhpcy5kaXNwYXRjaCh7IHR5cGU6ICdGRVRDSF9FVkVOVF9TT1VSQ0VTJywgaXNSZWZldGNoOiB0cnVlIH0pO1xuICAgIH1cbiAgICAvLyBTY3JvbGxcbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIHNjcm9sbFRvVGltZSh0aW1lSW5wdXQpIHtcbiAgICAgICAgbGV0IHRpbWUgPSBjcmVhdGVEdXJhdGlvbih0aW1lSW5wdXQpO1xuICAgICAgICBpZiAodGltZSkge1xuICAgICAgICAgICAgdGhpcy50cmlnZ2VyKCdfc2Nyb2xsUmVxdWVzdCcsIHsgdGltZSB9KTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuY2xhc3MgU3RvcmUge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLmhhbmRsZXJzID0gW107XG4gICAgfVxuICAgIHNldCh2YWx1ZSkge1xuICAgICAgICB0aGlzLmN1cnJlbnRWYWx1ZSA9IHZhbHVlO1xuICAgICAgICBmb3IgKGxldCBoYW5kbGVyIG9mIHRoaXMuaGFuZGxlcnMpIHtcbiAgICAgICAgICAgIGhhbmRsZXIodmFsdWUpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHN1YnNjcmliZShoYW5kbGVyKSB7XG4gICAgICAgIHRoaXMuaGFuZGxlcnMucHVzaChoYW5kbGVyKTtcbiAgICAgICAgaWYgKHRoaXMuY3VycmVudFZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGhhbmRsZXIodGhpcy5jdXJyZW50VmFsdWUpO1xuICAgICAgICB9XG4gICAgfVxufVxuXG4vKlxuU3Vic2NyaWJlcnMgd2lsbCBnZXQgYSBMSVNUIG9mIEN1c3RvbVJlbmRlcmluZ3NcbiovXG5jbGFzcyBDdXN0b21SZW5kZXJpbmdTdG9yZSBleHRlbmRzIFN0b3JlIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5tYXAgPSBuZXcgTWFwKCk7XG4gICAgfVxuICAgIC8vIGZvciBjb25zaXN0ZW50IG9yZGVyXG4gICAgaGFuZGxlKGN1c3RvbVJlbmRlcmluZykge1xuICAgICAgICBjb25zdCB7IG1hcCB9ID0gdGhpcztcbiAgICAgICAgbGV0IHVwZGF0ZWQgPSBmYWxzZTtcbiAgICAgICAgaWYgKGN1c3RvbVJlbmRlcmluZy5pc0FjdGl2ZSkge1xuICAgICAgICAgICAgbWFwLnNldChjdXN0b21SZW5kZXJpbmcuaWQsIGN1c3RvbVJlbmRlcmluZyk7XG4gICAgICAgICAgICB1cGRhdGVkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChtYXAuaGFzKGN1c3RvbVJlbmRlcmluZy5pZCkpIHtcbiAgICAgICAgICAgIG1hcC5kZWxldGUoY3VzdG9tUmVuZGVyaW5nLmlkKTtcbiAgICAgICAgICAgIHVwZGF0ZWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmICh1cGRhdGVkKSB7XG4gICAgICAgICAgICB0aGlzLnNldChtYXApO1xuICAgICAgICB9XG4gICAgfVxufVxuXG5leHBvcnQgeyBnZXRFbFNlZyBhcyAkLCBtZW1vaXplT2JqQXJnIGFzIEEsIEJBU0VfT1BUSU9OX0RFRkFVTFRTIGFzIEIsIENvbnRlbnRDb250YWluZXIgYXMgQywgRGVsYXllZFJ1bm5lciBhcyBELCBpc1Byb3BzRXF1YWwgYXMgRSwgRW1pdHRlciBhcyBGLCBnZXRJbml0aWFsRGF0ZSBhcyBHLCByYW5nZUNvbnRhaW5zTWFya2VyIGFzIEgsIGNyZWF0ZUVtcHR5RXZlbnRTdG9yZSBhcyBJLCByZWR1Y2VDdXJyZW50RGF0ZSBhcyBKLCByZWR1Y2VFdmVudFN0b3JlIGFzIEssIHJlem9uZUV2ZW50U3RvcmVEYXRlcyBhcyBMLCBtZXJnZVJhd09wdGlvbnMgYXMgTSwgQkFTRV9PUFRJT05fUkVGSU5FUlMgYXMgTiwgQ0FMRU5EQVJfTElTVEVORVJfUkVGSU5FUlMgYXMgTywgQ0FMRU5EQVJfT1BUSU9OX1JFRklORVJTIGFzIFAsIENPTVBMRVhfT1BUSU9OX0NPTVBBUkFUT1JTIGFzIFEsIFZJRVdfT1BUSU9OX1JFRklORVJTIGFzIFIsIERhdGVFbnYgYXMgUywgVGhlbWUgYXMgVCwgRGF0ZVByb2ZpbGVHZW5lcmF0b3IgYXMgVSwgVmlld0NvbnRleHRUeXBlIGFzIFYsIGNyZWF0ZUV2ZW50VWkgYXMgVywgcGFyc2VCdXNpbmVzc0hvdXJzIGFzIFgsIEJhc2VDb21wb25lbnQgYXMgWSwgc2V0UmVmIGFzIFosIEludGVyYWN0aW9uIGFzIF8sIGlzQXJyYXlzRXF1YWwgYXMgYSwgZ2V0RGF0ZU1ldGEgYXMgYSQsIGVsZW1lbnRDbG9zZXN0IGFzIGEwLCBFdmVudEltcGwgYXMgYTEsIGxpc3RlbkJ5U2VsZWN0b3IgYXMgYTIsIGxpc3RlblRvSG92ZXJCeVNlbGVjdG9yIGFzIGEzLCBQdXJlQ29tcG9uZW50IGFzIGE0LCBidWlsZFZpZXdDb250ZXh0IGFzIGE1LCBnZXRVbmlxdWVEb21JZCBhcyBhNiwgcGFyc2VJbnRlcmFjdGlvblNldHRpbmdzIGFzIGE3LCBpbnRlcmFjdGlvblNldHRpbmdzU3RvcmUgYXMgYTgsIGdldE5vdyBhcyBhOSwgZGlmZkRhdGVzIGFzIGFBLCByZW1vdmVFeGFjdCBhcyBhQiwgbWVtb2l6ZUFycmF5bGlrZSBhcyBhQywgbWVtb2l6ZUhhc2hsaWtlIGFzIGFELCBpbnRlcnNlY3RSZWN0cyBhcyBhRSwgcG9pbnRJbnNpZGVSZWN0IGFzIGFGLCBjb25zdHJhaW5Qb2ludCBhcyBhRywgZ2V0UmVjdENlbnRlciBhcyBhSCwgZGlmZlBvaW50cyBhcyBhSSwgdHJhbnNsYXRlUmVjdCBhcyBhSiwgY29tcGFyZU9ianMgYXMgYUssIGNvbGxlY3RGcm9tSGFzaCBhcyBhTCwgZmluZEVsZW1lbnRzIGFzIGFNLCBmaW5kRGlyZWN0Q2hpbGRyZW4gYXMgYU4sIHJlbW92ZUVsZW1lbnQgYXMgYU8sIGFwcGx5U3R5bGUgYXMgYVAsIGVsZW1lbnRNYXRjaGVzIGFzIGFRLCBnZXRFbFJvb3QgYXMgYVIsIGdldEV2ZW50VGFyZ2V0VmlhUm9vdCBhcyBhUywgcGFyc2VDbGFzc05hbWVzIGFzIGFULCBnZXRDYW5WR3Jvd1dpdGhpbkNlbGwgYXMgYVUsIG1lcmdlRXZlbnRTdG9yZXMgYXMgYVYsIGdldFJlbGV2YW50RXZlbnRzIGFzIGFXLCBldmVudFR1cGxlVG9TdG9yZSBhcyBhWCwgY29tYmluZUV2ZW50VWlzIGFzIGFZLCBTcGxpdHRlciBhcyBhWiwgZ2V0RGF5Q2xhc3NOYW1lcyBhcyBhXywgQ2FsZW5kYXJJbXBsIGFzIGFhLCBmbHVzaFN5bmMgYXMgYWIsIENhbGVuZGFyUm9vdCBhcyBhYywgUmVuZGVySWQgYXMgYWQsIGFwcGx5U3R5bGVQcm9wIGFzIGFlLCBzbGljZUV2ZW50U3RvcmUgYXMgYWYsIEpzb25SZXF1ZXN0RXJyb3IgYXMgYWcsIGNyZWF0ZUNvbnRleHQgYXMgYWgsIHJlZmluZVByb3BzIGFzIGFpLCBjcmVhdGVFdmVudEluc3RhbmNlIGFzIGFqLCBwYXJzZUV2ZW50RGVmIGFzIGFrLCByZWZpbmVFdmVudERlZiBhcyBhbCwgcGFkU3RhcnQgYXMgYW0sIGlzSW50IGFzIGFuLCBwYXJzZUZpZWxkU3BlY3MgYXMgYW8sIGNvbXBhcmVCeUZpZWxkU3BlY3MgYXMgYXAsIGZsZXhpYmxlQ29tcGFyZSBhcyBhcSwgcHJldmVudFNlbGVjdGlvbiBhcyBhciwgYWxsb3dTZWxlY3Rpb24gYXMgYXMsIHByZXZlbnRDb250ZXh0TWVudSBhcyBhdCwgYWxsb3dDb250ZXh0TWVudSBhcyBhdSwgY29tcGFyZU51bWJlcnMgYXMgYXYsIGVuYWJsZUN1cnNvciBhcyBhdywgZGlzYWJsZUN1cnNvciBhcyBheCwgY29tcHV0ZVZpc2libGVEYXlSYW5nZSBhcyBheSwgaXNNdWx0aURheVJhbmdlIGFzIGF6LCBtYXBIYXNoIGFzIGIsIFNpbXBsZVNjcm9sbEdyaWQgYXMgYiQsIGdldFNsb3RDbGFzc05hbWVzIGFzIGIwLCBidWlsZE5hdkxpbmtBdHRycyBhcyBiMSwgcHJldmVudERlZmF1bHQgYXMgYjIsIHdoZW5UcmFuc2l0aW9uRG9uZSBhcyBiMywgY29tcHV0ZUlubmVyUmVjdCBhcyBiNCwgY29tcHV0ZUVkZ2VzIGFzIGI1LCBnZXRDbGlwcGluZ1BhcmVudHMgYXMgYjYsIGNvbXB1dGVSZWN0IGFzIGI3LCByYW5nZXNFcXVhbCBhcyBiOCwgcmFuZ2VzSW50ZXJzZWN0IGFzIGI5LCBTZWdIaWVyYXJjaHkgYXMgYkEsIGJ1aWxkRW50cnlLZXkgYXMgYkIsIGdldEVudHJ5U3BhbkVuZCBhcyBiQywgYmluYXJ5U2VhcmNoIGFzIGJELCBncm91cEludGVyc2VjdGluZ0VudHJpZXMgYXMgYkUsIGludGVyc2VjdFNwYW5zIGFzIGJGLCBpbnRlcmFjdGlvblNldHRpbmdzVG9TdG9yZSBhcyBiRywgRWxlbWVudERyYWdnaW5nIGFzIGJILCBjb25maWcgYXMgYkksIHBhcnNlRHJhZ01ldGEgYXMgYkosIERheUhlYWRlciBhcyBiSywgY29tcHV0ZUZhbGxiYWNrSGVhZGVyRm9ybWF0IGFzIGJMLCBUYWJsZURhdGVDZWxsIGFzIGJNLCBUYWJsZURvd0NlbGwgYXMgYk4sIERheVNlcmllc01vZGVsIGFzIGJPLCBoYXNCZ1JlbmRlcmluZyBhcyBiUCwgYnVpbGRTZWdUaW1lVGV4dCBhcyBiUSwgc29ydEV2ZW50U2VncyBhcyBiUiwgZ2V0U2VnTWV0YSBhcyBiUywgYnVpbGRFdmVudFJhbmdlS2V5IGFzIGJULCBnZXRTZWdBbmNob3JBdHRycyBhcyBiVSwgRGF5VGFibGVNb2RlbCBhcyBiViwgU2xpY2VyIGFzIGJXLCBhcHBseU11dGF0aW9uVG9FdmVudFN0b3JlIGFzIGJYLCBpc1Byb3BzVmFsaWQgYXMgYlksIGlzSW50ZXJhY3Rpb25WYWxpZCBhcyBiWiwgaXNEYXRlU2VsZWN0aW9uVmFsaWQgYXMgYl8sIHJhbmdlQ29udGFpbnNSYW5nZSBhcyBiYSwgUG9zaXRpb25DYWNoZSBhcyBiYiwgU2Nyb2xsQ29udHJvbGxlciBhcyBiYywgRWxlbWVudFNjcm9sbENvbnRyb2xsZXIgYXMgYmQsIFdpbmRvd1Njcm9sbENvbnRyb2xsZXIgYXMgYmUsIERhdGVDb21wb25lbnQgYXMgYmYsIGlzRGF0ZVNwYW5zRXF1YWwgYXMgYmcsIGFkZE1zIGFzIGJoLCBhZGRXZWVrcyBhcyBiaSwgZGlmZldlZWtzIGFzIGJqLCBkaWZmV2hvbGVXZWVrcyBhcyBiaywgZGlmZkRheUFuZFRpbWUgYXMgYmwsIGRpZmZEYXlzIGFzIGJtLCBpc1ZhbGlkRGF0ZSBhcyBibiwgYXNDbGVhbkRheXMgYXMgYm8sIG11bHRpcGx5RHVyYXRpb24gYXMgYnAsIGFkZER1cmF0aW9ucyBhcyBicSwgYXNSb3VnaE1pbnV0ZXMgYXMgYnIsIGFzUm91Z2hTZWNvbmRzIGFzIGJzLCBhc1JvdWdoTXMgYXMgYnQsIHdob2xlRGl2aWRlRHVyYXRpb25zIGFzIGJ1LCBmb3JtYXRJc29UaW1lU3RyaW5nIGFzIGJ2LCBmb3JtYXREYXlTdHJpbmcgYXMgYncsIGJ1aWxkSXNvU3RyaW5nIGFzIGJ4LCBOYW1lZFRpbWVab25lSW1wbCBhcyBieSwgcGFyc2UgYXMgYnosIGJ1aWxkVmlld0NsYXNzTmFtZXMgYXMgYywgaGFzU2hyaW5rV2lkdGggYXMgYzAsIHJlbmRlck1pY3JvQ29sR3JvdXAgYXMgYzEsIGdldFNjcm9sbEdyaWRDbGFzc05hbWVzIGFzIGMyLCBnZXRTZWN0aW9uQ2xhc3NOYW1lcyBhcyBjMywgZ2V0U2VjdGlvbkhhc0xpcXVpZEhlaWdodCBhcyBjNCwgZ2V0QWxsb3dZU2Nyb2xsaW5nIGFzIGM1LCByZW5kZXJDaHVua0NvbnRlbnQgYXMgYzYsIGNvbXB1dGVTaHJpbmtXaWR0aCBhcyBjNywgc2FuaXRpemVTaHJpbmtXaWR0aCBhcyBjOCwgaXNDb2xQcm9wc0VxdWFsIGFzIGM5LCByZW5kZXJTY3JvbGxTaGltIGFzIGNhLCBnZXRTdGlja3lGb290ZXJTY3JvbGxiYXIgYXMgY2IsIGdldFN0aWNreUhlYWRlckRhdGVzIGFzIGNjLCBTY3JvbGxlciBhcyBjZCwgZ2V0U2Nyb2xsYmFyV2lkdGhzIGFzIGNlLCBSZWZNYXAgYXMgY2YsIGdldElzUnRsU2Nyb2xsYmFyT25MZWZ0IGFzIGNnLCBOb3dUaW1lciBhcyBjaCwgU2Nyb2xsUmVzcG9uZGVyIGFzIGNpLCBTdGFuZGFyZEV2ZW50IGFzIGNqLCBOb3dJbmRpY2F0b3JDb250YWluZXIgYXMgY2ssIERheUNlbGxDb250YWluZXIgYXMgY2wsIGhhc0N1c3RvbURheUNlbGxDb250ZW50IGFzIGNtLCBFdmVudENvbnRhaW5lciBhcyBjbiwgcmVuZGVyRmlsbCBhcyBjbywgQmdFdmVudCBhcyBjcCwgV2Vla051bWJlckNvbnRhaW5lciBhcyBjcSwgTW9yZUxpbmtDb250YWluZXIgYXMgY3IsIGNvbXB1dGVFYXJsaWVzdFNlZ1N0YXJ0IGFzIGNzLCBWaWV3Q29udGFpbmVyIGFzIGN0LCB0cmlnZ2VyRGF0ZVNlbGVjdCBhcyBjdSwgZ2V0RGVmYXVsdEV2ZW50RW5kIGFzIGN2LCBidWlsZEVsQXR0cnMgYXMgY3csIEN1c3RvbVJlbmRlcmluZ1N0b3JlIGFzIGN4LCBncmVhdGVzdER1cmF0aW9uRGVub21pbmF0b3IgYXMgZCwgY3JlYXRlRHVyYXRpb24gYXMgZSwgYXJyYXlUb0hhc2ggYXMgZiwgZ3VpZCBhcyBnLCBmaWx0ZXJIYXNoIGFzIGgsIGluamVjdFN0eWxlcyBhcyBpLCBidWlsZEV2ZW50U291cmNlUmVmaW5lcnMgYXMgaiwgZm9ybWF0V2l0aE9yZGluYWxzIGFzIGssIGJ1aWxkUmFuZ2VBcGlXaXRoVGltZVpvbmUgYXMgbCwgbWVyZ2VQcm9wcyBhcyBtLCBpZGVudGl0eSBhcyBuLCBpbnRlcnNlY3RSYW5nZXMgYXMgbywgcGFyc2VFdmVudFNvdXJjZSBhcyBwLCBzdGFydE9mRGF5IGFzIHEsIHJlcXVlc3RKc29uIGFzIHIsIHN1YnRyYWN0RHVyYXRpb25zIGFzIHMsIGFkZERheXMgYXMgdCwgdW5wcm9taXNpZnkgYXMgdSwgaGFzaFZhbHVlc1RvQXJyYXkgYXMgdiwgYnVpbGRFdmVudEFwaXMgYXMgdywgY3JlYXRlRm9ybWF0dGVyIGFzIHgsIGRpZmZXaG9sZURheXMgYXMgeSwgbWVtb2l6ZSBhcyB6IH07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/@fullcalendar/core/internal-common.esm.js\n"); /***/ }), /***/ "./node_modules/@fullcalendar/daygrid/index.esm.js": /*!*********************************************************!*\ !*** ./node_modules/@fullcalendar/daygrid/index.esm.js ***! \*********************************************************/ /***/ (function(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) { eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": function() { return /* binding */ index; }\n/* harmony export */ });\n/* harmony import */ var _fullcalendar_core__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @fullcalendar/core */ \"./node_modules/@fullcalendar/core/index.esm.js\");\n/* harmony import */ var _internal_esm_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./internal.esm.js */ \"./node_modules/@fullcalendar/daygrid/internal.esm.js\");\n/* harmony import */ var _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @fullcalendar/core/internal */ \"./node_modules/@fullcalendar/core/internal-common.esm.js\");\n\n\n\n\n\nclass TableDateProfileGenerator extends _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.U {\n // Computes the date range that will be rendered.\n buildRenderRange(currentRange, currentRangeUnit, isRangeAllDay) {\n let { dateEnv } = this.props;\n let renderRange = super.buildRenderRange(currentRange, currentRangeUnit, isRangeAllDay);\n let start = renderRange.start;\n let end = renderRange.end;\n let endOfWeek;\n // year and month views should be aligned with weeks. this is already done for week\n if (/^(year|month)$/.test(currentRangeUnit)) {\n start = dateEnv.startOfWeek(start);\n // make end-of-week if not already\n endOfWeek = dateEnv.startOfWeek(end);\n if (endOfWeek.valueOf() !== end.valueOf()) {\n end = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bi)(endOfWeek, 1);\n }\n }\n // ensure 6 weeks\n if (this.props.monthMode &&\n this.props.fixedWeekCount) {\n let rowCnt = Math.ceil(// could be partial weeks due to hiddenDays\n (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bj)(start, end));\n end = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bi)(end, 6 - rowCnt);\n }\n return { start, end };\n }\n}\n\nvar css_248z = \":root{--fc-daygrid-event-dot-width:8px}.fc-daygrid-day-events:after,.fc-daygrid-day-events:before,.fc-daygrid-day-frame:after,.fc-daygrid-day-frame:before,.fc-daygrid-event-harness:after,.fc-daygrid-event-harness:before{clear:both;content:\\\"\\\";display:table}.fc .fc-daygrid-body{position:relative;z-index:1}.fc .fc-daygrid-day.fc-day-today{background-color:var(--fc-today-bg-color)}.fc .fc-daygrid-day-frame{min-height:100%;position:relative}.fc .fc-daygrid-day-top{display:flex;flex-direction:row-reverse}.fc .fc-day-other .fc-daygrid-day-top{opacity:.3}.fc .fc-daygrid-day-number{padding:4px;position:relative;z-index:4}.fc .fc-daygrid-day-events{margin-top:1px}.fc .fc-daygrid-body-balanced .fc-daygrid-day-events{left:0;position:absolute;right:0}.fc .fc-daygrid-body-unbalanced .fc-daygrid-day-events{min-height:2em;position:relative}.fc .fc-daygrid-body-natural .fc-daygrid-day-events{margin-bottom:1em}.fc .fc-daygrid-event-harness{position:relative}.fc .fc-daygrid-event-harness-abs{left:0;position:absolute;right:0;top:0}.fc .fc-daygrid-bg-harness{bottom:0;position:absolute;top:0}.fc .fc-daygrid-day-bg .fc-non-business{z-index:1}.fc .fc-daygrid-day-bg .fc-bg-event{z-index:2}.fc .fc-daygrid-day-bg .fc-highlight{z-index:3}.fc .fc-daygrid-event{margin-top:1px;z-index:6}.fc .fc-daygrid-event.fc-event-mirror{z-index:7}.fc .fc-daygrid-day-bottom{font-size:.85em;padding:2px 3px 0}.fc .fc-daygrid-day-bottom:before{clear:both;content:\\\"\\\";display:table}.fc .fc-daygrid-more-link{cursor:pointer;position:relative;z-index:4}.fc .fc-daygrid-week-number{background-color:var(--fc-neutral-bg-color);color:var(--fc-neutral-text-color);min-width:1.5em;padding:2px;position:absolute;text-align:center;top:0;z-index:5}.fc .fc-more-popover .fc-popover-body{min-width:220px;padding:10px}.fc-direction-ltr .fc-daygrid-event.fc-event-start,.fc-direction-rtl .fc-daygrid-event.fc-event-end{margin-left:2px}.fc-direction-ltr .fc-daygrid-event.fc-event-end,.fc-direction-rtl .fc-daygrid-event.fc-event-start{margin-right:2px}.fc-direction-ltr .fc-daygrid-week-number{border-radius:0 0 3px 0;left:0}.fc-direction-rtl .fc-daygrid-week-number{border-radius:0 0 0 3px;right:0}.fc-liquid-hack .fc-daygrid-day-frame{position:static}.fc-daygrid-event{border-radius:3px;font-size:var(--fc-small-font-size);position:relative;white-space:nowrap}.fc-daygrid-block-event .fc-event-time{font-weight:700}.fc-daygrid-block-event .fc-event-time,.fc-daygrid-block-event .fc-event-title{padding:1px}.fc-daygrid-dot-event{align-items:center;display:flex;padding:2px 0}.fc-daygrid-dot-event .fc-event-title{flex-grow:1;flex-shrink:1;font-weight:700;min-width:0;overflow:hidden}.fc-daygrid-dot-event.fc-event-mirror,.fc-daygrid-dot-event:hover{background:rgba(0,0,0,.1)}.fc-daygrid-dot-event.fc-event-selected:before{bottom:-10px;top:-10px}.fc-daygrid-event-dot{border:calc(var(--fc-daygrid-event-dot-width)/2) solid var(--fc-event-border-color);border-radius:calc(var(--fc-daygrid-event-dot-width)/2);box-sizing:content-box;height:0;margin:0 4px;width:0}.fc-direction-ltr .fc-daygrid-event .fc-event-time{margin-right:3px}.fc-direction-rtl .fc-daygrid-event .fc-event-time{margin-left:3px}\";\n(0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.i)(css_248z);\n\nvar index = (0,_fullcalendar_core__WEBPACK_IMPORTED_MODULE_1__.createPlugin)({\n name: '@fullcalendar/daygrid',\n initialView: 'dayGridMonth',\n views: {\n dayGrid: {\n component: _internal_esm_js__WEBPACK_IMPORTED_MODULE_2__.DayGridView,\n dateProfileGeneratorClass: TableDateProfileGenerator,\n },\n dayGridDay: {\n type: 'dayGrid',\n duration: { days: 1 },\n },\n dayGridWeek: {\n type: 'dayGrid',\n duration: { weeks: 1 },\n },\n dayGridMonth: {\n type: 'dayGrid',\n duration: { months: 1 },\n monthMode: true,\n fixedWeekCount: true,\n },\n },\n});\n\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvQGZ1bGxjYWxlbmRhci9kYXlncmlkL2luZGV4LmVzbS5qcy5qcyIsIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQWtEO0FBQ2M7QUFDc0M7QUFDbkU7O0FBRW5DLHdDQUF3QywwREFBb0I7QUFDNUQ7QUFDQTtBQUNBLGNBQWMsVUFBVTtBQUN4QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNCQUFzQiwrREFBUTtBQUM5QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLCtEQUFTO0FBQ3JCLGtCQUFrQiwrREFBUTtBQUMxQjtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBOztBQUVBLHNCQUFzQixpQ0FBaUMscUxBQXFMLFdBQVcsYUFBYSxjQUFjLHFCQUFxQixrQkFBa0IsVUFBVSxpQ0FBaUMsMENBQTBDLDBCQUEwQixnQkFBZ0Isa0JBQWtCLHdCQUF3QixhQUFhLDJCQUEyQixzQ0FBc0MsV0FBVywyQkFBMkIsWUFBWSxrQkFBa0IsVUFBVSwyQkFBMkIsZUFBZSxxREFBcUQsT0FBTyxrQkFBa0IsUUFBUSx1REFBdUQsZUFBZSxrQkFBa0Isb0RBQW9ELGtCQUFrQiw4QkFBOEIsa0JBQWtCLGtDQUFrQyxPQUFPLGtCQUFrQixRQUFRLE1BQU0sMkJBQTJCLFNBQVMsa0JBQWtCLE1BQU0sd0NBQXdDLFVBQVUsb0NBQW9DLFVBQVUscUNBQXFDLFVBQVUsc0JBQXNCLGVBQWUsVUFBVSxzQ0FBc0MsVUFBVSwyQkFBMkIsZ0JBQWdCLGtCQUFrQixrQ0FBa0MsV0FBVyxhQUFhLGNBQWMsMEJBQTBCLGVBQWUsa0JBQWtCLFVBQVUsNEJBQTRCLDRDQUE0QyxtQ0FBbUMsZ0JBQWdCLFlBQVksa0JBQWtCLGtCQUFrQixNQUFNLFVBQVUsc0NBQXNDLGdCQUFnQixhQUFhLG9HQUFvRyxnQkFBZ0Isb0dBQW9HLGlCQUFpQiwwQ0FBMEMsd0JBQXdCLE9BQU8sMENBQTBDLHdCQUF3QixRQUFRLHNDQUFzQyxnQkFBZ0Isa0JBQWtCLGtCQUFrQixvQ0FBb0Msa0JBQWtCLG1CQUFtQix1Q0FBdUMsZ0JBQWdCLCtFQUErRSxZQUFZLHNCQUFzQixtQkFBbUIsYUFBYSxjQUFjLHNDQUFzQyxZQUFZLGNBQWMsZ0JBQWdCLFlBQVksZ0JBQWdCLGtFQUFrRSwwQkFBMEIsK0NBQStDLGFBQWEsVUFBVSxzQkFBc0Isb0ZBQW9GLHdEQUF3RCx1QkFBdUIsU0FBUyxhQUFhLFFBQVEsbURBQW1ELGlCQUFpQixtREFBbUQsZ0JBQWdCO0FBQ3htRyw4REFBWTs7QUFFWixZQUFZLGdFQUFZO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCLHlEQUFZO0FBQ25DO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSx3QkFBd0IsU0FBUztBQUNqQyxTQUFTO0FBQ1Q7QUFDQTtBQUNBLHdCQUF3QixVQUFVO0FBQ2xDLFNBQVM7QUFDVDtBQUNBO0FBQ0Esd0JBQXdCLFdBQVc7QUFDbkM7QUFDQTtBQUNBLFNBQVM7QUFDVCxLQUFLO0FBQ0wsQ0FBQzs7QUFFMkIiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9WdWV4eS8uL25vZGVfbW9kdWxlcy9AZnVsbGNhbGVuZGFyL2RheWdyaWQvaW5kZXguZXNtLmpzPzA2OGUiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgY3JlYXRlUGx1Z2luIH0gZnJvbSAnQGZ1bGxjYWxlbmRhci9jb3JlJztcbmltcG9ydCB7IERheUdyaWRWaWV3IGFzIERheVRhYmxlVmlldyB9IGZyb20gJy4vaW50ZXJuYWwuZXNtLmpzJztcbmltcG9ydCB7IERhdGVQcm9maWxlR2VuZXJhdG9yLCBhZGRXZWVrcywgZGlmZldlZWtzLCBpbmplY3RTdHlsZXMgfSBmcm9tICdAZnVsbGNhbGVuZGFyL2NvcmUvaW50ZXJuYWwnO1xuaW1wb3J0ICdAZnVsbGNhbGVuZGFyL2NvcmUvcHJlYWN0JztcblxuY2xhc3MgVGFibGVEYXRlUHJvZmlsZUdlbmVyYXRvciBleHRlbmRzIERhdGVQcm9maWxlR2VuZXJhdG9yIHtcbiAgICAvLyBDb21wdXRlcyB0aGUgZGF0ZSByYW5nZSB0aGF0IHdpbGwgYmUgcmVuZGVyZWQuXG4gICAgYnVpbGRSZW5kZXJSYW5nZShjdXJyZW50UmFuZ2UsIGN1cnJlbnRSYW5nZVVuaXQsIGlzUmFuZ2VBbGxEYXkpIHtcbiAgICAgICAgbGV0IHsgZGF0ZUVudiB9ID0gdGhpcy5wcm9wcztcbiAgICAgICAgbGV0IHJlbmRlclJhbmdlID0gc3VwZXIuYnVpbGRSZW5kZXJSYW5nZShjdXJyZW50UmFuZ2UsIGN1cnJlbnRSYW5nZVVuaXQsIGlzUmFuZ2VBbGxEYXkpO1xuICAgICAgICBsZXQgc3RhcnQgPSByZW5kZXJSYW5nZS5zdGFydDtcbiAgICAgICAgbGV0IGVuZCA9IHJlbmRlclJhbmdlLmVuZDtcbiAgICAgICAgbGV0IGVuZE9mV2VlaztcbiAgICAgICAgLy8geWVhciBhbmQgbW9udGggdmlld3Mgc2hvdWxkIGJlIGFsaWduZWQgd2l0aCB3ZWVrcy4gdGhpcyBpcyBhbHJlYWR5IGRvbmUgZm9yIHdlZWtcbiAgICAgICAgaWYgKC9eKHllYXJ8bW9udGgpJC8udGVzdChjdXJyZW50UmFuZ2VVbml0KSkge1xuICAgICAgICAgICAgc3RhcnQgPSBkYXRlRW52LnN0YXJ0T2ZXZWVrKHN0YXJ0KTtcbiAgICAgICAgICAgIC8vIG1ha2UgZW5kLW9mLXdlZWsgaWYgbm90IGFscmVhZHlcbiAgICAgICAgICAgIGVuZE9mV2VlayA9IGRhdGVFbnYuc3RhcnRPZldlZWsoZW5kKTtcbiAgICAgICAgICAgIGlmIChlbmRPZldlZWsudmFsdWVPZigpICE9PSBlbmQudmFsdWVPZigpKSB7XG4gICAgICAgICAgICAgICAgZW5kID0gYWRkV2Vla3MoZW5kT2ZXZWVrLCAxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBlbnN1cmUgNiB3ZWVrc1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5tb250aE1vZGUgJiZcbiAgICAgICAgICAgIHRoaXMucHJvcHMuZml4ZWRXZWVrQ291bnQpIHtcbiAgICAgICAgICAgIGxldCByb3dDbnQgPSBNYXRoLmNlaWwoLy8gY291bGQgYmUgcGFydGlhbCB3ZWVrcyBkdWUgdG8gaGlkZGVuRGF5c1xuICAgICAgICAgICAgZGlmZldlZWtzKHN0YXJ0LCBlbmQpKTtcbiAgICAgICAgICAgIGVuZCA9IGFkZFdlZWtzKGVuZCwgNiAtIHJvd0NudCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsgc3RhcnQsIGVuZCB9O1xuICAgIH1cbn1cblxudmFyIGNzc18yNDh6ID0gXCI6cm9vdHstLWZjLWRheWdyaWQtZXZlbnQtZG90LXdpZHRoOjhweH0uZmMtZGF5Z3JpZC1kYXktZXZlbnRzOmFmdGVyLC5mYy1kYXlncmlkLWRheS1ldmVudHM6YmVmb3JlLC5mYy1kYXlncmlkLWRheS1mcmFtZTphZnRlciwuZmMtZGF5Z3JpZC1kYXktZnJhbWU6YmVmb3JlLC5mYy1kYXlncmlkLWV2ZW50LWhhcm5lc3M6YWZ0ZXIsLmZjLWRheWdyaWQtZXZlbnQtaGFybmVzczpiZWZvcmV7Y2xlYXI6Ym90aDtjb250ZW50OlxcXCJcXFwiO2Rpc3BsYXk6dGFibGV9LmZjIC5mYy1kYXlncmlkLWJvZHl7cG9zaXRpb246cmVsYXRpdmU7ei1pbmRleDoxfS5mYyAuZmMtZGF5Z3JpZC1kYXkuZmMtZGF5LXRvZGF5e2JhY2tncm91bmQtY29sb3I6dmFyKC0tZmMtdG9kYXktYmctY29sb3IpfS5mYyAuZmMtZGF5Z3JpZC1kYXktZnJhbWV7bWluLWhlaWdodDoxMDAlO3Bvc2l0aW9uOnJlbGF0aXZlfS5mYyAuZmMtZGF5Z3JpZC1kYXktdG9we2Rpc3BsYXk6ZmxleDtmbGV4LWRpcmVjdGlvbjpyb3ctcmV2ZXJzZX0uZmMgLmZjLWRheS1vdGhlciAuZmMtZGF5Z3JpZC1kYXktdG9we29wYWNpdHk6LjN9LmZjIC5mYy1kYXlncmlkLWRheS1udW1iZXJ7cGFkZGluZzo0cHg7cG9zaXRpb246cmVsYXRpdmU7ei1pbmRleDo0fS5mYyAuZmMtZGF5Z3JpZC1kYXktZXZlbnRze21hcmdpbi10b3A6MXB4fS5mYyAuZmMtZGF5Z3JpZC1ib2R5LWJhbGFuY2VkIC5mYy1kYXlncmlkLWRheS1ldmVudHN7bGVmdDowO3Bvc2l0aW9uOmFic29sdXRlO3JpZ2h0OjB9LmZjIC5mYy1kYXlncmlkLWJvZHktdW5iYWxhbmNlZCAuZmMtZGF5Z3JpZC1kYXktZXZlbnRze21pbi1oZWlnaHQ6MmVtO3Bvc2l0aW9uOnJlbGF0aXZlfS5mYyAuZmMtZGF5Z3JpZC1ib2R5LW5hdHVyYWwgLmZjLWRheWdyaWQtZGF5LWV2ZW50c3ttYXJnaW4tYm90dG9tOjFlbX0uZmMgLmZjLWRheWdyaWQtZXZlbnQtaGFybmVzc3twb3NpdGlvbjpyZWxhdGl2ZX0uZmMgLmZjLWRheWdyaWQtZXZlbnQtaGFybmVzcy1hYnN7bGVmdDowO3Bvc2l0aW9uOmFic29sdXRlO3JpZ2h0OjA7dG9wOjB9LmZjIC5mYy1kYXlncmlkLWJnLWhhcm5lc3N7Ym90dG9tOjA7cG9zaXRpb246YWJzb2x1dGU7dG9wOjB9LmZjIC5mYy1kYXlncmlkLWRheS1iZyAuZmMtbm9uLWJ1c2luZXNze3otaW5kZXg6MX0uZmMgLmZjLWRheWdyaWQtZGF5LWJnIC5mYy1iZy1ldmVudHt6LWluZGV4OjJ9LmZjIC5mYy1kYXlncmlkLWRheS1iZyAuZmMtaGlnaGxpZ2h0e3otaW5kZXg6M30uZmMgLmZjLWRheWdyaWQtZXZlbnR7bWFyZ2luLXRvcDoxcHg7ei1pbmRleDo2fS5mYyAuZmMtZGF5Z3JpZC1ldmVudC5mYy1ldmVudC1taXJyb3J7ei1pbmRleDo3fS5mYyAuZmMtZGF5Z3JpZC1kYXktYm90dG9te2ZvbnQtc2l6ZTouODVlbTtwYWRkaW5nOjJweCAzcHggMH0uZmMgLmZjLWRheWdyaWQtZGF5LWJvdHRvbTpiZWZvcmV7Y2xlYXI6Ym90aDtjb250ZW50OlxcXCJcXFwiO2Rpc3BsYXk6dGFibGV9LmZjIC5mYy1kYXlncmlkLW1vcmUtbGlua3tjdXJzb3I6cG9pbnRlcjtwb3NpdGlvbjpyZWxhdGl2ZTt6LWluZGV4OjR9LmZjIC5mYy1kYXlncmlkLXdlZWstbnVtYmVye2JhY2tncm91bmQtY29sb3I6dmFyKC0tZmMtbmV1dHJhbC1iZy1jb2xvcik7Y29sb3I6dmFyKC0tZmMtbmV1dHJhbC10ZXh0LWNvbG9yKTttaW4td2lkdGg6MS41ZW07cGFkZGluZzoycHg7cG9zaXRpb246YWJzb2x1dGU7dGV4dC1hbGlnbjpjZW50ZXI7dG9wOjA7ei1pbmRleDo1fS5mYyAuZmMtbW9yZS1wb3BvdmVyIC5mYy1wb3BvdmVyLWJvZHl7bWluLXdpZHRoOjIyMHB4O3BhZGRpbmc6MTBweH0uZmMtZGlyZWN0aW9uLWx0ciAuZmMtZGF5Z3JpZC1ldmVudC5mYy1ldmVudC1zdGFydCwuZmMtZGlyZWN0aW9uLXJ0bCAuZmMtZGF5Z3JpZC1ldmVudC5mYy1ldmVudC1lbmR7bWFyZ2luLWxlZnQ6MnB4fS5mYy1kaXJlY3Rpb24tbHRyIC5mYy1kYXlncmlkLWV2ZW50LmZjLWV2ZW50LWVuZCwuZmMtZGlyZWN0aW9uLXJ0bCAuZmMtZGF5Z3JpZC1ldmVudC5mYy1ldmVudC1zdGFydHttYXJnaW4tcmlnaHQ6MnB4fS5mYy1kaXJlY3Rpb24tbHRyIC5mYy1kYXlncmlkLXdlZWstbnVtYmVye2JvcmRlci1yYWRpdXM6MCAwIDNweCAwO2xlZnQ6MH0uZmMtZGlyZWN0aW9uLXJ0bCAuZmMtZGF5Z3JpZC13ZWVrLW51bWJlcntib3JkZXItcmFkaXVzOjAgMCAwIDNweDtyaWdodDowfS5mYy1saXF1aWQtaGFjayAuZmMtZGF5Z3JpZC1kYXktZnJhbWV7cG9zaXRpb246c3RhdGljfS5mYy1kYXlncmlkLWV2ZW50e2JvcmRlci1yYWRpdXM6M3B4O2ZvbnQtc2l6ZTp2YXIoLS1mYy1zbWFsbC1mb250LXNpemUpO3Bvc2l0aW9uOnJlbGF0aXZlO3doaXRlLXNwYWNlOm5vd3JhcH0uZmMtZGF5Z3JpZC1ibG9jay1ldmVudCAuZmMtZXZlbnQtdGltZXtmb250LXdlaWdodDo3MDB9LmZjLWRheWdyaWQtYmxvY2stZXZlbnQgLmZjLWV2ZW50LXRpbWUsLmZjLWRheWdyaWQtYmxvY2stZXZlbnQgLmZjLWV2ZW50LXRpdGxle3BhZGRpbmc6MXB4fS5mYy1kYXlncmlkLWRvdC1ldmVudHthbGlnbi1pdGVtczpjZW50ZXI7ZGlzcGxheTpmbGV4O3BhZGRpbmc6MnB4IDB9LmZjLWRheWdyaWQtZG90LWV2ZW50IC5mYy1ldmVudC10aXRsZXtmbGV4LWdyb3c6MTtmbGV4LXNocmluazoxO2ZvbnQtd2VpZ2h0OjcwMDttaW4td2lkdGg6MDtvdmVyZmxvdzpoaWRkZW59LmZjLWRheWdyaWQtZG90LWV2ZW50LmZjLWV2ZW50LW1pcnJvciwuZmMtZGF5Z3JpZC1kb3QtZXZlbnQ6aG92ZXJ7YmFja2dyb3VuZDpyZ2JhKDAsMCwwLC4xKX0uZmMtZGF5Z3JpZC1kb3QtZXZlbnQuZmMtZXZlbnQtc2VsZWN0ZWQ6YmVmb3Jle2JvdHRvbTotMTBweDt0b3A6LTEwcHh9LmZjLWRheWdyaWQtZXZlbnQtZG90e2JvcmRlcjpjYWxjKHZhcigtLWZjLWRheWdyaWQtZXZlbnQtZG90LXdpZHRoKS8yKSBzb2xpZCB2YXIoLS1mYy1ldmVudC1ib3JkZXItY29sb3IpO2JvcmRlci1yYWRpdXM6Y2FsYyh2YXIoLS1mYy1kYXlncmlkLWV2ZW50LWRvdC13aWR0aCkvMik7Ym94LXNpemluZzpjb250ZW50LWJveDtoZWlnaHQ6MDttYXJnaW46MCA0cHg7d2lkdGg6MH0uZmMtZGlyZWN0aW9uLWx0ciAuZmMtZGF5Z3JpZC1ldmVudCAuZmMtZXZlbnQtdGltZXttYXJnaW4tcmlnaHQ6M3B4fS5mYy1kaXJlY3Rpb24tcnRsIC5mYy1kYXlncmlkLWV2ZW50IC5mYy1ldmVudC10aW1le21hcmdpbi1sZWZ0OjNweH1cIjtcbmluamVjdFN0eWxlcyhjc3NfMjQ4eik7XG5cbnZhciBpbmRleCA9IGNyZWF0ZVBsdWdpbih7XG4gICAgbmFtZTogJ0BmdWxsY2FsZW5kYXIvZGF5Z3JpZCcsXG4gICAgaW5pdGlhbFZpZXc6ICdkYXlHcmlkTW9udGgnLFxuICAgIHZpZXdzOiB7XG4gICAgICAgIGRheUdyaWQ6IHtcbiAgICAgICAgICAgIGNvbXBvbmVudDogRGF5VGFibGVWaWV3LFxuICAgICAgICAgICAgZGF0ZVByb2ZpbGVHZW5lcmF0b3JDbGFzczogVGFibGVEYXRlUHJvZmlsZUdlbmVyYXRvcixcbiAgICAgICAgfSxcbiAgICAgICAgZGF5R3JpZERheToge1xuICAgICAgICAgICAgdHlwZTogJ2RheUdyaWQnLFxuICAgICAgICAgICAgZHVyYXRpb246IHsgZGF5czogMSB9LFxuICAgICAgICB9LFxuICAgICAgICBkYXlHcmlkV2Vlazoge1xuICAgICAgICAgICAgdHlwZTogJ2RheUdyaWQnLFxuICAgICAgICAgICAgZHVyYXRpb246IHsgd2Vla3M6IDEgfSxcbiAgICAgICAgfSxcbiAgICAgICAgZGF5R3JpZE1vbnRoOiB7XG4gICAgICAgICAgICB0eXBlOiAnZGF5R3JpZCcsXG4gICAgICAgICAgICBkdXJhdGlvbjogeyBtb250aHM6IDEgfSxcbiAgICAgICAgICAgIG1vbnRoTW9kZTogdHJ1ZSxcbiAgICAgICAgICAgIGZpeGVkV2Vla0NvdW50OiB0cnVlLFxuICAgICAgICB9LFxuICAgIH0sXG59KTtcblxuZXhwb3J0IHsgaW5kZXggYXMgZGVmYXVsdCB9O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/@fullcalendar/daygrid/index.esm.js\n"); /***/ }), /***/ "./node_modules/@fullcalendar/daygrid/internal.esm.js": /*!************************************************************!*\ !*** ./node_modules/@fullcalendar/daygrid/internal.esm.js ***! \************************************************************/ /***/ (function(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) { eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"DayGridView\": function() { return /* binding */ DayTableView; },\n/* harmony export */ \"DayTable\": function() { return /* binding */ DayTable; },\n/* harmony export */ \"DayTableSlicer\": function() { return /* binding */ DayTableSlicer; },\n/* harmony export */ \"Table\": function() { return /* binding */ Table; },\n/* harmony export */ \"TableView\": function() { return /* binding */ TableView; },\n/* harmony export */ \"buildDayTableModel\": function() { return /* binding */ buildDayTableModel; }\n/* harmony export */ });\n/* harmony import */ var _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @fullcalendar/core/internal */ \"./node_modules/@fullcalendar/core/internal-common.esm.js\");\n/* harmony import */ var _fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @fullcalendar/core/preact */ \"./node_modules/preact/dist/preact.module.js\");\n\n\n\n/* An abstract class for the daygrid views, as well as month view. Renders one or more rows of day cells.\n----------------------------------------------------------------------------------------------------------------------*/\n// It is a manager for a Table subcomponent, which does most of the heavy lifting.\n// It is responsible for managing width/height.\nclass TableView extends _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bf {\n constructor() {\n super(...arguments);\n this.headerElRef = (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createRef)();\n }\n renderSimpleLayout(headerRowContent, bodyContent) {\n let { props, context } = this;\n let sections = [];\n let stickyHeaderDates = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.cc)(context.options);\n if (headerRowContent) {\n sections.push({\n type: 'header',\n key: 'header',\n isSticky: stickyHeaderDates,\n chunk: {\n elRef: this.headerElRef,\n tableClassName: 'fc-col-header',\n rowContent: headerRowContent,\n },\n });\n }\n sections.push({\n type: 'body',\n key: 'body',\n liquid: true,\n chunk: { content: bodyContent },\n });\n return ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.ct, { elClasses: ['fc-daygrid'], viewSpec: context.viewSpec },\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.b$, { liquid: !props.isHeightAuto && !props.forPrint, collapsibleWidth: props.forPrint, cols: [] /* TODO: make optional? */, sections: sections })));\n }\n renderHScrollLayout(headerRowContent, bodyContent, colCnt, dayMinWidth) {\n let ScrollGrid = this.context.pluginHooks.scrollGridImpl;\n if (!ScrollGrid) {\n throw new Error('No ScrollGrid implementation');\n }\n let { props, context } = this;\n let stickyHeaderDates = !props.forPrint && (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.cc)(context.options);\n let stickyFooterScrollbar = !props.forPrint && (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.cb)(context.options);\n let sections = [];\n if (headerRowContent) {\n sections.push({\n type: 'header',\n key: 'header',\n isSticky: stickyHeaderDates,\n chunks: [{\n key: 'main',\n elRef: this.headerElRef,\n tableClassName: 'fc-col-header',\n rowContent: headerRowContent,\n }],\n });\n }\n sections.push({\n type: 'body',\n key: 'body',\n liquid: true,\n chunks: [{\n key: 'main',\n content: bodyContent,\n }],\n });\n if (stickyFooterScrollbar) {\n sections.push({\n type: 'footer',\n key: 'footer',\n isSticky: true,\n chunks: [{\n key: 'main',\n content: _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.ca,\n }],\n });\n }\n return ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.ct, { elClasses: ['fc-daygrid'], viewSpec: context.viewSpec },\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(ScrollGrid, { liquid: !props.isHeightAuto && !props.forPrint, collapsibleWidth: props.forPrint, colGroups: [{ cols: [{ span: colCnt, minWidth: dayMinWidth }] }], sections: sections })));\n }\n}\n\nfunction splitSegsByRow(segs, rowCnt) {\n let byRow = [];\n for (let i = 0; i < rowCnt; i += 1) {\n byRow[i] = [];\n }\n for (let seg of segs) {\n byRow[seg.row].push(seg);\n }\n return byRow;\n}\nfunction splitSegsByFirstCol(segs, colCnt) {\n let byCol = [];\n for (let i = 0; i < colCnt; i += 1) {\n byCol[i] = [];\n }\n for (let seg of segs) {\n byCol[seg.firstCol].push(seg);\n }\n return byCol;\n}\nfunction splitInteractionByRow(ui, rowCnt) {\n let byRow = [];\n if (!ui) {\n for (let i = 0; i < rowCnt; i += 1) {\n byRow[i] = null;\n }\n }\n else {\n for (let i = 0; i < rowCnt; i += 1) {\n byRow[i] = {\n affectedInstances: ui.affectedInstances,\n isEvent: ui.isEvent,\n segs: [],\n };\n }\n for (let seg of ui.segs) {\n byRow[seg.row].segs.push(seg);\n }\n }\n return byRow;\n}\n\nconst DEFAULT_TABLE_EVENT_TIME_FORMAT = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.x)({\n hour: 'numeric',\n minute: '2-digit',\n omitZeroMinute: true,\n meridiem: 'narrow',\n});\nfunction hasListItemDisplay(seg) {\n let { display } = seg.eventRange.ui;\n return display === 'list-item' || (display === 'auto' &&\n !seg.eventRange.def.allDay &&\n seg.firstCol === seg.lastCol && // can't be multi-day\n seg.isStart && // \"\n seg.isEnd // \"\n );\n}\n\nclass TableBlockEvent extends _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.Y {\n render() {\n let { props } = this;\n return ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.cj, Object.assign({}, props, { elClasses: ['fc-daygrid-event', 'fc-daygrid-block-event', 'fc-h-event'], defaultTimeFormat: DEFAULT_TABLE_EVENT_TIME_FORMAT, defaultDisplayEventEnd: props.defaultDisplayEventEnd, disableResizing: !props.seg.eventRange.def.allDay })));\n }\n}\n\nclass TableListItemEvent extends _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.Y {\n render() {\n let { props, context } = this;\n let { options } = context;\n let { seg } = props;\n let timeFormat = options.eventTimeFormat || DEFAULT_TABLE_EVENT_TIME_FORMAT;\n let timeText = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bQ)(seg, timeFormat, context, true, props.defaultDisplayEventEnd);\n return ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.cn, Object.assign({}, props, { elTag: \"a\", elClasses: ['fc-daygrid-event', 'fc-daygrid-dot-event'], elAttrs: (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bU)(props.seg, context), defaultGenerator: renderInnerContent, timeText: timeText, isResizing: false, isDateSelecting: false })));\n }\n}\nfunction renderInnerContent(renderProps) {\n return ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.Fragment, null,\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"div\", { className: \"fc-daygrid-event-dot\", style: { borderColor: renderProps.borderColor || renderProps.backgroundColor } }),\n renderProps.timeText && ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"div\", { className: \"fc-event-time\" }, renderProps.timeText)),\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"div\", { className: \"fc-event-title\" }, renderProps.event.title || (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.Fragment, null, \"\\u00A0\"))));\n}\n\nclass TableCellMoreLink extends _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.Y {\n constructor() {\n super(...arguments);\n this.compileSegs = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.z)(compileSegs);\n }\n render() {\n let { props } = this;\n let { allSegs, invisibleSegs } = this.compileSegs(props.singlePlacements);\n return ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.cr, { elClasses: ['fc-daygrid-more-link'], dateProfile: props.dateProfile, todayRange: props.todayRange, allDayDate: props.allDayDate, moreCnt: props.moreCnt, allSegs: allSegs, hiddenSegs: invisibleSegs, alignmentElRef: props.alignmentElRef, alignGridTop: props.alignGridTop, extraDateSpan: props.extraDateSpan, popoverContent: () => {\n let isForcedInvisible = (props.eventDrag ? props.eventDrag.affectedInstances : null) ||\n (props.eventResize ? props.eventResize.affectedInstances : null) ||\n {};\n return ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.Fragment, null, allSegs.map((seg) => {\n let instanceId = seg.eventRange.instance.instanceId;\n return ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"div\", { className: \"fc-daygrid-event-harness\", key: instanceId, style: {\n visibility: isForcedInvisible[instanceId] ? 'hidden' : '',\n } }, hasListItemDisplay(seg) ? ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(TableListItemEvent, Object.assign({ seg: seg, isDragging: false, isSelected: instanceId === props.eventSelection, defaultDisplayEventEnd: false }, (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bS)(seg, props.todayRange)))) : ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(TableBlockEvent, Object.assign({ seg: seg, isDragging: false, isResizing: false, isDateSelecting: false, isSelected: instanceId === props.eventSelection, defaultDisplayEventEnd: false }, (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bS)(seg, props.todayRange))))));\n })));\n } }));\n }\n}\nfunction compileSegs(singlePlacements) {\n let allSegs = [];\n let invisibleSegs = [];\n for (let placement of singlePlacements) {\n allSegs.push(placement.seg);\n if (!placement.isVisible) {\n invisibleSegs.push(placement.seg);\n }\n }\n return { allSegs, invisibleSegs };\n}\n\nconst DEFAULT_WEEK_NUM_FORMAT = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.x)({ week: 'narrow' });\nclass TableCell extends _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bf {\n constructor() {\n super(...arguments);\n this.rootElRef = (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createRef)();\n this.state = {\n dayNumberId: (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.a6)(),\n };\n this.handleRootEl = (el) => {\n (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.Z)(this.rootElRef, el);\n (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.Z)(this.props.elRef, el);\n };\n }\n render() {\n let { context, props, state, rootElRef } = this;\n let { options } = context;\n let { date, dateProfile } = props;\n return ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.cl, { elTag: \"td\", elRef: this.handleRootEl, elClasses: [\n 'fc-daygrid-day',\n ...(props.extraClassNames || []),\n ], elAttrs: Object.assign(Object.assign(Object.assign({}, props.extraDataAttrs), (props.showDayNumber ? { 'aria-labelledby': state.dayNumberId } : {})), { role: 'gridcell' }), defaultGenerator: renderTopInner, date: date, dateProfile: dateProfile, todayRange: props.todayRange, showDayNumber: props.showDayNumber, extraRenderProps: props.extraRenderProps }, (InnerContent, renderProps) => ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"div\", { className: \"fc-daygrid-day-frame fc-scrollgrid-sync-inner\", ref: props.innerElRef },\n props.showWeekNumber && ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.cq, { elTag: \"a\", elClasses: ['fc-daygrid-week-number'], elAttrs: (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.b1)(context, date, 'week'), date: date, defaultFormat: DEFAULT_WEEK_NUM_FORMAT })),\n Boolean(!renderProps.isDisabled &&\n (props.showDayNumber || (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.cm)(options) || props.forceDayTop)) && ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"div\", { className: \"fc-daygrid-day-top\" },\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(InnerContent, { elTag: \"a\", elClasses: ['fc-daygrid-day-number'], elAttrs: Object.assign(Object.assign({}, (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.b1)(context, date)), { id: state.dayNumberId }) }))),\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"div\", { className: \"fc-daygrid-day-events\", ref: props.fgContentElRef },\n props.fgContent,\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"div\", { className: \"fc-daygrid-day-bottom\", style: { marginTop: props.moreMarginTop } },\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(TableCellMoreLink, { allDayDate: date, singlePlacements: props.singlePlacements, moreCnt: props.moreCnt, alignmentElRef: rootElRef, alignGridTop: !props.showDayNumber, extraDateSpan: props.extraDateSpan, dateProfile: props.dateProfile, eventSelection: props.eventSelection, eventDrag: props.eventDrag, eventResize: props.eventResize, todayRange: props.todayRange }))),\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"div\", { className: \"fc-daygrid-day-bg\" }, props.bgContent)))));\n }\n}\nfunction renderTopInner(props) {\n return props.dayNumberText || (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.Fragment, null, \"\\u00A0\");\n}\n\nfunction computeFgSegPlacement(segs, // assumed already sorted\ndayMaxEvents, dayMaxEventRows, strictOrder, eventInstanceHeights, maxContentHeight, cells) {\n let hierarchy = new DayGridSegHierarchy();\n hierarchy.allowReslicing = true;\n hierarchy.strictOrder = strictOrder;\n if (dayMaxEvents === true || dayMaxEventRows === true) {\n hierarchy.maxCoord = maxContentHeight;\n hierarchy.hiddenConsumes = true;\n }\n else if (typeof dayMaxEvents === 'number') {\n hierarchy.maxStackCnt = dayMaxEvents;\n }\n else if (typeof dayMaxEventRows === 'number') {\n hierarchy.maxStackCnt = dayMaxEventRows;\n hierarchy.hiddenConsumes = true;\n }\n // create segInputs only for segs with known heights\n let segInputs = [];\n let unknownHeightSegs = [];\n for (let i = 0; i < segs.length; i += 1) {\n let seg = segs[i];\n let { instanceId } = seg.eventRange.instance;\n let eventHeight = eventInstanceHeights[instanceId];\n if (eventHeight != null) {\n segInputs.push({\n index: i,\n thickness: eventHeight,\n span: {\n start: seg.firstCol,\n end: seg.lastCol + 1,\n },\n });\n }\n else {\n unknownHeightSegs.push(seg);\n }\n }\n let hiddenEntries = hierarchy.addSegs(segInputs);\n let segRects = hierarchy.toRects();\n let { singleColPlacements, multiColPlacements, leftoverMargins } = placeRects(segRects, segs, cells);\n let moreCnts = [];\n let moreMarginTops = [];\n // add segs with unknown heights\n for (let seg of unknownHeightSegs) {\n multiColPlacements[seg.firstCol].push({\n seg,\n isVisible: false,\n isAbsolute: true,\n absoluteTop: 0,\n marginTop: 0,\n });\n for (let col = seg.firstCol; col <= seg.lastCol; col += 1) {\n singleColPlacements[col].push({\n seg: resliceSeg(seg, col, col + 1, cells),\n isVisible: false,\n isAbsolute: false,\n absoluteTop: 0,\n marginTop: 0,\n });\n }\n }\n // add the hidden entries\n for (let col = 0; col < cells.length; col += 1) {\n moreCnts.push(0);\n }\n for (let hiddenEntry of hiddenEntries) {\n let seg = segs[hiddenEntry.index];\n let hiddenSpan = hiddenEntry.span;\n multiColPlacements[hiddenSpan.start].push({\n seg: resliceSeg(seg, hiddenSpan.start, hiddenSpan.end, cells),\n isVisible: false,\n isAbsolute: true,\n absoluteTop: 0,\n marginTop: 0,\n });\n for (let col = hiddenSpan.start; col < hiddenSpan.end; col += 1) {\n moreCnts[col] += 1;\n singleColPlacements[col].push({\n seg: resliceSeg(seg, col, col + 1, cells),\n isVisible: false,\n isAbsolute: false,\n absoluteTop: 0,\n marginTop: 0,\n });\n }\n }\n // deal with leftover margins\n for (let col = 0; col < cells.length; col += 1) {\n moreMarginTops.push(leftoverMargins[col]);\n }\n return { singleColPlacements, multiColPlacements, moreCnts, moreMarginTops };\n}\n// rects ordered by top coord, then left\nfunction placeRects(allRects, segs, cells) {\n let rectsByEachCol = groupRectsByEachCol(allRects, cells.length);\n let singleColPlacements = [];\n let multiColPlacements = [];\n let leftoverMargins = [];\n for (let col = 0; col < cells.length; col += 1) {\n let rects = rectsByEachCol[col];\n // compute all static segs in singlePlacements\n let singlePlacements = [];\n let currentHeight = 0;\n let currentMarginTop = 0;\n for (let rect of rects) {\n let seg = segs[rect.index];\n singlePlacements.push({\n seg: resliceSeg(seg, col, col + 1, cells),\n isVisible: true,\n isAbsolute: false,\n absoluteTop: rect.levelCoord,\n marginTop: rect.levelCoord - currentHeight,\n });\n currentHeight = rect.levelCoord + rect.thickness;\n }\n // compute mixed static/absolute segs in multiPlacements\n let multiPlacements = [];\n currentHeight = 0;\n currentMarginTop = 0;\n for (let rect of rects) {\n let seg = segs[rect.index];\n let isAbsolute = rect.span.end - rect.span.start > 1; // multi-column?\n let isFirstCol = rect.span.start === col;\n currentMarginTop += rect.levelCoord - currentHeight; // amount of space since bottom of previous seg\n currentHeight = rect.levelCoord + rect.thickness; // height will now be bottom of current seg\n if (isAbsolute) {\n currentMarginTop += rect.thickness;\n if (isFirstCol) {\n multiPlacements.push({\n seg: resliceSeg(seg, rect.span.start, rect.span.end, cells),\n isVisible: true,\n isAbsolute: true,\n absoluteTop: rect.levelCoord,\n marginTop: 0,\n });\n }\n }\n else if (isFirstCol) {\n multiPlacements.push({\n seg: resliceSeg(seg, rect.span.start, rect.span.end, cells),\n isVisible: true,\n isAbsolute: false,\n absoluteTop: rect.levelCoord,\n marginTop: currentMarginTop, // claim the margin\n });\n currentMarginTop = 0;\n }\n }\n singleColPlacements.push(singlePlacements);\n multiColPlacements.push(multiPlacements);\n leftoverMargins.push(currentMarginTop);\n }\n return { singleColPlacements, multiColPlacements, leftoverMargins };\n}\nfunction groupRectsByEachCol(rects, colCnt) {\n let rectsByEachCol = [];\n for (let col = 0; col < colCnt; col += 1) {\n rectsByEachCol.push([]);\n }\n for (let rect of rects) {\n for (let col = rect.span.start; col < rect.span.end; col += 1) {\n rectsByEachCol[col].push(rect);\n }\n }\n return rectsByEachCol;\n}\nfunction resliceSeg(seg, spanStart, spanEnd, cells) {\n if (seg.firstCol === spanStart && seg.lastCol === spanEnd - 1) {\n return seg;\n }\n let eventRange = seg.eventRange;\n let origRange = eventRange.range;\n let slicedRange = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.o)(origRange, {\n start: cells[spanStart].date,\n end: (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.t)(cells[spanEnd - 1].date, 1),\n });\n return Object.assign(Object.assign({}, seg), { firstCol: spanStart, lastCol: spanEnd - 1, eventRange: {\n def: eventRange.def,\n ui: Object.assign(Object.assign({}, eventRange.ui), { durationEditable: false }),\n instance: eventRange.instance,\n range: slicedRange,\n }, isStart: seg.isStart && slicedRange.start.valueOf() === origRange.start.valueOf(), isEnd: seg.isEnd && slicedRange.end.valueOf() === origRange.end.valueOf() });\n}\nclass DayGridSegHierarchy extends _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bA {\n constructor() {\n super(...arguments);\n // config\n this.hiddenConsumes = false;\n // allows us to keep hidden entries in the hierarchy so they take up space\n this.forceHidden = {};\n }\n addSegs(segInputs) {\n const hiddenSegs = super.addSegs(segInputs);\n const { entriesByLevel } = this;\n const excludeHidden = (entry) => !this.forceHidden[(0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bB)(entry)];\n // remove the forced-hidden segs\n for (let level = 0; level < entriesByLevel.length; level += 1) {\n entriesByLevel[level] = entriesByLevel[level].filter(excludeHidden);\n }\n return hiddenSegs;\n }\n handleInvalidInsertion(insertion, entry, hiddenEntries) {\n const { entriesByLevel, forceHidden } = this;\n const { touchingEntry, touchingLevel, touchingLateral } = insertion;\n if (this.hiddenConsumes && touchingEntry) {\n const touchingEntryId = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bB)(touchingEntry);\n // if not already hidden\n if (!forceHidden[touchingEntryId]) {\n if (this.allowReslicing) {\n const placeholderEntry = Object.assign(Object.assign({}, touchingEntry), { span: (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bF)(touchingEntry.span, entry.span) });\n const placeholderEntryId = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bB)(placeholderEntry);\n forceHidden[placeholderEntryId] = true;\n entriesByLevel[touchingLevel][touchingLateral] = placeholderEntry; // replace touchingEntry with our placeholder\n this.splitEntry(touchingEntry, entry, hiddenEntries); // split up the touchingEntry, reinsert it\n }\n else {\n forceHidden[touchingEntryId] = true;\n hiddenEntries.push(touchingEntry);\n }\n }\n }\n return super.handleInvalidInsertion(insertion, entry, hiddenEntries);\n }\n}\n\nclass TableRow extends _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bf {\n constructor() {\n super(...arguments);\n this.cellElRefs = new _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.cf(); // the ?\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"tr\", { role: \"presentation\", className: \"fc-scrollgrid-section\" },\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"td\", { className: 'fc-timegrid-divider ' + context.theme.getClass('tableCellShaded') }))),\n });\n }\n sections.push({\n type: 'body',\n key: 'body',\n liquid: true,\n expandRows: Boolean(context.options.expandRows),\n chunk: {\n scrollerElRef: this.scrollerElRef,\n content: timeContent,\n },\n });\n return ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.ct, { elRef: this.rootElRef, elClasses: ['fc-timegrid'], viewSpec: context.viewSpec },\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.b$, { liquid: !props.isHeightAuto && !props.forPrint, collapsibleWidth: props.forPrint, cols: [{ width: 'shrink' }], sections: sections })));\n }\n renderHScrollLayout(headerRowContent, allDayContent, timeContent, colCnt, dayMinWidth, slatMetas, slatCoords) {\n let ScrollGrid = this.context.pluginHooks.scrollGridImpl;\n if (!ScrollGrid) {\n throw new Error('No ScrollGrid implementation');\n }\n let { context, props } = this;\n let stickyHeaderDates = !props.forPrint && (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.cc)(context.options);\n let stickyFooterScrollbar = !props.forPrint && (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.cb)(context.options);\n let sections = [];\n if (headerRowContent) {\n sections.push({\n type: 'header',\n key: 'header',\n isSticky: stickyHeaderDates,\n syncRowHeights: true,\n chunks: [\n {\n key: 'axis',\n rowContent: (arg) => ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"tr\", { role: \"presentation\" }, this.renderHeadAxis('day', arg.rowSyncHeights[0]))),\n },\n {\n key: 'cols',\n elRef: this.headerElRef,\n tableClassName: 'fc-col-header',\n rowContent: headerRowContent,\n },\n ],\n });\n }\n if (allDayContent) {\n sections.push({\n type: 'body',\n key: 'all-day',\n syncRowHeights: true,\n chunks: [\n {\n key: 'axis',\n rowContent: (contentArg) => ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"tr\", { role: \"presentation\" }, this.renderTableRowAxis(contentArg.rowSyncHeights[0]))),\n },\n {\n key: 'cols',\n content: allDayContent,\n },\n ],\n });\n sections.push({\n key: 'all-day-divider',\n type: 'body',\n outerContent: ( // TODO: rename to cellContent so don't need to define ?\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"tr\", { role: \"presentation\", className: \"fc-scrollgrid-section\" },\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"td\", { colSpan: 2, className: 'fc-timegrid-divider ' + context.theme.getClass('tableCellShaded') }))),\n });\n }\n let isNowIndicator = context.options.nowIndicator;\n sections.push({\n type: 'body',\n key: 'body',\n liquid: true,\n expandRows: Boolean(context.options.expandRows),\n chunks: [\n {\n key: 'axis',\n content: (arg) => (\n // TODO: make this now-indicator arrow more DRY with TimeColsContent\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"div\", { className: \"fc-timegrid-axis-chunk\" },\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"table\", { \"aria-hidden\": true, style: { height: arg.expandRows ? arg.clientHeight : '' } },\n arg.tableColGroupNode,\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"tbody\", null,\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(TimeBodyAxis, { slatMetas: slatMetas }))),\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"div\", { className: \"fc-timegrid-now-indicator-container\" },\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.ch, { unit: isNowIndicator ? 'minute' : 'day' /* hacky */ }, (nowDate) => {\n let nowIndicatorTop = isNowIndicator &&\n slatCoords &&\n slatCoords.safeComputeTop(nowDate); // might return void\n if (typeof nowIndicatorTop === 'number') {\n return ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.ck, { elClasses: ['fc-timegrid-now-indicator-arrow'], elStyle: { top: nowIndicatorTop }, isAxis: true, date: nowDate }));\n }\n return null;\n })))),\n },\n {\n key: 'cols',\n scrollerElRef: this.scrollerElRef,\n content: timeContent,\n },\n ],\n });\n if (stickyFooterScrollbar) {\n sections.push({\n key: 'footer',\n type: 'footer',\n isSticky: true,\n chunks: [\n {\n key: 'axis',\n content: _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.ca,\n },\n {\n key: 'cols',\n content: _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.ca,\n },\n ],\n });\n }\n return ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.ct, { elRef: this.rootElRef, elClasses: ['fc-timegrid'], viewSpec: context.viewSpec },\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(ScrollGrid, { liquid: !props.isHeightAuto && !props.forPrint, collapsibleWidth: false, colGroups: [\n { width: 'shrink', cols: [{ width: 'shrink' }] },\n { cols: [{ span: colCnt, minWidth: dayMinWidth }] },\n ], sections: sections })));\n }\n /* Dimensions\n ------------------------------------------------------------------------------------------------------------------*/\n getAllDayMaxEventProps() {\n let { dayMaxEvents, dayMaxEventRows } = this.context.options;\n if (dayMaxEvents === true || dayMaxEventRows === true) { // is auto?\n dayMaxEvents = undefined;\n dayMaxEventRows = AUTO_ALL_DAY_MAX_EVENT_ROWS; // make sure \"auto\" goes to a real number\n }\n return { dayMaxEvents, dayMaxEventRows };\n }\n}\nfunction renderAllDayInner(renderProps) {\n return renderProps.text;\n}\n\nclass TimeColsSlatsCoords {\n constructor(positions, dateProfile, slotDuration) {\n this.positions = positions;\n this.dateProfile = dateProfile;\n this.slotDuration = slotDuration;\n }\n safeComputeTop(date) {\n let { dateProfile } = this;\n if ((0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.H)(dateProfile.currentRange, date)) {\n let startOfDayDate = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.q)(date);\n let timeMs = date.valueOf() - startOfDayDate.valueOf();\n if (timeMs >= (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bt)(dateProfile.slotMinTime) &&\n timeMs < (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bt)(dateProfile.slotMaxTime)) {\n return this.computeTimeTop((0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.e)(timeMs));\n }\n }\n return null;\n }\n // Computes the top coordinate, relative to the bounds of the grid, of the given date.\n // A `startOfDayDate` must be given for avoiding ambiguity over how to treat midnight.\n computeDateTop(when, startOfDayDate) {\n if (!startOfDayDate) {\n startOfDayDate = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.q)(when);\n }\n return this.computeTimeTop((0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.e)(when.valueOf() - startOfDayDate.valueOf()));\n }\n // Computes the top coordinate, relative to the bounds of the grid, of the given time (a Duration).\n // This is a makeshify way to compute the time-top. Assumes all slatMetas dates are uniform.\n // Eventually allow computation with arbirary slat dates.\n computeTimeTop(duration) {\n let { positions, dateProfile } = this;\n let len = positions.els.length;\n // floating-point value of # of slots covered\n let slatCoverage = (duration.milliseconds - (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bt)(dateProfile.slotMinTime)) / (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bt)(this.slotDuration);\n let slatIndex;\n let slatRemainder;\n // compute a floating-point number for how many slats should be progressed through.\n // from 0 to number of slats (inclusive)\n // constrained because slotMinTime/slotMaxTime might be customized.\n slatCoverage = Math.max(0, slatCoverage);\n slatCoverage = Math.min(len, slatCoverage);\n // an integer index of the furthest whole slat\n // from 0 to number slats (*exclusive*, so len-1)\n slatIndex = Math.floor(slatCoverage);\n slatIndex = Math.min(slatIndex, len - 1);\n // how much further through the slatIndex slat (from 0.0-1.0) must be covered in addition.\n // could be 1.0 if slatCoverage is covering *all* the slots\n slatRemainder = slatCoverage - slatIndex;\n return positions.tops[slatIndex] +\n positions.getHeight(slatIndex) * slatRemainder;\n }\n}\n\nclass TimeColsSlatsBody extends _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.Y {\n render() {\n let { props, context } = this;\n let { options } = context;\n let { slatElRefs } = props;\n return ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"tbody\", null, props.slatMetas.map((slatMeta, i) => {\n let renderProps = {\n time: slatMeta.time,\n date: context.dateEnv.toDate(slatMeta.date),\n view: context.viewApi,\n };\n return ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"tr\", { key: slatMeta.key, ref: slatElRefs.createRef(slatMeta.key) },\n props.axis && ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(TimeColsAxisCell, Object.assign({}, slatMeta))),\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.C, { elTag: \"td\", elClasses: [\n 'fc-timegrid-slot',\n 'fc-timegrid-slot-lane',\n !slatMeta.isLabeled && 'fc-timegrid-slot-minor',\n ], elAttrs: {\n 'data-time': slatMeta.isoTimeStr,\n }, renderProps: renderProps, generatorName: \"slotLaneContent\", generator: options.slotLaneContent, classNameGenerator: options.slotLaneClassNames, didMount: options.slotLaneDidMount, willUnmount: options.slotLaneWillUnmount })));\n })));\n }\n}\n\n/*\nfor the horizontal \"slats\" that run width-wise. Has a time axis on a side. Depends on RTL.\n*/\nclass TimeColsSlats extends _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.Y {\n constructor() {\n super(...arguments);\n this.rootElRef = (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createRef)();\n this.slatElRefs = new _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.cf();\n }\n render() {\n let { props, context } = this;\n return ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"div\", { ref: this.rootElRef, className: \"fc-timegrid-slots\" },\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"table\", { \"aria-hidden\": true, className: context.theme.getClass('table'), style: {\n minWidth: props.tableMinWidth,\n width: props.clientWidth,\n height: props.minHeight,\n } },\n props.tableColGroupNode /* relies on there only being a single for the axis */,\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(TimeColsSlatsBody, { slatElRefs: this.slatElRefs, axis: props.axis, slatMetas: props.slatMetas }))));\n }\n componentDidMount() {\n this.updateSizing();\n }\n componentDidUpdate() {\n this.updateSizing();\n }\n componentWillUnmount() {\n if (this.props.onCoords) {\n this.props.onCoords(null);\n }\n }\n updateSizing() {\n let { context, props } = this;\n if (props.onCoords &&\n props.clientWidth !== null // means sizing has stabilized\n ) {\n let rootEl = this.rootElRef.current;\n if (rootEl.offsetHeight) { // not hidden by css\n props.onCoords(new TimeColsSlatsCoords(new _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bb(this.rootElRef.current, collectSlatEls(this.slatElRefs.currentMap, props.slatMetas), false, true), this.props.dateProfile, context.options.slotDuration));\n }\n }\n }\n}\nfunction collectSlatEls(elMap, slatMetas) {\n return slatMetas.map((slatMeta) => elMap[slatMeta.key]);\n}\n\nfunction splitSegsByCol(segs, colCnt) {\n let segsByCol = [];\n let i;\n for (i = 0; i < colCnt; i += 1) {\n segsByCol.push([]);\n }\n if (segs) {\n for (i = 0; i < segs.length; i += 1) {\n segsByCol[segs[i].col].push(segs[i]);\n }\n }\n return segsByCol;\n}\nfunction splitInteractionByCol(ui, colCnt) {\n let byRow = [];\n if (!ui) {\n for (let i = 0; i < colCnt; i += 1) {\n byRow[i] = null;\n }\n }\n else {\n for (let i = 0; i < colCnt; i += 1) {\n byRow[i] = {\n affectedInstances: ui.affectedInstances,\n isEvent: ui.isEvent,\n segs: [],\n };\n }\n for (let seg of ui.segs) {\n byRow[seg.col].segs.push(seg);\n }\n }\n return byRow;\n}\n\nclass TimeColMoreLink extends _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.Y {\n render() {\n let { props } = this;\n return ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.cr, { elClasses: ['fc-timegrid-more-link'], elStyle: {\n top: props.top,\n bottom: props.bottom,\n }, allDayDate: null, moreCnt: props.hiddenSegs.length, allSegs: props.hiddenSegs, hiddenSegs: props.hiddenSegs, extraDateSpan: props.extraDateSpan, dateProfile: props.dateProfile, todayRange: props.todayRange, popoverContent: () => renderPlainFgSegs(props.hiddenSegs, props), defaultGenerator: renderMoreLinkInner }, (InnerContent) => ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(InnerContent, { elTag: \"div\", elClasses: ['fc-timegrid-more-link-inner', 'fc-sticky'] }))));\n }\n}\nfunction renderMoreLinkInner(props) {\n return props.shortText;\n}\n\n// segInputs assumed sorted\nfunction buildPositioning(segInputs, strictOrder, maxStackCnt) {\n let hierarchy = new _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bA();\n if (strictOrder != null) {\n hierarchy.strictOrder = strictOrder;\n }\n if (maxStackCnt != null) {\n hierarchy.maxStackCnt = maxStackCnt;\n }\n let hiddenEntries = hierarchy.addSegs(segInputs);\n let hiddenGroups = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bE)(hiddenEntries);\n let web = buildWeb(hierarchy);\n web = stretchWeb(web, 1); // all levelCoords/thickness will have 0.0-1.0\n let segRects = webToRects(web);\n return { segRects, hiddenGroups };\n}\nfunction buildWeb(hierarchy) {\n const { entriesByLevel } = hierarchy;\n const buildNode = cacheable((level, lateral) => level + ':' + lateral, (level, lateral) => {\n let siblingRange = findNextLevelSegs(hierarchy, level, lateral);\n let nextLevelRes = buildNodes(siblingRange, buildNode);\n let entry = entriesByLevel[level][lateral];\n return [\n Object.assign(Object.assign({}, entry), { nextLevelNodes: nextLevelRes[0] }),\n entry.thickness + nextLevelRes[1], // the pressure builds\n ];\n });\n return buildNodes(entriesByLevel.length\n ? { level: 0, lateralStart: 0, lateralEnd: entriesByLevel[0].length }\n : null, buildNode)[0];\n}\nfunction buildNodes(siblingRange, buildNode) {\n if (!siblingRange) {\n return [[], 0];\n }\n let { level, lateralStart, lateralEnd } = siblingRange;\n let lateral = lateralStart;\n let pairs = [];\n while (lateral < lateralEnd) {\n pairs.push(buildNode(level, lateral));\n lateral += 1;\n }\n pairs.sort(cmpDescPressures);\n return [\n pairs.map(extractNode),\n pairs[0][1], // first item's pressure\n ];\n}\nfunction cmpDescPressures(a, b) {\n return b[1] - a[1];\n}\nfunction extractNode(a) {\n return a[0];\n}\nfunction findNextLevelSegs(hierarchy, subjectLevel, subjectLateral) {\n let { levelCoords, entriesByLevel } = hierarchy;\n let subjectEntry = entriesByLevel[subjectLevel][subjectLateral];\n let afterSubject = levelCoords[subjectLevel] + subjectEntry.thickness;\n let levelCnt = levelCoords.length;\n let level = subjectLevel;\n // skip past levels that are too high up\n for (; level < levelCnt && levelCoords[level] < afterSubject; level += 1)\n ; // do nothing\n for (; level < levelCnt; level += 1) {\n let entries = entriesByLevel[level];\n let entry;\n let searchIndex = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bD)(entries, subjectEntry.span.start, _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bC);\n let lateralStart = searchIndex[0] + searchIndex[1]; // if exact match (which doesn't collide), go to next one\n let lateralEnd = lateralStart;\n while ( // loop through entries that horizontally intersect\n (entry = entries[lateralEnd]) && // but not past the whole seg list\n entry.span.start < subjectEntry.span.end) {\n lateralEnd += 1;\n }\n if (lateralStart < lateralEnd) {\n return { level, lateralStart, lateralEnd };\n }\n }\n return null;\n}\nfunction stretchWeb(topLevelNodes, totalThickness) {\n const stretchNode = cacheable((node, startCoord, prevThickness) => (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bB)(node), (node, startCoord, prevThickness) => {\n let { nextLevelNodes, thickness } = node;\n let allThickness = thickness + prevThickness;\n let thicknessFraction = thickness / allThickness;\n let endCoord;\n let newChildren = [];\n if (!nextLevelNodes.length) {\n endCoord = totalThickness;\n }\n else {\n for (let childNode of nextLevelNodes) {\n if (endCoord === undefined) {\n let res = stretchNode(childNode, startCoord, allThickness);\n endCoord = res[0];\n newChildren.push(res[1]);\n }\n else {\n let res = stretchNode(childNode, endCoord, 0);\n newChildren.push(res[1]);\n }\n }\n }\n let newThickness = (endCoord - startCoord) * thicknessFraction;\n return [endCoord - newThickness, Object.assign(Object.assign({}, node), { thickness: newThickness, nextLevelNodes: newChildren })];\n });\n return topLevelNodes.map((node) => stretchNode(node, 0, 0)[1]);\n}\n// not sorted in any particular order\nfunction webToRects(topLevelNodes) {\n let rects = [];\n const processNode = cacheable((node, levelCoord, stackDepth) => (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bB)(node), (node, levelCoord, stackDepth) => {\n let rect = Object.assign(Object.assign({}, node), { levelCoord,\n stackDepth, stackForward: 0 });\n rects.push(rect);\n return (rect.stackForward = processNodes(node.nextLevelNodes, levelCoord + node.thickness, stackDepth + 1) + 1);\n });\n function processNodes(nodes, levelCoord, stackDepth) {\n let stackForward = 0;\n for (let node of nodes) {\n stackForward = Math.max(processNode(node, levelCoord, stackDepth), stackForward);\n }\n return stackForward;\n }\n processNodes(topLevelNodes, 0, 0);\n return rects; // TODO: sort rects by levelCoord to be consistent with toRects?\n}\n// TODO: move to general util\nfunction cacheable(keyFunc, workFunc) {\n const cache = {};\n return (...args) => {\n let key = keyFunc(...args);\n return (key in cache)\n ? cache[key]\n : (cache[key] = workFunc(...args));\n };\n}\n\nfunction computeSegVCoords(segs, colDate, slatCoords = null, eventMinHeight = 0) {\n let vcoords = [];\n if (slatCoords) {\n for (let i = 0; i < segs.length; i += 1) {\n let seg = segs[i];\n let spanStart = slatCoords.computeDateTop(seg.start, colDate);\n let spanEnd = Math.max(spanStart + (eventMinHeight || 0), // :(\n slatCoords.computeDateTop(seg.end, colDate));\n vcoords.push({\n start: Math.round(spanStart),\n end: Math.round(spanEnd), //\n });\n }\n }\n return vcoords;\n}\nfunction computeFgSegPlacements(segs, segVCoords, // might not have for every seg\neventOrderStrict, eventMaxStack) {\n let segInputs = [];\n let dumbSegs = []; // segs without coords\n for (let i = 0; i < segs.length; i += 1) {\n let vcoords = segVCoords[i];\n if (vcoords) {\n segInputs.push({\n index: i,\n thickness: 1,\n span: vcoords,\n });\n }\n else {\n dumbSegs.push(segs[i]);\n }\n }\n let { segRects, hiddenGroups } = buildPositioning(segInputs, eventOrderStrict, eventMaxStack);\n let segPlacements = [];\n for (let segRect of segRects) {\n segPlacements.push({\n seg: segs[segRect.index],\n rect: segRect,\n });\n }\n for (let dumbSeg of dumbSegs) {\n segPlacements.push({ seg: dumbSeg, rect: null });\n }\n return { segPlacements, hiddenGroups };\n}\n\nconst DEFAULT_TIME_FORMAT = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.x)({\n hour: 'numeric',\n minute: '2-digit',\n meridiem: false,\n});\nclass TimeColEvent extends _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.Y {\n render() {\n return ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.cj, Object.assign({}, this.props, { elClasses: [\n 'fc-timegrid-event',\n 'fc-v-event',\n this.props.isShort && 'fc-timegrid-event-short',\n ], defaultTimeFormat: DEFAULT_TIME_FORMAT })));\n }\n}\n\nclass TimeCol extends _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.Y {\n constructor() {\n super(...arguments);\n this.sortEventSegs = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.z)(_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bR);\n }\n // TODO: memoize event-placement?\n render() {\n let { props, context } = this;\n let { options } = context;\n let isSelectMirror = options.selectMirror;\n let mirrorSegs = // yuck\n (props.eventDrag && props.eventDrag.segs) ||\n (props.eventResize && props.eventResize.segs) ||\n (isSelectMirror && props.dateSelectionSegs) ||\n [];\n let interactionAffectedInstances = // TODO: messy way to compute this\n (props.eventDrag && props.eventDrag.affectedInstances) ||\n (props.eventResize && props.eventResize.affectedInstances) ||\n {};\n let sortedFgSegs = this.sortEventSegs(props.fgEventSegs, options.eventOrder);\n return ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.cl, { elTag: \"td\", elRef: props.elRef, elClasses: [\n 'fc-timegrid-col',\n ...(props.extraClassNames || []),\n ], elAttrs: Object.assign({ role: 'gridcell' }, props.extraDataAttrs), date: props.date, dateProfile: props.dateProfile, todayRange: props.todayRange, extraRenderProps: props.extraRenderProps }, (InnerContent) => ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"div\", { className: \"fc-timegrid-col-frame\" },\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"div\", { className: \"fc-timegrid-col-bg\" },\n this.renderFillSegs(props.businessHourSegs, 'non-business'),\n this.renderFillSegs(props.bgEventSegs, 'bg-event'),\n this.renderFillSegs(props.dateSelectionSegs, 'highlight')),\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"div\", { className: \"fc-timegrid-col-events\" }, this.renderFgSegs(sortedFgSegs, interactionAffectedInstances, false, false, false)),\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"div\", { className: \"fc-timegrid-col-events\" }, this.renderFgSegs(mirrorSegs, {}, Boolean(props.eventDrag), Boolean(props.eventResize), Boolean(isSelectMirror))),\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"div\", { className: \"fc-timegrid-now-indicator-container\" }, this.renderNowIndicator(props.nowIndicatorSegs)),\n (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.cm)(options) && ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(InnerContent, { elTag: \"div\", elClasses: ['fc-timegrid-col-misc'] }))))));\n }\n renderFgSegs(sortedFgSegs, segIsInvisible, isDragging, isResizing, isDateSelecting) {\n let { props } = this;\n if (props.forPrint) {\n return renderPlainFgSegs(sortedFgSegs, props);\n }\n return this.renderPositionedFgSegs(sortedFgSegs, segIsInvisible, isDragging, isResizing, isDateSelecting);\n }\n renderPositionedFgSegs(segs, // if not mirror, needs to be sorted\n segIsInvisible, isDragging, isResizing, isDateSelecting) {\n let { eventMaxStack, eventShortHeight, eventOrderStrict, eventMinHeight } = this.context.options;\n let { date, slatCoords, eventSelection, todayRange, nowDate } = this.props;\n let isMirror = isDragging || isResizing || isDateSelecting;\n let segVCoords = computeSegVCoords(segs, date, slatCoords, eventMinHeight);\n let { segPlacements, hiddenGroups } = computeFgSegPlacements(segs, segVCoords, eventOrderStrict, eventMaxStack);\n return ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.Fragment, null,\n this.renderHiddenGroups(hiddenGroups, segs),\n segPlacements.map((segPlacement) => {\n let { seg, rect } = segPlacement;\n let instanceId = seg.eventRange.instance.instanceId;\n let isVisible = isMirror || Boolean(!segIsInvisible[instanceId] && rect);\n let vStyle = computeSegVStyle(rect && rect.span);\n let hStyle = (!isMirror && rect) ? this.computeSegHStyle(rect) : { left: 0, right: 0 };\n let isInset = Boolean(rect) && rect.stackForward > 0;\n let isShort = Boolean(rect) && (rect.span.end - rect.span.start) < eventShortHeight; // look at other places for this problem\n return ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"div\", { className: 'fc-timegrid-event-harness' +\n (isInset ? ' fc-timegrid-event-harness-inset' : ''), key: instanceId, style: Object.assign(Object.assign({ visibility: isVisible ? '' : 'hidden' }, vStyle), hStyle) },\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(TimeColEvent, Object.assign({ seg: seg, isDragging: isDragging, isResizing: isResizing, isDateSelecting: isDateSelecting, isSelected: instanceId === eventSelection, isShort: isShort }, (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bS)(seg, todayRange, nowDate)))));\n })));\n }\n // will already have eventMinHeight applied because segInputs already had it\n renderHiddenGroups(hiddenGroups, segs) {\n let { extraDateSpan, dateProfile, todayRange, nowDate, eventSelection, eventDrag, eventResize } = this.props;\n return ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.Fragment, null, hiddenGroups.map((hiddenGroup) => {\n let positionCss = computeSegVStyle(hiddenGroup.span);\n let hiddenSegs = compileSegsFromEntries(hiddenGroup.entries, segs);\n return ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(TimeColMoreLink, { key: (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bx)((0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.cs)(hiddenSegs)), hiddenSegs: hiddenSegs, top: positionCss.top, bottom: positionCss.bottom, extraDateSpan: extraDateSpan, dateProfile: dateProfile, todayRange: todayRange, nowDate: nowDate, eventSelection: eventSelection, eventDrag: eventDrag, eventResize: eventResize }));\n })));\n }\n renderFillSegs(segs, fillType) {\n let { props, context } = this;\n let segVCoords = computeSegVCoords(segs, props.date, props.slatCoords, context.options.eventMinHeight); // don't assume all populated\n let children = segVCoords.map((vcoords, i) => {\n let seg = segs[i];\n return ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"div\", { key: (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bT)(seg.eventRange), className: \"fc-timegrid-bg-harness\", style: computeSegVStyle(vcoords) }, fillType === 'bg-event' ?\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.cp, Object.assign({ seg: seg }, (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bS)(seg, props.todayRange, props.nowDate))) :\n (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.co)(fillType)));\n });\n return (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.Fragment, null, children);\n }\n renderNowIndicator(segs) {\n let { slatCoords, date } = this.props;\n if (!slatCoords) {\n return null;\n }\n return segs.map((seg, i) => ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.ck\n // key doesn't matter. will only ever be one\n , { \n // key doesn't matter. will only ever be one\n key: i, elClasses: ['fc-timegrid-now-indicator-line'], elStyle: {\n top: slatCoords.computeDateTop(seg.start, date),\n }, isAxis: false, date: date })));\n }\n computeSegHStyle(segHCoords) {\n let { isRtl, options } = this.context;\n let shouldOverlap = options.slotEventOverlap;\n let nearCoord = segHCoords.levelCoord; // the left side if LTR. the right side if RTL. floating-point\n let farCoord = segHCoords.levelCoord + segHCoords.thickness; // the right side if LTR. the left side if RTL. floating-point\n let left; // amount of space from left edge, a fraction of the total width\n let right; // amount of space from right edge, a fraction of the total width\n if (shouldOverlap) {\n // double the width, but don't go beyond the maximum forward coordinate (1.0)\n farCoord = Math.min(1, nearCoord + (farCoord - nearCoord) * 2);\n }\n if (isRtl) {\n left = 1 - farCoord;\n right = nearCoord;\n }\n else {\n left = nearCoord;\n right = 1 - farCoord;\n }\n let props = {\n zIndex: segHCoords.stackDepth + 1,\n left: left * 100 + '%',\n right: right * 100 + '%',\n };\n if (shouldOverlap && !segHCoords.stackForward) {\n // add padding to the edge so that forward stacked events don't cover the resizer's icon\n props[isRtl ? 'marginLeft' : 'marginRight'] = 10 * 2; // 10 is a guesstimate of the icon's width\n }\n return props;\n }\n}\nfunction renderPlainFgSegs(sortedFgSegs, { todayRange, nowDate, eventSelection, eventDrag, eventResize }) {\n let hiddenInstances = (eventDrag ? eventDrag.affectedInstances : null) ||\n (eventResize ? eventResize.affectedInstances : null) ||\n {};\n return ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.Fragment, null, sortedFgSegs.map((seg) => {\n let instanceId = seg.eventRange.instance.instanceId;\n return ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"div\", { key: instanceId, style: { visibility: hiddenInstances[instanceId] ? 'hidden' : '' } },\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(TimeColEvent, Object.assign({ seg: seg, isDragging: false, isResizing: false, isDateSelecting: false, isSelected: instanceId === eventSelection, isShort: false }, (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bS)(seg, todayRange, nowDate)))));\n })));\n}\nfunction computeSegVStyle(segVCoords) {\n if (!segVCoords) {\n return { top: '', bottom: '' };\n }\n return {\n top: segVCoords.start,\n bottom: -segVCoords.end,\n };\n}\nfunction compileSegsFromEntries(segEntries, allSegs) {\n return segEntries.map((segEntry) => allSegs[segEntry.index]);\n}\n\nclass TimeColsContent extends _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.Y {\n constructor() {\n super(...arguments);\n this.splitFgEventSegs = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.z)(splitSegsByCol);\n this.splitBgEventSegs = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.z)(splitSegsByCol);\n this.splitBusinessHourSegs = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.z)(splitSegsByCol);\n this.splitNowIndicatorSegs = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.z)(splitSegsByCol);\n this.splitDateSelectionSegs = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.z)(splitSegsByCol);\n this.splitEventDrag = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.z)(splitInteractionByCol);\n this.splitEventResize = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.z)(splitInteractionByCol);\n this.rootElRef = (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createRef)();\n this.cellElRefs = new _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.cf();\n }\n render() {\n let { props, context } = this;\n let nowIndicatorTop = context.options.nowIndicator &&\n props.slatCoords &&\n props.slatCoords.safeComputeTop(props.nowDate); // might return void\n let colCnt = props.cells.length;\n let fgEventSegsByRow = this.splitFgEventSegs(props.fgEventSegs, colCnt);\n let bgEventSegsByRow = this.splitBgEventSegs(props.bgEventSegs, colCnt);\n let businessHourSegsByRow = this.splitBusinessHourSegs(props.businessHourSegs, colCnt);\n let nowIndicatorSegsByRow = this.splitNowIndicatorSegs(props.nowIndicatorSegs, colCnt);\n let dateSelectionSegsByRow = this.splitDateSelectionSegs(props.dateSelectionSegs, colCnt);\n let eventDragByRow = this.splitEventDrag(props.eventDrag, colCnt);\n let eventResizeByRow = this.splitEventResize(props.eventResize, colCnt);\n return ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"div\", { className: \"fc-timegrid-cols\", ref: this.rootElRef },\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"table\", { role: \"presentation\", style: {\n minWidth: props.tableMinWidth,\n width: props.clientWidth,\n } },\n props.tableColGroupNode,\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"tbody\", { role: \"presentation\" },\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"tr\", { role: \"row\" },\n props.axis && ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"td\", { \"aria-hidden\": true, className: \"fc-timegrid-col fc-timegrid-axis\" },\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"div\", { className: \"fc-timegrid-col-frame\" },\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"div\", { className: \"fc-timegrid-now-indicator-container\" }, typeof nowIndicatorTop === 'number' && ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.ck, { elClasses: ['fc-timegrid-now-indicator-arrow'], elStyle: { top: nowIndicatorTop }, isAxis: true, date: props.nowDate })))))),\n props.cells.map((cell, i) => ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(TimeCol, { key: cell.key, elRef: this.cellElRefs.createRef(cell.key), dateProfile: props.dateProfile, date: cell.date, nowDate: props.nowDate, todayRange: props.todayRange, extraRenderProps: cell.extraRenderProps, extraDataAttrs: cell.extraDataAttrs, extraClassNames: cell.extraClassNames, extraDateSpan: cell.extraDateSpan, fgEventSegs: fgEventSegsByRow[i], bgEventSegs: bgEventSegsByRow[i], businessHourSegs: businessHourSegsByRow[i], nowIndicatorSegs: nowIndicatorSegsByRow[i], dateSelectionSegs: dateSelectionSegsByRow[i], eventDrag: eventDragByRow[i], eventResize: eventResizeByRow[i], slatCoords: props.slatCoords, eventSelection: props.eventSelection, forPrint: props.forPrint }))))))));\n }\n componentDidMount() {\n this.updateCoords();\n }\n componentDidUpdate() {\n this.updateCoords();\n }\n updateCoords() {\n let { props } = this;\n if (props.onColCoords &&\n props.clientWidth !== null // means sizing has stabilized\n ) {\n props.onColCoords(new _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bb(this.rootElRef.current, collectCellEls(this.cellElRefs.currentMap, props.cells), true, // horizontal\n false));\n }\n }\n}\nfunction collectCellEls(elMap, cells) {\n return cells.map((cell) => elMap[cell.key]);\n}\n\n/* A component that renders one or more columns of vertical time slots\n----------------------------------------------------------------------------------------------------------------------*/\nclass TimeCols extends _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bf {\n constructor() {\n super(...arguments);\n this.processSlotOptions = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.z)(processSlotOptions);\n this.state = {\n slatCoords: null,\n };\n this.handleRootEl = (el) => {\n if (el) {\n this.context.registerInteractiveComponent(this, {\n el,\n isHitComboAllowed: this.props.isHitComboAllowed,\n });\n }\n else {\n this.context.unregisterInteractiveComponent(this);\n }\n };\n this.handleScrollRequest = (request) => {\n let { onScrollTopRequest } = this.props;\n let { slatCoords } = this.state;\n if (onScrollTopRequest && slatCoords) {\n if (request.time) {\n let top = slatCoords.computeTimeTop(request.time);\n top = Math.ceil(top); // zoom can give weird floating-point values. rather scroll a little bit further\n if (top) {\n top += 1; // to overcome top border that slots beyond the first have. looks better\n }\n onScrollTopRequest(top);\n }\n return true;\n }\n return false;\n };\n this.handleColCoords = (colCoords) => {\n this.colCoords = colCoords;\n };\n this.handleSlatCoords = (slatCoords) => {\n this.setState({ slatCoords });\n if (this.props.onSlatCoords) {\n this.props.onSlatCoords(slatCoords);\n }\n };\n }\n render() {\n let { props, state } = this;\n return ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"div\", { className: \"fc-timegrid-body\", ref: this.handleRootEl, style: {\n // these props are important to give this wrapper correct dimensions for interactions\n // TODO: if we set it here, can we avoid giving to inner tables?\n width: props.clientWidth,\n minWidth: props.tableMinWidth,\n } },\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(TimeColsSlats, { axis: props.axis, dateProfile: props.dateProfile, slatMetas: props.slatMetas, clientWidth: props.clientWidth, minHeight: props.expandRows ? props.clientHeight : '', tableMinWidth: props.tableMinWidth, tableColGroupNode: props.axis ? props.tableColGroupNode : null /* axis depends on the colgroup's shrinking */, onCoords: this.handleSlatCoords }),\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(TimeColsContent, { cells: props.cells, axis: props.axis, dateProfile: props.dateProfile, businessHourSegs: props.businessHourSegs, bgEventSegs: props.bgEventSegs, fgEventSegs: props.fgEventSegs, dateSelectionSegs: props.dateSelectionSegs, eventSelection: props.eventSelection, eventDrag: props.eventDrag, eventResize: props.eventResize, todayRange: props.todayRange, nowDate: props.nowDate, nowIndicatorSegs: props.nowIndicatorSegs, clientWidth: props.clientWidth, tableMinWidth: props.tableMinWidth, tableColGroupNode: props.tableColGroupNode, slatCoords: state.slatCoords, onColCoords: this.handleColCoords, forPrint: props.forPrint })));\n }\n componentDidMount() {\n this.scrollResponder = this.context.createScrollResponder(this.handleScrollRequest);\n }\n componentDidUpdate(prevProps) {\n this.scrollResponder.update(prevProps.dateProfile !== this.props.dateProfile);\n }\n componentWillUnmount() {\n this.scrollResponder.detach();\n }\n queryHit(positionLeft, positionTop) {\n let { dateEnv, options } = this.context;\n let { colCoords } = this;\n let { dateProfile } = this.props;\n let { slatCoords } = this.state;\n let { snapDuration, snapsPerSlot } = this.processSlotOptions(this.props.slotDuration, options.snapDuration);\n let colIndex = colCoords.leftToIndex(positionLeft);\n let slatIndex = slatCoords.positions.topToIndex(positionTop);\n if (colIndex != null && slatIndex != null) {\n let cell = this.props.cells[colIndex];\n let slatTop = slatCoords.positions.tops[slatIndex];\n let slatHeight = slatCoords.positions.getHeight(slatIndex);\n let partial = (positionTop - slatTop) / slatHeight; // floating point number between 0 and 1\n let localSnapIndex = Math.floor(partial * snapsPerSlot); // the snap # relative to start of slat\n let snapIndex = slatIndex * snapsPerSlot + localSnapIndex;\n let dayDate = this.props.cells[colIndex].date;\n let time = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bq)(dateProfile.slotMinTime, (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bp)(snapDuration, snapIndex));\n let start = dateEnv.add(dayDate, time);\n let end = dateEnv.add(start, snapDuration);\n return {\n dateProfile,\n dateSpan: Object.assign({ range: { start, end }, allDay: false }, cell.extraDateSpan),\n dayEl: colCoords.els[colIndex],\n rect: {\n left: colCoords.lefts[colIndex],\n right: colCoords.rights[colIndex],\n top: slatTop,\n bottom: slatTop + slatHeight,\n },\n layer: 0,\n };\n }\n return null;\n }\n}\nfunction processSlotOptions(slotDuration, snapDurationOverride) {\n let snapDuration = snapDurationOverride || slotDuration;\n let snapsPerSlot = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bu)(slotDuration, snapDuration);\n if (snapsPerSlot === null) {\n snapDuration = slotDuration;\n snapsPerSlot = 1;\n // TODO: say warning?\n }\n return { snapDuration, snapsPerSlot };\n}\n\nclass DayTimeColsSlicer extends _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bW {\n sliceRange(range, dayRanges) {\n let segs = [];\n for (let col = 0; col < dayRanges.length; col += 1) {\n let segRange = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.o)(range, dayRanges[col]);\n if (segRange) {\n segs.push({\n start: segRange.start,\n end: segRange.end,\n isStart: segRange.start.valueOf() === range.start.valueOf(),\n isEnd: segRange.end.valueOf() === range.end.valueOf(),\n col,\n });\n }\n }\n return segs;\n }\n}\n\nclass DayTimeCols extends _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bf {\n constructor() {\n super(...arguments);\n this.buildDayRanges = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.z)(buildDayRanges);\n this.slicer = new DayTimeColsSlicer();\n this.timeColsRef = (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createRef)();\n }\n render() {\n let { props, context } = this;\n let { dateProfile, dayTableModel } = props;\n let isNowIndicator = context.options.nowIndicator;\n let dayRanges = this.buildDayRanges(dayTableModel, dateProfile, context.dateEnv);\n // give it the first row of cells\n // TODO: would move this further down hierarchy, but sliceNowDate needs it\n return ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.ch, { unit: isNowIndicator ? 'minute' : 'day' }, (nowDate, todayRange) => ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(TimeCols, Object.assign({ ref: this.timeColsRef }, this.slicer.sliceProps(props, dateProfile, null, context, dayRanges), { forPrint: props.forPrint, axis: props.axis, dateProfile: dateProfile, slatMetas: props.slatMetas, slotDuration: props.slotDuration, cells: dayTableModel.cells[0], tableColGroupNode: props.tableColGroupNode, tableMinWidth: props.tableMinWidth, clientWidth: props.clientWidth, clientHeight: props.clientHeight, expandRows: props.expandRows, nowDate: nowDate, nowIndicatorSegs: isNowIndicator && this.slicer.sliceNowDate(nowDate, context, dayRanges), todayRange: todayRange, onScrollTopRequest: props.onScrollTopRequest, onSlatCoords: props.onSlatCoords })))));\n }\n}\nfunction buildDayRanges(dayTableModel, dateProfile, dateEnv) {\n let ranges = [];\n for (let date of dayTableModel.headerDates) {\n ranges.push({\n start: dateEnv.add(date, dateProfile.slotMinTime),\n end: dateEnv.add(date, dateProfile.slotMaxTime),\n });\n }\n return ranges;\n}\n\n// potential nice values for the slot-duration and interval-duration\n// from largest to smallest\nconst STOCK_SUB_DURATIONS = [\n { hours: 1 },\n { minutes: 30 },\n { minutes: 15 },\n { seconds: 30 },\n { seconds: 15 },\n];\nfunction buildSlatMetas(slotMinTime, slotMaxTime, explicitLabelInterval, slotDuration, dateEnv) {\n let dayStart = new Date(0);\n let slatTime = slotMinTime;\n let slatIterator = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.e)(0);\n let labelInterval = explicitLabelInterval || computeLabelInterval(slotDuration);\n let metas = [];\n while ((0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bt)(slatTime) < (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bt)(slotMaxTime)) {\n let date = dateEnv.add(dayStart, slatTime);\n let isLabeled = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bu)(slatIterator, labelInterval) !== null;\n metas.push({\n date,\n time: slatTime,\n key: date.toISOString(),\n isoTimeStr: (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bv)(date),\n isLabeled,\n });\n slatTime = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bq)(slatTime, slotDuration);\n slatIterator = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bq)(slatIterator, slotDuration);\n }\n return metas;\n}\n// Computes an automatic value for slotLabelInterval\nfunction computeLabelInterval(slotDuration) {\n let i;\n let labelInterval;\n let slotsPerLabel;\n // find the smallest stock label interval that results in more than one slots-per-label\n for (i = STOCK_SUB_DURATIONS.length - 1; i >= 0; i -= 1) {\n labelInterval = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.e)(STOCK_SUB_DURATIONS[i]);\n slotsPerLabel = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bu)(labelInterval, slotDuration);\n if (slotsPerLabel !== null && slotsPerLabel > 1) {\n return labelInterval;\n }\n }\n return slotDuration; // fall back\n}\n\nclass DayTimeColsView extends TimeColsView {\n constructor() {\n super(...arguments);\n this.buildTimeColsModel = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.z)(buildTimeColsModel);\n this.buildSlatMetas = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.z)(buildSlatMetas);\n }\n render() {\n let { options, dateEnv, dateProfileGenerator } = this.context;\n let { props } = this;\n let { dateProfile } = props;\n let dayTableModel = this.buildTimeColsModel(dateProfile, dateProfileGenerator);\n let splitProps = this.allDaySplitter.splitProps(props);\n let slatMetas = this.buildSlatMetas(dateProfile.slotMinTime, dateProfile.slotMaxTime, options.slotLabelInterval, options.slotDuration, dateEnv);\n let { dayMinWidth } = options;\n let hasAttachedAxis = !dayMinWidth;\n let hasDetachedAxis = dayMinWidth;\n let headerContent = options.dayHeaders && ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bK, { dates: dayTableModel.headerDates, dateProfile: dateProfile, datesRepDistinctDays: true, renderIntro: hasAttachedAxis ? this.renderHeadAxis : null }));\n let allDayContent = (options.allDaySlot !== false) && ((contentArg) => ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_daygrid_internal__WEBPACK_IMPORTED_MODULE_2__.DayTable, Object.assign({}, splitProps.allDay, { dateProfile: dateProfile, dayTableModel: dayTableModel, nextDayThreshold: options.nextDayThreshold, tableMinWidth: contentArg.tableMinWidth, colGroupNode: contentArg.tableColGroupNode, renderRowIntro: hasAttachedAxis ? this.renderTableRowAxis : null, showWeekNumbers: false, expandRows: false, headerAlignElRef: this.headerElRef, clientWidth: contentArg.clientWidth, clientHeight: contentArg.clientHeight, forPrint: props.forPrint }, this.getAllDayMaxEventProps()))));\n let timeGridContent = (contentArg) => ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(DayTimeCols, Object.assign({}, splitProps.timed, { dayTableModel: dayTableModel, dateProfile: dateProfile, axis: hasAttachedAxis, slotDuration: options.slotDuration, slatMetas: slatMetas, forPrint: props.forPrint, tableColGroupNode: contentArg.tableColGroupNode, tableMinWidth: contentArg.tableMinWidth, clientWidth: contentArg.clientWidth, clientHeight: contentArg.clientHeight, onSlatCoords: this.handleSlatCoords, expandRows: contentArg.expandRows, onScrollTopRequest: this.handleScrollTopRequest })));\n return hasDetachedAxis\n ? this.renderHScrollLayout(headerContent, allDayContent, timeGridContent, dayTableModel.colCnt, dayMinWidth, slatMetas, this.state.slatCoords)\n : this.renderSimpleLayout(headerContent, allDayContent, timeGridContent);\n }\n}\nfunction buildTimeColsModel(dateProfile, dateProfileGenerator) {\n let daySeries = new _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bO(dateProfile.renderRange, dateProfileGenerator);\n return new _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bV(daySeries, false);\n}\n\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvQGZ1bGxjYWxlbmRhci90aW1lZ3JpZC9pbnRlcm5hbC5lc20uanMuanMiLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7O0FBQXkwQjtBQUMxdkI7QUFDckI7O0FBRTFELDZCQUE2QiwyREFBUTtBQUNyQztBQUNBO0FBQ0Esc0JBQXNCO0FBQ3RCLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLCtEQUFjO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsa0NBQWtDLDhEQUFlO0FBQ2pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksd0VBQWEsQ0FBQyxtRUFBd0I7QUFDbEQ7QUFDQSxvQkFBb0Isd0VBQWEsU0FBUyxnRUFBZ0U7QUFDMUc7QUFDQSxjQUFjLDRCQUE0QjtBQUMxQztBQUNBO0FBQ0EscURBQXFELDhEQUFlO0FBQ3BFLGdCQUFnQiw4REFBZTtBQUMvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQix3RUFBYSxDQUFDLDBEQUFnQixJQUFJO0FBQ2xEO0FBQ0EsYUFBYSwyUEFBMlAscUJBQXFCLHdFQUFhLFVBQVUsc0VBQXNFO0FBQzFYLFlBQVksd0VBQWEsaUJBQWlCO0FBQzFDO0FBQ0E7QUFDQSxtQkFBbUI7QUFDbkIsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBLDJCQUEyQiwwREFBYTtBQUN4QztBQUNBLHVEQUF1RCx3RUFBYSxTQUFTLG1CQUFtQjtBQUNoRyxZQUFZLHdFQUFhLG1DQUFtQztBQUM1RDtBQUNBOztBQUVBLGdDQUFnQyw4REFBZSxHQUFHLGVBQWU7QUFDakU7QUFDQSwyQkFBMkIsMkRBQWE7QUFDeEM7QUFDQTtBQUNBLG9EQUFvRDtBQUNwRCwyQkFBMkIsb0VBQVM7QUFDcEMseUJBQXlCLG9FQUFT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RTRKIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vVnVleHkvLi9ub2RlX21vZHVsZXMvQGZ1bGxjYWxlbmRhci90aW1lZ3JpZC9pbnRlcm5hbC5lc20uanM/NTMwNyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBTcGxpdHRlciwgaGFzQmdSZW5kZXJpbmcsIGNyZWF0ZUZvcm1hdHRlciwgVmlld0NvbnRleHRUeXBlLCBDb250ZW50Q29udGFpbmVyLCBCYXNlQ29tcG9uZW50LCBEYXRlQ29tcG9uZW50LCBkaWZmRGF5cywgYnVpbGROYXZMaW5rQXR0cnMsIFdlZWtOdW1iZXJDb250YWluZXIsIGdldFN0aWNreUhlYWRlckRhdGVzLCBWaWV3Q29udGFpbmVyLCBTaW1wbGVTY3JvbGxHcmlkLCBnZXRTdGlja3lGb290ZXJTY3JvbGxiYXIsIE5vd1RpbWVyLCBOb3dJbmRpY2F0b3JDb250YWluZXIsIHJlbmRlclNjcm9sbFNoaW0sIHJhbmdlQ29udGFpbnNNYXJrZXIsIHN0YXJ0T2ZEYXksIGFzUm91Z2hNcywgY3JlYXRlRHVyYXRpb24sIFJlZk1hcCwgUG9zaXRpb25DYWNoZSwgTW9yZUxpbmtDb250YWluZXIsIFNlZ0hpZXJhcmNoeSwgZ3JvdXBJbnRlcnNlY3RpbmdFbnRyaWVzLCBiaW5hcnlTZWFyY2gsIGdldEVudHJ5U3BhbkVuZCwgYnVpbGRFbnRyeUtleSwgU3RhbmRhcmRFdmVudCwgbWVtb2l6ZSwgc29ydEV2ZW50U2VncywgRGF5Q2VsbENvbnRhaW5lciwgaGFzQ3VzdG9tRGF5Q2VsbENvbnRlbnQsIGdldFNlZ01ldGEsIGJ1aWxkSXNvU3RyaW5nLCBjb21wdXRlRWFybGllc3RTZWdTdGFydCwgYnVpbGRFdmVudFJhbmdlS2V5LCBCZ0V2ZW50LCByZW5kZXJGaWxsLCBhZGREdXJhdGlvbnMsIG11bHRpcGx5RHVyYXRpb24sIHdob2xlRGl2aWRlRHVyYXRpb25zLCBTbGljZXIsIGludGVyc2VjdFJhbmdlcywgZm9ybWF0SXNvVGltZVN0cmluZywgRGF5SGVhZGVyLCBEYXlTZXJpZXNNb2RlbCwgRGF5VGFibGVNb2RlbCB9IGZyb20gJ0BmdWxsY2FsZW5kYXIvY29yZS9pbnRlcm5hbCc7XG5pbXBvcnQgeyBjcmVhdGVFbGVtZW50LCBjcmVhdGVSZWYsIEZyYWdtZW50IH0gZnJvbSAnQGZ1bGxjYWxlbmRhci9jb3JlL3ByZWFjdCc7XG5pbXBvcnQgeyBEYXlUYWJsZSB9IGZyb20gJ0BmdWxsY2FsZW5kYXIvZGF5Z3JpZC9pbnRlcm5hbCc7XG5cbmNsYXNzIEFsbERheVNwbGl0dGVyIGV4dGVuZHMgU3BsaXR0ZXIge1xuICAgIGdldEtleUluZm8oKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBhbGxEYXk6IHt9LFxuICAgICAgICAgICAgdGltZWQ6IHt9LFxuICAgICAgICB9O1xuICAgIH1cbiAgICBnZXRLZXlzRm9yRGF0ZVNwYW4oZGF0ZVNwYW4pIHtcbiAgICAgICAgaWYgKGRhdGVTcGFuLmFsbERheSkge1xuICAgICAgICAgICAgcmV0dXJuIFsnYWxsRGF5J107XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFsndGltZWQnXTtcbiAgICB9XG4gICAgZ2V0S2V5c0ZvckV2ZW50RGVmKGV2ZW50RGVmKSB7XG4gICAgICAgIGlmICghZXZlbnREZWYuYWxsRGF5KSB7XG4gICAgICAgICAgICByZXR1cm4gWyd0aW1lZCddO1xuICAgICAgICB9XG4gICAgICAgIGlmIChoYXNCZ1JlbmRlcmluZyhldmVudERlZikpIHtcbiAgICAgICAgICAgIHJldHVybiBbJ3RpbWVkJywgJ2FsbERheSddO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBbJ2FsbERheSddO1xuICAgIH1cbn1cblxuY29uc3QgREVGQVVMVF9TTEFUX0xBQkVMX0ZPUk1BVCA9IGNyZWF0ZUZvcm1hdHRlcih7XG4gICAgaG91cjogJ251bWVyaWMnLFxuICAgIG1pbnV0ZTogJzItZGlnaXQnLFxuICAgIG9taXRaZXJvTWludXRlOiB0cnVlLFxuICAgIG1lcmlkaWVtOiAnc2hvcnQnLFxufSk7XG5mdW5jdGlvbiBUaW1lQ29sc0F4aXNDZWxsKHByb3BzKSB7XG4gICAgbGV0IGNsYXNzTmFtZXMgPSBbXG4gICAgICAgICdmYy10aW1lZ3JpZC1zbG90JyxcbiAgICAgICAgJ2ZjLXRpbWVncmlkLXNsb3QtbGFiZWwnLFxuICAgICAgICBwcm9wcy5pc0xhYmVsZWQgPyAnZmMtc2Nyb2xsZ3JpZC1zaHJpbmsnIDogJ2ZjLXRpbWVncmlkLXNsb3QtbWlub3InLFxuICAgIF07XG4gICAgcmV0dXJuIChjcmVhdGVFbGVtZW50KFZpZXdDb250ZXh0VHlwZS5Db25zdW1lciwgbnVsbCwgKGNvbnRleHQpID0+IHtcbiAgICAgICAgaWYgKCFwcm9wcy5pc0xhYmVsZWQpIHtcbiAgICAgICAgICAgIHJldHVybiAoY3JlYXRlRWxlbWVudChcInRkXCIsIHsgY2xhc3NOYW1lOiBjbGFzc05hbWVzLmpvaW4oJyAnKSwgXCJkYXRhLXRpbWVcIjogcHJvcHMuaXNvVGltZVN0ciB9KSk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHsgZGF0ZUVudiwgb3B0aW9ucywgdmlld0FwaSB9ID0gY29udGV4dDtcbiAgICAgICAgbGV0IGxhYmVsRm9ybWF0ID0gLy8gVE9ETzogZnVsbHkgcHJlLXBhcnNlXG4gICAgICAgICBvcHRpb25zLnNsb3RMYWJlbEZvcm1hdCA9PSBudWxsID8gREVGQVVMVF9TTEFUX0xBQkVMX0ZPUk1BVCA6XG4gICAgICAgICAgICBBcnJheS5pc0FycmF5KG9wdGlvbnMuc2xvdExhYmVsRm9ybWF0KSA/IGNyZWF0ZUZvcm1hdHRlcihvcHRpb25zLnNsb3RMYWJlbEZvcm1hdFswXSkgOlxuICAgICAgICAgICAgICAgIGNyZWF0ZUZvcm1hdHRlcihvcHRpb25zLnNsb3RMYWJlbEZvcm1hdCk7XG4gICAgICAgIGxldCByZW5kZXJQcm9wcyA9IHtcbiAgICAgICAgICAgIGxldmVsOiAwLFxuICAgICAgICAgICAgdGltZTogcHJvcHMudGltZSxcbiAgICAgICAgICAgIGRhdGU6IGRhdGVFbnYudG9EYXRlKHByb3BzLmRhdGUpLFxuICAgICAgICAgICAgdmlldzogdmlld0FwaSxcbiAgICAgICAgICAgIHRleHQ6IGRhdGVFbnYuZm9ybWF0KHByb3BzLmRhdGUsIGxhYmVsRm9ybWF0KSxcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIChjcmVhdGVFbGVtZW50KENvbnRlbnRDb250YWluZXIsIHsgZWxUYWc6IFwidGRcIiwgZWxDbGFzc2VzOiBjbGFzc05hbWVzLCBlbEF0dHJzOiB7XG4gICAgICAgICAgICAgICAgJ2RhdGEtdGltZSc6IHByb3BzLmlzb1RpbWVTdHIsXG4gICAgICAgICAgICB9LCByZW5kZXJQcm9wczogcmVuZGVyUHJvcHMsIGdlbmVyYXRvck5hbWU6IFwic2xvdExhYmVsQ29udGVudFwiLCBnZW5lcmF0b3I6IG9wdGlvbnMuc2xvdExhYmVsQ29udGVudCB8fCByZW5kZXJJbm5lckNvbnRlbnQsIGNsYXNzTmFtZUdlbmVyYXRvcjogb3B0aW9ucy5zbG90TGFiZWxDbGFzc05hbWVzLCBkaWRNb3VudDogb3B0aW9ucy5zbG90TGFiZWxEaWRNb3VudCwgd2lsbFVubW91bnQ6IG9wdGlvbnMuc2xvdExhYmVsV2lsbFVubW91bnQgfSwgKElubmVyQ29udGVudCkgPT4gKGNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwgeyBjbGFzc05hbWU6IFwiZmMtdGltZWdyaWQtc2xvdC1sYWJlbC1mcmFtZSBmYy1zY3JvbGxncmlkLXNocmluay1mcmFtZVwiIH0sXG4gICAgICAgICAgICBjcmVhdGVFbGVtZW50KElubmVyQ29udGVudCwgeyBlbFRhZzogXCJkaXZcIiwgZWxDbGFzc2VzOiBbXG4gICAgICAgICAgICAgICAgICAgICdmYy10aW1lZ3JpZC1zbG90LWxhYmVsLWN1c2hpb24nLFxuICAgICAgICAgICAgICAgICAgICAnZmMtc2Nyb2xsZ3JpZC1zaHJpbmstY3VzaGlvbicsXG4gICAgICAgICAgICAgICAgXSB9KSkpKSk7XG4gICAgfSkpO1xufVxuZnVuY3Rpb24gcmVuZGVySW5uZXJDb250ZW50KHByb3BzKSB7XG4gICAgcmV0dXJuIHByb3BzLnRleHQ7XG59XG5cbmNsYXNzIFRpbWVCb2R5QXhpcyBleHRlbmRzIEJhc2VDb21wb25lbnQge1xuICAgIHJlbmRlcigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucHJvcHMuc2xhdE1ldGFzLm1hcCgoc2xhdE1ldGEpID0+IChjcmVhdGVFbGVtZW50KFwidHJcIiwgeyBrZXk6IHNsYXRNZXRhLmtleSB9LFxuICAgICAgICAgICAgY3JlYXRlRWxlbWVudChUaW1lQ29sc0F4aXNDZWxsLCBPYmplY3QuYXNzaWduKHt9LCBzbGF0TWV0YSkpKSkpO1xuICAgIH1cbn1cblxuY29uc3QgREVGQVVMVF9XRUVLX05VTV9GT1JNQVQgPSBjcmVhdGVGb3JtYXR0ZXIoeyB3ZWVrOiAnc2hvcnQnIH0pO1xuY29uc3QgQVVUT19BTExfREFZX01BWF9FVkVOVF9ST1dTID0gNTtcbmNsYXNzIFRpbWVDb2xzVmlldyBleHRlbmRzIERhdGVDb21wb25lbnQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLmFsbERheVNwbGl0dGVyID0gbmV3IEFsbERheVNwbGl0dGVyKCk7IC8vIGZvciB1c2UgYnkgc3ViY2xhc3Nlc1xuICAgICAgICB0aGlzLmhlYWRlckVsUmVmID0gY3JlYXRlUmVmKCk7XG4gICAgICAgIHRoaXMucm9vdEVsUmVmID0gY3JlYXRlUmVmKCk7XG4gICAgICAgIHRoaXMuc2Nyb2xsZXJFbFJlZiA9IGNyZWF0ZVJlZigpO1xuICAgICAgICB0aGlzLnN0YXRlID0ge1xuICAgICAgICAgICAgc2xhdENvb3JkczogbnVsbCxcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5oYW5kbGVTY3JvbGxUb3BSZXF1ZXN0ID0gKHNjcm9sbFRvcCkgPT4ge1xuICAgICAgICAgICAgbGV0IHNjcm9sbGVyRWwgPSB0aGlzLnNjcm9sbGVyRWxSZWYuY3VycmVudDtcbiAgICAgICAgICAgIGlmIChzY3JvbGxlckVsKSB7IC8vIFRPRE86IG5vdCBzdXJlIGhvdyB0aGlzIGNvdWxkIGV2ZXIgYmUgbnVsbC4gd2VpcmRuZXNzIHdpdGggdGhlIHJlZHVjZXJcbiAgICAgICAgICAgICAgICBzY3JvbGxlckVsLnNjcm9sbFRvcCA9IHNjcm9sbFRvcDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgLyogSGVhZGVyIFJlbmRlciBNZXRob2RzXG4gICAgICAgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG4gICAgICAgIHRoaXMucmVuZGVySGVhZEF4aXMgPSAocm93S2V5LCBmcmFtZUhlaWdodCA9ICcnKSA9PiB7XG4gICAgICAgICAgICBsZXQgeyBvcHRpb25zIH0gPSB0aGlzLmNvbnRleHQ7XG4gICAgICAgICAgICBsZXQgeyBkYXRlUHJvZmlsZSB9ID0gdGhpcy5wcm9wcztcbiAgICAgICAgICAgIGxldCByYW5nZSA9IGRhdGVQcm9maWxlLnJlbmRlclJhbmdlO1xuICAgICAgICAgICAgbGV0IGRheUNudCA9IGRpZmZEYXlzKHJhbmdlLnN0YXJ0LCByYW5nZS5lbmQpO1xuICAgICAgICAgICAgLy8gb25seSBkbyBpbiBkYXkgdmlld3MgKHRvIGF2b2lkIGRvaW5nIGluIHdlZWsgdmlld3MgdGhhdCBkb250IG5lZWQgaXQpXG4gICAgICAgICAgICBsZXQgbmF2TGlua0F0dHJzID0gKGRheUNudCA9PT0gMSlcbiAgICAgICAgICAgICAgICA/IGJ1aWxkTmF2TGlua0F0dHJzKHRoaXMuY29udGV4dCwgcmFuZ2Uuc3RhcnQsICd3ZWVrJylcbiAgICAgICAgICAgICAgICA6IHt9O1xuICAgICAgICAgICAgaWYgKG9wdGlvbnMud2Vla051bWJlcnMgJiYgcm93S2V5ID09PSAnZGF5Jykge1xuICAgICAgICAgICAgICAgIHJldHVybiAoY3JlYXRlRWxlbWVudChXZWVrTnVtYmVyQ29udGFpbmVyLCB7IGVsVGFnOiBcInRoXCIsIGVsQ2xhc3NlczogW1xuICAgICAgICAgICAgICAgICAgICAgICAgJ2ZjLXRpbWVncmlkLWF4aXMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgJ2ZjLXNjcm9sbGdyaWQtc2hyaW5rJyxcbiAgICAgICAgICAgICAgICAgICAgXSwgZWxBdHRyczoge1xuICAgICAgICAgICAgICAgICAgICAgICAgJ2FyaWEtaGlkZGVuJzogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgfSwgZGF0ZTogcmFuZ2Uuc3RhcnQsIGRlZmF1bHRGb3JtYXQ6IERFRkFVTFRfV0VFS19OVU1fRk9STUFUIH0sIChJbm5lckNvbnRlbnQpID0+IChjcmVhdGVFbGVtZW50KFwiZGl2XCIsIHsgY2xhc3NOYW1lOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICAnZmMtdGltZWdyaWQtYXhpcy1mcmFtZScsXG4gICAgICAgICAgICAgICAgICAgICAgICAnZmMtc2Nyb2xsZ3JpZC1zaHJpbmstZnJhbWUnLFxuICAgICAgICAgICAgICAgICAgICAgICAgJ2ZjLXRpbWVncmlkLWF4aXMtZnJhbWUtbGlxdWlkJyxcbiAgICAgICAgICAgICAgICAgICAgXS5qb2luKCcgJyksIHN0eWxlOiB7IGhlaWdodDogZnJhbWVIZWlnaHQgfSB9LFxuICAgICAgICAgICAgICAgICAgICBjcmVhdGVFbGVtZW50KElubmVyQ29udGVudCwgeyBlbFRhZzogXCJhXCIsIGVsQ2xhc3NlczogW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdmYy10aW1lZ3JpZC1heGlzLWN1c2hpb24nLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdmYy1zY3JvbGxncmlkLXNocmluay1jdXNoaW9uJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZmMtc2Nyb2xsZ3JpZC1zeW5jLWlubmVyJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIF0sIGVsQXR0cnM6IG5hdkxpbmtBdHRycyB9KSkpKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gKGNyZWF0ZUVsZW1lbnQoXCJ0aFwiLCB7IFwiYXJpYS1oaWRkZW5cIjogdHJ1ZSwgY2xhc3NOYW1lOiBcImZjLXRpbWVncmlkLWF4aXNcIiB9LFxuICAgICAgICAgICAgICAgIGNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwgeyBjbGFzc05hbWU6IFwiZmMtdGltZWdyaWQtYXhpcy1mcmFtZVwiLCBzdHlsZTogeyBoZWlnaHQ6IGZyYW1lSGVpZ2h0IH0gfSkpKTtcbiAgICAgICAgfTtcbiAgICAgICAgLyogVGFibGUgQ29tcG9uZW50IFJlbmRlciBNZXRob2RzXG4gICAgICAgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG4gICAgICAgIC8vIG9ubHkgYSBvbmUtd2F5IGhlaWdodCBzeW5jLiB3ZSBkb24ndCBzZW5kIHRoZSBheGlzIGlubmVyLWNvbnRlbnQgaGVpZ2h0IHRvIHRoZSBEYXlHcmlkLFxuICAgICAgICAvLyBidXQgRGF5R3JpZCBzdGlsbCBuZWVkcyB0byBoYXZlIGNsYXNzTmFtZXMgb24gaW5uZXIgZWxlbWVudHMgaW4gb3JkZXIgdG8gbWVhc3VyZS5cbiAgICAgICAgdGhpcy5yZW5kZXJUYWJsZVJvd0F4aXMgPSAocm93SGVpZ2h0KSA9PiB7XG4gICAgICAgICAgICBsZXQgeyBvcHRpb25zLCB2aWV3QXBpIH0gPSB0aGlzLmNvbnRleHQ7XG4gICAgICAgICAgICBsZXQgcmVuZGVyUHJvcHMgPSB7XG4gICAgICAgICAgICAgICAgdGV4dDogb3B0aW9ucy5hbGxEYXlUZXh0LFxuICAgICAgICAgICAgICAgIHZpZXc6IHZpZXdBcGksXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIC8vIFRPRE86IG1ha2UgcmV1c2FibGUgaG9vay4gdXNlZCBpbiBsaXN0IHZpZXcgdG9vXG4gICAgICAgICAgICBjcmVhdGVFbGVtZW50KENvbnRlbnRDb250YWluZXIsIHsgZWxUYWc6IFwidGRcIiwgZWxDbGFzc2VzOiBbXG4gICAgICAgICAgICAgICAgICAgICdmYy10aW1lZ3JpZC1heGlzJyxcbiAgICAgICAgICAgICAgICAgICAgJ2ZjLXNjcm9sbGdyaWQtc2hyaW5rJyxcbiAgICAgICAgICAgICAgICBdLCBlbEF0dHJzOiB7XG4gICAgICAgICAgICAgICAgICAgICdhcmlhLWhpZGRlbic6IHRydWUsXG4gICAgICAgICAgICAgICAgfSwgcmVuZGVyUHJvcHM6IHJlbmRlclByb3BzLCBnZW5lcmF0b3JOYW1lOiBcImFsbERheUNvbnRlbnRcIiwgZ2VuZXJhdG9yOiBvcHRpb25zLmFsbERheUNvbnRlbnQgfHwgcmVuZGVyQWxsRGF5SW5uZXIsIGNsYXNzTmFtZUdlbmVyYXRvcjogb3B0aW9ucy5hbGxEYXlDbGFzc05hbWVzLCBkaWRNb3VudDogb3B0aW9ucy5hbGxEYXlEaWRNb3VudCwgd2lsbFVubW91bnQ6IG9wdGlvbnMuYWxsRGF5V2lsbFVubW91bnQgfSwgKElubmVyQ29udGVudCkgPT4gKGNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwgeyBjbGFzc05hbWU6IFtcbiAgICAgICAgICAgICAgICAgICAgJ2ZjLXRpbWVncmlkLWF4aXMtZnJhbWUnLFxuICAgICAgICAgICAgICAgICAgICAnZmMtc2Nyb2xsZ3JpZC1zaHJpbmstZnJhbWUnLFxuICAgICAgICAgICAgICAgICAgICByb3dIZWlnaHQgPT0gbnVsbCA/ICcgZmMtdGltZWdyaWQtYXhpcy1mcmFtZS1saXF1aWQnIDogJycsXG4gICAgICAgICAgICAgICAgXS5qb2luKCcgJyksIHN0eWxlOiB7IGhlaWdodDogcm93SGVpZ2h0IH0gfSxcbiAgICAgICAgICAgICAgICBjcmVhdGVFbGVtZW50KElubmVyQ29udGVudCwgeyBlbFRhZzogXCJzcGFuXCIsIGVsQ2xhc3NlczogW1xuICAgICAgICAgICAgICAgICAgICAgICAgJ2ZjLXRpbWVncmlkLWF4aXMtY3VzaGlvbicsXG4gICAgICAgICAgICAgICAgICAgICAgICAnZmMtc2Nyb2xsZ3JpZC1zaHJpbmstY3VzaGlvbicsXG4gICAgICAgICAgICAgICAgICAgICAgICAnZmMtc2Nyb2xsZ3JpZC1zeW5jLWlubmVyJyxcbiAgICAgICAgICAgICAgICAgICAgXSB9KSkpKSk7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuaGFuZGxlU2xhdENvb3JkcyA9IChzbGF0Q29vcmRzKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgc2xhdENvb3JkcyB9KTtcbiAgICAgICAgfTtcbiAgICB9XG4gICAgLy8gcmVuZGVyaW5nXG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIHJlbmRlclNpbXBsZUxheW91dChoZWFkZXJSb3dDb250ZW50LCBhbGxEYXlDb250ZW50LCB0aW1lQ29udGVudCkge1xuICAgICAgICBsZXQgeyBjb250ZXh0LCBwcm9wcyB9ID0gdGhpcztcbiAgICAgICAgbGV0IHNlY3Rpb25zID0gW107XG4gICAgICAgIGxldCBzdGlja3lIZWFkZXJEYXRlcyA9IGdldFN0aWNreUhlYWRlckRhdGVzKGNvbnRleHQub3B0aW9ucyk7XG4gICAgICAgIGlmIChoZWFkZXJSb3dDb250ZW50KSB7XG4gICAgICAgICAgICBzZWN0aW9ucy5wdXNoKHtcbiAgICAgICAgICAgICAgICB0eXBlOiAnaGVhZGVyJyxcbiAgICAgICAgICAgICAgICBrZXk6ICdoZWFkZXInLFxuICAgICAgICAgICAgICAgIGlzU3RpY2t5OiBzdGlja3lIZWFkZXJEYXRlcyxcbiAgICAgICAgICAgICAgICBjaHVuazoge1xuICAgICAgICAgICAgICAgICAgICBlbFJlZjogdGhpcy5oZWFkZXJFbFJlZixcbiAgICAgICAgICAgICAgICAgICAgdGFibGVDbGFzc05hbWU6ICdmYy1jb2wtaGVhZGVyJyxcbiAgICAgICAgICAgICAgICAgICAgcm93Q29udGVudDogaGVhZGVyUm93Q29udGVudCxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGFsbERheUNvbnRlbnQpIHtcbiAgICAgICAgICAgIHNlY3Rpb25zLnB1c2goe1xuICAgICAgICAgICAgICAgIHR5cGU6ICdib2R5JyxcbiAgICAgICAgICAgICAgICBrZXk6ICdhbGwtZGF5JyxcbiAgICAgICAgICAgICAgICBjaHVuazogeyBjb250ZW50OiBhbGxEYXlDb250ZW50IH0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHNlY3Rpb25zLnB1c2goe1xuICAgICAgICAgICAgICAgIHR5cGU6ICdib2R5JyxcbiAgICAgICAgICAgICAgICBrZXk6ICdhbGwtZGF5LWRpdmlkZXInLFxuICAgICAgICAgICAgICAgIG91dGVyQ29udGVudDogKCAvLyBUT0RPOiByZW5hbWUgdG8gY2VsbENvbnRlbnQgc28gZG9uJ3QgbmVlZCB0byBkZWZpbmUgPHRyPj9cbiAgICAgICAgICAgICAgICBjcmVhdGVFbGVtZW50KFwidHJcIiwgeyByb2xlOiBcInByZXNlbnRhdGlvblwiLCBjbGFzc05hbWU6IFwiZmMtc2Nyb2xsZ3JpZC1zZWN0aW9uXCIgfSxcbiAgICAgICAgICAgICAgICAgICAgY3JlYXRlRWxlbWVudChcInRkXCIsIHsgY2xhc3NOYW1lOiAnZmMtdGltZWdyaWQtZGl2aWRlciAnICsgY29udGV4dC50aGVtZS5nZXRDbGFzcygndGFibGVDZWxsU2hhZGVkJykgfSkpKSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHNlY3Rpb25zLnB1c2goe1xuICAgICAgICAgICAgdHlwZTogJ2JvZHknLFxuICAgICAgICAgICAga2V5OiAnYm9keScsXG4gICAgICAgICAgICBsaXF1aWQ6IHRydWUsXG4gICAgICAgICAgICBleHBhbmRSb3dzOiBCb29sZWFuKGNvbnRleHQub3B0aW9ucy5leHBhbmRSb3dzKSxcbiAgICAgICAgICAgIGNodW5rOiB7XG4gICAgICAgICAgICAgICAgc2Nyb2xsZXJFbFJlZjogdGhpcy5zY3JvbGxlckVsUmVmLFxuICAgICAgICAgICAgICAgIGNvbnRlbnQ6IHRpbWVDb250ZW50LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiAoY3JlYXRlRWxlbWVudChWaWV3Q29udGFpbmVyLCB7IGVsUmVmOiB0aGlzLnJvb3RFbFJlZiwgZWxDbGFzc2VzOiBbJ2ZjLXRpbWVncmlkJ10sIHZpZXdTcGVjOiBjb250ZXh0LnZpZXdTcGVjIH0sXG4gICAgICAgICAgICBjcmVhdGVFbGVtZW50KFNpbXBsZVNjcm9sbEdyaWQsIHsgbGlxdWlkOiAhcHJvcHMuaXNIZWlnaHRBdXRvICYmICFwcm9wcy5mb3JQcmludCwgY29sbGFwc2libGVXaWR0aDogcHJvcHMuZm9yUHJpbnQsIGNvbHM6IFt7IHdpZHRoOiAnc2hyaW5rJyB9XSwgc2VjdGlvbnM6IHNlY3Rpb25zIH0pKSk7XG4gICAgfVxuICAgIHJlbmRlckhTY3JvbGxMYXlvdXQoaGVhZGVyUm93Q29udGVudCwgYWxsRGF5Q29udGVudCwgdGltZUNvbnRlbnQsIGNvbENudCwgZGF5TWluV2lkdGgsIHNsYXRNZXRhcywgc2xhdENvb3Jkcykge1xuICAgICAgICBsZXQgU2Nyb2xsR3JpZCA9IHRoaXMuY29udGV4dC5wbHVnaW5Ib29rcy5zY3JvbGxHcmlkSW1wbDtcbiAgICAgICAgaWYgKCFTY3JvbGxHcmlkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIFNjcm9sbEdyaWQgaW1wbGVtZW50YXRpb24nKTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgeyBjb250ZXh0LCBwcm9wcyB9ID0gdGhpcztcbiAgICAgICAgbGV0IHN0aWNreUhlYWRlckRhdGVzID0gIXByb3BzLmZvclByaW50ICYmIGdldFN0aWNreUhlYWRlckRhdGVzKGNvbnRleHQub3B0aW9ucyk7XG4gICAgICAgIGxldCBzdGlja3lGb290ZXJTY3JvbGxiYXIgPSAhcHJvcHMuZm9yUHJpbnQgJiYgZ2V0U3RpY2t5Rm9vdGVyU2Nyb2xsYmFyKGNvbnRleHQub3B0aW9ucyk7XG4gICAgICAgIGxldCBzZWN0aW9ucyA9IFtdO1xuICAgICAgICBpZiAoaGVhZGVyUm93Q29udGVudCkge1xuICAgICAgICAgICAgc2VjdGlvbnMucHVzaCh7XG4gICAgICAgICAgICAgICAgdHlwZTogJ2hlYWRlcicsXG4gICAgICAgICAgICAgICAga2V5OiAnaGVhZGVyJyxcbiAgICAgICAgICAgICAgICBpc1N0aWNreTogc3RpY2t5SGVhZGVyRGF0ZXMsXG4gICAgICAgICAgICAgICAgc3luY1Jvd0hlaWdodHM6IHRydWUsXG4gICAgICAgICAgICAgICAgY2h1bmtzOiBbXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGtleTogJ2F4aXMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgcm93Q29udGVudDogKGFyZykgPT4gKGNyZWF0ZUVsZW1lbnQoXCJ0clwiLCB7IHJvbGU6IFwicHJlc2VudGF0aW9uXCIgfSwgdGhpcy5yZW5kZXJIZWFkQXhpcygnZGF5JywgYXJnLnJvd1N5bmNIZWlnaHRzWzBdKSkpLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBrZXk6ICdjb2xzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsUmVmOiB0aGlzLmhlYWRlckVsUmVmLFxuICAgICAgICAgICAgICAgICAgICAgICAgdGFibGVDbGFzc05hbWU6ICdmYy1jb2wtaGVhZGVyJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJvd0NvbnRlbnQ6IGhlYWRlclJvd0NvbnRlbnQsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChhbGxEYXlDb250ZW50KSB7XG4gICAgICAgICAgICBzZWN0aW9ucy5wdXNoKHtcbiAgICAgICAgICAgICAgICB0eXBlOiAnYm9keScsXG4gICAgICAgICAgICAgICAga2V5OiAnYWxsLWRheScsXG4gICAgICAgICAgICAgICAgc3luY1Jvd0hlaWdodHM6IHRydWUsXG4gICAgICAgICAgICAgICAgY2h1bmtzOiBbXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGtleTogJ2F4aXMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgcm93Q29udGVudDogKGNvbnRlbnRBcmcpID0+IChjcmVhdGVFbGVtZW50KFwidHJcIiwgeyByb2xlOiBcInByZXNlbnRhdGlvblwiIH0sIHRoaXMucmVuZGVyVGFibGVSb3dBeGlzKGNvbnRlbnRBcmcucm93U3luY0hlaWdodHNbMF0pKSksXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGtleTogJ2NvbHMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudDogYWxsRGF5Q29udGVudCxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBzZWN0aW9ucy5wdXNoKHtcbiAgICAgICAgICAgICAgICBrZXk6ICdhbGwtZGF5LWRpdmlkZXInLFxuICAgICAgICAgICAgICAgIHR5cGU6ICdib2R5JyxcbiAgICAgICAgICAgICAgICBvdXRlckNvbnRlbnQ6ICggLy8gVE9ETzogcmVuYW1lIHRvIGNlbGxDb250ZW50IHNvIGRvbid0IG5lZWQgdG8gZGVmaW5lIDx0cj4/XG4gICAgICAgICAgICAgICAgY3JlYXRlRWxlbWVudChcInRyXCIsIHsgcm9sZTogXCJwcmVzZW50YXRpb25cIiwgY2xhc3NOYW1lOiBcImZjLXNjcm9sbGdyaWQtc2VjdGlvblwiIH0sXG4gICAgICAgICAgICAgICAgICAgIGNyZWF0ZUVsZW1lbnQoXCJ0ZFwiLCB7IGNvbFNwYW46IDIsIGNsYXNzTmFtZTogJ2ZjLXRpbWVncmlkLWRpdmlkZXIgJyArIGNvbnRleHQudGhlbWUuZ2V0Q2xhc3MoJ3RhYmxlQ2VsbFNoYWRlZCcpIH0pKSksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgaXNOb3dJbmRpY2F0b3IgPSBjb250ZXh0Lm9wdGlvbnMubm93SW5kaWNhdG9yO1xuICAgICAgICBzZWN0aW9ucy5wdXNoKHtcbiAgICAgICAgICAgIHR5cGU6ICdib2R5JyxcbiAgICAgICAgICAgIGtleTogJ2JvZHknLFxuICAgICAgICAgICAgbGlxdWlkOiB0cnVlLFxuICAgICAgICAgICAgZXhwYW5kUm93czogQm9vbGVhbihjb250ZXh0Lm9wdGlvbnMuZXhwYW5kUm93cyksXG4gICAgICAgICAgICBjaHVua3M6IFtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGtleTogJ2F4aXMnLFxuICAgICAgICAgICAgICAgICAgICBjb250ZW50OiAoYXJnKSA9PiAoXG4gICAgICAgICAgICAgICAgICAgIC8vIFRPRE86IG1ha2UgdGhpcyBub3ctaW5kaWNhdG9yIGFycm93IG1vcmUgRFJZIHdpdGggVGltZUNvbHNDb250ZW50XG4gICAgICAgICAgICAgICAgICAgIGNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwgeyBjbGFzc05hbWU6IFwiZmMtdGltZWdyaWQtYXhpcy1jaHVua1wiIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICBjcmVhdGVFbGVtZW50KFwidGFibGVcIiwgeyBcImFyaWEtaGlkZGVuXCI6IHRydWUsIHN0eWxlOiB7IGhlaWdodDogYXJnLmV4cGFuZFJvd3MgPyBhcmcuY2xpZW50SGVpZ2h0IDogJycgfSB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyZy50YWJsZUNvbEdyb3VwTm9kZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjcmVhdGVFbGVtZW50KFwidGJvZHlcIiwgbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlRWxlbWVudChUaW1lQm9keUF4aXMsIHsgc2xhdE1ldGFzOiBzbGF0TWV0YXMgfSkpKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwgeyBjbGFzc05hbWU6IFwiZmMtdGltZWdyaWQtbm93LWluZGljYXRvci1jb250YWluZXJcIiB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNyZWF0ZUVsZW1lbnQoTm93VGltZXIsIHsgdW5pdDogaXNOb3dJbmRpY2F0b3IgPyAnbWludXRlJyA6ICdkYXknIC8qIGhhY2t5ICovIH0sIChub3dEYXRlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBub3dJbmRpY2F0b3JUb3AgPSBpc05vd0luZGljYXRvciAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2xhdENvb3JkcyAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2xhdENvb3Jkcy5zYWZlQ29tcHV0ZVRvcChub3dEYXRlKTsgLy8gbWlnaHQgcmV0dXJuIHZvaWRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBub3dJbmRpY2F0b3JUb3AgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKGNyZWF0ZUVsZW1lbnQoTm93SW5kaWNhdG9yQ29udGFpbmVyLCB7IGVsQ2xhc3NlczogWydmYy10aW1lZ3JpZC1ub3ctaW5kaWNhdG9yLWFycm93J10sIGVsU3R5bGU6IHsgdG9wOiBub3dJbmRpY2F0b3JUb3AgfSwgaXNBeGlzOiB0cnVlLCBkYXRlOiBub3dEYXRlIH0pKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KSkpKSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAga2V5OiAnY29scycsXG4gICAgICAgICAgICAgICAgICAgIHNjcm9sbGVyRWxSZWY6IHRoaXMuc2Nyb2xsZXJFbFJlZixcbiAgICAgICAgICAgICAgICAgICAgY29udGVudDogdGltZUNvbnRlbnQsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoc3RpY2t5Rm9vdGVyU2Nyb2xsYmFyKSB7XG4gICAgICAgICAgICBzZWN0aW9ucy5wdXNoKHtcbiAgICAgICAgICAgICAgICBrZXk6ICdmb290ZXInLFxuICAgICAgICAgICAgICAgIHR5cGU6ICdmb290ZXInLFxuICAgICAgICAgICAgICAgIGlzU3RpY2t5OiB0cnVlLFxuICAgICAgICAgICAgICAgIGNodW5rczogW1xuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBrZXk6ICdheGlzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQ6IHJlbmRlclNjcm9sbFNoaW0sXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGtleTogJ2NvbHMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudDogcmVuZGVyU2Nyb2xsU2hpbSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIChjcmVhdGVFbGVtZW50KFZpZXdDb250YWluZXIsIHsgZWxSZWY6IHRoaXMucm9vdEVsUmVmLCBlbENsYXNzZXM6IFsnZmMtdGltZWdyaWQnXSwgdmlld1NwZWM6IGNvbnRleHQudmlld1NwZWMgfSxcbiAgICAgICAgICAgIGNyZWF0ZUVsZW1lbnQoU2Nyb2xsR3JpZCwgeyBsaXF1aWQ6ICFwcm9wcy5pc0hlaWdodEF1dG8gJiYgIXByb3BzLmZvclByaW50LCBjb2xsYXBzaWJsZVdpZHRoOiBmYWxzZSwgY29sR3JvdXBzOiBbXG4gICAgICAgICAgICAgICAgICAgIHsgd2lkdGg6ICdzaHJpbmsnLCBjb2xzOiBbeyB3aWR0aDogJ3NocmluaycgfV0gfSxcbiAgICAgICAgICAgICAgICAgICAgeyBjb2xzOiBbeyBzcGFuOiBjb2xDbnQsIG1pbldpZHRoOiBkYXlNaW5XaWR0aCB9XSB9LFxuICAgICAgICAgICAgICAgIF0sIHNlY3Rpb25zOiBzZWN0aW9ucyB9KSkpO1xuICAgIH1cbiAgICAvKiBEaW1lbnNpb25zXG4gICAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cbiAgICBnZXRBbGxEYXlNYXhFdmVudFByb3BzKCkge1xuICAgICAgICBsZXQgeyBkYXlNYXhFdmVudHMsIGRheU1heEV2ZW50Um93cyB9ID0gdGhpcy5jb250ZXh0Lm9wdGlvbnM7XG4gICAgICAgIGlmIChkYXlNYXhFdmVudHMgPT09IHRydWUgfHwgZGF5TWF4RXZlbnRSb3dzID09PSB0cnVlKSB7IC8vIGlzIGF1dG8/XG4gICAgICAgICAgICBkYXlNYXhFdmVudHMgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICBkYXlNYXhFdmVudFJvd3MgPSBBVVRPX0FMTF9EQVlfTUFYX0VWRU5UX1JPV1M7IC8vIG1ha2Ugc3VyZSBcImF1dG9cIiBnb2VzIHRvIGEgcmVhbCBudW1iZXJcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geyBkYXlNYXhFdmVudHMsIGRheU1heEV2ZW50Um93cyB9O1xuICAgIH1cbn1cbmZ1bmN0aW9uIHJlbmRlckFsbERheUlubmVyKHJlbmRlclByb3BzKSB7XG4gICAgcmV0dXJuIHJlbmRlclByb3BzLnRleHQ7XG59XG5cbmNsYXNzIFRpbWVDb2xzU2xhdHNDb29yZHMge1xuICAgIGNvbnN0cnVjdG9yKHBvc2l0aW9ucywgZGF0ZVByb2ZpbGUsIHNsb3REdXJhdGlvbikge1xuICAgICAgICB0aGlzLnBvc2l0aW9ucyA9IHBvc2l0aW9ucztcbiAgICAgICAgdGhpcy5kYXRlUHJvZmlsZSA9IGRhdGVQcm9maWxlO1xuICAgICAgICB0aGlzLnNsb3REdXJhdGlvbiA9IHNsb3REdXJhdGlvbjtcbiAgICB9XG4gICAgc2FmZUNvbXB1dGVUb3AoZGF0ZSkge1xuICAgICAgICBsZXQgeyBkYXRlUHJvZmlsZSB9ID0gdGhpcztcbiAgICAgICAgaWYgKHJhbmdlQ29udGFpbnNNYXJrZXIoZGF0ZVByb2ZpbGUuY3VycmVudFJhbmdlLCBkYXRlKSkge1xuICAgICAgICAgICAgbGV0IHN0YXJ0T2ZEYXlEYXRlID0gc3RhcnRPZkRheShkYXRlKTtcbiAgICAgICAgICAgIGxldCB0aW1lTXMgPSBkYXRlLnZhbHVlT2YoKSAtIHN0YXJ0T2ZEYXlEYXRlLnZhbHVlT2YoKTtcbiAgICAgICAgICAgIGlmICh0aW1lTXMgPj0gYXNSb3VnaE1zKGRhdGVQcm9maWxlLnNsb3RNaW5UaW1lKSAmJlxuICAgICAgICAgICAgICAgIHRpbWVNcyA8IGFzUm91Z2hNcyhkYXRlUHJvZmlsZS5zbG90TWF4VGltZSkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5jb21wdXRlVGltZVRvcChjcmVhdGVEdXJhdGlvbih0aW1lTXMpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgLy8gQ29tcHV0ZXMgdGhlIHRvcCBjb29yZGluYXRlLCByZWxhdGl2ZSB0byB0aGUgYm91bmRzIG9mIHRoZSBncmlkLCBvZiB0aGUgZ2l2ZW4gZGF0ZS5cbiAgICAvLyBBIGBzdGFydE9mRGF5RGF0ZWAgbXVzdCBiZSBnaXZlbiBmb3IgYXZvaWRpbmcgYW1iaWd1aXR5IG92ZXIgaG93IHRvIHRyZWF0IG1pZG5pZ2h0LlxuICAgIGNvbXB1dGVEYXRlVG9wKHdoZW4sIHN0YXJ0T2ZEYXlEYXRlKSB7XG4gICAgICAgIGlmICghc3RhcnRPZkRheURhdGUpIHtcbiAgICAgICAgICAgIHN0YXJ0T2ZEYXlEYXRlID0gc3RhcnRPZkRheSh3aGVuKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5jb21wdXRlVGltZVRvcChjcmVhdGVEdXJhdGlvbih3aGVuLnZhbHVlT2YoKSAtIHN0YXJ0T2ZEYXlEYXRlLnZhbHVlT2YoKSkpO1xuICAgIH1cbiAgICAvLyBDb21wdXRlcyB0aGUgdG9wIGNvb3JkaW5hdGUsIHJlbGF0aXZlIHRvIHRoZSBib3VuZHMgb2YgdGhlIGdyaWQsIG9mIHRoZSBnaXZlbiB0aW1lIChhIER1cmF0aW9uKS5cbiAgICAvLyBUaGlzIGlzIGEgbWFrZXNoaWZ5IHdheSB0byBjb21wdXRlIHRoZSB0aW1lLXRvcC4gQXNzdW1lcyBhbGwgc2xhdE1ldGFzIGRhdGVzIGFyZSB1bmlmb3JtLlxuICAgIC8vIEV2ZW50dWFsbHkgYWxsb3cgY29tcHV0YXRpb24gd2l0aCBhcmJpcmFyeSBzbGF0IGRhdGVzLlxuICAgIGNvbXB1dGVUaW1lVG9wKGR1cmF0aW9uKSB7XG4gICAgICAgIGxldCB7IHBvc2l0aW9ucywgZGF0ZVByb2ZpbGUgfSA9IHRoaXM7XG4gICAgICAgIGxldCBsZW4gPSBwb3NpdGlvbnMuZWxzLmxlbmd0aDtcbiAgICAgICAgLy8gZmxvYXRpbmctcG9pbnQgdmFsdWUgb2YgIyBvZiBzbG90cyBjb3ZlcmVkXG4gICAgICAgIGxldCBzbGF0Q292ZXJhZ2UgPSAoZHVyYXRpb24ubWlsbGlzZWNvbmRzIC0gYXNSb3VnaE1zKGRhdGVQcm9maWxlLnNsb3RNaW5UaW1lKSkgLyBhc1JvdWdoTXModGhpcy5zbG90RHVyYXRpb24pO1xuICAgICAgICBsZXQgc2xhdEluZGV4O1xuICAgICAgICBsZXQgc2xhdFJlbWFpbmRlcjtcbiAgICAgICAgLy8gY29tcHV0ZSBhIGZsb2F0aW5nLXBvaW50IG51bWJlciBmb3IgaG93IG1hbnkgc2xhdHMgc2hvdWxkIGJlIHByb2dyZXNzZWQgdGhyb3VnaC5cbiAgICAgICAgLy8gZnJvbSAwIHRvIG51bWJlciBvZiBzbGF0cyAoaW5jbHVzaXZlKVxuICAgICAgICAvLyBjb25zdHJhaW5lZCBiZWNhdXNlIHNsb3RNaW5UaW1lL3Nsb3RNYXhUaW1lIG1pZ2h0IGJlIGN1c3RvbWl6ZWQuXG4gICAgICAgIHNsYXRDb3ZlcmFnZSA9IE1hdGgubWF4KDAsIHNsYXRDb3ZlcmFnZSk7XG4gICAgICAgIHNsYXRDb3ZlcmFnZSA9IE1hdGgubWluKGxlbiwgc2xhdENvdmVyYWdlKTtcbiAgICAgICAgLy8gYW4gaW50ZWdlciBpbmRleCBvZiB0aGUgZnVydGhlc3Qgd2hvbGUgc2xhdFxuICAgICAgICAvLyBmcm9tIDAgdG8gbnVtYmVyIHNsYXRzICgqZXhjbHVzaXZlKiwgc28gbGVuLTEpXG4gICAgICAgIHNsYXRJbmRleCA9IE1hdGguZmxvb3Ioc2xhdENvdmVyYWdlKTtcbiAgICAgICAgc2xhdEluZGV4ID0gTWF0aC5taW4oc2xhdEluZGV4LCBsZW4gLSAxKTtcbiAgICAgICAgLy8gaG93IG11Y2ggZnVydGhlciB0aHJvdWdoIHRoZSBzbGF0SW5kZXggc2xhdCAoZnJvbSAwLjAtMS4wKSBtdXN0IGJlIGNvdmVyZWQgaW4gYWRkaXRpb24uXG4gICAgICAgIC8vIGNvdWxkIGJlIDEuMCBpZiBzbGF0Q292ZXJhZ2UgaXMgY292ZXJpbmcgKmFsbCogdGhlIHNsb3RzXG4gICAgICAgIHNsYXRSZW1haW5kZXIgPSBzbGF0Q292ZXJhZ2UgLSBzbGF0SW5kZXg7XG4gICAgICAgIHJldHVybiBwb3NpdGlvbnMudG9wc1tzbGF0SW5kZXhdICtcbiAgICAgICAgICAgIHBvc2l0aW9ucy5nZXRIZWlnaHQoc2xhdEluZGV4KSAqIHNsYXRSZW1haW5kZXI7XG4gICAgfVxufVxuXG5jbGFzcyBUaW1lQ29sc1NsYXRzQm9keSBleHRlbmRzIEJhc2VDb21wb25lbnQge1xuICAgIHJlbmRlcigpIHtcbiAgICAgICAgbGV0IHsgcHJvcHMsIGNvbnRleHQgfSA9IHRoaXM7XG4gICAgICAgIGxldCB7IG9wdGlvbnMgfSA9IGNvbnRleHQ7XG4gICAgICAgIGxldCB7IHNsYXRFbFJlZnMgfSA9IHByb3BzO1xuICAgICAgICByZXR1cm4gKGNyZWF0ZUVsZW1lbnQoXCJ0Ym9keVwiLCBudWxsLCBwcm9wcy5zbGF0TWV0YXMubWFwKChzbGF0TWV0YSwgaSkgPT4ge1xuICAgICAgICAgICAgbGV0IHJlbmRlclByb3BzID0ge1xuICAgICAgICAgICAgICAgIHRpbWU6IHNsYXRNZXRhLnRpbWUsXG4gICAgICAgICAgICAgICAgZGF0ZTogY29udGV4dC5kYXRlRW52LnRvRGF0ZShzbGF0TWV0YS5kYXRlKSxcbiAgICAgICAgICAgICAgICB2aWV3OiBjb250ZXh0LnZpZXdBcGksXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgcmV0dXJuIChjcmVhdGVFbGVtZW50KFwidHJcIiwgeyBrZXk6IHNsYXRNZXRhLmtleSwgcmVmOiBzbGF0RWxSZWZzLmNyZWF0ZVJlZihzbGF0TWV0YS5rZXkpIH0sXG4gICAgICAgICAgICAgICAgcHJvcHMuYXhpcyAmJiAoY3JlYXRlRWxlbWVudChUaW1lQ29sc0F4aXNDZWxsLCBPYmplY3QuYXNzaWduKHt9LCBzbGF0TWV0YSkpKSxcbiAgICAgICAgICAgICAgICBjcmVhdGVFbGVtZW50KENvbnRlbnRDb250YWluZXIsIHsgZWxUYWc6IFwidGRcIiwgZWxDbGFzc2VzOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICAnZmMtdGltZWdyaWQtc2xvdCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAnZmMtdGltZWdyaWQtc2xvdC1sYW5lJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICFzbGF0TWV0YS5pc0xhYmVsZWQgJiYgJ2ZjLXRpbWVncmlkLXNsb3QtbWlub3InLFxuICAgICAgICAgICAgICAgICAgICBdLCBlbEF0dHJzOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAnZGF0YS10aW1lJzogc2xhdE1ldGEuaXNvVGltZVN0cixcbiAgICAgICAgICAgICAgICAgICAgfSwgcmVuZGVyUHJvcHM6IHJlbmRlclByb3BzLCBnZW5lcmF0b3JOYW1lOiBcInNsb3RMYW5lQ29udGVudFwiLCBnZW5lcmF0b3I6IG9wdGlvbnMuc2xvdExhbmVDb250ZW50LCBjbGFzc05hbWVHZW5lcmF0b3I6IG9wdGlvbnMuc2xvdExhbmVDbGFzc05hbWVzLCBkaWRNb3VudDogb3B0aW9ucy5zbG90TGFuZURpZE1vdW50LCB3aWxsVW5tb3VudDogb3B0aW9ucy5zbG90TGFuZVdpbGxVbm1vdW50IH0pKSk7XG4gICAgICAgIH0pKSk7XG4gICAgfVxufVxuXG4vKlxuZm9yIHRoZSBob3Jpem9udGFsIFwic2xhdHNcIiB0aGF0IHJ1biB3aWR0aC13aXNlLiBIYXMgYSB0aW1lIGF4aXMgb24gYSBzaWRlLiBEZXBlbmRzIG9uIFJUTC5cbiovXG5jbGFzcyBUaW1lQ29sc1NsYXRzIGV4dGVuZHMgQmFzZUNvbXBvbmVudCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMucm9vdEVsUmVmID0gY3JlYXRlUmVmKCk7XG4gICAgICAgIHRoaXMuc2xhdEVsUmVmcyA9IG5ldyBSZWZNYXAoKTtcbiAgICB9XG4gICAgcmVuZGVyKCkge1xuICAgICAgICBsZXQgeyBwcm9wcywgY29udGV4dCB9ID0gdGhpcztcbiAgICAgICAgcmV0dXJuIChjcmVhdGVFbGVtZW50KFwiZGl2XCIsIHsgcmVmOiB0aGlzLnJvb3RFbFJlZiwgY2xhc3NOYW1lOiBcImZjLXRpbWVncmlkLXNsb3RzXCIgfSxcbiAgICAgICAgICAgIGNyZWF0ZUVsZW1lbnQoXCJ0YWJsZVwiLCB7IFwiYXJpYS1oaWRkZW5cIjogdHJ1ZSwgY2xhc3NOYW1lOiBjb250ZXh0LnRoZW1lLmdldENsYXNzKCd0YWJsZScpLCBzdHlsZToge1xuICAgICAgICAgICAgICAgICAgICBtaW5XaWR0aDogcHJvcHMudGFibGVNaW5XaWR0aCxcbiAgICAgICAgICAgICAgICAgICAgd2lkdGg6IHByb3BzLmNsaWVudFdpZHRoLFxuICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IHByb3BzLm1pbkhlaWdodCxcbiAgICAgICAgICAgICAgICB9IH0sXG4gICAgICAgICAgICAgICAgcHJvcHMudGFibGVDb2xHcm91cE5vZGUgLyogcmVsaWVzIG9uIHRoZXJlIG9ubHkgYmVpbmcgYSBzaW5nbGUgPGNvbD4gZm9yIHRoZSBheGlzICovLFxuICAgICAgICAgICAgICAgIGNyZWF0ZUVsZW1lbnQoVGltZUNvbHNTbGF0c0JvZHksIHsgc2xhdEVsUmVmczogdGhpcy5zbGF0RWxSZWZzLCBheGlzOiBwcm9wcy5heGlzLCBzbGF0TWV0YXM6IHByb3BzLnNsYXRNZXRhcyB9KSkpKTtcbiAgICB9XG4gICAgY29tcG9uZW50RGlkTW91bnQoKSB7XG4gICAgICAgIHRoaXMudXBkYXRlU2l6aW5nKCk7XG4gICAgfVxuICAgIGNvbXBvbmVudERpZFVwZGF0ZSgpIHtcbiAgICAgICAgdGhpcy51cGRhdGVTaXppbmcoKTtcbiAgICB9XG4gICAgY29tcG9uZW50V2lsbFVubW91bnQoKSB7XG4gICAgICAgIGlmICh0aGlzLnByb3BzLm9uQ29vcmRzKSB7XG4gICAgICAgICAgICB0aGlzLnByb3BzLm9uQ29vcmRzKG51bGwpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHVwZGF0ZVNpemluZygpIHtcbiAgICAgICAgbGV0IHsgY29udGV4dCwgcHJvcHMgfSA9IHRoaXM7XG4gICAgICAgIGlmIChwcm9wcy5vbkNvb3JkcyAmJlxuICAgICAgICAgICAgcHJvcHMuY2xpZW50V2lkdGggIT09IG51bGwgLy8gbWVhbnMgc2l6aW5nIGhhcyBzdGFiaWxpemVkXG4gICAgICAgICkge1xuICAgICAgICAgICAgbGV0IHJvb3RFbCA9IHRoaXMucm9vdEVsUmVmLmN1cnJlbnQ7XG4gICAgICAgICAgICBpZiAocm9vdEVsLm9mZnNldEhlaWdodCkgeyAvLyBub3QgaGlkZGVuIGJ5IGNzc1xuICAgICAgICAgICAgICAgIHByb3BzLm9uQ29vcmRzKG5ldyBUaW1lQ29sc1NsYXRzQ29vcmRzKG5ldyBQb3NpdGlvbkNhY2hlKHRoaXMucm9vdEVsUmVmLmN1cnJlbnQsIGNvbGxlY3RTbGF0RWxzKHRoaXMuc2xhdEVsUmVmcy5jdXJyZW50TWFwLCBwcm9wcy5zbGF0TWV0YXMpLCBmYWxzZSwgdHJ1ZSksIHRoaXMucHJvcHMuZGF0ZVByb2ZpbGUsIGNvbnRleHQub3B0aW9ucy5zbG90RHVyYXRpb24pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cbmZ1bmN0aW9uIGNvbGxlY3RTbGF0RWxzKGVsTWFwLCBzbGF0TWV0YXMpIHtcbiAgICByZXR1cm4gc2xhdE1ldGFzLm1hcCgoc2xhdE1ldGEpID0+IGVsTWFwW3NsYXRNZXRhLmtleV0pO1xufVxuXG5mdW5jdGlvbiBzcGxpdFNlZ3NCeUNvbChzZWdzLCBjb2xDbnQpIHtcbiAgICBsZXQgc2Vnc0J5Q29sID0gW107XG4gICAgbGV0IGk7XG4gICAgZm9yIChpID0gMDsgaSA8IGNvbENudDsgaSArPSAxKSB7XG4gICAgICAgIHNlZ3NCeUNvbC5wdXNoKFtdKTtcbiAgICB9XG4gICAgaWYgKHNlZ3MpIHtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IHNlZ3MubGVuZ3RoOyBpICs9IDEpIHtcbiAgICAgICAgICAgIHNlZ3NCeUNvbFtzZWdzW2ldLmNvbF0ucHVzaChzZWdzW2ldKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gc2Vnc0J5Q29sO1xufVxuZnVuY3Rpb24gc3BsaXRJbnRlcmFjdGlvbkJ5Q29sKHVpLCBjb2xDbnQpIHtcbiAgICBsZXQgYnlSb3cgPSBbXTtcbiAgICBpZiAoIXVpKSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY29sQ250OyBpICs9IDEpIHtcbiAgICAgICAgICAgIGJ5Um93W2ldID0gbnVsbDtcbiAgICAgICAgfVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb2xDbnQ7IGkgKz0gMSkge1xuICAgICAgICAgICAgYnlSb3dbaV0gPSB7XG4gICAgICAgICAgICAgICAgYWZmZWN0ZWRJbnN0YW5jZXM6IHVpLmFmZmVjdGVkSW5zdGFuY2VzLFxuICAgICAgICAgICAgICAgIGlzRXZlbnQ6IHVpLmlzRXZlbnQsXG4gICAgICAgICAgICAgICAgc2VnczogW10sXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGZvciAobGV0IHNlZyBvZiB1aS5zZWdzKSB7XG4gICAgICAgICAgICBieVJvd1tzZWcuY29sXS5zZWdzLnB1c2goc2VnKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gYnlSb3c7XG59XG5cbmNsYXNzIFRpbWVDb2xNb3JlTGluayBleHRlbmRzIEJhc2VDb21wb25lbnQge1xuICAgIHJlbmRlcigpIHtcbiAgICAgICAgbGV0IHsgcHJvcHMgfSA9IHRoaXM7XG4gICAgICAgIHJldHVybiAoY3JlYXRlRWxlbWVudChNb3JlTGlua0NvbnRhaW5lciwgeyBlbENsYXNzZXM6IFsnZmMtdGltZWdyaWQtbW9yZS1saW5rJ10sIGVsU3R5bGU6IHtcbiAgICAgICAgICAgICAgICB0b3A6IHByb3BzLnRvcCxcbiAgICAgICAgICAgICAgICBib3R0b206IHByb3BzLmJvdHRvbSxcbiAgICAgICAgICAgIH0sIGFsbERheURhdGU6IG51bGwsIG1vcmVDbnQ6IHByb3BzLmhpZGRlblNlZ3MubGVuZ3RoLCBhbGxTZWdzOiBwcm9wcy5oaWRkZW5TZWdzLCBoaWRkZW5TZWdzOiBwcm9wcy5oaWRkZW5TZWdzLCBleHRyYURhdGVTcGFuOiBwcm9wcy5leHRyYURhdGVTcGFuLCBkYXRlUHJvZmlsZTogcHJvcHMuZGF0ZVByb2ZpbGUsIHRvZGF5UmFuZ2U6IHByb3BzLnRvZGF5UmFuZ2UsIHBvcG92ZXJDb250ZW50OiAoKSA9PiByZW5kZXJQbGFpbkZnU2Vncyhwcm9wcy5oaWRkZW5TZWdzLCBwcm9wcyksIGRlZmF1bHRHZW5lcmF0b3I6IHJlbmRlck1vcmVMaW5rSW5uZXIgfSwgKElubmVyQ29udGVudCkgPT4gKGNyZWF0ZUVsZW1lbnQoSW5uZXJDb250ZW50LCB7IGVsVGFnOiBcImRpdlwiLCBlbENsYXNzZXM6IFsnZmMtdGltZWdyaWQtbW9yZS1saW5rLWlubmVyJywgJ2ZjLXN0aWNreSddIH0pKSkpO1xuICAgIH1cbn1cbmZ1bmN0aW9uIHJlbmRlck1vcmVMaW5rSW5uZXIocHJvcHMpIHtcbiAgICByZXR1cm4gcHJvcHMuc2hvcnRUZXh0O1xufVxuXG4vLyBzZWdJbnB1dHMgYXNzdW1lZCBzb3J0ZWRcbmZ1bmN0aW9uIGJ1aWxkUG9zaXRpb25pbmcoc2VnSW5wdXRzLCBzdHJpY3RPcmRlciwgbWF4U3RhY2tDbnQpIHtcbiAgICBsZXQgaGllcmFyY2h5ID0gbmV3IFNlZ0hpZXJhcmNoeSgpO1xuICAgIGlmIChzdHJpY3RPcmRlciAhPSBudWxsKSB7XG4gICAgICAgIGhpZXJhcmNoeS5zdHJpY3RPcmRlciA9IHN0cmljdE9yZGVyO1xuICAgIH1cbiAgICBpZiAobWF4U3RhY2tDbnQgIT0gbnVsbCkge1xuICAgICAgICBoaWVyYXJjaHkubWF4U3RhY2tDbnQgPSBtYXhTdGFja0NudDtcbiAgICB9XG4gICAgbGV0IGhpZGRlbkVudHJpZXMgPSBoaWVyYXJjaHkuYWRkU2VncyhzZWdJbnB1dHMpO1xuICAgIGxldCBoaWRkZW5Hcm91cHMgPSBncm91cEludGVyc2VjdGluZ0VudHJpZXMoaGlkZGVuRW50cmllcyk7XG4gICAgbGV0IHdlYiA9IGJ1aWxkV2ViKGhpZXJhcmNoeSk7XG4gICAgd2ViID0gc3RyZXRjaFdlYih3ZWIsIDEpOyAvLyBhbGwgbGV2ZWxDb29yZHMvdGhpY2tuZXNzIHdpbGwgaGF2ZSAwLjAtMS4wXG4gICAgbGV0IHNlZ1JlY3RzID0gd2ViVG9SZWN0cyh3ZWIpO1xuICAgIHJldHVybiB7IHNlZ1JlY3RzLCBoaWRkZW5Hcm91cHMgfTtcbn1cbmZ1bmN0aW9uIGJ1aWxkV2ViKGhpZXJhcmNoeSkge1xuICAgIGNvbnN0IHsgZW50cmllc0J5TGV2ZWwgfSA9IGhpZXJhcmNoeTtcbiAgICBjb25zdCBidWlsZE5vZGUgPSBjYWNoZWFibGUoKGxldmVsLCBsYXRlcmFsKSA9PiBsZXZlbCArICc6JyArIGxhdGVyYWwsIChsZXZlbCwgbGF0ZXJhbCkgPT4ge1xuICAgICAgICBsZXQgc2libGluZ1JhbmdlID0gZmluZE5leHRMZXZlbFNlZ3MoaGllcmFyY2h5LCBsZXZlbCwgbGF0ZXJhbCk7XG4gICAgICAgIGxldCBuZXh0TGV2ZWxSZXMgPSBidWlsZE5vZGVzKHNpYmxpbmdSYW5nZSwgYnVpbGROb2RlKTtcbiAgICAgICAgbGV0IGVudHJ5ID0gZW50cmllc0J5TGV2ZWxbbGV2ZWxdW2xhdGVyYWxdO1xuICAgICAgICByZXR1cm4gW1xuICAgICAgICAgICAgT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCBlbnRyeSksIHsgbmV4dExldmVsTm9kZXM6IG5leHRMZXZlbFJlc1swXSB9KSxcbiAgICAgICAgICAgIGVudHJ5LnRoaWNrbmVzcyArIG5leHRMZXZlbFJlc1sxXSwgLy8gdGhlIHByZXNzdXJlIGJ1aWxkc1xuICAgICAgICBdO1xuICAgIH0pO1xuICAgIHJldHVybiBidWlsZE5vZGVzKGVudHJpZXNCeUxldmVsLmxlbmd0aFxuICAgICAgICA/IHsgbGV2ZWw6IDAsIGxhdGVyYWxTdGFydDogMCwgbGF0ZXJhbEVuZDogZW50cmllc0J5TGV2ZWxbMF0ubGVuZ3RoIH1cbiAgICAgICAgOiBudWxsLCBidWlsZE5vZGUpWzBdO1xufVxuZnVuY3Rpb24gYnVpbGROb2RlcyhzaWJsaW5nUmFuZ2UsIGJ1aWxkTm9kZSkge1xuICAgIGlmICghc2libGluZ1JhbmdlKSB7XG4gICAgICAgIHJldHVybiBbW10sIDBdO1xuICAgIH1cbiAgICBsZXQgeyBsZXZlbCwgbGF0ZXJhbFN0YXJ0LCBsYXRlcmFsRW5kIH0gPSBzaWJsaW5nUmFuZ2U7XG4gICAgbGV0IGxhdGVyYWwgPSBsYXRlcmFsU3RhcnQ7XG4gICAgbGV0IHBhaXJzID0gW107XG4gICAgd2hpbGUgKGxhdGVyYWwgPCBsYXRlcmFsRW5kKSB7XG4gICAgICAgIHBhaXJzLnB1c2goYnVpbGROb2RlKGxldmVsLCBsYXRlcmFsKSk7XG4gICAgICAgIGxhdGVyYWwgKz0gMTtcbiAgICB9XG4gICAgcGFpcnMuc29ydChjbXBEZXNjUHJlc3N1cmVzKTtcbiAgICByZXR1cm4gW1xuICAgICAgICBwYWlycy5tYXAoZXh0cmFjdE5vZGUpLFxuICAgICAgICBwYWlyc1swXVsxXSwgLy8gZmlyc3QgaXRlbSdzIHByZXNzdXJlXG4gICAgXTtcbn1cbmZ1bmN0aW9uIGNtcERlc2NQcmVzc3VyZXMoYSwgYikge1xuICAgIHJldHVybiBiWzFdIC0gYVsxXTtcbn1cbmZ1bmN0aW9uIGV4dHJhY3ROb2RlKGEpIHtcbiAgICByZXR1cm4gYVswXTtcbn1cbmZ1bmN0aW9uIGZpbmROZXh0TGV2ZWxTZWdzKGhpZXJhcmNoeSwgc3ViamVjdExldmVsLCBzdWJqZWN0TGF0ZXJhbCkge1xuICAgIGxldCB7IGxldmVsQ29vcmRzLCBlbnRyaWVzQnlMZXZlbCB9ID0gaGllcmFyY2h5O1xuICAgIGxldCBzdWJqZWN0RW50cnkgPSBlbnRyaWVzQnlMZXZlbFtzdWJqZWN0TGV2ZWxdW3N1YmplY3RMYXRlcmFsXTtcbiAgICBsZXQgYWZ0ZXJTdWJqZWN0ID0gbGV2ZWxDb29yZHNbc3ViamVjdExldmVsXSArIHN1YmplY3RFbnRyeS50aGlja25lc3M7XG4gICAgbGV0IGxldmVsQ250ID0gbGV2ZWxDb29yZHMubGVuZ3RoO1xuICAgIGxldCBsZXZlbCA9IHN1YmplY3RMZXZlbDtcbiAgICAvLyBza2lwIHBhc3QgbGV2ZWxzIHRoYXQgYXJlIHRvbyBoaWdoIHVwXG4gICAgZm9yICg7IGxldmVsIDwgbGV2ZWxDbnQgJiYgbGV2ZWxDb29yZHNbbGV2ZWxdIDwgYWZ0ZXJTdWJqZWN0OyBsZXZlbCArPSAxKVxuICAgICAgICA7IC8vIGRvIG5vdGhpbmdcbiAgICBmb3IgKDsgbGV2ZWwgPCBsZXZlbENudDsgbGV2ZWwgKz0gMSkge1xuICAgICAgICBsZXQgZW50cmllcyA9IGVudHJpZXNCeUxldmVsW2xldmVsXTtcbiAgICAgICAgbGV0IGVudHJ5O1xuICAgICAgICBsZXQgc2VhcmNoSW5kZXggPSBiaW5hcnlTZWFyY2goZW50cmllcywgc3ViamVjdEVudHJ5LnNwYW4uc3RhcnQsIGdldEVudHJ5U3BhbkVuZCk7XG4gICAgICAgIGxldCBsYXRlcmFsU3RhcnQgPSBzZWFyY2hJbmRleFswXSArIHNlYXJjaEluZGV4WzFdOyAvLyBpZiBleGFjdCBtYXRjaCAod2hpY2ggZG9lc24ndCBjb2xsaWRlKSwgZ28gdG8gbmV4dCBvbmVcbiAgICAgICAgbGV0IGxhdGVyYWxFbmQgPSBsYXRlcmFsU3RhcnQ7XG4gICAgICAgIHdoaWxlICggLy8gbG9vcCB0aHJvdWdoIGVudHJpZXMgdGhhdCBob3Jpem9udGFsbHkgaW50ZXJzZWN0XG4gICAgICAgIChlbnRyeSA9IGVudHJpZXNbbGF0ZXJhbEVuZF0pICYmIC8vIGJ1dCBub3QgcGFzdCB0aGUgd2hvbGUgc2VnIGxpc3RcbiAgICAgICAgICAgIGVudHJ5LnNwYW4uc3RhcnQgPCBzdWJqZWN0RW50cnkuc3Bhbi5lbmQpIHtcbiAgICAgICAgICAgIGxhdGVyYWxFbmQgKz0gMTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobGF0ZXJhbFN0YXJ0IDwgbGF0ZXJhbEVuZCkge1xuICAgICAgICAgICAgcmV0dXJuIHsgbGV2ZWwsIGxhdGVyYWxTdGFydCwgbGF0ZXJhbEVuZCB9O1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xufVxuZnVuY3Rpb24gc3RyZXRjaFdlYih0b3BMZXZlbE5vZGVzLCB0b3RhbFRoaWNrbmVzcykge1xuICAgIGNvbnN0IHN0cmV0Y2hOb2RlID0gY2FjaGVhYmxlKChub2RlLCBzdGFydENvb3JkLCBwcmV2VGhpY2tuZXNzKSA9PiBidWlsZEVudHJ5S2V5KG5vZGUpLCAobm9kZSwgc3RhcnRDb29yZCwgcHJldlRoaWNrbmVzcykgPT4ge1xuICAgICAgICBsZXQgeyBuZXh0TGV2ZWxOb2RlcywgdGhpY2tuZXNzIH0gPSBub2RlO1xuICAgICAgICBsZXQgYWxsVGhpY2tuZXNzID0gdGhpY2tuZXNzICsgcHJldlRoaWNrbmVzcztcbiAgICAgICAgbGV0IHRoaWNrbmVzc0ZyYWN0aW9uID0gdGhpY2tuZXNzIC8gYWxsVGhpY2tuZXNzO1xuICAgICAgICBsZXQgZW5kQ29vcmQ7XG4gICAgICAgIGxldCBuZXdDaGlsZHJlbiA9IFtdO1xuICAgICAgICBpZiAoIW5leHRMZXZlbE5vZGVzLmxlbmd0aCkge1xuICAgICAgICAgICAgZW5kQ29vcmQgPSB0b3RhbFRoaWNrbmVzcztcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGZvciAobGV0IGNoaWxkTm9kZSBvZiBuZXh0TGV2ZWxOb2Rlcykge1xuICAgICAgICAgICAgICAgIGlmIChlbmRDb29yZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCByZXMgPSBzdHJldGNoTm9kZShjaGlsZE5vZGUsIHN0YXJ0Q29vcmQsIGFsbFRoaWNrbmVzcyk7XG4gICAgICAgICAgICAgICAgICAgIGVuZENvb3JkID0gcmVzWzBdO1xuICAgICAgICAgICAgICAgICAgICBuZXdDaGlsZHJlbi5wdXNoKHJlc1sxXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBsZXQgcmVzID0gc3RyZXRjaE5vZGUoY2hpbGROb2RlLCBlbmRDb29yZCwgMCk7XG4gICAgICAgICAgICAgICAgICAgIG5ld0NoaWxkcmVuLnB1c2gocmVzWzFdKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgbGV0IG5ld1RoaWNrbmVzcyA9IChlbmRDb29yZCAtIHN0YXJ0Q29vcmQpICogdGhpY2tuZXNzRnJhY3Rpb247XG4gICAgICAgIHJldHVybiBbZW5kQ29vcmQgLSBuZXdUaGlja25lc3MsIE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgbm9kZSksIHsgdGhpY2tuZXNzOiBuZXdUaGlja25lc3MsIG5leHRMZXZlbE5vZGVzOiBuZXdDaGlsZHJlbiB9KV07XG4gICAgfSk7XG4gICAgcmV0dXJuIHRvcExldmVsTm9kZXMubWFwKChub2RlKSA9PiBzdHJldGNoTm9kZShub2RlLCAwLCAwKVsxXSk7XG59XG4vLyBub3Qgc29ydGVkIGluIGFueSBwYXJ0aWN1bGFyIG9yZGVyXG5mdW5jdGlvbiB3ZWJUb1JlY3RzKHRvcExldmVsTm9kZXMpIHtcbiAgICBsZXQgcmVjdHMgPSBbXTtcbiAgICBjb25zdCBwcm9jZXNzTm9kZSA9IGNhY2hlYWJsZSgobm9kZSwgbGV2ZWxDb29yZCwgc3RhY2tEZXB0aCkgPT4gYnVpbGRFbnRyeUtleShub2RlKSwgKG5vZGUsIGxldmVsQ29vcmQsIHN0YWNrRGVwdGgpID0+IHtcbiAgICAgICAgbGV0IHJlY3QgPSBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sIG5vZGUpLCB7IGxldmVsQ29vcmQsXG4gICAgICAgICAgICBzdGFja0RlcHRoLCBzdGFja0ZvcndhcmQ6IDAgfSk7XG4gICAgICAgIHJlY3RzLnB1c2gocmVjdCk7XG4gICAgICAgIHJldHVybiAocmVjdC5zdGFja0ZvcndhcmQgPSBwcm9jZXNzTm9kZXMobm9kZS5uZXh0TGV2ZWxOb2RlcywgbGV2ZWxDb29yZCArIG5vZGUudGhpY2tuZXNzLCBzdGFja0RlcHRoICsgMSkgKyAxKTtcbiAgICB9KTtcbiAgICBmdW5jdGlvbiBwcm9jZXNzTm9kZXMobm9kZXMsIGxldmVsQ29vcmQsIHN0YWNrRGVwdGgpIHtcbiAgICAgICAgbGV0IHN0YWNrRm9yd2FyZCA9IDA7XG4gICAgICAgIGZvciAobGV0IG5vZGUgb2Ygbm9kZXMpIHtcbiAgICAgICAgICAgIHN0YWNrRm9yd2FyZCA9IE1hdGgubWF4KHByb2Nlc3NOb2RlKG5vZGUsIGxldmVsQ29vcmQsIHN0YWNrRGVwdGgpLCBzdGFja0ZvcndhcmQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzdGFja0ZvcndhcmQ7XG4gICAgfVxuICAgIHByb2Nlc3NOb2Rlcyh0b3BMZXZlbE5vZGVzLCAwLCAwKTtcbiAgICByZXR1cm4gcmVjdHM7IC8vIFRPRE86IHNvcnQgcmVjdHMgYnkgbGV2ZWxDb29yZCB0byBiZSBjb25zaXN0ZW50IHdpdGggdG9SZWN0cz9cbn1cbi8vIFRPRE86IG1vdmUgdG8gZ2VuZXJhbCB1dGlsXG5mdW5jdGlvbiBjYWNoZWFibGUoa2V5RnVuYywgd29ya0Z1bmMpIHtcbiAgICBjb25zdCBjYWNoZSA9IHt9O1xuICAgIHJldHVybiAoLi4uYXJncykgPT4ge1xuICAgICAgICBsZXQga2V5ID0ga2V5RnVuYyguLi5hcmdzKTtcbiAgICAgICAgcmV0dXJuIChrZXkgaW4gY2FjaGUpXG4gICAgICAgICAgICA/IGNhY2hlW2tleV1cbiAgICAgICAgICAgIDogKGNhY2hlW2tleV0gPSB3b3JrRnVuYyguLi5hcmdzKSk7XG4gICAgfTtcbn1cblxuZnVuY3Rpb24gY29tcHV0ZVNlZ1ZDb29yZHMoc2VncywgY29sRGF0ZSwgc2xhdENvb3JkcyA9IG51bGwsIGV2ZW50TWluSGVpZ2h0ID0gMCkge1xuICAgIGxldCB2Y29vcmRzID0gW107XG4gICAgaWYgKHNsYXRDb29yZHMpIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZWdzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgICAgICBsZXQgc2VnID0gc2Vnc1tpXTtcbiAgICAgICAgICAgIGxldCBzcGFuU3RhcnQgPSBzbGF0Q29vcmRzLmNvbXB1dGVEYXRlVG9wKHNlZy5zdGFydCwgY29sRGF0ZSk7XG4gICAgICAgICAgICBsZXQgc3BhbkVuZCA9IE1hdGgubWF4KHNwYW5TdGFydCArIChldmVudE1pbkhlaWdodCB8fCAwKSwgLy8gOihcbiAgICAgICAgICAgIHNsYXRDb29yZHMuY29tcHV0ZURhdGVUb3Aoc2VnLmVuZCwgY29sRGF0ZSkpO1xuICAgICAgICAgICAgdmNvb3Jkcy5wdXNoKHtcbiAgICAgICAgICAgICAgICBzdGFydDogTWF0aC5yb3VuZChzcGFuU3RhcnQpLFxuICAgICAgICAgICAgICAgIGVuZDogTWF0aC5yb3VuZChzcGFuRW5kKSwgLy9cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB2Y29vcmRzO1xufVxuZnVuY3Rpb24gY29tcHV0ZUZnU2VnUGxhY2VtZW50cyhzZWdzLCBzZWdWQ29vcmRzLCAvLyBtaWdodCBub3QgaGF2ZSBmb3IgZXZlcnkgc2VnXG5ldmVudE9yZGVyU3RyaWN0LCBldmVudE1heFN0YWNrKSB7XG4gICAgbGV0IHNlZ0lucHV0cyA9IFtdO1xuICAgIGxldCBkdW1iU2VncyA9IFtdOyAvLyBzZWdzIHdpdGhvdXQgY29vcmRzXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZWdzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgICAgIGxldCB2Y29vcmRzID0gc2VnVkNvb3Jkc1tpXTtcbiAgICAgICAgaWYgKHZjb29yZHMpIHtcbiAgICAgICAgICAgIHNlZ0lucHV0cy5wdXNoKHtcbiAgICAgICAgICAgICAgICBpbmRleDogaSxcbiAgICAgICAgICAgICAgICB0aGlja25lc3M6IDEsXG4gICAgICAgICAgICAgICAgc3BhbjogdmNvb3JkcyxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZHVtYlNlZ3MucHVzaChzZWdzW2ldKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBsZXQgeyBzZWdSZWN0cywgaGlkZGVuR3JvdXBzIH0gPSBidWlsZFBvc2l0aW9uaW5nKHNlZ0lucHV0cywgZXZlbnRPcmRlclN0cmljdCwgZXZlbnRNYXhTdGFjayk7XG4gICAgbGV0IHNlZ1BsYWNlbWVudHMgPSBbXTtcbiAgICBmb3IgKGxldCBzZWdSZWN0IG9mIHNlZ1JlY3RzKSB7XG4gICAgICAgIHNlZ1BsYWNlbWVudHMucHVzaCh7XG4gICAgICAgICAgICBzZWc6IHNlZ3Nbc2VnUmVjdC5pbmRleF0sXG4gICAgICAgICAgICByZWN0OiBzZWdSZWN0LFxuICAgICAgICB9KTtcbiAgICB9XG4gICAgZm9yIChsZXQgZHVtYlNlZyBvZiBkdW1iU2Vncykge1xuICAgICAgICBzZWdQbGFjZW1lbnRzLnB1c2goeyBzZWc6IGR1bWJTZWcsIHJlY3Q6IG51bGwgfSk7XG4gICAgfVxuICAgIHJldHVybiB7IHNlZ1BsYWNlbWVudHMsIGhpZGRlbkdyb3VwcyB9O1xufVxuXG5jb25zdCBERUZBVUxUX1RJTUVfRk9STUFUID0gY3JlYXRlRm9ybWF0dGVyKHtcbiAgICBob3VyOiAnbnVtZXJpYycsXG4gICAgbWludXRlOiAnMi1kaWdpdCcsXG4gICAgbWVyaWRpZW06IGZhbHNlLFxufSk7XG5jbGFzcyBUaW1lQ29sRXZlbnQgZXh0ZW5kcyBCYXNlQ29tcG9uZW50IHtcbiAgICByZW5kZXIoKSB7XG4gICAgICAgIHJldHVybiAoY3JlYXRlRWxlbWVudChTdGFuZGFyZEV2ZW50LCBPYmplY3QuYXNzaWduKHt9LCB0aGlzLnByb3BzLCB7IGVsQ2xhc3NlczogW1xuICAgICAgICAgICAgICAgICdmYy10aW1lZ3JpZC1ldmVudCcsXG4gICAgICAgICAgICAgICAgJ2ZjLXYtZXZlbnQnLFxuICAgICAgICAgICAgICAgIHRoaXMucHJvcHMuaXNTaG9ydCAmJiAnZmMtdGltZWdyaWQtZXZlbnQtc2hvcnQnLFxuICAgICAgICAgICAgXSwgZGVmYXVsdFRpbWVGb3JtYXQ6IERFRkFVTFRfVElNRV9GT1JNQVQgfSkpKTtcbiAgICB9XG59XG5cbmNsYXNzIFRpbWVDb2wgZXh0ZW5kcyBCYXNlQ29tcG9uZW50IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5zb3J0RXZlbnRTZWdzID0gbWVtb2l6ZShzb3J0RXZlbnRTZWdzKTtcbiAgICB9XG4gICAgLy8gVE9ETzogbWVtb2l6ZSBldmVudC1wbGFjZW1lbnQ/XG4gICAgcmVuZGVyKCkge1xuICAgICAgICBsZXQgeyBwcm9wcywgY29udGV4dCB9ID0gdGhpcztcbiAgICAgICAgbGV0IHsgb3B0aW9ucyB9ID0gY29udGV4dDtcbiAgICAgICAgbGV0IGlzU2VsZWN0TWlycm9yID0gb3B0aW9ucy5zZWxlY3RNaXJyb3I7XG4gICAgICAgIGxldCBtaXJyb3JTZWdzID0gLy8geXVja1xuICAgICAgICAgKHByb3BzLmV2ZW50RHJhZyAmJiBwcm9wcy5ldmVudERyYWcuc2VncykgfHxcbiAgICAgICAgICAgIChwcm9wcy5ldmVudFJlc2l6ZSAmJiBwcm9wcy5ldmVudFJlc2l6ZS5zZWdzKSB8fFxuICAgICAgICAgICAgKGlzU2VsZWN0TWlycm9yICYmIHByb3BzLmRhdGVTZWxlY3Rpb25TZWdzKSB8fFxuICAgICAgICAgICAgW107XG4gICAgICAgIGxldCBpbnRlcmFjdGlvbkFmZmVjdGVkSW5zdGFuY2VzID0gLy8gVE9ETzogbWVzc3kgd2F5IHRvIGNvbXB1dGUgdGhpc1xuICAgICAgICAgKHByb3BzLmV2ZW50RHJhZyAmJiBwcm9wcy5ldmVudERyYWcuYWZmZWN0ZWRJbnN0YW5jZXMpIHx8XG4gICAgICAgICAgICAocHJvcHMuZXZlbnRSZXNpemUgJiYgcHJvcHMuZXZlbnRSZXNpemUuYWZmZWN0ZWRJbnN0YW5jZXMpIHx8XG4gICAgICAgICAgICB7fTtcbiAgICAgICAgbGV0IHNvcnRlZEZnU2VncyA9IHRoaXMuc29ydEV2ZW50U2Vncyhwcm9wcy5mZ0V2ZW50U2Vncywgb3B0aW9ucy5ldmVudE9yZGVyKTtcbiAgICAgICAgcmV0dXJuIChjcmVhdGVFbGVtZW50KERheUNlbGxDb250YWluZXIsIHsgZWxUYWc6IFwidGRcIiwgZWxSZWY6IHByb3BzLmVsUmVmLCBlbENsYXNzZXM6IFtcbiAgICAgICAgICAgICAgICAnZmMtdGltZWdyaWQtY29sJyxcbiAgICAgICAgICAgICAgICAuLi4ocHJvcHMuZXh0cmFDbGFzc05hbWVzIHx8IFtdKSxcbiAgICAgICAgICAgIF0sIGVsQXR0cnM6IE9iamVjdC5hc3NpZ24oeyByb2xlOiAnZ3JpZGNlbGwnIH0sIHByb3BzLmV4dHJhRGF0YUF0dHJzKSwgZGF0ZTogcHJvcHMuZGF0ZSwgZGF0ZVByb2ZpbGU6IHByb3BzLmRhdGVQcm9maWxlLCB0b2RheVJhbmdlOiBwcm9wcy50b2RheVJhbmdlLCBleHRyYVJlbmRlclByb3BzOiBwcm9wcy5leHRyYVJlbmRlclByb3BzIH0sIChJbm5lckNvbnRlbnQpID0+IChjcmVhdGVFbGVtZW50KFwiZGl2XCIsIHsgY2xhc3NOYW1lOiBcImZjLXRpbWVncmlkLWNvbC1mcmFtZVwiIH0sXG4gICAgICAgICAgICBjcmVhdGVFbGVtZW50KFwiZGl2XCIsIHsgY2xhc3NOYW1lOiBcImZjLXRpbWVncmlkLWNvbC1iZ1wiIH0sXG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJGaWxsU2Vncyhwcm9wcy5idXNpbmVzc0hvdXJTZWdzLCAnbm9uLWJ1c2luZXNzJyksXG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJGaWxsU2Vncyhwcm9wcy5iZ0V2ZW50U2VncywgJ2JnLWV2ZW50JyksXG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJGaWxsU2Vncyhwcm9wcy5kYXRlU2VsZWN0aW9uU2VncywgJ2hpZ2hsaWdodCcpKSxcbiAgICAgICAgICAgIGNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwgeyBjbGFzc05hbWU6IFwiZmMtdGltZWdyaWQtY29sLWV2ZW50c1wiIH0sIHRoaXMucmVuZGVyRmdTZWdzKHNvcnRlZEZnU2VncywgaW50ZXJhY3Rpb25BZmZlY3RlZEluc3RhbmNlcywgZmFsc2UsIGZhbHNlLCBmYWxzZSkpLFxuICAgICAgICAgICAgY3JlYXRlRWxlbWVudChcImRpdlwiLCB7IGNsYXNzTmFtZTogXCJmYy10aW1lZ3JpZC1jb2wtZXZlbnRzXCIgfSwgdGhpcy5yZW5kZXJGZ1NlZ3MobWlycm9yU2Vncywge30sIEJvb2xlYW4ocHJvcHMuZXZlbnREcmFnKSwgQm9vbGVhbihwcm9wcy5ldmVudFJlc2l6ZSksIEJvb2xlYW4oaXNTZWxlY3RNaXJyb3IpKSksXG4gICAgICAgICAgICBjcmVhdGVFbGVtZW50KFwiZGl2XCIsIHsgY2xhc3NOYW1lOiBcImZjLXRpbWVncmlkLW5vdy1pbmRpY2F0b3ItY29udGFpbmVyXCIgfSwgdGhpcy5yZW5kZXJOb3dJbmRpY2F0b3IocHJvcHMubm93SW5kaWNhdG9yU2VncykpLFxuICAgICAgICAgICAgaGFzQ3VzdG9tRGF5Q2VsbENvbnRlbnQob3B0aW9ucykgJiYgKGNyZWF0ZUVsZW1lbnQoSW5uZXJDb250ZW50LCB7IGVsVGFnOiBcImRpdlwiLCBlbENsYXNzZXM6IFsnZmMtdGltZWdyaWQtY29sLW1pc2MnXSB9KSkpKSkpO1xuICAgIH1cbiAgICByZW5kZXJGZ1NlZ3Moc29ydGVkRmdTZWdzLCBzZWdJc0ludmlzaWJsZSwgaXNEcmFnZ2luZywgaXNSZXNpemluZywgaXNEYXRlU2VsZWN0aW5nKSB7XG4gICAgICAgIGxldCB7IHByb3BzIH0gPSB0aGlzO1xuICAgICAgICBpZiAocHJvcHMuZm9yUHJpbnQpIHtcbiAgICAgICAgICAgIHJldHVybiByZW5kZXJQbGFpbkZnU2Vncyhzb3J0ZWRGZ1NlZ3MsIHByb3BzKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5yZW5kZXJQb3NpdGlvbmVkRmdTZWdzKHNvcnRlZEZnU2Vncywgc2VnSXNJbnZpc2libGUsIGlzRHJhZ2dpbmcsIGlzUmVzaXppbmcsIGlzRGF0ZVNlbGVjdGluZyk7XG4gICAgfVxuICAgIHJlbmRlclBvc2l0aW9uZWRGZ1NlZ3Moc2VncywgLy8gaWYgbm90IG1pcnJvciwgbmVlZHMgdG8gYmUgc29ydGVkXG4gICAgc2VnSXNJbnZpc2libGUsIGlzRHJhZ2dpbmcsIGlzUmVzaXppbmcsIGlzRGF0ZVNlbGVjdGluZykge1xuICAgICAgICBsZXQgeyBldmVudE1heFN0YWNrLCBldmVudFNob3J0SGVpZ2h0LCBldmVudE9yZGVyU3RyaWN0LCBldmVudE1pbkhlaWdodCB9ID0gdGhpcy5jb250ZXh0Lm9wdGlvbnM7XG4gICAgICAgIGxldCB7IGRhdGUsIHNsYXRDb29yZHMsIGV2ZW50U2VsZWN0aW9uLCB0b2RheVJhbmdlLCBub3dEYXRlIH0gPSB0aGlzLnByb3BzO1xuICAgICAgICBsZXQgaXNNaXJyb3IgPSBpc0RyYWdnaW5nIHx8IGlzUmVzaXppbmcgfHwgaXNEYXRlU2VsZWN0aW5nO1xuICAgICAgICBsZXQgc2VnVkNvb3JkcyA9IGNvbXB1dGVTZWdWQ29vcmRzKHNlZ3MsIGRhdGUsIHNsYXRDb29yZHMsIGV2ZW50TWluSGVpZ2h0KTtcbiAgICAgICAgbGV0IHsgc2VnUGxhY2VtZW50cywgaGlkZGVuR3JvdXBzIH0gPSBjb21wdXRlRmdTZWdQbGFjZW1lbnRzKHNlZ3MsIHNlZ1ZDb29yZHMsIGV2ZW50T3JkZXJTdHJpY3QsIGV2ZW50TWF4U3RhY2spO1xuICAgICAgICByZXR1cm4gKGNyZWF0ZUVsZW1lbnQoRnJhZ21lbnQsIG51bGwsXG4gICAgICAgICAgICB0aGlzLnJlbmRlckhpZGRlbkdyb3VwcyhoaWRkZW5Hcm91cHMsIHNlZ3MpLFxuICAgICAgICAgICAgc2VnUGxhY2VtZW50cy5tYXAoKHNlZ1BsYWNlbWVudCkgPT4ge1xuICAgICAgICAgICAgICAgIGxldCB7IHNlZywgcmVjdCB9ID0gc2VnUGxhY2VtZW50O1xuICAgICAgICAgICAgICAgIGxldCBpbnN0YW5jZUlkID0gc2VnLmV2ZW50UmFuZ2UuaW5zdGFuY2UuaW5zdGFuY2VJZDtcbiAgICAgICAgICAgICAgICBsZXQgaXNWaXNpYmxlID0gaXNNaXJyb3IgfHwgQm9vbGVhbighc2VnSXNJbnZpc2libGVbaW5zdGFuY2VJZF0gJiYgcmVjdCk7XG4gICAgICAgICAgICAgICAgbGV0IHZTdHlsZSA9IGNvbXB1dGVTZWdWU3R5bGUocmVjdCAmJiByZWN0LnNwYW4pO1xuICAgICAgICAgICAgICAgIGxldCBoU3R5bGUgPSAoIWlzTWlycm9yICYmIHJlY3QpID8gdGhpcy5jb21wdXRlU2VnSFN0eWxlKHJlY3QpIDogeyBsZWZ0OiAwLCByaWdodDogMCB9O1xuICAgICAgICAgICAgICAgIGxldCBpc0luc2V0ID0gQm9vbGVhbihyZWN0KSAmJiByZWN0LnN0YWNrRm9yd2FyZCA+IDA7XG4gICAgICAgICAgICAgICAgbGV0IGlzU2hvcnQgPSBCb29sZWFuKHJlY3QpICYmIChyZWN0LnNwYW4uZW5kIC0gcmVjdC5zcGFuLnN0YXJ0KSA8IGV2ZW50U2hvcnRIZWlnaHQ7IC8vIGxvb2sgYXQgb3RoZXIgcGxhY2VzIGZvciB0aGlzIHByb2JsZW1cbiAgICAgICAgICAgICAgICByZXR1cm4gKGNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwgeyBjbGFzc05hbWU6ICdmYy10aW1lZ3JpZC1ldmVudC1oYXJuZXNzJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAoaXNJbnNldCA/ICcgZmMtdGltZWdyaWQtZXZlbnQtaGFybmVzcy1pbnNldCcgOiAnJyksIGtleTogaW5zdGFuY2VJZCwgc3R5bGU6IE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7IHZpc2liaWxpdHk6IGlzVmlzaWJsZSA/ICcnIDogJ2hpZGRlbicgfSwgdlN0eWxlKSwgaFN0eWxlKSB9LFxuICAgICAgICAgICAgICAgICAgICBjcmVhdGVFbGVtZW50KFRpbWVDb2xFdmVudCwgT2JqZWN0LmFzc2lnbih7IHNlZzogc2VnLCBpc0RyYWdnaW5nOiBpc0RyYWdnaW5nLCBpc1Jlc2l6aW5nOiBpc1Jlc2l6aW5nLCBpc0RhdGVTZWxlY3Rpbmc6IGlzRGF0ZVNlbGVjdGluZywgaXNTZWxlY3RlZDogaW5zdGFuY2VJZCA9PT0gZXZlbnRTZWxlY3Rpb24sIGlzU2hvcnQ6IGlzU2hvcnQgfSwgZ2V0U2VnTWV0YShzZWcsIHRvZGF5UmFuZ2UsIG5vd0RhdGUpKSkpKTtcbiAgICAgICAgICAgIH0pKSk7XG4gICAgfVxuICAgIC8vIHdpbGwgYWxyZWFkeSBoYXZlIGV2ZW50TWluSGVpZ2h0IGFwcGxpZWQgYmVjYXVzZSBzZWdJbnB1dHMgYWxyZWFkeSBoYWQgaXRcbiAgICByZW5kZXJIaWRkZW5Hcm91cHMoaGlkZGVuR3JvdXBzLCBzZWdzKSB7XG4gICAgICAgIGxldCB7IGV4dHJhRGF0ZVNwYW4sIGRhdGVQcm9maWxlLCB0b2RheVJhbmdlLCBub3dEYXRlLCBldmVudFNlbGVjdGlvbiwgZXZlbnREcmFnLCBldmVudFJlc2l6ZSB9ID0gdGhpcy5wcm9wcztcbiAgICAgICAgcmV0dXJuIChjcmVhdGVFbGVtZW50KEZyYWdtZW50LCBudWxsLCBoaWRkZW5Hcm91cHMubWFwKChoaWRkZW5Hcm91cCkgPT4ge1xuICAgICAgICAgICAgbGV0IHBvc2l0aW9uQ3NzID0gY29tcHV0ZVNlZ1ZTdHlsZShoaWRkZW5Hcm91cC5zcGFuKTtcbiAgICAgICAgICAgIGxldCBoaWRkZW5TZWdzID0gY29tcGlsZVNlZ3NGcm9tRW50cmllcyhoaWRkZW5Hcm91cC5lbnRyaWVzLCBzZWdzKTtcbiAgICAgICAgICAgIHJldHVybiAoY3JlYXRlRWxlbWVudChUaW1lQ29sTW9yZUxpbmssIHsga2V5OiBidWlsZElzb1N0cmluZyhjb21wdXRlRWFybGllc3RTZWdTdGFydChoaWRkZW5TZWdzKSksIGhpZGRlblNlZ3M6IGhpZGRlblNlZ3MsIHRvcDogcG9zaXRpb25Dc3MudG9wLCBib3R0b206IHBvc2l0aW9uQ3NzLmJvdHRvbSwgZXh0cmFEYXRlU3BhbjogZXh0cmFEYXRlU3BhbiwgZGF0ZVByb2ZpbGU6IGRhdGVQcm9maWxlLCB0b2RheVJhbmdlOiB0b2RheVJhbmdlLCBub3dEYXRlOiBub3dEYXRlLCBldmVudFNlbGVjdGlvbjogZXZlbnRTZWxlY3Rpb24sIGV2ZW50RHJhZzogZXZlbnREcmFnLCBldmVudFJlc2l6ZTogZXZlbnRSZXNpemUgfSkpO1xuICAgICAgICB9KSkpO1xuICAgIH1cbiAgICByZW5kZXJGaWxsU2VncyhzZWdzLCBmaWxsVHlwZSkge1xuICAgICAgICBsZXQgeyBwcm9wcywgY29udGV4dCB9ID0gdGhpcztcbiAgICAgICAgbGV0IHNlZ1ZDb29yZHMgPSBjb21wdXRlU2VnVkNvb3JkcyhzZWdzLCBwcm9wcy5kYXRlLCBwcm9wcy5zbGF0Q29vcmRzLCBjb250ZXh0Lm9wdGlvbnMuZXZlbnRNaW5IZWlnaHQpOyAvLyBkb24ndCBhc3N1bWUgYWxsIHBvcHVsYXRlZFxuICAgICAgICBsZXQgY2hpbGRyZW4gPSBzZWdWQ29vcmRzLm1hcCgodmNvb3JkcywgaSkgPT4ge1xuICAgICAgICAgICAgbGV0IHNlZyA9IHNlZ3NbaV07XG4gICAgICAgICAgICByZXR1cm4gKGNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwgeyBrZXk6IGJ1aWxkRXZlbnRSYW5nZUtleShzZWcuZXZlbnRSYW5nZSksIGNsYXNzTmFtZTogXCJmYy10aW1lZ3JpZC1iZy1oYXJuZXNzXCIsIHN0eWxlOiBjb21wdXRlU2VnVlN0eWxlKHZjb29yZHMpIH0sIGZpbGxUeXBlID09PSAnYmctZXZlbnQnID9cbiAgICAgICAgICAgICAgICBjcmVhdGVFbGVtZW50KEJnRXZlbnQsIE9iamVjdC5hc3NpZ24oeyBzZWc6IHNlZyB9LCBnZXRTZWdNZXRhKHNlZywgcHJvcHMudG9kYXlSYW5nZSwgcHJvcHMubm93RGF0ZSkpKSA6XG4gICAgICAgICAgICAgICAgcmVuZGVyRmlsbChmaWxsVHlwZSkpKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBjcmVhdGVFbGVtZW50KEZyYWdtZW50LCBudWxsLCBjaGlsZHJlbik7XG4gICAgfVxuICAgIHJlbmRlck5vd0luZGljYXRvcihzZWdzKSB7XG4gICAgICAgIGxldCB7IHNsYXRDb29yZHMsIGRhdGUgfSA9IHRoaXMucHJvcHM7XG4gICAgICAgIGlmICghc2xhdENvb3Jkcykge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHNlZ3MubWFwKChzZWcsIGkpID0+IChjcmVhdGVFbGVtZW50KE5vd0luZGljYXRvckNvbnRhaW5lclxuICAgICAgICAvLyBrZXkgZG9lc24ndCBtYXR0ZXIuIHdpbGwgb25seSBldmVyIGJlIG9uZVxuICAgICAgICAsIHsgXG4gICAgICAgICAgICAvLyBrZXkgZG9lc24ndCBtYXR0ZXIuIHdpbGwgb25seSBldmVyIGJlIG9uZVxuICAgICAgICAgICAga2V5OiBpLCBlbENsYXNzZXM6IFsnZmMtdGltZWdyaWQtbm93LWluZGljYXRvci1saW5lJ10sIGVsU3R5bGU6IHtcbiAgICAgICAgICAgICAgICB0b3A6IHNsYXRDb29yZHMuY29tcHV0ZURhdGVUb3Aoc2VnLnN0YXJ0LCBkYXRlKSxcbiAgICAgICAgICAgIH0sIGlzQXhpczogZmFsc2UsIGRhdGU6IGRhdGUgfSkpKTtcbiAgICB9XG4gICAgY29tcHV0ZVNlZ0hTdHlsZShzZWdIQ29vcmRzKSB7XG4gICAgICAgIGxldCB7IGlzUnRsLCBvcHRpb25zIH0gPSB0aGlzLmNvbnRleHQ7XG4gICAgICAgIGxldCBzaG91bGRPdmVybGFwID0gb3B0aW9ucy5zbG90RXZlbnRPdmVybGFwO1xuICAgICAgICBsZXQgbmVhckNvb3JkID0gc2VnSENvb3Jkcy5sZXZlbENvb3JkOyAvLyB0aGUgbGVmdCBzaWRlIGlmIExUUi4gdGhlIHJpZ2h0IHNpZGUgaWYgUlRMLiBmbG9hdGluZy1wb2ludFxuICAgICAgICBsZXQgZmFyQ29vcmQgPSBzZWdIQ29vcmRzLmxldmVsQ29vcmQgKyBzZWdIQ29vcmRzLnRoaWNrbmVzczsgLy8gdGhlIHJpZ2h0IHNpZGUgaWYgTFRSLiB0aGUgbGVmdCBzaWRlIGlmIFJUTC4gZmxvYXRpbmctcG9pbnRcbiAgICAgICAgbGV0IGxlZnQ7IC8vIGFtb3VudCBvZiBzcGFjZSBmcm9tIGxlZnQgZWRnZSwgYSBmcmFjdGlvbiBvZiB0aGUgdG90YWwgd2lkdGhcbiAgICAgICAgbGV0IHJpZ2h0OyAvLyBhbW91bnQgb2Ygc3BhY2UgZnJvbSByaWdodCBlZGdlLCBhIGZyYWN0aW9uIG9mIHRoZSB0b3RhbCB3aWR0aFxuICAgICAgICBpZiAoc2hvdWxkT3ZlcmxhcCkge1xuICAgICAgICAgICAgLy8gZG91YmxlIHRoZSB3aWR0aCwgYnV0IGRvbid0IGdvIGJleW9uZCB0aGUgbWF4aW11bSBmb3J3YXJkIGNvb3JkaW5hdGUgKDEuMClcbiAgICAgICAgICAgIGZhckNvb3JkID0gTWF0aC5taW4oMSwgbmVhckNvb3JkICsgKGZhckNvb3JkIC0gbmVhckNvb3JkKSAqIDIpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpc1J0bCkge1xuICAgICAgICAgICAgbGVmdCA9IDEgLSBmYXJDb29yZDtcbiAgICAgICAgICAgIHJpZ2h0ID0gbmVhckNvb3JkO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgbGVmdCA9IG5lYXJDb29yZDtcbiAgICAgICAgICAgIHJpZ2h0ID0gMSAtIGZhckNvb3JkO1xuICAgICAgICB9XG4gICAgICAgIGxldCBwcm9wcyA9IHtcbiAgICAgICAgICAgIHpJbmRleDogc2VnSENvb3Jkcy5zdGFja0RlcHRoICsgMSxcbiAgICAgICAgICAgIGxlZnQ6IGxlZnQgKiAxMDAgKyAnJScsXG4gICAgICAgICAgICByaWdodDogcmlnaHQgKiAxMDAgKyAnJScsXG4gICAgICAgIH07XG4gICAgICAgIGlmIChzaG91bGRPdmVybGFwICYmICFzZWdIQ29vcmRzLnN0YWNrRm9yd2FyZCkge1xuICAgICAgICAgICAgLy8gYWRkIHBhZGRpbmcgdG8gdGhlIGVkZ2Ugc28gdGhhdCBmb3J3YXJkIHN0YWNrZWQgZXZlbnRzIGRvbid0IGNvdmVyIHRoZSByZXNpemVyJ3MgaWNvblxuICAgICAgICAgICAgcHJvcHNbaXNSdGwgPyAnbWFyZ2luTGVmdCcgOiAnbWFyZ2luUmlnaHQnXSA9IDEwICogMjsgLy8gMTAgaXMgYSBndWVzc3RpbWF0ZSBvZiB0aGUgaWNvbidzIHdpZHRoXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHByb3BzO1xuICAgIH1cbn1cbmZ1bmN0aW9uIHJlbmRlclBsYWluRmdTZWdzKHNvcnRlZEZnU2VncywgeyB0b2RheVJhbmdlLCBub3dEYXRlLCBldmVudFNlbGVjdGlvbiwgZXZlbnREcmFnLCBldmVudFJlc2l6ZSB9KSB7XG4gICAgbGV0IGhpZGRlbkluc3RhbmNlcyA9IChldmVudERyYWcgPyBldmVudERyYWcuYWZmZWN0ZWRJbnN0YW5jZXMgOiBudWxsKSB8fFxuICAgICAgICAoZXZlbnRSZXNpemUgPyBldmVudFJlc2l6ZS5hZmZlY3RlZEluc3RhbmNlcyA6IG51bGwpIHx8XG4gICAgICAgIHt9O1xuICAgIHJldHVybiAoY3JlYXRlRWxlbWVudChGcmFnbWVudCwgbnVsbCwgc29ydGVkRmdTZWdzLm1hcCgoc2VnKSA9PiB7XG4gICAgICAgIGxldCBpbnN0YW5jZUlkID0gc2VnLmV2ZW50UmFuZ2UuaW5zdGFuY2UuaW5zdGFuY2VJZDtcbiAgICAgICAgcmV0dXJuIChjcmVhdGVFbGVtZW50KFwiZGl2XCIsIHsga2V5OiBpbnN0YW5jZUlkLCBzdHlsZTogeyB2aXNpYmlsaXR5OiBoaWRkZW5JbnN0YW5jZXNbaW5zdGFuY2VJZF0gPyAnaGlkZGVuJyA6ICcnIH0gfSxcbiAgICAgICAgICAgIGNyZWF0ZUVsZW1lbnQoVGltZUNvbEV2ZW50LCBPYmplY3QuYXNzaWduKHsgc2VnOiBzZWcsIGlzRHJhZ2dpbmc6IGZhbHNlLCBpc1Jlc2l6aW5nOiBmYWxzZSwgaXNEYXRlU2VsZWN0aW5nOiBmYWxzZSwgaXNTZWxlY3RlZDogaW5zdGFuY2VJZCA9PT0gZXZlbnRTZWxlY3Rpb24sIGlzU2hvcnQ6IGZhbHNlIH0sIGdldFNlZ01ldGEoc2VnLCB0b2RheVJhbmdlLCBub3dEYXRlKSkpKSk7XG4gICAgfSkpKTtcbn1cbmZ1bmN0aW9uIGNvbXB1dGVTZWdWU3R5bGUoc2VnVkNvb3Jkcykge1xuICAgIGlmICghc2VnVkNvb3Jkcykge1xuICAgICAgICByZXR1cm4geyB0b3A6ICcnLCBib3R0b206ICcnIH07XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICAgIHRvcDogc2VnVkNvb3Jkcy5zdGFydCxcbiAgICAgICAgYm90dG9tOiAtc2VnVkNvb3Jkcy5lbmQsXG4gICAgfTtcbn1cbmZ1bmN0aW9uIGNvbXBpbGVTZWdzRnJvbUVudHJpZXMoc2VnRW50cmllcywgYWxsU2Vncykge1xuICAgIHJldHVybiBzZWdFbnRyaWVzLm1hcCgoc2VnRW50cnkpID0+IGFsbFNlZ3Nbc2VnRW50cnkuaW5kZXhdKTtcbn1cblxuY2xhc3MgVGltZUNvbHNDb250ZW50IGV4dGVuZHMgQmFzZUNvbXBvbmVudCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMuc3BsaXRGZ0V2ZW50U2VncyA9IG1lbW9pemUoc3BsaXRTZWdzQnlDb2wpO1xuICAgICAgICB0aGlzLnNwbGl0QmdFdmVudFNlZ3MgPSBtZW1vaXplKHNwbGl0U2Vnc0J5Q29sKTtcbiAgICAgICAgdGhpcy5zcGxpdEJ1c2luZXNzSG91clNlZ3MgPSBtZW1vaXplKHNwbGl0U2Vnc0J5Q29sKTtcbiAgICAgICAgdGhpcy5zcGxpdE5vd0luZGljYXRvclNlZ3MgPSBtZW1vaXplKHNwbGl0U2Vnc0J5Q29sKTtcbiAgICAgICAgdGhpcy5zcGxpdERhdGVTZWxlY3Rpb25TZWdzID0gbWVtb2l6ZShzcGxpdFNlZ3NCeUNvbCk7XG4gICAgICAgIHRoaXMuc3BsaXRFdmVudERyYWcgPSBtZW1vaXplKHNwbGl0SW50ZXJhY3Rpb25CeUNvbCk7XG4gICAgICAgIHRoaXMuc3BsaXRFdmVudFJlc2l6ZSA9IG1lbW9pemUoc3BsaXRJbnRlcmFjdGlvbkJ5Q29sKTtcbiAgICAgICAgdGhpcy5yb290RWxSZWYgPSBjcmVhdGVSZWYoKTtcbiAgICAgICAgdGhpcy5jZWxsRWxSZWZzID0gbmV3IFJlZk1hcCgpO1xuICAgIH1cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGxldCB7IHByb3BzLCBjb250ZXh0IH0gPSB0aGlzO1xuICAgICAgICBsZXQgbm93SW5kaWNhdG9yVG9wID0gY29udGV4dC5vcHRpb25zLm5vd0luZGljYXRvciAmJlxuICAgICAgICAgICAgcHJvcHMuc2xhdENvb3JkcyAmJlxuICAgICAgICAgICAgcHJvcHMuc2xhdENvb3Jkcy5zYWZlQ29tcHV0ZVRvcChwcm9wcy5ub3dEYXRlKTsgLy8gbWlnaHQgcmV0dXJuIHZvaWRcbiAgICAgICAgbGV0IGNvbENudCA9IHByb3BzLmNlbGxzLmxlbmd0aDtcbiAgICAgICAgbGV0IGZnRXZlbnRTZWdzQnlSb3cgPSB0aGlzLnNwbGl0RmdFdmVudFNlZ3MocHJvcHMuZmdFdmVudFNlZ3MsIGNvbENudCk7XG4gICAgICAgIGxldCBiZ0V2ZW50U2Vnc0J5Um93ID0gdGhpcy5zcGxpdEJnRXZlbnRTZWdzKHByb3BzLmJnRXZlbnRTZWdzLCBjb2xDbnQpO1xuICAgICAgICBsZXQgYnVzaW5lc3NIb3VyU2Vnc0J5Um93ID0gdGhpcy5zcGxpdEJ1c2luZXNzSG91clNlZ3MocHJvcHMuYnVzaW5lc3NIb3VyU2VncywgY29sQ250KTtcbiAgICAgICAgbGV0IG5vd0luZGljYXRvclNlZ3NCeVJvdyA9IHRoaXMuc3BsaXROb3dJbmRpY2F0b3JTZWdzKHByb3BzLm5vd0luZGljYXRvclNlZ3MsIGNvbENudCk7XG4gICAgICAgIGxldCBkYXRlU2VsZWN0aW9uU2Vnc0J5Um93ID0gdGhpcy5zcGxpdERhdGVTZWxlY3Rpb25TZWdzKHByb3BzLmRhdGVTZWxlY3Rpb25TZWdzLCBjb2xDbnQpO1xuICAgICAgICBsZXQgZXZlbnREcmFnQnlSb3cgPSB0aGlzLnNwbGl0RXZlbnREcmFnKHByb3BzLmV2ZW50RHJhZywgY29sQ250KTtcbiAgICAgICAgbGV0IGV2ZW50UmVzaXplQnlSb3cgPSB0aGlzLnNwbGl0RXZlbnRSZXNpemUocHJvcHMuZXZlbnRSZXNpemUsIGNvbENudCk7XG4gICAgICAgIHJldHVybiAoY3JlYXRlRWxlbWVudChcImRpdlwiLCB7IGNsYXNzTmFtZTogXCJmYy10aW1lZ3JpZC1jb2xzXCIsIHJlZjogdGhpcy5yb290RWxSZWYgfSxcbiAgICAgICAgICAgIGNyZWF0ZUVsZW1lbnQoXCJ0YWJsZVwiLCB7IHJvbGU6IFwicHJlc2VudGF0aW9uXCIsIHN0eWxlOiB7XG4gICAgICAgICAgICAgICAgICAgIG1pbldpZHRoOiBwcm9wcy50YWJsZU1pbldpZHRoLFxuICAgICAgICAgICAgICAgICAgICB3aWR0aDogcHJvcHMuY2xpZW50V2lkdGgsXG4gICAgICAgICAgICAgICAgfSB9LFxuICAgICAgICAgICAgICAgIHByb3BzLnRhYmxlQ29sR3JvdXBOb2RlLFxuICAgICAgICAgICAgICAgIGNyZWF0ZUVsZW1lbnQoXCJ0Ym9keVwiLCB7IHJvbGU6IFwicHJlc2VudGF0aW9uXCIgfSxcbiAgICAgICAgICAgICAgICAgICAgY3JlYXRlRWxlbWVudChcInRyXCIsIHsgcm9sZTogXCJyb3dcIiB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgcHJvcHMuYXhpcyAmJiAoY3JlYXRlRWxlbWVudChcInRkXCIsIHsgXCJhcmlhLWhpZGRlblwiOiB0cnVlLCBjbGFzc05hbWU6IFwiZmMtdGltZWdyaWQtY29sIGZjLXRpbWVncmlkLWF4aXNcIiB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwgeyBjbGFzc05hbWU6IFwiZmMtdGltZWdyaWQtY29sLWZyYW1lXCIgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlRWxlbWVudChcImRpdlwiLCB7IGNsYXNzTmFtZTogXCJmYy10aW1lZ3JpZC1ub3ctaW5kaWNhdG9yLWNvbnRhaW5lclwiIH0sIHR5cGVvZiBub3dJbmRpY2F0b3JUb3AgPT09ICdudW1iZXInICYmIChjcmVhdGVFbGVtZW50KE5vd0luZGljYXRvckNvbnRhaW5lciwgeyBlbENsYXNzZXM6IFsnZmMtdGltZWdyaWQtbm93LWluZGljYXRvci1hcnJvdyddLCBlbFN0eWxlOiB7IHRvcDogbm93SW5kaWNhdG9yVG9wIH0sIGlzQXhpczogdHJ1ZSwgZGF0ZTogcHJvcHMubm93RGF0ZSB9KSkpKSkpLFxuICAgICAgICAgICAgICAgICAgICAgICAgcHJvcHMuY2VsbHMubWFwKChjZWxsLCBpKSA9PiAoY3JlYXRlRWxlbWVudChUaW1lQ29sLCB7IGtleTogY2VsbC5rZXksIGVsUmVmOiB0aGlzLmNlbGxFbFJlZnMuY3JlYXRlUmVmKGNlbGwua2V5KSwgZGF0ZVByb2ZpbGU6IHByb3BzLmRhdGVQcm9maWxlLCBkYXRlOiBjZWxsLmRhdGUsIG5vd0RhdGU6IHByb3BzLm5vd0RhdGUsIHRvZGF5UmFuZ2U6IHByb3BzLnRvZGF5UmFuZ2UsIGV4dHJhUmVuZGVyUHJvcHM6IGNlbGwuZXh0cmFSZW5kZXJQcm9wcywgZXh0cmFEYXRhQXR0cnM6IGNlbGwuZXh0cmFEYXRhQXR0cnMsIGV4dHJhQ2xhc3NOYW1lczogY2VsbC5leHRyYUNsYXNzTmFtZXMsIGV4dHJhRGF0ZVNwYW46IGNlbGwuZXh0cmFEYXRlU3BhbiwgZmdFdmVudFNlZ3M6IGZnRXZlbnRTZWdzQnlSb3dbaV0sIGJnRXZlbnRTZWdzOiBiZ0V2ZW50U2Vnc0J5Um93W2ldLCBidXNpbmVzc0hvdXJTZWdzOiBidXNpbmVzc0hvdXJTZWdzQnlSb3dbaV0sIG5vd0luZGljYXRvclNlZ3M6IG5vd0luZGljYXRvclNlZ3NCeVJvd1tpXSwgZGF0ZVNlbGVjdGlvblNlZ3M6IGRhdGVTZWxlY3Rpb25TZWdzQnlSb3dbaV0sIGV2ZW50RHJhZzogZXZlbnREcmFnQnlSb3dbaV0sIGV2ZW50UmVzaXplOiBldmVudFJlc2l6ZUJ5Um93W2ldLCBzbGF0Q29vcmRzOiBwcm9wcy5zbGF0Q29vcmRzLCBldmVudFNlbGVjdGlvbjogcHJvcHMuZXZlbnRTZWxlY3Rpb24sIGZvclByaW50OiBwcm9wcy5mb3JQcmludCB9KSkpKSkpKSk7XG4gICAgfVxuICAgIGNvbXBvbmVudERpZE1vdW50KCkge1xuICAgICAgICB0aGlzLnVwZGF0ZUNvb3JkcygpO1xuICAgIH1cbiAgICBjb21wb25lbnREaWRVcGRhdGUoKSB7XG4gICAgICAgIHRoaXMudXBkYXRlQ29vcmRzKCk7XG4gICAgfVxuICAgIHVwZGF0ZUNvb3JkcygpIHtcbiAgICAgICAgbGV0IHsgcHJvcHMgfSA9IHRoaXM7XG4gICAgICAgIGlmIChwcm9wcy5vbkNvbENvb3JkcyAmJlxuICAgICAgICAgICAgcHJvcHMuY2xpZW50V2lkdGggIT09IG51bGwgLy8gbWVhbnMgc2l6aW5nIGhhcyBzdGFiaWxpemVkXG4gICAgICAgICkge1xuICAgICAgICAgICAgcHJvcHMub25Db2xDb29yZHMobmV3IFBvc2l0aW9uQ2FjaGUodGhpcy5yb290RWxSZWYuY3VycmVudCwgY29sbGVjdENlbGxFbHModGhpcy5jZWxsRWxSZWZzLmN1cnJlbnRNYXAsIHByb3BzLmNlbGxzKSwgdHJ1ZSwgLy8gaG9yaXpvbnRhbFxuICAgICAgICAgICAgZmFsc2UpKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbmZ1bmN0aW9uIGNvbGxlY3RDZWxsRWxzKGVsTWFwLCBjZWxscykge1xuICAgIHJldHVybiBjZWxscy5tYXAoKGNlbGwpID0+IGVsTWFwW2NlbGwua2V5XSk7XG59XG5cbi8qIEEgY29tcG9uZW50IHRoYXQgcmVuZGVycyBvbmUgb3IgbW9yZSBjb2x1bW5zIG9mIHZlcnRpY2FsIHRpbWUgc2xvdHNcbi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuY2xhc3MgVGltZUNvbHMgZXh0ZW5kcyBEYXRlQ29tcG9uZW50IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5wcm9jZXNzU2xvdE9wdGlvbnMgPSBtZW1vaXplKHByb2Nlc3NTbG90T3B0aW9ucyk7XG4gICAgICAgIHRoaXMuc3RhdGUgPSB7XG4gICAgICAgICAgICBzbGF0Q29vcmRzOiBudWxsLFxuICAgICAgICB9O1xuICAgICAgICB0aGlzLmhhbmRsZVJvb3RFbCA9IChlbCkgPT4ge1xuICAgICAgICAgICAgaWYgKGVsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jb250ZXh0LnJlZ2lzdGVySW50ZXJhY3RpdmVDb21wb25lbnQodGhpcywge1xuICAgICAgICAgICAgICAgICAgICBlbCxcbiAgICAgICAgICAgICAgICAgICAgaXNIaXRDb21ib0FsbG93ZWQ6IHRoaXMucHJvcHMuaXNIaXRDb21ib0FsbG93ZWQsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbnRleHQudW5yZWdpc3RlckludGVyYWN0aXZlQ29tcG9uZW50KHRoaXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICB0aGlzLmhhbmRsZVNjcm9sbFJlcXVlc3QgPSAocmVxdWVzdCkgPT4ge1xuICAgICAgICAgICAgbGV0IHsgb25TY3JvbGxUb3BSZXF1ZXN0IH0gPSB0aGlzLnByb3BzO1xuICAgICAgICAgICAgbGV0IHsgc2xhdENvb3JkcyB9ID0gdGhpcy5zdGF0ZTtcbiAgICAgICAgICAgIGlmIChvblNjcm9sbFRvcFJlcXVlc3QgJiYgc2xhdENvb3Jkcykge1xuICAgICAgICAgICAgICAgIGlmIChyZXF1ZXN0LnRpbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IHRvcCA9IHNsYXRDb29yZHMuY29tcHV0ZVRpbWVUb3AocmVxdWVzdC50aW1lKTtcbiAgICAgICAgICAgICAgICAgICAgdG9wID0gTWF0aC5jZWlsKHRvcCk7IC8vIHpvb20gY2FuIGdpdmUgd2VpcmQgZmxvYXRpbmctcG9pbnQgdmFsdWVzLiByYXRoZXIgc2Nyb2xsIGEgbGl0dGxlIGJpdCBmdXJ0aGVyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0b3ApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvcCArPSAxOyAvLyB0byBvdmVyY29tZSB0b3AgYm9yZGVyIHRoYXQgc2xvdHMgYmV5b25kIHRoZSBmaXJzdCBoYXZlLiBsb29rcyBiZXR0ZXJcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBvblNjcm9sbFRvcFJlcXVlc3QodG9wKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuaGFuZGxlQ29sQ29vcmRzID0gKGNvbENvb3JkcykgPT4ge1xuICAgICAgICAgICAgdGhpcy5jb2xDb29yZHMgPSBjb2xDb29yZHM7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuaGFuZGxlU2xhdENvb3JkcyA9IChzbGF0Q29vcmRzKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgc2xhdENvb3JkcyB9KTtcbiAgICAgICAgICAgIGlmICh0aGlzLnByb3BzLm9uU2xhdENvb3Jkcykge1xuICAgICAgICAgICAgICAgIHRoaXMucHJvcHMub25TbGF0Q29vcmRzKHNsYXRDb29yZHMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH1cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGxldCB7IHByb3BzLCBzdGF0ZSB9ID0gdGhpcztcbiAgICAgICAgcmV0dXJuIChjcmVhdGVFbGVtZW50KFwiZGl2XCIsIHsgY2xhc3NOYW1lOiBcImZjLXRpbWVncmlkLWJvZHlcIiwgcmVmOiB0aGlzLmhhbmRsZVJvb3RFbCwgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAvLyB0aGVzZSBwcm9wcyBhcmUgaW1wb3J0YW50IHRvIGdpdmUgdGhpcyB3cmFwcGVyIGNvcnJlY3QgZGltZW5zaW9ucyBmb3IgaW50ZXJhY3Rpb25zXG4gICAgICAgICAgICAgICAgLy8gVE9ETzogaWYgd2Ugc2V0IGl0IGhlcmUsIGNhbiB3ZSBhdm9pZCBnaXZpbmcgdG8gaW5uZXIgdGFibGVzP1xuICAgICAgICAgICAgICAgIHdpZHRoOiBwcm9wcy5jbGllbnRXaWR0aCxcbiAgICAgICAgICAgICAgICBtaW5XaWR0aDogcHJvcHMudGFibGVNaW5XaWR0aCxcbiAgICAgICAgICAgIH0gfSxcbiAgICAgICAgICAgIGNyZWF0ZUVsZW1lbnQoVGltZUNvbHNTbGF0cywgeyBheGlzOiBwcm9wcy5heGlzLCBkYXRlUHJvZmlsZTogcHJvcHMuZGF0ZVByb2ZpbGUsIHNsYXRNZXRhczogcHJvcHMuc2xhdE1ldGFzLCBjbGllbnRXaWR0aDogcHJvcHMuY2xpZW50V2lkdGgsIG1pbkhlaWdodDogcHJvcHMuZXhwYW5kUm93cyA/IHByb3BzLmNsaWVudEhlaWdodCA6ICcnLCB0YWJsZU1pbldpZHRoOiBwcm9wcy50YWJsZU1pbldpZHRoLCB0YWJsZUNvbEdyb3VwTm9kZTogcHJvcHMuYXhpcyA/IHByb3BzLnRhYmxlQ29sR3JvdXBOb2RlIDogbnVsbCAvKiBheGlzIGRlcGVuZHMgb24gdGhlIGNvbGdyb3VwJ3Mgc2hyaW5raW5nICovLCBvbkNvb3JkczogdGhpcy5oYW5kbGVTbGF0Q29vcmRzIH0pLFxuICAgICAgICAgICAgY3JlYXRlRWxlbWVudChUaW1lQ29sc0NvbnRlbnQsIHsgY2VsbHM6IHByb3BzLmNlbGxzLCBheGlzOiBwcm9wcy5heGlzLCBkYXRlUHJvZmlsZTogcHJvcHMuZGF0ZVByb2ZpbGUsIGJ1c2luZXNzSG91clNlZ3M6IHByb3BzLmJ1c2luZXNzSG91clNlZ3MsIGJnRXZlbnRTZWdzOiBwcm9wcy5iZ0V2ZW50U2VncywgZmdFdmVudFNlZ3M6IHByb3BzLmZnRXZlbnRTZWdzLCBkYXRlU2VsZWN0aW9uU2VnczogcHJvcHMuZGF0ZVNlbGVjdGlvblNlZ3MsIGV2ZW50U2VsZWN0aW9uOiBwcm9wcy5ldmVudFNlbGVjdGlvbiwgZXZlbnREcmFnOiBwcm9wcy5ldmVudERyYWcsIGV2ZW50UmVzaXplOiBwcm9wcy5ldmVudFJlc2l6ZSwgdG9kYXlSYW5nZTogcHJvcHMudG9kYXlSYW5nZSwgbm93RGF0ZTogcHJvcHMubm93RGF0ZSwgbm93SW5kaWNhdG9yU2VnczogcHJvcHMubm93SW5kaWNhdG9yU2VncywgY2xpZW50V2lkdGg6IHByb3BzLmNsaWVudFdpZHRoLCB0YWJsZU1pbldpZHRoOiBwcm9wcy50YWJsZU1pbldpZHRoLCB0YWJsZUNvbEdyb3VwTm9kZTogcHJvcHMudGFibGVDb2xHcm91cE5vZGUsIHNsYXRDb29yZHM6IHN0YXRlLnNsYXRDb29yZHMsIG9uQ29sQ29vcmRzOiB0aGlzLmhhbmRsZUNvbENvb3JkcywgZm9yUHJpbnQ6IHByb3BzLmZvclByaW50IH0pKSk7XG4gICAgfVxuICAgIGNvbXBvbmVudERpZE1vdW50KCkge1xuICAgICAgICB0aGlzLnNjcm9sbFJlc3BvbmRlciA9IHRoaXMuY29udGV4dC5jcmVhdGVTY3JvbGxSZXNwb25kZXIodGhpcy5oYW5kbGVTY3JvbGxSZXF1ZXN0KTtcbiAgICB9XG4gICAgY29tcG9uZW50RGlkVXBkYXRlKHByZXZQcm9wcykge1xuICAgICAgICB0aGlzLnNjcm9sbFJlc3BvbmRlci51cGRhdGUocHJldlByb3BzLmRhdGVQcm9maWxlICE9PSB0aGlzLnByb3BzLmRhdGVQcm9maWxlKTtcbiAgICB9XG4gICAgY29tcG9uZW50V2lsbFVubW91bnQoKSB7XG4gICAgICAgIHRoaXMuc2Nyb2xsUmVzcG9uZGVyLmRldGFjaCgpO1xuICAgIH1cbiAgICBxdWVyeUhpdChwb3NpdGlvbkxlZnQsIHBvc2l0aW9uVG9wKSB7XG4gICAgICAgIGxldCB7IGRhdGVFbnYsIG9wdGlvbnMgfSA9IHRoaXMuY29udGV4dDtcbiAgICAgICAgbGV0IHsgY29sQ29vcmRzIH0gPSB0aGlzO1xuICAgICAgICBsZXQgeyBkYXRlUHJvZmlsZSB9ID0gdGhpcy5wcm9wcztcbiAgICAgICAgbGV0IHsgc2xhdENvb3JkcyB9ID0gdGhpcy5zdGF0ZTtcbiAgICAgICAgbGV0IHsgc25hcER1cmF0aW9uLCBzbmFwc1BlclNsb3QgfSA9IHRoaXMucHJvY2Vzc1Nsb3RPcHRpb25zKHRoaXMucHJvcHMuc2xvdER1cmF0aW9uLCBvcHRpb25zLnNuYXBEdXJhdGlvbik7XG4gICAgICAgIGxldCBjb2xJbmRleCA9IGNvbENvb3Jkcy5sZWZ0VG9JbmRleChwb3NpdGlvbkxlZnQpO1xuICAgICAgICBsZXQgc2xhdEluZGV4ID0gc2xhdENvb3Jkcy5wb3NpdGlvbnMudG9wVG9JbmRleChwb3NpdGlvblRvcCk7XG4gICAgICAgIGlmIChjb2xJbmRleCAhPSBudWxsICYmIHNsYXRJbmRleCAhPSBudWxsKSB7XG4gICAgICAgICAgICBsZXQgY2VsbCA9IHRoaXMucHJvcHMuY2VsbHNbY29sSW5kZXhdO1xuICAgICAgICAgICAgbGV0IHNsYXRUb3AgPSBzbGF0Q29vcmRzLnBvc2l0aW9ucy50b3BzW3NsYXRJbmRleF07XG4gICAgICAgICAgICBsZXQgc2xhdEhlaWdodCA9IHNsYXRDb29yZHMucG9zaXRpb25zLmdldEhlaWdodChzbGF0SW5kZXgpO1xuICAgICAgICAgICAgbGV0IHBhcnRpYWwgPSAocG9zaXRpb25Ub3AgLSBzbGF0VG9wKSAvIHNsYXRIZWlnaHQ7IC8vIGZsb2F0aW5nIHBvaW50IG51bWJlciBiZXR3ZWVuIDAgYW5kIDFcbiAgICAgICAgICAgIGxldCBsb2NhbFNuYXBJbmRleCA9IE1hdGguZmxvb3IocGFydGlhbCAqIHNuYXBzUGVyU2xvdCk7IC8vIHRoZSBzbmFwICMgcmVsYXRpdmUgdG8gc3RhcnQgb2Ygc2xhdFxuICAgICAgICAgICAgbGV0IHNuYXBJbmRleCA9IHNsYXRJbmRleCAqIHNuYXBzUGVyU2xvdCArIGxvY2FsU25hcEluZGV4O1xuICAgICAgICAgICAgbGV0IGRheURhdGUgPSB0aGlzLnByb3BzLmNlbGxzW2NvbEluZGV4XS5kYXRlO1xuICAgICAgICAgICAgbGV0IHRpbWUgPSBhZGREdXJhdGlvbnMoZGF0ZVByb2ZpbGUuc2xvdE1pblRpbWUsIG11bHRpcGx5RHVyYXRpb24oc25hcER1cmF0aW9uLCBzbmFwSW5kZXgpKTtcbiAgICAgICAgICAgIGxldCBzdGFydCA9IGRhdGVFbnYuYWRkKGRheURhdGUsIHRpbWUpO1xuICAgICAgICAgICAgbGV0IGVuZCA9IGRhdGVFbnYuYWRkKHN0YXJ0LCBzbmFwRHVyYXRpb24pO1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBkYXRlUHJvZmlsZSxcbiAgICAgICAgICAgICAgICBkYXRlU3BhbjogT2JqZWN0LmFzc2lnbih7IHJhbmdlOiB7IHN0YXJ0LCBlbmQgfSwgYWxsRGF5OiBmYWxzZSB9LCBjZWxsLmV4dHJhRGF0ZVNwYW4pLFxuICAgICAgICAgICAgICAgIGRheUVsOiBjb2xDb29yZHMuZWxzW2NvbEluZGV4XSxcbiAgICAgICAgICAgICAgICByZWN0OiB7XG4gICAgICAgICAgICAgICAgICAgIGxlZnQ6IGNvbENvb3Jkcy5sZWZ0c1tjb2xJbmRleF0sXG4gICAgICAgICAgICAgICAgICAgIHJpZ2h0OiBjb2xDb29yZHMucmlnaHRzW2NvbEluZGV4XSxcbiAgICAgICAgICAgICAgICAgICAgdG9wOiBzbGF0VG9wLFxuICAgICAgICAgICAgICAgICAgICBib3R0b206IHNsYXRUb3AgKyBzbGF0SGVpZ2h0LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgbGF5ZXI6IDAsXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbn1cbmZ1bmN0aW9uIHByb2Nlc3NTbG90T3B0aW9ucyhzbG90RHVyYXRpb24sIHNuYXBEdXJhdGlvbk92ZXJyaWRlKSB7XG4gICAgbGV0IHNuYXBEdXJhdGlvbiA9IHNuYXBEdXJhdGlvbk92ZXJyaWRlIHx8IHNsb3REdXJhdGlvbjtcbiAgICBsZXQgc25hcHNQZXJTbG90ID0gd2hvbGVEaXZpZGVEdXJhdGlvbnMoc2xvdER1cmF0aW9uLCBzbmFwRHVyYXRpb24pO1xuICAgIGlmIChzbmFwc1BlclNsb3QgPT09IG51bGwpIHtcbiAgICAgICAgc25hcER1cmF0aW9uID0gc2xvdER1cmF0aW9uO1xuICAgICAgICBzbmFwc1BlclNsb3QgPSAxO1xuICAgICAgICAvLyBUT0RPOiBzYXkgd2FybmluZz9cbiAgICB9XG4gICAgcmV0dXJuIHsgc25hcER1cmF0aW9uLCBzbmFwc1BlclNsb3QgfTtcbn1cblxuY2xhc3MgRGF5VGltZUNvbHNTbGljZXIgZXh0ZW5kcyBTbGljZXIge1xuICAgIHNsaWNlUmFuZ2UocmFuZ2UsIGRheVJhbmdlcykge1xuICAgICAgICBsZXQgc2VncyA9IFtdO1xuICAgICAgICBmb3IgKGxldCBjb2wgPSAwOyBjb2wgPCBkYXlSYW5nZXMubGVuZ3RoOyBjb2wgKz0gMSkge1xuICAgICAgICAgICAgbGV0IHNlZ1JhbmdlID0gaW50ZXJzZWN0UmFuZ2VzKHJhbmdlLCBkYXlSYW5nZXNbY29sXSk7XG4gICAgICAgICAgICBpZiAoc2VnUmFuZ2UpIHtcbiAgICAgICAgICAgICAgICBzZWdzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICBzdGFydDogc2VnUmFuZ2Uuc3RhcnQsXG4gICAgICAgICAgICAgICAgICAgIGVuZDogc2VnUmFuZ2UuZW5kLFxuICAgICAgICAgICAgICAgICAgICBpc1N0YXJ0OiBzZWdSYW5nZS5zdGFydC52YWx1ZU9mKCkgPT09IHJhbmdlLnN0YXJ0LnZhbHVlT2YoKSxcbiAgICAgICAgICAgICAgICAgICAgaXNFbmQ6IHNlZ1JhbmdlLmVuZC52YWx1ZU9mKCkgPT09IHJhbmdlLmVuZC52YWx1ZU9mKCksXG4gICAgICAgICAgICAgICAgICAgIGNvbCxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gc2VncztcbiAgICB9XG59XG5cbmNsYXNzIERheVRpbWVDb2xzIGV4dGVuZHMgRGF0ZUNvbXBvbmVudCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMuYnVpbGREYXlSYW5nZXMgPSBtZW1vaXplKGJ1aWxkRGF5UmFuZ2VzKTtcbiAgICAgICAgdGhpcy5zbGljZXIgPSBuZXcgRGF5VGltZUNvbHNTbGljZXIoKTtcbiAgICAgICAgdGhpcy50aW1lQ29sc1JlZiA9IGNyZWF0ZVJlZigpO1xuICAgIH1cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGxldCB7IHByb3BzLCBjb250ZXh0IH0gPSB0aGlzO1xuICAgICAgICBsZXQgeyBkYXRlUHJvZmlsZSwgZGF5VGFibGVNb2RlbCB9ID0gcHJvcHM7XG4gICAgICAgIGxldCBpc05vd0luZGljYXRvciA9IGNvbnRleHQub3B0aW9ucy5ub3dJbmRpY2F0b3I7XG4gICAgICAgIGxldCBkYXlSYW5nZXMgPSB0aGlzLmJ1aWxkRGF5UmFuZ2VzKGRheVRhYmxlTW9kZWwsIGRhdGVQcm9maWxlLCBjb250ZXh0LmRhdGVFbnYpO1xuICAgICAgICAvLyBnaXZlIGl0IHRoZSBmaXJzdCByb3cgb2YgY2VsbHNcbiAgICAgICAgLy8gVE9ETzogd291bGQgbW92ZSB0aGlzIGZ1cnRoZXIgZG93biBoaWVyYXJjaHksIGJ1dCBzbGljZU5vd0RhdGUgbmVlZHMgaXRcbiAgICAgICAgcmV0dXJuIChjcmVhdGVFbGVtZW50KE5vd1RpbWVyLCB7IHVuaXQ6IGlzTm93SW5kaWNhdG9yID8gJ21pbnV0ZScgOiAnZGF5JyB9LCAobm93RGF0ZSwgdG9kYXlSYW5nZSkgPT4gKGNyZWF0ZUVsZW1lbnQoVGltZUNvbHMsIE9iamVjdC5hc3NpZ24oeyByZWY6IHRoaXMudGltZUNvbHNSZWYgfSwgdGhpcy5zbGljZXIuc2xpY2VQcm9wcyhwcm9wcywgZGF0ZVByb2ZpbGUsIG51bGwsIGNvbnRleHQsIGRheVJhbmdlcyksIHsgZm9yUHJpbnQ6IHByb3BzLmZvclByaW50LCBheGlzOiBwcm9wcy5heGlzLCBkYXRlUHJvZmlsZTogZGF0ZVByb2ZpbGUsIHNsYXRNZXRhczogcHJvcHMuc2xhdE1ldGFzLCBzbG90RHVyYXRpb246IHByb3BzLnNsb3REdXJhdGlvbiwgY2VsbHM6IGRheVRhYmxlTW9kZWwuY2VsbHNbMF0sIHRhYmxlQ29sR3JvdXBOb2RlOiBwcm9wcy50YWJsZUNvbEdyb3VwTm9kZSwgdGFibGVNaW5XaWR0aDogcHJvcHMudGFibGVNaW5XaWR0aCwgY2xpZW50V2lkdGg6IHByb3BzLmNsaWVudFdpZHRoLCBjbGllbnRIZWlnaHQ6IHByb3BzLmNsaWVudEhlaWdodCwgZXhwYW5kUm93czogcHJvcHMuZXhwYW5kUm93cywgbm93RGF0ZTogbm93RGF0ZSwgbm93SW5kaWNhdG9yU2VnczogaXNOb3dJbmRpY2F0b3IgJiYgdGhpcy5zbGljZXIuc2xpY2VOb3dEYXRlKG5vd0RhdGUsIGNvbnRleHQsIGRheVJhbmdlcyksIHRvZGF5UmFuZ2U6IHRvZGF5UmFuZ2UsIG9uU2Nyb2xsVG9wUmVxdWVzdDogcHJvcHMub25TY3JvbGxUb3BSZXF1ZXN0LCBvblNsYXRDb29yZHM6IHByb3BzLm9uU2xhdENvb3JkcyB9KSkpKSk7XG4gICAgfVxufVxuZnVuY3Rpb24gYnVpbGREYXlSYW5nZXMoZGF5VGFibGVNb2RlbCwgZGF0ZVByb2ZpbGUsIGRhdGVFbnYpIHtcbiAgICBsZXQgcmFuZ2VzID0gW107XG4gICAgZm9yIChsZXQgZGF0ZSBvZiBkYXlUYWJsZU1vZGVsLmhlYWRlckRhdGVzKSB7XG4gICAgICAgIHJhbmdlcy5wdXNoKHtcbiAgICAgICAgICAgIHN0YXJ0OiBkYXRlRW52LmFkZChkYXRlLCBkYXRlUHJvZmlsZS5zbG90TWluVGltZSksXG4gICAgICAgICAgICBlbmQ6IGRhdGVFbnYuYWRkKGRhdGUsIGRhdGVQcm9maWxlLnNsb3RNYXhUaW1lKSxcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiByYW5nZXM7XG59XG5cbi8vIHBvdGVudGlhbCBuaWNlIHZhbHVlcyBmb3IgdGhlIHNsb3QtZHVyYXRpb24gYW5kIGludGVydmFsLWR1cmF0aW9uXG4vLyBmcm9tIGxhcmdlc3QgdG8gc21hbGxlc3RcbmNvbnN0IFNUT0NLX1NVQl9EVVJBVElPTlMgPSBbXG4gICAgeyBob3VyczogMSB9LFxuICAgIHsgbWludXRlczogMzAgfSxcbiAgICB7IG1pbnV0ZXM6IDE1IH0sXG4gICAgeyBzZWNvbmRzOiAzMCB9LFxuICAgIHsgc2Vjb25kczogMTUgfSxcbl07XG5mdW5jdGlvbiBidWlsZFNsYXRNZXRhcyhzbG90TWluVGltZSwgc2xvdE1heFRpbWUsIGV4cGxpY2l0TGFiZWxJbnRlcnZhbCwgc2xvdER1cmF0aW9uLCBkYXRlRW52KSB7XG4gICAgbGV0IGRheVN0YXJ0ID0gbmV3IERhdGUoMCk7XG4gICAgbGV0IHNsYXRUaW1lID0gc2xvdE1pblRpbWU7XG4gICAgbGV0IHNsYXRJdGVyYXRvciA9IGNyZWF0ZUR1cmF0aW9uKDApO1xuICAgIGxldCBsYWJlbEludGVydmFsID0gZXhwbGljaXRMYWJlbEludGVydmFsIHx8IGNvbXB1dGVMYWJlbEludGVydmFsKHNsb3REdXJhdGlvbik7XG4gICAgbGV0IG1ldGFzID0gW107XG4gICAgd2hpbGUgKGFzUm91Z2hNcyhzbGF0VGltZSkgPCBhc1JvdWdoTXMoc2xvdE1heFRpbWUpKSB7XG4gICAgICAgIGxldCBkYXRlID0gZGF0ZUVudi5hZGQoZGF5U3RhcnQsIHNsYXRUaW1lKTtcbiAgICAgICAgbGV0IGlzTGFiZWxlZCA9IHdob2xlRGl2aWRlRHVyYXRpb25zKHNsYXRJdGVyYXRvciwgbGFiZWxJbnRlcnZhbCkgIT09IG51bGw7XG4gICAgICAgIG1ldGFzLnB1c2goe1xuICAgICAgICAgICAgZGF0ZSxcbiAgICAgICAgICAgIHRpbWU6IHNsYXRUaW1lLFxuICAgICAgICAgICAga2V5OiBkYXRlLnRvSVNPU3RyaW5nKCksXG4gICAgICAgICAgICBpc29UaW1lU3RyOiBmb3JtYXRJc29UaW1lU3RyaW5nKGRhdGUpLFxuICAgICAgICAgICAgaXNMYWJlbGVkLFxuICAgICAgICB9KTtcbiAgICAgICAgc2xhdFRpbWUgPSBhZGREdXJhdGlvbnMoc2xhdFRpbWUsIHNsb3REdXJhdGlvbik7XG4gICAgICAgIHNsYXRJdGVyYXRvciA9IGFkZER1cmF0aW9ucyhzbGF0SXRlcmF0b3IsIHNsb3REdXJhdGlvbik7XG4gICAgfVxuICAgIHJldHVybiBtZXRhcztcbn1cbi8vIENvbXB1dGVzIGFuIGF1dG9tYXRpYyB2YWx1ZSBmb3Igc2xvdExhYmVsSW50ZXJ2YWxcbmZ1bmN0aW9uIGNvbXB1dGVMYWJlbEludGVydmFsKHNsb3REdXJhdGlvbikge1xuICAgIGxldCBpO1xuICAgIGxldCBsYWJlbEludGVydmFsO1xuICAgIGxldCBzbG90c1BlckxhYmVsO1xuICAgIC8vIGZpbmQgdGhlIHNtYWxsZXN0IHN0b2NrIGxhYmVsIGludGVydmFsIHRoYXQgcmVzdWx0cyBpbiBtb3JlIHRoYW4gb25lIHNsb3RzLXBlci1sYWJlbFxuICAgIGZvciAoaSA9IFNUT0NLX1NVQl9EVVJBVElPTlMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpIC09IDEpIHtcbiAgICAgICAgbGFiZWxJbnRlcnZhbCA9IGNyZWF0ZUR1cmF0aW9uKFNUT0NLX1NVQl9EVVJBVElPTlNbaV0pO1xuICAgICAgICBzbG90c1BlckxhYmVsID0gd2hvbGVEaXZpZGVEdXJhdGlvbnMobGFiZWxJbnRlcnZhbCwgc2xvdER1cmF0aW9uKTtcbiAgICAgICAgaWYgKHNsb3RzUGVyTGFiZWwgIT09IG51bGwgJiYgc2xvdHNQZXJMYWJlbCA+IDEpIHtcbiAgICAgICAgICAgIHJldHVybiBsYWJlbEludGVydmFsO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBzbG90RHVyYXRpb247IC8vIGZhbGwgYmFja1xufVxuXG5jbGFzcyBEYXlUaW1lQ29sc1ZpZXcgZXh0ZW5kcyBUaW1lQ29sc1ZpZXcge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLmJ1aWxkVGltZUNvbHNNb2RlbCA9IG1lbW9pemUoYnVpbGRUaW1lQ29sc01vZGVsKTtcbiAgICAgICAgdGhpcy5idWlsZFNsYXRNZXRhcyA9IG1lbW9pemUoYnVpbGRTbGF0TWV0YXMpO1xuICAgIH1cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGxldCB7IG9wdGlvbnMsIGRhdGVFbnYsIGRhdGVQcm9maWxlR2VuZXJhdG9yIH0gPSB0aGlzLmNvbnRleHQ7XG4gICAgICAgIGxldCB7IHByb3BzIH0gPSB0aGlzO1xuICAgICAgICBsZXQgeyBkYXRlUHJvZmlsZSB9ID0gcHJvcHM7XG4gICAgICAgIGxldCBkYXlUYWJsZU1vZGVsID0gdGhpcy5idWlsZFRpbWVDb2xzTW9kZWwoZGF0ZVByb2ZpbGUsIGRhdGVQcm9maWxlR2VuZXJhdG9yKTtcbiAgICAgICAgbGV0IHNwbGl0UHJvcHMgPSB0aGlzLmFsbERheVNwbGl0dGVyLnNwbGl0UHJvcHMocHJvcHMpO1xuICAgICAgICBsZXQgc2xhdE1ldGFzID0gdGhpcy5idWlsZFNsYXRNZXRhcyhkYXRlUHJvZmlsZS5zbG90TWluVGltZSwgZGF0ZVByb2ZpbGUuc2xvdE1heFRpbWUsIG9wdGlvbnMuc2xvdExhYmVsSW50ZXJ2YWwsIG9wdGlvbnMuc2xvdER1cmF0aW9uLCBkYXRlRW52KTtcbiAgICAgICAgbGV0IHsgZGF5TWluV2lkdGggfSA9IG9wdGlvbnM7XG4gICAgICAgIGxldCBoYXNBdHRhY2hlZEF4aXMgPSAhZGF5TWluV2lkdGg7XG4gICAgICAgIGxldCBoYXNEZXRhY2hlZEF4aXMgPSBkYXlNaW5XaWR0aDtcbiAgICAgICAgbGV0IGhlYWRlckNvbnRlbnQgPSBvcHRpb25zLmRheUhlYWRlcnMgJiYgKGNyZWF0ZUVsZW1lbnQoRGF5SGVhZGVyLCB7IGRhdGVzOiBkYXlUYWJsZU1vZGVsLmhlYWRlckRhdGVzLCBkYXRlUHJvZmlsZTogZGF0ZVByb2ZpbGUsIGRhdGVzUmVwRGlzdGluY3REYXlzOiB0cnVlLCByZW5kZXJJbnRybzogaGFzQXR0YWNoZWRBeGlzID8gdGhpcy5yZW5kZXJIZWFkQXhpcyA6IG51bGwgfSkpO1xuICAgICAgICBsZXQgYWxsRGF5Q29udGVudCA9IChvcHRpb25zLmFsbERheVNsb3QgIT09IGZhbHNlKSAmJiAoKGNvbnRlbnRBcmcpID0+IChjcmVhdGVFbGVtZW50KERheVRhYmxlLCBPYmplY3QuYXNzaWduKHt9LCBzcGxpdFByb3BzLmFsbERheSwgeyBkYXRlUHJvZmlsZTogZGF0ZVByb2ZpbGUsIGRheVRhYmxlTW9kZWw6IGRheVRhYmxlTW9kZWwsIG5leHREYXlUaHJlc2hvbGQ6IG9wdGlvbnMubmV4dERheVRocmVzaG9sZCwgdGFibGVNaW5XaWR0aDogY29udGVudEFyZy50YWJsZU1pbldpZHRoLCBjb2xHcm91cE5vZGU6IGNvbnRlbnRBcmcudGFibGVDb2xHcm91cE5vZGUsIHJlbmRlclJvd0ludHJvOiBoYXNBdHRhY2hlZEF4aXMgPyB0aGlzLnJlbmRlclRhYmxlUm93QXhpcyA6IG51bGwsIHNob3dXZWVrTnVtYmVyczogZmFsc2UsIGV4cGFuZFJvd3M6IGZhbHNlLCBoZWFkZXJBbGlnbkVsUmVmOiB0aGlzLmhlYWRlckVsUmVmLCBjbGllbnRXaWR0aDogY29udGVudEFyZy5jbGllbnRXaWR0aCwgY2xpZW50SGVpZ2h0OiBjb250ZW50QXJnLmNsaWVudEhlaWdodCwgZm9yUHJpbnQ6IHByb3BzLmZvclByaW50IH0sIHRoaXMuZ2V0QWxsRGF5TWF4RXZlbnRQcm9wcygpKSkpKTtcbiAgICAgICAgbGV0IHRpbWVHcmlkQ29udGVudCA9IChjb250ZW50QXJnKSA9PiAoY3JlYXRlRWxlbWVudChEYXlUaW1lQ29scywgT2JqZWN0LmFzc2lnbih7fSwgc3BsaXRQcm9wcy50aW1lZCwgeyBkYXlUYWJsZU1vZGVsOiBkYXlUYWJsZU1vZGVsLCBkYXRlUHJvZmlsZTogZGF0ZVByb2ZpbGUsIGF4aXM6IGhhc0F0dGFjaGVkQXhpcywgc2xvdER1cmF0aW9uOiBvcHRpb25zLnNsb3REdXJhdGlvbiwgc2xhdE1ldGFzOiBzbGF0TWV0YXMsIGZvclByaW50OiBwcm9wcy5mb3JQcmludCwgdGFibGVDb2xHcm91cE5vZGU6IGNvbnRlbnRBcmcudGFibGVDb2xHcm91cE5vZGUsIHRhYmxlTWluV2lkdGg6IGNvbnRlbnRBcmcudGFibGVNaW5XaWR0aCwgY2xpZW50V2lkdGg6IGNvbnRlbnRBcmcuY2xpZW50V2lkdGgsIGNsaWVudEhlaWdodDogY29udGVudEFyZy5jbGllbnRIZWlnaHQsIG9uU2xhdENvb3JkczogdGhpcy5oYW5kbGVTbGF0Q29vcmRzLCBleHBhbmRSb3dzOiBjb250ZW50QXJnLmV4cGFuZFJvd3MsIG9uU2Nyb2xsVG9wUmVxdWVzdDogdGhpcy5oYW5kbGVTY3JvbGxUb3BSZXF1ZXN0IH0pKSk7XG4gICAgICAgIHJldHVybiBoYXNEZXRhY2hlZEF4aXNcbiAgICAgICAgICAgID8gdGhpcy5yZW5kZXJIU2Nyb2xsTGF5b3V0KGhlYWRlckNvbnRlbnQsIGFsbERheUNvbnRlbnQsIHRpbWVHcmlkQ29udGVudCwgZGF5VGFibGVNb2RlbC5jb2xDbnQsIGRheU1pbldpZHRoLCBzbGF0TWV0YXMsIHRoaXMuc3RhdGUuc2xhdENvb3JkcylcbiAgICAgICAgICAgIDogdGhpcy5yZW5kZXJTaW1wbGVMYXlvdXQoaGVhZGVyQ29udGVudCwgYWxsRGF5Q29udGVudCwgdGltZUdyaWRDb250ZW50KTtcbiAgICB9XG59XG5mdW5jdGlvbiBidWlsZFRpbWVDb2xzTW9kZWwoZGF0ZVByb2ZpbGUsIGRhdGVQcm9maWxlR2VuZXJhdG9yKSB7XG4gICAgbGV0IGRheVNlcmllcyA9IG5ldyBEYXlTZXJpZXNNb2RlbChkYXRlUHJvZmlsZS5yZW5kZXJSYW5nZSwgZGF0ZVByb2ZpbGVHZW5lcmF0b3IpO1xuICAgIHJldHVybiBuZXcgRGF5VGFibGVNb2RlbChkYXlTZXJpZXMsIGZhbHNlKTtcbn1cblxuZXhwb3J0IHsgRGF5VGltZUNvbHMsIERheVRpbWVDb2xzU2xpY2VyLCBEYXlUaW1lQ29sc1ZpZXcsIFRpbWVDb2xzLCBUaW1lQ29sc1NsYXRzQ29vcmRzLCBUaW1lQ29sc1ZpZXcsIGJ1aWxkRGF5UmFuZ2VzLCBidWlsZFNsYXRNZXRhcywgYnVpbGRUaW1lQ29sc01vZGVsIH07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/@fullcalendar/timegrid/internal.esm.js\n"); /***/ }) /******/ }); /************************************************************************/ /******/ // The module cache /******/ var __webpack_module_cache__ = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache /******/ var cachedModule = __webpack_module_cache__[moduleId]; /******/ if (cachedModule !== undefined) { /******/ return cachedModule.exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = __webpack_module_cache__[moduleId] = { /******/ // no module.id needed /******/ // no module.loaded needed /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /************************************************************************/ /******/ /* webpack/runtime/define property getters */ /******/ !function() { /******/ // define getter functions for harmony exports /******/ __webpack_require__.d = function(exports, definition) { /******/ for(var key in definition) { /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); /******/ } /******/ } /******/ }; /******/ }(); /******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ !function() { /******/ __webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); } /******/ }(); /******/ /******/ /* webpack/runtime/make namespace object */ /******/ !function() { /******/ // define __esModule on exports /******/ __webpack_require__.r = function(exports) { /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ }(); /******/ /************************************************************************/ /******/ /******/ // startup /******/ // Load entry module and return exports /******/ // This entry module can't be inlined because the eval-source-map devtool is used. /******/ var __webpack_exports__ = __webpack_require__("./libs/fullcalendar/fullcalendar.js"); /******/ /******/ return __webpack_exports__; /******/ })() ; });
/ elements with colspans.\n SOLUTION: making individual
\n this.frameElRefs = new _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.cf(); // the fc-daygrid-day-frame\n this.fgElRefs = new _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.cf(); // the fc-daygrid-day-events\n this.segHarnessRefs = new _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.cf(); // indexed by \"instanceId:firstCol\"\n this.rootElRef = (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createRef)();\n this.state = {\n framePositions: null,\n maxContentHeight: null,\n eventInstanceHeights: {},\n };\n this.handleResize = (isForced) => {\n if (isForced) {\n this.updateSizing(true); // isExternal=true\n }\n };\n }\n render() {\n let { props, state, context } = this;\n let { options } = context;\n let colCnt = props.cells.length;\n let businessHoursByCol = splitSegsByFirstCol(props.businessHourSegs, colCnt);\n let bgEventSegsByCol = splitSegsByFirstCol(props.bgEventSegs, colCnt);\n let highlightSegsByCol = splitSegsByFirstCol(this.getHighlightSegs(), colCnt);\n let mirrorSegsByCol = splitSegsByFirstCol(this.getMirrorSegs(), colCnt);\n let { singleColPlacements, multiColPlacements, moreCnts, moreMarginTops } = computeFgSegPlacement((0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bR)(props.fgEventSegs, options.eventOrder), props.dayMaxEvents, props.dayMaxEventRows, options.eventOrderStrict, state.eventInstanceHeights, state.maxContentHeight, props.cells);\n let isForcedInvisible = // TODO: messy way to compute this\n (props.eventDrag && props.eventDrag.affectedInstances) ||\n (props.eventResize && props.eventResize.affectedInstances) ||\n {};\n return ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"tr\", { ref: this.rootElRef, role: \"row\" },\n props.renderIntro && props.renderIntro(),\n props.cells.map((cell, col) => {\n let normalFgNodes = this.renderFgSegs(col, props.forPrint ? singleColPlacements[col] : multiColPlacements[col], props.todayRange, isForcedInvisible);\n let mirrorFgNodes = this.renderFgSegs(col, buildMirrorPlacements(mirrorSegsByCol[col], multiColPlacements), props.todayRange, {}, Boolean(props.eventDrag), Boolean(props.eventResize), false);\n return ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(TableCell, { key: cell.key, elRef: this.cellElRefs.createRef(cell.key), innerElRef: this.frameElRefs.createRef(cell.key) /* FF problem, but okay to use for left/right. TODO: rename prop */, dateProfile: props.dateProfile, date: cell.date, showDayNumber: props.showDayNumbers, showWeekNumber: props.showWeekNumbers && col === 0, forceDayTop: props.showWeekNumbers /* even displaying weeknum for row, not necessarily day */, todayRange: props.todayRange, eventSelection: props.eventSelection, eventDrag: props.eventDrag, eventResize: props.eventResize, extraRenderProps: cell.extraRenderProps, extraDataAttrs: cell.extraDataAttrs, extraClassNames: cell.extraClassNames, extraDateSpan: cell.extraDateSpan, moreCnt: moreCnts[col], moreMarginTop: moreMarginTops[col], singlePlacements: singleColPlacements[col], fgContentElRef: this.fgElRefs.createRef(cell.key), fgContent: ( // Fragment scopes the keys\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.Fragment, null,\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.Fragment, null, normalFgNodes),\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.Fragment, null, mirrorFgNodes))), bgContent: ( // Fragment scopes the keys\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.Fragment, null,\n this.renderFillSegs(highlightSegsByCol[col], 'highlight'),\n this.renderFillSegs(businessHoursByCol[col], 'non-business'),\n this.renderFillSegs(bgEventSegsByCol[col], 'bg-event'))) }));\n })));\n }\n componentDidMount() {\n this.updateSizing(true);\n this.context.addResizeHandler(this.handleResize);\n }\n componentDidUpdate(prevProps, prevState) {\n let currentProps = this.props;\n this.updateSizing(!(0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.E)(prevProps, currentProps));\n }\n componentWillUnmount() {\n this.context.removeResizeHandler(this.handleResize);\n }\n getHighlightSegs() {\n let { props } = this;\n if (props.eventDrag && props.eventDrag.segs.length) { // messy check\n return props.eventDrag.segs;\n }\n if (props.eventResize && props.eventResize.segs.length) { // messy check\n return props.eventResize.segs;\n }\n return props.dateSelectionSegs;\n }\n getMirrorSegs() {\n let { props } = this;\n if (props.eventResize && props.eventResize.segs.length) { // messy check\n return props.eventResize.segs;\n }\n return [];\n }\n renderFgSegs(col, segPlacements, todayRange, isForcedInvisible, isDragging, isResizing, isDateSelecting) {\n let { context } = this;\n let { eventSelection } = this.props;\n let { framePositions } = this.state;\n let defaultDisplayEventEnd = this.props.cells.length === 1; // colCnt === 1\n let isMirror = isDragging || isResizing || isDateSelecting;\n let nodes = [];\n if (framePositions) {\n for (let placement of segPlacements) {\n let { seg } = placement;\n let { instanceId } = seg.eventRange.instance;\n let key = instanceId + ':' + col;\n let isVisible = placement.isVisible && !isForcedInvisible[instanceId];\n let isAbsolute = placement.isAbsolute;\n let left = '';\n let right = '';\n if (isAbsolute) {\n if (context.isRtl) {\n right = 0;\n left = framePositions.lefts[seg.lastCol] - framePositions.lefts[seg.firstCol];\n }\n else {\n left = 0;\n right = framePositions.rights[seg.firstCol] - framePositions.rights[seg.lastCol];\n }\n }\n /*\n known bug: events that are force to be list-item but span multiple days still take up space in later columns\n todo: in print view, for multi-day events, don't display title within non-start/end segs\n */\n nodes.push((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"div\", { className: 'fc-daygrid-event-harness' + (isAbsolute ? ' fc-daygrid-event-harness-abs' : ''), key: key, ref: isMirror ? null : this.segHarnessRefs.createRef(key), style: {\n visibility: isVisible ? '' : 'hidden',\n marginTop: isAbsolute ? '' : placement.marginTop,\n top: isAbsolute ? placement.absoluteTop : '',\n left,\n right,\n } }, hasListItemDisplay(seg) ? ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(TableListItemEvent, Object.assign({ seg: seg, isDragging: isDragging, isSelected: instanceId === eventSelection, defaultDisplayEventEnd: defaultDisplayEventEnd }, (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bS)(seg, todayRange)))) : ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(TableBlockEvent, Object.assign({ seg: seg, isDragging: isDragging, isResizing: isResizing, isDateSelecting: isDateSelecting, isSelected: instanceId === eventSelection, defaultDisplayEventEnd: defaultDisplayEventEnd }, (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bS)(seg, todayRange))))));\n }\n }\n return nodes;\n }\n renderFillSegs(segs, fillType) {\n let { isRtl } = this.context;\n let { todayRange } = this.props;\n let { framePositions } = this.state;\n let nodes = [];\n if (framePositions) {\n for (let seg of segs) {\n let leftRightCss = isRtl ? {\n right: 0,\n left: framePositions.lefts[seg.lastCol] - framePositions.lefts[seg.firstCol],\n } : {\n left: 0,\n right: framePositions.rights[seg.firstCol] - framePositions.rights[seg.lastCol],\n };\n nodes.push((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"div\", { key: (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bT)(seg.eventRange), className: \"fc-daygrid-bg-harness\", style: leftRightCss }, fillType === 'bg-event' ?\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.cp, Object.assign({ seg: seg }, (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bS)(seg, todayRange))) :\n (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.co)(fillType)));\n }\n }\n return (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.Fragment, {}, ...nodes);\n }\n updateSizing(isExternalSizingChange) {\n let { props, state, frameElRefs } = this;\n if (!props.forPrint &&\n props.clientWidth !== null // positioning ready?\n ) {\n if (isExternalSizingChange) {\n let frameEls = props.cells.map((cell) => frameElRefs.currentMap[cell.key]);\n if (frameEls.length) {\n let originEl = this.rootElRef.current;\n let newPositionCache = new _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bb(originEl, frameEls, true, // isHorizontal\n false);\n if (!state.framePositions || !state.framePositions.similarTo(newPositionCache)) {\n this.setState({\n framePositions: new _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bb(originEl, frameEls, true, // isHorizontal\n false),\n });\n }\n }\n }\n const oldInstanceHeights = this.state.eventInstanceHeights;\n const newInstanceHeights = this.queryEventInstanceHeights();\n const limitByContentHeight = props.dayMaxEvents === true || props.dayMaxEventRows === true;\n this.safeSetState({\n // HACK to prevent oscillations of events being shown/hidden from max-event-rows\n // Essentially, once you compute an element's height, never null-out.\n // TODO: always display all events, as visibility:hidden?\n eventInstanceHeights: Object.assign(Object.assign({}, oldInstanceHeights), newInstanceHeights),\n maxContentHeight: limitByContentHeight ? this.computeMaxContentHeight() : null,\n });\n }\n }\n queryEventInstanceHeights() {\n let segElMap = this.segHarnessRefs.currentMap;\n let eventInstanceHeights = {};\n // get the max height amongst instance segs\n for (let key in segElMap) {\n let height = Math.round(segElMap[key].getBoundingClientRect().height);\n let instanceId = key.split(':')[0]; // deconstruct how renderFgSegs makes the key\n eventInstanceHeights[instanceId] = Math.max(eventInstanceHeights[instanceId] || 0, height);\n }\n return eventInstanceHeights;\n }\n computeMaxContentHeight() {\n let firstKey = this.props.cells[0].key;\n let cellEl = this.cellElRefs.currentMap[firstKey];\n let fcContainerEl = this.fgElRefs.currentMap[firstKey];\n return cellEl.getBoundingClientRect().bottom - fcContainerEl.getBoundingClientRect().top;\n }\n getCellEls() {\n let elMap = this.cellElRefs.currentMap;\n return this.props.cells.map((cell) => elMap[cell.key]);\n }\n}\nTableRow.addStateEquality({\n eventInstanceHeights: _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.E,\n});\nfunction buildMirrorPlacements(mirrorSegs, colPlacements) {\n if (!mirrorSegs.length) {\n return [];\n }\n let topsByInstanceId = buildAbsoluteTopHash(colPlacements); // TODO: cache this at first render?\n return mirrorSegs.map((seg) => ({\n seg,\n isVisible: true,\n isAbsolute: true,\n absoluteTop: topsByInstanceId[seg.eventRange.instance.instanceId],\n marginTop: 0,\n }));\n}\nfunction buildAbsoluteTopHash(colPlacements) {\n let topsByInstanceId = {};\n for (let placements of colPlacements) {\n for (let placement of placements) {\n topsByInstanceId[placement.seg.eventRange.instance.instanceId] = placement.absoluteTop;\n }\n }\n return topsByInstanceId;\n}\n\nclass Table extends _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bf {\n constructor() {\n super(...arguments);\n this.splitBusinessHourSegs = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.z)(splitSegsByRow);\n this.splitBgEventSegs = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.z)(splitSegsByRow);\n this.splitFgEventSegs = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.z)(splitSegsByRow);\n this.splitDateSelectionSegs = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.z)(splitSegsByRow);\n this.splitEventDrag = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.z)(splitInteractionByRow);\n this.splitEventResize = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.z)(splitInteractionByRow);\n this.rowRefs = new _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.cf();\n this.handleRootEl = (rootEl) => {\n this.rootEl = rootEl;\n if (rootEl) {\n this.context.registerInteractiveComponent(this, {\n el: rootEl,\n isHitComboAllowed: this.props.isHitComboAllowed,\n });\n }\n else {\n this.context.unregisterInteractiveComponent(this);\n }\n };\n }\n render() {\n let { props } = this;\n let { dateProfile, dayMaxEventRows, dayMaxEvents, expandRows } = props;\n let rowCnt = props.cells.length;\n let businessHourSegsByRow = this.splitBusinessHourSegs(props.businessHourSegs, rowCnt);\n let bgEventSegsByRow = this.splitBgEventSegs(props.bgEventSegs, rowCnt);\n let fgEventSegsByRow = this.splitFgEventSegs(props.fgEventSegs, rowCnt);\n let dateSelectionSegsByRow = this.splitDateSelectionSegs(props.dateSelectionSegs, rowCnt);\n let eventDragByRow = this.splitEventDrag(props.eventDrag, rowCnt);\n let eventResizeByRow = this.splitEventResize(props.eventResize, rowCnt);\n let limitViaBalanced = dayMaxEvents === true || dayMaxEventRows === true;\n // if rows can't expand to fill fixed height, can't do balanced-height event limit\n // TODO: best place to normalize these options?\n if (limitViaBalanced && !expandRows) {\n limitViaBalanced = false;\n dayMaxEventRows = null;\n dayMaxEvents = null;\n }\n let classNames = [\n 'fc-daygrid-body',\n limitViaBalanced ? 'fc-daygrid-body-balanced' : 'fc-daygrid-body-unbalanced',\n expandRows ? '' : 'fc-daygrid-body-natural', // will height of one row depend on the others?\n ];\n return ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"div\", { className: classNames.join(' '), ref: this.handleRootEl, style: {\n // these props are important to give this wrapper correct dimensions for interactions\n // TODO: if we set it here, can we avoid giving to inner tables?\n width: props.clientWidth,\n minWidth: props.tableMinWidth,\n } },\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.ch, { unit: \"day\" }, (nowDate, todayRange) => ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.Fragment, null,\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"table\", { role: \"presentation\", className: \"fc-scrollgrid-sync-table\", style: {\n width: props.clientWidth,\n minWidth: props.tableMinWidth,\n height: expandRows ? props.clientHeight : '',\n } },\n props.colGroupNode,\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"tbody\", { role: \"presentation\" }, props.cells.map((cells, row) => ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(TableRow, { ref: this.rowRefs.createRef(row), key: cells.length\n ? cells[0].date.toISOString() /* best? or put key on cell? or use diff formatter? */\n : row // in case there are no cells (like when resource view is loading)\n , showDayNumbers: rowCnt > 1, showWeekNumbers: props.showWeekNumbers, todayRange: todayRange, dateProfile: dateProfile, cells: cells, renderIntro: props.renderRowIntro, businessHourSegs: businessHourSegsByRow[row], eventSelection: props.eventSelection, bgEventSegs: bgEventSegsByRow[row].filter(isSegAllDay) /* hack */, fgEventSegs: fgEventSegsByRow[row], dateSelectionSegs: dateSelectionSegsByRow[row], eventDrag: eventDragByRow[row], eventResize: eventResizeByRow[row], dayMaxEvents: dayMaxEvents, dayMaxEventRows: dayMaxEventRows, clientWidth: props.clientWidth, clientHeight: props.clientHeight, forPrint: props.forPrint }))))))))));\n }\n // Hit System\n // ----------------------------------------------------------------------------------------------------\n prepareHits() {\n this.rowPositions = new _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bb(this.rootEl, this.rowRefs.collect().map((rowObj) => rowObj.getCellEls()[0]), // first cell el in each row. TODO: not optimal\n false, true);\n this.colPositions = new _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bb(this.rootEl, this.rowRefs.currentMap[0].getCellEls(), // cell els in first row\n true, // horizontal\n false);\n }\n queryHit(positionLeft, positionTop) {\n let { colPositions, rowPositions } = this;\n let col = colPositions.leftToIndex(positionLeft);\n let row = rowPositions.topToIndex(positionTop);\n if (row != null && col != null) {\n let cell = this.props.cells[row][col];\n return {\n dateProfile: this.props.dateProfile,\n dateSpan: Object.assign({ range: this.getCellRange(row, col), allDay: true }, cell.extraDateSpan),\n dayEl: this.getCellEl(row, col),\n rect: {\n left: colPositions.lefts[col],\n right: colPositions.rights[col],\n top: rowPositions.tops[row],\n bottom: rowPositions.bottoms[row],\n },\n layer: 0,\n };\n }\n return null;\n }\n getCellEl(row, col) {\n return this.rowRefs.currentMap[row].getCellEls()[col]; // TODO: not optimal\n }\n getCellRange(row, col) {\n let start = this.props.cells[row][col].date;\n let end = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.t)(start, 1);\n return { start, end };\n }\n}\nfunction isSegAllDay(seg) {\n return seg.eventRange.def.allDay;\n}\n\nclass DayTableSlicer extends _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bW {\n constructor() {\n super(...arguments);\n this.forceDayIfListItem = true;\n }\n sliceRange(dateRange, dayTableModel) {\n return dayTableModel.sliceRange(dateRange);\n }\n}\n\nclass DayTable extends _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bf {\n constructor() {\n super(...arguments);\n this.slicer = new DayTableSlicer();\n this.tableRef = (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createRef)();\n }\n render() {\n let { props, context } = this;\n return ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(Table, Object.assign({ ref: this.tableRef }, this.slicer.sliceProps(props, props.dateProfile, props.nextDayThreshold, context, props.dayTableModel), { dateProfile: props.dateProfile, cells: props.dayTableModel.cells, colGroupNode: props.colGroupNode, tableMinWidth: props.tableMinWidth, renderRowIntro: props.renderRowIntro, dayMaxEvents: props.dayMaxEvents, dayMaxEventRows: props.dayMaxEventRows, showWeekNumbers: props.showWeekNumbers, expandRows: props.expandRows, headerAlignElRef: props.headerAlignElRef, clientWidth: props.clientWidth, clientHeight: props.clientHeight, forPrint: props.forPrint })));\n }\n}\n\nclass DayTableView extends TableView {\n constructor() {\n super(...arguments);\n this.buildDayTableModel = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.z)(buildDayTableModel);\n this.headerRef = (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createRef)();\n this.tableRef = (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createRef)();\n }\n render() {\n let { options, dateProfileGenerator } = this.context;\n let { props } = this;\n let dayTableModel = this.buildDayTableModel(props.dateProfile, dateProfileGenerator);\n let headerContent = options.dayHeaders && ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bK, { ref: this.headerRef, dateProfile: props.dateProfile, dates: dayTableModel.headerDates, datesRepDistinctDays: dayTableModel.rowCnt === 1 }));\n let bodyContent = (contentArg) => ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(DayTable, { ref: this.tableRef, dateProfile: props.dateProfile, dayTableModel: dayTableModel, businessHours: props.businessHours, dateSelection: props.dateSelection, eventStore: props.eventStore, eventUiBases: props.eventUiBases, eventSelection: props.eventSelection, eventDrag: props.eventDrag, eventResize: props.eventResize, nextDayThreshold: options.nextDayThreshold, colGroupNode: contentArg.tableColGroupNode, tableMinWidth: contentArg.tableMinWidth, dayMaxEvents: options.dayMaxEvents, dayMaxEventRows: options.dayMaxEventRows, showWeekNumbers: options.weekNumbers, expandRows: !props.isHeightAuto, headerAlignElRef: this.headerElRef, clientWidth: contentArg.clientWidth, clientHeight: contentArg.clientHeight, forPrint: props.forPrint }));\n return options.dayMinWidth\n ? this.renderHScrollLayout(headerContent, bodyContent, dayTableModel.colCnt, options.dayMinWidth)\n : this.renderSimpleLayout(headerContent, bodyContent);\n }\n}\nfunction buildDayTableModel(dateProfile, dateProfileGenerator) {\n let daySeries = new _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bO(dateProfile.renderRange, dateProfileGenerator);\n return new _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bV(daySeries, /year|month|week/.test(dateProfile.currentRangeUnit));\n}\n\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvQGZ1bGxjYWxlbmRhci9kYXlncmlkL2ludGVybmFsLmVzbS5qcy5qcyIsIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7OztBQUFzbkI7QUFDdmlCOztBQUUvRTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdCQUF3QiwyREFBYTtBQUNyQztBQUNBO0FBQ0EsMkJBQTJCLG9FQUFTO0FBQ3BDO0FBQ0E7QUFDQSxjQUFjLGlCQUFpQjtBQUMvQjtBQUNBLGdDQUFnQywrREFBb0I7QUFDcEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCLHNCQUFzQjtBQUMzQyxTQUFTO0FBQ1QsZ0JBQWdCLHdFQUFhLENBQUMsMkRBQWEsSUFBSSx1REFBdUQ7QUFDdEcsWUFBWSx3RUFBYSxDQUFDLDJEQUFnQixJQUFJLDJJQUEySTtBQUN6TDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLGlCQUFpQjtBQUMvQixtREFBbUQsK0RBQW9CO0FBQ3ZFLHVEQUF1RCwrREFBd0I7QUFDL0U7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQixhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQixTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQ0FBaUMsMkRBQWdCO0FBQ2pELHFCQUFxQjtBQUNyQixhQUFhO0FBQ2I7QUFDQSxnQkFBZ0Isd0VBQWEsQ0FBQywyREFBYSxJQUFJLHVEQUF1RDtBQUN0RyxZQUFZLHdFQUFhLGVBQWUsZ0dBQWdHLFNBQVMscUNBQXFDLEdBQUcsdUJBQXVCO0FBQ2hOO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG9CQUFvQixZQUFZO0FBQ2hDO0FBQ0E7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QU07QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSx1QkFBdUIsMkRBQWE7QUFDcEM7QUFDQTtBQUNBO0FBQ0Esd0JBQXdCLG9FQUFTO0FBQ2pDO0FBQ0E7QUFDQSxjQUFjLGlCQUFpQjtBQUMvQixnQkFBZ0Isd0VBQWEsd0JBQXdCLG9CQUFvQiw0R0FBNEcsb2NBQW9jO0FBQ3puQjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGtDQUFrQyw4REFBTztBQUN6Qyx5QkFBeUIsb0VBQVM7QUFDbEMsd0JBQXdCLG9FQUFTO0FBQ2pDO0FBQ0E7QUFDQSxjQUFjLGdDQUFnQztBQUM5QyxjQUFjLFFBQVE7QUFDdEI7QUFDQSxtREFBbUQsd0VBQWEsQ0FBQywyREFBUyxJQUFJLHlJQUF5STtBQUN2TiwyQ0FBMkMsd0VBQWEsYUFBYSw0dEJBQTR0QjtBQUNqeUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0JBQXdCLDJEQUFjO0FBQ3RDLGVBQWUsMkRBQWE7QUFDNUI7O0FBRXVHIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vVnVleHkvLi9ub2RlX21vZHVsZXMvQGZ1bGxjYWxlbmRhci9kYXlncmlkL2ludGVybmFsLmVzbS5qcz83M2MwIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERhdGVDb21wb25lbnQsIGdldFN0aWNreUhlYWRlckRhdGVzLCBWaWV3Q29udGFpbmVyLCBTaW1wbGVTY3JvbGxHcmlkLCBnZXRTdGlja3lGb290ZXJTY3JvbGxiYXIsIHJlbmRlclNjcm9sbFNoaW0sIGNyZWF0ZUZvcm1hdHRlciwgQmFzZUNvbXBvbmVudCwgU3RhbmRhcmRFdmVudCwgYnVpbGRTZWdUaW1lVGV4dCwgRXZlbnRDb250YWluZXIsIGdldFNlZ0FuY2hvckF0dHJzLCBtZW1vaXplLCBNb3JlTGlua0NvbnRhaW5lciwgZ2V0U2VnTWV0YSwgZ2V0VW5pcXVlRG9tSWQsIHNldFJlZiwgRGF5Q2VsbENvbnRhaW5lciwgV2Vla051bWJlckNvbnRhaW5lciwgYnVpbGROYXZMaW5rQXR0cnMsIGhhc0N1c3RvbURheUNlbGxDb250ZW50LCBpbnRlcnNlY3RSYW5nZXMsIGFkZERheXMsIFNlZ0hpZXJhcmNoeSwgYnVpbGRFbnRyeUtleSwgaW50ZXJzZWN0U3BhbnMsIFJlZk1hcCwgc29ydEV2ZW50U2VncywgaXNQcm9wc0VxdWFsLCBidWlsZEV2ZW50UmFuZ2VLZXksIEJnRXZlbnQsIHJlbmRlckZpbGwsIFBvc2l0aW9uQ2FjaGUsIE5vd1RpbWVyLCBTbGljZXIsIERheUhlYWRlciwgRGF5U2VyaWVzTW9kZWwsIERheVRhYmxlTW9kZWwgfSBmcm9tICdAZnVsbGNhbGVuZGFyL2NvcmUvaW50ZXJuYWwnO1xuaW1wb3J0IHsgY3JlYXRlUmVmLCBjcmVhdGVFbGVtZW50LCBGcmFnbWVudCB9IGZyb20gJ0BmdWxsY2FsZW5kYXIvY29yZS9wcmVhY3QnO1xuXG4vKiBBbiBhYnN0cmFjdCBjbGFzcyBmb3IgdGhlIGRheWdyaWQgdmlld3MsIGFzIHdlbGwgYXMgbW9udGggdmlldy4gUmVuZGVycyBvbmUgb3IgbW9yZSByb3dzIG9mIGRheSBjZWxscy5cbi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuLy8gSXQgaXMgYSBtYW5hZ2VyIGZvciBhIFRhYmxlIHN1YmNvbXBvbmVudCwgd2hpY2ggZG9lcyBtb3N0IG9mIHRoZSBoZWF2eSBsaWZ0aW5nLlxuLy8gSXQgaXMgcmVzcG9uc2libGUgZm9yIG1hbmFnaW5nIHdpZHRoL2hlaWdodC5cbmNsYXNzIFRhYmxlVmlldyBleHRlbmRzIERhdGVDb21wb25lbnQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLmhlYWRlckVsUmVmID0gY3JlYXRlUmVmKCk7XG4gICAgfVxuICAgIHJlbmRlclNpbXBsZUxheW91dChoZWFkZXJSb3dDb250ZW50LCBib2R5Q29udGVudCkge1xuICAgICAgICBsZXQgeyBwcm9wcywgY29udGV4dCB9ID0gdGhpcztcbiAgICAgICAgbGV0IHNlY3Rpb25zID0gW107XG4gICAgICAgIGxldCBzdGlja3lIZWFkZXJEYXRlcyA9IGdldFN0aWNreUhlYWRlckRhdGVzKGNvbnRleHQub3B0aW9ucyk7XG4gICAgICAgIGlmIChoZWFkZXJSb3dDb250ZW50KSB7XG4gICAgICAgICAgICBzZWN0aW9ucy5wdXNoKHtcbiAgICAgICAgICAgICAgICB0eXBlOiAnaGVhZGVyJyxcbiAgICAgICAgICAgICAgICBrZXk6ICdoZWFkZXInLFxuICAgICAgICAgICAgICAgIGlzU3RpY2t5OiBzdGlja3lIZWFkZXJEYXRlcyxcbiAgICAgICAgICAgICAgICBjaHVuazoge1xuICAgICAgICAgICAgICAgICAgICBlbFJlZjogdGhpcy5oZWFkZXJFbFJlZixcbiAgICAgICAgICAgICAgICAgICAgdGFibGVDbGFzc05hbWU6ICdmYy1jb2wtaGVhZGVyJyxcbiAgICAgICAgICAgICAgICAgICAgcm93Q29udGVudDogaGVhZGVyUm93Q29udGVudCxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgc2VjdGlvbnMucHVzaCh7XG4gICAgICAgICAgICB0eXBlOiAnYm9keScsXG4gICAgICAgICAgICBrZXk6ICdib2R5JyxcbiAgICAgICAgICAgIGxpcXVpZDogdHJ1ZSxcbiAgICAgICAgICAgIGNodW5rOiB7IGNvbnRlbnQ6IGJvZHlDb250ZW50IH0sXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gKGNyZWF0ZUVsZW1lbnQoVmlld0NvbnRhaW5lciwgeyBlbENsYXNzZXM6IFsnZmMtZGF5Z3JpZCddLCB2aWV3U3BlYzogY29udGV4dC52aWV3U3BlYyB9LFxuICAgICAgICAgICAgY3JlYXRlRWxlbWVudChTaW1wbGVTY3JvbGxHcmlkLCB7IGxpcXVpZDogIXByb3BzLmlzSGVpZ2h0QXV0byAmJiAhcHJvcHMuZm9yUHJpbnQsIGNvbGxhcHNpYmxlV2lkdGg6IHByb3BzLmZvclByaW50LCBjb2xzOiBbXSAvKiBUT0RPOiBtYWtlIG9wdGlvbmFsPyAqLywgc2VjdGlvbnM6IHNlY3Rpb25zIH0pKSk7XG4gICAgfVxuICAgIHJlbmRlckhTY3JvbGxMYXlvdXQoaGVhZGVyUm93Q29udGVudCwgYm9keUNvbnRlbnQsIGNvbENudCwgZGF5TWluV2lkdGgpIHtcbiAgICAgICAgbGV0IFNjcm9sbEdyaWQgPSB0aGlzLmNvbnRleHQucGx1Z2luSG9va3Muc2Nyb2xsR3JpZEltcGw7XG4gICAgICAgIGlmICghU2Nyb2xsR3JpZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyBTY3JvbGxHcmlkIGltcGxlbWVudGF0aW9uJyk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IHsgcHJvcHMsIGNvbnRleHQgfSA9IHRoaXM7XG4gICAgICAgIGxldCBzdGlja3lIZWFkZXJEYXRlcyA9ICFwcm9wcy5mb3JQcmludCAmJiBnZXRTdGlja3lIZWFkZXJEYXRlcyhjb250ZXh0Lm9wdGlvbnMpO1xuICAgICAgICBsZXQgc3RpY2t5Rm9vdGVyU2Nyb2xsYmFyID0gIXByb3BzLmZvclByaW50ICYmIGdldFN0aWNreUZvb3RlclNjcm9sbGJhcihjb250ZXh0Lm9wdGlvbnMpO1xuICAgICAgICBsZXQgc2VjdGlvbnMgPSBbXTtcbiAgICAgICAgaWYgKGhlYWRlclJvd0NvbnRlbnQpIHtcbiAgICAgICAgICAgIHNlY3Rpb25zLnB1c2goe1xuICAgICAgICAgICAgICAgIHR5cGU6ICdoZWFkZXInLFxuICAgICAgICAgICAgICAgIGtleTogJ2hlYWRlcicsXG4gICAgICAgICAgICAgICAgaXNTdGlja3k6IHN0aWNreUhlYWRlckRhdGVzLFxuICAgICAgICAgICAgICAgIGNodW5rczogW3tcbiAgICAgICAgICAgICAgICAgICAgICAgIGtleTogJ21haW4nLFxuICAgICAgICAgICAgICAgICAgICAgICAgZWxSZWY6IHRoaXMuaGVhZGVyRWxSZWYsXG4gICAgICAgICAgICAgICAgICAgICAgICB0YWJsZUNsYXNzTmFtZTogJ2ZjLWNvbC1oZWFkZXInLFxuICAgICAgICAgICAgICAgICAgICAgICAgcm93Q29udGVudDogaGVhZGVyUm93Q29udGVudCxcbiAgICAgICAgICAgICAgICAgICAgfV0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBzZWN0aW9ucy5wdXNoKHtcbiAgICAgICAgICAgIHR5cGU6ICdib2R5JyxcbiAgICAgICAgICAgIGtleTogJ2JvZHknLFxuICAgICAgICAgICAgbGlxdWlkOiB0cnVlLFxuICAgICAgICAgICAgY2h1bmtzOiBbe1xuICAgICAgICAgICAgICAgICAgICBrZXk6ICdtYWluJyxcbiAgICAgICAgICAgICAgICAgICAgY29udGVudDogYm9keUNvbnRlbnQsXG4gICAgICAgICAgICAgICAgfV0sXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoc3RpY2t5Rm9vdGVyU2Nyb2xsYmFyKSB7XG4gICAgICAgICAgICBzZWN0aW9ucy5wdXNoKHtcbiAgICAgICAgICAgICAgICB0eXBlOiAnZm9vdGVyJyxcbiAgICAgICAgICAgICAgICBrZXk6ICdmb290ZXInLFxuICAgICAgICAgICAgICAgIGlzU3RpY2t5OiB0cnVlLFxuICAgICAgICAgICAgICAgIGNodW5rczogW3tcbiAgICAgICAgICAgICAgICAgICAgICAgIGtleTogJ21haW4nLFxuICAgICAgICAgICAgICAgICAgICAgICAgY29udGVudDogcmVuZGVyU2Nyb2xsU2hpbSxcbiAgICAgICAgICAgICAgICAgICAgfV0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gKGNyZWF0ZUVsZW1lbnQoVmlld0NvbnRhaW5lciwgeyBlbENsYXNzZXM6IFsnZmMtZGF5Z3JpZCddLCB2aWV3U3BlYzogY29udGV4dC52aWV3U3BlYyB9LFxuICAgICAgICAgICAgY3JlYXRlRWxlbWVudChTY3JvbGxHcmlkLCB7IGxpcXVpZDogIXByb3BzLmlzSGVpZ2h0QXV0byAmJiAhcHJvcHMuZm9yUHJpbnQsIGNvbGxhcHNpYmxlV2lkdGg6IHByb3BzLmZvclByaW50LCBjb2xHcm91cHM6IFt7IGNvbHM6IFt7IHNwYW46IGNvbENudCwgbWluV2lkdGg6IGRheU1pbldpZHRoIH1dIH1dLCBzZWN0aW9uczogc2VjdGlvbnMgfSkpKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIHNwbGl0U2Vnc0J5Um93KHNlZ3MsIHJvd0NudCkge1xuICAgIGxldCBieVJvdyA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcm93Q250OyBpICs9IDEpIHtcbiAgICAgICAgYnlSb3dbaV0gPSBbXTtcbiAgICB9XG4gICAgZm9yIChsZXQgc2VnIG9mIHNlZ3MpIHtcbiAgICAgICAgYnlSb3dbc2VnLnJvd10ucHVzaChzZWcpO1xuICAgIH1cbiAgICByZXR1cm4gYnlSb3c7XG59XG5mdW5jdGlvbiBzcGxpdFNlZ3NCeUZpcnN0Q29sKHNlZ3MsIGNvbENudCkge1xuICAgIGxldCBieUNvbCA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY29sQ250OyBpICs9IDEpIHtcbiAgICAgICAgYnlDb2xbaV0gPSBbXTtcbiAgICB9XG4gICAgZm9yIChsZXQgc2VnIG9mIHNlZ3MpIHtcbiAgICAgICAgYnlDb2xbc2VnLmZpcnN0Q29sXS5wdXNoKHNlZyk7XG4gICAgfVxuICAgIHJldHVybiBieUNvbDtcbn1cbmZ1bmN0aW9uIHNwbGl0SW50ZXJhY3Rpb25CeVJvdyh1aSwgcm93Q250KSB7XG4gICAgbGV0IGJ5Um93ID0gW107XG4gICAgaWYgKCF1aSkge1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJvd0NudDsgaSArPSAxKSB7XG4gICAgICAgICAgICBieVJvd1tpXSA9IG51bGw7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcm93Q250OyBpICs9IDEpIHtcbiAgICAgICAgICAgIGJ5Um93W2ldID0ge1xuICAgICAgICAgICAgICAgIGFmZmVjdGVkSW5zdGFuY2VzOiB1aS5hZmZlY3RlZEluc3RhbmNlcyxcbiAgICAgICAgICAgICAgICBpc0V2ZW50OiB1aS5pc0V2ZW50LFxuICAgICAgICAgICAgICAgIHNlZ3M6IFtdLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGxldCBzZWcgb2YgdWkuc2Vncykge1xuICAgICAgICAgICAgYnlSb3dbc2VnLnJvd10uc2Vncy5wdXNoKHNlZyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGJ5Um93O1xufVxuXG5jb25zdCBERUZBVUxUX1RBQkxFX0VWRU5UX1RJTUVfRk9STUFUID0gY3JlYXRlRm9ybWF0dGVyKHtcbiAgICBob3VyOiAnbnVtZXJpYycsXG4gICAgbWludXRlOiAnMi1kaWdpdCcsXG4gICAgb21pdFplcm9NaW51dGU6IHRydWUsXG4gICAgbWVyaWRpZW06ICduYXJyb3cnLFxufSk7XG5mdW5jdGlvbiBoYXNMaXN0SXRlbURpc3BsYXkoc2VnKSB7XG4gICAgbGV0IHsgZGlzcGxheSB9ID0gc2VnLmV2ZW50UmFuZ2UudWk7XG4gICAgcmV0dXJuIGRpc3BsYXkgPT09ICdsaXN0LWl0ZW0nIHx8IChkaXNwbGF5ID09PSAnYXV0bycgJiZcbiAgICAgICAgIXNlZy5ldmVudFJhbmdlLmRlZi5hbGxEYXkgJiZcbiAgICAgICAgc2VnLmZpcnN0Q29sID09PSBzZWcubGFzdENvbCAmJiAvLyBjYW4ndCBiZSBtdWx0aS1kYXlcbiAgICAgICAgc2VnLmlzU3RhcnQgJiYgLy8gXCJcbiAgICAgICAgc2VnLmlzRW5kIC8vIFwiXG4gICAgKTtcbn1cblxuY2xhc3MgVGFibGVCbG9ja0V2ZW50IGV4dGVuZHMgQmFzZUNvbXBvbmVudCB7XG4gICAgcmVuZGVyKCkge1xuICAgICAgICBsZXQgeyBwcm9wcyB9ID0gdGhpcztcbiAgICAgICAgcmV0dXJuIChjcmVhdGVFbGVtZW50KFN0YW5kYXJkRXZlbnQsIE9iamVjdC5hc3NpZ24oe30sIHByb3BzLCB7IGVsQ2xhc3NlczogWydmYy1kYXlncmlkLWV2ZW50JywgJ2ZjLWRheWdyaWQtYmxvY2stZXZlbnQnLCAnZmMtaC1ldmVudCddLCBkZWZhdWx0VGltZUZvcm1hdDogREVGQVVMVF9UQUJMRV9FVkVOVF9USU1FX0ZPUk1BVCwgZGVmYXVsdERpc3BsYXlFdmVudEVuZDogcHJvcHMuZGVmYXVsdERpc3BsYXlFdmVudEVuZCwgZGlzYWJsZVJlc2l6aW5nOiAhcHJvcHMuc2VnLmV2ZW50UmFuZ2UuZGVmLmFsbERheSB9KSkpO1xuICAgIH1cbn1cblxuY2xhc3MgVGFibGVMaXN0SXRlbUV2ZW50IGV4dGVuZHMgQmFzZUNvbXBvbmVudCB7XG4gICAgcmVuZGVyKCkge1xuICAgICAgICBsZXQgeyBwcm9wcywgY29udGV4dCB9ID0gdGhpcztcbiAgICAgICAgbGV0IHsgb3B0aW9ucyB9ID0gY29udGV4dDtcbiAgICAgICAgbGV0IHsgc2VnIH0gPSBwcm9wcztcbiAgICAgICAgbGV0IHRpbWVGb3JtYXQgPSBvcHRpb25zLmV2ZW50VGltZUZvcm1hdCB8fCBERUZBVUxUX1RBQkxFX0VWRU5UX1RJTUVfRk9STUFUO1xuICAgICAgICBsZXQgdGltZVRleHQgPSBidWlsZFNlZ1RpbWVUZXh0KHNlZywgdGltZUZvcm1hdCwgY29udGV4dCwgdHJ1ZSwgcHJvcHMuZGVmYXVsdERpc3BsYXlFdmVudEVuZCk7XG4gICAgICAgIHJldHVybiAoY3JlYXRlRWxlbWVudChFdmVudENvbnRhaW5lciwgT2JqZWN0LmFzc2lnbih7fSwgcHJvcHMsIHsgZWxUYWc6IFwiYVwiLCBlbENsYXNzZXM6IFsnZmMtZGF5Z3JpZC1ldmVudCcsICdmYy1kYXlncmlkLWRvdC1ldmVudCddLCBlbEF0dHJzOiBnZXRTZWdBbmNob3JBdHRycyhwcm9wcy5zZWcsIGNvbnRleHQpLCBkZWZhdWx0R2VuZXJhdG9yOiByZW5kZXJJbm5lckNvbnRlbnQsIHRpbWVUZXh0OiB0aW1lVGV4dCwgaXNSZXNpemluZzogZmFsc2UsIGlzRGF0ZVNlbGVjdGluZzogZmFsc2UgfSkpKTtcbiAgICB9XG59XG5mdW5jdGlvbiByZW5kZXJJbm5lckNvbnRlbnQocmVuZGVyUHJvcHMpIHtcbiAgICByZXR1cm4gKGNyZWF0ZUVsZW1lbnQoRnJhZ21lbnQsIG51bGwsXG4gICAgICAgIGNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwgeyBjbGFzc05hbWU6IFwiZmMtZGF5Z3JpZC1ldmVudC1kb3RcIiwgc3R5bGU6IHsgYm9yZGVyQ29sb3I6IHJlbmRlclByb3BzLmJvcmRlckNvbG9yIHx8IHJlbmRlclByb3BzLmJhY2tncm91bmRDb2xvciB9IH0pLFxuICAgICAgICByZW5kZXJQcm9wcy50aW1lVGV4dCAmJiAoY3JlYXRlRWxlbWVudChcImRpdlwiLCB7IGNsYXNzTmFtZTogXCJmYy1ldmVudC10aW1lXCIgfSwgcmVuZGVyUHJvcHMudGltZVRleHQpKSxcbiAgICAgICAgY3JlYXRlRWxlbWVudChcImRpdlwiLCB7IGNsYXNzTmFtZTogXCJmYy1ldmVudC10aXRsZVwiIH0sIHJlbmRlclByb3BzLmV2ZW50LnRpdGxlIHx8IGNyZWF0ZUVsZW1lbnQoRnJhZ21lbnQsIG51bGwsIFwiXFx1MDBBMFwiKSkpKTtcbn1cblxuY2xhc3MgVGFibGVDZWxsTW9yZUxpbmsgZXh0ZW5kcyBCYXNlQ29tcG9uZW50IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5jb21waWxlU2VncyA9IG1lbW9pemUoY29tcGlsZVNlZ3MpO1xuICAgIH1cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGxldCB7IHByb3BzIH0gPSB0aGlzO1xuICAgICAgICBsZXQgeyBhbGxTZWdzLCBpbnZpc2libGVTZWdzIH0gPSB0aGlzLmNvbXBpbGVTZWdzKHByb3BzLnNpbmdsZVBsYWNlbWVudHMpO1xuICAgICAgICByZXR1cm4gKGNyZWF0ZUVsZW1lbnQoTW9yZUxpbmtDb250YWluZXIsIHsgZWxDbGFzc2VzOiBbJ2ZjLWRheWdyaWQtbW9yZS1saW5rJ10sIGRhdGVQcm9maWxlOiBwcm9wcy5kYXRlUHJvZmlsZSwgdG9kYXlSYW5nZTogcHJvcHMudG9kYXlSYW5nZSwgYWxsRGF5RGF0ZTogcHJvcHMuYWxsRGF5RGF0ZSwgbW9yZUNudDogcHJvcHMubW9yZUNudCwgYWxsU2VnczogYWxsU2VncywgaGlkZGVuU2VnczogaW52aXNpYmxlU2VncywgYWxpZ25tZW50RWxSZWY6IHByb3BzLmFsaWdubWVudEVsUmVmLCBhbGlnbkdyaWRUb3A6IHByb3BzLmFsaWduR3JpZFRvcCwgZXh0cmFEYXRlU3BhbjogcHJvcHMuZXh0cmFEYXRlU3BhbiwgcG9wb3ZlckNvbnRlbnQ6ICgpID0+IHtcbiAgICAgICAgICAgICAgICBsZXQgaXNGb3JjZWRJbnZpc2libGUgPSAocHJvcHMuZXZlbnREcmFnID8gcHJvcHMuZXZlbnREcmFnLmFmZmVjdGVkSW5zdGFuY2VzIDogbnVsbCkgfHxcbiAgICAgICAgICAgICAgICAgICAgKHByb3BzLmV2ZW50UmVzaXplID8gcHJvcHMuZXZlbnRSZXNpemUuYWZmZWN0ZWRJbnN0YW5jZXMgOiBudWxsKSB8fFxuICAgICAgICAgICAgICAgICAgICB7fTtcbiAgICAgICAgICAgICAgICByZXR1cm4gKGNyZWF0ZUVsZW1lbnQoRnJhZ21lbnQsIG51bGwsIGFsbFNlZ3MubWFwKChzZWcpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGluc3RhbmNlSWQgPSBzZWcuZXZlbnRSYW5nZS5pbnN0YW5jZS5pbnN0YW5jZUlkO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gKGNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwgeyBjbGFzc05hbWU6IFwiZmMtZGF5Z3JpZC1ldmVudC1oYXJuZXNzXCIsIGtleTogaW5zdGFuY2VJZCwgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aXNpYmlsaXR5OiBpc0ZvcmNlZEludmlzaWJsZVtpbnN0YW5jZUlkXSA/ICdoaWRkZW4nIDogJycsXG4gICAgICAgICAgICAgICAgICAgICAgICB9IH0sIGhhc0xpc3RJdGVtRGlzcGxheShzZWcpID8gKGNyZWF0ZUVsZW1lbnQoVGFibGVMaXN0SXRlbUV2ZW50LCBPYmplY3QuYXNzaWduKHsgc2VnOiBzZWcsIGlzRHJhZ2dpbmc6IGZhbHNlLCBpc1NlbGVjdGVkOiBpbnN0YW5jZUlkID09PSBwcm9wcy5ldmVudFNlbGVjdGlvbiwgZGVmYXVsdERpc3BsYXlFdmVudEVuZDogZmFsc2UgfSwgZ2V0U2VnTWV0YShzZWcsIHByb3BzLnRvZGF5UmFuZ2UpKSkpIDogKGNyZWF0ZUVsZW1lbnQoVGFibGVCbG9ja0V2ZW50LCBPYmplY3QuYXNzaWduKHsgc2VnOiBzZWcsIGlzRHJhZ2dpbmc6IGZhbHNlLCBpc1Jlc2l6aW5nOiBmYWxzZSwgaXNEYXRlU2VsZWN0aW5nOiBmYWxzZSwgaXNTZWxlY3RlZDogaW5zdGFuY2VJZCA9PT0gcHJvcHMuZXZlbnRTZWxlY3Rpb24sIGRlZmF1bHREaXNwbGF5RXZlbnRFbmQ6IGZhbHNlIH0sIGdldFNlZ01ldGEoc2VnLCBwcm9wcy50b2RheVJhbmdlKSkpKSkpO1xuICAgICAgICAgICAgICAgIH0pKSk7XG4gICAgICAgICAgICB9IH0pKTtcbiAgICB9XG59XG5mdW5jdGlvbiBjb21waWxlU2VncyhzaW5nbGVQbGFjZW1lbnRzKSB7XG4gICAgbGV0IGFsbFNlZ3MgPSBbXTtcbiAgICBsZXQgaW52aXNpYmxlU2VncyA9IFtdO1xuICAgIGZvciAobGV0IHBsYWNlbWVudCBvZiBzaW5nbGVQbGFjZW1lbnRzKSB7XG4gICAgICAgIGFsbFNlZ3MucHVzaChwbGFjZW1lbnQuc2VnKTtcbiAgICAgICAgaWYgKCFwbGFjZW1lbnQuaXNWaXNpYmxlKSB7XG4gICAgICAgICAgICBpbnZpc2libGVTZWdzLnB1c2gocGxhY2VtZW50LnNlZyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHsgYWxsU2VncywgaW52aXNpYmxlU2VncyB9O1xufVxuXG5jb25zdCBERUZBVUxUX1dFRUtfTlVNX0ZPUk1BVCA9IGNyZWF0ZUZvcm1hdHRlcih7IHdlZWs6ICduYXJyb3cnIH0pO1xuY2xhc3MgVGFibGVDZWxsIGV4dGVuZHMgRGF0ZUNvbXBvbmVudCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMucm9vdEVsUmVmID0gY3JlYXRlUmVmKCk7XG4gICAgICAgIHRoaXMuc3RhdGUgPSB7XG4gICAgICAgICAgICBkYXlOdW1iZXJJZDogZ2V0VW5pcXVlRG9tSWQoKSxcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5oYW5kbGVSb290RWwgPSAoZWwpID0+IHtcbiAgICAgICAgICAgIHNldFJlZih0aGlzLnJvb3RFbFJlZiwgZWwpO1xuICAgICAgICAgICAgc2V0UmVmKHRoaXMucHJvcHMuZWxSZWYsIGVsKTtcbiAgICAgICAgfTtcbiAgICB9XG4gICAgcmVuZGVyKCkge1xuICAgICAgICBsZXQgeyBjb250ZXh0LCBwcm9wcywgc3RhdGUsIHJvb3RFbFJlZiB9ID0gdGhpcztcbiAgICAgICAgbGV0IHsgb3B0aW9ucyB9ID0gY29udGV4dDtcbiAgICAgICAgbGV0IHsgZGF0ZSwgZGF0ZVByb2ZpbGUgfSA9IHByb3BzO1xuICAgICAgICByZXR1cm4gKGNyZWF0ZUVsZW1lbnQoRGF5Q2VsbENvbnRhaW5lciwgeyBlbFRhZzogXCJ0ZFwiLCBlbFJlZjogdGhpcy5oYW5kbGVSb290RWwsIGVsQ2xhc3NlczogW1xuICAgICAgICAgICAgICAgICdmYy1kYXlncmlkLWRheScsXG4gICAgICAgICAgICAgICAgLi4uKHByb3BzLmV4dHJhQ2xhc3NOYW1lcyB8fCBbXSksXG4gICAgICAgICAgICBdLCBlbEF0dHJzOiBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgcHJvcHMuZXh0cmFEYXRhQXR0cnMpLCAocHJvcHMuc2hvd0RheU51bWJlciA/IHsgJ2FyaWEtbGFiZWxsZWRieSc6IHN0YXRlLmRheU51bWJlcklkIH0gOiB7fSkpLCB7IHJvbGU6ICdncmlkY2VsbCcgfSksIGRlZmF1bHRHZW5lcmF0b3I6IHJlbmRlclRvcElubmVyLCBkYXRlOiBkYXRlLCBkYXRlUHJvZmlsZTogZGF0ZVByb2ZpbGUsIHRvZGF5UmFuZ2U6IHByb3BzLnRvZGF5UmFuZ2UsIHNob3dEYXlOdW1iZXI6IHByb3BzLnNob3dEYXlOdW1iZXIsIGV4dHJhUmVuZGVyUHJvcHM6IHByb3BzLmV4dHJhUmVuZGVyUHJvcHMgfSwgKElubmVyQ29udGVudCwgcmVuZGVyUHJvcHMpID0+IChjcmVhdGVFbGVtZW50KFwiZGl2XCIsIHsgY2xhc3NOYW1lOiBcImZjLWRheWdyaWQtZGF5LWZyYW1lIGZjLXNjcm9sbGdyaWQtc3luYy1pbm5lclwiLCByZWY6IHByb3BzLmlubmVyRWxSZWYgfSxcbiAgICAgICAgICAgIHByb3BzLnNob3dXZWVrTnVtYmVyICYmIChjcmVhdGVFbGVtZW50KFdlZWtOdW1iZXJDb250YWluZXIsIHsgZWxUYWc6IFwiYVwiLCBlbENsYXNzZXM6IFsnZmMtZGF5Z3JpZC13ZWVrLW51bWJlciddLCBlbEF0dHJzOiBidWlsZE5hdkxpbmtBdHRycyhjb250ZXh0LCBkYXRlLCAnd2VlaycpLCBkYXRlOiBkYXRlLCBkZWZhdWx0Rm9ybWF0OiBERUZBVUxUX1dFRUtfTlVNX0ZPUk1BVCB9KSksXG4gICAgICAgICAgICBCb29sZWFuKCFyZW5kZXJQcm9wcy5pc0Rpc2FibGVkICYmXG4gICAgICAgICAgICAgICAgKHByb3BzLnNob3dEYXlOdW1iZXIgfHwgaGFzQ3VzdG9tRGF5Q2VsbENvbnRlbnQob3B0aW9ucykgfHwgcHJvcHMuZm9yY2VEYXlUb3ApKSAmJiAoY3JlYXRlRWxlbWVudChcImRpdlwiLCB7IGNsYXNzTmFtZTogXCJmYy1kYXlncmlkLWRheS10b3BcIiB9LFxuICAgICAgICAgICAgICAgIGNyZWF0ZUVsZW1lbnQoSW5uZXJDb250ZW50LCB7IGVsVGFnOiBcImFcIiwgZWxDbGFzc2VzOiBbJ2ZjLWRheWdyaWQtZGF5LW51bWJlciddLCBlbEF0dHJzOiBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sIGJ1aWxkTmF2TGlua0F0dHJzKGNvbnRleHQsIGRhdGUpKSwgeyBpZDogc3RhdGUuZGF5TnVtYmVySWQgfSkgfSkpKSxcbiAgICAgICAgICAgIGNyZWF0ZUVsZW1lbnQoXCJkaXZcIiwgeyBjbGFzc05hbWU6IFwiZmMtZGF5Z3JpZC1kYXktZXZlbnRzXCIsIHJlZjogcHJvcHMuZmdDb250ZW50RWxSZWYgfSxcbiAgICAgICAgICAgICAgICBwcm9wcy5mZ0NvbnRlbnQsXG4gICAgICAgICAgICAgICAgY3JlYXRlRWxlbWVudChcImRpdlwiLCB7IGNsYXNzTmFtZTogXCJmYy1kYXlncmlkLWRheS1ib3R0b21cIiwgc3R5bGU6IHsgbWFyZ2luVG9wOiBwcm9wcy5tb3JlTWFyZ2luVG9wIH0gfSxcbiAgICAgICAgICAgICAgICAgICAgY3JlYXRlRWxlbWVudChUYWJsZUNlbGxNb3JlTGluaywgeyBhbGxEYXlEYXRlOiBkYXRlLCBzaW5nbGVQbGFjZW1lbnRzOiBwcm9wcy5zaW5nbGVQbGFjZW1lbnRzLCBtb3JlQ250OiBwcm9wcy5tb3JlQ250LCBhbGlnbm1lbnRFbFJlZjogcm9vdEVsUmVmLCBhbGlnbkdyaWRUb3A6ICFwcm9wcy5zaG93RGF5TnVtYmVyLCBleHRyYURhdGVTcGFuOiBwcm9wcy5leHRyYURhdGVTcGFuLCBkYXRlUHJvZmlsZTogcHJvcHMuZGF0ZVByb2ZpbGUsIGV2ZW50U2VsZWN0aW9uOiBwcm9wcy5ldmVudFNlbGVjdGlvbiwgZXZlbnREcmFnOiBwcm9wcy5ldmVudERyYWcsIGV2ZW50UmVzaXplOiBwcm9wcy5ldmVudFJlc2l6ZSwgdG9kYXlSYW5nZTogcHJvcHMudG9kYXlSYW5nZSB9KSkpLFxuICAgICAgICAgICAgY3JlYXRlRWxlbWVudChcImRpdlwiLCB7IGNsYXNzTmFtZTogXCJmYy1kYXlncmlkLWRheS1iZ1wiIH0sIHByb3BzLmJnQ29udGVudCkpKSkpO1xuICAgIH1cbn1cbmZ1bmN0aW9uIHJlbmRlclRvcElubmVyKHByb3BzKSB7XG4gICAgcmV0dXJuIHByb3BzLmRheU51bWJlclRleHQgfHwgY3JlYXRlRWxlbWVudChGcmFnbWVudCwgbnVsbCwgXCJcXHUwMEEwXCIpO1xufVxuXG5mdW5jdGlvbiBjb21wdXRlRmdTZWdQbGFjZW1lbnQoc2VncywgLy8gYXNzdW1lZCBhbHJlYWR5IHNvcnRlZFxuZGF5TWF4RXZlbnRzLCBkYXlNYXhFdmVudFJvd3MsIHN0cmljdE9yZGVyLCBldmVudEluc3RhbmNlSGVpZ2h0cywgbWF4Q29udGVudEhlaWdodCwgY2VsbHMpIHtcbiAgICBsZXQgaGllcmFyY2h5ID0gbmV3IERheUdyaWRTZWdIaWVyYXJjaHkoKTtcbiAgICBoaWVyYXJjaHkuYWxsb3dSZXNsaWNpbmcgPSB0cnVlO1xuICAgIGhpZXJhcmNoeS5zdHJpY3RPcmRlciA9IHN0cmljdE9yZGVyO1xuICAgIGlmIChkYXlNYXhFdmVudHMgPT09IHRydWUgfHwgZGF5TWF4RXZlbnRSb3dzID09PSB0cnVlKSB7XG4gICAgICAgIGhpZXJhcmNoeS5tYXhDb29yZCA9IG1heENvbnRlbnRIZWlnaHQ7XG4gICAgICAgIGhpZXJhcmNoeS5oaWRkZW5Db25zdW1lcyA9IHRydWU7XG4gICAgfVxuICAgIGVsc2UgaWYgKHR5cGVvZiBkYXlNYXhFdmVudHMgPT09ICdudW1iZXInKSB7XG4gICAgICAgIGhpZXJhcmNoeS5tYXhTdGFja0NudCA9IGRheU1heEV2ZW50cztcbiAgICB9XG4gICAgZWxzZSBpZiAodHlwZW9mIGRheU1heEV2ZW50Um93cyA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgaGllcmFyY2h5Lm1heFN0YWNrQ250ID0gZGF5TWF4RXZlbnRSb3dzO1xuICAgICAgICBoaWVyYXJjaHkuaGlkZGVuQ29uc3VtZXMgPSB0cnVlO1xuICAgIH1cbiAgICAvLyBjcmVhdGUgc2VnSW5wdXRzIG9ubHkgZm9yIHNlZ3Mgd2l0aCBrbm93biBoZWlnaHRzXG4gICAgbGV0IHNlZ0lucHV0cyA9IFtdO1xuICAgIGxldCB1bmtub3duSGVpZ2h0U2VncyA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2Vncy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICBsZXQgc2VnID0gc2Vnc1tpXTtcbiAgICAgICAgbGV0IHsgaW5zdGFuY2VJZCB9ID0gc2VnLmV2ZW50UmFuZ2UuaW5zdGFuY2U7XG4gICAgICAgIGxldCBldmVudEhlaWdodCA9IGV2ZW50SW5zdGFuY2VIZWlnaHRzW2luc3RhbmNlSWRdO1xuICAgICAgICBpZiAoZXZlbnRIZWlnaHQgIT0gbnVsbCkge1xuICAgICAgICAgICAgc2VnSW5wdXRzLnB1c2goe1xuICAgICAgICAgICAgICAgIGluZGV4OiBpLFxuICAgICAgICAgICAgICAgIHRoaWNrbmVzczogZXZlbnRIZWlnaHQsXG4gICAgICAgICAgICAgICAgc3Bhbjoge1xuICAgICAgICAgICAgICAgICAgICBzdGFydDogc2VnLmZpcnN0Q29sLFxuICAgICAgICAgICAgICAgICAgICBlbmQ6IHNlZy5sYXN0Q29sICsgMSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB1bmtub3duSGVpZ2h0U2Vncy5wdXNoKHNlZyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgbGV0IGhpZGRlbkVudHJpZXMgPSBoaWVyYXJjaHkuYWRkU2VncyhzZWdJbnB1dHMpO1xuICAgIGxldCBzZWdSZWN0cyA9IGhpZXJhcmNoeS50b1JlY3RzKCk7XG4gICAgbGV0IHsgc2luZ2xlQ29sUGxhY2VtZW50cywgbXVsdGlDb2xQbGFjZW1lbnRzLCBsZWZ0b3Zlck1hcmdpbnMgfSA9IHBsYWNlUmVjdHMoc2VnUmVjdHMsIHNlZ3MsIGNlbGxzKTtcbiAgICBsZXQgbW9yZUNudHMgPSBbXTtcbiAgICBsZXQgbW9yZU1hcmdpblRvcHMgPSBbXTtcbiAgICAvLyBhZGQgc2VncyB3aXRoIHVua25vd24gaGVpZ2h0c1xuICAgIGZvciAobGV0IHNlZyBvZiB1bmtub3duSGVpZ2h0U2Vncykge1xuICAgICAgICBtdWx0aUNvbFBsYWNlbWVudHNbc2VnLmZpcnN0Q29sXS5wdXNoKHtcbiAgICAgICAgICAgIHNlZyxcbiAgICAgICAgICAgIGlzVmlzaWJsZTogZmFsc2UsXG4gICAgICAgICAgICBpc0Fic29sdXRlOiB0cnVlLFxuICAgICAgICAgICAgYWJzb2x1dGVUb3A6IDAsXG4gICAgICAgICAgICBtYXJnaW5Ub3A6IDAsXG4gICAgICAgIH0pO1xuICAgICAgICBmb3IgKGxldCBjb2wgPSBzZWcuZmlyc3RDb2w7IGNvbCA8PSBzZWcubGFzdENvbDsgY29sICs9IDEpIHtcbiAgICAgICAgICAgIHNpbmdsZUNvbFBsYWNlbWVudHNbY29sXS5wdXNoKHtcbiAgICAgICAgICAgICAgICBzZWc6IHJlc2xpY2VTZWcoc2VnLCBjb2wsIGNvbCArIDEsIGNlbGxzKSxcbiAgICAgICAgICAgICAgICBpc1Zpc2libGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGlzQWJzb2x1dGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGFic29sdXRlVG9wOiAwLFxuICAgICAgICAgICAgICAgIG1hcmdpblRvcDogMCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8vIGFkZCB0aGUgaGlkZGVuIGVudHJpZXNcbiAgICBmb3IgKGxldCBjb2wgPSAwOyBjb2wgPCBjZWxscy5sZW5ndGg7IGNvbCArPSAxKSB7XG4gICAgICAgIG1vcmVDbnRzLnB1c2goMCk7XG4gICAgfVxuICAgIGZvciAobGV0IGhpZGRlbkVudHJ5IG9mIGhpZGRlbkVudHJpZXMpIHtcbiAgICAgICAgbGV0IHNlZyA9IHNlZ3NbaGlkZGVuRW50cnkuaW5kZXhdO1xuICAgICAgICBsZXQgaGlkZGVuU3BhbiA9IGhpZGRlbkVudHJ5LnNwYW47XG4gICAgICAgIG11bHRpQ29sUGxhY2VtZW50c1toaWRkZW5TcGFuLnN0YXJ0XS5wdXNoKHtcbiAgICAgICAgICAgIHNlZzogcmVzbGljZVNlZyhzZWcsIGhpZGRlblNwYW4uc3RhcnQsIGhpZGRlblNwYW4uZW5kLCBjZWxscyksXG4gICAgICAgICAgICBpc1Zpc2libGU6IGZhbHNlLFxuICAgICAgICAgICAgaXNBYnNvbHV0ZTogdHJ1ZSxcbiAgICAgICAgICAgIGFic29sdXRlVG9wOiAwLFxuICAgICAgICAgICAgbWFyZ2luVG9wOiAwLFxuICAgICAgICB9KTtcbiAgICAgICAgZm9yIChsZXQgY29sID0gaGlkZGVuU3Bhbi5zdGFydDsgY29sIDwgaGlkZGVuU3Bhbi5lbmQ7IGNvbCArPSAxKSB7XG4gICAgICAgICAgICBtb3JlQ250c1tjb2xdICs9IDE7XG4gICAgICAgICAgICBzaW5nbGVDb2xQbGFjZW1lbnRzW2NvbF0ucHVzaCh7XG4gICAgICAgICAgICAgICAgc2VnOiByZXNsaWNlU2VnKHNlZywgY29sLCBjb2wgKyAxLCBjZWxscyksXG4gICAgICAgICAgICAgICAgaXNWaXNpYmxlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBpc0Fic29sdXRlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBhYnNvbHV0ZVRvcDogMCxcbiAgICAgICAgICAgICAgICBtYXJnaW5Ub3A6IDAsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICAvLyBkZWFsIHdpdGggbGVmdG92ZXIgbWFyZ2luc1xuICAgIGZvciAobGV0IGNvbCA9IDA7IGNvbCA8IGNlbGxzLmxlbmd0aDsgY29sICs9IDEpIHtcbiAgICAgICAgbW9yZU1hcmdpblRvcHMucHVzaChsZWZ0b3Zlck1hcmdpbnNbY29sXSk7XG4gICAgfVxuICAgIHJldHVybiB7IHNpbmdsZUNvbFBsYWNlbWVudHMsIG11bHRpQ29sUGxhY2VtZW50cywgbW9yZUNudHMsIG1vcmVNYXJnaW5Ub3BzIH07XG59XG4vLyByZWN0cyBvcmRlcmVkIGJ5IHRvcCBjb29yZCwgdGhlbiBsZWZ0XG5mdW5jdGlvbiBwbGFjZVJlY3RzKGFsbFJlY3RzLCBzZWdzLCBjZWxscykge1xuICAgIGxldCByZWN0c0J5RWFjaENvbCA9IGdyb3VwUmVjdHNCeUVhY2hDb2woYWxsUmVjdHMsIGNlbGxzLmxlbmd0aCk7XG4gICAgbGV0IHNpbmdsZUNvbFBsYWNlbWVudHMgPSBbXTtcbiAgICBsZXQgbXVsdGlDb2xQbGFjZW1lbnRzID0gW107XG4gICAgbGV0IGxlZnRvdmVyTWFyZ2lucyA9IFtdO1xuICAgIGZvciAobGV0IGNvbCA9IDA7IGNvbCA8IGNlbGxzLmxlbmd0aDsgY29sICs9IDEpIHtcbiAgICAgICAgbGV0IHJlY3RzID0gcmVjdHNCeUVhY2hDb2xbY29sXTtcbiAgICAgICAgLy8gY29tcHV0ZSBhbGwgc3RhdGljIHNlZ3MgaW4gc2luZ2xlUGxhY2VtZW50c1xuICAgICAgICBsZXQgc2luZ2xlUGxhY2VtZW50cyA9IFtdO1xuICAgICAgICBsZXQgY3VycmVudEhlaWdodCA9IDA7XG4gICAgICAgIGxldCBjdXJyZW50TWFyZ2luVG9wID0gMDtcbiAgICAgICAgZm9yIChsZXQgcmVjdCBvZiByZWN0cykge1xuICAgICAgICAgICAgbGV0IHNlZyA9IHNlZ3NbcmVjdC5pbmRleF07XG4gICAgICAgICAgICBzaW5nbGVQbGFjZW1lbnRzLnB1c2goe1xuICAgICAgICAgICAgICAgIHNlZzogcmVzbGljZVNlZyhzZWcsIGNvbCwgY29sICsgMSwgY2VsbHMpLFxuICAgICAgICAgICAgICAgIGlzVmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBpc0Fic29sdXRlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBhYnNvbHV0ZVRvcDogcmVjdC5sZXZlbENvb3JkLFxuICAgICAgICAgICAgICAgIG1hcmdpblRvcDogcmVjdC5sZXZlbENvb3JkIC0gY3VycmVudEhlaWdodCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgY3VycmVudEhlaWdodCA9IHJlY3QubGV2ZWxDb29yZCArIHJlY3QudGhpY2tuZXNzO1xuICAgICAgICB9XG4gICAgICAgIC8vIGNvbXB1dGUgbWl4ZWQgc3RhdGljL2Fic29sdXRlIHNlZ3MgaW4gbXVsdGlQbGFjZW1lbnRzXG4gICAgICAgIGxldCBtdWx0aVBsYWNlbWVudHMgPSBbXTtcbiAgICAgICAgY3VycmVudEhlaWdodCA9IDA7XG4gICAgICAgIGN1cnJlbnRNYXJnaW5Ub3AgPSAwO1xuICAgICAgICBmb3IgKGxldCByZWN0IG9mIHJlY3RzKSB7XG4gICAgICAgICAgICBsZXQgc2VnID0gc2Vnc1tyZWN0LmluZGV4XTtcbiAgICAgICAgICAgIGxldCBpc0Fic29sdXRlID0gcmVjdC5zcGFuLmVuZCAtIHJlY3Quc3Bhbi5zdGFydCA+IDE7IC8vIG11bHRpLWNvbHVtbj9cbiAgICAgICAgICAgIGxldCBpc0ZpcnN0Q29sID0gcmVjdC5zcGFuLnN0YXJ0ID09PSBjb2w7XG4gICAgICAgICAgICBjdXJyZW50TWFyZ2luVG9wICs9IHJlY3QubGV2ZWxDb29yZCAtIGN1cnJlbnRIZWlnaHQ7IC8vIGFtb3VudCBvZiBzcGFjZSBzaW5jZSBib3R0b20gb2YgcHJldmlvdXMgc2VnXG4gICAgICAgICAgICBjdXJyZW50SGVpZ2h0ID0gcmVjdC5sZXZlbENvb3JkICsgcmVjdC50aGlja25lc3M7IC8vIGhlaWdodCB3aWxsIG5vdyBiZSBib3R0b20gb2YgY3VycmVudCBzZWdcbiAgICAgICAgICAgIGlmIChpc0Fic29sdXRlKSB7XG4gICAgICAgICAgICAgICAgY3VycmVudE1hcmdpblRvcCArPSByZWN0LnRoaWNrbmVzcztcbiAgICAgICAgICAgICAgICBpZiAoaXNGaXJzdENvbCkge1xuICAgICAgICAgICAgICAgICAgICBtdWx0aVBsYWNlbWVudHMucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZWc6IHJlc2xpY2VTZWcoc2VnLCByZWN0LnNwYW4uc3RhcnQsIHJlY3Quc3Bhbi5lbmQsIGNlbGxzKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGlzVmlzaWJsZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGlzQWJzb2x1dGU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBhYnNvbHV0ZVRvcDogcmVjdC5sZXZlbENvb3JkLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWFyZ2luVG9wOiAwLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChpc0ZpcnN0Q29sKSB7XG4gICAgICAgICAgICAgICAgbXVsdGlQbGFjZW1lbnRzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICBzZWc6IHJlc2xpY2VTZWcoc2VnLCByZWN0LnNwYW4uc3RhcnQsIHJlY3Quc3Bhbi5lbmQsIGNlbGxzKSxcbiAgICAgICAgICAgICAgICAgICAgaXNWaXNpYmxlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBpc0Fic29sdXRlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgYWJzb2x1dGVUb3A6IHJlY3QubGV2ZWxDb29yZCxcbiAgICAgICAgICAgICAgICAgICAgbWFyZ2luVG9wOiBjdXJyZW50TWFyZ2luVG9wLCAvLyBjbGFpbSB0aGUgbWFyZ2luXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgY3VycmVudE1hcmdpblRvcCA9IDA7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgc2luZ2xlQ29sUGxhY2VtZW50cy5wdXNoKHNpbmdsZVBsYWNlbWVudHMpO1xuICAgICAgICBtdWx0aUNvbFBsYWNlbWVudHMucHVzaChtdWx0aVBsYWNlbWVudHMpO1xuICAgICAgICBsZWZ0b3Zlck1hcmdpbnMucHVzaChjdXJyZW50TWFyZ2luVG9wKTtcbiAgICB9XG4gICAgcmV0dXJuIHsgc2luZ2xlQ29sUGxhY2VtZW50cywgbXVsdGlDb2xQbGFjZW1lbnRzLCBsZWZ0b3Zlck1hcmdpbnMgfTtcbn1cbmZ1bmN0aW9uIGdyb3VwUmVjdHNCeUVhY2hDb2wocmVjdHMsIGNvbENudCkge1xuICAgIGxldCByZWN0c0J5RWFjaENvbCA9IFtdO1xuICAgIGZvciAobGV0IGNvbCA9IDA7IGNvbCA8IGNvbENudDsgY29sICs9IDEpIHtcbiAgICAgICAgcmVjdHNCeUVhY2hDb2wucHVzaChbXSk7XG4gICAgfVxuICAgIGZvciAobGV0IHJlY3Qgb2YgcmVjdHMpIHtcbiAgICAgICAgZm9yIChsZXQgY29sID0gcmVjdC5zcGFuLnN0YXJ0OyBjb2wgPCByZWN0LnNwYW4uZW5kOyBjb2wgKz0gMSkge1xuICAgICAgICAgICAgcmVjdHNCeUVhY2hDb2xbY29sXS5wdXNoKHJlY3QpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZWN0c0J5RWFjaENvbDtcbn1cbmZ1bmN0aW9uIHJlc2xpY2VTZWcoc2VnLCBzcGFuU3RhcnQsIHNwYW5FbmQsIGNlbGxzKSB7XG4gICAgaWYgKHNlZy5maXJzdENvbCA9PT0gc3BhblN0YXJ0ICYmIHNlZy5sYXN0Q29sID09PSBzcGFuRW5kIC0gMSkge1xuICAgICAgICByZXR1cm4gc2VnO1xuICAgIH1cbiAgICBsZXQgZXZlbnRSYW5nZSA9IHNlZy5ldmVudFJhbmdlO1xuICAgIGxldCBvcmlnUmFuZ2UgPSBldmVudFJhbmdlLnJhbmdlO1xuICAgIGxldCBzbGljZWRSYW5nZSA9IGludGVyc2VjdFJhbmdlcyhvcmlnUmFuZ2UsIHtcbiAgICAgICAgc3RhcnQ6IGNlbGxzW3NwYW5TdGFydF0uZGF0ZSxcbiAgICAgICAgZW5kOiBhZGREYXlzKGNlbGxzW3NwYW5FbmQgLSAxXS5kYXRlLCAxKSxcbiAgICB9KTtcbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCBzZWcpLCB7IGZpcnN0Q29sOiBzcGFuU3RhcnQsIGxhc3RDb2w6IHNwYW5FbmQgLSAxLCBldmVudFJhbmdlOiB7XG4gICAgICAgICAgICBkZWY6IGV2ZW50UmFuZ2UuZGVmLFxuICAgICAgICAgICAgdWk6IE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgZXZlbnRSYW5nZS51aSksIHsgZHVyYXRpb25FZGl0YWJsZTogZmFsc2UgfSksXG4gICAgICAgICAgICBpbnN0YW5jZTogZXZlbnRSYW5nZS5pbnN0YW5jZSxcbiAgICAgICAgICAgIHJhbmdlOiBzbGljZWRSYW5nZSxcbiAgICAgICAgfSwgaXNTdGFydDogc2VnLmlzU3RhcnQgJiYgc2xpY2VkUmFuZ2Uuc3RhcnQudmFsdWVPZigpID09PSBvcmlnUmFuZ2Uuc3RhcnQudmFsdWVPZigpLCBpc0VuZDogc2VnLmlzRW5kICYmIHNsaWNlZFJhbmdlLmVuZC52YWx1ZU9mKCkgPT09IG9yaWdSYW5nZS5lbmQudmFsdWVPZigpIH0pO1xufVxuY2xhc3MgRGF5R3JpZFNlZ0hpZXJhcmNoeSBleHRlbmRzIFNlZ0hpZXJhcmNoeSB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIC8vIGNvbmZpZ1xuICAgICAgICB0aGlzLmhpZGRlbkNvbnN1bWVzID0gZmFsc2U7XG4gICAgICAgIC8vIGFsbG93cyB1cyB0byBrZWVwIGhpZGRlbiBlbnRyaWVzIGluIHRoZSBoaWVyYXJjaHkgc28gdGhleSB0YWtlIHVwIHNwYWNlXG4gICAgICAgIHRoaXMuZm9yY2VIaWRkZW4gPSB7fTtcbiAgICB9XG4gICAgYWRkU2VncyhzZWdJbnB1dHMpIHtcbiAgICAgICAgY29uc3QgaGlkZGVuU2VncyA9IHN1cGVyLmFkZFNlZ3Moc2VnSW5wdXRzKTtcbiAgICAgICAgY29uc3QgeyBlbnRyaWVzQnlMZXZlbCB9ID0gdGhpcztcbiAgICAgICAgY29uc3QgZXhjbHVkZUhpZGRlbiA9IChlbnRyeSkgPT4gIXRoaXMuZm9yY2VIaWRkZW5bYnVpbGRFbnRyeUtleShlbnRyeSldO1xuICAgICAgICAvLyByZW1vdmUgdGhlIGZvcmNlZC1oaWRkZW4gc2Vnc1xuICAgICAgICBmb3IgKGxldCBsZXZlbCA9IDA7IGxldmVsIDwgZW50cmllc0J5TGV2ZWwubGVuZ3RoOyBsZXZlbCArPSAxKSB7XG4gICAgICAgICAgICBlbnRyaWVzQnlMZXZlbFtsZXZlbF0gPSBlbnRyaWVzQnlMZXZlbFtsZXZlbF0uZmlsdGVyKGV4Y2x1ZGVIaWRkZW4pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBoaWRkZW5TZWdzO1xuICAgIH1cbiAgICBoYW5kbGVJbnZhbGlkSW5zZXJ0aW9uKGluc2VydGlvbiwgZW50cnksIGhpZGRlbkVudHJpZXMpIHtcbiAgICAgICAgY29uc3QgeyBlbnRyaWVzQnlMZXZlbCwgZm9yY2VIaWRkZW4gfSA9IHRoaXM7XG4gICAgICAgIGNvbnN0IHsgdG91Y2hpbmdFbnRyeSwgdG91Y2hpbmdMZXZlbCwgdG91Y2hpbmdMYXRlcmFsIH0gPSBpbnNlcnRpb247XG4gICAgICAgIGlmICh0aGlzLmhpZGRlbkNvbnN1bWVzICYmIHRvdWNoaW5nRW50cnkpIHtcbiAgICAgICAgICAgIGNvbnN0IHRvdWNoaW5nRW50cnlJZCA9IGJ1aWxkRW50cnlLZXkodG91Y2hpbmdFbnRyeSk7XG4gICAgICAgICAgICAvLyBpZiBub3QgYWxyZWFkeSBoaWRkZW5cbiAgICAgICAgICAgIGlmICghZm9yY2VIaWRkZW5bdG91Y2hpbmdFbnRyeUlkXSkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmFsbG93UmVzbGljaW5nKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHBsYWNlaG9sZGVyRW50cnkgPSBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sIHRvdWNoaW5nRW50cnkpLCB7IHNwYW46IGludGVyc2VjdFNwYW5zKHRvdWNoaW5nRW50cnkuc3BhbiwgZW50cnkuc3BhbikgfSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHBsYWNlaG9sZGVyRW50cnlJZCA9IGJ1aWxkRW50cnlLZXkocGxhY2Vob2xkZXJFbnRyeSk7XG4gICAgICAgICAgICAgICAgICAgIGZvcmNlSGlkZGVuW3BsYWNlaG9sZGVyRW50cnlJZF0gPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICBlbnRyaWVzQnlMZXZlbFt0b3VjaGluZ0xldmVsXVt0b3VjaGluZ0xhdGVyYWxdID0gcGxhY2Vob2xkZXJFbnRyeTsgLy8gcmVwbGFjZSB0b3VjaGluZ0VudHJ5IHdpdGggb3VyIHBsYWNlaG9sZGVyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3BsaXRFbnRyeSh0b3VjaGluZ0VudHJ5LCBlbnRyeSwgaGlkZGVuRW50cmllcyk7IC8vIHNwbGl0IHVwIHRoZSB0b3VjaGluZ0VudHJ5LCByZWluc2VydCBpdFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZm9yY2VIaWRkZW5bdG91Y2hpbmdFbnRyeUlkXSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIGhpZGRlbkVudHJpZXMucHVzaCh0b3VjaGluZ0VudHJ5KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHN1cGVyLmhhbmRsZUludmFsaWRJbnNlcnRpb24oaW5zZXJ0aW9uLCBlbnRyeSwgaGlkZGVuRW50cmllcyk7XG4gICAgfVxufVxuXG5jbGFzcyBUYWJsZVJvdyBleHRlbmRzIERhdGVDb21wb25lbnQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLmNlbGxFbFJlZnMgPSBuZXcgUmVmTWFwKCk7IC8vIHRoZSA8dGQ+XG4gICAgICAgIHRoaXMuZnJhbWVFbFJlZnMgPSBuZXcgUmVmTWFwKCk7IC8vIHRoZSBmYy1kYXlncmlkLWRheS1mcmFtZVxuICAgICAgICB0aGlzLmZnRWxSZWZzID0gbmV3IFJlZk1hcCgpOyAvLyB0aGUgZmMtZGF5Z3JpZC1kYXktZXZlbnRzXG4gICAgICAgIHRoaXMuc2VnSGFybmVzc1JlZnMgPSBuZXcgUmVmTWFwKCk7IC8vIGluZGV4ZWQgYnkgXCJpbnN0YW5jZUlkOmZpcnN0Q29sXCJcbiAgICAgICAgdGhpcy5yb290RWxSZWYgPSBjcmVhdGVSZWYoKTtcbiAgICAgICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgICAgICAgIGZyYW1lUG9zaXRpb25zOiBudWxsLFxuICAgICAgICAgICAgbWF4Q29udGVudEhlaWdodDogbnVsbCxcbiAgICAgICAgICAgIGV2ZW50SW5zdGFuY2VIZWlnaHRzOiB7fSxcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5oYW5kbGVSZXNpemUgPSAoaXNGb3JjZWQpID0+IHtcbiAgICAgICAgICAgIGlmIChpc0ZvcmNlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlU2l6aW5nKHRydWUpOyAvLyBpc0V4dGVybmFsPXRydWVcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9XG4gICAgcmVuZGVyKCkge1xuICAgICAgICBsZXQgeyBwcm9wcywgc3RhdGUsIGNvbnRleHQgfSA9IHRoaXM7XG4gICAgICAgIGxldCB7IG9wdGlvbnMgfSA9IGNvbnRleHQ7XG4gICAgICAgIGxldCBjb2xDbnQgPSBwcm9wcy5jZWxscy5sZW5ndGg7XG4gICAgICAgIGxldCBidXNpbmVzc0hvdXJzQnlDb2wgPSBzcGxpdFNlZ3NCeUZpcnN0Q29sKHByb3BzLmJ1c2luZXNzSG91clNlZ3MsIGNvbENudCk7XG4gICAgICAgIGxldCBiZ0V2ZW50U2Vnc0J5Q29sID0gc3BsaXRTZWdzQnlGaXJzdENvbChwcm9wcy5iZ0V2ZW50U2VncywgY29sQ250KTtcbiAgICAgICAgbGV0IGhpZ2hsaWdodFNlZ3NCeUNvbCA9IHNwbGl0U2Vnc0J5Rmlyc3RDb2wodGhpcy5nZXRIaWdobGlnaHRTZWdzKCksIGNvbENudCk7XG4gICAgICAgIGxldCBtaXJyb3JTZWdzQnlDb2wgPSBzcGxpdFNlZ3NCeUZpcnN0Q29sKHRoaXMuZ2V0TWlycm9yU2VncygpLCBjb2xDbnQpO1xuICAgICAgICBsZXQgeyBzaW5nbGVDb2xQbGFjZW1lbnRzLCBtdWx0aUNvbFBsYWNlbWVudHMsIG1vcmVDbnRzLCBtb3JlTWFyZ2luVG9wcyB9ID0gY29tcHV0ZUZnU2VnUGxhY2VtZW50KHNvcnRFdmVudFNlZ3MocHJvcHMuZmdFdmVudFNlZ3MsIG9wdGlvbnMuZXZlbnRPcmRlciksIHByb3BzLmRheU1heEV2ZW50cywgcHJvcHMuZGF5TWF4RXZlbnRSb3dzLCBvcHRpb25zLmV2ZW50T3JkZXJTdHJpY3QsIHN0YXRlLmV2ZW50SW5zdGFuY2VIZWlnaHRzLCBzdGF0ZS5tYXhDb250ZW50SGVpZ2h0LCBwcm9wcy5jZWxscyk7XG4gICAgICAgIGxldCBpc0ZvcmNlZEludmlzaWJsZSA9IC8vIFRPRE86IG1lc3N5IHdheSB0byBjb21wdXRlIHRoaXNcbiAgICAgICAgIChwcm9wcy5ldmVudERyYWcgJiYgcHJvcHMuZXZlbnREcmFnLmFmZmVjdGVkSW5zdGFuY2VzKSB8fFxuICAgICAgICAgICAgKHByb3BzLmV2ZW50UmVzaXplICYmIHByb3BzLmV2ZW50UmVzaXplLmFmZmVjdGVkSW5zdGFuY2VzKSB8fFxuICAgICAgICAgICAge307XG4gICAgICAgIHJldHVybiAoY3JlYXRlRWxlbWVudChcInRyXCIsIHsgcmVmOiB0aGlzLnJvb3RFbFJlZiwgcm9sZTogXCJyb3dcIiB9LFxuICAgICAgICAgICAgcHJvcHMucmVuZGVySW50cm8gJiYgcHJvcHMucmVuZGVySW50cm8oKSxcbiAgICAgICAgICAgIHByb3BzLmNlbGxzLm1hcCgoY2VsbCwgY29sKSA9PiB7XG4gICAgICAgICAgICAgICAgbGV0IG5vcm1hbEZnTm9kZXMgPSB0aGlzLnJlbmRlckZnU2Vncyhjb2wsIHByb3BzLmZvclByaW50ID8gc2luZ2xlQ29sUGxhY2VtZW50c1tjb2xdIDogbXVsdGlDb2xQbGFjZW1lbnRzW2NvbF0sIHByb3BzLnRvZGF5UmFuZ2UsIGlzRm9yY2VkSW52aXNpYmxlKTtcbiAgICAgICAgICAgICAgICBsZXQgbWlycm9yRmdOb2RlcyA9IHRoaXMucmVuZGVyRmdTZWdzKGNvbCwgYnVpbGRNaXJyb3JQbGFjZW1lbnRzKG1pcnJvclNlZ3NCeUNvbFtjb2xdLCBtdWx0aUNvbFBsYWNlbWVudHMpLCBwcm9wcy50b2RheVJhbmdlLCB7fSwgQm9vbGVhbihwcm9wcy5ldmVudERyYWcpLCBCb29sZWFuKHByb3BzLmV2ZW50UmVzaXplKSwgZmFsc2UpO1xuICAgICAgICAgICAgICAgIHJldHVybiAoY3JlYXRlRWxlbWVudChUYWJsZUNlbGwsIHsga2V5OiBjZWxsLmtleSwgZWxSZWY6IHRoaXMuY2VsbEVsUmVmcy5jcmVhdGVSZWYoY2VsbC5rZXkpLCBpbm5lckVsUmVmOiB0aGlzLmZyYW1lRWxSZWZzLmNyZWF0ZVJlZihjZWxsLmtleSkgLyogRkYgPHRkPiBwcm9ibGVtLCBidXQgb2theSB0byB1c2UgZm9yIGxlZnQvcmlnaHQuIFRPRE86IHJlbmFtZSBwcm9wICovLCBkYXRlUHJvZmlsZTogcHJvcHMuZGF0ZVByb2ZpbGUsIGRhdGU6IGNlbGwuZGF0ZSwgc2hvd0RheU51bWJlcjogcHJvcHMuc2hvd0RheU51bWJlcnMsIHNob3dXZWVrTnVtYmVyOiBwcm9wcy5zaG93V2Vla051bWJlcnMgJiYgY29sID09PSAwLCBmb3JjZURheVRvcDogcHJvcHMuc2hvd1dlZWtOdW1iZXJzIC8qIGV2ZW4gZGlzcGxheWluZyB3ZWVrbnVtIGZvciByb3csIG5vdCBuZWNlc3NhcmlseSBkYXkgKi8sIHRvZGF5UmFuZ2U6IHByb3BzLnRvZGF5UmFuZ2UsIGV2ZW50U2VsZWN0aW9uOiBwcm9wcy5ldmVudFNlbGVjdGlvbiwgZXZlbnREcmFnOiBwcm9wcy5ldmVudERyYWcsIGV2ZW50UmVzaXplOiBwcm9wcy5ldmVudFJlc2l6ZSwgZXh0cmFSZW5kZXJQcm9wczogY2VsbC5leHRyYVJlbmRlclByb3BzLCBleHRyYURhdGFBdHRyczogY2VsbC5leHRyYURhdGFBdHRycywgZXh0cmFDbGFzc05hbWVzOiBjZWxsLmV4dHJhQ2xhc3NOYW1lcywgZXh0cmFEYXRlU3BhbjogY2VsbC5leHRyYURhdGVTcGFuLCBtb3JlQ250OiBtb3JlQ250c1tjb2xdLCBtb3JlTWFyZ2luVG9wOiBtb3JlTWFyZ2luVG9wc1tjb2xdLCBzaW5nbGVQbGFjZW1lbnRzOiBzaW5nbGVDb2xQbGFjZW1lbnRzW2NvbF0sIGZnQ29udGVudEVsUmVmOiB0aGlzLmZnRWxSZWZzLmNyZWF0ZVJlZihjZWxsLmtleSksIGZnQ29udGVudDogKCAvLyBGcmFnbWVudCBzY29wZXMgdGhlIGtleXNcbiAgICAgICAgICAgICAgICAgICAgY3JlYXRlRWxlbWVudChGcmFnbWVudCwgbnVsbCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNyZWF0ZUVsZW1lbnQoRnJhZ21lbnQsIG51bGwsIG5vcm1hbEZnTm9kZXMpLFxuICAgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlRWxlbWVudChGcmFnbWVudCwgbnVsbCwgbWlycm9yRmdOb2RlcykpKSwgYmdDb250ZW50OiAoIC8vIEZyYWdtZW50IHNjb3BlcyB0aGUga2V5c1xuICAgICAgICAgICAgICAgICAgICBjcmVhdGVFbGVtZW50KEZyYWdtZW50LCBudWxsLFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJGaWxsU2VncyhoaWdobGlnaHRTZWdzQnlDb2xbY29sXSwgJ2hpZ2hsaWdodCcpLFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJGaWxsU2VncyhidXNpbmVzc0hvdXJzQnlDb2xbY29sXSwgJ25vbi1idXNpbmVzcycpLFxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJGaWxsU2VncyhiZ0V2ZW50U2Vnc0J5Q29sW2NvbF0sICdiZy1ldmVudCcpKSkgfSkpO1xuICAgICAgICAgICAgfSkpKTtcbiAgICB9XG4gICAgY29tcG9uZW50RGlkTW91bnQoKSB7XG4gICAgICAgIHRoaXMudXBkYXRlU2l6aW5nKHRydWUpO1xuICAgICAgICB0aGlzLmNvbnRleHQuYWRkUmVzaXplSGFuZGxlcih0aGlzLmhhbmRsZVJlc2l6ZSk7XG4gICAgfVxuICAgIGNvbXBvbmVudERpZFVwZGF0ZShwcmV2UHJvcHMsIHByZXZTdGF0ZSkge1xuICAgICAgICBsZXQgY3VycmVudFByb3BzID0gdGhpcy5wcm9wcztcbiAgICAgICAgdGhpcy51cGRhdGVTaXppbmcoIWlzUHJvcHNFcXVhbChwcmV2UHJvcHMsIGN1cnJlbnRQcm9wcykpO1xuICAgIH1cbiAgICBjb21wb25lbnRXaWxsVW5tb3VudCgpIHtcbiAgICAgICAgdGhpcy5jb250ZXh0LnJlbW92ZVJlc2l6ZUhhbmRsZXIodGhpcy5oYW5kbGVSZXNpemUpO1xuICAgIH1cbiAgICBnZXRIaWdobGlnaHRTZWdzKCkge1xuICAgICAgICBsZXQgeyBwcm9wcyB9ID0gdGhpcztcbiAgICAgICAgaWYgKHByb3BzLmV2ZW50RHJhZyAmJiBwcm9wcy5ldmVudERyYWcuc2Vncy5sZW5ndGgpIHsgLy8gbWVzc3kgY2hlY2tcbiAgICAgICAgICAgIHJldHVybiBwcm9wcy5ldmVudERyYWcuc2VncztcbiAgICAgICAgfVxuICAgICAgICBpZiAocHJvcHMuZXZlbnRSZXNpemUgJiYgcHJvcHMuZXZlbnRSZXNpemUuc2Vncy5sZW5ndGgpIHsgLy8gbWVzc3kgY2hlY2tcbiAgICAgICAgICAgIHJldHVybiBwcm9wcy5ldmVudFJlc2l6ZS5zZWdzO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBwcm9wcy5kYXRlU2VsZWN0aW9uU2VncztcbiAgICB9XG4gICAgZ2V0TWlycm9yU2VncygpIHtcbiAgICAgICAgbGV0IHsgcHJvcHMgfSA9IHRoaXM7XG4gICAgICAgIGlmIChwcm9wcy5ldmVudFJlc2l6ZSAmJiBwcm9wcy5ldmVudFJlc2l6ZS5zZWdzLmxlbmd0aCkgeyAvLyBtZXNzeSBjaGVja1xuICAgICAgICAgICAgcmV0dXJuIHByb3BzLmV2ZW50UmVzaXplLnNlZ3M7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFtdO1xuICAgIH1cbiAgICByZW5kZXJGZ1NlZ3MoY29sLCBzZWdQbGFjZW1lbnRzLCB0b2RheVJhbmdlLCBpc0ZvcmNlZEludmlzaWJsZSwgaXNEcmFnZ2luZywgaXNSZXNpemluZywgaXNEYXRlU2VsZWN0aW5nKSB7XG4gICAgICAgIGxldCB7IGNvbnRleHQgfSA9IHRoaXM7XG4gICAgICAgIGxldCB7IGV2ZW50U2VsZWN0aW9uIH0gPSB0aGlzLnByb3BzO1xuICAgICAgICBsZXQgeyBmcmFtZVBvc2l0aW9ucyB9ID0gdGhpcy5zdGF0ZTtcbiAgICAgICAgbGV0IGRlZmF1bHREaXNwbGF5RXZlbnRFbmQgPSB0aGlzLnByb3BzLmNlbGxzLmxlbmd0aCA9PT0gMTsgLy8gY29sQ250ID09PSAxXG4gICAgICAgIGxldCBpc01pcnJvciA9IGlzRHJhZ2dpbmcgfHwgaXNSZXNpemluZyB8fCBpc0RhdGVTZWxlY3Rpbmc7XG4gICAgICAgIGxldCBub2RlcyA9IFtdO1xuICAgICAgICBpZiAoZnJhbWVQb3NpdGlvbnMpIHtcbiAgICAgICAgICAgIGZvciAobGV0IHBsYWNlbWVudCBvZiBzZWdQbGFjZW1lbnRzKSB7XG4gICAgICAgICAgICAgICAgbGV0IHsgc2VnIH0gPSBwbGFjZW1lbnQ7XG4gICAgICAgICAgICAgICAgbGV0IHsgaW5zdGFuY2VJZCB9ID0gc2VnLmV2ZW50UmFuZ2UuaW5zdGFuY2U7XG4gICAgICAgICAgICAgICAgbGV0IGtleSA9IGluc3RhbmNlSWQgKyAnOicgKyBjb2w7XG4gICAgICAgICAgICAgICAgbGV0IGlzVmlzaWJsZSA9IHBsYWNlbWVudC5pc1Zpc2libGUgJiYgIWlzRm9yY2VkSW52aXNpYmxlW2luc3RhbmNlSWRdO1xuICAgICAgICAgICAgICAgIGxldCBpc0Fic29sdXRlID0gcGxhY2VtZW50LmlzQWJzb2x1dGU7XG4gICAgICAgICAgICAgICAgbGV0IGxlZnQgPSAnJztcbiAgICAgICAgICAgICAgICBsZXQgcmlnaHQgPSAnJztcbiAgICAgICAgICAgICAgICBpZiAoaXNBYnNvbHV0ZSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoY29udGV4dC5pc1J0bCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmlnaHQgPSAwO1xuICAgICAgICAgICAgICAgICAgICAgICAgbGVmdCA9IGZyYW1lUG9zaXRpb25zLmxlZnRzW3NlZy5sYXN0Q29sXSAtIGZyYW1lUG9zaXRpb25zLmxlZnRzW3NlZy5maXJzdENvbF07XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZWZ0ID0gMDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJpZ2h0ID0gZnJhbWVQb3NpdGlvbnMucmlnaHRzW3NlZy5maXJzdENvbF0gLSBmcmFtZVBvc2l0aW9ucy5yaWdodHNbc2VnLmxhc3RDb2xdO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8qXG4gICAgICAgICAgICAgICAga25vd24gYnVnOiBldmVudHMgdGhhdCBhcmUgZm9yY2UgdG8gYmUgbGlzdC1pdGVtIGJ1dCBzcGFuIG11bHRpcGxlIGRheXMgc3RpbGwgdGFrZSB1cCBzcGFjZSBpbiBsYXRlciBjb2x1bW5zXG4gICAgICAgICAgICAgICAgdG9kbzogaW4gcHJpbnQgdmlldywgZm9yIG11bHRpLWRheSBldmVudHMsIGRvbid0IGRpc3BsYXkgdGl0bGUgd2l0aGluIG5vbi1zdGFydC9lbmQgc2Vnc1xuICAgICAgICAgICAgICAgICovXG4gICAgICAgICAgICAgICAgbm9kZXMucHVzaChjcmVhdGVFbGVtZW50KFwiZGl2XCIsIHsgY2xhc3NOYW1lOiAnZmMtZGF5Z3JpZC1ldmVudC1oYXJuZXNzJyArIChpc0Fic29sdXRlID8gJyBmYy1kYXlncmlkLWV2ZW50LWhhcm5lc3MtYWJzJyA6ICcnKSwga2V5OiBrZXksIHJlZjogaXNNaXJyb3IgPyBudWxsIDogdGhpcy5zZWdIYXJuZXNzUmVmcy5jcmVhdGVSZWYoa2V5KSwgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZpc2liaWxpdHk6IGlzVmlzaWJsZSA/ICcnIDogJ2hpZGRlbicsXG4gICAgICAgICAgICAgICAgICAgICAgICBtYXJnaW5Ub3A6IGlzQWJzb2x1dGUgPyAnJyA6IHBsYWNlbWVudC5tYXJnaW5Ub3AsXG4gICAgICAgICAgICAgICAgICAgICAgICB0b3A6IGlzQWJzb2x1dGUgPyBwbGFjZW1lbnQuYWJzb2x1dGVUb3AgOiAnJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGxlZnQsXG4gICAgICAgICAgICAgICAgICAgICAgICByaWdodCxcbiAgICAgICAgICAgICAgICAgICAgfSB9LCBoYXNMaXN0SXRlbURpc3BsYXkoc2VnKSA/IChjcmVhdGVFbGVtZW50KFRhYmxlTGlzdEl0ZW1FdmVudCwgT2JqZWN0LmFzc2lnbih7IHNlZzogc2VnLCBpc0RyYWdnaW5nOiBpc0RyYWdnaW5nLCBpc1NlbGVjdGVkOiBpbnN0YW5jZUlkID09PSBldmVudFNlbGVjdGlvbiwgZGVmYXVsdERpc3BsYXlFdmVudEVuZDogZGVmYXVsdERpc3BsYXlFdmVudEVuZCB9LCBnZXRTZWdNZXRhKHNlZywgdG9kYXlSYW5nZSkpKSkgOiAoY3JlYXRlRWxlbWVudChUYWJsZUJsb2NrRXZlbnQsIE9iamVjdC5hc3NpZ24oeyBzZWc6IHNlZywgaXNEcmFnZ2luZzogaXNEcmFnZ2luZywgaXNSZXNpemluZzogaXNSZXNpemluZywgaXNEYXRlU2VsZWN0aW5nOiBpc0RhdGVTZWxlY3RpbmcsIGlzU2VsZWN0ZWQ6IGluc3RhbmNlSWQgPT09IGV2ZW50U2VsZWN0aW9uLCBkZWZhdWx0RGlzcGxheUV2ZW50RW5kOiBkZWZhdWx0RGlzcGxheUV2ZW50RW5kIH0sIGdldFNlZ01ldGEoc2VnLCB0b2RheVJhbmdlKSkpKSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBub2RlcztcbiAgICB9XG4gICAgcmVuZGVyRmlsbFNlZ3Moc2VncywgZmlsbFR5cGUpIHtcbiAgICAgICAgbGV0IHsgaXNSdGwgfSA9IHRoaXMuY29udGV4dDtcbiAgICAgICAgbGV0IHsgdG9kYXlSYW5nZSB9ID0gdGhpcy5wcm9wcztcbiAgICAgICAgbGV0IHsgZnJhbWVQb3NpdGlvbnMgfSA9IHRoaXMuc3RhdGU7XG4gICAgICAgIGxldCBub2RlcyA9IFtdO1xuICAgICAgICBpZiAoZnJhbWVQb3NpdGlvbnMpIHtcbiAgICAgICAgICAgIGZvciAobGV0IHNlZyBvZiBzZWdzKSB7XG4gICAgICAgICAgICAgICAgbGV0IGxlZnRSaWdodENzcyA9IGlzUnRsID8ge1xuICAgICAgICAgICAgICAgICAgICByaWdodDogMCxcbiAgICAgICAgICAgICAgICAgICAgbGVmdDogZnJhbWVQb3NpdGlvbnMubGVmdHNbc2VnLmxhc3RDb2xdIC0gZnJhbWVQb3NpdGlvbnMubGVmdHNbc2VnLmZpcnN0Q29sXSxcbiAgICAgICAgICAgICAgICB9IDoge1xuICAgICAgICAgICAgICAgICAgICBsZWZ0OiAwLFxuICAgICAgICAgICAgICAgICAgICByaWdodDogZnJhbWVQb3NpdGlvbnMucmlnaHRzW3NlZy5maXJzdENvbF0gLSBmcmFtZVBvc2l0aW9ucy5yaWdodHNbc2VnLmxhc3RDb2xdLFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgbm9kZXMucHVzaChjcmVhdGVFbGVtZW50KFwiZGl2XCIsIHsga2V5OiBidWlsZEV2ZW50UmFuZ2VLZXkoc2VnLmV2ZW50UmFuZ2UpLCBjbGFzc05hbWU6IFwiZmMtZGF5Z3JpZC1iZy1oYXJuZXNzXCIsIHN0eWxlOiBsZWZ0UmlnaHRDc3MgfSwgZmlsbFR5cGUgPT09ICdiZy1ldmVudCcgP1xuICAgICAgICAgICAgICAgICAgICBjcmVhdGVFbGVtZW50KEJnRXZlbnQsIE9iamVjdC5hc3NpZ24oeyBzZWc6IHNlZyB9LCBnZXRTZWdNZXRhKHNlZywgdG9kYXlSYW5nZSkpKSA6XG4gICAgICAgICAgICAgICAgICAgIHJlbmRlckZpbGwoZmlsbFR5cGUpKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNyZWF0ZUVsZW1lbnQoRnJhZ21lbnQsIHt9LCAuLi5ub2Rlcyk7XG4gICAgfVxuICAgIHVwZGF0ZVNpemluZyhpc0V4dGVybmFsU2l6aW5nQ2hhbmdlKSB7XG4gICAgICAgIGxldCB7IHByb3BzLCBzdGF0ZSwgZnJhbWVFbFJlZnMgfSA9IHRoaXM7XG4gICAgICAgIGlmICghcHJvcHMuZm9yUHJpbnQgJiZcbiAgICAgICAgICAgIHByb3BzLmNsaWVudFdpZHRoICE9PSBudWxsIC8vIHBvc2l0aW9uaW5nIHJlYWR5P1xuICAgICAgICApIHtcbiAgICAgICAgICAgIGlmIChpc0V4dGVybmFsU2l6aW5nQ2hhbmdlKSB7XG4gICAgICAgICAgICAgICAgbGV0IGZyYW1lRWxzID0gcHJvcHMuY2VsbHMubWFwKChjZWxsKSA9PiBmcmFtZUVsUmVmcy5jdXJyZW50TWFwW2NlbGwua2V5XSk7XG4gICAgICAgICAgICAgICAgaWYgKGZyYW1lRWxzLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgICBsZXQgb3JpZ2luRWwgPSB0aGlzLnJvb3RFbFJlZi5jdXJyZW50O1xuICAgICAgICAgICAgICAgICAgICBsZXQgbmV3UG9zaXRpb25DYWNoZSA9IG5ldyBQb3NpdGlvbkNhY2hlKG9yaWdpbkVsLCBmcmFtZUVscywgdHJ1ZSwgLy8gaXNIb3Jpem9udGFsXG4gICAgICAgICAgICAgICAgICAgIGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFzdGF0ZS5mcmFtZVBvc2l0aW9ucyB8fCAhc3RhdGUuZnJhbWVQb3NpdGlvbnMuc2ltaWxhclRvKG5ld1Bvc2l0aW9uQ2FjaGUpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcmFtZVBvc2l0aW9uczogbmV3IFBvc2l0aW9uQ2FjaGUob3JpZ2luRWwsIGZyYW1lRWxzLCB0cnVlLCAvLyBpc0hvcml6b250YWxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWxzZSksXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IG9sZEluc3RhbmNlSGVpZ2h0cyA9IHRoaXMuc3RhdGUuZXZlbnRJbnN0YW5jZUhlaWdodHM7XG4gICAgICAgICAgICBjb25zdCBuZXdJbnN0YW5jZUhlaWdodHMgPSB0aGlzLnF1ZXJ5RXZlbnRJbnN0YW5jZUhlaWdodHMoKTtcbiAgICAgICAgICAgIGNvbnN0IGxpbWl0QnlDb250ZW50SGVpZ2h0ID0gcHJvcHMuZGF5TWF4RXZlbnRzID09PSB0cnVlIHx8IHByb3BzLmRheU1heEV2ZW50Um93cyA9PT0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuc2FmZVNldFN0YXRlKHtcbiAgICAgICAgICAgICAgICAvLyBIQUNLIHRvIHByZXZlbnQgb3NjaWxsYXRpb25zIG9mIGV2ZW50cyBiZWluZyBzaG93bi9oaWRkZW4gZnJvbSBtYXgtZXZlbnQtcm93c1xuICAgICAgICAgICAgICAgIC8vIEVzc2VudGlhbGx5LCBvbmNlIHlvdSBjb21wdXRlIGFuIGVsZW1lbnQncyBoZWlnaHQsIG5ldmVyIG51bGwtb3V0LlxuICAgICAgICAgICAgICAgIC8vIFRPRE86IGFsd2F5cyBkaXNwbGF5IGFsbCBldmVudHMsIGFzIHZpc2liaWxpdHk6aGlkZGVuP1xuICAgICAgICAgICAgICAgIGV2ZW50SW5zdGFuY2VIZWlnaHRzOiBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oe30sIG9sZEluc3RhbmNlSGVpZ2h0cyksIG5ld0luc3RhbmNlSGVpZ2h0cyksXG4gICAgICAgICAgICAgICAgbWF4Q29udGVudEhlaWdodDogbGltaXRCeUNvbnRlbnRIZWlnaHQgPyB0aGlzLmNvbXB1dGVNYXhDb250ZW50SGVpZ2h0KCkgOiBudWxsLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcXVlcnlFdmVudEluc3RhbmNlSGVpZ2h0cygpIHtcbiAgICAgICAgbGV0IHNlZ0VsTWFwID0gdGhpcy5zZWdIYXJuZXNzUmVmcy5jdXJyZW50TWFwO1xuICAgICAgICBsZXQgZXZlbnRJbnN0YW5jZUhlaWdodHMgPSB7fTtcbiAgICAgICAgLy8gZ2V0IHRoZSBtYXggaGVpZ2h0IGFtb25nc3QgaW5zdGFuY2Ugc2Vnc1xuICAgICAgICBmb3IgKGxldCBrZXkgaW4gc2VnRWxNYXApIHtcbiAgICAgICAgICAgIGxldCBoZWlnaHQgPSBNYXRoLnJvdW5kKHNlZ0VsTWFwW2tleV0uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkuaGVpZ2h0KTtcbiAgICAgICAgICAgIGxldCBpbnN0YW5jZUlkID0ga2V5LnNwbGl0KCc6JylbMF07IC8vIGRlY29uc3RydWN0IGhvdyByZW5kZXJGZ1NlZ3MgbWFrZXMgdGhlIGtleVxuICAgICAgICAgICAgZXZlbnRJbnN0YW5jZUhlaWdodHNbaW5zdGFuY2VJZF0gPSBNYXRoLm1heChldmVudEluc3RhbmNlSGVpZ2h0c1tpbnN0YW5jZUlkXSB8fCAwLCBoZWlnaHQpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBldmVudEluc3RhbmNlSGVpZ2h0cztcbiAgICB9XG4gICAgY29tcHV0ZU1heENvbnRlbnRIZWlnaHQoKSB7XG4gICAgICAgIGxldCBmaXJzdEtleSA9IHRoaXMucHJvcHMuY2VsbHNbMF0ua2V5O1xuICAgICAgICBsZXQgY2VsbEVsID0gdGhpcy5jZWxsRWxSZWZzLmN1cnJlbnRNYXBbZmlyc3RLZXldO1xuICAgICAgICBsZXQgZmNDb250YWluZXJFbCA9IHRoaXMuZmdFbFJlZnMuY3VycmVudE1hcFtmaXJzdEtleV07XG4gICAgICAgIHJldHVybiBjZWxsRWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkuYm90dG9tIC0gZmNDb250YWluZXJFbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS50b3A7XG4gICAgfVxuICAgIGdldENlbGxFbHMoKSB7XG4gICAgICAgIGxldCBlbE1hcCA9IHRoaXMuY2VsbEVsUmVmcy5jdXJyZW50TWFwO1xuICAgICAgICByZXR1cm4gdGhpcy5wcm9wcy5jZWxscy5tYXAoKGNlbGwpID0+IGVsTWFwW2NlbGwua2V5XSk7XG4gICAgfVxufVxuVGFibGVSb3cuYWRkU3RhdGVFcXVhbGl0eSh7XG4gICAgZXZlbnRJbnN0YW5jZUhlaWdodHM6IGlzUHJvcHNFcXVhbCxcbn0pO1xuZnVuY3Rpb24gYnVpbGRNaXJyb3JQbGFjZW1lbnRzKG1pcnJvclNlZ3MsIGNvbFBsYWNlbWVudHMpIHtcbiAgICBpZiAoIW1pcnJvclNlZ3MubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gICAgbGV0IHRvcHNCeUluc3RhbmNlSWQgPSBidWlsZEFic29sdXRlVG9wSGFzaChjb2xQbGFjZW1lbnRzKTsgLy8gVE9ETzogY2FjaGUgdGhpcyBhdCBmaXJzdCByZW5kZXI/XG4gICAgcmV0dXJuIG1pcnJvclNlZ3MubWFwKChzZWcpID0+ICh7XG4gICAgICAgIHNlZyxcbiAgICAgICAgaXNWaXNpYmxlOiB0cnVlLFxuICAgICAgICBpc0Fic29sdXRlOiB0cnVlLFxuICAgICAgICBhYnNvbHV0ZVRvcDogdG9wc0J5SW5zdGFuY2VJZFtzZWcuZXZlbnRSYW5nZS5pbnN0YW5jZS5pbnN0YW5jZUlkXSxcbiAgICAgICAgbWFyZ2luVG9wOiAwLFxuICAgIH0pKTtcbn1cbmZ1bmN0aW9uIGJ1aWxkQWJzb2x1dGVUb3BIYXNoKGNvbFBsYWNlbWVudHMpIHtcbiAgICBsZXQgdG9wc0J5SW5zdGFuY2VJZCA9IHt9O1xuICAgIGZvciAobGV0IHBsYWNlbWVudHMgb2YgY29sUGxhY2VtZW50cykge1xuICAgICAgICBmb3IgKGxldCBwbGFjZW1lbnQgb2YgcGxhY2VtZW50cykge1xuICAgICAgICAgICAgdG9wc0J5SW5zdGFuY2VJZFtwbGFjZW1lbnQuc2VnLmV2ZW50UmFuZ2UuaW5zdGFuY2UuaW5zdGFuY2VJZF0gPSBwbGFjZW1lbnQuYWJzb2x1dGVUb3A7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRvcHNCeUluc3RhbmNlSWQ7XG59XG5cbmNsYXNzIFRhYmxlIGV4dGVuZHMgRGF0ZUNvbXBvbmVudCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMuc3BsaXRCdXNpbmVzc0hvdXJTZWdzID0gbWVtb2l6ZShzcGxpdFNlZ3NCeVJvdyk7XG4gICAgICAgIHRoaXMuc3BsaXRCZ0V2ZW50U2VncyA9IG1lbW9pemUoc3BsaXRTZWdzQnlSb3cpO1xuICAgICAgICB0aGlzLnNwbGl0RmdFdmVudFNlZ3MgPSBtZW1vaXplKHNwbGl0U2Vnc0J5Um93KTtcbiAgICAgICAgdGhpcy5zcGxpdERhdGVTZWxlY3Rpb25TZWdzID0gbWVtb2l6ZShzcGxpdFNlZ3NCeVJvdyk7XG4gICAgICAgIHRoaXMuc3BsaXRFdmVudERyYWcgPSBtZW1vaXplKHNwbGl0SW50ZXJhY3Rpb25CeVJvdyk7XG4gICAgICAgIHRoaXMuc3BsaXRFdmVudFJlc2l6ZSA9IG1lbW9pemUoc3BsaXRJbnRlcmFjdGlvbkJ5Um93KTtcbiAgICAgICAgdGhpcy5yb3dSZWZzID0gbmV3IFJlZk1hcCgpO1xuICAgICAgICB0aGlzLmhhbmRsZVJvb3RFbCA9IChyb290RWwpID0+IHtcbiAgICAgICAgICAgIHRoaXMucm9vdEVsID0gcm9vdEVsO1xuICAgICAgICAgICAgaWYgKHJvb3RFbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuY29udGV4dC5yZWdpc3RlckludGVyYWN0aXZlQ29tcG9uZW50KHRoaXMsIHtcbiAgICAgICAgICAgICAgICAgICAgZWw6IHJvb3RFbCxcbiAgICAgICAgICAgICAgICAgICAgaXNIaXRDb21ib0FsbG93ZWQ6IHRoaXMucHJvcHMuaXNIaXRDb21ib0FsbG93ZWQsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNvbnRleHQudW5yZWdpc3RlckludGVyYWN0aXZlQ29tcG9uZW50KHRoaXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH1cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGxldCB7IHByb3BzIH0gPSB0aGlzO1xuICAgICAgICBsZXQgeyBkYXRlUHJvZmlsZSwgZGF5TWF4RXZlbnRSb3dzLCBkYXlNYXhFdmVudHMsIGV4cGFuZFJvd3MgfSA9IHByb3BzO1xuICAgICAgICBsZXQgcm93Q250ID0gcHJvcHMuY2VsbHMubGVuZ3RoO1xuICAgICAgICBsZXQgYnVzaW5lc3NIb3VyU2Vnc0J5Um93ID0gdGhpcy5zcGxpdEJ1c2luZXNzSG91clNlZ3MocHJvcHMuYnVzaW5lc3NIb3VyU2Vncywgcm93Q250KTtcbiAgICAgICAgbGV0IGJnRXZlbnRTZWdzQnlSb3cgPSB0aGlzLnNwbGl0QmdFdmVudFNlZ3MocHJvcHMuYmdFdmVudFNlZ3MsIHJvd0NudCk7XG4gICAgICAgIGxldCBmZ0V2ZW50U2Vnc0J5Um93ID0gdGhpcy5zcGxpdEZnRXZlbnRTZWdzKHByb3BzLmZnRXZlbnRTZWdzLCByb3dDbnQpO1xuICAgICAgICBsZXQgZGF0ZVNlbGVjdGlvblNlZ3NCeVJvdyA9IHRoaXMuc3BsaXREYXRlU2VsZWN0aW9uU2Vncyhwcm9wcy5kYXRlU2VsZWN0aW9uU2Vncywgcm93Q250KTtcbiAgICAgICAgbGV0IGV2ZW50RHJhZ0J5Um93ID0gdGhpcy5zcGxpdEV2ZW50RHJhZyhwcm9wcy5ldmVudERyYWcsIHJvd0NudCk7XG4gICAgICAgIGxldCBldmVudFJlc2l6ZUJ5Um93ID0gdGhpcy5zcGxpdEV2ZW50UmVzaXplKHByb3BzLmV2ZW50UmVzaXplLCByb3dDbnQpO1xuICAgICAgICBsZXQgbGltaXRWaWFCYWxhbmNlZCA9IGRheU1heEV2ZW50cyA9PT0gdHJ1ZSB8fCBkYXlNYXhFdmVudFJvd3MgPT09IHRydWU7XG4gICAgICAgIC8vIGlmIHJvd3MgY2FuJ3QgZXhwYW5kIHRvIGZpbGwgZml4ZWQgaGVpZ2h0LCBjYW4ndCBkbyBiYWxhbmNlZC1oZWlnaHQgZXZlbnQgbGltaXRcbiAgICAgICAgLy8gVE9ETzogYmVzdCBwbGFjZSB0byBub3JtYWxpemUgdGhlc2Ugb3B0aW9ucz9cbiAgICAgICAgaWYgKGxpbWl0VmlhQmFsYW5jZWQgJiYgIWV4cGFuZFJvd3MpIHtcbiAgICAgICAgICAgIGxpbWl0VmlhQmFsYW5jZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGRheU1heEV2ZW50Um93cyA9IG51bGw7XG4gICAgICAgICAgICBkYXlNYXhFdmVudHMgPSBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGxldCBjbGFzc05hbWVzID0gW1xuICAgICAgICAgICAgJ2ZjLWRheWdyaWQtYm9keScsXG4gICAgICAgICAgICBsaW1pdFZpYUJhbGFuY2VkID8gJ2ZjLWRheWdyaWQtYm9keS1iYWxhbmNlZCcgOiAnZmMtZGF5Z3JpZC1ib2R5LXVuYmFsYW5jZWQnLFxuICAgICAgICAgICAgZXhwYW5kUm93cyA/ICcnIDogJ2ZjLWRheWdyaWQtYm9keS1uYXR1cmFsJywgLy8gd2lsbCBoZWlnaHQgb2Ygb25lIHJvdyBkZXBlbmQgb24gdGhlIG90aGVycz9cbiAgICAgICAgXTtcbiAgICAgICAgcmV0dXJuIChjcmVhdGVFbGVtZW50KFwiZGl2XCIsIHsgY2xhc3NOYW1lOiBjbGFzc05hbWVzLmpvaW4oJyAnKSwgcmVmOiB0aGlzLmhhbmRsZVJvb3RFbCwgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAvLyB0aGVzZSBwcm9wcyBhcmUgaW1wb3J0YW50IHRvIGdpdmUgdGhpcyB3cmFwcGVyIGNvcnJlY3QgZGltZW5zaW9ucyBmb3IgaW50ZXJhY3Rpb25zXG4gICAgICAgICAgICAgICAgLy8gVE9ETzogaWYgd2Ugc2V0IGl0IGhlcmUsIGNhbiB3ZSBhdm9pZCBnaXZpbmcgdG8gaW5uZXIgdGFibGVzP1xuICAgICAgICAgICAgICAgIHdpZHRoOiBwcm9wcy5jbGllbnRXaWR0aCxcbiAgICAgICAgICAgICAgICBtaW5XaWR0aDogcHJvcHMudGFibGVNaW5XaWR0aCxcbiAgICAgICAgICAgIH0gfSxcbiAgICAgICAgICAgIGNyZWF0ZUVsZW1lbnQoTm93VGltZXIsIHsgdW5pdDogXCJkYXlcIiB9LCAobm93RGF0ZSwgdG9kYXlSYW5nZSkgPT4gKGNyZWF0ZUVsZW1lbnQoRnJhZ21lbnQsIG51bGwsXG4gICAgICAgICAgICAgICAgY3JlYXRlRWxlbWVudChcInRhYmxlXCIsIHsgcm9sZTogXCJwcmVzZW50YXRpb25cIiwgY2xhc3NOYW1lOiBcImZjLXNjcm9sbGdyaWQtc3luYy10YWJsZVwiLCBzdHlsZToge1xuICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IHByb3BzLmNsaWVudFdpZHRoLFxuICAgICAgICAgICAgICAgICAgICAgICAgbWluV2lkdGg6IHByb3BzLnRhYmxlTWluV2lkdGgsXG4gICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IGV4cGFuZFJvd3MgPyBwcm9wcy5jbGllbnRIZWlnaHQgOiAnJyxcbiAgICAgICAgICAgICAgICAgICAgfSB9LFxuICAgICAgICAgICAgICAgICAgICBwcm9wcy5jb2xHcm91cE5vZGUsXG4gICAgICAgICAgICAgICAgICAgIGNyZWF0ZUVsZW1lbnQoXCJ0Ym9keVwiLCB7IHJvbGU6IFwicHJlc2VudGF0aW9uXCIgfSwgcHJvcHMuY2VsbHMubWFwKChjZWxscywgcm93KSA9PiAoY3JlYXRlRWxlbWVudChUYWJsZVJvdywgeyByZWY6IHRoaXMucm93UmVmcy5jcmVhdGVSZWYocm93KSwga2V5OiBjZWxscy5sZW5ndGhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IGNlbGxzWzBdLmRhdGUudG9JU09TdHJpbmcoKSAvKiBiZXN0PyBvciBwdXQga2V5IG9uIGNlbGw/IG9yIHVzZSBkaWZmIGZvcm1hdHRlcj8gKi9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IHJvdyAvLyBpbiBjYXNlIHRoZXJlIGFyZSBubyBjZWxscyAobGlrZSB3aGVuIHJlc291cmNlIHZpZXcgaXMgbG9hZGluZylcbiAgICAgICAgICAgICAgICAgICAgICAgICwgc2hvd0RheU51bWJlcnM6IHJvd0NudCA+IDEsIHNob3dXZWVrTnVtYmVyczogcHJvcHMuc2hvd1dlZWtOdW1iZXJzLCB0b2RheVJhbmdlOiB0b2RheVJhbmdlLCBkYXRlUHJvZmlsZTogZGF0ZVByb2ZpbGUsIGNlbGxzOiBjZWxscywgcmVuZGVySW50cm86IHByb3BzLnJlbmRlclJvd0ludHJvLCBidXNpbmVzc0hvdXJTZWdzOiBidXNpbmVzc0hvdXJTZWdzQnlSb3dbcm93XSwgZXZlbnRTZWxlY3Rpb246IHByb3BzLmV2ZW50U2VsZWN0aW9uLCBiZ0V2ZW50U2VnczogYmdFdmVudFNlZ3NCeVJvd1tyb3ddLmZpbHRlcihpc1NlZ0FsbERheSkgLyogaGFjayAqLywgZmdFdmVudFNlZ3M6IGZnRXZlbnRTZWdzQnlSb3dbcm93XSwgZGF0ZVNlbGVjdGlvblNlZ3M6IGRhdGVTZWxlY3Rpb25TZWdzQnlSb3dbcm93XSwgZXZlbnREcmFnOiBldmVudERyYWdCeVJvd1tyb3ddLCBldmVudFJlc2l6ZTogZXZlbnRSZXNpemVCeVJvd1tyb3ddLCBkYXlNYXhFdmVudHM6IGRheU1heEV2ZW50cywgZGF5TWF4RXZlbnRSb3dzOiBkYXlNYXhFdmVudFJvd3MsIGNsaWVudFdpZHRoOiBwcm9wcy5jbGllbnRXaWR0aCwgY2xpZW50SGVpZ2h0OiBwcm9wcy5jbGllbnRIZWlnaHQsIGZvclByaW50OiBwcm9wcy5mb3JQcmludCB9KSkpKSkpKSkpKTtcbiAgICB9XG4gICAgLy8gSGl0IFN5c3RlbVxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICBwcmVwYXJlSGl0cygpIHtcbiAgICAgICAgdGhpcy5yb3dQb3NpdGlvbnMgPSBuZXcgUG9zaXRpb25DYWNoZSh0aGlzLnJvb3RFbCwgdGhpcy5yb3dSZWZzLmNvbGxlY3QoKS5tYXAoKHJvd09iaikgPT4gcm93T2JqLmdldENlbGxFbHMoKVswXSksIC8vIGZpcnN0IGNlbGwgZWwgaW4gZWFjaCByb3cuIFRPRE86IG5vdCBvcHRpbWFsXG4gICAgICAgIGZhbHNlLCB0cnVlKTtcbiAgICAgICAgdGhpcy5jb2xQb3NpdGlvbnMgPSBuZXcgUG9zaXRpb25DYWNoZSh0aGlzLnJvb3RFbCwgdGhpcy5yb3dSZWZzLmN1cnJlbnRNYXBbMF0uZ2V0Q2VsbEVscygpLCAvLyBjZWxsIGVscyBpbiBmaXJzdCByb3dcbiAgICAgICAgdHJ1ZSwgLy8gaG9yaXpvbnRhbFxuICAgICAgICBmYWxzZSk7XG4gICAgfVxuICAgIHF1ZXJ5SGl0KHBvc2l0aW9uTGVmdCwgcG9zaXRpb25Ub3ApIHtcbiAgICAgICAgbGV0IHsgY29sUG9zaXRpb25zLCByb3dQb3NpdGlvbnMgfSA9IHRoaXM7XG4gICAgICAgIGxldCBjb2wgPSBjb2xQb3NpdGlvbnMubGVmdFRvSW5kZXgocG9zaXRpb25MZWZ0KTtcbiAgICAgICAgbGV0IHJvdyA9IHJvd1Bvc2l0aW9ucy50b3BUb0luZGV4KHBvc2l0aW9uVG9wKTtcbiAgICAgICAgaWYgKHJvdyAhPSBudWxsICYmIGNvbCAhPSBudWxsKSB7XG4gICAgICAgICAgICBsZXQgY2VsbCA9IHRoaXMucHJvcHMuY2VsbHNbcm93XVtjb2xdO1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBkYXRlUHJvZmlsZTogdGhpcy5wcm9wcy5kYXRlUHJvZmlsZSxcbiAgICAgICAgICAgICAgICBkYXRlU3BhbjogT2JqZWN0LmFzc2lnbih7IHJhbmdlOiB0aGlzLmdldENlbGxSYW5nZShyb3csIGNvbCksIGFsbERheTogdHJ1ZSB9LCBjZWxsLmV4dHJhRGF0ZVNwYW4pLFxuICAgICAgICAgICAgICAgIGRheUVsOiB0aGlzLmdldENlbGxFbChyb3csIGNvbCksXG4gICAgICAgICAgICAgICAgcmVjdDoge1xuICAgICAgICAgICAgICAgICAgICBsZWZ0OiBjb2xQb3NpdGlvbnMubGVmdHNbY29sXSxcbiAgICAgICAgICAgICAgICAgICAgcmlnaHQ6IGNvbFBvc2l0aW9ucy5yaWdodHNbY29sXSxcbiAgICAgICAgICAgICAgICAgICAgdG9wOiByb3dQb3NpdGlvbnMudG9wc1tyb3ddLFxuICAgICAgICAgICAgICAgICAgICBib3R0b206IHJvd1Bvc2l0aW9ucy5ib3R0b21zW3Jvd10sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBsYXllcjogMCxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGdldENlbGxFbChyb3csIGNvbCkge1xuICAgICAgICByZXR1cm4gdGhpcy5yb3dSZWZzLmN1cnJlbnRNYXBbcm93XS5nZXRDZWxsRWxzKClbY29sXTsgLy8gVE9ETzogbm90IG9wdGltYWxcbiAgICB9XG4gICAgZ2V0Q2VsbFJhbmdlKHJvdywgY29sKSB7XG4gICAgICAgIGxldCBzdGFydCA9IHRoaXMucHJvcHMuY2VsbHNbcm93XVtjb2xdLmRhdGU7XG4gICAgICAgIGxldCBlbmQgPSBhZGREYXlzKHN0YXJ0LCAxKTtcbiAgICAgICAgcmV0dXJuIHsgc3RhcnQsIGVuZCB9O1xuICAgIH1cbn1cbmZ1bmN0aW9uIGlzU2VnQWxsRGF5KHNlZykge1xuICAgIHJldHVybiBzZWcuZXZlbnRSYW5nZS5kZWYuYWxsRGF5O1xufVxuXG5jbGFzcyBEYXlUYWJsZVNsaWNlciBleHRlbmRzIFNsaWNlciB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7XG4gICAgICAgIHRoaXMuZm9yY2VEYXlJZkxpc3RJdGVtID0gdHJ1ZTtcbiAgICB9XG4gICAgc2xpY2VSYW5nZShkYXRlUmFuZ2UsIGRheVRhYmxlTW9kZWwpIHtcbiAgICAgICAgcmV0dXJuIGRheVRhYmxlTW9kZWwuc2xpY2VSYW5nZShkYXRlUmFuZ2UpO1xuICAgIH1cbn1cblxuY2xhc3MgRGF5VGFibGUgZXh0ZW5kcyBEYXRlQ29tcG9uZW50IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5zbGljZXIgPSBuZXcgRGF5VGFibGVTbGljZXIoKTtcbiAgICAgICAgdGhpcy50YWJsZVJlZiA9IGNyZWF0ZVJlZigpO1xuICAgIH1cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGxldCB7IHByb3BzLCBjb250ZXh0IH0gPSB0aGlzO1xuICAgICAgICByZXR1cm4gKGNyZWF0ZUVsZW1lbnQoVGFibGUsIE9iamVjdC5hc3NpZ24oeyByZWY6IHRoaXMudGFibGVSZWYgfSwgdGhpcy5zbGljZXIuc2xpY2VQcm9wcyhwcm9wcywgcHJvcHMuZGF0ZVByb2ZpbGUsIHByb3BzLm5leHREYXlUaHJlc2hvbGQsIGNvbnRleHQsIHByb3BzLmRheVRhYmxlTW9kZWwpLCB7IGRhdGVQcm9maWxlOiBwcm9wcy5kYXRlUHJvZmlsZSwgY2VsbHM6IHByb3BzLmRheVRhYmxlTW9kZWwuY2VsbHMsIGNvbEdyb3VwTm9kZTogcHJvcHMuY29sR3JvdXBOb2RlLCB0YWJsZU1pbldpZHRoOiBwcm9wcy50YWJsZU1pbldpZHRoLCByZW5kZXJSb3dJbnRybzogcHJvcHMucmVuZGVyUm93SW50cm8sIGRheU1heEV2ZW50czogcHJvcHMuZGF5TWF4RXZlbnRzLCBkYXlNYXhFdmVudFJvd3M6IHByb3BzLmRheU1heEV2ZW50Um93cywgc2hvd1dlZWtOdW1iZXJzOiBwcm9wcy5zaG93V2Vla051bWJlcnMsIGV4cGFuZFJvd3M6IHByb3BzLmV4cGFuZFJvd3MsIGhlYWRlckFsaWduRWxSZWY6IHByb3BzLmhlYWRlckFsaWduRWxSZWYsIGNsaWVudFdpZHRoOiBwcm9wcy5jbGllbnRXaWR0aCwgY2xpZW50SGVpZ2h0OiBwcm9wcy5jbGllbnRIZWlnaHQsIGZvclByaW50OiBwcm9wcy5mb3JQcmludCB9KSkpO1xuICAgIH1cbn1cblxuY2xhc3MgRGF5VGFibGVWaWV3IGV4dGVuZHMgVGFibGVWaWV3IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5idWlsZERheVRhYmxlTW9kZWwgPSBtZW1vaXplKGJ1aWxkRGF5VGFibGVNb2RlbCk7XG4gICAgICAgIHRoaXMuaGVhZGVyUmVmID0gY3JlYXRlUmVmKCk7XG4gICAgICAgIHRoaXMudGFibGVSZWYgPSBjcmVhdGVSZWYoKTtcbiAgICB9XG4gICAgcmVuZGVyKCkge1xuICAgICAgICBsZXQgeyBvcHRpb25zLCBkYXRlUHJvZmlsZUdlbmVyYXRvciB9ID0gdGhpcy5jb250ZXh0O1xuICAgICAgICBsZXQgeyBwcm9wcyB9ID0gdGhpcztcbiAgICAgICAgbGV0IGRheVRhYmxlTW9kZWwgPSB0aGlzLmJ1aWxkRGF5VGFibGVNb2RlbChwcm9wcy5kYXRlUHJvZmlsZSwgZGF0ZVByb2ZpbGVHZW5lcmF0b3IpO1xuICAgICAgICBsZXQgaGVhZGVyQ29udGVudCA9IG9wdGlvbnMuZGF5SGVhZGVycyAmJiAoY3JlYXRlRWxlbWVudChEYXlIZWFkZXIsIHsgcmVmOiB0aGlzLmhlYWRlclJlZiwgZGF0ZVByb2ZpbGU6IHByb3BzLmRhdGVQcm9maWxlLCBkYXRlczogZGF5VGFibGVNb2RlbC5oZWFkZXJEYXRlcywgZGF0ZXNSZXBEaXN0aW5jdERheXM6IGRheVRhYmxlTW9kZWwucm93Q250ID09PSAxIH0pKTtcbiAgICAgICAgbGV0IGJvZHlDb250ZW50ID0gKGNvbnRlbnRBcmcpID0+IChjcmVhdGVFbGVtZW50KERheVRhYmxlLCB7IHJlZjogdGhpcy50YWJsZVJlZiwgZGF0ZVByb2ZpbGU6IHByb3BzLmRhdGVQcm9maWxlLCBkYXlUYWJsZU1vZGVsOiBkYXlUYWJsZU1vZGVsLCBidXNpbmVzc0hvdXJzOiBwcm9wcy5idXNpbmVzc0hvdXJzLCBkYXRlU2VsZWN0aW9uOiBwcm9wcy5kYXRlU2VsZWN0aW9uLCBldmVudFN0b3JlOiBwcm9wcy5ldmVudFN0b3JlLCBldmVudFVpQmFzZXM6IHByb3BzLmV2ZW50VWlCYXNlcywgZXZlbnRTZWxlY3Rpb246IHByb3BzLmV2ZW50U2VsZWN0aW9uLCBldmVudERyYWc6IHByb3BzLmV2ZW50RHJhZywgZXZlbnRSZXNpemU6IHByb3BzLmV2ZW50UmVzaXplLCBuZXh0RGF5VGhyZXNob2xkOiBvcHRpb25zLm5leHREYXlUaHJlc2hvbGQsIGNvbEdyb3VwTm9kZTogY29udGVudEFyZy50YWJsZUNvbEdyb3VwTm9kZSwgdGFibGVNaW5XaWR0aDogY29udGVudEFyZy50YWJsZU1pbldpZHRoLCBkYXlNYXhFdmVudHM6IG9wdGlvbnMuZGF5TWF4RXZlbnRzLCBkYXlNYXhFdmVudFJvd3M6IG9wdGlvbnMuZGF5TWF4RXZlbnRSb3dzLCBzaG93V2Vla051bWJlcnM6IG9wdGlvbnMud2Vla051bWJlcnMsIGV4cGFuZFJvd3M6ICFwcm9wcy5pc0hlaWdodEF1dG8sIGhlYWRlckFsaWduRWxSZWY6IHRoaXMuaGVhZGVyRWxSZWYsIGNsaWVudFdpZHRoOiBjb250ZW50QXJnLmNsaWVudFdpZHRoLCBjbGllbnRIZWlnaHQ6IGNvbnRlbnRBcmcuY2xpZW50SGVpZ2h0LCBmb3JQcmludDogcHJvcHMuZm9yUHJpbnQgfSkpO1xuICAgICAgICByZXR1cm4gb3B0aW9ucy5kYXlNaW5XaWR0aFxuICAgICAgICAgICAgPyB0aGlzLnJlbmRlckhTY3JvbGxMYXlvdXQoaGVhZGVyQ29udGVudCwgYm9keUNvbnRlbnQsIGRheVRhYmxlTW9kZWwuY29sQ250LCBvcHRpb25zLmRheU1pbldpZHRoKVxuICAgICAgICAgICAgOiB0aGlzLnJlbmRlclNpbXBsZUxheW91dChoZWFkZXJDb250ZW50LCBib2R5Q29udGVudCk7XG4gICAgfVxufVxuZnVuY3Rpb24gYnVpbGREYXlUYWJsZU1vZGVsKGRhdGVQcm9maWxlLCBkYXRlUHJvZmlsZUdlbmVyYXRvcikge1xuICAgIGxldCBkYXlTZXJpZXMgPSBuZXcgRGF5U2VyaWVzTW9kZWwoZGF0ZVByb2ZpbGUucmVuZGVyUmFuZ2UsIGRhdGVQcm9maWxlR2VuZXJhdG9yKTtcbiAgICByZXR1cm4gbmV3IERheVRhYmxlTW9kZWwoZGF5U2VyaWVzLCAveWVhcnxtb250aHx3ZWVrLy50ZXN0KGRhdGVQcm9maWxlLmN1cnJlbnRSYW5nZVVuaXQpKTtcbn1cblxuZXhwb3J0IHsgRGF5VGFibGVWaWV3IGFzIERheUdyaWRWaWV3LCBEYXlUYWJsZSwgRGF5VGFibGVTbGljZXIsIFRhYmxlLCBUYWJsZVZpZXcsIGJ1aWxkRGF5VGFibGVNb2RlbCB9O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/@fullcalendar/daygrid/internal.esm.js\n"); /***/ }), /***/ "./node_modules/@fullcalendar/interaction/index.esm.js": /*!*************************************************************!*\ !*** ./node_modules/@fullcalendar/interaction/index.esm.js ***! \*************************************************************/ /***/ (function(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) { eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"Draggable\": function() { return /* binding */ ExternalDraggable; },\n/* harmony export */ \"ThirdPartyDraggable\": function() { return /* binding */ ThirdPartyDraggable; },\n/* harmony export */ \"default\": function() { return /* binding */ index; }\n/* harmony export */ });\n/* harmony import */ var _fullcalendar_core__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @fullcalendar/core */ \"./node_modules/@fullcalendar/core/index.esm.js\");\n/* harmony import */ var _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @fullcalendar/core/internal */ \"./node_modules/@fullcalendar/core/internal-common.esm.js\");\n\n\n\n_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bI.touchMouseIgnoreWait = 500;\nlet ignoreMouseDepth = 0;\nlet listenerCnt = 0;\nlet isWindowTouchMoveCancelled = false;\n/*\nUses a \"pointer\" abstraction, which monitors UI events for both mouse and touch.\nTracks when the pointer \"drags\" on a certain element, meaning down+move+up.\n\nAlso, tracks if there was touch-scrolling.\nAlso, can prevent touch-scrolling from happening.\nAlso, can fire pointermove events when scrolling happens underneath, even when no real pointer movement.\n\nemits:\n- pointerdown\n- pointermove\n- pointerup\n*/\nclass PointerDragging {\n constructor(containerEl) {\n this.subjectEl = null;\n // options that can be directly assigned by caller\n this.selector = ''; // will cause subjectEl in all emitted events to be this element\n this.handleSelector = '';\n this.shouldIgnoreMove = false;\n this.shouldWatchScroll = true; // for simulating pointermove on scroll\n // internal states\n this.isDragging = false;\n this.isTouchDragging = false;\n this.wasTouchScroll = false;\n // Mouse\n // ----------------------------------------------------------------------------------------------------\n this.handleMouseDown = (ev) => {\n if (!this.shouldIgnoreMouse() &&\n isPrimaryMouseButton(ev) &&\n this.tryStart(ev)) {\n let pev = this.createEventFromMouse(ev, true);\n this.emitter.trigger('pointerdown', pev);\n this.initScrollWatch(pev);\n if (!this.shouldIgnoreMove) {\n document.addEventListener('mousemove', this.handleMouseMove);\n }\n document.addEventListener('mouseup', this.handleMouseUp);\n }\n };\n this.handleMouseMove = (ev) => {\n let pev = this.createEventFromMouse(ev);\n this.recordCoords(pev);\n this.emitter.trigger('pointermove', pev);\n };\n this.handleMouseUp = (ev) => {\n document.removeEventListener('mousemove', this.handleMouseMove);\n document.removeEventListener('mouseup', this.handleMouseUp);\n this.emitter.trigger('pointerup', this.createEventFromMouse(ev));\n this.cleanup(); // call last so that pointerup has access to props\n };\n // Touch\n // ----------------------------------------------------------------------------------------------------\n this.handleTouchStart = (ev) => {\n if (this.tryStart(ev)) {\n this.isTouchDragging = true;\n let pev = this.createEventFromTouch(ev, true);\n this.emitter.trigger('pointerdown', pev);\n this.initScrollWatch(pev);\n // unlike mouse, need to attach to target, not document\n // https://stackoverflow.com/a/45760014\n let targetEl = ev.target;\n if (!this.shouldIgnoreMove) {\n targetEl.addEventListener('touchmove', this.handleTouchMove);\n }\n targetEl.addEventListener('touchend', this.handleTouchEnd);\n targetEl.addEventListener('touchcancel', this.handleTouchEnd); // treat it as a touch end\n // attach a handler to get called when ANY scroll action happens on the page.\n // this was impossible to do with normal on/off because 'scroll' doesn't bubble.\n // http://stackoverflow.com/a/32954565/96342\n window.addEventListener('scroll', this.handleTouchScroll, true);\n }\n };\n this.handleTouchMove = (ev) => {\n let pev = this.createEventFromTouch(ev);\n this.recordCoords(pev);\n this.emitter.trigger('pointermove', pev);\n };\n this.handleTouchEnd = (ev) => {\n if (this.isDragging) { // done to guard against touchend followed by touchcancel\n let targetEl = ev.target;\n targetEl.removeEventListener('touchmove', this.handleTouchMove);\n targetEl.removeEventListener('touchend', this.handleTouchEnd);\n targetEl.removeEventListener('touchcancel', this.handleTouchEnd);\n window.removeEventListener('scroll', this.handleTouchScroll, true); // useCaptured=true\n this.emitter.trigger('pointerup', this.createEventFromTouch(ev));\n this.cleanup(); // call last so that pointerup has access to props\n this.isTouchDragging = false;\n startIgnoringMouse();\n }\n };\n this.handleTouchScroll = () => {\n this.wasTouchScroll = true;\n };\n this.handleScroll = (ev) => {\n if (!this.shouldIgnoreMove) {\n let pageX = (window.pageXOffset - this.prevScrollX) + this.prevPageX;\n let pageY = (window.pageYOffset - this.prevScrollY) + this.prevPageY;\n this.emitter.trigger('pointermove', {\n origEvent: ev,\n isTouch: this.isTouchDragging,\n subjectEl: this.subjectEl,\n pageX,\n pageY,\n deltaX: pageX - this.origPageX,\n deltaY: pageY - this.origPageY,\n });\n }\n };\n this.containerEl = containerEl;\n this.emitter = new _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.F();\n containerEl.addEventListener('mousedown', this.handleMouseDown);\n containerEl.addEventListener('touchstart', this.handleTouchStart, { passive: true });\n listenerCreated();\n }\n destroy() {\n this.containerEl.removeEventListener('mousedown', this.handleMouseDown);\n this.containerEl.removeEventListener('touchstart', this.handleTouchStart, { passive: true });\n listenerDestroyed();\n }\n tryStart(ev) {\n let subjectEl = this.querySubjectEl(ev);\n let downEl = ev.target;\n if (subjectEl &&\n (!this.handleSelector || (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.a0)(downEl, this.handleSelector))) {\n this.subjectEl = subjectEl;\n this.isDragging = true; // do this first so cancelTouchScroll will work\n this.wasTouchScroll = false;\n return true;\n }\n return false;\n }\n cleanup() {\n isWindowTouchMoveCancelled = false;\n this.isDragging = false;\n this.subjectEl = null;\n // keep wasTouchScroll around for later access\n this.destroyScrollWatch();\n }\n querySubjectEl(ev) {\n if (this.selector) {\n return (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.a0)(ev.target, this.selector);\n }\n return this.containerEl;\n }\n shouldIgnoreMouse() {\n return ignoreMouseDepth || this.isTouchDragging;\n }\n // can be called by user of this class, to cancel touch-based scrolling for the current drag\n cancelTouchScroll() {\n if (this.isDragging) {\n isWindowTouchMoveCancelled = true;\n }\n }\n // Scrolling that simulates pointermoves\n // ----------------------------------------------------------------------------------------------------\n initScrollWatch(ev) {\n if (this.shouldWatchScroll) {\n this.recordCoords(ev);\n window.addEventListener('scroll', this.handleScroll, true); // useCapture=true\n }\n }\n recordCoords(ev) {\n if (this.shouldWatchScroll) {\n this.prevPageX = ev.pageX;\n this.prevPageY = ev.pageY;\n this.prevScrollX = window.pageXOffset;\n this.prevScrollY = window.pageYOffset;\n }\n }\n destroyScrollWatch() {\n if (this.shouldWatchScroll) {\n window.removeEventListener('scroll', this.handleScroll, true); // useCaptured=true\n }\n }\n // Event Normalization\n // ----------------------------------------------------------------------------------------------------\n createEventFromMouse(ev, isFirst) {\n let deltaX = 0;\n let deltaY = 0;\n // TODO: repeat code\n if (isFirst) {\n this.origPageX = ev.pageX;\n this.origPageY = ev.pageY;\n }\n else {\n deltaX = ev.pageX - this.origPageX;\n deltaY = ev.pageY - this.origPageY;\n }\n return {\n origEvent: ev,\n isTouch: false,\n subjectEl: this.subjectEl,\n pageX: ev.pageX,\n pageY: ev.pageY,\n deltaX,\n deltaY,\n };\n }\n createEventFromTouch(ev, isFirst) {\n let touches = ev.touches;\n let pageX;\n let pageY;\n let deltaX = 0;\n let deltaY = 0;\n // if touch coords available, prefer,\n // because FF would give bad ev.pageX ev.pageY\n if (touches && touches.length) {\n pageX = touches[0].pageX;\n pageY = touches[0].pageY;\n }\n else {\n pageX = ev.pageX;\n pageY = ev.pageY;\n }\n // TODO: repeat code\n if (isFirst) {\n this.origPageX = pageX;\n this.origPageY = pageY;\n }\n else {\n deltaX = pageX - this.origPageX;\n deltaY = pageY - this.origPageY;\n }\n return {\n origEvent: ev,\n isTouch: true,\n subjectEl: this.subjectEl,\n pageX,\n pageY,\n deltaX,\n deltaY,\n };\n }\n}\n// Returns a boolean whether this was a left mouse click and no ctrl key (which means right click on Mac)\nfunction isPrimaryMouseButton(ev) {\n return ev.button === 0 && !ev.ctrlKey;\n}\n// Ignoring fake mouse events generated by touch\n// ----------------------------------------------------------------------------------------------------\nfunction startIgnoringMouse() {\n ignoreMouseDepth += 1;\n setTimeout(() => {\n ignoreMouseDepth -= 1;\n }, _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bI.touchMouseIgnoreWait);\n}\n// We want to attach touchmove as early as possible for Safari\n// ----------------------------------------------------------------------------------------------------\nfunction listenerCreated() {\n listenerCnt += 1;\n if (listenerCnt === 1) {\n window.addEventListener('touchmove', onWindowTouchMove, { passive: false });\n }\n}\nfunction listenerDestroyed() {\n listenerCnt -= 1;\n if (!listenerCnt) {\n window.removeEventListener('touchmove', onWindowTouchMove, { passive: false });\n }\n}\nfunction onWindowTouchMove(ev) {\n if (isWindowTouchMoveCancelled) {\n ev.preventDefault();\n }\n}\n\n/*\nAn effect in which an element follows the movement of a pointer across the screen.\nThe moving element is a clone of some other element.\nMust call start + handleMove + stop.\n*/\nclass ElementMirror {\n constructor() {\n this.isVisible = false; // must be explicitly enabled\n this.sourceEl = null;\n this.mirrorEl = null;\n this.sourceElRect = null; // screen coords relative to viewport\n // options that can be set directly by caller\n this.parentNode = document.body; // HIGHLY SUGGESTED to set this to sidestep ShadowDOM issues\n this.zIndex = 9999;\n this.revertDuration = 0;\n }\n start(sourceEl, pageX, pageY) {\n this.sourceEl = sourceEl;\n this.sourceElRect = this.sourceEl.getBoundingClientRect();\n this.origScreenX = pageX - window.pageXOffset;\n this.origScreenY = pageY - window.pageYOffset;\n this.deltaX = 0;\n this.deltaY = 0;\n this.updateElPosition();\n }\n handleMove(pageX, pageY) {\n this.deltaX = (pageX - window.pageXOffset) - this.origScreenX;\n this.deltaY = (pageY - window.pageYOffset) - this.origScreenY;\n this.updateElPosition();\n }\n // can be called before start\n setIsVisible(bool) {\n if (bool) {\n if (!this.isVisible) {\n if (this.mirrorEl) {\n this.mirrorEl.style.display = '';\n }\n this.isVisible = bool; // needs to happen before updateElPosition\n this.updateElPosition(); // because was not updating the position while invisible\n }\n }\n else if (this.isVisible) {\n if (this.mirrorEl) {\n this.mirrorEl.style.display = 'none';\n }\n this.isVisible = bool;\n }\n }\n // always async\n stop(needsRevertAnimation, callback) {\n let done = () => {\n this.cleanup();\n callback();\n };\n if (needsRevertAnimation &&\n this.mirrorEl &&\n this.isVisible &&\n this.revertDuration && // if 0, transition won't work\n (this.deltaX || this.deltaY) // if same coords, transition won't work\n ) {\n this.doRevertAnimation(done, this.revertDuration);\n }\n else {\n setTimeout(done, 0);\n }\n }\n doRevertAnimation(callback, revertDuration) {\n let mirrorEl = this.mirrorEl;\n let finalSourceElRect = this.sourceEl.getBoundingClientRect(); // because autoscrolling might have happened\n mirrorEl.style.transition =\n 'top ' + revertDuration + 'ms,' +\n 'left ' + revertDuration + 'ms';\n (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.aP)(mirrorEl, {\n left: finalSourceElRect.left,\n top: finalSourceElRect.top,\n });\n (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.b3)(mirrorEl, () => {\n mirrorEl.style.transition = '';\n callback();\n });\n }\n cleanup() {\n if (this.mirrorEl) {\n (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.aO)(this.mirrorEl);\n this.mirrorEl = null;\n }\n this.sourceEl = null;\n }\n updateElPosition() {\n if (this.sourceEl && this.isVisible) {\n (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.aP)(this.getMirrorEl(), {\n left: this.sourceElRect.left + this.deltaX,\n top: this.sourceElRect.top + this.deltaY,\n });\n }\n }\n getMirrorEl() {\n let sourceElRect = this.sourceElRect;\n let mirrorEl = this.mirrorEl;\n if (!mirrorEl) {\n mirrorEl = this.mirrorEl = this.sourceEl.cloneNode(true); // cloneChildren=true\n // we don't want long taps or any mouse interaction causing selection/menus.\n // would use preventSelection(), but that prevents selectstart, causing problems.\n mirrorEl.classList.add('fc-unselectable');\n mirrorEl.classList.add('fc-event-dragging');\n (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.aP)(mirrorEl, {\n position: 'fixed',\n zIndex: this.zIndex,\n visibility: '',\n boxSizing: 'border-box',\n width: sourceElRect.right - sourceElRect.left,\n height: sourceElRect.bottom - sourceElRect.top,\n right: 'auto',\n bottom: 'auto',\n margin: 0,\n });\n this.parentNode.appendChild(mirrorEl);\n }\n return mirrorEl;\n }\n}\n\n/*\nIs a cache for a given element's scroll information (all the info that ScrollController stores)\nin addition the \"client rectangle\" of the element.. the area within the scrollbars.\n\nThe cache can be in one of two modes:\n- doesListening:false - ignores when the container is scrolled by someone else\n- doesListening:true - watch for scrolling and update the cache\n*/\nclass ScrollGeomCache extends _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bc {\n constructor(scrollController, doesListening) {\n super();\n this.handleScroll = () => {\n this.scrollTop = this.scrollController.getScrollTop();\n this.scrollLeft = this.scrollController.getScrollLeft();\n this.handleScrollChange();\n };\n this.scrollController = scrollController;\n this.doesListening = doesListening;\n this.scrollTop = this.origScrollTop = scrollController.getScrollTop();\n this.scrollLeft = this.origScrollLeft = scrollController.getScrollLeft();\n this.scrollWidth = scrollController.getScrollWidth();\n this.scrollHeight = scrollController.getScrollHeight();\n this.clientWidth = scrollController.getClientWidth();\n this.clientHeight = scrollController.getClientHeight();\n this.clientRect = this.computeClientRect(); // do last in case it needs cached values\n if (this.doesListening) {\n this.getEventTarget().addEventListener('scroll', this.handleScroll);\n }\n }\n destroy() {\n if (this.doesListening) {\n this.getEventTarget().removeEventListener('scroll', this.handleScroll);\n }\n }\n getScrollTop() {\n return this.scrollTop;\n }\n getScrollLeft() {\n return this.scrollLeft;\n }\n setScrollTop(top) {\n this.scrollController.setScrollTop(top);\n if (!this.doesListening) {\n // we are not relying on the element to normalize out-of-bounds scroll values\n // so we need to sanitize ourselves\n this.scrollTop = Math.max(Math.min(top, this.getMaxScrollTop()), 0);\n this.handleScrollChange();\n }\n }\n setScrollLeft(top) {\n this.scrollController.setScrollLeft(top);\n if (!this.doesListening) {\n // we are not relying on the element to normalize out-of-bounds scroll values\n // so we need to sanitize ourselves\n this.scrollLeft = Math.max(Math.min(top, this.getMaxScrollLeft()), 0);\n this.handleScrollChange();\n }\n }\n getClientWidth() {\n return this.clientWidth;\n }\n getClientHeight() {\n return this.clientHeight;\n }\n getScrollWidth() {\n return this.scrollWidth;\n }\n getScrollHeight() {\n return this.scrollHeight;\n }\n handleScrollChange() {\n }\n}\n\nclass ElementScrollGeomCache extends ScrollGeomCache {\n constructor(el, doesListening) {\n super(new _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bd(el), doesListening);\n }\n getEventTarget() {\n return this.scrollController.el;\n }\n computeClientRect() {\n return (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.b4)(this.scrollController.el);\n }\n}\n\nclass WindowScrollGeomCache extends ScrollGeomCache {\n constructor(doesListening) {\n super(new _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.be(), doesListening);\n }\n getEventTarget() {\n return window;\n }\n computeClientRect() {\n return {\n left: this.scrollLeft,\n right: this.scrollLeft + this.clientWidth,\n top: this.scrollTop,\n bottom: this.scrollTop + this.clientHeight,\n };\n }\n // the window is the only scroll object that changes it's rectangle relative\n // to the document's topleft as it scrolls\n handleScrollChange() {\n this.clientRect = this.computeClientRect();\n }\n}\n\n// If available we are using native \"performance\" API instead of \"Date\"\n// Read more about it on MDN:\n// https://developer.mozilla.org/en-US/docs/Web/API/Performance\nconst getTime = typeof performance === 'function' ? performance.now : Date.now;\n/*\nFor a pointer interaction, automatically scrolls certain scroll containers when the pointer\napproaches the edge.\n\nThe caller must call start + handleMove + stop.\n*/\nclass AutoScroller {\n constructor() {\n // options that can be set by caller\n this.isEnabled = true;\n this.scrollQuery = [window, '.fc-scroller'];\n this.edgeThreshold = 50; // pixels\n this.maxVelocity = 300; // pixels per second\n // internal state\n this.pointerScreenX = null;\n this.pointerScreenY = null;\n this.isAnimating = false;\n this.scrollCaches = null;\n // protect against the initial pointerdown being too close to an edge and starting the scroll\n this.everMovedUp = false;\n this.everMovedDown = false;\n this.everMovedLeft = false;\n this.everMovedRight = false;\n this.animate = () => {\n if (this.isAnimating) { // wasn't cancelled between animation calls\n let edge = this.computeBestEdge(this.pointerScreenX + window.pageXOffset, this.pointerScreenY + window.pageYOffset);\n if (edge) {\n let now = getTime();\n this.handleSide(edge, (now - this.msSinceRequest) / 1000);\n this.requestAnimation(now);\n }\n else {\n this.isAnimating = false; // will stop animation\n }\n }\n };\n }\n start(pageX, pageY, scrollStartEl) {\n if (this.isEnabled) {\n this.scrollCaches = this.buildCaches(scrollStartEl);\n this.pointerScreenX = null;\n this.pointerScreenY = null;\n this.everMovedUp = false;\n this.everMovedDown = false;\n this.everMovedLeft = false;\n this.everMovedRight = false;\n this.handleMove(pageX, pageY);\n }\n }\n handleMove(pageX, pageY) {\n if (this.isEnabled) {\n let pointerScreenX = pageX - window.pageXOffset;\n let pointerScreenY = pageY - window.pageYOffset;\n let yDelta = this.pointerScreenY === null ? 0 : pointerScreenY - this.pointerScreenY;\n let xDelta = this.pointerScreenX === null ? 0 : pointerScreenX - this.pointerScreenX;\n if (yDelta < 0) {\n this.everMovedUp = true;\n }\n else if (yDelta > 0) {\n this.everMovedDown = true;\n }\n if (xDelta < 0) {\n this.everMovedLeft = true;\n }\n else if (xDelta > 0) {\n this.everMovedRight = true;\n }\n this.pointerScreenX = pointerScreenX;\n this.pointerScreenY = pointerScreenY;\n if (!this.isAnimating) {\n this.isAnimating = true;\n this.requestAnimation(getTime());\n }\n }\n }\n stop() {\n if (this.isEnabled) {\n this.isAnimating = false; // will stop animation\n for (let scrollCache of this.scrollCaches) {\n scrollCache.destroy();\n }\n this.scrollCaches = null;\n }\n }\n requestAnimation(now) {\n this.msSinceRequest = now;\n requestAnimationFrame(this.animate);\n }\n handleSide(edge, seconds) {\n let { scrollCache } = edge;\n let { edgeThreshold } = this;\n let invDistance = edgeThreshold - edge.distance;\n let velocity = // the closer to the edge, the faster we scroll\n ((invDistance * invDistance) / (edgeThreshold * edgeThreshold)) * // quadratic\n this.maxVelocity * seconds;\n let sign = 1;\n switch (edge.name) {\n case 'left':\n sign = -1;\n // falls through\n case 'right':\n scrollCache.setScrollLeft(scrollCache.getScrollLeft() + velocity * sign);\n break;\n case 'top':\n sign = -1;\n // falls through\n case 'bottom':\n scrollCache.setScrollTop(scrollCache.getScrollTop() + velocity * sign);\n break;\n }\n }\n // left/top are relative to document topleft\n computeBestEdge(left, top) {\n let { edgeThreshold } = this;\n let bestSide = null;\n let scrollCaches = this.scrollCaches || [];\n for (let scrollCache of scrollCaches) {\n let rect = scrollCache.clientRect;\n let leftDist = left - rect.left;\n let rightDist = rect.right - left;\n let topDist = top - rect.top;\n let bottomDist = rect.bottom - top;\n // completely within the rect?\n if (leftDist >= 0 && rightDist >= 0 && topDist >= 0 && bottomDist >= 0) {\n if (topDist <= edgeThreshold && this.everMovedUp && scrollCache.canScrollUp() &&\n (!bestSide || bestSide.distance > topDist)) {\n bestSide = { scrollCache, name: 'top', distance: topDist };\n }\n if (bottomDist <= edgeThreshold && this.everMovedDown && scrollCache.canScrollDown() &&\n (!bestSide || bestSide.distance > bottomDist)) {\n bestSide = { scrollCache, name: 'bottom', distance: bottomDist };\n }\n if (leftDist <= edgeThreshold && this.everMovedLeft && scrollCache.canScrollLeft() &&\n (!bestSide || bestSide.distance > leftDist)) {\n bestSide = { scrollCache, name: 'left', distance: leftDist };\n }\n if (rightDist <= edgeThreshold && this.everMovedRight && scrollCache.canScrollRight() &&\n (!bestSide || bestSide.distance > rightDist)) {\n bestSide = { scrollCache, name: 'right', distance: rightDist };\n }\n }\n }\n return bestSide;\n }\n buildCaches(scrollStartEl) {\n return this.queryScrollEls(scrollStartEl).map((el) => {\n if (el === window) {\n return new WindowScrollGeomCache(false); // false = don't listen to user-generated scrolls\n }\n return new ElementScrollGeomCache(el, false); // false = don't listen to user-generated scrolls\n });\n }\n queryScrollEls(scrollStartEl) {\n let els = [];\n for (let query of this.scrollQuery) {\n if (typeof query === 'object') {\n els.push(query);\n }\n else {\n els.push(...Array.prototype.slice.call((0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.aR)(scrollStartEl).querySelectorAll(query)));\n }\n }\n return els;\n }\n}\n\n/*\nMonitors dragging on an element. Has a number of high-level features:\n- minimum distance required before dragging\n- minimum wait time (\"delay\") before dragging\n- a mirror element that follows the pointer\n*/\nclass FeaturefulElementDragging extends _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bH {\n constructor(containerEl, selector) {\n super(containerEl);\n this.containerEl = containerEl;\n // options that can be directly set by caller\n // the caller can also set the PointerDragging's options as well\n this.delay = null;\n this.minDistance = 0;\n this.touchScrollAllowed = true; // prevents drag from starting and blocks scrolling during drag\n this.mirrorNeedsRevert = false;\n this.isInteracting = false; // is the user validly moving the pointer? lasts until pointerup\n this.isDragging = false; // is it INTENTFULLY dragging? lasts until after revert animation\n this.isDelayEnded = false;\n this.isDistanceSurpassed = false;\n this.delayTimeoutId = null;\n this.onPointerDown = (ev) => {\n if (!this.isDragging) { // so new drag doesn't happen while revert animation is going\n this.isInteracting = true;\n this.isDelayEnded = false;\n this.isDistanceSurpassed = false;\n (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.ar)(document.body);\n (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.at)(document.body);\n // prevent links from being visited if there's an eventual drag.\n // also prevents selection in older browsers (maybe?).\n // not necessary for touch, besides, browser would complain about passiveness.\n if (!ev.isTouch) {\n ev.origEvent.preventDefault();\n }\n this.emitter.trigger('pointerdown', ev);\n if (this.isInteracting && // not destroyed via pointerdown handler\n !this.pointer.shouldIgnoreMove) {\n // actions related to initiating dragstart+dragmove+dragend...\n this.mirror.setIsVisible(false); // reset. caller must set-visible\n this.mirror.start(ev.subjectEl, ev.pageX, ev.pageY); // must happen on first pointer down\n this.startDelay(ev);\n if (!this.minDistance) {\n this.handleDistanceSurpassed(ev);\n }\n }\n }\n };\n this.onPointerMove = (ev) => {\n if (this.isInteracting) {\n this.emitter.trigger('pointermove', ev);\n if (!this.isDistanceSurpassed) {\n let minDistance = this.minDistance;\n let distanceSq; // current distance from the origin, squared\n let { deltaX, deltaY } = ev;\n distanceSq = deltaX * deltaX + deltaY * deltaY;\n if (distanceSq >= minDistance * minDistance) { // use pythagorean theorem\n this.handleDistanceSurpassed(ev);\n }\n }\n if (this.isDragging) {\n // a real pointer move? (not one simulated by scrolling)\n if (ev.origEvent.type !== 'scroll') {\n this.mirror.handleMove(ev.pageX, ev.pageY);\n this.autoScroller.handleMove(ev.pageX, ev.pageY);\n }\n this.emitter.trigger('dragmove', ev);\n }\n }\n };\n this.onPointerUp = (ev) => {\n if (this.isInteracting) {\n this.isInteracting = false;\n (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.as)(document.body);\n (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.au)(document.body);\n this.emitter.trigger('pointerup', ev); // can potentially set mirrorNeedsRevert\n if (this.isDragging) {\n this.autoScroller.stop();\n this.tryStopDrag(ev); // which will stop the mirror\n }\n if (this.delayTimeoutId) {\n clearTimeout(this.delayTimeoutId);\n this.delayTimeoutId = null;\n }\n }\n };\n let pointer = this.pointer = new PointerDragging(containerEl);\n pointer.emitter.on('pointerdown', this.onPointerDown);\n pointer.emitter.on('pointermove', this.onPointerMove);\n pointer.emitter.on('pointerup', this.onPointerUp);\n if (selector) {\n pointer.selector = selector;\n }\n this.mirror = new ElementMirror();\n this.autoScroller = new AutoScroller();\n }\n destroy() {\n this.pointer.destroy();\n // HACK: simulate a pointer-up to end the current drag\n // TODO: fire 'dragend' directly and stop interaction. discourage use of pointerup event (b/c might not fire)\n this.onPointerUp({});\n }\n startDelay(ev) {\n if (typeof this.delay === 'number') {\n this.delayTimeoutId = setTimeout(() => {\n this.delayTimeoutId = null;\n this.handleDelayEnd(ev);\n }, this.delay); // not assignable to number!\n }\n else {\n this.handleDelayEnd(ev);\n }\n }\n handleDelayEnd(ev) {\n this.isDelayEnded = true;\n this.tryStartDrag(ev);\n }\n handleDistanceSurpassed(ev) {\n this.isDistanceSurpassed = true;\n this.tryStartDrag(ev);\n }\n tryStartDrag(ev) {\n if (this.isDelayEnded && this.isDistanceSurpassed) {\n if (!this.pointer.wasTouchScroll || this.touchScrollAllowed) {\n this.isDragging = true;\n this.mirrorNeedsRevert = false;\n this.autoScroller.start(ev.pageX, ev.pageY, this.containerEl);\n this.emitter.trigger('dragstart', ev);\n if (this.touchScrollAllowed === false) {\n this.pointer.cancelTouchScroll();\n }\n }\n }\n }\n tryStopDrag(ev) {\n // .stop() is ALWAYS asynchronous, which we NEED because we want all pointerup events\n // that come from the document to fire beforehand. much more convenient this way.\n this.mirror.stop(this.mirrorNeedsRevert, this.stopDrag.bind(this, ev));\n }\n stopDrag(ev) {\n this.isDragging = false;\n this.emitter.trigger('dragend', ev);\n }\n // fill in the implementations...\n setIgnoreMove(bool) {\n this.pointer.shouldIgnoreMove = bool;\n }\n setMirrorIsVisible(bool) {\n this.mirror.setIsVisible(bool);\n }\n setMirrorNeedsRevert(bool) {\n this.mirrorNeedsRevert = bool;\n }\n setAutoScrollEnabled(bool) {\n this.autoScroller.isEnabled = bool;\n }\n}\n\n/*\nWhen this class is instantiated, it records the offset of an element (relative to the document topleft),\nand continues to monitor scrolling, updating the cached coordinates if it needs to.\nDoes not access the DOM after instantiation, so highly performant.\n\nAlso keeps track of all scrolling/overflow:hidden containers that are parents of the given element\nand an determine if a given point is inside the combined clipping rectangle.\n*/\nclass OffsetTracker {\n constructor(el) {\n this.origRect = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.b7)(el);\n // will work fine for divs that have overflow:hidden\n this.scrollCaches = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.b6)(el).map((scrollEl) => new ElementScrollGeomCache(scrollEl, true));\n }\n destroy() {\n for (let scrollCache of this.scrollCaches) {\n scrollCache.destroy();\n }\n }\n computeLeft() {\n let left = this.origRect.left;\n for (let scrollCache of this.scrollCaches) {\n left += scrollCache.origScrollLeft - scrollCache.getScrollLeft();\n }\n return left;\n }\n computeTop() {\n let top = this.origRect.top;\n for (let scrollCache of this.scrollCaches) {\n top += scrollCache.origScrollTop - scrollCache.getScrollTop();\n }\n return top;\n }\n isWithinClipping(pageX, pageY) {\n let point = { left: pageX, top: pageY };\n for (let scrollCache of this.scrollCaches) {\n if (!isIgnoredClipping(scrollCache.getEventTarget()) &&\n !(0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.aF)(point, scrollCache.clientRect)) {\n return false;\n }\n }\n return true;\n }\n}\n// certain clipping containers should never constrain interactions, like and \n// https://github.com/fullcalendar/fullcalendar/issues/3615\nfunction isIgnoredClipping(node) {\n let tagName = node.tagName;\n return tagName === 'HTML' || tagName === 'BODY';\n}\n\n/*\nTracks movement over multiple droppable areas (aka \"hits\")\nthat exist in one or more DateComponents.\nRelies on an existing draggable.\n\nemits:\n- pointerdown\n- dragstart\n- hitchange - fires initially, even if not over a hit\n- pointerup\n- (hitchange - again, to null, if ended over a hit)\n- dragend\n*/\nclass HitDragging {\n constructor(dragging, droppableStore) {\n // options that can be set by caller\n this.useSubjectCenter = false;\n this.requireInitial = true; // if doesn't start out on a hit, won't emit any events\n this.initialHit = null;\n this.movingHit = null;\n this.finalHit = null; // won't ever be populated if shouldIgnoreMove\n this.handlePointerDown = (ev) => {\n let { dragging } = this;\n this.initialHit = null;\n this.movingHit = null;\n this.finalHit = null;\n this.prepareHits();\n this.processFirstCoord(ev);\n if (this.initialHit || !this.requireInitial) {\n dragging.setIgnoreMove(false);\n // TODO: fire this before computing processFirstCoord, so listeners can cancel. this gets fired by almost every handler :(\n this.emitter.trigger('pointerdown', ev);\n }\n else {\n dragging.setIgnoreMove(true);\n }\n };\n this.handleDragStart = (ev) => {\n this.emitter.trigger('dragstart', ev);\n this.handleMove(ev, true); // force = fire even if initially null\n };\n this.handleDragMove = (ev) => {\n this.emitter.trigger('dragmove', ev);\n this.handleMove(ev);\n };\n this.handlePointerUp = (ev) => {\n this.releaseHits();\n this.emitter.trigger('pointerup', ev);\n };\n this.handleDragEnd = (ev) => {\n if (this.movingHit) {\n this.emitter.trigger('hitupdate', null, true, ev);\n }\n this.finalHit = this.movingHit;\n this.movingHit = null;\n this.emitter.trigger('dragend', ev);\n };\n this.droppableStore = droppableStore;\n dragging.emitter.on('pointerdown', this.handlePointerDown);\n dragging.emitter.on('dragstart', this.handleDragStart);\n dragging.emitter.on('dragmove', this.handleDragMove);\n dragging.emitter.on('pointerup', this.handlePointerUp);\n dragging.emitter.on('dragend', this.handleDragEnd);\n this.dragging = dragging;\n this.emitter = new _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.F();\n }\n // sets initialHit\n // sets coordAdjust\n processFirstCoord(ev) {\n let origPoint = { left: ev.pageX, top: ev.pageY };\n let adjustedPoint = origPoint;\n let subjectEl = ev.subjectEl;\n let subjectRect;\n if (subjectEl instanceof HTMLElement) { // i.e. not a Document/ShadowRoot\n subjectRect = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.b7)(subjectEl);\n adjustedPoint = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.aG)(adjustedPoint, subjectRect);\n }\n let initialHit = this.initialHit = this.queryHitForOffset(adjustedPoint.left, adjustedPoint.top);\n if (initialHit) {\n if (this.useSubjectCenter && subjectRect) {\n let slicedSubjectRect = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.aE)(subjectRect, initialHit.rect);\n if (slicedSubjectRect) {\n adjustedPoint = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.aH)(slicedSubjectRect);\n }\n }\n this.coordAdjust = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.aI)(adjustedPoint, origPoint);\n }\n else {\n this.coordAdjust = { left: 0, top: 0 };\n }\n }\n handleMove(ev, forceHandle) {\n let hit = this.queryHitForOffset(ev.pageX + this.coordAdjust.left, ev.pageY + this.coordAdjust.top);\n if (forceHandle || !isHitsEqual(this.movingHit, hit)) {\n this.movingHit = hit;\n this.emitter.trigger('hitupdate', hit, false, ev);\n }\n }\n prepareHits() {\n this.offsetTrackers = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.b)(this.droppableStore, (interactionSettings) => {\n interactionSettings.component.prepareHits();\n return new OffsetTracker(interactionSettings.el);\n });\n }\n releaseHits() {\n let { offsetTrackers } = this;\n for (let id in offsetTrackers) {\n offsetTrackers[id].destroy();\n }\n this.offsetTrackers = {};\n }\n queryHitForOffset(offsetLeft, offsetTop) {\n let { droppableStore, offsetTrackers } = this;\n let bestHit = null;\n for (let id in droppableStore) {\n let component = droppableStore[id].component;\n let offsetTracker = offsetTrackers[id];\n if (offsetTracker && // wasn't destroyed mid-drag\n offsetTracker.isWithinClipping(offsetLeft, offsetTop)) {\n let originLeft = offsetTracker.computeLeft();\n let originTop = offsetTracker.computeTop();\n let positionLeft = offsetLeft - originLeft;\n let positionTop = offsetTop - originTop;\n let { origRect } = offsetTracker;\n let width = origRect.right - origRect.left;\n let height = origRect.bottom - origRect.top;\n if (\n // must be within the element's bounds\n positionLeft >= 0 && positionLeft < width &&\n positionTop >= 0 && positionTop < height) {\n let hit = component.queryHit(positionLeft, positionTop, width, height);\n if (hit && (\n // make sure the hit is within activeRange, meaning it's not a dead cell\n (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.ba)(hit.dateProfile.activeRange, hit.dateSpan.range)) &&\n (!bestHit || hit.layer > bestHit.layer)) {\n hit.componentId = id;\n hit.context = component.context;\n // TODO: better way to re-orient rectangle\n hit.rect.left += originLeft;\n hit.rect.right += originLeft;\n hit.rect.top += originTop;\n hit.rect.bottom += originTop;\n bestHit = hit;\n }\n }\n }\n }\n return bestHit;\n }\n}\nfunction isHitsEqual(hit0, hit1) {\n if (!hit0 && !hit1) {\n return true;\n }\n if (Boolean(hit0) !== Boolean(hit1)) {\n return false;\n }\n return (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bg)(hit0.dateSpan, hit1.dateSpan);\n}\n\nfunction buildDatePointApiWithContext(dateSpan, context) {\n let props = {};\n for (let transform of context.pluginHooks.datePointTransforms) {\n Object.assign(props, transform(dateSpan, context));\n }\n Object.assign(props, buildDatePointApi(dateSpan, context.dateEnv));\n return props;\n}\nfunction buildDatePointApi(span, dateEnv) {\n return {\n date: dateEnv.toDate(span.range.start),\n dateStr: dateEnv.formatIso(span.range.start, { omitTime: span.allDay }),\n allDay: span.allDay,\n };\n}\n\n/*\nMonitors when the user clicks on a specific date/time of a component.\nA pointerdown+pointerup on the same \"hit\" constitutes a click.\n*/\nclass DateClicking extends _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__._ {\n constructor(settings) {\n super(settings);\n this.handlePointerDown = (pev) => {\n let { dragging } = this;\n let downEl = pev.origEvent.target;\n // do this in pointerdown (not dragend) because DOM might be mutated by the time dragend is fired\n dragging.setIgnoreMove(!this.component.isValidDateDownEl(downEl));\n };\n // won't even fire if moving was ignored\n this.handleDragEnd = (ev) => {\n let { component } = this;\n let { pointer } = this.dragging;\n if (!pointer.wasTouchScroll) {\n let { initialHit, finalHit } = this.hitDragging;\n if (initialHit && finalHit && isHitsEqual(initialHit, finalHit)) {\n let { context } = component;\n let arg = Object.assign(Object.assign({}, buildDatePointApiWithContext(initialHit.dateSpan, context)), { dayEl: initialHit.dayEl, jsEvent: ev.origEvent, view: context.viewApi || context.calendarApi.view });\n context.emitter.trigger('dateClick', arg);\n }\n }\n };\n // we DO want to watch pointer moves because otherwise finalHit won't get populated\n this.dragging = new FeaturefulElementDragging(settings.el);\n this.dragging.autoScroller.isEnabled = false;\n let hitDragging = this.hitDragging = new HitDragging(this.dragging, (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bG)(settings));\n hitDragging.emitter.on('pointerdown', this.handlePointerDown);\n hitDragging.emitter.on('dragend', this.handleDragEnd);\n }\n destroy() {\n this.dragging.destroy();\n }\n}\n\n/*\nTracks when the user selects a portion of time of a component,\nconstituted by a drag over date cells, with a possible delay at the beginning of the drag.\n*/\nclass DateSelecting extends _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__._ {\n constructor(settings) {\n super(settings);\n this.dragSelection = null;\n this.handlePointerDown = (ev) => {\n let { component, dragging } = this;\n let { options } = component.context;\n let canSelect = options.selectable &&\n component.isValidDateDownEl(ev.origEvent.target);\n // don't bother to watch expensive moves if component won't do selection\n dragging.setIgnoreMove(!canSelect);\n // if touch, require user to hold down\n dragging.delay = ev.isTouch ? getComponentTouchDelay$1(component) : null;\n };\n this.handleDragStart = (ev) => {\n this.component.context.calendarApi.unselect(ev); // unselect previous selections\n };\n this.handleHitUpdate = (hit, isFinal) => {\n let { context } = this.component;\n let dragSelection = null;\n let isInvalid = false;\n if (hit) {\n let initialHit = this.hitDragging.initialHit;\n let disallowed = hit.componentId === initialHit.componentId\n && this.isHitComboAllowed\n && !this.isHitComboAllowed(initialHit, hit);\n if (!disallowed) {\n dragSelection = joinHitsIntoSelection(initialHit, hit, context.pluginHooks.dateSelectionTransformers);\n }\n if (!dragSelection || !(0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.b_)(dragSelection, hit.dateProfile, context)) {\n isInvalid = true;\n dragSelection = null;\n }\n }\n if (dragSelection) {\n context.dispatch({ type: 'SELECT_DATES', selection: dragSelection });\n }\n else if (!isFinal) { // only unselect if moved away while dragging\n context.dispatch({ type: 'UNSELECT_DATES' });\n }\n if (!isInvalid) {\n (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.aw)();\n }\n else {\n (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.ax)();\n }\n if (!isFinal) {\n this.dragSelection = dragSelection; // only clear if moved away from all hits while dragging\n }\n };\n this.handlePointerUp = (pev) => {\n if (this.dragSelection) {\n // selection is already rendered, so just need to report selection\n (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.cu)(this.dragSelection, pev, this.component.context);\n this.dragSelection = null;\n }\n };\n let { component } = settings;\n let { options } = component.context;\n let dragging = this.dragging = new FeaturefulElementDragging(settings.el);\n dragging.touchScrollAllowed = false;\n dragging.minDistance = options.selectMinDistance || 0;\n dragging.autoScroller.isEnabled = options.dragScroll;\n let hitDragging = this.hitDragging = new HitDragging(this.dragging, (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bG)(settings));\n hitDragging.emitter.on('pointerdown', this.handlePointerDown);\n hitDragging.emitter.on('dragstart', this.handleDragStart);\n hitDragging.emitter.on('hitupdate', this.handleHitUpdate);\n hitDragging.emitter.on('pointerup', this.handlePointerUp);\n }\n destroy() {\n this.dragging.destroy();\n }\n}\nfunction getComponentTouchDelay$1(component) {\n let { options } = component.context;\n let delay = options.selectLongPressDelay;\n if (delay == null) {\n delay = options.longPressDelay;\n }\n return delay;\n}\nfunction joinHitsIntoSelection(hit0, hit1, dateSelectionTransformers) {\n let dateSpan0 = hit0.dateSpan;\n let dateSpan1 = hit1.dateSpan;\n let ms = [\n dateSpan0.range.start,\n dateSpan0.range.end,\n dateSpan1.range.start,\n dateSpan1.range.end,\n ];\n ms.sort(_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.av);\n let props = {};\n for (let transformer of dateSelectionTransformers) {\n let res = transformer(hit0, hit1);\n if (res === false) {\n return null;\n }\n if (res) {\n Object.assign(props, res);\n }\n }\n props.range = { start: ms[0], end: ms[3] };\n props.allDay = dateSpan0.allDay;\n return props;\n}\n\nclass EventDragging extends _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__._ {\n constructor(settings) {\n super(settings);\n // internal state\n this.subjectEl = null;\n this.subjectSeg = null; // the seg being selected/dragged\n this.isDragging = false;\n this.eventRange = null;\n this.relevantEvents = null; // the events being dragged\n this.receivingContext = null;\n this.validMutation = null;\n this.mutatedRelevantEvents = null;\n this.handlePointerDown = (ev) => {\n let origTarget = ev.origEvent.target;\n let { component, dragging } = this;\n let { mirror } = dragging;\n let { options } = component.context;\n let initialContext = component.context;\n this.subjectEl = ev.subjectEl;\n let subjectSeg = this.subjectSeg = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.$)(ev.subjectEl);\n let eventRange = this.eventRange = subjectSeg.eventRange;\n let eventInstanceId = eventRange.instance.instanceId;\n this.relevantEvents = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.aW)(initialContext.getCurrentData().eventStore, eventInstanceId);\n dragging.minDistance = ev.isTouch ? 0 : options.eventDragMinDistance;\n dragging.delay =\n // only do a touch delay if touch and this event hasn't been selected yet\n (ev.isTouch && eventInstanceId !== component.props.eventSelection) ?\n getComponentTouchDelay(component) :\n null;\n if (options.fixedMirrorParent) {\n mirror.parentNode = options.fixedMirrorParent;\n }\n else {\n mirror.parentNode = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.a0)(origTarget, '.fc');\n }\n mirror.revertDuration = options.dragRevertDuration;\n let isValid = component.isValidSegDownEl(origTarget) &&\n !(0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.a0)(origTarget, '.fc-event-resizer'); // NOT on a resizer\n dragging.setIgnoreMove(!isValid);\n // disable dragging for elements that are resizable (ie, selectable)\n // but are not draggable\n this.isDragging = isValid &&\n ev.subjectEl.classList.contains('fc-event-draggable');\n };\n this.handleDragStart = (ev) => {\n let initialContext = this.component.context;\n let eventRange = this.eventRange;\n let eventInstanceId = eventRange.instance.instanceId;\n if (ev.isTouch) {\n // need to select a different event?\n if (eventInstanceId !== this.component.props.eventSelection) {\n initialContext.dispatch({ type: 'SELECT_EVENT', eventInstanceId });\n }\n }\n else {\n // if now using mouse, but was previous touch interaction, clear selected event\n initialContext.dispatch({ type: 'UNSELECT_EVENT' });\n }\n if (this.isDragging) {\n initialContext.calendarApi.unselect(ev); // unselect *date* selection\n initialContext.emitter.trigger('eventDragStart', {\n el: this.subjectEl,\n event: new _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.a1(initialContext, eventRange.def, eventRange.instance),\n jsEvent: ev.origEvent,\n view: initialContext.viewApi,\n });\n }\n };\n this.handleHitUpdate = (hit, isFinal) => {\n if (!this.isDragging) {\n return;\n }\n let relevantEvents = this.relevantEvents;\n let initialHit = this.hitDragging.initialHit;\n let initialContext = this.component.context;\n // states based on new hit\n let receivingContext = null;\n let mutation = null;\n let mutatedRelevantEvents = null;\n let isInvalid = false;\n let interaction = {\n affectedEvents: relevantEvents,\n mutatedEvents: (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.I)(),\n isEvent: true,\n };\n if (hit) {\n receivingContext = hit.context;\n let receivingOptions = receivingContext.options;\n if (initialContext === receivingContext ||\n (receivingOptions.editable && receivingOptions.droppable)) {\n mutation = computeEventMutation(initialHit, hit, receivingContext.getCurrentData().pluginHooks.eventDragMutationMassagers);\n if (mutation) {\n mutatedRelevantEvents = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bX)(relevantEvents, receivingContext.getCurrentData().eventUiBases, mutation, receivingContext);\n interaction.mutatedEvents = mutatedRelevantEvents;\n if (!(0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bZ)(interaction, hit.dateProfile, receivingContext)) {\n isInvalid = true;\n mutation = null;\n mutatedRelevantEvents = null;\n interaction.mutatedEvents = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.I)();\n }\n }\n }\n else {\n receivingContext = null;\n }\n }\n this.displayDrag(receivingContext, interaction);\n if (!isInvalid) {\n (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.aw)();\n }\n else {\n (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.ax)();\n }\n if (!isFinal) {\n if (initialContext === receivingContext && // TODO: write test for this\n isHitsEqual(initialHit, hit)) {\n mutation = null;\n }\n this.dragging.setMirrorNeedsRevert(!mutation);\n // render the mirror if no already-rendered mirror\n // TODO: wish we could somehow wait for dispatch to guarantee render\n this.dragging.setMirrorIsVisible(!hit || !(0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.aR)(this.subjectEl).querySelector('.fc-event-mirror'));\n // assign states based on new hit\n this.receivingContext = receivingContext;\n this.validMutation = mutation;\n this.mutatedRelevantEvents = mutatedRelevantEvents;\n }\n };\n this.handlePointerUp = () => {\n if (!this.isDragging) {\n this.cleanup(); // because handleDragEnd won't fire\n }\n };\n this.handleDragEnd = (ev) => {\n if (this.isDragging) {\n let initialContext = this.component.context;\n let initialView = initialContext.viewApi;\n let { receivingContext, validMutation } = this;\n let eventDef = this.eventRange.def;\n let eventInstance = this.eventRange.instance;\n let eventApi = new _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.a1(initialContext, eventDef, eventInstance);\n let relevantEvents = this.relevantEvents;\n let mutatedRelevantEvents = this.mutatedRelevantEvents;\n let { finalHit } = this.hitDragging;\n this.clearDrag(); // must happen after revert animation\n initialContext.emitter.trigger('eventDragStop', {\n el: this.subjectEl,\n event: eventApi,\n jsEvent: ev.origEvent,\n view: initialView,\n });\n if (validMutation) {\n // dropped within same calendar\n if (receivingContext === initialContext) {\n let updatedEventApi = new _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.a1(initialContext, mutatedRelevantEvents.defs[eventDef.defId], eventInstance ? mutatedRelevantEvents.instances[eventInstance.instanceId] : null);\n initialContext.dispatch({\n type: 'MERGE_EVENTS',\n eventStore: mutatedRelevantEvents,\n });\n let eventChangeArg = {\n oldEvent: eventApi,\n event: updatedEventApi,\n relatedEvents: (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.w)(mutatedRelevantEvents, initialContext, eventInstance),\n revert() {\n initialContext.dispatch({\n type: 'MERGE_EVENTS',\n eventStore: relevantEvents, // the pre-change data\n });\n },\n };\n let transformed = {};\n for (let transformer of initialContext.getCurrentData().pluginHooks.eventDropTransformers) {\n Object.assign(transformed, transformer(validMutation, initialContext));\n }\n initialContext.emitter.trigger('eventDrop', Object.assign(Object.assign(Object.assign({}, eventChangeArg), transformed), { el: ev.subjectEl, delta: validMutation.datesDelta, jsEvent: ev.origEvent, view: initialView }));\n initialContext.emitter.trigger('eventChange', eventChangeArg);\n // dropped in different calendar\n }\n else if (receivingContext) {\n let eventRemoveArg = {\n event: eventApi,\n relatedEvents: (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.w)(relevantEvents, initialContext, eventInstance),\n revert() {\n initialContext.dispatch({\n type: 'MERGE_EVENTS',\n eventStore: relevantEvents,\n });\n },\n };\n initialContext.emitter.trigger('eventLeave', Object.assign(Object.assign({}, eventRemoveArg), { draggedEl: ev.subjectEl, view: initialView }));\n initialContext.dispatch({\n type: 'REMOVE_EVENTS',\n eventStore: relevantEvents,\n });\n initialContext.emitter.trigger('eventRemove', eventRemoveArg);\n let addedEventDef = mutatedRelevantEvents.defs[eventDef.defId];\n let addedEventInstance = mutatedRelevantEvents.instances[eventInstance.instanceId];\n let addedEventApi = new _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.a1(receivingContext, addedEventDef, addedEventInstance);\n receivingContext.dispatch({\n type: 'MERGE_EVENTS',\n eventStore: mutatedRelevantEvents,\n });\n let eventAddArg = {\n event: addedEventApi,\n relatedEvents: (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.w)(mutatedRelevantEvents, receivingContext, addedEventInstance),\n revert() {\n receivingContext.dispatch({\n type: 'REMOVE_EVENTS',\n eventStore: mutatedRelevantEvents,\n });\n },\n };\n receivingContext.emitter.trigger('eventAdd', eventAddArg);\n if (ev.isTouch) {\n receivingContext.dispatch({\n type: 'SELECT_EVENT',\n eventInstanceId: eventInstance.instanceId,\n });\n }\n receivingContext.emitter.trigger('drop', Object.assign(Object.assign({}, buildDatePointApiWithContext(finalHit.dateSpan, receivingContext)), { draggedEl: ev.subjectEl, jsEvent: ev.origEvent, view: finalHit.context.viewApi }));\n receivingContext.emitter.trigger('eventReceive', Object.assign(Object.assign({}, eventAddArg), { draggedEl: ev.subjectEl, view: finalHit.context.viewApi }));\n }\n }\n else {\n initialContext.emitter.trigger('_noEventDrop');\n }\n }\n this.cleanup();\n };\n let { component } = this;\n let { options } = component.context;\n let dragging = this.dragging = new FeaturefulElementDragging(settings.el);\n dragging.pointer.selector = EventDragging.SELECTOR;\n dragging.touchScrollAllowed = false;\n dragging.autoScroller.isEnabled = options.dragScroll;\n let hitDragging = this.hitDragging = new HitDragging(this.dragging, _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.a8);\n hitDragging.useSubjectCenter = settings.useEventCenter;\n hitDragging.emitter.on('pointerdown', this.handlePointerDown);\n hitDragging.emitter.on('dragstart', this.handleDragStart);\n hitDragging.emitter.on('hitupdate', this.handleHitUpdate);\n hitDragging.emitter.on('pointerup', this.handlePointerUp);\n hitDragging.emitter.on('dragend', this.handleDragEnd);\n }\n destroy() {\n this.dragging.destroy();\n }\n // render a drag state on the next receivingCalendar\n displayDrag(nextContext, state) {\n let initialContext = this.component.context;\n let prevContext = this.receivingContext;\n // does the previous calendar need to be cleared?\n if (prevContext && prevContext !== nextContext) {\n // does the initial calendar need to be cleared?\n // if so, don't clear all the way. we still need to to hide the affectedEvents\n if (prevContext === initialContext) {\n prevContext.dispatch({\n type: 'SET_EVENT_DRAG',\n state: {\n affectedEvents: state.affectedEvents,\n mutatedEvents: (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.I)(),\n isEvent: true,\n },\n });\n // completely clear the old calendar if it wasn't the initial\n }\n else {\n prevContext.dispatch({ type: 'UNSET_EVENT_DRAG' });\n }\n }\n if (nextContext) {\n nextContext.dispatch({ type: 'SET_EVENT_DRAG', state });\n }\n }\n clearDrag() {\n let initialCalendar = this.component.context;\n let { receivingContext } = this;\n if (receivingContext) {\n receivingContext.dispatch({ type: 'UNSET_EVENT_DRAG' });\n }\n // the initial calendar might have an dummy drag state from displayDrag\n if (initialCalendar !== receivingContext) {\n initialCalendar.dispatch({ type: 'UNSET_EVENT_DRAG' });\n }\n }\n cleanup() {\n this.subjectSeg = null;\n this.isDragging = false;\n this.eventRange = null;\n this.relevantEvents = null;\n this.receivingContext = null;\n this.validMutation = null;\n this.mutatedRelevantEvents = null;\n }\n}\n// TODO: test this in IE11\n// QUESTION: why do we need it on the resizable???\nEventDragging.SELECTOR = '.fc-event-draggable, .fc-event-resizable';\nfunction computeEventMutation(hit0, hit1, massagers) {\n let dateSpan0 = hit0.dateSpan;\n let dateSpan1 = hit1.dateSpan;\n let date0 = dateSpan0.range.start;\n let date1 = dateSpan1.range.start;\n let standardProps = {};\n if (dateSpan0.allDay !== dateSpan1.allDay) {\n standardProps.allDay = dateSpan1.allDay;\n standardProps.hasEnd = hit1.context.options.allDayMaintainDuration;\n if (dateSpan1.allDay) {\n // means date1 is already start-of-day,\n // but date0 needs to be converted\n date0 = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.q)(date0);\n }\n }\n let delta = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.aA)(date0, date1, hit0.context.dateEnv, hit0.componentId === hit1.componentId ?\n hit0.largeUnit :\n null);\n if (delta.milliseconds) { // has hours/minutes/seconds\n standardProps.allDay = false;\n }\n let mutation = {\n datesDelta: delta,\n standardProps,\n };\n for (let massager of massagers) {\n massager(mutation, hit0, hit1);\n }\n return mutation;\n}\nfunction getComponentTouchDelay(component) {\n let { options } = component.context;\n let delay = options.eventLongPressDelay;\n if (delay == null) {\n delay = options.longPressDelay;\n }\n return delay;\n}\n\nclass EventResizing extends _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__._ {\n constructor(settings) {\n super(settings);\n // internal state\n this.draggingSegEl = null;\n this.draggingSeg = null; // TODO: rename to resizingSeg? subjectSeg?\n this.eventRange = null;\n this.relevantEvents = null;\n this.validMutation = null;\n this.mutatedRelevantEvents = null;\n this.handlePointerDown = (ev) => {\n let { component } = this;\n let segEl = this.querySegEl(ev);\n let seg = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.$)(segEl);\n let eventRange = this.eventRange = seg.eventRange;\n this.dragging.minDistance = component.context.options.eventDragMinDistance;\n // if touch, need to be working with a selected event\n this.dragging.setIgnoreMove(!this.component.isValidSegDownEl(ev.origEvent.target) ||\n (ev.isTouch && this.component.props.eventSelection !== eventRange.instance.instanceId));\n };\n this.handleDragStart = (ev) => {\n let { context } = this.component;\n let eventRange = this.eventRange;\n this.relevantEvents = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.aW)(context.getCurrentData().eventStore, this.eventRange.instance.instanceId);\n let segEl = this.querySegEl(ev);\n this.draggingSegEl = segEl;\n this.draggingSeg = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.$)(segEl);\n context.calendarApi.unselect();\n context.emitter.trigger('eventResizeStart', {\n el: segEl,\n event: new _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.a1(context, eventRange.def, eventRange.instance),\n jsEvent: ev.origEvent,\n view: context.viewApi,\n });\n };\n this.handleHitUpdate = (hit, isFinal, ev) => {\n let { context } = this.component;\n let relevantEvents = this.relevantEvents;\n let initialHit = this.hitDragging.initialHit;\n let eventInstance = this.eventRange.instance;\n let mutation = null;\n let mutatedRelevantEvents = null;\n let isInvalid = false;\n let interaction = {\n affectedEvents: relevantEvents,\n mutatedEvents: (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.I)(),\n isEvent: true,\n };\n if (hit) {\n let disallowed = hit.componentId === initialHit.componentId\n && this.isHitComboAllowed\n && !this.isHitComboAllowed(initialHit, hit);\n if (!disallowed) {\n mutation = computeMutation(initialHit, hit, ev.subjectEl.classList.contains('fc-event-resizer-start'), eventInstance.range);\n }\n }\n if (mutation) {\n mutatedRelevantEvents = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bX)(relevantEvents, context.getCurrentData().eventUiBases, mutation, context);\n interaction.mutatedEvents = mutatedRelevantEvents;\n if (!(0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bZ)(interaction, hit.dateProfile, context)) {\n isInvalid = true;\n mutation = null;\n mutatedRelevantEvents = null;\n interaction.mutatedEvents = null;\n }\n }\n if (mutatedRelevantEvents) {\n context.dispatch({\n type: 'SET_EVENT_RESIZE',\n state: interaction,\n });\n }\n else {\n context.dispatch({ type: 'UNSET_EVENT_RESIZE' });\n }\n if (!isInvalid) {\n (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.aw)();\n }\n else {\n (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.ax)();\n }\n if (!isFinal) {\n if (mutation && isHitsEqual(initialHit, hit)) {\n mutation = null;\n }\n this.validMutation = mutation;\n this.mutatedRelevantEvents = mutatedRelevantEvents;\n }\n };\n this.handleDragEnd = (ev) => {\n let { context } = this.component;\n let eventDef = this.eventRange.def;\n let eventInstance = this.eventRange.instance;\n let eventApi = new _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.a1(context, eventDef, eventInstance);\n let relevantEvents = this.relevantEvents;\n let mutatedRelevantEvents = this.mutatedRelevantEvents;\n context.emitter.trigger('eventResizeStop', {\n el: this.draggingSegEl,\n event: eventApi,\n jsEvent: ev.origEvent,\n view: context.viewApi,\n });\n if (this.validMutation) {\n let updatedEventApi = new _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.a1(context, mutatedRelevantEvents.defs[eventDef.defId], eventInstance ? mutatedRelevantEvents.instances[eventInstance.instanceId] : null);\n context.dispatch({\n type: 'MERGE_EVENTS',\n eventStore: mutatedRelevantEvents,\n });\n let eventChangeArg = {\n oldEvent: eventApi,\n event: updatedEventApi,\n relatedEvents: (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.w)(mutatedRelevantEvents, context, eventInstance),\n revert() {\n context.dispatch({\n type: 'MERGE_EVENTS',\n eventStore: relevantEvents, // the pre-change events\n });\n },\n };\n context.emitter.trigger('eventResize', Object.assign(Object.assign({}, eventChangeArg), { el: this.draggingSegEl, startDelta: this.validMutation.startDelta || (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.e)(0), endDelta: this.validMutation.endDelta || (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.e)(0), jsEvent: ev.origEvent, view: context.viewApi }));\n context.emitter.trigger('eventChange', eventChangeArg);\n }\n else {\n context.emitter.trigger('_noEventResize');\n }\n // reset all internal state\n this.draggingSeg = null;\n this.relevantEvents = null;\n this.validMutation = null;\n // okay to keep eventInstance around. useful to set it in handlePointerDown\n };\n let { component } = settings;\n let dragging = this.dragging = new FeaturefulElementDragging(settings.el);\n dragging.pointer.selector = '.fc-event-resizer';\n dragging.touchScrollAllowed = false;\n dragging.autoScroller.isEnabled = component.context.options.dragScroll;\n let hitDragging = this.hitDragging = new HitDragging(this.dragging, (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bG)(settings));\n hitDragging.emitter.on('pointerdown', this.handlePointerDown);\n hitDragging.emitter.on('dragstart', this.handleDragStart);\n hitDragging.emitter.on('hitupdate', this.handleHitUpdate);\n hitDragging.emitter.on('dragend', this.handleDragEnd);\n }\n destroy() {\n this.dragging.destroy();\n }\n querySegEl(ev) {\n return (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.a0)(ev.subjectEl, '.fc-event');\n }\n}\nfunction computeMutation(hit0, hit1, isFromStart, instanceRange) {\n let dateEnv = hit0.context.dateEnv;\n let date0 = hit0.dateSpan.range.start;\n let date1 = hit1.dateSpan.range.start;\n let delta = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.aA)(date0, date1, dateEnv, hit0.largeUnit);\n if (isFromStart) {\n if (dateEnv.add(instanceRange.start, delta) < instanceRange.end) {\n return { startDelta: delta };\n }\n }\n else if (dateEnv.add(instanceRange.end, delta) > instanceRange.start) {\n return { endDelta: delta };\n }\n return null;\n}\n\nclass UnselectAuto {\n constructor(context) {\n this.context = context;\n this.isRecentPointerDateSelect = false; // wish we could use a selector to detect date selection, but uses hit system\n this.matchesCancel = false;\n this.matchesEvent = false;\n this.onSelect = (selectInfo) => {\n if (selectInfo.jsEvent) {\n this.isRecentPointerDateSelect = true;\n }\n };\n this.onDocumentPointerDown = (pev) => {\n let unselectCancel = this.context.options.unselectCancel;\n let downEl = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.aS)(pev.origEvent);\n this.matchesCancel = !!(0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.a0)(downEl, unselectCancel);\n this.matchesEvent = !!(0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.a0)(downEl, EventDragging.SELECTOR); // interaction started on an event?\n };\n this.onDocumentPointerUp = (pev) => {\n let { context } = this;\n let { documentPointer } = this;\n let calendarState = context.getCurrentData();\n // touch-scrolling should never unfocus any type of selection\n if (!documentPointer.wasTouchScroll) {\n if (calendarState.dateSelection && // an existing date selection?\n !this.isRecentPointerDateSelect // a new pointer-initiated date selection since last onDocumentPointerUp?\n ) {\n let unselectAuto = context.options.unselectAuto;\n if (unselectAuto && (!unselectAuto || !this.matchesCancel)) {\n context.calendarApi.unselect(pev);\n }\n }\n if (calendarState.eventSelection && // an existing event selected?\n !this.matchesEvent // interaction DIDN'T start on an event\n ) {\n context.dispatch({ type: 'UNSELECT_EVENT' });\n }\n }\n this.isRecentPointerDateSelect = false;\n };\n let documentPointer = this.documentPointer = new PointerDragging(document);\n documentPointer.shouldIgnoreMove = true;\n documentPointer.shouldWatchScroll = false;\n documentPointer.emitter.on('pointerdown', this.onDocumentPointerDown);\n documentPointer.emitter.on('pointerup', this.onDocumentPointerUp);\n /*\n TODO: better way to know about whether there was a selection with the pointer\n */\n context.emitter.on('select', this.onSelect);\n }\n destroy() {\n this.context.emitter.off('select', this.onSelect);\n this.documentPointer.destroy();\n }\n}\n\nconst OPTION_REFINERS = {\n fixedMirrorParent: _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.n,\n};\nconst LISTENER_REFINERS = {\n dateClick: _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.n,\n eventDragStart: _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.n,\n eventDragStop: _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.n,\n eventDrop: _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.n,\n eventResizeStart: _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.n,\n eventResizeStop: _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.n,\n eventResize: _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.n,\n drop: _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.n,\n eventReceive: _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.n,\n eventLeave: _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.n,\n};\n\n/*\nGiven an already instantiated draggable object for one-or-more elements,\nInterprets any dragging as an attempt to drag an events that lives outside\nof a calendar onto a calendar.\n*/\nclass ExternalElementDragging {\n constructor(dragging, suppliedDragMeta) {\n this.receivingContext = null;\n this.droppableEvent = null; // will exist for all drags, even if create:false\n this.suppliedDragMeta = null;\n this.dragMeta = null;\n this.handleDragStart = (ev) => {\n this.dragMeta = this.buildDragMeta(ev.subjectEl);\n };\n this.handleHitUpdate = (hit, isFinal, ev) => {\n let { dragging } = this.hitDragging;\n let receivingContext = null;\n let droppableEvent = null;\n let isInvalid = false;\n let interaction = {\n affectedEvents: (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.I)(),\n mutatedEvents: (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.I)(),\n isEvent: this.dragMeta.create,\n };\n if (hit) {\n receivingContext = hit.context;\n if (this.canDropElOnCalendar(ev.subjectEl, receivingContext)) {\n droppableEvent = computeEventForDateSpan(hit.dateSpan, this.dragMeta, receivingContext);\n interaction.mutatedEvents = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.aX)(droppableEvent);\n isInvalid = !(0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bZ)(interaction, hit.dateProfile, receivingContext);\n if (isInvalid) {\n interaction.mutatedEvents = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.I)();\n droppableEvent = null;\n }\n }\n }\n this.displayDrag(receivingContext, interaction);\n // show mirror if no already-rendered mirror element OR if we are shutting down the mirror (?)\n // TODO: wish we could somehow wait for dispatch to guarantee render\n dragging.setMirrorIsVisible(isFinal || !droppableEvent || !document.querySelector('.fc-event-mirror'));\n if (!isInvalid) {\n (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.aw)();\n }\n else {\n (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.ax)();\n }\n if (!isFinal) {\n dragging.setMirrorNeedsRevert(!droppableEvent);\n this.receivingContext = receivingContext;\n this.droppableEvent = droppableEvent;\n }\n };\n this.handleDragEnd = (pev) => {\n let { receivingContext, droppableEvent } = this;\n this.clearDrag();\n if (receivingContext && droppableEvent) {\n let finalHit = this.hitDragging.finalHit;\n let finalView = finalHit.context.viewApi;\n let dragMeta = this.dragMeta;\n receivingContext.emitter.trigger('drop', Object.assign(Object.assign({}, buildDatePointApiWithContext(finalHit.dateSpan, receivingContext)), { draggedEl: pev.subjectEl, jsEvent: pev.origEvent, view: finalView }));\n if (dragMeta.create) {\n let addingEvents = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.aX)(droppableEvent);\n receivingContext.dispatch({\n type: 'MERGE_EVENTS',\n eventStore: addingEvents,\n });\n if (pev.isTouch) {\n receivingContext.dispatch({\n type: 'SELECT_EVENT',\n eventInstanceId: droppableEvent.instance.instanceId,\n });\n }\n // signal that an external event landed\n receivingContext.emitter.trigger('eventReceive', {\n event: new _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.a1(receivingContext, droppableEvent.def, droppableEvent.instance),\n relatedEvents: [],\n revert() {\n receivingContext.dispatch({\n type: 'REMOVE_EVENTS',\n eventStore: addingEvents,\n });\n },\n draggedEl: pev.subjectEl,\n view: finalView,\n });\n }\n }\n this.receivingContext = null;\n this.droppableEvent = null;\n };\n let hitDragging = this.hitDragging = new HitDragging(dragging, _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.a8);\n hitDragging.requireInitial = false; // will start outside of a component\n hitDragging.emitter.on('dragstart', this.handleDragStart);\n hitDragging.emitter.on('hitupdate', this.handleHitUpdate);\n hitDragging.emitter.on('dragend', this.handleDragEnd);\n this.suppliedDragMeta = suppliedDragMeta;\n }\n buildDragMeta(subjectEl) {\n if (typeof this.suppliedDragMeta === 'object') {\n return (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bJ)(this.suppliedDragMeta);\n }\n if (typeof this.suppliedDragMeta === 'function') {\n return (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bJ)(this.suppliedDragMeta(subjectEl));\n }\n return getDragMetaFromEl(subjectEl);\n }\n displayDrag(nextContext, state) {\n let prevContext = this.receivingContext;\n if (prevContext && prevContext !== nextContext) {\n prevContext.dispatch({ type: 'UNSET_EVENT_DRAG' });\n }\n if (nextContext) {\n nextContext.dispatch({ type: 'SET_EVENT_DRAG', state });\n }\n }\n clearDrag() {\n if (this.receivingContext) {\n this.receivingContext.dispatch({ type: 'UNSET_EVENT_DRAG' });\n }\n }\n canDropElOnCalendar(el, receivingContext) {\n let dropAccept = receivingContext.options.dropAccept;\n if (typeof dropAccept === 'function') {\n return dropAccept.call(receivingContext.calendarApi, el);\n }\n if (typeof dropAccept === 'string' && dropAccept) {\n return Boolean((0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.aQ)(el, dropAccept));\n }\n return true;\n }\n}\n// Utils for computing event store from the DragMeta\n// ----------------------------------------------------------------------------------------------------\nfunction computeEventForDateSpan(dateSpan, dragMeta, context) {\n let defProps = Object.assign({}, dragMeta.leftoverProps);\n for (let transform of context.pluginHooks.externalDefTransforms) {\n Object.assign(defProps, transform(dateSpan, dragMeta));\n }\n let { refined, extra } = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.al)(defProps, context);\n let def = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.ak)(refined, extra, dragMeta.sourceId, dateSpan.allDay, context.options.forceEventDuration || Boolean(dragMeta.duration), // hasEnd\n context);\n let start = dateSpan.range.start;\n // only rely on time info if drop zone is all-day,\n // otherwise, we already know the time\n if (dateSpan.allDay && dragMeta.startTime) {\n start = context.dateEnv.add(start, dragMeta.startTime);\n }\n let end = dragMeta.duration ?\n context.dateEnv.add(start, dragMeta.duration) :\n (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.cv)(dateSpan.allDay, start, context);\n let instance = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.aj)(def.defId, { start, end });\n return { def, instance };\n}\n// Utils for extracting data from element\n// ----------------------------------------------------------------------------------------------------\nfunction getDragMetaFromEl(el) {\n let str = getEmbeddedElData(el, 'event');\n let obj = str ?\n JSON.parse(str) :\n { create: false }; // if no embedded data, assume no event creation\n return (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bJ)(obj);\n}\n_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bI.dataAttrPrefix = '';\nfunction getEmbeddedElData(el, name) {\n let prefix = _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bI.dataAttrPrefix;\n let prefixedName = (prefix ? prefix + '-' : '') + name;\n return el.getAttribute('data-' + prefixedName) || '';\n}\n\n/*\nMakes an element (that is *external* to any calendar) draggable.\nCan pass in data that determines how an event will be created when dropped onto a calendar.\nLeverages FullCalendar's internal drag-n-drop functionality WITHOUT a third-party drag system.\n*/\nclass ExternalDraggable {\n constructor(el, settings = {}) {\n this.handlePointerDown = (ev) => {\n let { dragging } = this;\n let { minDistance, longPressDelay } = this.settings;\n dragging.minDistance =\n minDistance != null ?\n minDistance :\n (ev.isTouch ? 0 : _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.B.eventDragMinDistance);\n dragging.delay =\n ev.isTouch ? // TODO: eventually read eventLongPressDelay instead vvv\n (longPressDelay != null ? longPressDelay : _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.B.longPressDelay) :\n 0;\n };\n this.handleDragStart = (ev) => {\n if (ev.isTouch &&\n this.dragging.delay &&\n ev.subjectEl.classList.contains('fc-event')) {\n this.dragging.mirror.getMirrorEl().classList.add('fc-event-selected');\n }\n };\n this.settings = settings;\n let dragging = this.dragging = new FeaturefulElementDragging(el);\n dragging.touchScrollAllowed = false;\n if (settings.itemSelector != null) {\n dragging.pointer.selector = settings.itemSelector;\n }\n if (settings.appendTo != null) {\n dragging.mirror.parentNode = settings.appendTo; // TODO: write tests\n }\n dragging.emitter.on('pointerdown', this.handlePointerDown);\n dragging.emitter.on('dragstart', this.handleDragStart);\n new ExternalElementDragging(dragging, settings.eventData); // eslint-disable-line no-new\n }\n destroy() {\n this.dragging.destroy();\n }\n}\n\n/*\nDetects when a *THIRD-PARTY* drag-n-drop system interacts with elements.\nThe third-party system is responsible for drawing the visuals effects of the drag.\nThis class simply monitors for pointer movements and fires events.\nIt also has the ability to hide the moving element (the \"mirror\") during the drag.\n*/\nclass InferredElementDragging extends _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bH {\n constructor(containerEl) {\n super(containerEl);\n this.shouldIgnoreMove = false;\n this.mirrorSelector = '';\n this.currentMirrorEl = null;\n this.handlePointerDown = (ev) => {\n this.emitter.trigger('pointerdown', ev);\n if (!this.shouldIgnoreMove) {\n // fire dragstart right away. does not support delay or min-distance\n this.emitter.trigger('dragstart', ev);\n }\n };\n this.handlePointerMove = (ev) => {\n if (!this.shouldIgnoreMove) {\n this.emitter.trigger('dragmove', ev);\n }\n };\n this.handlePointerUp = (ev) => {\n this.emitter.trigger('pointerup', ev);\n if (!this.shouldIgnoreMove) {\n // fire dragend right away. does not support a revert animation\n this.emitter.trigger('dragend', ev);\n }\n };\n let pointer = this.pointer = new PointerDragging(containerEl);\n pointer.emitter.on('pointerdown', this.handlePointerDown);\n pointer.emitter.on('pointermove', this.handlePointerMove);\n pointer.emitter.on('pointerup', this.handlePointerUp);\n }\n destroy() {\n this.pointer.destroy();\n }\n setIgnoreMove(bool) {\n this.shouldIgnoreMove = bool;\n }\n setMirrorIsVisible(bool) {\n if (bool) {\n // restore a previously hidden element.\n // use the reference in case the selector class has already been removed.\n if (this.currentMirrorEl) {\n this.currentMirrorEl.style.visibility = '';\n this.currentMirrorEl = null;\n }\n }\n else {\n let mirrorEl = this.mirrorSelector\n // TODO: somehow query FullCalendars WITHIN shadow-roots\n ? document.querySelector(this.mirrorSelector)\n : null;\n if (mirrorEl) {\n this.currentMirrorEl = mirrorEl;\n mirrorEl.style.visibility = 'hidden';\n }\n }\n }\n}\n\n/*\nBridges third-party drag-n-drop systems with FullCalendar.\nMust be instantiated and destroyed by caller.\n*/\nclass ThirdPartyDraggable {\n constructor(containerOrSettings, settings) {\n let containerEl = document;\n if (\n // wish we could just test instanceof EventTarget, but doesn't work in IE11\n containerOrSettings === document ||\n containerOrSettings instanceof Element) {\n containerEl = containerOrSettings;\n settings = settings || {};\n }\n else {\n settings = (containerOrSettings || {});\n }\n let dragging = this.dragging = new InferredElementDragging(containerEl);\n if (typeof settings.itemSelector === 'string') {\n dragging.pointer.selector = settings.itemSelector;\n }\n else if (containerEl === document) {\n dragging.pointer.selector = '[data-event]';\n }\n if (typeof settings.mirrorSelector === 'string') {\n dragging.mirrorSelector = settings.mirrorSelector;\n }\n new ExternalElementDragging(dragging, settings.eventData); // eslint-disable-line no-new\n }\n destroy() {\n this.dragging.destroy();\n }\n}\n\nvar index = (0,_fullcalendar_core__WEBPACK_IMPORTED_MODULE_1__.createPlugin)({\n name: '@fullcalendar/interaction',\n componentInteractions: [DateClicking, DateSelecting, EventDragging, EventResizing],\n calendarInteractions: [UnselectAuto],\n elementDraggingImpl: FeaturefulElementDragging,\n optionRefiners: OPTION_REFINERS,\n listenerRefiners: LISTENER_REFINERS,\n});\n\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvQGZ1bGxjYWxlbmRhci9pbnRlcmFjdGlvbi9pbmRleC5lc20uanMuanMiLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7QUFBa0Q7QUFDKzRCOztBQUVqOEIsZ0ZBQTJCO0FBQzNCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCO0FBQzVCO0FBQ0E7QUFDQSx1Q0FBdUM7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0QkFBNEI7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrRUFBK0U7QUFDL0U7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DO0FBQ25DO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0ZBQW9GO0FBQ3BGO0FBQ0EsZ0NBQWdDO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBLDJCQUEyQiwwREFBTztBQUNsQztBQUNBLDRFQUE0RSxlQUFlO0FBQzNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0ZBQW9GLGVBQWU7QUFDbkc7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUNBQXFDLCtEQUFjO0FBQ25EO0FBQ0Esb0NBQW9DO0FBQ3BD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Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaURBQWlEO0FBQ2pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtRUFBbUU7QUFDbkU7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxZQUFZLGdFQUFZO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRWdGIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vVnVleHkvLi9ub2RlX21vZHVsZXMvQGZ1bGxjYWxlbmRhci9pbnRlcmFjdGlvbi9pbmRleC5lc20uanM/ZGU2NiJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBjcmVhdGVQbHVnaW4gfSBmcm9tICdAZnVsbGNhbGVuZGFyL2NvcmUnO1xuaW1wb3J0IHsgY29uZmlnLCBFbWl0dGVyLCBlbGVtZW50Q2xvc2VzdCwgYXBwbHlTdHlsZSwgd2hlblRyYW5zaXRpb25Eb25lLCByZW1vdmVFbGVtZW50LCBTY3JvbGxDb250cm9sbGVyLCBFbGVtZW50U2Nyb2xsQ29udHJvbGxlciwgY29tcHV0ZUlubmVyUmVjdCwgV2luZG93U2Nyb2xsQ29udHJvbGxlciwgZ2V0RWxSb290LCBFbGVtZW50RHJhZ2dpbmcsIHByZXZlbnRTZWxlY3Rpb24sIHByZXZlbnRDb250ZXh0TWVudSwgYWxsb3dTZWxlY3Rpb24sIGFsbG93Q29udGV4dE1lbnUsIGNvbXB1dGVSZWN0LCBnZXRDbGlwcGluZ1BhcmVudHMsIHBvaW50SW5zaWRlUmVjdCwgY29uc3RyYWluUG9pbnQsIGludGVyc2VjdFJlY3RzLCBnZXRSZWN0Q2VudGVyLCBkaWZmUG9pbnRzLCBtYXBIYXNoLCByYW5nZUNvbnRhaW5zUmFuZ2UsIGlzRGF0ZVNwYW5zRXF1YWwsIEludGVyYWN0aW9uLCBpbnRlcmFjdGlvblNldHRpbmdzVG9TdG9yZSwgaXNEYXRlU2VsZWN0aW9uVmFsaWQsIGVuYWJsZUN1cnNvciwgZGlzYWJsZUN1cnNvciwgdHJpZ2dlckRhdGVTZWxlY3QsIGNvbXBhcmVOdW1iZXJzLCBnZXRFbFNlZywgZ2V0UmVsZXZhbnRFdmVudHMsIEV2ZW50SW1wbCwgY3JlYXRlRW1wdHlFdmVudFN0b3JlLCBhcHBseU11dGF0aW9uVG9FdmVudFN0b3JlLCBpc0ludGVyYWN0aW9uVmFsaWQsIGJ1aWxkRXZlbnRBcGlzLCBpbnRlcmFjdGlvblNldHRpbmdzU3RvcmUsIHN0YXJ0T2ZEYXksIGRpZmZEYXRlcywgY3JlYXRlRHVyYXRpb24sIGdldEV2ZW50VGFyZ2V0VmlhUm9vdCwgaWRlbnRpdHksIGV2ZW50VHVwbGVUb1N0b3JlLCBwYXJzZURyYWdNZXRhLCBlbGVtZW50TWF0Y2hlcywgcmVmaW5lRXZlbnREZWYsIHBhcnNlRXZlbnREZWYsIGdldERlZmF1bHRFdmVudEVuZCwgY3JlYXRlRXZlbnRJbnN0YW5jZSwgQkFTRV9PUFRJT05fREVGQVVMVFMgfSBmcm9tICdAZnVsbGNhbGVuZGFyL2NvcmUvaW50ZXJuYWwnO1xuXG5jb25maWcudG91Y2hNb3VzZUlnbm9yZVdhaXQgPSA1MDA7XG5sZXQgaWdub3JlTW91c2VEZXB0aCA9IDA7XG5sZXQgbGlzdGVuZXJDbnQgPSAwO1xubGV0IGlzV2luZG93VG91Y2hNb3ZlQ2FuY2VsbGVkID0gZmFsc2U7XG4vKlxuVXNlcyBhIFwicG9pbnRlclwiIGFic3RyYWN0aW9uLCB3aGljaCBtb25pdG9ycyBVSSBldmVudHMgZm9yIGJvdGggbW91c2UgYW5kIHRvdWNoLlxuVHJhY2tzIHdoZW4gdGhlIHBvaW50ZXIgXCJkcmFnc1wiIG9uIGEgY2VydGFpbiBlbGVtZW50LCBtZWFuaW5nIGRvd24rbW92ZSt1cC5cblxuQWxzbywgdHJhY2tzIGlmIHRoZXJlIHdhcyB0b3VjaC1zY3JvbGxpbmcuXG5BbHNvLCBjYW4gcHJldmVudCB0b3VjaC1zY3JvbGxpbmcgZnJvbSBoYXBwZW5pbmcuXG5BbHNvLCBjYW4gZmlyZSBwb2ludGVybW92ZSBldmVudHMgd2hlbiBzY3JvbGxpbmcgaGFwcGVucyB1bmRlcm5lYXRoLCBldmVuIHdoZW4gbm8gcmVhbCBwb2ludGVyIG1vdmVtZW50LlxuXG5lbWl0czpcbi0gcG9pbnRlcmRvd25cbi0gcG9pbnRlcm1vdmVcbi0gcG9pbnRlcnVwXG4qL1xuY2xhc3MgUG9pbnRlckRyYWdnaW5nIHtcbiAgICBjb25zdHJ1Y3Rvcihjb250YWluZXJFbCkge1xuICAgICAgICB0aGlzLnN1YmplY3RFbCA9IG51bGw7XG4gICAgICAgIC8vIG9wdGlvbnMgdGhhdCBjYW4gYmUgZGlyZWN0bHkgYXNzaWduZWQgYnkgY2FsbGVyXG4gICAgICAgIHRoaXMuc2VsZWN0b3IgPSAnJzsgLy8gd2lsbCBjYXVzZSBzdWJqZWN0RWwgaW4gYWxsIGVtaXR0ZWQgZXZlbnRzIHRvIGJlIHRoaXMgZWxlbWVudFxuICAgICAgICB0aGlzLmhhbmRsZVNlbGVjdG9yID0gJyc7XG4gICAgICAgIHRoaXMuc2hvdWxkSWdub3JlTW92ZSA9IGZhbHNlO1xuICAgICAgICB0aGlzLnNob3VsZFdhdGNoU2Nyb2xsID0gdHJ1ZTsgLy8gZm9yIHNpbXVsYXRpbmcgcG9pbnRlcm1vdmUgb24gc2Nyb2xsXG4gICAgICAgIC8vIGludGVybmFsIHN0YXRlc1xuICAgICAgICB0aGlzLmlzRHJhZ2dpbmcgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5pc1RvdWNoRHJhZ2dpbmcgPSBmYWxzZTtcbiAgICAgICAgdGhpcy53YXNUb3VjaFNjcm9sbCA9IGZhbHNlO1xuICAgICAgICAvLyBNb3VzZVxuICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAgIHRoaXMuaGFuZGxlTW91c2VEb3duID0gKGV2KSA9PiB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuc2hvdWxkSWdub3JlTW91c2UoKSAmJlxuICAgICAgICAgICAgICAgIGlzUHJpbWFyeU1vdXNlQnV0dG9uKGV2KSAmJlxuICAgICAgICAgICAgICAgIHRoaXMudHJ5U3RhcnQoZXYpKSB7XG4gICAgICAgICAgICAgICAgbGV0IHBldiA9IHRoaXMuY3JlYXRlRXZlbnRGcm9tTW91c2UoZXYsIHRydWUpO1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdHRlci50cmlnZ2VyKCdwb2ludGVyZG93bicsIHBldik7XG4gICAgICAgICAgICAgICAgdGhpcy5pbml0U2Nyb2xsV2F0Y2gocGV2KTtcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuc2hvdWxkSWdub3JlTW92ZSkge1xuICAgICAgICAgICAgICAgICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCB0aGlzLmhhbmRsZU1vdXNlTW92ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCB0aGlzLmhhbmRsZU1vdXNlVXApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICB0aGlzLmhhbmRsZU1vdXNlTW92ZSA9IChldikgPT4ge1xuICAgICAgICAgICAgbGV0IHBldiA9IHRoaXMuY3JlYXRlRXZlbnRGcm9tTW91c2UoZXYpO1xuICAgICAgICAgICAgdGhpcy5yZWNvcmRDb29yZHMocGV2KTtcbiAgICAgICAgICAgIHRoaXMuZW1pdHRlci50cmlnZ2VyKCdwb2ludGVybW92ZScsIHBldik7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuaGFuZGxlTW91c2VVcCA9IChldikgPT4ge1xuICAgICAgICAgICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgdGhpcy5oYW5kbGVNb3VzZU1vdmUpO1xuICAgICAgICAgICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsIHRoaXMuaGFuZGxlTW91c2VVcCk7XG4gICAgICAgICAgICB0aGlzLmVtaXR0ZXIudHJpZ2dlcigncG9pbnRlcnVwJywgdGhpcy5jcmVhdGVFdmVudEZyb21Nb3VzZShldikpO1xuICAgICAgICAgICAgdGhpcy5jbGVhbnVwKCk7IC8vIGNhbGwgbGFzdCBzbyB0aGF0IHBvaW50ZXJ1cCBoYXMgYWNjZXNzIHRvIHByb3BzXG4gICAgICAgIH07XG4gICAgICAgIC8vIFRvdWNoXG4gICAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAgICAgdGhpcy5oYW5kbGVUb3VjaFN0YXJ0ID0gKGV2KSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy50cnlTdGFydChldikpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmlzVG91Y2hEcmFnZ2luZyA9IHRydWU7XG4gICAgICAgICAgICAgICAgbGV0IHBldiA9IHRoaXMuY3JlYXRlRXZlbnRGcm9tVG91Y2goZXYsIHRydWUpO1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdHRlci50cmlnZ2VyKCdwb2ludGVyZG93bicsIHBldik7XG4gICAgICAgICAgICAgICAgdGhpcy5pbml0U2Nyb2xsV2F0Y2gocGV2KTtcbiAgICAgICAgICAgICAgICAvLyB1bmxpa2UgbW91c2UsIG5lZWQgdG8gYXR0YWNoIHRvIHRhcmdldCwgbm90IGRvY3VtZW50XG4gICAgICAgICAgICAgICAgLy8gaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9hLzQ1NzYwMDE0XG4gICAgICAgICAgICAgICAgbGV0IHRhcmdldEVsID0gZXYudGFyZ2V0O1xuICAgICAgICAgICAgICAgIGlmICghdGhpcy5zaG91bGRJZ25vcmVNb3ZlKSB7XG4gICAgICAgICAgICAgICAgICAgIHRhcmdldEVsLmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNobW92ZScsIHRoaXMuaGFuZGxlVG91Y2hNb3ZlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGFyZ2V0RWwuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2hlbmQnLCB0aGlzLmhhbmRsZVRvdWNoRW5kKTtcbiAgICAgICAgICAgICAgICB0YXJnZXRFbC5hZGRFdmVudExpc3RlbmVyKCd0b3VjaGNhbmNlbCcsIHRoaXMuaGFuZGxlVG91Y2hFbmQpOyAvLyB0cmVhdCBpdCBhcyBhIHRvdWNoIGVuZFxuICAgICAgICAgICAgICAgIC8vIGF0dGFjaCBhIGhhbmRsZXIgdG8gZ2V0IGNhbGxlZCB3aGVuIEFOWSBzY3JvbGwgYWN0aW9uIGhhcHBlbnMgb24gdGhlIHBhZ2UuXG4gICAgICAgICAgICAgICAgLy8gdGhpcyB3YXMgaW1wb3NzaWJsZSB0byBkbyB3aXRoIG5vcm1hbCBvbi9vZmYgYmVjYXVzZSAnc2Nyb2xsJyBkb2Vzbid0IGJ1YmJsZS5cbiAgICAgICAgICAgICAgICAvLyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8zMjk1NDU2NS85NjM0MlxuICAgICAgICAgICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdzY3JvbGwnLCB0aGlzLmhhbmRsZVRvdWNoU2Nyb2xsLCB0cnVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5oYW5kbGVUb3VjaE1vdmUgPSAoZXYpID0+IHtcbiAgICAgICAgICAgIGxldCBwZXYgPSB0aGlzLmNyZWF0ZUV2ZW50RnJvbVRvdWNoKGV2KTtcbiAgICAgICAgICAgIHRoaXMucmVjb3JkQ29vcmRzKHBldik7XG4gICAgICAgICAgICB0aGlzLmVtaXR0ZXIudHJpZ2dlcigncG9pbnRlcm1vdmUnLCBwZXYpO1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLmhhbmRsZVRvdWNoRW5kID0gKGV2KSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5pc0RyYWdnaW5nKSB7IC8vIGRvbmUgdG8gZ3VhcmQgYWdhaW5zdCB0b3VjaGVuZCBmb2xsb3dlZCBieSB0b3VjaGNhbmNlbFxuICAgICAgICAgICAgICAgIGxldCB0YXJnZXRFbCA9IGV2LnRhcmdldDtcbiAgICAgICAgICAgICAgICB0YXJnZXRFbC5yZW1vdmVFdmVudExpc3RlbmVyKCd0b3VjaG1vdmUnLCB0aGlzLmhhbmRsZVRvdWNoTW92ZSk7XG4gICAgICAgICAgICAgICAgdGFyZ2V0RWwucmVtb3ZlRXZlbnRMaXN0ZW5lcigndG91Y2hlbmQnLCB0aGlzLmhhbmRsZVRvdWNoRW5kKTtcbiAgICAgICAgICAgICAgICB0YXJnZXRFbC5yZW1vdmVFdmVudExpc3RlbmVyKCd0b3VjaGNhbmNlbCcsIHRoaXMuaGFuZGxlVG91Y2hFbmQpO1xuICAgICAgICAgICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdzY3JvbGwnLCB0aGlzLmhhbmRsZVRvdWNoU2Nyb2xsLCB0cnVlKTsgLy8gdXNlQ2FwdHVyZWQ9dHJ1ZVxuICAgICAgICAgICAgICAgIHRoaXMuZW1pdHRlci50cmlnZ2VyKCdwb2ludGVydXAnLCB0aGlzLmNyZWF0ZUV2ZW50RnJvbVRvdWNoKGV2KSk7XG4gICAgICAgICAgICAgICAgdGhpcy5jbGVhbnVwKCk7IC8vIGNhbGwgbGFzdCBzbyB0aGF0IHBvaW50ZXJ1cCBoYXMgYWNjZXNzIHRvIHByb3BzXG4gICAgICAgICAgICAgICAgdGhpcy5pc1RvdWNoRHJhZ2dpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBzdGFydElnbm9yaW5nTW91c2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5oYW5kbGVUb3VjaFNjcm9sbCA9ICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMud2FzVG91Y2hTY3JvbGwgPSB0cnVlO1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLmhhbmRsZVNjcm9sbCA9IChldikgPT4ge1xuICAgICAgICAgICAgaWYgKCF0aGlzLnNob3VsZElnbm9yZU1vdmUpIHtcbiAgICAgICAgICAgICAgICBsZXQgcGFnZVggPSAod2luZG93LnBhZ2VYT2Zmc2V0IC0gdGhpcy5wcmV2U2Nyb2xsWCkgKyB0aGlzLnByZXZQYWdlWDtcbiAgICAgICAgICAgICAgICBsZXQgcGFnZVkgPSAod2luZG93LnBhZ2VZT2Zmc2V0IC0gdGhpcy5wcmV2U2Nyb2xsWSkgKyB0aGlzLnByZXZQYWdlWTtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXR0ZXIudHJpZ2dlcigncG9pbnRlcm1vdmUnLCB7XG4gICAgICAgICAgICAgICAgICAgIG9yaWdFdmVudDogZXYsXG4gICAgICAgICAgICAgICAgICAgIGlzVG91Y2g6IHRoaXMuaXNUb3VjaERyYWdnaW5nLFxuICAgICAgICAgICAgICAgICAgICBzdWJqZWN0RWw6IHRoaXMuc3ViamVjdEVsLFxuICAgICAgICAgICAgICAgICAgICBwYWdlWCxcbiAgICAgICAgICAgICAgICAgICAgcGFnZVksXG4gICAgICAgICAgICAgICAgICAgIGRlbHRhWDogcGFnZVggLSB0aGlzLm9yaWdQYWdlWCxcbiAgICAgICAgICAgICAgICAgICAgZGVsdGFZOiBwYWdlWSAtIHRoaXMub3JpZ1BhZ2VZLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICB0aGlzLmNvbnRhaW5lckVsID0gY29udGFpbmVyRWw7XG4gICAgICAgIHRoaXMuZW1pdHRlciA9IG5ldyBFbWl0dGVyKCk7XG4gICAgICAgIGNvbnRhaW5lckVsLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIHRoaXMuaGFuZGxlTW91c2VEb3duKTtcbiAgICAgICAgY29udGFpbmVyRWwuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2hzdGFydCcsIHRoaXMuaGFuZGxlVG91Y2hTdGFydCwgeyBwYXNzaXZlOiB0cnVlIH0pO1xuICAgICAgICBsaXN0ZW5lckNyZWF0ZWQoKTtcbiAgICB9XG4gICAgZGVzdHJveSgpIHtcbiAgICAgICAgdGhpcy5jb250YWluZXJFbC5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZWRvd24nLCB0aGlzLmhhbmRsZU1vdXNlRG93bik7XG4gICAgICAgIHRoaXMuY29udGFpbmVyRWwucmVtb3ZlRXZlbnRMaXN0ZW5lcigndG91Y2hzdGFydCcsIHRoaXMuaGFuZGxlVG91Y2hTdGFydCwgeyBwYXNzaXZlOiB0cnVlIH0pO1xuICAgICAgICBsaXN0ZW5lckRlc3Ryb3llZCgpO1xuICAgIH1cbiAgICB0cnlTdGFydChldikge1xuICAgICAgICBsZXQgc3ViamVjdEVsID0gdGhpcy5xdWVyeVN1YmplY3RFbChldik7XG4gICAgICAgIGxldCBkb3duRWwgPSBldi50YXJnZXQ7XG4gICAgICAgIGlmIChzdWJqZWN0RWwgJiZcbiAgICAgICAgICAgICghdGhpcy5oYW5kbGVTZWxlY3RvciB8fCBlbGVtZW50Q2xvc2VzdChkb3duRWwsIHRoaXMuaGFuZGxlU2VsZWN0b3IpKSkge1xuICAgICAgICAgICAgdGhpcy5zdWJqZWN0RWwgPSBzdWJqZWN0RWw7XG4gICAgICAgICAgICB0aGlzLmlzRHJhZ2dpbmcgPSB0cnVlOyAvLyBkbyB0aGlzIGZpcnN0IHNvIGNhbmNlbFRvdWNoU2Nyb2xsIHdpbGwgd29ya1xuICAgICAgICAgICAgdGhpcy53YXNUb3VjaFNjcm9sbCA9IGZhbHNlO1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBjbGVhbnVwKCkge1xuICAgICAgICBpc1dpbmRvd1RvdWNoTW92ZUNhbmNlbGxlZCA9IGZhbHNlO1xuICAgICAgICB0aGlzLmlzRHJhZ2dpbmcgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5zdWJqZWN0RWwgPSBudWxsO1xuICAgICAgICAvLyBrZWVwIHdhc1RvdWNoU2Nyb2xsIGFyb3VuZCBmb3IgbGF0ZXIgYWNjZXNzXG4gICAgICAgIHRoaXMuZGVzdHJveVNjcm9sbFdhdGNoKCk7XG4gICAgfVxuICAgIHF1ZXJ5U3ViamVjdEVsKGV2KSB7XG4gICAgICAgIGlmICh0aGlzLnNlbGVjdG9yKSB7XG4gICAgICAgICAgICByZXR1cm4gZWxlbWVudENsb3Nlc3QoZXYudGFyZ2V0LCB0aGlzLnNlbGVjdG9yKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5jb250YWluZXJFbDtcbiAgICB9XG4gICAgc2hvdWxkSWdub3JlTW91c2UoKSB7XG4gICAgICAgIHJldHVybiBpZ25vcmVNb3VzZURlcHRoIHx8IHRoaXMuaXNUb3VjaERyYWdnaW5nO1xuICAgIH1cbiAgICAvLyBjYW4gYmUgY2FsbGVkIGJ5IHVzZXIgb2YgdGhpcyBjbGFzcywgdG8gY2FuY2VsIHRvdWNoLWJhc2VkIHNjcm9sbGluZyBmb3IgdGhlIGN1cnJlbnQgZHJhZ1xuICAgIGNhbmNlbFRvdWNoU2Nyb2xsKCkge1xuICAgICAgICBpZiAodGhpcy5pc0RyYWdnaW5nKSB7XG4gICAgICAgICAgICBpc1dpbmRvd1RvdWNoTW92ZUNhbmNlbGxlZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLy8gU2Nyb2xsaW5nIHRoYXQgc2ltdWxhdGVzIHBvaW50ZXJtb3Zlc1xuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICBpbml0U2Nyb2xsV2F0Y2goZXYpIHtcbiAgICAgICAgaWYgKHRoaXMuc2hvdWxkV2F0Y2hTY3JvbGwpIHtcbiAgICAgICAgICAgIHRoaXMucmVjb3JkQ29vcmRzKGV2KTtcbiAgICAgICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdzY3JvbGwnLCB0aGlzLmhhbmRsZVNjcm9sbCwgdHJ1ZSk7IC8vIHVzZUNhcHR1cmU9dHJ1ZVxuICAgICAgICB9XG4gICAgfVxuICAgIHJlY29yZENvb3Jkcyhldikge1xuICAgICAgICBpZiAodGhpcy5zaG91bGRXYXRjaFNjcm9sbCkge1xuICAgICAgICAgICAgdGhpcy5wcmV2UGFnZVggPSBldi5wYWdlWDtcbiAgICAgICAgICAgIHRoaXMucHJldlBhZ2VZID0gZXYucGFnZVk7XG4gICAgICAgICAgICB0aGlzLnByZXZTY3JvbGxYID0gd2luZG93LnBhZ2VYT2Zmc2V0O1xuICAgICAgICAgICAgdGhpcy5wcmV2U2Nyb2xsWSA9IHdpbmRvdy5wYWdlWU9mZnNldDtcbiAgICAgICAgfVxuICAgIH1cbiAgICBkZXN0cm95U2Nyb2xsV2F0Y2goKSB7XG4gICAgICAgIGlmICh0aGlzLnNob3VsZFdhdGNoU2Nyb2xsKSB7XG4gICAgICAgICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignc2Nyb2xsJywgdGhpcy5oYW5kbGVTY3JvbGwsIHRydWUpOyAvLyB1c2VDYXB0dXJlZD10cnVlXG4gICAgICAgIH1cbiAgICB9XG4gICAgLy8gRXZlbnQgTm9ybWFsaXphdGlvblxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICBjcmVhdGVFdmVudEZyb21Nb3VzZShldiwgaXNGaXJzdCkge1xuICAgICAgICBsZXQgZGVsdGFYID0gMDtcbiAgICAgICAgbGV0IGRlbHRhWSA9IDA7XG4gICAgICAgIC8vIFRPRE86IHJlcGVhdCBjb2RlXG4gICAgICAgIGlmIChpc0ZpcnN0KSB7XG4gICAgICAgICAgICB0aGlzLm9yaWdQYWdlWCA9IGV2LnBhZ2VYO1xuICAgICAgICAgICAgdGhpcy5vcmlnUGFnZVkgPSBldi5wYWdlWTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGRlbHRhWCA9IGV2LnBhZ2VYIC0gdGhpcy5vcmlnUGFnZVg7XG4gICAgICAgICAgICBkZWx0YVkgPSBldi5wYWdlWSAtIHRoaXMub3JpZ1BhZ2VZO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBvcmlnRXZlbnQ6IGV2LFxuICAgICAgICAgICAgaXNUb3VjaDogZmFsc2UsXG4gICAgICAgICAgICBzdWJqZWN0RWw6IHRoaXMuc3ViamVjdEVsLFxuICAgICAgICAgICAgcGFnZVg6IGV2LnBhZ2VYLFxuICAgICAgICAgICAgcGFnZVk6IGV2LnBhZ2VZLFxuICAgICAgICAgICAgZGVsdGFYLFxuICAgICAgICAgICAgZGVsdGFZLFxuICAgICAgICB9O1xuICAgIH1cbiAgICBjcmVhdGVFdmVudEZyb21Ub3VjaChldiwgaXNGaXJzdCkge1xuICAgICAgICBsZXQgdG91Y2hlcyA9IGV2LnRvdWNoZXM7XG4gICAgICAgIGxldCBwYWdlWDtcbiAgICAgICAgbGV0IHBhZ2VZO1xuICAgICAgICBsZXQgZGVsdGFYID0gMDtcbiAgICAgICAgbGV0IGRlbHRhWSA9IDA7XG4gICAgICAgIC8vIGlmIHRvdWNoIGNvb3JkcyBhdmFpbGFibGUsIHByZWZlcixcbiAgICAgICAgLy8gYmVjYXVzZSBGRiB3b3VsZCBnaXZlIGJhZCBldi5wYWdlWCBldi5wYWdlWVxuICAgICAgICBpZiAodG91Y2hlcyAmJiB0b3VjaGVzLmxlbmd0aCkge1xuICAgICAgICAgICAgcGFnZVggPSB0b3VjaGVzWzBdLnBhZ2VYO1xuICAgICAgICAgICAgcGFnZVkgPSB0b3VjaGVzWzBdLnBhZ2VZO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgcGFnZVggPSBldi5wYWdlWDtcbiAgICAgICAgICAgIHBhZ2VZID0gZXYucGFnZVk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gVE9ETzogcmVwZWF0IGNvZGVcbiAgICAgICAgaWYgKGlzRmlyc3QpIHtcbiAgICAgICAgICAgIHRoaXMub3JpZ1BhZ2VYID0gcGFnZVg7XG4gICAgICAgICAgICB0aGlzLm9yaWdQYWdlWSA9IHBhZ2VZO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZGVsdGFYID0gcGFnZVggLSB0aGlzLm9yaWdQYWdlWDtcbiAgICAgICAgICAgIGRlbHRhWSA9IHBhZ2VZIC0gdGhpcy5vcmlnUGFnZVk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIG9yaWdFdmVudDogZXYsXG4gICAgICAgICAgICBpc1RvdWNoOiB0cnVlLFxuICAgICAgICAgICAgc3ViamVjdEVsOiB0aGlzLnN1YmplY3RFbCxcbiAgICAgICAgICAgIHBhZ2VYLFxuICAgICAgICAgICAgcGFnZVksXG4gICAgICAgICAgICBkZWx0YVgsXG4gICAgICAgICAgICBkZWx0YVksXG4gICAgICAgIH07XG4gICAgfVxufVxuLy8gUmV0dXJucyBhIGJvb2xlYW4gd2hldGhlciB0aGlzIHdhcyBhIGxlZnQgbW91c2UgY2xpY2sgYW5kIG5vIGN0cmwga2V5ICh3aGljaCBtZWFucyByaWdodCBjbGljayBvbiBNYWMpXG5mdW5jdGlvbiBpc1ByaW1hcnlNb3VzZUJ1dHRvbihldikge1xuICAgIHJldHVybiBldi5idXR0b24gPT09IDAgJiYgIWV2LmN0cmxLZXk7XG59XG4vLyBJZ25vcmluZyBmYWtlIG1vdXNlIGV2ZW50cyBnZW5lcmF0ZWQgYnkgdG91Y2hcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbmZ1bmN0aW9uIHN0YXJ0SWdub3JpbmdNb3VzZSgpIHtcbiAgICBpZ25vcmVNb3VzZURlcHRoICs9IDE7XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIGlnbm9yZU1vdXNlRGVwdGggLT0gMTtcbiAgICB9LCBjb25maWcudG91Y2hNb3VzZUlnbm9yZVdhaXQpO1xufVxuLy8gV2Ugd2FudCB0byBhdHRhY2ggdG91Y2htb3ZlIGFzIGVhcmx5IGFzIHBvc3NpYmxlIGZvciBTYWZhcmlcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbmZ1bmN0aW9uIGxpc3RlbmVyQ3JlYXRlZCgpIHtcbiAgICBsaXN0ZW5lckNudCArPSAxO1xuICAgIGlmIChsaXN0ZW5lckNudCA9PT0gMSkge1xuICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2htb3ZlJywgb25XaW5kb3dUb3VjaE1vdmUsIHsgcGFzc2l2ZTogZmFsc2UgfSk7XG4gICAgfVxufVxuZnVuY3Rpb24gbGlzdGVuZXJEZXN0cm95ZWQoKSB7XG4gICAgbGlzdGVuZXJDbnQgLT0gMTtcbiAgICBpZiAoIWxpc3RlbmVyQ250KSB7XG4gICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCd0b3VjaG1vdmUnLCBvbldpbmRvd1RvdWNoTW92ZSwgeyBwYXNzaXZlOiBmYWxzZSB9KTtcbiAgICB9XG59XG5mdW5jdGlvbiBvbldpbmRvd1RvdWNoTW92ZShldikge1xuICAgIGlmIChpc1dpbmRvd1RvdWNoTW92ZUNhbmNlbGxlZCkge1xuICAgICAgICBldi5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cbn1cblxuLypcbkFuIGVmZmVjdCBpbiB3aGljaCBhbiBlbGVtZW50IGZvbGxvd3MgdGhlIG1vdmVtZW50IG9mIGEgcG9pbnRlciBhY3Jvc3MgdGhlIHNjcmVlbi5cblRoZSBtb3ZpbmcgZWxlbWVudCBpcyBhIGNsb25lIG9mIHNvbWUgb3RoZXIgZWxlbWVudC5cbk11c3QgY2FsbCBzdGFydCArIGhhbmRsZU1vdmUgKyBzdG9wLlxuKi9cbmNsYXNzIEVsZW1lbnRNaXJyb3Ige1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLmlzVmlzaWJsZSA9IGZhbHNlOyAvLyBtdXN0IGJlIGV4cGxpY2l0bHkgZW5hYmxlZFxuICAgICAgICB0aGlzLnNvdXJjZUVsID0gbnVsbDtcbiAgICAgICAgdGhpcy5taXJyb3JFbCA9IG51bGw7XG4gICAgICAgIHRoaXMuc291cmNlRWxSZWN0ID0gbnVsbDsgLy8gc2NyZWVuIGNvb3JkcyByZWxhdGl2ZSB0byB2aWV3cG9ydFxuICAgICAgICAvLyBvcHRpb25zIHRoYXQgY2FuIGJlIHNldCBkaXJlY3RseSBieSBjYWxsZXJcbiAgICAgICAgdGhpcy5wYXJlbnROb2RlID0gZG9jdW1lbnQuYm9keTsgLy8gSElHSExZIFNVR0dFU1RFRCB0byBzZXQgdGhpcyB0byBzaWRlc3RlcCBTaGFkb3dET00gaXNzdWVzXG4gICAgICAgIHRoaXMuekluZGV4ID0gOTk5OTtcbiAgICAgICAgdGhpcy5yZXZlcnREdXJhdGlvbiA9IDA7XG4gICAgfVxuICAgIHN0YXJ0KHNvdXJjZUVsLCBwYWdlWCwgcGFnZVkpIHtcbiAgICAgICAgdGhpcy5zb3VyY2VFbCA9IHNvdXJjZUVsO1xuICAgICAgICB0aGlzLnNvdXJjZUVsUmVjdCA9IHRoaXMuc291cmNlRWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICAgIHRoaXMub3JpZ1NjcmVlblggPSBwYWdlWCAtIHdpbmRvdy5wYWdlWE9mZnNldDtcbiAgICAgICAgdGhpcy5vcmlnU2NyZWVuWSA9IHBhZ2VZIC0gd2luZG93LnBhZ2VZT2Zmc2V0O1xuICAgICAgICB0aGlzLmRlbHRhWCA9IDA7XG4gICAgICAgIHRoaXMuZGVsdGFZID0gMDtcbiAgICAgICAgdGhpcy51cGRhdGVFbFBvc2l0aW9uKCk7XG4gICAgfVxuICAgIGhhbmRsZU1vdmUocGFnZVgsIHBhZ2VZKSB7XG4gICAgICAgIHRoaXMuZGVsdGFYID0gKHBhZ2VYIC0gd2luZG93LnBhZ2VYT2Zmc2V0KSAtIHRoaXMub3JpZ1NjcmVlblg7XG4gICAgICAgIHRoaXMuZGVsdGFZID0gKHBhZ2VZIC0gd2luZG93LnBhZ2VZT2Zmc2V0KSAtIHRoaXMub3JpZ1NjcmVlblk7XG4gICAgICAgIHRoaXMudXBkYXRlRWxQb3NpdGlvbigpO1xuICAgIH1cbiAgICAvLyBjYW4gYmUgY2FsbGVkIGJlZm9yZSBzdGFydFxuICAgIHNldElzVmlzaWJsZShib29sKSB7XG4gICAgICAgIGlmIChib29sKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuaXNWaXNpYmxlKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMubWlycm9yRWwpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5taXJyb3JFbC5zdHlsZS5kaXNwbGF5ID0gJyc7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuaXNWaXNpYmxlID0gYm9vbDsgLy8gbmVlZHMgdG8gaGFwcGVuIGJlZm9yZSB1cGRhdGVFbFBvc2l0aW9uXG4gICAgICAgICAgICAgICAgdGhpcy51cGRhdGVFbFBvc2l0aW9uKCk7IC8vIGJlY2F1c2Ugd2FzIG5vdCB1cGRhdGluZyB0aGUgcG9zaXRpb24gd2hpbGUgaW52aXNpYmxlXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodGhpcy5pc1Zpc2libGUpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLm1pcnJvckVsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5taXJyb3JFbC5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5pc1Zpc2libGUgPSBib29sO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8vIGFsd2F5cyBhc3luY1xuICAgIHN0b3AobmVlZHNSZXZlcnRBbmltYXRpb24sIGNhbGxiYWNrKSB7XG4gICAgICAgIGxldCBkb25lID0gKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5jbGVhbnVwKCk7XG4gICAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICB9O1xuICAgICAgICBpZiAobmVlZHNSZXZlcnRBbmltYXRpb24gJiZcbiAgICAgICAgICAgIHRoaXMubWlycm9yRWwgJiZcbiAgICAgICAgICAgIHRoaXMuaXNWaXNpYmxlICYmXG4gICAgICAgICAgICB0aGlzLnJldmVydER1cmF0aW9uICYmIC8vIGlmIDAsIHRyYW5zaXRpb24gd29uJ3Qgd29ya1xuICAgICAgICAgICAgKHRoaXMuZGVsdGFYIHx8IHRoaXMuZGVsdGFZKSAvLyBpZiBzYW1lIGNvb3JkcywgdHJhbnNpdGlvbiB3b24ndCB3b3JrXG4gICAgICAgICkge1xuICAgICAgICAgICAgdGhpcy5kb1JldmVydEFuaW1hdGlvbihkb25lLCB0aGlzLnJldmVydER1cmF0aW9uKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoZG9uZSwgMCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZG9SZXZlcnRBbmltYXRpb24oY2FsbGJhY2ssIHJldmVydER1cmF0aW9uKSB7XG4gICAgICAgIGxldCBtaXJyb3JFbCA9IHRoaXMubWlycm9yRWw7XG4gICAgICAgIGxldCBmaW5hbFNvdXJjZUVsUmVjdCA9IHRoaXMuc291cmNlRWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7IC8vIGJlY2F1c2UgYXV0b3Njcm9sbGluZyBtaWdodCBoYXZlIGhhcHBlbmVkXG4gICAgICAgIG1pcnJvckVsLnN0eWxlLnRyYW5zaXRpb24gPVxuICAgICAgICAgICAgJ3RvcCAnICsgcmV2ZXJ0RHVyYXRpb24gKyAnbXMsJyArXG4gICAgICAgICAgICAgICAgJ2xlZnQgJyArIHJldmVydER1cmF0aW9uICsgJ21zJztcbiAgICAgICAgYXBwbHlTdHlsZShtaXJyb3JFbCwge1xuICAgICAgICAgICAgbGVmdDogZmluYWxTb3VyY2VFbFJlY3QubGVmdCxcbiAgICAgICAgICAgIHRvcDogZmluYWxTb3VyY2VFbFJlY3QudG9wLFxuICAgICAgICB9KTtcbiAgICAgICAgd2hlblRyYW5zaXRpb25Eb25lKG1pcnJvckVsLCAoKSA9PiB7XG4gICAgICAgICAgICBtaXJyb3JFbC5zdHlsZS50cmFuc2l0aW9uID0gJyc7XG4gICAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICB9KTtcbiAgICB9XG4gICAgY2xlYW51cCgpIHtcbiAgICAgICAgaWYgKHRoaXMubWlycm9yRWwpIHtcbiAgICAgICAgICAgIHJlbW92ZUVsZW1lbnQodGhpcy5taXJyb3JFbCk7XG4gICAgICAgICAgICB0aGlzLm1pcnJvckVsID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNvdXJjZUVsID0gbnVsbDtcbiAgICB9XG4gICAgdXBkYXRlRWxQb3NpdGlvbigpIHtcbiAgICAgICAgaWYgKHRoaXMuc291cmNlRWwgJiYgdGhpcy5pc1Zpc2libGUpIHtcbiAgICAgICAgICAgIGFwcGx5U3R5bGUodGhpcy5nZXRNaXJyb3JFbCgpLCB7XG4gICAgICAgICAgICAgICAgbGVmdDogdGhpcy5zb3VyY2VFbFJlY3QubGVmdCArIHRoaXMuZGVsdGFYLFxuICAgICAgICAgICAgICAgIHRvcDogdGhpcy5zb3VyY2VFbFJlY3QudG9wICsgdGhpcy5kZWx0YVksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXRNaXJyb3JFbCgpIHtcbiAgICAgICAgbGV0IHNvdXJjZUVsUmVjdCA9IHRoaXMuc291cmNlRWxSZWN0O1xuICAgICAgICBsZXQgbWlycm9yRWwgPSB0aGlzLm1pcnJvckVsO1xuICAgICAgICBpZiAoIW1pcnJvckVsKSB7XG4gICAgICAgICAgICBtaXJyb3JFbCA9IHRoaXMubWlycm9yRWwgPSB0aGlzLnNvdXJjZUVsLmNsb25lTm9kZSh0cnVlKTsgLy8gY2xvbmVDaGlsZHJlbj10cnVlXG4gICAgICAgICAgICAvLyB3ZSBkb24ndCB3YW50IGxvbmcgdGFwcyBvciBhbnkgbW91c2UgaW50ZXJhY3Rpb24gY2F1c2luZyBzZWxlY3Rpb24vbWVudXMuXG4gICAgICAgICAgICAvLyB3b3VsZCB1c2UgcHJldmVudFNlbGVjdGlvbigpLCBidXQgdGhhdCBwcmV2ZW50cyBzZWxlY3RzdGFydCwgY2F1c2luZyBwcm9ibGVtcy5cbiAgICAgICAgICAgIG1pcnJvckVsLmNsYXNzTGlzdC5hZGQoJ2ZjLXVuc2VsZWN0YWJsZScpO1xuICAgICAgICAgICAgbWlycm9yRWwuY2xhc3NMaXN0LmFkZCgnZmMtZXZlbnQtZHJhZ2dpbmcnKTtcbiAgICAgICAgICAgIGFwcGx5U3R5bGUobWlycm9yRWwsIHtcbiAgICAgICAgICAgICAgICBwb3NpdGlvbjogJ2ZpeGVkJyxcbiAgICAgICAgICAgICAgICB6SW5kZXg6IHRoaXMuekluZGV4LFxuICAgICAgICAgICAgICAgIHZpc2liaWxpdHk6ICcnLFxuICAgICAgICAgICAgICAgIGJveFNpemluZzogJ2JvcmRlci1ib3gnLFxuICAgICAgICAgICAgICAgIHdpZHRoOiBzb3VyY2VFbFJlY3QucmlnaHQgLSBzb3VyY2VFbFJlY3QubGVmdCxcbiAgICAgICAgICAgICAgICBoZWlnaHQ6IHNvdXJjZUVsUmVjdC5ib3R0b20gLSBzb3VyY2VFbFJlY3QudG9wLFxuICAgICAgICAgICAgICAgIHJpZ2h0OiAnYXV0bycsXG4gICAgICAgICAgICAgICAgYm90dG9tOiAnYXV0bycsXG4gICAgICAgICAgICAgICAgbWFyZ2luOiAwLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLnBhcmVudE5vZGUuYXBwZW5kQ2hpbGQobWlycm9yRWwpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBtaXJyb3JFbDtcbiAgICB9XG59XG5cbi8qXG5JcyBhIGNhY2hlIGZvciBhIGdpdmVuIGVsZW1lbnQncyBzY3JvbGwgaW5mb3JtYXRpb24gKGFsbCB0aGUgaW5mbyB0aGF0IFNjcm9sbENvbnRyb2xsZXIgc3RvcmVzKVxuaW4gYWRkaXRpb24gdGhlIFwiY2xpZW50IHJlY3RhbmdsZVwiIG9mIHRoZSBlbGVtZW50Li4gdGhlIGFyZWEgd2l0aGluIHRoZSBzY3JvbGxiYXJzLlxuXG5UaGUgY2FjaGUgY2FuIGJlIGluIG9uZSBvZiB0d28gbW9kZXM6XG4tIGRvZXNMaXN0ZW5pbmc6ZmFsc2UgLSBpZ25vcmVzIHdoZW4gdGhlIGNvbnRhaW5lciBpcyBzY3JvbGxlZCBieSBzb21lb25lIGVsc2Vcbi0gZG9lc0xpc3RlbmluZzp0cnVlIC0gd2F0Y2ggZm9yIHNjcm9sbGluZyBhbmQgdXBkYXRlIHRoZSBjYWNoZVxuKi9cbmNsYXNzIFNjcm9sbEdlb21DYWNoZSBleHRlbmRzIFNjcm9sbENvbnRyb2xsZXIge1xuICAgIGNvbnN0cnVjdG9yKHNjcm9sbENvbnRyb2xsZXIsIGRvZXNMaXN0ZW5pbmcpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgdGhpcy5oYW5kbGVTY3JvbGwgPSAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnNjcm9sbFRvcCA9IHRoaXMuc2Nyb2xsQ29udHJvbGxlci5nZXRTY3JvbGxUb3AoKTtcbiAgICAgICAgICAgIHRoaXMuc2Nyb2xsTGVmdCA9IHRoaXMuc2Nyb2xsQ29udHJvbGxlci5nZXRTY3JvbGxMZWZ0KCk7XG4gICAgICAgICAgICB0aGlzLmhhbmRsZVNjcm9sbENoYW5nZSgpO1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLnNjcm9sbENvbnRyb2xsZXIgPSBzY3JvbGxDb250cm9sbGVyO1xuICAgICAgICB0aGlzLmRvZXNMaXN0ZW5pbmcgPSBkb2VzTGlzdGVuaW5nO1xuICAgICAgICB0aGlzLnNjcm9sbFRvcCA9IHRoaXMub3JpZ1Njcm9sbFRvcCA9IHNjcm9sbENvbnRyb2xsZXIuZ2V0U2Nyb2xsVG9wKCk7XG4gICAgICAgIHRoaXMuc2Nyb2xsTGVmdCA9IHRoaXMub3JpZ1Njcm9sbExlZnQgPSBzY3JvbGxDb250cm9sbGVyLmdldFNjcm9sbExlZnQoKTtcbiAgICAgICAgdGhpcy5zY3JvbGxXaWR0aCA9IHNjcm9sbENvbnRyb2xsZXIuZ2V0U2Nyb2xsV2lkdGgoKTtcbiAgICAgICAgdGhpcy5zY3JvbGxIZWlnaHQgPSBzY3JvbGxDb250cm9sbGVyLmdldFNjcm9sbEhlaWdodCgpO1xuICAgICAgICB0aGlzLmNsaWVudFdpZHRoID0gc2Nyb2xsQ29udHJvbGxlci5nZXRDbGllbnRXaWR0aCgpO1xuICAgICAgICB0aGlzLmNsaWVudEhlaWdodCA9IHNjcm9sbENvbnRyb2xsZXIuZ2V0Q2xpZW50SGVpZ2h0KCk7XG4gICAgICAgIHRoaXMuY2xpZW50UmVjdCA9IHRoaXMuY29tcHV0ZUNsaWVudFJlY3QoKTsgLy8gZG8gbGFzdCBpbiBjYXNlIGl0IG5lZWRzIGNhY2hlZCB2YWx1ZXNcbiAgICAgICAgaWYgKHRoaXMuZG9lc0xpc3RlbmluZykge1xuICAgICAgICAgICAgdGhpcy5nZXRFdmVudFRhcmdldCgpLmFkZEV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsIHRoaXMuaGFuZGxlU2Nyb2xsKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBkZXN0cm95KCkge1xuICAgICAgICBpZiAodGhpcy5kb2VzTGlzdGVuaW5nKSB7XG4gICAgICAgICAgICB0aGlzLmdldEV2ZW50VGFyZ2V0KCkucmVtb3ZlRXZlbnRMaXN0ZW5lcignc2Nyb2xsJywgdGhpcy5oYW5kbGVTY3JvbGwpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGdldFNjcm9sbFRvcCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2Nyb2xsVG9wO1xuICAgIH1cbiAgICBnZXRTY3JvbGxMZWZ0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5zY3JvbGxMZWZ0O1xuICAgIH1cbiAgICBzZXRTY3JvbGxUb3AodG9wKSB7XG4gICAgICAgIHRoaXMuc2Nyb2xsQ29udHJvbGxlci5zZXRTY3JvbGxUb3AodG9wKTtcbiAgICAgICAgaWYgKCF0aGlzLmRvZXNMaXN0ZW5pbmcpIHtcbiAgICAgICAgICAgIC8vIHdlIGFyZSBub3QgcmVseWluZyBvbiB0aGUgZWxlbWVudCB0byBub3JtYWxpemUgb3V0LW9mLWJvdW5kcyBzY3JvbGwgdmFsdWVzXG4gICAgICAgICAgICAvLyBzbyB3ZSBuZWVkIHRvIHNhbml0aXplIG91cnNlbHZlc1xuICAgICAgICAgICAgdGhpcy5zY3JvbGxUb3AgPSBNYXRoLm1heChNYXRoLm1pbih0b3AsIHRoaXMuZ2V0TWF4U2Nyb2xsVG9wKCkpLCAwKTtcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlU2Nyb2xsQ2hhbmdlKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgc2V0U2Nyb2xsTGVmdCh0b3ApIHtcbiAgICAgICAgdGhpcy5zY3JvbGxDb250cm9sbGVyLnNldFNjcm9sbExlZnQodG9wKTtcbiAgICAgICAgaWYgKCF0aGlzLmRvZXNMaXN0ZW5pbmcpIHtcbiAgICAgICAgICAgIC8vIHdlIGFyZSBub3QgcmVseWluZyBvbiB0aGUgZWxlbWVudCB0byBub3JtYWxpemUgb3V0LW9mLWJvdW5kcyBzY3JvbGwgdmFsdWVzXG4gICAgICAgICAgICAvLyBzbyB3ZSBuZWVkIHRvIHNhbml0aXplIG91cnNlbHZlc1xuICAgICAgICAgICAgdGhpcy5zY3JvbGxMZWZ0ID0gTWF0aC5tYXgoTWF0aC5taW4odG9wLCB0aGlzLmdldE1heFNjcm9sbExlZnQoKSksIDApO1xuICAgICAgICAgICAgdGhpcy5oYW5kbGVTY3JvbGxDaGFuZ2UoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXRDbGllbnRXaWR0aCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2xpZW50V2lkdGg7XG4gICAgfVxuICAgIGdldENsaWVudEhlaWdodCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2xpZW50SGVpZ2h0O1xuICAgIH1cbiAgICBnZXRTY3JvbGxXaWR0aCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2Nyb2xsV2lkdGg7XG4gICAgfVxuICAgIGdldFNjcm9sbEhlaWdodCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2Nyb2xsSGVpZ2h0O1xuICAgIH1cbiAgICBoYW5kbGVTY3JvbGxDaGFuZ2UoKSB7XG4gICAgfVxufVxuXG5jbGFzcyBFbGVtZW50U2Nyb2xsR2VvbUNhY2hlIGV4dGVuZHMgU2Nyb2xsR2VvbUNhY2hlIHtcbiAgICBjb25zdHJ1Y3RvcihlbCwgZG9lc0xpc3RlbmluZykge1xuICAgICAgICBzdXBlcihuZXcgRWxlbWVudFNjcm9sbENvbnRyb2xsZXIoZWwpLCBkb2VzTGlzdGVuaW5nKTtcbiAgICB9XG4gICAgZ2V0RXZlbnRUYXJnZXQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNjcm9sbENvbnRyb2xsZXIuZWw7XG4gICAgfVxuICAgIGNvbXB1dGVDbGllbnRSZWN0KCkge1xuICAgICAgICByZXR1cm4gY29tcHV0ZUlubmVyUmVjdCh0aGlzLnNjcm9sbENvbnRyb2xsZXIuZWwpO1xuICAgIH1cbn1cblxuY2xhc3MgV2luZG93U2Nyb2xsR2VvbUNhY2hlIGV4dGVuZHMgU2Nyb2xsR2VvbUNhY2hlIHtcbiAgICBjb25zdHJ1Y3Rvcihkb2VzTGlzdGVuaW5nKSB7XG4gICAgICAgIHN1cGVyKG5ldyBXaW5kb3dTY3JvbGxDb250cm9sbGVyKCksIGRvZXNMaXN0ZW5pbmcpO1xuICAgIH1cbiAgICBnZXRFdmVudFRhcmdldCgpIHtcbiAgICAgICAgcmV0dXJuIHdpbmRvdztcbiAgICB9XG4gICAgY29tcHV0ZUNsaWVudFJlY3QoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBsZWZ0OiB0aGlzLnNjcm9sbExlZnQsXG4gICAgICAgICAgICByaWdodDogdGhpcy5zY3JvbGxMZWZ0ICsgdGhpcy5jbGllbnRXaWR0aCxcbiAgICAgICAgICAgIHRvcDogdGhpcy5zY3JvbGxUb3AsXG4gICAgICAgICAgICBib3R0b206IHRoaXMuc2Nyb2xsVG9wICsgdGhpcy5jbGllbnRIZWlnaHQsXG4gICAgICAgIH07XG4gICAgfVxuICAgIC8vIHRoZSB3aW5kb3cgaXMgdGhlIG9ubHkgc2Nyb2xsIG9iamVjdCB0aGF0IGNoYW5nZXMgaXQncyByZWN0YW5nbGUgcmVsYXRpdmVcbiAgICAvLyB0byB0aGUgZG9jdW1lbnQncyB0b3BsZWZ0IGFzIGl0IHNjcm9sbHNcbiAgICBoYW5kbGVTY3JvbGxDaGFuZ2UoKSB7XG4gICAgICAgIHRoaXMuY2xpZW50UmVjdCA9IHRoaXMuY29tcHV0ZUNsaWVudFJlY3QoKTtcbiAgICB9XG59XG5cbi8vIElmIGF2YWlsYWJsZSB3ZSBhcmUgdXNpbmcgbmF0aXZlIFwicGVyZm9ybWFuY2VcIiBBUEkgaW5zdGVhZCBvZiBcIkRhdGVcIlxuLy8gUmVhZCBtb3JlIGFib3V0IGl0IG9uIE1ETjpcbi8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9QZXJmb3JtYW5jZVxuY29uc3QgZ2V0VGltZSA9IHR5cGVvZiBwZXJmb3JtYW5jZSA9PT0gJ2Z1bmN0aW9uJyA/IHBlcmZvcm1hbmNlLm5vdyA6IERhdGUubm93O1xuLypcbkZvciBhIHBvaW50ZXIgaW50ZXJhY3Rpb24sIGF1dG9tYXRpY2FsbHkgc2Nyb2xscyBjZXJ0YWluIHNjcm9sbCBjb250YWluZXJzIHdoZW4gdGhlIHBvaW50ZXJcbmFwcHJvYWNoZXMgdGhlIGVkZ2UuXG5cblRoZSBjYWxsZXIgbXVzdCBjYWxsIHN0YXJ0ICsgaGFuZGxlTW92ZSArIHN0b3AuXG4qL1xuY2xhc3MgQXV0b1Njcm9sbGVyIHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgLy8gb3B0aW9ucyB0aGF0IGNhbiBiZSBzZXQgYnkgY2FsbGVyXG4gICAgICAgIHRoaXMuaXNFbmFibGVkID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5zY3JvbGxRdWVyeSA9IFt3aW5kb3csICcuZmMtc2Nyb2xsZXInXTtcbiAgICAgICAgdGhpcy5lZGdlVGhyZXNob2xkID0gNTA7IC8vIHBpeGVsc1xuICAgICAgICB0aGlzLm1heFZlbG9jaXR5ID0gMzAwOyAvLyBwaXhlbHMgcGVyIHNlY29uZFxuICAgICAgICAvLyBpbnRlcm5hbCBzdGF0ZVxuICAgICAgICB0aGlzLnBvaW50ZXJTY3JlZW5YID0gbnVsbDtcbiAgICAgICAgdGhpcy5wb2ludGVyU2NyZWVuWSA9IG51bGw7XG4gICAgICAgIHRoaXMuaXNBbmltYXRpbmcgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5zY3JvbGxDYWNoZXMgPSBudWxsO1xuICAgICAgICAvLyBwcm90ZWN0IGFnYWluc3QgdGhlIGluaXRpYWwgcG9pbnRlcmRvd24gYmVpbmcgdG9vIGNsb3NlIHRvIGFuIGVkZ2UgYW5kIHN0YXJ0aW5nIHRoZSBzY3JvbGxcbiAgICAgICAgdGhpcy5ldmVyTW92ZWRVcCA9IGZhbHNlO1xuICAgICAgICB0aGlzLmV2ZXJNb3ZlZERvd24gPSBmYWxzZTtcbiAgICAgICAgdGhpcy5ldmVyTW92ZWRMZWZ0ID0gZmFsc2U7XG4gICAgICAgIHRoaXMuZXZlck1vdmVkUmlnaHQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5hbmltYXRlID0gKCkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuaXNBbmltYXRpbmcpIHsgLy8gd2Fzbid0IGNhbmNlbGxlZCBiZXR3ZWVuIGFuaW1hdGlvbiBjYWxsc1xuICAgICAgICAgICAgICAgIGxldCBlZGdlID0gdGhpcy5jb21wdXRlQmVzdEVkZ2UodGhpcy5wb2ludGVyU2NyZWVuWCArIHdpbmRvdy5wYWdlWE9mZnNldCwgdGhpcy5wb2ludGVyU2NyZWVuWSArIHdpbmRvdy5wYWdlWU9mZnNldCk7XG4gICAgICAgICAgICAgICAgaWYgKGVkZ2UpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IG5vdyA9IGdldFRpbWUoKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5oYW5kbGVTaWRlKGVkZ2UsIChub3cgLSB0aGlzLm1zU2luY2VSZXF1ZXN0KSAvIDEwMDApO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnJlcXVlc3RBbmltYXRpb24obm93KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaXNBbmltYXRpbmcgPSBmYWxzZTsgLy8gd2lsbCBzdG9wIGFuaW1hdGlvblxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9XG4gICAgc3RhcnQocGFnZVgsIHBhZ2VZLCBzY3JvbGxTdGFydEVsKSB7XG4gICAgICAgIGlmICh0aGlzLmlzRW5hYmxlZCkge1xuICAgICAgICAgICAgdGhpcy5zY3JvbGxDYWNoZXMgPSB0aGlzLmJ1aWxkQ2FjaGVzKHNjcm9sbFN0YXJ0RWwpO1xuICAgICAgICAgICAgdGhpcy5wb2ludGVyU2NyZWVuWCA9IG51bGw7XG4gICAgICAgICAgICB0aGlzLnBvaW50ZXJTY3JlZW5ZID0gbnVsbDtcbiAgICAgICAgICAgIHRoaXMuZXZlck1vdmVkVXAgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuZXZlck1vdmVkRG93biA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5ldmVyTW92ZWRMZWZ0ID0gZmFsc2U7XG4gICAgICAgICAgICB0aGlzLmV2ZXJNb3ZlZFJpZ2h0ID0gZmFsc2U7XG4gICAgICAgICAgICB0aGlzLmhhbmRsZU1vdmUocGFnZVgsIHBhZ2VZKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBoYW5kbGVNb3ZlKHBhZ2VYLCBwYWdlWSkge1xuICAgICAgICBpZiAodGhpcy5pc0VuYWJsZWQpIHtcbiAgICAgICAgICAgIGxldCBwb2ludGVyU2NyZWVuWCA9IHBhZ2VYIC0gd2luZG93LnBhZ2VYT2Zmc2V0O1xuICAgICAgICAgICAgbGV0IHBvaW50ZXJTY3JlZW5ZID0gcGFnZVkgLSB3aW5kb3cucGFnZVlPZmZzZXQ7XG4gICAgICAgICAgICBsZXQgeURlbHRhID0gdGhpcy5wb2ludGVyU2NyZWVuWSA9PT0gbnVsbCA/IDAgOiBwb2ludGVyU2NyZWVuWSAtIHRoaXMucG9pbnRlclNjcmVlblk7XG4gICAgICAgICAgICBsZXQgeERlbHRhID0gdGhpcy5wb2ludGVyU2NyZWVuWCA9PT0gbnVsbCA/IDAgOiBwb2ludGVyU2NyZWVuWCAtIHRoaXMucG9pbnRlclNjcmVlblg7XG4gICAgICAgICAgICBpZiAoeURlbHRhIDwgMCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZXZlck1vdmVkVXAgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoeURlbHRhID4gMCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZXZlck1vdmVkRG93biA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoeERlbHRhIDwgMCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZXZlck1vdmVkTGVmdCA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICh4RGVsdGEgPiAwKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5ldmVyTW92ZWRSaWdodCA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnBvaW50ZXJTY3JlZW5YID0gcG9pbnRlclNjcmVlblg7XG4gICAgICAgICAgICB0aGlzLnBvaW50ZXJTY3JlZW5ZID0gcG9pbnRlclNjcmVlblk7XG4gICAgICAgICAgICBpZiAoIXRoaXMuaXNBbmltYXRpbmcpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmlzQW5pbWF0aW5nID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB0aGlzLnJlcXVlc3RBbmltYXRpb24oZ2V0VGltZSgpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICBzdG9wKCkge1xuICAgICAgICBpZiAodGhpcy5pc0VuYWJsZWQpIHtcbiAgICAgICAgICAgIHRoaXMuaXNBbmltYXRpbmcgPSBmYWxzZTsgLy8gd2lsbCBzdG9wIGFuaW1hdGlvblxuICAgICAgICAgICAgZm9yIChsZXQgc2Nyb2xsQ2FjaGUgb2YgdGhpcy5zY3JvbGxDYWNoZXMpIHtcbiAgICAgICAgICAgICAgICBzY3JvbGxDYWNoZS5kZXN0cm95KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnNjcm9sbENhY2hlcyA9IG51bGw7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmVxdWVzdEFuaW1hdGlvbihub3cpIHtcbiAgICAgICAgdGhpcy5tc1NpbmNlUmVxdWVzdCA9IG5vdztcbiAgICAgICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKHRoaXMuYW5pbWF0ZSk7XG4gICAgfVxuICAgIGhhbmRsZVNpZGUoZWRnZSwgc2Vjb25kcykge1xuICAgICAgICBsZXQgeyBzY3JvbGxDYWNoZSB9ID0gZWRnZTtcbiAgICAgICAgbGV0IHsgZWRnZVRocmVzaG9sZCB9ID0gdGhpcztcbiAgICAgICAgbGV0IGludkRpc3RhbmNlID0gZWRnZVRocmVzaG9sZCAtIGVkZ2UuZGlzdGFuY2U7XG4gICAgICAgIGxldCB2ZWxvY2l0eSA9IC8vIHRoZSBjbG9zZXIgdG8gdGhlIGVkZ2UsIHRoZSBmYXN0ZXIgd2Ugc2Nyb2xsXG4gICAgICAgICAoKGludkRpc3RhbmNlICogaW52RGlzdGFuY2UpIC8gKGVkZ2VUaHJlc2hvbGQgKiBlZGdlVGhyZXNob2xkKSkgKiAvLyBxdWFkcmF0aWNcbiAgICAgICAgICAgIHRoaXMubWF4VmVsb2NpdHkgKiBzZWNvbmRzO1xuICAgICAgICBsZXQgc2lnbiA9IDE7XG4gICAgICAgIHN3aXRjaCAoZWRnZS5uYW1lKSB7XG4gICAgICAgICAgICBjYXNlICdsZWZ0JzpcbiAgICAgICAgICAgICAgICBzaWduID0gLTE7XG4gICAgICAgICAgICAvLyBmYWxscyB0aHJvdWdoXG4gICAgICAgICAgICBjYXNlICdyaWdodCc6XG4gICAgICAgICAgICAgICAgc2Nyb2xsQ2FjaGUuc2V0U2Nyb2xsTGVmdChzY3JvbGxDYWNoZS5nZXRTY3JvbGxMZWZ0KCkgKyB2ZWxvY2l0eSAqIHNpZ24pO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAndG9wJzpcbiAgICAgICAgICAgICAgICBzaWduID0gLTE7XG4gICAgICAgICAgICAvLyBmYWxscyB0aHJvdWdoXG4gICAgICAgICAgICBjYXNlICdib3R0b20nOlxuICAgICAgICAgICAgICAgIHNjcm9sbENhY2hlLnNldFNjcm9sbFRvcChzY3JvbGxDYWNoZS5nZXRTY3JvbGxUb3AoKSArIHZlbG9jaXR5ICogc2lnbik7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLy8gbGVmdC90b3AgYXJlIHJlbGF0aXZlIHRvIGRvY3VtZW50IHRvcGxlZnRcbiAgICBjb21wdXRlQmVzdEVkZ2UobGVmdCwgdG9wKSB7XG4gICAgICAgIGxldCB7IGVkZ2VUaHJlc2hvbGQgfSA9IHRoaXM7XG4gICAgICAgIGxldCBiZXN0U2lkZSA9IG51bGw7XG4gICAgICAgIGxldCBzY3JvbGxDYWNoZXMgPSB0aGlzLnNjcm9sbENhY2hlcyB8fCBbXTtcbiAgICAgICAgZm9yIChsZXQgc2Nyb2xsQ2FjaGUgb2Ygc2Nyb2xsQ2FjaGVzKSB7XG4gICAgICAgICAgICBsZXQgcmVjdCA9IHNjcm9sbENhY2hlLmNsaWVudFJlY3Q7XG4gICAgICAgICAgICBsZXQgbGVmdERpc3QgPSBsZWZ0IC0gcmVjdC5sZWZ0O1xuICAgICAgICAgICAgbGV0IHJpZ2h0RGlzdCA9IHJlY3QucmlnaHQgLSBsZWZ0O1xuICAgICAgICAgICAgbGV0IHRvcERpc3QgPSB0b3AgLSByZWN0LnRvcDtcbiAgICAgICAgICAgIGxldCBib3R0b21EaXN0ID0gcmVjdC5ib3R0b20gLSB0b3A7XG4gICAgICAgICAgICAvLyBjb21wbGV0ZWx5IHdpdGhpbiB0aGUgcmVjdD9cbiAgICAgICAgICAgIGlmIChsZWZ0RGlzdCA+PSAwICYmIHJpZ2h0RGlzdCA+PSAwICYmIHRvcERpc3QgPj0gMCAmJiBib3R0b21EaXN0ID49IDApIHtcbiAgICAgICAgICAgICAgICBpZiAodG9wRGlzdCA8PSBlZGdlVGhyZXNob2xkICYmIHRoaXMuZXZlck1vdmVkVXAgJiYgc2Nyb2xsQ2FjaGUuY2FuU2Nyb2xsVXAoKSAmJlxuICAgICAgICAgICAgICAgICAgICAoIWJlc3RTaWRlIHx8IGJlc3RTaWRlLmRpc3RhbmNlID4gdG9wRGlzdCkpIHtcbiAgICAgICAgICAgICAgICAgICAgYmVzdFNpZGUgPSB7IHNjcm9sbENhY2hlLCBuYW1lOiAndG9wJywgZGlzdGFuY2U6IHRvcERpc3QgfTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGJvdHRvbURpc3QgPD0gZWRnZVRocmVzaG9sZCAmJiB0aGlzLmV2ZXJNb3ZlZERvd24gJiYgc2Nyb2xsQ2FjaGUuY2FuU2Nyb2xsRG93bigpICYmXG4gICAgICAgICAgICAgICAgICAgICghYmVzdFNpZGUgfHwgYmVzdFNpZGUuZGlzdGFuY2UgPiBib3R0b21EaXN0KSkge1xuICAgICAgICAgICAgICAgICAgICBiZXN0U2lkZSA9IHsgc2Nyb2xsQ2FjaGUsIG5hbWU6ICdib3R0b20nLCBkaXN0YW5jZTogYm90dG9tRGlzdCB9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAobGVmdERpc3QgPD0gZWRnZVRocmVzaG9sZCAmJiB0aGlzLmV2ZXJNb3ZlZExlZnQgJiYgc2Nyb2xsQ2FjaGUuY2FuU2Nyb2xsTGVmdCgpICYmXG4gICAgICAgICAgICAgICAgICAgICghYmVzdFNpZGUgfHwgYmVzdFNpZGUuZGlzdGFuY2UgPiBsZWZ0RGlzdCkpIHtcbiAgICAgICAgICAgICAgICAgICAgYmVzdFNpZGUgPSB7IHNjcm9sbENhY2hlLCBuYW1lOiAnbGVmdCcsIGRpc3RhbmNlOiBsZWZ0RGlzdCB9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAocmlnaHREaXN0IDw9IGVkZ2VUaHJlc2hvbGQgJiYgdGhpcy5ldmVyTW92ZWRSaWdodCAmJiBzY3JvbGxDYWNoZS5jYW5TY3JvbGxSaWdodCgpICYmXG4gICAgICAgICAgICAgICAgICAgICghYmVzdFNpZGUgfHwgYmVzdFNpZGUuZGlzdGFuY2UgPiByaWdodERpc3QpKSB7XG4gICAgICAgICAgICAgICAgICAgIGJlc3RTaWRlID0geyBzY3JvbGxDYWNoZSwgbmFtZTogJ3JpZ2h0JywgZGlzdGFuY2U6IHJpZ2h0RGlzdCB9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYmVzdFNpZGU7XG4gICAgfVxuICAgIGJ1aWxkQ2FjaGVzKHNjcm9sbFN0YXJ0RWwpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucXVlcnlTY3JvbGxFbHMoc2Nyb2xsU3RhcnRFbCkubWFwKChlbCkgPT4ge1xuICAgICAgICAgICAgaWYgKGVsID09PSB3aW5kb3cpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFdpbmRvd1Njcm9sbEdlb21DYWNoZShmYWxzZSk7IC8vIGZhbHNlID0gZG9uJ3QgbGlzdGVuIHRvIHVzZXItZ2VuZXJhdGVkIHNjcm9sbHNcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBuZXcgRWxlbWVudFNjcm9sbEdlb21DYWNoZShlbCwgZmFsc2UpOyAvLyBmYWxzZSA9IGRvbid0IGxpc3RlbiB0byB1c2VyLWdlbmVyYXRlZCBzY3JvbGxzXG4gICAgICAgIH0pO1xuICAgIH1cbiAgICBxdWVyeVNjcm9sbEVscyhzY3JvbGxTdGFydEVsKSB7XG4gICAgICAgIGxldCBlbHMgPSBbXTtcbiAgICAgICAgZm9yIChsZXQgcXVlcnkgb2YgdGhpcy5zY3JvbGxRdWVyeSkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBxdWVyeSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICAgICBlbHMucHVzaChxdWVyeSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBlbHMucHVzaCguLi5BcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChnZXRFbFJvb3Qoc2Nyb2xsU3RhcnRFbCkucXVlcnlTZWxlY3RvckFsbChxdWVyeSkpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZWxzO1xuICAgIH1cbn1cblxuLypcbk1vbml0b3JzIGRyYWdnaW5nIG9uIGFuIGVsZW1lbnQuIEhhcyBhIG51bWJlciBvZiBoaWdoLWxldmVsIGZlYXR1cmVzOlxuLSBtaW5pbXVtIGRpc3RhbmNlIHJlcXVpcmVkIGJlZm9yZSBkcmFnZ2luZ1xuLSBtaW5pbXVtIHdhaXQgdGltZSAoXCJkZWxheVwiKSBiZWZvcmUgZHJhZ2dpbmdcbi0gYSBtaXJyb3IgZWxlbWVudCB0aGF0IGZvbGxvd3MgdGhlIHBvaW50ZXJcbiovXG5jbGFzcyBGZWF0dXJlZnVsRWxlbWVudERyYWdnaW5nIGV4dGVuZHMgRWxlbWVudERyYWdnaW5nIHtcbiAgICBjb25zdHJ1Y3Rvcihjb250YWluZXJFbCwgc2VsZWN0b3IpIHtcbiAgICAgICAgc3VwZXIoY29udGFpbmVyRWwpO1xuICAgICAgICB0aGlzLmNvbnRhaW5lckVsID0gY29udGFpbmVyRWw7XG4gICAgICAgIC8vIG9wdGlvbnMgdGhhdCBjYW4gYmUgZGlyZWN0bHkgc2V0IGJ5IGNhbGxlclxuICAgICAgICAvLyB0aGUgY2FsbGVyIGNhbiBhbHNvIHNldCB0aGUgUG9pbnRlckRyYWdnaW5nJ3Mgb3B0aW9ucyBhcyB3ZWxsXG4gICAgICAgIHRoaXMuZGVsYXkgPSBudWxsO1xuICAgICAgICB0aGlzLm1pbkRpc3RhbmNlID0gMDtcbiAgICAgICAgdGhpcy50b3VjaFNjcm9sbEFsbG93ZWQgPSB0cnVlOyAvLyBwcmV2ZW50cyBkcmFnIGZyb20gc3RhcnRpbmcgYW5kIGJsb2NrcyBzY3JvbGxpbmcgZHVyaW5nIGRyYWdcbiAgICAgICAgdGhpcy5taXJyb3JOZWVkc1JldmVydCA9IGZhbHNlO1xuICAgICAgICB0aGlzLmlzSW50ZXJhY3RpbmcgPSBmYWxzZTsgLy8gaXMgdGhlIHVzZXIgdmFsaWRseSBtb3ZpbmcgdGhlIHBvaW50ZXI/IGxhc3RzIHVudGlsIHBvaW50ZXJ1cFxuICAgICAgICB0aGlzLmlzRHJhZ2dpbmcgPSBmYWxzZTsgLy8gaXMgaXQgSU5URU5URlVMTFkgZHJhZ2dpbmc/IGxhc3RzIHVudGlsIGFmdGVyIHJldmVydCBhbmltYXRpb25cbiAgICAgICAgdGhpcy5pc0RlbGF5RW5kZWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5pc0Rpc3RhbmNlU3VycGFzc2VkID0gZmFsc2U7XG4gICAgICAgIHRoaXMuZGVsYXlUaW1lb3V0SWQgPSBudWxsO1xuICAgICAgICB0aGlzLm9uUG9pbnRlckRvd24gPSAoZXYpID0+IHtcbiAgICAgICAgICAgIGlmICghdGhpcy5pc0RyYWdnaW5nKSB7IC8vIHNvIG5ldyBkcmFnIGRvZXNuJ3QgaGFwcGVuIHdoaWxlIHJldmVydCBhbmltYXRpb24gaXMgZ29pbmdcbiAgICAgICAgICAgICAgICB0aGlzLmlzSW50ZXJhY3RpbmcgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHRoaXMuaXNEZWxheUVuZGVkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgdGhpcy5pc0Rpc3RhbmNlU3VycGFzc2VkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgcHJldmVudFNlbGVjdGlvbihkb2N1bWVudC5ib2R5KTtcbiAgICAgICAgICAgICAgICBwcmV2ZW50Q29udGV4dE1lbnUoZG9jdW1lbnQuYm9keSk7XG4gICAgICAgICAgICAgICAgLy8gcHJldmVudCBsaW5rcyBmcm9tIGJlaW5nIHZpc2l0ZWQgaWYgdGhlcmUncyBhbiBldmVudHVhbCBkcmFnLlxuICAgICAgICAgICAgICAgIC8vIGFsc28gcHJldmVudHMgc2VsZWN0aW9uIGluIG9sZGVyIGJyb3dzZXJzIChtYXliZT8pLlxuICAgICAgICAgICAgICAgIC8vIG5vdCBuZWNlc3NhcnkgZm9yIHRvdWNoLCBiZXNpZGVzLCBicm93c2VyIHdvdWxkIGNvbXBsYWluIGFib3V0IHBhc3NpdmVuZXNzLlxuICAgICAgICAgICAgICAgIGlmICghZXYuaXNUb3VjaCkge1xuICAgICAgICAgICAgICAgICAgICBldi5vcmlnRXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0dGVyLnRyaWdnZXIoJ3BvaW50ZXJkb3duJywgZXYpO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzSW50ZXJhY3RpbmcgJiYgLy8gbm90IGRlc3Ryb3llZCB2aWEgcG9pbnRlcmRvd24gaGFuZGxlclxuICAgICAgICAgICAgICAgICAgICAhdGhpcy5wb2ludGVyLnNob3VsZElnbm9yZU1vdmUpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gYWN0aW9ucyByZWxhdGVkIHRvIGluaXRpYXRpbmcgZHJhZ3N0YXJ0K2RyYWdtb3ZlK2RyYWdlbmQuLi5cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5taXJyb3Iuc2V0SXNWaXNpYmxlKGZhbHNlKTsgLy8gcmVzZXQuIGNhbGxlciBtdXN0IHNldC12aXNpYmxlXG4gICAgICAgICAgICAgICAgICAgIHRoaXMubWlycm9yLnN0YXJ0KGV2LnN1YmplY3RFbCwgZXYucGFnZVgsIGV2LnBhZ2VZKTsgLy8gbXVzdCBoYXBwZW4gb24gZmlyc3QgcG9pbnRlciBkb3duXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3RhcnREZWxheShldik7XG4gICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5taW5EaXN0YW5jZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5oYW5kbGVEaXN0YW5jZVN1cnBhc3NlZChldik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMub25Qb2ludGVyTW92ZSA9IChldikgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuaXNJbnRlcmFjdGluZykge1xuICAgICAgICAgICAgICAgIHRoaXMuZW1pdHRlci50cmlnZ2VyKCdwb2ludGVybW92ZScsIGV2KTtcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuaXNEaXN0YW5jZVN1cnBhc3NlZCkge1xuICAgICAgICAgICAgICAgICAgICBsZXQgbWluRGlzdGFuY2UgPSB0aGlzLm1pbkRpc3RhbmNlO1xuICAgICAgICAgICAgICAgICAgICBsZXQgZGlzdGFuY2VTcTsgLy8gY3VycmVudCBkaXN0YW5jZSBmcm9tIHRoZSBvcmlnaW4sIHNxdWFyZWRcbiAgICAgICAgICAgICAgICAgICAgbGV0IHsgZGVsdGFYLCBkZWx0YVkgfSA9IGV2O1xuICAgICAgICAgICAgICAgICAgICBkaXN0YW5jZVNxID0gZGVsdGFYICogZGVsdGFYICsgZGVsdGFZICogZGVsdGFZO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZGlzdGFuY2VTcSA+PSBtaW5EaXN0YW5jZSAqIG1pbkRpc3RhbmNlKSB7IC8vIHVzZSBweXRoYWdvcmVhbiB0aGVvcmVtXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmhhbmRsZURpc3RhbmNlU3VycGFzc2VkKGV2KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5pc0RyYWdnaW5nKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGEgcmVhbCBwb2ludGVyIG1vdmU/IChub3Qgb25lIHNpbXVsYXRlZCBieSBzY3JvbGxpbmcpXG4gICAgICAgICAgICAgICAgICAgIGlmIChldi5vcmlnRXZlbnQudHlwZSAhPT0gJ3Njcm9sbCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubWlycm9yLmhhbmRsZU1vdmUoZXYucGFnZVgsIGV2LnBhZ2VZKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYXV0b1Njcm9sbGVyLmhhbmRsZU1vdmUoZXYucGFnZVgsIGV2LnBhZ2VZKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXR0ZXIudHJpZ2dlcignZHJhZ21vdmUnLCBldik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICB0aGlzLm9uUG9pbnRlclVwID0gKGV2KSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5pc0ludGVyYWN0aW5nKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pc0ludGVyYWN0aW5nID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgYWxsb3dTZWxlY3Rpb24oZG9jdW1lbnQuYm9keSk7XG4gICAgICAgICAgICAgICAgYWxsb3dDb250ZXh0TWVudShkb2N1bWVudC5ib2R5KTtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXR0ZXIudHJpZ2dlcigncG9pbnRlcnVwJywgZXYpOyAvLyBjYW4gcG90ZW50aWFsbHkgc2V0IG1pcnJvck5lZWRzUmV2ZXJ0XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuaXNEcmFnZ2luZykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmF1dG9TY3JvbGxlci5zdG9wKCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudHJ5U3RvcERyYWcoZXYpOyAvLyB3aGljaCB3aWxsIHN0b3AgdGhlIG1pcnJvclxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5kZWxheVRpbWVvdXRJZCkge1xuICAgICAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5kZWxheVRpbWVvdXRJZCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZGVsYXlUaW1lb3V0SWQgPSBudWxsO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgbGV0IHBvaW50ZXIgPSB0aGlzLnBvaW50ZXIgPSBuZXcgUG9pbnRlckRyYWdnaW5nKGNvbnRhaW5lckVsKTtcbiAgICAgICAgcG9pbnRlci5lbWl0dGVyLm9uKCdwb2ludGVyZG93bicsIHRoaXMub25Qb2ludGVyRG93bik7XG4gICAgICAgIHBvaW50ZXIuZW1pdHRlci5vbigncG9pbnRlcm1vdmUnLCB0aGlzLm9uUG9pbnRlck1vdmUpO1xuICAgICAgICBwb2ludGVyLmVtaXR0ZXIub24oJ3BvaW50ZXJ1cCcsIHRoaXMub25Qb2ludGVyVXApO1xuICAgICAgICBpZiAoc2VsZWN0b3IpIHtcbiAgICAgICAgICAgIHBvaW50ZXIuc2VsZWN0b3IgPSBzZWxlY3RvcjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm1pcnJvciA9IG5ldyBFbGVtZW50TWlycm9yKCk7XG4gICAgICAgIHRoaXMuYXV0b1Njcm9sbGVyID0gbmV3IEF1dG9TY3JvbGxlcigpO1xuICAgIH1cbiAgICBkZXN0cm95KCkge1xuICAgICAgICB0aGlzLnBvaW50ZXIuZGVzdHJveSgpO1xuICAgICAgICAvLyBIQUNLOiBzaW11bGF0ZSBhIHBvaW50ZXItdXAgdG8gZW5kIHRoZSBjdXJyZW50IGRyYWdcbiAgICAgICAgLy8gVE9ETzogZmlyZSAnZHJhZ2VuZCcgZGlyZWN0bHkgYW5kIHN0b3AgaW50ZXJhY3Rpb24uIGRpc2NvdXJhZ2UgdXNlIG9mIHBvaW50ZXJ1cCBldmVudCAoYi9jIG1pZ2h0IG5vdCBmaXJlKVxuICAgICAgICB0aGlzLm9uUG9pbnRlclVwKHt9KTtcbiAgICB9XG4gICAgc3RhcnREZWxheShldikge1xuICAgICAgICBpZiAodHlwZW9mIHRoaXMuZGVsYXkgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgICB0aGlzLmRlbGF5VGltZW91dElkID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5kZWxheVRpbWVvdXRJZCA9IG51bGw7XG4gICAgICAgICAgICAgICAgdGhpcy5oYW5kbGVEZWxheUVuZChldik7XG4gICAgICAgICAgICB9LCB0aGlzLmRlbGF5KTsgLy8gbm90IGFzc2lnbmFibGUgdG8gbnVtYmVyIVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5oYW5kbGVEZWxheUVuZChldik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaGFuZGxlRGVsYXlFbmQoZXYpIHtcbiAgICAgICAgdGhpcy5pc0RlbGF5RW5kZWQgPSB0cnVlO1xuICAgICAgICB0aGlzLnRyeVN0YXJ0RHJhZyhldik7XG4gICAgfVxuICAgIGhhbmRsZURpc3RhbmNlU3VycGFzc2VkKGV2KSB7XG4gICAgICAgIHRoaXMuaXNEaXN0YW5jZVN1cnBhc3NlZCA9IHRydWU7XG4gICAgICAgIHRoaXMudHJ5U3RhcnREcmFnKGV2KTtcbiAgICB9XG4gICAgdHJ5U3RhcnREcmFnKGV2KSB7XG4gICAgICAgIGlmICh0aGlzLmlzRGVsYXlFbmRlZCAmJiB0aGlzLmlzRGlzdGFuY2VTdXJwYXNzZWQpIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5wb2ludGVyLndhc1RvdWNoU2Nyb2xsIHx8IHRoaXMudG91Y2hTY3JvbGxBbGxvd2VkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pc0RyYWdnaW5nID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB0aGlzLm1pcnJvck5lZWRzUmV2ZXJ0ID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgdGhpcy5hdXRvU2Nyb2xsZXIuc3RhcnQoZXYucGFnZVgsIGV2LnBhZ2VZLCB0aGlzLmNvbnRhaW5lckVsKTtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXR0ZXIudHJpZ2dlcignZHJhZ3N0YXJ0JywgZXYpO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnRvdWNoU2Nyb2xsQWxsb3dlZCA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wb2ludGVyLmNhbmNlbFRvdWNoU2Nyb2xsKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIHRyeVN0b3BEcmFnKGV2KSB7XG4gICAgICAgIC8vIC5zdG9wKCkgaXMgQUxXQVlTIGFzeW5jaHJvbm91cywgd2hpY2ggd2UgTkVFRCBiZWNhdXNlIHdlIHdhbnQgYWxsIHBvaW50ZXJ1cCBldmVudHNcbiAgICAgICAgLy8gdGhhdCBjb21lIGZyb20gdGhlIGRvY3VtZW50IHRvIGZpcmUgYmVmb3JlaGFuZC4gbXVjaCBtb3JlIGNvbnZlbmllbnQgdGhpcyB3YXkuXG4gICAgICAgIHRoaXMubWlycm9yLnN0b3AodGhpcy5taXJyb3JOZWVkc1JldmVydCwgdGhpcy5zdG9wRHJhZy5iaW5kKHRoaXMsIGV2KSk7XG4gICAgfVxuICAgIHN0b3BEcmFnKGV2KSB7XG4gICAgICAgIHRoaXMuaXNEcmFnZ2luZyA9IGZhbHNlO1xuICAgICAgICB0aGlzLmVtaXR0ZXIudHJpZ2dlcignZHJhZ2VuZCcsIGV2KTtcbiAgICB9XG4gICAgLy8gZmlsbCBpbiB0aGUgaW1wbGVtZW50YXRpb25zLi4uXG4gICAgc2V0SWdub3JlTW92ZShib29sKSB7XG4gICAgICAgIHRoaXMucG9pbnRlci5zaG91bGRJZ25vcmVNb3ZlID0gYm9vbDtcbiAgICB9XG4gICAgc2V0TWlycm9ySXNWaXNpYmxlKGJvb2wpIHtcbiAgICAgICAgdGhpcy5taXJyb3Iuc2V0SXNWaXNpYmxlKGJvb2wpO1xuICAgIH1cbiAgICBzZXRNaXJyb3JOZWVkc1JldmVydChib29sKSB7XG4gICAgICAgIHRoaXMubWlycm9yTmVlZHNSZXZlcnQgPSBib29sO1xuICAgIH1cbiAgICBzZXRBdXRvU2Nyb2xsRW5hYmxlZChib29sKSB7XG4gICAgICAgIHRoaXMuYXV0b1Njcm9sbGVyLmlzRW5hYmxlZCA9IGJvb2w7XG4gICAgfVxufVxuXG4vKlxuV2hlbiB0aGlzIGNsYXNzIGlzIGluc3RhbnRpYXRlZCwgaXQgcmVjb3JkcyB0aGUgb2Zmc2V0IG9mIGFuIGVsZW1lbnQgKHJlbGF0aXZlIHRvIHRoZSBkb2N1bWVudCB0b3BsZWZ0KSxcbmFuZCBjb250aW51ZXMgdG8gbW9uaXRvciBzY3JvbGxpbmcsIHVwZGF0aW5nIHRoZSBjYWNoZWQgY29vcmRpbmF0ZXMgaWYgaXQgbmVlZHMgdG8uXG5Eb2VzIG5vdCBhY2Nlc3MgdGhlIERPTSBhZnRlciBpbnN0YW50aWF0aW9uLCBzbyBoaWdobHkgcGVyZm9ybWFudC5cblxuQWxzbyBrZWVwcyB0cmFjayBvZiBhbGwgc2Nyb2xsaW5nL292ZXJmbG93OmhpZGRlbiBjb250YWluZXJzIHRoYXQgYXJlIHBhcmVudHMgb2YgdGhlIGdpdmVuIGVsZW1lbnRcbmFuZCBhbiBkZXRlcm1pbmUgaWYgYSBnaXZlbiBwb2ludCBpcyBpbnNpZGUgdGhlIGNvbWJpbmVkIGNsaXBwaW5nIHJlY3RhbmdsZS5cbiovXG5jbGFzcyBPZmZzZXRUcmFja2VyIHtcbiAgICBjb25zdHJ1Y3RvcihlbCkge1xuICAgICAgICB0aGlzLm9yaWdSZWN0ID0gY29tcHV0ZVJlY3QoZWwpO1xuICAgICAgICAvLyB3aWxsIHdvcmsgZmluZSBmb3IgZGl2cyB0aGF0IGhhdmUgb3ZlcmZsb3c6aGlkZGVuXG4gICAgICAgIHRoaXMuc2Nyb2xsQ2FjaGVzID0gZ2V0Q2xpcHBpbmdQYXJlbnRzKGVsKS5tYXAoKHNjcm9sbEVsKSA9PiBuZXcgRWxlbWVudFNjcm9sbEdlb21DYWNoZShzY3JvbGxFbCwgdHJ1ZSkpO1xuICAgIH1cbiAgICBkZXN0cm95KCkge1xuICAgICAgICBmb3IgKGxldCBzY3JvbGxDYWNoZSBvZiB0aGlzLnNjcm9sbENhY2hlcykge1xuICAgICAgICAgICAgc2Nyb2xsQ2FjaGUuZGVzdHJveSgpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGNvbXB1dGVMZWZ0KCkge1xuICAgICAgICBsZXQgbGVmdCA9IHRoaXMub3JpZ1JlY3QubGVmdDtcbiAgICAgICAgZm9yIChsZXQgc2Nyb2xsQ2FjaGUgb2YgdGhpcy5zY3JvbGxDYWNoZXMpIHtcbiAgICAgICAgICAgIGxlZnQgKz0gc2Nyb2xsQ2FjaGUub3JpZ1Njcm9sbExlZnQgLSBzY3JvbGxDYWNoZS5nZXRTY3JvbGxMZWZ0KCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGxlZnQ7XG4gICAgfVxuICAgIGNvbXB1dGVUb3AoKSB7XG4gICAgICAgIGxldCB0b3AgPSB0aGlzLm9yaWdSZWN0LnRvcDtcbiAgICAgICAgZm9yIChsZXQgc2Nyb2xsQ2FjaGUgb2YgdGhpcy5zY3JvbGxDYWNoZXMpIHtcbiAgICAgICAgICAgIHRvcCArPSBzY3JvbGxDYWNoZS5vcmlnU2Nyb2xsVG9wIC0gc2Nyb2xsQ2FjaGUuZ2V0U2Nyb2xsVG9wKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRvcDtcbiAgICB9XG4gICAgaXNXaXRoaW5DbGlwcGluZyhwYWdlWCwgcGFnZVkpIHtcbiAgICAgICAgbGV0IHBvaW50ID0geyBsZWZ0OiBwYWdlWCwgdG9wOiBwYWdlWSB9O1xuICAgICAgICBmb3IgKGxldCBzY3JvbGxDYWNoZSBvZiB0aGlzLnNjcm9sbENhY2hlcykge1xuICAgICAgICAgICAgaWYgKCFpc0lnbm9yZWRDbGlwcGluZyhzY3JvbGxDYWNoZS5nZXRFdmVudFRhcmdldCgpKSAmJlxuICAgICAgICAgICAgICAgICFwb2ludEluc2lkZVJlY3QocG9pbnQsIHNjcm9sbENhY2hlLmNsaWVudFJlY3QpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbn1cbi8vIGNlcnRhaW4gY2xpcHBpbmcgY29udGFpbmVycyBzaG91bGQgbmV2ZXIgY29uc3RyYWluIGludGVyYWN0aW9ucywgbGlrZSA8aHRtbD4gYW5kIDxib2R5PlxuLy8gaHR0cHM6Ly9naXRodWIuY29tL2Z1bGxjYWxlbmRhci9mdWxsY2FsZW5kYXIvaXNzdWVzLzM2MTVcbmZ1bmN0aW9uIGlzSWdub3JlZENsaXBwaW5nKG5vZGUpIHtcbiAgICBsZXQgdGFnTmFtZSA9IG5vZGUudGFnTmFtZTtcbiAgICByZXR1cm4gdGFnTmFtZSA9PT0gJ0hUTUwnIHx8IHRhZ05hbWUgPT09ICdCT0RZJztcbn1cblxuLypcblRyYWNrcyBtb3ZlbWVudCBvdmVyIG11bHRpcGxlIGRyb3BwYWJsZSBhcmVhcyAoYWthIFwiaGl0c1wiKVxudGhhdCBleGlzdCBpbiBvbmUgb3IgbW9yZSBEYXRlQ29tcG9uZW50cy5cblJlbGllcyBvbiBhbiBleGlzdGluZyBkcmFnZ2FibGUuXG5cbmVtaXRzOlxuLSBwb2ludGVyZG93blxuLSBkcmFnc3RhcnRcbi0gaGl0Y2hhbmdlIC0gZmlyZXMgaW5pdGlhbGx5LCBldmVuIGlmIG5vdCBvdmVyIGEgaGl0XG4tIHBvaW50ZXJ1cFxuLSAoaGl0Y2hhbmdlIC0gYWdhaW4sIHRvIG51bGwsIGlmIGVuZGVkIG92ZXIgYSBoaXQpXG4tIGRyYWdlbmRcbiovXG5jbGFzcyBIaXREcmFnZ2luZyB7XG4gICAgY29uc3RydWN0b3IoZHJhZ2dpbmcsIGRyb3BwYWJsZVN0b3JlKSB7XG4gICAgICAgIC8vIG9wdGlvbnMgdGhhdCBjYW4gYmUgc2V0IGJ5IGNhbGxlclxuICAgICAgICB0aGlzLnVzZVN1YmplY3RDZW50ZXIgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5yZXF1aXJlSW5pdGlhbCA9IHRydWU7IC8vIGlmIGRvZXNuJ3Qgc3RhcnQgb3V0IG9uIGEgaGl0LCB3b24ndCBlbWl0IGFueSBldmVudHNcbiAgICAgICAgdGhpcy5pbml0aWFsSGl0ID0gbnVsbDtcbiAgICAgICAgdGhpcy5tb3ZpbmdIaXQgPSBudWxsO1xuICAgICAgICB0aGlzLmZpbmFsSGl0ID0gbnVsbDsgLy8gd29uJ3QgZXZlciBiZSBwb3B1bGF0ZWQgaWYgc2hvdWxkSWdub3JlTW92ZVxuICAgICAgICB0aGlzLmhhbmRsZVBvaW50ZXJEb3duID0gKGV2KSA9PiB7XG4gICAgICAgICAgICBsZXQgeyBkcmFnZ2luZyB9ID0gdGhpcztcbiAgICAgICAgICAgIHRoaXMuaW5pdGlhbEhpdCA9IG51bGw7XG4gICAgICAgICAgICB0aGlzLm1vdmluZ0hpdCA9IG51bGw7XG4gICAgICAgICAgICB0aGlzLmZpbmFsSGl0ID0gbnVsbDtcbiAgICAgICAgICAgIHRoaXMucHJlcGFyZUhpdHMoKTtcbiAgICAgICAgICAgIHRoaXMucHJvY2Vzc0ZpcnN0Q29vcmQoZXYpO1xuICAgICAgICAgICAgaWYgKHRoaXMuaW5pdGlhbEhpdCB8fCAhdGhpcy5yZXF1aXJlSW5pdGlhbCkge1xuICAgICAgICAgICAgICAgIGRyYWdnaW5nLnNldElnbm9yZU1vdmUoZmFsc2UpO1xuICAgICAgICAgICAgICAgIC8vIFRPRE86IGZpcmUgdGhpcyBiZWZvcmUgY29tcHV0aW5nIHByb2Nlc3NGaXJzdENvb3JkLCBzbyBsaXN0ZW5lcnMgY2FuIGNhbmNlbC4gdGhpcyBnZXRzIGZpcmVkIGJ5IGFsbW9zdCBldmVyeSBoYW5kbGVyIDooXG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0dGVyLnRyaWdnZXIoJ3BvaW50ZXJkb3duJywgZXYpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgZHJhZ2dpbmcuc2V0SWdub3JlTW92ZSh0cnVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5oYW5kbGVEcmFnU3RhcnQgPSAoZXYpID0+IHtcbiAgICAgICAgICAgIHRoaXMuZW1pdHRlci50cmlnZ2VyKCdkcmFnc3RhcnQnLCBldik7XG4gICAgICAgICAgICB0aGlzLmhhbmRsZU1vdmUoZXYsIHRydWUpOyAvLyBmb3JjZSA9IGZpcmUgZXZlbiBpZiBpbml0aWFsbHkgbnVsbFxuICAgICAgICB9O1xuICAgICAgICB0aGlzLmhhbmRsZURyYWdNb3ZlID0gKGV2KSA9PiB7XG4gICAgICAgICAgICB0aGlzLmVtaXR0ZXIudHJpZ2dlcignZHJhZ21vdmUnLCBldik7XG4gICAgICAgICAgICB0aGlzLmhhbmRsZU1vdmUoZXYpO1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLmhhbmRsZVBvaW50ZXJVcCA9IChldikgPT4ge1xuICAgICAgICAgICAgdGhpcy5yZWxlYXNlSGl0cygpO1xuICAgICAgICAgICAgdGhpcy5lbWl0dGVyLnRyaWdnZXIoJ3BvaW50ZXJ1cCcsIGV2KTtcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5oYW5kbGVEcmFnRW5kID0gKGV2KSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5tb3ZpbmdIaXQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXR0ZXIudHJpZ2dlcignaGl0dXBkYXRlJywgbnVsbCwgdHJ1ZSwgZXYpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5maW5hbEhpdCA9IHRoaXMubW92aW5nSGl0O1xuICAgICAgICAgICAgdGhpcy5tb3ZpbmdIaXQgPSBudWxsO1xuICAgICAgICAgICAgdGhpcy5lbWl0dGVyLnRyaWdnZXIoJ2RyYWdlbmQnLCBldik7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuZHJvcHBhYmxlU3RvcmUgPSBkcm9wcGFibGVTdG9yZTtcbiAgICAgICAgZHJhZ2dpbmcuZW1pdHRlci5vbigncG9pbnRlcmRvd24nLCB0aGlzLmhhbmRsZVBvaW50ZXJEb3duKTtcbiAgICAgICAgZHJhZ2dpbmcuZW1pdHRlci5vbignZHJhZ3N0YXJ0JywgdGhpcy5oYW5kbGVEcmFnU3RhcnQpO1xuICAgICAgICBkcmFnZ2luZy5lbWl0dGVyLm9uKCdkcmFnbW92ZScsIHRoaXMuaGFuZGxlRHJhZ01vdmUpO1xuICAgICAgICBkcmFnZ2luZy5lbWl0dGVyLm9uKCdwb2ludGVydXAnLCB0aGlzLmhhbmRsZVBvaW50ZXJVcCk7XG4gICAgICAgIGRyYWdnaW5nLmVtaXR0ZXIub24oJ2RyYWdlbmQnLCB0aGlzLmhhbmRsZURyYWdFbmQpO1xuICAgICAgICB0aGlzLmRyYWdnaW5nID0gZHJhZ2dpbmc7XG4gICAgICAgIHRoaXMuZW1pdHRlciA9IG5ldyBFbWl0dGVyKCk7XG4gICAgfVxuICAgIC8vIHNldHMgaW5pdGlhbEhpdFxuICAgIC8vIHNldHMgY29vcmRBZGp1c3RcbiAgICBwcm9jZXNzRmlyc3RDb29yZChldikge1xuICAgICAgICBsZXQgb3JpZ1BvaW50ID0geyBsZWZ0OiBldi5wYWdlWCwgdG9wOiBldi5wYWdlWSB9O1xuICAgICAgICBsZXQgYWRqdXN0ZWRQb2ludCA9IG9yaWdQb2ludDtcbiAgICAgICAgbGV0IHN1YmplY3RFbCA9IGV2LnN1YmplY3RFbDtcbiAgICAgICAgbGV0IHN1YmplY3RSZWN0O1xuICAgICAgICBpZiAoc3ViamVjdEVsIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHsgLy8gaS5lLiBub3QgYSBEb2N1bWVudC9TaGFkb3dSb290XG4gICAgICAgICAgICBzdWJqZWN0UmVjdCA9IGNvbXB1dGVSZWN0KHN1YmplY3RFbCk7XG4gICAgICAgICAgICBhZGp1c3RlZFBvaW50ID0gY29uc3RyYWluUG9pbnQoYWRqdXN0ZWRQb2ludCwgc3ViamVjdFJlY3QpO1xuICAgICAgICB9XG4gICAgICAgIGxldCBpbml0aWFsSGl0ID0gdGhpcy5pbml0aWFsSGl0ID0gdGhpcy5xdWVyeUhpdEZvck9mZnNldChhZGp1c3RlZFBvaW50LmxlZnQsIGFkanVzdGVkUG9pbnQudG9wKTtcbiAgICAgICAgaWYgKGluaXRpYWxIaXQpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnVzZVN1YmplY3RDZW50ZXIgJiYgc3ViamVjdFJlY3QpIHtcbiAgICAgICAgICAgICAgICBsZXQgc2xpY2VkU3ViamVjdFJlY3QgPSBpbnRlcnNlY3RSZWN0cyhzdWJqZWN0UmVjdCwgaW5pdGlhbEhpdC5yZWN0KTtcbiAgICAgICAgICAgICAgICBpZiAoc2xpY2VkU3ViamVjdFJlY3QpIHtcbiAgICAgICAgICAgICAgICAgICAgYWRqdXN0ZWRQb2ludCA9IGdldFJlY3RDZW50ZXIoc2xpY2VkU3ViamVjdFJlY3QpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuY29vcmRBZGp1c3QgPSBkaWZmUG9pbnRzKGFkanVzdGVkUG9pbnQsIG9yaWdQb2ludCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNvb3JkQWRqdXN0ID0geyBsZWZ0OiAwLCB0b3A6IDAgfTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBoYW5kbGVNb3ZlKGV2LCBmb3JjZUhhbmRsZSkge1xuICAgICAgICBsZXQgaGl0ID0gdGhpcy5xdWVyeUhpdEZvck9mZnNldChldi5wYWdlWCArIHRoaXMuY29vcmRBZGp1c3QubGVmdCwgZXYucGFnZVkgKyB0aGlzLmNvb3JkQWRqdXN0LnRvcCk7XG4gICAgICAgIGlmIChmb3JjZUhhbmRsZSB8fCAhaXNIaXRzRXF1YWwodGhpcy5tb3ZpbmdIaXQsIGhpdCkpIHtcbiAgICAgICAgICAgIHRoaXMubW92aW5nSGl0ID0gaGl0O1xuICAgICAgICAgICAgdGhpcy5lbWl0dGVyLnRyaWdnZXIoJ2hpdHVwZGF0ZScsIGhpdCwgZmFsc2UsIGV2KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBwcmVwYXJlSGl0cygpIHtcbiAgICAgICAgdGhpcy5vZmZzZXRUcmFja2VycyA9IG1hcEhhc2godGhpcy5kcm9wcGFibGVTdG9yZSwgKGludGVyYWN0aW9uU2V0dGluZ3MpID0+IHtcbiAgICAgICAgICAgIGludGVyYWN0aW9uU2V0dGluZ3MuY29tcG9uZW50LnByZXBhcmVIaXRzKCk7XG4gICAgICAgICAgICByZXR1cm4gbmV3IE9mZnNldFRyYWNrZXIoaW50ZXJhY3Rpb25TZXR0aW5ncy5lbCk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgICByZWxlYXNlSGl0cygpIHtcbiAgICAgICAgbGV0IHsgb2Zmc2V0VHJhY2tlcnMgfSA9IHRoaXM7XG4gICAgICAgIGZvciAobGV0IGlkIGluIG9mZnNldFRyYWNrZXJzKSB7XG4gICAgICAgICAgICBvZmZzZXRUcmFja2Vyc1tpZF0uZGVzdHJveSgpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMub2Zmc2V0VHJhY2tlcnMgPSB7fTtcbiAgICB9XG4gICAgcXVlcnlIaXRGb3JPZmZzZXQob2Zmc2V0TGVmdCwgb2Zmc2V0VG9wKSB7XG4gICAgICAgIGxldCB7IGRyb3BwYWJsZVN0b3JlLCBvZmZzZXRUcmFja2VycyB9ID0gdGhpcztcbiAgICAgICAgbGV0IGJlc3RIaXQgPSBudWxsO1xuICAgICAgICBmb3IgKGxldCBpZCBpbiBkcm9wcGFibGVTdG9yZSkge1xuICAgICAgICAgICAgbGV0IGNvbXBvbmVudCA9IGRyb3BwYWJsZVN0b3JlW2lkXS5jb21wb25lbnQ7XG4gICAgICAgICAgICBsZXQgb2Zmc2V0VHJhY2tlciA9IG9mZnNldFRyYWNrZXJzW2lkXTtcbiAgICAgICAgICAgIGlmIChvZmZzZXRUcmFja2VyICYmIC8vIHdhc24ndCBkZXN0cm95ZWQgbWlkLWRyYWdcbiAgICAgICAgICAgICAgICBvZmZzZXRUcmFja2VyLmlzV2l0aGluQ2xpcHBpbmcob2Zmc2V0TGVmdCwgb2Zmc2V0VG9wKSkge1xuICAgICAgICAgICAgICAgIGxldCBvcmlnaW5MZWZ0ID0gb2Zmc2V0VHJhY2tlci5jb21wdXRlTGVmdCgpO1xuICAgICAgICAgICAgICAgIGxldCBvcmlnaW5Ub3AgPSBvZmZzZXRUcmFja2VyLmNvbXB1dGVUb3AoKTtcbiAgICAgICAgICAgICAgICBsZXQgcG9zaXRpb25MZWZ0ID0gb2Zmc2V0TGVmdCAtIG9yaWdpbkxlZnQ7XG4gICAgICAgICAgICAgICAgbGV0IHBvc2l0aW9uVG9wID0gb2Zmc2V0VG9wIC0gb3JpZ2luVG9wO1xuICAgICAgICAgICAgICAgIGxldCB7IG9yaWdSZWN0IH0gPSBvZmZzZXRUcmFja2VyO1xuICAgICAgICAgICAgICAgIGxldCB3aWR0aCA9IG9yaWdSZWN0LnJpZ2h0IC0gb3JpZ1JlY3QubGVmdDtcbiAgICAgICAgICAgICAgICBsZXQgaGVpZ2h0ID0gb3JpZ1JlY3QuYm90dG9tIC0gb3JpZ1JlY3QudG9wO1xuICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAvLyBtdXN0IGJlIHdpdGhpbiB0aGUgZWxlbWVudCdzIGJvdW5kc1xuICAgICAgICAgICAgICAgIHBvc2l0aW9uTGVmdCA+PSAwICYmIHBvc2l0aW9uTGVmdCA8IHdpZHRoICYmXG4gICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uVG9wID49IDAgJiYgcG9zaXRpb25Ub3AgPCBoZWlnaHQpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGhpdCA9IGNvbXBvbmVudC5xdWVyeUhpdChwb3NpdGlvbkxlZnQsIHBvc2l0aW9uVG9wLCB3aWR0aCwgaGVpZ2h0KTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGhpdCAmJiAoXG4gICAgICAgICAgICAgICAgICAgIC8vIG1ha2Ugc3VyZSB0aGUgaGl0IGlzIHdpdGhpbiBhY3RpdmVSYW5nZSwgbWVhbmluZyBpdCdzIG5vdCBhIGRlYWQgY2VsbFxuICAgICAgICAgICAgICAgICAgICByYW5nZUNvbnRhaW5zUmFuZ2UoaGl0LmRhdGVQcm9maWxlLmFjdGl2ZVJhbmdlLCBoaXQuZGF0ZVNwYW4ucmFuZ2UpKSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgKCFiZXN0SGl0IHx8IGhpdC5sYXllciA+IGJlc3RIaXQubGF5ZXIpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBoaXQuY29tcG9uZW50SWQgPSBpZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGhpdC5jb250ZXh0ID0gY29tcG9uZW50LmNvbnRleHQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBUT0RPOiBiZXR0ZXIgd2F5IHRvIHJlLW9yaWVudCByZWN0YW5nbGVcbiAgICAgICAgICAgICAgICAgICAgICAgIGhpdC5yZWN0LmxlZnQgKz0gb3JpZ2luTGVmdDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGhpdC5yZWN0LnJpZ2h0ICs9IG9yaWdpbkxlZnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICBoaXQucmVjdC50b3AgKz0gb3JpZ2luVG9wO1xuICAgICAgICAgICAgICAgICAgICAgICAgaGl0LnJlY3QuYm90dG9tICs9IG9yaWdpblRvcDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJlc3RIaXQgPSBoaXQ7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGJlc3RIaXQ7XG4gICAgfVxufVxuZnVuY3Rpb24gaXNIaXRzRXF1YWwoaGl0MCwgaGl0MSkge1xuICAgIGlmICghaGl0MCAmJiAhaGl0MSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKEJvb2xlYW4oaGl0MCkgIT09IEJvb2xlYW4oaGl0MSkpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gaXNEYXRlU3BhbnNFcXVhbChoaXQwLmRhdGVTcGFuLCBoaXQxLmRhdGVTcGFuKTtcbn1cblxuZnVuY3Rpb24gYnVpbGREYXRlUG9pbnRBcGlXaXRoQ29udGV4dChkYXRlU3BhbiwgY29udGV4dCkge1xuICAgIGxldCBwcm9wcyA9IHt9O1xuICAgIGZvciAobGV0IHRyYW5zZm9ybSBvZiBjb250ZXh0LnBsdWdpbkhvb2tzLmRhdGVQb2ludFRyYW5zZm9ybXMpIHtcbiAgICAgICAgT2JqZWN0LmFzc2lnbihwcm9wcywgdHJhbnNmb3JtKGRhdGVTcGFuLCBjb250ZXh0KSk7XG4gICAgfVxuICAgIE9iamVjdC5hc3NpZ24ocHJvcHMsIGJ1aWxkRGF0ZVBvaW50QXBpKGRhdGVTcGFuLCBjb250ZXh0LmRhdGVFbnYpKTtcbiAgICByZXR1cm4gcHJvcHM7XG59XG5mdW5jdGlvbiBidWlsZERhdGVQb2ludEFwaShzcGFuLCBkYXRlRW52KSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgZGF0ZTogZGF0ZUVudi50b0RhdGUoc3Bhbi5yYW5nZS5zdGFydCksXG4gICAgICAgIGRhdGVTdHI6IGRhdGVFbnYuZm9ybWF0SXNvKHNwYW4ucmFuZ2Uuc3RhcnQsIHsgb21pdFRpbWU6IHNwYW4uYWxsRGF5IH0pLFxuICAgICAgICBhbGxEYXk6IHNwYW4uYWxsRGF5LFxuICAgIH07XG59XG5cbi8qXG5Nb25pdG9ycyB3aGVuIHRoZSB1c2VyIGNsaWNrcyBvbiBhIHNwZWNpZmljIGRhdGUvdGltZSBvZiBhIGNvbXBvbmVudC5cbkEgcG9pbnRlcmRvd24rcG9pbnRlcnVwIG9uIHRoZSBzYW1lIFwiaGl0XCIgY29uc3RpdHV0ZXMgYSBjbGljay5cbiovXG5jbGFzcyBEYXRlQ2xpY2tpbmcgZXh0ZW5kcyBJbnRlcmFjdGlvbiB7XG4gICAgY29uc3RydWN0b3Ioc2V0dGluZ3MpIHtcbiAgICAgICAgc3VwZXIoc2V0dGluZ3MpO1xuICAgICAgICB0aGlzLmhhbmRsZVBvaW50ZXJEb3duID0gKHBldikgPT4ge1xuICAgICAgICAgICAgbGV0IHsgZHJhZ2dpbmcgfSA9IHRoaXM7XG4gICAgICAgICAgICBsZXQgZG93bkVsID0gcGV2Lm9yaWdFdmVudC50YXJnZXQ7XG4gICAgICAgICAgICAvLyBkbyB0aGlzIGluIHBvaW50ZXJkb3duIChub3QgZHJhZ2VuZCkgYmVjYXVzZSBET00gbWlnaHQgYmUgbXV0YXRlZCBieSB0aGUgdGltZSBkcmFnZW5kIGlzIGZpcmVkXG4gICAgICAgICAgICBkcmFnZ2luZy5zZXRJZ25vcmVNb3ZlKCF0aGlzLmNvbXBvbmVudC5pc1ZhbGlkRGF0ZURvd25FbChkb3duRWwpKTtcbiAgICAgICAgfTtcbiAgICAgICAgLy8gd29uJ3QgZXZlbiBmaXJlIGlmIG1vdmluZyB3YXMgaWdub3JlZFxuICAgICAgICB0aGlzLmhhbmRsZURyYWdFbmQgPSAoZXYpID0+IHtcbiAgICAgICAgICAgIGxldCB7IGNvbXBvbmVudCB9ID0gdGhpcztcbiAgICAgICAgICAgIGxldCB7IHBvaW50ZXIgfSA9IHRoaXMuZHJhZ2dpbmc7XG4gICAgICAgICAgICBpZiAoIXBvaW50ZXIud2FzVG91Y2hTY3JvbGwpIHtcbiAgICAgICAgICAgICAgICBsZXQgeyBpbml0aWFsSGl0LCBmaW5hbEhpdCB9ID0gdGhpcy5oaXREcmFnZ2luZztcbiAgICAgICAgICAgICAgICBpZiAoaW5pdGlhbEhpdCAmJiBmaW5hbEhpdCAmJiBpc0hpdHNFcXVhbChpbml0aWFsSGl0LCBmaW5hbEhpdCkpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IHsgY29udGV4dCB9ID0gY29tcG9uZW50O1xuICAgICAgICAgICAgICAgICAgICBsZXQgYXJnID0gT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCBidWlsZERhdGVQb2ludEFwaVdpdGhDb250ZXh0KGluaXRpYWxIaXQuZGF0ZVNwYW4sIGNvbnRleHQpKSwgeyBkYXlFbDogaW5pdGlhbEhpdC5kYXlFbCwganNFdmVudDogZXYub3JpZ0V2ZW50LCB2aWV3OiBjb250ZXh0LnZpZXdBcGkgfHwgY29udGV4dC5jYWxlbmRhckFwaS52aWV3IH0pO1xuICAgICAgICAgICAgICAgICAgICBjb250ZXh0LmVtaXR0ZXIudHJpZ2dlcignZGF0ZUNsaWNrJywgYXJnKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIC8vIHdlIERPIHdhbnQgdG8gd2F0Y2ggcG9pbnRlciBtb3ZlcyBiZWNhdXNlIG90aGVyd2lzZSBmaW5hbEhpdCB3b24ndCBnZXQgcG9wdWxhdGVkXG4gICAgICAgIHRoaXMuZHJhZ2dpbmcgPSBuZXcgRmVhdHVyZWZ1bEVsZW1lbnREcmFnZ2luZyhzZXR0aW5ncy5lbCk7XG4gICAgICAgIHRoaXMuZHJhZ2dpbmcuYXV0b1Njcm9sbGVyLmlzRW5hYmxlZCA9IGZhbHNlO1xuICAgICAgICBsZXQgaGl0RHJhZ2dpbmcgPSB0aGlzLmhpdERyYWdnaW5nID0gbmV3IEhpdERyYWdnaW5nKHRoaXMuZHJhZ2dpbmcsIGludGVyYWN0aW9uU2V0dGluZ3NUb1N0b3JlKHNldHRpbmdzKSk7XG4gICAgICAgIGhpdERyYWdnaW5nLmVtaXR0ZXIub24oJ3BvaW50ZXJkb3duJywgdGhpcy5oYW5kbGVQb2ludGVyRG93bik7XG4gICAgICAgIGhpdERyYWdnaW5nLmVtaXR0ZXIub24oJ2RyYWdlbmQnLCB0aGlzLmhhbmRsZURyYWdFbmQpO1xuICAgIH1cbiAgICBkZXN0cm95KCkge1xuICAgICAgICB0aGlzLmRyYWdnaW5nLmRlc3Ryb3koKTtcbiAgICB9XG59XG5cbi8qXG5UcmFja3Mgd2hlbiB0aGUgdXNlciBzZWxlY3RzIGEgcG9ydGlvbiBvZiB0aW1lIG9mIGEgY29tcG9uZW50LFxuY29uc3RpdHV0ZWQgYnkgYSBkcmFnIG92ZXIgZGF0ZSBjZWxscywgd2l0aCBhIHBvc3NpYmxlIGRlbGF5IGF0IHRoZSBiZWdpbm5pbmcgb2YgdGhlIGRyYWcuXG4qL1xuY2xhc3MgRGF0ZVNlbGVjdGluZyBleHRlbmRzIEludGVyYWN0aW9uIHtcbiAgICBjb25zdHJ1Y3RvcihzZXR0aW5ncykge1xuICAgICAgICBzdXBlcihzZXR0aW5ncyk7XG4gICAgICAgIHRoaXMuZHJhZ1NlbGVjdGlvbiA9IG51bGw7XG4gICAgICAgIHRoaXMuaGFuZGxlUG9pbnRlckRvd24gPSAoZXYpID0+IHtcbiAgICAgICAgICAgIGxldCB7IGNvbXBvbmVudCwgZHJhZ2dpbmcgfSA9IHRoaXM7XG4gICAgICAgICAgICBsZXQgeyBvcHRpb25zIH0gPSBjb21wb25lbnQuY29udGV4dDtcbiAgICAgICAgICAgIGxldCBjYW5TZWxlY3QgPSBvcHRpb25zLnNlbGVjdGFibGUgJiZcbiAgICAgICAgICAgICAgICBjb21wb25lbnQuaXNWYWxpZERhdGVEb3duRWwoZXYub3JpZ0V2ZW50LnRhcmdldCk7XG4gICAgICAgICAgICAvLyBkb24ndCBib3RoZXIgdG8gd2F0Y2ggZXhwZW5zaXZlIG1vdmVzIGlmIGNvbXBvbmVudCB3b24ndCBkbyBzZWxlY3Rpb25cbiAgICAgICAgICAgIGRyYWdnaW5nLnNldElnbm9yZU1vdmUoIWNhblNlbGVjdCk7XG4gICAgICAgICAgICAvLyBpZiB0b3VjaCwgcmVxdWlyZSB1c2VyIHRvIGhvbGQgZG93blxuICAgICAgICAgICAgZHJhZ2dpbmcuZGVsYXkgPSBldi5pc1RvdWNoID8gZ2V0Q29tcG9uZW50VG91Y2hEZWxheSQxKGNvbXBvbmVudCkgOiBudWxsO1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLmhhbmRsZURyYWdTdGFydCA9IChldikgPT4ge1xuICAgICAgICAgICAgdGhpcy5jb21wb25lbnQuY29udGV4dC5jYWxlbmRhckFwaS51bnNlbGVjdChldik7IC8vIHVuc2VsZWN0IHByZXZpb3VzIHNlbGVjdGlvbnNcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5oYW5kbGVIaXRVcGRhdGUgPSAoaGl0LCBpc0ZpbmFsKSA9PiB7XG4gICAgICAgICAgICBsZXQgeyBjb250ZXh0IH0gPSB0aGlzLmNvbXBvbmVudDtcbiAgICAgICAgICAgIGxldCBkcmFnU2VsZWN0aW9uID0gbnVsbDtcbiAgICAgICAgICAgIGxldCBpc0ludmFsaWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGlmIChoaXQpIHtcbiAgICAgICAgICAgICAgICBsZXQgaW5pdGlhbEhpdCA9IHRoaXMuaGl0RHJhZ2dpbmcuaW5pdGlhbEhpdDtcbiAgICAgICAgICAgICAgICBsZXQgZGlzYWxsb3dlZCA9IGhpdC5jb21wb25lbnRJZCA9PT0gaW5pdGlhbEhpdC5jb21wb25lbnRJZFxuICAgICAgICAgICAgICAgICAgICAmJiB0aGlzLmlzSGl0Q29tYm9BbGxvd2VkXG4gICAgICAgICAgICAgICAgICAgICYmICF0aGlzLmlzSGl0Q29tYm9BbGxvd2VkKGluaXRpYWxIaXQsIGhpdCk7XG4gICAgICAgICAgICAgICAgaWYgKCFkaXNhbGxvd2VkKSB7XG4gICAgICAgICAgICAgICAgICAgIGRyYWdTZWxlY3Rpb24gPSBqb2luSGl0c0ludG9TZWxlY3Rpb24oaW5pdGlhbEhpdCwgaGl0LCBjb250ZXh0LnBsdWdpbkhvb2tzLmRhdGVTZWxlY3Rpb25UcmFuc2Zvcm1lcnMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoIWRyYWdTZWxlY3Rpb24gfHwgIWlzRGF0ZVNlbGVjdGlvblZhbGlkKGRyYWdTZWxlY3Rpb24sIGhpdC5kYXRlUHJvZmlsZSwgY29udGV4dCkpIHtcbiAgICAgICAgICAgICAgICAgICAgaXNJbnZhbGlkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgZHJhZ1NlbGVjdGlvbiA9IG51bGw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGRyYWdTZWxlY3Rpb24pIHtcbiAgICAgICAgICAgICAgICBjb250ZXh0LmRpc3BhdGNoKHsgdHlwZTogJ1NFTEVDVF9EQVRFUycsIHNlbGVjdGlvbjogZHJhZ1NlbGVjdGlvbiB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKCFpc0ZpbmFsKSB7IC8vIG9ubHkgdW5zZWxlY3QgaWYgbW92ZWQgYXdheSB3aGlsZSBkcmFnZ2luZ1xuICAgICAgICAgICAgICAgIGNvbnRleHQuZGlzcGF0Y2goeyB0eXBlOiAnVU5TRUxFQ1RfREFURVMnIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFpc0ludmFsaWQpIHtcbiAgICAgICAgICAgICAgICBlbmFibGVDdXJzb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGRpc2FibGVDdXJzb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghaXNGaW5hbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZHJhZ1NlbGVjdGlvbiA9IGRyYWdTZWxlY3Rpb247IC8vIG9ubHkgY2xlYXIgaWYgbW92ZWQgYXdheSBmcm9tIGFsbCBoaXRzIHdoaWxlIGRyYWdnaW5nXG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuaGFuZGxlUG9pbnRlclVwID0gKHBldikgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuZHJhZ1NlbGVjdGlvbikge1xuICAgICAgICAgICAgICAgIC8vIHNlbGVjdGlvbiBpcyBhbHJlYWR5IHJlbmRlcmVkLCBzbyBqdXN0IG5lZWQgdG8gcmVwb3J0IHNlbGVjdGlvblxuICAgICAgICAgICAgICAgIHRyaWdnZXJEYXRlU2VsZWN0KHRoaXMuZHJhZ1NlbGVjdGlvbiwgcGV2LCB0aGlzLmNvbXBvbmVudC5jb250ZXh0KTtcbiAgICAgICAgICAgICAgICB0aGlzLmRyYWdTZWxlY3Rpb24gPSBudWxsO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBsZXQgeyBjb21wb25lbnQgfSA9IHNldHRpbmdzO1xuICAgICAgICBsZXQgeyBvcHRpb25zIH0gPSBjb21wb25lbnQuY29udGV4dDtcbiAgICAgICAgbGV0IGRyYWdnaW5nID0gdGhpcy5kcmFnZ2luZyA9IG5ldyBGZWF0dXJlZnVsRWxlbWVudERyYWdnaW5nKHNldHRpbmdzLmVsKTtcbiAgICAgICAgZHJhZ2dpbmcudG91Y2hTY3JvbGxBbGxvd2VkID0gZmFsc2U7XG4gICAgICAgIGRyYWdnaW5nLm1pbkRpc3RhbmNlID0gb3B0aW9ucy5zZWxlY3RNaW5EaXN0YW5jZSB8fCAwO1xuICAgICAgICBkcmFnZ2luZy5hdXRvU2Nyb2xsZXIuaXNFbmFibGVkID0gb3B0aW9ucy5kcmFnU2Nyb2xsO1xuICAgICAgICBsZXQgaGl0RHJhZ2dpbmcgPSB0aGlzLmhpdERyYWdnaW5nID0gbmV3IEhpdERyYWdnaW5nKHRoaXMuZHJhZ2dpbmcsIGludGVyYWN0aW9uU2V0dGluZ3NUb1N0b3JlKHNldHRpbmdzKSk7XG4gICAgICAgIGhpdERyYWdnaW5nLmVtaXR0ZXIub24oJ3BvaW50ZXJkb3duJywgdGhpcy5oYW5kbGVQb2ludGVyRG93bik7XG4gICAgICAgIGhpdERyYWdnaW5nLmVtaXR0ZXIub24oJ2RyYWdzdGFydCcsIHRoaXMuaGFuZGxlRHJhZ1N0YXJ0KTtcbiAgICAgICAgaGl0RHJhZ2dpbmcuZW1pdHRlci5vbignaGl0dXBkYXRlJywgdGhpcy5oYW5kbGVIaXRVcGRhdGUpO1xuICAgICAgICBoaXREcmFnZ2luZy5lbWl0dGVyLm9uKCdwb2ludGVydXAnLCB0aGlzLmhhbmRsZVBvaW50ZXJVcCk7XG4gICAgfVxuICAgIGRlc3Ryb3koKSB7XG4gICAgICAgIHRoaXMuZHJhZ2dpbmcuZGVzdHJveSgpO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGdldENvbXBvbmVudFRvdWNoRGVsYXkkMShjb21wb25lbnQpIHtcbiAgICBsZXQgeyBvcHRpb25zIH0gPSBjb21wb25lbnQuY29udGV4dDtcbiAgICBsZXQgZGVsYXkgPSBvcHRpb25zLnNlbGVjdExvbmdQcmVzc0RlbGF5O1xuICAgIGlmIChkZWxheSA9PSBudWxsKSB7XG4gICAgICAgIGRlbGF5ID0gb3B0aW9ucy5sb25nUHJlc3NEZWxheTtcbiAgICB9XG4gICAgcmV0dXJuIGRlbGF5O1xufVxuZnVuY3Rpb24gam9pbkhpdHNJbnRvU2VsZWN0aW9uKGhpdDAsIGhpdDEsIGRhdGVTZWxlY3Rpb25UcmFuc2Zvcm1lcnMpIHtcbiAgICBsZXQgZGF0ZVNwYW4wID0gaGl0MC5kYXRlU3BhbjtcbiAgICBsZXQgZGF0ZVNwYW4xID0gaGl0MS5kYXRlU3BhbjtcbiAgICBsZXQgbXMgPSBbXG4gICAgICAgIGRhdGVTcGFuMC5yYW5nZS5zdGFydCxcbiAgICAgICAgZGF0ZVNwYW4wLnJhbmdlLmVuZCxcbiAgICAgICAgZGF0ZVNwYW4xLnJhbmdlLnN0YXJ0LFxuICAgICAgICBkYXRlU3BhbjEucmFuZ2UuZW5kLFxuICAgIF07XG4gICAgbXMuc29ydChjb21wYXJlTnVtYmVycyk7XG4gICAgbGV0IHByb3BzID0ge307XG4gICAgZm9yIChsZXQgdHJhbnNmb3JtZXIgb2YgZGF0ZVNlbGVjdGlvblRyYW5zZm9ybWVycykge1xuICAgICAgICBsZXQgcmVzID0gdHJhbnNmb3JtZXIoaGl0MCwgaGl0MSk7XG4gICAgICAgIGlmIChyZXMgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmVzKSB7XG4gICAgICAgICAgICBPYmplY3QuYXNzaWduKHByb3BzLCByZXMpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHByb3BzLnJhbmdlID0geyBzdGFydDogbXNbMF0sIGVuZDogbXNbM10gfTtcbiAgICBwcm9wcy5hbGxEYXkgPSBkYXRlU3BhbjAuYWxsRGF5O1xuICAgIHJldHVybiBwcm9wcztcbn1cblxuY2xhc3MgRXZlbnREcmFnZ2luZyBleHRlbmRzIEludGVyYWN0aW9uIHtcbiAgICBjb25zdHJ1Y3RvcihzZXR0aW5ncykge1xuICAgICAgICBzdXBlcihzZXR0aW5ncyk7XG4gICAgICAgIC8vIGludGVybmFsIHN0YXRlXG4gICAgICAgIHRoaXMuc3ViamVjdEVsID0gbnVsbDtcbiAgICAgICAgdGhpcy5zdWJqZWN0U2VnID0gbnVsbDsgLy8gdGhlIHNlZyBiZWluZyBzZWxlY3RlZC9kcmFnZ2VkXG4gICAgICAgIHRoaXMuaXNEcmFnZ2luZyA9IGZhbHNlO1xuICAgICAgICB0aGlzLmV2ZW50UmFuZ2UgPSBudWxsO1xuICAgICAgICB0aGlzLnJlbGV2YW50RXZlbnRzID0gbnVsbDsgLy8gdGhlIGV2ZW50cyBiZWluZyBkcmFnZ2VkXG4gICAgICAgIHRoaXMucmVjZWl2aW5nQ29udGV4dCA9IG51bGw7XG4gICAgICAgIHRoaXMudmFsaWRNdXRhdGlvbiA9IG51bGw7XG4gICAgICAgIHRoaXMubXV0YXRlZFJlbGV2YW50RXZlbnRzID0gbnVsbDtcbiAgICAgICAgdGhpcy5oYW5kbGVQb2ludGVyRG93biA9IChldikgPT4ge1xuICAgICAgICAgICAgbGV0IG9yaWdUYXJnZXQgPSBldi5vcmlnRXZlbnQudGFyZ2V0O1xuICAgICAgICAgICAgbGV0IHsgY29tcG9uZW50LCBkcmFnZ2luZyB9ID0gdGhpcztcbiAgICAgICAgICAgIGxldCB7IG1pcnJvciB9ID0gZHJhZ2dpbmc7XG4gICAgICAgICAgICBsZXQgeyBvcHRpb25zIH0gPSBjb21wb25lbnQuY29udGV4dDtcbiAgICAgICAgICAgIGxldCBpbml0aWFsQ29udGV4dCA9IGNvbXBvbmVudC5jb250ZXh0O1xuICAgICAgICAgICAgdGhpcy5zdWJqZWN0RWwgPSBldi5zdWJqZWN0RWw7XG4gICAgICAgICAgICBsZXQgc3ViamVjdFNlZyA9IHRoaXMuc3ViamVjdFNlZyA9IGdldEVsU2VnKGV2LnN1YmplY3RFbCk7XG4gICAgICAgICAgICBsZXQgZXZlbnRSYW5nZSA9IHRoaXMuZXZlbnRSYW5nZSA9IHN1YmplY3RTZWcuZXZlbnRSYW5nZTtcbiAgICAgICAgICAgIGxldCBldmVudEluc3RhbmNlSWQgPSBldmVudFJhbmdlLmluc3RhbmNlLmluc3RhbmNlSWQ7XG4gICAgICAgICAgICB0aGlzLnJlbGV2YW50RXZlbnRzID0gZ2V0UmVsZXZhbnRFdmVudHMoaW5pdGlhbENvbnRleHQuZ2V0Q3VycmVudERhdGEoKS5ldmVudFN0b3JlLCBldmVudEluc3RhbmNlSWQpO1xuICAgICAgICAgICAgZHJhZ2dpbmcubWluRGlzdGFuY2UgPSBldi5pc1RvdWNoID8gMCA6IG9wdGlvbnMuZXZlbnREcmFnTWluRGlzdGFuY2U7XG4gICAgICAgICAgICBkcmFnZ2luZy5kZWxheSA9XG4gICAgICAgICAgICAgICAgLy8gb25seSBkbyBhIHRvdWNoIGRlbGF5IGlmIHRvdWNoIGFuZCB0aGlzIGV2ZW50IGhhc24ndCBiZWVuIHNlbGVjdGVkIHlldFxuICAgICAgICAgICAgICAgIChldi5pc1RvdWNoICYmIGV2ZW50SW5zdGFuY2VJZCAhPT0gY29tcG9uZW50LnByb3BzLmV2ZW50U2VsZWN0aW9uKSA/XG4gICAgICAgICAgICAgICAgICAgIGdldENvbXBvbmVudFRvdWNoRGVsYXkoY29tcG9uZW50KSA6XG4gICAgICAgICAgICAgICAgICAgIG51bGw7XG4gICAgICAgICAgICBpZiAob3B0aW9ucy5maXhlZE1pcnJvclBhcmVudCkge1xuICAgICAgICAgICAgICAgIG1pcnJvci5wYXJlbnROb2RlID0gb3B0aW9ucy5maXhlZE1pcnJvclBhcmVudDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIG1pcnJvci5wYXJlbnROb2RlID0gZWxlbWVudENsb3Nlc3Qob3JpZ1RhcmdldCwgJy5mYycpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbWlycm9yLnJldmVydER1cmF0aW9uID0gb3B0aW9ucy5kcmFnUmV2ZXJ0RHVyYXRpb247XG4gICAgICAgICAgICBsZXQgaXNWYWxpZCA9IGNvbXBvbmVudC5pc1ZhbGlkU2VnRG93bkVsKG9yaWdUYXJnZXQpICYmXG4gICAgICAgICAgICAgICAgIWVsZW1lbnRDbG9zZXN0KG9yaWdUYXJnZXQsICcuZmMtZXZlbnQtcmVzaXplcicpOyAvLyBOT1Qgb24gYSByZXNpemVyXG4gICAgICAgICAgICBkcmFnZ2luZy5zZXRJZ25vcmVNb3ZlKCFpc1ZhbGlkKTtcbiAgICAgICAgICAgIC8vIGRpc2FibGUgZHJhZ2dpbmcgZm9yIGVsZW1lbnRzIHRoYXQgYXJlIHJlc2l6YWJsZSAoaWUsIHNlbGVjdGFibGUpXG4gICAgICAgICAgICAvLyBidXQgYXJlIG5vdCBkcmFnZ2FibGVcbiAgICAgICAgICAgIHRoaXMuaXNEcmFnZ2luZyA9IGlzVmFsaWQgJiZcbiAgICAgICAgICAgICAgICBldi5zdWJqZWN0RWwuY2xhc3NMaXN0LmNvbnRhaW5zKCdmYy1ldmVudC1kcmFnZ2FibGUnKTtcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5oYW5kbGVEcmFnU3RhcnQgPSAoZXYpID0+IHtcbiAgICAgICAgICAgIGxldCBpbml0aWFsQ29udGV4dCA9IHRoaXMuY29tcG9uZW50LmNvbnRleHQ7XG4gICAgICAgICAgICBsZXQgZXZlbnRSYW5nZSA9IHRoaXMuZXZlbnRSYW5nZTtcbiAgICAgICAgICAgIGxldCBldmVudEluc3RhbmNlSWQgPSBldmVudFJhbmdlLmluc3RhbmNlLmluc3RhbmNlSWQ7XG4gICAgICAgICAgICBpZiAoZXYuaXNUb3VjaCkge1xuICAgICAgICAgICAgICAgIC8vIG5lZWQgdG8gc2VsZWN0IGEgZGlmZmVyZW50IGV2ZW50P1xuICAgICAgICAgICAgICAgIGlmIChldmVudEluc3RhbmNlSWQgIT09IHRoaXMuY29tcG9uZW50LnByb3BzLmV2ZW50U2VsZWN0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgIGluaXRpYWxDb250ZXh0LmRpc3BhdGNoKHsgdHlwZTogJ1NFTEVDVF9FVkVOVCcsIGV2ZW50SW5zdGFuY2VJZCB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBpZiBub3cgdXNpbmcgbW91c2UsIGJ1dCB3YXMgcHJldmlvdXMgdG91Y2ggaW50ZXJhY3Rpb24sIGNsZWFyIHNlbGVjdGVkIGV2ZW50XG4gICAgICAgICAgICAgICAgaW5pdGlhbENvbnRleHQuZGlzcGF0Y2goeyB0eXBlOiAnVU5TRUxFQ1RfRVZFTlQnIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuaXNEcmFnZ2luZykge1xuICAgICAgICAgICAgICAgIGluaXRpYWxDb250ZXh0LmNhbGVuZGFyQXBpLnVuc2VsZWN0KGV2KTsgLy8gdW5zZWxlY3QgKmRhdGUqIHNlbGVjdGlvblxuICAgICAgICAgICAgICAgIGluaXRpYWxDb250ZXh0LmVtaXR0ZXIudHJpZ2dlcignZXZlbnREcmFnU3RhcnQnLCB7XG4gICAgICAgICAgICAgICAgICAgIGVsOiB0aGlzLnN1YmplY3RFbCxcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQ6IG5ldyBFdmVudEltcGwoaW5pdGlhbENvbnRleHQsIGV2ZW50UmFuZ2UuZGVmLCBldmVudFJhbmdlLmluc3RhbmNlKSxcbiAgICAgICAgICAgICAgICAgICAganNFdmVudDogZXYub3JpZ0V2ZW50LFxuICAgICAgICAgICAgICAgICAgICB2aWV3OiBpbml0aWFsQ29udGV4dC52aWV3QXBpLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICB0aGlzLmhhbmRsZUhpdFVwZGF0ZSA9IChoaXQsIGlzRmluYWwpID0+IHtcbiAgICAgICAgICAgIGlmICghdGhpcy5pc0RyYWdnaW5nKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGV0IHJlbGV2YW50RXZlbnRzID0gdGhpcy5yZWxldmFudEV2ZW50cztcbiAgICAgICAgICAgIGxldCBpbml0aWFsSGl0ID0gdGhpcy5oaXREcmFnZ2luZy5pbml0aWFsSGl0O1xuICAgICAgICAgICAgbGV0IGluaXRpYWxDb250ZXh0ID0gdGhpcy5jb21wb25lbnQuY29udGV4dDtcbiAgICAgICAgICAgIC8vIHN0YXRlcyBiYXNlZCBvbiBuZXcgaGl0XG4gICAgICAgICAgICBsZXQgcmVjZWl2aW5nQ29udGV4dCA9IG51bGw7XG4gICAgICAgICAgICBsZXQgbXV0YXRpb24gPSBudWxsO1xuICAgICAgICAgICAgbGV0IG11dGF0ZWRSZWxldmFudEV2ZW50cyA9IG51bGw7XG4gICAgICAgICAgICBsZXQgaXNJbnZhbGlkID0gZmFsc2U7XG4gICAgICAgICAgICBsZXQgaW50ZXJhY3Rpb24gPSB7XG4gICAgICAgICAgICAgICAgYWZmZWN0ZWRFdmVudHM6IHJlbGV2YW50RXZlbnRzLFxuICAgICAgICAgICAgICAgIG11dGF0ZWRFdmVudHM6IGNyZWF0ZUVtcHR5RXZlbnRTdG9yZSgpLFxuICAgICAgICAgICAgICAgIGlzRXZlbnQ6IHRydWUsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaWYgKGhpdCkge1xuICAgICAgICAgICAgICAgIHJlY2VpdmluZ0NvbnRleHQgPSBoaXQuY29udGV4dDtcbiAgICAgICAgICAgICAgICBsZXQgcmVjZWl2aW5nT3B0aW9ucyA9IHJlY2VpdmluZ0NvbnRleHQub3B0aW9ucztcbiAgICAgICAgICAgICAgICBpZiAoaW5pdGlhbENvbnRleHQgPT09IHJlY2VpdmluZ0NvbnRleHQgfHxcbiAgICAgICAgICAgICAgICAgICAgKHJlY2VpdmluZ09wdGlvbnMuZWRpdGFibGUgJiYgcmVjZWl2aW5nT3B0aW9ucy5kcm9wcGFibGUpKSB7XG4gICAgICAgICAgICAgICAgICAgIG11dGF0aW9uID0gY29tcHV0ZUV2ZW50TXV0YXRpb24oaW5pdGlhbEhpdCwgaGl0LCByZWNlaXZpbmdDb250ZXh0LmdldEN1cnJlbnREYXRhKCkucGx1Z2luSG9va3MuZXZlbnREcmFnTXV0YXRpb25NYXNzYWdlcnMpO1xuICAgICAgICAgICAgICAgICAgICBpZiAobXV0YXRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG11dGF0ZWRSZWxldmFudEV2ZW50cyA9IGFwcGx5TXV0YXRpb25Ub0V2ZW50U3RvcmUocmVsZXZhbnRFdmVudHMsIHJlY2VpdmluZ0NvbnRleHQuZ2V0Q3VycmVudERhdGEoKS5ldmVudFVpQmFzZXMsIG11dGF0aW9uLCByZWNlaXZpbmdDb250ZXh0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGludGVyYWN0aW9uLm11dGF0ZWRFdmVudHMgPSBtdXRhdGVkUmVsZXZhbnRFdmVudHM7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWlzSW50ZXJhY3Rpb25WYWxpZChpbnRlcmFjdGlvbiwgaGl0LmRhdGVQcm9maWxlLCByZWNlaXZpbmdDb250ZXh0KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzSW52YWxpZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbXV0YXRpb24gPSBudWxsO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG11dGF0ZWRSZWxldmFudEV2ZW50cyA9IG51bGw7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50ZXJhY3Rpb24ubXV0YXRlZEV2ZW50cyA9IGNyZWF0ZUVtcHR5RXZlbnRTdG9yZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZWNlaXZpbmdDb250ZXh0ID0gbnVsbDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmRpc3BsYXlEcmFnKHJlY2VpdmluZ0NvbnRleHQsIGludGVyYWN0aW9uKTtcbiAgICAgICAgICAgIGlmICghaXNJbnZhbGlkKSB7XG4gICAgICAgICAgICAgICAgZW5hYmxlQ3Vyc29yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBkaXNhYmxlQ3Vyc29yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIWlzRmluYWwpIHtcbiAgICAgICAgICAgICAgICBpZiAoaW5pdGlhbENvbnRleHQgPT09IHJlY2VpdmluZ0NvbnRleHQgJiYgLy8gVE9ETzogd3JpdGUgdGVzdCBmb3IgdGhpc1xuICAgICAgICAgICAgICAgICAgICBpc0hpdHNFcXVhbChpbml0aWFsSGl0LCBoaXQpKSB7XG4gICAgICAgICAgICAgICAgICAgIG11dGF0aW9uID0gbnVsbDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5kcmFnZ2luZy5zZXRNaXJyb3JOZWVkc1JldmVydCghbXV0YXRpb24pO1xuICAgICAgICAgICAgICAgIC8vIHJlbmRlciB0aGUgbWlycm9yIGlmIG5vIGFscmVhZHktcmVuZGVyZWQgbWlycm9yXG4gICAgICAgICAgICAgICAgLy8gVE9ETzogd2lzaCB3ZSBjb3VsZCBzb21laG93IHdhaXQgZm9yIGRpc3BhdGNoIHRvIGd1YXJhbnRlZSByZW5kZXJcbiAgICAgICAgICAgICAgICB0aGlzLmRyYWdnaW5nLnNldE1pcnJvcklzVmlzaWJsZSghaGl0IHx8ICFnZXRFbFJvb3QodGhpcy5zdWJqZWN0RWwpLnF1ZXJ5U2VsZWN0b3IoJy5mYy1ldmVudC1taXJyb3InKSk7XG4gICAgICAgICAgICAgICAgLy8gYXNzaWduIHN0YXRlcyBiYXNlZCBvbiBuZXcgaGl0XG4gICAgICAgICAgICAgICAgdGhpcy5yZWNlaXZpbmdDb250ZXh0ID0gcmVjZWl2aW5nQ29udGV4dDtcbiAgICAgICAgICAgICAgICB0aGlzLnZhbGlkTXV0YXRpb24gPSBtdXRhdGlvbjtcbiAgICAgICAgICAgICAgICB0aGlzLm11dGF0ZWRSZWxldmFudEV2ZW50cyA9IG11dGF0ZWRSZWxldmFudEV2ZW50cztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5oYW5kbGVQb2ludGVyVXAgPSAoKSA9PiB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuaXNEcmFnZ2luZykge1xuICAgICAgICAgICAgICAgIHRoaXMuY2xlYW51cCgpOyAvLyBiZWNhdXNlIGhhbmRsZURyYWdFbmQgd29uJ3QgZmlyZVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICB0aGlzLmhhbmRsZURyYWdFbmQgPSAoZXYpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLmlzRHJhZ2dpbmcpIHtcbiAgICAgICAgICAgICAgICBsZXQgaW5pdGlhbENvbnRleHQgPSB0aGlzLmNvbXBvbmVudC5jb250ZXh0O1xuICAgICAgICAgICAgICAgIGxldCBpbml0aWFsVmlldyA9IGluaXRpYWxDb250ZXh0LnZpZXdBcGk7XG4gICAgICAgICAgICAgICAgbGV0IHsgcmVjZWl2aW5nQ29udGV4dCwgdmFsaWRNdXRhdGlvbiB9ID0gdGhpcztcbiAgICAgICAgICAgICAgICBsZXQgZXZlbnREZWYgPSB0aGlzLmV2ZW50UmFuZ2UuZGVmO1xuICAgICAgICAgICAgICAgIGxldCBldmVudEluc3RhbmNlID0gdGhpcy5ldmVudFJhbmdlLmluc3RhbmNlO1xuICAgICAgICAgICAgICAgIGxldCBldmVudEFwaSA9IG5ldyBFdmVudEltcGwoaW5pdGlhbENvbnRleHQsIGV2ZW50RGVmLCBldmVudEluc3RhbmNlKTtcbiAgICAgICAgICAgICAgICBsZXQgcmVsZXZhbnRFdmVudHMgPSB0aGlzLnJlbGV2YW50RXZlbnRzO1xuICAgICAgICAgICAgICAgIGxldCBtdXRhdGVkUmVsZXZhbnRFdmVudHMgPSB0aGlzLm11dGF0ZWRSZWxldmFudEV2ZW50cztcbiAgICAgICAgICAgICAgICBsZXQgeyBmaW5hbEhpdCB9ID0gdGhpcy5oaXREcmFnZ2luZztcbiAgICAgICAgICAgICAgICB0aGlzLmNsZWFyRHJhZygpOyAvLyBtdXN0IGhhcHBlbiBhZnRlciByZXZlcnQgYW5pbWF0aW9uXG4gICAgICAgICAgICAgICAgaW5pdGlhbENvbnRleHQuZW1pdHRlci50cmlnZ2VyKCdldmVudERyYWdTdG9wJywge1xuICAgICAgICAgICAgICAgICAgICBlbDogdGhpcy5zdWJqZWN0RWwsXG4gICAgICAgICAgICAgICAgICAgIGV2ZW50OiBldmVudEFwaSxcbiAgICAgICAgICAgICAgICAgICAganNFdmVudDogZXYub3JpZ0V2ZW50LFxuICAgICAgICAgICAgICAgICAgICB2aWV3OiBpbml0aWFsVmlldyxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBpZiAodmFsaWRNdXRhdGlvbikge1xuICAgICAgICAgICAgICAgICAgICAvLyBkcm9wcGVkIHdpdGhpbiBzYW1lIGNhbGVuZGFyXG4gICAgICAgICAgICAgICAgICAgIGlmIChyZWNlaXZpbmdDb250ZXh0ID09PSBpbml0aWFsQ29udGV4dCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHVwZGF0ZWRFdmVudEFwaSA9IG5ldyBFdmVudEltcGwoaW5pdGlhbENvbnRleHQsIG11dGF0ZWRSZWxldmFudEV2ZW50cy5kZWZzW2V2ZW50RGVmLmRlZklkXSwgZXZlbnRJbnN0YW5jZSA/IG11dGF0ZWRSZWxldmFudEV2ZW50cy5pbnN0YW5jZXNbZXZlbnRJbnN0YW5jZS5pbnN0YW5jZUlkXSA6IG51bGwpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaW5pdGlhbENvbnRleHQuZGlzcGF0Y2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdNRVJHRV9FVkVOVFMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50U3RvcmU6IG11dGF0ZWRSZWxldmFudEV2ZW50cyxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGV2ZW50Q2hhbmdlQXJnID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9sZEV2ZW50OiBldmVudEFwaSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudDogdXBkYXRlZEV2ZW50QXBpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbGF0ZWRFdmVudHM6IGJ1aWxkRXZlbnRBcGlzKG11dGF0ZWRSZWxldmFudEV2ZW50cywgaW5pdGlhbENvbnRleHQsIGV2ZW50SW5zdGFuY2UpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldmVydCgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5pdGlhbENvbnRleHQuZGlzcGF0Y2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ01FUkdFX0VWRU5UUycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudFN0b3JlOiByZWxldmFudEV2ZW50cywgLy8gdGhlIHByZS1jaGFuZ2UgZGF0YVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCB0cmFuc2Zvcm1lZCA9IHt9O1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgdHJhbnNmb3JtZXIgb2YgaW5pdGlhbENvbnRleHQuZ2V0Q3VycmVudERhdGEoKS5wbHVnaW5Ib29rcy5ldmVudERyb3BUcmFuc2Zvcm1lcnMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBPYmplY3QuYXNzaWduKHRyYW5zZm9ybWVkLCB0cmFuc2Zvcm1lcih2YWxpZE11dGF0aW9uLCBpbml0aWFsQ29udGV4dCkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgaW5pdGlhbENvbnRleHQuZW1pdHRlci50cmlnZ2VyKCdldmVudERyb3AnLCBPYmplY3QuYXNzaWduKE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgZXZlbnRDaGFuZ2VBcmcpLCB0cmFuc2Zvcm1lZCksIHsgZWw6IGV2LnN1YmplY3RFbCwgZGVsdGE6IHZhbGlkTXV0YXRpb24uZGF0ZXNEZWx0YSwganNFdmVudDogZXYub3JpZ0V2ZW50LCB2aWV3OiBpbml0aWFsVmlldyB9KSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpbml0aWFsQ29udGV4dC5lbWl0dGVyLnRyaWdnZXIoJ2V2ZW50Q2hhbmdlJywgZXZlbnRDaGFuZ2VBcmcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gZHJvcHBlZCBpbiBkaWZmZXJlbnQgY2FsZW5kYXJcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChyZWNlaXZpbmdDb250ZXh0KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgZXZlbnRSZW1vdmVBcmcgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQ6IGV2ZW50QXBpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbGF0ZWRFdmVudHM6IGJ1aWxkRXZlbnRBcGlzKHJlbGV2YW50RXZlbnRzLCBpbml0aWFsQ29udGV4dCwgZXZlbnRJbnN0YW5jZSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV2ZXJ0KCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbml0aWFsQ29udGV4dC5kaXNwYXRjaCh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAnTUVSR0VfRVZFTlRTJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50U3RvcmU6IHJlbGV2YW50RXZlbnRzLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGluaXRpYWxDb250ZXh0LmVtaXR0ZXIudHJpZ2dlcignZXZlbnRMZWF2ZScsIE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgZXZlbnRSZW1vdmVBcmcpLCB7IGRyYWdnZWRFbDogZXYuc3ViamVjdEVsLCB2aWV3OiBpbml0aWFsVmlldyB9KSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpbml0aWFsQ29udGV4dC5kaXNwYXRjaCh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ1JFTU9WRV9FVkVOVFMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50U3RvcmU6IHJlbGV2YW50RXZlbnRzLFxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpbml0aWFsQ29udGV4dC5lbWl0dGVyLnRyaWdnZXIoJ2V2ZW50UmVtb3ZlJywgZXZlbnRSZW1vdmVBcmcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGFkZGVkRXZlbnREZWYgPSBtdXRhdGVkUmVsZXZhbnRFdmVudHMuZGVmc1tldmVudERlZi5kZWZJZF07XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgYWRkZWRFdmVudEluc3RhbmNlID0gbXV0YXRlZFJlbGV2YW50RXZlbnRzLmluc3RhbmNlc1tldmVudEluc3RhbmNlLmluc3RhbmNlSWRdO1xuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGFkZGVkRXZlbnRBcGkgPSBuZXcgRXZlbnRJbXBsKHJlY2VpdmluZ0NvbnRleHQsIGFkZGVkRXZlbnREZWYsIGFkZGVkRXZlbnRJbnN0YW5jZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZWNlaXZpbmdDb250ZXh0LmRpc3BhdGNoKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAnTUVSR0VfRVZFTlRTJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudFN0b3JlOiBtdXRhdGVkUmVsZXZhbnRFdmVudHMsXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBldmVudEFkZEFyZyA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudDogYWRkZWRFdmVudEFwaSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWxhdGVkRXZlbnRzOiBidWlsZEV2ZW50QXBpcyhtdXRhdGVkUmVsZXZhbnRFdmVudHMsIHJlY2VpdmluZ0NvbnRleHQsIGFkZGVkRXZlbnRJbnN0YW5jZSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV2ZXJ0KCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWNlaXZpbmdDb250ZXh0LmRpc3BhdGNoKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdSRU1PVkVfRVZFTlRTJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50U3RvcmU6IG11dGF0ZWRSZWxldmFudEV2ZW50cyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgICAgICByZWNlaXZpbmdDb250ZXh0LmVtaXR0ZXIudHJpZ2dlcignZXZlbnRBZGQnLCBldmVudEFkZEFyZyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZXYuaXNUb3VjaCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlY2VpdmluZ0NvbnRleHQuZGlzcGF0Y2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAnU0VMRUNUX0VWRU5UJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnRJbnN0YW5jZUlkOiBldmVudEluc3RhbmNlLmluc3RhbmNlSWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICByZWNlaXZpbmdDb250ZXh0LmVtaXR0ZXIudHJpZ2dlcignZHJvcCcsIE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgYnVpbGREYXRlUG9pbnRBcGlXaXRoQ29udGV4dChmaW5hbEhpdC5kYXRlU3BhbiwgcmVjZWl2aW5nQ29udGV4dCkpLCB7IGRyYWdnZWRFbDogZXYuc3ViamVjdEVsLCBqc0V2ZW50OiBldi5vcmlnRXZlbnQsIHZpZXc6IGZpbmFsSGl0LmNvbnRleHQudmlld0FwaSB9KSk7XG4gICAgICAgICAgICAgICAgICAgICAgICByZWNlaXZpbmdDb250ZXh0LmVtaXR0ZXIudHJpZ2dlcignZXZlbnRSZWNlaXZlJywgT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCBldmVudEFkZEFyZyksIHsgZHJhZ2dlZEVsOiBldi5zdWJqZWN0RWwsIHZpZXc6IGZpbmFsSGl0LmNvbnRleHQudmlld0FwaSB9KSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGluaXRpYWxDb250ZXh0LmVtaXR0ZXIudHJpZ2dlcignX25vRXZlbnREcm9wJyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5jbGVhbnVwKCk7XG4gICAgICAgIH07XG4gICAgICAgIGxldCB7IGNvbXBvbmVudCB9ID0gdGhpcztcbiAgICAgICAgbGV0IHsgb3B0aW9ucyB9ID0gY29tcG9uZW50LmNvbnRleHQ7XG4gICAgICAgIGxldCBkcmFnZ2luZyA9IHRoaXMuZHJhZ2dpbmcgPSBuZXcgRmVhdHVyZWZ1bEVsZW1lbnREcmFnZ2luZyhzZXR0aW5ncy5lbCk7XG4gICAgICAgIGRyYWdnaW5nLnBvaW50ZXIuc2VsZWN0b3IgPSBFdmVudERyYWdnaW5nLlNFTEVDVE9SO1xuICAgICAgICBkcmFnZ2luZy50b3VjaFNjcm9sbEFsbG93ZWQgPSBmYWxzZTtcbiAgICAgICAgZHJhZ2dpbmcuYXV0b1Njcm9sbGVyLmlzRW5hYmxlZCA9IG9wdGlvbnMuZHJhZ1Njcm9sbDtcbiAgICAgICAgbGV0IGhpdERyYWdnaW5nID0gdGhpcy5oaXREcmFnZ2luZyA9IG5ldyBIaXREcmFnZ2luZyh0aGlzLmRyYWdnaW5nLCBpbnRlcmFjdGlvblNldHRpbmdzU3RvcmUpO1xuICAgICAgICBoaXREcmFnZ2luZy51c2VTdWJqZWN0Q2VudGVyID0gc2V0dGluZ3MudXNlRXZlbnRDZW50ZXI7XG4gICAgICAgIGhpdERyYWdnaW5nLmVtaXR0ZXIub24oJ3BvaW50ZXJkb3duJywgdGhpcy5oYW5kbGVQb2ludGVyRG93bik7XG4gICAgICAgIGhpdERyYWdnaW5nLmVtaXR0ZXIub24oJ2RyYWdzdGFydCcsIHRoaXMuaGFuZGxlRHJhZ1N0YXJ0KTtcbiAgICAgICAgaGl0RHJhZ2dpbmcuZW1pdHRlci5vbignaGl0dXBkYXRlJywgdGhpcy5oYW5kbGVIaXRVcGRhdGUpO1xuICAgICAgICBoaXREcmFnZ2luZy5lbWl0dGVyLm9uKCdwb2ludGVydXAnLCB0aGlzLmhhbmRsZVBvaW50ZXJVcCk7XG4gICAgICAgIGhpdERyYWdnaW5nLmVtaXR0ZXIub24oJ2RyYWdlbmQnLCB0aGlzLmhhbmRsZURyYWdFbmQpO1xuICAgIH1cbiAgICBkZXN0cm95KCkge1xuICAgICAgICB0aGlzLmRyYWdnaW5nLmRlc3Ryb3koKTtcbiAgICB9XG4gICAgLy8gcmVuZGVyIGEgZHJhZyBzdGF0ZSBvbiB0aGUgbmV4dCByZWNlaXZpbmdDYWxlbmRhclxuICAgIGRpc3BsYXlEcmFnKG5leHRDb250ZXh0LCBzdGF0ZSkge1xuICAgICAgICBsZXQgaW5pdGlhbENvbnRleHQgPSB0aGlzLmNvbXBvbmVudC5jb250ZXh0O1xuICAgICAgICBsZXQgcHJldkNvbnRleHQgPSB0aGlzLnJlY2VpdmluZ0NvbnRleHQ7XG4gICAgICAgIC8vIGRvZXMgdGhlIHByZXZpb3VzIGNhbGVuZGFyIG5lZWQgdG8gYmUgY2xlYXJlZD9cbiAgICAgICAgaWYgKHByZXZDb250ZXh0ICYmIHByZXZDb250ZXh0ICE9PSBuZXh0Q29udGV4dCkge1xuICAgICAgICAgICAgLy8gZG9lcyB0aGUgaW5pdGlhbCBjYWxlbmRhciBuZWVkIHRvIGJlIGNsZWFyZWQ/XG4gICAgICAgICAgICAvLyBpZiBzbywgZG9uJ3QgY2xlYXIgYWxsIHRoZSB3YXkuIHdlIHN0aWxsIG5lZWQgdG8gdG8gaGlkZSB0aGUgYWZmZWN0ZWRFdmVudHNcbiAgICAgICAgICAgIGlmIChwcmV2Q29udGV4dCA9PT0gaW5pdGlhbENvbnRleHQpIHtcbiAgICAgICAgICAgICAgICBwcmV2Q29udGV4dC5kaXNwYXRjaCh7XG4gICAgICAgICAgICAgICAgICAgIHR5cGU6ICdTRVRfRVZFTlRfRFJBRycsXG4gICAgICAgICAgICAgICAgICAgIHN0YXRlOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhZmZlY3RlZEV2ZW50czogc3RhdGUuYWZmZWN0ZWRFdmVudHMsXG4gICAgICAgICAgICAgICAgICAgICAgICBtdXRhdGVkRXZlbnRzOiBjcmVhdGVFbXB0eUV2ZW50U3RvcmUoKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGlzRXZlbnQ6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgLy8gY29tcGxldGVseSBjbGVhciB0aGUgb2xkIGNhbGVuZGFyIGlmIGl0IHdhc24ndCB0aGUgaW5pdGlhbFxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgcHJldkNvbnRleHQuZGlzcGF0Y2goeyB0eXBlOiAnVU5TRVRfRVZFTlRfRFJBRycgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG5leHRDb250ZXh0KSB7XG4gICAgICAgICAgICBuZXh0Q29udGV4dC5kaXNwYXRjaCh7IHR5cGU6ICdTRVRfRVZFTlRfRFJBRycsIHN0YXRlIH0pO1xuICAgICAgICB9XG4gICAgfVxuICAgIGNsZWFyRHJhZygpIHtcbiAgICAgICAgbGV0IGluaXRpYWxDYWxlbmRhciA9IHRoaXMuY29tcG9uZW50LmNvbnRleHQ7XG4gICAgICAgIGxldCB7IHJlY2VpdmluZ0NvbnRleHQgfSA9IHRoaXM7XG4gICAgICAgIGlmIChyZWNlaXZpbmdDb250ZXh0KSB7XG4gICAgICAgICAgICByZWNlaXZpbmdDb250ZXh0LmRpc3BhdGNoKHsgdHlwZTogJ1VOU0VUX0VWRU5UX0RSQUcnIH0pO1xuICAgICAgICB9XG4gICAgICAgIC8vIHRoZSBpbml0aWFsIGNhbGVuZGFyIG1pZ2h0IGhhdmUgYW4gZHVtbXkgZHJhZyBzdGF0ZSBmcm9tIGRpc3BsYXlEcmFnXG4gICAgICAgIGlmIChpbml0aWFsQ2FsZW5kYXIgIT09IHJlY2VpdmluZ0NvbnRleHQpIHtcbiAgICAgICAgICAgIGluaXRpYWxDYWxlbmRhci5kaXNwYXRjaCh7IHR5cGU6ICdVTlNFVF9FVkVOVF9EUkFHJyB9KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBjbGVhbnVwKCkge1xuICAgICAgICB0aGlzLnN1YmplY3RTZWcgPSBudWxsO1xuICAgICAgICB0aGlzLmlzRHJhZ2dpbmcgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5ldmVudFJhbmdlID0gbnVsbDtcbiAgICAgICAgdGhpcy5yZWxldmFudEV2ZW50cyA9IG51bGw7XG4gICAgICAgIHRoaXMucmVjZWl2aW5nQ29udGV4dCA9IG51bGw7XG4gICAgICAgIHRoaXMudmFsaWRNdXRhdGlvbiA9IG51bGw7XG4gICAgICAgIHRoaXMubXV0YXRlZFJlbGV2YW50RXZlbnRzID0gbnVsbDtcbiAgICB9XG59XG4vLyBUT0RPOiB0ZXN0IHRoaXMgaW4gSUUxMVxuLy8gUVVFU1RJT046IHdoeSBkbyB3ZSBuZWVkIGl0IG9uIHRoZSByZXNpemFibGU/Pz9cbkV2ZW50RHJhZ2dpbmcuU0VMRUNUT1IgPSAnLmZjLWV2ZW50LWRyYWdnYWJsZSwgLmZjLWV2ZW50LXJlc2l6YWJsZSc7XG5mdW5jdGlvbiBjb21wdXRlRXZlbnRNdXRhdGlvbihoaXQwLCBoaXQxLCBtYXNzYWdlcnMpIHtcbiAgICBsZXQgZGF0ZVNwYW4wID0gaGl0MC5kYXRlU3BhbjtcbiAgICBsZXQgZGF0ZVNwYW4xID0gaGl0MS5kYXRlU3BhbjtcbiAgICBsZXQgZGF0ZTAgPSBkYXRlU3BhbjAucmFuZ2Uuc3RhcnQ7XG4gICAgbGV0IGRhdGUxID0gZGF0ZVNwYW4xLnJhbmdlLnN0YXJ0O1xuICAgIGxldCBzdGFuZGFyZFByb3BzID0ge307XG4gICAgaWYgKGRhdGVTcGFuMC5hbGxEYXkgIT09IGRhdGVTcGFuMS5hbGxEYXkpIHtcbiAgICAgICAgc3RhbmRhcmRQcm9wcy5hbGxEYXkgPSBkYXRlU3BhbjEuYWxsRGF5O1xuICAgICAgICBzdGFuZGFyZFByb3BzLmhhc0VuZCA9IGhpdDEuY29udGV4dC5vcHRpb25zLmFsbERheU1haW50YWluRHVyYXRpb247XG4gICAgICAgIGlmIChkYXRlU3BhbjEuYWxsRGF5KSB7XG4gICAgICAgICAgICAvLyBtZWFucyBkYXRlMSBpcyBhbHJlYWR5IHN0YXJ0LW9mLWRheSxcbiAgICAgICAgICAgIC8vIGJ1dCBkYXRlMCBuZWVkcyB0byBiZSBjb252ZXJ0ZWRcbiAgICAgICAgICAgIGRhdGUwID0gc3RhcnRPZkRheShkYXRlMCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgbGV0IGRlbHRhID0gZGlmZkRhdGVzKGRhdGUwLCBkYXRlMSwgaGl0MC5jb250ZXh0LmRhdGVFbnYsIGhpdDAuY29tcG9uZW50SWQgPT09IGhpdDEuY29tcG9uZW50SWQgP1xuICAgICAgICBoaXQwLmxhcmdlVW5pdCA6XG4gICAgICAgIG51bGwpO1xuICAgIGlmIChkZWx0YS5taWxsaXNlY29uZHMpIHsgLy8gaGFzIGhvdXJzL21pbnV0ZXMvc2Vjb25kc1xuICAgICAgICBzdGFuZGFyZFByb3BzLmFsbERheSA9IGZhbHNlO1xuICAgIH1cbiAgICBsZXQgbXV0YXRpb24gPSB7XG4gICAgICAgIGRhdGVzRGVsdGE6IGRlbHRhLFxuICAgICAgICBzdGFuZGFyZFByb3BzLFxuICAgIH07XG4gICAgZm9yIChsZXQgbWFzc2FnZXIgb2YgbWFzc2FnZXJzKSB7XG4gICAgICAgIG1hc3NhZ2VyKG11dGF0aW9uLCBoaXQwLCBoaXQxKTtcbiAgICB9XG4gICAgcmV0dXJuIG11dGF0aW9uO1xufVxuZnVuY3Rpb24gZ2V0Q29tcG9uZW50VG91Y2hEZWxheShjb21wb25lbnQpIHtcbiAgICBsZXQgeyBvcHRpb25zIH0gPSBjb21wb25lbnQuY29udGV4dDtcbiAgICBsZXQgZGVsYXkgPSBvcHRpb25zLmV2ZW50TG9uZ1ByZXNzRGVsYXk7XG4gICAgaWYgKGRlbGF5ID09IG51bGwpIHtcbiAgICAgICAgZGVsYXkgPSBvcHRpb25zLmxvbmdQcmVzc0RlbGF5O1xuICAgIH1cbiAgICByZXR1cm4gZGVsYXk7XG59XG5cbmNsYXNzIEV2ZW50UmVzaXppbmcgZXh0ZW5kcyBJbnRlcmFjdGlvbiB7XG4gICAgY29uc3RydWN0b3Ioc2V0dGluZ3MpIHtcbiAgICAgICAgc3VwZXIoc2V0dGluZ3MpO1xuICAgICAgICAvLyBpbnRlcm5hbCBzdGF0ZVxuICAgICAgICB0aGlzLmRyYWdnaW5nU2VnRWwgPSBudWxsO1xuICAgICAgICB0aGlzLmRyYWdnaW5nU2VnID0gbnVsbDsgLy8gVE9ETzogcmVuYW1lIHRvIHJlc2l6aW5nU2VnPyBzdWJqZWN0U2VnP1xuICAgICAgICB0aGlzLmV2ZW50UmFuZ2UgPSBudWxsO1xuICAgICAgICB0aGlzLnJlbGV2YW50RXZlbnRzID0gbnVsbDtcbiAgICAgICAgdGhpcy52YWxpZE11dGF0aW9uID0gbnVsbDtcbiAgICAgICAgdGhpcy5tdXRhdGVkUmVsZXZhbnRFdmVudHMgPSBudWxsO1xuICAgICAgICB0aGlzLmhhbmRsZVBvaW50ZXJEb3duID0gKGV2KSA9PiB7XG4gICAgICAgICAgICBsZXQgeyBjb21wb25lbnQgfSA9IHRoaXM7XG4gICAgICAgICAgICBsZXQgc2VnRWwgPSB0aGlzLnF1ZXJ5U2VnRWwoZXYpO1xuICAgICAgICAgICAgbGV0IHNlZyA9IGdldEVsU2VnKHNlZ0VsKTtcbiAgICAgICAgICAgIGxldCBldmVudFJhbmdlID0gdGhpcy5ldmVudFJhbmdlID0gc2VnLmV2ZW50UmFuZ2U7XG4gICAgICAgICAgICB0aGlzLmRyYWdnaW5nLm1pbkRpc3RhbmNlID0gY29tcG9uZW50LmNvbnRleHQub3B0aW9ucy5ldmVudERyYWdNaW5EaXN0YW5jZTtcbiAgICAgICAgICAgIC8vIGlmIHRvdWNoLCBuZWVkIHRvIGJlIHdvcmtpbmcgd2l0aCBhIHNlbGVjdGVkIGV2ZW50XG4gICAgICAgICAgICB0aGlzLmRyYWdnaW5nLnNldElnbm9yZU1vdmUoIXRoaXMuY29tcG9uZW50LmlzVmFsaWRTZWdEb3duRWwoZXYub3JpZ0V2ZW50LnRhcmdldCkgfHxcbiAgICAgICAgICAgICAgICAoZXYuaXNUb3VjaCAmJiB0aGlzLmNvbXBvbmVudC5wcm9wcy5ldmVudFNlbGVjdGlvbiAhPT0gZXZlbnRSYW5nZS5pbnN0YW5jZS5pbnN0YW5jZUlkKSk7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuaGFuZGxlRHJhZ1N0YXJ0ID0gKGV2KSA9PiB7XG4gICAgICAgICAgICBsZXQgeyBjb250ZXh0IH0gPSB0aGlzLmNvbXBvbmVudDtcbiAgICAgICAgICAgIGxldCBldmVudFJhbmdlID0gdGhpcy5ldmVudFJhbmdlO1xuICAgICAgICAgICAgdGhpcy5yZWxldmFudEV2ZW50cyA9IGdldFJlbGV2YW50RXZlbnRzKGNvbnRleHQuZ2V0Q3VycmVudERhdGEoKS5ldmVudFN0b3JlLCB0aGlzLmV2ZW50UmFuZ2UuaW5zdGFuY2UuaW5zdGFuY2VJZCk7XG4gICAgICAgICAgICBsZXQgc2VnRWwgPSB0aGlzLnF1ZXJ5U2VnRWwoZXYpO1xuICAgICAgICAgICAgdGhpcy5kcmFnZ2luZ1NlZ0VsID0gc2VnRWw7XG4gICAgICAgICAgICB0aGlzLmRyYWdnaW5nU2VnID0gZ2V0RWxTZWcoc2VnRWwpO1xuICAgICAgICAgICAgY29udGV4dC5jYWxlbmRhckFwaS51bnNlbGVjdCgpO1xuICAgICAgICAgICAgY29udGV4dC5lbWl0dGVyLnRyaWdnZXIoJ2V2ZW50UmVzaXplU3RhcnQnLCB7XG4gICAgICAgICAgICAgICAgZWw6IHNlZ0VsLFxuICAgICAgICAgICAgICAgIGV2ZW50OiBuZXcgRXZlbnRJbXBsKGNvbnRleHQsIGV2ZW50UmFuZ2UuZGVmLCBldmVudFJhbmdlLmluc3RhbmNlKSxcbiAgICAgICAgICAgICAgICBqc0V2ZW50OiBldi5vcmlnRXZlbnQsXG4gICAgICAgICAgICAgICAgdmlldzogY29udGV4dC52aWV3QXBpLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuaGFuZGxlSGl0VXBkYXRlID0gKGhpdCwgaXNGaW5hbCwgZXYpID0+IHtcbiAgICAgICAgICAgIGxldCB7IGNvbnRleHQgfSA9IHRoaXMuY29tcG9uZW50O1xuICAgICAgICAgICAgbGV0IHJlbGV2YW50RXZlbnRzID0gdGhpcy5yZWxldmFudEV2ZW50cztcbiAgICAgICAgICAgIGxldCBpbml0aWFsSGl0ID0gdGhpcy5oaXREcmFnZ2luZy5pbml0aWFsSGl0O1xuICAgICAgICAgICAgbGV0IGV2ZW50SW5zdGFuY2UgPSB0aGlzLmV2ZW50UmFuZ2UuaW5zdGFuY2U7XG4gICAgICAgICAgICBsZXQgbXV0YXRpb24gPSBudWxsO1xuICAgICAgICAgICAgbGV0IG11dGF0ZWRSZWxldmFudEV2ZW50cyA9IG51bGw7XG4gICAgICAgICAgICBsZXQgaXNJbnZhbGlkID0gZmFsc2U7XG4gICAgICAgICAgICBsZXQgaW50ZXJhY3Rpb24gPSB7XG4gICAgICAgICAgICAgICAgYWZmZWN0ZWRFdmVudHM6IHJlbGV2YW50RXZlbnRzLFxuICAgICAgICAgICAgICAgIG11dGF0ZWRFdmVudHM6IGNyZWF0ZUVtcHR5RXZlbnRTdG9yZSgpLFxuICAgICAgICAgICAgICAgIGlzRXZlbnQ6IHRydWUsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaWYgKGhpdCkge1xuICAgICAgICAgICAgICAgIGxldCBkaXNhbGxvd2VkID0gaGl0LmNvbXBvbmVudElkID09PSBpbml0aWFsSGl0LmNvbXBvbmVudElkXG4gICAgICAgICAgICAgICAgICAgICYmIHRoaXMuaXNIaXRDb21ib0FsbG93ZWRcbiAgICAgICAgICAgICAgICAgICAgJiYgIXRoaXMuaXNIaXRDb21ib0FsbG93ZWQoaW5pdGlhbEhpdCwgaGl0KTtcbiAgICAgICAgICAgICAgICBpZiAoIWRpc2FsbG93ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgbXV0YXRpb24gPSBjb21wdXRlTXV0YXRpb24oaW5pdGlhbEhpdCwgaGl0LCBldi5zdWJqZWN0RWwuY2xhc3NMaXN0LmNvbnRhaW5zKCdmYy1ldmVudC1yZXNpemVyLXN0YXJ0JyksIGV2ZW50SW5zdGFuY2UucmFuZ2UpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtdXRhdGlvbikge1xuICAgICAgICAgICAgICAgIG11dGF0ZWRSZWxldmFudEV2ZW50cyA9IGFwcGx5TXV0YXRpb25Ub0V2ZW50U3RvcmUocmVsZXZhbnRFdmVudHMsIGNvbnRleHQuZ2V0Q3VycmVudERhdGEoKS5ldmVudFVpQmFzZXMsIG11dGF0aW9uLCBjb250ZXh0KTtcbiAgICAgICAgICAgICAgICBpbnRlcmFjdGlvbi5tdXRhdGVkRXZlbnRzID0gbXV0YXRlZFJlbGV2YW50RXZlbnRzO1xuICAgICAgICAgICAgICAgIGlmICghaXNJbnRlcmFjdGlvblZhbGlkKGludGVyYWN0aW9uLCBoaXQuZGF0ZVByb2ZpbGUsIGNvbnRleHQpKSB7XG4gICAgICAgICAgICAgICAgICAgIGlzSW52YWxpZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIG11dGF0aW9uID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgbXV0YXRlZFJlbGV2YW50RXZlbnRzID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgaW50ZXJhY3Rpb24ubXV0YXRlZEV2ZW50cyA9IG51bGw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG11dGF0ZWRSZWxldmFudEV2ZW50cykge1xuICAgICAgICAgICAgICAgIGNvbnRleHQuZGlzcGF0Y2goe1xuICAgICAgICAgICAgICAgICAgICB0eXBlOiAnU0VUX0VWRU5UX1JFU0laRScsXG4gICAgICAgICAgICAgICAgICAgIHN0YXRlOiBpbnRlcmFjdGlvbixcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnRleHQuZGlzcGF0Y2goeyB0eXBlOiAnVU5TRVRfRVZFTlRfUkVTSVpFJyB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghaXNJbnZhbGlkKSB7XG4gICAgICAgICAgICAgICAgZW5hYmxlQ3Vyc29yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBkaXNhYmxlQ3Vyc29yKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIWlzRmluYWwpIHtcbiAgICAgICAgICAgICAgICBpZiAobXV0YXRpb24gJiYgaXNIaXRzRXF1YWwoaW5pdGlhbEhpdCwgaGl0KSkge1xuICAgICAgICAgICAgICAgICAgICBtdXRhdGlvbiA9IG51bGw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMudmFsaWRNdXRhdGlvbiA9IG11dGF0aW9uO1xuICAgICAgICAgICAgICAgIHRoaXMubXV0YXRlZFJlbGV2YW50RXZlbnRzID0gbXV0YXRlZFJlbGV2YW50RXZlbnRzO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICB0aGlzLmhhbmRsZURyYWdFbmQgPSAoZXYpID0+IHtcbiAgICAgICAgICAgIGxldCB7IGNvbnRleHQgfSA9IHRoaXMuY29tcG9uZW50O1xuICAgICAgICAgICAgbGV0IGV2ZW50RGVmID0gdGhpcy5ldmVudFJhbmdlLmRlZjtcbiAgICAgICAgICAgIGxldCBldmVudEluc3RhbmNlID0gdGhpcy5ldmVudFJhbmdlLmluc3RhbmNlO1xuICAgICAgICAgICAgbGV0IGV2ZW50QXBpID0gbmV3IEV2ZW50SW1wbChjb250ZXh0LCBldmVudERlZiwgZXZlbnRJbnN0YW5jZSk7XG4gICAgICAgICAgICBsZXQgcmVsZXZhbnRFdmVudHMgPSB0aGlzLnJlbGV2YW50RXZlbnRzO1xuICAgICAgICAgICAgbGV0IG11dGF0ZWRSZWxldmFudEV2ZW50cyA9IHRoaXMubXV0YXRlZFJlbGV2YW50RXZlbnRzO1xuICAgICAgICAgICAgY29udGV4dC5lbWl0dGVyLnRyaWdnZXIoJ2V2ZW50UmVzaXplU3RvcCcsIHtcbiAgICAgICAgICAgICAgICBlbDogdGhpcy5kcmFnZ2luZ1NlZ0VsLFxuICAgICAgICAgICAgICAgIGV2ZW50OiBldmVudEFwaSxcbiAgICAgICAgICAgICAgICBqc0V2ZW50OiBldi5vcmlnRXZlbnQsXG4gICAgICAgICAgICAgICAgdmlldzogY29udGV4dC52aWV3QXBpLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBpZiAodGhpcy52YWxpZE11dGF0aW9uKSB7XG4gICAgICAgICAgICAgICAgbGV0IHVwZGF0ZWRFdmVudEFwaSA9IG5ldyBFdmVudEltcGwoY29udGV4dCwgbXV0YXRlZFJlbGV2YW50RXZlbnRzLmRlZnNbZXZlbnREZWYuZGVmSWRdLCBldmVudEluc3RhbmNlID8gbXV0YXRlZFJlbGV2YW50RXZlbnRzLmluc3RhbmNlc1tldmVudEluc3RhbmNlLmluc3RhbmNlSWRdIDogbnVsbCk7XG4gICAgICAgICAgICAgICAgY29udGV4dC5kaXNwYXRjaCh7XG4gICAgICAgICAgICAgICAgICAgIHR5cGU6ICdNRVJHRV9FVkVOVFMnLFxuICAgICAgICAgICAgICAgICAgICBldmVudFN0b3JlOiBtdXRhdGVkUmVsZXZhbnRFdmVudHMsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgbGV0IGV2ZW50Q2hhbmdlQXJnID0ge1xuICAgICAgICAgICAgICAgICAgICBvbGRFdmVudDogZXZlbnRBcGksXG4gICAgICAgICAgICAgICAgICAgIGV2ZW50OiB1cGRhdGVkRXZlbnRBcGksXG4gICAgICAgICAgICAgICAgICAgIHJlbGF0ZWRFdmVudHM6IGJ1aWxkRXZlbnRBcGlzKG11dGF0ZWRSZWxldmFudEV2ZW50cywgY29udGV4dCwgZXZlbnRJbnN0YW5jZSksXG4gICAgICAgICAgICAgICAgICAgIHJldmVydCgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQuZGlzcGF0Y2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdNRVJHRV9FVkVOVFMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50U3RvcmU6IHJlbGV2YW50RXZlbnRzLCAvLyB0aGUgcHJlLWNoYW5nZSBldmVudHNcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgY29udGV4dC5lbWl0dGVyLnRyaWdnZXIoJ2V2ZW50UmVzaXplJywgT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCBldmVudENoYW5nZUFyZyksIHsgZWw6IHRoaXMuZHJhZ2dpbmdTZWdFbCwgc3RhcnREZWx0YTogdGhpcy52YWxpZE11dGF0aW9uLnN0YXJ0RGVsdGEgfHwgY3JlYXRlRHVyYXRpb24oMCksIGVuZERlbHRhOiB0aGlzLnZhbGlkTXV0YXRpb24uZW5kRGVsdGEgfHwgY3JlYXRlRHVyYXRpb24oMCksIGpzRXZlbnQ6IGV2Lm9yaWdFdmVudCwgdmlldzogY29udGV4dC52aWV3QXBpIH0pKTtcbiAgICAgICAgICAgICAgICBjb250ZXh0LmVtaXR0ZXIudHJpZ2dlcignZXZlbnRDaGFuZ2UnLCBldmVudENoYW5nZUFyZyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBjb250ZXh0LmVtaXR0ZXIudHJpZ2dlcignX25vRXZlbnRSZXNpemUnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIHJlc2V0IGFsbCBpbnRlcm5hbCBzdGF0ZVxuICAgICAgICAgICAgdGhpcy5kcmFnZ2luZ1NlZyA9IG51bGw7XG4gICAgICAgICAgICB0aGlzLnJlbGV2YW50RXZlbnRzID0gbnVsbDtcbiAgICAgICAgICAgIHRoaXMudmFsaWRNdXRhdGlvbiA9IG51bGw7XG4gICAgICAgICAgICAvLyBva2F5IHRvIGtlZXAgZXZlbnRJbnN0YW5jZSBhcm91bmQuIHVzZWZ1bCB0byBzZXQgaXQgaW4gaGFuZGxlUG9pbnRlckRvd25cbiAgICAgICAgfTtcbiAgICAgICAgbGV0IHsgY29tcG9uZW50IH0gPSBzZXR0aW5ncztcbiAgICAgICAgbGV0IGRyYWdnaW5nID0gdGhpcy5kcmFnZ2luZyA9IG5ldyBGZWF0dXJlZnVsRWxlbWVudERyYWdnaW5nKHNldHRpbmdzLmVsKTtcbiAgICAgICAgZHJhZ2dpbmcucG9pbnRlci5zZWxlY3RvciA9ICcuZmMtZXZlbnQtcmVzaXplcic7XG4gICAgICAgIGRyYWdnaW5nLnRvdWNoU2Nyb2xsQWxsb3dlZCA9IGZhbHNlO1xuICAgICAgICBkcmFnZ2luZy5hdXRvU2Nyb2xsZXIuaXNFbmFibGVkID0gY29tcG9uZW50LmNvbnRleHQub3B0aW9ucy5kcmFnU2Nyb2xsO1xuICAgICAgICBsZXQgaGl0RHJhZ2dpbmcgPSB0aGlzLmhpdERyYWdnaW5nID0gbmV3IEhpdERyYWdnaW5nKHRoaXMuZHJhZ2dpbmcsIGludGVyYWN0aW9uU2V0dGluZ3NUb1N0b3JlKHNldHRpbmdzKSk7XG4gICAgICAgIGhpdERyYWdnaW5nLmVtaXR0ZXIub24oJ3BvaW50ZXJkb3duJywgdGhpcy5oYW5kbGVQb2ludGVyRG93bik7XG4gICAgICAgIGhpdERyYWdnaW5nLmVtaXR0ZXIub24oJ2RyYWdzdGFydCcsIHRoaXMuaGFuZGxlRHJhZ1N0YXJ0KTtcbiAgICAgICAgaGl0RHJhZ2dpbmcuZW1pdHRlci5vbignaGl0dXBkYXRlJywgdGhpcy5oYW5kbGVIaXRVcGRhdGUpO1xuICAgICAgICBoaXREcmFnZ2luZy5lbWl0dGVyLm9uKCdkcmFnZW5kJywgdGhpcy5oYW5kbGVEcmFnRW5kKTtcbiAgICB9XG4gICAgZGVzdHJveSgpIHtcbiAgICAgICAgdGhpcy5kcmFnZ2luZy5kZXN0cm95KCk7XG4gICAgfVxuICAgIHF1ZXJ5U2VnRWwoZXYpIHtcbiAgICAgICAgcmV0dXJuIGVsZW1lbnRDbG9zZXN0KGV2LnN1YmplY3RFbCwgJy5mYy1ldmVudCcpO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGNvbXB1dGVNdXRhdGlvbihoaXQwLCBoaXQxLCBpc0Zyb21TdGFydCwgaW5zdGFuY2VSYW5nZSkge1xuICAgIGxldCBkYXRlRW52ID0gaGl0MC5jb250ZXh0LmRhdGVFbnY7XG4gICAgbGV0IGRhdGUwID0gaGl0MC5kYXRlU3Bhbi5yYW5nZS5zdGFydDtcbiAgICBsZXQgZGF0ZTEgPSBoaXQxLmRhdGVTcGFuLnJhbmdlLnN0YXJ0O1xuICAgIGxldCBkZWx0YSA9IGRpZmZEYXRlcyhkYXRlMCwgZGF0ZTEsIGRhdGVFbnYsIGhpdDAubGFyZ2VVbml0KTtcbiAgICBpZiAoaXNGcm9tU3RhcnQpIHtcbiAgICAgICAgaWYgKGRhdGVFbnYuYWRkKGluc3RhbmNlUmFuZ2Uuc3RhcnQsIGRlbHRhKSA8IGluc3RhbmNlUmFuZ2UuZW5kKSB7XG4gICAgICAgICAgICByZXR1cm4geyBzdGFydERlbHRhOiBkZWx0YSB9O1xuICAgICAgICB9XG4gICAgfVxuICAgIGVsc2UgaWYgKGRhdGVFbnYuYWRkKGluc3RhbmNlUmFuZ2UuZW5kLCBkZWx0YSkgPiBpbnN0YW5jZVJhbmdlLnN0YXJ0KSB7XG4gICAgICAgIHJldHVybiB7IGVuZERlbHRhOiBkZWx0YSB9O1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbn1cblxuY2xhc3MgVW5zZWxlY3RBdXRvIHtcbiAgICBjb25zdHJ1Y3Rvcihjb250ZXh0KSB7XG4gICAgICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHQ7XG4gICAgICAgIHRoaXMuaXNSZWNlbnRQb2ludGVyRGF0ZVNlbGVjdCA9IGZhbHNlOyAvLyB3aXNoIHdlIGNvdWxkIHVzZSBhIHNlbGVjdG9yIHRvIGRldGVjdCBkYXRlIHNlbGVjdGlvbiwgYnV0IHVzZXMgaGl0IHN5c3RlbVxuICAgICAgICB0aGlzLm1hdGNoZXNDYW5jZWwgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5tYXRjaGVzRXZlbnQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5vblNlbGVjdCA9IChzZWxlY3RJbmZvKSA9PiB7XG4gICAgICAgICAgICBpZiAoc2VsZWN0SW5mby5qc0V2ZW50KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pc1JlY2VudFBvaW50ZXJEYXRlU2VsZWN0ID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5vbkRvY3VtZW50UG9pbnRlckRvd24gPSAocGV2KSA9PiB7XG4gICAgICAgICAgICBsZXQgdW5zZWxlY3RDYW5jZWwgPSB0aGlzLmNvbnRleHQub3B0aW9ucy51bnNlbGVjdENhbmNlbDtcbiAgICAgICAgICAgIGxldCBkb3duRWwgPSBnZXRFdmVudFRhcmdldFZpYVJvb3QocGV2Lm9yaWdFdmVudCk7XG4gICAgICAgICAgICB0aGlzLm1hdGNoZXNDYW5jZWwgPSAhIWVsZW1lbnRDbG9zZXN0KGRvd25FbCwgdW5zZWxlY3RDYW5jZWwpO1xuICAgICAgICAgICAgdGhpcy5tYXRjaGVzRXZlbnQgPSAhIWVsZW1lbnRDbG9zZXN0KGRvd25FbCwgRXZlbnREcmFnZ2luZy5TRUxFQ1RPUik7IC8vIGludGVyYWN0aW9uIHN0YXJ0ZWQgb24gYW4gZXZlbnQ/XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMub25Eb2N1bWVudFBvaW50ZXJVcCA9IChwZXYpID0+IHtcbiAgICAgICAgICAgIGxldCB7IGNvbnRleHQgfSA9IHRoaXM7XG4gICAgICAgICAgICBsZXQgeyBkb2N1bWVudFBvaW50ZXIgfSA9IHRoaXM7XG4gICAgICAgICAgICBsZXQgY2FsZW5kYXJTdGF0ZSA9IGNvbnRleHQuZ2V0Q3VycmVudERhdGEoKTtcbiAgICAgICAgICAgIC8vIHRvdWNoLXNjcm9sbGluZyBzaG91bGQgbmV2ZXIgdW5mb2N1cyBhbnkgdHlwZSBvZiBzZWxlY3Rpb25cbiAgICAgICAgICAgIGlmICghZG9jdW1lbnRQb2ludGVyLndhc1RvdWNoU2Nyb2xsKSB7XG4gICAgICAgICAgICAgICAgaWYgKGNhbGVuZGFyU3RhdGUuZGF0ZVNlbGVjdGlvbiAmJiAvLyBhbiBleGlzdGluZyBkYXRlIHNlbGVjdGlvbj9cbiAgICAgICAgICAgICAgICAgICAgIXRoaXMuaXNSZWNlbnRQb2ludGVyRGF0ZVNlbGVjdCAvLyBhIG5ldyBwb2ludGVyLWluaXRpYXRlZCBkYXRlIHNlbGVjdGlvbiBzaW5jZSBsYXN0IG9uRG9jdW1lbnRQb2ludGVyVXA/XG4gICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCB1bnNlbGVjdEF1dG8gPSBjb250ZXh0Lm9wdGlvbnMudW5zZWxlY3RBdXRvO1xuICAgICAgICAgICAgICAgICAgICBpZiAodW5zZWxlY3RBdXRvICYmICghdW5zZWxlY3RBdXRvIHx8ICF0aGlzLm1hdGNoZXNDYW5jZWwpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0LmNhbGVuZGFyQXBpLnVuc2VsZWN0KHBldik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGNhbGVuZGFyU3RhdGUuZXZlbnRTZWxlY3Rpb24gJiYgLy8gYW4gZXhpc3RpbmcgZXZlbnQgc2VsZWN0ZWQ/XG4gICAgICAgICAgICAgICAgICAgICF0aGlzLm1hdGNoZXNFdmVudCAvLyBpbnRlcmFjdGlvbiBESUROJ1Qgc3RhcnQgb24gYW4gZXZlbnRcbiAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgICAgY29udGV4dC5kaXNwYXRjaCh7IHR5cGU6ICdVTlNFTEVDVF9FVkVOVCcgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5pc1JlY2VudFBvaW50ZXJEYXRlU2VsZWN0ID0gZmFsc2U7XG4gICAgICAgIH07XG4gICAgICAgIGxldCBkb2N1bWVudFBvaW50ZXIgPSB0aGlzLmRvY3VtZW50UG9pbnRlciA9IG5ldyBQb2ludGVyRHJhZ2dpbmcoZG9jdW1lbnQpO1xuICAgICAgICBkb2N1bWVudFBvaW50ZXIuc2hvdWxkSWdub3JlTW92ZSA9IHRydWU7XG4gICAgICAgIGRvY3VtZW50UG9pbnRlci5zaG91bGRXYXRjaFNjcm9sbCA9IGZhbHNlO1xuICAgICAgICBkb2N1bWVudFBvaW50ZXIuZW1pdHRlci5vbigncG9pbnRlcmRvd24nLCB0aGlzLm9uRG9jdW1lbnRQb2ludGVyRG93bik7XG4gICAgICAgIGRvY3VtZW50UG9pbnRlci5lbWl0dGVyLm9uKCdwb2ludGVydXAnLCB0aGlzLm9uRG9jdW1lbnRQb2ludGVyVXApO1xuICAgICAgICAvKlxuICAgICAgICBUT0RPOiBiZXR0ZXIgd2F5IHRvIGtub3cgYWJvdXQgd2hldGhlciB0aGVyZSB3YXMgYSBzZWxlY3Rpb24gd2l0aCB0aGUgcG9pbnRlclxuICAgICAgICAqL1xuICAgICAgICBjb250ZXh0LmVtaXR0ZXIub24oJ3NlbGVjdCcsIHRoaXMub25TZWxlY3QpO1xuICAgIH1cbiAgICBkZXN0cm95KCkge1xuICAgICAgICB0aGlzLmNvbnRleHQuZW1pdHRlci5vZmYoJ3NlbGVjdCcsIHRoaXMub25TZWxlY3QpO1xuICAgICAgICB0aGlzLmRvY3VtZW50UG9pbnRlci5kZXN0cm95KCk7XG4gICAgfVxufVxuXG5jb25zdCBPUFRJT05fUkVGSU5FUlMgPSB7XG4gICAgZml4ZWRNaXJyb3JQYXJlbnQ6IGlkZW50aXR5LFxufTtcbmNvbnN0IExJU1RFTkVSX1JFRklORVJTID0ge1xuICAgIGRhdGVDbGljazogaWRlbnRpdHksXG4gICAgZXZlbnREcmFnU3RhcnQ6IGlkZW50aXR5LFxuICAgIGV2ZW50RHJhZ1N0b3A6IGlkZW50aXR5LFxuICAgIGV2ZW50RHJvcDogaWRlbnRpdHksXG4gICAgZXZlbnRSZXNpemVTdGFydDogaWRlbnRpdHksXG4gICAgZXZlbnRSZXNpemVTdG9wOiBpZGVudGl0eSxcbiAgICBldmVudFJlc2l6ZTogaWRlbnRpdHksXG4gICAgZHJvcDogaWRlbnRpdHksXG4gICAgZXZlbnRSZWNlaXZlOiBpZGVudGl0eSxcbiAgICBldmVudExlYXZlOiBpZGVudGl0eSxcbn07XG5cbi8qXG5HaXZlbiBhbiBhbHJlYWR5IGluc3RhbnRpYXRlZCBkcmFnZ2FibGUgb2JqZWN0IGZvciBvbmUtb3ItbW9yZSBlbGVtZW50cyxcbkludGVycHJldHMgYW55IGRyYWdnaW5nIGFzIGFuIGF0dGVtcHQgdG8gZHJhZyBhbiBldmVudHMgdGhhdCBsaXZlcyBvdXRzaWRlXG5vZiBhIGNhbGVuZGFyIG9udG8gYSBjYWxlbmRhci5cbiovXG5jbGFzcyBFeHRlcm5hbEVsZW1lbnREcmFnZ2luZyB7XG4gICAgY29uc3RydWN0b3IoZHJhZ2dpbmcsIHN1cHBsaWVkRHJhZ01ldGEpIHtcbiAgICAgICAgdGhpcy5yZWNlaXZpbmdDb250ZXh0ID0gbnVsbDtcbiAgICAgICAgdGhpcy5kcm9wcGFibGVFdmVudCA9IG51bGw7IC8vIHdpbGwgZXhpc3QgZm9yIGFsbCBkcmFncywgZXZlbiBpZiBjcmVhdGU6ZmFsc2VcbiAgICAgICAgdGhpcy5zdXBwbGllZERyYWdNZXRhID0gbnVsbDtcbiAgICAgICAgdGhpcy5kcmFnTWV0YSA9IG51bGw7XG4gICAgICAgIHRoaXMuaGFuZGxlRHJhZ1N0YXJ0ID0gKGV2KSA9PiB7XG4gICAgICAgICAgICB0aGlzLmRyYWdNZXRhID0gdGhpcy5idWlsZERyYWdNZXRhKGV2LnN1YmplY3RFbCk7XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuaGFuZGxlSGl0VXBkYXRlID0gKGhpdCwgaXNGaW5hbCwgZXYpID0+IHtcbiAgICAgICAgICAgIGxldCB7IGRyYWdnaW5nIH0gPSB0aGlzLmhpdERyYWdnaW5nO1xuICAgICAgICAgICAgbGV0IHJlY2VpdmluZ0NvbnRleHQgPSBudWxsO1xuICAgICAgICAgICAgbGV0IGRyb3BwYWJsZUV2ZW50ID0gbnVsbDtcbiAgICAgICAgICAgIGxldCBpc0ludmFsaWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGxldCBpbnRlcmFjdGlvbiA9IHtcbiAgICAgICAgICAgICAgICBhZmZlY3RlZEV2ZW50czogY3JlYXRlRW1wdHlFdmVudFN0b3JlKCksXG4gICAgICAgICAgICAgICAgbXV0YXRlZEV2ZW50czogY3JlYXRlRW1wdHlFdmVudFN0b3JlKCksXG4gICAgICAgICAgICAgICAgaXNFdmVudDogdGhpcy5kcmFnTWV0YS5jcmVhdGUsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgaWYgKGhpdCkge1xuICAgICAgICAgICAgICAgIHJlY2VpdmluZ0NvbnRleHQgPSBoaXQuY29udGV4dDtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5jYW5Ecm9wRWxPbkNhbGVuZGFyKGV2LnN1YmplY3RFbCwgcmVjZWl2aW5nQ29udGV4dCkpIHtcbiAgICAgICAgICAgICAgICAgICAgZHJvcHBhYmxlRXZlbnQgPSBjb21wdXRlRXZlbnRGb3JEYXRlU3BhbihoaXQuZGF0ZVNwYW4sIHRoaXMuZHJhZ01ldGEsIHJlY2VpdmluZ0NvbnRleHQpO1xuICAgICAgICAgICAgICAgICAgICBpbnRlcmFjdGlvbi5tdXRhdGVkRXZlbnRzID0gZXZlbnRUdXBsZVRvU3RvcmUoZHJvcHBhYmxlRXZlbnQpO1xuICAgICAgICAgICAgICAgICAgICBpc0ludmFsaWQgPSAhaXNJbnRlcmFjdGlvblZhbGlkKGludGVyYWN0aW9uLCBoaXQuZGF0ZVByb2ZpbGUsIHJlY2VpdmluZ0NvbnRleHQpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNJbnZhbGlkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpbnRlcmFjdGlvbi5tdXRhdGVkRXZlbnRzID0gY3JlYXRlRW1wdHlFdmVudFN0b3JlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBkcm9wcGFibGVFdmVudCA9IG51bGw7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmRpc3BsYXlEcmFnKHJlY2VpdmluZ0NvbnRleHQsIGludGVyYWN0aW9uKTtcbiAgICAgICAgICAgIC8vIHNob3cgbWlycm9yIGlmIG5vIGFscmVhZHktcmVuZGVyZWQgbWlycm9yIGVsZW1lbnQgT1IgaWYgd2UgYXJlIHNodXR0aW5nIGRvd24gdGhlIG1pcnJvciAoPylcbiAgICAgICAgICAgIC8vIFRPRE86IHdpc2ggd2UgY291bGQgc29tZWhvdyB3YWl0IGZvciBkaXNwYXRjaCB0byBndWFyYW50ZWUgcmVuZGVyXG4gICAgICAgICAgICBkcmFnZ2luZy5zZXRNaXJyb3JJc1Zpc2libGUoaXNGaW5hbCB8fCAhZHJvcHBhYmxlRXZlbnQgfHwgIWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5mYy1ldmVudC1taXJyb3InKSk7XG4gICAgICAgICAgICBpZiAoIWlzSW52YWxpZCkge1xuICAgICAgICAgICAgICAgIGVuYWJsZUN1cnNvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgZGlzYWJsZUN1cnNvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFpc0ZpbmFsKSB7XG4gICAgICAgICAgICAgICAgZHJhZ2dpbmcuc2V0TWlycm9yTmVlZHNSZXZlcnQoIWRyb3BwYWJsZUV2ZW50KTtcbiAgICAgICAgICAgICAgICB0aGlzLnJlY2VpdmluZ0NvbnRleHQgPSByZWNlaXZpbmdDb250ZXh0O1xuICAgICAgICAgICAgICAgIHRoaXMuZHJvcHBhYmxlRXZlbnQgPSBkcm9wcGFibGVFdmVudDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5oYW5kbGVEcmFnRW5kID0gKHBldikgPT4ge1xuICAgICAgICAgICAgbGV0IHsgcmVjZWl2aW5nQ29udGV4dCwgZHJvcHBhYmxlRXZlbnQgfSA9IHRoaXM7XG4gICAgICAgICAgICB0aGlzLmNsZWFyRHJhZygpO1xuICAgICAgICAgICAgaWYgKHJlY2VpdmluZ0NvbnRleHQgJiYgZHJvcHBhYmxlRXZlbnQpIHtcbiAgICAgICAgICAgICAgICBsZXQgZmluYWxIaXQgPSB0aGlzLmhpdERyYWdnaW5nLmZpbmFsSGl0O1xuICAgICAgICAgICAgICAgIGxldCBmaW5hbFZpZXcgPSBmaW5hbEhpdC5jb250ZXh0LnZpZXdBcGk7XG4gICAgICAgICAgICAgICAgbGV0IGRyYWdNZXRhID0gdGhpcy5kcmFnTWV0YTtcbiAgICAgICAgICAgICAgICByZWNlaXZpbmdDb250ZXh0LmVtaXR0ZXIudHJpZ2dlcignZHJvcCcsIE9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSwgYnVpbGREYXRlUG9pbnRBcGlXaXRoQ29udGV4dChmaW5hbEhpdC5kYXRlU3BhbiwgcmVjZWl2aW5nQ29udGV4dCkpLCB7IGRyYWdnZWRFbDogcGV2LnN1YmplY3RFbCwganNFdmVudDogcGV2Lm9yaWdFdmVudCwgdmlldzogZmluYWxWaWV3IH0pKTtcbiAgICAgICAgICAgICAgICBpZiAoZHJhZ01ldGEuY3JlYXRlKSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCBhZGRpbmdFdmVudHMgPSBldmVudFR1cGxlVG9TdG9yZShkcm9wcGFibGVFdmVudCk7XG4gICAgICAgICAgICAgICAgICAgIHJlY2VpdmluZ0NvbnRleHQuZGlzcGF0Y2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ01FUkdFX0VWRU5UUycsXG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudFN0b3JlOiBhZGRpbmdFdmVudHMsXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBpZiAocGV2LmlzVG91Y2gpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlY2VpdmluZ0NvbnRleHQuZGlzcGF0Y2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdTRUxFQ1RfRVZFTlQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50SW5zdGFuY2VJZDogZHJvcHBhYmxlRXZlbnQuaW5zdGFuY2UuaW5zdGFuY2VJZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIC8vIHNpZ25hbCB0aGF0IGFuIGV4dGVybmFsIGV2ZW50IGxhbmRlZFxuICAgICAgICAgICAgICAgICAgICByZWNlaXZpbmdDb250ZXh0LmVtaXR0ZXIudHJpZ2dlcignZXZlbnRSZWNlaXZlJywge1xuICAgICAgICAgICAgICAgICAgICAgICAgZXZlbnQ6IG5ldyBFdmVudEltcGwocmVjZWl2aW5nQ29udGV4dCwgZHJvcHBhYmxlRXZlbnQuZGVmLCBkcm9wcGFibGVFdmVudC5pbnN0YW5jZSksXG4gICAgICAgICAgICAgICAgICAgICAgICByZWxhdGVkRXZlbnRzOiBbXSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldmVydCgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWNlaXZpbmdDb250ZXh0LmRpc3BhdGNoKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ1JFTU9WRV9FVkVOVFMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudFN0b3JlOiBhZGRpbmdFdmVudHMsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgZHJhZ2dlZEVsOiBwZXYuc3ViamVjdEVsLFxuICAgICAgICAgICAgICAgICAgICAgICAgdmlldzogZmluYWxWaWV3LFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnJlY2VpdmluZ0NvbnRleHQgPSBudWxsO1xuICAgICAgICAgICAgdGhpcy5kcm9wcGFibGVFdmVudCA9IG51bGw7XG4gICAgICAgIH07XG4gICAgICAgIGxldCBoaXREcmFnZ2luZyA9IHRoaXMuaGl0RHJhZ2dpbmcgPSBuZXcgSGl0RHJhZ2dpbmcoZHJhZ2dpbmcsIGludGVyYWN0aW9uU2V0dGluZ3NTdG9yZSk7XG4gICAgICAgIGhpdERyYWdnaW5nLnJlcXVpcmVJbml0aWFsID0gZmFsc2U7IC8vIHdpbGwgc3RhcnQgb3V0c2lkZSBvZiBhIGNvbXBvbmVudFxuICAgICAgICBoaXREcmFnZ2luZy5lbWl0dGVyLm9uKCdkcmFnc3RhcnQnLCB0aGlzLmhhbmRsZURyYWdTdGFydCk7XG4gICAgICAgIGhpdERyYWdnaW5nLmVtaXR0ZXIub24oJ2hpdHVwZGF0ZScsIHRoaXMuaGFuZGxlSGl0VXBkYXRlKTtcbiAgICAgICAgaGl0RHJhZ2dpbmcuZW1pdHRlci5vbignZHJhZ2VuZCcsIHRoaXMuaGFuZGxlRHJhZ0VuZCk7XG4gICAgICAgIHRoaXMuc3VwcGxpZWREcmFnTWV0YSA9IHN1cHBsaWVkRHJhZ01ldGE7XG4gICAgfVxuICAgIGJ1aWxkRHJhZ01ldGEoc3ViamVjdEVsKSB7XG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5zdXBwbGllZERyYWdNZXRhID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgcmV0dXJuIHBhcnNlRHJhZ01ldGEodGhpcy5zdXBwbGllZERyYWdNZXRhKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIHRoaXMuc3VwcGxpZWREcmFnTWV0YSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgcmV0dXJuIHBhcnNlRHJhZ01ldGEodGhpcy5zdXBwbGllZERyYWdNZXRhKHN1YmplY3RFbCkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBnZXREcmFnTWV0YUZyb21FbChzdWJqZWN0RWwpO1xuICAgIH1cbiAgICBkaXNwbGF5RHJhZyhuZXh0Q29udGV4dCwgc3RhdGUpIHtcbiAgICAgICAgbGV0IHByZXZDb250ZXh0ID0gdGhpcy5yZWNlaXZpbmdDb250ZXh0O1xuICAgICAgICBpZiAocHJldkNvbnRleHQgJiYgcHJldkNvbnRleHQgIT09IG5leHRDb250ZXh0KSB7XG4gICAgICAgICAgICBwcmV2Q29udGV4dC5kaXNwYXRjaCh7IHR5cGU6ICdVTlNFVF9FVkVOVF9EUkFHJyB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobmV4dENvbnRleHQpIHtcbiAgICAgICAgICAgIG5leHRDb250ZXh0LmRpc3BhdGNoKHsgdHlwZTogJ1NFVF9FVkVOVF9EUkFHJywgc3RhdGUgfSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgY2xlYXJEcmFnKCkge1xuICAgICAgICBpZiAodGhpcy5yZWNlaXZpbmdDb250ZXh0KSB7XG4gICAgICAgICAgICB0aGlzLnJlY2VpdmluZ0NvbnRleHQuZGlzcGF0Y2goeyB0eXBlOiAnVU5TRVRfRVZFTlRfRFJBRycgfSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgY2FuRHJvcEVsT25DYWxlbmRhcihlbCwgcmVjZWl2aW5nQ29udGV4dCkge1xuICAgICAgICBsZXQgZHJvcEFjY2VwdCA9IHJlY2VpdmluZ0NvbnRleHQub3B0aW9ucy5kcm9wQWNjZXB0O1xuICAgICAgICBpZiAodHlwZW9mIGRyb3BBY2NlcHQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHJldHVybiBkcm9wQWNjZXB0LmNhbGwocmVjZWl2aW5nQ29udGV4dC5jYWxlbmRhckFwaSwgZWwpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgZHJvcEFjY2VwdCA9PT0gJ3N0cmluZycgJiYgZHJvcEFjY2VwdCkge1xuICAgICAgICAgICAgcmV0dXJuIEJvb2xlYW4oZWxlbWVudE1hdGNoZXMoZWwsIGRyb3BBY2NlcHQpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG59XG4vLyBVdGlscyBmb3IgY29tcHV0aW5nIGV2ZW50IHN0b3JlIGZyb20gdGhlIERyYWdNZXRhXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5mdW5jdGlvbiBjb21wdXRlRXZlbnRGb3JEYXRlU3BhbihkYXRlU3BhbiwgZHJhZ01ldGEsIGNvbnRleHQpIHtcbiAgICBsZXQgZGVmUHJvcHMgPSBPYmplY3QuYXNzaWduKHt9LCBkcmFnTWV0YS5sZWZ0b3ZlclByb3BzKTtcbiAgICBmb3IgKGxldCB0cmFuc2Zvcm0gb2YgY29udGV4dC5wbHVnaW5Ib29rcy5leHRlcm5hbERlZlRyYW5zZm9ybXMpIHtcbiAgICAgICAgT2JqZWN0LmFzc2lnbihkZWZQcm9wcywgdHJhbnNmb3JtKGRhdGVTcGFuLCBkcmFnTWV0YSkpO1xuICAgIH1cbiAgICBsZXQgeyByZWZpbmVkLCBleHRyYSB9ID0gcmVmaW5lRXZlbnREZWYoZGVmUHJvcHMsIGNvbnRleHQpO1xuICAgIGxldCBkZWYgPSBwYXJzZUV2ZW50RGVmKHJlZmluZWQsIGV4dHJhLCBkcmFnTWV0YS5zb3VyY2VJZCwgZGF0ZVNwYW4uYWxsRGF5LCBjb250ZXh0Lm9wdGlvbnMuZm9yY2VFdmVudER1cmF0aW9uIHx8IEJvb2xlYW4oZHJhZ01ldGEuZHVyYXRpb24pLCAvLyBoYXNFbmRcbiAgICBjb250ZXh0KTtcbiAgICBsZXQgc3RhcnQgPSBkYXRlU3Bhbi5yYW5nZS5zdGFydDtcbiAgICAvLyBvbmx5IHJlbHkgb24gdGltZSBpbmZvIGlmIGRyb3Agem9uZSBpcyBhbGwtZGF5LFxuICAgIC8vIG90aGVyd2lzZSwgd2UgYWxyZWFkeSBrbm93IHRoZSB0aW1lXG4gICAgaWYgKGRhdGVTcGFuLmFsbERheSAmJiBkcmFnTWV0YS5zdGFydFRpbWUpIHtcbiAgICAgICAgc3RhcnQgPSBjb250ZXh0LmRhdGVFbnYuYWRkKHN0YXJ0LCBkcmFnTWV0YS5zdGFydFRpbWUpO1xuICAgIH1cbiAgICBsZXQgZW5kID0gZHJhZ01ldGEuZHVyYXRpb24gP1xuICAgICAgICBjb250ZXh0LmRhdGVFbnYuYWRkKHN0YXJ0LCBkcmFnTWV0YS5kdXJhdGlvbikgOlxuICAgICAgICBnZXREZWZhdWx0RXZlbnRFbmQoZGF0ZVNwYW4uYWxsRGF5LCBzdGFydCwgY29udGV4dCk7XG4gICAgbGV0IGluc3RhbmNlID0gY3JlYXRlRXZlbnRJbnN0YW5jZShkZWYuZGVmSWQsIHsgc3RhcnQsIGVuZCB9KTtcbiAgICByZXR1cm4geyBkZWYsIGluc3RhbmNlIH07XG59XG4vLyBVdGlscyBmb3IgZXh0cmFjdGluZyBkYXRhIGZyb20gZWxlbWVudFxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuZnVuY3Rpb24gZ2V0RHJhZ01ldGFGcm9tRWwoZWwpIHtcbiAgICBsZXQgc3RyID0gZ2V0RW1iZWRkZWRFbERhdGEoZWwsICdldmVudCcpO1xuICAgIGxldCBvYmogPSBzdHIgP1xuICAgICAgICBKU09OLnBhcnNlKHN0cikgOlxuICAgICAgICB7IGNyZWF0ZTogZmFsc2UgfTsgLy8gaWYgbm8gZW1iZWRkZWQgZGF0YSwgYXNzdW1lIG5vIGV2ZW50IGNyZWF0aW9uXG4gICAgcmV0dXJuIHBhcnNlRHJhZ01ldGEob2JqKTtcbn1cbmNvbmZpZy5kYXRhQXR0clByZWZpeCA9ICcnO1xuZnVuY3Rpb24gZ2V0RW1iZWRkZWRFbERhdGEoZWwsIG5hbWUpIHtcbiAgICBsZXQgcHJlZml4ID0gY29uZmlnLmRhdGFBdHRyUHJlZml4O1xuICAgIGxldCBwcmVmaXhlZE5hbWUgPSAocHJlZml4ID8gcHJlZml4ICsgJy0nIDogJycpICsgbmFtZTtcbiAgICByZXR1cm4gZWwuZ2V0QXR0cmlidXRlKCdkYXRhLScgKyBwcmVmaXhlZE5hbWUpIHx8ICcnO1xufVxuXG4vKlxuTWFrZXMgYW4gZWxlbWVudCAodGhhdCBpcyAqZXh0ZXJuYWwqIHRvIGFueSBjYWxlbmRhcikgZHJhZ2dhYmxlLlxuQ2FuIHBhc3MgaW4gZGF0YSB0aGF0IGRldGVybWluZXMgaG93IGFuIGV2ZW50IHdpbGwgYmUgY3JlYXRlZCB3aGVuIGRyb3BwZWQgb250byBhIGNhbGVuZGFyLlxuTGV2ZXJhZ2VzIEZ1bGxDYWxlbmRhcidzIGludGVybmFsIGRyYWctbi1kcm9wIGZ1bmN0aW9uYWxpdHkgV0lUSE9VVCBhIHRoaXJkLXBhcnR5IGRyYWcgc3lzdGVtLlxuKi9cbmNsYXNzIEV4dGVybmFsRHJhZ2dhYmxlIHtcbiAgICBjb25zdHJ1Y3RvcihlbCwgc2V0dGluZ3MgPSB7fSkge1xuICAgICAgICB0aGlzLmhhbmRsZVBvaW50ZXJEb3duID0gKGV2KSA9PiB7XG4gICAgICAgICAgICBsZXQgeyBkcmFnZ2luZyB9ID0gdGhpcztcbiAgICAgICAgICAgIGxldCB7IG1pbkRpc3RhbmNlLCBsb25nUHJlc3NEZWxheSB9ID0gdGhpcy5zZXR0aW5ncztcbiAgICAgICAgICAgIGRyYWdnaW5nLm1pbkRpc3RhbmNlID1cbiAgICAgICAgICAgICAgICBtaW5EaXN0YW5jZSAhPSBudWxsID9cbiAgICAgICAgICAgICAgICAgICAgbWluRGlzdGFuY2UgOlxuICAgICAgICAgICAgICAgICAgICAoZXYuaXNUb3VjaCA/IDAgOiBCQVNFX09QVElPTl9ERUZBVUxUUy5ldmVudERyYWdNaW5EaXN0YW5jZSk7XG4gICAgICAgICAgICBkcmFnZ2luZy5kZWxheSA9XG4gICAgICAgICAgICAgICAgZXYuaXNUb3VjaCA/IC8vIFRPRE86IGV2ZW50dWFsbHkgcmVhZCBldmVudExvbmdQcmVzc0RlbGF5IGluc3RlYWQgdnZ2XG4gICAgICAgICAgICAgICAgICAgIChsb25nUHJlc3NEZWxheSAhPSBudWxsID8gbG9uZ1ByZXNzRGVsYXkgOiBCQVNFX09QVElPTl9ERUZBVUxUUy5sb25nUHJlc3NEZWxheSkgOlxuICAgICAgICAgICAgICAgICAgICAwO1xuICAgICAgICB9O1xuICAgICAgICB0aGlzLmhhbmRsZURyYWdTdGFydCA9IChldikgPT4ge1xuICAgICAgICAgICAgaWYgKGV2LmlzVG91Y2ggJiZcbiAgICAgICAgICAgICAgICB0aGlzLmRyYWdnaW5nLmRlbGF5ICYmXG4gICAgICAgICAgICAgICAgZXYuc3ViamVjdEVsLmNsYXNzTGlzdC5jb250YWlucygnZmMtZXZlbnQnKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZHJhZ2dpbmcubWlycm9yLmdldE1pcnJvckVsKCkuY2xhc3NMaXN0LmFkZCgnZmMtZXZlbnQtc2VsZWN0ZWQnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5zZXR0aW5ncyA9IHNldHRpbmdzO1xuICAgICAgICBsZXQgZHJhZ2dpbmcgPSB0aGlzLmRyYWdnaW5nID0gbmV3IEZlYXR1cmVmdWxFbGVtZW50RHJhZ2dpbmcoZWwpO1xuICAgICAgICBkcmFnZ2luZy50b3VjaFNjcm9sbEFsbG93ZWQgPSBmYWxzZTtcbiAgICAgICAgaWYgKHNldHRpbmdzLml0ZW1TZWxlY3RvciAhPSBudWxsKSB7XG4gICAgICAgICAgICBkcmFnZ2luZy5wb2ludGVyLnNlbGVjdG9yID0gc2V0dGluZ3MuaXRlbVNlbGVjdG9yO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzZXR0aW5ncy5hcHBlbmRUbyAhPSBudWxsKSB7XG4gICAgICAgICAgICBkcmFnZ2luZy5taXJyb3IucGFyZW50Tm9kZSA9IHNldHRpbmdzLmFwcGVuZFRvOyAvLyBUT0RPOiB3cml0ZSB0ZXN0c1xuICAgICAgICB9XG4gICAgICAgIGRyYWdnaW5nLmVtaXR0ZXIub24oJ3BvaW50ZXJkb3duJywgdGhpcy5oYW5kbGVQb2ludGVyRG93bik7XG4gICAgICAgIGRyYWdnaW5nLmVtaXR0ZXIub24oJ2RyYWdzdGFydCcsIHRoaXMuaGFuZGxlRHJhZ1N0YXJ0KTtcbiAgICAgICAgbmV3IEV4dGVybmFsRWxlbWVudERyYWdnaW5nKGRyYWdnaW5nLCBzZXR0aW5ncy5ldmVudERhdGEpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLW5ld1xuICAgIH1cbiAgICBkZXN0cm95KCkge1xuICAgICAgICB0aGlzLmRyYWdnaW5nLmRlc3Ryb3koKTtcbiAgICB9XG59XG5cbi8qXG5EZXRlY3RzIHdoZW4gYSAqVEhJUkQtUEFSVFkqIGRyYWctbi1kcm9wIHN5c3RlbSBpbnRlcmFjdHMgd2l0aCBlbGVtZW50cy5cblRoZSB0aGlyZC1wYXJ0eSBzeXN0ZW0gaXMgcmVzcG9uc2libGUgZm9yIGRyYXdpbmcgdGhlIHZpc3VhbHMgZWZmZWN0cyBvZiB0aGUgZHJhZy5cblRoaXMgY2xhc3Mgc2ltcGx5IG1vbml0b3JzIGZvciBwb2ludGVyIG1vdmVtZW50cyBhbmQgZmlyZXMgZXZlbnRzLlxuSXQgYWxzbyBoYXMgdGhlIGFiaWxpdHkgdG8gaGlkZSB0aGUgbW92aW5nIGVsZW1lbnQgKHRoZSBcIm1pcnJvclwiKSBkdXJpbmcgdGhlIGRyYWcuXG4qL1xuY2xhc3MgSW5mZXJyZWRFbGVtZW50RHJhZ2dpbmcgZXh0ZW5kcyBFbGVtZW50RHJhZ2dpbmcge1xuICAgIGNvbnN0cnVjdG9yKGNvbnRhaW5lckVsKSB7XG4gICAgICAgIHN1cGVyKGNvbnRhaW5lckVsKTtcbiAgICAgICAgdGhpcy5zaG91bGRJZ25vcmVNb3ZlID0gZmFsc2U7XG4gICAgICAgIHRoaXMubWlycm9yU2VsZWN0b3IgPSAnJztcbiAgICAgICAgdGhpcy5jdXJyZW50TWlycm9yRWwgPSBudWxsO1xuICAgICAgICB0aGlzLmhhbmRsZVBvaW50ZXJEb3duID0gKGV2KSA9PiB7XG4gICAgICAgICAgICB0aGlzLmVtaXR0ZXIudHJpZ2dlcigncG9pbnRlcmRvd24nLCBldik7XG4gICAgICAgICAgICBpZiAoIXRoaXMuc2hvdWxkSWdub3JlTW92ZSkge1xuICAgICAgICAgICAgICAgIC8vIGZpcmUgZHJhZ3N0YXJ0IHJpZ2h0IGF3YXkuIGRvZXMgbm90IHN1cHBvcnQgZGVsYXkgb3IgbWluLWRpc3RhbmNlXG4gICAgICAgICAgICAgICAgdGhpcy5lbWl0dGVyLnRyaWdnZXIoJ2RyYWdzdGFydCcsIGV2KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5oYW5kbGVQb2ludGVyTW92ZSA9IChldikgPT4ge1xuICAgICAgICAgICAgaWYgKCF0aGlzLnNob3VsZElnbm9yZU1vdmUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXR0ZXIudHJpZ2dlcignZHJhZ21vdmUnLCBldik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIHRoaXMuaGFuZGxlUG9pbnRlclVwID0gKGV2KSA9PiB7XG4gICAgICAgICAgICB0aGlzLmVtaXR0ZXIudHJpZ2dlcigncG9pbnRlcnVwJywgZXYpO1xuICAgICAgICAgICAgaWYgKCF0aGlzLnNob3VsZElnbm9yZU1vdmUpIHtcbiAgICAgICAgICAgICAgICAvLyBmaXJlIGRyYWdlbmQgcmlnaHQgYXdheS4gZG9lcyBub3Qgc3VwcG9ydCBhIHJldmVydCBhbmltYXRpb25cbiAgICAgICAgICAgICAgICB0aGlzLmVtaXR0ZXIudHJpZ2dlcignZHJhZ2VuZCcsIGV2KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgbGV0IHBvaW50ZXIgPSB0aGlzLnBvaW50ZXIgPSBuZXcgUG9pbnRlckRyYWdnaW5nKGNvbnRhaW5lckVsKTtcbiAgICAgICAgcG9pbnRlci5lbWl0dGVyLm9uKCdwb2ludGVyZG93bicsIHRoaXMuaGFuZGxlUG9pbnRlckRvd24pO1xuICAgICAgICBwb2ludGVyLmVtaXR0ZXIub24oJ3BvaW50ZXJtb3ZlJywgdGhpcy5oYW5kbGVQb2ludGVyTW92ZSk7XG4gICAgICAgIHBvaW50ZXIuZW1pdHRlci5vbigncG9pbnRlcnVwJywgdGhpcy5oYW5kbGVQb2ludGVyVXApO1xuICAgIH1cbiAgICBkZXN0cm95KCkge1xuICAgICAgICB0aGlzLnBvaW50ZXIuZGVzdHJveSgpO1xuICAgIH1cbiAgICBzZXRJZ25vcmVNb3ZlKGJvb2wpIHtcbiAgICAgICAgdGhpcy5zaG91bGRJZ25vcmVNb3ZlID0gYm9vbDtcbiAgICB9XG4gICAgc2V0TWlycm9ySXNWaXNpYmxlKGJvb2wpIHtcbiAgICAgICAgaWYgKGJvb2wpIHtcbiAgICAgICAgICAgIC8vIHJlc3RvcmUgYSBwcmV2aW91c2x5IGhpZGRlbiBlbGVtZW50LlxuICAgICAgICAgICAgLy8gdXNlIHRoZSByZWZlcmVuY2UgaW4gY2FzZSB0aGUgc2VsZWN0b3IgY2xhc3MgaGFzIGFscmVhZHkgYmVlbiByZW1vdmVkLlxuICAgICAgICAgICAgaWYgKHRoaXMuY3VycmVudE1pcnJvckVsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50TWlycm9yRWwuc3R5bGUudmlzaWJpbGl0eSA9ICcnO1xuICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudE1pcnJvckVsID0gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGxldCBtaXJyb3JFbCA9IHRoaXMubWlycm9yU2VsZWN0b3JcbiAgICAgICAgICAgICAgICAvLyBUT0RPOiBzb21laG93IHF1ZXJ5IEZ1bGxDYWxlbmRhcnMgV0lUSElOIHNoYWRvdy1yb290c1xuICAgICAgICAgICAgICAgID8gZG9jdW1lbnQucXVlcnlTZWxlY3Rvcih0aGlzLm1pcnJvclNlbGVjdG9yKVxuICAgICAgICAgICAgICAgIDogbnVsbDtcbiAgICAgICAgICAgIGlmIChtaXJyb3JFbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudE1pcnJvckVsID0gbWlycm9yRWw7XG4gICAgICAgICAgICAgICAgbWlycm9yRWwuc3R5bGUudmlzaWJpbGl0eSA9ICdoaWRkZW4nO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuXG4vKlxuQnJpZGdlcyB0aGlyZC1wYXJ0eSBkcmFnLW4tZHJvcCBzeXN0ZW1zIHdpdGggRnVsbENhbGVuZGFyLlxuTXVzdCBiZSBpbnN0YW50aWF0ZWQgYW5kIGRlc3Ryb3llZCBieSBjYWxsZXIuXG4qL1xuY2xhc3MgVGhpcmRQYXJ0eURyYWdnYWJsZSB7XG4gICAgY29uc3RydWN0b3IoY29udGFpbmVyT3JTZXR0aW5ncywgc2V0dGluZ3MpIHtcbiAgICAgICAgbGV0IGNvbnRhaW5lckVsID0gZG9jdW1lbnQ7XG4gICAgICAgIGlmIChcbiAgICAgICAgLy8gd2lzaCB3ZSBjb3VsZCBqdXN0IHRlc3QgaW5zdGFuY2VvZiBFdmVudFRhcmdldCwgYnV0IGRvZXNuJ3Qgd29yayBpbiBJRTExXG4gICAgICAgIGNvbnRhaW5lck9yU2V0dGluZ3MgPT09IGRvY3VtZW50IHx8XG4gICAgICAgICAgICBjb250YWluZXJPclNldHRpbmdzIGluc3RhbmNlb2YgRWxlbWVudCkge1xuICAgICAgICAgICAgY29udGFpbmVyRWwgPSBjb250YWluZXJPclNldHRpbmdzO1xuICAgICAgICAgICAgc2V0dGluZ3MgPSBzZXR0aW5ncyB8fCB7fTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHNldHRpbmdzID0gKGNvbnRhaW5lck9yU2V0dGluZ3MgfHwge30pO1xuICAgICAgICB9XG4gICAgICAgIGxldCBkcmFnZ2luZyA9IHRoaXMuZHJhZ2dpbmcgPSBuZXcgSW5mZXJyZWRFbGVtZW50RHJhZ2dpbmcoY29udGFpbmVyRWwpO1xuICAgICAgICBpZiAodHlwZW9mIHNldHRpbmdzLml0ZW1TZWxlY3RvciA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIGRyYWdnaW5nLnBvaW50ZXIuc2VsZWN0b3IgPSBzZXR0aW5ncy5pdGVtU2VsZWN0b3I7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoY29udGFpbmVyRWwgPT09IGRvY3VtZW50KSB7XG4gICAgICAgICAgICBkcmFnZ2luZy5wb2ludGVyLnNlbGVjdG9yID0gJ1tkYXRhLWV2ZW50XSc7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBzZXR0aW5ncy5taXJyb3JTZWxlY3RvciA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIGRyYWdnaW5nLm1pcnJvclNlbGVjdG9yID0gc2V0dGluZ3MubWlycm9yU2VsZWN0b3I7XG4gICAgICAgIH1cbiAgICAgICAgbmV3IEV4dGVybmFsRWxlbWVudERyYWdnaW5nKGRyYWdnaW5nLCBzZXR0aW5ncy5ldmVudERhdGEpOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLW5ld1xuICAgIH1cbiAgICBkZXN0cm95KCkge1xuICAgICAgICB0aGlzLmRyYWdnaW5nLmRlc3Ryb3koKTtcbiAgICB9XG59XG5cbnZhciBpbmRleCA9IGNyZWF0ZVBsdWdpbih7XG4gICAgbmFtZTogJ0BmdWxsY2FsZW5kYXIvaW50ZXJhY3Rpb24nLFxuICAgIGNvbXBvbmVudEludGVyYWN0aW9uczogW0RhdGVDbGlja2luZywgRGF0ZVNlbGVjdGluZywgRXZlbnREcmFnZ2luZywgRXZlbnRSZXNpemluZ10sXG4gICAgY2FsZW5kYXJJbnRlcmFjdGlvbnM6IFtVbnNlbGVjdEF1dG9dLFxuICAgIGVsZW1lbnREcmFnZ2luZ0ltcGw6IEZlYXR1cmVmdWxFbGVtZW50RHJhZ2dpbmcsXG4gICAgb3B0aW9uUmVmaW5lcnM6IE9QVElPTl9SRUZJTkVSUyxcbiAgICBsaXN0ZW5lclJlZmluZXJzOiBMSVNURU5FUl9SRUZJTkVSUyxcbn0pO1xuXG5leHBvcnQgeyBFeHRlcm5hbERyYWdnYWJsZSBhcyBEcmFnZ2FibGUsIFRoaXJkUGFydHlEcmFnZ2FibGUsIGluZGV4IGFzIGRlZmF1bHQgfTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/@fullcalendar/interaction/index.esm.js\n"); /***/ }), /***/ "./node_modules/@fullcalendar/list/index.esm.js": /*!******************************************************!*\ !*** ./node_modules/@fullcalendar/list/index.esm.js ***! \******************************************************/ /***/ (function(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) { eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": function() { return /* binding */ index; }\n/* harmony export */ });\n/* harmony import */ var _fullcalendar_core__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @fullcalendar/core */ \"./node_modules/@fullcalendar/core/index.esm.js\");\n/* harmony import */ var _internal_esm_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./internal.esm.js */ \"./node_modules/@fullcalendar/list/internal.esm.js\");\n/* harmony import */ var _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @fullcalendar/core/internal */ \"./node_modules/@fullcalendar/core/internal-common.esm.js\");\n\n\n\n\n\nconst OPTION_REFINERS = {\n listDayFormat: createFalsableFormatter,\n listDaySideFormat: createFalsableFormatter,\n noEventsClassNames: _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.n,\n noEventsContent: _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.n,\n noEventsDidMount: _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.n,\n noEventsWillUnmount: _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.n,\n // noEventsText is defined in base options\n};\nfunction createFalsableFormatter(input) {\n return input === false ? null : (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.x)(input);\n}\n\nvar css_248z = \":root{--fc-list-event-dot-width:10px;--fc-list-event-hover-bg-color:#f5f5f5}.fc-theme-standard .fc-list{border:1px solid var(--fc-border-color)}.fc .fc-list-empty{align-items:center;background-color:var(--fc-neutral-bg-color);display:flex;height:100%;justify-content:center}.fc .fc-list-empty-cushion{margin:5em 0}.fc .fc-list-table{border-style:hidden;width:100%}.fc .fc-list-table tr>*{border-left:0;border-right:0}.fc .fc-list-sticky .fc-list-day>*{background:var(--fc-page-bg-color);position:sticky;top:0}.fc .fc-list-table thead{left:-10000px;position:absolute}.fc .fc-list-table tbody>tr:first-child th{border-top:0}.fc .fc-list-table th{padding:0}.fc .fc-list-day-cushion,.fc .fc-list-table td{padding:8px 14px}.fc .fc-list-day-cushion:after{clear:both;content:\\\"\\\";display:table}.fc-theme-standard .fc-list-day-cushion{background-color:var(--fc-neutral-bg-color)}.fc-direction-ltr .fc-list-day-text,.fc-direction-rtl .fc-list-day-side-text{float:left}.fc-direction-ltr .fc-list-day-side-text,.fc-direction-rtl .fc-list-day-text{float:right}.fc-direction-ltr .fc-list-table .fc-list-event-graphic{padding-right:0}.fc-direction-rtl .fc-list-table .fc-list-event-graphic{padding-left:0}.fc .fc-list-event.fc-event-forced-url{cursor:pointer}.fc .fc-list-event:hover td{background-color:var(--fc-list-event-hover-bg-color)}.fc .fc-list-event-graphic,.fc .fc-list-event-time{white-space:nowrap;width:1px}.fc .fc-list-event-dot{border:calc(var(--fc-list-event-dot-width)/2) solid var(--fc-event-border-color);border-radius:calc(var(--fc-list-event-dot-width)/2);box-sizing:content-box;display:inline-block;height:0;width:0}.fc .fc-list-event-title a{color:inherit;text-decoration:none}.fc .fc-list-event.fc-event-forced-url:hover a{text-decoration:underline}\";\n(0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.i)(css_248z);\n\nvar index = (0,_fullcalendar_core__WEBPACK_IMPORTED_MODULE_1__.createPlugin)({\n name: '@fullcalendar/list',\n optionRefiners: OPTION_REFINERS,\n views: {\n list: {\n component: _internal_esm_js__WEBPACK_IMPORTED_MODULE_2__.ListView,\n buttonTextKey: 'list',\n listDayFormat: { month: 'long', day: 'numeric', year: 'numeric' }, // like \"January 1, 2016\"\n },\n listDay: {\n type: 'list',\n duration: { days: 1 },\n listDayFormat: { weekday: 'long' }, // day-of-week is all we need. full date is probably in headerToolbar\n },\n listWeek: {\n type: 'list',\n duration: { weeks: 1 },\n listDayFormat: { weekday: 'long' },\n listDaySideFormat: { month: 'long', day: 'numeric', year: 'numeric' },\n },\n listMonth: {\n type: 'list',\n duration: { month: 1 },\n listDaySideFormat: { weekday: 'long' }, // day-of-week is nice-to-have\n },\n listYear: {\n type: 'list',\n duration: { year: 1 },\n listDaySideFormat: { weekday: 'long' }, // day-of-week is nice-to-have\n },\n },\n});\n\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvQGZ1bGxjYWxlbmRhci9saXN0L2luZGV4LmVzbS5qcy5qcyIsIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQWtEO0FBQ0w7QUFDeUM7QUFDbkQ7O0FBRW5DO0FBQ0E7QUFDQTtBQUNBLHdCQUF3QiwwREFBUTtBQUNoQyxxQkFBcUIsMERBQVE7QUFDN0Isc0JBQXNCLDBEQUFRO0FBQzlCLHlCQUF5QiwwREFBUTtBQUNqQztBQUNBO0FBQ0E7QUFDQSxvQ0FBb0MsOERBQWU7QUFDbkQ7O0FBRUEsc0JBQXNCLCtCQUErQix1Q0FBdUMsNEJBQTRCLHdDQUF3QyxtQkFBbUIsbUJBQW1CLDRDQUE0QyxhQUFhLFlBQVksdUJBQXVCLDJCQUEyQixhQUFhLG1CQUFtQixvQkFBb0IsV0FBVyx3QkFBd0IsY0FBYyxlQUFlLG1DQUFtQyxtQ0FBbUMsZ0JBQWdCLE1BQU0seUJBQXlCLGNBQWMsa0JBQWtCLDJDQUEyQyxhQUFhLHNCQUFzQixVQUFVLCtDQUErQyxpQkFBaUIsK0JBQStCLFdBQVcsYUFBYSxjQUFjLHdDQUF3Qyw0Q0FBNEMsNkVBQTZFLFdBQVcsNkVBQTZFLFlBQVksd0RBQXdELGdCQUFnQix3REFBd0QsZUFBZSx1Q0FBdUMsZUFBZSw0QkFBNEIscURBQXFELG1EQUFtRCxtQkFBbUIsVUFBVSx1QkFBdUIsaUZBQWlGLHFEQUFxRCx1QkFBdUIscUJBQXFCLFNBQVMsUUFBUSwyQkFBMkIsY0FBYyxxQkFBcUIsK0NBQStDLDBCQUEwQjtBQUMvdUQsOERBQVk7O0FBRVosWUFBWSxnRUFBWTtBQUN4QjtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVCQUF1QixzREFBUTtBQUMvQjtBQUNBLDZCQUE2QixnREFBZ0Q7QUFDN0UsU0FBUztBQUNUO0FBQ0E7QUFDQSx3QkFBd0IsU0FBUztBQUNqQyw2QkFBNkIsaUJBQWlCO0FBQzlDLFNBQVM7QUFDVDtBQUNBO0FBQ0Esd0JBQXdCLFVBQVU7QUFDbEMsNkJBQTZCLGlCQUFpQjtBQUM5QyxpQ0FBaUMsZ0RBQWdEO0FBQ2pGLFNBQVM7QUFDVDtBQUNBO0FBQ0Esd0JBQXdCLFVBQVU7QUFDbEMsaUNBQWlDLGlCQUFpQjtBQUNsRCxTQUFTO0FBQ1Q7QUFDQTtBQUNBLHdCQUF3QixTQUFTO0FBQ2pDLGlDQUFpQyxpQkFBaUI7QUFDbEQsU0FBUztBQUNULEtBQUs7QUFDTCxDQUFDOztBQUUyQiIsInNvdXJjZXMiOlsid2VicGFjazovL1Z1ZXh5Ly4vbm9kZV9tb2R1bGVzL0BmdWxsY2FsZW5kYXIvbGlzdC9pbmRleC5lc20uanM/YTk2ZiJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBjcmVhdGVQbHVnaW4gfSBmcm9tICdAZnVsbGNhbGVuZGFyL2NvcmUnO1xuaW1wb3J0IHsgTGlzdFZpZXcgfSBmcm9tICcuL2ludGVybmFsLmVzbS5qcyc7XG5pbXBvcnQgeyBpZGVudGl0eSwgY3JlYXRlRm9ybWF0dGVyLCBpbmplY3RTdHlsZXMgfSBmcm9tICdAZnVsbGNhbGVuZGFyL2NvcmUvaW50ZXJuYWwnO1xuaW1wb3J0ICdAZnVsbGNhbGVuZGFyL2NvcmUvcHJlYWN0JztcblxuY29uc3QgT1BUSU9OX1JFRklORVJTID0ge1xuICAgIGxpc3REYXlGb3JtYXQ6IGNyZWF0ZUZhbHNhYmxlRm9ybWF0dGVyLFxuICAgIGxpc3REYXlTaWRlRm9ybWF0OiBjcmVhdGVGYWxzYWJsZUZvcm1hdHRlcixcbiAgICBub0V2ZW50c0NsYXNzTmFtZXM6IGlkZW50aXR5LFxuICAgIG5vRXZlbnRzQ29udGVudDogaWRlbnRpdHksXG4gICAgbm9FdmVudHNEaWRNb3VudDogaWRlbnRpdHksXG4gICAgbm9FdmVudHNXaWxsVW5tb3VudDogaWRlbnRpdHksXG4gICAgLy8gbm9FdmVudHNUZXh0IGlzIGRlZmluZWQgaW4gYmFzZSBvcHRpb25zXG59O1xuZnVuY3Rpb24gY3JlYXRlRmFsc2FibGVGb3JtYXR0ZXIoaW5wdXQpIHtcbiAgICByZXR1cm4gaW5wdXQgPT09IGZhbHNlID8gbnVsbCA6IGNyZWF0ZUZvcm1hdHRlcihpbnB1dCk7XG59XG5cbnZhciBjc3NfMjQ4eiA9IFwiOnJvb3R7LS1mYy1saXN0LWV2ZW50LWRvdC13aWR0aDoxMHB4Oy0tZmMtbGlzdC1ldmVudC1ob3Zlci1iZy1jb2xvcjojZjVmNWY1fS5mYy10aGVtZS1zdGFuZGFyZCAuZmMtbGlzdHtib3JkZXI6MXB4IHNvbGlkIHZhcigtLWZjLWJvcmRlci1jb2xvcil9LmZjIC5mYy1saXN0LWVtcHR5e2FsaWduLWl0ZW1zOmNlbnRlcjtiYWNrZ3JvdW5kLWNvbG9yOnZhcigtLWZjLW5ldXRyYWwtYmctY29sb3IpO2Rpc3BsYXk6ZmxleDtoZWlnaHQ6MTAwJTtqdXN0aWZ5LWNvbnRlbnQ6Y2VudGVyfS5mYyAuZmMtbGlzdC1lbXB0eS1jdXNoaW9ue21hcmdpbjo1ZW0gMH0uZmMgLmZjLWxpc3QtdGFibGV7Ym9yZGVyLXN0eWxlOmhpZGRlbjt3aWR0aDoxMDAlfS5mYyAuZmMtbGlzdC10YWJsZSB0cj4qe2JvcmRlci1sZWZ0OjA7Ym9yZGVyLXJpZ2h0OjB9LmZjIC5mYy1saXN0LXN0aWNreSAuZmMtbGlzdC1kYXk+KntiYWNrZ3JvdW5kOnZhcigtLWZjLXBhZ2UtYmctY29sb3IpO3Bvc2l0aW9uOnN0aWNreTt0b3A6MH0uZmMgLmZjLWxpc3QtdGFibGUgdGhlYWR7bGVmdDotMTAwMDBweDtwb3NpdGlvbjphYnNvbHV0ZX0uZmMgLmZjLWxpc3QtdGFibGUgdGJvZHk+dHI6Zmlyc3QtY2hpbGQgdGh7Ym9yZGVyLXRvcDowfS5mYyAuZmMtbGlzdC10YWJsZSB0aHtwYWRkaW5nOjB9LmZjIC5mYy1saXN0LWRheS1jdXNoaW9uLC5mYyAuZmMtbGlzdC10YWJsZSB0ZHtwYWRkaW5nOjhweCAxNHB4fS5mYyAuZmMtbGlzdC1kYXktY3VzaGlvbjphZnRlcntjbGVhcjpib3RoO2NvbnRlbnQ6XFxcIlxcXCI7ZGlzcGxheTp0YWJsZX0uZmMtdGhlbWUtc3RhbmRhcmQgLmZjLWxpc3QtZGF5LWN1c2hpb257YmFja2dyb3VuZC1jb2xvcjp2YXIoLS1mYy1uZXV0cmFsLWJnLWNvbG9yKX0uZmMtZGlyZWN0aW9uLWx0ciAuZmMtbGlzdC1kYXktdGV4dCwuZmMtZGlyZWN0aW9uLXJ0bCAuZmMtbGlzdC1kYXktc2lkZS10ZXh0e2Zsb2F0OmxlZnR9LmZjLWRpcmVjdGlvbi1sdHIgLmZjLWxpc3QtZGF5LXNpZGUtdGV4dCwuZmMtZGlyZWN0aW9uLXJ0bCAuZmMtbGlzdC1kYXktdGV4dHtmbG9hdDpyaWdodH0uZmMtZGlyZWN0aW9uLWx0ciAuZmMtbGlzdC10YWJsZSAuZmMtbGlzdC1ldmVudC1ncmFwaGlje3BhZGRpbmctcmlnaHQ6MH0uZmMtZGlyZWN0aW9uLXJ0bCAuZmMtbGlzdC10YWJsZSAuZmMtbGlzdC1ldmVudC1ncmFwaGlje3BhZGRpbmctbGVmdDowfS5mYyAuZmMtbGlzdC1ldmVudC5mYy1ldmVudC1mb3JjZWQtdXJse2N1cnNvcjpwb2ludGVyfS5mYyAuZmMtbGlzdC1ldmVudDpob3ZlciB0ZHtiYWNrZ3JvdW5kLWNvbG9yOnZhcigtLWZjLWxpc3QtZXZlbnQtaG92ZXItYmctY29sb3IpfS5mYyAuZmMtbGlzdC1ldmVudC1ncmFwaGljLC5mYyAuZmMtbGlzdC1ldmVudC10aW1le3doaXRlLXNwYWNlOm5vd3JhcDt3aWR0aDoxcHh9LmZjIC5mYy1saXN0LWV2ZW50LWRvdHtib3JkZXI6Y2FsYyh2YXIoLS1mYy1saXN0LWV2ZW50LWRvdC13aWR0aCkvMikgc29saWQgdmFyKC0tZmMtZXZlbnQtYm9yZGVyLWNvbG9yKTtib3JkZXItcmFkaXVzOmNhbGModmFyKC0tZmMtbGlzdC1ldmVudC1kb3Qtd2lkdGgpLzIpO2JveC1zaXppbmc6Y29udGVudC1ib3g7ZGlzcGxheTppbmxpbmUtYmxvY2s7aGVpZ2h0OjA7d2lkdGg6MH0uZmMgLmZjLWxpc3QtZXZlbnQtdGl0bGUgYXtjb2xvcjppbmhlcml0O3RleHQtZGVjb3JhdGlvbjpub25lfS5mYyAuZmMtbGlzdC1ldmVudC5mYy1ldmVudC1mb3JjZWQtdXJsOmhvdmVyIGF7dGV4dC1kZWNvcmF0aW9uOnVuZGVybGluZX1cIjtcbmluamVjdFN0eWxlcyhjc3NfMjQ4eik7XG5cbnZhciBpbmRleCA9IGNyZWF0ZVBsdWdpbih7XG4gICAgbmFtZTogJ0BmdWxsY2FsZW5kYXIvbGlzdCcsXG4gICAgb3B0aW9uUmVmaW5lcnM6IE9QVElPTl9SRUZJTkVSUyxcbiAgICB2aWV3czoge1xuICAgICAgICBsaXN0OiB7XG4gICAgICAgICAgICBjb21wb25lbnQ6IExpc3RWaWV3LFxuICAgICAgICAgICAgYnV0dG9uVGV4dEtleTogJ2xpc3QnLFxuICAgICAgICAgICAgbGlzdERheUZvcm1hdDogeyBtb250aDogJ2xvbmcnLCBkYXk6ICdudW1lcmljJywgeWVhcjogJ251bWVyaWMnIH0sIC8vIGxpa2UgXCJKYW51YXJ5IDEsIDIwMTZcIlxuICAgICAgICB9LFxuICAgICAgICBsaXN0RGF5OiB7XG4gICAgICAgICAgICB0eXBlOiAnbGlzdCcsXG4gICAgICAgICAgICBkdXJhdGlvbjogeyBkYXlzOiAxIH0sXG4gICAgICAgICAgICBsaXN0RGF5Rm9ybWF0OiB7IHdlZWtkYXk6ICdsb25nJyB9LCAvLyBkYXktb2Ytd2VlayBpcyBhbGwgd2UgbmVlZC4gZnVsbCBkYXRlIGlzIHByb2JhYmx5IGluIGhlYWRlclRvb2xiYXJcbiAgICAgICAgfSxcbiAgICAgICAgbGlzdFdlZWs6IHtcbiAgICAgICAgICAgIHR5cGU6ICdsaXN0JyxcbiAgICAgICAgICAgIGR1cmF0aW9uOiB7IHdlZWtzOiAxIH0sXG4gICAgICAgICAgICBsaXN0RGF5Rm9ybWF0OiB7IHdlZWtkYXk6ICdsb25nJyB9LFxuICAgICAgICAgICAgbGlzdERheVNpZGVGb3JtYXQ6IHsgbW9udGg6ICdsb25nJywgZGF5OiAnbnVtZXJpYycsIHllYXI6ICdudW1lcmljJyB9LFxuICAgICAgICB9LFxuICAgICAgICBsaXN0TW9udGg6IHtcbiAgICAgICAgICAgIHR5cGU6ICdsaXN0JyxcbiAgICAgICAgICAgIGR1cmF0aW9uOiB7IG1vbnRoOiAxIH0sXG4gICAgICAgICAgICBsaXN0RGF5U2lkZUZvcm1hdDogeyB3ZWVrZGF5OiAnbG9uZycgfSwgLy8gZGF5LW9mLXdlZWsgaXMgbmljZS10by1oYXZlXG4gICAgICAgIH0sXG4gICAgICAgIGxpc3RZZWFyOiB7XG4gICAgICAgICAgICB0eXBlOiAnbGlzdCcsXG4gICAgICAgICAgICBkdXJhdGlvbjogeyB5ZWFyOiAxIH0sXG4gICAgICAgICAgICBsaXN0RGF5U2lkZUZvcm1hdDogeyB3ZWVrZGF5OiAnbG9uZycgfSwgLy8gZGF5LW9mLXdlZWsgaXMgbmljZS10by1oYXZlXG4gICAgICAgIH0sXG4gICAgfSxcbn0pO1xuXG5leHBvcnQgeyBpbmRleCBhcyBkZWZhdWx0IH07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/@fullcalendar/list/index.esm.js\n"); /***/ }), /***/ "./node_modules/@fullcalendar/list/internal.esm.js": /*!*********************************************************!*\ !*** ./node_modules/@fullcalendar/list/internal.esm.js ***! \*********************************************************/ /***/ (function(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) { eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"ListView\": function() { return /* binding */ ListView; }\n/* harmony export */ });\n/* harmony import */ var _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @fullcalendar/core/internal */ \"./node_modules/@fullcalendar/core/internal-common.esm.js\");\n/* harmony import */ var _fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @fullcalendar/core/preact */ \"./node_modules/preact/dist/preact.module.js\");\n\n\n\nclass ListViewHeaderRow extends _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.Y {\n constructor() {\n super(...arguments);\n this.state = {\n textId: (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.a6)(),\n };\n }\n render() {\n let { theme, dateEnv, options, viewApi } = this.context;\n let { cellId, dayDate, todayRange } = this.props;\n let { textId } = this.state;\n let dayMeta = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.a$)(dayDate, todayRange);\n // will ever be falsy?\n let text = options.listDayFormat ? dateEnv.format(dayDate, options.listDayFormat) : '';\n // will ever be falsy? also, BAD NAME \"alt\"\n let sideText = options.listDaySideFormat ? dateEnv.format(dayDate, options.listDaySideFormat) : '';\n let renderProps = Object.assign({ date: dateEnv.toDate(dayDate), view: viewApi, textId,\n text,\n sideText, navLinkAttrs: (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.b1)(this.context, dayDate), sideNavLinkAttrs: (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.b1)(this.context, dayDate, 'day', false) }, dayMeta);\n // TODO: make a reusable HOC for dayHeader (used in daygrid/timegrid too)\n return ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.C, { elTag: \"tr\", elClasses: [\n 'fc-list-day',\n ...(0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.a_)(dayMeta, theme),\n ], elAttrs: {\n 'data-date': (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bw)(dayDate),\n }, renderProps: renderProps, generatorName: \"dayHeaderContent\", generator: options.dayHeaderContent || renderInnerContent, classNameGenerator: options.dayHeaderClassNames, didMount: options.dayHeaderDidMount, willUnmount: options.dayHeaderWillUnmount }, (InnerContent) => ( // TODO: force-hide top border based on :first-child\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"th\", { scope: \"colgroup\", colSpan: 3, id: cellId, \"aria-labelledby\": textId },\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(InnerContent, { elTag: \"div\", elClasses: [\n 'fc-list-day-cushion',\n theme.getClass('tableCellShaded'),\n ] })))));\n }\n}\nfunction renderInnerContent(props) {\n return ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.Fragment, null,\n props.text && ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"a\", Object.assign({ id: props.textId, className: \"fc-list-day-text\" }, props.navLinkAttrs), props.text)),\n props.sideText && ( /* not keyboard tabbable */(0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"a\", Object.assign({ \"aria-hidden\": true, className: \"fc-list-day-side-text\" }, props.sideNavLinkAttrs), props.sideText))));\n}\n\nconst DEFAULT_TIME_FORMAT = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.x)({\n hour: 'numeric',\n minute: '2-digit',\n meridiem: 'short',\n});\nclass ListViewEventRow extends _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.Y {\n render() {\n let { props, context } = this;\n let { options } = context;\n let { seg, timeHeaderId, eventHeaderId, dateHeaderId } = props;\n let timeFormat = options.eventTimeFormat || DEFAULT_TIME_FORMAT;\n return ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.cn, Object.assign({}, props, { elTag: \"tr\", elClasses: [\n 'fc-list-event',\n seg.eventRange.def.url && 'fc-event-forced-url',\n ], defaultGenerator: () => renderEventInnerContent(seg, context) /* weird */, seg: seg, timeText: \"\", disableDragging: true, disableResizing: true }), (InnerContent, eventContentArg) => ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.Fragment, null,\n buildTimeContent(seg, timeFormat, context, timeHeaderId, dateHeaderId),\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"td\", { \"aria-hidden\": true, className: \"fc-list-event-graphic\" },\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"span\", { className: \"fc-list-event-dot\", style: {\n borderColor: eventContentArg.borderColor || eventContentArg.backgroundColor,\n } })),\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(InnerContent, { elTag: \"td\", elClasses: ['fc-list-event-title'], elAttrs: { headers: `${eventHeaderId} ${dateHeaderId}` } })))));\n }\n}\nfunction renderEventInnerContent(seg, context) {\n let interactiveAttrs = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bU)(seg, context);\n return ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"a\", Object.assign({}, interactiveAttrs), seg.eventRange.def.title));\n}\nfunction buildTimeContent(seg, timeFormat, context, timeHeaderId, dateHeaderId) {\n let { options } = context;\n if (options.displayEventTime !== false) {\n let eventDef = seg.eventRange.def;\n let eventInstance = seg.eventRange.instance;\n let doAllDay = false;\n let timeText;\n if (eventDef.allDay) {\n doAllDay = true;\n }\n else if ((0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.az)(seg.eventRange.range)) { // TODO: use (!isStart || !isEnd) instead?\n if (seg.isStart) {\n timeText = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bQ)(seg, timeFormat, context, null, null, eventInstance.range.start, seg.end);\n }\n else if (seg.isEnd) {\n timeText = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bQ)(seg, timeFormat, context, null, null, seg.start, eventInstance.range.end);\n }\n else {\n doAllDay = true;\n }\n }\n else {\n timeText = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bQ)(seg, timeFormat, context);\n }\n if (doAllDay) {\n let renderProps = {\n text: context.options.allDayText,\n view: context.viewApi,\n };\n return ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.C, { elTag: \"td\", elClasses: ['fc-list-event-time'], elAttrs: {\n headers: `${timeHeaderId} ${dateHeaderId}`,\n }, renderProps: renderProps, generatorName: \"allDayContent\", generator: options.allDayContent || renderAllDayInner, classNameGenerator: options.allDayClassNames, didMount: options.allDayDidMount, willUnmount: options.allDayWillUnmount }));\n }\n return ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"td\", { className: \"fc-list-event-time\" }, timeText));\n }\n return null;\n}\nfunction renderAllDayInner(renderProps) {\n return renderProps.text;\n}\n\n/*\nResponsible for the scroller, and forwarding event-related actions into the \"grid\".\n*/\nclass ListView extends _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bf {\n constructor() {\n super(...arguments);\n this.computeDateVars = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.z)(computeDateVars);\n this.eventStoreToSegs = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.z)(this._eventStoreToSegs);\n this.state = {\n timeHeaderId: (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.a6)(),\n eventHeaderId: (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.a6)(),\n dateHeaderIdRoot: (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.a6)(),\n };\n this.setRootEl = (rootEl) => {\n if (rootEl) {\n this.context.registerInteractiveComponent(this, {\n el: rootEl,\n });\n }\n else {\n this.context.unregisterInteractiveComponent(this);\n }\n };\n }\n render() {\n let { props, context } = this;\n let { dayDates, dayRanges } = this.computeDateVars(props.dateProfile);\n let eventSegs = this.eventStoreToSegs(props.eventStore, props.eventUiBases, dayRanges);\n return ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.ct, { elRef: this.setRootEl, elClasses: [\n 'fc-list',\n context.theme.getClass('table'),\n context.options.stickyHeaderDates !== false ?\n 'fc-list-sticky' :\n '',\n ], viewSpec: context.viewSpec },\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.cd, { liquid: !props.isHeightAuto, overflowX: props.isHeightAuto ? 'visible' : 'hidden', overflowY: props.isHeightAuto ? 'visible' : 'auto' }, eventSegs.length > 0 ?\n this.renderSegList(eventSegs, dayDates) :\n this.renderEmptyMessage())));\n }\n renderEmptyMessage() {\n let { options, viewApi } = this.context;\n let renderProps = {\n text: options.noEventsText,\n view: viewApi,\n };\n return ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.C, { elTag: \"div\", elClasses: ['fc-list-empty'], renderProps: renderProps, generatorName: \"noEventsContent\", generator: options.noEventsContent || renderNoEventsInner, classNameGenerator: options.noEventsClassNames, didMount: options.noEventsDidMount, willUnmount: options.noEventsWillUnmount }, (InnerContent) => ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(InnerContent, { elTag: \"div\", elClasses: ['fc-list-empty-cushion'] }))));\n }\n renderSegList(allSegs, dayDates) {\n let { theme, options } = this.context;\n let { timeHeaderId, eventHeaderId, dateHeaderIdRoot } = this.state;\n let segsByDay = groupSegsByDay(allSegs); // sparse array\n return ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.ch, { unit: \"day\" }, (nowDate, todayRange) => {\n let innerNodes = [];\n for (let dayIndex = 0; dayIndex < segsByDay.length; dayIndex += 1) {\n let daySegs = segsByDay[dayIndex];\n if (daySegs) { // sparse array, so might be undefined\n let dayStr = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bw)(dayDates[dayIndex]);\n let dateHeaderId = dateHeaderIdRoot + '-' + dayStr;\n // append a day header\n innerNodes.push((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(ListViewHeaderRow, { key: dayStr, cellId: dateHeaderId, dayDate: dayDates[dayIndex], todayRange: todayRange }));\n daySegs = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bR)(daySegs, options.eventOrder);\n for (let seg of daySegs) {\n innerNodes.push((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(ListViewEventRow, Object.assign({ key: dayStr + ':' + seg.eventRange.instance.instanceId /* are multiple segs for an instanceId */, seg: seg, isDragging: false, isResizing: false, isDateSelecting: false, isSelected: false, timeHeaderId: timeHeaderId, eventHeaderId: eventHeaderId, dateHeaderId: dateHeaderId }, (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bS)(seg, todayRange, nowDate))));\n }\n }\n }\n return ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"table\", { className: 'fc-list-table ' + theme.getClass('table') },\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"thead\", null,\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"tr\", null,\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"th\", { scope: \"col\", id: timeHeaderId }, options.timeHint),\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"th\", { scope: \"col\", \"aria-hidden\": true }),\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"th\", { scope: \"col\", id: eventHeaderId }, options.eventHint))),\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"tbody\", null, innerNodes)));\n }));\n }\n _eventStoreToSegs(eventStore, eventUiBases, dayRanges) {\n return this.eventRangesToSegs((0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.af)(eventStore, eventUiBases, this.props.dateProfile.activeRange, this.context.options.nextDayThreshold).fg, dayRanges);\n }\n eventRangesToSegs(eventRanges, dayRanges) {\n let segs = [];\n for (let eventRange of eventRanges) {\n segs.push(...this.eventRangeToSegs(eventRange, dayRanges));\n }\n return segs;\n }\n eventRangeToSegs(eventRange, dayRanges) {\n let { dateEnv } = this.context;\n let { nextDayThreshold } = this.context.options;\n let range = eventRange.range;\n let allDay = eventRange.def.allDay;\n let dayIndex;\n let segRange;\n let seg;\n let segs = [];\n for (dayIndex = 0; dayIndex < dayRanges.length; dayIndex += 1) {\n segRange = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.o)(range, dayRanges[dayIndex]);\n if (segRange) {\n seg = {\n component: this,\n eventRange,\n start: segRange.start,\n end: segRange.end,\n isStart: eventRange.isStart && segRange.start.valueOf() === range.start.valueOf(),\n isEnd: eventRange.isEnd && segRange.end.valueOf() === range.end.valueOf(),\n dayIndex,\n };\n segs.push(seg);\n // detect when range won't go fully into the next day,\n // and mutate the latest seg to the be the end.\n if (!seg.isEnd && !allDay &&\n dayIndex + 1 < dayRanges.length &&\n range.end <\n dateEnv.add(dayRanges[dayIndex + 1].start, nextDayThreshold)) {\n seg.end = range.end;\n seg.isEnd = true;\n break;\n }\n }\n }\n return segs;\n }\n}\nfunction renderNoEventsInner(renderProps) {\n return renderProps.text;\n}\nfunction computeDateVars(dateProfile) {\n let dayStart = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.q)(dateProfile.renderRange.start);\n let viewEnd = dateProfile.renderRange.end;\n let dayDates = [];\n let dayRanges = [];\n while (dayStart < viewEnd) {\n dayDates.push(dayStart);\n dayRanges.push({\n start: dayStart,\n end: (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.t)(dayStart, 1),\n });\n dayStart = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.t)(dayStart, 1);\n }\n return { dayDates, dayRanges };\n}\n// Returns a sparse array of arrays, segs grouped by their dayIndex\nfunction groupSegsByDay(segs) {\n let segsByDay = []; // sparse array\n let i;\n let seg;\n for (i = 0; i < segs.length; i += 1) {\n seg = segs[i];\n (segsByDay[seg.dayIndex] || (segsByDay[seg.dayIndex] = []))\n .push(seg);\n }\n return segsByDay;\n}\n\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvQGZ1bGxjYWxlbmRhci9saXN0L2ludGVybmFsLmVzbS5qcy5qcyIsIm1hcHBpbmdzIjoiOzs7Ozs7QUFBcVk7QUFDalU7O0FBRXBFLGdDQUFnQywwREFBYTtBQUM3QztBQUNBO0FBQ0E7QUFDQSxvQkFBb0IsK0RBQWM7QUFDbEM7QUFDQTtBQUNBO0FBQ0EsY0FBYyxtQ0FBbUM7QUFDakQsY0FBYyw4QkFBOEI7QUFDNUMsY0FBYyxTQUFTO0FBQ3ZCLHNCQUFzQiwrREFBVztBQUNqQztBQUNBO0FBQ0E7QUFDQTtBQUNBLDBDQUEwQztBQUMxQztBQUNBLG9DQUFvQywrREFBaUIsMkNBQTJDLCtEQUFpQix1Q0FBdUM7QUFDeEo7QUFDQSxnQkFBZ0Isd0VBQWEsQ0FBQywwREFBZ0IsSUFBSTtBQUNsRDtBQUNBLG1CQUFtQiwrREFBZ0I7QUFDbkM7QUFDQSw2QkFBNkIsK0RBQWU7QUFDNUMsYUFBYSwyUEFBMlA7QUFDeFEsUUFBUSx3RUFBYSxTQUFTLHNFQUFzRTtBQUNwRyxZQUFZLHdFQUFhLGlCQUFpQjtBQUMxQztBQUNBO0FBQ0EsbUJBQW1CO0FBQ25CO0FBQ0E7QUFDQTtBQUNBLFlBQVksd0VBQWEsQ0FBQywrREFBUTtBQUNsQyx1QkFBdUIsd0VBQWEsc0JBQXNCLGlEQUFpRDtBQUMzRyx1REFBdUQsd0VBQWEsc0JBQXNCLHlEQUF5RDtBQUNuSjs7QUFFQSw0QkFBNEIsOERBQWU7QUFDM0M7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNELCtCQUErQiwwREFBYTtBQUM1QztBQUNBLGNBQWMsaUJBQWlCO0FBQy9CLGNBQWMsVUFBVTtBQUN4QixjQUFjLGlEQUFpRDtBQUMvRDtBQUNBLGdCQUFnQix3RUFBYSxDQUFDLDJEQUFjLGtCQUFrQixXQUFXO0FBQ3pFO0FBQ0E7QUFDQSxnS0FBZ0ssdUNBQXVDLHdFQUFhLENBQUMsK0RBQVE7QUFDN047QUFDQSxZQUFZLHdFQUFhLFNBQVMseURBQXlEO0FBQzNGLGdCQUFnQix3RUFBYSxXQUFXO0FBQ3hDO0FBQ0EsdUJBQXVCO0FBQ3ZCLFlBQVksd0VBQWEsaUJBQWlCLDREQUE0RCxZQUFZLGVBQWUsRUFBRSxhQUFhLEtBQUs7QUFDcko7QUFDQTtBQUNBO0FBQ0EsMkJBQTJCLCtEQUFpQjtBQUM1QyxZQUFZLHdFQUFhLHNCQUFzQjtBQUMvQztBQUNBO0FBQ0EsVUFBVSxVQUFVO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsK0RBQWUsMEJBQTBCO0FBQzFEO0FBQ0EsMkJBQTJCLCtEQUFnQjtBQUMzQztBQUNBO0FBQ0EsMkJBQTJCLCtEQUFnQjtBQUMzQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1QkFBdUIsK0RBQWdCO0FBQ3ZDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9CQUFvQix3RUFBYSxDQUFDLDBEQUFnQixJQUFJO0FBQ3RELGdDQUFnQyxjQUFjLEVBQUUsYUFBYTtBQUM3RCxpQkFBaUIsMk9BQTJPO0FBQzVQO0FBQ0EsZ0JBQWdCLHdFQUFhLFNBQVMsaUNBQWlDO0FBQ3ZFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSx1QkFBdUIsMkRBQWE7QUFDcEM7QUFDQTtBQUNBLCtCQUErQiw4REFBTztBQUN0QyxnQ0FBZ0MsOERBQU87QUFDdkM7QUFDQSwwQkFBMEIsK0RBQWM7QUFDeEMsMkJBQTJCLCtEQUFjO0FBQ3pDLDhCQUE4QiwrREFBYztBQUM1QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYyxpQkFBaUI7QUFDL0IsY0FBYyxzQkFBc0I7QUFDcEM7QUFDQSxnQkFBZ0Isd0VBQWEsQ0FBQywyREFBYSxJQUFJO0FBQy9DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyQ0FBMkM7QUFDM0MsWUFBWSx3RUFBYSxDQUFDLDJEQUFRLElBQUksdUlBQXVJO0FBQzdLO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYyxtQkFBbUI7QUFDakM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0Isd0VBQWEsQ0FBQywwREFBZ0IsSUFBSSxpU0FBaVMscUJBQXFCLHdFQUFhLGlCQUFpQixvREFBb0Q7QUFDMWI7QUFDQTtBQUNBLGNBQWMsaUJBQWlCO0FBQy9CLGNBQWMsZ0RBQWdEO0FBQzlELGlEQUFpRDtBQUNqRCxnQkFBZ0Isd0VBQWEsQ0FBQywyREFBUSxJQUFJLGFBQWE7QUFDdkQ7QUFDQSxtQ0FBbUMsNkJBQTZCO0FBQ2hFO0FBQ0EsK0JBQStCO0FBQy9CLGlDQUFpQywrREFBZTtBQUNoRDtBQUNBO0FBQ0Esb0NBQW9DLHdFQUFhLHNCQUFzQix3RkFBd0Y7QUFDL0osOEJBQThCLCtEQUFhO0FBQzNDO0FBQ0Esd0NBQXdDLHdFQUFhLG1DQUFtQyxtUkFBbVIsRUFBRSwrREFBVTtBQUN2WDtBQUNBO0FBQ0E7QUFDQSxvQkFBb0Isd0VBQWEsWUFBWSx1REFBdUQ7QUFDcEcsZ0JBQWdCLHdFQUFhO0FBQzdCLG9CQUFvQix3RUFBYTtBQUNqQyx3QkFBd0Isd0VBQWEsU0FBUyxnQ0FBZ0M7QUFDOUUsd0JBQXdCLHdFQUFhLFNBQVMsbUNBQW1DO0FBQ2pGLHdCQUF3Qix3RUFBYSxTQUFTLGlDQUFpQztBQUMvRSxnQkFBZ0Isd0VBQWE7QUFDN0IsU0FBUztBQUNUO0FBQ0E7QUFDQSxzQ0FBc0MsK0RBQWU7QUFDckQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYyxVQUFVO0FBQ3hCLGNBQWMsbUJBQW1CO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJCQUEyQiw2QkFBNkI7QUFDeEQsdUJBQXVCLDhEQUFlO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQiw4REFBVTtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQiw4REFBTztBQUN4QixTQUFTO0FBQ1QsbUJBQW1CLDhEQUFPO0FBQzFCO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBLHdCQUF3QjtBQUN4QjtBQUNBO0FBQ0EsZ0JBQWdCLGlCQUFpQjtBQUNqQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRW9CIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vVnVleHkvLi9ub2RlX21vZHVsZXMvQGZ1bGxjYWxlbmRhci9saXN0L2ludGVybmFsLmVzbS5qcz9jYWUwIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEJhc2VDb21wb25lbnQsIGdldFVuaXF1ZURvbUlkLCBnZXREYXRlTWV0YSwgYnVpbGROYXZMaW5rQXR0cnMsIENvbnRlbnRDb250YWluZXIsIGdldERheUNsYXNzTmFtZXMsIGZvcm1hdERheVN0cmluZywgY3JlYXRlRm9ybWF0dGVyLCBFdmVudENvbnRhaW5lciwgZ2V0U2VnQW5jaG9yQXR0cnMsIGlzTXVsdGlEYXlSYW5nZSwgYnVpbGRTZWdUaW1lVGV4dCwgRGF0ZUNvbXBvbmVudCwgbWVtb2l6ZSwgVmlld0NvbnRhaW5lciwgU2Nyb2xsZXIsIE5vd1RpbWVyLCBzb3J0RXZlbnRTZWdzLCBnZXRTZWdNZXRhLCBzbGljZUV2ZW50U3RvcmUsIGludGVyc2VjdFJhbmdlcywgc3RhcnRPZkRheSwgYWRkRGF5cyB9IGZyb20gJ0BmdWxsY2FsZW5kYXIvY29yZS9pbnRlcm5hbCc7XG5pbXBvcnQgeyBjcmVhdGVFbGVtZW50LCBGcmFnbWVudCB9IGZyb20gJ0BmdWxsY2FsZW5kYXIvY29yZS9wcmVhY3QnO1xuXG5jbGFzcyBMaXN0Vmlld0hlYWRlclJvdyBleHRlbmRzIEJhc2VDb21wb25lbnQge1xuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuICAgICAgICB0aGlzLnN0YXRlID0ge1xuICAgICAgICAgICAgdGV4dElkOiBnZXRVbmlxdWVEb21JZCgpLFxuICAgICAgICB9O1xuICAgIH1cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGxldCB7IHRoZW1lLCBkYXRlRW52LCBvcHRpb25zLCB2aWV3QXBpIH0gPSB0aGlzLmNvbnRleHQ7XG4gICAgICAgIGxldCB7IGNlbGxJZCwgZGF5RGF0ZSwgdG9kYXlSYW5nZSB9ID0gdGhpcy5wcm9wcztcbiAgICAgICAgbGV0IHsgdGV4dElkIH0gPSB0aGlzLnN0YXRlO1xuICAgICAgICBsZXQgZGF5TWV0YSA9IGdldERhdGVNZXRhKGRheURhdGUsIHRvZGF5UmFuZ2UpO1xuICAgICAgICAvLyB3aWxsIGV2ZXIgYmUgZmFsc3k/XG4gICAgICAgIGxldCB0ZXh0ID0gb3B0aW9ucy5saXN0RGF5Rm9ybWF0ID8gZGF0ZUVudi5mb3JtYXQoZGF5RGF0ZSwgb3B0aW9ucy5saXN0RGF5Rm9ybWF0KSA6ICcnO1xuICAgICAgICAvLyB3aWxsIGV2ZXIgYmUgZmFsc3k/IGFsc28sIEJBRCBOQU1FIFwiYWx0XCJcbiAgICAgICAgbGV0IHNpZGVUZXh0ID0gb3B0aW9ucy5saXN0RGF5U2lkZUZvcm1hdCA/IGRhdGVFbnYuZm9ybWF0KGRheURhdGUsIG9wdGlvbnMubGlzdERheVNpZGVGb3JtYXQpIDogJyc7XG4gICAgICAgIGxldCByZW5kZXJQcm9wcyA9IE9iamVjdC5hc3NpZ24oeyBkYXRlOiBkYXRlRW52LnRvRGF0ZShkYXlEYXRlKSwgdmlldzogdmlld0FwaSwgdGV4dElkLFxuICAgICAgICAgICAgdGV4dCxcbiAgICAgICAgICAgIHNpZGVUZXh0LCBuYXZMaW5rQXR0cnM6IGJ1aWxkTmF2TGlua0F0dHJzKHRoaXMuY29udGV4dCwgZGF5RGF0ZSksIHNpZGVOYXZMaW5rQXR0cnM6IGJ1aWxkTmF2TGlua0F0dHJzKHRoaXMuY29udGV4dCwgZGF5RGF0ZSwgJ2RheScsIGZhbHNlKSB9LCBkYXlNZXRhKTtcbiAgICAgICAgLy8gVE9ETzogbWFrZSBhIHJldXNhYmxlIEhPQyBmb3IgZGF5SGVhZGVyICh1c2VkIGluIGRheWdyaWQvdGltZWdyaWQgdG9vKVxuICAgICAgICByZXR1cm4gKGNyZWF0ZUVsZW1lbnQoQ29udGVudENvbnRhaW5lciwgeyBlbFRhZzogXCJ0clwiLCBlbENsYXNzZXM6IFtcbiAgICAgICAgICAgICAgICAnZmMtbGlzdC1kYXknLFxuICAgICAgICAgICAgICAgIC4uLmdldERheUNsYXNzTmFtZXMoZGF5TWV0YSwgdGhlbWUpLFxuICAgICAgICAgICAgXSwgZWxBdHRyczoge1xuICAgICAgICAgICAgICAgICdkYXRhLWRhdGUnOiBmb3JtYXREYXlTdHJpbmcoZGF5RGF0ZSksXG4gICAgICAgICAgICB9LCByZW5kZXJQcm9wczogcmVuZGVyUHJvcHMsIGdlbmVyYXRvck5hbWU6IFwiZGF5SGVhZGVyQ29udGVudFwiLCBnZW5lcmF0b3I6IG9wdGlvbnMuZGF5SGVhZGVyQ29udGVudCB8fCByZW5kZXJJbm5lckNvbnRlbnQsIGNsYXNzTmFtZUdlbmVyYXRvcjogb3B0aW9ucy5kYXlIZWFkZXJDbGFzc05hbWVzLCBkaWRNb3VudDogb3B0aW9ucy5kYXlIZWFkZXJEaWRNb3VudCwgd2lsbFVubW91bnQ6IG9wdGlvbnMuZGF5SGVhZGVyV2lsbFVubW91bnQgfSwgKElubmVyQ29udGVudCkgPT4gKCAvLyBUT0RPOiBmb3JjZS1oaWRlIHRvcCBib3JkZXIgYmFzZWQgb24gOmZpcnN0LWNoaWxkXG4gICAgICAgIGNyZWF0ZUVsZW1lbnQoXCJ0aFwiLCB7IHNjb3BlOiBcImNvbGdyb3VwXCIsIGNvbFNwYW46IDMsIGlkOiBjZWxsSWQsIFwiYXJpYS1sYWJlbGxlZGJ5XCI6IHRleHRJZCB9LFxuICAgICAgICAgICAgY3JlYXRlRWxlbWVudChJbm5lckNvbnRlbnQsIHsgZWxUYWc6IFwiZGl2XCIsIGVsQ2xhc3NlczogW1xuICAgICAgICAgICAgICAgICAgICAnZmMtbGlzdC1kYXktY3VzaGlvbicsXG4gICAgICAgICAgICAgICAgICAgIHRoZW1lLmdldENsYXNzKCd0YWJsZUNlbGxTaGFkZWQnKSxcbiAgICAgICAgICAgICAgICBdIH0pKSkpKTtcbiAgICB9XG59XG5mdW5jdGlvbiByZW5kZXJJbm5lckNvbnRlbnQocHJvcHMpIHtcbiAgICByZXR1cm4gKGNyZWF0ZUVsZW1lbnQoRnJhZ21lbnQsIG51bGwsXG4gICAgICAgIHByb3BzLnRleHQgJiYgKGNyZWF0ZUVsZW1lbnQoXCJhXCIsIE9iamVjdC5hc3NpZ24oeyBpZDogcHJvcHMudGV4dElkLCBjbGFzc05hbWU6IFwiZmMtbGlzdC1kYXktdGV4dFwiIH0sIHByb3BzLm5hdkxpbmtBdHRycyksIHByb3BzLnRleHQpKSxcbiAgICAgICAgcHJvcHMuc2lkZVRleHQgJiYgKCAvKiBub3Qga2V5Ym9hcmQgdGFiYmFibGUgKi9jcmVhdGVFbGVtZW50KFwiYVwiLCBPYmplY3QuYXNzaWduKHsgXCJhcmlhLWhpZGRlblwiOiB0cnVlLCBjbGFzc05hbWU6IFwiZmMtbGlzdC1kYXktc2lkZS10ZXh0XCIgfSwgcHJvcHMuc2lkZU5hdkxpbmtBdHRycyksIHByb3BzLnNpZGVUZXh0KSkpKTtcbn1cblxuY29uc3QgREVGQVVMVF9USU1FX0ZPUk1BVCA9IGNyZWF0ZUZvcm1hdHRlcih7XG4gICAgaG91cjogJ251bWVyaWMnLFxuICAgIG1pbnV0ZTogJzItZGlnaXQnLFxuICAgIG1lcmlkaWVtOiAnc2hvcnQnLFxufSk7XG5jbGFzcyBMaXN0Vmlld0V2ZW50Um93IGV4dGVuZHMgQmFzZUNvbXBvbmVudCB7XG4gICAgcmVuZGVyKCkge1xuICAgICAgICBsZXQgeyBwcm9wcywgY29udGV4dCB9ID0gdGhpcztcbiAgICAgICAgbGV0IHsgb3B0aW9ucyB9ID0gY29udGV4dDtcbiAgICAgICAgbGV0IHsgc2VnLCB0aW1lSGVhZGVySWQsIGV2ZW50SGVhZGVySWQsIGRhdGVIZWFkZXJJZCB9ID0gcHJvcHM7XG4gICAgICAgIGxldCB0aW1lRm9ybWF0ID0gb3B0aW9ucy5ldmVudFRpbWVGb3JtYXQgfHwgREVGQVVMVF9USU1FX0ZPUk1BVDtcbiAgICAgICAgcmV0dXJuIChjcmVhdGVFbGVtZW50KEV2ZW50Q29udGFpbmVyLCBPYmplY3QuYXNzaWduKHt9LCBwcm9wcywgeyBlbFRhZzogXCJ0clwiLCBlbENsYXNzZXM6IFtcbiAgICAgICAgICAgICAgICAnZmMtbGlzdC1ldmVudCcsXG4gICAgICAgICAgICAgICAgc2VnLmV2ZW50UmFuZ2UuZGVmLnVybCAmJiAnZmMtZXZlbnQtZm9yY2VkLXVybCcsXG4gICAgICAgICAgICBdLCBkZWZhdWx0R2VuZXJhdG9yOiAoKSA9PiByZW5kZXJFdmVudElubmVyQ29udGVudChzZWcsIGNvbnRleHQpIC8qIHdlaXJkICovLCBzZWc6IHNlZywgdGltZVRleHQ6IFwiXCIsIGRpc2FibGVEcmFnZ2luZzogdHJ1ZSwgZGlzYWJsZVJlc2l6aW5nOiB0cnVlIH0pLCAoSW5uZXJDb250ZW50LCBldmVudENvbnRlbnRBcmcpID0+IChjcmVhdGVFbGVtZW50KEZyYWdtZW50LCBudWxsLFxuICAgICAgICAgICAgYnVpbGRUaW1lQ29udGVudChzZWcsIHRpbWVGb3JtYXQsIGNvbnRleHQsIHRpbWVIZWFkZXJJZCwgZGF0ZUhlYWRlcklkKSxcbiAgICAgICAgICAgIGNyZWF0ZUVsZW1lbnQoXCJ0ZFwiLCB7IFwiYXJpYS1oaWRkZW5cIjogdHJ1ZSwgY2xhc3NOYW1lOiBcImZjLWxpc3QtZXZlbnQtZ3JhcGhpY1wiIH0sXG4gICAgICAgICAgICAgICAgY3JlYXRlRWxlbWVudChcInNwYW5cIiwgeyBjbGFzc05hbWU6IFwiZmMtbGlzdC1ldmVudC1kb3RcIiwgc3R5bGU6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJvcmRlckNvbG9yOiBldmVudENvbnRlbnRBcmcuYm9yZGVyQ29sb3IgfHwgZXZlbnRDb250ZW50QXJnLmJhY2tncm91bmRDb2xvcixcbiAgICAgICAgICAgICAgICAgICAgfSB9KSksXG4gICAgICAgICAgICBjcmVhdGVFbGVtZW50KElubmVyQ29udGVudCwgeyBlbFRhZzogXCJ0ZFwiLCBlbENsYXNzZXM6IFsnZmMtbGlzdC1ldmVudC10aXRsZSddLCBlbEF0dHJzOiB7IGhlYWRlcnM6IGAke2V2ZW50SGVhZGVySWR9ICR7ZGF0ZUhlYWRlcklkfWAgfSB9KSkpKSk7XG4gICAgfVxufVxuZnVuY3Rpb24gcmVuZGVyRXZlbnRJbm5lckNvbnRlbnQoc2VnLCBjb250ZXh0KSB7XG4gICAgbGV0IGludGVyYWN0aXZlQXR0cnMgPSBnZXRTZWdBbmNob3JBdHRycyhzZWcsIGNvbnRleHQpO1xuICAgIHJldHVybiAoY3JlYXRlRWxlbWVudChcImFcIiwgT2JqZWN0LmFzc2lnbih7fSwgaW50ZXJhY3RpdmVBdHRycyksIHNlZy5ldmVudFJhbmdlLmRlZi50aXRsZSkpO1xufVxuZnVuY3Rpb24gYnVpbGRUaW1lQ29udGVudChzZWcsIHRpbWVGb3JtYXQsIGNvbnRleHQsIHRpbWVIZWFkZXJJZCwgZGF0ZUhlYWRlcklkKSB7XG4gICAgbGV0IHsgb3B0aW9ucyB9ID0gY29udGV4dDtcbiAgICBpZiAob3B0aW9ucy5kaXNwbGF5RXZlbnRUaW1lICE9PSBmYWxzZSkge1xuICAgICAgICBsZXQgZXZlbnREZWYgPSBzZWcuZXZlbnRSYW5nZS5kZWY7XG4gICAgICAgIGxldCBldmVudEluc3RhbmNlID0gc2VnLmV2ZW50UmFuZ2UuaW5zdGFuY2U7XG4gICAgICAgIGxldCBkb0FsbERheSA9IGZhbHNlO1xuICAgICAgICBsZXQgdGltZVRleHQ7XG4gICAgICAgIGlmIChldmVudERlZi5hbGxEYXkpIHtcbiAgICAgICAgICAgIGRvQWxsRGF5ID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChpc011bHRpRGF5UmFuZ2Uoc2VnLmV2ZW50UmFuZ2UucmFuZ2UpKSB7IC8vIFRPRE86IHVzZSAoIWlzU3RhcnQgfHwgIWlzRW5kKSBpbnN0ZWFkP1xuICAgICAgICAgICAgaWYgKHNlZy5pc1N0YXJ0KSB7XG4gICAgICAgICAgICAgICAgdGltZVRleHQgPSBidWlsZFNlZ1RpbWVUZXh0KHNlZywgdGltZUZvcm1hdCwgY29udGV4dCwgbnVsbCwgbnVsbCwgZXZlbnRJbnN0YW5jZS5yYW5nZS5zdGFydCwgc2VnLmVuZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChzZWcuaXNFbmQpIHtcbiAgICAgICAgICAgICAgICB0aW1lVGV4dCA9IGJ1aWxkU2VnVGltZVRleHQoc2VnLCB0aW1lRm9ybWF0LCBjb250ZXh0LCBudWxsLCBudWxsLCBzZWcuc3RhcnQsIGV2ZW50SW5zdGFuY2UucmFuZ2UuZW5kKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGRvQWxsRGF5ID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRpbWVUZXh0ID0gYnVpbGRTZWdUaW1lVGV4dChzZWcsIHRpbWVGb3JtYXQsIGNvbnRleHQpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChkb0FsbERheSkge1xuICAgICAgICAgICAgbGV0IHJlbmRlclByb3BzID0ge1xuICAgICAgICAgICAgICAgIHRleHQ6IGNvbnRleHQub3B0aW9ucy5hbGxEYXlUZXh0LFxuICAgICAgICAgICAgICAgIHZpZXc6IGNvbnRleHQudmlld0FwaSxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICByZXR1cm4gKGNyZWF0ZUVsZW1lbnQoQ29udGVudENvbnRhaW5lciwgeyBlbFRhZzogXCJ0ZFwiLCBlbENsYXNzZXM6IFsnZmMtbGlzdC1ldmVudC10aW1lJ10sIGVsQXR0cnM6IHtcbiAgICAgICAgICAgICAgICAgICAgaGVhZGVyczogYCR7dGltZUhlYWRlcklkfSAke2RhdGVIZWFkZXJJZH1gLFxuICAgICAgICAgICAgICAgIH0sIHJlbmRlclByb3BzOiByZW5kZXJQcm9wcywgZ2VuZXJhdG9yTmFtZTogXCJhbGxEYXlDb250ZW50XCIsIGdlbmVyYXRvcjogb3B0aW9ucy5hbGxEYXlDb250ZW50IHx8IHJlbmRlckFsbERheUlubmVyLCBjbGFzc05hbWVHZW5lcmF0b3I6IG9wdGlvbnMuYWxsRGF5Q2xhc3NOYW1lcywgZGlkTW91bnQ6IG9wdGlvbnMuYWxsRGF5RGlkTW91bnQsIHdpbGxVbm1vdW50OiBvcHRpb25zLmFsbERheVdpbGxVbm1vdW50IH0pKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gKGNyZWF0ZUVsZW1lbnQoXCJ0ZFwiLCB7IGNsYXNzTmFtZTogXCJmYy1saXN0LWV2ZW50LXRpbWVcIiB9LCB0aW1lVGV4dCkpO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbn1cbmZ1bmN0aW9uIHJlbmRlckFsbERheUlubmVyKHJlbmRlclByb3BzKSB7XG4gICAgcmV0dXJuIHJlbmRlclByb3BzLnRleHQ7XG59XG5cbi8qXG5SZXNwb25zaWJsZSBmb3IgdGhlIHNjcm9sbGVyLCBhbmQgZm9yd2FyZGluZyBldmVudC1yZWxhdGVkIGFjdGlvbnMgaW50byB0aGUgXCJncmlkXCIuXG4qL1xuY2xhc3MgTGlzdFZpZXcgZXh0ZW5kcyBEYXRlQ29tcG9uZW50IHtcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTtcbiAgICAgICAgdGhpcy5jb21wdXRlRGF0ZVZhcnMgPSBtZW1vaXplKGNvbXB1dGVEYXRlVmFycyk7XG4gICAgICAgIHRoaXMuZXZlbnRTdG9yZVRvU2VncyA9IG1lbW9pemUodGhpcy5fZXZlbnRTdG9yZVRvU2Vncyk7XG4gICAgICAgIHRoaXMuc3RhdGUgPSB7XG4gICAgICAgICAgICB0aW1lSGVhZGVySWQ6IGdldFVuaXF1ZURvbUlkKCksXG4gICAgICAgICAgICBldmVudEhlYWRlcklkOiBnZXRVbmlxdWVEb21JZCgpLFxuICAgICAgICAgICAgZGF0ZUhlYWRlcklkUm9vdDogZ2V0VW5pcXVlRG9tSWQoKSxcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5zZXRSb290RWwgPSAocm9vdEVsKSA9PiB7XG4gICAgICAgICAgICBpZiAocm9vdEVsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jb250ZXh0LnJlZ2lzdGVySW50ZXJhY3RpdmVDb21wb25lbnQodGhpcywge1xuICAgICAgICAgICAgICAgICAgICBlbDogcm9vdEVsLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jb250ZXh0LnVucmVnaXN0ZXJJbnRlcmFjdGl2ZUNvbXBvbmVudCh0aGlzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9XG4gICAgcmVuZGVyKCkge1xuICAgICAgICBsZXQgeyBwcm9wcywgY29udGV4dCB9ID0gdGhpcztcbiAgICAgICAgbGV0IHsgZGF5RGF0ZXMsIGRheVJhbmdlcyB9ID0gdGhpcy5jb21wdXRlRGF0ZVZhcnMocHJvcHMuZGF0ZVByb2ZpbGUpO1xuICAgICAgICBsZXQgZXZlbnRTZWdzID0gdGhpcy5ldmVudFN0b3JlVG9TZWdzKHByb3BzLmV2ZW50U3RvcmUsIHByb3BzLmV2ZW50VWlCYXNlcywgZGF5UmFuZ2VzKTtcbiAgICAgICAgcmV0dXJuIChjcmVhdGVFbGVtZW50KFZpZXdDb250YWluZXIsIHsgZWxSZWY6IHRoaXMuc2V0Um9vdEVsLCBlbENsYXNzZXM6IFtcbiAgICAgICAgICAgICAgICAnZmMtbGlzdCcsXG4gICAgICAgICAgICAgICAgY29udGV4dC50aGVtZS5nZXRDbGFzcygndGFibGUnKSxcbiAgICAgICAgICAgICAgICBjb250ZXh0Lm9wdGlvbnMuc3RpY2t5SGVhZGVyRGF0ZXMgIT09IGZhbHNlID9cbiAgICAgICAgICAgICAgICAgICAgJ2ZjLWxpc3Qtc3RpY2t5JyA6XG4gICAgICAgICAgICAgICAgICAgICcnLFxuICAgICAgICAgICAgXSwgdmlld1NwZWM6IGNvbnRleHQudmlld1NwZWMgfSxcbiAgICAgICAgICAgIGNyZWF0ZUVsZW1lbnQoU2Nyb2xsZXIsIHsgbGlxdWlkOiAhcHJvcHMuaXNIZWlnaHRBdXRvLCBvdmVyZmxvd1g6IHByb3BzLmlzSGVpZ2h0QXV0byA/ICd2aXNpYmxlJyA6ICdoaWRkZW4nLCBvdmVyZmxvd1k6IHByb3BzLmlzSGVpZ2h0QXV0byA/ICd2aXNpYmxlJyA6ICdhdXRvJyB9LCBldmVudFNlZ3MubGVuZ3RoID4gMCA/XG4gICAgICAgICAgICAgICAgdGhpcy5yZW5kZXJTZWdMaXN0KGV2ZW50U2VncywgZGF5RGF0ZXMpIDpcbiAgICAgICAgICAgICAgICB0aGlzLnJlbmRlckVtcHR5TWVzc2FnZSgpKSkpO1xuICAgIH1cbiAgICByZW5kZXJFbXB0eU1lc3NhZ2UoKSB7XG4gICAgICAgIGxldCB7IG9wdGlvbnMsIHZpZXdBcGkgfSA9IHRoaXMuY29udGV4dDtcbiAgICAgICAgbGV0IHJlbmRlclByb3BzID0ge1xuICAgICAgICAgICAgdGV4dDogb3B0aW9ucy5ub0V2ZW50c1RleHQsXG4gICAgICAgICAgICB2aWV3OiB2aWV3QXBpLFxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gKGNyZWF0ZUVsZW1lbnQoQ29udGVudENvbnRhaW5lciwgeyBlbFRhZzogXCJkaXZcIiwgZWxDbGFzc2VzOiBbJ2ZjLWxpc3QtZW1wdHknXSwgcmVuZGVyUHJvcHM6IHJlbmRlclByb3BzLCBnZW5lcmF0b3JOYW1lOiBcIm5vRXZlbnRzQ29udGVudFwiLCBnZW5lcmF0b3I6IG9wdGlvbnMubm9FdmVudHNDb250ZW50IHx8IHJlbmRlck5vRXZlbnRzSW5uZXIsIGNsYXNzTmFtZUdlbmVyYXRvcjogb3B0aW9ucy5ub0V2ZW50c0NsYXNzTmFtZXMsIGRpZE1vdW50OiBvcHRpb25zLm5vRXZlbnRzRGlkTW91bnQsIHdpbGxVbm1vdW50OiBvcHRpb25zLm5vRXZlbnRzV2lsbFVubW91bnQgfSwgKElubmVyQ29udGVudCkgPT4gKGNyZWF0ZUVsZW1lbnQoSW5uZXJDb250ZW50LCB7IGVsVGFnOiBcImRpdlwiLCBlbENsYXNzZXM6IFsnZmMtbGlzdC1lbXB0eS1jdXNoaW9uJ10gfSkpKSk7XG4gICAgfVxuICAgIHJlbmRlclNlZ0xpc3QoYWxsU2VncywgZGF5RGF0ZXMpIHtcbiAgICAgICAgbGV0IHsgdGhlbWUsIG9wdGlvbnMgfSA9IHRoaXMuY29udGV4dDtcbiAgICAgICAgbGV0IHsgdGltZUhlYWRlcklkLCBldmVudEhlYWRlcklkLCBkYXRlSGVhZGVySWRSb290IH0gPSB0aGlzLnN0YXRlO1xuICAgICAgICBsZXQgc2Vnc0J5RGF5ID0gZ3JvdXBTZWdzQnlEYXkoYWxsU2Vncyk7IC8vIHNwYXJzZSBhcnJheVxuICAgICAgICByZXR1cm4gKGNyZWF0ZUVsZW1lbnQoTm93VGltZXIsIHsgdW5pdDogXCJkYXlcIiB9LCAobm93RGF0ZSwgdG9kYXlSYW5nZSkgPT4ge1xuICAgICAgICAgICAgbGV0IGlubmVyTm9kZXMgPSBbXTtcbiAgICAgICAgICAgIGZvciAobGV0IGRheUluZGV4ID0gMDsgZGF5SW5kZXggPCBzZWdzQnlEYXkubGVuZ3RoOyBkYXlJbmRleCArPSAxKSB7XG4gICAgICAgICAgICAgICAgbGV0IGRheVNlZ3MgPSBzZWdzQnlEYXlbZGF5SW5kZXhdO1xuICAgICAgICAgICAgICAgIGlmIChkYXlTZWdzKSB7IC8vIHNwYXJzZSBhcnJheSwgc28gbWlnaHQgYmUgdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgIGxldCBkYXlTdHIgPSBmb3JtYXREYXlTdHJpbmcoZGF5RGF0ZXNbZGF5SW5kZXhdKTtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGRhdGVIZWFkZXJJZCA9IGRhdGVIZWFkZXJJZFJvb3QgKyAnLScgKyBkYXlTdHI7XG4gICAgICAgICAgICAgICAgICAgIC8vIGFwcGVuZCBhIGRheSBoZWFkZXJcbiAgICAgICAgICAgICAgICAgICAgaW5uZXJOb2Rlcy5wdXNoKGNyZWF0ZUVsZW1lbnQoTGlzdFZpZXdIZWFkZXJSb3csIHsga2V5OiBkYXlTdHIsIGNlbGxJZDogZGF0ZUhlYWRlcklkLCBkYXlEYXRlOiBkYXlEYXRlc1tkYXlJbmRleF0sIHRvZGF5UmFuZ2U6IHRvZGF5UmFuZ2UgfSkpO1xuICAgICAgICAgICAgICAgICAgICBkYXlTZWdzID0gc29ydEV2ZW50U2VncyhkYXlTZWdzLCBvcHRpb25zLmV2ZW50T3JkZXIpO1xuICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBzZWcgb2YgZGF5U2Vncykge1xuICAgICAgICAgICAgICAgICAgICAgICAgaW5uZXJOb2Rlcy5wdXNoKGNyZWF0ZUVsZW1lbnQoTGlzdFZpZXdFdmVudFJvdywgT2JqZWN0LmFzc2lnbih7IGtleTogZGF5U3RyICsgJzonICsgc2VnLmV2ZW50UmFuZ2UuaW5zdGFuY2UuaW5zdGFuY2VJZCAvKiBhcmUgbXVsdGlwbGUgc2VncyBmb3IgYW4gaW5zdGFuY2VJZCAqLywgc2VnOiBzZWcsIGlzRHJhZ2dpbmc6IGZhbHNlLCBpc1Jlc2l6aW5nOiBmYWxzZSwgaXNEYXRlU2VsZWN0aW5nOiBmYWxzZSwgaXNTZWxlY3RlZDogZmFsc2UsIHRpbWVIZWFkZXJJZDogdGltZUhlYWRlcklkLCBldmVudEhlYWRlcklkOiBldmVudEhlYWRlcklkLCBkYXRlSGVhZGVySWQ6IGRhdGVIZWFkZXJJZCB9LCBnZXRTZWdNZXRhKHNlZywgdG9kYXlSYW5nZSwgbm93RGF0ZSkpKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gKGNyZWF0ZUVsZW1lbnQoXCJ0YWJsZVwiLCB7IGNsYXNzTmFtZTogJ2ZjLWxpc3QtdGFibGUgJyArIHRoZW1lLmdldENsYXNzKCd0YWJsZScpIH0sXG4gICAgICAgICAgICAgICAgY3JlYXRlRWxlbWVudChcInRoZWFkXCIsIG51bGwsXG4gICAgICAgICAgICAgICAgICAgIGNyZWF0ZUVsZW1lbnQoXCJ0clwiLCBudWxsLFxuICAgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlRWxlbWVudChcInRoXCIsIHsgc2NvcGU6IFwiY29sXCIsIGlkOiB0aW1lSGVhZGVySWQgfSwgb3B0aW9ucy50aW1lSGludCksXG4gICAgICAgICAgICAgICAgICAgICAgICBjcmVhdGVFbGVtZW50KFwidGhcIiwgeyBzY29wZTogXCJjb2xcIiwgXCJhcmlhLWhpZGRlblwiOiB0cnVlIH0pLFxuICAgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlRWxlbWVudChcInRoXCIsIHsgc2NvcGU6IFwiY29sXCIsIGlkOiBldmVudEhlYWRlcklkIH0sIG9wdGlvbnMuZXZlbnRIaW50KSkpLFxuICAgICAgICAgICAgICAgIGNyZWF0ZUVsZW1lbnQoXCJ0Ym9keVwiLCBudWxsLCBpbm5lck5vZGVzKSkpO1xuICAgICAgICB9KSk7XG4gICAgfVxuICAgIF9ldmVudFN0b3JlVG9TZWdzKGV2ZW50U3RvcmUsIGV2ZW50VWlCYXNlcywgZGF5UmFuZ2VzKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmV2ZW50UmFuZ2VzVG9TZWdzKHNsaWNlRXZlbnRTdG9yZShldmVudFN0b3JlLCBldmVudFVpQmFzZXMsIHRoaXMucHJvcHMuZGF0ZVByb2ZpbGUuYWN0aXZlUmFuZ2UsIHRoaXMuY29udGV4dC5vcHRpb25zLm5leHREYXlUaHJlc2hvbGQpLmZnLCBkYXlSYW5nZXMpO1xuICAgIH1cbiAgICBldmVudFJhbmdlc1RvU2VncyhldmVudFJhbmdlcywgZGF5UmFuZ2VzKSB7XG4gICAgICAgIGxldCBzZWdzID0gW107XG4gICAgICAgIGZvciAobGV0IGV2ZW50UmFuZ2Ugb2YgZXZlbnRSYW5nZXMpIHtcbiAgICAgICAgICAgIHNlZ3MucHVzaCguLi50aGlzLmV2ZW50UmFuZ2VUb1NlZ3MoZXZlbnRSYW5nZSwgZGF5UmFuZ2VzKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHNlZ3M7XG4gICAgfVxuICAgIGV2ZW50UmFuZ2VUb1NlZ3MoZXZlbnRSYW5nZSwgZGF5UmFuZ2VzKSB7XG4gICAgICAgIGxldCB7IGRhdGVFbnYgfSA9IHRoaXMuY29udGV4dDtcbiAgICAgICAgbGV0IHsgbmV4dERheVRocmVzaG9sZCB9ID0gdGhpcy5jb250ZXh0Lm9wdGlvbnM7XG4gICAgICAgIGxldCByYW5nZSA9IGV2ZW50UmFuZ2UucmFuZ2U7XG4gICAgICAgIGxldCBhbGxEYXkgPSBldmVudFJhbmdlLmRlZi5hbGxEYXk7XG4gICAgICAgIGxldCBkYXlJbmRleDtcbiAgICAgICAgbGV0IHNlZ1JhbmdlO1xuICAgICAgICBsZXQgc2VnO1xuICAgICAgICBsZXQgc2VncyA9IFtdO1xuICAgICAgICBmb3IgKGRheUluZGV4ID0gMDsgZGF5SW5kZXggPCBkYXlSYW5nZXMubGVuZ3RoOyBkYXlJbmRleCArPSAxKSB7XG4gICAgICAgICAgICBzZWdSYW5nZSA9IGludGVyc2VjdFJhbmdlcyhyYW5nZSwgZGF5UmFuZ2VzW2RheUluZGV4XSk7XG4gICAgICAgICAgICBpZiAoc2VnUmFuZ2UpIHtcbiAgICAgICAgICAgICAgICBzZWcgPSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudDogdGhpcyxcbiAgICAgICAgICAgICAgICAgICAgZXZlbnRSYW5nZSxcbiAgICAgICAgICAgICAgICAgICAgc3RhcnQ6IHNlZ1JhbmdlLnN0YXJ0LFxuICAgICAgICAgICAgICAgICAgICBlbmQ6IHNlZ1JhbmdlLmVuZCxcbiAgICAgICAgICAgICAgICAgICAgaXNTdGFydDogZXZlbnRSYW5nZS5pc1N0YXJ0ICYmIHNlZ1JhbmdlLnN0YXJ0LnZhbHVlT2YoKSA9PT0gcmFuZ2Uuc3RhcnQudmFsdWVPZigpLFxuICAgICAgICAgICAgICAgICAgICBpc0VuZDogZXZlbnRSYW5nZS5pc0VuZCAmJiBzZWdSYW5nZS5lbmQudmFsdWVPZigpID09PSByYW5nZS5lbmQudmFsdWVPZigpLFxuICAgICAgICAgICAgICAgICAgICBkYXlJbmRleCxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHNlZ3MucHVzaChzZWcpO1xuICAgICAgICAgICAgICAgIC8vIGRldGVjdCB3aGVuIHJhbmdlIHdvbid0IGdvIGZ1bGx5IGludG8gdGhlIG5leHQgZGF5LFxuICAgICAgICAgICAgICAgIC8vIGFuZCBtdXRhdGUgdGhlIGxhdGVzdCBzZWcgdG8gdGhlIGJlIHRoZSBlbmQuXG4gICAgICAgICAgICAgICAgaWYgKCFzZWcuaXNFbmQgJiYgIWFsbERheSAmJlxuICAgICAgICAgICAgICAgICAgICBkYXlJbmRleCArIDEgPCBkYXlSYW5nZXMubGVuZ3RoICYmXG4gICAgICAgICAgICAgICAgICAgIHJhbmdlLmVuZCA8XG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRlRW52LmFkZChkYXlSYW5nZXNbZGF5SW5kZXggKyAxXS5zdGFydCwgbmV4dERheVRocmVzaG9sZCkpIHtcbiAgICAgICAgICAgICAgICAgICAgc2VnLmVuZCA9IHJhbmdlLmVuZDtcbiAgICAgICAgICAgICAgICAgICAgc2VnLmlzRW5kID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzZWdzO1xuICAgIH1cbn1cbmZ1bmN0aW9uIHJlbmRlck5vRXZlbnRzSW5uZXIocmVuZGVyUHJvcHMpIHtcbiAgICByZXR1cm4gcmVuZGVyUHJvcHMudGV4dDtcbn1cbmZ1bmN0aW9uIGNvbXB1dGVEYXRlVmFycyhkYXRlUHJvZmlsZSkge1xuICAgIGxldCBkYXlTdGFydCA9IHN0YXJ0T2ZEYXkoZGF0ZVByb2ZpbGUucmVuZGVyUmFuZ2Uuc3RhcnQpO1xuICAgIGxldCB2aWV3RW5kID0gZGF0ZVByb2ZpbGUucmVuZGVyUmFuZ2UuZW5kO1xuICAgIGxldCBkYXlEYXRlcyA9IFtdO1xuICAgIGxldCBkYXlSYW5nZXMgPSBbXTtcbiAgICB3aGlsZSAoZGF5U3RhcnQgPCB2aWV3RW5kKSB7XG4gICAgICAgIGRheURhdGVzLnB1c2goZGF5U3RhcnQpO1xuICAgICAgICBkYXlSYW5nZXMucHVzaCh7XG4gICAgICAgICAgICBzdGFydDogZGF5U3RhcnQsXG4gICAgICAgICAgICBlbmQ6IGFkZERheXMoZGF5U3RhcnQsIDEpLFxuICAgICAgICB9KTtcbiAgICAgICAgZGF5U3RhcnQgPSBhZGREYXlzKGRheVN0YXJ0LCAxKTtcbiAgICB9XG4gICAgcmV0dXJuIHsgZGF5RGF0ZXMsIGRheVJhbmdlcyB9O1xufVxuLy8gUmV0dXJucyBhIHNwYXJzZSBhcnJheSBvZiBhcnJheXMsIHNlZ3MgZ3JvdXBlZCBieSB0aGVpciBkYXlJbmRleFxuZnVuY3Rpb24gZ3JvdXBTZWdzQnlEYXkoc2Vncykge1xuICAgIGxldCBzZWdzQnlEYXkgPSBbXTsgLy8gc3BhcnNlIGFycmF5XG4gICAgbGV0IGk7XG4gICAgbGV0IHNlZztcbiAgICBmb3IgKGkgPSAwOyBpIDwgc2Vncy5sZW5ndGg7IGkgKz0gMSkge1xuICAgICAgICBzZWcgPSBzZWdzW2ldO1xuICAgICAgICAoc2Vnc0J5RGF5W3NlZy5kYXlJbmRleF0gfHwgKHNlZ3NCeURheVtzZWcuZGF5SW5kZXhdID0gW10pKVxuICAgICAgICAgICAgLnB1c2goc2VnKTtcbiAgICB9XG4gICAgcmV0dXJuIHNlZ3NCeURheTtcbn1cblxuZXhwb3J0IHsgTGlzdFZpZXcgfTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/@fullcalendar/list/internal.esm.js\n"); /***/ }), /***/ "./node_modules/@fullcalendar/timegrid/index.esm.js": /*!**********************************************************!*\ !*** ./node_modules/@fullcalendar/timegrid/index.esm.js ***! \**********************************************************/ /***/ (function(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) { eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": function() { return /* binding */ index; }\n/* harmony export */ });\n/* harmony import */ var _fullcalendar_core__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @fullcalendar/core */ \"./node_modules/@fullcalendar/core/index.esm.js\");\n/* harmony import */ var _internal_esm_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./internal.esm.js */ \"./node_modules/@fullcalendar/timegrid/internal.esm.js\");\n/* harmony import */ var _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @fullcalendar/core/internal */ \"./node_modules/@fullcalendar/core/internal-common.esm.js\");\n\n\n\n\n\n\nconst OPTION_REFINERS = {\n allDaySlot: Boolean,\n};\n\nvar css_248z = \".fc-v-event{background-color:var(--fc-event-bg-color);border:1px solid var(--fc-event-border-color);display:block}.fc-v-event .fc-event-main{color:var(--fc-event-text-color);height:100%}.fc-v-event .fc-event-main-frame{display:flex;flex-direction:column;height:100%}.fc-v-event .fc-event-time{flex-grow:0;flex-shrink:0;max-height:100%;overflow:hidden}.fc-v-event .fc-event-title-container{flex-grow:1;flex-shrink:1;min-height:0}.fc-v-event .fc-event-title{bottom:0;max-height:100%;overflow:hidden;top:0}.fc-v-event:not(.fc-event-start){border-top-left-radius:0;border-top-right-radius:0;border-top-width:0}.fc-v-event:not(.fc-event-end){border-bottom-left-radius:0;border-bottom-right-radius:0;border-bottom-width:0}.fc-v-event.fc-event-selected:before{left:-10px;right:-10px}.fc-v-event .fc-event-resizer-start{cursor:n-resize}.fc-v-event .fc-event-resizer-end{cursor:s-resize}.fc-v-event:not(.fc-event-selected) .fc-event-resizer{height:var(--fc-event-resizer-thickness);left:0;right:0}.fc-v-event:not(.fc-event-selected) .fc-event-resizer-start{top:calc(var(--fc-event-resizer-thickness)/-2)}.fc-v-event:not(.fc-event-selected) .fc-event-resizer-end{bottom:calc(var(--fc-event-resizer-thickness)/-2)}.fc-v-event.fc-event-selected .fc-event-resizer{left:50%;margin-left:calc(var(--fc-event-resizer-dot-total-width)/-2)}.fc-v-event.fc-event-selected .fc-event-resizer-start{top:calc(var(--fc-event-resizer-dot-total-width)/-2)}.fc-v-event.fc-event-selected .fc-event-resizer-end{bottom:calc(var(--fc-event-resizer-dot-total-width)/-2)}.fc .fc-timegrid .fc-daygrid-body{z-index:2}.fc .fc-timegrid-divider{padding:0 0 2px}.fc .fc-timegrid-body{min-height:100%;position:relative;z-index:1}.fc .fc-timegrid-axis-chunk{position:relative}.fc .fc-timegrid-axis-chunk>table,.fc .fc-timegrid-slots{position:relative;z-index:1}.fc .fc-timegrid-slot{border-bottom:0;height:1.5em}.fc .fc-timegrid-slot:empty:before{content:\\\"\\\\00a0\\\"}.fc .fc-timegrid-slot-minor{border-top-style:dotted}.fc .fc-timegrid-slot-label-cushion{display:inline-block;white-space:nowrap}.fc .fc-timegrid-slot-label{vertical-align:middle}.fc .fc-timegrid-axis-cushion,.fc .fc-timegrid-slot-label-cushion{padding:0 4px}.fc .fc-timegrid-axis-frame-liquid{height:100%}.fc .fc-timegrid-axis-frame{align-items:center;display:flex;justify-content:flex-end;overflow:hidden}.fc .fc-timegrid-axis-cushion{flex-shrink:0;max-width:60px}.fc-direction-ltr .fc-timegrid-slot-label-frame{text-align:right}.fc-direction-rtl .fc-timegrid-slot-label-frame{text-align:left}.fc-liquid-hack .fc-timegrid-axis-frame-liquid{bottom:0;height:auto;left:0;position:absolute;right:0;top:0}.fc .fc-timegrid-col.fc-day-today{background-color:var(--fc-today-bg-color)}.fc .fc-timegrid-col-frame{min-height:100%;position:relative}.fc-media-screen.fc-liquid-hack .fc-timegrid-col-frame{bottom:0;height:auto;left:0;position:absolute;right:0;top:0}.fc-media-screen .fc-timegrid-cols{bottom:0;left:0;position:absolute;right:0;top:0}.fc-media-screen .fc-timegrid-cols>table{height:100%}.fc-media-screen .fc-timegrid-col-bg,.fc-media-screen .fc-timegrid-col-events,.fc-media-screen .fc-timegrid-now-indicator-container{left:0;position:absolute;right:0;top:0}.fc .fc-timegrid-col-bg{z-index:2}.fc .fc-timegrid-col-bg .fc-non-business{z-index:1}.fc .fc-timegrid-col-bg .fc-bg-event{z-index:2}.fc .fc-timegrid-col-bg .fc-highlight{z-index:3}.fc .fc-timegrid-bg-harness{left:0;position:absolute;right:0}.fc .fc-timegrid-col-events{z-index:3}.fc .fc-timegrid-now-indicator-container{bottom:0;overflow:hidden}.fc-direction-ltr .fc-timegrid-col-events{margin:0 2.5% 0 2px}.fc-direction-rtl .fc-timegrid-col-events{margin:0 2px 0 2.5%}.fc-timegrid-event-harness{position:absolute}.fc-timegrid-event-harness>.fc-timegrid-event{bottom:0;left:0;position:absolute;right:0;top:0}.fc-timegrid-event-harness-inset .fc-timegrid-event,.fc-timegrid-event.fc-event-mirror,.fc-timegrid-more-link{box-shadow:0 0 0 1px var(--fc-page-bg-color)}.fc-timegrid-event,.fc-timegrid-more-link{border-radius:3px;font-size:var(--fc-small-font-size)}.fc-timegrid-event{margin-bottom:1px}.fc-timegrid-event .fc-event-main{padding:1px 1px 0}.fc-timegrid-event .fc-event-time{font-size:var(--fc-small-font-size);margin-bottom:1px;white-space:nowrap}.fc-timegrid-event-short .fc-event-main-frame{flex-direction:row;overflow:hidden}.fc-timegrid-event-short .fc-event-time:after{content:\\\"\\\\00a0-\\\\00a0\\\"}.fc-timegrid-event-short .fc-event-title{font-size:var(--fc-small-font-size)}.fc-timegrid-more-link{background:var(--fc-more-link-bg-color);color:var(--fc-more-link-text-color);cursor:pointer;margin-bottom:1px;position:absolute;z-index:9999}.fc-timegrid-more-link-inner{padding:3px 2px;top:0}.fc-direction-ltr .fc-timegrid-more-link{right:0}.fc-direction-rtl .fc-timegrid-more-link{left:0}.fc .fc-timegrid-now-indicator-line{border-color:var(--fc-now-indicator-color);border-style:solid;border-width:1px 0 0;left:0;position:absolute;right:0;z-index:4}.fc .fc-timegrid-now-indicator-arrow{border-color:var(--fc-now-indicator-color);border-style:solid;margin-top:-5px;position:absolute;z-index:4}.fc-direction-ltr .fc-timegrid-now-indicator-arrow{border-bottom-color:transparent;border-top-color:transparent;border-width:5px 0 5px 6px;left:0}.fc-direction-rtl .fc-timegrid-now-indicator-arrow{border-bottom-color:transparent;border-top-color:transparent;border-width:5px 6px 5px 0;right:0}\";\n(0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.i)(css_248z);\n\nvar index = (0,_fullcalendar_core__WEBPACK_IMPORTED_MODULE_1__.createPlugin)({\n name: '@fullcalendar/timegrid',\n initialView: 'timeGridWeek',\n optionRefiners: OPTION_REFINERS,\n views: {\n timeGrid: {\n component: _internal_esm_js__WEBPACK_IMPORTED_MODULE_2__.DayTimeColsView,\n usesMinMaxTime: true,\n allDaySlot: true,\n slotDuration: '00:30:00',\n slotEventOverlap: true, // a bad name. confused with overlap/constraint system\n },\n timeGridDay: {\n type: 'timeGrid',\n duration: { days: 1 },\n },\n timeGridWeek: {\n type: 'timeGrid',\n duration: { weeks: 1 },\n },\n },\n});\n\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvQGZ1bGxjYWxlbmRhci90aW1lZ3JpZC9pbmRleC5lc20uanMuanMiLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQUFrRDtBQUNFO0FBQ087QUFDeEI7QUFDSzs7QUFFeEM7QUFDQTtBQUNBOztBQUVBLDRCQUE0QiwwQ0FBMEMsOENBQThDLGNBQWMsMkJBQTJCLGlDQUFpQyxZQUFZLGlDQUFpQyxhQUFhLHNCQUFzQixZQUFZLDJCQUEyQixZQUFZLGNBQWMsZ0JBQWdCLGdCQUFnQixzQ0FBc0MsWUFBWSxjQUFjLGFBQWEsNEJBQTRCLFNBQVMsZ0JBQWdCLGdCQUFnQixNQUFNLGlDQUFpQyx5QkFBeUIsMEJBQTBCLG1CQUFtQiwrQkFBK0IsNEJBQTRCLDZCQUE2QixzQkFBc0IscUNBQXFDLFdBQVcsWUFBWSxvQ0FBb0MsZ0JBQWdCLGtDQUFrQyxnQkFBZ0Isc0RBQXNELHlDQUF5QyxPQUFPLFFBQVEsNERBQTRELCtDQUErQywwREFBMEQsa0RBQWtELGdEQUFnRCxTQUFTLDZEQUE2RCxzREFBc0QscURBQXFELG9EQUFvRCx3REFBd0Qsa0NBQWtDLFVBQVUseUJBQXlCLGdCQUFnQixzQkFBc0IsZ0JBQWdCLGtCQUFrQixVQUFVLDRCQUE0QixrQkFBa0IseURBQXlELGtCQUFrQixVQUFVLHNCQUFzQixnQkFBZ0IsYUFBYSxtQ0FBbUMsbUJBQW1CLDRCQUE0Qix3QkFBd0Isb0NBQW9DLHFCQUFxQixtQkFBbUIsNEJBQTRCLHNCQUFzQixrRUFBa0UsY0FBYyxtQ0FBbUMsWUFBWSw0QkFBNEIsbUJBQW1CLGFBQWEseUJBQXlCLGdCQUFnQiw4QkFBOEIsY0FBYyxlQUFlLGdEQUFnRCxpQkFBaUIsZ0RBQWdELGdCQUFnQiwrQ0FBK0MsU0FBUyxZQUFZLE9BQU8sa0JBQWtCLFFBQVEsTUFBTSxrQ0FBa0MsMENBQTBDLDJCQUEyQixnQkFBZ0Isa0JBQWtCLHVEQUF1RCxTQUFTLFlBQVksT0FBTyxrQkFBa0IsUUFBUSxNQUFNLG1DQUFtQyxTQUFTLE9BQU8sa0JBQWtCLFFBQVEsTUFBTSx5Q0FBeUMsWUFBWSxvSUFBb0ksT0FBTyxrQkFBa0IsUUFBUSxNQUFNLHdCQUF3QixVQUFVLHlDQUF5QyxVQUFVLHFDQUFxQyxVQUFVLHNDQUFzQyxVQUFVLDRCQUE0QixPQUFPLGtCQUFrQixRQUFRLDRCQUE0QixVQUFVLHlDQUF5QyxTQUFTLGdCQUFnQiwwQ0FBMEMsb0JBQW9CLDBDQUEwQyxvQkFBb0IsMkJBQTJCLGtCQUFrQiw4Q0FBOEMsU0FBUyxPQUFPLGtCQUFrQixRQUFRLE1BQU0sOEdBQThHLDZDQUE2QywwQ0FBMEMsa0JBQWtCLG9DQUFvQyxtQkFBbUIsa0JBQWtCLGtDQUFrQyxrQkFBa0Isa0NBQWtDLG9DQUFvQyxrQkFBa0IsbUJBQW1CLDhDQUE4QyxtQkFBbUIsZ0JBQWdCLDhDQUE4QywwQkFBMEIseUNBQXlDLG9DQUFvQyx1QkFBdUIsd0NBQXdDLHFDQUFxQyxlQUFlLGtCQUFrQixrQkFBa0IsYUFBYSw2QkFBNkIsZ0JBQWdCLE1BQU0seUNBQXlDLFFBQVEseUNBQXlDLE9BQU8sb0NBQW9DLDJDQUEyQyxtQkFBbUIscUJBQXFCLE9BQU8sa0JBQWtCLFFBQVEsVUFBVSxxQ0FBcUMsMkNBQTJDLG1CQUFtQixnQkFBZ0Isa0JBQWtCLFVBQVUsbURBQW1ELGdDQUFnQyw2QkFBNkIsMkJBQTJCLE9BQU8sbURBQW1ELGdDQUFnQyw2QkFBNkIsMkJBQTJCLFFBQVE7QUFDbHhLLDhEQUFZOztBQUVaLFlBQVksZ0VBQVk7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVCQUF1Qiw2REFBZTtBQUN0QztBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0Esd0JBQXdCLFNBQVM7QUFDakMsU0FBUztBQUNUO0FBQ0E7QUFDQSx3QkFBd0IsVUFBVTtBQUNsQyxTQUFTO0FBQ1QsS0FBSztBQUNMLENBQUM7O0FBRTJCIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vVnVleHkvLi9ub2RlX21vZHVsZXMvQGZ1bGxjYWxlbmRhci90aW1lZ3JpZC9pbmRleC5lc20uanM/YjFhOCJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBjcmVhdGVQbHVnaW4gfSBmcm9tICdAZnVsbGNhbGVuZGFyL2NvcmUnO1xuaW1wb3J0IHsgRGF5VGltZUNvbHNWaWV3IH0gZnJvbSAnLi9pbnRlcm5hbC5lc20uanMnO1xuaW1wb3J0IHsgaW5qZWN0U3R5bGVzIH0gZnJvbSAnQGZ1bGxjYWxlbmRhci9jb3JlL2ludGVybmFsJztcbmltcG9ydCAnQGZ1bGxjYWxlbmRhci9jb3JlL3ByZWFjdCc7XG5pbXBvcnQgJ0BmdWxsY2FsZW5kYXIvZGF5Z3JpZC9pbnRlcm5hbCc7XG5cbmNvbnN0IE9QVElPTl9SRUZJTkVSUyA9IHtcbiAgICBhbGxEYXlTbG90OiBCb29sZWFuLFxufTtcblxudmFyIGNzc18yNDh6ID0gXCIuZmMtdi1ldmVudHtiYWNrZ3JvdW5kLWNvbG9yOnZhcigtLWZjLWV2ZW50LWJnLWNvbG9yKTtib3JkZXI6MXB4IHNvbGlkIHZhcigtLWZjLWV2ZW50LWJvcmRlci1jb2xvcik7ZGlzcGxheTpibG9ja30uZmMtdi1ldmVudCAuZmMtZXZlbnQtbWFpbntjb2xvcjp2YXIoLS1mYy1ldmVudC10ZXh0LWNvbG9yKTtoZWlnaHQ6MTAwJX0uZmMtdi1ldmVudCAuZmMtZXZlbnQtbWFpbi1mcmFtZXtkaXNwbGF5OmZsZXg7ZmxleC1kaXJlY3Rpb246Y29sdW1uO2hlaWdodDoxMDAlfS5mYy12LWV2ZW50IC5mYy1ldmVudC10aW1le2ZsZXgtZ3JvdzowO2ZsZXgtc2hyaW5rOjA7bWF4LWhlaWdodDoxMDAlO292ZXJmbG93OmhpZGRlbn0uZmMtdi1ldmVudCAuZmMtZXZlbnQtdGl0bGUtY29udGFpbmVye2ZsZXgtZ3JvdzoxO2ZsZXgtc2hyaW5rOjE7bWluLWhlaWdodDowfS5mYy12LWV2ZW50IC5mYy1ldmVudC10aXRsZXtib3R0b206MDttYXgtaGVpZ2h0OjEwMCU7b3ZlcmZsb3c6aGlkZGVuO3RvcDowfS5mYy12LWV2ZW50Om5vdCguZmMtZXZlbnQtc3RhcnQpe2JvcmRlci10b3AtbGVmdC1yYWRpdXM6MDtib3JkZXItdG9wLXJpZ2h0LXJhZGl1czowO2JvcmRlci10b3Atd2lkdGg6MH0uZmMtdi1ldmVudDpub3QoLmZjLWV2ZW50LWVuZCl7Ym9yZGVyLWJvdHRvbS1sZWZ0LXJhZGl1czowO2JvcmRlci1ib3R0b20tcmlnaHQtcmFkaXVzOjA7Ym9yZGVyLWJvdHRvbS13aWR0aDowfS5mYy12LWV2ZW50LmZjLWV2ZW50LXNlbGVjdGVkOmJlZm9yZXtsZWZ0Oi0xMHB4O3JpZ2h0Oi0xMHB4fS5mYy12LWV2ZW50IC5mYy1ldmVudC1yZXNpemVyLXN0YXJ0e2N1cnNvcjpuLXJlc2l6ZX0uZmMtdi1ldmVudCAuZmMtZXZlbnQtcmVzaXplci1lbmR7Y3Vyc29yOnMtcmVzaXplfS5mYy12LWV2ZW50Om5vdCguZmMtZXZlbnQtc2VsZWN0ZWQpIC5mYy1ldmVudC1yZXNpemVye2hlaWdodDp2YXIoLS1mYy1ldmVudC1yZXNpemVyLXRoaWNrbmVzcyk7bGVmdDowO3JpZ2h0OjB9LmZjLXYtZXZlbnQ6bm90KC5mYy1ldmVudC1zZWxlY3RlZCkgLmZjLWV2ZW50LXJlc2l6ZXItc3RhcnR7dG9wOmNhbGModmFyKC0tZmMtZXZlbnQtcmVzaXplci10aGlja25lc3MpLy0yKX0uZmMtdi1ldmVudDpub3QoLmZjLWV2ZW50LXNlbGVjdGVkKSAuZmMtZXZlbnQtcmVzaXplci1lbmR7Ym90dG9tOmNhbGModmFyKC0tZmMtZXZlbnQtcmVzaXplci10aGlja25lc3MpLy0yKX0uZmMtdi1ldmVudC5mYy1ldmVudC1zZWxlY3RlZCAuZmMtZXZlbnQtcmVzaXplcntsZWZ0OjUwJTttYXJnaW4tbGVmdDpjYWxjKHZhcigtLWZjLWV2ZW50LXJlc2l6ZXItZG90LXRvdGFsLXdpZHRoKS8tMil9LmZjLXYtZXZlbnQuZmMtZXZlbnQtc2VsZWN0ZWQgLmZjLWV2ZW50LXJlc2l6ZXItc3RhcnR7dG9wOmNhbGModmFyKC0tZmMtZXZlbnQtcmVzaXplci1kb3QtdG90YWwtd2lkdGgpLy0yKX0uZmMtdi1ldmVudC5mYy1ldmVudC1zZWxlY3RlZCAuZmMtZXZlbnQtcmVzaXplci1lbmR7Ym90dG9tOmNhbGModmFyKC0tZmMtZXZlbnQtcmVzaXplci1kb3QtdG90YWwtd2lkdGgpLy0yKX0uZmMgLmZjLXRpbWVncmlkIC5mYy1kYXlncmlkLWJvZHl7ei1pbmRleDoyfS5mYyAuZmMtdGltZWdyaWQtZGl2aWRlcntwYWRkaW5nOjAgMCAycHh9LmZjIC5mYy10aW1lZ3JpZC1ib2R5e21pbi1oZWlnaHQ6MTAwJTtwb3NpdGlvbjpyZWxhdGl2ZTt6LWluZGV4OjF9LmZjIC5mYy10aW1lZ3JpZC1heGlzLWNodW5re3Bvc2l0aW9uOnJlbGF0aXZlfS5mYyAuZmMtdGltZWdyaWQtYXhpcy1jaHVuaz50YWJsZSwuZmMgLmZjLXRpbWVncmlkLXNsb3Rze3Bvc2l0aW9uOnJlbGF0aXZlO3otaW5kZXg6MX0uZmMgLmZjLXRpbWVncmlkLXNsb3R7Ym9yZGVyLWJvdHRvbTowO2hlaWdodDoxLjVlbX0uZmMgLmZjLXRpbWVncmlkLXNsb3Q6ZW1wdHk6YmVmb3Jle2NvbnRlbnQ6XFxcIlxcXFwwMGEwXFxcIn0uZmMgLmZjLXRpbWVncmlkLXNsb3QtbWlub3J7Ym9yZGVyLXRvcC1zdHlsZTpkb3R0ZWR9LmZjIC5mYy10aW1lZ3JpZC1zbG90LWxhYmVsLWN1c2hpb257ZGlzcGxheTppbmxpbmUtYmxvY2s7d2hpdGUtc3BhY2U6bm93cmFwfS5mYyAuZmMtdGltZWdyaWQtc2xvdC1sYWJlbHt2ZXJ0aWNhbC1hbGlnbjptaWRkbGV9LmZjIC5mYy10aW1lZ3JpZC1heGlzLWN1c2hpb24sLmZjIC5mYy10aW1lZ3JpZC1zbG90LWxhYmVsLWN1c2hpb257cGFkZGluZzowIDRweH0uZmMgLmZjLXRpbWVncmlkLWF4aXMtZnJhbWUtbGlxdWlke2hlaWdodDoxMDAlfS5mYyAuZmMtdGltZWdyaWQtYXhpcy1mcmFtZXthbGlnbi1pdGVtczpjZW50ZXI7ZGlzcGxheTpmbGV4O2p1c3RpZnktY29udGVudDpmbGV4LWVuZDtvdmVyZmxvdzpoaWRkZW59LmZjIC5mYy10aW1lZ3JpZC1heGlzLWN1c2hpb257ZmxleC1zaHJpbms6MDttYXgtd2lkdGg6NjBweH0uZmMtZGlyZWN0aW9uLWx0ciAuZmMtdGltZWdyaWQtc2xvdC1sYWJlbC1mcmFtZXt0ZXh0LWFsaWduOnJpZ2h0fS5mYy1kaXJlY3Rpb24tcnRsIC5mYy10aW1lZ3JpZC1zbG90LWxhYmVsLWZyYW1le3RleHQtYWxpZ246bGVmdH0uZmMtbGlxdWlkLWhhY2sgLmZjLXRpbWVncmlkLWF4aXMtZnJhbWUtbGlxdWlke2JvdHRvbTowO2hlaWdodDphdXRvO2xlZnQ6MDtwb3NpdGlvbjphYnNvbHV0ZTtyaWdodDowO3RvcDowfS5mYyAuZmMtdGltZWdyaWQtY29sLmZjLWRheS10b2RheXtiYWNrZ3JvdW5kLWNvbG9yOnZhcigtLWZjLXRvZGF5LWJnLWNvbG9yKX0uZmMgLmZjLXRpbWVncmlkLWNvbC1mcmFtZXttaW4taGVpZ2h0OjEwMCU7cG9zaXRpb246cmVsYXRpdmV9LmZjLW1lZGlhLXNjcmVlbi5mYy1saXF1aWQtaGFjayAuZmMtdGltZWdyaWQtY29sLWZyYW1le2JvdHRvbTowO2hlaWdodDphdXRvO2xlZnQ6MDtwb3NpdGlvbjphYnNvbHV0ZTtyaWdodDowO3RvcDowfS5mYy1tZWRpYS1zY3JlZW4gLmZjLXRpbWVncmlkLWNvbHN7Ym90dG9tOjA7bGVmdDowO3Bvc2l0aW9uOmFic29sdXRlO3JpZ2h0OjA7dG9wOjB9LmZjLW1lZGlhLXNjcmVlbiAuZmMtdGltZWdyaWQtY29scz50YWJsZXtoZWlnaHQ6MTAwJX0uZmMtbWVkaWEtc2NyZWVuIC5mYy10aW1lZ3JpZC1jb2wtYmcsLmZjLW1lZGlhLXNjcmVlbiAuZmMtdGltZWdyaWQtY29sLWV2ZW50cywuZmMtbWVkaWEtc2NyZWVuIC5mYy10aW1lZ3JpZC1ub3ctaW5kaWNhdG9yLWNvbnRhaW5lcntsZWZ0OjA7cG9zaXRpb246YWJzb2x1dGU7cmlnaHQ6MDt0b3A6MH0uZmMgLmZjLXRpbWVncmlkLWNvbC1iZ3t6LWluZGV4OjJ9LmZjIC5mYy10aW1lZ3JpZC1jb2wtYmcgLmZjLW5vbi1idXNpbmVzc3t6LWluZGV4OjF9LmZjIC5mYy10aW1lZ3JpZC1jb2wtYmcgLmZjLWJnLWV2ZW50e3otaW5kZXg6Mn0uZmMgLmZjLXRpbWVncmlkLWNvbC1iZyAuZmMtaGlnaGxpZ2h0e3otaW5kZXg6M30uZmMgLmZjLXRpbWVncmlkLWJnLWhhcm5lc3N7bGVmdDowO3Bvc2l0aW9uOmFic29sdXRlO3JpZ2h0OjB9LmZjIC5mYy10aW1lZ3JpZC1jb2wtZXZlbnRze3otaW5kZXg6M30uZmMgLmZjLXRpbWVncmlkLW5vdy1pbmRpY2F0b3ItY29udGFpbmVye2JvdHRvbTowO292ZXJmbG93OmhpZGRlbn0uZmMtZGlyZWN0aW9uLWx0ciAuZmMtdGltZWdyaWQtY29sLWV2ZW50c3ttYXJnaW46MCAyLjUlIDAgMnB4fS5mYy1kaXJlY3Rpb24tcnRsIC5mYy10aW1lZ3JpZC1jb2wtZXZlbnRze21hcmdpbjowIDJweCAwIDIuNSV9LmZjLXRpbWVncmlkLWV2ZW50LWhhcm5lc3N7cG9zaXRpb246YWJzb2x1dGV9LmZjLXRpbWVncmlkLWV2ZW50LWhhcm5lc3M+LmZjLXRpbWVncmlkLWV2ZW50e2JvdHRvbTowO2xlZnQ6MDtwb3NpdGlvbjphYnNvbHV0ZTtyaWdodDowO3RvcDowfS5mYy10aW1lZ3JpZC1ldmVudC1oYXJuZXNzLWluc2V0IC5mYy10aW1lZ3JpZC1ldmVudCwuZmMtdGltZWdyaWQtZXZlbnQuZmMtZXZlbnQtbWlycm9yLC5mYy10aW1lZ3JpZC1tb3JlLWxpbmt7Ym94LXNoYWRvdzowIDAgMCAxcHggdmFyKC0tZmMtcGFnZS1iZy1jb2xvcil9LmZjLXRpbWVncmlkLWV2ZW50LC5mYy10aW1lZ3JpZC1tb3JlLWxpbmt7Ym9yZGVyLXJhZGl1czozcHg7Zm9udC1zaXplOnZhcigtLWZjLXNtYWxsLWZvbnQtc2l6ZSl9LmZjLXRpbWVncmlkLWV2ZW50e21hcmdpbi1ib3R0b206MXB4fS5mYy10aW1lZ3JpZC1ldmVudCAuZmMtZXZlbnQtbWFpbntwYWRkaW5nOjFweCAxcHggMH0uZmMtdGltZWdyaWQtZXZlbnQgLmZjLWV2ZW50LXRpbWV7Zm9udC1zaXplOnZhcigtLWZjLXNtYWxsLWZvbnQtc2l6ZSk7bWFyZ2luLWJvdHRvbToxcHg7d2hpdGUtc3BhY2U6bm93cmFwfS5mYy10aW1lZ3JpZC1ldmVudC1zaG9ydCAuZmMtZXZlbnQtbWFpbi1mcmFtZXtmbGV4LWRpcmVjdGlvbjpyb3c7b3ZlcmZsb3c6aGlkZGVufS5mYy10aW1lZ3JpZC1ldmVudC1zaG9ydCAuZmMtZXZlbnQtdGltZTphZnRlcntjb250ZW50OlxcXCJcXFxcMDBhMC1cXFxcMDBhMFxcXCJ9LmZjLXRpbWVncmlkLWV2ZW50LXNob3J0IC5mYy1ldmVudC10aXRsZXtmb250LXNpemU6dmFyKC0tZmMtc21hbGwtZm9udC1zaXplKX0uZmMtdGltZWdyaWQtbW9yZS1saW5re2JhY2tncm91bmQ6dmFyKC0tZmMtbW9yZS1saW5rLWJnLWNvbG9yKTtjb2xvcjp2YXIoLS1mYy1tb3JlLWxpbmstdGV4dC1jb2xvcik7Y3Vyc29yOnBvaW50ZXI7bWFyZ2luLWJvdHRvbToxcHg7cG9zaXRpb246YWJzb2x1dGU7ei1pbmRleDo5OTk5fS5mYy10aW1lZ3JpZC1tb3JlLWxpbmstaW5uZXJ7cGFkZGluZzozcHggMnB4O3RvcDowfS5mYy1kaXJlY3Rpb24tbHRyIC5mYy10aW1lZ3JpZC1tb3JlLWxpbmt7cmlnaHQ6MH0uZmMtZGlyZWN0aW9uLXJ0bCAuZmMtdGltZWdyaWQtbW9yZS1saW5re2xlZnQ6MH0uZmMgLmZjLXRpbWVncmlkLW5vdy1pbmRpY2F0b3ItbGluZXtib3JkZXItY29sb3I6dmFyKC0tZmMtbm93LWluZGljYXRvci1jb2xvcik7Ym9yZGVyLXN0eWxlOnNvbGlkO2JvcmRlci13aWR0aDoxcHggMCAwO2xlZnQ6MDtwb3NpdGlvbjphYnNvbHV0ZTtyaWdodDowO3otaW5kZXg6NH0uZmMgLmZjLXRpbWVncmlkLW5vdy1pbmRpY2F0b3ItYXJyb3d7Ym9yZGVyLWNvbG9yOnZhcigtLWZjLW5vdy1pbmRpY2F0b3ItY29sb3IpO2JvcmRlci1zdHlsZTpzb2xpZDttYXJnaW4tdG9wOi01cHg7cG9zaXRpb246YWJzb2x1dGU7ei1pbmRleDo0fS5mYy1kaXJlY3Rpb24tbHRyIC5mYy10aW1lZ3JpZC1ub3ctaW5kaWNhdG9yLWFycm93e2JvcmRlci1ib3R0b20tY29sb3I6dHJhbnNwYXJlbnQ7Ym9yZGVyLXRvcC1jb2xvcjp0cmFuc3BhcmVudDtib3JkZXItd2lkdGg6NXB4IDAgNXB4IDZweDtsZWZ0OjB9LmZjLWRpcmVjdGlvbi1ydGwgLmZjLXRpbWVncmlkLW5vdy1pbmRpY2F0b3ItYXJyb3d7Ym9yZGVyLWJvdHRvbS1jb2xvcjp0cmFuc3BhcmVudDtib3JkZXItdG9wLWNvbG9yOnRyYW5zcGFyZW50O2JvcmRlci13aWR0aDo1cHggNnB4IDVweCAwO3JpZ2h0OjB9XCI7XG5pbmplY3RTdHlsZXMoY3NzXzI0OHopO1xuXG52YXIgaW5kZXggPSBjcmVhdGVQbHVnaW4oe1xuICAgIG5hbWU6ICdAZnVsbGNhbGVuZGFyL3RpbWVncmlkJyxcbiAgICBpbml0aWFsVmlldzogJ3RpbWVHcmlkV2VlaycsXG4gICAgb3B0aW9uUmVmaW5lcnM6IE9QVElPTl9SRUZJTkVSUyxcbiAgICB2aWV3czoge1xuICAgICAgICB0aW1lR3JpZDoge1xuICAgICAgICAgICAgY29tcG9uZW50OiBEYXlUaW1lQ29sc1ZpZXcsXG4gICAgICAgICAgICB1c2VzTWluTWF4VGltZTogdHJ1ZSxcbiAgICAgICAgICAgIGFsbERheVNsb3Q6IHRydWUsXG4gICAgICAgICAgICBzbG90RHVyYXRpb246ICcwMDozMDowMCcsXG4gICAgICAgICAgICBzbG90RXZlbnRPdmVybGFwOiB0cnVlLCAvLyBhIGJhZCBuYW1lLiBjb25mdXNlZCB3aXRoIG92ZXJsYXAvY29uc3RyYWludCBzeXN0ZW1cbiAgICAgICAgfSxcbiAgICAgICAgdGltZUdyaWREYXk6IHtcbiAgICAgICAgICAgIHR5cGU6ICd0aW1lR3JpZCcsXG4gICAgICAgICAgICBkdXJhdGlvbjogeyBkYXlzOiAxIH0sXG4gICAgICAgIH0sXG4gICAgICAgIHRpbWVHcmlkV2Vlazoge1xuICAgICAgICAgICAgdHlwZTogJ3RpbWVHcmlkJyxcbiAgICAgICAgICAgIGR1cmF0aW9uOiB7IHdlZWtzOiAxIH0sXG4gICAgICAgIH0sXG4gICAgfSxcbn0pO1xuXG5leHBvcnQgeyBpbmRleCBhcyBkZWZhdWx0IH07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/@fullcalendar/timegrid/index.esm.js\n"); /***/ }), /***/ "./node_modules/@fullcalendar/timegrid/internal.esm.js": /*!*************************************************************!*\ !*** ./node_modules/@fullcalendar/timegrid/internal.esm.js ***! \*************************************************************/ /***/ (function(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) { eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"DayTimeCols\": function() { return /* binding */ DayTimeCols; },\n/* harmony export */ \"DayTimeColsSlicer\": function() { return /* binding */ DayTimeColsSlicer; },\n/* harmony export */ \"DayTimeColsView\": function() { return /* binding */ DayTimeColsView; },\n/* harmony export */ \"TimeCols\": function() { return /* binding */ TimeCols; },\n/* harmony export */ \"TimeColsSlatsCoords\": function() { return /* binding */ TimeColsSlatsCoords; },\n/* harmony export */ \"TimeColsView\": function() { return /* binding */ TimeColsView; },\n/* harmony export */ \"buildDayRanges\": function() { return /* binding */ buildDayRanges; },\n/* harmony export */ \"buildSlatMetas\": function() { return /* binding */ buildSlatMetas; },\n/* harmony export */ \"buildTimeColsModel\": function() { return /* binding */ buildTimeColsModel; }\n/* harmony export */ });\n/* harmony import */ var _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @fullcalendar/core/internal */ \"./node_modules/@fullcalendar/core/internal-common.esm.js\");\n/* harmony import */ var _fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @fullcalendar/core/preact */ \"./node_modules/preact/dist/preact.module.js\");\n/* harmony import */ var _fullcalendar_daygrid_internal__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @fullcalendar/daygrid/internal */ \"./node_modules/@fullcalendar/daygrid/internal.esm.js\");\n\n\n\n\nclass AllDaySplitter extends _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.aZ {\n getKeyInfo() {\n return {\n allDay: {},\n timed: {},\n };\n }\n getKeysForDateSpan(dateSpan) {\n if (dateSpan.allDay) {\n return ['allDay'];\n }\n return ['timed'];\n }\n getKeysForEventDef(eventDef) {\n if (!eventDef.allDay) {\n return ['timed'];\n }\n if ((0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bP)(eventDef)) {\n return ['timed', 'allDay'];\n }\n return ['allDay'];\n }\n}\n\nconst DEFAULT_SLAT_LABEL_FORMAT = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.x)({\n hour: 'numeric',\n minute: '2-digit',\n omitZeroMinute: true,\n meridiem: 'short',\n});\nfunction TimeColsAxisCell(props) {\n let classNames = [\n 'fc-timegrid-slot',\n 'fc-timegrid-slot-label',\n props.isLabeled ? 'fc-scrollgrid-shrink' : 'fc-timegrid-slot-minor',\n ];\n return ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.V.Consumer, null, (context) => {\n if (!props.isLabeled) {\n return ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"td\", { className: classNames.join(' '), \"data-time\": props.isoTimeStr }));\n }\n let { dateEnv, options, viewApi } = context;\n let labelFormat = // TODO: fully pre-parse\n options.slotLabelFormat == null ? DEFAULT_SLAT_LABEL_FORMAT :\n Array.isArray(options.slotLabelFormat) ? (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.x)(options.slotLabelFormat[0]) :\n (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.x)(options.slotLabelFormat);\n let renderProps = {\n level: 0,\n time: props.time,\n date: dateEnv.toDate(props.date),\n view: viewApi,\n text: dateEnv.format(props.date, labelFormat),\n };\n return ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.C, { elTag: \"td\", elClasses: classNames, elAttrs: {\n 'data-time': props.isoTimeStr,\n }, renderProps: renderProps, generatorName: \"slotLabelContent\", generator: options.slotLabelContent || renderInnerContent, classNameGenerator: options.slotLabelClassNames, didMount: options.slotLabelDidMount, willUnmount: options.slotLabelWillUnmount }, (InnerContent) => ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"div\", { className: \"fc-timegrid-slot-label-frame fc-scrollgrid-shrink-frame\" },\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(InnerContent, { elTag: \"div\", elClasses: [\n 'fc-timegrid-slot-label-cushion',\n 'fc-scrollgrid-shrink-cushion',\n ] })))));\n }));\n}\nfunction renderInnerContent(props) {\n return props.text;\n}\n\nclass TimeBodyAxis extends _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.Y {\n render() {\n return this.props.slatMetas.map((slatMeta) => ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"tr\", { key: slatMeta.key },\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(TimeColsAxisCell, Object.assign({}, slatMeta)))));\n }\n}\n\nconst DEFAULT_WEEK_NUM_FORMAT = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.x)({ week: 'short' });\nconst AUTO_ALL_DAY_MAX_EVENT_ROWS = 5;\nclass TimeColsView extends _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bf {\n constructor() {\n super(...arguments);\n this.allDaySplitter = new AllDaySplitter(); // for use by subclasses\n this.headerElRef = (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createRef)();\n this.rootElRef = (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createRef)();\n this.scrollerElRef = (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createRef)();\n this.state = {\n slatCoords: null,\n };\n this.handleScrollTopRequest = (scrollTop) => {\n let scrollerEl = this.scrollerElRef.current;\n if (scrollerEl) { // TODO: not sure how this could ever be null. weirdness with the reducer\n scrollerEl.scrollTop = scrollTop;\n }\n };\n /* Header Render Methods\n ------------------------------------------------------------------------------------------------------------------*/\n this.renderHeadAxis = (rowKey, frameHeight = '') => {\n let { options } = this.context;\n let { dateProfile } = this.props;\n let range = dateProfile.renderRange;\n let dayCnt = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.bm)(range.start, range.end);\n // only do in day views (to avoid doing in week views that dont need it)\n let navLinkAttrs = (dayCnt === 1)\n ? (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.b1)(this.context, range.start, 'week')\n : {};\n if (options.weekNumbers && rowKey === 'day') {\n return ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.cq, { elTag: \"th\", elClasses: [\n 'fc-timegrid-axis',\n 'fc-scrollgrid-shrink',\n ], elAttrs: {\n 'aria-hidden': true,\n }, date: range.start, defaultFormat: DEFAULT_WEEK_NUM_FORMAT }, (InnerContent) => ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"div\", { className: [\n 'fc-timegrid-axis-frame',\n 'fc-scrollgrid-shrink-frame',\n 'fc-timegrid-axis-frame-liquid',\n ].join(' '), style: { height: frameHeight } },\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(InnerContent, { elTag: \"a\", elClasses: [\n 'fc-timegrid-axis-cushion',\n 'fc-scrollgrid-shrink-cushion',\n 'fc-scrollgrid-sync-inner',\n ], elAttrs: navLinkAttrs })))));\n }\n return ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"th\", { \"aria-hidden\": true, className: \"fc-timegrid-axis\" },\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"div\", { className: \"fc-timegrid-axis-frame\", style: { height: frameHeight } })));\n };\n /* Table Component Render Methods\n ------------------------------------------------------------------------------------------------------------------*/\n // only a one-way height sync. we don't send the axis inner-content height to the DayGrid,\n // but DayGrid still needs to have classNames on inner elements in order to measure.\n this.renderTableRowAxis = (rowHeight) => {\n let { options, viewApi } = this.context;\n let renderProps = {\n text: options.allDayText,\n view: viewApi,\n };\n return (\n // TODO: make reusable hook. used in list view too\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.C, { elTag: \"td\", elClasses: [\n 'fc-timegrid-axis',\n 'fc-scrollgrid-shrink',\n ], elAttrs: {\n 'aria-hidden': true,\n }, renderProps: renderProps, generatorName: \"allDayContent\", generator: options.allDayContent || renderAllDayInner, classNameGenerator: options.allDayClassNames, didMount: options.allDayDidMount, willUnmount: options.allDayWillUnmount }, (InnerContent) => ((0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(\"div\", { className: [\n 'fc-timegrid-axis-frame',\n 'fc-scrollgrid-shrink-frame',\n rowHeight == null ? ' fc-timegrid-axis-frame-liquid' : '',\n ].join(' '), style: { height: rowHeight } },\n (0,_fullcalendar_core_preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(InnerContent, { elTag: \"span\", elClasses: [\n 'fc-timegrid-axis-cushion',\n 'fc-scrollgrid-shrink-cushion',\n 'fc-scrollgrid-sync-inner',\n ] })))));\n };\n this.handleSlatCoords = (slatCoords) => {\n this.setState({ slatCoords });\n };\n }\n // rendering\n // ----------------------------------------------------------------------------------------------------\n renderSimpleLayout(headerRowContent, allDayContent, timeContent) {\n let { context, props } = this;\n let sections = [];\n let stickyHeaderDates = (0,_fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_0__.cc)(context.options);\n if (headerRowContent) {\n sections.push({\n type: 'header',\n key: 'header',\n isSticky: stickyHeaderDates,\n chunk: {\n elRef: this.headerElRef,\n tableClassName: 'fc-col-header',\n rowContent: headerRowContent,\n },\n });\n }\n if (allDayContent) {\n sections.push({\n type: 'body',\n key: 'all-day',\n chunk: { content: allDayContent },\n });\n sections.push({\n type: 'body',\n key: 'all-day-divider',\n outerContent: ( // TODO: rename to cellContent so don't need to define