You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

441 lines
2.9 MiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/*
* 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/).
*/
(self["webpackChunk"] = self["webpackChunk"] || []).push([["/vendor/js/vendor"],{
/***/ "./node_modules/alertifyjs/build/alertify.min.js":
/*!*******************************************************!*\
!*** ./node_modules/alertifyjs/build/alertify.min.js ***!
\*******************************************************/
/***/ (function(module, exports) {
eval("var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! alertifyjs - v1.13.1 - Mohammad Younes <Mohammad@alertifyjs.com> (http://alertifyjs.com) */\n!function(a){\"use strict\";function b(a,b){a.className+=\" \"+b}function c(a,b){for(var c=a.className.split(\" \"),d=b.split(\" \"),e=0;e<d.length;e+=1){var f=c.indexOf(d[e]);f>-1&&c.splice(f,1)}a.className=c.join(\" \")}function d(){return\"rtl\"===a.getComputedStyle(document.body).direction}function e(){return document.documentElement&&document.documentElement.scrollTop||document.body.scrollTop}function f(){return document.documentElement&&document.documentElement.scrollLeft||document.body.scrollLeft}function g(a){for(;a.lastChild;)a.removeChild(a.lastChild)}function h(a){if(null===a)return a;var b;if(Array.isArray(a)){b=[];for(var c=0;c<a.length;c+=1)b.push(h(a[c]));return b}if(a instanceof Date)return new Date(a.getTime());if(a instanceof RegExp)return b=new RegExp(a.source),b.global=a.global,b.ignoreCase=a.ignoreCase,b.multiline=a.multiline,b.lastIndex=a.lastIndex,b;if(\"object\"==typeof a){b={};for(var d in a)a.hasOwnProperty(d)&&(b[d]=h(a[d]));return b}return a}function i(a,b){if(a.elements){var c=a.elements.root;c.parentNode.removeChild(c),delete a.elements,a.settings=h(a.__settings),a.__init=b,delete a.__internal}}function j(a,b){return function(){if(arguments.length>0){for(var c=[],d=0;d<arguments.length;d+=1)c.push(arguments[d]);return c.push(a),b.apply(a,c)}return b.apply(a,[null,a])}}function k(a,b){return{index:a,button:b,cancel:!1}}function l(a,b){if(\"function\"==typeof b.get(a))return b.get(a).call(b)}function m(){function a(a,b){for(var c in b)b.hasOwnProperty(c)&&(a[c]=b[c]);return a}function b(a){var b=d[a].dialog;return b&&\"function\"==typeof b.__init&&b.__init(b),b}function c(b,c,e,f){var g={dialog:null,factory:c};return void 0!==f&&(g.factory=function(){return a(new d[f].factory,new c)}),e||(g.dialog=a(new g.factory,w)),d[b]=g}var d={};return{defaults:p,dialog:function(d,e,f,g){if(\"function\"!=typeof e)return b(d);if(this.hasOwnProperty(d))throw new Error(\"alertify.dialog: name already exists\");var h=c(d,e,f,g);this[d]=f?function(){if(0===arguments.length)return h.dialog;var b=a(new h.factory,w);return b&&\"function\"==typeof b.__init&&b.__init(b),b.main.apply(b,arguments),b.show.apply(b)}:function(){if(h.dialog&&\"function\"==typeof h.dialog.__init&&h.dialog.__init(h.dialog),0===arguments.length)return h.dialog;var a=h.dialog;return a.main.apply(h.dialog,arguments),a.show.apply(h.dialog)}},closeAll:function(a){for(var b=q.slice(0),c=0;c<b.length;c+=1){var d=b[c];void 0!==a&&a===d||d.close()}},setting:function(a,c,d){if(\"notifier\"===a)return x.setting(c,d);var e=b(a);return e?e.setting(c,d):void 0},set:function(a,b,c){return this.setting(a,b,c)},get:function(a,b){return this.setting(a,b)},notify:function(a,b,c,d){return x.create(b,d).push(a,c)},message:function(a,b,c){return x.create(null,c).push(a,b)},success:function(a,b,c){return x.create(\"success\",c).push(a,b)},error:function(a,b,c){return x.create(\"error\",c).push(a,b)},warning:function(a,b,c){return x.create(\"warning\",c).push(a,b)},dismissAll:function(){x.dismissAll()}}}var n=\":not(:disabled):not(.ajs-reset)\",o={ENTER:13,ESC:27,F1:112,F12:123,LEFT:37,RIGHT:39,TAB:9},p={autoReset:!0,basic:!1,closable:!0,closableByDimmer:!0,invokeOnCloseOff:!1,frameless:!1,defaultFocusOff:!1,maintainFocus:!0,maximizable:!0,modal:!0,movable:!0,moveBounded:!1,overflow:!0,padding:!0,pinnable:!0,pinned:!0,preventBodyShift:!1,resizable:!0,startMaximized:!1,transition:\"pulse\",transitionOff:!1,tabbable:[\"button\",\"[href]\",\"input\",\"select\",\"textarea\",'[tabindex]:not([tabindex^=\"-\"])'+n].join(n+\",\"),notifier:{delay:5,position:\"bottom-right\",closeButton:!1,classes:{base:\"alertify-notifier\",prefix:\"ajs-\",message:\"ajs-message\",top:\"ajs-top\",right:\"ajs-right\",bottom:\"ajs-bottom\",left:\"ajs-left\",center:\"ajs-center\",visible:\"ajs-visible\",hidden:\"ajs-hidden\",close:\"ajs-close\"}},glossary:{title:\"AlertifyJS\",ok:\"OK\",cancel:\"Cancel\",acccpt:\"Accept\",deny:\"Deny\",confirm:\"Confirm\",decline:\"Decline\",close:\"Close\",maximize:\"Maximize\",restore:\"Restore\"},theme:{input:\"ajs-input\",ok:\"ajs-ok\",cancel:\"ajs-cancel\"},hooks:{preinit:function(){},postinit:function(){}}},q=[],r=!1;try{var s=Object.defineProperty({},\"passive\",{get:function(){r=!0}});a.addEventListener(\"test\",s,s),a.removeEventListener(\"test\",s,s)}catch(z){}var t=function(a,b,c,d,e){a.addEventListener(b,c,r?{capture:d,passive:e}:!0===d)},u=function(a,b,c,d,e){a.removeEventListener(b,c,r?{capture:d,passive:e}:!0===d)},v=function(){var a,b,c=!1,d={animation:\"animationend\",OAnimation:\"oAnimationEnd oanimationend\",msAnimation:\"MSAnimationEnd\",MozAnimation:\"animationend\",WebkitAnimation:\"webkitAnimationEnd\"};for(a in d)if(void 0!==document.documentElement.style[a]){b=d[a],c=!0;break}return{type:b,supported:c}}(),w=function(){function m(a){if(!a.__internal){y.defaults.hooks.preinit(a),delete a.__init,a.__settings||(a.__settings=h(a.settings));var c;\"function\"==typeof a.setup?(c=a.setup(),c.options=c.options||{},c.focus=c.focus||{}):c={buttons:[],focus:{element:null,select:!1},options:{}},\"object\"!=typeof a.hooks&&(a.hooks={});var d=[];if(Array.isArray(c.buttons))for(var e=0;e<c.buttons.length;e+=1){var f=c.buttons[e],g={};for(var i in f)f.hasOwnProperty(i)&&(g[i]=f[i]);d.push(g)}var k=a.__internal={isOpen:!1,activeElement:document.body,timerIn:void 0,timerOut:void 0,buttons:d,focus:c.focus,options:{title:void 0,modal:void 0,basic:void 0,frameless:void 0,defaultFocusOff:void 0,pinned:void 0,movable:void 0,moveBounded:void 0,resizable:void 0,autoReset:void 0,closable:void 0,closableByDimmer:void 0,invokeOnCloseOff:void 0,maximizable:void 0,startMaximized:void 0,pinnable:void 0,transition:void 0,transitionOff:void 0,padding:void 0,overflow:void 0,onshow:void 0,onclosing:void 0,onclose:void 0,onfocus:void 0,onmove:void 0,onmoved:void 0,onresize:void 0,onresized:void 0,onmaximize:void 0,onmaximized:void 0,onrestore:void 0,onrestored:void 0},resetHandler:void 0,beginMoveHandler:void 0,beginResizeHandler:void 0,bringToFrontHandler:void 0,modalClickHandler:void 0,buttonsClickHandler:void 0,commandsClickHandler:void 0,transitionInHandler:void 0,transitionOutHandler:void 0,destroy:void 0},l={};l.root=document.createElement(\"div\"),l.root.style.display=\"none\",l.root.className=Ha.base+\" \"+Ha.hidden+\" \",l.root.innerHTML=Ga.dimmer+Ga.modal,l.dimmer=l.root.firstChild,l.modal=l.root.lastChild,l.modal.innerHTML=Ga.dialog,l.dialog=l.modal.firstChild,l.dialog.innerHTML=Ga.reset+Ga.commands+Ga.header+Ga.body+Ga.footer+Ga.resizeHandle+Ga.reset,l.reset=[],l.reset.push(l.dialog.firstChild),l.reset.push(l.dialog.lastChild),l.commands={},l.commands.container=l.reset[0].nextSibling,l.commands.pin=l.commands.container.firstChild,l.commands.maximize=l.commands.pin.nextSibling,l.commands.close=l.commands.maximize.nextSibling,l.header=l.commands.container.nextSibling,l.body=l.header.nextSibling,l.body.innerHTML=Ga.content,l.content=l.body.firstChild,l.footer=l.body.nextSibling,l.footer.innerHTML=Ga.buttons.auxiliary+Ga.buttons.primary,l.resizeHandle=l.footer.nextSibling,l.buttons={},l.buttons.auxiliary=l.footer.firstChild,l.buttons.primary=l.buttons.auxiliary.nextSibling,l.buttons.primary.innerHTML=Ga.button,l.buttonTemplate=l.buttons.primary.firstChild,l.buttons.primary.removeChild(l.buttonTemplate);for(var m=0;m<a.__internal.buttons.length;m+=1){var n=a.__internal.buttons[m];Ca.indexOf(n.key)<0&&Ca.push(n.key),n.element=l.buttonTemplate.cloneNode(),n.element.innerHTML=n.text,\"string\"==typeof n.className&&\"\"!==n.className&&b(n.element,n.className);for(var o in n.attrs)\"className\"!==o&&n.attrs.hasOwnProperty(o)&&n.element.setAttribute(o,n.attrs[o]);\"auxiliary\"===n.scope?l.buttons.auxiliary.appendChild(n.element):l.buttons.primary.appendChild(n.element)}a.elements=l,k.resetHandler=j(a,Z),k.beginMoveHandler=j(a,ea),k.beginResizeHandler=j(a,ka),k.bringToFrontHandler=j(a,D),k.modalClickHandler=j(a,T),k.buttonsClickHandler=j(a,V),k.commandsClickHandler=j(a,H),k.transitionInHandler=j(a,aa),k.transitionOutHandler=j(a,ba);for(var p in k.options)void 0!==c.options[p]?a.set(p,c.options[p]):y.defaults.hasOwnProperty(p)?a.set(p,y.defaults[p]):\"title\"===p&&a.set(p,y.defaults.glossary[p]);\"function\"==typeof a.build&&a.build(),y.defaults.hooks.postinit(a)}document.body.appendChild(a.elements.root)}function n(){Aa=f(),Ba=e()}function r(){a.scrollTo(Aa,Ba)}function s(){for(var a=0,d=0;d<q.length;d+=1){var e=q[d];(e.isModal()||e.isMaximized())&&(a+=1)}0===a&&document.body.className.indexOf(Ha.noOverflow)>=0?(c(document.body,Ha.noOverflow),w(!1)):a>0&&document.body.className.indexOf(Ha.noOverflow)<0&&(w(!0),b(document.body,Ha.noOverflow))}function w(d){y.defaults.preventBodyShift&&(d&&document.documentElement.scrollHeight>document.documentElement.clientHeight?(Ja=Ba,Ia=a.getComputedStyle(document.body).top,b(document.body,Ha.fixed),document.body.style.top=-Ba+\"px\"):d||(Ba=Ja,document.body.style.top=Ia,c(document.body,Ha.fixed),r()))}function x(a,d,e){\"string\"==typeof e&&c(a.elements.root,Ha.prefix+e),b(a.elements.root,Ha.prefix+d),Da=a.elements.root.offsetWidth}function z(a){a.get(\"transitionOff\")?b(a.elements.root,Ha.noTransition):c(a.elements.root,Ha.noTransition)}function A(a){a.get(\"modal\")?(c(a.elements.root,Ha.modeless),a.isOpen()&&(ta(a),P(a),s())):(b(a.elements.root,Ha.modeless),a.isOpen()&&(sa(a),P(a),s()))}function B(a){a.get(\"basic\")?b(a.elements.root,Ha.basic):c(a.elements.root,Ha.basic)}function C(a){a.get(\"frameless\")?b(a.elements.root,Ha.frameless):c(a.elements.root,Ha.frameless)}function D(a,b){for(var c=q.indexOf(b),d=c+1;d<q.length;d+=1)if(q[d].isModal())return;return document.body.lastChild!==b.elements.root&&(document.body.appendChild(b.elements.root),q.splice(q.indexOf(b),1),q.push(b),Y(b)),!1}function E(a,d,e,f){switch(d){case\"title\":a.setHeader(f);break;case\"modal\":A(a);break;case\"basic\":B(a);break;case\"frameless\":C(a);break;case\"pinned\":Q(a);break;case\"closable\":S(a);break;case\"maximizable\":R(a);break;case\"pinnable\":M(a);break;case\"movable\":ia(a);break;case\"resizable\":oa(a);break;case\"padding\":f?c(a.elements.root,Ha.noPadding):a.elements.root.className.indexOf(Ha.noPadding)<0&&b(a.elements.root,Ha.noPadding);break;case\"overflow\":f?c(a.elements.root,Ha.noOverflow):a.elements.root.className.indexOf(Ha.noOverflow)<0&&b(a.elements.root,Ha.noOverflow);break;case\"transition\":x(a,f,e);break;case\"transitionOff\":z(a)}\"function\"==typeof a.hooks.onupdate&&a.hooks.onupdate.call(a,d,e,f)}function F(a,b,c,d,e){var f={op:void 0,items:[]};if(void 0===e&&\"string\"==typeof d)f.op=\"get\",b.hasOwnProperty(d)?(f.found=!0,f.value=b[d]):(f.found=!1,f.value=void 0);else{var g;if(f.op=\"set\",\"object\"==typeof d){var h=d;for(var i in h)b.hasOwnProperty(i)?(b[i]!==h[i]&&(g=b[i],b[i]=h[i],c.call(a,i,g,h[i])),f.items.push({key:i,value:h[i],found:!0})):f.items.push({key:i,value:h[i],found:!1})}else{if(\"string\"!=typeof d)throw new Error(\"args must be a string or object\");b.hasOwnProperty(d)?(b[d]!==e&&(g=b[d],b[d]=e,c.call(a,d,g,e)),f.items.push({key:d,value:e,found:!0})):f.items.push({key:d,value:e,found:!1})}}return f}function G(a){var b;U(a,function(c){return b=!0!==a.get(\"invokeOnCloseOff\")&&!0===c.invokeOnClose}),!b&&a.isOpen()&&a.close()}function H(a,b){switch(a.srcElement||a.target){case b.elements.commands.pin:b.isPinned()?J(b):I(b);break;case b.elements.commands.maximize:b.isMaximized()?L(b):K(b);break;case b.elements.commands.close:G(b)}return!1}function I(a){a.set(\"pinned\",!0)}function J(a){a.set(\"pinned\",!1)}function K(a){l(\"onmaximize\",a),b(a.elements.root,Ha.maximized),a.isOpen()&&s(),l(\"onmaximized\",a)}function L(a){l(\"onrestore\",a),c(a.elements.root,Ha.maximized),a.isOpen()&&s(),l(\"onrestored\",a)}function M(a){a.get(\"pinnable\")?b(a.elements.root,Ha.pinnable):c(a.elements.root,Ha.pinnable)}function N(a){var b=f();a.elements.modal.style.marginTop=e()+\"px\",a.elements.modal.style.marginLeft=b+\"px\",a.elements.modal.style.marginRight=-b+\"px\"}function O(a){var b=parseInt(a.elements.modal.style.marginTop,10),c=parseInt(a.elements.modal.style.marginLeft,10);if(a.elements.modal.style.marginTop=\"\",a.elements.modal.style.marginLeft=\"\",a.elements.modal.style.marginRight=\"\",a.isOpen()){var d=0,g=0;\"\"!==a.elements.dialog.style.top&&(d=parseInt(a.elements.dialog.style.top,10)),a.elements.dialog.style.top=d+(b-e())+\"px\",\"\"!==a.elements.dialog.style.left&&(g=parseInt(a.elements.dialog.style.left,10)),a.elements.dialog.style.left=g+(c-f())+\"px\"}}function P(a){a.get(\"modal\")||a.get(\"pinned\")?O(a):N(a)}function Q(a){a.get(\"pinned\")?(c(a.elements.root,Ha.unpinned),a.isOpen()&&O(a)):(b(a.elements.root,Ha.unpinned),a.isOpen()&&!a.isModal()&&N(a))}function R(a){a.get(\"maximizable\")?b(a.elements.root,Ha.maximizable):c(a.elements.root,Ha.maximizable)}function S(a){a.get(\"closable\")?(b(a.elements.root,Ha.closable),ya(a)):(c(a.elements.root,Ha.closable),za(a))}function T(a,b){if(a.timeStamp-La>200&&(La=a.timeStamp)&&!Ka){var c=a.srcElement||a.target;!0===b.get(\"closableByDimmer\")&&c===b.elements.modal&&G(b)}Ka=!1}function U(a,b){if(Date.now()-Ma>200&&(Ma=Date.now()))for(var c=0;c<a.__internal.buttons.length;c+=1){var d=a.__internal.buttons[c];if(!d.element.disabled&&b(d)){var e=k(c,d);\"function\"==typeof a.callback&&a.callback.apply(a,[e]),!1===e.cancel&&a.close();break}}}function V(a,b){var c=a.srcElement||a.target;U(b,function(a){return a.element===c&&(Na=!0)})}function W(a){if(Na)return void(Na=!1);var b=q[q.length-1],c=a.keyCode;return 0===b.__internal.buttons.length&&c===o.ESC&&!0===b.get(\"closable\")?(G(b),!1):Ca.indexOf(c)>-1?(U(b,function(a){return a.key===c}),!1):void 0}function X(a){var b=q[q.length-1],c=a.keyCode;if(c===o.LEFT||c===o.RIGHT){for(var d=b.__internal.buttons,e=0;e<d.length;e+=1)if(document.activeElement===d[e].element)switch(c){case o.LEFT:return void d[(e||d.length)-1].element.focus();case o.RIGHT:return void d[(e+1)%d.length].element.focus()}}else if(c<o.F12+1&&c>o.F1-1&&Ca.indexOf(c)>-1)return a.preventDefault(),a.stopPropagation(),U(b,function(a){return a.key===c}),!1}function Y(a,b){if(b)b.focus();else{var c=a.__internal.focus,d=c.element;switch(typeof c.element){case\"number\":a.__internal.buttons.length>c.element&&(d=!0===a.get(\"basic\")?a.elements.reset[0]:a.__internal.buttons[c.element].element);break;case\"string\":d=a.elements.body.querySelector(c.element);break;case\"function\":d=c.element.call(a)}!0!==a.get(\"defaultFocusOff\")&&(void 0!==d&&null!==d||0!==a.__internal.buttons.length)||(d=a.elements.reset[0]),d&&d.focus&&(d.focus(),c.select&&d.select&&d.select())}}function Z(a,b){if(!b)for(var c=q.length-1;c>-1;c-=1)if(q[c].isModal()){b=q[c];break}if(b&&b.isModal()){var d,e=b.elements.reset[0],f=b.elements.reset[1],g=a.relatedTarget,h=b.elements.root.contains(g),i=a.srcElement||a.target;if(i===e&&!h||i===f&&g===e)return;i===f||i===document.body?d=e:i===e&&g===f?d=$(b):i===e&&h&&(d=$(b,!0)),Y(b,d)}}function $(a,b){var c=[].slice.call(a.elements.dialog.querySelectorAll(p.tabbable));b&&c.reverse();for(var d=0;d<c.length;d+=1){var e=c[d];if(e.offsetParent||e.offsetWidth||e.offsetHeight||e.getClientRects().length)return e}}function _(a){var b=q[q.length-1];b&&a.shiftKey&&a.keyCode===o.TAB&&b.elements.reset[1].focus()}function aa(a,b){clearTimeout(b.__internal.timerIn),Y(b),Na=!1,l(\"onfocus\",b),u(b.elements.dialog,v.type,b.__internal.transitionInHandler),c(b.elements.root,Ha.animationIn)}function ba(a,b){clearTimeout(b.__internal.timerOut),u(b.elements.dialog,v.type,b.__internal.transitionOutHandler),ha(b),na(b),b.isMaximized()&&!b.get(\"startMaximized\")&&L(b),\"function\"==typeof b.__internal.destroy&&b.__internal.destroy.apply(b)}function ca(a,b){var c=a[Ra]-Pa,d=a[Sa]-Qa;Ua&&(d-=document.body.scrollTop),b.style.left=c+\"px\",b.style.top=d+\"px\"}function da(a,b){var c=a[Ra]-Pa,d=a[Sa]-Qa;Ua&&(d-=document.body.scrollTop),b.style.left=Math.min(Ta.maxLeft,Math.max(Ta.minLeft,c))+\"px\",b.style.top=Ua?Math.min(Ta.maxTop,Math.max(Ta.minTop,d))+\"px\":Math.max(Ta.minTop,d)+\"px\"}function ea(a,c){if(null===Wa&&!c.isMaximized()&&c.get(\"movable\")){var d,e=0,f=0;if(\"touchstart\"===a.type?(a.preventDefault(),d=a.targetTouches[0],Ra=\"clientX\",Sa=\"clientY\"):0===a.button&&(d=a),d){var g=c.elements.dialog;if(b(g,Ha.capture),g.style.left&&(e=parseInt(g.style.left,10)),g.style.top&&(f=parseInt(g.style.top,10)),Pa=d[Ra]-e,Qa=d[Sa]-f,c.isModal()?Qa+=c.elements.modal.scrollTop:c.isPinned()&&(Qa-=document.body.scrollTop),c.get(\"moveBounded\")){var h=g,i=-e,j=-f;do{i+=h.offsetLeft,j+=h.offsetTop}while(h=h.offsetParent);Ta={maxLeft:i,minLeft:-i,maxTop:document.documentElement.clientHeight-g.clientHeight-j,minTop:-j},Va=da}else Ta=null,Va=ca;return l(\"onmove\",c),Ua=!c.isModal()&&c.isPinned(),Oa=c,Va(d,g),b(document.body,Ha.noSelection),!1}}}function fa(a){if(Oa){var b;\"touchmove\"===a.type?(a.preventDefault(),b=a.targetTouches[0]):0===a.button&&(b=a),b&&Va(b,Oa.elements.dialog)}}function ga(){if(Oa){var a=Oa;Oa=Ta=null,c(document.body,Ha.noSelection),c(a.elements.dialog,Ha.capture),l(\"onmoved\",a)}}function ha(a){Oa=null;var b=a.elements.dialog;b.style.left=b.style.top=\"\"}function ia(a){a.get(\"movable\")?(b(a.elements.root,Ha.movable),a.isOpen()&&ua(a)):(ha(a),c(a.elements.root,Ha.movable),a.isOpen()&&va(a))}function ja(a,b,c){var e=b,f=0,g=0;do{f+=e.offsetLeft,g+=e.offsetTop}while(e=e.offsetParent);var h,i;!0===c?(h=a.pageX,i=a.pageY):(h=a.clientX,i=a.clientY);var j=d();if(j&&(h=document.body.offsetWidth-h,isNaN(Xa)||(f=document.body.offsetWidth-f-b.offsetWidth)),b.style.height=i-g+$a+\"px\",b.style.width=h-f+$a+\"px\",!isNaN(Xa)){var k=.5*Math.abs(b.offsetWidth-Ya);j&&(k*=-1),b.offsetWidth>Ya?b.style.left=Xa+k+\"px\":b.offsetWidth>=Za&&(b.style.left=Xa-k+\"px\")}}function ka(a,c){if(!c.isMaximized()){var d;if(\"touchstart\"===a.type?(a.preventDefault(),d=a.targetTouches[0]):0===a.button&&(d=a),d){l(\"onresize\",c),Wa=c,$a=c.elements.resizeHandle.offsetHeight/2;var e=c.elements.dialog;return b(e,Ha.capture),Xa=parseInt(e.style.left,10),e.style.height=e.offsetHeight+\"px\",e.style.minHeight=c.elements.header.offsetHeight+c.elements.footer.offsetHeight+\"px\",e.style.width=(Ya=e.offsetWidth)+\"px\",\"none\"!==e.style.maxWidth&&(e.style.minWidth=(Za=e.offsetWidth)+\"px\"),e.style.maxWidth=\"none\",b(document.body,Ha.noSelection),!1}}}function la(a){if(Wa){var b;\"touchmove\"===a.type?(a.preventDefault(),b=a.targetTouches[0]):0===a.button&&(b=a),b&&ja(b,Wa.elements.dialog,!Wa.get(\"modal\")&&!Wa.get(\"pinned\"))}}function ma(){if(Wa){var a=Wa;Wa=null,c(document.body,Ha.noSelection),c(a.elements.dialog,Ha.capture),Ka=!0,l(\"onresized\",a)}}function na(a){Wa=null;var b=a.elements.dialog;\"none\"===b.style.maxWidth&&(b.style.maxWidth=b.style.minWidth=b.style.width=b.style.height=b.style.minHeight=b.style.left=\"\",Xa=Number.Nan,Ya=Za=$a=0)}function oa(a){a.get(\"resizable\")?(b(a.elements.root,Ha.resizable),a.isOpen()&&wa(a)):(na(a),c(a.elements.root,Ha.resizable),a.isOpen()&&xa(a))}function pa(){for(var a=0;a<q.length;a+=1){var b=q[a];b.get(\"autoReset\")&&(ha(b),na(b))}}function qa(b){1===q.length&&(t(a,\"resize\",pa),t(document.body,\"keyup\",W),t(document.body,\"keydown\",X),t(document.body,\"focus\",Z),t(document.documentElement,\"mousemove\",fa),t(document.documentElement,\"touchmove\",fa,!1,!1),t(document.documentElement,\"mouseup\",ga),t(document.documentElement,\"touchend\",ga),t(document.documentElement,\"mousemove\",la),t(document.documentElement,\"touchmove\",la,!1,!1),t(document.documentElement,\"mouseup\",ma),t(document.documentElement,\"touchend\",ma)),t(b.elements.commands.container,\"click\",b.__internal.commandsClickHandler),t(b.elements.footer,\"click\",b.__internal.buttonsClickHandler),t(b.elements.reset[0],\"focusin\",b.__internal.resetHandler),t(b.elements.reset[0],\"keydown\",_),t(b.elements.reset[1],\"focusin\",b.__internal.resetHandler),Na=!0,t(b.elements.dialog,v.type,b.__internal.transitionInHandler),b.get(\"modal\")||sa(b),b.get(\"resizable\")&&wa(b),b.get(\"movable\")&&ua(b)}function ra(b){1===q.length&&(u(a,\"resize\",pa),u(document.body,\"keyup\",W),u(document.body,\"keydown\",X),u(document.body,\"focus\",Z),u(document.documentElement,\"mousemove\",fa),u(document.documentElement,\"mouseup\",ga),u(document.documentElement,\"mousemove\",la),u(document.documentElement,\"mouseup\",ma)),u(b.elements.commands.container,\"click\",b.__internal.commandsClickHandler),u(b.elements.footer,\"click\",b.__internal.buttonsClickHandler),u(b.elements.reset[0],\"focusin\",b.__internal.resetHandler),u(b.elements.reset[0],\"keydown\",_),u(b.elements.reset[1],\"focusin\",b.__internal.resetHandler),t(b.elements.dialog,v.type,b.__internal.transitionOutHandler),b.get(\"modal\")||ta(b),b.get(\"movable\")&&va(b),b.get(\"resizable\")&&xa(b)}function sa(a){t(a.elements.dialog,\"focus\",a.__internal.bringToFrontHandler,!0)}function ta(a){u(a.elements.dialog,\"focus\",a.__internal.bringToFrontHandler,!0)}function ua(a){t(a.elements.header,\"mousedown\",a.__internal.beginMoveHandler),t(a.elements.header,\"touchstart\",a.__internal.beginMoveHandler,!1,!1)}function va(a){u(a.elements.header,\"mousedown\",a.__internal.beginMoveHandler),u(a.elements.header,\"touchstart\",a.__internal.beginMoveHandler,!1,!1)}function wa(a){t(a.elements.resizeHandle,\"mousedown\",a.__internal.beginResizeHandler),t(a.elements.resizeHandle,\"touchstart\",a.__internal.beginResizeHandler,!1,!1)}function xa(a){u(a.elements.resizeHandle,\"mousedown\",a.__internal.beginResizeHandler),u(a.elements.resizeHandle,\"touchstart\",a.__internal.beginResizeHandler,!1,!1)}function ya(a){t(a.elements.modal,\"click\",a.__internal.modalClickHandler)}function za(a){u(a.elements.modal,\"click\",a.__internal.modalClickHandler)}var Aa,Ba,Ca=[],Da=null,Ea=!1,Fa=a.navigator.userAgent.indexOf(\"Safari\")>-1&&a.navigator.userAgent.indexOf(\"Chrome\")<0,Ga={dimmer:'<div class=\"ajs-dimmer\"></div>',modal:'<div class=\"ajs-modal\" tabindex=\"0\"></div>',dialog:'<div class=\"ajs-dialog\" tabindex=\"0\"></div>',reset:'<button class=\"ajs-reset\"></button>',commands:'<div class=\"ajs-commands\"><button class=\"ajs-pin\"></button><button class=\"ajs-maximize\"></button><button class=\"ajs-close\"></button></div>',header:'<div class=\"ajs-header\"></div>',body:'<div class=\"ajs-body\"></div>',content:'<div class=\"ajs-content\"></div>',footer:'<div class=\"ajs-footer\"></div>',buttons:{primary:'<div class=\"ajs-primary ajs-buttons\"></div>',auxiliary:'<div class=\"ajs-auxiliary ajs-buttons\"></div>'},button:'<button class=\"ajs-button\"></button>',resizeHandle:'<div class=\"ajs-handle\"></div>'},Ha={animationIn:\"ajs-in\",animationOut:\"ajs-out\",base:\"alertify\",basic:\"ajs-basic\",capture:\"ajs-capture\",closable:\"ajs-closable\",fixed:\"ajs-fixed\",frameless:\"ajs-frameless\",hidden:\"ajs-hidden\",maximize:\"ajs-maximize\",maximized:\"ajs-maximized\",maximizable:\"ajs-maximizable\",modeless:\"ajs-modeless\",movable:\"ajs-movable\",noSelection:\"ajs-no-selection\",noOverflow:\"ajs-no-overflow\",noPadding:\"ajs-no-padding\",pin:\"ajs-pin\",pinnable:\"ajs-pinnable\",prefix:\"ajs-\",resizable:\"ajs-resizable\",restore:\"ajs-restore\",shake:\"ajs-shake\",unpinned:\"ajs-unpinned\",noTransition:\"ajs-no-transition\"},Ia=\"\",Ja=0,Ka=!1,La=0,Ma=0,Na=!1,Oa=null,Pa=0,Qa=0,Ra=\"pageX\",Sa=\"pageY\",Ta=null,Ua=!1,Va=null,Wa=null,Xa=Number.Nan,Ya=0,Za=0,$a=0;return{__init:m,isOpen:function(){return this.__internal.isOpen},isModal:function(){return this.elements.root.className.indexOf(Ha.modeless)<0},isMaximized:function(){return this.elements.root.className.indexOf(Ha.maximized)>-1},isPinned:function(){return this.elements.root.className.indexOf(Ha.unpinned)<0},maximize:function(){return this.isMaximized()||K(this),this},restore:function(){return this.isMaximized()&&L(this),this},pin:function(){return this.isPinned()||I(this),this},unpin:function(){return this.isPinned()&&J(this),this},bringToFront:function(){return D(null,this),this},moveTo:function(a,b){if(!isNaN(a)&&!isNaN(b)){l(\"onmove\",this);var c=this.elements.dialog,e=c,f=0,g=0;c.style.left&&(f-=parseInt(c.style.left,10)),c.style.top&&(g-=parseInt(c.style.top,10));do{f+=e.offsetLeft,g+=e.offsetTop}while(e=e.offsetParent);var h=a-f,i=b-g;d()&&(h*=-1),c.style.left=h+\"px\",c.style.top=i+\"px\",l(\"onmoved\",this)}return this},resizeTo:function(a,b){var c=parseFloat(a),d=parseFloat(b),e=/(\\d*\\.\\d+|\\d+)%/;if(!isNaN(c)&&!isNaN(d)&&!0===this.get(\"resizable\")){l(\"onresize\",this),(\"\"+a).match(e)&&(c=c/100*document.documentElement.clientWidth),(\"\"+b).match(e)&&(d=d/100*document.documentElement.clientHeight);var f=this.elements.dialog;\"none\"!==f.style.maxWidth&&(f.style.minWidth=(Za=f.offsetWidth)+\"px\"),f.style.maxWidth=\"none\",f.style.minHeight=this.elements.header.offsetHeight+this.elements.footer.offsetHeight+\"px\",f.style.width=c+\"px\",f.style.height=d+\"px\",l(\"onresized\",this)}return this},setting:function(a,b){var c=this,d=F(this,this.__internal.options,function(a,b,d){E(c,a,b,d)},a,b);if(\"get\"===d.op)return d.found?d.value:void 0!==this.settings?F(this,this.settings,this.settingUpdated||function(){},a,b).value:void 0;if(\"set\"===d.op){if(d.items.length>0)for(var e=this.settingUpdated||function(){},f=0;f<d.items.length;f+=1){var g=d.items[f];g.found||void 0===this.settings||F(this,this.settings,e,g.key,g.value)}return this}},set:function(a,b){return this.setting(a,b),this},get:function(a){return this.setting(a)},setHeader:function(b){return\"string\"==typeof b?(g(this.elements.header),this.elements.header.innerHTML=b):b instanceof a.HTMLElement&&this.elements.header.firstChild!==b&&(g(this.elements.header),this.elements.header.appendChild(b)),this},setContent:function(b){return\"string\"==typeof b?(g(this.elements.content),this.elements.content.innerHTML=b):b instanceof a.HTMLElement&&this.elements.content.firstChild!==b&&(g(this.elements.content),this.elements.content.appendChild(b)),this},showModal:function(a){return this.show(!0,a)},show:function(a,d){if(m(this),this.__internal.isOpen){ha(this),na(this),b(this.elements.dialog,Ha.shake);var e=this;setTimeout(function(){c(e.elements.dialog,Ha.shake)},200)}else{if(this.__internal.isOpen=!0,q.push(this),y.defaults.maintainFocus&&(this.__internal.activeElement=document.activeElement),document.body.hasAttribute(\"tabindex\")||document.body.setAttribute(\"tabindex\",Ea=\"0\"),\"function\"==typeof this.prepare&&this.prepare(),qa(this),void 0!==a&&this.set(\"modal\",a),n(),s(),\"string\"==typeof d&&\"\"!==d&&(this.__internal.className=d,b(this.elements.root,d)),this.get(\"startMaximized\")?this.maximize():this.isMaximized()&&L(this),P(this),this.elements.root.removeAttribute(\"style\"),c(this.elements.root,Ha.animationOut),b(this.elements.root,Ha.animationIn),clearTimeout(this.__internal.timerIn),this.__internal.timerIn=setTimeout(this.__internal.transitionInHandler,v.supported?1e3:100),Fa){var f=this.elements.root;f.style.display=\"none\",setTimeout(function(){f.style.display=\"block\"},0)}Da=this.elements.root.offsetWidth,c(this.elements.root,Ha.hidden),r(),\"function\"==typeof this.hooks.onshow&&this.hooks.onshow.call(this),l(\"onshow\",this)}return this},close:function(){return this.__internal.isOpen&&!1!==l(\"onclosing\",this)&&(ra(this),c(this.elements.root,Ha.animationIn),b(this.elements.root,Ha.animationOut),clearTimeout(this.__internal.timerOut),this.__internal.timerOut=setTimeout(this.__internal.transitionOutHandler,v.supported?1e3:100),b(this.elements.root,Ha.hidden),Da=this.elements.modal.offsetWidth,y.defaults.maintainFocus&&this.__internal.activeElement&&(this.__internal.activeElement.focus(),this.__internal.activeElement=null),void 0!==this.__internal.className&&\"\"!==this.__internal.className&&c(this.elements.root,this.__internal.className),\"function\"==typeof this.hooks.onclose&&this.hooks.onclose.call(this),l(\"onclose\",this),q.splice(q.indexOf(this),1),this.__internal.isOpen=!1,s()),q.length||\"0\"!==Ea||document.body.removeAttribute(\"tabindex\"),this},closeOthers:function(){return y.closeAll(this),this},destroy:function(){return this.__internal&&(this.__internal.isOpen?(this.__internal.destroy=function(){i(this,m)},this.close()):this.__internal.destroy||i(this,m)),this}}}(),x=function(){function d(a){if(!a.__internal){a.__internal={position:y.defaults.notifier.position,delay:y.defaults.notifier.delay},l=document.createElement(\"DIV\");(\"transitionOff\"in p.notifier?p.notifier.transitionOff:p.transitionOff)&&(o=n.base+\" ajs-no-transition\"),h(a)}l.parentNode!==document.body&&document.body.appendChild(l)}function e(a){a.__internal.pushed=!0,m.push(a)}function f(a){m.splice(m.indexOf(a),1),a.__internal.pushed=!1}function h(a){switch(l.className=o,a.__internal.position){case\"top-right\":b(l,n.top+\" \"+n.right);break;case\"top-left\":b(l,n.top+\" \"+n.left);break;case\"top-center\":b(l,n.top+\" \"+n.center);break;case\"bottom-left\":b(l,n.bottom+\" \"+n.left);break;case\"bottom-center\":b(l,n.bottom+\" \"+n.center);break;default:case\"bottom-right\":b(l,n.bottom+\" \"+n.right)}}function i(d,h){function i(a,b){b.__internal.closeButton&&\"true\"!==a.target.getAttribute(\"data-close\")||b.dismiss(!0)}function m(a,b){u(b.element,v.type,m),l.removeChild(b.element)}function o(a){return a.__internal||(a.__internal={pushed:!1,delay:void 0,timer:void 0,clickHandler:void 0,transitionEndHandler:void 0,transitionTimeout:void 0},a.__internal.clickHandler=j(a,i),a.__internal.transitionEndHandler=j(a,m)),a}function p(a){clearTimeout(a.__internal.timer),clearTimeout(a.__internal.transitionTimeout)}return o({element:d,push:function(a,c){if(!this.__internal.pushed){e(this),p(this);var d,f;switch(arguments.length){case 0:f=this.__internal.delay;break;case 1:\"number\"==typeof a?f=a:(d=a,f=this.__internal.delay);break;case 2:d=a,f=c}return this.__internal.closeButton=y.defaults.notifier.closeButton,void 0!==d&&this.setContent(d),x.__internal.position.indexOf(\"top\")<0?l.appendChild(this.element):l.insertBefore(this.element,l.firstChild),k=this.element.offsetWidth,b(this.element,n.visible),t(this.element,\"click\",this.__internal.clickHandler),this.delay(f)}return this},ondismiss:function(){},callback:h,dismiss:function(a){return this.__internal.pushed&&(p(this),\"function\"==typeof this.ondismiss&&!1===this.ondismiss.call(this)||(u(this.element,\"click\",this.__internal.clickHandler),void 0!==this.element&&this.element.parentNode===l&&(this.__internal.transitionTimeout=setTimeout(this.__internal.transitionEndHandler,v.supported?1e3:100),c(this.element,n.visible),\"function\"==typeof this.callback&&this.callback.call(this,a)),f(this))),this},delay:function(a){if(p(this),this.__internal.delay=void 0===a||isNaN(+a)?x.__internal.delay:+a,this.__internal.delay>0){var b=this;this.__internal.timer=setTimeout(function(){b.dismiss()},1e3*this.__internal.delay)}return this},setContent:function(c){if(\"string\"==typeof c?(g(this.element),this.element.innerHTML=c):c instanceof a.HTMLElement&&this.element.firstChild!==c&&(g(this.element),this.element.appendChild(c)),this.__internal.closeButton){var d=document.createElement(\"span\");b(d,n.close),d.setAttribute(\"data-close\",!0),this.element.appendChild(d)}return this},dismissOthers:function(){return x.dismissAll(this),this}})}var k,l,m=[],n=p.notifier.classes,o=n.base;return{setting:function(a,b){if(d(this),void 0===b)return this.__internal[a];switch(a){case\"position\":this.__internal.position=b,h(this);break;case\"delay\":this.__internal.delay=b}return this},set:function(a,b){return this.setting(a,b),this},get:function(a){return this.setting(a)},create:function(a,b){d(this);var c=document.createElement(\"div\");return c.className=n.message+(\"string\"==typeof a&&\"\"!==a?\" \"+n.prefix+a:\"\"),i(c,b)},dismissAll:function(a){for(var b=m.slice(0),c=0;c<b.length;c+=1){var d=b[c];void 0!==a&&a===d||d.dismiss()}}}}(),y=new m;y.dialog(\"alert\",function(){return{main:function(a,b,c){var d,e,f;switch(arguments.length){case 1:e=a;break;case 2:\"function\"==typeof b?(e=a,f=b):(d=a,e=b);break;case 3:d=a,e=b,f=c}return this.set(\"title\",d),this.set(\"message\",e),this.set(\"onok\",f),this},setup:function(){return{buttons:[{text:y.defaults.glossary.ok,key:o.ESC,invokeOnClose:!0,className:y.defaults.theme.ok}],focus:{element:0,select:!1},options:{maximizable:!1,resizable:!1}}},build:function(){},prepare:function(){},setMessage:function(a){this.setContent(a)},settings:{message:void 0,onok:void 0,label:void 0},settingUpdated:function(a,b,c){switch(a){case\"message\":this.setMessage(c);break;case\"label\":this.__internal.buttons[0].element&&(this.__internal.buttons[0].element.innerHTML=c)}},\ncallback:function(a){if(\"function\"==typeof this.get(\"onok\")){var b=this.get(\"onok\").call(this,a);void 0!==b&&(a.cancel=!b)}}}}),y.dialog(\"confirm\",function(){function a(a){null!==c.timer&&(clearInterval(c.timer),c.timer=null,a.__internal.buttons[c.index].element.innerHTML=c.text)}function b(b,d,e){a(b),c.duration=e,c.index=d,c.text=b.__internal.buttons[d].element.innerHTML,c.timer=setInterval(j(b,c.task),1e3),c.task(null,b)}var c={timer:null,index:null,text:null,duration:null,task:function(b,d){if(d.isOpen()){if(d.__internal.buttons[c.index].element.innerHTML=c.text+\" (&#8207;\"+c.duration+\"&#8207;) \",c.duration-=1,-1===c.duration){a(d);var e=d.__internal.buttons[c.index],f=k(c.index,e);\"function\"==typeof d.callback&&d.callback.apply(d,[f]),!1!==f.close&&d.close()}}else a(d)}};return{main:function(a,b,c,d){var e,f,g,h;switch(arguments.length){case 1:f=a;break;case 2:f=a,g=b;break;case 3:f=a,g=b,h=c;break;case 4:e=a,f=b,g=c,h=d}return this.set(\"title\",e),this.set(\"message\",f),this.set(\"onok\",g),this.set(\"oncancel\",h),this},setup:function(){return{buttons:[{text:y.defaults.glossary.ok,key:o.ENTER,className:y.defaults.theme.ok},{text:y.defaults.glossary.cancel,key:o.ESC,invokeOnClose:!0,className:y.defaults.theme.cancel}],focus:{element:0,select:!1},options:{maximizable:!1,resizable:!1}}},build:function(){},prepare:function(){},setMessage:function(a){this.setContent(a)},settings:{message:null,labels:null,onok:null,oncancel:null,defaultFocus:null,reverseButtons:null},settingUpdated:function(a,b,c){switch(a){case\"message\":this.setMessage(c);break;case\"labels\":\"ok\"in c&&this.__internal.buttons[0].element&&(this.__internal.buttons[0].text=c.ok,this.__internal.buttons[0].element.innerHTML=c.ok),\"cancel\"in c&&this.__internal.buttons[1].element&&(this.__internal.buttons[1].text=c.cancel,this.__internal.buttons[1].element.innerHTML=c.cancel);break;case\"reverseButtons\":!0===c?this.elements.buttons.primary.appendChild(this.__internal.buttons[0].element):this.elements.buttons.primary.appendChild(this.__internal.buttons[1].element);break;case\"defaultFocus\":this.__internal.focus.element=\"ok\"===c?0:1}},callback:function(b){a(this);var c;switch(b.index){case 0:\"function\"==typeof this.get(\"onok\")&&void 0!==(c=this.get(\"onok\").call(this,b))&&(b.cancel=!c);break;case 1:\"function\"==typeof this.get(\"oncancel\")&&void 0!==(c=this.get(\"oncancel\").call(this,b))&&(b.cancel=!c)}},autoOk:function(a){return b(this,0,a),this},autoCancel:function(a){return b(this,1,a),this}}}),y.dialog(\"prompt\",function(){var b=document.createElement(\"INPUT\"),c=document.createElement(\"P\");return{main:function(a,b,c,d,e){var f,g,h,i,j;switch(arguments.length){case 1:g=a;break;case 2:g=a,h=b;break;case 3:g=a,h=b,i=c;break;case 4:g=a,h=b,i=c,j=d;break;case 5:f=a,g=b,h=c,i=d,j=e}return this.set(\"title\",f),this.set(\"message\",g),this.set(\"value\",h),this.set(\"onok\",i),this.set(\"oncancel\",j),this},setup:function(){return{buttons:[{text:y.defaults.glossary.ok,key:o.ENTER,className:y.defaults.theme.ok},{text:y.defaults.glossary.cancel,key:o.ESC,invokeOnClose:!0,className:y.defaults.theme.cancel}],focus:{element:b,select:!0},options:{maximizable:!1,resizable:!1}}},build:function(){b.className=y.defaults.theme.input,b.setAttribute(\"type\",\"text\"),b.value=this.get(\"value\"),this.elements.content.appendChild(c),this.elements.content.appendChild(b)},prepare:function(){},setMessage:function(b){\"string\"==typeof b?(g(c),c.innerHTML=b):b instanceof a.HTMLElement&&c.firstChild!==b&&(g(c),c.appendChild(b))},settings:{message:void 0,labels:void 0,onok:void 0,oncancel:void 0,value:\"\",type:\"text\",reverseButtons:void 0},settingUpdated:function(a,c,d){switch(a){case\"message\":this.setMessage(d);break;case\"value\":b.value=d;break;case\"type\":switch(d){case\"text\":case\"color\":case\"date\":case\"datetime-local\":case\"email\":case\"month\":case\"number\":case\"password\":case\"search\":case\"tel\":case\"time\":case\"week\":b.type=d;break;default:b.type=\"text\"}break;case\"labels\":d.ok&&this.__internal.buttons[0].element&&(this.__internal.buttons[0].element.innerHTML=d.ok),d.cancel&&this.__internal.buttons[1].element&&(this.__internal.buttons[1].element.innerHTML=d.cancel);break;case\"reverseButtons\":!0===d?this.elements.buttons.primary.appendChild(this.__internal.buttons[0].element):this.elements.buttons.primary.appendChild(this.__internal.buttons[1].element)}},callback:function(a){var c;switch(a.index){case 0:this.settings.value=b.value,\"function\"==typeof this.get(\"onok\")&&void 0!==(c=this.get(\"onok\").call(this,a,this.settings.value))&&(a.cancel=!c);break;case 1:\"function\"==typeof this.get(\"oncancel\")&&void 0!==(c=this.get(\"oncancel\").call(this,a))&&(a.cancel=!c),a.cancel||(b.value=this.settings.value)}}}}), true&&\"object\"==typeof module.exports?module.exports=y: true?!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = (function(){return y}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),\n\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)):0}(\"undefined\"!=typeof window?window:this);//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvYWxlcnRpZnlqcy9idWlsZC9hbGVydGlmeS5taW4uanMiLCJtYXBwaW5ncyI6IkFBQUE7QUFDQSxhQUFhLGFBQWEsZ0JBQWdCLG1CQUFtQixnQkFBZ0Isb0RBQW9ELFdBQVcsTUFBTSxzQkFBc0Isb0JBQW9CLHdCQUF3QixhQUFhLDBEQUEwRCxhQUFhLDZGQUE2RixhQUFhLCtGQUErRixjQUFjLEtBQUssWUFBWSw0QkFBNEIsY0FBYyxxQkFBcUIsTUFBTSxxQkFBcUIsS0FBSyxZQUFZLFdBQVcscUJBQXFCLFNBQVMsa0RBQWtELG1KQUFtSix1QkFBdUIsS0FBSyxtREFBbUQsU0FBUyxTQUFTLGdCQUFnQixlQUFlLHNCQUFzQix5R0FBeUcsZ0JBQWdCLGtCQUFrQix1QkFBdUIsaUJBQWlCLG1CQUFtQiwwQkFBMEIsOEJBQThCLDRCQUE0QixnQkFBZ0IsT0FBTyw0QkFBNEIsZ0JBQWdCLHVEQUF1RCxhQUFhLGdCQUFnQixnREFBZ0QsU0FBUyxjQUFjLGtCQUFrQixxREFBcUQsb0JBQW9CLE9BQU8sdUJBQXVCLHlDQUF5QyxpQ0FBaUMsMENBQTBDLFNBQVMsT0FBTyxvQ0FBb0Msb0NBQW9DLGtGQUFrRixpQkFBaUIscUJBQXFCLHdDQUF3Qyx5QkFBeUIsNkZBQTZGLFlBQVksZ0hBQWdILGVBQWUsZ0VBQWdFLHNCQUFzQix5QkFBeUIsV0FBVyxNQUFNLFdBQVcsOEJBQThCLHlCQUF5Qix3Q0FBd0MsV0FBVywrQkFBK0IscUJBQXFCLDJCQUEyQixtQkFBbUIseUJBQXlCLDBCQUEwQiwrQkFBK0IseUJBQXlCLGtDQUFrQyx5QkFBeUIsdUNBQXVDLHVCQUF1QixxQ0FBcUMseUJBQXlCLHVDQUF1Qyx1QkFBdUIsaUJBQWlCLDJDQUEyQyxzREFBc0QsSUFBSSxvYUFBb2Esd0RBQXdELGtOQUFrTixXQUFXLCtKQUErSixRQUFRLGtEQUFrRCxRQUFRLG9CQUFvQix3QkFBd0IsV0FBVyxJQUFJLDhCQUE4QixZQUFZLGVBQWUsTUFBTSxFQUFFLGlFQUFpRSxVQUFVLDBCQUEwQiwwQkFBMEIsb0JBQW9CLFNBQVMsdUJBQXVCLDZCQUE2QixvQkFBb0IsU0FBUyxjQUFjLGdCQUFnQixpS0FBaUssMERBQTBELFlBQVksTUFBTSxPQUFPLG9CQUFvQixnQkFBZ0IsY0FBYyxrQkFBa0IsdUZBQXVGLE1BQU0sK0RBQStELG9CQUFvQixLQUFLLGtCQUFrQix1QkFBdUIsWUFBWSxzQ0FBc0MsRUFBRSxTQUFTLHdDQUF3QyxtQkFBbUIsTUFBTSx3QkFBd0IsZ0RBQWdELFVBQVUsb0JBQW9CLHNHQUFzRyxtaUJBQW1pQix3UEFBd1AsTUFBTSxvYkFBb2IsaWNBQWljLCtOQUErTixZQUFZLDhCQUE4QixNQUFNLDhCQUE4QiwrS0FBK0ssc0dBQXNHLDBHQUEwRywyUUFBMlEsb0tBQW9LLG1FQUFtRSwyQ0FBMkMsYUFBYSxjQUFjLGFBQWEsa0JBQWtCLGFBQWEsZ0JBQWdCLFdBQVcsTUFBTSxXQUFXLHVDQUF1Qyw4TEFBOEwsY0FBYyw4UkFBOFIsa0JBQWtCLGlIQUFpSCxjQUFjLDZGQUE2RixjQUFjLDJJQUEySSxjQUFjLHVFQUF1RSxjQUFjLG1GQUFtRixnQkFBZ0IsNkJBQTZCLFdBQVcsOEJBQThCLDBJQUEwSSxvQkFBb0IsVUFBVSwyQkFBMkIsTUFBTSxpQkFBaUIsTUFBTSxpQkFBaUIsTUFBTSxxQkFBcUIsTUFBTSxrQkFBa0IsTUFBTSxvQkFBb0IsTUFBTSx1QkFBdUIsTUFBTSxvQkFBb0IsTUFBTSxvQkFBb0IsTUFBTSxzQkFBc0IsTUFBTSxtSUFBbUksTUFBTSx1SUFBdUksTUFBTSwwQkFBMEIsTUFBTSx5QkFBeUIsb0VBQW9FLHNCQUFzQixPQUFPLG9CQUFvQix1SEFBdUgsS0FBSyxNQUFNLGtDQUFrQyxRQUFRLHFHQUFxRywwQkFBMEIsaUJBQWlCLDBCQUEwQixFQUFFLEtBQUsseUVBQXlFLDZFQUE2RSx1QkFBdUIsaUJBQWlCLHVCQUF1QixHQUFHLFNBQVMsY0FBYyxNQUFNLGdCQUFnQiw4REFBOEQsNEJBQTRCLGdCQUFnQiwrQkFBK0Isb0RBQW9ELE1BQU0sNERBQTRELE1BQU0sb0NBQW9DLFNBQVMsY0FBYyxtQkFBbUIsY0FBYyxtQkFBbUIsY0FBYyxxRkFBcUYsY0FBYyxtRkFBbUYsY0FBYyxnRkFBZ0YsY0FBYyxVQUFVLDhIQUE4SCxjQUFjLHFHQUFxRyw4SEFBOEgsWUFBWSx3UEFBd1AsY0FBYywwQ0FBMEMsY0FBYyxrSUFBa0ksY0FBYyx5RkFBeUYsY0FBYyxnR0FBZ0csZ0JBQWdCLDhDQUE4Qyw2QkFBNkIsMkRBQTJELE1BQU0sZ0JBQWdCLGtEQUFrRCw4QkFBOEIsTUFBTSw4QkFBOEIsOEJBQThCLGFBQWEsZ0ZBQWdGLFFBQVEsZ0JBQWdCLDZCQUE2QixnQkFBZ0IsOEJBQThCLEVBQUUsY0FBYyx5QkFBeUIsZ0NBQWdDLHNIQUFzSCxpQkFBaUIsYUFBYSxjQUFjLGdDQUFnQyw0QkFBNEIsbUNBQW1DLFdBQVcsd0RBQXdELDJEQUEyRCw0REFBNEQsNEdBQTRHLGlCQUFpQixLQUFLLGdCQUFnQixlQUFlLEtBQUsscUNBQXFDLHlCQUF5Qix3SUFBd0ksTUFBTSx3REFBd0QsTUFBTSxtQ0FBbUMsd0tBQXdLLGdCQUFnQiwyQkFBMkIsS0FBSyx3QkFBd0IsT0FBTyxNQUFNLG1CQUFtQiwySEFBMkgsa0NBQWtDLCtFQUErRSxnQkFBZ0Isb0VBQW9FLGVBQWUsWUFBWSxXQUFXLE1BQU0sV0FBVyxzRkFBc0YsY0FBYyxvQkFBb0IsOERBQThELGlCQUFpQiw0SkFBNEosaUJBQWlCLHFPQUFxTyxpQkFBaUIsMEJBQTBCLHdFQUF3RSxpQkFBaUIsMEJBQTBCLHdMQUF3TCxpQkFBaUIsa0RBQWtELGNBQWMsb0hBQW9ILHdCQUF3Qiw0T0FBNE8sa0JBQWtCLEdBQUcsK0JBQStCLHdCQUF3QixJQUFJLDZGQUE2RixPQUFPLG1CQUFtQixxR0FBcUcsZUFBZSxPQUFPLE1BQU0sZ0hBQWdILGNBQWMsT0FBTyxTQUFTLDJGQUEyRixlQUFlLFFBQVEsd0JBQXdCLDRCQUE0QixlQUFlLDJIQUEySCxtQkFBbUIsZ0JBQWdCLEdBQUcsK0JBQStCLHdCQUF3QixRQUFRLHVEQUF1RCxVQUFVLGdLQUFnSyxvQ0FBb0MsZ0dBQWdHLGlCQUFpQixxQkFBcUIsTUFBTSwwRkFBMEYsK0RBQStELHdCQUF3QixxVkFBcVYsZUFBZSxPQUFPLE1BQU0sb0pBQW9KLGNBQWMsT0FBTyxTQUFTLGdHQUFnRyxlQUFlLFFBQVEsd0JBQXdCLHVKQUF1SixlQUFlLGlJQUFpSSxjQUFjLFlBQVksV0FBVyxNQUFNLFdBQVcsbUNBQW1DLGVBQWUsKzNCQUErM0IsZUFBZSxvc0JBQW9zQixlQUFlLGlFQUFpRSxlQUFlLGlFQUFpRSxlQUFlLHFJQUFxSSxlQUFlLHFJQUFxSSxlQUFlLHFKQUFxSixlQUFlLHFKQUFxSixlQUFlLDJEQUEyRCxlQUFlLDJEQUEyRCwySEFBMkgseWZBQXlmLGdIQUFnSCw2RkFBNkYsS0FBSyxna0JBQWdrQixxSUFBcUksT0FBTywyQkFBMkIsOEJBQThCLG9CQUFvQiwyREFBMkQsd0JBQXdCLDZEQUE2RCxxQkFBcUIsMkRBQTJELHFCQUFxQix3Q0FBd0Msb0JBQW9CLHdDQUF3QyxnQkFBZ0IscUNBQXFDLGtCQUFrQixxQ0FBcUMseUJBQXlCLHlCQUF5QixzQkFBc0IseUJBQXlCLGlCQUFpQix1Q0FBdUMsd0ZBQXdGLEdBQUcsK0JBQStCLHdCQUF3QixnQkFBZ0Isc0VBQXNFLFlBQVksd0JBQXdCLHdEQUF3RCxxREFBcUQsb0pBQW9KLDJCQUEyQix3UEFBd1AsWUFBWSx1QkFBdUIsNERBQTRELFdBQVcsTUFBTSxvSEFBb0gsbUJBQW1CLGlCQUFpQiwrREFBK0QsS0FBSyxpQkFBaUIsTUFBTSxpQkFBaUIsdUVBQXVFLGFBQWEsbUJBQW1CLDhCQUE4QixpQkFBaUIsdUJBQXVCLHVCQUF1Qix3TkFBd04sd0JBQXdCLDZOQUE2Tix1QkFBdUIsdUJBQXVCLG9CQUFvQixtQ0FBbUMsbURBQW1ELFdBQVcsc0JBQXNCLDhCQUE4QixNQUFNLEtBQUssZ3RCQUFndEIseUJBQXlCLDZDQUE2Qyx3QkFBd0IsSUFBSSwwSkFBMEosWUFBWSxrQkFBa0IsbXlCQUFteUIsd0JBQXdCLDZCQUE2QixvQkFBb0Isb0ZBQW9GLFVBQVUsMERBQTBELGdCQUFnQixjQUFjLGtCQUFrQixjQUFjLHNFQUFzRSxpQ0FBaUMsOEdBQThHLDJEQUEyRCxjQUFjLGlDQUFpQyxjQUFjLGdEQUFnRCxjQUFjLDRDQUE0Qyx1Q0FBdUMsTUFBTSxxQ0FBcUMsTUFBTSx5Q0FBeUMsTUFBTSwyQ0FBMkMsTUFBTSwrQ0FBK0MsTUFBTSxzREFBc0QsZ0JBQWdCLGdCQUFnQixzRkFBc0YsZ0JBQWdCLCtDQUErQyxjQUFjLG9DQUFvQyw2R0FBNkcsOEVBQThFLGNBQWMsOEVBQThFLFVBQVUsNkJBQTZCLDRCQUE0QixnQkFBZ0IsUUFBUSx5QkFBeUIsK0JBQStCLE1BQU0sNERBQTRELE1BQU0sZUFBZSx1VUFBdVUsWUFBWSx1QkFBdUIsZ0NBQWdDLG9hQUFvYSxtQkFBbUIsc0dBQXNHLFdBQVcsNENBQTRDLFlBQVksNEJBQTRCLFlBQVksd0JBQXdCLHFNQUFxTSxxQ0FBcUMseUVBQXlFLFlBQVksMEJBQTBCLGdDQUFnQyxFQUFFLDJDQUEyQyxPQUFPLHNCQUFzQixnREFBZ0QsVUFBVSxrREFBa0QsTUFBTSxvQ0FBb0MsWUFBWSxtQkFBbUIsOEJBQThCLGlCQUFpQix1QkFBdUIsc0JBQXNCLFFBQVEsb0NBQW9DLG1GQUFtRix3QkFBd0IseUJBQXlCLFdBQVcsTUFBTSxXQUFXLGtDQUFrQyxXQUFXLDRCQUE0QixPQUFPLHFCQUFxQixVQUFVLHlCQUF5QixXQUFXLE1BQU0sZ0RBQWdELE1BQU0sbUJBQW1CLHlFQUF5RSxrQkFBa0IsT0FBTyxVQUFVLHFGQUFxRixTQUFTLG9CQUFvQixVQUFVLDhCQUE4QixtQkFBbUIscUJBQXFCLHdCQUF3QixtQkFBbUIsV0FBVyx3Q0FBd0MsZ0NBQWdDLFVBQVUsaUNBQWlDLE1BQU0sa0dBQWtHO0FBQzN1K0IscUJBQXFCLHdDQUF3QyxvQ0FBb0MsNkJBQTZCLGdDQUFnQyxjQUFjLDZHQUE2RyxrQkFBa0IsaUlBQWlJLE9BQU8saUVBQWlFLGVBQWUsb0VBQW9FLHFCQUFxQixtQ0FBbUMsS0FBSyxtREFBbUQsZ0ZBQWdGLFlBQVksT0FBTyx1QkFBdUIsWUFBWSx5QkFBeUIsV0FBVyxNQUFNLGVBQWUsTUFBTSxtQkFBbUIsTUFBTSx1QkFBdUIsZ0dBQWdHLGtCQUFrQixPQUFPLFVBQVUsc0VBQXNFLEVBQUUsNkZBQTZGLFNBQVMsb0JBQW9CLFVBQVUsOEJBQThCLG1CQUFtQixxQkFBcUIsd0JBQXdCLG1CQUFtQixXQUFXLHVGQUF1RixnQ0FBZ0MsVUFBVSxpQ0FBaUMsTUFBTSx1U0FBdVMsTUFBTSx3TEFBd0wsTUFBTSwrREFBK0Qsc0JBQXNCLFFBQVEsTUFBTSxnQkFBZ0Isc0dBQXNHLE1BQU0sK0dBQStHLG9CQUFvQix3QkFBd0Isd0JBQXdCLDBCQUEwQiwrQkFBK0Isb0VBQW9FLE9BQU8seUJBQXlCLGNBQWMseUJBQXlCLFdBQVcsTUFBTSxlQUFlLE1BQU0sbUJBQW1CLE1BQU0sdUJBQXVCLE1BQU0sMkJBQTJCLG9IQUFvSCxrQkFBa0IsT0FBTyxVQUFVLHNFQUFzRSxFQUFFLDZGQUE2RixTQUFTLG9CQUFvQixVQUFVLDhCQUE4QixrQkFBa0IscUtBQXFLLHFCQUFxQix3QkFBd0IsOEdBQThHLFdBQVcsb0dBQW9HLGdDQUFnQyxVQUFVLGlDQUFpQyxNQUFNLHNCQUFzQixNQUFNLHFCQUFxQixpS0FBaUssTUFBTSxzQkFBc0IsTUFBTSxpTkFBaU4sTUFBTSx5TEFBeUwsc0JBQXNCLE1BQU0sZ0JBQWdCLHNKQUFzSixNQUFNLHlKQUF5SixFQUFFLEtBQXVCLG1EQUFtRCxLQUFxQyxDQUFDLGlDQUFPLEVBQUUsbUNBQUMsV0FBVyxTQUFTO0FBQUEsa0dBQUMsQ0FBQyxDQUEwQixDQUFDIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL2FsZXJ0aWZ5anMvYnVpbGQvYWxlcnRpZnkubWluLmpzPzA0NDYiXSwic291cmNlc0NvbnRlbnQiOlsiLyohIGFsZXJ0aWZ5anMgLSB2MS4xMy4xIC0gTW9oYW1tYWQgWW91bmVzIDxNb2hhbW1hZEBhbGVydGlmeWpzLmNvbT4gKGh0dHA6Ly9hbGVydGlmeWpzLmNvbSkgKi9cbiFmdW5jdGlvbihhKXtcInVzZSBzdHJpY3RcIjtmdW5jdGlvbiBiKGEsYil7YS5jbGFzc05hbWUrPVwiIFwiK2J9ZnVuY3Rpb24gYyhhLGIpe2Zvcih2YXIgYz1hLmNsYXNzTmFtZS5zcGxpdChcIiBcIiksZD1iLnNwbGl0KFwiIFwiKSxlPTA7ZTxkLmxlbmd0aDtlKz0xKXt2YXIgZj1jLmluZGV4T2YoZFtlXSk7Zj4tMSYmYy5zcGxpY2UoZiwxKX1hLmNsYXNzTmFtZT1jLmpvaW4oXCIgXCIpfWZ1bmN0aW9uIGQoKXtyZXR1cm5cInJ0bFwiPT09YS5nZXRDb21wdXRlZFN0eWxlKGRvY3VtZW50LmJvZHkpLmRpcmVjdGlvbn1mdW5jdGlvbiBlKCl7cmV0dXJuIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCYmZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbFRvcHx8ZG9jdW1lbnQuYm9keS5zY3JvbGxUb3B9ZnVuY3Rpb24gZigpe3JldHVybiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQmJmRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxMZWZ0fHxkb2N1bWVudC5ib2R5LnNjcm9sbExlZnR9ZnVuY3Rpb24gZyhhKXtmb3IoO2EubGFzdENoaWxkOylhLnJlbW92ZUNoaWxkKGEubGFzdENoaWxkKX1mdW5jdGlvbiBoKGEpe2lmKG51bGw9PT1hKXJldHVybiBhO3ZhciBiO2lmKEFycmF5LmlzQXJyYXkoYSkpe2I9W107Zm9yKHZhciBjPTA7YzxhLmxlbmd0aDtjKz0xKWIucHVzaChoKGFbY10pKTtyZXR1cm4gYn1pZihhIGluc3RhbmNlb2YgRGF0ZSlyZXR1cm4gbmV3IERhdGUoYS5nZXRUaW1lKCkpO2lmKGEgaW5zdGFuY2VvZiBSZWdFeHApcmV0dXJuIGI9bmV3IFJlZ0V4cChhLnNvdXJjZSksYi5nbG9iYWw9YS5nbG9iYWwsYi5pZ25vcmVDYXNlPWEuaWdub3JlQ2FzZSxiLm11bHRpbGluZT1hLm11bHRpbGluZSxiLmxhc3RJbmRleD1hLmxhc3RJbmRleCxiO2lmKFwib2JqZWN0XCI9PXR5cGVvZiBhKXtiPXt9O2Zvcih2YXIgZCBpbiBhKWEuaGFzT3duUHJvcGVydHkoZCkmJihiW2RdPWgoYVtkXSkpO3JldHVybiBifXJldHVybiBhfWZ1bmN0aW9uIGkoYSxiKXtpZihhLmVsZW1lbnRzKXt2YXIgYz1hLmVsZW1lbnRzLnJvb3Q7Yy5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGMpLGRlbGV0ZSBhLmVsZW1lbnRzLGEuc2V0dGluZ3M9aChhLl9fc2V0dGluZ3MpLGEuX19pbml0PWIsZGVsZXRlIGEuX19pbnRlcm5hbH19ZnVuY3Rpb24gaihhLGIpe3JldHVybiBmdW5jdGlvbigpe2lmKGFyZ3VtZW50cy5sZW5ndGg+MCl7Zm9yKHZhciBjPVtdLGQ9MDtkPGFyZ3VtZW50cy5sZW5ndGg7ZCs9MSljLnB1c2goYXJndW1lbnRzW2RdKTtyZXR1cm4gYy5wdXNoKGEpLGIuYXBwbHkoYSxjKX1yZXR1cm4gYi5hcHBseShhLFtudWxsLGFdKX19ZnVuY3Rpb24gayhhLGIpe3JldHVybntpbmRleDphLGJ1dHRvbjpiLGNhbmNlbDohMX19ZnVuY3Rpb24gbChhLGIpe2lmKFwiZnVuY3Rpb25cIj09dHlwZW9mIGIuZ2V0KGEpKXJldHVybiBiLmdldChhKS5jYWxsKGIpfWZ1bmN0aW9uIG0oKXtmdW5jdGlvbiBhKGEsYil7Zm9yKHZhciBjIGluIGIpYi5oYXNPd25Qcm9wZXJ0eShjKSYmKGFbY109YltjXSk7cmV0dXJuIGF9ZnVuY3Rpb24gYihhKXt2YXIgYj1kW2FdLmRpYWxvZztyZXR1cm4gYiYmXCJmdW5jdGlvblwiPT10eXBlb2YgYi5fX2luaXQmJmIuX19pbml0KGIpLGJ9ZnVuY3Rpb24gYyhiLGMsZSxmKXt2YXIgZz17ZGlhbG9nOm51bGwsZmFjdG9yeTpjfTtyZXR1cm4gdm9pZCAwIT09ZiYmKGcuZmFjdG9yeT1mdW5jdGlvbigpe3JldHVybiBhKG5ldyBkW2ZdLmZhY3RvcnksbmV3IGMpfSksZXx8KGcuZGlhbG9nPWEobmV3IGcuZmFjdG9yeSx3KSksZFtiXT1nfXZhciBkPXt9O3JldHVybntkZWZhdWx0czpwLGRpYWxvZzpmdW5jdGlvbihkLGUsZixnKXtpZihcImZ1bmN0aW9uXCIhPXR5cGVvZiBlKXJldHVybiBiKGQpO2lmKHRoaXMuaGFzT3duUHJvcGVydHkoZCkpdGhyb3cgbmV3IEVycm9yKFwiYWxlcnRpZnkuZGlhbG9nOiBuYW1lIGFscmVhZHkgZXhpc3RzXCIpO3ZhciBoPWMoZCxlLGYsZyk7dGhpc1tkXT1mP2Z1bmN0aW9uKCl7aWYoMD09PWFyZ3VtZW50cy5sZW5ndGgpcmV0dXJuIGguZGlhbG9nO3ZhciBiPWEobmV3IGguZmFjdG9yeSx3KTtyZXR1cm4gYiYmXCJmdW5jdGlvblwiPT10eXBlb2YgYi5fX2luaXQmJmIuX19pbml0KGIpLGIubWFpbi5hcHBseShiLGFyZ3VtZW50cyksYi5zaG93LmFwcGx5KGIpfTpmdW5jdGlvbigpe2lmKGguZGlhbG9nJiZcImZ1bmN0aW9uXCI9PXR5cGVvZiBoLmRpYWxvZy5fX2luaXQmJmguZGlhbG9nLl9faW5pdChoLmRpYWxvZyksMD09PWFyZ3VtZW50cy5sZW5ndGgpcmV0dXJuIGguZGlhbG9nO3ZhciBhPWguZGlhbG9nO3JldHVybiBhLm1haW4uYXBwbHkoaC5kaWFsb2csYXJndW1lbnRzKSxhLnNob3cuYXBwbHkoaC5kaWFsb2cpfX0sY2xvc2VBbGw6ZnVuY3Rpb24oYSl7Zm9yKHZhciBiPXEuc2xpY2UoMCksYz0wO2M8Yi5sZW5ndGg7Yys9MSl7dmFyIGQ9YltjXTt2b2lkIDAhPT1hJiZhPT09ZHx8ZC5jbG9zZSgpfX0sc2V0dGluZzpmdW5jdGlvbihhLGMsZCl7aWYoXCJub3RpZmllclwiPT09YSlyZXR1cm4geC5zZXR0aW5nKGMsZCk7dmFyIGU9YihhKTtyZXR1cm4gZT9lLnNldHRpbmcoYyxkKTp2b2lkIDB9LHNldDpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIHRoaXMuc2V0dGluZyhhLGIsYyl9LGdldDpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLnNldHRpbmcoYSxiKX0sbm90aWZ5OmZ1bmN0aW9uKGEsYixjLGQpe3JldHVybiB4LmNyZWF0ZShiLGQpLnB1c2goYSxjKX0sbWVzc2FnZTpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIHguY3JlYXRlKG51bGwsYykucHVzaChhLGIpfSxzdWNjZXNzOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4geC5jcmVhdGUoXCJzdWNjZXNzXCIsYykucHVzaChhLGIpfSxlcnJvcjpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIHguY3JlYXRlKFwiZXJyb3JcIixjKS5wdXNoKGEsYil9LHdhcm5pbmc6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiB4LmNyZWF0ZShcIndhcm5pbmdcIixjKS5wdXNoKGEsYil9LGRpc21pc3NBbGw6ZnVuY3Rpb24oKXt4LmRpc21pc3NBbGwoKX19fXZhciBuPVwiOm5vdCg6ZGlzYWJsZWQpOm5vdCguYWpzLXJlc2V0KVwiLG89e0VOVEVSOjEzLEVTQzoyNyxGMToxMTIsRjEyOjEyMyxMRUZUOjM3LFJJR0hUOjM5LFRBQjo5fSxwPXthdXRvUmVzZXQ6ITAsYmFzaWM6ITEsY2xvc2FibGU6ITAsY2xvc2FibGVCeURpbW1lcjohMCxpbnZva2VPbkNsb3NlT2ZmOiExLGZyYW1lbGVzczohMSxkZWZhdWx0Rm9jdXNPZmY6ITEsbWFpbnRhaW5Gb2N1czohMCxtYXhpbWl6YWJsZTohMCxtb2RhbDohMCxtb3ZhYmxlOiEwLG1vdmVCb3VuZGVkOiExLG92ZXJmbG93OiEwLHBhZGRpbmc6ITAscGlubmFibGU6ITAscGlubmVkOiEwLHByZXZlbnRCb2R5U2hpZnQ6ITEscmVzaXphYmxlOiEwLHN0YXJ0TWF4aW1pemVkOiExLHRyYW5zaXRpb246XCJwdWxzZVwiLHRyYW5zaXRpb25PZmY6ITEsdGFiYmFibGU6W1wiYnV0dG9uXCIsXCJbaHJlZl1cIixcImlucHV0XCIsXCJzZWxlY3RcIixcInRleHRhcmVhXCIsJ1t0YWJpbmRleF06bm90KFt0YWJpbmRleF49XCItXCJdKScrbl0uam9pbihuK1wiLFwiKSxub3RpZmllcjp7ZGVsYXk6NSxwb3NpdGlvbjpcImJvdHRvbS1yaWdodFwiLGNsb3NlQnV0dG9uOiExLGNsYXNzZXM6e2Jhc2U6XCJhbGVydGlmeS1ub3RpZmllclwiLHByZWZpeDpcImFqcy1cIixtZXNzYWdlOlwiYWpzLW1lc3NhZ2VcIix0b3A6XCJhanMtdG9wXCIscmlnaHQ6XCJhanMtcmlnaHRcIixib3R0b206XCJhanMtYm90dG9tXCIsbGVmdDpcImFqcy1sZWZ0XCIsY2VudGVyOlwiYWpzLWNlbnRlclwiLHZpc2libGU6XCJhanMtdmlzaWJsZVwiLGhpZGRlbjpcImFqcy1oaWRkZW5cIixjbG9zZTpcImFqcy1jbG9zZVwifX0sZ2xvc3Nhcnk6e3RpdGxlOlwiQWxlcnRpZnlKU1wiLG9rOlwiT0tcIixjYW5jZWw6XCJDYW5jZWxcIixhY2NjcHQ6XCJBY2NlcHRcIixkZW55OlwiRGVueVwiLGNvbmZpcm06XCJDb25maXJtXCIsZGVjbGluZTpcIkRlY2xpbmVcIixjbG9zZTpcIkNsb3NlXCIsbWF4aW1pemU6XCJNYXhpbWl6ZVwiLHJlc3RvcmU6XCJSZXN0b3JlXCJ9LHRoZW1lOntpbnB1dDpcImFqcy1pbnB1dFwiLG9rOlwiYWpzLW9rXCIsY2FuY2VsOlwiYWpzLWNhbmNlbFwifSxob29rczp7cHJlaW5pdDpmdW5jdGlvbigpe30scG9zdGluaXQ6ZnVuY3Rpb24oKXt9fX0scT1bXSxyPSExO3RyeXt2YXIgcz1PYmplY3QuZGVmaW5lUHJvcGVydHkoe30sXCJwYXNzaXZlXCIse2dldDpmdW5jdGlvbigpe3I9ITB9fSk7YS5hZGRFdmVudExpc3RlbmVyKFwidGVzdFwiLHMscyksYS5yZW1vdmVFdmVudExpc3RlbmVyKFwidGVzdFwiLHMscyl9Y2F0Y2goeil7fXZhciB0PWZ1bmN0aW9uKGEsYixjLGQsZSl7YS5hZGRFdmVudExpc3RlbmVyKGIsYyxyP3tjYXB0dXJlOmQscGFzc2l2ZTplfTohMD09PWQpfSx1PWZ1bmN0aW9uKGEsYixjLGQsZSl7YS5yZW1vdmVFdmVudExpc3RlbmVyKGIsYyxyP3tjYXB0dXJlOmQscGFzc2l2ZTplfTohMD09PWQpfSx2PWZ1bmN0aW9uKCl7dmFyIGEsYixjPSExLGQ9e2FuaW1hdGlvbjpcImFuaW1hdGlvbmVuZFwiLE9BbmltYXRpb246XCJvQW5pbWF0aW9uRW5kIG9hbmltYXRpb25lbmRcIixtc0FuaW1hdGlvbjpcIk1TQW5pbWF0aW9uRW5kXCIsTW96QW5pbWF0aW9uOlwiYW5pbWF0aW9uZW5kXCIsV2Via2l0QW5pbWF0aW9uOlwid2Via2l0QW5pbWF0aW9uRW5kXCJ9O2ZvcihhIGluIGQpaWYodm9pZCAwIT09ZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnN0eWxlW2FdKXtiPWRbYV0sYz0hMDticmVha31yZXR1cm57dHlwZTpiLHN1cHBvcnRlZDpjfX0oKSx3PWZ1bmN0aW9uKCl7ZnVuY3Rpb24gbShhKXtpZighYS5fX2ludGVybmFsKXt5LmRlZmF1bHRzLmhvb2tzLnByZWluaXQoYSksZGVsZXRlIGEuX19pbml0LGEuX19zZXR0aW5nc3x8KGEuX19zZXR0aW5ncz1oKGEuc2V0dGluZ3MpKTt2YXIgYztcImZ1bmN0aW9uXCI9PXR5cGVvZiBhLnNldHVwPyhjPWEuc2V0dXAoKSxjLm9wdGlvbnM9Yy5vcHRpb25zfHx7fSxjLmZvY3VzPWMuZm9jdXN8fHt9KTpjPXtidXR0b25zOltdLGZvY3VzOntlbGVtZW50Om51bGwsc2VsZWN0OiExfSxvcHRpb25zOnt9fSxcIm9iamVjdFwiIT10eXBlb2YgYS5ob29rcyYmKGEuaG9va3M9e30pO3ZhciBkPVtdO2lmKEFycmF5LmlzQXJyYXkoYy5idXR0b25zKSlmb3IodmFyIGU9MDtlPGMuYnV0dG9ucy5sZW5ndGg7ZSs9MSl7dmFyIGY9Yy5idXR0b25zW2VdLGc9e307Zm9yKHZhciBpIGluIGYpZi5oYXNPd25Qcm9wZXJ0eShpKSYmKGdbaV09ZltpXSk7ZC5wdXNoKGcpfXZhciBrPWEuX19pbnRlcm5hbD17aXNPcGVuOiExLGFjdGl2ZUVsZW1lbnQ6ZG9jdW1lbnQuYm9keSx0aW1lckluOnZvaWQgMCx0aW1lck91dDp2b2lkIDAsYnV0dG9uczpkLGZvY3VzOmMuZm9jdXMsb3B0aW9uczp7dGl0bGU6dm9pZCAwLG1vZGFsOnZvaWQgMCxiYXNpYzp2b2lkIDAsZnJhbWVsZXNzOnZvaWQgMCxkZWZhdWx0Rm9jdXNPZmY6dm9pZCAwLHBpbm5lZDp2b2lkIDAsbW92YWJsZTp2b2lkIDAsbW92ZUJvdW5kZWQ6dm9pZCAwLHJlc2l6YWJsZTp2b2lkIDAsYXV0b1Jlc2V0OnZvaWQgMCxjbG9zYWJsZTp2b2lkIDAsY2xvc2FibGVCeURpbW1lcjp2b2lkIDAsaW52b2tlT25DbG9zZU9mZjp2b2lkIDAsbWF4aW1pemFibGU6dm9pZCAwLHN0YXJ0TWF4aW1pemVkOnZvaWQgMCxwaW5uYWJsZTp2b2lkIDAsdHJhbnNpdGlvbjp2b2lkIDAsdHJhbnNpdGlvbk9mZjp2b2lkIDAscGFkZGluZzp2b2lkIDAsb3ZlcmZsb3c6dm9pZCAwLG9uc2hvdzp2b2lkIDAsb25jbG9zaW5nOnZvaWQgMCxvbmNsb3NlOnZvaWQgMCxvbmZvY3VzOnZvaWQgMCxvbm1vdmU6dm9pZCAwLG9ubW92ZWQ6dm9pZCAwLG9ucmVzaXplOnZvaWQgMCxvbnJlc2l6ZWQ6dm9pZCAwLG9ubWF4aW1pemU6dm9pZCAwLG9ubWF4aW1pemVkOnZvaWQgMCxvbnJlc3RvcmU6dm9pZCAwLG9ucmVzdG9yZWQ6dm9pZCAwfSxyZXNldEhhbmRsZXI6dm9pZCAwLGJlZ2luTW92ZUhhbmRsZXI6dm9pZCAwLGJlZ2luUmVzaXplSGFuZGxlcjp2b2lkIDAsYnJpbmdUb0Zyb250SGFuZGxlcjp2b2lkIDAsbW9kYWxDbGlja0hhbmRsZXI6dm9pZCAwLGJ1dHRvbnNDbGlja0hhbmRsZXI6dm9pZCAwLGNvbW1hbmRzQ2xpY2tIYW5kbGVyOnZvaWQgMCx0cmFuc2l0aW9uSW5IYW5kbGVyOnZvaWQgMCx0cmFuc2l0aW9uT3V0SGFuZGxlcjp2b2lkIDAsZGVzdHJveTp2b2lkIDB9LGw9e307bC5yb290PWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIiksbC5yb290LnN0eWxlLmRpc3BsYXk9XCJub25lXCIsbC5yb290LmNsYXNzTmFtZT1IYS5iYXNlK1wiIFwiK0hhLmhpZGRlbitcIiBcIixsLnJvb3QuaW5uZXJIVE1MPUdhLmRpbW1lcitHYS5tb2RhbCxsLmRpbW1lcj1sLnJvb3QuZmlyc3RDaGlsZCxsLm1vZGFsPWwucm9vdC5sYXN0Q2hpbGQsbC5tb2RhbC5pbm5lckhUTUw9R2EuZGlhbG9nLGwuZGlhbG9nPWwubW9kYWwuZmlyc3RDaGlsZCxsLmRpYWxvZy5pbm5lckhUTUw9R2EucmVzZXQrR2EuY29tbWFuZHMrR2EuaGVhZGVyK0dhLmJvZHkrR2EuZm9vdGVyK0dhLnJlc2l6ZUhhbmRsZStHYS5yZXNldCxsLnJlc2V0PVtdLGwucmVzZXQucHVzaChsLmRpYWxvZy5maXJzdENoaWxkKSxsLnJlc2V0LnB1c2gobC5kaWFsb2cubGFzdENoaWxkKSxsLmNvbW1hbmRzPXt9LGwuY29tbWFuZHMuY29udGFpbmVyPWwucmVzZXRbMF0ubmV4dFNpYmxpbmcsbC5jb21tYW5kcy5waW49bC5jb21tYW5kcy5jb250YWluZXIuZmlyc3RDaGlsZCxsLmNvbW1hbmRzLm1heGltaXplPWwuY29tbWFuZHMucGluLm5leHRTaWJsaW5nLGwuY29tbWFuZHMuY2xvc2U9bC5jb21tYW5kcy5tYXhpbWl6ZS5uZXh0U2libGluZyxsLmhlYWRlcj1sLmNvbW1hbmRzLmNvbnRhaW5lci5uZXh0U2libGluZyxsLmJvZHk9bC5oZWFkZXIubmV4dFNpYmxpbmcsbC5ib2R5LmlubmVySFRNTD1HYS5jb250ZW50LGwuY29udGVudD1sLmJvZHkuZmlyc3RDaGlsZCxsLmZvb3Rlcj1sLmJvZHkubmV4dFNpYmxpbmcsbC5mb290ZXIuaW5uZXJIVE1MPUdhLmJ1dHRvbnMuYXV4aWxpYXJ5K0dhLmJ1dHRvbnMucHJpbWFyeSxsLnJlc2l6ZUhhbmRsZT1sLmZvb3Rlci5uZXh0U2libGluZyxsLmJ1dHRvbnM9e30sbC5idXR0b25zLmF1eGlsaWFyeT1sLmZvb3Rlci5maXJzdENoaWxkLGwuYnV0dG9ucy5wcmltYXJ5PWwuYnV0dG9ucy5hdXhpbGlhcnkubmV4dFNpYmxpbmcsbC5idXR0b25zLnByaW1hcnkuaW5uZXJIVE1MPUdhLmJ1dHRvbixsLmJ1dHRvblRlbXBsYXRlPWwuYnV0dG9ucy5wcmltYXJ5LmZpcnN0Q2hpbGQsbC5idXR0b25zLnByaW1hcnkucmVtb3ZlQ2hpbGQobC5idXR0b25UZW1wbGF0ZSk7Zm9yKHZhciBtPTA7bTxhLl9faW50ZXJuYWwuYnV0dG9ucy5sZW5ndGg7bSs9MSl7dmFyIG49YS5fX2ludGVybmFsLmJ1dHRvbnNbbV07Q2EuaW5kZXhPZihuLmtleSk8MCYmQ2EucHVzaChuLmtleSksbi5lbGVtZW50PWwuYnV0dG9uVGVtcGxhdGUuY2xvbmVOb2RlKCksbi5lbGVtZW50LmlubmVySFRNTD1uLnRleHQsXCJzdHJpbmdcIj09dHlwZW9mIG4uY2xhc3NOYW1lJiZcIlwiIT09bi5jbGFzc05hbWUmJmIobi5lbGVtZW50LG4uY2xhc3NOYW1lKTtmb3IodmFyIG8gaW4gbi5hdHRycylcImNsYXNzTmFtZVwiIT09byYmbi5hdHRycy5oYXNPd25Qcm9wZXJ0eShvKSYmbi5lbGVtZW50LnNldEF0dHJpYnV0ZShvLG4uYXR0cnNbb10pO1wiYXV4aWxpYXJ5XCI9PT1uLnNjb3BlP2wuYnV0dG9ucy5hdXhpbGlhcnkuYXBwZW5kQ2hpbGQobi5lbGVtZW50KTpsLmJ1dHRvbnMucHJpbWFyeS5hcHBlbmRDaGlsZChuLmVsZW1lbnQpfWEuZWxlbWVudHM9bCxrLnJlc2V0SGFuZGxlcj1qKGEsWiksay5iZWdpbk1vdmVIYW5kbGVyPWooYSxlYSksay5iZWdpblJlc2l6ZUhhbmRsZXI9aihhLGthKSxrLmJyaW5nVG9Gcm9udEhhbmRsZXI9aihhLEQpLGsubW9kYWxDbGlja0hhbmRsZXI9aihhLFQpLGsuYnV0dG9uc0NsaWNrSGFuZGxlcj1qKGEsViksay5jb21tYW5kc0NsaWNrSGFuZGxlcj1qKGEsSCksay50cmFuc2l0aW9uSW5IYW5kbGVyPWooYSxhYSksay50cmFuc2l0aW9uT3V0SGFuZGxlcj1qKGEsYmEpO2Zvcih2YXIgcCBpbiBrLm9wdGlvbnMpdm9pZCAwIT09Yy5vcHRpb25zW3BdP2Euc2V0KHAsYy5vcHRpb25zW3BdKTp5LmRlZmF1bHRzLmhhc093blByb3BlcnR5KHApP2Euc2V0KHAseS5kZWZhdWx0c1twXSk6XCJ0aXRsZVwiPT09cCYmYS5zZXQocCx5LmRlZmF1bHRzLmdsb3NzYXJ5W3BdKTtcImZ1bmN0aW9uXCI9PXR5cGVvZiBhLmJ1aWxkJiZhLmJ1aWxkKCkseS5kZWZhdWx0cy5ob29rcy5wb3N0aW5pdChhKX1kb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGEuZWxlbWVudHMucm9vdCl9ZnVuY3Rpb24gbigpe0FhPWYoKSxCYT1lKCl9ZnVuY3Rpb24gcigpe2Euc2Nyb2xsVG8oQWEsQmEpfWZ1bmN0aW9uIHMoKXtmb3IodmFyIGE9MCxkPTA7ZDxxLmxlbmd0aDtkKz0xKXt2YXIgZT1xW2RdOyhlLmlzTW9kYWwoKXx8ZS5pc01heGltaXplZCgpKSYmKGErPTEpfTA9PT1hJiZkb2N1bWVudC5ib2R5LmNsYXNzTmFtZS5pbmRleE9mKEhhLm5vT3ZlcmZsb3cpPj0wPyhjKGRvY3VtZW50LmJvZHksSGEubm9PdmVyZmxvdyksdyghMSkpOmE+MCYmZG9jdW1lbnQuYm9keS5jbGFzc05hbWUuaW5kZXhPZihIYS5ub092ZXJmbG93KTwwJiYodyghMCksYihkb2N1bWVudC5ib2R5LEhhLm5vT3ZlcmZsb3cpKX1mdW5jdGlvbiB3KGQpe3kuZGVmYXVsdHMucHJldmVudEJvZHlTaGlmdCYmKGQmJmRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxIZWlnaHQ+ZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudEhlaWdodD8oSmE9QmEsSWE9YS5nZXRDb21wdXRlZFN0eWxlKGRvY3VtZW50LmJvZHkpLnRvcCxiKGRvY3VtZW50LmJvZHksSGEuZml4ZWQpLGRvY3VtZW50LmJvZHkuc3R5bGUudG9wPS1CYStcInB4XCIpOmR8fChCYT1KYSxkb2N1bWVudC5ib2R5LnN0eWxlLnRvcD1JYSxjKGRvY3VtZW50LmJvZHksSGEuZml4ZWQpLHIoKSkpfWZ1bmN0aW9uIHgoYSxkLGUpe1wic3RyaW5nXCI9PXR5cGVvZiBlJiZjKGEuZWxlbWVudHMucm9vdCxIYS5wcmVmaXgrZSksYihhLmVsZW1lbnRzLnJvb3QsSGEucHJlZml4K2QpLERhPWEuZWxlbWVudHMucm9vdC5vZmZzZXRXaWR0aH1mdW5jdGlvbiB6KGEpe2EuZ2V0KFwidHJhbnNpdGlvbk9mZlwiKT9iKGEuZWxlbWVudHMucm9vdCxIYS5ub1RyYW5zaXRpb24pOmMoYS5lbGVtZW50cy5yb290LEhhLm5vVHJhbnNpdGlvbil9ZnVuY3Rpb24gQShhKXthLmdldChcIm1vZGFsXCIpPyhjKGEuZWxlbWVudHMucm9vdCxIYS5tb2RlbGVzcyksYS5pc09wZW4oKSYmKHRhKGEpLFAoYSkscygpKSk6KGIoYS5lbGVtZW50cy5yb290LEhhLm1vZGVsZXNzKSxhLmlzT3BlbigpJiYoc2EoYSksUChhKSxzKCkpKX1mdW5jdGlvbiBCKGEpe2EuZ2V0KFwiYmFzaWNcIik/YihhLmVsZW1lbnRzLnJvb3QsSGEuYmFzaWMpOmMoYS5lbGVtZW50cy5yb290LEhhLmJhc2ljKX1mdW5jdGlvbiBDKGEpe2EuZ2V0KFwiZnJhbWVsZXNzXCIpP2IoYS5lbGVtZW50cy5yb290LEhhLmZyYW1lbGVzcyk6YyhhLmVsZW1lbnRzLnJvb3QsSGEuZnJhbWVsZXNzKX1mdW5jdGlvbiBEKGEsYil7Zm9yKHZhciBjPXEuaW5kZXhPZihiKSxkPWMrMTtkPHEubGVuZ3RoO2QrPTEpaWYocVtkXS5pc01vZGFsKCkpcmV0dXJuO3JldHVybiBkb2N1bWVudC5ib2R5Lmxhc3RDaGlsZCE9PWIuZWxlbWVudHMucm9vdCYmKGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoYi5lbGVtZW50cy5yb290KSxxLnNwbGljZShxLmluZGV4T2YoYiksMSkscS5wdXNoKGIpLFkoYikpLCExfWZ1bmN0aW9uIEUoYSxkLGUsZil7c3dpdGNoKGQpe2Nhc2VcInRpdGxlXCI6YS5zZXRIZWFkZXIoZik7YnJlYWs7Y2FzZVwibW9kYWxcIjpBKGEpO2JyZWFrO2Nhc2VcImJhc2ljXCI6QihhKTticmVhaztjYXNlXCJmcmFtZWxlc3NcIjpDKGEpO2JyZWFrO2Nhc2VcInBpbm5lZFwiOlEoYSk7YnJlYWs7Y2FzZVwiY2xvc2FibGVcIjpTKGEpO2JyZWFrO2Nhc2VcIm1heGltaXphYmxlXCI6UihhKTticmVhaztjYXNlXCJwaW5uYWJsZVwiOk0oYSk7YnJlYWs7Y2FzZVwibW92YWJsZVwiOmlhKGEpO2JyZWFrO2Nhc2VcInJlc2l6YWJsZVwiOm9hKGEpO2JyZWFrO2Nhc2VcInBhZGRpbmdcIjpmP2MoYS5lbGVtZW50cy5yb290LEhhLm5vUGFkZGluZyk6YS5lbGVtZW50cy5yb290LmNsYXNzTmFtZS5pbmRleE9mKEhhLm5vUGFkZGluZyk8MCYmYihhLmVsZW1lbnRzLnJvb3QsSGEubm9QYWRkaW5nKTticmVhaztjYXNlXCJvdmVyZmxvd1wiOmY/YyhhLmVsZW1lbnRzLnJvb3QsSGEubm9PdmVyZmxvdyk6YS5lbGVtZW50cy5yb290LmNsYXNzTmFtZS5pbmRleE9mKEhhLm5vT3ZlcmZsb3cpPDAmJmIoYS5lbGVtZW50cy5yb290LEhhLm5vT3ZlcmZsb3cpO2JyZWFrO2Nhc2VcInRyYW5zaXRpb25cIjp4KGEsZixlKTticmVhaztjYXNlXCJ0cmFuc2l0aW9uT2ZmXCI6eihhKX1cImZ1bmN0aW9uXCI9PXR5cGVvZiBhLmhvb2tzLm9udXBkYXRlJiZhLmhvb2tzLm9udXBkYXRlLmNhbGwoYSxkLGUsZil9ZnVuY3Rpb24gRihhLGIsYyxkLGUpe3ZhciBmPXtvcDp2b2lkIDAsaXRlbXM6W119O2lmKHZvaWQgMD09PWUmJlwic3RyaW5nXCI9PXR5cGVvZiBkKWYub3A9XCJnZXRcIixiLmhhc093blByb3BlcnR5KGQpPyhmLmZvdW5kPSEwLGYudmFsdWU9YltkXSk6KGYuZm91bmQ9ITEsZi52YWx1ZT12b2lkIDApO2Vsc2V7dmFyIGc7aWYoZi5vcD1cInNldFwiLFwib2JqZWN0XCI9PXR5cGVvZiBkKXt2YXIgaD1kO2Zvcih2YXIgaSBpbiBoKWIuaGFzT3duUHJvcGVydHkoaSk/KGJbaV0hPT1oW2ldJiYoZz1iW2ldLGJbaV09aFtpXSxjLmNhbGwoYSxpLGcsaFtpXSkpLGYuaXRlbXMucHVzaCh7a2V5OmksdmFsdWU6aFtpXSxmb3VuZDohMH0pKTpmLml0ZW1zLnB1c2goe2tleTppLHZhbHVlOmhbaV0sZm91bmQ6ITF9KX1lbHNle2lmKFwic3RyaW5nXCIhPXR5cGVvZiBkKXRocm93IG5ldyBFcnJvcihcImFyZ3MgbXVzdCBiZSBhIHN0cmluZyBvciBvYmplY3RcIik7Yi5oYXNPd25Qcm9wZXJ0eShkKT8oYltkXSE9PWUmJihnPWJbZF0sYltkXT1lLGMuY2FsbChhLGQsZyxlKSksZi5pdGVtcy5wdXNoKHtrZXk6ZCx2YWx1ZTplLGZvdW5kOiEwfSkpOmYuaXRlbXMucHVzaCh7a2V5OmQsdmFsdWU6ZSxmb3VuZDohMX0pfX1yZXR1cm4gZn1mdW5jdGlvbiBHKGEpe3ZhciBiO1UoYSxmdW5jdGlvbihjKXtyZXR1cm4gYj0hMCE9PWEuZ2V0KFwiaW52b2tlT25DbG9zZU9mZlwiKSYmITA9PT1jLmludm9rZU9uQ2xvc2V9KSwhYiYmYS5pc09wZW4oKSYmYS5jbG9zZSgpfWZ1bmN0aW9uIEgoYSxiKXtzd2l0Y2goYS5zcmNFbGVtZW50fHxhLnRhcmdldCl7Y2FzZSBiLmVsZW1lbnRzLmNvbW1hbmRzLnBpbjpiLmlzUGlubmVkKCk/SihiKTpJKGIpO2JyZWFrO2Nhc2UgYi5lbGVtZW50cy5jb21tYW5kcy5tYXhpbWl6ZTpiLmlzTWF4aW1pemVkKCk/TChiKTpLKGIpO2JyZWFrO2Nhc2UgYi5lbGVtZW50cy5jb21tYW5kcy5jbG9zZTpHKGIpfXJldHVybiExfWZ1bmN0aW9uIEkoYSl7YS5zZXQoXCJwaW5uZWRcIiwhMCl9ZnVuY3Rpb24gSihhKXthLnNldChcInBpbm5lZFwiLCExKX1mdW5jdGlvbiBLKGEpe2woXCJvbm1heGltaXplXCIsYSksYihhLmVsZW1lbnRzLnJvb3QsSGEubWF4aW1pemVkKSxhLmlzT3BlbigpJiZzKCksbChcIm9ubWF4aW1pemVkXCIsYSl9ZnVuY3Rpb24gTChhKXtsKFwib25yZXN0b3JlXCIsYSksYyhhLmVsZW1lbnRzLnJvb3QsSGEubWF4aW1pemVkKSxhLmlzT3BlbigpJiZzKCksbChcIm9ucmVzdG9yZWRcIixhKX1mdW5jdGlvbiBNKGEpe2EuZ2V0KFwicGlubmFibGVcIik/YihhLmVsZW1lbnRzLnJvb3QsSGEucGlubmFibGUpOmMoYS5lbGVtZW50cy5yb290LEhhLnBpbm5hYmxlKX1mdW5jdGlvbiBOKGEpe3ZhciBiPWYoKTthLmVsZW1lbnRzLm1vZGFsLnN0eWxlLm1hcmdpblRvcD1lKCkrXCJweFwiLGEuZWxlbWVudHMubW9kYWwuc3R5bGUubWFyZ2luTGVmdD1iK1wicHhcIixhLmVsZW1lbnRzLm1vZGFsLnN0eWxlLm1hcmdpblJpZ2h0PS1iK1wicHhcIn1mdW5jdGlvbiBPKGEpe3ZhciBiPXBhcnNlSW50KGEuZWxlbWVudHMubW9kYWwuc3R5bGUubWFyZ2luVG9wLDEwKSxjPXBhcnNlSW50KGEuZWxlbWVudHMubW9kYWwuc3R5bGUubWFyZ2luTGVmdCwxMCk7aWYoYS5lbGVtZW50cy5tb2RhbC5zdHlsZS5tYXJnaW5Ub3A9XCJcIixhLmVsZW1lbnRzLm1vZGFsLnN0eWxlLm1hcmdpbkxlZnQ9XCJcIixhLmVsZW1lbnRzLm1vZGFsLnN0eWxlLm1hcmdpblJpZ2h0PVwiXCIsYS5pc09wZW4oKSl7dmFyIGQ9MCxnPTA7XCJcIiE9PWEuZWxlbWVudHMuZGlhbG9nLnN0eWxlLnRvcCYmKGQ9cGFyc2VJbnQoYS5lbGVtZW50cy5kaWFsb2cuc3R5bGUudG9wLDEwKSksYS5lbGVtZW50cy5kaWFsb2cuc3R5bGUudG9wPWQrKGItZSgpKStcInB4XCIsXCJcIiE9PWEuZWxlbWVudHMuZGlhbG9nLnN0eWxlLmxlZnQmJihnPXBhcnNlSW50KGEuZWxlbWVudHMuZGlhbG9nLnN0eWxlLmxlZnQsMTApKSxhLmVsZW1lbnRzLmRpYWxvZy5zdHlsZS5sZWZ0PWcrKGMtZigpKStcInB4XCJ9fWZ1bmN0aW9uIFAoYSl7YS5nZXQoXCJtb2RhbFwiKXx8YS5nZXQoXCJwaW5uZWRcIik/TyhhKTpOKGEpfWZ1bmN0aW9uIFEoYSl7YS5nZXQoXCJwaW5uZWRcIik/KGMoYS5lbGVtZW50cy5yb290LEhhLnVucGlubmVkKSxhLmlzT3BlbigpJiZPKGEpKTooYihhLmVsZW1lbnRzLnJvb3QsSGEudW5waW5uZWQpLGEuaXNPcGVuKCkmJiFhLmlzTW9kYWwoKSYmTihhKSl9ZnVuY3Rpb24gUihhKXthLmdldChcIm1heGltaXphYmxlXCIpP2IoYS5lbGVtZW50cy5yb290LEhhLm1heGltaXphYmxlKTpjKGEuZWxlbWVudHMucm9vdCxIYS5tYXhpbWl6YWJsZSl9ZnVuY3Rpb24gUyhhKXthLmdldChcImNsb3NhYmxlXCIpPyhiKGEuZWxlbWVudHMucm9vdCxIYS5jbG9zYWJsZSkseWEoYSkpOihjKGEuZWxlbWVudHMucm9vdCxIYS5jbG9zYWJsZSksemEoYSkpfWZ1bmN0aW9uIFQoYSxiKXtpZihhLnRpbWVTdGFtcC1MYT4yMDAmJihMYT1hLnRpbWVTdGFtcCkmJiFLYSl7dmFyIGM9YS5zcmNFbGVtZW50fHxhLnRhcmdldDshMD09PWIuZ2V0KFwiY2xvc2FibGVCeURpbW1lclwiKSYmYz09PWIuZWxlbWVudHMubW9kYWwmJkcoYil9S2E9ITF9ZnVuY3Rpb24gVShhLGIpe2lmKERhdGUubm93KCktTWE+MjAwJiYoTWE9RGF0ZS5ub3coKSkpZm9yKHZhciBjPTA7YzxhLl9faW50ZXJuYWwuYnV0dG9ucy5sZW5ndGg7Yys9MSl7dmFyIGQ9YS5fX2ludGVybmFsLmJ1dHRvbnNbY107aWYoIWQuZWxlbWVudC5kaXNhYmxlZCYmYihkKSl7dmFyIGU9ayhjLGQpO1wiZnVuY3Rpb25cIj09dHlwZW9mIGEuY2FsbGJhY2smJmEuY2FsbGJhY2suYXBwbHkoYSxbZV0pLCExPT09ZS5jYW5jZWwmJmEuY2xvc2UoKTticmVha319fWZ1bmN0aW9uIFYoYSxiKXt2YXIgYz1hLnNyY0VsZW1lbnR8fGEudGFyZ2V0O1UoYixmdW5jdGlvbihhKXtyZXR1cm4gYS5lbGVtZW50PT09YyYmKE5hPSEwKX0pfWZ1bmN0aW9uIFcoYSl7aWYoTmEpcmV0dXJuIHZvaWQoTmE9ITEpO3ZhciBiPXFbcS5sZW5ndGgtMV0sYz1hLmtleUNvZGU7cmV0dXJuIDA9PT1iLl9faW50ZXJuYWwuYnV0dG9ucy5sZW5ndGgmJmM9PT1vLkVTQyYmITA9PT1iLmdldChcImNsb3NhYmxlXCIpPyhHKGIpLCExKTpDYS5pbmRleE9mKGMpPi0xPyhVKGIsZnVuY3Rpb24oYSl7cmV0dXJuIGEua2V5PT09Y30pLCExKTp2b2lkIDB9ZnVuY3Rpb24gWChhKXt2YXIgYj1xW3EubGVuZ3RoLTFdLGM9YS5rZXlDb2RlO2lmKGM9PT1vLkxFRlR8fGM9PT1vLlJJR0hUKXtmb3IodmFyIGQ9Yi5fX2ludGVybmFsLmJ1dHRvbnMsZT0wO2U8ZC5sZW5ndGg7ZSs9MSlpZihkb2N1bWVudC5hY3RpdmVFbGVtZW50PT09ZFtlXS5lbGVtZW50KXN3aXRjaChjKXtjYXNlIG8uTEVGVDpyZXR1cm4gdm9pZCBkWyhlfHxkLmxlbmd0aCktMV0uZWxlbWVudC5mb2N1cygpO2Nhc2Ugby5SSUdIVDpyZXR1cm4gdm9pZCBkWyhlKzEpJWQubGVuZ3RoXS5lbGVtZW50LmZvY3VzKCl9fWVsc2UgaWYoYzxvLkYxMisxJiZjPm8uRjEtMSYmQ2EuaW5kZXhPZihjKT4tMSlyZXR1cm4gYS5wcmV2ZW50RGVmYXVsdCgpLGEuc3RvcFByb3BhZ2F0aW9uKCksVShiLGZ1bmN0aW9uKGEpe3JldHVybiBhLmtleT09PWN9KSwhMX1mdW5jdGlvbiBZKGEsYil7aWYoYiliLmZvY3VzKCk7ZWxzZXt2YXIgYz1hLl9faW50ZXJuYWwuZm9jdXMsZD1jLmVsZW1lbnQ7c3dpdGNoKHR5cGVvZiBjLmVsZW1lbnQpe2Nhc2VcIm51bWJlclwiOmEuX19pbnRlcm5hbC5idXR0b25zLmxlbmd0aD5jLmVsZW1lbnQmJihkPSEwPT09YS5nZXQoXCJiYXNpY1wiKT9hLmVsZW1lbnRzLnJlc2V0WzBdOmEuX19pbnRlcm5hbC5idXR0b25zW2MuZWxlbWVudF0uZWxlbWVudCk7YnJlYWs7Y2FzZVwic3RyaW5nXCI6ZD1hLmVsZW1lbnRzLmJvZHkucXVlcnlTZWxlY3RvcihjLmVsZW1lbnQpO2JyZWFrO2Nhc2VcImZ1bmN0aW9uXCI6ZD1jLmVsZW1lbnQuY2FsbChhKX0hMCE9PWEuZ2V0KFwiZGVmYXVsdEZvY3VzT2ZmXCIpJiYodm9pZCAwIT09ZCYmbnVsbCE9PWR8fDAhPT1hLl9faW50ZXJuYWwuYnV0dG9ucy5sZW5ndGgpfHwoZD1hLmVsZW1lbnRzLnJlc2V0WzBdKSxkJiZkLmZvY3VzJiYoZC5mb2N1cygpLGMuc2VsZWN0JiZkLnNlbGVjdCYmZC5zZWxlY3QoKSl9fWZ1bmN0aW9uIFooYSxiKXtpZighYilmb3IodmFyIGM9cS5sZW5ndGgtMTtjPi0xO2MtPTEpaWYocVtjXS5pc01vZGFsKCkpe2I9cVtjXTticmVha31pZihiJiZiLmlzTW9kYWwoKSl7dmFyIGQsZT1iLmVsZW1lbnRzLnJlc2V0WzBdLGY9Yi5lbGVtZW50cy5yZXNldFsxXSxnPWEucmVsYXRlZFRhcmdldCxoPWIuZWxlbWVudHMucm9vdC5jb250YWlucyhnKSxpPWEuc3JjRWxlbWVudHx8YS50YXJnZXQ7aWYoaT09PWUmJiFofHxpPT09ZiYmZz09PWUpcmV0dXJuO2k9PT1mfHxpPT09ZG9jdW1lbnQuYm9keT9kPWU6aT09PWUmJmc9PT1mP2Q9JChiKTppPT09ZSYmaCYmKGQ9JChiLCEwKSksWShiLGQpfX1mdW5jdGlvbiAkKGEsYil7dmFyIGM9W10uc2xpY2UuY2FsbChhLmVsZW1lbnRzLmRpYWxvZy5xdWVyeVNlbGVjdG9yQWxsKHAudGFiYmFibGUpKTtiJiZjLnJldmVyc2UoKTtmb3IodmFyIGQ9MDtkPGMubGVuZ3RoO2QrPTEpe3ZhciBlPWNbZF07aWYoZS5vZmZzZXRQYXJlbnR8fGUub2Zmc2V0V2lkdGh8fGUub2Zmc2V0SGVpZ2h0fHxlLmdldENsaWVudFJlY3RzKCkubGVuZ3RoKXJldHVybiBlfX1mdW5jdGlvbiBfKGEpe3ZhciBiPXFbcS5sZW5ndGgtMV07YiYmYS5zaGlmdEtleSYmYS5rZXlDb2RlPT09by5UQUImJmIuZWxlbWVudHMucmVzZXRbMV0uZm9jdXMoKX1mdW5jdGlvbiBhYShhLGIpe2NsZWFyVGltZW91dChiLl9faW50ZXJuYWwudGltZXJJbiksWShiKSxOYT0hMSxsKFwib25mb2N1c1wiLGIpLHUoYi5lbGVtZW50cy5kaWFsb2csdi50eXBlLGIuX19pbnRlcm5hbC50cmFuc2l0aW9uSW5IYW5kbGVyKSxjKGIuZWxlbWVudHMucm9vdCxIYS5hbmltYXRpb25Jbil9ZnVuY3Rpb24gYmEoYSxiKXtjbGVhclRpbWVvdXQoYi5fX2ludGVybmFsLnRpbWVyT3V0KSx1KGIuZWxlbWVudHMuZGlhbG9nLHYudHlwZSxiLl9faW50ZXJuYWwudHJhbnNpdGlvbk91dEhhbmRsZXIpLGhhKGIpLG5hKGIpLGIuaXNNYXhpbWl6ZWQoKSYmIWIuZ2V0KFwic3RhcnRNYXhpbWl6ZWRcIikmJkwoYiksXCJmdW5jdGlvblwiPT10eXBlb2YgYi5fX2ludGVybmFsLmRlc3Ryb3kmJmIuX19pbnRlcm5hbC5kZXN0cm95LmFwcGx5KGIpfWZ1bmN0aW9uIGNhKGEsYil7dmFyIGM9YVtSYV0tUGEsZD1hW1NhXS1RYTtVYSYmKGQtPWRvY3VtZW50LmJvZHkuc2Nyb2xsVG9wKSxiLnN0eWxlLmxlZnQ9YytcInB4XCIsYi5zdHlsZS50b3A9ZCtcInB4XCJ9ZnVuY3Rpb24gZGEoYSxiKXt2YXIgYz1hW1JhXS1QYSxkPWFbU2FdLVFhO1VhJiYoZC09ZG9jdW1lbnQuYm9keS5zY3JvbGxUb3ApLGIuc3R5bGUubGVmdD1NYXRoLm1pbihUYS5tYXhMZWZ0LE1hdGgubWF4KFRhLm1pbkxlZnQsYykpK1wicHhcIixiLnN0eWxlLnRvcD1VYT9NYXRoLm1pbihUYS5tYXhUb3AsTWF0aC5tYXgoVGEubWluVG9wLGQpKStcInB4XCI6TWF0aC5tYXgoVGEubWluVG9wLGQpK1wicHhcIn1mdW5jdGlvbiBlYShhLGMpe2lmKG51bGw9PT1XYSYmIWMuaXNNYXhpbWl6ZWQoKSYmYy5nZXQoXCJtb3ZhYmxlXCIpKXt2YXIgZCxlPTAsZj0wO2lmKFwidG91Y2hzdGFydFwiPT09YS50eXBlPyhhLnByZXZlbnREZWZhdWx0KCksZD1hLnRhcmdldFRvdWNoZXNbMF0sUmE9XCJjbGllbnRYXCIsU2E9XCJjbGllbnRZXCIpOjA9PT1hLmJ1dHRvbiYmKGQ9YSksZCl7dmFyIGc9Yy5lbGVtZW50cy5kaWFsb2c7aWYoYihnLEhhLmNhcHR1cmUpLGcuc3R5bGUubGVmdCYmKGU9cGFyc2VJbnQoZy5zdHlsZS5sZWZ0LDEwKSksZy5zdHlsZS50b3AmJihmPXBhcnNlSW50KGcuc3R5bGUudG9wLDEwKSksUGE9ZFtSYV0tZSxRYT1kW1NhXS1mLGMuaXNNb2RhbCgpP1FhKz1jLmVsZW1lbnRzLm1vZGFsLnNjcm9sbFRvcDpjLmlzUGlubmVkKCkmJihRYS09ZG9jdW1lbnQuYm9keS5zY3JvbGxUb3ApLGMuZ2V0KFwibW92ZUJvdW5kZWRcIikpe3ZhciBoPWcsaT0tZSxqPS1mO2Rve2krPWgub2Zmc2V0TGVmdCxqKz1oLm9mZnNldFRvcH13aGlsZShoPWgub2Zmc2V0UGFyZW50KTtUYT17bWF4TGVmdDppLG1pbkxlZnQ6LWksbWF4VG9wOmRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRIZWlnaHQtZy5jbGllbnRIZWlnaHQtaixtaW5Ub3A6LWp9LFZhPWRhfWVsc2UgVGE9bnVsbCxWYT1jYTtyZXR1cm4gbChcIm9ubW92ZVwiLGMpLFVhPSFjLmlzTW9kYWwoKSYmYy5pc1Bpbm5lZCgpLE9hPWMsVmEoZCxnKSxiKGRvY3VtZW50LmJvZHksSGEubm9TZWxlY3Rpb24pLCExfX19ZnVuY3Rpb24gZmEoYSl7aWYoT2Epe3ZhciBiO1widG91Y2htb3ZlXCI9PT1hLnR5cGU/KGEucHJldmVudERlZmF1bHQoKSxiPWEudGFyZ2V0VG91Y2hlc1swXSk6MD09PWEuYnV0dG9uJiYoYj1hKSxiJiZWYShiLE9hLmVsZW1lbnRzLmRpYWxvZyl9fWZ1bmN0aW9uIGdhKCl7aWYoT2Epe3ZhciBhPU9hO09hPVRhPW51bGwsYyhkb2N1bWVudC5ib2R5LEhhLm5vU2VsZWN0aW9uKSxjKGEuZWxlbWVudHMuZGlhbG9nLEhhLmNhcHR1cmUpLGwoXCJvbm1vdmVkXCIsYSl9fWZ1bmN0aW9uIGhhKGEpe09hPW51bGw7dmFyIGI9YS5lbGVtZW50cy5kaWFsb2c7Yi5zdHlsZS5sZWZ0PWIuc3R5bGUudG9wPVwiXCJ9ZnVuY3Rpb24gaWEoYSl7YS5nZXQoXCJtb3ZhYmxlXCIpPyhiKGEuZWxlbWVudHMucm9vdCxIYS5tb3ZhYmxlKSxhLmlzT3BlbigpJiZ1YShhKSk6KGhhKGEpLGMoYS5lbGVtZW50cy5yb290LEhhLm1vdmFibGUpLGEuaXNPcGVuKCkmJnZhKGEpKX1mdW5jdGlvbiBqYShhLGIsYyl7dmFyIGU9YixmPTAsZz0wO2Rve2YrPWUub2Zmc2V0TGVmdCxnKz1lLm9mZnNldFRvcH13aGlsZShlPWUub2Zmc2V0UGFyZW50KTt2YXIgaCxpOyEwPT09Yz8oaD1hLnBhZ2VYLGk9YS5wYWdlWSk6KGg9YS5jbGllbnRYLGk9YS5jbGllbnRZKTt2YXIgaj1kKCk7aWYoaiYmKGg9ZG9jdW1lbnQuYm9keS5vZmZzZXRXaWR0aC1oLGlzTmFOKFhhKXx8KGY9ZG9jdW1lbnQuYm9keS5vZmZzZXRXaWR0aC1mLWIub2Zmc2V0V2lkdGgpKSxiLnN0eWxlLmhlaWdodD1pLWcrJGErXCJweFwiLGIuc3R5bGUud2lkdGg9aC1mKyRhK1wicHhcIiwhaXNOYU4oWGEpKXt2YXIgaz0uNSpNYXRoLmFicyhiLm9mZnNldFdpZHRoLVlhKTtqJiYoayo9LTEpLGIub2Zmc2V0V2lkdGg+WWE/Yi5zdHlsZS5sZWZ0PVhhK2srXCJweFwiOmIub2Zmc2V0V2lkdGg+PVphJiYoYi5zdHlsZS5sZWZ0PVhhLWsrXCJweFwiKX19ZnVuY3Rpb24ga2EoYSxjKXtpZighYy5pc01heGltaXplZCgpKXt2YXIgZDtpZihcInRvdWNoc3RhcnRcIj09PWEudHlwZT8oYS5wcmV2ZW50RGVmYXVsdCgpLGQ9YS50YXJnZXRUb3VjaGVzWzBdKTowPT09YS5idXR0b24mJihkPWEpLGQpe2woXCJvbnJlc2l6ZVwiLGMpLFdhPWMsJGE9Yy5lbGVtZW50cy5yZXNpemVIYW5kbGUub2Zmc2V0SGVpZ2h0LzI7dmFyIGU9Yy5lbGVtZW50cy5kaWFsb2c7cmV0dXJuIGIoZSxIYS5jYXB0dXJlKSxYYT1wYXJzZUludChlLnN0eWxlLmxlZnQsMTApLGUuc3R5bGUuaGVpZ2h0PWUub2Zmc2V0SGVpZ2h0K1wicHhcIixlLnN0eWxlLm1pbkhlaWdodD1jLmVsZW1lbnRzLmhlYWRlci5vZmZzZXRIZWlnaHQrYy5lbGVtZW50cy5mb290ZXIub2Zmc2V0SGVpZ2h0K1wicHhcIixlLnN0eWxlLndpZHRoPShZYT1lLm9mZnNldFdpZHRoKStcInB4XCIsXCJub25lXCIhPT1lLnN0eWxlLm1heFdpZHRoJiYoZS5zdHlsZS5taW5XaWR0aD0oWmE9ZS5vZmZzZXRXaWR0aCkrXCJweFwiKSxlLnN0eWxlLm1heFdpZHRoPVwibm9uZVwiLGIoZG9jdW1lbnQuYm9keSxIYS5ub1NlbGVjdGlvbiksITF9fX1mdW5jdGlvbiBsYShhKXtpZihXYSl7dmFyIGI7XCJ0b3VjaG1vdmVcIj09PWEudHlwZT8oYS5wcmV2ZW50RGVmYXVsdCgpLGI9YS50YXJnZXRUb3VjaGVzWzBdKTowPT09YS5idXR0b24mJihiPWEpLGImJmphKGIsV2EuZWxlbWVudHMuZGlhbG9nLCFXYS5nZXQoXCJtb2RhbFwiKSYmIVdhLmdldChcInBpbm5lZFwiKSl9fWZ1bmN0aW9uIG1hKCl7aWYoV2Epe3ZhciBhPVdhO1dhPW51bGwsYyhkb2N1bWVudC5ib2R5LEhhLm5vU2VsZWN0aW9uKSxjKGEuZWxlbWVudHMuZGlhbG9nLEhhLmNhcHR1cmUpLEthPSEwLGwoXCJvbnJlc2l6ZWRcIixhKX19ZnVuY3Rpb24gbmEoYSl7V2E9bnVsbDt2YXIgYj1hLmVsZW1lbnRzLmRpYWxvZztcIm5vbmVcIj09PWIuc3R5bGUubWF4V2lkdGgmJihiLnN0eWxlLm1heFdpZHRoPWIuc3R5bGUubWluV2lkdGg9Yi5zdHlsZS53aWR0aD1iLnN0eWxlLmhlaWdodD1iLnN0eWxlLm1pbkhlaWdodD1iLnN0eWxlLmxlZnQ9XCJcIixYYT1OdW1iZXIuTmFuLFlhPVphPSRhPTApfWZ1bmN0aW9uIG9hKGEpe2EuZ2V0KFwicmVzaXphYmxlXCIpPyhiKGEuZWxlbWVudHMucm9vdCxIYS5yZXNpemFibGUpLGEuaXNPcGVuKCkmJndhKGEpKToobmEoYSksYyhhLmVsZW1lbnRzLnJvb3QsSGEucmVzaXphYmxlKSxhLmlzT3BlbigpJiZ4YShhKSl9ZnVuY3Rpb24gcGEoKXtmb3IodmFyIGE9MDthPHEubGVuZ3RoO2ErPTEpe3ZhciBiPXFbYV07Yi5nZXQoXCJhdXRvUmVzZXRcIikmJihoYShiKSxuYShiKSl9fWZ1bmN0aW9uIHFhKGIpezE9PT1xLmxlbmd0aCYmKHQoYSxcInJlc2l6ZVwiLHBhKSx0KGRvY3VtZW50LmJvZHksXCJrZXl1cFwiLFcpLHQoZG9jdW1lbnQuYm9keSxcImtleWRvd25cIixYKSx0KGRvY3VtZW50LmJvZHksXCJmb2N1c1wiLFopLHQoZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LFwibW91c2Vtb3ZlXCIsZmEpLHQoZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LFwidG91Y2htb3ZlXCIsZmEsITEsITEpLHQoZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LFwibW91c2V1cFwiLGdhKSx0KGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCxcInRvdWNoZW5kXCIsZ2EpLHQoZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LFwibW91c2Vtb3ZlXCIsbGEpLHQoZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LFwidG91Y2htb3ZlXCIsbGEsITEsITEpLHQoZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LFwibW91c2V1cFwiLG1hKSx0KGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCxcInRvdWNoZW5kXCIsbWEpKSx0KGIuZWxlbWVudHMuY29tbWFuZHMuY29udGFpbmVyLFwiY2xpY2tcIixiLl9faW50ZXJuYWwuY29tbWFuZHNDbGlja0hhbmRsZXIpLHQoYi5lbGVtZW50cy5mb290ZXIsXCJjbGlja1wiLGIuX19pbnRlcm5hbC5idXR0b25zQ2xpY2tIYW5kbGVyKSx0KGIuZWxlbWVudHMucmVzZXRbMF0sXCJmb2N1c2luXCIsYi5fX2ludGVybmFsLnJlc2V0SGFuZGxlciksdChiLmVsZW1lbnRzLnJlc2V0WzBdLFwia2V5ZG93blwiLF8pLHQoYi5lbGVtZW50cy5yZXNldFsxXSxcImZvY3VzaW5cIixiLl9faW50ZXJuYWwucmVzZXRIYW5kbGVyKSxOYT0hMCx0KGIuZWxlbWVudHMuZGlhbG9nLHYudHlwZSxiLl9faW50ZXJuYWwudHJhbnNpdGlvbkluSGFuZGxlciksYi5nZXQoXCJtb2RhbFwiKXx8c2EoYiksYi5nZXQoXCJyZXNpemFibGVcIikmJndhKGIpLGIuZ2V0KFwibW92YWJsZVwiKSYmdWEoYil9ZnVuY3Rpb24gcmEoYil7MT09PXEubGVuZ3RoJiYodShhLFwicmVzaXplXCIscGEpLHUoZG9jdW1lbnQuYm9keSxcImtleXVwXCIsVyksdShkb2N1bWVudC5ib2R5LFwia2V5ZG93blwiLFgpLHUoZG9jdW1lbnQuYm9keSxcImZvY3VzXCIsWiksdShkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQsXCJtb3VzZW1vdmVcIixmYSksdShkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQsXCJtb3VzZXVwXCIsZ2EpLHUoZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LFwibW91c2Vtb3ZlXCIsbGEpLHUoZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LFwibW91c2V1cFwiLG1hKSksdShiLmVsZW1lbnRzLmNvbW1hbmRzLmNvbnRhaW5lcixcImNsaWNrXCIsYi5fX2ludGVybmFsLmNvbW1hbmRzQ2xpY2tIYW5kbGVyKSx1KGIuZWxlbWVudHMuZm9vdGVyLFwiY2xpY2tcIixiLl9faW50ZXJuYWwuYnV0dG9uc0NsaWNrSGFuZGxlciksdShiLmVsZW1lbnRzLnJlc2V0WzBdLFwiZm9jdXNpblwiLGIuX19pbnRlcm5hbC5yZXNldEhhbmRsZXIpLHUoYi5lbGVtZW50cy5yZXNldFswXSxcImtleWRvd25cIixfKSx1KGIuZWxlbWVudHMucmVzZXRbMV0sXCJmb2N1c2luXCIsYi5fX2ludGVybmFsLnJlc2V0SGFuZGxlciksdChiLmVsZW1lbnRzLmRpYWxvZyx2LnR5cGUsYi5fX2ludGVybmFsLnRyYW5zaXRpb25PdXRIYW5kbGVyKSxiLmdldChcIm1vZGFsXCIpfHx0YShiKSxiLmdldChcIm1vdmFibGVcIikmJnZhKGIpLGIuZ2V0KFwicmVzaXphYmxlXCIpJiZ4YShiKX1mdW5jdGlvbiBzYShhKXt0KGEuZWxlbWVudHMuZGlhbG9nLFwiZm9jdXNcIixhLl9faW50ZXJuYWwuYnJpbmdUb0Zyb250SGFuZGxlciwhMCl9ZnVuY3Rpb24gdGEoYSl7dShhLmVsZW1lbnRzLmRpYWxvZyxcImZvY3VzXCIsYS5fX2ludGVybmFsLmJyaW5nVG9Gcm9udEhhbmRsZXIsITApfWZ1bmN0aW9uIHVhKGEpe3QoYS5lbGVtZW50cy5oZWFkZXIsXCJtb3VzZWRvd25cIixhLl9faW50ZXJuYWwuYmVnaW5Nb3ZlSGFuZGxlciksdChhLmVsZW1lbnRzLmhlYWRlcixcInRvdWNoc3RhcnRcIixhLl9faW50ZXJuYWwuYmVnaW5Nb3ZlSGFuZGxlciwhMSwhMSl9ZnVuY3Rpb24gdmEoYSl7dShhLmVsZW1lbnRzLmhlYWRlcixcIm1vdXNlZG93blwiLGEuX19pbnRlcm5hbC5iZWdpbk1vdmVIYW5kbGVyKSx1KGEuZWxlbWVudHMuaGVhZGVyLFwidG91Y2hzdGFydFwiLGEuX19pbnRlcm5hbC5iZWdpbk1vdmVIYW5kbGVyLCExLCExKX1mdW5jdGlvbiB3YShhKXt0KGEuZWxlbWVudHMucmVzaXplSGFuZGxlLFwibW91c2Vkb3duXCIsYS5fX2ludGVybmFsLmJlZ2luUmVzaXplSGFuZGxlciksdChhLmVsZW1lbnRzLnJlc2l6ZUhhbmRsZSxcInRvdWNoc3RhcnRcIixhLl9faW50ZXJuYWwuYmVnaW5SZXNpemVIYW5kbGVyLCExLCExKX1mdW5jdGlvbiB4YShhKXt1KGEuZWxlbWVudHMucmVzaXplSGFuZGxlLFwibW91c2Vkb3duXCIsYS5fX2ludGVybmFsLmJlZ2luUmVzaXplSGFuZGxlciksdShhLmVsZW1lbnRzLnJlc2l6ZUhhbmRsZSxcInRvdWNoc3RhcnRcIixhLl9faW50ZXJuYWwuYmVnaW5SZXNpemVIYW5kbGVyLCExLCExKX1mdW5jdGlvbiB5YShhKXt0KGEuZWxlbWVudHMubW9kYWwsXCJjbGlja1wiLGEuX19pbnRlcm5hbC5tb2RhbENsaWNrSGFuZGxlcil9ZnVuY3Rpb24gemEoYSl7dShhLmVsZW1lbnRzLm1vZGFsLFwiY2xpY2tcIixhLl9faW50ZXJuYWwubW9kYWxDbGlja0hhbmRsZXIpfXZhciBBYSxCYSxDYT1bXSxEYT1udWxsLEVhPSExLEZhPWEubmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKFwiU2FmYXJpXCIpPi0xJiZhLm5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZihcIkNocm9tZVwiKTwwLEdhPXtkaW1tZXI6JzxkaXYgY2xhc3M9XCJhanMtZGltbWVyXCI+PC9kaXY+Jyxtb2RhbDonPGRpdiBjbGFzcz1cImFqcy1tb2RhbFwiIHRhYmluZGV4PVwiMFwiPjwvZGl2PicsZGlhbG9nOic8ZGl2IGNsYXNzPVwiYWpzLWRpYWxvZ1wiIHRhYmluZGV4PVwiMFwiPjwvZGl2PicscmVzZXQ6JzxidXR0b24gY2xhc3M9XCJhanMtcmVzZXRcIj48L2J1dHRvbj4nLGNvbW1hbmRzOic8ZGl2IGNsYXNzPVwiYWpzLWNvbW1hbmRzXCI+PGJ1dHRvbiBjbGFzcz1cImFqcy1waW5cIj48L2J1dHRvbj48YnV0dG9uIGNsYXNzPVwiYWpzLW1heGltaXplXCI+PC9idXR0b24+PGJ1dHRvbiBjbGFzcz1cImFqcy1jbG9zZVwiPjwvYnV0dG9uPjwvZGl2PicsaGVhZGVyOic8ZGl2IGNsYXNzPVwiYWpzLWhlYWRlclwiPjwvZGl2PicsYm9keTonPGRpdiBjbGFzcz1cImFqcy1ib2R5XCI+PC9kaXY+Jyxjb250ZW50Oic8ZGl2IGNsYXNzPVwiYWpzLWNvbnRlbnRcIj48L2Rpdj4nLGZvb3RlcjonPGRpdiBjbGFzcz1cImFqcy1mb290ZXJcIj48L2Rpdj4nLGJ1dHRvbnM6e3ByaW1hcnk6JzxkaXYgY2xhc3M9XCJhanMtcHJpbWFyeSBhanMtYnV0dG9uc1wiPjwvZGl2PicsYXV4aWxpYXJ5Oic8ZGl2IGNsYXNzPVwiYWpzLWF1eGlsaWFyeSBhanMtYnV0dG9uc1wiPjwvZGl2Pid9LGJ1dHRvbjonPGJ1dHRvbiBjbGFzcz1cImFqcy1idXR0b25cIj48L2J1dHRvbj4nLHJlc2l6ZUhhbmRsZTonPGRpdiBjbGFzcz1cImFqcy1oYW5kbGVcIj48L2Rpdj4nfSxIYT17YW5pbWF0aW9uSW46XCJhanMtaW5cIixhbmltYXRpb25PdXQ6XCJhanMtb3V0XCIsYmFzZTpcImFsZXJ0aWZ5XCIsYmFzaWM6XCJhanMtYmFzaWNcIixjYXB0dXJlOlwiYWpzLWNhcHR1cmVcIixjbG9zYWJsZTpcImFqcy1jbG9zYWJsZVwiLGZpeGVkOlwiYWpzLWZpeGVkXCIsZnJhbWVsZXNzOlwiYWpzLWZyYW1lbGVzc1wiLGhpZGRlbjpcImFqcy1oaWRkZW5cIixtYXhpbWl6ZTpcImFqcy1tYXhpbWl6ZVwiLG1heGltaXplZDpcImFqcy1tYXhpbWl6ZWRcIixtYXhpbWl6YWJsZTpcImFqcy1tYXhpbWl6YWJsZVwiLG1vZGVsZXNzOlwiYWpzLW1vZGVsZXNzXCIsbW92YWJsZTpcImFqcy1tb3ZhYmxlXCIsbm9TZWxlY3Rpb246XCJhanMtbm8tc2VsZWN0aW9uXCIsbm9PdmVyZmxvdzpcImFqcy1uby1vdmVyZmxvd1wiLG5vUGFkZGluZzpcImFqcy1uby1wYWRkaW5nXCIscGluOlwiYWpzLXBpblwiLHBpbm5hYmxlOlwiYWpzLXBpbm5hYmxlXCIscHJlZml4OlwiYWpzLVwiLHJlc2l6YWJsZTpcImFqcy1yZXNpemFibGVcIixyZXN0b3JlOlwiYWpzLXJlc3RvcmVcIixzaGFrZTpcImFqcy1zaGFrZVwiLHVucGlubmVkOlwiYWpzLXVucGlubmVkXCIsbm9UcmFuc2l0aW9uOlwiYWpzLW5vLXRyYW5zaXRpb25cIn0sSWE9XCJcIixKYT0wLEthPSExLExhPTAsTWE9MCxOYT0hMSxPYT1udWxsLFBhPTAsUWE9MCxSYT1cInBhZ2VYXCIsU2E9XCJwYWdlWVwiLFRhPW51bGwsVWE9ITEsVmE9bnVsbCxXYT1udWxsLFhhPU51bWJlci5OYW4sWWE9MCxaYT0wLCRhPTA7cmV0dXJue19faW5pdDptLGlzT3BlbjpmdW5jdGlvbigpe3JldHVybiB0aGlzLl9faW50ZXJuYWwuaXNPcGVufSxpc01vZGFsOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZWxlbWVudHMucm9vdC5jbGFzc05hbWUuaW5kZXhPZihIYS5tb2RlbGVzcyk8MH0saXNNYXhpbWl6ZWQ6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5lbGVtZW50cy5yb290LmNsYXNzTmFtZS5pbmRleE9mKEhhLm1heGltaXplZCk+LTF9LGlzUGlubmVkOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZWxlbWVudHMucm9vdC5jbGFzc05hbWUuaW5kZXhPZihIYS51bnBpbm5lZCk8MH0sbWF4aW1pemU6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5pc01heGltaXplZCgpfHxLKHRoaXMpLHRoaXN9LHJlc3RvcmU6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5pc01heGltaXplZCgpJiZMKHRoaXMpLHRoaXN9LHBpbjpmdW5jdGlvbigpe3JldHVybiB0aGlzLmlzUGlubmVkKCl8fEkodGhpcyksdGhpc30sdW5waW46ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5pc1Bpbm5lZCgpJiZKKHRoaXMpLHRoaXN9LGJyaW5nVG9Gcm9udDpmdW5jdGlvbigpe3JldHVybiBEKG51bGwsdGhpcyksdGhpc30sbW92ZVRvOmZ1bmN0aW9uKGEsYil7aWYoIWlzTmFOKGEpJiYhaXNOYU4oYikpe2woXCJvbm1vdmVcIix0aGlzKTt2YXIgYz10aGlzLmVsZW1lbnRzLmRpYWxvZyxlPWMsZj0wLGc9MDtjLnN0eWxlLmxlZnQmJihmLT1wYXJzZUludChjLnN0eWxlLmxlZnQsMTApKSxjLnN0eWxlLnRvcCYmKGctPXBhcnNlSW50KGMuc3R5bGUudG9wLDEwKSk7ZG97Zis9ZS5vZmZzZXRMZWZ0LGcrPWUub2Zmc2V0VG9wfXdoaWxlKGU9ZS5vZmZzZXRQYXJlbnQpO3ZhciBoPWEtZixpPWItZztkKCkmJihoKj0tMSksYy5zdHlsZS5sZWZ0PWgrXCJweFwiLGMuc3R5bGUudG9wPWkrXCJweFwiLGwoXCJvbm1vdmVkXCIsdGhpcyl9cmV0dXJuIHRoaXN9LHJlc2l6ZVRvOmZ1bmN0aW9uKGEsYil7dmFyIGM9cGFyc2VGbG9hdChhKSxkPXBhcnNlRmxvYXQoYiksZT0vKFxcZCpcXC5cXGQrfFxcZCspJS87aWYoIWlzTmFOKGMpJiYhaXNOYU4oZCkmJiEwPT09dGhpcy5nZXQoXCJyZXNpemFibGVcIikpe2woXCJvbnJlc2l6ZVwiLHRoaXMpLChcIlwiK2EpLm1hdGNoKGUpJiYoYz1jLzEwMCpkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50V2lkdGgpLChcIlwiK2IpLm1hdGNoKGUpJiYoZD1kLzEwMCpkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50SGVpZ2h0KTt2YXIgZj10aGlzLmVsZW1lbnRzLmRpYWxvZztcIm5vbmVcIiE9PWYuc3R5bGUubWF4V2lkdGgmJihmLnN0eWxlLm1pbldpZHRoPShaYT1mLm9mZnNldFdpZHRoKStcInB4XCIpLGYuc3R5bGUubWF4V2lkdGg9XCJub25lXCIsZi5zdHlsZS5taW5IZWlnaHQ9dGhpcy5lbGVtZW50cy5oZWFkZXIub2Zmc2V0SGVpZ2h0K3RoaXMuZWxlbWVudHMuZm9vdGVyLm9mZnNldEhlaWdodCtcInB4XCIsZi5zdHlsZS53aWR0aD1jK1wicHhcIixmLnN0eWxlLmhlaWdodD1kK1wicHhcIixsKFwib25yZXNpemVkXCIsdGhpcyl9cmV0dXJuIHRoaXN9LHNldHRpbmc6ZnVuY3Rpb24oYSxiKXt2YXIgYz10aGlzLGQ9Rih0aGlzLHRoaXMuX19pbnRlcm5hbC5vcHRpb25zLGZ1bmN0aW9uKGEsYixkKXtFKGMsYSxiLGQpfSxhLGIpO2lmKFwiZ2V0XCI9PT1kLm9wKXJldHVybiBkLmZvdW5kP2QudmFsdWU6dm9pZCAwIT09dGhpcy5zZXR0aW5ncz9GKHRoaXMsdGhpcy5zZXR0aW5ncyx0aGlzLnNldHRpbmdVcGRhdGVkfHxmdW5jdGlvbigpe30sYSxiKS52YWx1ZTp2b2lkIDA7aWYoXCJzZXRcIj09PWQub3Ape2lmKGQuaXRlbXMubGVuZ3RoPjApZm9yKHZhciBlPXRoaXMuc2V0dGluZ1VwZGF0ZWR8fGZ1bmN0aW9uKCl7fSxmPTA7ZjxkLml0ZW1zLmxlbmd0aDtmKz0xKXt2YXIgZz1kLml0ZW1zW2ZdO2cuZm91bmR8fHZvaWQgMD09PXRoaXMuc2V0dGluZ3N8fEYodGhpcyx0aGlzLnNldHRpbmdzLGUsZy5rZXksZy52YWx1ZSl9cmV0dXJuIHRoaXN9fSxzZXQ6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5zZXR0aW5nKGEsYiksdGhpc30sZ2V0OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLnNldHRpbmcoYSl9LHNldEhlYWRlcjpmdW5jdGlvbihiKXtyZXR1cm5cInN0cmluZ1wiPT10eXBlb2YgYj8oZyh0aGlzLmVsZW1lbnRzLmhlYWRlciksdGhpcy5lbGVtZW50cy5oZWFkZXIuaW5uZXJIVE1MPWIpOmIgaW5zdGFuY2VvZiBhLkhUTUxFbGVtZW50JiZ0aGlzLmVsZW1lbnRzLmhlYWRlci5maXJzdENoaWxkIT09YiYmKGcodGhpcy5lbGVtZW50cy5oZWFkZXIpLHRoaXMuZWxlbWVudHMuaGVhZGVyLmFwcGVuZENoaWxkKGIpKSx0aGlzfSxzZXRDb250ZW50OmZ1bmN0aW9uKGIpe3JldHVyblwic3RyaW5nXCI9PXR5cGVvZiBiPyhnKHRoaXMuZWxlbWVudHMuY29udGVudCksdGhpcy5lbGVtZW50cy5jb250ZW50LmlubmVySFRNTD1iKTpiIGluc3RhbmNlb2YgYS5IVE1MRWxlbWVudCYmdGhpcy5lbGVtZW50cy5jb250ZW50LmZpcnN0Q2hpbGQhPT1iJiYoZyh0aGlzLmVsZW1lbnRzLmNvbnRlbnQpLHRoaXMuZWxlbWVudHMuY29udGVudC5hcHBlbmRDaGlsZChiKSksdGhpc30sc2hvd01vZGFsOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLnNob3coITAsYSl9LHNob3c6ZnVuY3Rpb24oYSxkKXtpZihtKHRoaXMpLHRoaXMuX19pbnRlcm5hbC5pc09wZW4pe2hhKHRoaXMpLG5hKHRoaXMpLGIodGhpcy5lbGVtZW50cy5kaWFsb2csSGEuc2hha2UpO3ZhciBlPXRoaXM7c2V0VGltZW91dChmdW5jdGlvbigpe2MoZS5lbGVtZW50cy5kaWFsb2csSGEuc2hha2UpfSwyMDApfWVsc2V7aWYodGhpcy5fX2ludGVybmFsLmlzT3Blbj0hMCxxLnB1c2godGhpcykseS5kZWZhdWx0cy5tYWludGFpbkZvY3VzJiYodGhpcy5fX2ludGVybmFsLmFjdGl2ZUVsZW1lbnQ9ZG9jdW1lbnQuYWN0aXZlRWxlbWVudCksZG9jdW1lbnQuYm9keS5oYXNBdHRyaWJ1dGUoXCJ0YWJpbmRleFwiKXx8ZG9jdW1lbnQuYm9keS5zZXRBdHRyaWJ1dGUoXCJ0YWJpbmRleFwiLEVhPVwiMFwiKSxcImZ1bmN0aW9uXCI9PXR5cGVvZiB0aGlzLnByZXBhcmUmJnRoaXMucHJlcGFyZSgpLHFhKHRoaXMpLHZvaWQgMCE9PWEmJnRoaXMuc2V0KFwibW9kYWxcIixhKSxuKCkscygpLFwic3RyaW5nXCI9PXR5cGVvZiBkJiZcIlwiIT09ZCYmKHRoaXMuX19pbnRlcm5hbC5jbGFzc05hbWU9ZCxiKHRoaXMuZWxlbWVudHMucm9vdCxkKSksdGhpcy5nZXQoXCJzdGFydE1heGltaXplZFwiKT90aGlzLm1heGltaXplKCk6dGhpcy5pc01heGltaXplZCgpJiZMKHRoaXMpLFAodGhpcyksdGhpcy5lbGVtZW50cy5yb290LnJlbW92ZUF0dHJpYnV0ZShcInN0eWxlXCIpLGModGhpcy5lbGVtZW50cy5yb290LEhhLmFuaW1hdGlvbk91dCksYih0aGlzLmVsZW1lbnRzLnJvb3QsSGEuYW5pbWF0aW9uSW4pLGNsZWFyVGltZW91dCh0aGlzLl9faW50ZXJuYWwudGltZXJJbiksdGhpcy5fX2ludGVybmFsLnRpbWVySW49c2V0VGltZW91dCh0aGlzLl9faW50ZXJuYWwudHJhbnNpdGlvbkluSGFuZGxlcix2LnN1cHBvcnRlZD8xZTM6MTAwKSxGYSl7dmFyIGY9dGhpcy5lbGVtZW50cy5yb290O2Yuc3R5bGUuZGlzcGxheT1cIm5vbmVcIixzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7Zi5zdHlsZS5kaXNwbGF5PVwiYmxvY2tcIn0sMCl9RGE9dGhpcy5lbGVtZW50cy5yb290Lm9mZnNldFdpZHRoLGModGhpcy5lbGVtZW50cy5yb290LEhhLmhpZGRlbikscigpLFwiZnVuY3Rpb25cIj09dHlwZW9mIHRoaXMuaG9va3Mub25zaG93JiZ0aGlzLmhvb2tzLm9uc2hvdy5jYWxsKHRoaXMpLGwoXCJvbnNob3dcIix0aGlzKX1yZXR1cm4gdGhpc30sY2xvc2U6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5fX2ludGVybmFsLmlzT3BlbiYmITEhPT1sKFwib25jbG9zaW5nXCIsdGhpcykmJihyYSh0aGlzKSxjKHRoaXMuZWxlbWVudHMucm9vdCxIYS5hbmltYXRpb25JbiksYih0aGlzLmVsZW1lbnRzLnJvb3QsSGEuYW5pbWF0aW9uT3V0KSxjbGVhclRpbWVvdXQodGhpcy5fX2ludGVybmFsLnRpbWVyT3V0KSx0aGlzLl9faW50ZXJuYWwudGltZXJPdXQ9c2V0VGltZW91dCh0aGlzLl9faW50ZXJuYWwudHJhbnNpdGlvbk91dEhhbmRsZXIsdi5zdXBwb3J0ZWQ/MWUzOjEwMCksYih0aGlzLmVsZW1lbnRzLnJvb3QsSGEuaGlkZGVuKSxEYT10aGlzLmVsZW1lbnRzLm1vZGFsLm9mZnNldFdpZHRoLHkuZGVmYXVsdHMubWFpbnRhaW5Gb2N1cyYmdGhpcy5fX2ludGVybmFsLmFjdGl2ZUVsZW1lbnQmJih0aGlzLl9faW50ZXJuYWwuYWN0aXZlRWxlbWVudC5mb2N1cygpLHRoaXMuX19pbnRlcm5hbC5hY3RpdmVFbGVtZW50PW51bGwpLHZvaWQgMCE9PXRoaXMuX19pbnRlcm5hbC5jbGFzc05hbWUmJlwiXCIhPT10aGlzLl9faW50ZXJuYWwuY2xhc3NOYW1lJiZjKHRoaXMuZWxlbWVudHMucm9vdCx0aGlzLl9faW50ZXJuYWwuY2xhc3NOYW1lKSxcImZ1bmN0aW9uXCI9PXR5cGVvZiB0aGlzLmhvb2tzLm9uY2xvc2UmJnRoaXMuaG9va3Mub25jbG9zZS5jYWxsKHRoaXMpLGwoXCJvbmNsb3NlXCIsdGhpcykscS5zcGxpY2UocS5pbmRleE9mKHRoaXMpLDEpLHRoaXMuX19pbnRlcm5hbC5pc09wZW49ITEscygpKSxxLmxlbmd0aHx8XCIwXCIhPT1FYXx8ZG9jdW1lbnQuYm9keS5yZW1vdmVBdHRyaWJ1dGUoXCJ0YWJpbmRleFwiKSx0aGlzfSxjbG9zZU90aGVyczpmdW5jdGlvbigpe3JldHVybiB5LmNsb3NlQWxsKHRoaXMpLHRoaXN9LGRlc3Ryb3k6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5fX2ludGVybmFsJiYodGhpcy5fX2ludGVybmFsLmlzT3Blbj8odGhpcy5fX2ludGVybmFsLmRlc3Ryb3k9ZnVuY3Rpb24oKXtpKHRoaXMsbSl9LHRoaXMuY2xvc2UoKSk6dGhpcy5fX2ludGVybmFsLmRlc3Ryb3l8fGkodGhpcyxtKSksdGhpc319fSgpLHg9ZnVuY3Rpb24oKXtmdW5jdGlvbiBkKGEpe2lmKCFhLl9faW50ZXJuYWwpe2EuX19pbnRlcm5hbD17cG9zaXRpb246eS5kZWZhdWx0cy5ub3RpZmllci5wb3NpdGlvbixkZWxheTp5LmRlZmF1bHRzLm5vdGlmaWVyLmRlbGF5fSxsPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJESVZcIik7KFwidHJhbnNpdGlvbk9mZlwiaW4gcC5ub3RpZmllcj9wLm5vdGlmaWVyLnRyYW5zaXRpb25PZmY6cC50cmFuc2l0aW9uT2ZmKSYmKG89bi5iYXNlK1wiIGFqcy1uby10cmFuc2l0aW9uXCIpLGgoYSl9bC5wYXJlbnROb2RlIT09ZG9jdW1lbnQuYm9keSYmZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChsKX1mdW5jdGlvbiBlKGEpe2EuX19pbnRlcm5hbC5wdXNoZWQ9ITAsbS5wdXNoKGEpfWZ1bmN0aW9uIGYoYSl7bS5zcGxpY2UobS5pbmRleE9mKGEpLDEpLGEuX19pbnRlcm5hbC5wdXNoZWQ9ITF9ZnVuY3Rpb24gaChhKXtzd2l0Y2gobC5jbGFzc05hbWU9byxhLl9faW50ZXJuYWwucG9zaXRpb24pe2Nhc2VcInRvcC1yaWdodFwiOmIobCxuLnRvcCtcIiBcIituLnJpZ2h0KTticmVhaztjYXNlXCJ0b3AtbGVmdFwiOmIobCxuLnRvcCtcIiBcIituLmxlZnQpO2JyZWFrO2Nhc2VcInRvcC1jZW50ZXJcIjpiKGwsbi50b3ArXCIgXCIrbi5jZW50ZXIpO2JyZWFrO2Nhc2VcImJvdHRvbS1sZWZ0XCI6YihsLG4uYm90dG9tK1wiIFwiK24ubGVmdCk7YnJlYWs7Y2FzZVwiYm90dG9tLWNlbnRlclwiOmIobCxuLmJvdHRvbStcIiBcIituLmNlbnRlcik7YnJlYWs7ZGVmYXVsdDpjYXNlXCJib3R0b20tcmlnaHRcIjpiKGwsbi5ib3R0b20rXCIgXCIrbi5yaWdodCl9fWZ1bmN0aW9uIGkoZCxoKXtmdW5jdGlvbiBpKGEsYil7Yi5fX2ludGVybmFsLmNsb3NlQnV0dG9uJiZcInRydWVcIiE9PWEudGFyZ2V0LmdldEF0dHJpYnV0ZShcImRhdGEtY2xvc2VcIil8fGIuZGlzbWlzcyghMCl9ZnVuY3Rpb24gbShhLGIpe3UoYi5lbGVtZW50LHYudHlwZSxtKSxsLnJlbW92ZUNoaWxkKGIuZWxlbWVudCl9ZnVuY3Rpb24gbyhhKXtyZXR1cm4gYS5fX2ludGVybmFsfHwoYS5fX2ludGVybmFsPXtwdXNoZWQ6ITEsZGVsYXk6dm9pZCAwLHRpbWVyOnZvaWQgMCxjbGlja0hhbmRsZXI6dm9pZCAwLHRyYW5zaXRpb25FbmRIYW5kbGVyOnZvaWQgMCx0cmFuc2l0aW9uVGltZW91dDp2b2lkIDB9LGEuX19pbnRlcm5hbC5jbGlja0hhbmRsZXI9aihhLGkpLGEuX19pbnRlcm5hbC50cmFuc2l0aW9uRW5kSGFuZGxlcj1qKGEsbSkpLGF9ZnVuY3Rpb24gcChhKXtjbGVhclRpbWVvdXQoYS5fX2ludGVybmFsLnRpbWVyKSxjbGVhclRpbWVvdXQoYS5fX2ludGVybmFsLnRyYW5zaXRpb25UaW1lb3V0KX1yZXR1cm4gbyh7ZWxlbWVudDpkLHB1c2g6ZnVuY3Rpb24oYSxjKXtpZighdGhpcy5fX2ludGVybmFsLnB1c2hlZCl7ZSh0aGlzKSxwKHRoaXMpO3ZhciBkLGY7c3dpdGNoKGFyZ3VtZW50cy5sZW5ndGgpe2Nhc2UgMDpmPXRoaXMuX19pbnRlcm5hbC5kZWxheTticmVhaztjYXNlIDE6XCJudW1iZXJcIj09dHlwZW9mIGE/Zj1hOihkPWEsZj10aGlzLl9faW50ZXJuYWwuZGVsYXkpO2JyZWFrO2Nhc2UgMjpkPWEsZj1jfXJldHVybiB0aGlzLl9faW50ZXJuYWwuY2xvc2VCdXR0b249eS5kZWZhdWx0cy5ub3RpZmllci5jbG9zZUJ1dHRvbix2b2lkIDAhPT1kJiZ0aGlzLnNldENvbnRlbnQoZCkseC5fX2ludGVybmFsLnBvc2l0aW9uLmluZGV4T2YoXCJ0b3BcIik8MD9sLmFwcGVuZENoaWxkKHRoaXMuZWxlbWVudCk6bC5pbnNlcnRCZWZvcmUodGhpcy5lbGVtZW50LGwuZmlyc3RDaGlsZCksaz10aGlzLmVsZW1lbnQub2Zmc2V0V2lkdGgsYih0aGlzLmVsZW1lbnQsbi52aXNpYmxlKSx0KHRoaXMuZWxlbWVudCxcImNsaWNrXCIsdGhpcy5fX2ludGVybmFsLmNsaWNrSGFuZGxlciksdGhpcy5kZWxheShmKX1yZXR1cm4gdGhpc30sb25kaXNtaXNzOmZ1bmN0aW9uKCl7fSxjYWxsYmFjazpoLGRpc21pc3M6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuX19pbnRlcm5hbC5wdXNoZWQmJihwKHRoaXMpLFwiZnVuY3Rpb25cIj09dHlwZW9mIHRoaXMub25kaXNtaXNzJiYhMT09PXRoaXMub25kaXNtaXNzLmNhbGwodGhpcyl8fCh1KHRoaXMuZWxlbWVudCxcImNsaWNrXCIsdGhpcy5fX2ludGVybmFsLmNsaWNrSGFuZGxlciksdm9pZCAwIT09dGhpcy5lbGVtZW50JiZ0aGlzLmVsZW1lbnQucGFyZW50Tm9kZT09PWwmJih0aGlzLl9faW50ZXJuYWwudHJhbnNpdGlvblRpbWVvdXQ9c2V0VGltZW91dCh0aGlzLl9faW50ZXJuYWwudHJhbnNpdGlvbkVuZEhhbmRsZXIsdi5zdXBwb3J0ZWQ/MWUzOjEwMCksYyh0aGlzLmVsZW1lbnQsbi52aXNpYmxlKSxcImZ1bmN0aW9uXCI9PXR5cGVvZiB0aGlzLmNhbGxiYWNrJiZ0aGlzLmNhbGxiYWNrLmNhbGwodGhpcyxhKSksZih0aGlzKSkpLHRoaXN9LGRlbGF5OmZ1bmN0aW9uKGEpe2lmKHAodGhpcyksdGhpcy5fX2ludGVybmFsLmRlbGF5PXZvaWQgMD09PWF8fGlzTmFOKCthKT94Ll9faW50ZXJuYWwuZGVsYXk6K2EsdGhpcy5fX2ludGVybmFsLmRlbGF5PjApe3ZhciBiPXRoaXM7dGhpcy5fX2ludGVybmFsLnRpbWVyPXNldFRpbWVvdXQoZnVuY3Rpb24oKXtiLmRpc21pc3MoKX0sMWUzKnRoaXMuX19pbnRlcm5hbC5kZWxheSl9cmV0dXJuIHRoaXN9LHNldENvbnRlbnQ6ZnVuY3Rpb24oYyl7aWYoXCJzdHJpbmdcIj09dHlwZW9mIGM/KGcodGhpcy5lbGVtZW50KSx0aGlzLmVsZW1lbnQuaW5uZXJIVE1MPWMpOmMgaW5zdGFuY2VvZiBhLkhUTUxFbGVtZW50JiZ0aGlzLmVsZW1lbnQuZmlyc3RDaGlsZCE9PWMmJihnKHRoaXMuZWxlbWVudCksdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKGMpKSx0aGlzLl9faW50ZXJuYWwuY2xvc2VCdXR0b24pe3ZhciBkPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJzcGFuXCIpO2IoZCxuLmNsb3NlKSxkLnNldEF0dHJpYnV0ZShcImRhdGEtY2xvc2VcIiwhMCksdGhpcy5lbGVtZW50LmFwcGVuZENoaWxkKGQpfXJldHVybiB0aGlzfSxkaXNtaXNzT3RoZXJzOmZ1bmN0aW9uKCl7cmV0dXJuIHguZGlzbWlzc0FsbCh0aGlzKSx0aGlzfX0pfXZhciBrLGwsbT1bXSxuPXAubm90aWZpZXIuY2xhc3NlcyxvPW4uYmFzZTtyZXR1cm57c2V0dGluZzpmdW5jdGlvbihhLGIpe2lmKGQodGhpcyksdm9pZCAwPT09YilyZXR1cm4gdGhpcy5fX2ludGVybmFsW2FdO3N3aXRjaChhKXtjYXNlXCJwb3NpdGlvblwiOnRoaXMuX19pbnRlcm5hbC5wb3NpdGlvbj1iLGgodGhpcyk7YnJlYWs7Y2FzZVwiZGVsYXlcIjp0aGlzLl9faW50ZXJuYWwuZGVsYXk9Yn1yZXR1cm4gdGhpc30sc2V0OmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuc2V0dGluZyhhLGIpLHRoaXN9LGdldDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5zZXR0aW5nKGEpfSxjcmVhdGU6ZnVuY3Rpb24oYSxiKXtkKHRoaXMpO3ZhciBjPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7cmV0dXJuIGMuY2xhc3NOYW1lPW4ubWVzc2FnZSsoXCJzdHJpbmdcIj09dHlwZW9mIGEmJlwiXCIhPT1hP1wiIFwiK24ucHJlZml4K2E6XCJcIiksaShjLGIpfSxkaXNtaXNzQWxsOmZ1bmN0aW9uKGEpe2Zvcih2YXIgYj1tLnNsaWNlKDApLGM9MDtjPGIubGVuZ3RoO2MrPTEpe3ZhciBkPWJbY107dm9pZCAwIT09YSYmYT09PWR8fGQuZGlzbWlzcygpfX19fSgpLHk9bmV3IG07eS5kaWFsb2coXCJhbGVydFwiLGZ1bmN0aW9uKCl7cmV0dXJue21haW46ZnVuY3Rpb24oYSxiLGMpe3ZhciBkLGUsZjtzd2l0Y2goYXJndW1lbnRzLmxlbmd0aCl7Y2FzZSAxOmU9YTticmVhaztjYXNlIDI6XCJmdW5jdGlvblwiPT10eXBlb2YgYj8oZT1hLGY9Yik6KGQ9YSxlPWIpO2JyZWFrO2Nhc2UgMzpkPWEsZT1iLGY9Y31yZXR1cm4gdGhpcy5zZXQoXCJ0aXRsZVwiLGQpLHRoaXMuc2V0KFwibWVzc2FnZVwiLGUpLHRoaXMuc2V0KFwib25va1wiLGYpLHRoaXN9LHNldHVwOmZ1bmN0aW9uKCl7cmV0dXJue2J1dHRvbnM6W3t0ZXh0OnkuZGVmYXVsdHMuZ2xvc3Nhcnkub2ssa2V5Om8uRVNDLGludm9rZU9uQ2xvc2U6ITAsY2xhc3NOYW1lOnkuZGVmYXVsdHMudGhlbWUub2t9XSxmb2N1czp7ZWxlbWVudDowLHNlbGVjdDohMX0sb3B0aW9uczp7bWF4aW1pemFibGU6ITEscmVzaXphYmxlOiExfX19LGJ1aWxkOmZ1bmN0aW9uKCl7fSxwcmVwYXJlOmZ1bmN0aW9uKCl7fSxzZXRNZXNzYWdlOmZ1bmN0aW9uKGEpe3RoaXMuc2V0Q29udGVudChhKX0sc2V0dGluZ3M6e21lc3NhZ2U6dm9pZCAwLG9ub2s6dm9pZCAwLGxhYmVsOnZvaWQgMH0sc2V0dGluZ1VwZGF0ZWQ6ZnVuY3Rpb24oYSxiLGMpe3N3aXRjaChhKXtjYXNlXCJtZXNzYWdlXCI6dGhpcy5zZXRNZXNzYWdlKGMpO2JyZWFrO2Nhc2VcImxhYmVsXCI6dGhpcy5fX2ludGVybmFsLmJ1dHRvbnNbMF0uZWxlbWVudCYmKHRoaXMuX19pbnRlcm5hbC5idXR0b25zWzBdLmVsZW1lbnQuaW5uZXJIVE1MPWMpfX0sXG5jYWxsYmFjazpmdW5jdGlvbihhKXtpZihcImZ1bmN0aW9uXCI9PXR5cGVvZiB0aGlzLmdldChcIm9ub2tcIikpe3ZhciBiPXRoaXMuZ2V0KFwib25va1wiKS5jYWxsKHRoaXMsYSk7dm9pZCAwIT09YiYmKGEuY2FuY2VsPSFiKX19fX0pLHkuZGlhbG9nKFwiY29uZmlybVwiLGZ1bmN0aW9uKCl7ZnVuY3Rpb24gYShhKXtudWxsIT09Yy50aW1lciYmKGNsZWFySW50ZXJ2YWwoYy50aW1lciksYy50aW1lcj1udWxsLGEuX19pbnRlcm5hbC5idXR0b25zW2MuaW5kZXhdLmVsZW1lbnQuaW5uZXJIVE1MPWMudGV4dCl9ZnVuY3Rpb24gYihiLGQsZSl7YShiKSxjLmR1cmF0aW9uPWUsYy5pbmRleD1kLGMudGV4dD1iLl9faW50ZXJuYWwuYnV0dG9uc1tkXS5lbGVtZW50LmlubmVySFRNTCxjLnRpbWVyPXNldEludGVydmFsKGooYixjLnRhc2spLDFlMyksYy50YXNrKG51bGwsYil9dmFyIGM9e3RpbWVyOm51bGwsaW5kZXg6bnVsbCx0ZXh0Om51bGwsZHVyYXRpb246bnVsbCx0YXNrOmZ1bmN0aW9uKGIsZCl7aWYoZC5pc09wZW4oKSl7aWYoZC5fX2ludGVybmFsLmJ1dHRvbnNbYy5pbmRleF0uZWxlbWVudC5pbm5lckhUTUw9Yy50ZXh0K1wiICgmIzgyMDc7XCIrYy5kdXJhdGlvbitcIiYjODIwNzspIFwiLGMuZHVyYXRpb24tPTEsLTE9PT1jLmR1cmF0aW9uKXthKGQpO3ZhciBlPWQuX19pbnRlcm5hbC5idXR0b25zW2MuaW5kZXhdLGY9ayhjLmluZGV4LGUpO1wiZnVuY3Rpb25cIj09dHlwZW9mIGQuY2FsbGJhY2smJmQuY2FsbGJhY2suYXBwbHkoZCxbZl0pLCExIT09Zi5jbG9zZSYmZC5jbG9zZSgpfX1lbHNlIGEoZCl9fTtyZXR1cm57bWFpbjpmdW5jdGlvbihhLGIsYyxkKXt2YXIgZSxmLGcsaDtzd2l0Y2goYXJndW1lbnRzLmxlbmd0aCl7Y2FzZSAxOmY9YTticmVhaztjYXNlIDI6Zj1hLGc9YjticmVhaztjYXNlIDM6Zj1hLGc9YixoPWM7YnJlYWs7Y2FzZSA0OmU9YSxmPWIsZz1jLGg9ZH1yZXR1cm4gdGhpcy5zZXQoXCJ0aXRsZVwiLGUpLHRoaXMuc2V0KFwibWVzc2FnZVwiLGYpLHRoaXMuc2V0KFwib25va1wiLGcpLHRoaXMuc2V0KFwib25jYW5jZWxcIixoKSx0aGlzfSxzZXR1cDpmdW5jdGlvbigpe3JldHVybntidXR0b25zOlt7dGV4dDp5LmRlZmF1bHRzLmdsb3NzYXJ5Lm9rLGtleTpvLkVOVEVSLGNsYXNzTmFtZTp5LmRlZmF1bHRzLnRoZW1lLm9rfSx7dGV4dDp5LmRlZmF1bHRzLmdsb3NzYXJ5LmNhbmNlbCxrZXk6by5FU0MsaW52b2tlT25DbG9zZTohMCxjbGFzc05hbWU6eS5kZWZhdWx0cy50aGVtZS5jYW5jZWx9XSxmb2N1czp7ZWxlbWVudDowLHNlbGVjdDohMX0sb3B0aW9uczp7bWF4aW1pemFibGU6ITEscmVzaXphYmxlOiExfX19LGJ1aWxkOmZ1bmN0aW9uKCl7fSxwcmVwYXJlOmZ1bmN0aW9uKCl7fSxzZXRNZXNzYWdlOmZ1bmN0aW9uKGEpe3RoaXMuc2V0Q29udGVudChhKX0sc2V0dGluZ3M6e21lc3NhZ2U6bnVsbCxsYWJlbHM6bnVsbCxvbm9rOm51bGwsb25jYW5jZWw6bnVsbCxkZWZhdWx0Rm9jdXM6bnVsbCxyZXZlcnNlQnV0dG9uczpudWxsfSxzZXR0aW5nVXBkYXRlZDpmdW5jdGlvbihhLGIsYyl7c3dpdGNoKGEpe2Nhc2VcIm1lc3NhZ2VcIjp0aGlzLnNldE1lc3NhZ2UoYyk7YnJlYWs7Y2FzZVwibGFiZWxzXCI6XCJva1wiaW4gYyYmdGhpcy5fX2ludGVybmFsLmJ1dHRvbnNbMF0uZWxlbWVudCYmKHRoaXMuX19pbnRlcm5hbC5idXR0b25zWzBdLnRleHQ9Yy5vayx0aGlzLl9faW50ZXJuYWwuYnV0dG9uc1swXS5lbGVtZW50LmlubmVySFRNTD1jLm9rKSxcImNhbmNlbFwiaW4gYyYmdGhpcy5fX2ludGVybmFsLmJ1dHRvbnNbMV0uZWxlbWVudCYmKHRoaXMuX19pbnRlcm5hbC5idXR0b25zWzFdLnRleHQ9Yy5jYW5jZWwsdGhpcy5fX2ludGVybmFsLmJ1dHRvbnNbMV0uZWxlbWVudC5pbm5lckhUTUw9Yy5jYW5jZWwpO2JyZWFrO2Nhc2VcInJldmVyc2VCdXR0b25zXCI6ITA9PT1jP3RoaXMuZWxlbWVudHMuYnV0dG9ucy5wcmltYXJ5LmFwcGVuZENoaWxkKHRoaXMuX19pbnRlcm5hbC5idXR0b25zWzBdLmVsZW1lbnQpOnRoaXMuZWxlbWVudHMuYnV0dG9ucy5wcmltYXJ5LmFwcGVuZENoaWxkKHRoaXMuX19pbnRlcm5hbC5idXR0b25zWzFdLmVsZW1lbnQpO2JyZWFrO2Nhc2VcImRlZmF1bHRGb2N1c1wiOnRoaXMuX19pbnRlcm5hbC5mb2N1cy5lbGVtZW50PVwib2tcIj09PWM/MDoxfX0sY2FsbGJhY2s6ZnVuY3Rpb24oYil7YSh0aGlzKTt2YXIgYztzd2l0Y2goYi5pbmRleCl7Y2FzZSAwOlwiZnVuY3Rpb25cIj09dHlwZW9mIHRoaXMuZ2V0KFwib25va1wiKSYmdm9pZCAwIT09KGM9dGhpcy5nZXQoXCJvbm9rXCIpLmNhbGwodGhpcyxiKSkmJihiLmNhbmNlbD0hYyk7YnJlYWs7Y2FzZSAxOlwiZnVuY3Rpb25cIj09dHlwZW9mIHRoaXMuZ2V0KFwib25jYW5jZWxcIikmJnZvaWQgMCE9PShjPXRoaXMuZ2V0KFwib25jYW5jZWxcIikuY2FsbCh0aGlzLGIpKSYmKGIuY2FuY2VsPSFjKX19LGF1dG9PazpmdW5jdGlvbihhKXtyZXR1cm4gYih0aGlzLDAsYSksdGhpc30sYXV0b0NhbmNlbDpmdW5jdGlvbihhKXtyZXR1cm4gYih0aGlzLDEsYSksdGhpc319fSkseS5kaWFsb2coXCJwcm9tcHRcIixmdW5jdGlvbigpe3ZhciBiPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJJTlBVVFwiKSxjPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJQXCIpO3JldHVybnttYWluOmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIGYsZyxoLGksajtzd2l0Y2goYXJndW1lbnRzLmxlbmd0aCl7Y2FzZSAxOmc9YTticmVhaztjYXNlIDI6Zz1hLGg9YjticmVhaztjYXNlIDM6Zz1hLGg9YixpPWM7YnJlYWs7Y2FzZSA0Omc9YSxoPWIsaT1jLGo9ZDticmVhaztjYXNlIDU6Zj1hLGc9YixoPWMsaT1kLGo9ZX1yZXR1cm4gdGhpcy5zZXQoXCJ0aXRsZVwiLGYpLHRoaXMuc2V0KFwibWVzc2FnZVwiLGcpLHRoaXMuc2V0KFwidmFsdWVcIixoKSx0aGlzLnNldChcIm9ub2tcIixpKSx0aGlzLnNldChcIm9uY2FuY2VsXCIsaiksdGhpc30sc2V0dXA6ZnVuY3Rpb24oKXtyZXR1cm57YnV0dG9uczpbe3RleHQ6eS5kZWZhdWx0cy5nbG9zc2FyeS5vayxrZXk6by5FTlRFUixjbGFzc05hbWU6eS5kZWZhdWx0cy50aGVtZS5va30se3RleHQ6eS5kZWZhdWx0cy5nbG9zc2FyeS5jYW5jZWwsa2V5Om8uRVNDLGludm9rZU9uQ2xvc2U6ITAsY2xhc3NOYW1lOnkuZGVmYXVsdHMudGhlbWUuY2FuY2VsfV0sZm9jdXM6e2VsZW1lbnQ6YixzZWxlY3Q6ITB9LG9wdGlvbnM6e21heGltaXphYmxlOiExLHJlc2l6YWJsZTohMX19fSxidWlsZDpmdW5jdGlvbigpe2IuY2xhc3NOYW1lPXkuZGVmYXVsdHMudGhlbWUuaW5wdXQsYi5zZXRBdHRyaWJ1dGUoXCJ0eXBlXCIsXCJ0ZXh0XCIpLGIudmFsdWU9dGhpcy5nZXQoXCJ2YWx1ZVwiKSx0aGlzLmVsZW1lbnRzLmNvbnRlbnQuYXBwZW5kQ2hpbGQoYyksdGhpcy5lbGVtZW50cy5jb250ZW50LmFwcGVuZENoaWxkKGIpfSxwcmVwYXJlOmZ1bmN0aW9uKCl7fSxzZXRNZXNzYWdlOmZ1bmN0aW9uKGIpe1wic3RyaW5nXCI9PXR5cGVvZiBiPyhnKGMpLGMuaW5uZXJIVE1MPWIpOmIgaW5zdGFuY2VvZiBhLkhUTUxFbGVtZW50JiZjLmZpcnN0Q2hpbGQhPT1iJiYoZyhjKSxjLmFwcGVuZENoaWxkKGIpKX0sc2V0dGluZ3M6e21lc3NhZ2U6dm9pZCAwLGxhYmVsczp2b2lkIDAsb25vazp2b2lkIDAsb25jYW5jZWw6dm9pZCAwLHZhbHVlOlwiXCIsdHlwZTpcInRleHRcIixyZXZlcnNlQnV0dG9uczp2b2lkIDB9LHNldHRpbmdVcGRhdGVkOmZ1bmN0aW9uKGEsYyxkKXtzd2l0Y2goYSl7Y2FzZVwibWVzc2FnZVwiOnRoaXMuc2V0TWVzc2FnZShkKTticmVhaztjYXNlXCJ2YWx1ZVwiOmIudmFsdWU9ZDticmVhaztjYXNlXCJ0eXBlXCI6c3dpdGNoKGQpe2Nhc2VcInRleHRcIjpjYXNlXCJjb2xvclwiOmNhc2VcImRhdGVcIjpjYXNlXCJkYXRldGltZS1sb2NhbFwiOmNhc2VcImVtYWlsXCI6Y2FzZVwibW9udGhcIjpjYXNlXCJudW1iZXJcIjpjYXNlXCJwYXNzd29yZFwiOmNhc2VcInNlYXJjaFwiOmNhc2VcInRlbFwiOmNhc2VcInRpbWVcIjpjYXNlXCJ3ZWVrXCI6Yi50eXBlPWQ7YnJlYWs7ZGVmYXVsdDpiLnR5cGU9XCJ0ZXh0XCJ9YnJlYWs7Y2FzZVwibGFiZWxzXCI6ZC5vayYmdGhpcy5fX2ludGVybmFsLmJ1dHRvbnNbMF0uZWxlbWVudCYmKHRoaXMuX19pbnRlcm5hbC5idXR0b25zWzBdLmVsZW1lbnQuaW5uZXJIVE1MPWQub2spLGQuY2FuY2VsJiZ0aGlzLl9faW50ZXJuYWwuYnV0dG9uc1sxXS5lbGVtZW50JiYodGhpcy5fX2ludGVybmFsLmJ1dHRvbnNbMV0uZWxlbWVudC5pbm5lckhUTUw9ZC5jYW5jZWwpO2JyZWFrO2Nhc2VcInJldmVyc2VCdXR0b25zXCI6ITA9PT1kP3RoaXMuZWxlbWVudHMuYnV0dG9ucy5wcmltYXJ5LmFwcGVuZENoaWxkKHRoaXMuX19pbnRlcm5hbC5idXR0b25zWzBdLmVsZW1lbnQpOnRoaXMuZWxlbWVudHMuYnV0dG9ucy5wcmltYXJ5LmFwcGVuZENoaWxkKHRoaXMuX19pbnRlcm5hbC5idXR0b25zWzFdLmVsZW1lbnQpfX0sY2FsbGJhY2s6ZnVuY3Rpb24oYSl7dmFyIGM7c3dpdGNoKGEuaW5kZXgpe2Nhc2UgMDp0aGlzLnNldHRpbmdzLnZhbHVlPWIudmFsdWUsXCJmdW5jdGlvblwiPT10eXBlb2YgdGhpcy5nZXQoXCJvbm9rXCIpJiZ2b2lkIDAhPT0oYz10aGlzLmdldChcIm9ub2tcIikuY2FsbCh0aGlzLGEsdGhpcy5zZXR0aW5ncy52YWx1ZSkpJiYoYS5jYW5jZWw9IWMpO2JyZWFrO2Nhc2UgMTpcImZ1bmN0aW9uXCI9PXR5cGVvZiB0aGlzLmdldChcIm9uY2FuY2VsXCIpJiZ2b2lkIDAhPT0oYz10aGlzLmdldChcIm9uY2FuY2VsXCIpLmNhbGwodGhpcyxhKSkmJihhLmNhbmNlbD0hYyksYS5jYW5jZWx8fChiLnZhbHVlPXRoaXMuc2V0dGluZ3MudmFsdWUpfX19fSksXCJvYmplY3RcIj09dHlwZW9mIG1vZHVsZSYmXCJvYmplY3RcIj09dHlwZW9mIG1vZHVsZS5leHBvcnRzP21vZHVsZS5leHBvcnRzPXk6XCJmdW5jdGlvblwiPT10eXBlb2YgZGVmaW5lJiZkZWZpbmUuYW1kP2RlZmluZShbXSxmdW5jdGlvbigpe3JldHVybiB5fSk6YS5hbGVydGlmeXx8KGEuYWxlcnRpZnk9eSl9KFwidW5kZWZpbmVkXCIhPXR5cGVvZiB3aW5kb3c/d2luZG93OnRoaXMpOyJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/alertifyjs/build/alertify.min.js\n");
/***/ }),
/***/ "./node_modules/axios/index.js":
/*!*************************************!*\
!*** ./node_modules/axios/index.js ***!
\*************************************/
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
eval("module.exports = __webpack_require__(/*! ./lib/axios */ \"./node_modules/axios/lib/axios.js\");//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvYXhpb3MvaW5kZXguanMiLCJtYXBwaW5ncyI6IkFBQUEsNEZBQXVDIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL2F4aW9zL2luZGV4LmpzPzUzZTkiXSwic291cmNlc0NvbnRlbnQiOlsibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2xpYi9heGlvcycpOyJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/axios/index.js\n");
/***/ }),
/***/ "./node_modules/axios/lib/adapters/xhr.js":
/*!************************************************!*\
!*** ./node_modules/axios/lib/adapters/xhr.js ***!
\************************************************/
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict";
eval("\n\nvar utils = __webpack_require__(/*! ./../utils */ \"./node_modules/axios/lib/utils.js\");\nvar settle = __webpack_require__(/*! ./../core/settle */ \"./node_modules/axios/lib/core/settle.js\");\nvar cookies = __webpack_require__(/*! ./../helpers/cookies */ \"./node_modules/axios/lib/helpers/cookies.js\");\nvar buildURL = __webpack_require__(/*! ./../helpers/buildURL */ \"./node_modules/axios/lib/helpers/buildURL.js\");\nvar buildFullPath = __webpack_require__(/*! ../core/buildFullPath */ \"./node_modules/axios/lib/core/buildFullPath.js\");\nvar parseHeaders = __webpack_require__(/*! ./../helpers/parseHeaders */ \"./node_modules/axios/lib/helpers/parseHeaders.js\");\nvar isURLSameOrigin = __webpack_require__(/*! ./../helpers/isURLSameOrigin */ \"./node_modules/axios/lib/helpers/isURLSameOrigin.js\");\nvar transitionalDefaults = __webpack_require__(/*! ../defaults/transitional */ \"./node_modules/axios/lib/defaults/transitional.js\");\nvar AxiosError = __webpack_require__(/*! ../core/AxiosError */ \"./node_modules/axios/lib/core/AxiosError.js\");\nvar CanceledError = __webpack_require__(/*! ../cancel/CanceledError */ \"./node_modules/axios/lib/cancel/CanceledError.js\");\nvar parseProtocol = __webpack_require__(/*! ../helpers/parseProtocol */ \"./node_modules/axios/lib/helpers/parseProtocol.js\");\n\nmodule.exports = function xhrAdapter(config) {\n return new Promise(function dispatchXhrRequest(resolve, reject) {\n var requestData = config.data;\n var requestHeaders = config.headers;\n var responseType = config.responseType;\n var onCanceled;\n function done() {\n if (config.cancelToken) {\n config.cancelToken.unsubscribe(onCanceled);\n }\n\n if (config.signal) {\n config.signal.removeEventListener('abort', onCanceled);\n }\n }\n\n if (utils.isFormData(requestData) && utils.isStandardBrowserEnv()) {\n delete requestHeaders['Content-Type']; // Let the browser set it\n }\n\n var request = new XMLHttpRequest();\n\n // HTTP basic authentication\n if (config.auth) {\n var username = config.auth.username || '';\n var password = config.auth.password ? unescape(encodeURIComponent(config.auth.password)) : '';\n requestHeaders.Authorization = 'Basic ' + btoa(username + ':' + password);\n }\n\n var fullPath = buildFullPath(config.baseURL, config.url);\n\n request.open(config.method.toUpperCase(), buildURL(fullPath, config.params, config.paramsSerializer), true);\n\n // Set the request timeout in MS\n request.timeout = config.timeout;\n\n function onloadend() {\n if (!request) {\n return;\n }\n // Prepare the response\n var responseHeaders = 'getAllResponseHeaders' in request ? parseHeaders(request.getAllResponseHeaders()) : null;\n var responseData = !responseType || responseType === 'text' || responseType === 'json' ?\n request.responseText : request.response;\n var response = {\n data: responseData,\n status: request.status,\n statusText: request.statusText,\n headers: responseHeaders,\n config: config,\n request: request\n };\n\n settle(function _resolve(value) {\n resolve(value);\n done();\n }, function _reject(err) {\n reject(err);\n done();\n }, response);\n\n // Clean up request\n request = null;\n }\n\n if ('onloadend' in request) {\n // Use onloadend if available\n request.onloadend = onloadend;\n } else {\n // Listen for ready state to emulate onloadend\n request.onreadystatechange = function handleLoad() {\n if (!request || request.readyState !== 4) {\n return;\n }\n\n // The request errored out and we didn't get a response, this will be\n // handled by onerror instead\n // With one exception: request that using file: protocol, most browsers\n // will return status as 0 even though it's a successful request\n if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf('file:') === 0)) {\n return;\n }\n // readystate handler is calling before onerror or ontimeout handlers,\n // so we should call onloadend on the next 'tick'\n setTimeout(onloadend);\n };\n }\n\n // Handle browser request cancellation (as opposed to a manual cancellation)\n request.onabort = function handleAbort() {\n if (!request) {\n return;\n }\n\n reject(new AxiosError('Request aborted', AxiosError.ECONNABORTED, config, request));\n\n // Clean up request\n request = null;\n };\n\n // Handle low level network errors\n request.onerror = function handleError() {\n // Real errors are hidden from us by the browser\n // onerror should only fire if it's a network error\n reject(new AxiosError('Network Error', AxiosError.ERR_NETWORK, config, request, request));\n\n // Clean up request\n request = null;\n };\n\n // Handle timeout\n request.ontimeout = function handleTimeout() {\n var timeoutErrorMessage = config.timeout ? 'timeout of ' + config.timeout + 'ms exceeded' : 'timeout exceeded';\n var transitional = config.transitional || transitionalDefaults;\n if (config.timeoutErrorMessage) {\n timeoutErrorMessage = config.timeoutErrorMessage;\n }\n reject(new AxiosError(\n timeoutErrorMessage,\n transitional.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED,\n config,\n request));\n\n // Clean up request\n request = null;\n };\n\n // Add xsrf header\n // This is only done if running in a standard browser environment.\n // Specifically not if we're in a web worker, or react-native.\n if (utils.isStandardBrowserEnv()) {\n // Add xsrf header\n var xsrfValue = (config.withCredentials || isURLSameOrigin(fullPath)) && config.xsrfCookieName ?\n cookies.read(config.xsrfCookieName) :\n undefined;\n\n if (xsrfValue) {\n requestHeaders[config.xsrfHeaderName] = xsrfValue;\n }\n }\n\n // Add headers to the request\n if ('setRequestHeader' in request) {\n utils.forEach(requestHeaders, function setRequestHeader(val, key) {\n if (typeof requestData === 'undefined' && key.toLowerCase() === 'content-type') {\n // Remove Content-Type if data is undefined\n delete requestHeaders[key];\n } else {\n // Otherwise add header to the request\n request.setRequestHeader(key, val);\n }\n });\n }\n\n // Add withCredentials to request if needed\n if (!utils.isUndefined(config.withCredentials)) {\n request.withCredentials = !!config.withCredentials;\n }\n\n // Add responseType to request if needed\n if (responseType && responseType !== 'json') {\n request.responseType = config.responseType;\n }\n\n // Handle progress if needed\n if (typeof config.onDownloadProgress === 'function') {\n request.addEventListener('progress', config.onDownloadProgress);\n }\n\n // Not all browsers support upload events\n if (typeof config.onUploadProgress === 'function' && request.upload) {\n request.upload.addEventListener('progress', config.onUploadProgress);\n }\n\n if (config.cancelToken || config.signal) {\n // Handle cancellation\n // eslint-disable-next-line func-names\n onCanceled = function(cancel) {\n if (!request) {\n return;\n }\n reject(!cancel || (cancel && cancel.type) ? new CanceledError() : cancel);\n request.abort();\n request = null;\n };\n\n config.cancelToken && config.cancelToken.subscribe(onCanceled);\n if (config.signal) {\n config.signal.aborted ? onCanceled() : config.signal.addEventListener('abort', onCanceled);\n }\n }\n\n if (!requestData) {\n requestData = null;\n }\n\n var protocol = parseProtocol(fullPath);\n\n if (protocol && [ 'http', 'https', 'file' ].indexOf(protocol) === -1) {\n reject(new AxiosError('Unsupported protocol ' + protocol + ':', AxiosError.ERR_BAD_REQUEST, config));\n return;\n }\n\n\n // Send the request\n request.send(requestData);\n });\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2FkYXB0ZXJzL3hoci5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixZQUFZLG1CQUFPLENBQUMscURBQVk7QUFDaEMsYUFBYSxtQkFBTyxDQUFDLGlFQUFrQjtBQUN2QyxjQUFjLG1CQUFPLENBQUMseUVBQXNCO0FBQzVDLGVBQWUsbUJBQU8sQ0FBQywyRUFBdUI7QUFDOUMsb0JBQW9CLG1CQUFPLENBQUMsNkVBQXVCO0FBQ25ELG1CQUFtQixtQkFBTyxDQUFDLG1GQUEyQjtBQUN0RCxzQkFBc0IsbUJBQU8sQ0FBQyx5RkFBOEI7QUFDNUQsMkJBQTJCLG1CQUFPLENBQUMsbUZBQTBCO0FBQzdELGlCQUFpQixtQkFBTyxDQUFDLHVFQUFvQjtBQUM3QyxvQkFBb0IsbUJBQU8sQ0FBQyxpRkFBeUI7QUFDckQsb0JBQW9CLG1CQUFPLENBQUMsbUZBQTBCOztBQUV0RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDZDQUE2QztBQUM3Qzs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBLE9BQU87O0FBRVA7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0EsR0FBRztBQUNIIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL2F4aW9zL2xpYi9hZGFwdGVycy94aHIuanM/MWE1YyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4vLi4vdXRpbHMnKTtcbnZhciBzZXR0bGUgPSByZXF1aXJlKCcuLy4uL2NvcmUvc2V0dGxlJyk7XG52YXIgY29va2llcyA9IHJlcXVpcmUoJy4vLi4vaGVscGVycy9jb29raWVzJyk7XG52YXIgYnVpbGRVUkwgPSByZXF1aXJlKCcuLy4uL2hlbHBlcnMvYnVpbGRVUkwnKTtcbnZhciBidWlsZEZ1bGxQYXRoID0gcmVxdWlyZSgnLi4vY29yZS9idWlsZEZ1bGxQYXRoJyk7XG52YXIgcGFyc2VIZWFkZXJzID0gcmVxdWlyZSgnLi8uLi9oZWxwZXJzL3BhcnNlSGVhZGVycycpO1xudmFyIGlzVVJMU2FtZU9yaWdpbiA9IHJlcXVpcmUoJy4vLi4vaGVscGVycy9pc1VSTFNhbWVPcmlnaW4nKTtcbnZhciB0cmFuc2l0aW9uYWxEZWZhdWx0cyA9IHJlcXVpcmUoJy4uL2RlZmF1bHRzL3RyYW5zaXRpb25hbCcpO1xudmFyIEF4aW9zRXJyb3IgPSByZXF1aXJlKCcuLi9jb3JlL0F4aW9zRXJyb3InKTtcbnZhciBDYW5jZWxlZEVycm9yID0gcmVxdWlyZSgnLi4vY2FuY2VsL0NhbmNlbGVkRXJyb3InKTtcbnZhciBwYXJzZVByb3RvY29sID0gcmVxdWlyZSgnLi4vaGVscGVycy9wYXJzZVByb3RvY29sJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24geGhyQWRhcHRlcihjb25maWcpIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uIGRpc3BhdGNoWGhyUmVxdWVzdChyZXNvbHZlLCByZWplY3QpIHtcbiAgICB2YXIgcmVxdWVzdERhdGEgPSBjb25maWcuZGF0YTtcbiAgICB2YXIgcmVxdWVzdEhlYWRlcnMgPSBjb25maWcuaGVhZGVycztcbiAgICB2YXIgcmVzcG9uc2VUeXBlID0gY29uZmlnLnJlc3BvbnNlVHlwZTtcbiAgICB2YXIgb25DYW5jZWxlZDtcbiAgICBmdW5jdGlvbiBkb25lKCkge1xuICAgICAgaWYgKGNvbmZpZy5jYW5jZWxUb2tlbikge1xuICAgICAgICBjb25maWcuY2FuY2VsVG9rZW4udW5zdWJzY3JpYmUob25DYW5jZWxlZCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChjb25maWcuc2lnbmFsKSB7XG4gICAgICAgIGNvbmZpZy5zaWduYWwucmVtb3ZlRXZlbnRMaXN0ZW5lcignYWJvcnQnLCBvbkNhbmNlbGVkKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodXRpbHMuaXNGb3JtRGF0YShyZXF1ZXN0RGF0YSkgJiYgdXRpbHMuaXNTdGFuZGFyZEJyb3dzZXJFbnYoKSkge1xuICAgICAgZGVsZXRlIHJlcXVlc3RIZWFkZXJzWydDb250ZW50LVR5cGUnXTsgLy8gTGV0IHRoZSBicm93c2VyIHNldCBpdFxuICAgIH1cblxuICAgIHZhciByZXF1ZXN0ID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG5cbiAgICAvLyBIVFRQIGJhc2ljIGF1dGhlbnRpY2F0aW9uXG4gICAgaWYgKGNvbmZpZy5hdXRoKSB7XG4gICAgICB2YXIgdXNlcm5hbWUgPSBjb25maWcuYXV0aC51c2VybmFtZSB8fCAnJztcbiAgICAgIHZhciBwYXNzd29yZCA9IGNvbmZpZy5hdXRoLnBhc3N3b3JkID8gdW5lc2NhcGUoZW5jb2RlVVJJQ29tcG9uZW50KGNvbmZpZy5hdXRoLnBhc3N3b3JkKSkgOiAnJztcbiAgICAgIHJlcXVlc3RIZWFkZXJzLkF1dGhvcml6YXRpb24gPSAnQmFzaWMgJyArIGJ0b2EodXNlcm5hbWUgKyAnOicgKyBwYXNzd29yZCk7XG4gICAgfVxuXG4gICAgdmFyIGZ1bGxQYXRoID0gYnVpbGRGdWxsUGF0aChjb25maWcuYmFzZVVSTCwgY29uZmlnLnVybCk7XG5cbiAgICByZXF1ZXN0Lm9wZW4oY29uZmlnLm1ldGhvZC50b1VwcGVyQ2FzZSgpLCBidWlsZFVSTChmdWxsUGF0aCwgY29uZmlnLnBhcmFtcywgY29uZmlnLnBhcmFtc1NlcmlhbGl6ZXIpLCB0cnVlKTtcblxuICAgIC8vIFNldCB0aGUgcmVxdWVzdCB0aW1lb3V0IGluIE1TXG4gICAgcmVxdWVzdC50aW1lb3V0ID0gY29uZmlnLnRpbWVvdXQ7XG5cbiAgICBmdW5jdGlvbiBvbmxvYWRlbmQoKSB7XG4gICAgICBpZiAoIXJlcXVlc3QpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgLy8gUHJlcGFyZSB0aGUgcmVzcG9uc2VcbiAgICAgIHZhciByZXNwb25zZUhlYWRlcnMgPSAnZ2V0QWxsUmVzcG9uc2VIZWFkZXJzJyBpbiByZXF1ZXN0ID8gcGFyc2VIZWFkZXJzKHJlcXVlc3QuZ2V0QWxsUmVzcG9uc2VIZWFkZXJzKCkpIDogbnVsbDtcbiAgICAgIHZhciByZXNwb25zZURhdGEgPSAhcmVzcG9uc2VUeXBlIHx8IHJlc3BvbnNlVHlwZSA9PT0gJ3RleHQnIHx8ICByZXNwb25zZVR5cGUgPT09ICdqc29uJyA/XG4gICAgICAgIHJlcXVlc3QucmVzcG9uc2VUZXh0IDogcmVxdWVzdC5yZXNwb25zZTtcbiAgICAgIHZhciByZXNwb25zZSA9IHtcbiAgICAgICAgZGF0YTogcmVzcG9uc2VEYXRhLFxuICAgICAgICBzdGF0dXM6IHJlcXVlc3Quc3RhdHVzLFxuICAgICAgICBzdGF0dXNUZXh0OiByZXF1ZXN0LnN0YXR1c1RleHQsXG4gICAgICAgIGhlYWRlcnM6IHJlc3BvbnNlSGVhZGVycyxcbiAgICAgICAgY29uZmlnOiBjb25maWcsXG4gICAgICAgIHJlcXVlc3Q6IHJlcXVlc3RcbiAgICAgIH07XG5cbiAgICAgIHNldHRsZShmdW5jdGlvbiBfcmVzb2x2ZSh2YWx1ZSkge1xuICAgICAgICByZXNvbHZlKHZhbHVlKTtcbiAgICAgICAgZG9uZSgpO1xuICAgICAgfSwgZnVuY3Rpb24gX3JlamVjdChlcnIpIHtcbiAgICAgICAgcmVqZWN0KGVycik7XG4gICAgICAgIGRvbmUoKTtcbiAgICAgIH0sIHJlc3BvbnNlKTtcblxuICAgICAgLy8gQ2xlYW4gdXAgcmVxdWVzdFxuICAgICAgcmVxdWVzdCA9IG51bGw7XG4gICAgfVxuXG4gICAgaWYgKCdvbmxvYWRlbmQnIGluIHJlcXVlc3QpIHtcbiAgICAgIC8vIFVzZSBvbmxvYWRlbmQgaWYgYXZhaWxhYmxlXG4gICAgICByZXF1ZXN0Lm9ubG9hZGVuZCA9IG9ubG9hZGVuZDtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gTGlzdGVuIGZvciByZWFkeSBzdGF0ZSB0byBlbXVsYXRlIG9ubG9hZGVuZFxuICAgICAgcmVxdWVzdC5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBmdW5jdGlvbiBoYW5kbGVMb2FkKCkge1xuICAgICAgICBpZiAoIXJlcXVlc3QgfHwgcmVxdWVzdC5yZWFkeVN0YXRlICE9PSA0KSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gVGhlIHJlcXVlc3QgZXJyb3JlZCBvdXQgYW5kIHdlIGRpZG4ndCBnZXQgYSByZXNwb25zZSwgdGhpcyB3aWxsIGJlXG4gICAgICAgIC8vIGhhbmRsZWQgYnkgb25lcnJvciBpbnN0ZWFkXG4gICAgICAgIC8vIFdpdGggb25lIGV4Y2VwdGlvbjogcmVxdWVzdCB0aGF0IHVzaW5nIGZpbGU6IHByb3RvY29sLCBtb3N0IGJyb3dzZXJzXG4gICAgICAgIC8vIHdpbGwgcmV0dXJuIHN0YXR1cyBhcyAwIGV2ZW4gdGhvdWdoIGl0J3MgYSBzdWNjZXNzZnVsIHJlcXVlc3RcbiAgICAgICAgaWYgKHJlcXVlc3Quc3RhdHVzID09PSAwICYmICEocmVxdWVzdC5yZXNwb25zZVVSTCAmJiByZXF1ZXN0LnJlc3BvbnNlVVJMLmluZGV4T2YoJ2ZpbGU6JykgPT09IDApKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIC8vIHJlYWR5c3RhdGUgaGFuZGxlciBpcyBjYWxsaW5nIGJlZm9yZSBvbmVycm9yIG9yIG9udGltZW91dCBoYW5kbGVycyxcbiAgICAgICAgLy8gc28gd2Ugc2hvdWxkIGNhbGwgb25sb2FkZW5kIG9uIHRoZSBuZXh0ICd0aWNrJ1xuICAgICAgICBzZXRUaW1lb3V0KG9ubG9hZGVuZCk7XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8vIEhhbmRsZSBicm93c2VyIHJlcXVlc3QgY2FuY2VsbGF0aW9uIChhcyBvcHBvc2VkIHRvIGEgbWFudWFsIGNhbmNlbGxhdGlvbilcbiAgICByZXF1ZXN0Lm9uYWJvcnQgPSBmdW5jdGlvbiBoYW5kbGVBYm9ydCgpIHtcbiAgICAgIGlmICghcmVxdWVzdCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHJlamVjdChuZXcgQXhpb3NFcnJvcignUmVxdWVzdCBhYm9ydGVkJywgQXhpb3NFcnJvci5FQ09OTkFCT1JURUQsIGNvbmZpZywgcmVxdWVzdCkpO1xuXG4gICAgICAvLyBDbGVhbiB1cCByZXF1ZXN0XG4gICAgICByZXF1ZXN0ID0gbnVsbDtcbiAgICB9O1xuXG4gICAgLy8gSGFuZGxlIGxvdyBsZXZlbCBuZXR3b3JrIGVycm9yc1xuICAgIHJlcXVlc3Qub25lcnJvciA9IGZ1bmN0aW9uIGhhbmRsZUVycm9yKCkge1xuICAgICAgLy8gUmVhbCBlcnJvcnMgYXJlIGhpZGRlbiBmcm9tIHVzIGJ5IHRoZSBicm93c2VyXG4gICAgICAvLyBvbmVycm9yIHNob3VsZCBvbmx5IGZpcmUgaWYgaXQncyBhIG5ldHdvcmsgZXJyb3JcbiAgICAgIHJlamVjdChuZXcgQXhpb3NFcnJvcignTmV0d29yayBFcnJvcicsIEF4aW9zRXJyb3IuRVJSX05FVFdPUkssIGNvbmZpZywgcmVxdWVzdCwgcmVxdWVzdCkpO1xuXG4gICAgICAvLyBDbGVhbiB1cCByZXF1ZXN0XG4gICAgICByZXF1ZXN0ID0gbnVsbDtcbiAgICB9O1xuXG4gICAgLy8gSGFuZGxlIHRpbWVvdXRcbiAgICByZXF1ZXN0Lm9udGltZW91dCA9IGZ1bmN0aW9uIGhhbmRsZVRpbWVvdXQoKSB7XG4gICAgICB2YXIgdGltZW91dEVycm9yTWVzc2FnZSA9IGNvbmZpZy50aW1lb3V0ID8gJ3RpbWVvdXQgb2YgJyArIGNvbmZpZy50aW1lb3V0ICsgJ21zIGV4Y2VlZGVkJyA6ICd0aW1lb3V0IGV4Y2VlZGVkJztcbiAgICAgIHZhciB0cmFuc2l0aW9uYWwgPSBjb25maWcudHJhbnNpdGlvbmFsIHx8IHRyYW5zaXRpb25hbERlZmF1bHRzO1xuICAgICAgaWYgKGNvbmZpZy50aW1lb3V0RXJyb3JNZXNzYWdlKSB7XG4gICAgICAgIHRpbWVvdXRFcnJvck1lc3NhZ2UgPSBjb25maWcudGltZW91dEVycm9yTWVzc2FnZTtcbiAgICAgIH1cbiAgICAgIHJlamVjdChuZXcgQXhpb3NFcnJvcihcbiAgICAgICAgdGltZW91dEVycm9yTWVzc2FnZSxcbiAgICAgICAgdHJhbnNpdGlvbmFsLmNsYXJpZnlUaW1lb3V0RXJyb3IgPyBBeGlvc0Vycm9yLkVUSU1FRE9VVCA6IEF4aW9zRXJyb3IuRUNPTk5BQk9SVEVELFxuICAgICAgICBjb25maWcsXG4gICAgICAgIHJlcXVlc3QpKTtcblxuICAgICAgLy8gQ2xlYW4gdXAgcmVxdWVzdFxuICAgICAgcmVxdWVzdCA9IG51bGw7XG4gICAgfTtcblxuICAgIC8vIEFkZCB4c3JmIGhlYWRlclxuICAgIC8vIFRoaXMgaXMgb25seSBkb25lIGlmIHJ1bm5pbmcgaW4gYSBzdGFuZGFyZCBicm93c2VyIGVudmlyb25tZW50LlxuICAgIC8vIFNwZWNpZmljYWxseSBub3QgaWYgd2UncmUgaW4gYSB3ZWIgd29ya2VyLCBvciByZWFjdC1uYXRpdmUuXG4gICAgaWYgKHV0aWxzLmlzU3RhbmRhcmRCcm93c2VyRW52KCkpIHtcbiAgICAgIC8vIEFkZCB4c3JmIGhlYWRlclxuICAgICAgdmFyIHhzcmZWYWx1ZSA9IChjb25maWcud2l0aENyZWRlbnRpYWxzIHx8IGlzVVJMU2FtZU9yaWdpbihmdWxsUGF0aCkpICYmIGNvbmZpZy54c3JmQ29va2llTmFtZSA/XG4gICAgICAgIGNvb2tpZXMucmVhZChjb25maWcueHNyZkNvb2tpZU5hbWUpIDpcbiAgICAgICAgdW5kZWZpbmVkO1xuXG4gICAgICBpZiAoeHNyZlZhbHVlKSB7XG4gICAgICAgIHJlcXVlc3RIZWFkZXJzW2NvbmZpZy54c3JmSGVhZGVyTmFtZV0gPSB4c3JmVmFsdWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQWRkIGhlYWRlcnMgdG8gdGhlIHJlcXVlc3RcbiAgICBpZiAoJ3NldFJlcXVlc3RIZWFkZXInIGluIHJlcXVlc3QpIHtcbiAgICAgIHV0aWxzLmZvckVhY2gocmVxdWVzdEhlYWRlcnMsIGZ1bmN0aW9uIHNldFJlcXVlc3RIZWFkZXIodmFsLCBrZXkpIHtcbiAgICAgICAgaWYgKHR5cGVvZiByZXF1ZXN0RGF0YSA9PT0gJ3VuZGVmaW5lZCcgJiYga2V5LnRvTG93ZXJDYXNlKCkgPT09ICdjb250ZW50LXR5cGUnKSB7XG4gICAgICAgICAgLy8gUmVtb3ZlIENvbnRlbnQtVHlwZSBpZiBkYXRhIGlzIHVuZGVmaW5lZFxuICAgICAgICAgIGRlbGV0ZSByZXF1ZXN0SGVhZGVyc1trZXldO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIE90aGVyd2lzZSBhZGQgaGVhZGVyIHRvIHRoZSByZXF1ZXN0XG4gICAgICAgICAgcmVxdWVzdC5zZXRSZXF1ZXN0SGVhZGVyKGtleSwgdmFsKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gQWRkIHdpdGhDcmVkZW50aWFscyB0byByZXF1ZXN0IGlmIG5lZWRlZFxuICAgIGlmICghdXRpbHMuaXNVbmRlZmluZWQoY29uZmlnLndpdGhDcmVkZW50aWFscykpIHtcbiAgICAgIHJlcXVlc3Qud2l0aENyZWRlbnRpYWxzID0gISFjb25maWcud2l0aENyZWRlbnRpYWxzO1xuICAgIH1cblxuICAgIC8vIEFkZCByZXNwb25zZVR5cGUgdG8gcmVxdWVzdCBpZiBuZWVkZWRcbiAgICBpZiAocmVzcG9uc2VUeXBlICYmIHJlc3BvbnNlVHlwZSAhPT0gJ2pzb24nKSB7XG4gICAgICByZXF1ZXN0LnJlc3BvbnNlVHlwZSA9IGNvbmZpZy5yZXNwb25zZVR5cGU7XG4gICAgfVxuXG4gICAgLy8gSGFuZGxlIHByb2dyZXNzIGlmIG5lZWRlZFxuICAgIGlmICh0eXBlb2YgY29uZmlnLm9uRG93bmxvYWRQcm9ncmVzcyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcmVxdWVzdC5hZGRFdmVudExpc3RlbmVyKCdwcm9ncmVzcycsIGNvbmZpZy5vbkRvd25sb2FkUHJvZ3Jlc3MpO1xuICAgIH1cblxuICAgIC8vIE5vdCBhbGwgYnJvd3NlcnMgc3VwcG9ydCB1cGxvYWQgZXZlbnRzXG4gICAgaWYgKHR5cGVvZiBjb25maWcub25VcGxvYWRQcm9ncmVzcyA9PT0gJ2Z1bmN0aW9uJyAmJiByZXF1ZXN0LnVwbG9hZCkge1xuICAgICAgcmVxdWVzdC51cGxvYWQuYWRkRXZlbnRMaXN0ZW5lcigncHJvZ3Jlc3MnLCBjb25maWcub25VcGxvYWRQcm9ncmVzcyk7XG4gICAgfVxuXG4gICAgaWYgKGNvbmZpZy5jYW5jZWxUb2tlbiB8fCBjb25maWcuc2lnbmFsKSB7XG4gICAgICAvLyBIYW5kbGUgY2FuY2VsbGF0aW9uXG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZnVuYy1uYW1lc1xuICAgICAgb25DYW5jZWxlZCA9IGZ1bmN0aW9uKGNhbmNlbCkge1xuICAgICAgICBpZiAoIXJlcXVlc3QpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgcmVqZWN0KCFjYW5jZWwgfHwgKGNhbmNlbCAmJiBjYW5jZWwudHlwZSkgPyBuZXcgQ2FuY2VsZWRFcnJvcigpIDogY2FuY2VsKTtcbiAgICAgICAgcmVxdWVzdC5hYm9ydCgpO1xuICAgICAgICByZXF1ZXN0ID0gbnVsbDtcbiAgICAgIH07XG5cbiAgICAgIGNvbmZpZy5jYW5jZWxUb2tlbiAmJiBjb25maWcuY2FuY2VsVG9rZW4uc3Vic2NyaWJlKG9uQ2FuY2VsZWQpO1xuICAgICAgaWYgKGNvbmZpZy5zaWduYWwpIHtcbiAgICAgICAgY29uZmlnLnNpZ25hbC5hYm9ydGVkID8gb25DYW5jZWxlZCgpIDogY29uZmlnLnNpZ25hbC5hZGRFdmVudExpc3RlbmVyKCdhYm9ydCcsIG9uQ2FuY2VsZWQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghcmVxdWVzdERhdGEpIHtcbiAgICAgIHJlcXVlc3REYXRhID0gbnVsbDtcbiAgICB9XG5cbiAgICB2YXIgcHJvdG9jb2wgPSBwYXJzZVByb3RvY29sKGZ1bGxQYXRoKTtcblxuICAgIGlmIChwcm90b2NvbCAmJiBbICdodHRwJywgJ2h0dHBzJywgJ2ZpbGUnIF0uaW5kZXhPZihwcm90b2NvbCkgPT09IC0xKSB7XG4gICAgICByZWplY3QobmV3IEF4aW9zRXJyb3IoJ1Vuc3VwcG9ydGVkIHByb3RvY29sICcgKyBwcm90b2NvbCArICc6JywgQXhpb3NFcnJvci5FUlJfQkFEX1JFUVVFU1QsIGNvbmZpZykpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuXG4gICAgLy8gU2VuZCB0aGUgcmVxdWVzdFxuICAgIHJlcXVlc3Quc2VuZChyZXF1ZXN0RGF0YSk7XG4gIH0pO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/axios/lib/adapters/xhr.js\n");
/***/ }),
/***/ "./node_modules/axios/lib/axios.js":
/*!*****************************************!*\
!*** ./node_modules/axios/lib/axios.js ***!
\*****************************************/
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict";
eval("\n\nvar utils = __webpack_require__(/*! ./utils */ \"./node_modules/axios/lib/utils.js\");\nvar bind = __webpack_require__(/*! ./helpers/bind */ \"./node_modules/axios/lib/helpers/bind.js\");\nvar Axios = __webpack_require__(/*! ./core/Axios */ \"./node_modules/axios/lib/core/Axios.js\");\nvar mergeConfig = __webpack_require__(/*! ./core/mergeConfig */ \"./node_modules/axios/lib/core/mergeConfig.js\");\nvar defaults = __webpack_require__(/*! ./defaults */ \"./node_modules/axios/lib/defaults/index.js\");\n\n/**\n * Create an instance of Axios\n *\n * @param {Object} defaultConfig The default config for the instance\n * @return {Axios} A new instance of Axios\n */\nfunction createInstance(defaultConfig) {\n var context = new Axios(defaultConfig);\n var instance = bind(Axios.prototype.request, context);\n\n // Copy axios.prototype to instance\n utils.extend(instance, Axios.prototype, context);\n\n // Copy context to instance\n utils.extend(instance, context);\n\n // Factory for creating new instances\n instance.create = function create(instanceConfig) {\n return createInstance(mergeConfig(defaultConfig, instanceConfig));\n };\n\n return instance;\n}\n\n// Create the default instance to be exported\nvar axios = createInstance(defaults);\n\n// Expose Axios class to allow class inheritance\naxios.Axios = Axios;\n\n// Expose Cancel & CancelToken\naxios.CanceledError = __webpack_require__(/*! ./cancel/CanceledError */ \"./node_modules/axios/lib/cancel/CanceledError.js\");\naxios.CancelToken = __webpack_require__(/*! ./cancel/CancelToken */ \"./node_modules/axios/lib/cancel/CancelToken.js\");\naxios.isCancel = __webpack_require__(/*! ./cancel/isCancel */ \"./node_modules/axios/lib/cancel/isCancel.js\");\naxios.VERSION = (__webpack_require__(/*! ./env/data */ \"./node_modules/axios/lib/env/data.js\").version);\naxios.toFormData = __webpack_require__(/*! ./helpers/toFormData */ \"./node_modules/axios/lib/helpers/toFormData.js\");\n\n// Expose AxiosError class\naxios.AxiosError = __webpack_require__(/*! ../lib/core/AxiosError */ \"./node_modules/axios/lib/core/AxiosError.js\");\n\n// alias for CanceledError for backward compatibility\naxios.Cancel = axios.CanceledError;\n\n// Expose all/spread\naxios.all = function all(promises) {\n return Promise.all(promises);\n};\naxios.spread = __webpack_require__(/*! ./helpers/spread */ \"./node_modules/axios/lib/helpers/spread.js\");\n\n// Expose isAxiosError\naxios.isAxiosError = __webpack_require__(/*! ./helpers/isAxiosError */ \"./node_modules/axios/lib/helpers/isAxiosError.js\");\n\nmodule.exports = axios;\n\n// Allow use of default import syntax in TypeScript\nmodule.exports[\"default\"] = axios;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2F4aW9zLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLFlBQVksbUJBQU8sQ0FBQyxrREFBUztBQUM3QixXQUFXLG1CQUFPLENBQUMsZ0VBQWdCO0FBQ25DLFlBQVksbUJBQU8sQ0FBQyw0REFBYztBQUNsQyxrQkFBa0IsbUJBQU8sQ0FBQyx3RUFBb0I7QUFDOUMsZUFBZSxtQkFBTyxDQUFDLDhEQUFZOztBQUVuQztBQUNBO0FBQ0E7QUFDQSxXQUFXLFFBQVE7QUFDbkIsWUFBWSxPQUFPO0FBQ25CO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLHNCQUFzQixtQkFBTyxDQUFDLGdGQUF3QjtBQUN0RCxvQkFBb0IsbUJBQU8sQ0FBQyw0RUFBc0I7QUFDbEQsaUJBQWlCLG1CQUFPLENBQUMsc0VBQW1CO0FBQzVDLGdCQUFnQix1RkFBNkI7QUFDN0MsbUJBQW1CLG1CQUFPLENBQUMsNEVBQXNCOztBQUVqRDtBQUNBLG1CQUFtQixtQkFBTyxDQUFDLDJFQUF3Qjs7QUFFbkQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsbUJBQU8sQ0FBQyxvRUFBa0I7O0FBRXpDO0FBQ0EscUJBQXFCLG1CQUFPLENBQUMsZ0ZBQXdCOztBQUVyRDs7QUFFQTtBQUNBLHlCQUFzQiIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9heGlvcy9saWIvYXhpb3MuanM/ZmFkNiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4vdXRpbHMnKTtcbnZhciBiaW5kID0gcmVxdWlyZSgnLi9oZWxwZXJzL2JpbmQnKTtcbnZhciBBeGlvcyA9IHJlcXVpcmUoJy4vY29yZS9BeGlvcycpO1xudmFyIG1lcmdlQ29uZmlnID0gcmVxdWlyZSgnLi9jb3JlL21lcmdlQ29uZmlnJyk7XG52YXIgZGVmYXVsdHMgPSByZXF1aXJlKCcuL2RlZmF1bHRzJyk7XG5cbi8qKlxuICogQ3JlYXRlIGFuIGluc3RhbmNlIG9mIEF4aW9zXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGRlZmF1bHRDb25maWcgVGhlIGRlZmF1bHQgY29uZmlnIGZvciB0aGUgaW5zdGFuY2VcbiAqIEByZXR1cm4ge0F4aW9zfSBBIG5ldyBpbnN0YW5jZSBvZiBBeGlvc1xuICovXG5mdW5jdGlvbiBjcmVhdGVJbnN0YW5jZShkZWZhdWx0Q29uZmlnKSB7XG4gIHZhciBjb250ZXh0ID0gbmV3IEF4aW9zKGRlZmF1bHRDb25maWcpO1xuICB2YXIgaW5zdGFuY2UgPSBiaW5kKEF4aW9zLnByb3RvdHlwZS5yZXF1ZXN0LCBjb250ZXh0KTtcblxuICAvLyBDb3B5IGF4aW9zLnByb3RvdHlwZSB0byBpbnN0YW5jZVxuICB1dGlscy5leHRlbmQoaW5zdGFuY2UsIEF4aW9zLnByb3RvdHlwZSwgY29udGV4dCk7XG5cbiAgLy8gQ29weSBjb250ZXh0IHRvIGluc3RhbmNlXG4gIHV0aWxzLmV4dGVuZChpbnN0YW5jZSwgY29udGV4dCk7XG5cbiAgLy8gRmFjdG9yeSBmb3IgY3JlYXRpbmcgbmV3IGluc3RhbmNlc1xuICBpbnN0YW5jZS5jcmVhdGUgPSBmdW5jdGlvbiBjcmVhdGUoaW5zdGFuY2VDb25maWcpIHtcbiAgICByZXR1cm4gY3JlYXRlSW5zdGFuY2UobWVyZ2VDb25maWcoZGVmYXVsdENvbmZpZywgaW5zdGFuY2VDb25maWcpKTtcbiAgfTtcblxuICByZXR1cm4gaW5zdGFuY2U7XG59XG5cbi8vIENyZWF0ZSB0aGUgZGVmYXVsdCBpbnN0YW5jZSB0byBiZSBleHBvcnRlZFxudmFyIGF4aW9zID0gY3JlYXRlSW5zdGFuY2UoZGVmYXVsdHMpO1xuXG4vLyBFeHBvc2UgQXhpb3MgY2xhc3MgdG8gYWxsb3cgY2xhc3MgaW5oZXJpdGFuY2VcbmF4aW9zLkF4aW9zID0gQXhpb3M7XG5cbi8vIEV4cG9zZSBDYW5jZWwgJiBDYW5jZWxUb2tlblxuYXhpb3MuQ2FuY2VsZWRFcnJvciA9IHJlcXVpcmUoJy4vY2FuY2VsL0NhbmNlbGVkRXJyb3InKTtcbmF4aW9zLkNhbmNlbFRva2VuID0gcmVxdWlyZSgnLi9jYW5jZWwvQ2FuY2VsVG9rZW4nKTtcbmF4aW9zLmlzQ2FuY2VsID0gcmVxdWlyZSgnLi9jYW5jZWwvaXNDYW5jZWwnKTtcbmF4aW9zLlZFUlNJT04gPSByZXF1aXJlKCcuL2Vudi9kYXRhJykudmVyc2lvbjtcbmF4aW9zLnRvRm9ybURhdGEgPSByZXF1aXJlKCcuL2hlbHBlcnMvdG9Gb3JtRGF0YScpO1xuXG4vLyBFeHBvc2UgQXhpb3NFcnJvciBjbGFzc1xuYXhpb3MuQXhpb3NFcnJvciA9IHJlcXVpcmUoJy4uL2xpYi9jb3JlL0F4aW9zRXJyb3InKTtcblxuLy8gYWxpYXMgZm9yIENhbmNlbGVkRXJyb3IgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHlcbmF4aW9zLkNhbmNlbCA9IGF4aW9zLkNhbmNlbGVkRXJyb3I7XG5cbi8vIEV4cG9zZSBhbGwvc3ByZWFkXG5heGlvcy5hbGwgPSBmdW5jdGlvbiBhbGwocHJvbWlzZXMpIHtcbiAgcmV0dXJuIFByb21pc2UuYWxsKHByb21pc2VzKTtcbn07XG5heGlvcy5zcHJlYWQgPSByZXF1aXJlKCcuL2hlbHBlcnMvc3ByZWFkJyk7XG5cbi8vIEV4cG9zZSBpc0F4aW9zRXJyb3JcbmF4aW9zLmlzQXhpb3NFcnJvciA9IHJlcXVpcmUoJy4vaGVscGVycy9pc0F4aW9zRXJyb3InKTtcblxubW9kdWxlLmV4cG9ydHMgPSBheGlvcztcblxuLy8gQWxsb3cgdXNlIG9mIGRlZmF1bHQgaW1wb3J0IHN5bnRheCBpbiBUeXBlU2NyaXB0XG5tb2R1bGUuZXhwb3J0cy5kZWZhdWx0ID0gYXhpb3M7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/axios/lib/axios.js\n");
/***/ }),
/***/ "./node_modules/axios/lib/cancel/CancelToken.js":
/*!******************************************************!*\
!*** ./node_modules/axios/lib/cancel/CancelToken.js ***!
\******************************************************/
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict";
eval("\n\nvar CanceledError = __webpack_require__(/*! ./CanceledError */ \"./node_modules/axios/lib/cancel/CanceledError.js\");\n\n/**\n * A `CancelToken` is an object that can be used to request cancellation of an operation.\n *\n * @class\n * @param {Function} executor The executor function.\n */\nfunction CancelToken(executor) {\n if (typeof executor !== 'function') {\n throw new TypeError('executor must be a function.');\n }\n\n var resolvePromise;\n\n this.promise = new Promise(function promiseExecutor(resolve) {\n resolvePromise = resolve;\n });\n\n var token = this;\n\n // eslint-disable-next-line func-names\n this.promise.then(function(cancel) {\n if (!token._listeners) return;\n\n var i;\n var l = token._listeners.length;\n\n for (i = 0; i < l; i++) {\n token._listeners[i](cancel);\n }\n token._listeners = null;\n });\n\n // eslint-disable-next-line func-names\n this.promise.then = function(onfulfilled) {\n var _resolve;\n // eslint-disable-next-line func-names\n var promise = new Promise(function(resolve) {\n token.subscribe(resolve);\n _resolve = resolve;\n }).then(onfulfilled);\n\n promise.cancel = function reject() {\n token.unsubscribe(_resolve);\n };\n\n return promise;\n };\n\n executor(function cancel(message) {\n if (token.reason) {\n // Cancellation has already been requested\n return;\n }\n\n token.reason = new CanceledError(message);\n resolvePromise(token.reason);\n });\n}\n\n/**\n * Throws a `CanceledError` if cancellation has been requested.\n */\nCancelToken.prototype.throwIfRequested = function throwIfRequested() {\n if (this.reason) {\n throw this.reason;\n }\n};\n\n/**\n * Subscribe to the cancel signal\n */\n\nCancelToken.prototype.subscribe = function subscribe(listener) {\n if (this.reason) {\n listener(this.reason);\n return;\n }\n\n if (this._listeners) {\n this._listeners.push(listener);\n } else {\n this._listeners = [listener];\n }\n};\n\n/**\n * Unsubscribe from the cancel signal\n */\n\nCancelToken.prototype.unsubscribe = function unsubscribe(listener) {\n if (!this._listeners) {\n return;\n }\n var index = this._listeners.indexOf(listener);\n if (index !== -1) {\n this._listeners.splice(index, 1);\n }\n};\n\n/**\n * Returns an object that contains a new `CancelToken` and a function that, when called,\n * cancels the `CancelToken`.\n */\nCancelToken.source = function source() {\n var cancel;\n var token = new CancelToken(function executor(c) {\n cancel = c;\n });\n return {\n token: token,\n cancel: cancel\n };\n};\n\nmodule.exports = CancelToken;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2NhbmNlbC9DYW5jZWxUb2tlbi5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixvQkFBb0IsbUJBQU8sQ0FBQyx5RUFBaUI7O0FBRTdDO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxVQUFVO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLEdBQUc7O0FBRUg7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsZ0JBQWdCLE9BQU87QUFDdkI7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2NhbmNlbC9DYW5jZWxUb2tlbi5qcz83MmM4Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIENhbmNlbGVkRXJyb3IgPSByZXF1aXJlKCcuL0NhbmNlbGVkRXJyb3InKTtcblxuLyoqXG4gKiBBIGBDYW5jZWxUb2tlbmAgaXMgYW4gb2JqZWN0IHRoYXQgY2FuIGJlIHVzZWQgdG8gcmVxdWVzdCBjYW5jZWxsYXRpb24gb2YgYW4gb3BlcmF0aW9uLlxuICpcbiAqIEBjbGFzc1xuICogQHBhcmFtIHtGdW5jdGlvbn0gZXhlY3V0b3IgVGhlIGV4ZWN1dG9yIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBDYW5jZWxUb2tlbihleGVjdXRvcikge1xuICBpZiAodHlwZW9mIGV4ZWN1dG9yICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcignZXhlY3V0b3IgbXVzdCBiZSBhIGZ1bmN0aW9uLicpO1xuICB9XG5cbiAgdmFyIHJlc29sdmVQcm9taXNlO1xuXG4gIHRoaXMucHJvbWlzZSA9IG5ldyBQcm9taXNlKGZ1bmN0aW9uIHByb21pc2VFeGVjdXRvcihyZXNvbHZlKSB7XG4gICAgcmVzb2x2ZVByb21pc2UgPSByZXNvbHZlO1xuICB9KTtcblxuICB2YXIgdG9rZW4gPSB0aGlzO1xuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBmdW5jLW5hbWVzXG4gIHRoaXMucHJvbWlzZS50aGVuKGZ1bmN0aW9uKGNhbmNlbCkge1xuICAgIGlmICghdG9rZW4uX2xpc3RlbmVycykgcmV0dXJuO1xuXG4gICAgdmFyIGk7XG4gICAgdmFyIGwgPSB0b2tlbi5fbGlzdGVuZXJzLmxlbmd0aDtcblxuICAgIGZvciAoaSA9IDA7IGkgPCBsOyBpKyspIHtcbiAgICAgIHRva2VuLl9saXN0ZW5lcnNbaV0oY2FuY2VsKTtcbiAgICB9XG4gICAgdG9rZW4uX2xpc3RlbmVycyA9IG51bGw7XG4gIH0pO1xuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBmdW5jLW5hbWVzXG4gIHRoaXMucHJvbWlzZS50aGVuID0gZnVuY3Rpb24ob25mdWxmaWxsZWQpIHtcbiAgICB2YXIgX3Jlc29sdmU7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGZ1bmMtbmFtZXNcbiAgICB2YXIgcHJvbWlzZSA9IG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUpIHtcbiAgICAgIHRva2VuLnN1YnNjcmliZShyZXNvbHZlKTtcbiAgICAgIF9yZXNvbHZlID0gcmVzb2x2ZTtcbiAgICB9KS50aGVuKG9uZnVsZmlsbGVkKTtcblxuICAgIHByb21pc2UuY2FuY2VsID0gZnVuY3Rpb24gcmVqZWN0KCkge1xuICAgICAgdG9rZW4udW5zdWJzY3JpYmUoX3Jlc29sdmUpO1xuICAgIH07XG5cbiAgICByZXR1cm4gcHJvbWlzZTtcbiAgfTtcblxuICBleGVjdXRvcihmdW5jdGlvbiBjYW5jZWwobWVzc2FnZSkge1xuICAgIGlmICh0b2tlbi5yZWFzb24pIHtcbiAgICAgIC8vIENhbmNlbGxhdGlvbiBoYXMgYWxyZWFkeSBiZWVuIHJlcXVlc3RlZFxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRva2VuLnJlYXNvbiA9IG5ldyBDYW5jZWxlZEVycm9yKG1lc3NhZ2UpO1xuICAgIHJlc29sdmVQcm9taXNlKHRva2VuLnJlYXNvbik7XG4gIH0pO1xufVxuXG4vKipcbiAqIFRocm93cyBhIGBDYW5jZWxlZEVycm9yYCBpZiBjYW5jZWxsYXRpb24gaGFzIGJlZW4gcmVxdWVzdGVkLlxuICovXG5DYW5jZWxUb2tlbi5wcm90b3R5cGUudGhyb3dJZlJlcXVlc3RlZCA9IGZ1bmN0aW9uIHRocm93SWZSZXF1ZXN0ZWQoKSB7XG4gIGlmICh0aGlzLnJlYXNvbikge1xuICAgIHRocm93IHRoaXMucmVhc29uO1xuICB9XG59O1xuXG4vKipcbiAqIFN1YnNjcmliZSB0byB0aGUgY2FuY2VsIHNpZ25hbFxuICovXG5cbkNhbmNlbFRva2VuLnByb3RvdHlwZS5zdWJzY3JpYmUgPSBmdW5jdGlvbiBzdWJzY3JpYmUobGlzdGVuZXIpIHtcbiAgaWYgKHRoaXMucmVhc29uKSB7XG4gICAgbGlzdGVuZXIodGhpcy5yZWFzb24pO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmICh0aGlzLl9saXN0ZW5lcnMpIHtcbiAgICB0aGlzLl9saXN0ZW5lcnMucHVzaChsaXN0ZW5lcik7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5fbGlzdGVuZXJzID0gW2xpc3RlbmVyXTtcbiAgfVxufTtcblxuLyoqXG4gKiBVbnN1YnNjcmliZSBmcm9tIHRoZSBjYW5jZWwgc2lnbmFsXG4gKi9cblxuQ2FuY2VsVG9rZW4ucHJvdG90eXBlLnVuc3Vic2NyaWJlID0gZnVuY3Rpb24gdW5zdWJzY3JpYmUobGlzdGVuZXIpIHtcbiAgaWYgKCF0aGlzLl9saXN0ZW5lcnMpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgdmFyIGluZGV4ID0gdGhpcy5fbGlzdGVuZXJzLmluZGV4T2YobGlzdGVuZXIpO1xuICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgdGhpcy5fbGlzdGVuZXJzLnNwbGljZShpbmRleCwgMSk7XG4gIH1cbn07XG5cbi8qKlxuICogUmV0dXJucyBhbiBvYmplY3QgdGhhdCBjb250YWlucyBhIG5ldyBgQ2FuY2VsVG9rZW5gIGFuZCBhIGZ1bmN0aW9uIHRoYXQsIHdoZW4gY2FsbGVkLFxuICogY2FuY2VscyB0aGUgYENhbmNlbFRva2VuYC5cbiAqL1xuQ2FuY2VsVG9rZW4uc291cmNlID0gZnVuY3Rpb24gc291cmNlKCkge1xuICB2YXIgY2FuY2VsO1xuICB2YXIgdG9rZW4gPSBuZXcgQ2FuY2VsVG9rZW4oZnVuY3Rpb24gZXhlY3V0b3IoYykge1xuICAgIGNhbmNlbCA9IGM7XG4gIH0pO1xuICByZXR1cm4ge1xuICAgIHRva2VuOiB0b2tlbixcbiAgICBjYW5jZWw6IGNhbmNlbFxuICB9O1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBDYW5jZWxUb2tlbjtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/axios/lib/cancel/CancelToken.js\n");
/***/ }),
/***/ "./node_modules/axios/lib/cancel/CanceledError.js":
/*!********************************************************!*\
!*** ./node_modules/axios/lib/cancel/CanceledError.js ***!
\********************************************************/
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict";
eval("\n\nvar AxiosError = __webpack_require__(/*! ../core/AxiosError */ \"./node_modules/axios/lib/core/AxiosError.js\");\nvar utils = __webpack_require__(/*! ../utils */ \"./node_modules/axios/lib/utils.js\");\n\n/**\n * A `CanceledError` is an object that is thrown when an operation is canceled.\n *\n * @class\n * @param {string=} message The message.\n */\nfunction CanceledError(message) {\n // eslint-disable-next-line no-eq-null,eqeqeq\n AxiosError.call(this, message == null ? 'canceled' : message, AxiosError.ERR_CANCELED);\n this.name = 'CanceledError';\n}\n\nutils.inherits(CanceledError, AxiosError, {\n __CANCEL__: true\n});\n\nmodule.exports = CanceledError;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2NhbmNlbC9DYW5jZWxlZEVycm9yLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLGlCQUFpQixtQkFBTyxDQUFDLHVFQUFvQjtBQUM3QyxZQUFZLG1CQUFPLENBQUMsbURBQVU7O0FBRTlCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxTQUFTO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRCIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9heGlvcy9saWIvY2FuY2VsL0NhbmNlbGVkRXJyb3IuanM/NjhhNCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBBeGlvc0Vycm9yID0gcmVxdWlyZSgnLi4vY29yZS9BeGlvc0Vycm9yJyk7XG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpO1xuXG4vKipcbiAqIEEgYENhbmNlbGVkRXJyb3JgIGlzIGFuIG9iamVjdCB0aGF0IGlzIHRocm93biB3aGVuIGFuIG9wZXJhdGlvbiBpcyBjYW5jZWxlZC5cbiAqXG4gKiBAY2xhc3NcbiAqIEBwYXJhbSB7c3RyaW5nPX0gbWVzc2FnZSBUaGUgbWVzc2FnZS5cbiAqL1xuZnVuY3Rpb24gQ2FuY2VsZWRFcnJvcihtZXNzYWdlKSB7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1lcS1udWxsLGVxZXFlcVxuICBBeGlvc0Vycm9yLmNhbGwodGhpcywgbWVzc2FnZSA9PSBudWxsID8gJ2NhbmNlbGVkJyA6IG1lc3NhZ2UsIEF4aW9zRXJyb3IuRVJSX0NBTkNFTEVEKTtcbiAgdGhpcy5uYW1lID0gJ0NhbmNlbGVkRXJyb3InO1xufVxuXG51dGlscy5pbmhlcml0cyhDYW5jZWxlZEVycm9yLCBBeGlvc0Vycm9yLCB7XG4gIF9fQ0FOQ0VMX186IHRydWVcbn0pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IENhbmNlbGVkRXJyb3I7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/axios/lib/cancel/CanceledError.js\n");
/***/ }),
/***/ "./node_modules/axios/lib/cancel/isCancel.js":
/*!***************************************************!*\
!*** ./node_modules/axios/lib/cancel/isCancel.js ***!
\***************************************************/
/***/ ((module) => {
"use strict";
eval("\n\nmodule.exports = function isCancel(value) {\n return !!(value && value.__CANCEL__);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2NhbmNlbC9pc0NhbmNlbC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2NhbmNlbC9pc0NhbmNlbC5qcz9jMTdhIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpc0NhbmNlbCh2YWx1ZSkge1xuICByZXR1cm4gISEodmFsdWUgJiYgdmFsdWUuX19DQU5DRUxfXyk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/axios/lib/cancel/isCancel.js\n");
/***/ }),
/***/ "./node_modules/axios/lib/core/Axios.js":
/*!**********************************************!*\
!*** ./node_modules/axios/lib/core/Axios.js ***!
\**********************************************/
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict";
eval("\n\nvar utils = __webpack_require__(/*! ./../utils */ \"./node_modules/axios/lib/utils.js\");\nvar buildURL = __webpack_require__(/*! ../helpers/buildURL */ \"./node_modules/axios/lib/helpers/buildURL.js\");\nvar InterceptorManager = __webpack_require__(/*! ./InterceptorManager */ \"./node_modules/axios/lib/core/InterceptorManager.js\");\nvar dispatchRequest = __webpack_require__(/*! ./dispatchRequest */ \"./node_modules/axios/lib/core/dispatchRequest.js\");\nvar mergeConfig = __webpack_require__(/*! ./mergeConfig */ \"./node_modules/axios/lib/core/mergeConfig.js\");\nvar buildFullPath = __webpack_require__(/*! ./buildFullPath */ \"./node_modules/axios/lib/core/buildFullPath.js\");\nvar validator = __webpack_require__(/*! ../helpers/validator */ \"./node_modules/axios/lib/helpers/validator.js\");\n\nvar validators = validator.validators;\n/**\n * Create a new instance of Axios\n *\n * @param {Object} instanceConfig The default config for the instance\n */\nfunction Axios(instanceConfig) {\n this.defaults = instanceConfig;\n this.interceptors = {\n request: new InterceptorManager(),\n response: new InterceptorManager()\n };\n}\n\n/**\n * Dispatch a request\n *\n * @param {Object} config The config specific for this request (merged with this.defaults)\n */\nAxios.prototype.request = function request(configOrUrl, config) {\n /*eslint no-param-reassign:0*/\n // Allow for axios('example/url'[, config]) a la fetch API\n if (typeof configOrUrl === 'string') {\n config = config || {};\n config.url = configOrUrl;\n } else {\n config = configOrUrl || {};\n }\n\n config = mergeConfig(this.defaults, config);\n\n // Set config.method\n if (config.method) {\n config.method = config.method.toLowerCase();\n } else if (this.defaults.method) {\n config.method = this.defaults.method.toLowerCase();\n } else {\n config.method = 'get';\n }\n\n var transitional = config.transitional;\n\n if (transitional !== undefined) {\n validator.assertOptions(transitional, {\n silentJSONParsing: validators.transitional(validators.boolean),\n forcedJSONParsing: validators.transitional(validators.boolean),\n clarifyTimeoutError: validators.transitional(validators.boolean)\n }, false);\n }\n\n // filter out skipped interceptors\n var requestInterceptorChain = [];\n var synchronousRequestInterceptors = true;\n this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {\n if (typeof interceptor.runWhen === 'function' && interceptor.runWhen(config) === false) {\n return;\n }\n\n synchronousRequestInterceptors = synchronousRequestInterceptors && interceptor.synchronous;\n\n requestInterceptorChain.unshift(interceptor.fulfilled, interceptor.rejected);\n });\n\n var responseInterceptorChain = [];\n this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) {\n responseInterceptorChain.push(interceptor.fulfilled, interceptor.rejected);\n });\n\n var promise;\n\n if (!synchronousRequestInterceptors) {\n var chain = [dispatchRequest, undefined];\n\n Array.prototype.unshift.apply(chain, requestInterceptorChain);\n chain = chain.concat(responseInterceptorChain);\n\n promise = Promise.resolve(config);\n while (chain.length) {\n promise = promise.then(chain.shift(), chain.shift());\n }\n\n return promise;\n }\n\n\n var newConfig = config;\n while (requestInterceptorChain.length) {\n var onFulfilled = requestInterceptorChain.shift();\n var onRejected = requestInterceptorChain.shift();\n try {\n newConfig = onFulfilled(newConfig);\n } catch (error) {\n onRejected(error);\n break;\n }\n }\n\n try {\n promise = dispatchRequest(newConfig);\n } catch (error) {\n return Promise.reject(error);\n }\n\n while (responseInterceptorChain.length) {\n promise = promise.then(responseInterceptorChain.shift(), responseInterceptorChain.shift());\n }\n\n return promise;\n};\n\nAxios.prototype.getUri = function getUri(config) {\n config = mergeConfig(this.defaults, config);\n var fullPath = buildFullPath(config.baseURL, config.url);\n return buildURL(fullPath, config.params, config.paramsSerializer);\n};\n\n// Provide aliases for supported request methods\nutils.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData(method) {\n /*eslint func-names:0*/\n Axios.prototype[method] = function(url, config) {\n return this.request(mergeConfig(config || {}, {\n method: method,\n url: url,\n data: (config || {}).data\n }));\n };\n});\n\nutils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {\n /*eslint func-names:0*/\n\n function generateHTTPMethod(isForm) {\n return function httpMethod(url, data, config) {\n return this.request(mergeConfig(config || {}, {\n method: method,\n headers: isForm ? {\n 'Content-Type': 'multipart/form-data'\n } : {},\n url: url,\n data: data\n }));\n };\n }\n\n Axios.prototype[method] = generateHTTPMethod();\n\n Axios.prototype[method + 'Form'] = generateHTTPMethod(true);\n});\n\nmodule.exports = Axios;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2NvcmUvQXhpb3MuanMiLCJtYXBwaW5ncyI6IkFBQWE7O0FBRWIsWUFBWSxtQkFBTyxDQUFDLHFEQUFZO0FBQ2hDLGVBQWUsbUJBQU8sQ0FBQyx5RUFBcUI7QUFDNUMseUJBQXlCLG1CQUFPLENBQUMsaUZBQXNCO0FBQ3ZELHNCQUFzQixtQkFBTyxDQUFDLDJFQUFtQjtBQUNqRCxrQkFBa0IsbUJBQU8sQ0FBQyxtRUFBZTtBQUN6QyxvQkFBb0IsbUJBQU8sQ0FBQyx1RUFBaUI7QUFDN0MsZ0JBQWdCLG1CQUFPLENBQUMsMkVBQXNCOztBQUU5QztBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsUUFBUTtBQUNuQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsUUFBUTtBQUNuQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBLElBQUk7QUFDSjtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdEQUFnRDtBQUNoRDtBQUNBO0FBQ0EseUJBQXlCO0FBQ3pCLEtBQUs7QUFDTDtBQUNBLENBQUM7O0FBRUQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esa0RBQWtEO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBLFVBQVUsSUFBSTtBQUNkO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLENBQUM7O0FBRUQiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2NvcmUvQXhpb3MuanM/MjlmYiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4vLi4vdXRpbHMnKTtcbnZhciBidWlsZFVSTCA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvYnVpbGRVUkwnKTtcbnZhciBJbnRlcmNlcHRvck1hbmFnZXIgPSByZXF1aXJlKCcuL0ludGVyY2VwdG9yTWFuYWdlcicpO1xudmFyIGRpc3BhdGNoUmVxdWVzdCA9IHJlcXVpcmUoJy4vZGlzcGF0Y2hSZXF1ZXN0Jyk7XG52YXIgbWVyZ2VDb25maWcgPSByZXF1aXJlKCcuL21lcmdlQ29uZmlnJyk7XG52YXIgYnVpbGRGdWxsUGF0aCA9IHJlcXVpcmUoJy4vYnVpbGRGdWxsUGF0aCcpO1xudmFyIHZhbGlkYXRvciA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvdmFsaWRhdG9yJyk7XG5cbnZhciB2YWxpZGF0b3JzID0gdmFsaWRhdG9yLnZhbGlkYXRvcnM7XG4vKipcbiAqIENyZWF0ZSBhIG5ldyBpbnN0YW5jZSBvZiBBeGlvc1xuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBpbnN0YW5jZUNvbmZpZyBUaGUgZGVmYXVsdCBjb25maWcgZm9yIHRoZSBpbnN0YW5jZVxuICovXG5mdW5jdGlvbiBBeGlvcyhpbnN0YW5jZUNvbmZpZykge1xuICB0aGlzLmRlZmF1bHRzID0gaW5zdGFuY2VDb25maWc7XG4gIHRoaXMuaW50ZXJjZXB0b3JzID0ge1xuICAgIHJlcXVlc3Q6IG5ldyBJbnRlcmNlcHRvck1hbmFnZXIoKSxcbiAgICByZXNwb25zZTogbmV3IEludGVyY2VwdG9yTWFuYWdlcigpXG4gIH07XG59XG5cbi8qKlxuICogRGlzcGF0Y2ggYSByZXF1ZXN0XG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGNvbmZpZyBUaGUgY29uZmlnIHNwZWNpZmljIGZvciB0aGlzIHJlcXVlc3QgKG1lcmdlZCB3aXRoIHRoaXMuZGVmYXVsdHMpXG4gKi9cbkF4aW9zLnByb3RvdHlwZS5yZXF1ZXN0ID0gZnVuY3Rpb24gcmVxdWVzdChjb25maWdPclVybCwgY29uZmlnKSB7XG4gIC8qZXNsaW50IG5vLXBhcmFtLXJlYXNzaWduOjAqL1xuICAvLyBBbGxvdyBmb3IgYXhpb3MoJ2V4YW1wbGUvdXJsJ1ssIGNvbmZpZ10pIGEgbGEgZmV0Y2ggQVBJXG4gIGlmICh0eXBlb2YgY29uZmlnT3JVcmwgPT09ICdzdHJpbmcnKSB7XG4gICAgY29uZmlnID0gY29uZmlnIHx8IHt9O1xuICAgIGNvbmZpZy51cmwgPSBjb25maWdPclVybDtcbiAgfSBlbHNlIHtcbiAgICBjb25maWcgPSBjb25maWdPclVybCB8fCB7fTtcbiAgfVxuXG4gIGNvbmZpZyA9IG1lcmdlQ29uZmlnKHRoaXMuZGVmYXVsdHMsIGNvbmZpZyk7XG5cbiAgLy8gU2V0IGNvbmZpZy5tZXRob2RcbiAgaWYgKGNvbmZpZy5tZXRob2QpIHtcbiAgICBjb25maWcubWV0aG9kID0gY29uZmlnLm1ldGhvZC50b0xvd2VyQ2FzZSgpO1xuICB9IGVsc2UgaWYgKHRoaXMuZGVmYXVsdHMubWV0aG9kKSB7XG4gICAgY29uZmlnLm1ldGhvZCA9IHRoaXMuZGVmYXVsdHMubWV0aG9kLnRvTG93ZXJDYXNlKCk7XG4gIH0gZWxzZSB7XG4gICAgY29uZmlnLm1ldGhvZCA9ICdnZXQnO1xuICB9XG5cbiAgdmFyIHRyYW5zaXRpb25hbCA9IGNvbmZpZy50cmFuc2l0aW9uYWw7XG5cbiAgaWYgKHRyYW5zaXRpb25hbCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgdmFsaWRhdG9yLmFzc2VydE9wdGlvbnModHJhbnNpdGlvbmFsLCB7XG4gICAgICBzaWxlbnRKU09OUGFyc2luZzogdmFsaWRhdG9ycy50cmFuc2l0aW9uYWwodmFsaWRhdG9ycy5ib29sZWFuKSxcbiAgICAgIGZvcmNlZEpTT05QYXJzaW5nOiB2YWxpZGF0b3JzLnRyYW5zaXRpb25hbCh2YWxpZGF0b3JzLmJvb2xlYW4pLFxuICAgICAgY2xhcmlmeVRpbWVvdXRFcnJvcjogdmFsaWRhdG9ycy50cmFuc2l0aW9uYWwodmFsaWRhdG9ycy5ib29sZWFuKVxuICAgIH0sIGZhbHNlKTtcbiAgfVxuXG4gIC8vIGZpbHRlciBvdXQgc2tpcHBlZCBpbnRlcmNlcHRvcnNcbiAgdmFyIHJlcXVlc3RJbnRlcmNlcHRvckNoYWluID0gW107XG4gIHZhciBzeW5jaHJvbm91c1JlcXVlc3RJbnRlcmNlcHRvcnMgPSB0cnVlO1xuICB0aGlzLmludGVyY2VwdG9ycy5yZXF1ZXN0LmZvckVhY2goZnVuY3Rpb24gdW5zaGlmdFJlcXVlc3RJbnRlcmNlcHRvcnMoaW50ZXJjZXB0b3IpIHtcbiAgICBpZiAodHlwZW9mIGludGVyY2VwdG9yLnJ1bldoZW4gPT09ICdmdW5jdGlvbicgJiYgaW50ZXJjZXB0b3IucnVuV2hlbihjb25maWcpID09PSBmYWxzZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHN5bmNocm9ub3VzUmVxdWVzdEludGVyY2VwdG9ycyA9IHN5bmNocm9ub3VzUmVxdWVzdEludGVyY2VwdG9ycyAmJiBpbnRlcmNlcHRvci5zeW5jaHJvbm91cztcblxuICAgIHJlcXVlc3RJbnRlcmNlcHRvckNoYWluLnVuc2hpZnQoaW50ZXJjZXB0b3IuZnVsZmlsbGVkLCBpbnRlcmNlcHRvci5yZWplY3RlZCk7XG4gIH0pO1xuXG4gIHZhciByZXNwb25zZUludGVyY2VwdG9yQ2hhaW4gPSBbXTtcbiAgdGhpcy5pbnRlcmNlcHRvcnMucmVzcG9uc2UuZm9yRWFjaChmdW5jdGlvbiBwdXNoUmVzcG9uc2VJbnRlcmNlcHRvcnMoaW50ZXJjZXB0b3IpIHtcbiAgICByZXNwb25zZUludGVyY2VwdG9yQ2hhaW4ucHVzaChpbnRlcmNlcHRvci5mdWxmaWxsZWQsIGludGVyY2VwdG9yLnJlamVjdGVkKTtcbiAgfSk7XG5cbiAgdmFyIHByb21pc2U7XG5cbiAgaWYgKCFzeW5jaHJvbm91c1JlcXVlc3RJbnRlcmNlcHRvcnMpIHtcbiAgICB2YXIgY2hhaW4gPSBbZGlzcGF0Y2hSZXF1ZXN0LCB1bmRlZmluZWRdO1xuXG4gICAgQXJyYXkucHJvdG90eXBlLnVuc2hpZnQuYXBwbHkoY2hhaW4sIHJlcXVlc3RJbnRlcmNlcHRvckNoYWluKTtcbiAgICBjaGFpbiA9IGNoYWluLmNvbmNhdChyZXNwb25zZUludGVyY2VwdG9yQ2hhaW4pO1xuXG4gICAgcHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZShjb25maWcpO1xuICAgIHdoaWxlIChjaGFpbi5sZW5ndGgpIHtcbiAgICAgIHByb21pc2UgPSBwcm9taXNlLnRoZW4oY2hhaW4uc2hpZnQoKSwgY2hhaW4uc2hpZnQoKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHByb21pc2U7XG4gIH1cblxuXG4gIHZhciBuZXdDb25maWcgPSBjb25maWc7XG4gIHdoaWxlIChyZXF1ZXN0SW50ZXJjZXB0b3JDaGFpbi5sZW5ndGgpIHtcbiAgICB2YXIgb25GdWxmaWxsZWQgPSByZXF1ZXN0SW50ZXJjZXB0b3JDaGFpbi5zaGlmdCgpO1xuICAgIHZhciBvblJlamVjdGVkID0gcmVxdWVzdEludGVyY2VwdG9yQ2hhaW4uc2hpZnQoKTtcbiAgICB0cnkge1xuICAgICAgbmV3Q29uZmlnID0gb25GdWxmaWxsZWQobmV3Q29uZmlnKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgb25SZWplY3RlZChlcnJvcik7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICB0cnkge1xuICAgIHByb21pc2UgPSBkaXNwYXRjaFJlcXVlc3QobmV3Q29uZmlnKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZXJyb3IpO1xuICB9XG5cbiAgd2hpbGUgKHJlc3BvbnNlSW50ZXJjZXB0b3JDaGFpbi5sZW5ndGgpIHtcbiAgICBwcm9taXNlID0gcHJvbWlzZS50aGVuKHJlc3BvbnNlSW50ZXJjZXB0b3JDaGFpbi5zaGlmdCgpLCByZXNwb25zZUludGVyY2VwdG9yQ2hhaW4uc2hpZnQoKSk7XG4gIH1cblxuICByZXR1cm4gcHJvbWlzZTtcbn07XG5cbkF4aW9zLnByb3RvdHlwZS5nZXRVcmkgPSBmdW5jdGlvbiBnZXRVcmkoY29uZmlnKSB7XG4gIGNvbmZpZyA9IG1lcmdlQ29uZmlnKHRoaXMuZGVmYXVsdHMsIGNvbmZpZyk7XG4gIHZhciBmdWxsUGF0aCA9IGJ1aWxkRnVsbFBhdGgoY29uZmlnLmJhc2VVUkwsIGNvbmZpZy51cmwpO1xuICByZXR1cm4gYnVpbGRVUkwoZnVsbFBhdGgsIGNvbmZpZy5wYXJhbXMsIGNvbmZpZy5wYXJhbXNTZXJpYWxpemVyKTtcbn07XG5cbi8vIFByb3ZpZGUgYWxpYXNlcyBmb3Igc3VwcG9ydGVkIHJlcXVlc3QgbWV0aG9kc1xudXRpbHMuZm9yRWFjaChbJ2RlbGV0ZScsICdnZXQnLCAnaGVhZCcsICdvcHRpb25zJ10sIGZ1bmN0aW9uIGZvckVhY2hNZXRob2ROb0RhdGEobWV0aG9kKSB7XG4gIC8qZXNsaW50IGZ1bmMtbmFtZXM6MCovXG4gIEF4aW9zLnByb3RvdHlwZVttZXRob2RdID0gZnVuY3Rpb24odXJsLCBjb25maWcpIHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0KG1lcmdlQ29uZmlnKGNvbmZpZyB8fCB7fSwge1xuICAgICAgbWV0aG9kOiBtZXRob2QsXG4gICAgICB1cmw6IHVybCxcbiAgICAgIGRhdGE6IChjb25maWcgfHwge30pLmRhdGFcbiAgICB9KSk7XG4gIH07XG59KTtcblxudXRpbHMuZm9yRWFjaChbJ3Bvc3QnLCAncHV0JywgJ3BhdGNoJ10sIGZ1bmN0aW9uIGZvckVhY2hNZXRob2RXaXRoRGF0YShtZXRob2QpIHtcbiAgLyplc2xpbnQgZnVuYy1uYW1lczowKi9cblxuICBmdW5jdGlvbiBnZW5lcmF0ZUhUVFBNZXRob2QoaXNGb3JtKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIGh0dHBNZXRob2QodXJsLCBkYXRhLCBjb25maWcpIHtcbiAgICAgIHJldHVybiB0aGlzLnJlcXVlc3QobWVyZ2VDb25maWcoY29uZmlnIHx8IHt9LCB7XG4gICAgICAgIG1ldGhvZDogbWV0aG9kLFxuICAgICAgICBoZWFkZXJzOiBpc0Zvcm0gPyB7XG4gICAgICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdtdWx0aXBhcnQvZm9ybS1kYXRhJ1xuICAgICAgICB9IDoge30sXG4gICAgICAgIHVybDogdXJsLFxuICAgICAgICBkYXRhOiBkYXRhXG4gICAgICB9KSk7XG4gICAgfTtcbiAgfVxuXG4gIEF4aW9zLnByb3RvdHlwZVttZXRob2RdID0gZ2VuZXJhdGVIVFRQTWV0aG9kKCk7XG5cbiAgQXhpb3MucHJvdG90eXBlW21ldGhvZCArICdGb3JtJ10gPSBnZW5lcmF0ZUhUVFBNZXRob2QodHJ1ZSk7XG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSBBeGlvcztcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/axios/lib/core/Axios.js\n");
/***/ }),
/***/ "./node_modules/axios/lib/core/AxiosError.js":
/*!***************************************************!*\
!*** ./node_modules/axios/lib/core/AxiosError.js ***!
\***************************************************/
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict";
eval("\n\nvar utils = __webpack_require__(/*! ../utils */ \"./node_modules/axios/lib/utils.js\");\n\n/**\n * Create an Error with the specified message, config, error code, request and response.\n *\n * @param {string} message The error message.\n * @param {string} [code] The error code (for example, 'ECONNABORTED').\n * @param {Object} [config] The config.\n * @param {Object} [request] The request.\n * @param {Object} [response] The response.\n * @returns {Error} The created error.\n */\nfunction AxiosError(message, code, config, request, response) {\n Error.call(this);\n this.message = message;\n this.name = 'AxiosError';\n code && (this.code = code);\n config && (this.config = config);\n request && (this.request = request);\n response && (this.response = response);\n}\n\nutils.inherits(AxiosError, Error, {\n toJSON: function toJSON() {\n return {\n // Standard\n message: this.message,\n name: this.name,\n // Microsoft\n description: this.description,\n number: this.number,\n // Mozilla\n fileName: this.fileName,\n lineNumber: this.lineNumber,\n columnNumber: this.columnNumber,\n stack: this.stack,\n // Axios\n config: this.config,\n code: this.code,\n status: this.response && this.response.status ? this.response.status : null\n };\n }\n});\n\nvar prototype = AxiosError.prototype;\nvar descriptors = {};\n\n[\n 'ERR_BAD_OPTION_VALUE',\n 'ERR_BAD_OPTION',\n 'ECONNABORTED',\n 'ETIMEDOUT',\n 'ERR_NETWORK',\n 'ERR_FR_TOO_MANY_REDIRECTS',\n 'ERR_DEPRECATED',\n 'ERR_BAD_RESPONSE',\n 'ERR_BAD_REQUEST',\n 'ERR_CANCELED'\n// eslint-disable-next-line func-names\n].forEach(function(code) {\n descriptors[code] = {value: code};\n});\n\nObject.defineProperties(AxiosError, descriptors);\nObject.defineProperty(prototype, 'isAxiosError', {value: true});\n\n// eslint-disable-next-line func-names\nAxiosError.from = function(error, code, config, request, response, customProps) {\n var axiosError = Object.create(prototype);\n\n utils.toFlatObject(error, axiosError, function filter(obj) {\n return obj !== Error.prototype;\n });\n\n AxiosError.call(axiosError, error.message, code, config, request, response);\n\n axiosError.name = error.name;\n\n customProps && Object.assign(axiosError, customProps);\n\n return axiosError;\n};\n\nmodule.exports = AxiosError;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2NvcmUvQXhpb3NFcnJvci5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixZQUFZLG1CQUFPLENBQUMsbURBQVU7O0FBRTlCO0FBQ0E7QUFDQTtBQUNBLFdBQVcsUUFBUTtBQUNuQixXQUFXLFFBQVE7QUFDbkIsV0FBVyxRQUFRO0FBQ25CLFdBQVcsUUFBUTtBQUNuQixXQUFXLFFBQVE7QUFDbkIsYUFBYSxPQUFPO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1QkFBdUI7QUFDdkIsQ0FBQzs7QUFFRDtBQUNBLGtEQUFrRCxZQUFZOztBQUU5RDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7O0FBRUg7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQSIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9heGlvcy9saWIvY29yZS9BeGlvc0Vycm9yLmpzPzIwMjciXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpO1xuXG4vKipcbiAqIENyZWF0ZSBhbiBFcnJvciB3aXRoIHRoZSBzcGVjaWZpZWQgbWVzc2FnZSwgY29uZmlnLCBlcnJvciBjb2RlLCByZXF1ZXN0IGFuZCByZXNwb25zZS5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZSBUaGUgZXJyb3IgbWVzc2FnZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBbY29kZV0gVGhlIGVycm9yIGNvZGUgKGZvciBleGFtcGxlLCAnRUNPTk5BQk9SVEVEJykuXG4gKiBAcGFyYW0ge09iamVjdH0gW2NvbmZpZ10gVGhlIGNvbmZpZy5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbcmVxdWVzdF0gVGhlIHJlcXVlc3QuXG4gKiBAcGFyYW0ge09iamVjdH0gW3Jlc3BvbnNlXSBUaGUgcmVzcG9uc2UuXG4gKiBAcmV0dXJucyB7RXJyb3J9IFRoZSBjcmVhdGVkIGVycm9yLlxuICovXG5mdW5jdGlvbiBBeGlvc0Vycm9yKG1lc3NhZ2UsIGNvZGUsIGNvbmZpZywgcmVxdWVzdCwgcmVzcG9uc2UpIHtcbiAgRXJyb3IuY2FsbCh0aGlzKTtcbiAgdGhpcy5tZXNzYWdlID0gbWVzc2FnZTtcbiAgdGhpcy5uYW1lID0gJ0F4aW9zRXJyb3InO1xuICBjb2RlICYmICh0aGlzLmNvZGUgPSBjb2RlKTtcbiAgY29uZmlnICYmICh0aGlzLmNvbmZpZyA9IGNvbmZpZyk7XG4gIHJlcXVlc3QgJiYgKHRoaXMucmVxdWVzdCA9IHJlcXVlc3QpO1xuICByZXNwb25zZSAmJiAodGhpcy5yZXNwb25zZSA9IHJlc3BvbnNlKTtcbn1cblxudXRpbHMuaW5oZXJpdHMoQXhpb3NFcnJvciwgRXJyb3IsIHtcbiAgdG9KU09OOiBmdW5jdGlvbiB0b0pTT04oKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIC8vIFN0YW5kYXJkXG4gICAgICBtZXNzYWdlOiB0aGlzLm1lc3NhZ2UsXG4gICAgICBuYW1lOiB0aGlzLm5hbWUsXG4gICAgICAvLyBNaWNyb3NvZnRcbiAgICAgIGRlc2NyaXB0aW9uOiB0aGlzLmRlc2NyaXB0aW9uLFxuICAgICAgbnVtYmVyOiB0aGlzLm51bWJlcixcbiAgICAgIC8vIE1vemlsbGFcbiAgICAgIGZpbGVOYW1lOiB0aGlzLmZpbGVOYW1lLFxuICAgICAgbGluZU51bWJlcjogdGhpcy5saW5lTnVtYmVyLFxuICAgICAgY29sdW1uTnVtYmVyOiB0aGlzLmNvbHVtbk51bWJlcixcbiAgICAgIHN0YWNrOiB0aGlzLnN0YWNrLFxuICAgICAgLy8gQXhpb3NcbiAgICAgIGNvbmZpZzogdGhpcy5jb25maWcsXG4gICAgICBjb2RlOiB0aGlzLmNvZGUsXG4gICAgICBzdGF0dXM6IHRoaXMucmVzcG9uc2UgJiYgdGhpcy5yZXNwb25zZS5zdGF0dXMgPyB0aGlzLnJlc3BvbnNlLnN0YXR1cyA6IG51bGxcbiAgICB9O1xuICB9XG59KTtcblxudmFyIHByb3RvdHlwZSA9IEF4aW9zRXJyb3IucHJvdG90eXBlO1xudmFyIGRlc2NyaXB0b3JzID0ge307XG5cbltcbiAgJ0VSUl9CQURfT1BUSU9OX1ZBTFVFJyxcbiAgJ0VSUl9CQURfT1BUSU9OJyxcbiAgJ0VDT05OQUJPUlRFRCcsXG4gICdFVElNRURPVVQnLFxuICAnRVJSX05FVFdPUksnLFxuICAnRVJSX0ZSX1RPT19NQU5ZX1JFRElSRUNUUycsXG4gICdFUlJfREVQUkVDQVRFRCcsXG4gICdFUlJfQkFEX1JFU1BPTlNFJyxcbiAgJ0VSUl9CQURfUkVRVUVTVCcsXG4gICdFUlJfQ0FOQ0VMRUQnXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZnVuYy1uYW1lc1xuXS5mb3JFYWNoKGZ1bmN0aW9uKGNvZGUpIHtcbiAgZGVzY3JpcHRvcnNbY29kZV0gPSB7dmFsdWU6IGNvZGV9O1xufSk7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKEF4aW9zRXJyb3IsIGRlc2NyaXB0b3JzKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShwcm90b3R5cGUsICdpc0F4aW9zRXJyb3InLCB7dmFsdWU6IHRydWV9KTtcblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGZ1bmMtbmFtZXNcbkF4aW9zRXJyb3IuZnJvbSA9IGZ1bmN0aW9uKGVycm9yLCBjb2RlLCBjb25maWcsIHJlcXVlc3QsIHJlc3BvbnNlLCBjdXN0b21Qcm9wcykge1xuICB2YXIgYXhpb3NFcnJvciA9IE9iamVjdC5jcmVhdGUocHJvdG90eXBlKTtcblxuICB1dGlscy50b0ZsYXRPYmplY3QoZXJyb3IsIGF4aW9zRXJyb3IsIGZ1bmN0aW9uIGZpbHRlcihvYmopIHtcbiAgICByZXR1cm4gb2JqICE9PSBFcnJvci5wcm90b3R5cGU7XG4gIH0pO1xuXG4gIEF4aW9zRXJyb3IuY2FsbChheGlvc0Vycm9yLCBlcnJvci5tZXNzYWdlLCBjb2RlLCBjb25maWcsIHJlcXVlc3QsIHJlc3BvbnNlKTtcblxuICBheGlvc0Vycm9yLm5hbWUgPSBlcnJvci5uYW1lO1xuXG4gIGN1c3RvbVByb3BzICYmIE9iamVjdC5hc3NpZ24oYXhpb3NFcnJvciwgY3VzdG9tUHJvcHMpO1xuXG4gIHJldHVybiBheGlvc0Vycm9yO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBBeGlvc0Vycm9yO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/axios/lib/core/AxiosError.js\n");
/***/ }),
/***/ "./node_modules/axios/lib/core/InterceptorManager.js":
/*!***********************************************************!*\
!*** ./node_modules/axios/lib/core/InterceptorManager.js ***!
\***********************************************************/
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict";
eval("\n\nvar utils = __webpack_require__(/*! ./../utils */ \"./node_modules/axios/lib/utils.js\");\n\nfunction InterceptorManager() {\n this.handlers = [];\n}\n\n/**\n * Add a new interceptor to the stack\n *\n * @param {Function} fulfilled The function to handle `then` for a `Promise`\n * @param {Function} rejected The function to handle `reject` for a `Promise`\n *\n * @return {Number} An ID used to remove interceptor later\n */\nInterceptorManager.prototype.use = function use(fulfilled, rejected, options) {\n this.handlers.push({\n fulfilled: fulfilled,\n rejected: rejected,\n synchronous: options ? options.synchronous : false,\n runWhen: options ? options.runWhen : null\n });\n return this.handlers.length - 1;\n};\n\n/**\n * Remove an interceptor from the stack\n *\n * @param {Number} id The ID that was returned by `use`\n */\nInterceptorManager.prototype.eject = function eject(id) {\n if (this.handlers[id]) {\n this.handlers[id] = null;\n }\n};\n\n/**\n * Iterate over all the registered interceptors\n *\n * This method is particularly useful for skipping over any\n * interceptors that may have become `null` calling `eject`.\n *\n * @param {Function} fn The function to call for each interceptor\n */\nInterceptorManager.prototype.forEach = function forEach(fn) {\n utils.forEach(this.handlers, function forEachHandler(h) {\n if (h !== null) {\n fn(h);\n }\n });\n};\n\nmodule.exports = InterceptorManager;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2NvcmUvSW50ZXJjZXB0b3JNYW5hZ2VyLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLFlBQVksbUJBQU8sQ0FBQyxxREFBWTs7QUFFaEM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsVUFBVTtBQUNyQixXQUFXLFVBQVU7QUFDckI7QUFDQSxZQUFZLFFBQVE7QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLFFBQVE7QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsVUFBVTtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUEiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2NvcmUvSW50ZXJjZXB0b3JNYW5hZ2VyLmpzP2M3OTIiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLy4uL3V0aWxzJyk7XG5cbmZ1bmN0aW9uIEludGVyY2VwdG9yTWFuYWdlcigpIHtcbiAgdGhpcy5oYW5kbGVycyA9IFtdO1xufVxuXG4vKipcbiAqIEFkZCBhIG5ldyBpbnRlcmNlcHRvciB0byB0aGUgc3RhY2tcbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdWxmaWxsZWQgVGhlIGZ1bmN0aW9uIHRvIGhhbmRsZSBgdGhlbmAgZm9yIGEgYFByb21pc2VgXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSByZWplY3RlZCBUaGUgZnVuY3Rpb24gdG8gaGFuZGxlIGByZWplY3RgIGZvciBhIGBQcm9taXNlYFxuICpcbiAqIEByZXR1cm4ge051bWJlcn0gQW4gSUQgdXNlZCB0byByZW1vdmUgaW50ZXJjZXB0b3IgbGF0ZXJcbiAqL1xuSW50ZXJjZXB0b3JNYW5hZ2VyLnByb3RvdHlwZS51c2UgPSBmdW5jdGlvbiB1c2UoZnVsZmlsbGVkLCByZWplY3RlZCwgb3B0aW9ucykge1xuICB0aGlzLmhhbmRsZXJzLnB1c2goe1xuICAgIGZ1bGZpbGxlZDogZnVsZmlsbGVkLFxuICAgIHJlamVjdGVkOiByZWplY3RlZCxcbiAgICBzeW5jaHJvbm91czogb3B0aW9ucyA/IG9wdGlvbnMuc3luY2hyb25vdXMgOiBmYWxzZSxcbiAgICBydW5XaGVuOiBvcHRpb25zID8gb3B0aW9ucy5ydW5XaGVuIDogbnVsbFxuICB9KTtcbiAgcmV0dXJuIHRoaXMuaGFuZGxlcnMubGVuZ3RoIC0gMTtcbn07XG5cbi8qKlxuICogUmVtb3ZlIGFuIGludGVyY2VwdG9yIGZyb20gdGhlIHN0YWNrXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IGlkIFRoZSBJRCB0aGF0IHdhcyByZXR1cm5lZCBieSBgdXNlYFxuICovXG5JbnRlcmNlcHRvck1hbmFnZXIucHJvdG90eXBlLmVqZWN0ID0gZnVuY3Rpb24gZWplY3QoaWQpIHtcbiAgaWYgKHRoaXMuaGFuZGxlcnNbaWRdKSB7XG4gICAgdGhpcy5oYW5kbGVyc1tpZF0gPSBudWxsO1xuICB9XG59O1xuXG4vKipcbiAqIEl0ZXJhdGUgb3ZlciBhbGwgdGhlIHJlZ2lzdGVyZWQgaW50ZXJjZXB0b3JzXG4gKlxuICogVGhpcyBtZXRob2QgaXMgcGFydGljdWxhcmx5IHVzZWZ1bCBmb3Igc2tpcHBpbmcgb3ZlciBhbnlcbiAqIGludGVyY2VwdG9ycyB0aGF0IG1heSBoYXZlIGJlY29tZSBgbnVsbGAgY2FsbGluZyBgZWplY3RgLlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIFRoZSBmdW5jdGlvbiB0byBjYWxsIGZvciBlYWNoIGludGVyY2VwdG9yXG4gKi9cbkludGVyY2VwdG9yTWFuYWdlci5wcm90b3R5cGUuZm9yRWFjaCA9IGZ1bmN0aW9uIGZvckVhY2goZm4pIHtcbiAgdXRpbHMuZm9yRWFjaCh0aGlzLmhhbmRsZXJzLCBmdW5jdGlvbiBmb3JFYWNoSGFuZGxlcihoKSB7XG4gICAgaWYgKGggIT09IG51bGwpIHtcbiAgICAgIGZuKGgpO1xuICAgIH1cbiAgfSk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IEludGVyY2VwdG9yTWFuYWdlcjtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/axios/lib/core/InterceptorManager.js\n");
/***/ }),
/***/ "./node_modules/axios/lib/core/buildFullPath.js":
/*!******************************************************!*\
!*** ./node_modules/axios/lib/core/buildFullPath.js ***!
\******************************************************/
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict";
eval("\n\nvar isAbsoluteURL = __webpack_require__(/*! ../helpers/isAbsoluteURL */ \"./node_modules/axios/lib/helpers/isAbsoluteURL.js\");\nvar combineURLs = __webpack_require__(/*! ../helpers/combineURLs */ \"./node_modules/axios/lib/helpers/combineURLs.js\");\n\n/**\n * Creates a new URL by combining the baseURL with the requestedURL,\n * only when the requestedURL is not already an absolute URL.\n * If the requestURL is absolute, this function returns the requestedURL untouched.\n *\n * @param {string} baseURL The base URL\n * @param {string} requestedURL Absolute or relative URL to combine\n * @returns {string} The combined full path\n */\nmodule.exports = function buildFullPath(baseURL, requestedURL) {\n if (baseURL && !isAbsoluteURL(requestedURL)) {\n return combineURLs(baseURL, requestedURL);\n }\n return requestedURL;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2NvcmUvYnVpbGRGdWxsUGF0aC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixvQkFBb0IsbUJBQU8sQ0FBQyxtRkFBMEI7QUFDdEQsa0JBQWtCLG1CQUFPLENBQUMsK0VBQXdCOztBQUVsRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxRQUFRO0FBQ25CLFdBQVcsUUFBUTtBQUNuQixhQUFhLFFBQVE7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2NvcmUvYnVpbGRGdWxsUGF0aC5qcz9mMDJkIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIGlzQWJzb2x1dGVVUkwgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2lzQWJzb2x1dGVVUkwnKTtcbnZhciBjb21iaW5lVVJMcyA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvY29tYmluZVVSTHMnKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IFVSTCBieSBjb21iaW5pbmcgdGhlIGJhc2VVUkwgd2l0aCB0aGUgcmVxdWVzdGVkVVJMLFxuICogb25seSB3aGVuIHRoZSByZXF1ZXN0ZWRVUkwgaXMgbm90IGFscmVhZHkgYW4gYWJzb2x1dGUgVVJMLlxuICogSWYgdGhlIHJlcXVlc3RVUkwgaXMgYWJzb2x1dGUsIHRoaXMgZnVuY3Rpb24gcmV0dXJucyB0aGUgcmVxdWVzdGVkVVJMIHVudG91Y2hlZC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gYmFzZVVSTCBUaGUgYmFzZSBVUkxcbiAqIEBwYXJhbSB7c3RyaW5nfSByZXF1ZXN0ZWRVUkwgQWJzb2x1dGUgb3IgcmVsYXRpdmUgVVJMIHRvIGNvbWJpbmVcbiAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBjb21iaW5lZCBmdWxsIHBhdGhcbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBidWlsZEZ1bGxQYXRoKGJhc2VVUkwsIHJlcXVlc3RlZFVSTCkge1xuICBpZiAoYmFzZVVSTCAmJiAhaXNBYnNvbHV0ZVVSTChyZXF1ZXN0ZWRVUkwpKSB7XG4gICAgcmV0dXJuIGNvbWJpbmVVUkxzKGJhc2VVUkwsIHJlcXVlc3RlZFVSTCk7XG4gIH1cbiAgcmV0dXJuIHJlcXVlc3RlZFVSTDtcbn07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/axios/lib/core/buildFullPath.js\n");
/***/ }),
/***/ "./node_modules/axios/lib/core/dispatchRequest.js":
/*!********************************************************!*\
!*** ./node_modules/axios/lib/core/dispatchRequest.js ***!
\********************************************************/
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict";
eval("\n\nvar utils = __webpack_require__(/*! ./../utils */ \"./node_modules/axios/lib/utils.js\");\nvar transformData = __webpack_require__(/*! ./transformData */ \"./node_modules/axios/lib/core/transformData.js\");\nvar isCancel = __webpack_require__(/*! ../cancel/isCancel */ \"./node_modules/axios/lib/cancel/isCancel.js\");\nvar defaults = __webpack_require__(/*! ../defaults */ \"./node_modules/axios/lib/defaults/index.js\");\nvar CanceledError = __webpack_require__(/*! ../cancel/CanceledError */ \"./node_modules/axios/lib/cancel/CanceledError.js\");\n\n/**\n * Throws a `CanceledError` if cancellation has been requested.\n */\nfunction throwIfCancellationRequested(config) {\n if (config.cancelToken) {\n config.cancelToken.throwIfRequested();\n }\n\n if (config.signal && config.signal.aborted) {\n throw new CanceledError();\n }\n}\n\n/**\n * Dispatch a request to the server using the configured adapter.\n *\n * @param {object} config The config that is to be used for the request\n * @returns {Promise} The Promise to be fulfilled\n */\nmodule.exports = function dispatchRequest(config) {\n throwIfCancellationRequested(config);\n\n // Ensure headers exist\n config.headers = config.headers || {};\n\n // Transform request data\n config.data = transformData.call(\n config,\n config.data,\n config.headers,\n config.transformRequest\n );\n\n // Flatten headers\n config.headers = utils.merge(\n config.headers.common || {},\n config.headers[config.method] || {},\n config.headers\n );\n\n utils.forEach(\n ['delete', 'get', 'head', 'post', 'put', 'patch', 'common'],\n function cleanHeaderConfig(method) {\n delete config.headers[method];\n }\n );\n\n var adapter = config.adapter || defaults.adapter;\n\n return adapter(config).then(function onAdapterResolution(response) {\n throwIfCancellationRequested(config);\n\n // Transform response data\n response.data = transformData.call(\n config,\n response.data,\n response.headers,\n config.transformResponse\n );\n\n return response;\n }, function onAdapterRejection(reason) {\n if (!isCancel(reason)) {\n throwIfCancellationRequested(config);\n\n // Transform response data\n if (reason && reason.response) {\n reason.response.data = transformData.call(\n config,\n reason.response.data,\n reason.response.headers,\n config.transformResponse\n );\n }\n }\n\n return Promise.reject(reason);\n });\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2NvcmUvZGlzcGF0Y2hSZXF1ZXN0LmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLFlBQVksbUJBQU8sQ0FBQyxxREFBWTtBQUNoQyxvQkFBb0IsbUJBQU8sQ0FBQyx1RUFBaUI7QUFDN0MsZUFBZSxtQkFBTyxDQUFDLHVFQUFvQjtBQUMzQyxlQUFlLG1CQUFPLENBQUMsK0RBQWE7QUFDcEMsb0JBQW9CLG1CQUFPLENBQUMsaUZBQXlCOztBQUVyRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLFFBQVE7QUFDbkIsYUFBYSxTQUFTO0FBQ3RCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSwrQkFBK0I7QUFDL0IsdUNBQXVDO0FBQ3ZDO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEdBQUc7QUFDSCIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9heGlvcy9saWIvY29yZS9kaXNwYXRjaFJlcXVlc3QuanM/NGRjOSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4vLi4vdXRpbHMnKTtcbnZhciB0cmFuc2Zvcm1EYXRhID0gcmVxdWlyZSgnLi90cmFuc2Zvcm1EYXRhJyk7XG52YXIgaXNDYW5jZWwgPSByZXF1aXJlKCcuLi9jYW5jZWwvaXNDYW5jZWwnKTtcbnZhciBkZWZhdWx0cyA9IHJlcXVpcmUoJy4uL2RlZmF1bHRzJyk7XG52YXIgQ2FuY2VsZWRFcnJvciA9IHJlcXVpcmUoJy4uL2NhbmNlbC9DYW5jZWxlZEVycm9yJyk7XG5cbi8qKlxuICogVGhyb3dzIGEgYENhbmNlbGVkRXJyb3JgIGlmIGNhbmNlbGxhdGlvbiBoYXMgYmVlbiByZXF1ZXN0ZWQuXG4gKi9cbmZ1bmN0aW9uIHRocm93SWZDYW5jZWxsYXRpb25SZXF1ZXN0ZWQoY29uZmlnKSB7XG4gIGlmIChjb25maWcuY2FuY2VsVG9rZW4pIHtcbiAgICBjb25maWcuY2FuY2VsVG9rZW4udGhyb3dJZlJlcXVlc3RlZCgpO1xuICB9XG5cbiAgaWYgKGNvbmZpZy5zaWduYWwgJiYgY29uZmlnLnNpZ25hbC5hYm9ydGVkKSB7XG4gICAgdGhyb3cgbmV3IENhbmNlbGVkRXJyb3IoKTtcbiAgfVxufVxuXG4vKipcbiAqIERpc3BhdGNoIGEgcmVxdWVzdCB0byB0aGUgc2VydmVyIHVzaW5nIHRoZSBjb25maWd1cmVkIGFkYXB0ZXIuXG4gKlxuICogQHBhcmFtIHtvYmplY3R9IGNvbmZpZyBUaGUgY29uZmlnIHRoYXQgaXMgdG8gYmUgdXNlZCBmb3IgdGhlIHJlcXVlc3RcbiAqIEByZXR1cm5zIHtQcm9taXNlfSBUaGUgUHJvbWlzZSB0byBiZSBmdWxmaWxsZWRcbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBkaXNwYXRjaFJlcXVlc3QoY29uZmlnKSB7XG4gIHRocm93SWZDYW5jZWxsYXRpb25SZXF1ZXN0ZWQoY29uZmlnKTtcblxuICAvLyBFbnN1cmUgaGVhZGVycyBleGlzdFxuICBjb25maWcuaGVhZGVycyA9IGNvbmZpZy5oZWFkZXJzIHx8IHt9O1xuXG4gIC8vIFRyYW5zZm9ybSByZXF1ZXN0IGRhdGFcbiAgY29uZmlnLmRhdGEgPSB0cmFuc2Zvcm1EYXRhLmNhbGwoXG4gICAgY29uZmlnLFxuICAgIGNvbmZpZy5kYXRhLFxuICAgIGNvbmZpZy5oZWFkZXJzLFxuICAgIGNvbmZpZy50cmFuc2Zvcm1SZXF1ZXN0XG4gICk7XG5cbiAgLy8gRmxhdHRlbiBoZWFkZXJzXG4gIGNvbmZpZy5oZWFkZXJzID0gdXRpbHMubWVyZ2UoXG4gICAgY29uZmlnLmhlYWRlcnMuY29tbW9uIHx8IHt9LFxuICAgIGNvbmZpZy5oZWFkZXJzW2NvbmZpZy5tZXRob2RdIHx8IHt9LFxuICAgIGNvbmZpZy5oZWFkZXJzXG4gICk7XG5cbiAgdXRpbHMuZm9yRWFjaChcbiAgICBbJ2RlbGV0ZScsICdnZXQnLCAnaGVhZCcsICdwb3N0JywgJ3B1dCcsICdwYXRjaCcsICdjb21tb24nXSxcbiAgICBmdW5jdGlvbiBjbGVhbkhlYWRlckNvbmZpZyhtZXRob2QpIHtcbiAgICAgIGRlbGV0ZSBjb25maWcuaGVhZGVyc1ttZXRob2RdO1xuICAgIH1cbiAgKTtcblxuICB2YXIgYWRhcHRlciA9IGNvbmZpZy5hZGFwdGVyIHx8IGRlZmF1bHRzLmFkYXB0ZXI7XG5cbiAgcmV0dXJuIGFkYXB0ZXIoY29uZmlnKS50aGVuKGZ1bmN0aW9uIG9uQWRhcHRlclJlc29sdXRpb24ocmVzcG9uc2UpIHtcbiAgICB0aHJvd0lmQ2FuY2VsbGF0aW9uUmVxdWVzdGVkKGNvbmZpZyk7XG5cbiAgICAvLyBUcmFuc2Zvcm0gcmVzcG9uc2UgZGF0YVxuICAgIHJlc3BvbnNlLmRhdGEgPSB0cmFuc2Zvcm1EYXRhLmNhbGwoXG4gICAgICBjb25maWcsXG4gICAgICByZXNwb25zZS5kYXRhLFxuICAgICAgcmVzcG9uc2UuaGVhZGVycyxcbiAgICAgIGNvbmZpZy50cmFuc2Zvcm1SZXNwb25zZVxuICAgICk7XG5cbiAgICByZXR1cm4gcmVzcG9uc2U7XG4gIH0sIGZ1bmN0aW9uIG9uQWRhcHRlclJlamVjdGlvbihyZWFzb24pIHtcbiAgICBpZiAoIWlzQ2FuY2VsKHJlYXNvbikpIHtcbiAgICAgIHRocm93SWZDYW5jZWxsYXRpb25SZXF1ZXN0ZWQoY29uZmlnKTtcblxuICAgICAgLy8gVHJhbnNmb3JtIHJlc3BvbnNlIGRhdGFcbiAgICAgIGlmIChyZWFzb24gJiYgcmVhc29uLnJlc3BvbnNlKSB7XG4gICAgICAgIHJlYXNvbi5yZXNwb25zZS5kYXRhID0gdHJhbnNmb3JtRGF0YS5jYWxsKFxuICAgICAgICAgIGNvbmZpZyxcbiAgICAgICAgICByZWFzb24ucmVzcG9uc2UuZGF0YSxcbiAgICAgICAgICByZWFzb24ucmVzcG9uc2UuaGVhZGVycyxcbiAgICAgICAgICBjb25maWcudHJhbnNmb3JtUmVzcG9uc2VcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QocmVhc29uKTtcbiAgfSk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/axios/lib/core/dispatchRequest.js\n");
/***/ }),
/***/ "./node_modules/axios/lib/core/mergeConfig.js":
/*!****************************************************!*\
!*** ./node_modules/axios/lib/core/mergeConfig.js ***!
\****************************************************/
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict";
eval("\n\nvar utils = __webpack_require__(/*! ../utils */ \"./node_modules/axios/lib/utils.js\");\n\n/**\n * Config-specific merge-function which creates a new config-object\n * by merging two configuration objects together.\n *\n * @param {Object} config1\n * @param {Object} config2\n * @returns {Object} New object resulting from merging config2 to config1\n */\nmodule.exports = function mergeConfig(config1, config2) {\n // eslint-disable-next-line no-param-reassign\n config2 = config2 || {};\n var config = {};\n\n function getMergedValue(target, source) {\n if (utils.isPlainObject(target) && utils.isPlainObject(source)) {\n return utils.merge(target, source);\n } else if (utils.isPlainObject(source)) {\n return utils.merge({}, source);\n } else if (utils.isArray(source)) {\n return source.slice();\n }\n return source;\n }\n\n // eslint-disable-next-line consistent-return\n function mergeDeepProperties(prop) {\n if (!utils.isUndefined(config2[prop])) {\n return getMergedValue(config1[prop], config2[prop]);\n } else if (!utils.isUndefined(config1[prop])) {\n return getMergedValue(undefined, config1[prop]);\n }\n }\n\n // eslint-disable-next-line consistent-return\n function valueFromConfig2(prop) {\n if (!utils.isUndefined(config2[prop])) {\n return getMergedValue(undefined, config2[prop]);\n }\n }\n\n // eslint-disable-next-line consistent-return\n function defaultToConfig2(prop) {\n if (!utils.isUndefined(config2[prop])) {\n return getMergedValue(undefined, config2[prop]);\n } else if (!utils.isUndefined(config1[prop])) {\n return getMergedValue(undefined, config1[prop]);\n }\n }\n\n // eslint-disable-next-line consistent-return\n function mergeDirectKeys(prop) {\n if (prop in config2) {\n return getMergedValue(config1[prop], config2[prop]);\n } else if (prop in config1) {\n return getMergedValue(undefined, config1[prop]);\n }\n }\n\n var mergeMap = {\n 'url': valueFromConfig2,\n 'method': valueFromConfig2,\n 'data': valueFromConfig2,\n 'baseURL': defaultToConfig2,\n 'transformRequest': defaultToConfig2,\n 'transformResponse': defaultToConfig2,\n 'paramsSerializer': defaultToConfig2,\n 'timeout': defaultToConfig2,\n 'timeoutMessage': defaultToConfig2,\n 'withCredentials': defaultToConfig2,\n 'adapter': defaultToConfig2,\n 'responseType': defaultToConfig2,\n 'xsrfCookieName': defaultToConfig2,\n 'xsrfHeaderName': defaultToConfig2,\n 'onUploadProgress': defaultToConfig2,\n 'onDownloadProgress': defaultToConfig2,\n 'decompress': defaultToConfig2,\n 'maxContentLength': defaultToConfig2,\n 'maxBodyLength': defaultToConfig2,\n 'beforeRedirect': defaultToConfig2,\n 'transport': defaultToConfig2,\n 'httpAgent': defaultToConfig2,\n 'httpsAgent': defaultToConfig2,\n 'cancelToken': defaultToConfig2,\n 'socketPath': defaultToConfig2,\n 'responseEncoding': defaultToConfig2,\n 'validateStatus': mergeDirectKeys\n };\n\n utils.forEach(Object.keys(config1).concat(Object.keys(config2)), function computeConfigValue(prop) {\n var merge = mergeMap[prop] || mergeDeepProperties;\n var configValue = merge(prop);\n (utils.isUndefined(configValue) && merge !== mergeDirectKeys) || (config[prop] = configValue);\n });\n\n return config;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2NvcmUvbWVyZ2VDb25maWcuanMiLCJtYXBwaW5ncyI6IkFBQWE7O0FBRWIsWUFBWSxtQkFBTyxDQUFDLG1EQUFVOztBQUU5QjtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsUUFBUTtBQUNuQixXQUFXLFFBQVE7QUFDbkIsYUFBYSxRQUFRO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOLDJCQUEyQjtBQUMzQixNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2NvcmUvbWVyZ2VDb25maWcuanM/YmQxMyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uL3V0aWxzJyk7XG5cbi8qKlxuICogQ29uZmlnLXNwZWNpZmljIG1lcmdlLWZ1bmN0aW9uIHdoaWNoIGNyZWF0ZXMgYSBuZXcgY29uZmlnLW9iamVjdFxuICogYnkgbWVyZ2luZyB0d28gY29uZmlndXJhdGlvbiBvYmplY3RzIHRvZ2V0aGVyLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb25maWcxXG4gKiBAcGFyYW0ge09iamVjdH0gY29uZmlnMlxuICogQHJldHVybnMge09iamVjdH0gTmV3IG9iamVjdCByZXN1bHRpbmcgZnJvbSBtZXJnaW5nIGNvbmZpZzIgdG8gY29uZmlnMVxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIG1lcmdlQ29uZmlnKGNvbmZpZzEsIGNvbmZpZzIpIHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXBhcmFtLXJlYXNzaWduXG4gIGNvbmZpZzIgPSBjb25maWcyIHx8IHt9O1xuICB2YXIgY29uZmlnID0ge307XG5cbiAgZnVuY3Rpb24gZ2V0TWVyZ2VkVmFsdWUodGFyZ2V0LCBzb3VyY2UpIHtcbiAgICBpZiAodXRpbHMuaXNQbGFpbk9iamVjdCh0YXJnZXQpICYmIHV0aWxzLmlzUGxhaW5PYmplY3Qoc291cmNlKSkge1xuICAgICAgcmV0dXJuIHV0aWxzLm1lcmdlKHRhcmdldCwgc291cmNlKTtcbiAgICB9IGVsc2UgaWYgKHV0aWxzLmlzUGxhaW5PYmplY3Qoc291cmNlKSkge1xuICAgICAgcmV0dXJuIHV0aWxzLm1lcmdlKHt9LCBzb3VyY2UpO1xuICAgIH0gZWxzZSBpZiAodXRpbHMuaXNBcnJheShzb3VyY2UpKSB7XG4gICAgICByZXR1cm4gc291cmNlLnNsaWNlKCk7XG4gICAgfVxuICAgIHJldHVybiBzb3VyY2U7XG4gIH1cblxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY29uc2lzdGVudC1yZXR1cm5cbiAgZnVuY3Rpb24gbWVyZ2VEZWVwUHJvcGVydGllcyhwcm9wKSB7XG4gICAgaWYgKCF1dGlscy5pc1VuZGVmaW5lZChjb25maWcyW3Byb3BdKSkge1xuICAgICAgcmV0dXJuIGdldE1lcmdlZFZhbHVlKGNvbmZpZzFbcHJvcF0sIGNvbmZpZzJbcHJvcF0pO1xuICAgIH0gZWxzZSBpZiAoIXV0aWxzLmlzVW5kZWZpbmVkKGNvbmZpZzFbcHJvcF0pKSB7XG4gICAgICByZXR1cm4gZ2V0TWVyZ2VkVmFsdWUodW5kZWZpbmVkLCBjb25maWcxW3Byb3BdKTtcbiAgICB9XG4gIH1cblxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY29uc2lzdGVudC1yZXR1cm5cbiAgZnVuY3Rpb24gdmFsdWVGcm9tQ29uZmlnMihwcm9wKSB7XG4gICAgaWYgKCF1dGlscy5pc1VuZGVmaW5lZChjb25maWcyW3Byb3BdKSkge1xuICAgICAgcmV0dXJuIGdldE1lcmdlZFZhbHVlKHVuZGVmaW5lZCwgY29uZmlnMltwcm9wXSk7XG4gICAgfVxuICB9XG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNvbnNpc3RlbnQtcmV0dXJuXG4gIGZ1bmN0aW9uIGRlZmF1bHRUb0NvbmZpZzIocHJvcCkge1xuICAgIGlmICghdXRpbHMuaXNVbmRlZmluZWQoY29uZmlnMltwcm9wXSkpIHtcbiAgICAgIHJldHVybiBnZXRNZXJnZWRWYWx1ZSh1bmRlZmluZWQsIGNvbmZpZzJbcHJvcF0pO1xuICAgIH0gZWxzZSBpZiAoIXV0aWxzLmlzVW5kZWZpbmVkKGNvbmZpZzFbcHJvcF0pKSB7XG4gICAgICByZXR1cm4gZ2V0TWVyZ2VkVmFsdWUodW5kZWZpbmVkLCBjb25maWcxW3Byb3BdKTtcbiAgICB9XG4gIH1cblxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY29uc2lzdGVudC1yZXR1cm5cbiAgZnVuY3Rpb24gbWVyZ2VEaXJlY3RLZXlzKHByb3ApIHtcbiAgICBpZiAocHJvcCBpbiBjb25maWcyKSB7XG4gICAgICByZXR1cm4gZ2V0TWVyZ2VkVmFsdWUoY29uZmlnMVtwcm9wXSwgY29uZmlnMltwcm9wXSk7XG4gICAgfSBlbHNlIGlmIChwcm9wIGluIGNvbmZpZzEpIHtcbiAgICAgIHJldHVybiBnZXRNZXJnZWRWYWx1ZSh1bmRlZmluZWQsIGNvbmZpZzFbcHJvcF0pO1xuICAgIH1cbiAgfVxuXG4gIHZhciBtZXJnZU1hcCA9IHtcbiAgICAndXJsJzogdmFsdWVGcm9tQ29uZmlnMixcbiAgICAnbWV0aG9kJzogdmFsdWVGcm9tQ29uZmlnMixcbiAgICAnZGF0YSc6IHZhbHVlRnJvbUNvbmZpZzIsXG4gICAgJ2Jhc2VVUkwnOiBkZWZhdWx0VG9Db25maWcyLFxuICAgICd0cmFuc2Zvcm1SZXF1ZXN0JzogZGVmYXVsdFRvQ29uZmlnMixcbiAgICAndHJhbnNmb3JtUmVzcG9uc2UnOiBkZWZhdWx0VG9Db25maWcyLFxuICAgICdwYXJhbXNTZXJpYWxpemVyJzogZGVmYXVsdFRvQ29uZmlnMixcbiAgICAndGltZW91dCc6IGRlZmF1bHRUb0NvbmZpZzIsXG4gICAgJ3RpbWVvdXRNZXNzYWdlJzogZGVmYXVsdFRvQ29uZmlnMixcbiAgICAnd2l0aENyZWRlbnRpYWxzJzogZGVmYXVsdFRvQ29uZmlnMixcbiAgICAnYWRhcHRlcic6IGRlZmF1bHRUb0NvbmZpZzIsXG4gICAgJ3Jlc3BvbnNlVHlwZSc6IGRlZmF1bHRUb0NvbmZpZzIsXG4gICAgJ3hzcmZDb29raWVOYW1lJzogZGVmYXVsdFRvQ29uZmlnMixcbiAgICAneHNyZkhlYWRlck5hbWUnOiBkZWZhdWx0VG9Db25maWcyLFxuICAgICdvblVwbG9hZFByb2dyZXNzJzogZGVmYXVsdFRvQ29uZmlnMixcbiAgICAnb25Eb3dubG9hZFByb2dyZXNzJzogZGVmYXVsdFRvQ29uZmlnMixcbiAgICAnZGVjb21wcmVzcyc6IGRlZmF1bHRUb0NvbmZpZzIsXG4gICAgJ21heENvbnRlbnRMZW5ndGgnOiBkZWZhdWx0VG9Db25maWcyLFxuICAgICdtYXhCb2R5TGVuZ3RoJzogZGVmYXVsdFRvQ29uZmlnMixcbiAgICAnYmVmb3JlUmVkaXJlY3QnOiBkZWZhdWx0VG9Db25maWcyLFxuICAgICd0cmFuc3BvcnQnOiBkZWZhdWx0VG9Db25maWcyLFxuICAgICdodHRwQWdlbnQnOiBkZWZhdWx0VG9Db25maWcyLFxuICAgICdodHRwc0FnZW50JzogZGVmYXVsdFRvQ29uZmlnMixcbiAgICAnY2FuY2VsVG9rZW4nOiBkZWZhdWx0VG9Db25maWcyLFxuICAgICdzb2NrZXRQYXRoJzogZGVmYXVsdFRvQ29uZmlnMixcbiAgICAncmVzcG9uc2VFbmNvZGluZyc6IGRlZmF1bHRUb0NvbmZpZzIsXG4gICAgJ3ZhbGlkYXRlU3RhdHVzJzogbWVyZ2VEaXJlY3RLZXlzXG4gIH07XG5cbiAgdXRpbHMuZm9yRWFjaChPYmplY3Qua2V5cyhjb25maWcxKS5jb25jYXQoT2JqZWN0LmtleXMoY29uZmlnMikpLCBmdW5jdGlvbiBjb21wdXRlQ29uZmlnVmFsdWUocHJvcCkge1xuICAgIHZhciBtZXJnZSA9IG1lcmdlTWFwW3Byb3BdIHx8IG1lcmdlRGVlcFByb3BlcnRpZXM7XG4gICAgdmFyIGNvbmZpZ1ZhbHVlID0gbWVyZ2UocHJvcCk7XG4gICAgKHV0aWxzLmlzVW5kZWZpbmVkKGNvbmZpZ1ZhbHVlKSAmJiBtZXJnZSAhPT0gbWVyZ2VEaXJlY3RLZXlzKSB8fCAoY29uZmlnW3Byb3BdID0gY29uZmlnVmFsdWUpO1xuICB9KTtcblxuICByZXR1cm4gY29uZmlnO1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/axios/lib/core/mergeConfig.js\n");
/***/ }),
/***/ "./node_modules/axios/lib/core/settle.js":
/*!***********************************************!*\
!*** ./node_modules/axios/lib/core/settle.js ***!
\***********************************************/
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict";
eval("\n\nvar AxiosError = __webpack_require__(/*! ./AxiosError */ \"./node_modules/axios/lib/core/AxiosError.js\");\n\n/**\n * Resolve or reject a Promise based on response status.\n *\n * @param {Function} resolve A function that resolves the promise.\n * @param {Function} reject A function that rejects the promise.\n * @param {object} response The response.\n */\nmodule.exports = function settle(resolve, reject, response) {\n var validateStatus = response.config.validateStatus;\n if (!response.status || !validateStatus || validateStatus(response.status)) {\n resolve(response);\n } else {\n reject(new AxiosError(\n 'Request failed with status code ' + response.status,\n [AxiosError.ERR_BAD_REQUEST, AxiosError.ERR_BAD_RESPONSE][Math.floor(response.status / 100) - 4],\n response.config,\n response.request,\n response\n ));\n }\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2NvcmUvc2V0dGxlLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLGlCQUFpQixtQkFBTyxDQUFDLGlFQUFjOztBQUV2QztBQUNBO0FBQ0E7QUFDQSxXQUFXLFVBQVU7QUFDckIsV0FBVyxVQUFVO0FBQ3JCLFdBQVcsUUFBUTtBQUNuQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9heGlvcy9saWIvY29yZS9zZXR0bGUuanM/ODc2OCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciBBeGlvc0Vycm9yID0gcmVxdWlyZSgnLi9BeGlvc0Vycm9yJyk7XG5cbi8qKlxuICogUmVzb2x2ZSBvciByZWplY3QgYSBQcm9taXNlIGJhc2VkIG9uIHJlc3BvbnNlIHN0YXR1cy5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSByZXNvbHZlIEEgZnVuY3Rpb24gdGhhdCByZXNvbHZlcyB0aGUgcHJvbWlzZS5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IHJlamVjdCBBIGZ1bmN0aW9uIHRoYXQgcmVqZWN0cyB0aGUgcHJvbWlzZS5cbiAqIEBwYXJhbSB7b2JqZWN0fSByZXNwb25zZSBUaGUgcmVzcG9uc2UuXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gc2V0dGxlKHJlc29sdmUsIHJlamVjdCwgcmVzcG9uc2UpIHtcbiAgdmFyIHZhbGlkYXRlU3RhdHVzID0gcmVzcG9uc2UuY29uZmlnLnZhbGlkYXRlU3RhdHVzO1xuICBpZiAoIXJlc3BvbnNlLnN0YXR1cyB8fCAhdmFsaWRhdGVTdGF0dXMgfHwgdmFsaWRhdGVTdGF0dXMocmVzcG9uc2Uuc3RhdHVzKSkge1xuICAgIHJlc29sdmUocmVzcG9uc2UpO1xuICB9IGVsc2Uge1xuICAgIHJlamVjdChuZXcgQXhpb3NFcnJvcihcbiAgICAgICdSZXF1ZXN0IGZhaWxlZCB3aXRoIHN0YXR1cyBjb2RlICcgKyByZXNwb25zZS5zdGF0dXMsXG4gICAgICBbQXhpb3NFcnJvci5FUlJfQkFEX1JFUVVFU1QsIEF4aW9zRXJyb3IuRVJSX0JBRF9SRVNQT05TRV1bTWF0aC5mbG9vcihyZXNwb25zZS5zdGF0dXMgLyAxMDApIC0gNF0sXG4gICAgICByZXNwb25zZS5jb25maWcsXG4gICAgICByZXNwb25zZS5yZXF1ZXN0LFxuICAgICAgcmVzcG9uc2VcbiAgICApKTtcbiAgfVxufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/axios/lib/core/settle.js\n");
/***/ }),
/***/ "./node_modules/axios/lib/core/transformData.js":
/*!******************************************************!*\
!*** ./node_modules/axios/lib/core/transformData.js ***!
\******************************************************/
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict";
eval("\n\nvar utils = __webpack_require__(/*! ./../utils */ \"./node_modules/axios/lib/utils.js\");\nvar defaults = __webpack_require__(/*! ../defaults */ \"./node_modules/axios/lib/defaults/index.js\");\n\n/**\n * Transform the data for a request or a response\n *\n * @param {Object|String} data The data to be transformed\n * @param {Array} headers The headers for the request or response\n * @param {Array|Function} fns A single function or Array of functions\n * @returns {*} The resulting transformed data\n */\nmodule.exports = function transformData(data, headers, fns) {\n var context = this || defaults;\n /*eslint no-param-reassign:0*/\n utils.forEach(fns, function transform(fn) {\n data = fn.call(context, data, headers);\n });\n\n return data;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2NvcmUvdHJhbnNmb3JtRGF0YS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixZQUFZLG1CQUFPLENBQUMscURBQVk7QUFDaEMsZUFBZSxtQkFBTyxDQUFDLCtEQUFhOztBQUVwQztBQUNBO0FBQ0E7QUFDQSxXQUFXLGVBQWU7QUFDMUIsV0FBVyxPQUFPO0FBQ2xCLFdBQVcsZ0JBQWdCO0FBQzNCLGFBQWEsR0FBRztBQUNoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2NvcmUvdHJhbnNmb3JtRGF0YS5qcz83NjYyIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi8uLi91dGlscycpO1xudmFyIGRlZmF1bHRzID0gcmVxdWlyZSgnLi4vZGVmYXVsdHMnKTtcblxuLyoqXG4gKiBUcmFuc2Zvcm0gdGhlIGRhdGEgZm9yIGEgcmVxdWVzdCBvciBhIHJlc3BvbnNlXG4gKlxuICogQHBhcmFtIHtPYmplY3R8U3RyaW5nfSBkYXRhIFRoZSBkYXRhIHRvIGJlIHRyYW5zZm9ybWVkXG4gKiBAcGFyYW0ge0FycmF5fSBoZWFkZXJzIFRoZSBoZWFkZXJzIGZvciB0aGUgcmVxdWVzdCBvciByZXNwb25zZVxuICogQHBhcmFtIHtBcnJheXxGdW5jdGlvbn0gZm5zIEEgc2luZ2xlIGZ1bmN0aW9uIG9yIEFycmF5IG9mIGZ1bmN0aW9uc1xuICogQHJldHVybnMgeyp9IFRoZSByZXN1bHRpbmcgdHJhbnNmb3JtZWQgZGF0YVxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHRyYW5zZm9ybURhdGEoZGF0YSwgaGVhZGVycywgZm5zKSB7XG4gIHZhciBjb250ZXh0ID0gdGhpcyB8fCBkZWZhdWx0cztcbiAgLyplc2xpbnQgbm8tcGFyYW0tcmVhc3NpZ246MCovXG4gIHV0aWxzLmZvckVhY2goZm5zLCBmdW5jdGlvbiB0cmFuc2Zvcm0oZm4pIHtcbiAgICBkYXRhID0gZm4uY2FsbChjb250ZXh0LCBkYXRhLCBoZWFkZXJzKTtcbiAgfSk7XG5cbiAgcmV0dXJuIGRhdGE7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/axios/lib/core/transformData.js\n");
/***/ }),
/***/ "./node_modules/axios/lib/defaults/index.js":
/*!**************************************************!*\
!*** ./node_modules/axios/lib/defaults/index.js ***!
\**************************************************/
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict";
eval("/* provided dependency */ var process = __webpack_require__(/*! process/browser.js */ \"./node_modules/process/browser.js\");\n\n\nvar utils = __webpack_require__(/*! ../utils */ \"./node_modules/axios/lib/utils.js\");\nvar normalizeHeaderName = __webpack_require__(/*! ../helpers/normalizeHeaderName */ \"./node_modules/axios/lib/helpers/normalizeHeaderName.js\");\nvar AxiosError = __webpack_require__(/*! ../core/AxiosError */ \"./node_modules/axios/lib/core/AxiosError.js\");\nvar transitionalDefaults = __webpack_require__(/*! ./transitional */ \"./node_modules/axios/lib/defaults/transitional.js\");\nvar toFormData = __webpack_require__(/*! ../helpers/toFormData */ \"./node_modules/axios/lib/helpers/toFormData.js\");\n\nvar DEFAULT_CONTENT_TYPE = {\n 'Content-Type': 'application/x-www-form-urlencoded'\n};\n\nfunction setContentTypeIfUnset(headers, value) {\n if (!utils.isUndefined(headers) && utils.isUndefined(headers['Content-Type'])) {\n headers['Content-Type'] = value;\n }\n}\n\nfunction getDefaultAdapter() {\n var adapter;\n if (typeof XMLHttpRequest !== 'undefined') {\n // For browsers use XHR adapter\n adapter = __webpack_require__(/*! ../adapters/xhr */ \"./node_modules/axios/lib/adapters/xhr.js\");\n } else if (typeof process !== 'undefined' && Object.prototype.toString.call(process) === '[object process]') {\n // For node use HTTP adapter\n adapter = __webpack_require__(/*! ../adapters/http */ \"./node_modules/axios/lib/adapters/xhr.js\");\n }\n return adapter;\n}\n\nfunction stringifySafely(rawValue, parser, encoder) {\n if (utils.isString(rawValue)) {\n try {\n (parser || JSON.parse)(rawValue);\n return utils.trim(rawValue);\n } catch (e) {\n if (e.name !== 'SyntaxError') {\n throw e;\n }\n }\n }\n\n return (encoder || JSON.stringify)(rawValue);\n}\n\nvar defaults = {\n\n transitional: transitionalDefaults,\n\n adapter: getDefaultAdapter(),\n\n transformRequest: [function transformRequest(data, headers) {\n normalizeHeaderName(headers, 'Accept');\n normalizeHeaderName(headers, 'Content-Type');\n\n if (utils.isFormData(data) ||\n utils.isArrayBuffer(data) ||\n utils.isBuffer(data) ||\n utils.isStream(data) ||\n utils.isFile(data) ||\n utils.isBlob(data)\n ) {\n return data;\n }\n if (utils.isArrayBufferView(data)) {\n return data.buffer;\n }\n if (utils.isURLSearchParams(data)) {\n setContentTypeIfUnset(headers, 'application/x-www-form-urlencoded;charset=utf-8');\n return data.toString();\n }\n\n var isObjectPayload = utils.isObject(data);\n var contentType = headers && headers['Content-Type'];\n\n var isFileList;\n\n if ((isFileList = utils.isFileList(data)) || (isObjectPayload && contentType === 'multipart/form-data')) {\n var _FormData = this.env && this.env.FormData;\n return toFormData(isFileList ? {'files[]': data} : data, _FormData && new _FormData());\n } else if (isObjectPayload || contentType === 'application/json') {\n setContentTypeIfUnset(headers, 'application/json');\n return stringifySafely(data);\n }\n\n return data;\n }],\n\n transformResponse: [function transformResponse(data) {\n var transitional = this.transitional || defaults.transitional;\n var silentJSONParsing = transitional && transitional.silentJSONParsing;\n var forcedJSONParsing = transitional && transitional.forcedJSONParsing;\n var strictJSONParsing = !silentJSONParsing && this.responseType === 'json';\n\n if (strictJSONParsing || (forcedJSONParsing && utils.isString(data) && data.length)) {\n try {\n return JSON.parse(data);\n } catch (e) {\n if (strictJSONParsing) {\n if (e.name === 'SyntaxError') {\n throw AxiosError.from(e, AxiosError.ERR_BAD_RESPONSE, this, null, this.response);\n }\n throw e;\n }\n }\n }\n\n return data;\n }],\n\n /**\n * A timeout in milliseconds to abort a request. If set to 0 (default) a\n * timeout is not created.\n */\n timeout: 0,\n\n xsrfCookieName: 'XSRF-TOKEN',\n xsrfHeaderName: 'X-XSRF-TOKEN',\n\n maxContentLength: -1,\n maxBodyLength: -1,\n\n env: {\n FormData: __webpack_require__(/*! ./env/FormData */ \"./node_modules/axios/lib/helpers/null.js\")\n },\n\n validateStatus: function validateStatus(status) {\n return status >= 200 && status < 300;\n },\n\n headers: {\n common: {\n 'Accept': 'application/json, text/plain, */*'\n }\n }\n};\n\nutils.forEach(['delete', 'get', 'head'], function forEachMethodNoData(method) {\n defaults.headers[method] = {};\n});\n\nutils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {\n defaults.headers[method] = utils.merge(DEFAULT_CONTENT_TYPE);\n});\n\nmodule.exports = defaults;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2RlZmF1bHRzL2luZGV4LmpzIiwibWFwcGluZ3MiOiI7QUFBYTs7QUFFYixZQUFZLG1CQUFPLENBQUMsbURBQVU7QUFDOUIsMEJBQTBCLG1CQUFPLENBQUMsK0ZBQWdDO0FBQ2xFLGlCQUFpQixtQkFBTyxDQUFDLHVFQUFvQjtBQUM3QywyQkFBMkIsbUJBQU8sQ0FBQyx5RUFBZ0I7QUFDbkQsaUJBQWlCLG1CQUFPLENBQUMsNkVBQXVCOztBQUVoRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWMsbUJBQU8sQ0FBQyxpRUFBaUI7QUFDdkMsSUFBSSxnQkFBZ0IsT0FBTyxtREFBbUQsT0FBTztBQUNyRjtBQUNBLGNBQWMsbUJBQU8sQ0FBQyxrRUFBa0I7QUFDeEM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdFQUF3RTtBQUN4RTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLHNDQUFzQyxpQkFBaUI7QUFDdkQsTUFBTTtBQUNOO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxjQUFjLG1CQUFPLENBQUMsZ0VBQWdCO0FBQ3RDLEdBQUc7O0FBRUg7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQSxDQUFDOztBQUVEIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL2F4aW9zL2xpYi9kZWZhdWx0cy9pbmRleC5qcz9mZjEwIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKTtcbnZhciBub3JtYWxpemVIZWFkZXJOYW1lID0gcmVxdWlyZSgnLi4vaGVscGVycy9ub3JtYWxpemVIZWFkZXJOYW1lJyk7XG52YXIgQXhpb3NFcnJvciA9IHJlcXVpcmUoJy4uL2NvcmUvQXhpb3NFcnJvcicpO1xudmFyIHRyYW5zaXRpb25hbERlZmF1bHRzID0gcmVxdWlyZSgnLi90cmFuc2l0aW9uYWwnKTtcbnZhciB0b0Zvcm1EYXRhID0gcmVxdWlyZSgnLi4vaGVscGVycy90b0Zvcm1EYXRhJyk7XG5cbnZhciBERUZBVUxUX0NPTlRFTlRfVFlQRSA9IHtcbiAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnXG59O1xuXG5mdW5jdGlvbiBzZXRDb250ZW50VHlwZUlmVW5zZXQoaGVhZGVycywgdmFsdWUpIHtcbiAgaWYgKCF1dGlscy5pc1VuZGVmaW5lZChoZWFkZXJzKSAmJiB1dGlscy5pc1VuZGVmaW5lZChoZWFkZXJzWydDb250ZW50LVR5cGUnXSkpIHtcbiAgICBoZWFkZXJzWydDb250ZW50LVR5cGUnXSA9IHZhbHVlO1xuICB9XG59XG5cbmZ1bmN0aW9uIGdldERlZmF1bHRBZGFwdGVyKCkge1xuICB2YXIgYWRhcHRlcjtcbiAgaWYgKHR5cGVvZiBYTUxIdHRwUmVxdWVzdCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAvLyBGb3IgYnJvd3NlcnMgdXNlIFhIUiBhZGFwdGVyXG4gICAgYWRhcHRlciA9IHJlcXVpcmUoJy4uL2FkYXB0ZXJzL3hocicpO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBwcm9jZXNzICE9PSAndW5kZWZpbmVkJyAmJiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwocHJvY2VzcykgPT09ICdbb2JqZWN0IHByb2Nlc3NdJykge1xuICAgIC8vIEZvciBub2RlIHVzZSBIVFRQIGFkYXB0ZXJcbiAgICBhZGFwdGVyID0gcmVxdWlyZSgnLi4vYWRhcHRlcnMvaHR0cCcpO1xuICB9XG4gIHJldHVybiBhZGFwdGVyO1xufVxuXG5mdW5jdGlvbiBzdHJpbmdpZnlTYWZlbHkocmF3VmFsdWUsIHBhcnNlciwgZW5jb2Rlcikge1xuICBpZiAodXRpbHMuaXNTdHJpbmcocmF3VmFsdWUpKSB7XG4gICAgdHJ5IHtcbiAgICAgIChwYXJzZXIgfHwgSlNPTi5wYXJzZSkocmF3VmFsdWUpO1xuICAgICAgcmV0dXJuIHV0aWxzLnRyaW0ocmF3VmFsdWUpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGlmIChlLm5hbWUgIT09ICdTeW50YXhFcnJvcicpIHtcbiAgICAgICAgdGhyb3cgZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gKGVuY29kZXIgfHwgSlNPTi5zdHJpbmdpZnkpKHJhd1ZhbHVlKTtcbn1cblxudmFyIGRlZmF1bHRzID0ge1xuXG4gIHRyYW5zaXRpb25hbDogdHJhbnNpdGlvbmFsRGVmYXVsdHMsXG5cbiAgYWRhcHRlcjogZ2V0RGVmYXVsdEFkYXB0ZXIoKSxcblxuICB0cmFuc2Zvcm1SZXF1ZXN0OiBbZnVuY3Rpb24gdHJhbnNmb3JtUmVxdWVzdChkYXRhLCBoZWFkZXJzKSB7XG4gICAgbm9ybWFsaXplSGVhZGVyTmFtZShoZWFkZXJzLCAnQWNjZXB0Jyk7XG4gICAgbm9ybWFsaXplSGVhZGVyTmFtZShoZWFkZXJzLCAnQ29udGVudC1UeXBlJyk7XG5cbiAgICBpZiAodXRpbHMuaXNGb3JtRGF0YShkYXRhKSB8fFxuICAgICAgdXRpbHMuaXNBcnJheUJ1ZmZlcihkYXRhKSB8fFxuICAgICAgdXRpbHMuaXNCdWZmZXIoZGF0YSkgfHxcbiAgICAgIHV0aWxzLmlzU3RyZWFtKGRhdGEpIHx8XG4gICAgICB1dGlscy5pc0ZpbGUoZGF0YSkgfHxcbiAgICAgIHV0aWxzLmlzQmxvYihkYXRhKVxuICAgICkge1xuICAgICAgcmV0dXJuIGRhdGE7XG4gICAgfVxuICAgIGlmICh1dGlscy5pc0FycmF5QnVmZmVyVmlldyhkYXRhKSkge1xuICAgICAgcmV0dXJuIGRhdGEuYnVmZmVyO1xuICAgIH1cbiAgICBpZiAodXRpbHMuaXNVUkxTZWFyY2hQYXJhbXMoZGF0YSkpIHtcbiAgICAgIHNldENvbnRlbnRUeXBlSWZVbnNldChoZWFkZXJzLCAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkO2NoYXJzZXQ9dXRmLTgnKTtcbiAgICAgIHJldHVybiBkYXRhLnRvU3RyaW5nKCk7XG4gICAgfVxuXG4gICAgdmFyIGlzT2JqZWN0UGF5bG9hZCA9IHV0aWxzLmlzT2JqZWN0KGRhdGEpO1xuICAgIHZhciBjb250ZW50VHlwZSA9IGhlYWRlcnMgJiYgaGVhZGVyc1snQ29udGVudC1UeXBlJ107XG5cbiAgICB2YXIgaXNGaWxlTGlzdDtcblxuICAgIGlmICgoaXNGaWxlTGlzdCA9IHV0aWxzLmlzRmlsZUxpc3QoZGF0YSkpIHx8IChpc09iamVjdFBheWxvYWQgJiYgY29udGVudFR5cGUgPT09ICdtdWx0aXBhcnQvZm9ybS1kYXRhJykpIHtcbiAgICAgIHZhciBfRm9ybURhdGEgPSB0aGlzLmVudiAmJiB0aGlzLmVudi5Gb3JtRGF0YTtcbiAgICAgIHJldHVybiB0b0Zvcm1EYXRhKGlzRmlsZUxpc3QgPyB7J2ZpbGVzW10nOiBkYXRhfSA6IGRhdGEsIF9Gb3JtRGF0YSAmJiBuZXcgX0Zvcm1EYXRhKCkpO1xuICAgIH0gZWxzZSBpZiAoaXNPYmplY3RQYXlsb2FkIHx8IGNvbnRlbnRUeXBlID09PSAnYXBwbGljYXRpb24vanNvbicpIHtcbiAgICAgIHNldENvbnRlbnRUeXBlSWZVbnNldChoZWFkZXJzLCAnYXBwbGljYXRpb24vanNvbicpO1xuICAgICAgcmV0dXJuIHN0cmluZ2lmeVNhZmVseShkYXRhKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZGF0YTtcbiAgfV0sXG5cbiAgdHJhbnNmb3JtUmVzcG9uc2U6IFtmdW5jdGlvbiB0cmFuc2Zvcm1SZXNwb25zZShkYXRhKSB7XG4gICAgdmFyIHRyYW5zaXRpb25hbCA9IHRoaXMudHJhbnNpdGlvbmFsIHx8IGRlZmF1bHRzLnRyYW5zaXRpb25hbDtcbiAgICB2YXIgc2lsZW50SlNPTlBhcnNpbmcgPSB0cmFuc2l0aW9uYWwgJiYgdHJhbnNpdGlvbmFsLnNpbGVudEpTT05QYXJzaW5nO1xuICAgIHZhciBmb3JjZWRKU09OUGFyc2luZyA9IHRyYW5zaXRpb25hbCAmJiB0cmFuc2l0aW9uYWwuZm9yY2VkSlNPTlBhcnNpbmc7XG4gICAgdmFyIHN0cmljdEpTT05QYXJzaW5nID0gIXNpbGVudEpTT05QYXJzaW5nICYmIHRoaXMucmVzcG9uc2VUeXBlID09PSAnanNvbic7XG5cbiAgICBpZiAoc3RyaWN0SlNPTlBhcnNpbmcgfHwgKGZvcmNlZEpTT05QYXJzaW5nICYmIHV0aWxzLmlzU3RyaW5nKGRhdGEpICYmIGRhdGEubGVuZ3RoKSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIEpTT04ucGFyc2UoZGF0YSk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGlmIChzdHJpY3RKU09OUGFyc2luZykge1xuICAgICAgICAgIGlmIChlLm5hbWUgPT09ICdTeW50YXhFcnJvcicpIHtcbiAgICAgICAgICAgIHRocm93IEF4aW9zRXJyb3IuZnJvbShlLCBBeGlvc0Vycm9yLkVSUl9CQURfUkVTUE9OU0UsIHRoaXMsIG51bGwsIHRoaXMucmVzcG9uc2UpO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGRhdGE7XG4gIH1dLFxuXG4gIC8qKlxuICAgKiBBIHRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzIHRvIGFib3J0IGEgcmVxdWVzdC4gSWYgc2V0IHRvIDAgKGRlZmF1bHQpIGFcbiAgICogdGltZW91dCBpcyBub3QgY3JlYXRlZC5cbiAgICovXG4gIHRpbWVvdXQ6IDAsXG5cbiAgeHNyZkNvb2tpZU5hbWU6ICdYU1JGLVRPS0VOJyxcbiAgeHNyZkhlYWRlck5hbWU6ICdYLVhTUkYtVE9LRU4nLFxuXG4gIG1heENvbnRlbnRMZW5ndGg6IC0xLFxuICBtYXhCb2R5TGVuZ3RoOiAtMSxcblxuICBlbnY6IHtcbiAgICBGb3JtRGF0YTogcmVxdWlyZSgnLi9lbnYvRm9ybURhdGEnKVxuICB9LFxuXG4gIHZhbGlkYXRlU3RhdHVzOiBmdW5jdGlvbiB2YWxpZGF0ZVN0YXR1cyhzdGF0dXMpIHtcbiAgICByZXR1cm4gc3RhdHVzID49IDIwMCAmJiBzdGF0dXMgPCAzMDA7XG4gIH0sXG5cbiAgaGVhZGVyczoge1xuICAgIGNvbW1vbjoge1xuICAgICAgJ0FjY2VwdCc6ICdhcHBsaWNhdGlvbi9qc29uLCB0ZXh0L3BsYWluLCAqLyonXG4gICAgfVxuICB9XG59O1xuXG51dGlscy5mb3JFYWNoKFsnZGVsZXRlJywgJ2dldCcsICdoZWFkJ10sIGZ1bmN0aW9uIGZvckVhY2hNZXRob2ROb0RhdGEobWV0aG9kKSB7XG4gIGRlZmF1bHRzLmhlYWRlcnNbbWV0aG9kXSA9IHt9O1xufSk7XG5cbnV0aWxzLmZvckVhY2goWydwb3N0JywgJ3B1dCcsICdwYXRjaCddLCBmdW5jdGlvbiBmb3JFYWNoTWV0aG9kV2l0aERhdGEobWV0aG9kKSB7XG4gIGRlZmF1bHRzLmhlYWRlcnNbbWV0aG9kXSA9IHV0aWxzLm1lcmdlKERFRkFVTFRfQ09OVEVOVF9UWVBFKTtcbn0pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGRlZmF1bHRzO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/axios/lib/defaults/index.js\n");
/***/ }),
/***/ "./node_modules/axios/lib/defaults/transitional.js":
/*!*********************************************************!*\
!*** ./node_modules/axios/lib/defaults/transitional.js ***!
\*********************************************************/
/***/ ((module) => {
"use strict";
eval("\n\nmodule.exports = {\n silentJSONParsing: true,\n forcedJSONParsing: true,\n clarifyTimeoutError: false\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2RlZmF1bHRzL3RyYW5zaXRpb25hbC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL2F4aW9zL2xpYi9kZWZhdWx0cy90cmFuc2l0aW9uYWwuanM/MjdhNCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBzaWxlbnRKU09OUGFyc2luZzogdHJ1ZSxcbiAgZm9yY2VkSlNPTlBhcnNpbmc6IHRydWUsXG4gIGNsYXJpZnlUaW1lb3V0RXJyb3I6IGZhbHNlXG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/axios/lib/defaults/transitional.js\n");
/***/ }),
/***/ "./node_modules/axios/lib/env/data.js":
/*!********************************************!*\
!*** ./node_modules/axios/lib/env/data.js ***!
\********************************************/
/***/ ((module) => {
eval("module.exports = {\n \"version\": \"0.27.2\"\n};//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2Vudi9kYXRhLmpzIiwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9heGlvcy9saWIvZW52L2RhdGEuanM/MTEwZiJdLCJzb3VyY2VzQ29udGVudCI6WyJtb2R1bGUuZXhwb3J0cyA9IHtcbiAgXCJ2ZXJzaW9uXCI6IFwiMC4yNy4yXCJcbn07Il0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/axios/lib/env/data.js\n");
/***/ }),
/***/ "./node_modules/axios/lib/helpers/bind.js":
/*!************************************************!*\
!*** ./node_modules/axios/lib/helpers/bind.js ***!
\************************************************/
/***/ ((module) => {
"use strict";
eval("\n\nmodule.exports = function bind(fn, thisArg) {\n return function wrap() {\n var args = new Array(arguments.length);\n for (var i = 0; i < args.length; i++) {\n args[i] = arguments[i];\n }\n return fn.apply(thisArg, args);\n };\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2hlbHBlcnMvYmluZC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0E7QUFDQSxvQkFBb0IsaUJBQWlCO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2hlbHBlcnMvYmluZC5qcz80YmVhIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBiaW5kKGZuLCB0aGlzQXJnKSB7XG4gIHJldHVybiBmdW5jdGlvbiB3cmFwKCkge1xuICAgIHZhciBhcmdzID0gbmV3IEFycmF5KGFyZ3VtZW50cy5sZW5ndGgpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJncy5sZW5ndGg7IGkrKykge1xuICAgICAgYXJnc1tpXSA9IGFyZ3VtZW50c1tpXTtcbiAgICB9XG4gICAgcmV0dXJuIGZuLmFwcGx5KHRoaXNBcmcsIGFyZ3MpO1xuICB9O1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/axios/lib/helpers/bind.js\n");
/***/ }),
/***/ "./node_modules/axios/lib/helpers/buildURL.js":
/*!****************************************************!*\
!*** ./node_modules/axios/lib/helpers/buildURL.js ***!
\****************************************************/
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict";
eval("\n\nvar utils = __webpack_require__(/*! ./../utils */ \"./node_modules/axios/lib/utils.js\");\n\nfunction encode(val) {\n return encodeURIComponent(val).\n replace(/%3A/gi, ':').\n replace(/%24/g, '$').\n replace(/%2C/gi, ',').\n replace(/%20/g, '+').\n replace(/%5B/gi, '[').\n replace(/%5D/gi, ']');\n}\n\n/**\n * Build a URL by appending params to the end\n *\n * @param {string} url The base of the url (e.g., http://www.google.com)\n * @param {object} [params] The params to be appended\n * @returns {string} The formatted url\n */\nmodule.exports = function buildURL(url, params, paramsSerializer) {\n /*eslint no-param-reassign:0*/\n if (!params) {\n return url;\n }\n\n var serializedParams;\n if (paramsSerializer) {\n serializedParams = paramsSerializer(params);\n } else if (utils.isURLSearchParams(params)) {\n serializedParams = params.toString();\n } else {\n var parts = [];\n\n utils.forEach(params, function serialize(val, key) {\n if (val === null || typeof val === 'undefined') {\n return;\n }\n\n if (utils.isArray(val)) {\n key = key + '[]';\n } else {\n val = [val];\n }\n\n utils.forEach(val, function parseValue(v) {\n if (utils.isDate(v)) {\n v = v.toISOString();\n } else if (utils.isObject(v)) {\n v = JSON.stringify(v);\n }\n parts.push(encode(key) + '=' + encode(v));\n });\n });\n\n serializedParams = parts.join('&');\n }\n\n if (serializedParams) {\n var hashmarkIndex = url.indexOf('#');\n if (hashmarkIndex !== -1) {\n url = url.slice(0, hashmarkIndex);\n }\n\n url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams;\n }\n\n return url;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2hlbHBlcnMvYnVpbGRVUkwuanMiLCJtYXBwaW5ncyI6IkFBQWE7O0FBRWIsWUFBWSxtQkFBTyxDQUFDLHFEQUFZOztBQUVoQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsV0FBVyxRQUFRO0FBQ25CLFdBQVcsUUFBUTtBQUNuQixhQUFhLFFBQVE7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBLElBQUk7QUFDSjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUCxLQUFLOztBQUVMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2hlbHBlcnMvYnVpbGRVUkwuanM/YzE3OCJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4vLi4vdXRpbHMnKTtcblxuZnVuY3Rpb24gZW5jb2RlKHZhbCkge1xuICByZXR1cm4gZW5jb2RlVVJJQ29tcG9uZW50KHZhbCkuXG4gICAgcmVwbGFjZSgvJTNBL2dpLCAnOicpLlxuICAgIHJlcGxhY2UoLyUyNC9nLCAnJCcpLlxuICAgIHJlcGxhY2UoLyUyQy9naSwgJywnKS5cbiAgICByZXBsYWNlKC8lMjAvZywgJysnKS5cbiAgICByZXBsYWNlKC8lNUIvZ2ksICdbJykuXG4gICAgcmVwbGFjZSgvJTVEL2dpLCAnXScpO1xufVxuXG4vKipcbiAqIEJ1aWxkIGEgVVJMIGJ5IGFwcGVuZGluZyBwYXJhbXMgdG8gdGhlIGVuZFxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB1cmwgVGhlIGJhc2Ugb2YgdGhlIHVybCAoZS5nLiwgaHR0cDovL3d3dy5nb29nbGUuY29tKVxuICogQHBhcmFtIHtvYmplY3R9IFtwYXJhbXNdIFRoZSBwYXJhbXMgdG8gYmUgYXBwZW5kZWRcbiAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBmb3JtYXR0ZWQgdXJsXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gYnVpbGRVUkwodXJsLCBwYXJhbXMsIHBhcmFtc1NlcmlhbGl6ZXIpIHtcbiAgLyplc2xpbnQgbm8tcGFyYW0tcmVhc3NpZ246MCovXG4gIGlmICghcGFyYW1zKSB7XG4gICAgcmV0dXJuIHVybDtcbiAgfVxuXG4gIHZhciBzZXJpYWxpemVkUGFyYW1zO1xuICBpZiAocGFyYW1zU2VyaWFsaXplcikge1xuICAgIHNlcmlhbGl6ZWRQYXJhbXMgPSBwYXJhbXNTZXJpYWxpemVyKHBhcmFtcyk7XG4gIH0gZWxzZSBpZiAodXRpbHMuaXNVUkxTZWFyY2hQYXJhbXMocGFyYW1zKSkge1xuICAgIHNlcmlhbGl6ZWRQYXJhbXMgPSBwYXJhbXMudG9TdHJpbmcoKTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgcGFydHMgPSBbXTtcblxuICAgIHV0aWxzLmZvckVhY2gocGFyYW1zLCBmdW5jdGlvbiBzZXJpYWxpemUodmFsLCBrZXkpIHtcbiAgICAgIGlmICh2YWwgPT09IG51bGwgfHwgdHlwZW9mIHZhbCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAodXRpbHMuaXNBcnJheSh2YWwpKSB7XG4gICAgICAgIGtleSA9IGtleSArICdbXSc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YWwgPSBbdmFsXTtcbiAgICAgIH1cblxuICAgICAgdXRpbHMuZm9yRWFjaCh2YWwsIGZ1bmN0aW9uIHBhcnNlVmFsdWUodikge1xuICAgICAgICBpZiAodXRpbHMuaXNEYXRlKHYpKSB7XG4gICAgICAgICAgdiA9IHYudG9JU09TdHJpbmcoKTtcbiAgICAgICAgfSBlbHNlIGlmICh1dGlscy5pc09iamVjdCh2KSkge1xuICAgICAgICAgIHYgPSBKU09OLnN0cmluZ2lmeSh2KTtcbiAgICAgICAgfVxuICAgICAgICBwYXJ0cy5wdXNoKGVuY29kZShrZXkpICsgJz0nICsgZW5jb2RlKHYpKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgc2VyaWFsaXplZFBhcmFtcyA9IHBhcnRzLmpvaW4oJyYnKTtcbiAgfVxuXG4gIGlmIChzZXJpYWxpemVkUGFyYW1zKSB7XG4gICAgdmFyIGhhc2htYXJrSW5kZXggPSB1cmwuaW5kZXhPZignIycpO1xuICAgIGlmIChoYXNobWFya0luZGV4ICE9PSAtMSkge1xuICAgICAgdXJsID0gdXJsLnNsaWNlKDAsIGhhc2htYXJrSW5kZXgpO1xuICAgIH1cblxuICAgIHVybCArPSAodXJsLmluZGV4T2YoJz8nKSA9PT0gLTEgPyAnPycgOiAnJicpICsgc2VyaWFsaXplZFBhcmFtcztcbiAgfVxuXG4gIHJldHVybiB1cmw7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/axios/lib/helpers/buildURL.js\n");
/***/ }),
/***/ "./node_modules/axios/lib/helpers/combineURLs.js":
/*!*******************************************************!*\
!*** ./node_modules/axios/lib/helpers/combineURLs.js ***!
\*******************************************************/
/***/ ((module) => {
"use strict";
eval("\n\n/**\n * Creates a new URL by combining the specified URLs\n *\n * @param {string} baseURL The base URL\n * @param {string} relativeURL The relative URL\n * @returns {string} The combined URL\n */\nmodule.exports = function combineURLs(baseURL, relativeURL) {\n return relativeURL\n ? baseURL.replace(/\\/+$/, '') + '/' + relativeURL.replace(/^\\/+/, '')\n : baseURL;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2hlbHBlcnMvY29tYmluZVVSTHMuanMiLCJtYXBwaW5ncyI6IkFBQWE7O0FBRWI7QUFDQTtBQUNBO0FBQ0EsV0FBVyxRQUFRO0FBQ25CLFdBQVcsUUFBUTtBQUNuQixhQUFhLFFBQVE7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL2F4aW9zL2xpYi9oZWxwZXJzL2NvbWJpbmVVUkxzLmpzPzZiYzYiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgVVJMIGJ5IGNvbWJpbmluZyB0aGUgc3BlY2lmaWVkIFVSTHNcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gYmFzZVVSTCBUaGUgYmFzZSBVUkxcbiAqIEBwYXJhbSB7c3RyaW5nfSByZWxhdGl2ZVVSTCBUaGUgcmVsYXRpdmUgVVJMXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgY29tYmluZWQgVVJMXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gY29tYmluZVVSTHMoYmFzZVVSTCwgcmVsYXRpdmVVUkwpIHtcbiAgcmV0dXJuIHJlbGF0aXZlVVJMXG4gICAgPyBiYXNlVVJMLnJlcGxhY2UoL1xcLyskLywgJycpICsgJy8nICsgcmVsYXRpdmVVUkwucmVwbGFjZSgvXlxcLysvLCAnJylcbiAgICA6IGJhc2VVUkw7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/axios/lib/helpers/combineURLs.js\n");
/***/ }),
/***/ "./node_modules/axios/lib/helpers/cookies.js":
/*!***************************************************!*\
!*** ./node_modules/axios/lib/helpers/cookies.js ***!
\***************************************************/
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict";
eval("\n\nvar utils = __webpack_require__(/*! ./../utils */ \"./node_modules/axios/lib/utils.js\");\n\nmodule.exports = (\n utils.isStandardBrowserEnv() ?\n\n // Standard browser envs support document.cookie\n (function standardBrowserEnv() {\n return {\n write: function write(name, value, expires, path, domain, secure) {\n var cookie = [];\n cookie.push(name + '=' + encodeURIComponent(value));\n\n if (utils.isNumber(expires)) {\n cookie.push('expires=' + new Date(expires).toGMTString());\n }\n\n if (utils.isString(path)) {\n cookie.push('path=' + path);\n }\n\n if (utils.isString(domain)) {\n cookie.push('domain=' + domain);\n }\n\n if (secure === true) {\n cookie.push('secure');\n }\n\n document.cookie = cookie.join('; ');\n },\n\n read: function read(name) {\n var match = document.cookie.match(new RegExp('(^|;\\\\s*)(' + name + ')=([^;]*)'));\n return (match ? decodeURIComponent(match[3]) : null);\n },\n\n remove: function remove(name) {\n this.write(name, '', Date.now() - 86400000);\n }\n };\n })() :\n\n // Non standard browser env (web workers, react-native) lack needed support.\n (function nonStandardBrowserEnv() {\n return {\n write: function write() {},\n read: function read() { return null; },\n remove: function remove() {}\n };\n })()\n);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2hlbHBlcnMvY29va2llcy5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixZQUFZLG1CQUFPLENBQUMscURBQVk7O0FBRWhDO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSwyQ0FBMkM7QUFDM0MsU0FBUzs7QUFFVDtBQUNBLDREQUE0RCx3QkFBd0I7QUFDcEY7QUFDQSxTQUFTOztBQUVUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQSxrQ0FBa0M7QUFDbEMsZ0NBQWdDLGNBQWM7QUFDOUM7QUFDQTtBQUNBLEtBQUs7QUFDTCIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9heGlvcy9saWIvaGVscGVycy9jb29raWVzLmpzPzFkM2YiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLy4uL3V0aWxzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gKFxuICB1dGlscy5pc1N0YW5kYXJkQnJvd3NlckVudigpID9cblxuICAvLyBTdGFuZGFyZCBicm93c2VyIGVudnMgc3VwcG9ydCBkb2N1bWVudC5jb29raWVcbiAgICAoZnVuY3Rpb24gc3RhbmRhcmRCcm93c2VyRW52KCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgd3JpdGU6IGZ1bmN0aW9uIHdyaXRlKG5hbWUsIHZhbHVlLCBleHBpcmVzLCBwYXRoLCBkb21haW4sIHNlY3VyZSkge1xuICAgICAgICAgIHZhciBjb29raWUgPSBbXTtcbiAgICAgICAgICBjb29raWUucHVzaChuYW1lICsgJz0nICsgZW5jb2RlVVJJQ29tcG9uZW50KHZhbHVlKSk7XG5cbiAgICAgICAgICBpZiAodXRpbHMuaXNOdW1iZXIoZXhwaXJlcykpIHtcbiAgICAgICAgICAgIGNvb2tpZS5wdXNoKCdleHBpcmVzPScgKyBuZXcgRGF0ZShleHBpcmVzKS50b0dNVFN0cmluZygpKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAodXRpbHMuaXNTdHJpbmcocGF0aCkpIHtcbiAgICAgICAgICAgIGNvb2tpZS5wdXNoKCdwYXRoPScgKyBwYXRoKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAodXRpbHMuaXNTdHJpbmcoZG9tYWluKSkge1xuICAgICAgICAgICAgY29va2llLnB1c2goJ2RvbWFpbj0nICsgZG9tYWluKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoc2VjdXJlID09PSB0cnVlKSB7XG4gICAgICAgICAgICBjb29raWUucHVzaCgnc2VjdXJlJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZG9jdW1lbnQuY29va2llID0gY29va2llLmpvaW4oJzsgJyk7XG4gICAgICAgIH0sXG5cbiAgICAgICAgcmVhZDogZnVuY3Rpb24gcmVhZChuYW1lKSB7XG4gICAgICAgICAgdmFyIG1hdGNoID0gZG9jdW1lbnQuY29va2llLm1hdGNoKG5ldyBSZWdFeHAoJyhefDtcXFxccyopKCcgKyBuYW1lICsgJyk9KFteO10qKScpKTtcbiAgICAgICAgICByZXR1cm4gKG1hdGNoID8gZGVjb2RlVVJJQ29tcG9uZW50KG1hdGNoWzNdKSA6IG51bGwpO1xuICAgICAgICB9LFxuXG4gICAgICAgIHJlbW92ZTogZnVuY3Rpb24gcmVtb3ZlKG5hbWUpIHtcbiAgICAgICAgICB0aGlzLndyaXRlKG5hbWUsICcnLCBEYXRlLm5vdygpIC0gODY0MDAwMDApO1xuICAgICAgICB9XG4gICAgICB9O1xuICAgIH0pKCkgOlxuXG4gIC8vIE5vbiBzdGFuZGFyZCBicm93c2VyIGVudiAod2ViIHdvcmtlcnMsIHJlYWN0LW5hdGl2ZSkgbGFjayBuZWVkZWQgc3VwcG9ydC5cbiAgICAoZnVuY3Rpb24gbm9uU3RhbmRhcmRCcm93c2VyRW52KCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgd3JpdGU6IGZ1bmN0aW9uIHdyaXRlKCkge30sXG4gICAgICAgIHJlYWQ6IGZ1bmN0aW9uIHJlYWQoKSB7IHJldHVybiBudWxsOyB9LFxuICAgICAgICByZW1vdmU6IGZ1bmN0aW9uIHJlbW92ZSgpIHt9XG4gICAgICB9O1xuICAgIH0pKClcbik7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/axios/lib/helpers/cookies.js\n");
/***/ }),
/***/ "./node_modules/axios/lib/helpers/isAbsoluteURL.js":
/*!*********************************************************!*\
!*** ./node_modules/axios/lib/helpers/isAbsoluteURL.js ***!
\*********************************************************/
/***/ ((module) => {
"use strict";
eval("\n\n/**\n * Determines whether the specified URL is absolute\n *\n * @param {string} url The URL to test\n * @returns {boolean} True if the specified URL is absolute, otherwise false\n */\nmodule.exports = function isAbsoluteURL(url) {\n // A URL is considered absolute if it begins with \"<scheme>://\" or \"//\" (protocol-relative URL).\n // RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed\n // by any combination of letters, digits, plus, period, or hyphen.\n return /^([a-z][a-z\\d+\\-.]*:)?\\/\\//i.test(url);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2hlbHBlcnMvaXNBYnNvbHV0ZVVSTC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBO0FBQ0E7QUFDQSxXQUFXLFFBQVE7QUFDbkIsYUFBYSxTQUFTO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL2F4aW9zL2xpYi9oZWxwZXJzL2lzQWJzb2x1dGVVUkwuanM/YTIyNyJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbi8qKlxuICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBzcGVjaWZpZWQgVVJMIGlzIGFic29sdXRlXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHVybCBUaGUgVVJMIHRvIHRlc3RcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHRoZSBzcGVjaWZpZWQgVVJMIGlzIGFic29sdXRlLCBvdGhlcndpc2UgZmFsc2VcbiAqL1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpc0Fic29sdXRlVVJMKHVybCkge1xuICAvLyBBIFVSTCBpcyBjb25zaWRlcmVkIGFic29sdXRlIGlmIGl0IGJlZ2lucyB3aXRoIFwiPHNjaGVtZT46Ly9cIiBvciBcIi8vXCIgKHByb3RvY29sLXJlbGF0aXZlIFVSTCkuXG4gIC8vIFJGQyAzOTg2IGRlZmluZXMgc2NoZW1lIG5hbWUgYXMgYSBzZXF1ZW5jZSBvZiBjaGFyYWN0ZXJzIGJlZ2lubmluZyB3aXRoIGEgbGV0dGVyIGFuZCBmb2xsb3dlZFxuICAvLyBieSBhbnkgY29tYmluYXRpb24gb2YgbGV0dGVycywgZGlnaXRzLCBwbHVzLCBwZXJpb2QsIG9yIGh5cGhlbi5cbiAgcmV0dXJuIC9eKFthLXpdW2EtelxcZCtcXC0uXSo6KT9cXC9cXC8vaS50ZXN0KHVybCk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/axios/lib/helpers/isAbsoluteURL.js\n");
/***/ }),
/***/ "./node_modules/axios/lib/helpers/isAxiosError.js":
/*!********************************************************!*\
!*** ./node_modules/axios/lib/helpers/isAxiosError.js ***!
\********************************************************/
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict";
eval("\n\nvar utils = __webpack_require__(/*! ./../utils */ \"./node_modules/axios/lib/utils.js\");\n\n/**\n * Determines whether the payload is an error thrown by Axios\n *\n * @param {*} payload The value to test\n * @returns {boolean} True if the payload is an error thrown by Axios, otherwise false\n */\nmodule.exports = function isAxiosError(payload) {\n return utils.isObject(payload) && (payload.isAxiosError === true);\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2hlbHBlcnMvaXNBeGlvc0Vycm9yLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLFlBQVksbUJBQU8sQ0FBQyxxREFBWTs7QUFFaEM7QUFDQTtBQUNBO0FBQ0EsV0FBVyxHQUFHO0FBQ2QsYUFBYSxTQUFTO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL2F4aW9zL2xpYi9oZWxwZXJzL2lzQXhpb3NFcnJvci5qcz9iZDlkIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi8uLi91dGlscycpO1xuXG4vKipcbiAqIERldGVybWluZXMgd2hldGhlciB0aGUgcGF5bG9hZCBpcyBhbiBlcnJvciB0aHJvd24gYnkgQXhpb3NcbiAqXG4gKiBAcGFyYW0geyp9IHBheWxvYWQgVGhlIHZhbHVlIHRvIHRlc3RcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHRoZSBwYXlsb2FkIGlzIGFuIGVycm9yIHRocm93biBieSBBeGlvcywgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNBeGlvc0Vycm9yKHBheWxvYWQpIHtcbiAgcmV0dXJuIHV0aWxzLmlzT2JqZWN0KHBheWxvYWQpICYmIChwYXlsb2FkLmlzQXhpb3NFcnJvciA9PT0gdHJ1ZSk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/axios/lib/helpers/isAxiosError.js\n");
/***/ }),
/***/ "./node_modules/axios/lib/helpers/isURLSameOrigin.js":
/*!***********************************************************!*\
!*** ./node_modules/axios/lib/helpers/isURLSameOrigin.js ***!
\***********************************************************/
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict";
eval("\n\nvar utils = __webpack_require__(/*! ./../utils */ \"./node_modules/axios/lib/utils.js\");\n\nmodule.exports = (\n utils.isStandardBrowserEnv() ?\n\n // Standard browser envs have full support of the APIs needed to test\n // whether the request URL is of the same origin as current location.\n (function standardBrowserEnv() {\n var msie = /(msie|trident)/i.test(navigator.userAgent);\n var urlParsingNode = document.createElement('a');\n var originURL;\n\n /**\n * Parse a URL to discover it's components\n *\n * @param {String} url The URL to be parsed\n * @returns {Object}\n */\n function resolveURL(url) {\n var href = url;\n\n if (msie) {\n // IE needs attribute set twice to normalize properties\n urlParsingNode.setAttribute('href', href);\n href = urlParsingNode.href;\n }\n\n urlParsingNode.setAttribute('href', href);\n\n // urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils\n return {\n href: urlParsingNode.href,\n protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '',\n host: urlParsingNode.host,\n search: urlParsingNode.search ? urlParsingNode.search.replace(/^\\?/, '') : '',\n hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '',\n hostname: urlParsingNode.hostname,\n port: urlParsingNode.port,\n pathname: (urlParsingNode.pathname.charAt(0) === '/') ?\n urlParsingNode.pathname :\n '/' + urlParsingNode.pathname\n };\n }\n\n originURL = resolveURL(window.location.href);\n\n /**\n * Determine if a URL shares the same origin as the current location\n *\n * @param {String} requestURL The URL to test\n * @returns {boolean} True if URL shares the same origin, otherwise false\n */\n return function isURLSameOrigin(requestURL) {\n var parsed = (utils.isString(requestURL)) ? resolveURL(requestURL) : requestURL;\n return (parsed.protocol === originURL.protocol &&\n parsed.host === originURL.host);\n };\n })() :\n\n // Non standard browser envs (web workers, react-native) lack needed support.\n (function nonStandardBrowserEnv() {\n return function isURLSameOrigin() {\n return true;\n };\n })()\n);\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2hlbHBlcnMvaXNVUkxTYW1lT3JpZ2luLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLFlBQVksbUJBQU8sQ0FBQyxxREFBWTs7QUFFaEM7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsY0FBYyxRQUFRO0FBQ3RCLGdCQUFnQjtBQUNoQjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGNBQWMsUUFBUTtBQUN0QixnQkFBZ0IsU0FBUztBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0wiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2hlbHBlcnMvaXNVUkxTYW1lT3JpZ2luLmpzPzg3OTUiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLy4uL3V0aWxzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gKFxuICB1dGlscy5pc1N0YW5kYXJkQnJvd3NlckVudigpID9cblxuICAvLyBTdGFuZGFyZCBicm93c2VyIGVudnMgaGF2ZSBmdWxsIHN1cHBvcnQgb2YgdGhlIEFQSXMgbmVlZGVkIHRvIHRlc3RcbiAgLy8gd2hldGhlciB0aGUgcmVxdWVzdCBVUkwgaXMgb2YgdGhlIHNhbWUgb3JpZ2luIGFzIGN1cnJlbnQgbG9jYXRpb24uXG4gICAgKGZ1bmN0aW9uIHN0YW5kYXJkQnJvd3NlckVudigpIHtcbiAgICAgIHZhciBtc2llID0gLyhtc2llfHRyaWRlbnQpL2kudGVzdChuYXZpZ2F0b3IudXNlckFnZW50KTtcbiAgICAgIHZhciB1cmxQYXJzaW5nTm9kZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2EnKTtcbiAgICAgIHZhciBvcmlnaW5VUkw7XG5cbiAgICAgIC8qKlxuICAgICogUGFyc2UgYSBVUkwgdG8gZGlzY292ZXIgaXQncyBjb21wb25lbnRzXG4gICAgKlxuICAgICogQHBhcmFtIHtTdHJpbmd9IHVybCBUaGUgVVJMIHRvIGJlIHBhcnNlZFxuICAgICogQHJldHVybnMge09iamVjdH1cbiAgICAqL1xuICAgICAgZnVuY3Rpb24gcmVzb2x2ZVVSTCh1cmwpIHtcbiAgICAgICAgdmFyIGhyZWYgPSB1cmw7XG5cbiAgICAgICAgaWYgKG1zaWUpIHtcbiAgICAgICAgLy8gSUUgbmVlZHMgYXR0cmlidXRlIHNldCB0d2ljZSB0byBub3JtYWxpemUgcHJvcGVydGllc1xuICAgICAgICAgIHVybFBhcnNpbmdOb2RlLnNldEF0dHJpYnV0ZSgnaHJlZicsIGhyZWYpO1xuICAgICAgICAgIGhyZWYgPSB1cmxQYXJzaW5nTm9kZS5ocmVmO1xuICAgICAgICB9XG5cbiAgICAgICAgdXJsUGFyc2luZ05vZGUuc2V0QXR0cmlidXRlKCdocmVmJywgaHJlZik7XG5cbiAgICAgICAgLy8gdXJsUGFyc2luZ05vZGUgcHJvdmlkZXMgdGhlIFVybFV0aWxzIGludGVyZmFjZSAtIGh0dHA6Ly91cmwuc3BlYy53aGF0d2cub3JnLyN1cmx1dGlsc1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGhyZWY6IHVybFBhcnNpbmdOb2RlLmhyZWYsXG4gICAgICAgICAgcHJvdG9jb2w6IHVybFBhcnNpbmdOb2RlLnByb3RvY29sID8gdXJsUGFyc2luZ05vZGUucHJvdG9jb2wucmVwbGFjZSgvOiQvLCAnJykgOiAnJyxcbiAgICAgICAgICBob3N0OiB1cmxQYXJzaW5nTm9kZS5ob3N0LFxuICAgICAgICAgIHNlYXJjaDogdXJsUGFyc2luZ05vZGUuc2VhcmNoID8gdXJsUGFyc2luZ05vZGUuc2VhcmNoLnJlcGxhY2UoL15cXD8vLCAnJykgOiAnJyxcbiAgICAgICAgICBoYXNoOiB1cmxQYXJzaW5nTm9kZS5oYXNoID8gdXJsUGFyc2luZ05vZGUuaGFzaC5yZXBsYWNlKC9eIy8sICcnKSA6ICcnLFxuICAgICAgICAgIGhvc3RuYW1lOiB1cmxQYXJzaW5nTm9kZS5ob3N0bmFtZSxcbiAgICAgICAgICBwb3J0OiB1cmxQYXJzaW5nTm9kZS5wb3J0LFxuICAgICAgICAgIHBhdGhuYW1lOiAodXJsUGFyc2luZ05vZGUucGF0aG5hbWUuY2hhckF0KDApID09PSAnLycpID9cbiAgICAgICAgICAgIHVybFBhcnNpbmdOb2RlLnBhdGhuYW1lIDpcbiAgICAgICAgICAgICcvJyArIHVybFBhcnNpbmdOb2RlLnBhdGhuYW1lXG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIG9yaWdpblVSTCA9IHJlc29sdmVVUkwod2luZG93LmxvY2F0aW9uLmhyZWYpO1xuXG4gICAgICAvKipcbiAgICAqIERldGVybWluZSBpZiBhIFVSTCBzaGFyZXMgdGhlIHNhbWUgb3JpZ2luIGFzIHRoZSBjdXJyZW50IGxvY2F0aW9uXG4gICAgKlxuICAgICogQHBhcmFtIHtTdHJpbmd9IHJlcXVlc3RVUkwgVGhlIFVSTCB0byB0ZXN0XG4gICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiBVUkwgc2hhcmVzIHRoZSBzYW1lIG9yaWdpbiwgb3RoZXJ3aXNlIGZhbHNlXG4gICAgKi9cbiAgICAgIHJldHVybiBmdW5jdGlvbiBpc1VSTFNhbWVPcmlnaW4ocmVxdWVzdFVSTCkge1xuICAgICAgICB2YXIgcGFyc2VkID0gKHV0aWxzLmlzU3RyaW5nKHJlcXVlc3RVUkwpKSA/IHJlc29sdmVVUkwocmVxdWVzdFVSTCkgOiByZXF1ZXN0VVJMO1xuICAgICAgICByZXR1cm4gKHBhcnNlZC5wcm90b2NvbCA9PT0gb3JpZ2luVVJMLnByb3RvY29sICYmXG4gICAgICAgICAgICBwYXJzZWQuaG9zdCA9PT0gb3JpZ2luVVJMLmhvc3QpO1xuICAgICAgfTtcbiAgICB9KSgpIDpcblxuICAvLyBOb24gc3RhbmRhcmQgYnJvd3NlciBlbnZzICh3ZWIgd29ya2VycywgcmVhY3QtbmF0aXZlKSBsYWNrIG5lZWRlZCBzdXBwb3J0LlxuICAgIChmdW5jdGlvbiBub25TdGFuZGFyZEJyb3dzZXJFbnYoKSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24gaXNVUkxTYW1lT3JpZ2luKCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH07XG4gICAgfSkoKVxuKTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/axios/lib/helpers/isURLSameOrigin.js\n");
/***/ }),
/***/ "./node_modules/axios/lib/helpers/normalizeHeaderName.js":
/*!***************************************************************!*\
!*** ./node_modules/axios/lib/helpers/normalizeHeaderName.js ***!
\***************************************************************/
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict";
eval("\n\nvar utils = __webpack_require__(/*! ../utils */ \"./node_modules/axios/lib/utils.js\");\n\nmodule.exports = function normalizeHeaderName(headers, normalizedName) {\n utils.forEach(headers, function processHeader(value, name) {\n if (name !== normalizedName && name.toUpperCase() === normalizedName.toUpperCase()) {\n headers[normalizedName] = value;\n delete headers[name];\n }\n });\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2hlbHBlcnMvbm9ybWFsaXplSGVhZGVyTmFtZS5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYixZQUFZLG1CQUFPLENBQUMsbURBQVU7O0FBRTlCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSCIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9heGlvcy9saWIvaGVscGVycy9ub3JtYWxpemVIZWFkZXJOYW1lLmpzPzZiMTUiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi91dGlscycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIG5vcm1hbGl6ZUhlYWRlck5hbWUoaGVhZGVycywgbm9ybWFsaXplZE5hbWUpIHtcbiAgdXRpbHMuZm9yRWFjaChoZWFkZXJzLCBmdW5jdGlvbiBwcm9jZXNzSGVhZGVyKHZhbHVlLCBuYW1lKSB7XG4gICAgaWYgKG5hbWUgIT09IG5vcm1hbGl6ZWROYW1lICYmIG5hbWUudG9VcHBlckNhc2UoKSA9PT0gbm9ybWFsaXplZE5hbWUudG9VcHBlckNhc2UoKSkge1xuICAgICAgaGVhZGVyc1tub3JtYWxpemVkTmFtZV0gPSB2YWx1ZTtcbiAgICAgIGRlbGV0ZSBoZWFkZXJzW25hbWVdO1xuICAgIH1cbiAgfSk7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/axios/lib/helpers/normalizeHeaderName.js\n");
/***/ }),
/***/ "./node_modules/axios/lib/helpers/null.js":
/*!************************************************!*\
!*** ./node_modules/axios/lib/helpers/null.js ***!
\************************************************/
/***/ ((module) => {
eval("// eslint-disable-next-line strict\nmodule.exports = null;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2hlbHBlcnMvbnVsbC5qcyIsIm1hcHBpbmdzIjoiQUFBQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL2F4aW9zL2xpYi9oZWxwZXJzL251bGwuanM/MWE5NCJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgc3RyaWN0XG5tb2R1bGUuZXhwb3J0cyA9IG51bGw7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/axios/lib/helpers/null.js\n");
/***/ }),
/***/ "./node_modules/axios/lib/helpers/parseHeaders.js":
/*!********************************************************!*\
!*** ./node_modules/axios/lib/helpers/parseHeaders.js ***!
\********************************************************/
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict";
eval("\n\nvar utils = __webpack_require__(/*! ./../utils */ \"./node_modules/axios/lib/utils.js\");\n\n// Headers whose duplicates are ignored by node\n// c.f. https://nodejs.org/api/http.html#http_message_headers\nvar ignoreDuplicateOf = [\n 'age', 'authorization', 'content-length', 'content-type', 'etag',\n 'expires', 'from', 'host', 'if-modified-since', 'if-unmodified-since',\n 'last-modified', 'location', 'max-forwards', 'proxy-authorization',\n 'referer', 'retry-after', 'user-agent'\n];\n\n/**\n * Parse headers into an object\n *\n * ```\n * Date: Wed, 27 Aug 2014 08:58:49 GMT\n * Content-Type: application/json\n * Connection: keep-alive\n * Transfer-Encoding: chunked\n * ```\n *\n * @param {String} headers Headers needing to be parsed\n * @returns {Object} Headers parsed into an object\n */\nmodule.exports = function parseHeaders(headers) {\n var parsed = {};\n var key;\n var val;\n var i;\n\n if (!headers) { return parsed; }\n\n utils.forEach(headers.split('\\n'), function parser(line) {\n i = line.indexOf(':');\n key = utils.trim(line.substr(0, i)).toLowerCase();\n val = utils.trim(line.substr(i + 1));\n\n if (key) {\n if (parsed[key] && ignoreDuplicateOf.indexOf(key) >= 0) {\n return;\n }\n if (key === 'set-cookie') {\n parsed[key] = (parsed[key] ? parsed[key] : []).concat([val]);\n } else {\n parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;\n }\n }\n });\n\n return parsed;\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2hlbHBlcnMvcGFyc2VIZWFkZXJzLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLFlBQVksbUJBQU8sQ0FBQyxxREFBWTs7QUFFaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsUUFBUTtBQUNuQixhQUFhLFFBQVE7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGtCQUFrQjs7QUFFbEI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQSIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9heGlvcy9saWIvaGVscGVycy9wYXJzZUhlYWRlcnMuanM/NTRlOSJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbnZhciB1dGlscyA9IHJlcXVpcmUoJy4vLi4vdXRpbHMnKTtcblxuLy8gSGVhZGVycyB3aG9zZSBkdXBsaWNhdGVzIGFyZSBpZ25vcmVkIGJ5IG5vZGVcbi8vIGMuZi4gaHR0cHM6Ly9ub2RlanMub3JnL2FwaS9odHRwLmh0bWwjaHR0cF9tZXNzYWdlX2hlYWRlcnNcbnZhciBpZ25vcmVEdXBsaWNhdGVPZiA9IFtcbiAgJ2FnZScsICdhdXRob3JpemF0aW9uJywgJ2NvbnRlbnQtbGVuZ3RoJywgJ2NvbnRlbnQtdHlwZScsICdldGFnJyxcbiAgJ2V4cGlyZXMnLCAnZnJvbScsICdob3N0JywgJ2lmLW1vZGlmaWVkLXNpbmNlJywgJ2lmLXVubW9kaWZpZWQtc2luY2UnLFxuICAnbGFzdC1tb2RpZmllZCcsICdsb2NhdGlvbicsICdtYXgtZm9yd2FyZHMnLCAncHJveHktYXV0aG9yaXphdGlvbicsXG4gICdyZWZlcmVyJywgJ3JldHJ5LWFmdGVyJywgJ3VzZXItYWdlbnQnXG5dO1xuXG4vKipcbiAqIFBhcnNlIGhlYWRlcnMgaW50byBhbiBvYmplY3RcbiAqXG4gKiBgYGBcbiAqIERhdGU6IFdlZCwgMjcgQXVnIDIwMTQgMDg6NTg6NDkgR01UXG4gKiBDb250ZW50LVR5cGU6IGFwcGxpY2F0aW9uL2pzb25cbiAqIENvbm5lY3Rpb246IGtlZXAtYWxpdmVcbiAqIFRyYW5zZmVyLUVuY29kaW5nOiBjaHVua2VkXG4gKiBgYGBcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gaGVhZGVycyBIZWFkZXJzIG5lZWRpbmcgdG8gYmUgcGFyc2VkXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBIZWFkZXJzIHBhcnNlZCBpbnRvIGFuIG9iamVjdFxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIHBhcnNlSGVhZGVycyhoZWFkZXJzKSB7XG4gIHZhciBwYXJzZWQgPSB7fTtcbiAgdmFyIGtleTtcbiAgdmFyIHZhbDtcbiAgdmFyIGk7XG5cbiAgaWYgKCFoZWFkZXJzKSB7IHJldHVybiBwYXJzZWQ7IH1cblxuICB1dGlscy5mb3JFYWNoKGhlYWRlcnMuc3BsaXQoJ1xcbicpLCBmdW5jdGlvbiBwYXJzZXIobGluZSkge1xuICAgIGkgPSBsaW5lLmluZGV4T2YoJzonKTtcbiAgICBrZXkgPSB1dGlscy50cmltKGxpbmUuc3Vic3RyKDAsIGkpKS50b0xvd2VyQ2FzZSgpO1xuICAgIHZhbCA9IHV0aWxzLnRyaW0obGluZS5zdWJzdHIoaSArIDEpKTtcblxuICAgIGlmIChrZXkpIHtcbiAgICAgIGlmIChwYXJzZWRba2V5XSAmJiBpZ25vcmVEdXBsaWNhdGVPZi5pbmRleE9mKGtleSkgPj0gMCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAoa2V5ID09PSAnc2V0LWNvb2tpZScpIHtcbiAgICAgICAgcGFyc2VkW2tleV0gPSAocGFyc2VkW2tleV0gPyBwYXJzZWRba2V5XSA6IFtdKS5jb25jYXQoW3ZhbF0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcGFyc2VkW2tleV0gPSBwYXJzZWRba2V5XSA/IHBhcnNlZFtrZXldICsgJywgJyArIHZhbCA6IHZhbDtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiBwYXJzZWQ7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/axios/lib/helpers/parseHeaders.js\n");
/***/ }),
/***/ "./node_modules/axios/lib/helpers/parseProtocol.js":
/*!*********************************************************!*\
!*** ./node_modules/axios/lib/helpers/parseProtocol.js ***!
\*********************************************************/
/***/ ((module) => {
"use strict";
eval("\n\nmodule.exports = function parseProtocol(url) {\n var match = /^([-+\\w]{1,25})(:?\\/\\/|:)/.exec(url);\n return match && match[1] || '';\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2hlbHBlcnMvcGFyc2VQcm90b2NvbC5qcyIsIm1hcHBpbmdzIjoiQUFBYTs7QUFFYjtBQUNBLHdCQUF3QixLQUFLO0FBQzdCO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2hlbHBlcnMvcGFyc2VQcm90b2NvbC5qcz85ZmFjIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBwYXJzZVByb3RvY29sKHVybCkge1xuICB2YXIgbWF0Y2ggPSAvXihbLStcXHddezEsMjV9KSg6P1xcL1xcL3w6KS8uZXhlYyh1cmwpO1xuICByZXR1cm4gbWF0Y2ggJiYgbWF0Y2hbMV0gfHwgJyc7XG59O1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/axios/lib/helpers/parseProtocol.js\n");
/***/ }),
/***/ "./node_modules/axios/lib/helpers/spread.js":
/*!**************************************************!*\
!*** ./node_modules/axios/lib/helpers/spread.js ***!
\**************************************************/
/***/ ((module) => {
"use strict";
eval("\n\n/**\n * Syntactic sugar for invoking a function and expanding an array for arguments.\n *\n * Common use case would be to use `Function.prototype.apply`.\n *\n * ```js\n * function f(x, y, z) {}\n * var args = [1, 2, 3];\n * f.apply(null, args);\n * ```\n *\n * With `spread` this example can be re-written.\n *\n * ```js\n * spread(function(x, y, z) {})([1, 2, 3]);\n * ```\n *\n * @param {Function} callback\n * @returns {Function}\n */\nmodule.exports = function spread(callback) {\n return function wrap(arr) {\n return callback.apply(null, arr);\n };\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2hlbHBlcnMvc3ByZWFkLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrQkFBK0I7QUFDL0I7QUFDQTtBQUNBLFdBQVcsVUFBVTtBQUNyQixhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL2F4aW9zL2xpYi9oZWxwZXJzL3NwcmVhZC5qcz8yNzI5Il0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiBTeW50YWN0aWMgc3VnYXIgZm9yIGludm9raW5nIGEgZnVuY3Rpb24gYW5kIGV4cGFuZGluZyBhbiBhcnJheSBmb3IgYXJndW1lbnRzLlxuICpcbiAqIENvbW1vbiB1c2UgY2FzZSB3b3VsZCBiZSB0byB1c2UgYEZ1bmN0aW9uLnByb3RvdHlwZS5hcHBseWAuXG4gKlxuICogIGBgYGpzXG4gKiAgZnVuY3Rpb24gZih4LCB5LCB6KSB7fVxuICogIHZhciBhcmdzID0gWzEsIDIsIDNdO1xuICogIGYuYXBwbHkobnVsbCwgYXJncyk7XG4gKiAgYGBgXG4gKlxuICogV2l0aCBgc3ByZWFkYCB0aGlzIGV4YW1wbGUgY2FuIGJlIHJlLXdyaXR0ZW4uXG4gKlxuICogIGBgYGpzXG4gKiAgc3ByZWFkKGZ1bmN0aW9uKHgsIHksIHopIHt9KShbMSwgMiwgM10pO1xuICogIGBgYFxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259XG4gKi9cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gc3ByZWFkKGNhbGxiYWNrKSB7XG4gIHJldHVybiBmdW5jdGlvbiB3cmFwKGFycikge1xuICAgIHJldHVybiBjYWxsYmFjay5hcHBseShudWxsLCBhcnIpO1xuICB9O1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/axios/lib/helpers/spread.js\n");
/***/ }),
/***/ "./node_modules/axios/lib/helpers/toFormData.js":
/*!******************************************************!*\
!*** ./node_modules/axios/lib/helpers/toFormData.js ***!
\******************************************************/
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict";
eval("/* provided dependency */ var Buffer = __webpack_require__(/*! buffer */ \"./node_modules/buffer/index.js\")[\"Buffer\"];\n\n\nvar utils = __webpack_require__(/*! ../utils */ \"./node_modules/axios/lib/utils.js\");\n\n/**\n * Convert a data object to FormData\n * @param {Object} obj\n * @param {?Object} [formData]\n * @returns {Object}\n **/\n\nfunction toFormData(obj, formData) {\n // eslint-disable-next-line no-param-reassign\n formData = formData || new FormData();\n\n var stack = [];\n\n function convertValue(value) {\n if (value === null) return '';\n\n if (utils.isDate(value)) {\n return value.toISOString();\n }\n\n if (utils.isArrayBuffer(value) || utils.isTypedArray(value)) {\n return typeof Blob === 'function' ? new Blob([value]) : Buffer.from(value);\n }\n\n return value;\n }\n\n function build(data, parentKey) {\n if (utils.isPlainObject(data) || utils.isArray(data)) {\n if (stack.indexOf(data) !== -1) {\n throw Error('Circular reference detected in ' + parentKey);\n }\n\n stack.push(data);\n\n utils.forEach(data, function each(value, key) {\n if (utils.isUndefined(value)) return;\n var fullKey = parentKey ? parentKey + '.' + key : key;\n var arr;\n\n if (value && !parentKey && typeof value === 'object') {\n if (utils.endsWith(key, '{}')) {\n // eslint-disable-next-line no-param-reassign\n value = JSON.stringify(value);\n } else if (utils.endsWith(key, '[]') && (arr = utils.toArray(value))) {\n // eslint-disable-next-line func-names\n arr.forEach(function(el) {\n !utils.isUndefined(el) && formData.append(fullKey, convertValue(el));\n });\n return;\n }\n }\n\n build(value, fullKey);\n });\n\n stack.pop();\n } else {\n formData.append(parentKey, convertValue(data));\n }\n }\n\n build(obj);\n\n return formData;\n}\n\nmodule.exports = toFormData;\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2hlbHBlcnMvdG9Gb3JtRGF0YS5qcyIsIm1hcHBpbmdzIjoiO0FBQWE7O0FBRWIsWUFBWSxtQkFBTyxDQUFDLG1EQUFVOztBQUU5QjtBQUNBO0FBQ0EsV0FBVyxRQUFRO0FBQ25CLFdBQVcsU0FBUztBQUNwQixhQUFhO0FBQ2I7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsOERBQThELE1BQU07QUFDcEU7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EscUNBQXFDO0FBQ3JDO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLE9BQU87O0FBRVA7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUEiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2hlbHBlcnMvdG9Gb3JtRGF0YS5qcz85YmEzIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMnKTtcblxuLyoqXG4gKiBDb252ZXJ0IGEgZGF0YSBvYmplY3QgdG8gRm9ybURhdGFcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmpcbiAqIEBwYXJhbSB7P09iamVjdH0gW2Zvcm1EYXRhXVxuICogQHJldHVybnMge09iamVjdH1cbiAqKi9cblxuZnVuY3Rpb24gdG9Gb3JtRGF0YShvYmosIGZvcm1EYXRhKSB7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuICBmb3JtRGF0YSA9IGZvcm1EYXRhIHx8IG5ldyBGb3JtRGF0YSgpO1xuXG4gIHZhciBzdGFjayA9IFtdO1xuXG4gIGZ1bmN0aW9uIGNvbnZlcnRWYWx1ZSh2YWx1ZSkge1xuICAgIGlmICh2YWx1ZSA9PT0gbnVsbCkgcmV0dXJuICcnO1xuXG4gICAgaWYgKHV0aWxzLmlzRGF0ZSh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiB2YWx1ZS50b0lTT1N0cmluZygpO1xuICAgIH1cblxuICAgIGlmICh1dGlscy5pc0FycmF5QnVmZmVyKHZhbHVlKSB8fCB1dGlscy5pc1R5cGVkQXJyYXkodmFsdWUpKSB7XG4gICAgICByZXR1cm4gdHlwZW9mIEJsb2IgPT09ICdmdW5jdGlvbicgPyBuZXcgQmxvYihbdmFsdWVdKSA6IEJ1ZmZlci5mcm9tKHZhbHVlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cblxuICBmdW5jdGlvbiBidWlsZChkYXRhLCBwYXJlbnRLZXkpIHtcbiAgICBpZiAodXRpbHMuaXNQbGFpbk9iamVjdChkYXRhKSB8fCB1dGlscy5pc0FycmF5KGRhdGEpKSB7XG4gICAgICBpZiAoc3RhY2suaW5kZXhPZihkYXRhKSAhPT0gLTEpIHtcbiAgICAgICAgdGhyb3cgRXJyb3IoJ0NpcmN1bGFyIHJlZmVyZW5jZSBkZXRlY3RlZCBpbiAnICsgcGFyZW50S2V5KTtcbiAgICAgIH1cblxuICAgICAgc3RhY2sucHVzaChkYXRhKTtcblxuICAgICAgdXRpbHMuZm9yRWFjaChkYXRhLCBmdW5jdGlvbiBlYWNoKHZhbHVlLCBrZXkpIHtcbiAgICAgICAgaWYgKHV0aWxzLmlzVW5kZWZpbmVkKHZhbHVlKSkgcmV0dXJuO1xuICAgICAgICB2YXIgZnVsbEtleSA9IHBhcmVudEtleSA/IHBhcmVudEtleSArICcuJyArIGtleSA6IGtleTtcbiAgICAgICAgdmFyIGFycjtcblxuICAgICAgICBpZiAodmFsdWUgJiYgIXBhcmVudEtleSAmJiB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgaWYgKHV0aWxzLmVuZHNXaXRoKGtleSwgJ3t9JykpIHtcbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuICAgICAgICAgICAgdmFsdWUgPSBKU09OLnN0cmluZ2lmeSh2YWx1ZSk7XG4gICAgICAgICAgfSBlbHNlIGlmICh1dGlscy5lbmRzV2l0aChrZXksICdbXScpICYmIChhcnIgPSB1dGlscy50b0FycmF5KHZhbHVlKSkpIHtcbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBmdW5jLW5hbWVzXG4gICAgICAgICAgICBhcnIuZm9yRWFjaChmdW5jdGlvbihlbCkge1xuICAgICAgICAgICAgICAhdXRpbHMuaXNVbmRlZmluZWQoZWwpICYmIGZvcm1EYXRhLmFwcGVuZChmdWxsS2V5LCBjb252ZXJ0VmFsdWUoZWwpKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGJ1aWxkKHZhbHVlLCBmdWxsS2V5KTtcbiAgICAgIH0pO1xuXG4gICAgICBzdGFjay5wb3AoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZm9ybURhdGEuYXBwZW5kKHBhcmVudEtleSwgY29udmVydFZhbHVlKGRhdGEpKTtcbiAgICB9XG4gIH1cblxuICBidWlsZChvYmopO1xuXG4gIHJldHVybiBmb3JtRGF0YTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB0b0Zvcm1EYXRhO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/axios/lib/helpers/toFormData.js\n");
/***/ }),
/***/ "./node_modules/axios/lib/helpers/validator.js":
/*!*****************************************************!*\
!*** ./node_modules/axios/lib/helpers/validator.js ***!
\*****************************************************/
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict";
eval("\n\nvar VERSION = (__webpack_require__(/*! ../env/data */ \"./node_modules/axios/lib/env/data.js\").version);\nvar AxiosError = __webpack_require__(/*! ../core/AxiosError */ \"./node_modules/axios/lib/core/AxiosError.js\");\n\nvar validators = {};\n\n// eslint-disable-next-line func-names\n['object', 'boolean', 'number', 'function', 'string', 'symbol'].forEach(function(type, i) {\n validators[type] = function validator(thing) {\n return typeof thing === type || 'a' + (i < 1 ? 'n ' : ' ') + type;\n };\n});\n\nvar deprecatedWarnings = {};\n\n/**\n * Transitional option validator\n * @param {function|boolean?} validator - set to false if the transitional option has been removed\n * @param {string?} version - deprecated version / removed since version\n * @param {string?} message - some message with additional info\n * @returns {function}\n */\nvalidators.transitional = function transitional(validator, version, message) {\n function formatMessage(opt, desc) {\n return '[Axios v' + VERSION + '] Transitional option \\'' + opt + '\\'' + desc + (message ? '. ' + message : '');\n }\n\n // eslint-disable-next-line func-names\n return function(value, opt, opts) {\n if (validator === false) {\n throw new AxiosError(\n formatMessage(opt, ' has been removed' + (version ? ' in ' + version : '')),\n AxiosError.ERR_DEPRECATED\n );\n }\n\n if (version && !deprecatedWarnings[opt]) {\n deprecatedWarnings[opt] = true;\n // eslint-disable-next-line no-console\n console.warn(\n formatMessage(\n opt,\n ' has been deprecated since v' + version + ' and will be removed in the near future'\n )\n );\n }\n\n return validator ? validator(value, opt, opts) : true;\n };\n};\n\n/**\n * Assert object's properties type\n * @param {object} options\n * @param {object} schema\n * @param {boolean?} allowUnknown\n */\n\nfunction assertOptions(options, schema, allowUnknown) {\n if (typeof options !== 'object') {\n throw new AxiosError('options must be an object', AxiosError.ERR_BAD_OPTION_VALUE);\n }\n var keys = Object.keys(options);\n var i = keys.length;\n while (i-- > 0) {\n var opt = keys[i];\n var validator = schema[opt];\n if (validator) {\n var value = options[opt];\n var result = value === undefined || validator(value, opt, options);\n if (result !== true) {\n throw new AxiosError('option ' + opt + ' must be ' + result, AxiosError.ERR_BAD_OPTION_VALUE);\n }\n continue;\n }\n if (allowUnknown !== true) {\n throw new AxiosError('Unknown option ' + opt, AxiosError.ERR_BAD_OPTION);\n }\n }\n}\n\nmodule.exports = {\n assertOptions: assertOptions,\n validators: validators\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL2hlbHBlcnMvdmFsaWRhdG9yLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLGNBQWMsd0ZBQThCO0FBQzVDLGlCQUFpQixtQkFBTyxDQUFDLHVFQUFvQjs7QUFFN0M7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7O0FBRUE7QUFDQTtBQUNBLFdBQVcsbUJBQW1CO0FBQzlCLFdBQVcsU0FBUztBQUNwQixXQUFXLFNBQVM7QUFDcEIsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFdBQVcsUUFBUTtBQUNuQixXQUFXLFFBQVE7QUFDbkIsV0FBVyxVQUFVO0FBQ3JCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL2F4aW9zL2xpYi9oZWxwZXJzL3ZhbGlkYXRvci5qcz8wMTMyIl0sInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0JztcblxudmFyIFZFUlNJT04gPSByZXF1aXJlKCcuLi9lbnYvZGF0YScpLnZlcnNpb247XG52YXIgQXhpb3NFcnJvciA9IHJlcXVpcmUoJy4uL2NvcmUvQXhpb3NFcnJvcicpO1xuXG52YXIgdmFsaWRhdG9ycyA9IHt9O1xuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZnVuYy1uYW1lc1xuWydvYmplY3QnLCAnYm9vbGVhbicsICdudW1iZXInLCAnZnVuY3Rpb24nLCAnc3RyaW5nJywgJ3N5bWJvbCddLmZvckVhY2goZnVuY3Rpb24odHlwZSwgaSkge1xuICB2YWxpZGF0b3JzW3R5cGVdID0gZnVuY3Rpb24gdmFsaWRhdG9yKHRoaW5nKSB7XG4gICAgcmV0dXJuIHR5cGVvZiB0aGluZyA9PT0gdHlwZSB8fCAnYScgKyAoaSA8IDEgPyAnbiAnIDogJyAnKSArIHR5cGU7XG4gIH07XG59KTtcblxudmFyIGRlcHJlY2F0ZWRXYXJuaW5ncyA9IHt9O1xuXG4vKipcbiAqIFRyYW5zaXRpb25hbCBvcHRpb24gdmFsaWRhdG9yXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufGJvb2xlYW4/fSB2YWxpZGF0b3IgLSBzZXQgdG8gZmFsc2UgaWYgdGhlIHRyYW5zaXRpb25hbCBvcHRpb24gaGFzIGJlZW4gcmVtb3ZlZFxuICogQHBhcmFtIHtzdHJpbmc/fSB2ZXJzaW9uIC0gZGVwcmVjYXRlZCB2ZXJzaW9uIC8gcmVtb3ZlZCBzaW5jZSB2ZXJzaW9uXG4gKiBAcGFyYW0ge3N0cmluZz99IG1lc3NhZ2UgLSBzb21lIG1lc3NhZ2Ugd2l0aCBhZGRpdGlvbmFsIGluZm9cbiAqIEByZXR1cm5zIHtmdW5jdGlvbn1cbiAqL1xudmFsaWRhdG9ycy50cmFuc2l0aW9uYWwgPSBmdW5jdGlvbiB0cmFuc2l0aW9uYWwodmFsaWRhdG9yLCB2ZXJzaW9uLCBtZXNzYWdlKSB7XG4gIGZ1bmN0aW9uIGZvcm1hdE1lc3NhZ2Uob3B0LCBkZXNjKSB7XG4gICAgcmV0dXJuICdbQXhpb3MgdicgKyBWRVJTSU9OICsgJ10gVHJhbnNpdGlvbmFsIG9wdGlvbiBcXCcnICsgb3B0ICsgJ1xcJycgKyBkZXNjICsgKG1lc3NhZ2UgPyAnLiAnICsgbWVzc2FnZSA6ICcnKTtcbiAgfVxuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBmdW5jLW5hbWVzXG4gIHJldHVybiBmdW5jdGlvbih2YWx1ZSwgb3B0LCBvcHRzKSB7XG4gICAgaWYgKHZhbGlkYXRvciA9PT0gZmFsc2UpIHtcbiAgICAgIHRocm93IG5ldyBBeGlvc0Vycm9yKFxuICAgICAgICBmb3JtYXRNZXNzYWdlKG9wdCwgJyBoYXMgYmVlbiByZW1vdmVkJyArICh2ZXJzaW9uID8gJyBpbiAnICsgdmVyc2lvbiA6ICcnKSksXG4gICAgICAgIEF4aW9zRXJyb3IuRVJSX0RFUFJFQ0FURURcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKHZlcnNpb24gJiYgIWRlcHJlY2F0ZWRXYXJuaW5nc1tvcHRdKSB7XG4gICAgICBkZXByZWNhdGVkV2FybmluZ3Nbb3B0XSA9IHRydWU7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICBmb3JtYXRNZXNzYWdlKFxuICAgICAgICAgIG9wdCxcbiAgICAgICAgICAnIGhhcyBiZWVuIGRlcHJlY2F0ZWQgc2luY2UgdicgKyB2ZXJzaW9uICsgJyBhbmQgd2lsbCBiZSByZW1vdmVkIGluIHRoZSBuZWFyIGZ1dHVyZSdcbiAgICAgICAgKVxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdmFsaWRhdG9yID8gdmFsaWRhdG9yKHZhbHVlLCBvcHQsIG9wdHMpIDogdHJ1ZTtcbiAgfTtcbn07XG5cbi8qKlxuICogQXNzZXJ0IG9iamVjdCdzIHByb3BlcnRpZXMgdHlwZVxuICogQHBhcmFtIHtvYmplY3R9IG9wdGlvbnNcbiAqIEBwYXJhbSB7b2JqZWN0fSBzY2hlbWFcbiAqIEBwYXJhbSB7Ym9vbGVhbj99IGFsbG93VW5rbm93blxuICovXG5cbmZ1bmN0aW9uIGFzc2VydE9wdGlvbnMob3B0aW9ucywgc2NoZW1hLCBhbGxvd1Vua25vd24pIHtcbiAgaWYgKHR5cGVvZiBvcHRpb25zICE9PSAnb2JqZWN0Jykge1xuICAgIHRocm93IG5ldyBBeGlvc0Vycm9yKCdvcHRpb25zIG11c3QgYmUgYW4gb2JqZWN0JywgQXhpb3NFcnJvci5FUlJfQkFEX09QVElPTl9WQUxVRSk7XG4gIH1cbiAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhvcHRpb25zKTtcbiAgdmFyIGkgPSBrZXlzLmxlbmd0aDtcbiAgd2hpbGUgKGktLSA+IDApIHtcbiAgICB2YXIgb3B0ID0ga2V5c1tpXTtcbiAgICB2YXIgdmFsaWRhdG9yID0gc2NoZW1hW29wdF07XG4gICAgaWYgKHZhbGlkYXRvcikge1xuICAgICAgdmFyIHZhbHVlID0gb3B0aW9uc1tvcHRdO1xuICAgICAgdmFyIHJlc3VsdCA9IHZhbHVlID09PSB1bmRlZmluZWQgfHwgdmFsaWRhdG9yKHZhbHVlLCBvcHQsIG9wdGlvbnMpO1xuICAgICAgaWYgKHJlc3VsdCAhPT0gdHJ1ZSkge1xuICAgICAgICB0aHJvdyBuZXcgQXhpb3NFcnJvcignb3B0aW9uICcgKyBvcHQgKyAnIG11c3QgYmUgJyArIHJlc3VsdCwgQXhpb3NFcnJvci5FUlJfQkFEX09QVElPTl9WQUxVRSk7XG4gICAgICB9XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgaWYgKGFsbG93VW5rbm93biAhPT0gdHJ1ZSkge1xuICAgICAgdGhyb3cgbmV3IEF4aW9zRXJyb3IoJ1Vua25vd24gb3B0aW9uICcgKyBvcHQsIEF4aW9zRXJyb3IuRVJSX0JBRF9PUFRJT04pO1xuICAgIH1cbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgYXNzZXJ0T3B0aW9uczogYXNzZXJ0T3B0aW9ucyxcbiAgdmFsaWRhdG9yczogdmFsaWRhdG9yc1xufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/axios/lib/helpers/validator.js\n");
/***/ }),
/***/ "./node_modules/axios/lib/utils.js":
/*!*****************************************!*\
!*** ./node_modules/axios/lib/utils.js ***!
\*****************************************/
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
"use strict";
eval("\n\nvar bind = __webpack_require__(/*! ./helpers/bind */ \"./node_modules/axios/lib/helpers/bind.js\");\n\n// utils is a library of generic helper functions non-specific to axios\n\nvar toString = Object.prototype.toString;\n\n// eslint-disable-next-line func-names\nvar kindOf = (function(cache) {\n // eslint-disable-next-line func-names\n return function(thing) {\n var str = toString.call(thing);\n return cache[str] || (cache[str] = str.slice(8, -1).toLowerCase());\n };\n})(Object.create(null));\n\nfunction kindOfTest(type) {\n type = type.toLowerCase();\n return function isKindOf(thing) {\n return kindOf(thing) === type;\n };\n}\n\n/**\n * Determine if a value is an Array\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if value is an Array, otherwise false\n */\nfunction isArray(val) {\n return Array.isArray(val);\n}\n\n/**\n * Determine if a value is undefined\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if the value is undefined, otherwise false\n */\nfunction isUndefined(val) {\n return typeof val === 'undefined';\n}\n\n/**\n * Determine if a value is a Buffer\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if value is a Buffer, otherwise false\n */\nfunction isBuffer(val) {\n return val !== null && !isUndefined(val) && val.constructor !== null && !isUndefined(val.constructor)\n && typeof val.constructor.isBuffer === 'function' && val.constructor.isBuffer(val);\n}\n\n/**\n * Determine if a value is an ArrayBuffer\n *\n * @function\n * @param {Object} val The value to test\n * @returns {boolean} True if value is an ArrayBuffer, otherwise false\n */\nvar isArrayBuffer = kindOfTest('ArrayBuffer');\n\n\n/**\n * Determine if a value is a view on an ArrayBuffer\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if value is a view on an ArrayBuffer, otherwise false\n */\nfunction isArrayBufferView(val) {\n var result;\n if ((typeof ArrayBuffer !== 'undefined') && (ArrayBuffer.isView)) {\n result = ArrayBuffer.isView(val);\n } else {\n result = (val) && (val.buffer) && (isArrayBuffer(val.buffer));\n }\n return result;\n}\n\n/**\n * Determine if a value is a String\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if value is a String, otherwise false\n */\nfunction isString(val) {\n return typeof val === 'string';\n}\n\n/**\n * Determine if a value is a Number\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if value is a Number, otherwise false\n */\nfunction isNumber(val) {\n return typeof val === 'number';\n}\n\n/**\n * Determine if a value is an Object\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if value is an Object, otherwise false\n */\nfunction isObject(val) {\n return val !== null && typeof val === 'object';\n}\n\n/**\n * Determine if a value is a plain Object\n *\n * @param {Object} val The value to test\n * @return {boolean} True if value is a plain Object, otherwise false\n */\nfunction isPlainObject(val) {\n if (kindOf(val) !== 'object') {\n return false;\n }\n\n var prototype = Object.getPrototypeOf(val);\n return prototype === null || prototype === Object.prototype;\n}\n\n/**\n * Determine if a value is a Date\n *\n * @function\n * @param {Object} val The value to test\n * @returns {boolean} True if value is a Date, otherwise false\n */\nvar isDate = kindOfTest('Date');\n\n/**\n * Determine if a value is a File\n *\n * @function\n * @param {Object} val The value to test\n * @returns {boolean} True if value is a File, otherwise false\n */\nvar isFile = kindOfTest('File');\n\n/**\n * Determine if a value is a Blob\n *\n * @function\n * @param {Object} val The value to test\n * @returns {boolean} True if value is a Blob, otherwise false\n */\nvar isBlob = kindOfTest('Blob');\n\n/**\n * Determine if a value is a FileList\n *\n * @function\n * @param {Object} val The value to test\n * @returns {boolean} True if value is a File, otherwise false\n */\nvar isFileList = kindOfTest('FileList');\n\n/**\n * Determine if a value is a Function\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if value is a Function, otherwise false\n */\nfunction isFunction(val) {\n return toString.call(val) === '[object Function]';\n}\n\n/**\n * Determine if a value is a Stream\n *\n * @param {Object} val The value to test\n * @returns {boolean} True if value is a Stream, otherwise false\n */\nfunction isStream(val) {\n return isObject(val) && isFunction(val.pipe);\n}\n\n/**\n * Determine if a value is a FormData\n *\n * @param {Object} thing The value to test\n * @returns {boolean} True if value is an FormData, otherwise false\n */\nfunction isFormData(thing) {\n var pattern = '[object FormData]';\n return thing && (\n (typeof FormData === 'function' && thing instanceof FormData) ||\n toString.call(thing) === pattern ||\n (isFunction(thing.toString) && thing.toString() === pattern)\n );\n}\n\n/**\n * Determine if a value is a URLSearchParams object\n * @function\n * @param {Object} val The value to test\n * @returns {boolean} True if value is a URLSearchParams object, otherwise false\n */\nvar isURLSearchParams = kindOfTest('URLSearchParams');\n\n/**\n * Trim excess whitespace off the beginning and end of a string\n *\n * @param {String} str The String to trim\n * @returns {String} The String freed of excess whitespace\n */\nfunction trim(str) {\n return str.trim ? str.trim() : str.replace(/^\\s+|\\s+$/g, '');\n}\n\n/**\n * Determine if we're running in a standard browser environment\n *\n * This allows axios to run in a web worker, and react-native.\n * Both environments support XMLHttpRequest, but not fully standard globals.\n *\n * web workers:\n * typeof window -> undefined\n * typeof document -> undefined\n *\n * react-native:\n * navigator.product -> 'ReactNative'\n * nativescript\n * navigator.product -> 'NativeScript' or 'NS'\n */\nfunction isStandardBrowserEnv() {\n if (typeof navigator !== 'undefined' && (navigator.product === 'ReactNative' ||\n navigator.product === 'NativeScript' ||\n navigator.product === 'NS')) {\n return false;\n }\n return (\n typeof window !== 'undefined' &&\n typeof document !== 'undefined'\n );\n}\n\n/**\n * Iterate over an Array or an Object invoking a function for each item.\n *\n * If `obj` is an Array callback will be called passing\n * the value, index, and complete array for each item.\n *\n * If 'obj' is an Object callback will be called passing\n * the value, key, and complete object for each property.\n *\n * @param {Object|Array} obj The object to iterate\n * @param {Function} fn The callback to invoke for each item\n */\nfunction forEach(obj, fn) {\n // Don't bother if no value provided\n if (obj === null || typeof obj === 'undefined') {\n return;\n }\n\n // Force an array if not already something iterable\n if (typeof obj !== 'object') {\n /*eslint no-param-reassign:0*/\n obj = [obj];\n }\n\n if (isArray(obj)) {\n // Iterate over array values\n for (var i = 0, l = obj.length; i < l; i++) {\n fn.call(null, obj[i], i, obj);\n }\n } else {\n // Iterate over object keys\n for (var key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n fn.call(null, obj[key], key, obj);\n }\n }\n }\n}\n\n/**\n * Accepts varargs expecting each argument to be an object, then\n * immutably merges the properties of each object and returns result.\n *\n * When multiple objects contain the same key the later object in\n * the arguments list will take precedence.\n *\n * Example:\n *\n * ```js\n * var result = merge({foo: 123}, {foo: 456});\n * console.log(result.foo); // outputs 456\n * ```\n *\n * @param {Object} obj1 Object to merge\n * @returns {Object} Result of all merge properties\n */\nfunction merge(/* obj1, obj2, obj3, ... */) {\n var result = {};\n function assignValue(val, key) {\n if (isPlainObject(result[key]) && isPlainObject(val)) {\n result[key] = merge(result[key], val);\n } else if (isPlainObject(val)) {\n result[key] = merge({}, val);\n } else if (isArray(val)) {\n result[key] = val.slice();\n } else {\n result[key] = val;\n }\n }\n\n for (var i = 0, l = arguments.length; i < l; i++) {\n forEach(arguments[i], assignValue);\n }\n return result;\n}\n\n/**\n * Extends object a by mutably adding to it the properties of object b.\n *\n * @param {Object} a The object to be extended\n * @param {Object} b The object to copy properties from\n * @param {Object} thisArg The object to bind function to\n * @return {Object} The resulting value of object a\n */\nfunction extend(a, b, thisArg) {\n forEach(b, function assignValue(val, key) {\n if (thisArg && typeof val === 'function') {\n a[key] = bind(val, thisArg);\n } else {\n a[key] = val;\n }\n });\n return a;\n}\n\n/**\n * Remove byte order marker. This catches EF BB BF (the UTF-8 BOM)\n *\n * @param {string} content with BOM\n * @return {string} content value without BOM\n */\nfunction stripBOM(content) {\n if (content.charCodeAt(0) === 0xFEFF) {\n content = content.slice(1);\n }\n return content;\n}\n\n/**\n * Inherit the prototype methods from one constructor into another\n * @param {function} constructor\n * @param {function} superConstructor\n * @param {object} [props]\n * @param {object} [descriptors]\n */\n\nfunction inherits(constructor, superConstructor, props, descriptors) {\n constructor.prototype = Object.create(superConstructor.prototype, descriptors);\n constructor.prototype.constructor = constructor;\n props && Object.assign(constructor.prototype, props);\n}\n\n/**\n * Resolve object with deep prototype chain to a flat object\n * @param {Object} sourceObj source object\n * @param {Object} [destObj]\n * @param {Function} [filter]\n * @returns {Object}\n */\n\nfunction toFlatObject(sourceObj, destObj, filter) {\n var props;\n var i;\n var prop;\n var merged = {};\n\n destObj = destObj || {};\n\n do {\n props = Object.getOwnPropertyNames(sourceObj);\n i = props.length;\n while (i-- > 0) {\n prop = props[i];\n if (!merged[prop]) {\n destObj[prop] = sourceObj[prop];\n merged[prop] = true;\n }\n }\n sourceObj = Object.getPrototypeOf(sourceObj);\n } while (sourceObj && (!filter || filter(sourceObj, destObj)) && sourceObj !== Object.prototype);\n\n return destObj;\n}\n\n/*\n * determines whether a string ends with the characters of a specified string\n * @param {String} str\n * @param {String} searchString\n * @param {Number} [position= 0]\n * @returns {boolean}\n */\nfunction endsWith(str, searchString, position) {\n str = String(str);\n if (position === undefined || position > str.length) {\n position = str.length;\n }\n position -= searchString.length;\n var lastIndex = str.indexOf(searchString, position);\n return lastIndex !== -1 && lastIndex === position;\n}\n\n\n/**\n * Returns new array from array like object\n * @param {*} [thing]\n * @returns {Array}\n */\nfunction toArray(thing) {\n if (!thing) return null;\n var i = thing.length;\n if (isUndefined(i)) return null;\n var arr = new Array(i);\n while (i-- > 0) {\n arr[i] = thing[i];\n }\n return arr;\n}\n\n// eslint-disable-next-line func-names\nvar isTypedArray = (function(TypedArray) {\n // eslint-disable-next-line func-names\n return function(thing) {\n return TypedArray && thing instanceof TypedArray;\n };\n})(typeof Uint8Array !== 'undefined' && Object.getPrototypeOf(Uint8Array));\n\nmodule.exports = {\n isArray: isArray,\n isArrayBuffer: isArrayBuffer,\n isBuffer: isBuffer,\n isFormData: isFormData,\n isArrayBufferView: isArrayBufferView,\n isString: isString,\n isNumber: isNumber,\n isObject: isObject,\n isPlainObject: isPlainObject,\n isUndefined: isUndefined,\n isDate: isDate,\n isFile: isFile,\n isBlob: isBlob,\n isFunction: isFunction,\n isStream: isStream,\n isURLSearchParams: isURLSearchParams,\n isStandardBrowserEnv: isStandardBrowserEnv,\n forEach: forEach,\n merge: merge,\n extend: extend,\n trim: trim,\n stripBOM: stripBOM,\n inherits: inherits,\n toFlatObject: toFlatObject,\n kindOf: kindOf,\n kindOfTest: kindOfTest,\n endsWith: endsWith,\n toArray: toArray,\n isTypedArray: isTypedArray,\n isFileList: isFileList\n};\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL3V0aWxzLmpzIiwibWFwcGluZ3MiOiJBQUFhOztBQUViLFdBQVcsbUJBQU8sQ0FBQyxnRUFBZ0I7O0FBRW5DOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsV0FBVyxRQUFRO0FBQ25CLGFBQWEsU0FBUztBQUN0QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLFFBQVE7QUFDbkIsYUFBYSxTQUFTO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsUUFBUTtBQUNuQixhQUFhLFNBQVM7QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsUUFBUTtBQUNuQixhQUFhLFNBQVM7QUFDdEI7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxRQUFRO0FBQ25CLGFBQWEsU0FBUztBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsUUFBUTtBQUNuQixhQUFhLFNBQVM7QUFDdEI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsV0FBVyxRQUFRO0FBQ25CLGFBQWEsU0FBUztBQUN0QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLFFBQVE7QUFDbkIsYUFBYSxTQUFTO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsUUFBUTtBQUNuQixZQUFZLFNBQVM7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLFFBQVE7QUFDbkIsYUFBYSxTQUFTO0FBQ3RCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLFFBQVE7QUFDbkIsYUFBYSxTQUFTO0FBQ3RCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLFFBQVE7QUFDbkIsYUFBYSxTQUFTO0FBQ3RCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLFFBQVE7QUFDbkIsYUFBYSxTQUFTO0FBQ3RCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsV0FBVyxRQUFRO0FBQ25CLGFBQWEsU0FBUztBQUN0QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLFFBQVE7QUFDbkIsYUFBYSxTQUFTO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsUUFBUTtBQUNuQixhQUFhLFNBQVM7QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsUUFBUTtBQUNuQixhQUFhLFNBQVM7QUFDdEI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLFFBQVE7QUFDbkIsYUFBYSxRQUFRO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxjQUFjO0FBQ3pCLFdBQVcsVUFBVTtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esb0NBQW9DLE9BQU87QUFDM0M7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCLFNBQVMsR0FBRyxTQUFTO0FBQzVDLDRCQUE0QjtBQUM1QjtBQUNBO0FBQ0EsV0FBVyxRQUFRO0FBQ25CLGFBQWEsUUFBUTtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ04sNEJBQTRCO0FBQzVCLE1BQU07QUFDTjtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7O0FBRUEsd0NBQXdDLE9BQU87QUFDL0M7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsV0FBVyxRQUFRO0FBQ25CLFdBQVcsUUFBUTtBQUNuQixXQUFXLFFBQVE7QUFDbkIsWUFBWSxRQUFRO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsUUFBUTtBQUNuQixZQUFZLFFBQVE7QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFdBQVcsVUFBVTtBQUNyQixXQUFXLFVBQVU7QUFDckIsV0FBVyxRQUFRO0FBQ25CLFdBQVcsUUFBUTtBQUNuQjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxXQUFXLFFBQVE7QUFDbkIsV0FBVyxRQUFRO0FBQ25CLFdBQVcsVUFBVTtBQUNyQixhQUFhO0FBQ2I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTs7QUFFSjtBQUNBOztBQUVBO0FBQ0E7QUFDQSxXQUFXLFFBQVE7QUFDbkIsV0FBVyxRQUFRO0FBQ25CLFdBQVcsUUFBUTtBQUNuQixhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQSxXQUFXLEdBQUc7QUFDZCxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvYXhpb3MvbGliL3V0aWxzLmpzP2M5ZWIiXSwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG52YXIgYmluZCA9IHJlcXVpcmUoJy4vaGVscGVycy9iaW5kJyk7XG5cbi8vIHV0aWxzIGlzIGEgbGlicmFyeSBvZiBnZW5lcmljIGhlbHBlciBmdW5jdGlvbnMgbm9uLXNwZWNpZmljIHRvIGF4aW9zXG5cbnZhciB0b1N0cmluZyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBmdW5jLW5hbWVzXG52YXIga2luZE9mID0gKGZ1bmN0aW9uKGNhY2hlKSB7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBmdW5jLW5hbWVzXG4gIHJldHVybiBmdW5jdGlvbih0aGluZykge1xuICAgIHZhciBzdHIgPSB0b1N0cmluZy5jYWxsKHRoaW5nKTtcbiAgICByZXR1cm4gY2FjaGVbc3RyXSB8fCAoY2FjaGVbc3RyXSA9IHN0ci5zbGljZSg4LCAtMSkudG9Mb3dlckNhc2UoKSk7XG4gIH07XG59KShPYmplY3QuY3JlYXRlKG51bGwpKTtcblxuZnVuY3Rpb24ga2luZE9mVGVzdCh0eXBlKSB7XG4gIHR5cGUgPSB0eXBlLnRvTG93ZXJDYXNlKCk7XG4gIHJldHVybiBmdW5jdGlvbiBpc0tpbmRPZih0aGluZykge1xuICAgIHJldHVybiBraW5kT2YodGhpbmcpID09PSB0eXBlO1xuICB9O1xufVxuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGFuIEFycmF5XG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHZhbCBUaGUgdmFsdWUgdG8gdGVzdFxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdmFsdWUgaXMgYW4gQXJyYXksIG90aGVyd2lzZSBmYWxzZVxuICovXG5mdW5jdGlvbiBpc0FycmF5KHZhbCkge1xuICByZXR1cm4gQXJyYXkuaXNBcnJheSh2YWwpO1xufVxuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIHVuZGVmaW5lZFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSB2YWwgVGhlIHZhbHVlIHRvIHRlc3RcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHRoZSB2YWx1ZSBpcyB1bmRlZmluZWQsIG90aGVyd2lzZSBmYWxzZVxuICovXG5mdW5jdGlvbiBpc1VuZGVmaW5lZCh2YWwpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWwgPT09ICd1bmRlZmluZWQnO1xufVxuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGEgQnVmZmVyXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHZhbCBUaGUgdmFsdWUgdG8gdGVzdFxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdmFsdWUgaXMgYSBCdWZmZXIsIG90aGVyd2lzZSBmYWxzZVxuICovXG5mdW5jdGlvbiBpc0J1ZmZlcih2YWwpIHtcbiAgcmV0dXJuIHZhbCAhPT0gbnVsbCAmJiAhaXNVbmRlZmluZWQodmFsKSAmJiB2YWwuY29uc3RydWN0b3IgIT09IG51bGwgJiYgIWlzVW5kZWZpbmVkKHZhbC5jb25zdHJ1Y3RvcilcbiAgICAmJiB0eXBlb2YgdmFsLmNvbnN0cnVjdG9yLmlzQnVmZmVyID09PSAnZnVuY3Rpb24nICYmIHZhbC5jb25zdHJ1Y3Rvci5pc0J1ZmZlcih2YWwpO1xufVxuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGFuIEFycmF5QnVmZmVyXG4gKlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge09iamVjdH0gdmFsIFRoZSB2YWx1ZSB0byB0ZXN0XG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB2YWx1ZSBpcyBhbiBBcnJheUJ1ZmZlciwgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbnZhciBpc0FycmF5QnVmZmVyID0ga2luZE9mVGVzdCgnQXJyYXlCdWZmZXInKTtcblxuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGEgdmlldyBvbiBhbiBBcnJheUJ1ZmZlclxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSB2YWwgVGhlIHZhbHVlIHRvIHRlc3RcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHZhbHVlIGlzIGEgdmlldyBvbiBhbiBBcnJheUJ1ZmZlciwgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzQXJyYXlCdWZmZXJWaWV3KHZhbCkge1xuICB2YXIgcmVzdWx0O1xuICBpZiAoKHR5cGVvZiBBcnJheUJ1ZmZlciAhPT0gJ3VuZGVmaW5lZCcpICYmIChBcnJheUJ1ZmZlci5pc1ZpZXcpKSB7XG4gICAgcmVzdWx0ID0gQXJyYXlCdWZmZXIuaXNWaWV3KHZhbCk7XG4gIH0gZWxzZSB7XG4gICAgcmVzdWx0ID0gKHZhbCkgJiYgKHZhbC5idWZmZXIpICYmIChpc0FycmF5QnVmZmVyKHZhbC5idWZmZXIpKTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGEgU3RyaW5nXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHZhbCBUaGUgdmFsdWUgdG8gdGVzdFxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdmFsdWUgaXMgYSBTdHJpbmcsIG90aGVyd2lzZSBmYWxzZVxuICovXG5mdW5jdGlvbiBpc1N0cmluZyh2YWwpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWwgPT09ICdzdHJpbmcnO1xufVxuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGEgTnVtYmVyXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHZhbCBUaGUgdmFsdWUgdG8gdGVzdFxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdmFsdWUgaXMgYSBOdW1iZXIsIG90aGVyd2lzZSBmYWxzZVxuICovXG5mdW5jdGlvbiBpc051bWJlcih2YWwpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWwgPT09ICdudW1iZXInO1xufVxuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGFuIE9iamVjdFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSB2YWwgVGhlIHZhbHVlIHRvIHRlc3RcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHZhbHVlIGlzIGFuIE9iamVjdCwgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzT2JqZWN0KHZhbCkge1xuICByZXR1cm4gdmFsICE9PSBudWxsICYmIHR5cGVvZiB2YWwgPT09ICdvYmplY3QnO1xufVxuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGEgcGxhaW4gT2JqZWN0XG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHZhbCBUaGUgdmFsdWUgdG8gdGVzdFxuICogQHJldHVybiB7Ym9vbGVhbn0gVHJ1ZSBpZiB2YWx1ZSBpcyBhIHBsYWluIE9iamVjdCwgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzUGxhaW5PYmplY3QodmFsKSB7XG4gIGlmIChraW5kT2YodmFsKSAhPT0gJ29iamVjdCcpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICB2YXIgcHJvdG90eXBlID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKHZhbCk7XG4gIHJldHVybiBwcm90b3R5cGUgPT09IG51bGwgfHwgcHJvdG90eXBlID09PSBPYmplY3QucHJvdG90eXBlO1xufVxuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGEgRGF0ZVxuICpcbiAqIEBmdW5jdGlvblxuICogQHBhcmFtIHtPYmplY3R9IHZhbCBUaGUgdmFsdWUgdG8gdGVzdFxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdmFsdWUgaXMgYSBEYXRlLCBvdGhlcndpc2UgZmFsc2VcbiAqL1xudmFyIGlzRGF0ZSA9IGtpbmRPZlRlc3QoJ0RhdGUnKTtcblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgYSB2YWx1ZSBpcyBhIEZpbGVcbiAqXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7T2JqZWN0fSB2YWwgVGhlIHZhbHVlIHRvIHRlc3RcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHZhbHVlIGlzIGEgRmlsZSwgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbnZhciBpc0ZpbGUgPSBraW5kT2ZUZXN0KCdGaWxlJyk7XG5cbi8qKlxuICogRGV0ZXJtaW5lIGlmIGEgdmFsdWUgaXMgYSBCbG9iXG4gKlxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge09iamVjdH0gdmFsIFRoZSB2YWx1ZSB0byB0ZXN0XG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB2YWx1ZSBpcyBhIEJsb2IsIG90aGVyd2lzZSBmYWxzZVxuICovXG52YXIgaXNCbG9iID0ga2luZE9mVGVzdCgnQmxvYicpO1xuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGEgRmlsZUxpc3RcbiAqXG4gKiBAZnVuY3Rpb25cbiAqIEBwYXJhbSB7T2JqZWN0fSB2YWwgVGhlIHZhbHVlIHRvIHRlc3RcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHZhbHVlIGlzIGEgRmlsZSwgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbnZhciBpc0ZpbGVMaXN0ID0ga2luZE9mVGVzdCgnRmlsZUxpc3QnKTtcblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgYSB2YWx1ZSBpcyBhIEZ1bmN0aW9uXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHZhbCBUaGUgdmFsdWUgdG8gdGVzdFxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdmFsdWUgaXMgYSBGdW5jdGlvbiwgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzRnVuY3Rpb24odmFsKSB7XG4gIHJldHVybiB0b1N0cmluZy5jYWxsKHZhbCkgPT09ICdbb2JqZWN0IEZ1bmN0aW9uXSc7XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lIGlmIGEgdmFsdWUgaXMgYSBTdHJlYW1cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gdmFsIFRoZSB2YWx1ZSB0byB0ZXN0XG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB2YWx1ZSBpcyBhIFN0cmVhbSwgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzU3RyZWFtKHZhbCkge1xuICByZXR1cm4gaXNPYmplY3QodmFsKSAmJiBpc0Z1bmN0aW9uKHZhbC5waXBlKTtcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgYSB2YWx1ZSBpcyBhIEZvcm1EYXRhXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHRoaW5nIFRoZSB2YWx1ZSB0byB0ZXN0XG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB2YWx1ZSBpcyBhbiBGb3JtRGF0YSwgb3RoZXJ3aXNlIGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzRm9ybURhdGEodGhpbmcpIHtcbiAgdmFyIHBhdHRlcm4gPSAnW29iamVjdCBGb3JtRGF0YV0nO1xuICByZXR1cm4gdGhpbmcgJiYgKFxuICAgICh0eXBlb2YgRm9ybURhdGEgPT09ICdmdW5jdGlvbicgJiYgdGhpbmcgaW5zdGFuY2VvZiBGb3JtRGF0YSkgfHxcbiAgICB0b1N0cmluZy5jYWxsKHRoaW5nKSA9PT0gcGF0dGVybiB8fFxuICAgIChpc0Z1bmN0aW9uKHRoaW5nLnRvU3RyaW5nKSAmJiB0aGluZy50b1N0cmluZygpID09PSBwYXR0ZXJuKVxuICApO1xufVxuXG4vKipcbiAqIERldGVybWluZSBpZiBhIHZhbHVlIGlzIGEgVVJMU2VhcmNoUGFyYW1zIG9iamVjdFxuICogQGZ1bmN0aW9uXG4gKiBAcGFyYW0ge09iamVjdH0gdmFsIFRoZSB2YWx1ZSB0byB0ZXN0XG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB2YWx1ZSBpcyBhIFVSTFNlYXJjaFBhcmFtcyBvYmplY3QsIG90aGVyd2lzZSBmYWxzZVxuICovXG52YXIgaXNVUkxTZWFyY2hQYXJhbXMgPSBraW5kT2ZUZXN0KCdVUkxTZWFyY2hQYXJhbXMnKTtcblxuLyoqXG4gKiBUcmltIGV4Y2VzcyB3aGl0ZXNwYWNlIG9mZiB0aGUgYmVnaW5uaW5nIGFuZCBlbmQgb2YgYSBzdHJpbmdcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gc3RyIFRoZSBTdHJpbmcgdG8gdHJpbVxuICogQHJldHVybnMge1N0cmluZ30gVGhlIFN0cmluZyBmcmVlZCBvZiBleGNlc3Mgd2hpdGVzcGFjZVxuICovXG5mdW5jdGlvbiB0cmltKHN0cikge1xuICByZXR1cm4gc3RyLnRyaW0gPyBzdHIudHJpbSgpIDogc3RyLnJlcGxhY2UoL15cXHMrfFxccyskL2csICcnKTtcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgaWYgd2UncmUgcnVubmluZyBpbiBhIHN0YW5kYXJkIGJyb3dzZXIgZW52aXJvbm1lbnRcbiAqXG4gKiBUaGlzIGFsbG93cyBheGlvcyB0byBydW4gaW4gYSB3ZWIgd29ya2VyLCBhbmQgcmVhY3QtbmF0aXZlLlxuICogQm90aCBlbnZpcm9ubWVudHMgc3VwcG9ydCBYTUxIdHRwUmVxdWVzdCwgYnV0IG5vdCBmdWxseSBzdGFuZGFyZCBnbG9iYWxzLlxuICpcbiAqIHdlYiB3b3JrZXJzOlxuICogIHR5cGVvZiB3aW5kb3cgLT4gdW5kZWZpbmVkXG4gKiAgdHlwZW9mIGRvY3VtZW50IC0+IHVuZGVmaW5lZFxuICpcbiAqIHJlYWN0LW5hdGl2ZTpcbiAqICBuYXZpZ2F0b3IucHJvZHVjdCAtPiAnUmVhY3ROYXRpdmUnXG4gKiBuYXRpdmVzY3JpcHRcbiAqICBuYXZpZ2F0b3IucHJvZHVjdCAtPiAnTmF0aXZlU2NyaXB0JyBvciAnTlMnXG4gKi9cbmZ1bmN0aW9uIGlzU3RhbmRhcmRCcm93c2VyRW52KCkge1xuICBpZiAodHlwZW9mIG5hdmlnYXRvciAhPT0gJ3VuZGVmaW5lZCcgJiYgKG5hdmlnYXRvci5wcm9kdWN0ID09PSAnUmVhY3ROYXRpdmUnIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF2aWdhdG9yLnByb2R1Y3QgPT09ICdOYXRpdmVTY3JpcHQnIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF2aWdhdG9yLnByb2R1Y3QgPT09ICdOUycpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiAoXG4gICAgdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgICB0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnXG4gICk7XG59XG5cbi8qKlxuICogSXRlcmF0ZSBvdmVyIGFuIEFycmF5IG9yIGFuIE9iamVjdCBpbnZva2luZyBhIGZ1bmN0aW9uIGZvciBlYWNoIGl0ZW0uXG4gKlxuICogSWYgYG9iamAgaXMgYW4gQXJyYXkgY2FsbGJhY2sgd2lsbCBiZSBjYWxsZWQgcGFzc2luZ1xuICogdGhlIHZhbHVlLCBpbmRleCwgYW5kIGNvbXBsZXRlIGFycmF5IGZvciBlYWNoIGl0ZW0uXG4gKlxuICogSWYgJ29iaicgaXMgYW4gT2JqZWN0IGNhbGxiYWNrIHdpbGwgYmUgY2FsbGVkIHBhc3NpbmdcbiAqIHRoZSB2YWx1ZSwga2V5LCBhbmQgY29tcGxldGUgb2JqZWN0IGZvciBlYWNoIHByb3BlcnR5LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fEFycmF5fSBvYmogVGhlIG9iamVjdCB0byBpdGVyYXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiBUaGUgY2FsbGJhY2sgdG8gaW52b2tlIGZvciBlYWNoIGl0ZW1cbiAqL1xuZnVuY3Rpb24gZm9yRWFjaChvYmosIGZuKSB7XG4gIC8vIERvbid0IGJvdGhlciBpZiBubyB2YWx1ZSBwcm92aWRlZFxuICBpZiAob2JqID09PSBudWxsIHx8IHR5cGVvZiBvYmogPT09ICd1bmRlZmluZWQnKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gRm9yY2UgYW4gYXJyYXkgaWYgbm90IGFscmVhZHkgc29tZXRoaW5nIGl0ZXJhYmxlXG4gIGlmICh0eXBlb2Ygb2JqICE9PSAnb2JqZWN0Jykge1xuICAgIC8qZXNsaW50IG5vLXBhcmFtLXJlYXNzaWduOjAqL1xuICAgIG9iaiA9IFtvYmpdO1xuICB9XG5cbiAgaWYgKGlzQXJyYXkob2JqKSkge1xuICAgIC8vIEl0ZXJhdGUgb3ZlciBhcnJheSB2YWx1ZXNcbiAgICBmb3IgKHZhciBpID0gMCwgbCA9IG9iai5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgIGZuLmNhbGwobnVsbCwgb2JqW2ldLCBpLCBvYmopO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICAvLyBJdGVyYXRlIG92ZXIgb2JqZWN0IGtleXNcbiAgICBmb3IgKHZhciBrZXkgaW4gb2JqKSB7XG4gICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwga2V5KSkge1xuICAgICAgICBmbi5jYWxsKG51bGwsIG9ialtrZXldLCBrZXksIG9iaik7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogQWNjZXB0cyB2YXJhcmdzIGV4cGVjdGluZyBlYWNoIGFyZ3VtZW50IHRvIGJlIGFuIG9iamVjdCwgdGhlblxuICogaW1tdXRhYmx5IG1lcmdlcyB0aGUgcHJvcGVydGllcyBvZiBlYWNoIG9iamVjdCBhbmQgcmV0dXJucyByZXN1bHQuXG4gKlxuICogV2hlbiBtdWx0aXBsZSBvYmplY3RzIGNvbnRhaW4gdGhlIHNhbWUga2V5IHRoZSBsYXRlciBvYmplY3QgaW5cbiAqIHRoZSBhcmd1bWVudHMgbGlzdCB3aWxsIHRha2UgcHJlY2VkZW5jZS5cbiAqXG4gKiBFeGFtcGxlOlxuICpcbiAqIGBgYGpzXG4gKiB2YXIgcmVzdWx0ID0gbWVyZ2Uoe2ZvbzogMTIzfSwge2ZvbzogNDU2fSk7XG4gKiBjb25zb2xlLmxvZyhyZXN1bHQuZm9vKTsgLy8gb3V0cHV0cyA0NTZcbiAqIGBgYFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmoxIE9iamVjdCB0byBtZXJnZVxuICogQHJldHVybnMge09iamVjdH0gUmVzdWx0IG9mIGFsbCBtZXJnZSBwcm9wZXJ0aWVzXG4gKi9cbmZ1bmN0aW9uIG1lcmdlKC8qIG9iajEsIG9iajIsIG9iajMsIC4uLiAqLykge1xuICB2YXIgcmVzdWx0ID0ge307XG4gIGZ1bmN0aW9uIGFzc2lnblZhbHVlKHZhbCwga2V5KSB7XG4gICAgaWYgKGlzUGxhaW5PYmplY3QocmVzdWx0W2tleV0pICYmIGlzUGxhaW5PYmplY3QodmFsKSkge1xuICAgICAgcmVzdWx0W2tleV0gPSBtZXJnZShyZXN1bHRba2V5XSwgdmFsKTtcbiAgICB9IGVsc2UgaWYgKGlzUGxhaW5PYmplY3QodmFsKSkge1xuICAgICAgcmVzdWx0W2tleV0gPSBtZXJnZSh7fSwgdmFsKTtcbiAgICB9IGVsc2UgaWYgKGlzQXJyYXkodmFsKSkge1xuICAgICAgcmVzdWx0W2tleV0gPSB2YWwuc2xpY2UoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVzdWx0W2tleV0gPSB2YWw7XG4gICAgfVxuICB9XG5cbiAgZm9yICh2YXIgaSA9IDAsIGwgPSBhcmd1bWVudHMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgZm9yRWFjaChhcmd1bWVudHNbaV0sIGFzc2lnblZhbHVlKTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKipcbiAqIEV4dGVuZHMgb2JqZWN0IGEgYnkgbXV0YWJseSBhZGRpbmcgdG8gaXQgdGhlIHByb3BlcnRpZXMgb2Ygb2JqZWN0IGIuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGEgVGhlIG9iamVjdCB0byBiZSBleHRlbmRlZFxuICogQHBhcmFtIHtPYmplY3R9IGIgVGhlIG9iamVjdCB0byBjb3B5IHByb3BlcnRpZXMgZnJvbVxuICogQHBhcmFtIHtPYmplY3R9IHRoaXNBcmcgVGhlIG9iamVjdCB0byBiaW5kIGZ1bmN0aW9uIHRvXG4gKiBAcmV0dXJuIHtPYmplY3R9IFRoZSByZXN1bHRpbmcgdmFsdWUgb2Ygb2JqZWN0IGFcbiAqL1xuZnVuY3Rpb24gZXh0ZW5kKGEsIGIsIHRoaXNBcmcpIHtcbiAgZm9yRWFjaChiLCBmdW5jdGlvbiBhc3NpZ25WYWx1ZSh2YWwsIGtleSkge1xuICAgIGlmICh0aGlzQXJnICYmIHR5cGVvZiB2YWwgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGFba2V5XSA9IGJpbmQodmFsLCB0aGlzQXJnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYVtrZXldID0gdmFsO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiBhO1xufVxuXG4vKipcbiAqIFJlbW92ZSBieXRlIG9yZGVyIG1hcmtlci4gVGhpcyBjYXRjaGVzIEVGIEJCIEJGICh0aGUgVVRGLTggQk9NKVxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBjb250ZW50IHdpdGggQk9NXG4gKiBAcmV0dXJuIHtzdHJpbmd9IGNvbnRlbnQgdmFsdWUgd2l0aG91dCBCT01cbiAqL1xuZnVuY3Rpb24gc3RyaXBCT00oY29udGVudCkge1xuICBpZiAoY29udGVudC5jaGFyQ29kZUF0KDApID09PSAweEZFRkYpIHtcbiAgICBjb250ZW50ID0gY29udGVudC5zbGljZSgxKTtcbiAgfVxuICByZXR1cm4gY29udGVudDtcbn1cblxuLyoqXG4gKiBJbmhlcml0IHRoZSBwcm90b3R5cGUgbWV0aG9kcyBmcm9tIG9uZSBjb25zdHJ1Y3RvciBpbnRvIGFub3RoZXJcbiAqIEBwYXJhbSB7ZnVuY3Rpb259IGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufSBzdXBlckNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge29iamVjdH0gW3Byb3BzXVxuICogQHBhcmFtIHtvYmplY3R9IFtkZXNjcmlwdG9yc11cbiAqL1xuXG5mdW5jdGlvbiBpbmhlcml0cyhjb25zdHJ1Y3Rvciwgc3VwZXJDb25zdHJ1Y3RvciwgcHJvcHMsIGRlc2NyaXB0b3JzKSB7XG4gIGNvbnN0cnVjdG9yLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoc3VwZXJDb25zdHJ1Y3Rvci5wcm90b3R5cGUsIGRlc2NyaXB0b3JzKTtcbiAgY29uc3RydWN0b3IucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gY29uc3RydWN0b3I7XG4gIHByb3BzICYmIE9iamVjdC5hc3NpZ24oY29uc3RydWN0b3IucHJvdG90eXBlLCBwcm9wcyk7XG59XG5cbi8qKlxuICogUmVzb2x2ZSBvYmplY3Qgd2l0aCBkZWVwIHByb3RvdHlwZSBjaGFpbiB0byBhIGZsYXQgb2JqZWN0XG4gKiBAcGFyYW0ge09iamVjdH0gc291cmNlT2JqIHNvdXJjZSBvYmplY3RcbiAqIEBwYXJhbSB7T2JqZWN0fSBbZGVzdE9ial1cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtmaWx0ZXJdXG4gKiBAcmV0dXJucyB7T2JqZWN0fVxuICovXG5cbmZ1bmN0aW9uIHRvRmxhdE9iamVjdChzb3VyY2VPYmosIGRlc3RPYmosIGZpbHRlcikge1xuICB2YXIgcHJvcHM7XG4gIHZhciBpO1xuICB2YXIgcHJvcDtcbiAgdmFyIG1lcmdlZCA9IHt9O1xuXG4gIGRlc3RPYmogPSBkZXN0T2JqIHx8IHt9O1xuXG4gIGRvIHtcbiAgICBwcm9wcyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHNvdXJjZU9iaik7XG4gICAgaSA9IHByb3BzLmxlbmd0aDtcbiAgICB3aGlsZSAoaS0tID4gMCkge1xuICAgICAgcHJvcCA9IHByb3BzW2ldO1xuICAgICAgaWYgKCFtZXJnZWRbcHJvcF0pIHtcbiAgICAgICAgZGVzdE9ialtwcm9wXSA9IHNvdXJjZU9ialtwcm9wXTtcbiAgICAgICAgbWVyZ2VkW3Byb3BdID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgc291cmNlT2JqID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKHNvdXJjZU9iaik7XG4gIH0gd2hpbGUgKHNvdXJjZU9iaiAmJiAoIWZpbHRlciB8fCBmaWx0ZXIoc291cmNlT2JqLCBkZXN0T2JqKSkgJiYgc291cmNlT2JqICE9PSBPYmplY3QucHJvdG90eXBlKTtcblxuICByZXR1cm4gZGVzdE9iajtcbn1cblxuLypcbiAqIGRldGVybWluZXMgd2hldGhlciBhIHN0cmluZyBlbmRzIHdpdGggdGhlIGNoYXJhY3RlcnMgb2YgYSBzcGVjaWZpZWQgc3RyaW5nXG4gKiBAcGFyYW0ge1N0cmluZ30gc3RyXG4gKiBAcGFyYW0ge1N0cmluZ30gc2VhcmNoU3RyaW5nXG4gKiBAcGFyYW0ge051bWJlcn0gW3Bvc2l0aW9uPSAwXVxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbmZ1bmN0aW9uIGVuZHNXaXRoKHN0ciwgc2VhcmNoU3RyaW5nLCBwb3NpdGlvbikge1xuICBzdHIgPSBTdHJpbmcoc3RyKTtcbiAgaWYgKHBvc2l0aW9uID09PSB1bmRlZmluZWQgfHwgcG9zaXRpb24gPiBzdHIubGVuZ3RoKSB7XG4gICAgcG9zaXRpb24gPSBzdHIubGVuZ3RoO1xuICB9XG4gIHBvc2l0aW9uIC09IHNlYXJjaFN0cmluZy5sZW5ndGg7XG4gIHZhciBsYXN0SW5kZXggPSBzdHIuaW5kZXhPZihzZWFyY2hTdHJpbmcsIHBvc2l0aW9uKTtcbiAgcmV0dXJuIGxhc3RJbmRleCAhPT0gLTEgJiYgbGFzdEluZGV4ID09PSBwb3NpdGlvbjtcbn1cblxuXG4vKipcbiAqIFJldHVybnMgbmV3IGFycmF5IGZyb20gYXJyYXkgbGlrZSBvYmplY3RcbiAqIEBwYXJhbSB7Kn0gW3RoaW5nXVxuICogQHJldHVybnMge0FycmF5fVxuICovXG5mdW5jdGlvbiB0b0FycmF5KHRoaW5nKSB7XG4gIGlmICghdGhpbmcpIHJldHVybiBudWxsO1xuICB2YXIgaSA9IHRoaW5nLmxlbmd0aDtcbiAgaWYgKGlzVW5kZWZpbmVkKGkpKSByZXR1cm4gbnVsbDtcbiAgdmFyIGFyciA9IG5ldyBBcnJheShpKTtcbiAgd2hpbGUgKGktLSA+IDApIHtcbiAgICBhcnJbaV0gPSB0aGluZ1tpXTtcbiAgfVxuICByZXR1cm4gYXJyO1xufVxuXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZnVuYy1uYW1lc1xudmFyIGlzVHlwZWRBcnJheSA9IChmdW5jdGlvbihUeXBlZEFycmF5KSB7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBmdW5jLW5hbWVzXG4gIHJldHVybiBmdW5jdGlvbih0aGluZykge1xuICAgIHJldHVybiBUeXBlZEFycmF5ICYmIHRoaW5nIGluc3RhbmNlb2YgVHlwZWRBcnJheTtcbiAgfTtcbn0pKHR5cGVvZiBVaW50OEFycmF5ICE9PSAndW5kZWZpbmVkJyAmJiBPYmplY3QuZ2V0UHJvdG90eXBlT2YoVWludDhBcnJheSkpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgaXNBcnJheTogaXNBcnJheSxcbiAgaXNBcnJheUJ1ZmZlcjogaXNBcnJheUJ1ZmZlcixcbiAgaXNCdWZmZXI6IGlzQnVmZmVyLFxuICBpc0Zvcm1EYXRhOiBpc0Zvcm1EYXRhLFxuICBpc0FycmF5QnVmZmVyVmlldzogaXNBcnJheUJ1ZmZlclZpZXcsXG4gIGlzU3RyaW5nOiBpc1N0cmluZyxcbiAgaXNOdW1iZXI6IGlzTnVtYmVyLFxuICBpc09iamVjdDogaXNPYmplY3QsXG4gIGlzUGxhaW5PYmplY3Q6IGlzUGxhaW5PYmplY3QsXG4gIGlzVW5kZWZpbmVkOiBpc1VuZGVmaW5lZCxcbiAgaXNEYXRlOiBpc0RhdGUsXG4gIGlzRmlsZTogaXNGaWxlLFxuICBpc0Jsb2I6IGlzQmxvYixcbiAgaXNGdW5jdGlvbjogaXNGdW5jdGlvbixcbiAgaXNTdHJlYW06IGlzU3RyZWFtLFxuICBpc1VSTFNlYXJjaFBhcmFtczogaXNVUkxTZWFyY2hQYXJhbXMsXG4gIGlzU3RhbmRhcmRCcm93c2VyRW52OiBpc1N0YW5kYXJkQnJvd3NlckVudixcbiAgZm9yRWFjaDogZm9yRWFjaCxcbiAgbWVyZ2U6IG1lcmdlLFxuICBleHRlbmQ6IGV4dGVuZCxcbiAgdHJpbTogdHJpbSxcbiAgc3RyaXBCT006IHN0cmlwQk9NLFxuICBpbmhlcml0czogaW5oZXJpdHMsXG4gIHRvRmxhdE9iamVjdDogdG9GbGF0T2JqZWN0LFxuICBraW5kT2Y6IGtpbmRPZixcbiAga2luZE9mVGVzdDoga2luZE9mVGVzdCxcbiAgZW5kc1dpdGg6IGVuZHNXaXRoLFxuICB0b0FycmF5OiB0b0FycmF5LFxuICBpc1R5cGVkQXJyYXk6IGlzVHlwZWRBcnJheSxcbiAgaXNGaWxlTGlzdDogaXNGaWxlTGlzdFxufTtcbiJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/axios/lib/utils.js\n");
/***/ }),
/***/ "./node_modules/bootstrap-select/dist/js/bootstrap-select.min.js":
/*!***********************************************************************!*\
!*** ./node_modules/bootstrap-select/dist/js/bootstrap-select.min.js ***!
\***********************************************************************/
/***/ (function(module, exports, __webpack_require__) {
eval("var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!\n * Bootstrap-select v1.13.18 (https://developer.snapappointments.com/bootstrap-select)\n *\n * Copyright 2012-2020 SnapAppointments, LLC\n * Licensed under MIT (https://github.com/snapappointments/bootstrap-select/blob/master/LICENSE)\n */\n\n!function(e,t){void 0===e&&void 0!==window&&(e=window), true?!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\")], __WEBPACK_AMD_DEFINE_RESULT__ = (function(e){return t(e)}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),\n\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)):0}(this,function(e){!function(P){\"use strict\";var d=[\"sanitize\",\"whiteList\",\"sanitizeFn\"],r=[\"background\",\"cite\",\"href\",\"itemtype\",\"longdesc\",\"poster\",\"src\",\"xlink:href\"],e={\"*\":[\"class\",\"dir\",\"id\",\"lang\",\"role\",\"tabindex\",\"style\",/^aria-[\\w-]*$/i],a:[\"target\",\"href\",\"title\",\"rel\"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:[\"src\",\"alt\",\"title\",\"width\",\"height\"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},l=/^(?:(?:https?|mailto|ftp|tel|file):|[^&:/?#]*(?:[/?#]|$))/gi,a=/^data:(?:image\\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\\/(?:mpeg|mp4|ogg|webm)|audio\\/(?:mp3|oga|ogg|opus));base64,[a-z0-9+/]+=*$/i;function v(e,t){var i=e.nodeName.toLowerCase();if(-1!==P.inArray(i,t))return-1===P.inArray(i,r)||Boolean(e.nodeValue.match(l)||e.nodeValue.match(a));for(var s=P(t).filter(function(e,t){return t instanceof RegExp}),n=0,o=s.length;n<o;n++)if(i.match(s[n]))return!0;return!1}function W(e,t,i){if(i&&\"function\"==typeof i)return i(e);for(var s=Object.keys(t),n=0,o=e.length;n<o;n++)for(var r=e[n].querySelectorAll(\"*\"),l=0,a=r.length;l<a;l++){var c=r[l],d=c.nodeName.toLowerCase();if(-1!==s.indexOf(d))for(var h=[].slice.call(c.attributes),p=[].concat(t[\"*\"]||[],t[d]||[]),u=0,f=h.length;u<f;u++){var m=h[u];v(m,p)||c.removeAttribute(m.nodeName)}else c.parentNode.removeChild(c)}}\"classList\"in document.createElement(\"_\")||function(e){if(\"Element\"in e){var t=\"classList\",i=\"prototype\",s=e.Element[i],n=Object,o=function(){var i=P(this);return{add:function(e){return e=Array.prototype.slice.call(arguments).join(\" \"),i.addClass(e)},remove:function(e){return e=Array.prototype.slice.call(arguments).join(\" \"),i.removeClass(e)},toggle:function(e,t){return i.toggleClass(e,t)},contains:function(e){return i.hasClass(e)}}};if(n.defineProperty){var r={get:o,enumerable:!0,configurable:!0};try{n.defineProperty(s,t,r)}catch(e){void 0!==e.number&&-2146823252!==e.number||(r.enumerable=!1,n.defineProperty(s,t,r))}}else n[i].__defineGetter__&&s.__defineGetter__(t,o)}}(window);var t,c,i=document.createElement(\"_\");if(i.classList.add(\"c1\",\"c2\"),!i.classList.contains(\"c2\")){var s=DOMTokenList.prototype.add,n=DOMTokenList.prototype.remove;DOMTokenList.prototype.add=function(){Array.prototype.forEach.call(arguments,s.bind(this))},DOMTokenList.prototype.remove=function(){Array.prototype.forEach.call(arguments,n.bind(this))}}if(i.classList.toggle(\"c3\",!1),i.classList.contains(\"c3\")){var o=DOMTokenList.prototype.toggle;DOMTokenList.prototype.toggle=function(e,t){return 1 in arguments&&!this.contains(e)==!t?t:o.call(this,e)}}function h(e){if(null==this)throw new TypeError;var t=String(this);if(e&&\"[object RegExp]\"==c.call(e))throw new TypeError;var i=t.length,s=String(e),n=s.length,o=1<arguments.length?arguments[1]:void 0,r=o?Number(o):0;r!=r&&(r=0);var l=Math.min(Math.max(r,0),i);if(i<n+l)return!1;for(var a=-1;++a<n;)if(t.charCodeAt(l+a)!=s.charCodeAt(a))return!1;return!0}function O(e,t){var i,s=e.selectedOptions,n=[];if(t){for(var o=0,r=s.length;o<r;o++)(i=s[o]).disabled||\"OPTGROUP\"===i.parentNode.tagName&&i.parentNode.disabled||n.push(i);return n}return s}function z(e,t){for(var i,s=[],n=t||e.selectedOptions,o=0,r=n.length;o<r;o++)(i=n[o]).disabled||\"OPTGROUP\"===i.parentNode.tagName&&i.parentNode.disabled||s.push(i.value);return e.multiple?s:s.length?s[0]:null}i=null,String.prototype.startsWith||(t=function(){try{var e={},t=Object.defineProperty,i=t(e,e,e)&&t}catch(e){}return i}(),c={}.toString,t?t(String.prototype,\"startsWith\",{value:h,configurable:!0,writable:!0}):String.prototype.startsWith=h),Object.keys||(Object.keys=function(e,t,i){for(t in i=[],e)i.hasOwnProperty.call(e,t)&&i.push(t);return i}),HTMLSelectElement&&!HTMLSelectElement.prototype.hasOwnProperty(\"selectedOptions\")&&Object.defineProperty(HTMLSelectElement.prototype,\"selectedOptions\",{get:function(){return this.querySelectorAll(\":checked\")}});var p={useDefault:!1,_set:P.valHooks.select.set};P.valHooks.select.set=function(e,t){return t&&!p.useDefault&&P(e).data(\"selected\",!0),p._set.apply(this,arguments)};var T=null,u=function(){try{return new Event(\"change\"),!0}catch(e){return!1}}();function k(e,t,i,s){for(var n=[\"display\",\"subtext\",\"tokens\"],o=!1,r=0;r<n.length;r++){var l=n[r],a=e[l];if(a&&(a=a.toString(),\"display\"===l&&(a=a.replace(/<[^>]+>/g,\"\")),s&&(a=w(a)),a=a.toUpperCase(),o=\"contains\"===i?0<=a.indexOf(t):a.startsWith(t)))break}return o}function N(e){return parseInt(e,10)||0}P.fn.triggerNative=function(e){var t,i=this[0];i.dispatchEvent?(u?t=new Event(e,{bubbles:!0}):(t=document.createEvent(\"Event\")).initEvent(e,!0,!1),i.dispatchEvent(t)):i.fireEvent?((t=document.createEventObject()).eventType=e,i.fireEvent(\"on\"+e,t)):this.trigger(e)};var f={\"\\xc0\":\"A\",\"\\xc1\":\"A\",\"\\xc2\":\"A\",\"\\xc3\":\"A\",\"\\xc4\":\"A\",\"\\xc5\":\"A\",\"\\xe0\":\"a\",\"\\xe1\":\"a\",\"\\xe2\":\"a\",\"\\xe3\":\"a\",\"\\xe4\":\"a\",\"\\xe5\":\"a\",\"\\xc7\":\"C\",\"\\xe7\":\"c\",\"\\xd0\":\"D\",\"\\xf0\":\"d\",\"\\xc8\":\"E\",\"\\xc9\":\"E\",\"\\xca\":\"E\",\"\\xcb\":\"E\",\"\\xe8\":\"e\",\"\\xe9\":\"e\",\"\\xea\":\"e\",\"\\xeb\":\"e\",\"\\xcc\":\"I\",\"\\xcd\":\"I\",\"\\xce\":\"I\",\"\\xcf\":\"I\",\"\\xec\":\"i\",\"\\xed\":\"i\",\"\\xee\":\"i\",\"\\xef\":\"i\",\"\\xd1\":\"N\",\"\\xf1\":\"n\",\"\\xd2\":\"O\",\"\\xd3\":\"O\",\"\\xd4\":\"O\",\"\\xd5\":\"O\",\"\\xd6\":\"O\",\"\\xd8\":\"O\",\"\\xf2\":\"o\",\"\\xf3\":\"o\",\"\\xf4\":\"o\",\"\\xf5\":\"o\",\"\\xf6\":\"o\",\"\\xf8\":\"o\",\"\\xd9\":\"U\",\"\\xda\":\"U\",\"\\xdb\":\"U\",\"\\xdc\":\"U\",\"\\xf9\":\"u\",\"\\xfa\":\"u\",\"\\xfb\":\"u\",\"\\xfc\":\"u\",\"\\xdd\":\"Y\",\"\\xfd\":\"y\",\"\\xff\":\"y\",\"\\xc6\":\"Ae\",\"\\xe6\":\"ae\",\"\\xde\":\"Th\",\"\\xfe\":\"th\",\"\\xdf\":\"ss\",\"\\u0100\":\"A\",\"\\u0102\":\"A\",\"\\u0104\":\"A\",\"\\u0101\":\"a\",\"\\u0103\":\"a\",\"\\u0105\":\"a\",\"\\u0106\":\"C\",\"\\u0108\":\"C\",\"\\u010a\":\"C\",\"\\u010c\":\"C\",\"\\u0107\":\"c\",\"\\u0109\":\"c\",\"\\u010b\":\"c\",\"\\u010d\":\"c\",\"\\u010e\":\"D\",\"\\u0110\":\"D\",\"\\u010f\":\"d\",\"\\u0111\":\"d\",\"\\u0112\":\"E\",\"\\u0114\":\"E\",\"\\u0116\":\"E\",\"\\u0118\":\"E\",\"\\u011a\":\"E\",\"\\u0113\":\"e\",\"\\u0115\":\"e\",\"\\u0117\":\"e\",\"\\u0119\":\"e\",\"\\u011b\":\"e\",\"\\u011c\":\"G\",\"\\u011e\":\"G\",\"\\u0120\":\"G\",\"\\u0122\":\"G\",\"\\u011d\":\"g\",\"\\u011f\":\"g\",\"\\u0121\":\"g\",\"\\u0123\":\"g\",\"\\u0124\":\"H\",\"\\u0126\":\"H\",\"\\u0125\":\"h\",\"\\u0127\":\"h\",\"\\u0128\":\"I\",\"\\u012a\":\"I\",\"\\u012c\":\"I\",\"\\u012e\":\"I\",\"\\u0130\":\"I\",\"\\u0129\":\"i\",\"\\u012b\":\"i\",\"\\u012d\":\"i\",\"\\u012f\":\"i\",\"\\u0131\":\"i\",\"\\u0134\":\"J\",\"\\u0135\":\"j\",\"\\u0136\":\"K\",\"\\u0137\":\"k\",\"\\u0138\":\"k\",\"\\u0139\":\"L\",\"\\u013b\":\"L\",\"\\u013d\":\"L\",\"\\u013f\":\"L\",\"\\u0141\":\"L\",\"\\u013a\":\"l\",\"\\u013c\":\"l\",\"\\u013e\":\"l\",\"\\u0140\":\"l\",\"\\u0142\":\"l\",\"\\u0143\":\"N\",\"\\u0145\":\"N\",\"\\u0147\":\"N\",\"\\u014a\":\"N\",\"\\u0144\":\"n\",\"\\u0146\":\"n\",\"\\u0148\":\"n\",\"\\u014b\":\"n\",\"\\u014c\":\"O\",\"\\u014e\":\"O\",\"\\u0150\":\"O\",\"\\u014d\":\"o\",\"\\u014f\":\"o\",\"\\u0151\":\"o\",\"\\u0154\":\"R\",\"\\u0156\":\"R\",\"\\u0158\":\"R\",\"\\u0155\":\"r\",\"\\u0157\":\"r\",\"\\u0159\":\"r\",\"\\u015a\":\"S\",\"\\u015c\":\"S\",\"\\u015e\":\"S\",\"\\u0160\":\"S\",\"\\u015b\":\"s\",\"\\u015d\":\"s\",\"\\u015f\":\"s\",\"\\u0161\":\"s\",\"\\u0162\":\"T\",\"\\u0164\":\"T\",\"\\u0166\":\"T\",\"\\u0163\":\"t\",\"\\u0165\":\"t\",\"\\u0167\":\"t\",\"\\u0168\":\"U\",\"\\u016a\":\"U\",\"\\u016c\":\"U\",\"\\u016e\":\"U\",\"\\u0170\":\"U\",\"\\u0172\":\"U\",\"\\u0169\":\"u\",\"\\u016b\":\"u\",\"\\u016d\":\"u\",\"\\u016f\":\"u\",\"\\u0171\":\"u\",\"\\u0173\":\"u\",\"\\u0174\":\"W\",\"\\u0175\":\"w\",\"\\u0176\":\"Y\",\"\\u0177\":\"y\",\"\\u0178\":\"Y\",\"\\u0179\":\"Z\",\"\\u017b\":\"Z\",\"\\u017d\":\"Z\",\"\\u017a\":\"z\",\"\\u017c\":\"z\",\"\\u017e\":\"z\",\"\\u0132\":\"IJ\",\"\\u0133\":\"ij\",\"\\u0152\":\"Oe\",\"\\u0153\":\"oe\",\"\\u0149\":\"'n\",\"\\u017f\":\"s\"},m=/[\\xc0-\\xd6\\xd8-\\xf6\\xf8-\\xff\\u0100-\\u017f]/g,g=RegExp(\"[\\\\u0300-\\\\u036f\\\\ufe20-\\\\ufe2f\\\\u20d0-\\\\u20ff\\\\u1ab0-\\\\u1aff\\\\u1dc0-\\\\u1dff]\",\"g\");function b(e){return f[e]}function w(e){return(e=e.toString())&&e.replace(m,b).replace(g,\"\")}var I,x,y,$,S=(I={\"&\":\"&amp;\",\"<\":\"&lt;\",\">\":\"&gt;\",'\"':\"&quot;\",\"'\":\"&#x27;\",\"`\":\"&#x60;\"},x=\"(?:\"+Object.keys(I).join(\"|\")+\")\",y=RegExp(x),$=RegExp(x,\"g\"),function(e){return e=null==e?\"\":\"\"+e,y.test(e)?e.replace($,E):e});function E(e){return I[e]}var C={32:\" \",48:\"0\",49:\"1\",50:\"2\",51:\"3\",52:\"4\",53:\"5\",54:\"6\",55:\"7\",56:\"8\",57:\"9\",59:\";\",65:\"A\",66:\"B\",67:\"C\",68:\"D\",69:\"E\",70:\"F\",71:\"G\",72:\"H\",73:\"I\",74:\"J\",75:\"K\",76:\"L\",77:\"M\",78:\"N\",79:\"O\",80:\"P\",81:\"Q\",82:\"R\",83:\"S\",84:\"T\",85:\"U\",86:\"V\",87:\"W\",88:\"X\",89:\"Y\",90:\"Z\",96:\"0\",97:\"1\",98:\"2\",99:\"3\",100:\"4\",101:\"5\",102:\"6\",103:\"7\",104:\"8\",105:\"9\"},A=27,L=13,D=32,H=9,B=38,R=40,M={success:!1,major:\"3\"};try{M.full=(P.fn.dropdown.Constructor.VERSION||\"\").split(\" \")[0].split(\".\"),M.major=M.full[0],M.success=!0}catch(e){}var U=0,j=\".bs.select\",V={DISABLED:\"disabled\",DIVIDER:\"divider\",SHOW:\"open\",DROPUP:\"dropup\",MENU:\"dropdown-menu\",MENURIGHT:\"dropdown-menu-right\",MENULEFT:\"dropdown-menu-left\",BUTTONCLASS:\"btn-default\",POPOVERHEADER:\"popover-title\",ICONBASE:\"glyphicon\",TICKICON:\"glyphicon-ok\"},F={MENU:\".\"+V.MENU},_={div:document.createElement(\"div\"),span:document.createElement(\"span\"),i:document.createElement(\"i\"),subtext:document.createElement(\"small\"),a:document.createElement(\"a\"),li:document.createElement(\"li\"),whitespace:document.createTextNode(\"\\xa0\"),fragment:document.createDocumentFragment()};_.noResults=_.li.cloneNode(!1),_.noResults.className=\"no-results\",_.a.setAttribute(\"role\",\"option\"),_.a.className=\"dropdown-item\",_.subtext.className=\"text-muted\",_.text=_.span.cloneNode(!1),_.text.className=\"text\",_.checkMark=_.span.cloneNode(!1);var G=new RegExp(B+\"|\"+R),q=new RegExp(\"^\"+H+\"$|\"+A),K={li:function(e,t,i){var s=_.li.cloneNode(!1);return e&&(1===e.nodeType||11===e.nodeType?s.appendChild(e):s.innerHTML=e),void 0!==t&&\"\"!==t&&(s.className=t),null!=i&&s.classList.add(\"optgroup-\"+i),s},a:function(e,t,i){var s=_.a.cloneNode(!0);return e&&(11===e.nodeType?s.appendChild(e):s.insertAdjacentHTML(\"beforeend\",e)),void 0!==t&&\"\"!==t&&s.classList.add.apply(s.classList,t.split(/\\s+/)),i&&s.setAttribute(\"style\",i),s},text:function(e,t){var i,s,n=_.text.cloneNode(!1);if(e.content)n.innerHTML=e.content;else{if(n.textContent=e.text,e.icon){var o=_.whitespace.cloneNode(!1);(s=(!0===t?_.i:_.span).cloneNode(!1)).className=this.options.iconBase+\" \"+e.icon,_.fragment.appendChild(s),_.fragment.appendChild(o)}e.subtext&&((i=_.subtext.cloneNode(!1)).textContent=e.subtext,n.appendChild(i))}if(!0===t)for(;0<n.childNodes.length;)_.fragment.appendChild(n.childNodes[0]);else _.fragment.appendChild(n);return _.fragment},label:function(e){var t,i,s=_.text.cloneNode(!1);if(s.innerHTML=e.display,e.icon){var n=_.whitespace.cloneNode(!1);(i=_.span.cloneNode(!1)).className=this.options.iconBase+\" \"+e.icon,_.fragment.appendChild(i),_.fragment.appendChild(n)}return e.subtext&&((t=_.subtext.cloneNode(!1)).textContent=e.subtext,s.appendChild(t)),_.fragment.appendChild(s),_.fragment}};var Y=function(e,t){var i=this;p.useDefault||(P.valHooks.select.set=p._set,p.useDefault=!0),this.$element=P(e),this.$newElement=null,this.$button=null,this.$menu=null,this.options=t,this.selectpicker={main:{},search:{},current:{},view:{},isSearching:!1,keydown:{keyHistory:\"\",resetKeyHistory:{start:function(){return setTimeout(function(){i.selectpicker.keydown.keyHistory=\"\"},800)}}}},this.sizeInfo={},null===this.options.title&&(this.options.title=this.$element.attr(\"title\"));var s=this.options.windowPadding;\"number\"==typeof s&&(this.options.windowPadding=[s,s,s,s]),this.val=Y.prototype.val,this.render=Y.prototype.render,this.refresh=Y.prototype.refresh,this.setStyle=Y.prototype.setStyle,this.selectAll=Y.prototype.selectAll,this.deselectAll=Y.prototype.deselectAll,this.destroy=Y.prototype.destroy,this.remove=Y.prototype.remove,this.show=Y.prototype.show,this.hide=Y.prototype.hide,this.init()};function Z(e){var l,a=arguments,c=e;if([].shift.apply(a),!M.success){try{M.full=(P.fn.dropdown.Constructor.VERSION||\"\").split(\" \")[0].split(\".\")}catch(e){Y.BootstrapVersion?M.full=Y.BootstrapVersion.split(\" \")[0].split(\".\"):(M.full=[M.major,\"0\",\"0\"],console.warn(\"There was an issue retrieving Bootstrap's version. Ensure Bootstrap is being loaded before bootstrap-select and there is no namespace collision. If loading Bootstrap asynchronously, the version may need to be manually specified via $.fn.selectpicker.Constructor.BootstrapVersion.\",e))}M.major=M.full[0],M.success=!0}if(\"4\"===M.major){var t=[];Y.DEFAULTS.style===V.BUTTONCLASS&&t.push({name:\"style\",className:\"BUTTONCLASS\"}),Y.DEFAULTS.iconBase===V.ICONBASE&&t.push({name:\"iconBase\",className:\"ICONBASE\"}),Y.DEFAULTS.tickIcon===V.TICKICON&&t.push({name:\"tickIcon\",className:\"TICKICON\"}),V.DIVIDER=\"dropdown-divider\",V.SHOW=\"show\",V.BUTTONCLASS=\"btn-light\",V.POPOVERHEADER=\"popover-header\",V.ICONBASE=\"\",V.TICKICON=\"bs-ok-default\";for(var i=0;i<t.length;i++){e=t[i];Y.DEFAULTS[e.name]=V[e.className]}}var s=this.each(function(){var e=P(this);if(e.is(\"select\")){var t=e.data(\"selectpicker\"),i=\"object\"==typeof c&&c;if(t){if(i)for(var s in i)Object.prototype.hasOwnProperty.call(i,s)&&(t.options[s]=i[s])}else{var n=e.data();for(var o in n)Object.prototype.hasOwnProperty.call(n,o)&&-1!==P.inArray(o,d)&&delete n[o];var r=P.extend({},Y.DEFAULTS,P.fn.selectpicker.defaults||{},n,i);r.template=P.extend({},Y.DEFAULTS.template,P.fn.selectpicker.defaults?P.fn.selectpicker.defaults.template:{},n.template,i.template),e.data(\"selectpicker\",t=new Y(this,r))}\"string\"==typeof c&&(l=t[c]instanceof Function?t[c].apply(t,a):t.options[c])}});return void 0!==l?l:s}Y.VERSION=\"1.13.18\",Y.DEFAULTS={noneSelectedText:\"Nothing selected\",noneResultsText:\"No results matched {0}\",countSelectedText:function(e,t){return 1==e?\"{0} item selected\":\"{0} items selected\"},maxOptionsText:function(e,t){return[1==e?\"Limit reached ({n} item max)\":\"Limit reached ({n} items max)\",1==t?\"Group limit reached ({n} item max)\":\"Group limit reached ({n} items max)\"]},selectAllText:\"Select All\",deselectAllText:\"Deselect All\",doneButton:!1,doneButtonText:\"Close\",multipleSeparator:\", \",styleBase:\"btn\",style:V.BUTTONCLASS,size:\"auto\",title:null,selectedTextFormat:\"values\",width:!1,container:!1,hideDisabled:!1,showSubtext:!1,showIcon:!0,showContent:!0,dropupAuto:!0,header:!1,liveSearch:!1,liveSearchPlaceholder:null,liveSearchNormalize:!1,liveSearchStyle:\"contains\",actionsBox:!1,iconBase:V.ICONBASE,tickIcon:V.TICKICON,showTick:!1,template:{caret:'<span class=\"caret\"></span>'},maxOptions:!1,mobile:!1,selectOnTab:!1,dropdownAlignRight:!1,windowPadding:0,virtualScroll:600,display:!1,sanitize:!0,sanitizeFn:null,whiteList:e},Y.prototype={constructor:Y,init:function(){var i=this,e=this.$element.attr(\"id\"),t=this.$element[0],s=t.form;U++,this.selectId=\"bs-select-\"+U,t.classList.add(\"bs-select-hidden\"),this.multiple=this.$element.prop(\"multiple\"),this.autofocus=this.$element.prop(\"autofocus\"),t.classList.contains(\"show-tick\")&&(this.options.showTick=!0),this.$newElement=this.createDropdown(),this.buildData(),this.$element.after(this.$newElement).prependTo(this.$newElement),s&&null===t.form&&(s.id||(s.id=\"form-\"+this.selectId),t.setAttribute(\"form\",s.id)),this.$button=this.$newElement.children(\"button\"),this.$menu=this.$newElement.children(F.MENU),this.$menuInner=this.$menu.children(\".inner\"),this.$searchbox=this.$menu.find(\"input\"),t.classList.remove(\"bs-select-hidden\"),!0===this.options.dropdownAlignRight&&this.$menu[0].classList.add(V.MENURIGHT),void 0!==e&&this.$button.attr(\"data-id\",e),this.checkDisabled(),this.clickListener(),this.options.liveSearch?(this.liveSearchListener(),this.focusedParent=this.$searchbox[0]):this.focusedParent=this.$menuInner[0],this.setStyle(),this.render(),this.setWidth(),this.options.container?this.selectPosition():this.$element.on(\"hide\"+j,function(){if(i.isVirtual()){var e=i.$menuInner[0],t=e.firstChild.cloneNode(!1);e.replaceChild(t,e.firstChild),e.scrollTop=0}}),this.$menu.data(\"this\",this),this.$newElement.data(\"this\",this),this.options.mobile&&this.mobile(),this.$newElement.on({\"hide.bs.dropdown\":function(e){i.$element.trigger(\"hide\"+j,e)},\"hidden.bs.dropdown\":function(e){i.$element.trigger(\"hidden\"+j,e)},\"show.bs.dropdown\":function(e){i.$element.trigger(\"show\"+j,e)},\"shown.bs.dropdown\":function(e){i.$element.trigger(\"shown\"+j,e)}}),t.hasAttribute(\"required\")&&this.$element.on(\"invalid\"+j,function(){i.$button[0].classList.add(\"bs-invalid\"),i.$element.on(\"shown\"+j+\".invalid\",function(){i.$element.val(i.$element.val()).off(\"shown\"+j+\".invalid\")}).on(\"rendered\"+j,function(){this.validity.valid&&i.$button[0].classList.remove(\"bs-invalid\"),i.$element.off(\"rendered\"+j)}),i.$button.on(\"blur\"+j,function(){i.$element.trigger(\"focus\").trigger(\"blur\"),i.$button.off(\"blur\"+j)})}),setTimeout(function(){i.buildList(),i.$element.trigger(\"loaded\"+j)})},createDropdown:function(){var e=this.multiple||this.options.showTick?\" show-tick\":\"\",t=this.multiple?' aria-multiselectable=\"true\"':\"\",i=\"\",s=this.autofocus?\" autofocus\":\"\";M.major<4&&this.$element.parent().hasClass(\"input-group\")&&(i=\" input-group-btn\");var n,o=\"\",r=\"\",l=\"\",a=\"\";return this.options.header&&(o='<div class=\"'+V.POPOVERHEADER+'\"><button type=\"button\" class=\"close\" aria-hidden=\"true\">&times;</button>'+this.options.header+\"</div>\"),this.options.liveSearch&&(r='<div class=\"bs-searchbox\"><input type=\"search\" class=\"form-control\" autocomplete=\"off\"'+(null===this.options.liveSearchPlaceholder?\"\":' placeholder=\"'+S(this.options.liveSearchPlaceholder)+'\"')+' role=\"combobox\" aria-label=\"Search\" aria-controls=\"'+this.selectId+'\" aria-autocomplete=\"list\"></div>'),this.multiple&&this.options.actionsBox&&(l='<div class=\"bs-actionsbox\"><div class=\"btn-group btn-group-sm btn-block\"><button type=\"button\" class=\"actions-btn bs-select-all btn '+V.BUTTONCLASS+'\">'+this.options.selectAllText+'</button><button type=\"button\" class=\"actions-btn bs-deselect-all btn '+V.BUTTONCLASS+'\">'+this.options.deselectAllText+\"</button></div></div>\"),this.multiple&&this.options.doneButton&&(a='<div class=\"bs-donebutton\"><div class=\"btn-group btn-block\"><button type=\"button\" class=\"btn btn-sm '+V.BUTTONCLASS+'\">'+this.options.doneButtonText+\"</button></div></div>\"),n='<div class=\"dropdown bootstrap-select'+e+i+'\"><button type=\"button\" tabindex=\"-1\" class=\"'+this.options.styleBase+' dropdown-toggle\" '+(\"static\"===this.options.display?'data-display=\"static\"':\"\")+'data-toggle=\"dropdown\"'+s+' role=\"combobox\" aria-owns=\"'+this.selectId+'\" aria-haspopup=\"listbox\" aria-expanded=\"false\"><div class=\"filter-option\"><div class=\"filter-option-inner\"><div class=\"filter-option-inner-inner\"></div></div> </div>'+(\"4\"===M.major?\"\":'<span class=\"bs-caret\">'+this.options.template.caret+\"</span>\")+'</button><div class=\"'+V.MENU+\" \"+(\"4\"===M.major?\"\":V.SHOW)+'\">'+o+r+l+'<div class=\"inner '+V.SHOW+'\" role=\"listbox\" id=\"'+this.selectId+'\" tabindex=\"-1\" '+t+'><ul class=\"'+V.MENU+\" inner \"+(\"4\"===M.major?V.SHOW:\"\")+'\" role=\"presentation\"></ul></div>'+a+\"</div></div>\",P(n)},setPositionData:function(){this.selectpicker.view.canHighlight=[],this.selectpicker.view.size=0,this.selectpicker.view.firstHighlightIndex=!1;for(var e=0;e<this.selectpicker.current.data.length;e++){var t=this.selectpicker.current.data[e],i=!0;\"divider\"===t.type?(i=!1,t.height=this.sizeInfo.dividerHeight):\"optgroup-label\"===t.type?(i=!1,t.height=this.sizeInfo.dropdownHeaderHeight):t.height=this.sizeInfo.liHeight,t.disabled&&(i=!1),this.selectpicker.view.canHighlight.push(i),i&&(this.selectpicker.view.size++,t.posinset=this.selectpicker.view.size,!1===this.selectpicker.view.firstHighlightIndex&&(this.selectpicker.view.firstHighlightIndex=e)),t.position=(0===e?0:this.selectpicker.current.data[e-1].position)+t.height}},isVirtual:function(){return!1!==this.options.virtualScroll&&this.selectpicker.main.elements.length>=this.options.virtualScroll||!0===this.options.virtualScroll},createView:function(N,e,t){var A,L,D=this,i=0,H=[];if(this.selectpicker.isSearching=N,this.selectpicker.current=N?this.selectpicker.search:this.selectpicker.main,this.setPositionData(),e)if(t)i=this.$menuInner[0].scrollTop;else if(!D.multiple){var s=D.$element[0],n=(s.options[s.selectedIndex]||{}).liIndex;if(\"number\"==typeof n&&!1!==D.options.size){var o=D.selectpicker.main.data[n],r=o&&o.position;r&&(i=r-(D.sizeInfo.menuInnerHeight+D.sizeInfo.liHeight)/2)}}function l(e,t){var i,s,n,o,r,l,a,c,d=D.selectpicker.current.elements.length,h=[],p=!0,u=D.isVirtual();D.selectpicker.view.scrollTop=e,i=Math.ceil(D.sizeInfo.menuInnerHeight/D.sizeInfo.liHeight*1.5),s=Math.round(d/i)||1;for(var f=0;f<s;f++){var m=(f+1)*i;if(f===s-1&&(m=d),h[f]=[f*i+(f?1:0),m],!d)break;void 0===r&&e-1<=D.selectpicker.current.data[m-1].position-D.sizeInfo.menuInnerHeight&&(r=f)}if(void 0===r&&(r=0),l=[D.selectpicker.view.position0,D.selectpicker.view.position1],n=Math.max(0,r-1),o=Math.min(s-1,r+1),D.selectpicker.view.position0=!1===u?0:Math.max(0,h[n][0])||0,D.selectpicker.view.position1=!1===u?d:Math.min(d,h[o][1])||0,a=l[0]!==D.selectpicker.view.position0||l[1]!==D.selectpicker.view.position1,void 0!==D.activeIndex&&(L=D.selectpicker.main.elements[D.prevActiveIndex],H=D.selectpicker.main.elements[D.activeIndex],A=D.selectpicker.main.elements[D.selectedIndex],t&&(D.activeIndex!==D.selectedIndex&&D.defocusItem(H),D.activeIndex=void 0),D.activeIndex&&D.activeIndex!==D.selectedIndex&&D.defocusItem(A)),void 0!==D.prevActiveIndex&&D.prevActiveIndex!==D.activeIndex&&D.prevActiveIndex!==D.selectedIndex&&D.defocusItem(L),(t||a)&&(c=D.selectpicker.view.visibleElements?D.selectpicker.view.visibleElements.slice():[],D.selectpicker.view.visibleElements=!1===u?D.selectpicker.current.elements:D.selectpicker.current.elements.slice(D.selectpicker.view.position0,D.selectpicker.view.position1),D.setOptionStatus(),(N||!1===u&&t)&&(p=!function(e,i){return e.length===i.length&&e.every(function(e,t){return e===i[t]})}(c,D.selectpicker.view.visibleElements)),(t||!0===u)&&p)){var v,g,b=D.$menuInner[0],w=document.createDocumentFragment(),I=b.firstChild.cloneNode(!1),x=D.selectpicker.view.visibleElements,k=[];b.replaceChild(I,b.firstChild);f=0;for(var y=x.length;f<y;f++){var $,S,E=x[f];D.options.sanitize&&($=E.lastChild)&&(S=D.selectpicker.current.data[f+D.selectpicker.view.position0])&&S.content&&!S.sanitized&&(k.push($),S.sanitized=!0),w.appendChild(E)}if(D.options.sanitize&&k.length&&W(k,D.options.whiteList,D.options.sanitizeFn),!0===u?(v=0===D.selectpicker.view.position0?0:D.selectpicker.current.data[D.selectpicker.view.position0-1].position,g=D.selectpicker.view.position1>d-1?0:D.selectpicker.current.data[d-1].position-D.selectpicker.current.data[D.selectpicker.view.position1-1].position,b.firstChild.style.marginTop=v+\"px\",b.firstChild.style.marginBottom=g+\"px\"):(b.firstChild.style.marginTop=0,b.firstChild.style.marginBottom=0),b.firstChild.appendChild(w),!0===u&&D.sizeInfo.hasScrollBar){var C=b.firstChild.offsetWidth;if(t&&C<D.sizeInfo.menuInnerInnerWidth&&D.sizeInfo.totalMenuWidth>D.sizeInfo.selectWidth)b.firstChild.style.minWidth=D.sizeInfo.menuInnerInnerWidth+\"px\";else if(C>D.sizeInfo.menuInnerInnerWidth){D.$menu[0].style.minWidth=0;var O=b.firstChild.offsetWidth;O>D.sizeInfo.menuInnerInnerWidth&&(D.sizeInfo.menuInnerInnerWidth=O,b.firstChild.style.minWidth=D.sizeInfo.menuInnerInnerWidth+\"px\"),D.$menu[0].style.minWidth=\"\"}}}if(D.prevActiveIndex=D.activeIndex,D.options.liveSearch){if(N&&t){var z,T=0;D.selectpicker.view.canHighlight[T]||(T=1+D.selectpicker.view.canHighlight.slice(1).indexOf(!0)),z=D.selectpicker.view.visibleElements[T],D.defocusItem(D.selectpicker.view.currentActive),D.activeIndex=(D.selectpicker.current.data[T]||{}).index,D.focusItem(z)}}else D.$menuInner.trigger(\"focus\")}l(i,!0),this.$menuInner.off(\"scroll.createView\").on(\"scroll.createView\",function(e,t){D.noScroll||l(this.scrollTop,t),D.noScroll=!1}),P(window).off(\"resize\"+j+\".\"+this.selectId+\".createView\").on(\"resize\"+j+\".\"+this.selectId+\".createView\",function(){D.$newElement.hasClass(V.SHOW)&&l(D.$menuInner[0].scrollTop)})},focusItem:function(e,t,i){if(e){t=t||this.selectpicker.main.data[this.activeIndex];var s=e.firstChild;s&&(s.setAttribute(\"aria-setsize\",this.selectpicker.view.size),s.setAttribute(\"aria-posinset\",t.posinset),!0!==i&&(this.focusedParent.setAttribute(\"aria-activedescendant\",s.id),e.classList.add(\"active\"),s.classList.add(\"active\")))}},defocusItem:function(e){e&&(e.classList.remove(\"active\"),e.firstChild&&e.firstChild.classList.remove(\"active\"))},setPlaceholder:function(){var e=this,t=!1;if(this.options.title&&!this.multiple){this.selectpicker.view.titleOption||(this.selectpicker.view.titleOption=document.createElement(\"option\")),t=!0;var i=this.$element[0],s=!1,n=!this.selectpicker.view.titleOption.parentNode,o=i.selectedIndex,r=i.options[o],l=window.performance&&window.performance.getEntriesByType(\"navigation\"),a=l&&l.length?\"back_forward\"!==l[0].type:2!==window.performance.navigation.type;n&&(this.selectpicker.view.titleOption.className=\"bs-title-option\",this.selectpicker.view.titleOption.value=\"\",s=!r||0===o&&!1===r.defaultSelected&&void 0===this.$element.data(\"selected\")),!n&&0===this.selectpicker.view.titleOption.index||i.insertBefore(this.selectpicker.view.titleOption,i.firstChild),s&&a?i.selectedIndex=0:\"complete\"!==document.readyState&&window.addEventListener(\"pageshow\",function(){e.selectpicker.view.displayedValue!==i.value&&e.render()})}return t},buildData:function(){var p=':not([hidden]):not([data-hidden=\"true\"])',u=[],f=0,m=this.setPlaceholder()?1:0;this.options.hideDisabled&&(p+=\":not(:disabled)\");var e=this.$element[0].querySelectorAll(\"select > *\"+p);function v(e){var t=u[u.length-1];t&&\"divider\"===t.type&&(t.optID||e.optID)||((e=e||{}).type=\"divider\",u.push(e))}function g(e,t){if((t=t||{}).divider=\"true\"===e.getAttribute(\"data-divider\"),t.divider)v({optID:t.optID});else{var i=u.length,s=e.style.cssText,n=s?S(s):\"\",o=(e.className||\"\")+(t.optgroupClass||\"\");t.optID&&(o=\"opt \"+o),t.optionClass=o.trim(),t.inlineStyle=n,t.text=e.textContent,t.content=e.getAttribute(\"data-content\"),t.tokens=e.getAttribute(\"data-tokens\"),t.subtext=e.getAttribute(\"data-subtext\"),t.icon=e.getAttribute(\"data-icon\"),e.liIndex=i,t.display=t.content||t.text,t.type=\"option\",t.index=i,t.option=e,t.selected=!!e.selected,t.disabled=t.disabled||!!e.disabled,u.push(t)}}function t(e,t){var i=t[e],s=!(e-1<m)&&t[e-1],n=t[e+1],o=i.querySelectorAll(\"option\"+p);if(o.length){var r,l,a={display:S(i.label),subtext:i.getAttribute(\"data-subtext\"),icon:i.getAttribute(\"data-icon\"),type:\"optgroup-label\",optgroupClass:\" \"+(i.className||\"\")};f++,s&&v({optID:f}),a.optID=f,u.push(a);for(var c=0,d=o.length;c<d;c++){var h=o[c];0===c&&(l=(r=u.length-1)+d),g(h,{headerIndex:r,lastIndex:l,optID:a.optID,optgroupClass:a.optgroupClass,disabled:i.disabled})}n&&v({optID:f})}}for(var i=e.length,s=m;s<i;s++){var n=e[s];\"OPTGROUP\"!==n.tagName?g(n,{}):t(s,e)}this.selectpicker.main.data=this.selectpicker.current.data=u},buildList:function(){var s=this,e=this.selectpicker.main.data,n=[],o=0;function t(e){var t,i=0;switch(e.type){case\"divider\":t=K.li(!1,V.DIVIDER,e.optID?e.optID+\"div\":void 0);break;case\"option\":(t=K.li(K.a(K.text.call(s,e),e.optionClass,e.inlineStyle),\"\",e.optID)).firstChild&&(t.firstChild.id=s.selectId+\"-\"+e.index);break;case\"optgroup-label\":t=K.li(K.label.call(s,e),\"dropdown-header\"+e.optgroupClass,e.optID)}e.element=t,n.push(t),e.display&&(i+=e.display.length),e.subtext&&(i+=e.subtext.length),e.icon&&(i+=1),o<i&&(o=i,s.selectpicker.view.widestOption=n[n.length-1])}!s.options.showTick&&!s.multiple||_.checkMark.parentNode||(_.checkMark.className=this.options.iconBase+\" \"+s.options.tickIcon+\" check-mark\",_.a.appendChild(_.checkMark));for(var i=e.length,r=0;r<i;r++){t(e[r])}this.selectpicker.main.elements=this.selectpicker.current.elements=n},findLis:function(){return this.$menuInner.find(\".inner > li\")},render:function(){var e,t=this,i=this.$element[0],s=this.setPlaceholder()&&0===i.selectedIndex,n=O(i,this.options.hideDisabled),o=n.length,r=this.$button[0],l=r.querySelector(\".filter-option-inner-inner\"),a=document.createTextNode(this.options.multipleSeparator),c=_.fragment.cloneNode(!1),d=!1;if(r.classList.toggle(\"bs-placeholder\",t.multiple?!o:!z(i,n)),t.multiple||1!==n.length||(t.selectpicker.view.displayedValue=z(i,n)),\"static\"===this.options.selectedTextFormat)c=K.text.call(this,{text:this.options.title},!0);else if(!1===(this.multiple&&-1!==this.options.selectedTextFormat.indexOf(\"count\")&&1<o&&(1<(e=this.options.selectedTextFormat.split(\">\")).length&&o>e[1]||1===e.length&&2<=o))){if(!s){for(var h=0;h<o&&h<50;h++){var p=n[h],u=this.selectpicker.main.data[p.liIndex],f={};this.multiple&&0<h&&c.appendChild(a.cloneNode(!1)),p.title?f.text=p.title:u&&(u.content&&t.options.showContent?(f.content=u.content.toString(),d=!0):(t.options.showIcon&&(f.icon=u.icon),t.options.showSubtext&&!t.multiple&&u.subtext&&(f.subtext=\" \"+u.subtext),f.text=p.textContent.trim())),c.appendChild(K.text.call(this,f,!0))}49<o&&c.appendChild(document.createTextNode(\"...\"))}}else{var m=':not([hidden]):not([data-hidden=\"true\"]):not([data-divider=\"true\"])';this.options.hideDisabled&&(m+=\":not(:disabled)\");var v=this.$element[0].querySelectorAll(\"select > option\"+m+\", optgroup\"+m+\" option\"+m).length,g=\"function\"==typeof this.options.countSelectedText?this.options.countSelectedText(o,v):this.options.countSelectedText;c=K.text.call(this,{text:g.replace(\"{0}\",o.toString()).replace(\"{1}\",v.toString())},!0)}if(null==this.options.title&&(this.options.title=this.$element.attr(\"title\")),c.childNodes.length||(c=K.text.call(this,{text:void 0!==this.options.title?this.options.title:this.options.noneSelectedText},!0)),r.title=c.textContent.replace(/<[^>]*>?/g,\"\").trim(),this.options.sanitize&&d&&W([c],t.options.whiteList,t.options.sanitizeFn),l.innerHTML=\"\",l.appendChild(c),M.major<4&&this.$newElement[0].classList.contains(\"bs3-has-addon\")){var b=r.querySelector(\".filter-expand\"),w=l.cloneNode(!0);w.className=\"filter-expand\",b?r.replaceChild(w,b):r.appendChild(w)}this.$element.trigger(\"rendered\"+j)},setStyle:function(e,t){var i,s=this.$button[0],n=this.$newElement[0],o=this.options.style.trim();this.$element.attr(\"class\")&&this.$newElement.addClass(this.$element.attr(\"class\").replace(/selectpicker|mobile-device|bs-select-hidden|validate\\[.*\\]/gi,\"\")),M.major<4&&(n.classList.add(\"bs3\"),n.parentNode.classList&&n.parentNode.classList.contains(\"input-group\")&&(n.previousElementSibling||n.nextElementSibling)&&(n.previousElementSibling||n.nextElementSibling).classList.contains(\"input-group-addon\")&&n.classList.add(\"bs3-has-addon\")),i=e?e.trim():o,\"add\"==t?i&&s.classList.add.apply(s.classList,i.split(\" \")):\"remove\"==t?i&&s.classList.remove.apply(s.classList,i.split(\" \")):(o&&s.classList.remove.apply(s.classList,o.split(\" \")),i&&s.classList.add.apply(s.classList,i.split(\" \")))},liHeight:function(e){if(e||!1!==this.options.size&&!Object.keys(this.sizeInfo).length){var t,i=_.div.cloneNode(!1),s=_.div.cloneNode(!1),n=_.div.cloneNode(!1),o=document.createElement(\"ul\"),r=_.li.cloneNode(!1),l=_.li.cloneNode(!1),a=_.a.cloneNode(!1),c=_.span.cloneNode(!1),d=this.options.header&&0<this.$menu.find(\".\"+V.POPOVERHEADER).length?this.$menu.find(\".\"+V.POPOVERHEADER)[0].cloneNode(!0):null,h=this.options.liveSearch?_.div.cloneNode(!1):null,p=this.options.actionsBox&&this.multiple&&0<this.$menu.find(\".bs-actionsbox\").length?this.$menu.find(\".bs-actionsbox\")[0].cloneNode(!0):null,u=this.options.doneButton&&this.multiple&&0<this.$menu.find(\".bs-donebutton\").length?this.$menu.find(\".bs-donebutton\")[0].cloneNode(!0):null,f=this.$element.find(\"option\")[0];if(this.sizeInfo.selectWidth=this.$newElement[0].offsetWidth,c.className=\"text\",a.className=\"dropdown-item \"+(f?f.className:\"\"),i.className=this.$menu[0].parentNode.className+\" \"+V.SHOW,i.style.width=0,\"auto\"===this.options.width&&(s.style.minWidth=0),s.className=V.MENU+\" \"+V.SHOW,n.className=\"inner \"+V.SHOW,o.className=V.MENU+\" inner \"+(\"4\"===M.major?V.SHOW:\"\"),r.className=V.DIVIDER,l.className=\"dropdown-header\",c.appendChild(document.createTextNode(\"\\u200b\")),this.selectpicker.current.data.length)for(var m=0;m<this.selectpicker.current.data.length;m++){var v=this.selectpicker.current.data[m];if(\"option\"===v.type){t=v.element;break}}else t=_.li.cloneNode(!1),a.appendChild(c),t.appendChild(a);if(l.appendChild(c.cloneNode(!0)),this.selectpicker.view.widestOption&&o.appendChild(this.selectpicker.view.widestOption.cloneNode(!0)),o.appendChild(t),o.appendChild(r),o.appendChild(l),d&&s.appendChild(d),h){var g=document.createElement(\"input\");h.className=\"bs-searchbox\",g.className=\"form-control\",h.appendChild(g),s.appendChild(h)}p&&s.appendChild(p),n.appendChild(o),s.appendChild(n),u&&s.appendChild(u),i.appendChild(s),document.body.appendChild(i);var b,w=t.offsetHeight,I=l?l.offsetHeight:0,x=d?d.offsetHeight:0,k=h?h.offsetHeight:0,y=p?p.offsetHeight:0,$=u?u.offsetHeight:0,S=P(r).outerHeight(!0),E=!!window.getComputedStyle&&window.getComputedStyle(s),C=s.offsetWidth,O=E?null:P(s),z={vert:N(E?E.paddingTop:O.css(\"paddingTop\"))+N(E?E.paddingBottom:O.css(\"paddingBottom\"))+N(E?E.borderTopWidth:O.css(\"borderTopWidth\"))+N(E?E.borderBottomWidth:O.css(\"borderBottomWidth\")),horiz:N(E?E.paddingLeft:O.css(\"paddingLeft\"))+N(E?E.paddingRight:O.css(\"paddingRight\"))+N(E?E.borderLeftWidth:O.css(\"borderLeftWidth\"))+N(E?E.borderRightWidth:O.css(\"borderRightWidth\"))},T={vert:z.vert+N(E?E.marginTop:O.css(\"marginTop\"))+N(E?E.marginBottom:O.css(\"marginBottom\"))+2,horiz:z.horiz+N(E?E.marginLeft:O.css(\"marginLeft\"))+N(E?E.marginRight:O.css(\"marginRight\"))+2};n.style.overflowY=\"scroll\",b=s.offsetWidth-C,document.body.removeChild(i),this.sizeInfo.liHeight=w,this.sizeInfo.dropdownHeaderHeight=I,this.sizeInfo.headerHeight=x,this.sizeInfo.searchHeight=k,this.sizeInfo.actionsHeight=y,this.sizeInfo.doneButtonHeight=$,this.sizeInfo.dividerHeight=S,this.sizeInfo.menuPadding=z,this.sizeInfo.menuExtras=T,this.sizeInfo.menuWidth=C,this.sizeInfo.menuInnerInnerWidth=C-z.horiz,this.sizeInfo.totalMenuWidth=this.sizeInfo.menuWidth,this.sizeInfo.scrollBarWidth=b,this.sizeInfo.selectHeight=this.$newElement[0].offsetHeight,this.setPositionData()}},getSelectPosition:function(){var e,t=P(window),i=this.$newElement.offset(),s=P(this.options.container);this.options.container&&s.length&&!s.is(\"body\")?((e=s.offset()).top+=parseInt(s.css(\"borderTopWidth\")),e.left+=parseInt(s.css(\"borderLeftWidth\"))):e={top:0,left:0};var n=this.options.windowPadding;this.sizeInfo.selectOffsetTop=i.top-e.top-t.scrollTop(),this.sizeInfo.selectOffsetBot=t.height()-this.sizeInfo.selectOffsetTop-this.sizeInfo.selectHeight-e.top-n[2],this.sizeInfo.selectOffsetLeft=i.left-e.left-t.scrollLeft(),this.sizeInfo.selectOffsetRight=t.width()-this.sizeInfo.selectOffsetLeft-this.sizeInfo.selectWidth-e.left-n[1],this.sizeInfo.selectOffsetTop-=n[0],this.sizeInfo.selectOffsetLeft-=n[3]},setMenuSize:function(e){this.getSelectPosition();var t,i,s,n,o,r,l,a,c=this.sizeInfo.selectWidth,d=this.sizeInfo.liHeight,h=this.sizeInfo.headerHeight,p=this.sizeInfo.searchHeight,u=this.sizeInfo.actionsHeight,f=this.sizeInfo.doneButtonHeight,m=this.sizeInfo.dividerHeight,v=this.sizeInfo.menuPadding,g=0;if(this.options.dropupAuto&&(l=d*this.selectpicker.current.elements.length+v.vert,a=this.sizeInfo.selectOffsetTop-this.sizeInfo.selectOffsetBot>this.sizeInfo.menuExtras.vert&&l+this.sizeInfo.menuExtras.vert+50>this.sizeInfo.selectOffsetBot,!0===this.selectpicker.isSearching&&(a=this.selectpicker.dropup),this.$newElement.toggleClass(V.DROPUP,a),this.selectpicker.dropup=a),\"auto\"===this.options.size)n=3<this.selectpicker.current.elements.length?3*this.sizeInfo.liHeight+this.sizeInfo.menuExtras.vert-2:0,i=this.sizeInfo.selectOffsetBot-this.sizeInfo.menuExtras.vert,s=n+h+p+u+f,r=Math.max(n-v.vert,0),this.$newElement.hasClass(V.DROPUP)&&(i=this.sizeInfo.selectOffsetTop-this.sizeInfo.menuExtras.vert),t=(o=i)-h-p-u-f-v.vert;else if(this.options.size&&\"auto\"!=this.options.size&&this.selectpicker.current.elements.length>this.options.size){for(var b=0;b<this.options.size;b++)\"divider\"===this.selectpicker.current.data[b].type&&g++;t=(i=d*this.options.size+g*m+v.vert)-v.vert,o=i+h+p+u+f,s=r=\"\"}this.$menu.css({\"max-height\":o+\"px\",overflow:\"hidden\",\"min-height\":s+\"px\"}),this.$menuInner.css({\"max-height\":t+\"px\",\"overflow-y\":\"auto\",\"min-height\":r+\"px\"}),this.sizeInfo.menuInnerHeight=Math.max(t,1),this.selectpicker.current.data.length&&this.selectpicker.current.data[this.selectpicker.current.data.length-1].position>this.sizeInfo.menuInnerHeight&&(this.sizeInfo.hasScrollBar=!0,this.sizeInfo.totalMenuWidth=this.sizeInfo.menuWidth+this.sizeInfo.scrollBarWidth),\"auto\"===this.options.dropdownAlignRight&&this.$menu.toggleClass(V.MENURIGHT,this.sizeInfo.selectOffsetLeft>this.sizeInfo.selectOffsetRight&&this.sizeInfo.selectOffsetRight<this.sizeInfo.totalMenuWidth-c),this.dropdown&&this.dropdown._popper&&this.dropdown._popper.update()},setSize:function(e){if(this.liHeight(e),this.options.header&&this.$menu.css(\"padding-top\",0),!1!==this.options.size){var t=this,i=P(window);this.setMenuSize(),this.options.liveSearch&&this.$searchbox.off(\"input.setMenuSize propertychange.setMenuSize\").on(\"input.setMenuSize propertychange.setMenuSize\",function(){return t.setMenuSize()}),\"auto\"===this.options.size?i.off(\"resize\"+j+\".\"+this.selectId+\".setMenuSize scroll\"+j+\".\"+this.selectId+\".setMenuSize\").on(\"resize\"+j+\".\"+this.selectId+\".setMenuSize scroll\"+j+\".\"+this.selectId+\".setMenuSize\",function(){return t.setMenuSize()}):this.options.size&&\"auto\"!=this.options.size&&this.selectpicker.current.elements.length>this.options.size&&i.off(\"resize\"+j+\".\"+this.selectId+\".setMenuSize scroll\"+j+\".\"+this.selectId+\".setMenuSize\")}this.createView(!1,!0,e)},setWidth:function(){var i=this;\"auto\"===this.options.width?requestAnimationFrame(function(){i.$menu.css(\"min-width\",\"0\"),i.$element.on(\"loaded\"+j,function(){i.liHeight(),i.setMenuSize();var e=i.$newElement.clone().appendTo(\"body\"),t=e.css(\"width\",\"auto\").children(\"button\").outerWidth();e.remove(),i.sizeInfo.selectWidth=Math.max(i.sizeInfo.totalMenuWidth,t),i.$newElement.css(\"width\",i.sizeInfo.selectWidth+\"px\")})}):\"fit\"===this.options.width?(this.$menu.css(\"min-width\",\"\"),this.$newElement.css(\"width\",\"\").addClass(\"fit-width\")):this.options.width?(this.$menu.css(\"min-width\",\"\"),this.$newElement.css(\"width\",this.options.width)):(this.$menu.css(\"min-width\",\"\"),this.$newElement.css(\"width\",\"\")),this.$newElement.hasClass(\"fit-width\")&&\"fit\"!==this.options.width&&this.$newElement[0].classList.remove(\"fit-width\")},selectPosition:function(){this.$bsContainer=P('<div class=\"bs-container\" />');function e(e){var t={},i=r.options.display||!!P.fn.dropdown.Constructor.Default&&P.fn.dropdown.Constructor.Default.display;r.$bsContainer.addClass(e.attr(\"class\").replace(/form-control|fit-width/gi,\"\")).toggleClass(V.DROPUP,e.hasClass(V.DROPUP)),s=e.offset(),l.is(\"body\")?n={top:0,left:0}:((n=l.offset()).top+=parseInt(l.css(\"borderTopWidth\"))-l.scrollTop(),n.left+=parseInt(l.css(\"borderLeftWidth\"))-l.scrollLeft()),o=e.hasClass(V.DROPUP)?0:e[0].offsetHeight,(M.major<4||\"static\"===i)&&(t.top=s.top-n.top+o,t.left=s.left-n.left),t.width=e[0].offsetWidth,r.$bsContainer.css(t)}var s,n,o,r=this,l=P(this.options.container);this.$button.on(\"click.bs.dropdown.data-api\",function(){r.isDisabled()||(e(r.$newElement),r.$bsContainer.appendTo(r.options.container).toggleClass(V.SHOW,!r.$button.hasClass(V.SHOW)).append(r.$menu))}),P(window).off(\"resize\"+j+\".\"+this.selectId+\" scroll\"+j+\".\"+this.selectId).on(\"resize\"+j+\".\"+this.selectId+\" scroll\"+j+\".\"+this.selectId,function(){r.$newElement.hasClass(V.SHOW)&&e(r.$newElement)}),this.$element.on(\"hide\"+j,function(){r.$menu.data(\"height\",r.$menu.height()),r.$bsContainer.detach()})},setOptionStatus:function(e){var t=this;if(t.noScroll=!1,t.selectpicker.view.visibleElements&&t.selectpicker.view.visibleElements.length)for(var i=0;i<t.selectpicker.view.visibleElements.length;i++){var s=t.selectpicker.current.data[i+t.selectpicker.view.position0],n=s.option;n&&(!0!==e&&t.setDisabled(s.index,s.disabled),t.setSelected(s.index,n.selected))}},setSelected:function(e,t){var i,s,n=this.selectpicker.main.elements[e],o=this.selectpicker.main.data[e],r=void 0!==this.activeIndex,l=this.activeIndex===e||t&&!this.multiple&&!r;o.selected=t,s=n.firstChild,t&&(this.selectedIndex=e),n.classList.toggle(\"selected\",t),l?(this.focusItem(n,o),this.selectpicker.view.currentActive=n,this.activeIndex=e):this.defocusItem(n),s&&(s.classList.toggle(\"selected\",t),t?s.setAttribute(\"aria-selected\",!0):this.multiple?s.setAttribute(\"aria-selected\",!1):s.removeAttribute(\"aria-selected\")),l||r||!t||void 0===this.prevActiveIndex||(i=this.selectpicker.main.elements[this.prevActiveIndex],this.defocusItem(i))},setDisabled:function(e,t){var i,s=this.selectpicker.main.elements[e];this.selectpicker.main.data[e].disabled=t,i=s.firstChild,s.classList.toggle(V.DISABLED,t),i&&(\"4\"===M.major&&i.classList.toggle(V.DISABLED,t),t?(i.setAttribute(\"aria-disabled\",t),i.setAttribute(\"tabindex\",-1)):(i.removeAttribute(\"aria-disabled\"),i.setAttribute(\"tabindex\",0)))},isDisabled:function(){return this.$element[0].disabled},checkDisabled:function(){this.isDisabled()?(this.$newElement[0].classList.add(V.DISABLED),this.$button.addClass(V.DISABLED).attr(\"aria-disabled\",!0)):this.$button[0].classList.contains(V.DISABLED)&&(this.$newElement[0].classList.remove(V.DISABLED),this.$button.removeClass(V.DISABLED).attr(\"aria-disabled\",!1))},clickListener:function(){var C=this,t=P(document);function e(){C.options.liveSearch?C.$searchbox.trigger(\"focus\"):C.$menuInner.trigger(\"focus\")}function i(){C.dropdown&&C.dropdown._popper&&C.dropdown._popper.state.isCreated?e():requestAnimationFrame(i)}t.data(\"spaceSelect\",!1),this.$button.on(\"keyup\",function(e){/(32)/.test(e.keyCode.toString(10))&&t.data(\"spaceSelect\")&&(e.preventDefault(),t.data(\"spaceSelect\",!1))}),this.$newElement.on(\"show.bs.dropdown\",function(){3<M.major&&!C.dropdown&&(C.dropdown=C.$button.data(\"bs.dropdown\"),C.dropdown._menu=C.$menu[0])}),this.$button.on(\"click.bs.dropdown.data-api\",function(){C.$newElement.hasClass(V.SHOW)||C.setSize()}),this.$element.on(\"shown\"+j,function(){C.$menuInner[0].scrollTop!==C.selectpicker.view.scrollTop&&(C.$menuInner[0].scrollTop=C.selectpicker.view.scrollTop),3<M.major?requestAnimationFrame(i):e()}),this.$menuInner.on(\"mouseenter\",\"li a\",function(e){var t=this.parentElement,i=C.isVirtual()?C.selectpicker.view.position0:0,s=Array.prototype.indexOf.call(t.parentElement.children,t),n=C.selectpicker.current.data[s+i];C.focusItem(t,n,!0)}),this.$menuInner.on(\"click\",\"li a\",function(e,t){var i=P(this),s=C.$element[0],n=C.isVirtual()?C.selectpicker.view.position0:0,o=C.selectpicker.current.data[i.parent().index()+n],r=o.index,l=z(s),a=s.selectedIndex,c=s.options[a],d=!0;if(C.multiple&&1!==C.options.maxOptions&&e.stopPropagation(),e.preventDefault(),!C.isDisabled()&&!i.parent().hasClass(V.DISABLED)){var h=o.option,p=P(h),u=h.selected,f=p.parent(\"optgroup\"),m=f.find(\"option\"),v=C.options.maxOptions,g=f.data(\"maxOptions\")||!1;if(r===C.activeIndex&&(t=!0),t||(C.prevActiveIndex=C.activeIndex,C.activeIndex=void 0),C.multiple){if(h.selected=!u,C.setSelected(r,!u),C.focusedParent.focus(),!1!==v||!1!==g){var b=v<O(s).length,w=g<f.find(\"option:selected\").length;if(v&&b||g&&w)if(v&&1==v)s.selectedIndex=-1,h.selected=!0,C.setOptionStatus(!0);else if(g&&1==g){for(var I=0;I<m.length;I++){var x=m[I];x.selected=!1,C.setSelected(x.liIndex,!1)}h.selected=!0,C.setSelected(r,!0)}else{var k=\"string\"==typeof C.options.maxOptionsText?[C.options.maxOptionsText,C.options.maxOptionsText]:C.options.maxOptionsText,y=\"function\"==typeof k?k(v,g):k,$=y[0].replace(\"{n}\",v),S=y[1].replace(\"{n}\",g),E=P('<div class=\"notify\"></div>');y[2]&&($=$.replace(\"{var}\",y[2][1<v?0:1]),S=S.replace(\"{var}\",y[2][1<g?0:1])),h.selected=!1,C.$menu.append(E),v&&b&&(E.append(P(\"<div>\"+$+\"</div>\")),d=!1,C.$element.trigger(\"maxReached\"+j)),g&&w&&(E.append(P(\"<div>\"+S+\"</div>\")),d=!1,C.$element.trigger(\"maxReachedGrp\"+j)),setTimeout(function(){C.setSelected(r,!1)},10),E[0].classList.add(\"fadeOut\"),setTimeout(function(){E.remove()},1050)}}}else c&&(c.selected=!1),h.selected=!0,C.setSelected(r,!0);!C.multiple||C.multiple&&1===C.options.maxOptions?C.$button.trigger(\"focus\"):C.options.liveSearch&&C.$searchbox.trigger(\"focus\"),d&&(!C.multiple&&a===s.selectedIndex||(T=[h.index,p.prop(\"selected\"),l],C.$element.triggerNative(\"change\")))}}),this.$menu.on(\"click\",\"li.\"+V.DISABLED+\" a, .\"+V.POPOVERHEADER+\", .\"+V.POPOVERHEADER+\" :not(.close)\",function(e){e.currentTarget==this&&(e.preventDefault(),e.stopPropagation(),C.options.liveSearch&&!P(e.target).hasClass(\"close\")?C.$searchbox.trigger(\"focus\"):C.$button.trigger(\"focus\"))}),this.$menuInner.on(\"click\",\".divider, .dropdown-header\",function(e){e.preventDefault(),e.stopPropagation(),C.options.liveSearch?C.$searchbox.trigger(\"focus\"):C.$button.trigger(\"focus\")}),this.$menu.on(\"click\",\".\"+V.POPOVERHEADER+\" .close\",function(){C.$button.trigger(\"click\")}),this.$searchbox.on(\"click\",function(e){e.stopPropagation()}),this.$menu.on(\"click\",\".actions-btn\",function(e){C.options.liveSearch?C.$searchbox.trigger(\"focus\"):C.$button.trigger(\"focus\"),e.preventDefault(),e.stopPropagation(),P(this).hasClass(\"bs-select-all\")?C.selectAll():C.deselectAll()}),this.$button.on(\"focus\"+j,function(e){var t=C.$element[0].getAttribute(\"tabindex\");void 0!==t&&e.originalEvent&&e.originalEvent.isTrusted&&(this.setAttribute(\"tabindex\",t),C.$element[0].setAttribute(\"tabindex\",-1),C.selectpicker.view.tabindex=t)}).on(\"blur\"+j,function(e){void 0!==C.selectpicker.view.tabindex&&e.originalEvent&&e.originalEvent.isTrusted&&(C.$element[0].setAttribute(\"tabindex\",C.selectpicker.view.tabindex),this.setAttribute(\"tabindex\",-1),C.selectpicker.view.tabindex=void 0)}),this.$element.on(\"change\"+j,function(){C.render(),C.$element.trigger(\"changed\"+j,T),T=null}).on(\"focus\"+j,function(){C.options.mobile||C.$button[0].focus()})},liveSearchListener:function(){var u=this;this.$button.on(\"click.bs.dropdown.data-api\",function(){u.$searchbox.val()&&(u.$searchbox.val(\"\"),u.selectpicker.search.previousValue=void 0)}),this.$searchbox.on(\"click.bs.dropdown.data-api focus.bs.dropdown.data-api touchend.bs.dropdown.data-api\",function(e){e.stopPropagation()}),this.$searchbox.on(\"input propertychange\",function(){var e=u.$searchbox[0].value;if(u.selectpicker.search.elements=[],u.selectpicker.search.data=[],e){var t=[],i=e.toUpperCase(),s={},n=[],o=u._searchStyle(),r=u.options.liveSearchNormalize;r&&(i=w(i));for(var l=0;l<u.selectpicker.main.data.length;l++){var a=u.selectpicker.main.data[l];s[l]||(s[l]=k(a,i,o,r)),s[l]&&void 0!==a.headerIndex&&-1===n.indexOf(a.headerIndex)&&(0<a.headerIndex&&(s[a.headerIndex-1]=!0,n.push(a.headerIndex-1)),s[a.headerIndex]=!0,n.push(a.headerIndex),s[a.lastIndex+1]=!0),s[l]&&\"optgroup-label\"!==a.type&&n.push(l)}l=0;for(var c=n.length;l<c;l++){var d=n[l],h=n[l-1],p=(a=u.selectpicker.main.data[d],u.selectpicker.main.data[h]);(\"divider\"!==a.type||\"divider\"===a.type&&p&&\"divider\"!==p.type&&c-1!==l)&&(u.selectpicker.search.data.push(a),t.push(u.selectpicker.main.elements[d]))}u.activeIndex=void 0,u.noScroll=!0,u.$menuInner.scrollTop(0),u.selectpicker.search.elements=t,u.createView(!0),function(e,t){e.length||(_.noResults.innerHTML=this.options.noneResultsText.replace(\"{0}\",'\"'+S(t)+'\"'),this.$menuInner[0].firstChild.appendChild(_.noResults))}.call(u,t,e)}else u.selectpicker.search.previousValue&&(u.$menuInner.scrollTop(0),u.createView(!1));u.selectpicker.search.previousValue=e})},_searchStyle:function(){return this.options.liveSearchStyle||\"contains\"},val:function(e){var t=this.$element[0];if(void 0===e)return this.$element.val();var i=z(t);if(T=[null,null,i],this.$element.val(e).trigger(\"changed\"+j,T),this.$newElement.hasClass(V.SHOW))if(this.multiple)this.setOptionStatus(!0);else{var s=(t.options[t.selectedIndex]||{}).liIndex;\"number\"==typeof s&&(this.setSelected(this.selectedIndex,!1),this.setSelected(s,!0))}return this.render(),T=null,this.$element},changeAll:function(e){if(this.multiple){void 0===e&&(e=!0);var t=this.$element[0],i=0,s=0,n=z(t);t.classList.add(\"bs-select-hidden\");for(var o=0,r=this.selectpicker.current.data,l=r.length;o<l;o++){var a=r[o],c=a.option;c&&!a.disabled&&\"divider\"!==a.type&&(a.selected&&i++,!0===(c.selected=e)&&s++)}t.classList.remove(\"bs-select-hidden\"),i!==s&&(this.setOptionStatus(),T=[null,null,n],this.$element.triggerNative(\"change\"))}},selectAll:function(){return this.changeAll(!0)},deselectAll:function(){return this.changeAll(!1)},toggle:function(e){(e=e||window.event)&&e.stopPropagation(),this.$button.trigger(\"click.bs.dropdown.data-api\")},keydown:function(e){var t,i,s,n,o,r=P(this),l=r.hasClass(\"dropdown-toggle\"),a=(l?r.closest(\".dropdown\"):r.closest(F.MENU)).data(\"this\"),c=a.findLis(),d=!1,h=e.which===H&&!l&&!a.options.selectOnTab,p=G.test(e.which)||h,u=a.$menuInner[0].scrollTop,f=!0===a.isVirtual()?a.selectpicker.view.position0:0;if(!(112<=e.which&&e.which<=123))if(!(i=a.$newElement.hasClass(V.SHOW))&&(p||48<=e.which&&e.which<=57||96<=e.which&&e.which<=105||65<=e.which&&e.which<=90)&&(a.$button.trigger(\"click.bs.dropdown.data-api\"),a.options.liveSearch))a.$searchbox.trigger(\"focus\");else{if(e.which===A&&i&&(e.preventDefault(),a.$button.trigger(\"click.bs.dropdown.data-api\").trigger(\"focus\")),p){if(!c.length)return;-1!==(t=(s=a.selectpicker.main.elements[a.activeIndex])?Array.prototype.indexOf.call(s.parentElement.children,s):-1)&&a.defocusItem(s),e.which===B?(-1!==t&&t--,t+f<0&&(t+=c.length),a.selectpicker.view.canHighlight[t+f]||-1===(t=a.selectpicker.view.canHighlight.slice(0,t+f).lastIndexOf(!0)-f)&&(t=c.length-1)):e.which!==R&&!h||(++t+f>=a.selectpicker.view.canHighlight.length&&(t=a.selectpicker.view.firstHighlightIndex),a.selectpicker.view.canHighlight[t+f]||(t=t+1+a.selectpicker.view.canHighlight.slice(t+f+1).indexOf(!0))),e.preventDefault();var m=f+t;e.which===B?0===f&&t===c.length-1?(a.$menuInner[0].scrollTop=a.$menuInner[0].scrollHeight,m=a.selectpicker.current.elements.length-1):d=(o=(n=a.selectpicker.current.data[m]).position-n.height)<u:e.which!==R&&!h||(t===a.selectpicker.view.firstHighlightIndex?(a.$menuInner[0].scrollTop=0,m=a.selectpicker.view.firstHighlightIndex):d=u<(o=(n=a.selectpicker.current.data[m]).position-a.sizeInfo.menuInnerHeight)),s=a.selectpicker.current.elements[m],a.activeIndex=a.selectpicker.current.data[m].index,a.focusItem(s),a.selectpicker.view.currentActive=s,d&&(a.$menuInner[0].scrollTop=o),a.options.liveSearch?a.$searchbox.trigger(\"focus\"):r.trigger(\"focus\")}else if(!r.is(\"input\")&&!q.test(e.which)||e.which===D&&a.selectpicker.keydown.keyHistory){var v,g,b=[];e.preventDefault(),a.selectpicker.keydown.keyHistory+=C[e.which],a.selectpicker.keydown.resetKeyHistory.cancel&&clearTimeout(a.selectpicker.keydown.resetKeyHistory.cancel),a.selectpicker.keydown.resetKeyHistory.cancel=a.selectpicker.keydown.resetKeyHistory.start(),g=a.selectpicker.keydown.keyHistory,/^(.)\\1+$/.test(g)&&(g=g.charAt(0));for(var w=0;w<a.selectpicker.current.data.length;w++){var I=a.selectpicker.current.data[w];k(I,g,\"startsWith\",!0)&&a.selectpicker.view.canHighlight[w]&&b.push(I.index)}if(b.length){var x=0;c.removeClass(\"active\").find(\"a\").removeClass(\"active\"),1===g.length&&(-1===(x=b.indexOf(a.activeIndex))||x===b.length-1?x=0:x++),v=b[x],d=0<u-(n=a.selectpicker.main.data[v]).position?(o=n.position-n.height,!0):(o=n.position-a.sizeInfo.menuInnerHeight,n.position>u+a.sizeInfo.menuInnerHeight),s=a.selectpicker.main.elements[v],a.activeIndex=b[x],a.focusItem(s),s&&s.firstChild.focus(),d&&(a.$menuInner[0].scrollTop=o),r.trigger(\"focus\")}}i&&(e.which===D&&!a.selectpicker.keydown.keyHistory||e.which===L||e.which===H&&a.options.selectOnTab)&&(e.which!==D&&e.preventDefault(),a.options.liveSearch&&e.which===D||(a.$menuInner.find(\".active a\").trigger(\"click\",!0),r.trigger(\"focus\"),a.options.liveSearch||(e.preventDefault(),P(document).data(\"spaceSelect\",!0))))}},mobile:function(){this.options.mobile=!0,this.$element[0].classList.add(\"mobile-device\")},refresh:function(){var e=P.extend({},this.options,this.$element.data());this.options=e,this.checkDisabled(),this.buildData(),this.setStyle(),this.render(),this.buildList(),this.setWidth(),this.setSize(!0),this.$element.trigger(\"refreshed\"+j)},hide:function(){this.$newElement.hide()},show:function(){this.$newElement.show()},remove:function(){this.$newElement.remove(),this.$element.remove()},destroy:function(){this.$newElement.before(this.$element).remove(),this.$bsContainer?this.$bsContainer.remove():this.$menu.remove(),this.selectpicker.view.titleOption&&this.selectpicker.view.titleOption.parentNode&&this.selectpicker.view.titleOption.parentNode.removeChild(this.selectpicker.view.titleOption),this.$element.off(j).removeData(\"selectpicker\").removeClass(\"bs-select-hidden selectpicker\"),P(window).off(j+\".\"+this.selectId)}};var J=P.fn.selectpicker;function Q(){if(P.fn.dropdown)return(P.fn.dropdown.Constructor._dataApiKeydownHandler||P.fn.dropdown.Constructor.prototype.keydown).apply(this,arguments)}P.fn.selectpicker=Z,P.fn.selectpicker.Constructor=Y,P.fn.selectpicker.noConflict=function(){return P.fn.selectpicker=J,this},P(document).off(\"keydown.bs.dropdown.data-api\").on(\"keydown.bs.dropdown.data-api\",':not(.bootstrap-select) > [data-toggle=\"dropdown\"]',Q).on(\"keydown.bs.dropdown.data-api\",\":not(.bootstrap-select) > .dropdown-menu\",Q).on(\"keydown\"+j,'.bootstrap-select [data-toggle=\"dropdown\"], .bootstrap-select [role=\"listbox\"], .bootstrap-select .bs-searchbox input',Y.prototype.keydown).on(\"focusin.modal\",'.bootstrap-select [data-toggle=\"dropdown\"], .bootstrap-select [role=\"listbox\"], .bootstrap-select .bs-searchbox input',function(e){e.stopPropagation()}),P(window).on(\"load\"+j+\".data-api\",function(){P(\".selectpicker\").each(function(){var e=P(this);Z.call(e,e.data())})})}(e)});\n//# sourceMappingURL=bootstrap-select.min.js.map//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvYm9vdHN0cmFwLXNlbGVjdC9kaXN0L2pzL2Jvb3RzdHJhcC1zZWxlY3QubWluLmpzIiwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxlQUFlLHdDQUF3QyxLQUFxQyxDQUFDLGlDQUFPLENBQUMseUVBQVEsQ0FBQyxtQ0FBQyxZQUFZLFlBQVk7QUFBQSxrR0FBQyxDQUFDLENBQXVGLENBQUMsa0JBQWtCLGFBQWEsYUFBYSxnSUFBZ0ksdVVBQXVVLGlMQUFpTCx3QkFBd0IsZ0JBQWdCLCtCQUErQixzR0FBc0csb0NBQW9DLDJCQUEyQixpQkFBaUIsSUFBSSw4QkFBOEIsU0FBUyxrQkFBa0IsdUNBQXVDLHdDQUF3QyxJQUFJLHdEQUF3RCxJQUFJLEtBQUssc0NBQXNDLDJHQUEyRyxJQUFJLEtBQUssV0FBVyxzQ0FBc0Msa0NBQWtDLHVEQUF1RCxrQkFBa0IscUVBQXFFLGNBQWMsT0FBTyxnQkFBZ0IsdUVBQXVFLG9CQUFvQiwwRUFBMEUsc0JBQXNCLDBCQUEwQixzQkFBc0Isd0JBQXdCLHFCQUFxQixPQUFPLHFDQUFxQyxJQUFJLHdCQUF3QixTQUFTLHNGQUFzRixxREFBcUQsU0FBUyxzQ0FBc0MsMkRBQTJELGlFQUFpRSxzQ0FBc0MscURBQXFELDBDQUEwQyxzREFBc0QsMkRBQTJELG9DQUFvQyw0Q0FBNEMsK0RBQStELGNBQWMsa0NBQWtDLG1CQUFtQix1REFBdUQsK0ZBQStGLFlBQVksZ0NBQWdDLGtCQUFrQixhQUFhLE1BQU0sZ0RBQWdELFNBQVMsZ0JBQWdCLCtCQUErQixNQUFNLHVCQUF1QixJQUFJLDJGQUEyRixTQUFTLFNBQVMsZ0JBQWdCLHFEQUFxRCxJQUFJLGlHQUFpRyx1Q0FBdUMsa0RBQWtELElBQUksUUFBUSx1Q0FBdUMsVUFBVSxTQUFTLE9BQU8sNkNBQTZDLG9DQUFvQywyRUFBMkUsc0RBQXNELFNBQVMsMEpBQTBKLGVBQWUsMENBQTBDLEVBQUUsT0FBTywwQ0FBMEMsb0NBQW9DLGdGQUFnRix3QkFBd0IsSUFBSSw4QkFBOEIsU0FBUyxVQUFVLEdBQUcsb0JBQW9CLGtEQUFrRCxXQUFXLEtBQUssa0JBQWtCLHdKQUF3SixTQUFTLGNBQWMseUJBQXlCLCtCQUErQixnQkFBZ0Isa0NBQWtDLFdBQVcsNktBQTZLLE9BQU8sb3pFQUFvekUsK0lBQStJLGNBQWMsWUFBWSxjQUFjLHFEQUFxRCxrQkFBa0IsVUFBVSxXQUFXLFdBQVcsYUFBYSxhQUFhLGFBQWEsRUFBRSw4RUFBOEUsb0RBQW9ELEVBQUUsY0FBYyxZQUFZLE9BQU8sa0ZBQWtGLG9RQUFvUSxpQ0FBaUMsc0JBQXNCLElBQUksdUdBQXVHLFVBQVUsMEJBQTBCLDBQQUEwUCxJQUFJLGdCQUFnQixJQUFJLGlTQUFpUyx3UEFBd1Asd0RBQXdELG1CQUFtQix5QkFBeUIseUpBQXlKLG1CQUFtQix3QkFBd0Isc0xBQXNMLG9CQUFvQiwrQkFBK0IsbUNBQW1DLEtBQUssZ0NBQWdDLGlDQUFpQyxxSUFBcUksZ0ZBQWdGLGVBQWUsc0JBQXNCLHlDQUF5QywrQkFBK0Isa0JBQWtCLG1CQUFtQiwrQkFBK0IsaUNBQWlDLGlDQUFpQyx3SEFBd0gsOEhBQThILG9CQUFvQixXQUFXLDBLQUEwSyxPQUFPLFVBQVUsV0FBVyxRQUFRLHlCQUF5QiwrQkFBK0IsaUJBQWlCLDZCQUE2QixxQ0FBcUMsU0FBUyxpQkFBaUIsNkVBQTZFLGlDQUFpQyx3WUFBd1ksY0FBYyxzQkFBc0IsaUNBQWlDLElBQUksd0VBQXdFLFNBQVMsMllBQTJZLCtCQUErQixrQkFBa0IsU0FBUywwQ0FBMEMscUNBQXFDLDRDQUE0QyxxQ0FBcUMsNENBQTRDLHFDQUFxQyxpSkFBaUosWUFBWSxXQUFXLEtBQUssT0FBTyxtQ0FBbUMsMkJBQTJCLGNBQWMsbUJBQW1CLHFEQUFxRCxNQUFNLG1GQUFtRixLQUFLLGVBQWUsMkZBQTJGLGlCQUFpQiwwQ0FBMEMsTUFBTSxzQkFBc0Isc0ZBQXNGLCtEQUErRCw4RUFBOEUsRUFBRSxzQkFBc0IsZ0NBQWdDLHlFQUF5RSxFQUFFLGtDQUFrQyxjQUFjLEdBQUcsaUJBQWlCLEdBQUcsZ0JBQWdCLDhCQUE4Qiw2QkFBNkIsR0FBRyw0QkFBNEIsR0FBRyx3Q0FBd0MsR0FBRyxrQ0FBa0MsR0FBRyxhQUFhLDZkQUE2ZCxvQ0FBb0MsbUpBQW1KLGNBQWMsOEJBQThCLGtFQUFrRSw0aUNBQTRpQyxrQkFBa0IsbURBQW1ELDhDQUE4QywwSEFBMEgsK0JBQStCLCtCQUErQixrQ0FBa0MsaUNBQWlDLGdDQUFnQywrQkFBK0IsaUNBQWlDLGlDQUFpQyxzRUFBc0UsdUZBQXVGLDJEQUEyRCw2QkFBNkIsOEZBQThGLG1DQUFtQyxvRUFBb0UsRUFBRSx3QkFBd0IsNkNBQTZDLEVBQUUsMkJBQTJCLG1KQUFtSixrRkFBa0YsMEJBQTBCLCtIQUErSCw0dERBQTR0RCw0QkFBNEIsbUhBQW1ILFlBQVksd0NBQXdDLEtBQUssNkNBQTZDLGllQUFpZSxzQkFBc0IsMklBQTJJLDRCQUE0Qix3QkFBd0IsNEtBQTRLLHFCQUFxQixxREFBcUQsVUFBVSw0Q0FBNEMsa0RBQWtELDZEQUE2RCxnQkFBZ0IsdUZBQXVGLHFIQUFxSCxZQUFZLElBQUksS0FBSyxjQUFjLGdEQUFnRCw2RkFBNkYsa2pDQUFrakMsa0RBQWtELGdCQUFnQixFQUFFLDBEQUEwRCxzSUFBc0ksK0JBQStCLElBQUksbUJBQW1CLElBQUksS0FBSyxlQUFlLDRLQUE0SyxxaUJBQXFpQiwrQkFBK0IseUpBQXlKLDBDQUEwQyw0QkFBNEIsK0JBQStCLG9LQUFvSyx5REFBeUQsU0FBUyxVQUFVLDRPQUE0Tyx3QkFBd0IsbUNBQW1DLHNGQUFzRiw4Q0FBOEMscUhBQXFILDZEQUE2RCxFQUFFLDJCQUEyQixNQUFNLG1EQUFtRCxtQkFBbUIsd09BQXdPLHlCQUF5Qix3RkFBd0YsMkJBQTJCLGdCQUFnQix1Q0FBdUMsK0dBQStHLHNRQUFzUSxzWkFBc1oseURBQXlELEVBQUUsU0FBUyxzQkFBc0Isc0ZBQXNGLGtEQUFrRCx3REFBd0QsY0FBYyxvQkFBb0Isb0RBQW9ELDRCQUE0QixnQkFBZ0IsV0FBVywrREFBK0QsY0FBYyxFQUFFLEtBQUssdUZBQXVGLGtZQUFrWSxnQkFBZ0Isd0VBQXdFLGFBQWEsV0FBVyxzSkFBc0osVUFBVSxRQUFRLHNCQUFzQix1QkFBdUIsSUFBSSxLQUFLLFdBQVcsaUNBQWlDLDBGQUEwRixFQUFFLE1BQU0sUUFBUSxHQUFHLHVCQUF1QixJQUFJLEtBQUssV0FBVyw2QkFBNkIsU0FBUyw2REFBNkQsc0JBQXNCLGtEQUFrRCxjQUFjLFVBQVUsZUFBZSxnRUFBZ0UsTUFBTSx5SUFBeUksTUFBTSx5RkFBeUYsaUtBQWlLLDBLQUEwSyx1QkFBdUIsSUFBSSxLQUFLLFFBQVEscUVBQXFFLG9CQUFvQiwyQ0FBMkMsbUJBQW1CLHFSQUFxUixtTUFBbU0sd0JBQXdCLEtBQUssaUxBQWlMLE9BQU8sWUFBWSxVQUFVLEtBQUsseURBQXlELHVVQUF1VSxxREFBcUQsS0FBSyw0RUFBNEUsa0RBQWtELHNOQUFzTixvQkFBb0IsaUJBQWlCLEVBQUUsMEJBQTBCLEVBQUUsZ0JBQWdCLEtBQUssd0hBQXdILGtGQUFrRix5T0FBeU8sMERBQTBELG1FQUFtRSxvQ0FBb0Msd0JBQXdCLDBFQUEwRSxnckJBQWdyQixzQkFBc0Isa0VBQWtFLDJxQkFBMnFCLG9nQkFBb2dCLHdDQUF3QyxLQUFLLHdDQUF3QyxzQkFBc0IsWUFBWSxPQUFPLDREQUE0RCxrTkFBa04sc0NBQXNDLHdGQUF3Rix3SEFBd0gsZ1BBQWdQLG1YQUFtWCxJQUFJLDJMQUEyTCxva0JBQW9rQiw4QkFBOEIsMEVBQTBFLHNKQUFzSixjQUFjLGlDQUFpQyx5WkFBeVoseUJBQXlCLHlCQUF5QixnUUFBZ1EsdXRCQUF1dEIsbUhBQW1ILFlBQVksb0JBQW9CLDREQUE0RCwrREFBK0QsZ0JBQWdCLDBEQUEwRCx1QkFBdUIsNERBQTRELHlrQkFBeWtCLHFCQUFxQixpR0FBaUcsdUJBQXVCLDZLQUE2Syx1QkFBdUIsOE5BQThOLHVCQUF1QiwwTUFBME0seUJBQXlCLHFCQUFxQixXQUFXLDZEQUE2RCxpRUFBaUUsNkJBQTZCLHFHQUFxRywrSEFBK0gsRUFBRSxrWkFBa1osMkJBQTJCLG9EQUFvRCxjQUFjLFFBQVEscUdBQXFHLHdKQUF3SixhQUFhLGlTQUFpUyw2Q0FBNkMsd0RBQXdELGdKQUFnSixxSkFBcUosaURBQWlELHVDQUF1QyxnRUFBZ0UsRUFBRSw2QkFBNkIsV0FBVyw2R0FBNkcsNkNBQTZDLEtBQUssOEVBQThFLGtGQUFrRiwyQkFBMkIsd0pBQXdKLG1kQUFtZCwyQkFBMkIsMkNBQTJDLHFSQUFxUix1QkFBdUIsaUNBQWlDLDBCQUEwQiw4UkFBOFIsMEJBQTBCLHlCQUF5QixhQUFhLGlGQUFpRixhQUFhLGdHQUFnRyw2REFBNkQsMEdBQTBHLG9EQUFvRCwrRkFBK0YsMERBQTBELDRDQUE0Qyx3Q0FBd0MsNEpBQTRKLHFEQUFxRCx1S0FBdUssb0JBQW9CLGtEQUFrRCx5TEFBeUwsbUlBQW1JLCtIQUErSCxtR0FBbUcsNkVBQTZFLHlEQUF5RCxnRkFBZ0YsaUJBQWlCLFlBQVksV0FBVyxLQUFLLFdBQVcsMENBQTBDLGtDQUFrQyxLQUFLLDhLQUE4SyxFQUFFLHNCQUFzQixFQUFFLHVDQUF1QyxxQkFBcUIsSUFBSSwrQkFBK0IsSUFBSSwyT0FBMk8sb0JBQW9CLHlEQUF5RCxXQUFXLFNBQVMsMERBQTBELCtPQUErTyxtSEFBbUgsOEtBQThLLHNFQUFzRSxxSEFBcUgsaUVBQWlFLDJCQUEyQix5Q0FBeUMsb0JBQW9CLG1EQUFtRCxxTEFBcUwsd0NBQXdDLDZDQUE2QyxtS0FBbUssMEJBQTBCLDhOQUE4Tix5Q0FBeUMsb0RBQW9ELDBCQUEwQix1Q0FBdUMsRUFBRSwrQkFBK0IsV0FBVyx3REFBd0Qsc0ZBQXNGLHVIQUF1SCxvQkFBb0IsdURBQXVELDRCQUE0QixzRUFBc0UsK0JBQStCLHlEQUF5RCxZQUFZLFlBQVksa0NBQWtDLEtBQUssa0NBQWtDLGlRQUFpUSxJQUFJLG1CQUFtQixJQUFJLEtBQUssa0ZBQWtGLHVKQUF1Siw2SEFBNkgsd0VBQXdFLEVBQUUsd0VBQXdFLGFBQWEsdUZBQXVGLHNDQUFzQyxFQUFFLHlCQUF5QixnREFBZ0QsaUJBQWlCLHVCQUF1Qix5Q0FBeUMsV0FBVywySUFBMkksS0FBSyxxQ0FBcUMsVUFBVSxxRkFBcUYsMENBQTBDLHVCQUF1QixrQkFBa0IsbUJBQW1CLHNDQUFzQyxvQ0FBb0Msd0RBQXdELElBQUksS0FBSyxzQkFBc0IsK0VBQStFLDhIQUE4SCxzQkFBc0IsMEJBQTBCLHdCQUF3QiwwQkFBMEIsb0JBQW9CLDRGQUE0RixxQkFBcUIsdVJBQXVSLGtRQUFrUSxLQUFLLDRHQUE0RyxvQkFBb0IsaWlCQUFpaUIsVUFBVSwyb0JBQTJvQiwwRkFBMEYsYUFBYSxpVkFBaVYsWUFBWSxxQ0FBcUMsS0FBSyxxQ0FBcUMsNkVBQTZFLGFBQWEsUUFBUSxzYkFBc2IsbVVBQW1VLG1CQUFtQix1RUFBdUUsb0JBQW9CLGlCQUFpQixvQ0FBb0MsMEtBQTBLLGlCQUFpQix3QkFBd0IsaUJBQWlCLHdCQUF3QixtQkFBbUIsaURBQWlELG9CQUFvQixvYUFBb2Esd0JBQXdCLGFBQWEsNklBQTZJLDRGQUE0RixnQ0FBZ0MsOGdCQUE4Z0Isb0JBQW9CLCtDQUErQyxtQ0FBbUMsY0FBYyxtQkFBbUIsRUFBRSxFQUFFLElBQUk7QUFDeG1vRCIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9ib290c3RyYXAtc2VsZWN0L2Rpc3QvanMvYm9vdHN0cmFwLXNlbGVjdC5taW4uanM/MGEwOCJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiFcbiAqIEJvb3RzdHJhcC1zZWxlY3QgdjEuMTMuMTggKGh0dHBzOi8vZGV2ZWxvcGVyLnNuYXBhcHBvaW50bWVudHMuY29tL2Jvb3RzdHJhcC1zZWxlY3QpXG4gKlxuICogQ29weXJpZ2h0IDIwMTItMjAyMCBTbmFwQXBwb2ludG1lbnRzLCBMTENcbiAqIExpY2Vuc2VkIHVuZGVyIE1JVCAoaHR0cHM6Ly9naXRodWIuY29tL3NuYXBhcHBvaW50bWVudHMvYm9vdHN0cmFwLXNlbGVjdC9ibG9iL21hc3Rlci9MSUNFTlNFKVxuICovXG5cbiFmdW5jdGlvbihlLHQpe3ZvaWQgMD09PWUmJnZvaWQgMCE9PXdpbmRvdyYmKGU9d2luZG93KSxcImZ1bmN0aW9uXCI9PXR5cGVvZiBkZWZpbmUmJmRlZmluZS5hbWQ/ZGVmaW5lKFtcImpxdWVyeVwiXSxmdW5jdGlvbihlKXtyZXR1cm4gdChlKX0pOlwib2JqZWN0XCI9PXR5cGVvZiBtb2R1bGUmJm1vZHVsZS5leHBvcnRzP21vZHVsZS5leHBvcnRzPXQocmVxdWlyZShcImpxdWVyeVwiKSk6dChlLmpRdWVyeSl9KHRoaXMsZnVuY3Rpb24oZSl7IWZ1bmN0aW9uKFApe1widXNlIHN0cmljdFwiO3ZhciBkPVtcInNhbml0aXplXCIsXCJ3aGl0ZUxpc3RcIixcInNhbml0aXplRm5cIl0scj1bXCJiYWNrZ3JvdW5kXCIsXCJjaXRlXCIsXCJocmVmXCIsXCJpdGVtdHlwZVwiLFwibG9uZ2Rlc2NcIixcInBvc3RlclwiLFwic3JjXCIsXCJ4bGluazpocmVmXCJdLGU9e1wiKlwiOltcImNsYXNzXCIsXCJkaXJcIixcImlkXCIsXCJsYW5nXCIsXCJyb2xlXCIsXCJ0YWJpbmRleFwiLFwic3R5bGVcIiwvXmFyaWEtW1xcdy1dKiQvaV0sYTpbXCJ0YXJnZXRcIixcImhyZWZcIixcInRpdGxlXCIsXCJyZWxcIl0sYXJlYTpbXSxiOltdLGJyOltdLGNvbDpbXSxjb2RlOltdLGRpdjpbXSxlbTpbXSxocjpbXSxoMTpbXSxoMjpbXSxoMzpbXSxoNDpbXSxoNTpbXSxoNjpbXSxpOltdLGltZzpbXCJzcmNcIixcImFsdFwiLFwidGl0bGVcIixcIndpZHRoXCIsXCJoZWlnaHRcIl0sbGk6W10sb2w6W10scDpbXSxwcmU6W10sczpbXSxzbWFsbDpbXSxzcGFuOltdLHN1YjpbXSxzdXA6W10sc3Ryb25nOltdLHU6W10sdWw6W119LGw9L14oPzooPzpodHRwcz98bWFpbHRvfGZ0cHx0ZWx8ZmlsZSk6fFteJjovPyNdKig/OlsvPyNdfCQpKS9naSxhPS9eZGF0YTooPzppbWFnZVxcLyg/OmJtcHxnaWZ8anBlZ3xqcGd8cG5nfHRpZmZ8d2VicCl8dmlkZW9cXC8oPzptcGVnfG1wNHxvZ2d8d2VibSl8YXVkaW9cXC8oPzptcDN8b2dhfG9nZ3xvcHVzKSk7YmFzZTY0LFthLXowLTkrL10rPSokL2k7ZnVuY3Rpb24gdihlLHQpe3ZhciBpPWUubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtpZigtMSE9PVAuaW5BcnJheShpLHQpKXJldHVybi0xPT09UC5pbkFycmF5KGkscil8fEJvb2xlYW4oZS5ub2RlVmFsdWUubWF0Y2gobCl8fGUubm9kZVZhbHVlLm1hdGNoKGEpKTtmb3IodmFyIHM9UCh0KS5maWx0ZXIoZnVuY3Rpb24oZSx0KXtyZXR1cm4gdCBpbnN0YW5jZW9mIFJlZ0V4cH0pLG49MCxvPXMubGVuZ3RoO248bztuKyspaWYoaS5tYXRjaChzW25dKSlyZXR1cm4hMDtyZXR1cm4hMX1mdW5jdGlvbiBXKGUsdCxpKXtpZihpJiZcImZ1bmN0aW9uXCI9PXR5cGVvZiBpKXJldHVybiBpKGUpO2Zvcih2YXIgcz1PYmplY3Qua2V5cyh0KSxuPTAsbz1lLmxlbmd0aDtuPG87bisrKWZvcih2YXIgcj1lW25dLnF1ZXJ5U2VsZWN0b3JBbGwoXCIqXCIpLGw9MCxhPXIubGVuZ3RoO2w8YTtsKyspe3ZhciBjPXJbbF0sZD1jLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7aWYoLTEhPT1zLmluZGV4T2YoZCkpZm9yKHZhciBoPVtdLnNsaWNlLmNhbGwoYy5hdHRyaWJ1dGVzKSxwPVtdLmNvbmNhdCh0W1wiKlwiXXx8W10sdFtkXXx8W10pLHU9MCxmPWgubGVuZ3RoO3U8Zjt1Kyspe3ZhciBtPWhbdV07dihtLHApfHxjLnJlbW92ZUF0dHJpYnV0ZShtLm5vZGVOYW1lKX1lbHNlIGMucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChjKX19XCJjbGFzc0xpc3RcImluIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJfXCIpfHxmdW5jdGlvbihlKXtpZihcIkVsZW1lbnRcImluIGUpe3ZhciB0PVwiY2xhc3NMaXN0XCIsaT1cInByb3RvdHlwZVwiLHM9ZS5FbGVtZW50W2ldLG49T2JqZWN0LG89ZnVuY3Rpb24oKXt2YXIgaT1QKHRoaXMpO3JldHVybnthZGQ6ZnVuY3Rpb24oZSl7cmV0dXJuIGU9QXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKS5qb2luKFwiIFwiKSxpLmFkZENsYXNzKGUpfSxyZW1vdmU6ZnVuY3Rpb24oZSl7cmV0dXJuIGU9QXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKS5qb2luKFwiIFwiKSxpLnJlbW92ZUNsYXNzKGUpfSx0b2dnbGU6ZnVuY3Rpb24oZSx0KXtyZXR1cm4gaS50b2dnbGVDbGFzcyhlLHQpfSxjb250YWluczpmdW5jdGlvbihlKXtyZXR1cm4gaS5oYXNDbGFzcyhlKX19fTtpZihuLmRlZmluZVByb3BlcnR5KXt2YXIgcj17Z2V0Om8sZW51bWVyYWJsZTohMCxjb25maWd1cmFibGU6ITB9O3RyeXtuLmRlZmluZVByb3BlcnR5KHMsdCxyKX1jYXRjaChlKXt2b2lkIDAhPT1lLm51bWJlciYmLTIxNDY4MjMyNTIhPT1lLm51bWJlcnx8KHIuZW51bWVyYWJsZT0hMSxuLmRlZmluZVByb3BlcnR5KHMsdCxyKSl9fWVsc2UgbltpXS5fX2RlZmluZUdldHRlcl9fJiZzLl9fZGVmaW5lR2V0dGVyX18odCxvKX19KHdpbmRvdyk7dmFyIHQsYyxpPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJfXCIpO2lmKGkuY2xhc3NMaXN0LmFkZChcImMxXCIsXCJjMlwiKSwhaS5jbGFzc0xpc3QuY29udGFpbnMoXCJjMlwiKSl7dmFyIHM9RE9NVG9rZW5MaXN0LnByb3RvdHlwZS5hZGQsbj1ET01Ub2tlbkxpc3QucHJvdG90eXBlLnJlbW92ZTtET01Ub2tlbkxpc3QucHJvdG90eXBlLmFkZD1mdW5jdGlvbigpe0FycmF5LnByb3RvdHlwZS5mb3JFYWNoLmNhbGwoYXJndW1lbnRzLHMuYmluZCh0aGlzKSl9LERPTVRva2VuTGlzdC5wcm90b3R5cGUucmVtb3ZlPWZ1bmN0aW9uKCl7QXJyYXkucHJvdG90eXBlLmZvckVhY2guY2FsbChhcmd1bWVudHMsbi5iaW5kKHRoaXMpKX19aWYoaS5jbGFzc0xpc3QudG9nZ2xlKFwiYzNcIiwhMSksaS5jbGFzc0xpc3QuY29udGFpbnMoXCJjM1wiKSl7dmFyIG89RE9NVG9rZW5MaXN0LnByb3RvdHlwZS50b2dnbGU7RE9NVG9rZW5MaXN0LnByb3RvdHlwZS50b2dnbGU9ZnVuY3Rpb24oZSx0KXtyZXR1cm4gMSBpbiBhcmd1bWVudHMmJiF0aGlzLmNvbnRhaW5zKGUpPT0hdD90Om8uY2FsbCh0aGlzLGUpfX1mdW5jdGlvbiBoKGUpe2lmKG51bGw9PXRoaXMpdGhyb3cgbmV3IFR5cGVFcnJvcjt2YXIgdD1TdHJpbmcodGhpcyk7aWYoZSYmXCJbb2JqZWN0IFJlZ0V4cF1cIj09Yy5jYWxsKGUpKXRocm93IG5ldyBUeXBlRXJyb3I7dmFyIGk9dC5sZW5ndGgscz1TdHJpbmcoZSksbj1zLmxlbmd0aCxvPTE8YXJndW1lbnRzLmxlbmd0aD9hcmd1bWVudHNbMV06dm9pZCAwLHI9bz9OdW1iZXIobyk6MDtyIT1yJiYocj0wKTt2YXIgbD1NYXRoLm1pbihNYXRoLm1heChyLDApLGkpO2lmKGk8bitsKXJldHVybiExO2Zvcih2YXIgYT0tMTsrK2E8bjspaWYodC5jaGFyQ29kZUF0KGwrYSkhPXMuY2hhckNvZGVBdChhKSlyZXR1cm4hMTtyZXR1cm4hMH1mdW5jdGlvbiBPKGUsdCl7dmFyIGkscz1lLnNlbGVjdGVkT3B0aW9ucyxuPVtdO2lmKHQpe2Zvcih2YXIgbz0wLHI9cy5sZW5ndGg7bzxyO28rKykoaT1zW29dKS5kaXNhYmxlZHx8XCJPUFRHUk9VUFwiPT09aS5wYXJlbnROb2RlLnRhZ05hbWUmJmkucGFyZW50Tm9kZS5kaXNhYmxlZHx8bi5wdXNoKGkpO3JldHVybiBufXJldHVybiBzfWZ1bmN0aW9uIHooZSx0KXtmb3IodmFyIGkscz1bXSxuPXR8fGUuc2VsZWN0ZWRPcHRpb25zLG89MCxyPW4ubGVuZ3RoO288cjtvKyspKGk9bltvXSkuZGlzYWJsZWR8fFwiT1BUR1JPVVBcIj09PWkucGFyZW50Tm9kZS50YWdOYW1lJiZpLnBhcmVudE5vZGUuZGlzYWJsZWR8fHMucHVzaChpLnZhbHVlKTtyZXR1cm4gZS5tdWx0aXBsZT9zOnMubGVuZ3RoP3NbMF06bnVsbH1pPW51bGwsU3RyaW5nLnByb3RvdHlwZS5zdGFydHNXaXRofHwodD1mdW5jdGlvbigpe3RyeXt2YXIgZT17fSx0PU9iamVjdC5kZWZpbmVQcm9wZXJ0eSxpPXQoZSxlLGUpJiZ0fWNhdGNoKGUpe31yZXR1cm4gaX0oKSxjPXt9LnRvU3RyaW5nLHQ/dChTdHJpbmcucHJvdG90eXBlLFwic3RhcnRzV2l0aFwiLHt2YWx1ZTpoLGNvbmZpZ3VyYWJsZTohMCx3cml0YWJsZTohMH0pOlN0cmluZy5wcm90b3R5cGUuc3RhcnRzV2l0aD1oKSxPYmplY3Qua2V5c3x8KE9iamVjdC5rZXlzPWZ1bmN0aW9uKGUsdCxpKXtmb3IodCBpbiBpPVtdLGUpaS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGUsdCkmJmkucHVzaCh0KTtyZXR1cm4gaX0pLEhUTUxTZWxlY3RFbGVtZW50JiYhSFRNTFNlbGVjdEVsZW1lbnQucHJvdG90eXBlLmhhc093blByb3BlcnR5KFwic2VsZWN0ZWRPcHRpb25zXCIpJiZPYmplY3QuZGVmaW5lUHJvcGVydHkoSFRNTFNlbGVjdEVsZW1lbnQucHJvdG90eXBlLFwic2VsZWN0ZWRPcHRpb25zXCIse2dldDpmdW5jdGlvbigpe3JldHVybiB0aGlzLnF1ZXJ5U2VsZWN0b3JBbGwoXCI6Y2hlY2tlZFwiKX19KTt2YXIgcD17dXNlRGVmYXVsdDohMSxfc2V0OlAudmFsSG9va3Muc2VsZWN0LnNldH07UC52YWxIb29rcy5zZWxlY3Quc2V0PWZ1bmN0aW9uKGUsdCl7cmV0dXJuIHQmJiFwLnVzZURlZmF1bHQmJlAoZSkuZGF0YShcInNlbGVjdGVkXCIsITApLHAuX3NldC5hcHBseSh0aGlzLGFyZ3VtZW50cyl9O3ZhciBUPW51bGwsdT1mdW5jdGlvbigpe3RyeXtyZXR1cm4gbmV3IEV2ZW50KFwiY2hhbmdlXCIpLCEwfWNhdGNoKGUpe3JldHVybiExfX0oKTtmdW5jdGlvbiBrKGUsdCxpLHMpe2Zvcih2YXIgbj1bXCJkaXNwbGF5XCIsXCJzdWJ0ZXh0XCIsXCJ0b2tlbnNcIl0sbz0hMSxyPTA7cjxuLmxlbmd0aDtyKyspe3ZhciBsPW5bcl0sYT1lW2xdO2lmKGEmJihhPWEudG9TdHJpbmcoKSxcImRpc3BsYXlcIj09PWwmJihhPWEucmVwbGFjZSgvPFtePl0rPi9nLFwiXCIpKSxzJiYoYT13KGEpKSxhPWEudG9VcHBlckNhc2UoKSxvPVwiY29udGFpbnNcIj09PWk/MDw9YS5pbmRleE9mKHQpOmEuc3RhcnRzV2l0aCh0KSkpYnJlYWt9cmV0dXJuIG99ZnVuY3Rpb24gTihlKXtyZXR1cm4gcGFyc2VJbnQoZSwxMCl8fDB9UC5mbi50cmlnZ2VyTmF0aXZlPWZ1bmN0aW9uKGUpe3ZhciB0LGk9dGhpc1swXTtpLmRpc3BhdGNoRXZlbnQ/KHU/dD1uZXcgRXZlbnQoZSx7YnViYmxlczohMH0pOih0PWRvY3VtZW50LmNyZWF0ZUV2ZW50KFwiRXZlbnRcIikpLmluaXRFdmVudChlLCEwLCExKSxpLmRpc3BhdGNoRXZlbnQodCkpOmkuZmlyZUV2ZW50PygodD1kb2N1bWVudC5jcmVhdGVFdmVudE9iamVjdCgpKS5ldmVudFR5cGU9ZSxpLmZpcmVFdmVudChcIm9uXCIrZSx0KSk6dGhpcy50cmlnZ2VyKGUpfTt2YXIgZj17XCJcXHhjMFwiOlwiQVwiLFwiXFx4YzFcIjpcIkFcIixcIlxceGMyXCI6XCJBXCIsXCJcXHhjM1wiOlwiQVwiLFwiXFx4YzRcIjpcIkFcIixcIlxceGM1XCI6XCJBXCIsXCJcXHhlMFwiOlwiYVwiLFwiXFx4ZTFcIjpcImFcIixcIlxceGUyXCI6XCJhXCIsXCJcXHhlM1wiOlwiYVwiLFwiXFx4ZTRcIjpcImFcIixcIlxceGU1XCI6XCJhXCIsXCJcXHhjN1wiOlwiQ1wiLFwiXFx4ZTdcIjpcImNcIixcIlxceGQwXCI6XCJEXCIsXCJcXHhmMFwiOlwiZFwiLFwiXFx4YzhcIjpcIkVcIixcIlxceGM5XCI6XCJFXCIsXCJcXHhjYVwiOlwiRVwiLFwiXFx4Y2JcIjpcIkVcIixcIlxceGU4XCI6XCJlXCIsXCJcXHhlOVwiOlwiZVwiLFwiXFx4ZWFcIjpcImVcIixcIlxceGViXCI6XCJlXCIsXCJcXHhjY1wiOlwiSVwiLFwiXFx4Y2RcIjpcIklcIixcIlxceGNlXCI6XCJJXCIsXCJcXHhjZlwiOlwiSVwiLFwiXFx4ZWNcIjpcImlcIixcIlxceGVkXCI6XCJpXCIsXCJcXHhlZVwiOlwiaVwiLFwiXFx4ZWZcIjpcImlcIixcIlxceGQxXCI6XCJOXCIsXCJcXHhmMVwiOlwiblwiLFwiXFx4ZDJcIjpcIk9cIixcIlxceGQzXCI6XCJPXCIsXCJcXHhkNFwiOlwiT1wiLFwiXFx4ZDVcIjpcIk9cIixcIlxceGQ2XCI6XCJPXCIsXCJcXHhkOFwiOlwiT1wiLFwiXFx4ZjJcIjpcIm9cIixcIlxceGYzXCI6XCJvXCIsXCJcXHhmNFwiOlwib1wiLFwiXFx4ZjVcIjpcIm9cIixcIlxceGY2XCI6XCJvXCIsXCJcXHhmOFwiOlwib1wiLFwiXFx4ZDlcIjpcIlVcIixcIlxceGRhXCI6XCJVXCIsXCJcXHhkYlwiOlwiVVwiLFwiXFx4ZGNcIjpcIlVcIixcIlxceGY5XCI6XCJ1XCIsXCJcXHhmYVwiOlwidVwiLFwiXFx4ZmJcIjpcInVcIixcIlxceGZjXCI6XCJ1XCIsXCJcXHhkZFwiOlwiWVwiLFwiXFx4ZmRcIjpcInlcIixcIlxceGZmXCI6XCJ5XCIsXCJcXHhjNlwiOlwiQWVcIixcIlxceGU2XCI6XCJhZVwiLFwiXFx4ZGVcIjpcIlRoXCIsXCJcXHhmZVwiOlwidGhcIixcIlxceGRmXCI6XCJzc1wiLFwiXFx1MDEwMFwiOlwiQVwiLFwiXFx1MDEwMlwiOlwiQVwiLFwiXFx1MDEwNFwiOlwiQVwiLFwiXFx1MDEwMVwiOlwiYVwiLFwiXFx1MDEwM1wiOlwiYVwiLFwiXFx1MDEwNVwiOlwiYVwiLFwiXFx1MDEwNlwiOlwiQ1wiLFwiXFx1MDEwOFwiOlwiQ1wiLFwiXFx1MDEwYVwiOlwiQ1wiLFwiXFx1MDEwY1wiOlwiQ1wiLFwiXFx1MDEwN1wiOlwiY1wiLFwiXFx1MDEwOVwiOlwiY1wiLFwiXFx1MDEwYlwiOlwiY1wiLFwiXFx1MDEwZFwiOlwiY1wiLFwiXFx1MDEwZVwiOlwiRFwiLFwiXFx1MDExMFwiOlwiRFwiLFwiXFx1MDEwZlwiOlwiZFwiLFwiXFx1MDExMVwiOlwiZFwiLFwiXFx1MDExMlwiOlwiRVwiLFwiXFx1MDExNFwiOlwiRVwiLFwiXFx1MDExNlwiOlwiRVwiLFwiXFx1MDExOFwiOlwiRVwiLFwiXFx1MDExYVwiOlwiRVwiLFwiXFx1MDExM1wiOlwiZVwiLFwiXFx1MDExNVwiOlwiZVwiLFwiXFx1MDExN1wiOlwiZVwiLFwiXFx1MDExOVwiOlwiZVwiLFwiXFx1MDExYlwiOlwiZVwiLFwiXFx1MDExY1wiOlwiR1wiLFwiXFx1MDExZVwiOlwiR1wiLFwiXFx1MDEyMFwiOlwiR1wiLFwiXFx1MDEyMlwiOlwiR1wiLFwiXFx1MDExZFwiOlwiZ1wiLFwiXFx1MDExZlwiOlwiZ1wiLFwiXFx1MDEyMVwiOlwiZ1wiLFwiXFx1MDEyM1wiOlwiZ1wiLFwiXFx1MDEyNFwiOlwiSFwiLFwiXFx1MDEyNlwiOlwiSFwiLFwiXFx1MDEyNVwiOlwiaFwiLFwiXFx1MDEyN1wiOlwiaFwiLFwiXFx1MDEyOFwiOlwiSVwiLFwiXFx1MDEyYVwiOlwiSVwiLFwiXFx1MDEyY1wiOlwiSVwiLFwiXFx1MDEyZVwiOlwiSVwiLFwiXFx1MDEzMFwiOlwiSVwiLFwiXFx1MDEyOVwiOlwiaVwiLFwiXFx1MDEyYlwiOlwiaVwiLFwiXFx1MDEyZFwiOlwiaVwiLFwiXFx1MDEyZlwiOlwiaVwiLFwiXFx1MDEzMVwiOlwiaVwiLFwiXFx1MDEzNFwiOlwiSlwiLFwiXFx1MDEzNVwiOlwialwiLFwiXFx1MDEzNlwiOlwiS1wiLFwiXFx1MDEzN1wiOlwia1wiLFwiXFx1MDEzOFwiOlwia1wiLFwiXFx1MDEzOVwiOlwiTFwiLFwiXFx1MDEzYlwiOlwiTFwiLFwiXFx1MDEzZFwiOlwiTFwiLFwiXFx1MDEzZlwiOlwiTFwiLFwiXFx1MDE0MVwiOlwiTFwiLFwiXFx1MDEzYVwiOlwibFwiLFwiXFx1MDEzY1wiOlwibFwiLFwiXFx1MDEzZVwiOlwibFwiLFwiXFx1MDE0MFwiOlwibFwiLFwiXFx1MDE0MlwiOlwibFwiLFwiXFx1MDE0M1wiOlwiTlwiLFwiXFx1MDE0NVwiOlwiTlwiLFwiXFx1MDE0N1wiOlwiTlwiLFwiXFx1MDE0YVwiOlwiTlwiLFwiXFx1MDE0NFwiOlwiblwiLFwiXFx1MDE0NlwiOlwiblwiLFwiXFx1MDE0OFwiOlwiblwiLFwiXFx1MDE0YlwiOlwiblwiLFwiXFx1MDE0Y1wiOlwiT1wiLFwiXFx1MDE0ZVwiOlwiT1wiLFwiXFx1MDE1MFwiOlwiT1wiLFwiXFx1MDE0ZFwiOlwib1wiLFwiXFx1MDE0ZlwiOlwib1wiLFwiXFx1MDE1MVwiOlwib1wiLFwiXFx1MDE1NFwiOlwiUlwiLFwiXFx1MDE1NlwiOlwiUlwiLFwiXFx1MDE1OFwiOlwiUlwiLFwiXFx1MDE1NVwiOlwiclwiLFwiXFx1MDE1N1wiOlwiclwiLFwiXFx1MDE1OVwiOlwiclwiLFwiXFx1MDE1YVwiOlwiU1wiLFwiXFx1MDE1Y1wiOlwiU1wiLFwiXFx1MDE1ZVwiOlwiU1wiLFwiXFx1MDE2MFwiOlwiU1wiLFwiXFx1MDE1YlwiOlwic1wiLFwiXFx1MDE1ZFwiOlwic1wiLFwiXFx1MDE1ZlwiOlwic1wiLFwiXFx1MDE2MVwiOlwic1wiLFwiXFx1MDE2MlwiOlwiVFwiLFwiXFx1MDE2NFwiOlwiVFwiLFwiXFx1MDE2NlwiOlwiVFwiLFwiXFx1MDE2M1wiOlwidFwiLFwiXFx1MDE2NVwiOlwidFwiLFwiXFx1MDE2N1wiOlwidFwiLFwiXFx1MDE2OFwiOlwiVVwiLFwiXFx1MDE2YVwiOlwiVVwiLFwiXFx1MDE2Y1wiOlwiVVwiLFwiXFx1MDE2ZVwiOlwiVVwiLFwiXFx1MDE3MFwiOlwiVVwiLFwiXFx1MDE3MlwiOlwiVVwiLFwiXFx1MDE2OVwiOlwidVwiLFwiXFx1MDE2YlwiOlwidVwiLFwiXFx1MDE2ZFwiOlwidVwiLFwiXFx1MDE2ZlwiOlwidVwiLFwiXFx1MDE3MVwiOlwidVwiLFwiXFx1MDE3M1wiOlwidVwiLFwiXFx1MDE3NFwiOlwiV1wiLFwiXFx1MDE3NVwiOlwid1wiLFwiXFx1MDE3NlwiOlwiWVwiLFwiXFx1MDE3N1wiOlwieVwiLFwiXFx1MDE3OFwiOlwiWVwiLFwiXFx1MDE3OVwiOlwiWlwiLFwiXFx1MDE3YlwiOlwiWlwiLFwiXFx1MDE3ZFwiOlwiWlwiLFwiXFx1MDE3YVwiOlwielwiLFwiXFx1MDE3Y1wiOlwielwiLFwiXFx1MDE3ZVwiOlwielwiLFwiXFx1MDEzMlwiOlwiSUpcIixcIlxcdTAxMzNcIjpcImlqXCIsXCJcXHUwMTUyXCI6XCJPZVwiLFwiXFx1MDE1M1wiOlwib2VcIixcIlxcdTAxNDlcIjpcIiduXCIsXCJcXHUwMTdmXCI6XCJzXCJ9LG09L1tcXHhjMC1cXHhkNlxceGQ4LVxceGY2XFx4ZjgtXFx4ZmZcXHUwMTAwLVxcdTAxN2ZdL2csZz1SZWdFeHAoXCJbXFxcXHUwMzAwLVxcXFx1MDM2ZlxcXFx1ZmUyMC1cXFxcdWZlMmZcXFxcdTIwZDAtXFxcXHUyMGZmXFxcXHUxYWIwLVxcXFx1MWFmZlxcXFx1MWRjMC1cXFxcdTFkZmZdXCIsXCJnXCIpO2Z1bmN0aW9uIGIoZSl7cmV0dXJuIGZbZV19ZnVuY3Rpb24gdyhlKXtyZXR1cm4oZT1lLnRvU3RyaW5nKCkpJiZlLnJlcGxhY2UobSxiKS5yZXBsYWNlKGcsXCJcIil9dmFyIEkseCx5LCQsUz0oST17XCImXCI6XCImYW1wO1wiLFwiPFwiOlwiJmx0O1wiLFwiPlwiOlwiJmd0O1wiLCdcIic6XCImcXVvdDtcIixcIidcIjpcIiYjeDI3O1wiLFwiYFwiOlwiJiN4NjA7XCJ9LHg9XCIoPzpcIitPYmplY3Qua2V5cyhJKS5qb2luKFwifFwiKStcIilcIix5PVJlZ0V4cCh4KSwkPVJlZ0V4cCh4LFwiZ1wiKSxmdW5jdGlvbihlKXtyZXR1cm4gZT1udWxsPT1lP1wiXCI6XCJcIitlLHkudGVzdChlKT9lLnJlcGxhY2UoJCxFKTplfSk7ZnVuY3Rpb24gRShlKXtyZXR1cm4gSVtlXX12YXIgQz17MzI6XCIgXCIsNDg6XCIwXCIsNDk6XCIxXCIsNTA6XCIyXCIsNTE6XCIzXCIsNTI6XCI0XCIsNTM6XCI1XCIsNTQ6XCI2XCIsNTU6XCI3XCIsNTY6XCI4XCIsNTc6XCI5XCIsNTk6XCI7XCIsNjU6XCJBXCIsNjY6XCJCXCIsNjc6XCJDXCIsNjg6XCJEXCIsNjk6XCJFXCIsNzA6XCJGXCIsNzE6XCJHXCIsNzI6XCJIXCIsNzM6XCJJXCIsNzQ6XCJKXCIsNzU6XCJLXCIsNzY6XCJMXCIsNzc6XCJNXCIsNzg6XCJOXCIsNzk6XCJPXCIsODA6XCJQXCIsODE6XCJRXCIsODI6XCJSXCIsODM6XCJTXCIsODQ6XCJUXCIsODU6XCJVXCIsODY6XCJWXCIsODc6XCJXXCIsODg6XCJYXCIsODk6XCJZXCIsOTA6XCJaXCIsOTY6XCIwXCIsOTc6XCIxXCIsOTg6XCIyXCIsOTk6XCIzXCIsMTAwOlwiNFwiLDEwMTpcIjVcIiwxMDI6XCI2XCIsMTAzOlwiN1wiLDEwNDpcIjhcIiwxMDU6XCI5XCJ9LEE9MjcsTD0xMyxEPTMyLEg9OSxCPTM4LFI9NDAsTT17c3VjY2VzczohMSxtYWpvcjpcIjNcIn07dHJ5e00uZnVsbD0oUC5mbi5kcm9wZG93bi5Db25zdHJ1Y3Rvci5WRVJTSU9OfHxcIlwiKS5zcGxpdChcIiBcIilbMF0uc3BsaXQoXCIuXCIpLE0ubWFqb3I9TS5mdWxsWzBdLE0uc3VjY2Vzcz0hMH1jYXRjaChlKXt9dmFyIFU9MCxqPVwiLmJzLnNlbGVjdFwiLFY9e0RJU0FCTEVEOlwiZGlzYWJsZWRcIixESVZJREVSOlwiZGl2aWRlclwiLFNIT1c6XCJvcGVuXCIsRFJPUFVQOlwiZHJvcHVwXCIsTUVOVTpcImRyb3Bkb3duLW1lbnVcIixNRU5VUklHSFQ6XCJkcm9wZG93bi1tZW51LXJpZ2h0XCIsTUVOVUxFRlQ6XCJkcm9wZG93bi1tZW51LWxlZnRcIixCVVRUT05DTEFTUzpcImJ0bi1kZWZhdWx0XCIsUE9QT1ZFUkhFQURFUjpcInBvcG92ZXItdGl0bGVcIixJQ09OQkFTRTpcImdseXBoaWNvblwiLFRJQ0tJQ09OOlwiZ2x5cGhpY29uLW9rXCJ9LEY9e01FTlU6XCIuXCIrVi5NRU5VfSxfPXtkaXY6ZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKSxzcGFuOmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJzcGFuXCIpLGk6ZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImlcIiksc3VidGV4dDpkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic21hbGxcIiksYTpkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiYVwiKSxsaTpkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwibGlcIiksd2hpdGVzcGFjZTpkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShcIlxceGEwXCIpLGZyYWdtZW50OmRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKX07Xy5ub1Jlc3VsdHM9Xy5saS5jbG9uZU5vZGUoITEpLF8ubm9SZXN1bHRzLmNsYXNzTmFtZT1cIm5vLXJlc3VsdHNcIixfLmEuc2V0QXR0cmlidXRlKFwicm9sZVwiLFwib3B0aW9uXCIpLF8uYS5jbGFzc05hbWU9XCJkcm9wZG93bi1pdGVtXCIsXy5zdWJ0ZXh0LmNsYXNzTmFtZT1cInRleHQtbXV0ZWRcIixfLnRleHQ9Xy5zcGFuLmNsb25lTm9kZSghMSksXy50ZXh0LmNsYXNzTmFtZT1cInRleHRcIixfLmNoZWNrTWFyaz1fLnNwYW4uY2xvbmVOb2RlKCExKTt2YXIgRz1uZXcgUmVnRXhwKEIrXCJ8XCIrUikscT1uZXcgUmVnRXhwKFwiXlwiK0grXCIkfFwiK0EpLEs9e2xpOmZ1bmN0aW9uKGUsdCxpKXt2YXIgcz1fLmxpLmNsb25lTm9kZSghMSk7cmV0dXJuIGUmJigxPT09ZS5ub2RlVHlwZXx8MTE9PT1lLm5vZGVUeXBlP3MuYXBwZW5kQ2hpbGQoZSk6cy5pbm5lckhUTUw9ZSksdm9pZCAwIT09dCYmXCJcIiE9PXQmJihzLmNsYXNzTmFtZT10KSxudWxsIT1pJiZzLmNsYXNzTGlzdC5hZGQoXCJvcHRncm91cC1cIitpKSxzfSxhOmZ1bmN0aW9uKGUsdCxpKXt2YXIgcz1fLmEuY2xvbmVOb2RlKCEwKTtyZXR1cm4gZSYmKDExPT09ZS5ub2RlVHlwZT9zLmFwcGVuZENoaWxkKGUpOnMuaW5zZXJ0QWRqYWNlbnRIVE1MKFwiYmVmb3JlZW5kXCIsZSkpLHZvaWQgMCE9PXQmJlwiXCIhPT10JiZzLmNsYXNzTGlzdC5hZGQuYXBwbHkocy5jbGFzc0xpc3QsdC5zcGxpdCgvXFxzKy8pKSxpJiZzLnNldEF0dHJpYnV0ZShcInN0eWxlXCIsaSksc30sdGV4dDpmdW5jdGlvbihlLHQpe3ZhciBpLHMsbj1fLnRleHQuY2xvbmVOb2RlKCExKTtpZihlLmNvbnRlbnQpbi5pbm5lckhUTUw9ZS5jb250ZW50O2Vsc2V7aWYobi50ZXh0Q29udGVudD1lLnRleHQsZS5pY29uKXt2YXIgbz1fLndoaXRlc3BhY2UuY2xvbmVOb2RlKCExKTsocz0oITA9PT10P18uaTpfLnNwYW4pLmNsb25lTm9kZSghMSkpLmNsYXNzTmFtZT10aGlzLm9wdGlvbnMuaWNvbkJhc2UrXCIgXCIrZS5pY29uLF8uZnJhZ21lbnQuYXBwZW5kQ2hpbGQocyksXy5mcmFnbWVudC5hcHBlbmRDaGlsZChvKX1lLnN1YnRleHQmJigoaT1fLnN1YnRleHQuY2xvbmVOb2RlKCExKSkudGV4dENvbnRlbnQ9ZS5zdWJ0ZXh0LG4uYXBwZW5kQ2hpbGQoaSkpfWlmKCEwPT09dClmb3IoOzA8bi5jaGlsZE5vZGVzLmxlbmd0aDspXy5mcmFnbWVudC5hcHBlbmRDaGlsZChuLmNoaWxkTm9kZXNbMF0pO2Vsc2UgXy5mcmFnbWVudC5hcHBlbmRDaGlsZChuKTtyZXR1cm4gXy5mcmFnbWVudH0sbGFiZWw6ZnVuY3Rpb24oZSl7dmFyIHQsaSxzPV8udGV4dC5jbG9uZU5vZGUoITEpO2lmKHMuaW5uZXJIVE1MPWUuZGlzcGxheSxlLmljb24pe3ZhciBuPV8ud2hpdGVzcGFjZS5jbG9uZU5vZGUoITEpOyhpPV8uc3Bhbi5jbG9uZU5vZGUoITEpKS5jbGFzc05hbWU9dGhpcy5vcHRpb25zLmljb25CYXNlK1wiIFwiK2UuaWNvbixfLmZyYWdtZW50LmFwcGVuZENoaWxkKGkpLF8uZnJhZ21lbnQuYXBwZW5kQ2hpbGQobil9cmV0dXJuIGUuc3VidGV4dCYmKCh0PV8uc3VidGV4dC5jbG9uZU5vZGUoITEpKS50ZXh0Q29udGVudD1lLnN1YnRleHQscy5hcHBlbmRDaGlsZCh0KSksXy5mcmFnbWVudC5hcHBlbmRDaGlsZChzKSxfLmZyYWdtZW50fX07dmFyIFk9ZnVuY3Rpb24oZSx0KXt2YXIgaT10aGlzO3AudXNlRGVmYXVsdHx8KFAudmFsSG9va3Muc2VsZWN0LnNldD1wLl9zZXQscC51c2VEZWZhdWx0PSEwKSx0aGlzLiRlbGVtZW50PVAoZSksdGhpcy4kbmV3RWxlbWVudD1udWxsLHRoaXMuJGJ1dHRvbj1udWxsLHRoaXMuJG1lbnU9bnVsbCx0aGlzLm9wdGlvbnM9dCx0aGlzLnNlbGVjdHBpY2tlcj17bWFpbjp7fSxzZWFyY2g6e30sY3VycmVudDp7fSx2aWV3Ont9LGlzU2VhcmNoaW5nOiExLGtleWRvd246e2tleUhpc3Rvcnk6XCJcIixyZXNldEtleUhpc3Rvcnk6e3N0YXJ0OmZ1bmN0aW9uKCl7cmV0dXJuIHNldFRpbWVvdXQoZnVuY3Rpb24oKXtpLnNlbGVjdHBpY2tlci5rZXlkb3duLmtleUhpc3Rvcnk9XCJcIn0sODAwKX19fX0sdGhpcy5zaXplSW5mbz17fSxudWxsPT09dGhpcy5vcHRpb25zLnRpdGxlJiYodGhpcy5vcHRpb25zLnRpdGxlPXRoaXMuJGVsZW1lbnQuYXR0cihcInRpdGxlXCIpKTt2YXIgcz10aGlzLm9wdGlvbnMud2luZG93UGFkZGluZztcIm51bWJlclwiPT10eXBlb2YgcyYmKHRoaXMub3B0aW9ucy53aW5kb3dQYWRkaW5nPVtzLHMscyxzXSksdGhpcy52YWw9WS5wcm90b3R5cGUudmFsLHRoaXMucmVuZGVyPVkucHJvdG90eXBlLnJlbmRlcix0aGlzLnJlZnJlc2g9WS5wcm90b3R5cGUucmVmcmVzaCx0aGlzLnNldFN0eWxlPVkucHJvdG90eXBlLnNldFN0eWxlLHRoaXMuc2VsZWN0QWxsPVkucHJvdG90eXBlLnNlbGVjdEFsbCx0aGlzLmRlc2VsZWN0QWxsPVkucHJvdG90eXBlLmRlc2VsZWN0QWxsLHRoaXMuZGVzdHJveT1ZLnByb3RvdHlwZS5kZXN0cm95LHRoaXMucmVtb3ZlPVkucHJvdG90eXBlLnJlbW92ZSx0aGlzLnNob3c9WS5wcm90b3R5cGUuc2hvdyx0aGlzLmhpZGU9WS5wcm90b3R5cGUuaGlkZSx0aGlzLmluaXQoKX07ZnVuY3Rpb24gWihlKXt2YXIgbCxhPWFyZ3VtZW50cyxjPWU7aWYoW10uc2hpZnQuYXBwbHkoYSksIU0uc3VjY2Vzcyl7dHJ5e00uZnVsbD0oUC5mbi5kcm9wZG93bi5Db25zdHJ1Y3Rvci5WRVJTSU9OfHxcIlwiKS5zcGxpdChcIiBcIilbMF0uc3BsaXQoXCIuXCIpfWNhdGNoKGUpe1kuQm9vdHN0cmFwVmVyc2lvbj9NLmZ1bGw9WS5Cb290c3RyYXBWZXJzaW9uLnNwbGl0KFwiIFwiKVswXS5zcGxpdChcIi5cIik6KE0uZnVsbD1bTS5tYWpvcixcIjBcIixcIjBcIl0sY29uc29sZS53YXJuKFwiVGhlcmUgd2FzIGFuIGlzc3VlIHJldHJpZXZpbmcgQm9vdHN0cmFwJ3MgdmVyc2lvbi4gRW5zdXJlIEJvb3RzdHJhcCBpcyBiZWluZyBsb2FkZWQgYmVmb3JlIGJvb3RzdHJhcC1zZWxlY3QgYW5kIHRoZXJlIGlzIG5vIG5hbWVzcGFjZSBjb2xsaXNpb24uIElmIGxvYWRpbmcgQm9vdHN0cmFwIGFzeW5jaHJvbm91c2x5LCB0aGUgdmVyc2lvbiBtYXkgbmVlZCB0byBiZSBtYW51YWxseSBzcGVjaWZpZWQgdmlhICQuZm4uc2VsZWN0cGlja2VyLkNvbnN0cnVjdG9yLkJvb3RzdHJhcFZlcnNpb24uXCIsZSkpfU0ubWFqb3I9TS5mdWxsWzBdLE0uc3VjY2Vzcz0hMH1pZihcIjRcIj09PU0ubWFqb3Ipe3ZhciB0PVtdO1kuREVGQVVMVFMuc3R5bGU9PT1WLkJVVFRPTkNMQVNTJiZ0LnB1c2goe25hbWU6XCJzdHlsZVwiLGNsYXNzTmFtZTpcIkJVVFRPTkNMQVNTXCJ9KSxZLkRFRkFVTFRTLmljb25CYXNlPT09Vi5JQ09OQkFTRSYmdC5wdXNoKHtuYW1lOlwiaWNvbkJhc2VcIixjbGFzc05hbWU6XCJJQ09OQkFTRVwifSksWS5ERUZBVUxUUy50aWNrSWNvbj09PVYuVElDS0lDT04mJnQucHVzaCh7bmFtZTpcInRpY2tJY29uXCIsY2xhc3NOYW1lOlwiVElDS0lDT05cIn0pLFYuRElWSURFUj1cImRyb3Bkb3duLWRpdmlkZXJcIixWLlNIT1c9XCJzaG93XCIsVi5CVVRUT05DTEFTUz1cImJ0bi1saWdodFwiLFYuUE9QT1ZFUkhFQURFUj1cInBvcG92ZXItaGVhZGVyXCIsVi5JQ09OQkFTRT1cIlwiLFYuVElDS0lDT049XCJicy1vay1kZWZhdWx0XCI7Zm9yKHZhciBpPTA7aTx0Lmxlbmd0aDtpKyspe2U9dFtpXTtZLkRFRkFVTFRTW2UubmFtZV09VltlLmNsYXNzTmFtZV19fXZhciBzPXRoaXMuZWFjaChmdW5jdGlvbigpe3ZhciBlPVAodGhpcyk7aWYoZS5pcyhcInNlbGVjdFwiKSl7dmFyIHQ9ZS5kYXRhKFwic2VsZWN0cGlja2VyXCIpLGk9XCJvYmplY3RcIj09dHlwZW9mIGMmJmM7aWYodCl7aWYoaSlmb3IodmFyIHMgaW4gaSlPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoaSxzKSYmKHQub3B0aW9uc1tzXT1pW3NdKX1lbHNle3ZhciBuPWUuZGF0YSgpO2Zvcih2YXIgbyBpbiBuKU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChuLG8pJiYtMSE9PVAuaW5BcnJheShvLGQpJiZkZWxldGUgbltvXTt2YXIgcj1QLmV4dGVuZCh7fSxZLkRFRkFVTFRTLFAuZm4uc2VsZWN0cGlja2VyLmRlZmF1bHRzfHx7fSxuLGkpO3IudGVtcGxhdGU9UC5leHRlbmQoe30sWS5ERUZBVUxUUy50ZW1wbGF0ZSxQLmZuLnNlbGVjdHBpY2tlci5kZWZhdWx0cz9QLmZuLnNlbGVjdHBpY2tlci5kZWZhdWx0cy50ZW1wbGF0ZTp7fSxuLnRlbXBsYXRlLGkudGVtcGxhdGUpLGUuZGF0YShcInNlbGVjdHBpY2tlclwiLHQ9bmV3IFkodGhpcyxyKSl9XCJzdHJpbmdcIj09dHlwZW9mIGMmJihsPXRbY11pbnN0YW5jZW9mIEZ1bmN0aW9uP3RbY10uYXBwbHkodCxhKTp0Lm9wdGlvbnNbY10pfX0pO3JldHVybiB2b2lkIDAhPT1sP2w6c31ZLlZFUlNJT049XCIxLjEzLjE4XCIsWS5ERUZBVUxUUz17bm9uZVNlbGVjdGVkVGV4dDpcIk5vdGhpbmcgc2VsZWN0ZWRcIixub25lUmVzdWx0c1RleHQ6XCJObyByZXN1bHRzIG1hdGNoZWQgezB9XCIsY291bnRTZWxlY3RlZFRleHQ6ZnVuY3Rpb24oZSx0KXtyZXR1cm4gMT09ZT9cInswfSBpdGVtIHNlbGVjdGVkXCI6XCJ7MH0gaXRlbXMgc2VsZWN0ZWRcIn0sbWF4T3B0aW9uc1RleHQ6ZnVuY3Rpb24oZSx0KXtyZXR1cm5bMT09ZT9cIkxpbWl0IHJlYWNoZWQgKHtufSBpdGVtIG1heClcIjpcIkxpbWl0IHJlYWNoZWQgKHtufSBpdGVtcyBtYXgpXCIsMT09dD9cIkdyb3VwIGxpbWl0IHJlYWNoZWQgKHtufSBpdGVtIG1heClcIjpcIkdyb3VwIGxpbWl0IHJlYWNoZWQgKHtufSBpdGVtcyBtYXgpXCJdfSxzZWxlY3RBbGxUZXh0OlwiU2VsZWN0IEFsbFwiLGRlc2VsZWN0QWxsVGV4dDpcIkRlc2VsZWN0IEFsbFwiLGRvbmVCdXR0b246ITEsZG9uZUJ1dHRvblRleHQ6XCJDbG9zZVwiLG11bHRpcGxlU2VwYXJhdG9yOlwiLCBcIixzdHlsZUJhc2U6XCJidG5cIixzdHlsZTpWLkJVVFRPTkNMQVNTLHNpemU6XCJhdXRvXCIsdGl0bGU6bnVsbCxzZWxlY3RlZFRleHRGb3JtYXQ6XCJ2YWx1ZXNcIix3aWR0aDohMSxjb250YWluZXI6ITEsaGlkZURpc2FibGVkOiExLHNob3dTdWJ0ZXh0OiExLHNob3dJY29uOiEwLHNob3dDb250ZW50OiEwLGRyb3B1cEF1dG86ITAsaGVhZGVyOiExLGxpdmVTZWFyY2g6ITEsbGl2ZVNlYXJjaFBsYWNlaG9sZGVyOm51bGwsbGl2ZVNlYXJjaE5vcm1hbGl6ZTohMSxsaXZlU2VhcmNoU3R5bGU6XCJjb250YWluc1wiLGFjdGlvbnNCb3g6ITEsaWNvbkJhc2U6Vi5JQ09OQkFTRSx0aWNrSWNvbjpWLlRJQ0tJQ09OLHNob3dUaWNrOiExLHRlbXBsYXRlOntjYXJldDonPHNwYW4gY2xhc3M9XCJjYXJldFwiPjwvc3Bhbj4nfSxtYXhPcHRpb25zOiExLG1vYmlsZTohMSxzZWxlY3RPblRhYjohMSxkcm9wZG93bkFsaWduUmlnaHQ6ITEsd2luZG93UGFkZGluZzowLHZpcnR1YWxTY3JvbGw6NjAwLGRpc3BsYXk6ITEsc2FuaXRpemU6ITAsc2FuaXRpemVGbjpudWxsLHdoaXRlTGlzdDplfSxZLnByb3RvdHlwZT17Y29uc3RydWN0b3I6WSxpbml0OmZ1bmN0aW9uKCl7dmFyIGk9dGhpcyxlPXRoaXMuJGVsZW1lbnQuYXR0cihcImlkXCIpLHQ9dGhpcy4kZWxlbWVudFswXSxzPXQuZm9ybTtVKyssdGhpcy5zZWxlY3RJZD1cImJzLXNlbGVjdC1cIitVLHQuY2xhc3NMaXN0LmFkZChcImJzLXNlbGVjdC1oaWRkZW5cIiksdGhpcy5tdWx0aXBsZT10aGlzLiRlbGVtZW50LnByb3AoXCJtdWx0aXBsZVwiKSx0aGlzLmF1dG9mb2N1cz10aGlzLiRlbGVtZW50LnByb3AoXCJhdXRvZm9jdXNcIiksdC5jbGFzc0xpc3QuY29udGFpbnMoXCJzaG93LXRpY2tcIikmJih0aGlzLm9wdGlvbnMuc2hvd1RpY2s9ITApLHRoaXMuJG5ld0VsZW1lbnQ9dGhpcy5jcmVhdGVEcm9wZG93bigpLHRoaXMuYnVpbGREYXRhKCksdGhpcy4kZWxlbWVudC5hZnRlcih0aGlzLiRuZXdFbGVtZW50KS5wcmVwZW5kVG8odGhpcy4kbmV3RWxlbWVudCkscyYmbnVsbD09PXQuZm9ybSYmKHMuaWR8fChzLmlkPVwiZm9ybS1cIit0aGlzLnNlbGVjdElkKSx0LnNldEF0dHJpYnV0ZShcImZvcm1cIixzLmlkKSksdGhpcy4kYnV0dG9uPXRoaXMuJG5ld0VsZW1lbnQuY2hpbGRyZW4oXCJidXR0b25cIiksdGhpcy4kbWVudT10aGlzLiRuZXdFbGVtZW50LmNoaWxkcmVuKEYuTUVOVSksdGhpcy4kbWVudUlubmVyPXRoaXMuJG1lbnUuY2hpbGRyZW4oXCIuaW5uZXJcIiksdGhpcy4kc2VhcmNoYm94PXRoaXMuJG1lbnUuZmluZChcImlucHV0XCIpLHQuY2xhc3NMaXN0LnJlbW92ZShcImJzLXNlbGVjdC1oaWRkZW5cIiksITA9PT10aGlzLm9wdGlvbnMuZHJvcGRvd25BbGlnblJpZ2h0JiZ0aGlzLiRtZW51WzBdLmNsYXNzTGlzdC5hZGQoVi5NRU5VUklHSFQpLHZvaWQgMCE9PWUmJnRoaXMuJGJ1dHRvbi5hdHRyKFwiZGF0YS1pZFwiLGUpLHRoaXMuY2hlY2tEaXNhYmxlZCgpLHRoaXMuY2xpY2tMaXN0ZW5lcigpLHRoaXMub3B0aW9ucy5saXZlU2VhcmNoPyh0aGlzLmxpdmVTZWFyY2hMaXN0ZW5lcigpLHRoaXMuZm9jdXNlZFBhcmVudD10aGlzLiRzZWFyY2hib3hbMF0pOnRoaXMuZm9jdXNlZFBhcmVudD10aGlzLiRtZW51SW5uZXJbMF0sdGhpcy5zZXRTdHlsZSgpLHRoaXMucmVuZGVyKCksdGhpcy5zZXRXaWR0aCgpLHRoaXMub3B0aW9ucy5jb250YWluZXI/dGhpcy5zZWxlY3RQb3NpdGlvbigpOnRoaXMuJGVsZW1lbnQub24oXCJoaWRlXCIraixmdW5jdGlvbigpe2lmKGkuaXNWaXJ0dWFsKCkpe3ZhciBlPWkuJG1lbnVJbm5lclswXSx0PWUuZmlyc3RDaGlsZC5jbG9uZU5vZGUoITEpO2UucmVwbGFjZUNoaWxkKHQsZS5maXJzdENoaWxkKSxlLnNjcm9sbFRvcD0wfX0pLHRoaXMuJG1lbnUuZGF0YShcInRoaXNcIix0aGlzKSx0aGlzLiRuZXdFbGVtZW50LmRhdGEoXCJ0aGlzXCIsdGhpcyksdGhpcy5vcHRpb25zLm1vYmlsZSYmdGhpcy5tb2JpbGUoKSx0aGlzLiRuZXdFbGVtZW50Lm9uKHtcImhpZGUuYnMuZHJvcGRvd25cIjpmdW5jdGlvbihlKXtpLiRlbGVtZW50LnRyaWdnZXIoXCJoaWRlXCIraixlKX0sXCJoaWRkZW4uYnMuZHJvcGRvd25cIjpmdW5jdGlvbihlKXtpLiRlbGVtZW50LnRyaWdnZXIoXCJoaWRkZW5cIitqLGUpfSxcInNob3cuYnMuZHJvcGRvd25cIjpmdW5jdGlvbihlKXtpLiRlbGVtZW50LnRyaWdnZXIoXCJzaG93XCIraixlKX0sXCJzaG93bi5icy5kcm9wZG93blwiOmZ1bmN0aW9uKGUpe2kuJGVsZW1lbnQudHJpZ2dlcihcInNob3duXCIraixlKX19KSx0Lmhhc0F0dHJpYnV0ZShcInJlcXVpcmVkXCIpJiZ0aGlzLiRlbGVtZW50Lm9uKFwiaW52YWxpZFwiK2osZnVuY3Rpb24oKXtpLiRidXR0b25bMF0uY2xhc3NMaXN0LmFkZChcImJzLWludmFsaWRcIiksaS4kZWxlbWVudC5vbihcInNob3duXCIraitcIi5pbnZhbGlkXCIsZnVuY3Rpb24oKXtpLiRlbGVtZW50LnZhbChpLiRlbGVtZW50LnZhbCgpKS5vZmYoXCJzaG93blwiK2orXCIuaW52YWxpZFwiKX0pLm9uKFwicmVuZGVyZWRcIitqLGZ1bmN0aW9uKCl7dGhpcy52YWxpZGl0eS52YWxpZCYmaS4kYnV0dG9uWzBdLmNsYXNzTGlzdC5yZW1vdmUoXCJicy1pbnZhbGlkXCIpLGkuJGVsZW1lbnQub2ZmKFwicmVuZGVyZWRcIitqKX0pLGkuJGJ1dHRvbi5vbihcImJsdXJcIitqLGZ1bmN0aW9uKCl7aS4kZWxlbWVudC50cmlnZ2VyKFwiZm9jdXNcIikudHJpZ2dlcihcImJsdXJcIiksaS4kYnV0dG9uLm9mZihcImJsdXJcIitqKX0pfSksc2V0VGltZW91dChmdW5jdGlvbigpe2kuYnVpbGRMaXN0KCksaS4kZWxlbWVudC50cmlnZ2VyKFwibG9hZGVkXCIrail9KX0sY3JlYXRlRHJvcGRvd246ZnVuY3Rpb24oKXt2YXIgZT10aGlzLm11bHRpcGxlfHx0aGlzLm9wdGlvbnMuc2hvd1RpY2s/XCIgc2hvdy10aWNrXCI6XCJcIix0PXRoaXMubXVsdGlwbGU/JyBhcmlhLW11bHRpc2VsZWN0YWJsZT1cInRydWVcIic6XCJcIixpPVwiXCIscz10aGlzLmF1dG9mb2N1cz9cIiBhdXRvZm9jdXNcIjpcIlwiO00ubWFqb3I8NCYmdGhpcy4kZWxlbWVudC5wYXJlbnQoKS5oYXNDbGFzcyhcImlucHV0LWdyb3VwXCIpJiYoaT1cIiBpbnB1dC1ncm91cC1idG5cIik7dmFyIG4sbz1cIlwiLHI9XCJcIixsPVwiXCIsYT1cIlwiO3JldHVybiB0aGlzLm9wdGlvbnMuaGVhZGVyJiYobz0nPGRpdiBjbGFzcz1cIicrVi5QT1BPVkVSSEVBREVSKydcIj48YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImNsb3NlXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+JnRpbWVzOzwvYnV0dG9uPicrdGhpcy5vcHRpb25zLmhlYWRlcitcIjwvZGl2PlwiKSx0aGlzLm9wdGlvbnMubGl2ZVNlYXJjaCYmKHI9JzxkaXYgY2xhc3M9XCJicy1zZWFyY2hib3hcIj48aW5wdXQgdHlwZT1cInNlYXJjaFwiIGNsYXNzPVwiZm9ybS1jb250cm9sXCIgYXV0b2NvbXBsZXRlPVwib2ZmXCInKyhudWxsPT09dGhpcy5vcHRpb25zLmxpdmVTZWFyY2hQbGFjZWhvbGRlcj9cIlwiOicgcGxhY2Vob2xkZXI9XCInK1ModGhpcy5vcHRpb25zLmxpdmVTZWFyY2hQbGFjZWhvbGRlcikrJ1wiJykrJyByb2xlPVwiY29tYm9ib3hcIiBhcmlhLWxhYmVsPVwiU2VhcmNoXCIgYXJpYS1jb250cm9scz1cIicrdGhpcy5zZWxlY3RJZCsnXCIgYXJpYS1hdXRvY29tcGxldGU9XCJsaXN0XCI+PC9kaXY+JyksdGhpcy5tdWx0aXBsZSYmdGhpcy5vcHRpb25zLmFjdGlvbnNCb3gmJihsPSc8ZGl2IGNsYXNzPVwiYnMtYWN0aW9uc2JveFwiPjxkaXYgY2xhc3M9XCJidG4tZ3JvdXAgYnRuLWdyb3VwLXNtIGJ0bi1ibG9ja1wiPjxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYWN0aW9ucy1idG4gYnMtc2VsZWN0LWFsbCBidG4gJytWLkJVVFRPTkNMQVNTKydcIj4nK3RoaXMub3B0aW9ucy5zZWxlY3RBbGxUZXh0Kyc8L2J1dHRvbj48YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImFjdGlvbnMtYnRuIGJzLWRlc2VsZWN0LWFsbCBidG4gJytWLkJVVFRPTkNMQVNTKydcIj4nK3RoaXMub3B0aW9ucy5kZXNlbGVjdEFsbFRleHQrXCI8L2J1dHRvbj48L2Rpdj48L2Rpdj5cIiksdGhpcy5tdWx0aXBsZSYmdGhpcy5vcHRpb25zLmRvbmVCdXR0b24mJihhPSc8ZGl2IGNsYXNzPVwiYnMtZG9uZWJ1dHRvblwiPjxkaXYgY2xhc3M9XCJidG4tZ3JvdXAgYnRuLWJsb2NrXCI+PGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLXNtICcrVi5CVVRUT05DTEFTUysnXCI+Jyt0aGlzLm9wdGlvbnMuZG9uZUJ1dHRvblRleHQrXCI8L2J1dHRvbj48L2Rpdj48L2Rpdj5cIiksbj0nPGRpdiBjbGFzcz1cImRyb3Bkb3duIGJvb3RzdHJhcC1zZWxlY3QnK2UraSsnXCI+PGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgdGFiaW5kZXg9XCItMVwiIGNsYXNzPVwiJyt0aGlzLm9wdGlvbnMuc3R5bGVCYXNlKycgZHJvcGRvd24tdG9nZ2xlXCIgJysoXCJzdGF0aWNcIj09PXRoaXMub3B0aW9ucy5kaXNwbGF5PydkYXRhLWRpc3BsYXk9XCJzdGF0aWNcIic6XCJcIikrJ2RhdGEtdG9nZ2xlPVwiZHJvcGRvd25cIicrcysnIHJvbGU9XCJjb21ib2JveFwiIGFyaWEtb3ducz1cIicrdGhpcy5zZWxlY3RJZCsnXCIgYXJpYS1oYXNwb3B1cD1cImxpc3Rib3hcIiBhcmlhLWV4cGFuZGVkPVwiZmFsc2VcIj48ZGl2IGNsYXNzPVwiZmlsdGVyLW9wdGlvblwiPjxkaXYgY2xhc3M9XCJmaWx0ZXItb3B0aW9uLWlubmVyXCI+PGRpdiBjbGFzcz1cImZpbHRlci1vcHRpb24taW5uZXItaW5uZXJcIj48L2Rpdj48L2Rpdj4gPC9kaXY+JysoXCI0XCI9PT1NLm1ham9yP1wiXCI6JzxzcGFuIGNsYXNzPVwiYnMtY2FyZXRcIj4nK3RoaXMub3B0aW9ucy50ZW1wbGF0ZS5jYXJldCtcIjwvc3Bhbj5cIikrJzwvYnV0dG9uPjxkaXYgY2xhc3M9XCInK1YuTUVOVStcIiBcIisoXCI0XCI9PT1NLm1ham9yP1wiXCI6Vi5TSE9XKSsnXCI+JytvK3IrbCsnPGRpdiBjbGFzcz1cImlubmVyICcrVi5TSE9XKydcIiByb2xlPVwibGlzdGJveFwiIGlkPVwiJyt0aGlzLnNlbGVjdElkKydcIiB0YWJpbmRleD1cIi0xXCIgJyt0Kyc+PHVsIGNsYXNzPVwiJytWLk1FTlUrXCIgaW5uZXIgXCIrKFwiNFwiPT09TS5tYWpvcj9WLlNIT1c6XCJcIikrJ1wiIHJvbGU9XCJwcmVzZW50YXRpb25cIj48L3VsPjwvZGl2PicrYStcIjwvZGl2PjwvZGl2PlwiLFAobil9LHNldFBvc2l0aW9uRGF0YTpmdW5jdGlvbigpe3RoaXMuc2VsZWN0cGlja2VyLnZpZXcuY2FuSGlnaGxpZ2h0PVtdLHRoaXMuc2VsZWN0cGlja2VyLnZpZXcuc2l6ZT0wLHRoaXMuc2VsZWN0cGlja2VyLnZpZXcuZmlyc3RIaWdobGlnaHRJbmRleD0hMTtmb3IodmFyIGU9MDtlPHRoaXMuc2VsZWN0cGlja2VyLmN1cnJlbnQuZGF0YS5sZW5ndGg7ZSsrKXt2YXIgdD10aGlzLnNlbGVjdHBpY2tlci5jdXJyZW50LmRhdGFbZV0saT0hMDtcImRpdmlkZXJcIj09PXQudHlwZT8oaT0hMSx0LmhlaWdodD10aGlzLnNpemVJbmZvLmRpdmlkZXJIZWlnaHQpOlwib3B0Z3JvdXAtbGFiZWxcIj09PXQudHlwZT8oaT0hMSx0LmhlaWdodD10aGlzLnNpemVJbmZvLmRyb3Bkb3duSGVhZGVySGVpZ2h0KTp0LmhlaWdodD10aGlzLnNpemVJbmZvLmxpSGVpZ2h0LHQuZGlzYWJsZWQmJihpPSExKSx0aGlzLnNlbGVjdHBpY2tlci52aWV3LmNhbkhpZ2hsaWdodC5wdXNoKGkpLGkmJih0aGlzLnNlbGVjdHBpY2tlci52aWV3LnNpemUrKyx0LnBvc2luc2V0PXRoaXMuc2VsZWN0cGlja2VyLnZpZXcuc2l6ZSwhMT09PXRoaXMuc2VsZWN0cGlja2VyLnZpZXcuZmlyc3RIaWdobGlnaHRJbmRleCYmKHRoaXMuc2VsZWN0cGlja2VyLnZpZXcuZmlyc3RIaWdobGlnaHRJbmRleD1lKSksdC5wb3NpdGlvbj0oMD09PWU/MDp0aGlzLnNlbGVjdHBpY2tlci5jdXJyZW50LmRhdGFbZS0xXS5wb3NpdGlvbikrdC5oZWlnaHR9fSxpc1ZpcnR1YWw6ZnVuY3Rpb24oKXtyZXR1cm4hMSE9PXRoaXMub3B0aW9ucy52aXJ0dWFsU2Nyb2xsJiZ0aGlzLnNlbGVjdHBpY2tlci5tYWluLmVsZW1lbnRzLmxlbmd0aD49dGhpcy5vcHRpb25zLnZpcnR1YWxTY3JvbGx8fCEwPT09dGhpcy5vcHRpb25zLnZpcnR1YWxTY3JvbGx9LGNyZWF0ZVZpZXc6ZnVuY3Rpb24oTixlLHQpe3ZhciBBLEwsRD10aGlzLGk9MCxIPVtdO2lmKHRoaXMuc2VsZWN0cGlja2VyLmlzU2VhcmNoaW5nPU4sdGhpcy5zZWxlY3RwaWNrZXIuY3VycmVudD1OP3RoaXMuc2VsZWN0cGlja2VyLnNlYXJjaDp0aGlzLnNlbGVjdHBpY2tlci5tYWluLHRoaXMuc2V0UG9zaXRpb25EYXRhKCksZSlpZih0KWk9dGhpcy4kbWVudUlubmVyWzBdLnNjcm9sbFRvcDtlbHNlIGlmKCFELm11bHRpcGxlKXt2YXIgcz1ELiRlbGVtZW50WzBdLG49KHMub3B0aW9uc1tzLnNlbGVjdGVkSW5kZXhdfHx7fSkubGlJbmRleDtpZihcIm51bWJlclwiPT10eXBlb2YgbiYmITEhPT1ELm9wdGlvbnMuc2l6ZSl7dmFyIG89RC5zZWxlY3RwaWNrZXIubWFpbi5kYXRhW25dLHI9byYmby5wb3NpdGlvbjtyJiYoaT1yLShELnNpemVJbmZvLm1lbnVJbm5lckhlaWdodCtELnNpemVJbmZvLmxpSGVpZ2h0KS8yKX19ZnVuY3Rpb24gbChlLHQpe3ZhciBpLHMsbixvLHIsbCxhLGMsZD1ELnNlbGVjdHBpY2tlci5jdXJyZW50LmVsZW1lbnRzLmxlbmd0aCxoPVtdLHA9ITAsdT1ELmlzVmlydHVhbCgpO0Quc2VsZWN0cGlja2VyLnZpZXcuc2Nyb2xsVG9wPWUsaT1NYXRoLmNlaWwoRC5zaXplSW5mby5tZW51SW5uZXJIZWlnaHQvRC5zaXplSW5mby5saUhlaWdodCoxLjUpLHM9TWF0aC5yb3VuZChkL2kpfHwxO2Zvcih2YXIgZj0wO2Y8cztmKyspe3ZhciBtPShmKzEpKmk7aWYoZj09PXMtMSYmKG09ZCksaFtmXT1bZippKyhmPzE6MCksbV0sIWQpYnJlYWs7dm9pZCAwPT09ciYmZS0xPD1ELnNlbGVjdHBpY2tlci5jdXJyZW50LmRhdGFbbS0xXS5wb3NpdGlvbi1ELnNpemVJbmZvLm1lbnVJbm5lckhlaWdodCYmKHI9Zil9aWYodm9pZCAwPT09ciYmKHI9MCksbD1bRC5zZWxlY3RwaWNrZXIudmlldy5wb3NpdGlvbjAsRC5zZWxlY3RwaWNrZXIudmlldy5wb3NpdGlvbjFdLG49TWF0aC5tYXgoMCxyLTEpLG89TWF0aC5taW4ocy0xLHIrMSksRC5zZWxlY3RwaWNrZXIudmlldy5wb3NpdGlvbjA9ITE9PT11PzA6TWF0aC5tYXgoMCxoW25dWzBdKXx8MCxELnNlbGVjdHBpY2tlci52aWV3LnBvc2l0aW9uMT0hMT09PXU/ZDpNYXRoLm1pbihkLGhbb11bMV0pfHwwLGE9bFswXSE9PUQuc2VsZWN0cGlja2VyLnZpZXcucG9zaXRpb24wfHxsWzFdIT09RC5zZWxlY3RwaWNrZXIudmlldy5wb3NpdGlvbjEsdm9pZCAwIT09RC5hY3RpdmVJbmRleCYmKEw9RC5zZWxlY3RwaWNrZXIubWFpbi5lbGVtZW50c1tELnByZXZBY3RpdmVJbmRleF0sSD1ELnNlbGVjdHBpY2tlci5tYWluLmVsZW1lbnRzW0QuYWN0aXZlSW5kZXhdLEE9RC5zZWxlY3RwaWNrZXIubWFpbi5lbGVtZW50c1tELnNlbGVjdGVkSW5kZXhdLHQmJihELmFjdGl2ZUluZGV4IT09RC5zZWxlY3RlZEluZGV4JiZELmRlZm9jdXNJdGVtKEgpLEQuYWN0aXZlSW5kZXg9dm9pZCAwKSxELmFjdGl2ZUluZGV4JiZELmFjdGl2ZUluZGV4IT09RC5zZWxlY3RlZEluZGV4JiZELmRlZm9jdXNJdGVtKEEpKSx2b2lkIDAhPT1ELnByZXZBY3RpdmVJbmRleCYmRC5wcmV2QWN0aXZlSW5kZXghPT1ELmFjdGl2ZUluZGV4JiZELnByZXZBY3RpdmVJbmRleCE9PUQuc2VsZWN0ZWRJbmRleCYmRC5kZWZvY3VzSXRlbShMKSwodHx8YSkmJihjPUQuc2VsZWN0cGlja2VyLnZpZXcudmlzaWJsZUVsZW1lbnRzP0Quc2VsZWN0cGlja2VyLnZpZXcudmlzaWJsZUVsZW1lbnRzLnNsaWNlKCk6W10sRC5zZWxlY3RwaWNrZXIudmlldy52aXNpYmxlRWxlbWVudHM9ITE9PT11P0Quc2VsZWN0cGlja2VyLmN1cnJlbnQuZWxlbWVudHM6RC5zZWxlY3RwaWNrZXIuY3VycmVudC5lbGVtZW50cy5zbGljZShELnNlbGVjdHBpY2tlci52aWV3LnBvc2l0aW9uMCxELnNlbGVjdHBpY2tlci52aWV3LnBvc2l0aW9uMSksRC5zZXRPcHRpb25TdGF0dXMoKSwoTnx8ITE9PT11JiZ0KSYmKHA9IWZ1bmN0aW9uKGUsaSl7cmV0dXJuIGUubGVuZ3RoPT09aS5sZW5ndGgmJmUuZXZlcnkoZnVuY3Rpb24oZSx0KXtyZXR1cm4gZT09PWlbdF19KX0oYyxELnNlbGVjdHBpY2tlci52aWV3LnZpc2libGVFbGVtZW50cykpLCh0fHwhMD09PXUpJiZwKSl7dmFyIHYsZyxiPUQuJG1lbnVJbm5lclswXSx3PWRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKSxJPWIuZmlyc3RDaGlsZC5jbG9uZU5vZGUoITEpLHg9RC5zZWxlY3RwaWNrZXIudmlldy52aXNpYmxlRWxlbWVudHMsaz1bXTtiLnJlcGxhY2VDaGlsZChJLGIuZmlyc3RDaGlsZCk7Zj0wO2Zvcih2YXIgeT14Lmxlbmd0aDtmPHk7ZisrKXt2YXIgJCxTLEU9eFtmXTtELm9wdGlvbnMuc2FuaXRpemUmJigkPUUubGFzdENoaWxkKSYmKFM9RC5zZWxlY3RwaWNrZXIuY3VycmVudC5kYXRhW2YrRC5zZWxlY3RwaWNrZXIudmlldy5wb3NpdGlvbjBdKSYmUy5jb250ZW50JiYhUy5zYW5pdGl6ZWQmJihrLnB1c2goJCksUy5zYW5pdGl6ZWQ9ITApLHcuYXBwZW5kQ2hpbGQoRSl9aWYoRC5vcHRpb25zLnNhbml0aXplJiZrLmxlbmd0aCYmVyhrLEQub3B0aW9ucy53aGl0ZUxpc3QsRC5vcHRpb25zLnNhbml0aXplRm4pLCEwPT09dT8odj0wPT09RC5zZWxlY3RwaWNrZXIudmlldy5wb3NpdGlvbjA/MDpELnNlbGVjdHBpY2tlci5jdXJyZW50LmRhdGFbRC5zZWxlY3RwaWNrZXIudmlldy5wb3NpdGlvbjAtMV0ucG9zaXRpb24sZz1ELnNlbGVjdHBpY2tlci52aWV3LnBvc2l0aW9uMT5kLTE/MDpELnNlbGVjdHBpY2tlci5jdXJyZW50LmRhdGFbZC0xXS5wb3NpdGlvbi1ELnNlbGVjdHBpY2tlci5jdXJyZW50LmRhdGFbRC5zZWxlY3RwaWNrZXIudmlldy5wb3NpdGlvbjEtMV0ucG9zaXRpb24sYi5maXJzdENoaWxkLnN0eWxlLm1hcmdpblRvcD12K1wicHhcIixiLmZpcnN0Q2hpbGQuc3R5bGUubWFyZ2luQm90dG9tPWcrXCJweFwiKTooYi5maXJzdENoaWxkLnN0eWxlLm1hcmdpblRvcD0wLGIuZmlyc3RDaGlsZC5zdHlsZS5tYXJnaW5Cb3R0b209MCksYi5maXJzdENoaWxkLmFwcGVuZENoaWxkKHcpLCEwPT09dSYmRC5zaXplSW5mby5oYXNTY3JvbGxCYXIpe3ZhciBDPWIuZmlyc3RDaGlsZC5vZmZzZXRXaWR0aDtpZih0JiZDPEQuc2l6ZUluZm8ubWVudUlubmVySW5uZXJXaWR0aCYmRC5zaXplSW5mby50b3RhbE1lbnVXaWR0aD5ELnNpemVJbmZvLnNlbGVjdFdpZHRoKWIuZmlyc3RDaGlsZC5zdHlsZS5taW5XaWR0aD1ELnNpemVJbmZvLm1lbnVJbm5lcklubmVyV2lkdGgrXCJweFwiO2Vsc2UgaWYoQz5ELnNpemVJbmZvLm1lbnVJbm5lcklubmVyV2lkdGgpe0QuJG1lbnVbMF0uc3R5bGUubWluV2lkdGg9MDt2YXIgTz1iLmZpcnN0Q2hpbGQub2Zmc2V0V2lkdGg7Tz5ELnNpemVJbmZvLm1lbnVJbm5lcklubmVyV2lkdGgmJihELnNpemVJbmZvLm1lbnVJbm5lcklubmVyV2lkdGg9TyxiLmZpcnN0Q2hpbGQuc3R5bGUubWluV2lkdGg9RC5zaXplSW5mby5tZW51SW5uZXJJbm5lcldpZHRoK1wicHhcIiksRC4kbWVudVswXS5zdHlsZS5taW5XaWR0aD1cIlwifX19aWYoRC5wcmV2QWN0aXZlSW5kZXg9RC5hY3RpdmVJbmRleCxELm9wdGlvbnMubGl2ZVNlYXJjaCl7aWYoTiYmdCl7dmFyIHosVD0wO0Quc2VsZWN0cGlja2VyLnZpZXcuY2FuSGlnaGxpZ2h0W1RdfHwoVD0xK0Quc2VsZWN0cGlja2VyLnZpZXcuY2FuSGlnaGxpZ2h0LnNsaWNlKDEpLmluZGV4T2YoITApKSx6PUQuc2VsZWN0cGlja2VyLnZpZXcudmlzaWJsZUVsZW1lbnRzW1RdLEQuZGVmb2N1c0l0ZW0oRC5zZWxlY3RwaWNrZXIudmlldy5jdXJyZW50QWN0aXZlKSxELmFjdGl2ZUluZGV4PShELnNlbGVjdHBpY2tlci5jdXJyZW50LmRhdGFbVF18fHt9KS5pbmRleCxELmZvY3VzSXRlbSh6KX19ZWxzZSBELiRtZW51SW5uZXIudHJpZ2dlcihcImZvY3VzXCIpfWwoaSwhMCksdGhpcy4kbWVudUlubmVyLm9mZihcInNjcm9sbC5jcmVhdGVWaWV3XCIpLm9uKFwic2Nyb2xsLmNyZWF0ZVZpZXdcIixmdW5jdGlvbihlLHQpe0Qubm9TY3JvbGx8fGwodGhpcy5zY3JvbGxUb3AsdCksRC5ub1Njcm9sbD0hMX0pLFAod2luZG93KS5vZmYoXCJyZXNpemVcIitqK1wiLlwiK3RoaXMuc2VsZWN0SWQrXCIuY3JlYXRlVmlld1wiKS5vbihcInJlc2l6ZVwiK2orXCIuXCIrdGhpcy5zZWxlY3RJZCtcIi5jcmVhdGVWaWV3XCIsZnVuY3Rpb24oKXtELiRuZXdFbGVtZW50Lmhhc0NsYXNzKFYuU0hPVykmJmwoRC4kbWVudUlubmVyWzBdLnNjcm9sbFRvcCl9KX0sZm9jdXNJdGVtOmZ1bmN0aW9uKGUsdCxpKXtpZihlKXt0PXR8fHRoaXMuc2VsZWN0cGlja2VyLm1haW4uZGF0YVt0aGlzLmFjdGl2ZUluZGV4XTt2YXIgcz1lLmZpcnN0Q2hpbGQ7cyYmKHMuc2V0QXR0cmlidXRlKFwiYXJpYS1zZXRzaXplXCIsdGhpcy5zZWxlY3RwaWNrZXIudmlldy5zaXplKSxzLnNldEF0dHJpYnV0ZShcImFyaWEtcG9zaW5zZXRcIix0LnBvc2luc2V0KSwhMCE9PWkmJih0aGlzLmZvY3VzZWRQYXJlbnQuc2V0QXR0cmlidXRlKFwiYXJpYS1hY3RpdmVkZXNjZW5kYW50XCIscy5pZCksZS5jbGFzc0xpc3QuYWRkKFwiYWN0aXZlXCIpLHMuY2xhc3NMaXN0LmFkZChcImFjdGl2ZVwiKSkpfX0sZGVmb2N1c0l0ZW06ZnVuY3Rpb24oZSl7ZSYmKGUuY2xhc3NMaXN0LnJlbW92ZShcImFjdGl2ZVwiKSxlLmZpcnN0Q2hpbGQmJmUuZmlyc3RDaGlsZC5jbGFzc0xpc3QucmVtb3ZlKFwiYWN0aXZlXCIpKX0sc2V0UGxhY2Vob2xkZXI6ZnVuY3Rpb24oKXt2YXIgZT10aGlzLHQ9ITE7aWYodGhpcy5vcHRpb25zLnRpdGxlJiYhdGhpcy5tdWx0aXBsZSl7dGhpcy5zZWxlY3RwaWNrZXIudmlldy50aXRsZU9wdGlvbnx8KHRoaXMuc2VsZWN0cGlja2VyLnZpZXcudGl0bGVPcHRpb249ZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcIm9wdGlvblwiKSksdD0hMDt2YXIgaT10aGlzLiRlbGVtZW50WzBdLHM9ITEsbj0hdGhpcy5zZWxlY3RwaWNrZXIudmlldy50aXRsZU9wdGlvbi5wYXJlbnROb2RlLG89aS5zZWxlY3RlZEluZGV4LHI9aS5vcHRpb25zW29dLGw9d2luZG93LnBlcmZvcm1hbmNlJiZ3aW5kb3cucGVyZm9ybWFuY2UuZ2V0RW50cmllc0J5VHlwZShcIm5hdmlnYXRpb25cIiksYT1sJiZsLmxlbmd0aD9cImJhY2tfZm9yd2FyZFwiIT09bFswXS50eXBlOjIhPT13aW5kb3cucGVyZm9ybWFuY2UubmF2aWdhdGlvbi50eXBlO24mJih0aGlzLnNlbGVjdHBpY2tlci52aWV3LnRpdGxlT3B0aW9uLmNsYXNzTmFtZT1cImJzLXRpdGxlLW9wdGlvblwiLHRoaXMuc2VsZWN0cGlja2VyLnZpZXcudGl0bGVPcHRpb24udmFsdWU9XCJcIixzPSFyfHwwPT09byYmITE9PT1yLmRlZmF1bHRTZWxlY3RlZCYmdm9pZCAwPT09dGhpcy4kZWxlbWVudC5kYXRhKFwic2VsZWN0ZWRcIikpLCFuJiYwPT09dGhpcy5zZWxlY3RwaWNrZXIudmlldy50aXRsZU9wdGlvbi5pbmRleHx8aS5pbnNlcnRCZWZvcmUodGhpcy5zZWxlY3RwaWNrZXIudmlldy50aXRsZU9wdGlvbixpLmZpcnN0Q2hpbGQpLHMmJmE/aS5zZWxlY3RlZEluZGV4PTA6XCJjb21wbGV0ZVwiIT09ZG9jdW1lbnQucmVhZHlTdGF0ZSYmd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJwYWdlc2hvd1wiLGZ1bmN0aW9uKCl7ZS5zZWxlY3RwaWNrZXIudmlldy5kaXNwbGF5ZWRWYWx1ZSE9PWkudmFsdWUmJmUucmVuZGVyKCl9KX1yZXR1cm4gdH0sYnVpbGREYXRhOmZ1bmN0aW9uKCl7dmFyIHA9Jzpub3QoW2hpZGRlbl0pOm5vdChbZGF0YS1oaWRkZW49XCJ0cnVlXCJdKScsdT1bXSxmPTAsbT10aGlzLnNldFBsYWNlaG9sZGVyKCk/MTowO3RoaXMub3B0aW9ucy5oaWRlRGlzYWJsZWQmJihwKz1cIjpub3QoOmRpc2FibGVkKVwiKTt2YXIgZT10aGlzLiRlbGVtZW50WzBdLnF1ZXJ5U2VsZWN0b3JBbGwoXCJzZWxlY3QgPiAqXCIrcCk7ZnVuY3Rpb24gdihlKXt2YXIgdD11W3UubGVuZ3RoLTFdO3QmJlwiZGl2aWRlclwiPT09dC50eXBlJiYodC5vcHRJRHx8ZS5vcHRJRCl8fCgoZT1lfHx7fSkudHlwZT1cImRpdmlkZXJcIix1LnB1c2goZSkpfWZ1bmN0aW9uIGcoZSx0KXtpZigodD10fHx7fSkuZGl2aWRlcj1cInRydWVcIj09PWUuZ2V0QXR0cmlidXRlKFwiZGF0YS1kaXZpZGVyXCIpLHQuZGl2aWRlcil2KHtvcHRJRDp0Lm9wdElEfSk7ZWxzZXt2YXIgaT11Lmxlbmd0aCxzPWUuc3R5bGUuY3NzVGV4dCxuPXM/UyhzKTpcIlwiLG89KGUuY2xhc3NOYW1lfHxcIlwiKSsodC5vcHRncm91cENsYXNzfHxcIlwiKTt0Lm9wdElEJiYobz1cIm9wdCBcIitvKSx0Lm9wdGlvbkNsYXNzPW8udHJpbSgpLHQuaW5saW5lU3R5bGU9bix0LnRleHQ9ZS50ZXh0Q29udGVudCx0LmNvbnRlbnQ9ZS5nZXRBdHRyaWJ1dGUoXCJkYXRhLWNvbnRlbnRcIiksdC50b2tlbnM9ZS5nZXRBdHRyaWJ1dGUoXCJkYXRhLXRva2Vuc1wiKSx0LnN1YnRleHQ9ZS5nZXRBdHRyaWJ1dGUoXCJkYXRhLXN1YnRleHRcIiksdC5pY29uPWUuZ2V0QXR0cmlidXRlKFwiZGF0YS1pY29uXCIpLGUubGlJbmRleD1pLHQuZGlzcGxheT10LmNvbnRlbnR8fHQudGV4dCx0LnR5cGU9XCJvcHRpb25cIix0LmluZGV4PWksdC5vcHRpb249ZSx0LnNlbGVjdGVkPSEhZS5zZWxlY3RlZCx0LmRpc2FibGVkPXQuZGlzYWJsZWR8fCEhZS5kaXNhYmxlZCx1LnB1c2godCl9fWZ1bmN0aW9uIHQoZSx0KXt2YXIgaT10W2VdLHM9IShlLTE8bSkmJnRbZS0xXSxuPXRbZSsxXSxvPWkucXVlcnlTZWxlY3RvckFsbChcIm9wdGlvblwiK3ApO2lmKG8ubGVuZ3RoKXt2YXIgcixsLGE9e2Rpc3BsYXk6UyhpLmxhYmVsKSxzdWJ0ZXh0OmkuZ2V0QXR0cmlidXRlKFwiZGF0YS1zdWJ0ZXh0XCIpLGljb246aS5nZXRBdHRyaWJ1dGUoXCJkYXRhLWljb25cIiksdHlwZTpcIm9wdGdyb3VwLWxhYmVsXCIsb3B0Z3JvdXBDbGFzczpcIiBcIisoaS5jbGFzc05hbWV8fFwiXCIpfTtmKysscyYmdih7b3B0SUQ6Zn0pLGEub3B0SUQ9Zix1LnB1c2goYSk7Zm9yKHZhciBjPTAsZD1vLmxlbmd0aDtjPGQ7YysrKXt2YXIgaD1vW2NdOzA9PT1jJiYobD0ocj11Lmxlbmd0aC0xKStkKSxnKGgse2hlYWRlckluZGV4OnIsbGFzdEluZGV4Omwsb3B0SUQ6YS5vcHRJRCxvcHRncm91cENsYXNzOmEub3B0Z3JvdXBDbGFzcyxkaXNhYmxlZDppLmRpc2FibGVkfSl9biYmdih7b3B0SUQ6Zn0pfX1mb3IodmFyIGk9ZS5sZW5ndGgscz1tO3M8aTtzKyspe3ZhciBuPWVbc107XCJPUFRHUk9VUFwiIT09bi50YWdOYW1lP2cobix7fSk6dChzLGUpfXRoaXMuc2VsZWN0cGlja2VyLm1haW4uZGF0YT10aGlzLnNlbGVjdHBpY2tlci5jdXJyZW50LmRhdGE9dX0sYnVpbGRMaXN0OmZ1bmN0aW9uKCl7dmFyIHM9dGhpcyxlPXRoaXMuc2VsZWN0cGlja2VyLm1haW4uZGF0YSxuPVtdLG89MDtmdW5jdGlvbiB0KGUpe3ZhciB0LGk9MDtzd2l0Y2goZS50eXBlKXtjYXNlXCJkaXZpZGVyXCI6dD1LLmxpKCExLFYuRElWSURFUixlLm9wdElEP2Uub3B0SUQrXCJkaXZcIjp2b2lkIDApO2JyZWFrO2Nhc2VcIm9wdGlvblwiOih0PUsubGkoSy5hKEsudGV4dC5jYWxsKHMsZSksZS5vcHRpb25DbGFzcyxlLmlubGluZVN0eWxlKSxcIlwiLGUub3B0SUQpKS5maXJzdENoaWxkJiYodC5maXJzdENoaWxkLmlkPXMuc2VsZWN0SWQrXCItXCIrZS5pbmRleCk7YnJlYWs7Y2FzZVwib3B0Z3JvdXAtbGFiZWxcIjp0PUsubGkoSy5sYWJlbC5jYWxsKHMsZSksXCJkcm9wZG93bi1oZWFkZXJcIitlLm9wdGdyb3VwQ2xhc3MsZS5vcHRJRCl9ZS5lbGVtZW50PXQsbi5wdXNoKHQpLGUuZGlzcGxheSYmKGkrPWUuZGlzcGxheS5sZW5ndGgpLGUuc3VidGV4dCYmKGkrPWUuc3VidGV4dC5sZW5ndGgpLGUuaWNvbiYmKGkrPTEpLG88aSYmKG89aSxzLnNlbGVjdHBpY2tlci52aWV3LndpZGVzdE9wdGlvbj1uW24ubGVuZ3RoLTFdKX0hcy5vcHRpb25zLnNob3dUaWNrJiYhcy5tdWx0aXBsZXx8Xy5jaGVja01hcmsucGFyZW50Tm9kZXx8KF8uY2hlY2tNYXJrLmNsYXNzTmFtZT10aGlzLm9wdGlvbnMuaWNvbkJhc2UrXCIgXCIrcy5vcHRpb25zLnRpY2tJY29uK1wiIGNoZWNrLW1hcmtcIixfLmEuYXBwZW5kQ2hpbGQoXy5jaGVja01hcmspKTtmb3IodmFyIGk9ZS5sZW5ndGgscj0wO3I8aTtyKyspe3QoZVtyXSl9dGhpcy5zZWxlY3RwaWNrZXIubWFpbi5lbGVtZW50cz10aGlzLnNlbGVjdHBpY2tlci5jdXJyZW50LmVsZW1lbnRzPW59LGZpbmRMaXM6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy4kbWVudUlubmVyLmZpbmQoXCIuaW5uZXIgPiBsaVwiKX0scmVuZGVyOmZ1bmN0aW9uKCl7dmFyIGUsdD10aGlzLGk9dGhpcy4kZWxlbWVudFswXSxzPXRoaXMuc2V0UGxhY2Vob2xkZXIoKSYmMD09PWkuc2VsZWN0ZWRJbmRleCxuPU8oaSx0aGlzLm9wdGlvbnMuaGlkZURpc2FibGVkKSxvPW4ubGVuZ3RoLHI9dGhpcy4kYnV0dG9uWzBdLGw9ci5xdWVyeVNlbGVjdG9yKFwiLmZpbHRlci1vcHRpb24taW5uZXItaW5uZXJcIiksYT1kb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSh0aGlzLm9wdGlvbnMubXVsdGlwbGVTZXBhcmF0b3IpLGM9Xy5mcmFnbWVudC5jbG9uZU5vZGUoITEpLGQ9ITE7aWYoci5jbGFzc0xpc3QudG9nZ2xlKFwiYnMtcGxhY2Vob2xkZXJcIix0Lm11bHRpcGxlPyFvOiF6KGksbikpLHQubXVsdGlwbGV8fDEhPT1uLmxlbmd0aHx8KHQuc2VsZWN0cGlja2VyLnZpZXcuZGlzcGxheWVkVmFsdWU9eihpLG4pKSxcInN0YXRpY1wiPT09dGhpcy5vcHRpb25zLnNlbGVjdGVkVGV4dEZvcm1hdCljPUsudGV4dC5jYWxsKHRoaXMse3RleHQ6dGhpcy5vcHRpb25zLnRpdGxlfSwhMCk7ZWxzZSBpZighMT09PSh0aGlzLm11bHRpcGxlJiYtMSE9PXRoaXMub3B0aW9ucy5zZWxlY3RlZFRleHRGb3JtYXQuaW5kZXhPZihcImNvdW50XCIpJiYxPG8mJigxPChlPXRoaXMub3B0aW9ucy5zZWxlY3RlZFRleHRGb3JtYXQuc3BsaXQoXCI+XCIpKS5sZW5ndGgmJm8+ZVsxXXx8MT09PWUubGVuZ3RoJiYyPD1vKSkpe2lmKCFzKXtmb3IodmFyIGg9MDtoPG8mJmg8NTA7aCsrKXt2YXIgcD1uW2hdLHU9dGhpcy5zZWxlY3RwaWNrZXIubWFpbi5kYXRhW3AubGlJbmRleF0sZj17fTt0aGlzLm11bHRpcGxlJiYwPGgmJmMuYXBwZW5kQ2hpbGQoYS5jbG9uZU5vZGUoITEpKSxwLnRpdGxlP2YudGV4dD1wLnRpdGxlOnUmJih1LmNvbnRlbnQmJnQub3B0aW9ucy5zaG93Q29udGVudD8oZi5jb250ZW50PXUuY29udGVudC50b1N0cmluZygpLGQ9ITApOih0Lm9wdGlvbnMuc2hvd0ljb24mJihmLmljb249dS5pY29uKSx0Lm9wdGlvbnMuc2hvd1N1YnRleHQmJiF0Lm11bHRpcGxlJiZ1LnN1YnRleHQmJihmLnN1YnRleHQ9XCIgXCIrdS5zdWJ0ZXh0KSxmLnRleHQ9cC50ZXh0Q29udGVudC50cmltKCkpKSxjLmFwcGVuZENoaWxkKEsudGV4dC5jYWxsKHRoaXMsZiwhMCkpfTQ5PG8mJmMuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoXCIuLi5cIikpfX1lbHNle3ZhciBtPSc6bm90KFtoaWRkZW5dKTpub3QoW2RhdGEtaGlkZGVuPVwidHJ1ZVwiXSk6bm90KFtkYXRhLWRpdmlkZXI9XCJ0cnVlXCJdKSc7dGhpcy5vcHRpb25zLmhpZGVEaXNhYmxlZCYmKG0rPVwiOm5vdCg6ZGlzYWJsZWQpXCIpO3ZhciB2PXRoaXMuJGVsZW1lbnRbMF0ucXVlcnlTZWxlY3RvckFsbChcInNlbGVjdCA+IG9wdGlvblwiK20rXCIsIG9wdGdyb3VwXCIrbStcIiBvcHRpb25cIittKS5sZW5ndGgsZz1cImZ1bmN0aW9uXCI9PXR5cGVvZiB0aGlzLm9wdGlvbnMuY291bnRTZWxlY3RlZFRleHQ/dGhpcy5vcHRpb25zLmNvdW50U2VsZWN0ZWRUZXh0KG8sdik6dGhpcy5vcHRpb25zLmNvdW50U2VsZWN0ZWRUZXh0O2M9Sy50ZXh0LmNhbGwodGhpcyx7dGV4dDpnLnJlcGxhY2UoXCJ7MH1cIixvLnRvU3RyaW5nKCkpLnJlcGxhY2UoXCJ7MX1cIix2LnRvU3RyaW5nKCkpfSwhMCl9aWYobnVsbD09dGhpcy5vcHRpb25zLnRpdGxlJiYodGhpcy5vcHRpb25zLnRpdGxlPXRoaXMuJGVsZW1lbnQuYXR0cihcInRpdGxlXCIpKSxjLmNoaWxkTm9kZXMubGVuZ3RofHwoYz1LLnRleHQuY2FsbCh0aGlzLHt0ZXh0OnZvaWQgMCE9PXRoaXMub3B0aW9ucy50aXRsZT90aGlzLm9wdGlvbnMudGl0bGU6dGhpcy5vcHRpb25zLm5vbmVTZWxlY3RlZFRleHR9LCEwKSksci50aXRsZT1jLnRleHRDb250ZW50LnJlcGxhY2UoLzxbXj5dKj4/L2csXCJcIikudHJpbSgpLHRoaXMub3B0aW9ucy5zYW5pdGl6ZSYmZCYmVyhbY10sdC5vcHRpb25zLndoaXRlTGlzdCx0Lm9wdGlvbnMuc2FuaXRpemVGbiksbC5pbm5lckhUTUw9XCJcIixsLmFwcGVuZENoaWxkKGMpLE0ubWFqb3I8NCYmdGhpcy4kbmV3RWxlbWVudFswXS5jbGFzc0xpc3QuY29udGFpbnMoXCJiczMtaGFzLWFkZG9uXCIpKXt2YXIgYj1yLnF1ZXJ5U2VsZWN0b3IoXCIuZmlsdGVyLWV4cGFuZFwiKSx3PWwuY2xvbmVOb2RlKCEwKTt3LmNsYXNzTmFtZT1cImZpbHRlci1leHBhbmRcIixiP3IucmVwbGFjZUNoaWxkKHcsYik6ci5hcHBlbmRDaGlsZCh3KX10aGlzLiRlbGVtZW50LnRyaWdnZXIoXCJyZW5kZXJlZFwiK2opfSxzZXRTdHlsZTpmdW5jdGlvbihlLHQpe3ZhciBpLHM9dGhpcy4kYnV0dG9uWzBdLG49dGhpcy4kbmV3RWxlbWVudFswXSxvPXRoaXMub3B0aW9ucy5zdHlsZS50cmltKCk7dGhpcy4kZWxlbWVudC5hdHRyKFwiY2xhc3NcIikmJnRoaXMuJG5ld0VsZW1lbnQuYWRkQ2xhc3ModGhpcy4kZWxlbWVudC5hdHRyKFwiY2xhc3NcIikucmVwbGFjZSgvc2VsZWN0cGlja2VyfG1vYmlsZS1kZXZpY2V8YnMtc2VsZWN0LWhpZGRlbnx2YWxpZGF0ZVxcWy4qXFxdL2dpLFwiXCIpKSxNLm1ham9yPDQmJihuLmNsYXNzTGlzdC5hZGQoXCJiczNcIiksbi5wYXJlbnROb2RlLmNsYXNzTGlzdCYmbi5wYXJlbnROb2RlLmNsYXNzTGlzdC5jb250YWlucyhcImlucHV0LWdyb3VwXCIpJiYobi5wcmV2aW91c0VsZW1lbnRTaWJsaW5nfHxuLm5leHRFbGVtZW50U2libGluZykmJihuLnByZXZpb3VzRWxlbWVudFNpYmxpbmd8fG4ubmV4dEVsZW1lbnRTaWJsaW5nKS5jbGFzc0xpc3QuY29udGFpbnMoXCJpbnB1dC1ncm91cC1hZGRvblwiKSYmbi5jbGFzc0xpc3QuYWRkKFwiYnMzLWhhcy1hZGRvblwiKSksaT1lP2UudHJpbSgpOm8sXCJhZGRcIj09dD9pJiZzLmNsYXNzTGlzdC5hZGQuYXBwbHkocy5jbGFzc0xpc3QsaS5zcGxpdChcIiBcIikpOlwicmVtb3ZlXCI9PXQ/aSYmcy5jbGFzc0xpc3QucmVtb3ZlLmFwcGx5KHMuY2xhc3NMaXN0LGkuc3BsaXQoXCIgXCIpKToobyYmcy5jbGFzc0xpc3QucmVtb3ZlLmFwcGx5KHMuY2xhc3NMaXN0LG8uc3BsaXQoXCIgXCIpKSxpJiZzLmNsYXNzTGlzdC5hZGQuYXBwbHkocy5jbGFzc0xpc3QsaS5zcGxpdChcIiBcIikpKX0sbGlIZWlnaHQ6ZnVuY3Rpb24oZSl7aWYoZXx8ITEhPT10aGlzLm9wdGlvbnMuc2l6ZSYmIU9iamVjdC5rZXlzKHRoaXMuc2l6ZUluZm8pLmxlbmd0aCl7dmFyIHQsaT1fLmRpdi5jbG9uZU5vZGUoITEpLHM9Xy5kaXYuY2xvbmVOb2RlKCExKSxuPV8uZGl2LmNsb25lTm9kZSghMSksbz1kb2N1bWVudC5jcmVhdGVFbGVtZW50KFwidWxcIikscj1fLmxpLmNsb25lTm9kZSghMSksbD1fLmxpLmNsb25lTm9kZSghMSksYT1fLmEuY2xvbmVOb2RlKCExKSxjPV8uc3Bhbi5jbG9uZU5vZGUoITEpLGQ9dGhpcy5vcHRpb25zLmhlYWRlciYmMDx0aGlzLiRtZW51LmZpbmQoXCIuXCIrVi5QT1BPVkVSSEVBREVSKS5sZW5ndGg/dGhpcy4kbWVudS5maW5kKFwiLlwiK1YuUE9QT1ZFUkhFQURFUilbMF0uY2xvbmVOb2RlKCEwKTpudWxsLGg9dGhpcy5vcHRpb25zLmxpdmVTZWFyY2g/Xy5kaXYuY2xvbmVOb2RlKCExKTpudWxsLHA9dGhpcy5vcHRpb25zLmFjdGlvbnNCb3gmJnRoaXMubXVsdGlwbGUmJjA8dGhpcy4kbWVudS5maW5kKFwiLmJzLWFjdGlvbnNib3hcIikubGVuZ3RoP3RoaXMuJG1lbnUuZmluZChcIi5icy1hY3Rpb25zYm94XCIpWzBdLmNsb25lTm9kZSghMCk6bnVsbCx1PXRoaXMub3B0aW9ucy5kb25lQnV0dG9uJiZ0aGlzLm11bHRpcGxlJiYwPHRoaXMuJG1lbnUuZmluZChcIi5icy1kb25lYnV0dG9uXCIpLmxlbmd0aD90aGlzLiRtZW51LmZpbmQoXCIuYnMtZG9uZWJ1dHRvblwiKVswXS5jbG9uZU5vZGUoITApOm51bGwsZj10aGlzLiRlbGVtZW50LmZpbmQoXCJvcHRpb25cIilbMF07aWYodGhpcy5zaXplSW5mby5zZWxlY3RXaWR0aD10aGlzLiRuZXdFbGVtZW50WzBdLm9mZnNldFdpZHRoLGMuY2xhc3NOYW1lPVwidGV4dFwiLGEuY2xhc3NOYW1lPVwiZHJvcGRvd24taXRlbSBcIisoZj9mLmNsYXNzTmFtZTpcIlwiKSxpLmNsYXNzTmFtZT10aGlzLiRtZW51WzBdLnBhcmVudE5vZGUuY2xhc3NOYW1lK1wiIFwiK1YuU0hPVyxpLnN0eWxlLndpZHRoPTAsXCJhdXRvXCI9PT10aGlzLm9wdGlvbnMud2lkdGgmJihzLnN0eWxlLm1pbldpZHRoPTApLHMuY2xhc3NOYW1lPVYuTUVOVStcIiBcIitWLlNIT1csbi5jbGFzc05hbWU9XCJpbm5lciBcIitWLlNIT1csby5jbGFzc05hbWU9Vi5NRU5VK1wiIGlubmVyIFwiKyhcIjRcIj09PU0ubWFqb3I/Vi5TSE9XOlwiXCIpLHIuY2xhc3NOYW1lPVYuRElWSURFUixsLmNsYXNzTmFtZT1cImRyb3Bkb3duLWhlYWRlclwiLGMuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoXCJcXHUyMDBiXCIpKSx0aGlzLnNlbGVjdHBpY2tlci5jdXJyZW50LmRhdGEubGVuZ3RoKWZvcih2YXIgbT0wO208dGhpcy5zZWxlY3RwaWNrZXIuY3VycmVudC5kYXRhLmxlbmd0aDttKyspe3ZhciB2PXRoaXMuc2VsZWN0cGlja2VyLmN1cnJlbnQuZGF0YVttXTtpZihcIm9wdGlvblwiPT09di50eXBlKXt0PXYuZWxlbWVudDticmVha319ZWxzZSB0PV8ubGkuY2xvbmVOb2RlKCExKSxhLmFwcGVuZENoaWxkKGMpLHQuYXBwZW5kQ2hpbGQoYSk7aWYobC5hcHBlbmRDaGlsZChjLmNsb25lTm9kZSghMCkpLHRoaXMuc2VsZWN0cGlja2VyLnZpZXcud2lkZXN0T3B0aW9uJiZvLmFwcGVuZENoaWxkKHRoaXMuc2VsZWN0cGlja2VyLnZpZXcud2lkZXN0T3B0aW9uLmNsb25lTm9kZSghMCkpLG8uYXBwZW5kQ2hpbGQodCksby5hcHBlbmRDaGlsZChyKSxvLmFwcGVuZENoaWxkKGwpLGQmJnMuYXBwZW5kQ2hpbGQoZCksaCl7dmFyIGc9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImlucHV0XCIpO2guY2xhc3NOYW1lPVwiYnMtc2VhcmNoYm94XCIsZy5jbGFzc05hbWU9XCJmb3JtLWNvbnRyb2xcIixoLmFwcGVuZENoaWxkKGcpLHMuYXBwZW5kQ2hpbGQoaCl9cCYmcy5hcHBlbmRDaGlsZChwKSxuLmFwcGVuZENoaWxkKG8pLHMuYXBwZW5kQ2hpbGQobiksdSYmcy5hcHBlbmRDaGlsZCh1KSxpLmFwcGVuZENoaWxkKHMpLGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoaSk7dmFyIGIsdz10Lm9mZnNldEhlaWdodCxJPWw/bC5vZmZzZXRIZWlnaHQ6MCx4PWQ/ZC5vZmZzZXRIZWlnaHQ6MCxrPWg/aC5vZmZzZXRIZWlnaHQ6MCx5PXA/cC5vZmZzZXRIZWlnaHQ6MCwkPXU/dS5vZmZzZXRIZWlnaHQ6MCxTPVAocikub3V0ZXJIZWlnaHQoITApLEU9ISF3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZSYmd2luZG93LmdldENvbXB1dGVkU3R5bGUocyksQz1zLm9mZnNldFdpZHRoLE89RT9udWxsOlAocyksej17dmVydDpOKEU/RS5wYWRkaW5nVG9wOk8uY3NzKFwicGFkZGluZ1RvcFwiKSkrTihFP0UucGFkZGluZ0JvdHRvbTpPLmNzcyhcInBhZGRpbmdCb3R0b21cIikpK04oRT9FLmJvcmRlclRvcFdpZHRoOk8uY3NzKFwiYm9yZGVyVG9wV2lkdGhcIikpK04oRT9FLmJvcmRlckJvdHRvbVdpZHRoOk8uY3NzKFwiYm9yZGVyQm90dG9tV2lkdGhcIikpLGhvcml6Ok4oRT9FLnBhZGRpbmdMZWZ0Ok8uY3NzKFwicGFkZGluZ0xlZnRcIikpK04oRT9FLnBhZGRpbmdSaWdodDpPLmNzcyhcInBhZGRpbmdSaWdodFwiKSkrTihFP0UuYm9yZGVyTGVmdFdpZHRoOk8uY3NzKFwiYm9yZGVyTGVmdFdpZHRoXCIpKStOKEU/RS5ib3JkZXJSaWdodFdpZHRoOk8uY3NzKFwiYm9yZGVyUmlnaHRXaWR0aFwiKSl9LFQ9e3ZlcnQ6ei52ZXJ0K04oRT9FLm1hcmdpblRvcDpPLmNzcyhcIm1hcmdpblRvcFwiKSkrTihFP0UubWFyZ2luQm90dG9tOk8uY3NzKFwibWFyZ2luQm90dG9tXCIpKSsyLGhvcml6OnouaG9yaXorTihFP0UubWFyZ2luTGVmdDpPLmNzcyhcIm1hcmdpbkxlZnRcIikpK04oRT9FLm1hcmdpblJpZ2h0Ok8uY3NzKFwibWFyZ2luUmlnaHRcIikpKzJ9O24uc3R5bGUub3ZlcmZsb3dZPVwic2Nyb2xsXCIsYj1zLm9mZnNldFdpZHRoLUMsZG9jdW1lbnQuYm9keS5yZW1vdmVDaGlsZChpKSx0aGlzLnNpemVJbmZvLmxpSGVpZ2h0PXcsdGhpcy5zaXplSW5mby5kcm9wZG93bkhlYWRlckhlaWdodD1JLHRoaXMuc2l6ZUluZm8uaGVhZGVySGVpZ2h0PXgsdGhpcy5zaXplSW5mby5zZWFyY2hIZWlnaHQ9ayx0aGlzLnNpemVJbmZvLmFjdGlvbnNIZWlnaHQ9eSx0aGlzLnNpemVJbmZvLmRvbmVCdXR0b25IZWlnaHQ9JCx0aGlzLnNpemVJbmZvLmRpdmlkZXJIZWlnaHQ9Uyx0aGlzLnNpemVJbmZvLm1lbnVQYWRkaW5nPXosdGhpcy5zaXplSW5mby5tZW51RXh0cmFzPVQsdGhpcy5zaXplSW5mby5tZW51V2lkdGg9Qyx0aGlzLnNpemVJbmZvLm1lbnVJbm5lcklubmVyV2lkdGg9Qy16Lmhvcml6LHRoaXMuc2l6ZUluZm8udG90YWxNZW51V2lkdGg9dGhpcy5zaXplSW5mby5tZW51V2lkdGgsdGhpcy5zaXplSW5mby5zY3JvbGxCYXJXaWR0aD1iLHRoaXMuc2l6ZUluZm8uc2VsZWN0SGVpZ2h0PXRoaXMuJG5ld0VsZW1lbnRbMF0ub2Zmc2V0SGVpZ2h0LHRoaXMuc2V0UG9zaXRpb25EYXRhKCl9fSxnZXRTZWxlY3RQb3NpdGlvbjpmdW5jdGlvbigpe3ZhciBlLHQ9UCh3aW5kb3cpLGk9dGhpcy4kbmV3RWxlbWVudC5vZmZzZXQoKSxzPVAodGhpcy5vcHRpb25zLmNvbnRhaW5lcik7dGhpcy5vcHRpb25zLmNvbnRhaW5lciYmcy5sZW5ndGgmJiFzLmlzKFwiYm9keVwiKT8oKGU9cy5vZmZzZXQoKSkudG9wKz1wYXJzZUludChzLmNzcyhcImJvcmRlclRvcFdpZHRoXCIpKSxlLmxlZnQrPXBhcnNlSW50KHMuY3NzKFwiYm9yZGVyTGVmdFdpZHRoXCIpKSk6ZT17dG9wOjAsbGVmdDowfTt2YXIgbj10aGlzLm9wdGlvbnMud2luZG93UGFkZGluZzt0aGlzLnNpemVJbmZvLnNlbGVjdE9mZnNldFRvcD1pLnRvcC1lLnRvcC10LnNjcm9sbFRvcCgpLHRoaXMuc2l6ZUluZm8uc2VsZWN0T2Zmc2V0Qm90PXQuaGVpZ2h0KCktdGhpcy5zaXplSW5mby5zZWxlY3RPZmZzZXRUb3AtdGhpcy5zaXplSW5mby5zZWxlY3RIZWlnaHQtZS50b3AtblsyXSx0aGlzLnNpemVJbmZvLnNlbGVjdE9mZnNldExlZnQ9aS5sZWZ0LWUubGVmdC10LnNjcm9sbExlZnQoKSx0aGlzLnNpemVJbmZvLnNlbGVjdE9mZnNldFJpZ2h0PXQud2lkdGgoKS10aGlzLnNpemVJbmZvLnNlbGVjdE9mZnNldExlZnQtdGhpcy5zaXplSW5mby5zZWxlY3RXaWR0aC1lLmxlZnQtblsxXSx0aGlzLnNpemVJbmZvLnNlbGVjdE9mZnNldFRvcC09blswXSx0aGlzLnNpemVJbmZvLnNlbGVjdE9mZnNldExlZnQtPW5bM119LHNldE1lbnVTaXplOmZ1bmN0aW9uKGUpe3RoaXMuZ2V0U2VsZWN0UG9zaXRpb24oKTt2YXIgdCxpLHMsbixvLHIsbCxhLGM9dGhpcy5zaXplSW5mby5zZWxlY3RXaWR0aCxkPXRoaXMuc2l6ZUluZm8ubGlIZWlnaHQsaD10aGlzLnNpemVJbmZvLmhlYWRlckhlaWdodCxwPXRoaXMuc2l6ZUluZm8uc2VhcmNoSGVpZ2h0LHU9dGhpcy5zaXplSW5mby5hY3Rpb25zSGVpZ2h0LGY9dGhpcy5zaXplSW5mby5kb25lQnV0dG9uSGVpZ2h0LG09dGhpcy5zaXplSW5mby5kaXZpZGVySGVpZ2h0LHY9dGhpcy5zaXplSW5mby5tZW51UGFkZGluZyxnPTA7aWYodGhpcy5vcHRpb25zLmRyb3B1cEF1dG8mJihsPWQqdGhpcy5zZWxlY3RwaWNrZXIuY3VycmVudC5lbGVtZW50cy5sZW5ndGgrdi52ZXJ0LGE9dGhpcy5zaXplSW5mby5zZWxlY3RPZmZzZXRUb3AtdGhpcy5zaXplSW5mby5zZWxlY3RPZmZzZXRCb3Q+dGhpcy5zaXplSW5mby5tZW51RXh0cmFzLnZlcnQmJmwrdGhpcy5zaXplSW5mby5tZW51RXh0cmFzLnZlcnQrNTA+dGhpcy5zaXplSW5mby5zZWxlY3RPZmZzZXRCb3QsITA9PT10aGlzLnNlbGVjdHBpY2tlci5pc1NlYXJjaGluZyYmKGE9dGhpcy5zZWxlY3RwaWNrZXIuZHJvcHVwKSx0aGlzLiRuZXdFbGVtZW50LnRvZ2dsZUNsYXNzKFYuRFJPUFVQLGEpLHRoaXMuc2VsZWN0cGlja2VyLmRyb3B1cD1hKSxcImF1dG9cIj09PXRoaXMub3B0aW9ucy5zaXplKW49Mzx0aGlzLnNlbGVjdHBpY2tlci5jdXJyZW50LmVsZW1lbnRzLmxlbmd0aD8zKnRoaXMuc2l6ZUluZm8ubGlIZWlnaHQrdGhpcy5zaXplSW5mby5tZW51RXh0cmFzLnZlcnQtMjowLGk9dGhpcy5zaXplSW5mby5zZWxlY3RPZmZzZXRCb3QtdGhpcy5zaXplSW5mby5tZW51RXh0cmFzLnZlcnQscz1uK2grcCt1K2Yscj1NYXRoLm1heChuLXYudmVydCwwKSx0aGlzLiRuZXdFbGVtZW50Lmhhc0NsYXNzKFYuRFJPUFVQKSYmKGk9dGhpcy5zaXplSW5mby5zZWxlY3RPZmZzZXRUb3AtdGhpcy5zaXplSW5mby5tZW51RXh0cmFzLnZlcnQpLHQ9KG89aSktaC1wLXUtZi12LnZlcnQ7ZWxzZSBpZih0aGlzLm9wdGlvbnMuc2l6ZSYmXCJhdXRvXCIhPXRoaXMub3B0aW9ucy5zaXplJiZ0aGlzLnNlbGVjdHBpY2tlci5jdXJyZW50LmVsZW1lbnRzLmxlbmd0aD50aGlzLm9wdGlvbnMuc2l6ZSl7Zm9yKHZhciBiPTA7Yjx0aGlzLm9wdGlvbnMuc2l6ZTtiKyspXCJkaXZpZGVyXCI9PT10aGlzLnNlbGVjdHBpY2tlci5jdXJyZW50LmRhdGFbYl0udHlwZSYmZysrO3Q9KGk9ZCp0aGlzLm9wdGlvbnMuc2l6ZStnKm0rdi52ZXJ0KS12LnZlcnQsbz1pK2grcCt1K2Yscz1yPVwiXCJ9dGhpcy4kbWVudS5jc3Moe1wibWF4LWhlaWdodFwiOm8rXCJweFwiLG92ZXJmbG93OlwiaGlkZGVuXCIsXCJtaW4taGVpZ2h0XCI6cytcInB4XCJ9KSx0aGlzLiRtZW51SW5uZXIuY3NzKHtcIm1heC1oZWlnaHRcIjp0K1wicHhcIixcIm92ZXJmbG93LXlcIjpcImF1dG9cIixcIm1pbi1oZWlnaHRcIjpyK1wicHhcIn0pLHRoaXMuc2l6ZUluZm8ubWVudUlubmVySGVpZ2h0PU1hdGgubWF4KHQsMSksdGhpcy5zZWxlY3RwaWNrZXIuY3VycmVudC5kYXRhLmxlbmd0aCYmdGhpcy5zZWxlY3RwaWNrZXIuY3VycmVudC5kYXRhW3RoaXMuc2VsZWN0cGlja2VyLmN1cnJlbnQuZGF0YS5sZW5ndGgtMV0ucG9zaXRpb24+dGhpcy5zaXplSW5mby5tZW51SW5uZXJIZWlnaHQmJih0aGlzLnNpemVJbmZvLmhhc1Njcm9sbEJhcj0hMCx0aGlzLnNpemVJbmZvLnRvdGFsTWVudVdpZHRoPXRoaXMuc2l6ZUluZm8ubWVudVdpZHRoK3RoaXMuc2l6ZUluZm8uc2Nyb2xsQmFyV2lkdGgpLFwiYXV0b1wiPT09dGhpcy5vcHRpb25zLmRyb3Bkb3duQWxpZ25SaWdodCYmdGhpcy4kbWVudS50b2dnbGVDbGFzcyhWLk1FTlVSSUdIVCx0aGlzLnNpemVJbmZvLnNlbGVjdE9mZnNldExlZnQ+dGhpcy5zaXplSW5mby5zZWxlY3RPZmZzZXRSaWdodCYmdGhpcy5zaXplSW5mby5zZWxlY3RPZmZzZXRSaWdodDx0aGlzLnNpemVJbmZvLnRvdGFsTWVudVdpZHRoLWMpLHRoaXMuZHJvcGRvd24mJnRoaXMuZHJvcGRvd24uX3BvcHBlciYmdGhpcy5kcm9wZG93bi5fcG9wcGVyLnVwZGF0ZSgpfSxzZXRTaXplOmZ1bmN0aW9uKGUpe2lmKHRoaXMubGlIZWlnaHQoZSksdGhpcy5vcHRpb25zLmhlYWRlciYmdGhpcy4kbWVudS5jc3MoXCJwYWRkaW5nLXRvcFwiLDApLCExIT09dGhpcy5vcHRpb25zLnNpemUpe3ZhciB0PXRoaXMsaT1QKHdpbmRvdyk7dGhpcy5zZXRNZW51U2l6ZSgpLHRoaXMub3B0aW9ucy5saXZlU2VhcmNoJiZ0aGlzLiRzZWFyY2hib3gub2ZmKFwiaW5wdXQuc2V0TWVudVNpemUgcHJvcGVydHljaGFuZ2Uuc2V0TWVudVNpemVcIikub24oXCJpbnB1dC5zZXRNZW51U2l6ZSBwcm9wZXJ0eWNoYW5nZS5zZXRNZW51U2l6ZVwiLGZ1bmN0aW9uKCl7cmV0dXJuIHQuc2V0TWVudVNpemUoKX0pLFwiYXV0b1wiPT09dGhpcy5vcHRpb25zLnNpemU/aS5vZmYoXCJyZXNpemVcIitqK1wiLlwiK3RoaXMuc2VsZWN0SWQrXCIuc2V0TWVudVNpemUgc2Nyb2xsXCIraitcIi5cIit0aGlzLnNlbGVjdElkK1wiLnNldE1lbnVTaXplXCIpLm9uKFwicmVzaXplXCIraitcIi5cIit0aGlzLnNlbGVjdElkK1wiLnNldE1lbnVTaXplIHNjcm9sbFwiK2orXCIuXCIrdGhpcy5zZWxlY3RJZCtcIi5zZXRNZW51U2l6ZVwiLGZ1bmN0aW9uKCl7cmV0dXJuIHQuc2V0TWVudVNpemUoKX0pOnRoaXMub3B0aW9ucy5zaXplJiZcImF1dG9cIiE9dGhpcy5vcHRpb25zLnNpemUmJnRoaXMuc2VsZWN0cGlja2VyLmN1cnJlbnQuZWxlbWVudHMubGVuZ3RoPnRoaXMub3B0aW9ucy5zaXplJiZpLm9mZihcInJlc2l6ZVwiK2orXCIuXCIrdGhpcy5zZWxlY3RJZCtcIi5zZXRNZW51U2l6ZSBzY3JvbGxcIitqK1wiLlwiK3RoaXMuc2VsZWN0SWQrXCIuc2V0TWVudVNpemVcIil9dGhpcy5jcmVhdGVWaWV3KCExLCEwLGUpfSxzZXRXaWR0aDpmdW5jdGlvbigpe3ZhciBpPXRoaXM7XCJhdXRvXCI9PT10aGlzLm9wdGlvbnMud2lkdGg/cmVxdWVzdEFuaW1hdGlvbkZyYW1lKGZ1bmN0aW9uKCl7aS4kbWVudS5jc3MoXCJtaW4td2lkdGhcIixcIjBcIiksaS4kZWxlbWVudC5vbihcImxvYWRlZFwiK2osZnVuY3Rpb24oKXtpLmxpSGVpZ2h0KCksaS5zZXRNZW51U2l6ZSgpO3ZhciBlPWkuJG5ld0VsZW1lbnQuY2xvbmUoKS5hcHBlbmRUbyhcImJvZHlcIiksdD1lLmNzcyhcIndpZHRoXCIsXCJhdXRvXCIpLmNoaWxkcmVuKFwiYnV0dG9uXCIpLm91dGVyV2lkdGgoKTtlLnJlbW92ZSgpLGkuc2l6ZUluZm8uc2VsZWN0V2lkdGg9TWF0aC5tYXgoaS5zaXplSW5mby50b3RhbE1lbnVXaWR0aCx0KSxpLiRuZXdFbGVtZW50LmNzcyhcIndpZHRoXCIsaS5zaXplSW5mby5zZWxlY3RXaWR0aCtcInB4XCIpfSl9KTpcImZpdFwiPT09dGhpcy5vcHRpb25zLndpZHRoPyh0aGlzLiRtZW51LmNzcyhcIm1pbi13aWR0aFwiLFwiXCIpLHRoaXMuJG5ld0VsZW1lbnQuY3NzKFwid2lkdGhcIixcIlwiKS5hZGRDbGFzcyhcImZpdC13aWR0aFwiKSk6dGhpcy5vcHRpb25zLndpZHRoPyh0aGlzLiRtZW51LmNzcyhcIm1pbi13aWR0aFwiLFwiXCIpLHRoaXMuJG5ld0VsZW1lbnQuY3NzKFwid2lkdGhcIix0aGlzLm9wdGlvbnMud2lkdGgpKToodGhpcy4kbWVudS5jc3MoXCJtaW4td2lkdGhcIixcIlwiKSx0aGlzLiRuZXdFbGVtZW50LmNzcyhcIndpZHRoXCIsXCJcIikpLHRoaXMuJG5ld0VsZW1lbnQuaGFzQ2xhc3MoXCJmaXQtd2lkdGhcIikmJlwiZml0XCIhPT10aGlzLm9wdGlvbnMud2lkdGgmJnRoaXMuJG5ld0VsZW1lbnRbMF0uY2xhc3NMaXN0LnJlbW92ZShcImZpdC13aWR0aFwiKX0sc2VsZWN0UG9zaXRpb246ZnVuY3Rpb24oKXt0aGlzLiRic0NvbnRhaW5lcj1QKCc8ZGl2IGNsYXNzPVwiYnMtY29udGFpbmVyXCIgLz4nKTtmdW5jdGlvbiBlKGUpe3ZhciB0PXt9LGk9ci5vcHRpb25zLmRpc3BsYXl8fCEhUC5mbi5kcm9wZG93bi5Db25zdHJ1Y3Rvci5EZWZhdWx0JiZQLmZuLmRyb3Bkb3duLkNvbnN0cnVjdG9yLkRlZmF1bHQuZGlzcGxheTtyLiRic0NvbnRhaW5lci5hZGRDbGFzcyhlLmF0dHIoXCJjbGFzc1wiKS5yZXBsYWNlKC9mb3JtLWNvbnRyb2x8Zml0LXdpZHRoL2dpLFwiXCIpKS50b2dnbGVDbGFzcyhWLkRST1BVUCxlLmhhc0NsYXNzKFYuRFJPUFVQKSkscz1lLm9mZnNldCgpLGwuaXMoXCJib2R5XCIpP249e3RvcDowLGxlZnQ6MH06KChuPWwub2Zmc2V0KCkpLnRvcCs9cGFyc2VJbnQobC5jc3MoXCJib3JkZXJUb3BXaWR0aFwiKSktbC5zY3JvbGxUb3AoKSxuLmxlZnQrPXBhcnNlSW50KGwuY3NzKFwiYm9yZGVyTGVmdFdpZHRoXCIpKS1sLnNjcm9sbExlZnQoKSksbz1lLmhhc0NsYXNzKFYuRFJPUFVQKT8wOmVbMF0ub2Zmc2V0SGVpZ2h0LChNLm1ham9yPDR8fFwic3RhdGljXCI9PT1pKSYmKHQudG9wPXMudG9wLW4udG9wK28sdC5sZWZ0PXMubGVmdC1uLmxlZnQpLHQud2lkdGg9ZVswXS5vZmZzZXRXaWR0aCxyLiRic0NvbnRhaW5lci5jc3ModCl9dmFyIHMsbixvLHI9dGhpcyxsPVAodGhpcy5vcHRpb25zLmNvbnRhaW5lcik7dGhpcy4kYnV0dG9uLm9uKFwiY2xpY2suYnMuZHJvcGRvd24uZGF0YS1hcGlcIixmdW5jdGlvbigpe3IuaXNEaXNhYmxlZCgpfHwoZShyLiRuZXdFbGVtZW50KSxyLiRic0NvbnRhaW5lci5hcHBlbmRUbyhyLm9wdGlvbnMuY29udGFpbmVyKS50b2dnbGVDbGFzcyhWLlNIT1csIXIuJGJ1dHRvbi5oYXNDbGFzcyhWLlNIT1cpKS5hcHBlbmQoci4kbWVudSkpfSksUCh3aW5kb3cpLm9mZihcInJlc2l6ZVwiK2orXCIuXCIrdGhpcy5zZWxlY3RJZCtcIiBzY3JvbGxcIitqK1wiLlwiK3RoaXMuc2VsZWN0SWQpLm9uKFwicmVzaXplXCIraitcIi5cIit0aGlzLnNlbGVjdElkK1wiIHNjcm9sbFwiK2orXCIuXCIrdGhpcy5zZWxlY3RJZCxmdW5jdGlvbigpe3IuJG5ld0VsZW1lbnQuaGFzQ2xhc3MoVi5TSE9XKSYmZShyLiRuZXdFbGVtZW50KX0pLHRoaXMuJGVsZW1lbnQub24oXCJoaWRlXCIraixmdW5jdGlvbigpe3IuJG1lbnUuZGF0YShcImhlaWdodFwiLHIuJG1lbnUuaGVpZ2h0KCkpLHIuJGJzQ29udGFpbmVyLmRldGFjaCgpfSl9LHNldE9wdGlvblN0YXR1czpmdW5jdGlvbihlKXt2YXIgdD10aGlzO2lmKHQubm9TY3JvbGw9ITEsdC5zZWxlY3RwaWNrZXIudmlldy52aXNpYmxlRWxlbWVudHMmJnQuc2VsZWN0cGlja2VyLnZpZXcudmlzaWJsZUVsZW1lbnRzLmxlbmd0aClmb3IodmFyIGk9MDtpPHQuc2VsZWN0cGlja2VyLnZpZXcudmlzaWJsZUVsZW1lbnRzLmxlbmd0aDtpKyspe3ZhciBzPXQuc2VsZWN0cGlja2VyLmN1cnJlbnQuZGF0YVtpK3Quc2VsZWN0cGlja2VyLnZpZXcucG9zaXRpb24wXSxuPXMub3B0aW9uO24mJighMCE9PWUmJnQuc2V0RGlzYWJsZWQocy5pbmRleCxzLmRpc2FibGVkKSx0LnNldFNlbGVjdGVkKHMuaW5kZXgsbi5zZWxlY3RlZCkpfX0sc2V0U2VsZWN0ZWQ6ZnVuY3Rpb24oZSx0KXt2YXIgaSxzLG49dGhpcy5zZWxlY3RwaWNrZXIubWFpbi5lbGVtZW50c1tlXSxvPXRoaXMuc2VsZWN0cGlja2VyLm1haW4uZGF0YVtlXSxyPXZvaWQgMCE9PXRoaXMuYWN0aXZlSW5kZXgsbD10aGlzLmFjdGl2ZUluZGV4PT09ZXx8dCYmIXRoaXMubXVsdGlwbGUmJiFyO28uc2VsZWN0ZWQ9dCxzPW4uZmlyc3RDaGlsZCx0JiYodGhpcy5zZWxlY3RlZEluZGV4PWUpLG4uY2xhc3NMaXN0LnRvZ2dsZShcInNlbGVjdGVkXCIsdCksbD8odGhpcy5mb2N1c0l0ZW0obixvKSx0aGlzLnNlbGVjdHBpY2tlci52aWV3LmN1cnJlbnRBY3RpdmU9bix0aGlzLmFjdGl2ZUluZGV4PWUpOnRoaXMuZGVmb2N1c0l0ZW0obikscyYmKHMuY2xhc3NMaXN0LnRvZ2dsZShcInNlbGVjdGVkXCIsdCksdD9zLnNldEF0dHJpYnV0ZShcImFyaWEtc2VsZWN0ZWRcIiwhMCk6dGhpcy5tdWx0aXBsZT9zLnNldEF0dHJpYnV0ZShcImFyaWEtc2VsZWN0ZWRcIiwhMSk6cy5yZW1vdmVBdHRyaWJ1dGUoXCJhcmlhLXNlbGVjdGVkXCIpKSxsfHxyfHwhdHx8dm9pZCAwPT09dGhpcy5wcmV2QWN0aXZlSW5kZXh8fChpPXRoaXMuc2VsZWN0cGlja2VyLm1haW4uZWxlbWVudHNbdGhpcy5wcmV2QWN0aXZlSW5kZXhdLHRoaXMuZGVmb2N1c0l0ZW0oaSkpfSxzZXREaXNhYmxlZDpmdW5jdGlvbihlLHQpe3ZhciBpLHM9dGhpcy5zZWxlY3RwaWNrZXIubWFpbi5lbGVtZW50c1tlXTt0aGlzLnNlbGVjdHBpY2tlci5tYWluLmRhdGFbZV0uZGlzYWJsZWQ9dCxpPXMuZmlyc3RDaGlsZCxzLmNsYXNzTGlzdC50b2dnbGUoVi5ESVNBQkxFRCx0KSxpJiYoXCI0XCI9PT1NLm1ham9yJiZpLmNsYXNzTGlzdC50b2dnbGUoVi5ESVNBQkxFRCx0KSx0PyhpLnNldEF0dHJpYnV0ZShcImFyaWEtZGlzYWJsZWRcIix0KSxpLnNldEF0dHJpYnV0ZShcInRhYmluZGV4XCIsLTEpKTooaS5yZW1vdmVBdHRyaWJ1dGUoXCJhcmlhLWRpc2FibGVkXCIpLGkuc2V0QXR0cmlidXRlKFwidGFiaW5kZXhcIiwwKSkpfSxpc0Rpc2FibGVkOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuJGVsZW1lbnRbMF0uZGlzYWJsZWR9LGNoZWNrRGlzYWJsZWQ6ZnVuY3Rpb24oKXt0aGlzLmlzRGlzYWJsZWQoKT8odGhpcy4kbmV3RWxlbWVudFswXS5jbGFzc0xpc3QuYWRkKFYuRElTQUJMRUQpLHRoaXMuJGJ1dHRvbi5hZGRDbGFzcyhWLkRJU0FCTEVEKS5hdHRyKFwiYXJpYS1kaXNhYmxlZFwiLCEwKSk6dGhpcy4kYnV0dG9uWzBdLmNsYXNzTGlzdC5jb250YWlucyhWLkRJU0FCTEVEKSYmKHRoaXMuJG5ld0VsZW1lbnRbMF0uY2xhc3NMaXN0LnJlbW92ZShWLkRJU0FCTEVEKSx0aGlzLiRidXR0b24ucmVtb3ZlQ2xhc3MoVi5ESVNBQkxFRCkuYXR0cihcImFyaWEtZGlzYWJsZWRcIiwhMSkpfSxjbGlja0xpc3RlbmVyOmZ1bmN0aW9uKCl7dmFyIEM9dGhpcyx0PVAoZG9jdW1lbnQpO2Z1bmN0aW9uIGUoKXtDLm9wdGlvbnMubGl2ZVNlYXJjaD9DLiRzZWFyY2hib3gudHJpZ2dlcihcImZvY3VzXCIpOkMuJG1lbnVJbm5lci50cmlnZ2VyKFwiZm9jdXNcIil9ZnVuY3Rpb24gaSgpe0MuZHJvcGRvd24mJkMuZHJvcGRvd24uX3BvcHBlciYmQy5kcm9wZG93bi5fcG9wcGVyLnN0YXRlLmlzQ3JlYXRlZD9lKCk6cmVxdWVzdEFuaW1hdGlvbkZyYW1lKGkpfXQuZGF0YShcInNwYWNlU2VsZWN0XCIsITEpLHRoaXMuJGJ1dHRvbi5vbihcImtleXVwXCIsZnVuY3Rpb24oZSl7LygzMikvLnRlc3QoZS5rZXlDb2RlLnRvU3RyaW5nKDEwKSkmJnQuZGF0YShcInNwYWNlU2VsZWN0XCIpJiYoZS5wcmV2ZW50RGVmYXVsdCgpLHQuZGF0YShcInNwYWNlU2VsZWN0XCIsITEpKX0pLHRoaXMuJG5ld0VsZW1lbnQub24oXCJzaG93LmJzLmRyb3Bkb3duXCIsZnVuY3Rpb24oKXszPE0ubWFqb3ImJiFDLmRyb3Bkb3duJiYoQy5kcm9wZG93bj1DLiRidXR0b24uZGF0YShcImJzLmRyb3Bkb3duXCIpLEMuZHJvcGRvd24uX21lbnU9Qy4kbWVudVswXSl9KSx0aGlzLiRidXR0b24ub24oXCJjbGljay5icy5kcm9wZG93bi5kYXRhLWFwaVwiLGZ1bmN0aW9uKCl7Qy4kbmV3RWxlbWVudC5oYXNDbGFzcyhWLlNIT1cpfHxDLnNldFNpemUoKX0pLHRoaXMuJGVsZW1lbnQub24oXCJzaG93blwiK2osZnVuY3Rpb24oKXtDLiRtZW51SW5uZXJbMF0uc2Nyb2xsVG9wIT09Qy5zZWxlY3RwaWNrZXIudmlldy5zY3JvbGxUb3AmJihDLiRtZW51SW5uZXJbMF0uc2Nyb2xsVG9wPUMuc2VsZWN0cGlja2VyLnZpZXcuc2Nyb2xsVG9wKSwzPE0ubWFqb3I/cmVxdWVzdEFuaW1hdGlvbkZyYW1lKGkpOmUoKX0pLHRoaXMuJG1lbnVJbm5lci5vbihcIm1vdXNlZW50ZXJcIixcImxpIGFcIixmdW5jdGlvbihlKXt2YXIgdD10aGlzLnBhcmVudEVsZW1lbnQsaT1DLmlzVmlydHVhbCgpP0Muc2VsZWN0cGlja2VyLnZpZXcucG9zaXRpb24wOjAscz1BcnJheS5wcm90b3R5cGUuaW5kZXhPZi5jYWxsKHQucGFyZW50RWxlbWVudC5jaGlsZHJlbix0KSxuPUMuc2VsZWN0cGlja2VyLmN1cnJlbnQuZGF0YVtzK2ldO0MuZm9jdXNJdGVtKHQsbiwhMCl9KSx0aGlzLiRtZW51SW5uZXIub24oXCJjbGlja1wiLFwibGkgYVwiLGZ1bmN0aW9uKGUsdCl7dmFyIGk9UCh0aGlzKSxzPUMuJGVsZW1lbnRbMF0sbj1DLmlzVmlydHVhbCgpP0Muc2VsZWN0cGlja2VyLnZpZXcucG9zaXRpb24wOjAsbz1DLnNlbGVjdHBpY2tlci5jdXJyZW50LmRhdGFbaS5wYXJlbnQoKS5pbmRleCgpK25dLHI9by5pbmRleCxsPXoocyksYT1zLnNlbGVjdGVkSW5kZXgsYz1zLm9wdGlvbnNbYV0sZD0hMDtpZihDLm11bHRpcGxlJiYxIT09Qy5vcHRpb25zLm1heE9wdGlvbnMmJmUuc3RvcFByb3BhZ2F0aW9uKCksZS5wcmV2ZW50RGVmYXVsdCgpLCFDLmlzRGlzYWJsZWQoKSYmIWkucGFyZW50KCkuaGFzQ2xhc3MoVi5ESVNBQkxFRCkpe3ZhciBoPW8ub3B0aW9uLHA9UChoKSx1PWguc2VsZWN0ZWQsZj1wLnBhcmVudChcIm9wdGdyb3VwXCIpLG09Zi5maW5kKFwib3B0aW9uXCIpLHY9Qy5vcHRpb25zLm1heE9wdGlvbnMsZz1mLmRhdGEoXCJtYXhPcHRpb25zXCIpfHwhMTtpZihyPT09Qy5hY3RpdmVJbmRleCYmKHQ9ITApLHR8fChDLnByZXZBY3RpdmVJbmRleD1DLmFjdGl2ZUluZGV4LEMuYWN0aXZlSW5kZXg9dm9pZCAwKSxDLm11bHRpcGxlKXtpZihoLnNlbGVjdGVkPSF1LEMuc2V0U2VsZWN0ZWQociwhdSksQy5mb2N1c2VkUGFyZW50LmZvY3VzKCksITEhPT12fHwhMSE9PWcpe3ZhciBiPXY8TyhzKS5sZW5ndGgsdz1nPGYuZmluZChcIm9wdGlvbjpzZWxlY3RlZFwiKS5sZW5ndGg7aWYodiYmYnx8ZyYmdylpZih2JiYxPT12KXMuc2VsZWN0ZWRJbmRleD0tMSxoLnNlbGVjdGVkPSEwLEMuc2V0T3B0aW9uU3RhdHVzKCEwKTtlbHNlIGlmKGcmJjE9PWcpe2Zvcih2YXIgST0wO0k8bS5sZW5ndGg7SSsrKXt2YXIgeD1tW0ldO3guc2VsZWN0ZWQ9ITEsQy5zZXRTZWxlY3RlZCh4LmxpSW5kZXgsITEpfWguc2VsZWN0ZWQ9ITAsQy5zZXRTZWxlY3RlZChyLCEwKX1lbHNle3ZhciBrPVwic3RyaW5nXCI9PXR5cGVvZiBDLm9wdGlvbnMubWF4T3B0aW9uc1RleHQ/W0Mub3B0aW9ucy5tYXhPcHRpb25zVGV4dCxDLm9wdGlvbnMubWF4T3B0aW9uc1RleHRdOkMub3B0aW9ucy5tYXhPcHRpb25zVGV4dCx5PVwiZnVuY3Rpb25cIj09dHlwZW9mIGs/ayh2LGcpOmssJD15WzBdLnJlcGxhY2UoXCJ7bn1cIix2KSxTPXlbMV0ucmVwbGFjZShcIntufVwiLGcpLEU9UCgnPGRpdiBjbGFzcz1cIm5vdGlmeVwiPjwvZGl2PicpO3lbMl0mJigkPSQucmVwbGFjZShcInt2YXJ9XCIseVsyXVsxPHY/MDoxXSksUz1TLnJlcGxhY2UoXCJ7dmFyfVwiLHlbMl1bMTxnPzA6MV0pKSxoLnNlbGVjdGVkPSExLEMuJG1lbnUuYXBwZW5kKEUpLHYmJmImJihFLmFwcGVuZChQKFwiPGRpdj5cIiskK1wiPC9kaXY+XCIpKSxkPSExLEMuJGVsZW1lbnQudHJpZ2dlcihcIm1heFJlYWNoZWRcIitqKSksZyYmdyYmKEUuYXBwZW5kKFAoXCI8ZGl2PlwiK1MrXCI8L2Rpdj5cIikpLGQ9ITEsQy4kZWxlbWVudC50cmlnZ2VyKFwibWF4UmVhY2hlZEdycFwiK2opKSxzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7Qy5zZXRTZWxlY3RlZChyLCExKX0sMTApLEVbMF0uY2xhc3NMaXN0LmFkZChcImZhZGVPdXRcIiksc2V0VGltZW91dChmdW5jdGlvbigpe0UucmVtb3ZlKCl9LDEwNTApfX19ZWxzZSBjJiYoYy5zZWxlY3RlZD0hMSksaC5zZWxlY3RlZD0hMCxDLnNldFNlbGVjdGVkKHIsITApOyFDLm11bHRpcGxlfHxDLm11bHRpcGxlJiYxPT09Qy5vcHRpb25zLm1heE9wdGlvbnM/Qy4kYnV0dG9uLnRyaWdnZXIoXCJmb2N1c1wiKTpDLm9wdGlvbnMubGl2ZVNlYXJjaCYmQy4kc2VhcmNoYm94LnRyaWdnZXIoXCJmb2N1c1wiKSxkJiYoIUMubXVsdGlwbGUmJmE9PT1zLnNlbGVjdGVkSW5kZXh8fChUPVtoLmluZGV4LHAucHJvcChcInNlbGVjdGVkXCIpLGxdLEMuJGVsZW1lbnQudHJpZ2dlck5hdGl2ZShcImNoYW5nZVwiKSkpfX0pLHRoaXMuJG1lbnUub24oXCJjbGlja1wiLFwibGkuXCIrVi5ESVNBQkxFRCtcIiBhLCAuXCIrVi5QT1BPVkVSSEVBREVSK1wiLCAuXCIrVi5QT1BPVkVSSEVBREVSK1wiIDpub3QoLmNsb3NlKVwiLGZ1bmN0aW9uKGUpe2UuY3VycmVudFRhcmdldD09dGhpcyYmKGUucHJldmVudERlZmF1bHQoKSxlLnN0b3BQcm9wYWdhdGlvbigpLEMub3B0aW9ucy5saXZlU2VhcmNoJiYhUChlLnRhcmdldCkuaGFzQ2xhc3MoXCJjbG9zZVwiKT9DLiRzZWFyY2hib3gudHJpZ2dlcihcImZvY3VzXCIpOkMuJGJ1dHRvbi50cmlnZ2VyKFwiZm9jdXNcIikpfSksdGhpcy4kbWVudUlubmVyLm9uKFwiY2xpY2tcIixcIi5kaXZpZGVyLCAuZHJvcGRvd24taGVhZGVyXCIsZnVuY3Rpb24oZSl7ZS5wcmV2ZW50RGVmYXVsdCgpLGUuc3RvcFByb3BhZ2F0aW9uKCksQy5vcHRpb25zLmxpdmVTZWFyY2g/Qy4kc2VhcmNoYm94LnRyaWdnZXIoXCJmb2N1c1wiKTpDLiRidXR0b24udHJpZ2dlcihcImZvY3VzXCIpfSksdGhpcy4kbWVudS5vbihcImNsaWNrXCIsXCIuXCIrVi5QT1BPVkVSSEVBREVSK1wiIC5jbG9zZVwiLGZ1bmN0aW9uKCl7Qy4kYnV0dG9uLnRyaWdnZXIoXCJjbGlja1wiKX0pLHRoaXMuJHNlYXJjaGJveC5vbihcImNsaWNrXCIsZnVuY3Rpb24oZSl7ZS5zdG9wUHJvcGFnYXRpb24oKX0pLHRoaXMuJG1lbnUub24oXCJjbGlja1wiLFwiLmFjdGlvbnMtYnRuXCIsZnVuY3Rpb24oZSl7Qy5vcHRpb25zLmxpdmVTZWFyY2g/Qy4kc2VhcmNoYm94LnRyaWdnZXIoXCJmb2N1c1wiKTpDLiRidXR0b24udHJpZ2dlcihcImZvY3VzXCIpLGUucHJldmVudERlZmF1bHQoKSxlLnN0b3BQcm9wYWdhdGlvbigpLFAodGhpcykuaGFzQ2xhc3MoXCJicy1zZWxlY3QtYWxsXCIpP0Muc2VsZWN0QWxsKCk6Qy5kZXNlbGVjdEFsbCgpfSksdGhpcy4kYnV0dG9uLm9uKFwiZm9jdXNcIitqLGZ1bmN0aW9uKGUpe3ZhciB0PUMuJGVsZW1lbnRbMF0uZ2V0QXR0cmlidXRlKFwidGFiaW5kZXhcIik7dm9pZCAwIT09dCYmZS5vcmlnaW5hbEV2ZW50JiZlLm9yaWdpbmFsRXZlbnQuaXNUcnVzdGVkJiYodGhpcy5zZXRBdHRyaWJ1dGUoXCJ0YWJpbmRleFwiLHQpLEMuJGVsZW1lbnRbMF0uc2V0QXR0cmlidXRlKFwidGFiaW5kZXhcIiwtMSksQy5zZWxlY3RwaWNrZXIudmlldy50YWJpbmRleD10KX0pLm9uKFwiYmx1clwiK2osZnVuY3Rpb24oZSl7dm9pZCAwIT09Qy5zZWxlY3RwaWNrZXIudmlldy50YWJpbmRleCYmZS5vcmlnaW5hbEV2ZW50JiZlLm9yaWdpbmFsRXZlbnQuaXNUcnVzdGVkJiYoQy4kZWxlbWVudFswXS5zZXRBdHRyaWJ1dGUoXCJ0YWJpbmRleFwiLEMuc2VsZWN0cGlja2VyLnZpZXcudGFiaW5kZXgpLHRoaXMuc2V0QXR0cmlidXRlKFwidGFiaW5kZXhcIiwtMSksQy5zZWxlY3RwaWNrZXIudmlldy50YWJpbmRleD12b2lkIDApfSksdGhpcy4kZWxlbWVudC5vbihcImNoYW5nZVwiK2osZnVuY3Rpb24oKXtDLnJlbmRlcigpLEMuJGVsZW1lbnQudHJpZ2dlcihcImNoYW5nZWRcIitqLFQpLFQ9bnVsbH0pLm9uKFwiZm9jdXNcIitqLGZ1bmN0aW9uKCl7Qy5vcHRpb25zLm1vYmlsZXx8Qy4kYnV0dG9uWzBdLmZvY3VzKCl9KX0sbGl2ZVNlYXJjaExpc3RlbmVyOmZ1bmN0aW9uKCl7dmFyIHU9dGhpczt0aGlzLiRidXR0b24ub24oXCJjbGljay5icy5kcm9wZG93bi5kYXRhLWFwaVwiLGZ1bmN0aW9uKCl7dS4kc2VhcmNoYm94LnZhbCgpJiYodS4kc2VhcmNoYm94LnZhbChcIlwiKSx1LnNlbGVjdHBpY2tlci5zZWFyY2gucHJldmlvdXNWYWx1ZT12b2lkIDApfSksdGhpcy4kc2VhcmNoYm94Lm9uKFwiY2xpY2suYnMuZHJvcGRvd24uZGF0YS1hcGkgZm9jdXMuYnMuZHJvcGRvd24uZGF0YS1hcGkgdG91Y2hlbmQuYnMuZHJvcGRvd24uZGF0YS1hcGlcIixmdW5jdGlvbihlKXtlLnN0b3BQcm9wYWdhdGlvbigpfSksdGhpcy4kc2VhcmNoYm94Lm9uKFwiaW5wdXQgcHJvcGVydHljaGFuZ2VcIixmdW5jdGlvbigpe3ZhciBlPXUuJHNlYXJjaGJveFswXS52YWx1ZTtpZih1LnNlbGVjdHBpY2tlci5zZWFyY2guZWxlbWVudHM9W10sdS5zZWxlY3RwaWNrZXIuc2VhcmNoLmRhdGE9W10sZSl7dmFyIHQ9W10saT1lLnRvVXBwZXJDYXNlKCkscz17fSxuPVtdLG89dS5fc2VhcmNoU3R5bGUoKSxyPXUub3B0aW9ucy5saXZlU2VhcmNoTm9ybWFsaXplO3ImJihpPXcoaSkpO2Zvcih2YXIgbD0wO2w8dS5zZWxlY3RwaWNrZXIubWFpbi5kYXRhLmxlbmd0aDtsKyspe3ZhciBhPXUuc2VsZWN0cGlja2VyLm1haW4uZGF0YVtsXTtzW2xdfHwoc1tsXT1rKGEsaSxvLHIpKSxzW2xdJiZ2b2lkIDAhPT1hLmhlYWRlckluZGV4JiYtMT09PW4uaW5kZXhPZihhLmhlYWRlckluZGV4KSYmKDA8YS5oZWFkZXJJbmRleCYmKHNbYS5oZWFkZXJJbmRleC0xXT0hMCxuLnB1c2goYS5oZWFkZXJJbmRleC0xKSksc1thLmhlYWRlckluZGV4XT0hMCxuLnB1c2goYS5oZWFkZXJJbmRleCksc1thLmxhc3RJbmRleCsxXT0hMCksc1tsXSYmXCJvcHRncm91cC1sYWJlbFwiIT09YS50eXBlJiZuLnB1c2gobCl9bD0wO2Zvcih2YXIgYz1uLmxlbmd0aDtsPGM7bCsrKXt2YXIgZD1uW2xdLGg9bltsLTFdLHA9KGE9dS5zZWxlY3RwaWNrZXIubWFpbi5kYXRhW2RdLHUuc2VsZWN0cGlja2VyLm1haW4uZGF0YVtoXSk7KFwiZGl2aWRlclwiIT09YS50eXBlfHxcImRpdmlkZXJcIj09PWEudHlwZSYmcCYmXCJkaXZpZGVyXCIhPT1wLnR5cGUmJmMtMSE9PWwpJiYodS5zZWxlY3RwaWNrZXIuc2VhcmNoLmRhdGEucHVzaChhKSx0LnB1c2godS5zZWxlY3RwaWNrZXIubWFpbi5lbGVtZW50c1tkXSkpfXUuYWN0aXZlSW5kZXg9dm9pZCAwLHUubm9TY3JvbGw9ITAsdS4kbWVudUlubmVyLnNjcm9sbFRvcCgwKSx1LnNlbGVjdHBpY2tlci5zZWFyY2guZWxlbWVudHM9dCx1LmNyZWF0ZVZpZXcoITApLGZ1bmN0aW9uKGUsdCl7ZS5sZW5ndGh8fChfLm5vUmVzdWx0cy5pbm5lckhUTUw9dGhpcy5vcHRpb25zLm5vbmVSZXN1bHRzVGV4dC5yZXBsYWNlKFwiezB9XCIsJ1wiJytTKHQpKydcIicpLHRoaXMuJG1lbnVJbm5lclswXS5maXJzdENoaWxkLmFwcGVuZENoaWxkKF8ubm9SZXN1bHRzKSl9LmNhbGwodSx0LGUpfWVsc2UgdS5zZWxlY3RwaWNrZXIuc2VhcmNoLnByZXZpb3VzVmFsdWUmJih1LiRtZW51SW5uZXIuc2Nyb2xsVG9wKDApLHUuY3JlYXRlVmlldyghMSkpO3Uuc2VsZWN0cGlja2VyLnNlYXJjaC5wcmV2aW91c1ZhbHVlPWV9KX0sX3NlYXJjaFN0eWxlOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMub3B0aW9ucy5saXZlU2VhcmNoU3R5bGV8fFwiY29udGFpbnNcIn0sdmFsOmZ1bmN0aW9uKGUpe3ZhciB0PXRoaXMuJGVsZW1lbnRbMF07aWYodm9pZCAwPT09ZSlyZXR1cm4gdGhpcy4kZWxlbWVudC52YWwoKTt2YXIgaT16KHQpO2lmKFQ9W251bGwsbnVsbCxpXSx0aGlzLiRlbGVtZW50LnZhbChlKS50cmlnZ2VyKFwiY2hhbmdlZFwiK2osVCksdGhpcy4kbmV3RWxlbWVudC5oYXNDbGFzcyhWLlNIT1cpKWlmKHRoaXMubXVsdGlwbGUpdGhpcy5zZXRPcHRpb25TdGF0dXMoITApO2Vsc2V7dmFyIHM9KHQub3B0aW9uc1t0LnNlbGVjdGVkSW5kZXhdfHx7fSkubGlJbmRleDtcIm51bWJlclwiPT10eXBlb2YgcyYmKHRoaXMuc2V0U2VsZWN0ZWQodGhpcy5zZWxlY3RlZEluZGV4LCExKSx0aGlzLnNldFNlbGVjdGVkKHMsITApKX1yZXR1cm4gdGhpcy5yZW5kZXIoKSxUPW51bGwsdGhpcy4kZWxlbWVudH0sY2hhbmdlQWxsOmZ1bmN0aW9uKGUpe2lmKHRoaXMubXVsdGlwbGUpe3ZvaWQgMD09PWUmJihlPSEwKTt2YXIgdD10aGlzLiRlbGVtZW50WzBdLGk9MCxzPTAsbj16KHQpO3QuY2xhc3NMaXN0LmFkZChcImJzLXNlbGVjdC1oaWRkZW5cIik7Zm9yKHZhciBvPTAscj10aGlzLnNlbGVjdHBpY2tlci5jdXJyZW50LmRhdGEsbD1yLmxlbmd0aDtvPGw7bysrKXt2YXIgYT1yW29dLGM9YS5vcHRpb247YyYmIWEuZGlzYWJsZWQmJlwiZGl2aWRlclwiIT09YS50eXBlJiYoYS5zZWxlY3RlZCYmaSsrLCEwPT09KGMuc2VsZWN0ZWQ9ZSkmJnMrKyl9dC5jbGFzc0xpc3QucmVtb3ZlKFwiYnMtc2VsZWN0LWhpZGRlblwiKSxpIT09cyYmKHRoaXMuc2V0T3B0aW9uU3RhdHVzKCksVD1bbnVsbCxudWxsLG5dLHRoaXMuJGVsZW1lbnQudHJpZ2dlck5hdGl2ZShcImNoYW5nZVwiKSl9fSxzZWxlY3RBbGw6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5jaGFuZ2VBbGwoITApfSxkZXNlbGVjdEFsbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmNoYW5nZUFsbCghMSl9LHRvZ2dsZTpmdW5jdGlvbihlKXsoZT1lfHx3aW5kb3cuZXZlbnQpJiZlLnN0b3BQcm9wYWdhdGlvbigpLHRoaXMuJGJ1dHRvbi50cmlnZ2VyKFwiY2xpY2suYnMuZHJvcGRvd24uZGF0YS1hcGlcIil9LGtleWRvd246ZnVuY3Rpb24oZSl7dmFyIHQsaSxzLG4sbyxyPVAodGhpcyksbD1yLmhhc0NsYXNzKFwiZHJvcGRvd24tdG9nZ2xlXCIpLGE9KGw/ci5jbG9zZXN0KFwiLmRyb3Bkb3duXCIpOnIuY2xvc2VzdChGLk1FTlUpKS5kYXRhKFwidGhpc1wiKSxjPWEuZmluZExpcygpLGQ9ITEsaD1lLndoaWNoPT09SCYmIWwmJiFhLm9wdGlvbnMuc2VsZWN0T25UYWIscD1HLnRlc3QoZS53aGljaCl8fGgsdT1hLiRtZW51SW5uZXJbMF0uc2Nyb2xsVG9wLGY9ITA9PT1hLmlzVmlydHVhbCgpP2Euc2VsZWN0cGlja2VyLnZpZXcucG9zaXRpb24wOjA7aWYoISgxMTI8PWUud2hpY2gmJmUud2hpY2g8PTEyMykpaWYoIShpPWEuJG5ld0VsZW1lbnQuaGFzQ2xhc3MoVi5TSE9XKSkmJihwfHw0ODw9ZS53aGljaCYmZS53aGljaDw9NTd8fDk2PD1lLndoaWNoJiZlLndoaWNoPD0xMDV8fDY1PD1lLndoaWNoJiZlLndoaWNoPD05MCkmJihhLiRidXR0b24udHJpZ2dlcihcImNsaWNrLmJzLmRyb3Bkb3duLmRhdGEtYXBpXCIpLGEub3B0aW9ucy5saXZlU2VhcmNoKSlhLiRzZWFyY2hib3gudHJpZ2dlcihcImZvY3VzXCIpO2Vsc2V7aWYoZS53aGljaD09PUEmJmkmJihlLnByZXZlbnREZWZhdWx0KCksYS4kYnV0dG9uLnRyaWdnZXIoXCJjbGljay5icy5kcm9wZG93bi5kYXRhLWFwaVwiKS50cmlnZ2VyKFwiZm9jdXNcIikpLHApe2lmKCFjLmxlbmd0aClyZXR1cm47LTEhPT0odD0ocz1hLnNlbGVjdHBpY2tlci5tYWluLmVsZW1lbnRzW2EuYWN0aXZlSW5kZXhdKT9BcnJheS5wcm90b3R5cGUuaW5kZXhPZi5jYWxsKHMucGFyZW50RWxlbWVudC5jaGlsZHJlbixzKTotMSkmJmEuZGVmb2N1c0l0ZW0ocyksZS53aGljaD09PUI/KC0xIT09dCYmdC0tLHQrZjwwJiYodCs9Yy5sZW5ndGgpLGEuc2VsZWN0cGlja2VyLnZpZXcuY2FuSGlnaGxpZ2h0W3QrZl18fC0xPT09KHQ9YS5zZWxlY3RwaWNrZXIudmlldy5jYW5IaWdobGlnaHQuc2xpY2UoMCx0K2YpLmxhc3RJbmRleE9mKCEwKS1mKSYmKHQ9Yy5sZW5ndGgtMSkpOmUud2hpY2ghPT1SJiYhaHx8KCsrdCtmPj1hLnNlbGVjdHBpY2tlci52aWV3LmNhbkhpZ2hsaWdodC5sZW5ndGgmJih0PWEuc2VsZWN0cGlja2VyLnZpZXcuZmlyc3RIaWdobGlnaHRJbmRleCksYS5zZWxlY3RwaWNrZXIudmlldy5jYW5IaWdobGlnaHRbdCtmXXx8KHQ9dCsxK2Euc2VsZWN0cGlja2VyLnZpZXcuY2FuSGlnaGxpZ2h0LnNsaWNlKHQrZisxKS5pbmRleE9mKCEwKSkpLGUucHJldmVudERlZmF1bHQoKTt2YXIgbT1mK3Q7ZS53aGljaD09PUI/MD09PWYmJnQ9PT1jLmxlbmd0aC0xPyhhLiRtZW51SW5uZXJbMF0uc2Nyb2xsVG9wPWEuJG1lbnVJbm5lclswXS5zY3JvbGxIZWlnaHQsbT1hLnNlbGVjdHBpY2tlci5jdXJyZW50LmVsZW1lbnRzLmxlbmd0aC0xKTpkPShvPShuPWEuc2VsZWN0cGlja2VyLmN1cnJlbnQuZGF0YVttXSkucG9zaXRpb24tbi5oZWlnaHQpPHU6ZS53aGljaCE9PVImJiFofHwodD09PWEuc2VsZWN0cGlja2VyLnZpZXcuZmlyc3RIaWdobGlnaHRJbmRleD8oYS4kbWVudUlubmVyWzBdLnNjcm9sbFRvcD0wLG09YS5zZWxlY3RwaWNrZXIudmlldy5maXJzdEhpZ2hsaWdodEluZGV4KTpkPXU8KG89KG49YS5zZWxlY3RwaWNrZXIuY3VycmVudC5kYXRhW21dKS5wb3NpdGlvbi1hLnNpemVJbmZvLm1lbnVJbm5lckhlaWdodCkpLHM9YS5zZWxlY3RwaWNrZXIuY3VycmVudC5lbGVtZW50c1ttXSxhLmFjdGl2ZUluZGV4PWEuc2VsZWN0cGlja2VyLmN1cnJlbnQuZGF0YVttXS5pbmRleCxhLmZvY3VzSXRlbShzKSxhLnNlbGVjdHBpY2tlci52aWV3LmN1cnJlbnRBY3RpdmU9cyxkJiYoYS4kbWVudUlubmVyWzBdLnNjcm9sbFRvcD1vKSxhLm9wdGlvbnMubGl2ZVNlYXJjaD9hLiRzZWFyY2hib3gudHJpZ2dlcihcImZvY3VzXCIpOnIudHJpZ2dlcihcImZvY3VzXCIpfWVsc2UgaWYoIXIuaXMoXCJpbnB1dFwiKSYmIXEudGVzdChlLndoaWNoKXx8ZS53aGljaD09PUQmJmEuc2VsZWN0cGlja2VyLmtleWRvd24ua2V5SGlzdG9yeSl7dmFyIHYsZyxiPVtdO2UucHJldmVudERlZmF1bHQoKSxhLnNlbGVjdHBpY2tlci5rZXlkb3duLmtleUhpc3RvcnkrPUNbZS53aGljaF0sYS5zZWxlY3RwaWNrZXIua2V5ZG93bi5yZXNldEtleUhpc3RvcnkuY2FuY2VsJiZjbGVhclRpbWVvdXQoYS5zZWxlY3RwaWNrZXIua2V5ZG93bi5yZXNldEtleUhpc3RvcnkuY2FuY2VsKSxhLnNlbGVjdHBpY2tlci5rZXlkb3duLnJlc2V0S2V5SGlzdG9yeS5jYW5jZWw9YS5zZWxlY3RwaWNrZXIua2V5ZG93bi5yZXNldEtleUhpc3Rvcnkuc3RhcnQoKSxnPWEuc2VsZWN0cGlja2VyLmtleWRvd24ua2V5SGlzdG9yeSwvXiguKVxcMSskLy50ZXN0KGcpJiYoZz1nLmNoYXJBdCgwKSk7Zm9yKHZhciB3PTA7dzxhLnNlbGVjdHBpY2tlci5jdXJyZW50LmRhdGEubGVuZ3RoO3crKyl7dmFyIEk9YS5zZWxlY3RwaWNrZXIuY3VycmVudC5kYXRhW3ddO2soSSxnLFwic3RhcnRzV2l0aFwiLCEwKSYmYS5zZWxlY3RwaWNrZXIudmlldy5jYW5IaWdobGlnaHRbd10mJmIucHVzaChJLmluZGV4KX1pZihiLmxlbmd0aCl7dmFyIHg9MDtjLnJlbW92ZUNsYXNzKFwiYWN0aXZlXCIpLmZpbmQoXCJhXCIpLnJlbW92ZUNsYXNzKFwiYWN0aXZlXCIpLDE9PT1nLmxlbmd0aCYmKC0xPT09KHg9Yi5pbmRleE9mKGEuYWN0aXZlSW5kZXgpKXx8eD09PWIubGVuZ3RoLTE/eD0wOngrKyksdj1iW3hdLGQ9MDx1LShuPWEuc2VsZWN0cGlja2VyLm1haW4uZGF0YVt2XSkucG9zaXRpb24/KG89bi5wb3NpdGlvbi1uLmhlaWdodCwhMCk6KG89bi5wb3NpdGlvbi1hLnNpemVJbmZvLm1lbnVJbm5lckhlaWdodCxuLnBvc2l0aW9uPnUrYS5zaXplSW5mby5tZW51SW5uZXJIZWlnaHQpLHM9YS5zZWxlY3RwaWNrZXIubWFpbi5lbGVtZW50c1t2XSxhLmFjdGl2ZUluZGV4PWJbeF0sYS5mb2N1c0l0ZW0ocykscyYmcy5maXJzdENoaWxkLmZvY3VzKCksZCYmKGEuJG1lbnVJbm5lclswXS5zY3JvbGxUb3A9byksci50cmlnZ2VyKFwiZm9jdXNcIil9fWkmJihlLndoaWNoPT09RCYmIWEuc2VsZWN0cGlja2VyLmtleWRvd24ua2V5SGlzdG9yeXx8ZS53aGljaD09PUx8fGUud2hpY2g9PT1IJiZhLm9wdGlvbnMuc2VsZWN0T25UYWIpJiYoZS53aGljaCE9PUQmJmUucHJldmVudERlZmF1bHQoKSxhLm9wdGlvbnMubGl2ZVNlYXJjaCYmZS53aGljaD09PUR8fChhLiRtZW51SW5uZXIuZmluZChcIi5hY3RpdmUgYVwiKS50cmlnZ2VyKFwiY2xpY2tcIiwhMCksci50cmlnZ2VyKFwiZm9jdXNcIiksYS5vcHRpb25zLmxpdmVTZWFyY2h8fChlLnByZXZlbnREZWZhdWx0KCksUChkb2N1bWVudCkuZGF0YShcInNwYWNlU2VsZWN0XCIsITApKSkpfX0sbW9iaWxlOmZ1bmN0aW9uKCl7dGhpcy5vcHRpb25zLm1vYmlsZT0hMCx0aGlzLiRlbGVtZW50WzBdLmNsYXNzTGlzdC5hZGQoXCJtb2JpbGUtZGV2aWNlXCIpfSxyZWZyZXNoOmZ1bmN0aW9uKCl7dmFyIGU9UC5leHRlbmQoe30sdGhpcy5vcHRpb25zLHRoaXMuJGVsZW1lbnQuZGF0YSgpKTt0aGlzLm9wdGlvbnM9ZSx0aGlzLmNoZWNrRGlzYWJsZWQoKSx0aGlzLmJ1aWxkRGF0YSgpLHRoaXMuc2V0U3R5bGUoKSx0aGlzLnJlbmRlcigpLHRoaXMuYnVpbGRMaXN0KCksdGhpcy5zZXRXaWR0aCgpLHRoaXMuc2V0U2l6ZSghMCksdGhpcy4kZWxlbWVudC50cmlnZ2VyKFwicmVmcmVzaGVkXCIrail9LGhpZGU6ZnVuY3Rpb24oKXt0aGlzLiRuZXdFbGVtZW50LmhpZGUoKX0sc2hvdzpmdW5jdGlvbigpe3RoaXMuJG5ld0VsZW1lbnQuc2hvdygpfSxyZW1vdmU6ZnVuY3Rpb24oKXt0aGlzLiRuZXdFbGVtZW50LnJlbW92ZSgpLHRoaXMuJGVsZW1lbnQucmVtb3ZlKCl9LGRlc3Ryb3k6ZnVuY3Rpb24oKXt0aGlzLiRuZXdFbGVtZW50LmJlZm9yZSh0aGlzLiRlbGVtZW50KS5yZW1vdmUoKSx0aGlzLiRic0NvbnRhaW5lcj90aGlzLiRic0NvbnRhaW5lci5yZW1vdmUoKTp0aGlzLiRtZW51LnJlbW92ZSgpLHRoaXMuc2VsZWN0cGlja2VyLnZpZXcudGl0bGVPcHRpb24mJnRoaXMuc2VsZWN0cGlja2VyLnZpZXcudGl0bGVPcHRpb24ucGFyZW50Tm9kZSYmdGhpcy5zZWxlY3RwaWNrZXIudmlldy50aXRsZU9wdGlvbi5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHRoaXMuc2VsZWN0cGlja2VyLnZpZXcudGl0bGVPcHRpb24pLHRoaXMuJGVsZW1lbnQub2ZmKGopLnJlbW92ZURhdGEoXCJzZWxlY3RwaWNrZXJcIikucmVtb3ZlQ2xhc3MoXCJicy1zZWxlY3QtaGlkZGVuIHNlbGVjdHBpY2tlclwiKSxQKHdpbmRvdykub2ZmKGorXCIuXCIrdGhpcy5zZWxlY3RJZCl9fTt2YXIgSj1QLmZuLnNlbGVjdHBpY2tlcjtmdW5jdGlvbiBRKCl7aWYoUC5mbi5kcm9wZG93bilyZXR1cm4oUC5mbi5kcm9wZG93bi5Db25zdHJ1Y3Rvci5fZGF0YUFwaUtleWRvd25IYW5kbGVyfHxQLmZuLmRyb3Bkb3duLkNvbnN0cnVjdG9yLnByb3RvdHlwZS5rZXlkb3duKS5hcHBseSh0aGlzLGFyZ3VtZW50cyl9UC5mbi5zZWxlY3RwaWNrZXI9WixQLmZuLnNlbGVjdHBpY2tlci5Db25zdHJ1Y3Rvcj1ZLFAuZm4uc2VsZWN0cGlja2VyLm5vQ29uZmxpY3Q9ZnVuY3Rpb24oKXtyZXR1cm4gUC5mbi5zZWxlY3RwaWNrZXI9Six0aGlzfSxQKGRvY3VtZW50KS5vZmYoXCJrZXlkb3duLmJzLmRyb3Bkb3duLmRhdGEtYXBpXCIpLm9uKFwia2V5ZG93bi5icy5kcm9wZG93bi5kYXRhLWFwaVwiLCc6bm90KC5ib290c3RyYXAtc2VsZWN0KSA+IFtkYXRhLXRvZ2dsZT1cImRyb3Bkb3duXCJdJyxRKS5vbihcImtleWRvd24uYnMuZHJvcGRvd24uZGF0YS1hcGlcIixcIjpub3QoLmJvb3RzdHJhcC1zZWxlY3QpID4gLmRyb3Bkb3duLW1lbnVcIixRKS5vbihcImtleWRvd25cIitqLCcuYm9vdHN0cmFwLXNlbGVjdCBbZGF0YS10b2dnbGU9XCJkcm9wZG93blwiXSwgLmJvb3RzdHJhcC1zZWxlY3QgW3JvbGU9XCJsaXN0Ym94XCJdLCAuYm9vdHN0cmFwLXNlbGVjdCAuYnMtc2VhcmNoYm94IGlucHV0JyxZLnByb3RvdHlwZS5rZXlkb3duKS5vbihcImZvY3VzaW4ubW9kYWxcIiwnLmJvb3RzdHJhcC1zZWxlY3QgW2RhdGEtdG9nZ2xlPVwiZHJvcGRvd25cIl0sIC5ib290c3RyYXAtc2VsZWN0IFtyb2xlPVwibGlzdGJveFwiXSwgLmJvb3RzdHJhcC1zZWxlY3QgLmJzLXNlYXJjaGJveCBpbnB1dCcsZnVuY3Rpb24oZSl7ZS5zdG9wUHJvcGFnYXRpb24oKX0pLFAod2luZG93KS5vbihcImxvYWRcIitqK1wiLmRhdGEtYXBpXCIsZnVuY3Rpb24oKXtQKFwiLnNlbGVjdHBpY2tlclwiKS5lYWNoKGZ1bmN0aW9uKCl7dmFyIGU9UCh0aGlzKTtaLmNhbGwoZSxlLmRhdGEoKSl9KX0pfShlKX0pO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Ym9vdHN0cmFwLXNlbGVjdC5taW4uanMubWFwIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/bootstrap-select/dist/js/bootstrap-select.min.js\n");
/***/ }),
/***/ "./node_modules/bootstrap-select/dist/js/i18n/defaults-fa_IR.min.js":
/*!**************************************************************************!*\
!*** ./node_modules/bootstrap-select/dist/js/i18n/defaults-fa_IR.min.js ***!
\**************************************************************************/
/***/ (function(module, exports, __webpack_require__) {
eval("var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!\n * Bootstrap-select v1.13.18 (https://developer.snapappointments.com/bootstrap-select)\n *\n * Copyright 2012-2020 SnapAppointments, LLC\n * Licensed under MIT (https://github.com/snapappointments/bootstrap-select/blob/master/LICENSE)\n */\n\n!function(e,t){void 0===e&&void 0!==window&&(e=window), true?!(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__(/*! jquery */ \"./node_modules/jquery/dist/jquery.js\")], __WEBPACK_AMD_DEFINE_RESULT__ = (function(e){return t(e)}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),\n\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)):0}(this,function(e){e.fn.selectpicker.defaults={noneSelectedText:\"\\u0686\\u06cc\\u0632\\u06cc \\u0627\\u0646\\u062a\\u062e\\u0627\\u0628 \\u0646\\u0634\\u062f\\u0647 \\u0627\\u0633\\u062a\",noneResultsText:\"\\u0647\\u06cc\\u062c \\u0645\\u0634\\u0627\\u0628\\u0647\\u06cc \\u0628\\u0631\\u0627\\u06cc {0} \\u067e\\u06cc\\u062f\\u0627 \\u0646\\u0634\\u062f\",countSelectedText:\"{0} \\u0627\\u0632 {1} \\u0645\\u0648\\u0631\\u062f \\u0627\\u0646\\u062a\\u062e\\u0627\\u0628 \\u0634\\u062f\\u0647\",maxOptionsText:[\"\\u0628\\u06cc\\u0634\\u062a\\u0631 \\u0645\\u0645\\u06a9\\u0646 \\u0646\\u06cc\\u0633\\u062a {\\u062d\\u062f\\u0627\\u06a9\\u062b\\u0631 {n} \\u0639\\u062f\\u062f}\",\"\\u0628\\u06cc\\u0634\\u062a\\u0631 \\u0645\\u0645\\u06a9\\u0646 \\u0646\\u06cc\\u0633\\u062a {\\u062d\\u062f\\u0627\\u06a9\\u062b\\u0631 {n} \\u0639\\u062f\\u062f}\"],selectAllText:\"\\u0627\\u0646\\u062a\\u062e\\u0627\\u0628 \\u0647\\u0645\\u0647\",deselectAllText:\"\\u0627\\u0646\\u062a\\u062e\\u0627\\u0628 \\u0647\\u06cc\\u0686 \\u06a9\\u062f\\u0627\\u0645\",multipleSeparator:\", \"}});//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvYm9vdHN0cmFwLXNlbGVjdC9kaXN0L2pzL2kxOG4vZGVmYXVsdHMtZmFfSVIubWluLmpzIiwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxlQUFlLHdDQUF3QyxLQUFxQyxDQUFDLGlDQUFPLENBQUMseUVBQVEsQ0FBQyxtQ0FBQyxZQUFZLFlBQVk7QUFBQSxrR0FBQyxDQUFDLENBQXVGLENBQUMsa0JBQWtCLDRCQUE0QixnT0FBZ08sR0FBRyxpRUFBaUUsR0FBRyxjQUFjLEdBQUcscUxBQXFMLHNDQUFzQyxHQUFHLG1CQUFtQixxRkFBcUYsc0NBQXNDLEdBQUcsbUJBQW1CLHNNQUFzTSIsInNvdXJjZXMiOlsid2VicGFjazovLy8uL25vZGVfbW9kdWxlcy9ib290c3RyYXAtc2VsZWN0L2Rpc3QvanMvaTE4bi9kZWZhdWx0cy1mYV9JUi5taW4uanM/MTBmZSJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiFcbiAqIEJvb3RzdHJhcC1zZWxlY3QgdjEuMTMuMTggKGh0dHBzOi8vZGV2ZWxvcGVyLnNuYXBhcHBvaW50bWVudHMuY29tL2Jvb3RzdHJhcC1zZWxlY3QpXG4gKlxuICogQ29weXJpZ2h0IDIwMTItMjAyMCBTbmFwQXBwb2ludG1lbnRzLCBMTENcbiAqIExpY2Vuc2VkIHVuZGVyIE1JVCAoaHR0cHM6Ly9naXRodWIuY29tL3NuYXBhcHBvaW50bWVudHMvYm9vdHN0cmFwLXNlbGVjdC9ibG9iL21hc3Rlci9MSUNFTlNFKVxuICovXG5cbiFmdW5jdGlvbihlLHQpe3ZvaWQgMD09PWUmJnZvaWQgMCE9PXdpbmRvdyYmKGU9d2luZG93KSxcImZ1bmN0aW9uXCI9PXR5cGVvZiBkZWZpbmUmJmRlZmluZS5hbWQ/ZGVmaW5lKFtcImpxdWVyeVwiXSxmdW5jdGlvbihlKXtyZXR1cm4gdChlKX0pOlwib2JqZWN0XCI9PXR5cGVvZiBtb2R1bGUmJm1vZHVsZS5leHBvcnRzP21vZHVsZS5leHBvcnRzPXQocmVxdWlyZShcImpxdWVyeVwiKSk6dChlLmpRdWVyeSl9KHRoaXMsZnVuY3Rpb24oZSl7ZS5mbi5zZWxlY3RwaWNrZXIuZGVmYXVsdHM9e25vbmVTZWxlY3RlZFRleHQ6XCJcXHUwNjg2XFx1MDZjY1xcdTA2MzJcXHUwNmNjIFxcdTA2MjdcXHUwNjQ2XFx1MDYyYVxcdTA2MmVcXHUwNjI3XFx1MDYyOCBcXHUwNjQ2XFx1MDYzNFxcdTA2MmZcXHUwNjQ3IFxcdTA2MjdcXHUwNjMzXFx1MDYyYVwiLG5vbmVSZXN1bHRzVGV4dDpcIlxcdTA2NDdcXHUwNmNjXFx1MDYyYyBcXHUwNjQ1XFx1MDYzNFxcdTA2MjdcXHUwNjI4XFx1MDY0N1xcdTA2Y2MgXFx1MDYyOFxcdTA2MzFcXHUwNjI3XFx1MDZjYyB7MH0gXFx1MDY3ZVxcdTA2Y2NcXHUwNjJmXFx1MDYyNyBcXHUwNjQ2XFx1MDYzNFxcdTA2MmZcIixjb3VudFNlbGVjdGVkVGV4dDpcInswfSBcXHUwNjI3XFx1MDYzMiB7MX0gXFx1MDY0NVxcdTA2NDhcXHUwNjMxXFx1MDYyZiBcXHUwNjI3XFx1MDY0NlxcdTA2MmFcXHUwNjJlXFx1MDYyN1xcdTA2MjggXFx1MDYzNFxcdTA2MmZcXHUwNjQ3XCIsbWF4T3B0aW9uc1RleHQ6W1wiXFx1MDYyOFxcdTA2Y2NcXHUwNjM0XFx1MDYyYVxcdTA2MzEgXFx1MDY0NVxcdTA2NDVcXHUwNmE5XFx1MDY0NiBcXHUwNjQ2XFx1MDZjY1xcdTA2MzNcXHUwNjJhIHtcXHUwNjJkXFx1MDYyZlxcdTA2MjdcXHUwNmE5XFx1MDYyYlxcdTA2MzEge259IFxcdTA2MzlcXHUwNjJmXFx1MDYyZn1cIixcIlxcdTA2MjhcXHUwNmNjXFx1MDYzNFxcdTA2MmFcXHUwNjMxIFxcdTA2NDVcXHUwNjQ1XFx1MDZhOVxcdTA2NDYgXFx1MDY0NlxcdTA2Y2NcXHUwNjMzXFx1MDYyYSB7XFx1MDYyZFxcdTA2MmZcXHUwNjI3XFx1MDZhOVxcdTA2MmJcXHUwNjMxIHtufSBcXHUwNjM5XFx1MDYyZlxcdTA2MmZ9XCJdLHNlbGVjdEFsbFRleHQ6XCJcXHUwNjI3XFx1MDY0NlxcdTA2MmFcXHUwNjJlXFx1MDYyN1xcdTA2MjggXFx1MDY0N1xcdTA2NDVcXHUwNjQ3XCIsZGVzZWxlY3RBbGxUZXh0OlwiXFx1MDYyN1xcdTA2NDZcXHUwNjJhXFx1MDYyZVxcdTA2MjdcXHUwNjI4IFxcdTA2NDdcXHUwNmNjXFx1MDY4NiBcXHUwNmE5XFx1MDYyZlxcdTA2MjdcXHUwNjQ1XCIsbXVsdGlwbGVTZXBhcmF0b3I6XCIsIFwifX0pOyJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./node_modules/bootstrap-select/dist/js/i18n/defaults-fa_IR.min.js\n");
/***/ }),
/***/ "./node_modules/bootstrap-tagsinput/dist/bootstrap-tagsinput.min.js":
/*!**************************************************************************!*\
!*** ./node_modules/bootstrap-tagsinput/dist/bootstrap-tagsinput.min.js ***!
\**************************************************************************/
/***/ (() => {
eval("/*\n * bootstrap-tagsinput v0.7.1 by Tim Schlechter\n * \n */\n\n!function(a){\"use strict\";function b(b,c){this.isInit=!0,this.itemsArray=[],this.$element=a(b),this.$element.hide(),this.isSelect=\"SELECT\"===b.tagName,this.multiple=this.isSelect&&b.hasAttribute(\"multiple\"),this.objectItems=c&&c.itemValue,this.placeholderText=b.hasAttribute(\"placeholder\")?this.$element.attr(\"placeholder\"):\"\",this.inputSize=Math.max(1,this.placeholderText.length),this.$container=a('<div class=\"bootstrap-tagsinput\"></div>'),this.$input=a('<input type=\"text\" placeholder=\"'+this.placeholderText+'\"/>').appendTo(this.$container),this.$element.before(this.$container),this.build(c),this.isInit=!1}function c(a,b){if(\"function\"!=typeof a[b]){var c=a[b];a[b]=function(a){return a[c]}}}function d(a,b){if(\"function\"!=typeof a[b]){var c=a[b];a[b]=function(){return c}}}function e(a){return a?i.text(a).html():\"\"}function f(a){var b=0;if(document.selection){a.focus();var c=document.selection.createRange();c.moveStart(\"character\",-a.value.length),b=c.text.length}else(a.selectionStart||\"0\"==a.selectionStart)&&(b=a.selectionStart);return b}function g(b,c){var d=!1;return a.each(c,function(a,c){if(\"number\"==typeof c&&b.which===c)return d=!0,!1;if(b.which===c.which){var e=!c.hasOwnProperty(\"altKey\")||b.altKey===c.altKey,f=!c.hasOwnProperty(\"shiftKey\")||b.shiftKey===c.shiftKey,g=!c.hasOwnProperty(\"ctrlKey\")||b.ctrlKey===c.ctrlKey;if(e&&f&&g)return d=!0,!1}}),d}var h={tagClass:function(a){return\"label label-info\"},itemValue:function(a){return a?a.toString():a},itemText:function(a){return this.itemValue(a)},itemTitle:function(a){return null},freeInput:!0,addOnBlur:!0,maxTags:void 0,maxChars:void 0,confirmKeys:[13,44],delimiter:\",\",delimiterRegex:null,cancelConfirmKeysOnEmpty:!1,onTagExists:function(a,b){b.hide().fadeIn()},trimValue:!1,allowDuplicates:!1};b.prototype={constructor:b,add:function(b,c,d){var f=this;if(!(f.options.maxTags&&f.itemsArray.length>=f.options.maxTags)&&(b===!1||b)){if(\"string\"==typeof b&&f.options.trimValue&&(b=a.trim(b)),\"object\"==typeof b&&!f.objectItems)throw\"Can't add objects when itemValue option is not set\";if(!b.toString().match(/^\\s*$/)){if(f.isSelect&&!f.multiple&&f.itemsArray.length>0&&f.remove(f.itemsArray[0]),\"string\"==typeof b&&\"INPUT\"===this.$element[0].tagName){var g=f.options.delimiterRegex?f.options.delimiterRegex:f.options.delimiter,h=b.split(g);if(h.length>1){for(var i=0;i<h.length;i++)this.add(h[i],!0);return void(c||f.pushVal())}}var j=f.options.itemValue(b),k=f.options.itemText(b),l=f.options.tagClass(b),m=f.options.itemTitle(b),n=a.grep(f.itemsArray,function(a){return f.options.itemValue(a)===j})[0];if(!n||f.options.allowDuplicates){if(!(f.items().toString().length+b.length+1>f.options.maxInputLength)){var o=a.Event(\"beforeItemAdd\",{item:b,cancel:!1,options:d});if(f.$element.trigger(o),!o.cancel){f.itemsArray.push(b);var p=a('<span class=\"tag '+e(l)+(null!==m?'\" title=\"'+m:\"\")+'\">'+e(k)+'<span data-role=\"remove\"></span></span>');p.data(\"item\",b),f.findInputWrapper().before(p),p.after(\" \");var q=a('option[value=\"'+encodeURIComponent(j)+'\"]',f.$element).length||a('option[value=\"'+e(j)+'\"]',f.$element).length;if(f.isSelect&&!q){var r=a(\"<option selected>\"+e(k)+\"</option>\");r.data(\"item\",b),r.attr(\"value\",j),f.$element.append(r)}c||f.pushVal(),(f.options.maxTags===f.itemsArray.length||f.items().toString().length===f.options.maxInputLength)&&f.$container.addClass(\"bootstrap-tagsinput-max\"),a(\".typeahead, .twitter-typeahead\",f.$container).length&&f.$input.typeahead(\"val\",\"\"),this.isInit?f.$element.trigger(a.Event(\"itemAddedOnInit\",{item:b,options:d})):f.$element.trigger(a.Event(\"itemAdded\",{item:b,options:d}))}}}else if(f.options.onTagExists){var s=a(\".tag\",f.$container).filter(function(){return a(this).data(\"item\")===n});f.options.onTagExists(b,s)}}}},remove:function(b,c,d){var e=this;if(e.objectItems&&(b=\"object\"==typeof b?a.grep(e.itemsArray,function(a){return e.options.itemValue(a)==e.options.itemValue(b)}):a.grep(e.itemsArray,function(a){return e.options.itemValue(a)==b}),b=b[b.length-1]),b){var f=a.Event(\"beforeItemRemove\",{item:b,cancel:!1,options:d});if(e.$element.trigger(f),f.cancel)return;a(\".tag\",e.$container).filter(function(){return a(this).data(\"item\")===b}).remove(),a(\"option\",e.$element).filter(function(){return a(this).data(\"item\")===b}).remove(),-1!==a.inArray(b,e.itemsArray)&&e.itemsArray.splice(a.inArray(b,e.itemsArray),1)}c||e.pushVal(),e.options.maxTags>e.itemsArray.length&&e.$container.removeClass(\"bootstrap-tagsinput-max\"),e.$element.trigger(a.Event(\"itemRemoved\",{item:b,options:d}))},removeAll:function(){var b=this;for(a(\".tag\",b.$container).remove(),a(\"option\",b.$element).remove();b.itemsArray.length>0;)b.itemsArray.pop();b.pushVal()},refresh:function(){var b=this;a(\".tag\",b.$container).each(function(){var c=a(this),d=c.data(\"item\"),f=b.options.itemValue(d),g=b.options.itemText(d),h=b.options.tagClass(d);if(c.attr(\"class\",null),c.addClass(\"tag \"+e(h)),c.contents().filter(function(){return 3==this.nodeType})[0].nodeValue=e(g),b.isSelect){var i=a(\"option\",b.$element).filter(function(){return a(this).data(\"item\")===d});i.attr(\"value\",f)}})},items:function(){return this.itemsArray},pushVal:function(){var b=this,c=a.map(b.items(),function(a){return b.options.itemValue(a).toString()});b.$element.val(c,!0).trigger(\"change\")},build:function(b){var e=this;if(e.options=a.extend({},h,b),e.objectItems&&(e.options.freeInput=!1),c(e.options,\"itemValue\"),c(e.options,\"itemText\"),d(e.options,\"tagClass\"),e.options.typeahead){var i=e.options.typeahead||{};d(i,\"source\"),e.$input.typeahead(a.extend({},i,{source:function(b,c){function d(a){for(var b=[],d=0;d<a.length;d++){var g=e.options.itemText(a[d]);f[g]=a[d],b.push(g)}c(b)}this.map={};var f=this.map,g=i.source(b);a.isFunction(g.success)?g.success(d):a.isFunction(g.then)?g.then(d):a.when(g).then(d)},updater:function(a){return e.add(this.map[a]),this.map[a]},matcher:function(a){return-1!==a.toLowerCase().indexOf(this.query.trim().toLowerCase())},sorter:function(a){return a.sort()},highlighter:function(a){var b=new RegExp(\"(\"+this.query+\")\",\"gi\");return a.replace(b,\"<strong>$1</strong>\")}}))}if(e.options.typeaheadjs){var j=null,k={},l=e.options.typeaheadjs;a.isArray(l)?(j=l[0],k=l[1]):k=l,e.$input.typeahead(j,k).on(\"typeahead:selected\",a.proxy(function(a,b){k.valueKey?e.add(b[k.valueKey]):e.add(b),e.$input.typeahead(\"val\",\"\")},e))}e.$container.on(\"click\",a.proxy(function(a){e.$element.attr(\"disabled\")||e.$input.removeAttr(\"disabled\"),e.$input.focus()},e)),e.options.addOnBlur&&e.options.freeInput&&e.$input.on(\"focusout\",a.proxy(function(b){0===a(\".typeahead, .twitter-typeahead\",e.$container).length&&(e.add(e.$input.val()),e.$input.val(\"\"))},e)),e.$container.on(\"keydown\",\"input\",a.proxy(function(b){var c=a(b.target),d=e.findInputWrapper();if(e.$element.attr(\"disabled\"))return void e.$input.attr(\"disabled\",\"disabled\");switch(b.which){case 8:if(0===f(c[0])){var g=d.prev();g.length&&e.remove(g.data(\"item\"))}break;case 46:if(0===f(c[0])){var h=d.next();h.length&&e.remove(h.data(\"item\"))}break;case 37:var i=d.prev();0===c.val().length&&i[0]&&(i.before(d),c.focus());break;case 39:var j=d.next();0===c.val().length&&j[0]&&(j.after(d),c.focus())}var k=c.val().length;Math.ceil(k/5);c.attr(\"size\",Math.max(this.inputSize,c.val().length))},e)),e.$container.on(\"keypress\",\"input\",a.proxy(function(b){var c=a(b.target);if(e.$element.attr(\"disabled\"))return void e.$input.attr(\"disabled\",\"disabled\");var d=c.val(),f=e.options.maxChars&&d.length>=e.options.maxChars;e.options.freeInput&&(g(b,e.options.confirmKeys)||f)&&(0!==d.length&&(e.add(f?d.substr(0,e.options.maxChars):d),c.val(\"\")),e.options.cancelConfirmKeysOnEmpty===!1&&b.preventDefault());var h=c.val().length;Math.ceil(h/5);c.attr(\"size\",Math.max(this.inputSize,c.val().length))},e)),e.$container.on(\"click\",\"[data-role=remove]\",a.proxy(function(b){e.$element.attr(\"disabled\")||e.remove(a(b.target).closest(\".tag\").data(\"item\"))},e)),e.options.itemValue===h.itemValue&&(\"INPUT\"===e.$element[0].tagName?e.add(e.$element.val()):a(\"option\",e.$element).each(function(){e.add(a(this).attr(\"value\"),!0)}))},destroy:function(){var a=this;a.$container.off(\"keypress\",\"input\"),a.$container.off(\"click\",\"[role=remove]\"),a.$container.remove(),a.$element.removeData(\"tagsinput\"),a.$element.show()},focus:function(){this.$input.focus()},input:function(){return this.$input},findInputWrapper:function(){for(var b=this.$input[0],c=this.$container[0];b&&b.parentNode!==c;)b=b.parentNode;return a(b)}},a.fn.tagsinput=function(c,d,e){var f=[];return this.each(function(){var g=a(this).data(\"tagsinput\");if(g)if(c||d){if(void 0!==g[c]){if(3===g[c].length&&void 0!==e)var h=g[c](d,null,e);else var h=g[c](d);void 0!==h&&f.push(h)}}else f.push(g);else g=new b(this,c),a(this).data(\"tagsinput\",g),f.push(g),\"SELECT\"===this.tagName&&a(\"option\",a(this)).attr(\"selected\",\"selected\"),a(this).val(a(this).val())}),\"string\"==typeof c?f.length>1?f:f[0]:f},a.fn.tagsinput.Constructor=b;var i=a(\"<div />\");a(function(){a(\"input[data-role=tagsinput], select[multiple][data-role=tagsinput]\").tagsinput()})}(window.jQuery);\n//# sourceMappingURL=bootstrap-tagsinput.min.js.map//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvYm9vdHN0cmFwLXRhZ3NpbnB1dC9kaXN0L2Jvb3RzdHJhcC10YWdzaW5wdXQubWluLmpzIiwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGFBQWEsYUFBYSxnQkFBZ0IsMmpCQUEyakIsZ0JBQWdCLDRCQUE0QixXQUFXLGlCQUFpQixjQUFjLGdCQUFnQiw0QkFBNEIsV0FBVyxnQkFBZ0IsV0FBVyxjQUFjLDZCQUE2QixjQUFjLFFBQVEsdUJBQXVCLFVBQVUsdUNBQXVDLHlEQUF5RCxvRUFBb0UsU0FBUyxnQkFBZ0IsU0FBUyw4QkFBOEIsa0RBQWtELHNCQUFzQixzS0FBc0ssMkJBQTJCLElBQUksT0FBTyxxQkFBcUIseUJBQXlCLHVCQUF1Qix3QkFBd0Isc0JBQXNCLHlCQUF5Qix1QkFBdUIsWUFBWSxzS0FBc0ssa0JBQWtCLGtDQUFrQyxhQUFhLGtDQUFrQyxXQUFXLDhFQUE4RSx1SkFBdUosaUNBQWlDLHFJQUFxSSx5RkFBeUYsZUFBZSxZQUFZLFdBQVcsc0JBQXNCLDZCQUE2Qix3SUFBd0ksa0NBQWtDLEtBQUssa0NBQWtDLHVFQUF1RSwrQkFBK0IsMkJBQTJCLEVBQUUsb0NBQW9DLHFCQUFxQixrSEFBa0gsNkRBQTZELHdIQUF3SCxtQkFBbUIsOENBQThDLHdEQUF3RCxtVEFBbVQsaUJBQWlCLDJDQUEyQyxpQkFBaUIsS0FBSywrQkFBK0IsK0NBQStDLGdDQUFnQyxFQUFFLDhCQUE4Qix3QkFBd0IsV0FBVyx3RUFBd0Usc0RBQXNELGtDQUFrQyxpQ0FBaUMsc0JBQXNCLGtDQUFrQywyQkFBMkIsRUFBRSx5Q0FBeUMseUNBQXlDLGdDQUFnQyxvREFBb0QsZ0NBQWdDLDRGQUE0RixvSkFBb0osaUJBQWlCLEdBQUcsc0JBQXNCLFdBQVcsb0VBQW9FLHNCQUFzQixvQkFBb0IsWUFBWSxvQkFBb0IsV0FBVyx1Q0FBdUMsd0dBQXdHLCtFQUErRSx3QkFBd0IsZ0NBQWdDLCtDQUErQyxnQ0FBZ0MsRUFBRSxtQkFBbUIsRUFBRSxrQkFBa0IsdUJBQXVCLG9CQUFvQix5Q0FBeUMseUNBQXlDLEVBQUUsdUNBQXVDLG1CQUFtQixXQUFXLHdCQUF3Qiw0SUFBNEksOEJBQThCLDRDQUE0QyxJQUFJLHFCQUFxQixjQUFjLGlCQUFpQixXQUFXLEtBQUssK0JBQStCLG9CQUFvQixLQUFLLFlBQVksNkJBQTZCLHNGQUFzRixxQkFBcUIsc0NBQXNDLHFCQUFxQixvRUFBb0Usb0JBQW9CLGdCQUFnQix5QkFBeUIsMENBQTBDLDJDQUEyQyxHQUFHLDBCQUEwQixlQUFlLHlCQUF5Qix1R0FBdUcsc0VBQXNFLEtBQUssNENBQTRDLDhFQUE4RSwwRkFBMEYsc0dBQXNHLDJEQUEyRCx5Q0FBeUMsZ0ZBQWdGLGdCQUFnQix1QkFBdUIsZUFBZSxtQ0FBbUMsTUFBTSx3QkFBd0IsZUFBZSxtQ0FBbUMsTUFBTSx1QkFBdUIsa0RBQWtELE1BQU0sdUJBQXVCLGlEQUFpRCxxQkFBcUIsZUFBZSx1REFBdUQsNERBQTRELGtCQUFrQixnRkFBZ0YsaUVBQWlFLHdMQUF3TCxxQkFBcUIsZUFBZSx1REFBdUQsc0VBQXNFLGdGQUFnRix3SUFBd0ksZ0NBQWdDLEdBQUcsb0JBQW9CLFdBQVcsMEpBQTBKLGtCQUFrQixvQkFBb0Isa0JBQWtCLG1CQUFtQiw2QkFBNkIsOENBQThDLG9CQUFvQixnQkFBZ0IsYUFBYSxnQ0FBZ0MsU0FBUyw0QkFBNEIsZ0NBQWdDLGNBQWMsa0JBQWtCLG9EQUFvRCxtQkFBbUIsdUJBQXVCLGVBQWUsK0pBQStKLHlDQUF5Qyw4QkFBOEIsbUJBQW1CLGFBQWEsbUZBQW1GLEVBQUU7QUFDLzBSIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL2Jvb3RzdHJhcC10YWdzaW5wdXQvZGlzdC9ib290c3RyYXAtdGFnc2lucHV0Lm1pbi5qcz83N2MxIl0sInNvdXJjZXNDb250ZW50IjpbIi8qXG4gKiBib290c3RyYXAtdGFnc2lucHV0IHYwLjcuMSBieSBUaW0gU2NobGVjaHRlclxuICogXG4gKi9cblxuIWZ1bmN0aW9uKGEpe1widXNlIHN0cmljdFwiO2Z1bmN0aW9uIGIoYixjKXt0aGlzLmlzSW5pdD0hMCx0aGlzLml0ZW1zQXJyYXk9W10sdGhpcy4kZWxlbWVudD1hKGIpLHRoaXMuJGVsZW1lbnQuaGlkZSgpLHRoaXMuaXNTZWxlY3Q9XCJTRUxFQ1RcIj09PWIudGFnTmFtZSx0aGlzLm11bHRpcGxlPXRoaXMuaXNTZWxlY3QmJmIuaGFzQXR0cmlidXRlKFwibXVsdGlwbGVcIiksdGhpcy5vYmplY3RJdGVtcz1jJiZjLml0ZW1WYWx1ZSx0aGlzLnBsYWNlaG9sZGVyVGV4dD1iLmhhc0F0dHJpYnV0ZShcInBsYWNlaG9sZGVyXCIpP3RoaXMuJGVsZW1lbnQuYXR0cihcInBsYWNlaG9sZGVyXCIpOlwiXCIsdGhpcy5pbnB1dFNpemU9TWF0aC5tYXgoMSx0aGlzLnBsYWNlaG9sZGVyVGV4dC5sZW5ndGgpLHRoaXMuJGNvbnRhaW5lcj1hKCc8ZGl2IGNsYXNzPVwiYm9vdHN0cmFwLXRhZ3NpbnB1dFwiPjwvZGl2PicpLHRoaXMuJGlucHV0PWEoJzxpbnB1dCB0eXBlPVwidGV4dFwiIHBsYWNlaG9sZGVyPVwiJyt0aGlzLnBsYWNlaG9sZGVyVGV4dCsnXCIvPicpLmFwcGVuZFRvKHRoaXMuJGNvbnRhaW5lciksdGhpcy4kZWxlbWVudC5iZWZvcmUodGhpcy4kY29udGFpbmVyKSx0aGlzLmJ1aWxkKGMpLHRoaXMuaXNJbml0PSExfWZ1bmN0aW9uIGMoYSxiKXtpZihcImZ1bmN0aW9uXCIhPXR5cGVvZiBhW2JdKXt2YXIgYz1hW2JdO2FbYl09ZnVuY3Rpb24oYSl7cmV0dXJuIGFbY119fX1mdW5jdGlvbiBkKGEsYil7aWYoXCJmdW5jdGlvblwiIT10eXBlb2YgYVtiXSl7dmFyIGM9YVtiXTthW2JdPWZ1bmN0aW9uKCl7cmV0dXJuIGN9fX1mdW5jdGlvbiBlKGEpe3JldHVybiBhP2kudGV4dChhKS5odG1sKCk6XCJcIn1mdW5jdGlvbiBmKGEpe3ZhciBiPTA7aWYoZG9jdW1lbnQuc2VsZWN0aW9uKXthLmZvY3VzKCk7dmFyIGM9ZG9jdW1lbnQuc2VsZWN0aW9uLmNyZWF0ZVJhbmdlKCk7Yy5tb3ZlU3RhcnQoXCJjaGFyYWN0ZXJcIiwtYS52YWx1ZS5sZW5ndGgpLGI9Yy50ZXh0Lmxlbmd0aH1lbHNlKGEuc2VsZWN0aW9uU3RhcnR8fFwiMFwiPT1hLnNlbGVjdGlvblN0YXJ0KSYmKGI9YS5zZWxlY3Rpb25TdGFydCk7cmV0dXJuIGJ9ZnVuY3Rpb24gZyhiLGMpe3ZhciBkPSExO3JldHVybiBhLmVhY2goYyxmdW5jdGlvbihhLGMpe2lmKFwibnVtYmVyXCI9PXR5cGVvZiBjJiZiLndoaWNoPT09YylyZXR1cm4gZD0hMCwhMTtpZihiLndoaWNoPT09Yy53aGljaCl7dmFyIGU9IWMuaGFzT3duUHJvcGVydHkoXCJhbHRLZXlcIil8fGIuYWx0S2V5PT09Yy5hbHRLZXksZj0hYy5oYXNPd25Qcm9wZXJ0eShcInNoaWZ0S2V5XCIpfHxiLnNoaWZ0S2V5PT09Yy5zaGlmdEtleSxnPSFjLmhhc093blByb3BlcnR5KFwiY3RybEtleVwiKXx8Yi5jdHJsS2V5PT09Yy5jdHJsS2V5O2lmKGUmJmYmJmcpcmV0dXJuIGQ9ITAsITF9fSksZH12YXIgaD17dGFnQ2xhc3M6ZnVuY3Rpb24oYSl7cmV0dXJuXCJsYWJlbCBsYWJlbC1pbmZvXCJ9LGl0ZW1WYWx1ZTpmdW5jdGlvbihhKXtyZXR1cm4gYT9hLnRvU3RyaW5nKCk6YX0saXRlbVRleHQ6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuaXRlbVZhbHVlKGEpfSxpdGVtVGl0bGU6ZnVuY3Rpb24oYSl7cmV0dXJuIG51bGx9LGZyZWVJbnB1dDohMCxhZGRPbkJsdXI6ITAsbWF4VGFnczp2b2lkIDAsbWF4Q2hhcnM6dm9pZCAwLGNvbmZpcm1LZXlzOlsxMyw0NF0sZGVsaW1pdGVyOlwiLFwiLGRlbGltaXRlclJlZ2V4Om51bGwsY2FuY2VsQ29uZmlybUtleXNPbkVtcHR5OiExLG9uVGFnRXhpc3RzOmZ1bmN0aW9uKGEsYil7Yi5oaWRlKCkuZmFkZUluKCl9LHRyaW1WYWx1ZTohMSxhbGxvd0R1cGxpY2F0ZXM6ITF9O2IucHJvdG90eXBlPXtjb25zdHJ1Y3RvcjpiLGFkZDpmdW5jdGlvbihiLGMsZCl7dmFyIGY9dGhpcztpZighKGYub3B0aW9ucy5tYXhUYWdzJiZmLml0ZW1zQXJyYXkubGVuZ3RoPj1mLm9wdGlvbnMubWF4VGFncykmJihiPT09ITF8fGIpKXtpZihcInN0cmluZ1wiPT10eXBlb2YgYiYmZi5vcHRpb25zLnRyaW1WYWx1ZSYmKGI9YS50cmltKGIpKSxcIm9iamVjdFwiPT10eXBlb2YgYiYmIWYub2JqZWN0SXRlbXMpdGhyb3dcIkNhbid0IGFkZCBvYmplY3RzIHdoZW4gaXRlbVZhbHVlIG9wdGlvbiBpcyBub3Qgc2V0XCI7aWYoIWIudG9TdHJpbmcoKS5tYXRjaCgvXlxccyokLykpe2lmKGYuaXNTZWxlY3QmJiFmLm11bHRpcGxlJiZmLml0ZW1zQXJyYXkubGVuZ3RoPjAmJmYucmVtb3ZlKGYuaXRlbXNBcnJheVswXSksXCJzdHJpbmdcIj09dHlwZW9mIGImJlwiSU5QVVRcIj09PXRoaXMuJGVsZW1lbnRbMF0udGFnTmFtZSl7dmFyIGc9Zi5vcHRpb25zLmRlbGltaXRlclJlZ2V4P2Yub3B0aW9ucy5kZWxpbWl0ZXJSZWdleDpmLm9wdGlvbnMuZGVsaW1pdGVyLGg9Yi5zcGxpdChnKTtpZihoLmxlbmd0aD4xKXtmb3IodmFyIGk9MDtpPGgubGVuZ3RoO2krKyl0aGlzLmFkZChoW2ldLCEwKTtyZXR1cm4gdm9pZChjfHxmLnB1c2hWYWwoKSl9fXZhciBqPWYub3B0aW9ucy5pdGVtVmFsdWUoYiksaz1mLm9wdGlvbnMuaXRlbVRleHQoYiksbD1mLm9wdGlvbnMudGFnQ2xhc3MoYiksbT1mLm9wdGlvbnMuaXRlbVRpdGxlKGIpLG49YS5ncmVwKGYuaXRlbXNBcnJheSxmdW5jdGlvbihhKXtyZXR1cm4gZi5vcHRpb25zLml0ZW1WYWx1ZShhKT09PWp9KVswXTtpZighbnx8Zi5vcHRpb25zLmFsbG93RHVwbGljYXRlcyl7aWYoIShmLml0ZW1zKCkudG9TdHJpbmcoKS5sZW5ndGgrYi5sZW5ndGgrMT5mLm9wdGlvbnMubWF4SW5wdXRMZW5ndGgpKXt2YXIgbz1hLkV2ZW50KFwiYmVmb3JlSXRlbUFkZFwiLHtpdGVtOmIsY2FuY2VsOiExLG9wdGlvbnM6ZH0pO2lmKGYuJGVsZW1lbnQudHJpZ2dlcihvKSwhby5jYW5jZWwpe2YuaXRlbXNBcnJheS5wdXNoKGIpO3ZhciBwPWEoJzxzcGFuIGNsYXNzPVwidGFnICcrZShsKSsobnVsbCE9PW0/J1wiIHRpdGxlPVwiJyttOlwiXCIpKydcIj4nK2UoaykrJzxzcGFuIGRhdGEtcm9sZT1cInJlbW92ZVwiPjwvc3Bhbj48L3NwYW4+Jyk7cC5kYXRhKFwiaXRlbVwiLGIpLGYuZmluZElucHV0V3JhcHBlcigpLmJlZm9yZShwKSxwLmFmdGVyKFwiIFwiKTt2YXIgcT1hKCdvcHRpb25bdmFsdWU9XCInK2VuY29kZVVSSUNvbXBvbmVudChqKSsnXCJdJyxmLiRlbGVtZW50KS5sZW5ndGh8fGEoJ29wdGlvblt2YWx1ZT1cIicrZShqKSsnXCJdJyxmLiRlbGVtZW50KS5sZW5ndGg7aWYoZi5pc1NlbGVjdCYmIXEpe3ZhciByPWEoXCI8b3B0aW9uIHNlbGVjdGVkPlwiK2UoaykrXCI8L29wdGlvbj5cIik7ci5kYXRhKFwiaXRlbVwiLGIpLHIuYXR0cihcInZhbHVlXCIsaiksZi4kZWxlbWVudC5hcHBlbmQocil9Y3x8Zi5wdXNoVmFsKCksKGYub3B0aW9ucy5tYXhUYWdzPT09Zi5pdGVtc0FycmF5Lmxlbmd0aHx8Zi5pdGVtcygpLnRvU3RyaW5nKCkubGVuZ3RoPT09Zi5vcHRpb25zLm1heElucHV0TGVuZ3RoKSYmZi4kY29udGFpbmVyLmFkZENsYXNzKFwiYm9vdHN0cmFwLXRhZ3NpbnB1dC1tYXhcIiksYShcIi50eXBlYWhlYWQsIC50d2l0dGVyLXR5cGVhaGVhZFwiLGYuJGNvbnRhaW5lcikubGVuZ3RoJiZmLiRpbnB1dC50eXBlYWhlYWQoXCJ2YWxcIixcIlwiKSx0aGlzLmlzSW5pdD9mLiRlbGVtZW50LnRyaWdnZXIoYS5FdmVudChcIml0ZW1BZGRlZE9uSW5pdFwiLHtpdGVtOmIsb3B0aW9uczpkfSkpOmYuJGVsZW1lbnQudHJpZ2dlcihhLkV2ZW50KFwiaXRlbUFkZGVkXCIse2l0ZW06YixvcHRpb25zOmR9KSl9fX1lbHNlIGlmKGYub3B0aW9ucy5vblRhZ0V4aXN0cyl7dmFyIHM9YShcIi50YWdcIixmLiRjb250YWluZXIpLmZpbHRlcihmdW5jdGlvbigpe3JldHVybiBhKHRoaXMpLmRhdGEoXCJpdGVtXCIpPT09bn0pO2Yub3B0aW9ucy5vblRhZ0V4aXN0cyhiLHMpfX19fSxyZW1vdmU6ZnVuY3Rpb24oYixjLGQpe3ZhciBlPXRoaXM7aWYoZS5vYmplY3RJdGVtcyYmKGI9XCJvYmplY3RcIj09dHlwZW9mIGI/YS5ncmVwKGUuaXRlbXNBcnJheSxmdW5jdGlvbihhKXtyZXR1cm4gZS5vcHRpb25zLml0ZW1WYWx1ZShhKT09ZS5vcHRpb25zLml0ZW1WYWx1ZShiKX0pOmEuZ3JlcChlLml0ZW1zQXJyYXksZnVuY3Rpb24oYSl7cmV0dXJuIGUub3B0aW9ucy5pdGVtVmFsdWUoYSk9PWJ9KSxiPWJbYi5sZW5ndGgtMV0pLGIpe3ZhciBmPWEuRXZlbnQoXCJiZWZvcmVJdGVtUmVtb3ZlXCIse2l0ZW06YixjYW5jZWw6ITEsb3B0aW9uczpkfSk7aWYoZS4kZWxlbWVudC50cmlnZ2VyKGYpLGYuY2FuY2VsKXJldHVybjthKFwiLnRhZ1wiLGUuJGNvbnRhaW5lcikuZmlsdGVyKGZ1bmN0aW9uKCl7cmV0dXJuIGEodGhpcykuZGF0YShcIml0ZW1cIik9PT1ifSkucmVtb3ZlKCksYShcIm9wdGlvblwiLGUuJGVsZW1lbnQpLmZpbHRlcihmdW5jdGlvbigpe3JldHVybiBhKHRoaXMpLmRhdGEoXCJpdGVtXCIpPT09Yn0pLnJlbW92ZSgpLC0xIT09YS5pbkFycmF5KGIsZS5pdGVtc0FycmF5KSYmZS5pdGVtc0FycmF5LnNwbGljZShhLmluQXJyYXkoYixlLml0ZW1zQXJyYXkpLDEpfWN8fGUucHVzaFZhbCgpLGUub3B0aW9ucy5tYXhUYWdzPmUuaXRlbXNBcnJheS5sZW5ndGgmJmUuJGNvbnRhaW5lci5yZW1vdmVDbGFzcyhcImJvb3RzdHJhcC10YWdzaW5wdXQtbWF4XCIpLGUuJGVsZW1lbnQudHJpZ2dlcihhLkV2ZW50KFwiaXRlbVJlbW92ZWRcIix7aXRlbTpiLG9wdGlvbnM6ZH0pKX0scmVtb3ZlQWxsOmZ1bmN0aW9uKCl7dmFyIGI9dGhpcztmb3IoYShcIi50YWdcIixiLiRjb250YWluZXIpLnJlbW92ZSgpLGEoXCJvcHRpb25cIixiLiRlbGVtZW50KS5yZW1vdmUoKTtiLml0ZW1zQXJyYXkubGVuZ3RoPjA7KWIuaXRlbXNBcnJheS5wb3AoKTtiLnB1c2hWYWwoKX0scmVmcmVzaDpmdW5jdGlvbigpe3ZhciBiPXRoaXM7YShcIi50YWdcIixiLiRjb250YWluZXIpLmVhY2goZnVuY3Rpb24oKXt2YXIgYz1hKHRoaXMpLGQ9Yy5kYXRhKFwiaXRlbVwiKSxmPWIub3B0aW9ucy5pdGVtVmFsdWUoZCksZz1iLm9wdGlvbnMuaXRlbVRleHQoZCksaD1iLm9wdGlvbnMudGFnQ2xhc3MoZCk7aWYoYy5hdHRyKFwiY2xhc3NcIixudWxsKSxjLmFkZENsYXNzKFwidGFnIFwiK2UoaCkpLGMuY29udGVudHMoKS5maWx0ZXIoZnVuY3Rpb24oKXtyZXR1cm4gMz09dGhpcy5ub2RlVHlwZX0pWzBdLm5vZGVWYWx1ZT1lKGcpLGIuaXNTZWxlY3Qpe3ZhciBpPWEoXCJvcHRpb25cIixiLiRlbGVtZW50KS5maWx0ZXIoZnVuY3Rpb24oKXtyZXR1cm4gYSh0aGlzKS5kYXRhKFwiaXRlbVwiKT09PWR9KTtpLmF0dHIoXCJ2YWx1ZVwiLGYpfX0pfSxpdGVtczpmdW5jdGlvbigpe3JldHVybiB0aGlzLml0ZW1zQXJyYXl9LHB1c2hWYWw6ZnVuY3Rpb24oKXt2YXIgYj10aGlzLGM9YS5tYXAoYi5pdGVtcygpLGZ1bmN0aW9uKGEpe3JldHVybiBiLm9wdGlvbnMuaXRlbVZhbHVlKGEpLnRvU3RyaW5nKCl9KTtiLiRlbGVtZW50LnZhbChjLCEwKS50cmlnZ2VyKFwiY2hhbmdlXCIpfSxidWlsZDpmdW5jdGlvbihiKXt2YXIgZT10aGlzO2lmKGUub3B0aW9ucz1hLmV4dGVuZCh7fSxoLGIpLGUub2JqZWN0SXRlbXMmJihlLm9wdGlvbnMuZnJlZUlucHV0PSExKSxjKGUub3B0aW9ucyxcIml0ZW1WYWx1ZVwiKSxjKGUub3B0aW9ucyxcIml0ZW1UZXh0XCIpLGQoZS5vcHRpb25zLFwidGFnQ2xhc3NcIiksZS5vcHRpb25zLnR5cGVhaGVhZCl7dmFyIGk9ZS5vcHRpb25zLnR5cGVhaGVhZHx8e307ZChpLFwic291cmNlXCIpLGUuJGlucHV0LnR5cGVhaGVhZChhLmV4dGVuZCh7fSxpLHtzb3VyY2U6ZnVuY3Rpb24oYixjKXtmdW5jdGlvbiBkKGEpe2Zvcih2YXIgYj1bXSxkPTA7ZDxhLmxlbmd0aDtkKyspe3ZhciBnPWUub3B0aW9ucy5pdGVtVGV4dChhW2RdKTtmW2ddPWFbZF0sYi5wdXNoKGcpfWMoYil9dGhpcy5tYXA9e307dmFyIGY9dGhpcy5tYXAsZz1pLnNvdXJjZShiKTthLmlzRnVuY3Rpb24oZy5zdWNjZXNzKT9nLnN1Y2Nlc3MoZCk6YS5pc0Z1bmN0aW9uKGcudGhlbik/Zy50aGVuKGQpOmEud2hlbihnKS50aGVuKGQpfSx1cGRhdGVyOmZ1bmN0aW9uKGEpe3JldHVybiBlLmFkZCh0aGlzLm1hcFthXSksdGhpcy5tYXBbYV19LG1hdGNoZXI6ZnVuY3Rpb24oYSl7cmV0dXJuLTEhPT1hLnRvTG93ZXJDYXNlKCkuaW5kZXhPZih0aGlzLnF1ZXJ5LnRyaW0oKS50b0xvd2VyQ2FzZSgpKX0sc29ydGVyOmZ1bmN0aW9uKGEpe3JldHVybiBhLnNvcnQoKX0saGlnaGxpZ2h0ZXI6ZnVuY3Rpb24oYSl7dmFyIGI9bmV3IFJlZ0V4cChcIihcIit0aGlzLnF1ZXJ5K1wiKVwiLFwiZ2lcIik7cmV0dXJuIGEucmVwbGFjZShiLFwiPHN0cm9uZz4kMTwvc3Ryb25nPlwiKX19KSl9aWYoZS5vcHRpb25zLnR5cGVhaGVhZGpzKXt2YXIgaj1udWxsLGs9e30sbD1lLm9wdGlvbnMudHlwZWFoZWFkanM7YS5pc0FycmF5KGwpPyhqPWxbMF0saz1sWzFdKTprPWwsZS4kaW5wdXQudHlwZWFoZWFkKGosaykub24oXCJ0eXBlYWhlYWQ6c2VsZWN0ZWRcIixhLnByb3h5KGZ1bmN0aW9uKGEsYil7ay52YWx1ZUtleT9lLmFkZChiW2sudmFsdWVLZXldKTplLmFkZChiKSxlLiRpbnB1dC50eXBlYWhlYWQoXCJ2YWxcIixcIlwiKX0sZSkpfWUuJGNvbnRhaW5lci5vbihcImNsaWNrXCIsYS5wcm94eShmdW5jdGlvbihhKXtlLiRlbGVtZW50LmF0dHIoXCJkaXNhYmxlZFwiKXx8ZS4kaW5wdXQucmVtb3ZlQXR0cihcImRpc2FibGVkXCIpLGUuJGlucHV0LmZvY3VzKCl9LGUpKSxlLm9wdGlvbnMuYWRkT25CbHVyJiZlLm9wdGlvbnMuZnJlZUlucHV0JiZlLiRpbnB1dC5vbihcImZvY3Vzb3V0XCIsYS5wcm94eShmdW5jdGlvbihiKXswPT09YShcIi50eXBlYWhlYWQsIC50d2l0dGVyLXR5cGVhaGVhZFwiLGUuJGNvbnRhaW5lcikubGVuZ3RoJiYoZS5hZGQoZS4kaW5wdXQudmFsKCkpLGUuJGlucHV0LnZhbChcIlwiKSl9LGUpKSxlLiRjb250YWluZXIub24oXCJrZXlkb3duXCIsXCJpbnB1dFwiLGEucHJveHkoZnVuY3Rpb24oYil7dmFyIGM9YShiLnRhcmdldCksZD1lLmZpbmRJbnB1dFdyYXBwZXIoKTtpZihlLiRlbGVtZW50LmF0dHIoXCJkaXNhYmxlZFwiKSlyZXR1cm4gdm9pZCBlLiRpbnB1dC5hdHRyKFwiZGlzYWJsZWRcIixcImRpc2FibGVkXCIpO3N3aXRjaChiLndoaWNoKXtjYXNlIDg6aWYoMD09PWYoY1swXSkpe3ZhciBnPWQucHJldigpO2cubGVuZ3RoJiZlLnJlbW92ZShnLmRhdGEoXCJpdGVtXCIpKX1icmVhaztjYXNlIDQ2OmlmKDA9PT1mKGNbMF0pKXt2YXIgaD1kLm5leHQoKTtoLmxlbmd0aCYmZS5yZW1vdmUoaC5kYXRhKFwiaXRlbVwiKSl9YnJlYWs7Y2FzZSAzNzp2YXIgaT1kLnByZXYoKTswPT09Yy52YWwoKS5sZW5ndGgmJmlbMF0mJihpLmJlZm9yZShkKSxjLmZvY3VzKCkpO2JyZWFrO2Nhc2UgMzk6dmFyIGo9ZC5uZXh0KCk7MD09PWMudmFsKCkubGVuZ3RoJiZqWzBdJiYoai5hZnRlcihkKSxjLmZvY3VzKCkpfXZhciBrPWMudmFsKCkubGVuZ3RoO01hdGguY2VpbChrLzUpO2MuYXR0cihcInNpemVcIixNYXRoLm1heCh0aGlzLmlucHV0U2l6ZSxjLnZhbCgpLmxlbmd0aCkpfSxlKSksZS4kY29udGFpbmVyLm9uKFwia2V5cHJlc3NcIixcImlucHV0XCIsYS5wcm94eShmdW5jdGlvbihiKXt2YXIgYz1hKGIudGFyZ2V0KTtpZihlLiRlbGVtZW50LmF0dHIoXCJkaXNhYmxlZFwiKSlyZXR1cm4gdm9pZCBlLiRpbnB1dC5hdHRyKFwiZGlzYWJsZWRcIixcImRpc2FibGVkXCIpO3ZhciBkPWMudmFsKCksZj1lLm9wdGlvbnMubWF4Q2hhcnMmJmQubGVuZ3RoPj1lLm9wdGlvbnMubWF4Q2hhcnM7ZS5vcHRpb25zLmZyZWVJbnB1dCYmKGcoYixlLm9wdGlvbnMuY29uZmlybUtleXMpfHxmKSYmKDAhPT1kLmxlbmd0aCYmKGUuYWRkKGY/ZC5zdWJzdHIoMCxlLm9wdGlvbnMubWF4Q2hhcnMpOmQpLGMudmFsKFwiXCIpKSxlLm9wdGlvbnMuY2FuY2VsQ29uZmlybUtleXNPbkVtcHR5PT09ITEmJmIucHJldmVudERlZmF1bHQoKSk7dmFyIGg9Yy52YWwoKS5sZW5ndGg7TWF0aC5jZWlsKGgvNSk7Yy5hdHRyKFwic2l6ZVwiLE1hdGgubWF4KHRoaXMuaW5wdXRTaXplLGMudmFsKCkubGVuZ3RoKSl9LGUpKSxlLiRjb250YWluZXIub24oXCJjbGlja1wiLFwiW2RhdGEtcm9sZT1yZW1vdmVdXCIsYS5wcm94eShmdW5jdGlvbihiKXtlLiRlbGVtZW50LmF0dHIoXCJkaXNhYmxlZFwiKXx8ZS5yZW1vdmUoYShiLnRhcmdldCkuY2xvc2VzdChcIi50YWdcIikuZGF0YShcIml0ZW1cIikpfSxlKSksZS5vcHRpb25zLml0ZW1WYWx1ZT09PWguaXRlbVZhbHVlJiYoXCJJTlBVVFwiPT09ZS4kZWxlbWVudFswXS50YWdOYW1lP2UuYWRkKGUuJGVsZW1lbnQudmFsKCkpOmEoXCJvcHRpb25cIixlLiRlbGVtZW50KS5lYWNoKGZ1bmN0aW9uKCl7ZS5hZGQoYSh0aGlzKS5hdHRyKFwidmFsdWVcIiksITApfSkpfSxkZXN0cm95OmZ1bmN0aW9uKCl7dmFyIGE9dGhpczthLiRjb250YWluZXIub2ZmKFwia2V5cHJlc3NcIixcImlucHV0XCIpLGEuJGNvbnRhaW5lci5vZmYoXCJjbGlja1wiLFwiW3JvbGU9cmVtb3ZlXVwiKSxhLiRjb250YWluZXIucmVtb3ZlKCksYS4kZWxlbWVudC5yZW1vdmVEYXRhKFwidGFnc2lucHV0XCIpLGEuJGVsZW1lbnQuc2hvdygpfSxmb2N1czpmdW5jdGlvbigpe3RoaXMuJGlucHV0LmZvY3VzKCl9LGlucHV0OmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuJGlucHV0fSxmaW5kSW5wdXRXcmFwcGVyOmZ1bmN0aW9uKCl7Zm9yKHZhciBiPXRoaXMuJGlucHV0WzBdLGM9dGhpcy4kY29udGFpbmVyWzBdO2ImJmIucGFyZW50Tm9kZSE9PWM7KWI9Yi5wYXJlbnROb2RlO3JldHVybiBhKGIpfX0sYS5mbi50YWdzaW5wdXQ9ZnVuY3Rpb24oYyxkLGUpe3ZhciBmPVtdO3JldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKXt2YXIgZz1hKHRoaXMpLmRhdGEoXCJ0YWdzaW5wdXRcIik7aWYoZylpZihjfHxkKXtpZih2b2lkIDAhPT1nW2NdKXtpZigzPT09Z1tjXS5sZW5ndGgmJnZvaWQgMCE9PWUpdmFyIGg9Z1tjXShkLG51bGwsZSk7ZWxzZSB2YXIgaD1nW2NdKGQpO3ZvaWQgMCE9PWgmJmYucHVzaChoKX19ZWxzZSBmLnB1c2goZyk7ZWxzZSBnPW5ldyBiKHRoaXMsYyksYSh0aGlzKS5kYXRhKFwidGFnc2lucHV0XCIsZyksZi5wdXNoKGcpLFwiU0VMRUNUXCI9PT10aGlzLnRhZ05hbWUmJmEoXCJvcHRpb25cIixhKHRoaXMpKS5hdHRyKFwic2VsZWN0ZWRcIixcInNlbGVjdGVkXCIpLGEodGhpcykudmFsKGEodGhpcykudmFsKCkpfSksXCJzdHJpbmdcIj09dHlwZW9mIGM/Zi5sZW5ndGg+MT9mOmZbMF06Zn0sYS5mbi50YWdzaW5wdXQuQ29uc3RydWN0b3I9Yjt2YXIgaT1hKFwiPGRpdiAvPlwiKTthKGZ1bmN0aW9uKCl7YShcImlucHV0W2RhdGEtcm9sZT10YWdzaW5wdXRdLCBzZWxlY3RbbXVsdGlwbGVdW2RhdGEtcm9sZT10YWdzaW5wdXRdXCIpLnRhZ3NpbnB1dCgpfSl9KHdpbmRvdy5qUXVlcnkpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Ym9vdHN0cmFwLXRhZ3NpbnB1dC5taW4uanMubWFwIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/bootstrap-tagsinput/dist/bootstrap-tagsinput.min.js\n");
/***/ }),
/***/ "./node_modules/bootstrap/dist/js/bootstrap.esm.js":
/*!*********************************************************!*\
!*** ./node_modules/bootstrap/dist/js/bootstrap.esm.js ***!
\*********************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Alert: () => (/* binding */ Alert),\n/* harmony export */ Button: () => (/* binding */ Button),\n/* harmony export */ Carousel: () => (/* binding */ Carousel),\n/* harmony export */ Collapse: () => (/* binding */ Collapse),\n/* harmony export */ Dropdown: () => (/* binding */ Dropdown),\n/* harmony export */ Modal: () => (/* binding */ Modal),\n/* harmony export */ Offcanvas: () => (/* binding */ Offcanvas),\n/* harmony export */ Popover: () => (/* binding */ Popover),\n/* harmony export */ ScrollSpy: () => (/* binding */ ScrollSpy),\n/* harmony export */ Tab: () => (/* binding */ Tab),\n/* harmony export */ Toast: () => (/* binding */ Toast),\n/* harmony export */ Tooltip: () => (/* binding */ Tooltip)\n/* harmony export */ });\n/* harmony import */ var _popperjs_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @popperjs/core */ \"./node_modules/@popperjs/core/lib/index.js\");\n/* harmony import */ var _popperjs_core__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @popperjs/core */ \"./node_modules/@popperjs/core/lib/popper.js\");\n/*!\n * Bootstrap v5.3.0 (https://getbootstrap.com/)\n * Copyright 2011-2023 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n */\n\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap dom/data.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n/**\n * Constants\n */\n\nconst elementMap = new Map();\nconst Data = {\n set(element, key, instance) {\n if (!elementMap.has(element)) {\n elementMap.set(element, new Map());\n }\n const instanceMap = elementMap.get(element);\n\n // make it clear we only want one instance per element\n // can be removed later when multiple key/instances are fine to be used\n if (!instanceMap.has(key) && instanceMap.size !== 0) {\n // eslint-disable-next-line no-console\n console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(instanceMap.keys())[0]}.`);\n return;\n }\n instanceMap.set(key, instance);\n },\n get(element, key) {\n if (elementMap.has(element)) {\n return elementMap.get(element).get(key) || null;\n }\n return null;\n },\n remove(element, key) {\n if (!elementMap.has(element)) {\n return;\n }\n const instanceMap = elementMap.get(element);\n instanceMap.delete(key);\n\n // free up element references if there are no instances left for an element\n if (instanceMap.size === 0) {\n elementMap.delete(element);\n }\n }\n};\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap util/index.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst MAX_UID = 1000000;\nconst MILLISECONDS_MULTIPLIER = 1000;\nconst TRANSITION_END = 'transitionend';\n\n/**\n * Properly escape IDs selectors to handle weird IDs\n * @param {string} selector\n * @returns {string}\n */\nconst parseSelector = selector => {\n if (selector && window.CSS && window.CSS.escape) {\n // document.querySelector needs escaping to handle IDs (html5+) containing for instance /\n selector = selector.replace(/#([^\\s\"#']+)/g, (match, id) => `#${CSS.escape(id)}`);\n }\n return selector;\n};\n\n// Shout-out Angus Croll (https://goo.gl/pxwQGp)\nconst toType = object => {\n if (object === null || object === undefined) {\n return `${object}`;\n }\n return Object.prototype.toString.call(object).match(/\\s([a-z]+)/i)[1].toLowerCase();\n};\n\n/**\n * Public Util API\n */\n\nconst getUID = prefix => {\n do {\n prefix += Math.floor(Math.random() * MAX_UID);\n } while (document.getElementById(prefix));\n return prefix;\n};\nconst getTransitionDurationFromElement = element => {\n if (!element) {\n return 0;\n }\n\n // Get transition-duration of the element\n let {\n transitionDuration,\n transitionDelay\n } = window.getComputedStyle(element);\n const floatTransitionDuration = Number.parseFloat(transitionDuration);\n const floatTransitionDelay = Number.parseFloat(transitionDelay);\n\n // Return 0 if element or transition duration is not found\n if (!floatTransitionDuration && !floatTransitionDelay) {\n return 0;\n }\n\n // If multiple durations are defined, take the first\n transitionDuration = transitionDuration.split(',')[0];\n transitionDelay = transitionDelay.split(',')[0];\n return (Number.parseFloat(transitionDuration) + Number.parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER;\n};\nconst triggerTransitionEnd = element => {\n element.dispatchEvent(new Event(TRANSITION_END));\n};\nconst isElement = object => {\n if (!object || typeof object !== 'object') {\n return false;\n }\n if (typeof object.jquery !== 'undefined') {\n object = object[0];\n }\n return typeof object.nodeType !== 'undefined';\n};\nconst getElement = object => {\n // it's a jQuery object or a node element\n if (isElement(object)) {\n return object.jquery ? object[0] : object;\n }\n if (typeof object === 'string' && object.length > 0) {\n return document.querySelector(parseSelector(object));\n }\n return null;\n};\nconst isVisible = element => {\n if (!isElement(element) || element.getClientRects().length === 0) {\n return false;\n }\n const elementIsVisible = getComputedStyle(element).getPropertyValue('visibility') === 'visible';\n // Handle `details` element as its content may falsie appear visible when it is closed\n const closedDetails = element.closest('details:not([open])');\n if (!closedDetails) {\n return elementIsVisible;\n }\n if (closedDetails !== element) {\n const summary = element.closest('summary');\n if (summary && summary.parentNode !== closedDetails) {\n return false;\n }\n if (summary === null) {\n return false;\n }\n }\n return elementIsVisible;\n};\nconst isDisabled = element => {\n if (!element || element.nodeType !== Node.ELEMENT_NODE) {\n return true;\n }\n if (element.classList.contains('disabled')) {\n return true;\n }\n if (typeof element.disabled !== 'undefined') {\n return element.disabled;\n }\n return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false';\n};\nconst findShadowRoot = element => {\n if (!document.documentElement.attachShadow) {\n return null;\n }\n\n // Can find the shadow root otherwise it'll return the document\n if (typeof element.getRootNode === 'function') {\n const root = element.getRootNode();\n return root instanceof ShadowRoot ? root : null;\n }\n if (element instanceof ShadowRoot) {\n return element;\n }\n\n // when we don't find a shadow root\n if (!element.parentNode) {\n return null;\n }\n return findShadowRoot(element.parentNode);\n};\nconst noop = () => {};\n\n/**\n * Trick to restart an element's animation\n *\n * @param {HTMLElement} element\n * @return void\n *\n * @see https://www.charistheo.io/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation\n */\nconst reflow = element => {\n element.offsetHeight; // eslint-disable-line no-unused-expressions\n};\n\nconst getjQuery = () => {\n if (window.jQuery && !document.body.hasAttribute('data-bs-no-jquery')) {\n return window.jQuery;\n }\n return null;\n};\nconst DOMContentLoadedCallbacks = [];\nconst onDOMContentLoaded = callback => {\n if (document.readyState === 'loading') {\n // add listener on the first call when the document is in loading state\n if (!DOMContentLoadedCallbacks.length) {\n document.addEventListener('DOMContentLoaded', () => {\n for (const callback of DOMContentLoadedCallbacks) {\n callback();\n }\n });\n }\n DOMContentLoadedCallbacks.push(callback);\n } else {\n callback();\n }\n};\nconst isRTL = () => document.documentElement.dir === 'rtl';\nconst defineJQueryPlugin = plugin => {\n onDOMContentLoaded(() => {\n const $ = getjQuery();\n /* istanbul ignore if */\n if ($) {\n const name = plugin.NAME;\n const JQUERY_NO_CONFLICT = $.fn[name];\n $.fn[name] = plugin.jQueryInterface;\n $.fn[name].Constructor = plugin;\n $.fn[name].noConflict = () => {\n $.fn[name] = JQUERY_NO_CONFLICT;\n return plugin.jQueryInterface;\n };\n }\n });\n};\nconst execute = (possibleCallback, args = [], defaultValue = possibleCallback) => {\n return typeof possibleCallback === 'function' ? possibleCallback(...args) : defaultValue;\n};\nconst executeAfterTransition = (callback, transitionElement, waitForTransition = true) => {\n if (!waitForTransition) {\n execute(callback);\n return;\n }\n const durationPadding = 5;\n const emulatedDuration = getTransitionDurationFromElement(transitionElement) + durationPadding;\n let called = false;\n const handler = ({\n target\n }) => {\n if (target !== transitionElement) {\n return;\n }\n called = true;\n transitionElement.removeEventListener(TRANSITION_END, handler);\n execute(callback);\n };\n transitionElement.addEventListener(TRANSITION_END, handler);\n setTimeout(() => {\n if (!called) {\n triggerTransitionEnd(transitionElement);\n }\n }, emulatedDuration);\n};\n\n/**\n * Return the previous/next element of a list.\n *\n * @param {array} list The list of elements\n * @param activeElement The active element\n * @param shouldGetNext Choose to get next or previous element\n * @param isCycleAllowed\n * @return {Element|elem} The proper element\n */\nconst getNextActiveElement = (list, activeElement, shouldGetNext, isCycleAllowed) => {\n const listLength = list.length;\n let index = list.indexOf(activeElement);\n\n // if the element does not exist in the list return an element\n // depending on the direction and if cycle is allowed\n if (index === -1) {\n return !shouldGetNext && isCycleAllowed ? list[listLength - 1] : list[0];\n }\n index += shouldGetNext ? 1 : -1;\n if (isCycleAllowed) {\n index = (index + listLength) % listLength;\n }\n return list[Math.max(0, Math.min(index, listLength - 1))];\n};\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap dom/event-handler.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst namespaceRegex = /[^.]*(?=\\..*)\\.|.*/;\nconst stripNameRegex = /\\..*/;\nconst stripUidRegex = /::\\d+$/;\nconst eventRegistry = {}; // Events storage\nlet uidEvent = 1;\nconst customEvents = {\n mouseenter: 'mouseover',\n mouseleave: 'mouseout'\n};\nconst nativeEvents = new Set(['click', 'dblclick', 'mouseup', 'mousedown', 'contextmenu', 'mousewheel', 'DOMMouseScroll', 'mouseover', 'mouseout', 'mousemove', 'selectstart', 'selectend', 'keydown', 'keypress', 'keyup', 'orientationchange', 'touchstart', 'touchmove', 'touchend', 'touchcancel', 'pointerdown', 'pointermove', 'pointerup', 'pointerleave', 'pointercancel', 'gesturestart', 'gesturechange', 'gestureend', 'focus', 'blur', 'change', 'reset', 'select', 'submit', 'focusin', 'focusout', 'load', 'unload', 'beforeunload', 'resize', 'move', 'DOMContentLoaded', 'readystatechange', 'error', 'abort', 'scroll']);\n\n/**\n * Private methods\n */\n\nfunction makeEventUid(element, uid) {\n return uid && `${uid}::${uidEvent++}` || element.uidEvent || uidEvent++;\n}\nfunction getElementEvents(element) {\n const uid = makeEventUid(element);\n element.uidEvent = uid;\n eventRegistry[uid] = eventRegistry[uid] || {};\n return eventRegistry[uid];\n}\nfunction bootstrapHandler(element, fn) {\n return function handler(event) {\n hydrateObj(event, {\n delegateTarget: element\n });\n if (handler.oneOff) {\n EventHandler.off(element, event.type, fn);\n }\n return fn.apply(element, [event]);\n };\n}\nfunction bootstrapDelegationHandler(element, selector, fn) {\n return function handler(event) {\n const domElements = element.querySelectorAll(selector);\n for (let {\n target\n } = event; target && target !== this; target = target.parentNode) {\n for (const domElement of domElements) {\n if (domElement !== target) {\n continue;\n }\n hydrateObj(event, {\n delegateTarget: target\n });\n if (handler.oneOff) {\n EventHandler.off(element, event.type, selector, fn);\n }\n return fn.apply(target, [event]);\n }\n }\n };\n}\nfunction findHandler(events, callable, delegationSelector = null) {\n return Object.values(events).find(event => event.callable === callable && event.delegationSelector === delegationSelector);\n}\nfunction normalizeParameters(originalTypeEvent, handler, delegationFunction) {\n const isDelegated = typeof handler === 'string';\n // TODO: tooltip passes `false` instead of selector, so we need to check\n const callable = isDelegated ? delegationFunction : handler || delegationFunction;\n let typeEvent = getTypeEvent(originalTypeEvent);\n if (!nativeEvents.has(typeEvent)) {\n typeEvent = originalTypeEvent;\n }\n return [isDelegated, callable, typeEvent];\n}\nfunction addHandler(element, originalTypeEvent, handler, delegationFunction, oneOff) {\n if (typeof originalTypeEvent !== 'string' || !element) {\n return;\n }\n let [isDelegated, callable, typeEvent] = normalizeParameters(originalTypeEvent, handler, delegationFunction);\n\n // in case of mouseenter or mouseleave wrap the handler within a function that checks for its DOM position\n // this prevents the handler from being dispatched the same way as mouseover or mouseout does\n if (originalTypeEvent in customEvents) {\n const wrapFunction = fn => {\n return function (event) {\n if (!event.relatedTarget || event.relatedTarget !== event.delegateTarget && !event.delegateTarget.contains(event.relatedTarget)) {\n return fn.call(this, event);\n }\n };\n };\n callable = wrapFunction(callable);\n }\n const events = getElementEvents(element);\n const handlers = events[typeEvent] || (events[typeEvent] = {});\n const previousFunction = findHandler(handlers, callable, isDelegated ? handler : null);\n if (previousFunction) {\n previousFunction.oneOff = previousFunction.oneOff && oneOff;\n return;\n }\n const uid = makeEventUid(callable, originalTypeEvent.replace(namespaceRegex, ''));\n const fn = isDelegated ? bootstrapDelegationHandler(element, handler, callable) : bootstrapHandler(element, callable);\n fn.delegationSelector = isDelegated ? handler : null;\n fn.callable = callable;\n fn.oneOff = oneOff;\n fn.uidEvent = uid;\n handlers[uid] = fn;\n element.addEventListener(typeEvent, fn, isDelegated);\n}\nfunction removeHandler(element, events, typeEvent, handler, delegationSelector) {\n const fn = findHandler(events[typeEvent], handler, delegationSelector);\n if (!fn) {\n return;\n }\n element.removeEventListener(typeEvent, fn, Boolean(delegationSelector));\n delete events[typeEvent][fn.uidEvent];\n}\nfunction removeNamespacedHandlers(element, events, typeEvent, namespace) {\n const storeElementEvent = events[typeEvent] || {};\n for (const [handlerKey, event] of Object.entries(storeElementEvent)) {\n if (handlerKey.includes(namespace)) {\n removeHandler(element, events, typeEvent, event.callable, event.delegationSelector);\n }\n }\n}\nfunction getTypeEvent(event) {\n // allow to get the native events from namespaced events ('click.bs.button' --> 'click')\n event = event.replace(stripNameRegex, '');\n return customEvents[event] || event;\n}\nconst EventHandler = {\n on(element, event, handler, delegationFunction) {\n addHandler(element, event, handler, delegationFunction, false);\n },\n one(element, event, handler, delegationFunction) {\n addHandler(element, event, handler, delegationFunction, true);\n },\n off(element, originalTypeEvent, handler, delegationFunction) {\n if (typeof originalTypeEvent !== 'string' || !element) {\n return;\n }\n const [isDelegated, callable, typeEvent] = normalizeParameters(originalTypeEvent, handler, delegationFunction);\n const inNamespace = typeEvent !== originalTypeEvent;\n const events = getElementEvents(element);\n const storeElementEvent = events[typeEvent] || {};\n const isNamespace = originalTypeEvent.startsWith('.');\n if (typeof callable !== 'undefined') {\n // Simplest case: handler is passed, remove that listener ONLY.\n if (!Object.keys(storeElementEvent).length) {\n return;\n }\n removeHandler(element, events, typeEvent, callable, isDelegated ? handler : null);\n return;\n }\n if (isNamespace) {\n for (const elementEvent of Object.keys(events)) {\n removeNamespacedHandlers(element, events, elementEvent, originalTypeEvent.slice(1));\n }\n }\n for (const [keyHandlers, event] of Object.entries(storeElementEvent)) {\n const handlerKey = keyHandlers.replace(stripUidRegex, '');\n if (!inNamespace || originalTypeEvent.includes(handlerKey)) {\n removeHandler(element, events, typeEvent, event.callable, event.delegationSelector);\n }\n }\n },\n trigger(element, event, args) {\n if (typeof event !== 'string' || !element) {\n return null;\n }\n const $ = getjQuery();\n const typeEvent = getTypeEvent(event);\n const inNamespace = event !== typeEvent;\n let jQueryEvent = null;\n let bubbles = true;\n let nativeDispatch = true;\n let defaultPrevented = false;\n if (inNamespace && $) {\n jQueryEvent = $.Event(event, args);\n $(element).trigger(jQueryEvent);\n bubbles = !jQueryEvent.isPropagationStopped();\n nativeDispatch = !jQueryEvent.isImmediatePropagationStopped();\n defaultPrevented = jQueryEvent.isDefaultPrevented();\n }\n const evt = hydrateObj(new Event(event, {\n bubbles,\n cancelable: true\n }), args);\n if (defaultPrevented) {\n evt.preventDefault();\n }\n if (nativeDispatch) {\n element.dispatchEvent(evt);\n }\n if (evt.defaultPrevented && jQueryEvent) {\n jQueryEvent.preventDefault();\n }\n return evt;\n }\n};\nfunction hydrateObj(obj, meta = {}) {\n for (const [key, value] of Object.entries(meta)) {\n try {\n obj[key] = value;\n } catch (_unused) {\n Object.defineProperty(obj, key, {\n configurable: true,\n get() {\n return value;\n }\n });\n }\n }\n return obj;\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap dom/manipulator.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nfunction normalizeData(value) {\n if (value === 'true') {\n return true;\n }\n if (value === 'false') {\n return false;\n }\n if (value === Number(value).toString()) {\n return Number(value);\n }\n if (value === '' || value === 'null') {\n return null;\n }\n if (typeof value !== 'string') {\n return value;\n }\n try {\n return JSON.parse(decodeURIComponent(value));\n } catch (_unused) {\n return value;\n }\n}\nfunction normalizeDataKey(key) {\n return key.replace(/[A-Z]/g, chr => `-${chr.toLowerCase()}`);\n}\nconst Manipulator = {\n setDataAttribute(element, key, value) {\n element.setAttribute(`data-bs-${normalizeDataKey(key)}`, value);\n },\n removeDataAttribute(element, key) {\n element.removeAttribute(`data-bs-${normalizeDataKey(key)}`);\n },\n getDataAttributes(element) {\n if (!element) {\n return {};\n }\n const attributes = {};\n const bsKeys = Object.keys(element.dataset).filter(key => key.startsWith('bs') && !key.startsWith('bsConfig'));\n for (const key of bsKeys) {\n let pureKey = key.replace(/^bs/, '');\n pureKey = pureKey.charAt(0).toLowerCase() + pureKey.slice(1, pureKey.length);\n attributes[pureKey] = normalizeData(element.dataset[key]);\n }\n return attributes;\n },\n getDataAttribute(element, key) {\n return normalizeData(element.getAttribute(`data-bs-${normalizeDataKey(key)}`));\n }\n};\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap util/config.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Class definition\n */\n\nclass Config {\n // Getters\n static get Default() {\n return {};\n }\n static get DefaultType() {\n return {};\n }\n static get NAME() {\n throw new Error('You have to implement the static method \"NAME\", for each component!');\n }\n _getConfig(config) {\n config = this._mergeConfigObj(config);\n config = this._configAfterMerge(config);\n this._typeCheckConfig(config);\n return config;\n }\n _configAfterMerge(config) {\n return config;\n }\n _mergeConfigObj(config, element) {\n const jsonConfig = isElement(element) ? Manipulator.getDataAttribute(element, 'config') : {}; // try to parse\n\n return {\n ...this.constructor.Default,\n ...(typeof jsonConfig === 'object' ? jsonConfig : {}),\n ...(isElement(element) ? Manipulator.getDataAttributes(element) : {}),\n ...(typeof config === 'object' ? config : {})\n };\n }\n _typeCheckConfig(config, configTypes = this.constructor.DefaultType) {\n for (const [property, expectedTypes] of Object.entries(configTypes)) {\n const value = config[property];\n const valueType = isElement(value) ? 'element' : toType(value);\n if (!new RegExp(expectedTypes).test(valueType)) {\n throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option \"${property}\" provided type \"${valueType}\" but expected type \"${expectedTypes}\".`);\n }\n }\n }\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap base-component.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst VERSION = '5.3.0';\n\n/**\n * Class definition\n */\n\nclass BaseComponent extends Config {\n constructor(element, config) {\n super();\n element = getElement(element);\n if (!element) {\n return;\n }\n this._element = element;\n this._config = this._getConfig(config);\n Data.set(this._element, this.constructor.DATA_KEY, this);\n }\n\n // Public\n dispose() {\n Data.remove(this._element, this.constructor.DATA_KEY);\n EventHandler.off(this._element, this.constructor.EVENT_KEY);\n for (const propertyName of Object.getOwnPropertyNames(this)) {\n this[propertyName] = null;\n }\n }\n _queueCallback(callback, element, isAnimated = true) {\n executeAfterTransition(callback, element, isAnimated);\n }\n _getConfig(config) {\n config = this._mergeConfigObj(config, this._element);\n config = this._configAfterMerge(config);\n this._typeCheckConfig(config);\n return config;\n }\n\n // Static\n static getInstance(element) {\n return Data.get(getElement(element), this.DATA_KEY);\n }\n static getOrCreateInstance(element, config = {}) {\n return this.getInstance(element) || new this(element, typeof config === 'object' ? config : null);\n }\n static get VERSION() {\n return VERSION;\n }\n static get DATA_KEY() {\n return `bs.${this.NAME}`;\n }\n static get EVENT_KEY() {\n return `.${this.DATA_KEY}`;\n }\n static eventName(name) {\n return `${name}${this.EVENT_KEY}`;\n }\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap dom/selector-engine.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst getSelector = element => {\n let selector = element.getAttribute('data-bs-target');\n if (!selector || selector === '#') {\n let hrefAttribute = element.getAttribute('href');\n\n // The only valid content that could double as a selector are IDs or classes,\n // so everything starting with `#` or `.`. If a \"real\" URL is used as the selector,\n // `document.querySelector` will rightfully complain it is invalid.\n // See https://github.com/twbs/bootstrap/issues/32273\n if (!hrefAttribute || !hrefAttribute.includes('#') && !hrefAttribute.startsWith('.')) {\n return null;\n }\n\n // Just in case some CMS puts out a full URL with the anchor appended\n if (hrefAttribute.includes('#') && !hrefAttribute.startsWith('#')) {\n hrefAttribute = `#${hrefAttribute.split('#')[1]}`;\n }\n selector = hrefAttribute && hrefAttribute !== '#' ? hrefAttribute.trim() : null;\n }\n return parseSelector(selector);\n};\nconst SelectorEngine = {\n find(selector, element = document.documentElement) {\n return [].concat(...Element.prototype.querySelectorAll.call(element, selector));\n },\n findOne(selector, element = document.documentElement) {\n return Element.prototype.querySelector.call(element, selector);\n },\n children(element, selector) {\n return [].concat(...element.children).filter(child => child.matches(selector));\n },\n parents(element, selector) {\n const parents = [];\n let ancestor = element.parentNode.closest(selector);\n while (ancestor) {\n parents.push(ancestor);\n ancestor = ancestor.parentNode.closest(selector);\n }\n return parents;\n },\n prev(element, selector) {\n let previous = element.previousElementSibling;\n while (previous) {\n if (previous.matches(selector)) {\n return [previous];\n }\n previous = previous.previousElementSibling;\n }\n return [];\n },\n // TODO: this is now unused; remove later along with prev()\n next(element, selector) {\n let next = element.nextElementSibling;\n while (next) {\n if (next.matches(selector)) {\n return [next];\n }\n next = next.nextElementSibling;\n }\n return [];\n },\n focusableChildren(element) {\n const focusables = ['a', 'button', 'input', 'textarea', 'select', 'details', '[tabindex]', '[contenteditable=\"true\"]'].map(selector => `${selector}:not([tabindex^=\"-\"])`).join(',');\n return this.find(focusables, element).filter(el => !isDisabled(el) && isVisible(el));\n },\n getSelectorFromElement(element) {\n const selector = getSelector(element);\n if (selector) {\n return SelectorEngine.findOne(selector) ? selector : null;\n }\n return null;\n },\n getElementFromSelector(element) {\n const selector = getSelector(element);\n return selector ? SelectorEngine.findOne(selector) : null;\n },\n getMultipleElementsFromSelector(element) {\n const selector = getSelector(element);\n return selector ? SelectorEngine.find(selector) : [];\n }\n};\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap util/component-functions.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nconst enableDismissTrigger = (component, method = 'hide') => {\n const clickEvent = `click.dismiss${component.EVENT_KEY}`;\n const name = component.NAME;\n EventHandler.on(document, clickEvent, `[data-bs-dismiss=\"${name}\"]`, function (event) {\n if (['A', 'AREA'].includes(this.tagName)) {\n event.preventDefault();\n }\n if (isDisabled(this)) {\n return;\n }\n const target = SelectorEngine.getElementFromSelector(this) || this.closest(`.${name}`);\n const instance = component.getOrCreateInstance(target);\n\n // Method argument is left, for Alert and only, as it doesn't implement the 'hide' method\n instance[method]();\n });\n};\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap alert.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$f = 'alert';\nconst DATA_KEY$a = 'bs.alert';\nconst EVENT_KEY$b = `.${DATA_KEY$a}`;\nconst EVENT_CLOSE = `close${EVENT_KEY$b}`;\nconst EVENT_CLOSED = `closed${EVENT_KEY$b}`;\nconst CLASS_NAME_FADE$5 = 'fade';\nconst CLASS_NAME_SHOW$8 = 'show';\n\n/**\n * Class definition\n */\n\nclass Alert extends BaseComponent {\n // Getters\n static get NAME() {\n return NAME$f;\n }\n\n // Public\n close() {\n const closeEvent = EventHandler.trigger(this._element, EVENT_CLOSE);\n if (closeEvent.defaultPrevented) {\n return;\n }\n this._element.classList.remove(CLASS_NAME_SHOW$8);\n const isAnimated = this._element.classList.contains(CLASS_NAME_FADE$5);\n this._queueCallback(() => this._destroyElement(), this._element, isAnimated);\n }\n\n // Private\n _destroyElement() {\n this._element.remove();\n EventHandler.trigger(this._element, EVENT_CLOSED);\n this.dispose();\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Alert.getOrCreateInstance(this);\n if (typeof config !== 'string') {\n return;\n }\n if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {\n throw new TypeError(`No method named \"${config}\"`);\n }\n data[config](this);\n });\n }\n}\n\n/**\n * Data API implementation\n */\n\nenableDismissTrigger(Alert, 'close');\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Alert);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap button.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$e = 'button';\nconst DATA_KEY$9 = 'bs.button';\nconst EVENT_KEY$a = `.${DATA_KEY$9}`;\nconst DATA_API_KEY$6 = '.data-api';\nconst CLASS_NAME_ACTIVE$3 = 'active';\nconst SELECTOR_DATA_TOGGLE$5 = '[data-bs-toggle=\"button\"]';\nconst EVENT_CLICK_DATA_API$6 = `click${EVENT_KEY$a}${DATA_API_KEY$6}`;\n\n/**\n * Class definition\n */\n\nclass Button extends BaseComponent {\n // Getters\n static get NAME() {\n return NAME$e;\n }\n\n // Public\n toggle() {\n // Toggle class and sync the `aria-pressed` attribute with the return value of the `.toggle()` method\n this._element.setAttribute('aria-pressed', this._element.classList.toggle(CLASS_NAME_ACTIVE$3));\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Button.getOrCreateInstance(this);\n if (config === 'toggle') {\n data[config]();\n }\n });\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_CLICK_DATA_API$6, SELECTOR_DATA_TOGGLE$5, event => {\n event.preventDefault();\n const button = event.target.closest(SELECTOR_DATA_TOGGLE$5);\n const data = Button.getOrCreateInstance(button);\n data.toggle();\n});\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Button);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap util/swipe.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$d = 'swipe';\nconst EVENT_KEY$9 = '.bs.swipe';\nconst EVENT_TOUCHSTART = `touchstart${EVENT_KEY$9}`;\nconst EVENT_TOUCHMOVE = `touchmove${EVENT_KEY$9}`;\nconst EVENT_TOUCHEND = `touchend${EVENT_KEY$9}`;\nconst EVENT_POINTERDOWN = `pointerdown${EVENT_KEY$9}`;\nconst EVENT_POINTERUP = `pointerup${EVENT_KEY$9}`;\nconst POINTER_TYPE_TOUCH = 'touch';\nconst POINTER_TYPE_PEN = 'pen';\nconst CLASS_NAME_POINTER_EVENT = 'pointer-event';\nconst SWIPE_THRESHOLD = 40;\nconst Default$c = {\n endCallback: null,\n leftCallback: null,\n rightCallback: null\n};\nconst DefaultType$c = {\n endCallback: '(function|null)',\n leftCallback: '(function|null)',\n rightCallback: '(function|null)'\n};\n\n/**\n * Class definition\n */\n\nclass Swipe extends Config {\n constructor(element, config) {\n super();\n this._element = element;\n if (!element || !Swipe.isSupported()) {\n return;\n }\n this._config = this._getConfig(config);\n this._deltaX = 0;\n this._supportPointerEvents = Boolean(window.PointerEvent);\n this._initEvents();\n }\n\n // Getters\n static get Default() {\n return Default$c;\n }\n static get DefaultType() {\n return DefaultType$c;\n }\n static get NAME() {\n return NAME$d;\n }\n\n // Public\n dispose() {\n EventHandler.off(this._element, EVENT_KEY$9);\n }\n\n // Private\n _start(event) {\n if (!this._supportPointerEvents) {\n this._deltaX = event.touches[0].clientX;\n return;\n }\n if (this._eventIsPointerPenTouch(event)) {\n this._deltaX = event.clientX;\n }\n }\n _end(event) {\n if (this._eventIsPointerPenTouch(event)) {\n this._deltaX = event.clientX - this._deltaX;\n }\n this._handleSwipe();\n execute(this._config.endCallback);\n }\n _move(event) {\n this._deltaX = event.touches && event.touches.length > 1 ? 0 : event.touches[0].clientX - this._deltaX;\n }\n _handleSwipe() {\n const absDeltaX = Math.abs(this._deltaX);\n if (absDeltaX <= SWIPE_THRESHOLD) {\n return;\n }\n const direction = absDeltaX / this._deltaX;\n this._deltaX = 0;\n if (!direction) {\n return;\n }\n execute(direction > 0 ? this._config.rightCallback : this._config.leftCallback);\n }\n _initEvents() {\n if (this._supportPointerEvents) {\n EventHandler.on(this._element, EVENT_POINTERDOWN, event => this._start(event));\n EventHandler.on(this._element, EVENT_POINTERUP, event => this._end(event));\n this._element.classList.add(CLASS_NAME_POINTER_EVENT);\n } else {\n EventHandler.on(this._element, EVENT_TOUCHSTART, event => this._start(event));\n EventHandler.on(this._element, EVENT_TOUCHMOVE, event => this._move(event));\n EventHandler.on(this._element, EVENT_TOUCHEND, event => this._end(event));\n }\n }\n _eventIsPointerPenTouch(event) {\n return this._supportPointerEvents && (event.pointerType === POINTER_TYPE_PEN || event.pointerType === POINTER_TYPE_TOUCH);\n }\n\n // Static\n static isSupported() {\n return 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0;\n }\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap carousel.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$c = 'carousel';\nconst DATA_KEY$8 = 'bs.carousel';\nconst EVENT_KEY$8 = `.${DATA_KEY$8}`;\nconst DATA_API_KEY$5 = '.data-api';\nconst ARROW_LEFT_KEY$1 = 'ArrowLeft';\nconst ARROW_RIGHT_KEY$1 = 'ArrowRight';\nconst TOUCHEVENT_COMPAT_WAIT = 500; // Time for mouse compat events to fire after touch\n\nconst ORDER_NEXT = 'next';\nconst ORDER_PREV = 'prev';\nconst DIRECTION_LEFT = 'left';\nconst DIRECTION_RIGHT = 'right';\nconst EVENT_SLIDE = `slide${EVENT_KEY$8}`;\nconst EVENT_SLID = `slid${EVENT_KEY$8}`;\nconst EVENT_KEYDOWN$1 = `keydown${EVENT_KEY$8}`;\nconst EVENT_MOUSEENTER$1 = `mouseenter${EVENT_KEY$8}`;\nconst EVENT_MOUSELEAVE$1 = `mouseleave${EVENT_KEY$8}`;\nconst EVENT_DRAG_START = `dragstart${EVENT_KEY$8}`;\nconst EVENT_LOAD_DATA_API$3 = `load${EVENT_KEY$8}${DATA_API_KEY$5}`;\nconst EVENT_CLICK_DATA_API$5 = `click${EVENT_KEY$8}${DATA_API_KEY$5}`;\nconst CLASS_NAME_CAROUSEL = 'carousel';\nconst CLASS_NAME_ACTIVE$2 = 'active';\nconst CLASS_NAME_SLIDE = 'slide';\nconst CLASS_NAME_END = 'carousel-item-end';\nconst CLASS_NAME_START = 'carousel-item-start';\nconst CLASS_NAME_NEXT = 'carousel-item-next';\nconst CLASS_NAME_PREV = 'carousel-item-prev';\nconst SELECTOR_ACTIVE = '.active';\nconst SELECTOR_ITEM = '.carousel-item';\nconst SELECTOR_ACTIVE_ITEM = SELECTOR_ACTIVE + SELECTOR_ITEM;\nconst SELECTOR_ITEM_IMG = '.carousel-item img';\nconst SELECTOR_INDICATORS = '.carousel-indicators';\nconst SELECTOR_DATA_SLIDE = '[data-bs-slide], [data-bs-slide-to]';\nconst SELECTOR_DATA_RIDE = '[data-bs-ride=\"carousel\"]';\nconst KEY_TO_DIRECTION = {\n [ARROW_LEFT_KEY$1]: DIRECTION_RIGHT,\n [ARROW_RIGHT_KEY$1]: DIRECTION_LEFT\n};\nconst Default$b = {\n interval: 5000,\n keyboard: true,\n pause: 'hover',\n ride: false,\n touch: true,\n wrap: true\n};\nconst DefaultType$b = {\n interval: '(number|boolean)',\n // TODO:v6 remove boolean support\n keyboard: 'boolean',\n pause: '(string|boolean)',\n ride: '(boolean|string)',\n touch: 'boolean',\n wrap: 'boolean'\n};\n\n/**\n * Class definition\n */\n\nclass Carousel extends BaseComponent {\n constructor(element, config) {\n super(element, config);\n this._interval = null;\n this._activeElement = null;\n this._isSliding = false;\n this.touchTimeout = null;\n this._swipeHelper = null;\n this._indicatorsElement = SelectorEngine.findOne(SELECTOR_INDICATORS, this._element);\n this._addEventListeners();\n if (this._config.ride === CLASS_NAME_CAROUSEL) {\n this.cycle();\n }\n }\n\n // Getters\n static get Default() {\n return Default$b;\n }\n static get DefaultType() {\n return DefaultType$b;\n }\n static get NAME() {\n return NAME$c;\n }\n\n // Public\n next() {\n this._slide(ORDER_NEXT);\n }\n nextWhenVisible() {\n // FIXME TODO use `document.visibilityState`\n // Don't call next when the page isn't visible\n // or the carousel or its parent isn't visible\n if (!document.hidden && isVisible(this._element)) {\n this.next();\n }\n }\n prev() {\n this._slide(ORDER_PREV);\n }\n pause() {\n if (this._isSliding) {\n triggerTransitionEnd(this._element);\n }\n this._clearInterval();\n }\n cycle() {\n this._clearInterval();\n this._updateInterval();\n this._interval = setInterval(() => this.nextWhenVisible(), this._config.interval);\n }\n _maybeEnableCycle() {\n if (!this._config.ride) {\n return;\n }\n if (this._isSliding) {\n EventHandler.one(this._element, EVENT_SLID, () => this.cycle());\n return;\n }\n this.cycle();\n }\n to(index) {\n const items = this._getItems();\n if (index > items.length - 1 || index < 0) {\n return;\n }\n if (this._isSliding) {\n EventHandler.one(this._element, EVENT_SLID, () => this.to(index));\n return;\n }\n const activeIndex = this._getItemIndex(this._getActive());\n if (activeIndex === index) {\n return;\n }\n const order = index > activeIndex ? ORDER_NEXT : ORDER_PREV;\n this._slide(order, items[index]);\n }\n dispose() {\n if (this._swipeHelper) {\n this._swipeHelper.dispose();\n }\n super.dispose();\n }\n\n // Private\n _configAfterMerge(config) {\n config.defaultInterval = config.interval;\n return config;\n }\n _addEventListeners() {\n if (this._config.keyboard) {\n EventHandler.on(this._element, EVENT_KEYDOWN$1, event => this._keydown(event));\n }\n if (this._config.pause === 'hover') {\n EventHandler.on(this._element, EVENT_MOUSEENTER$1, () => this.pause());\n EventHandler.on(this._element, EVENT_MOUSELEAVE$1, () => this._maybeEnableCycle());\n }\n if (this._config.touch && Swipe.isSupported()) {\n this._addTouchEventListeners();\n }\n }\n _addTouchEventListeners() {\n for (const img of SelectorEngine.find(SELECTOR_ITEM_IMG, this._element)) {\n EventHandler.on(img, EVENT_DRAG_START, event => event.preventDefault());\n }\n const endCallBack = () => {\n if (this._config.pause !== 'hover') {\n return;\n }\n\n // If it's a touch-enabled device, mouseenter/leave are fired as\n // part of the mouse compatibility events on first tap - the carousel\n // would stop cycling until user tapped out of it;\n // here, we listen for touchend, explicitly pause the carousel\n // (as if it's the second time we tap on it, mouseenter compat event\n // is NOT fired) and after a timeout (to allow for mouse compatibility\n // events to fire) we explicitly restart cycling\n\n this.pause();\n if (this.touchTimeout) {\n clearTimeout(this.touchTimeout);\n }\n this.touchTimeout = setTimeout(() => this._maybeEnableCycle(), TOUCHEVENT_COMPAT_WAIT + this._config.interval);\n };\n const swipeConfig = {\n leftCallback: () => this._slide(this._directionToOrder(DIRECTION_LEFT)),\n rightCallback: () => this._slide(this._directionToOrder(DIRECTION_RIGHT)),\n endCallback: endCallBack\n };\n this._swipeHelper = new Swipe(this._element, swipeConfig);\n }\n _keydown(event) {\n if (/input|textarea/i.test(event.target.tagName)) {\n return;\n }\n const direction = KEY_TO_DIRECTION[event.key];\n if (direction) {\n event.preventDefault();\n this._slide(this._directionToOrder(direction));\n }\n }\n _getItemIndex(element) {\n return this._getItems().indexOf(element);\n }\n _setActiveIndicatorElement(index) {\n if (!this._indicatorsElement) {\n return;\n }\n const activeIndicator = SelectorEngine.findOne(SELECTOR_ACTIVE, this._indicatorsElement);\n activeIndicator.classList.remove(CLASS_NAME_ACTIVE$2);\n activeIndicator.removeAttribute('aria-current');\n const newActiveIndicator = SelectorEngine.findOne(`[data-bs-slide-to=\"${index}\"]`, this._indicatorsElement);\n if (newActiveIndicator) {\n newActiveIndicator.classList.add(CLASS_NAME_ACTIVE$2);\n newActiveIndicator.setAttribute('aria-current', 'true');\n }\n }\n _updateInterval() {\n const element = this._activeElement || this._getActive();\n if (!element) {\n return;\n }\n const elementInterval = Number.parseInt(element.getAttribute('data-bs-interval'), 10);\n this._config.interval = elementInterval || this._config.defaultInterval;\n }\n _slide(order, element = null) {\n if (this._isSliding) {\n return;\n }\n const activeElement = this._getActive();\n const isNext = order === ORDER_NEXT;\n const nextElement = element || getNextActiveElement(this._getItems(), activeElement, isNext, this._config.wrap);\n if (nextElement === activeElement) {\n return;\n }\n const nextElementIndex = this._getItemIndex(nextElement);\n const triggerEvent = eventName => {\n return EventHandler.trigger(this._element, eventName, {\n relatedTarget: nextElement,\n direction: this._orderToDirection(order),\n from: this._getItemIndex(activeElement),\n to: nextElementIndex\n });\n };\n const slideEvent = triggerEvent(EVENT_SLIDE);\n if (slideEvent.defaultPrevented) {\n return;\n }\n if (!activeElement || !nextElement) {\n // Some weirdness is happening, so we bail\n // TODO: change tests that use empty divs to avoid this check\n return;\n }\n const isCycling = Boolean(this._interval);\n this.pause();\n this._isSliding = true;\n this._setActiveIndicatorElement(nextElementIndex);\n this._activeElement = nextElement;\n const directionalClassName = isNext ? CLASS_NAME_START : CLASS_NAME_END;\n const orderClassName = isNext ? CLASS_NAME_NEXT : CLASS_NAME_PREV;\n nextElement.classList.add(orderClassName);\n reflow(nextElement);\n activeElement.classList.add(directionalClassName);\n nextElement.classList.add(directionalClassName);\n const completeCallBack = () => {\n nextElement.classList.remove(directionalClassName, orderClassName);\n nextElement.classList.add(CLASS_NAME_ACTIVE$2);\n activeElement.classList.remove(CLASS_NAME_ACTIVE$2, orderClassName, directionalClassName);\n this._isSliding = false;\n triggerEvent(EVENT_SLID);\n };\n this._queueCallback(completeCallBack, activeElement, this._isAnimated());\n if (isCycling) {\n this.cycle();\n }\n }\n _isAnimated() {\n return this._element.classList.contains(CLASS_NAME_SLIDE);\n }\n _getActive() {\n return SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element);\n }\n _getItems() {\n return SelectorEngine.find(SELECTOR_ITEM, this._element);\n }\n _clearInterval() {\n if (this._interval) {\n clearInterval(this._interval);\n this._interval = null;\n }\n }\n _directionToOrder(direction) {\n if (isRTL()) {\n return direction === DIRECTION_LEFT ? ORDER_PREV : ORDER_NEXT;\n }\n return direction === DIRECTION_LEFT ? ORDER_NEXT : ORDER_PREV;\n }\n _orderToDirection(order) {\n if (isRTL()) {\n return order === ORDER_PREV ? DIRECTION_LEFT : DIRECTION_RIGHT;\n }\n return order === ORDER_PREV ? DIRECTION_RIGHT : DIRECTION_LEFT;\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Carousel.getOrCreateInstance(this, config);\n if (typeof config === 'number') {\n data.to(config);\n return;\n }\n if (typeof config === 'string') {\n if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {\n throw new TypeError(`No method named \"${config}\"`);\n }\n data[config]();\n }\n });\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_CLICK_DATA_API$5, SELECTOR_DATA_SLIDE, function (event) {\n const target = SelectorEngine.getElementFromSelector(this);\n if (!target || !target.classList.contains(CLASS_NAME_CAROUSEL)) {\n return;\n }\n event.preventDefault();\n const carousel = Carousel.getOrCreateInstance(target);\n const slideIndex = this.getAttribute('data-bs-slide-to');\n if (slideIndex) {\n carousel.to(slideIndex);\n carousel._maybeEnableCycle();\n return;\n }\n if (Manipulator.getDataAttribute(this, 'slide') === 'next') {\n carousel.next();\n carousel._maybeEnableCycle();\n return;\n }\n carousel.prev();\n carousel._maybeEnableCycle();\n});\nEventHandler.on(window, EVENT_LOAD_DATA_API$3, () => {\n const carousels = SelectorEngine.find(SELECTOR_DATA_RIDE);\n for (const carousel of carousels) {\n Carousel.getOrCreateInstance(carousel);\n }\n});\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Carousel);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap collapse.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$b = 'collapse';\nconst DATA_KEY$7 = 'bs.collapse';\nconst EVENT_KEY$7 = `.${DATA_KEY$7}`;\nconst DATA_API_KEY$4 = '.data-api';\nconst EVENT_SHOW$6 = `show${EVENT_KEY$7}`;\nconst EVENT_SHOWN$6 = `shown${EVENT_KEY$7}`;\nconst EVENT_HIDE$6 = `hide${EVENT_KEY$7}`;\nconst EVENT_HIDDEN$6 = `hidden${EVENT_KEY$7}`;\nconst EVENT_CLICK_DATA_API$4 = `click${EVENT_KEY$7}${DATA_API_KEY$4}`;\nconst CLASS_NAME_SHOW$7 = 'show';\nconst CLASS_NAME_COLLAPSE = 'collapse';\nconst CLASS_NAME_COLLAPSING = 'collapsing';\nconst CLASS_NAME_COLLAPSED = 'collapsed';\nconst CLASS_NAME_DEEPER_CHILDREN = `:scope .${CLASS_NAME_COLLAPSE} .${CLASS_NAME_COLLAPSE}`;\nconst CLASS_NAME_HORIZONTAL = 'collapse-horizontal';\nconst WIDTH = 'width';\nconst HEIGHT = 'height';\nconst SELECTOR_ACTIVES = '.collapse.show, .collapse.collapsing';\nconst SELECTOR_DATA_TOGGLE$4 = '[data-bs-toggle=\"collapse\"]';\nconst Default$a = {\n parent: null,\n toggle: true\n};\nconst DefaultType$a = {\n parent: '(null|element)',\n toggle: 'boolean'\n};\n\n/**\n * Class definition\n */\n\nclass Collapse extends BaseComponent {\n constructor(element, config) {\n super(element, config);\n this._isTransitioning = false;\n this._triggerArray = [];\n const toggleList = SelectorEngine.find(SELECTOR_DATA_TOGGLE$4);\n for (const elem of toggleList) {\n const selector = SelectorEngine.getSelectorFromElement(elem);\n const filterElement = SelectorEngine.find(selector).filter(foundElement => foundElement === this._element);\n if (selector !== null && filterElement.length) {\n this._triggerArray.push(elem);\n }\n }\n this._initializeChildren();\n if (!this._config.parent) {\n this._addAriaAndCollapsedClass(this._triggerArray, this._isShown());\n }\n if (this._config.toggle) {\n this.toggle();\n }\n }\n\n // Getters\n static get Default() {\n return Default$a;\n }\n static get DefaultType() {\n return DefaultType$a;\n }\n static get NAME() {\n return NAME$b;\n }\n\n // Public\n toggle() {\n if (this._isShown()) {\n this.hide();\n } else {\n this.show();\n }\n }\n show() {\n if (this._isTransitioning || this._isShown()) {\n return;\n }\n let activeChildren = [];\n\n // find active children\n if (this._config.parent) {\n activeChildren = this._getFirstLevelChildren(SELECTOR_ACTIVES).filter(element => element !== this._element).map(element => Collapse.getOrCreateInstance(element, {\n toggle: false\n }));\n }\n if (activeChildren.length && activeChildren[0]._isTransitioning) {\n return;\n }\n const startEvent = EventHandler.trigger(this._element, EVENT_SHOW$6);\n if (startEvent.defaultPrevented) {\n return;\n }\n for (const activeInstance of activeChildren) {\n activeInstance.hide();\n }\n const dimension = this._getDimension();\n this._element.classList.remove(CLASS_NAME_COLLAPSE);\n this._element.classList.add(CLASS_NAME_COLLAPSING);\n this._element.style[dimension] = 0;\n this._addAriaAndCollapsedClass(this._triggerArray, true);\n this._isTransitioning = true;\n const complete = () => {\n this._isTransitioning = false;\n this._element.classList.remove(CLASS_NAME_COLLAPSING);\n this._element.classList.add(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW$7);\n this._element.style[dimension] = '';\n EventHandler.trigger(this._element, EVENT_SHOWN$6);\n };\n const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1);\n const scrollSize = `scroll${capitalizedDimension}`;\n this._queueCallback(complete, this._element, true);\n this._element.style[dimension] = `${this._element[scrollSize]}px`;\n }\n hide() {\n if (this._isTransitioning || !this._isShown()) {\n return;\n }\n const startEvent = EventHandler.trigger(this._element, EVENT_HIDE$6);\n if (startEvent.defaultPrevented) {\n return;\n }\n const dimension = this._getDimension();\n this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`;\n reflow(this._element);\n this._element.classList.add(CLASS_NAME_COLLAPSING);\n this._element.classList.remove(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW$7);\n for (const trigger of this._triggerArray) {\n const element = SelectorEngine.getElementFromSelector(trigger);\n if (element && !this._isShown(element)) {\n this._addAriaAndCollapsedClass([trigger], false);\n }\n }\n this._isTransitioning = true;\n const complete = () => {\n this._isTransitioning = false;\n this._element.classList.remove(CLASS_NAME_COLLAPSING);\n this._element.classList.add(CLASS_NAME_COLLAPSE);\n EventHandler.trigger(this._element, EVENT_HIDDEN$6);\n };\n this._element.style[dimension] = '';\n this._queueCallback(complete, this._element, true);\n }\n _isShown(element = this._element) {\n return element.classList.contains(CLASS_NAME_SHOW$7);\n }\n\n // Private\n _configAfterMerge(config) {\n config.toggle = Boolean(config.toggle); // Coerce string values\n config.parent = getElement(config.parent);\n return config;\n }\n _getDimension() {\n return this._element.classList.contains(CLASS_NAME_HORIZONTAL) ? WIDTH : HEIGHT;\n }\n _initializeChildren() {\n if (!this._config.parent) {\n return;\n }\n const children = this._getFirstLevelChildren(SELECTOR_DATA_TOGGLE$4);\n for (const element of children) {\n const selected = SelectorEngine.getElementFromSelector(element);\n if (selected) {\n this._addAriaAndCollapsedClass([element], this._isShown(selected));\n }\n }\n }\n _getFirstLevelChildren(selector) {\n const children = SelectorEngine.find(CLASS_NAME_DEEPER_CHILDREN, this._config.parent);\n // remove children if greater depth\n return SelectorEngine.find(selector, this._config.parent).filter(element => !children.includes(element));\n }\n _addAriaAndCollapsedClass(triggerArray, isOpen) {\n if (!triggerArray.length) {\n return;\n }\n for (const element of triggerArray) {\n element.classList.toggle(CLASS_NAME_COLLAPSED, !isOpen);\n element.setAttribute('aria-expanded', isOpen);\n }\n }\n\n // Static\n static jQueryInterface(config) {\n const _config = {};\n if (typeof config === 'string' && /show|hide/.test(config)) {\n _config.toggle = false;\n }\n return this.each(function () {\n const data = Collapse.getOrCreateInstance(this, _config);\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`);\n }\n data[config]();\n }\n });\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_CLICK_DATA_API$4, SELECTOR_DATA_TOGGLE$4, function (event) {\n // preventDefault only for <a> elements (which change the URL) not inside the collapsible element\n if (event.target.tagName === 'A' || event.delegateTarget && event.delegateTarget.tagName === 'A') {\n event.preventDefault();\n }\n for (const element of SelectorEngine.getMultipleElementsFromSelector(this)) {\n Collapse.getOrCreateInstance(element, {\n toggle: false\n }).toggle();\n }\n});\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Collapse);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap dropdown.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$a = 'dropdown';\nconst DATA_KEY$6 = 'bs.dropdown';\nconst EVENT_KEY$6 = `.${DATA_KEY$6}`;\nconst DATA_API_KEY$3 = '.data-api';\nconst ESCAPE_KEY$2 = 'Escape';\nconst TAB_KEY$1 = 'Tab';\nconst ARROW_UP_KEY$1 = 'ArrowUp';\nconst ARROW_DOWN_KEY$1 = 'ArrowDown';\nconst RIGHT_MOUSE_BUTTON = 2; // MouseEvent.button value for the secondary button, usually the right button\n\nconst EVENT_HIDE$5 = `hide${EVENT_KEY$6}`;\nconst EVENT_HIDDEN$5 = `hidden${EVENT_KEY$6}`;\nconst EVENT_SHOW$5 = `show${EVENT_KEY$6}`;\nconst EVENT_SHOWN$5 = `shown${EVENT_KEY$6}`;\nconst EVENT_CLICK_DATA_API$3 = `click${EVENT_KEY$6}${DATA_API_KEY$3}`;\nconst EVENT_KEYDOWN_DATA_API = `keydown${EVENT_KEY$6}${DATA_API_KEY$3}`;\nconst EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY$6}${DATA_API_KEY$3}`;\nconst CLASS_NAME_SHOW$6 = 'show';\nconst CLASS_NAME_DROPUP = 'dropup';\nconst CLASS_NAME_DROPEND = 'dropend';\nconst CLASS_NAME_DROPSTART = 'dropstart';\nconst CLASS_NAME_DROPUP_CENTER = 'dropup-center';\nconst CLASS_NAME_DROPDOWN_CENTER = 'dropdown-center';\nconst SELECTOR_DATA_TOGGLE$3 = '[data-bs-toggle=\"dropdown\"]:not(.disabled):not(:disabled)';\nconst SELECTOR_DATA_TOGGLE_SHOWN = `${SELECTOR_DATA_TOGGLE$3}.${CLASS_NAME_SHOW$6}`;\nconst SELECTOR_MENU = '.dropdown-menu';\nconst SELECTOR_NAVBAR = '.navbar';\nconst SELECTOR_NAVBAR_NAV = '.navbar-nav';\nconst SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)';\nconst PLACEMENT_TOP = isRTL() ? 'top-end' : 'top-start';\nconst PLACEMENT_TOPEND = isRTL() ? 'top-start' : 'top-end';\nconst PLACEMENT_BOTTOM = isRTL() ? 'bottom-end' : 'bottom-start';\nconst PLACEMENT_BOTTOMEND = isRTL() ? 'bottom-start' : 'bottom-end';\nconst PLACEMENT_RIGHT = isRTL() ? 'left-start' : 'right-start';\nconst PLACEMENT_LEFT = isRTL() ? 'right-start' : 'left-start';\nconst PLACEMENT_TOPCENTER = 'top';\nconst PLACEMENT_BOTTOMCENTER = 'bottom';\nconst Default$9 = {\n autoClose: true,\n boundary: 'clippingParents',\n display: 'dynamic',\n offset: [0, 2],\n popperConfig: null,\n reference: 'toggle'\n};\nconst DefaultType$9 = {\n autoClose: '(boolean|string)',\n boundary: '(string|element)',\n display: 'string',\n offset: '(array|string|function)',\n popperConfig: '(null|object|function)',\n reference: '(string|element|object)'\n};\n\n/**\n * Class definition\n */\n\nclass Dropdown extends BaseComponent {\n constructor(element, config) {\n super(element, config);\n this._popper = null;\n this._parent = this._element.parentNode; // dropdown wrapper\n // TODO: v6 revert #37011 & change markup https://getbootstrap.com/docs/5.3/forms/input-group/\n this._menu = SelectorEngine.next(this._element, SELECTOR_MENU)[0] || SelectorEngine.prev(this._element, SELECTOR_MENU)[0] || SelectorEngine.findOne(SELECTOR_MENU, this._parent);\n this._inNavbar = this._detectNavbar();\n }\n\n // Getters\n static get Default() {\n return Default$9;\n }\n static get DefaultType() {\n return DefaultType$9;\n }\n static get NAME() {\n return NAME$a;\n }\n\n // Public\n toggle() {\n return this._isShown() ? this.hide() : this.show();\n }\n show() {\n if (isDisabled(this._element) || this._isShown()) {\n return;\n }\n const relatedTarget = {\n relatedTarget: this._element\n };\n const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$5, relatedTarget);\n if (showEvent.defaultPrevented) {\n return;\n }\n this._createPopper();\n\n // If this is a touch-enabled device we add extra\n // empty mouseover listeners to the body's immediate children;\n // only needed because of broken event delegation on iOS\n // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n if ('ontouchstart' in document.documentElement && !this._parent.closest(SELECTOR_NAVBAR_NAV)) {\n for (const element of [].concat(...document.body.children)) {\n EventHandler.on(element, 'mouseover', noop);\n }\n }\n this._element.focus();\n this._element.setAttribute('aria-expanded', true);\n this._menu.classList.add(CLASS_NAME_SHOW$6);\n this._element.classList.add(CLASS_NAME_SHOW$6);\n EventHandler.trigger(this._element, EVENT_SHOWN$5, relatedTarget);\n }\n hide() {\n if (isDisabled(this._element) || !this._isShown()) {\n return;\n }\n const relatedTarget = {\n relatedTarget: this._element\n };\n this._completeHide(relatedTarget);\n }\n dispose() {\n if (this._popper) {\n this._popper.destroy();\n }\n super.dispose();\n }\n update() {\n this._inNavbar = this._detectNavbar();\n if (this._popper) {\n this._popper.update();\n }\n }\n\n // Private\n _completeHide(relatedTarget) {\n const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$5, relatedTarget);\n if (hideEvent.defaultPrevented) {\n return;\n }\n\n // If this is a touch-enabled device we remove the extra\n // empty mouseover listeners we added for iOS support\n if ('ontouchstart' in document.documentElement) {\n for (const element of [].concat(...document.body.children)) {\n EventHandler.off(element, 'mouseover', noop);\n }\n }\n if (this._popper) {\n this._popper.destroy();\n }\n this._menu.classList.remove(CLASS_NAME_SHOW$6);\n this._element.classList.remove(CLASS_NAME_SHOW$6);\n this._element.setAttribute('aria-expanded', 'false');\n Manipulator.removeDataAttribute(this._menu, 'popper');\n EventHandler.trigger(this._element, EVENT_HIDDEN$5, relatedTarget);\n }\n _getConfig(config) {\n config = super._getConfig(config);\n if (typeof config.reference === 'object' && !isElement(config.reference) && typeof config.reference.getBoundingClientRect !== 'function') {\n // Popper virtual elements require a getBoundingClientRect method\n throw new TypeError(`${NAME$a.toUpperCase()}: Option \"reference\" provided type \"object\" without a required \"getBoundingClientRect\" method.`);\n }\n return config;\n }\n _createPopper() {\n if (typeof _popperjs_core__WEBPACK_IMPORTED_MODULE_0__ === 'undefined') {\n throw new TypeError('Bootstrap\\'s dropdowns require Popper (https://popper.js.org)');\n }\n let referenceElement = this._element;\n if (this._config.reference === 'parent') {\n referenceElement = this._parent;\n } else if (isElement(this._config.reference)) {\n referenceElement = getElement(this._config.reference);\n } else if (typeof this._config.reference === 'object') {\n referenceElement = this._config.reference;\n }\n const popperConfig = this._getPopperConfig();\n this._popper = _popperjs_core__WEBPACK_IMPORTED_MODULE_1__.createPopper(referenceElement, this._menu, popperConfig);\n }\n _isShown() {\n return this._menu.classList.contains(CLASS_NAME_SHOW$6);\n }\n _getPlacement() {\n const parentDropdown = this._parent;\n if (parentDropdown.classList.contains(CLASS_NAME_DROPEND)) {\n return PLACEMENT_RIGHT;\n }\n if (parentDropdown.classList.contains(CLASS_NAME_DROPSTART)) {\n return PLACEMENT_LEFT;\n }\n if (parentDropdown.classList.contains(CLASS_NAME_DROPUP_CENTER)) {\n return PLACEMENT_TOPCENTER;\n }\n if (parentDropdown.classList.contains(CLASS_NAME_DROPDOWN_CENTER)) {\n return PLACEMENT_BOTTOMCENTER;\n }\n\n // We need to trim the value because custom properties can also include spaces\n const isEnd = getComputedStyle(this._menu).getPropertyValue('--bs-position').trim() === 'end';\n if (parentDropdown.classList.contains(CLASS_NAME_DROPUP)) {\n return isEnd ? PLACEMENT_TOPEND : PLACEMENT_TOP;\n }\n return isEnd ? PLACEMENT_BOTTOMEND : PLACEMENT_BOTTOM;\n }\n _detectNavbar() {\n return this._element.closest(SELECTOR_NAVBAR) !== null;\n }\n _getOffset() {\n const {\n offset\n } = this._config;\n if (typeof offset === 'string') {\n return offset.split(',').map(value => Number.parseInt(value, 10));\n }\n if (typeof offset === 'function') {\n return popperData => offset(popperData, this._element);\n }\n return offset;\n }\n _getPopperConfig() {\n const defaultBsPopperConfig = {\n placement: this._getPlacement(),\n modifiers: [{\n name: 'preventOverflow',\n options: {\n boundary: this._config.boundary\n }\n }, {\n name: 'offset',\n options: {\n offset: this._getOffset()\n }\n }]\n };\n\n // Disable Popper if we have a static display or Dropdown is in Navbar\n if (this._inNavbar || this._config.display === 'static') {\n Manipulator.setDataAttribute(this._menu, 'popper', 'static'); // TODO: v6 remove\n defaultBsPopperConfig.modifiers = [{\n name: 'applyStyles',\n enabled: false\n }];\n }\n return {\n ...defaultBsPopperConfig,\n ...execute(this._config.popperConfig, [defaultBsPopperConfig])\n };\n }\n _selectMenuItem({\n key,\n target\n }) {\n const items = SelectorEngine.find(SELECTOR_VISIBLE_ITEMS, this._menu).filter(element => isVisible(element));\n if (!items.length) {\n return;\n }\n\n // if target isn't included in items (e.g. when expanding the dropdown)\n // allow cycling to get the last item in case key equals ARROW_UP_KEY\n getNextActiveElement(items, target, key === ARROW_DOWN_KEY$1, !items.includes(target)).focus();\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Dropdown.getOrCreateInstance(this, config);\n if (typeof config !== 'string') {\n return;\n }\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`);\n }\n data[config]();\n });\n }\n static clearMenus(event) {\n if (event.button === RIGHT_MOUSE_BUTTON || event.type === 'keyup' && event.key !== TAB_KEY$1) {\n return;\n }\n const openToggles = SelectorEngine.find(SELECTOR_DATA_TOGGLE_SHOWN);\n for (const toggle of openToggles) {\n const context = Dropdown.getInstance(toggle);\n if (!context || context._config.autoClose === false) {\n continue;\n }\n const composedPath = event.composedPath();\n const isMenuTarget = composedPath.includes(context._menu);\n if (composedPath.includes(context._element) || context._config.autoClose === 'inside' && !isMenuTarget || context._config.autoClose === 'outside' && isMenuTarget) {\n continue;\n }\n\n // Tab navigation through the dropdown menu or events from contained inputs shouldn't close the menu\n if (context._menu.contains(event.target) && (event.type === 'keyup' && event.key === TAB_KEY$1 || /input|select|option|textarea|form/i.test(event.target.tagName))) {\n continue;\n }\n const relatedTarget = {\n relatedTarget: context._element\n };\n if (event.type === 'click') {\n relatedTarget.clickEvent = event;\n }\n context._completeHide(relatedTarget);\n }\n }\n static dataApiKeydownHandler(event) {\n // If not an UP | DOWN | ESCAPE key => not a dropdown command\n // If input/textarea && if key is other than ESCAPE => not a dropdown command\n\n const isInput = /input|textarea/i.test(event.target.tagName);\n const isEscapeEvent = event.key === ESCAPE_KEY$2;\n const isUpOrDownEvent = [ARROW_UP_KEY$1, ARROW_DOWN_KEY$1].includes(event.key);\n if (!isUpOrDownEvent && !isEscapeEvent) {\n return;\n }\n if (isInput && !isEscapeEvent) {\n return;\n }\n event.preventDefault();\n\n // TODO: v6 revert #37011 & change markup https://getbootstrap.com/docs/5.3/forms/input-group/\n const getToggleButton = this.matches(SELECTOR_DATA_TOGGLE$3) ? this : SelectorEngine.prev(this, SELECTOR_DATA_TOGGLE$3)[0] || SelectorEngine.next(this, SELECTOR_DATA_TOGGLE$3)[0] || SelectorEngine.findOne(SELECTOR_DATA_TOGGLE$3, event.delegateTarget.parentNode);\n const instance = Dropdown.getOrCreateInstance(getToggleButton);\n if (isUpOrDownEvent) {\n event.stopPropagation();\n instance.show();\n instance._selectMenuItem(event);\n return;\n }\n if (instance._isShown()) {\n // else is escape and we check if it is shown\n event.stopPropagation();\n instance.hide();\n getToggleButton.focus();\n }\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE$3, Dropdown.dataApiKeydownHandler);\nEventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown.dataApiKeydownHandler);\nEventHandler.on(document, EVENT_CLICK_DATA_API$3, Dropdown.clearMenus);\nEventHandler.on(document, EVENT_KEYUP_DATA_API, Dropdown.clearMenus);\nEventHandler.on(document, EVENT_CLICK_DATA_API$3, SELECTOR_DATA_TOGGLE$3, function (event) {\n event.preventDefault();\n Dropdown.getOrCreateInstance(this).toggle();\n});\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Dropdown);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap util/backdrop.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$9 = 'backdrop';\nconst CLASS_NAME_FADE$4 = 'fade';\nconst CLASS_NAME_SHOW$5 = 'show';\nconst EVENT_MOUSEDOWN = `mousedown.bs.${NAME$9}`;\nconst Default$8 = {\n className: 'modal-backdrop',\n clickCallback: null,\n isAnimated: false,\n isVisible: true,\n // if false, we use the backdrop helper without adding any element to the dom\n rootElement: 'body' // give the choice to place backdrop under different elements\n};\n\nconst DefaultType$8 = {\n className: 'string',\n clickCallback: '(function|null)',\n isAnimated: 'boolean',\n isVisible: 'boolean',\n rootElement: '(element|string)'\n};\n\n/**\n * Class definition\n */\n\nclass Backdrop extends Config {\n constructor(config) {\n super();\n this._config = this._getConfig(config);\n this._isAppended = false;\n this._element = null;\n }\n\n // Getters\n static get Default() {\n return Default$8;\n }\n static get DefaultType() {\n return DefaultType$8;\n }\n static get NAME() {\n return NAME$9;\n }\n\n // Public\n show(callback) {\n if (!this._config.isVisible) {\n execute(callback);\n return;\n }\n this._append();\n const element = this._getElement();\n if (this._config.isAnimated) {\n reflow(element);\n }\n element.classList.add(CLASS_NAME_SHOW$5);\n this._emulateAnimation(() => {\n execute(callback);\n });\n }\n hide(callback) {\n if (!this._config.isVisible) {\n execute(callback);\n return;\n }\n this._getElement().classList.remove(CLASS_NAME_SHOW$5);\n this._emulateAnimation(() => {\n this.dispose();\n execute(callback);\n });\n }\n dispose() {\n if (!this._isAppended) {\n return;\n }\n EventHandler.off(this._element, EVENT_MOUSEDOWN);\n this._element.remove();\n this._isAppended = false;\n }\n\n // Private\n _getElement() {\n if (!this._element) {\n const backdrop = document.createElement('div');\n backdrop.className = this._config.className;\n if (this._config.isAnimated) {\n backdrop.classList.add(CLASS_NAME_FADE$4);\n }\n this._element = backdrop;\n }\n return this._element;\n }\n _configAfterMerge(config) {\n // use getElement() with the default \"body\" to get a fresh Element on each instantiation\n config.rootElement = getElement(config.rootElement);\n return config;\n }\n _append() {\n if (this._isAppended) {\n return;\n }\n const element = this._getElement();\n this._config.rootElement.append(element);\n EventHandler.on(element, EVENT_MOUSEDOWN, () => {\n execute(this._config.clickCallback);\n });\n this._isAppended = true;\n }\n _emulateAnimation(callback) {\n executeAfterTransition(callback, this._getElement(), this._config.isAnimated);\n }\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap util/focustrap.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$8 = 'focustrap';\nconst DATA_KEY$5 = 'bs.focustrap';\nconst EVENT_KEY$5 = `.${DATA_KEY$5}`;\nconst EVENT_FOCUSIN$2 = `focusin${EVENT_KEY$5}`;\nconst EVENT_KEYDOWN_TAB = `keydown.tab${EVENT_KEY$5}`;\nconst TAB_KEY = 'Tab';\nconst TAB_NAV_FORWARD = 'forward';\nconst TAB_NAV_BACKWARD = 'backward';\nconst Default$7 = {\n autofocus: true,\n trapElement: null // The element to trap focus inside of\n};\n\nconst DefaultType$7 = {\n autofocus: 'boolean',\n trapElement: 'element'\n};\n\n/**\n * Class definition\n */\n\nclass FocusTrap extends Config {\n constructor(config) {\n super();\n this._config = this._getConfig(config);\n this._isActive = false;\n this._lastTabNavDirection = null;\n }\n\n // Getters\n static get Default() {\n return Default$7;\n }\n static get DefaultType() {\n return DefaultType$7;\n }\n static get NAME() {\n return NAME$8;\n }\n\n // Public\n activate() {\n if (this._isActive) {\n return;\n }\n if (this._config.autofocus) {\n this._config.trapElement.focus();\n }\n EventHandler.off(document, EVENT_KEY$5); // guard against infinite focus loop\n EventHandler.on(document, EVENT_FOCUSIN$2, event => this._handleFocusin(event));\n EventHandler.on(document, EVENT_KEYDOWN_TAB, event => this._handleKeydown(event));\n this._isActive = true;\n }\n deactivate() {\n if (!this._isActive) {\n return;\n }\n this._isActive = false;\n EventHandler.off(document, EVENT_KEY$5);\n }\n\n // Private\n _handleFocusin(event) {\n const {\n trapElement\n } = this._config;\n if (event.target === document || event.target === trapElement || trapElement.contains(event.target)) {\n return;\n }\n const elements = SelectorEngine.focusableChildren(trapElement);\n if (elements.length === 0) {\n trapElement.focus();\n } else if (this._lastTabNavDirection === TAB_NAV_BACKWARD) {\n elements[elements.length - 1].focus();\n } else {\n elements[0].focus();\n }\n }\n _handleKeydown(event) {\n if (event.key !== TAB_KEY) {\n return;\n }\n this._lastTabNavDirection = event.shiftKey ? TAB_NAV_BACKWARD : TAB_NAV_FORWARD;\n }\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap util/scrollBar.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top';\nconst SELECTOR_STICKY_CONTENT = '.sticky-top';\nconst PROPERTY_PADDING = 'padding-right';\nconst PROPERTY_MARGIN = 'margin-right';\n\n/**\n * Class definition\n */\n\nclass ScrollBarHelper {\n constructor() {\n this._element = document.body;\n }\n\n // Public\n getWidth() {\n // https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth#usage_notes\n const documentWidth = document.documentElement.clientWidth;\n return Math.abs(window.innerWidth - documentWidth);\n }\n hide() {\n const width = this.getWidth();\n this._disableOverFlow();\n // give padding to element to balance the hidden scrollbar width\n this._setElementAttributes(this._element, PROPERTY_PADDING, calculatedValue => calculatedValue + width);\n // trick: We adjust positive paddingRight and negative marginRight to sticky-top elements to keep showing fullwidth\n this._setElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING, calculatedValue => calculatedValue + width);\n this._setElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN, calculatedValue => calculatedValue - width);\n }\n reset() {\n this._resetElementAttributes(this._element, 'overflow');\n this._resetElementAttributes(this._element, PROPERTY_PADDING);\n this._resetElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING);\n this._resetElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN);\n }\n isOverflowing() {\n return this.getWidth() > 0;\n }\n\n // Private\n _disableOverFlow() {\n this._saveInitialAttribute(this._element, 'overflow');\n this._element.style.overflow = 'hidden';\n }\n _setElementAttributes(selector, styleProperty, callback) {\n const scrollbarWidth = this.getWidth();\n const manipulationCallBack = element => {\n if (element !== this._element && window.innerWidth > element.clientWidth + scrollbarWidth) {\n return;\n }\n this._saveInitialAttribute(element, styleProperty);\n const calculatedValue = window.getComputedStyle(element).getPropertyValue(styleProperty);\n element.style.setProperty(styleProperty, `${callback(Number.parseFloat(calculatedValue))}px`);\n };\n this._applyManipulationCallback(selector, manipulationCallBack);\n }\n _saveInitialAttribute(element, styleProperty) {\n const actualValue = element.style.getPropertyValue(styleProperty);\n if (actualValue) {\n Manipulator.setDataAttribute(element, styleProperty, actualValue);\n }\n }\n _resetElementAttributes(selector, styleProperty) {\n const manipulationCallBack = element => {\n const value = Manipulator.getDataAttribute(element, styleProperty);\n // We only want to remove the property if the value is `null`; the value can also be zero\n if (value === null) {\n element.style.removeProperty(styleProperty);\n return;\n }\n Manipulator.removeDataAttribute(element, styleProperty);\n element.style.setProperty(styleProperty, value);\n };\n this._applyManipulationCallback(selector, manipulationCallBack);\n }\n _applyManipulationCallback(selector, callBack) {\n if (isElement(selector)) {\n callBack(selector);\n return;\n }\n for (const sel of SelectorEngine.find(selector, this._element)) {\n callBack(sel);\n }\n }\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap modal.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$7 = 'modal';\nconst DATA_KEY$4 = 'bs.modal';\nconst EVENT_KEY$4 = `.${DATA_KEY$4}`;\nconst DATA_API_KEY$2 = '.data-api';\nconst ESCAPE_KEY$1 = 'Escape';\nconst EVENT_HIDE$4 = `hide${EVENT_KEY$4}`;\nconst EVENT_HIDE_PREVENTED$1 = `hidePrevented${EVENT_KEY$4}`;\nconst EVENT_HIDDEN$4 = `hidden${EVENT_KEY$4}`;\nconst EVENT_SHOW$4 = `show${EVENT_KEY$4}`;\nconst EVENT_SHOWN$4 = `shown${EVENT_KEY$4}`;\nconst EVENT_RESIZE$1 = `resize${EVENT_KEY$4}`;\nconst EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY$4}`;\nconst EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY$4}`;\nconst EVENT_KEYDOWN_DISMISS$1 = `keydown.dismiss${EVENT_KEY$4}`;\nconst EVENT_CLICK_DATA_API$2 = `click${EVENT_KEY$4}${DATA_API_KEY$2}`;\nconst CLASS_NAME_OPEN = 'modal-open';\nconst CLASS_NAME_FADE$3 = 'fade';\nconst CLASS_NAME_SHOW$4 = 'show';\nconst CLASS_NAME_STATIC = 'modal-static';\nconst OPEN_SELECTOR$1 = '.modal.show';\nconst SELECTOR_DIALOG = '.modal-dialog';\nconst SELECTOR_MODAL_BODY = '.modal-body';\nconst SELECTOR_DATA_TOGGLE$2 = '[data-bs-toggle=\"modal\"]';\nconst Default$6 = {\n backdrop: true,\n focus: true,\n keyboard: true\n};\nconst DefaultType$6 = {\n backdrop: '(boolean|string)',\n focus: 'boolean',\n keyboard: 'boolean'\n};\n\n/**\n * Class definition\n */\n\nclass Modal extends BaseComponent {\n constructor(element, config) {\n super(element, config);\n this._dialog = SelectorEngine.findOne(SELECTOR_DIALOG, this._element);\n this._backdrop = this._initializeBackDrop();\n this._focustrap = this._initializeFocusTrap();\n this._isShown = false;\n this._isTransitioning = false;\n this._scrollBar = new ScrollBarHelper();\n this._addEventListeners();\n }\n\n // Getters\n static get Default() {\n return Default$6;\n }\n static get DefaultType() {\n return DefaultType$6;\n }\n static get NAME() {\n return NAME$7;\n }\n\n // Public\n toggle(relatedTarget) {\n return this._isShown ? this.hide() : this.show(relatedTarget);\n }\n show(relatedTarget) {\n if (this._isShown || this._isTransitioning) {\n return;\n }\n const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$4, {\n relatedTarget\n });\n if (showEvent.defaultPrevented) {\n return;\n }\n this._isShown = true;\n this._isTransitioning = true;\n this._scrollBar.hide();\n document.body.classList.add(CLASS_NAME_OPEN);\n this._adjustDialog();\n this._backdrop.show(() => this._showElement(relatedTarget));\n }\n hide() {\n if (!this._isShown || this._isTransitioning) {\n return;\n }\n const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$4);\n if (hideEvent.defaultPrevented) {\n return;\n }\n this._isShown = false;\n this._isTransitioning = true;\n this._focustrap.deactivate();\n this._element.classList.remove(CLASS_NAME_SHOW$4);\n this._queueCallback(() => this._hideModal(), this._element, this._isAnimated());\n }\n dispose() {\n EventHandler.off(window, EVENT_KEY$4);\n EventHandler.off(this._dialog, EVENT_KEY$4);\n this._backdrop.dispose();\n this._focustrap.deactivate();\n super.dispose();\n }\n handleUpdate() {\n this._adjustDialog();\n }\n\n // Private\n _initializeBackDrop() {\n return new Backdrop({\n isVisible: Boolean(this._config.backdrop),\n // 'static' option will be translated to true, and booleans will keep their value,\n isAnimated: this._isAnimated()\n });\n }\n _initializeFocusTrap() {\n return new FocusTrap({\n trapElement: this._element\n });\n }\n _showElement(relatedTarget) {\n // try to append dynamic modal\n if (!document.body.contains(this._element)) {\n document.body.append(this._element);\n }\n this._element.style.display = 'block';\n this._element.removeAttribute('aria-hidden');\n this._element.setAttribute('aria-modal', true);\n this._element.setAttribute('role', 'dialog');\n this._element.scrollTop = 0;\n const modalBody = SelectorEngine.findOne(SELECTOR_MODAL_BODY, this._dialog);\n if (modalBody) {\n modalBody.scrollTop = 0;\n }\n reflow(this._element);\n this._element.classList.add(CLASS_NAME_SHOW$4);\n const transitionComplete = () => {\n if (this._config.focus) {\n this._focustrap.activate();\n }\n this._isTransitioning = false;\n EventHandler.trigger(this._element, EVENT_SHOWN$4, {\n relatedTarget\n });\n };\n this._queueCallback(transitionComplete, this._dialog, this._isAnimated());\n }\n _addEventListeners() {\n EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS$1, event => {\n if (event.key !== ESCAPE_KEY$1) {\n return;\n }\n if (this._config.keyboard) {\n this.hide();\n return;\n }\n this._triggerBackdropTransition();\n });\n EventHandler.on(window, EVENT_RESIZE$1, () => {\n if (this._isShown && !this._isTransitioning) {\n this._adjustDialog();\n }\n });\n EventHandler.on(this._element, EVENT_MOUSEDOWN_DISMISS, event => {\n // a bad trick to segregate clicks that may start inside dialog but end outside, and avoid listen to scrollbar clicks\n EventHandler.one(this._element, EVENT_CLICK_DISMISS, event2 => {\n if (this._element !== event.target || this._element !== event2.target) {\n return;\n }\n if (this._config.backdrop === 'static') {\n this._triggerBackdropTransition();\n return;\n }\n if (this._config.backdrop) {\n this.hide();\n }\n });\n });\n }\n _hideModal() {\n this._element.style.display = 'none';\n this._element.setAttribute('aria-hidden', true);\n this._element.removeAttribute('aria-modal');\n this._element.removeAttribute('role');\n this._isTransitioning = false;\n this._backdrop.hide(() => {\n document.body.classList.remove(CLASS_NAME_OPEN);\n this._resetAdjustments();\n this._scrollBar.reset();\n EventHandler.trigger(this._element, EVENT_HIDDEN$4);\n });\n }\n _isAnimated() {\n return this._element.classList.contains(CLASS_NAME_FADE$3);\n }\n _triggerBackdropTransition() {\n const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED$1);\n if (hideEvent.defaultPrevented) {\n return;\n }\n const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;\n const initialOverflowY = this._element.style.overflowY;\n // return if the following background transition hasn't yet completed\n if (initialOverflowY === 'hidden' || this._element.classList.contains(CLASS_NAME_STATIC)) {\n return;\n }\n if (!isModalOverflowing) {\n this._element.style.overflowY = 'hidden';\n }\n this._element.classList.add(CLASS_NAME_STATIC);\n this._queueCallback(() => {\n this._element.classList.remove(CLASS_NAME_STATIC);\n this._queueCallback(() => {\n this._element.style.overflowY = initialOverflowY;\n }, this._dialog);\n }, this._dialog);\n this._element.focus();\n }\n\n /**\n * The following methods are used to handle overflowing modals\n */\n\n _adjustDialog() {\n const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;\n const scrollbarWidth = this._scrollBar.getWidth();\n const isBodyOverflowing = scrollbarWidth > 0;\n if (isBodyOverflowing && !isModalOverflowing) {\n const property = isRTL() ? 'paddingLeft' : 'paddingRight';\n this._element.style[property] = `${scrollbarWidth}px`;\n }\n if (!isBodyOverflowing && isModalOverflowing) {\n const property = isRTL() ? 'paddingRight' : 'paddingLeft';\n this._element.style[property] = `${scrollbarWidth}px`;\n }\n }\n _resetAdjustments() {\n this._element.style.paddingLeft = '';\n this._element.style.paddingRight = '';\n }\n\n // Static\n static jQueryInterface(config, relatedTarget) {\n return this.each(function () {\n const data = Modal.getOrCreateInstance(this, config);\n if (typeof config !== 'string') {\n return;\n }\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`);\n }\n data[config](relatedTarget);\n });\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_CLICK_DATA_API$2, SELECTOR_DATA_TOGGLE$2, function (event) {\n const target = SelectorEngine.getElementFromSelector(this);\n if (['A', 'AREA'].includes(this.tagName)) {\n event.preventDefault();\n }\n EventHandler.one(target, EVENT_SHOW$4, showEvent => {\n if (showEvent.defaultPrevented) {\n // only register focus restorer if modal will actually get shown\n return;\n }\n EventHandler.one(target, EVENT_HIDDEN$4, () => {\n if (isVisible(this)) {\n this.focus();\n }\n });\n });\n\n // avoid conflict when clicking modal toggler while another one is open\n const alreadyOpen = SelectorEngine.findOne(OPEN_SELECTOR$1);\n if (alreadyOpen) {\n Modal.getInstance(alreadyOpen).hide();\n }\n const data = Modal.getOrCreateInstance(target);\n data.toggle(this);\n});\nenableDismissTrigger(Modal);\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Modal);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap offcanvas.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$6 = 'offcanvas';\nconst DATA_KEY$3 = 'bs.offcanvas';\nconst EVENT_KEY$3 = `.${DATA_KEY$3}`;\nconst DATA_API_KEY$1 = '.data-api';\nconst EVENT_LOAD_DATA_API$2 = `load${EVENT_KEY$3}${DATA_API_KEY$1}`;\nconst ESCAPE_KEY = 'Escape';\nconst CLASS_NAME_SHOW$3 = 'show';\nconst CLASS_NAME_SHOWING$1 = 'showing';\nconst CLASS_NAME_HIDING = 'hiding';\nconst CLASS_NAME_BACKDROP = 'offcanvas-backdrop';\nconst OPEN_SELECTOR = '.offcanvas.show';\nconst EVENT_SHOW$3 = `show${EVENT_KEY$3}`;\nconst EVENT_SHOWN$3 = `shown${EVENT_KEY$3}`;\nconst EVENT_HIDE$3 = `hide${EVENT_KEY$3}`;\nconst EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY$3}`;\nconst EVENT_HIDDEN$3 = `hidden${EVENT_KEY$3}`;\nconst EVENT_RESIZE = `resize${EVENT_KEY$3}`;\nconst EVENT_CLICK_DATA_API$1 = `click${EVENT_KEY$3}${DATA_API_KEY$1}`;\nconst EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY$3}`;\nconst SELECTOR_DATA_TOGGLE$1 = '[data-bs-toggle=\"offcanvas\"]';\nconst Default$5 = {\n backdrop: true,\n keyboard: true,\n scroll: false\n};\nconst DefaultType$5 = {\n backdrop: '(boolean|string)',\n keyboard: 'boolean',\n scroll: 'boolean'\n};\n\n/**\n * Class definition\n */\n\nclass Offcanvas extends BaseComponent {\n constructor(element, config) {\n super(element, config);\n this._isShown = false;\n this._backdrop = this._initializeBackDrop();\n this._focustrap = this._initializeFocusTrap();\n this._addEventListeners();\n }\n\n // Getters\n static get Default() {\n return Default$5;\n }\n static get DefaultType() {\n return DefaultType$5;\n }\n static get NAME() {\n return NAME$6;\n }\n\n // Public\n toggle(relatedTarget) {\n return this._isShown ? this.hide() : this.show(relatedTarget);\n }\n show(relatedTarget) {\n if (this._isShown) {\n return;\n }\n const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$3, {\n relatedTarget\n });\n if (showEvent.defaultPrevented) {\n return;\n }\n this._isShown = true;\n this._backdrop.show();\n if (!this._config.scroll) {\n new ScrollBarHelper().hide();\n }\n this._element.setAttribute('aria-modal', true);\n this._element.setAttribute('role', 'dialog');\n this._element.classList.add(CLASS_NAME_SHOWING$1);\n const completeCallBack = () => {\n if (!this._config.scroll || this._config.backdrop) {\n this._focustrap.activate();\n }\n this._element.classList.add(CLASS_NAME_SHOW$3);\n this._element.classList.remove(CLASS_NAME_SHOWING$1);\n EventHandler.trigger(this._element, EVENT_SHOWN$3, {\n relatedTarget\n });\n };\n this._queueCallback(completeCallBack, this._element, true);\n }\n hide() {\n if (!this._isShown) {\n return;\n }\n const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$3);\n if (hideEvent.defaultPrevented) {\n return;\n }\n this._focustrap.deactivate();\n this._element.blur();\n this._isShown = false;\n this._element.classList.add(CLASS_NAME_HIDING);\n this._backdrop.hide();\n const completeCallback = () => {\n this._element.classList.remove(CLASS_NAME_SHOW$3, CLASS_NAME_HIDING);\n this._element.removeAttribute('aria-modal');\n this._element.removeAttribute('role');\n if (!this._config.scroll) {\n new ScrollBarHelper().reset();\n }\n EventHandler.trigger(this._element, EVENT_HIDDEN$3);\n };\n this._queueCallback(completeCallback, this._element, true);\n }\n dispose() {\n this._backdrop.dispose();\n this._focustrap.deactivate();\n super.dispose();\n }\n\n // Private\n _initializeBackDrop() {\n const clickCallback = () => {\n if (this._config.backdrop === 'static') {\n EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED);\n return;\n }\n this.hide();\n };\n\n // 'static' option will be translated to true, and booleans will keep their value\n const isVisible = Boolean(this._config.backdrop);\n return new Backdrop({\n className: CLASS_NAME_BACKDROP,\n isVisible,\n isAnimated: true,\n rootElement: this._element.parentNode,\n clickCallback: isVisible ? clickCallback : null\n });\n }\n _initializeFocusTrap() {\n return new FocusTrap({\n trapElement: this._element\n });\n }\n _addEventListeners() {\n EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, event => {\n if (event.key !== ESCAPE_KEY) {\n return;\n }\n if (this._config.keyboard) {\n this.hide();\n return;\n }\n EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED);\n });\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Offcanvas.getOrCreateInstance(this, config);\n if (typeof config !== 'string') {\n return;\n }\n if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {\n throw new TypeError(`No method named \"${config}\"`);\n }\n data[config](this);\n });\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_CLICK_DATA_API$1, SELECTOR_DATA_TOGGLE$1, function (event) {\n const target = SelectorEngine.getElementFromSelector(this);\n if (['A', 'AREA'].includes(this.tagName)) {\n event.preventDefault();\n }\n if (isDisabled(this)) {\n return;\n }\n EventHandler.one(target, EVENT_HIDDEN$3, () => {\n // focus on trigger when it is closed\n if (isVisible(this)) {\n this.focus();\n }\n });\n\n // avoid conflict when clicking a toggler of an offcanvas, while another is open\n const alreadyOpen = SelectorEngine.findOne(OPEN_SELECTOR);\n if (alreadyOpen && alreadyOpen !== target) {\n Offcanvas.getInstance(alreadyOpen).hide();\n }\n const data = Offcanvas.getOrCreateInstance(target);\n data.toggle(this);\n});\nEventHandler.on(window, EVENT_LOAD_DATA_API$2, () => {\n for (const selector of SelectorEngine.find(OPEN_SELECTOR)) {\n Offcanvas.getOrCreateInstance(selector).show();\n }\n});\nEventHandler.on(window, EVENT_RESIZE, () => {\n for (const element of SelectorEngine.find('[aria-modal][class*=show][class*=offcanvas-]')) {\n if (getComputedStyle(element).position !== 'fixed') {\n Offcanvas.getOrCreateInstance(element).hide();\n }\n }\n});\nenableDismissTrigger(Offcanvas);\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Offcanvas);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap util/sanitizer.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n// js-docs-start allow-list\nconst ARIA_ATTRIBUTE_PATTERN = /^aria-[\\w-]*$/i;\nconst DefaultAllowlist = {\n // Global attributes allowed on any supplied element below.\n '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],\n a: ['target', 'href', 'title', 'rel'],\n area: [],\n b: [],\n br: [],\n col: [],\n code: [],\n div: [],\n em: [],\n hr: [],\n h1: [],\n h2: [],\n h3: [],\n h4: [],\n h5: [],\n h6: [],\n i: [],\n img: ['src', 'srcset', 'alt', 'title', 'width', 'height'],\n li: [],\n ol: [],\n p: [],\n pre: [],\n s: [],\n small: [],\n span: [],\n sub: [],\n sup: [],\n strong: [],\n u: [],\n ul: []\n};\n// js-docs-end allow-list\n\nconst uriAttributes = new Set(['background', 'cite', 'href', 'itemtype', 'longdesc', 'poster', 'src', 'xlink:href']);\n\n/**\n * A pattern that recognizes URLs that are safe wrt. XSS in URL navigation\n * contexts.\n *\n * Shout-out to Angular https://github.com/angular/angular/blob/15.2.8/packages/core/src/sanitization/url_sanitizer.ts#L38\n */\n// eslint-disable-next-line unicorn/better-regex\nconst SAFE_URL_PATTERN = /^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:/?#]*(?:[/?#]|$))/i;\nconst allowedAttribute = (attribute, allowedAttributeList) => {\n const attributeName = attribute.nodeName.toLowerCase();\n if (allowedAttributeList.includes(attributeName)) {\n if (uriAttributes.has(attributeName)) {\n return Boolean(SAFE_URL_PATTERN.test(attribute.nodeValue));\n }\n return true;\n }\n\n // Check if a regular expression validates the attribute.\n return allowedAttributeList.filter(attributeRegex => attributeRegex instanceof RegExp).some(regex => regex.test(attributeName));\n};\nfunction sanitizeHtml(unsafeHtml, allowList, sanitizeFunction) {\n if (!unsafeHtml.length) {\n return unsafeHtml;\n }\n if (sanitizeFunction && typeof sanitizeFunction === 'function') {\n return sanitizeFunction(unsafeHtml);\n }\n const domParser = new window.DOMParser();\n const createdDocument = domParser.parseFromString(unsafeHtml, 'text/html');\n const elements = [].concat(...createdDocument.body.querySelectorAll('*'));\n for (const element of elements) {\n const elementName = element.nodeName.toLowerCase();\n if (!Object.keys(allowList).includes(elementName)) {\n element.remove();\n continue;\n }\n const attributeList = [].concat(...element.attributes);\n const allowedAttributes = [].concat(allowList['*'] || [], allowList[elementName] || []);\n for (const attribute of attributeList) {\n if (!allowedAttribute(attribute, allowedAttributes)) {\n element.removeAttribute(attribute.nodeName);\n }\n }\n }\n return createdDocument.body.innerHTML;\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap util/template-factory.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$5 = 'TemplateFactory';\nconst Default$4 = {\n allowList: DefaultAllowlist,\n content: {},\n // { selector : text , selector2 : text2 , }\n extraClass: '',\n html: false,\n sanitize: true,\n sanitizeFn: null,\n template: '<div></div>'\n};\nconst DefaultType$4 = {\n allowList: 'object',\n content: 'object',\n extraClass: '(string|function)',\n html: 'boolean',\n sanitize: 'boolean',\n sanitizeFn: '(null|function)',\n template: 'string'\n};\nconst DefaultContentType = {\n entry: '(string|element|function|null)',\n selector: '(string|element)'\n};\n\n/**\n * Class definition\n */\n\nclass TemplateFactory extends Config {\n constructor(config) {\n super();\n this._config = this._getConfig(config);\n }\n\n // Getters\n static get Default() {\n return Default$4;\n }\n static get DefaultType() {\n return DefaultType$4;\n }\n static get NAME() {\n return NAME$5;\n }\n\n // Public\n getContent() {\n return Object.values(this._config.content).map(config => this._resolvePossibleFunction(config)).filter(Boolean);\n }\n hasContent() {\n return this.getContent().length > 0;\n }\n changeContent(content) {\n this._checkContent(content);\n this._config.content = {\n ...this._config.content,\n ...content\n };\n return this;\n }\n toHtml() {\n const templateWrapper = document.createElement('div');\n templateWrapper.innerHTML = this._maybeSanitize(this._config.template);\n for (const [selector, text] of Object.entries(this._config.content)) {\n this._setContent(templateWrapper, text, selector);\n }\n const template = templateWrapper.children[0];\n const extraClass = this._resolvePossibleFunction(this._config.extraClass);\n if (extraClass) {\n template.classList.add(...extraClass.split(' '));\n }\n return template;\n }\n\n // Private\n _typeCheckConfig(config) {\n super._typeCheckConfig(config);\n this._checkContent(config.content);\n }\n _checkContent(arg) {\n for (const [selector, content] of Object.entries(arg)) {\n super._typeCheckConfig({\n selector,\n entry: content\n }, DefaultContentType);\n }\n }\n _setContent(template, content, selector) {\n const templateElement = SelectorEngine.findOne(selector, template);\n if (!templateElement) {\n return;\n }\n content = this._resolvePossibleFunction(content);\n if (!content) {\n templateElement.remove();\n return;\n }\n if (isElement(content)) {\n this._putElementInTemplate(getElement(content), templateElement);\n return;\n }\n if (this._config.html) {\n templateElement.innerHTML = this._maybeSanitize(content);\n return;\n }\n templateElement.textContent = content;\n }\n _maybeSanitize(arg) {\n return this._config.sanitize ? sanitizeHtml(arg, this._config.allowList, this._config.sanitizeFn) : arg;\n }\n _resolvePossibleFunction(arg) {\n return execute(arg, [this]);\n }\n _putElementInTemplate(element, templateElement) {\n if (this._config.html) {\n templateElement.innerHTML = '';\n templateElement.append(element);\n return;\n }\n templateElement.textContent = element.textContent;\n }\n}\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap tooltip.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$4 = 'tooltip';\nconst DISALLOWED_ATTRIBUTES = new Set(['sanitize', 'allowList', 'sanitizeFn']);\nconst CLASS_NAME_FADE$2 = 'fade';\nconst CLASS_NAME_MODAL = 'modal';\nconst CLASS_NAME_SHOW$2 = 'show';\nconst SELECTOR_TOOLTIP_INNER = '.tooltip-inner';\nconst SELECTOR_MODAL = `.${CLASS_NAME_MODAL}`;\nconst EVENT_MODAL_HIDE = 'hide.bs.modal';\nconst TRIGGER_HOVER = 'hover';\nconst TRIGGER_FOCUS = 'focus';\nconst TRIGGER_CLICK = 'click';\nconst TRIGGER_MANUAL = 'manual';\nconst EVENT_HIDE$2 = 'hide';\nconst EVENT_HIDDEN$2 = 'hidden';\nconst EVENT_SHOW$2 = 'show';\nconst EVENT_SHOWN$2 = 'shown';\nconst EVENT_INSERTED = 'inserted';\nconst EVENT_CLICK$1 = 'click';\nconst EVENT_FOCUSIN$1 = 'focusin';\nconst EVENT_FOCUSOUT$1 = 'focusout';\nconst EVENT_MOUSEENTER = 'mouseenter';\nconst EVENT_MOUSELEAVE = 'mouseleave';\nconst AttachmentMap = {\n AUTO: 'auto',\n TOP: 'top',\n RIGHT: isRTL() ? 'left' : 'right',\n BOTTOM: 'bottom',\n LEFT: isRTL() ? 'right' : 'left'\n};\nconst Default$3 = {\n allowList: DefaultAllowlist,\n animation: true,\n boundary: 'clippingParents',\n container: false,\n customClass: '',\n delay: 0,\n fallbackPlacements: ['top', 'right', 'bottom', 'left'],\n html: false,\n offset: [0, 6],\n placement: 'top',\n popperConfig: null,\n sanitize: true,\n sanitizeFn: null,\n selector: false,\n template: '<div class=\"tooltip\" role=\"tooltip\">' + '<div class=\"tooltip-arrow\"></div>' + '<div class=\"tooltip-inner\"></div>' + '</div>',\n title: '',\n trigger: 'hover focus'\n};\nconst DefaultType$3 = {\n allowList: 'object',\n animation: 'boolean',\n boundary: '(string|element)',\n container: '(string|element|boolean)',\n customClass: '(string|function)',\n delay: '(number|object)',\n fallbackPlacements: 'array',\n html: 'boolean',\n offset: '(array|string|function)',\n placement: '(string|function)',\n popperConfig: '(null|object|function)',\n sanitize: 'boolean',\n sanitizeFn: '(null|function)',\n selector: '(string|boolean)',\n template: 'string',\n title: '(string|element|function)',\n trigger: 'string'\n};\n\n/**\n * Class definition\n */\n\nclass Tooltip extends BaseComponent {\n constructor(element, config) {\n if (typeof _popperjs_core__WEBPACK_IMPORTED_MODULE_0__ === 'undefined') {\n throw new TypeError('Bootstrap\\'s tooltips require Popper (https://popper.js.org)');\n }\n super(element, config);\n\n // Private\n this._isEnabled = true;\n this._timeout = 0;\n this._isHovered = null;\n this._activeTrigger = {};\n this._popper = null;\n this._templateFactory = null;\n this._newContent = null;\n\n // Protected\n this.tip = null;\n this._setListeners();\n if (!this._config.selector) {\n this._fixTitle();\n }\n }\n\n // Getters\n static get Default() {\n return Default$3;\n }\n static get DefaultType() {\n return DefaultType$3;\n }\n static get NAME() {\n return NAME$4;\n }\n\n // Public\n enable() {\n this._isEnabled = true;\n }\n disable() {\n this._isEnabled = false;\n }\n toggleEnabled() {\n this._isEnabled = !this._isEnabled;\n }\n toggle() {\n if (!this._isEnabled) {\n return;\n }\n this._activeTrigger.click = !this._activeTrigger.click;\n if (this._isShown()) {\n this._leave();\n return;\n }\n this._enter();\n }\n dispose() {\n clearTimeout(this._timeout);\n EventHandler.off(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler);\n if (this._element.getAttribute('data-bs-original-title')) {\n this._element.setAttribute('title', this._element.getAttribute('data-bs-original-title'));\n }\n this._disposePopper();\n super.dispose();\n }\n show() {\n if (this._element.style.display === 'none') {\n throw new Error('Please use show on visible elements');\n }\n if (!(this._isWithContent() && this._isEnabled)) {\n return;\n }\n const showEvent = EventHandler.trigger(this._element, this.constructor.eventName(EVENT_SHOW$2));\n const shadowRoot = findShadowRoot(this._element);\n const isInTheDom = (shadowRoot || this._element.ownerDocument.documentElement).contains(this._element);\n if (showEvent.defaultPrevented || !isInTheDom) {\n return;\n }\n\n // TODO: v6 remove this or make it optional\n this._disposePopper();\n const tip = this._getTipElement();\n this._element.setAttribute('aria-describedby', tip.getAttribute('id'));\n const {\n container\n } = this._config;\n if (!this._element.ownerDocument.documentElement.contains(this.tip)) {\n container.append(tip);\n EventHandler.trigger(this._element, this.constructor.eventName(EVENT_INSERTED));\n }\n this._popper = this._createPopper(tip);\n tip.classList.add(CLASS_NAME_SHOW$2);\n\n // If this is a touch-enabled device we add extra\n // empty mouseover listeners to the body's immediate children;\n // only needed because of broken event delegation on iOS\n // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html\n if ('ontouchstart' in document.documentElement) {\n for (const element of [].concat(...document.body.children)) {\n EventHandler.on(element, 'mouseover', noop);\n }\n }\n const complete = () => {\n EventHandler.trigger(this._element, this.constructor.eventName(EVENT_SHOWN$2));\n if (this._isHovered === false) {\n this._leave();\n }\n this._isHovered = false;\n };\n this._queueCallback(complete, this.tip, this._isAnimated());\n }\n hide() {\n if (!this._isShown()) {\n return;\n }\n const hideEvent = EventHandler.trigger(this._element, this.constructor.eventName(EVENT_HIDE$2));\n if (hideEvent.defaultPrevented) {\n return;\n }\n const tip = this._getTipElement();\n tip.classList.remove(CLASS_NAME_SHOW$2);\n\n // If this is a touch-enabled device we remove the extra\n // empty mouseover listeners we added for iOS support\n if ('ontouchstart' in document.documentElement) {\n for (const element of [].concat(...document.body.children)) {\n EventHandler.off(element, 'mouseover', noop);\n }\n }\n this._activeTrigger[TRIGGER_CLICK] = false;\n this._activeTrigger[TRIGGER_FOCUS] = false;\n this._activeTrigger[TRIGGER_HOVER] = false;\n this._isHovered = null; // it is a trick to support manual triggering\n\n const complete = () => {\n if (this._isWithActiveTrigger()) {\n return;\n }\n if (!this._isHovered) {\n this._disposePopper();\n }\n this._element.removeAttribute('aria-describedby');\n EventHandler.trigger(this._element, this.constructor.eventName(EVENT_HIDDEN$2));\n };\n this._queueCallback(complete, this.tip, this._isAnimated());\n }\n update() {\n if (this._popper) {\n this._popper.update();\n }\n }\n\n // Protected\n _isWithContent() {\n return Boolean(this._getTitle());\n }\n _getTipElement() {\n if (!this.tip) {\n this.tip = this._createTipElement(this._newContent || this._getContentForTemplate());\n }\n return this.tip;\n }\n _createTipElement(content) {\n const tip = this._getTemplateFactory(content).toHtml();\n\n // TODO: remove this check in v6\n if (!tip) {\n return null;\n }\n tip.classList.remove(CLASS_NAME_FADE$2, CLASS_NAME_SHOW$2);\n // TODO: v6 the following can be achieved with CSS only\n tip.classList.add(`bs-${this.constructor.NAME}-auto`);\n const tipId = getUID(this.constructor.NAME).toString();\n tip.setAttribute('id', tipId);\n if (this._isAnimated()) {\n tip.classList.add(CLASS_NAME_FADE$2);\n }\n return tip;\n }\n setContent(content) {\n this._newContent = content;\n if (this._isShown()) {\n this._disposePopper();\n this.show();\n }\n }\n _getTemplateFactory(content) {\n if (this._templateFactory) {\n this._templateFactory.changeContent(content);\n } else {\n this._templateFactory = new TemplateFactory({\n ...this._config,\n // the `content` var has to be after `this._config`\n // to override config.content in case of popover\n content,\n extraClass: this._resolvePossibleFunction(this._config.customClass)\n });\n }\n return this._templateFactory;\n }\n _getContentForTemplate() {\n return {\n [SELECTOR_TOOLTIP_INNER]: this._getTitle()\n };\n }\n _getTitle() {\n return this._resolvePossibleFunction(this._config.title) || this._element.getAttribute('data-bs-original-title');\n }\n\n // Private\n _initializeOnDelegatedTarget(event) {\n return this.constructor.getOrCreateInstance(event.delegateTarget, this._getDelegateConfig());\n }\n _isAnimated() {\n return this._config.animation || this.tip && this.tip.classList.contains(CLASS_NAME_FADE$2);\n }\n _isShown() {\n return this.tip && this.tip.classList.contains(CLASS_NAME_SHOW$2);\n }\n _createPopper(tip) {\n const placement = execute(this._config.placement, [this, tip, this._element]);\n const attachment = AttachmentMap[placement.toUpperCase()];\n return _popperjs_core__WEBPACK_IMPORTED_MODULE_1__.createPopper(this._element, tip, this._getPopperConfig(attachment));\n }\n _getOffset() {\n const {\n offset\n } = this._config;\n if (typeof offset === 'string') {\n return offset.split(',').map(value => Number.parseInt(value, 10));\n }\n if (typeof offset === 'function') {\n return popperData => offset(popperData, this._element);\n }\n return offset;\n }\n _resolvePossibleFunction(arg) {\n return execute(arg, [this._element]);\n }\n _getPopperConfig(attachment) {\n const defaultBsPopperConfig = {\n placement: attachment,\n modifiers: [{\n name: 'flip',\n options: {\n fallbackPlacements: this._config.fallbackPlacements\n }\n }, {\n name: 'offset',\n options: {\n offset: this._getOffset()\n }\n }, {\n name: 'preventOverflow',\n options: {\n boundary: this._config.boundary\n }\n }, {\n name: 'arrow',\n options: {\n element: `.${this.constructor.NAME}-arrow`\n }\n }, {\n name: 'preSetPlacement',\n enabled: true,\n phase: 'beforeMain',\n fn: data => {\n // Pre-set Popper's placement attribute in order to read the arrow sizes properly.\n // Otherwise, Popper mixes up the width and height dimensions since the initial arrow style is for top placement\n this._getTipElement().setAttribute('data-popper-placement', data.state.placement);\n }\n }]\n };\n return {\n ...defaultBsPopperConfig,\n ...execute(this._config.popperConfig, [defaultBsPopperConfig])\n };\n }\n _setListeners() {\n const triggers = this._config.trigger.split(' ');\n for (const trigger of triggers) {\n if (trigger === 'click') {\n EventHandler.on(this._element, this.constructor.eventName(EVENT_CLICK$1), this._config.selector, event => {\n const context = this._initializeOnDelegatedTarget(event);\n context.toggle();\n });\n } else if (trigger !== TRIGGER_MANUAL) {\n const eventIn = trigger === TRIGGER_HOVER ? this.constructor.eventName(EVENT_MOUSEENTER) : this.constructor.eventName(EVENT_FOCUSIN$1);\n const eventOut = trigger === TRIGGER_HOVER ? this.constructor.eventName(EVENT_MOUSELEAVE) : this.constructor.eventName(EVENT_FOCUSOUT$1);\n EventHandler.on(this._element, eventIn, this._config.selector, event => {\n const context = this._initializeOnDelegatedTarget(event);\n context._activeTrigger[event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER] = true;\n context._enter();\n });\n EventHandler.on(this._element, eventOut, this._config.selector, event => {\n const context = this._initializeOnDelegatedTarget(event);\n context._activeTrigger[event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER] = context._element.contains(event.relatedTarget);\n context._leave();\n });\n }\n }\n this._hideModalHandler = () => {\n if (this._element) {\n this.hide();\n }\n };\n EventHandler.on(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler);\n }\n _fixTitle() {\n const title = this._element.getAttribute('title');\n if (!title) {\n return;\n }\n if (!this._element.getAttribute('aria-label') && !this._element.textContent.trim()) {\n this._element.setAttribute('aria-label', title);\n }\n this._element.setAttribute('data-bs-original-title', title); // DO NOT USE IT. Is only for backwards compatibility\n this._element.removeAttribute('title');\n }\n _enter() {\n if (this._isShown() || this._isHovered) {\n this._isHovered = true;\n return;\n }\n this._isHovered = true;\n this._setTimeout(() => {\n if (this._isHovered) {\n this.show();\n }\n }, this._config.delay.show);\n }\n _leave() {\n if (this._isWithActiveTrigger()) {\n return;\n }\n this._isHovered = false;\n this._setTimeout(() => {\n if (!this._isHovered) {\n this.hide();\n }\n }, this._config.delay.hide);\n }\n _setTimeout(handler, timeout) {\n clearTimeout(this._timeout);\n this._timeout = setTimeout(handler, timeout);\n }\n _isWithActiveTrigger() {\n return Object.values(this._activeTrigger).includes(true);\n }\n _getConfig(config) {\n const dataAttributes = Manipulator.getDataAttributes(this._element);\n for (const dataAttribute of Object.keys(dataAttributes)) {\n if (DISALLOWED_ATTRIBUTES.has(dataAttribute)) {\n delete dataAttributes[dataAttribute];\n }\n }\n config = {\n ...dataAttributes,\n ...(typeof config === 'object' && config ? config : {})\n };\n config = this._mergeConfigObj(config);\n config = this._configAfterMerge(config);\n this._typeCheckConfig(config);\n return config;\n }\n _configAfterMerge(config) {\n config.container = config.container === false ? document.body : getElement(config.container);\n if (typeof config.delay === 'number') {\n config.delay = {\n show: config.delay,\n hide: config.delay\n };\n }\n if (typeof config.title === 'number') {\n config.title = config.title.toString();\n }\n if (typeof config.content === 'number') {\n config.content = config.content.toString();\n }\n return config;\n }\n _getDelegateConfig() {\n const config = {};\n for (const [key, value] of Object.entries(this._config)) {\n if (this.constructor.Default[key] !== value) {\n config[key] = value;\n }\n }\n config.selector = false;\n config.trigger = 'manual';\n\n // In the future can be replaced with:\n // const keysWithDifferentValues = Object.entries(this._config).filter(entry => this.constructor.Default[entry[0]] !== this._config[entry[0]])\n // `Object.fromEntries(keysWithDifferentValues)`\n return config;\n }\n _disposePopper() {\n if (this._popper) {\n this._popper.destroy();\n this._popper = null;\n }\n if (this.tip) {\n this.tip.remove();\n this.tip = null;\n }\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Tooltip.getOrCreateInstance(this, config);\n if (typeof config !== 'string') {\n return;\n }\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`);\n }\n data[config]();\n });\n }\n}\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Tooltip);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap popover.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$3 = 'popover';\nconst SELECTOR_TITLE = '.popover-header';\nconst SELECTOR_CONTENT = '.popover-body';\nconst Default$2 = {\n ...Tooltip.Default,\n content: '',\n offset: [0, 8],\n placement: 'right',\n template: '<div class=\"popover\" role=\"tooltip\">' + '<div class=\"popover-arrow\"></div>' + '<h3 class=\"popover-header\"></h3>' + '<div class=\"popover-body\"></div>' + '</div>',\n trigger: 'click'\n};\nconst DefaultType$2 = {\n ...Tooltip.DefaultType,\n content: '(null|string|element|function)'\n};\n\n/**\n * Class definition\n */\n\nclass Popover extends Tooltip {\n // Getters\n static get Default() {\n return Default$2;\n }\n static get DefaultType() {\n return DefaultType$2;\n }\n static get NAME() {\n return NAME$3;\n }\n\n // Overrides\n _isWithContent() {\n return this._getTitle() || this._getContent();\n }\n\n // Private\n _getContentForTemplate() {\n return {\n [SELECTOR_TITLE]: this._getTitle(),\n [SELECTOR_CONTENT]: this._getContent()\n };\n }\n _getContent() {\n return this._resolvePossibleFunction(this._config.content);\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Popover.getOrCreateInstance(this, config);\n if (typeof config !== 'string') {\n return;\n }\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`);\n }\n data[config]();\n });\n }\n}\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Popover);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap scrollspy.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$2 = 'scrollspy';\nconst DATA_KEY$2 = 'bs.scrollspy';\nconst EVENT_KEY$2 = `.${DATA_KEY$2}`;\nconst DATA_API_KEY = '.data-api';\nconst EVENT_ACTIVATE = `activate${EVENT_KEY$2}`;\nconst EVENT_CLICK = `click${EVENT_KEY$2}`;\nconst EVENT_LOAD_DATA_API$1 = `load${EVENT_KEY$2}${DATA_API_KEY}`;\nconst CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item';\nconst CLASS_NAME_ACTIVE$1 = 'active';\nconst SELECTOR_DATA_SPY = '[data-bs-spy=\"scroll\"]';\nconst SELECTOR_TARGET_LINKS = '[href]';\nconst SELECTOR_NAV_LIST_GROUP = '.nav, .list-group';\nconst SELECTOR_NAV_LINKS = '.nav-link';\nconst SELECTOR_NAV_ITEMS = '.nav-item';\nconst SELECTOR_LIST_ITEMS = '.list-group-item';\nconst SELECTOR_LINK_ITEMS = `${SELECTOR_NAV_LINKS}, ${SELECTOR_NAV_ITEMS} > ${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`;\nconst SELECTOR_DROPDOWN = '.dropdown';\nconst SELECTOR_DROPDOWN_TOGGLE$1 = '.dropdown-toggle';\nconst Default$1 = {\n offset: null,\n // TODO: v6 @deprecated, keep it for backwards compatibility reasons\n rootMargin: '0px 0px -25%',\n smoothScroll: false,\n target: null,\n threshold: [0.1, 0.5, 1]\n};\nconst DefaultType$1 = {\n offset: '(number|null)',\n // TODO v6 @deprecated, keep it for backwards compatibility reasons\n rootMargin: 'string',\n smoothScroll: 'boolean',\n target: 'element',\n threshold: 'array'\n};\n\n/**\n * Class definition\n */\n\nclass ScrollSpy extends BaseComponent {\n constructor(element, config) {\n super(element, config);\n\n // this._element is the observablesContainer and config.target the menu links wrapper\n this._targetLinks = new Map();\n this._observableSections = new Map();\n this._rootElement = getComputedStyle(this._element).overflowY === 'visible' ? null : this._element;\n this._activeTarget = null;\n this._observer = null;\n this._previousScrollData = {\n visibleEntryTop: 0,\n parentScrollTop: 0\n };\n this.refresh(); // initialize\n }\n\n // Getters\n static get Default() {\n return Default$1;\n }\n static get DefaultType() {\n return DefaultType$1;\n }\n static get NAME() {\n return NAME$2;\n }\n\n // Public\n refresh() {\n this._initializeTargetsAndObservables();\n this._maybeEnableSmoothScroll();\n if (this._observer) {\n this._observer.disconnect();\n } else {\n this._observer = this._getNewObserver();\n }\n for (const section of this._observableSections.values()) {\n this._observer.observe(section);\n }\n }\n dispose() {\n this._observer.disconnect();\n super.dispose();\n }\n\n // Private\n _configAfterMerge(config) {\n // TODO: on v6 target should be given explicitly & remove the {target: 'ss-target'} case\n config.target = getElement(config.target) || document.body;\n\n // TODO: v6 Only for backwards compatibility reasons. Use rootMargin only\n config.rootMargin = config.offset ? `${config.offset}px 0px -30%` : config.rootMargin;\n if (typeof config.threshold === 'string') {\n config.threshold = config.threshold.split(',').map(value => Number.parseFloat(value));\n }\n return config;\n }\n _maybeEnableSmoothScroll() {\n if (!this._config.smoothScroll) {\n return;\n }\n\n // unregister any previous listeners\n EventHandler.off(this._config.target, EVENT_CLICK);\n EventHandler.on(this._config.target, EVENT_CLICK, SELECTOR_TARGET_LINKS, event => {\n const observableSection = this._observableSections.get(event.target.hash);\n if (observableSection) {\n event.preventDefault();\n const root = this._rootElement || window;\n const height = observableSection.offsetTop - this._element.offsetTop;\n if (root.scrollTo) {\n root.scrollTo({\n top: height,\n behavior: 'smooth'\n });\n return;\n }\n\n // Chrome 60 doesn't support `scrollTo`\n root.scrollTop = height;\n }\n });\n }\n _getNewObserver() {\n const options = {\n root: this._rootElement,\n threshold: this._config.threshold,\n rootMargin: this._config.rootMargin\n };\n return new IntersectionObserver(entries => this._observerCallback(entries), options);\n }\n\n // The logic of selection\n _observerCallback(entries) {\n const targetElement = entry => this._targetLinks.get(`#${entry.target.id}`);\n const activate = entry => {\n this._previousScrollData.visibleEntryTop = entry.target.offsetTop;\n this._process(targetElement(entry));\n };\n const parentScrollTop = (this._rootElement || document.documentElement).scrollTop;\n const userScrollsDown = parentScrollTop >= this._previousScrollData.parentScrollTop;\n this._previousScrollData.parentScrollTop = parentScrollTop;\n for (const entry of entries) {\n if (!entry.isIntersecting) {\n this._activeTarget = null;\n this._clearActiveClass(targetElement(entry));\n continue;\n }\n const entryIsLowerThanPrevious = entry.target.offsetTop >= this._previousScrollData.visibleEntryTop;\n // if we are scrolling down, pick the bigger offsetTop\n if (userScrollsDown && entryIsLowerThanPrevious) {\n activate(entry);\n // if parent isn't scrolled, let's keep the first visible item, breaking the iteration\n if (!parentScrollTop) {\n return;\n }\n continue;\n }\n\n // if we are scrolling up, pick the smallest offsetTop\n if (!userScrollsDown && !entryIsLowerThanPrevious) {\n activate(entry);\n }\n }\n }\n _initializeTargetsAndObservables() {\n this._targetLinks = new Map();\n this._observableSections = new Map();\n const targetLinks = SelectorEngine.find(SELECTOR_TARGET_LINKS, this._config.target);\n for (const anchor of targetLinks) {\n // ensure that the anchor has an id and is not disabled\n if (!anchor.hash || isDisabled(anchor)) {\n continue;\n }\n const observableSection = SelectorEngine.findOne(decodeURI(anchor.hash), this._element);\n\n // ensure that the observableSection exists & is visible\n if (isVisible(observableSection)) {\n this._targetLinks.set(decodeURI(anchor.hash), anchor);\n this._observableSections.set(anchor.hash, observableSection);\n }\n }\n }\n _process(target) {\n if (this._activeTarget === target) {\n return;\n }\n this._clearActiveClass(this._config.target);\n this._activeTarget = target;\n target.classList.add(CLASS_NAME_ACTIVE$1);\n this._activateParents(target);\n EventHandler.trigger(this._element, EVENT_ACTIVATE, {\n relatedTarget: target\n });\n }\n _activateParents(target) {\n // Activate dropdown parents\n if (target.classList.contains(CLASS_NAME_DROPDOWN_ITEM)) {\n SelectorEngine.findOne(SELECTOR_DROPDOWN_TOGGLE$1, target.closest(SELECTOR_DROPDOWN)).classList.add(CLASS_NAME_ACTIVE$1);\n return;\n }\n for (const listGroup of SelectorEngine.parents(target, SELECTOR_NAV_LIST_GROUP)) {\n // Set triggered links parents as active\n // With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor\n for (const item of SelectorEngine.prev(listGroup, SELECTOR_LINK_ITEMS)) {\n item.classList.add(CLASS_NAME_ACTIVE$1);\n }\n }\n }\n _clearActiveClass(parent) {\n parent.classList.remove(CLASS_NAME_ACTIVE$1);\n const activeNodes = SelectorEngine.find(`${SELECTOR_TARGET_LINKS}.${CLASS_NAME_ACTIVE$1}`, parent);\n for (const node of activeNodes) {\n node.classList.remove(CLASS_NAME_ACTIVE$1);\n }\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = ScrollSpy.getOrCreateInstance(this, config);\n if (typeof config !== 'string') {\n return;\n }\n if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {\n throw new TypeError(`No method named \"${config}\"`);\n }\n data[config]();\n });\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(window, EVENT_LOAD_DATA_API$1, () => {\n for (const spy of SelectorEngine.find(SELECTOR_DATA_SPY)) {\n ScrollSpy.getOrCreateInstance(spy);\n }\n});\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(ScrollSpy);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap tab.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME$1 = 'tab';\nconst DATA_KEY$1 = 'bs.tab';\nconst EVENT_KEY$1 = `.${DATA_KEY$1}`;\nconst EVENT_HIDE$1 = `hide${EVENT_KEY$1}`;\nconst EVENT_HIDDEN$1 = `hidden${EVENT_KEY$1}`;\nconst EVENT_SHOW$1 = `show${EVENT_KEY$1}`;\nconst EVENT_SHOWN$1 = `shown${EVENT_KEY$1}`;\nconst EVENT_CLICK_DATA_API = `click${EVENT_KEY$1}`;\nconst EVENT_KEYDOWN = `keydown${EVENT_KEY$1}`;\nconst EVENT_LOAD_DATA_API = `load${EVENT_KEY$1}`;\nconst ARROW_LEFT_KEY = 'ArrowLeft';\nconst ARROW_RIGHT_KEY = 'ArrowRight';\nconst ARROW_UP_KEY = 'ArrowUp';\nconst ARROW_DOWN_KEY = 'ArrowDown';\nconst CLASS_NAME_ACTIVE = 'active';\nconst CLASS_NAME_FADE$1 = 'fade';\nconst CLASS_NAME_SHOW$1 = 'show';\nconst CLASS_DROPDOWN = 'dropdown';\nconst SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle';\nconst SELECTOR_DROPDOWN_MENU = '.dropdown-menu';\nconst NOT_SELECTOR_DROPDOWN_TOGGLE = ':not(.dropdown-toggle)';\nconst SELECTOR_TAB_PANEL = '.list-group, .nav, [role=\"tablist\"]';\nconst SELECTOR_OUTER = '.nav-item, .list-group-item';\nconst SELECTOR_INNER = `.nav-link${NOT_SELECTOR_DROPDOWN_TOGGLE}, .list-group-item${NOT_SELECTOR_DROPDOWN_TOGGLE}, [role=\"tab\"]${NOT_SELECTOR_DROPDOWN_TOGGLE}`;\nconst SELECTOR_DATA_TOGGLE = '[data-bs-toggle=\"tab\"], [data-bs-toggle=\"pill\"], [data-bs-toggle=\"list\"]'; // TODO: could only be `tab` in v6\nconst SELECTOR_INNER_ELEM = `${SELECTOR_INNER}, ${SELECTOR_DATA_TOGGLE}`;\nconst SELECTOR_DATA_TOGGLE_ACTIVE = `.${CLASS_NAME_ACTIVE}[data-bs-toggle=\"tab\"], .${CLASS_NAME_ACTIVE}[data-bs-toggle=\"pill\"], .${CLASS_NAME_ACTIVE}[data-bs-toggle=\"list\"]`;\n\n/**\n * Class definition\n */\n\nclass Tab extends BaseComponent {\n constructor(element) {\n super(element);\n this._parent = this._element.closest(SELECTOR_TAB_PANEL);\n if (!this._parent) {\n return;\n // TODO: should throw exception in v6\n // throw new TypeError(`${element.outerHTML} has not a valid parent ${SELECTOR_INNER_ELEM}`)\n }\n\n // Set up initial aria attributes\n this._setInitialAttributes(this._parent, this._getChildren());\n EventHandler.on(this._element, EVENT_KEYDOWN, event => this._keydown(event));\n }\n\n // Getters\n static get NAME() {\n return NAME$1;\n }\n\n // Public\n show() {\n // Shows this elem and deactivate the active sibling if exists\n const innerElem = this._element;\n if (this._elemIsActive(innerElem)) {\n return;\n }\n\n // Search for active tab on same parent to deactivate it\n const active = this._getActiveElem();\n const hideEvent = active ? EventHandler.trigger(active, EVENT_HIDE$1, {\n relatedTarget: innerElem\n }) : null;\n const showEvent = EventHandler.trigger(innerElem, EVENT_SHOW$1, {\n relatedTarget: active\n });\n if (showEvent.defaultPrevented || hideEvent && hideEvent.defaultPrevented) {\n return;\n }\n this._deactivate(active, innerElem);\n this._activate(innerElem, active);\n }\n\n // Private\n _activate(element, relatedElem) {\n if (!element) {\n return;\n }\n element.classList.add(CLASS_NAME_ACTIVE);\n this._activate(SelectorEngine.getElementFromSelector(element)); // Search and activate/show the proper section\n\n const complete = () => {\n if (element.getAttribute('role') !== 'tab') {\n element.classList.add(CLASS_NAME_SHOW$1);\n return;\n }\n element.removeAttribute('tabindex');\n element.setAttribute('aria-selected', true);\n this._toggleDropDown(element, true);\n EventHandler.trigger(element, EVENT_SHOWN$1, {\n relatedTarget: relatedElem\n });\n };\n this._queueCallback(complete, element, element.classList.contains(CLASS_NAME_FADE$1));\n }\n _deactivate(element, relatedElem) {\n if (!element) {\n return;\n }\n element.classList.remove(CLASS_NAME_ACTIVE);\n element.blur();\n this._deactivate(SelectorEngine.getElementFromSelector(element)); // Search and deactivate the shown section too\n\n const complete = () => {\n if (element.getAttribute('role') !== 'tab') {\n element.classList.remove(CLASS_NAME_SHOW$1);\n return;\n }\n element.setAttribute('aria-selected', false);\n element.setAttribute('tabindex', '-1');\n this._toggleDropDown(element, false);\n EventHandler.trigger(element, EVENT_HIDDEN$1, {\n relatedTarget: relatedElem\n });\n };\n this._queueCallback(complete, element, element.classList.contains(CLASS_NAME_FADE$1));\n }\n _keydown(event) {\n if (![ARROW_LEFT_KEY, ARROW_RIGHT_KEY, ARROW_UP_KEY, ARROW_DOWN_KEY].includes(event.key)) {\n return;\n }\n event.stopPropagation(); // stopPropagation/preventDefault both added to support up/down keys without scrolling the page\n event.preventDefault();\n const isNext = [ARROW_RIGHT_KEY, ARROW_DOWN_KEY].includes(event.key);\n const nextActiveElement = getNextActiveElement(this._getChildren().filter(element => !isDisabled(element)), event.target, isNext, true);\n if (nextActiveElement) {\n nextActiveElement.focus({\n preventScroll: true\n });\n Tab.getOrCreateInstance(nextActiveElement).show();\n }\n }\n _getChildren() {\n // collection of inner elements\n return SelectorEngine.find(SELECTOR_INNER_ELEM, this._parent);\n }\n _getActiveElem() {\n return this._getChildren().find(child => this._elemIsActive(child)) || null;\n }\n _setInitialAttributes(parent, children) {\n this._setAttributeIfNotExists(parent, 'role', 'tablist');\n for (const child of children) {\n this._setInitialAttributesOnChild(child);\n }\n }\n _setInitialAttributesOnChild(child) {\n child = this._getInnerElement(child);\n const isActive = this._elemIsActive(child);\n const outerElem = this._getOuterElement(child);\n child.setAttribute('aria-selected', isActive);\n if (outerElem !== child) {\n this._setAttributeIfNotExists(outerElem, 'role', 'presentation');\n }\n if (!isActive) {\n child.setAttribute('tabindex', '-1');\n }\n this._setAttributeIfNotExists(child, 'role', 'tab');\n\n // set attributes to the related panel too\n this._setInitialAttributesOnTargetPanel(child);\n }\n _setInitialAttributesOnTargetPanel(child) {\n const target = SelectorEngine.getElementFromSelector(child);\n if (!target) {\n return;\n }\n this._setAttributeIfNotExists(target, 'role', 'tabpanel');\n if (child.id) {\n this._setAttributeIfNotExists(target, 'aria-labelledby', `${child.id}`);\n }\n }\n _toggleDropDown(element, open) {\n const outerElem = this._getOuterElement(element);\n if (!outerElem.classList.contains(CLASS_DROPDOWN)) {\n return;\n }\n const toggle = (selector, className) => {\n const element = SelectorEngine.findOne(selector, outerElem);\n if (element) {\n element.classList.toggle(className, open);\n }\n };\n toggle(SELECTOR_DROPDOWN_TOGGLE, CLASS_NAME_ACTIVE);\n toggle(SELECTOR_DROPDOWN_MENU, CLASS_NAME_SHOW$1);\n outerElem.setAttribute('aria-expanded', open);\n }\n _setAttributeIfNotExists(element, attribute, value) {\n if (!element.hasAttribute(attribute)) {\n element.setAttribute(attribute, value);\n }\n }\n _elemIsActive(elem) {\n return elem.classList.contains(CLASS_NAME_ACTIVE);\n }\n\n // Try to get the inner element (usually the .nav-link)\n _getInnerElement(elem) {\n return elem.matches(SELECTOR_INNER_ELEM) ? elem : SelectorEngine.findOne(SELECTOR_INNER_ELEM, elem);\n }\n\n // Try to get the outer element (usually the .nav-item)\n _getOuterElement(elem) {\n return elem.closest(SELECTOR_OUTER) || elem;\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Tab.getOrCreateInstance(this);\n if (typeof config !== 'string') {\n return;\n }\n if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {\n throw new TypeError(`No method named \"${config}\"`);\n }\n data[config]();\n });\n }\n}\n\n/**\n * Data API implementation\n */\n\nEventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {\n if (['A', 'AREA'].includes(this.tagName)) {\n event.preventDefault();\n }\n if (isDisabled(this)) {\n return;\n }\n Tab.getOrCreateInstance(this).show();\n});\n\n/**\n * Initialize on focus\n */\nEventHandler.on(window, EVENT_LOAD_DATA_API, () => {\n for (const element of SelectorEngine.find(SELECTOR_DATA_TOGGLE_ACTIVE)) {\n Tab.getOrCreateInstance(element);\n }\n});\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Tab);\n\n/**\n * --------------------------------------------------------------------------\n * Bootstrap toast.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n\n/**\n * Constants\n */\n\nconst NAME = 'toast';\nconst DATA_KEY = 'bs.toast';\nconst EVENT_KEY = `.${DATA_KEY}`;\nconst EVENT_MOUSEOVER = `mouseover${EVENT_KEY}`;\nconst EVENT_MOUSEOUT = `mouseout${EVENT_KEY}`;\nconst EVENT_FOCUSIN = `focusin${EVENT_KEY}`;\nconst EVENT_FOCUSOUT = `focusout${EVENT_KEY}`;\nconst EVENT_HIDE = `hide${EVENT_KEY}`;\nconst EVENT_HIDDEN = `hidden${EVENT_KEY}`;\nconst EVENT_SHOW = `show${EVENT_KEY}`;\nconst EVENT_SHOWN = `shown${EVENT_KEY}`;\nconst CLASS_NAME_FADE = 'fade';\nconst CLASS_NAME_HIDE = 'hide'; // @deprecated - kept here only for backwards compatibility\nconst CLASS_NAME_SHOW = 'show';\nconst CLASS_NAME_SHOWING = 'showing';\nconst DefaultType = {\n animation: 'boolean',\n autohide: 'boolean',\n delay: 'number'\n};\nconst Default = {\n animation: true,\n autohide: true,\n delay: 5000\n};\n\n/**\n * Class definition\n */\n\nclass Toast extends BaseComponent {\n constructor(element, config) {\n super(element, config);\n this._timeout = null;\n this._hasMouseInteraction = false;\n this._hasKeyboardInteraction = false;\n this._setListeners();\n }\n\n // Getters\n static get Default() {\n return Default;\n }\n static get DefaultType() {\n return DefaultType;\n }\n static get NAME() {\n return NAME;\n }\n\n // Public\n show() {\n const showEvent = EventHandler.trigger(this._element, EVENT_SHOW);\n if (showEvent.defaultPrevented) {\n return;\n }\n this._clearTimeout();\n if (this._config.animation) {\n this._element.classList.add(CLASS_NAME_FADE);\n }\n const complete = () => {\n this._element.classList.remove(CLASS_NAME_SHOWING);\n EventHandler.trigger(this._element, EVENT_SHOWN);\n this._maybeScheduleHide();\n };\n this._element.classList.remove(CLASS_NAME_HIDE); // @deprecated\n reflow(this._element);\n this._element.classList.add(CLASS_NAME_SHOW, CLASS_NAME_SHOWING);\n this._queueCallback(complete, this._element, this._config.animation);\n }\n hide() {\n if (!this.isShown()) {\n return;\n }\n const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE);\n if (hideEvent.defaultPrevented) {\n return;\n }\n const complete = () => {\n this._element.classList.add(CLASS_NAME_HIDE); // @deprecated\n this._element.classList.remove(CLASS_NAME_SHOWING, CLASS_NAME_SHOW);\n EventHandler.trigger(this._element, EVENT_HIDDEN);\n };\n this._element.classList.add(CLASS_NAME_SHOWING);\n this._queueCallback(complete, this._element, this._config.animation);\n }\n dispose() {\n this._clearTimeout();\n if (this.isShown()) {\n this._element.classList.remove(CLASS_NAME_SHOW);\n }\n super.dispose();\n }\n isShown() {\n return this._element.classList.contains(CLASS_NAME_SHOW);\n }\n\n // Private\n\n _maybeScheduleHide() {\n if (!this._config.autohide) {\n return;\n }\n if (this._hasMouseInteraction || this._hasKeyboardInteraction) {\n return;\n }\n this._timeout = setTimeout(() => {\n this.hide();\n }, this._config.delay);\n }\n _onInteraction(event, isInteracting) {\n switch (event.type) {\n case 'mouseover':\n case 'mouseout':\n {\n this._hasMouseInteraction = isInteracting;\n break;\n }\n case 'focusin':\n case 'focusout':\n {\n this._hasKeyboardInteraction = isInteracting;\n break;\n }\n }\n if (isInteracting) {\n this._clearTimeout();\n return;\n }\n const nextElement = event.relatedTarget;\n if (this._element === nextElement || this._element.contains(nextElement)) {\n return;\n }\n this._maybeScheduleHide();\n }\n _setListeners() {\n EventHandler.on(this._element, EVENT_MOUSEOVER, event => this._onInteraction(event, true));\n EventHandler.on(this._element, EVENT_MOUSEOUT, event => this._onInteraction(event, false));\n EventHandler.on(this._element, EVENT_FOCUSIN, event => this._onInteraction(event, true));\n EventHandler.on(this._element, EVENT_FOCUSOUT, event => this._onInteraction(event, false));\n }\n _clearTimeout() {\n clearTimeout(this._timeout);\n this._timeout = null;\n }\n\n // Static\n static jQueryInterface(config) {\n return this.each(function () {\n const data = Toast.getOrCreateInstance(this, config);\n if (typeof config === 'string') {\n if (typeof data[config] === 'undefined') {\n throw new TypeError(`No method named \"${config}\"`);\n }\n data[config](this);\n }\n });\n }\n}\n\n/**\n * Data API implementation\n */\n\nenableDismissTrigger(Toast);\n\n/**\n * jQuery\n */\n\ndefineJQueryPlugin(Toast);\n\n\n//# sourceMappingURL=bootstrap.esm.js.map\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvYm9vdHN0cmFwL2Rpc3QvanMvYm9vdHN0cmFwLmVzbS5qcyIsIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDeUM7O0FBRXpDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtR0FBbUcsa0NBQWtDO0FBQ3JJO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsV0FBVyxRQUFRO0FBQ25CLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9FQUFvRSxlQUFlO0FBQ25GO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLE9BQU87QUFDckI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLGFBQWE7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdCQUF3QjtBQUN4Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsV0FBVyxPQUFPO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBLFlBQVksY0FBYztBQUMxQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLDBCQUEwQjtBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsbUJBQW1CLElBQUksSUFBSSxXQUFXO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU0sU0FBUywyQkFBMkI7QUFDMUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrREFBK0Q7QUFDL0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQ0FBa0M7QUFDbEM7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBDQUEwQyxrQkFBa0I7QUFDNUQ7QUFDQTtBQUNBO0FBQ0Esb0NBQW9DLHNCQUFzQjtBQUMxRCxHQUFHO0FBQ0g7QUFDQSx1Q0FBdUMsc0JBQXNCO0FBQzdELEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSx5REFBeUQsc0JBQXNCO0FBQy9FO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0dBQWtHOztBQUVsRztBQUNBO0FBQ0EsMERBQTBEO0FBQzFELDBFQUEwRTtBQUMxRSxrREFBa0Q7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrQkFBK0Isb0NBQW9DLFlBQVksU0FBUyxtQkFBbUIsVUFBVSx1QkFBdUIsY0FBYztBQUMxSjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaURBQWlEO0FBQ2pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixVQUFVO0FBQzNCO0FBQ0E7QUFDQSxlQUFlLGNBQWM7QUFDN0I7QUFDQTtBQUNBLGNBQWMsS0FBSyxFQUFFLGVBQWU7QUFDcEM7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDBCQUEwQiw0QkFBNEI7QUFDdEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsK0JBQStCO0FBQy9CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLDhJQUE4SSxTQUFTO0FBQ3ZKO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxxQ0FBcUMsb0JBQW9CO0FBQ3pEO0FBQ0EsNkRBQTZELEtBQUs7QUFDbEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUZBQW1GLEtBQUs7QUFDeEY7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esd0JBQXdCLFdBQVc7QUFDbkMsNEJBQTRCLFlBQVk7QUFDeEMsOEJBQThCLFlBQVk7QUFDMUM7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdEQUFnRCxPQUFPO0FBQ3ZEO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSx3QkFBd0IsV0FBVztBQUNuQztBQUNBO0FBQ0E7QUFDQSx1Q0FBdUMsWUFBWSxFQUFFLGVBQWU7O0FBRXBFO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxzQ0FBc0MsWUFBWTtBQUNsRCxvQ0FBb0MsWUFBWTtBQUNoRCxrQ0FBa0MsWUFBWTtBQUM5Qyx3Q0FBd0MsWUFBWTtBQUNwRCxvQ0FBb0MsWUFBWTtBQUNoRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSx3QkFBd0IsV0FBVztBQUNuQztBQUNBO0FBQ0E7QUFDQSxvQ0FBb0M7O0FBRXBDO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCLFlBQVk7QUFDeEMsMEJBQTBCLFlBQVk7QUFDdEMsa0NBQWtDLFlBQVk7QUFDOUMsd0NBQXdDLFlBQVk7QUFDcEQsd0NBQXdDLFlBQVk7QUFDcEQscUNBQXFDLFlBQVk7QUFDakQscUNBQXFDLFlBQVksRUFBRSxlQUFlO0FBQ2xFLHVDQUF1QyxZQUFZLEVBQUUsZUFBZTtBQUNwRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRFQUE0RSxNQUFNO0FBQ2xGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrREFBa0QsT0FBTztBQUN6RDtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLHdCQUF3QixXQUFXO0FBQ25DO0FBQ0EsNEJBQTRCLFlBQVk7QUFDeEMsOEJBQThCLFlBQVk7QUFDMUMsNEJBQTRCLFlBQVk7QUFDeEMsZ0NBQWdDLFlBQVk7QUFDNUMsdUNBQXVDLFlBQVksRUFBRSxlQUFlO0FBQ3BFO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsOENBQThDLHFCQUFxQixHQUFHLG9CQUFvQjtBQUMxRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0MscUJBQXFCO0FBQ3JEO0FBQ0Esd0NBQXdDLDBCQUEwQjtBQUNsRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdDQUF3QyxpREFBaUQ7QUFDekY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDRDQUE0QztBQUM1QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0RBQWtELE9BQU87QUFDekQ7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esd0JBQXdCLFdBQVc7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDhCQUE4Qjs7QUFFOUIsNEJBQTRCLFlBQVk7QUFDeEMsZ0NBQWdDLFlBQVk7QUFDNUMsNEJBQTRCLFlBQVk7QUFDeEMsOEJBQThCLFlBQVk7QUFDMUMsdUNBQXVDLFlBQVksRUFBRSxlQUFlO0FBQ3BFLHlDQUF5QyxZQUFZLEVBQUUsZUFBZTtBQUN0RSxxQ0FBcUMsWUFBWSxFQUFFLGVBQWU7QUFDbEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQ0FBc0MsdUJBQXVCLEdBQUcsa0JBQWtCO0FBQ2xGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZDQUE2QztBQUM3QztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkIscUJBQXFCO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSwyQ0FBTTtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQix3REFBbUI7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQOztBQUVBO0FBQ0E7QUFDQSxvRUFBb0U7QUFDcEU7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0RBQWdELE9BQU87QUFDdkQ7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLHdDQUF3QyxPQUFPO0FBQy9DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esd0JBQXdCLFdBQVc7QUFDbkMsa0NBQWtDLFlBQVk7QUFDOUMsd0NBQXdDLFlBQVk7QUFDcEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2Q0FBNkM7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtEQUFrRCw2Q0FBNkM7QUFDL0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUVBQXFFO0FBQ3JFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSx3QkFBd0IsV0FBVztBQUNuQztBQUNBO0FBQ0EsNEJBQTRCLFlBQVk7QUFDeEMsK0NBQStDLFlBQVk7QUFDM0QsZ0NBQWdDLFlBQVk7QUFDNUMsNEJBQTRCLFlBQVk7QUFDeEMsOEJBQThCLFlBQVk7QUFDMUMsZ0NBQWdDLFlBQVk7QUFDNUMsNENBQTRDLFlBQVk7QUFDeEQsb0RBQW9ELFlBQVk7QUFDaEUsa0RBQWtELFlBQVk7QUFDOUQsdUNBQXVDLFlBQVksRUFBRSxlQUFlO0FBQ3BFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUCxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseUNBQXlDLGVBQWU7QUFDeEQ7QUFDQTtBQUNBO0FBQ0EseUNBQXlDLGVBQWU7QUFDeEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnREFBZ0QsT0FBTztBQUN2RDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLHdCQUF3QixXQUFXO0FBQ25DO0FBQ0EscUNBQXFDLFlBQVksRUFBRSxlQUFlO0FBQ2xFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRCQUE0QixZQUFZO0FBQ3hDLDhCQUE4QixZQUFZO0FBQzFDLDRCQUE0QixZQUFZO0FBQ3hDLDZDQUE2QyxZQUFZO0FBQ3pELGdDQUFnQyxZQUFZO0FBQzVDLDhCQUE4QixZQUFZO0FBQzFDLHVDQUF1QyxZQUFZLEVBQUUsZUFBZTtBQUNwRSxnREFBZ0QsWUFBWTtBQUM1RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0RBQWdELE9BQU87QUFDdkQ7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyQkFBMkIsaUJBQWlCO0FBQzVDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGVBQWUsMkNBQU07QUFDckI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRCQUE0Qjs7QUFFNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEJBQTRCLHNCQUFzQjtBQUNsRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyx3REFBbUI7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBLHVCQUF1QixzQkFBc0I7QUFDN0M7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpRUFBaUU7QUFDakU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0REFBNEQ7QUFDNUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnREFBZ0QsT0FBTztBQUN2RDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0RBQWdELE9BQU87QUFDdkQ7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esd0JBQXdCLFdBQVc7QUFDbkM7QUFDQSxrQ0FBa0MsWUFBWTtBQUM5Qyw0QkFBNEIsWUFBWTtBQUN4QyxxQ0FBcUMsWUFBWSxFQUFFLGFBQWE7QUFDaEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtCQUErQixtQkFBbUIsSUFBSSxvQkFBb0IsSUFBSSxtQkFBbUIsSUFBSSxvQkFBb0I7QUFDekg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0I7QUFDcEI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxtRUFBbUUscUJBQXFCO0FBQ3hGOztBQUVBO0FBQ0EsMkNBQTJDLGNBQWM7QUFDekQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVc7QUFDWDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLDZEQUE2RCxnQkFBZ0I7QUFDN0U7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrQ0FBK0Msc0JBQXNCLEdBQUcsb0JBQW9CO0FBQzVGO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnREFBZ0QsT0FBTztBQUN2RDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLHdCQUF3QixXQUFXO0FBQ25DLDRCQUE0QixZQUFZO0FBQ3hDLGdDQUFnQyxZQUFZO0FBQzVDLDRCQUE0QixZQUFZO0FBQ3hDLDhCQUE4QixZQUFZO0FBQzFDLHFDQUFxQyxZQUFZO0FBQ2pELGdDQUFnQyxZQUFZO0FBQzVDLG1DQUFtQyxZQUFZO0FBQy9DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DLDZCQUE2QixvQkFBb0IsNkJBQTZCLGdCQUFnQiw2QkFBNkI7QUFDOUoseUdBQXlHO0FBQ3pHLCtCQUErQixlQUFlLElBQUkscUJBQXFCO0FBQ3ZFLHdDQUF3QyxrQkFBa0IsMkJBQTJCLGtCQUFrQiw0QkFBNEIsa0JBQWtCOztBQUVySjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0MsbUJBQW1CLHlCQUF5QixvQkFBb0I7QUFDaEc7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0VBQW9FOztBQUVwRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzRUFBc0U7O0FBRXRFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtFQUFrRSxTQUFTO0FBQzNFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnREFBZ0QsT0FBTztBQUN2RDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0Esc0JBQXNCLFNBQVM7QUFDL0Isb0NBQW9DLFVBQVU7QUFDOUMsa0NBQWtDLFVBQVU7QUFDNUMsZ0NBQWdDLFVBQVU7QUFDMUMsa0NBQWtDLFVBQVU7QUFDNUMsMEJBQTBCLFVBQVU7QUFDcEMsOEJBQThCLFVBQVU7QUFDeEMsMEJBQTBCLFVBQVU7QUFDcEMsNEJBQTRCLFVBQVU7QUFDdEM7QUFDQSxnQ0FBZ0M7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFEQUFxRDtBQUNyRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9EQUFvRDtBQUNwRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtEQUFrRCxPQUFPO0FBQ3pEO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRWtIO0FBQ2xIIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vLy4vbm9kZV9tb2R1bGVzL2Jvb3RzdHJhcC9kaXN0L2pzL2Jvb3RzdHJhcC5lc20uanM/MGE2NyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiFcbiAgKiBCb290c3RyYXAgdjUuMy4wIChodHRwczovL2dldGJvb3RzdHJhcC5jb20vKVxuICAqIENvcHlyaWdodCAyMDExLTIwMjMgVGhlIEJvb3RzdHJhcCBBdXRob3JzIChodHRwczovL2dpdGh1Yi5jb20vdHdicy9ib290c3RyYXAvZ3JhcGhzL2NvbnRyaWJ1dG9ycylcbiAgKiBMaWNlbnNlZCB1bmRlciBNSVQgKGh0dHBzOi8vZ2l0aHViLmNvbS90d2JzL2Jvb3RzdHJhcC9ibG9iL21haW4vTElDRU5TRSlcbiAgKi9cbmltcG9ydCAqIGFzIFBvcHBlciBmcm9tICdAcG9wcGVyanMvY29yZSc7XG5cbi8qKlxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIEJvb3RzdHJhcCBkb20vZGF0YS5qc1xuICogTGljZW5zZWQgdW5kZXIgTUlUIChodHRwczovL2dpdGh1Yi5jb20vdHdicy9ib290c3RyYXAvYmxvYi9tYWluL0xJQ0VOU0UpXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICovXG5cbi8qKlxuICogQ29uc3RhbnRzXG4gKi9cblxuY29uc3QgZWxlbWVudE1hcCA9IG5ldyBNYXAoKTtcbmNvbnN0IERhdGEgPSB7XG4gIHNldChlbGVtZW50LCBrZXksIGluc3RhbmNlKSB7XG4gICAgaWYgKCFlbGVtZW50TWFwLmhhcyhlbGVtZW50KSkge1xuICAgICAgZWxlbWVudE1hcC5zZXQoZWxlbWVudCwgbmV3IE1hcCgpKTtcbiAgICB9XG4gICAgY29uc3QgaW5zdGFuY2VNYXAgPSBlbGVtZW50TWFwLmdldChlbGVtZW50KTtcblxuICAgIC8vIG1ha2UgaXQgY2xlYXIgd2Ugb25seSB3YW50IG9uZSBpbnN0YW5jZSBwZXIgZWxlbWVudFxuICAgIC8vIGNhbiBiZSByZW1vdmVkIGxhdGVyIHdoZW4gbXVsdGlwbGUga2V5L2luc3RhbmNlcyBhcmUgZmluZSB0byBiZSB1c2VkXG4gICAgaWYgKCFpbnN0YW5jZU1hcC5oYXMoa2V5KSAmJiBpbnN0YW5jZU1hcC5zaXplICE9PSAwKSB7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICAgICAgY29uc29sZS5lcnJvcihgQm9vdHN0cmFwIGRvZXNuJ3QgYWxsb3cgbW9yZSB0aGFuIG9uZSBpbnN0YW5jZSBwZXIgZWxlbWVudC4gQm91bmQgaW5zdGFuY2U6ICR7QXJyYXkuZnJvbShpbnN0YW5jZU1hcC5rZXlzKCkpWzBdfS5gKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaW5zdGFuY2VNYXAuc2V0KGtleSwgaW5zdGFuY2UpO1xuICB9LFxuICBnZXQoZWxlbWVudCwga2V5KSB7XG4gICAgaWYgKGVsZW1lbnRNYXAuaGFzKGVsZW1lbnQpKSB7XG4gICAgICByZXR1cm4gZWxlbWVudE1hcC5nZXQoZWxlbWVudCkuZ2V0KGtleSkgfHwgbnVsbDtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH0sXG4gIHJlbW92ZShlbGVtZW50LCBrZXkpIHtcbiAgICBpZiAoIWVsZW1lbnRNYXAuaGFzKGVsZW1lbnQpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGluc3RhbmNlTWFwID0gZWxlbWVudE1hcC5nZXQoZWxlbWVudCk7XG4gICAgaW5zdGFuY2VNYXAuZGVsZXRlKGtleSk7XG5cbiAgICAvLyBmcmVlIHVwIGVsZW1lbnQgcmVmZXJlbmNlcyBpZiB0aGVyZSBhcmUgbm8gaW5zdGFuY2VzIGxlZnQgZm9yIGFuIGVsZW1lbnRcbiAgICBpZiAoaW5zdGFuY2VNYXAuc2l6ZSA9PT0gMCkge1xuICAgICAgZWxlbWVudE1hcC5kZWxldGUoZWxlbWVudCk7XG4gICAgfVxuICB9XG59O1xuXG4vKipcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiBCb290c3RyYXAgdXRpbC9pbmRleC5qc1xuICogTGljZW5zZWQgdW5kZXIgTUlUIChodHRwczovL2dpdGh1Yi5jb20vdHdicy9ib290c3RyYXAvYmxvYi9tYWluL0xJQ0VOU0UpXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICovXG5cbmNvbnN0IE1BWF9VSUQgPSAxMDAwMDAwO1xuY29uc3QgTUlMTElTRUNPTkRTX01VTFRJUExJRVIgPSAxMDAwO1xuY29uc3QgVFJBTlNJVElPTl9FTkQgPSAndHJhbnNpdGlvbmVuZCc7XG5cbi8qKlxuICogUHJvcGVybHkgZXNjYXBlIElEcyBzZWxlY3RvcnMgdG8gaGFuZGxlIHdlaXJkIElEc1xuICogQHBhcmFtIHtzdHJpbmd9IHNlbGVjdG9yXG4gKiBAcmV0dXJucyB7c3RyaW5nfVxuICovXG5jb25zdCBwYXJzZVNlbGVjdG9yID0gc2VsZWN0b3IgPT4ge1xuICBpZiAoc2VsZWN0b3IgJiYgd2luZG93LkNTUyAmJiB3aW5kb3cuQ1NTLmVzY2FwZSkge1xuICAgIC8vIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IgbmVlZHMgZXNjYXBpbmcgdG8gaGFuZGxlIElEcyAoaHRtbDUrKSBjb250YWluaW5nIGZvciBpbnN0YW5jZSAvXG4gICAgc2VsZWN0b3IgPSBzZWxlY3Rvci5yZXBsYWNlKC8jKFteXFxzXCIjJ10rKS9nLCAobWF0Y2gsIGlkKSA9PiBgIyR7Q1NTLmVzY2FwZShpZCl9YCk7XG4gIH1cbiAgcmV0dXJuIHNlbGVjdG9yO1xufTtcblxuLy8gU2hvdXQtb3V0IEFuZ3VzIENyb2xsIChodHRwczovL2dvby5nbC9weHdRR3ApXG5jb25zdCB0b1R5cGUgPSBvYmplY3QgPT4ge1xuICBpZiAob2JqZWN0ID09PSBudWxsIHx8IG9iamVjdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIGAke29iamVjdH1gO1xuICB9XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwob2JqZWN0KS5tYXRjaCgvXFxzKFthLXpdKykvaSlbMV0udG9Mb3dlckNhc2UoKTtcbn07XG5cbi8qKlxuICogUHVibGljIFV0aWwgQVBJXG4gKi9cblxuY29uc3QgZ2V0VUlEID0gcHJlZml4ID0+IHtcbiAgZG8ge1xuICAgIHByZWZpeCArPSBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBNQVhfVUlEKTtcbiAgfSB3aGlsZSAoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQocHJlZml4KSk7XG4gIHJldHVybiBwcmVmaXg7XG59O1xuY29uc3QgZ2V0VHJhbnNpdGlvbkR1cmF0aW9uRnJvbUVsZW1lbnQgPSBlbGVtZW50ID0+IHtcbiAgaWYgKCFlbGVtZW50KSB7XG4gICAgcmV0dXJuIDA7XG4gIH1cblxuICAvLyBHZXQgdHJhbnNpdGlvbi1kdXJhdGlvbiBvZiB0aGUgZWxlbWVudFxuICBsZXQge1xuICAgIHRyYW5zaXRpb25EdXJhdGlvbixcbiAgICB0cmFuc2l0aW9uRGVsYXlcbiAgfSA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpO1xuICBjb25zdCBmbG9hdFRyYW5zaXRpb25EdXJhdGlvbiA9IE51bWJlci5wYXJzZUZsb2F0KHRyYW5zaXRpb25EdXJhdGlvbik7XG4gIGNvbnN0IGZsb2F0VHJhbnNpdGlvbkRlbGF5ID0gTnVtYmVyLnBhcnNlRmxvYXQodHJhbnNpdGlvbkRlbGF5KTtcblxuICAvLyBSZXR1cm4gMCBpZiBlbGVtZW50IG9yIHRyYW5zaXRpb24gZHVyYXRpb24gaXMgbm90IGZvdW5kXG4gIGlmICghZmxvYXRUcmFuc2l0aW9uRHVyYXRpb24gJiYgIWZsb2F0VHJhbnNpdGlvbkRlbGF5KSB7XG4gICAgcmV0dXJuIDA7XG4gIH1cblxuICAvLyBJZiBtdWx0aXBsZSBkdXJhdGlvbnMgYXJlIGRlZmluZWQsIHRha2UgdGhlIGZpcnN0XG4gIHRyYW5zaXRpb25EdXJhdGlvbiA9IHRyYW5zaXRpb25EdXJhdGlvbi5zcGxpdCgnLCcpWzBdO1xuICB0cmFuc2l0aW9uRGVsYXkgPSB0cmFuc2l0aW9uRGVsYXkuc3BsaXQoJywnKVswXTtcbiAgcmV0dXJuIChOdW1iZXIucGFyc2VGbG9hdCh0cmFuc2l0aW9uRHVyYXRpb24pICsgTnVtYmVyLnBhcnNlRmxvYXQodHJhbnNpdGlvbkRlbGF5KSkgKiBNSUxMSVNFQ09ORFNfTVVMVElQTElFUjtcbn07XG5jb25zdCB0cmlnZ2VyVHJhbnNpdGlvbkVuZCA9IGVsZW1lbnQgPT4ge1xuICBlbGVtZW50LmRpc3BhdGNoRXZlbnQobmV3IEV2ZW50KFRSQU5TSVRJT05fRU5EKSk7XG59O1xuY29uc3QgaXNFbGVtZW50ID0gb2JqZWN0ID0+IHtcbiAgaWYgKCFvYmplY3QgfHwgdHlwZW9mIG9iamVjdCAhPT0gJ29iamVjdCcpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKHR5cGVvZiBvYmplY3QuanF1ZXJ5ICE9PSAndW5kZWZpbmVkJykge1xuICAgIG9iamVjdCA9IG9iamVjdFswXTtcbiAgfVxuICByZXR1cm4gdHlwZW9mIG9iamVjdC5ub2RlVHlwZSAhPT0gJ3VuZGVmaW5lZCc7XG59O1xuY29uc3QgZ2V0RWxlbWVudCA9IG9iamVjdCA9PiB7XG4gIC8vIGl0J3MgYSBqUXVlcnkgb2JqZWN0IG9yIGEgbm9kZSBlbGVtZW50XG4gIGlmIChpc0VsZW1lbnQob2JqZWN0KSkge1xuICAgIHJldHVybiBvYmplY3QuanF1ZXJ5ID8gb2JqZWN0WzBdIDogb2JqZWN0O1xuICB9XG4gIGlmICh0eXBlb2Ygb2JqZWN0ID09PSAnc3RyaW5nJyAmJiBvYmplY3QubGVuZ3RoID4gMCkge1xuICAgIHJldHVybiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHBhcnNlU2VsZWN0b3Iob2JqZWN0KSk7XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59O1xuY29uc3QgaXNWaXNpYmxlID0gZWxlbWVudCA9PiB7XG4gIGlmICghaXNFbGVtZW50KGVsZW1lbnQpIHx8IGVsZW1lbnQuZ2V0Q2xpZW50UmVjdHMoKS5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgY29uc3QgZWxlbWVudElzVmlzaWJsZSA9IGdldENvbXB1dGVkU3R5bGUoZWxlbWVudCkuZ2V0UHJvcGVydHlWYWx1ZSgndmlzaWJpbGl0eScpID09PSAndmlzaWJsZSc7XG4gIC8vIEhhbmRsZSBgZGV0YWlsc2AgZWxlbWVudCBhcyBpdHMgY29udGVudCBtYXkgZmFsc2llIGFwcGVhciB2aXNpYmxlIHdoZW4gaXQgaXMgY2xvc2VkXG4gIGNvbnN0IGNsb3NlZERldGFpbHMgPSBlbGVtZW50LmNsb3Nlc3QoJ2RldGFpbHM6bm90KFtvcGVuXSknKTtcbiAgaWYgKCFjbG9zZWREZXRhaWxzKSB7XG4gICAgcmV0dXJuIGVsZW1lbnRJc1Zpc2libGU7XG4gIH1cbiAgaWYgKGNsb3NlZERldGFpbHMgIT09IGVsZW1lbnQpIHtcbiAgICBjb25zdCBzdW1tYXJ5ID0gZWxlbWVudC5jbG9zZXN0KCdzdW1tYXJ5Jyk7XG4gICAgaWYgKHN1bW1hcnkgJiYgc3VtbWFyeS5wYXJlbnROb2RlICE9PSBjbG9zZWREZXRhaWxzKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmIChzdW1tYXJ5ID09PSBudWxsKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIHJldHVybiBlbGVtZW50SXNWaXNpYmxlO1xufTtcbmNvbnN0IGlzRGlzYWJsZWQgPSBlbGVtZW50ID0+IHtcbiAgaWYgKCFlbGVtZW50IHx8IGVsZW1lbnQubm9kZVR5cGUgIT09IE5vZGUuRUxFTUVOVF9OT0RFKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgaWYgKGVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKCdkaXNhYmxlZCcpKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgaWYgKHR5cGVvZiBlbGVtZW50LmRpc2FibGVkICE9PSAndW5kZWZpbmVkJykge1xuICAgIHJldHVybiBlbGVtZW50LmRpc2FibGVkO1xuICB9XG4gIHJldHVybiBlbGVtZW50Lmhhc0F0dHJpYnV0ZSgnZGlzYWJsZWQnKSAmJiBlbGVtZW50LmdldEF0dHJpYnV0ZSgnZGlzYWJsZWQnKSAhPT0gJ2ZhbHNlJztcbn07XG5jb25zdCBmaW5kU2hhZG93Um9vdCA9IGVsZW1lbnQgPT4ge1xuICBpZiAoIWRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5hdHRhY2hTaGFkb3cpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIC8vIENhbiBmaW5kIHRoZSBzaGFkb3cgcm9vdCBvdGhlcndpc2UgaXQnbGwgcmV0dXJuIHRoZSBkb2N1bWVudFxuICBpZiAodHlwZW9mIGVsZW1lbnQuZ2V0Um9vdE5vZGUgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjb25zdCByb290ID0gZWxlbWVudC5nZXRSb290Tm9kZSgpO1xuICAgIHJldHVybiByb290IGluc3RhbmNlb2YgU2hhZG93Um9vdCA/IHJvb3QgOiBudWxsO1xuICB9XG4gIGlmIChlbGVtZW50IGluc3RhbmNlb2YgU2hhZG93Um9vdCkge1xuICAgIHJldHVybiBlbGVtZW50O1xuICB9XG5cbiAgLy8gd2hlbiB3ZSBkb24ndCBmaW5kIGEgc2hhZG93IHJvb3RcbiAgaWYgKCFlbGVtZW50LnBhcmVudE5vZGUpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICByZXR1cm4gZmluZFNoYWRvd1Jvb3QoZWxlbWVudC5wYXJlbnROb2RlKTtcbn07XG5jb25zdCBub29wID0gKCkgPT4ge307XG5cbi8qKlxuICogVHJpY2sgdG8gcmVzdGFydCBhbiBlbGVtZW50J3MgYW5pbWF0aW9uXG4gKlxuICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZWxlbWVudFxuICogQHJldHVybiB2b2lkXG4gKlxuICogQHNlZSBodHRwczovL3d3dy5jaGFyaXN0aGVvLmlvL2Jsb2cvMjAyMS8wMi9yZXN0YXJ0LWEtY3NzLWFuaW1hdGlvbi13aXRoLWphdmFzY3JpcHQvI3Jlc3RhcnRpbmctYS1jc3MtYW5pbWF0aW9uXG4gKi9cbmNvbnN0IHJlZmxvdyA9IGVsZW1lbnQgPT4ge1xuICBlbGVtZW50Lm9mZnNldEhlaWdodDsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bnVzZWQtZXhwcmVzc2lvbnNcbn07XG5cbmNvbnN0IGdldGpRdWVyeSA9ICgpID0+IHtcbiAgaWYgKHdpbmRvdy5qUXVlcnkgJiYgIWRvY3VtZW50LmJvZHkuaGFzQXR0cmlidXRlKCdkYXRhLWJzLW5vLWpxdWVyeScpKSB7XG4gICAgcmV0dXJuIHdpbmRvdy5qUXVlcnk7XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59O1xuY29uc3QgRE9NQ29udGVudExvYWRlZENhbGxiYWNrcyA9IFtdO1xuY29uc3Qgb25ET01Db250ZW50TG9hZGVkID0gY2FsbGJhY2sgPT4ge1xuICBpZiAoZG9jdW1lbnQucmVhZHlTdGF0ZSA9PT0gJ2xvYWRpbmcnKSB7XG4gICAgLy8gYWRkIGxpc3RlbmVyIG9uIHRoZSBmaXJzdCBjYWxsIHdoZW4gdGhlIGRvY3VtZW50IGlzIGluIGxvYWRpbmcgc3RhdGVcbiAgICBpZiAoIURPTUNvbnRlbnRMb2FkZWRDYWxsYmFja3MubGVuZ3RoKSB7XG4gICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdET01Db250ZW50TG9hZGVkJywgKCkgPT4ge1xuICAgICAgICBmb3IgKGNvbnN0IGNhbGxiYWNrIG9mIERPTUNvbnRlbnRMb2FkZWRDYWxsYmFja3MpIHtcbiAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gICAgRE9NQ29udGVudExvYWRlZENhbGxiYWNrcy5wdXNoKGNhbGxiYWNrKTtcbiAgfSBlbHNlIHtcbiAgICBjYWxsYmFjaygpO1xuICB9XG59O1xuY29uc3QgaXNSVEwgPSAoKSA9PiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuZGlyID09PSAncnRsJztcbmNvbnN0IGRlZmluZUpRdWVyeVBsdWdpbiA9IHBsdWdpbiA9PiB7XG4gIG9uRE9NQ29udGVudExvYWRlZCgoKSA9PiB7XG4gICAgY29uc3QgJCA9IGdldGpRdWVyeSgpO1xuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgIGlmICgkKSB7XG4gICAgICBjb25zdCBuYW1lID0gcGx1Z2luLk5BTUU7XG4gICAgICBjb25zdCBKUVVFUllfTk9fQ09ORkxJQ1QgPSAkLmZuW25hbWVdO1xuICAgICAgJC5mbltuYW1lXSA9IHBsdWdpbi5qUXVlcnlJbnRlcmZhY2U7XG4gICAgICAkLmZuW25hbWVdLkNvbnN0cnVjdG9yID0gcGx1Z2luO1xuICAgICAgJC5mbltuYW1lXS5ub0NvbmZsaWN0ID0gKCkgPT4ge1xuICAgICAgICAkLmZuW25hbWVdID0gSlFVRVJZX05PX0NPTkZMSUNUO1xuICAgICAgICByZXR1cm4gcGx1Z2luLmpRdWVyeUludGVyZmFjZTtcbiAgICAgIH07XG4gICAgfVxuICB9KTtcbn07XG5jb25zdCBleGVjdXRlID0gKHBvc3NpYmxlQ2FsbGJhY2ssIGFyZ3MgPSBbXSwgZGVmYXVsdFZhbHVlID0gcG9zc2libGVDYWxsYmFjaykgPT4ge1xuICByZXR1cm4gdHlwZW9mIHBvc3NpYmxlQ2FsbGJhY2sgPT09ICdmdW5jdGlvbicgPyBwb3NzaWJsZUNhbGxiYWNrKC4uLmFyZ3MpIDogZGVmYXVsdFZhbHVlO1xufTtcbmNvbnN0IGV4ZWN1dGVBZnRlclRyYW5zaXRpb24gPSAoY2FsbGJhY2ssIHRyYW5zaXRpb25FbGVtZW50LCB3YWl0Rm9yVHJhbnNpdGlvbiA9IHRydWUpID0+IHtcbiAgaWYgKCF3YWl0Rm9yVHJhbnNpdGlvbikge1xuICAgIGV4ZWN1dGUoY2FsbGJhY2spO1xuICAgIHJldHVybjtcbiAgfVxuICBjb25zdCBkdXJhdGlvblBhZGRpbmcgPSA1O1xuICBjb25zdCBlbXVsYXRlZER1cmF0aW9uID0gZ2V0VHJhbnNpdGlvbkR1cmF0aW9uRnJvbUVsZW1lbnQodHJhbnNpdGlvbkVsZW1lbnQpICsgZHVyYXRpb25QYWRkaW5nO1xuICBsZXQgY2FsbGVkID0gZmFsc2U7XG4gIGNvbnN0IGhhbmRsZXIgPSAoe1xuICAgIHRhcmdldFxuICB9KSA9PiB7XG4gICAgaWYgKHRhcmdldCAhPT0gdHJhbnNpdGlvbkVsZW1lbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY2FsbGVkID0gdHJ1ZTtcbiAgICB0cmFuc2l0aW9uRWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKFRSQU5TSVRJT05fRU5ELCBoYW5kbGVyKTtcbiAgICBleGVjdXRlKGNhbGxiYWNrKTtcbiAgfTtcbiAgdHJhbnNpdGlvbkVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihUUkFOU0lUSU9OX0VORCwgaGFuZGxlcik7XG4gIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgIGlmICghY2FsbGVkKSB7XG4gICAgICB0cmlnZ2VyVHJhbnNpdGlvbkVuZCh0cmFuc2l0aW9uRWxlbWVudCk7XG4gICAgfVxuICB9LCBlbXVsYXRlZER1cmF0aW9uKTtcbn07XG5cbi8qKlxuICogUmV0dXJuIHRoZSBwcmV2aW91cy9uZXh0IGVsZW1lbnQgb2YgYSBsaXN0LlxuICpcbiAqIEBwYXJhbSB7YXJyYXl9IGxpc3QgICAgVGhlIGxpc3Qgb2YgZWxlbWVudHNcbiAqIEBwYXJhbSBhY3RpdmVFbGVtZW50ICAgVGhlIGFjdGl2ZSBlbGVtZW50XG4gKiBAcGFyYW0gc2hvdWxkR2V0TmV4dCAgIENob29zZSB0byBnZXQgbmV4dCBvciBwcmV2aW91cyBlbGVtZW50XG4gKiBAcGFyYW0gaXNDeWNsZUFsbG93ZWRcbiAqIEByZXR1cm4ge0VsZW1lbnR8ZWxlbX0gVGhlIHByb3BlciBlbGVtZW50XG4gKi9cbmNvbnN0IGdldE5leHRBY3RpdmVFbGVtZW50ID0gKGxpc3QsIGFjdGl2ZUVsZW1lbnQsIHNob3VsZEdldE5leHQsIGlzQ3ljbGVBbGxvd2VkKSA9PiB7XG4gIGNvbnN0IGxpc3RMZW5ndGggPSBsaXN0Lmxlbmd0aDtcbiAgbGV0IGluZGV4ID0gbGlzdC5pbmRleE9mKGFjdGl2ZUVsZW1lbnQpO1xuXG4gIC8vIGlmIHRoZSBlbGVtZW50IGRvZXMgbm90IGV4aXN0IGluIHRoZSBsaXN0IHJldHVybiBhbiBlbGVtZW50XG4gIC8vIGRlcGVuZGluZyBvbiB0aGUgZGlyZWN0aW9uIGFuZCBpZiBjeWNsZSBpcyBhbGxvd2VkXG4gIGlmIChpbmRleCA9PT0gLTEpIHtcbiAgICByZXR1cm4gIXNob3VsZEdldE5leHQgJiYgaXNDeWNsZUFsbG93ZWQgPyBsaXN0W2xpc3RMZW5ndGggLSAxXSA6IGxpc3RbMF07XG4gIH1cbiAgaW5kZXggKz0gc2hvdWxkR2V0TmV4dCA/IDEgOiAtMTtcbiAgaWYgKGlzQ3ljbGVBbGxvd2VkKSB7XG4gICAgaW5kZXggPSAoaW5kZXggKyBsaXN0TGVuZ3RoKSAlIGxpc3RMZW5ndGg7XG4gIH1cbiAgcmV0dXJuIGxpc3RbTWF0aC5tYXgoMCwgTWF0aC5taW4oaW5kZXgsIGxpc3RMZW5ndGggLSAxKSldO1xufTtcblxuLyoqXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogQm9vdHN0cmFwIGRvbS9ldmVudC1oYW5kbGVyLmpzXG4gKiBMaWNlbnNlZCB1bmRlciBNSVQgKGh0dHBzOi8vZ2l0aHViLmNvbS90d2JzL2Jvb3RzdHJhcC9ibG9iL21haW4vTElDRU5TRSlcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKi9cblxuXG4vKipcbiAqIENvbnN0YW50c1xuICovXG5cbmNvbnN0IG5hbWVzcGFjZVJlZ2V4ID0gL1teLl0qKD89XFwuLiopXFwufC4qLztcbmNvbnN0IHN0cmlwTmFtZVJlZ2V4ID0gL1xcLi4qLztcbmNvbnN0IHN0cmlwVWlkUmVnZXggPSAvOjpcXGQrJC87XG5jb25zdCBldmVudFJlZ2lzdHJ5ID0ge307IC8vIEV2ZW50cyBzdG9yYWdlXG5sZXQgdWlkRXZlbnQgPSAxO1xuY29uc3QgY3VzdG9tRXZlbnRzID0ge1xuICBtb3VzZWVudGVyOiAnbW91c2VvdmVyJyxcbiAgbW91c2VsZWF2ZTogJ21vdXNlb3V0J1xufTtcbmNvbnN0IG5hdGl2ZUV2ZW50cyA9IG5ldyBTZXQoWydjbGljaycsICdkYmxjbGljaycsICdtb3VzZXVwJywgJ21vdXNlZG93bicsICdjb250ZXh0bWVudScsICdtb3VzZXdoZWVsJywgJ0RPTU1vdXNlU2Nyb2xsJywgJ21vdXNlb3ZlcicsICdtb3VzZW91dCcsICdtb3VzZW1vdmUnLCAnc2VsZWN0c3RhcnQnLCAnc2VsZWN0ZW5kJywgJ2tleWRvd24nLCAna2V5cHJlc3MnLCAna2V5dXAnLCAnb3JpZW50YXRpb25jaGFuZ2UnLCAndG91Y2hzdGFydCcsICd0b3VjaG1vdmUnLCAndG91Y2hlbmQnLCAndG91Y2hjYW5jZWwnLCAncG9pbnRlcmRvd24nLCAncG9pbnRlcm1vdmUnLCAncG9pbnRlcnVwJywgJ3BvaW50ZXJsZWF2ZScsICdwb2ludGVyY2FuY2VsJywgJ2dlc3R1cmVzdGFydCcsICdnZXN0dXJlY2hhbmdlJywgJ2dlc3R1cmVlbmQnLCAnZm9jdXMnLCAnYmx1cicsICdjaGFuZ2UnLCAncmVzZXQnLCAnc2VsZWN0JywgJ3N1Ym1pdCcsICdmb2N1c2luJywgJ2ZvY3Vzb3V0JywgJ2xvYWQnLCAndW5sb2FkJywgJ2JlZm9yZXVubG9hZCcsICdyZXNpemUnLCAnbW92ZScsICdET01Db250ZW50TG9hZGVkJywgJ3JlYWR5c3RhdGVjaGFuZ2UnLCAnZXJyb3InLCAnYWJvcnQnLCAnc2Nyb2xsJ10pO1xuXG4vKipcbiAqIFByaXZhdGUgbWV0aG9kc1xuICovXG5cbmZ1bmN0aW9uIG1ha2VFdmVudFVpZChlbGVtZW50LCB1aWQpIHtcbiAgcmV0dXJuIHVpZCAmJiBgJHt1aWR9Ojoke3VpZEV2ZW50Kyt9YCB8fCBlbGVtZW50LnVpZEV2ZW50IHx8IHVpZEV2ZW50Kys7XG59XG5mdW5jdGlvbiBnZXRFbGVtZW50RXZlbnRzKGVsZW1lbnQpIHtcbiAgY29uc3QgdWlkID0gbWFrZUV2ZW50VWlkKGVsZW1lbnQpO1xuICBlbGVtZW50LnVpZEV2ZW50ID0gdWlkO1xuICBldmVudFJlZ2lzdHJ5W3VpZF0gPSBldmVudFJlZ2lzdHJ5W3VpZF0gfHwge307XG4gIHJldHVybiBldmVudFJlZ2lzdHJ5W3VpZF07XG59XG5mdW5jdGlvbiBib290c3RyYXBIYW5kbGVyKGVsZW1lbnQsIGZuKSB7XG4gIHJldHVybiBmdW5jdGlvbiBoYW5kbGVyKGV2ZW50KSB7XG4gICAgaHlkcmF0ZU9iaihldmVudCwge1xuICAgICAgZGVsZWdhdGVUYXJnZXQ6IGVsZW1lbnRcbiAgICB9KTtcbiAgICBpZiAoaGFuZGxlci5vbmVPZmYpIHtcbiAgICAgIEV2ZW50SGFuZGxlci5vZmYoZWxlbWVudCwgZXZlbnQudHlwZSwgZm4pO1xuICAgIH1cbiAgICByZXR1cm4gZm4uYXBwbHkoZWxlbWVudCwgW2V2ZW50XSk7XG4gIH07XG59XG5mdW5jdGlvbiBib290c3RyYXBEZWxlZ2F0aW9uSGFuZGxlcihlbGVtZW50LCBzZWxlY3RvciwgZm4pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGhhbmRsZXIoZXZlbnQpIHtcbiAgICBjb25zdCBkb21FbGVtZW50cyA9IGVsZW1lbnQucXVlcnlTZWxlY3RvckFsbChzZWxlY3Rvcik7XG4gICAgZm9yIChsZXQge1xuICAgICAgdGFyZ2V0XG4gICAgfSA9IGV2ZW50OyB0YXJnZXQgJiYgdGFyZ2V0ICE9PSB0aGlzOyB0YXJnZXQgPSB0YXJnZXQucGFyZW50Tm9kZSkge1xuICAgICAgZm9yIChjb25zdCBkb21FbGVtZW50IG9mIGRvbUVsZW1lbnRzKSB7XG4gICAgICAgIGlmIChkb21FbGVtZW50ICE9PSB0YXJnZXQpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBoeWRyYXRlT2JqKGV2ZW50LCB7XG4gICAgICAgICAgZGVsZWdhdGVUYXJnZXQ6IHRhcmdldFxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKGhhbmRsZXIub25lT2ZmKSB7XG4gICAgICAgICAgRXZlbnRIYW5kbGVyLm9mZihlbGVtZW50LCBldmVudC50eXBlLCBzZWxlY3RvciwgZm4pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmbi5hcHBseSh0YXJnZXQsIFtldmVudF0pO1xuICAgICAgfVxuICAgIH1cbiAgfTtcbn1cbmZ1bmN0aW9uIGZpbmRIYW5kbGVyKGV2ZW50cywgY2FsbGFibGUsIGRlbGVnYXRpb25TZWxlY3RvciA9IG51bGwpIHtcbiAgcmV0dXJuIE9iamVjdC52YWx1ZXMoZXZlbnRzKS5maW5kKGV2ZW50ID0+IGV2ZW50LmNhbGxhYmxlID09PSBjYWxsYWJsZSAmJiBldmVudC5kZWxlZ2F0aW9uU2VsZWN0b3IgPT09IGRlbGVnYXRpb25TZWxlY3Rvcik7XG59XG5mdW5jdGlvbiBub3JtYWxpemVQYXJhbWV0ZXJzKG9yaWdpbmFsVHlwZUV2ZW50LCBoYW5kbGVyLCBkZWxlZ2F0aW9uRnVuY3Rpb24pIHtcbiAgY29uc3QgaXNEZWxlZ2F0ZWQgPSB0eXBlb2YgaGFuZGxlciA9PT0gJ3N0cmluZyc7XG4gIC8vIFRPRE86IHRvb2x0aXAgcGFzc2VzIGBmYWxzZWAgaW5zdGVhZCBvZiBzZWxlY3Rvciwgc28gd2UgbmVlZCB0byBjaGVja1xuICBjb25zdCBjYWxsYWJsZSA9IGlzRGVsZWdhdGVkID8gZGVsZWdhdGlvbkZ1bmN0aW9uIDogaGFuZGxlciB8fCBkZWxlZ2F0aW9uRnVuY3Rpb247XG4gIGxldCB0eXBlRXZlbnQgPSBnZXRUeXBlRXZlbnQob3JpZ2luYWxUeXBlRXZlbnQpO1xuICBpZiAoIW5hdGl2ZUV2ZW50cy5oYXModHlwZUV2ZW50KSkge1xuICAgIHR5cGVFdmVudCA9IG9yaWdpbmFsVHlwZUV2ZW50O1xuICB9XG4gIHJldHVybiBbaXNEZWxlZ2F0ZWQsIGNhbGxhYmxlLCB0eXBlRXZlbnRdO1xufVxuZnVuY3Rpb24gYWRkSGFuZGxlcihlbGVtZW50LCBvcmlnaW5hbFR5cGVFdmVudCwgaGFuZGxlciwgZGVsZWdhdGlvbkZ1bmN0aW9uLCBvbmVPZmYpIHtcbiAgaWYgKHR5cGVvZiBvcmlnaW5hbFR5cGVFdmVudCAhPT0gJ3N0cmluZycgfHwgIWVsZW1lbnQpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgbGV0IFtpc0RlbGVnYXRlZCwgY2FsbGFibGUsIHR5cGVFdmVudF0gPSBub3JtYWxpemVQYXJhbWV0ZXJzKG9yaWdpbmFsVHlwZUV2ZW50LCBoYW5kbGVyLCBkZWxlZ2F0aW9uRnVuY3Rpb24pO1xuXG4gIC8vIGluIGNhc2Ugb2YgbW91c2VlbnRlciBvciBtb3VzZWxlYXZlIHdyYXAgdGhlIGhhbmRsZXIgd2l0aGluIGEgZnVuY3Rpb24gdGhhdCBjaGVja3MgZm9yIGl0cyBET00gcG9zaXRpb25cbiAgLy8gdGhpcyBwcmV2ZW50cyB0aGUgaGFuZGxlciBmcm9tIGJlaW5nIGRpc3BhdGNoZWQgdGhlIHNhbWUgd2F5IGFzIG1vdXNlb3ZlciBvciBtb3VzZW91dCBkb2VzXG4gIGlmIChvcmlnaW5hbFR5cGVFdmVudCBpbiBjdXN0b21FdmVudHMpIHtcbiAgICBjb25zdCB3cmFwRnVuY3Rpb24gPSBmbiA9PiB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgIGlmICghZXZlbnQucmVsYXRlZFRhcmdldCB8fCBldmVudC5yZWxhdGVkVGFyZ2V0ICE9PSBldmVudC5kZWxlZ2F0ZVRhcmdldCAmJiAhZXZlbnQuZGVsZWdhdGVUYXJnZXQuY29udGFpbnMoZXZlbnQucmVsYXRlZFRhcmdldCkpIHtcbiAgICAgICAgICByZXR1cm4gZm4uY2FsbCh0aGlzLCBldmVudCk7XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgfTtcbiAgICBjYWxsYWJsZSA9IHdyYXBGdW5jdGlvbihjYWxsYWJsZSk7XG4gIH1cbiAgY29uc3QgZXZlbnRzID0gZ2V0RWxlbWVudEV2ZW50cyhlbGVtZW50KTtcbiAgY29uc3QgaGFuZGxlcnMgPSBldmVudHNbdHlwZUV2ZW50XSB8fCAoZXZlbnRzW3R5cGVFdmVudF0gPSB7fSk7XG4gIGNvbnN0IHByZXZpb3VzRnVuY3Rpb24gPSBmaW5kSGFuZGxlcihoYW5kbGVycywgY2FsbGFibGUsIGlzRGVsZWdhdGVkID8gaGFuZGxlciA6IG51bGwpO1xuICBpZiAocHJldmlvdXNGdW5jdGlvbikge1xuICAgIHByZXZpb3VzRnVuY3Rpb24ub25lT2ZmID0gcHJldmlvdXNGdW5jdGlvbi5vbmVPZmYgJiYgb25lT2ZmO1xuICAgIHJldHVybjtcbiAgfVxuICBjb25zdCB1aWQgPSBtYWtlRXZlbnRVaWQoY2FsbGFibGUsIG9yaWdpbmFsVHlwZUV2ZW50LnJlcGxhY2UobmFtZXNwYWNlUmVnZXgsICcnKSk7XG4gIGNvbnN0IGZuID0gaXNEZWxlZ2F0ZWQgPyBib290c3RyYXBEZWxlZ2F0aW9uSGFuZGxlcihlbGVtZW50LCBoYW5kbGVyLCBjYWxsYWJsZSkgOiBib290c3RyYXBIYW5kbGVyKGVsZW1lbnQsIGNhbGxhYmxlKTtcbiAgZm4uZGVsZWdhdGlvblNlbGVjdG9yID0gaXNEZWxlZ2F0ZWQgPyBoYW5kbGVyIDogbnVsbDtcbiAgZm4uY2FsbGFibGUgPSBjYWxsYWJsZTtcbiAgZm4ub25lT2ZmID0gb25lT2ZmO1xuICBmbi51aWRFdmVudCA9IHVpZDtcbiAgaGFuZGxlcnNbdWlkXSA9IGZuO1xuICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIodHlwZUV2ZW50LCBmbiwgaXNEZWxlZ2F0ZWQpO1xufVxuZnVuY3Rpb24gcmVtb3ZlSGFuZGxlcihlbGVtZW50LCBldmVudHMsIHR5cGVFdmVudCwgaGFuZGxlciwgZGVsZWdhdGlvblNlbGVjdG9yKSB7XG4gIGNvbnN0IGZuID0gZmluZEhhbmRsZXIoZXZlbnRzW3R5cGVFdmVudF0sIGhhbmRsZXIsIGRlbGVnYXRpb25TZWxlY3Rvcik7XG4gIGlmICghZm4pIHtcbiAgICByZXR1cm47XG4gIH1cbiAgZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKHR5cGVFdmVudCwgZm4sIEJvb2xlYW4oZGVsZWdhdGlvblNlbGVjdG9yKSk7XG4gIGRlbGV0ZSBldmVudHNbdHlwZUV2ZW50XVtmbi51aWRFdmVudF07XG59XG5mdW5jdGlvbiByZW1vdmVOYW1lc3BhY2VkSGFuZGxlcnMoZWxlbWVudCwgZXZlbnRzLCB0eXBlRXZlbnQsIG5hbWVzcGFjZSkge1xuICBjb25zdCBzdG9yZUVsZW1lbnRFdmVudCA9IGV2ZW50c1t0eXBlRXZlbnRdIHx8IHt9O1xuICBmb3IgKGNvbnN0IFtoYW5kbGVyS2V5LCBldmVudF0gb2YgT2JqZWN0LmVudHJpZXMoc3RvcmVFbGVtZW50RXZlbnQpKSB7XG4gICAgaWYgKGhhbmRsZXJLZXkuaW5jbHVkZXMobmFtZXNwYWNlKSkge1xuICAgICAgcmVtb3ZlSGFuZGxlcihlbGVtZW50LCBldmVudHMsIHR5cGVFdmVudCwgZXZlbnQuY2FsbGFibGUsIGV2ZW50LmRlbGVnYXRpb25TZWxlY3Rvcik7XG4gICAgfVxuICB9XG59XG5mdW5jdGlvbiBnZXRUeXBlRXZlbnQoZXZlbnQpIHtcbiAgLy8gYWxsb3cgdG8gZ2V0IHRoZSBuYXRpdmUgZXZlbnRzIGZyb20gbmFtZXNwYWNlZCBldmVudHMgKCdjbGljay5icy5idXR0b24nIC0tPiAnY2xpY2snKVxuICBldmVudCA9IGV2ZW50LnJlcGxhY2Uoc3RyaXBOYW1lUmVnZXgsICcnKTtcbiAgcmV0dXJuIGN1c3RvbUV2ZW50c1tldmVudF0gfHwgZXZlbnQ7XG59XG5jb25zdCBFdmVudEhhbmRsZXIgPSB7XG4gIG9uKGVsZW1lbnQsIGV2ZW50LCBoYW5kbGVyLCBkZWxlZ2F0aW9uRnVuY3Rpb24pIHtcbiAgICBhZGRIYW5kbGVyKGVsZW1lbnQsIGV2ZW50LCBoYW5kbGVyLCBkZWxlZ2F0aW9uRnVuY3Rpb24sIGZhbHNlKTtcbiAgfSxcbiAgb25lKGVsZW1lbnQsIGV2ZW50LCBoYW5kbGVyLCBkZWxlZ2F0aW9uRnVuY3Rpb24pIHtcbiAgICBhZGRIYW5kbGVyKGVsZW1lbnQsIGV2ZW50LCBoYW5kbGVyLCBkZWxlZ2F0aW9uRnVuY3Rpb24sIHRydWUpO1xuICB9LFxuICBvZmYoZWxlbWVudCwgb3JpZ2luYWxUeXBlRXZlbnQsIGhhbmRsZXIsIGRlbGVnYXRpb25GdW5jdGlvbikge1xuICAgIGlmICh0eXBlb2Ygb3JpZ2luYWxUeXBlRXZlbnQgIT09ICdzdHJpbmcnIHx8ICFlbGVtZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IFtpc0RlbGVnYXRlZCwgY2FsbGFibGUsIHR5cGVFdmVudF0gPSBub3JtYWxpemVQYXJhbWV0ZXJzKG9yaWdpbmFsVHlwZUV2ZW50LCBoYW5kbGVyLCBkZWxlZ2F0aW9uRnVuY3Rpb24pO1xuICAgIGNvbnN0IGluTmFtZXNwYWNlID0gdHlwZUV2ZW50ICE9PSBvcmlnaW5hbFR5cGVFdmVudDtcbiAgICBjb25zdCBldmVudHMgPSBnZXRFbGVtZW50RXZlbnRzKGVsZW1lbnQpO1xuICAgIGNvbnN0IHN0b3JlRWxlbWVudEV2ZW50ID0gZXZlbnRzW3R5cGVFdmVudF0gfHwge307XG4gICAgY29uc3QgaXNOYW1lc3BhY2UgPSBvcmlnaW5hbFR5cGVFdmVudC5zdGFydHNXaXRoKCcuJyk7XG4gICAgaWYgKHR5cGVvZiBjYWxsYWJsZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIC8vIFNpbXBsZXN0IGNhc2U6IGhhbmRsZXIgaXMgcGFzc2VkLCByZW1vdmUgdGhhdCBsaXN0ZW5lciBPTkxZLlxuICAgICAgaWYgKCFPYmplY3Qua2V5cyhzdG9yZUVsZW1lbnRFdmVudCkubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHJlbW92ZUhhbmRsZXIoZWxlbWVudCwgZXZlbnRzLCB0eXBlRXZlbnQsIGNhbGxhYmxlLCBpc0RlbGVnYXRlZCA/IGhhbmRsZXIgOiBudWxsKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKGlzTmFtZXNwYWNlKSB7XG4gICAgICBmb3IgKGNvbnN0IGVsZW1lbnRFdmVudCBvZiBPYmplY3Qua2V5cyhldmVudHMpKSB7XG4gICAgICAgIHJlbW92ZU5hbWVzcGFjZWRIYW5kbGVycyhlbGVtZW50LCBldmVudHMsIGVsZW1lbnRFdmVudCwgb3JpZ2luYWxUeXBlRXZlbnQuc2xpY2UoMSkpO1xuICAgICAgfVxuICAgIH1cbiAgICBmb3IgKGNvbnN0IFtrZXlIYW5kbGVycywgZXZlbnRdIG9mIE9iamVjdC5lbnRyaWVzKHN0b3JlRWxlbWVudEV2ZW50KSkge1xuICAgICAgY29uc3QgaGFuZGxlcktleSA9IGtleUhhbmRsZXJzLnJlcGxhY2Uoc3RyaXBVaWRSZWdleCwgJycpO1xuICAgICAgaWYgKCFpbk5hbWVzcGFjZSB8fCBvcmlnaW5hbFR5cGVFdmVudC5pbmNsdWRlcyhoYW5kbGVyS2V5KSkge1xuICAgICAgICByZW1vdmVIYW5kbGVyKGVsZW1lbnQsIGV2ZW50cywgdHlwZUV2ZW50LCBldmVudC5jYWxsYWJsZSwgZXZlbnQuZGVsZWdhdGlvblNlbGVjdG9yKTtcbiAgICAgIH1cbiAgICB9XG4gIH0sXG4gIHRyaWdnZXIoZWxlbWVudCwgZXZlbnQsIGFyZ3MpIHtcbiAgICBpZiAodHlwZW9mIGV2ZW50ICE9PSAnc3RyaW5nJyB8fCAhZWxlbWVudCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGNvbnN0ICQgPSBnZXRqUXVlcnkoKTtcbiAgICBjb25zdCB0eXBlRXZlbnQgPSBnZXRUeXBlRXZlbnQoZXZlbnQpO1xuICAgIGNvbnN0IGluTmFtZXNwYWNlID0gZXZlbnQgIT09IHR5cGVFdmVudDtcbiAgICBsZXQgalF1ZXJ5RXZlbnQgPSBudWxsO1xuICAgIGxldCBidWJibGVzID0gdHJ1ZTtcbiAgICBsZXQgbmF0aXZlRGlzcGF0Y2ggPSB0cnVlO1xuICAgIGxldCBkZWZhdWx0UHJldmVudGVkID0gZmFsc2U7XG4gICAgaWYgKGluTmFtZXNwYWNlICYmICQpIHtcbiAgICAgIGpRdWVyeUV2ZW50ID0gJC5FdmVudChldmVudCwgYXJncyk7XG4gICAgICAkKGVsZW1lbnQpLnRyaWdnZXIoalF1ZXJ5RXZlbnQpO1xuICAgICAgYnViYmxlcyA9ICFqUXVlcnlFdmVudC5pc1Byb3BhZ2F0aW9uU3RvcHBlZCgpO1xuICAgICAgbmF0aXZlRGlzcGF0Y2ggPSAhalF1ZXJ5RXZlbnQuaXNJbW1lZGlhdGVQcm9wYWdhdGlvblN0b3BwZWQoKTtcbiAgICAgIGRlZmF1bHRQcmV2ZW50ZWQgPSBqUXVlcnlFdmVudC5pc0RlZmF1bHRQcmV2ZW50ZWQoKTtcbiAgICB9XG4gICAgY29uc3QgZXZ0ID0gaHlkcmF0ZU9iaihuZXcgRXZlbnQoZXZlbnQsIHtcbiAgICAgIGJ1YmJsZXMsXG4gICAgICBjYW5jZWxhYmxlOiB0cnVlXG4gICAgfSksIGFyZ3MpO1xuICAgIGlmIChkZWZhdWx0UHJldmVudGVkKSB7XG4gICAgICBldnQucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG4gICAgaWYgKG5hdGl2ZURpc3BhdGNoKSB7XG4gICAgICBlbGVtZW50LmRpc3BhdGNoRXZlbnQoZXZ0KTtcbiAgICB9XG4gICAgaWYgKGV2dC5kZWZhdWx0UHJldmVudGVkICYmIGpRdWVyeUV2ZW50KSB7XG4gICAgICBqUXVlcnlFdmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cbiAgICByZXR1cm4gZXZ0O1xuICB9XG59O1xuZnVuY3Rpb24gaHlkcmF0ZU9iaihvYmosIG1ldGEgPSB7fSkge1xuICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhtZXRhKSkge1xuICAgIHRyeSB7XG4gICAgICBvYmpba2V5XSA9IHZhbHVlO1xuICAgIH0gY2F0Y2ggKF91bnVzZWQpIHtcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvYmosIGtleSwge1xuICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgIGdldCgpIHtcbiAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuICByZXR1cm4gb2JqO1xufVxuXG4vKipcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiBCb290c3RyYXAgZG9tL21hbmlwdWxhdG9yLmpzXG4gKiBMaWNlbnNlZCB1bmRlciBNSVQgKGh0dHBzOi8vZ2l0aHViLmNvbS90d2JzL2Jvb3RzdHJhcC9ibG9iL21haW4vTElDRU5TRSlcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKi9cblxuZnVuY3Rpb24gbm9ybWFsaXplRGF0YSh2YWx1ZSkge1xuICBpZiAodmFsdWUgPT09ICd0cnVlJykge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIGlmICh2YWx1ZSA9PT0gJ2ZhbHNlJykge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAodmFsdWUgPT09IE51bWJlcih2YWx1ZSkudG9TdHJpbmcoKSkge1xuICAgIHJldHVybiBOdW1iZXIodmFsdWUpO1xuICB9XG4gIGlmICh2YWx1ZSA9PT0gJycgfHwgdmFsdWUgPT09ICdudWxsJykge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIGlmICh0eXBlb2YgdmFsdWUgIT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG4gIHRyeSB7XG4gICAgcmV0dXJuIEpTT04ucGFyc2UoZGVjb2RlVVJJQ29tcG9uZW50KHZhbHVlKSk7XG4gIH0gY2F0Y2ggKF91bnVzZWQpIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cbn1cbmZ1bmN0aW9uIG5vcm1hbGl6ZURhdGFLZXkoa2V5KSB7XG4gIHJldHVybiBrZXkucmVwbGFjZSgvW0EtWl0vZywgY2hyID0+IGAtJHtjaHIudG9Mb3dlckNhc2UoKX1gKTtcbn1cbmNvbnN0IE1hbmlwdWxhdG9yID0ge1xuICBzZXREYXRhQXR0cmlidXRlKGVsZW1lbnQsIGtleSwgdmFsdWUpIHtcbiAgICBlbGVtZW50LnNldEF0dHJpYnV0ZShgZGF0YS1icy0ke25vcm1hbGl6ZURhdGFLZXkoa2V5KX1gLCB2YWx1ZSk7XG4gIH0sXG4gIHJlbW92ZURhdGFBdHRyaWJ1dGUoZWxlbWVudCwga2V5KSB7XG4gICAgZWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUoYGRhdGEtYnMtJHtub3JtYWxpemVEYXRhS2V5KGtleSl9YCk7XG4gIH0sXG4gIGdldERhdGFBdHRyaWJ1dGVzKGVsZW1lbnQpIHtcbiAgICBpZiAoIWVsZW1lbnQpIHtcbiAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgY29uc3QgYXR0cmlidXRlcyA9IHt9O1xuICAgIGNvbnN0IGJzS2V5cyA9IE9iamVjdC5rZXlzKGVsZW1lbnQuZGF0YXNldCkuZmlsdGVyKGtleSA9PiBrZXkuc3RhcnRzV2l0aCgnYnMnKSAmJiAha2V5LnN0YXJ0c1dpdGgoJ2JzQ29uZmlnJykpO1xuICAgIGZvciAoY29uc3Qga2V5IG9mIGJzS2V5cykge1xuICAgICAgbGV0IHB1cmVLZXkgPSBrZXkucmVwbGFjZSgvXmJzLywgJycpO1xuICAgICAgcHVyZUtleSA9IHB1cmVLZXkuY2hhckF0KDApLnRvTG93ZXJDYXNlKCkgKyBwdXJlS2V5LnNsaWNlKDEsIHB1cmVLZXkubGVuZ3RoKTtcbiAgICAgIGF0dHJpYnV0ZXNbcHVyZUtleV0gPSBub3JtYWxpemVEYXRhKGVsZW1lbnQuZGF0YXNldFtrZXldKTtcbiAgICB9XG4gICAgcmV0dXJuIGF0dHJpYnV0ZXM7XG4gIH0sXG4gIGdldERhdGFBdHRyaWJ1dGUoZWxlbWVudCwga2V5KSB7XG4gICAgcmV0dXJuIG5vcm1hbGl6ZURhdGEoZWxlbWVudC5nZXRBdHRyaWJ1dGUoYGRhdGEtYnMtJHtub3JtYWxpemVEYXRhS2V5KGtleSl9YCkpO1xuICB9XG59O1xuXG4vKipcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiBCb290c3RyYXAgdXRpbC9jb25maWcuanNcbiAqIExpY2Vuc2VkIHVuZGVyIE1JVCAoaHR0cHM6Ly9naXRodWIuY29tL3R3YnMvYm9vdHN0cmFwL2Jsb2IvbWFpbi9MSUNFTlNFKVxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqL1xuXG5cbi8qKlxuICogQ2xhc3MgZGVmaW5pdGlvblxuICovXG5cbmNsYXNzIENvbmZpZyB7XG4gIC8vIEdldHRlcnNcbiAgc3RhdGljIGdldCBEZWZhdWx0KCkge1xuICAgIHJldHVybiB7fTtcbiAgfVxuICBzdGF0aWMgZ2V0IERlZmF1bHRUeXBlKCkge1xuICAgIHJldHVybiB7fTtcbiAgfVxuICBzdGF0aWMgZ2V0IE5BTUUoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdZb3UgaGF2ZSB0byBpbXBsZW1lbnQgdGhlIHN0YXRpYyBtZXRob2QgXCJOQU1FXCIsIGZvciBlYWNoIGNvbXBvbmVudCEnKTtcbiAgfVxuICBfZ2V0Q29uZmlnKGNvbmZpZykge1xuICAgIGNvbmZpZyA9IHRoaXMuX21lcmdlQ29uZmlnT2JqKGNvbmZpZyk7XG4gICAgY29uZmlnID0gdGhpcy5fY29uZmlnQWZ0ZXJNZXJnZShjb25maWcpO1xuICAgIHRoaXMuX3R5cGVDaGVja0NvbmZpZyhjb25maWcpO1xuICAgIHJldHVybiBjb25maWc7XG4gIH1cbiAgX2NvbmZpZ0FmdGVyTWVyZ2UoY29uZmlnKSB7XG4gICAgcmV0dXJuIGNvbmZpZztcbiAgfVxuICBfbWVyZ2VDb25maWdPYmooY29uZmlnLCBlbGVtZW50KSB7XG4gICAgY29uc3QganNvbkNvbmZpZyA9IGlzRWxlbWVudChlbGVtZW50KSA/IE1hbmlwdWxhdG9yLmdldERhdGFBdHRyaWJ1dGUoZWxlbWVudCwgJ2NvbmZpZycpIDoge307IC8vIHRyeSB0byBwYXJzZVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLnRoaXMuY29uc3RydWN0b3IuRGVmYXVsdCxcbiAgICAgIC4uLih0eXBlb2YganNvbkNvbmZpZyA9PT0gJ29iamVjdCcgPyBqc29uQ29uZmlnIDoge30pLFxuICAgICAgLi4uKGlzRWxlbWVudChlbGVtZW50KSA/IE1hbmlwdWxhdG9yLmdldERhdGFBdHRyaWJ1dGVzKGVsZW1lbnQpIDoge30pLFxuICAgICAgLi4uKHR5cGVvZiBjb25maWcgPT09ICdvYmplY3QnID8gY29uZmlnIDoge30pXG4gICAgfTtcbiAgfVxuICBfdHlwZUNoZWNrQ29uZmlnKGNvbmZpZywgY29uZmlnVHlwZXMgPSB0aGlzLmNvbnN0cnVjdG9yLkRlZmF1bHRUeXBlKSB7XG4gICAgZm9yIChjb25zdCBbcHJvcGVydHksIGV4cGVjdGVkVHlwZXNdIG9mIE9iamVjdC5lbnRyaWVzKGNvbmZpZ1R5cGVzKSkge1xuICAgICAgY29uc3QgdmFsdWUgPSBjb25maWdbcHJvcGVydHldO1xuICAgICAgY29uc3QgdmFsdWVUeXBlID0gaXNFbGVtZW50KHZhbHVlKSA/ICdlbGVtZW50JyA6IHRvVHlwZSh2YWx1ZSk7XG4gICAgICBpZiAoIW5ldyBSZWdFeHAoZXhwZWN0ZWRUeXBlcykudGVzdCh2YWx1ZVR5cGUpKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYCR7dGhpcy5jb25zdHJ1Y3Rvci5OQU1FLnRvVXBwZXJDYXNlKCl9OiBPcHRpb24gXCIke3Byb3BlcnR5fVwiIHByb3ZpZGVkIHR5cGUgXCIke3ZhbHVlVHlwZX1cIiBidXQgZXhwZWN0ZWQgdHlwZSBcIiR7ZXhwZWN0ZWRUeXBlc31cIi5gKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogQm9vdHN0cmFwIGJhc2UtY29tcG9uZW50LmpzXG4gKiBMaWNlbnNlZCB1bmRlciBNSVQgKGh0dHBzOi8vZ2l0aHViLmNvbS90d2JzL2Jvb3RzdHJhcC9ibG9iL21haW4vTElDRU5TRSlcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKi9cblxuXG4vKipcbiAqIENvbnN0YW50c1xuICovXG5cbmNvbnN0IFZFUlNJT04gPSAnNS4zLjAnO1xuXG4vKipcbiAqIENsYXNzIGRlZmluaXRpb25cbiAqL1xuXG5jbGFzcyBCYXNlQ29tcG9uZW50IGV4dGVuZHMgQ29uZmlnIHtcbiAgY29uc3RydWN0b3IoZWxlbWVudCwgY29uZmlnKSB7XG4gICAgc3VwZXIoKTtcbiAgICBlbGVtZW50ID0gZ2V0RWxlbWVudChlbGVtZW50KTtcbiAgICBpZiAoIWVsZW1lbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5fZWxlbWVudCA9IGVsZW1lbnQ7XG4gICAgdGhpcy5fY29uZmlnID0gdGhpcy5fZ2V0Q29uZmlnKGNvbmZpZyk7XG4gICAgRGF0YS5zZXQodGhpcy5fZWxlbWVudCwgdGhpcy5jb25zdHJ1Y3Rvci5EQVRBX0tFWSwgdGhpcyk7XG4gIH1cblxuICAvLyBQdWJsaWNcbiAgZGlzcG9zZSgpIHtcbiAgICBEYXRhLnJlbW92ZSh0aGlzLl9lbGVtZW50LCB0aGlzLmNvbnN0cnVjdG9yLkRBVEFfS0VZKTtcbiAgICBFdmVudEhhbmRsZXIub2ZmKHRoaXMuX2VsZW1lbnQsIHRoaXMuY29uc3RydWN0b3IuRVZFTlRfS0VZKTtcbiAgICBmb3IgKGNvbnN0IHByb3BlcnR5TmFtZSBvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh0aGlzKSkge1xuICAgICAgdGhpc1twcm9wZXJ0eU5hbWVdID0gbnVsbDtcbiAgICB9XG4gIH1cbiAgX3F1ZXVlQ2FsbGJhY2soY2FsbGJhY2ssIGVsZW1lbnQsIGlzQW5pbWF0ZWQgPSB0cnVlKSB7XG4gICAgZXhlY3V0ZUFmdGVyVHJhbnNpdGlvbihjYWxsYmFjaywgZWxlbWVudCwgaXNBbmltYXRlZCk7XG4gIH1cbiAgX2dldENvbmZpZyhjb25maWcpIHtcbiAgICBjb25maWcgPSB0aGlzLl9tZXJnZUNvbmZpZ09iaihjb25maWcsIHRoaXMuX2VsZW1lbnQpO1xuICAgIGNvbmZpZyA9IHRoaXMuX2NvbmZpZ0FmdGVyTWVyZ2UoY29uZmlnKTtcbiAgICB0aGlzLl90eXBlQ2hlY2tDb25maWcoY29uZmlnKTtcbiAgICByZXR1cm4gY29uZmlnO1xuICB9XG5cbiAgLy8gU3RhdGljXG4gIHN0YXRpYyBnZXRJbnN0YW5jZShlbGVtZW50KSB7XG4gICAgcmV0dXJuIERhdGEuZ2V0KGdldEVsZW1lbnQoZWxlbWVudCksIHRoaXMuREFUQV9LRVkpO1xuICB9XG4gIHN0YXRpYyBnZXRPckNyZWF0ZUluc3RhbmNlKGVsZW1lbnQsIGNvbmZpZyA9IHt9KSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0SW5zdGFuY2UoZWxlbWVudCkgfHwgbmV3IHRoaXMoZWxlbWVudCwgdHlwZW9mIGNvbmZpZyA9PT0gJ29iamVjdCcgPyBjb25maWcgOiBudWxsKTtcbiAgfVxuICBzdGF0aWMgZ2V0IFZFUlNJT04oKSB7XG4gICAgcmV0dXJuIFZFUlNJT047XG4gIH1cbiAgc3RhdGljIGdldCBEQVRBX0tFWSgpIHtcbiAgICByZXR1cm4gYGJzLiR7dGhpcy5OQU1FfWA7XG4gIH1cbiAgc3RhdGljIGdldCBFVkVOVF9LRVkoKSB7XG4gICAgcmV0dXJuIGAuJHt0aGlzLkRBVEFfS0VZfWA7XG4gIH1cbiAgc3RhdGljIGV2ZW50TmFtZShuYW1lKSB7XG4gICAgcmV0dXJuIGAke25hbWV9JHt0aGlzLkVWRU5UX0tFWX1gO1xuICB9XG59XG5cbi8qKlxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIEJvb3RzdHJhcCBkb20vc2VsZWN0b3ItZW5naW5lLmpzXG4gKiBMaWNlbnNlZCB1bmRlciBNSVQgKGh0dHBzOi8vZ2l0aHViLmNvbS90d2JzL2Jvb3RzdHJhcC9ibG9iL21haW4vTElDRU5TRSlcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKi9cblxuY29uc3QgZ2V0U2VsZWN0b3IgPSBlbGVtZW50ID0+IHtcbiAgbGV0IHNlbGVjdG9yID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2RhdGEtYnMtdGFyZ2V0Jyk7XG4gIGlmICghc2VsZWN0b3IgfHwgc2VsZWN0b3IgPT09ICcjJykge1xuICAgIGxldCBocmVmQXR0cmlidXRlID0gZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2hyZWYnKTtcblxuICAgIC8vIFRoZSBvbmx5IHZhbGlkIGNvbnRlbnQgdGhhdCBjb3VsZCBkb3VibGUgYXMgYSBzZWxlY3RvciBhcmUgSURzIG9yIGNsYXNzZXMsXG4gICAgLy8gc28gZXZlcnl0aGluZyBzdGFydGluZyB3aXRoIGAjYCBvciBgLmAuIElmIGEgXCJyZWFsXCIgVVJMIGlzIHVzZWQgYXMgdGhlIHNlbGVjdG9yLFxuICAgIC8vIGBkb2N1bWVudC5xdWVyeVNlbGVjdG9yYCB3aWxsIHJpZ2h0ZnVsbHkgY29tcGxhaW4gaXQgaXMgaW52YWxpZC5cbiAgICAvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL3R3YnMvYm9vdHN0cmFwL2lzc3Vlcy8zMjI3M1xuICAgIGlmICghaHJlZkF0dHJpYnV0ZSB8fCAhaHJlZkF0dHJpYnV0ZS5pbmNsdWRlcygnIycpICYmICFocmVmQXR0cmlidXRlLnN0YXJ0c1dpdGgoJy4nKSkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgLy8gSnVzdCBpbiBjYXNlIHNvbWUgQ01TIHB1dHMgb3V0IGEgZnVsbCBVUkwgd2l0aCB0aGUgYW5jaG9yIGFwcGVuZGVkXG4gICAgaWYgKGhyZWZBdHRyaWJ1dGUuaW5jbHVkZXMoJyMnKSAmJiAhaHJlZkF0dHJpYnV0ZS5zdGFydHNXaXRoKCcjJykpIHtcbiAgICAgIGhyZWZBdHRyaWJ1dGUgPSBgIyR7aHJlZkF0dHJpYnV0ZS5zcGxpdCgnIycpWzFdfWA7XG4gICAgfVxuICAgIHNlbGVjdG9yID0gaHJlZkF0dHJpYnV0ZSAmJiBocmVmQXR0cmlidXRlICE9PSAnIycgPyBocmVmQXR0cmlidXRlLnRyaW0oKSA6IG51bGw7XG4gIH1cbiAgcmV0dXJuIHBhcnNlU2VsZWN0b3Ioc2VsZWN0b3IpO1xufTtcbmNvbnN0IFNlbGVjdG9yRW5naW5lID0ge1xuICBmaW5kKHNlbGVjdG9yLCBlbGVtZW50ID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50KSB7XG4gICAgcmV0dXJuIFtdLmNvbmNhdCguLi5FbGVtZW50LnByb3RvdHlwZS5xdWVyeVNlbGVjdG9yQWxsLmNhbGwoZWxlbWVudCwgc2VsZWN0b3IpKTtcbiAgfSxcbiAgZmluZE9uZShzZWxlY3RvciwgZWxlbWVudCA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCkge1xuICAgIHJldHVybiBFbGVtZW50LnByb3RvdHlwZS5xdWVyeVNlbGVjdG9yLmNhbGwoZWxlbWVudCwgc2VsZWN0b3IpO1xuICB9LFxuICBjaGlsZHJlbihlbGVtZW50LCBzZWxlY3Rvcikge1xuICAgIHJldHVybiBbXS5jb25jYXQoLi4uZWxlbWVudC5jaGlsZHJlbikuZmlsdGVyKGNoaWxkID0+IGNoaWxkLm1hdGNoZXMoc2VsZWN0b3IpKTtcbiAgfSxcbiAgcGFyZW50cyhlbGVtZW50LCBzZWxlY3Rvcikge1xuICAgIGNvbnN0IHBhcmVudHMgPSBbXTtcbiAgICBsZXQgYW5jZXN0b3IgPSBlbGVtZW50LnBhcmVudE5vZGUuY2xvc2VzdChzZWxlY3Rvcik7XG4gICAgd2hpbGUgKGFuY2VzdG9yKSB7XG4gICAgICBwYXJlbnRzLnB1c2goYW5jZXN0b3IpO1xuICAgICAgYW5jZXN0b3IgPSBhbmNlc3Rvci5wYXJlbnROb2RlLmNsb3Nlc3Qoc2VsZWN0b3IpO1xuICAgIH1cbiAgICByZXR1cm4gcGFyZW50cztcbiAgfSxcbiAgcHJldihlbGVtZW50LCBzZWxlY3Rvcikge1xuICAgIGxldCBwcmV2aW91cyA9IGVsZW1lbnQucHJldmlvdXNFbGVtZW50U2libGluZztcbiAgICB3aGlsZSAocHJldmlvdXMpIHtcbiAgICAgIGlmIChwcmV2aW91cy5tYXRjaGVzKHNlbGVjdG9yKSkge1xuICAgICAgICByZXR1cm4gW3ByZXZpb3VzXTtcbiAgICAgIH1cbiAgICAgIHByZXZpb3VzID0gcHJldmlvdXMucHJldmlvdXNFbGVtZW50U2libGluZztcbiAgICB9XG4gICAgcmV0dXJuIFtdO1xuICB9LFxuICAvLyBUT0RPOiB0aGlzIGlzIG5vdyB1bnVzZWQ7IHJlbW92ZSBsYXRlciBhbG9uZyB3aXRoIHByZXYoKVxuICBuZXh0KGVsZW1lbnQsIHNlbGVjdG9yKSB7XG4gICAgbGV0IG5leHQgPSBlbGVtZW50Lm5leHRFbGVtZW50U2libGluZztcbiAgICB3aGlsZSAobmV4dCkge1xuICAgICAgaWYgKG5leHQubWF0Y2hlcyhzZWxlY3RvcikpIHtcbiAgICAgICAgcmV0dXJuIFtuZXh0XTtcbiAgICAgIH1cbiAgICAgIG5leHQgPSBuZXh0Lm5leHRFbGVtZW50U2libGluZztcbiAgICB9XG4gICAgcmV0dXJuIFtdO1xuICB9LFxuICBmb2N1c2FibGVDaGlsZHJlbihlbGVtZW50KSB7XG4gICAgY29uc3QgZm9jdXNhYmxlcyA9IFsnYScsICdidXR0b24nLCAnaW5wdXQnLCAndGV4dGFyZWEnLCAnc2VsZWN0JywgJ2RldGFpbHMnLCAnW3RhYmluZGV4XScsICdbY29udGVudGVkaXRhYmxlPVwidHJ1ZVwiXSddLm1hcChzZWxlY3RvciA9PiBgJHtzZWxlY3Rvcn06bm90KFt0YWJpbmRleF49XCItXCJdKWApLmpvaW4oJywnKTtcbiAgICByZXR1cm4gdGhpcy5maW5kKGZvY3VzYWJsZXMsIGVsZW1lbnQpLmZpbHRlcihlbCA9PiAhaXNEaXNhYmxlZChlbCkgJiYgaXNWaXNpYmxlKGVsKSk7XG4gIH0sXG4gIGdldFNlbGVjdG9yRnJvbUVsZW1lbnQoZWxlbWVudCkge1xuICAgIGNvbnN0IHNlbGVjdG9yID0gZ2V0U2VsZWN0b3IoZWxlbWVudCk7XG4gICAgaWYgKHNlbGVjdG9yKSB7XG4gICAgICByZXR1cm4gU2VsZWN0b3JFbmdpbmUuZmluZE9uZShzZWxlY3RvcikgPyBzZWxlY3RvciA6IG51bGw7XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9LFxuICBnZXRFbGVtZW50RnJvbVNlbGVjdG9yKGVsZW1lbnQpIHtcbiAgICBjb25zdCBzZWxlY3RvciA9IGdldFNlbGVjdG9yKGVsZW1lbnQpO1xuICAgIHJldHVybiBzZWxlY3RvciA/IFNlbGVjdG9yRW5naW5lLmZpbmRPbmUoc2VsZWN0b3IpIDogbnVsbDtcbiAgfSxcbiAgZ2V0TXVsdGlwbGVFbGVtZW50c0Zyb21TZWxlY3RvcihlbGVtZW50KSB7XG4gICAgY29uc3Qgc2VsZWN0b3IgPSBnZXRTZWxlY3RvcihlbGVtZW50KTtcbiAgICByZXR1cm4gc2VsZWN0b3IgPyBTZWxlY3RvckVuZ2luZS5maW5kKHNlbGVjdG9yKSA6IFtdO1xuICB9XG59O1xuXG4vKipcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiBCb290c3RyYXAgdXRpbC9jb21wb25lbnQtZnVuY3Rpb25zLmpzXG4gKiBMaWNlbnNlZCB1bmRlciBNSVQgKGh0dHBzOi8vZ2l0aHViLmNvbS90d2JzL2Jvb3RzdHJhcC9ibG9iL21haW4vTElDRU5TRSlcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKi9cblxuY29uc3QgZW5hYmxlRGlzbWlzc1RyaWdnZXIgPSAoY29tcG9uZW50LCBtZXRob2QgPSAnaGlkZScpID0+IHtcbiAgY29uc3QgY2xpY2tFdmVudCA9IGBjbGljay5kaXNtaXNzJHtjb21wb25lbnQuRVZFTlRfS0VZfWA7XG4gIGNvbnN0IG5hbWUgPSBjb21wb25lbnQuTkFNRTtcbiAgRXZlbnRIYW5kbGVyLm9uKGRvY3VtZW50LCBjbGlja0V2ZW50LCBgW2RhdGEtYnMtZGlzbWlzcz1cIiR7bmFtZX1cIl1gLCBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICBpZiAoWydBJywgJ0FSRUEnXS5pbmNsdWRlcyh0aGlzLnRhZ05hbWUpKSB7XG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cbiAgICBpZiAoaXNEaXNhYmxlZCh0aGlzKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCB0YXJnZXQgPSBTZWxlY3RvckVuZ2luZS5nZXRFbGVtZW50RnJvbVNlbGVjdG9yKHRoaXMpIHx8IHRoaXMuY2xvc2VzdChgLiR7bmFtZX1gKTtcbiAgICBjb25zdCBpbnN0YW5jZSA9IGNvbXBvbmVudC5nZXRPckNyZWF0ZUluc3RhbmNlKHRhcmdldCk7XG5cbiAgICAvLyBNZXRob2QgYXJndW1lbnQgaXMgbGVmdCwgZm9yIEFsZXJ0IGFuZCBvbmx5LCBhcyBpdCBkb2Vzbid0IGltcGxlbWVudCB0aGUgJ2hpZGUnIG1ldGhvZFxuICAgIGluc3RhbmNlW21ldGhvZF0oKTtcbiAgfSk7XG59O1xuXG4vKipcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiBCb290c3RyYXAgYWxlcnQuanNcbiAqIExpY2Vuc2VkIHVuZGVyIE1JVCAoaHR0cHM6Ly9naXRodWIuY29tL3R3YnMvYm9vdHN0cmFwL2Jsb2IvbWFpbi9MSUNFTlNFKVxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqL1xuXG5cbi8qKlxuICogQ29uc3RhbnRzXG4gKi9cblxuY29uc3QgTkFNRSRmID0gJ2FsZXJ0JztcbmNvbnN0IERBVEFfS0VZJGEgPSAnYnMuYWxlcnQnO1xuY29uc3QgRVZFTlRfS0VZJGIgPSBgLiR7REFUQV9LRVkkYX1gO1xuY29uc3QgRVZFTlRfQ0xPU0UgPSBgY2xvc2Uke0VWRU5UX0tFWSRifWA7XG5jb25zdCBFVkVOVF9DTE9TRUQgPSBgY2xvc2VkJHtFVkVOVF9LRVkkYn1gO1xuY29uc3QgQ0xBU1NfTkFNRV9GQURFJDUgPSAnZmFkZSc7XG5jb25zdCBDTEFTU19OQU1FX1NIT1ckOCA9ICdzaG93JztcblxuLyoqXG4gKiBDbGFzcyBkZWZpbml0aW9uXG4gKi9cblxuY2xhc3MgQWxlcnQgZXh0ZW5kcyBCYXNlQ29tcG9uZW50IHtcbiAgLy8gR2V0dGVyc1xuICBzdGF0aWMgZ2V0IE5BTUUoKSB7XG4gICAgcmV0dXJuIE5BTUUkZjtcbiAgfVxuXG4gIC8vIFB1YmxpY1xuICBjbG9zZSgpIHtcbiAgICBjb25zdCBjbG9zZUV2ZW50ID0gRXZlbnRIYW5kbGVyLnRyaWdnZXIodGhpcy5fZWxlbWVudCwgRVZFTlRfQ0xPU0UpO1xuICAgIGlmIChjbG9zZUV2ZW50LmRlZmF1bHRQcmV2ZW50ZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5fZWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKENMQVNTX05BTUVfU0hPVyQ4KTtcbiAgICBjb25zdCBpc0FuaW1hdGVkID0gdGhpcy5fZWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoQ0xBU1NfTkFNRV9GQURFJDUpO1xuICAgIHRoaXMuX3F1ZXVlQ2FsbGJhY2soKCkgPT4gdGhpcy5fZGVzdHJveUVsZW1lbnQoKSwgdGhpcy5fZWxlbWVudCwgaXNBbmltYXRlZCk7XG4gIH1cblxuICAvLyBQcml2YXRlXG4gIF9kZXN0cm95RWxlbWVudCgpIHtcbiAgICB0aGlzLl9lbGVtZW50LnJlbW92ZSgpO1xuICAgIEV2ZW50SGFuZGxlci50cmlnZ2VyKHRoaXMuX2VsZW1lbnQsIEVWRU5UX0NMT1NFRCk7XG4gICAgdGhpcy5kaXNwb3NlKCk7XG4gIH1cblxuICAvLyBTdGF0aWNcbiAgc3RhdGljIGpRdWVyeUludGVyZmFjZShjb25maWcpIHtcbiAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGRhdGEgPSBBbGVydC5nZXRPckNyZWF0ZUluc3RhbmNlKHRoaXMpO1xuICAgICAgaWYgKHR5cGVvZiBjb25maWcgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmIChkYXRhW2NvbmZpZ10gPT09IHVuZGVmaW5lZCB8fCBjb25maWcuc3RhcnRzV2l0aCgnXycpIHx8IGNvbmZpZyA9PT0gJ2NvbnN0cnVjdG9yJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBObyBtZXRob2QgbmFtZWQgXCIke2NvbmZpZ31cImApO1xuICAgICAgfVxuICAgICAgZGF0YVtjb25maWddKHRoaXMpO1xuICAgIH0pO1xuICB9XG59XG5cbi8qKlxuICogRGF0YSBBUEkgaW1wbGVtZW50YXRpb25cbiAqL1xuXG5lbmFibGVEaXNtaXNzVHJpZ2dlcihBbGVydCwgJ2Nsb3NlJyk7XG5cbi8qKlxuICogalF1ZXJ5XG4gKi9cblxuZGVmaW5lSlF1ZXJ5UGx1Z2luKEFsZXJ0KTtcblxuLyoqXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogQm9vdHN0cmFwIGJ1dHRvbi5qc1xuICogTGljZW5zZWQgdW5kZXIgTUlUIChodHRwczovL2dpdGh1Yi5jb20vdHdicy9ib290c3RyYXAvYmxvYi9tYWluL0xJQ0VOU0UpXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICovXG5cblxuLyoqXG4gKiBDb25zdGFudHNcbiAqL1xuXG5jb25zdCBOQU1FJGUgPSAnYnV0dG9uJztcbmNvbnN0IERBVEFfS0VZJDkgPSAnYnMuYnV0dG9uJztcbmNvbnN0IEVWRU5UX0tFWSRhID0gYC4ke0RBVEFfS0VZJDl9YDtcbmNvbnN0IERBVEFfQVBJX0tFWSQ2ID0gJy5kYXRhLWFwaSc7XG5jb25zdCBDTEFTU19OQU1FX0FDVElWRSQzID0gJ2FjdGl2ZSc7XG5jb25zdCBTRUxFQ1RPUl9EQVRBX1RPR0dMRSQ1ID0gJ1tkYXRhLWJzLXRvZ2dsZT1cImJ1dHRvblwiXSc7XG5jb25zdCBFVkVOVF9DTElDS19EQVRBX0FQSSQ2ID0gYGNsaWNrJHtFVkVOVF9LRVkkYX0ke0RBVEFfQVBJX0tFWSQ2fWA7XG5cbi8qKlxuICogQ2xhc3MgZGVmaW5pdGlvblxuICovXG5cbmNsYXNzIEJ1dHRvbiBleHRlbmRzIEJhc2VDb21wb25lbnQge1xuICAvLyBHZXR0ZXJzXG4gIHN0YXRpYyBnZXQgTkFNRSgpIHtcbiAgICByZXR1cm4gTkFNRSRlO1xuICB9XG5cbiAgLy8gUHVibGljXG4gIHRvZ2dsZSgpIHtcbiAgICAvLyBUb2dnbGUgY2xhc3MgYW5kIHN5bmMgdGhlIGBhcmlhLXByZXNzZWRgIGF0dHJpYnV0ZSB3aXRoIHRoZSByZXR1cm4gdmFsdWUgb2YgdGhlIGAudG9nZ2xlKClgIG1ldGhvZFxuICAgIHRoaXMuX2VsZW1lbnQuc2V0QXR0cmlidXRlKCdhcmlhLXByZXNzZWQnLCB0aGlzLl9lbGVtZW50LmNsYXNzTGlzdC50b2dnbGUoQ0xBU1NfTkFNRV9BQ1RJVkUkMykpO1xuICB9XG5cbiAgLy8gU3RhdGljXG4gIHN0YXRpYyBqUXVlcnlJbnRlcmZhY2UoY29uZmlnKSB7XG4gICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBkYXRhID0gQnV0dG9uLmdldE9yQ3JlYXRlSW5zdGFuY2UodGhpcyk7XG4gICAgICBpZiAoY29uZmlnID09PSAndG9nZ2xlJykge1xuICAgICAgICBkYXRhW2NvbmZpZ10oKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufVxuXG4vKipcbiAqIERhdGEgQVBJIGltcGxlbWVudGF0aW9uXG4gKi9cblxuRXZlbnRIYW5kbGVyLm9uKGRvY3VtZW50LCBFVkVOVF9DTElDS19EQVRBX0FQSSQ2LCBTRUxFQ1RPUl9EQVRBX1RPR0dMRSQ1LCBldmVudCA9PiB7XG4gIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gIGNvbnN0IGJ1dHRvbiA9IGV2ZW50LnRhcmdldC5jbG9zZXN0KFNFTEVDVE9SX0RBVEFfVE9HR0xFJDUpO1xuICBjb25zdCBkYXRhID0gQnV0dG9uLmdldE9yQ3JlYXRlSW5zdGFuY2UoYnV0dG9uKTtcbiAgZGF0YS50b2dnbGUoKTtcbn0pO1xuXG4vKipcbiAqIGpRdWVyeVxuICovXG5cbmRlZmluZUpRdWVyeVBsdWdpbihCdXR0b24pO1xuXG4vKipcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiBCb290c3RyYXAgdXRpbC9zd2lwZS5qc1xuICogTGljZW5zZWQgdW5kZXIgTUlUIChodHRwczovL2dpdGh1Yi5jb20vdHdicy9ib290c3RyYXAvYmxvYi9tYWluL0xJQ0VOU0UpXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICovXG5cblxuLyoqXG4gKiBDb25zdGFudHNcbiAqL1xuXG5jb25zdCBOQU1FJGQgPSAnc3dpcGUnO1xuY29uc3QgRVZFTlRfS0VZJDkgPSAnLmJzLnN3aXBlJztcbmNvbnN0IEVWRU5UX1RPVUNIU1RBUlQgPSBgdG91Y2hzdGFydCR7RVZFTlRfS0VZJDl9YDtcbmNvbnN0IEVWRU5UX1RPVUNITU9WRSA9IGB0b3VjaG1vdmUke0VWRU5UX0tFWSQ5fWA7XG5jb25zdCBFVkVOVF9UT1VDSEVORCA9IGB0b3VjaGVuZCR7RVZFTlRfS0VZJDl9YDtcbmNvbnN0IEVWRU5UX1BPSU5URVJET1dOID0gYHBvaW50ZXJkb3duJHtFVkVOVF9LRVkkOX1gO1xuY29uc3QgRVZFTlRfUE9JTlRFUlVQID0gYHBvaW50ZXJ1cCR7RVZFTlRfS0VZJDl9YDtcbmNvbnN0IFBPSU5URVJfVFlQRV9UT1VDSCA9ICd0b3VjaCc7XG5jb25zdCBQT0lOVEVSX1RZUEVfUEVOID0gJ3Blbic7XG5jb25zdCBDTEFTU19OQU1FX1BPSU5URVJfRVZFTlQgPSAncG9pbnRlci1ldmVudCc7XG5jb25zdCBTV0lQRV9USFJFU0hPTEQgPSA0MDtcbmNvbnN0IERlZmF1bHQkYyA9IHtcbiAgZW5kQ2FsbGJhY2s6IG51bGwsXG4gIGxlZnRDYWxsYmFjazogbnVsbCxcbiAgcmlnaHRDYWxsYmFjazogbnVsbFxufTtcbmNvbnN0IERlZmF1bHRUeXBlJGMgPSB7XG4gIGVuZENhbGxiYWNrOiAnKGZ1bmN0aW9ufG51bGwpJyxcbiAgbGVmdENhbGxiYWNrOiAnKGZ1bmN0aW9ufG51bGwpJyxcbiAgcmlnaHRDYWxsYmFjazogJyhmdW5jdGlvbnxudWxsKSdcbn07XG5cbi8qKlxuICogQ2xhc3MgZGVmaW5pdGlvblxuICovXG5cbmNsYXNzIFN3aXBlIGV4dGVuZHMgQ29uZmlnIHtcbiAgY29uc3RydWN0b3IoZWxlbWVudCwgY29uZmlnKSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLl9lbGVtZW50ID0gZWxlbWVudDtcbiAgICBpZiAoIWVsZW1lbnQgfHwgIVN3aXBlLmlzU3VwcG9ydGVkKCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5fY29uZmlnID0gdGhpcy5fZ2V0Q29uZmlnKGNvbmZpZyk7XG4gICAgdGhpcy5fZGVsdGFYID0gMDtcbiAgICB0aGlzLl9zdXBwb3J0UG9pbnRlckV2ZW50cyA9IEJvb2xlYW4od2luZG93LlBvaW50ZXJFdmVudCk7XG4gICAgdGhpcy5faW5pdEV2ZW50cygpO1xuICB9XG5cbiAgLy8gR2V0dGVyc1xuICBzdGF0aWMgZ2V0IERlZmF1bHQoKSB7XG4gICAgcmV0dXJuIERlZmF1bHQkYztcbiAgfVxuICBzdGF0aWMgZ2V0IERlZmF1bHRUeXBlKCkge1xuICAgIHJldHVybiBEZWZhdWx0VHlwZSRjO1xuICB9XG4gIHN0YXRpYyBnZXQgTkFNRSgpIHtcbiAgICByZXR1cm4gTkFNRSRkO1xuICB9XG5cbiAgLy8gUHVibGljXG4gIGRpc3Bvc2UoKSB7XG4gICAgRXZlbnRIYW5kbGVyLm9mZih0aGlzLl9lbGVtZW50LCBFVkVOVF9LRVkkOSk7XG4gIH1cblxuICAvLyBQcml2YXRlXG4gIF9zdGFydChldmVudCkge1xuICAgIGlmICghdGhpcy5fc3VwcG9ydFBvaW50ZXJFdmVudHMpIHtcbiAgICAgIHRoaXMuX2RlbHRhWCA9IGV2ZW50LnRvdWNoZXNbMF0uY2xpZW50WDtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHRoaXMuX2V2ZW50SXNQb2ludGVyUGVuVG91Y2goZXZlbnQpKSB7XG4gICAgICB0aGlzLl9kZWx0YVggPSBldmVudC5jbGllbnRYO1xuICAgIH1cbiAgfVxuICBfZW5kKGV2ZW50KSB7XG4gICAgaWYgKHRoaXMuX2V2ZW50SXNQb2ludGVyUGVuVG91Y2goZXZlbnQpKSB7XG4gICAgICB0aGlzLl9kZWx0YVggPSBldmVudC5jbGllbnRYIC0gdGhpcy5fZGVsdGFYO1xuICAgIH1cbiAgICB0aGlzLl9oYW5kbGVTd2lwZSgpO1xuICAgIGV4ZWN1dGUodGhpcy5fY29uZmlnLmVuZENhbGxiYWNrKTtcbiAgfVxuICBfbW92ZShldmVudCkge1xuICAgIHRoaXMuX2RlbHRhWCA9IGV2ZW50LnRvdWNoZXMgJiYgZXZlbnQudG91Y2hlcy5sZW5ndGggPiAxID8gMCA6IGV2ZW50LnRvdWNoZXNbMF0uY2xpZW50WCAtIHRoaXMuX2RlbHRhWDtcbiAgfVxuICBfaGFuZGxlU3dpcGUoKSB7XG4gICAgY29uc3QgYWJzRGVsdGFYID0gTWF0aC5hYnModGhpcy5fZGVsdGFYKTtcbiAgICBpZiAoYWJzRGVsdGFYIDw9IFNXSVBFX1RIUkVTSE9MRCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBkaXJlY3Rpb24gPSBhYnNEZWx0YVggLyB0aGlzLl9kZWx0YVg7XG4gICAgdGhpcy5fZGVsdGFYID0gMDtcbiAgICBpZiAoIWRpcmVjdGlvbikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBleGVjdXRlKGRpcmVjdGlvbiA+IDAgPyB0aGlzLl9jb25maWcucmlnaHRDYWxsYmFjayA6IHRoaXMuX2NvbmZpZy5sZWZ0Q2FsbGJhY2spO1xuICB9XG4gIF9pbml0RXZlbnRzKCkge1xuICAgIGlmICh0aGlzLl9zdXBwb3J0UG9pbnRlckV2ZW50cykge1xuICAgICAgRXZlbnRIYW5kbGVyLm9uKHRoaXMuX2VsZW1lbnQsIEVWRU5UX1BPSU5URVJET1dOLCBldmVudCA9PiB0aGlzLl9zdGFydChldmVudCkpO1xuICAgICAgRXZlbnRIYW5kbGVyLm9uKHRoaXMuX2VsZW1lbnQsIEVWRU5UX1BPSU5URVJVUCwgZXZlbnQgPT4gdGhpcy5fZW5kKGV2ZW50KSk7XG4gICAgICB0aGlzLl9lbGVtZW50LmNsYXNzTGlzdC5hZGQoQ0xBU1NfTkFNRV9QT0lOVEVSX0VWRU5UKTtcbiAgICB9IGVsc2Uge1xuICAgICAgRXZlbnRIYW5kbGVyLm9uKHRoaXMuX2VsZW1lbnQsIEVWRU5UX1RPVUNIU1RBUlQsIGV2ZW50ID0+IHRoaXMuX3N0YXJ0KGV2ZW50KSk7XG4gICAgICBFdmVudEhhbmRsZXIub24odGhpcy5fZWxlbWVudCwgRVZFTlRfVE9VQ0hNT1ZFLCBldmVudCA9PiB0aGlzLl9tb3ZlKGV2ZW50KSk7XG4gICAgICBFdmVudEhhbmRsZXIub24odGhpcy5fZWxlbWVudCwgRVZFTlRfVE9VQ0hFTkQsIGV2ZW50ID0+IHRoaXMuX2VuZChldmVudCkpO1xuICAgIH1cbiAgfVxuICBfZXZlbnRJc1BvaW50ZXJQZW5Ub3VjaChldmVudCkge1xuICAgIHJldHVybiB0aGlzLl9zdXBwb3J0UG9pbnRlckV2ZW50cyAmJiAoZXZlbnQucG9pbnRlclR5cGUgPT09IFBPSU5URVJfVFlQRV9QRU4gfHwgZXZlbnQucG9pbnRlclR5cGUgPT09IFBPSU5URVJfVFlQRV9UT1VDSCk7XG4gIH1cblxuICAvLyBTdGF0aWNcbiAgc3RhdGljIGlzU3VwcG9ydGVkKCkge1xuICAgIHJldHVybiAnb250b3VjaHN0YXJ0JyBpbiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQgfHwgbmF2aWdhdG9yLm1heFRvdWNoUG9pbnRzID4gMDtcbiAgfVxufVxuXG4vKipcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiBCb290c3RyYXAgY2Fyb3VzZWwuanNcbiAqIExpY2Vuc2VkIHVuZGVyIE1JVCAoaHR0cHM6Ly9naXRodWIuY29tL3R3YnMvYm9vdHN0cmFwL2Jsb2IvbWFpbi9MSUNFTlNFKVxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqL1xuXG5cbi8qKlxuICogQ29uc3RhbnRzXG4gKi9cblxuY29uc3QgTkFNRSRjID0gJ2Nhcm91c2VsJztcbmNvbnN0IERBVEFfS0VZJDggPSAnYnMuY2Fyb3VzZWwnO1xuY29uc3QgRVZFTlRfS0VZJDggPSBgLiR7REFUQV9LRVkkOH1gO1xuY29uc3QgREFUQV9BUElfS0VZJDUgPSAnLmRhdGEtYXBpJztcbmNvbnN0IEFSUk9XX0xFRlRfS0VZJDEgPSAnQXJyb3dMZWZ0JztcbmNvbnN0IEFSUk9XX1JJR0hUX0tFWSQxID0gJ0Fycm93UmlnaHQnO1xuY29uc3QgVE9VQ0hFVkVOVF9DT01QQVRfV0FJVCA9IDUwMDsgLy8gVGltZSBmb3IgbW91c2UgY29tcGF0IGV2ZW50cyB0byBmaXJlIGFmdGVyIHRvdWNoXG5cbmNvbnN0IE9SREVSX05FWFQgPSAnbmV4dCc7XG5jb25zdCBPUkRFUl9QUkVWID0gJ3ByZXYnO1xuY29uc3QgRElSRUNUSU9OX0xFRlQgPSAnbGVmdCc7XG5jb25zdCBESVJFQ1RJT05fUklHSFQgPSAncmlnaHQnO1xuY29uc3QgRVZFTlRfU0xJREUgPSBgc2xpZGUke0VWRU5UX0tFWSQ4fWA7XG5jb25zdCBFVkVOVF9TTElEID0gYHNsaWQke0VWRU5UX0tFWSQ4fWA7XG5jb25zdCBFVkVOVF9LRVlET1dOJDEgPSBga2V5ZG93biR7RVZFTlRfS0VZJDh9YDtcbmNvbnN0IEVWRU5UX01PVVNFRU5URVIkMSA9IGBtb3VzZWVudGVyJHtFVkVOVF9LRVkkOH1gO1xuY29uc3QgRVZFTlRfTU9VU0VMRUFWRSQxID0gYG1vdXNlbGVhdmUke0VWRU5UX0tFWSQ4fWA7XG5jb25zdCBFVkVOVF9EUkFHX1NUQVJUID0gYGRyYWdzdGFydCR7RVZFTlRfS0VZJDh9YDtcbmNvbnN0IEVWRU5UX0xPQURfREFUQV9BUEkkMyA9IGBsb2FkJHtFVkVOVF9LRVkkOH0ke0RBVEFfQVBJX0tFWSQ1fWA7XG5jb25zdCBFVkVOVF9DTElDS19EQVRBX0FQSSQ1ID0gYGNsaWNrJHtFVkVOVF9LRVkkOH0ke0RBVEFfQVBJX0tFWSQ1fWA7XG5jb25zdCBDTEFTU19OQU1FX0NBUk9VU0VMID0gJ2Nhcm91c2VsJztcbmNvbnN0IENMQVNTX05BTUVfQUNUSVZFJDIgPSAnYWN0aXZlJztcbmNvbnN0IENMQVNTX05BTUVfU0xJREUgPSAnc2xpZGUnO1xuY29uc3QgQ0xBU1NfTkFNRV9FTkQgPSAnY2Fyb3VzZWwtaXRlbS1lbmQnO1xuY29uc3QgQ0xBU1NfTkFNRV9TVEFSVCA9ICdjYXJvdXNlbC1pdGVtLXN0YXJ0JztcbmNvbnN0IENMQVNTX05BTUVfTkVYVCA9ICdjYXJvdXNlbC1pdGVtLW5leHQnO1xuY29uc3QgQ0xBU1NfTkFNRV9QUkVWID0gJ2Nhcm91c2VsLWl0ZW0tcHJldic7XG5jb25zdCBTRUxFQ1RPUl9BQ1RJVkUgPSAnLmFjdGl2ZSc7XG5jb25zdCBTRUxFQ1RPUl9JVEVNID0gJy5jYXJvdXNlbC1pdGVtJztcbmNvbnN0IFNFTEVDVE9SX0FDVElWRV9JVEVNID0gU0VMRUNUT1JfQUNUSVZFICsgU0VMRUNUT1JfSVRFTTtcbmNvbnN0IFNFTEVDVE9SX0lURU1fSU1HID0gJy5jYXJvdXNlbC1pdGVtIGltZyc7XG5jb25zdCBTRUxFQ1RPUl9JTkRJQ0FUT1JTID0gJy5jYXJvdXNlbC1pbmRpY2F0b3JzJztcbmNvbnN0IFNFTEVDVE9SX0RBVEFfU0xJREUgPSAnW2RhdGEtYnMtc2xpZGVdLCBbZGF0YS1icy1zbGlkZS10b10nO1xuY29uc3QgU0VMRUNUT1JfREFUQV9SSURFID0gJ1tkYXRhLWJzLXJpZGU9XCJjYXJvdXNlbFwiXSc7XG5jb25zdCBLRVlfVE9fRElSRUNUSU9OID0ge1xuICBbQVJST1dfTEVGVF9LRVkkMV06IERJUkVDVElPTl9SSUdIVCxcbiAgW0FSUk9XX1JJR0hUX0tFWSQxXTogRElSRUNUSU9OX0xFRlRcbn07XG5jb25zdCBEZWZhdWx0JGIgPSB7XG4gIGludGVydmFsOiA1MDAwLFxuICBrZXlib2FyZDogdHJ1ZSxcbiAgcGF1c2U6ICdob3ZlcicsXG4gIHJpZGU6IGZhbHNlLFxuICB0b3VjaDogdHJ1ZSxcbiAgd3JhcDogdHJ1ZVxufTtcbmNvbnN0IERlZmF1bHRUeXBlJGIgPSB7XG4gIGludGVydmFsOiAnKG51bWJlcnxib29sZWFuKScsXG4gIC8vIFRPRE86djYgcmVtb3ZlIGJvb2xlYW4gc3VwcG9ydFxuICBrZXlib2FyZDogJ2Jvb2xlYW4nLFxuICBwYXVzZTogJyhzdHJpbmd8Ym9vbGVhbiknLFxuICByaWRlOiAnKGJvb2xlYW58c3RyaW5nKScsXG4gIHRvdWNoOiAnYm9vbGVhbicsXG4gIHdyYXA6ICdib29sZWFuJ1xufTtcblxuLyoqXG4gKiBDbGFzcyBkZWZpbml0aW9uXG4gKi9cblxuY2xhc3MgQ2Fyb3VzZWwgZXh0ZW5kcyBCYXNlQ29tcG9uZW50IHtcbiAgY29uc3RydWN0b3IoZWxlbWVudCwgY29uZmlnKSB7XG4gICAgc3VwZXIoZWxlbWVudCwgY29uZmlnKTtcbiAgICB0aGlzLl9pbnRlcnZhbCA9IG51bGw7XG4gICAgdGhpcy5fYWN0aXZlRWxlbWVudCA9IG51bGw7XG4gICAgdGhpcy5faXNTbGlkaW5nID0gZmFsc2U7XG4gICAgdGhpcy50b3VjaFRpbWVvdXQgPSBudWxsO1xuICAgIHRoaXMuX3N3aXBlSGVscGVyID0gbnVsbDtcbiAgICB0aGlzLl9pbmRpY2F0b3JzRWxlbWVudCA9IFNlbGVjdG9yRW5naW5lLmZpbmRPbmUoU0VMRUNUT1JfSU5ESUNBVE9SUywgdGhpcy5fZWxlbWVudCk7XG4gICAgdGhpcy5fYWRkRXZlbnRMaXN0ZW5lcnMoKTtcbiAgICBpZiAodGhpcy5fY29uZmlnLnJpZGUgPT09IENMQVNTX05BTUVfQ0FST1VTRUwpIHtcbiAgICAgIHRoaXMuY3ljbGUoKTtcbiAgICB9XG4gIH1cblxuICAvLyBHZXR0ZXJzXG4gIHN0YXRpYyBnZXQgRGVmYXVsdCgpIHtcbiAgICByZXR1cm4gRGVmYXVsdCRiO1xuICB9XG4gIHN0YXRpYyBnZXQgRGVmYXVsdFR5cGUoKSB7XG4gICAgcmV0dXJuIERlZmF1bHRUeXBlJGI7XG4gIH1cbiAgc3RhdGljIGdldCBOQU1FKCkge1xuICAgIHJldHVybiBOQU1FJGM7XG4gIH1cblxuICAvLyBQdWJsaWNcbiAgbmV4dCgpIHtcbiAgICB0aGlzLl9zbGlkZShPUkRFUl9ORVhUKTtcbiAgfVxuICBuZXh0V2hlblZpc2libGUoKSB7XG4gICAgLy8gRklYTUUgVE9ETyB1c2UgYGRvY3VtZW50LnZpc2liaWxpdHlTdGF0ZWBcbiAgICAvLyBEb24ndCBjYWxsIG5leHQgd2hlbiB0aGUgcGFnZSBpc24ndCB2aXNpYmxlXG4gICAgLy8gb3IgdGhlIGNhcm91c2VsIG9yIGl0cyBwYXJlbnQgaXNuJ3QgdmlzaWJsZVxuICAgIGlmICghZG9jdW1lbnQuaGlkZGVuICYmIGlzVmlzaWJsZSh0aGlzLl9lbGVtZW50KSkge1xuICAgICAgdGhpcy5uZXh0KCk7XG4gICAgfVxuICB9XG4gIHByZXYoKSB7XG4gICAgdGhpcy5fc2xpZGUoT1JERVJfUFJFVik7XG4gIH1cbiAgcGF1c2UoKSB7XG4gICAgaWYgKHRoaXMuX2lzU2xpZGluZykge1xuICAgICAgdHJpZ2dlclRyYW5zaXRpb25FbmQodGhpcy5fZWxlbWVudCk7XG4gICAgfVxuICAgIHRoaXMuX2NsZWFySW50ZXJ2YWwoKTtcbiAgfVxuICBjeWNsZSgpIHtcbiAgICB0aGlzLl9jbGVhckludGVydmFsKCk7XG4gICAgdGhpcy5fdXBkYXRlSW50ZXJ2YWwoKTtcbiAgICB0aGlzLl9pbnRlcnZhbCA9IHNldEludGVydmFsKCgpID0+IHRoaXMubmV4dFdoZW5WaXNpYmxlKCksIHRoaXMuX2NvbmZpZy5pbnRlcnZhbCk7XG4gIH1cbiAgX21heWJlRW5hYmxlQ3ljbGUoKSB7XG4gICAgaWYgKCF0aGlzLl9jb25maWcucmlkZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAodGhpcy5faXNTbGlkaW5nKSB7XG4gICAgICBFdmVudEhhbmRsZXIub25lKHRoaXMuX2VsZW1lbnQsIEVWRU5UX1NMSUQsICgpID0+IHRoaXMuY3ljbGUoKSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuY3ljbGUoKTtcbiAgfVxuICB0byhpbmRleCkge1xuICAgIGNvbnN0IGl0ZW1zID0gdGhpcy5fZ2V0SXRlbXMoKTtcbiAgICBpZiAoaW5kZXggPiBpdGVtcy5sZW5ndGggLSAxIHx8IGluZGV4IDwgMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAodGhpcy5faXNTbGlkaW5nKSB7XG4gICAgICBFdmVudEhhbmRsZXIub25lKHRoaXMuX2VsZW1lbnQsIEVWRU5UX1NMSUQsICgpID0+IHRoaXMudG8oaW5kZXgpKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgYWN0aXZlSW5kZXggPSB0aGlzLl9nZXRJdGVtSW5kZXgodGhpcy5fZ2V0QWN0aXZlKCkpO1xuICAgIGlmIChhY3RpdmVJbmRleCA9PT0gaW5kZXgpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3Qgb3JkZXIgPSBpbmRleCA+IGFjdGl2ZUluZGV4ID8gT1JERVJfTkVYVCA6IE9SREVSX1BSRVY7XG4gICAgdGhpcy5fc2xpZGUob3JkZXIsIGl0ZW1zW2luZGV4XSk7XG4gIH1cbiAgZGlzcG9zZSgpIHtcbiAgICBpZiAodGhpcy5fc3dpcGVIZWxwZXIpIHtcbiAgICAgIHRoaXMuX3N3aXBlSGVscGVyLmRpc3Bvc2UoKTtcbiAgICB9XG4gICAgc3VwZXIuZGlzcG9zZSgpO1xuICB9XG5cbiAgLy8gUHJpdmF0ZVxuICBfY29uZmlnQWZ0ZXJNZXJnZShjb25maWcpIHtcbiAgICBjb25maWcuZGVmYXVsdEludGVydmFsID0gY29uZmlnLmludGVydmFsO1xuICAgIHJldHVybiBjb25maWc7XG4gIH1cbiAgX2FkZEV2ZW50TGlzdGVuZXJzKCkge1xuICAgIGlmICh0aGlzLl9jb25maWcua2V5Ym9hcmQpIHtcbiAgICAgIEV2ZW50SGFuZGxlci5vbih0aGlzLl9lbGVtZW50LCBFVkVOVF9LRVlET1dOJDEsIGV2ZW50ID0+IHRoaXMuX2tleWRvd24oZXZlbnQpKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuX2NvbmZpZy5wYXVzZSA9PT0gJ2hvdmVyJykge1xuICAgICAgRXZlbnRIYW5kbGVyLm9uKHRoaXMuX2VsZW1lbnQsIEVWRU5UX01PVVNFRU5URVIkMSwgKCkgPT4gdGhpcy5wYXVzZSgpKTtcbiAgICAgIEV2ZW50SGFuZGxlci5vbih0aGlzLl9lbGVtZW50LCBFVkVOVF9NT1VTRUxFQVZFJDEsICgpID0+IHRoaXMuX21heWJlRW5hYmxlQ3ljbGUoKSk7XG4gICAgfVxuICAgIGlmICh0aGlzLl9jb25maWcudG91Y2ggJiYgU3dpcGUuaXNTdXBwb3J0ZWQoKSkge1xuICAgICAgdGhpcy5fYWRkVG91Y2hFdmVudExpc3RlbmVycygpO1xuICAgIH1cbiAgfVxuICBfYWRkVG91Y2hFdmVudExpc3RlbmVycygpIHtcbiAgICBmb3IgKGNvbnN0IGltZyBvZiBTZWxlY3RvckVuZ2luZS5maW5kKFNFTEVDVE9SX0lURU1fSU1HLCB0aGlzLl9lbGVtZW50KSkge1xuICAgICAgRXZlbnRIYW5kbGVyLm9uKGltZywgRVZFTlRfRFJBR19TVEFSVCwgZXZlbnQgPT4gZXZlbnQucHJldmVudERlZmF1bHQoKSk7XG4gICAgfVxuICAgIGNvbnN0IGVuZENhbGxCYWNrID0gKCkgPT4ge1xuICAgICAgaWYgKHRoaXMuX2NvbmZpZy5wYXVzZSAhPT0gJ2hvdmVyJykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIElmIGl0J3MgYSB0b3VjaC1lbmFibGVkIGRldmljZSwgbW91c2VlbnRlci9sZWF2ZSBhcmUgZmlyZWQgYXNcbiAgICAgIC8vIHBhcnQgb2YgdGhlIG1vdXNlIGNvbXBhdGliaWxpdHkgZXZlbnRzIG9uIGZpcnN0IHRhcCAtIHRoZSBjYXJvdXNlbFxuICAgICAgLy8gd291bGQgc3RvcCBjeWNsaW5nIHVudGlsIHVzZXIgdGFwcGVkIG91dCBvZiBpdDtcbiAgICAgIC8vIGhlcmUsIHdlIGxpc3RlbiBmb3IgdG91Y2hlbmQsIGV4cGxpY2l0bHkgcGF1c2UgdGhlIGNhcm91c2VsXG4gICAgICAvLyAoYXMgaWYgaXQncyB0aGUgc2Vjb25kIHRpbWUgd2UgdGFwIG9uIGl0LCBtb3VzZWVudGVyIGNvbXBhdCBldmVudFxuICAgICAgLy8gaXMgTk9UIGZpcmVkKSBhbmQgYWZ0ZXIgYSB0aW1lb3V0ICh0byBhbGxvdyBmb3IgbW91c2UgY29tcGF0aWJpbGl0eVxuICAgICAgLy8gZXZlbnRzIHRvIGZpcmUpIHdlIGV4cGxpY2l0bHkgcmVzdGFydCBjeWNsaW5nXG5cbiAgICAgIHRoaXMucGF1c2UoKTtcbiAgICAgIGlmICh0aGlzLnRvdWNoVGltZW91dCkge1xuICAgICAgICBjbGVhclRpbWVvdXQodGhpcy50b3VjaFRpbWVvdXQpO1xuICAgICAgfVxuICAgICAgdGhpcy50b3VjaFRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHRoaXMuX21heWJlRW5hYmxlQ3ljbGUoKSwgVE9VQ0hFVkVOVF9DT01QQVRfV0FJVCArIHRoaXMuX2NvbmZpZy5pbnRlcnZhbCk7XG4gICAgfTtcbiAgICBjb25zdCBzd2lwZUNvbmZpZyA9IHtcbiAgICAgIGxlZnRDYWxsYmFjazogKCkgPT4gdGhpcy5fc2xpZGUodGhpcy5fZGlyZWN0aW9uVG9PcmRlcihESVJFQ1RJT05fTEVGVCkpLFxuICAgICAgcmlnaHRDYWxsYmFjazogKCkgPT4gdGhpcy5fc2xpZGUodGhpcy5fZGlyZWN0aW9uVG9PcmRlcihESVJFQ1RJT05fUklHSFQpKSxcbiAgICAgIGVuZENhbGxiYWNrOiBlbmRDYWxsQmFja1xuICAgIH07XG4gICAgdGhpcy5fc3dpcGVIZWxwZXIgPSBuZXcgU3dpcGUodGhpcy5fZWxlbWVudCwgc3dpcGVDb25maWcpO1xuICB9XG4gIF9rZXlkb3duKGV2ZW50KSB7XG4gICAgaWYgKC9pbnB1dHx0ZXh0YXJlYS9pLnRlc3QoZXZlbnQudGFyZ2V0LnRhZ05hbWUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGRpcmVjdGlvbiA9IEtFWV9UT19ESVJFQ1RJT05bZXZlbnQua2V5XTtcbiAgICBpZiAoZGlyZWN0aW9uKSB7XG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgdGhpcy5fc2xpZGUodGhpcy5fZGlyZWN0aW9uVG9PcmRlcihkaXJlY3Rpb24pKTtcbiAgICB9XG4gIH1cbiAgX2dldEl0ZW1JbmRleChlbGVtZW50KSB7XG4gICAgcmV0dXJuIHRoaXMuX2dldEl0ZW1zKCkuaW5kZXhPZihlbGVtZW50KTtcbiAgfVxuICBfc2V0QWN0aXZlSW5kaWNhdG9yRWxlbWVudChpbmRleCkge1xuICAgIGlmICghdGhpcy5faW5kaWNhdG9yc0VsZW1lbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgYWN0aXZlSW5kaWNhdG9yID0gU2VsZWN0b3JFbmdpbmUuZmluZE9uZShTRUxFQ1RPUl9BQ1RJVkUsIHRoaXMuX2luZGljYXRvcnNFbGVtZW50KTtcbiAgICBhY3RpdmVJbmRpY2F0b3IuY2xhc3NMaXN0LnJlbW92ZShDTEFTU19OQU1FX0FDVElWRSQyKTtcbiAgICBhY3RpdmVJbmRpY2F0b3IucmVtb3ZlQXR0cmlidXRlKCdhcmlhLWN1cnJlbnQnKTtcbiAgICBjb25zdCBuZXdBY3RpdmVJbmRpY2F0b3IgPSBTZWxlY3RvckVuZ2luZS5maW5kT25lKGBbZGF0YS1icy1zbGlkZS10bz1cIiR7aW5kZXh9XCJdYCwgdGhpcy5faW5kaWNhdG9yc0VsZW1lbnQpO1xuICAgIGlmIChuZXdBY3RpdmVJbmRpY2F0b3IpIHtcbiAgICAgIG5ld0FjdGl2ZUluZGljYXRvci5jbGFzc0xpc3QuYWRkKENMQVNTX05BTUVfQUNUSVZFJDIpO1xuICAgICAgbmV3QWN0aXZlSW5kaWNhdG9yLnNldEF0dHJpYnV0ZSgnYXJpYS1jdXJyZW50JywgJ3RydWUnKTtcbiAgICB9XG4gIH1cbiAgX3VwZGF0ZUludGVydmFsKCkge1xuICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLl9hY3RpdmVFbGVtZW50IHx8IHRoaXMuX2dldEFjdGl2ZSgpO1xuICAgIGlmICghZWxlbWVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBlbGVtZW50SW50ZXJ2YWwgPSBOdW1iZXIucGFyc2VJbnQoZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2RhdGEtYnMtaW50ZXJ2YWwnKSwgMTApO1xuICAgIHRoaXMuX2NvbmZpZy5pbnRlcnZhbCA9IGVsZW1lbnRJbnRlcnZhbCB8fCB0aGlzLl9jb25maWcuZGVmYXVsdEludGVydmFsO1xuICB9XG4gIF9zbGlkZShvcmRlciwgZWxlbWVudCA9IG51bGwpIHtcbiAgICBpZiAodGhpcy5faXNTbGlkaW5nKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGFjdGl2ZUVsZW1lbnQgPSB0aGlzLl9nZXRBY3RpdmUoKTtcbiAgICBjb25zdCBpc05leHQgPSBvcmRlciA9PT0gT1JERVJfTkVYVDtcbiAgICBjb25zdCBuZXh0RWxlbWVudCA9IGVsZW1lbnQgfHwgZ2V0TmV4dEFjdGl2ZUVsZW1lbnQodGhpcy5fZ2V0SXRlbXMoKSwgYWN0aXZlRWxlbWVudCwgaXNOZXh0LCB0aGlzLl9jb25maWcud3JhcCk7XG4gICAgaWYgKG5leHRFbGVtZW50ID09PSBhY3RpdmVFbGVtZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IG5leHRFbGVtZW50SW5kZXggPSB0aGlzLl9nZXRJdGVtSW5kZXgobmV4dEVsZW1lbnQpO1xuICAgIGNvbnN0IHRyaWdnZXJFdmVudCA9IGV2ZW50TmFtZSA9PiB7XG4gICAgICByZXR1cm4gRXZlbnRIYW5kbGVyLnRyaWdnZXIodGhpcy5fZWxlbWVudCwgZXZlbnROYW1lLCB7XG4gICAgICAgIHJlbGF0ZWRUYXJnZXQ6IG5leHRFbGVtZW50LFxuICAgICAgICBkaXJlY3Rpb246IHRoaXMuX29yZGVyVG9EaXJlY3Rpb24ob3JkZXIpLFxuICAgICAgICBmcm9tOiB0aGlzLl9nZXRJdGVtSW5kZXgoYWN0aXZlRWxlbWVudCksXG4gICAgICAgIHRvOiBuZXh0RWxlbWVudEluZGV4XG4gICAgICB9KTtcbiAgICB9O1xuICAgIGNvbnN0IHNsaWRlRXZlbnQgPSB0cmlnZ2VyRXZlbnQoRVZFTlRfU0xJREUpO1xuICAgIGlmIChzbGlkZUV2ZW50LmRlZmF1bHRQcmV2ZW50ZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKCFhY3RpdmVFbGVtZW50IHx8ICFuZXh0RWxlbWVudCkge1xuICAgICAgLy8gU29tZSB3ZWlyZG5lc3MgaXMgaGFwcGVuaW5nLCBzbyB3ZSBiYWlsXG4gICAgICAvLyBUT0RPOiBjaGFuZ2UgdGVzdHMgdGhhdCB1c2UgZW1wdHkgZGl2cyB0byBhdm9pZCB0aGlzIGNoZWNrXG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGlzQ3ljbGluZyA9IEJvb2xlYW4odGhpcy5faW50ZXJ2YWwpO1xuICAgIHRoaXMucGF1c2UoKTtcbiAgICB0aGlzLl9pc1NsaWRpbmcgPSB0cnVlO1xuICAgIHRoaXMuX3NldEFjdGl2ZUluZGljYXRvckVsZW1lbnQobmV4dEVsZW1lbnRJbmRleCk7XG4gICAgdGhpcy5fYWN0aXZlRWxlbWVudCA9IG5leHRFbGVtZW50O1xuICAgIGNvbnN0IGRpcmVjdGlvbmFsQ2xhc3NOYW1lID0gaXNOZXh0ID8gQ0xBU1NfTkFNRV9TVEFSVCA6IENMQVNTX05BTUVfRU5EO1xuICAgIGNvbnN0IG9yZGVyQ2xhc3NOYW1lID0gaXNOZXh0ID8gQ0xBU1NfTkFNRV9ORVhUIDogQ0xBU1NfTkFNRV9QUkVWO1xuICAgIG5leHRFbGVtZW50LmNsYXNzTGlzdC5hZGQob3JkZXJDbGFzc05hbWUpO1xuICAgIHJlZmxvdyhuZXh0RWxlbWVudCk7XG4gICAgYWN0aXZlRWxlbWVudC5jbGFzc0xpc3QuYWRkKGRpcmVjdGlvbmFsQ2xhc3NOYW1lKTtcbiAgICBuZXh0RWxlbWVudC5jbGFzc0xpc3QuYWRkKGRpcmVjdGlvbmFsQ2xhc3NOYW1lKTtcbiAgICBjb25zdCBjb21wbGV0ZUNhbGxCYWNrID0gKCkgPT4ge1xuICAgICAgbmV4dEVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZShkaXJlY3Rpb25hbENsYXNzTmFtZSwgb3JkZXJDbGFzc05hbWUpO1xuICAgICAgbmV4dEVsZW1lbnQuY2xhc3NMaXN0LmFkZChDTEFTU19OQU1FX0FDVElWRSQyKTtcbiAgICAgIGFjdGl2ZUVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZShDTEFTU19OQU1FX0FDVElWRSQyLCBvcmRlckNsYXNzTmFtZSwgZGlyZWN0aW9uYWxDbGFzc05hbWUpO1xuICAgICAgdGhpcy5faXNTbGlkaW5nID0gZmFsc2U7XG4gICAgICB0cmlnZ2VyRXZlbnQoRVZFTlRfU0xJRCk7XG4gICAgfTtcbiAgICB0aGlzLl9xdWV1ZUNhbGxiYWNrKGNvbXBsZXRlQ2FsbEJhY2ssIGFjdGl2ZUVsZW1lbnQsIHRoaXMuX2lzQW5pbWF0ZWQoKSk7XG4gICAgaWYgKGlzQ3ljbGluZykge1xuICAgICAgdGhpcy5jeWNsZSgpO1xuICAgIH1cbiAgfVxuICBfaXNBbmltYXRlZCgpIHtcbiAgICByZXR1cm4gdGhpcy5fZWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoQ0xBU1NfTkFNRV9TTElERSk7XG4gIH1cbiAgX2dldEFjdGl2ZSgpIHtcbiAgICByZXR1cm4gU2VsZWN0b3JFbmdpbmUuZmluZE9uZShTRUxFQ1RPUl9BQ1RJVkVfSVRFTSwgdGhpcy5fZWxlbWVudCk7XG4gIH1cbiAgX2dldEl0ZW1zKCkge1xuICAgIHJldHVybiBTZWxlY3RvckVuZ2luZS5maW5kKFNFTEVDVE9SX0lURU0sIHRoaXMuX2VsZW1lbnQpO1xuICB9XG4gIF9jbGVhckludGVydmFsKCkge1xuICAgIGlmICh0aGlzLl9pbnRlcnZhbCkge1xuICAgICAgY2xlYXJJbnRlcnZhbCh0aGlzLl9pbnRlcnZhbCk7XG4gICAgICB0aGlzLl9pbnRlcnZhbCA9IG51bGw7XG4gICAgfVxuICB9XG4gIF9kaXJlY3Rpb25Ub09yZGVyKGRpcmVjdGlvbikge1xuICAgIGlmIChpc1JUTCgpKSB7XG4gICAgICByZXR1cm4gZGlyZWN0aW9uID09PSBESVJFQ1RJT05fTEVGVCA/IE9SREVSX1BSRVYgOiBPUkRFUl9ORVhUO1xuICAgIH1cbiAgICByZXR1cm4gZGlyZWN0aW9uID09PSBESVJFQ1RJT05fTEVGVCA/IE9SREVSX05FWFQgOiBPUkRFUl9QUkVWO1xuICB9XG4gIF9vcmRlclRvRGlyZWN0aW9uKG9yZGVyKSB7XG4gICAgaWYgKGlzUlRMKCkpIHtcbiAgICAgIHJldHVybiBvcmRlciA9PT0gT1JERVJfUFJFViA/IERJUkVDVElPTl9MRUZUIDogRElSRUNUSU9OX1JJR0hUO1xuICAgIH1cbiAgICByZXR1cm4gb3JkZXIgPT09IE9SREVSX1BSRVYgPyBESVJFQ1RJT05fUklHSFQgOiBESVJFQ1RJT05fTEVGVDtcbiAgfVxuXG4gIC8vIFN0YXRpY1xuICBzdGF0aWMgalF1ZXJ5SW50ZXJmYWNlKGNvbmZpZykge1xuICAgIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZGF0YSA9IENhcm91c2VsLmdldE9yQ3JlYXRlSW5zdGFuY2UodGhpcywgY29uZmlnKTtcbiAgICAgIGlmICh0eXBlb2YgY29uZmlnID09PSAnbnVtYmVyJykge1xuICAgICAgICBkYXRhLnRvKGNvbmZpZyk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgY29uZmlnID09PSAnc3RyaW5nJykge1xuICAgICAgICBpZiAoZGF0YVtjb25maWddID09PSB1bmRlZmluZWQgfHwgY29uZmlnLnN0YXJ0c1dpdGgoJ18nKSB8fCBjb25maWcgPT09ICdjb25zdHJ1Y3RvcicpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBObyBtZXRob2QgbmFtZWQgXCIke2NvbmZpZ31cImApO1xuICAgICAgICB9XG4gICAgICAgIGRhdGFbY29uZmlnXSgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG59XG5cbi8qKlxuICogRGF0YSBBUEkgaW1wbGVtZW50YXRpb25cbiAqL1xuXG5FdmVudEhhbmRsZXIub24oZG9jdW1lbnQsIEVWRU5UX0NMSUNLX0RBVEFfQVBJJDUsIFNFTEVDVE9SX0RBVEFfU0xJREUsIGZ1bmN0aW9uIChldmVudCkge1xuICBjb25zdCB0YXJnZXQgPSBTZWxlY3RvckVuZ2luZS5nZXRFbGVtZW50RnJvbVNlbGVjdG9yKHRoaXMpO1xuICBpZiAoIXRhcmdldCB8fCAhdGFyZ2V0LmNsYXNzTGlzdC5jb250YWlucyhDTEFTU19OQU1FX0NBUk9VU0VMKSkge1xuICAgIHJldHVybjtcbiAgfVxuICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICBjb25zdCBjYXJvdXNlbCA9IENhcm91c2VsLmdldE9yQ3JlYXRlSW5zdGFuY2UodGFyZ2V0KTtcbiAgY29uc3Qgc2xpZGVJbmRleCA9IHRoaXMuZ2V0QXR0cmlidXRlKCdkYXRhLWJzLXNsaWRlLXRvJyk7XG4gIGlmIChzbGlkZUluZGV4KSB7XG4gICAgY2Fyb3VzZWwudG8oc2xpZGVJbmRleCk7XG4gICAgY2Fyb3VzZWwuX21heWJlRW5hYmxlQ3ljbGUoKTtcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKE1hbmlwdWxhdG9yLmdldERhdGFBdHRyaWJ1dGUodGhpcywgJ3NsaWRlJykgPT09ICduZXh0Jykge1xuICAgIGNhcm91c2VsLm5leHQoKTtcbiAgICBjYXJvdXNlbC5fbWF5YmVFbmFibGVDeWNsZSgpO1xuICAgIHJldHVybjtcbiAgfVxuICBjYXJvdXNlbC5wcmV2KCk7XG4gIGNhcm91c2VsLl9tYXliZUVuYWJsZUN5Y2xlKCk7XG59KTtcbkV2ZW50SGFuZGxlci5vbih3aW5kb3csIEVWRU5UX0xPQURfREFUQV9BUEkkMywgKCkgPT4ge1xuICBjb25zdCBjYXJvdXNlbHMgPSBTZWxlY3RvckVuZ2luZS5maW5kKFNFTEVDVE9SX0RBVEFfUklERSk7XG4gIGZvciAoY29uc3QgY2Fyb3VzZWwgb2YgY2Fyb3VzZWxzKSB7XG4gICAgQ2Fyb3VzZWwuZ2V0T3JDcmVhdGVJbnN0YW5jZShjYXJvdXNlbCk7XG4gIH1cbn0pO1xuXG4vKipcbiAqIGpRdWVyeVxuICovXG5cbmRlZmluZUpRdWVyeVBsdWdpbihDYXJvdXNlbCk7XG5cbi8qKlxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIEJvb3RzdHJhcCBjb2xsYXBzZS5qc1xuICogTGljZW5zZWQgdW5kZXIgTUlUIChodHRwczovL2dpdGh1Yi5jb20vdHdicy9ib290c3RyYXAvYmxvYi9tYWluL0xJQ0VOU0UpXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICovXG5cblxuLyoqXG4gKiBDb25zdGFudHNcbiAqL1xuXG5jb25zdCBOQU1FJGIgPSAnY29sbGFwc2UnO1xuY29uc3QgREFUQV9LRVkkNyA9ICdicy5jb2xsYXBzZSc7XG5jb25zdCBFVkVOVF9LRVkkNyA9IGAuJHtEQVRBX0tFWSQ3fWA7XG5jb25zdCBEQVRBX0FQSV9LRVkkNCA9ICcuZGF0YS1hcGknO1xuY29uc3QgRVZFTlRfU0hPVyQ2ID0gYHNob3cke0VWRU5UX0tFWSQ3fWA7XG5jb25zdCBFVkVOVF9TSE9XTiQ2ID0gYHNob3duJHtFVkVOVF9LRVkkN31gO1xuY29uc3QgRVZFTlRfSElERSQ2ID0gYGhpZGUke0VWRU5UX0tFWSQ3fWA7XG5jb25zdCBFVkVOVF9ISURERU4kNiA9IGBoaWRkZW4ke0VWRU5UX0tFWSQ3fWA7XG5jb25zdCBFVkVOVF9DTElDS19EQVRBX0FQSSQ0ID0gYGNsaWNrJHtFVkVOVF9LRVkkN30ke0RBVEFfQVBJX0tFWSQ0fWA7XG5jb25zdCBDTEFTU19OQU1FX1NIT1ckNyA9ICdzaG93JztcbmNvbnN0IENMQVNTX05BTUVfQ09MTEFQU0UgPSAnY29sbGFwc2UnO1xuY29uc3QgQ0xBU1NfTkFNRV9DT0xMQVBTSU5HID0gJ2NvbGxhcHNpbmcnO1xuY29uc3QgQ0xBU1NfTkFNRV9DT0xMQVBTRUQgPSAnY29sbGFwc2VkJztcbmNvbnN0IENMQVNTX05BTUVfREVFUEVSX0NISUxEUkVOID0gYDpzY29wZSAuJHtDTEFTU19OQU1FX0NPTExBUFNFfSAuJHtDTEFTU19OQU1FX0NPTExBUFNFfWA7XG5jb25zdCBDTEFTU19OQU1FX0hPUklaT05UQUwgPSAnY29sbGFwc2UtaG9yaXpvbnRhbCc7XG5jb25zdCBXSURUSCA9ICd3aWR0aCc7XG5jb25zdCBIRUlHSFQgPSAnaGVpZ2h0JztcbmNvbnN0IFNFTEVDVE9SX0FDVElWRVMgPSAnLmNvbGxhcHNlLnNob3csIC5jb2xsYXBzZS5jb2xsYXBzaW5nJztcbmNvbnN0IFNFTEVDVE9SX0RBVEFfVE9HR0xFJDQgPSAnW2RhdGEtYnMtdG9nZ2xlPVwiY29sbGFwc2VcIl0nO1xuY29uc3QgRGVmYXVsdCRhID0ge1xuICBwYXJlbnQ6IG51bGwsXG4gIHRvZ2dsZTogdHJ1ZVxufTtcbmNvbnN0IERlZmF1bHRUeXBlJGEgPSB7XG4gIHBhcmVudDogJyhudWxsfGVsZW1lbnQpJyxcbiAgdG9nZ2xlOiAnYm9vbGVhbidcbn07XG5cbi8qKlxuICogQ2xhc3MgZGVmaW5pdGlvblxuICovXG5cbmNsYXNzIENvbGxhcHNlIGV4dGVuZHMgQmFzZUNvbXBvbmVudCB7XG4gIGNvbnN0cnVjdG9yKGVsZW1lbnQsIGNvbmZpZykge1xuICAgIHN1cGVyKGVsZW1lbnQsIGNvbmZpZyk7XG4gICAgdGhpcy5faXNUcmFuc2l0aW9uaW5nID0gZmFsc2U7XG4gICAgdGhpcy5fdHJpZ2dlckFycmF5ID0gW107XG4gICAgY29uc3QgdG9nZ2xlTGlzdCA9IFNlbGVjdG9yRW5naW5lLmZpbmQoU0VMRUNUT1JfREFUQV9UT0dHTEUkNCk7XG4gICAgZm9yIChjb25zdCBlbGVtIG9mIHRvZ2dsZUxpc3QpIHtcbiAgICAgIGNvbnN0IHNlbGVjdG9yID0gU2VsZWN0b3JFbmdpbmUuZ2V0U2VsZWN0b3JGcm9tRWxlbWVudChlbGVtKTtcbiAgICAgIGNvbnN0IGZpbHRlckVsZW1lbnQgPSBTZWxlY3RvckVuZ2luZS5maW5kKHNlbGVjdG9yKS5maWx0ZXIoZm91bmRFbGVtZW50ID0+IGZvdW5kRWxlbWVudCA9PT0gdGhpcy5fZWxlbWVudCk7XG4gICAgICBpZiAoc2VsZWN0b3IgIT09IG51bGwgJiYgZmlsdGVyRWxlbWVudC5sZW5ndGgpIHtcbiAgICAgICAgdGhpcy5fdHJpZ2dlckFycmF5LnB1c2goZWxlbSk7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMuX2luaXRpYWxpemVDaGlsZHJlbigpO1xuICAgIGlmICghdGhpcy5fY29uZmlnLnBhcmVudCkge1xuICAgICAgdGhpcy5fYWRkQXJpYUFuZENvbGxhcHNlZENsYXNzKHRoaXMuX3RyaWdnZXJBcnJheSwgdGhpcy5faXNTaG93bigpKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuX2NvbmZpZy50b2dnbGUpIHtcbiAgICAgIHRoaXMudG9nZ2xlKCk7XG4gICAgfVxuICB9XG5cbiAgLy8gR2V0dGVyc1xuICBzdGF0aWMgZ2V0IERlZmF1bHQoKSB7XG4gICAgcmV0dXJuIERlZmF1bHQkYTtcbiAgfVxuICBzdGF0aWMgZ2V0IERlZmF1bHRUeXBlKCkge1xuICAgIHJldHVybiBEZWZhdWx0VHlwZSRhO1xuICB9XG4gIHN0YXRpYyBnZXQgTkFNRSgpIHtcbiAgICByZXR1cm4gTkFNRSRiO1xuICB9XG5cbiAgLy8gUHVibGljXG4gIHRvZ2dsZSgpIHtcbiAgICBpZiAodGhpcy5faXNTaG93bigpKSB7XG4gICAgICB0aGlzLmhpZGUoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zaG93KCk7XG4gICAgfVxuICB9XG4gIHNob3coKSB7XG4gICAgaWYgKHRoaXMuX2lzVHJhbnNpdGlvbmluZyB8fCB0aGlzLl9pc1Nob3duKCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgbGV0IGFjdGl2ZUNoaWxkcmVuID0gW107XG5cbiAgICAvLyBmaW5kIGFjdGl2ZSBjaGlsZHJlblxuICAgIGlmICh0aGlzLl9jb25maWcucGFyZW50KSB7XG4gICAgICBhY3RpdmVDaGlsZHJlbiA9IHRoaXMuX2dldEZpcnN0TGV2ZWxDaGlsZHJlbihTRUxFQ1RPUl9BQ1RJVkVTKS5maWx0ZXIoZWxlbWVudCA9PiBlbGVtZW50ICE9PSB0aGlzLl9lbGVtZW50KS5tYXAoZWxlbWVudCA9PiBDb2xsYXBzZS5nZXRPckNyZWF0ZUluc3RhbmNlKGVsZW1lbnQsIHtcbiAgICAgICAgdG9nZ2xlOiBmYWxzZVxuICAgICAgfSkpO1xuICAgIH1cbiAgICBpZiAoYWN0aXZlQ2hpbGRyZW4ubGVuZ3RoICYmIGFjdGl2ZUNoaWxkcmVuWzBdLl9pc1RyYW5zaXRpb25pbmcpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3Qgc3RhcnRFdmVudCA9IEV2ZW50SGFuZGxlci50cmlnZ2VyKHRoaXMuX2VsZW1lbnQsIEVWRU5UX1NIT1ckNik7XG4gICAgaWYgKHN0YXJ0RXZlbnQuZGVmYXVsdFByZXZlbnRlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IGFjdGl2ZUluc3RhbmNlIG9mIGFjdGl2ZUNoaWxkcmVuKSB7XG4gICAgICBhY3RpdmVJbnN0YW5jZS5oaWRlKCk7XG4gICAgfVxuICAgIGNvbnN0IGRpbWVuc2lvbiA9IHRoaXMuX2dldERpbWVuc2lvbigpO1xuICAgIHRoaXMuX2VsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZShDTEFTU19OQU1FX0NPTExBUFNFKTtcbiAgICB0aGlzLl9lbGVtZW50LmNsYXNzTGlzdC5hZGQoQ0xBU1NfTkFNRV9DT0xMQVBTSU5HKTtcbiAgICB0aGlzLl9lbGVtZW50LnN0eWxlW2RpbWVuc2lvbl0gPSAwO1xuICAgIHRoaXMuX2FkZEFyaWFBbmRDb2xsYXBzZWRDbGFzcyh0aGlzLl90cmlnZ2VyQXJyYXksIHRydWUpO1xuICAgIHRoaXMuX2lzVHJhbnNpdGlvbmluZyA9IHRydWU7XG4gICAgY29uc3QgY29tcGxldGUgPSAoKSA9PiB7XG4gICAgICB0aGlzLl9pc1RyYW5zaXRpb25pbmcgPSBmYWxzZTtcbiAgICAgIHRoaXMuX2VsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZShDTEFTU19OQU1FX0NPTExBUFNJTkcpO1xuICAgICAgdGhpcy5fZWxlbWVudC5jbGFzc0xpc3QuYWRkKENMQVNTX05BTUVfQ09MTEFQU0UsIENMQVNTX05BTUVfU0hPVyQ3KTtcbiAgICAgIHRoaXMuX2VsZW1lbnQuc3R5bGVbZGltZW5zaW9uXSA9ICcnO1xuICAgICAgRXZlbnRIYW5kbGVyLnRyaWdnZXIodGhpcy5fZWxlbWVudCwgRVZFTlRfU0hPV04kNik7XG4gICAgfTtcbiAgICBjb25zdCBjYXBpdGFsaXplZERpbWVuc2lvbiA9IGRpbWVuc2lvblswXS50b1VwcGVyQ2FzZSgpICsgZGltZW5zaW9uLnNsaWNlKDEpO1xuICAgIGNvbnN0IHNjcm9sbFNpemUgPSBgc2Nyb2xsJHtjYXBpdGFsaXplZERpbWVuc2lvbn1gO1xuICAgIHRoaXMuX3F1ZXVlQ2FsbGJhY2soY29tcGxldGUsIHRoaXMuX2VsZW1lbnQsIHRydWUpO1xuICAgIHRoaXMuX2VsZW1lbnQuc3R5bGVbZGltZW5zaW9uXSA9IGAke3RoaXMuX2VsZW1lbnRbc2Nyb2xsU2l6ZV19cHhgO1xuICB9XG4gIGhpZGUoKSB7XG4gICAgaWYgKHRoaXMuX2lzVHJhbnNpdGlvbmluZyB8fCAhdGhpcy5faXNTaG93bigpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHN0YXJ0RXZlbnQgPSBFdmVudEhhbmRsZXIudHJpZ2dlcih0aGlzLl9lbGVtZW50LCBFVkVOVF9ISURFJDYpO1xuICAgIGlmIChzdGFydEV2ZW50LmRlZmF1bHRQcmV2ZW50ZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgZGltZW5zaW9uID0gdGhpcy5fZ2V0RGltZW5zaW9uKCk7XG4gICAgdGhpcy5fZWxlbWVudC5zdHlsZVtkaW1lbnNpb25dID0gYCR7dGhpcy5fZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKVtkaW1lbnNpb25dfXB4YDtcbiAgICByZWZsb3codGhpcy5fZWxlbWVudCk7XG4gICAgdGhpcy5fZWxlbWVudC5jbGFzc0xpc3QuYWRkKENMQVNTX05BTUVfQ09MTEFQU0lORyk7XG4gICAgdGhpcy5fZWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKENMQVNTX05BTUVfQ09MTEFQU0UsIENMQVNTX05BTUVfU0hPVyQ3KTtcbiAgICBmb3IgKGNvbnN0IHRyaWdnZXIgb2YgdGhpcy5fdHJpZ2dlckFycmF5KSB7XG4gICAgICBjb25zdCBlbGVtZW50ID0gU2VsZWN0b3JFbmdpbmUuZ2V0RWxlbWVudEZyb21TZWxlY3Rvcih0cmlnZ2VyKTtcbiAgICAgIGlmIChlbGVtZW50ICYmICF0aGlzLl9pc1Nob3duKGVsZW1lbnQpKSB7XG4gICAgICAgIHRoaXMuX2FkZEFyaWFBbmRDb2xsYXBzZWRDbGFzcyhbdHJpZ2dlcl0sIGZhbHNlKTtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5faXNUcmFuc2l0aW9uaW5nID0gdHJ1ZTtcbiAgICBjb25zdCBjb21wbGV0ZSA9ICgpID0+IHtcbiAgICAgIHRoaXMuX2lzVHJhbnNpdGlvbmluZyA9IGZhbHNlO1xuICAgICAgdGhpcy5fZWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKENMQVNTX05BTUVfQ09MTEFQU0lORyk7XG4gICAgICB0aGlzLl9lbGVtZW50LmNsYXNzTGlzdC5hZGQoQ0xBU1NfTkFNRV9DT0xMQVBTRSk7XG4gICAgICBFdmVudEhhbmRsZXIudHJpZ2dlcih0aGlzLl9lbGVtZW50LCBFVkVOVF9ISURERU4kNik7XG4gICAgfTtcbiAgICB0aGlzLl9lbGVtZW50LnN0eWxlW2RpbWVuc2lvbl0gPSAnJztcbiAgICB0aGlzLl9xdWV1ZUNhbGxiYWNrKGNvbXBsZXRlLCB0aGlzLl9lbGVtZW50LCB0cnVlKTtcbiAgfVxuICBfaXNTaG93bihlbGVtZW50ID0gdGhpcy5fZWxlbWVudCkge1xuICAgIHJldHVybiBlbGVtZW50LmNsYXNzTGlzdC5jb250YWlucyhDTEFTU19OQU1FX1NIT1ckNyk7XG4gIH1cblxuICAvLyBQcml2YXRlXG4gIF9jb25maWdBZnRlck1lcmdlKGNvbmZpZykge1xuICAgIGNvbmZpZy50b2dnbGUgPSBCb29sZWFuKGNvbmZpZy50b2dnbGUpOyAvLyBDb2VyY2Ugc3RyaW5nIHZhbHVlc1xuICAgIGNvbmZpZy5wYXJlbnQgPSBnZXRFbGVtZW50KGNvbmZpZy5wYXJlbnQpO1xuICAgIHJldHVybiBjb25maWc7XG4gIH1cbiAgX2dldERpbWVuc2lvbigpIHtcbiAgICByZXR1cm4gdGhpcy5fZWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoQ0xBU1NfTkFNRV9IT1JJWk9OVEFMKSA/IFdJRFRIIDogSEVJR0hUO1xuICB9XG4gIF9pbml0aWFsaXplQ2hpbGRyZW4oKSB7XG4gICAgaWYgKCF0aGlzLl9jb25maWcucGFyZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGNoaWxkcmVuID0gdGhpcy5fZ2V0Rmlyc3RMZXZlbENoaWxkcmVuKFNFTEVDVE9SX0RBVEFfVE9HR0xFJDQpO1xuICAgIGZvciAoY29uc3QgZWxlbWVudCBvZiBjaGlsZHJlbikge1xuICAgICAgY29uc3Qgc2VsZWN0ZWQgPSBTZWxlY3RvckVuZ2luZS5nZXRFbGVtZW50RnJvbVNlbGVjdG9yKGVsZW1lbnQpO1xuICAgICAgaWYgKHNlbGVjdGVkKSB7XG4gICAgICAgIHRoaXMuX2FkZEFyaWFBbmRDb2xsYXBzZWRDbGFzcyhbZWxlbWVudF0sIHRoaXMuX2lzU2hvd24oc2VsZWN0ZWQpKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgX2dldEZpcnN0TGV2ZWxDaGlsZHJlbihzZWxlY3Rvcikge1xuICAgIGNvbnN0IGNoaWxkcmVuID0gU2VsZWN0b3JFbmdpbmUuZmluZChDTEFTU19OQU1FX0RFRVBFUl9DSElMRFJFTiwgdGhpcy5fY29uZmlnLnBhcmVudCk7XG4gICAgLy8gcmVtb3ZlIGNoaWxkcmVuIGlmIGdyZWF0ZXIgZGVwdGhcbiAgICByZXR1cm4gU2VsZWN0b3JFbmdpbmUuZmluZChzZWxlY3RvciwgdGhpcy5fY29uZmlnLnBhcmVudCkuZmlsdGVyKGVsZW1lbnQgPT4gIWNoaWxkcmVuLmluY2x1ZGVzKGVsZW1lbnQpKTtcbiAgfVxuICBfYWRkQXJpYUFuZENvbGxhcHNlZENsYXNzKHRyaWdnZXJBcnJheSwgaXNPcGVuKSB7XG4gICAgaWYgKCF0cmlnZ2VyQXJyYXkubGVuZ3RoKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGZvciAoY29uc3QgZWxlbWVudCBvZiB0cmlnZ2VyQXJyYXkpIHtcbiAgICAgIGVsZW1lbnQuY2xhc3NMaXN0LnRvZ2dsZShDTEFTU19OQU1FX0NPTExBUFNFRCwgIWlzT3Blbik7XG4gICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZSgnYXJpYS1leHBhbmRlZCcsIGlzT3Blbik7XG4gICAgfVxuICB9XG5cbiAgLy8gU3RhdGljXG4gIHN0YXRpYyBqUXVlcnlJbnRlcmZhY2UoY29uZmlnKSB7XG4gICAgY29uc3QgX2NvbmZpZyA9IHt9O1xuICAgIGlmICh0eXBlb2YgY29uZmlnID09PSAnc3RyaW5nJyAmJiAvc2hvd3xoaWRlLy50ZXN0KGNvbmZpZykpIHtcbiAgICAgIF9jb25maWcudG9nZ2xlID0gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZGF0YSA9IENvbGxhcHNlLmdldE9yQ3JlYXRlSW5zdGFuY2UodGhpcywgX2NvbmZpZyk7XG4gICAgICBpZiAodHlwZW9mIGNvbmZpZyA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBkYXRhW2NvbmZpZ10gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgTm8gbWV0aG9kIG5hbWVkIFwiJHtjb25maWd9XCJgKTtcbiAgICAgICAgfVxuICAgICAgICBkYXRhW2NvbmZpZ10oKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufVxuXG4vKipcbiAqIERhdGEgQVBJIGltcGxlbWVudGF0aW9uXG4gKi9cblxuRXZlbnRIYW5kbGVyLm9uKGRvY3VtZW50LCBFVkVOVF9DTElDS19EQVRBX0FQSSQ0LCBTRUxFQ1RPUl9EQVRBX1RPR0dMRSQ0LCBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgLy8gcHJldmVudERlZmF1bHQgb25seSBmb3IgPGE+IGVsZW1lbnRzICh3aGljaCBjaGFuZ2UgdGhlIFVSTCkgbm90IGluc2lkZSB0aGUgY29sbGFwc2libGUgZWxlbWVudFxuICBpZiAoZXZlbnQudGFyZ2V0LnRhZ05hbWUgPT09ICdBJyB8fCBldmVudC5kZWxlZ2F0ZVRhcmdldCAmJiBldmVudC5kZWxlZ2F0ZVRhcmdldC50YWdOYW1lID09PSAnQScpIHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICB9XG4gIGZvciAoY29uc3QgZWxlbWVudCBvZiBTZWxlY3RvckVuZ2luZS5nZXRNdWx0aXBsZUVsZW1lbnRzRnJvbVNlbGVjdG9yKHRoaXMpKSB7XG4gICAgQ29sbGFwc2UuZ2V0T3JDcmVhdGVJbnN0YW5jZShlbGVtZW50LCB7XG4gICAgICB0b2dnbGU6IGZhbHNlXG4gICAgfSkudG9nZ2xlKCk7XG4gIH1cbn0pO1xuXG4vKipcbiAqIGpRdWVyeVxuICovXG5cbmRlZmluZUpRdWVyeVBsdWdpbihDb2xsYXBzZSk7XG5cbi8qKlxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIEJvb3RzdHJhcCBkcm9wZG93bi5qc1xuICogTGljZW5zZWQgdW5kZXIgTUlUIChodHRwczovL2dpdGh1Yi5jb20vdHdicy9ib290c3RyYXAvYmxvYi9tYWluL0xJQ0VOU0UpXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICovXG5cblxuLyoqXG4gKiBDb25zdGFudHNcbiAqL1xuXG5jb25zdCBOQU1FJGEgPSAnZHJvcGRvd24nO1xuY29uc3QgREFUQV9LRVkkNiA9ICdicy5kcm9wZG93bic7XG5jb25zdCBFVkVOVF9LRVkkNiA9IGAuJHtEQVRBX0tFWSQ2fWA7XG5jb25zdCBEQVRBX0FQSV9LRVkkMyA9ICcuZGF0YS1hcGknO1xuY29uc3QgRVNDQVBFX0tFWSQyID0gJ0VzY2FwZSc7XG5jb25zdCBUQUJfS0VZJDEgPSAnVGFiJztcbmNvbnN0IEFSUk9XX1VQX0tFWSQxID0gJ0Fycm93VXAnO1xuY29uc3QgQVJST1dfRE9XTl9LRVkkMSA9ICdBcnJvd0Rvd24nO1xuY29uc3QgUklHSFRfTU9VU0VfQlVUVE9OID0gMjsgLy8gTW91c2VFdmVudC5idXR0b24gdmFsdWUgZm9yIHRoZSBzZWNvbmRhcnkgYnV0dG9uLCB1c3VhbGx5IHRoZSByaWdodCBidXR0b25cblxuY29uc3QgRVZFTlRfSElERSQ1ID0gYGhpZGUke0VWRU5UX0tFWSQ2fWA7XG5jb25zdCBFVkVOVF9ISURERU4kNSA9IGBoaWRkZW4ke0VWRU5UX0tFWSQ2fWA7XG5jb25zdCBFVkVOVF9TSE9XJDUgPSBgc2hvdyR7RVZFTlRfS0VZJDZ9YDtcbmNvbnN0IEVWRU5UX1NIT1dOJDUgPSBgc2hvd24ke0VWRU5UX0tFWSQ2fWA7XG5jb25zdCBFVkVOVF9DTElDS19EQVRBX0FQSSQzID0gYGNsaWNrJHtFVkVOVF9LRVkkNn0ke0RBVEFfQVBJX0tFWSQzfWA7XG5jb25zdCBFVkVOVF9LRVlET1dOX0RBVEFfQVBJID0gYGtleWRvd24ke0VWRU5UX0tFWSQ2fSR7REFUQV9BUElfS0VZJDN9YDtcbmNvbnN0IEVWRU5UX0tFWVVQX0RBVEFfQVBJID0gYGtleXVwJHtFVkVOVF9LRVkkNn0ke0RBVEFfQVBJX0tFWSQzfWA7XG5jb25zdCBDTEFTU19OQU1FX1NIT1ckNiA9ICdzaG93JztcbmNvbnN0IENMQVNTX05BTUVfRFJPUFVQID0gJ2Ryb3B1cCc7XG5jb25zdCBDTEFTU19OQU1FX0RST1BFTkQgPSAnZHJvcGVuZCc7XG5jb25zdCBDTEFTU19OQU1FX0RST1BTVEFSVCA9ICdkcm9wc3RhcnQnO1xuY29uc3QgQ0xBU1NfTkFNRV9EUk9QVVBfQ0VOVEVSID0gJ2Ryb3B1cC1jZW50ZXInO1xuY29uc3QgQ0xBU1NfTkFNRV9EUk9QRE9XTl9DRU5URVIgPSAnZHJvcGRvd24tY2VudGVyJztcbmNvbnN0IFNFTEVDVE9SX0RBVEFfVE9HR0xFJDMgPSAnW2RhdGEtYnMtdG9nZ2xlPVwiZHJvcGRvd25cIl06bm90KC5kaXNhYmxlZCk6bm90KDpkaXNhYmxlZCknO1xuY29uc3QgU0VMRUNUT1JfREFUQV9UT0dHTEVfU0hPV04gPSBgJHtTRUxFQ1RPUl9EQVRBX1RPR0dMRSQzfS4ke0NMQVNTX05BTUVfU0hPVyQ2fWA7XG5jb25zdCBTRUxFQ1RPUl9NRU5VID0gJy5kcm9wZG93bi1tZW51JztcbmNvbnN0IFNFTEVDVE9SX05BVkJBUiA9ICcubmF2YmFyJztcbmNvbnN0IFNFTEVDVE9SX05BVkJBUl9OQVYgPSAnLm5hdmJhci1uYXYnO1xuY29uc3QgU0VMRUNUT1JfVklTSUJMRV9JVEVNUyA9ICcuZHJvcGRvd24tbWVudSAuZHJvcGRvd24taXRlbTpub3QoLmRpc2FibGVkKTpub3QoOmRpc2FibGVkKSc7XG5jb25zdCBQTEFDRU1FTlRfVE9QID0gaXNSVEwoKSA/ICd0b3AtZW5kJyA6ICd0b3Atc3RhcnQnO1xuY29uc3QgUExBQ0VNRU5UX1RPUEVORCA9IGlzUlRMKCkgPyAndG9wLXN0YXJ0JyA6ICd0b3AtZW5kJztcbmNvbnN0IFBMQUNFTUVOVF9CT1RUT00gPSBpc1JUTCgpID8gJ2JvdHRvbS1lbmQnIDogJ2JvdHRvbS1zdGFydCc7XG5jb25zdCBQTEFDRU1FTlRfQk9UVE9NRU5EID0gaXNSVEwoKSA/ICdib3R0b20tc3RhcnQnIDogJ2JvdHRvbS1lbmQnO1xuY29uc3QgUExBQ0VNRU5UX1JJR0hUID0gaXNSVEwoKSA/ICdsZWZ0LXN0YXJ0JyA6ICdyaWdodC1zdGFydCc7XG5jb25zdCBQTEFDRU1FTlRfTEVGVCA9IGlzUlRMKCkgPyAncmlnaHQtc3RhcnQnIDogJ2xlZnQtc3RhcnQnO1xuY29uc3QgUExBQ0VNRU5UX1RPUENFTlRFUiA9ICd0b3AnO1xuY29uc3QgUExBQ0VNRU5UX0JPVFRPTUNFTlRFUiA9ICdib3R0b20nO1xuY29uc3QgRGVmYXVsdCQ5ID0ge1xuICBhdXRvQ2xvc2U6IHRydWUsXG4gIGJvdW5kYXJ5OiAnY2xpcHBpbmdQYXJlbnRzJyxcbiAgZGlzcGxheTogJ2R5bmFtaWMnLFxuICBvZmZzZXQ6IFswLCAyXSxcbiAgcG9wcGVyQ29uZmlnOiBudWxsLFxuICByZWZlcmVuY2U6ICd0b2dnbGUnXG59O1xuY29uc3QgRGVmYXVsdFR5cGUkOSA9IHtcbiAgYXV0b0Nsb3NlOiAnKGJvb2xlYW58c3RyaW5nKScsXG4gIGJvdW5kYXJ5OiAnKHN0cmluZ3xlbGVtZW50KScsXG4gIGRpc3BsYXk6ICdzdHJpbmcnLFxuICBvZmZzZXQ6ICcoYXJyYXl8c3RyaW5nfGZ1bmN0aW9uKScsXG4gIHBvcHBlckNvbmZpZzogJyhudWxsfG9iamVjdHxmdW5jdGlvbiknLFxuICByZWZlcmVuY2U6ICcoc3RyaW5nfGVsZW1lbnR8b2JqZWN0KSdcbn07XG5cbi8qKlxuICogQ2xhc3MgZGVmaW5pdGlvblxuICovXG5cbmNsYXNzIERyb3Bkb3duIGV4dGVuZHMgQmFzZUNvbXBvbmVudCB7XG4gIGNvbnN0cnVjdG9yKGVsZW1lbnQsIGNvbmZpZykge1xuICAgIHN1cGVyKGVsZW1lbnQsIGNvbmZpZyk7XG4gICAgdGhpcy5fcG9wcGVyID0gbnVsbDtcbiAgICB0aGlzLl9wYXJlbnQgPSB0aGlzLl9lbGVtZW50LnBhcmVudE5vZGU7IC8vIGRyb3Bkb3duIHdyYXBwZXJcbiAgICAvLyBUT0RPOiB2NiByZXZlcnQgIzM3MDExICYgY2hhbmdlIG1hcmt1cCBodHRwczovL2dldGJvb3RzdHJhcC5jb20vZG9jcy81LjMvZm9ybXMvaW5wdXQtZ3JvdXAvXG4gICAgdGhpcy5fbWVudSA9IFNlbGVjdG9yRW5naW5lLm5leHQodGhpcy5fZWxlbWVudCwgU0VMRUNUT1JfTUVOVSlbMF0gfHwgU2VsZWN0b3JFbmdpbmUucHJldih0aGlzLl9lbGVtZW50LCBTRUxFQ1RPUl9NRU5VKVswXSB8fCBTZWxlY3RvckVuZ2luZS5maW5kT25lKFNFTEVDVE9SX01FTlUsIHRoaXMuX3BhcmVudCk7XG4gICAgdGhpcy5faW5OYXZiYXIgPSB0aGlzLl9kZXRlY3ROYXZiYXIoKTtcbiAgfVxuXG4gIC8vIEdldHRlcnNcbiAgc3RhdGljIGdldCBEZWZhdWx0KCkge1xuICAgIHJldHVybiBEZWZhdWx0JDk7XG4gIH1cbiAgc3RhdGljIGdldCBEZWZhdWx0VHlwZSgpIHtcbiAgICByZXR1cm4gRGVmYXVsdFR5cGUkOTtcbiAgfVxuICBzdGF0aWMgZ2V0IE5BTUUoKSB7XG4gICAgcmV0dXJuIE5BTUUkYTtcbiAgfVxuXG4gIC8vIFB1YmxpY1xuICB0b2dnbGUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2lzU2hvd24oKSA/IHRoaXMuaGlkZSgpIDogdGhpcy5zaG93KCk7XG4gIH1cbiAgc2hvdygpIHtcbiAgICBpZiAoaXNEaXNhYmxlZCh0aGlzLl9lbGVtZW50KSB8fCB0aGlzLl9pc1Nob3duKCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgcmVsYXRlZFRhcmdldCA9IHtcbiAgICAgIHJlbGF0ZWRUYXJnZXQ6IHRoaXMuX2VsZW1lbnRcbiAgICB9O1xuICAgIGNvbnN0IHNob3dFdmVudCA9IEV2ZW50SGFuZGxlci50cmlnZ2VyKHRoaXMuX2VsZW1lbnQsIEVWRU5UX1NIT1ckNSwgcmVsYXRlZFRhcmdldCk7XG4gICAgaWYgKHNob3dFdmVudC5kZWZhdWx0UHJldmVudGVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuX2NyZWF0ZVBvcHBlcigpO1xuXG4gICAgLy8gSWYgdGhpcyBpcyBhIHRvdWNoLWVuYWJsZWQgZGV2aWNlIHdlIGFkZCBleHRyYVxuICAgIC8vIGVtcHR5IG1vdXNlb3ZlciBsaXN0ZW5lcnMgdG8gdGhlIGJvZHkncyBpbW1lZGlhdGUgY2hpbGRyZW47XG4gICAgLy8gb25seSBuZWVkZWQgYmVjYXVzZSBvZiBicm9rZW4gZXZlbnQgZGVsZWdhdGlvbiBvbiBpT1NcbiAgICAvLyBodHRwczovL3d3dy5xdWlya3Ntb2RlLm9yZy9ibG9nL2FyY2hpdmVzLzIwMTQvMDIvbW91c2VfZXZlbnRfYnViLmh0bWxcbiAgICBpZiAoJ29udG91Y2hzdGFydCcgaW4gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50ICYmICF0aGlzLl9wYXJlbnQuY2xvc2VzdChTRUxFQ1RPUl9OQVZCQVJfTkFWKSkge1xuICAgICAgZm9yIChjb25zdCBlbGVtZW50IG9mIFtdLmNvbmNhdCguLi5kb2N1bWVudC5ib2R5LmNoaWxkcmVuKSkge1xuICAgICAgICBFdmVudEhhbmRsZXIub24oZWxlbWVudCwgJ21vdXNlb3ZlcicsIG5vb3ApO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLl9lbGVtZW50LmZvY3VzKCk7XG4gICAgdGhpcy5fZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2FyaWEtZXhwYW5kZWQnLCB0cnVlKTtcbiAgICB0aGlzLl9tZW51LmNsYXNzTGlzdC5hZGQoQ0xBU1NfTkFNRV9TSE9XJDYpO1xuICAgIHRoaXMuX2VsZW1lbnQuY2xhc3NMaXN0LmFkZChDTEFTU19OQU1FX1NIT1ckNik7XG4gICAgRXZlbnRIYW5kbGVyLnRyaWdnZXIodGhpcy5fZWxlbWVudCwgRVZFTlRfU0hPV04kNSwgcmVsYXRlZFRhcmdldCk7XG4gIH1cbiAgaGlkZSgpIHtcbiAgICBpZiAoaXNEaXNhYmxlZCh0aGlzLl9lbGVtZW50KSB8fCAhdGhpcy5faXNTaG93bigpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHJlbGF0ZWRUYXJnZXQgPSB7XG4gICAgICByZWxhdGVkVGFyZ2V0OiB0aGlzLl9lbGVtZW50XG4gICAgfTtcbiAgICB0aGlzLl9jb21wbGV0ZUhpZGUocmVsYXRlZFRhcmdldCk7XG4gIH1cbiAgZGlzcG9zZSgpIHtcbiAgICBpZiAodGhpcy5fcG9wcGVyKSB7XG4gICAgICB0aGlzLl9wb3BwZXIuZGVzdHJveSgpO1xuICAgIH1cbiAgICBzdXBlci5kaXNwb3NlKCk7XG4gIH1cbiAgdXBkYXRlKCkge1xuICAgIHRoaXMuX2luTmF2YmFyID0gdGhpcy5fZGV0ZWN0TmF2YmFyKCk7XG4gICAgaWYgKHRoaXMuX3BvcHBlcikge1xuICAgICAgdGhpcy5fcG9wcGVyLnVwZGF0ZSgpO1xuICAgIH1cbiAgfVxuXG4gIC8vIFByaXZhdGVcbiAgX2NvbXBsZXRlSGlkZShyZWxhdGVkVGFyZ2V0KSB7XG4gICAgY29uc3QgaGlkZUV2ZW50ID0gRXZlbnRIYW5kbGVyLnRyaWdnZXIodGhpcy5fZWxlbWVudCwgRVZFTlRfSElERSQ1LCByZWxhdGVkVGFyZ2V0KTtcbiAgICBpZiAoaGlkZUV2ZW50LmRlZmF1bHRQcmV2ZW50ZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBJZiB0aGlzIGlzIGEgdG91Y2gtZW5hYmxlZCBkZXZpY2Ugd2UgcmVtb3ZlIHRoZSBleHRyYVxuICAgIC8vIGVtcHR5IG1vdXNlb3ZlciBsaXN0ZW5lcnMgd2UgYWRkZWQgZm9yIGlPUyBzdXBwb3J0XG4gICAgaWYgKCdvbnRvdWNoc3RhcnQnIGluIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCkge1xuICAgICAgZm9yIChjb25zdCBlbGVtZW50IG9mIFtdLmNvbmNhdCguLi5kb2N1bWVudC5ib2R5LmNoaWxkcmVuKSkge1xuICAgICAgICBFdmVudEhhbmRsZXIub2ZmKGVsZW1lbnQsICdtb3VzZW92ZXInLCBub29wKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHRoaXMuX3BvcHBlcikge1xuICAgICAgdGhpcy5fcG9wcGVyLmRlc3Ryb3koKTtcbiAgICB9XG4gICAgdGhpcy5fbWVudS5jbGFzc0xpc3QucmVtb3ZlKENMQVNTX05BTUVfU0hPVyQ2KTtcbiAgICB0aGlzLl9lbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoQ0xBU1NfTkFNRV9TSE9XJDYpO1xuICAgIHRoaXMuX2VsZW1lbnQuc2V0QXR0cmlidXRlKCdhcmlhLWV4cGFuZGVkJywgJ2ZhbHNlJyk7XG4gICAgTWFuaXB1bGF0b3IucmVtb3ZlRGF0YUF0dHJpYnV0ZSh0aGlzLl9tZW51LCAncG9wcGVyJyk7XG4gICAgRXZlbnRIYW5kbGVyLnRyaWdnZXIodGhpcy5fZWxlbWVudCwgRVZFTlRfSElEREVOJDUsIHJlbGF0ZWRUYXJnZXQpO1xuICB9XG4gIF9nZXRDb25maWcoY29uZmlnKSB7XG4gICAgY29uZmlnID0gc3VwZXIuX2dldENvbmZpZyhjb25maWcpO1xuICAgIGlmICh0eXBlb2YgY29uZmlnLnJlZmVyZW5jZSA9PT0gJ29iamVjdCcgJiYgIWlzRWxlbWVudChjb25maWcucmVmZXJlbmNlKSAmJiB0eXBlb2YgY29uZmlnLnJlZmVyZW5jZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgIC8vIFBvcHBlciB2aXJ0dWFsIGVsZW1lbnRzIHJlcXVpcmUgYSBnZXRCb3VuZGluZ0NsaWVudFJlY3QgbWV0aG9kXG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGAke05BTUUkYS50b1VwcGVyQ2FzZSgpfTogT3B0aW9uIFwicmVmZXJlbmNlXCIgcHJvdmlkZWQgdHlwZSBcIm9iamVjdFwiIHdpdGhvdXQgYSByZXF1aXJlZCBcImdldEJvdW5kaW5nQ2xpZW50UmVjdFwiIG1ldGhvZC5gKTtcbiAgICB9XG4gICAgcmV0dXJuIGNvbmZpZztcbiAgfVxuICBfY3JlYXRlUG9wcGVyKCkge1xuICAgIGlmICh0eXBlb2YgUG9wcGVyID09PSAndW5kZWZpbmVkJykge1xuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQm9vdHN0cmFwXFwncyBkcm9wZG93bnMgcmVxdWlyZSBQb3BwZXIgKGh0dHBzOi8vcG9wcGVyLmpzLm9yZyknKTtcbiAgICB9XG4gICAgbGV0IHJlZmVyZW5jZUVsZW1lbnQgPSB0aGlzLl9lbGVtZW50O1xuICAgIGlmICh0aGlzLl9jb25maWcucmVmZXJlbmNlID09PSAncGFyZW50Jykge1xuICAgICAgcmVmZXJlbmNlRWxlbWVudCA9IHRoaXMuX3BhcmVudDtcbiAgICB9IGVsc2UgaWYgKGlzRWxlbWVudCh0aGlzLl9jb25maWcucmVmZXJlbmNlKSkge1xuICAgICAgcmVmZXJlbmNlRWxlbWVudCA9IGdldEVsZW1lbnQodGhpcy5fY29uZmlnLnJlZmVyZW5jZSk7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgdGhpcy5fY29uZmlnLnJlZmVyZW5jZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgIHJlZmVyZW5jZUVsZW1lbnQgPSB0aGlzLl9jb25maWcucmVmZXJlbmNlO1xuICAgIH1cbiAgICBjb25zdCBwb3BwZXJDb25maWcgPSB0aGlzLl9nZXRQb3BwZXJDb25maWcoKTtcbiAgICB0aGlzLl9wb3BwZXIgPSBQb3BwZXIuY3JlYXRlUG9wcGVyKHJlZmVyZW5jZUVsZW1lbnQsIHRoaXMuX21lbnUsIHBvcHBlckNvbmZpZyk7XG4gIH1cbiAgX2lzU2hvd24oKSB7XG4gICAgcmV0dXJuIHRoaXMuX21lbnUuY2xhc3NMaXN0LmNvbnRhaW5zKENMQVNTX05BTUVfU0hPVyQ2KTtcbiAgfVxuICBfZ2V0UGxhY2VtZW50KCkge1xuICAgIGNvbnN0IHBhcmVudERyb3Bkb3duID0gdGhpcy5fcGFyZW50O1xuICAgIGlmIChwYXJlbnREcm9wZG93bi5jbGFzc0xpc3QuY29udGFpbnMoQ0xBU1NfTkFNRV9EUk9QRU5EKSkge1xuICAgICAgcmV0dXJuIFBMQUNFTUVOVF9SSUdIVDtcbiAgICB9XG4gICAgaWYgKHBhcmVudERyb3Bkb3duLmNsYXNzTGlzdC5jb250YWlucyhDTEFTU19OQU1FX0RST1BTVEFSVCkpIHtcbiAgICAgIHJldHVybiBQTEFDRU1FTlRfTEVGVDtcbiAgICB9XG4gICAgaWYgKHBhcmVudERyb3Bkb3duLmNsYXNzTGlzdC5jb250YWlucyhDTEFTU19OQU1FX0RST1BVUF9DRU5URVIpKSB7XG4gICAgICByZXR1cm4gUExBQ0VNRU5UX1RPUENFTlRFUjtcbiAgICB9XG4gICAgaWYgKHBhcmVudERyb3Bkb3duLmNsYXNzTGlzdC5jb250YWlucyhDTEFTU19OQU1FX0RST1BET1dOX0NFTlRFUikpIHtcbiAgICAgIHJldHVybiBQTEFDRU1FTlRfQk9UVE9NQ0VOVEVSO1xuICAgIH1cblxuICAgIC8vIFdlIG5lZWQgdG8gdHJpbSB0aGUgdmFsdWUgYmVjYXVzZSBjdXN0b20gcHJvcGVydGllcyBjYW4gYWxzbyBpbmNsdWRlIHNwYWNlc1xuICAgIGNvbnN0IGlzRW5kID0gZ2V0Q29tcHV0ZWRTdHlsZSh0aGlzLl9tZW51KS5nZXRQcm9wZXJ0eVZhbHVlKCctLWJzLXBvc2l0aW9uJykudHJpbSgpID09PSAnZW5kJztcbiAgICBpZiAocGFyZW50RHJvcGRvd24uY2xhc3NMaXN0LmNvbnRhaW5zKENMQVNTX05BTUVfRFJPUFVQKSkge1xuICAgICAgcmV0dXJuIGlzRW5kID8gUExBQ0VNRU5UX1RPUEVORCA6IFBMQUNFTUVOVF9UT1A7XG4gICAgfVxuICAgIHJldHVybiBpc0VuZCA/IFBMQUNFTUVOVF9CT1RUT01FTkQgOiBQTEFDRU1FTlRfQk9UVE9NO1xuICB9XG4gIF9kZXRlY3ROYXZiYXIoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2VsZW1lbnQuY2xvc2VzdChTRUxFQ1RPUl9OQVZCQVIpICE9PSBudWxsO1xuICB9XG4gIF9nZXRPZmZzZXQoKSB7XG4gICAgY29uc3Qge1xuICAgICAgb2Zmc2V0XG4gICAgfSA9IHRoaXMuX2NvbmZpZztcbiAgICBpZiAodHlwZW9mIG9mZnNldCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHJldHVybiBvZmZzZXQuc3BsaXQoJywnKS5tYXAodmFsdWUgPT4gTnVtYmVyLnBhcnNlSW50KHZhbHVlLCAxMCkpO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIG9mZnNldCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcmV0dXJuIHBvcHBlckRhdGEgPT4gb2Zmc2V0KHBvcHBlckRhdGEsIHRoaXMuX2VsZW1lbnQpO1xuICAgIH1cbiAgICByZXR1cm4gb2Zmc2V0O1xuICB9XG4gIF9nZXRQb3BwZXJDb25maWcoKSB7XG4gICAgY29uc3QgZGVmYXVsdEJzUG9wcGVyQ29uZmlnID0ge1xuICAgICAgcGxhY2VtZW50OiB0aGlzLl9nZXRQbGFjZW1lbnQoKSxcbiAgICAgIG1vZGlmaWVyczogW3tcbiAgICAgICAgbmFtZTogJ3ByZXZlbnRPdmVyZmxvdycsXG4gICAgICAgIG9wdGlvbnM6IHtcbiAgICAgICAgICBib3VuZGFyeTogdGhpcy5fY29uZmlnLmJvdW5kYXJ5XG4gICAgICAgIH1cbiAgICAgIH0sIHtcbiAgICAgICAgbmFtZTogJ29mZnNldCcsXG4gICAgICAgIG9wdGlvbnM6IHtcbiAgICAgICAgICBvZmZzZXQ6IHRoaXMuX2dldE9mZnNldCgpXG4gICAgICAgIH1cbiAgICAgIH1dXG4gICAgfTtcblxuICAgIC8vIERpc2FibGUgUG9wcGVyIGlmIHdlIGhhdmUgYSBzdGF0aWMgZGlzcGxheSBvciBEcm9wZG93biBpcyBpbiBOYXZiYXJcbiAgICBpZiAodGhpcy5faW5OYXZiYXIgfHwgdGhpcy5fY29uZmlnLmRpc3BsYXkgPT09ICdzdGF0aWMnKSB7XG4gICAgICBNYW5pcHVsYXRvci5zZXREYXRhQXR0cmlidXRlKHRoaXMuX21lbnUsICdwb3BwZXInLCAnc3RhdGljJyk7IC8vIFRPRE86IHY2IHJlbW92ZVxuICAgICAgZGVmYXVsdEJzUG9wcGVyQ29uZmlnLm1vZGlmaWVycyA9IFt7XG4gICAgICAgIG5hbWU6ICdhcHBseVN0eWxlcycsXG4gICAgICAgIGVuYWJsZWQ6IGZhbHNlXG4gICAgICB9XTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLmRlZmF1bHRCc1BvcHBlckNvbmZpZyxcbiAgICAgIC4uLmV4ZWN1dGUodGhpcy5fY29uZmlnLnBvcHBlckNvbmZpZywgW2RlZmF1bHRCc1BvcHBlckNvbmZpZ10pXG4gICAgfTtcbiAgfVxuICBfc2VsZWN0TWVudUl0ZW0oe1xuICAgIGtleSxcbiAgICB0YXJnZXRcbiAgfSkge1xuICAgIGNvbnN0IGl0ZW1zID0gU2VsZWN0b3JFbmdpbmUuZmluZChTRUxFQ1RPUl9WSVNJQkxFX0lURU1TLCB0aGlzLl9tZW51KS5maWx0ZXIoZWxlbWVudCA9PiBpc1Zpc2libGUoZWxlbWVudCkpO1xuICAgIGlmICghaXRlbXMubGVuZ3RoKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gaWYgdGFyZ2V0IGlzbid0IGluY2x1ZGVkIGluIGl0ZW1zIChlLmcuIHdoZW4gZXhwYW5kaW5nIHRoZSBkcm9wZG93bilcbiAgICAvLyBhbGxvdyBjeWNsaW5nIHRvIGdldCB0aGUgbGFzdCBpdGVtIGluIGNhc2Uga2V5IGVxdWFscyBBUlJPV19VUF9LRVlcbiAgICBnZXROZXh0QWN0aXZlRWxlbWVudChpdGVtcywgdGFyZ2V0LCBrZXkgPT09IEFSUk9XX0RPV05fS0VZJDEsICFpdGVtcy5pbmNsdWRlcyh0YXJnZXQpKS5mb2N1cygpO1xuICB9XG5cbiAgLy8gU3RhdGljXG4gIHN0YXRpYyBqUXVlcnlJbnRlcmZhY2UoY29uZmlnKSB7XG4gICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBkYXRhID0gRHJvcGRvd24uZ2V0T3JDcmVhdGVJbnN0YW5jZSh0aGlzLCBjb25maWcpO1xuICAgICAgaWYgKHR5cGVvZiBjb25maWcgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgZGF0YVtjb25maWddID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBObyBtZXRob2QgbmFtZWQgXCIke2NvbmZpZ31cImApO1xuICAgICAgfVxuICAgICAgZGF0YVtjb25maWddKCk7XG4gICAgfSk7XG4gIH1cbiAgc3RhdGljIGNsZWFyTWVudXMoZXZlbnQpIHtcbiAgICBpZiAoZXZlbnQuYnV0dG9uID09PSBSSUdIVF9NT1VTRV9CVVRUT04gfHwgZXZlbnQudHlwZSA9PT0gJ2tleXVwJyAmJiBldmVudC5rZXkgIT09IFRBQl9LRVkkMSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBvcGVuVG9nZ2xlcyA9IFNlbGVjdG9yRW5naW5lLmZpbmQoU0VMRUNUT1JfREFUQV9UT0dHTEVfU0hPV04pO1xuICAgIGZvciAoY29uc3QgdG9nZ2xlIG9mIG9wZW5Ub2dnbGVzKSB7XG4gICAgICBjb25zdCBjb250ZXh0ID0gRHJvcGRvd24uZ2V0SW5zdGFuY2UodG9nZ2xlKTtcbiAgICAgIGlmICghY29udGV4dCB8fCBjb250ZXh0Ll9jb25maWcuYXV0b0Nsb3NlID09PSBmYWxzZSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGNvbXBvc2VkUGF0aCA9IGV2ZW50LmNvbXBvc2VkUGF0aCgpO1xuICAgICAgY29uc3QgaXNNZW51VGFyZ2V0ID0gY29tcG9zZWRQYXRoLmluY2x1ZGVzKGNvbnRleHQuX21lbnUpO1xuICAgICAgaWYgKGNvbXBvc2VkUGF0aC5pbmNsdWRlcyhjb250ZXh0Ll9lbGVtZW50KSB8fCBjb250ZXh0Ll9jb25maWcuYXV0b0Nsb3NlID09PSAnaW5zaWRlJyAmJiAhaXNNZW51VGFyZ2V0IHx8IGNvbnRleHQuX2NvbmZpZy5hdXRvQ2xvc2UgPT09ICdvdXRzaWRlJyAmJiBpc01lbnVUYXJnZXQpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIFRhYiBuYXZpZ2F0aW9uIHRocm91Z2ggdGhlIGRyb3Bkb3duIG1lbnUgb3IgZXZlbnRzIGZyb20gY29udGFpbmVkIGlucHV0cyBzaG91bGRuJ3QgY2xvc2UgdGhlIG1lbnVcbiAgICAgIGlmIChjb250ZXh0Ll9tZW51LmNvbnRhaW5zKGV2ZW50LnRhcmdldCkgJiYgKGV2ZW50LnR5cGUgPT09ICdrZXl1cCcgJiYgZXZlbnQua2V5ID09PSBUQUJfS0VZJDEgfHwgL2lucHV0fHNlbGVjdHxvcHRpb258dGV4dGFyZWF8Zm9ybS9pLnRlc3QoZXZlbnQudGFyZ2V0LnRhZ05hbWUpKSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHJlbGF0ZWRUYXJnZXQgPSB7XG4gICAgICAgIHJlbGF0ZWRUYXJnZXQ6IGNvbnRleHQuX2VsZW1lbnRcbiAgICAgIH07XG4gICAgICBpZiAoZXZlbnQudHlwZSA9PT0gJ2NsaWNrJykge1xuICAgICAgICByZWxhdGVkVGFyZ2V0LmNsaWNrRXZlbnQgPSBldmVudDtcbiAgICAgIH1cbiAgICAgIGNvbnRleHQuX2NvbXBsZXRlSGlkZShyZWxhdGVkVGFyZ2V0KTtcbiAgICB9XG4gIH1cbiAgc3RhdGljIGRhdGFBcGlLZXlkb3duSGFuZGxlcihldmVudCkge1xuICAgIC8vIElmIG5vdCBhbiBVUCB8IERPV04gfCBFU0NBUEUga2V5ID0+IG5vdCBhIGRyb3Bkb3duIGNvbW1hbmRcbiAgICAvLyBJZiBpbnB1dC90ZXh0YXJlYSAmJiBpZiBrZXkgaXMgb3RoZXIgdGhhbiBFU0NBUEUgPT4gbm90IGEgZHJvcGRvd24gY29tbWFuZFxuXG4gICAgY29uc3QgaXNJbnB1dCA9IC9pbnB1dHx0ZXh0YXJlYS9pLnRlc3QoZXZlbnQudGFyZ2V0LnRhZ05hbWUpO1xuICAgIGNvbnN0IGlzRXNjYXBlRXZlbnQgPSBldmVudC5rZXkgPT09IEVTQ0FQRV9LRVkkMjtcbiAgICBjb25zdCBpc1VwT3JEb3duRXZlbnQgPSBbQVJST1dfVVBfS0VZJDEsIEFSUk9XX0RPV05fS0VZJDFdLmluY2x1ZGVzKGV2ZW50LmtleSk7XG4gICAgaWYgKCFpc1VwT3JEb3duRXZlbnQgJiYgIWlzRXNjYXBlRXZlbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKGlzSW5wdXQgJiYgIWlzRXNjYXBlRXZlbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuICAgIC8vIFRPRE86IHY2IHJldmVydCAjMzcwMTEgJiBjaGFuZ2UgbWFya3VwIGh0dHBzOi8vZ2V0Ym9vdHN0cmFwLmNvbS9kb2NzLzUuMy9mb3Jtcy9pbnB1dC1ncm91cC9cbiAgICBjb25zdCBnZXRUb2dnbGVCdXR0b24gPSB0aGlzLm1hdGNoZXMoU0VMRUNUT1JfREFUQV9UT0dHTEUkMykgPyB0aGlzIDogU2VsZWN0b3JFbmdpbmUucHJldih0aGlzLCBTRUxFQ1RPUl9EQVRBX1RPR0dMRSQzKVswXSB8fCBTZWxlY3RvckVuZ2luZS5uZXh0KHRoaXMsIFNFTEVDVE9SX0RBVEFfVE9HR0xFJDMpWzBdIHx8IFNlbGVjdG9yRW5naW5lLmZpbmRPbmUoU0VMRUNUT1JfREFUQV9UT0dHTEUkMywgZXZlbnQuZGVsZWdhdGVUYXJnZXQucGFyZW50Tm9kZSk7XG4gICAgY29uc3QgaW5zdGFuY2UgPSBEcm9wZG93bi5nZXRPckNyZWF0ZUluc3RhbmNlKGdldFRvZ2dsZUJ1dHRvbik7XG4gICAgaWYgKGlzVXBPckRvd25FdmVudCkge1xuICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICBpbnN0YW5jZS5zaG93KCk7XG4gICAgICBpbnN0YW5jZS5fc2VsZWN0TWVudUl0ZW0oZXZlbnQpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoaW5zdGFuY2UuX2lzU2hvd24oKSkge1xuICAgICAgLy8gZWxzZSBpcyBlc2NhcGUgYW5kIHdlIGNoZWNrIGlmIGl0IGlzIHNob3duXG4gICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgIGluc3RhbmNlLmhpZGUoKTtcbiAgICAgIGdldFRvZ2dsZUJ1dHRvbi5mb2N1cygpO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIERhdGEgQVBJIGltcGxlbWVudGF0aW9uXG4gKi9cblxuRXZlbnRIYW5kbGVyLm9uKGRvY3VtZW50LCBFVkVOVF9LRVlET1dOX0RBVEFfQVBJLCBTRUxFQ1RPUl9EQVRBX1RPR0dMRSQzLCBEcm9wZG93bi5kYXRhQXBpS2V5ZG93bkhhbmRsZXIpO1xuRXZlbnRIYW5kbGVyLm9uKGRvY3VtZW50LCBFVkVOVF9LRVlET1dOX0RBVEFfQVBJLCBTRUxFQ1RPUl9NRU5VLCBEcm9wZG93bi5kYXRhQXBpS2V5ZG93bkhhbmRsZXIpO1xuRXZlbnRIYW5kbGVyLm9uKGRvY3VtZW50LCBFVkVOVF9DTElDS19EQVRBX0FQSSQzLCBEcm9wZG93bi5jbGVhck1lbnVzKTtcbkV2ZW50SGFuZGxlci5vbihkb2N1bWVudCwgRVZFTlRfS0VZVVBfREFUQV9BUEksIERyb3Bkb3duLmNsZWFyTWVudXMpO1xuRXZlbnRIYW5kbGVyLm9uKGRvY3VtZW50LCBFVkVOVF9DTElDS19EQVRBX0FQSSQzLCBTRUxFQ1RPUl9EQVRBX1RPR0dMRSQzLCBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgRHJvcGRvd24uZ2V0T3JDcmVhdGVJbnN0YW5jZSh0aGlzKS50b2dnbGUoKTtcbn0pO1xuXG4vKipcbiAqIGpRdWVyeVxuICovXG5cbmRlZmluZUpRdWVyeVBsdWdpbihEcm9wZG93bik7XG5cbi8qKlxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIEJvb3RzdHJhcCB1dGlsL2JhY2tkcm9wLmpzXG4gKiBMaWNlbnNlZCB1bmRlciBNSVQgKGh0dHBzOi8vZ2l0aHViLmNvbS90d2JzL2Jvb3RzdHJhcC9ibG9iL21haW4vTElDRU5TRSlcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKi9cblxuXG4vKipcbiAqIENvbnN0YW50c1xuICovXG5cbmNvbnN0IE5BTUUkOSA9ICdiYWNrZHJvcCc7XG5jb25zdCBDTEFTU19OQU1FX0ZBREUkNCA9ICdmYWRlJztcbmNvbnN0IENMQVNTX05BTUVfU0hPVyQ1ID0gJ3Nob3cnO1xuY29uc3QgRVZFTlRfTU9VU0VET1dOID0gYG1vdXNlZG93bi5icy4ke05BTUUkOX1gO1xuY29uc3QgRGVmYXVsdCQ4ID0ge1xuICBjbGFzc05hbWU6ICdtb2RhbC1iYWNrZHJvcCcsXG4gIGNsaWNrQ2FsbGJhY2s6IG51bGwsXG4gIGlzQW5pbWF0ZWQ6IGZhbHNlLFxuICBpc1Zpc2libGU6IHRydWUsXG4gIC8vIGlmIGZhbHNlLCB3ZSB1c2UgdGhlIGJhY2tkcm9wIGhlbHBlciB3aXRob3V0IGFkZGluZyBhbnkgZWxlbWVudCB0byB0aGUgZG9tXG4gIHJvb3RFbGVtZW50OiAnYm9keScgLy8gZ2l2ZSB0aGUgY2hvaWNlIHRvIHBsYWNlIGJhY2tkcm9wIHVuZGVyIGRpZmZlcmVudCBlbGVtZW50c1xufTtcblxuY29uc3QgRGVmYXVsdFR5cGUkOCA9IHtcbiAgY2xhc3NOYW1lOiAnc3RyaW5nJyxcbiAgY2xpY2tDYWxsYmFjazogJyhmdW5jdGlvbnxudWxsKScsXG4gIGlzQW5pbWF0ZWQ6ICdib29sZWFuJyxcbiAgaXNWaXNpYmxlOiAnYm9vbGVhbicsXG4gIHJvb3RFbGVtZW50OiAnKGVsZW1lbnR8c3RyaW5nKSdcbn07XG5cbi8qKlxuICogQ2xhc3MgZGVmaW5pdGlvblxuICovXG5cbmNsYXNzIEJhY2tkcm9wIGV4dGVuZHMgQ29uZmlnIHtcbiAgY29uc3RydWN0b3IoY29uZmlnKSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLl9jb25maWcgPSB0aGlzLl9nZXRDb25maWcoY29uZmlnKTtcbiAgICB0aGlzLl9pc0FwcGVuZGVkID0gZmFsc2U7XG4gICAgdGhpcy5fZWxlbWVudCA9IG51bGw7XG4gIH1cblxuICAvLyBHZXR0ZXJzXG4gIHN0YXRpYyBnZXQgRGVmYXVsdCgpIHtcbiAgICByZXR1cm4gRGVmYXVsdCQ4O1xuICB9XG4gIHN0YXRpYyBnZXQgRGVmYXVsdFR5cGUoKSB7XG4gICAgcmV0dXJuIERlZmF1bHRUeXBlJDg7XG4gIH1cbiAgc3RhdGljIGdldCBOQU1FKCkge1xuICAgIHJldHVybiBOQU1FJDk7XG4gIH1cblxuICAvLyBQdWJsaWNcbiAgc2hvdyhjYWxsYmFjaykge1xuICAgIGlmICghdGhpcy5fY29uZmlnLmlzVmlzaWJsZSkge1xuICAgICAgZXhlY3V0ZShjYWxsYmFjayk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuX2FwcGVuZCgpO1xuICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLl9nZXRFbGVtZW50KCk7XG4gICAgaWYgKHRoaXMuX2NvbmZpZy5pc0FuaW1hdGVkKSB7XG4gICAgICByZWZsb3coZWxlbWVudCk7XG4gICAgfVxuICAgIGVsZW1lbnQuY2xhc3NMaXN0LmFkZChDTEFTU19OQU1FX1NIT1ckNSk7XG4gICAgdGhpcy5fZW11bGF0ZUFuaW1hdGlvbigoKSA9PiB7XG4gICAgICBleGVjdXRlKGNhbGxiYWNrKTtcbiAgICB9KTtcbiAgfVxuICBoaWRlKGNhbGxiYWNrKSB7XG4gICAgaWYgKCF0aGlzLl9jb25maWcuaXNWaXNpYmxlKSB7XG4gICAgICBleGVjdXRlKGNhbGxiYWNrKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5fZ2V0RWxlbWVudCgpLmNsYXNzTGlzdC5yZW1vdmUoQ0xBU1NfTkFNRV9TSE9XJDUpO1xuICAgIHRoaXMuX2VtdWxhdGVBbmltYXRpb24oKCkgPT4ge1xuICAgICAgdGhpcy5kaXNwb3NlKCk7XG4gICAgICBleGVjdXRlKGNhbGxiYWNrKTtcbiAgICB9KTtcbiAgfVxuICBkaXNwb3NlKCkge1xuICAgIGlmICghdGhpcy5faXNBcHBlbmRlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBFdmVudEhhbmRsZXIub2ZmKHRoaXMuX2VsZW1lbnQsIEVWRU5UX01PVVNFRE9XTik7XG4gICAgdGhpcy5fZWxlbWVudC5yZW1vdmUoKTtcbiAgICB0aGlzLl9pc0FwcGVuZGVkID0gZmFsc2U7XG4gIH1cblxuICAvLyBQcml2YXRlXG4gIF9nZXRFbGVtZW50KCkge1xuICAgIGlmICghdGhpcy5fZWxlbWVudCkge1xuICAgICAgY29uc3QgYmFja2Ryb3AgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgIGJhY2tkcm9wLmNsYXNzTmFtZSA9IHRoaXMuX2NvbmZpZy5jbGFzc05hbWU7XG4gICAgICBpZiAodGhpcy5fY29uZmlnLmlzQW5pbWF0ZWQpIHtcbiAgICAgICAgYmFja2Ryb3AuY2xhc3NMaXN0LmFkZChDTEFTU19OQU1FX0ZBREUkNCk7XG4gICAgICB9XG4gICAgICB0aGlzLl9lbGVtZW50ID0gYmFja2Ryb3A7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9lbGVtZW50O1xuICB9XG4gIF9jb25maWdBZnRlck1lcmdlKGNvbmZpZykge1xuICAgIC8vIHVzZSBnZXRFbGVtZW50KCkgd2l0aCB0aGUgZGVmYXVsdCBcImJvZHlcIiB0byBnZXQgYSBmcmVzaCBFbGVtZW50IG9uIGVhY2ggaW5zdGFudGlhdGlvblxuICAgIGNvbmZpZy5yb290RWxlbWVudCA9IGdldEVsZW1lbnQoY29uZmlnLnJvb3RFbGVtZW50KTtcbiAgICByZXR1cm4gY29uZmlnO1xuICB9XG4gIF9hcHBlbmQoKSB7XG4gICAgaWYgKHRoaXMuX2lzQXBwZW5kZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgZWxlbWVudCA9IHRoaXMuX2dldEVsZW1lbnQoKTtcbiAgICB0aGlzLl9jb25maWcucm9vdEVsZW1lbnQuYXBwZW5kKGVsZW1lbnQpO1xuICAgIEV2ZW50SGFuZGxlci5vbihlbGVtZW50LCBFVkVOVF9NT1VTRURPV04sICgpID0+IHtcbiAgICAgIGV4ZWN1dGUodGhpcy5fY29uZmlnLmNsaWNrQ2FsbGJhY2spO1xuICAgIH0pO1xuICAgIHRoaXMuX2lzQXBwZW5kZWQgPSB0cnVlO1xuICB9XG4gIF9lbXVsYXRlQW5pbWF0aW9uKGNhbGxiYWNrKSB7XG4gICAgZXhlY3V0ZUFmdGVyVHJhbnNpdGlvbihjYWxsYmFjaywgdGhpcy5fZ2V0RWxlbWVudCgpLCB0aGlzLl9jb25maWcuaXNBbmltYXRlZCk7XG4gIH1cbn1cblxuLyoqXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogQm9vdHN0cmFwIHV0aWwvZm9jdXN0cmFwLmpzXG4gKiBMaWNlbnNlZCB1bmRlciBNSVQgKGh0dHBzOi8vZ2l0aHViLmNvbS90d2JzL2Jvb3RzdHJhcC9ibG9iL21haW4vTElDRU5TRSlcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKi9cblxuXG4vKipcbiAqIENvbnN0YW50c1xuICovXG5cbmNvbnN0IE5BTUUkOCA9ICdmb2N1c3RyYXAnO1xuY29uc3QgREFUQV9LRVkkNSA9ICdicy5mb2N1c3RyYXAnO1xuY29uc3QgRVZFTlRfS0VZJDUgPSBgLiR7REFUQV9LRVkkNX1gO1xuY29uc3QgRVZFTlRfRk9DVVNJTiQyID0gYGZvY3VzaW4ke0VWRU5UX0tFWSQ1fWA7XG5jb25zdCBFVkVOVF9LRVlET1dOX1RBQiA9IGBrZXlkb3duLnRhYiR7RVZFTlRfS0VZJDV9YDtcbmNvbnN0IFRBQl9LRVkgPSAnVGFiJztcbmNvbnN0IFRBQl9OQVZfRk9SV0FSRCA9ICdmb3J3YXJkJztcbmNvbnN0IFRBQl9OQVZfQkFDS1dBUkQgPSAnYmFja3dhcmQnO1xuY29uc3QgRGVmYXVsdCQ3ID0ge1xuICBhdXRvZm9jdXM6IHRydWUsXG4gIHRyYXBFbGVtZW50OiBudWxsIC8vIFRoZSBlbGVtZW50IHRvIHRyYXAgZm9jdXMgaW5zaWRlIG9mXG59O1xuXG5jb25zdCBEZWZhdWx0VHlwZSQ3ID0ge1xuICBhdXRvZm9jdXM6ICdib29sZWFuJyxcbiAgdHJhcEVsZW1lbnQ6ICdlbGVtZW50J1xufTtcblxuLyoqXG4gKiBDbGFzcyBkZWZpbml0aW9uXG4gKi9cblxuY2xhc3MgRm9jdXNUcmFwIGV4dGVuZHMgQ29uZmlnIHtcbiAgY29uc3RydWN0b3IoY29uZmlnKSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLl9jb25maWcgPSB0aGlzLl9nZXRDb25maWcoY29uZmlnKTtcbiAgICB0aGlzLl9pc0FjdGl2ZSA9IGZhbHNlO1xuICAgIHRoaXMuX2xhc3RUYWJOYXZEaXJlY3Rpb24gPSBudWxsO1xuICB9XG5cbiAgLy8gR2V0dGVyc1xuICBzdGF0aWMgZ2V0IERlZmF1bHQoKSB7XG4gICAgcmV0dXJuIERlZmF1bHQkNztcbiAgfVxuICBzdGF0aWMgZ2V0IERlZmF1bHRUeXBlKCkge1xuICAgIHJldHVybiBEZWZhdWx0VHlwZSQ3O1xuICB9XG4gIHN0YXRpYyBnZXQgTkFNRSgpIHtcbiAgICByZXR1cm4gTkFNRSQ4O1xuICB9XG5cbiAgLy8gUHVibGljXG4gIGFjdGl2YXRlKCkge1xuICAgIGlmICh0aGlzLl9pc0FjdGl2ZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAodGhpcy5fY29uZmlnLmF1dG9mb2N1cykge1xuICAgICAgdGhpcy5fY29uZmlnLnRyYXBFbGVtZW50LmZvY3VzKCk7XG4gICAgfVxuICAgIEV2ZW50SGFuZGxlci5vZmYoZG9jdW1lbnQsIEVWRU5UX0tFWSQ1KTsgLy8gZ3VhcmQgYWdhaW5zdCBpbmZpbml0ZSBmb2N1cyBsb29wXG4gICAgRXZlbnRIYW5kbGVyLm9uKGRvY3VtZW50LCBFVkVOVF9GT0NVU0lOJDIsIGV2ZW50ID0+IHRoaXMuX2hhbmRsZUZvY3VzaW4oZXZlbnQpKTtcbiAgICBFdmVudEhhbmRsZXIub24oZG9jdW1lbnQsIEVWRU5UX0tFWURPV05fVEFCLCBldmVudCA9PiB0aGlzLl9oYW5kbGVLZXlkb3duKGV2ZW50KSk7XG4gICAgdGhpcy5faXNBY3RpdmUgPSB0cnVlO1xuICB9XG4gIGRlYWN0aXZhdGUoKSB7XG4gICAgaWYgKCF0aGlzLl9pc0FjdGl2ZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLl9pc0FjdGl2ZSA9IGZhbHNlO1xuICAgIEV2ZW50SGFuZGxlci5vZmYoZG9jdW1lbnQsIEVWRU5UX0tFWSQ1KTtcbiAgfVxuXG4gIC8vIFByaXZhdGVcbiAgX2hhbmRsZUZvY3VzaW4oZXZlbnQpIHtcbiAgICBjb25zdCB7XG4gICAgICB0cmFwRWxlbWVudFxuICAgIH0gPSB0aGlzLl9jb25maWc7XG4gICAgaWYgKGV2ZW50LnRhcmdldCA9PT0gZG9jdW1lbnQgfHwgZXZlbnQudGFyZ2V0ID09PSB0cmFwRWxlbWVudCB8fCB0cmFwRWxlbWVudC5jb250YWlucyhldmVudC50YXJnZXQpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGVsZW1lbnRzID0gU2VsZWN0b3JFbmdpbmUuZm9jdXNhYmxlQ2hpbGRyZW4odHJhcEVsZW1lbnQpO1xuICAgIGlmIChlbGVtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgIHRyYXBFbGVtZW50LmZvY3VzKCk7XG4gICAgfSBlbHNlIGlmICh0aGlzLl9sYXN0VGFiTmF2RGlyZWN0aW9uID09PSBUQUJfTkFWX0JBQ0tXQVJEKSB7XG4gICAgICBlbGVtZW50c1tlbGVtZW50cy5sZW5ndGggLSAxXS5mb2N1cygpO1xuICAgIH0gZWxzZSB7XG4gICAgICBlbGVtZW50c1swXS5mb2N1cygpO1xuICAgIH1cbiAgfVxuICBfaGFuZGxlS2V5ZG93bihldmVudCkge1xuICAgIGlmIChldmVudC5rZXkgIT09IFRBQl9LRVkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5fbGFzdFRhYk5hdkRpcmVjdGlvbiA9IGV2ZW50LnNoaWZ0S2V5ID8gVEFCX05BVl9CQUNLV0FSRCA6IFRBQl9OQVZfRk9SV0FSRDtcbiAgfVxufVxuXG4vKipcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiBCb290c3RyYXAgdXRpbC9zY3JvbGxCYXIuanNcbiAqIExpY2Vuc2VkIHVuZGVyIE1JVCAoaHR0cHM6Ly9naXRodWIuY29tL3R3YnMvYm9vdHN0cmFwL2Jsb2IvbWFpbi9MSUNFTlNFKVxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqL1xuXG5cbi8qKlxuICogQ29uc3RhbnRzXG4gKi9cblxuY29uc3QgU0VMRUNUT1JfRklYRURfQ09OVEVOVCA9ICcuZml4ZWQtdG9wLCAuZml4ZWQtYm90dG9tLCAuaXMtZml4ZWQsIC5zdGlja3ktdG9wJztcbmNvbnN0IFNFTEVDVE9SX1NUSUNLWV9DT05URU5UID0gJy5zdGlja3ktdG9wJztcbmNvbnN0IFBST1BFUlRZX1BBRERJTkcgPSAncGFkZGluZy1yaWdodCc7XG5jb25zdCBQUk9QRVJUWV9NQVJHSU4gPSAnbWFyZ2luLXJpZ2h0JztcblxuLyoqXG4gKiBDbGFzcyBkZWZpbml0aW9uXG4gKi9cblxuY2xhc3MgU2Nyb2xsQmFySGVscGVyIHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgdGhpcy5fZWxlbWVudCA9IGRvY3VtZW50LmJvZHk7XG4gIH1cblxuICAvLyBQdWJsaWNcbiAgZ2V0V2lkdGgoKSB7XG4gICAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL1dpbmRvdy9pbm5lcldpZHRoI3VzYWdlX25vdGVzXG4gICAgY29uc3QgZG9jdW1lbnRXaWR0aCA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRXaWR0aDtcbiAgICByZXR1cm4gTWF0aC5hYnMod2luZG93LmlubmVyV2lkdGggLSBkb2N1bWVudFdpZHRoKTtcbiAgfVxuICBoaWRlKCkge1xuICAgIGNvbnN0IHdpZHRoID0gdGhpcy5nZXRXaWR0aCgpO1xuICAgIHRoaXMuX2Rpc2FibGVPdmVyRmxvdygpO1xuICAgIC8vIGdpdmUgcGFkZGluZyB0byBlbGVtZW50IHRvIGJhbGFuY2UgdGhlIGhpZGRlbiBzY3JvbGxiYXIgd2lkdGhcbiAgICB0aGlzLl9zZXRFbGVtZW50QXR0cmlidXRlcyh0aGlzLl9lbGVtZW50LCBQUk9QRVJUWV9QQURESU5HLCBjYWxjdWxhdGVkVmFsdWUgPT4gY2FsY3VsYXRlZFZhbHVlICsgd2lkdGgpO1xuICAgIC8vIHRyaWNrOiBXZSBhZGp1c3QgcG9zaXRpdmUgcGFkZGluZ1JpZ2h0IGFuZCBuZWdhdGl2ZSBtYXJnaW5SaWdodCB0byBzdGlja3ktdG9wIGVsZW1lbnRzIHRvIGtlZXAgc2hvd2luZyBmdWxsd2lkdGhcbiAgICB0aGlzLl9zZXRFbGVtZW50QXR0cmlidXRlcyhTRUxFQ1RPUl9GSVhFRF9DT05URU5ULCBQUk9QRVJUWV9QQURESU5HLCBjYWxjdWxhdGVkVmFsdWUgPT4gY2FsY3VsYXRlZFZhbHVlICsgd2lkdGgpO1xuICAgIHRoaXMuX3NldEVsZW1lbnRBdHRyaWJ1dGVzKFNFTEVDVE9SX1NUSUNLWV9DT05URU5ULCBQUk9QRVJUWV9NQVJHSU4sIGNhbGN1bGF0ZWRWYWx1ZSA9PiBjYWxjdWxhdGVkVmFsdWUgLSB3aWR0aCk7XG4gIH1cbiAgcmVzZXQoKSB7XG4gICAgdGhpcy5fcmVzZXRFbGVtZW50QXR0cmlidXRlcyh0aGlzLl9lbGVtZW50LCAnb3ZlcmZsb3cnKTtcbiAgICB0aGlzLl9yZXNldEVsZW1lbnRBdHRyaWJ1dGVzKHRoaXMuX2VsZW1lbnQsIFBST1BFUlRZX1BBRERJTkcpO1xuICAgIHRoaXMuX3Jlc2V0RWxlbWVudEF0dHJpYnV0ZXMoU0VMRUNUT1JfRklYRURfQ09OVEVOVCwgUFJPUEVSVFlfUEFERElORyk7XG4gICAgdGhpcy5fcmVzZXRFbGVtZW50QXR0cmlidXRlcyhTRUxFQ1RPUl9TVElDS1lfQ09OVEVOVCwgUFJPUEVSVFlfTUFSR0lOKTtcbiAgfVxuICBpc092ZXJmbG93aW5nKCkge1xuICAgIHJldHVybiB0aGlzLmdldFdpZHRoKCkgPiAwO1xuICB9XG5cbiAgLy8gUHJpdmF0ZVxuICBfZGlzYWJsZU92ZXJGbG93KCkge1xuICAgIHRoaXMuX3NhdmVJbml0aWFsQXR0cmlidXRlKHRoaXMuX2VsZW1lbnQsICdvdmVyZmxvdycpO1xuICAgIHRoaXMuX2VsZW1lbnQuc3R5bGUub3ZlcmZsb3cgPSAnaGlkZGVuJztcbiAgfVxuICBfc2V0RWxlbWVudEF0dHJpYnV0ZXMoc2VsZWN0b3IsIHN0eWxlUHJvcGVydHksIGNhbGxiYWNrKSB7XG4gICAgY29uc3Qgc2Nyb2xsYmFyV2lkdGggPSB0aGlzLmdldFdpZHRoKCk7XG4gICAgY29uc3QgbWFuaXB1bGF0aW9uQ2FsbEJhY2sgPSBlbGVtZW50ID0+IHtcbiAgICAgIGlmIChlbGVtZW50ICE9PSB0aGlzLl9lbGVtZW50ICYmIHdpbmRvdy5pbm5lcldpZHRoID4gZWxlbWVudC5jbGllbnRXaWR0aCArIHNjcm9sbGJhcldpZHRoKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMuX3NhdmVJbml0aWFsQXR0cmlidXRlKGVsZW1lbnQsIHN0eWxlUHJvcGVydHkpO1xuICAgICAgY29uc3QgY2FsY3VsYXRlZFZhbHVlID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUoZWxlbWVudCkuZ2V0UHJvcGVydHlWYWx1ZShzdHlsZVByb3BlcnR5KTtcbiAgICAgIGVsZW1lbnQuc3R5bGUuc2V0UHJvcGVydHkoc3R5bGVQcm9wZXJ0eSwgYCR7Y2FsbGJhY2soTnVtYmVyLnBhcnNlRmxvYXQoY2FsY3VsYXRlZFZhbHVlKSl9cHhgKTtcbiAgICB9O1xuICAgIHRoaXMuX2FwcGx5TWFuaXB1bGF0aW9uQ2FsbGJhY2soc2VsZWN0b3IsIG1hbmlwdWxhdGlvbkNhbGxCYWNrKTtcbiAgfVxuICBfc2F2ZUluaXRpYWxBdHRyaWJ1dGUoZWxlbWVudCwgc3R5bGVQcm9wZXJ0eSkge1xuICAgIGNvbnN0IGFjdHVhbFZhbHVlID0gZWxlbWVudC5zdHlsZS5nZXRQcm9wZXJ0eVZhbHVlKHN0eWxlUHJvcGVydHkpO1xuICAgIGlmIChhY3R1YWxWYWx1ZSkge1xuICAgICAgTWFuaXB1bGF0b3Iuc2V0RGF0YUF0dHJpYnV0ZShlbGVtZW50LCBzdHlsZVByb3BlcnR5LCBhY3R1YWxWYWx1ZSk7XG4gICAgfVxuICB9XG4gIF9yZXNldEVsZW1lbnRBdHRyaWJ1dGVzKHNlbGVjdG9yLCBzdHlsZVByb3BlcnR5KSB7XG4gICAgY29uc3QgbWFuaXB1bGF0aW9uQ2FsbEJhY2sgPSBlbGVtZW50ID0+IHtcbiAgICAgIGNvbnN0IHZhbHVlID0gTWFuaXB1bGF0b3IuZ2V0RGF0YUF0dHJpYnV0ZShlbGVtZW50LCBzdHlsZVByb3BlcnR5KTtcbiAgICAgIC8vIFdlIG9ubHkgd2FudCB0byByZW1vdmUgdGhlIHByb3BlcnR5IGlmIHRoZSB2YWx1ZSBpcyBgbnVsbGA7IHRoZSB2YWx1ZSBjYW4gYWxzbyBiZSB6ZXJvXG4gICAgICBpZiAodmFsdWUgPT09IG51bGwpIHtcbiAgICAgICAgZWxlbWVudC5zdHlsZS5yZW1vdmVQcm9wZXJ0eShzdHlsZVByb3BlcnR5KTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgTWFuaXB1bGF0b3IucmVtb3ZlRGF0YUF0dHJpYnV0ZShlbGVtZW50LCBzdHlsZVByb3BlcnR5KTtcbiAgICAgIGVsZW1lbnQuc3R5bGUuc2V0UHJvcGVydHkoc3R5bGVQcm9wZXJ0eSwgdmFsdWUpO1xuICAgIH07XG4gICAgdGhpcy5fYXBwbHlNYW5pcHVsYXRpb25DYWxsYmFjayhzZWxlY3RvciwgbWFuaXB1bGF0aW9uQ2FsbEJhY2spO1xuICB9XG4gIF9hcHBseU1hbmlwdWxhdGlvbkNhbGxiYWNrKHNlbGVjdG9yLCBjYWxsQmFjaykge1xuICAgIGlmIChpc0VsZW1lbnQoc2VsZWN0b3IpKSB7XG4gICAgICBjYWxsQmFjayhzZWxlY3Rvcik7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGZvciAoY29uc3Qgc2VsIG9mIFNlbGVjdG9yRW5naW5lLmZpbmQoc2VsZWN0b3IsIHRoaXMuX2VsZW1lbnQpKSB7XG4gICAgICBjYWxsQmFjayhzZWwpO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiBCb290c3RyYXAgbW9kYWwuanNcbiAqIExpY2Vuc2VkIHVuZGVyIE1JVCAoaHR0cHM6Ly9naXRodWIuY29tL3R3YnMvYm9vdHN0cmFwL2Jsb2IvbWFpbi9MSUNFTlNFKVxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqL1xuXG5cbi8qKlxuICogQ29uc3RhbnRzXG4gKi9cblxuY29uc3QgTkFNRSQ3ID0gJ21vZGFsJztcbmNvbnN0IERBVEFfS0VZJDQgPSAnYnMubW9kYWwnO1xuY29uc3QgRVZFTlRfS0VZJDQgPSBgLiR7REFUQV9LRVkkNH1gO1xuY29uc3QgREFUQV9BUElfS0VZJDIgPSAnLmRhdGEtYXBpJztcbmNvbnN0IEVTQ0FQRV9LRVkkMSA9ICdFc2NhcGUnO1xuY29uc3QgRVZFTlRfSElERSQ0ID0gYGhpZGUke0VWRU5UX0tFWSQ0fWA7XG5jb25zdCBFVkVOVF9ISURFX1BSRVZFTlRFRCQxID0gYGhpZGVQcmV2ZW50ZWQke0VWRU5UX0tFWSQ0fWA7XG5jb25zdCBFVkVOVF9ISURERU4kNCA9IGBoaWRkZW4ke0VWRU5UX0tFWSQ0fWA7XG5jb25zdCBFVkVOVF9TSE9XJDQgPSBgc2hvdyR7RVZFTlRfS0VZJDR9YDtcbmNvbnN0IEVWRU5UX1NIT1dOJDQgPSBgc2hvd24ke0VWRU5UX0tFWSQ0fWA7XG5jb25zdCBFVkVOVF9SRVNJWkUkMSA9IGByZXNpemUke0VWRU5UX0tFWSQ0fWA7XG5jb25zdCBFVkVOVF9DTElDS19ESVNNSVNTID0gYGNsaWNrLmRpc21pc3Mke0VWRU5UX0tFWSQ0fWA7XG5jb25zdCBFVkVOVF9NT1VTRURPV05fRElTTUlTUyA9IGBtb3VzZWRvd24uZGlzbWlzcyR7RVZFTlRfS0VZJDR9YDtcbmNvbnN0IEVWRU5UX0tFWURPV05fRElTTUlTUyQxID0gYGtleWRvd24uZGlzbWlzcyR7RVZFTlRfS0VZJDR9YDtcbmNvbnN0IEVWRU5UX0NMSUNLX0RBVEFfQVBJJDIgPSBgY2xpY2ske0VWRU5UX0tFWSQ0fSR7REFUQV9BUElfS0VZJDJ9YDtcbmNvbnN0IENMQVNTX05BTUVfT1BFTiA9ICdtb2RhbC1vcGVuJztcbmNvbnN0IENMQVNTX05BTUVfRkFERSQzID0gJ2ZhZGUnO1xuY29uc3QgQ0xBU1NfTkFNRV9TSE9XJDQgPSAnc2hvdyc7XG5jb25zdCBDTEFTU19OQU1FX1NUQVRJQyA9ICdtb2RhbC1zdGF0aWMnO1xuY29uc3QgT1BFTl9TRUxFQ1RPUiQxID0gJy5tb2RhbC5zaG93JztcbmNvbnN0IFNFTEVDVE9SX0RJQUxPRyA9ICcubW9kYWwtZGlhbG9nJztcbmNvbnN0IFNFTEVDVE9SX01PREFMX0JPRFkgPSAnLm1vZGFsLWJvZHknO1xuY29uc3QgU0VMRUNUT1JfREFUQV9UT0dHTEUkMiA9ICdbZGF0YS1icy10b2dnbGU9XCJtb2RhbFwiXSc7XG5jb25zdCBEZWZhdWx0JDYgPSB7XG4gIGJhY2tkcm9wOiB0cnVlLFxuICBmb2N1czogdHJ1ZSxcbiAga2V5Ym9hcmQ6IHRydWVcbn07XG5jb25zdCBEZWZhdWx0VHlwZSQ2ID0ge1xuICBiYWNrZHJvcDogJyhib29sZWFufHN0cmluZyknLFxuICBmb2N1czogJ2Jvb2xlYW4nLFxuICBrZXlib2FyZDogJ2Jvb2xlYW4nXG59O1xuXG4vKipcbiAqIENsYXNzIGRlZmluaXRpb25cbiAqL1xuXG5jbGFzcyBNb2RhbCBleHRlbmRzIEJhc2VDb21wb25lbnQge1xuICBjb25zdHJ1Y3RvcihlbGVtZW50LCBjb25maWcpIHtcbiAgICBzdXBlcihlbGVtZW50LCBjb25maWcpO1xuICAgIHRoaXMuX2RpYWxvZyA9IFNlbGVjdG9yRW5naW5lLmZpbmRPbmUoU0VMRUNUT1JfRElBTE9HLCB0aGlzLl9lbGVtZW50KTtcbiAgICB0aGlzLl9iYWNrZHJvcCA9IHRoaXMuX2luaXRpYWxpemVCYWNrRHJvcCgpO1xuICAgIHRoaXMuX2ZvY3VzdHJhcCA9IHRoaXMuX2luaXRpYWxpemVGb2N1c1RyYXAoKTtcbiAgICB0aGlzLl9pc1Nob3duID0gZmFsc2U7XG4gICAgdGhpcy5faXNUcmFuc2l0aW9uaW5nID0gZmFsc2U7XG4gICAgdGhpcy5fc2Nyb2xsQmFyID0gbmV3IFNjcm9sbEJhckhlbHBlcigpO1xuICAgIHRoaXMuX2FkZEV2ZW50TGlzdGVuZXJzKCk7XG4gIH1cblxuICAvLyBHZXR0ZXJzXG4gIHN0YXRpYyBnZXQgRGVmYXVsdCgpIHtcbiAgICByZXR1cm4gRGVmYXVsdCQ2O1xuICB9XG4gIHN0YXRpYyBnZXQgRGVmYXVsdFR5cGUoKSB7XG4gICAgcmV0dXJuIERlZmF1bHRUeXBlJDY7XG4gIH1cbiAgc3RhdGljIGdldCBOQU1FKCkge1xuICAgIHJldHVybiBOQU1FJDc7XG4gIH1cblxuICAvLyBQdWJsaWNcbiAgdG9nZ2xlKHJlbGF0ZWRUYXJnZXQpIHtcbiAgICByZXR1cm4gdGhpcy5faXNTaG93biA/IHRoaXMuaGlkZSgpIDogdGhpcy5zaG93KHJlbGF0ZWRUYXJnZXQpO1xuICB9XG4gIHNob3cocmVsYXRlZFRhcmdldCkge1xuICAgIGlmICh0aGlzLl9pc1Nob3duIHx8IHRoaXMuX2lzVHJhbnNpdGlvbmluZykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBzaG93RXZlbnQgPSBFdmVudEhhbmRsZXIudHJpZ2dlcih0aGlzLl9lbGVtZW50LCBFVkVOVF9TSE9XJDQsIHtcbiAgICAgIHJlbGF0ZWRUYXJnZXRcbiAgICB9KTtcbiAgICBpZiAoc2hvd0V2ZW50LmRlZmF1bHRQcmV2ZW50ZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5faXNTaG93biA9IHRydWU7XG4gICAgdGhpcy5faXNUcmFuc2l0aW9uaW5nID0gdHJ1ZTtcbiAgICB0aGlzLl9zY3JvbGxCYXIuaGlkZSgpO1xuICAgIGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LmFkZChDTEFTU19OQU1FX09QRU4pO1xuICAgIHRoaXMuX2FkanVzdERpYWxvZygpO1xuICAgIHRoaXMuX2JhY2tkcm9wLnNob3coKCkgPT4gdGhpcy5fc2hvd0VsZW1lbnQocmVsYXRlZFRhcmdldCkpO1xuICB9XG4gIGhpZGUoKSB7XG4gICAgaWYgKCF0aGlzLl9pc1Nob3duIHx8IHRoaXMuX2lzVHJhbnNpdGlvbmluZykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBoaWRlRXZlbnQgPSBFdmVudEhhbmRsZXIudHJpZ2dlcih0aGlzLl9lbGVtZW50LCBFVkVOVF9ISURFJDQpO1xuICAgIGlmIChoaWRlRXZlbnQuZGVmYXVsdFByZXZlbnRlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLl9pc1Nob3duID0gZmFsc2U7XG4gICAgdGhpcy5faXNUcmFuc2l0aW9uaW5nID0gdHJ1ZTtcbiAgICB0aGlzLl9mb2N1c3RyYXAuZGVhY3RpdmF0ZSgpO1xuICAgIHRoaXMuX2VsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZShDTEFTU19OQU1FX1NIT1ckNCk7XG4gICAgdGhpcy5fcXVldWVDYWxsYmFjaygoKSA9PiB0aGlzLl9oaWRlTW9kYWwoKSwgdGhpcy5fZWxlbWVudCwgdGhpcy5faXNBbmltYXRlZCgpKTtcbiAgfVxuICBkaXNwb3NlKCkge1xuICAgIEV2ZW50SGFuZGxlci5vZmYod2luZG93LCBFVkVOVF9LRVkkNCk7XG4gICAgRXZlbnRIYW5kbGVyLm9mZih0aGlzLl9kaWFsb2csIEVWRU5UX0tFWSQ0KTtcbiAgICB0aGlzLl9iYWNrZHJvcC5kaXNwb3NlKCk7XG4gICAgdGhpcy5fZm9jdXN0cmFwLmRlYWN0aXZhdGUoKTtcbiAgICBzdXBlci5kaXNwb3NlKCk7XG4gIH1cbiAgaGFuZGxlVXBkYXRlKCkge1xuICAgIHRoaXMuX2FkanVzdERpYWxvZygpO1xuICB9XG5cbiAgLy8gUHJpdmF0ZVxuICBfaW5pdGlhbGl6ZUJhY2tEcm9wKCkge1xuICAgIHJldHVybiBuZXcgQmFja2Ryb3Aoe1xuICAgICAgaXNWaXNpYmxlOiBCb29sZWFuKHRoaXMuX2NvbmZpZy5iYWNrZHJvcCksXG4gICAgICAvLyAnc3RhdGljJyBvcHRpb24gd2lsbCBiZSB0cmFuc2xhdGVkIHRvIHRydWUsIGFuZCBib29sZWFucyB3aWxsIGtlZXAgdGhlaXIgdmFsdWUsXG4gICAgICBpc0FuaW1hdGVkOiB0aGlzLl9pc0FuaW1hdGVkKClcbiAgICB9KTtcbiAgfVxuICBfaW5pdGlhbGl6ZUZvY3VzVHJhcCgpIHtcbiAgICByZXR1cm4gbmV3IEZvY3VzVHJhcCh7XG4gICAgICB0cmFwRWxlbWVudDogdGhpcy5fZWxlbWVudFxuICAgIH0pO1xuICB9XG4gIF9zaG93RWxlbWVudChyZWxhdGVkVGFyZ2V0KSB7XG4gICAgLy8gdHJ5IHRvIGFwcGVuZCBkeW5hbWljIG1vZGFsXG4gICAgaWYgKCFkb2N1bWVudC5ib2R5LmNvbnRhaW5zKHRoaXMuX2VsZW1lbnQpKSB7XG4gICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZCh0aGlzLl9lbGVtZW50KTtcbiAgICB9XG4gICAgdGhpcy5fZWxlbWVudC5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcbiAgICB0aGlzLl9lbGVtZW50LnJlbW92ZUF0dHJpYnV0ZSgnYXJpYS1oaWRkZW4nKTtcbiAgICB0aGlzLl9lbGVtZW50LnNldEF0dHJpYnV0ZSgnYXJpYS1tb2RhbCcsIHRydWUpO1xuICAgIHRoaXMuX2VsZW1lbnQuc2V0QXR0cmlidXRlKCdyb2xlJywgJ2RpYWxvZycpO1xuICAgIHRoaXMuX2VsZW1lbnQuc2Nyb2xsVG9wID0gMDtcbiAgICBjb25zdCBtb2RhbEJvZHkgPSBTZWxlY3RvckVuZ2luZS5maW5kT25lKFNFTEVDVE9SX01PREFMX0JPRFksIHRoaXMuX2RpYWxvZyk7XG4gICAgaWYgKG1vZGFsQm9keSkge1xuICAgICAgbW9kYWxCb2R5LnNjcm9sbFRvcCA9IDA7XG4gICAgfVxuICAgIHJlZmxvdyh0aGlzLl9lbGVtZW50KTtcbiAgICB0aGlzLl9lbGVtZW50LmNsYXNzTGlzdC5hZGQoQ0xBU1NfTkFNRV9TSE9XJDQpO1xuICAgIGNvbnN0IHRyYW5zaXRpb25Db21wbGV0ZSA9ICgpID0+IHtcbiAgICAgIGlmICh0aGlzLl9jb25maWcuZm9jdXMpIHtcbiAgICAgICAgdGhpcy5fZm9jdXN0cmFwLmFjdGl2YXRlKCk7XG4gICAgICB9XG4gICAgICB0aGlzLl9pc1RyYW5zaXRpb25pbmcgPSBmYWxzZTtcbiAgICAgIEV2ZW50SGFuZGxlci50cmlnZ2VyKHRoaXMuX2VsZW1lbnQsIEVWRU5UX1NIT1dOJDQsIHtcbiAgICAgICAgcmVsYXRlZFRhcmdldFxuICAgICAgfSk7XG4gICAgfTtcbiAgICB0aGlzLl9xdWV1ZUNhbGxiYWNrKHRyYW5zaXRpb25Db21wbGV0ZSwgdGhpcy5fZGlhbG9nLCB0aGlzLl9pc0FuaW1hdGVkKCkpO1xuICB9XG4gIF9hZGRFdmVudExpc3RlbmVycygpIHtcbiAgICBFdmVudEhhbmRsZXIub24odGhpcy5fZWxlbWVudCwgRVZFTlRfS0VZRE9XTl9ESVNNSVNTJDEsIGV2ZW50ID0+IHtcbiAgICAgIGlmIChldmVudC5rZXkgIT09IEVTQ0FQRV9LRVkkMSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5fY29uZmlnLmtleWJvYXJkKSB7XG4gICAgICAgIHRoaXMuaGlkZSgpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aGlzLl90cmlnZ2VyQmFja2Ryb3BUcmFuc2l0aW9uKCk7XG4gICAgfSk7XG4gICAgRXZlbnRIYW5kbGVyLm9uKHdpbmRvdywgRVZFTlRfUkVTSVpFJDEsICgpID0+IHtcbiAgICAgIGlmICh0aGlzLl9pc1Nob3duICYmICF0aGlzLl9pc1RyYW5zaXRpb25pbmcpIHtcbiAgICAgICAgdGhpcy5fYWRqdXN0RGlhbG9nKCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgRXZlbnRIYW5kbGVyLm9uKHRoaXMuX2VsZW1lbnQsIEVWRU5UX01PVVNFRE9XTl9ESVNNSVNTLCBldmVudCA9PiB7XG4gICAgICAvLyBhIGJhZCB0cmljayB0byBzZWdyZWdhdGUgY2xpY2tzIHRoYXQgbWF5IHN0YXJ0IGluc2lkZSBkaWFsb2cgYnV0IGVuZCBvdXRzaWRlLCBhbmQgYXZvaWQgbGlzdGVuIHRvIHNjcm9sbGJhciBjbGlja3NcbiAgICAgIEV2ZW50SGFuZGxlci5vbmUodGhpcy5fZWxlbWVudCwgRVZFTlRfQ0xJQ0tfRElTTUlTUywgZXZlbnQyID0+IHtcbiAgICAgICAgaWYgKHRoaXMuX2VsZW1lbnQgIT09IGV2ZW50LnRhcmdldCB8fCB0aGlzLl9lbGVtZW50ICE9PSBldmVudDIudGFyZ2V0KSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLl9jb25maWcuYmFja2Ryb3AgPT09ICdzdGF0aWMnKSB7XG4gICAgICAgICAgdGhpcy5fdHJpZ2dlckJhY2tkcm9wVHJhbnNpdGlvbigpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5fY29uZmlnLmJhY2tkcm9wKSB7XG4gICAgICAgICAgdGhpcy5oaWRlKCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG4gIF9oaWRlTW9kYWwoKSB7XG4gICAgdGhpcy5fZWxlbWVudC5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgIHRoaXMuX2VsZW1lbnQuc2V0QXR0cmlidXRlKCdhcmlhLWhpZGRlbicsIHRydWUpO1xuICAgIHRoaXMuX2VsZW1lbnQucmVtb3ZlQXR0cmlidXRlKCdhcmlhLW1vZGFsJyk7XG4gICAgdGhpcy5fZWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUoJ3JvbGUnKTtcbiAgICB0aGlzLl9pc1RyYW5zaXRpb25pbmcgPSBmYWxzZTtcbiAgICB0aGlzLl9iYWNrZHJvcC5oaWRlKCgpID0+IHtcbiAgICAgIGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LnJlbW92ZShDTEFTU19OQU1FX09QRU4pO1xuICAgICAgdGhpcy5fcmVzZXRBZGp1c3RtZW50cygpO1xuICAgICAgdGhpcy5fc2Nyb2xsQmFyLnJlc2V0KCk7XG4gICAgICBFdmVudEhhbmRsZXIudHJpZ2dlcih0aGlzLl9lbGVtZW50LCBFVkVOVF9ISURERU4kNCk7XG4gICAgfSk7XG4gIH1cbiAgX2lzQW5pbWF0ZWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2VsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKENMQVNTX05BTUVfRkFERSQzKTtcbiAgfVxuICBfdHJpZ2dlckJhY2tkcm9wVHJhbnNpdGlvbigpIHtcbiAgICBjb25zdCBoaWRlRXZlbnQgPSBFdmVudEhhbmRsZXIudHJpZ2dlcih0aGlzLl9lbGVtZW50LCBFVkVOVF9ISURFX1BSRVZFTlRFRCQxKTtcbiAgICBpZiAoaGlkZUV2ZW50LmRlZmF1bHRQcmV2ZW50ZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgaXNNb2RhbE92ZXJmbG93aW5nID0gdGhpcy5fZWxlbWVudC5zY3JvbGxIZWlnaHQgPiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50SGVpZ2h0O1xuICAgIGNvbnN0IGluaXRpYWxPdmVyZmxvd1kgPSB0aGlzLl9lbGVtZW50LnN0eWxlLm92ZXJmbG93WTtcbiAgICAvLyByZXR1cm4gaWYgdGhlIGZvbGxvd2luZyBiYWNrZ3JvdW5kIHRyYW5zaXRpb24gaGFzbid0IHlldCBjb21wbGV0ZWRcbiAgICBpZiAoaW5pdGlhbE92ZXJmbG93WSA9PT0gJ2hpZGRlbicgfHwgdGhpcy5fZWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoQ0xBU1NfTkFNRV9TVEFUSUMpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICghaXNNb2RhbE92ZXJmbG93aW5nKSB7XG4gICAgICB0aGlzLl9lbGVtZW50LnN0eWxlLm92ZXJmbG93WSA9ICdoaWRkZW4nO1xuICAgIH1cbiAgICB0aGlzLl9lbGVtZW50LmNsYXNzTGlzdC5hZGQoQ0xBU1NfTkFNRV9TVEFUSUMpO1xuICAgIHRoaXMuX3F1ZXVlQ2FsbGJhY2soKCkgPT4ge1xuICAgICAgdGhpcy5fZWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKENMQVNTX05BTUVfU1RBVElDKTtcbiAgICAgIHRoaXMuX3F1ZXVlQ2FsbGJhY2soKCkgPT4ge1xuICAgICAgICB0aGlzLl9lbGVtZW50LnN0eWxlLm92ZXJmbG93WSA9IGluaXRpYWxPdmVyZmxvd1k7XG4gICAgICB9LCB0aGlzLl9kaWFsb2cpO1xuICAgIH0sIHRoaXMuX2RpYWxvZyk7XG4gICAgdGhpcy5fZWxlbWVudC5mb2N1cygpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBmb2xsb3dpbmcgbWV0aG9kcyBhcmUgdXNlZCB0byBoYW5kbGUgb3ZlcmZsb3dpbmcgbW9kYWxzXG4gICAqL1xuXG4gIF9hZGp1c3REaWFsb2coKSB7XG4gICAgY29uc3QgaXNNb2RhbE92ZXJmbG93aW5nID0gdGhpcy5fZWxlbWVudC5zY3JvbGxIZWlnaHQgPiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50SGVpZ2h0O1xuICAgIGNvbnN0IHNjcm9sbGJhcldpZHRoID0gdGhpcy5fc2Nyb2xsQmFyLmdldFdpZHRoKCk7XG4gICAgY29uc3QgaXNCb2R5T3ZlcmZsb3dpbmcgPSBzY3JvbGxiYXJXaWR0aCA+IDA7XG4gICAgaWYgKGlzQm9keU92ZXJmbG93aW5nICYmICFpc01vZGFsT3ZlcmZsb3dpbmcpIHtcbiAgICAgIGNvbnN0IHByb3BlcnR5ID0gaXNSVEwoKSA/ICdwYWRkaW5nTGVmdCcgOiAncGFkZGluZ1JpZ2h0JztcbiAgICAgIHRoaXMuX2VsZW1lbnQuc3R5bGVbcHJvcGVydHldID0gYCR7c2Nyb2xsYmFyV2lkdGh9cHhgO1xuICAgIH1cbiAgICBpZiAoIWlzQm9keU92ZXJmbG93aW5nICYmIGlzTW9kYWxPdmVyZmxvd2luZykge1xuICAgICAgY29uc3QgcHJvcGVydHkgPSBpc1JUTCgpID8gJ3BhZGRpbmdSaWdodCcgOiAncGFkZGluZ0xlZnQnO1xuICAgICAgdGhpcy5fZWxlbWVudC5zdHlsZVtwcm9wZXJ0eV0gPSBgJHtzY3JvbGxiYXJXaWR0aH1weGA7XG4gICAgfVxuICB9XG4gIF9yZXNldEFkanVzdG1lbnRzKCkge1xuICAgIHRoaXMuX2VsZW1lbnQuc3R5bGUucGFkZGluZ0xlZnQgPSAnJztcbiAgICB0aGlzLl9lbGVtZW50LnN0eWxlLnBhZGRpbmdSaWdodCA9ICcnO1xuICB9XG5cbiAgLy8gU3RhdGljXG4gIHN0YXRpYyBqUXVlcnlJbnRlcmZhY2UoY29uZmlnLCByZWxhdGVkVGFyZ2V0KSB7XG4gICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBkYXRhID0gTW9kYWwuZ2V0T3JDcmVhdGVJbnN0YW5jZSh0aGlzLCBjb25maWcpO1xuICAgICAgaWYgKHR5cGVvZiBjb25maWcgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgZGF0YVtjb25maWddID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBObyBtZXRob2QgbmFtZWQgXCIke2NvbmZpZ31cImApO1xuICAgICAgfVxuICAgICAgZGF0YVtjb25maWddKHJlbGF0ZWRUYXJnZXQpO1xuICAgIH0pO1xuICB9XG59XG5cbi8qKlxuICogRGF0YSBBUEkgaW1wbGVtZW50YXRpb25cbiAqL1xuXG5FdmVudEhhbmRsZXIub24oZG9jdW1lbnQsIEVWRU5UX0NMSUNLX0RBVEFfQVBJJDIsIFNFTEVDVE9SX0RBVEFfVE9HR0xFJDIsIGZ1bmN0aW9uIChldmVudCkge1xuICBjb25zdCB0YXJnZXQgPSBTZWxlY3RvckVuZ2luZS5nZXRFbGVtZW50RnJvbVNlbGVjdG9yKHRoaXMpO1xuICBpZiAoWydBJywgJ0FSRUEnXS5pbmNsdWRlcyh0aGlzLnRhZ05hbWUpKSB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgfVxuICBFdmVudEhhbmRsZXIub25lKHRhcmdldCwgRVZFTlRfU0hPVyQ0LCBzaG93RXZlbnQgPT4ge1xuICAgIGlmIChzaG93RXZlbnQuZGVmYXVsdFByZXZlbnRlZCkge1xuICAgICAgLy8gb25seSByZWdpc3RlciBmb2N1cyByZXN0b3JlciBpZiBtb2RhbCB3aWxsIGFjdHVhbGx5IGdldCBzaG93blxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBFdmVudEhhbmRsZXIub25lKHRhcmdldCwgRVZFTlRfSElEREVOJDQsICgpID0+IHtcbiAgICAgIGlmIChpc1Zpc2libGUodGhpcykpIHtcbiAgICAgICAgdGhpcy5mb2N1cygpO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcblxuICAvLyBhdm9pZCBjb25mbGljdCB3aGVuIGNsaWNraW5nIG1vZGFsIHRvZ2dsZXIgd2hpbGUgYW5vdGhlciBvbmUgaXMgb3BlblxuICBjb25zdCBhbHJlYWR5T3BlbiA9IFNlbGVjdG9yRW5naW5lLmZpbmRPbmUoT1BFTl9TRUxFQ1RPUiQxKTtcbiAgaWYgKGFscmVhZHlPcGVuKSB7XG4gICAgTW9kYWwuZ2V0SW5zdGFuY2UoYWxyZWFkeU9wZW4pLmhpZGUoKTtcbiAgfVxuICBjb25zdCBkYXRhID0gTW9kYWwuZ2V0T3JDcmVhdGVJbnN0YW5jZSh0YXJnZXQpO1xuICBkYXRhLnRvZ2dsZSh0aGlzKTtcbn0pO1xuZW5hYmxlRGlzbWlzc1RyaWdnZXIoTW9kYWwpO1xuXG4vKipcbiAqIGpRdWVyeVxuICovXG5cbmRlZmluZUpRdWVyeVBsdWdpbihNb2RhbCk7XG5cbi8qKlxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIEJvb3RzdHJhcCBvZmZjYW52YXMuanNcbiAqIExpY2Vuc2VkIHVuZGVyIE1JVCAoaHR0cHM6Ly9naXRodWIuY29tL3R3YnMvYm9vdHN0cmFwL2Jsb2IvbWFpbi9MSUNFTlNFKVxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqL1xuXG5cbi8qKlxuICogQ29uc3RhbnRzXG4gKi9cblxuY29uc3QgTkFNRSQ2ID0gJ29mZmNhbnZhcyc7XG5jb25zdCBEQVRBX0tFWSQzID0gJ2JzLm9mZmNhbnZhcyc7XG5jb25zdCBFVkVOVF9LRVkkMyA9IGAuJHtEQVRBX0tFWSQzfWA7XG5jb25zdCBEQVRBX0FQSV9LRVkkMSA9ICcuZGF0YS1hcGknO1xuY29uc3QgRVZFTlRfTE9BRF9EQVRBX0FQSSQyID0gYGxvYWQke0VWRU5UX0tFWSQzfSR7REFUQV9BUElfS0VZJDF9YDtcbmNvbnN0IEVTQ0FQRV9LRVkgPSAnRXNjYXBlJztcbmNvbnN0IENMQVNTX05BTUVfU0hPVyQzID0gJ3Nob3cnO1xuY29uc3QgQ0xBU1NfTkFNRV9TSE9XSU5HJDEgPSAnc2hvd2luZyc7XG5jb25zdCBDTEFTU19OQU1FX0hJRElORyA9ICdoaWRpbmcnO1xuY29uc3QgQ0xBU1NfTkFNRV9CQUNLRFJPUCA9ICdvZmZjYW52YXMtYmFja2Ryb3AnO1xuY29uc3QgT1BFTl9TRUxFQ1RPUiA9ICcub2ZmY2FudmFzLnNob3cnO1xuY29uc3QgRVZFTlRfU0hPVyQzID0gYHNob3cke0VWRU5UX0tFWSQzfWA7XG5jb25zdCBFVkVOVF9TSE9XTiQzID0gYHNob3duJHtFVkVOVF9LRVkkM31gO1xuY29uc3QgRVZFTlRfSElERSQzID0gYGhpZGUke0VWRU5UX0tFWSQzfWA7XG5jb25zdCBFVkVOVF9ISURFX1BSRVZFTlRFRCA9IGBoaWRlUHJldmVudGVkJHtFVkVOVF9LRVkkM31gO1xuY29uc3QgRVZFTlRfSElEREVOJDMgPSBgaGlkZGVuJHtFVkVOVF9LRVkkM31gO1xuY29uc3QgRVZFTlRfUkVTSVpFID0gYHJlc2l6ZSR7RVZFTlRfS0VZJDN9YDtcbmNvbnN0IEVWRU5UX0NMSUNLX0RBVEFfQVBJJDEgPSBgY2xpY2ske0VWRU5UX0tFWSQzfSR7REFUQV9BUElfS0VZJDF9YDtcbmNvbnN0IEVWRU5UX0tFWURPV05fRElTTUlTUyA9IGBrZXlkb3duLmRpc21pc3Mke0VWRU5UX0tFWSQzfWA7XG5jb25zdCBTRUxFQ1RPUl9EQVRBX1RPR0dMRSQxID0gJ1tkYXRhLWJzLXRvZ2dsZT1cIm9mZmNhbnZhc1wiXSc7XG5jb25zdCBEZWZhdWx0JDUgPSB7XG4gIGJhY2tkcm9wOiB0cnVlLFxuICBrZXlib2FyZDogdHJ1ZSxcbiAgc2Nyb2xsOiBmYWxzZVxufTtcbmNvbnN0IERlZmF1bHRUeXBlJDUgPSB7XG4gIGJhY2tkcm9wOiAnKGJvb2xlYW58c3RyaW5nKScsXG4gIGtleWJvYXJkOiAnYm9vbGVhbicsXG4gIHNjcm9sbDogJ2Jvb2xlYW4nXG59O1xuXG4vKipcbiAqIENsYXNzIGRlZmluaXRpb25cbiAqL1xuXG5jbGFzcyBPZmZjYW52YXMgZXh0ZW5kcyBCYXNlQ29tcG9uZW50IHtcbiAgY29uc3RydWN0b3IoZWxlbWVudCwgY29uZmlnKSB7XG4gICAgc3VwZXIoZWxlbWVudCwgY29uZmlnKTtcbiAgICB0aGlzLl9pc1Nob3duID0gZmFsc2U7XG4gICAgdGhpcy5fYmFja2Ryb3AgPSB0aGlzLl9pbml0aWFsaXplQmFja0Ryb3AoKTtcbiAgICB0aGlzLl9mb2N1c3RyYXAgPSB0aGlzLl9pbml0aWFsaXplRm9jdXNUcmFwKCk7XG4gICAgdGhpcy5fYWRkRXZlbnRMaXN0ZW5lcnMoKTtcbiAgfVxuXG4gIC8vIEdldHRlcnNcbiAgc3RhdGljIGdldCBEZWZhdWx0KCkge1xuICAgIHJldHVybiBEZWZhdWx0JDU7XG4gIH1cbiAgc3RhdGljIGdldCBEZWZhdWx0VHlwZSgpIHtcbiAgICByZXR1cm4gRGVmYXVsdFR5cGUkNTtcbiAgfVxuICBzdGF0aWMgZ2V0IE5BTUUoKSB7XG4gICAgcmV0dXJuIE5BTUUkNjtcbiAgfVxuXG4gIC8vIFB1YmxpY1xuICB0b2dnbGUocmVsYXRlZFRhcmdldCkge1xuICAgIHJldHVybiB0aGlzLl9pc1Nob3duID8gdGhpcy5oaWRlKCkgOiB0aGlzLnNob3cocmVsYXRlZFRhcmdldCk7XG4gIH1cbiAgc2hvdyhyZWxhdGVkVGFyZ2V0KSB7XG4gICAgaWYgKHRoaXMuX2lzU2hvd24pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3Qgc2hvd0V2ZW50ID0gRXZlbnRIYW5kbGVyLnRyaWdnZXIodGhpcy5fZWxlbWVudCwgRVZFTlRfU0hPVyQzLCB7XG4gICAgICByZWxhdGVkVGFyZ2V0XG4gICAgfSk7XG4gICAgaWYgKHNob3dFdmVudC5kZWZhdWx0UHJldmVudGVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuX2lzU2hvd24gPSB0cnVlO1xuICAgIHRoaXMuX2JhY2tkcm9wLnNob3coKTtcbiAgICBpZiAoIXRoaXMuX2NvbmZpZy5zY3JvbGwpIHtcbiAgICAgIG5ldyBTY3JvbGxCYXJIZWxwZXIoKS5oaWRlKCk7XG4gICAgfVxuICAgIHRoaXMuX2VsZW1lbnQuc2V0QXR0cmlidXRlKCdhcmlhLW1vZGFsJywgdHJ1ZSk7XG4gICAgdGhpcy5fZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ3JvbGUnLCAnZGlhbG9nJyk7XG4gICAgdGhpcy5fZWxlbWVudC5jbGFzc0xpc3QuYWRkKENMQVNTX05BTUVfU0hPV0lORyQxKTtcbiAgICBjb25zdCBjb21wbGV0ZUNhbGxCYWNrID0gKCkgPT4ge1xuICAgICAgaWYgKCF0aGlzLl9jb25maWcuc2Nyb2xsIHx8IHRoaXMuX2NvbmZpZy5iYWNrZHJvcCkge1xuICAgICAgICB0aGlzLl9mb2N1c3RyYXAuYWN0aXZhdGUoKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuX2VsZW1lbnQuY2xhc3NMaXN0LmFkZChDTEFTU19OQU1FX1NIT1ckMyk7XG4gICAgICB0aGlzLl9lbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoQ0xBU1NfTkFNRV9TSE9XSU5HJDEpO1xuICAgICAgRXZlbnRIYW5kbGVyLnRyaWdnZXIodGhpcy5fZWxlbWVudCwgRVZFTlRfU0hPV04kMywge1xuICAgICAgICByZWxhdGVkVGFyZ2V0XG4gICAgICB9KTtcbiAgICB9O1xuICAgIHRoaXMuX3F1ZXVlQ2FsbGJhY2soY29tcGxldGVDYWxsQmFjaywgdGhpcy5fZWxlbWVudCwgdHJ1ZSk7XG4gIH1cbiAgaGlkZSgpIHtcbiAgICBpZiAoIXRoaXMuX2lzU2hvd24pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgaGlkZUV2ZW50ID0gRXZlbnRIYW5kbGVyLnRyaWdnZXIodGhpcy5fZWxlbWVudCwgRVZFTlRfSElERSQzKTtcbiAgICBpZiAoaGlkZUV2ZW50LmRlZmF1bHRQcmV2ZW50ZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5fZm9jdXN0cmFwLmRlYWN0aXZhdGUoKTtcbiAgICB0aGlzLl9lbGVtZW50LmJsdXIoKTtcbiAgICB0aGlzLl9pc1Nob3duID0gZmFsc2U7XG4gICAgdGhpcy5fZWxlbWVudC5jbGFzc0xpc3QuYWRkKENMQVNTX05BTUVfSElESU5HKTtcbiAgICB0aGlzLl9iYWNrZHJvcC5oaWRlKCk7XG4gICAgY29uc3QgY29tcGxldGVDYWxsYmFjayA9ICgpID0+IHtcbiAgICAgIHRoaXMuX2VsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZShDTEFTU19OQU1FX1NIT1ckMywgQ0xBU1NfTkFNRV9ISURJTkcpO1xuICAgICAgdGhpcy5fZWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUoJ2FyaWEtbW9kYWwnKTtcbiAgICAgIHRoaXMuX2VsZW1lbnQucmVtb3ZlQXR0cmlidXRlKCdyb2xlJyk7XG4gICAgICBpZiAoIXRoaXMuX2NvbmZpZy5zY3JvbGwpIHtcbiAgICAgICAgbmV3IFNjcm9sbEJhckhlbHBlcigpLnJlc2V0KCk7XG4gICAgICB9XG4gICAgICBFdmVudEhhbmRsZXIudHJpZ2dlcih0aGlzLl9lbGVtZW50LCBFVkVOVF9ISURERU4kMyk7XG4gICAgfTtcbiAgICB0aGlzLl9xdWV1ZUNhbGxiYWNrKGNvbXBsZXRlQ2FsbGJhY2ssIHRoaXMuX2VsZW1lbnQsIHRydWUpO1xuICB9XG4gIGRpc3Bvc2UoKSB7XG4gICAgdGhpcy5fYmFja2Ryb3AuZGlzcG9zZSgpO1xuICAgIHRoaXMuX2ZvY3VzdHJhcC5kZWFjdGl2YXRlKCk7XG4gICAgc3VwZXIuZGlzcG9zZSgpO1xuICB9XG5cbiAgLy8gUHJpdmF0ZVxuICBfaW5pdGlhbGl6ZUJhY2tEcm9wKCkge1xuICAgIGNvbnN0IGNsaWNrQ2FsbGJhY2sgPSAoKSA9PiB7XG4gICAgICBpZiAodGhpcy5fY29uZmlnLmJhY2tkcm9wID09PSAnc3RhdGljJykge1xuICAgICAgICBFdmVudEhhbmRsZXIudHJpZ2dlcih0aGlzLl9lbGVtZW50LCBFVkVOVF9ISURFX1BSRVZFTlRFRCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMuaGlkZSgpO1xuICAgIH07XG5cbiAgICAvLyAnc3RhdGljJyBvcHRpb24gd2lsbCBiZSB0cmFuc2xhdGVkIHRvIHRydWUsIGFuZCBib29sZWFucyB3aWxsIGtlZXAgdGhlaXIgdmFsdWVcbiAgICBjb25zdCBpc1Zpc2libGUgPSBCb29sZWFuKHRoaXMuX2NvbmZpZy5iYWNrZHJvcCk7XG4gICAgcmV0dXJuIG5ldyBCYWNrZHJvcCh7XG4gICAgICBjbGFzc05hbWU6IENMQVNTX05BTUVfQkFDS0RST1AsXG4gICAgICBpc1Zpc2libGUsXG4gICAgICBpc0FuaW1hdGVkOiB0cnVlLFxuICAgICAgcm9vdEVsZW1lbnQ6IHRoaXMuX2VsZW1lbnQucGFyZW50Tm9kZSxcbiAgICAgIGNsaWNrQ2FsbGJhY2s6IGlzVmlzaWJsZSA/IGNsaWNrQ2FsbGJhY2sgOiBudWxsXG4gICAgfSk7XG4gIH1cbiAgX2luaXRpYWxpemVGb2N1c1RyYXAoKSB7XG4gICAgcmV0dXJuIG5ldyBGb2N1c1RyYXAoe1xuICAgICAgdHJhcEVsZW1lbnQ6IHRoaXMuX2VsZW1lbnRcbiAgICB9KTtcbiAgfVxuICBfYWRkRXZlbnRMaXN0ZW5lcnMoKSB7XG4gICAgRXZlbnRIYW5kbGVyLm9uKHRoaXMuX2VsZW1lbnQsIEVWRU5UX0tFWURPV05fRElTTUlTUywgZXZlbnQgPT4ge1xuICAgICAgaWYgKGV2ZW50LmtleSAhPT0gRVNDQVBFX0tFWSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5fY29uZmlnLmtleWJvYXJkKSB7XG4gICAgICAgIHRoaXMuaGlkZSgpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBFdmVudEhhbmRsZXIudHJpZ2dlcih0aGlzLl9lbGVtZW50LCBFVkVOVF9ISURFX1BSRVZFTlRFRCk7XG4gICAgfSk7XG4gIH1cblxuICAvLyBTdGF0aWNcbiAgc3RhdGljIGpRdWVyeUludGVyZmFjZShjb25maWcpIHtcbiAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGRhdGEgPSBPZmZjYW52YXMuZ2V0T3JDcmVhdGVJbnN0YW5jZSh0aGlzLCBjb25maWcpO1xuICAgICAgaWYgKHR5cGVvZiBjb25maWcgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmIChkYXRhW2NvbmZpZ10gPT09IHVuZGVmaW5lZCB8fCBjb25maWcuc3RhcnRzV2l0aCgnXycpIHx8IGNvbmZpZyA9PT0gJ2NvbnN0cnVjdG9yJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBObyBtZXRob2QgbmFtZWQgXCIke2NvbmZpZ31cImApO1xuICAgICAgfVxuICAgICAgZGF0YVtjb25maWddKHRoaXMpO1xuICAgIH0pO1xuICB9XG59XG5cbi8qKlxuICogRGF0YSBBUEkgaW1wbGVtZW50YXRpb25cbiAqL1xuXG5FdmVudEhhbmRsZXIub24oZG9jdW1lbnQsIEVWRU5UX0NMSUNLX0RBVEFfQVBJJDEsIFNFTEVDVE9SX0RBVEFfVE9HR0xFJDEsIGZ1bmN0aW9uIChldmVudCkge1xuICBjb25zdCB0YXJnZXQgPSBTZWxlY3RvckVuZ2luZS5nZXRFbGVtZW50RnJvbVNlbGVjdG9yKHRoaXMpO1xuICBpZiAoWydBJywgJ0FSRUEnXS5pbmNsdWRlcyh0aGlzLnRhZ05hbWUpKSB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgfVxuICBpZiAoaXNEaXNhYmxlZCh0aGlzKSkge1xuICAgIHJldHVybjtcbiAgfVxuICBFdmVudEhhbmRsZXIub25lKHRhcmdldCwgRVZFTlRfSElEREVOJDMsICgpID0+IHtcbiAgICAvLyBmb2N1cyBvbiB0cmlnZ2VyIHdoZW4gaXQgaXMgY2xvc2VkXG4gICAgaWYgKGlzVmlzaWJsZSh0aGlzKSkge1xuICAgICAgdGhpcy5mb2N1cygpO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gYXZvaWQgY29uZmxpY3Qgd2hlbiBjbGlja2luZyBhIHRvZ2dsZXIgb2YgYW4gb2ZmY2FudmFzLCB3aGlsZSBhbm90aGVyIGlzIG9wZW5cbiAgY29uc3QgYWxyZWFkeU9wZW4gPSBTZWxlY3RvckVuZ2luZS5maW5kT25lKE9QRU5fU0VMRUNUT1IpO1xuICBpZiAoYWxyZWFkeU9wZW4gJiYgYWxyZWFkeU9wZW4gIT09IHRhcmdldCkge1xuICAgIE9mZmNhbnZhcy5nZXRJbnN0YW5jZShhbHJlYWR5T3BlbikuaGlkZSgpO1xuICB9XG4gIGNvbnN0IGRhdGEgPSBPZmZjYW52YXMuZ2V0T3JDcmVhdGVJbnN0YW5jZSh0YXJnZXQpO1xuICBkYXRhLnRvZ2dsZSh0aGlzKTtcbn0pO1xuRXZlbnRIYW5kbGVyLm9uKHdpbmRvdywgRVZFTlRfTE9BRF9EQVRBX0FQSSQyLCAoKSA9PiB7XG4gIGZvciAoY29uc3Qgc2VsZWN0b3Igb2YgU2VsZWN0b3JFbmdpbmUuZmluZChPUEVOX1NFTEVDVE9SKSkge1xuICAgIE9mZmNhbnZhcy5nZXRPckNyZWF0ZUluc3RhbmNlKHNlbGVjdG9yKS5zaG93KCk7XG4gIH1cbn0pO1xuRXZlbnRIYW5kbGVyLm9uKHdpbmRvdywgRVZFTlRfUkVTSVpFLCAoKSA9PiB7XG4gIGZvciAoY29uc3QgZWxlbWVudCBvZiBTZWxlY3RvckVuZ2luZS5maW5kKCdbYXJpYS1tb2RhbF1bY2xhc3MqPXNob3ddW2NsYXNzKj1vZmZjYW52YXMtXScpKSB7XG4gICAgaWYgKGdldENvbXB1dGVkU3R5bGUoZWxlbWVudCkucG9zaXRpb24gIT09ICdmaXhlZCcpIHtcbiAgICAgIE9mZmNhbnZhcy5nZXRPckNyZWF0ZUluc3RhbmNlKGVsZW1lbnQpLmhpZGUoKTtcbiAgICB9XG4gIH1cbn0pO1xuZW5hYmxlRGlzbWlzc1RyaWdnZXIoT2ZmY2FudmFzKTtcblxuLyoqXG4gKiBqUXVlcnlcbiAqL1xuXG5kZWZpbmVKUXVlcnlQbHVnaW4oT2ZmY2FudmFzKTtcblxuLyoqXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogQm9vdHN0cmFwIHV0aWwvc2FuaXRpemVyLmpzXG4gKiBMaWNlbnNlZCB1bmRlciBNSVQgKGh0dHBzOi8vZ2l0aHViLmNvbS90d2JzL2Jvb3RzdHJhcC9ibG9iL21haW4vTElDRU5TRSlcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKi9cblxuLy8ganMtZG9jcy1zdGFydCBhbGxvdy1saXN0XG5jb25zdCBBUklBX0FUVFJJQlVURV9QQVRURVJOID0gL15hcmlhLVtcXHctXSokL2k7XG5jb25zdCBEZWZhdWx0QWxsb3dsaXN0ID0ge1xuICAvLyBHbG9iYWwgYXR0cmlidXRlcyBhbGxvd2VkIG9uIGFueSBzdXBwbGllZCBlbGVtZW50IGJlbG93LlxuICAnKic6IFsnY2xhc3MnLCAnZGlyJywgJ2lkJywgJ2xhbmcnLCAncm9sZScsIEFSSUFfQVRUUklCVVRFX1BBVFRFUk5dLFxuICBhOiBbJ3RhcmdldCcsICdocmVmJywgJ3RpdGxlJywgJ3JlbCddLFxuICBhcmVhOiBbXSxcbiAgYjogW10sXG4gIGJyOiBbXSxcbiAgY29sOiBbXSxcbiAgY29kZTogW10sXG4gIGRpdjogW10sXG4gIGVtOiBbXSxcbiAgaHI6IFtdLFxuICBoMTogW10sXG4gIGgyOiBbXSxcbiAgaDM6IFtdLFxuICBoNDogW10sXG4gIGg1OiBbXSxcbiAgaDY6IFtdLFxuICBpOiBbXSxcbiAgaW1nOiBbJ3NyYycsICdzcmNzZXQnLCAnYWx0JywgJ3RpdGxlJywgJ3dpZHRoJywgJ2hlaWdodCddLFxuICBsaTogW10sXG4gIG9sOiBbXSxcbiAgcDogW10sXG4gIHByZTogW10sXG4gIHM6IFtdLFxuICBzbWFsbDogW10sXG4gIHNwYW46IFtdLFxuICBzdWI6IFtdLFxuICBzdXA6IFtdLFxuICBzdHJvbmc6IFtdLFxuICB1OiBbXSxcbiAgdWw6IFtdXG59O1xuLy8ganMtZG9jcy1lbmQgYWxsb3ctbGlzdFxuXG5jb25zdCB1cmlBdHRyaWJ1dGVzID0gbmV3IFNldChbJ2JhY2tncm91bmQnLCAnY2l0ZScsICdocmVmJywgJ2l0ZW10eXBlJywgJ2xvbmdkZXNjJywgJ3Bvc3RlcicsICdzcmMnLCAneGxpbms6aHJlZiddKTtcblxuLyoqXG4gKiBBIHBhdHRlcm4gdGhhdCByZWNvZ25pemVzIFVSTHMgdGhhdCBhcmUgc2FmZSB3cnQuIFhTUyBpbiBVUkwgbmF2aWdhdGlvblxuICogY29udGV4dHMuXG4gKlxuICogU2hvdXQtb3V0IHRvIEFuZ3VsYXIgaHR0cHM6Ly9naXRodWIuY29tL2FuZ3VsYXIvYW5ndWxhci9ibG9iLzE1LjIuOC9wYWNrYWdlcy9jb3JlL3NyYy9zYW5pdGl6YXRpb24vdXJsX3Nhbml0aXplci50cyNMMzhcbiAqL1xuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHVuaWNvcm4vYmV0dGVyLXJlZ2V4XG5jb25zdCBTQUZFX1VSTF9QQVRURVJOID0gL14oPyFqYXZhc2NyaXB0OikoPzpbYS16MC05Ky4tXSs6fFteJjovPyNdKig/OlsvPyNdfCQpKS9pO1xuY29uc3QgYWxsb3dlZEF0dHJpYnV0ZSA9IChhdHRyaWJ1dGUsIGFsbG93ZWRBdHRyaWJ1dGVMaXN0KSA9PiB7XG4gIGNvbnN0IGF0dHJpYnV0ZU5hbWUgPSBhdHRyaWJ1dGUubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtcbiAgaWYgKGFsbG93ZWRBdHRyaWJ1dGVMaXN0LmluY2x1ZGVzKGF0dHJpYnV0ZU5hbWUpKSB7XG4gICAgaWYgKHVyaUF0dHJpYnV0ZXMuaGFzKGF0dHJpYnV0ZU5hbWUpKSB7XG4gICAgICByZXR1cm4gQm9vbGVhbihTQUZFX1VSTF9QQVRURVJOLnRlc3QoYXR0cmlidXRlLm5vZGVWYWx1ZSkpO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8vIENoZWNrIGlmIGEgcmVndWxhciBleHByZXNzaW9uIHZhbGlkYXRlcyB0aGUgYXR0cmlidXRlLlxuICByZXR1cm4gYWxsb3dlZEF0dHJpYnV0ZUxpc3QuZmlsdGVyKGF0dHJpYnV0ZVJlZ2V4ID0+IGF0dHJpYnV0ZVJlZ2V4IGluc3RhbmNlb2YgUmVnRXhwKS5zb21lKHJlZ2V4ID0+IHJlZ2V4LnRlc3QoYXR0cmlidXRlTmFtZSkpO1xufTtcbmZ1bmN0aW9uIHNhbml0aXplSHRtbCh1bnNhZmVIdG1sLCBhbGxvd0xpc3QsIHNhbml0aXplRnVuY3Rpb24pIHtcbiAgaWYgKCF1bnNhZmVIdG1sLmxlbmd0aCkge1xuICAgIHJldHVybiB1bnNhZmVIdG1sO1xuICB9XG4gIGlmIChzYW5pdGl6ZUZ1bmN0aW9uICYmIHR5cGVvZiBzYW5pdGl6ZUZ1bmN0aW9uID09PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIHNhbml0aXplRnVuY3Rpb24odW5zYWZlSHRtbCk7XG4gIH1cbiAgY29uc3QgZG9tUGFyc2VyID0gbmV3IHdpbmRvdy5ET01QYXJzZXIoKTtcbiAgY29uc3QgY3JlYXRlZERvY3VtZW50ID0gZG9tUGFyc2VyLnBhcnNlRnJvbVN0cmluZyh1bnNhZmVIdG1sLCAndGV4dC9odG1sJyk7XG4gIGNvbnN0IGVsZW1lbnRzID0gW10uY29uY2F0KC4uLmNyZWF0ZWREb2N1bWVudC5ib2R5LnF1ZXJ5U2VsZWN0b3JBbGwoJyonKSk7XG4gIGZvciAoY29uc3QgZWxlbWVudCBvZiBlbGVtZW50cykge1xuICAgIGNvbnN0IGVsZW1lbnROYW1lID0gZWxlbWVudC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1xuICAgIGlmICghT2JqZWN0LmtleXMoYWxsb3dMaXN0KS5pbmNsdWRlcyhlbGVtZW50TmFtZSkpIHtcbiAgICAgIGVsZW1lbnQucmVtb3ZlKCk7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgY29uc3QgYXR0cmlidXRlTGlzdCA9IFtdLmNvbmNhdCguLi5lbGVtZW50LmF0dHJpYnV0ZXMpO1xuICAgIGNvbnN0IGFsbG93ZWRBdHRyaWJ1dGVzID0gW10uY29uY2F0KGFsbG93TGlzdFsnKiddIHx8IFtdLCBhbGxvd0xpc3RbZWxlbWVudE5hbWVdIHx8IFtdKTtcbiAgICBmb3IgKGNvbnN0IGF0dHJpYnV0ZSBvZiBhdHRyaWJ1dGVMaXN0KSB7XG4gICAgICBpZiAoIWFsbG93ZWRBdHRyaWJ1dGUoYXR0cmlidXRlLCBhbGxvd2VkQXR0cmlidXRlcykpIHtcbiAgICAgICAgZWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUoYXR0cmlidXRlLm5vZGVOYW1lKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIGNyZWF0ZWREb2N1bWVudC5ib2R5LmlubmVySFRNTDtcbn1cblxuLyoqXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogQm9vdHN0cmFwIHV0aWwvdGVtcGxhdGUtZmFjdG9yeS5qc1xuICogTGljZW5zZWQgdW5kZXIgTUlUIChodHRwczovL2dpdGh1Yi5jb20vdHdicy9ib290c3RyYXAvYmxvYi9tYWluL0xJQ0VOU0UpXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICovXG5cblxuLyoqXG4gKiBDb25zdGFudHNcbiAqL1xuXG5jb25zdCBOQU1FJDUgPSAnVGVtcGxhdGVGYWN0b3J5JztcbmNvbnN0IERlZmF1bHQkNCA9IHtcbiAgYWxsb3dMaXN0OiBEZWZhdWx0QWxsb3dsaXN0LFxuICBjb250ZW50OiB7fSxcbiAgLy8geyBzZWxlY3RvciA6IHRleHQgLCAgc2VsZWN0b3IyIDogdGV4dDIgLCB9XG4gIGV4dHJhQ2xhc3M6ICcnLFxuICBodG1sOiBmYWxzZSxcbiAgc2FuaXRpemU6IHRydWUsXG4gIHNhbml0aXplRm46IG51bGwsXG4gIHRlbXBsYXRlOiAnPGRpdj48L2Rpdj4nXG59O1xuY29uc3QgRGVmYXVsdFR5cGUkNCA9IHtcbiAgYWxsb3dMaXN0OiAnb2JqZWN0JyxcbiAgY29udGVudDogJ29iamVjdCcsXG4gIGV4dHJhQ2xhc3M6ICcoc3RyaW5nfGZ1bmN0aW9uKScsXG4gIGh0bWw6ICdib29sZWFuJyxcbiAgc2FuaXRpemU6ICdib29sZWFuJyxcbiAgc2FuaXRpemVGbjogJyhudWxsfGZ1bmN0aW9uKScsXG4gIHRlbXBsYXRlOiAnc3RyaW5nJ1xufTtcbmNvbnN0IERlZmF1bHRDb250ZW50VHlwZSA9IHtcbiAgZW50cnk6ICcoc3RyaW5nfGVsZW1lbnR8ZnVuY3Rpb258bnVsbCknLFxuICBzZWxlY3RvcjogJyhzdHJpbmd8ZWxlbWVudCknXG59O1xuXG4vKipcbiAqIENsYXNzIGRlZmluaXRpb25cbiAqL1xuXG5jbGFzcyBUZW1wbGF0ZUZhY3RvcnkgZXh0ZW5kcyBDb25maWcge1xuICBjb25zdHJ1Y3Rvcihjb25maWcpIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMuX2NvbmZpZyA9IHRoaXMuX2dldENvbmZpZyhjb25maWcpO1xuICB9XG5cbiAgLy8gR2V0dGVyc1xuICBzdGF0aWMgZ2V0IERlZmF1bHQoKSB7XG4gICAgcmV0dXJuIERlZmF1bHQkNDtcbiAgfVxuICBzdGF0aWMgZ2V0IERlZmF1bHRUeXBlKCkge1xuICAgIHJldHVybiBEZWZhdWx0VHlwZSQ0O1xuICB9XG4gIHN0YXRpYyBnZXQgTkFNRSgpIHtcbiAgICByZXR1cm4gTkFNRSQ1O1xuICB9XG5cbiAgLy8gUHVibGljXG4gIGdldENvbnRlbnQoKSB7XG4gICAgcmV0dXJuIE9iamVjdC52YWx1ZXModGhpcy5fY29uZmlnLmNvbnRlbnQpLm1hcChjb25maWcgPT4gdGhpcy5fcmVzb2x2ZVBvc3NpYmxlRnVuY3Rpb24oY29uZmlnKSkuZmlsdGVyKEJvb2xlYW4pO1xuICB9XG4gIGhhc0NvbnRlbnQoKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0Q29udGVudCgpLmxlbmd0aCA+IDA7XG4gIH1cbiAgY2hhbmdlQ29udGVudChjb250ZW50KSB7XG4gICAgdGhpcy5fY2hlY2tDb250ZW50KGNvbnRlbnQpO1xuICAgIHRoaXMuX2NvbmZpZy5jb250ZW50ID0ge1xuICAgICAgLi4udGhpcy5fY29uZmlnLmNvbnRlbnQsXG4gICAgICAuLi5jb250ZW50XG4gICAgfTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuICB0b0h0bWwoKSB7XG4gICAgY29uc3QgdGVtcGxhdGVXcmFwcGVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgdGVtcGxhdGVXcmFwcGVyLmlubmVySFRNTCA9IHRoaXMuX21heWJlU2FuaXRpemUodGhpcy5fY29uZmlnLnRlbXBsYXRlKTtcbiAgICBmb3IgKGNvbnN0IFtzZWxlY3RvciwgdGV4dF0gb2YgT2JqZWN0LmVudHJpZXModGhpcy5fY29uZmlnLmNvbnRlbnQpKSB7XG4gICAgICB0aGlzLl9zZXRDb250ZW50KHRlbXBsYXRlV3JhcHBlciwgdGV4dCwgc2VsZWN0b3IpO1xuICAgIH1cbiAgICBjb25zdCB0ZW1wbGF0ZSA9IHRlbXBsYXRlV3JhcHBlci5jaGlsZHJlblswXTtcbiAgICBjb25zdCBleHRyYUNsYXNzID0gdGhpcy5fcmVzb2x2ZVBvc3NpYmxlRnVuY3Rpb24odGhpcy5fY29uZmlnLmV4dHJhQ2xhc3MpO1xuICAgIGlmIChleHRyYUNsYXNzKSB7XG4gICAgICB0ZW1wbGF0ZS5jbGFzc0xpc3QuYWRkKC4uLmV4dHJhQ2xhc3Muc3BsaXQoJyAnKSk7XG4gICAgfVxuICAgIHJldHVybiB0ZW1wbGF0ZTtcbiAgfVxuXG4gIC8vIFByaXZhdGVcbiAgX3R5cGVDaGVja0NvbmZpZyhjb25maWcpIHtcbiAgICBzdXBlci5fdHlwZUNoZWNrQ29uZmlnKGNvbmZpZyk7XG4gICAgdGhpcy5fY2hlY2tDb250ZW50KGNvbmZpZy5jb250ZW50KTtcbiAgfVxuICBfY2hlY2tDb250ZW50KGFyZykge1xuICAgIGZvciAoY29uc3QgW3NlbGVjdG9yLCBjb250ZW50XSBvZiBPYmplY3QuZW50cmllcyhhcmcpKSB7XG4gICAgICBzdXBlci5fdHlwZUNoZWNrQ29uZmlnKHtcbiAgICAgICAgc2VsZWN0b3IsXG4gICAgICAgIGVudHJ5OiBjb250ZW50XG4gICAgICB9LCBEZWZhdWx0Q29udGVudFR5cGUpO1xuICAgIH1cbiAgfVxuICBfc2V0Q29udGVudCh0ZW1wbGF0ZSwgY29udGVudCwgc2VsZWN0b3IpIHtcbiAgICBjb25zdCB0ZW1wbGF0ZUVsZW1lbnQgPSBTZWxlY3RvckVuZ2luZS5maW5kT25lKHNlbGVjdG9yLCB0ZW1wbGF0ZSk7XG4gICAgaWYgKCF0ZW1wbGF0ZUVsZW1lbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29udGVudCA9IHRoaXMuX3Jlc29sdmVQb3NzaWJsZUZ1bmN0aW9uKGNvbnRlbnQpO1xuICAgIGlmICghY29udGVudCkge1xuICAgICAgdGVtcGxhdGVFbGVtZW50LnJlbW92ZSgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoaXNFbGVtZW50KGNvbnRlbnQpKSB7XG4gICAgICB0aGlzLl9wdXRFbGVtZW50SW5UZW1wbGF0ZShnZXRFbGVtZW50KGNvbnRlbnQpLCB0ZW1wbGF0ZUVsZW1lbnQpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAodGhpcy5fY29uZmlnLmh0bWwpIHtcbiAgICAgIHRlbXBsYXRlRWxlbWVudC5pbm5lckhUTUwgPSB0aGlzLl9tYXliZVNhbml0aXplKGNvbnRlbnQpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0ZW1wbGF0ZUVsZW1lbnQudGV4dENvbnRlbnQgPSBjb250ZW50O1xuICB9XG4gIF9tYXliZVNhbml0aXplKGFyZykge1xuICAgIHJldHVybiB0aGlzLl9jb25maWcuc2FuaXRpemUgPyBzYW5pdGl6ZUh0bWwoYXJnLCB0aGlzLl9jb25maWcuYWxsb3dMaXN0LCB0aGlzLl9jb25maWcuc2FuaXRpemVGbikgOiBhcmc7XG4gIH1cbiAgX3Jlc29sdmVQb3NzaWJsZUZ1bmN0aW9uKGFyZykge1xuICAgIHJldHVybiBleGVjdXRlKGFyZywgW3RoaXNdKTtcbiAgfVxuICBfcHV0RWxlbWVudEluVGVtcGxhdGUoZWxlbWVudCwgdGVtcGxhdGVFbGVtZW50KSB7XG4gICAgaWYgKHRoaXMuX2NvbmZpZy5odG1sKSB7XG4gICAgICB0ZW1wbGF0ZUVsZW1lbnQuaW5uZXJIVE1MID0gJyc7XG4gICAgICB0ZW1wbGF0ZUVsZW1lbnQuYXBwZW5kKGVsZW1lbnQpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0ZW1wbGF0ZUVsZW1lbnQudGV4dENvbnRlbnQgPSBlbGVtZW50LnRleHRDb250ZW50O1xuICB9XG59XG5cbi8qKlxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIEJvb3RzdHJhcCB0b29sdGlwLmpzXG4gKiBMaWNlbnNlZCB1bmRlciBNSVQgKGh0dHBzOi8vZ2l0aHViLmNvbS90d2JzL2Jvb3RzdHJhcC9ibG9iL21haW4vTElDRU5TRSlcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKi9cblxuXG4vKipcbiAqIENvbnN0YW50c1xuICovXG5cbmNvbnN0IE5BTUUkNCA9ICd0b29sdGlwJztcbmNvbnN0IERJU0FMTE9XRURfQVRUUklCVVRFUyA9IG5ldyBTZXQoWydzYW5pdGl6ZScsICdhbGxvd0xpc3QnLCAnc2FuaXRpemVGbiddKTtcbmNvbnN0IENMQVNTX05BTUVfRkFERSQyID0gJ2ZhZGUnO1xuY29uc3QgQ0xBU1NfTkFNRV9NT0RBTCA9ICdtb2RhbCc7XG5jb25zdCBDTEFTU19OQU1FX1NIT1ckMiA9ICdzaG93JztcbmNvbnN0IFNFTEVDVE9SX1RPT0xUSVBfSU5ORVIgPSAnLnRvb2x0aXAtaW5uZXInO1xuY29uc3QgU0VMRUNUT1JfTU9EQUwgPSBgLiR7Q0xBU1NfTkFNRV9NT0RBTH1gO1xuY29uc3QgRVZFTlRfTU9EQUxfSElERSA9ICdoaWRlLmJzLm1vZGFsJztcbmNvbnN0IFRSSUdHRVJfSE9WRVIgPSAnaG92ZXInO1xuY29uc3QgVFJJR0dFUl9GT0NVUyA9ICdmb2N1cyc7XG5jb25zdCBUUklHR0VSX0NMSUNLID0gJ2NsaWNrJztcbmNvbnN0IFRSSUdHRVJfTUFOVUFMID0gJ21hbnVhbCc7XG5jb25zdCBFVkVOVF9ISURFJDIgPSAnaGlkZSc7XG5jb25zdCBFVkVOVF9ISURERU4kMiA9ICdoaWRkZW4nO1xuY29uc3QgRVZFTlRfU0hPVyQyID0gJ3Nob3cnO1xuY29uc3QgRVZFTlRfU0hPV04kMiA9ICdzaG93bic7XG5jb25zdCBFVkVOVF9JTlNFUlRFRCA9ICdpbnNlcnRlZCc7XG5jb25zdCBFVkVOVF9DTElDSyQxID0gJ2NsaWNrJztcbmNvbnN0IEVWRU5UX0ZPQ1VTSU4kMSA9ICdmb2N1c2luJztcbmNvbnN0IEVWRU5UX0ZPQ1VTT1VUJDEgPSAnZm9jdXNvdXQnO1xuY29uc3QgRVZFTlRfTU9VU0VFTlRFUiA9ICdtb3VzZWVudGVyJztcbmNvbnN0IEVWRU5UX01PVVNFTEVBVkUgPSAnbW91c2VsZWF2ZSc7XG5jb25zdCBBdHRhY2htZW50TWFwID0ge1xuICBBVVRPOiAnYXV0bycsXG4gIFRPUDogJ3RvcCcsXG4gIFJJR0hUOiBpc1JUTCgpID8gJ2xlZnQnIDogJ3JpZ2h0JyxcbiAgQk9UVE9NOiAnYm90dG9tJyxcbiAgTEVGVDogaXNSVEwoKSA/ICdyaWdodCcgOiAnbGVmdCdcbn07XG5jb25zdCBEZWZhdWx0JDMgPSB7XG4gIGFsbG93TGlzdDogRGVmYXVsdEFsbG93bGlzdCxcbiAgYW5pbWF0aW9uOiB0cnVlLFxuICBib3VuZGFyeTogJ2NsaXBwaW5nUGFyZW50cycsXG4gIGNvbnRhaW5lcjogZmFsc2UsXG4gIGN1c3RvbUNsYXNzOiAnJyxcbiAgZGVsYXk6IDAsXG4gIGZhbGxiYWNrUGxhY2VtZW50czogWyd0b3AnLCAncmlnaHQnLCAnYm90dG9tJywgJ2xlZnQnXSxcbiAgaHRtbDogZmFsc2UsXG4gIG9mZnNldDogWzAsIDZdLFxuICBwbGFjZW1lbnQ6ICd0b3AnLFxuICBwb3BwZXJDb25maWc6IG51bGwsXG4gIHNhbml0aXplOiB0cnVlLFxuICBzYW5pdGl6ZUZuOiBudWxsLFxuICBzZWxlY3RvcjogZmFsc2UsXG4gIHRlbXBsYXRlOiAnPGRpdiBjbGFzcz1cInRvb2x0aXBcIiByb2xlPVwidG9vbHRpcFwiPicgKyAnPGRpdiBjbGFzcz1cInRvb2x0aXAtYXJyb3dcIj48L2Rpdj4nICsgJzxkaXYgY2xhc3M9XCJ0b29sdGlwLWlubmVyXCI+PC9kaXY+JyArICc8L2Rpdj4nLFxuICB0aXRsZTogJycsXG4gIHRyaWdnZXI6ICdob3ZlciBmb2N1cydcbn07XG5jb25zdCBEZWZhdWx0VHlwZSQzID0ge1xuICBhbGxvd0xpc3Q6ICdvYmplY3QnLFxuICBhbmltYXRpb246ICdib29sZWFuJyxcbiAgYm91bmRhcnk6ICcoc3RyaW5nfGVsZW1lbnQpJyxcbiAgY29udGFpbmVyOiAnKHN0cmluZ3xlbGVtZW50fGJvb2xlYW4pJyxcbiAgY3VzdG9tQ2xhc3M6ICcoc3RyaW5nfGZ1bmN0aW9uKScsXG4gIGRlbGF5OiAnKG51bWJlcnxvYmplY3QpJyxcbiAgZmFsbGJhY2tQbGFjZW1lbnRzOiAnYXJyYXknLFxuICBodG1sOiAnYm9vbGVhbicsXG4gIG9mZnNldDogJyhhcnJheXxzdHJpbmd8ZnVuY3Rpb24pJyxcbiAgcGxhY2VtZW50OiAnKHN0cmluZ3xmdW5jdGlvbiknLFxuICBwb3BwZXJDb25maWc6ICcobnVsbHxvYmplY3R8ZnVuY3Rpb24pJyxcbiAgc2FuaXRpemU6ICdib29sZWFuJyxcbiAgc2FuaXRpemVGbjogJyhudWxsfGZ1bmN0aW9uKScsXG4gIHNlbGVjdG9yOiAnKHN0cmluZ3xib29sZWFuKScsXG4gIHRlbXBsYXRlOiAnc3RyaW5nJyxcbiAgdGl0bGU6ICcoc3RyaW5nfGVsZW1lbnR8ZnVuY3Rpb24pJyxcbiAgdHJpZ2dlcjogJ3N0cmluZydcbn07XG5cbi8qKlxuICogQ2xhc3MgZGVmaW5pdGlvblxuICovXG5cbmNsYXNzIFRvb2x0aXAgZXh0ZW5kcyBCYXNlQ29tcG9uZW50IHtcbiAgY29uc3RydWN0b3IoZWxlbWVudCwgY29uZmlnKSB7XG4gICAgaWYgKHR5cGVvZiBQb3BwZXIgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdCb290c3RyYXBcXCdzIHRvb2x0aXBzIHJlcXVpcmUgUG9wcGVyIChodHRwczovL3BvcHBlci5qcy5vcmcpJyk7XG4gICAgfVxuICAgIHN1cGVyKGVsZW1lbnQsIGNvbmZpZyk7XG5cbiAgICAvLyBQcml2YXRlXG4gICAgdGhpcy5faXNFbmFibGVkID0gdHJ1ZTtcbiAgICB0aGlzLl90aW1lb3V0ID0gMDtcbiAgICB0aGlzLl9pc0hvdmVyZWQgPSBudWxsO1xuICAgIHRoaXMuX2FjdGl2ZVRyaWdnZXIgPSB7fTtcbiAgICB0aGlzLl9wb3BwZXIgPSBudWxsO1xuICAgIHRoaXMuX3RlbXBsYXRlRmFjdG9yeSA9IG51bGw7XG4gICAgdGhpcy5fbmV3Q29udGVudCA9IG51bGw7XG5cbiAgICAvLyBQcm90ZWN0ZWRcbiAgICB0aGlzLnRpcCA9IG51bGw7XG4gICAgdGhpcy5fc2V0TGlzdGVuZXJzKCk7XG4gICAgaWYgKCF0aGlzLl9jb25maWcuc2VsZWN0b3IpIHtcbiAgICAgIHRoaXMuX2ZpeFRpdGxlKCk7XG4gICAgfVxuICB9XG5cbiAgLy8gR2V0dGVyc1xuICBzdGF0aWMgZ2V0IERlZmF1bHQoKSB7XG4gICAgcmV0dXJuIERlZmF1bHQkMztcbiAgfVxuICBzdGF0aWMgZ2V0IERlZmF1bHRUeXBlKCkge1xuICAgIHJldHVybiBEZWZhdWx0VHlwZSQzO1xuICB9XG4gIHN0YXRpYyBnZXQgTkFNRSgpIHtcbiAgICByZXR1cm4gTkFNRSQ0O1xuICB9XG5cbiAgLy8gUHVibGljXG4gIGVuYWJsZSgpIHtcbiAgICB0aGlzLl9pc0VuYWJsZWQgPSB0cnVlO1xuICB9XG4gIGRpc2FibGUoKSB7XG4gICAgdGhpcy5faXNFbmFibGVkID0gZmFsc2U7XG4gIH1cbiAgdG9nZ2xlRW5hYmxlZCgpIHtcbiAgICB0aGlzLl9pc0VuYWJsZWQgPSAhdGhpcy5faXNFbmFibGVkO1xuICB9XG4gIHRvZ2dsZSgpIHtcbiAgICBpZiAoIXRoaXMuX2lzRW5hYmxlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLl9hY3RpdmVUcmlnZ2VyLmNsaWNrID0gIXRoaXMuX2FjdGl2ZVRyaWdnZXIuY2xpY2s7XG4gICAgaWYgKHRoaXMuX2lzU2hvd24oKSkge1xuICAgICAgdGhpcy5fbGVhdmUoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5fZW50ZXIoKTtcbiAgfVxuICBkaXNwb3NlKCkge1xuICAgIGNsZWFyVGltZW91dCh0aGlzLl90aW1lb3V0KTtcbiAgICBFdmVudEhhbmRsZXIub2ZmKHRoaXMuX2VsZW1lbnQuY2xvc2VzdChTRUxFQ1RPUl9NT0RBTCksIEVWRU5UX01PREFMX0hJREUsIHRoaXMuX2hpZGVNb2RhbEhhbmRsZXIpO1xuICAgIGlmICh0aGlzLl9lbGVtZW50LmdldEF0dHJpYnV0ZSgnZGF0YS1icy1vcmlnaW5hbC10aXRsZScpKSB7XG4gICAgICB0aGlzLl9lbGVtZW50LnNldEF0dHJpYnV0ZSgndGl0bGUnLCB0aGlzLl9lbGVtZW50LmdldEF0dHJpYnV0ZSgnZGF0YS1icy1vcmlnaW5hbC10aXRsZScpKTtcbiAgICB9XG4gICAgdGhpcy5fZGlzcG9zZVBvcHBlcigpO1xuICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgfVxuICBzaG93KCkge1xuICAgIGlmICh0aGlzLl9lbGVtZW50LnN0eWxlLmRpc3BsYXkgPT09ICdub25lJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdQbGVhc2UgdXNlIHNob3cgb24gdmlzaWJsZSBlbGVtZW50cycpO1xuICAgIH1cbiAgICBpZiAoISh0aGlzLl9pc1dpdGhDb250ZW50KCkgJiYgdGhpcy5faXNFbmFibGVkKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBzaG93RXZlbnQgPSBFdmVudEhhbmRsZXIudHJpZ2dlcih0aGlzLl9lbGVtZW50LCB0aGlzLmNvbnN0cnVjdG9yLmV2ZW50TmFtZShFVkVOVF9TSE9XJDIpKTtcbiAgICBjb25zdCBzaGFkb3dSb290ID0gZmluZFNoYWRvd1Jvb3QodGhpcy5fZWxlbWVudCk7XG4gICAgY29uc3QgaXNJblRoZURvbSA9IChzaGFkb3dSb290IHx8IHRoaXMuX2VsZW1lbnQub3duZXJEb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpLmNvbnRhaW5zKHRoaXMuX2VsZW1lbnQpO1xuICAgIGlmIChzaG93RXZlbnQuZGVmYXVsdFByZXZlbnRlZCB8fCAhaXNJblRoZURvbSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIFRPRE86IHY2IHJlbW92ZSB0aGlzIG9yIG1ha2UgaXQgb3B0aW9uYWxcbiAgICB0aGlzLl9kaXNwb3NlUG9wcGVyKCk7XG4gICAgY29uc3QgdGlwID0gdGhpcy5fZ2V0VGlwRWxlbWVudCgpO1xuICAgIHRoaXMuX2VsZW1lbnQuc2V0QXR0cmlidXRlKCdhcmlhLWRlc2NyaWJlZGJ5JywgdGlwLmdldEF0dHJpYnV0ZSgnaWQnKSk7XG4gICAgY29uc3Qge1xuICAgICAgY29udGFpbmVyXG4gICAgfSA9IHRoaXMuX2NvbmZpZztcbiAgICBpZiAoIXRoaXMuX2VsZW1lbnQub3duZXJEb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY29udGFpbnModGhpcy50aXApKSB7XG4gICAgICBjb250YWluZXIuYXBwZW5kKHRpcCk7XG4gICAgICBFdmVudEhhbmRsZXIudHJpZ2dlcih0aGlzLl9lbGVtZW50LCB0aGlzLmNvbnN0cnVjdG9yLmV2ZW50TmFtZShFVkVOVF9JTlNFUlRFRCkpO1xuICAgIH1cbiAgICB0aGlzLl9wb3BwZXIgPSB0aGlzLl9jcmVhdGVQb3BwZXIodGlwKTtcbiAgICB0aXAuY2xhc3NMaXN0LmFkZChDTEFTU19OQU1FX1NIT1ckMik7XG5cbiAgICAvLyBJZiB0aGlzIGlzIGEgdG91Y2gtZW5hYmxlZCBkZXZpY2Ugd2UgYWRkIGV4dHJhXG4gICAgLy8gZW1wdHkgbW91c2VvdmVyIGxpc3RlbmVycyB0byB0aGUgYm9keSdzIGltbWVkaWF0ZSBjaGlsZHJlbjtcbiAgICAvLyBvbmx5IG5lZWRlZCBiZWNhdXNlIG9mIGJyb2tlbiBldmVudCBkZWxlZ2F0aW9uIG9uIGlPU1xuICAgIC8vIGh0dHBzOi8vd3d3LnF1aXJrc21vZGUub3JnL2Jsb2cvYXJjaGl2ZXMvMjAxNC8wMi9tb3VzZV9ldmVudF9idWIuaHRtbFxuICAgIGlmICgnb250b3VjaHN0YXJ0JyBpbiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpIHtcbiAgICAgIGZvciAoY29uc3QgZWxlbWVudCBvZiBbXS5jb25jYXQoLi4uZG9jdW1lbnQuYm9keS5jaGlsZHJlbikpIHtcbiAgICAgICAgRXZlbnRIYW5kbGVyLm9uKGVsZW1lbnQsICdtb3VzZW92ZXInLCBub29wKTtcbiAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgY29tcGxldGUgPSAoKSA9PiB7XG4gICAgICBFdmVudEhhbmRsZXIudHJpZ2dlcih0aGlzLl9lbGVtZW50LCB0aGlzLmNvbnN0cnVjdG9yLmV2ZW50TmFtZShFVkVOVF9TSE9XTiQyKSk7XG4gICAgICBpZiAodGhpcy5faXNIb3ZlcmVkID09PSBmYWxzZSkge1xuICAgICAgICB0aGlzLl9sZWF2ZSgpO1xuICAgICAgfVxuICAgICAgdGhpcy5faXNIb3ZlcmVkID0gZmFsc2U7XG4gICAgfTtcbiAgICB0aGlzLl9xdWV1ZUNhbGxiYWNrKGNvbXBsZXRlLCB0aGlzLnRpcCwgdGhpcy5faXNBbmltYXRlZCgpKTtcbiAgfVxuICBoaWRlKCkge1xuICAgIGlmICghdGhpcy5faXNTaG93bigpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGhpZGVFdmVudCA9IEV2ZW50SGFuZGxlci50cmlnZ2VyKHRoaXMuX2VsZW1lbnQsIHRoaXMuY29uc3RydWN0b3IuZXZlbnROYW1lKEVWRU5UX0hJREUkMikpO1xuICAgIGlmIChoaWRlRXZlbnQuZGVmYXVsdFByZXZlbnRlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCB0aXAgPSB0aGlzLl9nZXRUaXBFbGVtZW50KCk7XG4gICAgdGlwLmNsYXNzTGlzdC5yZW1vdmUoQ0xBU1NfTkFNRV9TSE9XJDIpO1xuXG4gICAgLy8gSWYgdGhpcyBpcyBhIHRvdWNoLWVuYWJsZWQgZGV2aWNlIHdlIHJlbW92ZSB0aGUgZXh0cmFcbiAgICAvLyBlbXB0eSBtb3VzZW92ZXIgbGlzdGVuZXJzIHdlIGFkZGVkIGZvciBpT1Mgc3VwcG9ydFxuICAgIGlmICgnb250b3VjaHN0YXJ0JyBpbiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpIHtcbiAgICAgIGZvciAoY29uc3QgZWxlbWVudCBvZiBbXS5jb25jYXQoLi4uZG9jdW1lbnQuYm9keS5jaGlsZHJlbikpIHtcbiAgICAgICAgRXZlbnRIYW5kbGVyLm9mZihlbGVtZW50LCAnbW91c2VvdmVyJywgbm9vcCk7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMuX2FjdGl2ZVRyaWdnZXJbVFJJR0dFUl9DTElDS10gPSBmYWxzZTtcbiAgICB0aGlzLl9hY3RpdmVUcmlnZ2VyW1RSSUdHRVJfRk9DVVNdID0gZmFsc2U7XG4gICAgdGhpcy5fYWN0aXZlVHJpZ2dlcltUUklHR0VSX0hPVkVSXSA9IGZhbHNlO1xuICAgIHRoaXMuX2lzSG92ZXJlZCA9IG51bGw7IC8vIGl0IGlzIGEgdHJpY2sgdG8gc3VwcG9ydCBtYW51YWwgdHJpZ2dlcmluZ1xuXG4gICAgY29uc3QgY29tcGxldGUgPSAoKSA9PiB7XG4gICAgICBpZiAodGhpcy5faXNXaXRoQWN0aXZlVHJpZ2dlcigpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmICghdGhpcy5faXNIb3ZlcmVkKSB7XG4gICAgICAgIHRoaXMuX2Rpc3Bvc2VQb3BwZXIoKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuX2VsZW1lbnQucmVtb3ZlQXR0cmlidXRlKCdhcmlhLWRlc2NyaWJlZGJ5Jyk7XG4gICAgICBFdmVudEhhbmRsZXIudHJpZ2dlcih0aGlzLl9lbGVtZW50LCB0aGlzLmNvbnN0cnVjdG9yLmV2ZW50TmFtZShFVkVOVF9ISURERU4kMikpO1xuICAgIH07XG4gICAgdGhpcy5fcXVldWVDYWxsYmFjayhjb21wbGV0ZSwgdGhpcy50aXAsIHRoaXMuX2lzQW5pbWF0ZWQoKSk7XG4gIH1cbiAgdXBkYXRlKCkge1xuICAgIGlmICh0aGlzLl9wb3BwZXIpIHtcbiAgICAgIHRoaXMuX3BvcHBlci51cGRhdGUoKTtcbiAgICB9XG4gIH1cblxuICAvLyBQcm90ZWN0ZWRcbiAgX2lzV2l0aENvbnRlbnQoKSB7XG4gICAgcmV0dXJuIEJvb2xlYW4odGhpcy5fZ2V0VGl0bGUoKSk7XG4gIH1cbiAgX2dldFRpcEVsZW1lbnQoKSB7XG4gICAgaWYgKCF0aGlzLnRpcCkge1xuICAgICAgdGhpcy50aXAgPSB0aGlzLl9jcmVhdGVUaXBFbGVtZW50KHRoaXMuX25ld0NvbnRlbnQgfHwgdGhpcy5fZ2V0Q29udGVudEZvclRlbXBsYXRlKCkpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy50aXA7XG4gIH1cbiAgX2NyZWF0ZVRpcEVsZW1lbnQoY29udGVudCkge1xuICAgIGNvbnN0IHRpcCA9IHRoaXMuX2dldFRlbXBsYXRlRmFjdG9yeShjb250ZW50KS50b0h0bWwoKTtcblxuICAgIC8vIFRPRE86IHJlbW92ZSB0aGlzIGNoZWNrIGluIHY2XG4gICAgaWYgKCF0aXApIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICB0aXAuY2xhc3NMaXN0LnJlbW92ZShDTEFTU19OQU1FX0ZBREUkMiwgQ0xBU1NfTkFNRV9TSE9XJDIpO1xuICAgIC8vIFRPRE86IHY2IHRoZSBmb2xsb3dpbmcgY2FuIGJlIGFjaGlldmVkIHdpdGggQ1NTIG9ubHlcbiAgICB0aXAuY2xhc3NMaXN0LmFkZChgYnMtJHt0aGlzLmNvbnN0cnVjdG9yLk5BTUV9LWF1dG9gKTtcbiAgICBjb25zdCB0aXBJZCA9IGdldFVJRCh0aGlzLmNvbnN0cnVjdG9yLk5BTUUpLnRvU3RyaW5nKCk7XG4gICAgdGlwLnNldEF0dHJpYnV0ZSgnaWQnLCB0aXBJZCk7XG4gICAgaWYgKHRoaXMuX2lzQW5pbWF0ZWQoKSkge1xuICAgICAgdGlwLmNsYXNzTGlzdC5hZGQoQ0xBU1NfTkFNRV9GQURFJDIpO1xuICAgIH1cbiAgICByZXR1cm4gdGlwO1xuICB9XG4gIHNldENvbnRlbnQoY29udGVudCkge1xuICAgIHRoaXMuX25ld0NvbnRlbnQgPSBjb250ZW50O1xuICAgIGlmICh0aGlzLl9pc1Nob3duKCkpIHtcbiAgICAgIHRoaXMuX2Rpc3Bvc2VQb3BwZXIoKTtcbiAgICAgIHRoaXMuc2hvdygpO1xuICAgIH1cbiAgfVxuICBfZ2V0VGVtcGxhdGVGYWN0b3J5KGNvbnRlbnQpIHtcbiAgICBpZiAodGhpcy5fdGVtcGxhdGVGYWN0b3J5KSB7XG4gICAgICB0aGlzLl90ZW1wbGF0ZUZhY3RvcnkuY2hhbmdlQ29udGVudChjb250ZW50KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fdGVtcGxhdGVGYWN0b3J5ID0gbmV3IFRlbXBsYXRlRmFjdG9yeSh7XG4gICAgICAgIC4uLnRoaXMuX2NvbmZpZyxcbiAgICAgICAgLy8gdGhlIGBjb250ZW50YCB2YXIgaGFzIHRvIGJlIGFmdGVyIGB0aGlzLl9jb25maWdgXG4gICAgICAgIC8vIHRvIG92ZXJyaWRlIGNvbmZpZy5jb250ZW50IGluIGNhc2Ugb2YgcG9wb3ZlclxuICAgICAgICBjb250ZW50LFxuICAgICAgICBleHRyYUNsYXNzOiB0aGlzLl9yZXNvbHZlUG9zc2libGVGdW5jdGlvbih0aGlzLl9jb25maWcuY3VzdG9tQ2xhc3MpXG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX3RlbXBsYXRlRmFjdG9yeTtcbiAgfVxuICBfZ2V0Q29udGVudEZvclRlbXBsYXRlKCkge1xuICAgIHJldHVybiB7XG4gICAgICBbU0VMRUNUT1JfVE9PTFRJUF9JTk5FUl06IHRoaXMuX2dldFRpdGxlKClcbiAgICB9O1xuICB9XG4gIF9nZXRUaXRsZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fcmVzb2x2ZVBvc3NpYmxlRnVuY3Rpb24odGhpcy5fY29uZmlnLnRpdGxlKSB8fCB0aGlzLl9lbGVtZW50LmdldEF0dHJpYnV0ZSgnZGF0YS1icy1vcmlnaW5hbC10aXRsZScpO1xuICB9XG5cbiAgLy8gUHJpdmF0ZVxuICBfaW5pdGlhbGl6ZU9uRGVsZWdhdGVkVGFyZ2V0KGV2ZW50KSB7XG4gICAgcmV0dXJuIHRoaXMuY29uc3RydWN0b3IuZ2V0T3JDcmVhdGVJbnN0YW5jZShldmVudC5kZWxlZ2F0ZVRhcmdldCwgdGhpcy5fZ2V0RGVsZWdhdGVDb25maWcoKSk7XG4gIH1cbiAgX2lzQW5pbWF0ZWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2NvbmZpZy5hbmltYXRpb24gfHwgdGhpcy50aXAgJiYgdGhpcy50aXAuY2xhc3NMaXN0LmNvbnRhaW5zKENMQVNTX05BTUVfRkFERSQyKTtcbiAgfVxuICBfaXNTaG93bigpIHtcbiAgICByZXR1cm4gdGhpcy50aXAgJiYgdGhpcy50aXAuY2xhc3NMaXN0LmNvbnRhaW5zKENMQVNTX05BTUVfU0hPVyQyKTtcbiAgfVxuICBfY3JlYXRlUG9wcGVyKHRpcCkge1xuICAgIGNvbnN0IHBsYWNlbWVudCA9IGV4ZWN1dGUodGhpcy5fY29uZmlnLnBsYWNlbWVudCwgW3RoaXMsIHRpcCwgdGhpcy5fZWxlbWVudF0pO1xuICAgIGNvbnN0IGF0dGFjaG1lbnQgPSBBdHRhY2htZW50TWFwW3BsYWNlbWVudC50b1VwcGVyQ2FzZSgpXTtcbiAgICByZXR1cm4gUG9wcGVyLmNyZWF0ZVBvcHBlcih0aGlzLl9lbGVtZW50LCB0aXAsIHRoaXMuX2dldFBvcHBlckNvbmZpZyhhdHRhY2htZW50KSk7XG4gIH1cbiAgX2dldE9mZnNldCgpIHtcbiAgICBjb25zdCB7XG4gICAgICBvZmZzZXRcbiAgICB9ID0gdGhpcy5fY29uZmlnO1xuICAgIGlmICh0eXBlb2Ygb2Zmc2V0ID09PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIG9mZnNldC5zcGxpdCgnLCcpLm1hcCh2YWx1ZSA9PiBOdW1iZXIucGFyc2VJbnQodmFsdWUsIDEwKSk7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2Zmc2V0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gcG9wcGVyRGF0YSA9PiBvZmZzZXQocG9wcGVyRGF0YSwgdGhpcy5fZWxlbWVudCk7XG4gICAgfVxuICAgIHJldHVybiBvZmZzZXQ7XG4gIH1cbiAgX3Jlc29sdmVQb3NzaWJsZUZ1bmN0aW9uKGFyZykge1xuICAgIHJldHVybiBleGVjdXRlKGFyZywgW3RoaXMuX2VsZW1lbnRdKTtcbiAgfVxuICBfZ2V0UG9wcGVyQ29uZmlnKGF0dGFjaG1lbnQpIHtcbiAgICBjb25zdCBkZWZhdWx0QnNQb3BwZXJDb25maWcgPSB7XG4gICAgICBwbGFjZW1lbnQ6IGF0dGFjaG1lbnQsXG4gICAgICBtb2RpZmllcnM6IFt7XG4gICAgICAgIG5hbWU6ICdmbGlwJyxcbiAgICAgICAgb3B0aW9uczoge1xuICAgICAgICAgIGZhbGxiYWNrUGxhY2VtZW50czogdGhpcy5fY29uZmlnLmZhbGxiYWNrUGxhY2VtZW50c1xuICAgICAgICB9XG4gICAgICB9LCB7XG4gICAgICAgIG5hbWU6ICdvZmZzZXQnLFxuICAgICAgICBvcHRpb25zOiB7XG4gICAgICAgICAgb2Zmc2V0OiB0aGlzLl9nZXRPZmZzZXQoKVxuICAgICAgICB9XG4gICAgICB9LCB7XG4gICAgICAgIG5hbWU6ICdwcmV2ZW50T3ZlcmZsb3cnLFxuICAgICAgICBvcHRpb25zOiB7XG4gICAgICAgICAgYm91bmRhcnk6IHRoaXMuX2NvbmZpZy5ib3VuZGFyeVxuICAgICAgICB9XG4gICAgICB9LCB7XG4gICAgICAgIG5hbWU6ICdhcnJvdycsXG4gICAgICAgIG9wdGlvbnM6IHtcbiAgICAgICAgICBlbGVtZW50OiBgLiR7dGhpcy5jb25zdHJ1Y3Rvci5OQU1FfS1hcnJvd2BcbiAgICAgICAgfVxuICAgICAgfSwge1xuICAgICAgICBuYW1lOiAncHJlU2V0UGxhY2VtZW50JyxcbiAgICAgICAgZW5hYmxlZDogdHJ1ZSxcbiAgICAgICAgcGhhc2U6ICdiZWZvcmVNYWluJyxcbiAgICAgICAgZm46IGRhdGEgPT4ge1xuICAgICAgICAgIC8vIFByZS1zZXQgUG9wcGVyJ3MgcGxhY2VtZW50IGF0dHJpYnV0ZSBpbiBvcmRlciB0byByZWFkIHRoZSBhcnJvdyBzaXplcyBwcm9wZXJseS5cbiAgICAgICAgICAvLyBPdGhlcndpc2UsIFBvcHBlciBtaXhlcyB1cCB0aGUgd2lkdGggYW5kIGhlaWdodCBkaW1lbnNpb25zIHNpbmNlIHRoZSBpbml0aWFsIGFycm93IHN0eWxlIGlzIGZvciB0b3AgcGxhY2VtZW50XG4gICAgICAgICAgdGhpcy5fZ2V0VGlwRWxlbWVudCgpLnNldEF0dHJpYnV0ZSgnZGF0YS1wb3BwZXItcGxhY2VtZW50JywgZGF0YS5zdGF0ZS5wbGFjZW1lbnQpO1xuICAgICAgICB9XG4gICAgICB9XVxuICAgIH07XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLmRlZmF1bHRCc1BvcHBlckNvbmZpZyxcbiAgICAgIC4uLmV4ZWN1dGUodGhpcy5fY29uZmlnLnBvcHBlckNvbmZpZywgW2RlZmF1bHRCc1BvcHBlckNvbmZpZ10pXG4gICAgfTtcbiAgfVxuICBfc2V0TGlzdGVuZXJzKCkge1xuICAgIGNvbnN0IHRyaWdnZXJzID0gdGhpcy5fY29uZmlnLnRyaWdnZXIuc3BsaXQoJyAnKTtcbiAgICBmb3IgKGNvbnN0IHRyaWdnZXIgb2YgdHJpZ2dlcnMpIHtcbiAgICAgIGlmICh0cmlnZ2VyID09PSAnY2xpY2snKSB7XG4gICAgICAgIEV2ZW50SGFuZGxlci5vbih0aGlzLl9lbGVtZW50LCB0aGlzLmNvbnN0cnVjdG9yLmV2ZW50TmFtZShFVkVOVF9DTElDSyQxKSwgdGhpcy5fY29uZmlnLnNlbGVjdG9yLCBldmVudCA9PiB7XG4gICAgICAgICAgY29uc3QgY29udGV4dCA9IHRoaXMuX2luaXRpYWxpemVPbkRlbGVnYXRlZFRhcmdldChldmVudCk7XG4gICAgICAgICAgY29udGV4dC50b2dnbGUoKTtcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2UgaWYgKHRyaWdnZXIgIT09IFRSSUdHRVJfTUFOVUFMKSB7XG4gICAgICAgIGNvbnN0IGV2ZW50SW4gPSB0cmlnZ2VyID09PSBUUklHR0VSX0hPVkVSID8gdGhpcy5jb25zdHJ1Y3Rvci5ldmVudE5hbWUoRVZFTlRfTU9VU0VFTlRFUikgOiB0aGlzLmNvbnN0cnVjdG9yLmV2ZW50TmFtZShFVkVOVF9GT0NVU0lOJDEpO1xuICAgICAgICBjb25zdCBldmVudE91dCA9IHRyaWdnZXIgPT09IFRSSUdHRVJfSE9WRVIgPyB0aGlzLmNvbnN0cnVjdG9yLmV2ZW50TmFtZShFVkVOVF9NT1VTRUxFQVZFKSA6IHRoaXMuY29uc3RydWN0b3IuZXZlbnROYW1lKEVWRU5UX0ZPQ1VTT1VUJDEpO1xuICAgICAgICBFdmVudEhhbmRsZXIub24odGhpcy5fZWxlbWVudCwgZXZlbnRJbiwgdGhpcy5fY29uZmlnLnNlbGVjdG9yLCBldmVudCA9PiB7XG4gICAgICAgICAgY29uc3QgY29udGV4dCA9IHRoaXMuX2luaXRpYWxpemVPbkRlbGVnYXRlZFRhcmdldChldmVudCk7XG4gICAgICAgICAgY29udGV4dC5fYWN0aXZlVHJpZ2dlcltldmVudC50eXBlID09PSAnZm9jdXNpbicgPyBUUklHR0VSX0ZPQ1VTIDogVFJJR0dFUl9IT1ZFUl0gPSB0cnVlO1xuICAgICAgICAgIGNvbnRleHQuX2VudGVyKCk7XG4gICAgICAgIH0pO1xuICAgICAgICBFdmVudEhhbmRsZXIub24odGhpcy5fZWxlbWVudCwgZXZlbnRPdXQsIHRoaXMuX2NvbmZpZy5zZWxlY3RvciwgZXZlbnQgPT4ge1xuICAgICAgICAgIGNvbnN0IGNvbnRleHQgPSB0aGlzLl9pbml0aWFsaXplT25EZWxlZ2F0ZWRUYXJnZXQoZXZlbnQpO1xuICAgICAgICAgIGNvbnRleHQuX2FjdGl2ZVRyaWdnZXJbZXZlbnQudHlwZSA9PT0gJ2ZvY3Vzb3V0JyA/IFRSSUdHRVJfRk9DVVMgOiBUUklHR0VSX0hPVkVSXSA9IGNvbnRleHQuX2VsZW1lbnQuY29udGFpbnMoZXZlbnQucmVsYXRlZFRhcmdldCk7XG4gICAgICAgICAgY29udGV4dC5fbGVhdmUoKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMuX2hpZGVNb2RhbEhhbmRsZXIgPSAoKSA9PiB7XG4gICAgICBpZiAodGhpcy5fZWxlbWVudCkge1xuICAgICAgICB0aGlzLmhpZGUoKTtcbiAgICAgIH1cbiAgICB9O1xuICAgIEV2ZW50SGFuZGxlci5vbih0aGlzLl9lbGVtZW50LmNsb3Nlc3QoU0VMRUNUT1JfTU9EQUwpLCBFVkVOVF9NT0RBTF9ISURFLCB0aGlzLl9oaWRlTW9kYWxIYW5kbGVyKTtcbiAgfVxuICBfZml4VGl0bGUoKSB7XG4gICAgY29uc3QgdGl0bGUgPSB0aGlzLl9lbGVtZW50LmdldEF0dHJpYnV0ZSgndGl0bGUnKTtcbiAgICBpZiAoIXRpdGxlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICghdGhpcy5fZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2FyaWEtbGFiZWwnKSAmJiAhdGhpcy5fZWxlbWVudC50ZXh0Q29udGVudC50cmltKCkpIHtcbiAgICAgIHRoaXMuX2VsZW1lbnQuc2V0QXR0cmlidXRlKCdhcmlhLWxhYmVsJywgdGl0bGUpO1xuICAgIH1cbiAgICB0aGlzLl9lbGVtZW50LnNldEF0dHJpYnV0ZSgnZGF0YS1icy1vcmlnaW5hbC10aXRsZScsIHRpdGxlKTsgLy8gRE8gTk9UIFVTRSBJVC4gSXMgb25seSBmb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHlcbiAgICB0aGlzLl9lbGVtZW50LnJlbW92ZUF0dHJpYnV0ZSgndGl0bGUnKTtcbiAgfVxuICBfZW50ZXIoKSB7XG4gICAgaWYgKHRoaXMuX2lzU2hvd24oKSB8fCB0aGlzLl9pc0hvdmVyZWQpIHtcbiAgICAgIHRoaXMuX2lzSG92ZXJlZCA9IHRydWU7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuX2lzSG92ZXJlZCA9IHRydWU7XG4gICAgdGhpcy5fc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBpZiAodGhpcy5faXNIb3ZlcmVkKSB7XG4gICAgICAgIHRoaXMuc2hvdygpO1xuICAgICAgfVxuICAgIH0sIHRoaXMuX2NvbmZpZy5kZWxheS5zaG93KTtcbiAgfVxuICBfbGVhdmUoKSB7XG4gICAgaWYgKHRoaXMuX2lzV2l0aEFjdGl2ZVRyaWdnZXIoKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLl9pc0hvdmVyZWQgPSBmYWxzZTtcbiAgICB0aGlzLl9zZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGlmICghdGhpcy5faXNIb3ZlcmVkKSB7XG4gICAgICAgIHRoaXMuaGlkZSgpO1xuICAgICAgfVxuICAgIH0sIHRoaXMuX2NvbmZpZy5kZWxheS5oaWRlKTtcbiAgfVxuICBfc2V0VGltZW91dChoYW5kbGVyLCB0aW1lb3V0KSB7XG4gICAgY2xlYXJUaW1lb3V0KHRoaXMuX3RpbWVvdXQpO1xuICAgIHRoaXMuX3RpbWVvdXQgPSBzZXRUaW1lb3V0KGhhbmRsZXIsIHRpbWVvdXQpO1xuICB9XG4gIF9pc1dpdGhBY3RpdmVUcmlnZ2VyKCkge1xuICAgIHJldHVybiBPYmplY3QudmFsdWVzKHRoaXMuX2FjdGl2ZVRyaWdnZXIpLmluY2x1ZGVzKHRydWUpO1xuICB9XG4gIF9nZXRDb25maWcoY29uZmlnKSB7XG4gICAgY29uc3QgZGF0YUF0dHJpYnV0ZXMgPSBNYW5pcHVsYXRvci5nZXREYXRhQXR0cmlidXRlcyh0aGlzLl9lbGVtZW50KTtcbiAgICBmb3IgKGNvbnN0IGRhdGFBdHRyaWJ1dGUgb2YgT2JqZWN0LmtleXMoZGF0YUF0dHJpYnV0ZXMpKSB7XG4gICAgICBpZiAoRElTQUxMT1dFRF9BVFRSSUJVVEVTLmhhcyhkYXRhQXR0cmlidXRlKSkge1xuICAgICAgICBkZWxldGUgZGF0YUF0dHJpYnV0ZXNbZGF0YUF0dHJpYnV0ZV07XG4gICAgICB9XG4gICAgfVxuICAgIGNvbmZpZyA9IHtcbiAgICAgIC4uLmRhdGFBdHRyaWJ1dGVzLFxuICAgICAgLi4uKHR5cGVvZiBjb25maWcgPT09ICdvYmplY3QnICYmIGNvbmZpZyA/IGNvbmZpZyA6IHt9KVxuICAgIH07XG4gICAgY29uZmlnID0gdGhpcy5fbWVyZ2VDb25maWdPYmooY29uZmlnKTtcbiAgICBjb25maWcgPSB0aGlzLl9jb25maWdBZnRlck1lcmdlKGNvbmZpZyk7XG4gICAgdGhpcy5fdHlwZUNoZWNrQ29uZmlnKGNvbmZpZyk7XG4gICAgcmV0dXJuIGNvbmZpZztcbiAgfVxuICBfY29uZmlnQWZ0ZXJNZXJnZShjb25maWcpIHtcbiAgICBjb25maWcuY29udGFpbmVyID0gY29uZmlnLmNvbnRhaW5lciA9PT0gZmFsc2UgPyBkb2N1bWVudC5ib2R5IDogZ2V0RWxlbWVudChjb25maWcuY29udGFpbmVyKTtcbiAgICBpZiAodHlwZW9mIGNvbmZpZy5kZWxheSA9PT0gJ251bWJlcicpIHtcbiAgICAgIGNvbmZpZy5kZWxheSA9IHtcbiAgICAgICAgc2hvdzogY29uZmlnLmRlbGF5LFxuICAgICAgICBoaWRlOiBjb25maWcuZGVsYXlcbiAgICAgIH07XG4gICAgfVxuICAgIGlmICh0eXBlb2YgY29uZmlnLnRpdGxlID09PSAnbnVtYmVyJykge1xuICAgICAgY29uZmlnLnRpdGxlID0gY29uZmlnLnRpdGxlLnRvU3RyaW5nKCk7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgY29uZmlnLmNvbnRlbnQgPT09ICdudW1iZXInKSB7XG4gICAgICBjb25maWcuY29udGVudCA9IGNvbmZpZy5jb250ZW50LnRvU3RyaW5nKCk7XG4gICAgfVxuICAgIHJldHVybiBjb25maWc7XG4gIH1cbiAgX2dldERlbGVnYXRlQ29uZmlnKCkge1xuICAgIGNvbnN0IGNvbmZpZyA9IHt9O1xuICAgIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKHRoaXMuX2NvbmZpZykpIHtcbiAgICAgIGlmICh0aGlzLmNvbnN0cnVjdG9yLkRlZmF1bHRba2V5XSAhPT0gdmFsdWUpIHtcbiAgICAgICAgY29uZmlnW2tleV0gPSB2YWx1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgY29uZmlnLnNlbGVjdG9yID0gZmFsc2U7XG4gICAgY29uZmlnLnRyaWdnZXIgPSAnbWFudWFsJztcblxuICAgIC8vIEluIHRoZSBmdXR1cmUgY2FuIGJlIHJlcGxhY2VkIHdpdGg6XG4gICAgLy8gY29uc3Qga2V5c1dpdGhEaWZmZXJlbnRWYWx1ZXMgPSBPYmplY3QuZW50cmllcyh0aGlzLl9jb25maWcpLmZpbHRlcihlbnRyeSA9PiB0aGlzLmNvbnN0cnVjdG9yLkRlZmF1bHRbZW50cnlbMF1dICE9PSB0aGlzLl9jb25maWdbZW50cnlbMF1dKVxuICAgIC8vIGBPYmplY3QuZnJvbUVudHJpZXMoa2V5c1dpdGhEaWZmZXJlbnRWYWx1ZXMpYFxuICAgIHJldHVybiBjb25maWc7XG4gIH1cbiAgX2Rpc3Bvc2VQb3BwZXIoKSB7XG4gICAgaWYgKHRoaXMuX3BvcHBlcikge1xuICAgICAgdGhpcy5fcG9wcGVyLmRlc3Ryb3koKTtcbiAgICAgIHRoaXMuX3BvcHBlciA9IG51bGw7XG4gICAgfVxuICAgIGlmICh0aGlzLnRpcCkge1xuICAgICAgdGhpcy50aXAucmVtb3ZlKCk7XG4gICAgICB0aGlzLnRpcCA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgLy8gU3RhdGljXG4gIHN0YXRpYyBqUXVlcnlJbnRlcmZhY2UoY29uZmlnKSB7XG4gICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBkYXRhID0gVG9vbHRpcC5nZXRPckNyZWF0ZUluc3RhbmNlKHRoaXMsIGNvbmZpZyk7XG4gICAgICBpZiAodHlwZW9mIGNvbmZpZyAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiBkYXRhW2NvbmZpZ10gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYE5vIG1ldGhvZCBuYW1lZCBcIiR7Y29uZmlnfVwiYCk7XG4gICAgICB9XG4gICAgICBkYXRhW2NvbmZpZ10oKTtcbiAgICB9KTtcbiAgfVxufVxuXG4vKipcbiAqIGpRdWVyeVxuICovXG5cbmRlZmluZUpRdWVyeVBsdWdpbihUb29sdGlwKTtcblxuLyoqXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogQm9vdHN0cmFwIHBvcG92ZXIuanNcbiAqIExpY2Vuc2VkIHVuZGVyIE1JVCAoaHR0cHM6Ly9naXRodWIuY29tL3R3YnMvYm9vdHN0cmFwL2Jsb2IvbWFpbi9MSUNFTlNFKVxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqL1xuXG5cbi8qKlxuICogQ29uc3RhbnRzXG4gKi9cblxuY29uc3QgTkFNRSQzID0gJ3BvcG92ZXInO1xuY29uc3QgU0VMRUNUT1JfVElUTEUgPSAnLnBvcG92ZXItaGVhZGVyJztcbmNvbnN0IFNFTEVDVE9SX0NPTlRFTlQgPSAnLnBvcG92ZXItYm9keSc7XG5jb25zdCBEZWZhdWx0JDIgPSB7XG4gIC4uLlRvb2x0aXAuRGVmYXVsdCxcbiAgY29udGVudDogJycsXG4gIG9mZnNldDogWzAsIDhdLFxuICBwbGFjZW1lbnQ6ICdyaWdodCcsXG4gIHRlbXBsYXRlOiAnPGRpdiBjbGFzcz1cInBvcG92ZXJcIiByb2xlPVwidG9vbHRpcFwiPicgKyAnPGRpdiBjbGFzcz1cInBvcG92ZXItYXJyb3dcIj48L2Rpdj4nICsgJzxoMyBjbGFzcz1cInBvcG92ZXItaGVhZGVyXCI+PC9oMz4nICsgJzxkaXYgY2xhc3M9XCJwb3BvdmVyLWJvZHlcIj48L2Rpdj4nICsgJzwvZGl2PicsXG4gIHRyaWdnZXI6ICdjbGljaydcbn07XG5jb25zdCBEZWZhdWx0VHlwZSQyID0ge1xuICAuLi5Ub29sdGlwLkRlZmF1bHRUeXBlLFxuICBjb250ZW50OiAnKG51bGx8c3RyaW5nfGVsZW1lbnR8ZnVuY3Rpb24pJ1xufTtcblxuLyoqXG4gKiBDbGFzcyBkZWZpbml0aW9uXG4gKi9cblxuY2xhc3MgUG9wb3ZlciBleHRlbmRzIFRvb2x0aXAge1xuICAvLyBHZXR0ZXJzXG4gIHN0YXRpYyBnZXQgRGVmYXVsdCgpIHtcbiAgICByZXR1cm4gRGVmYXVsdCQyO1xuICB9XG4gIHN0YXRpYyBnZXQgRGVmYXVsdFR5cGUoKSB7XG4gICAgcmV0dXJuIERlZmF1bHRUeXBlJDI7XG4gIH1cbiAgc3RhdGljIGdldCBOQU1FKCkge1xuICAgIHJldHVybiBOQU1FJDM7XG4gIH1cblxuICAvLyBPdmVycmlkZXNcbiAgX2lzV2l0aENvbnRlbnQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2dldFRpdGxlKCkgfHwgdGhpcy5fZ2V0Q29udGVudCgpO1xuICB9XG5cbiAgLy8gUHJpdmF0ZVxuICBfZ2V0Q29udGVudEZvclRlbXBsYXRlKCkge1xuICAgIHJldHVybiB7XG4gICAgICBbU0VMRUNUT1JfVElUTEVdOiB0aGlzLl9nZXRUaXRsZSgpLFxuICAgICAgW1NFTEVDVE9SX0NPTlRFTlRdOiB0aGlzLl9nZXRDb250ZW50KClcbiAgICB9O1xuICB9XG4gIF9nZXRDb250ZW50KCkge1xuICAgIHJldHVybiB0aGlzLl9yZXNvbHZlUG9zc2libGVGdW5jdGlvbih0aGlzLl9jb25maWcuY29udGVudCk7XG4gIH1cblxuICAvLyBTdGF0aWNcbiAgc3RhdGljIGpRdWVyeUludGVyZmFjZShjb25maWcpIHtcbiAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGRhdGEgPSBQb3BvdmVyLmdldE9yQ3JlYXRlSW5zdGFuY2UodGhpcywgY29uZmlnKTtcbiAgICAgIGlmICh0eXBlb2YgY29uZmlnICE9PSAnc3RyaW5nJykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAodHlwZW9mIGRhdGFbY29uZmlnXSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgTm8gbWV0aG9kIG5hbWVkIFwiJHtjb25maWd9XCJgKTtcbiAgICAgIH1cbiAgICAgIGRhdGFbY29uZmlnXSgpO1xuICAgIH0pO1xuICB9XG59XG5cbi8qKlxuICogalF1ZXJ5XG4gKi9cblxuZGVmaW5lSlF1ZXJ5UGx1Z2luKFBvcG92ZXIpO1xuXG4vKipcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiBCb290c3RyYXAgc2Nyb2xsc3B5LmpzXG4gKiBMaWNlbnNlZCB1bmRlciBNSVQgKGh0dHBzOi8vZ2l0aHViLmNvbS90d2JzL2Jvb3RzdHJhcC9ibG9iL21haW4vTElDRU5TRSlcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKi9cblxuXG4vKipcbiAqIENvbnN0YW50c1xuICovXG5cbmNvbnN0IE5BTUUkMiA9ICdzY3JvbGxzcHknO1xuY29uc3QgREFUQV9LRVkkMiA9ICdicy5zY3JvbGxzcHknO1xuY29uc3QgRVZFTlRfS0VZJDIgPSBgLiR7REFUQV9LRVkkMn1gO1xuY29uc3QgREFUQV9BUElfS0VZID0gJy5kYXRhLWFwaSc7XG5jb25zdCBFVkVOVF9BQ1RJVkFURSA9IGBhY3RpdmF0ZSR7RVZFTlRfS0VZJDJ9YDtcbmNvbnN0IEVWRU5UX0NMSUNLID0gYGNsaWNrJHtFVkVOVF9LRVkkMn1gO1xuY29uc3QgRVZFTlRfTE9BRF9EQVRBX0FQSSQxID0gYGxvYWQke0VWRU5UX0tFWSQyfSR7REFUQV9BUElfS0VZfWA7XG5jb25zdCBDTEFTU19OQU1FX0RST1BET1dOX0lURU0gPSAnZHJvcGRvd24taXRlbSc7XG5jb25zdCBDTEFTU19OQU1FX0FDVElWRSQxID0gJ2FjdGl2ZSc7XG5jb25zdCBTRUxFQ1RPUl9EQVRBX1NQWSA9ICdbZGF0YS1icy1zcHk9XCJzY3JvbGxcIl0nO1xuY29uc3QgU0VMRUNUT1JfVEFSR0VUX0xJTktTID0gJ1tocmVmXSc7XG5jb25zdCBTRUxFQ1RPUl9OQVZfTElTVF9HUk9VUCA9ICcubmF2LCAubGlzdC1ncm91cCc7XG5jb25zdCBTRUxFQ1RPUl9OQVZfTElOS1MgPSAnLm5hdi1saW5rJztcbmNvbnN0IFNFTEVDVE9SX05BVl9JVEVNUyA9ICcubmF2LWl0ZW0nO1xuY29uc3QgU0VMRUNUT1JfTElTVF9JVEVNUyA9ICcubGlzdC1ncm91cC1pdGVtJztcbmNvbnN0IFNFTEVDVE9SX0xJTktfSVRFTVMgPSBgJHtTRUxFQ1RPUl9OQVZfTElOS1N9LCAke1NFTEVDVE9SX05BVl9JVEVNU30gPiAke1NFTEVDVE9SX05BVl9MSU5LU30sICR7U0VMRUNUT1JfTElTVF9JVEVNU31gO1xuY29uc3QgU0VMRUNUT1JfRFJPUERPV04gPSAnLmRyb3Bkb3duJztcbmNvbnN0IFNFTEVDVE9SX0RST1BET1dOX1RPR0dMRSQxID0gJy5kcm9wZG93bi10b2dnbGUnO1xuY29uc3QgRGVmYXVsdCQxID0ge1xuICBvZmZzZXQ6IG51bGwsXG4gIC8vIFRPRE86IHY2IEBkZXByZWNhdGVkLCBrZWVwIGl0IGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSByZWFzb25zXG4gIHJvb3RNYXJnaW46ICcwcHggMHB4IC0yNSUnLFxuICBzbW9vdGhTY3JvbGw6IGZhbHNlLFxuICB0YXJnZXQ6IG51bGwsXG4gIHRocmVzaG9sZDogWzAuMSwgMC41LCAxXVxufTtcbmNvbnN0IERlZmF1bHRUeXBlJDEgPSB7XG4gIG9mZnNldDogJyhudW1iZXJ8bnVsbCknLFxuICAvLyBUT0RPIHY2IEBkZXByZWNhdGVkLCBrZWVwIGl0IGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSByZWFzb25zXG4gIHJvb3RNYXJnaW46ICdzdHJpbmcnLFxuICBzbW9vdGhTY3JvbGw6ICdib29sZWFuJyxcbiAgdGFyZ2V0OiAnZWxlbWVudCcsXG4gIHRocmVzaG9sZDogJ2FycmF5J1xufTtcblxuLyoqXG4gKiBDbGFzcyBkZWZpbml0aW9uXG4gKi9cblxuY2xhc3MgU2Nyb2xsU3B5IGV4dGVuZHMgQmFzZUNvbXBvbmVudCB7XG4gIGNvbnN0cnVjdG9yKGVsZW1lbnQsIGNvbmZpZykge1xuICAgIHN1cGVyKGVsZW1lbnQsIGNvbmZpZyk7XG5cbiAgICAvLyB0aGlzLl9lbGVtZW50IGlzIHRoZSBvYnNlcnZhYmxlc0NvbnRhaW5lciBhbmQgY29uZmlnLnRhcmdldCB0aGUgbWVudSBsaW5rcyB3cmFwcGVyXG4gICAgdGhpcy5fdGFyZ2V0TGlua3MgPSBuZXcgTWFwKCk7XG4gICAgdGhpcy5fb2JzZXJ2YWJsZVNlY3Rpb25zID0gbmV3IE1hcCgpO1xuICAgIHRoaXMuX3Jvb3RFbGVtZW50ID0gZ2V0Q29tcHV0ZWRTdHlsZSh0aGlzLl9lbGVtZW50KS5vdmVyZmxvd1kgPT09ICd2aXNpYmxlJyA/IG51bGwgOiB0aGlzLl9lbGVtZW50O1xuICAgIHRoaXMuX2FjdGl2ZVRhcmdldCA9IG51bGw7XG4gICAgdGhpcy5fb2JzZXJ2ZXIgPSBudWxsO1xuICAgIHRoaXMuX3ByZXZpb3VzU2Nyb2xsRGF0YSA9IHtcbiAgICAgIHZpc2libGVFbnRyeVRvcDogMCxcbiAgICAgIHBhcmVudFNjcm9sbFRvcDogMFxuICAgIH07XG4gICAgdGhpcy5yZWZyZXNoKCk7IC8vIGluaXRpYWxpemVcbiAgfVxuXG4gIC8vIEdldHRlcnNcbiAgc3RhdGljIGdldCBEZWZhdWx0KCkge1xuICAgIHJldHVybiBEZWZhdWx0JDE7XG4gIH1cbiAgc3RhdGljIGdldCBEZWZhdWx0VHlwZSgpIHtcbiAgICByZXR1cm4gRGVmYXVsdFR5cGUkMTtcbiAgfVxuICBzdGF0aWMgZ2V0IE5BTUUoKSB7XG4gICAgcmV0dXJuIE5BTUUkMjtcbiAgfVxuXG4gIC8vIFB1YmxpY1xuICByZWZyZXNoKCkge1xuICAgIHRoaXMuX2luaXRpYWxpemVUYXJnZXRzQW5kT2JzZXJ2YWJsZXMoKTtcbiAgICB0aGlzLl9tYXliZUVuYWJsZVNtb290aFNjcm9sbCgpO1xuICAgIGlmICh0aGlzLl9vYnNlcnZlcikge1xuICAgICAgdGhpcy5fb2JzZXJ2ZXIuZGlzY29ubmVjdCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9vYnNlcnZlciA9IHRoaXMuX2dldE5ld09ic2VydmVyKCk7XG4gICAgfVxuICAgIGZvciAoY29uc3Qgc2VjdGlvbiBvZiB0aGlzLl9vYnNlcnZhYmxlU2VjdGlvbnMudmFsdWVzKCkpIHtcbiAgICAgIHRoaXMuX29ic2VydmVyLm9ic2VydmUoc2VjdGlvbik7XG4gICAgfVxuICB9XG4gIGRpc3Bvc2UoKSB7XG4gICAgdGhpcy5fb2JzZXJ2ZXIuZGlzY29ubmVjdCgpO1xuICAgIHN1cGVyLmRpc3Bvc2UoKTtcbiAgfVxuXG4gIC8vIFByaXZhdGVcbiAgX2NvbmZpZ0FmdGVyTWVyZ2UoY29uZmlnKSB7XG4gICAgLy8gVE9ETzogb24gdjYgdGFyZ2V0IHNob3VsZCBiZSBnaXZlbiBleHBsaWNpdGx5ICYgcmVtb3ZlIHRoZSB7dGFyZ2V0OiAnc3MtdGFyZ2V0J30gY2FzZVxuICAgIGNvbmZpZy50YXJnZXQgPSBnZXRFbGVtZW50KGNvbmZpZy50YXJnZXQpIHx8IGRvY3VtZW50LmJvZHk7XG5cbiAgICAvLyBUT0RPOiB2NiBPbmx5IGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSByZWFzb25zLiBVc2Ugcm9vdE1hcmdpbiBvbmx5XG4gICAgY29uZmlnLnJvb3RNYXJnaW4gPSBjb25maWcub2Zmc2V0ID8gYCR7Y29uZmlnLm9mZnNldH1weCAwcHggLTMwJWAgOiBjb25maWcucm9vdE1hcmdpbjtcbiAgICBpZiAodHlwZW9mIGNvbmZpZy50aHJlc2hvbGQgPT09ICdzdHJpbmcnKSB7XG4gICAgICBjb25maWcudGhyZXNob2xkID0gY29uZmlnLnRocmVzaG9sZC5zcGxpdCgnLCcpLm1hcCh2YWx1ZSA9PiBOdW1iZXIucGFyc2VGbG9hdCh2YWx1ZSkpO1xuICAgIH1cbiAgICByZXR1cm4gY29uZmlnO1xuICB9XG4gIF9tYXliZUVuYWJsZVNtb290aFNjcm9sbCgpIHtcbiAgICBpZiAoIXRoaXMuX2NvbmZpZy5zbW9vdGhTY3JvbGwpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyB1bnJlZ2lzdGVyIGFueSBwcmV2aW91cyBsaXN0ZW5lcnNcbiAgICBFdmVudEhhbmRsZXIub2ZmKHRoaXMuX2NvbmZpZy50YXJnZXQsIEVWRU5UX0NMSUNLKTtcbiAgICBFdmVudEhhbmRsZXIub24odGhpcy5fY29uZmlnLnRhcmdldCwgRVZFTlRfQ0xJQ0ssIFNFTEVDVE9SX1RBUkdFVF9MSU5LUywgZXZlbnQgPT4ge1xuICAgICAgY29uc3Qgb2JzZXJ2YWJsZVNlY3Rpb24gPSB0aGlzLl9vYnNlcnZhYmxlU2VjdGlvbnMuZ2V0KGV2ZW50LnRhcmdldC5oYXNoKTtcbiAgICAgIGlmIChvYnNlcnZhYmxlU2VjdGlvbikge1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBjb25zdCByb290ID0gdGhpcy5fcm9vdEVsZW1lbnQgfHwgd2luZG93O1xuICAgICAgICBjb25zdCBoZWlnaHQgPSBvYnNlcnZhYmxlU2VjdGlvbi5vZmZzZXRUb3AgLSB0aGlzLl9lbGVtZW50Lm9mZnNldFRvcDtcbiAgICAgICAgaWYgKHJvb3Quc2Nyb2xsVG8pIHtcbiAgICAgICAgICByb290LnNjcm9sbFRvKHtcbiAgICAgICAgICAgIHRvcDogaGVpZ2h0LFxuICAgICAgICAgICAgYmVoYXZpb3I6ICdzbW9vdGgnXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ2hyb21lIDYwIGRvZXNuJ3Qgc3VwcG9ydCBgc2Nyb2xsVG9gXG4gICAgICAgIHJvb3Quc2Nyb2xsVG9wID0gaGVpZ2h0O1xuICAgICAgfVxuICAgIH0pO1xuICB9XG4gIF9nZXROZXdPYnNlcnZlcigpIHtcbiAgICBjb25zdCBvcHRpb25zID0ge1xuICAgICAgcm9vdDogdGhpcy5fcm9vdEVsZW1lbnQsXG4gICAgICB0aHJlc2hvbGQ6IHRoaXMuX2NvbmZpZy50aHJlc2hvbGQsXG4gICAgICByb290TWFyZ2luOiB0aGlzLl9jb25maWcucm9vdE1hcmdpblxuICAgIH07XG4gICAgcmV0dXJuIG5ldyBJbnRlcnNlY3Rpb25PYnNlcnZlcihlbnRyaWVzID0+IHRoaXMuX29ic2VydmVyQ2FsbGJhY2soZW50cmllcyksIG9wdGlvbnMpO1xuICB9XG5cbiAgLy8gVGhlIGxvZ2ljIG9mIHNlbGVjdGlvblxuICBfb2JzZXJ2ZXJDYWxsYmFjayhlbnRyaWVzKSB7XG4gICAgY29uc3QgdGFyZ2V0RWxlbWVudCA9IGVudHJ5ID0+IHRoaXMuX3RhcmdldExpbmtzLmdldChgIyR7ZW50cnkudGFyZ2V0LmlkfWApO1xuICAgIGNvbnN0IGFjdGl2YXRlID0gZW50cnkgPT4ge1xuICAgICAgdGhpcy5fcHJldmlvdXNTY3JvbGxEYXRhLnZpc2libGVFbnRyeVRvcCA9IGVudHJ5LnRhcmdldC5vZmZzZXRUb3A7XG4gICAgICB0aGlzLl9wcm9jZXNzKHRhcmdldEVsZW1lbnQoZW50cnkpKTtcbiAgICB9O1xuICAgIGNvbnN0IHBhcmVudFNjcm9sbFRvcCA9ICh0aGlzLl9yb290RWxlbWVudCB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpLnNjcm9sbFRvcDtcbiAgICBjb25zdCB1c2VyU2Nyb2xsc0Rvd24gPSBwYXJlbnRTY3JvbGxUb3AgPj0gdGhpcy5fcHJldmlvdXNTY3JvbGxEYXRhLnBhcmVudFNjcm9sbFRvcDtcbiAgICB0aGlzLl9wcmV2aW91c1Njcm9sbERhdGEucGFyZW50U2Nyb2xsVG9wID0gcGFyZW50U2Nyb2xsVG9wO1xuICAgIGZvciAoY29uc3QgZW50cnkgb2YgZW50cmllcykge1xuICAgICAgaWYgKCFlbnRyeS5pc0ludGVyc2VjdGluZykge1xuICAgICAgICB0aGlzLl9hY3RpdmVUYXJnZXQgPSBudWxsO1xuICAgICAgICB0aGlzLl9jbGVhckFjdGl2ZUNsYXNzKHRhcmdldEVsZW1lbnQoZW50cnkpKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBjb25zdCBlbnRyeUlzTG93ZXJUaGFuUHJldmlvdXMgPSBlbnRyeS50YXJnZXQub2Zmc2V0VG9wID49IHRoaXMuX3ByZXZpb3VzU2Nyb2xsRGF0YS52aXNpYmxlRW50cnlUb3A7XG4gICAgICAvLyBpZiB3ZSBhcmUgc2Nyb2xsaW5nIGRvd24sIHBpY2sgdGhlIGJpZ2dlciBvZmZzZXRUb3BcbiAgICAgIGlmICh1c2VyU2Nyb2xsc0Rvd24gJiYgZW50cnlJc0xvd2VyVGhhblByZXZpb3VzKSB7XG4gICAgICAgIGFjdGl2YXRlKGVudHJ5KTtcbiAgICAgICAgLy8gaWYgcGFyZW50IGlzbid0IHNjcm9sbGVkLCBsZXQncyBrZWVwIHRoZSBmaXJzdCB2aXNpYmxlIGl0ZW0sIGJyZWFraW5nIHRoZSBpdGVyYXRpb25cbiAgICAgICAgaWYgKCFwYXJlbnRTY3JvbGxUb3ApIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIGlmIHdlIGFyZSBzY3JvbGxpbmcgdXAsIHBpY2sgdGhlIHNtYWxsZXN0IG9mZnNldFRvcFxuICAgICAgaWYgKCF1c2VyU2Nyb2xsc0Rvd24gJiYgIWVudHJ5SXNMb3dlclRoYW5QcmV2aW91cykge1xuICAgICAgICBhY3RpdmF0ZShlbnRyeSk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIF9pbml0aWFsaXplVGFyZ2V0c0FuZE9ic2VydmFibGVzKCkge1xuICAgIHRoaXMuX3RhcmdldExpbmtzID0gbmV3IE1hcCgpO1xuICAgIHRoaXMuX29ic2VydmFibGVTZWN0aW9ucyA9IG5ldyBNYXAoKTtcbiAgICBjb25zdCB0YXJnZXRMaW5rcyA9IFNlbGVjdG9yRW5naW5lLmZpbmQoU0VMRUNUT1JfVEFSR0VUX0xJTktTLCB0aGlzLl9jb25maWcudGFyZ2V0KTtcbiAgICBmb3IgKGNvbnN0IGFuY2hvciBvZiB0YXJnZXRMaW5rcykge1xuICAgICAgLy8gZW5zdXJlIHRoYXQgdGhlIGFuY2hvciBoYXMgYW4gaWQgYW5kIGlzIG5vdCBkaXNhYmxlZFxuICAgICAgaWYgKCFhbmNob3IuaGFzaCB8fCBpc0Rpc2FibGVkKGFuY2hvcikpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBjb25zdCBvYnNlcnZhYmxlU2VjdGlvbiA9IFNlbGVjdG9yRW5naW5lLmZpbmRPbmUoZGVjb2RlVVJJKGFuY2hvci5oYXNoKSwgdGhpcy5fZWxlbWVudCk7XG5cbiAgICAgIC8vIGVuc3VyZSB0aGF0IHRoZSBvYnNlcnZhYmxlU2VjdGlvbiBleGlzdHMgJiBpcyB2aXNpYmxlXG4gICAgICBpZiAoaXNWaXNpYmxlKG9ic2VydmFibGVTZWN0aW9uKSkge1xuICAgICAgICB0aGlzLl90YXJnZXRMaW5rcy5zZXQoZGVjb2RlVVJJKGFuY2hvci5oYXNoKSwgYW5jaG9yKTtcbiAgICAgICAgdGhpcy5fb2JzZXJ2YWJsZVNlY3Rpb25zLnNldChhbmNob3IuaGFzaCwgb2JzZXJ2YWJsZVNlY3Rpb24pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBfcHJvY2Vzcyh0YXJnZXQpIHtcbiAgICBpZiAodGhpcy5fYWN0aXZlVGFyZ2V0ID09PSB0YXJnZXQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5fY2xlYXJBY3RpdmVDbGFzcyh0aGlzLl9jb25maWcudGFyZ2V0KTtcbiAgICB0aGlzLl9hY3RpdmVUYXJnZXQgPSB0YXJnZXQ7XG4gICAgdGFyZ2V0LmNsYXNzTGlzdC5hZGQoQ0xBU1NfTkFNRV9BQ1RJVkUkMSk7XG4gICAgdGhpcy5fYWN0aXZhdGVQYXJlbnRzKHRhcmdldCk7XG4gICAgRXZlbnRIYW5kbGVyLnRyaWdnZXIodGhpcy5fZWxlbWVudCwgRVZFTlRfQUNUSVZBVEUsIHtcbiAgICAgIHJlbGF0ZWRUYXJnZXQ6IHRhcmdldFxuICAgIH0pO1xuICB9XG4gIF9hY3RpdmF0ZVBhcmVudHModGFyZ2V0KSB7XG4gICAgLy8gQWN0aXZhdGUgZHJvcGRvd24gcGFyZW50c1xuICAgIGlmICh0YXJnZXQuY2xhc3NMaXN0LmNvbnRhaW5zKENMQVNTX05BTUVfRFJPUERPV05fSVRFTSkpIHtcbiAgICAgIFNlbGVjdG9yRW5naW5lLmZpbmRPbmUoU0VMRUNUT1JfRFJPUERPV05fVE9HR0xFJDEsIHRhcmdldC5jbG9zZXN0KFNFTEVDVE9SX0RST1BET1dOKSkuY2xhc3NMaXN0LmFkZChDTEFTU19OQU1FX0FDVElWRSQxKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZm9yIChjb25zdCBsaXN0R3JvdXAgb2YgU2VsZWN0b3JFbmdpbmUucGFyZW50cyh0YXJnZXQsIFNFTEVDVE9SX05BVl9MSVNUX0dST1VQKSkge1xuICAgICAgLy8gU2V0IHRyaWdnZXJlZCBsaW5rcyBwYXJlbnRzIGFzIGFjdGl2ZVxuICAgICAgLy8gV2l0aCBib3RoIDx1bD4gYW5kIDxuYXY+IG1hcmt1cCBhIHBhcmVudCBpcyB0aGUgcHJldmlvdXMgc2libGluZyBvZiBhbnkgbmF2IGFuY2VzdG9yXG4gICAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgU2VsZWN0b3JFbmdpbmUucHJldihsaXN0R3JvdXAsIFNFTEVDVE9SX0xJTktfSVRFTVMpKSB7XG4gICAgICAgIGl0ZW0uY2xhc3NMaXN0LmFkZChDTEFTU19OQU1FX0FDVElWRSQxKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgX2NsZWFyQWN0aXZlQ2xhc3MocGFyZW50KSB7XG4gICAgcGFyZW50LmNsYXNzTGlzdC5yZW1vdmUoQ0xBU1NfTkFNRV9BQ1RJVkUkMSk7XG4gICAgY29uc3QgYWN0aXZlTm9kZXMgPSBTZWxlY3RvckVuZ2luZS5maW5kKGAke1NFTEVDVE9SX1RBUkdFVF9MSU5LU30uJHtDTEFTU19OQU1FX0FDVElWRSQxfWAsIHBhcmVudCk7XG4gICAgZm9yIChjb25zdCBub2RlIG9mIGFjdGl2ZU5vZGVzKSB7XG4gICAgICBub2RlLmNsYXNzTGlzdC5yZW1vdmUoQ0xBU1NfTkFNRV9BQ1RJVkUkMSk7XG4gICAgfVxuICB9XG5cbiAgLy8gU3RhdGljXG4gIHN0YXRpYyBqUXVlcnlJbnRlcmZhY2UoY29uZmlnKSB7XG4gICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBkYXRhID0gU2Nyb2xsU3B5LmdldE9yQ3JlYXRlSW5zdGFuY2UodGhpcywgY29uZmlnKTtcbiAgICAgIGlmICh0eXBlb2YgY29uZmlnICE9PSAnc3RyaW5nJykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAoZGF0YVtjb25maWddID09PSB1bmRlZmluZWQgfHwgY29uZmlnLnN0YXJ0c1dpdGgoJ18nKSB8fCBjb25maWcgPT09ICdjb25zdHJ1Y3RvcicpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgTm8gbWV0aG9kIG5hbWVkIFwiJHtjb25maWd9XCJgKTtcbiAgICAgIH1cbiAgICAgIGRhdGFbY29uZmlnXSgpO1xuICAgIH0pO1xuICB9XG59XG5cbi8qKlxuICogRGF0YSBBUEkgaW1wbGVtZW50YXRpb25cbiAqL1xuXG5FdmVudEhhbmRsZXIub24od2luZG93LCBFVkVOVF9MT0FEX0RBVEFfQVBJJDEsICgpID0+IHtcbiAgZm9yIChjb25zdCBzcHkgb2YgU2VsZWN0b3JFbmdpbmUuZmluZChTRUxFQ1RPUl9EQVRBX1NQWSkpIHtcbiAgICBTY3JvbGxTcHkuZ2V0T3JDcmVhdGVJbnN0YW5jZShzcHkpO1xuICB9XG59KTtcblxuLyoqXG4gKiBqUXVlcnlcbiAqL1xuXG5kZWZpbmVKUXVlcnlQbHVnaW4oU2Nyb2xsU3B5KTtcblxuLyoqXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogQm9vdHN0cmFwIHRhYi5qc1xuICogTGljZW5zZWQgdW5kZXIgTUlUIChodHRwczovL2dpdGh1Yi5jb20vdHdicy9ib290c3RyYXAvYmxvYi9tYWluL0xJQ0VOU0UpXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICovXG5cblxuLyoqXG4gKiBDb25zdGFudHNcbiAqL1xuXG5jb25zdCBOQU1FJDEgPSAndGFiJztcbmNvbnN0IERBVEFfS0VZJDEgPSAnYnMudGFiJztcbmNvbnN0IEVWRU5UX0tFWSQxID0gYC4ke0RBVEFfS0VZJDF9YDtcbmNvbnN0IEVWRU5UX0hJREUkMSA9IGBoaWRlJHtFVkVOVF9LRVkkMX1gO1xuY29uc3QgRVZFTlRfSElEREVOJDEgPSBgaGlkZGVuJHtFVkVOVF9LRVkkMX1gO1xuY29uc3QgRVZFTlRfU0hPVyQxID0gYHNob3cke0VWRU5UX0tFWSQxfWA7XG5jb25zdCBFVkVOVF9TSE9XTiQxID0gYHNob3duJHtFVkVOVF9LRVkkMX1gO1xuY29uc3QgRVZFTlRfQ0xJQ0tfREFUQV9BUEkgPSBgY2xpY2ske0VWRU5UX0tFWSQxfWA7XG5jb25zdCBFVkVOVF9LRVlET1dOID0gYGtleWRvd24ke0VWRU5UX0tFWSQxfWA7XG5jb25zdCBFVkVOVF9MT0FEX0RBVEFfQVBJID0gYGxvYWQke0VWRU5UX0tFWSQxfWA7XG5jb25zdCBBUlJPV19MRUZUX0tFWSA9ICdBcnJvd0xlZnQnO1xuY29uc3QgQVJST1dfUklHSFRfS0VZID0gJ0Fycm93UmlnaHQnO1xuY29uc3QgQVJST1dfVVBfS0VZID0gJ0Fycm93VXAnO1xuY29uc3QgQVJST1dfRE9XTl9LRVkgPSAnQXJyb3dEb3duJztcbmNvbnN0IENMQVNTX05BTUVfQUNUSVZFID0gJ2FjdGl2ZSc7XG5jb25zdCBDTEFTU19OQU1FX0ZBREUkMSA9ICdmYWRlJztcbmNvbnN0IENMQVNTX05BTUVfU0hPVyQxID0gJ3Nob3cnO1xuY29uc3QgQ0xBU1NfRFJPUERPV04gPSAnZHJvcGRvd24nO1xuY29uc3QgU0VMRUNUT1JfRFJPUERPV05fVE9HR0xFID0gJy5kcm9wZG93bi10b2dnbGUnO1xuY29uc3QgU0VMRUNUT1JfRFJPUERPV05fTUVOVSA9ICcuZHJvcGRvd24tbWVudSc7XG5jb25zdCBOT1RfU0VMRUNUT1JfRFJPUERPV05fVE9HR0xFID0gJzpub3QoLmRyb3Bkb3duLXRvZ2dsZSknO1xuY29uc3QgU0VMRUNUT1JfVEFCX1BBTkVMID0gJy5saXN0LWdyb3VwLCAubmF2LCBbcm9sZT1cInRhYmxpc3RcIl0nO1xuY29uc3QgU0VMRUNUT1JfT1VURVIgPSAnLm5hdi1pdGVtLCAubGlzdC1ncm91cC1pdGVtJztcbmNvbnN0IFNFTEVDVE9SX0lOTkVSID0gYC5uYXYtbGluayR7Tk9UX1NFTEVDVE9SX0RST1BET1dOX1RPR0dMRX0sIC5saXN0LWdyb3VwLWl0ZW0ke05PVF9TRUxFQ1RPUl9EUk9QRE9XTl9UT0dHTEV9LCBbcm9sZT1cInRhYlwiXSR7Tk9UX1NFTEVDVE9SX0RST1BET1dOX1RPR0dMRX1gO1xuY29uc3QgU0VMRUNUT1JfREFUQV9UT0dHTEUgPSAnW2RhdGEtYnMtdG9nZ2xlPVwidGFiXCJdLCBbZGF0YS1icy10b2dnbGU9XCJwaWxsXCJdLCBbZGF0YS1icy10b2dnbGU9XCJsaXN0XCJdJzsgLy8gVE9ETzogY291bGQgb25seSBiZSBgdGFiYCBpbiB2NlxuY29uc3QgU0VMRUNUT1JfSU5ORVJfRUxFTSA9IGAke1NFTEVDVE9SX0lOTkVSfSwgJHtTRUxFQ1RPUl9EQVRBX1RPR0dMRX1gO1xuY29uc3QgU0VMRUNUT1JfREFUQV9UT0dHTEVfQUNUSVZFID0gYC4ke0NMQVNTX05BTUVfQUNUSVZFfVtkYXRhLWJzLXRvZ2dsZT1cInRhYlwiXSwgLiR7Q0xBU1NfTkFNRV9BQ1RJVkV9W2RhdGEtYnMtdG9nZ2xlPVwicGlsbFwiXSwgLiR7Q0xBU1NfTkFNRV9BQ1RJVkV9W2RhdGEtYnMtdG9nZ2xlPVwibGlzdFwiXWA7XG5cbi8qKlxuICogQ2xhc3MgZGVmaW5pdGlvblxuICovXG5cbmNsYXNzIFRhYiBleHRlbmRzIEJhc2VDb21wb25lbnQge1xuICBjb25zdHJ1Y3RvcihlbGVtZW50KSB7XG4gICAgc3VwZXIoZWxlbWVudCk7XG4gICAgdGhpcy5fcGFyZW50ID0gdGhpcy5fZWxlbWVudC5jbG9zZXN0KFNFTEVDVE9SX1RBQl9QQU5FTCk7XG4gICAgaWYgKCF0aGlzLl9wYXJlbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICAgIC8vIFRPRE86IHNob3VsZCB0aHJvdyBleGNlcHRpb24gaW4gdjZcbiAgICAgIC8vIHRocm93IG5ldyBUeXBlRXJyb3IoYCR7ZWxlbWVudC5vdXRlckhUTUx9IGhhcyBub3QgYSB2YWxpZCBwYXJlbnQgJHtTRUxFQ1RPUl9JTk5FUl9FTEVNfWApXG4gICAgfVxuXG4gICAgLy8gU2V0IHVwIGluaXRpYWwgYXJpYSBhdHRyaWJ1dGVzXG4gICAgdGhpcy5fc2V0SW5pdGlhbEF0dHJpYnV0ZXModGhpcy5fcGFyZW50LCB0aGlzLl9nZXRDaGlsZHJlbigpKTtcbiAgICBFdmVudEhhbmRsZXIub24odGhpcy5fZWxlbWVudCwgRVZFTlRfS0VZRE9XTiwgZXZlbnQgPT4gdGhpcy5fa2V5ZG93bihldmVudCkpO1xuICB9XG5cbiAgLy8gR2V0dGVyc1xuICBzdGF0aWMgZ2V0IE5BTUUoKSB7XG4gICAgcmV0dXJuIE5BTUUkMTtcbiAgfVxuXG4gIC8vIFB1YmxpY1xuICBzaG93KCkge1xuICAgIC8vIFNob3dzIHRoaXMgZWxlbSBhbmQgZGVhY3RpdmF0ZSB0aGUgYWN0aXZlIHNpYmxpbmcgaWYgZXhpc3RzXG4gICAgY29uc3QgaW5uZXJFbGVtID0gdGhpcy5fZWxlbWVudDtcbiAgICBpZiAodGhpcy5fZWxlbUlzQWN0aXZlKGlubmVyRWxlbSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBTZWFyY2ggZm9yIGFjdGl2ZSB0YWIgb24gc2FtZSBwYXJlbnQgdG8gZGVhY3RpdmF0ZSBpdFxuICAgIGNvbnN0IGFjdGl2ZSA9IHRoaXMuX2dldEFjdGl2ZUVsZW0oKTtcbiAgICBjb25zdCBoaWRlRXZlbnQgPSBhY3RpdmUgPyBFdmVudEhhbmRsZXIudHJpZ2dlcihhY3RpdmUsIEVWRU5UX0hJREUkMSwge1xuICAgICAgcmVsYXRlZFRhcmdldDogaW5uZXJFbGVtXG4gICAgfSkgOiBudWxsO1xuICAgIGNvbnN0IHNob3dFdmVudCA9IEV2ZW50SGFuZGxlci50cmlnZ2VyKGlubmVyRWxlbSwgRVZFTlRfU0hPVyQxLCB7XG4gICAgICByZWxhdGVkVGFyZ2V0OiBhY3RpdmVcbiAgICB9KTtcbiAgICBpZiAoc2hvd0V2ZW50LmRlZmF1bHRQcmV2ZW50ZWQgfHwgaGlkZUV2ZW50ICYmIGhpZGVFdmVudC5kZWZhdWx0UHJldmVudGVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuX2RlYWN0aXZhdGUoYWN0aXZlLCBpbm5lckVsZW0pO1xuICAgIHRoaXMuX2FjdGl2YXRlKGlubmVyRWxlbSwgYWN0aXZlKTtcbiAgfVxuXG4gIC8vIFByaXZhdGVcbiAgX2FjdGl2YXRlKGVsZW1lbnQsIHJlbGF0ZWRFbGVtKSB7XG4gICAgaWYgKCFlbGVtZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGVsZW1lbnQuY2xhc3NMaXN0LmFkZChDTEFTU19OQU1FX0FDVElWRSk7XG4gICAgdGhpcy5fYWN0aXZhdGUoU2VsZWN0b3JFbmdpbmUuZ2V0RWxlbWVudEZyb21TZWxlY3RvcihlbGVtZW50KSk7IC8vIFNlYXJjaCBhbmQgYWN0aXZhdGUvc2hvdyB0aGUgcHJvcGVyIHNlY3Rpb25cblxuICAgIGNvbnN0IGNvbXBsZXRlID0gKCkgPT4ge1xuICAgICAgaWYgKGVsZW1lbnQuZ2V0QXR0cmlidXRlKCdyb2xlJykgIT09ICd0YWInKSB7XG4gICAgICAgIGVsZW1lbnQuY2xhc3NMaXN0LmFkZChDTEFTU19OQU1FX1NIT1ckMSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGVsZW1lbnQucmVtb3ZlQXR0cmlidXRlKCd0YWJpbmRleCcpO1xuICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2FyaWEtc2VsZWN0ZWQnLCB0cnVlKTtcbiAgICAgIHRoaXMuX3RvZ2dsZURyb3BEb3duKGVsZW1lbnQsIHRydWUpO1xuICAgICAgRXZlbnRIYW5kbGVyLnRyaWdnZXIoZWxlbWVudCwgRVZFTlRfU0hPV04kMSwge1xuICAgICAgICByZWxhdGVkVGFyZ2V0OiByZWxhdGVkRWxlbVxuICAgICAgfSk7XG4gICAgfTtcbiAgICB0aGlzLl9xdWV1ZUNhbGxiYWNrKGNvbXBsZXRlLCBlbGVtZW50LCBlbGVtZW50LmNsYXNzTGlzdC5jb250YWlucyhDTEFTU19OQU1FX0ZBREUkMSkpO1xuICB9XG4gIF9kZWFjdGl2YXRlKGVsZW1lbnQsIHJlbGF0ZWRFbGVtKSB7XG4gICAgaWYgKCFlbGVtZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZShDTEFTU19OQU1FX0FDVElWRSk7XG4gICAgZWxlbWVudC5ibHVyKCk7XG4gICAgdGhpcy5fZGVhY3RpdmF0ZShTZWxlY3RvckVuZ2luZS5nZXRFbGVtZW50RnJvbVNlbGVjdG9yKGVsZW1lbnQpKTsgLy8gU2VhcmNoIGFuZCBkZWFjdGl2YXRlIHRoZSBzaG93biBzZWN0aW9uIHRvb1xuXG4gICAgY29uc3QgY29tcGxldGUgPSAoKSA9PiB7XG4gICAgICBpZiAoZWxlbWVudC5nZXRBdHRyaWJ1dGUoJ3JvbGUnKSAhPT0gJ3RhYicpIHtcbiAgICAgICAgZWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKENMQVNTX05BTUVfU0hPVyQxKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2FyaWEtc2VsZWN0ZWQnLCBmYWxzZSk7XG4gICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZSgndGFiaW5kZXgnLCAnLTEnKTtcbiAgICAgIHRoaXMuX3RvZ2dsZURyb3BEb3duKGVsZW1lbnQsIGZhbHNlKTtcbiAgICAgIEV2ZW50SGFuZGxlci50cmlnZ2VyKGVsZW1lbnQsIEVWRU5UX0hJRERFTiQxLCB7XG4gICAgICAgIHJlbGF0ZWRUYXJnZXQ6IHJlbGF0ZWRFbGVtXG4gICAgICB9KTtcbiAgICB9O1xuICAgIHRoaXMuX3F1ZXVlQ2FsbGJhY2soY29tcGxldGUsIGVsZW1lbnQsIGVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKENMQVNTX05BTUVfRkFERSQxKSk7XG4gIH1cbiAgX2tleWRvd24oZXZlbnQpIHtcbiAgICBpZiAoIVtBUlJPV19MRUZUX0tFWSwgQVJST1dfUklHSFRfS0VZLCBBUlJPV19VUF9LRVksIEFSUk9XX0RPV05fS0VZXS5pbmNsdWRlcyhldmVudC5rZXkpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpOyAvLyBzdG9wUHJvcGFnYXRpb24vcHJldmVudERlZmF1bHQgYm90aCBhZGRlZCB0byBzdXBwb3J0IHVwL2Rvd24ga2V5cyB3aXRob3V0IHNjcm9sbGluZyB0aGUgcGFnZVxuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgY29uc3QgaXNOZXh0ID0gW0FSUk9XX1JJR0hUX0tFWSwgQVJST1dfRE9XTl9LRVldLmluY2x1ZGVzKGV2ZW50LmtleSk7XG4gICAgY29uc3QgbmV4dEFjdGl2ZUVsZW1lbnQgPSBnZXROZXh0QWN0aXZlRWxlbWVudCh0aGlzLl9nZXRDaGlsZHJlbigpLmZpbHRlcihlbGVtZW50ID0+ICFpc0Rpc2FibGVkKGVsZW1lbnQpKSwgZXZlbnQudGFyZ2V0LCBpc05leHQsIHRydWUpO1xuICAgIGlmIChuZXh0QWN0aXZlRWxlbWVudCkge1xuICAgICAgbmV4dEFjdGl2ZUVsZW1lbnQuZm9jdXMoe1xuICAgICAgICBwcmV2ZW50U2Nyb2xsOiB0cnVlXG4gICAgICB9KTtcbiAgICAgIFRhYi5nZXRPckNyZWF0ZUluc3RhbmNlKG5leHRBY3RpdmVFbGVtZW50KS5zaG93KCk7XG4gICAgfVxuICB9XG4gIF9nZXRDaGlsZHJlbigpIHtcbiAgICAvLyBjb2xsZWN0aW9uIG9mIGlubmVyIGVsZW1lbnRzXG4gICAgcmV0dXJuIFNlbGVjdG9yRW5naW5lLmZpbmQoU0VMRUNUT1JfSU5ORVJfRUxFTSwgdGhpcy5fcGFyZW50KTtcbiAgfVxuICBfZ2V0QWN0aXZlRWxlbSgpIHtcbiAgICByZXR1cm4gdGhpcy5fZ2V0Q2hpbGRyZW4oKS5maW5kKGNoaWxkID0+IHRoaXMuX2VsZW1Jc0FjdGl2ZShjaGlsZCkpIHx8IG51bGw7XG4gIH1cbiAgX3NldEluaXRpYWxBdHRyaWJ1dGVzKHBhcmVudCwgY2hpbGRyZW4pIHtcbiAgICB0aGlzLl9zZXRBdHRyaWJ1dGVJZk5vdEV4aXN0cyhwYXJlbnQsICdyb2xlJywgJ3RhYmxpc3QnKTtcbiAgICBmb3IgKGNvbnN0IGNoaWxkIG9mIGNoaWxkcmVuKSB7XG4gICAgICB0aGlzLl9zZXRJbml0aWFsQXR0cmlidXRlc09uQ2hpbGQoY2hpbGQpO1xuICAgIH1cbiAgfVxuICBfc2V0SW5pdGlhbEF0dHJpYnV0ZXNPbkNoaWxkKGNoaWxkKSB7XG4gICAgY2hpbGQgPSB0aGlzLl9nZXRJbm5lckVsZW1lbnQoY2hpbGQpO1xuICAgIGNvbnN0IGlzQWN0aXZlID0gdGhpcy5fZWxlbUlzQWN0aXZlKGNoaWxkKTtcbiAgICBjb25zdCBvdXRlckVsZW0gPSB0aGlzLl9nZXRPdXRlckVsZW1lbnQoY2hpbGQpO1xuICAgIGNoaWxkLnNldEF0dHJpYnV0ZSgnYXJpYS1zZWxlY3RlZCcsIGlzQWN0aXZlKTtcbiAgICBpZiAob3V0ZXJFbGVtICE9PSBjaGlsZCkge1xuICAgICAgdGhpcy5fc2V0QXR0cmlidXRlSWZOb3RFeGlzdHMob3V0ZXJFbGVtLCAncm9sZScsICdwcmVzZW50YXRpb24nKTtcbiAgICB9XG4gICAgaWYgKCFpc0FjdGl2ZSkge1xuICAgICAgY2hpbGQuc2V0QXR0cmlidXRlKCd0YWJpbmRleCcsICctMScpO1xuICAgIH1cbiAgICB0aGlzLl9zZXRBdHRyaWJ1dGVJZk5vdEV4aXN0cyhjaGlsZCwgJ3JvbGUnLCAndGFiJyk7XG5cbiAgICAvLyBzZXQgYXR0cmlidXRlcyB0byB0aGUgcmVsYXRlZCBwYW5lbCB0b29cbiAgICB0aGlzLl9zZXRJbml0aWFsQXR0cmlidXRlc09uVGFyZ2V0UGFuZWwoY2hpbGQpO1xuICB9XG4gIF9zZXRJbml0aWFsQXR0cmlidXRlc09uVGFyZ2V0UGFuZWwoY2hpbGQpIHtcbiAgICBjb25zdCB0YXJnZXQgPSBTZWxlY3RvckVuZ2luZS5nZXRFbGVtZW50RnJvbVNlbGVjdG9yKGNoaWxkKTtcbiAgICBpZiAoIXRhcmdldCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLl9zZXRBdHRyaWJ1dGVJZk5vdEV4aXN0cyh0YXJnZXQsICdyb2xlJywgJ3RhYnBhbmVsJyk7XG4gICAgaWYgKGNoaWxkLmlkKSB7XG4gICAgICB0aGlzLl9zZXRBdHRyaWJ1dGVJZk5vdEV4aXN0cyh0YXJnZXQsICdhcmlhLWxhYmVsbGVkYnknLCBgJHtjaGlsZC5pZH1gKTtcbiAgICB9XG4gIH1cbiAgX3RvZ2dsZURyb3BEb3duKGVsZW1lbnQsIG9wZW4pIHtcbiAgICBjb25zdCBvdXRlckVsZW0gPSB0aGlzLl9nZXRPdXRlckVsZW1lbnQoZWxlbWVudCk7XG4gICAgaWYgKCFvdXRlckVsZW0uY2xhc3NMaXN0LmNvbnRhaW5zKENMQVNTX0RST1BET1dOKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCB0b2dnbGUgPSAoc2VsZWN0b3IsIGNsYXNzTmFtZSkgPT4ge1xuICAgICAgY29uc3QgZWxlbWVudCA9IFNlbGVjdG9yRW5naW5lLmZpbmRPbmUoc2VsZWN0b3IsIG91dGVyRWxlbSk7XG4gICAgICBpZiAoZWxlbWVudCkge1xuICAgICAgICBlbGVtZW50LmNsYXNzTGlzdC50b2dnbGUoY2xhc3NOYW1lLCBvcGVuKTtcbiAgICAgIH1cbiAgICB9O1xuICAgIHRvZ2dsZShTRUxFQ1RPUl9EUk9QRE9XTl9UT0dHTEUsIENMQVNTX05BTUVfQUNUSVZFKTtcbiAgICB0b2dnbGUoU0VMRUNUT1JfRFJPUERPV05fTUVOVSwgQ0xBU1NfTkFNRV9TSE9XJDEpO1xuICAgIG91dGVyRWxlbS5zZXRBdHRyaWJ1dGUoJ2FyaWEtZXhwYW5kZWQnLCBvcGVuKTtcbiAgfVxuICBfc2V0QXR0cmlidXRlSWZOb3RFeGlzdHMoZWxlbWVudCwgYXR0cmlidXRlLCB2YWx1ZSkge1xuICAgIGlmICghZWxlbWVudC5oYXNBdHRyaWJ1dGUoYXR0cmlidXRlKSkge1xuICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoYXR0cmlidXRlLCB2YWx1ZSk7XG4gICAgfVxuICB9XG4gIF9lbGVtSXNBY3RpdmUoZWxlbSkge1xuICAgIHJldHVybiBlbGVtLmNsYXNzTGlzdC5jb250YWlucyhDTEFTU19OQU1FX0FDVElWRSk7XG4gIH1cblxuICAvLyBUcnkgdG8gZ2V0IHRoZSBpbm5lciBlbGVtZW50ICh1c3VhbGx5IHRoZSAubmF2LWxpbmspXG4gIF9nZXRJbm5lckVsZW1lbnQoZWxlbSkge1xuICAgIHJldHVybiBlbGVtLm1hdGNoZXMoU0VMRUNUT1JfSU5ORVJfRUxFTSkgPyBlbGVtIDogU2VsZWN0b3JFbmdpbmUuZmluZE9uZShTRUxFQ1RPUl9JTk5FUl9FTEVNLCBlbGVtKTtcbiAgfVxuXG4gIC8vIFRyeSB0byBnZXQgdGhlIG91dGVyIGVsZW1lbnQgKHVzdWFsbHkgdGhlIC5uYXYtaXRlbSlcbiAgX2dldE91dGVyRWxlbWVudChlbGVtKSB7XG4gICAgcmV0dXJuIGVsZW0uY2xvc2VzdChTRUxFQ1RPUl9PVVRFUikgfHwgZWxlbTtcbiAgfVxuXG4gIC8vIFN0YXRpY1xuICBzdGF0aWMgalF1ZXJ5SW50ZXJmYWNlKGNvbmZpZykge1xuICAgIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZGF0YSA9IFRhYi5nZXRPckNyZWF0ZUluc3RhbmNlKHRoaXMpO1xuICAgICAgaWYgKHR5cGVvZiBjb25maWcgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmIChkYXRhW2NvbmZpZ10gPT09IHVuZGVmaW5lZCB8fCBjb25maWcuc3RhcnRzV2l0aCgnXycpIHx8IGNvbmZpZyA9PT0gJ2NvbnN0cnVjdG9yJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBObyBtZXRob2QgbmFtZWQgXCIke2NvbmZpZ31cImApO1xuICAgICAgfVxuICAgICAgZGF0YVtjb25maWddKCk7XG4gICAgfSk7XG4gIH1cbn1cblxuLyoqXG4gKiBEYXRhIEFQSSBpbXBsZW1lbnRhdGlvblxuICovXG5cbkV2ZW50SGFuZGxlci5vbihkb2N1bWVudCwgRVZFTlRfQ0xJQ0tfREFUQV9BUEksIFNFTEVDVE9SX0RBVEFfVE9HR0xFLCBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgaWYgKFsnQScsICdBUkVBJ10uaW5jbHVkZXModGhpcy50YWdOYW1lKSkge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gIH1cbiAgaWYgKGlzRGlzYWJsZWQodGhpcykpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgVGFiLmdldE9yQ3JlYXRlSW5zdGFuY2UodGhpcykuc2hvdygpO1xufSk7XG5cbi8qKlxuICogSW5pdGlhbGl6ZSBvbiBmb2N1c1xuICovXG5FdmVudEhhbmRsZXIub24od2luZG93LCBFVkVOVF9MT0FEX0RBVEFfQVBJLCAoKSA9PiB7XG4gIGZvciAoY29uc3QgZWxlbWVudCBvZiBTZWxlY3RvckVuZ2luZS5maW5kKFNFTEVDVE9SX0RBVEFfVE9HR0xFX0FDVElWRSkpIHtcbiAgICBUYWIuZ2V0T3JDcmVhdGVJbnN0YW5jZShlbGVtZW50KTtcbiAgfVxufSk7XG4vKipcbiAqIGpRdWVyeVxuICovXG5cbmRlZmluZUpRdWVyeVBsdWdpbihUYWIpO1xuXG4vKipcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiBCb290c3RyYXAgdG9hc3QuanNcbiAqIExpY2Vuc2VkIHVuZGVyIE1JVCAoaHR0cHM6Ly9naXRodWIuY29tL3R3YnMvYm9vdHN0cmFwL2Jsb2IvbWFpbi9MSUNFTlNFKVxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqL1xuXG5cbi8qKlxuICogQ29uc3RhbnRzXG4gKi9cblxuY29uc3QgTkFNRSA9ICd0b2FzdCc7XG5jb25zdCBEQVRBX0tFWSA9ICdicy50b2FzdCc7XG5jb25zdCBFVkVOVF9LRVkgPSBgLiR7REFUQV9LRVl9YDtcbmNvbnN0IEVWRU5UX01PVVNFT1ZFUiA9IGBtb3VzZW92ZXIke0VWRU5UX0tFWX1gO1xuY29uc3QgRVZFTlRfTU9VU0VPVVQgPSBgbW91c2VvdXQke0VWRU5UX0tFWX1gO1xuY29uc3QgRVZFTlRfRk9DVVNJTiA9IGBmb2N1c2luJHtFVkVOVF9LRVl9YDtcbmNvbnN0IEVWRU5UX0ZPQ1VTT1VUID0gYGZvY3Vzb3V0JHtFVkVOVF9LRVl9YDtcbmNvbnN0IEVWRU5UX0hJREUgPSBgaGlkZSR7RVZFTlRfS0VZfWA7XG5jb25zdCBFVkVOVF9ISURERU4gPSBgaGlkZGVuJHtFVkVOVF9LRVl9YDtcbmNvbnN0IEVWRU5UX1NIT1cgPSBgc2hvdyR7RVZFTlRfS0VZfWA7XG5jb25zdCBFVkVOVF9TSE9XTiA9IGBzaG93biR7RVZFTlRfS0VZfWA7XG5jb25zdCBDTEFTU19OQU1FX0ZBREUgPSAnZmFkZSc7XG5jb25zdCBDTEFTU19OQU1FX0hJREUgPSAnaGlkZSc7IC8vIEBkZXByZWNhdGVkIC0ga2VwdCBoZXJlIG9ubHkgZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5XG5jb25zdCBDTEFTU19OQU1FX1NIT1cgPSAnc2hvdyc7XG5jb25zdCBDTEFTU19OQU1FX1NIT1dJTkcgPSAnc2hvd2luZyc7XG5jb25zdCBEZWZhdWx0VHlwZSA9IHtcbiAgYW5pbWF0aW9uOiAnYm9vbGVhbicsXG4gIGF1dG9oaWRlOiAnYm9vbGVhbicsXG4gIGRlbGF5OiAnbnVtYmVyJ1xufTtcbmNvbnN0IERlZmF1bHQgPSB7XG4gIGFuaW1hdGlvbjogdHJ1ZSxcbiAgYXV0b2hpZGU6IHRydWUsXG4gIGRlbGF5OiA1MDAwXG59O1xuXG4vKipcbiAqIENsYXNzIGRlZmluaXRpb25cbiAqL1xuXG5jbGFzcyBUb2FzdCBleHRlbmRzIEJhc2VDb21wb25lbnQge1xuICBjb25zdHJ1Y3RvcihlbGVtZW50LCBjb25maWcpIHtcbiAgICBzdXBlcihlbGVtZW50LCBjb25maWcpO1xuICAgIHRoaXMuX3RpbWVvdXQgPSBudWxsO1xuICAgIHRoaXMuX2hhc01vdXNlSW50ZXJhY3Rpb24gPSBmYWxzZTtcbiAgICB0aGlzLl9oYXNLZXlib2FyZEludGVyYWN0aW9uID0gZmFsc2U7XG4gICAgdGhpcy5fc2V0TGlzdGVuZXJzKCk7XG4gIH1cblxuICAvLyBHZXR0ZXJzXG4gIHN0YXRpYyBnZXQgRGVmYXVsdCgpIHtcbiAgICByZXR1cm4gRGVmYXVsdDtcbiAgfVxuICBzdGF0aWMgZ2V0IERlZmF1bHRUeXBlKCkge1xuICAgIHJldHVybiBEZWZhdWx0VHlwZTtcbiAgfVxuICBzdGF0aWMgZ2V0IE5BTUUoKSB7XG4gICAgcmV0dXJuIE5BTUU7XG4gIH1cblxuICAvLyBQdWJsaWNcbiAgc2hvdygpIHtcbiAgICBjb25zdCBzaG93RXZlbnQgPSBFdmVudEhhbmRsZXIudHJpZ2dlcih0aGlzLl9lbGVtZW50LCBFVkVOVF9TSE9XKTtcbiAgICBpZiAoc2hvd0V2ZW50LmRlZmF1bHRQcmV2ZW50ZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5fY2xlYXJUaW1lb3V0KCk7XG4gICAgaWYgKHRoaXMuX2NvbmZpZy5hbmltYXRpb24pIHtcbiAgICAgIHRoaXMuX2VsZW1lbnQuY2xhc3NMaXN0LmFkZChDTEFTU19OQU1FX0ZBREUpO1xuICAgIH1cbiAgICBjb25zdCBjb21wbGV0ZSA9ICgpID0+IHtcbiAgICAgIHRoaXMuX2VsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZShDTEFTU19OQU1FX1NIT1dJTkcpO1xuICAgICAgRXZlbnRIYW5kbGVyLnRyaWdnZXIodGhpcy5fZWxlbWVudCwgRVZFTlRfU0hPV04pO1xuICAgICAgdGhpcy5fbWF5YmVTY2hlZHVsZUhpZGUoKTtcbiAgICB9O1xuICAgIHRoaXMuX2VsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZShDTEFTU19OQU1FX0hJREUpOyAvLyBAZGVwcmVjYXRlZFxuICAgIHJlZmxvdyh0aGlzLl9lbGVtZW50KTtcbiAgICB0aGlzLl9lbGVtZW50LmNsYXNzTGlzdC5hZGQoQ0xBU1NfTkFNRV9TSE9XLCBDTEFTU19OQU1FX1NIT1dJTkcpO1xuICAgIHRoaXMuX3F1ZXVlQ2FsbGJhY2soY29tcGxldGUsIHRoaXMuX2VsZW1lbnQsIHRoaXMuX2NvbmZpZy5hbmltYXRpb24pO1xuICB9XG4gIGhpZGUoKSB7XG4gICAgaWYgKCF0aGlzLmlzU2hvd24oKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBoaWRlRXZlbnQgPSBFdmVudEhhbmRsZXIudHJpZ2dlcih0aGlzLl9lbGVtZW50LCBFVkVOVF9ISURFKTtcbiAgICBpZiAoaGlkZUV2ZW50LmRlZmF1bHRQcmV2ZW50ZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgY29tcGxldGUgPSAoKSA9PiB7XG4gICAgICB0aGlzLl9lbGVtZW50LmNsYXNzTGlzdC5hZGQoQ0xBU1NfTkFNRV9ISURFKTsgLy8gQGRlcHJlY2F0ZWRcbiAgICAgIHRoaXMuX2VsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZShDTEFTU19OQU1FX1NIT1dJTkcsIENMQVNTX05BTUVfU0hPVyk7XG4gICAgICBFdmVudEhhbmRsZXIudHJpZ2dlcih0aGlzLl9lbGVtZW50LCBFVkVOVF9ISURERU4pO1xuICAgIH07XG4gICAgdGhpcy5fZWxlbWVudC5jbGFzc0xpc3QuYWRkKENMQVNTX05BTUVfU0hPV0lORyk7XG4gICAgdGhpcy5fcXVldWVDYWxsYmFjayhjb21wbGV0ZSwgdGhpcy5fZWxlbWVudCwgdGhpcy5fY29uZmlnLmFuaW1hdGlvbik7XG4gIH1cbiAgZGlzcG9zZSgpIHtcbiAgICB0aGlzLl9jbGVhclRpbWVvdXQoKTtcbiAgICBpZiAodGhpcy5pc1Nob3duKCkpIHtcbiAgICAgIHRoaXMuX2VsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZShDTEFTU19OQU1FX1NIT1cpO1xuICAgIH1cbiAgICBzdXBlci5kaXNwb3NlKCk7XG4gIH1cbiAgaXNTaG93bigpIHtcbiAgICByZXR1cm4gdGhpcy5fZWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoQ0xBU1NfTkFNRV9TSE9XKTtcbiAgfVxuXG4gIC8vIFByaXZhdGVcblxuICBfbWF5YmVTY2hlZHVsZUhpZGUoKSB7XG4gICAgaWYgKCF0aGlzLl9jb25maWcuYXV0b2hpZGUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHRoaXMuX2hhc01vdXNlSW50ZXJhY3Rpb24gfHwgdGhpcy5faGFzS2V5Ym9hcmRJbnRlcmFjdGlvbikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLl90aW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLmhpZGUoKTtcbiAgICB9LCB0aGlzLl9jb25maWcuZGVsYXkpO1xuICB9XG4gIF9vbkludGVyYWN0aW9uKGV2ZW50LCBpc0ludGVyYWN0aW5nKSB7XG4gICAgc3dpdGNoIChldmVudC50eXBlKSB7XG4gICAgICBjYXNlICdtb3VzZW92ZXInOlxuICAgICAgY2FzZSAnbW91c2VvdXQnOlxuICAgICAgICB7XG4gICAgICAgICAgdGhpcy5faGFzTW91c2VJbnRlcmFjdGlvbiA9IGlzSW50ZXJhY3Rpbmc7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIGNhc2UgJ2ZvY3VzaW4nOlxuICAgICAgY2FzZSAnZm9jdXNvdXQnOlxuICAgICAgICB7XG4gICAgICAgICAgdGhpcy5faGFzS2V5Ym9hcmRJbnRlcmFjdGlvbiA9IGlzSW50ZXJhY3Rpbmc7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKGlzSW50ZXJhY3RpbmcpIHtcbiAgICAgIHRoaXMuX2NsZWFyVGltZW91dCgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBuZXh0RWxlbWVudCA9IGV2ZW50LnJlbGF0ZWRUYXJnZXQ7XG4gICAgaWYgKHRoaXMuX2VsZW1lbnQgPT09IG5leHRFbGVtZW50IHx8IHRoaXMuX2VsZW1lbnQuY29udGFpbnMobmV4dEVsZW1lbnQpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuX21heWJlU2NoZWR1bGVIaWRlKCk7XG4gIH1cbiAgX3NldExpc3RlbmVycygpIHtcbiAgICBFdmVudEhhbmRsZXIub24odGhpcy5fZWxlbWVudCwgRVZFTlRfTU9VU0VPVkVSLCBldmVudCA9PiB0aGlzLl9vbkludGVyYWN0aW9uKGV2ZW50LCB0cnVlKSk7XG4gICAgRXZlbnRIYW5kbGVyLm9uKHRoaXMuX2VsZW1lbnQsIEVWRU5UX01PVVNFT1VULCBldmVudCA9PiB0aGlzLl9vbkludGVyYWN0aW9uKGV2ZW50LCBmYWxzZSkpO1xuICAgIEV2ZW50SGFuZGxlci5vbih0aGlzLl9lbGVtZW50LCBFVkVOVF9GT0NVU0lOLCBldmVudCA9PiB0aGlzLl9vbkludGVyYWN0aW9uKGV2ZW50LCB0cnVlKSk7XG4gICAgRXZlbnRIYW5kbGVyLm9uKHRoaXMuX2VsZW1lbnQsIEVWRU5UX0ZPQ1VTT1VULCBldmVudCA9PiB0aGlzLl9vbkludGVyYWN0aW9uKGV2ZW50LCBmYWxzZSkpO1xuICB9XG4gIF9jbGVhclRpbWVvdXQoKSB7XG4gICAgY2xlYXJUaW1lb3V0KHRoaXMuX3RpbWVvdXQpO1xuICAgIHRoaXMuX3RpbWVvdXQgPSBudWxsO1xuICB9XG5cbiAgLy8gU3RhdGljXG4gIHN0YXRpYyBqUXVlcnlJbnRlcmZhY2UoY29uZmlnKSB7XG4gICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBkYXRhID0gVG9hc3QuZ2V0T3JDcmVhdGVJbnN0YW5jZSh0aGlzLCBjb25maWcpO1xuICAgICAgaWYgKHR5cGVvZiBjb25maWcgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIGlmICh0eXBlb2YgZGF0YVtjb25maWddID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYE5vIG1ldGhvZCBuYW1lZCBcIiR7Y29uZmlnfVwiYCk7XG4gICAgICAgIH1cbiAgICAgICAgZGF0YVtjb25maWddKHRoaXMpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG59XG5cbi8qKlxuICogRGF0YSBBUEkgaW1wbGVtZW50YXRpb25cbiAqL1xuXG5lbmFibGVEaXNtaXNzVHJpZ2dlcihUb2FzdCk7XG5cbi8qKlxuICogalF1ZXJ5XG4gKi9cblxuZGVmaW5lSlF1ZXJ5UGx1Z2luKFRvYXN0KTtcblxuZXhwb3J0IHsgQWxlcnQsIEJ1dHRvbiwgQ2Fyb3VzZWwsIENvbGxhcHNlLCBEcm9wZG93biwgTW9kYWwsIE9mZmNhbnZhcywgUG9wb3ZlciwgU2Nyb2xsU3B5LCBUYWIsIFRvYXN0LCBUb29sdGlwIH07XG4vLyMgc291cmNlTWFwcGluZ1VSTD1ib290c3RyYXAuZXNtLmpzLm1hcFxuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/bootstrap/dist/js/bootstrap.esm.js\n");
/***/ }),
/***/ "./node_modules/chart.js/dist/Chart.js":
/*!*********************************************!*\
!*** ./node_modules/chart.js/dist/Chart.js ***!
\*********************************************/
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {
eval("/*!\n * Chart.js v2.9.4\n * https://www.chartjs.org\n * (c) 2020 Chart.js Contributors\n * Released under the MIT License\n */\n(function (global, factory) {\n true ? module.exports = factory(function() { try { return __webpack_require__(/*! moment */ \"./node_modules/moment/moment.js\"); } catch(e) { } }()) :\n0;\n}(this, (function (moment) { 'use strict';\n\nmoment = moment && moment.hasOwnProperty('default') ? moment['default'] : moment;\n\nfunction createCommonjsModule(fn, module) {\n\treturn module = { exports: {} }, fn(module, module.exports), module.exports;\n}\n\nfunction getCjsExportFromNamespace (n) {\n\treturn n && n['default'] || n;\n}\n\nvar colorName = {\r\n\t\"aliceblue\": [240, 248, 255],\r\n\t\"antiquewhite\": [250, 235, 215],\r\n\t\"aqua\": [0, 255, 255],\r\n\t\"aquamarine\": [127, 255, 212],\r\n\t\"azure\": [240, 255, 255],\r\n\t\"beige\": [245, 245, 220],\r\n\t\"bisque\": [255, 228, 196],\r\n\t\"black\": [0, 0, 0],\r\n\t\"blanchedalmond\": [255, 235, 205],\r\n\t\"blue\": [0, 0, 255],\r\n\t\"blueviolet\": [138, 43, 226],\r\n\t\"brown\": [165, 42, 42],\r\n\t\"burlywood\": [222, 184, 135],\r\n\t\"cadetblue\": [95, 158, 160],\r\n\t\"chartreuse\": [127, 255, 0],\r\n\t\"chocolate\": [210, 105, 30],\r\n\t\"coral\": [255, 127, 80],\r\n\t\"cornflowerblue\": [100, 149, 237],\r\n\t\"cornsilk\": [255, 248, 220],\r\n\t\"crimson\": [220, 20, 60],\r\n\t\"cyan\": [0, 255, 255],\r\n\t\"darkblue\": [0, 0, 139],\r\n\t\"darkcyan\": [0, 139, 139],\r\n\t\"darkgoldenrod\": [184, 134, 11],\r\n\t\"darkgray\": [169, 169, 169],\r\n\t\"darkgreen\": [0, 100, 0],\r\n\t\"darkgrey\": [169, 169, 169],\r\n\t\"darkkhaki\": [189, 183, 107],\r\n\t\"darkmagenta\": [139, 0, 139],\r\n\t\"darkolivegreen\": [85, 107, 47],\r\n\t\"darkorange\": [255, 140, 0],\r\n\t\"darkorchid\": [153, 50, 204],\r\n\t\"darkred\": [139, 0, 0],\r\n\t\"darksalmon\": [233, 150, 122],\r\n\t\"darkseagreen\": [143, 188, 143],\r\n\t\"darkslateblue\": [72, 61, 139],\r\n\t\"darkslategray\": [47, 79, 79],\r\n\t\"darkslategrey\": [47, 79, 79],\r\n\t\"darkturquoise\": [0, 206, 209],\r\n\t\"darkviolet\": [148, 0, 211],\r\n\t\"deeppink\": [255, 20, 147],\r\n\t\"deepskyblue\": [0, 191, 255],\r\n\t\"dimgray\": [105, 105, 105],\r\n\t\"dimgrey\": [105, 105, 105],\r\n\t\"dodgerblue\": [30, 144, 255],\r\n\t\"firebrick\": [178, 34, 34],\r\n\t\"floralwhite\": [255, 250, 240],\r\n\t\"forestgreen\": [34, 139, 34],\r\n\t\"fuchsia\": [255, 0, 255],\r\n\t\"gainsboro\": [220, 220, 220],\r\n\t\"ghostwhite\": [248, 248, 255],\r\n\t\"gold\": [255, 215, 0],\r\n\t\"goldenrod\": [218, 165, 32],\r\n\t\"gray\": [128, 128, 128],\r\n\t\"green\": [0, 128, 0],\r\n\t\"greenyellow\": [173, 255, 47],\r\n\t\"grey\": [128, 128, 128],\r\n\t\"honeydew\": [240, 255, 240],\r\n\t\"hotpink\": [255, 105, 180],\r\n\t\"indianred\": [205, 92, 92],\r\n\t\"indigo\": [75, 0, 130],\r\n\t\"ivory\": [255, 255, 240],\r\n\t\"khaki\": [240, 230, 140],\r\n\t\"lavender\": [230, 230, 250],\r\n\t\"lavenderblush\": [255, 240, 245],\r\n\t\"lawngreen\": [124, 252, 0],\r\n\t\"lemonchiffon\": [255, 250, 205],\r\n\t\"lightblue\": [173, 216, 230],\r\n\t\"lightcoral\": [240, 128, 128],\r\n\t\"lightcyan\": [224, 255, 255],\r\n\t\"lightgoldenrodyellow\": [250, 250, 210],\r\n\t\"lightgray\": [211, 211, 211],\r\n\t\"lightgreen\": [144, 238, 144],\r\n\t\"lightgrey\": [211, 211, 211],\r\n\t\"lightpink\": [255, 182, 193],\r\n\t\"lightsalmon\": [255, 160, 122],\r\n\t\"lightseagreen\": [32, 178, 170],\r\n\t\"lightskyblue\": [135, 206, 250],\r\n\t\"lightslategray\": [119, 136, 153],\r\n\t\"lightslategrey\": [119, 136, 153],\r\n\t\"lightsteelblue\": [176, 196, 222],\r\n\t\"lightyellow\": [255, 255, 224],\r\n\t\"lime\": [0, 255, 0],\r\n\t\"limegreen\": [50, 205, 50],\r\n\t\"linen\": [250, 240, 230],\r\n\t\"magenta\": [255, 0, 255],\r\n\t\"maroon\": [128, 0, 0],\r\n\t\"mediumaquamarine\": [102, 205, 170],\r\n\t\"mediumblue\": [0, 0, 205],\r\n\t\"mediumorchid\": [186, 85, 211],\r\n\t\"mediumpurple\": [147, 112, 219],\r\n\t\"mediumseagreen\": [60, 179, 113],\r\n\t\"mediumslateblue\": [123, 104, 238],\r\n\t\"mediumspringgreen\": [0, 250, 154],\r\n\t\"mediumturquoise\": [72, 209, 204],\r\n\t\"mediumvioletred\": [199, 21, 133],\r\n\t\"midnightblue\": [25, 25, 112],\r\n\t\"mintcream\": [245, 255, 250],\r\n\t\"mistyrose\": [255, 228, 225],\r\n\t\"moccasin\": [255, 228, 181],\r\n\t\"navajowhite\": [255, 222, 173],\r\n\t\"navy\": [0, 0, 128],\r\n\t\"oldlace\": [253, 245, 230],\r\n\t\"olive\": [128, 128, 0],\r\n\t\"olivedrab\": [107, 142, 35],\r\n\t\"orange\": [255, 165, 0],\r\n\t\"orangered\": [255, 69, 0],\r\n\t\"orchid\": [218, 112, 214],\r\n\t\"palegoldenrod\": [238, 232, 170],\r\n\t\"palegreen\": [152, 251, 152],\r\n\t\"paleturquoise\": [175, 238, 238],\r\n\t\"palevioletred\": [219, 112, 147],\r\n\t\"papayawhip\": [255, 239, 213],\r\n\t\"peachpuff\": [255, 218, 185],\r\n\t\"peru\": [205, 133, 63],\r\n\t\"pink\": [255, 192, 203],\r\n\t\"plum\": [221, 160, 221],\r\n\t\"powderblue\": [176, 224, 230],\r\n\t\"purple\": [128, 0, 128],\r\n\t\"rebeccapurple\": [102, 51, 153],\r\n\t\"red\": [255, 0, 0],\r\n\t\"rosybrown\": [188, 143, 143],\r\n\t\"royalblue\": [65, 105, 225],\r\n\t\"saddlebrown\": [139, 69, 19],\r\n\t\"salmon\": [250, 128, 114],\r\n\t\"sandybrown\": [244, 164, 96],\r\n\t\"seagreen\": [46, 139, 87],\r\n\t\"seashell\": [255, 245, 238],\r\n\t\"sienna\": [160, 82, 45],\r\n\t\"silver\": [192, 192, 192],\r\n\t\"skyblue\": [135, 206, 235],\r\n\t\"slateblue\": [106, 90, 205],\r\n\t\"slategray\": [112, 128, 144],\r\n\t\"slategrey\": [112, 128, 144],\r\n\t\"snow\": [255, 250, 250],\r\n\t\"springgreen\": [0, 255, 127],\r\n\t\"steelblue\": [70, 130, 180],\r\n\t\"tan\": [210, 180, 140],\r\n\t\"teal\": [0, 128, 128],\r\n\t\"thistle\": [216, 191, 216],\r\n\t\"tomato\": [255, 99, 71],\r\n\t\"turquoise\": [64, 224, 208],\r\n\t\"violet\": [238, 130, 238],\r\n\t\"wheat\": [245, 222, 179],\r\n\t\"white\": [255, 255, 255],\r\n\t\"whitesmoke\": [245, 245, 245],\r\n\t\"yellow\": [255, 255, 0],\r\n\t\"yellowgreen\": [154, 205, 50]\r\n};\n\nvar conversions = createCommonjsModule(function (module) {\n/* MIT license */\n\n\n// NOTE: conversions should only return primitive values (i.e. arrays, or\n// values that give correct `typeof` results).\n// do not use box values types (i.e. Number(), String(), etc.)\n\nvar reverseKeywords = {};\nfor (var key in colorName) {\n\tif (colorName.hasOwnProperty(key)) {\n\t\treverseKeywords[colorName[key]] = key;\n\t}\n}\n\nvar convert = module.exports = {\n\trgb: {channels: 3, labels: 'rgb'},\n\thsl: {channels: 3, labels: 'hsl'},\n\thsv: {channels: 3, labels: 'hsv'},\n\thwb: {channels: 3, labels: 'hwb'},\n\tcmyk: {channels: 4, labels: 'cmyk'},\n\txyz: {channels: 3, labels: 'xyz'},\n\tlab: {channels: 3, labels: 'lab'},\n\tlch: {channels: 3, labels: 'lch'},\n\thex: {channels: 1, labels: ['hex']},\n\tkeyword: {channels: 1, labels: ['keyword']},\n\tansi16: {channels: 1, labels: ['ansi16']},\n\tansi256: {channels: 1, labels: ['ansi256']},\n\thcg: {channels: 3, labels: ['h', 'c', 'g']},\n\tapple: {channels: 3, labels: ['r16', 'g16', 'b16']},\n\tgray: {channels: 1, labels: ['gray']}\n};\n\n// hide .channels and .labels properties\nfor (var model in convert) {\n\tif (convert.hasOwnProperty(model)) {\n\t\tif (!('channels' in convert[model])) {\n\t\t\tthrow new Error('missing channels property: ' + model);\n\t\t}\n\n\t\tif (!('labels' in convert[model])) {\n\t\t\tthrow new Error('missing channel labels property: ' + model);\n\t\t}\n\n\t\tif (convert[model].labels.length !== convert[model].channels) {\n\t\t\tthrow new Error('channel and label counts mismatch: ' + model);\n\t\t}\n\n\t\tvar channels = convert[model].channels;\n\t\tvar labels = convert[model].labels;\n\t\tdelete convert[model].channels;\n\t\tdelete convert[model].labels;\n\t\tObject.defineProperty(convert[model], 'channels', {value: channels});\n\t\tObject.defineProperty(convert[model], 'labels', {value: labels});\n\t}\n}\n\nconvert.rgb.hsl = function (rgb) {\n\tvar r = rgb[0] / 255;\n\tvar g = rgb[1] / 255;\n\tvar b = rgb[2] / 255;\n\tvar min = Math.min(r, g, b);\n\tvar max = Math.max(r, g, b);\n\tvar delta = max - min;\n\tvar h;\n\tvar s;\n\tvar l;\n\n\tif (max === min) {\n\t\th = 0;\n\t} else if (r === max) {\n\t\th = (g - b) / delta;\n\t} else if (g === max) {\n\t\th = 2 + (b - r) / delta;\n\t} else if (b === max) {\n\t\th = 4 + (r - g) / delta;\n\t}\n\n\th = Math.min(h * 60, 360);\n\n\tif (h < 0) {\n\t\th += 360;\n\t}\n\n\tl = (min + max) / 2;\n\n\tif (max === min) {\n\t\ts = 0;\n\t} else if (l <= 0.5) {\n\t\ts = delta / (max + min);\n\t} else {\n\t\ts = delta / (2 - max - min);\n\t}\n\n\treturn [h, s * 100, l * 100];\n};\n\nconvert.rgb.hsv = function (rgb) {\n\tvar rdif;\n\tvar gdif;\n\tvar bdif;\n\tvar h;\n\tvar s;\n\n\tvar r = rgb[0] / 255;\n\tvar g = rgb[1] / 255;\n\tvar b = rgb[2] / 255;\n\tvar v = Math.max(r, g, b);\n\tvar diff = v - Math.min(r, g, b);\n\tvar diffc = function (c) {\n\t\treturn (v - c) / 6 / diff + 1 / 2;\n\t};\n\n\tif (diff === 0) {\n\t\th = s = 0;\n\t} else {\n\t\ts = diff / v;\n\t\trdif = diffc(r);\n\t\tgdif = diffc(g);\n\t\tbdif = diffc(b);\n\n\t\tif (r === v) {\n\t\t\th = bdif - gdif;\n\t\t} else if (g === v) {\n\t\t\th = (1 / 3) + rdif - bdif;\n\t\t} else if (b === v) {\n\t\t\th = (2 / 3) + gdif - rdif;\n\t\t}\n\t\tif (h < 0) {\n\t\t\th += 1;\n\t\t} else if (h > 1) {\n\t\t\th -= 1;\n\t\t}\n\t}\n\n\treturn [\n\t\th * 360,\n\t\ts * 100,\n\t\tv * 100\n\t];\n};\n\nconvert.rgb.hwb = function (rgb) {\n\tvar r = rgb[0];\n\tvar g = rgb[1];\n\tvar b = rgb[2];\n\tvar h = convert.rgb.hsl(rgb)[0];\n\tvar w = 1 / 255 * Math.min(r, Math.min(g, b));\n\n\tb = 1 - 1 / 255 * Math.max(r, Math.max(g, b));\n\n\treturn [h, w * 100, b * 100];\n};\n\nconvert.rgb.cmyk = function (rgb) {\n\tvar r = rgb[0] / 255;\n\tvar g = rgb[1] / 255;\n\tvar b = rgb[2] / 255;\n\tvar c;\n\tvar m;\n\tvar y;\n\tvar k;\n\n\tk = Math.min(1 - r, 1 - g, 1 - b);\n\tc = (1 - r - k) / (1 - k) || 0;\n\tm = (1 - g - k) / (1 - k) || 0;\n\ty = (1 - b - k) / (1 - k) || 0;\n\n\treturn [c * 100, m * 100, y * 100, k * 100];\n};\n\n/**\n * See https://en.m.wikipedia.org/wiki/Euclidean_distance#Squared_Euclidean_distance\n * */\nfunction comparativeDistance(x, y) {\n\treturn (\n\t\tMath.pow(x[0] - y[0], 2) +\n\t\tMath.pow(x[1] - y[1], 2) +\n\t\tMath.pow(x[2] - y[2], 2)\n\t);\n}\n\nconvert.rgb.keyword = function (rgb) {\n\tvar reversed = reverseKeywords[rgb];\n\tif (reversed) {\n\t\treturn reversed;\n\t}\n\n\tvar currentClosestDistance = Infinity;\n\tvar currentClosestKeyword;\n\n\tfor (var keyword in colorName) {\n\t\tif (colorName.hasOwnProperty(keyword)) {\n\t\t\tvar value = colorName[keyword];\n\n\t\t\t// Compute comparative distance\n\t\t\tvar distance = comparativeDistance(rgb, value);\n\n\t\t\t// Check if its less, if so set as closest\n\t\t\tif (distance < currentClosestDistance) {\n\t\t\t\tcurrentClosestDistance = distance;\n\t\t\t\tcurrentClosestKeyword = keyword;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn currentClosestKeyword;\n};\n\nconvert.keyword.rgb = function (keyword) {\n\treturn colorName[keyword];\n};\n\nconvert.rgb.xyz = function (rgb) {\n\tvar r = rgb[0] / 255;\n\tvar g = rgb[1] / 255;\n\tvar b = rgb[2] / 255;\n\n\t// assume sRGB\n\tr = r > 0.04045 ? Math.pow(((r + 0.055) / 1.055), 2.4) : (r / 12.92);\n\tg = g > 0.04045 ? Math.pow(((g + 0.055) / 1.055), 2.4) : (g / 12.92);\n\tb = b > 0.04045 ? Math.pow(((b + 0.055) / 1.055), 2.4) : (b / 12.92);\n\n\tvar x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805);\n\tvar y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722);\n\tvar z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505);\n\n\treturn [x * 100, y * 100, z * 100];\n};\n\nconvert.rgb.lab = function (rgb) {\n\tvar xyz = convert.rgb.xyz(rgb);\n\tvar x = xyz[0];\n\tvar y = xyz[1];\n\tvar z = xyz[2];\n\tvar l;\n\tvar a;\n\tvar b;\n\n\tx /= 95.047;\n\ty /= 100;\n\tz /= 108.883;\n\n\tx = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116);\n\ty = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116);\n\tz = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116);\n\n\tl = (116 * y) - 16;\n\ta = 500 * (x - y);\n\tb = 200 * (y - z);\n\n\treturn [l, a, b];\n};\n\nconvert.hsl.rgb = function (hsl) {\n\tvar h = hsl[0] / 360;\n\tvar s = hsl[1] / 100;\n\tvar l = hsl[2] / 100;\n\tvar t1;\n\tvar t2;\n\tvar t3;\n\tvar rgb;\n\tvar val;\n\n\tif (s === 0) {\n\t\tval = l * 255;\n\t\treturn [val, val, val];\n\t}\n\n\tif (l < 0.5) {\n\t\tt2 = l * (1 + s);\n\t} else {\n\t\tt2 = l + s - l * s;\n\t}\n\n\tt1 = 2 * l - t2;\n\n\trgb = [0, 0, 0];\n\tfor (var i = 0; i < 3; i++) {\n\t\tt3 = h + 1 / 3 * -(i - 1);\n\t\tif (t3 < 0) {\n\t\t\tt3++;\n\t\t}\n\t\tif (t3 > 1) {\n\t\t\tt3--;\n\t\t}\n\n\t\tif (6 * t3 < 1) {\n\t\t\tval = t1 + (t2 - t1) * 6 * t3;\n\t\t} else if (2 * t3 < 1) {\n\t\t\tval = t2;\n\t\t} else if (3 * t3 < 2) {\n\t\t\tval = t1 + (t2 - t1) * (2 / 3 - t3) * 6;\n\t\t} else {\n\t\t\tval = t1;\n\t\t}\n\n\t\trgb[i] = val * 255;\n\t}\n\n\treturn rgb;\n};\n\nconvert.hsl.hsv = function (hsl) {\n\tvar h = hsl[0];\n\tvar s = hsl[1] / 100;\n\tvar l = hsl[2] / 100;\n\tvar smin = s;\n\tvar lmin = Math.max(l, 0.01);\n\tvar sv;\n\tvar v;\n\n\tl *= 2;\n\ts *= (l <= 1) ? l : 2 - l;\n\tsmin *= lmin <= 1 ? lmin : 2 - lmin;\n\tv = (l + s) / 2;\n\tsv = l === 0 ? (2 * smin) / (lmin + smin) : (2 * s) / (l + s);\n\n\treturn [h, sv * 100, v * 100];\n};\n\nconvert.hsv.rgb = function (hsv) {\n\tvar h = hsv[0] / 60;\n\tvar s = hsv[1] / 100;\n\tvar v = hsv[2] / 100;\n\tvar hi = Math.floor(h) % 6;\n\n\tvar f = h - Math.floor(h);\n\tvar p = 255 * v * (1 - s);\n\tvar q = 255 * v * (1 - (s * f));\n\tvar t = 255 * v * (1 - (s * (1 - f)));\n\tv *= 255;\n\n\tswitch (hi) {\n\t\tcase 0:\n\t\t\treturn [v, t, p];\n\t\tcase 1:\n\t\t\treturn [q, v, p];\n\t\tcase 2:\n\t\t\treturn [p, v, t];\n\t\tcase 3:\n\t\t\treturn [p, q, v];\n\t\tcase 4:\n\t\t\treturn [t, p, v];\n\t\tcase 5:\n\t\t\treturn [v, p, q];\n\t}\n};\n\nconvert.hsv.hsl = function (hsv) {\n\tvar h = hsv[0];\n\tvar s = hsv[1] / 100;\n\tvar v = hsv[2] / 100;\n\tvar vmin = Math.max(v, 0.01);\n\tvar lmin;\n\tvar sl;\n\tvar l;\n\n\tl = (2 - s) * v;\n\tlmin = (2 - s) * vmin;\n\tsl = s * vmin;\n\tsl /= (lmin <= 1) ? lmin : 2 - lmin;\n\tsl = sl || 0;\n\tl /= 2;\n\n\treturn [h, sl * 100, l * 100];\n};\n\n// http://dev.w3.org/csswg/css-color/#hwb-to-rgb\nconvert.hwb.rgb = function (hwb) {\n\tvar h = hwb[0] / 360;\n\tvar wh = hwb[1] / 100;\n\tvar bl = hwb[2] / 100;\n\tvar ratio = wh + bl;\n\tvar i;\n\tvar v;\n\tvar f;\n\tvar n;\n\n\t// wh + bl cant be > 1\n\tif (ratio > 1) {\n\t\twh /= ratio;\n\t\tbl /= ratio;\n\t}\n\n\ti = Math.floor(6 * h);\n\tv = 1 - bl;\n\tf = 6 * h - i;\n\n\tif ((i & 0x01) !== 0) {\n\t\tf = 1 - f;\n\t}\n\n\tn = wh + f * (v - wh); // linear interpolation\n\n\tvar r;\n\tvar g;\n\tvar b;\n\tswitch (i) {\n\t\tdefault:\n\t\tcase 6:\n\t\tcase 0: r = v; g = n; b = wh; break;\n\t\tcase 1: r = n; g = v; b = wh; break;\n\t\tcase 2: r = wh; g = v; b = n; break;\n\t\tcase 3: r = wh; g = n; b = v; break;\n\t\tcase 4: r = n; g = wh; b = v; break;\n\t\tcase 5: r = v; g = wh; b = n; break;\n\t}\n\n\treturn [r * 255, g * 255, b * 255];\n};\n\nconvert.cmyk.rgb = function (cmyk) {\n\tvar c = cmyk[0] / 100;\n\tvar m = cmyk[1] / 100;\n\tvar y = cmyk[2] / 100;\n\tvar k = cmyk[3] / 100;\n\tvar r;\n\tvar g;\n\tvar b;\n\n\tr = 1 - Math.min(1, c * (1 - k) + k);\n\tg = 1 - Math.min(1, m * (1 - k) + k);\n\tb = 1 - Math.min(1, y * (1 - k) + k);\n\n\treturn [r * 255, g * 255, b * 255];\n};\n\nconvert.xyz.rgb = function (xyz) {\n\tvar x = xyz[0] / 100;\n\tvar y = xyz[1] / 100;\n\tvar z = xyz[2] / 100;\n\tvar r;\n\tvar g;\n\tvar b;\n\n\tr = (x * 3.2406) + (y * -1.5372) + (z * -0.4986);\n\tg = (x * -0.9689) + (y * 1.8758) + (z * 0.0415);\n\tb = (x * 0.0557) + (y * -0.2040) + (z * 1.0570);\n\n\t// assume sRGB\n\tr = r > 0.0031308\n\t\t? ((1.055 * Math.pow(r, 1.0 / 2.4)) - 0.055)\n\t\t: r * 12.92;\n\n\tg = g > 0.0031308\n\t\t? ((1.055 * Math.pow(g, 1.0 / 2.4)) - 0.055)\n\t\t: g * 12.92;\n\n\tb = b > 0.0031308\n\t\t? ((1.055 * Math.pow(b, 1.0 / 2.4)) - 0.055)\n\t\t: b * 12.92;\n\n\tr = Math.min(Math.max(0, r), 1);\n\tg = Math.min(Math.max(0, g), 1);\n\tb = Math.min(Math.max(0, b), 1);\n\n\treturn [r * 255, g * 255, b * 255];\n};\n\nconvert.xyz.lab = function (xyz) {\n\tvar x = xyz[0];\n\tvar y = xyz[1];\n\tvar z = xyz[2];\n\tvar l;\n\tvar a;\n\tvar b;\n\n\tx /= 95.047;\n\ty /= 100;\n\tz /= 108.883;\n\n\tx = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116);\n\ty = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116);\n\tz = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116);\n\n\tl = (116 * y) - 16;\n\ta = 500 * (x - y);\n\tb = 200 * (y - z);\n\n\treturn [l, a, b];\n};\n\nconvert.lab.xyz = function (lab) {\n\tvar l = lab[0];\n\tvar a = lab[1];\n\tvar b = lab[2];\n\tvar x;\n\tvar y;\n\tvar z;\n\n\ty = (l + 16) / 116;\n\tx = a / 500 + y;\n\tz = y - b / 200;\n\n\tvar y2 = Math.pow(y, 3);\n\tvar x2 = Math.pow(x, 3);\n\tvar z2 = Math.pow(z, 3);\n\ty = y2 > 0.008856 ? y2 : (y - 16 / 116) / 7.787;\n\tx = x2 > 0.008856 ? x2 : (x - 16 / 116) / 7.787;\n\tz = z2 > 0.008856 ? z2 : (z - 16 / 116) / 7.787;\n\n\tx *= 95.047;\n\ty *= 100;\n\tz *= 108.883;\n\n\treturn [x, y, z];\n};\n\nconvert.lab.lch = function (lab) {\n\tvar l = lab[0];\n\tvar a = lab[1];\n\tvar b = lab[2];\n\tvar hr;\n\tvar h;\n\tvar c;\n\n\thr = Math.atan2(b, a);\n\th = hr * 360 / 2 / Math.PI;\n\n\tif (h < 0) {\n\t\th += 360;\n\t}\n\n\tc = Math.sqrt(a * a + b * b);\n\n\treturn [l, c, h];\n};\n\nconvert.lch.lab = function (lch) {\n\tvar l = lch[0];\n\tvar c = lch[1];\n\tvar h = lch[2];\n\tvar a;\n\tvar b;\n\tvar hr;\n\n\thr = h / 360 * 2 * Math.PI;\n\ta = c * Math.cos(hr);\n\tb = c * Math.sin(hr);\n\n\treturn [l, a, b];\n};\n\nconvert.rgb.ansi16 = function (args) {\n\tvar r = args[0];\n\tvar g = args[1];\n\tvar b = args[2];\n\tvar value = 1 in arguments ? arguments[1] : convert.rgb.hsv(args)[2]; // hsv -> ansi16 optimization\n\n\tvalue = Math.round(value / 50);\n\n\tif (value === 0) {\n\t\treturn 30;\n\t}\n\n\tvar ansi = 30\n\t\t+ ((Math.round(b / 255) << 2)\n\t\t| (Math.round(g / 255) << 1)\n\t\t| Math.round(r / 255));\n\n\tif (value === 2) {\n\t\tansi += 60;\n\t}\n\n\treturn ansi;\n};\n\nconvert.hsv.ansi16 = function (args) {\n\t// optimization here; we already know the value and don't need to get\n\t// it converted for us.\n\treturn convert.rgb.ansi16(convert.hsv.rgb(args), args[2]);\n};\n\nconvert.rgb.ansi256 = function (args) {\n\tvar r = args[0];\n\tvar g = args[1];\n\tvar b = args[2];\n\n\t// we use the extended greyscale palette here, with the exception of\n\t// black and white. normal palette only has 4 greyscale shades.\n\tif (r === g && g === b) {\n\t\tif (r < 8) {\n\t\t\treturn 16;\n\t\t}\n\n\t\tif (r > 248) {\n\t\t\treturn 231;\n\t\t}\n\n\t\treturn Math.round(((r - 8) / 247) * 24) + 232;\n\t}\n\n\tvar ansi = 16\n\t\t+ (36 * Math.round(r / 255 * 5))\n\t\t+ (6 * Math.round(g / 255 * 5))\n\t\t+ Math.round(b / 255 * 5);\n\n\treturn ansi;\n};\n\nconvert.ansi16.rgb = function (args) {\n\tvar color = args % 10;\n\n\t// handle greyscale\n\tif (color === 0 || color === 7) {\n\t\tif (args > 50) {\n\t\t\tcolor += 3.5;\n\t\t}\n\n\t\tcolor = color / 10.5 * 255;\n\n\t\treturn [color, color, color];\n\t}\n\n\tvar mult = (~~(args > 50) + 1) * 0.5;\n\tvar r = ((color & 1) * mult) * 255;\n\tvar g = (((color >> 1) & 1) * mult) * 255;\n\tvar b = (((color >> 2) & 1) * mult) * 255;\n\n\treturn [r, g, b];\n};\n\nconvert.ansi256.rgb = function (args) {\n\t// handle greyscale\n\tif (args >= 232) {\n\t\tvar c = (args - 232) * 10 + 8;\n\t\treturn [c, c, c];\n\t}\n\n\targs -= 16;\n\n\tvar rem;\n\tvar r = Math.floor(args / 36) / 5 * 255;\n\tvar g = Math.floor((rem = args % 36) / 6) / 5 * 255;\n\tvar b = (rem % 6) / 5 * 255;\n\n\treturn [r, g, b];\n};\n\nconvert.rgb.hex = function (args) {\n\tvar integer = ((Math.round(args[0]) & 0xFF) << 16)\n\t\t+ ((Math.round(args[1]) & 0xFF) << 8)\n\t\t+ (Math.round(args[2]) & 0xFF);\n\n\tvar string = integer.toString(16).toUpperCase();\n\treturn '000000'.substring(string.length) + string;\n};\n\nconvert.hex.rgb = function (args) {\n\tvar match = args.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);\n\tif (!match) {\n\t\treturn [0, 0, 0];\n\t}\n\n\tvar colorString = match[0];\n\n\tif (match[0].length === 3) {\n\t\tcolorString = colorString.split('').map(function (char) {\n\t\t\treturn char + char;\n\t\t}).join('');\n\t}\n\n\tvar integer = parseInt(colorString, 16);\n\tvar r = (integer >> 16) & 0xFF;\n\tvar g = (integer >> 8) & 0xFF;\n\tvar b = integer & 0xFF;\n\n\treturn [r, g, b];\n};\n\nconvert.rgb.hcg = function (rgb) {\n\tvar r = rgb[0] / 255;\n\tvar g = rgb[1] / 255;\n\tvar b = rgb[2] / 255;\n\tvar max = Math.max(Math.max(r, g), b);\n\tvar min = Math.min(Math.min(r, g), b);\n\tvar chroma = (max - min);\n\tvar grayscale;\n\tvar hue;\n\n\tif (chroma < 1) {\n\t\tgrayscale = min / (1 - chroma);\n\t} else {\n\t\tgrayscale = 0;\n\t}\n\n\tif (chroma <= 0) {\n\t\thue = 0;\n\t} else\n\tif (max === r) {\n\t\thue = ((g - b) / chroma) % 6;\n\t} else\n\tif (max === g) {\n\t\thue = 2 + (b - r) / chroma;\n\t} else {\n\t\thue = 4 + (r - g) / chroma + 4;\n\t}\n\n\thue /= 6;\n\thue %= 1;\n\n\treturn [hue * 360, chroma * 100, grayscale * 100];\n};\n\nconvert.hsl.hcg = function (hsl) {\n\tvar s = hsl[1] / 100;\n\tvar l = hsl[2] / 100;\n\tvar c = 1;\n\tvar f = 0;\n\n\tif (l < 0.5) {\n\t\tc = 2.0 * s * l;\n\t} else {\n\t\tc = 2.0 * s * (1.0 - l);\n\t}\n\n\tif (c < 1.0) {\n\t\tf = (l - 0.5 * c) / (1.0 - c);\n\t}\n\n\treturn [hsl[0], c * 100, f * 100];\n};\n\nconvert.hsv.hcg = function (hsv) {\n\tvar s = hsv[1] / 100;\n\tvar v = hsv[2] / 100;\n\n\tvar c = s * v;\n\tvar f = 0;\n\n\tif (c < 1.0) {\n\t\tf = (v - c) / (1 - c);\n\t}\n\n\treturn [hsv[0], c * 100, f * 100];\n};\n\nconvert.hcg.rgb = function (hcg) {\n\tvar h = hcg[0] / 360;\n\tvar c = hcg[1] / 100;\n\tvar g = hcg[2] / 100;\n\n\tif (c === 0.0) {\n\t\treturn [g * 255, g * 255, g * 255];\n\t}\n\n\tvar pure = [0, 0, 0];\n\tvar hi = (h % 1) * 6;\n\tvar v = hi % 1;\n\tvar w = 1 - v;\n\tvar mg = 0;\n\n\tswitch (Math.floor(hi)) {\n\t\tcase 0:\n\t\t\tpure[0] = 1; pure[1] = v; pure[2] = 0; break;\n\t\tcase 1:\n\t\t\tpure[0] = w; pure[1] = 1; pure[2] = 0; break;\n\t\tcase 2:\n\t\t\tpure[0] = 0; pure[1] = 1; pure[2] = v; break;\n\t\tcase 3:\n\t\t\tpure[0] = 0; pure[1] = w; pure[2] = 1; break;\n\t\tcase 4:\n\t\t\tpure[0] = v; pure[1] = 0; pure[2] = 1; break;\n\t\tdefault:\n\t\t\tpure[0] = 1; pure[1] = 0; pure[2] = w;\n\t}\n\n\tmg = (1.0 - c) * g;\n\n\treturn [\n\t\t(c * pure[0] + mg) * 255,\n\t\t(c * pure[1] + mg) * 255,\n\t\t(c * pure[2] + mg) * 255\n\t];\n};\n\nconvert.hcg.hsv = function (hcg) {\n\tvar c = hcg[1] / 100;\n\tvar g = hcg[2] / 100;\n\n\tvar v = c + g * (1.0 - c);\n\tvar f = 0;\n\n\tif (v > 0.0) {\n\t\tf = c / v;\n\t}\n\n\treturn [hcg[0], f * 100, v * 100];\n};\n\nconvert.hcg.hsl = function (hcg) {\n\tvar c = hcg[1] / 100;\n\tvar g = hcg[2] / 100;\n\n\tvar l = g * (1.0 - c) + 0.5 * c;\n\tvar s = 0;\n\n\tif (l > 0.0 && l < 0.5) {\n\t\ts = c / (2 * l);\n\t} else\n\tif (l >= 0.5 && l < 1.0) {\n\t\ts = c / (2 * (1 - l));\n\t}\n\n\treturn [hcg[0], s * 100, l * 100];\n};\n\nconvert.hcg.hwb = function (hcg) {\n\tvar c = hcg[1] / 100;\n\tvar g = hcg[2] / 100;\n\tvar v = c + g * (1.0 - c);\n\treturn [hcg[0], (v - c) * 100, (1 - v) * 100];\n};\n\nconvert.hwb.hcg = function (hwb) {\n\tvar w = hwb[1] / 100;\n\tvar b = hwb[2] / 100;\n\tvar v = 1 - b;\n\tvar c = v - w;\n\tvar g = 0;\n\n\tif (c < 1) {\n\t\tg = (v - c) / (1 - c);\n\t}\n\n\treturn [hwb[0], c * 100, g * 100];\n};\n\nconvert.apple.rgb = function (apple) {\n\treturn [(apple[0] / 65535) * 255, (apple[1] / 65535) * 255, (apple[2] / 65535) * 255];\n};\n\nconvert.rgb.apple = function (rgb) {\n\treturn [(rgb[0] / 255) * 65535, (rgb[1] / 255) * 65535, (rgb[2] / 255) * 65535];\n};\n\nconvert.gray.rgb = function (args) {\n\treturn [args[0] / 100 * 255, args[0] / 100 * 255, args[0] / 100 * 255];\n};\n\nconvert.gray.hsl = convert.gray.hsv = function (args) {\n\treturn [0, 0, args[0]];\n};\n\nconvert.gray.hwb = function (gray) {\n\treturn [0, 100, gray[0]];\n};\n\nconvert.gray.cmyk = function (gray) {\n\treturn [0, 0, 0, gray[0]];\n};\n\nconvert.gray.lab = function (gray) {\n\treturn [gray[0], 0, 0];\n};\n\nconvert.gray.hex = function (gray) {\n\tvar val = Math.round(gray[0] / 100 * 255) & 0xFF;\n\tvar integer = (val << 16) + (val << 8) + val;\n\n\tvar string = integer.toString(16).toUpperCase();\n\treturn '000000'.substring(string.length) + string;\n};\n\nconvert.rgb.gray = function (rgb) {\n\tvar val = (rgb[0] + rgb[1] + rgb[2]) / 3;\n\treturn [val / 255 * 100];\n};\n});\nvar conversions_1 = conversions.rgb;\nvar conversions_2 = conversions.hsl;\nvar conversions_3 = conversions.hsv;\nvar conversions_4 = conversions.hwb;\nvar conversions_5 = conversions.cmyk;\nvar conversions_6 = conversions.xyz;\nvar conversions_7 = conversions.lab;\nvar conversions_8 = conversions.lch;\nvar conversions_9 = conversions.hex;\nvar conversions_10 = conversions.keyword;\nvar conversions_11 = conversions.ansi16;\nvar conversions_12 = conversions.ansi256;\nvar conversions_13 = conversions.hcg;\nvar conversions_14 = conversions.apple;\nvar conversions_15 = conversions.gray;\n\n/*\n\tthis function routes a model to all other models.\n\n\tall functions that are routed have a property `.conversion` attached\n\tto the returned synthetic function. This property is an array\n\tof strings, each with the steps in between the 'from' and 'to'\n\tcolor models (inclusive).\n\n\tconversions that are not possible simply are not included.\n*/\n\nfunction buildGraph() {\n\tvar graph = {};\n\t// https://jsperf.com/object-keys-vs-for-in-with-closure/3\n\tvar models = Object.keys(conversions);\n\n\tfor (var len = models.length, i = 0; i < len; i++) {\n\t\tgraph[models[i]] = {\n\t\t\t// http://jsperf.com/1-vs-infinity\n\t\t\t// micro-opt, but this is simple.\n\t\t\tdistance: -1,\n\t\t\tparent: null\n\t\t};\n\t}\n\n\treturn graph;\n}\n\n// https://en.wikipedia.org/wiki/Breadth-first_search\nfunction deriveBFS(fromModel) {\n\tvar graph = buildGraph();\n\tvar queue = [fromModel]; // unshift -> queue -> pop\n\n\tgraph[fromModel].distance = 0;\n\n\twhile (queue.length) {\n\t\tvar current = queue.pop();\n\t\tvar adjacents = Object.keys(conversions[current]);\n\n\t\tfor (var len = adjacents.length, i = 0; i < len; i++) {\n\t\t\tvar adjacent = adjacents[i];\n\t\t\tvar node = graph[adjacent];\n\n\t\t\tif (node.distance === -1) {\n\t\t\t\tnode.distance = graph[current].distance + 1;\n\t\t\t\tnode.parent = current;\n\t\t\t\tqueue.unshift(adjacent);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn graph;\n}\n\nfunction link(from, to) {\n\treturn function (args) {\n\t\treturn to(from(args));\n\t};\n}\n\nfunction wrapConversion(toModel, graph) {\n\tvar path = [graph[toModel].parent, toModel];\n\tvar fn = conversions[graph[toModel].parent][toModel];\n\n\tvar cur = graph[toModel].parent;\n\twhile (graph[cur].parent) {\n\t\tpath.unshift(graph[cur].parent);\n\t\tfn = link(conversions[graph[cur].parent][cur], fn);\n\t\tcur = graph[cur].parent;\n\t}\n\n\tfn.conversion = path;\n\treturn fn;\n}\n\nvar route = function (fromModel) {\n\tvar graph = deriveBFS(fromModel);\n\tvar conversion = {};\n\n\tvar models = Object.keys(graph);\n\tfor (var len = models.length, i = 0; i < len; i++) {\n\t\tvar toModel = models[i];\n\t\tvar node = graph[toModel];\n\n\t\tif (node.parent === null) {\n\t\t\t// no possible conversion, or this node is the source model.\n\t\t\tcontinue;\n\t\t}\n\n\t\tconversion[toModel] = wrapConversion(toModel, graph);\n\t}\n\n\treturn conversion;\n};\n\nvar convert = {};\n\nvar models = Object.keys(conversions);\n\nfunction wrapRaw(fn) {\n\tvar wrappedFn = function (args) {\n\t\tif (args === undefined || args === null) {\n\t\t\treturn args;\n\t\t}\n\n\t\tif (arguments.length > 1) {\n\t\t\targs = Array.prototype.slice.call(arguments);\n\t\t}\n\n\t\treturn fn(args);\n\t};\n\n\t// preserve .conversion property if there is one\n\tif ('conversion' in fn) {\n\t\twrappedFn.conversion = fn.conversion;\n\t}\n\n\treturn wrappedFn;\n}\n\nfunction wrapRounded(fn) {\n\tvar wrappedFn = function (args) {\n\t\tif (args === undefined || args === null) {\n\t\t\treturn args;\n\t\t}\n\n\t\tif (arguments.length > 1) {\n\t\t\targs = Array.prototype.slice.call(arguments);\n\t\t}\n\n\t\tvar result = fn(args);\n\n\t\t// we're assuming the result is an array here.\n\t\t// see notice in conversions.js; don't use box types\n\t\t// in conversion functions.\n\t\tif (typeof result === 'object') {\n\t\t\tfor (var len = result.length, i = 0; i < len; i++) {\n\t\t\t\tresult[i] = Math.round(result[i]);\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t};\n\n\t// preserve .conversion property if there is one\n\tif ('conversion' in fn) {\n\t\twrappedFn.conversion = fn.conversion;\n\t}\n\n\treturn wrappedFn;\n}\n\nmodels.forEach(function (fromModel) {\n\tconvert[fromModel] = {};\n\n\tObject.defineProperty(convert[fromModel], 'channels', {value: conversions[fromModel].channels});\n\tObject.defineProperty(convert[fromModel], 'labels', {value: conversions[fromModel].labels});\n\n\tvar routes = route(fromModel);\n\tvar routeModels = Object.keys(routes);\n\n\trouteModels.forEach(function (toModel) {\n\t\tvar fn = routes[toModel];\n\n\t\tconvert[fromModel][toModel] = wrapRounded(fn);\n\t\tconvert[fromModel][toModel].raw = wrapRaw(fn);\n\t});\n});\n\nvar colorConvert = convert;\n\nvar colorName$1 = {\r\n\t\"aliceblue\": [240, 248, 255],\r\n\t\"antiquewhite\": [250, 235, 215],\r\n\t\"aqua\": [0, 255, 255],\r\n\t\"aquamarine\": [127, 255, 212],\r\n\t\"azure\": [240, 255, 255],\r\n\t\"beige\": [245, 245, 220],\r\n\t\"bisque\": [255, 228, 196],\r\n\t\"black\": [0, 0, 0],\r\n\t\"blanchedalmond\": [255, 235, 205],\r\n\t\"blue\": [0, 0, 255],\r\n\t\"blueviolet\": [138, 43, 226],\r\n\t\"brown\": [165, 42, 42],\r\n\t\"burlywood\": [222, 184, 135],\r\n\t\"cadetblue\": [95, 158, 160],\r\n\t\"chartreuse\": [127, 255, 0],\r\n\t\"chocolate\": [210, 105, 30],\r\n\t\"coral\": [255, 127, 80],\r\n\t\"cornflowerblue\": [100, 149, 237],\r\n\t\"cornsilk\": [255, 248, 220],\r\n\t\"crimson\": [220, 20, 60],\r\n\t\"cyan\": [0, 255, 255],\r\n\t\"darkblue\": [0, 0, 139],\r\n\t\"darkcyan\": [0, 139, 139],\r\n\t\"darkgoldenrod\": [184, 134, 11],\r\n\t\"darkgray\": [169, 169, 169],\r\n\t\"darkgreen\": [0, 100, 0],\r\n\t\"darkgrey\": [169, 169, 169],\r\n\t\"darkkhaki\": [189, 183, 107],\r\n\t\"darkmagenta\": [139, 0, 139],\r\n\t\"darkolivegreen\": [85, 107, 47],\r\n\t\"darkorange\": [255, 140, 0],\r\n\t\"darkorchid\": [153, 50, 204],\r\n\t\"darkred\": [139, 0, 0],\r\n\t\"darksalmon\": [233, 150, 122],\r\n\t\"darkseagreen\": [143, 188, 143],\r\n\t\"darkslateblue\": [72, 61, 139],\r\n\t\"darkslategray\": [47, 79, 79],\r\n\t\"darkslategrey\": [47, 79, 79],\r\n\t\"darkturquoise\": [0, 206, 209],\r\n\t\"darkviolet\": [148, 0, 211],\r\n\t\"deeppink\": [255, 20, 147],\r\n\t\"deepskyblue\": [0, 191, 255],\r\n\t\"dimgray\": [105, 105, 105],\r\n\t\"dimgrey\": [105, 105, 105],\r\n\t\"dodgerblue\": [30, 144, 255],\r\n\t\"firebrick\": [178, 34, 34],\r\n\t\"floralwhite\": [255, 250, 240],\r\n\t\"forestgreen\": [34, 139, 34],\r\n\t\"fuchsia\": [255, 0, 255],\r\n\t\"gainsboro\": [220, 220, 220],\r\n\t\"ghostwhite\": [248, 248, 255],\r\n\t\"gold\": [255, 215, 0],\r\n\t\"goldenrod\": [218, 165, 32],\r\n\t\"gray\": [128, 128, 128],\r\n\t\"green\": [0, 128, 0],\r\n\t\"greenyellow\": [173, 255, 47],\r\n\t\"grey\": [128, 128, 128],\r\n\t\"honeydew\": [240, 255, 240],\r\n\t\"hotpink\": [255, 105, 180],\r\n\t\"indianred\": [205, 92, 92],\r\n\t\"indigo\": [75, 0, 130],\r\n\t\"ivory\": [255, 255, 240],\r\n\t\"khaki\": [240, 230, 140],\r\n\t\"lavender\": [230, 230, 250],\r\n\t\"lavenderblush\": [255, 240, 245],\r\n\t\"lawngreen\": [124, 252, 0],\r\n\t\"lemonchiffon\": [255, 250, 205],\r\n\t\"lightblue\": [173, 216, 230],\r\n\t\"lightcoral\": [240, 128, 128],\r\n\t\"lightcyan\": [224, 255, 255],\r\n\t\"lightgoldenrodyellow\": [250, 250, 210],\r\n\t\"lightgray\": [211, 211, 211],\r\n\t\"lightgreen\": [144, 238, 144],\r\n\t\"lightgrey\": [211, 211, 211],\r\n\t\"lightpink\": [255, 182, 193],\r\n\t\"lightsalmon\": [255, 160, 122],\r\n\t\"lightseagreen\": [32, 178, 170],\r\n\t\"lightskyblue\": [135, 206, 250],\r\n\t\"lightslategray\": [119, 136, 153],\r\n\t\"lightslategrey\": [119, 136, 153],\r\n\t\"lightsteelblue\": [176, 196, 222],\r\n\t\"lightyellow\": [255, 255, 224],\r\n\t\"lime\": [0, 255, 0],\r\n\t\"limegreen\": [50, 205, 50],\r\n\t\"linen\": [250, 240, 230],\r\n\t\"magenta\": [255, 0, 255],\r\n\t\"maroon\": [128, 0, 0],\r\n\t\"mediumaquamarine\": [102, 205, 170],\r\n\t\"mediumblue\": [0, 0, 205],\r\n\t\"mediumorchid\": [186, 85, 211],\r\n\t\"mediumpurple\": [147, 112, 219],\r\n\t\"mediumseagreen\": [60, 179, 113],\r\n\t\"mediumslateblue\": [123, 104, 238],\r\n\t\"mediumspringgreen\": [0, 250, 154],\r\n\t\"mediumturquoise\": [72, 209, 204],\r\n\t\"mediumvioletred\": [199, 21, 133],\r\n\t\"midnightblue\": [25, 25, 112],\r\n\t\"mintcream\": [245, 255, 250],\r\n\t\"mistyrose\": [255, 228, 225],\r\n\t\"moccasin\": [255, 228, 181],\r\n\t\"navajowhite\": [255, 222, 173],\r\n\t\"navy\": [0, 0, 128],\r\n\t\"oldlace\": [253, 245, 230],\r\n\t\"olive\": [128, 128, 0],\r\n\t\"olivedrab\": [107, 142, 35],\r\n\t\"orange\": [255, 165, 0],\r\n\t\"orangered\": [255, 69, 0],\r\n\t\"orchid\": [218, 112, 214],\r\n\t\"palegoldenrod\": [238, 232, 170],\r\n\t\"palegreen\": [152, 251, 152],\r\n\t\"paleturquoise\": [175, 238, 238],\r\n\t\"palevioletred\": [219, 112, 147],\r\n\t\"papayawhip\": [255, 239, 213],\r\n\t\"peachpuff\": [255, 218, 185],\r\n\t\"peru\": [205, 133, 63],\r\n\t\"pink\": [255, 192, 203],\r\n\t\"plum\": [221, 160, 221],\r\n\t\"powderblue\": [176, 224, 230],\r\n\t\"purple\": [128, 0, 128],\r\n\t\"rebeccapurple\": [102, 51, 153],\r\n\t\"red\": [255, 0, 0],\r\n\t\"rosybrown\": [188, 143, 143],\r\n\t\"royalblue\": [65, 105, 225],\r\n\t\"saddlebrown\": [139, 69, 19],\r\n\t\"salmon\": [250, 128, 114],\r\n\t\"sandybrown\": [244, 164, 96],\r\n\t\"seagreen\": [46, 139, 87],\r\n\t\"seashell\": [255, 245, 238],\r\n\t\"sienna\": [160, 82, 45],\r\n\t\"silver\": [192, 192, 192],\r\n\t\"skyblue\": [135, 206, 235],\r\n\t\"slateblue\": [106, 90, 205],\r\n\t\"slategray\": [112, 128, 144],\r\n\t\"slategrey\": [112, 128, 144],\r\n\t\"snow\": [255, 250, 250],\r\n\t\"springgreen\": [0, 255, 127],\r\n\t\"steelblue\": [70, 130, 180],\r\n\t\"tan\": [210, 180, 140],\r\n\t\"teal\": [0, 128, 128],\r\n\t\"thistle\": [216, 191, 216],\r\n\t\"tomato\": [255, 99, 71],\r\n\t\"turquoise\": [64, 224, 208],\r\n\t\"violet\": [238, 130, 238],\r\n\t\"wheat\": [245, 222, 179],\r\n\t\"white\": [255, 255, 255],\r\n\t\"whitesmoke\": [245, 245, 245],\r\n\t\"yellow\": [255, 255, 0],\r\n\t\"yellowgreen\": [154, 205, 50]\r\n};\n\n/* MIT license */\n\n\nvar colorString = {\n getRgba: getRgba,\n getHsla: getHsla,\n getRgb: getRgb,\n getHsl: getHsl,\n getHwb: getHwb,\n getAlpha: getAlpha,\n\n hexString: hexString,\n rgbString: rgbString,\n rgbaString: rgbaString,\n percentString: percentString,\n percentaString: percentaString,\n hslString: hslString,\n hslaString: hslaString,\n hwbString: hwbString,\n keyword: keyword\n};\n\nfunction getRgba(string) {\n if (!string) {\n return;\n }\n var abbr = /^#([a-fA-F0-9]{3,4})$/i,\n hex = /^#([a-fA-F0-9]{6}([a-fA-F0-9]{2})?)$/i,\n rgba = /^rgba?\\(\\s*([+-]?\\d+)\\s*,\\s*([+-]?\\d+)\\s*,\\s*([+-]?\\d+)\\s*(?:,\\s*([+-]?[\\d\\.]+)\\s*)?\\)$/i,\n per = /^rgba?\\(\\s*([+-]?[\\d\\.]+)\\%\\s*,\\s*([+-]?[\\d\\.]+)\\%\\s*,\\s*([+-]?[\\d\\.]+)\\%\\s*(?:,\\s*([+-]?[\\d\\.]+)\\s*)?\\)$/i,\n keyword = /(\\w+)/;\n\n var rgb = [0, 0, 0],\n a = 1,\n match = string.match(abbr),\n hexAlpha = \"\";\n if (match) {\n match = match[1];\n hexAlpha = match[3];\n for (var i = 0; i < rgb.length; i++) {\n rgb[i] = parseInt(match[i] + match[i], 16);\n }\n if (hexAlpha) {\n a = Math.round((parseInt(hexAlpha + hexAlpha, 16) / 255) * 100) / 100;\n }\n }\n else if (match = string.match(hex)) {\n hexAlpha = match[2];\n match = match[1];\n for (var i = 0; i < rgb.length; i++) {\n rgb[i] = parseInt(match.slice(i * 2, i * 2 + 2), 16);\n }\n if (hexAlpha) {\n a = Math.round((parseInt(hexAlpha, 16) / 255) * 100) / 100;\n }\n }\n else if (match = string.match(rgba)) {\n for (var i = 0; i < rgb.length; i++) {\n rgb[i] = parseInt(match[i + 1]);\n }\n a = parseFloat(match[4]);\n }\n else if (match = string.match(per)) {\n for (var i = 0; i < rgb.length; i++) {\n rgb[i] = Math.round(parseFloat(match[i + 1]) * 2.55);\n }\n a = parseFloat(match[4]);\n }\n else if (match = string.match(keyword)) {\n if (match[1] == \"transparent\") {\n return [0, 0, 0, 0];\n }\n rgb = colorName$1[match[1]];\n if (!rgb) {\n return;\n }\n }\n\n for (var i = 0; i < rgb.length; i++) {\n rgb[i] = scale(rgb[i], 0, 255);\n }\n if (!a && a != 0) {\n a = 1;\n }\n else {\n a = scale(a, 0, 1);\n }\n rgb[3] = a;\n return rgb;\n}\n\nfunction getHsla(string) {\n if (!string) {\n return;\n }\n var hsl = /^hsla?\\(\\s*([+-]?\\d+)(?:deg)?\\s*,\\s*([+-]?[\\d\\.]+)%\\s*,\\s*([+-]?[\\d\\.]+)%\\s*(?:,\\s*([+-]?[\\d\\.]+)\\s*)?\\)/;\n var match = string.match(hsl);\n if (match) {\n var alpha = parseFloat(match[4]);\n var h = scale(parseInt(match[1]), 0, 360),\n s = scale(parseFloat(match[2]), 0, 100),\n l = scale(parseFloat(match[3]), 0, 100),\n a = scale(isNaN(alpha) ? 1 : alpha, 0, 1);\n return [h, s, l, a];\n }\n}\n\nfunction getHwb(string) {\n if (!string) {\n return;\n }\n var hwb = /^hwb\\(\\s*([+-]?\\d+)(?:deg)?\\s*,\\s*([+-]?[\\d\\.]+)%\\s*,\\s*([+-]?[\\d\\.]+)%\\s*(?:,\\s*([+-]?[\\d\\.]+)\\s*)?\\)/;\n var match = string.match(hwb);\n if (match) {\n var alpha = parseFloat(match[4]);\n var h = scale(parseInt(match[1]), 0, 360),\n w = scale(parseFloat(match[2]), 0, 100),\n b = scale(parseFloat(match[3]), 0, 100),\n a = scale(isNaN(alpha) ? 1 : alpha, 0, 1);\n return [h, w, b, a];\n }\n}\n\nfunction getRgb(string) {\n var rgba = getRgba(string);\n return rgba && rgba.slice(0, 3);\n}\n\nfunction getHsl(string) {\n var hsla = getHsla(string);\n return hsla && hsla.slice(0, 3);\n}\n\nfunction getAlpha(string) {\n var vals = getRgba(string);\n if (vals) {\n return vals[3];\n }\n else if (vals = getHsla(string)) {\n return vals[3];\n }\n else if (vals = getHwb(string)) {\n return vals[3];\n }\n}\n\n// generators\nfunction hexString(rgba, a) {\n var a = (a !== undefined && rgba.length === 3) ? a : rgba[3];\n return \"#\" + hexDouble(rgba[0]) \n + hexDouble(rgba[1])\n + hexDouble(rgba[2])\n + (\n (a >= 0 && a < 1)\n ? hexDouble(Math.round(a * 255))\n : \"\"\n );\n}\n\nfunction rgbString(rgba, alpha) {\n if (alpha < 1 || (rgba[3] && rgba[3] < 1)) {\n return rgbaString(rgba, alpha);\n }\n return \"rgb(\" + rgba[0] + \", \" + rgba[1] + \", \" + rgba[2] + \")\";\n}\n\nfunction rgbaString(rgba, alpha) {\n if (alpha === undefined) {\n alpha = (rgba[3] !== undefined ? rgba[3] : 1);\n }\n return \"rgba(\" + rgba[0] + \", \" + rgba[1] + \", \" + rgba[2]\n + \", \" + alpha + \")\";\n}\n\nfunction percentString(rgba, alpha) {\n if (alpha < 1 || (rgba[3] && rgba[3] < 1)) {\n return percentaString(rgba, alpha);\n }\n var r = Math.round(rgba[0]/255 * 100),\n g = Math.round(rgba[1]/255 * 100),\n b = Math.round(rgba[2]/255 * 100);\n\n return \"rgb(\" + r + \"%, \" + g + \"%, \" + b + \"%)\";\n}\n\nfunction percentaString(rgba, alpha) {\n var r = Math.round(rgba[0]/255 * 100),\n g = Math.round(rgba[1]/255 * 100),\n b = Math.round(rgba[2]/255 * 100);\n return \"rgba(\" + r + \"%, \" + g + \"%, \" + b + \"%, \" + (alpha || rgba[3] || 1) + \")\";\n}\n\nfunction hslString(hsla, alpha) {\n if (alpha < 1 || (hsla[3] && hsla[3] < 1)) {\n return hslaString(hsla, alpha);\n }\n return \"hsl(\" + hsla[0] + \", \" + hsla[1] + \"%, \" + hsla[2] + \"%)\";\n}\n\nfunction hslaString(hsla, alpha) {\n if (alpha === undefined) {\n alpha = (hsla[3] !== undefined ? hsla[3] : 1);\n }\n return \"hsla(\" + hsla[0] + \", \" + hsla[1] + \"%, \" + hsla[2] + \"%, \"\n + alpha + \")\";\n}\n\n// hwb is a bit different than rgb(a) & hsl(a) since there is no alpha specific syntax\n// (hwb have alpha optional & 1 is default value)\nfunction hwbString(hwb, alpha) {\n if (alpha === undefined) {\n alpha = (hwb[3] !== undefined ? hwb[3] : 1);\n }\n return \"hwb(\" + hwb[0] + \", \" + hwb[1] + \"%, \" + hwb[2] + \"%\"\n + (alpha !== undefined && alpha !== 1 ? \", \" + alpha : \"\") + \")\";\n}\n\nfunction keyword(rgb) {\n return reverseNames[rgb.slice(0, 3)];\n}\n\n// helpers\nfunction scale(num, min, max) {\n return Math.min(Math.max(min, num), max);\n}\n\nfunction hexDouble(num) {\n var str = num.toString(16).toUpperCase();\n return (str.length < 2) ? \"0\" + str : str;\n}\n\n\n//create a list of reverse color names\nvar reverseNames = {};\nfor (var name in colorName$1) {\n reverseNames[colorName$1[name]] = name;\n}\n\n/* MIT license */\n\n\n\nvar Color = function (obj) {\n\tif (obj instanceof Color) {\n\t\treturn obj;\n\t}\n\tif (!(this instanceof Color)) {\n\t\treturn new Color(obj);\n\t}\n\n\tthis.valid = false;\n\tthis.values = {\n\t\trgb: [0, 0, 0],\n\t\thsl: [0, 0, 0],\n\t\thsv: [0, 0, 0],\n\t\thwb: [0, 0, 0],\n\t\tcmyk: [0, 0, 0, 0],\n\t\talpha: 1\n\t};\n\n\t// parse Color() argument\n\tvar vals;\n\tif (typeof obj === 'string') {\n\t\tvals = colorString.getRgba(obj);\n\t\tif (vals) {\n\t\t\tthis.setValues('rgb', vals);\n\t\t} else if (vals = colorString.getHsla(obj)) {\n\t\t\tthis.setValues('hsl', vals);\n\t\t} else if (vals = colorString.getHwb(obj)) {\n\t\t\tthis.setValues('hwb', vals);\n\t\t}\n\t} else if (typeof obj === 'object') {\n\t\tvals = obj;\n\t\tif (vals.r !== undefined || vals.red !== undefined) {\n\t\t\tthis.setValues('rgb', vals);\n\t\t} else if (vals.l !== undefined || vals.lightness !== undefined) {\n\t\t\tthis.setValues('hsl', vals);\n\t\t} else if (vals.v !== undefined || vals.value !== undefined) {\n\t\t\tthis.setValues('hsv', vals);\n\t\t} else if (vals.w !== undefined || vals.whiteness !== undefined) {\n\t\t\tthis.setValues('hwb', vals);\n\t\t} else if (vals.c !== undefined || vals.cyan !== undefined) {\n\t\t\tthis.setValues('cmyk', vals);\n\t\t}\n\t}\n};\n\nColor.prototype = {\n\tisValid: function () {\n\t\treturn this.valid;\n\t},\n\trgb: function () {\n\t\treturn this.setSpace('rgb', arguments);\n\t},\n\thsl: function () {\n\t\treturn this.setSpace('hsl', arguments);\n\t},\n\thsv: function () {\n\t\treturn this.setSpace('hsv', arguments);\n\t},\n\thwb: function () {\n\t\treturn this.setSpace('hwb', arguments);\n\t},\n\tcmyk: function () {\n\t\treturn this.setSpace('cmyk', arguments);\n\t},\n\n\trgbArray: function () {\n\t\treturn this.values.rgb;\n\t},\n\thslArray: function () {\n\t\treturn this.values.hsl;\n\t},\n\thsvArray: function () {\n\t\treturn this.values.hsv;\n\t},\n\thwbArray: function () {\n\t\tvar values = this.values;\n\t\tif (values.alpha !== 1) {\n\t\t\treturn values.hwb.concat([values.alpha]);\n\t\t}\n\t\treturn values.hwb;\n\t},\n\tcmykArray: function () {\n\t\treturn this.values.cmyk;\n\t},\n\trgbaArray: function () {\n\t\tvar values = this.values;\n\t\treturn values.rgb.concat([values.alpha]);\n\t},\n\thslaArray: function () {\n\t\tvar values = this.values;\n\t\treturn values.hsl.concat([values.alpha]);\n\t},\n\talpha: function (val) {\n\t\tif (val === undefined) {\n\t\t\treturn this.values.alpha;\n\t\t}\n\t\tthis.setValues('alpha', val);\n\t\treturn this;\n\t},\n\n\tred: function (val) {\n\t\treturn this.setChannel('rgb', 0, val);\n\t},\n\tgreen: function (val) {\n\t\treturn this.setChannel('rgb', 1, val);\n\t},\n\tblue: function (val) {\n\t\treturn this.setChannel('rgb', 2, val);\n\t},\n\thue: function (val) {\n\t\tif (val) {\n\t\t\tval %= 360;\n\t\t\tval = val < 0 ? 360 + val : val;\n\t\t}\n\t\treturn this.setChannel('hsl', 0, val);\n\t},\n\tsaturation: function (val) {\n\t\treturn this.setChannel('hsl', 1, val);\n\t},\n\tlightness: function (val) {\n\t\treturn this.setChannel('hsl', 2, val);\n\t},\n\tsaturationv: function (val) {\n\t\treturn this.setChannel('hsv', 1, val);\n\t},\n\twhiteness: function (val) {\n\t\treturn this.setChannel('hwb', 1, val);\n\t},\n\tblackness: function (val) {\n\t\treturn this.setChannel('hwb', 2, val);\n\t},\n\tvalue: function (val) {\n\t\treturn this.setChannel('hsv', 2, val);\n\t},\n\tcyan: function (val) {\n\t\treturn this.setChannel('cmyk', 0, val);\n\t},\n\tmagenta: function (val) {\n\t\treturn this.setChannel('cmyk', 1, val);\n\t},\n\tyellow: function (val) {\n\t\treturn this.setChannel('cmyk', 2, val);\n\t},\n\tblack: function (val) {\n\t\treturn this.setChannel('cmyk', 3, val);\n\t},\n\n\thexString: function () {\n\t\treturn colorString.hexString(this.values.rgb);\n\t},\n\trgbString: function () {\n\t\treturn colorString.rgbString(this.values.rgb, this.values.alpha);\n\t},\n\trgbaString: function () {\n\t\treturn colorString.rgbaString(this.values.rgb, this.values.alpha);\n\t},\n\tpercentString: function () {\n\t\treturn colorString.percentString(this.values.rgb, this.values.alpha);\n\t},\n\thslString: function () {\n\t\treturn colorString.hslString(this.values.hsl, this.values.alpha);\n\t},\n\thslaString: function () {\n\t\treturn colorString.hslaString(this.values.hsl, this.values.alpha);\n\t},\n\thwbString: function () {\n\t\treturn colorString.hwbString(this.values.hwb, this.values.alpha);\n\t},\n\tkeyword: function () {\n\t\treturn colorString.keyword(this.values.rgb, this.values.alpha);\n\t},\n\n\trgbNumber: function () {\n\t\tvar rgb = this.values.rgb;\n\t\treturn (rgb[0] << 16) | (rgb[1] << 8) | rgb[2];\n\t},\n\n\tluminosity: function () {\n\t\t// http://www.w3.org/TR/WCAG20/#relativeluminancedef\n\t\tvar rgb = this.values.rgb;\n\t\tvar lum = [];\n\t\tfor (var i = 0; i < rgb.length; i++) {\n\t\t\tvar chan = rgb[i] / 255;\n\t\t\tlum[i] = (chan <= 0.03928) ? chan / 12.92 : Math.pow(((chan + 0.055) / 1.055), 2.4);\n\t\t}\n\t\treturn 0.2126 * lum[0] + 0.7152 * lum[1] + 0.0722 * lum[2];\n\t},\n\n\tcontrast: function (color2) {\n\t\t// http://www.w3.org/TR/WCAG20/#contrast-ratiodef\n\t\tvar lum1 = this.luminosity();\n\t\tvar lum2 = color2.luminosity();\n\t\tif (lum1 > lum2) {\n\t\t\treturn (lum1 + 0.05) / (lum2 + 0.05);\n\t\t}\n\t\treturn (lum2 + 0.05) / (lum1 + 0.05);\n\t},\n\n\tlevel: function (color2) {\n\t\tvar contrastRatio = this.contrast(color2);\n\t\tif (contrastRatio >= 7.1) {\n\t\t\treturn 'AAA';\n\t\t}\n\n\t\treturn (contrastRatio >= 4.5) ? 'AA' : '';\n\t},\n\n\tdark: function () {\n\t\t// YIQ equation from http://24ways.org/2010/calculating-color-contrast\n\t\tvar rgb = this.values.rgb;\n\t\tvar yiq = (rgb[0] * 299 + rgb[1] * 587 + rgb[2] * 114) / 1000;\n\t\treturn yiq < 128;\n\t},\n\n\tlight: function () {\n\t\treturn !this.dark();\n\t},\n\n\tnegate: function () {\n\t\tvar rgb = [];\n\t\tfor (var i = 0; i < 3; i++) {\n\t\t\trgb[i] = 255 - this.values.rgb[i];\n\t\t}\n\t\tthis.setValues('rgb', rgb);\n\t\treturn this;\n\t},\n\n\tlighten: function (ratio) {\n\t\tvar hsl = this.values.hsl;\n\t\thsl[2] += hsl[2] * ratio;\n\t\tthis.setValues('hsl', hsl);\n\t\treturn this;\n\t},\n\n\tdarken: function (ratio) {\n\t\tvar hsl = this.values.hsl;\n\t\thsl[2] -= hsl[2] * ratio;\n\t\tthis.setValues('hsl', hsl);\n\t\treturn this;\n\t},\n\n\tsaturate: function (ratio) {\n\t\tvar hsl = this.values.hsl;\n\t\thsl[1] += hsl[1] * ratio;\n\t\tthis.setValues('hsl', hsl);\n\t\treturn this;\n\t},\n\n\tdesaturate: function (ratio) {\n\t\tvar hsl = this.values.hsl;\n\t\thsl[1] -= hsl[1] * ratio;\n\t\tthis.setValues('hsl', hsl);\n\t\treturn this;\n\t},\n\n\twhiten: function (ratio) {\n\t\tvar hwb = this.values.hwb;\n\t\thwb[1] += hwb[1] * ratio;\n\t\tthis.setValues('hwb', hwb);\n\t\treturn this;\n\t},\n\n\tblacken: function (ratio) {\n\t\tvar hwb = this.values.hwb;\n\t\thwb[2] += hwb[2] * ratio;\n\t\tthis.setValues('hwb', hwb);\n\t\treturn this;\n\t},\n\n\tgreyscale: function () {\n\t\tvar rgb = this.values.rgb;\n\t\t// http://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale\n\t\tvar val = rgb[0] * 0.3 + rgb[1] * 0.59 + rgb[2] * 0.11;\n\t\tthis.setValues('rgb', [val, val, val]);\n\t\treturn this;\n\t},\n\n\tclearer: function (ratio) {\n\t\tvar alpha = this.values.alpha;\n\t\tthis.setValues('alpha', alpha - (alpha * ratio));\n\t\treturn this;\n\t},\n\n\topaquer: function (ratio) {\n\t\tvar alpha = this.values.alpha;\n\t\tthis.setValues('alpha', alpha + (alpha * ratio));\n\t\treturn this;\n\t},\n\n\trotate: function (degrees) {\n\t\tvar hsl = this.values.hsl;\n\t\tvar hue = (hsl[0] + degrees) % 360;\n\t\thsl[0] = hue < 0 ? 360 + hue : hue;\n\t\tthis.setValues('hsl', hsl);\n\t\treturn this;\n\t},\n\n\t/**\n\t * Ported from sass implementation in C\n\t * https://github.com/sass/libsass/blob/0e6b4a2850092356aa3ece07c6b249f0221caced/functions.cpp#L209\n\t */\n\tmix: function (mixinColor, weight) {\n\t\tvar color1 = this;\n\t\tvar color2 = mixinColor;\n\t\tvar p = weight === undefined ? 0.5 : weight;\n\n\t\tvar w = 2 * p - 1;\n\t\tvar a = color1.alpha() - color2.alpha();\n\n\t\tvar w1 = (((w * a === -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;\n\t\tvar w2 = 1 - w1;\n\n\t\treturn this\n\t\t\t.rgb(\n\t\t\t\tw1 * color1.red() + w2 * color2.red(),\n\t\t\t\tw1 * color1.green() + w2 * color2.green(),\n\t\t\t\tw1 * color1.blue() + w2 * color2.blue()\n\t\t\t)\n\t\t\t.alpha(color1.alpha() * p + color2.alpha() * (1 - p));\n\t},\n\n\ttoJSON: function () {\n\t\treturn this.rgb();\n\t},\n\n\tclone: function () {\n\t\t// NOTE(SB): using node-clone creates a dependency to Buffer when using browserify,\n\t\t// making the final build way to big to embed in Chart.js. So let's do it manually,\n\t\t// assuming that values to clone are 1 dimension arrays containing only numbers,\n\t\t// except 'alpha' which is a number.\n\t\tvar result = new Color();\n\t\tvar source = this.values;\n\t\tvar target = result.values;\n\t\tvar value, type;\n\n\t\tfor (var prop in source) {\n\t\t\tif (source.hasOwnProperty(prop)) {\n\t\t\t\tvalue = source[prop];\n\t\t\t\ttype = ({}).toString.call(value);\n\t\t\t\tif (type === '[object Array]') {\n\t\t\t\t\ttarget[prop] = value.slice(0);\n\t\t\t\t} else if (type === '[object Number]') {\n\t\t\t\t\ttarget[prop] = value;\n\t\t\t\t} else {\n\t\t\t\t\tconsole.error('unexpected color value:', value);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n};\n\nColor.prototype.spaces = {\n\trgb: ['red', 'green', 'blue'],\n\thsl: ['hue', 'saturation', 'lightness'],\n\thsv: ['hue', 'saturation', 'value'],\n\thwb: ['hue', 'whiteness', 'blackness'],\n\tcmyk: ['cyan', 'magenta', 'yellow', 'black']\n};\n\nColor.prototype.maxes = {\n\trgb: [255, 255, 255],\n\thsl: [360, 100, 100],\n\thsv: [360, 100, 100],\n\thwb: [360, 100, 100],\n\tcmyk: [100, 100, 100, 100]\n};\n\nColor.prototype.getValues = function (space) {\n\tvar values = this.values;\n\tvar vals = {};\n\n\tfor (var i = 0; i < space.length; i++) {\n\t\tvals[space.charAt(i)] = values[space][i];\n\t}\n\n\tif (values.alpha !== 1) {\n\t\tvals.a = values.alpha;\n\t}\n\n\t// {r: 255, g: 255, b: 255, a: 0.4}\n\treturn vals;\n};\n\nColor.prototype.setValues = function (space, vals) {\n\tvar values = this.values;\n\tvar spaces = this.spaces;\n\tvar maxes = this.maxes;\n\tvar alpha = 1;\n\tvar i;\n\n\tthis.valid = true;\n\n\tif (space === 'alpha') {\n\t\talpha = vals;\n\t} else if (vals.length) {\n\t\t// [10, 10, 10]\n\t\tvalues[space] = vals.slice(0, space.length);\n\t\talpha = vals[space.length];\n\t} else if (vals[space.charAt(0)] !== undefined) {\n\t\t// {r: 10, g: 10, b: 10}\n\t\tfor (i = 0; i < space.length; i++) {\n\t\t\tvalues[space][i] = vals[space.charAt(i)];\n\t\t}\n\n\t\talpha = vals.a;\n\t} else if (vals[spaces[space][0]] !== undefined) {\n\t\t// {red: 10, green: 10, blue: 10}\n\t\tvar chans = spaces[space];\n\n\t\tfor (i = 0; i < space.length; i++) {\n\t\t\tvalues[space][i] = vals[chans[i]];\n\t\t}\n\n\t\talpha = vals.alpha;\n\t}\n\n\tvalues.alpha = Math.max(0, Math.min(1, (alpha === undefined ? values.alpha : alpha)));\n\n\tif (space === 'alpha') {\n\t\treturn false;\n\t}\n\n\tvar capped;\n\n\t// cap values of the space prior converting all values\n\tfor (i = 0; i < space.length; i++) {\n\t\tcapped = Math.max(0, Math.min(maxes[space][i], values[space][i]));\n\t\tvalues[space][i] = Math.round(capped);\n\t}\n\n\t// convert to all the other color spaces\n\tfor (var sname in spaces) {\n\t\tif (sname !== space) {\n\t\t\tvalues[sname] = colorConvert[space][sname](values[space]);\n\t\t}\n\t}\n\n\treturn true;\n};\n\nColor.prototype.setSpace = function (space, args) {\n\tvar vals = args[0];\n\n\tif (vals === undefined) {\n\t\t// color.rgb()\n\t\treturn this.getValues(space);\n\t}\n\n\t// color.rgb(10, 10, 10)\n\tif (typeof vals === 'number') {\n\t\tvals = Array.prototype.slice.call(args);\n\t}\n\n\tthis.setValues(space, vals);\n\treturn this;\n};\n\nColor.prototype.setChannel = function (space, index, val) {\n\tvar svalues = this.values[space];\n\tif (val === undefined) {\n\t\t// color.red()\n\t\treturn svalues[index];\n\t} else if (val === svalues[index]) {\n\t\t// color.red(color.red())\n\t\treturn this;\n\t}\n\n\t// color.red(100)\n\tsvalues[index] = val;\n\tthis.setValues(space, svalues);\n\n\treturn this;\n};\n\nif (typeof window !== 'undefined') {\n\twindow.Color = Color;\n}\n\nvar chartjsColor = Color;\n\nfunction isValidKey(key) {\r\n\treturn ['__proto__', 'prototype', 'constructor'].indexOf(key) === -1;\r\n}\r\n\r\n/**\r\n * @namespace Chart.helpers\r\n */\r\nvar helpers = {\r\n\t/**\r\n\t * An empty function that can be used, for example, for optional callback.\r\n\t */\r\n\tnoop: function() {},\r\n\r\n\t/**\r\n\t * Returns a unique id, sequentially generated from a global variable.\r\n\t * @returns {number}\r\n\t * @function\r\n\t */\r\n\tuid: (function() {\r\n\t\tvar id = 0;\r\n\t\treturn function() {\r\n\t\t\treturn id++;\r\n\t\t};\r\n\t}()),\r\n\r\n\t/**\r\n\t * Returns true if `value` is neither null nor undefined, else returns false.\r\n\t * @param {*} value - The value to test.\r\n\t * @returns {boolean}\r\n\t * @since 2.7.0\r\n\t */\r\n\tisNullOrUndef: function(value) {\r\n\t\treturn value === null || typeof value === 'undefined';\r\n\t},\r\n\r\n\t/**\r\n\t * Returns true if `value` is an array (including typed arrays), else returns false.\r\n\t * @param {*} value - The value to test.\r\n\t * @returns {boolean}\r\n\t * @function\r\n\t */\r\n\tisArray: function(value) {\r\n\t\tif (Array.isArray && Array.isArray(value)) {\r\n\t\t\treturn true;\r\n\t\t}\r\n\t\tvar type = Object.prototype.toString.call(value);\r\n\t\tif (type.substr(0, 7) === '[object' && type.substr(-6) === 'Array]') {\r\n\t\t\treturn true;\r\n\t\t}\r\n\t\treturn false;\r\n\t},\r\n\r\n\t/**\r\n\t * Returns true if `value` is an object (excluding null), else returns false.\r\n\t * @param {*} value - The value to test.\r\n\t * @returns {boolean}\r\n\t * @since 2.7.0\r\n\t */\r\n\tisObject: function(value) {\r\n\t\treturn value !== null && Object.prototype.toString.call(value) === '[object Object]';\r\n\t},\r\n\r\n\t/**\r\n\t * Returns true if `value` is a finite number, else returns false\r\n\t * @param {*} value - The value to test.\r\n\t * @returns {boolean}\r\n\t */\r\n\tisFinite: function(value) {\r\n\t\treturn (typeof value === 'number' || value instanceof Number) && isFinite(value);\r\n\t},\r\n\r\n\t/**\r\n\t * Returns `value` if defined, else returns `defaultValue`.\r\n\t * @param {*} value - The value to return if defined.\r\n\t * @param {*} defaultValue - The value to return if `value` is undefined.\r\n\t * @returns {*}\r\n\t */\r\n\tvalueOrDefault: function(value, defaultValue) {\r\n\t\treturn typeof value === 'undefined' ? defaultValue : value;\r\n\t},\r\n\r\n\t/**\r\n\t * Returns value at the given `index` in array if defined, else returns `defaultValue`.\r\n\t * @param {Array} value - The array to lookup for value at `index`.\r\n\t * @param {number} index - The index in `value` to lookup for value.\r\n\t * @param {*} defaultValue - The value to return if `value[index]` is undefined.\r\n\t * @returns {*}\r\n\t */\r\n\tvalueAtIndexOrDefault: function(value, index, defaultValue) {\r\n\t\treturn helpers.valueOrDefault(helpers.isArray(value) ? value[index] : value, defaultValue);\r\n\t},\r\n\r\n\t/**\r\n\t * Calls `fn` with the given `args` in the scope defined by `thisArg` and returns the\r\n\t * value returned by `fn`. If `fn` is not a function, this method returns undefined.\r\n\t * @param {function} fn - The function to call.\r\n\t * @param {Array|undefined|null} args - The arguments with which `fn` should be called.\r\n\t * @param {object} [thisArg] - The value of `this` provided for the call to `fn`.\r\n\t * @returns {*}\r\n\t */\r\n\tcallback: function(fn, args, thisArg) {\r\n\t\tif (fn && typeof fn.call === 'function') {\r\n\t\t\treturn fn.apply(thisArg, args);\r\n\t\t}\r\n\t},\r\n\r\n\t/**\r\n\t * Note(SB) for performance sake, this method should only be used when loopable type\r\n\t * is unknown or in none intensive code (not called often and small loopable). Else\r\n\t * it's preferable to use a regular for() loop and save extra function calls.\r\n\t * @param {object|Array} loopable - The object or array to be iterated.\r\n\t * @param {function} fn - The function to call for each item.\r\n\t * @param {object} [thisArg] - The value of `this` provided for the call to `fn`.\r\n\t * @param {boolean} [reverse] - If true, iterates backward on the loopable.\r\n\t */\r\n\teach: function(loopable, fn, thisArg, reverse) {\r\n\t\tvar i, len, keys;\r\n\t\tif (helpers.isArray(loopable)) {\r\n\t\t\tlen = loopable.length;\r\n\t\t\tif (reverse) {\r\n\t\t\t\tfor (i = len - 1; i >= 0; i--) {\r\n\t\t\t\t\tfn.call(thisArg, loopable[i], i);\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tfor (i = 0; i < len; i++) {\r\n\t\t\t\t\tfn.call(thisArg, loopable[i], i);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t} else if (helpers.isObject(loopable)) {\r\n\t\t\tkeys = Object.keys(loopable);\r\n\t\t\tlen = keys.length;\r\n\t\t\tfor (i = 0; i < len; i++) {\r\n\t\t\t\tfn.call(thisArg, loopable[keys[i]], keys[i]);\r\n\t\t\t}\r\n\t\t}\r\n\t},\r\n\r\n\t/**\r\n\t * Returns true if the `a0` and `a1` arrays have the same content, else returns false.\r\n\t * @see https://stackoverflow.com/a/14853974\r\n\t * @param {Array} a0 - The array to compare\r\n\t * @param {Array} a1 - The array to compare\r\n\t * @returns {boolean}\r\n\t */\r\n\tarrayEquals: function(a0, a1) {\r\n\t\tvar i, ilen, v0, v1;\r\n\r\n\t\tif (!a0 || !a1 || a0.length !== a1.length) {\r\n\t\t\treturn false;\r\n\t\t}\r\n\r\n\t\tfor (i = 0, ilen = a0.length; i < ilen; ++i) {\r\n\t\t\tv0 = a0[i];\r\n\t\t\tv1 = a1[i];\r\n\r\n\t\t\tif (v0 instanceof Array && v1 instanceof Array) {\r\n\t\t\t\tif (!helpers.arrayEquals(v0, v1)) {\r\n\t\t\t\t\treturn false;\r\n\t\t\t\t}\r\n\t\t\t} else if (v0 !== v1) {\r\n\t\t\t\t// NOTE: two different object instances will never be equal: {x:20} != {x:20}\r\n\t\t\t\treturn false;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn true;\r\n\t},\r\n\r\n\t/**\r\n\t * Returns a deep copy of `source` without keeping references on objects and arrays.\r\n\t * @param {*} source - The value to clone.\r\n\t * @returns {*}\r\n\t */\r\n\tclone: function(source) {\r\n\t\tif (helpers.isArray(source)) {\r\n\t\t\treturn source.map(helpers.clone);\r\n\t\t}\r\n\r\n\t\tif (helpers.isObject(source)) {\r\n\t\t\tvar target = Object.create(source);\r\n\t\t\tvar keys = Object.keys(source);\r\n\t\t\tvar klen = keys.length;\r\n\t\t\tvar k = 0;\r\n\r\n\t\t\tfor (; k < klen; ++k) {\r\n\t\t\t\ttarget[keys[k]] = helpers.clone(source[keys[k]]);\r\n\t\t\t}\r\n\r\n\t\t\treturn target;\r\n\t\t}\r\n\r\n\t\treturn source;\r\n\t},\r\n\r\n\t/**\r\n\t * The default merger when Chart.helpers.merge is called without merger option.\r\n\t * Note(SB): also used by mergeConfig and mergeScaleConfig as fallback.\r\n\t * @private\r\n\t */\r\n\t_merger: function(key, target, source, options) {\r\n\t\tif (!isValidKey(key)) {\r\n\t\t\t// We want to ensure we do not copy prototypes over\r\n\t\t\t// as this can pollute global namespaces\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tvar tval = target[key];\r\n\t\tvar sval = source[key];\r\n\r\n\t\tif (helpers.isObject(tval) && helpers.isObject(sval)) {\r\n\t\t\thelpers.merge(tval, sval, options);\r\n\t\t} else {\r\n\t\t\ttarget[key] = helpers.clone(sval);\r\n\t\t}\r\n\t},\r\n\r\n\t/**\r\n\t * Merges source[key] in target[key] only if target[key] is undefined.\r\n\t * @private\r\n\t */\r\n\t_mergerIf: function(key, target, source) {\r\n\t\tif (!isValidKey(key)) {\r\n\t\t\t// We want to ensure we do not copy prototypes over\r\n\t\t\t// as this can pollute global namespaces\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tvar tval = target[key];\r\n\t\tvar sval = source[key];\r\n\r\n\t\tif (helpers.isObject(tval) && helpers.isObject(sval)) {\r\n\t\t\thelpers.mergeIf(tval, sval);\r\n\t\t} else if (!target.hasOwnProperty(key)) {\r\n\t\t\ttarget[key] = helpers.clone(sval);\r\n\t\t}\r\n\t},\r\n\r\n\t/**\r\n\t * Recursively deep copies `source` properties into `target` with the given `options`.\r\n\t * IMPORTANT: `target` is not cloned and will be updated with `source` properties.\r\n\t * @param {object} target - The target object in which all sources are merged into.\r\n\t * @param {object|object[]} source - Object(s) to merge into `target`.\r\n\t * @param {object} [options] - Merging options:\r\n\t * @param {function} [options.merger] - The merge method (key, target, source, options)\r\n\t * @returns {object} The `target` object.\r\n\t */\r\n\tmerge: function(target, source, options) {\r\n\t\tvar sources = helpers.isArray(source) ? source : [source];\r\n\t\tvar ilen = sources.length;\r\n\t\tvar merge, i, keys, klen, k;\r\n\r\n\t\tif (!helpers.isObject(target)) {\r\n\t\t\treturn target;\r\n\t\t}\r\n\r\n\t\toptions = options || {};\r\n\t\tmerge = options.merger || helpers._merger;\r\n\r\n\t\tfor (i = 0; i < ilen; ++i) {\r\n\t\t\tsource = sources[i];\r\n\t\t\tif (!helpers.isObject(source)) {\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\r\n\t\t\tkeys = Object.keys(source);\r\n\t\t\tfor (k = 0, klen = keys.length; k < klen; ++k) {\r\n\t\t\t\tmerge(keys[k], target, source, options);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn target;\r\n\t},\r\n\r\n\t/**\r\n\t * Recursively deep copies `source` properties into `target` *only* if not defined in target.\r\n\t * IMPORTANT: `target` is not cloned and will be updated with `source` properties.\r\n\t * @param {object} target - The target object in which all sources are merged into.\r\n\t * @param {object|object[]} source - Object(s) to merge into `target`.\r\n\t * @returns {object} The `target` object.\r\n\t */\r\n\tmergeIf: function(target, source) {\r\n\t\treturn helpers.merge(target, source, {merger: helpers._mergerIf});\r\n\t},\r\n\r\n\t/**\r\n\t * Applies the contents of two or more objects together into the first object.\r\n\t * @param {object} target - The target object in which all objects are merged into.\r\n\t * @param {object} arg1 - Object containing additional properties to merge in target.\r\n\t * @param {object} argN - Additional objects containing properties to merge in target.\r\n\t * @returns {object} The `target` object.\r\n\t */\r\n\textend: Object.assign || function(target) {\r\n\t\treturn helpers.merge(target, [].slice.call(arguments, 1), {\r\n\t\t\tmerger: function(key, dst, src) {\r\n\t\t\t\tdst[key] = src[key];\r\n\t\t\t}\r\n\t\t});\r\n\t},\r\n\r\n\t/**\r\n\t * Basic javascript inheritance based on the model created in Backbone.js\r\n\t */\r\n\tinherits: function(extensions) {\r\n\t\tvar me = this;\r\n\t\tvar ChartElement = (extensions && extensions.hasOwnProperty('constructor')) ? extensions.constructor : function() {\r\n\t\t\treturn me.apply(this, arguments);\r\n\t\t};\r\n\r\n\t\tvar Surrogate = function() {\r\n\t\t\tthis.constructor = ChartElement;\r\n\t\t};\r\n\r\n\t\tSurrogate.prototype = me.prototype;\r\n\t\tChartElement.prototype = new Surrogate();\r\n\t\tChartElement.extend = helpers.inherits;\r\n\r\n\t\tif (extensions) {\r\n\t\t\thelpers.extend(ChartElement.prototype, extensions);\r\n\t\t}\r\n\r\n\t\tChartElement.__super__ = me.prototype;\r\n\t\treturn ChartElement;\r\n\t},\r\n\r\n\t_deprecated: function(scope, value, previous, current) {\r\n\t\tif (value !== undefined) {\r\n\t\t\tconsole.warn(scope + ': \"' + previous +\r\n\t\t\t\t'\" is deprecated. Please use \"' + current + '\" instead');\r\n\t\t}\r\n\t}\r\n};\r\n\r\nvar helpers_core = helpers;\r\n\r\n// DEPRECATIONS\r\n\r\n/**\r\n * Provided for backward compatibility, use Chart.helpers.callback instead.\r\n * @function Chart.helpers.callCallback\r\n * @deprecated since version 2.6.0\r\n * @todo remove at version 3\r\n * @private\r\n */\r\nhelpers.callCallback = helpers.callback;\r\n\r\n/**\r\n * Provided for backward compatibility, use Array.prototype.indexOf instead.\r\n * Array.prototype.indexOf compatibility: Chrome, Opera, Safari, FF1.5+, IE9+\r\n * @function Chart.helpers.indexOf\r\n * @deprecated since version 2.7.0\r\n * @todo remove at version 3\r\n * @private\r\n */\r\nhelpers.indexOf = function(array, item, fromIndex) {\r\n\treturn Array.prototype.indexOf.call(array, item, fromIndex);\r\n};\r\n\r\n/**\r\n * Provided for backward compatibility, use Chart.helpers.valueOrDefault instead.\r\n * @function Chart.helpers.getValueOrDefault\r\n * @deprecated since version 2.7.0\r\n * @todo remove at version 3\r\n * @private\r\n */\r\nhelpers.getValueOrDefault = helpers.valueOrDefault;\r\n\r\n/**\r\n * Provided for backward compatibility, use Chart.helpers.valueAtIndexOrDefault instead.\r\n * @function Chart.helpers.getValueAtIndexOrDefault\r\n * @deprecated since version 2.7.0\r\n * @todo remove at version 3\r\n * @private\r\n */\r\nhelpers.getValueAtIndexOrDefault = helpers.valueAtIndexOrDefault;\n\n/**\r\n * Easing functions adapted from Robert Penner's easing equations.\r\n * @namespace Chart.helpers.easingEffects\r\n * @see http://www.robertpenner.com/easing/\r\n */\r\nvar effects = {\r\n\tlinear: function(t) {\r\n\t\treturn t;\r\n\t},\r\n\r\n\teaseInQuad: function(t) {\r\n\t\treturn t * t;\r\n\t},\r\n\r\n\teaseOutQuad: function(t) {\r\n\t\treturn -t * (t - 2);\r\n\t},\r\n\r\n\teaseInOutQuad: function(t) {\r\n\t\tif ((t /= 0.5) < 1) {\r\n\t\t\treturn 0.5 * t * t;\r\n\t\t}\r\n\t\treturn -0.5 * ((--t) * (t - 2) - 1);\r\n\t},\r\n\r\n\teaseInCubic: function(t) {\r\n\t\treturn t * t * t;\r\n\t},\r\n\r\n\teaseOutCubic: function(t) {\r\n\t\treturn (t = t - 1) * t * t + 1;\r\n\t},\r\n\r\n\teaseInOutCubic: function(t) {\r\n\t\tif ((t /= 0.5) < 1) {\r\n\t\t\treturn 0.5 * t * t * t;\r\n\t\t}\r\n\t\treturn 0.5 * ((t -= 2) * t * t + 2);\r\n\t},\r\n\r\n\teaseInQuart: function(t) {\r\n\t\treturn t * t * t * t;\r\n\t},\r\n\r\n\teaseOutQuart: function(t) {\r\n\t\treturn -((t = t - 1) * t * t * t - 1);\r\n\t},\r\n\r\n\teaseInOutQuart: function(t) {\r\n\t\tif ((t /= 0.5) < 1) {\r\n\t\t\treturn 0.5 * t * t * t * t;\r\n\t\t}\r\n\t\treturn -0.5 * ((t -= 2) * t * t * t - 2);\r\n\t},\r\n\r\n\teaseInQuint: function(t) {\r\n\t\treturn t * t * t * t * t;\r\n\t},\r\n\r\n\teaseOutQuint: function(t) {\r\n\t\treturn (t = t - 1) * t * t * t * t + 1;\r\n\t},\r\n\r\n\teaseInOutQuint: function(t) {\r\n\t\tif ((t /= 0.5) < 1) {\r\n\t\t\treturn 0.5 * t * t * t * t * t;\r\n\t\t}\r\n\t\treturn 0.5 * ((t -= 2) * t * t * t * t + 2);\r\n\t},\r\n\r\n\teaseInSine: function(t) {\r\n\t\treturn -Math.cos(t * (Math.PI / 2)) + 1;\r\n\t},\r\n\r\n\teaseOutSine: function(t) {\r\n\t\treturn Math.sin(t * (Math.PI / 2));\r\n\t},\r\n\r\n\teaseInOutSine: function(t) {\r\n\t\treturn -0.5 * (Math.cos(Math.PI * t) - 1);\r\n\t},\r\n\r\n\teaseInExpo: function(t) {\r\n\t\treturn (t === 0) ? 0 : Math.pow(2, 10 * (t - 1));\r\n\t},\r\n\r\n\teaseOutExpo: function(t) {\r\n\t\treturn (t === 1) ? 1 : -Math.pow(2, -10 * t) + 1;\r\n\t},\r\n\r\n\teaseInOutExpo: function(t) {\r\n\t\tif (t === 0) {\r\n\t\t\treturn 0;\r\n\t\t}\r\n\t\tif (t === 1) {\r\n\t\t\treturn 1;\r\n\t\t}\r\n\t\tif ((t /= 0.5) < 1) {\r\n\t\t\treturn 0.5 * Math.pow(2, 10 * (t - 1));\r\n\t\t}\r\n\t\treturn 0.5 * (-Math.pow(2, -10 * --t) + 2);\r\n\t},\r\n\r\n\teaseInCirc: function(t) {\r\n\t\tif (t >= 1) {\r\n\t\t\treturn t;\r\n\t\t}\r\n\t\treturn -(Math.sqrt(1 - t * t) - 1);\r\n\t},\r\n\r\n\teaseOutCirc: function(t) {\r\n\t\treturn Math.sqrt(1 - (t = t - 1) * t);\r\n\t},\r\n\r\n\teaseInOutCirc: function(t) {\r\n\t\tif ((t /= 0.5) < 1) {\r\n\t\t\treturn -0.5 * (Math.sqrt(1 - t * t) - 1);\r\n\t\t}\r\n\t\treturn 0.5 * (Math.sqrt(1 - (t -= 2) * t) + 1);\r\n\t},\r\n\r\n\teaseInElastic: function(t) {\r\n\t\tvar s = 1.70158;\r\n\t\tvar p = 0;\r\n\t\tvar a = 1;\r\n\t\tif (t === 0) {\r\n\t\t\treturn 0;\r\n\t\t}\r\n\t\tif (t === 1) {\r\n\t\t\treturn 1;\r\n\t\t}\r\n\t\tif (!p) {\r\n\t\t\tp = 0.3;\r\n\t\t}\r\n\t\tif (a < 1) {\r\n\t\t\ta = 1;\r\n\t\t\ts = p / 4;\r\n\t\t} else {\r\n\t\t\ts = p / (2 * Math.PI) * Math.asin(1 / a);\r\n\t\t}\r\n\t\treturn -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t - s) * (2 * Math.PI) / p));\r\n\t},\r\n\r\n\teaseOutElastic: function(t) {\r\n\t\tvar s = 1.70158;\r\n\t\tvar p = 0;\r\n\t\tvar a = 1;\r\n\t\tif (t === 0) {\r\n\t\t\treturn 0;\r\n\t\t}\r\n\t\tif (t === 1) {\r\n\t\t\treturn 1;\r\n\t\t}\r\n\t\tif (!p) {\r\n\t\t\tp = 0.3;\r\n\t\t}\r\n\t\tif (a < 1) {\r\n\t\t\ta = 1;\r\n\t\t\ts = p / 4;\r\n\t\t} else {\r\n\t\t\ts = p / (2 * Math.PI) * Math.asin(1 / a);\r\n\t\t}\r\n\t\treturn a * Math.pow(2, -10 * t) * Math.sin((t - s) * (2 * Math.PI) / p) + 1;\r\n\t},\r\n\r\n\teaseInOutElastic: function(t) {\r\n\t\tvar s = 1.70158;\r\n\t\tvar p = 0;\r\n\t\tvar a = 1;\r\n\t\tif (t === 0) {\r\n\t\t\treturn 0;\r\n\t\t}\r\n\t\tif ((t /= 0.5) === 2) {\r\n\t\t\treturn 1;\r\n\t\t}\r\n\t\tif (!p) {\r\n\t\t\tp = 0.45;\r\n\t\t}\r\n\t\tif (a < 1) {\r\n\t\t\ta = 1;\r\n\t\t\ts = p / 4;\r\n\t\t} else {\r\n\t\t\ts = p / (2 * Math.PI) * Math.asin(1 / a);\r\n\t\t}\r\n\t\tif (t < 1) {\r\n\t\t\treturn -0.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t - s) * (2 * Math.PI) / p));\r\n\t\t}\r\n\t\treturn a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t - s) * (2 * Math.PI) / p) * 0.5 + 1;\r\n\t},\r\n\teaseInBack: function(t) {\r\n\t\tvar s = 1.70158;\r\n\t\treturn t * t * ((s + 1) * t - s);\r\n\t},\r\n\r\n\teaseOutBack: function(t) {\r\n\t\tvar s = 1.70158;\r\n\t\treturn (t = t - 1) * t * ((s + 1) * t + s) + 1;\r\n\t},\r\n\r\n\teaseInOutBack: function(t) {\r\n\t\tvar s = 1.70158;\r\n\t\tif ((t /= 0.5) < 1) {\r\n\t\t\treturn 0.5 * (t * t * (((s *= (1.525)) + 1) * t - s));\r\n\t\t}\r\n\t\treturn 0.5 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2);\r\n\t},\r\n\r\n\teaseInBounce: function(t) {\r\n\t\treturn 1 - effects.easeOutBounce(1 - t);\r\n\t},\r\n\r\n\teaseOutBounce: function(t) {\r\n\t\tif (t < (1 / 2.75)) {\r\n\t\t\treturn 7.5625 * t * t;\r\n\t\t}\r\n\t\tif (t < (2 / 2.75)) {\r\n\t\t\treturn 7.5625 * (t -= (1.5 / 2.75)) * t + 0.75;\r\n\t\t}\r\n\t\tif (t < (2.5 / 2.75)) {\r\n\t\t\treturn 7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375;\r\n\t\t}\r\n\t\treturn 7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375;\r\n\t},\r\n\r\n\teaseInOutBounce: function(t) {\r\n\t\tif (t < 0.5) {\r\n\t\t\treturn effects.easeInBounce(t * 2) * 0.5;\r\n\t\t}\r\n\t\treturn effects.easeOutBounce(t * 2 - 1) * 0.5 + 0.5;\r\n\t}\r\n};\r\n\r\nvar helpers_easing = {\r\n\teffects: effects\r\n};\r\n\r\n// DEPRECATIONS\r\n\r\n/**\r\n * Provided for backward compatibility, use Chart.helpers.easing.effects instead.\r\n * @function Chart.helpers.easingEffects\r\n * @deprecated since version 2.7.0\r\n * @todo remove at version 3\r\n * @private\r\n */\r\nhelpers_core.easingEffects = effects;\n\nvar PI = Math.PI;\r\nvar RAD_PER_DEG = PI / 180;\r\nvar DOUBLE_PI = PI * 2;\r\nvar HALF_PI = PI / 2;\r\nvar QUARTER_PI = PI / 4;\r\nvar TWO_THIRDS_PI = PI * 2 / 3;\r\n\r\n/**\r\n * @namespace Chart.helpers.canvas\r\n */\r\nvar exports$1 = {\r\n\t/**\r\n\t * Clears the entire canvas associated to the given `chart`.\r\n\t * @param {Chart} chart - The chart for which to clear the canvas.\r\n\t */\r\n\tclear: function(chart) {\r\n\t\tchart.ctx.clearRect(0, 0, chart.width, chart.height);\r\n\t},\r\n\r\n\t/**\r\n\t * Creates a \"path\" for a rectangle with rounded corners at position (x, y) with a\r\n\t * given size (width, height) and the same `radius` for all corners.\r\n\t * @param {CanvasRenderingContext2D} ctx - The canvas 2D Context.\r\n\t * @param {number} x - The x axis of the coordinate for the rectangle starting point.\r\n\t * @param {number} y - The y axis of the coordinate for the rectangle starting point.\r\n\t * @param {number} width - The rectangle's width.\r\n\t * @param {number} height - The rectangle's height.\r\n\t * @param {number} radius - The rounded amount (in pixels) for the four corners.\r\n\t * @todo handle `radius` as top-left, top-right, bottom-right, bottom-left array/object?\r\n\t */\r\n\troundedRect: function(ctx, x, y, width, height, radius) {\r\n\t\tif (radius) {\r\n\t\t\tvar r = Math.min(radius, height / 2, width / 2);\r\n\t\t\tvar left = x + r;\r\n\t\t\tvar top = y + r;\r\n\t\t\tvar right = x + width - r;\r\n\t\t\tvar bottom = y + height - r;\r\n\r\n\t\t\tctx.moveTo(x, top);\r\n\t\t\tif (left < right && top < bottom) {\r\n\t\t\t\tctx.arc(left, top, r, -PI, -HALF_PI);\r\n\t\t\t\tctx.arc(right, top, r, -HALF_PI, 0);\r\n\t\t\t\tctx.arc(right, bottom, r, 0, HALF_PI);\r\n\t\t\t\tctx.arc(left, bottom, r, HALF_PI, PI);\r\n\t\t\t} else if (left < right) {\r\n\t\t\t\tctx.moveTo(left, y);\r\n\t\t\t\tctx.arc(right, top, r, -HALF_PI, HALF_PI);\r\n\t\t\t\tctx.arc(left, top, r, HALF_PI, PI + HALF_PI);\r\n\t\t\t} else if (top < bottom) {\r\n\t\t\t\tctx.arc(left, top, r, -PI, 0);\r\n\t\t\t\tctx.arc(left, bottom, r, 0, PI);\r\n\t\t\t} else {\r\n\t\t\t\tctx.arc(left, top, r, -PI, PI);\r\n\t\t\t}\r\n\t\t\tctx.closePath();\r\n\t\t\tctx.moveTo(x, y);\r\n\t\t} else {\r\n\t\t\tctx.rect(x, y, width, height);\r\n\t\t}\r\n\t},\r\n\r\n\tdrawPoint: function(ctx, style, radius, x, y, rotation) {\r\n\t\tvar type, xOffset, yOffset, size, cornerRadius;\r\n\t\tvar rad = (rotation || 0) * RAD_PER_DEG;\r\n\r\n\t\tif (style && typeof style === 'object') {\r\n\t\t\ttype = style.toString();\r\n\t\t\tif (type === '[object HTMLImageElement]' || type === '[object HTMLCanvasElement]') {\r\n\t\t\t\tctx.save();\r\n\t\t\t\tctx.translate(x, y);\r\n\t\t\t\tctx.rotate(rad);\r\n\t\t\t\tctx.drawImage(style, -style.width / 2, -style.height / 2, style.width, style.height);\r\n\t\t\t\tctx.restore();\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (isNaN(radius) || radius <= 0) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tctx.beginPath();\r\n\r\n\t\tswitch (style) {\r\n\t\t// Default includes circle\r\n\t\tdefault:\r\n\t\t\tctx.arc(x, y, radius, 0, DOUBLE_PI);\r\n\t\t\tctx.closePath();\r\n\t\t\tbreak;\r\n\t\tcase 'triangle':\r\n\t\t\tctx.moveTo(x + Math.sin(rad) * radius, y - Math.cos(rad) * radius);\r\n\t\t\trad += TWO_THIRDS_PI;\r\n\t\t\tctx.lineTo(x + Math.sin(rad) * radius, y - Math.cos(rad) * radius);\r\n\t\t\trad += TWO_THIRDS_PI;\r\n\t\t\tctx.lineTo(x + Math.sin(rad) * radius, y - Math.cos(rad) * radius);\r\n\t\t\tctx.closePath();\r\n\t\t\tbreak;\r\n\t\tcase 'rectRounded':\r\n\t\t\t// NOTE: the rounded rect implementation changed to use `arc` instead of\r\n\t\t\t// `quadraticCurveTo` since it generates better results when rect is\r\n\t\t\t// almost a circle. 0.516 (instead of 0.5) produces results with visually\r\n\t\t\t// closer proportion to the previous impl and it is inscribed in the\r\n\t\t\t// circle with `radius`. For more details, see the following PRs:\r\n\t\t\t// https://github.com/chartjs/Chart.js/issues/5597\r\n\t\t\t// https://github.com/chartjs/Chart.js/issues/5858\r\n\t\t\tcornerRadius = radius * 0.516;\r\n\t\t\tsize = radius - cornerRadius;\r\n\t\t\txOffset = Math.cos(rad + QUARTER_PI) * size;\r\n\t\t\tyOffset = Math.sin(rad + QUARTER_PI) * size;\r\n\t\t\tctx.arc(x - xOffset, y - yOffset, cornerRadius, rad - PI, rad - HALF_PI);\r\n\t\t\tctx.arc(x + yOffset, y - xOffset, cornerRadius, rad - HALF_PI, rad);\r\n\t\t\tctx.arc(x + xOffset, y + yOffset, cornerRadius, rad, rad + HALF_PI);\r\n\t\t\tctx.arc(x - yOffset, y + xOffset, cornerRadius, rad + HALF_PI, rad + PI);\r\n\t\t\tctx.closePath();\r\n\t\t\tbreak;\r\n\t\tcase 'rect':\r\n\t\t\tif (!rotation) {\r\n\t\t\t\tsize = Math.SQRT1_2 * radius;\r\n\t\t\t\tctx.rect(x - size, y - size, 2 * size, 2 * size);\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\trad += QUARTER_PI;\r\n\t\t\t/* falls through */\r\n\t\tcase 'rectRot':\r\n\t\t\txOffset = Math.cos(rad) * radius;\r\n\t\t\tyOffset = Math.sin(rad) * radius;\r\n\t\t\tctx.moveTo(x - xOffset, y - yOffset);\r\n\t\t\tctx.lineTo(x + yOffset, y - xOffset);\r\n\t\t\tctx.lineTo(x + xOffset, y + yOffset);\r\n\t\t\tctx.lineTo(x - yOffset, y + xOffset);\r\n\t\t\tctx.closePath();\r\n\t\t\tbreak;\r\n\t\tcase 'crossRot':\r\n\t\t\trad += QUARTER_PI;\r\n\t\t\t/* falls through */\r\n\t\tcase 'cross':\r\n\t\t\txOffset = Math.cos(rad) * radius;\r\n\t\t\tyOffset = Math.sin(rad) * radius;\r\n\t\t\tctx.moveTo(x - xOffset, y - yOffset);\r\n\t\t\tctx.lineTo(x + xOffset, y + yOffset);\r\n\t\t\tctx.moveTo(x + yOffset, y - xOffset);\r\n\t\t\tctx.lineTo(x - yOffset, y + xOffset);\r\n\t\t\tbreak;\r\n\t\tcase 'star':\r\n\t\t\txOffset = Math.cos(rad) * radius;\r\n\t\t\tyOffset = Math.sin(rad) * radius;\r\n\t\t\tctx.moveTo(x - xOffset, y - yOffset);\r\n\t\t\tctx.lineTo(x + xOffset, y + yOffset);\r\n\t\t\tctx.moveTo(x + yOffset, y - xOffset);\r\n\t\t\tctx.lineTo(x - yOffset, y + xOffset);\r\n\t\t\trad += QUARTER_PI;\r\n\t\t\txOffset = Math.cos(rad) * radius;\r\n\t\t\tyOffset = Math.sin(rad) * radius;\r\n\t\t\tctx.moveTo(x - xOffset, y - yOffset);\r\n\t\t\tctx.lineTo(x + xOffset, y + yOffset);\r\n\t\t\tctx.moveTo(x + yOffset, y - xOffset);\r\n\t\t\tctx.lineTo(x - yOffset, y + xOffset);\r\n\t\t\tbreak;\r\n\t\tcase 'line':\r\n\t\t\txOffset = Math.cos(rad) * radius;\r\n\t\t\tyOffset = Math.sin(rad) * radius;\r\n\t\t\tctx.moveTo(x - xOffset, y - yOffset);\r\n\t\t\tctx.lineTo(x + xOffset, y + yOffset);\r\n\t\t\tbreak;\r\n\t\tcase 'dash':\r\n\t\t\tctx.moveTo(x, y);\r\n\t\t\tctx.lineTo(x + Math.cos(rad) * radius, y + Math.sin(rad) * radius);\r\n\t\t\tbreak;\r\n\t\t}\r\n\r\n\t\tctx.fill();\r\n\t\tctx.stroke();\r\n\t},\r\n\r\n\t/**\r\n\t * Returns true if the point is inside the rectangle\r\n\t * @param {object} point - The point to test\r\n\t * @param {object} area - The rectangle\r\n\t * @returns {boolean}\r\n\t * @private\r\n\t */\r\n\t_isPointInArea: function(point, area) {\r\n\t\tvar epsilon = 1e-6; // 1e-6 is margin in pixels for accumulated error.\r\n\r\n\t\treturn point.x > area.left - epsilon && point.x < area.right + epsilon &&\r\n\t\t\tpoint.y > area.top - epsilon && point.y < area.bottom + epsilon;\r\n\t},\r\n\r\n\tclipArea: function(ctx, area) {\r\n\t\tctx.save();\r\n\t\tctx.beginPath();\r\n\t\tctx.rect(area.left, area.top, area.right - area.left, area.bottom - area.top);\r\n\t\tctx.clip();\r\n\t},\r\n\r\n\tunclipArea: function(ctx) {\r\n\t\tctx.restore();\r\n\t},\r\n\r\n\tlineTo: function(ctx, previous, target, flip) {\r\n\t\tvar stepped = target.steppedLine;\r\n\t\tif (stepped) {\r\n\t\t\tif (stepped === 'middle') {\r\n\t\t\t\tvar midpoint = (previous.x + target.x) / 2.0;\r\n\t\t\t\tctx.lineTo(midpoint, flip ? target.y : previous.y);\r\n\t\t\t\tctx.lineTo(midpoint, flip ? previous.y : target.y);\r\n\t\t\t} else if ((stepped === 'after' && !flip) || (stepped !== 'after' && flip)) {\r\n\t\t\t\tctx.lineTo(previous.x, target.y);\r\n\t\t\t} else {\r\n\t\t\t\tctx.lineTo(target.x, previous.y);\r\n\t\t\t}\r\n\t\t\tctx.lineTo(target.x, target.y);\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tif (!target.tension) {\r\n\t\t\tctx.lineTo(target.x, target.y);\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tctx.bezierCurveTo(\r\n\t\t\tflip ? previous.controlPointPreviousX : previous.controlPointNextX,\r\n\t\t\tflip ? previous.controlPointPreviousY : previous.controlPointNextY,\r\n\t\t\tflip ? target.controlPointNextX : target.controlPointPreviousX,\r\n\t\t\tflip ? target.controlPointNextY : target.controlPointPreviousY,\r\n\t\t\ttarget.x,\r\n\t\t\ttarget.y);\r\n\t}\r\n};\r\n\r\nvar helpers_canvas = exports$1;\r\n\r\n// DEPRECATIONS\r\n\r\n/**\r\n * Provided for backward compatibility, use Chart.helpers.canvas.clear instead.\r\n * @namespace Chart.helpers.clear\r\n * @deprecated since version 2.7.0\r\n * @todo remove at version 3\r\n * @private\r\n */\r\nhelpers_core.clear = exports$1.clear;\r\n\r\n/**\r\n * Provided for backward compatibility, use Chart.helpers.canvas.roundedRect instead.\r\n * @namespace Chart.helpers.drawRoundedRectangle\r\n * @deprecated since version 2.7.0\r\n * @todo remove at version 3\r\n * @private\r\n */\r\nhelpers_core.drawRoundedRectangle = function(ctx) {\r\n\tctx.beginPath();\r\n\texports$1.roundedRect.apply(exports$1, arguments);\r\n};\n\nvar defaults = {\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_set: function(scope, values) {\r\n\t\treturn helpers_core.merge(this[scope] || (this[scope] = {}), values);\r\n\t}\r\n};\r\n\r\n// TODO(v3): remove 'global' from namespace. all default are global and\r\n// there's inconsistency around which options are under 'global'\r\ndefaults._set('global', {\r\n\tdefaultColor: 'rgba(0,0,0,0.1)',\r\n\tdefaultFontColor: '#666',\r\n\tdefaultFontFamily: \"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif\",\r\n\tdefaultFontSize: 12,\r\n\tdefaultFontStyle: 'normal',\r\n\tdefaultLineHeight: 1.2,\r\n\tshowLines: true\r\n});\r\n\r\nvar core_defaults = defaults;\n\nvar valueOrDefault = helpers_core.valueOrDefault;\r\n\r\n/**\r\n * Converts the given font object into a CSS font string.\r\n * @param {object} font - A font object.\r\n * @return {string} The CSS font string. See https://developer.mozilla.org/en-US/docs/Web/CSS/font\r\n * @private\r\n */\r\nfunction toFontString(font) {\r\n\tif (!font || helpers_core.isNullOrUndef(font.size) || helpers_core.isNullOrUndef(font.family)) {\r\n\t\treturn null;\r\n\t}\r\n\r\n\treturn (font.style ? font.style + ' ' : '')\r\n\t\t+ (font.weight ? font.weight + ' ' : '')\r\n\t\t+ font.size + 'px '\r\n\t\t+ font.family;\r\n}\r\n\r\n/**\r\n * @alias Chart.helpers.options\r\n * @namespace\r\n */\r\nvar helpers_options = {\r\n\t/**\r\n\t * Converts the given line height `value` in pixels for a specific font `size`.\r\n\t * @param {number|string} value - The lineHeight to parse (eg. 1.6, '14px', '75%', '1.6em').\r\n\t * @param {number} size - The font size (in pixels) used to resolve relative `value`.\r\n\t * @returns {number} The effective line height in pixels (size * 1.2 if value is invalid).\r\n\t * @see https://developer.mozilla.org/en-US/docs/Web/CSS/line-height\r\n\t * @since 2.7.0\r\n\t */\r\n\ttoLineHeight: function(value, size) {\r\n\t\tvar matches = ('' + value).match(/^(normal|(\\d+(?:\\.\\d+)?)(px|em|%)?)$/);\r\n\t\tif (!matches || matches[1] === 'normal') {\r\n\t\t\treturn size * 1.2;\r\n\t\t}\r\n\r\n\t\tvalue = +matches[2];\r\n\r\n\t\tswitch (matches[3]) {\r\n\t\tcase 'px':\r\n\t\t\treturn value;\r\n\t\tcase '%':\r\n\t\t\tvalue /= 100;\r\n\t\t\tbreak;\r\n\t\t}\r\n\r\n\t\treturn size * value;\r\n\t},\r\n\r\n\t/**\r\n\t * Converts the given value into a padding object with pre-computed width/height.\r\n\t * @param {number|object} value - If a number, set the value to all TRBL component,\r\n\t * else, if and object, use defined properties and sets undefined ones to 0.\r\n\t * @returns {object} The padding values (top, right, bottom, left, width, height)\r\n\t * @since 2.7.0\r\n\t */\r\n\ttoPadding: function(value) {\r\n\t\tvar t, r, b, l;\r\n\r\n\t\tif (helpers_core.isObject(value)) {\r\n\t\t\tt = +value.top || 0;\r\n\t\t\tr = +value.right || 0;\r\n\t\t\tb = +value.bottom || 0;\r\n\t\t\tl = +value.left || 0;\r\n\t\t} else {\r\n\t\t\tt = r = b = l = +value || 0;\r\n\t\t}\r\n\r\n\t\treturn {\r\n\t\t\ttop: t,\r\n\t\t\tright: r,\r\n\t\t\tbottom: b,\r\n\t\t\tleft: l,\r\n\t\t\theight: t + b,\r\n\t\t\twidth: l + r\r\n\t\t};\r\n\t},\r\n\r\n\t/**\r\n\t * Parses font options and returns the font object.\r\n\t * @param {object} options - A object that contains font options to be parsed.\r\n\t * @return {object} The font object.\r\n\t * @todo Support font.* options and renamed to toFont().\r\n\t * @private\r\n\t */\r\n\t_parseFont: function(options) {\r\n\t\tvar globalDefaults = core_defaults.global;\r\n\t\tvar size = valueOrDefault(options.fontSize, globalDefaults.defaultFontSize);\r\n\t\tvar font = {\r\n\t\t\tfamily: valueOrDefault(options.fontFamily, globalDefaults.defaultFontFamily),\r\n\t\t\tlineHeight: helpers_core.options.toLineHeight(valueOrDefault(options.lineHeight, globalDefaults.defaultLineHeight), size),\r\n\t\t\tsize: size,\r\n\t\t\tstyle: valueOrDefault(options.fontStyle, globalDefaults.defaultFontStyle),\r\n\t\t\tweight: null,\r\n\t\t\tstring: ''\r\n\t\t};\r\n\r\n\t\tfont.string = toFontString(font);\r\n\t\treturn font;\r\n\t},\r\n\r\n\t/**\r\n\t * Evaluates the given `inputs` sequentially and returns the first defined value.\r\n\t * @param {Array} inputs - An array of values, falling back to the last value.\r\n\t * @param {object} [context] - If defined and the current value is a function, the value\r\n\t * is called with `context` as first argument and the result becomes the new input.\r\n\t * @param {number} [index] - If defined and the current value is an array, the value\r\n\t * at `index` become the new input.\r\n\t * @param {object} [info] - object to return information about resolution in\r\n\t * @param {boolean} [info.cacheable] - Will be set to `false` if option is not cacheable.\r\n\t * @since 2.7.0\r\n\t */\r\n\tresolve: function(inputs, context, index, info) {\r\n\t\tvar cacheable = true;\r\n\t\tvar i, ilen, value;\r\n\r\n\t\tfor (i = 0, ilen = inputs.length; i < ilen; ++i) {\r\n\t\t\tvalue = inputs[i];\r\n\t\t\tif (value === undefined) {\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\t\t\tif (context !== undefined && typeof value === 'function') {\r\n\t\t\t\tvalue = value(context);\r\n\t\t\t\tcacheable = false;\r\n\t\t\t}\r\n\t\t\tif (index !== undefined && helpers_core.isArray(value)) {\r\n\t\t\t\tvalue = value[index];\r\n\t\t\t\tcacheable = false;\r\n\t\t\t}\r\n\t\t\tif (value !== undefined) {\r\n\t\t\t\tif (info && !cacheable) {\r\n\t\t\t\t\tinfo.cacheable = false;\r\n\t\t\t\t}\r\n\t\t\t\treturn value;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n};\n\n/**\r\n * @alias Chart.helpers.math\r\n * @namespace\r\n */\r\nvar exports$2 = {\r\n\t/**\r\n\t * Returns an array of factors sorted from 1 to sqrt(value)\r\n\t * @private\r\n\t */\r\n\t_factorize: function(value) {\r\n\t\tvar result = [];\r\n\t\tvar sqrt = Math.sqrt(value);\r\n\t\tvar i;\r\n\r\n\t\tfor (i = 1; i < sqrt; i++) {\r\n\t\t\tif (value % i === 0) {\r\n\t\t\t\tresult.push(i);\r\n\t\t\t\tresult.push(value / i);\r\n\t\t\t}\r\n\t\t}\r\n\t\tif (sqrt === (sqrt | 0)) { // if value is a square number\r\n\t\t\tresult.push(sqrt);\r\n\t\t}\r\n\r\n\t\tresult.sort(function(a, b) {\r\n\t\t\treturn a - b;\r\n\t\t}).pop();\r\n\t\treturn result;\r\n\t},\r\n\r\n\tlog10: Math.log10 || function(x) {\r\n\t\tvar exponent = Math.log(x) * Math.LOG10E; // Math.LOG10E = 1 / Math.LN10.\r\n\t\t// Check for whole powers of 10,\r\n\t\t// which due to floating point rounding error should be corrected.\r\n\t\tvar powerOf10 = Math.round(exponent);\r\n\t\tvar isPowerOf10 = x === Math.pow(10, powerOf10);\r\n\r\n\t\treturn isPowerOf10 ? powerOf10 : exponent;\r\n\t}\r\n};\r\n\r\nvar helpers_math = exports$2;\r\n\r\n// DEPRECATIONS\r\n\r\n/**\r\n * Provided for backward compatibility, use Chart.helpers.math.log10 instead.\r\n * @namespace Chart.helpers.log10\r\n * @deprecated since version 2.9.0\r\n * @todo remove at version 3\r\n * @private\r\n */\r\nhelpers_core.log10 = exports$2.log10;\n\nvar getRtlAdapter = function(rectX, width) {\r\n\treturn {\r\n\t\tx: function(x) {\r\n\t\t\treturn rectX + rectX + width - x;\r\n\t\t},\r\n\t\tsetWidth: function(w) {\r\n\t\t\twidth = w;\r\n\t\t},\r\n\t\ttextAlign: function(align) {\r\n\t\t\tif (align === 'center') {\r\n\t\t\t\treturn align;\r\n\t\t\t}\r\n\t\t\treturn align === 'right' ? 'left' : 'right';\r\n\t\t},\r\n\t\txPlus: function(x, value) {\r\n\t\t\treturn x - value;\r\n\t\t},\r\n\t\tleftForLtr: function(x, itemWidth) {\r\n\t\t\treturn x - itemWidth;\r\n\t\t},\r\n\t};\r\n};\r\n\r\nvar getLtrAdapter = function() {\r\n\treturn {\r\n\t\tx: function(x) {\r\n\t\t\treturn x;\r\n\t\t},\r\n\t\tsetWidth: function(w) { // eslint-disable-line no-unused-vars\r\n\t\t},\r\n\t\ttextAlign: function(align) {\r\n\t\t\treturn align;\r\n\t\t},\r\n\t\txPlus: function(x, value) {\r\n\t\t\treturn x + value;\r\n\t\t},\r\n\t\tleftForLtr: function(x, _itemWidth) { // eslint-disable-line no-unused-vars\r\n\t\t\treturn x;\r\n\t\t},\r\n\t};\r\n};\r\n\r\nvar getAdapter = function(rtl, rectX, width) {\r\n\treturn rtl ? getRtlAdapter(rectX, width) : getLtrAdapter();\r\n};\r\n\r\nvar overrideTextDirection = function(ctx, direction) {\r\n\tvar style, original;\r\n\tif (direction === 'ltr' || direction === 'rtl') {\r\n\t\tstyle = ctx.canvas.style;\r\n\t\toriginal = [\r\n\t\t\tstyle.getPropertyValue('direction'),\r\n\t\t\tstyle.getPropertyPriority('direction'),\r\n\t\t];\r\n\r\n\t\tstyle.setProperty('direction', direction, 'important');\r\n\t\tctx.prevTextDirection = original;\r\n\t}\r\n};\r\n\r\nvar restoreTextDirection = function(ctx) {\r\n\tvar original = ctx.prevTextDirection;\r\n\tif (original !== undefined) {\r\n\t\tdelete ctx.prevTextDirection;\r\n\t\tctx.canvas.style.setProperty('direction', original[0], original[1]);\r\n\t}\r\n};\r\n\r\nvar helpers_rtl = {\r\n\tgetRtlAdapter: getAdapter,\r\n\toverrideTextDirection: overrideTextDirection,\r\n\trestoreTextDirection: restoreTextDirection,\r\n};\n\nvar helpers$1 = helpers_core;\r\nvar easing = helpers_easing;\r\nvar canvas = helpers_canvas;\r\nvar options = helpers_options;\r\nvar math = helpers_math;\r\nvar rtl = helpers_rtl;\nhelpers$1.easing = easing;\nhelpers$1.canvas = canvas;\nhelpers$1.options = options;\nhelpers$1.math = math;\nhelpers$1.rtl = rtl;\n\nfunction interpolate(start, view, model, ease) {\r\n\tvar keys = Object.keys(model);\r\n\tvar i, ilen, key, actual, origin, target, type, c0, c1;\r\n\r\n\tfor (i = 0, ilen = keys.length; i < ilen; ++i) {\r\n\t\tkey = keys[i];\r\n\r\n\t\ttarget = model[key];\r\n\r\n\t\t// if a value is added to the model after pivot() has been called, the view\r\n\t\t// doesn't contain it, so let's initialize the view to the target value.\r\n\t\tif (!view.hasOwnProperty(key)) {\r\n\t\t\tview[key] = target;\r\n\t\t}\r\n\r\n\t\tactual = view[key];\r\n\r\n\t\tif (actual === target || key[0] === '_') {\r\n\t\t\tcontinue;\r\n\t\t}\r\n\r\n\t\tif (!start.hasOwnProperty(key)) {\r\n\t\t\tstart[key] = actual;\r\n\t\t}\r\n\r\n\t\torigin = start[key];\r\n\r\n\t\ttype = typeof target;\r\n\r\n\t\tif (type === typeof origin) {\r\n\t\t\tif (type === 'string') {\r\n\t\t\t\tc0 = chartjsColor(origin);\r\n\t\t\t\tif (c0.valid) {\r\n\t\t\t\t\tc1 = chartjsColor(target);\r\n\t\t\t\t\tif (c1.valid) {\r\n\t\t\t\t\t\tview[key] = c1.mix(c0, ease).rgbString();\r\n\t\t\t\t\t\tcontinue;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t} else if (helpers$1.isFinite(origin) && helpers$1.isFinite(target)) {\r\n\t\t\t\tview[key] = origin + (target - origin) * ease;\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tview[key] = target;\r\n\t}\r\n}\r\n\r\nvar Element = function(configuration) {\r\n\thelpers$1.extend(this, configuration);\r\n\tthis.initialize.apply(this, arguments);\r\n};\r\n\r\nhelpers$1.extend(Element.prototype, {\r\n\t_type: undefined,\r\n\r\n\tinitialize: function() {\r\n\t\tthis.hidden = false;\r\n\t},\r\n\r\n\tpivot: function() {\r\n\t\tvar me = this;\r\n\t\tif (!me._view) {\r\n\t\t\tme._view = helpers$1.extend({}, me._model);\r\n\t\t}\r\n\t\tme._start = {};\r\n\t\treturn me;\r\n\t},\r\n\r\n\ttransition: function(ease) {\r\n\t\tvar me = this;\r\n\t\tvar model = me._model;\r\n\t\tvar start = me._start;\r\n\t\tvar view = me._view;\r\n\r\n\t\t// No animation -> No Transition\r\n\t\tif (!model || ease === 1) {\r\n\t\t\tme._view = helpers$1.extend({}, model);\r\n\t\t\tme._start = null;\r\n\t\t\treturn me;\r\n\t\t}\r\n\r\n\t\tif (!view) {\r\n\t\t\tview = me._view = {};\r\n\t\t}\r\n\r\n\t\tif (!start) {\r\n\t\t\tstart = me._start = {};\r\n\t\t}\r\n\r\n\t\tinterpolate(start, view, model, ease);\r\n\r\n\t\treturn me;\r\n\t},\r\n\r\n\ttooltipPosition: function() {\r\n\t\treturn {\r\n\t\t\tx: this._model.x,\r\n\t\t\ty: this._model.y\r\n\t\t};\r\n\t},\r\n\r\n\thasValue: function() {\r\n\t\treturn helpers$1.isNumber(this._model.x) && helpers$1.isNumber(this._model.y);\r\n\t}\r\n});\r\n\r\nElement.extend = helpers$1.inherits;\r\n\r\nvar core_element = Element;\n\nvar exports$3 = core_element.extend({\r\n\tchart: null, // the animation associated chart instance\r\n\tcurrentStep: 0, // the current animation step\r\n\tnumSteps: 60, // default number of steps\r\n\teasing: '', // the easing to use for this animation\r\n\trender: null, // render function used by the animation service\r\n\r\n\tonAnimationProgress: null, // user specified callback to fire on each step of the animation\r\n\tonAnimationComplete: null, // user specified callback to fire when the animation finishes\r\n});\r\n\r\nvar core_animation = exports$3;\r\n\r\n// DEPRECATIONS\r\n\r\n/**\r\n * Provided for backward compatibility, use Chart.Animation instead\r\n * @prop Chart.Animation#animationObject\r\n * @deprecated since version 2.6.0\r\n * @todo remove at version 3\r\n */\r\nObject.defineProperty(exports$3.prototype, 'animationObject', {\r\n\tget: function() {\r\n\t\treturn this;\r\n\t}\r\n});\r\n\r\n/**\r\n * Provided for backward compatibility, use Chart.Animation#chart instead\r\n * @prop Chart.Animation#chartInstance\r\n * @deprecated since version 2.6.0\r\n * @todo remove at version 3\r\n */\r\nObject.defineProperty(exports$3.prototype, 'chartInstance', {\r\n\tget: function() {\r\n\t\treturn this.chart;\r\n\t},\r\n\tset: function(value) {\r\n\t\tthis.chart = value;\r\n\t}\r\n});\n\ncore_defaults._set('global', {\r\n\tanimation: {\r\n\t\tduration: 1000,\r\n\t\teasing: 'easeOutQuart',\r\n\t\tonProgress: helpers$1.noop,\r\n\t\tonComplete: helpers$1.noop\r\n\t}\r\n});\r\n\r\nvar core_animations = {\r\n\tanimations: [],\r\n\trequest: null,\r\n\r\n\t/**\r\n\t * @param {Chart} chart - The chart to animate.\r\n\t * @param {Chart.Animation} animation - The animation that we will animate.\r\n\t * @param {number} duration - The animation duration in ms.\r\n\t * @param {boolean} lazy - if true, the chart is not marked as animating to enable more responsive interactions\r\n\t */\r\n\taddAnimation: function(chart, animation, duration, lazy) {\r\n\t\tvar animations = this.animations;\r\n\t\tvar i, ilen;\r\n\r\n\t\tanimation.chart = chart;\r\n\t\tanimation.startTime = Date.now();\r\n\t\tanimation.duration = duration;\r\n\r\n\t\tif (!lazy) {\r\n\t\t\tchart.animating = true;\r\n\t\t}\r\n\r\n\t\tfor (i = 0, ilen = animations.length; i < ilen; ++i) {\r\n\t\t\tif (animations[i].chart === chart) {\r\n\t\t\t\tanimations[i] = animation;\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tanimations.push(animation);\r\n\r\n\t\t// If there are no animations queued, manually kickstart a digest, for lack of a better word\r\n\t\tif (animations.length === 1) {\r\n\t\t\tthis.requestAnimationFrame();\r\n\t\t}\r\n\t},\r\n\r\n\tcancelAnimation: function(chart) {\r\n\t\tvar index = helpers$1.findIndex(this.animations, function(animation) {\r\n\t\t\treturn animation.chart === chart;\r\n\t\t});\r\n\r\n\t\tif (index !== -1) {\r\n\t\t\tthis.animations.splice(index, 1);\r\n\t\t\tchart.animating = false;\r\n\t\t}\r\n\t},\r\n\r\n\trequestAnimationFrame: function() {\r\n\t\tvar me = this;\r\n\t\tif (me.request === null) {\r\n\t\t\t// Skip animation frame requests until the active one is executed.\r\n\t\t\t// This can happen when processing mouse events, e.g. 'mousemove'\r\n\t\t\t// and 'mouseout' events will trigger multiple renders.\r\n\t\t\tme.request = helpers$1.requestAnimFrame.call(window, function() {\r\n\t\t\t\tme.request = null;\r\n\t\t\t\tme.startDigest();\r\n\t\t\t});\r\n\t\t}\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\tstartDigest: function() {\r\n\t\tvar me = this;\r\n\r\n\t\tme.advance();\r\n\r\n\t\t// Do we have more stuff to animate?\r\n\t\tif (me.animations.length > 0) {\r\n\t\t\tme.requestAnimationFrame();\r\n\t\t}\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\tadvance: function() {\r\n\t\tvar animations = this.animations;\r\n\t\tvar animation, chart, numSteps, nextStep;\r\n\t\tvar i = 0;\r\n\r\n\t\t// 1 animation per chart, so we are looping charts here\r\n\t\twhile (i < animations.length) {\r\n\t\t\tanimation = animations[i];\r\n\t\t\tchart = animation.chart;\r\n\t\t\tnumSteps = animation.numSteps;\r\n\r\n\t\t\t// Make sure that currentStep starts at 1\r\n\t\t\t// https://github.com/chartjs/Chart.js/issues/6104\r\n\t\t\tnextStep = Math.floor((Date.now() - animation.startTime) / animation.duration * numSteps) + 1;\r\n\t\t\tanimation.currentStep = Math.min(nextStep, numSteps);\r\n\r\n\t\t\thelpers$1.callback(animation.render, [chart, animation], chart);\r\n\t\t\thelpers$1.callback(animation.onAnimationProgress, [animation], chart);\r\n\r\n\t\t\tif (animation.currentStep >= numSteps) {\r\n\t\t\t\thelpers$1.callback(animation.onAnimationComplete, [animation], chart);\r\n\t\t\t\tchart.animating = false;\r\n\t\t\t\tanimations.splice(i, 1);\r\n\t\t\t} else {\r\n\t\t\t\t++i;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n};\n\nvar resolve = helpers$1.options.resolve;\r\n\r\nvar arrayEvents = ['push', 'pop', 'shift', 'splice', 'unshift'];\r\n\r\n/**\r\n * Hooks the array methods that add or remove values ('push', pop', 'shift', 'splice',\r\n * 'unshift') and notify the listener AFTER the array has been altered. Listeners are\r\n * called on the 'onData*' callbacks (e.g. onDataPush, etc.) with same arguments.\r\n */\r\nfunction listenArrayEvents(array, listener) {\r\n\tif (array._chartjs) {\r\n\t\tarray._chartjs.listeners.push(listener);\r\n\t\treturn;\r\n\t}\r\n\r\n\tObject.defineProperty(array, '_chartjs', {\r\n\t\tconfigurable: true,\r\n\t\tenumerable: false,\r\n\t\tvalue: {\r\n\t\t\tlisteners: [listener]\r\n\t\t}\r\n\t});\r\n\r\n\tarrayEvents.forEach(function(key) {\r\n\t\tvar method = 'onData' + key.charAt(0).toUpperCase() + key.slice(1);\r\n\t\tvar base = array[key];\r\n\r\n\t\tObject.defineProperty(array, key, {\r\n\t\t\tconfigurable: true,\r\n\t\t\tenumerable: false,\r\n\t\t\tvalue: function() {\r\n\t\t\t\tvar args = Array.prototype.slice.call(arguments);\r\n\t\t\t\tvar res = base.apply(this, args);\r\n\r\n\t\t\t\thelpers$1.each(array._chartjs.listeners, function(object) {\r\n\t\t\t\t\tif (typeof object[method] === 'function') {\r\n\t\t\t\t\t\tobject[method].apply(object, args);\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\r\n\t\t\t\treturn res;\r\n\t\t\t}\r\n\t\t});\r\n\t});\r\n}\r\n\r\n/**\r\n * Removes the given array event listener and cleanup extra attached properties (such as\r\n * the _chartjs stub and overridden methods) if array doesn't have any more listeners.\r\n */\r\nfunction unlistenArrayEvents(array, listener) {\r\n\tvar stub = array._chartjs;\r\n\tif (!stub) {\r\n\t\treturn;\r\n\t}\r\n\r\n\tvar listeners = stub.listeners;\r\n\tvar index = listeners.indexOf(listener);\r\n\tif (index !== -1) {\r\n\t\tlisteners.splice(index, 1);\r\n\t}\r\n\r\n\tif (listeners.length > 0) {\r\n\t\treturn;\r\n\t}\r\n\r\n\tarrayEvents.forEach(function(key) {\r\n\t\tdelete array[key];\r\n\t});\r\n\r\n\tdelete array._chartjs;\r\n}\r\n\r\n// Base class for all dataset controllers (line, bar, etc)\r\nvar DatasetController = function(chart, datasetIndex) {\r\n\tthis.initialize(chart, datasetIndex);\r\n};\r\n\r\nhelpers$1.extend(DatasetController.prototype, {\r\n\r\n\t/**\r\n\t * Element type used to generate a meta dataset (e.g. Chart.element.Line).\r\n\t * @type {Chart.core.element}\r\n\t */\r\n\tdatasetElementType: null,\r\n\r\n\t/**\r\n\t * Element type used to generate a meta data (e.g. Chart.element.Point).\r\n\t * @type {Chart.core.element}\r\n\t */\r\n\tdataElementType: null,\r\n\r\n\t/**\r\n\t * Dataset element option keys to be resolved in _resolveDatasetElementOptions.\r\n\t * A derived controller may override this to resolve controller-specific options.\r\n\t * The keys defined here are for backward compatibility for legend styles.\r\n\t * @private\r\n\t */\r\n\t_datasetElementOptions: [\r\n\t\t'backgroundColor',\r\n\t\t'borderCapStyle',\r\n\t\t'borderColor',\r\n\t\t'borderDash',\r\n\t\t'borderDashOffset',\r\n\t\t'borderJoinStyle',\r\n\t\t'borderWidth'\r\n\t],\r\n\r\n\t/**\r\n\t * Data element option keys to be resolved in _resolveDataElementOptions.\r\n\t * A derived controller may override this to resolve controller-specific options.\r\n\t * The keys defined here are for backward compatibility for legend styles.\r\n\t * @private\r\n\t */\r\n\t_dataElementOptions: [\r\n\t\t'backgroundColor',\r\n\t\t'borderColor',\r\n\t\t'borderWidth',\r\n\t\t'pointStyle'\r\n\t],\r\n\r\n\tinitialize: function(chart, datasetIndex) {\r\n\t\tvar me = this;\r\n\t\tme.chart = chart;\r\n\t\tme.index = datasetIndex;\r\n\t\tme.linkScales();\r\n\t\tme.addElements();\r\n\t\tme._type = me.getMeta().type;\r\n\t},\r\n\r\n\tupdateIndex: function(datasetIndex) {\r\n\t\tthis.index = datasetIndex;\r\n\t},\r\n\r\n\tlinkScales: function() {\r\n\t\tvar me = this;\r\n\t\tvar meta = me.getMeta();\r\n\t\tvar chart = me.chart;\r\n\t\tvar scales = chart.scales;\r\n\t\tvar dataset = me.getDataset();\r\n\t\tvar scalesOpts = chart.options.scales;\r\n\r\n\t\tif (meta.xAxisID === null || !(meta.xAxisID in scales) || dataset.xAxisID) {\r\n\t\t\tmeta.xAxisID = dataset.xAxisID || scalesOpts.xAxes[0].id;\r\n\t\t}\r\n\t\tif (meta.yAxisID === null || !(meta.yAxisID in scales) || dataset.yAxisID) {\r\n\t\t\tmeta.yAxisID = dataset.yAxisID || scalesOpts.yAxes[0].id;\r\n\t\t}\r\n\t},\r\n\r\n\tgetDataset: function() {\r\n\t\treturn this.chart.data.datasets[this.index];\r\n\t},\r\n\r\n\tgetMeta: function() {\r\n\t\treturn this.chart.getDatasetMeta(this.index);\r\n\t},\r\n\r\n\tgetScaleForId: function(scaleID) {\r\n\t\treturn this.chart.scales[scaleID];\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_getValueScaleId: function() {\r\n\t\treturn this.getMeta().yAxisID;\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_getIndexScaleId: function() {\r\n\t\treturn this.getMeta().xAxisID;\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_getValueScale: function() {\r\n\t\treturn this.getScaleForId(this._getValueScaleId());\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_getIndexScale: function() {\r\n\t\treturn this.getScaleForId(this._getIndexScaleId());\r\n\t},\r\n\r\n\treset: function() {\r\n\t\tthis._update(true);\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\tdestroy: function() {\r\n\t\tif (this._data) {\r\n\t\t\tunlistenArrayEvents(this._data, this);\r\n\t\t}\r\n\t},\r\n\r\n\tcreateMetaDataset: function() {\r\n\t\tvar me = this;\r\n\t\tvar type = me.datasetElementType;\r\n\t\treturn type && new type({\r\n\t\t\t_chart: me.chart,\r\n\t\t\t_datasetIndex: me.index\r\n\t\t});\r\n\t},\r\n\r\n\tcreateMetaData: function(index) {\r\n\t\tvar me = this;\r\n\t\tvar type = me.dataElementType;\r\n\t\treturn type && new type({\r\n\t\t\t_chart: me.chart,\r\n\t\t\t_datasetIndex: me.index,\r\n\t\t\t_index: index\r\n\t\t});\r\n\t},\r\n\r\n\taddElements: function() {\r\n\t\tvar me = this;\r\n\t\tvar meta = me.getMeta();\r\n\t\tvar data = me.getDataset().data || [];\r\n\t\tvar metaData = meta.data;\r\n\t\tvar i, ilen;\r\n\r\n\t\tfor (i = 0, ilen = data.length; i < ilen; ++i) {\r\n\t\t\tmetaData[i] = metaData[i] || me.createMetaData(i);\r\n\t\t}\r\n\r\n\t\tmeta.dataset = meta.dataset || me.createMetaDataset();\r\n\t},\r\n\r\n\taddElementAndReset: function(index) {\r\n\t\tvar element = this.createMetaData(index);\r\n\t\tthis.getMeta().data.splice(index, 0, element);\r\n\t\tthis.updateElement(element, index, true);\r\n\t},\r\n\r\n\tbuildOrUpdateElements: function() {\r\n\t\tvar me = this;\r\n\t\tvar dataset = me.getDataset();\r\n\t\tvar data = dataset.data || (dataset.data = []);\r\n\r\n\t\t// In order to correctly handle data addition/deletion animation (an thus simulate\r\n\t\t// real-time charts), we need to monitor these data modifications and synchronize\r\n\t\t// the internal meta data accordingly.\r\n\t\tif (me._data !== data) {\r\n\t\t\tif (me._data) {\r\n\t\t\t\t// This case happens when the user replaced the data array instance.\r\n\t\t\t\tunlistenArrayEvents(me._data, me);\r\n\t\t\t}\r\n\r\n\t\t\tif (data && Object.isExtensible(data)) {\r\n\t\t\t\tlistenArrayEvents(data, me);\r\n\t\t\t}\r\n\t\t\tme._data = data;\r\n\t\t}\r\n\r\n\t\t// Re-sync meta data in case the user replaced the data array or if we missed\r\n\t\t// any updates and so make sure that we handle number of datapoints changing.\r\n\t\tme.resyncElements();\r\n\t},\r\n\r\n\t/**\r\n\t * Returns the merged user-supplied and default dataset-level options\r\n\t * @private\r\n\t */\r\n\t_configure: function() {\r\n\t\tvar me = this;\r\n\t\tme._config = helpers$1.merge(Object.create(null), [\r\n\t\t\tme.chart.options.datasets[me._type],\r\n\t\t\tme.getDataset(),\r\n\t\t], {\r\n\t\t\tmerger: function(key, target, source) {\r\n\t\t\t\tif (key !== '_meta' && key !== 'data') {\r\n\t\t\t\t\thelpers$1._merger(key, target, source);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t});\r\n\t},\r\n\r\n\t_update: function(reset) {\r\n\t\tvar me = this;\r\n\t\tme._configure();\r\n\t\tme._cachedDataOpts = null;\r\n\t\tme.update(reset);\r\n\t},\r\n\r\n\tupdate: helpers$1.noop,\r\n\r\n\ttransition: function(easingValue) {\r\n\t\tvar meta = this.getMeta();\r\n\t\tvar elements = meta.data || [];\r\n\t\tvar ilen = elements.length;\r\n\t\tvar i = 0;\r\n\r\n\t\tfor (; i < ilen; ++i) {\r\n\t\t\telements[i].transition(easingValue);\r\n\t\t}\r\n\r\n\t\tif (meta.dataset) {\r\n\t\t\tmeta.dataset.transition(easingValue);\r\n\t\t}\r\n\t},\r\n\r\n\tdraw: function() {\r\n\t\tvar meta = this.getMeta();\r\n\t\tvar elements = meta.data || [];\r\n\t\tvar ilen = elements.length;\r\n\t\tvar i = 0;\r\n\r\n\t\tif (meta.dataset) {\r\n\t\t\tmeta.dataset.draw();\r\n\t\t}\r\n\r\n\t\tfor (; i < ilen; ++i) {\r\n\t\t\telements[i].draw();\r\n\t\t}\r\n\t},\r\n\r\n\t/**\r\n\t * Returns a set of predefined style properties that should be used to represent the dataset\r\n\t * or the data if the index is specified\r\n\t * @param {number} index - data index\r\n\t * @return {IStyleInterface} style object\r\n\t */\r\n\tgetStyle: function(index) {\r\n\t\tvar me = this;\r\n\t\tvar meta = me.getMeta();\r\n\t\tvar dataset = meta.dataset;\r\n\t\tvar style;\r\n\r\n\t\tme._configure();\r\n\t\tif (dataset && index === undefined) {\r\n\t\t\tstyle = me._resolveDatasetElementOptions(dataset || {});\r\n\t\t} else {\r\n\t\t\tindex = index || 0;\r\n\t\t\tstyle = me._resolveDataElementOptions(meta.data[index] || {}, index);\r\n\t\t}\r\n\r\n\t\tif (style.fill === false || style.fill === null) {\r\n\t\t\tstyle.backgroundColor = style.borderColor;\r\n\t\t}\r\n\r\n\t\treturn style;\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_resolveDatasetElementOptions: function(element, hover) {\r\n\t\tvar me = this;\r\n\t\tvar chart = me.chart;\r\n\t\tvar datasetOpts = me._config;\r\n\t\tvar custom = element.custom || {};\r\n\t\tvar options = chart.options.elements[me.datasetElementType.prototype._type] || {};\r\n\t\tvar elementOptions = me._datasetElementOptions;\r\n\t\tvar values = {};\r\n\t\tvar i, ilen, key, readKey;\r\n\r\n\t\t// Scriptable options\r\n\t\tvar context = {\r\n\t\t\tchart: chart,\r\n\t\t\tdataset: me.getDataset(),\r\n\t\t\tdatasetIndex: me.index,\r\n\t\t\thover: hover\r\n\t\t};\r\n\r\n\t\tfor (i = 0, ilen = elementOptions.length; i < ilen; ++i) {\r\n\t\t\tkey = elementOptions[i];\r\n\t\t\treadKey = hover ? 'hover' + key.charAt(0).toUpperCase() + key.slice(1) : key;\r\n\t\t\tvalues[key] = resolve([\r\n\t\t\t\tcustom[readKey],\r\n\t\t\t\tdatasetOpts[readKey],\r\n\t\t\t\toptions[readKey]\r\n\t\t\t], context);\r\n\t\t}\r\n\r\n\t\treturn values;\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_resolveDataElementOptions: function(element, index) {\r\n\t\tvar me = this;\r\n\t\tvar custom = element && element.custom;\r\n\t\tvar cached = me._cachedDataOpts;\r\n\t\tif (cached && !custom) {\r\n\t\t\treturn cached;\r\n\t\t}\r\n\t\tvar chart = me.chart;\r\n\t\tvar datasetOpts = me._config;\r\n\t\tvar options = chart.options.elements[me.dataElementType.prototype._type] || {};\r\n\t\tvar elementOptions = me._dataElementOptions;\r\n\t\tvar values = {};\r\n\r\n\t\t// Scriptable options\r\n\t\tvar context = {\r\n\t\t\tchart: chart,\r\n\t\t\tdataIndex: index,\r\n\t\t\tdataset: me.getDataset(),\r\n\t\t\tdatasetIndex: me.index\r\n\t\t};\r\n\r\n\t\t// `resolve` sets cacheable to `false` if any option is indexed or scripted\r\n\t\tvar info = {cacheable: !custom};\r\n\r\n\t\tvar keys, i, ilen, key;\r\n\r\n\t\tcustom = custom || {};\r\n\r\n\t\tif (helpers$1.isArray(elementOptions)) {\r\n\t\t\tfor (i = 0, ilen = elementOptions.length; i < ilen; ++i) {\r\n\t\t\t\tkey = elementOptions[i];\r\n\t\t\t\tvalues[key] = resolve([\r\n\t\t\t\t\tcustom[key],\r\n\t\t\t\t\tdatasetOpts[key],\r\n\t\t\t\t\toptions[key]\r\n\t\t\t\t], context, index, info);\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tkeys = Object.keys(elementOptions);\r\n\t\t\tfor (i = 0, ilen = keys.length; i < ilen; ++i) {\r\n\t\t\t\tkey = keys[i];\r\n\t\t\t\tvalues[key] = resolve([\r\n\t\t\t\t\tcustom[key],\r\n\t\t\t\t\tdatasetOpts[elementOptions[key]],\r\n\t\t\t\t\tdatasetOpts[key],\r\n\t\t\t\t\toptions[key]\r\n\t\t\t\t], context, index, info);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (info.cacheable) {\r\n\t\t\tme._cachedDataOpts = Object.freeze(values);\r\n\t\t}\r\n\r\n\t\treturn values;\r\n\t},\r\n\r\n\tremoveHoverStyle: function(element) {\r\n\t\thelpers$1.merge(element._model, element.$previousStyle || {});\r\n\t\tdelete element.$previousStyle;\r\n\t},\r\n\r\n\tsetHoverStyle: function(element) {\r\n\t\tvar dataset = this.chart.data.datasets[element._datasetIndex];\r\n\t\tvar index = element._index;\r\n\t\tvar custom = element.custom || {};\r\n\t\tvar model = element._model;\r\n\t\tvar getHoverColor = helpers$1.getHoverColor;\r\n\r\n\t\telement.$previousStyle = {\r\n\t\t\tbackgroundColor: model.backgroundColor,\r\n\t\t\tborderColor: model.borderColor,\r\n\t\t\tborderWidth: model.borderWidth\r\n\t\t};\r\n\r\n\t\tmodel.backgroundColor = resolve([custom.hoverBackgroundColor, dataset.hoverBackgroundColor, getHoverColor(model.backgroundColor)], undefined, index);\r\n\t\tmodel.borderColor = resolve([custom.hoverBorderColor, dataset.hoverBorderColor, getHoverColor(model.borderColor)], undefined, index);\r\n\t\tmodel.borderWidth = resolve([custom.hoverBorderWidth, dataset.hoverBorderWidth, model.borderWidth], undefined, index);\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_removeDatasetHoverStyle: function() {\r\n\t\tvar element = this.getMeta().dataset;\r\n\r\n\t\tif (element) {\r\n\t\t\tthis.removeHoverStyle(element);\r\n\t\t}\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_setDatasetHoverStyle: function() {\r\n\t\tvar element = this.getMeta().dataset;\r\n\t\tvar prev = {};\r\n\t\tvar i, ilen, key, keys, hoverOptions, model;\r\n\r\n\t\tif (!element) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tmodel = element._model;\r\n\t\thoverOptions = this._resolveDatasetElementOptions(element, true);\r\n\r\n\t\tkeys = Object.keys(hoverOptions);\r\n\t\tfor (i = 0, ilen = keys.length; i < ilen; ++i) {\r\n\t\t\tkey = keys[i];\r\n\t\t\tprev[key] = model[key];\r\n\t\t\tmodel[key] = hoverOptions[key];\r\n\t\t}\r\n\r\n\t\telement.$previousStyle = prev;\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\tresyncElements: function() {\r\n\t\tvar me = this;\r\n\t\tvar meta = me.getMeta();\r\n\t\tvar data = me.getDataset().data;\r\n\t\tvar numMeta = meta.data.length;\r\n\t\tvar numData = data.length;\r\n\r\n\t\tif (numData < numMeta) {\r\n\t\t\tmeta.data.splice(numData, numMeta - numData);\r\n\t\t} else if (numData > numMeta) {\r\n\t\t\tme.insertElements(numMeta, numData - numMeta);\r\n\t\t}\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\tinsertElements: function(start, count) {\r\n\t\tfor (var i = 0; i < count; ++i) {\r\n\t\t\tthis.addElementAndReset(start + i);\r\n\t\t}\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\tonDataPush: function() {\r\n\t\tvar count = arguments.length;\r\n\t\tthis.insertElements(this.getDataset().data.length - count, count);\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\tonDataPop: function() {\r\n\t\tthis.getMeta().data.pop();\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\tonDataShift: function() {\r\n\t\tthis.getMeta().data.shift();\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\tonDataSplice: function(start, count) {\r\n\t\tthis.getMeta().data.splice(start, count);\r\n\t\tthis.insertElements(start, arguments.length - 2);\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\tonDataUnshift: function() {\r\n\t\tthis.insertElements(0, arguments.length);\r\n\t}\r\n});\r\n\r\nDatasetController.extend = helpers$1.inherits;\r\n\r\nvar core_datasetController = DatasetController;\n\nvar TAU = Math.PI * 2;\r\n\r\ncore_defaults._set('global', {\r\n\telements: {\r\n\t\tarc: {\r\n\t\t\tbackgroundColor: core_defaults.global.defaultColor,\r\n\t\t\tborderColor: '#fff',\r\n\t\t\tborderWidth: 2,\r\n\t\t\tborderAlign: 'center'\r\n\t\t}\r\n\t}\r\n});\r\n\r\nfunction clipArc(ctx, arc) {\r\n\tvar startAngle = arc.startAngle;\r\n\tvar endAngle = arc.endAngle;\r\n\tvar pixelMargin = arc.pixelMargin;\r\n\tvar angleMargin = pixelMargin / arc.outerRadius;\r\n\tvar x = arc.x;\r\n\tvar y = arc.y;\r\n\r\n\t// Draw an inner border by cliping the arc and drawing a double-width border\r\n\t// Enlarge the clipping arc by 0.33 pixels to eliminate glitches between borders\r\n\tctx.beginPath();\r\n\tctx.arc(x, y, arc.outerRadius, startAngle - angleMargin, endAngle + angleMargin);\r\n\tif (arc.innerRadius > pixelMargin) {\r\n\t\tangleMargin = pixelMargin / arc.innerRadius;\r\n\t\tctx.arc(x, y, arc.innerRadius - pixelMargin, endAngle + angleMargin, startAngle - angleMargin, true);\r\n\t} else {\r\n\t\tctx.arc(x, y, pixelMargin, endAngle + Math.PI / 2, startAngle - Math.PI / 2);\r\n\t}\r\n\tctx.closePath();\r\n\tctx.clip();\r\n}\r\n\r\nfunction drawFullCircleBorders(ctx, vm, arc, inner) {\r\n\tvar endAngle = arc.endAngle;\r\n\tvar i;\r\n\r\n\tif (inner) {\r\n\t\tarc.endAngle = arc.startAngle + TAU;\r\n\t\tclipArc(ctx, arc);\r\n\t\tarc.endAngle = endAngle;\r\n\t\tif (arc.endAngle === arc.startAngle && arc.fullCircles) {\r\n\t\t\tarc.endAngle += TAU;\r\n\t\t\tarc.fullCircles--;\r\n\t\t}\r\n\t}\r\n\r\n\tctx.beginPath();\r\n\tctx.arc(arc.x, arc.y, arc.innerRadius, arc.startAngle + TAU, arc.startAngle, true);\r\n\tfor (i = 0; i < arc.fullCircles; ++i) {\r\n\t\tctx.stroke();\r\n\t}\r\n\r\n\tctx.beginPath();\r\n\tctx.arc(arc.x, arc.y, vm.outerRadius, arc.startAngle, arc.startAngle + TAU);\r\n\tfor (i = 0; i < arc.fullCircles; ++i) {\r\n\t\tctx.stroke();\r\n\t}\r\n}\r\n\r\nfunction drawBorder(ctx, vm, arc) {\r\n\tvar inner = vm.borderAlign === 'inner';\r\n\r\n\tif (inner) {\r\n\t\tctx.lineWidth = vm.borderWidth * 2;\r\n\t\tctx.lineJoin = 'round';\r\n\t} else {\r\n\t\tctx.lineWidth = vm.borderWidth;\r\n\t\tctx.lineJoin = 'bevel';\r\n\t}\r\n\r\n\tif (arc.fullCircles) {\r\n\t\tdrawFullCircleBorders(ctx, vm, arc, inner);\r\n\t}\r\n\r\n\tif (inner) {\r\n\t\tclipArc(ctx, arc);\r\n\t}\r\n\r\n\tctx.beginPath();\r\n\tctx.arc(arc.x, arc.y, vm.outerRadius, arc.startAngle, arc.endAngle);\r\n\tctx.arc(arc.x, arc.y, arc.innerRadius, arc.endAngle, arc.startAngle, true);\r\n\tctx.closePath();\r\n\tctx.stroke();\r\n}\r\n\r\nvar element_arc = core_element.extend({\r\n\t_type: 'arc',\r\n\r\n\tinLabelRange: function(mouseX) {\r\n\t\tvar vm = this._view;\r\n\r\n\t\tif (vm) {\r\n\t\t\treturn (Math.pow(mouseX - vm.x, 2) < Math.pow(vm.radius + vm.hoverRadius, 2));\r\n\t\t}\r\n\t\treturn false;\r\n\t},\r\n\r\n\tinRange: function(chartX, chartY) {\r\n\t\tvar vm = this._view;\r\n\r\n\t\tif (vm) {\r\n\t\t\tvar pointRelativePosition = helpers$1.getAngleFromPoint(vm, {x: chartX, y: chartY});\r\n\t\t\tvar angle = pointRelativePosition.angle;\r\n\t\t\tvar distance = pointRelativePosition.distance;\r\n\r\n\t\t\t// Sanitise angle range\r\n\t\t\tvar startAngle = vm.startAngle;\r\n\t\t\tvar endAngle = vm.endAngle;\r\n\t\t\twhile (endAngle < startAngle) {\r\n\t\t\t\tendAngle += TAU;\r\n\t\t\t}\r\n\t\t\twhile (angle > endAngle) {\r\n\t\t\t\tangle -= TAU;\r\n\t\t\t}\r\n\t\t\twhile (angle < startAngle) {\r\n\t\t\t\tangle += TAU;\r\n\t\t\t}\r\n\r\n\t\t\t// Check if within the range of the open/close angle\r\n\t\t\tvar betweenAngles = (angle >= startAngle && angle <= endAngle);\r\n\t\t\tvar withinRadius = (distance >= vm.innerRadius && distance <= vm.outerRadius);\r\n\r\n\t\t\treturn (betweenAngles && withinRadius);\r\n\t\t}\r\n\t\treturn false;\r\n\t},\r\n\r\n\tgetCenterPoint: function() {\r\n\t\tvar vm = this._view;\r\n\t\tvar halfAngle = (vm.startAngle + vm.endAngle) / 2;\r\n\t\tvar halfRadius = (vm.innerRadius + vm.outerRadius) / 2;\r\n\t\treturn {\r\n\t\t\tx: vm.x + Math.cos(halfAngle) * halfRadius,\r\n\t\t\ty: vm.y + Math.sin(halfAngle) * halfRadius\r\n\t\t};\r\n\t},\r\n\r\n\tgetArea: function() {\r\n\t\tvar vm = this._view;\r\n\t\treturn Math.PI * ((vm.endAngle - vm.startAngle) / (2 * Math.PI)) * (Math.pow(vm.outerRadius, 2) - Math.pow(vm.innerRadius, 2));\r\n\t},\r\n\r\n\ttooltipPosition: function() {\r\n\t\tvar vm = this._view;\r\n\t\tvar centreAngle = vm.startAngle + ((vm.endAngle - vm.startAngle) / 2);\r\n\t\tvar rangeFromCentre = (vm.outerRadius - vm.innerRadius) / 2 + vm.innerRadius;\r\n\r\n\t\treturn {\r\n\t\t\tx: vm.x + (Math.cos(centreAngle) * rangeFromCentre),\r\n\t\t\ty: vm.y + (Math.sin(centreAngle) * rangeFromCentre)\r\n\t\t};\r\n\t},\r\n\r\n\tdraw: function() {\r\n\t\tvar ctx = this._chart.ctx;\r\n\t\tvar vm = this._view;\r\n\t\tvar pixelMargin = (vm.borderAlign === 'inner') ? 0.33 : 0;\r\n\t\tvar arc = {\r\n\t\t\tx: vm.x,\r\n\t\t\ty: vm.y,\r\n\t\t\tinnerRadius: vm.innerRadius,\r\n\t\t\touterRadius: Math.max(vm.outerRadius - pixelMargin, 0),\r\n\t\t\tpixelMargin: pixelMargin,\r\n\t\t\tstartAngle: vm.startAngle,\r\n\t\t\tendAngle: vm.endAngle,\r\n\t\t\tfullCircles: Math.floor(vm.circumference / TAU)\r\n\t\t};\r\n\t\tvar i;\r\n\r\n\t\tctx.save();\r\n\r\n\t\tctx.fillStyle = vm.backgroundColor;\r\n\t\tctx.strokeStyle = vm.borderColor;\r\n\r\n\t\tif (arc.fullCircles) {\r\n\t\t\tarc.endAngle = arc.startAngle + TAU;\r\n\t\t\tctx.beginPath();\r\n\t\t\tctx.arc(arc.x, arc.y, arc.outerRadius, arc.startAngle, arc.endAngle);\r\n\t\t\tctx.arc(arc.x, arc.y, arc.innerRadius, arc.endAngle, arc.startAngle, true);\r\n\t\t\tctx.closePath();\r\n\t\t\tfor (i = 0; i < arc.fullCircles; ++i) {\r\n\t\t\t\tctx.fill();\r\n\t\t\t}\r\n\t\t\tarc.endAngle = arc.startAngle + vm.circumference % TAU;\r\n\t\t}\r\n\r\n\t\tctx.beginPath();\r\n\t\tctx.arc(arc.x, arc.y, arc.outerRadius, arc.startAngle, arc.endAngle);\r\n\t\tctx.arc(arc.x, arc.y, arc.innerRadius, arc.endAngle, arc.startAngle, true);\r\n\t\tctx.closePath();\r\n\t\tctx.fill();\r\n\r\n\t\tif (vm.borderWidth) {\r\n\t\t\tdrawBorder(ctx, vm, arc);\r\n\t\t}\r\n\r\n\t\tctx.restore();\r\n\t}\r\n});\n\nvar valueOrDefault$1 = helpers$1.valueOrDefault;\r\n\r\nvar defaultColor = core_defaults.global.defaultColor;\r\n\r\ncore_defaults._set('global', {\r\n\telements: {\r\n\t\tline: {\r\n\t\t\ttension: 0.4,\r\n\t\t\tbackgroundColor: defaultColor,\r\n\t\t\tborderWidth: 3,\r\n\t\t\tborderColor: defaultColor,\r\n\t\t\tborderCapStyle: 'butt',\r\n\t\t\tborderDash: [],\r\n\t\t\tborderDashOffset: 0.0,\r\n\t\t\tborderJoinStyle: 'miter',\r\n\t\t\tcapBezierPoints: true,\r\n\t\t\tfill: true, // do we fill in the area between the line and its base axis\r\n\t\t}\r\n\t}\r\n});\r\n\r\nvar element_line = core_element.extend({\r\n\t_type: 'line',\r\n\r\n\tdraw: function() {\r\n\t\tvar me = this;\r\n\t\tvar vm = me._view;\r\n\t\tvar ctx = me._chart.ctx;\r\n\t\tvar spanGaps = vm.spanGaps;\r\n\t\tvar points = me._children.slice(); // clone array\r\n\t\tvar globalDefaults = core_defaults.global;\r\n\t\tvar globalOptionLineElements = globalDefaults.elements.line;\r\n\t\tvar lastDrawnIndex = -1;\r\n\t\tvar closePath = me._loop;\r\n\t\tvar index, previous, currentVM;\r\n\r\n\t\tif (!points.length) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tif (me._loop) {\r\n\t\t\tfor (index = 0; index < points.length; ++index) {\r\n\t\t\t\tprevious = helpers$1.previousItem(points, index);\r\n\t\t\t\t// If the line has an open path, shift the point array\r\n\t\t\t\tif (!points[index]._view.skip && previous._view.skip) {\r\n\t\t\t\t\tpoints = points.slice(index).concat(points.slice(0, index));\r\n\t\t\t\t\tclosePath = spanGaps;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t// If the line has a close path, add the first point again\r\n\t\t\tif (closePath) {\r\n\t\t\t\tpoints.push(points[0]);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tctx.save();\r\n\r\n\t\t// Stroke Line Options\r\n\t\tctx.lineCap = vm.borderCapStyle || globalOptionLineElements.borderCapStyle;\r\n\r\n\t\t// IE 9 and 10 do not support line dash\r\n\t\tif (ctx.setLineDash) {\r\n\t\t\tctx.setLineDash(vm.borderDash || globalOptionLineElements.borderDash);\r\n\t\t}\r\n\r\n\t\tctx.lineDashOffset = valueOrDefault$1(vm.borderDashOffset, globalOptionLineElements.borderDashOffset);\r\n\t\tctx.lineJoin = vm.borderJoinStyle || globalOptionLineElements.borderJoinStyle;\r\n\t\tctx.lineWidth = valueOrDefault$1(vm.borderWidth, globalOptionLineElements.borderWidth);\r\n\t\tctx.strokeStyle = vm.borderColor || globalDefaults.defaultColor;\r\n\r\n\t\t// Stroke Line\r\n\t\tctx.beginPath();\r\n\r\n\t\t// First point moves to it's starting position no matter what\r\n\t\tcurrentVM = points[0]._view;\r\n\t\tif (!currentVM.skip) {\r\n\t\t\tctx.moveTo(currentVM.x, currentVM.y);\r\n\t\t\tlastDrawnIndex = 0;\r\n\t\t}\r\n\r\n\t\tfor (index = 1; index < points.length; ++index) {\r\n\t\t\tcurrentVM = points[index]._view;\r\n\t\t\tprevious = lastDrawnIndex === -1 ? helpers$1.previousItem(points, index) : points[lastDrawnIndex];\r\n\r\n\t\t\tif (!currentVM.skip) {\r\n\t\t\t\tif ((lastDrawnIndex !== (index - 1) && !spanGaps) || lastDrawnIndex === -1) {\r\n\t\t\t\t\t// There was a gap and this is the first point after the gap\r\n\t\t\t\t\tctx.moveTo(currentVM.x, currentVM.y);\r\n\t\t\t\t} else {\r\n\t\t\t\t\t// Line to next point\r\n\t\t\t\t\thelpers$1.canvas.lineTo(ctx, previous._view, currentVM);\r\n\t\t\t\t}\r\n\t\t\t\tlastDrawnIndex = index;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (closePath) {\r\n\t\t\tctx.closePath();\r\n\t\t}\r\n\r\n\t\tctx.stroke();\r\n\t\tctx.restore();\r\n\t}\r\n});\n\nvar valueOrDefault$2 = helpers$1.valueOrDefault;\r\n\r\nvar defaultColor$1 = core_defaults.global.defaultColor;\r\n\r\ncore_defaults._set('global', {\r\n\telements: {\r\n\t\tpoint: {\r\n\t\t\tradius: 3,\r\n\t\t\tpointStyle: 'circle',\r\n\t\t\tbackgroundColor: defaultColor$1,\r\n\t\t\tborderColor: defaultColor$1,\r\n\t\t\tborderWidth: 1,\r\n\t\t\t// Hover\r\n\t\t\thitRadius: 1,\r\n\t\t\thoverRadius: 4,\r\n\t\t\thoverBorderWidth: 1\r\n\t\t}\r\n\t}\r\n});\r\n\r\nfunction xRange(mouseX) {\r\n\tvar vm = this._view;\r\n\treturn vm ? (Math.abs(mouseX - vm.x) < vm.radius + vm.hitRadius) : false;\r\n}\r\n\r\nfunction yRange(mouseY) {\r\n\tvar vm = this._view;\r\n\treturn vm ? (Math.abs(mouseY - vm.y) < vm.radius + vm.hitRadius) : false;\r\n}\r\n\r\nvar element_point = core_element.extend({\r\n\t_type: 'point',\r\n\r\n\tinRange: function(mouseX, mouseY) {\r\n\t\tvar vm = this._view;\r\n\t\treturn vm ? ((Math.pow(mouseX - vm.x, 2) + Math.pow(mouseY - vm.y, 2)) < Math.pow(vm.hitRadius + vm.radius, 2)) : false;\r\n\t},\r\n\r\n\tinLabelRange: xRange,\r\n\tinXRange: xRange,\r\n\tinYRange: yRange,\r\n\r\n\tgetCenterPoint: function() {\r\n\t\tvar vm = this._view;\r\n\t\treturn {\r\n\t\t\tx: vm.x,\r\n\t\t\ty: vm.y\r\n\t\t};\r\n\t},\r\n\r\n\tgetArea: function() {\r\n\t\treturn Math.PI * Math.pow(this._view.radius, 2);\r\n\t},\r\n\r\n\ttooltipPosition: function() {\r\n\t\tvar vm = this._view;\r\n\t\treturn {\r\n\t\t\tx: vm.x,\r\n\t\t\ty: vm.y,\r\n\t\t\tpadding: vm.radius + vm.borderWidth\r\n\t\t};\r\n\t},\r\n\r\n\tdraw: function(chartArea) {\r\n\t\tvar vm = this._view;\r\n\t\tvar ctx = this._chart.ctx;\r\n\t\tvar pointStyle = vm.pointStyle;\r\n\t\tvar rotation = vm.rotation;\r\n\t\tvar radius = vm.radius;\r\n\t\tvar x = vm.x;\r\n\t\tvar y = vm.y;\r\n\t\tvar globalDefaults = core_defaults.global;\r\n\t\tvar defaultColor = globalDefaults.defaultColor; // eslint-disable-line no-shadow\r\n\r\n\t\tif (vm.skip) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// Clipping for Points.\r\n\t\tif (chartArea === undefined || helpers$1.canvas._isPointInArea(vm, chartArea)) {\r\n\t\t\tctx.strokeStyle = vm.borderColor || defaultColor;\r\n\t\t\tctx.lineWidth = valueOrDefault$2(vm.borderWidth, globalDefaults.elements.point.borderWidth);\r\n\t\t\tctx.fillStyle = vm.backgroundColor || defaultColor;\r\n\t\t\thelpers$1.canvas.drawPoint(ctx, pointStyle, radius, x, y, rotation);\r\n\t\t}\r\n\t}\r\n});\n\nvar defaultColor$2 = core_defaults.global.defaultColor;\r\n\r\ncore_defaults._set('global', {\r\n\telements: {\r\n\t\trectangle: {\r\n\t\t\tbackgroundColor: defaultColor$2,\r\n\t\t\tborderColor: defaultColor$2,\r\n\t\t\tborderSkipped: 'bottom',\r\n\t\t\tborderWidth: 0\r\n\t\t}\r\n\t}\r\n});\r\n\r\nfunction isVertical(vm) {\r\n\treturn vm && vm.width !== undefined;\r\n}\r\n\r\n/**\r\n * Helper function to get the bounds of the bar regardless of the orientation\r\n * @param bar {Chart.Element.Rectangle} the bar\r\n * @return {Bounds} bounds of the bar\r\n * @private\r\n */\r\nfunction getBarBounds(vm) {\r\n\tvar x1, x2, y1, y2, half;\r\n\r\n\tif (isVertical(vm)) {\r\n\t\thalf = vm.width / 2;\r\n\t\tx1 = vm.x - half;\r\n\t\tx2 = vm.x + half;\r\n\t\ty1 = Math.min(vm.y, vm.base);\r\n\t\ty2 = Math.max(vm.y, vm.base);\r\n\t} else {\r\n\t\thalf = vm.height / 2;\r\n\t\tx1 = Math.min(vm.x, vm.base);\r\n\t\tx2 = Math.max(vm.x, vm.base);\r\n\t\ty1 = vm.y - half;\r\n\t\ty2 = vm.y + half;\r\n\t}\r\n\r\n\treturn {\r\n\t\tleft: x1,\r\n\t\ttop: y1,\r\n\t\tright: x2,\r\n\t\tbottom: y2\r\n\t};\r\n}\r\n\r\nfunction swap(orig, v1, v2) {\r\n\treturn orig === v1 ? v2 : orig === v2 ? v1 : orig;\r\n}\r\n\r\nfunction parseBorderSkipped(vm) {\r\n\tvar edge = vm.borderSkipped;\r\n\tvar res = {};\r\n\r\n\tif (!edge) {\r\n\t\treturn res;\r\n\t}\r\n\r\n\tif (vm.horizontal) {\r\n\t\tif (vm.base > vm.x) {\r\n\t\t\tedge = swap(edge, 'left', 'right');\r\n\t\t}\r\n\t} else if (vm.base < vm.y) {\r\n\t\tedge = swap(edge, 'bottom', 'top');\r\n\t}\r\n\r\n\tres[edge] = true;\r\n\treturn res;\r\n}\r\n\r\nfunction parseBorderWidth(vm, maxW, maxH) {\r\n\tvar value = vm.borderWidth;\r\n\tvar skip = parseBorderSkipped(vm);\r\n\tvar t, r, b, l;\r\n\r\n\tif (helpers$1.isObject(value)) {\r\n\t\tt = +value.top || 0;\r\n\t\tr = +value.right || 0;\r\n\t\tb = +value.bottom || 0;\r\n\t\tl = +value.left || 0;\r\n\t} else {\r\n\t\tt = r = b = l = +value || 0;\r\n\t}\r\n\r\n\treturn {\r\n\t\tt: skip.top || (t < 0) ? 0 : t > maxH ? maxH : t,\r\n\t\tr: skip.right || (r < 0) ? 0 : r > maxW ? maxW : r,\r\n\t\tb: skip.bottom || (b < 0) ? 0 : b > maxH ? maxH : b,\r\n\t\tl: skip.left || (l < 0) ? 0 : l > maxW ? maxW : l\r\n\t};\r\n}\r\n\r\nfunction boundingRects(vm) {\r\n\tvar bounds = getBarBounds(vm);\r\n\tvar width = bounds.right - bounds.left;\r\n\tvar height = bounds.bottom - bounds.top;\r\n\tvar border = parseBorderWidth(vm, width / 2, height / 2);\r\n\r\n\treturn {\r\n\t\touter: {\r\n\t\t\tx: bounds.left,\r\n\t\t\ty: bounds.top,\r\n\t\t\tw: width,\r\n\t\t\th: height\r\n\t\t},\r\n\t\tinner: {\r\n\t\t\tx: bounds.left + border.l,\r\n\t\t\ty: bounds.top + border.t,\r\n\t\t\tw: width - border.l - border.r,\r\n\t\t\th: height - border.t - border.b\r\n\t\t}\r\n\t};\r\n}\r\n\r\nfunction inRange(vm, x, y) {\r\n\tvar skipX = x === null;\r\n\tvar skipY = y === null;\r\n\tvar bounds = !vm || (skipX && skipY) ? false : getBarBounds(vm);\r\n\r\n\treturn bounds\r\n\t\t&& (skipX || x >= bounds.left && x <= bounds.right)\r\n\t\t&& (skipY || y >= bounds.top && y <= bounds.bottom);\r\n}\r\n\r\nvar element_rectangle = core_element.extend({\r\n\t_type: 'rectangle',\r\n\r\n\tdraw: function() {\r\n\t\tvar ctx = this._chart.ctx;\r\n\t\tvar vm = this._view;\r\n\t\tvar rects = boundingRects(vm);\r\n\t\tvar outer = rects.outer;\r\n\t\tvar inner = rects.inner;\r\n\r\n\t\tctx.fillStyle = vm.backgroundColor;\r\n\t\tctx.fillRect(outer.x, outer.y, outer.w, outer.h);\r\n\r\n\t\tif (outer.w === inner.w && outer.h === inner.h) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tctx.save();\r\n\t\tctx.beginPath();\r\n\t\tctx.rect(outer.x, outer.y, outer.w, outer.h);\r\n\t\tctx.clip();\r\n\t\tctx.fillStyle = vm.borderColor;\r\n\t\tctx.rect(inner.x, inner.y, inner.w, inner.h);\r\n\t\tctx.fill('evenodd');\r\n\t\tctx.restore();\r\n\t},\r\n\r\n\theight: function() {\r\n\t\tvar vm = this._view;\r\n\t\treturn vm.base - vm.y;\r\n\t},\r\n\r\n\tinRange: function(mouseX, mouseY) {\r\n\t\treturn inRange(this._view, mouseX, mouseY);\r\n\t},\r\n\r\n\tinLabelRange: function(mouseX, mouseY) {\r\n\t\tvar vm = this._view;\r\n\t\treturn isVertical(vm)\r\n\t\t\t? inRange(vm, mouseX, null)\r\n\t\t\t: inRange(vm, null, mouseY);\r\n\t},\r\n\r\n\tinXRange: function(mouseX) {\r\n\t\treturn inRange(this._view, mouseX, null);\r\n\t},\r\n\r\n\tinYRange: function(mouseY) {\r\n\t\treturn inRange(this._view, null, mouseY);\r\n\t},\r\n\r\n\tgetCenterPoint: function() {\r\n\t\tvar vm = this._view;\r\n\t\tvar x, y;\r\n\t\tif (isVertical(vm)) {\r\n\t\t\tx = vm.x;\r\n\t\t\ty = (vm.y + vm.base) / 2;\r\n\t\t} else {\r\n\t\t\tx = (vm.x + vm.base) / 2;\r\n\t\t\ty = vm.y;\r\n\t\t}\r\n\r\n\t\treturn {x: x, y: y};\r\n\t},\r\n\r\n\tgetArea: function() {\r\n\t\tvar vm = this._view;\r\n\r\n\t\treturn isVertical(vm)\r\n\t\t\t? vm.width * Math.abs(vm.y - vm.base)\r\n\t\t\t: vm.height * Math.abs(vm.x - vm.base);\r\n\t},\r\n\r\n\ttooltipPosition: function() {\r\n\t\tvar vm = this._view;\r\n\t\treturn {\r\n\t\t\tx: vm.x,\r\n\t\t\ty: vm.y\r\n\t\t};\r\n\t}\r\n});\n\nvar elements = {};\r\nvar Arc = element_arc;\r\nvar Line = element_line;\r\nvar Point = element_point;\r\nvar Rectangle = element_rectangle;\nelements.Arc = Arc;\nelements.Line = Line;\nelements.Point = Point;\nelements.Rectangle = Rectangle;\n\nvar deprecated = helpers$1._deprecated;\r\nvar valueOrDefault$3 = helpers$1.valueOrDefault;\r\n\r\ncore_defaults._set('bar', {\r\n\thover: {\r\n\t\tmode: 'label'\r\n\t},\r\n\r\n\tscales: {\r\n\t\txAxes: [{\r\n\t\t\ttype: 'category',\r\n\t\t\toffset: true,\r\n\t\t\tgridLines: {\r\n\t\t\t\toffsetGridLines: true\r\n\t\t\t}\r\n\t\t}],\r\n\r\n\t\tyAxes: [{\r\n\t\t\ttype: 'linear'\r\n\t\t}]\r\n\t}\r\n});\r\n\r\ncore_defaults._set('global', {\r\n\tdatasets: {\r\n\t\tbar: {\r\n\t\t\tcategoryPercentage: 0.8,\r\n\t\t\tbarPercentage: 0.9\r\n\t\t}\r\n\t}\r\n});\r\n\r\n/**\r\n * Computes the \"optimal\" sample size to maintain bars equally sized while preventing overlap.\r\n * @private\r\n */\r\nfunction computeMinSampleSize(scale, pixels) {\r\n\tvar min = scale._length;\r\n\tvar prev, curr, i, ilen;\r\n\r\n\tfor (i = 1, ilen = pixels.length; i < ilen; ++i) {\r\n\t\tmin = Math.min(min, Math.abs(pixels[i] - pixels[i - 1]));\r\n\t}\r\n\r\n\tfor (i = 0, ilen = scale.getTicks().length; i < ilen; ++i) {\r\n\t\tcurr = scale.getPixelForTick(i);\r\n\t\tmin = i > 0 ? Math.min(min, Math.abs(curr - prev)) : min;\r\n\t\tprev = curr;\r\n\t}\r\n\r\n\treturn min;\r\n}\r\n\r\n/**\r\n * Computes an \"ideal\" category based on the absolute bar thickness or, if undefined or null,\r\n * uses the smallest interval (see computeMinSampleSize) that prevents bar overlapping. This\r\n * mode currently always generates bars equally sized (until we introduce scriptable options?).\r\n * @private\r\n */\r\nfunction computeFitCategoryTraits(index, ruler, options) {\r\n\tvar thickness = options.barThickness;\r\n\tvar count = ruler.stackCount;\r\n\tvar curr = ruler.pixels[index];\r\n\tvar min = helpers$1.isNullOrUndef(thickness)\r\n\t\t? computeMinSampleSize(ruler.scale, ruler.pixels)\r\n\t\t: -1;\r\n\tvar size, ratio;\r\n\r\n\tif (helpers$1.isNullOrUndef(thickness)) {\r\n\t\tsize = min * options.categoryPercentage;\r\n\t\tratio = options.barPercentage;\r\n\t} else {\r\n\t\t// When bar thickness is enforced, category and bar percentages are ignored.\r\n\t\t// Note(SB): we could add support for relative bar thickness (e.g. barThickness: '50%')\r\n\t\t// and deprecate barPercentage since this value is ignored when thickness is absolute.\r\n\t\tsize = thickness * count;\r\n\t\tratio = 1;\r\n\t}\r\n\r\n\treturn {\r\n\t\tchunk: size / count,\r\n\t\tratio: ratio,\r\n\t\tstart: curr - (size / 2)\r\n\t};\r\n}\r\n\r\n/**\r\n * Computes an \"optimal\" category that globally arranges bars side by side (no gap when\r\n * percentage options are 1), based on the previous and following categories. This mode\r\n * generates bars with different widths when data are not evenly spaced.\r\n * @private\r\n */\r\nfunction computeFlexCategoryTraits(index, ruler, options) {\r\n\tvar pixels = ruler.pixels;\r\n\tvar curr = pixels[index];\r\n\tvar prev = index > 0 ? pixels[index - 1] : null;\r\n\tvar next = index < pixels.length - 1 ? pixels[index + 1] : null;\r\n\tvar percent = options.categoryPercentage;\r\n\tvar start, size;\r\n\r\n\tif (prev === null) {\r\n\t\t// first data: its size is double based on the next point or,\r\n\t\t// if it's also the last data, we use the scale size.\r\n\t\tprev = curr - (next === null ? ruler.end - ruler.start : next - curr);\r\n\t}\r\n\r\n\tif (next === null) {\r\n\t\t// last data: its size is also double based on the previous point.\r\n\t\tnext = curr + curr - prev;\r\n\t}\r\n\r\n\tstart = curr - (curr - Math.min(prev, next)) / 2 * percent;\r\n\tsize = Math.abs(next - prev) / 2 * percent;\r\n\r\n\treturn {\r\n\t\tchunk: size / ruler.stackCount,\r\n\t\tratio: options.barPercentage,\r\n\t\tstart: start\r\n\t};\r\n}\r\n\r\nvar controller_bar = core_datasetController.extend({\r\n\r\n\tdataElementType: elements.Rectangle,\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_dataElementOptions: [\r\n\t\t'backgroundColor',\r\n\t\t'borderColor',\r\n\t\t'borderSkipped',\r\n\t\t'borderWidth',\r\n\t\t'barPercentage',\r\n\t\t'barThickness',\r\n\t\t'categoryPercentage',\r\n\t\t'maxBarThickness',\r\n\t\t'minBarLength'\r\n\t],\r\n\r\n\tinitialize: function() {\r\n\t\tvar me = this;\r\n\t\tvar meta, scaleOpts;\r\n\r\n\t\tcore_datasetController.prototype.initialize.apply(me, arguments);\r\n\r\n\t\tmeta = me.getMeta();\r\n\t\tmeta.stack = me.getDataset().stack;\r\n\t\tmeta.bar = true;\r\n\r\n\t\tscaleOpts = me._getIndexScale().options;\r\n\t\tdeprecated('bar chart', scaleOpts.barPercentage, 'scales.[x/y]Axes.barPercentage', 'dataset.barPercentage');\r\n\t\tdeprecated('bar chart', scaleOpts.barThickness, 'scales.[x/y]Axes.barThickness', 'dataset.barThickness');\r\n\t\tdeprecated('bar chart', scaleOpts.categoryPercentage, 'scales.[x/y]Axes.categoryPercentage', 'dataset.categoryPercentage');\r\n\t\tdeprecated('bar chart', me._getValueScale().options.minBarLength, 'scales.[x/y]Axes.minBarLength', 'dataset.minBarLength');\r\n\t\tdeprecated('bar chart', scaleOpts.maxBarThickness, 'scales.[x/y]Axes.maxBarThickness', 'dataset.maxBarThickness');\r\n\t},\r\n\r\n\tupdate: function(reset) {\r\n\t\tvar me = this;\r\n\t\tvar rects = me.getMeta().data;\r\n\t\tvar i, ilen;\r\n\r\n\t\tme._ruler = me.getRuler();\r\n\r\n\t\tfor (i = 0, ilen = rects.length; i < ilen; ++i) {\r\n\t\t\tme.updateElement(rects[i], i, reset);\r\n\t\t}\r\n\t},\r\n\r\n\tupdateElement: function(rectangle, index, reset) {\r\n\t\tvar me = this;\r\n\t\tvar meta = me.getMeta();\r\n\t\tvar dataset = me.getDataset();\r\n\t\tvar options = me._resolveDataElementOptions(rectangle, index);\r\n\r\n\t\trectangle._xScale = me.getScaleForId(meta.xAxisID);\r\n\t\trectangle._yScale = me.getScaleForId(meta.yAxisID);\r\n\t\trectangle._datasetIndex = me.index;\r\n\t\trectangle._index = index;\r\n\t\trectangle._model = {\r\n\t\t\tbackgroundColor: options.backgroundColor,\r\n\t\t\tborderColor: options.borderColor,\r\n\t\t\tborderSkipped: options.borderSkipped,\r\n\t\t\tborderWidth: options.borderWidth,\r\n\t\t\tdatasetLabel: dataset.label,\r\n\t\t\tlabel: me.chart.data.labels[index]\r\n\t\t};\r\n\r\n\t\tif (helpers$1.isArray(dataset.data[index])) {\r\n\t\t\trectangle._model.borderSkipped = null;\r\n\t\t}\r\n\r\n\t\tme._updateElementGeometry(rectangle, index, reset, options);\r\n\r\n\t\trectangle.pivot();\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_updateElementGeometry: function(rectangle, index, reset, options) {\r\n\t\tvar me = this;\r\n\t\tvar model = rectangle._model;\r\n\t\tvar vscale = me._getValueScale();\r\n\t\tvar base = vscale.getBasePixel();\r\n\t\tvar horizontal = vscale.isHorizontal();\r\n\t\tvar ruler = me._ruler || me.getRuler();\r\n\t\tvar vpixels = me.calculateBarValuePixels(me.index, index, options);\r\n\t\tvar ipixels = me.calculateBarIndexPixels(me.index, index, ruler, options);\r\n\r\n\t\tmodel.horizontal = horizontal;\r\n\t\tmodel.base = reset ? base : vpixels.base;\r\n\t\tmodel.x = horizontal ? reset ? base : vpixels.head : ipixels.center;\r\n\t\tmodel.y = horizontal ? ipixels.center : reset ? base : vpixels.head;\r\n\t\tmodel.height = horizontal ? ipixels.size : undefined;\r\n\t\tmodel.width = horizontal ? undefined : ipixels.size;\r\n\t},\r\n\r\n\t/**\r\n\t * Returns the stacks based on groups and bar visibility.\r\n\t * @param {number} [last] - The dataset index\r\n\t * @returns {string[]} The list of stack IDs\r\n\t * @private\r\n\t */\r\n\t_getStacks: function(last) {\r\n\t\tvar me = this;\r\n\t\tvar scale = me._getIndexScale();\r\n\t\tvar metasets = scale._getMatchingVisibleMetas(me._type);\r\n\t\tvar stacked = scale.options.stacked;\r\n\t\tvar ilen = metasets.length;\r\n\t\tvar stacks = [];\r\n\t\tvar i, meta;\r\n\r\n\t\tfor (i = 0; i < ilen; ++i) {\r\n\t\t\tmeta = metasets[i];\r\n\t\t\t// stacked | meta.stack\r\n\t\t\t// | found | not found | undefined\r\n\t\t\t// false | x | x | x\r\n\t\t\t// true | | x |\r\n\t\t\t// undefined | | x | x\r\n\t\t\tif (stacked === false || stacks.indexOf(meta.stack) === -1 ||\r\n\t\t\t\t(stacked === undefined && meta.stack === undefined)) {\r\n\t\t\t\tstacks.push(meta.stack);\r\n\t\t\t}\r\n\t\t\tif (meta.index === last) {\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn stacks;\r\n\t},\r\n\r\n\t/**\r\n\t * Returns the effective number of stacks based on groups and bar visibility.\r\n\t * @private\r\n\t */\r\n\tgetStackCount: function() {\r\n\t\treturn this._getStacks().length;\r\n\t},\r\n\r\n\t/**\r\n\t * Returns the stack index for the given dataset based on groups and bar visibility.\r\n\t * @param {number} [datasetIndex] - The dataset index\r\n\t * @param {string} [name] - The stack name to find\r\n\t * @returns {number} The stack index\r\n\t * @private\r\n\t */\r\n\tgetStackIndex: function(datasetIndex, name) {\r\n\t\tvar stacks = this._getStacks(datasetIndex);\r\n\t\tvar index = (name !== undefined)\r\n\t\t\t? stacks.indexOf(name)\r\n\t\t\t: -1; // indexOf returns -1 if element is not present\r\n\r\n\t\treturn (index === -1)\r\n\t\t\t? stacks.length - 1\r\n\t\t\t: index;\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\tgetRuler: function() {\r\n\t\tvar me = this;\r\n\t\tvar scale = me._getIndexScale();\r\n\t\tvar pixels = [];\r\n\t\tvar i, ilen;\r\n\r\n\t\tfor (i = 0, ilen = me.getMeta().data.length; i < ilen; ++i) {\r\n\t\t\tpixels.push(scale.getPixelForValue(null, i, me.index));\r\n\t\t}\r\n\r\n\t\treturn {\r\n\t\t\tpixels: pixels,\r\n\t\t\tstart: scale._startPixel,\r\n\t\t\tend: scale._endPixel,\r\n\t\t\tstackCount: me.getStackCount(),\r\n\t\t\tscale: scale\r\n\t\t};\r\n\t},\r\n\r\n\t/**\r\n\t * Note: pixel values are not clamped to the scale area.\r\n\t * @private\r\n\t */\r\n\tcalculateBarValuePixels: function(datasetIndex, index, options) {\r\n\t\tvar me = this;\r\n\t\tvar chart = me.chart;\r\n\t\tvar scale = me._getValueScale();\r\n\t\tvar isHorizontal = scale.isHorizontal();\r\n\t\tvar datasets = chart.data.datasets;\r\n\t\tvar metasets = scale._getMatchingVisibleMetas(me._type);\r\n\t\tvar value = scale._parseValue(datasets[datasetIndex].data[index]);\r\n\t\tvar minBarLength = options.minBarLength;\r\n\t\tvar stacked = scale.options.stacked;\r\n\t\tvar stack = me.getMeta().stack;\r\n\t\tvar start = value.start === undefined ? 0 : value.max >= 0 && value.min >= 0 ? value.min : value.max;\r\n\t\tvar length = value.start === undefined ? value.end : value.max >= 0 && value.min >= 0 ? value.max - value.min : value.min - value.max;\r\n\t\tvar ilen = metasets.length;\r\n\t\tvar i, imeta, ivalue, base, head, size, stackLength;\r\n\r\n\t\tif (stacked || (stacked === undefined && stack !== undefined)) {\r\n\t\t\tfor (i = 0; i < ilen; ++i) {\r\n\t\t\t\timeta = metasets[i];\r\n\r\n\t\t\t\tif (imeta.index === datasetIndex) {\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (imeta.stack === stack) {\r\n\t\t\t\t\tstackLength = scale._parseValue(datasets[imeta.index].data[index]);\r\n\t\t\t\t\tivalue = stackLength.start === undefined ? stackLength.end : stackLength.min >= 0 && stackLength.max >= 0 ? stackLength.max : stackLength.min;\r\n\r\n\t\t\t\t\tif ((value.min < 0 && ivalue < 0) || (value.max >= 0 && ivalue > 0)) {\r\n\t\t\t\t\t\tstart += ivalue;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tbase = scale.getPixelForValue(start);\r\n\t\thead = scale.getPixelForValue(start + length);\r\n\t\tsize = head - base;\r\n\r\n\t\tif (minBarLength !== undefined && Math.abs(size) < minBarLength) {\r\n\t\t\tsize = minBarLength;\r\n\t\t\tif (length >= 0 && !isHorizontal || length < 0 && isHorizontal) {\r\n\t\t\t\thead = base - minBarLength;\r\n\t\t\t} else {\r\n\t\t\t\thead = base + minBarLength;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn {\r\n\t\t\tsize: size,\r\n\t\t\tbase: base,\r\n\t\t\thead: head,\r\n\t\t\tcenter: head + size / 2\r\n\t\t};\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\tcalculateBarIndexPixels: function(datasetIndex, index, ruler, options) {\r\n\t\tvar me = this;\r\n\t\tvar range = options.barThickness === 'flex'\r\n\t\t\t? computeFlexCategoryTraits(index, ruler, options)\r\n\t\t\t: computeFitCategoryTraits(index, ruler, options);\r\n\r\n\t\tvar stackIndex = me.getStackIndex(datasetIndex, me.getMeta().stack);\r\n\t\tvar center = range.start + (range.chunk * stackIndex) + (range.chunk / 2);\r\n\t\tvar size = Math.min(\r\n\t\t\tvalueOrDefault$3(options.maxBarThickness, Infinity),\r\n\t\t\trange.chunk * range.ratio);\r\n\r\n\t\treturn {\r\n\t\t\tbase: center - size / 2,\r\n\t\t\thead: center + size / 2,\r\n\t\t\tcenter: center,\r\n\t\t\tsize: size\r\n\t\t};\r\n\t},\r\n\r\n\tdraw: function() {\r\n\t\tvar me = this;\r\n\t\tvar chart = me.chart;\r\n\t\tvar scale = me._getValueScale();\r\n\t\tvar rects = me.getMeta().data;\r\n\t\tvar dataset = me.getDataset();\r\n\t\tvar ilen = rects.length;\r\n\t\tvar i = 0;\r\n\r\n\t\thelpers$1.canvas.clipArea(chart.ctx, chart.chartArea);\r\n\r\n\t\tfor (; i < ilen; ++i) {\r\n\t\t\tvar val = scale._parseValue(dataset.data[i]);\r\n\t\t\tif (!isNaN(val.min) && !isNaN(val.max)) {\r\n\t\t\t\trects[i].draw();\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\thelpers$1.canvas.unclipArea(chart.ctx);\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_resolveDataElementOptions: function() {\r\n\t\tvar me = this;\r\n\t\tvar values = helpers$1.extend({}, core_datasetController.prototype._resolveDataElementOptions.apply(me, arguments));\r\n\t\tvar indexOpts = me._getIndexScale().options;\r\n\t\tvar valueOpts = me._getValueScale().options;\r\n\r\n\t\tvalues.barPercentage = valueOrDefault$3(indexOpts.barPercentage, values.barPercentage);\r\n\t\tvalues.barThickness = valueOrDefault$3(indexOpts.barThickness, values.barThickness);\r\n\t\tvalues.categoryPercentage = valueOrDefault$3(indexOpts.categoryPercentage, values.categoryPercentage);\r\n\t\tvalues.maxBarThickness = valueOrDefault$3(indexOpts.maxBarThickness, values.maxBarThickness);\r\n\t\tvalues.minBarLength = valueOrDefault$3(valueOpts.minBarLength, values.minBarLength);\r\n\r\n\t\treturn values;\r\n\t}\r\n\r\n});\n\nvar valueOrDefault$4 = helpers$1.valueOrDefault;\r\nvar resolve$1 = helpers$1.options.resolve;\r\n\r\ncore_defaults._set('bubble', {\r\n\thover: {\r\n\t\tmode: 'single'\r\n\t},\r\n\r\n\tscales: {\r\n\t\txAxes: [{\r\n\t\t\ttype: 'linear', // bubble should probably use a linear scale by default\r\n\t\t\tposition: 'bottom',\r\n\t\t\tid: 'x-axis-0' // need an ID so datasets can reference the scale\r\n\t\t}],\r\n\t\tyAxes: [{\r\n\t\t\ttype: 'linear',\r\n\t\t\tposition: 'left',\r\n\t\t\tid: 'y-axis-0'\r\n\t\t}]\r\n\t},\r\n\r\n\ttooltips: {\r\n\t\tcallbacks: {\r\n\t\t\ttitle: function() {\r\n\t\t\t\t// Title doesn't make sense for scatter since we format the data as a point\r\n\t\t\t\treturn '';\r\n\t\t\t},\r\n\t\t\tlabel: function(item, data) {\r\n\t\t\t\tvar datasetLabel = data.datasets[item.datasetIndex].label || '';\r\n\t\t\t\tvar dataPoint = data.datasets[item.datasetIndex].data[item.index];\r\n\t\t\t\treturn datasetLabel + ': (' + item.xLabel + ', ' + item.yLabel + ', ' + dataPoint.r + ')';\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n});\r\n\r\nvar controller_bubble = core_datasetController.extend({\r\n\t/**\r\n\t * @protected\r\n\t */\r\n\tdataElementType: elements.Point,\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_dataElementOptions: [\r\n\t\t'backgroundColor',\r\n\t\t'borderColor',\r\n\t\t'borderWidth',\r\n\t\t'hoverBackgroundColor',\r\n\t\t'hoverBorderColor',\r\n\t\t'hoverBorderWidth',\r\n\t\t'hoverRadius',\r\n\t\t'hitRadius',\r\n\t\t'pointStyle',\r\n\t\t'rotation'\r\n\t],\r\n\r\n\t/**\r\n\t * @protected\r\n\t */\r\n\tupdate: function(reset) {\r\n\t\tvar me = this;\r\n\t\tvar meta = me.getMeta();\r\n\t\tvar points = meta.data;\r\n\r\n\t\t// Update Points\r\n\t\thelpers$1.each(points, function(point, index) {\r\n\t\t\tme.updateElement(point, index, reset);\r\n\t\t});\r\n\t},\r\n\r\n\t/**\r\n\t * @protected\r\n\t */\r\n\tupdateElement: function(point, index, reset) {\r\n\t\tvar me = this;\r\n\t\tvar meta = me.getMeta();\r\n\t\tvar custom = point.custom || {};\r\n\t\tvar xScale = me.getScaleForId(meta.xAxisID);\r\n\t\tvar yScale = me.getScaleForId(meta.yAxisID);\r\n\t\tvar options = me._resolveDataElementOptions(point, index);\r\n\t\tvar data = me.getDataset().data[index];\r\n\t\tvar dsIndex = me.index;\r\n\r\n\t\tvar x = reset ? xScale.getPixelForDecimal(0.5) : xScale.getPixelForValue(typeof data === 'object' ? data : NaN, index, dsIndex);\r\n\t\tvar y = reset ? yScale.getBasePixel() : yScale.getPixelForValue(data, index, dsIndex);\r\n\r\n\t\tpoint._xScale = xScale;\r\n\t\tpoint._yScale = yScale;\r\n\t\tpoint._options = options;\r\n\t\tpoint._datasetIndex = dsIndex;\r\n\t\tpoint._index = index;\r\n\t\tpoint._model = {\r\n\t\t\tbackgroundColor: options.backgroundColor,\r\n\t\t\tborderColor: options.borderColor,\r\n\t\t\tborderWidth: options.borderWidth,\r\n\t\t\thitRadius: options.hitRadius,\r\n\t\t\tpointStyle: options.pointStyle,\r\n\t\t\trotation: options.rotation,\r\n\t\t\tradius: reset ? 0 : options.radius,\r\n\t\t\tskip: custom.skip || isNaN(x) || isNaN(y),\r\n\t\t\tx: x,\r\n\t\t\ty: y,\r\n\t\t};\r\n\r\n\t\tpoint.pivot();\r\n\t},\r\n\r\n\t/**\r\n\t * @protected\r\n\t */\r\n\tsetHoverStyle: function(point) {\r\n\t\tvar model = point._model;\r\n\t\tvar options = point._options;\r\n\t\tvar getHoverColor = helpers$1.getHoverColor;\r\n\r\n\t\tpoint.$previousStyle = {\r\n\t\t\tbackgroundColor: model.backgroundColor,\r\n\t\t\tborderColor: model.borderColor,\r\n\t\t\tborderWidth: model.borderWidth,\r\n\t\t\tradius: model.radius\r\n\t\t};\r\n\r\n\t\tmodel.backgroundColor = valueOrDefault$4(options.hoverBackgroundColor, getHoverColor(options.backgroundColor));\r\n\t\tmodel.borderColor = valueOrDefault$4(options.hoverBorderColor, getHoverColor(options.borderColor));\r\n\t\tmodel.borderWidth = valueOrDefault$4(options.hoverBorderWidth, options.borderWidth);\r\n\t\tmodel.radius = options.radius + options.hoverRadius;\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_resolveDataElementOptions: function(point, index) {\r\n\t\tvar me = this;\r\n\t\tvar chart = me.chart;\r\n\t\tvar dataset = me.getDataset();\r\n\t\tvar custom = point.custom || {};\r\n\t\tvar data = dataset.data[index] || {};\r\n\t\tvar values = core_datasetController.prototype._resolveDataElementOptions.apply(me, arguments);\r\n\r\n\t\t// Scriptable options\r\n\t\tvar context = {\r\n\t\t\tchart: chart,\r\n\t\t\tdataIndex: index,\r\n\t\t\tdataset: dataset,\r\n\t\t\tdatasetIndex: me.index\r\n\t\t};\r\n\r\n\t\t// In case values were cached (and thus frozen), we need to clone the values\r\n\t\tif (me._cachedDataOpts === values) {\r\n\t\t\tvalues = helpers$1.extend({}, values);\r\n\t\t}\r\n\r\n\t\t// Custom radius resolution\r\n\t\tvalues.radius = resolve$1([\r\n\t\t\tcustom.radius,\r\n\t\t\tdata.r,\r\n\t\t\tme._config.radius,\r\n\t\t\tchart.options.elements.point.radius\r\n\t\t], context, index);\r\n\r\n\t\treturn values;\r\n\t}\r\n});\n\nvar valueOrDefault$5 = helpers$1.valueOrDefault;\r\n\r\nvar PI$1 = Math.PI;\r\nvar DOUBLE_PI$1 = PI$1 * 2;\r\nvar HALF_PI$1 = PI$1 / 2;\r\n\r\ncore_defaults._set('doughnut', {\r\n\tanimation: {\r\n\t\t// Boolean - Whether we animate the rotation of the Doughnut\r\n\t\tanimateRotate: true,\r\n\t\t// Boolean - Whether we animate scaling the Doughnut from the centre\r\n\t\tanimateScale: false\r\n\t},\r\n\thover: {\r\n\t\tmode: 'single'\r\n\t},\r\n\tlegendCallback: function(chart) {\r\n\t\tvar list = document.createElement('ul');\r\n\t\tvar data = chart.data;\r\n\t\tvar datasets = data.datasets;\r\n\t\tvar labels = data.labels;\r\n\t\tvar i, ilen, listItem, listItemSpan;\r\n\r\n\t\tlist.setAttribute('class', chart.id + '-legend');\r\n\t\tif (datasets.length) {\r\n\t\t\tfor (i = 0, ilen = datasets[0].data.length; i < ilen; ++i) {\r\n\t\t\t\tlistItem = list.appendChild(document.createElement('li'));\r\n\t\t\t\tlistItemSpan = listItem.appendChild(document.createElement('span'));\r\n\t\t\t\tlistItemSpan.style.backgroundColor = datasets[0].backgroundColor[i];\r\n\t\t\t\tif (labels[i]) {\r\n\t\t\t\t\tlistItem.appendChild(document.createTextNode(labels[i]));\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn list.outerHTML;\r\n\t},\r\n\tlegend: {\r\n\t\tlabels: {\r\n\t\t\tgenerateLabels: function(chart) {\r\n\t\t\t\tvar data = chart.data;\r\n\t\t\t\tif (data.labels.length && data.datasets.length) {\r\n\t\t\t\t\treturn data.labels.map(function(label, i) {\r\n\t\t\t\t\t\tvar meta = chart.getDatasetMeta(0);\r\n\t\t\t\t\t\tvar style = meta.controller.getStyle(i);\r\n\r\n\t\t\t\t\t\treturn {\r\n\t\t\t\t\t\t\ttext: label,\r\n\t\t\t\t\t\t\tfillStyle: style.backgroundColor,\r\n\t\t\t\t\t\t\tstrokeStyle: style.borderColor,\r\n\t\t\t\t\t\t\tlineWidth: style.borderWidth,\r\n\t\t\t\t\t\t\thidden: isNaN(data.datasets[0].data[i]) || meta.data[i].hidden,\r\n\r\n\t\t\t\t\t\t\t// Extra data used for toggling the correct item\r\n\t\t\t\t\t\t\tindex: i\r\n\t\t\t\t\t\t};\r\n\t\t\t\t\t});\r\n\t\t\t\t}\r\n\t\t\t\treturn [];\r\n\t\t\t}\r\n\t\t},\r\n\r\n\t\tonClick: function(e, legendItem) {\r\n\t\t\tvar index = legendItem.index;\r\n\t\t\tvar chart = this.chart;\r\n\t\t\tvar i, ilen, meta;\r\n\r\n\t\t\tfor (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) {\r\n\t\t\t\tmeta = chart.getDatasetMeta(i);\r\n\t\t\t\t// toggle visibility of index if exists\r\n\t\t\t\tif (meta.data[index]) {\r\n\t\t\t\t\tmeta.data[index].hidden = !meta.data[index].hidden;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tchart.update();\r\n\t\t}\r\n\t},\r\n\r\n\t// The percentage of the chart that we cut out of the middle.\r\n\tcutoutPercentage: 50,\r\n\r\n\t// The rotation of the chart, where the first data arc begins.\r\n\trotation: -HALF_PI$1,\r\n\r\n\t// The total circumference of the chart.\r\n\tcircumference: DOUBLE_PI$1,\r\n\r\n\t// Need to override these to give a nice default\r\n\ttooltips: {\r\n\t\tcallbacks: {\r\n\t\t\ttitle: function() {\r\n\t\t\t\treturn '';\r\n\t\t\t},\r\n\t\t\tlabel: function(tooltipItem, data) {\r\n\t\t\t\tvar dataLabel = data.labels[tooltipItem.index];\r\n\t\t\t\tvar value = ': ' + data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];\r\n\r\n\t\t\t\tif (helpers$1.isArray(dataLabel)) {\r\n\t\t\t\t\t// show value on first line of multiline label\r\n\t\t\t\t\t// need to clone because we are changing the value\r\n\t\t\t\t\tdataLabel = dataLabel.slice();\r\n\t\t\t\t\tdataLabel[0] += value;\r\n\t\t\t\t} else {\r\n\t\t\t\t\tdataLabel += value;\r\n\t\t\t\t}\r\n\r\n\t\t\t\treturn dataLabel;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n});\r\n\r\nvar controller_doughnut = core_datasetController.extend({\r\n\r\n\tdataElementType: elements.Arc,\r\n\r\n\tlinkScales: helpers$1.noop,\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_dataElementOptions: [\r\n\t\t'backgroundColor',\r\n\t\t'borderColor',\r\n\t\t'borderWidth',\r\n\t\t'borderAlign',\r\n\t\t'hoverBackgroundColor',\r\n\t\t'hoverBorderColor',\r\n\t\t'hoverBorderWidth',\r\n\t],\r\n\r\n\t// Get index of the dataset in relation to the visible datasets. This allows determining the inner and outer radius correctly\r\n\tgetRingIndex: function(datasetIndex) {\r\n\t\tvar ringIndex = 0;\r\n\r\n\t\tfor (var j = 0; j < datasetIndex; ++j) {\r\n\t\t\tif (this.chart.isDatasetVisible(j)) {\r\n\t\t\t\t++ringIndex;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn ringIndex;\r\n\t},\r\n\r\n\tupdate: function(reset) {\r\n\t\tvar me = this;\r\n\t\tvar chart = me.chart;\r\n\t\tvar chartArea = chart.chartArea;\r\n\t\tvar opts = chart.options;\r\n\t\tvar ratioX = 1;\r\n\t\tvar ratioY = 1;\r\n\t\tvar offsetX = 0;\r\n\t\tvar offsetY = 0;\r\n\t\tvar meta = me.getMeta();\r\n\t\tvar arcs = meta.data;\r\n\t\tvar cutout = opts.cutoutPercentage / 100 || 0;\r\n\t\tvar circumference = opts.circumference;\r\n\t\tvar chartWeight = me._getRingWeight(me.index);\r\n\t\tvar maxWidth, maxHeight, i, ilen;\r\n\r\n\t\t// If the chart's circumference isn't a full circle, calculate size as a ratio of the width/height of the arc\r\n\t\tif (circumference < DOUBLE_PI$1) {\r\n\t\t\tvar startAngle = opts.rotation % DOUBLE_PI$1;\r\n\t\t\tstartAngle += startAngle >= PI$1 ? -DOUBLE_PI$1 : startAngle < -PI$1 ? DOUBLE_PI$1 : 0;\r\n\t\t\tvar endAngle = startAngle + circumference;\r\n\t\t\tvar startX = Math.cos(startAngle);\r\n\t\t\tvar startY = Math.sin(startAngle);\r\n\t\t\tvar endX = Math.cos(endAngle);\r\n\t\t\tvar endY = Math.sin(endAngle);\r\n\t\t\tvar contains0 = (startAngle <= 0 && endAngle >= 0) || endAngle >= DOUBLE_PI$1;\r\n\t\t\tvar contains90 = (startAngle <= HALF_PI$1 && endAngle >= HALF_PI$1) || endAngle >= DOUBLE_PI$1 + HALF_PI$1;\r\n\t\t\tvar contains180 = startAngle === -PI$1 || endAngle >= PI$1;\r\n\t\t\tvar contains270 = (startAngle <= -HALF_PI$1 && endAngle >= -HALF_PI$1) || endAngle >= PI$1 + HALF_PI$1;\r\n\t\t\tvar minX = contains180 ? -1 : Math.min(startX, startX * cutout, endX, endX * cutout);\r\n\t\t\tvar minY = contains270 ? -1 : Math.min(startY, startY * cutout, endY, endY * cutout);\r\n\t\t\tvar maxX = contains0 ? 1 : Math.max(startX, startX * cutout, endX, endX * cutout);\r\n\t\t\tvar maxY = contains90 ? 1 : Math.max(startY, startY * cutout, endY, endY * cutout);\r\n\t\t\tratioX = (maxX - minX) / 2;\r\n\t\t\tratioY = (maxY - minY) / 2;\r\n\t\t\toffsetX = -(maxX + minX) / 2;\r\n\t\t\toffsetY = -(maxY + minY) / 2;\r\n\t\t}\r\n\r\n\t\tfor (i = 0, ilen = arcs.length; i < ilen; ++i) {\r\n\t\t\tarcs[i]._options = me._resolveDataElementOptions(arcs[i], i);\r\n\t\t}\r\n\r\n\t\tchart.borderWidth = me.getMaxBorderWidth();\r\n\t\tmaxWidth = (chartArea.right - chartArea.left - chart.borderWidth) / ratioX;\r\n\t\tmaxHeight = (chartArea.bottom - chartArea.top - chart.borderWidth) / ratioY;\r\n\t\tchart.outerRadius = Math.max(Math.min(maxWidth, maxHeight) / 2, 0);\r\n\t\tchart.innerRadius = Math.max(chart.outerRadius * cutout, 0);\r\n\t\tchart.radiusLength = (chart.outerRadius - chart.innerRadius) / (me._getVisibleDatasetWeightTotal() || 1);\r\n\t\tchart.offsetX = offsetX * chart.outerRadius;\r\n\t\tchart.offsetY = offsetY * chart.outerRadius;\r\n\r\n\t\tmeta.total = me.calculateTotal();\r\n\r\n\t\tme.outerRadius = chart.outerRadius - chart.radiusLength * me._getRingWeightOffset(me.index);\r\n\t\tme.innerRadius = Math.max(me.outerRadius - chart.radiusLength * chartWeight, 0);\r\n\r\n\t\tfor (i = 0, ilen = arcs.length; i < ilen; ++i) {\r\n\t\t\tme.updateElement(arcs[i], i, reset);\r\n\t\t}\r\n\t},\r\n\r\n\tupdateElement: function(arc, index, reset) {\r\n\t\tvar me = this;\r\n\t\tvar chart = me.chart;\r\n\t\tvar chartArea = chart.chartArea;\r\n\t\tvar opts = chart.options;\r\n\t\tvar animationOpts = opts.animation;\r\n\t\tvar centerX = (chartArea.left + chartArea.right) / 2;\r\n\t\tvar centerY = (chartArea.top + chartArea.bottom) / 2;\r\n\t\tvar startAngle = opts.rotation; // non reset case handled later\r\n\t\tvar endAngle = opts.rotation; // non reset case handled later\r\n\t\tvar dataset = me.getDataset();\r\n\t\tvar circumference = reset && animationOpts.animateRotate ? 0 : arc.hidden ? 0 : me.calculateCircumference(dataset.data[index]) * (opts.circumference / DOUBLE_PI$1);\r\n\t\tvar innerRadius = reset && animationOpts.animateScale ? 0 : me.innerRadius;\r\n\t\tvar outerRadius = reset && animationOpts.animateScale ? 0 : me.outerRadius;\r\n\t\tvar options = arc._options || {};\r\n\r\n\t\thelpers$1.extend(arc, {\r\n\t\t\t// Utility\r\n\t\t\t_datasetIndex: me.index,\r\n\t\t\t_index: index,\r\n\r\n\t\t\t// Desired view properties\r\n\t\t\t_model: {\r\n\t\t\t\tbackgroundColor: options.backgroundColor,\r\n\t\t\t\tborderColor: options.borderColor,\r\n\t\t\t\tborderWidth: options.borderWidth,\r\n\t\t\t\tborderAlign: options.borderAlign,\r\n\t\t\t\tx: centerX + chart.offsetX,\r\n\t\t\t\ty: centerY + chart.offsetY,\r\n\t\t\t\tstartAngle: startAngle,\r\n\t\t\t\tendAngle: endAngle,\r\n\t\t\t\tcircumference: circumference,\r\n\t\t\t\touterRadius: outerRadius,\r\n\t\t\t\tinnerRadius: innerRadius,\r\n\t\t\t\tlabel: helpers$1.valueAtIndexOrDefault(dataset.label, index, chart.data.labels[index])\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tvar model = arc._model;\r\n\r\n\t\t// Set correct angles if not resetting\r\n\t\tif (!reset || !animationOpts.animateRotate) {\r\n\t\t\tif (index === 0) {\r\n\t\t\t\tmodel.startAngle = opts.rotation;\r\n\t\t\t} else {\r\n\t\t\t\tmodel.startAngle = me.getMeta().data[index - 1]._model.endAngle;\r\n\t\t\t}\r\n\r\n\t\t\tmodel.endAngle = model.startAngle + model.circumference;\r\n\t\t}\r\n\r\n\t\tarc.pivot();\r\n\t},\r\n\r\n\tcalculateTotal: function() {\r\n\t\tvar dataset = this.getDataset();\r\n\t\tvar meta = this.getMeta();\r\n\t\tvar total = 0;\r\n\t\tvar value;\r\n\r\n\t\thelpers$1.each(meta.data, function(element, index) {\r\n\t\t\tvalue = dataset.data[index];\r\n\t\t\tif (!isNaN(value) && !element.hidden) {\r\n\t\t\t\ttotal += Math.abs(value);\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\t/* if (total === 0) {\r\n\t\t\ttotal = NaN;\r\n\t\t}*/\r\n\r\n\t\treturn total;\r\n\t},\r\n\r\n\tcalculateCircumference: function(value) {\r\n\t\tvar total = this.getMeta().total;\r\n\t\tif (total > 0 && !isNaN(value)) {\r\n\t\t\treturn DOUBLE_PI$1 * (Math.abs(value) / total);\r\n\t\t}\r\n\t\treturn 0;\r\n\t},\r\n\r\n\t// gets the max border or hover width to properly scale pie charts\r\n\tgetMaxBorderWidth: function(arcs) {\r\n\t\tvar me = this;\r\n\t\tvar max = 0;\r\n\t\tvar chart = me.chart;\r\n\t\tvar i, ilen, meta, arc, controller, options, borderWidth, hoverWidth;\r\n\r\n\t\tif (!arcs) {\r\n\t\t\t// Find the outmost visible dataset\r\n\t\t\tfor (i = 0, ilen = chart.data.datasets.length; i < ilen; ++i) {\r\n\t\t\t\tif (chart.isDatasetVisible(i)) {\r\n\t\t\t\t\tmeta = chart.getDatasetMeta(i);\r\n\t\t\t\t\tarcs = meta.data;\r\n\t\t\t\t\tif (i !== me.index) {\r\n\t\t\t\t\t\tcontroller = meta.controller;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (!arcs) {\r\n\t\t\treturn 0;\r\n\t\t}\r\n\r\n\t\tfor (i = 0, ilen = arcs.length; i < ilen; ++i) {\r\n\t\t\tarc = arcs[i];\r\n\t\t\tif (controller) {\r\n\t\t\t\tcontroller._configure();\r\n\t\t\t\toptions = controller._resolveDataElementOptions(arc, i);\r\n\t\t\t} else {\r\n\t\t\t\toptions = arc._options;\r\n\t\t\t}\r\n\t\t\tif (options.borderAlign !== 'inner') {\r\n\t\t\t\tborderWidth = options.borderWidth;\r\n\t\t\t\thoverWidth = options.hoverBorderWidth;\r\n\r\n\t\t\t\tmax = borderWidth > max ? borderWidth : max;\r\n\t\t\t\tmax = hoverWidth > max ? hoverWidth : max;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn max;\r\n\t},\r\n\r\n\t/**\r\n\t * @protected\r\n\t */\r\n\tsetHoverStyle: function(arc) {\r\n\t\tvar model = arc._model;\r\n\t\tvar options = arc._options;\r\n\t\tvar getHoverColor = helpers$1.getHoverColor;\r\n\r\n\t\tarc.$previousStyle = {\r\n\t\t\tbackgroundColor: model.backgroundColor,\r\n\t\t\tborderColor: model.borderColor,\r\n\t\t\tborderWidth: model.borderWidth,\r\n\t\t};\r\n\r\n\t\tmodel.backgroundColor = valueOrDefault$5(options.hoverBackgroundColor, getHoverColor(options.backgroundColor));\r\n\t\tmodel.borderColor = valueOrDefault$5(options.hoverBorderColor, getHoverColor(options.borderColor));\r\n\t\tmodel.borderWidth = valueOrDefault$5(options.hoverBorderWidth, options.borderWidth);\r\n\t},\r\n\r\n\t/**\r\n\t * Get radius length offset of the dataset in relation to the visible datasets weights. This allows determining the inner and outer radius correctly\r\n\t * @private\r\n\t */\r\n\t_getRingWeightOffset: function(datasetIndex) {\r\n\t\tvar ringWeightOffset = 0;\r\n\r\n\t\tfor (var i = 0; i < datasetIndex; ++i) {\r\n\t\t\tif (this.chart.isDatasetVisible(i)) {\r\n\t\t\t\tringWeightOffset += this._getRingWeight(i);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn ringWeightOffset;\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_getRingWeight: function(dataSetIndex) {\r\n\t\treturn Math.max(valueOrDefault$5(this.chart.data.datasets[dataSetIndex].weight, 1), 0);\r\n\t},\r\n\r\n\t/**\r\n\t * Returns the sum of all visibile data set weights. This value can be 0.\r\n\t * @private\r\n\t */\r\n\t_getVisibleDatasetWeightTotal: function() {\r\n\t\treturn this._getRingWeightOffset(this.chart.data.datasets.length);\r\n\t}\r\n});\n\ncore_defaults._set('horizontalBar', {\r\n\thover: {\r\n\t\tmode: 'index',\r\n\t\taxis: 'y'\r\n\t},\r\n\r\n\tscales: {\r\n\t\txAxes: [{\r\n\t\t\ttype: 'linear',\r\n\t\t\tposition: 'bottom'\r\n\t\t}],\r\n\r\n\t\tyAxes: [{\r\n\t\t\ttype: 'category',\r\n\t\t\tposition: 'left',\r\n\t\t\toffset: true,\r\n\t\t\tgridLines: {\r\n\t\t\t\toffsetGridLines: true\r\n\t\t\t}\r\n\t\t}]\r\n\t},\r\n\r\n\telements: {\r\n\t\trectangle: {\r\n\t\t\tborderSkipped: 'left'\r\n\t\t}\r\n\t},\r\n\r\n\ttooltips: {\r\n\t\tmode: 'index',\r\n\t\taxis: 'y'\r\n\t}\r\n});\r\n\r\ncore_defaults._set('global', {\r\n\tdatasets: {\r\n\t\thorizontalBar: {\r\n\t\t\tcategoryPercentage: 0.8,\r\n\t\t\tbarPercentage: 0.9\r\n\t\t}\r\n\t}\r\n});\r\n\r\nvar controller_horizontalBar = controller_bar.extend({\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_getValueScaleId: function() {\r\n\t\treturn this.getMeta().xAxisID;\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_getIndexScaleId: function() {\r\n\t\treturn this.getMeta().yAxisID;\r\n\t}\r\n});\n\nvar valueOrDefault$6 = helpers$1.valueOrDefault;\r\nvar resolve$2 = helpers$1.options.resolve;\r\nvar isPointInArea = helpers$1.canvas._isPointInArea;\r\n\r\ncore_defaults._set('line', {\r\n\tshowLines: true,\r\n\tspanGaps: false,\r\n\r\n\thover: {\r\n\t\tmode: 'label'\r\n\t},\r\n\r\n\tscales: {\r\n\t\txAxes: [{\r\n\t\t\ttype: 'category',\r\n\t\t\tid: 'x-axis-0'\r\n\t\t}],\r\n\t\tyAxes: [{\r\n\t\t\ttype: 'linear',\r\n\t\t\tid: 'y-axis-0'\r\n\t\t}]\r\n\t}\r\n});\r\n\r\nfunction scaleClip(scale, halfBorderWidth) {\r\n\tvar tickOpts = scale && scale.options.ticks || {};\r\n\tvar reverse = tickOpts.reverse;\r\n\tvar min = tickOpts.min === undefined ? halfBorderWidth : 0;\r\n\tvar max = tickOpts.max === undefined ? halfBorderWidth : 0;\r\n\treturn {\r\n\t\tstart: reverse ? max : min,\r\n\t\tend: reverse ? min : max\r\n\t};\r\n}\r\n\r\nfunction defaultClip(xScale, yScale, borderWidth) {\r\n\tvar halfBorderWidth = borderWidth / 2;\r\n\tvar x = scaleClip(xScale, halfBorderWidth);\r\n\tvar y = scaleClip(yScale, halfBorderWidth);\r\n\r\n\treturn {\r\n\t\ttop: y.end,\r\n\t\tright: x.end,\r\n\t\tbottom: y.start,\r\n\t\tleft: x.start\r\n\t};\r\n}\r\n\r\nfunction toClip(value) {\r\n\tvar t, r, b, l;\r\n\r\n\tif (helpers$1.isObject(value)) {\r\n\t\tt = value.top;\r\n\t\tr = value.right;\r\n\t\tb = value.bottom;\r\n\t\tl = value.left;\r\n\t} else {\r\n\t\tt = r = b = l = value;\r\n\t}\r\n\r\n\treturn {\r\n\t\ttop: t,\r\n\t\tright: r,\r\n\t\tbottom: b,\r\n\t\tleft: l\r\n\t};\r\n}\r\n\r\n\r\nvar controller_line = core_datasetController.extend({\r\n\r\n\tdatasetElementType: elements.Line,\r\n\r\n\tdataElementType: elements.Point,\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_datasetElementOptions: [\r\n\t\t'backgroundColor',\r\n\t\t'borderCapStyle',\r\n\t\t'borderColor',\r\n\t\t'borderDash',\r\n\t\t'borderDashOffset',\r\n\t\t'borderJoinStyle',\r\n\t\t'borderWidth',\r\n\t\t'cubicInterpolationMode',\r\n\t\t'fill'\r\n\t],\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_dataElementOptions: {\r\n\t\tbackgroundColor: 'pointBackgroundColor',\r\n\t\tborderColor: 'pointBorderColor',\r\n\t\tborderWidth: 'pointBorderWidth',\r\n\t\thitRadius: 'pointHitRadius',\r\n\t\thoverBackgroundColor: 'pointHoverBackgroundColor',\r\n\t\thoverBorderColor: 'pointHoverBorderColor',\r\n\t\thoverBorderWidth: 'pointHoverBorderWidth',\r\n\t\thoverRadius: 'pointHoverRadius',\r\n\t\tpointStyle: 'pointStyle',\r\n\t\tradius: 'pointRadius',\r\n\t\trotation: 'pointRotation'\r\n\t},\r\n\r\n\tupdate: function(reset) {\r\n\t\tvar me = this;\r\n\t\tvar meta = me.getMeta();\r\n\t\tvar line = meta.dataset;\r\n\t\tvar points = meta.data || [];\r\n\t\tvar options = me.chart.options;\r\n\t\tvar config = me._config;\r\n\t\tvar showLine = me._showLine = valueOrDefault$6(config.showLine, options.showLines);\r\n\t\tvar i, ilen;\r\n\r\n\t\tme._xScale = me.getScaleForId(meta.xAxisID);\r\n\t\tme._yScale = me.getScaleForId(meta.yAxisID);\r\n\r\n\t\t// Update Line\r\n\t\tif (showLine) {\r\n\t\t\t// Compatibility: If the properties are defined with only the old name, use those values\r\n\t\t\tif (config.tension !== undefined && config.lineTension === undefined) {\r\n\t\t\t\tconfig.lineTension = config.tension;\r\n\t\t\t}\r\n\r\n\t\t\t// Utility\r\n\t\t\tline._scale = me._yScale;\r\n\t\t\tline._datasetIndex = me.index;\r\n\t\t\t// Data\r\n\t\t\tline._children = points;\r\n\t\t\t// Model\r\n\t\t\tline._model = me._resolveDatasetElementOptions(line);\r\n\r\n\t\t\tline.pivot();\r\n\t\t}\r\n\r\n\t\t// Update Points\r\n\t\tfor (i = 0, ilen = points.length; i < ilen; ++i) {\r\n\t\t\tme.updateElement(points[i], i, reset);\r\n\t\t}\r\n\r\n\t\tif (showLine && line._model.tension !== 0) {\r\n\t\t\tme.updateBezierControlPoints();\r\n\t\t}\r\n\r\n\t\t// Now pivot the point for animation\r\n\t\tfor (i = 0, ilen = points.length; i < ilen; ++i) {\r\n\t\t\tpoints[i].pivot();\r\n\t\t}\r\n\t},\r\n\r\n\tupdateElement: function(point, index, reset) {\r\n\t\tvar me = this;\r\n\t\tvar meta = me.getMeta();\r\n\t\tvar custom = point.custom || {};\r\n\t\tvar dataset = me.getDataset();\r\n\t\tvar datasetIndex = me.index;\r\n\t\tvar value = dataset.data[index];\r\n\t\tvar xScale = me._xScale;\r\n\t\tvar yScale = me._yScale;\r\n\t\tvar lineModel = meta.dataset._model;\r\n\t\tvar x, y;\r\n\r\n\t\tvar options = me._resolveDataElementOptions(point, index);\r\n\r\n\t\tx = xScale.getPixelForValue(typeof value === 'object' ? value : NaN, index, datasetIndex);\r\n\t\ty = reset ? yScale.getBasePixel() : me.calculatePointY(value, index, datasetIndex);\r\n\r\n\t\t// Utility\r\n\t\tpoint._xScale = xScale;\r\n\t\tpoint._yScale = yScale;\r\n\t\tpoint._options = options;\r\n\t\tpoint._datasetIndex = datasetIndex;\r\n\t\tpoint._index = index;\r\n\r\n\t\t// Desired view properties\r\n\t\tpoint._model = {\r\n\t\t\tx: x,\r\n\t\t\ty: y,\r\n\t\t\tskip: custom.skip || isNaN(x) || isNaN(y),\r\n\t\t\t// Appearance\r\n\t\t\tradius: options.radius,\r\n\t\t\tpointStyle: options.pointStyle,\r\n\t\t\trotation: options.rotation,\r\n\t\t\tbackgroundColor: options.backgroundColor,\r\n\t\t\tborderColor: options.borderColor,\r\n\t\t\tborderWidth: options.borderWidth,\r\n\t\t\ttension: valueOrDefault$6(custom.tension, lineModel ? lineModel.tension : 0),\r\n\t\t\tsteppedLine: lineModel ? lineModel.steppedLine : false,\r\n\t\t\t// Tooltip\r\n\t\t\thitRadius: options.hitRadius\r\n\t\t};\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_resolveDatasetElementOptions: function(element) {\r\n\t\tvar me = this;\r\n\t\tvar config = me._config;\r\n\t\tvar custom = element.custom || {};\r\n\t\tvar options = me.chart.options;\r\n\t\tvar lineOptions = options.elements.line;\r\n\t\tvar values = core_datasetController.prototype._resolveDatasetElementOptions.apply(me, arguments);\r\n\r\n\t\t// The default behavior of lines is to break at null values, according\r\n\t\t// to https://github.com/chartjs/Chart.js/issues/2435#issuecomment-216718158\r\n\t\t// This option gives lines the ability to span gaps\r\n\t\tvalues.spanGaps = valueOrDefault$6(config.spanGaps, options.spanGaps);\r\n\t\tvalues.tension = valueOrDefault$6(config.lineTension, lineOptions.tension);\r\n\t\tvalues.steppedLine = resolve$2([custom.steppedLine, config.steppedLine, lineOptions.stepped]);\r\n\t\tvalues.clip = toClip(valueOrDefault$6(config.clip, defaultClip(me._xScale, me._yScale, values.borderWidth)));\r\n\r\n\t\treturn values;\r\n\t},\r\n\r\n\tcalculatePointY: function(value, index, datasetIndex) {\r\n\t\tvar me = this;\r\n\t\tvar chart = me.chart;\r\n\t\tvar yScale = me._yScale;\r\n\t\tvar sumPos = 0;\r\n\t\tvar sumNeg = 0;\r\n\t\tvar i, ds, dsMeta, stackedRightValue, rightValue, metasets, ilen;\r\n\r\n\t\tif (yScale.options.stacked) {\r\n\t\t\trightValue = +yScale.getRightValue(value);\r\n\t\t\tmetasets = chart._getSortedVisibleDatasetMetas();\r\n\t\t\tilen = metasets.length;\r\n\r\n\t\t\tfor (i = 0; i < ilen; ++i) {\r\n\t\t\t\tdsMeta = metasets[i];\r\n\t\t\t\tif (dsMeta.index === datasetIndex) {\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tds = chart.data.datasets[dsMeta.index];\r\n\t\t\t\tif (dsMeta.type === 'line' && dsMeta.yAxisID === yScale.id) {\r\n\t\t\t\t\tstackedRightValue = +yScale.getRightValue(ds.data[index]);\r\n\t\t\t\t\tif (stackedRightValue < 0) {\r\n\t\t\t\t\t\tsumNeg += stackedRightValue || 0;\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tsumPos += stackedRightValue || 0;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (rightValue < 0) {\r\n\t\t\t\treturn yScale.getPixelForValue(sumNeg + rightValue);\r\n\t\t\t}\r\n\t\t\treturn yScale.getPixelForValue(sumPos + rightValue);\r\n\t\t}\r\n\t\treturn yScale.getPixelForValue(value);\r\n\t},\r\n\r\n\tupdateBezierControlPoints: function() {\r\n\t\tvar me = this;\r\n\t\tvar chart = me.chart;\r\n\t\tvar meta = me.getMeta();\r\n\t\tvar lineModel = meta.dataset._model;\r\n\t\tvar area = chart.chartArea;\r\n\t\tvar points = meta.data || [];\r\n\t\tvar i, ilen, model, controlPoints;\r\n\r\n\t\t// Only consider points that are drawn in case the spanGaps option is used\r\n\t\tif (lineModel.spanGaps) {\r\n\t\t\tpoints = points.filter(function(pt) {\r\n\t\t\t\treturn !pt._model.skip;\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tfunction capControlPoint(pt, min, max) {\r\n\t\t\treturn Math.max(Math.min(pt, max), min);\r\n\t\t}\r\n\r\n\t\tif (lineModel.cubicInterpolationMode === 'monotone') {\r\n\t\t\thelpers$1.splineCurveMonotone(points);\r\n\t\t} else {\r\n\t\t\tfor (i = 0, ilen = points.length; i < ilen; ++i) {\r\n\t\t\t\tmodel = points[i]._model;\r\n\t\t\t\tcontrolPoints = helpers$1.splineCurve(\r\n\t\t\t\t\thelpers$1.previousItem(points, i)._model,\r\n\t\t\t\t\tmodel,\r\n\t\t\t\t\thelpers$1.nextItem(points, i)._model,\r\n\t\t\t\t\tlineModel.tension\r\n\t\t\t\t);\r\n\t\t\t\tmodel.controlPointPreviousX = controlPoints.previous.x;\r\n\t\t\t\tmodel.controlPointPreviousY = controlPoints.previous.y;\r\n\t\t\t\tmodel.controlPointNextX = controlPoints.next.x;\r\n\t\t\t\tmodel.controlPointNextY = controlPoints.next.y;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (chart.options.elements.line.capBezierPoints) {\r\n\t\t\tfor (i = 0, ilen = points.length; i < ilen; ++i) {\r\n\t\t\t\tmodel = points[i]._model;\r\n\t\t\t\tif (isPointInArea(model, area)) {\r\n\t\t\t\t\tif (i > 0 && isPointInArea(points[i - 1]._model, area)) {\r\n\t\t\t\t\t\tmodel.controlPointPreviousX = capControlPoint(model.controlPointPreviousX, area.left, area.right);\r\n\t\t\t\t\t\tmodel.controlPointPreviousY = capControlPoint(model.controlPointPreviousY, area.top, area.bottom);\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (i < points.length - 1 && isPointInArea(points[i + 1]._model, area)) {\r\n\t\t\t\t\t\tmodel.controlPointNextX = capControlPoint(model.controlPointNextX, area.left, area.right);\r\n\t\t\t\t\t\tmodel.controlPointNextY = capControlPoint(model.controlPointNextY, area.top, area.bottom);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t},\r\n\r\n\tdraw: function() {\r\n\t\tvar me = this;\r\n\t\tvar chart = me.chart;\r\n\t\tvar meta = me.getMeta();\r\n\t\tvar points = meta.data || [];\r\n\t\tvar area = chart.chartArea;\r\n\t\tvar canvas = chart.canvas;\r\n\t\tvar i = 0;\r\n\t\tvar ilen = points.length;\r\n\t\tvar clip;\r\n\r\n\t\tif (me._showLine) {\r\n\t\t\tclip = meta.dataset._model.clip;\r\n\r\n\t\t\thelpers$1.canvas.clipArea(chart.ctx, {\r\n\t\t\t\tleft: clip.left === false ? 0 : area.left - clip.left,\r\n\t\t\t\tright: clip.right === false ? canvas.width : area.right + clip.right,\r\n\t\t\t\ttop: clip.top === false ? 0 : area.top - clip.top,\r\n\t\t\t\tbottom: clip.bottom === false ? canvas.height : area.bottom + clip.bottom\r\n\t\t\t});\r\n\r\n\t\t\tmeta.dataset.draw();\r\n\r\n\t\t\thelpers$1.canvas.unclipArea(chart.ctx);\r\n\t\t}\r\n\r\n\t\t// Draw the points\r\n\t\tfor (; i < ilen; ++i) {\r\n\t\t\tpoints[i].draw(area);\r\n\t\t}\r\n\t},\r\n\r\n\t/**\r\n\t * @protected\r\n\t */\r\n\tsetHoverStyle: function(point) {\r\n\t\tvar model = point._model;\r\n\t\tvar options = point._options;\r\n\t\tvar getHoverColor = helpers$1.getHoverColor;\r\n\r\n\t\tpoint.$previousStyle = {\r\n\t\t\tbackgroundColor: model.backgroundColor,\r\n\t\t\tborderColor: model.borderColor,\r\n\t\t\tborderWidth: model.borderWidth,\r\n\t\t\tradius: model.radius\r\n\t\t};\r\n\r\n\t\tmodel.backgroundColor = valueOrDefault$6(options.hoverBackgroundColor, getHoverColor(options.backgroundColor));\r\n\t\tmodel.borderColor = valueOrDefault$6(options.hoverBorderColor, getHoverColor(options.borderColor));\r\n\t\tmodel.borderWidth = valueOrDefault$6(options.hoverBorderWidth, options.borderWidth);\r\n\t\tmodel.radius = valueOrDefault$6(options.hoverRadius, options.radius);\r\n\t},\r\n});\n\nvar resolve$3 = helpers$1.options.resolve;\r\n\r\ncore_defaults._set('polarArea', {\r\n\tscale: {\r\n\t\ttype: 'radialLinear',\r\n\t\tangleLines: {\r\n\t\t\tdisplay: false\r\n\t\t},\r\n\t\tgridLines: {\r\n\t\t\tcircular: true\r\n\t\t},\r\n\t\tpointLabels: {\r\n\t\t\tdisplay: false\r\n\t\t},\r\n\t\tticks: {\r\n\t\t\tbeginAtZero: true\r\n\t\t}\r\n\t},\r\n\r\n\t// Boolean - Whether to animate the rotation of the chart\r\n\tanimation: {\r\n\t\tanimateRotate: true,\r\n\t\tanimateScale: true\r\n\t},\r\n\r\n\tstartAngle: -0.5 * Math.PI,\r\n\tlegendCallback: function(chart) {\r\n\t\tvar list = document.createElement('ul');\r\n\t\tvar data = chart.data;\r\n\t\tvar datasets = data.datasets;\r\n\t\tvar labels = data.labels;\r\n\t\tvar i, ilen, listItem, listItemSpan;\r\n\r\n\t\tlist.setAttribute('class', chart.id + '-legend');\r\n\t\tif (datasets.length) {\r\n\t\t\tfor (i = 0, ilen = datasets[0].data.length; i < ilen; ++i) {\r\n\t\t\t\tlistItem = list.appendChild(document.createElement('li'));\r\n\t\t\t\tlistItemSpan = listItem.appendChild(document.createElement('span'));\r\n\t\t\t\tlistItemSpan.style.backgroundColor = datasets[0].backgroundColor[i];\r\n\t\t\t\tif (labels[i]) {\r\n\t\t\t\t\tlistItem.appendChild(document.createTextNode(labels[i]));\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn list.outerHTML;\r\n\t},\r\n\tlegend: {\r\n\t\tlabels: {\r\n\t\t\tgenerateLabels: function(chart) {\r\n\t\t\t\tvar data = chart.data;\r\n\t\t\t\tif (data.labels.length && data.datasets.length) {\r\n\t\t\t\t\treturn data.labels.map(function(label, i) {\r\n\t\t\t\t\t\tvar meta = chart.getDatasetMeta(0);\r\n\t\t\t\t\t\tvar style = meta.controller.getStyle(i);\r\n\r\n\t\t\t\t\t\treturn {\r\n\t\t\t\t\t\t\ttext: label,\r\n\t\t\t\t\t\t\tfillStyle: style.backgroundColor,\r\n\t\t\t\t\t\t\tstrokeStyle: style.borderColor,\r\n\t\t\t\t\t\t\tlineWidth: style.borderWidth,\r\n\t\t\t\t\t\t\thidden: isNaN(data.datasets[0].data[i]) || meta.data[i].hidden,\r\n\r\n\t\t\t\t\t\t\t// Extra data used for toggling the correct item\r\n\t\t\t\t\t\t\tindex: i\r\n\t\t\t\t\t\t};\r\n\t\t\t\t\t});\r\n\t\t\t\t}\r\n\t\t\t\treturn [];\r\n\t\t\t}\r\n\t\t},\r\n\r\n\t\tonClick: function(e, legendItem) {\r\n\t\t\tvar index = legendItem.index;\r\n\t\t\tvar chart = this.chart;\r\n\t\t\tvar i, ilen, meta;\r\n\r\n\t\t\tfor (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) {\r\n\t\t\t\tmeta = chart.getDatasetMeta(i);\r\n\t\t\t\tmeta.data[index].hidden = !meta.data[index].hidden;\r\n\t\t\t}\r\n\r\n\t\t\tchart.update();\r\n\t\t}\r\n\t},\r\n\r\n\t// Need to override these to give a nice default\r\n\ttooltips: {\r\n\t\tcallbacks: {\r\n\t\t\ttitle: function() {\r\n\t\t\t\treturn '';\r\n\t\t\t},\r\n\t\t\tlabel: function(item, data) {\r\n\t\t\t\treturn data.labels[item.index] + ': ' + item.yLabel;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n});\r\n\r\nvar controller_polarArea = core_datasetController.extend({\r\n\r\n\tdataElementType: elements.Arc,\r\n\r\n\tlinkScales: helpers$1.noop,\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_dataElementOptions: [\r\n\t\t'backgroundColor',\r\n\t\t'borderColor',\r\n\t\t'borderWidth',\r\n\t\t'borderAlign',\r\n\t\t'hoverBackgroundColor',\r\n\t\t'hoverBorderColor',\r\n\t\t'hoverBorderWidth',\r\n\t],\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_getIndexScaleId: function() {\r\n\t\treturn this.chart.scale.id;\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_getValueScaleId: function() {\r\n\t\treturn this.chart.scale.id;\r\n\t},\r\n\r\n\tupdate: function(reset) {\r\n\t\tvar me = this;\r\n\t\tvar dataset = me.getDataset();\r\n\t\tvar meta = me.getMeta();\r\n\t\tvar start = me.chart.options.startAngle || 0;\r\n\t\tvar starts = me._starts = [];\r\n\t\tvar angles = me._angles = [];\r\n\t\tvar arcs = meta.data;\r\n\t\tvar i, ilen, angle;\r\n\r\n\t\tme._updateRadius();\r\n\r\n\t\tmeta.count = me.countVisibleElements();\r\n\r\n\t\tfor (i = 0, ilen = dataset.data.length; i < ilen; i++) {\r\n\t\t\tstarts[i] = start;\r\n\t\t\tangle = me._computeAngle(i);\r\n\t\t\tangles[i] = angle;\r\n\t\t\tstart += angle;\r\n\t\t}\r\n\r\n\t\tfor (i = 0, ilen = arcs.length; i < ilen; ++i) {\r\n\t\t\tarcs[i]._options = me._resolveDataElementOptions(arcs[i], i);\r\n\t\t\tme.updateElement(arcs[i], i, reset);\r\n\t\t}\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_updateRadius: function() {\r\n\t\tvar me = this;\r\n\t\tvar chart = me.chart;\r\n\t\tvar chartArea = chart.chartArea;\r\n\t\tvar opts = chart.options;\r\n\t\tvar minSize = Math.min(chartArea.right - chartArea.left, chartArea.bottom - chartArea.top);\r\n\r\n\t\tchart.outerRadius = Math.max(minSize / 2, 0);\r\n\t\tchart.innerRadius = Math.max(opts.cutoutPercentage ? (chart.outerRadius / 100) * (opts.cutoutPercentage) : 1, 0);\r\n\t\tchart.radiusLength = (chart.outerRadius - chart.innerRadius) / chart.getVisibleDatasetCount();\r\n\r\n\t\tme.outerRadius = chart.outerRadius - (chart.radiusLength * me.index);\r\n\t\tme.innerRadius = me.outerRadius - chart.radiusLength;\r\n\t},\r\n\r\n\tupdateElement: function(arc, index, reset) {\r\n\t\tvar me = this;\r\n\t\tvar chart = me.chart;\r\n\t\tvar dataset = me.getDataset();\r\n\t\tvar opts = chart.options;\r\n\t\tvar animationOpts = opts.animation;\r\n\t\tvar scale = chart.scale;\r\n\t\tvar labels = chart.data.labels;\r\n\r\n\t\tvar centerX = scale.xCenter;\r\n\t\tvar centerY = scale.yCenter;\r\n\r\n\t\t// var negHalfPI = -0.5 * Math.PI;\r\n\t\tvar datasetStartAngle = opts.startAngle;\r\n\t\tvar distance = arc.hidden ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]);\r\n\t\tvar startAngle = me._starts[index];\r\n\t\tvar endAngle = startAngle + (arc.hidden ? 0 : me._angles[index]);\r\n\r\n\t\tvar resetRadius = animationOpts.animateScale ? 0 : scale.getDistanceFromCenterForValue(dataset.data[index]);\r\n\t\tvar options = arc._options || {};\r\n\r\n\t\thelpers$1.extend(arc, {\r\n\t\t\t// Utility\r\n\t\t\t_datasetIndex: me.index,\r\n\t\t\t_index: index,\r\n\t\t\t_scale: scale,\r\n\r\n\t\t\t// Desired view properties\r\n\t\t\t_model: {\r\n\t\t\t\tbackgroundColor: options.backgroundColor,\r\n\t\t\t\tborderColor: options.borderColor,\r\n\t\t\t\tborderWidth: options.borderWidth,\r\n\t\t\t\tborderAlign: options.borderAlign,\r\n\t\t\t\tx: centerX,\r\n\t\t\t\ty: centerY,\r\n\t\t\t\tinnerRadius: 0,\r\n\t\t\t\touterRadius: reset ? resetRadius : distance,\r\n\t\t\t\tstartAngle: reset && animationOpts.animateRotate ? datasetStartAngle : startAngle,\r\n\t\t\t\tendAngle: reset && animationOpts.animateRotate ? datasetStartAngle : endAngle,\r\n\t\t\t\tlabel: helpers$1.valueAtIndexOrDefault(labels, index, labels[index])\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tarc.pivot();\r\n\t},\r\n\r\n\tcountVisibleElements: function() {\r\n\t\tvar dataset = this.getDataset();\r\n\t\tvar meta = this.getMeta();\r\n\t\tvar count = 0;\r\n\r\n\t\thelpers$1.each(meta.data, function(element, index) {\r\n\t\t\tif (!isNaN(dataset.data[index]) && !element.hidden) {\r\n\t\t\t\tcount++;\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\treturn count;\r\n\t},\r\n\r\n\t/**\r\n\t * @protected\r\n\t */\r\n\tsetHoverStyle: function(arc) {\r\n\t\tvar model = arc._model;\r\n\t\tvar options = arc._options;\r\n\t\tvar getHoverColor = helpers$1.getHoverColor;\r\n\t\tvar valueOrDefault = helpers$1.valueOrDefault;\r\n\r\n\t\tarc.$previousStyle = {\r\n\t\t\tbackgroundColor: model.backgroundColor,\r\n\t\t\tborderColor: model.borderColor,\r\n\t\t\tborderWidth: model.borderWidth,\r\n\t\t};\r\n\r\n\t\tmodel.backgroundColor = valueOrDefault(options.hoverBackgroundColor, getHoverColor(options.backgroundColor));\r\n\t\tmodel.borderColor = valueOrDefault(options.hoverBorderColor, getHoverColor(options.borderColor));\r\n\t\tmodel.borderWidth = valueOrDefault(options.hoverBorderWidth, options.borderWidth);\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_computeAngle: function(index) {\r\n\t\tvar me = this;\r\n\t\tvar count = this.getMeta().count;\r\n\t\tvar dataset = me.getDataset();\r\n\t\tvar meta = me.getMeta();\r\n\r\n\t\tif (isNaN(dataset.data[index]) || meta.data[index].hidden) {\r\n\t\t\treturn 0;\r\n\t\t}\r\n\r\n\t\t// Scriptable options\r\n\t\tvar context = {\r\n\t\t\tchart: me.chart,\r\n\t\t\tdataIndex: index,\r\n\t\t\tdataset: dataset,\r\n\t\t\tdatasetIndex: me.index\r\n\t\t};\r\n\r\n\t\treturn resolve$3([\r\n\t\t\tme.chart.options.elements.arc.angle,\r\n\t\t\t(2 * Math.PI) / count\r\n\t\t], context, index);\r\n\t}\r\n});\n\ncore_defaults._set('pie', helpers$1.clone(core_defaults.doughnut));\r\ncore_defaults._set('pie', {\r\n\tcutoutPercentage: 0\r\n});\r\n\r\n// Pie charts are Doughnut chart with different defaults\r\nvar controller_pie = controller_doughnut;\n\nvar valueOrDefault$7 = helpers$1.valueOrDefault;\r\n\r\ncore_defaults._set('radar', {\r\n\tspanGaps: false,\r\n\tscale: {\r\n\t\ttype: 'radialLinear'\r\n\t},\r\n\telements: {\r\n\t\tline: {\r\n\t\t\tfill: 'start',\r\n\t\t\ttension: 0 // no bezier in radar\r\n\t\t}\r\n\t}\r\n});\r\n\r\nvar controller_radar = core_datasetController.extend({\r\n\tdatasetElementType: elements.Line,\r\n\r\n\tdataElementType: elements.Point,\r\n\r\n\tlinkScales: helpers$1.noop,\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_datasetElementOptions: [\r\n\t\t'backgroundColor',\r\n\t\t'borderWidth',\r\n\t\t'borderColor',\r\n\t\t'borderCapStyle',\r\n\t\t'borderDash',\r\n\t\t'borderDashOffset',\r\n\t\t'borderJoinStyle',\r\n\t\t'fill'\r\n\t],\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_dataElementOptions: {\r\n\t\tbackgroundColor: 'pointBackgroundColor',\r\n\t\tborderColor: 'pointBorderColor',\r\n\t\tborderWidth: 'pointBorderWidth',\r\n\t\thitRadius: 'pointHitRadius',\r\n\t\thoverBackgroundColor: 'pointHoverBackgroundColor',\r\n\t\thoverBorderColor: 'pointHoverBorderColor',\r\n\t\thoverBorderWidth: 'pointHoverBorderWidth',\r\n\t\thoverRadius: 'pointHoverRadius',\r\n\t\tpointStyle: 'pointStyle',\r\n\t\tradius: 'pointRadius',\r\n\t\trotation: 'pointRotation'\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_getIndexScaleId: function() {\r\n\t\treturn this.chart.scale.id;\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_getValueScaleId: function() {\r\n\t\treturn this.chart.scale.id;\r\n\t},\r\n\r\n\tupdate: function(reset) {\r\n\t\tvar me = this;\r\n\t\tvar meta = me.getMeta();\r\n\t\tvar line = meta.dataset;\r\n\t\tvar points = meta.data || [];\r\n\t\tvar scale = me.chart.scale;\r\n\t\tvar config = me._config;\r\n\t\tvar i, ilen;\r\n\r\n\t\t// Compatibility: If the properties are defined with only the old name, use those values\r\n\t\tif (config.tension !== undefined && config.lineTension === undefined) {\r\n\t\t\tconfig.lineTension = config.tension;\r\n\t\t}\r\n\r\n\t\t// Utility\r\n\t\tline._scale = scale;\r\n\t\tline._datasetIndex = me.index;\r\n\t\t// Data\r\n\t\tline._children = points;\r\n\t\tline._loop = true;\r\n\t\t// Model\r\n\t\tline._model = me._resolveDatasetElementOptions(line);\r\n\r\n\t\tline.pivot();\r\n\r\n\t\t// Update Points\r\n\t\tfor (i = 0, ilen = points.length; i < ilen; ++i) {\r\n\t\t\tme.updateElement(points[i], i, reset);\r\n\t\t}\r\n\r\n\t\t// Update bezier control points\r\n\t\tme.updateBezierControlPoints();\r\n\r\n\t\t// Now pivot the point for animation\r\n\t\tfor (i = 0, ilen = points.length; i < ilen; ++i) {\r\n\t\t\tpoints[i].pivot();\r\n\t\t}\r\n\t},\r\n\r\n\tupdateElement: function(point, index, reset) {\r\n\t\tvar me = this;\r\n\t\tvar custom = point.custom || {};\r\n\t\tvar dataset = me.getDataset();\r\n\t\tvar scale = me.chart.scale;\r\n\t\tvar pointPosition = scale.getPointPositionForValue(index, dataset.data[index]);\r\n\t\tvar options = me._resolveDataElementOptions(point, index);\r\n\t\tvar lineModel = me.getMeta().dataset._model;\r\n\t\tvar x = reset ? scale.xCenter : pointPosition.x;\r\n\t\tvar y = reset ? scale.yCenter : pointPosition.y;\r\n\r\n\t\t// Utility\r\n\t\tpoint._scale = scale;\r\n\t\tpoint._options = options;\r\n\t\tpoint._datasetIndex = me.index;\r\n\t\tpoint._index = index;\r\n\r\n\t\t// Desired view properties\r\n\t\tpoint._model = {\r\n\t\t\tx: x, // value not used in dataset scale, but we want a consistent API between scales\r\n\t\t\ty: y,\r\n\t\t\tskip: custom.skip || isNaN(x) || isNaN(y),\r\n\t\t\t// Appearance\r\n\t\t\tradius: options.radius,\r\n\t\t\tpointStyle: options.pointStyle,\r\n\t\t\trotation: options.rotation,\r\n\t\t\tbackgroundColor: options.backgroundColor,\r\n\t\t\tborderColor: options.borderColor,\r\n\t\t\tborderWidth: options.borderWidth,\r\n\t\t\ttension: valueOrDefault$7(custom.tension, lineModel ? lineModel.tension : 0),\r\n\r\n\t\t\t// Tooltip\r\n\t\t\thitRadius: options.hitRadius\r\n\t\t};\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_resolveDatasetElementOptions: function() {\r\n\t\tvar me = this;\r\n\t\tvar config = me._config;\r\n\t\tvar options = me.chart.options;\r\n\t\tvar values = core_datasetController.prototype._resolveDatasetElementOptions.apply(me, arguments);\r\n\r\n\t\tvalues.spanGaps = valueOrDefault$7(config.spanGaps, options.spanGaps);\r\n\t\tvalues.tension = valueOrDefault$7(config.lineTension, options.elements.line.tension);\r\n\r\n\t\treturn values;\r\n\t},\r\n\r\n\tupdateBezierControlPoints: function() {\r\n\t\tvar me = this;\r\n\t\tvar meta = me.getMeta();\r\n\t\tvar area = me.chart.chartArea;\r\n\t\tvar points = meta.data || [];\r\n\t\tvar i, ilen, model, controlPoints;\r\n\r\n\t\t// Only consider points that are drawn in case the spanGaps option is used\r\n\t\tif (meta.dataset._model.spanGaps) {\r\n\t\t\tpoints = points.filter(function(pt) {\r\n\t\t\t\treturn !pt._model.skip;\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tfunction capControlPoint(pt, min, max) {\r\n\t\t\treturn Math.max(Math.min(pt, max), min);\r\n\t\t}\r\n\r\n\t\tfor (i = 0, ilen = points.length; i < ilen; ++i) {\r\n\t\t\tmodel = points[i]._model;\r\n\t\t\tcontrolPoints = helpers$1.splineCurve(\r\n\t\t\t\thelpers$1.previousItem(points, i, true)._model,\r\n\t\t\t\tmodel,\r\n\t\t\t\thelpers$1.nextItem(points, i, true)._model,\r\n\t\t\t\tmodel.tension\r\n\t\t\t);\r\n\r\n\t\t\t// Prevent the bezier going outside of the bounds of the graph\r\n\t\t\tmodel.controlPointPreviousX = capControlPoint(controlPoints.previous.x, area.left, area.right);\r\n\t\t\tmodel.controlPointPreviousY = capControlPoint(controlPoints.previous.y, area.top, area.bottom);\r\n\t\t\tmodel.controlPointNextX = capControlPoint(controlPoints.next.x, area.left, area.right);\r\n\t\t\tmodel.controlPointNextY = capControlPoint(controlPoints.next.y, area.top, area.bottom);\r\n\t\t}\r\n\t},\r\n\r\n\tsetHoverStyle: function(point) {\r\n\t\tvar model = point._model;\r\n\t\tvar options = point._options;\r\n\t\tvar getHoverColor = helpers$1.getHoverColor;\r\n\r\n\t\tpoint.$previousStyle = {\r\n\t\t\tbackgroundColor: model.backgroundColor,\r\n\t\t\tborderColor: model.borderColor,\r\n\t\t\tborderWidth: model.borderWidth,\r\n\t\t\tradius: model.radius\r\n\t\t};\r\n\r\n\t\tmodel.backgroundColor = valueOrDefault$7(options.hoverBackgroundColor, getHoverColor(options.backgroundColor));\r\n\t\tmodel.borderColor = valueOrDefault$7(options.hoverBorderColor, getHoverColor(options.borderColor));\r\n\t\tmodel.borderWidth = valueOrDefault$7(options.hoverBorderWidth, options.borderWidth);\r\n\t\tmodel.radius = valueOrDefault$7(options.hoverRadius, options.radius);\r\n\t}\r\n});\n\ncore_defaults._set('scatter', {\r\n\thover: {\r\n\t\tmode: 'single'\r\n\t},\r\n\r\n\tscales: {\r\n\t\txAxes: [{\r\n\t\t\tid: 'x-axis-1', // need an ID so datasets can reference the scale\r\n\t\t\ttype: 'linear', // scatter should not use a category axis\r\n\t\t\tposition: 'bottom'\r\n\t\t}],\r\n\t\tyAxes: [{\r\n\t\t\tid: 'y-axis-1',\r\n\t\t\ttype: 'linear',\r\n\t\t\tposition: 'left'\r\n\t\t}]\r\n\t},\r\n\r\n\ttooltips: {\r\n\t\tcallbacks: {\r\n\t\t\ttitle: function() {\r\n\t\t\t\treturn ''; // doesn't make sense for scatter since data are formatted as a point\r\n\t\t\t},\r\n\t\t\tlabel: function(item) {\r\n\t\t\t\treturn '(' + item.xLabel + ', ' + item.yLabel + ')';\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n});\r\n\r\ncore_defaults._set('global', {\r\n\tdatasets: {\r\n\t\tscatter: {\r\n\t\t\tshowLine: false\r\n\t\t}\r\n\t}\r\n});\r\n\r\n// Scatter charts use line controllers\r\nvar controller_scatter = controller_line;\n\n// NOTE export a map in which the key represents the controller type, not\r\n// the class, and so must be CamelCase in order to be correctly retrieved\r\n// by the controller in core.controller.js (`controllers[meta.type]`).\r\n\r\nvar controllers = {\r\n\tbar: controller_bar,\r\n\tbubble: controller_bubble,\r\n\tdoughnut: controller_doughnut,\r\n\thorizontalBar: controller_horizontalBar,\r\n\tline: controller_line,\r\n\tpolarArea: controller_polarArea,\r\n\tpie: controller_pie,\r\n\tradar: controller_radar,\r\n\tscatter: controller_scatter\r\n};\n\n/**\r\n * Helper function to get relative position for an event\r\n * @param {Event|IEvent} event - The event to get the position for\r\n * @param {Chart} chart - The chart\r\n * @returns {object} the event position\r\n */\r\nfunction getRelativePosition(e, chart) {\r\n\tif (e.native) {\r\n\t\treturn {\r\n\t\t\tx: e.x,\r\n\t\t\ty: e.y\r\n\t\t};\r\n\t}\r\n\r\n\treturn helpers$1.getRelativePosition(e, chart);\r\n}\r\n\r\n/**\r\n * Helper function to traverse all of the visible elements in the chart\r\n * @param {Chart} chart - the chart\r\n * @param {function} handler - the callback to execute for each visible item\r\n */\r\nfunction parseVisibleItems(chart, handler) {\r\n\tvar metasets = chart._getSortedVisibleDatasetMetas();\r\n\tvar metadata, i, j, ilen, jlen, element;\r\n\r\n\tfor (i = 0, ilen = metasets.length; i < ilen; ++i) {\r\n\t\tmetadata = metasets[i].data;\r\n\t\tfor (j = 0, jlen = metadata.length; j < jlen; ++j) {\r\n\t\t\telement = metadata[j];\r\n\t\t\tif (!element._view.skip) {\r\n\t\t\t\thandler(element);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n}\r\n\r\n/**\r\n * Helper function to get the items that intersect the event position\r\n * @param {ChartElement[]} items - elements to filter\r\n * @param {object} position - the point to be nearest to\r\n * @return {ChartElement[]} the nearest items\r\n */\r\nfunction getIntersectItems(chart, position) {\r\n\tvar elements = [];\r\n\r\n\tparseVisibleItems(chart, function(element) {\r\n\t\tif (element.inRange(position.x, position.y)) {\r\n\t\t\telements.push(element);\r\n\t\t}\r\n\t});\r\n\r\n\treturn elements;\r\n}\r\n\r\n/**\r\n * Helper function to get the items nearest to the event position considering all visible items in teh chart\r\n * @param {Chart} chart - the chart to look at elements from\r\n * @param {object} position - the point to be nearest to\r\n * @param {boolean} intersect - if true, only consider items that intersect the position\r\n * @param {function} distanceMetric - function to provide the distance between points\r\n * @return {ChartElement[]} the nearest items\r\n */\r\nfunction getNearestItems(chart, position, intersect, distanceMetric) {\r\n\tvar minDistance = Number.POSITIVE_INFINITY;\r\n\tvar nearestItems = [];\r\n\r\n\tparseVisibleItems(chart, function(element) {\r\n\t\tif (intersect && !element.inRange(position.x, position.y)) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tvar center = element.getCenterPoint();\r\n\t\tvar distance = distanceMetric(position, center);\r\n\t\tif (distance < minDistance) {\r\n\t\t\tnearestItems = [element];\r\n\t\t\tminDistance = distance;\r\n\t\t} else if (distance === minDistance) {\r\n\t\t\t// Can have multiple items at the same distance in which case we sort by size\r\n\t\t\tnearestItems.push(element);\r\n\t\t}\r\n\t});\r\n\r\n\treturn nearestItems;\r\n}\r\n\r\n/**\r\n * Get a distance metric function for two points based on the\r\n * axis mode setting\r\n * @param {string} axis - the axis mode. x|y|xy\r\n */\r\nfunction getDistanceMetricForAxis(axis) {\r\n\tvar useX = axis.indexOf('x') !== -1;\r\n\tvar useY = axis.indexOf('y') !== -1;\r\n\r\n\treturn function(pt1, pt2) {\r\n\t\tvar deltaX = useX ? Math.abs(pt1.x - pt2.x) : 0;\r\n\t\tvar deltaY = useY ? Math.abs(pt1.y - pt2.y) : 0;\r\n\t\treturn Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2));\r\n\t};\r\n}\r\n\r\nfunction indexMode(chart, e, options) {\r\n\tvar position = getRelativePosition(e, chart);\r\n\t// Default axis for index mode is 'x' to match old behaviour\r\n\toptions.axis = options.axis || 'x';\r\n\tvar distanceMetric = getDistanceMetricForAxis(options.axis);\r\n\tvar items = options.intersect ? getIntersectItems(chart, position) : getNearestItems(chart, position, false, distanceMetric);\r\n\tvar elements = [];\r\n\r\n\tif (!items.length) {\r\n\t\treturn [];\r\n\t}\r\n\r\n\tchart._getSortedVisibleDatasetMetas().forEach(function(meta) {\r\n\t\tvar element = meta.data[items[0]._index];\r\n\r\n\t\t// don't count items that are skipped (null data)\r\n\t\tif (element && !element._view.skip) {\r\n\t\t\telements.push(element);\r\n\t\t}\r\n\t});\r\n\r\n\treturn elements;\r\n}\r\n\r\n/**\r\n * @interface IInteractionOptions\r\n */\r\n/**\r\n * If true, only consider items that intersect the point\r\n * @name IInterfaceOptions#boolean\r\n * @type Boolean\r\n */\r\n\r\n/**\r\n * Contains interaction related functions\r\n * @namespace Chart.Interaction\r\n */\r\nvar core_interaction = {\r\n\t// Helper function for different modes\r\n\tmodes: {\r\n\t\tsingle: function(chart, e) {\r\n\t\t\tvar position = getRelativePosition(e, chart);\r\n\t\t\tvar elements = [];\r\n\r\n\t\t\tparseVisibleItems(chart, function(element) {\r\n\t\t\t\tif (element.inRange(position.x, position.y)) {\r\n\t\t\t\t\telements.push(element);\r\n\t\t\t\t\treturn elements;\r\n\t\t\t\t}\r\n\t\t\t});\r\n\r\n\t\t\treturn elements.slice(0, 1);\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * @function Chart.Interaction.modes.label\r\n\t\t * @deprecated since version 2.4.0\r\n\t\t * @todo remove at version 3\r\n\t\t * @private\r\n\t\t */\r\n\t\tlabel: indexMode,\r\n\r\n\t\t/**\r\n\t\t * Returns items at the same index. If the options.intersect parameter is true, we only return items if we intersect something\r\n\t\t * If the options.intersect mode is false, we find the nearest item and return the items at the same index as that item\r\n\t\t * @function Chart.Interaction.modes.index\r\n\t\t * @since v2.4.0\r\n\t\t * @param {Chart} chart - the chart we are returning items from\r\n\t\t * @param {Event} e - the event we are find things at\r\n\t\t * @param {IInteractionOptions} options - options to use during interaction\r\n\t\t * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned\r\n\t\t */\r\n\t\tindex: indexMode,\r\n\r\n\t\t/**\r\n\t\t * Returns items in the same dataset. If the options.intersect parameter is true, we only return items if we intersect something\r\n\t\t * If the options.intersect is false, we find the nearest item and return the items in that dataset\r\n\t\t * @function Chart.Interaction.modes.dataset\r\n\t\t * @param {Chart} chart - the chart we are returning items from\r\n\t\t * @param {Event} e - the event we are find things at\r\n\t\t * @param {IInteractionOptions} options - options to use during interaction\r\n\t\t * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned\r\n\t\t */\r\n\t\tdataset: function(chart, e, options) {\r\n\t\t\tvar position = getRelativePosition(e, chart);\r\n\t\t\toptions.axis = options.axis || 'xy';\r\n\t\t\tvar distanceMetric = getDistanceMetricForAxis(options.axis);\r\n\t\t\tvar items = options.intersect ? getIntersectItems(chart, position) : getNearestItems(chart, position, false, distanceMetric);\r\n\r\n\t\t\tif (items.length > 0) {\r\n\t\t\t\titems = chart.getDatasetMeta(items[0]._datasetIndex).data;\r\n\t\t\t}\r\n\r\n\t\t\treturn items;\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * @function Chart.Interaction.modes.x-axis\r\n\t\t * @deprecated since version 2.4.0. Use index mode and intersect == true\r\n\t\t * @todo remove at version 3\r\n\t\t * @private\r\n\t\t */\r\n\t\t'x-axis': function(chart, e) {\r\n\t\t\treturn indexMode(chart, e, {intersect: false});\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Point mode returns all elements that hit test based on the event position\r\n\t\t * of the event\r\n\t\t * @function Chart.Interaction.modes.intersect\r\n\t\t * @param {Chart} chart - the chart we are returning items from\r\n\t\t * @param {Event} e - the event we are find things at\r\n\t\t * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned\r\n\t\t */\r\n\t\tpoint: function(chart, e) {\r\n\t\t\tvar position = getRelativePosition(e, chart);\r\n\t\t\treturn getIntersectItems(chart, position);\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * nearest mode returns the element closest to the point\r\n\t\t * @function Chart.Interaction.modes.intersect\r\n\t\t * @param {Chart} chart - the chart we are returning items from\r\n\t\t * @param {Event} e - the event we are find things at\r\n\t\t * @param {IInteractionOptions} options - options to use\r\n\t\t * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned\r\n\t\t */\r\n\t\tnearest: function(chart, e, options) {\r\n\t\t\tvar position = getRelativePosition(e, chart);\r\n\t\t\toptions.axis = options.axis || 'xy';\r\n\t\t\tvar distanceMetric = getDistanceMetricForAxis(options.axis);\r\n\t\t\treturn getNearestItems(chart, position, options.intersect, distanceMetric);\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * x mode returns the elements that hit-test at the current x coordinate\r\n\t\t * @function Chart.Interaction.modes.x\r\n\t\t * @param {Chart} chart - the chart we are returning items from\r\n\t\t * @param {Event} e - the event we are find things at\r\n\t\t * @param {IInteractionOptions} options - options to use\r\n\t\t * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned\r\n\t\t */\r\n\t\tx: function(chart, e, options) {\r\n\t\t\tvar position = getRelativePosition(e, chart);\r\n\t\t\tvar items = [];\r\n\t\t\tvar intersectsItem = false;\r\n\r\n\t\t\tparseVisibleItems(chart, function(element) {\r\n\t\t\t\tif (element.inXRange(position.x)) {\r\n\t\t\t\t\titems.push(element);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (element.inRange(position.x, position.y)) {\r\n\t\t\t\t\tintersectsItem = true;\r\n\t\t\t\t}\r\n\t\t\t});\r\n\r\n\t\t\t// If we want to trigger on an intersect and we don't have any items\r\n\t\t\t// that intersect the position, return nothing\r\n\t\t\tif (options.intersect && !intersectsItem) {\r\n\t\t\t\titems = [];\r\n\t\t\t}\r\n\t\t\treturn items;\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * y mode returns the elements that hit-test at the current y coordinate\r\n\t\t * @function Chart.Interaction.modes.y\r\n\t\t * @param {Chart} chart - the chart we are returning items from\r\n\t\t * @param {Event} e - the event we are find things at\r\n\t\t * @param {IInteractionOptions} options - options to use\r\n\t\t * @return {Chart.Element[]} Array of elements that are under the point. If none are found, an empty array is returned\r\n\t\t */\r\n\t\ty: function(chart, e, options) {\r\n\t\t\tvar position = getRelativePosition(e, chart);\r\n\t\t\tvar items = [];\r\n\t\t\tvar intersectsItem = false;\r\n\r\n\t\t\tparseVisibleItems(chart, function(element) {\r\n\t\t\t\tif (element.inYRange(position.y)) {\r\n\t\t\t\t\titems.push(element);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (element.inRange(position.x, position.y)) {\r\n\t\t\t\t\tintersectsItem = true;\r\n\t\t\t\t}\r\n\t\t\t});\r\n\r\n\t\t\t// If we want to trigger on an intersect and we don't have any items\r\n\t\t\t// that intersect the position, return nothing\r\n\t\t\tif (options.intersect && !intersectsItem) {\r\n\t\t\t\titems = [];\r\n\t\t\t}\r\n\t\t\treturn items;\r\n\t\t}\r\n\t}\r\n};\n\nvar extend = helpers$1.extend;\r\n\r\nfunction filterByPosition(array, position) {\r\n\treturn helpers$1.where(array, function(v) {\r\n\t\treturn v.pos === position;\r\n\t});\r\n}\r\n\r\nfunction sortByWeight(array, reverse) {\r\n\treturn array.sort(function(a, b) {\r\n\t\tvar v0 = reverse ? b : a;\r\n\t\tvar v1 = reverse ? a : b;\r\n\t\treturn v0.weight === v1.weight ?\r\n\t\t\tv0.index - v1.index :\r\n\t\t\tv0.weight - v1.weight;\r\n\t});\r\n}\r\n\r\nfunction wrapBoxes(boxes) {\r\n\tvar layoutBoxes = [];\r\n\tvar i, ilen, box;\r\n\r\n\tfor (i = 0, ilen = (boxes || []).length; i < ilen; ++i) {\r\n\t\tbox = boxes[i];\r\n\t\tlayoutBoxes.push({\r\n\t\t\tindex: i,\r\n\t\t\tbox: box,\r\n\t\t\tpos: box.position,\r\n\t\t\thorizontal: box.isHorizontal(),\r\n\t\t\tweight: box.weight\r\n\t\t});\r\n\t}\r\n\treturn layoutBoxes;\r\n}\r\n\r\nfunction setLayoutDims(layouts, params) {\r\n\tvar i, ilen, layout;\r\n\tfor (i = 0, ilen = layouts.length; i < ilen; ++i) {\r\n\t\tlayout = layouts[i];\r\n\t\t// store width used instead of chartArea.w in fitBoxes\r\n\t\tlayout.width = layout.horizontal\r\n\t\t\t? layout.box.fullWidth && params.availableWidth\r\n\t\t\t: params.vBoxMaxWidth;\r\n\t\t// store height used instead of chartArea.h in fitBoxes\r\n\t\tlayout.height = layout.horizontal && params.hBoxMaxHeight;\r\n\t}\r\n}\r\n\r\nfunction buildLayoutBoxes(boxes) {\r\n\tvar layoutBoxes = wrapBoxes(boxes);\r\n\tvar left = sortByWeight(filterByPosition(layoutBoxes, 'left'), true);\r\n\tvar right = sortByWeight(filterByPosition(layoutBoxes, 'right'));\r\n\tvar top = sortByWeight(filterByPosition(layoutBoxes, 'top'), true);\r\n\tvar bottom = sortByWeight(filterByPosition(layoutBoxes, 'bottom'));\r\n\r\n\treturn {\r\n\t\tleftAndTop: left.concat(top),\r\n\t\trightAndBottom: right.concat(bottom),\r\n\t\tchartArea: filterByPosition(layoutBoxes, 'chartArea'),\r\n\t\tvertical: left.concat(right),\r\n\t\thorizontal: top.concat(bottom)\r\n\t};\r\n}\r\n\r\nfunction getCombinedMax(maxPadding, chartArea, a, b) {\r\n\treturn Math.max(maxPadding[a], chartArea[a]) + Math.max(maxPadding[b], chartArea[b]);\r\n}\r\n\r\nfunction updateDims(chartArea, params, layout) {\r\n\tvar box = layout.box;\r\n\tvar maxPadding = chartArea.maxPadding;\r\n\tvar newWidth, newHeight;\r\n\r\n\tif (layout.size) {\r\n\t\t// this layout was already counted for, lets first reduce old size\r\n\t\tchartArea[layout.pos] -= layout.size;\r\n\t}\r\n\tlayout.size = layout.horizontal ? box.height : box.width;\r\n\tchartArea[layout.pos] += layout.size;\r\n\r\n\tif (box.getPadding) {\r\n\t\tvar boxPadding = box.getPadding();\r\n\t\tmaxPadding.top = Math.max(maxPadding.top, boxPadding.top);\r\n\t\tmaxPadding.left = Math.max(maxPadding.left, boxPadding.left);\r\n\t\tmaxPadding.bottom = Math.max(maxPadding.bottom, boxPadding.bottom);\r\n\t\tmaxPadding.right = Math.max(maxPadding.right, boxPadding.right);\r\n\t}\r\n\r\n\tnewWidth = params.outerWidth - getCombinedMax(maxPadding, chartArea, 'left', 'right');\r\n\tnewHeight = params.outerHeight - getCombinedMax(maxPadding, chartArea, 'top', 'bottom');\r\n\r\n\tif (newWidth !== chartArea.w || newHeight !== chartArea.h) {\r\n\t\tchartArea.w = newWidth;\r\n\t\tchartArea.h = newHeight;\r\n\r\n\t\t// return true if chart area changed in layout's direction\r\n\t\tvar sizes = layout.horizontal ? [newWidth, chartArea.w] : [newHeight, chartArea.h];\r\n\t\treturn sizes[0] !== sizes[1] && (!isNaN(sizes[0]) || !isNaN(sizes[1]));\r\n\t}\r\n}\r\n\r\nfunction handleMaxPadding(chartArea) {\r\n\tvar maxPadding = chartArea.maxPadding;\r\n\r\n\tfunction updatePos(pos) {\r\n\t\tvar change = Math.max(maxPadding[pos] - chartArea[pos], 0);\r\n\t\tchartArea[pos] += change;\r\n\t\treturn change;\r\n\t}\r\n\tchartArea.y += updatePos('top');\r\n\tchartArea.x += updatePos('left');\r\n\tupdatePos('right');\r\n\tupdatePos('bottom');\r\n}\r\n\r\nfunction getMargins(horizontal, chartArea) {\r\n\tvar maxPadding = chartArea.maxPadding;\r\n\r\n\tfunction marginForPositions(positions) {\r\n\t\tvar margin = {left: 0, top: 0, right: 0, bottom: 0};\r\n\t\tpositions.forEach(function(pos) {\r\n\t\t\tmargin[pos] = Math.max(chartArea[pos], maxPadding[pos]);\r\n\t\t});\r\n\t\treturn margin;\r\n\t}\r\n\r\n\treturn horizontal\r\n\t\t? marginForPositions(['left', 'right'])\r\n\t\t: marginForPositions(['top', 'bottom']);\r\n}\r\n\r\nfunction fitBoxes(boxes, chartArea, params) {\r\n\tvar refitBoxes = [];\r\n\tvar i, ilen, layout, box, refit, changed;\r\n\r\n\tfor (i = 0, ilen = boxes.length; i < ilen; ++i) {\r\n\t\tlayout = boxes[i];\r\n\t\tbox = layout.box;\r\n\r\n\t\tbox.update(\r\n\t\t\tlayout.width || chartArea.w,\r\n\t\t\tlayout.height || chartArea.h,\r\n\t\t\tgetMargins(layout.horizontal, chartArea)\r\n\t\t);\r\n\t\tif (updateDims(chartArea, params, layout)) {\r\n\t\t\tchanged = true;\r\n\t\t\tif (refitBoxes.length) {\r\n\t\t\t\t// Dimensions changed and there were non full width boxes before this\r\n\t\t\t\t// -> we have to refit those\r\n\t\t\t\trefit = true;\r\n\t\t\t}\r\n\t\t}\r\n\t\tif (!box.fullWidth) { // fullWidth boxes don't need to be re-fitted in any case\r\n\t\t\trefitBoxes.push(layout);\r\n\t\t}\r\n\t}\r\n\r\n\treturn refit ? fitBoxes(refitBoxes, chartArea, params) || changed : changed;\r\n}\r\n\r\nfunction placeBoxes(boxes, chartArea, params) {\r\n\tvar userPadding = params.padding;\r\n\tvar x = chartArea.x;\r\n\tvar y = chartArea.y;\r\n\tvar i, ilen, layout, box;\r\n\r\n\tfor (i = 0, ilen = boxes.length; i < ilen; ++i) {\r\n\t\tlayout = boxes[i];\r\n\t\tbox = layout.box;\r\n\t\tif (layout.horizontal) {\r\n\t\t\tbox.left = box.fullWidth ? userPadding.left : chartArea.left;\r\n\t\t\tbox.right = box.fullWidth ? params.outerWidth - userPadding.right : chartArea.left + chartArea.w;\r\n\t\t\tbox.top = y;\r\n\t\t\tbox.bottom = y + box.height;\r\n\t\t\tbox.width = box.right - box.left;\r\n\t\t\ty = box.bottom;\r\n\t\t} else {\r\n\t\t\tbox.left = x;\r\n\t\t\tbox.right = x + box.width;\r\n\t\t\tbox.top = chartArea.top;\r\n\t\t\tbox.bottom = chartArea.top + chartArea.h;\r\n\t\t\tbox.height = box.bottom - box.top;\r\n\t\t\tx = box.right;\r\n\t\t}\r\n\t}\r\n\r\n\tchartArea.x = x;\r\n\tchartArea.y = y;\r\n}\r\n\r\ncore_defaults._set('global', {\r\n\tlayout: {\r\n\t\tpadding: {\r\n\t\t\ttop: 0,\r\n\t\t\tright: 0,\r\n\t\t\tbottom: 0,\r\n\t\t\tleft: 0\r\n\t\t}\r\n\t}\r\n});\r\n\r\n/**\r\n * @interface ILayoutItem\r\n * @prop {string} position - The position of the item in the chart layout. Possible values are\r\n * 'left', 'top', 'right', 'bottom', and 'chartArea'\r\n * @prop {number} weight - The weight used to sort the item. Higher weights are further away from the chart area\r\n * @prop {boolean} fullWidth - if true, and the item is horizontal, then push vertical boxes down\r\n * @prop {function} isHorizontal - returns true if the layout item is horizontal (ie. top or bottom)\r\n * @prop {function} update - Takes two parameters: width and height. Returns size of item\r\n * @prop {function} getPadding - Returns an object with padding on the edges\r\n * @prop {number} width - Width of item. Must be valid after update()\r\n * @prop {number} height - Height of item. Must be valid after update()\r\n * @prop {number} left - Left edge of the item. Set by layout system and cannot be used in update\r\n * @prop {number} top - Top edge of the item. Set by layout system and cannot be used in update\r\n * @prop {number} right - Right edge of the item. Set by layout system and cannot be used in update\r\n * @prop {number} bottom - Bottom edge of the item. Set by layout system and cannot be used in update\r\n */\r\n\r\n// The layout service is very self explanatory. It's responsible for the layout within a chart.\r\n// Scales, Legends and Plugins all rely on the layout service and can easily register to be placed anywhere they need\r\n// It is this service's responsibility of carrying out that layout.\r\nvar core_layouts = {\r\n\tdefaults: {},\r\n\r\n\t/**\r\n\t * Register a box to a chart.\r\n\t * A box is simply a reference to an object that requires layout. eg. Scales, Legend, Title.\r\n\t * @param {Chart} chart - the chart to use\r\n\t * @param {ILayoutItem} item - the item to add to be layed out\r\n\t */\r\n\taddBox: function(chart, item) {\r\n\t\tif (!chart.boxes) {\r\n\t\t\tchart.boxes = [];\r\n\t\t}\r\n\r\n\t\t// initialize item with default values\r\n\t\titem.fullWidth = item.fullWidth || false;\r\n\t\titem.position = item.position || 'top';\r\n\t\titem.weight = item.weight || 0;\r\n\t\titem._layers = item._layers || function() {\r\n\t\t\treturn [{\r\n\t\t\t\tz: 0,\r\n\t\t\t\tdraw: function() {\r\n\t\t\t\t\titem.draw.apply(item, arguments);\r\n\t\t\t\t}\r\n\t\t\t}];\r\n\t\t};\r\n\r\n\t\tchart.boxes.push(item);\r\n\t},\r\n\r\n\t/**\r\n\t * Remove a layoutItem from a chart\r\n\t * @param {Chart} chart - the chart to remove the box from\r\n\t * @param {ILayoutItem} layoutItem - the item to remove from the layout\r\n\t */\r\n\tremoveBox: function(chart, layoutItem) {\r\n\t\tvar index = chart.boxes ? chart.boxes.indexOf(layoutItem) : -1;\r\n\t\tif (index !== -1) {\r\n\t\t\tchart.boxes.splice(index, 1);\r\n\t\t}\r\n\t},\r\n\r\n\t/**\r\n\t * Sets (or updates) options on the given `item`.\r\n\t * @param {Chart} chart - the chart in which the item lives (or will be added to)\r\n\t * @param {ILayoutItem} item - the item to configure with the given options\r\n\t * @param {object} options - the new item options.\r\n\t */\r\n\tconfigure: function(chart, item, options) {\r\n\t\tvar props = ['fullWidth', 'position', 'weight'];\r\n\t\tvar ilen = props.length;\r\n\t\tvar i = 0;\r\n\t\tvar prop;\r\n\r\n\t\tfor (; i < ilen; ++i) {\r\n\t\t\tprop = props[i];\r\n\t\t\tif (options.hasOwnProperty(prop)) {\r\n\t\t\t\titem[prop] = options[prop];\r\n\t\t\t}\r\n\t\t}\r\n\t},\r\n\r\n\t/**\r\n\t * Fits boxes of the given chart into the given size by having each box measure itself\r\n\t * then running a fitting algorithm\r\n\t * @param {Chart} chart - the chart\r\n\t * @param {number} width - the width to fit into\r\n\t * @param {number} height - the height to fit into\r\n\t */\r\n\tupdate: function(chart, width, height) {\r\n\t\tif (!chart) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tvar layoutOptions = chart.options.layout || {};\r\n\t\tvar padding = helpers$1.options.toPadding(layoutOptions.padding);\r\n\r\n\t\tvar availableWidth = width - padding.width;\r\n\t\tvar availableHeight = height - padding.height;\r\n\t\tvar boxes = buildLayoutBoxes(chart.boxes);\r\n\t\tvar verticalBoxes = boxes.vertical;\r\n\t\tvar horizontalBoxes = boxes.horizontal;\r\n\r\n\t\t// Essentially we now have any number of boxes on each of the 4 sides.\r\n\t\t// Our canvas looks like the following.\r\n\t\t// The areas L1 and L2 are the left axes. R1 is the right axis, T1 is the top axis and\r\n\t\t// B1 is the bottom axis\r\n\t\t// There are also 4 quadrant-like locations (left to right instead of clockwise) reserved for chart overlays\r\n\t\t// These locations are single-box locations only, when trying to register a chartArea location that is already taken,\r\n\t\t// an error will be thrown.\r\n\t\t//\r\n\t\t// |----------------------------------------------------|\r\n\t\t// | T1 (Full Width) |\r\n\t\t// |----------------------------------------------------|\r\n\t\t// | | | T2 | |\r\n\t\t// | |----|-------------------------------------|----|\r\n\t\t// | | | C1 | | C2 | |\r\n\t\t// | | |----| |----| |\r\n\t\t// | | | | |\r\n\t\t// | L1 | L2 | ChartArea (C0) | R1 |\r\n\t\t// | | | | |\r\n\t\t// | | |----| |----| |\r\n\t\t// | | | C3 | | C4 | |\r\n\t\t// | |----|-------------------------------------|----|\r\n\t\t// | | | B1 | |\r\n\t\t// |----------------------------------------------------|\r\n\t\t// | B2 (Full Width) |\r\n\t\t// |----------------------------------------------------|\r\n\t\t//\r\n\r\n\t\tvar params = Object.freeze({\r\n\t\t\touterWidth: width,\r\n\t\t\touterHeight: height,\r\n\t\t\tpadding: padding,\r\n\t\t\tavailableWidth: availableWidth,\r\n\t\t\tvBoxMaxWidth: availableWidth / 2 / verticalBoxes.length,\r\n\t\t\thBoxMaxHeight: availableHeight / 2\r\n\t\t});\r\n\t\tvar chartArea = extend({\r\n\t\t\tmaxPadding: extend({}, padding),\r\n\t\t\tw: availableWidth,\r\n\t\t\th: availableHeight,\r\n\t\t\tx: padding.left,\r\n\t\t\ty: padding.top\r\n\t\t}, padding);\r\n\r\n\t\tsetLayoutDims(verticalBoxes.concat(horizontalBoxes), params);\r\n\r\n\t\t// First fit vertical boxes\r\n\t\tfitBoxes(verticalBoxes, chartArea, params);\r\n\r\n\t\t// Then fit horizontal boxes\r\n\t\tif (fitBoxes(horizontalBoxes, chartArea, params)) {\r\n\t\t\t// if the area changed, re-fit vertical boxes\r\n\t\t\tfitBoxes(verticalBoxes, chartArea, params);\r\n\t\t}\r\n\r\n\t\thandleMaxPadding(chartArea);\r\n\r\n\t\t// Finally place the boxes to correct coordinates\r\n\t\tplaceBoxes(boxes.leftAndTop, chartArea, params);\r\n\r\n\t\t// Move to opposite side of chart\r\n\t\tchartArea.x += chartArea.w;\r\n\t\tchartArea.y += chartArea.h;\r\n\r\n\t\tplaceBoxes(boxes.rightAndBottom, chartArea, params);\r\n\r\n\t\tchart.chartArea = {\r\n\t\t\tleft: chartArea.left,\r\n\t\t\ttop: chartArea.top,\r\n\t\t\tright: chartArea.left + chartArea.w,\r\n\t\t\tbottom: chartArea.top + chartArea.h\r\n\t\t};\r\n\r\n\t\t// Finally update boxes in chartArea (radial scale for example)\r\n\t\thelpers$1.each(boxes.chartArea, function(layout) {\r\n\t\t\tvar box = layout.box;\r\n\t\t\textend(box, chart.chartArea);\r\n\t\t\tbox.update(chartArea.w, chartArea.h);\r\n\t\t});\r\n\t}\r\n};\n\n/**\r\n * Platform fallback implementation (minimal).\r\n * @see https://github.com/chartjs/Chart.js/pull/4591#issuecomment-319575939\r\n */\r\n\r\nvar platform_basic = {\r\n\tacquireContext: function(item) {\r\n\t\tif (item && item.canvas) {\r\n\t\t\t// Support for any object associated to a canvas (including a context2d)\r\n\t\t\titem = item.canvas;\r\n\t\t}\r\n\r\n\t\treturn item && item.getContext('2d') || null;\r\n\t}\r\n};\n\nvar platform_dom = \"/*\\r\\n * DOM element rendering detection\\r\\n * https://davidwalsh.name/detect-node-insertion\\r\\n */\\r\\n@keyframes chartjs-render-animation {\\r\\n\\tfrom { opacity: 0.99; }\\r\\n\\tto { opacity: 1; }\\r\\n}\\r\\n\\r\\n.chartjs-render-monitor {\\r\\n\\tanimation: chartjs-render-animation 0.001s;\\r\\n}\\r\\n\\r\\n/*\\r\\n * DOM element resizing detection\\r\\n * https://github.com/marcj/css-element-queries\\r\\n */\\r\\n.chartjs-size-monitor,\\r\\n.chartjs-size-monitor-expand,\\r\\n.chartjs-size-monitor-shrink {\\r\\n\\tposition: absolute;\\r\\n\\tdirection: ltr;\\r\\n\\tleft: 0;\\r\\n\\ttop: 0;\\r\\n\\tright: 0;\\r\\n\\tbottom: 0;\\r\\n\\toverflow: hidden;\\r\\n\\tpointer-events: none;\\r\\n\\tvisibility: hidden;\\r\\n\\tz-index: -1;\\r\\n}\\r\\n\\r\\n.chartjs-size-monitor-expand > div {\\r\\n\\tposition: absolute;\\r\\n\\twidth: 1000000px;\\r\\n\\theight: 1000000px;\\r\\n\\tleft: 0;\\r\\n\\ttop: 0;\\r\\n}\\r\\n\\r\\n.chartjs-size-monitor-shrink > div {\\r\\n\\tposition: absolute;\\r\\n\\twidth: 200%;\\r\\n\\theight: 200%;\\r\\n\\tleft: 0;\\r\\n\\ttop: 0;\\r\\n}\\r\\n\";\n\nvar platform_dom$1 = /*#__PURE__*/Object.freeze({\n__proto__: null,\n'default': platform_dom\n});\n\nvar stylesheet = getCjsExportFromNamespace(platform_dom$1);\n\nvar EXPANDO_KEY = '$chartjs';\r\nvar CSS_PREFIX = 'chartjs-';\r\nvar CSS_SIZE_MONITOR = CSS_PREFIX + 'size-monitor';\r\nvar CSS_RENDER_MONITOR = CSS_PREFIX + 'render-monitor';\r\nvar CSS_RENDER_ANIMATION = CSS_PREFIX + 'render-animation';\r\nvar ANIMATION_START_EVENTS = ['animationstart', 'webkitAnimationStart'];\r\n\r\n/**\r\n * DOM event types -> Chart.js event types.\r\n * Note: only events with different types are mapped.\r\n * @see https://developer.mozilla.org/en-US/docs/Web/Events\r\n */\r\nvar EVENT_TYPES = {\r\n\ttouchstart: 'mousedown',\r\n\ttouchmove: 'mousemove',\r\n\ttouchend: 'mouseup',\r\n\tpointerenter: 'mouseenter',\r\n\tpointerdown: 'mousedown',\r\n\tpointermove: 'mousemove',\r\n\tpointerup: 'mouseup',\r\n\tpointerleave: 'mouseout',\r\n\tpointerout: 'mouseout'\r\n};\r\n\r\n/**\r\n * The \"used\" size is the final value of a dimension property after all calculations have\r\n * been performed. This method uses the computed style of `element` but returns undefined\r\n * if the computed style is not expressed in pixels. That can happen in some cases where\r\n * `element` has a size relative to its parent and this last one is not yet displayed,\r\n * for example because of `display: none` on a parent node.\r\n * @see https://developer.mozilla.org/en-US/docs/Web/CSS/used_value\r\n * @returns {number} Size in pixels or undefined if unknown.\r\n */\r\nfunction readUsedSize(element, property) {\r\n\tvar value = helpers$1.getStyle(element, property);\r\n\tvar matches = value && value.match(/^(\\d+)(\\.\\d+)?px$/);\r\n\treturn matches ? Number(matches[1]) : undefined;\r\n}\r\n\r\n/**\r\n * Initializes the canvas style and render size without modifying the canvas display size,\r\n * since responsiveness is handled by the controller.resize() method. The config is used\r\n * to determine the aspect ratio to apply in case no explicit height has been specified.\r\n */\r\nfunction initCanvas(canvas, config) {\r\n\tvar style = canvas.style;\r\n\r\n\t// NOTE(SB) canvas.getAttribute('width') !== canvas.width: in the first case it\r\n\t// returns null or '' if no explicit value has been set to the canvas attribute.\r\n\tvar renderHeight = canvas.getAttribute('height');\r\n\tvar renderWidth = canvas.getAttribute('width');\r\n\r\n\t// Chart.js modifies some canvas values that we want to restore on destroy\r\n\tcanvas[EXPANDO_KEY] = {\r\n\t\tinitial: {\r\n\t\t\theight: renderHeight,\r\n\t\t\twidth: renderWidth,\r\n\t\t\tstyle: {\r\n\t\t\t\tdisplay: style.display,\r\n\t\t\t\theight: style.height,\r\n\t\t\t\twidth: style.width\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n\r\n\t// Force canvas to display as block to avoid extra space caused by inline\r\n\t// elements, which would interfere with the responsive resize process.\r\n\t// https://github.com/chartjs/Chart.js/issues/2538\r\n\tstyle.display = style.display || 'block';\r\n\r\n\tif (renderWidth === null || renderWidth === '') {\r\n\t\tvar displayWidth = readUsedSize(canvas, 'width');\r\n\t\tif (displayWidth !== undefined) {\r\n\t\t\tcanvas.width = displayWidth;\r\n\t\t}\r\n\t}\r\n\r\n\tif (renderHeight === null || renderHeight === '') {\r\n\t\tif (canvas.style.height === '') {\r\n\t\t\t// If no explicit render height and style height, let's apply the aspect ratio,\r\n\t\t\t// which one can be specified by the user but also by charts as default option\r\n\t\t\t// (i.e. options.aspectRatio). If not specified, use canvas aspect ratio of 2.\r\n\t\t\tcanvas.height = canvas.width / (config.options.aspectRatio || 2);\r\n\t\t} else {\r\n\t\t\tvar displayHeight = readUsedSize(canvas, 'height');\r\n\t\t\tif (displayWidth !== undefined) {\r\n\t\t\t\tcanvas.height = displayHeight;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\treturn canvas;\r\n}\r\n\r\n/**\r\n * Detects support for options object argument in addEventListener.\r\n * https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Safely_detecting_option_support\r\n * @private\r\n */\r\nvar supportsEventListenerOptions = (function() {\r\n\tvar supports = false;\r\n\ttry {\r\n\t\tvar options = Object.defineProperty({}, 'passive', {\r\n\t\t\t// eslint-disable-next-line getter-return\r\n\t\t\tget: function() {\r\n\t\t\t\tsupports = true;\r\n\t\t\t}\r\n\t\t});\r\n\t\twindow.addEventListener('e', null, options);\r\n\t} catch (e) {\r\n\t\t// continue regardless of error\r\n\t}\r\n\treturn supports;\r\n}());\r\n\r\n// Default passive to true as expected by Chrome for 'touchstart' and 'touchend' events.\r\n// https://github.com/chartjs/Chart.js/issues/4287\r\nvar eventListenerOptions = supportsEventListenerOptions ? {passive: true} : false;\r\n\r\nfunction addListener(node, type, listener) {\r\n\tnode.addEventListener(type, listener, eventListenerOptions);\r\n}\r\n\r\nfunction removeListener(node, type, listener) {\r\n\tnode.removeEventListener(type, listener, eventListenerOptions);\r\n}\r\n\r\nfunction createEvent(type, chart, x, y, nativeEvent) {\r\n\treturn {\r\n\t\ttype: type,\r\n\t\tchart: chart,\r\n\t\tnative: nativeEvent || null,\r\n\t\tx: x !== undefined ? x : null,\r\n\t\ty: y !== undefined ? y : null,\r\n\t};\r\n}\r\n\r\nfunction fromNativeEvent(event, chart) {\r\n\tvar type = EVENT_TYPES[event.type] || event.type;\r\n\tvar pos = helpers$1.getRelativePosition(event, chart);\r\n\treturn createEvent(type, chart, pos.x, pos.y, event);\r\n}\r\n\r\nfunction throttled(fn, thisArg) {\r\n\tvar ticking = false;\r\n\tvar args = [];\r\n\r\n\treturn function() {\r\n\t\targs = Array.prototype.slice.call(arguments);\r\n\t\tthisArg = thisArg || this;\r\n\r\n\t\tif (!ticking) {\r\n\t\t\tticking = true;\r\n\t\t\thelpers$1.requestAnimFrame.call(window, function() {\r\n\t\t\t\tticking = false;\r\n\t\t\t\tfn.apply(thisArg, args);\r\n\t\t\t});\r\n\t\t}\r\n\t};\r\n}\r\n\r\nfunction createDiv(cls) {\r\n\tvar el = document.createElement('div');\r\n\tel.className = cls || '';\r\n\treturn el;\r\n}\r\n\r\n// Implementation based on https://github.com/marcj/css-element-queries\r\nfunction createResizer(handler) {\r\n\tvar maxSize = 1000000;\r\n\r\n\t// NOTE(SB) Don't use innerHTML because it could be considered unsafe.\r\n\t// https://github.com/chartjs/Chart.js/issues/5902\r\n\tvar resizer = createDiv(CSS_SIZE_MONITOR);\r\n\tvar expand = createDiv(CSS_SIZE_MONITOR + '-expand');\r\n\tvar shrink = createDiv(CSS_SIZE_MONITOR + '-shrink');\r\n\r\n\texpand.appendChild(createDiv());\r\n\tshrink.appendChild(createDiv());\r\n\r\n\tresizer.appendChild(expand);\r\n\tresizer.appendChild(shrink);\r\n\tresizer._reset = function() {\r\n\t\texpand.scrollLeft = maxSize;\r\n\t\texpand.scrollTop = maxSize;\r\n\t\tshrink.scrollLeft = maxSize;\r\n\t\tshrink.scrollTop = maxSize;\r\n\t};\r\n\r\n\tvar onScroll = function() {\r\n\t\tresizer._reset();\r\n\t\thandler();\r\n\t};\r\n\r\n\taddListener(expand, 'scroll', onScroll.bind(expand, 'expand'));\r\n\taddListener(shrink, 'scroll', onScroll.bind(shrink, 'shrink'));\r\n\r\n\treturn resizer;\r\n}\r\n\r\n// https://davidwalsh.name/detect-node-insertion\r\nfunction watchForRender(node, handler) {\r\n\tvar expando = node[EXPANDO_KEY] || (node[EXPANDO_KEY] = {});\r\n\tvar proxy = expando.renderProxy = function(e) {\r\n\t\tif (e.animationName === CSS_RENDER_ANIMATION) {\r\n\t\t\thandler();\r\n\t\t}\r\n\t};\r\n\r\n\thelpers$1.each(ANIMATION_START_EVENTS, function(type) {\r\n\t\taddListener(node, type, proxy);\r\n\t});\r\n\r\n\t// #4737: Chrome might skip the CSS animation when the CSS_RENDER_MONITOR class\r\n\t// is removed then added back immediately (same animation frame?). Accessing the\r\n\t// `offsetParent` property will force a reflow and re-evaluate the CSS animation.\r\n\t// https://gist.github.com/paulirish/5d52fb081b3570c81e3a#box-metrics\r\n\t// https://github.com/chartjs/Chart.js/issues/4737\r\n\texpando.reflow = !!node.offsetParent;\r\n\r\n\tnode.classList.add(CSS_RENDER_MONITOR);\r\n}\r\n\r\nfunction unwatchForRender(node) {\r\n\tvar expando = node[EXPANDO_KEY] || {};\r\n\tvar proxy = expando.renderProxy;\r\n\r\n\tif (proxy) {\r\n\t\thelpers$1.each(ANIMATION_START_EVENTS, function(type) {\r\n\t\t\tremoveListener(node, type, proxy);\r\n\t\t});\r\n\r\n\t\tdelete expando.renderProxy;\r\n\t}\r\n\r\n\tnode.classList.remove(CSS_RENDER_MONITOR);\r\n}\r\n\r\nfunction addResizeListener(node, listener, chart) {\r\n\tvar expando = node[EXPANDO_KEY] || (node[EXPANDO_KEY] = {});\r\n\r\n\t// Let's keep track of this added resizer and thus avoid DOM query when removing it.\r\n\tvar resizer = expando.resizer = createResizer(throttled(function() {\r\n\t\tif (expando.resizer) {\r\n\t\t\tvar container = chart.options.maintainAspectRatio && node.parentNode;\r\n\t\t\tvar w = container ? container.clientWidth : 0;\r\n\t\t\tlistener(createEvent('resize', chart));\r\n\t\t\tif (container && container.clientWidth < w && chart.canvas) {\r\n\t\t\t\t// If the container size shrank during chart resize, let's assume\r\n\t\t\t\t// scrollbar appeared. So we resize again with the scrollbar visible -\r\n\t\t\t\t// effectively making chart smaller and the scrollbar hidden again.\r\n\t\t\t\t// Because we are inside `throttled`, and currently `ticking`, scroll\r\n\t\t\t\t// events are ignored during this whole 2 resize process.\r\n\t\t\t\t// If we assumed wrong and something else happened, we are resizing\r\n\t\t\t\t// twice in a frame (potential performance issue)\r\n\t\t\t\tlistener(createEvent('resize', chart));\r\n\t\t\t}\r\n\t\t}\r\n\t}));\r\n\r\n\t// The resizer needs to be attached to the node parent, so we first need to be\r\n\t// sure that `node` is attached to the DOM before injecting the resizer element.\r\n\twatchForRender(node, function() {\r\n\t\tif (expando.resizer) {\r\n\t\t\tvar container = node.parentNode;\r\n\t\t\tif (container && container !== resizer.parentNode) {\r\n\t\t\t\tcontainer.insertBefore(resizer, container.firstChild);\r\n\t\t\t}\r\n\r\n\t\t\t// The container size might have changed, let's reset the resizer state.\r\n\t\t\tresizer._reset();\r\n\t\t}\r\n\t});\r\n}\r\n\r\nfunction removeResizeListener(node) {\r\n\tvar expando = node[EXPANDO_KEY] || {};\r\n\tvar resizer = expando.resizer;\r\n\r\n\tdelete expando.resizer;\r\n\tunwatchForRender(node);\r\n\r\n\tif (resizer && resizer.parentNode) {\r\n\t\tresizer.parentNode.removeChild(resizer);\r\n\t}\r\n}\r\n\r\n/**\r\n * Injects CSS styles inline if the styles are not already present.\r\n * @param {HTMLDocument|ShadowRoot} rootNode - the node to contain the <style>.\r\n * @param {string} css - the CSS to be injected.\r\n */\r\nfunction injectCSS(rootNode, css) {\r\n\t// https://stackoverflow.com/q/3922139\r\n\tvar expando = rootNode[EXPANDO_KEY] || (rootNode[EXPANDO_KEY] = {});\r\n\tif (!expando.containsStyles) {\r\n\t\texpando.containsStyles = true;\r\n\t\tcss = '/* Chart.js */\\n' + css;\r\n\t\tvar style = document.createElement('style');\r\n\t\tstyle.setAttribute('type', 'text/css');\r\n\t\tstyle.appendChild(document.createTextNode(css));\r\n\t\trootNode.appendChild(style);\r\n\t}\r\n}\r\n\r\nvar platform_dom$2 = {\r\n\t/**\r\n\t * When `true`, prevents the automatic injection of the stylesheet required to\r\n\t * correctly detect when the chart is added to the DOM and then resized. This\r\n\t * switch has been added to allow external stylesheet (`dist/Chart(.min)?.js`)\r\n\t * to be manually imported to make this library compatible with any CSP.\r\n\t * See https://github.com/chartjs/Chart.js/issues/5208\r\n\t */\r\n\tdisableCSSInjection: false,\r\n\r\n\t/**\r\n\t * This property holds whether this platform is enabled for the current environment.\r\n\t * Currently used by platform.js to select the proper implementation.\r\n\t * @private\r\n\t */\r\n\t_enabled: typeof window !== 'undefined' && typeof document !== 'undefined',\r\n\r\n\t/**\r\n\t * Initializes resources that depend on platform options.\r\n\t * @param {HTMLCanvasElement} canvas - The Canvas element.\r\n\t * @private\r\n\t */\r\n\t_ensureLoaded: function(canvas) {\r\n\t\tif (!this.disableCSSInjection) {\r\n\t\t\t// If the canvas is in a shadow DOM, then the styles must also be inserted\r\n\t\t\t// into the same shadow DOM.\r\n\t\t\t// https://github.com/chartjs/Chart.js/issues/5763\r\n\t\t\tvar root = canvas.getRootNode ? canvas.getRootNode() : document;\r\n\t\t\tvar targetNode = root.host ? root : document.head;\r\n\t\t\tinjectCSS(targetNode, stylesheet);\r\n\t\t}\r\n\t},\r\n\r\n\tacquireContext: function(item, config) {\r\n\t\tif (typeof item === 'string') {\r\n\t\t\titem = document.getElementById(item);\r\n\t\t} else if (item.length) {\r\n\t\t\t// Support for array based queries (such as jQuery)\r\n\t\t\titem = item[0];\r\n\t\t}\r\n\r\n\t\tif (item && item.canvas) {\r\n\t\t\t// Support for any object associated to a canvas (including a context2d)\r\n\t\t\titem = item.canvas;\r\n\t\t}\r\n\r\n\t\t// To prevent canvas fingerprinting, some add-ons undefine the getContext\r\n\t\t// method, for example: https://github.com/kkapsner/CanvasBlocker\r\n\t\t// https://github.com/chartjs/Chart.js/issues/2807\r\n\t\tvar context = item && item.getContext && item.getContext('2d');\r\n\r\n\t\t// `instanceof HTMLCanvasElement/CanvasRenderingContext2D` fails when the item is\r\n\t\t// inside an iframe or when running in a protected environment. We could guess the\r\n\t\t// types from their toString() value but let's keep things flexible and assume it's\r\n\t\t// a sufficient condition if the item has a context2D which has item as `canvas`.\r\n\t\t// https://github.com/chartjs/Chart.js/issues/3887\r\n\t\t// https://github.com/chartjs/Chart.js/issues/4102\r\n\t\t// https://github.com/chartjs/Chart.js/issues/4152\r\n\t\tif (context && context.canvas === item) {\r\n\t\t\t// Load platform resources on first chart creation, to make it possible to\r\n\t\t\t// import the library before setting platform options.\r\n\t\t\tthis._ensureLoaded(item);\r\n\t\t\tinitCanvas(item, config);\r\n\t\t\treturn context;\r\n\t\t}\r\n\r\n\t\treturn null;\r\n\t},\r\n\r\n\treleaseContext: function(context) {\r\n\t\tvar canvas = context.canvas;\r\n\t\tif (!canvas[EXPANDO_KEY]) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tvar initial = canvas[EXPANDO_KEY].initial;\r\n\t\t['height', 'width'].forEach(function(prop) {\r\n\t\t\tvar value = initial[prop];\r\n\t\t\tif (helpers$1.isNullOrUndef(value)) {\r\n\t\t\t\tcanvas.removeAttribute(prop);\r\n\t\t\t} else {\r\n\t\t\t\tcanvas.setAttribute(prop, value);\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\thelpers$1.each(initial.style || {}, function(value, key) {\r\n\t\t\tcanvas.style[key] = value;\r\n\t\t});\r\n\r\n\t\t// The canvas render size might have been changed (and thus the state stack discarded),\r\n\t\t// we can't use save() and restore() to restore the initial state. So make sure that at\r\n\t\t// least the canvas context is reset to the default state by setting the canvas width.\r\n\t\t// https://www.w3.org/TR/2011/WD-html5-20110525/the-canvas-element.html\r\n\t\t// eslint-disable-next-line no-self-assign\r\n\t\tcanvas.width = canvas.width;\r\n\r\n\t\tdelete canvas[EXPANDO_KEY];\r\n\t},\r\n\r\n\taddEventListener: function(chart, type, listener) {\r\n\t\tvar canvas = chart.canvas;\r\n\t\tif (type === 'resize') {\r\n\t\t\t// Note: the resize event is not supported on all browsers.\r\n\t\t\taddResizeListener(canvas, listener, chart);\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tvar expando = listener[EXPANDO_KEY] || (listener[EXPANDO_KEY] = {});\r\n\t\tvar proxies = expando.proxies || (expando.proxies = {});\r\n\t\tvar proxy = proxies[chart.id + '_' + type] = function(event) {\r\n\t\t\tlistener(fromNativeEvent(event, chart));\r\n\t\t};\r\n\r\n\t\taddListener(canvas, type, proxy);\r\n\t},\r\n\r\n\tremoveEventListener: function(chart, type, listener) {\r\n\t\tvar canvas = chart.canvas;\r\n\t\tif (type === 'resize') {\r\n\t\t\t// Note: the resize event is not supported on all browsers.\r\n\t\t\tremoveResizeListener(canvas);\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tvar expando = listener[EXPANDO_KEY] || {};\r\n\t\tvar proxies = expando.proxies || {};\r\n\t\tvar proxy = proxies[chart.id + '_' + type];\r\n\t\tif (!proxy) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tremoveListener(canvas, type, proxy);\r\n\t}\r\n};\r\n\r\n// DEPRECATIONS\r\n\r\n/**\r\n * Provided for backward compatibility, use EventTarget.addEventListener instead.\r\n * EventTarget.addEventListener compatibility: Chrome, Opera 7, Safari, FF1.5+, IE9+\r\n * @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener\r\n * @function Chart.helpers.addEvent\r\n * @deprecated since version 2.7.0\r\n * @todo remove at version 3\r\n * @private\r\n */\r\nhelpers$1.addEvent = addListener;\r\n\r\n/**\r\n * Provided for backward compatibility, use EventTarget.removeEventListener instead.\r\n * EventTarget.removeEventListener compatibility: Chrome, Opera 7, Safari, FF1.5+, IE9+\r\n * @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener\r\n * @function Chart.helpers.removeEvent\r\n * @deprecated since version 2.7.0\r\n * @todo remove at version 3\r\n * @private\r\n */\r\nhelpers$1.removeEvent = removeListener;\n\n// @TODO Make possible to select another platform at build time.\r\nvar implementation = platform_dom$2._enabled ? platform_dom$2 : platform_basic;\r\n\r\n/**\r\n * @namespace Chart.platform\r\n * @see https://chartjs.gitbooks.io/proposals/content/Platform.html\r\n * @since 2.4.0\r\n */\r\nvar platform = helpers$1.extend({\r\n\t/**\r\n\t * @since 2.7.0\r\n\t */\r\n\tinitialize: function() {},\r\n\r\n\t/**\r\n\t * Called at chart construction time, returns a context2d instance implementing\r\n\t * the [W3C Canvas 2D Context API standard]{@link https://www.w3.org/TR/2dcontext/}.\r\n\t * @param {*} item - The native item from which to acquire context (platform specific)\r\n\t * @param {object} options - The chart options\r\n\t * @returns {CanvasRenderingContext2D} context2d instance\r\n\t */\r\n\tacquireContext: function() {},\r\n\r\n\t/**\r\n\t * Called at chart destruction time, releases any resources associated to the context\r\n\t * previously returned by the acquireContext() method.\r\n\t * @param {CanvasRenderingContext2D} context - The context2d instance\r\n\t * @returns {boolean} true if the method succeeded, else false\r\n\t */\r\n\treleaseContext: function() {},\r\n\r\n\t/**\r\n\t * Registers the specified listener on the given chart.\r\n\t * @param {Chart} chart - Chart from which to listen for event\r\n\t * @param {string} type - The ({@link IEvent}) type to listen for\r\n\t * @param {function} listener - Receives a notification (an object that implements\r\n\t * the {@link IEvent} interface) when an event of the specified type occurs.\r\n\t */\r\n\taddEventListener: function() {},\r\n\r\n\t/**\r\n\t * Removes the specified listener previously registered with addEventListener.\r\n\t * @param {Chart} chart - Chart from which to remove the listener\r\n\t * @param {string} type - The ({@link IEvent}) type to remove\r\n\t * @param {function} listener - The listener function to remove from the event target.\r\n\t */\r\n\tremoveEventListener: function() {}\r\n\r\n}, implementation);\n\ncore_defaults._set('global', {\r\n\tplugins: {}\r\n});\r\n\r\n/**\r\n * The plugin service singleton\r\n * @namespace Chart.plugins\r\n * @since 2.1.0\r\n */\r\nvar core_plugins = {\r\n\t/**\r\n\t * Globally registered plugins.\r\n\t * @private\r\n\t */\r\n\t_plugins: [],\r\n\r\n\t/**\r\n\t * This identifier is used to invalidate the descriptors cache attached to each chart\r\n\t * when a global plugin is registered or unregistered. In this case, the cache ID is\r\n\t * incremented and descriptors are regenerated during following API calls.\r\n\t * @private\r\n\t */\r\n\t_cacheId: 0,\r\n\r\n\t/**\r\n\t * Registers the given plugin(s) if not already registered.\r\n\t * @param {IPlugin[]|IPlugin} plugins plugin instance(s).\r\n\t */\r\n\tregister: function(plugins) {\r\n\t\tvar p = this._plugins;\r\n\t\t([]).concat(plugins).forEach(function(plugin) {\r\n\t\t\tif (p.indexOf(plugin) === -1) {\r\n\t\t\t\tp.push(plugin);\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tthis._cacheId++;\r\n\t},\r\n\r\n\t/**\r\n\t * Unregisters the given plugin(s) only if registered.\r\n\t * @param {IPlugin[]|IPlugin} plugins plugin instance(s).\r\n\t */\r\n\tunregister: function(plugins) {\r\n\t\tvar p = this._plugins;\r\n\t\t([]).concat(plugins).forEach(function(plugin) {\r\n\t\t\tvar idx = p.indexOf(plugin);\r\n\t\t\tif (idx !== -1) {\r\n\t\t\t\tp.splice(idx, 1);\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tthis._cacheId++;\r\n\t},\r\n\r\n\t/**\r\n\t * Remove all registered plugins.\r\n\t * @since 2.1.5\r\n\t */\r\n\tclear: function() {\r\n\t\tthis._plugins = [];\r\n\t\tthis._cacheId++;\r\n\t},\r\n\r\n\t/**\r\n\t * Returns the number of registered plugins?\r\n\t * @returns {number}\r\n\t * @since 2.1.5\r\n\t */\r\n\tcount: function() {\r\n\t\treturn this._plugins.length;\r\n\t},\r\n\r\n\t/**\r\n\t * Returns all registered plugin instances.\r\n\t * @returns {IPlugin[]} array of plugin objects.\r\n\t * @since 2.1.5\r\n\t */\r\n\tgetAll: function() {\r\n\t\treturn this._plugins;\r\n\t},\r\n\r\n\t/**\r\n\t * Calls enabled plugins for `chart` on the specified hook and with the given args.\r\n\t * This method immediately returns as soon as a plugin explicitly returns false. The\r\n\t * returned value can be used, for instance, to interrupt the current action.\r\n\t * @param {Chart} chart - The chart instance for which plugins should be called.\r\n\t * @param {string} hook - The name of the plugin method to call (e.g. 'beforeUpdate').\r\n\t * @param {Array} [args] - Extra arguments to apply to the hook call.\r\n\t * @returns {boolean} false if any of the plugins return false, else returns true.\r\n\t */\r\n\tnotify: function(chart, hook, args) {\r\n\t\tvar descriptors = this.descriptors(chart);\r\n\t\tvar ilen = descriptors.length;\r\n\t\tvar i, descriptor, plugin, params, method;\r\n\r\n\t\tfor (i = 0; i < ilen; ++i) {\r\n\t\t\tdescriptor = descriptors[i];\r\n\t\t\tplugin = descriptor.plugin;\r\n\t\t\tmethod = plugin[hook];\r\n\t\t\tif (typeof method === 'function') {\r\n\t\t\t\tparams = [chart].concat(args || []);\r\n\t\t\t\tparams.push(descriptor.options);\r\n\t\t\t\tif (method.apply(plugin, params) === false) {\r\n\t\t\t\t\treturn false;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn true;\r\n\t},\r\n\r\n\t/**\r\n\t * Returns descriptors of enabled plugins for the given chart.\r\n\t * @returns {object[]} [{ plugin, options }]\r\n\t * @private\r\n\t */\r\n\tdescriptors: function(chart) {\r\n\t\tvar cache = chart.$plugins || (chart.$plugins = {});\r\n\t\tif (cache.id === this._cacheId) {\r\n\t\t\treturn cache.descriptors;\r\n\t\t}\r\n\r\n\t\tvar plugins = [];\r\n\t\tvar descriptors = [];\r\n\t\tvar config = (chart && chart.config) || {};\r\n\t\tvar options = (config.options && config.options.plugins) || {};\r\n\r\n\t\tthis._plugins.concat(config.plugins || []).forEach(function(plugin) {\r\n\t\t\tvar idx = plugins.indexOf(plugin);\r\n\t\t\tif (idx !== -1) {\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\tvar id = plugin.id;\r\n\t\t\tvar opts = options[id];\r\n\t\t\tif (opts === false) {\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\tif (opts === true) {\r\n\t\t\t\topts = helpers$1.clone(core_defaults.global.plugins[id]);\r\n\t\t\t}\r\n\r\n\t\t\tplugins.push(plugin);\r\n\t\t\tdescriptors.push({\r\n\t\t\t\tplugin: plugin,\r\n\t\t\t\toptions: opts || {}\r\n\t\t\t});\r\n\t\t});\r\n\r\n\t\tcache.descriptors = descriptors;\r\n\t\tcache.id = this._cacheId;\r\n\t\treturn descriptors;\r\n\t},\r\n\r\n\t/**\r\n\t * Invalidates cache for the given chart: descriptors hold a reference on plugin option,\r\n\t * but in some cases, this reference can be changed by the user when updating options.\r\n\t * https://github.com/chartjs/Chart.js/issues/5111#issuecomment-355934167\r\n\t * @private\r\n\t */\r\n\t_invalidate: function(chart) {\r\n\t\tdelete chart.$plugins;\r\n\t}\r\n};\n\nvar core_scaleService = {\r\n\t// Scale registration object. Extensions can register new scale types (such as log or DB scales) and then\r\n\t// use the new chart options to grab the correct scale\r\n\tconstructors: {},\r\n\t// Use a registration function so that we can move to an ES6 map when we no longer need to support\r\n\t// old browsers\r\n\r\n\t// Scale config defaults\r\n\tdefaults: {},\r\n\tregisterScaleType: function(type, scaleConstructor, scaleDefaults) {\r\n\t\tthis.constructors[type] = scaleConstructor;\r\n\t\tthis.defaults[type] = helpers$1.clone(scaleDefaults);\r\n\t},\r\n\tgetScaleConstructor: function(type) {\r\n\t\treturn this.constructors.hasOwnProperty(type) ? this.constructors[type] : undefined;\r\n\t},\r\n\tgetScaleDefaults: function(type) {\r\n\t\t// Return the scale defaults merged with the global settings so that we always use the latest ones\r\n\t\treturn this.defaults.hasOwnProperty(type) ? helpers$1.merge(Object.create(null), [core_defaults.scale, this.defaults[type]]) : {};\r\n\t},\r\n\tupdateScaleDefaults: function(type, additions) {\r\n\t\tvar me = this;\r\n\t\tif (me.defaults.hasOwnProperty(type)) {\r\n\t\t\tme.defaults[type] = helpers$1.extend(me.defaults[type], additions);\r\n\t\t}\r\n\t},\r\n\taddScalesToLayout: function(chart) {\r\n\t\t// Adds each scale to the chart.boxes array to be sized accordingly\r\n\t\thelpers$1.each(chart.scales, function(scale) {\r\n\t\t\t// Set ILayoutItem parameters for backwards compatibility\r\n\t\t\tscale.fullWidth = scale.options.fullWidth;\r\n\t\t\tscale.position = scale.options.position;\r\n\t\t\tscale.weight = scale.options.weight;\r\n\t\t\tcore_layouts.addBox(chart, scale);\r\n\t\t});\r\n\t}\r\n};\n\nvar valueOrDefault$8 = helpers$1.valueOrDefault;\r\nvar getRtlHelper = helpers$1.rtl.getRtlAdapter;\r\n\r\ncore_defaults._set('global', {\r\n\ttooltips: {\r\n\t\tenabled: true,\r\n\t\tcustom: null,\r\n\t\tmode: 'nearest',\r\n\t\tposition: 'average',\r\n\t\tintersect: true,\r\n\t\tbackgroundColor: 'rgba(0,0,0,0.8)',\r\n\t\ttitleFontStyle: 'bold',\r\n\t\ttitleSpacing: 2,\r\n\t\ttitleMarginBottom: 6,\r\n\t\ttitleFontColor: '#fff',\r\n\t\ttitleAlign: 'left',\r\n\t\tbodySpacing: 2,\r\n\t\tbodyFontColor: '#fff',\r\n\t\tbodyAlign: 'left',\r\n\t\tfooterFontStyle: 'bold',\r\n\t\tfooterSpacing: 2,\r\n\t\tfooterMarginTop: 6,\r\n\t\tfooterFontColor: '#fff',\r\n\t\tfooterAlign: 'left',\r\n\t\tyPadding: 6,\r\n\t\txPadding: 6,\r\n\t\tcaretPadding: 2,\r\n\t\tcaretSize: 5,\r\n\t\tcornerRadius: 6,\r\n\t\tmultiKeyBackground: '#fff',\r\n\t\tdisplayColors: true,\r\n\t\tborderColor: 'rgba(0,0,0,0)',\r\n\t\tborderWidth: 0,\r\n\t\tcallbacks: {\r\n\t\t\t// Args are: (tooltipItems, data)\r\n\t\t\tbeforeTitle: helpers$1.noop,\r\n\t\t\ttitle: function(tooltipItems, data) {\r\n\t\t\t\tvar title = '';\r\n\t\t\t\tvar labels = data.labels;\r\n\t\t\t\tvar labelCount = labels ? labels.length : 0;\r\n\r\n\t\t\t\tif (tooltipItems.length > 0) {\r\n\t\t\t\t\tvar item = tooltipItems[0];\r\n\t\t\t\t\tif (item.label) {\r\n\t\t\t\t\t\ttitle = item.label;\r\n\t\t\t\t\t} else if (item.xLabel) {\r\n\t\t\t\t\t\ttitle = item.xLabel;\r\n\t\t\t\t\t} else if (labelCount > 0 && item.index < labelCount) {\r\n\t\t\t\t\t\ttitle = labels[item.index];\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\treturn title;\r\n\t\t\t},\r\n\t\t\tafterTitle: helpers$1.noop,\r\n\r\n\t\t\t// Args are: (tooltipItems, data)\r\n\t\t\tbeforeBody: helpers$1.noop,\r\n\r\n\t\t\t// Args are: (tooltipItem, data)\r\n\t\t\tbeforeLabel: helpers$1.noop,\r\n\t\t\tlabel: function(tooltipItem, data) {\r\n\t\t\t\tvar label = data.datasets[tooltipItem.datasetIndex].label || '';\r\n\r\n\t\t\t\tif (label) {\r\n\t\t\t\t\tlabel += ': ';\r\n\t\t\t\t}\r\n\t\t\t\tif (!helpers$1.isNullOrUndef(tooltipItem.value)) {\r\n\t\t\t\t\tlabel += tooltipItem.value;\r\n\t\t\t\t} else {\r\n\t\t\t\t\tlabel += tooltipItem.yLabel;\r\n\t\t\t\t}\r\n\t\t\t\treturn label;\r\n\t\t\t},\r\n\t\t\tlabelColor: function(tooltipItem, chart) {\r\n\t\t\t\tvar meta = chart.getDatasetMeta(tooltipItem.datasetIndex);\r\n\t\t\t\tvar activeElement = meta.data[tooltipItem.index];\r\n\t\t\t\tvar view = activeElement._view;\r\n\t\t\t\treturn {\r\n\t\t\t\t\tborderColor: view.borderColor,\r\n\t\t\t\t\tbackgroundColor: view.backgroundColor\r\n\t\t\t\t};\r\n\t\t\t},\r\n\t\t\tlabelTextColor: function() {\r\n\t\t\t\treturn this._options.bodyFontColor;\r\n\t\t\t},\r\n\t\t\tafterLabel: helpers$1.noop,\r\n\r\n\t\t\t// Args are: (tooltipItems, data)\r\n\t\t\tafterBody: helpers$1.noop,\r\n\r\n\t\t\t// Args are: (tooltipItems, data)\r\n\t\t\tbeforeFooter: helpers$1.noop,\r\n\t\t\tfooter: helpers$1.noop,\r\n\t\t\tafterFooter: helpers$1.noop\r\n\t\t}\r\n\t}\r\n});\r\n\r\nvar positioners = {\r\n\t/**\r\n\t * Average mode places the tooltip at the average position of the elements shown\r\n\t * @function Chart.Tooltip.positioners.average\r\n\t * @param elements {ChartElement[]} the elements being displayed in the tooltip\r\n\t * @returns {object} tooltip position\r\n\t */\r\n\taverage: function(elements) {\r\n\t\tif (!elements.length) {\r\n\t\t\treturn false;\r\n\t\t}\r\n\r\n\t\tvar i, len;\r\n\t\tvar x = 0;\r\n\t\tvar y = 0;\r\n\t\tvar count = 0;\r\n\r\n\t\tfor (i = 0, len = elements.length; i < len; ++i) {\r\n\t\t\tvar el = elements[i];\r\n\t\t\tif (el && el.hasValue()) {\r\n\t\t\t\tvar pos = el.tooltipPosition();\r\n\t\t\t\tx += pos.x;\r\n\t\t\t\ty += pos.y;\r\n\t\t\t\t++count;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn {\r\n\t\t\tx: x / count,\r\n\t\t\ty: y / count\r\n\t\t};\r\n\t},\r\n\r\n\t/**\r\n\t * Gets the tooltip position nearest of the item nearest to the event position\r\n\t * @function Chart.Tooltip.positioners.nearest\r\n\t * @param elements {Chart.Element[]} the tooltip elements\r\n\t * @param eventPosition {object} the position of the event in canvas coordinates\r\n\t * @returns {object} the tooltip position\r\n\t */\r\n\tnearest: function(elements, eventPosition) {\r\n\t\tvar x = eventPosition.x;\r\n\t\tvar y = eventPosition.y;\r\n\t\tvar minDistance = Number.POSITIVE_INFINITY;\r\n\t\tvar i, len, nearestElement;\r\n\r\n\t\tfor (i = 0, len = elements.length; i < len; ++i) {\r\n\t\t\tvar el = elements[i];\r\n\t\t\tif (el && el.hasValue()) {\r\n\t\t\t\tvar center = el.getCenterPoint();\r\n\t\t\t\tvar d = helpers$1.distanceBetweenPoints(eventPosition, center);\r\n\r\n\t\t\t\tif (d < minDistance) {\r\n\t\t\t\t\tminDistance = d;\r\n\t\t\t\t\tnearestElement = el;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (nearestElement) {\r\n\t\t\tvar tp = nearestElement.tooltipPosition();\r\n\t\t\tx = tp.x;\r\n\t\t\ty = tp.y;\r\n\t\t}\r\n\r\n\t\treturn {\r\n\t\t\tx: x,\r\n\t\t\ty: y\r\n\t\t};\r\n\t}\r\n};\r\n\r\n// Helper to push or concat based on if the 2nd parameter is an array or not\r\nfunction pushOrConcat(base, toPush) {\r\n\tif (toPush) {\r\n\t\tif (helpers$1.isArray(toPush)) {\r\n\t\t\t// base = base.concat(toPush);\r\n\t\t\tArray.prototype.push.apply(base, toPush);\r\n\t\t} else {\r\n\t\t\tbase.push(toPush);\r\n\t\t}\r\n\t}\r\n\r\n\treturn base;\r\n}\r\n\r\n/**\r\n * Returns array of strings split by newline\r\n * @param {string} value - The value to split by newline.\r\n * @returns {string[]} value if newline present - Returned from String split() method\r\n * @function\r\n */\r\nfunction splitNewlines(str) {\r\n\tif ((typeof str === 'string' || str instanceof String) && str.indexOf('\\n') > -1) {\r\n\t\treturn str.split('\\n');\r\n\t}\r\n\treturn str;\r\n}\r\n\r\n\r\n/**\r\n * Private helper to create a tooltip item model\r\n * @param element - the chart element (point, arc, bar) to create the tooltip item for\r\n * @return new tooltip item\r\n */\r\nfunction createTooltipItem(element) {\r\n\tvar xScale = element._xScale;\r\n\tvar yScale = element._yScale || element._scale; // handle radar || polarArea charts\r\n\tvar index = element._index;\r\n\tvar datasetIndex = element._datasetIndex;\r\n\tvar controller = element._chart.getDatasetMeta(datasetIndex).controller;\r\n\tvar indexScale = controller._getIndexScale();\r\n\tvar valueScale = controller._getValueScale();\r\n\r\n\treturn {\r\n\t\txLabel: xScale ? xScale.getLabelForIndex(index, datasetIndex) : '',\r\n\t\tyLabel: yScale ? yScale.getLabelForIndex(index, datasetIndex) : '',\r\n\t\tlabel: indexScale ? '' + indexScale.getLabelForIndex(index, datasetIndex) : '',\r\n\t\tvalue: valueScale ? '' + valueScale.getLabelForIndex(index, datasetIndex) : '',\r\n\t\tindex: index,\r\n\t\tdatasetIndex: datasetIndex,\r\n\t\tx: element._model.x,\r\n\t\ty: element._model.y\r\n\t};\r\n}\r\n\r\n/**\r\n * Helper to get the reset model for the tooltip\r\n * @param tooltipOpts {object} the tooltip options\r\n */\r\nfunction getBaseModel(tooltipOpts) {\r\n\tvar globalDefaults = core_defaults.global;\r\n\r\n\treturn {\r\n\t\t// Positioning\r\n\t\txPadding: tooltipOpts.xPadding,\r\n\t\tyPadding: tooltipOpts.yPadding,\r\n\t\txAlign: tooltipOpts.xAlign,\r\n\t\tyAlign: tooltipOpts.yAlign,\r\n\r\n\t\t// Drawing direction and text direction\r\n\t\trtl: tooltipOpts.rtl,\r\n\t\ttextDirection: tooltipOpts.textDirection,\r\n\r\n\t\t// Body\r\n\t\tbodyFontColor: tooltipOpts.bodyFontColor,\r\n\t\t_bodyFontFamily: valueOrDefault$8(tooltipOpts.bodyFontFamily, globalDefaults.defaultFontFamily),\r\n\t\t_bodyFontStyle: valueOrDefault$8(tooltipOpts.bodyFontStyle, globalDefaults.defaultFontStyle),\r\n\t\t_bodyAlign: tooltipOpts.bodyAlign,\r\n\t\tbodyFontSize: valueOrDefault$8(tooltipOpts.bodyFontSize, globalDefaults.defaultFontSize),\r\n\t\tbodySpacing: tooltipOpts.bodySpacing,\r\n\r\n\t\t// Title\r\n\t\ttitleFontColor: tooltipOpts.titleFontColor,\r\n\t\t_titleFontFamily: valueOrDefault$8(tooltipOpts.titleFontFamily, globalDefaults.defaultFontFamily),\r\n\t\t_titleFontStyle: valueOrDefault$8(tooltipOpts.titleFontStyle, globalDefaults.defaultFontStyle),\r\n\t\ttitleFontSize: valueOrDefault$8(tooltipOpts.titleFontSize, globalDefaults.defaultFontSize),\r\n\t\t_titleAlign: tooltipOpts.titleAlign,\r\n\t\ttitleSpacing: tooltipOpts.titleSpacing,\r\n\t\ttitleMarginBottom: tooltipOpts.titleMarginBottom,\r\n\r\n\t\t// Footer\r\n\t\tfooterFontColor: tooltipOpts.footerFontColor,\r\n\t\t_footerFontFamily: valueOrDefault$8(tooltipOpts.footerFontFamily, globalDefaults.defaultFontFamily),\r\n\t\t_footerFontStyle: valueOrDefault$8(tooltipOpts.footerFontStyle, globalDefaults.defaultFontStyle),\r\n\t\tfooterFontSize: valueOrDefault$8(tooltipOpts.footerFontSize, globalDefaults.defaultFontSize),\r\n\t\t_footerAlign: tooltipOpts.footerAlign,\r\n\t\tfooterSpacing: tooltipOpts.footerSpacing,\r\n\t\tfooterMarginTop: tooltipOpts.footerMarginTop,\r\n\r\n\t\t// Appearance\r\n\t\tcaretSize: tooltipOpts.caretSize,\r\n\t\tcornerRadius: tooltipOpts.cornerRadius,\r\n\t\tbackgroundColor: tooltipOpts.backgroundColor,\r\n\t\topacity: 0,\r\n\t\tlegendColorBackground: tooltipOpts.multiKeyBackground,\r\n\t\tdisplayColors: tooltipOpts.displayColors,\r\n\t\tborderColor: tooltipOpts.borderColor,\r\n\t\tborderWidth: tooltipOpts.borderWidth\r\n\t};\r\n}\r\n\r\n/**\r\n * Get the size of the tooltip\r\n */\r\nfunction getTooltipSize(tooltip, model) {\r\n\tvar ctx = tooltip._chart.ctx;\r\n\r\n\tvar height = model.yPadding * 2; // Tooltip Padding\r\n\tvar width = 0;\r\n\r\n\t// Count of all lines in the body\r\n\tvar body = model.body;\r\n\tvar combinedBodyLength = body.reduce(function(count, bodyItem) {\r\n\t\treturn count + bodyItem.before.length + bodyItem.lines.length + bodyItem.after.length;\r\n\t}, 0);\r\n\tcombinedBodyLength += model.beforeBody.length + model.afterBody.length;\r\n\r\n\tvar titleLineCount = model.title.length;\r\n\tvar footerLineCount = model.footer.length;\r\n\tvar titleFontSize = model.titleFontSize;\r\n\tvar bodyFontSize = model.bodyFontSize;\r\n\tvar footerFontSize = model.footerFontSize;\r\n\r\n\theight += titleLineCount * titleFontSize; // Title Lines\r\n\theight += titleLineCount ? (titleLineCount - 1) * model.titleSpacing : 0; // Title Line Spacing\r\n\theight += titleLineCount ? model.titleMarginBottom : 0; // Title's bottom Margin\r\n\theight += combinedBodyLength * bodyFontSize; // Body Lines\r\n\theight += combinedBodyLength ? (combinedBodyLength - 1) * model.bodySpacing : 0; // Body Line Spacing\r\n\theight += footerLineCount ? model.footerMarginTop : 0; // Footer Margin\r\n\theight += footerLineCount * (footerFontSize); // Footer Lines\r\n\theight += footerLineCount ? (footerLineCount - 1) * model.footerSpacing : 0; // Footer Line Spacing\r\n\r\n\t// Title width\r\n\tvar widthPadding = 0;\r\n\tvar maxLineWidth = function(line) {\r\n\t\twidth = Math.max(width, ctx.measureText(line).width + widthPadding);\r\n\t};\r\n\r\n\tctx.font = helpers$1.fontString(titleFontSize, model._titleFontStyle, model._titleFontFamily);\r\n\thelpers$1.each(model.title, maxLineWidth);\r\n\r\n\t// Body width\r\n\tctx.font = helpers$1.fontString(bodyFontSize, model._bodyFontStyle, model._bodyFontFamily);\r\n\thelpers$1.each(model.beforeBody.concat(model.afterBody), maxLineWidth);\r\n\r\n\t// Body lines may include some extra width due to the color box\r\n\twidthPadding = model.displayColors ? (bodyFontSize + 2) : 0;\r\n\thelpers$1.each(body, function(bodyItem) {\r\n\t\thelpers$1.each(bodyItem.before, maxLineWidth);\r\n\t\thelpers$1.each(bodyItem.lines, maxLineWidth);\r\n\t\thelpers$1.each(bodyItem.after, maxLineWidth);\r\n\t});\r\n\r\n\t// Reset back to 0\r\n\twidthPadding = 0;\r\n\r\n\t// Footer width\r\n\tctx.font = helpers$1.fontString(footerFontSize, model._footerFontStyle, model._footerFontFamily);\r\n\thelpers$1.each(model.footer, maxLineWidth);\r\n\r\n\t// Add padding\r\n\twidth += 2 * model.xPadding;\r\n\r\n\treturn {\r\n\t\twidth: width,\r\n\t\theight: height\r\n\t};\r\n}\r\n\r\n/**\r\n * Helper to get the alignment of a tooltip given the size\r\n */\r\nfunction determineAlignment(tooltip, size) {\r\n\tvar model = tooltip._model;\r\n\tvar chart = tooltip._chart;\r\n\tvar chartArea = tooltip._chart.chartArea;\r\n\tvar xAlign = 'center';\r\n\tvar yAlign = 'center';\r\n\r\n\tif (model.y < size.height) {\r\n\t\tyAlign = 'top';\r\n\t} else if (model.y > (chart.height - size.height)) {\r\n\t\tyAlign = 'bottom';\r\n\t}\r\n\r\n\tvar lf, rf; // functions to determine left, right alignment\r\n\tvar olf, orf; // functions to determine if left/right alignment causes tooltip to go outside chart\r\n\tvar yf; // function to get the y alignment if the tooltip goes outside of the left or right edges\r\n\tvar midX = (chartArea.left + chartArea.right) / 2;\r\n\tvar midY = (chartArea.top + chartArea.bottom) / 2;\r\n\r\n\tif (yAlign === 'center') {\r\n\t\tlf = function(x) {\r\n\t\t\treturn x <= midX;\r\n\t\t};\r\n\t\trf = function(x) {\r\n\t\t\treturn x > midX;\r\n\t\t};\r\n\t} else {\r\n\t\tlf = function(x) {\r\n\t\t\treturn x <= (size.width / 2);\r\n\t\t};\r\n\t\trf = function(x) {\r\n\t\t\treturn x >= (chart.width - (size.width / 2));\r\n\t\t};\r\n\t}\r\n\r\n\tolf = function(x) {\r\n\t\treturn x + size.width + model.caretSize + model.caretPadding > chart.width;\r\n\t};\r\n\torf = function(x) {\r\n\t\treturn x - size.width - model.caretSize - model.caretPadding < 0;\r\n\t};\r\n\tyf = function(y) {\r\n\t\treturn y <= midY ? 'top' : 'bottom';\r\n\t};\r\n\r\n\tif (lf(model.x)) {\r\n\t\txAlign = 'left';\r\n\r\n\t\t// Is tooltip too wide and goes over the right side of the chart.?\r\n\t\tif (olf(model.x)) {\r\n\t\t\txAlign = 'center';\r\n\t\t\tyAlign = yf(model.y);\r\n\t\t}\r\n\t} else if (rf(model.x)) {\r\n\t\txAlign = 'right';\r\n\r\n\t\t// Is tooltip too wide and goes outside left edge of canvas?\r\n\t\tif (orf(model.x)) {\r\n\t\t\txAlign = 'center';\r\n\t\t\tyAlign = yf(model.y);\r\n\t\t}\r\n\t}\r\n\r\n\tvar opts = tooltip._options;\r\n\treturn {\r\n\t\txAlign: opts.xAlign ? opts.xAlign : xAlign,\r\n\t\tyAlign: opts.yAlign ? opts.yAlign : yAlign\r\n\t};\r\n}\r\n\r\n/**\r\n * Helper to get the location a tooltip needs to be placed at given the initial position (via the vm) and the size and alignment\r\n */\r\nfunction getBackgroundPoint(vm, size, alignment, chart) {\r\n\t// Background Position\r\n\tvar x = vm.x;\r\n\tvar y = vm.y;\r\n\r\n\tvar caretSize = vm.caretSize;\r\n\tvar caretPadding = vm.caretPadding;\r\n\tvar cornerRadius = vm.cornerRadius;\r\n\tvar xAlign = alignment.xAlign;\r\n\tvar yAlign = alignment.yAlign;\r\n\tvar paddingAndSize = caretSize + caretPadding;\r\n\tvar radiusAndPadding = cornerRadius + caretPadding;\r\n\r\n\tif (xAlign === 'right') {\r\n\t\tx -= size.width;\r\n\t} else if (xAlign === 'center') {\r\n\t\tx -= (size.width / 2);\r\n\t\tif (x + size.width > chart.width) {\r\n\t\t\tx = chart.width - size.width;\r\n\t\t}\r\n\t\tif (x < 0) {\r\n\t\t\tx = 0;\r\n\t\t}\r\n\t}\r\n\r\n\tif (yAlign === 'top') {\r\n\t\ty += paddingAndSize;\r\n\t} else if (yAlign === 'bottom') {\r\n\t\ty -= size.height + paddingAndSize;\r\n\t} else {\r\n\t\ty -= (size.height / 2);\r\n\t}\r\n\r\n\tif (yAlign === 'center') {\r\n\t\tif (xAlign === 'left') {\r\n\t\t\tx += paddingAndSize;\r\n\t\t} else if (xAlign === 'right') {\r\n\t\t\tx -= paddingAndSize;\r\n\t\t}\r\n\t} else if (xAlign === 'left') {\r\n\t\tx -= radiusAndPadding;\r\n\t} else if (xAlign === 'right') {\r\n\t\tx += radiusAndPadding;\r\n\t}\r\n\r\n\treturn {\r\n\t\tx: x,\r\n\t\ty: y\r\n\t};\r\n}\r\n\r\nfunction getAlignedX(vm, align) {\r\n\treturn align === 'center'\r\n\t\t? vm.x + vm.width / 2\r\n\t\t: align === 'right'\r\n\t\t\t? vm.x + vm.width - vm.xPadding\r\n\t\t\t: vm.x + vm.xPadding;\r\n}\r\n\r\n/**\r\n * Helper to build before and after body lines\r\n */\r\nfunction getBeforeAfterBodyLines(callback) {\r\n\treturn pushOrConcat([], splitNewlines(callback));\r\n}\r\n\r\nvar exports$4 = core_element.extend({\r\n\tinitialize: function() {\r\n\t\tthis._model = getBaseModel(this._options);\r\n\t\tthis._lastActive = [];\r\n\t},\r\n\r\n\t// Get the title\r\n\t// Args are: (tooltipItem, data)\r\n\tgetTitle: function() {\r\n\t\tvar me = this;\r\n\t\tvar opts = me._options;\r\n\t\tvar callbacks = opts.callbacks;\r\n\r\n\t\tvar beforeTitle = callbacks.beforeTitle.apply(me, arguments);\r\n\t\tvar title = callbacks.title.apply(me, arguments);\r\n\t\tvar afterTitle = callbacks.afterTitle.apply(me, arguments);\r\n\r\n\t\tvar lines = [];\r\n\t\tlines = pushOrConcat(lines, splitNewlines(beforeTitle));\r\n\t\tlines = pushOrConcat(lines, splitNewlines(title));\r\n\t\tlines = pushOrConcat(lines, splitNewlines(afterTitle));\r\n\r\n\t\treturn lines;\r\n\t},\r\n\r\n\t// Args are: (tooltipItem, data)\r\n\tgetBeforeBody: function() {\r\n\t\treturn getBeforeAfterBodyLines(this._options.callbacks.beforeBody.apply(this, arguments));\r\n\t},\r\n\r\n\t// Args are: (tooltipItem, data)\r\n\tgetBody: function(tooltipItems, data) {\r\n\t\tvar me = this;\r\n\t\tvar callbacks = me._options.callbacks;\r\n\t\tvar bodyItems = [];\r\n\r\n\t\thelpers$1.each(tooltipItems, function(tooltipItem) {\r\n\t\t\tvar bodyItem = {\r\n\t\t\t\tbefore: [],\r\n\t\t\t\tlines: [],\r\n\t\t\t\tafter: []\r\n\t\t\t};\r\n\t\t\tpushOrConcat(bodyItem.before, splitNewlines(callbacks.beforeLabel.call(me, tooltipItem, data)));\r\n\t\t\tpushOrConcat(bodyItem.lines, callbacks.label.call(me, tooltipItem, data));\r\n\t\t\tpushOrConcat(bodyItem.after, splitNewlines(callbacks.afterLabel.call(me, tooltipItem, data)));\r\n\r\n\t\t\tbodyItems.push(bodyItem);\r\n\t\t});\r\n\r\n\t\treturn bodyItems;\r\n\t},\r\n\r\n\t// Args are: (tooltipItem, data)\r\n\tgetAfterBody: function() {\r\n\t\treturn getBeforeAfterBodyLines(this._options.callbacks.afterBody.apply(this, arguments));\r\n\t},\r\n\r\n\t// Get the footer and beforeFooter and afterFooter lines\r\n\t// Args are: (tooltipItem, data)\r\n\tgetFooter: function() {\r\n\t\tvar me = this;\r\n\t\tvar callbacks = me._options.callbacks;\r\n\r\n\t\tvar beforeFooter = callbacks.beforeFooter.apply(me, arguments);\r\n\t\tvar footer = callbacks.footer.apply(me, arguments);\r\n\t\tvar afterFooter = callbacks.afterFooter.apply(me, arguments);\r\n\r\n\t\tvar lines = [];\r\n\t\tlines = pushOrConcat(lines, splitNewlines(beforeFooter));\r\n\t\tlines = pushOrConcat(lines, splitNewlines(footer));\r\n\t\tlines = pushOrConcat(lines, splitNewlines(afterFooter));\r\n\r\n\t\treturn lines;\r\n\t},\r\n\r\n\tupdate: function(changed) {\r\n\t\tvar me = this;\r\n\t\tvar opts = me._options;\r\n\r\n\t\t// Need to regenerate the model because its faster than using extend and it is necessary due to the optimization in Chart.Element.transition\r\n\t\t// that does _view = _model if ease === 1. This causes the 2nd tooltip update to set properties in both the view and model at the same time\r\n\t\t// which breaks any animations.\r\n\t\tvar existingModel = me._model;\r\n\t\tvar model = me._model = getBaseModel(opts);\r\n\t\tvar active = me._active;\r\n\r\n\t\tvar data = me._data;\r\n\r\n\t\t// In the case where active.length === 0 we need to keep these at existing values for good animations\r\n\t\tvar alignment = {\r\n\t\t\txAlign: existingModel.xAlign,\r\n\t\t\tyAlign: existingModel.yAlign\r\n\t\t};\r\n\t\tvar backgroundPoint = {\r\n\t\t\tx: existingModel.x,\r\n\t\t\ty: existingModel.y\r\n\t\t};\r\n\t\tvar tooltipSize = {\r\n\t\t\twidth: existingModel.width,\r\n\t\t\theight: existingModel.height\r\n\t\t};\r\n\t\tvar tooltipPosition = {\r\n\t\t\tx: existingModel.caretX,\r\n\t\t\ty: existingModel.caretY\r\n\t\t};\r\n\r\n\t\tvar i, len;\r\n\r\n\t\tif (active.length) {\r\n\t\t\tmodel.opacity = 1;\r\n\r\n\t\t\tvar labelColors = [];\r\n\t\t\tvar labelTextColors = [];\r\n\t\t\ttooltipPosition = positioners[opts.position].call(me, active, me._eventPosition);\r\n\r\n\t\t\tvar tooltipItems = [];\r\n\t\t\tfor (i = 0, len = active.length; i < len; ++i) {\r\n\t\t\t\ttooltipItems.push(createTooltipItem(active[i]));\r\n\t\t\t}\r\n\r\n\t\t\t// If the user provided a filter function, use it to modify the tooltip items\r\n\t\t\tif (opts.filter) {\r\n\t\t\t\ttooltipItems = tooltipItems.filter(function(a) {\r\n\t\t\t\t\treturn opts.filter(a, data);\r\n\t\t\t\t});\r\n\t\t\t}\r\n\r\n\t\t\t// If the user provided a sorting function, use it to modify the tooltip items\r\n\t\t\tif (opts.itemSort) {\r\n\t\t\t\ttooltipItems = tooltipItems.sort(function(a, b) {\r\n\t\t\t\t\treturn opts.itemSort(a, b, data);\r\n\t\t\t\t});\r\n\t\t\t}\r\n\r\n\t\t\t// Determine colors for boxes\r\n\t\t\thelpers$1.each(tooltipItems, function(tooltipItem) {\r\n\t\t\t\tlabelColors.push(opts.callbacks.labelColor.call(me, tooltipItem, me._chart));\r\n\t\t\t\tlabelTextColors.push(opts.callbacks.labelTextColor.call(me, tooltipItem, me._chart));\r\n\t\t\t});\r\n\r\n\r\n\t\t\t// Build the Text Lines\r\n\t\t\tmodel.title = me.getTitle(tooltipItems, data);\r\n\t\t\tmodel.beforeBody = me.getBeforeBody(tooltipItems, data);\r\n\t\t\tmodel.body = me.getBody(tooltipItems, data);\r\n\t\t\tmodel.afterBody = me.getAfterBody(tooltipItems, data);\r\n\t\t\tmodel.footer = me.getFooter(tooltipItems, data);\r\n\r\n\t\t\t// Initial positioning and colors\r\n\t\t\tmodel.x = tooltipPosition.x;\r\n\t\t\tmodel.y = tooltipPosition.y;\r\n\t\t\tmodel.caretPadding = opts.caretPadding;\r\n\t\t\tmodel.labelColors = labelColors;\r\n\t\t\tmodel.labelTextColors = labelTextColors;\r\n\r\n\t\t\t// data points\r\n\t\t\tmodel.dataPoints = tooltipItems;\r\n\r\n\t\t\t// We need to determine alignment of the tooltip\r\n\t\t\ttooltipSize = getTooltipSize(this, model);\r\n\t\t\talignment = determineAlignment(this, tooltipSize);\r\n\t\t\t// Final Size and Position\r\n\t\t\tbackgroundPoint = getBackgroundPoint(model, tooltipSize, alignment, me._chart);\r\n\t\t} else {\r\n\t\t\tmodel.opacity = 0;\r\n\t\t}\r\n\r\n\t\tmodel.xAlign = alignment.xAlign;\r\n\t\tmodel.yAlign = alignment.yAlign;\r\n\t\tmodel.x = backgroundPoint.x;\r\n\t\tmodel.y = backgroundPoint.y;\r\n\t\tmodel.width = tooltipSize.width;\r\n\t\tmodel.height = tooltipSize.height;\r\n\r\n\t\t// Point where the caret on the tooltip points to\r\n\t\tmodel.caretX = tooltipPosition.x;\r\n\t\tmodel.caretY = tooltipPosition.y;\r\n\r\n\t\tme._model = model;\r\n\r\n\t\tif (changed && opts.custom) {\r\n\t\t\topts.custom.call(me, model);\r\n\t\t}\r\n\r\n\t\treturn me;\r\n\t},\r\n\r\n\tdrawCaret: function(tooltipPoint, size) {\r\n\t\tvar ctx = this._chart.ctx;\r\n\t\tvar vm = this._view;\r\n\t\tvar caretPosition = this.getCaretPosition(tooltipPoint, size, vm);\r\n\r\n\t\tctx.lineTo(caretPosition.x1, caretPosition.y1);\r\n\t\tctx.lineTo(caretPosition.x2, caretPosition.y2);\r\n\t\tctx.lineTo(caretPosition.x3, caretPosition.y3);\r\n\t},\r\n\tgetCaretPosition: function(tooltipPoint, size, vm) {\r\n\t\tvar x1, x2, x3, y1, y2, y3;\r\n\t\tvar caretSize = vm.caretSize;\r\n\t\tvar cornerRadius = vm.cornerRadius;\r\n\t\tvar xAlign = vm.xAlign;\r\n\t\tvar yAlign = vm.yAlign;\r\n\t\tvar ptX = tooltipPoint.x;\r\n\t\tvar ptY = tooltipPoint.y;\r\n\t\tvar width = size.width;\r\n\t\tvar height = size.height;\r\n\r\n\t\tif (yAlign === 'center') {\r\n\t\t\ty2 = ptY + (height / 2);\r\n\r\n\t\t\tif (xAlign === 'left') {\r\n\t\t\t\tx1 = ptX;\r\n\t\t\t\tx2 = x1 - caretSize;\r\n\t\t\t\tx3 = x1;\r\n\r\n\t\t\t\ty1 = y2 + caretSize;\r\n\t\t\t\ty3 = y2 - caretSize;\r\n\t\t\t} else {\r\n\t\t\t\tx1 = ptX + width;\r\n\t\t\t\tx2 = x1 + caretSize;\r\n\t\t\t\tx3 = x1;\r\n\r\n\t\t\t\ty1 = y2 - caretSize;\r\n\t\t\t\ty3 = y2 + caretSize;\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tif (xAlign === 'left') {\r\n\t\t\t\tx2 = ptX + cornerRadius + (caretSize);\r\n\t\t\t\tx1 = x2 - caretSize;\r\n\t\t\t\tx3 = x2 + caretSize;\r\n\t\t\t} else if (xAlign === 'right') {\r\n\t\t\t\tx2 = ptX + width - cornerRadius - caretSize;\r\n\t\t\t\tx1 = x2 - caretSize;\r\n\t\t\t\tx3 = x2 + caretSize;\r\n\t\t\t} else {\r\n\t\t\t\tx2 = vm.caretX;\r\n\t\t\t\tx1 = x2 - caretSize;\r\n\t\t\t\tx3 = x2 + caretSize;\r\n\t\t\t}\r\n\t\t\tif (yAlign === 'top') {\r\n\t\t\t\ty1 = ptY;\r\n\t\t\t\ty2 = y1 - caretSize;\r\n\t\t\t\ty3 = y1;\r\n\t\t\t} else {\r\n\t\t\t\ty1 = ptY + height;\r\n\t\t\t\ty2 = y1 + caretSize;\r\n\t\t\t\ty3 = y1;\r\n\t\t\t\t// invert drawing order\r\n\t\t\t\tvar tmp = x3;\r\n\t\t\t\tx3 = x1;\r\n\t\t\t\tx1 = tmp;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn {x1: x1, x2: x2, x3: x3, y1: y1, y2: y2, y3: y3};\r\n\t},\r\n\r\n\tdrawTitle: function(pt, vm, ctx) {\r\n\t\tvar title = vm.title;\r\n\t\tvar length = title.length;\r\n\t\tvar titleFontSize, titleSpacing, i;\r\n\r\n\t\tif (length) {\r\n\t\t\tvar rtlHelper = getRtlHelper(vm.rtl, vm.x, vm.width);\r\n\r\n\t\t\tpt.x = getAlignedX(vm, vm._titleAlign);\r\n\r\n\t\t\tctx.textAlign = rtlHelper.textAlign(vm._titleAlign);\r\n\t\t\tctx.textBaseline = 'middle';\r\n\r\n\t\t\ttitleFontSize = vm.titleFontSize;\r\n\t\t\ttitleSpacing = vm.titleSpacing;\r\n\r\n\t\t\tctx.fillStyle = vm.titleFontColor;\r\n\t\t\tctx.font = helpers$1.fontString(titleFontSize, vm._titleFontStyle, vm._titleFontFamily);\r\n\r\n\t\t\tfor (i = 0; i < length; ++i) {\r\n\t\t\t\tctx.fillText(title[i], rtlHelper.x(pt.x), pt.y + titleFontSize / 2);\r\n\t\t\t\tpt.y += titleFontSize + titleSpacing; // Line Height and spacing\r\n\r\n\t\t\t\tif (i + 1 === length) {\r\n\t\t\t\t\tpt.y += vm.titleMarginBottom - titleSpacing; // If Last, add margin, remove spacing\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t},\r\n\r\n\tdrawBody: function(pt, vm, ctx) {\r\n\t\tvar bodyFontSize = vm.bodyFontSize;\r\n\t\tvar bodySpacing = vm.bodySpacing;\r\n\t\tvar bodyAlign = vm._bodyAlign;\r\n\t\tvar body = vm.body;\r\n\t\tvar drawColorBoxes = vm.displayColors;\r\n\t\tvar xLinePadding = 0;\r\n\t\tvar colorX = drawColorBoxes ? getAlignedX(vm, 'left') : 0;\r\n\r\n\t\tvar rtlHelper = getRtlHelper(vm.rtl, vm.x, vm.width);\r\n\r\n\t\tvar fillLineOfText = function(line) {\r\n\t\t\tctx.fillText(line, rtlHelper.x(pt.x + xLinePadding), pt.y + bodyFontSize / 2);\r\n\t\t\tpt.y += bodyFontSize + bodySpacing;\r\n\t\t};\r\n\r\n\t\tvar bodyItem, textColor, labelColors, lines, i, j, ilen, jlen;\r\n\t\tvar bodyAlignForCalculation = rtlHelper.textAlign(bodyAlign);\r\n\r\n\t\tctx.textAlign = bodyAlign;\r\n\t\tctx.textBaseline = 'middle';\r\n\t\tctx.font = helpers$1.fontString(bodyFontSize, vm._bodyFontStyle, vm._bodyFontFamily);\r\n\r\n\t\tpt.x = getAlignedX(vm, bodyAlignForCalculation);\r\n\r\n\t\t// Before body lines\r\n\t\tctx.fillStyle = vm.bodyFontColor;\r\n\t\thelpers$1.each(vm.beforeBody, fillLineOfText);\r\n\r\n\t\txLinePadding = drawColorBoxes && bodyAlignForCalculation !== 'right'\r\n\t\t\t? bodyAlign === 'center' ? (bodyFontSize / 2 + 1) : (bodyFontSize + 2)\r\n\t\t\t: 0;\r\n\r\n\t\t// Draw body lines now\r\n\t\tfor (i = 0, ilen = body.length; i < ilen; ++i) {\r\n\t\t\tbodyItem = body[i];\r\n\t\t\ttextColor = vm.labelTextColors[i];\r\n\t\t\tlabelColors = vm.labelColors[i];\r\n\r\n\t\t\tctx.fillStyle = textColor;\r\n\t\t\thelpers$1.each(bodyItem.before, fillLineOfText);\r\n\r\n\t\t\tlines = bodyItem.lines;\r\n\t\t\tfor (j = 0, jlen = lines.length; j < jlen; ++j) {\r\n\t\t\t\t// Draw Legend-like boxes if needed\r\n\t\t\t\tif (drawColorBoxes) {\r\n\t\t\t\t\tvar rtlColorX = rtlHelper.x(colorX);\r\n\r\n\t\t\t\t\t// Fill a white rect so that colours merge nicely if the opacity is < 1\r\n\t\t\t\t\tctx.fillStyle = vm.legendColorBackground;\r\n\t\t\t\t\tctx.fillRect(rtlHelper.leftForLtr(rtlColorX, bodyFontSize), pt.y, bodyFontSize, bodyFontSize);\r\n\r\n\t\t\t\t\t// Border\r\n\t\t\t\t\tctx.lineWidth = 1;\r\n\t\t\t\t\tctx.strokeStyle = labelColors.borderColor;\r\n\t\t\t\t\tctx.strokeRect(rtlHelper.leftForLtr(rtlColorX, bodyFontSize), pt.y, bodyFontSize, bodyFontSize);\r\n\r\n\t\t\t\t\t// Inner square\r\n\t\t\t\t\tctx.fillStyle = labelColors.backgroundColor;\r\n\t\t\t\t\tctx.fillRect(rtlHelper.leftForLtr(rtlHelper.xPlus(rtlColorX, 1), bodyFontSize - 2), pt.y + 1, bodyFontSize - 2, bodyFontSize - 2);\r\n\t\t\t\t\tctx.fillStyle = textColor;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tfillLineOfText(lines[j]);\r\n\t\t\t}\r\n\r\n\t\t\thelpers$1.each(bodyItem.after, fillLineOfText);\r\n\t\t}\r\n\r\n\t\t// Reset back to 0 for after body\r\n\t\txLinePadding = 0;\r\n\r\n\t\t// After body lines\r\n\t\thelpers$1.each(vm.afterBody, fillLineOfText);\r\n\t\tpt.y -= bodySpacing; // Remove last body spacing\r\n\t},\r\n\r\n\tdrawFooter: function(pt, vm, ctx) {\r\n\t\tvar footer = vm.footer;\r\n\t\tvar length = footer.length;\r\n\t\tvar footerFontSize, i;\r\n\r\n\t\tif (length) {\r\n\t\t\tvar rtlHelper = getRtlHelper(vm.rtl, vm.x, vm.width);\r\n\r\n\t\t\tpt.x = getAlignedX(vm, vm._footerAlign);\r\n\t\t\tpt.y += vm.footerMarginTop;\r\n\r\n\t\t\tctx.textAlign = rtlHelper.textAlign(vm._footerAlign);\r\n\t\t\tctx.textBaseline = 'middle';\r\n\r\n\t\t\tfooterFontSize = vm.footerFontSize;\r\n\r\n\t\t\tctx.fillStyle = vm.footerFontColor;\r\n\t\t\tctx.font = helpers$1.fontString(footerFontSize, vm._footerFontStyle, vm._footerFontFamily);\r\n\r\n\t\t\tfor (i = 0; i < length; ++i) {\r\n\t\t\t\tctx.fillText(footer[i], rtlHelper.x(pt.x), pt.y + footerFontSize / 2);\r\n\t\t\t\tpt.y += footerFontSize + vm.footerSpacing;\r\n\t\t\t}\r\n\t\t}\r\n\t},\r\n\r\n\tdrawBackground: function(pt, vm, ctx, tooltipSize) {\r\n\t\tctx.fillStyle = vm.backgroundColor;\r\n\t\tctx.strokeStyle = vm.borderColor;\r\n\t\tctx.lineWidth = vm.borderWidth;\r\n\t\tvar xAlign = vm.xAlign;\r\n\t\tvar yAlign = vm.yAlign;\r\n\t\tvar x = pt.x;\r\n\t\tvar y = pt.y;\r\n\t\tvar width = tooltipSize.width;\r\n\t\tvar height = tooltipSize.height;\r\n\t\tvar radius = vm.cornerRadius;\r\n\r\n\t\tctx.beginPath();\r\n\t\tctx.moveTo(x + radius, y);\r\n\t\tif (yAlign === 'top') {\r\n\t\t\tthis.drawCaret(pt, tooltipSize);\r\n\t\t}\r\n\t\tctx.lineTo(x + width - radius, y);\r\n\t\tctx.quadraticCurveTo(x + width, y, x + width, y + radius);\r\n\t\tif (yAlign === 'center' && xAlign === 'right') {\r\n\t\t\tthis.drawCaret(pt, tooltipSize);\r\n\t\t}\r\n\t\tctx.lineTo(x + width, y + height - radius);\r\n\t\tctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);\r\n\t\tif (yAlign === 'bottom') {\r\n\t\t\tthis.drawCaret(pt, tooltipSize);\r\n\t\t}\r\n\t\tctx.lineTo(x + radius, y + height);\r\n\t\tctx.quadraticCurveTo(x, y + height, x, y + height - radius);\r\n\t\tif (yAlign === 'center' && xAlign === 'left') {\r\n\t\t\tthis.drawCaret(pt, tooltipSize);\r\n\t\t}\r\n\t\tctx.lineTo(x, y + radius);\r\n\t\tctx.quadraticCurveTo(x, y, x + radius, y);\r\n\t\tctx.closePath();\r\n\r\n\t\tctx.fill();\r\n\r\n\t\tif (vm.borderWidth > 0) {\r\n\t\t\tctx.stroke();\r\n\t\t}\r\n\t},\r\n\r\n\tdraw: function() {\r\n\t\tvar ctx = this._chart.ctx;\r\n\t\tvar vm = this._view;\r\n\r\n\t\tif (vm.opacity === 0) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tvar tooltipSize = {\r\n\t\t\twidth: vm.width,\r\n\t\t\theight: vm.height\r\n\t\t};\r\n\t\tvar pt = {\r\n\t\t\tx: vm.x,\r\n\t\t\ty: vm.y\r\n\t\t};\r\n\r\n\t\t// IE11/Edge does not like very small opacities, so snap to 0\r\n\t\tvar opacity = Math.abs(vm.opacity < 1e-3) ? 0 : vm.opacity;\r\n\r\n\t\t// Truthy/falsey value for empty tooltip\r\n\t\tvar hasTooltipContent = vm.title.length || vm.beforeBody.length || vm.body.length || vm.afterBody.length || vm.footer.length;\r\n\r\n\t\tif (this._options.enabled && hasTooltipContent) {\r\n\t\t\tctx.save();\r\n\t\t\tctx.globalAlpha = opacity;\r\n\r\n\t\t\t// Draw Background\r\n\t\t\tthis.drawBackground(pt, vm, ctx, tooltipSize);\r\n\r\n\t\t\t// Draw Title, Body, and Footer\r\n\t\t\tpt.y += vm.yPadding;\r\n\r\n\t\t\thelpers$1.rtl.overrideTextDirection(ctx, vm.textDirection);\r\n\r\n\t\t\t// Titles\r\n\t\t\tthis.drawTitle(pt, vm, ctx);\r\n\r\n\t\t\t// Body\r\n\t\t\tthis.drawBody(pt, vm, ctx);\r\n\r\n\t\t\t// Footer\r\n\t\t\tthis.drawFooter(pt, vm, ctx);\r\n\r\n\t\t\thelpers$1.rtl.restoreTextDirection(ctx, vm.textDirection);\r\n\r\n\t\t\tctx.restore();\r\n\t\t}\r\n\t},\r\n\r\n\t/**\r\n\t * Handle an event\r\n\t * @private\r\n\t * @param {IEvent} event - The event to handle\r\n\t * @returns {boolean} true if the tooltip changed\r\n\t */\r\n\thandleEvent: function(e) {\r\n\t\tvar me = this;\r\n\t\tvar options = me._options;\r\n\t\tvar changed = false;\r\n\r\n\t\tme._lastActive = me._lastActive || [];\r\n\r\n\t\t// Find Active Elements for tooltips\r\n\t\tif (e.type === 'mouseout') {\r\n\t\t\tme._active = [];\r\n\t\t} else {\r\n\t\t\tme._active = me._chart.getElementsAtEventForMode(e, options.mode, options);\r\n\t\t\tif (options.reverse) {\r\n\t\t\t\tme._active.reverse();\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Remember Last Actives\r\n\t\tchanged = !helpers$1.arrayEquals(me._active, me._lastActive);\r\n\r\n\t\t// Only handle target event on tooltip change\r\n\t\tif (changed) {\r\n\t\t\tme._lastActive = me._active;\r\n\r\n\t\t\tif (options.enabled || options.custom) {\r\n\t\t\t\tme._eventPosition = {\r\n\t\t\t\t\tx: e.x,\r\n\t\t\t\t\ty: e.y\r\n\t\t\t\t};\r\n\r\n\t\t\t\tme.update(true);\r\n\t\t\t\tme.pivot();\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn changed;\r\n\t}\r\n});\r\n\r\n/**\r\n * @namespace Chart.Tooltip.positioners\r\n */\r\nvar positioners_1 = positioners;\r\n\r\nvar core_tooltip = exports$4;\ncore_tooltip.positioners = positioners_1;\n\nvar valueOrDefault$9 = helpers$1.valueOrDefault;\r\n\r\ncore_defaults._set('global', {\r\n\telements: {},\r\n\tevents: [\r\n\t\t'mousemove',\r\n\t\t'mouseout',\r\n\t\t'click',\r\n\t\t'touchstart',\r\n\t\t'touchmove'\r\n\t],\r\n\thover: {\r\n\t\tonHover: null,\r\n\t\tmode: 'nearest',\r\n\t\tintersect: true,\r\n\t\tanimationDuration: 400\r\n\t},\r\n\tonClick: null,\r\n\tmaintainAspectRatio: true,\r\n\tresponsive: true,\r\n\tresponsiveAnimationDuration: 0\r\n});\r\n\r\n/**\r\n * Recursively merge the given config objects representing the `scales` option\r\n * by incorporating scale defaults in `xAxes` and `yAxes` array items, then\r\n * returns a deep copy of the result, thus doesn't alter inputs.\r\n */\r\nfunction mergeScaleConfig(/* config objects ... */) {\r\n\treturn helpers$1.merge(Object.create(null), [].slice.call(arguments), {\r\n\t\tmerger: function(key, target, source, options) {\r\n\t\t\tif (key === 'xAxes' || key === 'yAxes') {\r\n\t\t\t\tvar slen = source[key].length;\r\n\t\t\t\tvar i, type, scale;\r\n\r\n\t\t\t\tif (!target[key]) {\r\n\t\t\t\t\ttarget[key] = [];\r\n\t\t\t\t}\r\n\r\n\t\t\t\tfor (i = 0; i < slen; ++i) {\r\n\t\t\t\t\tscale = source[key][i];\r\n\t\t\t\t\ttype = valueOrDefault$9(scale.type, key === 'xAxes' ? 'category' : 'linear');\r\n\r\n\t\t\t\t\tif (i >= target[key].length) {\r\n\t\t\t\t\t\ttarget[key].push({});\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tif (!target[key][i].type || (scale.type && scale.type !== target[key][i].type)) {\r\n\t\t\t\t\t\t// new/untyped scale or type changed: let's apply the new defaults\r\n\t\t\t\t\t\t// then merge source scale to correctly overwrite the defaults.\r\n\t\t\t\t\t\thelpers$1.merge(target[key][i], [core_scaleService.getScaleDefaults(type), scale]);\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\t// scales type are the same\r\n\t\t\t\t\t\thelpers$1.merge(target[key][i], scale);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\thelpers$1._merger(key, target, source, options);\r\n\t\t\t}\r\n\t\t}\r\n\t});\r\n}\r\n\r\n/**\r\n * Recursively merge the given config objects as the root options by handling\r\n * default scale options for the `scales` and `scale` properties, then returns\r\n * a deep copy of the result, thus doesn't alter inputs.\r\n */\r\nfunction mergeConfig(/* config objects ... */) {\r\n\treturn helpers$1.merge(Object.create(null), [].slice.call(arguments), {\r\n\t\tmerger: function(key, target, source, options) {\r\n\t\t\tvar tval = target[key] || Object.create(null);\r\n\t\t\tvar sval = source[key];\r\n\r\n\t\t\tif (key === 'scales') {\r\n\t\t\t\t// scale config merging is complex. Add our own function here for that\r\n\t\t\t\ttarget[key] = mergeScaleConfig(tval, sval);\r\n\t\t\t} else if (key === 'scale') {\r\n\t\t\t\t// used in polar area & radar charts since there is only one scale\r\n\t\t\t\ttarget[key] = helpers$1.merge(tval, [core_scaleService.getScaleDefaults(sval.type), sval]);\r\n\t\t\t} else {\r\n\t\t\t\thelpers$1._merger(key, target, source, options);\r\n\t\t\t}\r\n\t\t}\r\n\t});\r\n}\r\n\r\nfunction initConfig(config) {\r\n\tconfig = config || Object.create(null);\r\n\r\n\t// Do NOT use mergeConfig for the data object because this method merges arrays\r\n\t// and so would change references to labels and datasets, preventing data updates.\r\n\tvar data = config.data = config.data || {};\r\n\tdata.datasets = data.datasets || [];\r\n\tdata.labels = data.labels || [];\r\n\r\n\tconfig.options = mergeConfig(\r\n\t\tcore_defaults.global,\r\n\t\tcore_defaults[config.type],\r\n\t\tconfig.options || {});\r\n\r\n\treturn config;\r\n}\r\n\r\nfunction updateConfig(chart) {\r\n\tvar newOptions = chart.options;\r\n\r\n\thelpers$1.each(chart.scales, function(scale) {\r\n\t\tcore_layouts.removeBox(chart, scale);\r\n\t});\r\n\r\n\tnewOptions = mergeConfig(\r\n\t\tcore_defaults.global,\r\n\t\tcore_defaults[chart.config.type],\r\n\t\tnewOptions);\r\n\r\n\tchart.options = chart.config.options = newOptions;\r\n\tchart.ensureScalesHaveIDs();\r\n\tchart.buildOrUpdateScales();\r\n\r\n\t// Tooltip\r\n\tchart.tooltip._options = newOptions.tooltips;\r\n\tchart.tooltip.initialize();\r\n}\r\n\r\nfunction nextAvailableScaleId(axesOpts, prefix, index) {\r\n\tvar id;\r\n\tvar hasId = function(obj) {\r\n\t\treturn obj.id === id;\r\n\t};\r\n\r\n\tdo {\r\n\t\tid = prefix + index++;\r\n\t} while (helpers$1.findIndex(axesOpts, hasId) >= 0);\r\n\r\n\treturn id;\r\n}\r\n\r\nfunction positionIsHorizontal(position) {\r\n\treturn position === 'top' || position === 'bottom';\r\n}\r\n\r\nfunction compare2Level(l1, l2) {\r\n\treturn function(a, b) {\r\n\t\treturn a[l1] === b[l1]\r\n\t\t\t? a[l2] - b[l2]\r\n\t\t\t: a[l1] - b[l1];\r\n\t};\r\n}\r\n\r\nvar Chart = function(item, config) {\r\n\tthis.construct(item, config);\r\n\treturn this;\r\n};\r\n\r\nhelpers$1.extend(Chart.prototype, /** @lends Chart */ {\r\n\t/**\r\n\t * @private\r\n\t */\r\n\tconstruct: function(item, config) {\r\n\t\tvar me = this;\r\n\r\n\t\tconfig = initConfig(config);\r\n\r\n\t\tvar context = platform.acquireContext(item, config);\r\n\t\tvar canvas = context && context.canvas;\r\n\t\tvar height = canvas && canvas.height;\r\n\t\tvar width = canvas && canvas.width;\r\n\r\n\t\tme.id = helpers$1.uid();\r\n\t\tme.ctx = context;\r\n\t\tme.canvas = canvas;\r\n\t\tme.config = config;\r\n\t\tme.width = width;\r\n\t\tme.height = height;\r\n\t\tme.aspectRatio = height ? width / height : null;\r\n\t\tme.options = config.options;\r\n\t\tme._bufferedRender = false;\r\n\t\tme._layers = [];\r\n\r\n\t\t/**\r\n\t\t * Provided for backward compatibility, Chart and Chart.Controller have been merged,\r\n\t\t * the \"instance\" still need to be defined since it might be called from plugins.\r\n\t\t * @prop Chart#chart\r\n\t\t * @deprecated since version 2.6.0\r\n\t\t * @todo remove at version 3\r\n\t\t * @private\r\n\t\t */\r\n\t\tme.chart = me;\r\n\t\tme.controller = me; // chart.chart.controller #inception\r\n\r\n\t\t// Add the chart instance to the global namespace\r\n\t\tChart.instances[me.id] = me;\r\n\r\n\t\t// Define alias to the config data: `chart.data === chart.config.data`\r\n\t\tObject.defineProperty(me, 'data', {\r\n\t\t\tget: function() {\r\n\t\t\t\treturn me.config.data;\r\n\t\t\t},\r\n\t\t\tset: function(value) {\r\n\t\t\t\tme.config.data = value;\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tif (!context || !canvas) {\r\n\t\t\t// The given item is not a compatible context2d element, let's return before finalizing\r\n\t\t\t// the chart initialization but after setting basic chart / controller properties that\r\n\t\t\t// can help to figure out that the chart is not valid (e.g chart.canvas !== null);\r\n\t\t\t// https://github.com/chartjs/Chart.js/issues/2807\r\n\t\t\tconsole.error(\"Failed to create chart: can't acquire context from the given item\");\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tme.initialize();\r\n\t\tme.update();\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\tinitialize: function() {\r\n\t\tvar me = this;\r\n\r\n\t\t// Before init plugin notification\r\n\t\tcore_plugins.notify(me, 'beforeInit');\r\n\r\n\t\thelpers$1.retinaScale(me, me.options.devicePixelRatio);\r\n\r\n\t\tme.bindEvents();\r\n\r\n\t\tif (me.options.responsive) {\r\n\t\t\t// Initial resize before chart draws (must be silent to preserve initial animations).\r\n\t\t\tme.resize(true);\r\n\t\t}\r\n\r\n\t\tme.initToolTip();\r\n\r\n\t\t// After init plugin notification\r\n\t\tcore_plugins.notify(me, 'afterInit');\r\n\r\n\t\treturn me;\r\n\t},\r\n\r\n\tclear: function() {\r\n\t\thelpers$1.canvas.clear(this);\r\n\t\treturn this;\r\n\t},\r\n\r\n\tstop: function() {\r\n\t\t// Stops any current animation loop occurring\r\n\t\tcore_animations.cancelAnimation(this);\r\n\t\treturn this;\r\n\t},\r\n\r\n\tresize: function(silent) {\r\n\t\tvar me = this;\r\n\t\tvar options = me.options;\r\n\t\tvar canvas = me.canvas;\r\n\t\tvar aspectRatio = (options.maintainAspectRatio && me.aspectRatio) || null;\r\n\r\n\t\t// the canvas render width and height will be casted to integers so make sure that\r\n\t\t// the canvas display style uses the same integer values to avoid blurring effect.\r\n\r\n\t\t// Set to 0 instead of canvas.size because the size defaults to 300x150 if the element is collapsed\r\n\t\tvar newWidth = Math.max(0, Math.floor(helpers$1.getMaximumWidth(canvas)));\r\n\t\tvar newHeight = Math.max(0, Math.floor(aspectRatio ? newWidth / aspectRatio : helpers$1.getMaximumHeight(canvas)));\r\n\r\n\t\tif (me.width === newWidth && me.height === newHeight) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tcanvas.width = me.width = newWidth;\r\n\t\tcanvas.height = me.height = newHeight;\r\n\t\tcanvas.style.width = newWidth + 'px';\r\n\t\tcanvas.style.height = newHeight + 'px';\r\n\r\n\t\thelpers$1.retinaScale(me, options.devicePixelRatio);\r\n\r\n\t\tif (!silent) {\r\n\t\t\t// Notify any plugins about the resize\r\n\t\t\tvar newSize = {width: newWidth, height: newHeight};\r\n\t\t\tcore_plugins.notify(me, 'resize', [newSize]);\r\n\r\n\t\t\t// Notify of resize\r\n\t\t\tif (options.onResize) {\r\n\t\t\t\toptions.onResize(me, newSize);\r\n\t\t\t}\r\n\r\n\t\t\tme.stop();\r\n\t\t\tme.update({\r\n\t\t\t\tduration: options.responsiveAnimationDuration\r\n\t\t\t});\r\n\t\t}\r\n\t},\r\n\r\n\tensureScalesHaveIDs: function() {\r\n\t\tvar options = this.options;\r\n\t\tvar scalesOptions = options.scales || {};\r\n\t\tvar scaleOptions = options.scale;\r\n\r\n\t\thelpers$1.each(scalesOptions.xAxes, function(xAxisOptions, index) {\r\n\t\t\tif (!xAxisOptions.id) {\r\n\t\t\t\txAxisOptions.id = nextAvailableScaleId(scalesOptions.xAxes, 'x-axis-', index);\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\thelpers$1.each(scalesOptions.yAxes, function(yAxisOptions, index) {\r\n\t\t\tif (!yAxisOptions.id) {\r\n\t\t\t\tyAxisOptions.id = nextAvailableScaleId(scalesOptions.yAxes, 'y-axis-', index);\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tif (scaleOptions) {\r\n\t\t\tscaleOptions.id = scaleOptions.id || 'scale';\r\n\t\t}\r\n\t},\r\n\r\n\t/**\r\n\t * Builds a map of scale ID to scale object for future lookup.\r\n\t */\r\n\tbuildOrUpdateScales: function() {\r\n\t\tvar me = this;\r\n\t\tvar options = me.options;\r\n\t\tvar scales = me.scales || {};\r\n\t\tvar items = [];\r\n\t\tvar updated = Object.keys(scales).reduce(function(obj, id) {\r\n\t\t\tobj[id] = false;\r\n\t\t\treturn obj;\r\n\t\t}, {});\r\n\r\n\t\tif (options.scales) {\r\n\t\t\titems = items.concat(\r\n\t\t\t\t(options.scales.xAxes || []).map(function(xAxisOptions) {\r\n\t\t\t\t\treturn {options: xAxisOptions, dtype: 'category', dposition: 'bottom'};\r\n\t\t\t\t}),\r\n\t\t\t\t(options.scales.yAxes || []).map(function(yAxisOptions) {\r\n\t\t\t\t\treturn {options: yAxisOptions, dtype: 'linear', dposition: 'left'};\r\n\t\t\t\t})\r\n\t\t\t);\r\n\t\t}\r\n\r\n\t\tif (options.scale) {\r\n\t\t\titems.push({\r\n\t\t\t\toptions: options.scale,\r\n\t\t\t\tdtype: 'radialLinear',\r\n\t\t\t\tisDefault: true,\r\n\t\t\t\tdposition: 'chartArea'\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\thelpers$1.each(items, function(item) {\r\n\t\t\tvar scaleOptions = item.options;\r\n\t\t\tvar id = scaleOptions.id;\r\n\t\t\tvar scaleType = valueOrDefault$9(scaleOptions.type, item.dtype);\r\n\r\n\t\t\tif (positionIsHorizontal(scaleOptions.position) !== positionIsHorizontal(item.dposition)) {\r\n\t\t\t\tscaleOptions.position = item.dposition;\r\n\t\t\t}\r\n\r\n\t\t\tupdated[id] = true;\r\n\t\t\tvar scale = null;\r\n\t\t\tif (id in scales && scales[id].type === scaleType) {\r\n\t\t\t\tscale = scales[id];\r\n\t\t\t\tscale.options = scaleOptions;\r\n\t\t\t\tscale.ctx = me.ctx;\r\n\t\t\t\tscale.chart = me;\r\n\t\t\t} else {\r\n\t\t\t\tvar scaleClass = core_scaleService.getScaleConstructor(scaleType);\r\n\t\t\t\tif (!scaleClass) {\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t\tscale = new scaleClass({\r\n\t\t\t\t\tid: id,\r\n\t\t\t\t\ttype: scaleType,\r\n\t\t\t\t\toptions: scaleOptions,\r\n\t\t\t\t\tctx: me.ctx,\r\n\t\t\t\t\tchart: me\r\n\t\t\t\t});\r\n\t\t\t\tscales[scale.id] = scale;\r\n\t\t\t}\r\n\r\n\t\t\tscale.mergeTicksOptions();\r\n\r\n\t\t\t// TODO(SB): I think we should be able to remove this custom case (options.scale)\r\n\t\t\t// and consider it as a regular scale part of the \"scales\"\" map only! This would\r\n\t\t\t// make the logic easier and remove some useless? custom code.\r\n\t\t\tif (item.isDefault) {\r\n\t\t\t\tme.scale = scale;\r\n\t\t\t}\r\n\t\t});\r\n\t\t// clear up discarded scales\r\n\t\thelpers$1.each(updated, function(hasUpdated, id) {\r\n\t\t\tif (!hasUpdated) {\r\n\t\t\t\tdelete scales[id];\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tme.scales = scales;\r\n\r\n\t\tcore_scaleService.addScalesToLayout(this);\r\n\t},\r\n\r\n\tbuildOrUpdateControllers: function() {\r\n\t\tvar me = this;\r\n\t\tvar newControllers = [];\r\n\t\tvar datasets = me.data.datasets;\r\n\t\tvar i, ilen;\r\n\r\n\t\tfor (i = 0, ilen = datasets.length; i < ilen; i++) {\r\n\t\t\tvar dataset = datasets[i];\r\n\t\t\tvar meta = me.getDatasetMeta(i);\r\n\t\t\tvar type = dataset.type || me.config.type;\r\n\r\n\t\t\tif (meta.type && meta.type !== type) {\r\n\t\t\t\tme.destroyDatasetMeta(i);\r\n\t\t\t\tmeta = me.getDatasetMeta(i);\r\n\t\t\t}\r\n\t\t\tmeta.type = type;\r\n\t\t\tmeta.order = dataset.order || 0;\r\n\t\t\tmeta.index = i;\r\n\r\n\t\t\tif (meta.controller) {\r\n\t\t\t\tmeta.controller.updateIndex(i);\r\n\t\t\t\tmeta.controller.linkScales();\r\n\t\t\t} else {\r\n\t\t\t\tvar ControllerClass = controllers[meta.type];\r\n\t\t\t\tif (ControllerClass === undefined) {\r\n\t\t\t\t\tthrow new Error('\"' + meta.type + '\" is not a chart type.');\r\n\t\t\t\t}\r\n\r\n\t\t\t\tmeta.controller = new ControllerClass(me, i);\r\n\t\t\t\tnewControllers.push(meta.controller);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn newControllers;\r\n\t},\r\n\r\n\t/**\r\n\t * Reset the elements of all datasets\r\n\t * @private\r\n\t */\r\n\tresetElements: function() {\r\n\t\tvar me = this;\r\n\t\thelpers$1.each(me.data.datasets, function(dataset, datasetIndex) {\r\n\t\t\tme.getDatasetMeta(datasetIndex).controller.reset();\r\n\t\t}, me);\r\n\t},\r\n\r\n\t/**\r\n\t* Resets the chart back to it's state before the initial animation\r\n\t*/\r\n\treset: function() {\r\n\t\tthis.resetElements();\r\n\t\tthis.tooltip.initialize();\r\n\t},\r\n\r\n\tupdate: function(config) {\r\n\t\tvar me = this;\r\n\t\tvar i, ilen;\r\n\r\n\t\tif (!config || typeof config !== 'object') {\r\n\t\t\t// backwards compatibility\r\n\t\t\tconfig = {\r\n\t\t\t\tduration: config,\r\n\t\t\t\tlazy: arguments[1]\r\n\t\t\t};\r\n\t\t}\r\n\r\n\t\tupdateConfig(me);\r\n\r\n\t\t// plugins options references might have change, let's invalidate the cache\r\n\t\t// https://github.com/chartjs/Chart.js/issues/5111#issuecomment-355934167\r\n\t\tcore_plugins._invalidate(me);\r\n\r\n\t\tif (core_plugins.notify(me, 'beforeUpdate') === false) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// In case the entire data object changed\r\n\t\tme.tooltip._data = me.data;\r\n\r\n\t\t// Make sure dataset controllers are updated and new controllers are reset\r\n\t\tvar newControllers = me.buildOrUpdateControllers();\r\n\r\n\t\t// Make sure all dataset controllers have correct meta data counts\r\n\t\tfor (i = 0, ilen = me.data.datasets.length; i < ilen; i++) {\r\n\t\t\tme.getDatasetMeta(i).controller.buildOrUpdateElements();\r\n\t\t}\r\n\r\n\t\tme.updateLayout();\r\n\r\n\t\t// Can only reset the new controllers after the scales have been updated\r\n\t\tif (me.options.animation && me.options.animation.duration) {\r\n\t\t\thelpers$1.each(newControllers, function(controller) {\r\n\t\t\t\tcontroller.reset();\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tme.updateDatasets();\r\n\r\n\t\t// Need to reset tooltip in case it is displayed with elements that are removed\r\n\t\t// after update.\r\n\t\tme.tooltip.initialize();\r\n\r\n\t\t// Last active contains items that were previously in the tooltip.\r\n\t\t// When we reset the tooltip, we need to clear it\r\n\t\tme.lastActive = [];\r\n\r\n\t\t// Do this before render so that any plugins that need final scale updates can use it\r\n\t\tcore_plugins.notify(me, 'afterUpdate');\r\n\r\n\t\tme._layers.sort(compare2Level('z', '_idx'));\r\n\r\n\t\tif (me._bufferedRender) {\r\n\t\t\tme._bufferedRequest = {\r\n\t\t\t\tduration: config.duration,\r\n\t\t\t\teasing: config.easing,\r\n\t\t\t\tlazy: config.lazy\r\n\t\t\t};\r\n\t\t} else {\r\n\t\t\tme.render(config);\r\n\t\t}\r\n\t},\r\n\r\n\t/**\r\n\t * Updates the chart layout unless a plugin returns `false` to the `beforeLayout`\r\n\t * hook, in which case, plugins will not be called on `afterLayout`.\r\n\t * @private\r\n\t */\r\n\tupdateLayout: function() {\r\n\t\tvar me = this;\r\n\r\n\t\tif (core_plugins.notify(me, 'beforeLayout') === false) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tcore_layouts.update(this, this.width, this.height);\r\n\r\n\t\tme._layers = [];\r\n\t\thelpers$1.each(me.boxes, function(box) {\r\n\t\t\t// _configure is called twice, once in core.scale.update and once here.\r\n\t\t\t// Here the boxes are fully updated and at their final positions.\r\n\t\t\tif (box._configure) {\r\n\t\t\t\tbox._configure();\r\n\t\t\t}\r\n\t\t\tme._layers.push.apply(me._layers, box._layers());\r\n\t\t}, me);\r\n\r\n\t\tme._layers.forEach(function(item, index) {\r\n\t\t\titem._idx = index;\r\n\t\t});\r\n\r\n\t\t/**\r\n\t\t * Provided for backward compatibility, use `afterLayout` instead.\r\n\t\t * @method IPlugin#afterScaleUpdate\r\n\t\t * @deprecated since version 2.5.0\r\n\t\t * @todo remove at version 3\r\n\t\t * @private\r\n\t\t */\r\n\t\tcore_plugins.notify(me, 'afterScaleUpdate');\r\n\t\tcore_plugins.notify(me, 'afterLayout');\r\n\t},\r\n\r\n\t/**\r\n\t * Updates all datasets unless a plugin returns `false` to the `beforeDatasetsUpdate`\r\n\t * hook, in which case, plugins will not be called on `afterDatasetsUpdate`.\r\n\t * @private\r\n\t */\r\n\tupdateDatasets: function() {\r\n\t\tvar me = this;\r\n\r\n\t\tif (core_plugins.notify(me, 'beforeDatasetsUpdate') === false) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tfor (var i = 0, ilen = me.data.datasets.length; i < ilen; ++i) {\r\n\t\t\tme.updateDataset(i);\r\n\t\t}\r\n\r\n\t\tcore_plugins.notify(me, 'afterDatasetsUpdate');\r\n\t},\r\n\r\n\t/**\r\n\t * Updates dataset at index unless a plugin returns `false` to the `beforeDatasetUpdate`\r\n\t * hook, in which case, plugins will not be called on `afterDatasetUpdate`.\r\n\t * @private\r\n\t */\r\n\tupdateDataset: function(index) {\r\n\t\tvar me = this;\r\n\t\tvar meta = me.getDatasetMeta(index);\r\n\t\tvar args = {\r\n\t\t\tmeta: meta,\r\n\t\t\tindex: index\r\n\t\t};\r\n\r\n\t\tif (core_plugins.notify(me, 'beforeDatasetUpdate', [args]) === false) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tmeta.controller._update();\r\n\r\n\t\tcore_plugins.notify(me, 'afterDatasetUpdate', [args]);\r\n\t},\r\n\r\n\trender: function(config) {\r\n\t\tvar me = this;\r\n\r\n\t\tif (!config || typeof config !== 'object') {\r\n\t\t\t// backwards compatibility\r\n\t\t\tconfig = {\r\n\t\t\t\tduration: config,\r\n\t\t\t\tlazy: arguments[1]\r\n\t\t\t};\r\n\t\t}\r\n\r\n\t\tvar animationOptions = me.options.animation;\r\n\t\tvar duration = valueOrDefault$9(config.duration, animationOptions && animationOptions.duration);\r\n\t\tvar lazy = config.lazy;\r\n\r\n\t\tif (core_plugins.notify(me, 'beforeRender') === false) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tvar onComplete = function(animation) {\r\n\t\t\tcore_plugins.notify(me, 'afterRender');\r\n\t\t\thelpers$1.callback(animationOptions && animationOptions.onComplete, [animation], me);\r\n\t\t};\r\n\r\n\t\tif (animationOptions && duration) {\r\n\t\t\tvar animation = new core_animation({\r\n\t\t\t\tnumSteps: duration / 16.66, // 60 fps\r\n\t\t\t\teasing: config.easing || animationOptions.easing,\r\n\r\n\t\t\t\trender: function(chart, animationObject) {\r\n\t\t\t\t\tvar easingFunction = helpers$1.easing.effects[animationObject.easing];\r\n\t\t\t\t\tvar currentStep = animationObject.currentStep;\r\n\t\t\t\t\tvar stepDecimal = currentStep / animationObject.numSteps;\r\n\r\n\t\t\t\t\tchart.draw(easingFunction(stepDecimal), stepDecimal, currentStep);\r\n\t\t\t\t},\r\n\r\n\t\t\t\tonAnimationProgress: animationOptions.onProgress,\r\n\t\t\t\tonAnimationComplete: onComplete\r\n\t\t\t});\r\n\r\n\t\t\tcore_animations.addAnimation(me, animation, duration, lazy);\r\n\t\t} else {\r\n\t\t\tme.draw();\r\n\r\n\t\t\t// See https://github.com/chartjs/Chart.js/issues/3781\r\n\t\t\tonComplete(new core_animation({numSteps: 0, chart: me}));\r\n\t\t}\r\n\r\n\t\treturn me;\r\n\t},\r\n\r\n\tdraw: function(easingValue) {\r\n\t\tvar me = this;\r\n\t\tvar i, layers;\r\n\r\n\t\tme.clear();\r\n\r\n\t\tif (helpers$1.isNullOrUndef(easingValue)) {\r\n\t\t\teasingValue = 1;\r\n\t\t}\r\n\r\n\t\tme.transition(easingValue);\r\n\r\n\t\tif (me.width <= 0 || me.height <= 0) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tif (core_plugins.notify(me, 'beforeDraw', [easingValue]) === false) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// Because of plugin hooks (before/afterDatasetsDraw), datasets can't\r\n\t\t// currently be part of layers. Instead, we draw\r\n\t\t// layers <= 0 before(default, backward compat), and the rest after\r\n\t\tlayers = me._layers;\r\n\t\tfor (i = 0; i < layers.length && layers[i].z <= 0; ++i) {\r\n\t\t\tlayers[i].draw(me.chartArea);\r\n\t\t}\r\n\r\n\t\tme.drawDatasets(easingValue);\r\n\r\n\t\t// Rest of layers\r\n\t\tfor (; i < layers.length; ++i) {\r\n\t\t\tlayers[i].draw(me.chartArea);\r\n\t\t}\r\n\r\n\t\tme._drawTooltip(easingValue);\r\n\r\n\t\tcore_plugins.notify(me, 'afterDraw', [easingValue]);\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\ttransition: function(easingValue) {\r\n\t\tvar me = this;\r\n\r\n\t\tfor (var i = 0, ilen = (me.data.datasets || []).length; i < ilen; ++i) {\r\n\t\t\tif (me.isDatasetVisible(i)) {\r\n\t\t\t\tme.getDatasetMeta(i).controller.transition(easingValue);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tme.tooltip.transition(easingValue);\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_getSortedDatasetMetas: function(filterVisible) {\r\n\t\tvar me = this;\r\n\t\tvar datasets = me.data.datasets || [];\r\n\t\tvar result = [];\r\n\t\tvar i, ilen;\r\n\r\n\t\tfor (i = 0, ilen = datasets.length; i < ilen; ++i) {\r\n\t\t\tif (!filterVisible || me.isDatasetVisible(i)) {\r\n\t\t\t\tresult.push(me.getDatasetMeta(i));\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tresult.sort(compare2Level('order', 'index'));\r\n\r\n\t\treturn result;\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_getSortedVisibleDatasetMetas: function() {\r\n\t\treturn this._getSortedDatasetMetas(true);\r\n\t},\r\n\r\n\t/**\r\n\t * Draws all datasets unless a plugin returns `false` to the `beforeDatasetsDraw`\r\n\t * hook, in which case, plugins will not be called on `afterDatasetsDraw`.\r\n\t * @private\r\n\t */\r\n\tdrawDatasets: function(easingValue) {\r\n\t\tvar me = this;\r\n\t\tvar metasets, i;\r\n\r\n\t\tif (core_plugins.notify(me, 'beforeDatasetsDraw', [easingValue]) === false) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tmetasets = me._getSortedVisibleDatasetMetas();\r\n\t\tfor (i = metasets.length - 1; i >= 0; --i) {\r\n\t\t\tme.drawDataset(metasets[i], easingValue);\r\n\t\t}\r\n\r\n\t\tcore_plugins.notify(me, 'afterDatasetsDraw', [easingValue]);\r\n\t},\r\n\r\n\t/**\r\n\t * Draws dataset at index unless a plugin returns `false` to the `beforeDatasetDraw`\r\n\t * hook, in which case, plugins will not be called on `afterDatasetDraw`.\r\n\t * @private\r\n\t */\r\n\tdrawDataset: function(meta, easingValue) {\r\n\t\tvar me = this;\r\n\t\tvar args = {\r\n\t\t\tmeta: meta,\r\n\t\t\tindex: meta.index,\r\n\t\t\teasingValue: easingValue\r\n\t\t};\r\n\r\n\t\tif (core_plugins.notify(me, 'beforeDatasetDraw', [args]) === false) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tmeta.controller.draw(easingValue);\r\n\r\n\t\tcore_plugins.notify(me, 'afterDatasetDraw', [args]);\r\n\t},\r\n\r\n\t/**\r\n\t * Draws tooltip unless a plugin returns `false` to the `beforeTooltipDraw`\r\n\t * hook, in which case, plugins will not be called on `afterTooltipDraw`.\r\n\t * @private\r\n\t */\r\n\t_drawTooltip: function(easingValue) {\r\n\t\tvar me = this;\r\n\t\tvar tooltip = me.tooltip;\r\n\t\tvar args = {\r\n\t\t\ttooltip: tooltip,\r\n\t\t\teasingValue: easingValue\r\n\t\t};\r\n\r\n\t\tif (core_plugins.notify(me, 'beforeTooltipDraw', [args]) === false) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\ttooltip.draw();\r\n\r\n\t\tcore_plugins.notify(me, 'afterTooltipDraw', [args]);\r\n\t},\r\n\r\n\t/**\r\n\t * Get the single element that was clicked on\r\n\t * @return An object containing the dataset index and element index of the matching element. Also contains the rectangle that was draw\r\n\t */\r\n\tgetElementAtEvent: function(e) {\r\n\t\treturn core_interaction.modes.single(this, e);\r\n\t},\r\n\r\n\tgetElementsAtEvent: function(e) {\r\n\t\treturn core_interaction.modes.label(this, e, {intersect: true});\r\n\t},\r\n\r\n\tgetElementsAtXAxis: function(e) {\r\n\t\treturn core_interaction.modes['x-axis'](this, e, {intersect: true});\r\n\t},\r\n\r\n\tgetElementsAtEventForMode: function(e, mode, options) {\r\n\t\tvar method = core_interaction.modes[mode];\r\n\t\tif (typeof method === 'function') {\r\n\t\t\treturn method(this, e, options);\r\n\t\t}\r\n\r\n\t\treturn [];\r\n\t},\r\n\r\n\tgetDatasetAtEvent: function(e) {\r\n\t\treturn core_interaction.modes.dataset(this, e, {intersect: true});\r\n\t},\r\n\r\n\tgetDatasetMeta: function(datasetIndex) {\r\n\t\tvar me = this;\r\n\t\tvar dataset = me.data.datasets[datasetIndex];\r\n\t\tif (!dataset._meta) {\r\n\t\t\tdataset._meta = {};\r\n\t\t}\r\n\r\n\t\tvar meta = dataset._meta[me.id];\r\n\t\tif (!meta) {\r\n\t\t\tmeta = dataset._meta[me.id] = {\r\n\t\t\t\ttype: null,\r\n\t\t\t\tdata: [],\r\n\t\t\t\tdataset: null,\r\n\t\t\t\tcontroller: null,\r\n\t\t\t\thidden: null,\t\t\t// See isDatasetVisible() comment\r\n\t\t\t\txAxisID: null,\r\n\t\t\t\tyAxisID: null,\r\n\t\t\t\torder: dataset.order || 0,\r\n\t\t\t\tindex: datasetIndex\r\n\t\t\t};\r\n\t\t}\r\n\r\n\t\treturn meta;\r\n\t},\r\n\r\n\tgetVisibleDatasetCount: function() {\r\n\t\tvar count = 0;\r\n\t\tfor (var i = 0, ilen = this.data.datasets.length; i < ilen; ++i) {\r\n\t\t\tif (this.isDatasetVisible(i)) {\r\n\t\t\t\tcount++;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn count;\r\n\t},\r\n\r\n\tisDatasetVisible: function(datasetIndex) {\r\n\t\tvar meta = this.getDatasetMeta(datasetIndex);\r\n\r\n\t\t// meta.hidden is a per chart dataset hidden flag override with 3 states: if true or false,\r\n\t\t// the dataset.hidden value is ignored, else if null, the dataset hidden state is returned.\r\n\t\treturn typeof meta.hidden === 'boolean' ? !meta.hidden : !this.data.datasets[datasetIndex].hidden;\r\n\t},\r\n\r\n\tgenerateLegend: function() {\r\n\t\treturn this.options.legendCallback(this);\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\tdestroyDatasetMeta: function(datasetIndex) {\r\n\t\tvar id = this.id;\r\n\t\tvar dataset = this.data.datasets[datasetIndex];\r\n\t\tvar meta = dataset._meta && dataset._meta[id];\r\n\r\n\t\tif (meta) {\r\n\t\t\tmeta.controller.destroy();\r\n\t\t\tdelete dataset._meta[id];\r\n\t\t}\r\n\t},\r\n\r\n\tdestroy: function() {\r\n\t\tvar me = this;\r\n\t\tvar canvas = me.canvas;\r\n\t\tvar i, ilen;\r\n\r\n\t\tme.stop();\r\n\r\n\t\t// dataset controllers need to cleanup associated data\r\n\t\tfor (i = 0, ilen = me.data.datasets.length; i < ilen; ++i) {\r\n\t\t\tme.destroyDatasetMeta(i);\r\n\t\t}\r\n\r\n\t\tif (canvas) {\r\n\t\t\tme.unbindEvents();\r\n\t\t\thelpers$1.canvas.clear(me);\r\n\t\t\tplatform.releaseContext(me.ctx);\r\n\t\t\tme.canvas = null;\r\n\t\t\tme.ctx = null;\r\n\t\t}\r\n\r\n\t\tcore_plugins.notify(me, 'destroy');\r\n\r\n\t\tdelete Chart.instances[me.id];\r\n\t},\r\n\r\n\ttoBase64Image: function() {\r\n\t\treturn this.canvas.toDataURL.apply(this.canvas, arguments);\r\n\t},\r\n\r\n\tinitToolTip: function() {\r\n\t\tvar me = this;\r\n\t\tme.tooltip = new core_tooltip({\r\n\t\t\t_chart: me,\r\n\t\t\t_chartInstance: me, // deprecated, backward compatibility\r\n\t\t\t_data: me.data,\r\n\t\t\t_options: me.options.tooltips\r\n\t\t}, me);\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\tbindEvents: function() {\r\n\t\tvar me = this;\r\n\t\tvar listeners = me._listeners = {};\r\n\t\tvar listener = function() {\r\n\t\t\tme.eventHandler.apply(me, arguments);\r\n\t\t};\r\n\r\n\t\thelpers$1.each(me.options.events, function(type) {\r\n\t\t\tplatform.addEventListener(me, type, listener);\r\n\t\t\tlisteners[type] = listener;\r\n\t\t});\r\n\r\n\t\t// Elements used to detect size change should not be injected for non responsive charts.\r\n\t\t// See https://github.com/chartjs/Chart.js/issues/2210\r\n\t\tif (me.options.responsive) {\r\n\t\t\tlistener = function() {\r\n\t\t\t\tme.resize();\r\n\t\t\t};\r\n\r\n\t\t\tplatform.addEventListener(me, 'resize', listener);\r\n\t\t\tlisteners.resize = listener;\r\n\t\t}\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\tunbindEvents: function() {\r\n\t\tvar me = this;\r\n\t\tvar listeners = me._listeners;\r\n\t\tif (!listeners) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tdelete me._listeners;\r\n\t\thelpers$1.each(listeners, function(listener, type) {\r\n\t\t\tplatform.removeEventListener(me, type, listener);\r\n\t\t});\r\n\t},\r\n\r\n\tupdateHoverStyle: function(elements, mode, enabled) {\r\n\t\tvar prefix = enabled ? 'set' : 'remove';\r\n\t\tvar element, i, ilen;\r\n\r\n\t\tfor (i = 0, ilen = elements.length; i < ilen; ++i) {\r\n\t\t\telement = elements[i];\r\n\t\t\tif (element) {\r\n\t\t\t\tthis.getDatasetMeta(element._datasetIndex).controller[prefix + 'HoverStyle'](element);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (mode === 'dataset') {\r\n\t\t\tthis.getDatasetMeta(elements[0]._datasetIndex).controller['_' + prefix + 'DatasetHoverStyle']();\r\n\t\t}\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\teventHandler: function(e) {\r\n\t\tvar me = this;\r\n\t\tvar tooltip = me.tooltip;\r\n\r\n\t\tif (core_plugins.notify(me, 'beforeEvent', [e]) === false) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// Buffer any update calls so that renders do not occur\r\n\t\tme._bufferedRender = true;\r\n\t\tme._bufferedRequest = null;\r\n\r\n\t\tvar changed = me.handleEvent(e);\r\n\t\t// for smooth tooltip animations issue #4989\r\n\t\t// the tooltip should be the source of change\r\n\t\t// Animation check workaround:\r\n\t\t// tooltip._start will be null when tooltip isn't animating\r\n\t\tif (tooltip) {\r\n\t\t\tchanged = tooltip._start\r\n\t\t\t\t? tooltip.handleEvent(e)\r\n\t\t\t\t: changed | tooltip.handleEvent(e);\r\n\t\t}\r\n\r\n\t\tcore_plugins.notify(me, 'afterEvent', [e]);\r\n\r\n\t\tvar bufferedRequest = me._bufferedRequest;\r\n\t\tif (bufferedRequest) {\r\n\t\t\t// If we have an update that was triggered, we need to do a normal render\r\n\t\t\tme.render(bufferedRequest);\r\n\t\t} else if (changed && !me.animating) {\r\n\t\t\t// If entering, leaving, or changing elements, animate the change via pivot\r\n\t\t\tme.stop();\r\n\r\n\t\t\t// We only need to render at this point. Updating will cause scales to be\r\n\t\t\t// recomputed generating flicker & using more memory than necessary.\r\n\t\t\tme.render({\r\n\t\t\t\tduration: me.options.hover.animationDuration,\r\n\t\t\t\tlazy: true\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tme._bufferedRender = false;\r\n\t\tme._bufferedRequest = null;\r\n\r\n\t\treturn me;\r\n\t},\r\n\r\n\t/**\r\n\t * Handle an event\r\n\t * @private\r\n\t * @param {IEvent} event the event to handle\r\n\t * @return {boolean} true if the chart needs to re-render\r\n\t */\r\n\thandleEvent: function(e) {\r\n\t\tvar me = this;\r\n\t\tvar options = me.options || {};\r\n\t\tvar hoverOptions = options.hover;\r\n\t\tvar changed = false;\r\n\r\n\t\tme.lastActive = me.lastActive || [];\r\n\r\n\t\t// Find Active Elements for hover and tooltips\r\n\t\tif (e.type === 'mouseout') {\r\n\t\t\tme.active = [];\r\n\t\t} else {\r\n\t\t\tme.active = me.getElementsAtEventForMode(e, hoverOptions.mode, hoverOptions);\r\n\t\t}\r\n\r\n\t\t// Invoke onHover hook\r\n\t\t// Need to call with native event here to not break backwards compatibility\r\n\t\thelpers$1.callback(options.onHover || options.hover.onHover, [e.native, me.active], me);\r\n\r\n\t\tif (e.type === 'mouseup' || e.type === 'click') {\r\n\t\t\tif (options.onClick) {\r\n\t\t\t\t// Use e.native here for backwards compatibility\r\n\t\t\t\toptions.onClick.call(me, e.native, me.active);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Remove styling for last active (even if it may still be active)\r\n\t\tif (me.lastActive.length) {\r\n\t\t\tme.updateHoverStyle(me.lastActive, hoverOptions.mode, false);\r\n\t\t}\r\n\r\n\t\t// Built in hover styling\r\n\t\tif (me.active.length && hoverOptions.mode) {\r\n\t\t\tme.updateHoverStyle(me.active, hoverOptions.mode, true);\r\n\t\t}\r\n\r\n\t\tchanged = !helpers$1.arrayEquals(me.active, me.lastActive);\r\n\r\n\t\t// Remember Last Actives\r\n\t\tme.lastActive = me.active;\r\n\r\n\t\treturn changed;\r\n\t}\r\n});\r\n\r\n/**\r\n * NOTE(SB) We actually don't use this container anymore but we need to keep it\r\n * for backward compatibility. Though, it can still be useful for plugins that\r\n * would need to work on multiple charts?!\r\n */\r\nChart.instances = {};\r\n\r\nvar core_controller = Chart;\r\n\r\n// DEPRECATIONS\r\n\r\n/**\r\n * Provided for backward compatibility, use Chart instead.\r\n * @class Chart.Controller\r\n * @deprecated since version 2.6\r\n * @todo remove at version 3\r\n * @private\r\n */\r\nChart.Controller = Chart;\r\n\r\n/**\r\n * Provided for backward compatibility, not available anymore.\r\n * @namespace Chart\r\n * @deprecated since version 2.8\r\n * @todo remove at version 3\r\n * @private\r\n */\r\nChart.types = {};\r\n\r\n/**\r\n * Provided for backward compatibility, not available anymore.\r\n * @namespace Chart.helpers.configMerge\r\n * @deprecated since version 2.8.0\r\n * @todo remove at version 3\r\n * @private\r\n */\r\nhelpers$1.configMerge = mergeConfig;\r\n\r\n/**\r\n * Provided for backward compatibility, not available anymore.\r\n * @namespace Chart.helpers.scaleMerge\r\n * @deprecated since version 2.8.0\r\n * @todo remove at version 3\r\n * @private\r\n */\r\nhelpers$1.scaleMerge = mergeScaleConfig;\n\nvar core_helpers = function() {\r\n\r\n\t// -- Basic js utility methods\r\n\r\n\thelpers$1.where = function(collection, filterCallback) {\r\n\t\tif (helpers$1.isArray(collection) && Array.prototype.filter) {\r\n\t\t\treturn collection.filter(filterCallback);\r\n\t\t}\r\n\t\tvar filtered = [];\r\n\r\n\t\thelpers$1.each(collection, function(item) {\r\n\t\t\tif (filterCallback(item)) {\r\n\t\t\t\tfiltered.push(item);\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\treturn filtered;\r\n\t};\r\n\thelpers$1.findIndex = Array.prototype.findIndex ?\r\n\t\tfunction(array, callback, scope) {\r\n\t\t\treturn array.findIndex(callback, scope);\r\n\t\t} :\r\n\t\tfunction(array, callback, scope) {\r\n\t\t\tscope = scope === undefined ? array : scope;\r\n\t\t\tfor (var i = 0, ilen = array.length; i < ilen; ++i) {\r\n\t\t\t\tif (callback.call(scope, array[i], i, array)) {\r\n\t\t\t\t\treturn i;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturn -1;\r\n\t\t};\r\n\thelpers$1.findNextWhere = function(arrayToSearch, filterCallback, startIndex) {\r\n\t\t// Default to start of the array\r\n\t\tif (helpers$1.isNullOrUndef(startIndex)) {\r\n\t\t\tstartIndex = -1;\r\n\t\t}\r\n\t\tfor (var i = startIndex + 1; i < arrayToSearch.length; i++) {\r\n\t\t\tvar currentItem = arrayToSearch[i];\r\n\t\t\tif (filterCallback(currentItem)) {\r\n\t\t\t\treturn currentItem;\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n\thelpers$1.findPreviousWhere = function(arrayToSearch, filterCallback, startIndex) {\r\n\t\t// Default to end of the array\r\n\t\tif (helpers$1.isNullOrUndef(startIndex)) {\r\n\t\t\tstartIndex = arrayToSearch.length;\r\n\t\t}\r\n\t\tfor (var i = startIndex - 1; i >= 0; i--) {\r\n\t\t\tvar currentItem = arrayToSearch[i];\r\n\t\t\tif (filterCallback(currentItem)) {\r\n\t\t\t\treturn currentItem;\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n\r\n\t// -- Math methods\r\n\thelpers$1.isNumber = function(n) {\r\n\t\treturn !isNaN(parseFloat(n)) && isFinite(n);\r\n\t};\r\n\thelpers$1.almostEquals = function(x, y, epsilon) {\r\n\t\treturn Math.abs(x - y) < epsilon;\r\n\t};\r\n\thelpers$1.almostWhole = function(x, epsilon) {\r\n\t\tvar rounded = Math.round(x);\r\n\t\treturn ((rounded - epsilon) <= x) && ((rounded + epsilon) >= x);\r\n\t};\r\n\thelpers$1.max = function(array) {\r\n\t\treturn array.reduce(function(max, value) {\r\n\t\t\tif (!isNaN(value)) {\r\n\t\t\t\treturn Math.max(max, value);\r\n\t\t\t}\r\n\t\t\treturn max;\r\n\t\t}, Number.NEGATIVE_INFINITY);\r\n\t};\r\n\thelpers$1.min = function(array) {\r\n\t\treturn array.reduce(function(min, value) {\r\n\t\t\tif (!isNaN(value)) {\r\n\t\t\t\treturn Math.min(min, value);\r\n\t\t\t}\r\n\t\t\treturn min;\r\n\t\t}, Number.POSITIVE_INFINITY);\r\n\t};\r\n\thelpers$1.sign = Math.sign ?\r\n\t\tfunction(x) {\r\n\t\t\treturn Math.sign(x);\r\n\t\t} :\r\n\t\tfunction(x) {\r\n\t\t\tx = +x; // convert to a number\r\n\t\t\tif (x === 0 || isNaN(x)) {\r\n\t\t\t\treturn x;\r\n\t\t\t}\r\n\t\t\treturn x > 0 ? 1 : -1;\r\n\t\t};\r\n\thelpers$1.toRadians = function(degrees) {\r\n\t\treturn degrees * (Math.PI / 180);\r\n\t};\r\n\thelpers$1.toDegrees = function(radians) {\r\n\t\treturn radians * (180 / Math.PI);\r\n\t};\r\n\r\n\t/**\r\n\t * Returns the number of decimal places\r\n\t * i.e. the number of digits after the decimal point, of the value of this Number.\r\n\t * @param {number} x - A number.\r\n\t * @returns {number} The number of decimal places.\r\n\t * @private\r\n\t */\r\n\thelpers$1._decimalPlaces = function(x) {\r\n\t\tif (!helpers$1.isFinite(x)) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tvar e = 1;\r\n\t\tvar p = 0;\r\n\t\twhile (Math.round(x * e) / e !== x) {\r\n\t\t\te *= 10;\r\n\t\t\tp++;\r\n\t\t}\r\n\t\treturn p;\r\n\t};\r\n\r\n\t// Gets the angle from vertical upright to the point about a centre.\r\n\thelpers$1.getAngleFromPoint = function(centrePoint, anglePoint) {\r\n\t\tvar distanceFromXCenter = anglePoint.x - centrePoint.x;\r\n\t\tvar distanceFromYCenter = anglePoint.y - centrePoint.y;\r\n\t\tvar radialDistanceFromCenter = Math.sqrt(distanceFromXCenter * distanceFromXCenter + distanceFromYCenter * distanceFromYCenter);\r\n\r\n\t\tvar angle = Math.atan2(distanceFromYCenter, distanceFromXCenter);\r\n\r\n\t\tif (angle < (-0.5 * Math.PI)) {\r\n\t\t\tangle += 2.0 * Math.PI; // make sure the returned angle is in the range of (-PI/2, 3PI/2]\r\n\t\t}\r\n\r\n\t\treturn {\r\n\t\t\tangle: angle,\r\n\t\t\tdistance: radialDistanceFromCenter\r\n\t\t};\r\n\t};\r\n\thelpers$1.distanceBetweenPoints = function(pt1, pt2) {\r\n\t\treturn Math.sqrt(Math.pow(pt2.x - pt1.x, 2) + Math.pow(pt2.y - pt1.y, 2));\r\n\t};\r\n\r\n\t/**\r\n\t * Provided for backward compatibility, not available anymore\r\n\t * @function Chart.helpers.aliasPixel\r\n\t * @deprecated since version 2.8.0\r\n\t * @todo remove at version 3\r\n\t */\r\n\thelpers$1.aliasPixel = function(pixelWidth) {\r\n\t\treturn (pixelWidth % 2 === 0) ? 0 : 0.5;\r\n\t};\r\n\r\n\t/**\r\n\t * Returns the aligned pixel value to avoid anti-aliasing blur\r\n\t * @param {Chart} chart - The chart instance.\r\n\t * @param {number} pixel - A pixel value.\r\n\t * @param {number} width - The width of the element.\r\n\t * @returns {number} The aligned pixel value.\r\n\t * @private\r\n\t */\r\n\thelpers$1._alignPixel = function(chart, pixel, width) {\r\n\t\tvar devicePixelRatio = chart.currentDevicePixelRatio;\r\n\t\tvar halfWidth = width / 2;\r\n\t\treturn Math.round((pixel - halfWidth) * devicePixelRatio) / devicePixelRatio + halfWidth;\r\n\t};\r\n\r\n\thelpers$1.splineCurve = function(firstPoint, middlePoint, afterPoint, t) {\r\n\t\t// Props to Rob Spencer at scaled innovation for his post on splining between points\r\n\t\t// http://scaledinnovation.com/analytics/splines/aboutSplines.html\r\n\r\n\t\t// This function must also respect \"skipped\" points\r\n\r\n\t\tvar previous = firstPoint.skip ? middlePoint : firstPoint;\r\n\t\tvar current = middlePoint;\r\n\t\tvar next = afterPoint.skip ? middlePoint : afterPoint;\r\n\r\n\t\tvar d01 = Math.sqrt(Math.pow(current.x - previous.x, 2) + Math.pow(current.y - previous.y, 2));\r\n\t\tvar d12 = Math.sqrt(Math.pow(next.x - current.x, 2) + Math.pow(next.y - current.y, 2));\r\n\r\n\t\tvar s01 = d01 / (d01 + d12);\r\n\t\tvar s12 = d12 / (d01 + d12);\r\n\r\n\t\t// If all points are the same, s01 & s02 will be inf\r\n\t\ts01 = isNaN(s01) ? 0 : s01;\r\n\t\ts12 = isNaN(s12) ? 0 : s12;\r\n\r\n\t\tvar fa = t * s01; // scaling factor for triangle Ta\r\n\t\tvar fb = t * s12;\r\n\r\n\t\treturn {\r\n\t\t\tprevious: {\r\n\t\t\t\tx: current.x - fa * (next.x - previous.x),\r\n\t\t\t\ty: current.y - fa * (next.y - previous.y)\r\n\t\t\t},\r\n\t\t\tnext: {\r\n\t\t\t\tx: current.x + fb * (next.x - previous.x),\r\n\t\t\t\ty: current.y + fb * (next.y - previous.y)\r\n\t\t\t}\r\n\t\t};\r\n\t};\r\n\thelpers$1.EPSILON = Number.EPSILON || 1e-14;\r\n\thelpers$1.splineCurveMonotone = function(points) {\r\n\t\t// This function calculates Bézier control points in a similar way than |splineCurve|,\r\n\t\t// but preserves monotonicity of the provided data and ensures no local extremums are added\r\n\t\t// between the dataset discrete points due to the interpolation.\r\n\t\t// See : https://en.wikipedia.org/wiki/Monotone_cubic_interpolation\r\n\r\n\t\tvar pointsWithTangents = (points || []).map(function(point) {\r\n\t\t\treturn {\r\n\t\t\t\tmodel: point._model,\r\n\t\t\t\tdeltaK: 0,\r\n\t\t\t\tmK: 0\r\n\t\t\t};\r\n\t\t});\r\n\r\n\t\t// Calculate slopes (deltaK) and initialize tangents (mK)\r\n\t\tvar pointsLen = pointsWithTangents.length;\r\n\t\tvar i, pointBefore, pointCurrent, pointAfter;\r\n\t\tfor (i = 0; i < pointsLen; ++i) {\r\n\t\t\tpointCurrent = pointsWithTangents[i];\r\n\t\t\tif (pointCurrent.model.skip) {\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\r\n\t\t\tpointBefore = i > 0 ? pointsWithTangents[i - 1] : null;\r\n\t\t\tpointAfter = i < pointsLen - 1 ? pointsWithTangents[i + 1] : null;\r\n\t\t\tif (pointAfter && !pointAfter.model.skip) {\r\n\t\t\t\tvar slopeDeltaX = (pointAfter.model.x - pointCurrent.model.x);\r\n\r\n\t\t\t\t// In the case of two points that appear at the same x pixel, slopeDeltaX is 0\r\n\t\t\t\tpointCurrent.deltaK = slopeDeltaX !== 0 ? (pointAfter.model.y - pointCurrent.model.y) / slopeDeltaX : 0;\r\n\t\t\t}\r\n\r\n\t\t\tif (!pointBefore || pointBefore.model.skip) {\r\n\t\t\t\tpointCurrent.mK = pointCurrent.deltaK;\r\n\t\t\t} else if (!pointAfter || pointAfter.model.skip) {\r\n\t\t\t\tpointCurrent.mK = pointBefore.deltaK;\r\n\t\t\t} else if (this.sign(pointBefore.deltaK) !== this.sign(pointCurrent.deltaK)) {\r\n\t\t\t\tpointCurrent.mK = 0;\r\n\t\t\t} else {\r\n\t\t\t\tpointCurrent.mK = (pointBefore.deltaK + pointCurrent.deltaK) / 2;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Adjust tangents to ensure monotonic properties\r\n\t\tvar alphaK, betaK, tauK, squaredMagnitude;\r\n\t\tfor (i = 0; i < pointsLen - 1; ++i) {\r\n\t\t\tpointCurrent = pointsWithTangents[i];\r\n\t\t\tpointAfter = pointsWithTangents[i + 1];\r\n\t\t\tif (pointCurrent.model.skip || pointAfter.model.skip) {\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\r\n\t\t\tif (helpers$1.almostEquals(pointCurrent.deltaK, 0, this.EPSILON)) {\r\n\t\t\t\tpointCurrent.mK = pointAfter.mK = 0;\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\r\n\t\t\talphaK = pointCurrent.mK / pointCurrent.deltaK;\r\n\t\t\tbetaK = pointAfter.mK / pointCurrent.deltaK;\r\n\t\t\tsquaredMagnitude = Math.pow(alphaK, 2) + Math.pow(betaK, 2);\r\n\t\t\tif (squaredMagnitude <= 9) {\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\r\n\t\t\ttauK = 3 / Math.sqrt(squaredMagnitude);\r\n\t\t\tpointCurrent.mK = alphaK * tauK * pointCurrent.deltaK;\r\n\t\t\tpointAfter.mK = betaK * tauK * pointCurrent.deltaK;\r\n\t\t}\r\n\r\n\t\t// Compute control points\r\n\t\tvar deltaX;\r\n\t\tfor (i = 0; i < pointsLen; ++i) {\r\n\t\t\tpointCurrent = pointsWithTangents[i];\r\n\t\t\tif (pointCurrent.model.skip) {\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\r\n\t\t\tpointBefore = i > 0 ? pointsWithTangents[i - 1] : null;\r\n\t\t\tpointAfter = i < pointsLen - 1 ? pointsWithTangents[i + 1] : null;\r\n\t\t\tif (pointBefore && !pointBefore.model.skip) {\r\n\t\t\t\tdeltaX = (pointCurrent.model.x - pointBefore.model.x) / 3;\r\n\t\t\t\tpointCurrent.model.controlPointPreviousX = pointCurrent.model.x - deltaX;\r\n\t\t\t\tpointCurrent.model.controlPointPreviousY = pointCurrent.model.y - deltaX * pointCurrent.mK;\r\n\t\t\t}\r\n\t\t\tif (pointAfter && !pointAfter.model.skip) {\r\n\t\t\t\tdeltaX = (pointAfter.model.x - pointCurrent.model.x) / 3;\r\n\t\t\t\tpointCurrent.model.controlPointNextX = pointCurrent.model.x + deltaX;\r\n\t\t\t\tpointCurrent.model.controlPointNextY = pointCurrent.model.y + deltaX * pointCurrent.mK;\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n\thelpers$1.nextItem = function(collection, index, loop) {\r\n\t\tif (loop) {\r\n\t\t\treturn index >= collection.length - 1 ? collection[0] : collection[index + 1];\r\n\t\t}\r\n\t\treturn index >= collection.length - 1 ? collection[collection.length - 1] : collection[index + 1];\r\n\t};\r\n\thelpers$1.previousItem = function(collection, index, loop) {\r\n\t\tif (loop) {\r\n\t\t\treturn index <= 0 ? collection[collection.length - 1] : collection[index - 1];\r\n\t\t}\r\n\t\treturn index <= 0 ? collection[0] : collection[index - 1];\r\n\t};\r\n\t// Implementation of the nice number algorithm used in determining where axis labels will go\r\n\thelpers$1.niceNum = function(range, round) {\r\n\t\tvar exponent = Math.floor(helpers$1.log10(range));\r\n\t\tvar fraction = range / Math.pow(10, exponent);\r\n\t\tvar niceFraction;\r\n\r\n\t\tif (round) {\r\n\t\t\tif (fraction < 1.5) {\r\n\t\t\t\tniceFraction = 1;\r\n\t\t\t} else if (fraction < 3) {\r\n\t\t\t\tniceFraction = 2;\r\n\t\t\t} else if (fraction < 7) {\r\n\t\t\t\tniceFraction = 5;\r\n\t\t\t} else {\r\n\t\t\t\tniceFraction = 10;\r\n\t\t\t}\r\n\t\t} else if (fraction <= 1.0) {\r\n\t\t\tniceFraction = 1;\r\n\t\t} else if (fraction <= 2) {\r\n\t\t\tniceFraction = 2;\r\n\t\t} else if (fraction <= 5) {\r\n\t\t\tniceFraction = 5;\r\n\t\t} else {\r\n\t\t\tniceFraction = 10;\r\n\t\t}\r\n\r\n\t\treturn niceFraction * Math.pow(10, exponent);\r\n\t};\r\n\t// Request animation polyfill - https://www.paulirish.com/2011/requestanimationframe-for-smart-animating/\r\n\thelpers$1.requestAnimFrame = (function() {\r\n\t\tif (typeof window === 'undefined') {\r\n\t\t\treturn function(callback) {\r\n\t\t\t\tcallback();\r\n\t\t\t};\r\n\t\t}\r\n\t\treturn window.requestAnimationFrame ||\r\n\t\t\twindow.webkitRequestAnimationFrame ||\r\n\t\t\twindow.mozRequestAnimationFrame ||\r\n\t\t\twindow.oRequestAnimationFrame ||\r\n\t\t\twindow.msRequestAnimationFrame ||\r\n\t\t\tfunction(callback) {\r\n\t\t\t\treturn window.setTimeout(callback, 1000 / 60);\r\n\t\t\t};\r\n\t}());\r\n\t// -- DOM methods\r\n\thelpers$1.getRelativePosition = function(evt, chart) {\r\n\t\tvar mouseX, mouseY;\r\n\t\tvar e = evt.originalEvent || evt;\r\n\t\tvar canvas = evt.target || evt.srcElement;\r\n\t\tvar boundingRect = canvas.getBoundingClientRect();\r\n\r\n\t\tvar touches = e.touches;\r\n\t\tif (touches && touches.length > 0) {\r\n\t\t\tmouseX = touches[0].clientX;\r\n\t\t\tmouseY = touches[0].clientY;\r\n\r\n\t\t} else {\r\n\t\t\tmouseX = e.clientX;\r\n\t\t\tmouseY = e.clientY;\r\n\t\t}\r\n\r\n\t\t// Scale mouse coordinates into canvas coordinates\r\n\t\t// by following the pattern laid out by 'jerryj' in the comments of\r\n\t\t// https://www.html5canvastutorials.com/advanced/html5-canvas-mouse-coordinates/\r\n\t\tvar paddingLeft = parseFloat(helpers$1.getStyle(canvas, 'padding-left'));\r\n\t\tvar paddingTop = parseFloat(helpers$1.getStyle(canvas, 'padding-top'));\r\n\t\tvar paddingRight = parseFloat(helpers$1.getStyle(canvas, 'padding-right'));\r\n\t\tvar paddingBottom = parseFloat(helpers$1.getStyle(canvas, 'padding-bottom'));\r\n\t\tvar width = boundingRect.right - boundingRect.left - paddingLeft - paddingRight;\r\n\t\tvar height = boundingRect.bottom - boundingRect.top - paddingTop - paddingBottom;\r\n\r\n\t\t// We divide by the current device pixel ratio, because the canvas is scaled up by that amount in each direction. However\r\n\t\t// the backend model is in unscaled coordinates. Since we are going to deal with our model coordinates, we go back here\r\n\t\tmouseX = Math.round((mouseX - boundingRect.left - paddingLeft) / (width) * canvas.width / chart.currentDevicePixelRatio);\r\n\t\tmouseY = Math.round((mouseY - boundingRect.top - paddingTop) / (height) * canvas.height / chart.currentDevicePixelRatio);\r\n\r\n\t\treturn {\r\n\t\t\tx: mouseX,\r\n\t\t\ty: mouseY\r\n\t\t};\r\n\r\n\t};\r\n\r\n\t// Private helper function to convert max-width/max-height values that may be percentages into a number\r\n\tfunction parseMaxStyle(styleValue, node, parentProperty) {\r\n\t\tvar valueInPixels;\r\n\t\tif (typeof styleValue === 'string') {\r\n\t\t\tvalueInPixels = parseInt(styleValue, 10);\r\n\r\n\t\t\tif (styleValue.indexOf('%') !== -1) {\r\n\t\t\t\t// percentage * size in dimension\r\n\t\t\t\tvalueInPixels = valueInPixels / 100 * node.parentNode[parentProperty];\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tvalueInPixels = styleValue;\r\n\t\t}\r\n\r\n\t\treturn valueInPixels;\r\n\t}\r\n\r\n\t/**\r\n\t * Returns if the given value contains an effective constraint.\r\n\t * @private\r\n\t */\r\n\tfunction isConstrainedValue(value) {\r\n\t\treturn value !== undefined && value !== null && value !== 'none';\r\n\t}\r\n\r\n\t/**\r\n\t * Returns the max width or height of the given DOM node in a cross-browser compatible fashion\r\n\t * @param {HTMLElement} domNode - the node to check the constraint on\r\n\t * @param {string} maxStyle - the style that defines the maximum for the direction we are using ('max-width' / 'max-height')\r\n\t * @param {string} percentageProperty - property of parent to use when calculating width as a percentage\r\n\t * @see {@link https://www.nathanaeljones.com/blog/2013/reading-max-width-cross-browser}\r\n\t */\r\n\tfunction getConstraintDimension(domNode, maxStyle, percentageProperty) {\r\n\t\tvar view = document.defaultView;\r\n\t\tvar parentNode = helpers$1._getParentNode(domNode);\r\n\t\tvar constrainedNode = view.getComputedStyle(domNode)[maxStyle];\r\n\t\tvar constrainedContainer = view.getComputedStyle(parentNode)[maxStyle];\r\n\t\tvar hasCNode = isConstrainedValue(constrainedNode);\r\n\t\tvar hasCContainer = isConstrainedValue(constrainedContainer);\r\n\t\tvar infinity = Number.POSITIVE_INFINITY;\r\n\r\n\t\tif (hasCNode || hasCContainer) {\r\n\t\t\treturn Math.min(\r\n\t\t\t\thasCNode ? parseMaxStyle(constrainedNode, domNode, percentageProperty) : infinity,\r\n\t\t\t\thasCContainer ? parseMaxStyle(constrainedContainer, parentNode, percentageProperty) : infinity);\r\n\t\t}\r\n\r\n\t\treturn 'none';\r\n\t}\r\n\t// returns Number or undefined if no constraint\r\n\thelpers$1.getConstraintWidth = function(domNode) {\r\n\t\treturn getConstraintDimension(domNode, 'max-width', 'clientWidth');\r\n\t};\r\n\t// returns Number or undefined if no constraint\r\n\thelpers$1.getConstraintHeight = function(domNode) {\r\n\t\treturn getConstraintDimension(domNode, 'max-height', 'clientHeight');\r\n\t};\r\n\t/**\r\n\t * @private\r\n \t */\r\n\thelpers$1._calculatePadding = function(container, padding, parentDimension) {\r\n\t\tpadding = helpers$1.getStyle(container, padding);\r\n\r\n\t\treturn padding.indexOf('%') > -1 ? parentDimension * parseInt(padding, 10) / 100 : parseInt(padding, 10);\r\n\t};\r\n\t/**\r\n\t * @private\r\n\t */\r\n\thelpers$1._getParentNode = function(domNode) {\r\n\t\tvar parent = domNode.parentNode;\r\n\t\tif (parent && parent.toString() === '[object ShadowRoot]') {\r\n\t\t\tparent = parent.host;\r\n\t\t}\r\n\t\treturn parent;\r\n\t};\r\n\thelpers$1.getMaximumWidth = function(domNode) {\r\n\t\tvar container = helpers$1._getParentNode(domNode);\r\n\t\tif (!container) {\r\n\t\t\treturn domNode.clientWidth;\r\n\t\t}\r\n\r\n\t\tvar clientWidth = container.clientWidth;\r\n\t\tvar paddingLeft = helpers$1._calculatePadding(container, 'padding-left', clientWidth);\r\n\t\tvar paddingRight = helpers$1._calculatePadding(container, 'padding-right', clientWidth);\r\n\r\n\t\tvar w = clientWidth - paddingLeft - paddingRight;\r\n\t\tvar cw = helpers$1.getConstraintWidth(domNode);\r\n\t\treturn isNaN(cw) ? w : Math.min(w, cw);\r\n\t};\r\n\thelpers$1.getMaximumHeight = function(domNode) {\r\n\t\tvar container = helpers$1._getParentNode(domNode);\r\n\t\tif (!container) {\r\n\t\t\treturn domNode.clientHeight;\r\n\t\t}\r\n\r\n\t\tvar clientHeight = container.clientHeight;\r\n\t\tvar paddingTop = helpers$1._calculatePadding(container, 'padding-top', clientHeight);\r\n\t\tvar paddingBottom = helpers$1._calculatePadding(container, 'padding-bottom', clientHeight);\r\n\r\n\t\tvar h = clientHeight - paddingTop - paddingBottom;\r\n\t\tvar ch = helpers$1.getConstraintHeight(domNode);\r\n\t\treturn isNaN(ch) ? h : Math.min(h, ch);\r\n\t};\r\n\thelpers$1.getStyle = function(el, property) {\r\n\t\treturn el.currentStyle ?\r\n\t\t\tel.currentStyle[property] :\r\n\t\t\tdocument.defaultView.getComputedStyle(el, null).getPropertyValue(property);\r\n\t};\r\n\thelpers$1.retinaScale = function(chart, forceRatio) {\r\n\t\tvar pixelRatio = chart.currentDevicePixelRatio = forceRatio || (typeof window !== 'undefined' && window.devicePixelRatio) || 1;\r\n\t\tif (pixelRatio === 1) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tvar canvas = chart.canvas;\r\n\t\tvar height = chart.height;\r\n\t\tvar width = chart.width;\r\n\r\n\t\tcanvas.height = height * pixelRatio;\r\n\t\tcanvas.width = width * pixelRatio;\r\n\t\tchart.ctx.scale(pixelRatio, pixelRatio);\r\n\r\n\t\t// If no style has been set on the canvas, the render size is used as display size,\r\n\t\t// making the chart visually bigger, so let's enforce it to the \"correct\" values.\r\n\t\t// See https://github.com/chartjs/Chart.js/issues/3575\r\n\t\tif (!canvas.style.height && !canvas.style.width) {\r\n\t\t\tcanvas.style.height = height + 'px';\r\n\t\t\tcanvas.style.width = width + 'px';\r\n\t\t}\r\n\t};\r\n\t// -- Canvas methods\r\n\thelpers$1.fontString = function(pixelSize, fontStyle, fontFamily) {\r\n\t\treturn fontStyle + ' ' + pixelSize + 'px ' + fontFamily;\r\n\t};\r\n\thelpers$1.longestText = function(ctx, font, arrayOfThings, cache) {\r\n\t\tcache = cache || {};\r\n\t\tvar data = cache.data = cache.data || {};\r\n\t\tvar gc = cache.garbageCollect = cache.garbageCollect || [];\r\n\r\n\t\tif (cache.font !== font) {\r\n\t\t\tdata = cache.data = {};\r\n\t\t\tgc = cache.garbageCollect = [];\r\n\t\t\tcache.font = font;\r\n\t\t}\r\n\r\n\t\tctx.font = font;\r\n\t\tvar longest = 0;\r\n\t\tvar ilen = arrayOfThings.length;\r\n\t\tvar i, j, jlen, thing, nestedThing;\r\n\t\tfor (i = 0; i < ilen; i++) {\r\n\t\t\tthing = arrayOfThings[i];\r\n\r\n\t\t\t// Undefined strings and arrays should not be measured\r\n\t\t\tif (thing !== undefined && thing !== null && helpers$1.isArray(thing) !== true) {\r\n\t\t\t\tlongest = helpers$1.measureText(ctx, data, gc, longest, thing);\r\n\t\t\t} else if (helpers$1.isArray(thing)) {\r\n\t\t\t\t// if it is an array lets measure each element\r\n\t\t\t\t// to do maybe simplify this function a bit so we can do this more recursively?\r\n\t\t\t\tfor (j = 0, jlen = thing.length; j < jlen; j++) {\r\n\t\t\t\t\tnestedThing = thing[j];\r\n\t\t\t\t\t// Undefined strings and arrays should not be measured\r\n\t\t\t\t\tif (nestedThing !== undefined && nestedThing !== null && !helpers$1.isArray(nestedThing)) {\r\n\t\t\t\t\t\tlongest = helpers$1.measureText(ctx, data, gc, longest, nestedThing);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tvar gcLen = gc.length / 2;\r\n\t\tif (gcLen > arrayOfThings.length) {\r\n\t\t\tfor (i = 0; i < gcLen; i++) {\r\n\t\t\t\tdelete data[gc[i]];\r\n\t\t\t}\r\n\t\t\tgc.splice(0, gcLen);\r\n\t\t}\r\n\t\treturn longest;\r\n\t};\r\n\thelpers$1.measureText = function(ctx, data, gc, longest, string) {\r\n\t\tvar textWidth = data[string];\r\n\t\tif (!textWidth) {\r\n\t\t\ttextWidth = data[string] = ctx.measureText(string).width;\r\n\t\t\tgc.push(string);\r\n\t\t}\r\n\t\tif (textWidth > longest) {\r\n\t\t\tlongest = textWidth;\r\n\t\t}\r\n\t\treturn longest;\r\n\t};\r\n\r\n\t/**\r\n\t * @deprecated\r\n\t */\r\n\thelpers$1.numberOfLabelLines = function(arrayOfThings) {\r\n\t\tvar numberOfLines = 1;\r\n\t\thelpers$1.each(arrayOfThings, function(thing) {\r\n\t\t\tif (helpers$1.isArray(thing)) {\r\n\t\t\t\tif (thing.length > numberOfLines) {\r\n\t\t\t\t\tnumberOfLines = thing.length;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t});\r\n\t\treturn numberOfLines;\r\n\t};\r\n\r\n\thelpers$1.color = !chartjsColor ?\r\n\t\tfunction(value) {\r\n\t\t\tconsole.error('Color.js not found!');\r\n\t\t\treturn value;\r\n\t\t} :\r\n\t\tfunction(value) {\r\n\t\t\t/* global CanvasGradient */\r\n\t\t\tif (value instanceof CanvasGradient) {\r\n\t\t\t\tvalue = core_defaults.global.defaultColor;\r\n\t\t\t}\r\n\r\n\t\t\treturn chartjsColor(value);\r\n\t\t};\r\n\r\n\thelpers$1.getHoverColor = function(colorValue) {\r\n\t\t/* global CanvasPattern */\r\n\t\treturn (colorValue instanceof CanvasPattern || colorValue instanceof CanvasGradient) ?\r\n\t\t\tcolorValue :\r\n\t\t\thelpers$1.color(colorValue).saturate(0.5).darken(0.1).rgbString();\r\n\t};\r\n};\n\nfunction abstract() {\r\n\tthrow new Error(\r\n\t\t'This method is not implemented: either no adapter can ' +\r\n\t\t'be found or an incomplete integration was provided.'\r\n\t);\r\n}\r\n\r\n/**\r\n * Date adapter (current used by the time scale)\r\n * @namespace Chart._adapters._date\r\n * @memberof Chart._adapters\r\n * @private\r\n */\r\n\r\n/**\r\n * Currently supported unit string values.\r\n * @typedef {('millisecond'|'second'|'minute'|'hour'|'day'|'week'|'month'|'quarter'|'year')}\r\n * @memberof Chart._adapters._date\r\n * @name Unit\r\n */\r\n\r\n/**\r\n * @class\r\n */\r\nfunction DateAdapter(options) {\r\n\tthis.options = options || {};\r\n}\r\n\r\nhelpers$1.extend(DateAdapter.prototype, /** @lends DateAdapter */ {\r\n\t/**\r\n\t * Returns a map of time formats for the supported formatting units defined\r\n\t * in Unit as well as 'datetime' representing a detailed date/time string.\r\n\t * @returns {{string: string}}\r\n\t */\r\n\tformats: abstract,\r\n\r\n\t/**\r\n\t * Parses the given `value` and return the associated timestamp.\r\n\t * @param {any} value - the value to parse (usually comes from the data)\r\n\t * @param {string} [format] - the expected data format\r\n\t * @returns {(number|null)}\r\n\t * @function\r\n\t */\r\n\tparse: abstract,\r\n\r\n\t/**\r\n\t * Returns the formatted date in the specified `format` for a given `timestamp`.\r\n\t * @param {number} timestamp - the timestamp to format\r\n\t * @param {string} format - the date/time token\r\n\t * @return {string}\r\n\t * @function\r\n\t */\r\n\tformat: abstract,\r\n\r\n\t/**\r\n\t * Adds the specified `amount` of `unit` to the given `timestamp`.\r\n\t * @param {number} timestamp - the input timestamp\r\n\t * @param {number} amount - the amount to add\r\n\t * @param {Unit} unit - the unit as string\r\n\t * @return {number}\r\n\t * @function\r\n\t */\r\n\tadd: abstract,\r\n\r\n\t/**\r\n\t * Returns the number of `unit` between the given timestamps.\r\n\t * @param {number} max - the input timestamp (reference)\r\n\t * @param {number} min - the timestamp to substract\r\n\t * @param {Unit} unit - the unit as string\r\n\t * @return {number}\r\n\t * @function\r\n\t */\r\n\tdiff: abstract,\r\n\r\n\t/**\r\n\t * Returns start of `unit` for the given `timestamp`.\r\n\t * @param {number} timestamp - the input timestamp\r\n\t * @param {Unit} unit - the unit as string\r\n\t * @param {number} [weekday] - the ISO day of the week with 1 being Monday\r\n\t * and 7 being Sunday (only needed if param *unit* is `isoWeek`).\r\n\t * @function\r\n\t */\r\n\tstartOf: abstract,\r\n\r\n\t/**\r\n\t * Returns end of `unit` for the given `timestamp`.\r\n\t * @param {number} timestamp - the input timestamp\r\n\t * @param {Unit} unit - the unit as string\r\n\t * @function\r\n\t */\r\n\tendOf: abstract,\r\n\r\n\t// DEPRECATIONS\r\n\r\n\t/**\r\n\t * Provided for backward compatibility for scale.getValueForPixel(),\r\n\t * this method should be overridden only by the moment adapter.\r\n\t * @deprecated since version 2.8.0\r\n\t * @todo remove at version 3\r\n\t * @private\r\n\t */\r\n\t_create: function(value) {\r\n\t\treturn value;\r\n\t}\r\n});\r\n\r\nDateAdapter.override = function(members) {\r\n\thelpers$1.extend(DateAdapter.prototype, members);\r\n};\r\n\r\nvar _date = DateAdapter;\n\nvar core_adapters = {\n\t_date: _date\n};\n\n/**\r\n * Namespace to hold static tick generation functions\r\n * @namespace Chart.Ticks\r\n */\r\nvar core_ticks = {\r\n\t/**\r\n\t * Namespace to hold formatters for different types of ticks\r\n\t * @namespace Chart.Ticks.formatters\r\n\t */\r\n\tformatters: {\r\n\t\t/**\r\n\t\t * Formatter for value labels\r\n\t\t * @method Chart.Ticks.formatters.values\r\n\t\t * @param value the value to display\r\n\t\t * @return {string|string[]} the label to display\r\n\t\t */\r\n\t\tvalues: function(value) {\r\n\t\t\treturn helpers$1.isArray(value) ? value : '' + value;\r\n\t\t},\r\n\r\n\t\t/**\r\n\t\t * Formatter for linear numeric ticks\r\n\t\t * @method Chart.Ticks.formatters.linear\r\n\t\t * @param tickValue {number} the value to be formatted\r\n\t\t * @param index {number} the position of the tickValue parameter in the ticks array\r\n\t\t * @param ticks {number[]} the list of ticks being converted\r\n\t\t * @return {string} string representation of the tickValue parameter\r\n\t\t */\r\n\t\tlinear: function(tickValue, index, ticks) {\r\n\t\t\t// If we have lots of ticks, don't use the ones\r\n\t\t\tvar delta = ticks.length > 3 ? ticks[2] - ticks[1] : ticks[1] - ticks[0];\r\n\r\n\t\t\t// If we have a number like 2.5 as the delta, figure out how many decimal places we need\r\n\t\t\tif (Math.abs(delta) > 1) {\r\n\t\t\t\tif (tickValue !== Math.floor(tickValue)) {\r\n\t\t\t\t\t// not an integer\r\n\t\t\t\t\tdelta = tickValue - Math.floor(tickValue);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tvar logDelta = helpers$1.log10(Math.abs(delta));\r\n\t\t\tvar tickString = '';\r\n\r\n\t\t\tif (tickValue !== 0) {\r\n\t\t\t\tvar maxTick = Math.max(Math.abs(ticks[0]), Math.abs(ticks[ticks.length - 1]));\r\n\t\t\t\tif (maxTick < 1e-4) { // all ticks are small numbers; use scientific notation\r\n\t\t\t\t\tvar logTick = helpers$1.log10(Math.abs(tickValue));\r\n\t\t\t\t\tvar numExponential = Math.floor(logTick) - Math.floor(logDelta);\r\n\t\t\t\t\tnumExponential = Math.max(Math.min(numExponential, 20), 0);\r\n\t\t\t\t\ttickString = tickValue.toExponential(numExponential);\r\n\t\t\t\t} else {\r\n\t\t\t\t\tvar numDecimal = -1 * Math.floor(logDelta);\r\n\t\t\t\t\tnumDecimal = Math.max(Math.min(numDecimal, 20), 0); // toFixed has a max of 20 decimal places\r\n\t\t\t\t\ttickString = tickValue.toFixed(numDecimal);\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\ttickString = '0'; // never show decimal places for 0\r\n\t\t\t}\r\n\r\n\t\t\treturn tickString;\r\n\t\t},\r\n\r\n\t\tlogarithmic: function(tickValue, index, ticks) {\r\n\t\t\tvar remain = tickValue / (Math.pow(10, Math.floor(helpers$1.log10(tickValue))));\r\n\r\n\t\t\tif (tickValue === 0) {\r\n\t\t\t\treturn '0';\r\n\t\t\t} else if (remain === 1 || remain === 2 || remain === 5 || index === 0 || index === ticks.length - 1) {\r\n\t\t\t\treturn tickValue.toExponential();\r\n\t\t\t}\r\n\t\t\treturn '';\r\n\t\t}\r\n\t}\r\n};\n\nvar isArray = helpers$1.isArray;\r\nvar isNullOrUndef = helpers$1.isNullOrUndef;\r\nvar valueOrDefault$a = helpers$1.valueOrDefault;\r\nvar valueAtIndexOrDefault = helpers$1.valueAtIndexOrDefault;\r\n\r\ncore_defaults._set('scale', {\r\n\tdisplay: true,\r\n\tposition: 'left',\r\n\toffset: false,\r\n\r\n\t// grid line settings\r\n\tgridLines: {\r\n\t\tdisplay: true,\r\n\t\tcolor: 'rgba(0,0,0,0.1)',\r\n\t\tlineWidth: 1,\r\n\t\tdrawBorder: true,\r\n\t\tdrawOnChartArea: true,\r\n\t\tdrawTicks: true,\r\n\t\ttickMarkLength: 10,\r\n\t\tzeroLineWidth: 1,\r\n\t\tzeroLineColor: 'rgba(0,0,0,0.25)',\r\n\t\tzeroLineBorderDash: [],\r\n\t\tzeroLineBorderDashOffset: 0.0,\r\n\t\toffsetGridLines: false,\r\n\t\tborderDash: [],\r\n\t\tborderDashOffset: 0.0\r\n\t},\r\n\r\n\t// scale label\r\n\tscaleLabel: {\r\n\t\t// display property\r\n\t\tdisplay: false,\r\n\r\n\t\t// actual label\r\n\t\tlabelString: '',\r\n\r\n\t\t// top/bottom padding\r\n\t\tpadding: {\r\n\t\t\ttop: 4,\r\n\t\t\tbottom: 4\r\n\t\t}\r\n\t},\r\n\r\n\t// label settings\r\n\tticks: {\r\n\t\tbeginAtZero: false,\r\n\t\tminRotation: 0,\r\n\t\tmaxRotation: 50,\r\n\t\tmirror: false,\r\n\t\tpadding: 0,\r\n\t\treverse: false,\r\n\t\tdisplay: true,\r\n\t\tautoSkip: true,\r\n\t\tautoSkipPadding: 0,\r\n\t\tlabelOffset: 0,\r\n\t\t// We pass through arrays to be rendered as multiline labels, we convert Others to strings here.\r\n\t\tcallback: core_ticks.formatters.values,\r\n\t\tminor: {},\r\n\t\tmajor: {}\r\n\t}\r\n});\r\n\r\n/** Returns a new array containing numItems from arr */\r\nfunction sample(arr, numItems) {\r\n\tvar result = [];\r\n\tvar increment = arr.length / numItems;\r\n\tvar i = 0;\r\n\tvar len = arr.length;\r\n\r\n\tfor (; i < len; i += increment) {\r\n\t\tresult.push(arr[Math.floor(i)]);\r\n\t}\r\n\treturn result;\r\n}\r\n\r\nfunction getPixelForGridLine(scale, index, offsetGridLines) {\r\n\tvar length = scale.getTicks().length;\r\n\tvar validIndex = Math.min(index, length - 1);\r\n\tvar lineValue = scale.getPixelForTick(validIndex);\r\n\tvar start = scale._startPixel;\r\n\tvar end = scale._endPixel;\r\n\tvar epsilon = 1e-6; // 1e-6 is margin in pixels for accumulated error.\r\n\tvar offset;\r\n\r\n\tif (offsetGridLines) {\r\n\t\tif (length === 1) {\r\n\t\t\toffset = Math.max(lineValue - start, end - lineValue);\r\n\t\t} else if (index === 0) {\r\n\t\t\toffset = (scale.getPixelForTick(1) - lineValue) / 2;\r\n\t\t} else {\r\n\t\t\toffset = (lineValue - scale.getPixelForTick(validIndex - 1)) / 2;\r\n\t\t}\r\n\t\tlineValue += validIndex < index ? offset : -offset;\r\n\r\n\t\t// Return undefined if the pixel is out of the range\r\n\t\tif (lineValue < start - epsilon || lineValue > end + epsilon) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t}\r\n\treturn lineValue;\r\n}\r\n\r\nfunction garbageCollect(caches, length) {\r\n\thelpers$1.each(caches, function(cache) {\r\n\t\tvar gc = cache.gc;\r\n\t\tvar gcLen = gc.length / 2;\r\n\t\tvar i;\r\n\t\tif (gcLen > length) {\r\n\t\t\tfor (i = 0; i < gcLen; ++i) {\r\n\t\t\t\tdelete cache.data[gc[i]];\r\n\t\t\t}\r\n\t\t\tgc.splice(0, gcLen);\r\n\t\t}\r\n\t});\r\n}\r\n\r\n/**\r\n * Returns {width, height, offset} objects for the first, last, widest, highest tick\r\n * labels where offset indicates the anchor point offset from the top in pixels.\r\n */\r\nfunction computeLabelSizes(ctx, tickFonts, ticks, caches) {\r\n\tvar length = ticks.length;\r\n\tvar widths = [];\r\n\tvar heights = [];\r\n\tvar offsets = [];\r\n\tvar widestLabelSize = 0;\r\n\tvar highestLabelSize = 0;\r\n\tvar i, j, jlen, label, tickFont, fontString, cache, lineHeight, width, height, nestedLabel, widest, highest;\r\n\r\n\tfor (i = 0; i < length; ++i) {\r\n\t\tlabel = ticks[i].label;\r\n\t\ttickFont = ticks[i].major ? tickFonts.major : tickFonts.minor;\r\n\t\tctx.font = fontString = tickFont.string;\r\n\t\tcache = caches[fontString] = caches[fontString] || {data: {}, gc: []};\r\n\t\tlineHeight = tickFont.lineHeight;\r\n\t\twidth = height = 0;\r\n\t\t// Undefined labels and arrays should not be measured\r\n\t\tif (!isNullOrUndef(label) && !isArray(label)) {\r\n\t\t\twidth = helpers$1.measureText(ctx, cache.data, cache.gc, width, label);\r\n\t\t\theight = lineHeight;\r\n\t\t} else if (isArray(label)) {\r\n\t\t\t// if it is an array let's measure each element\r\n\t\t\tfor (j = 0, jlen = label.length; j < jlen; ++j) {\r\n\t\t\t\tnestedLabel = label[j];\r\n\t\t\t\t// Undefined labels and arrays should not be measured\r\n\t\t\t\tif (!isNullOrUndef(nestedLabel) && !isArray(nestedLabel)) {\r\n\t\t\t\t\twidth = helpers$1.measureText(ctx, cache.data, cache.gc, width, nestedLabel);\r\n\t\t\t\t\theight += lineHeight;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\twidths.push(width);\r\n\t\theights.push(height);\r\n\t\toffsets.push(lineHeight / 2);\r\n\t\twidestLabelSize = Math.max(width, widestLabelSize);\r\n\t\thighestLabelSize = Math.max(height, highestLabelSize);\r\n\t}\r\n\tgarbageCollect(caches, length);\r\n\r\n\twidest = widths.indexOf(widestLabelSize);\r\n\thighest = heights.indexOf(highestLabelSize);\r\n\r\n\tfunction valueAt(idx) {\r\n\t\treturn {\r\n\t\t\twidth: widths[idx] || 0,\r\n\t\t\theight: heights[idx] || 0,\r\n\t\t\toffset: offsets[idx] || 0\r\n\t\t};\r\n\t}\r\n\r\n\treturn {\r\n\t\tfirst: valueAt(0),\r\n\t\tlast: valueAt(length - 1),\r\n\t\twidest: valueAt(widest),\r\n\t\thighest: valueAt(highest)\r\n\t};\r\n}\r\n\r\nfunction getTickMarkLength(options) {\r\n\treturn options.drawTicks ? options.tickMarkLength : 0;\r\n}\r\n\r\nfunction getScaleLabelHeight(options) {\r\n\tvar font, padding;\r\n\r\n\tif (!options.display) {\r\n\t\treturn 0;\r\n\t}\r\n\r\n\tfont = helpers$1.options._parseFont(options);\r\n\tpadding = helpers$1.options.toPadding(options.padding);\r\n\r\n\treturn font.lineHeight + padding.height;\r\n}\r\n\r\nfunction parseFontOptions(options, nestedOpts) {\r\n\treturn helpers$1.extend(helpers$1.options._parseFont({\r\n\t\tfontFamily: valueOrDefault$a(nestedOpts.fontFamily, options.fontFamily),\r\n\t\tfontSize: valueOrDefault$a(nestedOpts.fontSize, options.fontSize),\r\n\t\tfontStyle: valueOrDefault$a(nestedOpts.fontStyle, options.fontStyle),\r\n\t\tlineHeight: valueOrDefault$a(nestedOpts.lineHeight, options.lineHeight)\r\n\t}), {\r\n\t\tcolor: helpers$1.options.resolve([nestedOpts.fontColor, options.fontColor, core_defaults.global.defaultFontColor])\r\n\t});\r\n}\r\n\r\nfunction parseTickFontOptions(options) {\r\n\tvar minor = parseFontOptions(options, options.minor);\r\n\tvar major = options.major.enabled ? parseFontOptions(options, options.major) : minor;\r\n\r\n\treturn {minor: minor, major: major};\r\n}\r\n\r\nfunction nonSkipped(ticksToFilter) {\r\n\tvar filtered = [];\r\n\tvar item, index, len;\r\n\tfor (index = 0, len = ticksToFilter.length; index < len; ++index) {\r\n\t\titem = ticksToFilter[index];\r\n\t\tif (typeof item._index !== 'undefined') {\r\n\t\t\tfiltered.push(item);\r\n\t\t}\r\n\t}\r\n\treturn filtered;\r\n}\r\n\r\nfunction getEvenSpacing(arr) {\r\n\tvar len = arr.length;\r\n\tvar i, diff;\r\n\r\n\tif (len < 2) {\r\n\t\treturn false;\r\n\t}\r\n\r\n\tfor (diff = arr[0], i = 1; i < len; ++i) {\r\n\t\tif (arr[i] - arr[i - 1] !== diff) {\r\n\t\t\treturn false;\r\n\t\t}\r\n\t}\r\n\treturn diff;\r\n}\r\n\r\nfunction calculateSpacing(majorIndices, ticks, axisLength, ticksLimit) {\r\n\tvar evenMajorSpacing = getEvenSpacing(majorIndices);\r\n\tvar spacing = (ticks.length - 1) / ticksLimit;\r\n\tvar factors, factor, i, ilen;\r\n\r\n\t// If the major ticks are evenly spaced apart, place the minor ticks\r\n\t// so that they divide the major ticks into even chunks\r\n\tif (!evenMajorSpacing) {\r\n\t\treturn Math.max(spacing, 1);\r\n\t}\r\n\r\n\tfactors = helpers$1.math._factorize(evenMajorSpacing);\r\n\tfor (i = 0, ilen = factors.length - 1; i < ilen; i++) {\r\n\t\tfactor = factors[i];\r\n\t\tif (factor > spacing) {\r\n\t\t\treturn factor;\r\n\t\t}\r\n\t}\r\n\treturn Math.max(spacing, 1);\r\n}\r\n\r\nfunction getMajorIndices(ticks) {\r\n\tvar result = [];\r\n\tvar i, ilen;\r\n\tfor (i = 0, ilen = ticks.length; i < ilen; i++) {\r\n\t\tif (ticks[i].major) {\r\n\t\t\tresult.push(i);\r\n\t\t}\r\n\t}\r\n\treturn result;\r\n}\r\n\r\nfunction skipMajors(ticks, majorIndices, spacing) {\r\n\tvar count = 0;\r\n\tvar next = majorIndices[0];\r\n\tvar i, tick;\r\n\r\n\tspacing = Math.ceil(spacing);\r\n\tfor (i = 0; i < ticks.length; i++) {\r\n\t\ttick = ticks[i];\r\n\t\tif (i === next) {\r\n\t\t\ttick._index = i;\r\n\t\t\tcount++;\r\n\t\t\tnext = majorIndices[count * spacing];\r\n\t\t} else {\r\n\t\t\tdelete tick.label;\r\n\t\t}\r\n\t}\r\n}\r\n\r\nfunction skip(ticks, spacing, majorStart, majorEnd) {\r\n\tvar start = valueOrDefault$a(majorStart, 0);\r\n\tvar end = Math.min(valueOrDefault$a(majorEnd, ticks.length), ticks.length);\r\n\tvar count = 0;\r\n\tvar length, i, tick, next;\r\n\r\n\tspacing = Math.ceil(spacing);\r\n\tif (majorEnd) {\r\n\t\tlength = majorEnd - majorStart;\r\n\t\tspacing = length / Math.floor(length / spacing);\r\n\t}\r\n\r\n\tnext = start;\r\n\r\n\twhile (next < 0) {\r\n\t\tcount++;\r\n\t\tnext = Math.round(start + count * spacing);\r\n\t}\r\n\r\n\tfor (i = Math.max(start, 0); i < end; i++) {\r\n\t\ttick = ticks[i];\r\n\t\tif (i === next) {\r\n\t\t\ttick._index = i;\r\n\t\t\tcount++;\r\n\t\t\tnext = Math.round(start + count * spacing);\r\n\t\t} else {\r\n\t\t\tdelete tick.label;\r\n\t\t}\r\n\t}\r\n}\r\n\r\nvar Scale = core_element.extend({\r\n\r\n\tzeroLineIndex: 0,\r\n\r\n\t/**\r\n\t * Get the padding needed for the scale\r\n\t * @method getPadding\r\n\t * @private\r\n\t * @returns {Padding} the necessary padding\r\n\t */\r\n\tgetPadding: function() {\r\n\t\tvar me = this;\r\n\t\treturn {\r\n\t\t\tleft: me.paddingLeft || 0,\r\n\t\t\ttop: me.paddingTop || 0,\r\n\t\t\tright: me.paddingRight || 0,\r\n\t\t\tbottom: me.paddingBottom || 0\r\n\t\t};\r\n\t},\r\n\r\n\t/**\r\n\t * Returns the scale tick objects ({label, major})\r\n\t * @since 2.7\r\n\t */\r\n\tgetTicks: function() {\r\n\t\treturn this._ticks;\r\n\t},\r\n\r\n\t/**\r\n\t* @private\r\n\t*/\r\n\t_getLabels: function() {\r\n\t\tvar data = this.chart.data;\r\n\t\treturn this.options.labels || (this.isHorizontal() ? data.xLabels : data.yLabels) || data.labels || [];\r\n\t},\r\n\r\n\t// These methods are ordered by lifecyle. Utilities then follow.\r\n\t// Any function defined here is inherited by all scale types.\r\n\t// Any function can be extended by the scale type\r\n\r\n\t/**\r\n\t * Provided for backward compatibility, not available anymore\r\n\t * @function Chart.Scale.mergeTicksOptions\r\n\t * @deprecated since version 2.8.0\r\n\t * @todo remove at version 3\r\n\t */\r\n\tmergeTicksOptions: function() {\r\n\t\t// noop\r\n\t},\r\n\r\n\tbeforeUpdate: function() {\r\n\t\thelpers$1.callback(this.options.beforeUpdate, [this]);\r\n\t},\r\n\r\n\t/**\r\n\t * @param {number} maxWidth - the max width in pixels\r\n\t * @param {number} maxHeight - the max height in pixels\r\n\t * @param {object} margins - the space between the edge of the other scales and edge of the chart\r\n\t * This space comes from two sources:\r\n\t * - padding - space that's required to show the labels at the edges of the scale\r\n\t * - thickness of scales or legends in another orientation\r\n\t */\r\n\tupdate: function(maxWidth, maxHeight, margins) {\r\n\t\tvar me = this;\r\n\t\tvar tickOpts = me.options.ticks;\r\n\t\tvar sampleSize = tickOpts.sampleSize;\r\n\t\tvar i, ilen, labels, ticks, samplingEnabled;\r\n\r\n\t\t// Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)\r\n\t\tme.beforeUpdate();\r\n\r\n\t\t// Absorb the master measurements\r\n\t\tme.maxWidth = maxWidth;\r\n\t\tme.maxHeight = maxHeight;\r\n\t\tme.margins = helpers$1.extend({\r\n\t\t\tleft: 0,\r\n\t\t\tright: 0,\r\n\t\t\ttop: 0,\r\n\t\t\tbottom: 0\r\n\t\t}, margins);\r\n\r\n\t\tme._ticks = null;\r\n\t\tme.ticks = null;\r\n\t\tme._labelSizes = null;\r\n\t\tme._maxLabelLines = 0;\r\n\t\tme.longestLabelWidth = 0;\r\n\t\tme.longestTextCache = me.longestTextCache || {};\r\n\t\tme._gridLineItems = null;\r\n\t\tme._labelItems = null;\r\n\r\n\t\t// Dimensions\r\n\t\tme.beforeSetDimensions();\r\n\t\tme.setDimensions();\r\n\t\tme.afterSetDimensions();\r\n\r\n\t\t// Data min/max\r\n\t\tme.beforeDataLimits();\r\n\t\tme.determineDataLimits();\r\n\t\tme.afterDataLimits();\r\n\r\n\t\t// Ticks - `this.ticks` is now DEPRECATED!\r\n\t\t// Internal ticks are now stored as objects in the PRIVATE `this._ticks` member\r\n\t\t// and must not be accessed directly from outside this class. `this.ticks` being\r\n\t\t// around for long time and not marked as private, we can't change its structure\r\n\t\t// without unexpected breaking changes. If you need to access the scale ticks,\r\n\t\t// use scale.getTicks() instead.\r\n\r\n\t\tme.beforeBuildTicks();\r\n\r\n\t\t// New implementations should return an array of objects but for BACKWARD COMPAT,\r\n\t\t// we still support no return (`this.ticks` internally set by calling this method).\r\n\t\tticks = me.buildTicks() || [];\r\n\r\n\t\t// Allow modification of ticks in callback.\r\n\t\tticks = me.afterBuildTicks(ticks) || ticks;\r\n\r\n\t\t// Ensure ticks contains ticks in new tick format\r\n\t\tif ((!ticks || !ticks.length) && me.ticks) {\r\n\t\t\tticks = [];\r\n\t\t\tfor (i = 0, ilen = me.ticks.length; i < ilen; ++i) {\r\n\t\t\t\tticks.push({\r\n\t\t\t\t\tvalue: me.ticks[i],\r\n\t\t\t\t\tmajor: false\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tme._ticks = ticks;\r\n\r\n\t\t// Compute tick rotation and fit using a sampled subset of labels\r\n\t\t// We generally don't need to compute the size of every single label for determining scale size\r\n\t\tsamplingEnabled = sampleSize < ticks.length;\r\n\t\tlabels = me._convertTicksToLabels(samplingEnabled ? sample(ticks, sampleSize) : ticks);\r\n\r\n\t\t// _configure is called twice, once here, once from core.controller.updateLayout.\r\n\t\t// Here we haven't been positioned yet, but dimensions are correct.\r\n\t\t// Variables set in _configure are needed for calculateTickRotation, and\r\n\t\t// it's ok that coordinates are not correct there, only dimensions matter.\r\n\t\tme._configure();\r\n\r\n\t\t// Tick Rotation\r\n\t\tme.beforeCalculateTickRotation();\r\n\t\tme.calculateTickRotation();\r\n\t\tme.afterCalculateTickRotation();\r\n\r\n\t\tme.beforeFit();\r\n\t\tme.fit();\r\n\t\tme.afterFit();\r\n\r\n\t\t// Auto-skip\r\n\t\tme._ticksToDraw = tickOpts.display && (tickOpts.autoSkip || tickOpts.source === 'auto') ? me._autoSkip(ticks) : ticks;\r\n\r\n\t\tif (samplingEnabled) {\r\n\t\t\t// Generate labels using all non-skipped ticks\r\n\t\t\tlabels = me._convertTicksToLabels(me._ticksToDraw);\r\n\t\t}\r\n\r\n\t\tme.ticks = labels; // BACKWARD COMPATIBILITY\r\n\r\n\t\t// IMPORTANT: after this point, we consider that `this.ticks` will NEVER change!\r\n\r\n\t\tme.afterUpdate();\r\n\r\n\t\t// TODO(v3): remove minSize as a public property and return value from all layout boxes. It is unused\r\n\t\t// make maxWidth and maxHeight private\r\n\t\treturn me.minSize;\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_configure: function() {\r\n\t\tvar me = this;\r\n\t\tvar reversePixels = me.options.ticks.reverse;\r\n\t\tvar startPixel, endPixel;\r\n\r\n\t\tif (me.isHorizontal()) {\r\n\t\t\tstartPixel = me.left;\r\n\t\t\tendPixel = me.right;\r\n\t\t} else {\r\n\t\t\tstartPixel = me.top;\r\n\t\t\tendPixel = me.bottom;\r\n\t\t\t// by default vertical scales are from bottom to top, so pixels are reversed\r\n\t\t\treversePixels = !reversePixels;\r\n\t\t}\r\n\t\tme._startPixel = startPixel;\r\n\t\tme._endPixel = endPixel;\r\n\t\tme._reversePixels = reversePixels;\r\n\t\tme._length = endPixel - startPixel;\r\n\t},\r\n\r\n\tafterUpdate: function() {\r\n\t\thelpers$1.callback(this.options.afterUpdate, [this]);\r\n\t},\r\n\r\n\t//\r\n\r\n\tbeforeSetDimensions: function() {\r\n\t\thelpers$1.callback(this.options.beforeSetDimensions, [this]);\r\n\t},\r\n\tsetDimensions: function() {\r\n\t\tvar me = this;\r\n\t\t// Set the unconstrained dimension before label rotation\r\n\t\tif (me.isHorizontal()) {\r\n\t\t\t// Reset position before calculating rotation\r\n\t\t\tme.width = me.maxWidth;\r\n\t\t\tme.left = 0;\r\n\t\t\tme.right = me.width;\r\n\t\t} else {\r\n\t\t\tme.height = me.maxHeight;\r\n\r\n\t\t\t// Reset position before calculating rotation\r\n\t\t\tme.top = 0;\r\n\t\t\tme.bottom = me.height;\r\n\t\t}\r\n\r\n\t\t// Reset padding\r\n\t\tme.paddingLeft = 0;\r\n\t\tme.paddingTop = 0;\r\n\t\tme.paddingRight = 0;\r\n\t\tme.paddingBottom = 0;\r\n\t},\r\n\tafterSetDimensions: function() {\r\n\t\thelpers$1.callback(this.options.afterSetDimensions, [this]);\r\n\t},\r\n\r\n\t// Data limits\r\n\tbeforeDataLimits: function() {\r\n\t\thelpers$1.callback(this.options.beforeDataLimits, [this]);\r\n\t},\r\n\tdetermineDataLimits: helpers$1.noop,\r\n\tafterDataLimits: function() {\r\n\t\thelpers$1.callback(this.options.afterDataLimits, [this]);\r\n\t},\r\n\r\n\t//\r\n\tbeforeBuildTicks: function() {\r\n\t\thelpers$1.callback(this.options.beforeBuildTicks, [this]);\r\n\t},\r\n\tbuildTicks: helpers$1.noop,\r\n\tafterBuildTicks: function(ticks) {\r\n\t\tvar me = this;\r\n\t\t// ticks is empty for old axis implementations here\r\n\t\tif (isArray(ticks) && ticks.length) {\r\n\t\t\treturn helpers$1.callback(me.options.afterBuildTicks, [me, ticks]);\r\n\t\t}\r\n\t\t// Support old implementations (that modified `this.ticks` directly in buildTicks)\r\n\t\tme.ticks = helpers$1.callback(me.options.afterBuildTicks, [me, me.ticks]) || me.ticks;\r\n\t\treturn ticks;\r\n\t},\r\n\r\n\tbeforeTickToLabelConversion: function() {\r\n\t\thelpers$1.callback(this.options.beforeTickToLabelConversion, [this]);\r\n\t},\r\n\tconvertTicksToLabels: function() {\r\n\t\tvar me = this;\r\n\t\t// Convert ticks to strings\r\n\t\tvar tickOpts = me.options.ticks;\r\n\t\tme.ticks = me.ticks.map(tickOpts.userCallback || tickOpts.callback, this);\r\n\t},\r\n\tafterTickToLabelConversion: function() {\r\n\t\thelpers$1.callback(this.options.afterTickToLabelConversion, [this]);\r\n\t},\r\n\r\n\t//\r\n\r\n\tbeforeCalculateTickRotation: function() {\r\n\t\thelpers$1.callback(this.options.beforeCalculateTickRotation, [this]);\r\n\t},\r\n\tcalculateTickRotation: function() {\r\n\t\tvar me = this;\r\n\t\tvar options = me.options;\r\n\t\tvar tickOpts = options.ticks;\r\n\t\tvar numTicks = me.getTicks().length;\r\n\t\tvar minRotation = tickOpts.minRotation || 0;\r\n\t\tvar maxRotation = tickOpts.maxRotation;\r\n\t\tvar labelRotation = minRotation;\r\n\t\tvar labelSizes, maxLabelWidth, maxLabelHeight, maxWidth, tickWidth, maxHeight, maxLabelDiagonal;\r\n\r\n\t\tif (!me._isVisible() || !tickOpts.display || minRotation >= maxRotation || numTicks <= 1 || !me.isHorizontal()) {\r\n\t\t\tme.labelRotation = minRotation;\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tlabelSizes = me._getLabelSizes();\r\n\t\tmaxLabelWidth = labelSizes.widest.width;\r\n\t\tmaxLabelHeight = labelSizes.highest.height - labelSizes.highest.offset;\r\n\r\n\t\t// Estimate the width of each grid based on the canvas width, the maximum\r\n\t\t// label width and the number of tick intervals\r\n\t\tmaxWidth = Math.min(me.maxWidth, me.chart.width - maxLabelWidth);\r\n\t\ttickWidth = options.offset ? me.maxWidth / numTicks : maxWidth / (numTicks - 1);\r\n\r\n\t\t// Allow 3 pixels x2 padding either side for label readability\r\n\t\tif (maxLabelWidth + 6 > tickWidth) {\r\n\t\t\ttickWidth = maxWidth / (numTicks - (options.offset ? 0.5 : 1));\r\n\t\t\tmaxHeight = me.maxHeight - getTickMarkLength(options.gridLines)\r\n\t\t\t\t- tickOpts.padding - getScaleLabelHeight(options.scaleLabel);\r\n\t\t\tmaxLabelDiagonal = Math.sqrt(maxLabelWidth * maxLabelWidth + maxLabelHeight * maxLabelHeight);\r\n\t\t\tlabelRotation = helpers$1.toDegrees(Math.min(\r\n\t\t\t\tMath.asin(Math.min((labelSizes.highest.height + 6) / tickWidth, 1)),\r\n\t\t\t\tMath.asin(Math.min(maxHeight / maxLabelDiagonal, 1)) - Math.asin(maxLabelHeight / maxLabelDiagonal)\r\n\t\t\t));\r\n\t\t\tlabelRotation = Math.max(minRotation, Math.min(maxRotation, labelRotation));\r\n\t\t}\r\n\r\n\t\tme.labelRotation = labelRotation;\r\n\t},\r\n\tafterCalculateTickRotation: function() {\r\n\t\thelpers$1.callback(this.options.afterCalculateTickRotation, [this]);\r\n\t},\r\n\r\n\t//\r\n\r\n\tbeforeFit: function() {\r\n\t\thelpers$1.callback(this.options.beforeFit, [this]);\r\n\t},\r\n\tfit: function() {\r\n\t\tvar me = this;\r\n\t\t// Reset\r\n\t\tvar minSize = me.minSize = {\r\n\t\t\twidth: 0,\r\n\t\t\theight: 0\r\n\t\t};\r\n\r\n\t\tvar chart = me.chart;\r\n\t\tvar opts = me.options;\r\n\t\tvar tickOpts = opts.ticks;\r\n\t\tvar scaleLabelOpts = opts.scaleLabel;\r\n\t\tvar gridLineOpts = opts.gridLines;\r\n\t\tvar display = me._isVisible();\r\n\t\tvar isBottom = opts.position === 'bottom';\r\n\t\tvar isHorizontal = me.isHorizontal();\r\n\r\n\t\t// Width\r\n\t\tif (isHorizontal) {\r\n\t\t\tminSize.width = me.maxWidth;\r\n\t\t} else if (display) {\r\n\t\t\tminSize.width = getTickMarkLength(gridLineOpts) + getScaleLabelHeight(scaleLabelOpts);\r\n\t\t}\r\n\r\n\t\t// height\r\n\t\tif (!isHorizontal) {\r\n\t\t\tminSize.height = me.maxHeight; // fill all the height\r\n\t\t} else if (display) {\r\n\t\t\tminSize.height = getTickMarkLength(gridLineOpts) + getScaleLabelHeight(scaleLabelOpts);\r\n\t\t}\r\n\r\n\t\t// Don't bother fitting the ticks if we are not showing the labels\r\n\t\tif (tickOpts.display && display) {\r\n\t\t\tvar tickFonts = parseTickFontOptions(tickOpts);\r\n\t\t\tvar labelSizes = me._getLabelSizes();\r\n\t\t\tvar firstLabelSize = labelSizes.first;\r\n\t\t\tvar lastLabelSize = labelSizes.last;\r\n\t\t\tvar widestLabelSize = labelSizes.widest;\r\n\t\t\tvar highestLabelSize = labelSizes.highest;\r\n\t\t\tvar lineSpace = tickFonts.minor.lineHeight * 0.4;\r\n\t\t\tvar tickPadding = tickOpts.padding;\r\n\r\n\t\t\tif (isHorizontal) {\r\n\t\t\t\t// A horizontal axis is more constrained by the height.\r\n\t\t\t\tvar isRotated = me.labelRotation !== 0;\r\n\t\t\t\tvar angleRadians = helpers$1.toRadians(me.labelRotation);\r\n\t\t\t\tvar cosRotation = Math.cos(angleRadians);\r\n\t\t\t\tvar sinRotation = Math.sin(angleRadians);\r\n\r\n\t\t\t\tvar labelHeight = sinRotation * widestLabelSize.width\r\n\t\t\t\t\t+ cosRotation * (highestLabelSize.height - (isRotated ? highestLabelSize.offset : 0))\r\n\t\t\t\t\t+ (isRotated ? 0 : lineSpace); // padding\r\n\r\n\t\t\t\tminSize.height = Math.min(me.maxHeight, minSize.height + labelHeight + tickPadding);\r\n\r\n\t\t\t\tvar offsetLeft = me.getPixelForTick(0) - me.left;\r\n\t\t\t\tvar offsetRight = me.right - me.getPixelForTick(me.getTicks().length - 1);\r\n\t\t\t\tvar paddingLeft, paddingRight;\r\n\r\n\t\t\t\t// Ensure that our ticks are always inside the canvas. When rotated, ticks are right aligned\r\n\t\t\t\t// which means that the right padding is dominated by the font height\r\n\t\t\t\tif (isRotated) {\r\n\t\t\t\t\tpaddingLeft = isBottom ?\r\n\t\t\t\t\t\tcosRotation * firstLabelSize.width + sinRotation * firstLabelSize.offset :\r\n\t\t\t\t\t\tsinRotation * (firstLabelSize.height - firstLabelSize.offset);\r\n\t\t\t\t\tpaddingRight = isBottom ?\r\n\t\t\t\t\t\tsinRotation * (lastLabelSize.height - lastLabelSize.offset) :\r\n\t\t\t\t\t\tcosRotation * lastLabelSize.width + sinRotation * lastLabelSize.offset;\r\n\t\t\t\t} else {\r\n\t\t\t\t\tpaddingLeft = firstLabelSize.width / 2;\r\n\t\t\t\t\tpaddingRight = lastLabelSize.width / 2;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Adjust padding taking into account changes in offsets\r\n\t\t\t\t// and add 3 px to move away from canvas edges\r\n\t\t\t\tme.paddingLeft = Math.max((paddingLeft - offsetLeft) * me.width / (me.width - offsetLeft), 0) + 3;\r\n\t\t\t\tme.paddingRight = Math.max((paddingRight - offsetRight) * me.width / (me.width - offsetRight), 0) + 3;\r\n\t\t\t} else {\r\n\t\t\t\t// A vertical axis is more constrained by the width. Labels are the\r\n\t\t\t\t// dominant factor here, so get that length first and account for padding\r\n\t\t\t\tvar labelWidth = tickOpts.mirror ? 0 :\r\n\t\t\t\t\t// use lineSpace for consistency with horizontal axis\r\n\t\t\t\t\t// tickPadding is not implemented for horizontal\r\n\t\t\t\t\twidestLabelSize.width + tickPadding + lineSpace;\r\n\r\n\t\t\t\tminSize.width = Math.min(me.maxWidth, minSize.width + labelWidth);\r\n\r\n\t\t\t\tme.paddingTop = firstLabelSize.height / 2;\r\n\t\t\t\tme.paddingBottom = lastLabelSize.height / 2;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tme.handleMargins();\r\n\r\n\t\tif (isHorizontal) {\r\n\t\t\tme.width = me._length = chart.width - me.margins.left - me.margins.right;\r\n\t\t\tme.height = minSize.height;\r\n\t\t} else {\r\n\t\t\tme.width = minSize.width;\r\n\t\t\tme.height = me._length = chart.height - me.margins.top - me.margins.bottom;\r\n\t\t}\r\n\t},\r\n\r\n\t/**\r\n\t * Handle margins and padding interactions\r\n\t * @private\r\n\t */\r\n\thandleMargins: function() {\r\n\t\tvar me = this;\r\n\t\tif (me.margins) {\r\n\t\t\tme.margins.left = Math.max(me.paddingLeft, me.margins.left);\r\n\t\t\tme.margins.top = Math.max(me.paddingTop, me.margins.top);\r\n\t\t\tme.margins.right = Math.max(me.paddingRight, me.margins.right);\r\n\t\t\tme.margins.bottom = Math.max(me.paddingBottom, me.margins.bottom);\r\n\t\t}\r\n\t},\r\n\r\n\tafterFit: function() {\r\n\t\thelpers$1.callback(this.options.afterFit, [this]);\r\n\t},\r\n\r\n\t// Shared Methods\r\n\tisHorizontal: function() {\r\n\t\tvar pos = this.options.position;\r\n\t\treturn pos === 'top' || pos === 'bottom';\r\n\t},\r\n\tisFullWidth: function() {\r\n\t\treturn this.options.fullWidth;\r\n\t},\r\n\r\n\t// Get the correct value. NaN bad inputs, If the value type is object get the x or y based on whether we are horizontal or not\r\n\tgetRightValue: function(rawValue) {\r\n\t\t// Null and undefined values first\r\n\t\tif (isNullOrUndef(rawValue)) {\r\n\t\t\treturn NaN;\r\n\t\t}\r\n\t\t// isNaN(object) returns true, so make sure NaN is checking for a number; Discard Infinite values\r\n\t\tif ((typeof rawValue === 'number' || rawValue instanceof Number) && !isFinite(rawValue)) {\r\n\t\t\treturn NaN;\r\n\t\t}\r\n\r\n\t\t// If it is in fact an object, dive in one more level\r\n\t\tif (rawValue) {\r\n\t\t\tif (this.isHorizontal()) {\r\n\t\t\t\tif (rawValue.x !== undefined) {\r\n\t\t\t\t\treturn this.getRightValue(rawValue.x);\r\n\t\t\t\t}\r\n\t\t\t} else if (rawValue.y !== undefined) {\r\n\t\t\t\treturn this.getRightValue(rawValue.y);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Value is good, return it\r\n\t\treturn rawValue;\r\n\t},\r\n\r\n\t_convertTicksToLabels: function(ticks) {\r\n\t\tvar me = this;\r\n\t\tvar labels, i, ilen;\r\n\r\n\t\tme.ticks = ticks.map(function(tick) {\r\n\t\t\treturn tick.value;\r\n\t\t});\r\n\r\n\t\tme.beforeTickToLabelConversion();\r\n\r\n\t\t// New implementations should return the formatted tick labels but for BACKWARD\r\n\t\t// COMPAT, we still support no return (`this.ticks` internally changed by calling\r\n\t\t// this method and supposed to contain only string values).\r\n\t\tlabels = me.convertTicksToLabels(ticks) || me.ticks;\r\n\r\n\t\tme.afterTickToLabelConversion();\r\n\r\n\t\t// BACKWARD COMPAT: synchronize `_ticks` with labels (so potentially `this.ticks`)\r\n\t\tfor (i = 0, ilen = ticks.length; i < ilen; ++i) {\r\n\t\t\tticks[i].label = labels[i];\r\n\t\t}\r\n\r\n\t\treturn labels;\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_getLabelSizes: function() {\r\n\t\tvar me = this;\r\n\t\tvar labelSizes = me._labelSizes;\r\n\r\n\t\tif (!labelSizes) {\r\n\t\t\tme._labelSizes = labelSizes = computeLabelSizes(me.ctx, parseTickFontOptions(me.options.ticks), me.getTicks(), me.longestTextCache);\r\n\t\t\tme.longestLabelWidth = labelSizes.widest.width;\r\n\t\t}\r\n\r\n\t\treturn labelSizes;\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_parseValue: function(value) {\r\n\t\tvar start, end, min, max;\r\n\r\n\t\tif (isArray(value)) {\r\n\t\t\tstart = +this.getRightValue(value[0]);\r\n\t\t\tend = +this.getRightValue(value[1]);\r\n\t\t\tmin = Math.min(start, end);\r\n\t\t\tmax = Math.max(start, end);\r\n\t\t} else {\r\n\t\t\tvalue = +this.getRightValue(value);\r\n\t\t\tstart = undefined;\r\n\t\t\tend = value;\r\n\t\t\tmin = value;\r\n\t\t\tmax = value;\r\n\t\t}\r\n\r\n\t\treturn {\r\n\t\t\tmin: min,\r\n\t\t\tmax: max,\r\n\t\t\tstart: start,\r\n\t\t\tend: end\r\n\t\t};\r\n\t},\r\n\r\n\t/**\r\n\t* @private\r\n\t*/\r\n\t_getScaleLabel: function(rawValue) {\r\n\t\tvar v = this._parseValue(rawValue);\r\n\t\tif (v.start !== undefined) {\r\n\t\t\treturn '[' + v.start + ', ' + v.end + ']';\r\n\t\t}\r\n\r\n\t\treturn +this.getRightValue(rawValue);\r\n\t},\r\n\r\n\t/**\r\n\t * Used to get the value to display in the tooltip for the data at the given index\r\n\t * @param index\r\n\t * @param datasetIndex\r\n\t */\r\n\tgetLabelForIndex: helpers$1.noop,\r\n\r\n\t/**\r\n\t * Returns the location of the given data point. Value can either be an index or a numerical value\r\n\t * The coordinate (0, 0) is at the upper-left corner of the canvas\r\n\t * @param value\r\n\t * @param index\r\n\t * @param datasetIndex\r\n\t */\r\n\tgetPixelForValue: helpers$1.noop,\r\n\r\n\t/**\r\n\t * Used to get the data value from a given pixel. This is the inverse of getPixelForValue\r\n\t * The coordinate (0, 0) is at the upper-left corner of the canvas\r\n\t * @param pixel\r\n\t */\r\n\tgetValueForPixel: helpers$1.noop,\r\n\r\n\t/**\r\n\t * Returns the location of the tick at the given index\r\n\t * The coordinate (0, 0) is at the upper-left corner of the canvas\r\n\t */\r\n\tgetPixelForTick: function(index) {\r\n\t\tvar me = this;\r\n\t\tvar offset = me.options.offset;\r\n\t\tvar numTicks = me._ticks.length;\r\n\t\tvar tickWidth = 1 / Math.max(numTicks - (offset ? 0 : 1), 1);\r\n\r\n\t\treturn index < 0 || index > numTicks - 1\r\n\t\t\t? null\r\n\t\t\t: me.getPixelForDecimal(index * tickWidth + (offset ? tickWidth / 2 : 0));\r\n\t},\r\n\r\n\t/**\r\n\t * Utility for getting the pixel location of a percentage of scale\r\n\t * The coordinate (0, 0) is at the upper-left corner of the canvas\r\n\t */\r\n\tgetPixelForDecimal: function(decimal) {\r\n\t\tvar me = this;\r\n\r\n\t\tif (me._reversePixels) {\r\n\t\t\tdecimal = 1 - decimal;\r\n\t\t}\r\n\r\n\t\treturn me._startPixel + decimal * me._length;\r\n\t},\r\n\r\n\tgetDecimalForPixel: function(pixel) {\r\n\t\tvar decimal = (pixel - this._startPixel) / this._length;\r\n\t\treturn this._reversePixels ? 1 - decimal : decimal;\r\n\t},\r\n\r\n\t/**\r\n\t * Returns the pixel for the minimum chart value\r\n\t * The coordinate (0, 0) is at the upper-left corner of the canvas\r\n\t */\r\n\tgetBasePixel: function() {\r\n\t\treturn this.getPixelForValue(this.getBaseValue());\r\n\t},\r\n\r\n\tgetBaseValue: function() {\r\n\t\tvar me = this;\r\n\t\tvar min = me.min;\r\n\t\tvar max = me.max;\r\n\r\n\t\treturn me.beginAtZero ? 0 :\r\n\t\t\tmin < 0 && max < 0 ? max :\r\n\t\t\tmin > 0 && max > 0 ? min :\r\n\t\t\t0;\r\n\t},\r\n\r\n\t/**\r\n\t * Returns a subset of ticks to be plotted to avoid overlapping labels.\r\n\t * @private\r\n\t */\r\n\t_autoSkip: function(ticks) {\r\n\t\tvar me = this;\r\n\t\tvar tickOpts = me.options.ticks;\r\n\t\tvar axisLength = me._length;\r\n\t\tvar ticksLimit = tickOpts.maxTicksLimit || axisLength / me._tickSize() + 1;\r\n\t\tvar majorIndices = tickOpts.major.enabled ? getMajorIndices(ticks) : [];\r\n\t\tvar numMajorIndices = majorIndices.length;\r\n\t\tvar first = majorIndices[0];\r\n\t\tvar last = majorIndices[numMajorIndices - 1];\r\n\t\tvar i, ilen, spacing, avgMajorSpacing;\r\n\r\n\t\t// If there are too many major ticks to display them all\r\n\t\tif (numMajorIndices > ticksLimit) {\r\n\t\t\tskipMajors(ticks, majorIndices, numMajorIndices / ticksLimit);\r\n\t\t\treturn nonSkipped(ticks);\r\n\t\t}\r\n\r\n\t\tspacing = calculateSpacing(majorIndices, ticks, axisLength, ticksLimit);\r\n\r\n\t\tif (numMajorIndices > 0) {\r\n\t\t\tfor (i = 0, ilen = numMajorIndices - 1; i < ilen; i++) {\r\n\t\t\t\tskip(ticks, spacing, majorIndices[i], majorIndices[i + 1]);\r\n\t\t\t}\r\n\t\t\tavgMajorSpacing = numMajorIndices > 1 ? (last - first) / (numMajorIndices - 1) : null;\r\n\t\t\tskip(ticks, spacing, helpers$1.isNullOrUndef(avgMajorSpacing) ? 0 : first - avgMajorSpacing, first);\r\n\t\t\tskip(ticks, spacing, last, helpers$1.isNullOrUndef(avgMajorSpacing) ? ticks.length : last + avgMajorSpacing);\r\n\t\t\treturn nonSkipped(ticks);\r\n\t\t}\r\n\t\tskip(ticks, spacing);\r\n\t\treturn nonSkipped(ticks);\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_tickSize: function() {\r\n\t\tvar me = this;\r\n\t\tvar optionTicks = me.options.ticks;\r\n\r\n\t\t// Calculate space needed by label in axis direction.\r\n\t\tvar rot = helpers$1.toRadians(me.labelRotation);\r\n\t\tvar cos = Math.abs(Math.cos(rot));\r\n\t\tvar sin = Math.abs(Math.sin(rot));\r\n\r\n\t\tvar labelSizes = me._getLabelSizes();\r\n\t\tvar padding = optionTicks.autoSkipPadding || 0;\r\n\t\tvar w = labelSizes ? labelSizes.widest.width + padding : 0;\r\n\t\tvar h = labelSizes ? labelSizes.highest.height + padding : 0;\r\n\r\n\t\t// Calculate space needed for 1 tick in axis direction.\r\n\t\treturn me.isHorizontal()\r\n\t\t\t? h * cos > w * sin ? w / cos : h / sin\r\n\t\t\t: h * sin < w * cos ? h / cos : w / sin;\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_isVisible: function() {\r\n\t\tvar me = this;\r\n\t\tvar chart = me.chart;\r\n\t\tvar display = me.options.display;\r\n\t\tvar i, ilen, meta;\r\n\r\n\t\tif (display !== 'auto') {\r\n\t\t\treturn !!display;\r\n\t\t}\r\n\r\n\t\t// When 'auto', the scale is visible if at least one associated dataset is visible.\r\n\t\tfor (i = 0, ilen = chart.data.datasets.length; i < ilen; ++i) {\r\n\t\t\tif (chart.isDatasetVisible(i)) {\r\n\t\t\t\tmeta = chart.getDatasetMeta(i);\r\n\t\t\t\tif (meta.xAxisID === me.id || meta.yAxisID === me.id) {\r\n\t\t\t\t\treturn true;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn false;\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_computeGridLineItems: function(chartArea) {\r\n\t\tvar me = this;\r\n\t\tvar chart = me.chart;\r\n\t\tvar options = me.options;\r\n\t\tvar gridLines = options.gridLines;\r\n\t\tvar position = options.position;\r\n\t\tvar offsetGridLines = gridLines.offsetGridLines;\r\n\t\tvar isHorizontal = me.isHorizontal();\r\n\t\tvar ticks = me._ticksToDraw;\r\n\t\tvar ticksLength = ticks.length + (offsetGridLines ? 1 : 0);\r\n\r\n\t\tvar tl = getTickMarkLength(gridLines);\r\n\t\tvar items = [];\r\n\t\tvar axisWidth = gridLines.drawBorder ? valueAtIndexOrDefault(gridLines.lineWidth, 0, 0) : 0;\r\n\t\tvar axisHalfWidth = axisWidth / 2;\r\n\t\tvar alignPixel = helpers$1._alignPixel;\r\n\t\tvar alignBorderValue = function(pixel) {\r\n\t\t\treturn alignPixel(chart, pixel, axisWidth);\r\n\t\t};\r\n\t\tvar borderValue, i, tick, lineValue, alignedLineValue;\r\n\t\tvar tx1, ty1, tx2, ty2, x1, y1, x2, y2, lineWidth, lineColor, borderDash, borderDashOffset;\r\n\r\n\t\tif (position === 'top') {\r\n\t\t\tborderValue = alignBorderValue(me.bottom);\r\n\t\t\tty1 = me.bottom - tl;\r\n\t\t\tty2 = borderValue - axisHalfWidth;\r\n\t\t\ty1 = alignBorderValue(chartArea.top) + axisHalfWidth;\r\n\t\t\ty2 = chartArea.bottom;\r\n\t\t} else if (position === 'bottom') {\r\n\t\t\tborderValue = alignBorderValue(me.top);\r\n\t\t\ty1 = chartArea.top;\r\n\t\t\ty2 = alignBorderValue(chartArea.bottom) - axisHalfWidth;\r\n\t\t\tty1 = borderValue + axisHalfWidth;\r\n\t\t\tty2 = me.top + tl;\r\n\t\t} else if (position === 'left') {\r\n\t\t\tborderValue = alignBorderValue(me.right);\r\n\t\t\ttx1 = me.right - tl;\r\n\t\t\ttx2 = borderValue - axisHalfWidth;\r\n\t\t\tx1 = alignBorderValue(chartArea.left) + axisHalfWidth;\r\n\t\t\tx2 = chartArea.right;\r\n\t\t} else {\r\n\t\t\tborderValue = alignBorderValue(me.left);\r\n\t\t\tx1 = chartArea.left;\r\n\t\t\tx2 = alignBorderValue(chartArea.right) - axisHalfWidth;\r\n\t\t\ttx1 = borderValue + axisHalfWidth;\r\n\t\t\ttx2 = me.left + tl;\r\n\t\t}\r\n\r\n\t\tfor (i = 0; i < ticksLength; ++i) {\r\n\t\t\ttick = ticks[i] || {};\r\n\r\n\t\t\t// autoskipper skipped this tick (#4635)\r\n\t\t\tif (isNullOrUndef(tick.label) && i < ticks.length) {\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\r\n\t\t\tif (i === me.zeroLineIndex && options.offset === offsetGridLines) {\r\n\t\t\t\t// Draw the first index specially\r\n\t\t\t\tlineWidth = gridLines.zeroLineWidth;\r\n\t\t\t\tlineColor = gridLines.zeroLineColor;\r\n\t\t\t\tborderDash = gridLines.zeroLineBorderDash || [];\r\n\t\t\t\tborderDashOffset = gridLines.zeroLineBorderDashOffset || 0.0;\r\n\t\t\t} else {\r\n\t\t\t\tlineWidth = valueAtIndexOrDefault(gridLines.lineWidth, i, 1);\r\n\t\t\t\tlineColor = valueAtIndexOrDefault(gridLines.color, i, 'rgba(0,0,0,0.1)');\r\n\t\t\t\tborderDash = gridLines.borderDash || [];\r\n\t\t\t\tborderDashOffset = gridLines.borderDashOffset || 0.0;\r\n\t\t\t}\r\n\r\n\t\t\tlineValue = getPixelForGridLine(me, tick._index || i, offsetGridLines);\r\n\r\n\t\t\t// Skip if the pixel is out of the range\r\n\t\t\tif (lineValue === undefined) {\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\r\n\t\t\talignedLineValue = alignPixel(chart, lineValue, lineWidth);\r\n\r\n\t\t\tif (isHorizontal) {\r\n\t\t\t\ttx1 = tx2 = x1 = x2 = alignedLineValue;\r\n\t\t\t} else {\r\n\t\t\t\tty1 = ty2 = y1 = y2 = alignedLineValue;\r\n\t\t\t}\r\n\r\n\t\t\titems.push({\r\n\t\t\t\ttx1: tx1,\r\n\t\t\t\tty1: ty1,\r\n\t\t\t\ttx2: tx2,\r\n\t\t\t\tty2: ty2,\r\n\t\t\t\tx1: x1,\r\n\t\t\t\ty1: y1,\r\n\t\t\t\tx2: x2,\r\n\t\t\t\ty2: y2,\r\n\t\t\t\twidth: lineWidth,\r\n\t\t\t\tcolor: lineColor,\r\n\t\t\t\tborderDash: borderDash,\r\n\t\t\t\tborderDashOffset: borderDashOffset,\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\titems.ticksLength = ticksLength;\r\n\t\titems.borderValue = borderValue;\r\n\r\n\t\treturn items;\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_computeLabelItems: function() {\r\n\t\tvar me = this;\r\n\t\tvar options = me.options;\r\n\t\tvar optionTicks = options.ticks;\r\n\t\tvar position = options.position;\r\n\t\tvar isMirrored = optionTicks.mirror;\r\n\t\tvar isHorizontal = me.isHorizontal();\r\n\t\tvar ticks = me._ticksToDraw;\r\n\t\tvar fonts = parseTickFontOptions(optionTicks);\r\n\t\tvar tickPadding = optionTicks.padding;\r\n\t\tvar tl = getTickMarkLength(options.gridLines);\r\n\t\tvar rotation = -helpers$1.toRadians(me.labelRotation);\r\n\t\tvar items = [];\r\n\t\tvar i, ilen, tick, label, x, y, textAlign, pixel, font, lineHeight, lineCount, textOffset;\r\n\r\n\t\tif (position === 'top') {\r\n\t\t\ty = me.bottom - tl - tickPadding;\r\n\t\t\ttextAlign = !rotation ? 'center' : 'left';\r\n\t\t} else if (position === 'bottom') {\r\n\t\t\ty = me.top + tl + tickPadding;\r\n\t\t\ttextAlign = !rotation ? 'center' : 'right';\r\n\t\t} else if (position === 'left') {\r\n\t\t\tx = me.right - (isMirrored ? 0 : tl) - tickPadding;\r\n\t\t\ttextAlign = isMirrored ? 'left' : 'right';\r\n\t\t} else {\r\n\t\t\tx = me.left + (isMirrored ? 0 : tl) + tickPadding;\r\n\t\t\ttextAlign = isMirrored ? 'right' : 'left';\r\n\t\t}\r\n\r\n\t\tfor (i = 0, ilen = ticks.length; i < ilen; ++i) {\r\n\t\t\ttick = ticks[i];\r\n\t\t\tlabel = tick.label;\r\n\r\n\t\t\t// autoskipper skipped this tick (#4635)\r\n\t\t\tif (isNullOrUndef(label)) {\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\r\n\t\t\tpixel = me.getPixelForTick(tick._index || i) + optionTicks.labelOffset;\r\n\t\t\tfont = tick.major ? fonts.major : fonts.minor;\r\n\t\t\tlineHeight = font.lineHeight;\r\n\t\t\tlineCount = isArray(label) ? label.length : 1;\r\n\r\n\t\t\tif (isHorizontal) {\r\n\t\t\t\tx = pixel;\r\n\t\t\t\ttextOffset = position === 'top'\r\n\t\t\t\t\t? ((!rotation ? 0.5 : 1) - lineCount) * lineHeight\r\n\t\t\t\t\t: (!rotation ? 0.5 : 0) * lineHeight;\r\n\t\t\t} else {\r\n\t\t\t\ty = pixel;\r\n\t\t\t\ttextOffset = (1 - lineCount) * lineHeight / 2;\r\n\t\t\t}\r\n\r\n\t\t\titems.push({\r\n\t\t\t\tx: x,\r\n\t\t\t\ty: y,\r\n\t\t\t\trotation: rotation,\r\n\t\t\t\tlabel: label,\r\n\t\t\t\tfont: font,\r\n\t\t\t\ttextOffset: textOffset,\r\n\t\t\t\ttextAlign: textAlign\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\treturn items;\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_drawGrid: function(chartArea) {\r\n\t\tvar me = this;\r\n\t\tvar gridLines = me.options.gridLines;\r\n\r\n\t\tif (!gridLines.display) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tvar ctx = me.ctx;\r\n\t\tvar chart = me.chart;\r\n\t\tvar alignPixel = helpers$1._alignPixel;\r\n\t\tvar axisWidth = gridLines.drawBorder ? valueAtIndexOrDefault(gridLines.lineWidth, 0, 0) : 0;\r\n\t\tvar items = me._gridLineItems || (me._gridLineItems = me._computeGridLineItems(chartArea));\r\n\t\tvar width, color, i, ilen, item;\r\n\r\n\t\tfor (i = 0, ilen = items.length; i < ilen; ++i) {\r\n\t\t\titem = items[i];\r\n\t\t\twidth = item.width;\r\n\t\t\tcolor = item.color;\r\n\r\n\t\t\tif (width && color) {\r\n\t\t\t\tctx.save();\r\n\t\t\t\tctx.lineWidth = width;\r\n\t\t\t\tctx.strokeStyle = color;\r\n\t\t\t\tif (ctx.setLineDash) {\r\n\t\t\t\t\tctx.setLineDash(item.borderDash);\r\n\t\t\t\t\tctx.lineDashOffset = item.borderDashOffset;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tctx.beginPath();\r\n\r\n\t\t\t\tif (gridLines.drawTicks) {\r\n\t\t\t\t\tctx.moveTo(item.tx1, item.ty1);\r\n\t\t\t\t\tctx.lineTo(item.tx2, item.ty2);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (gridLines.drawOnChartArea) {\r\n\t\t\t\t\tctx.moveTo(item.x1, item.y1);\r\n\t\t\t\t\tctx.lineTo(item.x2, item.y2);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tctx.stroke();\r\n\t\t\t\tctx.restore();\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (axisWidth) {\r\n\t\t\t// Draw the line at the edge of the axis\r\n\t\t\tvar firstLineWidth = axisWidth;\r\n\t\t\tvar lastLineWidth = valueAtIndexOrDefault(gridLines.lineWidth, items.ticksLength - 1, 1);\r\n\t\t\tvar borderValue = items.borderValue;\r\n\t\t\tvar x1, x2, y1, y2;\r\n\r\n\t\t\tif (me.isHorizontal()) {\r\n\t\t\t\tx1 = alignPixel(chart, me.left, firstLineWidth) - firstLineWidth / 2;\r\n\t\t\t\tx2 = alignPixel(chart, me.right, lastLineWidth) + lastLineWidth / 2;\r\n\t\t\t\ty1 = y2 = borderValue;\r\n\t\t\t} else {\r\n\t\t\t\ty1 = alignPixel(chart, me.top, firstLineWidth) - firstLineWidth / 2;\r\n\t\t\t\ty2 = alignPixel(chart, me.bottom, lastLineWidth) + lastLineWidth / 2;\r\n\t\t\t\tx1 = x2 = borderValue;\r\n\t\t\t}\r\n\r\n\t\t\tctx.lineWidth = axisWidth;\r\n\t\t\tctx.strokeStyle = valueAtIndexOrDefault(gridLines.color, 0);\r\n\t\t\tctx.beginPath();\r\n\t\t\tctx.moveTo(x1, y1);\r\n\t\t\tctx.lineTo(x2, y2);\r\n\t\t\tctx.stroke();\r\n\t\t}\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_drawLabels: function() {\r\n\t\tvar me = this;\r\n\t\tvar optionTicks = me.options.ticks;\r\n\r\n\t\tif (!optionTicks.display) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tvar ctx = me.ctx;\r\n\t\tvar items = me._labelItems || (me._labelItems = me._computeLabelItems());\r\n\t\tvar i, j, ilen, jlen, item, tickFont, label, y;\r\n\r\n\t\tfor (i = 0, ilen = items.length; i < ilen; ++i) {\r\n\t\t\titem = items[i];\r\n\t\t\ttickFont = item.font;\r\n\r\n\t\t\t// Make sure we draw text in the correct color and font\r\n\t\t\tctx.save();\r\n\t\t\tctx.translate(item.x, item.y);\r\n\t\t\tctx.rotate(item.rotation);\r\n\t\t\tctx.font = tickFont.string;\r\n\t\t\tctx.fillStyle = tickFont.color;\r\n\t\t\tctx.textBaseline = 'middle';\r\n\t\t\tctx.textAlign = item.textAlign;\r\n\r\n\t\t\tlabel = item.label;\r\n\t\t\ty = item.textOffset;\r\n\t\t\tif (isArray(label)) {\r\n\t\t\t\tfor (j = 0, jlen = label.length; j < jlen; ++j) {\r\n\t\t\t\t\t// We just make sure the multiline element is a string here..\r\n\t\t\t\t\tctx.fillText('' + label[j], 0, y);\r\n\t\t\t\t\ty += tickFont.lineHeight;\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tctx.fillText(label, 0, y);\r\n\t\t\t}\r\n\t\t\tctx.restore();\r\n\t\t}\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_drawTitle: function() {\r\n\t\tvar me = this;\r\n\t\tvar ctx = me.ctx;\r\n\t\tvar options = me.options;\r\n\t\tvar scaleLabel = options.scaleLabel;\r\n\r\n\t\tif (!scaleLabel.display) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tvar scaleLabelFontColor = valueOrDefault$a(scaleLabel.fontColor, core_defaults.global.defaultFontColor);\r\n\t\tvar scaleLabelFont = helpers$1.options._parseFont(scaleLabel);\r\n\t\tvar scaleLabelPadding = helpers$1.options.toPadding(scaleLabel.padding);\r\n\t\tvar halfLineHeight = scaleLabelFont.lineHeight / 2;\r\n\t\tvar position = options.position;\r\n\t\tvar rotation = 0;\r\n\t\tvar scaleLabelX, scaleLabelY;\r\n\r\n\t\tif (me.isHorizontal()) {\r\n\t\t\tscaleLabelX = me.left + me.width / 2; // midpoint of the width\r\n\t\t\tscaleLabelY = position === 'bottom'\r\n\t\t\t\t? me.bottom - halfLineHeight - scaleLabelPadding.bottom\r\n\t\t\t\t: me.top + halfLineHeight + scaleLabelPadding.top;\r\n\t\t} else {\r\n\t\t\tvar isLeft = position === 'left';\r\n\t\t\tscaleLabelX = isLeft\r\n\t\t\t\t? me.left + halfLineHeight + scaleLabelPadding.top\r\n\t\t\t\t: me.right - halfLineHeight - scaleLabelPadding.top;\r\n\t\t\tscaleLabelY = me.top + me.height / 2;\r\n\t\t\trotation = isLeft ? -0.5 * Math.PI : 0.5 * Math.PI;\r\n\t\t}\r\n\r\n\t\tctx.save();\r\n\t\tctx.translate(scaleLabelX, scaleLabelY);\r\n\t\tctx.rotate(rotation);\r\n\t\tctx.textAlign = 'center';\r\n\t\tctx.textBaseline = 'middle';\r\n\t\tctx.fillStyle = scaleLabelFontColor; // render in correct colour\r\n\t\tctx.font = scaleLabelFont.string;\r\n\t\tctx.fillText(scaleLabel.labelString, 0, 0);\r\n\t\tctx.restore();\r\n\t},\r\n\r\n\tdraw: function(chartArea) {\r\n\t\tvar me = this;\r\n\r\n\t\tif (!me._isVisible()) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tme._drawGrid(chartArea);\r\n\t\tme._drawTitle();\r\n\t\tme._drawLabels();\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_layers: function() {\r\n\t\tvar me = this;\r\n\t\tvar opts = me.options;\r\n\t\tvar tz = opts.ticks && opts.ticks.z || 0;\r\n\t\tvar gz = opts.gridLines && opts.gridLines.z || 0;\r\n\r\n\t\tif (!me._isVisible() || tz === gz || me.draw !== me._draw) {\r\n\t\t\t// backward compatibility: draw has been overridden by custom scale\r\n\t\t\treturn [{\r\n\t\t\t\tz: tz,\r\n\t\t\t\tdraw: function() {\r\n\t\t\t\t\tme.draw.apply(me, arguments);\r\n\t\t\t\t}\r\n\t\t\t}];\r\n\t\t}\r\n\r\n\t\treturn [{\r\n\t\t\tz: gz,\r\n\t\t\tdraw: function() {\r\n\t\t\t\tme._drawGrid.apply(me, arguments);\r\n\t\t\t\tme._drawTitle.apply(me, arguments);\r\n\t\t\t}\r\n\t\t}, {\r\n\t\t\tz: tz,\r\n\t\t\tdraw: function() {\r\n\t\t\t\tme._drawLabels.apply(me, arguments);\r\n\t\t\t}\r\n\t\t}];\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_getMatchingVisibleMetas: function(type) {\r\n\t\tvar me = this;\r\n\t\tvar isHorizontal = me.isHorizontal();\r\n\t\treturn me.chart._getSortedVisibleDatasetMetas()\r\n\t\t\t.filter(function(meta) {\r\n\t\t\t\treturn (!type || meta.type === type)\r\n\t\t\t\t\t&& (isHorizontal ? meta.xAxisID === me.id : meta.yAxisID === me.id);\r\n\t\t\t});\r\n\t}\r\n});\r\n\r\nScale.prototype._draw = Scale.prototype.draw;\r\n\r\nvar core_scale = Scale;\n\nvar isNullOrUndef$1 = helpers$1.isNullOrUndef;\r\n\r\nvar defaultConfig = {\r\n\tposition: 'bottom'\r\n};\r\n\r\nvar scale_category = core_scale.extend({\r\n\tdetermineDataLimits: function() {\r\n\t\tvar me = this;\r\n\t\tvar labels = me._getLabels();\r\n\t\tvar ticksOpts = me.options.ticks;\r\n\t\tvar min = ticksOpts.min;\r\n\t\tvar max = ticksOpts.max;\r\n\t\tvar minIndex = 0;\r\n\t\tvar maxIndex = labels.length - 1;\r\n\t\tvar findIndex;\r\n\r\n\t\tif (min !== undefined) {\r\n\t\t\t// user specified min value\r\n\t\t\tfindIndex = labels.indexOf(min);\r\n\t\t\tif (findIndex >= 0) {\r\n\t\t\t\tminIndex = findIndex;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (max !== undefined) {\r\n\t\t\t// user specified max value\r\n\t\t\tfindIndex = labels.indexOf(max);\r\n\t\t\tif (findIndex >= 0) {\r\n\t\t\t\tmaxIndex = findIndex;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tme.minIndex = minIndex;\r\n\t\tme.maxIndex = maxIndex;\r\n\t\tme.min = labels[minIndex];\r\n\t\tme.max = labels[maxIndex];\r\n\t},\r\n\r\n\tbuildTicks: function() {\r\n\t\tvar me = this;\r\n\t\tvar labels = me._getLabels();\r\n\t\tvar minIndex = me.minIndex;\r\n\t\tvar maxIndex = me.maxIndex;\r\n\r\n\t\t// If we are viewing some subset of labels, slice the original array\r\n\t\tme.ticks = (minIndex === 0 && maxIndex === labels.length - 1) ? labels : labels.slice(minIndex, maxIndex + 1);\r\n\t},\r\n\r\n\tgetLabelForIndex: function(index, datasetIndex) {\r\n\t\tvar me = this;\r\n\t\tvar chart = me.chart;\r\n\r\n\t\tif (chart.getDatasetMeta(datasetIndex).controller._getValueScaleId() === me.id) {\r\n\t\t\treturn me.getRightValue(chart.data.datasets[datasetIndex].data[index]);\r\n\t\t}\r\n\r\n\t\treturn me._getLabels()[index];\r\n\t},\r\n\r\n\t_configure: function() {\r\n\t\tvar me = this;\r\n\t\tvar offset = me.options.offset;\r\n\t\tvar ticks = me.ticks;\r\n\r\n\t\tcore_scale.prototype._configure.call(me);\r\n\r\n\t\tif (!me.isHorizontal()) {\r\n\t\t\t// For backward compatibility, vertical category scale reverse is inverted.\r\n\t\t\tme._reversePixels = !me._reversePixels;\r\n\t\t}\r\n\r\n\t\tif (!ticks) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tme._startValue = me.minIndex - (offset ? 0.5 : 0);\r\n\t\tme._valueRange = Math.max(ticks.length - (offset ? 0 : 1), 1);\r\n\t},\r\n\r\n\t// Used to get data value locations. Value can either be an index or a numerical value\r\n\tgetPixelForValue: function(value, index, datasetIndex) {\r\n\t\tvar me = this;\r\n\t\tvar valueCategory, labels, idx;\r\n\r\n\t\tif (!isNullOrUndef$1(index) && !isNullOrUndef$1(datasetIndex)) {\r\n\t\t\tvalue = me.chart.data.datasets[datasetIndex].data[index];\r\n\t\t}\r\n\r\n\t\t// If value is a data object, then index is the index in the data array,\r\n\t\t// not the index of the scale. We need to change that.\r\n\t\tif (!isNullOrUndef$1(value)) {\r\n\t\t\tvalueCategory = me.isHorizontal() ? value.x : value.y;\r\n\t\t}\r\n\t\tif (valueCategory !== undefined || (value !== undefined && isNaN(index))) {\r\n\t\t\tlabels = me._getLabels();\r\n\t\t\tvalue = helpers$1.valueOrDefault(valueCategory, value);\r\n\t\t\tidx = labels.indexOf(value);\r\n\t\t\tindex = idx !== -1 ? idx : index;\r\n\t\t\tif (isNaN(index)) {\r\n\t\t\t\tindex = value;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn me.getPixelForDecimal((index - me._startValue) / me._valueRange);\r\n\t},\r\n\r\n\tgetPixelForTick: function(index) {\r\n\t\tvar ticks = this.ticks;\r\n\t\treturn index < 0 || index > ticks.length - 1\r\n\t\t\t? null\r\n\t\t\t: this.getPixelForValue(ticks[index], index + this.minIndex);\r\n\t},\r\n\r\n\tgetValueForPixel: function(pixel) {\r\n\t\tvar me = this;\r\n\t\tvar value = Math.round(me._startValue + me.getDecimalForPixel(pixel) * me._valueRange);\r\n\t\treturn Math.min(Math.max(value, 0), me.ticks.length - 1);\r\n\t},\r\n\r\n\tgetBasePixel: function() {\r\n\t\treturn this.bottom;\r\n\t}\r\n});\r\n\r\n// INTERNAL: static default options, registered in src/index.js\r\nvar _defaults = defaultConfig;\nscale_category._defaults = _defaults;\n\nvar noop = helpers$1.noop;\r\nvar isNullOrUndef$2 = helpers$1.isNullOrUndef;\r\n\r\n/**\r\n * Generate a set of linear ticks\r\n * @param generationOptions the options used to generate the ticks\r\n * @param dataRange the range of the data\r\n * @returns {number[]} array of tick values\r\n */\r\nfunction generateTicks(generationOptions, dataRange) {\r\n\tvar ticks = [];\r\n\t// To get a \"nice\" value for the tick spacing, we will use the appropriately named\r\n\t// \"nice number\" algorithm. See https://stackoverflow.com/questions/8506881/nice-label-algorithm-for-charts-with-minimum-ticks\r\n\t// for details.\r\n\r\n\tvar MIN_SPACING = 1e-14;\r\n\tvar stepSize = generationOptions.stepSize;\r\n\tvar unit = stepSize || 1;\r\n\tvar maxNumSpaces = generationOptions.maxTicks - 1;\r\n\tvar min = generationOptions.min;\r\n\tvar max = generationOptions.max;\r\n\tvar precision = generationOptions.precision;\r\n\tvar rmin = dataRange.min;\r\n\tvar rmax = dataRange.max;\r\n\tvar spacing = helpers$1.niceNum((rmax - rmin) / maxNumSpaces / unit) * unit;\r\n\tvar factor, niceMin, niceMax, numSpaces;\r\n\r\n\t// Beyond MIN_SPACING floating point numbers being to lose precision\r\n\t// such that we can't do the math necessary to generate ticks\r\n\tif (spacing < MIN_SPACING && isNullOrUndef$2(min) && isNullOrUndef$2(max)) {\r\n\t\treturn [rmin, rmax];\r\n\t}\r\n\r\n\tnumSpaces = Math.ceil(rmax / spacing) - Math.floor(rmin / spacing);\r\n\tif (numSpaces > maxNumSpaces) {\r\n\t\t// If the calculated num of spaces exceeds maxNumSpaces, recalculate it\r\n\t\tspacing = helpers$1.niceNum(numSpaces * spacing / maxNumSpaces / unit) * unit;\r\n\t}\r\n\r\n\tif (stepSize || isNullOrUndef$2(precision)) {\r\n\t\t// If a precision is not specified, calculate factor based on spacing\r\n\t\tfactor = Math.pow(10, helpers$1._decimalPlaces(spacing));\r\n\t} else {\r\n\t\t// If the user specified a precision, round to that number of decimal places\r\n\t\tfactor = Math.pow(10, precision);\r\n\t\tspacing = Math.ceil(spacing * factor) / factor;\r\n\t}\r\n\r\n\tniceMin = Math.floor(rmin / spacing) * spacing;\r\n\tniceMax = Math.ceil(rmax / spacing) * spacing;\r\n\r\n\t// If min, max and stepSize is set and they make an evenly spaced scale use it.\r\n\tif (stepSize) {\r\n\t\t// If very close to our whole number, use it.\r\n\t\tif (!isNullOrUndef$2(min) && helpers$1.almostWhole(min / spacing, spacing / 1000)) {\r\n\t\t\tniceMin = min;\r\n\t\t}\r\n\t\tif (!isNullOrUndef$2(max) && helpers$1.almostWhole(max / spacing, spacing / 1000)) {\r\n\t\t\tniceMax = max;\r\n\t\t}\r\n\t}\r\n\r\n\tnumSpaces = (niceMax - niceMin) / spacing;\r\n\t// If very close to our rounded value, use it.\r\n\tif (helpers$1.almostEquals(numSpaces, Math.round(numSpaces), spacing / 1000)) {\r\n\t\tnumSpaces = Math.round(numSpaces);\r\n\t} else {\r\n\t\tnumSpaces = Math.ceil(numSpaces);\r\n\t}\r\n\r\n\tniceMin = Math.round(niceMin * factor) / factor;\r\n\tniceMax = Math.round(niceMax * factor) / factor;\r\n\tticks.push(isNullOrUndef$2(min) ? niceMin : min);\r\n\tfor (var j = 1; j < numSpaces; ++j) {\r\n\t\tticks.push(Math.round((niceMin + j * spacing) * factor) / factor);\r\n\t}\r\n\tticks.push(isNullOrUndef$2(max) ? niceMax : max);\r\n\r\n\treturn ticks;\r\n}\r\n\r\nvar scale_linearbase = core_scale.extend({\r\n\tgetRightValue: function(value) {\r\n\t\tif (typeof value === 'string') {\r\n\t\t\treturn +value;\r\n\t\t}\r\n\t\treturn core_scale.prototype.getRightValue.call(this, value);\r\n\t},\r\n\r\n\thandleTickRangeOptions: function() {\r\n\t\tvar me = this;\r\n\t\tvar opts = me.options;\r\n\t\tvar tickOpts = opts.ticks;\r\n\r\n\t\t// If we are forcing it to begin at 0, but 0 will already be rendered on the chart,\r\n\t\t// do nothing since that would make the chart weird. If the user really wants a weird chart\r\n\t\t// axis, they can manually override it\r\n\t\tif (tickOpts.beginAtZero) {\r\n\t\t\tvar minSign = helpers$1.sign(me.min);\r\n\t\t\tvar maxSign = helpers$1.sign(me.max);\r\n\r\n\t\t\tif (minSign < 0 && maxSign < 0) {\r\n\t\t\t\t// move the top up to 0\r\n\t\t\t\tme.max = 0;\r\n\t\t\t} else if (minSign > 0 && maxSign > 0) {\r\n\t\t\t\t// move the bottom down to 0\r\n\t\t\t\tme.min = 0;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tvar setMin = tickOpts.min !== undefined || tickOpts.suggestedMin !== undefined;\r\n\t\tvar setMax = tickOpts.max !== undefined || tickOpts.suggestedMax !== undefined;\r\n\r\n\t\tif (tickOpts.min !== undefined) {\r\n\t\t\tme.min = tickOpts.min;\r\n\t\t} else if (tickOpts.suggestedMin !== undefined) {\r\n\t\t\tif (me.min === null) {\r\n\t\t\t\tme.min = tickOpts.suggestedMin;\r\n\t\t\t} else {\r\n\t\t\t\tme.min = Math.min(me.min, tickOpts.suggestedMin);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (tickOpts.max !== undefined) {\r\n\t\t\tme.max = tickOpts.max;\r\n\t\t} else if (tickOpts.suggestedMax !== undefined) {\r\n\t\t\tif (me.max === null) {\r\n\t\t\t\tme.max = tickOpts.suggestedMax;\r\n\t\t\t} else {\r\n\t\t\t\tme.max = Math.max(me.max, tickOpts.suggestedMax);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (setMin !== setMax) {\r\n\t\t\t// We set the min or the max but not both.\r\n\t\t\t// So ensure that our range is good\r\n\t\t\t// Inverted or 0 length range can happen when\r\n\t\t\t// ticks.min is set, and no datasets are visible\r\n\t\t\tif (me.min >= me.max) {\r\n\t\t\t\tif (setMin) {\r\n\t\t\t\t\tme.max = me.min + 1;\r\n\t\t\t\t} else {\r\n\t\t\t\t\tme.min = me.max - 1;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (me.min === me.max) {\r\n\t\t\tme.max++;\r\n\r\n\t\t\tif (!tickOpts.beginAtZero) {\r\n\t\t\t\tme.min--;\r\n\t\t\t}\r\n\t\t}\r\n\t},\r\n\r\n\tgetTickLimit: function() {\r\n\t\tvar me = this;\r\n\t\tvar tickOpts = me.options.ticks;\r\n\t\tvar stepSize = tickOpts.stepSize;\r\n\t\tvar maxTicksLimit = tickOpts.maxTicksLimit;\r\n\t\tvar maxTicks;\r\n\r\n\t\tif (stepSize) {\r\n\t\t\tmaxTicks = Math.ceil(me.max / stepSize) - Math.floor(me.min / stepSize) + 1;\r\n\t\t} else {\r\n\t\t\tmaxTicks = me._computeTickLimit();\r\n\t\t\tmaxTicksLimit = maxTicksLimit || 11;\r\n\t\t}\r\n\r\n\t\tif (maxTicksLimit) {\r\n\t\t\tmaxTicks = Math.min(maxTicksLimit, maxTicks);\r\n\t\t}\r\n\r\n\t\treturn maxTicks;\r\n\t},\r\n\r\n\t_computeTickLimit: function() {\r\n\t\treturn Number.POSITIVE_INFINITY;\r\n\t},\r\n\r\n\thandleDirectionalChanges: noop,\r\n\r\n\tbuildTicks: function() {\r\n\t\tvar me = this;\r\n\t\tvar opts = me.options;\r\n\t\tvar tickOpts = opts.ticks;\r\n\r\n\t\t// Figure out what the max number of ticks we can support it is based on the size of\r\n\t\t// the axis area. For now, we say that the minimum tick spacing in pixels must be 40\r\n\t\t// We also limit the maximum number of ticks to 11 which gives a nice 10 squares on\r\n\t\t// the graph. Make sure we always have at least 2 ticks\r\n\t\tvar maxTicks = me.getTickLimit();\r\n\t\tmaxTicks = Math.max(2, maxTicks);\r\n\r\n\t\tvar numericGeneratorOptions = {\r\n\t\t\tmaxTicks: maxTicks,\r\n\t\t\tmin: tickOpts.min,\r\n\t\t\tmax: tickOpts.max,\r\n\t\t\tprecision: tickOpts.precision,\r\n\t\t\tstepSize: helpers$1.valueOrDefault(tickOpts.fixedStepSize, tickOpts.stepSize)\r\n\t\t};\r\n\t\tvar ticks = me.ticks = generateTicks(numericGeneratorOptions, me);\r\n\r\n\t\tme.handleDirectionalChanges();\r\n\r\n\t\t// At this point, we need to update our max and min given the tick values since we have expanded the\r\n\t\t// range of the scale\r\n\t\tme.max = helpers$1.max(ticks);\r\n\t\tme.min = helpers$1.min(ticks);\r\n\r\n\t\tif (tickOpts.reverse) {\r\n\t\t\tticks.reverse();\r\n\r\n\t\t\tme.start = me.max;\r\n\t\t\tme.end = me.min;\r\n\t\t} else {\r\n\t\t\tme.start = me.min;\r\n\t\t\tme.end = me.max;\r\n\t\t}\r\n\t},\r\n\r\n\tconvertTicksToLabels: function() {\r\n\t\tvar me = this;\r\n\t\tme.ticksAsNumbers = me.ticks.slice();\r\n\t\tme.zeroLineIndex = me.ticks.indexOf(0);\r\n\r\n\t\tcore_scale.prototype.convertTicksToLabels.call(me);\r\n\t},\r\n\r\n\t_configure: function() {\r\n\t\tvar me = this;\r\n\t\tvar ticks = me.getTicks();\r\n\t\tvar start = me.min;\r\n\t\tvar end = me.max;\r\n\t\tvar offset;\r\n\r\n\t\tcore_scale.prototype._configure.call(me);\r\n\r\n\t\tif (me.options.offset && ticks.length) {\r\n\t\t\toffset = (end - start) / Math.max(ticks.length - 1, 1) / 2;\r\n\t\t\tstart -= offset;\r\n\t\t\tend += offset;\r\n\t\t}\r\n\t\tme._startValue = start;\r\n\t\tme._endValue = end;\r\n\t\tme._valueRange = end - start;\r\n\t}\r\n});\n\nvar defaultConfig$1 = {\r\n\tposition: 'left',\r\n\tticks: {\r\n\t\tcallback: core_ticks.formatters.linear\r\n\t}\r\n};\r\n\r\nvar DEFAULT_MIN = 0;\r\nvar DEFAULT_MAX = 1;\r\n\r\nfunction getOrCreateStack(stacks, stacked, meta) {\r\n\tvar key = [\r\n\t\tmeta.type,\r\n\t\t// we have a separate stack for stack=undefined datasets when the opts.stacked is undefined\r\n\t\tstacked === undefined && meta.stack === undefined ? meta.index : '',\r\n\t\tmeta.stack\r\n\t].join('.');\r\n\r\n\tif (stacks[key] === undefined) {\r\n\t\tstacks[key] = {\r\n\t\t\tpos: [],\r\n\t\t\tneg: []\r\n\t\t};\r\n\t}\r\n\r\n\treturn stacks[key];\r\n}\r\n\r\nfunction stackData(scale, stacks, meta, data) {\r\n\tvar opts = scale.options;\r\n\tvar stacked = opts.stacked;\r\n\tvar stack = getOrCreateStack(stacks, stacked, meta);\r\n\tvar pos = stack.pos;\r\n\tvar neg = stack.neg;\r\n\tvar ilen = data.length;\r\n\tvar i, value;\r\n\r\n\tfor (i = 0; i < ilen; ++i) {\r\n\t\tvalue = scale._parseValue(data[i]);\r\n\t\tif (isNaN(value.min) || isNaN(value.max) || meta.data[i].hidden) {\r\n\t\t\tcontinue;\r\n\t\t}\r\n\r\n\t\tpos[i] = pos[i] || 0;\r\n\t\tneg[i] = neg[i] || 0;\r\n\r\n\t\tif (opts.relativePoints) {\r\n\t\t\tpos[i] = 100;\r\n\t\t} else if (value.min < 0 || value.max < 0) {\r\n\t\t\tneg[i] += value.min;\r\n\t\t} else {\r\n\t\t\tpos[i] += value.max;\r\n\t\t}\r\n\t}\r\n}\r\n\r\nfunction updateMinMax(scale, meta, data) {\r\n\tvar ilen = data.length;\r\n\tvar i, value;\r\n\r\n\tfor (i = 0; i < ilen; ++i) {\r\n\t\tvalue = scale._parseValue(data[i]);\r\n\t\tif (isNaN(value.min) || isNaN(value.max) || meta.data[i].hidden) {\r\n\t\t\tcontinue;\r\n\t\t}\r\n\r\n\t\tscale.min = Math.min(scale.min, value.min);\r\n\t\tscale.max = Math.max(scale.max, value.max);\r\n\t}\r\n}\r\n\r\nvar scale_linear = scale_linearbase.extend({\r\n\tdetermineDataLimits: function() {\r\n\t\tvar me = this;\r\n\t\tvar opts = me.options;\r\n\t\tvar chart = me.chart;\r\n\t\tvar datasets = chart.data.datasets;\r\n\t\tvar metasets = me._getMatchingVisibleMetas();\r\n\t\tvar hasStacks = opts.stacked;\r\n\t\tvar stacks = {};\r\n\t\tvar ilen = metasets.length;\r\n\t\tvar i, meta, data, values;\r\n\r\n\t\tme.min = Number.POSITIVE_INFINITY;\r\n\t\tme.max = Number.NEGATIVE_INFINITY;\r\n\r\n\t\tif (hasStacks === undefined) {\r\n\t\t\tfor (i = 0; !hasStacks && i < ilen; ++i) {\r\n\t\t\t\tmeta = metasets[i];\r\n\t\t\t\thasStacks = meta.stack !== undefined;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tfor (i = 0; i < ilen; ++i) {\r\n\t\t\tmeta = metasets[i];\r\n\t\t\tdata = datasets[meta.index].data;\r\n\t\t\tif (hasStacks) {\r\n\t\t\t\tstackData(me, stacks, meta, data);\r\n\t\t\t} else {\r\n\t\t\t\tupdateMinMax(me, meta, data);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\thelpers$1.each(stacks, function(stackValues) {\r\n\t\t\tvalues = stackValues.pos.concat(stackValues.neg);\r\n\t\t\tme.min = Math.min(me.min, helpers$1.min(values));\r\n\t\t\tme.max = Math.max(me.max, helpers$1.max(values));\r\n\t\t});\r\n\r\n\t\tme.min = helpers$1.isFinite(me.min) && !isNaN(me.min) ? me.min : DEFAULT_MIN;\r\n\t\tme.max = helpers$1.isFinite(me.max) && !isNaN(me.max) ? me.max : DEFAULT_MAX;\r\n\r\n\t\t// Common base implementation to handle ticks.min, ticks.max, ticks.beginAtZero\r\n\t\tme.handleTickRangeOptions();\r\n\t},\r\n\r\n\t// Returns the maximum number of ticks based on the scale dimension\r\n\t_computeTickLimit: function() {\r\n\t\tvar me = this;\r\n\t\tvar tickFont;\r\n\r\n\t\tif (me.isHorizontal()) {\r\n\t\t\treturn Math.ceil(me.width / 40);\r\n\t\t}\r\n\t\ttickFont = helpers$1.options._parseFont(me.options.ticks);\r\n\t\treturn Math.ceil(me.height / tickFont.lineHeight);\r\n\t},\r\n\r\n\t// Called after the ticks are built. We need\r\n\thandleDirectionalChanges: function() {\r\n\t\tif (!this.isHorizontal()) {\r\n\t\t\t// We are in a vertical orientation. The top value is the highest. So reverse the array\r\n\t\t\tthis.ticks.reverse();\r\n\t\t}\r\n\t},\r\n\r\n\tgetLabelForIndex: function(index, datasetIndex) {\r\n\t\treturn this._getScaleLabel(this.chart.data.datasets[datasetIndex].data[index]);\r\n\t},\r\n\r\n\t// Utils\r\n\tgetPixelForValue: function(value) {\r\n\t\tvar me = this;\r\n\t\treturn me.getPixelForDecimal((+me.getRightValue(value) - me._startValue) / me._valueRange);\r\n\t},\r\n\r\n\tgetValueForPixel: function(pixel) {\r\n\t\treturn this._startValue + this.getDecimalForPixel(pixel) * this._valueRange;\r\n\t},\r\n\r\n\tgetPixelForTick: function(index) {\r\n\t\tvar ticks = this.ticksAsNumbers;\r\n\t\tif (index < 0 || index > ticks.length - 1) {\r\n\t\t\treturn null;\r\n\t\t}\r\n\t\treturn this.getPixelForValue(ticks[index]);\r\n\t}\r\n});\r\n\r\n// INTERNAL: static default options, registered in src/index.js\r\nvar _defaults$1 = defaultConfig$1;\nscale_linear._defaults = _defaults$1;\n\nvar valueOrDefault$b = helpers$1.valueOrDefault;\r\nvar log10 = helpers$1.math.log10;\r\n\r\n/**\r\n * Generate a set of logarithmic ticks\r\n * @param generationOptions the options used to generate the ticks\r\n * @param dataRange the range of the data\r\n * @returns {number[]} array of tick values\r\n */\r\nfunction generateTicks$1(generationOptions, dataRange) {\r\n\tvar ticks = [];\r\n\r\n\tvar tickVal = valueOrDefault$b(generationOptions.min, Math.pow(10, Math.floor(log10(dataRange.min))));\r\n\r\n\tvar endExp = Math.floor(log10(dataRange.max));\r\n\tvar endSignificand = Math.ceil(dataRange.max / Math.pow(10, endExp));\r\n\tvar exp, significand;\r\n\r\n\tif (tickVal === 0) {\r\n\t\texp = Math.floor(log10(dataRange.minNotZero));\r\n\t\tsignificand = Math.floor(dataRange.minNotZero / Math.pow(10, exp));\r\n\r\n\t\tticks.push(tickVal);\r\n\t\ttickVal = significand * Math.pow(10, exp);\r\n\t} else {\r\n\t\texp = Math.floor(log10(tickVal));\r\n\t\tsignificand = Math.floor(tickVal / Math.pow(10, exp));\r\n\t}\r\n\tvar precision = exp < 0 ? Math.pow(10, Math.abs(exp)) : 1;\r\n\r\n\tdo {\r\n\t\tticks.push(tickVal);\r\n\r\n\t\t++significand;\r\n\t\tif (significand === 10) {\r\n\t\t\tsignificand = 1;\r\n\t\t\t++exp;\r\n\t\t\tprecision = exp >= 0 ? 1 : precision;\r\n\t\t}\r\n\r\n\t\ttickVal = Math.round(significand * Math.pow(10, exp) * precision) / precision;\r\n\t} while (exp < endExp || (exp === endExp && significand < endSignificand));\r\n\r\n\tvar lastTick = valueOrDefault$b(generationOptions.max, tickVal);\r\n\tticks.push(lastTick);\r\n\r\n\treturn ticks;\r\n}\r\n\r\nvar defaultConfig$2 = {\r\n\tposition: 'left',\r\n\r\n\t// label settings\r\n\tticks: {\r\n\t\tcallback: core_ticks.formatters.logarithmic\r\n\t}\r\n};\r\n\r\n// TODO(v3): change this to positiveOrDefault\r\nfunction nonNegativeOrDefault(value, defaultValue) {\r\n\treturn helpers$1.isFinite(value) && value >= 0 ? value : defaultValue;\r\n}\r\n\r\nvar scale_logarithmic = core_scale.extend({\r\n\tdetermineDataLimits: function() {\r\n\t\tvar me = this;\r\n\t\tvar opts = me.options;\r\n\t\tvar chart = me.chart;\r\n\t\tvar datasets = chart.data.datasets;\r\n\t\tvar isHorizontal = me.isHorizontal();\r\n\t\tfunction IDMatches(meta) {\r\n\t\t\treturn isHorizontal ? meta.xAxisID === me.id : meta.yAxisID === me.id;\r\n\t\t}\r\n\t\tvar datasetIndex, meta, value, data, i, ilen;\r\n\r\n\t\t// Calculate Range\r\n\t\tme.min = Number.POSITIVE_INFINITY;\r\n\t\tme.max = Number.NEGATIVE_INFINITY;\r\n\t\tme.minNotZero = Number.POSITIVE_INFINITY;\r\n\r\n\t\tvar hasStacks = opts.stacked;\r\n\t\tif (hasStacks === undefined) {\r\n\t\t\tfor (datasetIndex = 0; datasetIndex < datasets.length; datasetIndex++) {\r\n\t\t\t\tmeta = chart.getDatasetMeta(datasetIndex);\r\n\t\t\t\tif (chart.isDatasetVisible(datasetIndex) && IDMatches(meta) &&\r\n\t\t\t\t\tmeta.stack !== undefined) {\r\n\t\t\t\t\thasStacks = true;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (opts.stacked || hasStacks) {\r\n\t\t\tvar valuesPerStack = {};\r\n\r\n\t\t\tfor (datasetIndex = 0; datasetIndex < datasets.length; datasetIndex++) {\r\n\t\t\t\tmeta = chart.getDatasetMeta(datasetIndex);\r\n\t\t\t\tvar key = [\r\n\t\t\t\t\tmeta.type,\r\n\t\t\t\t\t// we have a separate stack for stack=undefined datasets when the opts.stacked is undefined\r\n\t\t\t\t\t((opts.stacked === undefined && meta.stack === undefined) ? datasetIndex : ''),\r\n\t\t\t\t\tmeta.stack\r\n\t\t\t\t].join('.');\r\n\r\n\t\t\t\tif (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {\r\n\t\t\t\t\tif (valuesPerStack[key] === undefined) {\r\n\t\t\t\t\t\tvaluesPerStack[key] = [];\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tdata = datasets[datasetIndex].data;\r\n\t\t\t\t\tfor (i = 0, ilen = data.length; i < ilen; i++) {\r\n\t\t\t\t\t\tvar values = valuesPerStack[key];\r\n\t\t\t\t\t\tvalue = me._parseValue(data[i]);\r\n\t\t\t\t\t\t// invalid, hidden and negative values are ignored\r\n\t\t\t\t\t\tif (isNaN(value.min) || isNaN(value.max) || meta.data[i].hidden || value.min < 0 || value.max < 0) {\r\n\t\t\t\t\t\t\tcontinue;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tvalues[i] = values[i] || 0;\r\n\t\t\t\t\t\tvalues[i] += value.max;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\thelpers$1.each(valuesPerStack, function(valuesForType) {\r\n\t\t\t\tif (valuesForType.length > 0) {\r\n\t\t\t\t\tvar minVal = helpers$1.min(valuesForType);\r\n\t\t\t\t\tvar maxVal = helpers$1.max(valuesForType);\r\n\t\t\t\t\tme.min = Math.min(me.min, minVal);\r\n\t\t\t\t\tme.max = Math.max(me.max, maxVal);\r\n\t\t\t\t}\r\n\t\t\t});\r\n\r\n\t\t} else {\r\n\t\t\tfor (datasetIndex = 0; datasetIndex < datasets.length; datasetIndex++) {\r\n\t\t\t\tmeta = chart.getDatasetMeta(datasetIndex);\r\n\t\t\t\tif (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {\r\n\t\t\t\t\tdata = datasets[datasetIndex].data;\r\n\t\t\t\t\tfor (i = 0, ilen = data.length; i < ilen; i++) {\r\n\t\t\t\t\t\tvalue = me._parseValue(data[i]);\r\n\t\t\t\t\t\t// invalid, hidden and negative values are ignored\r\n\t\t\t\t\t\tif (isNaN(value.min) || isNaN(value.max) || meta.data[i].hidden || value.min < 0 || value.max < 0) {\r\n\t\t\t\t\t\t\tcontinue;\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\tme.min = Math.min(value.min, me.min);\r\n\t\t\t\t\t\tme.max = Math.max(value.max, me.max);\r\n\r\n\t\t\t\t\t\tif (value.min !== 0) {\r\n\t\t\t\t\t\t\tme.minNotZero = Math.min(value.min, me.minNotZero);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tme.min = helpers$1.isFinite(me.min) ? me.min : null;\r\n\t\tme.max = helpers$1.isFinite(me.max) ? me.max : null;\r\n\t\tme.minNotZero = helpers$1.isFinite(me.minNotZero) ? me.minNotZero : null;\r\n\r\n\t\t// Common base implementation to handle ticks.min, ticks.max\r\n\t\tthis.handleTickRangeOptions();\r\n\t},\r\n\r\n\thandleTickRangeOptions: function() {\r\n\t\tvar me = this;\r\n\t\tvar tickOpts = me.options.ticks;\r\n\t\tvar DEFAULT_MIN = 1;\r\n\t\tvar DEFAULT_MAX = 10;\r\n\r\n\t\tme.min = nonNegativeOrDefault(tickOpts.min, me.min);\r\n\t\tme.max = nonNegativeOrDefault(tickOpts.max, me.max);\r\n\r\n\t\tif (me.min === me.max) {\r\n\t\t\tif (me.min !== 0 && me.min !== null) {\r\n\t\t\t\tme.min = Math.pow(10, Math.floor(log10(me.min)) - 1);\r\n\t\t\t\tme.max = Math.pow(10, Math.floor(log10(me.max)) + 1);\r\n\t\t\t} else {\r\n\t\t\t\tme.min = DEFAULT_MIN;\r\n\t\t\t\tme.max = DEFAULT_MAX;\r\n\t\t\t}\r\n\t\t}\r\n\t\tif (me.min === null) {\r\n\t\t\tme.min = Math.pow(10, Math.floor(log10(me.max)) - 1);\r\n\t\t}\r\n\t\tif (me.max === null) {\r\n\t\t\tme.max = me.min !== 0\r\n\t\t\t\t? Math.pow(10, Math.floor(log10(me.min)) + 1)\r\n\t\t\t\t: DEFAULT_MAX;\r\n\t\t}\r\n\t\tif (me.minNotZero === null) {\r\n\t\t\tif (me.min > 0) {\r\n\t\t\t\tme.minNotZero = me.min;\r\n\t\t\t} else if (me.max < 1) {\r\n\t\t\t\tme.minNotZero = Math.pow(10, Math.floor(log10(me.max)));\r\n\t\t\t} else {\r\n\t\t\t\tme.minNotZero = DEFAULT_MIN;\r\n\t\t\t}\r\n\t\t}\r\n\t},\r\n\r\n\tbuildTicks: function() {\r\n\t\tvar me = this;\r\n\t\tvar tickOpts = me.options.ticks;\r\n\t\tvar reverse = !me.isHorizontal();\r\n\r\n\t\tvar generationOptions = {\r\n\t\t\tmin: nonNegativeOrDefault(tickOpts.min),\r\n\t\t\tmax: nonNegativeOrDefault(tickOpts.max)\r\n\t\t};\r\n\t\tvar ticks = me.ticks = generateTicks$1(generationOptions, me);\r\n\r\n\t\t// At this point, we need to update our max and min given the tick values since we have expanded the\r\n\t\t// range of the scale\r\n\t\tme.max = helpers$1.max(ticks);\r\n\t\tme.min = helpers$1.min(ticks);\r\n\r\n\t\tif (tickOpts.reverse) {\r\n\t\t\treverse = !reverse;\r\n\t\t\tme.start = me.max;\r\n\t\t\tme.end = me.min;\r\n\t\t} else {\r\n\t\t\tme.start = me.min;\r\n\t\t\tme.end = me.max;\r\n\t\t}\r\n\t\tif (reverse) {\r\n\t\t\tticks.reverse();\r\n\t\t}\r\n\t},\r\n\r\n\tconvertTicksToLabels: function() {\r\n\t\tthis.tickValues = this.ticks.slice();\r\n\r\n\t\tcore_scale.prototype.convertTicksToLabels.call(this);\r\n\t},\r\n\r\n\t// Get the correct tooltip label\r\n\tgetLabelForIndex: function(index, datasetIndex) {\r\n\t\treturn this._getScaleLabel(this.chart.data.datasets[datasetIndex].data[index]);\r\n\t},\r\n\r\n\tgetPixelForTick: function(index) {\r\n\t\tvar ticks = this.tickValues;\r\n\t\tif (index < 0 || index > ticks.length - 1) {\r\n\t\t\treturn null;\r\n\t\t}\r\n\t\treturn this.getPixelForValue(ticks[index]);\r\n\t},\r\n\r\n\t/**\r\n\t * Returns the value of the first tick.\r\n\t * @param {number} value - The minimum not zero value.\r\n\t * @return {number} The first tick value.\r\n\t * @private\r\n\t */\r\n\t_getFirstTickValue: function(value) {\r\n\t\tvar exp = Math.floor(log10(value));\r\n\t\tvar significand = Math.floor(value / Math.pow(10, exp));\r\n\r\n\t\treturn significand * Math.pow(10, exp);\r\n\t},\r\n\r\n\t_configure: function() {\r\n\t\tvar me = this;\r\n\t\tvar start = me.min;\r\n\t\tvar offset = 0;\r\n\r\n\t\tcore_scale.prototype._configure.call(me);\r\n\r\n\t\tif (start === 0) {\r\n\t\t\tstart = me._getFirstTickValue(me.minNotZero);\r\n\t\t\toffset = valueOrDefault$b(me.options.ticks.fontSize, core_defaults.global.defaultFontSize) / me._length;\r\n\t\t}\r\n\r\n\t\tme._startValue = log10(start);\r\n\t\tme._valueOffset = offset;\r\n\t\tme._valueRange = (log10(me.max) - log10(start)) / (1 - offset);\r\n\t},\r\n\r\n\tgetPixelForValue: function(value) {\r\n\t\tvar me = this;\r\n\t\tvar decimal = 0;\r\n\r\n\t\tvalue = +me.getRightValue(value);\r\n\r\n\t\tif (value > me.min && value > 0) {\r\n\t\t\tdecimal = (log10(value) - me._startValue) / me._valueRange + me._valueOffset;\r\n\t\t}\r\n\t\treturn me.getPixelForDecimal(decimal);\r\n\t},\r\n\r\n\tgetValueForPixel: function(pixel) {\r\n\t\tvar me = this;\r\n\t\tvar decimal = me.getDecimalForPixel(pixel);\r\n\t\treturn decimal === 0 && me.min === 0\r\n\t\t\t? 0\r\n\t\t\t: Math.pow(10, me._startValue + (decimal - me._valueOffset) * me._valueRange);\r\n\t}\r\n});\r\n\r\n// INTERNAL: static default options, registered in src/index.js\r\nvar _defaults$2 = defaultConfig$2;\nscale_logarithmic._defaults = _defaults$2;\n\nvar valueOrDefault$c = helpers$1.valueOrDefault;\r\nvar valueAtIndexOrDefault$1 = helpers$1.valueAtIndexOrDefault;\r\nvar resolve$4 = helpers$1.options.resolve;\r\n\r\nvar defaultConfig$3 = {\r\n\tdisplay: true,\r\n\r\n\t// Boolean - Whether to animate scaling the chart from the centre\r\n\tanimate: true,\r\n\tposition: 'chartArea',\r\n\r\n\tangleLines: {\r\n\t\tdisplay: true,\r\n\t\tcolor: 'rgba(0,0,0,0.1)',\r\n\t\tlineWidth: 1,\r\n\t\tborderDash: [],\r\n\t\tborderDashOffset: 0.0\r\n\t},\r\n\r\n\tgridLines: {\r\n\t\tcircular: false\r\n\t},\r\n\r\n\t// label settings\r\n\tticks: {\r\n\t\t// Boolean - Show a backdrop to the scale label\r\n\t\tshowLabelBackdrop: true,\r\n\r\n\t\t// String - The colour of the label backdrop\r\n\t\tbackdropColor: 'rgba(255,255,255,0.75)',\r\n\r\n\t\t// Number - The backdrop padding above & below the label in pixels\r\n\t\tbackdropPaddingY: 2,\r\n\r\n\t\t// Number - The backdrop padding to the side of the label in pixels\r\n\t\tbackdropPaddingX: 2,\r\n\r\n\t\tcallback: core_ticks.formatters.linear\r\n\t},\r\n\r\n\tpointLabels: {\r\n\t\t// Boolean - if true, show point labels\r\n\t\tdisplay: true,\r\n\r\n\t\t// Number - Point label font size in pixels\r\n\t\tfontSize: 10,\r\n\r\n\t\t// Function - Used to convert point labels\r\n\t\tcallback: function(label) {\r\n\t\t\treturn label;\r\n\t\t}\r\n\t}\r\n};\r\n\r\nfunction getTickBackdropHeight(opts) {\r\n\tvar tickOpts = opts.ticks;\r\n\r\n\tif (tickOpts.display && opts.display) {\r\n\t\treturn valueOrDefault$c(tickOpts.fontSize, core_defaults.global.defaultFontSize) + tickOpts.backdropPaddingY * 2;\r\n\t}\r\n\treturn 0;\r\n}\r\n\r\nfunction measureLabelSize(ctx, lineHeight, label) {\r\n\tif (helpers$1.isArray(label)) {\r\n\t\treturn {\r\n\t\t\tw: helpers$1.longestText(ctx, ctx.font, label),\r\n\t\t\th: label.length * lineHeight\r\n\t\t};\r\n\t}\r\n\r\n\treturn {\r\n\t\tw: ctx.measureText(label).width,\r\n\t\th: lineHeight\r\n\t};\r\n}\r\n\r\nfunction determineLimits(angle, pos, size, min, max) {\r\n\tif (angle === min || angle === max) {\r\n\t\treturn {\r\n\t\t\tstart: pos - (size / 2),\r\n\t\t\tend: pos + (size / 2)\r\n\t\t};\r\n\t} else if (angle < min || angle > max) {\r\n\t\treturn {\r\n\t\t\tstart: pos - size,\r\n\t\t\tend: pos\r\n\t\t};\r\n\t}\r\n\r\n\treturn {\r\n\t\tstart: pos,\r\n\t\tend: pos + size\r\n\t};\r\n}\r\n\r\n/**\r\n * Helper function to fit a radial linear scale with point labels\r\n */\r\nfunction fitWithPointLabels(scale) {\r\n\r\n\t// Right, this is really confusing and there is a lot of maths going on here\r\n\t// The gist of the problem is here: https://gist.github.com/nnnick/696cc9c55f4b0beb8fe9\r\n\t//\r\n\t// Reaction: https://dl.dropboxusercontent.com/u/34601363/toomuchscience.gif\r\n\t//\r\n\t// Solution:\r\n\t//\r\n\t// We assume the radius of the polygon is half the size of the canvas at first\r\n\t// at each index we check if the text overlaps.\r\n\t//\r\n\t// Where it does, we store that angle and that index.\r\n\t//\r\n\t// After finding the largest index and angle we calculate how much we need to remove\r\n\t// from the shape radius to move the point inwards by that x.\r\n\t//\r\n\t// We average the left and right distances to get the maximum shape radius that can fit in the box\r\n\t// along with labels.\r\n\t//\r\n\t// Once we have that, we can find the centre point for the chart, by taking the x text protrusion\r\n\t// on each side, removing that from the size, halving it and adding the left x protrusion width.\r\n\t//\r\n\t// This will mean we have a shape fitted to the canvas, as large as it can be with the labels\r\n\t// and position it in the most space efficient manner\r\n\t//\r\n\t// https://dl.dropboxusercontent.com/u/34601363/yeahscience.gif\r\n\r\n\tvar plFont = helpers$1.options._parseFont(scale.options.pointLabels);\r\n\r\n\t// Get maximum radius of the polygon. Either half the height (minus the text width) or half the width.\r\n\t// Use this to calculate the offset + change. - Make sure L/R protrusion is at least 0 to stop issues with centre points\r\n\tvar furthestLimits = {\r\n\t\tl: 0,\r\n\t\tr: scale.width,\r\n\t\tt: 0,\r\n\t\tb: scale.height - scale.paddingTop\r\n\t};\r\n\tvar furthestAngles = {};\r\n\tvar i, textSize, pointPosition;\r\n\r\n\tscale.ctx.font = plFont.string;\r\n\tscale._pointLabelSizes = [];\r\n\r\n\tvar valueCount = scale.chart.data.labels.length;\r\n\tfor (i = 0; i < valueCount; i++) {\r\n\t\tpointPosition = scale.getPointPosition(i, scale.drawingArea + 5);\r\n\t\ttextSize = measureLabelSize(scale.ctx, plFont.lineHeight, scale.pointLabels[i]);\r\n\t\tscale._pointLabelSizes[i] = textSize;\r\n\r\n\t\t// Add quarter circle to make degree 0 mean top of circle\r\n\t\tvar angleRadians = scale.getIndexAngle(i);\r\n\t\tvar angle = helpers$1.toDegrees(angleRadians) % 360;\r\n\t\tvar hLimits = determineLimits(angle, pointPosition.x, textSize.w, 0, 180);\r\n\t\tvar vLimits = determineLimits(angle, pointPosition.y, textSize.h, 90, 270);\r\n\r\n\t\tif (hLimits.start < furthestLimits.l) {\r\n\t\t\tfurthestLimits.l = hLimits.start;\r\n\t\t\tfurthestAngles.l = angleRadians;\r\n\t\t}\r\n\r\n\t\tif (hLimits.end > furthestLimits.r) {\r\n\t\t\tfurthestLimits.r = hLimits.end;\r\n\t\t\tfurthestAngles.r = angleRadians;\r\n\t\t}\r\n\r\n\t\tif (vLimits.start < furthestLimits.t) {\r\n\t\t\tfurthestLimits.t = vLimits.start;\r\n\t\t\tfurthestAngles.t = angleRadians;\r\n\t\t}\r\n\r\n\t\tif (vLimits.end > furthestLimits.b) {\r\n\t\t\tfurthestLimits.b = vLimits.end;\r\n\t\t\tfurthestAngles.b = angleRadians;\r\n\t\t}\r\n\t}\r\n\r\n\tscale.setReductions(scale.drawingArea, furthestLimits, furthestAngles);\r\n}\r\n\r\nfunction getTextAlignForAngle(angle) {\r\n\tif (angle === 0 || angle === 180) {\r\n\t\treturn 'center';\r\n\t} else if (angle < 180) {\r\n\t\treturn 'left';\r\n\t}\r\n\r\n\treturn 'right';\r\n}\r\n\r\nfunction fillText(ctx, text, position, lineHeight) {\r\n\tvar y = position.y + lineHeight / 2;\r\n\tvar i, ilen;\r\n\r\n\tif (helpers$1.isArray(text)) {\r\n\t\tfor (i = 0, ilen = text.length; i < ilen; ++i) {\r\n\t\t\tctx.fillText(text[i], position.x, y);\r\n\t\t\ty += lineHeight;\r\n\t\t}\r\n\t} else {\r\n\t\tctx.fillText(text, position.x, y);\r\n\t}\r\n}\r\n\r\nfunction adjustPointPositionForLabelHeight(angle, textSize, position) {\r\n\tif (angle === 90 || angle === 270) {\r\n\t\tposition.y -= (textSize.h / 2);\r\n\t} else if (angle > 270 || angle < 90) {\r\n\t\tposition.y -= textSize.h;\r\n\t}\r\n}\r\n\r\nfunction drawPointLabels(scale) {\r\n\tvar ctx = scale.ctx;\r\n\tvar opts = scale.options;\r\n\tvar pointLabelOpts = opts.pointLabels;\r\n\tvar tickBackdropHeight = getTickBackdropHeight(opts);\r\n\tvar outerDistance = scale.getDistanceFromCenterForValue(opts.ticks.reverse ? scale.min : scale.max);\r\n\tvar plFont = helpers$1.options._parseFont(pointLabelOpts);\r\n\r\n\tctx.save();\r\n\r\n\tctx.font = plFont.string;\r\n\tctx.textBaseline = 'middle';\r\n\r\n\tfor (var i = scale.chart.data.labels.length - 1; i >= 0; i--) {\r\n\t\t// Extra pixels out for some label spacing\r\n\t\tvar extra = (i === 0 ? tickBackdropHeight / 2 : 0);\r\n\t\tvar pointLabelPosition = scale.getPointPosition(i, outerDistance + extra + 5);\r\n\r\n\t\t// Keep this in loop since we may support array properties here\r\n\t\tvar pointLabelFontColor = valueAtIndexOrDefault$1(pointLabelOpts.fontColor, i, core_defaults.global.defaultFontColor);\r\n\t\tctx.fillStyle = pointLabelFontColor;\r\n\r\n\t\tvar angleRadians = scale.getIndexAngle(i);\r\n\t\tvar angle = helpers$1.toDegrees(angleRadians);\r\n\t\tctx.textAlign = getTextAlignForAngle(angle);\r\n\t\tadjustPointPositionForLabelHeight(angle, scale._pointLabelSizes[i], pointLabelPosition);\r\n\t\tfillText(ctx, scale.pointLabels[i], pointLabelPosition, plFont.lineHeight);\r\n\t}\r\n\tctx.restore();\r\n}\r\n\r\nfunction drawRadiusLine(scale, gridLineOpts, radius, index) {\r\n\tvar ctx = scale.ctx;\r\n\tvar circular = gridLineOpts.circular;\r\n\tvar valueCount = scale.chart.data.labels.length;\r\n\tvar lineColor = valueAtIndexOrDefault$1(gridLineOpts.color, index - 1);\r\n\tvar lineWidth = valueAtIndexOrDefault$1(gridLineOpts.lineWidth, index - 1);\r\n\tvar pointPosition;\r\n\r\n\tif ((!circular && !valueCount) || !lineColor || !lineWidth) {\r\n\t\treturn;\r\n\t}\r\n\r\n\tctx.save();\r\n\tctx.strokeStyle = lineColor;\r\n\tctx.lineWidth = lineWidth;\r\n\tif (ctx.setLineDash) {\r\n\t\tctx.setLineDash(gridLineOpts.borderDash || []);\r\n\t\tctx.lineDashOffset = gridLineOpts.borderDashOffset || 0.0;\r\n\t}\r\n\r\n\tctx.beginPath();\r\n\tif (circular) {\r\n\t\t// Draw circular arcs between the points\r\n\t\tctx.arc(scale.xCenter, scale.yCenter, radius, 0, Math.PI * 2);\r\n\t} else {\r\n\t\t// Draw straight lines connecting each index\r\n\t\tpointPosition = scale.getPointPosition(0, radius);\r\n\t\tctx.moveTo(pointPosition.x, pointPosition.y);\r\n\r\n\t\tfor (var i = 1; i < valueCount; i++) {\r\n\t\t\tpointPosition = scale.getPointPosition(i, radius);\r\n\t\t\tctx.lineTo(pointPosition.x, pointPosition.y);\r\n\t\t}\r\n\t}\r\n\tctx.closePath();\r\n\tctx.stroke();\r\n\tctx.restore();\r\n}\r\n\r\nfunction numberOrZero(param) {\r\n\treturn helpers$1.isNumber(param) ? param : 0;\r\n}\r\n\r\nvar scale_radialLinear = scale_linearbase.extend({\r\n\tsetDimensions: function() {\r\n\t\tvar me = this;\r\n\r\n\t\t// Set the unconstrained dimension before label rotation\r\n\t\tme.width = me.maxWidth;\r\n\t\tme.height = me.maxHeight;\r\n\t\tme.paddingTop = getTickBackdropHeight(me.options) / 2;\r\n\t\tme.xCenter = Math.floor(me.width / 2);\r\n\t\tme.yCenter = Math.floor((me.height - me.paddingTop) / 2);\r\n\t\tme.drawingArea = Math.min(me.height - me.paddingTop, me.width) / 2;\r\n\t},\r\n\r\n\tdetermineDataLimits: function() {\r\n\t\tvar me = this;\r\n\t\tvar chart = me.chart;\r\n\t\tvar min = Number.POSITIVE_INFINITY;\r\n\t\tvar max = Number.NEGATIVE_INFINITY;\r\n\r\n\t\thelpers$1.each(chart.data.datasets, function(dataset, datasetIndex) {\r\n\t\t\tif (chart.isDatasetVisible(datasetIndex)) {\r\n\t\t\t\tvar meta = chart.getDatasetMeta(datasetIndex);\r\n\r\n\t\t\t\thelpers$1.each(dataset.data, function(rawValue, index) {\r\n\t\t\t\t\tvar value = +me.getRightValue(rawValue);\r\n\t\t\t\t\tif (isNaN(value) || meta.data[index].hidden) {\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tmin = Math.min(value, min);\r\n\t\t\t\t\tmax = Math.max(value, max);\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tme.min = (min === Number.POSITIVE_INFINITY ? 0 : min);\r\n\t\tme.max = (max === Number.NEGATIVE_INFINITY ? 0 : max);\r\n\r\n\t\t// Common base implementation to handle ticks.min, ticks.max, ticks.beginAtZero\r\n\t\tme.handleTickRangeOptions();\r\n\t},\r\n\r\n\t// Returns the maximum number of ticks based on the scale dimension\r\n\t_computeTickLimit: function() {\r\n\t\treturn Math.ceil(this.drawingArea / getTickBackdropHeight(this.options));\r\n\t},\r\n\r\n\tconvertTicksToLabels: function() {\r\n\t\tvar me = this;\r\n\r\n\t\tscale_linearbase.prototype.convertTicksToLabels.call(me);\r\n\r\n\t\t// Point labels\r\n\t\tme.pointLabels = me.chart.data.labels.map(function() {\r\n\t\t\tvar label = helpers$1.callback(me.options.pointLabels.callback, arguments, me);\r\n\t\t\treturn label || label === 0 ? label : '';\r\n\t\t});\r\n\t},\r\n\r\n\tgetLabelForIndex: function(index, datasetIndex) {\r\n\t\treturn +this.getRightValue(this.chart.data.datasets[datasetIndex].data[index]);\r\n\t},\r\n\r\n\tfit: function() {\r\n\t\tvar me = this;\r\n\t\tvar opts = me.options;\r\n\r\n\t\tif (opts.display && opts.pointLabels.display) {\r\n\t\t\tfitWithPointLabels(me);\r\n\t\t} else {\r\n\t\t\tme.setCenterPoint(0, 0, 0, 0);\r\n\t\t}\r\n\t},\r\n\r\n\t/**\r\n\t * Set radius reductions and determine new radius and center point\r\n\t * @private\r\n\t */\r\n\tsetReductions: function(largestPossibleRadius, furthestLimits, furthestAngles) {\r\n\t\tvar me = this;\r\n\t\tvar radiusReductionLeft = furthestLimits.l / Math.sin(furthestAngles.l);\r\n\t\tvar radiusReductionRight = Math.max(furthestLimits.r - me.width, 0) / Math.sin(furthestAngles.r);\r\n\t\tvar radiusReductionTop = -furthestLimits.t / Math.cos(furthestAngles.t);\r\n\t\tvar radiusReductionBottom = -Math.max(furthestLimits.b - (me.height - me.paddingTop), 0) / Math.cos(furthestAngles.b);\r\n\r\n\t\tradiusReductionLeft = numberOrZero(radiusReductionLeft);\r\n\t\tradiusReductionRight = numberOrZero(radiusReductionRight);\r\n\t\tradiusReductionTop = numberOrZero(radiusReductionTop);\r\n\t\tradiusReductionBottom = numberOrZero(radiusReductionBottom);\r\n\r\n\t\tme.drawingArea = Math.min(\r\n\t\t\tMath.floor(largestPossibleRadius - (radiusReductionLeft + radiusReductionRight) / 2),\r\n\t\t\tMath.floor(largestPossibleRadius - (radiusReductionTop + radiusReductionBottom) / 2));\r\n\t\tme.setCenterPoint(radiusReductionLeft, radiusReductionRight, radiusReductionTop, radiusReductionBottom);\r\n\t},\r\n\r\n\tsetCenterPoint: function(leftMovement, rightMovement, topMovement, bottomMovement) {\r\n\t\tvar me = this;\r\n\t\tvar maxRight = me.width - rightMovement - me.drawingArea;\r\n\t\tvar maxLeft = leftMovement + me.drawingArea;\r\n\t\tvar maxTop = topMovement + me.drawingArea;\r\n\t\tvar maxBottom = (me.height - me.paddingTop) - bottomMovement - me.drawingArea;\r\n\r\n\t\tme.xCenter = Math.floor(((maxLeft + maxRight) / 2) + me.left);\r\n\t\tme.yCenter = Math.floor(((maxTop + maxBottom) / 2) + me.top + me.paddingTop);\r\n\t},\r\n\r\n\tgetIndexAngle: function(index) {\r\n\t\tvar chart = this.chart;\r\n\t\tvar angleMultiplier = 360 / chart.data.labels.length;\r\n\t\tvar options = chart.options || {};\r\n\t\tvar startAngle = options.startAngle || 0;\r\n\r\n\t\t// Start from the top instead of right, so remove a quarter of the circle\r\n\t\tvar angle = (index * angleMultiplier + startAngle) % 360;\r\n\r\n\t\treturn (angle < 0 ? angle + 360 : angle) * Math.PI * 2 / 360;\r\n\t},\r\n\r\n\tgetDistanceFromCenterForValue: function(value) {\r\n\t\tvar me = this;\r\n\r\n\t\tif (helpers$1.isNullOrUndef(value)) {\r\n\t\t\treturn NaN;\r\n\t\t}\r\n\r\n\t\t// Take into account half font size + the yPadding of the top value\r\n\t\tvar scalingFactor = me.drawingArea / (me.max - me.min);\r\n\t\tif (me.options.ticks.reverse) {\r\n\t\t\treturn (me.max - value) * scalingFactor;\r\n\t\t}\r\n\t\treturn (value - me.min) * scalingFactor;\r\n\t},\r\n\r\n\tgetPointPosition: function(index, distanceFromCenter) {\r\n\t\tvar me = this;\r\n\t\tvar thisAngle = me.getIndexAngle(index) - (Math.PI / 2);\r\n\t\treturn {\r\n\t\t\tx: Math.cos(thisAngle) * distanceFromCenter + me.xCenter,\r\n\t\t\ty: Math.sin(thisAngle) * distanceFromCenter + me.yCenter\r\n\t\t};\r\n\t},\r\n\r\n\tgetPointPositionForValue: function(index, value) {\r\n\t\treturn this.getPointPosition(index, this.getDistanceFromCenterForValue(value));\r\n\t},\r\n\r\n\tgetBasePosition: function(index) {\r\n\t\tvar me = this;\r\n\t\tvar min = me.min;\r\n\t\tvar max = me.max;\r\n\r\n\t\treturn me.getPointPositionForValue(index || 0,\r\n\t\t\tme.beginAtZero ? 0 :\r\n\t\t\tmin < 0 && max < 0 ? max :\r\n\t\t\tmin > 0 && max > 0 ? min :\r\n\t\t\t0);\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_drawGrid: function() {\r\n\t\tvar me = this;\r\n\t\tvar ctx = me.ctx;\r\n\t\tvar opts = me.options;\r\n\t\tvar gridLineOpts = opts.gridLines;\r\n\t\tvar angleLineOpts = opts.angleLines;\r\n\t\tvar lineWidth = valueOrDefault$c(angleLineOpts.lineWidth, gridLineOpts.lineWidth);\r\n\t\tvar lineColor = valueOrDefault$c(angleLineOpts.color, gridLineOpts.color);\r\n\t\tvar i, offset, position;\r\n\r\n\t\tif (opts.pointLabels.display) {\r\n\t\t\tdrawPointLabels(me);\r\n\t\t}\r\n\r\n\t\tif (gridLineOpts.display) {\r\n\t\t\thelpers$1.each(me.ticks, function(label, index) {\r\n\t\t\t\tif (index !== 0) {\r\n\t\t\t\t\toffset = me.getDistanceFromCenterForValue(me.ticksAsNumbers[index]);\r\n\t\t\t\t\tdrawRadiusLine(me, gridLineOpts, offset, index);\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tif (angleLineOpts.display && lineWidth && lineColor) {\r\n\t\t\tctx.save();\r\n\t\t\tctx.lineWidth = lineWidth;\r\n\t\t\tctx.strokeStyle = lineColor;\r\n\t\t\tif (ctx.setLineDash) {\r\n\t\t\t\tctx.setLineDash(resolve$4([angleLineOpts.borderDash, gridLineOpts.borderDash, []]));\r\n\t\t\t\tctx.lineDashOffset = resolve$4([angleLineOpts.borderDashOffset, gridLineOpts.borderDashOffset, 0.0]);\r\n\t\t\t}\r\n\r\n\t\t\tfor (i = me.chart.data.labels.length - 1; i >= 0; i--) {\r\n\t\t\t\toffset = me.getDistanceFromCenterForValue(opts.ticks.reverse ? me.min : me.max);\r\n\t\t\t\tposition = me.getPointPosition(i, offset);\r\n\t\t\t\tctx.beginPath();\r\n\t\t\t\tctx.moveTo(me.xCenter, me.yCenter);\r\n\t\t\t\tctx.lineTo(position.x, position.y);\r\n\t\t\t\tctx.stroke();\r\n\t\t\t}\r\n\r\n\t\t\tctx.restore();\r\n\t\t}\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_drawLabels: function() {\r\n\t\tvar me = this;\r\n\t\tvar ctx = me.ctx;\r\n\t\tvar opts = me.options;\r\n\t\tvar tickOpts = opts.ticks;\r\n\r\n\t\tif (!tickOpts.display) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tvar startAngle = me.getIndexAngle(0);\r\n\t\tvar tickFont = helpers$1.options._parseFont(tickOpts);\r\n\t\tvar tickFontColor = valueOrDefault$c(tickOpts.fontColor, core_defaults.global.defaultFontColor);\r\n\t\tvar offset, width;\r\n\r\n\t\tctx.save();\r\n\t\tctx.font = tickFont.string;\r\n\t\tctx.translate(me.xCenter, me.yCenter);\r\n\t\tctx.rotate(startAngle);\r\n\t\tctx.textAlign = 'center';\r\n\t\tctx.textBaseline = 'middle';\r\n\r\n\t\thelpers$1.each(me.ticks, function(label, index) {\r\n\t\t\tif (index === 0 && !tickOpts.reverse) {\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\toffset = me.getDistanceFromCenterForValue(me.ticksAsNumbers[index]);\r\n\r\n\t\t\tif (tickOpts.showLabelBackdrop) {\r\n\t\t\t\twidth = ctx.measureText(label).width;\r\n\t\t\t\tctx.fillStyle = tickOpts.backdropColor;\r\n\r\n\t\t\t\tctx.fillRect(\r\n\t\t\t\t\t-width / 2 - tickOpts.backdropPaddingX,\r\n\t\t\t\t\t-offset - tickFont.size / 2 - tickOpts.backdropPaddingY,\r\n\t\t\t\t\twidth + tickOpts.backdropPaddingX * 2,\r\n\t\t\t\t\ttickFont.size + tickOpts.backdropPaddingY * 2\r\n\t\t\t\t);\r\n\t\t\t}\r\n\r\n\t\t\tctx.fillStyle = tickFontColor;\r\n\t\t\tctx.fillText(label, 0, -offset);\r\n\t\t});\r\n\r\n\t\tctx.restore();\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_drawTitle: helpers$1.noop\r\n});\r\n\r\n// INTERNAL: static default options, registered in src/index.js\r\nvar _defaults$3 = defaultConfig$3;\nscale_radialLinear._defaults = _defaults$3;\n\nvar deprecated$1 = helpers$1._deprecated;\r\nvar resolve$5 = helpers$1.options.resolve;\r\nvar valueOrDefault$d = helpers$1.valueOrDefault;\r\n\r\n// Integer constants are from the ES6 spec.\r\nvar MIN_INTEGER = Number.MIN_SAFE_INTEGER || -9007199254740991;\r\nvar MAX_INTEGER = Number.MAX_SAFE_INTEGER || 9007199254740991;\r\n\r\nvar INTERVALS = {\r\n\tmillisecond: {\r\n\t\tcommon: true,\r\n\t\tsize: 1,\r\n\t\tsteps: 1000\r\n\t},\r\n\tsecond: {\r\n\t\tcommon: true,\r\n\t\tsize: 1000,\r\n\t\tsteps: 60\r\n\t},\r\n\tminute: {\r\n\t\tcommon: true,\r\n\t\tsize: 60000,\r\n\t\tsteps: 60\r\n\t},\r\n\thour: {\r\n\t\tcommon: true,\r\n\t\tsize: 3600000,\r\n\t\tsteps: 24\r\n\t},\r\n\tday: {\r\n\t\tcommon: true,\r\n\t\tsize: 86400000,\r\n\t\tsteps: 30\r\n\t},\r\n\tweek: {\r\n\t\tcommon: false,\r\n\t\tsize: 604800000,\r\n\t\tsteps: 4\r\n\t},\r\n\tmonth: {\r\n\t\tcommon: true,\r\n\t\tsize: 2.628e9,\r\n\t\tsteps: 12\r\n\t},\r\n\tquarter: {\r\n\t\tcommon: false,\r\n\t\tsize: 7.884e9,\r\n\t\tsteps: 4\r\n\t},\r\n\tyear: {\r\n\t\tcommon: true,\r\n\t\tsize: 3.154e10\r\n\t}\r\n};\r\n\r\nvar UNITS = Object.keys(INTERVALS);\r\n\r\nfunction sorter(a, b) {\r\n\treturn a - b;\r\n}\r\n\r\nfunction arrayUnique(items) {\r\n\tvar hash = {};\r\n\tvar out = [];\r\n\tvar i, ilen, item;\r\n\r\n\tfor (i = 0, ilen = items.length; i < ilen; ++i) {\r\n\t\titem = items[i];\r\n\t\tif (!hash[item]) {\r\n\t\t\thash[item] = true;\r\n\t\t\tout.push(item);\r\n\t\t}\r\n\t}\r\n\r\n\treturn out;\r\n}\r\n\r\nfunction getMin(options) {\r\n\treturn helpers$1.valueOrDefault(options.time.min, options.ticks.min);\r\n}\r\n\r\nfunction getMax(options) {\r\n\treturn helpers$1.valueOrDefault(options.time.max, options.ticks.max);\r\n}\r\n\r\n/**\r\n * Returns an array of {time, pos} objects used to interpolate a specific `time` or position\r\n * (`pos`) on the scale, by searching entries before and after the requested value. `pos` is\r\n * a decimal between 0 and 1: 0 being the start of the scale (left or top) and 1 the other\r\n * extremity (left + width or top + height). Note that it would be more optimized to directly\r\n * store pre-computed pixels, but the scale dimensions are not guaranteed at the time we need\r\n * to create the lookup table. The table ALWAYS contains at least two items: min and max.\r\n *\r\n * @param {number[]} timestamps - timestamps sorted from lowest to highest.\r\n * @param {string} distribution - If 'linear', timestamps will be spread linearly along the min\r\n * and max range, so basically, the table will contains only two items: {min, 0} and {max, 1}.\r\n * If 'series', timestamps will be positioned at the same distance from each other. In this\r\n * case, only timestamps that break the time linearity are registered, meaning that in the\r\n * best case, all timestamps are linear, the table contains only min and max.\r\n */\r\nfunction buildLookupTable(timestamps, min, max, distribution) {\r\n\tif (distribution === 'linear' || !timestamps.length) {\r\n\t\treturn [\r\n\t\t\t{time: min, pos: 0},\r\n\t\t\t{time: max, pos: 1}\r\n\t\t];\r\n\t}\r\n\r\n\tvar table = [];\r\n\tvar items = [min];\r\n\tvar i, ilen, prev, curr, next;\r\n\r\n\tfor (i = 0, ilen = timestamps.length; i < ilen; ++i) {\r\n\t\tcurr = timestamps[i];\r\n\t\tif (curr > min && curr < max) {\r\n\t\t\titems.push(curr);\r\n\t\t}\r\n\t}\r\n\r\n\titems.push(max);\r\n\r\n\tfor (i = 0, ilen = items.length; i < ilen; ++i) {\r\n\t\tnext = items[i + 1];\r\n\t\tprev = items[i - 1];\r\n\t\tcurr = items[i];\r\n\r\n\t\t// only add points that breaks the scale linearity\r\n\t\tif (prev === undefined || next === undefined || Math.round((next + prev) / 2) !== curr) {\r\n\t\t\ttable.push({time: curr, pos: i / (ilen - 1)});\r\n\t\t}\r\n\t}\r\n\r\n\treturn table;\r\n}\r\n\r\n// @see adapted from https://www.anujgakhar.com/2014/03/01/binary-search-in-javascript/\r\nfunction lookup(table, key, value) {\r\n\tvar lo = 0;\r\n\tvar hi = table.length - 1;\r\n\tvar mid, i0, i1;\r\n\r\n\twhile (lo >= 0 && lo <= hi) {\r\n\t\tmid = (lo + hi) >> 1;\r\n\t\ti0 = table[mid - 1] || null;\r\n\t\ti1 = table[mid];\r\n\r\n\t\tif (!i0) {\r\n\t\t\t// given value is outside table (before first item)\r\n\t\t\treturn {lo: null, hi: i1};\r\n\t\t} else if (i1[key] < value) {\r\n\t\t\tlo = mid + 1;\r\n\t\t} else if (i0[key] > value) {\r\n\t\t\thi = mid - 1;\r\n\t\t} else {\r\n\t\t\treturn {lo: i0, hi: i1};\r\n\t\t}\r\n\t}\r\n\r\n\t// given value is outside table (after last item)\r\n\treturn {lo: i1, hi: null};\r\n}\r\n\r\n/**\r\n * Linearly interpolates the given source `value` using the table items `skey` values and\r\n * returns the associated `tkey` value. For example, interpolate(table, 'time', 42, 'pos')\r\n * returns the position for a timestamp equal to 42. If value is out of bounds, values at\r\n * index [0, 1] or [n - 1, n] are used for the interpolation.\r\n */\r\nfunction interpolate$1(table, skey, sval, tkey) {\r\n\tvar range = lookup(table, skey, sval);\r\n\r\n\t// Note: the lookup table ALWAYS contains at least 2 items (min and max)\r\n\tvar prev = !range.lo ? table[0] : !range.hi ? table[table.length - 2] : range.lo;\r\n\tvar next = !range.lo ? table[1] : !range.hi ? table[table.length - 1] : range.hi;\r\n\r\n\tvar span = next[skey] - prev[skey];\r\n\tvar ratio = span ? (sval - prev[skey]) / span : 0;\r\n\tvar offset = (next[tkey] - prev[tkey]) * ratio;\r\n\r\n\treturn prev[tkey] + offset;\r\n}\r\n\r\nfunction toTimestamp(scale, input) {\r\n\tvar adapter = scale._adapter;\r\n\tvar options = scale.options.time;\r\n\tvar parser = options.parser;\r\n\tvar format = parser || options.format;\r\n\tvar value = input;\r\n\r\n\tif (typeof parser === 'function') {\r\n\t\tvalue = parser(value);\r\n\t}\r\n\r\n\t// Only parse if its not a timestamp already\r\n\tif (!helpers$1.isFinite(value)) {\r\n\t\tvalue = typeof format === 'string'\r\n\t\t\t? adapter.parse(value, format)\r\n\t\t\t: adapter.parse(value);\r\n\t}\r\n\r\n\tif (value !== null) {\r\n\t\treturn +value;\r\n\t}\r\n\r\n\t// Labels are in an incompatible format and no `parser` has been provided.\r\n\t// The user might still use the deprecated `format` option for parsing.\r\n\tif (!parser && typeof format === 'function') {\r\n\t\tvalue = format(input);\r\n\r\n\t\t// `format` could return something else than a timestamp, if so, parse it\r\n\t\tif (!helpers$1.isFinite(value)) {\r\n\t\t\tvalue = adapter.parse(value);\r\n\t\t}\r\n\t}\r\n\r\n\treturn value;\r\n}\r\n\r\nfunction parse(scale, input) {\r\n\tif (helpers$1.isNullOrUndef(input)) {\r\n\t\treturn null;\r\n\t}\r\n\r\n\tvar options = scale.options.time;\r\n\tvar value = toTimestamp(scale, scale.getRightValue(input));\r\n\tif (value === null) {\r\n\t\treturn value;\r\n\t}\r\n\r\n\tif (options.round) {\r\n\t\tvalue = +scale._adapter.startOf(value, options.round);\r\n\t}\r\n\r\n\treturn value;\r\n}\r\n\r\n/**\r\n * Figures out what unit results in an appropriate number of auto-generated ticks\r\n */\r\nfunction determineUnitForAutoTicks(minUnit, min, max, capacity) {\r\n\tvar ilen = UNITS.length;\r\n\tvar i, interval, factor;\r\n\r\n\tfor (i = UNITS.indexOf(minUnit); i < ilen - 1; ++i) {\r\n\t\tinterval = INTERVALS[UNITS[i]];\r\n\t\tfactor = interval.steps ? interval.steps : MAX_INTEGER;\r\n\r\n\t\tif (interval.common && Math.ceil((max - min) / (factor * interval.size)) <= capacity) {\r\n\t\t\treturn UNITS[i];\r\n\t\t}\r\n\t}\r\n\r\n\treturn UNITS[ilen - 1];\r\n}\r\n\r\n/**\r\n * Figures out what unit to format a set of ticks with\r\n */\r\nfunction determineUnitForFormatting(scale, numTicks, minUnit, min, max) {\r\n\tvar i, unit;\r\n\r\n\tfor (i = UNITS.length - 1; i >= UNITS.indexOf(minUnit); i--) {\r\n\t\tunit = UNITS[i];\r\n\t\tif (INTERVALS[unit].common && scale._adapter.diff(max, min, unit) >= numTicks - 1) {\r\n\t\t\treturn unit;\r\n\t\t}\r\n\t}\r\n\r\n\treturn UNITS[minUnit ? UNITS.indexOf(minUnit) : 0];\r\n}\r\n\r\nfunction determineMajorUnit(unit) {\r\n\tfor (var i = UNITS.indexOf(unit) + 1, ilen = UNITS.length; i < ilen; ++i) {\r\n\t\tif (INTERVALS[UNITS[i]].common) {\r\n\t\t\treturn UNITS[i];\r\n\t\t}\r\n\t}\r\n}\r\n\r\n/**\r\n * Generates a maximum of `capacity` timestamps between min and max, rounded to the\r\n * `minor` unit using the given scale time `options`.\r\n * Important: this method can return ticks outside the min and max range, it's the\r\n * responsibility of the calling code to clamp values if needed.\r\n */\r\nfunction generate(scale, min, max, capacity) {\r\n\tvar adapter = scale._adapter;\r\n\tvar options = scale.options;\r\n\tvar timeOpts = options.time;\r\n\tvar minor = timeOpts.unit || determineUnitForAutoTicks(timeOpts.minUnit, min, max, capacity);\r\n\tvar stepSize = resolve$5([timeOpts.stepSize, timeOpts.unitStepSize, 1]);\r\n\tvar weekday = minor === 'week' ? timeOpts.isoWeekday : false;\r\n\tvar first = min;\r\n\tvar ticks = [];\r\n\tvar time;\r\n\r\n\t// For 'week' unit, handle the first day of week option\r\n\tif (weekday) {\r\n\t\tfirst = +adapter.startOf(first, 'isoWeek', weekday);\r\n\t}\r\n\r\n\t// Align first ticks on unit\r\n\tfirst = +adapter.startOf(first, weekday ? 'day' : minor);\r\n\r\n\t// Prevent browser from freezing in case user options request millions of milliseconds\r\n\tif (adapter.diff(max, min, minor) > 100000 * stepSize) {\r\n\t\tthrow min + ' and ' + max + ' are too far apart with stepSize of ' + stepSize + ' ' + minor;\r\n\t}\r\n\r\n\tfor (time = first; time < max; time = +adapter.add(time, stepSize, minor)) {\r\n\t\tticks.push(time);\r\n\t}\r\n\r\n\tif (time === max || options.bounds === 'ticks') {\r\n\t\tticks.push(time);\r\n\t}\r\n\r\n\treturn ticks;\r\n}\r\n\r\n/**\r\n * Returns the start and end offsets from edges in the form of {start, end}\r\n * where each value is a relative width to the scale and ranges between 0 and 1.\r\n * They add extra margins on the both sides by scaling down the original scale.\r\n * Offsets are added when the `offset` option is true.\r\n */\r\nfunction computeOffsets(table, ticks, min, max, options) {\r\n\tvar start = 0;\r\n\tvar end = 0;\r\n\tvar first, last;\r\n\r\n\tif (options.offset && ticks.length) {\r\n\t\tfirst = interpolate$1(table, 'time', ticks[0], 'pos');\r\n\t\tif (ticks.length === 1) {\r\n\t\t\tstart = 1 - first;\r\n\t\t} else {\r\n\t\t\tstart = (interpolate$1(table, 'time', ticks[1], 'pos') - first) / 2;\r\n\t\t}\r\n\t\tlast = interpolate$1(table, 'time', ticks[ticks.length - 1], 'pos');\r\n\t\tif (ticks.length === 1) {\r\n\t\t\tend = last;\r\n\t\t} else {\r\n\t\t\tend = (last - interpolate$1(table, 'time', ticks[ticks.length - 2], 'pos')) / 2;\r\n\t\t}\r\n\t}\r\n\r\n\treturn {start: start, end: end, factor: 1 / (start + 1 + end)};\r\n}\r\n\r\nfunction setMajorTicks(scale, ticks, map, majorUnit) {\r\n\tvar adapter = scale._adapter;\r\n\tvar first = +adapter.startOf(ticks[0].value, majorUnit);\r\n\tvar last = ticks[ticks.length - 1].value;\r\n\tvar major, index;\r\n\r\n\tfor (major = first; major <= last; major = +adapter.add(major, 1, majorUnit)) {\r\n\t\tindex = map[major];\r\n\t\tif (index >= 0) {\r\n\t\t\tticks[index].major = true;\r\n\t\t}\r\n\t}\r\n\treturn ticks;\r\n}\r\n\r\nfunction ticksFromTimestamps(scale, values, majorUnit) {\r\n\tvar ticks = [];\r\n\tvar map = {};\r\n\tvar ilen = values.length;\r\n\tvar i, value;\r\n\r\n\tfor (i = 0; i < ilen; ++i) {\r\n\t\tvalue = values[i];\r\n\t\tmap[value] = i;\r\n\r\n\t\tticks.push({\r\n\t\t\tvalue: value,\r\n\t\t\tmajor: false\r\n\t\t});\r\n\t}\r\n\r\n\t// We set the major ticks separately from the above loop because calling startOf for every tick\r\n\t// is expensive when there is a large number of ticks\r\n\treturn (ilen === 0 || !majorUnit) ? ticks : setMajorTicks(scale, ticks, map, majorUnit);\r\n}\r\n\r\nvar defaultConfig$4 = {\r\n\tposition: 'bottom',\r\n\r\n\t/**\r\n\t * Data distribution along the scale:\r\n\t * - 'linear': data are spread according to their time (distances can vary),\r\n\t * - 'series': data are spread at the same distance from each other.\r\n\t * @see https://github.com/chartjs/Chart.js/pull/4507\r\n\t * @since 2.7.0\r\n\t */\r\n\tdistribution: 'linear',\r\n\r\n\t/**\r\n\t * Scale boundary strategy (bypassed by min/max time options)\r\n\t * - `data`: make sure data are fully visible, ticks outside are removed\r\n\t * - `ticks`: make sure ticks are fully visible, data outside are truncated\r\n\t * @see https://github.com/chartjs/Chart.js/pull/4556\r\n\t * @since 2.7.0\r\n\t */\r\n\tbounds: 'data',\r\n\r\n\tadapters: {},\r\n\ttime: {\r\n\t\tparser: false, // false == a pattern string from https://momentjs.com/docs/#/parsing/string-format/ or a custom callback that converts its argument to a moment\r\n\t\tunit: false, // false == automatic or override with week, month, year, etc.\r\n\t\tround: false, // none, or override with week, month, year, etc.\r\n\t\tdisplayFormat: false, // DEPRECATED\r\n\t\tisoWeekday: false, // override week start day - see https://momentjs.com/docs/#/get-set/iso-weekday/\r\n\t\tminUnit: 'millisecond',\r\n\t\tdisplayFormats: {}\r\n\t},\r\n\tticks: {\r\n\t\tautoSkip: false,\r\n\r\n\t\t/**\r\n\t\t * Ticks generation input values:\r\n\t\t * - 'auto': generates \"optimal\" ticks based on scale size and time options.\r\n\t\t * - 'data': generates ticks from data (including labels from data {t|x|y} objects).\r\n\t\t * - 'labels': generates ticks from user given `data.labels` values ONLY.\r\n\t\t * @see https://github.com/chartjs/Chart.js/pull/4507\r\n\t\t * @since 2.7.0\r\n\t\t */\r\n\t\tsource: 'auto',\r\n\r\n\t\tmajor: {\r\n\t\t\tenabled: false\r\n\t\t}\r\n\t}\r\n};\r\n\r\nvar scale_time = core_scale.extend({\r\n\tinitialize: function() {\r\n\t\tthis.mergeTicksOptions();\r\n\t\tcore_scale.prototype.initialize.call(this);\r\n\t},\r\n\r\n\tupdate: function() {\r\n\t\tvar me = this;\r\n\t\tvar options = me.options;\r\n\t\tvar time = options.time || (options.time = {});\r\n\t\tvar adapter = me._adapter = new core_adapters._date(options.adapters.date);\r\n\r\n\t\t// DEPRECATIONS: output a message only one time per update\r\n\t\tdeprecated$1('time scale', time.format, 'time.format', 'time.parser');\r\n\t\tdeprecated$1('time scale', time.min, 'time.min', 'ticks.min');\r\n\t\tdeprecated$1('time scale', time.max, 'time.max', 'ticks.max');\r\n\r\n\t\t// Backward compatibility: before introducing adapter, `displayFormats` was\r\n\t\t// supposed to contain *all* unit/string pairs but this can't be resolved\r\n\t\t// when loading the scale (adapters are loaded afterward), so let's populate\r\n\t\t// missing formats on update\r\n\t\thelpers$1.mergeIf(time.displayFormats, adapter.formats());\r\n\r\n\t\treturn core_scale.prototype.update.apply(me, arguments);\r\n\t},\r\n\r\n\t/**\r\n\t * Allows data to be referenced via 't' attribute\r\n\t */\r\n\tgetRightValue: function(rawValue) {\r\n\t\tif (rawValue && rawValue.t !== undefined) {\r\n\t\t\trawValue = rawValue.t;\r\n\t\t}\r\n\t\treturn core_scale.prototype.getRightValue.call(this, rawValue);\r\n\t},\r\n\r\n\tdetermineDataLimits: function() {\r\n\t\tvar me = this;\r\n\t\tvar chart = me.chart;\r\n\t\tvar adapter = me._adapter;\r\n\t\tvar options = me.options;\r\n\t\tvar unit = options.time.unit || 'day';\r\n\t\tvar min = MAX_INTEGER;\r\n\t\tvar max = MIN_INTEGER;\r\n\t\tvar timestamps = [];\r\n\t\tvar datasets = [];\r\n\t\tvar labels = [];\r\n\t\tvar i, j, ilen, jlen, data, timestamp, labelsAdded;\r\n\t\tvar dataLabels = me._getLabels();\r\n\r\n\t\tfor (i = 0, ilen = dataLabels.length; i < ilen; ++i) {\r\n\t\t\tlabels.push(parse(me, dataLabels[i]));\r\n\t\t}\r\n\r\n\t\tfor (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) {\r\n\t\t\tif (chart.isDatasetVisible(i)) {\r\n\t\t\t\tdata = chart.data.datasets[i].data;\r\n\r\n\t\t\t\t// Let's consider that all data have the same format.\r\n\t\t\t\tif (helpers$1.isObject(data[0])) {\r\n\t\t\t\t\tdatasets[i] = [];\r\n\r\n\t\t\t\t\tfor (j = 0, jlen = data.length; j < jlen; ++j) {\r\n\t\t\t\t\t\ttimestamp = parse(me, data[j]);\r\n\t\t\t\t\t\ttimestamps.push(timestamp);\r\n\t\t\t\t\t\tdatasets[i][j] = timestamp;\r\n\t\t\t\t\t}\r\n\t\t\t\t} else {\r\n\t\t\t\t\tdatasets[i] = labels.slice(0);\r\n\t\t\t\t\tif (!labelsAdded) {\r\n\t\t\t\t\t\ttimestamps = timestamps.concat(labels);\r\n\t\t\t\t\t\tlabelsAdded = true;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tdatasets[i] = [];\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tif (labels.length) {\r\n\t\t\tmin = Math.min(min, labels[0]);\r\n\t\t\tmax = Math.max(max, labels[labels.length - 1]);\r\n\t\t}\r\n\r\n\t\tif (timestamps.length) {\r\n\t\t\ttimestamps = ilen > 1 ? arrayUnique(timestamps).sort(sorter) : timestamps.sort(sorter);\r\n\t\t\tmin = Math.min(min, timestamps[0]);\r\n\t\t\tmax = Math.max(max, timestamps[timestamps.length - 1]);\r\n\t\t}\r\n\r\n\t\tmin = parse(me, getMin(options)) || min;\r\n\t\tmax = parse(me, getMax(options)) || max;\r\n\r\n\t\t// In case there is no valid min/max, set limits based on unit time option\r\n\t\tmin = min === MAX_INTEGER ? +adapter.startOf(Date.now(), unit) : min;\r\n\t\tmax = max === MIN_INTEGER ? +adapter.endOf(Date.now(), unit) + 1 : max;\r\n\r\n\t\t// Make sure that max is strictly higher than min (required by the lookup table)\r\n\t\tme.min = Math.min(min, max);\r\n\t\tme.max = Math.max(min + 1, max);\r\n\r\n\t\t// PRIVATE\r\n\t\tme._table = [];\r\n\t\tme._timestamps = {\r\n\t\t\tdata: timestamps,\r\n\t\t\tdatasets: datasets,\r\n\t\t\tlabels: labels\r\n\t\t};\r\n\t},\r\n\r\n\tbuildTicks: function() {\r\n\t\tvar me = this;\r\n\t\tvar min = me.min;\r\n\t\tvar max = me.max;\r\n\t\tvar options = me.options;\r\n\t\tvar tickOpts = options.ticks;\r\n\t\tvar timeOpts = options.time;\r\n\t\tvar timestamps = me._timestamps;\r\n\t\tvar ticks = [];\r\n\t\tvar capacity = me.getLabelCapacity(min);\r\n\t\tvar source = tickOpts.source;\r\n\t\tvar distribution = options.distribution;\r\n\t\tvar i, ilen, timestamp;\r\n\r\n\t\tif (source === 'data' || (source === 'auto' && distribution === 'series')) {\r\n\t\t\ttimestamps = timestamps.data;\r\n\t\t} else if (source === 'labels') {\r\n\t\t\ttimestamps = timestamps.labels;\r\n\t\t} else {\r\n\t\t\ttimestamps = generate(me, min, max, capacity);\r\n\t\t}\r\n\r\n\t\tif (options.bounds === 'ticks' && timestamps.length) {\r\n\t\t\tmin = timestamps[0];\r\n\t\t\tmax = timestamps[timestamps.length - 1];\r\n\t\t}\r\n\r\n\t\t// Enforce limits with user min/max options\r\n\t\tmin = parse(me, getMin(options)) || min;\r\n\t\tmax = parse(me, getMax(options)) || max;\r\n\r\n\t\t// Remove ticks outside the min/max range\r\n\t\tfor (i = 0, ilen = timestamps.length; i < ilen; ++i) {\r\n\t\t\ttimestamp = timestamps[i];\r\n\t\t\tif (timestamp >= min && timestamp <= max) {\r\n\t\t\t\tticks.push(timestamp);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tme.min = min;\r\n\t\tme.max = max;\r\n\r\n\t\t// PRIVATE\r\n\t\t// determineUnitForFormatting relies on the number of ticks so we don't use it when\r\n\t\t// autoSkip is enabled because we don't yet know what the final number of ticks will be\r\n\t\tme._unit = timeOpts.unit || (tickOpts.autoSkip\r\n\t\t\t? determineUnitForAutoTicks(timeOpts.minUnit, me.min, me.max, capacity)\r\n\t\t\t: determineUnitForFormatting(me, ticks.length, timeOpts.minUnit, me.min, me.max));\r\n\t\tme._majorUnit = !tickOpts.major.enabled || me._unit === 'year' ? undefined\r\n\t\t\t: determineMajorUnit(me._unit);\r\n\t\tme._table = buildLookupTable(me._timestamps.data, min, max, distribution);\r\n\t\tme._offsets = computeOffsets(me._table, ticks, min, max, options);\r\n\r\n\t\tif (tickOpts.reverse) {\r\n\t\t\tticks.reverse();\r\n\t\t}\r\n\r\n\t\treturn ticksFromTimestamps(me, ticks, me._majorUnit);\r\n\t},\r\n\r\n\tgetLabelForIndex: function(index, datasetIndex) {\r\n\t\tvar me = this;\r\n\t\tvar adapter = me._adapter;\r\n\t\tvar data = me.chart.data;\r\n\t\tvar timeOpts = me.options.time;\r\n\t\tvar label = data.labels && index < data.labels.length ? data.labels[index] : '';\r\n\t\tvar value = data.datasets[datasetIndex].data[index];\r\n\r\n\t\tif (helpers$1.isObject(value)) {\r\n\t\t\tlabel = me.getRightValue(value);\r\n\t\t}\r\n\t\tif (timeOpts.tooltipFormat) {\r\n\t\t\treturn adapter.format(toTimestamp(me, label), timeOpts.tooltipFormat);\r\n\t\t}\r\n\t\tif (typeof label === 'string') {\r\n\t\t\treturn label;\r\n\t\t}\r\n\t\treturn adapter.format(toTimestamp(me, label), timeOpts.displayFormats.datetime);\r\n\t},\r\n\r\n\t/**\r\n\t * Function to format an individual tick mark\r\n\t * @private\r\n\t */\r\n\ttickFormatFunction: function(time, index, ticks, format) {\r\n\t\tvar me = this;\r\n\t\tvar adapter = me._adapter;\r\n\t\tvar options = me.options;\r\n\t\tvar formats = options.time.displayFormats;\r\n\t\tvar minorFormat = formats[me._unit];\r\n\t\tvar majorUnit = me._majorUnit;\r\n\t\tvar majorFormat = formats[majorUnit];\r\n\t\tvar tick = ticks[index];\r\n\t\tvar tickOpts = options.ticks;\r\n\t\tvar major = majorUnit && majorFormat && tick && tick.major;\r\n\t\tvar label = adapter.format(time, format ? format : major ? majorFormat : minorFormat);\r\n\t\tvar nestedTickOpts = major ? tickOpts.major : tickOpts.minor;\r\n\t\tvar formatter = resolve$5([\r\n\t\t\tnestedTickOpts.callback,\r\n\t\t\tnestedTickOpts.userCallback,\r\n\t\t\ttickOpts.callback,\r\n\t\t\ttickOpts.userCallback\r\n\t\t]);\r\n\r\n\t\treturn formatter ? formatter(label, index, ticks) : label;\r\n\t},\r\n\r\n\tconvertTicksToLabels: function(ticks) {\r\n\t\tvar labels = [];\r\n\t\tvar i, ilen;\r\n\r\n\t\tfor (i = 0, ilen = ticks.length; i < ilen; ++i) {\r\n\t\t\tlabels.push(this.tickFormatFunction(ticks[i].value, i, ticks));\r\n\t\t}\r\n\r\n\t\treturn labels;\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\tgetPixelForOffset: function(time) {\r\n\t\tvar me = this;\r\n\t\tvar offsets = me._offsets;\r\n\t\tvar pos = interpolate$1(me._table, 'time', time, 'pos');\r\n\t\treturn me.getPixelForDecimal((offsets.start + pos) * offsets.factor);\r\n\t},\r\n\r\n\tgetPixelForValue: function(value, index, datasetIndex) {\r\n\t\tvar me = this;\r\n\t\tvar time = null;\r\n\r\n\t\tif (index !== undefined && datasetIndex !== undefined) {\r\n\t\t\ttime = me._timestamps.datasets[datasetIndex][index];\r\n\t\t}\r\n\r\n\t\tif (time === null) {\r\n\t\t\ttime = parse(me, value);\r\n\t\t}\r\n\r\n\t\tif (time !== null) {\r\n\t\t\treturn me.getPixelForOffset(time);\r\n\t\t}\r\n\t},\r\n\r\n\tgetPixelForTick: function(index) {\r\n\t\tvar ticks = this.getTicks();\r\n\t\treturn index >= 0 && index < ticks.length ?\r\n\t\t\tthis.getPixelForOffset(ticks[index].value) :\r\n\t\t\tnull;\r\n\t},\r\n\r\n\tgetValueForPixel: function(pixel) {\r\n\t\tvar me = this;\r\n\t\tvar offsets = me._offsets;\r\n\t\tvar pos = me.getDecimalForPixel(pixel) / offsets.factor - offsets.end;\r\n\t\tvar time = interpolate$1(me._table, 'pos', pos, 'time');\r\n\r\n\t\t// DEPRECATION, we should return time directly\r\n\t\treturn me._adapter._create(time);\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_getLabelSize: function(label) {\r\n\t\tvar me = this;\r\n\t\tvar ticksOpts = me.options.ticks;\r\n\t\tvar tickLabelWidth = me.ctx.measureText(label).width;\r\n\t\tvar angle = helpers$1.toRadians(me.isHorizontal() ? ticksOpts.maxRotation : ticksOpts.minRotation);\r\n\t\tvar cosRotation = Math.cos(angle);\r\n\t\tvar sinRotation = Math.sin(angle);\r\n\t\tvar tickFontSize = valueOrDefault$d(ticksOpts.fontSize, core_defaults.global.defaultFontSize);\r\n\r\n\t\treturn {\r\n\t\t\tw: (tickLabelWidth * cosRotation) + (tickFontSize * sinRotation),\r\n\t\t\th: (tickLabelWidth * sinRotation) + (tickFontSize * cosRotation)\r\n\t\t};\r\n\t},\r\n\r\n\t/**\r\n\t * Crude approximation of what the label width might be\r\n\t * @private\r\n\t */\r\n\tgetLabelWidth: function(label) {\r\n\t\treturn this._getLabelSize(label).w;\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\tgetLabelCapacity: function(exampleTime) {\r\n\t\tvar me = this;\r\n\t\tvar timeOpts = me.options.time;\r\n\t\tvar displayFormats = timeOpts.displayFormats;\r\n\r\n\t\t// pick the longest format (milliseconds) for guestimation\r\n\t\tvar format = displayFormats[timeOpts.unit] || displayFormats.millisecond;\r\n\t\tvar exampleLabel = me.tickFormatFunction(exampleTime, 0, ticksFromTimestamps(me, [exampleTime], me._majorUnit), format);\r\n\t\tvar size = me._getLabelSize(exampleLabel);\r\n\t\tvar capacity = Math.floor(me.isHorizontal() ? me.width / size.w : me.height / size.h);\r\n\r\n\t\tif (me.options.offset) {\r\n\t\t\tcapacity--;\r\n\t\t}\r\n\r\n\t\treturn capacity > 0 ? capacity : 1;\r\n\t}\r\n});\r\n\r\n// INTERNAL: static default options, registered in src/index.js\r\nvar _defaults$4 = defaultConfig$4;\nscale_time._defaults = _defaults$4;\n\nvar scales = {\r\n\tcategory: scale_category,\r\n\tlinear: scale_linear,\r\n\tlogarithmic: scale_logarithmic,\r\n\tradialLinear: scale_radialLinear,\r\n\ttime: scale_time\r\n};\n\nvar FORMATS = {\r\n\tdatetime: 'MMM D, YYYY, h:mm:ss a',\r\n\tmillisecond: 'h:mm:ss.SSS a',\r\n\tsecond: 'h:mm:ss a',\r\n\tminute: 'h:mm a',\r\n\thour: 'hA',\r\n\tday: 'MMM D',\r\n\tweek: 'll',\r\n\tmonth: 'MMM YYYY',\r\n\tquarter: '[Q]Q - YYYY',\r\n\tyear: 'YYYY'\r\n};\r\n\r\ncore_adapters._date.override(typeof moment === 'function' ? {\r\n\t_id: 'moment', // DEBUG ONLY\r\n\r\n\tformats: function() {\r\n\t\treturn FORMATS;\r\n\t},\r\n\r\n\tparse: function(value, format) {\r\n\t\tif (typeof value === 'string' && typeof format === 'string') {\r\n\t\t\tvalue = moment(value, format);\r\n\t\t} else if (!(value instanceof moment)) {\r\n\t\t\tvalue = moment(value);\r\n\t\t}\r\n\t\treturn value.isValid() ? value.valueOf() : null;\r\n\t},\r\n\r\n\tformat: function(time, format) {\r\n\t\treturn moment(time).format(format);\r\n\t},\r\n\r\n\tadd: function(time, amount, unit) {\r\n\t\treturn moment(time).add(amount, unit).valueOf();\r\n\t},\r\n\r\n\tdiff: function(max, min, unit) {\r\n\t\treturn moment(max).diff(moment(min), unit);\r\n\t},\r\n\r\n\tstartOf: function(time, unit, weekday) {\r\n\t\ttime = moment(time);\r\n\t\tif (unit === 'isoWeek') {\r\n\t\t\treturn time.isoWeekday(weekday).valueOf();\r\n\t\t}\r\n\t\treturn time.startOf(unit).valueOf();\r\n\t},\r\n\r\n\tendOf: function(time, unit) {\r\n\t\treturn moment(time).endOf(unit).valueOf();\r\n\t},\r\n\r\n\t// DEPRECATIONS\r\n\r\n\t/**\r\n\t * Provided for backward compatibility with scale.getValueForPixel().\r\n\t * @deprecated since version 2.8.0\r\n\t * @todo remove at version 3\r\n\t * @private\r\n\t */\r\n\t_create: function(time) {\r\n\t\treturn moment(time);\r\n\t},\r\n} : {});\n\ncore_defaults._set('global', {\r\n\tplugins: {\r\n\t\tfiller: {\r\n\t\t\tpropagate: true\r\n\t\t}\r\n\t}\r\n});\r\n\r\nvar mappers = {\r\n\tdataset: function(source) {\r\n\t\tvar index = source.fill;\r\n\t\tvar chart = source.chart;\r\n\t\tvar meta = chart.getDatasetMeta(index);\r\n\t\tvar visible = meta && chart.isDatasetVisible(index);\r\n\t\tvar points = (visible && meta.dataset._children) || [];\r\n\t\tvar length = points.length || 0;\r\n\r\n\t\treturn !length ? null : function(point, i) {\r\n\t\t\treturn (i < length && points[i]._view) || null;\r\n\t\t};\r\n\t},\r\n\r\n\tboundary: function(source) {\r\n\t\tvar boundary = source.boundary;\r\n\t\tvar x = boundary ? boundary.x : null;\r\n\t\tvar y = boundary ? boundary.y : null;\r\n\r\n\t\tif (helpers$1.isArray(boundary)) {\r\n\t\t\treturn function(point, i) {\r\n\t\t\t\treturn boundary[i];\r\n\t\t\t};\r\n\t\t}\r\n\r\n\t\treturn function(point) {\r\n\t\t\treturn {\r\n\t\t\t\tx: x === null ? point.x : x,\r\n\t\t\t\ty: y === null ? point.y : y,\r\n\t\t\t};\r\n\t\t};\r\n\t}\r\n};\r\n\r\n// @todo if (fill[0] === '#')\r\nfunction decodeFill(el, index, count) {\r\n\tvar model = el._model || {};\r\n\tvar fill = model.fill;\r\n\tvar target;\r\n\r\n\tif (fill === undefined) {\r\n\t\tfill = !!model.backgroundColor;\r\n\t}\r\n\r\n\tif (fill === false || fill === null) {\r\n\t\treturn false;\r\n\t}\r\n\r\n\tif (fill === true) {\r\n\t\treturn 'origin';\r\n\t}\r\n\r\n\ttarget = parseFloat(fill, 10);\r\n\tif (isFinite(target) && Math.floor(target) === target) {\r\n\t\tif (fill[0] === '-' || fill[0] === '+') {\r\n\t\t\ttarget = index + target;\r\n\t\t}\r\n\r\n\t\tif (target === index || target < 0 || target >= count) {\r\n\t\t\treturn false;\r\n\t\t}\r\n\r\n\t\treturn target;\r\n\t}\r\n\r\n\tswitch (fill) {\r\n\t// compatibility\r\n\tcase 'bottom':\r\n\t\treturn 'start';\r\n\tcase 'top':\r\n\t\treturn 'end';\r\n\tcase 'zero':\r\n\t\treturn 'origin';\r\n\t// supported boundaries\r\n\tcase 'origin':\r\n\tcase 'start':\r\n\tcase 'end':\r\n\t\treturn fill;\r\n\t// invalid fill values\r\n\tdefault:\r\n\t\treturn false;\r\n\t}\r\n}\r\n\r\nfunction computeLinearBoundary(source) {\r\n\tvar model = source.el._model || {};\r\n\tvar scale = source.el._scale || {};\r\n\tvar fill = source.fill;\r\n\tvar target = null;\r\n\tvar horizontal;\r\n\r\n\tif (isFinite(fill)) {\r\n\t\treturn null;\r\n\t}\r\n\r\n\t// Backward compatibility: until v3, we still need to support boundary values set on\r\n\t// the model (scaleTop, scaleBottom and scaleZero) because some external plugins and\r\n\t// controllers might still use it (e.g. the Smith chart).\r\n\r\n\tif (fill === 'start') {\r\n\t\ttarget = model.scaleBottom === undefined ? scale.bottom : model.scaleBottom;\r\n\t} else if (fill === 'end') {\r\n\t\ttarget = model.scaleTop === undefined ? scale.top : model.scaleTop;\r\n\t} else if (model.scaleZero !== undefined) {\r\n\t\ttarget = model.scaleZero;\r\n\t} else if (scale.getBasePixel) {\r\n\t\ttarget = scale.getBasePixel();\r\n\t}\r\n\r\n\tif (target !== undefined && target !== null) {\r\n\t\tif (target.x !== undefined && target.y !== undefined) {\r\n\t\t\treturn target;\r\n\t\t}\r\n\r\n\t\tif (helpers$1.isFinite(target)) {\r\n\t\t\thorizontal = scale.isHorizontal();\r\n\t\t\treturn {\r\n\t\t\t\tx: horizontal ? target : null,\r\n\t\t\t\ty: horizontal ? null : target\r\n\t\t\t};\r\n\t\t}\r\n\t}\r\n\r\n\treturn null;\r\n}\r\n\r\nfunction computeCircularBoundary(source) {\r\n\tvar scale = source.el._scale;\r\n\tvar options = scale.options;\r\n\tvar length = scale.chart.data.labels.length;\r\n\tvar fill = source.fill;\r\n\tvar target = [];\r\n\tvar start, end, center, i, point;\r\n\r\n\tif (!length) {\r\n\t\treturn null;\r\n\t}\r\n\r\n\tstart = options.ticks.reverse ? scale.max : scale.min;\r\n\tend = options.ticks.reverse ? scale.min : scale.max;\r\n\tcenter = scale.getPointPositionForValue(0, start);\r\n\tfor (i = 0; i < length; ++i) {\r\n\t\tpoint = fill === 'start' || fill === 'end'\r\n\t\t\t? scale.getPointPositionForValue(i, fill === 'start' ? start : end)\r\n\t\t\t: scale.getBasePosition(i);\r\n\t\tif (options.gridLines.circular) {\r\n\t\t\tpoint.cx = center.x;\r\n\t\t\tpoint.cy = center.y;\r\n\t\t\tpoint.angle = scale.getIndexAngle(i) - Math.PI / 2;\r\n\t\t}\r\n\t\ttarget.push(point);\r\n\t}\r\n\treturn target;\r\n}\r\n\r\nfunction computeBoundary(source) {\r\n\tvar scale = source.el._scale || {};\r\n\r\n\tif (scale.getPointPositionForValue) {\r\n\t\treturn computeCircularBoundary(source);\r\n\t}\r\n\treturn computeLinearBoundary(source);\r\n}\r\n\r\nfunction resolveTarget(sources, index, propagate) {\r\n\tvar source = sources[index];\r\n\tvar fill = source.fill;\r\n\tvar visited = [index];\r\n\tvar target;\r\n\r\n\tif (!propagate) {\r\n\t\treturn fill;\r\n\t}\r\n\r\n\twhile (fill !== false && visited.indexOf(fill) === -1) {\r\n\t\tif (!isFinite(fill)) {\r\n\t\t\treturn fill;\r\n\t\t}\r\n\r\n\t\ttarget = sources[fill];\r\n\t\tif (!target) {\r\n\t\t\treturn false;\r\n\t\t}\r\n\r\n\t\tif (target.visible) {\r\n\t\t\treturn fill;\r\n\t\t}\r\n\r\n\t\tvisited.push(fill);\r\n\t\tfill = target.fill;\r\n\t}\r\n\r\n\treturn false;\r\n}\r\n\r\nfunction createMapper(source) {\r\n\tvar fill = source.fill;\r\n\tvar type = 'dataset';\r\n\r\n\tif (fill === false) {\r\n\t\treturn null;\r\n\t}\r\n\r\n\tif (!isFinite(fill)) {\r\n\t\ttype = 'boundary';\r\n\t}\r\n\r\n\treturn mappers[type](source);\r\n}\r\n\r\nfunction isDrawable(point) {\r\n\treturn point && !point.skip;\r\n}\r\n\r\nfunction drawArea(ctx, curve0, curve1, len0, len1) {\r\n\tvar i, cx, cy, r;\r\n\r\n\tif (!len0 || !len1) {\r\n\t\treturn;\r\n\t}\r\n\r\n\t// building first area curve (normal)\r\n\tctx.moveTo(curve0[0].x, curve0[0].y);\r\n\tfor (i = 1; i < len0; ++i) {\r\n\t\thelpers$1.canvas.lineTo(ctx, curve0[i - 1], curve0[i]);\r\n\t}\r\n\r\n\tif (curve1[0].angle !== undefined) {\r\n\t\tcx = curve1[0].cx;\r\n\t\tcy = curve1[0].cy;\r\n\t\tr = Math.sqrt(Math.pow(curve1[0].x - cx, 2) + Math.pow(curve1[0].y - cy, 2));\r\n\t\tfor (i = len1 - 1; i > 0; --i) {\r\n\t\t\tctx.arc(cx, cy, r, curve1[i].angle, curve1[i - 1].angle, true);\r\n\t\t}\r\n\t\treturn;\r\n\t}\r\n\r\n\t// joining the two area curves\r\n\tctx.lineTo(curve1[len1 - 1].x, curve1[len1 - 1].y);\r\n\r\n\t// building opposite area curve (reverse)\r\n\tfor (i = len1 - 1; i > 0; --i) {\r\n\t\thelpers$1.canvas.lineTo(ctx, curve1[i], curve1[i - 1], true);\r\n\t}\r\n}\r\n\r\nfunction doFill(ctx, points, mapper, view, color, loop) {\r\n\tvar count = points.length;\r\n\tvar span = view.spanGaps;\r\n\tvar curve0 = [];\r\n\tvar curve1 = [];\r\n\tvar len0 = 0;\r\n\tvar len1 = 0;\r\n\tvar i, ilen, index, p0, p1, d0, d1, loopOffset;\r\n\r\n\tctx.beginPath();\r\n\r\n\tfor (i = 0, ilen = count; i < ilen; ++i) {\r\n\t\tindex = i % count;\r\n\t\tp0 = points[index]._view;\r\n\t\tp1 = mapper(p0, index, view);\r\n\t\td0 = isDrawable(p0);\r\n\t\td1 = isDrawable(p1);\r\n\r\n\t\tif (loop && loopOffset === undefined && d0) {\r\n\t\t\tloopOffset = i + 1;\r\n\t\t\tilen = count + loopOffset;\r\n\t\t}\r\n\r\n\t\tif (d0 && d1) {\r\n\t\t\tlen0 = curve0.push(p0);\r\n\t\t\tlen1 = curve1.push(p1);\r\n\t\t} else if (len0 && len1) {\r\n\t\t\tif (!span) {\r\n\t\t\t\tdrawArea(ctx, curve0, curve1, len0, len1);\r\n\t\t\t\tlen0 = len1 = 0;\r\n\t\t\t\tcurve0 = [];\r\n\t\t\t\tcurve1 = [];\r\n\t\t\t} else {\r\n\t\t\t\tif (d0) {\r\n\t\t\t\t\tcurve0.push(p0);\r\n\t\t\t\t}\r\n\t\t\t\tif (d1) {\r\n\t\t\t\t\tcurve1.push(p1);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tdrawArea(ctx, curve0, curve1, len0, len1);\r\n\r\n\tctx.closePath();\r\n\tctx.fillStyle = color;\r\n\tctx.fill();\r\n}\r\n\r\nvar plugin_filler = {\r\n\tid: 'filler',\r\n\r\n\tafterDatasetsUpdate: function(chart, options) {\r\n\t\tvar count = (chart.data.datasets || []).length;\r\n\t\tvar propagate = options.propagate;\r\n\t\tvar sources = [];\r\n\t\tvar meta, i, el, source;\r\n\r\n\t\tfor (i = 0; i < count; ++i) {\r\n\t\t\tmeta = chart.getDatasetMeta(i);\r\n\t\t\tel = meta.dataset;\r\n\t\t\tsource = null;\r\n\r\n\t\t\tif (el && el._model && el instanceof elements.Line) {\r\n\t\t\t\tsource = {\r\n\t\t\t\t\tvisible: chart.isDatasetVisible(i),\r\n\t\t\t\t\tfill: decodeFill(el, i, count),\r\n\t\t\t\t\tchart: chart,\r\n\t\t\t\t\tel: el\r\n\t\t\t\t};\r\n\t\t\t}\r\n\r\n\t\t\tmeta.$filler = source;\r\n\t\t\tsources.push(source);\r\n\t\t}\r\n\r\n\t\tfor (i = 0; i < count; ++i) {\r\n\t\t\tsource = sources[i];\r\n\t\t\tif (!source) {\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\r\n\t\t\tsource.fill = resolveTarget(sources, i, propagate);\r\n\t\t\tsource.boundary = computeBoundary(source);\r\n\t\t\tsource.mapper = createMapper(source);\r\n\t\t}\r\n\t},\r\n\r\n\tbeforeDatasetsDraw: function(chart) {\r\n\t\tvar metasets = chart._getSortedVisibleDatasetMetas();\r\n\t\tvar ctx = chart.ctx;\r\n\t\tvar meta, i, el, view, points, mapper, color;\r\n\r\n\t\tfor (i = metasets.length - 1; i >= 0; --i) {\r\n\t\t\tmeta = metasets[i].$filler;\r\n\r\n\t\t\tif (!meta || !meta.visible) {\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\r\n\t\t\tel = meta.el;\r\n\t\t\tview = el._view;\r\n\t\t\tpoints = el._children || [];\r\n\t\t\tmapper = meta.mapper;\r\n\t\t\tcolor = view.backgroundColor || core_defaults.global.defaultColor;\r\n\r\n\t\t\tif (mapper && color && points.length) {\r\n\t\t\t\thelpers$1.canvas.clipArea(ctx, chart.chartArea);\r\n\t\t\t\tdoFill(ctx, points, mapper, view, color, el._loop);\r\n\t\t\t\thelpers$1.canvas.unclipArea(ctx);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n};\n\nvar getRtlHelper$1 = helpers$1.rtl.getRtlAdapter;\r\nvar noop$1 = helpers$1.noop;\r\nvar valueOrDefault$e = helpers$1.valueOrDefault;\r\n\r\ncore_defaults._set('global', {\r\n\tlegend: {\r\n\t\tdisplay: true,\r\n\t\tposition: 'top',\r\n\t\talign: 'center',\r\n\t\tfullWidth: true,\r\n\t\treverse: false,\r\n\t\tweight: 1000,\r\n\r\n\t\t// a callback that will handle\r\n\t\tonClick: function(e, legendItem) {\r\n\t\t\tvar index = legendItem.datasetIndex;\r\n\t\t\tvar ci = this.chart;\r\n\t\t\tvar meta = ci.getDatasetMeta(index);\r\n\r\n\t\t\t// See controller.isDatasetVisible comment\r\n\t\t\tmeta.hidden = meta.hidden === null ? !ci.data.datasets[index].hidden : null;\r\n\r\n\t\t\t// We hid a dataset ... rerender the chart\r\n\t\t\tci.update();\r\n\t\t},\r\n\r\n\t\tonHover: null,\r\n\t\tonLeave: null,\r\n\r\n\t\tlabels: {\r\n\t\t\tboxWidth: 40,\r\n\t\t\tpadding: 10,\r\n\t\t\t// Generates labels shown in the legend\r\n\t\t\t// Valid properties to return:\r\n\t\t\t// text : text to display\r\n\t\t\t// fillStyle : fill of coloured box\r\n\t\t\t// strokeStyle: stroke of coloured box\r\n\t\t\t// hidden : if this legend item refers to a hidden item\r\n\t\t\t// lineCap : cap style for line\r\n\t\t\t// lineDash\r\n\t\t\t// lineDashOffset :\r\n\t\t\t// lineJoin :\r\n\t\t\t// lineWidth :\r\n\t\t\tgenerateLabels: function(chart) {\r\n\t\t\t\tvar datasets = chart.data.datasets;\r\n\t\t\t\tvar options = chart.options.legend || {};\r\n\t\t\t\tvar usePointStyle = options.labels && options.labels.usePointStyle;\r\n\r\n\t\t\t\treturn chart._getSortedDatasetMetas().map(function(meta) {\r\n\t\t\t\t\tvar style = meta.controller.getStyle(usePointStyle ? 0 : undefined);\r\n\r\n\t\t\t\t\treturn {\r\n\t\t\t\t\t\ttext: datasets[meta.index].label,\r\n\t\t\t\t\t\tfillStyle: style.backgroundColor,\r\n\t\t\t\t\t\thidden: !chart.isDatasetVisible(meta.index),\r\n\t\t\t\t\t\tlineCap: style.borderCapStyle,\r\n\t\t\t\t\t\tlineDash: style.borderDash,\r\n\t\t\t\t\t\tlineDashOffset: style.borderDashOffset,\r\n\t\t\t\t\t\tlineJoin: style.borderJoinStyle,\r\n\t\t\t\t\t\tlineWidth: style.borderWidth,\r\n\t\t\t\t\t\tstrokeStyle: style.borderColor,\r\n\t\t\t\t\t\tpointStyle: style.pointStyle,\r\n\t\t\t\t\t\trotation: style.rotation,\r\n\r\n\t\t\t\t\t\t// Below is extra data used for toggling the datasets\r\n\t\t\t\t\t\tdatasetIndex: meta.index\r\n\t\t\t\t\t};\r\n\t\t\t\t}, this);\r\n\t\t\t}\r\n\t\t}\r\n\t},\r\n\r\n\tlegendCallback: function(chart) {\r\n\t\tvar list = document.createElement('ul');\r\n\t\tvar datasets = chart.data.datasets;\r\n\t\tvar i, ilen, listItem, listItemSpan;\r\n\r\n\t\tlist.setAttribute('class', chart.id + '-legend');\r\n\r\n\t\tfor (i = 0, ilen = datasets.length; i < ilen; i++) {\r\n\t\t\tlistItem = list.appendChild(document.createElement('li'));\r\n\t\t\tlistItemSpan = listItem.appendChild(document.createElement('span'));\r\n\t\t\tlistItemSpan.style.backgroundColor = datasets[i].backgroundColor;\r\n\t\t\tif (datasets[i].label) {\r\n\t\t\t\tlistItem.appendChild(document.createTextNode(datasets[i].label));\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn list.outerHTML;\r\n\t}\r\n});\r\n\r\n/**\r\n * Helper function to get the box width based on the usePointStyle option\r\n * @param {object} labelopts - the label options on the legend\r\n * @param {number} fontSize - the label font size\r\n * @return {number} width of the color box area\r\n */\r\nfunction getBoxWidth(labelOpts, fontSize) {\r\n\treturn labelOpts.usePointStyle && labelOpts.boxWidth > fontSize ?\r\n\t\tfontSize :\r\n\t\tlabelOpts.boxWidth;\r\n}\r\n\r\n/**\r\n * IMPORTANT: this class is exposed publicly as Chart.Legend, backward compatibility required!\r\n */\r\nvar Legend = core_element.extend({\r\n\r\n\tinitialize: function(config) {\r\n\t\tvar me = this;\r\n\t\thelpers$1.extend(me, config);\r\n\r\n\t\t// Contains hit boxes for each dataset (in dataset order)\r\n\t\tme.legendHitBoxes = [];\r\n\r\n\t\t/**\r\n \t\t * @private\r\n \t\t */\r\n\t\tme._hoveredItem = null;\r\n\r\n\t\t// Are we in doughnut mode which has a different data type\r\n\t\tme.doughnutMode = false;\r\n\t},\r\n\r\n\t// These methods are ordered by lifecycle. Utilities then follow.\r\n\t// Any function defined here is inherited by all legend types.\r\n\t// Any function can be extended by the legend type\r\n\r\n\tbeforeUpdate: noop$1,\r\n\tupdate: function(maxWidth, maxHeight, margins) {\r\n\t\tvar me = this;\r\n\r\n\t\t// Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)\r\n\t\tme.beforeUpdate();\r\n\r\n\t\t// Absorb the master measurements\r\n\t\tme.maxWidth = maxWidth;\r\n\t\tme.maxHeight = maxHeight;\r\n\t\tme.margins = margins;\r\n\r\n\t\t// Dimensions\r\n\t\tme.beforeSetDimensions();\r\n\t\tme.setDimensions();\r\n\t\tme.afterSetDimensions();\r\n\t\t// Labels\r\n\t\tme.beforeBuildLabels();\r\n\t\tme.buildLabels();\r\n\t\tme.afterBuildLabels();\r\n\r\n\t\t// Fit\r\n\t\tme.beforeFit();\r\n\t\tme.fit();\r\n\t\tme.afterFit();\r\n\t\t//\r\n\t\tme.afterUpdate();\r\n\r\n\t\treturn me.minSize;\r\n\t},\r\n\tafterUpdate: noop$1,\r\n\r\n\t//\r\n\r\n\tbeforeSetDimensions: noop$1,\r\n\tsetDimensions: function() {\r\n\t\tvar me = this;\r\n\t\t// Set the unconstrained dimension before label rotation\r\n\t\tif (me.isHorizontal()) {\r\n\t\t\t// Reset position before calculating rotation\r\n\t\t\tme.width = me.maxWidth;\r\n\t\t\tme.left = 0;\r\n\t\t\tme.right = me.width;\r\n\t\t} else {\r\n\t\t\tme.height = me.maxHeight;\r\n\r\n\t\t\t// Reset position before calculating rotation\r\n\t\t\tme.top = 0;\r\n\t\t\tme.bottom = me.height;\r\n\t\t}\r\n\r\n\t\t// Reset padding\r\n\t\tme.paddingLeft = 0;\r\n\t\tme.paddingTop = 0;\r\n\t\tme.paddingRight = 0;\r\n\t\tme.paddingBottom = 0;\r\n\r\n\t\t// Reset minSize\r\n\t\tme.minSize = {\r\n\t\t\twidth: 0,\r\n\t\t\theight: 0\r\n\t\t};\r\n\t},\r\n\tafterSetDimensions: noop$1,\r\n\r\n\t//\r\n\r\n\tbeforeBuildLabels: noop$1,\r\n\tbuildLabels: function() {\r\n\t\tvar me = this;\r\n\t\tvar labelOpts = me.options.labels || {};\r\n\t\tvar legendItems = helpers$1.callback(labelOpts.generateLabels, [me.chart], me) || [];\r\n\r\n\t\tif (labelOpts.filter) {\r\n\t\t\tlegendItems = legendItems.filter(function(item) {\r\n\t\t\t\treturn labelOpts.filter(item, me.chart.data);\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tif (me.options.reverse) {\r\n\t\t\tlegendItems.reverse();\r\n\t\t}\r\n\r\n\t\tme.legendItems = legendItems;\r\n\t},\r\n\tafterBuildLabels: noop$1,\r\n\r\n\t//\r\n\r\n\tbeforeFit: noop$1,\r\n\tfit: function() {\r\n\t\tvar me = this;\r\n\t\tvar opts = me.options;\r\n\t\tvar labelOpts = opts.labels;\r\n\t\tvar display = opts.display;\r\n\r\n\t\tvar ctx = me.ctx;\r\n\r\n\t\tvar labelFont = helpers$1.options._parseFont(labelOpts);\r\n\t\tvar fontSize = labelFont.size;\r\n\r\n\t\t// Reset hit boxes\r\n\t\tvar hitboxes = me.legendHitBoxes = [];\r\n\r\n\t\tvar minSize = me.minSize;\r\n\t\tvar isHorizontal = me.isHorizontal();\r\n\r\n\t\tif (isHorizontal) {\r\n\t\t\tminSize.width = me.maxWidth; // fill all the width\r\n\t\t\tminSize.height = display ? 10 : 0;\r\n\t\t} else {\r\n\t\t\tminSize.width = display ? 10 : 0;\r\n\t\t\tminSize.height = me.maxHeight; // fill all the height\r\n\t\t}\r\n\r\n\t\t// Increase sizes here\r\n\t\tif (!display) {\r\n\t\t\tme.width = minSize.width = me.height = minSize.height = 0;\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tctx.font = labelFont.string;\r\n\r\n\t\tif (isHorizontal) {\r\n\t\t\t// Labels\r\n\r\n\t\t\t// Width of each line of legend boxes. Labels wrap onto multiple lines when there are too many to fit on one\r\n\t\t\tvar lineWidths = me.lineWidths = [0];\r\n\t\t\tvar totalHeight = 0;\r\n\r\n\t\t\tctx.textAlign = 'left';\r\n\t\t\tctx.textBaseline = 'middle';\r\n\r\n\t\t\thelpers$1.each(me.legendItems, function(legendItem, i) {\r\n\t\t\t\tvar boxWidth = getBoxWidth(labelOpts, fontSize);\r\n\t\t\t\tvar width = boxWidth + (fontSize / 2) + ctx.measureText(legendItem.text).width;\r\n\r\n\t\t\t\tif (i === 0 || lineWidths[lineWidths.length - 1] + width + 2 * labelOpts.padding > minSize.width) {\r\n\t\t\t\t\ttotalHeight += fontSize + labelOpts.padding;\r\n\t\t\t\t\tlineWidths[lineWidths.length - (i > 0 ? 0 : 1)] = 0;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Store the hitbox width and height here. Final position will be updated in `draw`\r\n\t\t\t\thitboxes[i] = {\r\n\t\t\t\t\tleft: 0,\r\n\t\t\t\t\ttop: 0,\r\n\t\t\t\t\twidth: width,\r\n\t\t\t\t\theight: fontSize\r\n\t\t\t\t};\r\n\r\n\t\t\t\tlineWidths[lineWidths.length - 1] += width + labelOpts.padding;\r\n\t\t\t});\r\n\r\n\t\t\tminSize.height += totalHeight;\r\n\r\n\t\t} else {\r\n\t\t\tvar vPadding = labelOpts.padding;\r\n\t\t\tvar columnWidths = me.columnWidths = [];\r\n\t\t\tvar columnHeights = me.columnHeights = [];\r\n\t\t\tvar totalWidth = labelOpts.padding;\r\n\t\t\tvar currentColWidth = 0;\r\n\t\t\tvar currentColHeight = 0;\r\n\r\n\t\t\thelpers$1.each(me.legendItems, function(legendItem, i) {\r\n\t\t\t\tvar boxWidth = getBoxWidth(labelOpts, fontSize);\r\n\t\t\t\tvar itemWidth = boxWidth + (fontSize / 2) + ctx.measureText(legendItem.text).width;\r\n\r\n\t\t\t\t// If too tall, go to new column\r\n\t\t\t\tif (i > 0 && currentColHeight + fontSize + 2 * vPadding > minSize.height) {\r\n\t\t\t\t\ttotalWidth += currentColWidth + labelOpts.padding;\r\n\t\t\t\t\tcolumnWidths.push(currentColWidth); // previous column width\r\n\t\t\t\t\tcolumnHeights.push(currentColHeight);\r\n\t\t\t\t\tcurrentColWidth = 0;\r\n\t\t\t\t\tcurrentColHeight = 0;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Get max width\r\n\t\t\t\tcurrentColWidth = Math.max(currentColWidth, itemWidth);\r\n\t\t\t\tcurrentColHeight += fontSize + vPadding;\r\n\r\n\t\t\t\t// Store the hitbox width and height here. Final position will be updated in `draw`\r\n\t\t\t\thitboxes[i] = {\r\n\t\t\t\t\tleft: 0,\r\n\t\t\t\t\ttop: 0,\r\n\t\t\t\t\twidth: itemWidth,\r\n\t\t\t\t\theight: fontSize\r\n\t\t\t\t};\r\n\t\t\t});\r\n\r\n\t\t\ttotalWidth += currentColWidth;\r\n\t\t\tcolumnWidths.push(currentColWidth);\r\n\t\t\tcolumnHeights.push(currentColHeight);\r\n\t\t\tminSize.width += totalWidth;\r\n\t\t}\r\n\r\n\t\tme.width = minSize.width;\r\n\t\tme.height = minSize.height;\r\n\t},\r\n\tafterFit: noop$1,\r\n\r\n\t// Shared Methods\r\n\tisHorizontal: function() {\r\n\t\treturn this.options.position === 'top' || this.options.position === 'bottom';\r\n\t},\r\n\r\n\t// Actually draw the legend on the canvas\r\n\tdraw: function() {\r\n\t\tvar me = this;\r\n\t\tvar opts = me.options;\r\n\t\tvar labelOpts = opts.labels;\r\n\t\tvar globalDefaults = core_defaults.global;\r\n\t\tvar defaultColor = globalDefaults.defaultColor;\r\n\t\tvar lineDefault = globalDefaults.elements.line;\r\n\t\tvar legendHeight = me.height;\r\n\t\tvar columnHeights = me.columnHeights;\r\n\t\tvar legendWidth = me.width;\r\n\t\tvar lineWidths = me.lineWidths;\r\n\r\n\t\tif (!opts.display) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tvar rtlHelper = getRtlHelper$1(opts.rtl, me.left, me.minSize.width);\r\n\t\tvar ctx = me.ctx;\r\n\t\tvar fontColor = valueOrDefault$e(labelOpts.fontColor, globalDefaults.defaultFontColor);\r\n\t\tvar labelFont = helpers$1.options._parseFont(labelOpts);\r\n\t\tvar fontSize = labelFont.size;\r\n\t\tvar cursor;\r\n\r\n\t\t// Canvas setup\r\n\t\tctx.textAlign = rtlHelper.textAlign('left');\r\n\t\tctx.textBaseline = 'middle';\r\n\t\tctx.lineWidth = 0.5;\r\n\t\tctx.strokeStyle = fontColor; // for strikethrough effect\r\n\t\tctx.fillStyle = fontColor; // render in correct colour\r\n\t\tctx.font = labelFont.string;\r\n\r\n\t\tvar boxWidth = getBoxWidth(labelOpts, fontSize);\r\n\t\tvar hitboxes = me.legendHitBoxes;\r\n\r\n\t\t// current position\r\n\t\tvar drawLegendBox = function(x, y, legendItem) {\r\n\t\t\tif (isNaN(boxWidth) || boxWidth <= 0) {\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\t// Set the ctx for the box\r\n\t\t\tctx.save();\r\n\r\n\t\t\tvar lineWidth = valueOrDefault$e(legendItem.lineWidth, lineDefault.borderWidth);\r\n\t\t\tctx.fillStyle = valueOrDefault$e(legendItem.fillStyle, defaultColor);\r\n\t\t\tctx.lineCap = valueOrDefault$e(legendItem.lineCap, lineDefault.borderCapStyle);\r\n\t\t\tctx.lineDashOffset = valueOrDefault$e(legendItem.lineDashOffset, lineDefault.borderDashOffset);\r\n\t\t\tctx.lineJoin = valueOrDefault$e(legendItem.lineJoin, lineDefault.borderJoinStyle);\r\n\t\t\tctx.lineWidth = lineWidth;\r\n\t\t\tctx.strokeStyle = valueOrDefault$e(legendItem.strokeStyle, defaultColor);\r\n\r\n\t\t\tif (ctx.setLineDash) {\r\n\t\t\t\t// IE 9 and 10 do not support line dash\r\n\t\t\t\tctx.setLineDash(valueOrDefault$e(legendItem.lineDash, lineDefault.borderDash));\r\n\t\t\t}\r\n\r\n\t\t\tif (labelOpts && labelOpts.usePointStyle) {\r\n\t\t\t\t// Recalculate x and y for drawPoint() because its expecting\r\n\t\t\t\t// x and y to be center of figure (instead of top left)\r\n\t\t\t\tvar radius = boxWidth * Math.SQRT2 / 2;\r\n\t\t\t\tvar centerX = rtlHelper.xPlus(x, boxWidth / 2);\r\n\t\t\t\tvar centerY = y + fontSize / 2;\r\n\r\n\t\t\t\t// Draw pointStyle as legend symbol\r\n\t\t\t\thelpers$1.canvas.drawPoint(ctx, legendItem.pointStyle, radius, centerX, centerY, legendItem.rotation);\r\n\t\t\t} else {\r\n\t\t\t\t// Draw box as legend symbol\r\n\t\t\t\tctx.fillRect(rtlHelper.leftForLtr(x, boxWidth), y, boxWidth, fontSize);\r\n\t\t\t\tif (lineWidth !== 0) {\r\n\t\t\t\t\tctx.strokeRect(rtlHelper.leftForLtr(x, boxWidth), y, boxWidth, fontSize);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tctx.restore();\r\n\t\t};\r\n\r\n\t\tvar fillText = function(x, y, legendItem, textWidth) {\r\n\t\t\tvar halfFontSize = fontSize / 2;\r\n\t\t\tvar xLeft = rtlHelper.xPlus(x, boxWidth + halfFontSize);\r\n\t\t\tvar yMiddle = y + halfFontSize;\r\n\r\n\t\t\tctx.fillText(legendItem.text, xLeft, yMiddle);\r\n\r\n\t\t\tif (legendItem.hidden) {\r\n\t\t\t\t// Strikethrough the text if hidden\r\n\t\t\t\tctx.beginPath();\r\n\t\t\t\tctx.lineWidth = 2;\r\n\t\t\t\tctx.moveTo(xLeft, yMiddle);\r\n\t\t\t\tctx.lineTo(rtlHelper.xPlus(xLeft, textWidth), yMiddle);\r\n\t\t\t\tctx.stroke();\r\n\t\t\t}\r\n\t\t};\r\n\r\n\t\tvar alignmentOffset = function(dimension, blockSize) {\r\n\t\t\tswitch (opts.align) {\r\n\t\t\tcase 'start':\r\n\t\t\t\treturn labelOpts.padding;\r\n\t\t\tcase 'end':\r\n\t\t\t\treturn dimension - blockSize;\r\n\t\t\tdefault: // center\r\n\t\t\t\treturn (dimension - blockSize + labelOpts.padding) / 2;\r\n\t\t\t}\r\n\t\t};\r\n\r\n\t\t// Horizontal\r\n\t\tvar isHorizontal = me.isHorizontal();\r\n\t\tif (isHorizontal) {\r\n\t\t\tcursor = {\r\n\t\t\t\tx: me.left + alignmentOffset(legendWidth, lineWidths[0]),\r\n\t\t\t\ty: me.top + labelOpts.padding,\r\n\t\t\t\tline: 0\r\n\t\t\t};\r\n\t\t} else {\r\n\t\t\tcursor = {\r\n\t\t\t\tx: me.left + labelOpts.padding,\r\n\t\t\t\ty: me.top + alignmentOffset(legendHeight, columnHeights[0]),\r\n\t\t\t\tline: 0\r\n\t\t\t};\r\n\t\t}\r\n\r\n\t\thelpers$1.rtl.overrideTextDirection(me.ctx, opts.textDirection);\r\n\r\n\t\tvar itemHeight = fontSize + labelOpts.padding;\r\n\t\thelpers$1.each(me.legendItems, function(legendItem, i) {\r\n\t\t\tvar textWidth = ctx.measureText(legendItem.text).width;\r\n\t\t\tvar width = boxWidth + (fontSize / 2) + textWidth;\r\n\t\t\tvar x = cursor.x;\r\n\t\t\tvar y = cursor.y;\r\n\r\n\t\t\trtlHelper.setWidth(me.minSize.width);\r\n\r\n\t\t\t// Use (me.left + me.minSize.width) and (me.top + me.minSize.height)\r\n\t\t\t// instead of me.right and me.bottom because me.width and me.height\r\n\t\t\t// may have been changed since me.minSize was calculated\r\n\t\t\tif (isHorizontal) {\r\n\t\t\t\tif (i > 0 && x + width + labelOpts.padding > me.left + me.minSize.width) {\r\n\t\t\t\t\ty = cursor.y += itemHeight;\r\n\t\t\t\t\tcursor.line++;\r\n\t\t\t\t\tx = cursor.x = me.left + alignmentOffset(legendWidth, lineWidths[cursor.line]);\r\n\t\t\t\t}\r\n\t\t\t} else if (i > 0 && y + itemHeight > me.top + me.minSize.height) {\r\n\t\t\t\tx = cursor.x = x + me.columnWidths[cursor.line] + labelOpts.padding;\r\n\t\t\t\tcursor.line++;\r\n\t\t\t\ty = cursor.y = me.top + alignmentOffset(legendHeight, columnHeights[cursor.line]);\r\n\t\t\t}\r\n\r\n\t\t\tvar realX = rtlHelper.x(x);\r\n\r\n\t\t\tdrawLegendBox(realX, y, legendItem);\r\n\r\n\t\t\thitboxes[i].left = rtlHelper.leftForLtr(realX, hitboxes[i].width);\r\n\t\t\thitboxes[i].top = y;\r\n\r\n\t\t\t// Fill the actual label\r\n\t\t\tfillText(realX, y, legendItem, textWidth);\r\n\r\n\t\t\tif (isHorizontal) {\r\n\t\t\t\tcursor.x += width + labelOpts.padding;\r\n\t\t\t} else {\r\n\t\t\t\tcursor.y += itemHeight;\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\thelpers$1.rtl.restoreTextDirection(me.ctx, opts.textDirection);\r\n\t},\r\n\r\n\t/**\r\n\t * @private\r\n\t */\r\n\t_getLegendItemAt: function(x, y) {\r\n\t\tvar me = this;\r\n\t\tvar i, hitBox, lh;\r\n\r\n\t\tif (x >= me.left && x <= me.right && y >= me.top && y <= me.bottom) {\r\n\t\t\t// See if we are touching one of the dataset boxes\r\n\t\t\tlh = me.legendHitBoxes;\r\n\t\t\tfor (i = 0; i < lh.length; ++i) {\r\n\t\t\t\thitBox = lh[i];\r\n\r\n\t\t\t\tif (x >= hitBox.left && x <= hitBox.left + hitBox.width && y >= hitBox.top && y <= hitBox.top + hitBox.height) {\r\n\t\t\t\t\t// Touching an element\r\n\t\t\t\t\treturn me.legendItems[i];\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn null;\r\n\t},\r\n\r\n\t/**\r\n\t * Handle an event\r\n\t * @private\r\n\t * @param {IEvent} event - The event to handle\r\n\t */\r\n\thandleEvent: function(e) {\r\n\t\tvar me = this;\r\n\t\tvar opts = me.options;\r\n\t\tvar type = e.type === 'mouseup' ? 'click' : e.type;\r\n\t\tvar hoveredItem;\r\n\r\n\t\tif (type === 'mousemove') {\r\n\t\t\tif (!opts.onHover && !opts.onLeave) {\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t} else if (type === 'click') {\r\n\t\t\tif (!opts.onClick) {\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// Chart event already has relative position in it\r\n\t\thoveredItem = me._getLegendItemAt(e.x, e.y);\r\n\r\n\t\tif (type === 'click') {\r\n\t\t\tif (hoveredItem && opts.onClick) {\r\n\t\t\t\t// use e.native for backwards compatibility\r\n\t\t\t\topts.onClick.call(me, e.native, hoveredItem);\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tif (opts.onLeave && hoveredItem !== me._hoveredItem) {\r\n\t\t\t\tif (me._hoveredItem) {\r\n\t\t\t\t\topts.onLeave.call(me, e.native, me._hoveredItem);\r\n\t\t\t\t}\r\n\t\t\t\tme._hoveredItem = hoveredItem;\r\n\t\t\t}\r\n\r\n\t\t\tif (opts.onHover && hoveredItem) {\r\n\t\t\t\t// use e.native for backwards compatibility\r\n\t\t\t\topts.onHover.call(me, e.native, hoveredItem);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n});\r\n\r\nfunction createNewLegendAndAttach(chart, legendOpts) {\r\n\tvar legend = new Legend({\r\n\t\tctx: chart.ctx,\r\n\t\toptions: legendOpts,\r\n\t\tchart: chart\r\n\t});\r\n\r\n\tcore_layouts.configure(chart, legend, legendOpts);\r\n\tcore_layouts.addBox(chart, legend);\r\n\tchart.legend = legend;\r\n}\r\n\r\nvar plugin_legend = {\r\n\tid: 'legend',\r\n\r\n\t/**\r\n\t * Backward compatibility: since 2.1.5, the legend is registered as a plugin, making\r\n\t * Chart.Legend obsolete. To avoid a breaking change, we export the Legend as part of\r\n\t * the plugin, which one will be re-exposed in the chart.js file.\r\n\t * https://github.com/chartjs/Chart.js/pull/2640\r\n\t * @private\r\n\t */\r\n\t_element: Legend,\r\n\r\n\tbeforeInit: function(chart) {\r\n\t\tvar legendOpts = chart.options.legend;\r\n\r\n\t\tif (legendOpts) {\r\n\t\t\tcreateNewLegendAndAttach(chart, legendOpts);\r\n\t\t}\r\n\t},\r\n\r\n\tbeforeUpdate: function(chart) {\r\n\t\tvar legendOpts = chart.options.legend;\r\n\t\tvar legend = chart.legend;\r\n\r\n\t\tif (legendOpts) {\r\n\t\t\thelpers$1.mergeIf(legendOpts, core_defaults.global.legend);\r\n\r\n\t\t\tif (legend) {\r\n\t\t\t\tcore_layouts.configure(chart, legend, legendOpts);\r\n\t\t\t\tlegend.options = legendOpts;\r\n\t\t\t} else {\r\n\t\t\t\tcreateNewLegendAndAttach(chart, legendOpts);\r\n\t\t\t}\r\n\t\t} else if (legend) {\r\n\t\t\tcore_layouts.removeBox(chart, legend);\r\n\t\t\tdelete chart.legend;\r\n\t\t}\r\n\t},\r\n\r\n\tafterEvent: function(chart, e) {\r\n\t\tvar legend = chart.legend;\r\n\t\tif (legend) {\r\n\t\t\tlegend.handleEvent(e);\r\n\t\t}\r\n\t}\r\n};\n\nvar noop$2 = helpers$1.noop;\r\n\r\ncore_defaults._set('global', {\r\n\ttitle: {\r\n\t\tdisplay: false,\r\n\t\tfontStyle: 'bold',\r\n\t\tfullWidth: true,\r\n\t\tpadding: 10,\r\n\t\tposition: 'top',\r\n\t\ttext: '',\r\n\t\tweight: 2000 // by default greater than legend (1000) to be above\r\n\t}\r\n});\r\n\r\n/**\r\n * IMPORTANT: this class is exposed publicly as Chart.Legend, backward compatibility required!\r\n */\r\nvar Title = core_element.extend({\r\n\tinitialize: function(config) {\r\n\t\tvar me = this;\r\n\t\thelpers$1.extend(me, config);\r\n\r\n\t\t// Contains hit boxes for each dataset (in dataset order)\r\n\t\tme.legendHitBoxes = [];\r\n\t},\r\n\r\n\t// These methods are ordered by lifecycle. Utilities then follow.\r\n\r\n\tbeforeUpdate: noop$2,\r\n\tupdate: function(maxWidth, maxHeight, margins) {\r\n\t\tvar me = this;\r\n\r\n\t\t// Update Lifecycle - Probably don't want to ever extend or overwrite this function ;)\r\n\t\tme.beforeUpdate();\r\n\r\n\t\t// Absorb the master measurements\r\n\t\tme.maxWidth = maxWidth;\r\n\t\tme.maxHeight = maxHeight;\r\n\t\tme.margins = margins;\r\n\r\n\t\t// Dimensions\r\n\t\tme.beforeSetDimensions();\r\n\t\tme.setDimensions();\r\n\t\tme.afterSetDimensions();\r\n\t\t// Labels\r\n\t\tme.beforeBuildLabels();\r\n\t\tme.buildLabels();\r\n\t\tme.afterBuildLabels();\r\n\r\n\t\t// Fit\r\n\t\tme.beforeFit();\r\n\t\tme.fit();\r\n\t\tme.afterFit();\r\n\t\t//\r\n\t\tme.afterUpdate();\r\n\r\n\t\treturn me.minSize;\r\n\r\n\t},\r\n\tafterUpdate: noop$2,\r\n\r\n\t//\r\n\r\n\tbeforeSetDimensions: noop$2,\r\n\tsetDimensions: function() {\r\n\t\tvar me = this;\r\n\t\t// Set the unconstrained dimension before label rotation\r\n\t\tif (me.isHorizontal()) {\r\n\t\t\t// Reset position before calculating rotation\r\n\t\t\tme.width = me.maxWidth;\r\n\t\t\tme.left = 0;\r\n\t\t\tme.right = me.width;\r\n\t\t} else {\r\n\t\t\tme.height = me.maxHeight;\r\n\r\n\t\t\t// Reset position before calculating rotation\r\n\t\t\tme.top = 0;\r\n\t\t\tme.bottom = me.height;\r\n\t\t}\r\n\r\n\t\t// Reset padding\r\n\t\tme.paddingLeft = 0;\r\n\t\tme.paddingTop = 0;\r\n\t\tme.paddingRight = 0;\r\n\t\tme.paddingBottom = 0;\r\n\r\n\t\t// Reset minSize\r\n\t\tme.minSize = {\r\n\t\t\twidth: 0,\r\n\t\t\theight: 0\r\n\t\t};\r\n\t},\r\n\tafterSetDimensions: noop$2,\r\n\r\n\t//\r\n\r\n\tbeforeBuildLabels: noop$2,\r\n\tbuildLabels: noop$2,\r\n\tafterBuildLabels: noop$2,\r\n\r\n\t//\r\n\r\n\tbeforeFit: noop$2,\r\n\tfit: function() {\r\n\t\tvar me = this;\r\n\t\tvar opts = me.options;\r\n\t\tvar minSize = me.minSize = {};\r\n\t\tvar isHorizontal = me.isHorizontal();\r\n\t\tvar lineCount, textSize;\r\n\r\n\t\tif (!opts.display) {\r\n\t\t\tme.width = minSize.width = me.height = minSize.height = 0;\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tlineCount = helpers$1.isArray(opts.text) ? opts.text.length : 1;\r\n\t\ttextSize = lineCount * helpers$1.options._parseFont(opts).lineHeight + opts.padding * 2;\r\n\r\n\t\tme.width = minSize.width = isHorizontal ? me.maxWidth : textSize;\r\n\t\tme.height = minSize.height = isHorizontal ? textSize : me.maxHeight;\r\n\t},\r\n\tafterFit: noop$2,\r\n\r\n\t// Shared Methods\r\n\tisHorizontal: function() {\r\n\t\tvar pos = this.options.position;\r\n\t\treturn pos === 'top' || pos === 'bottom';\r\n\t},\r\n\r\n\t// Actually draw the title block on the canvas\r\n\tdraw: function() {\r\n\t\tvar me = this;\r\n\t\tvar ctx = me.ctx;\r\n\t\tvar opts = me.options;\r\n\r\n\t\tif (!opts.display) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tvar fontOpts = helpers$1.options._parseFont(opts);\r\n\t\tvar lineHeight = fontOpts.lineHeight;\r\n\t\tvar offset = lineHeight / 2 + opts.padding;\r\n\t\tvar rotation = 0;\r\n\t\tvar top = me.top;\r\n\t\tvar left = me.left;\r\n\t\tvar bottom = me.bottom;\r\n\t\tvar right = me.right;\r\n\t\tvar maxWidth, titleX, titleY;\r\n\r\n\t\tctx.fillStyle = helpers$1.valueOrDefault(opts.fontColor, core_defaults.global.defaultFontColor); // render in correct colour\r\n\t\tctx.font = fontOpts.string;\r\n\r\n\t\t// Horizontal\r\n\t\tif (me.isHorizontal()) {\r\n\t\t\ttitleX = left + ((right - left) / 2); // midpoint of the width\r\n\t\t\ttitleY = top + offset;\r\n\t\t\tmaxWidth = right - left;\r\n\t\t} else {\r\n\t\t\ttitleX = opts.position === 'left' ? left + offset : right - offset;\r\n\t\t\ttitleY = top + ((bottom - top) / 2);\r\n\t\t\tmaxWidth = bottom - top;\r\n\t\t\trotation = Math.PI * (opts.position === 'left' ? -0.5 : 0.5);\r\n\t\t}\r\n\r\n\t\tctx.save();\r\n\t\tctx.translate(titleX, titleY);\r\n\t\tctx.rotate(rotation);\r\n\t\tctx.textAlign = 'center';\r\n\t\tctx.textBaseline = 'middle';\r\n\r\n\t\tvar text = opts.text;\r\n\t\tif (helpers$1.isArray(text)) {\r\n\t\t\tvar y = 0;\r\n\t\t\tfor (var i = 0; i < text.length; ++i) {\r\n\t\t\t\tctx.fillText(text[i], 0, y, maxWidth);\r\n\t\t\t\ty += lineHeight;\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tctx.fillText(text, 0, 0, maxWidth);\r\n\t\t}\r\n\r\n\t\tctx.restore();\r\n\t}\r\n});\r\n\r\nfunction createNewTitleBlockAndAttach(chart, titleOpts) {\r\n\tvar title = new Title({\r\n\t\tctx: chart.ctx,\r\n\t\toptions: titleOpts,\r\n\t\tchart: chart\r\n\t});\r\n\r\n\tcore_layouts.configure(chart, title, titleOpts);\r\n\tcore_layouts.addBox(chart, title);\r\n\tchart.titleBlock = title;\r\n}\r\n\r\nvar plugin_title = {\r\n\tid: 'title',\r\n\r\n\t/**\r\n\t * Backward compatibility: since 2.1.5, the title is registered as a plugin, making\r\n\t * Chart.Title obsolete. To avoid a breaking change, we export the Title as part of\r\n\t * the plugin, which one will be re-exposed in the chart.js file.\r\n\t * https://github.com/chartjs/Chart.js/pull/2640\r\n\t * @private\r\n\t */\r\n\t_element: Title,\r\n\r\n\tbeforeInit: function(chart) {\r\n\t\tvar titleOpts = chart.options.title;\r\n\r\n\t\tif (titleOpts) {\r\n\t\t\tcreateNewTitleBlockAndAttach(chart, titleOpts);\r\n\t\t}\r\n\t},\r\n\r\n\tbeforeUpdate: function(chart) {\r\n\t\tvar titleOpts = chart.options.title;\r\n\t\tvar titleBlock = chart.titleBlock;\r\n\r\n\t\tif (titleOpts) {\r\n\t\t\thelpers$1.mergeIf(titleOpts, core_defaults.global.title);\r\n\r\n\t\t\tif (titleBlock) {\r\n\t\t\t\tcore_layouts.configure(chart, titleBlock, titleOpts);\r\n\t\t\t\ttitleBlock.options = titleOpts;\r\n\t\t\t} else {\r\n\t\t\t\tcreateNewTitleBlockAndAttach(chart, titleOpts);\r\n\t\t\t}\r\n\t\t} else if (titleBlock) {\r\n\t\t\tcore_layouts.removeBox(chart, titleBlock);\r\n\t\t\tdelete chart.titleBlock;\r\n\t\t}\r\n\t}\r\n};\n\nvar plugins = {};\r\nvar filler = plugin_filler;\r\nvar legend = plugin_legend;\r\nvar title = plugin_title;\nplugins.filler = filler;\nplugins.legend = legend;\nplugins.title = title;\n\n/**\r\n * @namespace Chart\r\n */\r\n\r\n\r\ncore_controller.helpers = helpers$1;\r\n\r\n// @todo dispatch these helpers into appropriated helpers/helpers.* file and write unit tests!\r\ncore_helpers();\r\n\r\ncore_controller._adapters = core_adapters;\r\ncore_controller.Animation = core_animation;\r\ncore_controller.animationService = core_animations;\r\ncore_controller.controllers = controllers;\r\ncore_controller.DatasetController = core_datasetController;\r\ncore_controller.defaults = core_defaults;\r\ncore_controller.Element = core_element;\r\ncore_controller.elements = elements;\r\ncore_controller.Interaction = core_interaction;\r\ncore_controller.layouts = core_layouts;\r\ncore_controller.platform = platform;\r\ncore_controller.plugins = core_plugins;\r\ncore_controller.Scale = core_scale;\r\ncore_controller.scaleService = core_scaleService;\r\ncore_controller.Ticks = core_ticks;\r\ncore_controller.Tooltip = core_tooltip;\r\n\r\n// Register built-in scales\r\n\r\ncore_controller.helpers.each(scales, function(scale, type) {\r\n\tcore_controller.scaleService.registerScaleType(type, scale, scale._defaults);\r\n});\r\n\r\n// Load to register built-in adapters (as side effects)\r\n\r\n\r\n// Loading built-in plugins\r\n\r\nfor (var k in plugins) {\r\n\tif (plugins.hasOwnProperty(k)) {\r\n\t\tcore_controller.plugins.register(plugins[k]);\r\n\t}\r\n}\r\n\r\ncore_controller.platform.initialize();\r\n\r\nvar src = core_controller;\r\nif (typeof window !== 'undefined') {\r\n\twindow.Chart = core_controller;\r\n}\r\n\r\n// DEPRECATIONS\r\n\r\n/**\r\n * Provided for backward compatibility, not available anymore\r\n * @namespace Chart.Chart\r\n * @deprecated since version 2.8.0\r\n * @todo remove at version 3\r\n * @private\r\n */\r\ncore_controller.Chart = core_controller;\r\n\r\n/**\r\n * Provided for backward compatibility, not available anymore\r\n * @namespace Chart.Legend\r\n * @deprecated since version 2.1.5\r\n * @todo remove at version 3\r\n * @private\r\n */\r\ncore_controller.Legend = plugins.legend._element;\r\n\r\n/**\r\n * Provided for backward compatibility, not available anymore\r\n * @namespace Chart.Title\r\n * @deprecated since version 2.1.5\r\n * @todo remove at version 3\r\n * @private\r\n */\r\ncore_controller.Title = plugins.title._element;\r\n\r\n/**\r\n * Provided for backward compatibility, use Chart.plugins instead\r\n * @namespace Chart.pluginService\r\n * @deprecated since version 2.1.5\r\n * @todo remove at version 3\r\n * @private\r\n */\r\ncore_controller.pluginService = core_controller.plugins;\r\n\r\n/**\r\n * Provided for backward compatibility, inheriting from Chart.PlugingBase has no\r\n * effect, instead simply create/register plugins via plain JavaScript objects.\r\n * @interface Chart.PluginBase\r\n * @deprecated since version 2.5.0\r\n * @todo remove at version 3\r\n * @private\r\n */\r\ncore_controller.PluginBase = core_controller.Element.extend({});\r\n\r\n/**\r\n * Provided for backward compatibility, use Chart.helpers.canvas instead.\r\n * @namespace Chart.canvasHelpers\r\n * @deprecated since version 2.6.0\r\n * @todo remove at version 3\r\n * @private\r\n */\r\ncore_controller.canvasHelpers = core_controller.helpers.canvas;\r\n\r\n/**\r\n * Provided for backward compatibility, use Chart.layouts instead.\r\n * @namespace Chart.layoutService\r\n * @deprecated since version 2.7.3\r\n * @todo remove at version 3\r\n * @private\r\n */\r\ncore_controller.layoutService = core_controller.layouts;\r\n\r\n/**\r\n * Provided for backward compatibility, not available anymore.\r\n * @namespace Chart.LinearScaleBase\r\n * @deprecated since version 2.8\r\n * @todo remove at version 3\r\n * @private\r\n */\r\ncore_controller.LinearScaleBase = scale_linearbase;\r\n\r\n/**\r\n * Provided for backward compatibility, instead we should create a new Chart\r\n * by setting the type in the config (`new Chart(id, {type: '{chart-type}'}`).\r\n * @deprecated since version 2.8.0\r\n * @todo remove at version 3\r\n */\r\ncore_controller.helpers.each(\r\n\t[\r\n\t\t'Bar',\r\n\t\t'Bubble',\r\n\t\t'Doughnut',\r\n\t\t'Line',\r\n\t\t'PolarArea',\r\n\t\t'Radar',\r\n\t\t'Scatter'\r\n\t],\r\n\tfunction(klass) {\r\n\t\tcore_controller[klass] = function(ctx, cfg) {\r\n\t\t\treturn new core_controller(ctx, core_controller.helpers.merge(cfg || {}, {\r\n\t\t\t\ttype: klass.charAt(0).toLowerCase() + klass.slice(1)\r\n\t\t\t}));\r\n\t\t};\r\n\t}\r\n);\n\nreturn src;\n\n})));\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvZGlzdC9DaGFydC5qcyIsIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQTRELHlDQUF5QyxNQUFNLE9BQU8sbUJBQU8sQ0FBQywrQ0FBUSxLQUFLLGNBQWM7QUFDckosQ0FDZ0U7QUFDaEUsQ0FBQyw0QkFBNEI7O0FBRTdCOztBQUVBO0FBQ0EsbUJBQW1CLGFBQWE7QUFDaEM7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsT0FBTywyQkFBMkI7QUFDbEMsT0FBTywyQkFBMkI7QUFDbEMsT0FBTywyQkFBMkI7QUFDbEMsT0FBTywyQkFBMkI7QUFDbEMsUUFBUSw0QkFBNEI7QUFDcEMsT0FBTywyQkFBMkI7QUFDbEMsT0FBTywyQkFBMkI7QUFDbEMsT0FBTywyQkFBMkI7QUFDbEMsT0FBTyw2QkFBNkI7QUFDcEMsV0FBVyxpQ0FBaUM7QUFDNUMsVUFBVSxnQ0FBZ0M7QUFDMUMsV0FBVyxpQ0FBaUM7QUFDNUMsT0FBTyxxQ0FBcUM7QUFDNUMsU0FBUywyQ0FBMkM7QUFDcEQsUUFBUTtBQUNSOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscURBQXFELGdCQUFnQjtBQUNyRSxtREFBbUQsY0FBYztBQUNqRTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLGlCQUFpQixPQUFPO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQSxJQUFJO0FBQ0o7QUFDQSxJQUFJO0FBQ0o7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSx3QkFBd0I7O0FBRXhCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixPQUFPLFFBQVE7QUFDaEMsaUJBQWlCLE9BQU8sUUFBUTtBQUNoQyxrQkFBa0IsT0FBTyxPQUFPO0FBQ2hDLGtCQUFrQixPQUFPLE9BQU87QUFDaEMsaUJBQWlCLFFBQVEsT0FBTztBQUNoQyxpQkFBaUIsUUFBUSxPQUFPO0FBQ2hDOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVFQUF1RTs7QUFFdkU7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsdUJBQXVCO0FBQ3ZCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLCtDQUErQyxFQUFFLFVBQVUsRUFBRTtBQUM3RDtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsZ0JBQWdCLGFBQWEsYUFBYTtBQUMxQztBQUNBLGdCQUFnQixhQUFhLGFBQWE7QUFDMUM7QUFDQSxnQkFBZ0IsYUFBYSxhQUFhO0FBQzFDO0FBQ0EsZ0JBQWdCLGFBQWEsYUFBYTtBQUMxQztBQUNBLGdCQUFnQixhQUFhLGFBQWE7QUFDMUM7QUFDQSxnQkFBZ0IsYUFBYTtBQUM3Qjs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsc0NBQXNDLFNBQVM7QUFDL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSwwQkFBMEI7O0FBRTFCOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSwwQ0FBMEMsU0FBUztBQUNuRDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxzQ0FBc0MsU0FBUztBQUMvQztBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSxtQ0FBbUM7QUFDbkM7QUFDQTtBQUNBLHdDQUF3QyxTQUFTO0FBQ2pEO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSx3REFBd0QsdUNBQXVDO0FBQy9GLHNEQUFzRCxxQ0FBcUM7O0FBRTNGO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsRUFBRTtBQUNGLENBQUM7O0FBRUQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLCtCQUErQixJQUFJO0FBQ25DLDhCQUE4QixFQUFFLGFBQWEsRUFBRTtBQUMvQztBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBc0IsZ0JBQWdCO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNCQUFzQixnQkFBZ0I7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBc0IsZ0JBQWdCO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBc0IsZ0JBQWdCO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLG1CQUFtQixnQkFBZ0I7QUFDbkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBLElBQUk7QUFDSjtBQUNBLElBQUk7QUFDSjtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQixnQkFBZ0I7QUFDbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQSxrQkFBa0IsT0FBTztBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLGlCQUFpQixrQkFBa0I7QUFDbkM7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNILE1BQU07QUFDTixjQUFjLGtCQUFrQjtBQUNoQztBQUNBOztBQUVBO0FBQ0EsR0FBRztBQUNILE1BQU07QUFDTjs7QUFFQSxjQUFjLGtCQUFrQjtBQUNoQztBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0EsYUFBYSxrQkFBa0I7QUFDL0I7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQSxZQUFZLEdBQUc7QUFDZixjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0EsWUFBWSxHQUFHO0FBQ2YsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0EsWUFBWSxHQUFHO0FBQ2YsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBLFlBQVksR0FBRztBQUNmLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0EsWUFBWSxHQUFHO0FBQ2YsWUFBWSxHQUFHO0FBQ2YsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQSxZQUFZLE9BQU87QUFDbkIsWUFBWSxRQUFRO0FBQ3BCLFlBQVksR0FBRztBQUNmLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLFVBQVU7QUFDdEIsWUFBWSxzQkFBc0I7QUFDbEMsWUFBWSxRQUFRO0FBQ3BCLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLGNBQWM7QUFDMUIsWUFBWSxVQUFVO0FBQ3RCLFlBQVksUUFBUTtBQUNwQixZQUFZLFNBQVM7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0JBQXNCLFFBQVE7QUFDOUI7QUFDQTtBQUNBLEtBQUs7QUFDTCxnQkFBZ0IsU0FBUztBQUN6QjtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBLGVBQWUsU0FBUztBQUN4QjtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLE9BQU87QUFDbkIsWUFBWSxPQUFPO0FBQ25CLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLFVBQVU7QUFDMUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsa0VBQWtFLE1BQU0sSUFBSTtBQUM1RTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBLFlBQVksR0FBRztBQUNmLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVLFVBQVU7QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxRQUFRO0FBQ3BCLFlBQVksaUJBQWlCO0FBQzdCLFlBQVksUUFBUTtBQUNwQixZQUFZLFVBQVU7QUFDdEIsY0FBYyxRQUFRO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYyxVQUFVO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQyxVQUFVO0FBQzdDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLFFBQVE7QUFDcEIsWUFBWSxpQkFBaUI7QUFDN0IsY0FBYyxRQUFRO0FBQ3RCO0FBQ0E7QUFDQSx3Q0FBd0MsMEJBQTBCO0FBQ2xFLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQSxZQUFZLFFBQVE7QUFDcEIsWUFBWSxRQUFRO0FBQ3BCLFlBQVksUUFBUTtBQUNwQixjQUFjLFFBQVE7QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNILEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksT0FBTztBQUNuQjtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLDBCQUEwQjtBQUN0QyxZQUFZLFFBQVE7QUFDcEIsWUFBWSxRQUFRO0FBQ3BCLFlBQVksUUFBUTtBQUNwQixZQUFZLFFBQVE7QUFDcEIsWUFBWSxRQUFRO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0EsWUFBWSxRQUFRO0FBQ3BCLFlBQVksUUFBUTtBQUNwQixjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0Esc0JBQXNCO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0REFBNEQ7QUFDNUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsUUFBUTtBQUNuQixZQUFZLFFBQVE7QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksZUFBZTtBQUMzQixZQUFZLFFBQVE7QUFDcEIsY0FBYyxRQUFRO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0EsWUFBWSxlQUFlO0FBQzNCO0FBQ0EsY0FBYyxRQUFRO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0EsWUFBWSxRQUFRO0FBQ3BCLGFBQWEsUUFBUTtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBLFlBQVksT0FBTztBQUNuQixZQUFZLFFBQVE7QUFDcEI7QUFDQSxZQUFZLFFBQVE7QUFDcEI7QUFDQSxZQUFZLFFBQVE7QUFDcEIsWUFBWSxTQUFTO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9DQUFvQyxVQUFVO0FBQzlDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYyxVQUFVO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0EsNENBQTRDO0FBQzVDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNILDBCQUEwQjtBQUMxQixHQUFHO0FBQ0g7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsR0FBRztBQUNILHdDQUF3QztBQUN4QztBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUNBQWlDLFVBQVU7QUFDM0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQ0FBaUM7QUFDakM7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlDQUFpQztBQUNqQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLE9BQU87QUFDbkIsWUFBWSxpQkFBaUI7QUFDN0IsWUFBWSxRQUFRO0FBQ3BCLFlBQVksU0FBUztBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdDQUF3QyxVQUFVO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVc7QUFDWDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSCxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSCxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtDQUFrQyxVQUFVO0FBQzVDO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNILEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUyxVQUFVO0FBQ25CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUyxVQUFVO0FBQ25CO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLFFBQVE7QUFDcEIsYUFBYSxpQkFBaUI7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EseURBQXlEO0FBQ3pELElBQUk7QUFDSjtBQUNBLCtEQUErRDtBQUMvRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRDQUE0QyxVQUFVO0FBQ3REO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkNBQTZDLFVBQVU7QUFDdkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQSxtQ0FBbUMsVUFBVTtBQUM3QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBLDhEQUE4RDtBQUM5RDtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQ0FBa0MsVUFBVTtBQUM1QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCLFdBQVc7QUFDN0I7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhLHFCQUFxQjtBQUNsQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYSxxQkFBcUI7QUFDbEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0VBQWdFLHFCQUFxQjtBQUNyRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUscUJBQXFCO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFDQUFxQztBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CLHVCQUF1QjtBQUMxQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQkFBa0IsdUJBQXVCO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrREFBa0Q7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLHlCQUF5QjtBQUN4QyxZQUFZLFFBQVE7QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1YsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUMsVUFBVTtBQUM3QztBQUNBO0FBQ0E7QUFDQSw2Q0FBNkMsVUFBVTtBQUN2RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DLFVBQVU7QUFDN0M7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQSxZQUFZLFFBQVE7QUFDcEIsY0FBYyxVQUFVO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLFVBQVU7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0EsWUFBWSxRQUFRO0FBQ3BCLFlBQVksUUFBUTtBQUNwQixjQUFjLFFBQVE7QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0NBQStDLFVBQVU7QUFDekQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFVBQVU7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUyxVQUFVO0FBQ25CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtDQUFrQztBQUNsQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSCxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrQkFBK0I7QUFDL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrQ0FBK0MsVUFBVTtBQUN6RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMERBQTBELFVBQVU7QUFDcEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCLGtCQUFrQjtBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQ0FBa0MsVUFBVTtBQUM1QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0NBQWtDLFVBQVU7QUFDNUM7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQ0FBa0M7QUFDbEMsZ0NBQWdDO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0RBQWtELFVBQVU7QUFDNUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0NBQWtDLFVBQVU7QUFDNUM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQixrQkFBa0I7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9DQUFvQyxVQUFVO0FBQzlDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQ0FBb0MsVUFBVTtBQUM5QztBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsVUFBVTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSixxQ0FBcUMsVUFBVTtBQUMvQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQ0FBcUMsVUFBVTtBQUMvQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUyxVQUFVO0FBQ25CO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRixDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0NBQStDLFVBQVU7QUFDekQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBEQUEwRCxVQUFVO0FBQ3BFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMENBQTBDLFVBQVU7QUFDcEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0NBQWtDLFVBQVU7QUFDNUM7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9DQUFvQyxVQUFVO0FBQzlDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0NBQW9DLFVBQVU7QUFDOUM7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9DQUFvQyxVQUFVO0FBQzlDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQzs7QUFFRDtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNILEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQjtBQUNuQixJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxXQUFXLGNBQWM7QUFDekIsV0FBVyxPQUFPO0FBQ2xCLGFBQWEsUUFBUTtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxPQUFPO0FBQ2xCLFdBQVcsVUFBVTtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUNBQXFDLFVBQVU7QUFDL0M7QUFDQSxzQ0FBc0MsVUFBVTtBQUNoRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsZ0JBQWdCO0FBQzNCLFdBQVcsUUFBUTtBQUNuQixZQUFZLGdCQUFnQjtBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsT0FBTztBQUNsQixXQUFXLFFBQVE7QUFDbkIsV0FBVyxTQUFTO0FBQ3BCLFdBQVcsVUFBVTtBQUNyQixZQUFZLGdCQUFnQjtBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxRQUFRO0FBQ25CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYSxPQUFPO0FBQ3BCLGFBQWEsT0FBTztBQUNwQixhQUFhLHFCQUFxQjtBQUNsQyxjQUFjLGlCQUFpQjtBQUMvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWEsT0FBTztBQUNwQixhQUFhLE9BQU87QUFDcEIsYUFBYSxxQkFBcUI7QUFDbEMsY0FBYyxpQkFBaUI7QUFDL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrQkFBK0IsaUJBQWlCO0FBQ2hELEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYSxPQUFPO0FBQ3BCLGFBQWEsT0FBTztBQUNwQixjQUFjLGlCQUFpQjtBQUMvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWEsT0FBTztBQUNwQixhQUFhLE9BQU87QUFDcEIsYUFBYSxxQkFBcUI7QUFDbEMsY0FBYyxpQkFBaUI7QUFDL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYSxPQUFPO0FBQ3BCLGFBQWEsT0FBTztBQUNwQixhQUFhLHFCQUFxQjtBQUNsQyxjQUFjLGlCQUFpQjtBQUMvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYSxPQUFPO0FBQ3BCLGFBQWEsT0FBTztBQUNwQixhQUFhLHFCQUFxQjtBQUNsQyxjQUFjLGlCQUFpQjtBQUMvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBDQUEwQyxVQUFVO0FBQ3BEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9DQUFvQyxVQUFVO0FBQzlDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQjtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtDQUFrQyxVQUFVO0FBQzVDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0JBQXdCO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0NBQWtDLFVBQVU7QUFDNUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBLFVBQVUsUUFBUTtBQUNsQjtBQUNBLFVBQVUsUUFBUTtBQUNsQixVQUFVLFNBQVM7QUFDbkIsVUFBVSxVQUFVO0FBQ3BCLFVBQVUsVUFBVTtBQUNwQixVQUFVLFVBQVU7QUFDcEIsVUFBVSxRQUFRO0FBQ2xCLFVBQVUsUUFBUTtBQUNsQixVQUFVLFFBQVE7QUFDbEIsVUFBVSxRQUFRO0FBQ2xCLFVBQVUsUUFBUTtBQUNsQixVQUFVLFFBQVE7QUFDbEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxPQUFPO0FBQ25CLFlBQVksYUFBYTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0EsWUFBWSxPQUFPO0FBQ25CLFlBQVksYUFBYTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0EsWUFBWSxPQUFPO0FBQ25CLFlBQVksYUFBYTtBQUN6QixZQUFZLFFBQVE7QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTLFVBQVU7QUFDbkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksT0FBTztBQUNuQixZQUFZLFFBQVE7QUFDcEIsWUFBWSxRQUFRO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0Esd0JBQXdCO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsZ0tBQWdLLGFBQWEsZ0JBQWdCLFdBQVcsYUFBYSxLQUFLLGlDQUFpQyxpREFBaUQsS0FBSyxzTUFBc00seUJBQXlCLHFCQUFxQixjQUFjLGFBQWEsZUFBZSxnQkFBZ0IsdUJBQXVCLDJCQUEyQix5QkFBeUIsa0JBQWtCLEtBQUssNENBQTRDLHlCQUF5Qix1QkFBdUIsd0JBQXdCLGNBQWMsYUFBYSxLQUFLLDRDQUE0Qyx5QkFBeUIsa0JBQWtCLG1CQUFtQixjQUFjLGFBQWEsS0FBSzs7QUFFLzlCO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQ7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhLFFBQVE7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdDQUF3QztBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0EsMkRBQTJELGVBQWU7QUFDMUU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyREFBMkQ7QUFDM0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJEQUEyRDtBQUMzRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLHlCQUF5QjtBQUNwQyxXQUFXLFFBQVE7QUFDbkI7QUFDQTtBQUNBO0FBQ0EsbUVBQW1FO0FBQ25FO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLG1CQUFtQjtBQUMvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLG9DQUFvQztBQUNwQztBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0VBQW9FO0FBQ3BFLHdEQUF3RDtBQUN4RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBCQUEwQjtBQUMxQjtBQUNBO0FBQ0E7QUFDQSw2Q0FBNkMsdUNBQXVDO0FBQ3BGLFlBQVksR0FBRztBQUNmLFlBQVksUUFBUTtBQUNwQixjQUFjLDBCQUEwQjtBQUN4QztBQUNBLDhCQUE4QjtBQUM5QjtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksMEJBQTBCO0FBQ3RDLGNBQWMsU0FBUztBQUN2QjtBQUNBLDhCQUE4QjtBQUM5QjtBQUNBO0FBQ0E7QUFDQSxZQUFZLE9BQU87QUFDbkIsWUFBWSxRQUFRLGFBQWEsYUFBYTtBQUM5QyxZQUFZLFVBQVU7QUFDdEIsU0FBUyxjQUFjO0FBQ3ZCO0FBQ0EsZ0NBQWdDO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBLFlBQVksT0FBTztBQUNuQixZQUFZLFFBQVEsYUFBYSxhQUFhO0FBQzlDLFlBQVksVUFBVTtBQUN0QjtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksbUJBQW1CO0FBQy9CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0EsWUFBWSxtQkFBbUI7QUFDL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBLGNBQWMsV0FBVztBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxPQUFPO0FBQ25CLFlBQVksUUFBUTtBQUNwQixZQUFZLE9BQU87QUFDbkIsY0FBYyxTQUFTO0FBQ3ZCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWMsVUFBVTtBQUN4QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQSxjQUFjLFVBQVUsR0FBRyxpQkFBaUI7QUFDNUM7QUFDQTtBQUNBO0FBQ0Esb0RBQW9EO0FBQ3BEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0osR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUIsZ0JBQWdCO0FBQ3JDLGNBQWMsUUFBUTtBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUNBQXFDLFNBQVM7QUFDOUM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUIsaUJBQWlCO0FBQ3RDLDBCQUEwQixRQUFRO0FBQ2xDLGNBQWMsUUFBUTtBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFDQUFxQyxTQUFTO0FBQzlDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsUUFBUTtBQUNuQixhQUFhLFVBQVU7QUFDdkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlEQUFpRDtBQUNqRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCLFFBQVE7QUFDL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtDQUFrQztBQUNsQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJDQUEyQztBQUMzQywyRUFBMkU7QUFDM0UseURBQXlEO0FBQ3pELDhDQUE4QztBQUM5QyxrRkFBa0Y7QUFDbEYsd0RBQXdEO0FBQ3hELCtDQUErQztBQUMvQyw4RUFBOEU7QUFDOUU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYixlQUFlO0FBQ2YsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQ0FBb0MsU0FBUztBQUM3QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1YsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFlBQVk7QUFDM0I7QUFDQSwwQ0FBMEM7QUFDMUM7QUFDQTtBQUNBLGtEQUFrRDtBQUNsRDtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtDQUFrQyxVQUFVO0FBQzVDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQ0FBb0MsVUFBVTtBQUM5QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1QkFBdUI7QUFDdkIsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLFlBQVk7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxRQUFRO0FBQ3BCLGNBQWMsU0FBUztBQUN2QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsVUFBVTtBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QjtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBc0I7QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBc0I7QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRyxJQUFJO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2IsS0FBSztBQUNMO0FBQ0EsYUFBYTtBQUNiLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNDQUFzQyxVQUFVO0FBQ2hEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSCxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsOENBQThDLFVBQVU7QUFDeEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtEQUFrRCxVQUFVO0FBQzVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0Esa0NBQWtDLHVCQUF1QjtBQUN6RDtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLHVDQUF1QztBQUNyRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTLG1CQUFtQjtBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwREFBMEQsVUFBVTtBQUNwRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQ0FBc0MsVUFBVTtBQUNoRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0MsUUFBUTtBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQSxnREFBZ0QsZ0JBQWdCO0FBQ2hFLEVBQUU7QUFDRjtBQUNBO0FBQ0Esb0RBQW9ELGdCQUFnQjtBQUNwRSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0Esa0RBQWtELGdCQUFnQjtBQUNsRSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBLG9EQUFvRCxVQUFVO0FBQzlEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDhDQUE4QyxVQUFVO0FBQ3hEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNILEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0NBQXNDLFVBQVU7QUFDaEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksUUFBUTtBQUNwQixhQUFhLFNBQVM7QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBLHdDQUF3QyxVQUFVO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrQkFBK0IsMEJBQTBCO0FBQ3pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwrQkFBK0IsUUFBUTtBQUN2QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQSxXQUFXO0FBQ1g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxRQUFRO0FBQ3BCLGNBQWMsUUFBUTtBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwyQkFBMkI7QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksT0FBTztBQUNuQixZQUFZLFFBQVE7QUFDcEIsWUFBWSxRQUFRO0FBQ3BCLGNBQWMsUUFBUTtBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9CQUFvQjtBQUNwQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLGVBQWU7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQSxLQUFLO0FBQ0w7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYyxtQkFBbUI7QUFDakM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLGVBQWU7QUFDN0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQSxLQUFLO0FBQ0w7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBLElBQUk7QUFDSjtBQUNBLElBQUk7QUFDSjtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLGFBQWE7QUFDekIsWUFBWSxRQUFRO0FBQ3BCLFlBQVksUUFBUTtBQUNwQixVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLFVBQVU7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EscUNBQXFDLFVBQVU7QUFDL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsV0FBVztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWU7QUFDZjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxLQUFLO0FBQ2pCLFlBQVksUUFBUTtBQUNwQixjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxRQUFRO0FBQ3BCLFlBQVksUUFBUTtBQUNwQixhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxRQUFRO0FBQ3BCLFlBQVksUUFBUTtBQUNwQixZQUFZLE1BQU07QUFDbEIsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksUUFBUTtBQUNwQixZQUFZLFFBQVE7QUFDcEIsWUFBWSxNQUFNO0FBQ2xCLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLFFBQVE7QUFDcEIsWUFBWSxNQUFNO0FBQ2xCLFlBQVksUUFBUTtBQUNwQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVksUUFBUTtBQUNwQixZQUFZLE1BQU07QUFDbEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYyxpQkFBaUI7QUFDL0I7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCLFFBQVE7QUFDL0IsbUJBQW1CLFFBQVE7QUFDM0IsbUJBQW1CLFVBQVU7QUFDN0IsY0FBYyxRQUFRO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBCQUEwQixnQ0FBZ0M7QUFDMUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQSx5REFBeUQ7QUFDekQ7QUFDQTtBQUNBLEtBQUs7QUFDTCxzQkFBc0I7QUFDdEI7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVc7QUFDWDtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRLFNBQVM7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsV0FBVztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQSxZQUFZLHVCQUF1QjtBQUNuQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYSxZQUFZO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBLHNEQUFzRCxRQUFRO0FBQzlEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBLG9DQUFvQyxVQUFVO0FBQzlDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkNBQTZDLGFBQWE7QUFDMUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0QkFBNEIsU0FBUztBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdDQUF3QyxVQUFVO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQ0FBa0MsVUFBVTtBQUM1QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWEsa0JBQWtCO0FBQy9CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsOEJBQThCLFNBQVM7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWMsU0FBUztBQUN2QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBLHFDQUFxQyxhQUFhO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0EsWUFBWSxRQUFRO0FBQ3BCLFlBQVksUUFBUTtBQUNwQixZQUFZLFFBQVE7QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1RkFBdUY7QUFDdkY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUNBQXVDLFVBQVU7QUFDakQ7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVCQUF1QjtBQUN2QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtDQUFrQztBQUNsQyxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9DQUFvQztBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNEVBQTRFO0FBQzVFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DLFVBQVU7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJDQUEyQyxVQUFVO0FBQ3JEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpREFBaUQsVUFBVTtBQUMzRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLGlCQUFpQjtBQUMvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUMsVUFBVTtBQUM3QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQyxVQUFVO0FBQzdDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DLFVBQVU7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUNBQXFDLFVBQVU7QUFDL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlDQUF5QztBQUN6QztBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1Q0FBdUM7QUFDdkM7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNILEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWEsVUFBVTtBQUN2QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixlQUFlO0FBQ2hDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYSxVQUFVO0FBQ3ZCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWEsVUFBVTtBQUN2QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZUFBZSx3QkFBd0I7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWMsVUFBVTtBQUN4QjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYSxVQUFVO0FBQ3ZCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMEJBQTBCLGdDQUFnQztBQUMxRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwQkFBMEIsZ0NBQWdDO0FBQzFEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQ0FBcUMsVUFBVTtBQUMvQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBLElBQUk7QUFDSiwwQkFBMEIsZ0NBQWdDO0FBQzFEO0FBQ0E7QUFDQTtBQUNBLHFDQUFxQyxVQUFVO0FBQy9DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQSxZQUFZLFFBQVE7QUFDcEIsYUFBYSxRQUFRO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWEsZ0JBQWdCO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQ0FBa0MsVUFBVTtBQUM1QztBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtEQUFrRCxRQUFRO0FBQzFEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQkFBa0IsZ0JBQWdCO0FBQ2xDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZDQUE2QyxRQUFRO0FBQ3JEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQ0FBa0MsVUFBVTtBQUM1QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdCQUF3QixXQUFXO0FBQ25DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsVUFBVTtBQUNyQixXQUFXLFFBQVE7QUFDbkIseUVBQXlFLFFBQVEsS0FBSyxPQUFPO0FBQzdGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxrQkFBa0I7QUFDdEIsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUNBQXVDLFVBQVU7QUFDakQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtDQUFrQyxVQUFVO0FBQzVDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGVBQWUsZ0NBQWdDO0FBQy9DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVztBQUNYLElBQUk7QUFDSjtBQUNBLElBQUk7QUFDSjtBQUNBLElBQUk7QUFDSixXQUFXO0FBQ1g7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtDQUFrQyxjQUFjO0FBQ2hEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSw0QkFBNEIsNkJBQTZCO0FBQ3pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNERBQTRELFVBQVU7QUFDdEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLFlBQVk7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdFQUFnRTtBQUNoRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUIsZUFBZTtBQUNwQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYSxVQUFVO0FBQ3ZCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNFQUFzRSxPQUFPO0FBQzdFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0NBQStDO0FBQy9DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdDQUF3QyxVQUFVO0FBQ2xEO0FBQ0E7QUFDQTtBQUNBLHlEQUF5RCxVQUFVO0FBQ25FO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUNBQXFDLFVBQVU7QUFDL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esd0NBQXdDLFVBQVU7QUFDbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUNBQW1DLFVBQVU7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRixFQUFFLElBQUk7O0FBRU47QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhLFlBQVk7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYSxVQUFVO0FBQ3ZCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCLE9BQU87QUFDNUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CLE9BQU87QUFDM0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkJBQTJCLFVBQVU7QUFDckM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjLFdBQVc7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWMsV0FBVztBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLFFBQVE7QUFDeEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNDQUFzQyxVQUFVO0FBQ2hEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7QUFDQTtBQUNBLFdBQVcsUUFBUTtBQUNuQixXQUFXLFFBQVE7QUFDbkIsWUFBWSxRQUFRO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUZBQXVGO0FBQ3ZGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQztBQUNoQztBQUNBLElBQUk7QUFDSjtBQUNBLGtDQUFrQztBQUNsQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHlDQUF5QztBQUN6QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsK0JBQStCO0FBQy9CLDZCQUE2QjtBQUM3QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLGVBQWU7QUFDOUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLFFBQVE7QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVGQUF1RjtBQUN2RjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1HQUFtRztBQUNuRztBQUNBO0FBQ0E7QUFDQTtBQUNBLHlDQUF5QztBQUN6QztBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixpQkFBaUI7QUFDcEM7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsOERBQThEO0FBQzlEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNEQUFzRCxRQUFRLFdBQVcsRUFBRTtBQUMzRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwRUFBMEU7QUFDMUU7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBOztBQUVBOztBQUVBLENBQUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvY2hhcnQuanMvZGlzdC9DaGFydC5qcz80NzNlIl0sInNvdXJjZXNDb250ZW50IjpbIi8qIVxuICogQ2hhcnQuanMgdjIuOS40XG4gKiBodHRwczovL3d3dy5jaGFydGpzLm9yZ1xuICogKGMpIDIwMjAgQ2hhcnQuanMgQ29udHJpYnV0b3JzXG4gKiBSZWxlYXNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2VcbiAqL1xuKGZ1bmN0aW9uIChnbG9iYWwsIGZhY3RvcnkpIHtcbnR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgbW9kdWxlICE9PSAndW5kZWZpbmVkJyA/IG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeShmdW5jdGlvbigpIHsgdHJ5IHsgcmV0dXJuIHJlcXVpcmUoJ21vbWVudCcpOyB9IGNhdGNoKGUpIHsgfSB9KCkpIDpcbnR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCA/IGRlZmluZShbJ3JlcXVpcmUnXSwgZnVuY3Rpb24ocmVxdWlyZSkgeyByZXR1cm4gZmFjdG9yeShmdW5jdGlvbigpIHsgdHJ5IHsgcmV0dXJuIHJlcXVpcmUoJ21vbWVudCcpOyB9IGNhdGNoKGUpIHsgfSB9KCkpOyB9KSA6XG4oZ2xvYmFsID0gZ2xvYmFsIHx8IHNlbGYsIGdsb2JhbC5DaGFydCA9IGZhY3RvcnkoZ2xvYmFsLm1vbWVudCkpO1xufSh0aGlzLCAoZnVuY3Rpb24gKG1vbWVudCkgeyAndXNlIHN0cmljdCc7XG5cbm1vbWVudCA9IG1vbWVudCAmJiBtb21lbnQuaGFzT3duUHJvcGVydHkoJ2RlZmF1bHQnKSA/IG1vbWVudFsnZGVmYXVsdCddIDogbW9tZW50O1xuXG5mdW5jdGlvbiBjcmVhdGVDb21tb25qc01vZHVsZShmbiwgbW9kdWxlKSB7XG5cdHJldHVybiBtb2R1bGUgPSB7IGV4cG9ydHM6IHt9IH0sIGZuKG1vZHVsZSwgbW9kdWxlLmV4cG9ydHMpLCBtb2R1bGUuZXhwb3J0cztcbn1cblxuZnVuY3Rpb24gZ2V0Q2pzRXhwb3J0RnJvbU5hbWVzcGFjZSAobikge1xuXHRyZXR1cm4gbiAmJiBuWydkZWZhdWx0J10gfHwgbjtcbn1cblxudmFyIGNvbG9yTmFtZSA9IHtcclxuXHRcImFsaWNlYmx1ZVwiOiBbMjQwLCAyNDgsIDI1NV0sXHJcblx0XCJhbnRpcXVld2hpdGVcIjogWzI1MCwgMjM1LCAyMTVdLFxyXG5cdFwiYXF1YVwiOiBbMCwgMjU1LCAyNTVdLFxyXG5cdFwiYXF1YW1hcmluZVwiOiBbMTI3LCAyNTUsIDIxMl0sXHJcblx0XCJhenVyZVwiOiBbMjQwLCAyNTUsIDI1NV0sXHJcblx0XCJiZWlnZVwiOiBbMjQ1LCAyNDUsIDIyMF0sXHJcblx0XCJiaXNxdWVcIjogWzI1NSwgMjI4LCAxOTZdLFxyXG5cdFwiYmxhY2tcIjogWzAsIDAsIDBdLFxyXG5cdFwiYmxhbmNoZWRhbG1vbmRcIjogWzI1NSwgMjM1LCAyMDVdLFxyXG5cdFwiYmx1ZVwiOiBbMCwgMCwgMjU1XSxcclxuXHRcImJsdWV2aW9sZXRcIjogWzEzOCwgNDMsIDIyNl0sXHJcblx0XCJicm93blwiOiBbMTY1LCA0MiwgNDJdLFxyXG5cdFwiYnVybHl3b29kXCI6IFsyMjIsIDE4NCwgMTM1XSxcclxuXHRcImNhZGV0Ymx1ZVwiOiBbOTUsIDE1OCwgMTYwXSxcclxuXHRcImNoYXJ0cmV1c2VcIjogWzEyNywgMjU1LCAwXSxcclxuXHRcImNob2NvbGF0ZVwiOiBbMjEwLCAxMDUsIDMwXSxcclxuXHRcImNvcmFsXCI6IFsyNTUsIDEyNywgODBdLFxyXG5cdFwiY29ybmZsb3dlcmJsdWVcIjogWzEwMCwgMTQ5LCAyMzddLFxyXG5cdFwiY29ybnNpbGtcIjogWzI1NSwgMjQ4LCAyMjBdLFxyXG5cdFwiY3JpbXNvblwiOiBbMjIwLCAyMCwgNjBdLFxyXG5cdFwiY3lhblwiOiBbMCwgMjU1LCAyNTVdLFxyXG5cdFwiZGFya2JsdWVcIjogWzAsIDAsIDEzOV0sXHJcblx0XCJkYXJrY3lhblwiOiBbMCwgMTM5LCAxMzldLFxyXG5cdFwiZGFya2dvbGRlbnJvZFwiOiBbMTg0LCAxMzQsIDExXSxcclxuXHRcImRhcmtncmF5XCI6IFsxNjksIDE2OSwgMTY5XSxcclxuXHRcImRhcmtncmVlblwiOiBbMCwgMTAwLCAwXSxcclxuXHRcImRhcmtncmV5XCI6IFsxNjksIDE2OSwgMTY5XSxcclxuXHRcImRhcmtraGFraVwiOiBbMTg5LCAxODMsIDEwN10sXHJcblx0XCJkYXJrbWFnZW50YVwiOiBbMTM5LCAwLCAxMzldLFxyXG5cdFwiZGFya29saXZlZ3JlZW5cIjogWzg1LCAxMDcsIDQ3XSxcclxuXHRcImRhcmtvcmFuZ2VcIjogWzI1NSwgMTQwLCAwXSxcclxuXHRcImRhcmtvcmNoaWRcIjogWzE1MywgNTAsIDIwNF0sXHJcblx0XCJkYXJrcmVkXCI6IFsxMzksIDAsIDBdLFxyXG5cdFwiZGFya3NhbG1vblwiOiBbMjMzLCAxNTAsIDEyMl0sXHJcblx0XCJkYXJrc2VhZ3JlZW5cIjogWzE0MywgMTg4LCAxNDNdLFxyXG5cdFwiZGFya3NsYXRlYmx1ZVwiOiBbNzIsIDYxLCAxMzldLFxyXG5cdFwiZGFya3NsYXRlZ3JheVwiOiBbNDcsIDc5LCA3OV0sXHJcblx0XCJkYXJrc2xhdGVncmV5XCI6IFs0NywgNzksIDc5XSxcclxuXHRcImRhcmt0dXJxdW9pc2VcIjogWzAsIDIwNiwgMjA5XSxcclxuXHRcImRhcmt2aW9sZXRcIjogWzE0OCwgMCwgMjExXSxcclxuXHRcImRlZXBwaW5rXCI6IFsyNTUsIDIwLCAxNDddLFxyXG5cdFwiZGVlcHNreWJsdWVcIjogWzAsIDE5MSwgMjU1XSxcclxuXHRcImRpbWdyYXlcIjogWzEwNSwgMTA1LCAxMDVdLFxyXG5cdFwiZGltZ3JleVwiOiBbMTA1LCAxMDUsIDEwNV0sXHJcblx0XCJkb2RnZXJibHVlXCI6IFszMCwgMTQ0LCAyNTVdLFxyXG5cdFwiZmlyZWJyaWNrXCI6IFsxNzgsIDM0LCAzNF0sXHJcblx0XCJmbG9yYWx3aGl0ZVwiOiBbMjU1LCAyNTAsIDI0MF0sXHJcblx0XCJmb3Jlc3RncmVlblwiOiBbMzQsIDEzOSwgMzRdLFxyXG5cdFwiZnVjaHNpYVwiOiBbMjU1LCAwLCAyNTVdLFxyXG5cdFwiZ2FpbnNib3JvXCI6IFsyMjAsIDIyMCwgMjIwXSxcclxuXHRcImdob3N0d2hpdGVcIjogWzI0OCwgMjQ4LCAyNTVdLFxyXG5cdFwiZ29sZFwiOiBbMjU1LCAyMTUsIDBdLFxyXG5cdFwiZ29sZGVucm9kXCI6IFsyMTgsIDE2NSwgMzJdLFxyXG5cdFwiZ3JheVwiOiBbMTI4LCAxMjgsIDEyOF0sXHJcblx0XCJncmVlblwiOiBbMCwgMTI4LCAwXSxcclxuXHRcImdyZWVueWVsbG93XCI6IFsxNzMsIDI1NSwgNDddLFxyXG5cdFwiZ3JleVwiOiBbMTI4LCAxMjgsIDEyOF0sXHJcblx0XCJob25leWRld1wiOiBbMjQwLCAyNTUsIDI0MF0sXHJcblx0XCJob3RwaW5rXCI6IFsyNTUsIDEwNSwgMTgwXSxcclxuXHRcImluZGlhbnJlZFwiOiBbMjA1LCA5MiwgOTJdLFxyXG5cdFwiaW5kaWdvXCI6IFs3NSwgMCwgMTMwXSxcclxuXHRcIml2b3J5XCI6IFsyNTUsIDI1NSwgMjQwXSxcclxuXHRcImtoYWtpXCI6IFsyNDAsIDIzMCwgMTQwXSxcclxuXHRcImxhdmVuZGVyXCI6IFsyMzAsIDIzMCwgMjUwXSxcclxuXHRcImxhdmVuZGVyYmx1c2hcIjogWzI1NSwgMjQwLCAyNDVdLFxyXG5cdFwibGF3bmdyZWVuXCI6IFsxMjQsIDI1MiwgMF0sXHJcblx0XCJsZW1vbmNoaWZmb25cIjogWzI1NSwgMjUwLCAyMDVdLFxyXG5cdFwibGlnaHRibHVlXCI6IFsxNzMsIDIxNiwgMjMwXSxcclxuXHRcImxpZ2h0Y29yYWxcIjogWzI0MCwgMTI4LCAxMjhdLFxyXG5cdFwibGlnaHRjeWFuXCI6IFsyMjQsIDI1NSwgMjU1XSxcclxuXHRcImxpZ2h0Z29sZGVucm9keWVsbG93XCI6IFsyNTAsIDI1MCwgMjEwXSxcclxuXHRcImxpZ2h0Z3JheVwiOiBbMjExLCAyMTEsIDIxMV0sXHJcblx0XCJsaWdodGdyZWVuXCI6IFsxNDQsIDIzOCwgMTQ0XSxcclxuXHRcImxpZ2h0Z3JleVwiOiBbMjExLCAyMTEsIDIxMV0sXHJcblx0XCJsaWdodHBpbmtcIjogWzI1NSwgMTgyLCAxOTNdLFxyXG5cdFwibGlnaHRzYWxtb25cIjogWzI1NSwgMTYwLCAxMjJdLFxyXG5cdFwibGlnaHRzZWFncmVlblwiOiBbMzIsIDE3OCwgMTcwXSxcclxuXHRcImxpZ2h0c2t5Ymx1ZVwiOiBbMTM1LCAyMDYsIDI1MF0sXHJcblx0XCJsaWdodHNsYXRlZ3JheVwiOiBbMTE5LCAxMzYsIDE1M10sXHJcblx0XCJsaWdodHNsYXRlZ3JleVwiOiBbMTE5LCAxMzYsIDE1M10sXHJcblx0XCJsaWdodHN0ZWVsYmx1ZVwiOiBbMTc2LCAxOTYsIDIyMl0sXHJcblx0XCJsaWdodHllbGxvd1wiOiBbMjU1LCAyNTUsIDIyNF0sXHJcblx0XCJsaW1lXCI6IFswLCAyNTUsIDBdLFxyXG5cdFwibGltZWdyZWVuXCI6IFs1MCwgMjA1LCA1MF0sXHJcblx0XCJsaW5lblwiOiBbMjUwLCAyNDAsIDIzMF0sXHJcblx0XCJtYWdlbnRhXCI6IFsyNTUsIDAsIDI1NV0sXHJcblx0XCJtYXJvb25cIjogWzEyOCwgMCwgMF0sXHJcblx0XCJtZWRpdW1hcXVhbWFyaW5lXCI6IFsxMDIsIDIwNSwgMTcwXSxcclxuXHRcIm1lZGl1bWJsdWVcIjogWzAsIDAsIDIwNV0sXHJcblx0XCJtZWRpdW1vcmNoaWRcIjogWzE4NiwgODUsIDIxMV0sXHJcblx0XCJtZWRpdW1wdXJwbGVcIjogWzE0NywgMTEyLCAyMTldLFxyXG5cdFwibWVkaXVtc2VhZ3JlZW5cIjogWzYwLCAxNzksIDExM10sXHJcblx0XCJtZWRpdW1zbGF0ZWJsdWVcIjogWzEyMywgMTA0LCAyMzhdLFxyXG5cdFwibWVkaXVtc3ByaW5nZ3JlZW5cIjogWzAsIDI1MCwgMTU0XSxcclxuXHRcIm1lZGl1bXR1cnF1b2lzZVwiOiBbNzIsIDIwOSwgMjA0XSxcclxuXHRcIm1lZGl1bXZpb2xldHJlZFwiOiBbMTk5LCAyMSwgMTMzXSxcclxuXHRcIm1pZG5pZ2h0Ymx1ZVwiOiBbMjUsIDI1LCAxMTJdLFxyXG5cdFwibWludGNyZWFtXCI6IFsyNDUsIDI1NSwgMjUwXSxcclxuXHRcIm1pc3R5cm9zZVwiOiBbMjU1LCAyMjgsIDIyNV0sXHJcblx0XCJtb2NjYXNpblwiOiBbMjU1LCAyMjgsIDE4MV0sXHJcblx0XCJuYXZham93aGl0ZVwiOiBbMjU1LCAyMjIsIDE3M10sXHJcblx0XCJuYXZ5XCI6IFswLCAwLCAxMjhdLFxyXG5cdFwib2xkbGFjZVwiOiBbMjUzLCAyNDUsIDIzMF0sXHJcblx0XCJvbGl2ZVwiOiBbMTI4LCAxMjgsIDBdLFxyXG5cdFwib2xpdmVkcmFiXCI6IFsxMDcsIDE0MiwgMzVdLFxyXG5cdFwib3JhbmdlXCI6IFsyNTUsIDE2NSwgMF0sXHJcblx0XCJvcmFuZ2VyZWRcIjogWzI1NSwgNjksIDBdLFxyXG5cdFwib3JjaGlkXCI6IFsyMTgsIDExMiwgMjE0XSxcclxuXHRcInBhbGVnb2xkZW5yb2RcIjogWzIzOCwgMjMyLCAxNzBdLFxyXG5cdFwicGFsZWdyZWVuXCI6IFsxNTIsIDI1MSwgMTUyXSxcclxuXHRcInBhbGV0dXJxdW9pc2VcIjogWzE3NSwgMjM4LCAyMzhdLFxyXG5cdFwicGFsZXZpb2xldHJlZFwiOiBbMjE5LCAxMTIsIDE0N10sXHJcblx0XCJwYXBheWF3aGlwXCI6IFsyNTUsIDIzOSwgMjEzXSxcclxuXHRcInBlYWNocHVmZlwiOiBbMjU1LCAyMTgsIDE4NV0sXHJcblx0XCJwZXJ1XCI6IFsyMDUsIDEzMywgNjNdLFxyXG5cdFwicGlua1wiOiBbMjU1LCAxOTIsIDIwM10sXHJcblx0XCJwbHVtXCI6IFsyMjEsIDE2MCwgMjIxXSxcclxuXHRcInBvd2RlcmJsdWVcIjogWzE3NiwgMjI0LCAyMzBdLFxyXG5cdFwicHVycGxlXCI6IFsxMjgsIDAsIDEyOF0sXHJcblx0XCJyZWJlY2NhcHVycGxlXCI6IFsxMDIsIDUxLCAxNTNdLFxyXG5cdFwicmVkXCI6IFsyNTUsIDAsIDBdLFxyXG5cdFwicm9zeWJyb3duXCI6IFsxODgsIDE0MywgMTQzXSxcclxuXHRcInJveWFsYmx1ZVwiOiBbNjUsIDEwNSwgMjI1XSxcclxuXHRcInNhZGRsZWJyb3duXCI6IFsxMzksIDY5LCAxOV0sXHJcblx0XCJzYWxtb25cIjogWzI1MCwgMTI4LCAxMTRdLFxyXG5cdFwic2FuZHlicm93blwiOiBbMjQ0LCAxNjQsIDk2XSxcclxuXHRcInNlYWdyZWVuXCI6IFs0NiwgMTM5LCA4N10sXHJcblx0XCJzZWFzaGVsbFwiOiBbMjU1LCAyNDUsIDIzOF0sXHJcblx0XCJzaWVubmFcIjogWzE2MCwgODIsIDQ1XSxcclxuXHRcInNpbHZlclwiOiBbMTkyLCAxOTIsIDE5Ml0sXHJcblx0XCJza3libHVlXCI6IFsxMzUsIDIwNiwgMjM1XSxcclxuXHRcInNsYXRlYmx1ZVwiOiBbMTA2LCA5MCwgMjA1XSxcclxuXHRcInNsYXRlZ3JheVwiOiBbMTEyLCAxMjgsIDE0NF0sXHJcblx0XCJzbGF0ZWdyZXlcIjogWzExMiwgMTI4LCAxNDRdLFxyXG5cdFwic25vd1wiOiBbMjU1LCAyNTAsIDI1MF0sXHJcblx0XCJzcHJpbmdncmVlblwiOiBbMCwgMjU1LCAxMjddLFxyXG5cdFwic3RlZWxibHVlXCI6IFs3MCwgMTMwLCAxODBdLFxyXG5cdFwidGFuXCI6IFsyMTAsIDE4MCwgMTQwXSxcclxuXHRcInRlYWxcIjogWzAsIDEyOCwgMTI4XSxcclxuXHRcInRoaXN0bGVcIjogWzIxNiwgMTkxLCAyMTZdLFxyXG5cdFwidG9tYXRvXCI6IFsyNTUsIDk5LCA3MV0sXHJcblx0XCJ0dXJxdW9pc2VcIjogWzY0LCAyMjQsIDIwOF0sXHJcblx0XCJ2aW9sZXRcIjogWzIzOCwgMTMwLCAyMzhdLFxyXG5cdFwid2hlYXRcIjogWzI0NSwgMjIyLCAxNzldLFxyXG5cdFwid2hpdGVcIjogWzI1NSwgMjU1LCAyNTVdLFxyXG5cdFwid2hpdGVzbW9rZVwiOiBbMjQ1LCAyNDUsIDI0NV0sXHJcblx0XCJ5ZWxsb3dcIjogWzI1NSwgMjU1LCAwXSxcclxuXHRcInllbGxvd2dyZWVuXCI6IFsxNTQsIDIwNSwgNTBdXHJcbn07XG5cbnZhciBjb252ZXJzaW9ucyA9IGNyZWF0ZUNvbW1vbmpzTW9kdWxlKGZ1bmN0aW9uIChtb2R1bGUpIHtcbi8qIE1JVCBsaWNlbnNlICovXG5cblxuLy8gTk9URTogY29udmVyc2lvbnMgc2hvdWxkIG9ubHkgcmV0dXJuIHByaW1pdGl2ZSB2YWx1ZXMgKGkuZS4gYXJyYXlzLCBvclxuLy8gICAgICAgdmFsdWVzIHRoYXQgZ2l2ZSBjb3JyZWN0IGB0eXBlb2ZgIHJlc3VsdHMpLlxuLy8gICAgICAgZG8gbm90IHVzZSBib3ggdmFsdWVzIHR5cGVzIChpLmUuIE51bWJlcigpLCBTdHJpbmcoKSwgZXRjLilcblxudmFyIHJldmVyc2VLZXl3b3JkcyA9IHt9O1xuZm9yICh2YXIga2V5IGluIGNvbG9yTmFtZSkge1xuXHRpZiAoY29sb3JOYW1lLmhhc093blByb3BlcnR5KGtleSkpIHtcblx0XHRyZXZlcnNlS2V5d29yZHNbY29sb3JOYW1lW2tleV1dID0ga2V5O1xuXHR9XG59XG5cbnZhciBjb252ZXJ0ID0gbW9kdWxlLmV4cG9ydHMgPSB7XG5cdHJnYjoge2NoYW5uZWxzOiAzLCBsYWJlbHM6ICdyZ2InfSxcblx0aHNsOiB7Y2hhbm5lbHM6IDMsIGxhYmVsczogJ2hzbCd9LFxuXHRoc3Y6IHtjaGFubmVsczogMywgbGFiZWxzOiAnaHN2J30sXG5cdGh3Yjoge2NoYW5uZWxzOiAzLCBsYWJlbHM6ICdod2InfSxcblx0Y215azoge2NoYW5uZWxzOiA0LCBsYWJlbHM6ICdjbXlrJ30sXG5cdHh5ejoge2NoYW5uZWxzOiAzLCBsYWJlbHM6ICd4eXonfSxcblx0bGFiOiB7Y2hhbm5lbHM6IDMsIGxhYmVsczogJ2xhYid9LFxuXHRsY2g6IHtjaGFubmVsczogMywgbGFiZWxzOiAnbGNoJ30sXG5cdGhleDoge2NoYW5uZWxzOiAxLCBsYWJlbHM6IFsnaGV4J119LFxuXHRrZXl3b3JkOiB7Y2hhbm5lbHM6IDEsIGxhYmVsczogWydrZXl3b3JkJ119LFxuXHRhbnNpMTY6IHtjaGFubmVsczogMSwgbGFiZWxzOiBbJ2Fuc2kxNiddfSxcblx0YW5zaTI1Njoge2NoYW5uZWxzOiAxLCBsYWJlbHM6IFsnYW5zaTI1NiddfSxcblx0aGNnOiB7Y2hhbm5lbHM6IDMsIGxhYmVsczogWydoJywgJ2MnLCAnZyddfSxcblx0YXBwbGU6IHtjaGFubmVsczogMywgbGFiZWxzOiBbJ3IxNicsICdnMTYnLCAnYjE2J119LFxuXHRncmF5OiB7Y2hhbm5lbHM6IDEsIGxhYmVsczogWydncmF5J119XG59O1xuXG4vLyBoaWRlIC5jaGFubmVscyBhbmQgLmxhYmVscyBwcm9wZXJ0aWVzXG5mb3IgKHZhciBtb2RlbCBpbiBjb252ZXJ0KSB7XG5cdGlmIChjb252ZXJ0Lmhhc093blByb3BlcnR5KG1vZGVsKSkge1xuXHRcdGlmICghKCdjaGFubmVscycgaW4gY29udmVydFttb2RlbF0pKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgY2hhbm5lbHMgcHJvcGVydHk6ICcgKyBtb2RlbCk7XG5cdFx0fVxuXG5cdFx0aWYgKCEoJ2xhYmVscycgaW4gY29udmVydFttb2RlbF0pKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoJ21pc3NpbmcgY2hhbm5lbCBsYWJlbHMgcHJvcGVydHk6ICcgKyBtb2RlbCk7XG5cdFx0fVxuXG5cdFx0aWYgKGNvbnZlcnRbbW9kZWxdLmxhYmVscy5sZW5ndGggIT09IGNvbnZlcnRbbW9kZWxdLmNoYW5uZWxzKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoJ2NoYW5uZWwgYW5kIGxhYmVsIGNvdW50cyBtaXNtYXRjaDogJyArIG1vZGVsKTtcblx0XHR9XG5cblx0XHR2YXIgY2hhbm5lbHMgPSBjb252ZXJ0W21vZGVsXS5jaGFubmVscztcblx0XHR2YXIgbGFiZWxzID0gY29udmVydFttb2RlbF0ubGFiZWxzO1xuXHRcdGRlbGV0ZSBjb252ZXJ0W21vZGVsXS5jaGFubmVscztcblx0XHRkZWxldGUgY29udmVydFttb2RlbF0ubGFiZWxzO1xuXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjb252ZXJ0W21vZGVsXSwgJ2NoYW5uZWxzJywge3ZhbHVlOiBjaGFubmVsc30pO1xuXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjb252ZXJ0W21vZGVsXSwgJ2xhYmVscycsIHt2YWx1ZTogbGFiZWxzfSk7XG5cdH1cbn1cblxuY29udmVydC5yZ2IuaHNsID0gZnVuY3Rpb24gKHJnYikge1xuXHR2YXIgciA9IHJnYlswXSAvIDI1NTtcblx0dmFyIGcgPSByZ2JbMV0gLyAyNTU7XG5cdHZhciBiID0gcmdiWzJdIC8gMjU1O1xuXHR2YXIgbWluID0gTWF0aC5taW4ociwgZywgYik7XG5cdHZhciBtYXggPSBNYXRoLm1heChyLCBnLCBiKTtcblx0dmFyIGRlbHRhID0gbWF4IC0gbWluO1xuXHR2YXIgaDtcblx0dmFyIHM7XG5cdHZhciBsO1xuXG5cdGlmIChtYXggPT09IG1pbikge1xuXHRcdGggPSAwO1xuXHR9IGVsc2UgaWYgKHIgPT09IG1heCkge1xuXHRcdGggPSAoZyAtIGIpIC8gZGVsdGE7XG5cdH0gZWxzZSBpZiAoZyA9PT0gbWF4KSB7XG5cdFx0aCA9IDIgKyAoYiAtIHIpIC8gZGVsdGE7XG5cdH0gZWxzZSBpZiAoYiA9PT0gbWF4KSB7XG5cdFx0aCA9IDQgKyAociAtIGcpIC8gZGVsdGE7XG5cdH1cblxuXHRoID0gTWF0aC5taW4oaCAqIDYwLCAzNjApO1xuXG5cdGlmIChoIDwgMCkge1xuXHRcdGggKz0gMzYwO1xuXHR9XG5cblx0bCA9IChtaW4gKyBtYXgpIC8gMjtcblxuXHRpZiAobWF4ID09PSBtaW4pIHtcblx0XHRzID0gMDtcblx0fSBlbHNlIGlmIChsIDw9IDAuNSkge1xuXHRcdHMgPSBkZWx0YSAvIChtYXggKyBtaW4pO1xuXHR9IGVsc2Uge1xuXHRcdHMgPSBkZWx0YSAvICgyIC0gbWF4IC0gbWluKTtcblx0fVxuXG5cdHJldHVybiBbaCwgcyAqIDEwMCwgbCAqIDEwMF07XG59O1xuXG5jb252ZXJ0LnJnYi5oc3YgPSBmdW5jdGlvbiAocmdiKSB7XG5cdHZhciByZGlmO1xuXHR2YXIgZ2RpZjtcblx0dmFyIGJkaWY7XG5cdHZhciBoO1xuXHR2YXIgcztcblxuXHR2YXIgciA9IHJnYlswXSAvIDI1NTtcblx0dmFyIGcgPSByZ2JbMV0gLyAyNTU7XG5cdHZhciBiID0gcmdiWzJdIC8gMjU1O1xuXHR2YXIgdiA9IE1hdGgubWF4KHIsIGcsIGIpO1xuXHR2YXIgZGlmZiA9IHYgLSBNYXRoLm1pbihyLCBnLCBiKTtcblx0dmFyIGRpZmZjID0gZnVuY3Rpb24gKGMpIHtcblx0XHRyZXR1cm4gKHYgLSBjKSAvIDYgLyBkaWZmICsgMSAvIDI7XG5cdH07XG5cblx0aWYgKGRpZmYgPT09IDApIHtcblx0XHRoID0gcyA9IDA7XG5cdH0gZWxzZSB7XG5cdFx0cyA9IGRpZmYgLyB2O1xuXHRcdHJkaWYgPSBkaWZmYyhyKTtcblx0XHRnZGlmID0gZGlmZmMoZyk7XG5cdFx0YmRpZiA9IGRpZmZjKGIpO1xuXG5cdFx0aWYgKHIgPT09IHYpIHtcblx0XHRcdGggPSBiZGlmIC0gZ2RpZjtcblx0XHR9IGVsc2UgaWYgKGcgPT09IHYpIHtcblx0XHRcdGggPSAoMSAvIDMpICsgcmRpZiAtIGJkaWY7XG5cdFx0fSBlbHNlIGlmIChiID09PSB2KSB7XG5cdFx0XHRoID0gKDIgLyAzKSArIGdkaWYgLSByZGlmO1xuXHRcdH1cblx0XHRpZiAoaCA8IDApIHtcblx0XHRcdGggKz0gMTtcblx0XHR9IGVsc2UgaWYgKGggPiAxKSB7XG5cdFx0XHRoIC09IDE7XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIFtcblx0XHRoICogMzYwLFxuXHRcdHMgKiAxMDAsXG5cdFx0diAqIDEwMFxuXHRdO1xufTtcblxuY29udmVydC5yZ2IuaHdiID0gZnVuY3Rpb24gKHJnYikge1xuXHR2YXIgciA9IHJnYlswXTtcblx0dmFyIGcgPSByZ2JbMV07XG5cdHZhciBiID0gcmdiWzJdO1xuXHR2YXIgaCA9IGNvbnZlcnQucmdiLmhzbChyZ2IpWzBdO1xuXHR2YXIgdyA9IDEgLyAyNTUgKiBNYXRoLm1pbihyLCBNYXRoLm1pbihnLCBiKSk7XG5cblx0YiA9IDEgLSAxIC8gMjU1ICogTWF0aC5tYXgociwgTWF0aC5tYXgoZywgYikpO1xuXG5cdHJldHVybiBbaCwgdyAqIDEwMCwgYiAqIDEwMF07XG59O1xuXG5jb252ZXJ0LnJnYi5jbXlrID0gZnVuY3Rpb24gKHJnYikge1xuXHR2YXIgciA9IHJnYlswXSAvIDI1NTtcblx0dmFyIGcgPSByZ2JbMV0gLyAyNTU7XG5cdHZhciBiID0gcmdiWzJdIC8gMjU1O1xuXHR2YXIgYztcblx0dmFyIG07XG5cdHZhciB5O1xuXHR2YXIgaztcblxuXHRrID0gTWF0aC5taW4oMSAtIHIsIDEgLSBnLCAxIC0gYik7XG5cdGMgPSAoMSAtIHIgLSBrKSAvICgxIC0gaykgfHwgMDtcblx0bSA9ICgxIC0gZyAtIGspIC8gKDEgLSBrKSB8fCAwO1xuXHR5ID0gKDEgLSBiIC0gaykgLyAoMSAtIGspIHx8IDA7XG5cblx0cmV0dXJuIFtjICogMTAwLCBtICogMTAwLCB5ICogMTAwLCBrICogMTAwXTtcbn07XG5cbi8qKlxuICogU2VlIGh0dHBzOi8vZW4ubS53aWtpcGVkaWEub3JnL3dpa2kvRXVjbGlkZWFuX2Rpc3RhbmNlI1NxdWFyZWRfRXVjbGlkZWFuX2Rpc3RhbmNlXG4gKiAqL1xuZnVuY3Rpb24gY29tcGFyYXRpdmVEaXN0YW5jZSh4LCB5KSB7XG5cdHJldHVybiAoXG5cdFx0TWF0aC5wb3coeFswXSAtIHlbMF0sIDIpICtcblx0XHRNYXRoLnBvdyh4WzFdIC0geVsxXSwgMikgK1xuXHRcdE1hdGgucG93KHhbMl0gLSB5WzJdLCAyKVxuXHQpO1xufVxuXG5jb252ZXJ0LnJnYi5rZXl3b3JkID0gZnVuY3Rpb24gKHJnYikge1xuXHR2YXIgcmV2ZXJzZWQgPSByZXZlcnNlS2V5d29yZHNbcmdiXTtcblx0aWYgKHJldmVyc2VkKSB7XG5cdFx0cmV0dXJuIHJldmVyc2VkO1xuXHR9XG5cblx0dmFyIGN1cnJlbnRDbG9zZXN0RGlzdGFuY2UgPSBJbmZpbml0eTtcblx0dmFyIGN1cnJlbnRDbG9zZXN0S2V5d29yZDtcblxuXHRmb3IgKHZhciBrZXl3b3JkIGluIGNvbG9yTmFtZSkge1xuXHRcdGlmIChjb2xvck5hbWUuaGFzT3duUHJvcGVydHkoa2V5d29yZCkpIHtcblx0XHRcdHZhciB2YWx1ZSA9IGNvbG9yTmFtZVtrZXl3b3JkXTtcblxuXHRcdFx0Ly8gQ29tcHV0ZSBjb21wYXJhdGl2ZSBkaXN0YW5jZVxuXHRcdFx0dmFyIGRpc3RhbmNlID0gY29tcGFyYXRpdmVEaXN0YW5jZShyZ2IsIHZhbHVlKTtcblxuXHRcdFx0Ly8gQ2hlY2sgaWYgaXRzIGxlc3MsIGlmIHNvIHNldCBhcyBjbG9zZXN0XG5cdFx0XHRpZiAoZGlzdGFuY2UgPCBjdXJyZW50Q2xvc2VzdERpc3RhbmNlKSB7XG5cdFx0XHRcdGN1cnJlbnRDbG9zZXN0RGlzdGFuY2UgPSBkaXN0YW5jZTtcblx0XHRcdFx0Y3VycmVudENsb3Nlc3RLZXl3b3JkID0ga2V5d29yZDtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gY3VycmVudENsb3Nlc3RLZXl3b3JkO1xufTtcblxuY29udmVydC5rZXl3b3JkLnJnYiA9IGZ1bmN0aW9uIChrZXl3b3JkKSB7XG5cdHJldHVybiBjb2xvck5hbWVba2V5d29yZF07XG59O1xuXG5jb252ZXJ0LnJnYi54eXogPSBmdW5jdGlvbiAocmdiKSB7XG5cdHZhciByID0gcmdiWzBdIC8gMjU1O1xuXHR2YXIgZyA9IHJnYlsxXSAvIDI1NTtcblx0dmFyIGIgPSByZ2JbMl0gLyAyNTU7XG5cblx0Ly8gYXNzdW1lIHNSR0Jcblx0ciA9IHIgPiAwLjA0MDQ1ID8gTWF0aC5wb3coKChyICsgMC4wNTUpIC8gMS4wNTUpLCAyLjQpIDogKHIgLyAxMi45Mik7XG5cdGcgPSBnID4gMC4wNDA0NSA/IE1hdGgucG93KCgoZyArIDAuMDU1KSAvIDEuMDU1KSwgMi40KSA6IChnIC8gMTIuOTIpO1xuXHRiID0gYiA+IDAuMDQwNDUgPyBNYXRoLnBvdygoKGIgKyAwLjA1NSkgLyAxLjA1NSksIDIuNCkgOiAoYiAvIDEyLjkyKTtcblxuXHR2YXIgeCA9IChyICogMC40MTI0KSArIChnICogMC4zNTc2KSArIChiICogMC4xODA1KTtcblx0dmFyIHkgPSAociAqIDAuMjEyNikgKyAoZyAqIDAuNzE1MikgKyAoYiAqIDAuMDcyMik7XG5cdHZhciB6ID0gKHIgKiAwLjAxOTMpICsgKGcgKiAwLjExOTIpICsgKGIgKiAwLjk1MDUpO1xuXG5cdHJldHVybiBbeCAqIDEwMCwgeSAqIDEwMCwgeiAqIDEwMF07XG59O1xuXG5jb252ZXJ0LnJnYi5sYWIgPSBmdW5jdGlvbiAocmdiKSB7XG5cdHZhciB4eXogPSBjb252ZXJ0LnJnYi54eXoocmdiKTtcblx0dmFyIHggPSB4eXpbMF07XG5cdHZhciB5ID0geHl6WzFdO1xuXHR2YXIgeiA9IHh5elsyXTtcblx0dmFyIGw7XG5cdHZhciBhO1xuXHR2YXIgYjtcblxuXHR4IC89IDk1LjA0Nztcblx0eSAvPSAxMDA7XG5cdHogLz0gMTA4Ljg4MztcblxuXHR4ID0geCA+IDAuMDA4ODU2ID8gTWF0aC5wb3coeCwgMSAvIDMpIDogKDcuNzg3ICogeCkgKyAoMTYgLyAxMTYpO1xuXHR5ID0geSA+IDAuMDA4ODU2ID8gTWF0aC5wb3coeSwgMSAvIDMpIDogKDcuNzg3ICogeSkgKyAoMTYgLyAxMTYpO1xuXHR6ID0geiA+IDAuMDA4ODU2ID8gTWF0aC5wb3coeiwgMSAvIDMpIDogKDcuNzg3ICogeikgKyAoMTYgLyAxMTYpO1xuXG5cdGwgPSAoMTE2ICogeSkgLSAxNjtcblx0YSA9IDUwMCAqICh4IC0geSk7XG5cdGIgPSAyMDAgKiAoeSAtIHopO1xuXG5cdHJldHVybiBbbCwgYSwgYl07XG59O1xuXG5jb252ZXJ0LmhzbC5yZ2IgPSBmdW5jdGlvbiAoaHNsKSB7XG5cdHZhciBoID0gaHNsWzBdIC8gMzYwO1xuXHR2YXIgcyA9IGhzbFsxXSAvIDEwMDtcblx0dmFyIGwgPSBoc2xbMl0gLyAxMDA7XG5cdHZhciB0MTtcblx0dmFyIHQyO1xuXHR2YXIgdDM7XG5cdHZhciByZ2I7XG5cdHZhciB2YWw7XG5cblx0aWYgKHMgPT09IDApIHtcblx0XHR2YWwgPSBsICogMjU1O1xuXHRcdHJldHVybiBbdmFsLCB2YWwsIHZhbF07XG5cdH1cblxuXHRpZiAobCA8IDAuNSkge1xuXHRcdHQyID0gbCAqICgxICsgcyk7XG5cdH0gZWxzZSB7XG5cdFx0dDIgPSBsICsgcyAtIGwgKiBzO1xuXHR9XG5cblx0dDEgPSAyICogbCAtIHQyO1xuXG5cdHJnYiA9IFswLCAwLCAwXTtcblx0Zm9yICh2YXIgaSA9IDA7IGkgPCAzOyBpKyspIHtcblx0XHR0MyA9IGggKyAxIC8gMyAqIC0oaSAtIDEpO1xuXHRcdGlmICh0MyA8IDApIHtcblx0XHRcdHQzKys7XG5cdFx0fVxuXHRcdGlmICh0MyA+IDEpIHtcblx0XHRcdHQzLS07XG5cdFx0fVxuXG5cdFx0aWYgKDYgKiB0MyA8IDEpIHtcblx0XHRcdHZhbCA9IHQxICsgKHQyIC0gdDEpICogNiAqIHQzO1xuXHRcdH0gZWxzZSBpZiAoMiAqIHQzIDwgMSkge1xuXHRcdFx0dmFsID0gdDI7XG5cdFx0fSBlbHNlIGlmICgzICogdDMgPCAyKSB7XG5cdFx0XHR2YWwgPSB0MSArICh0MiAtIHQxKSAqICgyIC8gMyAtIHQzKSAqIDY7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHZhbCA9IHQxO1xuXHRcdH1cblxuXHRcdHJnYltpXSA9IHZhbCAqIDI1NTtcblx0fVxuXG5cdHJldHVybiByZ2I7XG59O1xuXG5jb252ZXJ0LmhzbC5oc3YgPSBmdW5jdGlvbiAoaHNsKSB7XG5cdHZhciBoID0gaHNsWzBdO1xuXHR2YXIgcyA9IGhzbFsxXSAvIDEwMDtcblx0dmFyIGwgPSBoc2xbMl0gLyAxMDA7XG5cdHZhciBzbWluID0gcztcblx0dmFyIGxtaW4gPSBNYXRoLm1heChsLCAwLjAxKTtcblx0dmFyIHN2O1xuXHR2YXIgdjtcblxuXHRsICo9IDI7XG5cdHMgKj0gKGwgPD0gMSkgPyBsIDogMiAtIGw7XG5cdHNtaW4gKj0gbG1pbiA8PSAxID8gbG1pbiA6IDIgLSBsbWluO1xuXHR2ID0gKGwgKyBzKSAvIDI7XG5cdHN2ID0gbCA9PT0gMCA/ICgyICogc21pbikgLyAobG1pbiArIHNtaW4pIDogKDIgKiBzKSAvIChsICsgcyk7XG5cblx0cmV0dXJuIFtoLCBzdiAqIDEwMCwgdiAqIDEwMF07XG59O1xuXG5jb252ZXJ0Lmhzdi5yZ2IgPSBmdW5jdGlvbiAoaHN2KSB7XG5cdHZhciBoID0gaHN2WzBdIC8gNjA7XG5cdHZhciBzID0gaHN2WzFdIC8gMTAwO1xuXHR2YXIgdiA9IGhzdlsyXSAvIDEwMDtcblx0dmFyIGhpID0gTWF0aC5mbG9vcihoKSAlIDY7XG5cblx0dmFyIGYgPSBoIC0gTWF0aC5mbG9vcihoKTtcblx0dmFyIHAgPSAyNTUgKiB2ICogKDEgLSBzKTtcblx0dmFyIHEgPSAyNTUgKiB2ICogKDEgLSAocyAqIGYpKTtcblx0dmFyIHQgPSAyNTUgKiB2ICogKDEgLSAocyAqICgxIC0gZikpKTtcblx0diAqPSAyNTU7XG5cblx0c3dpdGNoIChoaSkge1xuXHRcdGNhc2UgMDpcblx0XHRcdHJldHVybiBbdiwgdCwgcF07XG5cdFx0Y2FzZSAxOlxuXHRcdFx0cmV0dXJuIFtxLCB2LCBwXTtcblx0XHRjYXNlIDI6XG5cdFx0XHRyZXR1cm4gW3AsIHYsIHRdO1xuXHRcdGNhc2UgMzpcblx0XHRcdHJldHVybiBbcCwgcSwgdl07XG5cdFx0Y2FzZSA0OlxuXHRcdFx0cmV0dXJuIFt0LCBwLCB2XTtcblx0XHRjYXNlIDU6XG5cdFx0XHRyZXR1cm4gW3YsIHAsIHFdO1xuXHR9XG59O1xuXG5jb252ZXJ0Lmhzdi5oc2wgPSBmdW5jdGlvbiAoaHN2KSB7XG5cdHZhciBoID0gaHN2WzBdO1xuXHR2YXIgcyA9IGhzdlsxXSAvIDEwMDtcblx0dmFyIHYgPSBoc3ZbMl0gLyAxMDA7XG5cdHZhciB2bWluID0gTWF0aC5tYXgodiwgMC4wMSk7XG5cdHZhciBsbWluO1xuXHR2YXIgc2w7XG5cdHZhciBsO1xuXG5cdGwgPSAoMiAtIHMpICogdjtcblx0bG1pbiA9ICgyIC0gcykgKiB2bWluO1xuXHRzbCA9IHMgKiB2bWluO1xuXHRzbCAvPSAobG1pbiA8PSAxKSA/IGxtaW4gOiAyIC0gbG1pbjtcblx0c2wgPSBzbCB8fCAwO1xuXHRsIC89IDI7XG5cblx0cmV0dXJuIFtoLCBzbCAqIDEwMCwgbCAqIDEwMF07XG59O1xuXG4vLyBodHRwOi8vZGV2LnczLm9yZy9jc3N3Zy9jc3MtY29sb3IvI2h3Yi10by1yZ2JcbmNvbnZlcnQuaHdiLnJnYiA9IGZ1bmN0aW9uIChod2IpIHtcblx0dmFyIGggPSBod2JbMF0gLyAzNjA7XG5cdHZhciB3aCA9IGh3YlsxXSAvIDEwMDtcblx0dmFyIGJsID0gaHdiWzJdIC8gMTAwO1xuXHR2YXIgcmF0aW8gPSB3aCArIGJsO1xuXHR2YXIgaTtcblx0dmFyIHY7XG5cdHZhciBmO1xuXHR2YXIgbjtcblxuXHQvLyB3aCArIGJsIGNhbnQgYmUgPiAxXG5cdGlmIChyYXRpbyA+IDEpIHtcblx0XHR3aCAvPSByYXRpbztcblx0XHRibCAvPSByYXRpbztcblx0fVxuXG5cdGkgPSBNYXRoLmZsb29yKDYgKiBoKTtcblx0diA9IDEgLSBibDtcblx0ZiA9IDYgKiBoIC0gaTtcblxuXHRpZiAoKGkgJiAweDAxKSAhPT0gMCkge1xuXHRcdGYgPSAxIC0gZjtcblx0fVxuXG5cdG4gPSB3aCArIGYgKiAodiAtIHdoKTsgLy8gbGluZWFyIGludGVycG9sYXRpb25cblxuXHR2YXIgcjtcblx0dmFyIGc7XG5cdHZhciBiO1xuXHRzd2l0Y2ggKGkpIHtcblx0XHRkZWZhdWx0OlxuXHRcdGNhc2UgNjpcblx0XHRjYXNlIDA6IHIgPSB2OyBnID0gbjsgYiA9IHdoOyBicmVhaztcblx0XHRjYXNlIDE6IHIgPSBuOyBnID0gdjsgYiA9IHdoOyBicmVhaztcblx0XHRjYXNlIDI6IHIgPSB3aDsgZyA9IHY7IGIgPSBuOyBicmVhaztcblx0XHRjYXNlIDM6IHIgPSB3aDsgZyA9IG47IGIgPSB2OyBicmVhaztcblx0XHRjYXNlIDQ6IHIgPSBuOyBnID0gd2g7IGIgPSB2OyBicmVhaztcblx0XHRjYXNlIDU6IHIgPSB2OyBnID0gd2g7IGIgPSBuOyBicmVhaztcblx0fVxuXG5cdHJldHVybiBbciAqIDI1NSwgZyAqIDI1NSwgYiAqIDI1NV07XG59O1xuXG5jb252ZXJ0LmNteWsucmdiID0gZnVuY3Rpb24gKGNteWspIHtcblx0dmFyIGMgPSBjbXlrWzBdIC8gMTAwO1xuXHR2YXIgbSA9IGNteWtbMV0gLyAxMDA7XG5cdHZhciB5ID0gY215a1syXSAvIDEwMDtcblx0dmFyIGsgPSBjbXlrWzNdIC8gMTAwO1xuXHR2YXIgcjtcblx0dmFyIGc7XG5cdHZhciBiO1xuXG5cdHIgPSAxIC0gTWF0aC5taW4oMSwgYyAqICgxIC0gaykgKyBrKTtcblx0ZyA9IDEgLSBNYXRoLm1pbigxLCBtICogKDEgLSBrKSArIGspO1xuXHRiID0gMSAtIE1hdGgubWluKDEsIHkgKiAoMSAtIGspICsgayk7XG5cblx0cmV0dXJuIFtyICogMjU1LCBnICogMjU1LCBiICogMjU1XTtcbn07XG5cbmNvbnZlcnQueHl6LnJnYiA9IGZ1bmN0aW9uICh4eXopIHtcblx0dmFyIHggPSB4eXpbMF0gLyAxMDA7XG5cdHZhciB5ID0geHl6WzFdIC8gMTAwO1xuXHR2YXIgeiA9IHh5elsyXSAvIDEwMDtcblx0dmFyIHI7XG5cdHZhciBnO1xuXHR2YXIgYjtcblxuXHRyID0gKHggKiAzLjI0MDYpICsgKHkgKiAtMS41MzcyKSArICh6ICogLTAuNDk4Nik7XG5cdGcgPSAoeCAqIC0wLjk2ODkpICsgKHkgKiAxLjg3NTgpICsgKHogKiAwLjA0MTUpO1xuXHRiID0gKHggKiAwLjA1NTcpICsgKHkgKiAtMC4yMDQwKSArICh6ICogMS4wNTcwKTtcblxuXHQvLyBhc3N1bWUgc1JHQlxuXHRyID0gciA+IDAuMDAzMTMwOFxuXHRcdD8gKCgxLjA1NSAqIE1hdGgucG93KHIsIDEuMCAvIDIuNCkpIC0gMC4wNTUpXG5cdFx0OiByICogMTIuOTI7XG5cblx0ZyA9IGcgPiAwLjAwMzEzMDhcblx0XHQ/ICgoMS4wNTUgKiBNYXRoLnBvdyhnLCAxLjAgLyAyLjQpKSAtIDAuMDU1KVxuXHRcdDogZyAqIDEyLjkyO1xuXG5cdGIgPSBiID4gMC4wMDMxMzA4XG5cdFx0PyAoKDEuMDU1ICogTWF0aC5wb3coYiwgMS4wIC8gMi40KSkgLSAwLjA1NSlcblx0XHQ6IGIgKiAxMi45MjtcblxuXHRyID0gTWF0aC5taW4oTWF0aC5tYXgoMCwgciksIDEpO1xuXHRnID0gTWF0aC5taW4oTWF0aC5tYXgoMCwgZyksIDEpO1xuXHRiID0gTWF0aC5taW4oTWF0aC5tYXgoMCwgYiksIDEpO1xuXG5cdHJldHVybiBbciAqIDI1NSwgZyAqIDI1NSwgYiAqIDI1NV07XG59O1xuXG5jb252ZXJ0Lnh5ei5sYWIgPSBmdW5jdGlvbiAoeHl6KSB7XG5cdHZhciB4ID0geHl6WzBdO1xuXHR2YXIgeSA9IHh5elsxXTtcblx0dmFyIHogPSB4eXpbMl07XG5cdHZhciBsO1xuXHR2YXIgYTtcblx0dmFyIGI7XG5cblx0eCAvPSA5NS4wNDc7XG5cdHkgLz0gMTAwO1xuXHR6IC89IDEwOC44ODM7XG5cblx0eCA9IHggPiAwLjAwODg1NiA/IE1hdGgucG93KHgsIDEgLyAzKSA6ICg3Ljc4NyAqIHgpICsgKDE2IC8gMTE2KTtcblx0eSA9IHkgPiAwLjAwODg1NiA/IE1hdGgucG93KHksIDEgLyAzKSA6ICg3Ljc4NyAqIHkpICsgKDE2IC8gMTE2KTtcblx0eiA9IHogPiAwLjAwODg1NiA/IE1hdGgucG93KHosIDEgLyAzKSA6ICg3Ljc4NyAqIHopICsgKDE2IC8gMTE2KTtcblxuXHRsID0gKDExNiAqIHkpIC0gMTY7XG5cdGEgPSA1MDAgKiAoeCAtIHkpO1xuXHRiID0gMjAwICogKHkgLSB6KTtcblxuXHRyZXR1cm4gW2wsIGEsIGJdO1xufTtcblxuY29udmVydC5sYWIueHl6ID0gZnVuY3Rpb24gKGxhYikge1xuXHR2YXIgbCA9IGxhYlswXTtcblx0dmFyIGEgPSBsYWJbMV07XG5cdHZhciBiID0gbGFiWzJdO1xuXHR2YXIgeDtcblx0dmFyIHk7XG5cdHZhciB6O1xuXG5cdHkgPSAobCArIDE2KSAvIDExNjtcblx0eCA9IGEgLyA1MDAgKyB5O1xuXHR6ID0geSAtIGIgLyAyMDA7XG5cblx0dmFyIHkyID0gTWF0aC5wb3coeSwgMyk7XG5cdHZhciB4MiA9IE1hdGgucG93KHgsIDMpO1xuXHR2YXIgejIgPSBNYXRoLnBvdyh6LCAzKTtcblx0eSA9IHkyID4gMC4wMDg4NTYgPyB5MiA6ICh5IC0gMTYgLyAxMTYpIC8gNy43ODc7XG5cdHggPSB4MiA+IDAuMDA4ODU2ID8geDIgOiAoeCAtIDE2IC8gMTE2KSAvIDcuNzg3O1xuXHR6ID0gejIgPiAwLjAwODg1NiA/IHoyIDogKHogLSAxNiAvIDExNikgLyA3Ljc4NztcblxuXHR4ICo9IDk1LjA0Nztcblx0eSAqPSAxMDA7XG5cdHogKj0gMTA4Ljg4MztcblxuXHRyZXR1cm4gW3gsIHksIHpdO1xufTtcblxuY29udmVydC5sYWIubGNoID0gZnVuY3Rpb24gKGxhYikge1xuXHR2YXIgbCA9IGxhYlswXTtcblx0dmFyIGEgPSBsYWJbMV07XG5cdHZhciBiID0gbGFiWzJdO1xuXHR2YXIgaHI7XG5cdHZhciBoO1xuXHR2YXIgYztcblxuXHRociA9IE1hdGguYXRhbjIoYiwgYSk7XG5cdGggPSBociAqIDM2MCAvIDIgLyBNYXRoLlBJO1xuXG5cdGlmIChoIDwgMCkge1xuXHRcdGggKz0gMzYwO1xuXHR9XG5cblx0YyA9IE1hdGguc3FydChhICogYSArIGIgKiBiKTtcblxuXHRyZXR1cm4gW2wsIGMsIGhdO1xufTtcblxuY29udmVydC5sY2gubGFiID0gZnVuY3Rpb24gKGxjaCkge1xuXHR2YXIgbCA9IGxjaFswXTtcblx0dmFyIGMgPSBsY2hbMV07XG5cdHZhciBoID0gbGNoWzJdO1xuXHR2YXIgYTtcblx0dmFyIGI7XG5cdHZhciBocjtcblxuXHRociA9IGggLyAzNjAgKiAyICogTWF0aC5QSTtcblx0YSA9IGMgKiBNYXRoLmNvcyhocik7XG5cdGIgPSBjICogTWF0aC5zaW4oaHIpO1xuXG5cdHJldHVybiBbbCwgYSwgYl07XG59O1xuXG5jb252ZXJ0LnJnYi5hbnNpMTYgPSBmdW5jdGlvbiAoYXJncykge1xuXHR2YXIgciA9IGFyZ3NbMF07XG5cdHZhciBnID0gYXJnc1sxXTtcblx0dmFyIGIgPSBhcmdzWzJdO1xuXHR2YXIgdmFsdWUgPSAxIGluIGFyZ3VtZW50cyA/IGFyZ3VtZW50c1sxXSA6IGNvbnZlcnQucmdiLmhzdihhcmdzKVsyXTsgLy8gaHN2IC0+IGFuc2kxNiBvcHRpbWl6YXRpb25cblxuXHR2YWx1ZSA9IE1hdGgucm91bmQodmFsdWUgLyA1MCk7XG5cblx0aWYgKHZhbHVlID09PSAwKSB7XG5cdFx0cmV0dXJuIDMwO1xuXHR9XG5cblx0dmFyIGFuc2kgPSAzMFxuXHRcdCsgKChNYXRoLnJvdW5kKGIgLyAyNTUpIDw8IDIpXG5cdFx0fCAoTWF0aC5yb3VuZChnIC8gMjU1KSA8PCAxKVxuXHRcdHwgTWF0aC5yb3VuZChyIC8gMjU1KSk7XG5cblx0aWYgKHZhbHVlID09PSAyKSB7XG5cdFx0YW5zaSArPSA2MDtcblx0fVxuXG5cdHJldHVybiBhbnNpO1xufTtcblxuY29udmVydC5oc3YuYW5zaTE2ID0gZnVuY3Rpb24gKGFyZ3MpIHtcblx0Ly8gb3B0aW1pemF0aW9uIGhlcmU7IHdlIGFscmVhZHkga25vdyB0aGUgdmFsdWUgYW5kIGRvbid0IG5lZWQgdG8gZ2V0XG5cdC8vIGl0IGNvbnZlcnRlZCBmb3IgdXMuXG5cdHJldHVybiBjb252ZXJ0LnJnYi5hbnNpMTYoY29udmVydC5oc3YucmdiKGFyZ3MpLCBhcmdzWzJdKTtcbn07XG5cbmNvbnZlcnQucmdiLmFuc2kyNTYgPSBmdW5jdGlvbiAoYXJncykge1xuXHR2YXIgciA9IGFyZ3NbMF07XG5cdHZhciBnID0gYXJnc1sxXTtcblx0dmFyIGIgPSBhcmdzWzJdO1xuXG5cdC8vIHdlIHVzZSB0aGUgZXh0ZW5kZWQgZ3JleXNjYWxlIHBhbGV0dGUgaGVyZSwgd2l0aCB0aGUgZXhjZXB0aW9uIG9mXG5cdC8vIGJsYWNrIGFuZCB3aGl0ZS4gbm9ybWFsIHBhbGV0dGUgb25seSBoYXMgNCBncmV5c2NhbGUgc2hhZGVzLlxuXHRpZiAociA9PT0gZyAmJiBnID09PSBiKSB7XG5cdFx0aWYgKHIgPCA4KSB7XG5cdFx0XHRyZXR1cm4gMTY7XG5cdFx0fVxuXG5cdFx0aWYgKHIgPiAyNDgpIHtcblx0XHRcdHJldHVybiAyMzE7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIE1hdGgucm91bmQoKChyIC0gOCkgLyAyNDcpICogMjQpICsgMjMyO1xuXHR9XG5cblx0dmFyIGFuc2kgPSAxNlxuXHRcdCsgKDM2ICogTWF0aC5yb3VuZChyIC8gMjU1ICogNSkpXG5cdFx0KyAoNiAqIE1hdGgucm91bmQoZyAvIDI1NSAqIDUpKVxuXHRcdCsgTWF0aC5yb3VuZChiIC8gMjU1ICogNSk7XG5cblx0cmV0dXJuIGFuc2k7XG59O1xuXG5jb252ZXJ0LmFuc2kxNi5yZ2IgPSBmdW5jdGlvbiAoYXJncykge1xuXHR2YXIgY29sb3IgPSBhcmdzICUgMTA7XG5cblx0Ly8gaGFuZGxlIGdyZXlzY2FsZVxuXHRpZiAoY29sb3IgPT09IDAgfHwgY29sb3IgPT09IDcpIHtcblx0XHRpZiAoYXJncyA+IDUwKSB7XG5cdFx0XHRjb2xvciArPSAzLjU7XG5cdFx0fVxuXG5cdFx0Y29sb3IgPSBjb2xvciAvIDEwLjUgKiAyNTU7XG5cblx0XHRyZXR1cm4gW2NvbG9yLCBjb2xvciwgY29sb3JdO1xuXHR9XG5cblx0dmFyIG11bHQgPSAofn4oYXJncyA+IDUwKSArIDEpICogMC41O1xuXHR2YXIgciA9ICgoY29sb3IgJiAxKSAqIG11bHQpICogMjU1O1xuXHR2YXIgZyA9ICgoKGNvbG9yID4+IDEpICYgMSkgKiBtdWx0KSAqIDI1NTtcblx0dmFyIGIgPSAoKChjb2xvciA+PiAyKSAmIDEpICogbXVsdCkgKiAyNTU7XG5cblx0cmV0dXJuIFtyLCBnLCBiXTtcbn07XG5cbmNvbnZlcnQuYW5zaTI1Ni5yZ2IgPSBmdW5jdGlvbiAoYXJncykge1xuXHQvLyBoYW5kbGUgZ3JleXNjYWxlXG5cdGlmIChhcmdzID49IDIzMikge1xuXHRcdHZhciBjID0gKGFyZ3MgLSAyMzIpICogMTAgKyA4O1xuXHRcdHJldHVybiBbYywgYywgY107XG5cdH1cblxuXHRhcmdzIC09IDE2O1xuXG5cdHZhciByZW07XG5cdHZhciByID0gTWF0aC5mbG9vcihhcmdzIC8gMzYpIC8gNSAqIDI1NTtcblx0dmFyIGcgPSBNYXRoLmZsb29yKChyZW0gPSBhcmdzICUgMzYpIC8gNikgLyA1ICogMjU1O1xuXHR2YXIgYiA9IChyZW0gJSA2KSAvIDUgKiAyNTU7XG5cblx0cmV0dXJuIFtyLCBnLCBiXTtcbn07XG5cbmNvbnZlcnQucmdiLmhleCA9IGZ1bmN0aW9uIChhcmdzKSB7XG5cdHZhciBpbnRlZ2VyID0gKChNYXRoLnJvdW5kKGFyZ3NbMF0pICYgMHhGRikgPDwgMTYpXG5cdFx0KyAoKE1hdGgucm91bmQoYXJnc1sxXSkgJiAweEZGKSA8PCA4KVxuXHRcdCsgKE1hdGgucm91bmQoYXJnc1syXSkgJiAweEZGKTtcblxuXHR2YXIgc3RyaW5nID0gaW50ZWdlci50b1N0cmluZygxNikudG9VcHBlckNhc2UoKTtcblx0cmV0dXJuICcwMDAwMDAnLnN1YnN0cmluZyhzdHJpbmcubGVuZ3RoKSArIHN0cmluZztcbn07XG5cbmNvbnZlcnQuaGV4LnJnYiA9IGZ1bmN0aW9uIChhcmdzKSB7XG5cdHZhciBtYXRjaCA9IGFyZ3MudG9TdHJpbmcoMTYpLm1hdGNoKC9bYS1mMC05XXs2fXxbYS1mMC05XXszfS9pKTtcblx0aWYgKCFtYXRjaCkge1xuXHRcdHJldHVybiBbMCwgMCwgMF07XG5cdH1cblxuXHR2YXIgY29sb3JTdHJpbmcgPSBtYXRjaFswXTtcblxuXHRpZiAobWF0Y2hbMF0ubGVuZ3RoID09PSAzKSB7XG5cdFx0Y29sb3JTdHJpbmcgPSBjb2xvclN0cmluZy5zcGxpdCgnJykubWFwKGZ1bmN0aW9uIChjaGFyKSB7XG5cdFx0XHRyZXR1cm4gY2hhciArIGNoYXI7XG5cdFx0fSkuam9pbignJyk7XG5cdH1cblxuXHR2YXIgaW50ZWdlciA9IHBhcnNlSW50KGNvbG9yU3RyaW5nLCAxNik7XG5cdHZhciByID0gKGludGVnZXIgPj4gMTYpICYgMHhGRjtcblx0dmFyIGcgPSAoaW50ZWdlciA+PiA4KSAmIDB4RkY7XG5cdHZhciBiID0gaW50ZWdlciAmIDB4RkY7XG5cblx0cmV0dXJuIFtyLCBnLCBiXTtcbn07XG5cbmNvbnZlcnQucmdiLmhjZyA9IGZ1bmN0aW9uIChyZ2IpIHtcblx0dmFyIHIgPSByZ2JbMF0gLyAyNTU7XG5cdHZhciBnID0gcmdiWzFdIC8gMjU1O1xuXHR2YXIgYiA9IHJnYlsyXSAvIDI1NTtcblx0dmFyIG1heCA9IE1hdGgubWF4KE1hdGgubWF4KHIsIGcpLCBiKTtcblx0dmFyIG1pbiA9IE1hdGgubWluKE1hdGgubWluKHIsIGcpLCBiKTtcblx0dmFyIGNocm9tYSA9IChtYXggLSBtaW4pO1xuXHR2YXIgZ3JheXNjYWxlO1xuXHR2YXIgaHVlO1xuXG5cdGlmIChjaHJvbWEgPCAxKSB7XG5cdFx0Z3JheXNjYWxlID0gbWluIC8gKDEgLSBjaHJvbWEpO1xuXHR9IGVsc2Uge1xuXHRcdGdyYXlzY2FsZSA9IDA7XG5cdH1cblxuXHRpZiAoY2hyb21hIDw9IDApIHtcblx0XHRodWUgPSAwO1xuXHR9IGVsc2Vcblx0aWYgKG1heCA9PT0gcikge1xuXHRcdGh1ZSA9ICgoZyAtIGIpIC8gY2hyb21hKSAlIDY7XG5cdH0gZWxzZVxuXHRpZiAobWF4ID09PSBnKSB7XG5cdFx0aHVlID0gMiArIChiIC0gcikgLyBjaHJvbWE7XG5cdH0gZWxzZSB7XG5cdFx0aHVlID0gNCArIChyIC0gZykgLyBjaHJvbWEgKyA0O1xuXHR9XG5cblx0aHVlIC89IDY7XG5cdGh1ZSAlPSAxO1xuXG5cdHJldHVybiBbaHVlICogMzYwLCBjaHJvbWEgKiAxMDAsIGdyYXlzY2FsZSAqIDEwMF07XG59O1xuXG5jb252ZXJ0LmhzbC5oY2cgPSBmdW5jdGlvbiAoaHNsKSB7XG5cdHZhciBzID0gaHNsWzFdIC8gMTAwO1xuXHR2YXIgbCA9IGhzbFsyXSAvIDEwMDtcblx0dmFyIGMgPSAxO1xuXHR2YXIgZiA9IDA7XG5cblx0aWYgKGwgPCAwLjUpIHtcblx0XHRjID0gMi4wICogcyAqIGw7XG5cdH0gZWxzZSB7XG5cdFx0YyA9IDIuMCAqIHMgKiAoMS4wIC0gbCk7XG5cdH1cblxuXHRpZiAoYyA8IDEuMCkge1xuXHRcdGYgPSAobCAtIDAuNSAqIGMpIC8gKDEuMCAtIGMpO1xuXHR9XG5cblx0cmV0dXJuIFtoc2xbMF0sIGMgKiAxMDAsIGYgKiAxMDBdO1xufTtcblxuY29udmVydC5oc3YuaGNnID0gZnVuY3Rpb24gKGhzdikge1xuXHR2YXIgcyA9IGhzdlsxXSAvIDEwMDtcblx0dmFyIHYgPSBoc3ZbMl0gLyAxMDA7XG5cblx0dmFyIGMgPSBzICogdjtcblx0dmFyIGYgPSAwO1xuXG5cdGlmIChjIDwgMS4wKSB7XG5cdFx0ZiA9ICh2IC0gYykgLyAoMSAtIGMpO1xuXHR9XG5cblx0cmV0dXJuIFtoc3ZbMF0sIGMgKiAxMDAsIGYgKiAxMDBdO1xufTtcblxuY29udmVydC5oY2cucmdiID0gZnVuY3Rpb24gKGhjZykge1xuXHR2YXIgaCA9IGhjZ1swXSAvIDM2MDtcblx0dmFyIGMgPSBoY2dbMV0gLyAxMDA7XG5cdHZhciBnID0gaGNnWzJdIC8gMTAwO1xuXG5cdGlmIChjID09PSAwLjApIHtcblx0XHRyZXR1cm4gW2cgKiAyNTUsIGcgKiAyNTUsIGcgKiAyNTVdO1xuXHR9XG5cblx0dmFyIHB1cmUgPSBbMCwgMCwgMF07XG5cdHZhciBoaSA9IChoICUgMSkgKiA2O1xuXHR2YXIgdiA9IGhpICUgMTtcblx0dmFyIHcgPSAxIC0gdjtcblx0dmFyIG1nID0gMDtcblxuXHRzd2l0Y2ggKE1hdGguZmxvb3IoaGkpKSB7XG5cdFx0Y2FzZSAwOlxuXHRcdFx0cHVyZVswXSA9IDE7IHB1cmVbMV0gPSB2OyBwdXJlWzJdID0gMDsgYnJlYWs7XG5cdFx0Y2FzZSAxOlxuXHRcdFx0cHVyZVswXSA9IHc7IHB1cmVbMV0gPSAxOyBwdXJlWzJdID0gMDsgYnJlYWs7XG5cdFx0Y2FzZSAyOlxuXHRcdFx0cHVyZVswXSA9IDA7IHB1cmVbMV0gPSAxOyBwdXJlWzJdID0gdjsgYnJlYWs7XG5cdFx0Y2FzZSAzOlxuXHRcdFx0cHVyZVswXSA9IDA7IHB1cmVbMV0gPSB3OyBwdXJlWzJdID0gMTsgYnJlYWs7XG5cdFx0Y2FzZSA0OlxuXHRcdFx0cHVyZVswXSA9IHY7IHB1cmVbMV0gPSAwOyBwdXJlWzJdID0gMTsgYnJlYWs7XG5cdFx0ZGVmYXVsdDpcblx0XHRcdHB1cmVbMF0gPSAxOyBwdXJlWzFdID0gMDsgcHVyZVsyXSA9IHc7XG5cdH1cblxuXHRtZyA9ICgxLjAgLSBjKSAqIGc7XG5cblx0cmV0dXJuIFtcblx0XHQoYyAqIHB1cmVbMF0gKyBtZykgKiAyNTUsXG5cdFx0KGMgKiBwdXJlWzFdICsgbWcpICogMjU1LFxuXHRcdChjICogcHVyZVsyXSArIG1nKSAqIDI1NVxuXHRdO1xufTtcblxuY29udmVydC5oY2cuaHN2ID0gZnVuY3Rpb24gKGhjZykge1xuXHR2YXIgYyA9IGhjZ1sxXSAvIDEwMDtcblx0dmFyIGcgPSBoY2dbMl0gLyAxMDA7XG5cblx0dmFyIHYgPSBjICsgZyAqICgxLjAgLSBjKTtcblx0dmFyIGYgPSAwO1xuXG5cdGlmICh2ID4gMC4wKSB7XG5cdFx0ZiA9IGMgLyB2O1xuXHR9XG5cblx0cmV0dXJuIFtoY2dbMF0sIGYgKiAxMDAsIHYgKiAxMDBdO1xufTtcblxuY29udmVydC5oY2cuaHNsID0gZnVuY3Rpb24gKGhjZykge1xuXHR2YXIgYyA9IGhjZ1sxXSAvIDEwMDtcblx0dmFyIGcgPSBoY2dbMl0gLyAxMDA7XG5cblx0dmFyIGwgPSBnICogKDEuMCAtIGMpICsgMC41ICogYztcblx0dmFyIHMgPSAwO1xuXG5cdGlmIChsID4gMC4wICYmIGwgPCAwLjUpIHtcblx0XHRzID0gYyAvICgyICogbCk7XG5cdH0gZWxzZVxuXHRpZiAobCA+PSAwLjUgJiYgbCA8IDEuMCkge1xuXHRcdHMgPSBjIC8gKDIgKiAoMSAtIGwpKTtcblx0fVxuXG5cdHJldHVybiBbaGNnWzBdLCBzICogMTAwLCBsICogMTAwXTtcbn07XG5cbmNvbnZlcnQuaGNnLmh3YiA9IGZ1bmN0aW9uIChoY2cpIHtcblx0dmFyIGMgPSBoY2dbMV0gLyAxMDA7XG5cdHZhciBnID0gaGNnWzJdIC8gMTAwO1xuXHR2YXIgdiA9IGMgKyBnICogKDEuMCAtIGMpO1xuXHRyZXR1cm4gW2hjZ1swXSwgKHYgLSBjKSAqIDEwMCwgKDEgLSB2KSAqIDEwMF07XG59O1xuXG5jb252ZXJ0Lmh3Yi5oY2cgPSBmdW5jdGlvbiAoaHdiKSB7XG5cdHZhciB3ID0gaHdiWzFdIC8gMTAwO1xuXHR2YXIgYiA9IGh3YlsyXSAvIDEwMDtcblx0dmFyIHYgPSAxIC0gYjtcblx0dmFyIGMgPSB2IC0gdztcblx0dmFyIGcgPSAwO1xuXG5cdGlmIChjIDwgMSkge1xuXHRcdGcgPSAodiAtIGMpIC8gKDEgLSBjKTtcblx0fVxuXG5cdHJldHVybiBbaHdiWzBdLCBjICogMTAwLCBnICogMTAwXTtcbn07XG5cbmNvbnZlcnQuYXBwbGUucmdiID0gZnVuY3Rpb24gKGFwcGxlKSB7XG5cdHJldHVybiBbKGFwcGxlWzBdIC8gNjU1MzUpICogMjU1LCAoYXBwbGVbMV0gLyA2NTUzNSkgKiAyNTUsIChhcHBsZVsyXSAvIDY1NTM1KSAqIDI1NV07XG59O1xuXG5jb252ZXJ0LnJnYi5hcHBsZSA9IGZ1bmN0aW9uIChyZ2IpIHtcblx0cmV0dXJuIFsocmdiWzBdIC8gMjU1KSAqIDY1NTM1LCAocmdiWzFdIC8gMjU1KSAqIDY1NTM1LCAocmdiWzJdIC8gMjU1KSAqIDY1NTM1XTtcbn07XG5cbmNvbnZlcnQuZ3JheS5yZ2IgPSBmdW5jdGlvbiAoYXJncykge1xuXHRyZXR1cm4gW2FyZ3NbMF0gLyAxMDAgKiAyNTUsIGFyZ3NbMF0gLyAxMDAgKiAyNTUsIGFyZ3NbMF0gLyAxMDAgKiAyNTVdO1xufTtcblxuY29udmVydC5ncmF5LmhzbCA9IGNvbnZlcnQuZ3JheS5oc3YgPSBmdW5jdGlvbiAoYXJncykge1xuXHRyZXR1cm4gWzAsIDAsIGFyZ3NbMF1dO1xufTtcblxuY29udmVydC5ncmF5Lmh3YiA9IGZ1bmN0aW9uIChncmF5KSB7XG5cdHJldHVybiBbMCwgMTAwLCBncmF5WzBdXTtcbn07XG5cbmNvbnZlcnQuZ3JheS5jbXlrID0gZnVuY3Rpb24gKGdyYXkpIHtcblx0cmV0dXJuIFswLCAwLCAwLCBncmF5WzBdXTtcbn07XG5cbmNvbnZlcnQuZ3JheS5sYWIgPSBmdW5jdGlvbiAoZ3JheSkge1xuXHRyZXR1cm4gW2dyYXlbMF0sIDAsIDBdO1xufTtcblxuY29udmVydC5ncmF5LmhleCA9IGZ1bmN0aW9uIChncmF5KSB7XG5cdHZhciB2YWwgPSBNYXRoLnJvdW5kKGdyYXlbMF0gLyAxMDAgKiAyNTUpICYgMHhGRjtcblx0dmFyIGludGVnZXIgPSAodmFsIDw8IDE2KSArICh2YWwgPDwgOCkgKyB2YWw7XG5cblx0dmFyIHN0cmluZyA9IGludGVnZXIudG9TdHJpbmcoMTYpLnRvVXBwZXJDYXNlKCk7XG5cdHJldHVybiAnMDAwMDAwJy5zdWJzdHJpbmcoc3RyaW5nLmxlbmd0aCkgKyBzdHJpbmc7XG59O1xuXG5jb252ZXJ0LnJnYi5ncmF5ID0gZnVuY3Rpb24gKHJnYikge1xuXHR2YXIgdmFsID0gKHJnYlswXSArIHJnYlsxXSArIHJnYlsyXSkgLyAzO1xuXHRyZXR1cm4gW3ZhbCAvIDI1NSAqIDEwMF07XG59O1xufSk7XG52YXIgY29udmVyc2lvbnNfMSA9IGNvbnZlcnNpb25zLnJnYjtcbnZhciBjb252ZXJzaW9uc18yID0gY29udmVyc2lvbnMuaHNsO1xudmFyIGNvbnZlcnNpb25zXzMgPSBjb252ZXJzaW9ucy5oc3Y7XG52YXIgY29udmVyc2lvbnNfNCA9IGNvbnZlcnNpb25zLmh3YjtcbnZhciBjb252ZXJzaW9uc181ID0gY29udmVyc2lvbnMuY215aztcbnZhciBjb252ZXJzaW9uc182ID0gY29udmVyc2lvbnMueHl6O1xudmFyIGNvbnZlcnNpb25zXzcgPSBjb252ZXJzaW9ucy5sYWI7XG52YXIgY29udmVyc2lvbnNfOCA9IGNvbnZlcnNpb25zLmxjaDtcbnZhciBjb252ZXJzaW9uc185ID0gY29udmVyc2lvbnMuaGV4O1xudmFyIGNvbnZlcnNpb25zXzEwID0gY29udmVyc2lvbnMua2V5d29yZDtcbnZhciBjb252ZXJzaW9uc18xMSA9IGNvbnZlcnNpb25zLmFuc2kxNjtcbnZhciBjb252ZXJzaW9uc18xMiA9IGNvbnZlcnNpb25zLmFuc2kyNTY7XG52YXIgY29udmVyc2lvbnNfMTMgPSBjb252ZXJzaW9ucy5oY2c7XG52YXIgY29udmVyc2lvbnNfMTQgPSBjb252ZXJzaW9ucy5hcHBsZTtcbnZhciBjb252ZXJzaW9uc18xNSA9IGNvbnZlcnNpb25zLmdyYXk7XG5cbi8qXG5cdHRoaXMgZnVuY3Rpb24gcm91dGVzIGEgbW9kZWwgdG8gYWxsIG90aGVyIG1vZGVscy5cblxuXHRhbGwgZnVuY3Rpb25zIHRoYXQgYXJlIHJvdXRlZCBoYXZlIGEgcHJvcGVydHkgYC5jb252ZXJzaW9uYCBhdHRhY2hlZFxuXHR0byB0aGUgcmV0dXJuZWQgc3ludGhldGljIGZ1bmN0aW9uLiBUaGlzIHByb3BlcnR5IGlzIGFuIGFycmF5XG5cdG9mIHN0cmluZ3MsIGVhY2ggd2l0aCB0aGUgc3RlcHMgaW4gYmV0d2VlbiB0aGUgJ2Zyb20nIGFuZCAndG8nXG5cdGNvbG9yIG1vZGVscyAoaW5jbHVzaXZlKS5cblxuXHRjb252ZXJzaW9ucyB0aGF0IGFyZSBub3QgcG9zc2libGUgc2ltcGx5IGFyZSBub3QgaW5jbHVkZWQuXG4qL1xuXG5mdW5jdGlvbiBidWlsZEdyYXBoKCkge1xuXHR2YXIgZ3JhcGggPSB7fTtcblx0Ly8gaHR0cHM6Ly9qc3BlcmYuY29tL29iamVjdC1rZXlzLXZzLWZvci1pbi13aXRoLWNsb3N1cmUvM1xuXHR2YXIgbW9kZWxzID0gT2JqZWN0LmtleXMoY29udmVyc2lvbnMpO1xuXG5cdGZvciAodmFyIGxlbiA9IG1vZGVscy5sZW5ndGgsIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcblx0XHRncmFwaFttb2RlbHNbaV1dID0ge1xuXHRcdFx0Ly8gaHR0cDovL2pzcGVyZi5jb20vMS12cy1pbmZpbml0eVxuXHRcdFx0Ly8gbWljcm8tb3B0LCBidXQgdGhpcyBpcyBzaW1wbGUuXG5cdFx0XHRkaXN0YW5jZTogLTEsXG5cdFx0XHRwYXJlbnQ6IG51bGxcblx0XHR9O1xuXHR9XG5cblx0cmV0dXJuIGdyYXBoO1xufVxuXG4vLyBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9CcmVhZHRoLWZpcnN0X3NlYXJjaFxuZnVuY3Rpb24gZGVyaXZlQkZTKGZyb21Nb2RlbCkge1xuXHR2YXIgZ3JhcGggPSBidWlsZEdyYXBoKCk7XG5cdHZhciBxdWV1ZSA9IFtmcm9tTW9kZWxdOyAvLyB1bnNoaWZ0IC0+IHF1ZXVlIC0+IHBvcFxuXG5cdGdyYXBoW2Zyb21Nb2RlbF0uZGlzdGFuY2UgPSAwO1xuXG5cdHdoaWxlIChxdWV1ZS5sZW5ndGgpIHtcblx0XHR2YXIgY3VycmVudCA9IHF1ZXVlLnBvcCgpO1xuXHRcdHZhciBhZGphY2VudHMgPSBPYmplY3Qua2V5cyhjb252ZXJzaW9uc1tjdXJyZW50XSk7XG5cblx0XHRmb3IgKHZhciBsZW4gPSBhZGphY2VudHMubGVuZ3RoLCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG5cdFx0XHR2YXIgYWRqYWNlbnQgPSBhZGphY2VudHNbaV07XG5cdFx0XHR2YXIgbm9kZSA9IGdyYXBoW2FkamFjZW50XTtcblxuXHRcdFx0aWYgKG5vZGUuZGlzdGFuY2UgPT09IC0xKSB7XG5cdFx0XHRcdG5vZGUuZGlzdGFuY2UgPSBncmFwaFtjdXJyZW50XS5kaXN0YW5jZSArIDE7XG5cdFx0XHRcdG5vZGUucGFyZW50ID0gY3VycmVudDtcblx0XHRcdFx0cXVldWUudW5zaGlmdChhZGphY2VudCk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIGdyYXBoO1xufVxuXG5mdW5jdGlvbiBsaW5rKGZyb20sIHRvKSB7XG5cdHJldHVybiBmdW5jdGlvbiAoYXJncykge1xuXHRcdHJldHVybiB0byhmcm9tKGFyZ3MpKTtcblx0fTtcbn1cblxuZnVuY3Rpb24gd3JhcENvbnZlcnNpb24odG9Nb2RlbCwgZ3JhcGgpIHtcblx0dmFyIHBhdGggPSBbZ3JhcGhbdG9Nb2RlbF0ucGFyZW50LCB0b01vZGVsXTtcblx0dmFyIGZuID0gY29udmVyc2lvbnNbZ3JhcGhbdG9Nb2RlbF0ucGFyZW50XVt0b01vZGVsXTtcblxuXHR2YXIgY3VyID0gZ3JhcGhbdG9Nb2RlbF0ucGFyZW50O1xuXHR3aGlsZSAoZ3JhcGhbY3VyXS5wYXJlbnQpIHtcblx0XHRwYXRoLnVuc2hpZnQoZ3JhcGhbY3VyXS5wYXJlbnQpO1xuXHRcdGZuID0gbGluayhjb252ZXJzaW9uc1tncmFwaFtjdXJdLnBhcmVudF1bY3VyXSwgZm4pO1xuXHRcdGN1ciA9IGdyYXBoW2N1cl0ucGFyZW50O1xuXHR9XG5cblx0Zm4uY29udmVyc2lvbiA9IHBhdGg7XG5cdHJldHVybiBmbjtcbn1cblxudmFyIHJvdXRlID0gZnVuY3Rpb24gKGZyb21Nb2RlbCkge1xuXHR2YXIgZ3JhcGggPSBkZXJpdmVCRlMoZnJvbU1vZGVsKTtcblx0dmFyIGNvbnZlcnNpb24gPSB7fTtcblxuXHR2YXIgbW9kZWxzID0gT2JqZWN0LmtleXMoZ3JhcGgpO1xuXHRmb3IgKHZhciBsZW4gPSBtb2RlbHMubGVuZ3RoLCBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG5cdFx0dmFyIHRvTW9kZWwgPSBtb2RlbHNbaV07XG5cdFx0dmFyIG5vZGUgPSBncmFwaFt0b01vZGVsXTtcblxuXHRcdGlmIChub2RlLnBhcmVudCA9PT0gbnVsbCkge1xuXHRcdFx0Ly8gbm8gcG9zc2libGUgY29udmVyc2lvbiwgb3IgdGhpcyBub2RlIGlzIHRoZSBzb3VyY2UgbW9kZWwuXG5cdFx0XHRjb250aW51ZTtcblx0XHR9XG5cblx0XHRjb252ZXJzaW9uW3RvTW9kZWxdID0gd3JhcENvbnZlcnNpb24odG9Nb2RlbCwgZ3JhcGgpO1xuXHR9XG5cblx0cmV0dXJuIGNvbnZlcnNpb247XG59O1xuXG52YXIgY29udmVydCA9IHt9O1xuXG52YXIgbW9kZWxzID0gT2JqZWN0LmtleXMoY29udmVyc2lvbnMpO1xuXG5mdW5jdGlvbiB3cmFwUmF3KGZuKSB7XG5cdHZhciB3cmFwcGVkRm4gPSBmdW5jdGlvbiAoYXJncykge1xuXHRcdGlmIChhcmdzID09PSB1bmRlZmluZWQgfHwgYXJncyA9PT0gbnVsbCkge1xuXHRcdFx0cmV0dXJuIGFyZ3M7XG5cdFx0fVxuXG5cdFx0aWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG5cdFx0XHRhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gZm4oYXJncyk7XG5cdH07XG5cblx0Ly8gcHJlc2VydmUgLmNvbnZlcnNpb24gcHJvcGVydHkgaWYgdGhlcmUgaXMgb25lXG5cdGlmICgnY29udmVyc2lvbicgaW4gZm4pIHtcblx0XHR3cmFwcGVkRm4uY29udmVyc2lvbiA9IGZuLmNvbnZlcnNpb247XG5cdH1cblxuXHRyZXR1cm4gd3JhcHBlZEZuO1xufVxuXG5mdW5jdGlvbiB3cmFwUm91bmRlZChmbikge1xuXHR2YXIgd3JhcHBlZEZuID0gZnVuY3Rpb24gKGFyZ3MpIHtcblx0XHRpZiAoYXJncyA9PT0gdW5kZWZpbmVkIHx8IGFyZ3MgPT09IG51bGwpIHtcblx0XHRcdHJldHVybiBhcmdzO1xuXHRcdH1cblxuXHRcdGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuXHRcdFx0YXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cyk7XG5cdFx0fVxuXG5cdFx0dmFyIHJlc3VsdCA9IGZuKGFyZ3MpO1xuXG5cdFx0Ly8gd2UncmUgYXNzdW1pbmcgdGhlIHJlc3VsdCBpcyBhbiBhcnJheSBoZXJlLlxuXHRcdC8vIHNlZSBub3RpY2UgaW4gY29udmVyc2lvbnMuanM7IGRvbid0IHVzZSBib3ggdHlwZXNcblx0XHQvLyBpbiBjb252ZXJzaW9uIGZ1bmN0aW9ucy5cblx0XHRpZiAodHlwZW9mIHJlc3VsdCA9PT0gJ29iamVjdCcpIHtcblx0XHRcdGZvciAodmFyIGxlbiA9IHJlc3VsdC5sZW5ndGgsIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcblx0XHRcdFx0cmVzdWx0W2ldID0gTWF0aC5yb3VuZChyZXN1bHRbaV0pO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiByZXN1bHQ7XG5cdH07XG5cblx0Ly8gcHJlc2VydmUgLmNvbnZlcnNpb24gcHJvcGVydHkgaWYgdGhlcmUgaXMgb25lXG5cdGlmICgnY29udmVyc2lvbicgaW4gZm4pIHtcblx0XHR3cmFwcGVkRm4uY29udmVyc2lvbiA9IGZuLmNvbnZlcnNpb247XG5cdH1cblxuXHRyZXR1cm4gd3JhcHBlZEZuO1xufVxuXG5tb2RlbHMuZm9yRWFjaChmdW5jdGlvbiAoZnJvbU1vZGVsKSB7XG5cdGNvbnZlcnRbZnJvbU1vZGVsXSA9IHt9O1xuXG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjb252ZXJ0W2Zyb21Nb2RlbF0sICdjaGFubmVscycsIHt2YWx1ZTogY29udmVyc2lvbnNbZnJvbU1vZGVsXS5jaGFubmVsc30pO1xuXHRPYmplY3QuZGVmaW5lUHJvcGVydHkoY29udmVydFtmcm9tTW9kZWxdLCAnbGFiZWxzJywge3ZhbHVlOiBjb252ZXJzaW9uc1tmcm9tTW9kZWxdLmxhYmVsc30pO1xuXG5cdHZhciByb3V0ZXMgPSByb3V0ZShmcm9tTW9kZWwpO1xuXHR2YXIgcm91dGVNb2RlbHMgPSBPYmplY3Qua2V5cyhyb3V0ZXMpO1xuXG5cdHJvdXRlTW9kZWxzLmZvckVhY2goZnVuY3Rpb24gKHRvTW9kZWwpIHtcblx0XHR2YXIgZm4gPSByb3V0ZXNbdG9Nb2RlbF07XG5cblx0XHRjb252ZXJ0W2Zyb21Nb2RlbF1bdG9Nb2RlbF0gPSB3cmFwUm91bmRlZChmbik7XG5cdFx0Y29udmVydFtmcm9tTW9kZWxdW3RvTW9kZWxdLnJhdyA9IHdyYXBSYXcoZm4pO1xuXHR9KTtcbn0pO1xuXG52YXIgY29sb3JDb252ZXJ0ID0gY29udmVydDtcblxudmFyIGNvbG9yTmFtZSQxID0ge1xyXG5cdFwiYWxpY2VibHVlXCI6IFsyNDAsIDI0OCwgMjU1XSxcclxuXHRcImFudGlxdWV3aGl0ZVwiOiBbMjUwLCAyMzUsIDIxNV0sXHJcblx0XCJhcXVhXCI6IFswLCAyNTUsIDI1NV0sXHJcblx0XCJhcXVhbWFyaW5lXCI6IFsxMjcsIDI1NSwgMjEyXSxcclxuXHRcImF6dXJlXCI6IFsyNDAsIDI1NSwgMjU1XSxcclxuXHRcImJlaWdlXCI6IFsyNDUsIDI0NSwgMjIwXSxcclxuXHRcImJpc3F1ZVwiOiBbMjU1LCAyMjgsIDE5Nl0sXHJcblx0XCJibGFja1wiOiBbMCwgMCwgMF0sXHJcblx0XCJibGFuY2hlZGFsbW9uZFwiOiBbMjU1LCAyMzUsIDIwNV0sXHJcblx0XCJibHVlXCI6IFswLCAwLCAyNTVdLFxyXG5cdFwiYmx1ZXZpb2xldFwiOiBbMTM4LCA0MywgMjI2XSxcclxuXHRcImJyb3duXCI6IFsxNjUsIDQyLCA0Ml0sXHJcblx0XCJidXJseXdvb2RcIjogWzIyMiwgMTg0LCAxMzVdLFxyXG5cdFwiY2FkZXRibHVlXCI6IFs5NSwgMTU4LCAxNjBdLFxyXG5cdFwiY2hhcnRyZXVzZVwiOiBbMTI3LCAyNTUsIDBdLFxyXG5cdFwiY2hvY29sYXRlXCI6IFsyMTAsIDEwNSwgMzBdLFxyXG5cdFwiY29yYWxcIjogWzI1NSwgMTI3LCA4MF0sXHJcblx0XCJjb3JuZmxvd2VyYmx1ZVwiOiBbMTAwLCAxNDksIDIzN10sXHJcblx0XCJjb3Juc2lsa1wiOiBbMjU1LCAyNDgsIDIyMF0sXHJcblx0XCJjcmltc29uXCI6IFsyMjAsIDIwLCA2MF0sXHJcblx0XCJjeWFuXCI6IFswLCAyNTUsIDI1NV0sXHJcblx0XCJkYXJrYmx1ZVwiOiBbMCwgMCwgMTM5XSxcclxuXHRcImRhcmtjeWFuXCI6IFswLCAxMzksIDEzOV0sXHJcblx0XCJkYXJrZ29sZGVucm9kXCI6IFsxODQsIDEzNCwgMTFdLFxyXG5cdFwiZGFya2dyYXlcIjogWzE2OSwgMTY5LCAxNjldLFxyXG5cdFwiZGFya2dyZWVuXCI6IFswLCAxMDAsIDBdLFxyXG5cdFwiZGFya2dyZXlcIjogWzE2OSwgMTY5LCAxNjldLFxyXG5cdFwiZGFya2toYWtpXCI6IFsxODksIDE4MywgMTA3XSxcclxuXHRcImRhcmttYWdlbnRhXCI6IFsxMzksIDAsIDEzOV0sXHJcblx0XCJkYXJrb2xpdmVncmVlblwiOiBbODUsIDEwNywgNDddLFxyXG5cdFwiZGFya29yYW5nZVwiOiBbMjU1LCAxNDAsIDBdLFxyXG5cdFwiZGFya29yY2hpZFwiOiBbMTUzLCA1MCwgMjA0XSxcclxuXHRcImRhcmtyZWRcIjogWzEzOSwgMCwgMF0sXHJcblx0XCJkYXJrc2FsbW9uXCI6IFsyMzMsIDE1MCwgMTIyXSxcclxuXHRcImRhcmtzZWFncmVlblwiOiBbMTQzLCAxODgsIDE0M10sXHJcblx0XCJkYXJrc2xhdGVibHVlXCI6IFs3MiwgNjEsIDEzOV0sXHJcblx0XCJkYXJrc2xhdGVncmF5XCI6IFs0NywgNzksIDc5XSxcclxuXHRcImRhcmtzbGF0ZWdyZXlcIjogWzQ3LCA3OSwgNzldLFxyXG5cdFwiZGFya3R1cnF1b2lzZVwiOiBbMCwgMjA2LCAyMDldLFxyXG5cdFwiZGFya3Zpb2xldFwiOiBbMTQ4LCAwLCAyMTFdLFxyXG5cdFwiZGVlcHBpbmtcIjogWzI1NSwgMjAsIDE0N10sXHJcblx0XCJkZWVwc2t5Ymx1ZVwiOiBbMCwgMTkxLCAyNTVdLFxyXG5cdFwiZGltZ3JheVwiOiBbMTA1LCAxMDUsIDEwNV0sXHJcblx0XCJkaW1ncmV5XCI6IFsxMDUsIDEwNSwgMTA1XSxcclxuXHRcImRvZGdlcmJsdWVcIjogWzMwLCAxNDQsIDI1NV0sXHJcblx0XCJmaXJlYnJpY2tcIjogWzE3OCwgMzQsIDM0XSxcclxuXHRcImZsb3JhbHdoaXRlXCI6IFsyNTUsIDI1MCwgMjQwXSxcclxuXHRcImZvcmVzdGdyZWVuXCI6IFszNCwgMTM5LCAzNF0sXHJcblx0XCJmdWNoc2lhXCI6IFsyNTUsIDAsIDI1NV0sXHJcblx0XCJnYWluc2Jvcm9cIjogWzIyMCwgMjIwLCAyMjBdLFxyXG5cdFwiZ2hvc3R3aGl0ZVwiOiBbMjQ4LCAyNDgsIDI1NV0sXHJcblx0XCJnb2xkXCI6IFsyNTUsIDIxNSwgMF0sXHJcblx0XCJnb2xkZW5yb2RcIjogWzIxOCwgMTY1LCAzMl0sXHJcblx0XCJncmF5XCI6IFsxMjgsIDEyOCwgMTI4XSxcclxuXHRcImdyZWVuXCI6IFswLCAxMjgsIDBdLFxyXG5cdFwiZ3JlZW55ZWxsb3dcIjogWzE3MywgMjU1LCA0N10sXHJcblx0XCJncmV5XCI6IFsxMjgsIDEyOCwgMTI4XSxcclxuXHRcImhvbmV5ZGV3XCI6IFsyNDAsIDI1NSwgMjQwXSxcclxuXHRcImhvdHBpbmtcIjogWzI1NSwgMTA1LCAxODBdLFxyXG5cdFwiaW5kaWFucmVkXCI6IFsyMDUsIDkyLCA5Ml0sXHJcblx0XCJpbmRpZ29cIjogWzc1LCAwLCAxMzBdLFxyXG5cdFwiaXZvcnlcIjogWzI1NSwgMjU1LCAyNDBdLFxyXG5cdFwia2hha2lcIjogWzI0MCwgMjMwLCAxNDBdLFxyXG5cdFwibGF2ZW5kZXJcIjogWzIzMCwgMjMwLCAyNTBdLFxyXG5cdFwibGF2ZW5kZXJibHVzaFwiOiBbMjU1LCAyNDAsIDI0NV0sXHJcblx0XCJsYXduZ3JlZW5cIjogWzEyNCwgMjUyLCAwXSxcclxuXHRcImxlbW9uY2hpZmZvblwiOiBbMjU1LCAyNTAsIDIwNV0sXHJcblx0XCJsaWdodGJsdWVcIjogWzE3MywgMjE2LCAyMzBdLFxyXG5cdFwibGlnaHRjb3JhbFwiOiBbMjQwLCAxMjgsIDEyOF0sXHJcblx0XCJsaWdodGN5YW5cIjogWzIyNCwgMjU1LCAyNTVdLFxyXG5cdFwibGlnaHRnb2xkZW5yb2R5ZWxsb3dcIjogWzI1MCwgMjUwLCAyMTBdLFxyXG5cdFwibGlnaHRncmF5XCI6IFsyMTEsIDIxMSwgMjExXSxcclxuXHRcImxpZ2h0Z3JlZW5cIjogWzE0NCwgMjM4LCAxNDRdLFxyXG5cdFwibGlnaHRncmV5XCI6IFsyMTEsIDIxMSwgMjExXSxcclxuXHRcImxpZ2h0cGlua1wiOiBbMjU1LCAxODIsIDE5M10sXHJcblx0XCJsaWdodHNhbG1vblwiOiBbMjU1LCAxNjAsIDEyMl0sXHJcblx0XCJsaWdodHNlYWdyZWVuXCI6IFszMiwgMTc4LCAxNzBdLFxyXG5cdFwibGlnaHRza3libHVlXCI6IFsxMzUsIDIwNiwgMjUwXSxcclxuXHRcImxpZ2h0c2xhdGVncmF5XCI6IFsxMTksIDEzNiwgMTUzXSxcclxuXHRcImxpZ2h0c2xhdGVncmV5XCI6IFsxMTksIDEzNiwgMTUzXSxcclxuXHRcImxpZ2h0c3RlZWxibHVlXCI6IFsxNzYsIDE5NiwgMjIyXSxcclxuXHRcImxpZ2h0eWVsbG93XCI6IFsyNTUsIDI1NSwgMjI0XSxcclxuXHRcImxpbWVcIjogWzAsIDI1NSwgMF0sXHJcblx0XCJsaW1lZ3JlZW5cIjogWzUwLCAyMDUsIDUwXSxcclxuXHRcImxpbmVuXCI6IFsyNTAsIDI0MCwgMjMwXSxcclxuXHRcIm1hZ2VudGFcIjogWzI1NSwgMCwgMjU1XSxcclxuXHRcIm1hcm9vblwiOiBbMTI4LCAwLCAwXSxcclxuXHRcIm1lZGl1bWFxdWFtYXJpbmVcIjogWzEwMiwgMjA1LCAxNzBdLFxyXG5cdFwibWVkaXVtYmx1ZVwiOiBbMCwgMCwgMjA1XSxcclxuXHRcIm1lZGl1bW9yY2hpZFwiOiBbMTg2LCA4NSwgMjExXSxcclxuXHRcIm1lZGl1bXB1cnBsZVwiOiBbMTQ3LCAxMTIsIDIxOV0sXHJcblx0XCJtZWRpdW1zZWFncmVlblwiOiBbNjAsIDE3OSwgMTEzXSxcclxuXHRcIm1lZGl1bXNsYXRlYmx1ZVwiOiBbMTIzLCAxMDQsIDIzOF0sXHJcblx0XCJtZWRpdW1zcHJpbmdncmVlblwiOiBbMCwgMjUwLCAxNTRdLFxyXG5cdFwibWVkaXVtdHVycXVvaXNlXCI6IFs3MiwgMjA5LCAyMDRdLFxyXG5cdFwibWVkaXVtdmlvbGV0cmVkXCI6IFsxOTksIDIxLCAxMzNdLFxyXG5cdFwibWlkbmlnaHRibHVlXCI6IFsyNSwgMjUsIDExMl0sXHJcblx0XCJtaW50Y3JlYW1cIjogWzI0NSwgMjU1LCAyNTBdLFxyXG5cdFwibWlzdHlyb3NlXCI6IFsyNTUsIDIyOCwgMjI1XSxcclxuXHRcIm1vY2Nhc2luXCI6IFsyNTUsIDIyOCwgMTgxXSxcclxuXHRcIm5hdmFqb3doaXRlXCI6IFsyNTUsIDIyMiwgMTczXSxcclxuXHRcIm5hdnlcIjogWzAsIDAsIDEyOF0sXHJcblx0XCJvbGRsYWNlXCI6IFsyNTMsIDI0NSwgMjMwXSxcclxuXHRcIm9saXZlXCI6IFsxMjgsIDEyOCwgMF0sXHJcblx0XCJvbGl2ZWRyYWJcIjogWzEwNywgMTQyLCAzNV0sXHJcblx0XCJvcmFuZ2VcIjogWzI1NSwgMTY1LCAwXSxcclxuXHRcIm9yYW5nZXJlZFwiOiBbMjU1LCA2OSwgMF0sXHJcblx0XCJvcmNoaWRcIjogWzIxOCwgMTEyLCAyMTRdLFxyXG5cdFwicGFsZWdvbGRlbnJvZFwiOiBbMjM4LCAyMzIsIDE3MF0sXHJcblx0XCJwYWxlZ3JlZW5cIjogWzE1MiwgMjUxLCAxNTJdLFxyXG5cdFwicGFsZXR1cnF1b2lzZVwiOiBbMTc1LCAyMzgsIDIzOF0sXHJcblx0XCJwYWxldmlvbGV0cmVkXCI6IFsyMTksIDExMiwgMTQ3XSxcclxuXHRcInBhcGF5YXdoaXBcIjogWzI1NSwgMjM5LCAyMTNdLFxyXG5cdFwicGVhY2hwdWZmXCI6IFsyNTUsIDIxOCwgMTg1XSxcclxuXHRcInBlcnVcIjogWzIwNSwgMTMzLCA2M10sXHJcblx0XCJwaW5rXCI6IFsyNTUsIDE5MiwgMjAzXSxcclxuXHRcInBsdW1cIjogWzIyMSwgMTYwLCAyMjFdLFxyXG5cdFwicG93ZGVyYmx1ZVwiOiBbMTc2LCAyMjQsIDIzMF0sXHJcblx0XCJwdXJwbGVcIjogWzEyOCwgMCwgMTI4XSxcclxuXHRcInJlYmVjY2FwdXJwbGVcIjogWzEwMiwgNTEsIDE1M10sXHJcblx0XCJyZWRcIjogWzI1NSwgMCwgMF0sXHJcblx0XCJyb3N5YnJvd25cIjogWzE4OCwgMTQzLCAxNDNdLFxyXG5cdFwicm95YWxibHVlXCI6IFs2NSwgMTA1LCAyMjVdLFxyXG5cdFwic2FkZGxlYnJvd25cIjogWzEzOSwgNjksIDE5XSxcclxuXHRcInNhbG1vblwiOiBbMjUwLCAxMjgsIDExNF0sXHJcblx0XCJzYW5keWJyb3duXCI6IFsyNDQsIDE2NCwgOTZdLFxyXG5cdFwic2VhZ3JlZW5cIjogWzQ2LCAxMzksIDg3XSxcclxuXHRcInNlYXNoZWxsXCI6IFsyNTUsIDI0NSwgMjM4XSxcclxuXHRcInNpZW5uYVwiOiBbMTYwLCA4MiwgNDVdLFxyXG5cdFwic2lsdmVyXCI6IFsxOTIsIDE5MiwgMTkyXSxcclxuXHRcInNreWJsdWVcIjogWzEzNSwgMjA2LCAyMzVdLFxyXG5cdFwic2xhdGVibHVlXCI6IFsxMDYsIDkwLCAyMDVdLFxyXG5cdFwic2xhdGVncmF5XCI6IFsxMTIsIDEyOCwgMTQ0XSxcclxuXHRcInNsYXRlZ3JleVwiOiBbMTEyLCAxMjgsIDE0NF0sXHJcblx0XCJzbm93XCI6IFsyNTUsIDI1MCwgMjUwXSxcclxuXHRcInNwcmluZ2dyZWVuXCI6IFswLCAyNTUsIDEyN10sXHJcblx0XCJzdGVlbGJsdWVcIjogWzcwLCAxMzAsIDE4MF0sXHJcblx0XCJ0YW5cIjogWzIxMCwgMTgwLCAxNDBdLFxyXG5cdFwidGVhbFwiOiBbMCwgMTI4LCAxMjhdLFxyXG5cdFwidGhpc3RsZVwiOiBbMjE2LCAxOTEsIDIxNl0sXHJcblx0XCJ0b21hdG9cIjogWzI1NSwgOTksIDcxXSxcclxuXHRcInR1cnF1b2lzZVwiOiBbNjQsIDIyNCwgMjA4XSxcclxuXHRcInZpb2xldFwiOiBbMjM4LCAxMzAsIDIzOF0sXHJcblx0XCJ3aGVhdFwiOiBbMjQ1LCAyMjIsIDE3OV0sXHJcblx0XCJ3aGl0ZVwiOiBbMjU1LCAyNTUsIDI1NV0sXHJcblx0XCJ3aGl0ZXNtb2tlXCI6IFsyNDUsIDI0NSwgMjQ1XSxcclxuXHRcInllbGxvd1wiOiBbMjU1LCAyNTUsIDBdLFxyXG5cdFwieWVsbG93Z3JlZW5cIjogWzE1NCwgMjA1LCA1MF1cclxufTtcblxuLyogTUlUIGxpY2Vuc2UgKi9cblxuXG52YXIgY29sb3JTdHJpbmcgPSB7XG4gICBnZXRSZ2JhOiBnZXRSZ2JhLFxuICAgZ2V0SHNsYTogZ2V0SHNsYSxcbiAgIGdldFJnYjogZ2V0UmdiLFxuICAgZ2V0SHNsOiBnZXRIc2wsXG4gICBnZXRId2I6IGdldEh3YixcbiAgIGdldEFscGhhOiBnZXRBbHBoYSxcblxuICAgaGV4U3RyaW5nOiBoZXhTdHJpbmcsXG4gICByZ2JTdHJpbmc6IHJnYlN0cmluZyxcbiAgIHJnYmFTdHJpbmc6IHJnYmFTdHJpbmcsXG4gICBwZXJjZW50U3RyaW5nOiBwZXJjZW50U3RyaW5nLFxuICAgcGVyY2VudGFTdHJpbmc6IHBlcmNlbnRhU3RyaW5nLFxuICAgaHNsU3RyaW5nOiBoc2xTdHJpbmcsXG4gICBoc2xhU3RyaW5nOiBoc2xhU3RyaW5nLFxuICAgaHdiU3RyaW5nOiBod2JTdHJpbmcsXG4gICBrZXl3b3JkOiBrZXl3b3JkXG59O1xuXG5mdW5jdGlvbiBnZXRSZ2JhKHN0cmluZykge1xuICAgaWYgKCFzdHJpbmcpIHtcbiAgICAgIHJldHVybjtcbiAgIH1cbiAgIHZhciBhYmJyID0gIC9eIyhbYS1mQS1GMC05XXszLDR9KSQvaSxcbiAgICAgICBoZXggPSAgL14jKFthLWZBLUYwLTldezZ9KFthLWZBLUYwLTldezJ9KT8pJC9pLFxuICAgICAgIHJnYmEgPSAvXnJnYmE/XFwoXFxzKihbKy1dP1xcZCspXFxzKixcXHMqKFsrLV0/XFxkKylcXHMqLFxccyooWystXT9cXGQrKVxccyooPzosXFxzKihbKy1dP1tcXGRcXC5dKylcXHMqKT9cXCkkL2ksXG4gICAgICAgcGVyID0gL15yZ2JhP1xcKFxccyooWystXT9bXFxkXFwuXSspXFwlXFxzKixcXHMqKFsrLV0/W1xcZFxcLl0rKVxcJVxccyosXFxzKihbKy1dP1tcXGRcXC5dKylcXCVcXHMqKD86LFxccyooWystXT9bXFxkXFwuXSspXFxzKik/XFwpJC9pLFxuICAgICAgIGtleXdvcmQgPSAvKFxcdyspLztcblxuICAgdmFyIHJnYiA9IFswLCAwLCAwXSxcbiAgICAgICBhID0gMSxcbiAgICAgICBtYXRjaCA9IHN0cmluZy5tYXRjaChhYmJyKSxcbiAgICAgICBoZXhBbHBoYSA9IFwiXCI7XG4gICBpZiAobWF0Y2gpIHtcbiAgICAgIG1hdGNoID0gbWF0Y2hbMV07XG4gICAgICBoZXhBbHBoYSA9IG1hdGNoWzNdO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCByZ2IubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgIHJnYltpXSA9IHBhcnNlSW50KG1hdGNoW2ldICsgbWF0Y2hbaV0sIDE2KTtcbiAgICAgIH1cbiAgICAgIGlmIChoZXhBbHBoYSkge1xuICAgICAgICAgYSA9IE1hdGgucm91bmQoKHBhcnNlSW50KGhleEFscGhhICsgaGV4QWxwaGEsIDE2KSAvIDI1NSkgKiAxMDApIC8gMTAwO1xuICAgICAgfVxuICAgfVxuICAgZWxzZSBpZiAobWF0Y2ggPSBzdHJpbmcubWF0Y2goaGV4KSkge1xuICAgICAgaGV4QWxwaGEgPSBtYXRjaFsyXTtcbiAgICAgIG1hdGNoID0gbWF0Y2hbMV07XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJnYi5sZW5ndGg7IGkrKykge1xuICAgICAgICAgcmdiW2ldID0gcGFyc2VJbnQobWF0Y2guc2xpY2UoaSAqIDIsIGkgKiAyICsgMiksIDE2KTtcbiAgICAgIH1cbiAgICAgIGlmIChoZXhBbHBoYSkge1xuICAgICAgICAgYSA9IE1hdGgucm91bmQoKHBhcnNlSW50KGhleEFscGhhLCAxNikgLyAyNTUpICogMTAwKSAvIDEwMDtcbiAgICAgIH1cbiAgIH1cbiAgIGVsc2UgaWYgKG1hdGNoID0gc3RyaW5nLm1hdGNoKHJnYmEpKSB7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJnYi5sZW5ndGg7IGkrKykge1xuICAgICAgICAgcmdiW2ldID0gcGFyc2VJbnQobWF0Y2hbaSArIDFdKTtcbiAgICAgIH1cbiAgICAgIGEgPSBwYXJzZUZsb2F0KG1hdGNoWzRdKTtcbiAgIH1cbiAgIGVsc2UgaWYgKG1hdGNoID0gc3RyaW5nLm1hdGNoKHBlcikpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmdiLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICByZ2JbaV0gPSBNYXRoLnJvdW5kKHBhcnNlRmxvYXQobWF0Y2hbaSArIDFdKSAqIDIuNTUpO1xuICAgICAgfVxuICAgICAgYSA9IHBhcnNlRmxvYXQobWF0Y2hbNF0pO1xuICAgfVxuICAgZWxzZSBpZiAobWF0Y2ggPSBzdHJpbmcubWF0Y2goa2V5d29yZCkpIHtcbiAgICAgIGlmIChtYXRjaFsxXSA9PSBcInRyYW5zcGFyZW50XCIpIHtcbiAgICAgICAgIHJldHVybiBbMCwgMCwgMCwgMF07XG4gICAgICB9XG4gICAgICByZ2IgPSBjb2xvck5hbWUkMVttYXRjaFsxXV07XG4gICAgICBpZiAoIXJnYikge1xuICAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgfVxuXG4gICBmb3IgKHZhciBpID0gMDsgaSA8IHJnYi5sZW5ndGg7IGkrKykge1xuICAgICAgcmdiW2ldID0gc2NhbGUocmdiW2ldLCAwLCAyNTUpO1xuICAgfVxuICAgaWYgKCFhICYmIGEgIT0gMCkge1xuICAgICAgYSA9IDE7XG4gICB9XG4gICBlbHNlIHtcbiAgICAgIGEgPSBzY2FsZShhLCAwLCAxKTtcbiAgIH1cbiAgIHJnYlszXSA9IGE7XG4gICByZXR1cm4gcmdiO1xufVxuXG5mdW5jdGlvbiBnZXRIc2xhKHN0cmluZykge1xuICAgaWYgKCFzdHJpbmcpIHtcbiAgICAgIHJldHVybjtcbiAgIH1cbiAgIHZhciBoc2wgPSAvXmhzbGE/XFwoXFxzKihbKy1dP1xcZCspKD86ZGVnKT9cXHMqLFxccyooWystXT9bXFxkXFwuXSspJVxccyosXFxzKihbKy1dP1tcXGRcXC5dKyklXFxzKig/OixcXHMqKFsrLV0/W1xcZFxcLl0rKVxccyopP1xcKS87XG4gICB2YXIgbWF0Y2ggPSBzdHJpbmcubWF0Y2goaHNsKTtcbiAgIGlmIChtYXRjaCkge1xuICAgICAgdmFyIGFscGhhID0gcGFyc2VGbG9hdChtYXRjaFs0XSk7XG4gICAgICB2YXIgaCA9IHNjYWxlKHBhcnNlSW50KG1hdGNoWzFdKSwgMCwgMzYwKSxcbiAgICAgICAgICBzID0gc2NhbGUocGFyc2VGbG9hdChtYXRjaFsyXSksIDAsIDEwMCksXG4gICAgICAgICAgbCA9IHNjYWxlKHBhcnNlRmxvYXQobWF0Y2hbM10pLCAwLCAxMDApLFxuICAgICAgICAgIGEgPSBzY2FsZShpc05hTihhbHBoYSkgPyAxIDogYWxwaGEsIDAsIDEpO1xuICAgICAgcmV0dXJuIFtoLCBzLCBsLCBhXTtcbiAgIH1cbn1cblxuZnVuY3Rpb24gZ2V0SHdiKHN0cmluZykge1xuICAgaWYgKCFzdHJpbmcpIHtcbiAgICAgIHJldHVybjtcbiAgIH1cbiAgIHZhciBod2IgPSAvXmh3YlxcKFxccyooWystXT9cXGQrKSg/OmRlZyk/XFxzKixcXHMqKFsrLV0/W1xcZFxcLl0rKSVcXHMqLFxccyooWystXT9bXFxkXFwuXSspJVxccyooPzosXFxzKihbKy1dP1tcXGRcXC5dKylcXHMqKT9cXCkvO1xuICAgdmFyIG1hdGNoID0gc3RyaW5nLm1hdGNoKGh3Yik7XG4gICBpZiAobWF0Y2gpIHtcbiAgICB2YXIgYWxwaGEgPSBwYXJzZUZsb2F0KG1hdGNoWzRdKTtcbiAgICAgIHZhciBoID0gc2NhbGUocGFyc2VJbnQobWF0Y2hbMV0pLCAwLCAzNjApLFxuICAgICAgICAgIHcgPSBzY2FsZShwYXJzZUZsb2F0KG1hdGNoWzJdKSwgMCwgMTAwKSxcbiAgICAgICAgICBiID0gc2NhbGUocGFyc2VGbG9hdChtYXRjaFszXSksIDAsIDEwMCksXG4gICAgICAgICAgYSA9IHNjYWxlKGlzTmFOKGFscGhhKSA/IDEgOiBhbHBoYSwgMCwgMSk7XG4gICAgICByZXR1cm4gW2gsIHcsIGIsIGFdO1xuICAgfVxufVxuXG5mdW5jdGlvbiBnZXRSZ2Ioc3RyaW5nKSB7XG4gICB2YXIgcmdiYSA9IGdldFJnYmEoc3RyaW5nKTtcbiAgIHJldHVybiByZ2JhICYmIHJnYmEuc2xpY2UoMCwgMyk7XG59XG5cbmZ1bmN0aW9uIGdldEhzbChzdHJpbmcpIHtcbiAgdmFyIGhzbGEgPSBnZXRIc2xhKHN0cmluZyk7XG4gIHJldHVybiBoc2xhICYmIGhzbGEuc2xpY2UoMCwgMyk7XG59XG5cbmZ1bmN0aW9uIGdldEFscGhhKHN0cmluZykge1xuICAgdmFyIHZhbHMgPSBnZXRSZ2JhKHN0cmluZyk7XG4gICBpZiAodmFscykge1xuICAgICAgcmV0dXJuIHZhbHNbM107XG4gICB9XG4gICBlbHNlIGlmICh2YWxzID0gZ2V0SHNsYShzdHJpbmcpKSB7XG4gICAgICByZXR1cm4gdmFsc1szXTtcbiAgIH1cbiAgIGVsc2UgaWYgKHZhbHMgPSBnZXRId2Ioc3RyaW5nKSkge1xuICAgICAgcmV0dXJuIHZhbHNbM107XG4gICB9XG59XG5cbi8vIGdlbmVyYXRvcnNcbmZ1bmN0aW9uIGhleFN0cmluZyhyZ2JhLCBhKSB7XG4gICB2YXIgYSA9IChhICE9PSB1bmRlZmluZWQgJiYgcmdiYS5sZW5ndGggPT09IDMpID8gYSA6IHJnYmFbM107XG4gICByZXR1cm4gXCIjXCIgKyBoZXhEb3VibGUocmdiYVswXSkgXG4gICAgICAgICAgICAgICsgaGV4RG91YmxlKHJnYmFbMV0pXG4gICAgICAgICAgICAgICsgaGV4RG91YmxlKHJnYmFbMl0pXG4gICAgICAgICAgICAgICsgKFxuICAgICAgICAgICAgICAgICAoYSA+PSAwICYmIGEgPCAxKVxuICAgICAgICAgICAgICAgICA/IGhleERvdWJsZShNYXRoLnJvdW5kKGEgKiAyNTUpKVxuICAgICAgICAgICAgICAgICA6IFwiXCJcbiAgICAgICAgICAgICAgKTtcbn1cblxuZnVuY3Rpb24gcmdiU3RyaW5nKHJnYmEsIGFscGhhKSB7XG4gICBpZiAoYWxwaGEgPCAxIHx8IChyZ2JhWzNdICYmIHJnYmFbM10gPCAxKSkge1xuICAgICAgcmV0dXJuIHJnYmFTdHJpbmcocmdiYSwgYWxwaGEpO1xuICAgfVxuICAgcmV0dXJuIFwicmdiKFwiICsgcmdiYVswXSArIFwiLCBcIiArIHJnYmFbMV0gKyBcIiwgXCIgKyByZ2JhWzJdICsgXCIpXCI7XG59XG5cbmZ1bmN0aW9uIHJnYmFTdHJpbmcocmdiYSwgYWxwaGEpIHtcbiAgIGlmIChhbHBoYSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBhbHBoYSA9IChyZ2JhWzNdICE9PSB1bmRlZmluZWQgPyByZ2JhWzNdIDogMSk7XG4gICB9XG4gICByZXR1cm4gXCJyZ2JhKFwiICsgcmdiYVswXSArIFwiLCBcIiArIHJnYmFbMV0gKyBcIiwgXCIgKyByZ2JhWzJdXG4gICAgICAgICAgICsgXCIsIFwiICsgYWxwaGEgKyBcIilcIjtcbn1cblxuZnVuY3Rpb24gcGVyY2VudFN0cmluZyhyZ2JhLCBhbHBoYSkge1xuICAgaWYgKGFscGhhIDwgMSB8fCAocmdiYVszXSAmJiByZ2JhWzNdIDwgMSkpIHtcbiAgICAgIHJldHVybiBwZXJjZW50YVN0cmluZyhyZ2JhLCBhbHBoYSk7XG4gICB9XG4gICB2YXIgciA9IE1hdGgucm91bmQocmdiYVswXS8yNTUgKiAxMDApLFxuICAgICAgIGcgPSBNYXRoLnJvdW5kKHJnYmFbMV0vMjU1ICogMTAwKSxcbiAgICAgICBiID0gTWF0aC5yb3VuZChyZ2JhWzJdLzI1NSAqIDEwMCk7XG5cbiAgIHJldHVybiBcInJnYihcIiArIHIgKyBcIiUsIFwiICsgZyArIFwiJSwgXCIgKyBiICsgXCIlKVwiO1xufVxuXG5mdW5jdGlvbiBwZXJjZW50YVN0cmluZyhyZ2JhLCBhbHBoYSkge1xuICAgdmFyIHIgPSBNYXRoLnJvdW5kKHJnYmFbMF0vMjU1ICogMTAwKSxcbiAgICAgICBnID0gTWF0aC5yb3VuZChyZ2JhWzFdLzI1NSAqIDEwMCksXG4gICAgICAgYiA9IE1hdGgucm91bmQocmdiYVsyXS8yNTUgKiAxMDApO1xuICAgcmV0dXJuIFwicmdiYShcIiArIHIgKyBcIiUsIFwiICsgZyArIFwiJSwgXCIgKyBiICsgXCIlLCBcIiArIChhbHBoYSB8fCByZ2JhWzNdIHx8IDEpICsgXCIpXCI7XG59XG5cbmZ1bmN0aW9uIGhzbFN0cmluZyhoc2xhLCBhbHBoYSkge1xuICAgaWYgKGFscGhhIDwgMSB8fCAoaHNsYVszXSAmJiBoc2xhWzNdIDwgMSkpIHtcbiAgICAgIHJldHVybiBoc2xhU3RyaW5nKGhzbGEsIGFscGhhKTtcbiAgIH1cbiAgIHJldHVybiBcImhzbChcIiArIGhzbGFbMF0gKyBcIiwgXCIgKyBoc2xhWzFdICsgXCIlLCBcIiArIGhzbGFbMl0gKyBcIiUpXCI7XG59XG5cbmZ1bmN0aW9uIGhzbGFTdHJpbmcoaHNsYSwgYWxwaGEpIHtcbiAgIGlmIChhbHBoYSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBhbHBoYSA9IChoc2xhWzNdICE9PSB1bmRlZmluZWQgPyBoc2xhWzNdIDogMSk7XG4gICB9XG4gICByZXR1cm4gXCJoc2xhKFwiICsgaHNsYVswXSArIFwiLCBcIiArIGhzbGFbMV0gKyBcIiUsIFwiICsgaHNsYVsyXSArIFwiJSwgXCJcbiAgICAgICAgICAgKyBhbHBoYSArIFwiKVwiO1xufVxuXG4vLyBod2IgaXMgYSBiaXQgZGlmZmVyZW50IHRoYW4gcmdiKGEpICYgaHNsKGEpIHNpbmNlIHRoZXJlIGlzIG5vIGFscGhhIHNwZWNpZmljIHN5bnRheFxuLy8gKGh3YiBoYXZlIGFscGhhIG9wdGlvbmFsICYgMSBpcyBkZWZhdWx0IHZhbHVlKVxuZnVuY3Rpb24gaHdiU3RyaW5nKGh3YiwgYWxwaGEpIHtcbiAgIGlmIChhbHBoYSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBhbHBoYSA9IChod2JbM10gIT09IHVuZGVmaW5lZCA/IGh3YlszXSA6IDEpO1xuICAgfVxuICAgcmV0dXJuIFwiaHdiKFwiICsgaHdiWzBdICsgXCIsIFwiICsgaHdiWzFdICsgXCIlLCBcIiArIGh3YlsyXSArIFwiJVwiXG4gICAgICAgICAgICsgKGFscGhhICE9PSB1bmRlZmluZWQgJiYgYWxwaGEgIT09IDEgPyBcIiwgXCIgKyBhbHBoYSA6IFwiXCIpICsgXCIpXCI7XG59XG5cbmZ1bmN0aW9uIGtleXdvcmQocmdiKSB7XG4gIHJldHVybiByZXZlcnNlTmFtZXNbcmdiLnNsaWNlKDAsIDMpXTtcbn1cblxuLy8gaGVscGVyc1xuZnVuY3Rpb24gc2NhbGUobnVtLCBtaW4sIG1heCkge1xuICAgcmV0dXJuIE1hdGgubWluKE1hdGgubWF4KG1pbiwgbnVtKSwgbWF4KTtcbn1cblxuZnVuY3Rpb24gaGV4RG91YmxlKG51bSkge1xuICB2YXIgc3RyID0gbnVtLnRvU3RyaW5nKDE2KS50b1VwcGVyQ2FzZSgpO1xuICByZXR1cm4gKHN0ci5sZW5ndGggPCAyKSA/IFwiMFwiICsgc3RyIDogc3RyO1xufVxuXG5cbi8vY3JlYXRlIGEgbGlzdCBvZiByZXZlcnNlIGNvbG9yIG5hbWVzXG52YXIgcmV2ZXJzZU5hbWVzID0ge307XG5mb3IgKHZhciBuYW1lIGluIGNvbG9yTmFtZSQxKSB7XG4gICByZXZlcnNlTmFtZXNbY29sb3JOYW1lJDFbbmFtZV1dID0gbmFtZTtcbn1cblxuLyogTUlUIGxpY2Vuc2UgKi9cblxuXG5cbnZhciBDb2xvciA9IGZ1bmN0aW9uIChvYmopIHtcblx0aWYgKG9iaiBpbnN0YW5jZW9mIENvbG9yKSB7XG5cdFx0cmV0dXJuIG9iajtcblx0fVxuXHRpZiAoISh0aGlzIGluc3RhbmNlb2YgQ29sb3IpKSB7XG5cdFx0cmV0dXJuIG5ldyBDb2xvcihvYmopO1xuXHR9XG5cblx0dGhpcy52YWxpZCA9IGZhbHNlO1xuXHR0aGlzLnZhbHVlcyA9IHtcblx0XHRyZ2I6IFswLCAwLCAwXSxcblx0XHRoc2w6IFswLCAwLCAwXSxcblx0XHRoc3Y6IFswLCAwLCAwXSxcblx0XHRod2I6IFswLCAwLCAwXSxcblx0XHRjbXlrOiBbMCwgMCwgMCwgMF0sXG5cdFx0YWxwaGE6IDFcblx0fTtcblxuXHQvLyBwYXJzZSBDb2xvcigpIGFyZ3VtZW50XG5cdHZhciB2YWxzO1xuXHRpZiAodHlwZW9mIG9iaiA9PT0gJ3N0cmluZycpIHtcblx0XHR2YWxzID0gY29sb3JTdHJpbmcuZ2V0UmdiYShvYmopO1xuXHRcdGlmICh2YWxzKSB7XG5cdFx0XHR0aGlzLnNldFZhbHVlcygncmdiJywgdmFscyk7XG5cdFx0fSBlbHNlIGlmICh2YWxzID0gY29sb3JTdHJpbmcuZ2V0SHNsYShvYmopKSB7XG5cdFx0XHR0aGlzLnNldFZhbHVlcygnaHNsJywgdmFscyk7XG5cdFx0fSBlbHNlIGlmICh2YWxzID0gY29sb3JTdHJpbmcuZ2V0SHdiKG9iaikpIHtcblx0XHRcdHRoaXMuc2V0VmFsdWVzKCdod2InLCB2YWxzKTtcblx0XHR9XG5cdH0gZWxzZSBpZiAodHlwZW9mIG9iaiA9PT0gJ29iamVjdCcpIHtcblx0XHR2YWxzID0gb2JqO1xuXHRcdGlmICh2YWxzLnIgIT09IHVuZGVmaW5lZCB8fCB2YWxzLnJlZCAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0XHR0aGlzLnNldFZhbHVlcygncmdiJywgdmFscyk7XG5cdFx0fSBlbHNlIGlmICh2YWxzLmwgIT09IHVuZGVmaW5lZCB8fCB2YWxzLmxpZ2h0bmVzcyAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0XHR0aGlzLnNldFZhbHVlcygnaHNsJywgdmFscyk7XG5cdFx0fSBlbHNlIGlmICh2YWxzLnYgIT09IHVuZGVmaW5lZCB8fCB2YWxzLnZhbHVlICE9PSB1bmRlZmluZWQpIHtcblx0XHRcdHRoaXMuc2V0VmFsdWVzKCdoc3YnLCB2YWxzKTtcblx0XHR9IGVsc2UgaWYgKHZhbHMudyAhPT0gdW5kZWZpbmVkIHx8IHZhbHMud2hpdGVuZXNzICE9PSB1bmRlZmluZWQpIHtcblx0XHRcdHRoaXMuc2V0VmFsdWVzKCdod2InLCB2YWxzKTtcblx0XHR9IGVsc2UgaWYgKHZhbHMuYyAhPT0gdW5kZWZpbmVkIHx8IHZhbHMuY3lhbiAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0XHR0aGlzLnNldFZhbHVlcygnY215aycsIHZhbHMpO1xuXHRcdH1cblx0fVxufTtcblxuQ29sb3IucHJvdG90eXBlID0ge1xuXHRpc1ZhbGlkOiBmdW5jdGlvbiAoKSB7XG5cdFx0cmV0dXJuIHRoaXMudmFsaWQ7XG5cdH0sXG5cdHJnYjogZnVuY3Rpb24gKCkge1xuXHRcdHJldHVybiB0aGlzLnNldFNwYWNlKCdyZ2InLCBhcmd1bWVudHMpO1xuXHR9LFxuXHRoc2w6IGZ1bmN0aW9uICgpIHtcblx0XHRyZXR1cm4gdGhpcy5zZXRTcGFjZSgnaHNsJywgYXJndW1lbnRzKTtcblx0fSxcblx0aHN2OiBmdW5jdGlvbiAoKSB7XG5cdFx0cmV0dXJuIHRoaXMuc2V0U3BhY2UoJ2hzdicsIGFyZ3VtZW50cyk7XG5cdH0sXG5cdGh3YjogZnVuY3Rpb24gKCkge1xuXHRcdHJldHVybiB0aGlzLnNldFNwYWNlKCdod2InLCBhcmd1bWVudHMpO1xuXHR9LFxuXHRjbXlrOiBmdW5jdGlvbiAoKSB7XG5cdFx0cmV0dXJuIHRoaXMuc2V0U3BhY2UoJ2NteWsnLCBhcmd1bWVudHMpO1xuXHR9LFxuXG5cdHJnYkFycmF5OiBmdW5jdGlvbiAoKSB7XG5cdFx0cmV0dXJuIHRoaXMudmFsdWVzLnJnYjtcblx0fSxcblx0aHNsQXJyYXk6IGZ1bmN0aW9uICgpIHtcblx0XHRyZXR1cm4gdGhpcy52YWx1ZXMuaHNsO1xuXHR9LFxuXHRoc3ZBcnJheTogZnVuY3Rpb24gKCkge1xuXHRcdHJldHVybiB0aGlzLnZhbHVlcy5oc3Y7XG5cdH0sXG5cdGh3YkFycmF5OiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIHZhbHVlcyA9IHRoaXMudmFsdWVzO1xuXHRcdGlmICh2YWx1ZXMuYWxwaGEgIT09IDEpIHtcblx0XHRcdHJldHVybiB2YWx1ZXMuaHdiLmNvbmNhdChbdmFsdWVzLmFscGhhXSk7XG5cdFx0fVxuXHRcdHJldHVybiB2YWx1ZXMuaHdiO1xuXHR9LFxuXHRjbXlrQXJyYXk6IGZ1bmN0aW9uICgpIHtcblx0XHRyZXR1cm4gdGhpcy52YWx1ZXMuY215aztcblx0fSxcblx0cmdiYUFycmF5OiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIHZhbHVlcyA9IHRoaXMudmFsdWVzO1xuXHRcdHJldHVybiB2YWx1ZXMucmdiLmNvbmNhdChbdmFsdWVzLmFscGhhXSk7XG5cdH0sXG5cdGhzbGFBcnJheTogZnVuY3Rpb24gKCkge1xuXHRcdHZhciB2YWx1ZXMgPSB0aGlzLnZhbHVlcztcblx0XHRyZXR1cm4gdmFsdWVzLmhzbC5jb25jYXQoW3ZhbHVlcy5hbHBoYV0pO1xuXHR9LFxuXHRhbHBoYTogZnVuY3Rpb24gKHZhbCkge1xuXHRcdGlmICh2YWwgPT09IHVuZGVmaW5lZCkge1xuXHRcdFx0cmV0dXJuIHRoaXMudmFsdWVzLmFscGhhO1xuXHRcdH1cblx0XHR0aGlzLnNldFZhbHVlcygnYWxwaGEnLCB2YWwpO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9LFxuXG5cdHJlZDogZnVuY3Rpb24gKHZhbCkge1xuXHRcdHJldHVybiB0aGlzLnNldENoYW5uZWwoJ3JnYicsIDAsIHZhbCk7XG5cdH0sXG5cdGdyZWVuOiBmdW5jdGlvbiAodmFsKSB7XG5cdFx0cmV0dXJuIHRoaXMuc2V0Q2hhbm5lbCgncmdiJywgMSwgdmFsKTtcblx0fSxcblx0Ymx1ZTogZnVuY3Rpb24gKHZhbCkge1xuXHRcdHJldHVybiB0aGlzLnNldENoYW5uZWwoJ3JnYicsIDIsIHZhbCk7XG5cdH0sXG5cdGh1ZTogZnVuY3Rpb24gKHZhbCkge1xuXHRcdGlmICh2YWwpIHtcblx0XHRcdHZhbCAlPSAzNjA7XG5cdFx0XHR2YWwgPSB2YWwgPCAwID8gMzYwICsgdmFsIDogdmFsO1xuXHRcdH1cblx0XHRyZXR1cm4gdGhpcy5zZXRDaGFubmVsKCdoc2wnLCAwLCB2YWwpO1xuXHR9LFxuXHRzYXR1cmF0aW9uOiBmdW5jdGlvbiAodmFsKSB7XG5cdFx0cmV0dXJuIHRoaXMuc2V0Q2hhbm5lbCgnaHNsJywgMSwgdmFsKTtcblx0fSxcblx0bGlnaHRuZXNzOiBmdW5jdGlvbiAodmFsKSB7XG5cdFx0cmV0dXJuIHRoaXMuc2V0Q2hhbm5lbCgnaHNsJywgMiwgdmFsKTtcblx0fSxcblx0c2F0dXJhdGlvbnY6IGZ1bmN0aW9uICh2YWwpIHtcblx0XHRyZXR1cm4gdGhpcy5zZXRDaGFubmVsKCdoc3YnLCAxLCB2YWwpO1xuXHR9LFxuXHR3aGl0ZW5lc3M6IGZ1bmN0aW9uICh2YWwpIHtcblx0XHRyZXR1cm4gdGhpcy5zZXRDaGFubmVsKCdod2InLCAxLCB2YWwpO1xuXHR9LFxuXHRibGFja25lc3M6IGZ1bmN0aW9uICh2YWwpIHtcblx0XHRyZXR1cm4gdGhpcy5zZXRDaGFubmVsKCdod2InLCAyLCB2YWwpO1xuXHR9LFxuXHR2YWx1ZTogZnVuY3Rpb24gKHZhbCkge1xuXHRcdHJldHVybiB0aGlzLnNldENoYW5uZWwoJ2hzdicsIDIsIHZhbCk7XG5cdH0sXG5cdGN5YW46IGZ1bmN0aW9uICh2YWwpIHtcblx0XHRyZXR1cm4gdGhpcy5zZXRDaGFubmVsKCdjbXlrJywgMCwgdmFsKTtcblx0fSxcblx0bWFnZW50YTogZnVuY3Rpb24gKHZhbCkge1xuXHRcdHJldHVybiB0aGlzLnNldENoYW5uZWwoJ2NteWsnLCAxLCB2YWwpO1xuXHR9LFxuXHR5ZWxsb3c6IGZ1bmN0aW9uICh2YWwpIHtcblx0XHRyZXR1cm4gdGhpcy5zZXRDaGFubmVsKCdjbXlrJywgMiwgdmFsKTtcblx0fSxcblx0YmxhY2s6IGZ1bmN0aW9uICh2YWwpIHtcblx0XHRyZXR1cm4gdGhpcy5zZXRDaGFubmVsKCdjbXlrJywgMywgdmFsKTtcblx0fSxcblxuXHRoZXhTdHJpbmc6IGZ1bmN0aW9uICgpIHtcblx0XHRyZXR1cm4gY29sb3JTdHJpbmcuaGV4U3RyaW5nKHRoaXMudmFsdWVzLnJnYik7XG5cdH0sXG5cdHJnYlN0cmluZzogZnVuY3Rpb24gKCkge1xuXHRcdHJldHVybiBjb2xvclN0cmluZy5yZ2JTdHJpbmcodGhpcy52YWx1ZXMucmdiLCB0aGlzLnZhbHVlcy5hbHBoYSk7XG5cdH0sXG5cdHJnYmFTdHJpbmc6IGZ1bmN0aW9uICgpIHtcblx0XHRyZXR1cm4gY29sb3JTdHJpbmcucmdiYVN0cmluZyh0aGlzLnZhbHVlcy5yZ2IsIHRoaXMudmFsdWVzLmFscGhhKTtcblx0fSxcblx0cGVyY2VudFN0cmluZzogZnVuY3Rpb24gKCkge1xuXHRcdHJldHVybiBjb2xvclN0cmluZy5wZXJjZW50U3RyaW5nKHRoaXMudmFsdWVzLnJnYiwgdGhpcy52YWx1ZXMuYWxwaGEpO1xuXHR9LFxuXHRoc2xTdHJpbmc6IGZ1bmN0aW9uICgpIHtcblx0XHRyZXR1cm4gY29sb3JTdHJpbmcuaHNsU3RyaW5nKHRoaXMudmFsdWVzLmhzbCwgdGhpcy52YWx1ZXMuYWxwaGEpO1xuXHR9LFxuXHRoc2xhU3RyaW5nOiBmdW5jdGlvbiAoKSB7XG5cdFx0cmV0dXJuIGNvbG9yU3RyaW5nLmhzbGFTdHJpbmcodGhpcy52YWx1ZXMuaHNsLCB0aGlzLnZhbHVlcy5hbHBoYSk7XG5cdH0sXG5cdGh3YlN0cmluZzogZnVuY3Rpb24gKCkge1xuXHRcdHJldHVybiBjb2xvclN0cmluZy5od2JTdHJpbmcodGhpcy52YWx1ZXMuaHdiLCB0aGlzLnZhbHVlcy5hbHBoYSk7XG5cdH0sXG5cdGtleXdvcmQ6IGZ1bmN0aW9uICgpIHtcblx0XHRyZXR1cm4gY29sb3JTdHJpbmcua2V5d29yZCh0aGlzLnZhbHVlcy5yZ2IsIHRoaXMudmFsdWVzLmFscGhhKTtcblx0fSxcblxuXHRyZ2JOdW1iZXI6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgcmdiID0gdGhpcy52YWx1ZXMucmdiO1xuXHRcdHJldHVybiAocmdiWzBdIDw8IDE2KSB8IChyZ2JbMV0gPDwgOCkgfCByZ2JbMl07XG5cdH0sXG5cblx0bHVtaW5vc2l0eTogZnVuY3Rpb24gKCkge1xuXHRcdC8vIGh0dHA6Ly93d3cudzMub3JnL1RSL1dDQUcyMC8jcmVsYXRpdmVsdW1pbmFuY2VkZWZcblx0XHR2YXIgcmdiID0gdGhpcy52YWx1ZXMucmdiO1xuXHRcdHZhciBsdW0gPSBbXTtcblx0XHRmb3IgKHZhciBpID0gMDsgaSA8IHJnYi5sZW5ndGg7IGkrKykge1xuXHRcdFx0dmFyIGNoYW4gPSByZ2JbaV0gLyAyNTU7XG5cdFx0XHRsdW1baV0gPSAoY2hhbiA8PSAwLjAzOTI4KSA/IGNoYW4gLyAxMi45MiA6IE1hdGgucG93KCgoY2hhbiArIDAuMDU1KSAvIDEuMDU1KSwgMi40KTtcblx0XHR9XG5cdFx0cmV0dXJuIDAuMjEyNiAqIGx1bVswXSArIDAuNzE1MiAqIGx1bVsxXSArIDAuMDcyMiAqIGx1bVsyXTtcblx0fSxcblxuXHRjb250cmFzdDogZnVuY3Rpb24gKGNvbG9yMikge1xuXHRcdC8vIGh0dHA6Ly93d3cudzMub3JnL1RSL1dDQUcyMC8jY29udHJhc3QtcmF0aW9kZWZcblx0XHR2YXIgbHVtMSA9IHRoaXMubHVtaW5vc2l0eSgpO1xuXHRcdHZhciBsdW0yID0gY29sb3IyLmx1bWlub3NpdHkoKTtcblx0XHRpZiAobHVtMSA+IGx1bTIpIHtcblx0XHRcdHJldHVybiAobHVtMSArIDAuMDUpIC8gKGx1bTIgKyAwLjA1KTtcblx0XHR9XG5cdFx0cmV0dXJuIChsdW0yICsgMC4wNSkgLyAobHVtMSArIDAuMDUpO1xuXHR9LFxuXG5cdGxldmVsOiBmdW5jdGlvbiAoY29sb3IyKSB7XG5cdFx0dmFyIGNvbnRyYXN0UmF0aW8gPSB0aGlzLmNvbnRyYXN0KGNvbG9yMik7XG5cdFx0aWYgKGNvbnRyYXN0UmF0aW8gPj0gNy4xKSB7XG5cdFx0XHRyZXR1cm4gJ0FBQSc7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIChjb250cmFzdFJhdGlvID49IDQuNSkgPyAnQUEnIDogJyc7XG5cdH0sXG5cblx0ZGFyazogZnVuY3Rpb24gKCkge1xuXHRcdC8vIFlJUSBlcXVhdGlvbiBmcm9tIGh0dHA6Ly8yNHdheXMub3JnLzIwMTAvY2FsY3VsYXRpbmctY29sb3ItY29udHJhc3Rcblx0XHR2YXIgcmdiID0gdGhpcy52YWx1ZXMucmdiO1xuXHRcdHZhciB5aXEgPSAocmdiWzBdICogMjk5ICsgcmdiWzFdICogNTg3ICsgcmdiWzJdICogMTE0KSAvIDEwMDA7XG5cdFx0cmV0dXJuIHlpcSA8IDEyODtcblx0fSxcblxuXHRsaWdodDogZnVuY3Rpb24gKCkge1xuXHRcdHJldHVybiAhdGhpcy5kYXJrKCk7XG5cdH0sXG5cblx0bmVnYXRlOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIHJnYiA9IFtdO1xuXHRcdGZvciAodmFyIGkgPSAwOyBpIDwgMzsgaSsrKSB7XG5cdFx0XHRyZ2JbaV0gPSAyNTUgLSB0aGlzLnZhbHVlcy5yZ2JbaV07XG5cdFx0fVxuXHRcdHRoaXMuc2V0VmFsdWVzKCdyZ2InLCByZ2IpO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9LFxuXG5cdGxpZ2h0ZW46IGZ1bmN0aW9uIChyYXRpbykge1xuXHRcdHZhciBoc2wgPSB0aGlzLnZhbHVlcy5oc2w7XG5cdFx0aHNsWzJdICs9IGhzbFsyXSAqIHJhdGlvO1xuXHRcdHRoaXMuc2V0VmFsdWVzKCdoc2wnLCBoc2wpO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9LFxuXG5cdGRhcmtlbjogZnVuY3Rpb24gKHJhdGlvKSB7XG5cdFx0dmFyIGhzbCA9IHRoaXMudmFsdWVzLmhzbDtcblx0XHRoc2xbMl0gLT0gaHNsWzJdICogcmF0aW87XG5cdFx0dGhpcy5zZXRWYWx1ZXMoJ2hzbCcsIGhzbCk7XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH0sXG5cblx0c2F0dXJhdGU6IGZ1bmN0aW9uIChyYXRpbykge1xuXHRcdHZhciBoc2wgPSB0aGlzLnZhbHVlcy5oc2w7XG5cdFx0aHNsWzFdICs9IGhzbFsxXSAqIHJhdGlvO1xuXHRcdHRoaXMuc2V0VmFsdWVzKCdoc2wnLCBoc2wpO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9LFxuXG5cdGRlc2F0dXJhdGU6IGZ1bmN0aW9uIChyYXRpbykge1xuXHRcdHZhciBoc2wgPSB0aGlzLnZhbHVlcy5oc2w7XG5cdFx0aHNsWzFdIC09IGhzbFsxXSAqIHJhdGlvO1xuXHRcdHRoaXMuc2V0VmFsdWVzKCdoc2wnLCBoc2wpO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9LFxuXG5cdHdoaXRlbjogZnVuY3Rpb24gKHJhdGlvKSB7XG5cdFx0dmFyIGh3YiA9IHRoaXMudmFsdWVzLmh3Yjtcblx0XHRod2JbMV0gKz0gaHdiWzFdICogcmF0aW87XG5cdFx0dGhpcy5zZXRWYWx1ZXMoJ2h3YicsIGh3Yik7XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH0sXG5cblx0YmxhY2tlbjogZnVuY3Rpb24gKHJhdGlvKSB7XG5cdFx0dmFyIGh3YiA9IHRoaXMudmFsdWVzLmh3Yjtcblx0XHRod2JbMl0gKz0gaHdiWzJdICogcmF0aW87XG5cdFx0dGhpcy5zZXRWYWx1ZXMoJ2h3YicsIGh3Yik7XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH0sXG5cblx0Z3JleXNjYWxlOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIHJnYiA9IHRoaXMudmFsdWVzLnJnYjtcblx0XHQvLyBodHRwOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0dyYXlzY2FsZSNDb252ZXJ0aW5nX2NvbG9yX3RvX2dyYXlzY2FsZVxuXHRcdHZhciB2YWwgPSByZ2JbMF0gKiAwLjMgKyByZ2JbMV0gKiAwLjU5ICsgcmdiWzJdICogMC4xMTtcblx0XHR0aGlzLnNldFZhbHVlcygncmdiJywgW3ZhbCwgdmFsLCB2YWxdKTtcblx0XHRyZXR1cm4gdGhpcztcblx0fSxcblxuXHRjbGVhcmVyOiBmdW5jdGlvbiAocmF0aW8pIHtcblx0XHR2YXIgYWxwaGEgPSB0aGlzLnZhbHVlcy5hbHBoYTtcblx0XHR0aGlzLnNldFZhbHVlcygnYWxwaGEnLCBhbHBoYSAtIChhbHBoYSAqIHJhdGlvKSk7XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH0sXG5cblx0b3BhcXVlcjogZnVuY3Rpb24gKHJhdGlvKSB7XG5cdFx0dmFyIGFscGhhID0gdGhpcy52YWx1ZXMuYWxwaGE7XG5cdFx0dGhpcy5zZXRWYWx1ZXMoJ2FscGhhJywgYWxwaGEgKyAoYWxwaGEgKiByYXRpbykpO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9LFxuXG5cdHJvdGF0ZTogZnVuY3Rpb24gKGRlZ3JlZXMpIHtcblx0XHR2YXIgaHNsID0gdGhpcy52YWx1ZXMuaHNsO1xuXHRcdHZhciBodWUgPSAoaHNsWzBdICsgZGVncmVlcykgJSAzNjA7XG5cdFx0aHNsWzBdID0gaHVlIDwgMCA/IDM2MCArIGh1ZSA6IGh1ZTtcblx0XHR0aGlzLnNldFZhbHVlcygnaHNsJywgaHNsKTtcblx0XHRyZXR1cm4gdGhpcztcblx0fSxcblxuXHQvKipcblx0ICogUG9ydGVkIGZyb20gc2FzcyBpbXBsZW1lbnRhdGlvbiBpbiBDXG5cdCAqIGh0dHBzOi8vZ2l0aHViLmNvbS9zYXNzL2xpYnNhc3MvYmxvYi8wZTZiNGEyODUwMDkyMzU2YWEzZWNlMDdjNmIyNDlmMDIyMWNhY2VkL2Z1bmN0aW9ucy5jcHAjTDIwOVxuXHQgKi9cblx0bWl4OiBmdW5jdGlvbiAobWl4aW5Db2xvciwgd2VpZ2h0KSB7XG5cdFx0dmFyIGNvbG9yMSA9IHRoaXM7XG5cdFx0dmFyIGNvbG9yMiA9IG1peGluQ29sb3I7XG5cdFx0dmFyIHAgPSB3ZWlnaHQgPT09IHVuZGVmaW5lZCA/IDAuNSA6IHdlaWdodDtcblxuXHRcdHZhciB3ID0gMiAqIHAgLSAxO1xuXHRcdHZhciBhID0gY29sb3IxLmFscGhhKCkgLSBjb2xvcjIuYWxwaGEoKTtcblxuXHRcdHZhciB3MSA9ICgoKHcgKiBhID09PSAtMSkgPyB3IDogKHcgKyBhKSAvICgxICsgdyAqIGEpKSArIDEpIC8gMi4wO1xuXHRcdHZhciB3MiA9IDEgLSB3MTtcblxuXHRcdHJldHVybiB0aGlzXG5cdFx0XHQucmdiKFxuXHRcdFx0XHR3MSAqIGNvbG9yMS5yZWQoKSArIHcyICogY29sb3IyLnJlZCgpLFxuXHRcdFx0XHR3MSAqIGNvbG9yMS5ncmVlbigpICsgdzIgKiBjb2xvcjIuZ3JlZW4oKSxcblx0XHRcdFx0dzEgKiBjb2xvcjEuYmx1ZSgpICsgdzIgKiBjb2xvcjIuYmx1ZSgpXG5cdFx0XHQpXG5cdFx0XHQuYWxwaGEoY29sb3IxLmFscGhhKCkgKiBwICsgY29sb3IyLmFscGhhKCkgKiAoMSAtIHApKTtcblx0fSxcblxuXHR0b0pTT046IGZ1bmN0aW9uICgpIHtcblx0XHRyZXR1cm4gdGhpcy5yZ2IoKTtcblx0fSxcblxuXHRjbG9uZTogZnVuY3Rpb24gKCkge1xuXHRcdC8vIE5PVEUoU0IpOiB1c2luZyBub2RlLWNsb25lIGNyZWF0ZXMgYSBkZXBlbmRlbmN5IHRvIEJ1ZmZlciB3aGVuIHVzaW5nIGJyb3dzZXJpZnksXG5cdFx0Ly8gbWFraW5nIHRoZSBmaW5hbCBidWlsZCB3YXkgdG8gYmlnIHRvIGVtYmVkIGluIENoYXJ0LmpzLiBTbyBsZXQncyBkbyBpdCBtYW51YWxseSxcblx0XHQvLyBhc3N1bWluZyB0aGF0IHZhbHVlcyB0byBjbG9uZSBhcmUgMSBkaW1lbnNpb24gYXJyYXlzIGNvbnRhaW5pbmcgb25seSBudW1iZXJzLFxuXHRcdC8vIGV4Y2VwdCAnYWxwaGEnIHdoaWNoIGlzIGEgbnVtYmVyLlxuXHRcdHZhciByZXN1bHQgPSBuZXcgQ29sb3IoKTtcblx0XHR2YXIgc291cmNlID0gdGhpcy52YWx1ZXM7XG5cdFx0dmFyIHRhcmdldCA9IHJlc3VsdC52YWx1ZXM7XG5cdFx0dmFyIHZhbHVlLCB0eXBlO1xuXG5cdFx0Zm9yICh2YXIgcHJvcCBpbiBzb3VyY2UpIHtcblx0XHRcdGlmIChzb3VyY2UuaGFzT3duUHJvcGVydHkocHJvcCkpIHtcblx0XHRcdFx0dmFsdWUgPSBzb3VyY2VbcHJvcF07XG5cdFx0XHRcdHR5cGUgPSAoe30pLnRvU3RyaW5nLmNhbGwodmFsdWUpO1xuXHRcdFx0XHRpZiAodHlwZSA9PT0gJ1tvYmplY3QgQXJyYXldJykge1xuXHRcdFx0XHRcdHRhcmdldFtwcm9wXSA9IHZhbHVlLnNsaWNlKDApO1xuXHRcdFx0XHR9IGVsc2UgaWYgKHR5cGUgPT09ICdbb2JqZWN0IE51bWJlcl0nKSB7XG5cdFx0XHRcdFx0dGFyZ2V0W3Byb3BdID0gdmFsdWU7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0Y29uc29sZS5lcnJvcigndW5leHBlY3RlZCBjb2xvciB2YWx1ZTonLCB2YWx1ZSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gcmVzdWx0O1xuXHR9XG59O1xuXG5Db2xvci5wcm90b3R5cGUuc3BhY2VzID0ge1xuXHRyZ2I6IFsncmVkJywgJ2dyZWVuJywgJ2JsdWUnXSxcblx0aHNsOiBbJ2h1ZScsICdzYXR1cmF0aW9uJywgJ2xpZ2h0bmVzcyddLFxuXHRoc3Y6IFsnaHVlJywgJ3NhdHVyYXRpb24nLCAndmFsdWUnXSxcblx0aHdiOiBbJ2h1ZScsICd3aGl0ZW5lc3MnLCAnYmxhY2tuZXNzJ10sXG5cdGNteWs6IFsnY3lhbicsICdtYWdlbnRhJywgJ3llbGxvdycsICdibGFjayddXG59O1xuXG5Db2xvci5wcm90b3R5cGUubWF4ZXMgPSB7XG5cdHJnYjogWzI1NSwgMjU1LCAyNTVdLFxuXHRoc2w6IFszNjAsIDEwMCwgMTAwXSxcblx0aHN2OiBbMzYwLCAxMDAsIDEwMF0sXG5cdGh3YjogWzM2MCwgMTAwLCAxMDBdLFxuXHRjbXlrOiBbMTAwLCAxMDAsIDEwMCwgMTAwXVxufTtcblxuQ29sb3IucHJvdG90eXBlLmdldFZhbHVlcyA9IGZ1bmN0aW9uIChzcGFjZSkge1xuXHR2YXIgdmFsdWVzID0gdGhpcy52YWx1ZXM7XG5cdHZhciB2YWxzID0ge307XG5cblx0Zm9yICh2YXIgaSA9IDA7IGkgPCBzcGFjZS5sZW5ndGg7IGkrKykge1xuXHRcdHZhbHNbc3BhY2UuY2hhckF0KGkpXSA9IHZhbHVlc1tzcGFjZV1baV07XG5cdH1cblxuXHRpZiAodmFsdWVzLmFscGhhICE9PSAxKSB7XG5cdFx0dmFscy5hID0gdmFsdWVzLmFscGhhO1xuXHR9XG5cblx0Ly8ge3I6IDI1NSwgZzogMjU1LCBiOiAyNTUsIGE6IDAuNH1cblx0cmV0dXJuIHZhbHM7XG59O1xuXG5Db2xvci5wcm90b3R5cGUuc2V0VmFsdWVzID0gZnVuY3Rpb24gKHNwYWNlLCB2YWxzKSB7XG5cdHZhciB2YWx1ZXMgPSB0aGlzLnZhbHVlcztcblx0dmFyIHNwYWNlcyA9IHRoaXMuc3BhY2VzO1xuXHR2YXIgbWF4ZXMgPSB0aGlzLm1heGVzO1xuXHR2YXIgYWxwaGEgPSAxO1xuXHR2YXIgaTtcblxuXHR0aGlzLnZhbGlkID0gdHJ1ZTtcblxuXHRpZiAoc3BhY2UgPT09ICdhbHBoYScpIHtcblx0XHRhbHBoYSA9IHZhbHM7XG5cdH0gZWxzZSBpZiAodmFscy5sZW5ndGgpIHtcblx0XHQvLyBbMTAsIDEwLCAxMF1cblx0XHR2YWx1ZXNbc3BhY2VdID0gdmFscy5zbGljZSgwLCBzcGFjZS5sZW5ndGgpO1xuXHRcdGFscGhhID0gdmFsc1tzcGFjZS5sZW5ndGhdO1xuXHR9IGVsc2UgaWYgKHZhbHNbc3BhY2UuY2hhckF0KDApXSAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0Ly8ge3I6IDEwLCBnOiAxMCwgYjogMTB9XG5cdFx0Zm9yIChpID0gMDsgaSA8IHNwYWNlLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHR2YWx1ZXNbc3BhY2VdW2ldID0gdmFsc1tzcGFjZS5jaGFyQXQoaSldO1xuXHRcdH1cblxuXHRcdGFscGhhID0gdmFscy5hO1xuXHR9IGVsc2UgaWYgKHZhbHNbc3BhY2VzW3NwYWNlXVswXV0gIT09IHVuZGVmaW5lZCkge1xuXHRcdC8vIHtyZWQ6IDEwLCBncmVlbjogMTAsIGJsdWU6IDEwfVxuXHRcdHZhciBjaGFucyA9IHNwYWNlc1tzcGFjZV07XG5cblx0XHRmb3IgKGkgPSAwOyBpIDwgc3BhY2UubGVuZ3RoOyBpKyspIHtcblx0XHRcdHZhbHVlc1tzcGFjZV1baV0gPSB2YWxzW2NoYW5zW2ldXTtcblx0XHR9XG5cblx0XHRhbHBoYSA9IHZhbHMuYWxwaGE7XG5cdH1cblxuXHR2YWx1ZXMuYWxwaGEgPSBNYXRoLm1heCgwLCBNYXRoLm1pbigxLCAoYWxwaGEgPT09IHVuZGVmaW5lZCA/IHZhbHVlcy5hbHBoYSA6IGFscGhhKSkpO1xuXG5cdGlmIChzcGFjZSA9PT0gJ2FscGhhJykge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG5cdHZhciBjYXBwZWQ7XG5cblx0Ly8gY2FwIHZhbHVlcyBvZiB0aGUgc3BhY2UgcHJpb3IgY29udmVydGluZyBhbGwgdmFsdWVzXG5cdGZvciAoaSA9IDA7IGkgPCBzcGFjZS5sZW5ndGg7IGkrKykge1xuXHRcdGNhcHBlZCA9IE1hdGgubWF4KDAsIE1hdGgubWluKG1heGVzW3NwYWNlXVtpXSwgdmFsdWVzW3NwYWNlXVtpXSkpO1xuXHRcdHZhbHVlc1tzcGFjZV1baV0gPSBNYXRoLnJvdW5kKGNhcHBlZCk7XG5cdH1cblxuXHQvLyBjb252ZXJ0IHRvIGFsbCB0aGUgb3RoZXIgY29sb3Igc3BhY2VzXG5cdGZvciAodmFyIHNuYW1lIGluIHNwYWNlcykge1xuXHRcdGlmIChzbmFtZSAhPT0gc3BhY2UpIHtcblx0XHRcdHZhbHVlc1tzbmFtZV0gPSBjb2xvckNvbnZlcnRbc3BhY2VdW3NuYW1lXSh2YWx1ZXNbc3BhY2VdKTtcblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gdHJ1ZTtcbn07XG5cbkNvbG9yLnByb3RvdHlwZS5zZXRTcGFjZSA9IGZ1bmN0aW9uIChzcGFjZSwgYXJncykge1xuXHR2YXIgdmFscyA9IGFyZ3NbMF07XG5cblx0aWYgKHZhbHMgPT09IHVuZGVmaW5lZCkge1xuXHRcdC8vIGNvbG9yLnJnYigpXG5cdFx0cmV0dXJuIHRoaXMuZ2V0VmFsdWVzKHNwYWNlKTtcblx0fVxuXG5cdC8vIGNvbG9yLnJnYigxMCwgMTAsIDEwKVxuXHRpZiAodHlwZW9mIHZhbHMgPT09ICdudW1iZXInKSB7XG5cdFx0dmFscyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3MpO1xuXHR9XG5cblx0dGhpcy5zZXRWYWx1ZXMoc3BhY2UsIHZhbHMpO1xuXHRyZXR1cm4gdGhpcztcbn07XG5cbkNvbG9yLnByb3RvdHlwZS5zZXRDaGFubmVsID0gZnVuY3Rpb24gKHNwYWNlLCBpbmRleCwgdmFsKSB7XG5cdHZhciBzdmFsdWVzID0gdGhpcy52YWx1ZXNbc3BhY2VdO1xuXHRpZiAodmFsID09PSB1bmRlZmluZWQpIHtcblx0XHQvLyBjb2xvci5yZWQoKVxuXHRcdHJldHVybiBzdmFsdWVzW2luZGV4XTtcblx0fSBlbHNlIGlmICh2YWwgPT09IHN2YWx1ZXNbaW5kZXhdKSB7XG5cdFx0Ly8gY29sb3IucmVkKGNvbG9yLnJlZCgpKVxuXHRcdHJldHVybiB0aGlzO1xuXHR9XG5cblx0Ly8gY29sb3IucmVkKDEwMClcblx0c3ZhbHVlc1tpbmRleF0gPSB2YWw7XG5cdHRoaXMuc2V0VmFsdWVzKHNwYWNlLCBzdmFsdWVzKTtcblxuXHRyZXR1cm4gdGhpcztcbn07XG5cbmlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykge1xuXHR3aW5kb3cuQ29sb3IgPSBDb2xvcjtcbn1cblxudmFyIGNoYXJ0anNDb2xvciA9IENvbG9yO1xuXG5mdW5jdGlvbiBpc1ZhbGlkS2V5KGtleSkge1xyXG5cdHJldHVybiBbJ19fcHJvdG9fXycsICdwcm90b3R5cGUnLCAnY29uc3RydWN0b3InXS5pbmRleE9mKGtleSkgPT09IC0xO1xyXG59XHJcblxyXG4vKipcclxuICogQG5hbWVzcGFjZSBDaGFydC5oZWxwZXJzXHJcbiAqL1xyXG52YXIgaGVscGVycyA9IHtcclxuXHQvKipcclxuXHQgKiBBbiBlbXB0eSBmdW5jdGlvbiB0aGF0IGNhbiBiZSB1c2VkLCBmb3IgZXhhbXBsZSwgZm9yIG9wdGlvbmFsIGNhbGxiYWNrLlxyXG5cdCAqL1xyXG5cdG5vb3A6IGZ1bmN0aW9uKCkge30sXHJcblxyXG5cdC8qKlxyXG5cdCAqIFJldHVybnMgYSB1bmlxdWUgaWQsIHNlcXVlbnRpYWxseSBnZW5lcmF0ZWQgZnJvbSBhIGdsb2JhbCB2YXJpYWJsZS5cclxuXHQgKiBAcmV0dXJucyB7bnVtYmVyfVxyXG5cdCAqIEBmdW5jdGlvblxyXG5cdCAqL1xyXG5cdHVpZDogKGZ1bmN0aW9uKCkge1xyXG5cdFx0dmFyIGlkID0gMDtcclxuXHRcdHJldHVybiBmdW5jdGlvbigpIHtcclxuXHRcdFx0cmV0dXJuIGlkKys7XHJcblx0XHR9O1xyXG5cdH0oKSksXHJcblxyXG5cdC8qKlxyXG5cdCAqIFJldHVybnMgdHJ1ZSBpZiBgdmFsdWVgIGlzIG5laXRoZXIgbnVsbCBub3IgdW5kZWZpbmVkLCBlbHNlIHJldHVybnMgZmFsc2UuXHJcblx0ICogQHBhcmFtIHsqfSB2YWx1ZSAtIFRoZSB2YWx1ZSB0byB0ZXN0LlxyXG5cdCAqIEByZXR1cm5zIHtib29sZWFufVxyXG5cdCAqIEBzaW5jZSAyLjcuMFxyXG5cdCAqL1xyXG5cdGlzTnVsbE9yVW5kZWY6IGZ1bmN0aW9uKHZhbHVlKSB7XHJcblx0XHRyZXR1cm4gdmFsdWUgPT09IG51bGwgfHwgdHlwZW9mIHZhbHVlID09PSAndW5kZWZpbmVkJztcclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBSZXR1cm5zIHRydWUgaWYgYHZhbHVlYCBpcyBhbiBhcnJheSAoaW5jbHVkaW5nIHR5cGVkIGFycmF5cyksIGVsc2UgcmV0dXJucyBmYWxzZS5cclxuXHQgKiBAcGFyYW0geyp9IHZhbHVlIC0gVGhlIHZhbHVlIHRvIHRlc3QuXHJcblx0ICogQHJldHVybnMge2Jvb2xlYW59XHJcblx0ICogQGZ1bmN0aW9uXHJcblx0ICovXHJcblx0aXNBcnJheTogZnVuY3Rpb24odmFsdWUpIHtcclxuXHRcdGlmIChBcnJheS5pc0FycmF5ICYmIEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XHJcblx0XHRcdHJldHVybiB0cnVlO1xyXG5cdFx0fVxyXG5cdFx0dmFyIHR5cGUgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpO1xyXG5cdFx0aWYgKHR5cGUuc3Vic3RyKDAsIDcpID09PSAnW29iamVjdCcgJiYgdHlwZS5zdWJzdHIoLTYpID09PSAnQXJyYXldJykge1xyXG5cdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdH1cclxuXHRcdHJldHVybiBmYWxzZTtcclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBSZXR1cm5zIHRydWUgaWYgYHZhbHVlYCBpcyBhbiBvYmplY3QgKGV4Y2x1ZGluZyBudWxsKSwgZWxzZSByZXR1cm5zIGZhbHNlLlxyXG5cdCAqIEBwYXJhbSB7Kn0gdmFsdWUgLSBUaGUgdmFsdWUgdG8gdGVzdC5cclxuXHQgKiBAcmV0dXJucyB7Ym9vbGVhbn1cclxuXHQgKiBAc2luY2UgMi43LjBcclxuXHQgKi9cclxuXHRpc09iamVjdDogZnVuY3Rpb24odmFsdWUpIHtcclxuXHRcdHJldHVybiB2YWx1ZSAhPT0gbnVsbCAmJiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpID09PSAnW29iamVjdCBPYmplY3RdJztcclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBSZXR1cm5zIHRydWUgaWYgYHZhbHVlYCBpcyBhIGZpbml0ZSBudW1iZXIsIGVsc2UgcmV0dXJucyBmYWxzZVxyXG5cdCAqIEBwYXJhbSB7Kn0gdmFsdWUgIC0gVGhlIHZhbHVlIHRvIHRlc3QuXHJcblx0ICogQHJldHVybnMge2Jvb2xlYW59XHJcblx0ICovXHJcblx0aXNGaW5pdGU6IGZ1bmN0aW9uKHZhbHVlKSB7XHJcblx0XHRyZXR1cm4gKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicgfHwgdmFsdWUgaW5zdGFuY2VvZiBOdW1iZXIpICYmIGlzRmluaXRlKHZhbHVlKTtcclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBSZXR1cm5zIGB2YWx1ZWAgaWYgZGVmaW5lZCwgZWxzZSByZXR1cm5zIGBkZWZhdWx0VmFsdWVgLlxyXG5cdCAqIEBwYXJhbSB7Kn0gdmFsdWUgLSBUaGUgdmFsdWUgdG8gcmV0dXJuIGlmIGRlZmluZWQuXHJcblx0ICogQHBhcmFtIHsqfSBkZWZhdWx0VmFsdWUgLSBUaGUgdmFsdWUgdG8gcmV0dXJuIGlmIGB2YWx1ZWAgaXMgdW5kZWZpbmVkLlxyXG5cdCAqIEByZXR1cm5zIHsqfVxyXG5cdCAqL1xyXG5cdHZhbHVlT3JEZWZhdWx0OiBmdW5jdGlvbih2YWx1ZSwgZGVmYXVsdFZhbHVlKSB7XHJcblx0XHRyZXR1cm4gdHlwZW9mIHZhbHVlID09PSAndW5kZWZpbmVkJyA/IGRlZmF1bHRWYWx1ZSA6IHZhbHVlO1xyXG5cdH0sXHJcblxyXG5cdC8qKlxyXG5cdCAqIFJldHVybnMgdmFsdWUgYXQgdGhlIGdpdmVuIGBpbmRleGAgaW4gYXJyYXkgaWYgZGVmaW5lZCwgZWxzZSByZXR1cm5zIGBkZWZhdWx0VmFsdWVgLlxyXG5cdCAqIEBwYXJhbSB7QXJyYXl9IHZhbHVlIC0gVGhlIGFycmF5IHRvIGxvb2t1cCBmb3IgdmFsdWUgYXQgYGluZGV4YC5cclxuXHQgKiBAcGFyYW0ge251bWJlcn0gaW5kZXggLSBUaGUgaW5kZXggaW4gYHZhbHVlYCB0byBsb29rdXAgZm9yIHZhbHVlLlxyXG5cdCAqIEBwYXJhbSB7Kn0gZGVmYXVsdFZhbHVlIC0gVGhlIHZhbHVlIHRvIHJldHVybiBpZiBgdmFsdWVbaW5kZXhdYCBpcyB1bmRlZmluZWQuXHJcblx0ICogQHJldHVybnMgeyp9XHJcblx0ICovXHJcblx0dmFsdWVBdEluZGV4T3JEZWZhdWx0OiBmdW5jdGlvbih2YWx1ZSwgaW5kZXgsIGRlZmF1bHRWYWx1ZSkge1xyXG5cdFx0cmV0dXJuIGhlbHBlcnMudmFsdWVPckRlZmF1bHQoaGVscGVycy5pc0FycmF5KHZhbHVlKSA/IHZhbHVlW2luZGV4XSA6IHZhbHVlLCBkZWZhdWx0VmFsdWUpO1xyXG5cdH0sXHJcblxyXG5cdC8qKlxyXG5cdCAqIENhbGxzIGBmbmAgd2l0aCB0aGUgZ2l2ZW4gYGFyZ3NgIGluIHRoZSBzY29wZSBkZWZpbmVkIGJ5IGB0aGlzQXJnYCBhbmQgcmV0dXJucyB0aGVcclxuXHQgKiB2YWx1ZSByZXR1cm5lZCBieSBgZm5gLiBJZiBgZm5gIGlzIG5vdCBhIGZ1bmN0aW9uLCB0aGlzIG1ldGhvZCByZXR1cm5zIHVuZGVmaW5lZC5cclxuXHQgKiBAcGFyYW0ge2Z1bmN0aW9ufSBmbiAtIFRoZSBmdW5jdGlvbiB0byBjYWxsLlxyXG5cdCAqIEBwYXJhbSB7QXJyYXl8dW5kZWZpbmVkfG51bGx9IGFyZ3MgLSBUaGUgYXJndW1lbnRzIHdpdGggd2hpY2ggYGZuYCBzaG91bGQgYmUgY2FsbGVkLlxyXG5cdCAqIEBwYXJhbSB7b2JqZWN0fSBbdGhpc0FyZ10gLSBUaGUgdmFsdWUgb2YgYHRoaXNgIHByb3ZpZGVkIGZvciB0aGUgY2FsbCB0byBgZm5gLlxyXG5cdCAqIEByZXR1cm5zIHsqfVxyXG5cdCAqL1xyXG5cdGNhbGxiYWNrOiBmdW5jdGlvbihmbiwgYXJncywgdGhpc0FyZykge1xyXG5cdFx0aWYgKGZuICYmIHR5cGVvZiBmbi5jYWxsID09PSAnZnVuY3Rpb24nKSB7XHJcblx0XHRcdHJldHVybiBmbi5hcHBseSh0aGlzQXJnLCBhcmdzKTtcclxuXHRcdH1cclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBOb3RlKFNCKSBmb3IgcGVyZm9ybWFuY2Ugc2FrZSwgdGhpcyBtZXRob2Qgc2hvdWxkIG9ubHkgYmUgdXNlZCB3aGVuIGxvb3BhYmxlIHR5cGVcclxuXHQgKiBpcyB1bmtub3duIG9yIGluIG5vbmUgaW50ZW5zaXZlIGNvZGUgKG5vdCBjYWxsZWQgb2Z0ZW4gYW5kIHNtYWxsIGxvb3BhYmxlKS4gRWxzZVxyXG5cdCAqIGl0J3MgcHJlZmVyYWJsZSB0byB1c2UgYSByZWd1bGFyIGZvcigpIGxvb3AgYW5kIHNhdmUgZXh0cmEgZnVuY3Rpb24gY2FsbHMuXHJcblx0ICogQHBhcmFtIHtvYmplY3R8QXJyYXl9IGxvb3BhYmxlIC0gVGhlIG9iamVjdCBvciBhcnJheSB0byBiZSBpdGVyYXRlZC5cclxuXHQgKiBAcGFyYW0ge2Z1bmN0aW9ufSBmbiAtIFRoZSBmdW5jdGlvbiB0byBjYWxsIGZvciBlYWNoIGl0ZW0uXHJcblx0ICogQHBhcmFtIHtvYmplY3R9IFt0aGlzQXJnXSAtIFRoZSB2YWx1ZSBvZiBgdGhpc2AgcHJvdmlkZWQgZm9yIHRoZSBjYWxsIHRvIGBmbmAuXHJcblx0ICogQHBhcmFtIHtib29sZWFufSBbcmV2ZXJzZV0gLSBJZiB0cnVlLCBpdGVyYXRlcyBiYWNrd2FyZCBvbiB0aGUgbG9vcGFibGUuXHJcblx0ICovXHJcblx0ZWFjaDogZnVuY3Rpb24obG9vcGFibGUsIGZuLCB0aGlzQXJnLCByZXZlcnNlKSB7XHJcblx0XHR2YXIgaSwgbGVuLCBrZXlzO1xyXG5cdFx0aWYgKGhlbHBlcnMuaXNBcnJheShsb29wYWJsZSkpIHtcclxuXHRcdFx0bGVuID0gbG9vcGFibGUubGVuZ3RoO1xyXG5cdFx0XHRpZiAocmV2ZXJzZSkge1xyXG5cdFx0XHRcdGZvciAoaSA9IGxlbiAtIDE7IGkgPj0gMDsgaS0tKSB7XHJcblx0XHRcdFx0XHRmbi5jYWxsKHRoaXNBcmcsIGxvb3BhYmxlW2ldLCBpKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0Zm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKSB7XHJcblx0XHRcdFx0XHRmbi5jYWxsKHRoaXNBcmcsIGxvb3BhYmxlW2ldLCBpKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH0gZWxzZSBpZiAoaGVscGVycy5pc09iamVjdChsb29wYWJsZSkpIHtcclxuXHRcdFx0a2V5cyA9IE9iamVjdC5rZXlzKGxvb3BhYmxlKTtcclxuXHRcdFx0bGVuID0ga2V5cy5sZW5ndGg7XHJcblx0XHRcdGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKykge1xyXG5cdFx0XHRcdGZuLmNhbGwodGhpc0FyZywgbG9vcGFibGVba2V5c1tpXV0sIGtleXNbaV0pO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0fSxcclxuXHJcblx0LyoqXHJcblx0ICogUmV0dXJucyB0cnVlIGlmIHRoZSBgYTBgIGFuZCBgYTFgIGFycmF5cyBoYXZlIHRoZSBzYW1lIGNvbnRlbnQsIGVsc2UgcmV0dXJucyBmYWxzZS5cclxuXHQgKiBAc2VlIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8xNDg1Mzk3NFxyXG5cdCAqIEBwYXJhbSB7QXJyYXl9IGEwIC0gVGhlIGFycmF5IHRvIGNvbXBhcmVcclxuXHQgKiBAcGFyYW0ge0FycmF5fSBhMSAtIFRoZSBhcnJheSB0byBjb21wYXJlXHJcblx0ICogQHJldHVybnMge2Jvb2xlYW59XHJcblx0ICovXHJcblx0YXJyYXlFcXVhbHM6IGZ1bmN0aW9uKGEwLCBhMSkge1xyXG5cdFx0dmFyIGksIGlsZW4sIHYwLCB2MTtcclxuXHJcblx0XHRpZiAoIWEwIHx8ICFhMSB8fCBhMC5sZW5ndGggIT09IGExLmxlbmd0aCkge1xyXG5cdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHR9XHJcblxyXG5cdFx0Zm9yIChpID0gMCwgaWxlbiA9IGEwLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xyXG5cdFx0XHR2MCA9IGEwW2ldO1xyXG5cdFx0XHR2MSA9IGExW2ldO1xyXG5cclxuXHRcdFx0aWYgKHYwIGluc3RhbmNlb2YgQXJyYXkgJiYgdjEgaW5zdGFuY2VvZiBBcnJheSkge1xyXG5cdFx0XHRcdGlmICghaGVscGVycy5hcnJheUVxdWFscyh2MCwgdjEpKSB7XHJcblx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9IGVsc2UgaWYgKHYwICE9PSB2MSkge1xyXG5cdFx0XHRcdC8vIE5PVEU6IHR3byBkaWZmZXJlbnQgb2JqZWN0IGluc3RhbmNlcyB3aWxsIG5ldmVyIGJlIGVxdWFsOiB7eDoyMH0gIT0ge3g6MjB9XHJcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIHRydWU7XHJcblx0fSxcclxuXHJcblx0LyoqXHJcblx0ICogUmV0dXJucyBhIGRlZXAgY29weSBvZiBgc291cmNlYCB3aXRob3V0IGtlZXBpbmcgcmVmZXJlbmNlcyBvbiBvYmplY3RzIGFuZCBhcnJheXMuXHJcblx0ICogQHBhcmFtIHsqfSBzb3VyY2UgLSBUaGUgdmFsdWUgdG8gY2xvbmUuXHJcblx0ICogQHJldHVybnMgeyp9XHJcblx0ICovXHJcblx0Y2xvbmU6IGZ1bmN0aW9uKHNvdXJjZSkge1xyXG5cdFx0aWYgKGhlbHBlcnMuaXNBcnJheShzb3VyY2UpKSB7XHJcblx0XHRcdHJldHVybiBzb3VyY2UubWFwKGhlbHBlcnMuY2xvbmUpO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmIChoZWxwZXJzLmlzT2JqZWN0KHNvdXJjZSkpIHtcclxuXHRcdFx0dmFyIHRhcmdldCA9IE9iamVjdC5jcmVhdGUoc291cmNlKTtcclxuXHRcdFx0dmFyIGtleXMgPSBPYmplY3Qua2V5cyhzb3VyY2UpO1xyXG5cdFx0XHR2YXIga2xlbiA9IGtleXMubGVuZ3RoO1xyXG5cdFx0XHR2YXIgayA9IDA7XHJcblxyXG5cdFx0XHRmb3IgKDsgayA8IGtsZW47ICsraykge1xyXG5cdFx0XHRcdHRhcmdldFtrZXlzW2tdXSA9IGhlbHBlcnMuY2xvbmUoc291cmNlW2tleXNba11dKTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0cmV0dXJuIHRhcmdldDtcclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gc291cmNlO1xyXG5cdH0sXHJcblxyXG5cdC8qKlxyXG5cdCAqIFRoZSBkZWZhdWx0IG1lcmdlciB3aGVuIENoYXJ0LmhlbHBlcnMubWVyZ2UgaXMgY2FsbGVkIHdpdGhvdXQgbWVyZ2VyIG9wdGlvbi5cclxuXHQgKiBOb3RlKFNCKTogYWxzbyB1c2VkIGJ5IG1lcmdlQ29uZmlnIGFuZCBtZXJnZVNjYWxlQ29uZmlnIGFzIGZhbGxiYWNrLlxyXG5cdCAqIEBwcml2YXRlXHJcblx0ICovXHJcblx0X21lcmdlcjogZnVuY3Rpb24oa2V5LCB0YXJnZXQsIHNvdXJjZSwgb3B0aW9ucykge1xyXG5cdFx0aWYgKCFpc1ZhbGlkS2V5KGtleSkpIHtcclxuXHRcdFx0Ly8gV2Ugd2FudCB0byBlbnN1cmUgd2UgZG8gbm90IGNvcHkgcHJvdG90eXBlcyBvdmVyXHJcblx0XHRcdC8vIGFzIHRoaXMgY2FuIHBvbGx1dGUgZ2xvYmFsIG5hbWVzcGFjZXNcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdHZhciB0dmFsID0gdGFyZ2V0W2tleV07XHJcblx0XHR2YXIgc3ZhbCA9IHNvdXJjZVtrZXldO1xyXG5cclxuXHRcdGlmIChoZWxwZXJzLmlzT2JqZWN0KHR2YWwpICYmIGhlbHBlcnMuaXNPYmplY3Qoc3ZhbCkpIHtcclxuXHRcdFx0aGVscGVycy5tZXJnZSh0dmFsLCBzdmFsLCBvcHRpb25zKTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdHRhcmdldFtrZXldID0gaGVscGVycy5jbG9uZShzdmFsKTtcclxuXHRcdH1cclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBNZXJnZXMgc291cmNlW2tleV0gaW4gdGFyZ2V0W2tleV0gb25seSBpZiB0YXJnZXRba2V5XSBpcyB1bmRlZmluZWQuXHJcblx0ICogQHByaXZhdGVcclxuXHQgKi9cclxuXHRfbWVyZ2VySWY6IGZ1bmN0aW9uKGtleSwgdGFyZ2V0LCBzb3VyY2UpIHtcclxuXHRcdGlmICghaXNWYWxpZEtleShrZXkpKSB7XHJcblx0XHRcdC8vIFdlIHdhbnQgdG8gZW5zdXJlIHdlIGRvIG5vdCBjb3B5IHByb3RvdHlwZXMgb3ZlclxyXG5cdFx0XHQvLyBhcyB0aGlzIGNhbiBwb2xsdXRlIGdsb2JhbCBuYW1lc3BhY2VzXHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHJcblx0XHR2YXIgdHZhbCA9IHRhcmdldFtrZXldO1xyXG5cdFx0dmFyIHN2YWwgPSBzb3VyY2Vba2V5XTtcclxuXHJcblx0XHRpZiAoaGVscGVycy5pc09iamVjdCh0dmFsKSAmJiBoZWxwZXJzLmlzT2JqZWN0KHN2YWwpKSB7XHJcblx0XHRcdGhlbHBlcnMubWVyZ2VJZih0dmFsLCBzdmFsKTtcclxuXHRcdH0gZWxzZSBpZiAoIXRhcmdldC5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XHJcblx0XHRcdHRhcmdldFtrZXldID0gaGVscGVycy5jbG9uZShzdmFsKTtcclxuXHRcdH1cclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBSZWN1cnNpdmVseSBkZWVwIGNvcGllcyBgc291cmNlYCBwcm9wZXJ0aWVzIGludG8gYHRhcmdldGAgd2l0aCB0aGUgZ2l2ZW4gYG9wdGlvbnNgLlxyXG5cdCAqIElNUE9SVEFOVDogYHRhcmdldGAgaXMgbm90IGNsb25lZCBhbmQgd2lsbCBiZSB1cGRhdGVkIHdpdGggYHNvdXJjZWAgcHJvcGVydGllcy5cclxuXHQgKiBAcGFyYW0ge29iamVjdH0gdGFyZ2V0IC0gVGhlIHRhcmdldCBvYmplY3QgaW4gd2hpY2ggYWxsIHNvdXJjZXMgYXJlIG1lcmdlZCBpbnRvLlxyXG5cdCAqIEBwYXJhbSB7b2JqZWN0fG9iamVjdFtdfSBzb3VyY2UgLSBPYmplY3QocykgdG8gbWVyZ2UgaW50byBgdGFyZ2V0YC5cclxuXHQgKiBAcGFyYW0ge29iamVjdH0gW29wdGlvbnNdIC0gTWVyZ2luZyBvcHRpb25zOlxyXG5cdCAqIEBwYXJhbSB7ZnVuY3Rpb259IFtvcHRpb25zLm1lcmdlcl0gLSBUaGUgbWVyZ2UgbWV0aG9kIChrZXksIHRhcmdldCwgc291cmNlLCBvcHRpb25zKVxyXG5cdCAqIEByZXR1cm5zIHtvYmplY3R9IFRoZSBgdGFyZ2V0YCBvYmplY3QuXHJcblx0ICovXHJcblx0bWVyZ2U6IGZ1bmN0aW9uKHRhcmdldCwgc291cmNlLCBvcHRpb25zKSB7XHJcblx0XHR2YXIgc291cmNlcyA9IGhlbHBlcnMuaXNBcnJheShzb3VyY2UpID8gc291cmNlIDogW3NvdXJjZV07XHJcblx0XHR2YXIgaWxlbiA9IHNvdXJjZXMubGVuZ3RoO1xyXG5cdFx0dmFyIG1lcmdlLCBpLCBrZXlzLCBrbGVuLCBrO1xyXG5cclxuXHRcdGlmICghaGVscGVycy5pc09iamVjdCh0YXJnZXQpKSB7XHJcblx0XHRcdHJldHVybiB0YXJnZXQ7XHJcblx0XHR9XHJcblxyXG5cdFx0b3B0aW9ucyA9IG9wdGlvbnMgfHwge307XHJcblx0XHRtZXJnZSA9IG9wdGlvbnMubWVyZ2VyIHx8IGhlbHBlcnMuX21lcmdlcjtcclxuXHJcblx0XHRmb3IgKGkgPSAwOyBpIDwgaWxlbjsgKytpKSB7XHJcblx0XHRcdHNvdXJjZSA9IHNvdXJjZXNbaV07XHJcblx0XHRcdGlmICghaGVscGVycy5pc09iamVjdChzb3VyY2UpKSB7XHJcblx0XHRcdFx0Y29udGludWU7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdGtleXMgPSBPYmplY3Qua2V5cyhzb3VyY2UpO1xyXG5cdFx0XHRmb3IgKGsgPSAwLCBrbGVuID0ga2V5cy5sZW5ndGg7IGsgPCBrbGVuOyArK2spIHtcclxuXHRcdFx0XHRtZXJnZShrZXlzW2tdLCB0YXJnZXQsIHNvdXJjZSwgb3B0aW9ucyk7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gdGFyZ2V0O1xyXG5cdH0sXHJcblxyXG5cdC8qKlxyXG5cdCAqIFJlY3Vyc2l2ZWx5IGRlZXAgY29waWVzIGBzb3VyY2VgIHByb3BlcnRpZXMgaW50byBgdGFyZ2V0YCAqb25seSogaWYgbm90IGRlZmluZWQgaW4gdGFyZ2V0LlxyXG5cdCAqIElNUE9SVEFOVDogYHRhcmdldGAgaXMgbm90IGNsb25lZCBhbmQgd2lsbCBiZSB1cGRhdGVkIHdpdGggYHNvdXJjZWAgcHJvcGVydGllcy5cclxuXHQgKiBAcGFyYW0ge29iamVjdH0gdGFyZ2V0IC0gVGhlIHRhcmdldCBvYmplY3QgaW4gd2hpY2ggYWxsIHNvdXJjZXMgYXJlIG1lcmdlZCBpbnRvLlxyXG5cdCAqIEBwYXJhbSB7b2JqZWN0fG9iamVjdFtdfSBzb3VyY2UgLSBPYmplY3QocykgdG8gbWVyZ2UgaW50byBgdGFyZ2V0YC5cclxuXHQgKiBAcmV0dXJucyB7b2JqZWN0fSBUaGUgYHRhcmdldGAgb2JqZWN0LlxyXG5cdCAqL1xyXG5cdG1lcmdlSWY6IGZ1bmN0aW9uKHRhcmdldCwgc291cmNlKSB7XHJcblx0XHRyZXR1cm4gaGVscGVycy5tZXJnZSh0YXJnZXQsIHNvdXJjZSwge21lcmdlcjogaGVscGVycy5fbWVyZ2VySWZ9KTtcclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBBcHBsaWVzIHRoZSBjb250ZW50cyBvZiB0d28gb3IgbW9yZSBvYmplY3RzIHRvZ2V0aGVyIGludG8gdGhlIGZpcnN0IG9iamVjdC5cclxuXHQgKiBAcGFyYW0ge29iamVjdH0gdGFyZ2V0IC0gVGhlIHRhcmdldCBvYmplY3QgaW4gd2hpY2ggYWxsIG9iamVjdHMgYXJlIG1lcmdlZCBpbnRvLlxyXG5cdCAqIEBwYXJhbSB7b2JqZWN0fSBhcmcxIC0gT2JqZWN0IGNvbnRhaW5pbmcgYWRkaXRpb25hbCBwcm9wZXJ0aWVzIHRvIG1lcmdlIGluIHRhcmdldC5cclxuXHQgKiBAcGFyYW0ge29iamVjdH0gYXJnTiAtIEFkZGl0aW9uYWwgb2JqZWN0cyBjb250YWluaW5nIHByb3BlcnRpZXMgdG8gbWVyZ2UgaW4gdGFyZ2V0LlxyXG5cdCAqIEByZXR1cm5zIHtvYmplY3R9IFRoZSBgdGFyZ2V0YCBvYmplY3QuXHJcblx0ICovXHJcblx0ZXh0ZW5kOiBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uKHRhcmdldCkge1xyXG5cdFx0cmV0dXJuIGhlbHBlcnMubWVyZ2UodGFyZ2V0LCBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSksIHtcclxuXHRcdFx0bWVyZ2VyOiBmdW5jdGlvbihrZXksIGRzdCwgc3JjKSB7XHJcblx0XHRcdFx0ZHN0W2tleV0gPSBzcmNba2V5XTtcclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblx0fSxcclxuXHJcblx0LyoqXHJcblx0ICogQmFzaWMgamF2YXNjcmlwdCBpbmhlcml0YW5jZSBiYXNlZCBvbiB0aGUgbW9kZWwgY3JlYXRlZCBpbiBCYWNrYm9uZS5qc1xyXG5cdCAqL1xyXG5cdGluaGVyaXRzOiBmdW5jdGlvbihleHRlbnNpb25zKSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0dmFyIENoYXJ0RWxlbWVudCA9IChleHRlbnNpb25zICYmIGV4dGVuc2lvbnMuaGFzT3duUHJvcGVydHkoJ2NvbnN0cnVjdG9yJykpID8gZXh0ZW5zaW9ucy5jb25zdHJ1Y3RvciA6IGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRyZXR1cm4gbWUuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcclxuXHRcdH07XHJcblxyXG5cdFx0dmFyIFN1cnJvZ2F0ZSA9IGZ1bmN0aW9uKCkge1xyXG5cdFx0XHR0aGlzLmNvbnN0cnVjdG9yID0gQ2hhcnRFbGVtZW50O1xyXG5cdFx0fTtcclxuXHJcblx0XHRTdXJyb2dhdGUucHJvdG90eXBlID0gbWUucHJvdG90eXBlO1xyXG5cdFx0Q2hhcnRFbGVtZW50LnByb3RvdHlwZSA9IG5ldyBTdXJyb2dhdGUoKTtcclxuXHRcdENoYXJ0RWxlbWVudC5leHRlbmQgPSBoZWxwZXJzLmluaGVyaXRzO1xyXG5cclxuXHRcdGlmIChleHRlbnNpb25zKSB7XHJcblx0XHRcdGhlbHBlcnMuZXh0ZW5kKENoYXJ0RWxlbWVudC5wcm90b3R5cGUsIGV4dGVuc2lvbnMpO1xyXG5cdFx0fVxyXG5cclxuXHRcdENoYXJ0RWxlbWVudC5fX3N1cGVyX18gPSBtZS5wcm90b3R5cGU7XHJcblx0XHRyZXR1cm4gQ2hhcnRFbGVtZW50O1xyXG5cdH0sXHJcblxyXG5cdF9kZXByZWNhdGVkOiBmdW5jdGlvbihzY29wZSwgdmFsdWUsIHByZXZpb3VzLCBjdXJyZW50KSB7XHJcblx0XHRpZiAodmFsdWUgIT09IHVuZGVmaW5lZCkge1xyXG5cdFx0XHRjb25zb2xlLndhcm4oc2NvcGUgKyAnOiBcIicgKyBwcmV2aW91cyArXHJcblx0XHRcdFx0J1wiIGlzIGRlcHJlY2F0ZWQuIFBsZWFzZSB1c2UgXCInICsgY3VycmVudCArICdcIiBpbnN0ZWFkJyk7XHJcblx0XHR9XHJcblx0fVxyXG59O1xyXG5cclxudmFyIGhlbHBlcnNfY29yZSA9IGhlbHBlcnM7XHJcblxyXG4vLyBERVBSRUNBVElPTlNcclxuXHJcbi8qKlxyXG4gKiBQcm92aWRlZCBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSwgdXNlIENoYXJ0LmhlbHBlcnMuY2FsbGJhY2sgaW5zdGVhZC5cclxuICogQGZ1bmN0aW9uIENoYXJ0LmhlbHBlcnMuY2FsbENhbGxiYWNrXHJcbiAqIEBkZXByZWNhdGVkIHNpbmNlIHZlcnNpb24gMi42LjBcclxuICogQHRvZG8gcmVtb3ZlIGF0IHZlcnNpb24gM1xyXG4gKiBAcHJpdmF0ZVxyXG4gKi9cclxuaGVscGVycy5jYWxsQ2FsbGJhY2sgPSBoZWxwZXJzLmNhbGxiYWNrO1xyXG5cclxuLyoqXHJcbiAqIFByb3ZpZGVkIGZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5LCB1c2UgQXJyYXkucHJvdG90eXBlLmluZGV4T2YgaW5zdGVhZC5cclxuICogQXJyYXkucHJvdG90eXBlLmluZGV4T2YgY29tcGF0aWJpbGl0eTogQ2hyb21lLCBPcGVyYSwgU2FmYXJpLCBGRjEuNSssIElFOStcclxuICogQGZ1bmN0aW9uIENoYXJ0LmhlbHBlcnMuaW5kZXhPZlxyXG4gKiBAZGVwcmVjYXRlZCBzaW5jZSB2ZXJzaW9uIDIuNy4wXHJcbiAqIEB0b2RvIHJlbW92ZSBhdCB2ZXJzaW9uIDNcclxuICogQHByaXZhdGVcclxuICovXHJcbmhlbHBlcnMuaW5kZXhPZiA9IGZ1bmN0aW9uKGFycmF5LCBpdGVtLCBmcm9tSW5kZXgpIHtcclxuXHRyZXR1cm4gQXJyYXkucHJvdG90eXBlLmluZGV4T2YuY2FsbChhcnJheSwgaXRlbSwgZnJvbUluZGV4KTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBQcm92aWRlZCBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSwgdXNlIENoYXJ0LmhlbHBlcnMudmFsdWVPckRlZmF1bHQgaW5zdGVhZC5cclxuICogQGZ1bmN0aW9uIENoYXJ0LmhlbHBlcnMuZ2V0VmFsdWVPckRlZmF1bHRcclxuICogQGRlcHJlY2F0ZWQgc2luY2UgdmVyc2lvbiAyLjcuMFxyXG4gKiBAdG9kbyByZW1vdmUgYXQgdmVyc2lvbiAzXHJcbiAqIEBwcml2YXRlXHJcbiAqL1xyXG5oZWxwZXJzLmdldFZhbHVlT3JEZWZhdWx0ID0gaGVscGVycy52YWx1ZU9yRGVmYXVsdDtcclxuXHJcbi8qKlxyXG4gKiBQcm92aWRlZCBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSwgdXNlIENoYXJ0LmhlbHBlcnMudmFsdWVBdEluZGV4T3JEZWZhdWx0IGluc3RlYWQuXHJcbiAqIEBmdW5jdGlvbiBDaGFydC5oZWxwZXJzLmdldFZhbHVlQXRJbmRleE9yRGVmYXVsdFxyXG4gKiBAZGVwcmVjYXRlZCBzaW5jZSB2ZXJzaW9uIDIuNy4wXHJcbiAqIEB0b2RvIHJlbW92ZSBhdCB2ZXJzaW9uIDNcclxuICogQHByaXZhdGVcclxuICovXHJcbmhlbHBlcnMuZ2V0VmFsdWVBdEluZGV4T3JEZWZhdWx0ID0gaGVscGVycy52YWx1ZUF0SW5kZXhPckRlZmF1bHQ7XG5cbi8qKlxyXG4gKiBFYXNpbmcgZnVuY3Rpb25zIGFkYXB0ZWQgZnJvbSBSb2JlcnQgUGVubmVyJ3MgZWFzaW5nIGVxdWF0aW9ucy5cclxuICogQG5hbWVzcGFjZSBDaGFydC5oZWxwZXJzLmVhc2luZ0VmZmVjdHNcclxuICogQHNlZSBodHRwOi8vd3d3LnJvYmVydHBlbm5lci5jb20vZWFzaW5nL1xyXG4gKi9cclxudmFyIGVmZmVjdHMgPSB7XHJcblx0bGluZWFyOiBmdW5jdGlvbih0KSB7XHJcblx0XHRyZXR1cm4gdDtcclxuXHR9LFxyXG5cclxuXHRlYXNlSW5RdWFkOiBmdW5jdGlvbih0KSB7XHJcblx0XHRyZXR1cm4gdCAqIHQ7XHJcblx0fSxcclxuXHJcblx0ZWFzZU91dFF1YWQ6IGZ1bmN0aW9uKHQpIHtcclxuXHRcdHJldHVybiAtdCAqICh0IC0gMik7XHJcblx0fSxcclxuXHJcblx0ZWFzZUluT3V0UXVhZDogZnVuY3Rpb24odCkge1xyXG5cdFx0aWYgKCh0IC89IDAuNSkgPCAxKSB7XHJcblx0XHRcdHJldHVybiAwLjUgKiB0ICogdDtcclxuXHRcdH1cclxuXHRcdHJldHVybiAtMC41ICogKCgtLXQpICogKHQgLSAyKSAtIDEpO1xyXG5cdH0sXHJcblxyXG5cdGVhc2VJbkN1YmljOiBmdW5jdGlvbih0KSB7XHJcblx0XHRyZXR1cm4gdCAqIHQgKiB0O1xyXG5cdH0sXHJcblxyXG5cdGVhc2VPdXRDdWJpYzogZnVuY3Rpb24odCkge1xyXG5cdFx0cmV0dXJuICh0ID0gdCAtIDEpICogdCAqIHQgKyAxO1xyXG5cdH0sXHJcblxyXG5cdGVhc2VJbk91dEN1YmljOiBmdW5jdGlvbih0KSB7XHJcblx0XHRpZiAoKHQgLz0gMC41KSA8IDEpIHtcclxuXHRcdFx0cmV0dXJuIDAuNSAqIHQgKiB0ICogdDtcclxuXHRcdH1cclxuXHRcdHJldHVybiAwLjUgKiAoKHQgLT0gMikgKiB0ICogdCArIDIpO1xyXG5cdH0sXHJcblxyXG5cdGVhc2VJblF1YXJ0OiBmdW5jdGlvbih0KSB7XHJcblx0XHRyZXR1cm4gdCAqIHQgKiB0ICogdDtcclxuXHR9LFxyXG5cclxuXHRlYXNlT3V0UXVhcnQ6IGZ1bmN0aW9uKHQpIHtcclxuXHRcdHJldHVybiAtKCh0ID0gdCAtIDEpICogdCAqIHQgKiB0IC0gMSk7XHJcblx0fSxcclxuXHJcblx0ZWFzZUluT3V0UXVhcnQ6IGZ1bmN0aW9uKHQpIHtcclxuXHRcdGlmICgodCAvPSAwLjUpIDwgMSkge1xyXG5cdFx0XHRyZXR1cm4gMC41ICogdCAqIHQgKiB0ICogdDtcclxuXHRcdH1cclxuXHRcdHJldHVybiAtMC41ICogKCh0IC09IDIpICogdCAqIHQgKiB0IC0gMik7XHJcblx0fSxcclxuXHJcblx0ZWFzZUluUXVpbnQ6IGZ1bmN0aW9uKHQpIHtcclxuXHRcdHJldHVybiB0ICogdCAqIHQgKiB0ICogdDtcclxuXHR9LFxyXG5cclxuXHRlYXNlT3V0UXVpbnQ6IGZ1bmN0aW9uKHQpIHtcclxuXHRcdHJldHVybiAodCA9IHQgLSAxKSAqIHQgKiB0ICogdCAqIHQgKyAxO1xyXG5cdH0sXHJcblxyXG5cdGVhc2VJbk91dFF1aW50OiBmdW5jdGlvbih0KSB7XHJcblx0XHRpZiAoKHQgLz0gMC41KSA8IDEpIHtcclxuXHRcdFx0cmV0dXJuIDAuNSAqIHQgKiB0ICogdCAqIHQgKiB0O1xyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIDAuNSAqICgodCAtPSAyKSAqIHQgKiB0ICogdCAqIHQgKyAyKTtcclxuXHR9LFxyXG5cclxuXHRlYXNlSW5TaW5lOiBmdW5jdGlvbih0KSB7XHJcblx0XHRyZXR1cm4gLU1hdGguY29zKHQgKiAoTWF0aC5QSSAvIDIpKSArIDE7XHJcblx0fSxcclxuXHJcblx0ZWFzZU91dFNpbmU6IGZ1bmN0aW9uKHQpIHtcclxuXHRcdHJldHVybiBNYXRoLnNpbih0ICogKE1hdGguUEkgLyAyKSk7XHJcblx0fSxcclxuXHJcblx0ZWFzZUluT3V0U2luZTogZnVuY3Rpb24odCkge1xyXG5cdFx0cmV0dXJuIC0wLjUgKiAoTWF0aC5jb3MoTWF0aC5QSSAqIHQpIC0gMSk7XHJcblx0fSxcclxuXHJcblx0ZWFzZUluRXhwbzogZnVuY3Rpb24odCkge1xyXG5cdFx0cmV0dXJuICh0ID09PSAwKSA/IDAgOiBNYXRoLnBvdygyLCAxMCAqICh0IC0gMSkpO1xyXG5cdH0sXHJcblxyXG5cdGVhc2VPdXRFeHBvOiBmdW5jdGlvbih0KSB7XHJcblx0XHRyZXR1cm4gKHQgPT09IDEpID8gMSA6IC1NYXRoLnBvdygyLCAtMTAgKiB0KSArIDE7XHJcblx0fSxcclxuXHJcblx0ZWFzZUluT3V0RXhwbzogZnVuY3Rpb24odCkge1xyXG5cdFx0aWYgKHQgPT09IDApIHtcclxuXHRcdFx0cmV0dXJuIDA7XHJcblx0XHR9XHJcblx0XHRpZiAodCA9PT0gMSkge1xyXG5cdFx0XHRyZXR1cm4gMTtcclxuXHRcdH1cclxuXHRcdGlmICgodCAvPSAwLjUpIDwgMSkge1xyXG5cdFx0XHRyZXR1cm4gMC41ICogTWF0aC5wb3coMiwgMTAgKiAodCAtIDEpKTtcclxuXHRcdH1cclxuXHRcdHJldHVybiAwLjUgKiAoLU1hdGgucG93KDIsIC0xMCAqIC0tdCkgKyAyKTtcclxuXHR9LFxyXG5cclxuXHRlYXNlSW5DaXJjOiBmdW5jdGlvbih0KSB7XHJcblx0XHRpZiAodCA+PSAxKSB7XHJcblx0XHRcdHJldHVybiB0O1xyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIC0oTWF0aC5zcXJ0KDEgLSB0ICogdCkgLSAxKTtcclxuXHR9LFxyXG5cclxuXHRlYXNlT3V0Q2lyYzogZnVuY3Rpb24odCkge1xyXG5cdFx0cmV0dXJuIE1hdGguc3FydCgxIC0gKHQgPSB0IC0gMSkgKiB0KTtcclxuXHR9LFxyXG5cclxuXHRlYXNlSW5PdXRDaXJjOiBmdW5jdGlvbih0KSB7XHJcblx0XHRpZiAoKHQgLz0gMC41KSA8IDEpIHtcclxuXHRcdFx0cmV0dXJuIC0wLjUgKiAoTWF0aC5zcXJ0KDEgLSB0ICogdCkgLSAxKTtcclxuXHRcdH1cclxuXHRcdHJldHVybiAwLjUgKiAoTWF0aC5zcXJ0KDEgLSAodCAtPSAyKSAqIHQpICsgMSk7XHJcblx0fSxcclxuXHJcblx0ZWFzZUluRWxhc3RpYzogZnVuY3Rpb24odCkge1xyXG5cdFx0dmFyIHMgPSAxLjcwMTU4O1xyXG5cdFx0dmFyIHAgPSAwO1xyXG5cdFx0dmFyIGEgPSAxO1xyXG5cdFx0aWYgKHQgPT09IDApIHtcclxuXHRcdFx0cmV0dXJuIDA7XHJcblx0XHR9XHJcblx0XHRpZiAodCA9PT0gMSkge1xyXG5cdFx0XHRyZXR1cm4gMTtcclxuXHRcdH1cclxuXHRcdGlmICghcCkge1xyXG5cdFx0XHRwID0gMC4zO1xyXG5cdFx0fVxyXG5cdFx0aWYgKGEgPCAxKSB7XHJcblx0XHRcdGEgPSAxO1xyXG5cdFx0XHRzID0gcCAvIDQ7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRzID0gcCAvICgyICogTWF0aC5QSSkgKiBNYXRoLmFzaW4oMSAvIGEpO1xyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIC0oYSAqIE1hdGgucG93KDIsIDEwICogKHQgLT0gMSkpICogTWF0aC5zaW4oKHQgLSBzKSAqICgyICogTWF0aC5QSSkgLyBwKSk7XHJcblx0fSxcclxuXHJcblx0ZWFzZU91dEVsYXN0aWM6IGZ1bmN0aW9uKHQpIHtcclxuXHRcdHZhciBzID0gMS43MDE1ODtcclxuXHRcdHZhciBwID0gMDtcclxuXHRcdHZhciBhID0gMTtcclxuXHRcdGlmICh0ID09PSAwKSB7XHJcblx0XHRcdHJldHVybiAwO1xyXG5cdFx0fVxyXG5cdFx0aWYgKHQgPT09IDEpIHtcclxuXHRcdFx0cmV0dXJuIDE7XHJcblx0XHR9XHJcblx0XHRpZiAoIXApIHtcclxuXHRcdFx0cCA9IDAuMztcclxuXHRcdH1cclxuXHRcdGlmIChhIDwgMSkge1xyXG5cdFx0XHRhID0gMTtcclxuXHRcdFx0cyA9IHAgLyA0O1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0cyA9IHAgLyAoMiAqIE1hdGguUEkpICogTWF0aC5hc2luKDEgLyBhKTtcclxuXHRcdH1cclxuXHRcdHJldHVybiBhICogTWF0aC5wb3coMiwgLTEwICogdCkgKiBNYXRoLnNpbigodCAtIHMpICogKDIgKiBNYXRoLlBJKSAvIHApICsgMTtcclxuXHR9LFxyXG5cclxuXHRlYXNlSW5PdXRFbGFzdGljOiBmdW5jdGlvbih0KSB7XHJcblx0XHR2YXIgcyA9IDEuNzAxNTg7XHJcblx0XHR2YXIgcCA9IDA7XHJcblx0XHR2YXIgYSA9IDE7XHJcblx0XHRpZiAodCA9PT0gMCkge1xyXG5cdFx0XHRyZXR1cm4gMDtcclxuXHRcdH1cclxuXHRcdGlmICgodCAvPSAwLjUpID09PSAyKSB7XHJcblx0XHRcdHJldHVybiAxO1xyXG5cdFx0fVxyXG5cdFx0aWYgKCFwKSB7XHJcblx0XHRcdHAgPSAwLjQ1O1xyXG5cdFx0fVxyXG5cdFx0aWYgKGEgPCAxKSB7XHJcblx0XHRcdGEgPSAxO1xyXG5cdFx0XHRzID0gcCAvIDQ7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRzID0gcCAvICgyICogTWF0aC5QSSkgKiBNYXRoLmFzaW4oMSAvIGEpO1xyXG5cdFx0fVxyXG5cdFx0aWYgKHQgPCAxKSB7XHJcblx0XHRcdHJldHVybiAtMC41ICogKGEgKiBNYXRoLnBvdygyLCAxMCAqICh0IC09IDEpKSAqIE1hdGguc2luKCh0IC0gcykgKiAoMiAqIE1hdGguUEkpIC8gcCkpO1xyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIGEgKiBNYXRoLnBvdygyLCAtMTAgKiAodCAtPSAxKSkgKiBNYXRoLnNpbigodCAtIHMpICogKDIgKiBNYXRoLlBJKSAvIHApICogMC41ICsgMTtcclxuXHR9LFxyXG5cdGVhc2VJbkJhY2s6IGZ1bmN0aW9uKHQpIHtcclxuXHRcdHZhciBzID0gMS43MDE1ODtcclxuXHRcdHJldHVybiB0ICogdCAqICgocyArIDEpICogdCAtIHMpO1xyXG5cdH0sXHJcblxyXG5cdGVhc2VPdXRCYWNrOiBmdW5jdGlvbih0KSB7XHJcblx0XHR2YXIgcyA9IDEuNzAxNTg7XHJcblx0XHRyZXR1cm4gKHQgPSB0IC0gMSkgKiB0ICogKChzICsgMSkgKiB0ICsgcykgKyAxO1xyXG5cdH0sXHJcblxyXG5cdGVhc2VJbk91dEJhY2s6IGZ1bmN0aW9uKHQpIHtcclxuXHRcdHZhciBzID0gMS43MDE1ODtcclxuXHRcdGlmICgodCAvPSAwLjUpIDwgMSkge1xyXG5cdFx0XHRyZXR1cm4gMC41ICogKHQgKiB0ICogKCgocyAqPSAoMS41MjUpKSArIDEpICogdCAtIHMpKTtcclxuXHRcdH1cclxuXHRcdHJldHVybiAwLjUgKiAoKHQgLT0gMikgKiB0ICogKCgocyAqPSAoMS41MjUpKSArIDEpICogdCArIHMpICsgMik7XHJcblx0fSxcclxuXHJcblx0ZWFzZUluQm91bmNlOiBmdW5jdGlvbih0KSB7XHJcblx0XHRyZXR1cm4gMSAtIGVmZmVjdHMuZWFzZU91dEJvdW5jZSgxIC0gdCk7XHJcblx0fSxcclxuXHJcblx0ZWFzZU91dEJvdW5jZTogZnVuY3Rpb24odCkge1xyXG5cdFx0aWYgKHQgPCAoMSAvIDIuNzUpKSB7XHJcblx0XHRcdHJldHVybiA3LjU2MjUgKiB0ICogdDtcclxuXHRcdH1cclxuXHRcdGlmICh0IDwgKDIgLyAyLjc1KSkge1xyXG5cdFx0XHRyZXR1cm4gNy41NjI1ICogKHQgLT0gKDEuNSAvIDIuNzUpKSAqIHQgKyAwLjc1O1xyXG5cdFx0fVxyXG5cdFx0aWYgKHQgPCAoMi41IC8gMi43NSkpIHtcclxuXHRcdFx0cmV0dXJuIDcuNTYyNSAqICh0IC09ICgyLjI1IC8gMi43NSkpICogdCArIDAuOTM3NTtcclxuXHRcdH1cclxuXHRcdHJldHVybiA3LjU2MjUgKiAodCAtPSAoMi42MjUgLyAyLjc1KSkgKiB0ICsgMC45ODQzNzU7XHJcblx0fSxcclxuXHJcblx0ZWFzZUluT3V0Qm91bmNlOiBmdW5jdGlvbih0KSB7XHJcblx0XHRpZiAodCA8IDAuNSkge1xyXG5cdFx0XHRyZXR1cm4gZWZmZWN0cy5lYXNlSW5Cb3VuY2UodCAqIDIpICogMC41O1xyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIGVmZmVjdHMuZWFzZU91dEJvdW5jZSh0ICogMiAtIDEpICogMC41ICsgMC41O1xyXG5cdH1cclxufTtcclxuXHJcbnZhciBoZWxwZXJzX2Vhc2luZyA9IHtcclxuXHRlZmZlY3RzOiBlZmZlY3RzXHJcbn07XHJcblxyXG4vLyBERVBSRUNBVElPTlNcclxuXHJcbi8qKlxyXG4gKiBQcm92aWRlZCBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSwgdXNlIENoYXJ0LmhlbHBlcnMuZWFzaW5nLmVmZmVjdHMgaW5zdGVhZC5cclxuICogQGZ1bmN0aW9uIENoYXJ0LmhlbHBlcnMuZWFzaW5nRWZmZWN0c1xyXG4gKiBAZGVwcmVjYXRlZCBzaW5jZSB2ZXJzaW9uIDIuNy4wXHJcbiAqIEB0b2RvIHJlbW92ZSBhdCB2ZXJzaW9uIDNcclxuICogQHByaXZhdGVcclxuICovXHJcbmhlbHBlcnNfY29yZS5lYXNpbmdFZmZlY3RzID0gZWZmZWN0cztcblxudmFyIFBJID0gTWF0aC5QSTtcclxudmFyIFJBRF9QRVJfREVHID0gUEkgLyAxODA7XHJcbnZhciBET1VCTEVfUEkgPSBQSSAqIDI7XHJcbnZhciBIQUxGX1BJID0gUEkgLyAyO1xyXG52YXIgUVVBUlRFUl9QSSA9IFBJIC8gNDtcclxudmFyIFRXT19USElSRFNfUEkgPSBQSSAqIDIgLyAzO1xyXG5cclxuLyoqXHJcbiAqIEBuYW1lc3BhY2UgQ2hhcnQuaGVscGVycy5jYW52YXNcclxuICovXHJcbnZhciBleHBvcnRzJDEgPSB7XHJcblx0LyoqXHJcblx0ICogQ2xlYXJzIHRoZSBlbnRpcmUgY2FudmFzIGFzc29jaWF0ZWQgdG8gdGhlIGdpdmVuIGBjaGFydGAuXHJcblx0ICogQHBhcmFtIHtDaGFydH0gY2hhcnQgLSBUaGUgY2hhcnQgZm9yIHdoaWNoIHRvIGNsZWFyIHRoZSBjYW52YXMuXHJcblx0ICovXHJcblx0Y2xlYXI6IGZ1bmN0aW9uKGNoYXJ0KSB7XHJcblx0XHRjaGFydC5jdHguY2xlYXJSZWN0KDAsIDAsIGNoYXJ0LndpZHRoLCBjaGFydC5oZWlnaHQpO1xyXG5cdH0sXHJcblxyXG5cdC8qKlxyXG5cdCAqIENyZWF0ZXMgYSBcInBhdGhcIiBmb3IgYSByZWN0YW5nbGUgd2l0aCByb3VuZGVkIGNvcm5lcnMgYXQgcG9zaXRpb24gKHgsIHkpIHdpdGggYVxyXG5cdCAqIGdpdmVuIHNpemUgKHdpZHRoLCBoZWlnaHQpIGFuZCB0aGUgc2FtZSBgcmFkaXVzYCBmb3IgYWxsIGNvcm5lcnMuXHJcblx0ICogQHBhcmFtIHtDYW52YXNSZW5kZXJpbmdDb250ZXh0MkR9IGN0eCAtIFRoZSBjYW52YXMgMkQgQ29udGV4dC5cclxuXHQgKiBAcGFyYW0ge251bWJlcn0geCAtIFRoZSB4IGF4aXMgb2YgdGhlIGNvb3JkaW5hdGUgZm9yIHRoZSByZWN0YW5nbGUgc3RhcnRpbmcgcG9pbnQuXHJcblx0ICogQHBhcmFtIHtudW1iZXJ9IHkgLSBUaGUgeSBheGlzIG9mIHRoZSBjb29yZGluYXRlIGZvciB0aGUgcmVjdGFuZ2xlIHN0YXJ0aW5nIHBvaW50LlxyXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSB3aWR0aCAtIFRoZSByZWN0YW5nbGUncyB3aWR0aC5cclxuXHQgKiBAcGFyYW0ge251bWJlcn0gaGVpZ2h0IC0gVGhlIHJlY3RhbmdsZSdzIGhlaWdodC5cclxuXHQgKiBAcGFyYW0ge251bWJlcn0gcmFkaXVzIC0gVGhlIHJvdW5kZWQgYW1vdW50IChpbiBwaXhlbHMpIGZvciB0aGUgZm91ciBjb3JuZXJzLlxyXG5cdCAqIEB0b2RvIGhhbmRsZSBgcmFkaXVzYCBhcyB0b3AtbGVmdCwgdG9wLXJpZ2h0LCBib3R0b20tcmlnaHQsIGJvdHRvbS1sZWZ0IGFycmF5L29iamVjdD9cclxuXHQgKi9cclxuXHRyb3VuZGVkUmVjdDogZnVuY3Rpb24oY3R4LCB4LCB5LCB3aWR0aCwgaGVpZ2h0LCByYWRpdXMpIHtcclxuXHRcdGlmIChyYWRpdXMpIHtcclxuXHRcdFx0dmFyIHIgPSBNYXRoLm1pbihyYWRpdXMsIGhlaWdodCAvIDIsIHdpZHRoIC8gMik7XHJcblx0XHRcdHZhciBsZWZ0ID0geCArIHI7XHJcblx0XHRcdHZhciB0b3AgPSB5ICsgcjtcclxuXHRcdFx0dmFyIHJpZ2h0ID0geCArIHdpZHRoIC0gcjtcclxuXHRcdFx0dmFyIGJvdHRvbSA9IHkgKyBoZWlnaHQgLSByO1xyXG5cclxuXHRcdFx0Y3R4Lm1vdmVUbyh4LCB0b3ApO1xyXG5cdFx0XHRpZiAobGVmdCA8IHJpZ2h0ICYmIHRvcCA8IGJvdHRvbSkge1xyXG5cdFx0XHRcdGN0eC5hcmMobGVmdCwgdG9wLCByLCAtUEksIC1IQUxGX1BJKTtcclxuXHRcdFx0XHRjdHguYXJjKHJpZ2h0LCB0b3AsIHIsIC1IQUxGX1BJLCAwKTtcclxuXHRcdFx0XHRjdHguYXJjKHJpZ2h0LCBib3R0b20sIHIsIDAsIEhBTEZfUEkpO1xyXG5cdFx0XHRcdGN0eC5hcmMobGVmdCwgYm90dG9tLCByLCBIQUxGX1BJLCBQSSk7XHJcblx0XHRcdH0gZWxzZSBpZiAobGVmdCA8IHJpZ2h0KSB7XHJcblx0XHRcdFx0Y3R4Lm1vdmVUbyhsZWZ0LCB5KTtcclxuXHRcdFx0XHRjdHguYXJjKHJpZ2h0LCB0b3AsIHIsIC1IQUxGX1BJLCBIQUxGX1BJKTtcclxuXHRcdFx0XHRjdHguYXJjKGxlZnQsIHRvcCwgciwgSEFMRl9QSSwgUEkgKyBIQUxGX1BJKTtcclxuXHRcdFx0fSBlbHNlIGlmICh0b3AgPCBib3R0b20pIHtcclxuXHRcdFx0XHRjdHguYXJjKGxlZnQsIHRvcCwgciwgLVBJLCAwKTtcclxuXHRcdFx0XHRjdHguYXJjKGxlZnQsIGJvdHRvbSwgciwgMCwgUEkpO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdGN0eC5hcmMobGVmdCwgdG9wLCByLCAtUEksIFBJKTtcclxuXHRcdFx0fVxyXG5cdFx0XHRjdHguY2xvc2VQYXRoKCk7XHJcblx0XHRcdGN0eC5tb3ZlVG8oeCwgeSk7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRjdHgucmVjdCh4LCB5LCB3aWR0aCwgaGVpZ2h0KTtcclxuXHRcdH1cclxuXHR9LFxyXG5cclxuXHRkcmF3UG9pbnQ6IGZ1bmN0aW9uKGN0eCwgc3R5bGUsIHJhZGl1cywgeCwgeSwgcm90YXRpb24pIHtcclxuXHRcdHZhciB0eXBlLCB4T2Zmc2V0LCB5T2Zmc2V0LCBzaXplLCBjb3JuZXJSYWRpdXM7XHJcblx0XHR2YXIgcmFkID0gKHJvdGF0aW9uIHx8IDApICogUkFEX1BFUl9ERUc7XHJcblxyXG5cdFx0aWYgKHN0eWxlICYmIHR5cGVvZiBzdHlsZSA9PT0gJ29iamVjdCcpIHtcclxuXHRcdFx0dHlwZSA9IHN0eWxlLnRvU3RyaW5nKCk7XHJcblx0XHRcdGlmICh0eXBlID09PSAnW29iamVjdCBIVE1MSW1hZ2VFbGVtZW50XScgfHwgdHlwZSA9PT0gJ1tvYmplY3QgSFRNTENhbnZhc0VsZW1lbnRdJykge1xyXG5cdFx0XHRcdGN0eC5zYXZlKCk7XHJcblx0XHRcdFx0Y3R4LnRyYW5zbGF0ZSh4LCB5KTtcclxuXHRcdFx0XHRjdHgucm90YXRlKHJhZCk7XHJcblx0XHRcdFx0Y3R4LmRyYXdJbWFnZShzdHlsZSwgLXN0eWxlLndpZHRoIC8gMiwgLXN0eWxlLmhlaWdodCAvIDIsIHN0eWxlLndpZHRoLCBzdHlsZS5oZWlnaHQpO1xyXG5cdFx0XHRcdGN0eC5yZXN0b3JlKCk7XHJcblx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKGlzTmFOKHJhZGl1cykgfHwgcmFkaXVzIDw9IDApIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdGN0eC5iZWdpblBhdGgoKTtcclxuXHJcblx0XHRzd2l0Y2ggKHN0eWxlKSB7XHJcblx0XHQvLyBEZWZhdWx0IGluY2x1ZGVzIGNpcmNsZVxyXG5cdFx0ZGVmYXVsdDpcclxuXHRcdFx0Y3R4LmFyYyh4LCB5LCByYWRpdXMsIDAsIERPVUJMRV9QSSk7XHJcblx0XHRcdGN0eC5jbG9zZVBhdGgoKTtcclxuXHRcdFx0YnJlYWs7XHJcblx0XHRjYXNlICd0cmlhbmdsZSc6XHJcblx0XHRcdGN0eC5tb3ZlVG8oeCArIE1hdGguc2luKHJhZCkgKiByYWRpdXMsIHkgLSBNYXRoLmNvcyhyYWQpICogcmFkaXVzKTtcclxuXHRcdFx0cmFkICs9IFRXT19USElSRFNfUEk7XHJcblx0XHRcdGN0eC5saW5lVG8oeCArIE1hdGguc2luKHJhZCkgKiByYWRpdXMsIHkgLSBNYXRoLmNvcyhyYWQpICogcmFkaXVzKTtcclxuXHRcdFx0cmFkICs9IFRXT19USElSRFNfUEk7XHJcblx0XHRcdGN0eC5saW5lVG8oeCArIE1hdGguc2luKHJhZCkgKiByYWRpdXMsIHkgLSBNYXRoLmNvcyhyYWQpICogcmFkaXVzKTtcclxuXHRcdFx0Y3R4LmNsb3NlUGF0aCgpO1xyXG5cdFx0XHRicmVhaztcclxuXHRcdGNhc2UgJ3JlY3RSb3VuZGVkJzpcclxuXHRcdFx0Ly8gTk9URTogdGhlIHJvdW5kZWQgcmVjdCBpbXBsZW1lbnRhdGlvbiBjaGFuZ2VkIHRvIHVzZSBgYXJjYCBpbnN0ZWFkIG9mXHJcblx0XHRcdC8vIGBxdWFkcmF0aWNDdXJ2ZVRvYCBzaW5jZSBpdCBnZW5lcmF0ZXMgYmV0dGVyIHJlc3VsdHMgd2hlbiByZWN0IGlzXHJcblx0XHRcdC8vIGFsbW9zdCBhIGNpcmNsZS4gMC41MTYgKGluc3RlYWQgb2YgMC41KSBwcm9kdWNlcyByZXN1bHRzIHdpdGggdmlzdWFsbHlcclxuXHRcdFx0Ly8gY2xvc2VyIHByb3BvcnRpb24gdG8gdGhlIHByZXZpb3VzIGltcGwgYW5kIGl0IGlzIGluc2NyaWJlZCBpbiB0aGVcclxuXHRcdFx0Ly8gY2lyY2xlIHdpdGggYHJhZGl1c2AuIEZvciBtb3JlIGRldGFpbHMsIHNlZSB0aGUgZm9sbG93aW5nIFBSczpcclxuXHRcdFx0Ly8gaHR0cHM6Ly9naXRodWIuY29tL2NoYXJ0anMvQ2hhcnQuanMvaXNzdWVzLzU1OTdcclxuXHRcdFx0Ly8gaHR0cHM6Ly9naXRodWIuY29tL2NoYXJ0anMvQ2hhcnQuanMvaXNzdWVzLzU4NThcclxuXHRcdFx0Y29ybmVyUmFkaXVzID0gcmFkaXVzICogMC41MTY7XHJcblx0XHRcdHNpemUgPSByYWRpdXMgLSBjb3JuZXJSYWRpdXM7XHJcblx0XHRcdHhPZmZzZXQgPSBNYXRoLmNvcyhyYWQgKyBRVUFSVEVSX1BJKSAqIHNpemU7XHJcblx0XHRcdHlPZmZzZXQgPSBNYXRoLnNpbihyYWQgKyBRVUFSVEVSX1BJKSAqIHNpemU7XHJcblx0XHRcdGN0eC5hcmMoeCAtIHhPZmZzZXQsIHkgLSB5T2Zmc2V0LCBjb3JuZXJSYWRpdXMsIHJhZCAtIFBJLCByYWQgLSBIQUxGX1BJKTtcclxuXHRcdFx0Y3R4LmFyYyh4ICsgeU9mZnNldCwgeSAtIHhPZmZzZXQsIGNvcm5lclJhZGl1cywgcmFkIC0gSEFMRl9QSSwgcmFkKTtcclxuXHRcdFx0Y3R4LmFyYyh4ICsgeE9mZnNldCwgeSArIHlPZmZzZXQsIGNvcm5lclJhZGl1cywgcmFkLCByYWQgKyBIQUxGX1BJKTtcclxuXHRcdFx0Y3R4LmFyYyh4IC0geU9mZnNldCwgeSArIHhPZmZzZXQsIGNvcm5lclJhZGl1cywgcmFkICsgSEFMRl9QSSwgcmFkICsgUEkpO1xyXG5cdFx0XHRjdHguY2xvc2VQYXRoKCk7XHJcblx0XHRcdGJyZWFrO1xyXG5cdFx0Y2FzZSAncmVjdCc6XHJcblx0XHRcdGlmICghcm90YXRpb24pIHtcclxuXHRcdFx0XHRzaXplID0gTWF0aC5TUVJUMV8yICogcmFkaXVzO1xyXG5cdFx0XHRcdGN0eC5yZWN0KHggLSBzaXplLCB5IC0gc2l6ZSwgMiAqIHNpemUsIDIgKiBzaXplKTtcclxuXHRcdFx0XHRicmVhaztcclxuXHRcdFx0fVxyXG5cdFx0XHRyYWQgKz0gUVVBUlRFUl9QSTtcclxuXHRcdFx0LyogZmFsbHMgdGhyb3VnaCAqL1xyXG5cdFx0Y2FzZSAncmVjdFJvdCc6XHJcblx0XHRcdHhPZmZzZXQgPSBNYXRoLmNvcyhyYWQpICogcmFkaXVzO1xyXG5cdFx0XHR5T2Zmc2V0ID0gTWF0aC5zaW4ocmFkKSAqIHJhZGl1cztcclxuXHRcdFx0Y3R4Lm1vdmVUbyh4IC0geE9mZnNldCwgeSAtIHlPZmZzZXQpO1xyXG5cdFx0XHRjdHgubGluZVRvKHggKyB5T2Zmc2V0LCB5IC0geE9mZnNldCk7XHJcblx0XHRcdGN0eC5saW5lVG8oeCArIHhPZmZzZXQsIHkgKyB5T2Zmc2V0KTtcclxuXHRcdFx0Y3R4LmxpbmVUbyh4IC0geU9mZnNldCwgeSArIHhPZmZzZXQpO1xyXG5cdFx0XHRjdHguY2xvc2VQYXRoKCk7XHJcblx0XHRcdGJyZWFrO1xyXG5cdFx0Y2FzZSAnY3Jvc3NSb3QnOlxyXG5cdFx0XHRyYWQgKz0gUVVBUlRFUl9QSTtcclxuXHRcdFx0LyogZmFsbHMgdGhyb3VnaCAqL1xyXG5cdFx0Y2FzZSAnY3Jvc3MnOlxyXG5cdFx0XHR4T2Zmc2V0ID0gTWF0aC5jb3MocmFkKSAqIHJhZGl1cztcclxuXHRcdFx0eU9mZnNldCA9IE1hdGguc2luKHJhZCkgKiByYWRpdXM7XHJcblx0XHRcdGN0eC5tb3ZlVG8oeCAtIHhPZmZzZXQsIHkgLSB5T2Zmc2V0KTtcclxuXHRcdFx0Y3R4LmxpbmVUbyh4ICsgeE9mZnNldCwgeSArIHlPZmZzZXQpO1xyXG5cdFx0XHRjdHgubW92ZVRvKHggKyB5T2Zmc2V0LCB5IC0geE9mZnNldCk7XHJcblx0XHRcdGN0eC5saW5lVG8oeCAtIHlPZmZzZXQsIHkgKyB4T2Zmc2V0KTtcclxuXHRcdFx0YnJlYWs7XHJcblx0XHRjYXNlICdzdGFyJzpcclxuXHRcdFx0eE9mZnNldCA9IE1hdGguY29zKHJhZCkgKiByYWRpdXM7XHJcblx0XHRcdHlPZmZzZXQgPSBNYXRoLnNpbihyYWQpICogcmFkaXVzO1xyXG5cdFx0XHRjdHgubW92ZVRvKHggLSB4T2Zmc2V0LCB5IC0geU9mZnNldCk7XHJcblx0XHRcdGN0eC5saW5lVG8oeCArIHhPZmZzZXQsIHkgKyB5T2Zmc2V0KTtcclxuXHRcdFx0Y3R4Lm1vdmVUbyh4ICsgeU9mZnNldCwgeSAtIHhPZmZzZXQpO1xyXG5cdFx0XHRjdHgubGluZVRvKHggLSB5T2Zmc2V0LCB5ICsgeE9mZnNldCk7XHJcblx0XHRcdHJhZCArPSBRVUFSVEVSX1BJO1xyXG5cdFx0XHR4T2Zmc2V0ID0gTWF0aC5jb3MocmFkKSAqIHJhZGl1cztcclxuXHRcdFx0eU9mZnNldCA9IE1hdGguc2luKHJhZCkgKiByYWRpdXM7XHJcblx0XHRcdGN0eC5tb3ZlVG8oeCAtIHhPZmZzZXQsIHkgLSB5T2Zmc2V0KTtcclxuXHRcdFx0Y3R4LmxpbmVUbyh4ICsgeE9mZnNldCwgeSArIHlPZmZzZXQpO1xyXG5cdFx0XHRjdHgubW92ZVRvKHggKyB5T2Zmc2V0LCB5IC0geE9mZnNldCk7XHJcblx0XHRcdGN0eC5saW5lVG8oeCAtIHlPZmZzZXQsIHkgKyB4T2Zmc2V0KTtcclxuXHRcdFx0YnJlYWs7XHJcblx0XHRjYXNlICdsaW5lJzpcclxuXHRcdFx0eE9mZnNldCA9IE1hdGguY29zKHJhZCkgKiByYWRpdXM7XHJcblx0XHRcdHlPZmZzZXQgPSBNYXRoLnNpbihyYWQpICogcmFkaXVzO1xyXG5cdFx0XHRjdHgubW92ZVRvKHggLSB4T2Zmc2V0LCB5IC0geU9mZnNldCk7XHJcblx0XHRcdGN0eC5saW5lVG8oeCArIHhPZmZzZXQsIHkgKyB5T2Zmc2V0KTtcclxuXHRcdFx0YnJlYWs7XHJcblx0XHRjYXNlICdkYXNoJzpcclxuXHRcdFx0Y3R4Lm1vdmVUbyh4LCB5KTtcclxuXHRcdFx0Y3R4LmxpbmVUbyh4ICsgTWF0aC5jb3MocmFkKSAqIHJhZGl1cywgeSArIE1hdGguc2luKHJhZCkgKiByYWRpdXMpO1xyXG5cdFx0XHRicmVhaztcclxuXHRcdH1cclxuXHJcblx0XHRjdHguZmlsbCgpO1xyXG5cdFx0Y3R4LnN0cm9rZSgpO1xyXG5cdH0sXHJcblxyXG5cdC8qKlxyXG5cdCAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgcG9pbnQgaXMgaW5zaWRlIHRoZSByZWN0YW5nbGVcclxuXHQgKiBAcGFyYW0ge29iamVjdH0gcG9pbnQgLSBUaGUgcG9pbnQgdG8gdGVzdFxyXG5cdCAqIEBwYXJhbSB7b2JqZWN0fSBhcmVhIC0gVGhlIHJlY3RhbmdsZVxyXG5cdCAqIEByZXR1cm5zIHtib29sZWFufVxyXG5cdCAqIEBwcml2YXRlXHJcblx0ICovXHJcblx0X2lzUG9pbnRJbkFyZWE6IGZ1bmN0aW9uKHBvaW50LCBhcmVhKSB7XHJcblx0XHR2YXIgZXBzaWxvbiA9IDFlLTY7IC8vIDFlLTYgaXMgbWFyZ2luIGluIHBpeGVscyBmb3IgYWNjdW11bGF0ZWQgZXJyb3IuXHJcblxyXG5cdFx0cmV0dXJuIHBvaW50LnggPiBhcmVhLmxlZnQgLSBlcHNpbG9uICYmIHBvaW50LnggPCBhcmVhLnJpZ2h0ICsgZXBzaWxvbiAmJlxyXG5cdFx0XHRwb2ludC55ID4gYXJlYS50b3AgLSBlcHNpbG9uICYmIHBvaW50LnkgPCBhcmVhLmJvdHRvbSArIGVwc2lsb247XHJcblx0fSxcclxuXHJcblx0Y2xpcEFyZWE6IGZ1bmN0aW9uKGN0eCwgYXJlYSkge1xyXG5cdFx0Y3R4LnNhdmUoKTtcclxuXHRcdGN0eC5iZWdpblBhdGgoKTtcclxuXHRcdGN0eC5yZWN0KGFyZWEubGVmdCwgYXJlYS50b3AsIGFyZWEucmlnaHQgLSBhcmVhLmxlZnQsIGFyZWEuYm90dG9tIC0gYXJlYS50b3ApO1xyXG5cdFx0Y3R4LmNsaXAoKTtcclxuXHR9LFxyXG5cclxuXHR1bmNsaXBBcmVhOiBmdW5jdGlvbihjdHgpIHtcclxuXHRcdGN0eC5yZXN0b3JlKCk7XHJcblx0fSxcclxuXHJcblx0bGluZVRvOiBmdW5jdGlvbihjdHgsIHByZXZpb3VzLCB0YXJnZXQsIGZsaXApIHtcclxuXHRcdHZhciBzdGVwcGVkID0gdGFyZ2V0LnN0ZXBwZWRMaW5lO1xyXG5cdFx0aWYgKHN0ZXBwZWQpIHtcclxuXHRcdFx0aWYgKHN0ZXBwZWQgPT09ICdtaWRkbGUnKSB7XHJcblx0XHRcdFx0dmFyIG1pZHBvaW50ID0gKHByZXZpb3VzLnggKyB0YXJnZXQueCkgLyAyLjA7XHJcblx0XHRcdFx0Y3R4LmxpbmVUbyhtaWRwb2ludCwgZmxpcCA/IHRhcmdldC55IDogcHJldmlvdXMueSk7XHJcblx0XHRcdFx0Y3R4LmxpbmVUbyhtaWRwb2ludCwgZmxpcCA/IHByZXZpb3VzLnkgOiB0YXJnZXQueSk7XHJcblx0XHRcdH0gZWxzZSBpZiAoKHN0ZXBwZWQgPT09ICdhZnRlcicgJiYgIWZsaXApIHx8IChzdGVwcGVkICE9PSAnYWZ0ZXInICYmIGZsaXApKSB7XHJcblx0XHRcdFx0Y3R4LmxpbmVUbyhwcmV2aW91cy54LCB0YXJnZXQueSk7XHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0Y3R4LmxpbmVUbyh0YXJnZXQueCwgcHJldmlvdXMueSk7XHJcblx0XHRcdH1cclxuXHRcdFx0Y3R4LmxpbmVUbyh0YXJnZXQueCwgdGFyZ2V0LnkpO1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKCF0YXJnZXQudGVuc2lvbikge1xyXG5cdFx0XHRjdHgubGluZVRvKHRhcmdldC54LCB0YXJnZXQueSk7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHJcblx0XHRjdHguYmV6aWVyQ3VydmVUbyhcclxuXHRcdFx0ZmxpcCA/IHByZXZpb3VzLmNvbnRyb2xQb2ludFByZXZpb3VzWCA6IHByZXZpb3VzLmNvbnRyb2xQb2ludE5leHRYLFxyXG5cdFx0XHRmbGlwID8gcHJldmlvdXMuY29udHJvbFBvaW50UHJldmlvdXNZIDogcHJldmlvdXMuY29udHJvbFBvaW50TmV4dFksXHJcblx0XHRcdGZsaXAgPyB0YXJnZXQuY29udHJvbFBvaW50TmV4dFggOiB0YXJnZXQuY29udHJvbFBvaW50UHJldmlvdXNYLFxyXG5cdFx0XHRmbGlwID8gdGFyZ2V0LmNvbnRyb2xQb2ludE5leHRZIDogdGFyZ2V0LmNvbnRyb2xQb2ludFByZXZpb3VzWSxcclxuXHRcdFx0dGFyZ2V0LngsXHJcblx0XHRcdHRhcmdldC55KTtcclxuXHR9XHJcbn07XHJcblxyXG52YXIgaGVscGVyc19jYW52YXMgPSBleHBvcnRzJDE7XHJcblxyXG4vLyBERVBSRUNBVElPTlNcclxuXHJcbi8qKlxyXG4gKiBQcm92aWRlZCBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSwgdXNlIENoYXJ0LmhlbHBlcnMuY2FudmFzLmNsZWFyIGluc3RlYWQuXHJcbiAqIEBuYW1lc3BhY2UgQ2hhcnQuaGVscGVycy5jbGVhclxyXG4gKiBAZGVwcmVjYXRlZCBzaW5jZSB2ZXJzaW9uIDIuNy4wXHJcbiAqIEB0b2RvIHJlbW92ZSBhdCB2ZXJzaW9uIDNcclxuICogQHByaXZhdGVcclxuICovXHJcbmhlbHBlcnNfY29yZS5jbGVhciA9IGV4cG9ydHMkMS5jbGVhcjtcclxuXHJcbi8qKlxyXG4gKiBQcm92aWRlZCBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSwgdXNlIENoYXJ0LmhlbHBlcnMuY2FudmFzLnJvdW5kZWRSZWN0IGluc3RlYWQuXHJcbiAqIEBuYW1lc3BhY2UgQ2hhcnQuaGVscGVycy5kcmF3Um91bmRlZFJlY3RhbmdsZVxyXG4gKiBAZGVwcmVjYXRlZCBzaW5jZSB2ZXJzaW9uIDIuNy4wXHJcbiAqIEB0b2RvIHJlbW92ZSBhdCB2ZXJzaW9uIDNcclxuICogQHByaXZhdGVcclxuICovXHJcbmhlbHBlcnNfY29yZS5kcmF3Um91bmRlZFJlY3RhbmdsZSA9IGZ1bmN0aW9uKGN0eCkge1xyXG5cdGN0eC5iZWdpblBhdGgoKTtcclxuXHRleHBvcnRzJDEucm91bmRlZFJlY3QuYXBwbHkoZXhwb3J0cyQxLCBhcmd1bWVudHMpO1xyXG59O1xuXG52YXIgZGVmYXVsdHMgPSB7XHJcblx0LyoqXHJcblx0ICogQHByaXZhdGVcclxuXHQgKi9cclxuXHRfc2V0OiBmdW5jdGlvbihzY29wZSwgdmFsdWVzKSB7XHJcblx0XHRyZXR1cm4gaGVscGVyc19jb3JlLm1lcmdlKHRoaXNbc2NvcGVdIHx8ICh0aGlzW3Njb3BlXSA9IHt9KSwgdmFsdWVzKTtcclxuXHR9XHJcbn07XHJcblxyXG4vLyBUT0RPKHYzKTogcmVtb3ZlICdnbG9iYWwnIGZyb20gbmFtZXNwYWNlLiAgYWxsIGRlZmF1bHQgYXJlIGdsb2JhbCBhbmRcclxuLy8gdGhlcmUncyBpbmNvbnNpc3RlbmN5IGFyb3VuZCB3aGljaCBvcHRpb25zIGFyZSB1bmRlciAnZ2xvYmFsJ1xyXG5kZWZhdWx0cy5fc2V0KCdnbG9iYWwnLCB7XHJcblx0ZGVmYXVsdENvbG9yOiAncmdiYSgwLDAsMCwwLjEpJyxcclxuXHRkZWZhdWx0Rm9udENvbG9yOiAnIzY2NicsXHJcblx0ZGVmYXVsdEZvbnRGYW1pbHk6IFwiJ0hlbHZldGljYSBOZXVlJywgJ0hlbHZldGljYScsICdBcmlhbCcsIHNhbnMtc2VyaWZcIixcclxuXHRkZWZhdWx0Rm9udFNpemU6IDEyLFxyXG5cdGRlZmF1bHRGb250U3R5bGU6ICdub3JtYWwnLFxyXG5cdGRlZmF1bHRMaW5lSGVpZ2h0OiAxLjIsXHJcblx0c2hvd0xpbmVzOiB0cnVlXHJcbn0pO1xyXG5cclxudmFyIGNvcmVfZGVmYXVsdHMgPSBkZWZhdWx0cztcblxudmFyIHZhbHVlT3JEZWZhdWx0ID0gaGVscGVyc19jb3JlLnZhbHVlT3JEZWZhdWx0O1xyXG5cclxuLyoqXHJcbiAqIENvbnZlcnRzIHRoZSBnaXZlbiBmb250IG9iamVjdCBpbnRvIGEgQ1NTIGZvbnQgc3RyaW5nLlxyXG4gKiBAcGFyYW0ge29iamVjdH0gZm9udCAtIEEgZm9udCBvYmplY3QuXHJcbiAqIEByZXR1cm4ge3N0cmluZ30gVGhlIENTUyBmb250IHN0cmluZy4gU2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0NTUy9mb250XHJcbiAqIEBwcml2YXRlXHJcbiAqL1xyXG5mdW5jdGlvbiB0b0ZvbnRTdHJpbmcoZm9udCkge1xyXG5cdGlmICghZm9udCB8fCBoZWxwZXJzX2NvcmUuaXNOdWxsT3JVbmRlZihmb250LnNpemUpIHx8IGhlbHBlcnNfY29yZS5pc051bGxPclVuZGVmKGZvbnQuZmFtaWx5KSkge1xyXG5cdFx0cmV0dXJuIG51bGw7XHJcblx0fVxyXG5cclxuXHRyZXR1cm4gKGZvbnQuc3R5bGUgPyBmb250LnN0eWxlICsgJyAnIDogJycpXHJcblx0XHQrIChmb250LndlaWdodCA/IGZvbnQud2VpZ2h0ICsgJyAnIDogJycpXHJcblx0XHQrIGZvbnQuc2l6ZSArICdweCAnXHJcblx0XHQrIGZvbnQuZmFtaWx5O1xyXG59XHJcblxyXG4vKipcclxuICogQGFsaWFzIENoYXJ0LmhlbHBlcnMub3B0aW9uc1xyXG4gKiBAbmFtZXNwYWNlXHJcbiAqL1xyXG52YXIgaGVscGVyc19vcHRpb25zID0ge1xyXG5cdC8qKlxyXG5cdCAqIENvbnZlcnRzIHRoZSBnaXZlbiBsaW5lIGhlaWdodCBgdmFsdWVgIGluIHBpeGVscyBmb3IgYSBzcGVjaWZpYyBmb250IGBzaXplYC5cclxuXHQgKiBAcGFyYW0ge251bWJlcnxzdHJpbmd9IHZhbHVlIC0gVGhlIGxpbmVIZWlnaHQgdG8gcGFyc2UgKGVnLiAxLjYsICcxNHB4JywgJzc1JScsICcxLjZlbScpLlxyXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBzaXplIC0gVGhlIGZvbnQgc2l6ZSAoaW4gcGl4ZWxzKSB1c2VkIHRvIHJlc29sdmUgcmVsYXRpdmUgYHZhbHVlYC5cclxuXHQgKiBAcmV0dXJucyB7bnVtYmVyfSBUaGUgZWZmZWN0aXZlIGxpbmUgaGVpZ2h0IGluIHBpeGVscyAoc2l6ZSAqIDEuMiBpZiB2YWx1ZSBpcyBpbnZhbGlkKS5cclxuXHQgKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0NTUy9saW5lLWhlaWdodFxyXG5cdCAqIEBzaW5jZSAyLjcuMFxyXG5cdCAqL1xyXG5cdHRvTGluZUhlaWdodDogZnVuY3Rpb24odmFsdWUsIHNpemUpIHtcclxuXHRcdHZhciBtYXRjaGVzID0gKCcnICsgdmFsdWUpLm1hdGNoKC9eKG5vcm1hbHwoXFxkKyg/OlxcLlxcZCspPykocHh8ZW18JSk/KSQvKTtcclxuXHRcdGlmICghbWF0Y2hlcyB8fCBtYXRjaGVzWzFdID09PSAnbm9ybWFsJykge1xyXG5cdFx0XHRyZXR1cm4gc2l6ZSAqIDEuMjtcclxuXHRcdH1cclxuXHJcblx0XHR2YWx1ZSA9ICttYXRjaGVzWzJdO1xyXG5cclxuXHRcdHN3aXRjaCAobWF0Y2hlc1szXSkge1xyXG5cdFx0Y2FzZSAncHgnOlxyXG5cdFx0XHRyZXR1cm4gdmFsdWU7XHJcblx0XHRjYXNlICclJzpcclxuXHRcdFx0dmFsdWUgLz0gMTAwO1xyXG5cdFx0XHRicmVhaztcclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gc2l6ZSAqIHZhbHVlO1xyXG5cdH0sXHJcblxyXG5cdC8qKlxyXG5cdCAqIENvbnZlcnRzIHRoZSBnaXZlbiB2YWx1ZSBpbnRvIGEgcGFkZGluZyBvYmplY3Qgd2l0aCBwcmUtY29tcHV0ZWQgd2lkdGgvaGVpZ2h0LlxyXG5cdCAqIEBwYXJhbSB7bnVtYmVyfG9iamVjdH0gdmFsdWUgLSBJZiBhIG51bWJlciwgc2V0IHRoZSB2YWx1ZSB0byBhbGwgVFJCTCBjb21wb25lbnQsXHJcblx0ICogIGVsc2UsIGlmIGFuZCBvYmplY3QsIHVzZSBkZWZpbmVkIHByb3BlcnRpZXMgYW5kIHNldHMgdW5kZWZpbmVkIG9uZXMgdG8gMC5cclxuXHQgKiBAcmV0dXJucyB7b2JqZWN0fSBUaGUgcGFkZGluZyB2YWx1ZXMgKHRvcCwgcmlnaHQsIGJvdHRvbSwgbGVmdCwgd2lkdGgsIGhlaWdodClcclxuXHQgKiBAc2luY2UgMi43LjBcclxuXHQgKi9cclxuXHR0b1BhZGRpbmc6IGZ1bmN0aW9uKHZhbHVlKSB7XHJcblx0XHR2YXIgdCwgciwgYiwgbDtcclxuXHJcblx0XHRpZiAoaGVscGVyc19jb3JlLmlzT2JqZWN0KHZhbHVlKSkge1xyXG5cdFx0XHR0ID0gK3ZhbHVlLnRvcCB8fCAwO1xyXG5cdFx0XHRyID0gK3ZhbHVlLnJpZ2h0IHx8IDA7XHJcblx0XHRcdGIgPSArdmFsdWUuYm90dG9tIHx8IDA7XHJcblx0XHRcdGwgPSArdmFsdWUubGVmdCB8fCAwO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0dCA9IHIgPSBiID0gbCA9ICt2YWx1ZSB8fCAwO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiB7XHJcblx0XHRcdHRvcDogdCxcclxuXHRcdFx0cmlnaHQ6IHIsXHJcblx0XHRcdGJvdHRvbTogYixcclxuXHRcdFx0bGVmdDogbCxcclxuXHRcdFx0aGVpZ2h0OiB0ICsgYixcclxuXHRcdFx0d2lkdGg6IGwgKyByXHJcblx0XHR9O1xyXG5cdH0sXHJcblxyXG5cdC8qKlxyXG5cdCAqIFBhcnNlcyBmb250IG9wdGlvbnMgYW5kIHJldHVybnMgdGhlIGZvbnQgb2JqZWN0LlxyXG5cdCAqIEBwYXJhbSB7b2JqZWN0fSBvcHRpb25zIC0gQSBvYmplY3QgdGhhdCBjb250YWlucyBmb250IG9wdGlvbnMgdG8gYmUgcGFyc2VkLlxyXG5cdCAqIEByZXR1cm4ge29iamVjdH0gVGhlIGZvbnQgb2JqZWN0LlxyXG5cdCAqIEB0b2RvIFN1cHBvcnQgZm9udC4qIG9wdGlvbnMgYW5kIHJlbmFtZWQgdG8gdG9Gb250KCkuXHJcblx0ICogQHByaXZhdGVcclxuXHQgKi9cclxuXHRfcGFyc2VGb250OiBmdW5jdGlvbihvcHRpb25zKSB7XHJcblx0XHR2YXIgZ2xvYmFsRGVmYXVsdHMgPSBjb3JlX2RlZmF1bHRzLmdsb2JhbDtcclxuXHRcdHZhciBzaXplID0gdmFsdWVPckRlZmF1bHQob3B0aW9ucy5mb250U2l6ZSwgZ2xvYmFsRGVmYXVsdHMuZGVmYXVsdEZvbnRTaXplKTtcclxuXHRcdHZhciBmb250ID0ge1xyXG5cdFx0XHRmYW1pbHk6IHZhbHVlT3JEZWZhdWx0KG9wdGlvbnMuZm9udEZhbWlseSwgZ2xvYmFsRGVmYXVsdHMuZGVmYXVsdEZvbnRGYW1pbHkpLFxyXG5cdFx0XHRsaW5lSGVpZ2h0OiBoZWxwZXJzX2NvcmUub3B0aW9ucy50b0xpbmVIZWlnaHQodmFsdWVPckRlZmF1bHQob3B0aW9ucy5saW5lSGVpZ2h0LCBnbG9iYWxEZWZhdWx0cy5kZWZhdWx0TGluZUhlaWdodCksIHNpemUpLFxyXG5cdFx0XHRzaXplOiBzaXplLFxyXG5cdFx0XHRzdHlsZTogdmFsdWVPckRlZmF1bHQob3B0aW9ucy5mb250U3R5bGUsIGdsb2JhbERlZmF1bHRzLmRlZmF1bHRGb250U3R5bGUpLFxyXG5cdFx0XHR3ZWlnaHQ6IG51bGwsXHJcblx0XHRcdHN0cmluZzogJydcclxuXHRcdH07XHJcblxyXG5cdFx0Zm9udC5zdHJpbmcgPSB0b0ZvbnRTdHJpbmcoZm9udCk7XHJcblx0XHRyZXR1cm4gZm9udDtcclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBFdmFsdWF0ZXMgdGhlIGdpdmVuIGBpbnB1dHNgIHNlcXVlbnRpYWxseSBhbmQgcmV0dXJucyB0aGUgZmlyc3QgZGVmaW5lZCB2YWx1ZS5cclxuXHQgKiBAcGFyYW0ge0FycmF5fSBpbnB1dHMgLSBBbiBhcnJheSBvZiB2YWx1ZXMsIGZhbGxpbmcgYmFjayB0byB0aGUgbGFzdCB2YWx1ZS5cclxuXHQgKiBAcGFyYW0ge29iamVjdH0gW2NvbnRleHRdIC0gSWYgZGVmaW5lZCBhbmQgdGhlIGN1cnJlbnQgdmFsdWUgaXMgYSBmdW5jdGlvbiwgdGhlIHZhbHVlXHJcblx0ICogaXMgY2FsbGVkIHdpdGggYGNvbnRleHRgIGFzIGZpcnN0IGFyZ3VtZW50IGFuZCB0aGUgcmVzdWx0IGJlY29tZXMgdGhlIG5ldyBpbnB1dC5cclxuXHQgKiBAcGFyYW0ge251bWJlcn0gW2luZGV4XSAtIElmIGRlZmluZWQgYW5kIHRoZSBjdXJyZW50IHZhbHVlIGlzIGFuIGFycmF5LCB0aGUgdmFsdWVcclxuXHQgKiBhdCBgaW5kZXhgIGJlY29tZSB0aGUgbmV3IGlucHV0LlxyXG5cdCAqIEBwYXJhbSB7b2JqZWN0fSBbaW5mb10gLSBvYmplY3QgdG8gcmV0dXJuIGluZm9ybWF0aW9uIGFib3V0IHJlc29sdXRpb24gaW5cclxuXHQgKiBAcGFyYW0ge2Jvb2xlYW59IFtpbmZvLmNhY2hlYWJsZV0gLSBXaWxsIGJlIHNldCB0byBgZmFsc2VgIGlmIG9wdGlvbiBpcyBub3QgY2FjaGVhYmxlLlxyXG5cdCAqIEBzaW5jZSAyLjcuMFxyXG5cdCAqL1xyXG5cdHJlc29sdmU6IGZ1bmN0aW9uKGlucHV0cywgY29udGV4dCwgaW5kZXgsIGluZm8pIHtcclxuXHRcdHZhciBjYWNoZWFibGUgPSB0cnVlO1xyXG5cdFx0dmFyIGksIGlsZW4sIHZhbHVlO1xyXG5cclxuXHRcdGZvciAoaSA9IDAsIGlsZW4gPSBpbnB1dHMubGVuZ3RoOyBpIDwgaWxlbjsgKytpKSB7XHJcblx0XHRcdHZhbHVlID0gaW5wdXRzW2ldO1xyXG5cdFx0XHRpZiAodmFsdWUgPT09IHVuZGVmaW5lZCkge1xyXG5cdFx0XHRcdGNvbnRpbnVlO1xyXG5cdFx0XHR9XHJcblx0XHRcdGlmIChjb250ZXh0ICE9PSB1bmRlZmluZWQgJiYgdHlwZW9mIHZhbHVlID09PSAnZnVuY3Rpb24nKSB7XHJcblx0XHRcdFx0dmFsdWUgPSB2YWx1ZShjb250ZXh0KTtcclxuXHRcdFx0XHRjYWNoZWFibGUgPSBmYWxzZTtcclxuXHRcdFx0fVxyXG5cdFx0XHRpZiAoaW5kZXggIT09IHVuZGVmaW5lZCAmJiBoZWxwZXJzX2NvcmUuaXNBcnJheSh2YWx1ZSkpIHtcclxuXHRcdFx0XHR2YWx1ZSA9IHZhbHVlW2luZGV4XTtcclxuXHRcdFx0XHRjYWNoZWFibGUgPSBmYWxzZTtcclxuXHRcdFx0fVxyXG5cdFx0XHRpZiAodmFsdWUgIT09IHVuZGVmaW5lZCkge1xyXG5cdFx0XHRcdGlmIChpbmZvICYmICFjYWNoZWFibGUpIHtcclxuXHRcdFx0XHRcdGluZm8uY2FjaGVhYmxlID0gZmFsc2U7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdHJldHVybiB2YWx1ZTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdH1cclxufTtcblxuLyoqXHJcbiAqIEBhbGlhcyBDaGFydC5oZWxwZXJzLm1hdGhcclxuICogQG5hbWVzcGFjZVxyXG4gKi9cclxudmFyIGV4cG9ydHMkMiA9IHtcclxuXHQvKipcclxuXHQgKiBSZXR1cm5zIGFuIGFycmF5IG9mIGZhY3RvcnMgc29ydGVkIGZyb20gMSB0byBzcXJ0KHZhbHVlKVxyXG5cdCAqIEBwcml2YXRlXHJcblx0ICovXHJcblx0X2ZhY3Rvcml6ZTogZnVuY3Rpb24odmFsdWUpIHtcclxuXHRcdHZhciByZXN1bHQgPSBbXTtcclxuXHRcdHZhciBzcXJ0ID0gTWF0aC5zcXJ0KHZhbHVlKTtcclxuXHRcdHZhciBpO1xyXG5cclxuXHRcdGZvciAoaSA9IDE7IGkgPCBzcXJ0OyBpKyspIHtcclxuXHRcdFx0aWYgKHZhbHVlICUgaSA9PT0gMCkge1xyXG5cdFx0XHRcdHJlc3VsdC5wdXNoKGkpO1xyXG5cdFx0XHRcdHJlc3VsdC5wdXNoKHZhbHVlIC8gaSk7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHRcdGlmIChzcXJ0ID09PSAoc3FydCB8IDApKSB7IC8vIGlmIHZhbHVlIGlzIGEgc3F1YXJlIG51bWJlclxyXG5cdFx0XHRyZXN1bHQucHVzaChzcXJ0KTtcclxuXHRcdH1cclxuXHJcblx0XHRyZXN1bHQuc29ydChmdW5jdGlvbihhLCBiKSB7XHJcblx0XHRcdHJldHVybiBhIC0gYjtcclxuXHRcdH0pLnBvcCgpO1xyXG5cdFx0cmV0dXJuIHJlc3VsdDtcclxuXHR9LFxyXG5cclxuXHRsb2cxMDogTWF0aC5sb2cxMCB8fCBmdW5jdGlvbih4KSB7XHJcblx0XHR2YXIgZXhwb25lbnQgPSBNYXRoLmxvZyh4KSAqIE1hdGguTE9HMTBFOyAvLyBNYXRoLkxPRzEwRSA9IDEgLyBNYXRoLkxOMTAuXHJcblx0XHQvLyBDaGVjayBmb3Igd2hvbGUgcG93ZXJzIG9mIDEwLFxyXG5cdFx0Ly8gd2hpY2ggZHVlIHRvIGZsb2F0aW5nIHBvaW50IHJvdW5kaW5nIGVycm9yIHNob3VsZCBiZSBjb3JyZWN0ZWQuXHJcblx0XHR2YXIgcG93ZXJPZjEwID0gTWF0aC5yb3VuZChleHBvbmVudCk7XHJcblx0XHR2YXIgaXNQb3dlck9mMTAgPSB4ID09PSBNYXRoLnBvdygxMCwgcG93ZXJPZjEwKTtcclxuXHJcblx0XHRyZXR1cm4gaXNQb3dlck9mMTAgPyBwb3dlck9mMTAgOiBleHBvbmVudDtcclxuXHR9XHJcbn07XHJcblxyXG52YXIgaGVscGVyc19tYXRoID0gZXhwb3J0cyQyO1xyXG5cclxuLy8gREVQUkVDQVRJT05TXHJcblxyXG4vKipcclxuICogUHJvdmlkZWQgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHksIHVzZSBDaGFydC5oZWxwZXJzLm1hdGgubG9nMTAgaW5zdGVhZC5cclxuICogQG5hbWVzcGFjZSBDaGFydC5oZWxwZXJzLmxvZzEwXHJcbiAqIEBkZXByZWNhdGVkIHNpbmNlIHZlcnNpb24gMi45LjBcclxuICogQHRvZG8gcmVtb3ZlIGF0IHZlcnNpb24gM1xyXG4gKiBAcHJpdmF0ZVxyXG4gKi9cclxuaGVscGVyc19jb3JlLmxvZzEwID0gZXhwb3J0cyQyLmxvZzEwO1xuXG52YXIgZ2V0UnRsQWRhcHRlciA9IGZ1bmN0aW9uKHJlY3RYLCB3aWR0aCkge1xyXG5cdHJldHVybiB7XHJcblx0XHR4OiBmdW5jdGlvbih4KSB7XHJcblx0XHRcdHJldHVybiByZWN0WCArIHJlY3RYICsgd2lkdGggLSB4O1xyXG5cdFx0fSxcclxuXHRcdHNldFdpZHRoOiBmdW5jdGlvbih3KSB7XHJcblx0XHRcdHdpZHRoID0gdztcclxuXHRcdH0sXHJcblx0XHR0ZXh0QWxpZ246IGZ1bmN0aW9uKGFsaWduKSB7XHJcblx0XHRcdGlmIChhbGlnbiA9PT0gJ2NlbnRlcicpIHtcclxuXHRcdFx0XHRyZXR1cm4gYWxpZ247XHJcblx0XHRcdH1cclxuXHRcdFx0cmV0dXJuIGFsaWduID09PSAncmlnaHQnID8gJ2xlZnQnIDogJ3JpZ2h0JztcclxuXHRcdH0sXHJcblx0XHR4UGx1czogZnVuY3Rpb24oeCwgdmFsdWUpIHtcclxuXHRcdFx0cmV0dXJuIHggLSB2YWx1ZTtcclxuXHRcdH0sXHJcblx0XHRsZWZ0Rm9yTHRyOiBmdW5jdGlvbih4LCBpdGVtV2lkdGgpIHtcclxuXHRcdFx0cmV0dXJuIHggLSBpdGVtV2lkdGg7XHJcblx0XHR9LFxyXG5cdH07XHJcbn07XHJcblxyXG52YXIgZ2V0THRyQWRhcHRlciA9IGZ1bmN0aW9uKCkge1xyXG5cdHJldHVybiB7XHJcblx0XHR4OiBmdW5jdGlvbih4KSB7XHJcblx0XHRcdHJldHVybiB4O1xyXG5cdFx0fSxcclxuXHRcdHNldFdpZHRoOiBmdW5jdGlvbih3KSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLXZhcnNcclxuXHRcdH0sXHJcblx0XHR0ZXh0QWxpZ246IGZ1bmN0aW9uKGFsaWduKSB7XHJcblx0XHRcdHJldHVybiBhbGlnbjtcclxuXHRcdH0sXHJcblx0XHR4UGx1czogZnVuY3Rpb24oeCwgdmFsdWUpIHtcclxuXHRcdFx0cmV0dXJuIHggKyB2YWx1ZTtcclxuXHRcdH0sXHJcblx0XHRsZWZ0Rm9yTHRyOiBmdW5jdGlvbih4LCBfaXRlbVdpZHRoKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgbm8tdW51c2VkLXZhcnNcclxuXHRcdFx0cmV0dXJuIHg7XHJcblx0XHR9LFxyXG5cdH07XHJcbn07XHJcblxyXG52YXIgZ2V0QWRhcHRlciA9IGZ1bmN0aW9uKHJ0bCwgcmVjdFgsIHdpZHRoKSB7XHJcblx0cmV0dXJuIHJ0bCA/IGdldFJ0bEFkYXB0ZXIocmVjdFgsIHdpZHRoKSA6IGdldEx0ckFkYXB0ZXIoKTtcclxufTtcclxuXHJcbnZhciBvdmVycmlkZVRleHREaXJlY3Rpb24gPSBmdW5jdGlvbihjdHgsIGRpcmVjdGlvbikge1xyXG5cdHZhciBzdHlsZSwgb3JpZ2luYWw7XHJcblx0aWYgKGRpcmVjdGlvbiA9PT0gJ2x0cicgfHwgZGlyZWN0aW9uID09PSAncnRsJykge1xyXG5cdFx0c3R5bGUgPSBjdHguY2FudmFzLnN0eWxlO1xyXG5cdFx0b3JpZ2luYWwgPSBbXHJcblx0XHRcdHN0eWxlLmdldFByb3BlcnR5VmFsdWUoJ2RpcmVjdGlvbicpLFxyXG5cdFx0XHRzdHlsZS5nZXRQcm9wZXJ0eVByaW9yaXR5KCdkaXJlY3Rpb24nKSxcclxuXHRcdF07XHJcblxyXG5cdFx0c3R5bGUuc2V0UHJvcGVydHkoJ2RpcmVjdGlvbicsIGRpcmVjdGlvbiwgJ2ltcG9ydGFudCcpO1xyXG5cdFx0Y3R4LnByZXZUZXh0RGlyZWN0aW9uID0gb3JpZ2luYWw7XHJcblx0fVxyXG59O1xyXG5cclxudmFyIHJlc3RvcmVUZXh0RGlyZWN0aW9uID0gZnVuY3Rpb24oY3R4KSB7XHJcblx0dmFyIG9yaWdpbmFsID0gY3R4LnByZXZUZXh0RGlyZWN0aW9uO1xyXG5cdGlmIChvcmlnaW5hbCAhPT0gdW5kZWZpbmVkKSB7XHJcblx0XHRkZWxldGUgY3R4LnByZXZUZXh0RGlyZWN0aW9uO1xyXG5cdFx0Y3R4LmNhbnZhcy5zdHlsZS5zZXRQcm9wZXJ0eSgnZGlyZWN0aW9uJywgb3JpZ2luYWxbMF0sIG9yaWdpbmFsWzFdKTtcclxuXHR9XHJcbn07XHJcblxyXG52YXIgaGVscGVyc19ydGwgPSB7XHJcblx0Z2V0UnRsQWRhcHRlcjogZ2V0QWRhcHRlcixcclxuXHRvdmVycmlkZVRleHREaXJlY3Rpb246IG92ZXJyaWRlVGV4dERpcmVjdGlvbixcclxuXHRyZXN0b3JlVGV4dERpcmVjdGlvbjogcmVzdG9yZVRleHREaXJlY3Rpb24sXHJcbn07XG5cbnZhciBoZWxwZXJzJDEgPSBoZWxwZXJzX2NvcmU7XHJcbnZhciBlYXNpbmcgPSBoZWxwZXJzX2Vhc2luZztcclxudmFyIGNhbnZhcyA9IGhlbHBlcnNfY2FudmFzO1xyXG52YXIgb3B0aW9ucyA9IGhlbHBlcnNfb3B0aW9ucztcclxudmFyIG1hdGggPSBoZWxwZXJzX21hdGg7XHJcbnZhciBydGwgPSBoZWxwZXJzX3J0bDtcbmhlbHBlcnMkMS5lYXNpbmcgPSBlYXNpbmc7XG5oZWxwZXJzJDEuY2FudmFzID0gY2FudmFzO1xuaGVscGVycyQxLm9wdGlvbnMgPSBvcHRpb25zO1xuaGVscGVycyQxLm1hdGggPSBtYXRoO1xuaGVscGVycyQxLnJ0bCA9IHJ0bDtcblxuZnVuY3Rpb24gaW50ZXJwb2xhdGUoc3RhcnQsIHZpZXcsIG1vZGVsLCBlYXNlKSB7XHJcblx0dmFyIGtleXMgPSBPYmplY3Qua2V5cyhtb2RlbCk7XHJcblx0dmFyIGksIGlsZW4sIGtleSwgYWN0dWFsLCBvcmlnaW4sIHRhcmdldCwgdHlwZSwgYzAsIGMxO1xyXG5cclxuXHRmb3IgKGkgPSAwLCBpbGVuID0ga2V5cy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcclxuXHRcdGtleSA9IGtleXNbaV07XHJcblxyXG5cdFx0dGFyZ2V0ID0gbW9kZWxba2V5XTtcclxuXHJcblx0XHQvLyBpZiBhIHZhbHVlIGlzIGFkZGVkIHRvIHRoZSBtb2RlbCBhZnRlciBwaXZvdCgpIGhhcyBiZWVuIGNhbGxlZCwgdGhlIHZpZXdcclxuXHRcdC8vIGRvZXNuJ3QgY29udGFpbiBpdCwgc28gbGV0J3MgaW5pdGlhbGl6ZSB0aGUgdmlldyB0byB0aGUgdGFyZ2V0IHZhbHVlLlxyXG5cdFx0aWYgKCF2aWV3Lmhhc093blByb3BlcnR5KGtleSkpIHtcclxuXHRcdFx0dmlld1trZXldID0gdGFyZ2V0O1xyXG5cdFx0fVxyXG5cclxuXHRcdGFjdHVhbCA9IHZpZXdba2V5XTtcclxuXHJcblx0XHRpZiAoYWN0dWFsID09PSB0YXJnZXQgfHwga2V5WzBdID09PSAnXycpIHtcclxuXHRcdFx0Y29udGludWU7XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKCFzdGFydC5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XHJcblx0XHRcdHN0YXJ0W2tleV0gPSBhY3R1YWw7XHJcblx0XHR9XHJcblxyXG5cdFx0b3JpZ2luID0gc3RhcnRba2V5XTtcclxuXHJcblx0XHR0eXBlID0gdHlwZW9mIHRhcmdldDtcclxuXHJcblx0XHRpZiAodHlwZSA9PT0gdHlwZW9mIG9yaWdpbikge1xyXG5cdFx0XHRpZiAodHlwZSA9PT0gJ3N0cmluZycpIHtcclxuXHRcdFx0XHRjMCA9IGNoYXJ0anNDb2xvcihvcmlnaW4pO1xyXG5cdFx0XHRcdGlmIChjMC52YWxpZCkge1xyXG5cdFx0XHRcdFx0YzEgPSBjaGFydGpzQ29sb3IodGFyZ2V0KTtcclxuXHRcdFx0XHRcdGlmIChjMS52YWxpZCkge1xyXG5cdFx0XHRcdFx0XHR2aWV3W2tleV0gPSBjMS5taXgoYzAsIGVhc2UpLnJnYlN0cmluZygpO1xyXG5cdFx0XHRcdFx0XHRjb250aW51ZTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblx0XHRcdH0gZWxzZSBpZiAoaGVscGVycyQxLmlzRmluaXRlKG9yaWdpbikgJiYgaGVscGVycyQxLmlzRmluaXRlKHRhcmdldCkpIHtcclxuXHRcdFx0XHR2aWV3W2tleV0gPSBvcmlnaW4gKyAodGFyZ2V0IC0gb3JpZ2luKSAqIGVhc2U7XHJcblx0XHRcdFx0Y29udGludWU7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHR2aWV3W2tleV0gPSB0YXJnZXQ7XHJcblx0fVxyXG59XHJcblxyXG52YXIgRWxlbWVudCA9IGZ1bmN0aW9uKGNvbmZpZ3VyYXRpb24pIHtcclxuXHRoZWxwZXJzJDEuZXh0ZW5kKHRoaXMsIGNvbmZpZ3VyYXRpb24pO1xyXG5cdHRoaXMuaW5pdGlhbGl6ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xyXG59O1xyXG5cclxuaGVscGVycyQxLmV4dGVuZChFbGVtZW50LnByb3RvdHlwZSwge1xyXG5cdF90eXBlOiB1bmRlZmluZWQsXHJcblxyXG5cdGluaXRpYWxpemU6IGZ1bmN0aW9uKCkge1xyXG5cdFx0dGhpcy5oaWRkZW4gPSBmYWxzZTtcclxuXHR9LFxyXG5cclxuXHRwaXZvdDogZnVuY3Rpb24oKSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0aWYgKCFtZS5fdmlldykge1xyXG5cdFx0XHRtZS5fdmlldyA9IGhlbHBlcnMkMS5leHRlbmQoe30sIG1lLl9tb2RlbCk7XHJcblx0XHR9XHJcblx0XHRtZS5fc3RhcnQgPSB7fTtcclxuXHRcdHJldHVybiBtZTtcclxuXHR9LFxyXG5cclxuXHR0cmFuc2l0aW9uOiBmdW5jdGlvbihlYXNlKSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0dmFyIG1vZGVsID0gbWUuX21vZGVsO1xyXG5cdFx0dmFyIHN0YXJ0ID0gbWUuX3N0YXJ0O1xyXG5cdFx0dmFyIHZpZXcgPSBtZS5fdmlldztcclxuXHJcblx0XHQvLyBObyBhbmltYXRpb24gLT4gTm8gVHJhbnNpdGlvblxyXG5cdFx0aWYgKCFtb2RlbCB8fCBlYXNlID09PSAxKSB7XHJcblx0XHRcdG1lLl92aWV3ID0gaGVscGVycyQxLmV4dGVuZCh7fSwgbW9kZWwpO1xyXG5cdFx0XHRtZS5fc3RhcnQgPSBudWxsO1xyXG5cdFx0XHRyZXR1cm4gbWU7XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKCF2aWV3KSB7XHJcblx0XHRcdHZpZXcgPSBtZS5fdmlldyA9IHt9O1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmICghc3RhcnQpIHtcclxuXHRcdFx0c3RhcnQgPSBtZS5fc3RhcnQgPSB7fTtcclxuXHRcdH1cclxuXHJcblx0XHRpbnRlcnBvbGF0ZShzdGFydCwgdmlldywgbW9kZWwsIGVhc2UpO1xyXG5cclxuXHRcdHJldHVybiBtZTtcclxuXHR9LFxyXG5cclxuXHR0b29sdGlwUG9zaXRpb246IGZ1bmN0aW9uKCkge1xyXG5cdFx0cmV0dXJuIHtcclxuXHRcdFx0eDogdGhpcy5fbW9kZWwueCxcclxuXHRcdFx0eTogdGhpcy5fbW9kZWwueVxyXG5cdFx0fTtcclxuXHR9LFxyXG5cclxuXHRoYXNWYWx1ZTogZnVuY3Rpb24oKSB7XHJcblx0XHRyZXR1cm4gaGVscGVycyQxLmlzTnVtYmVyKHRoaXMuX21vZGVsLngpICYmIGhlbHBlcnMkMS5pc051bWJlcih0aGlzLl9tb2RlbC55KTtcclxuXHR9XHJcbn0pO1xyXG5cclxuRWxlbWVudC5leHRlbmQgPSBoZWxwZXJzJDEuaW5oZXJpdHM7XHJcblxyXG52YXIgY29yZV9lbGVtZW50ID0gRWxlbWVudDtcblxudmFyIGV4cG9ydHMkMyA9IGNvcmVfZWxlbWVudC5leHRlbmQoe1xyXG5cdGNoYXJ0OiBudWxsLCAvLyB0aGUgYW5pbWF0aW9uIGFzc29jaWF0ZWQgY2hhcnQgaW5zdGFuY2VcclxuXHRjdXJyZW50U3RlcDogMCwgLy8gdGhlIGN1cnJlbnQgYW5pbWF0aW9uIHN0ZXBcclxuXHRudW1TdGVwczogNjAsIC8vIGRlZmF1bHQgbnVtYmVyIG9mIHN0ZXBzXHJcblx0ZWFzaW5nOiAnJywgLy8gdGhlIGVhc2luZyB0byB1c2UgZm9yIHRoaXMgYW5pbWF0aW9uXHJcblx0cmVuZGVyOiBudWxsLCAvLyByZW5kZXIgZnVuY3Rpb24gdXNlZCBieSB0aGUgYW5pbWF0aW9uIHNlcnZpY2VcclxuXHJcblx0b25BbmltYXRpb25Qcm9ncmVzczogbnVsbCwgLy8gdXNlciBzcGVjaWZpZWQgY2FsbGJhY2sgdG8gZmlyZSBvbiBlYWNoIHN0ZXAgb2YgdGhlIGFuaW1hdGlvblxyXG5cdG9uQW5pbWF0aW9uQ29tcGxldGU6IG51bGwsIC8vIHVzZXIgc3BlY2lmaWVkIGNhbGxiYWNrIHRvIGZpcmUgd2hlbiB0aGUgYW5pbWF0aW9uIGZpbmlzaGVzXHJcbn0pO1xyXG5cclxudmFyIGNvcmVfYW5pbWF0aW9uID0gZXhwb3J0cyQzO1xyXG5cclxuLy8gREVQUkVDQVRJT05TXHJcblxyXG4vKipcclxuICogUHJvdmlkZWQgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHksIHVzZSBDaGFydC5BbmltYXRpb24gaW5zdGVhZFxyXG4gKiBAcHJvcCBDaGFydC5BbmltYXRpb24jYW5pbWF0aW9uT2JqZWN0XHJcbiAqIEBkZXByZWNhdGVkIHNpbmNlIHZlcnNpb24gMi42LjBcclxuICogQHRvZG8gcmVtb3ZlIGF0IHZlcnNpb24gM1xyXG4gKi9cclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMkMy5wcm90b3R5cGUsICdhbmltYXRpb25PYmplY3QnLCB7XHJcblx0Z2V0OiBmdW5jdGlvbigpIHtcclxuXHRcdHJldHVybiB0aGlzO1xyXG5cdH1cclxufSk7XHJcblxyXG4vKipcclxuICogUHJvdmlkZWQgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHksIHVzZSBDaGFydC5BbmltYXRpb24jY2hhcnQgaW5zdGVhZFxyXG4gKiBAcHJvcCBDaGFydC5BbmltYXRpb24jY2hhcnRJbnN0YW5jZVxyXG4gKiBAZGVwcmVjYXRlZCBzaW5jZSB2ZXJzaW9uIDIuNi4wXHJcbiAqIEB0b2RvIHJlbW92ZSBhdCB2ZXJzaW9uIDNcclxuICovXHJcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzJDMucHJvdG90eXBlLCAnY2hhcnRJbnN0YW5jZScsIHtcclxuXHRnZXQ6IGZ1bmN0aW9uKCkge1xyXG5cdFx0cmV0dXJuIHRoaXMuY2hhcnQ7XHJcblx0fSxcclxuXHRzZXQ6IGZ1bmN0aW9uKHZhbHVlKSB7XHJcblx0XHR0aGlzLmNoYXJ0ID0gdmFsdWU7XHJcblx0fVxyXG59KTtcblxuY29yZV9kZWZhdWx0cy5fc2V0KCdnbG9iYWwnLCB7XHJcblx0YW5pbWF0aW9uOiB7XHJcblx0XHRkdXJhdGlvbjogMTAwMCxcclxuXHRcdGVhc2luZzogJ2Vhc2VPdXRRdWFydCcsXHJcblx0XHRvblByb2dyZXNzOiBoZWxwZXJzJDEubm9vcCxcclxuXHRcdG9uQ29tcGxldGU6IGhlbHBlcnMkMS5ub29wXHJcblx0fVxyXG59KTtcclxuXHJcbnZhciBjb3JlX2FuaW1hdGlvbnMgPSB7XHJcblx0YW5pbWF0aW9uczogW10sXHJcblx0cmVxdWVzdDogbnVsbCxcclxuXHJcblx0LyoqXHJcblx0ICogQHBhcmFtIHtDaGFydH0gY2hhcnQgLSBUaGUgY2hhcnQgdG8gYW5pbWF0ZS5cclxuXHQgKiBAcGFyYW0ge0NoYXJ0LkFuaW1hdGlvbn0gYW5pbWF0aW9uIC0gVGhlIGFuaW1hdGlvbiB0aGF0IHdlIHdpbGwgYW5pbWF0ZS5cclxuXHQgKiBAcGFyYW0ge251bWJlcn0gZHVyYXRpb24gLSBUaGUgYW5pbWF0aW9uIGR1cmF0aW9uIGluIG1zLlxyXG5cdCAqIEBwYXJhbSB7Ym9vbGVhbn0gbGF6eSAtIGlmIHRydWUsIHRoZSBjaGFydCBpcyBub3QgbWFya2VkIGFzIGFuaW1hdGluZyB0byBlbmFibGUgbW9yZSByZXNwb25zaXZlIGludGVyYWN0aW9uc1xyXG5cdCAqL1xyXG5cdGFkZEFuaW1hdGlvbjogZnVuY3Rpb24oY2hhcnQsIGFuaW1hdGlvbiwgZHVyYXRpb24sIGxhenkpIHtcclxuXHRcdHZhciBhbmltYXRpb25zID0gdGhpcy5hbmltYXRpb25zO1xyXG5cdFx0dmFyIGksIGlsZW47XHJcblxyXG5cdFx0YW5pbWF0aW9uLmNoYXJ0ID0gY2hhcnQ7XHJcblx0XHRhbmltYXRpb24uc3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcclxuXHRcdGFuaW1hdGlvbi5kdXJhdGlvbiA9IGR1cmF0aW9uO1xyXG5cclxuXHRcdGlmICghbGF6eSkge1xyXG5cdFx0XHRjaGFydC5hbmltYXRpbmcgPSB0cnVlO1xyXG5cdFx0fVxyXG5cclxuXHRcdGZvciAoaSA9IDAsIGlsZW4gPSBhbmltYXRpb25zLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xyXG5cdFx0XHRpZiAoYW5pbWF0aW9uc1tpXS5jaGFydCA9PT0gY2hhcnQpIHtcclxuXHRcdFx0XHRhbmltYXRpb25zW2ldID0gYW5pbWF0aW9uO1xyXG5cdFx0XHRcdHJldHVybjtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdGFuaW1hdGlvbnMucHVzaChhbmltYXRpb24pO1xyXG5cclxuXHRcdC8vIElmIHRoZXJlIGFyZSBubyBhbmltYXRpb25zIHF1ZXVlZCwgbWFudWFsbHkga2lja3N0YXJ0IGEgZGlnZXN0LCBmb3IgbGFjayBvZiBhIGJldHRlciB3b3JkXHJcblx0XHRpZiAoYW5pbWF0aW9ucy5sZW5ndGggPT09IDEpIHtcclxuXHRcdFx0dGhpcy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKTtcclxuXHRcdH1cclxuXHR9LFxyXG5cclxuXHRjYW5jZWxBbmltYXRpb246IGZ1bmN0aW9uKGNoYXJ0KSB7XHJcblx0XHR2YXIgaW5kZXggPSBoZWxwZXJzJDEuZmluZEluZGV4KHRoaXMuYW5pbWF0aW9ucywgZnVuY3Rpb24oYW5pbWF0aW9uKSB7XHJcblx0XHRcdHJldHVybiBhbmltYXRpb24uY2hhcnQgPT09IGNoYXJ0O1xyXG5cdFx0fSk7XHJcblxyXG5cdFx0aWYgKGluZGV4ICE9PSAtMSkge1xyXG5cdFx0XHR0aGlzLmFuaW1hdGlvbnMuc3BsaWNlKGluZGV4LCAxKTtcclxuXHRcdFx0Y2hhcnQuYW5pbWF0aW5nID0gZmFsc2U7XHJcblx0XHR9XHJcblx0fSxcclxuXHJcblx0cmVxdWVzdEFuaW1hdGlvbkZyYW1lOiBmdW5jdGlvbigpIHtcclxuXHRcdHZhciBtZSA9IHRoaXM7XHJcblx0XHRpZiAobWUucmVxdWVzdCA9PT0gbnVsbCkge1xyXG5cdFx0XHQvLyBTa2lwIGFuaW1hdGlvbiBmcmFtZSByZXF1ZXN0cyB1bnRpbCB0aGUgYWN0aXZlIG9uZSBpcyBleGVjdXRlZC5cclxuXHRcdFx0Ly8gVGhpcyBjYW4gaGFwcGVuIHdoZW4gcHJvY2Vzc2luZyBtb3VzZSBldmVudHMsIGUuZy4gJ21vdXNlbW92ZSdcclxuXHRcdFx0Ly8gYW5kICdtb3VzZW91dCcgZXZlbnRzIHdpbGwgdHJpZ2dlciBtdWx0aXBsZSByZW5kZXJzLlxyXG5cdFx0XHRtZS5yZXF1ZXN0ID0gaGVscGVycyQxLnJlcXVlc3RBbmltRnJhbWUuY2FsbCh3aW5kb3csIGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdG1lLnJlcXVlc3QgPSBudWxsO1xyXG5cdFx0XHRcdG1lLnN0YXJ0RGlnZXN0KCk7XHJcblx0XHRcdH0pO1xyXG5cdFx0fVxyXG5cdH0sXHJcblxyXG5cdC8qKlxyXG5cdCAqIEBwcml2YXRlXHJcblx0ICovXHJcblx0c3RhcnREaWdlc3Q6IGZ1bmN0aW9uKCkge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHJcblx0XHRtZS5hZHZhbmNlKCk7XHJcblxyXG5cdFx0Ly8gRG8gd2UgaGF2ZSBtb3JlIHN0dWZmIHRvIGFuaW1hdGU/XHJcblx0XHRpZiAobWUuYW5pbWF0aW9ucy5sZW5ndGggPiAwKSB7XHJcblx0XHRcdG1lLnJlcXVlc3RBbmltYXRpb25GcmFtZSgpO1xyXG5cdFx0fVxyXG5cdH0sXHJcblxyXG5cdC8qKlxyXG5cdCAqIEBwcml2YXRlXHJcblx0ICovXHJcblx0YWR2YW5jZTogZnVuY3Rpb24oKSB7XHJcblx0XHR2YXIgYW5pbWF0aW9ucyA9IHRoaXMuYW5pbWF0aW9ucztcclxuXHRcdHZhciBhbmltYXRpb24sIGNoYXJ0LCBudW1TdGVwcywgbmV4dFN0ZXA7XHJcblx0XHR2YXIgaSA9IDA7XHJcblxyXG5cdFx0Ly8gMSBhbmltYXRpb24gcGVyIGNoYXJ0LCBzbyB3ZSBhcmUgbG9vcGluZyBjaGFydHMgaGVyZVxyXG5cdFx0d2hpbGUgKGkgPCBhbmltYXRpb25zLmxlbmd0aCkge1xyXG5cdFx0XHRhbmltYXRpb24gPSBhbmltYXRpb25zW2ldO1xyXG5cdFx0XHRjaGFydCA9IGFuaW1hdGlvbi5jaGFydDtcclxuXHRcdFx0bnVtU3RlcHMgPSBhbmltYXRpb24ubnVtU3RlcHM7XHJcblxyXG5cdFx0XHQvLyBNYWtlIHN1cmUgdGhhdCBjdXJyZW50U3RlcCBzdGFydHMgYXQgMVxyXG5cdFx0XHQvLyBodHRwczovL2dpdGh1Yi5jb20vY2hhcnRqcy9DaGFydC5qcy9pc3N1ZXMvNjEwNFxyXG5cdFx0XHRuZXh0U3RlcCA9IE1hdGguZmxvb3IoKERhdGUubm93KCkgLSBhbmltYXRpb24uc3RhcnRUaW1lKSAvIGFuaW1hdGlvbi5kdXJhdGlvbiAqIG51bVN0ZXBzKSArIDE7XHJcblx0XHRcdGFuaW1hdGlvbi5jdXJyZW50U3RlcCA9IE1hdGgubWluKG5leHRTdGVwLCBudW1TdGVwcyk7XHJcblxyXG5cdFx0XHRoZWxwZXJzJDEuY2FsbGJhY2soYW5pbWF0aW9uLnJlbmRlciwgW2NoYXJ0LCBhbmltYXRpb25dLCBjaGFydCk7XHJcblx0XHRcdGhlbHBlcnMkMS5jYWxsYmFjayhhbmltYXRpb24ub25BbmltYXRpb25Qcm9ncmVzcywgW2FuaW1hdGlvbl0sIGNoYXJ0KTtcclxuXHJcblx0XHRcdGlmIChhbmltYXRpb24uY3VycmVudFN0ZXAgPj0gbnVtU3RlcHMpIHtcclxuXHRcdFx0XHRoZWxwZXJzJDEuY2FsbGJhY2soYW5pbWF0aW9uLm9uQW5pbWF0aW9uQ29tcGxldGUsIFthbmltYXRpb25dLCBjaGFydCk7XHJcblx0XHRcdFx0Y2hhcnQuYW5pbWF0aW5nID0gZmFsc2U7XHJcblx0XHRcdFx0YW5pbWF0aW9ucy5zcGxpY2UoaSwgMSk7XHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0KytpO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0fVxyXG59O1xuXG52YXIgcmVzb2x2ZSA9IGhlbHBlcnMkMS5vcHRpb25zLnJlc29sdmU7XHJcblxyXG52YXIgYXJyYXlFdmVudHMgPSBbJ3B1c2gnLCAncG9wJywgJ3NoaWZ0JywgJ3NwbGljZScsICd1bnNoaWZ0J107XHJcblxyXG4vKipcclxuICogSG9va3MgdGhlIGFycmF5IG1ldGhvZHMgdGhhdCBhZGQgb3IgcmVtb3ZlIHZhbHVlcyAoJ3B1c2gnLCBwb3AnLCAnc2hpZnQnLCAnc3BsaWNlJyxcclxuICogJ3Vuc2hpZnQnKSBhbmQgbm90aWZ5IHRoZSBsaXN0ZW5lciBBRlRFUiB0aGUgYXJyYXkgaGFzIGJlZW4gYWx0ZXJlZC4gTGlzdGVuZXJzIGFyZVxyXG4gKiBjYWxsZWQgb24gdGhlICdvbkRhdGEqJyBjYWxsYmFja3MgKGUuZy4gb25EYXRhUHVzaCwgZXRjLikgd2l0aCBzYW1lIGFyZ3VtZW50cy5cclxuICovXHJcbmZ1bmN0aW9uIGxpc3RlbkFycmF5RXZlbnRzKGFycmF5LCBsaXN0ZW5lcikge1xyXG5cdGlmIChhcnJheS5fY2hhcnRqcykge1xyXG5cdFx0YXJyYXkuX2NoYXJ0anMubGlzdGVuZXJzLnB1c2gobGlzdGVuZXIpO1xyXG5cdFx0cmV0dXJuO1xyXG5cdH1cclxuXHJcblx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGFycmF5LCAnX2NoYXJ0anMnLCB7XHJcblx0XHRjb25maWd1cmFibGU6IHRydWUsXHJcblx0XHRlbnVtZXJhYmxlOiBmYWxzZSxcclxuXHRcdHZhbHVlOiB7XHJcblx0XHRcdGxpc3RlbmVyczogW2xpc3RlbmVyXVxyXG5cdFx0fVxyXG5cdH0pO1xyXG5cclxuXHRhcnJheUV2ZW50cy5mb3JFYWNoKGZ1bmN0aW9uKGtleSkge1xyXG5cdFx0dmFyIG1ldGhvZCA9ICdvbkRhdGEnICsga2V5LmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsga2V5LnNsaWNlKDEpO1xyXG5cdFx0dmFyIGJhc2UgPSBhcnJheVtrZXldO1xyXG5cclxuXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShhcnJheSwga2V5LCB7XHJcblx0XHRcdGNvbmZpZ3VyYWJsZTogdHJ1ZSxcclxuXHRcdFx0ZW51bWVyYWJsZTogZmFsc2UsXHJcblx0XHRcdHZhbHVlOiBmdW5jdGlvbigpIHtcclxuXHRcdFx0XHR2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cyk7XHJcblx0XHRcdFx0dmFyIHJlcyA9IGJhc2UuYXBwbHkodGhpcywgYXJncyk7XHJcblxyXG5cdFx0XHRcdGhlbHBlcnMkMS5lYWNoKGFycmF5Ll9jaGFydGpzLmxpc3RlbmVycywgZnVuY3Rpb24ob2JqZWN0KSB7XHJcblx0XHRcdFx0XHRpZiAodHlwZW9mIG9iamVjdFttZXRob2RdID09PSAnZnVuY3Rpb24nKSB7XHJcblx0XHRcdFx0XHRcdG9iamVjdFttZXRob2RdLmFwcGx5KG9iamVjdCwgYXJncyk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fSk7XHJcblxyXG5cdFx0XHRcdHJldHVybiByZXM7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cdH0pO1xyXG59XHJcblxyXG4vKipcclxuICogUmVtb3ZlcyB0aGUgZ2l2ZW4gYXJyYXkgZXZlbnQgbGlzdGVuZXIgYW5kIGNsZWFudXAgZXh0cmEgYXR0YWNoZWQgcHJvcGVydGllcyAoc3VjaCBhc1xyXG4gKiB0aGUgX2NoYXJ0anMgc3R1YiBhbmQgb3ZlcnJpZGRlbiBtZXRob2RzKSBpZiBhcnJheSBkb2Vzbid0IGhhdmUgYW55IG1vcmUgbGlzdGVuZXJzLlxyXG4gKi9cclxuZnVuY3Rpb24gdW5saXN0ZW5BcnJheUV2ZW50cyhhcnJheSwgbGlzdGVuZXIpIHtcclxuXHR2YXIgc3R1YiA9IGFycmF5Ll9jaGFydGpzO1xyXG5cdGlmICghc3R1Yikge1xyXG5cdFx0cmV0dXJuO1xyXG5cdH1cclxuXHJcblx0dmFyIGxpc3RlbmVycyA9IHN0dWIubGlzdGVuZXJzO1xyXG5cdHZhciBpbmRleCA9IGxpc3RlbmVycy5pbmRleE9mKGxpc3RlbmVyKTtcclxuXHRpZiAoaW5kZXggIT09IC0xKSB7XHJcblx0XHRsaXN0ZW5lcnMuc3BsaWNlKGluZGV4LCAxKTtcclxuXHR9XHJcblxyXG5cdGlmIChsaXN0ZW5lcnMubGVuZ3RoID4gMCkge1xyXG5cdFx0cmV0dXJuO1xyXG5cdH1cclxuXHJcblx0YXJyYXlFdmVudHMuZm9yRWFjaChmdW5jdGlvbihrZXkpIHtcclxuXHRcdGRlbGV0ZSBhcnJheVtrZXldO1xyXG5cdH0pO1xyXG5cclxuXHRkZWxldGUgYXJyYXkuX2NoYXJ0anM7XHJcbn1cclxuXHJcbi8vIEJhc2UgY2xhc3MgZm9yIGFsbCBkYXRhc2V0IGNvbnRyb2xsZXJzIChsaW5lLCBiYXIsIGV0YylcclxudmFyIERhdGFzZXRDb250cm9sbGVyID0gZnVuY3Rpb24oY2hhcnQsIGRhdGFzZXRJbmRleCkge1xyXG5cdHRoaXMuaW5pdGlhbGl6ZShjaGFydCwgZGF0YXNldEluZGV4KTtcclxufTtcclxuXHJcbmhlbHBlcnMkMS5leHRlbmQoRGF0YXNldENvbnRyb2xsZXIucHJvdG90eXBlLCB7XHJcblxyXG5cdC8qKlxyXG5cdCAqIEVsZW1lbnQgdHlwZSB1c2VkIHRvIGdlbmVyYXRlIGEgbWV0YSBkYXRhc2V0IChlLmcuIENoYXJ0LmVsZW1lbnQuTGluZSkuXHJcblx0ICogQHR5cGUge0NoYXJ0LmNvcmUuZWxlbWVudH1cclxuXHQgKi9cclxuXHRkYXRhc2V0RWxlbWVudFR5cGU6IG51bGwsXHJcblxyXG5cdC8qKlxyXG5cdCAqIEVsZW1lbnQgdHlwZSB1c2VkIHRvIGdlbmVyYXRlIGEgbWV0YSBkYXRhIChlLmcuIENoYXJ0LmVsZW1lbnQuUG9pbnQpLlxyXG5cdCAqIEB0eXBlIHtDaGFydC5jb3JlLmVsZW1lbnR9XHJcblx0ICovXHJcblx0ZGF0YUVsZW1lbnRUeXBlOiBudWxsLFxyXG5cclxuXHQvKipcclxuXHQgKiBEYXRhc2V0IGVsZW1lbnQgb3B0aW9uIGtleXMgdG8gYmUgcmVzb2x2ZWQgaW4gX3Jlc29sdmVEYXRhc2V0RWxlbWVudE9wdGlvbnMuXHJcblx0ICogQSBkZXJpdmVkIGNvbnRyb2xsZXIgbWF5IG92ZXJyaWRlIHRoaXMgdG8gcmVzb2x2ZSBjb250cm9sbGVyLXNwZWNpZmljIG9wdGlvbnMuXHJcblx0ICogVGhlIGtleXMgZGVmaW5lZCBoZXJlIGFyZSBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSBmb3IgbGVnZW5kIHN0eWxlcy5cclxuXHQgKiBAcHJpdmF0ZVxyXG5cdCAqL1xyXG5cdF9kYXRhc2V0RWxlbWVudE9wdGlvbnM6IFtcclxuXHRcdCdiYWNrZ3JvdW5kQ29sb3InLFxyXG5cdFx0J2JvcmRlckNhcFN0eWxlJyxcclxuXHRcdCdib3JkZXJDb2xvcicsXHJcblx0XHQnYm9yZGVyRGFzaCcsXHJcblx0XHQnYm9yZGVyRGFzaE9mZnNldCcsXHJcblx0XHQnYm9yZGVySm9pblN0eWxlJyxcclxuXHRcdCdib3JkZXJXaWR0aCdcclxuXHRdLFxyXG5cclxuXHQvKipcclxuXHQgKiBEYXRhIGVsZW1lbnQgb3B0aW9uIGtleXMgdG8gYmUgcmVzb2x2ZWQgaW4gX3Jlc29sdmVEYXRhRWxlbWVudE9wdGlvbnMuXHJcblx0ICogQSBkZXJpdmVkIGNvbnRyb2xsZXIgbWF5IG92ZXJyaWRlIHRoaXMgdG8gcmVzb2x2ZSBjb250cm9sbGVyLXNwZWNpZmljIG9wdGlvbnMuXHJcblx0ICogVGhlIGtleXMgZGVmaW5lZCBoZXJlIGFyZSBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSBmb3IgbGVnZW5kIHN0eWxlcy5cclxuXHQgKiBAcHJpdmF0ZVxyXG5cdCAqL1xyXG5cdF9kYXRhRWxlbWVudE9wdGlvbnM6IFtcclxuXHRcdCdiYWNrZ3JvdW5kQ29sb3InLFxyXG5cdFx0J2JvcmRlckNvbG9yJyxcclxuXHRcdCdib3JkZXJXaWR0aCcsXHJcblx0XHQncG9pbnRTdHlsZSdcclxuXHRdLFxyXG5cclxuXHRpbml0aWFsaXplOiBmdW5jdGlvbihjaGFydCwgZGF0YXNldEluZGV4KSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0bWUuY2hhcnQgPSBjaGFydDtcclxuXHRcdG1lLmluZGV4ID0gZGF0YXNldEluZGV4O1xyXG5cdFx0bWUubGlua1NjYWxlcygpO1xyXG5cdFx0bWUuYWRkRWxlbWVudHMoKTtcclxuXHRcdG1lLl90eXBlID0gbWUuZ2V0TWV0YSgpLnR5cGU7XHJcblx0fSxcclxuXHJcblx0dXBkYXRlSW5kZXg6IGZ1bmN0aW9uKGRhdGFzZXRJbmRleCkge1xyXG5cdFx0dGhpcy5pbmRleCA9IGRhdGFzZXRJbmRleDtcclxuXHR9LFxyXG5cclxuXHRsaW5rU2NhbGVzOiBmdW5jdGlvbigpIHtcclxuXHRcdHZhciBtZSA9IHRoaXM7XHJcblx0XHR2YXIgbWV0YSA9IG1lLmdldE1ldGEoKTtcclxuXHRcdHZhciBjaGFydCA9IG1lLmNoYXJ0O1xyXG5cdFx0dmFyIHNjYWxlcyA9IGNoYXJ0LnNjYWxlcztcclxuXHRcdHZhciBkYXRhc2V0ID0gbWUuZ2V0RGF0YXNldCgpO1xyXG5cdFx0dmFyIHNjYWxlc09wdHMgPSBjaGFydC5vcHRpb25zLnNjYWxlcztcclxuXHJcblx0XHRpZiAobWV0YS54QXhpc0lEID09PSBudWxsIHx8ICEobWV0YS54QXhpc0lEIGluIHNjYWxlcykgfHwgZGF0YXNldC54QXhpc0lEKSB7XHJcblx0XHRcdG1ldGEueEF4aXNJRCA9IGRhdGFzZXQueEF4aXNJRCB8fCBzY2FsZXNPcHRzLnhBeGVzWzBdLmlkO1xyXG5cdFx0fVxyXG5cdFx0aWYgKG1ldGEueUF4aXNJRCA9PT0gbnVsbCB8fCAhKG1ldGEueUF4aXNJRCBpbiBzY2FsZXMpIHx8IGRhdGFzZXQueUF4aXNJRCkge1xyXG5cdFx0XHRtZXRhLnlBeGlzSUQgPSBkYXRhc2V0LnlBeGlzSUQgfHwgc2NhbGVzT3B0cy55QXhlc1swXS5pZDtcclxuXHRcdH1cclxuXHR9LFxyXG5cclxuXHRnZXREYXRhc2V0OiBmdW5jdGlvbigpIHtcclxuXHRcdHJldHVybiB0aGlzLmNoYXJ0LmRhdGEuZGF0YXNldHNbdGhpcy5pbmRleF07XHJcblx0fSxcclxuXHJcblx0Z2V0TWV0YTogZnVuY3Rpb24oKSB7XHJcblx0XHRyZXR1cm4gdGhpcy5jaGFydC5nZXREYXRhc2V0TWV0YSh0aGlzLmluZGV4KTtcclxuXHR9LFxyXG5cclxuXHRnZXRTY2FsZUZvcklkOiBmdW5jdGlvbihzY2FsZUlEKSB7XHJcblx0XHRyZXR1cm4gdGhpcy5jaGFydC5zY2FsZXNbc2NhbGVJRF07XHJcblx0fSxcclxuXHJcblx0LyoqXHJcblx0ICogQHByaXZhdGVcclxuXHQgKi9cclxuXHRfZ2V0VmFsdWVTY2FsZUlkOiBmdW5jdGlvbigpIHtcclxuXHRcdHJldHVybiB0aGlzLmdldE1ldGEoKS55QXhpc0lEO1xyXG5cdH0sXHJcblxyXG5cdC8qKlxyXG5cdCAqIEBwcml2YXRlXHJcblx0ICovXHJcblx0X2dldEluZGV4U2NhbGVJZDogZnVuY3Rpb24oKSB7XHJcblx0XHRyZXR1cm4gdGhpcy5nZXRNZXRhKCkueEF4aXNJRDtcclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBAcHJpdmF0ZVxyXG5cdCAqL1xyXG5cdF9nZXRWYWx1ZVNjYWxlOiBmdW5jdGlvbigpIHtcclxuXHRcdHJldHVybiB0aGlzLmdldFNjYWxlRm9ySWQodGhpcy5fZ2V0VmFsdWVTY2FsZUlkKCkpO1xyXG5cdH0sXHJcblxyXG5cdC8qKlxyXG5cdCAqIEBwcml2YXRlXHJcblx0ICovXHJcblx0X2dldEluZGV4U2NhbGU6IGZ1bmN0aW9uKCkge1xyXG5cdFx0cmV0dXJuIHRoaXMuZ2V0U2NhbGVGb3JJZCh0aGlzLl9nZXRJbmRleFNjYWxlSWQoKSk7XHJcblx0fSxcclxuXHJcblx0cmVzZXQ6IGZ1bmN0aW9uKCkge1xyXG5cdFx0dGhpcy5fdXBkYXRlKHRydWUpO1xyXG5cdH0sXHJcblxyXG5cdC8qKlxyXG5cdCAqIEBwcml2YXRlXHJcblx0ICovXHJcblx0ZGVzdHJveTogZnVuY3Rpb24oKSB7XHJcblx0XHRpZiAodGhpcy5fZGF0YSkge1xyXG5cdFx0XHR1bmxpc3RlbkFycmF5RXZlbnRzKHRoaXMuX2RhdGEsIHRoaXMpO1xyXG5cdFx0fVxyXG5cdH0sXHJcblxyXG5cdGNyZWF0ZU1ldGFEYXRhc2V0OiBmdW5jdGlvbigpIHtcclxuXHRcdHZhciBtZSA9IHRoaXM7XHJcblx0XHR2YXIgdHlwZSA9IG1lLmRhdGFzZXRFbGVtZW50VHlwZTtcclxuXHRcdHJldHVybiB0eXBlICYmIG5ldyB0eXBlKHtcclxuXHRcdFx0X2NoYXJ0OiBtZS5jaGFydCxcclxuXHRcdFx0X2RhdGFzZXRJbmRleDogbWUuaW5kZXhcclxuXHRcdH0pO1xyXG5cdH0sXHJcblxyXG5cdGNyZWF0ZU1ldGFEYXRhOiBmdW5jdGlvbihpbmRleCkge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHRcdHZhciB0eXBlID0gbWUuZGF0YUVsZW1lbnRUeXBlO1xyXG5cdFx0cmV0dXJuIHR5cGUgJiYgbmV3IHR5cGUoe1xyXG5cdFx0XHRfY2hhcnQ6IG1lLmNoYXJ0LFxyXG5cdFx0XHRfZGF0YXNldEluZGV4OiBtZS5pbmRleCxcclxuXHRcdFx0X2luZGV4OiBpbmRleFxyXG5cdFx0fSk7XHJcblx0fSxcclxuXHJcblx0YWRkRWxlbWVudHM6IGZ1bmN0aW9uKCkge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHRcdHZhciBtZXRhID0gbWUuZ2V0TWV0YSgpO1xyXG5cdFx0dmFyIGRhdGEgPSBtZS5nZXREYXRhc2V0KCkuZGF0YSB8fCBbXTtcclxuXHRcdHZhciBtZXRhRGF0YSA9IG1ldGEuZGF0YTtcclxuXHRcdHZhciBpLCBpbGVuO1xyXG5cclxuXHRcdGZvciAoaSA9IDAsIGlsZW4gPSBkYXRhLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xyXG5cdFx0XHRtZXRhRGF0YVtpXSA9IG1ldGFEYXRhW2ldIHx8IG1lLmNyZWF0ZU1ldGFEYXRhKGkpO1xyXG5cdFx0fVxyXG5cclxuXHRcdG1ldGEuZGF0YXNldCA9IG1ldGEuZGF0YXNldCB8fCBtZS5jcmVhdGVNZXRhRGF0YXNldCgpO1xyXG5cdH0sXHJcblxyXG5cdGFkZEVsZW1lbnRBbmRSZXNldDogZnVuY3Rpb24oaW5kZXgpIHtcclxuXHRcdHZhciBlbGVtZW50ID0gdGhpcy5jcmVhdGVNZXRhRGF0YShpbmRleCk7XHJcblx0XHR0aGlzLmdldE1ldGEoKS5kYXRhLnNwbGljZShpbmRleCwgMCwgZWxlbWVudCk7XHJcblx0XHR0aGlzLnVwZGF0ZUVsZW1lbnQoZWxlbWVudCwgaW5kZXgsIHRydWUpO1xyXG5cdH0sXHJcblxyXG5cdGJ1aWxkT3JVcGRhdGVFbGVtZW50czogZnVuY3Rpb24oKSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0dmFyIGRhdGFzZXQgPSBtZS5nZXREYXRhc2V0KCk7XHJcblx0XHR2YXIgZGF0YSA9IGRhdGFzZXQuZGF0YSB8fCAoZGF0YXNldC5kYXRhID0gW10pO1xyXG5cclxuXHRcdC8vIEluIG9yZGVyIHRvIGNvcnJlY3RseSBoYW5kbGUgZGF0YSBhZGRpdGlvbi9kZWxldGlvbiBhbmltYXRpb24gKGFuIHRodXMgc2ltdWxhdGVcclxuXHRcdC8vIHJlYWwtdGltZSBjaGFydHMpLCB3ZSBuZWVkIHRvIG1vbml0b3IgdGhlc2UgZGF0YSBtb2RpZmljYXRpb25zIGFuZCBzeW5jaHJvbml6ZVxyXG5cdFx0Ly8gdGhlIGludGVybmFsIG1ldGEgZGF0YSBhY2NvcmRpbmdseS5cclxuXHRcdGlmIChtZS5fZGF0YSAhPT0gZGF0YSkge1xyXG5cdFx0XHRpZiAobWUuX2RhdGEpIHtcclxuXHRcdFx0XHQvLyBUaGlzIGNhc2UgaGFwcGVucyB3aGVuIHRoZSB1c2VyIHJlcGxhY2VkIHRoZSBkYXRhIGFycmF5IGluc3RhbmNlLlxyXG5cdFx0XHRcdHVubGlzdGVuQXJyYXlFdmVudHMobWUuX2RhdGEsIG1lKTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0aWYgKGRhdGEgJiYgT2JqZWN0LmlzRXh0ZW5zaWJsZShkYXRhKSkge1xyXG5cdFx0XHRcdGxpc3RlbkFycmF5RXZlbnRzKGRhdGEsIG1lKTtcclxuXHRcdFx0fVxyXG5cdFx0XHRtZS5fZGF0YSA9IGRhdGE7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gUmUtc3luYyBtZXRhIGRhdGEgaW4gY2FzZSB0aGUgdXNlciByZXBsYWNlZCB0aGUgZGF0YSBhcnJheSBvciBpZiB3ZSBtaXNzZWRcclxuXHRcdC8vIGFueSB1cGRhdGVzIGFuZCBzbyBtYWtlIHN1cmUgdGhhdCB3ZSBoYW5kbGUgbnVtYmVyIG9mIGRhdGFwb2ludHMgY2hhbmdpbmcuXHJcblx0XHRtZS5yZXN5bmNFbGVtZW50cygpO1xyXG5cdH0sXHJcblxyXG5cdC8qKlxyXG5cdCAqIFJldHVybnMgdGhlIG1lcmdlZCB1c2VyLXN1cHBsaWVkIGFuZCBkZWZhdWx0IGRhdGFzZXQtbGV2ZWwgb3B0aW9uc1xyXG5cdCAqIEBwcml2YXRlXHJcblx0ICovXHJcblx0X2NvbmZpZ3VyZTogZnVuY3Rpb24oKSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0bWUuX2NvbmZpZyA9IGhlbHBlcnMkMS5tZXJnZShPYmplY3QuY3JlYXRlKG51bGwpLCBbXHJcblx0XHRcdG1lLmNoYXJ0Lm9wdGlvbnMuZGF0YXNldHNbbWUuX3R5cGVdLFxyXG5cdFx0XHRtZS5nZXREYXRhc2V0KCksXHJcblx0XHRdLCB7XHJcblx0XHRcdG1lcmdlcjogZnVuY3Rpb24oa2V5LCB0YXJnZXQsIHNvdXJjZSkge1xyXG5cdFx0XHRcdGlmIChrZXkgIT09ICdfbWV0YScgJiYga2V5ICE9PSAnZGF0YScpIHtcclxuXHRcdFx0XHRcdGhlbHBlcnMkMS5fbWVyZ2VyKGtleSwgdGFyZ2V0LCBzb3VyY2UpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblx0fSxcclxuXHJcblx0X3VwZGF0ZTogZnVuY3Rpb24ocmVzZXQpIHtcclxuXHRcdHZhciBtZSA9IHRoaXM7XHJcblx0XHRtZS5fY29uZmlndXJlKCk7XHJcblx0XHRtZS5fY2FjaGVkRGF0YU9wdHMgPSBudWxsO1xyXG5cdFx0bWUudXBkYXRlKHJlc2V0KTtcclxuXHR9LFxyXG5cclxuXHR1cGRhdGU6IGhlbHBlcnMkMS5ub29wLFxyXG5cclxuXHR0cmFuc2l0aW9uOiBmdW5jdGlvbihlYXNpbmdWYWx1ZSkge1xyXG5cdFx0dmFyIG1ldGEgPSB0aGlzLmdldE1ldGEoKTtcclxuXHRcdHZhciBlbGVtZW50cyA9IG1ldGEuZGF0YSB8fCBbXTtcclxuXHRcdHZhciBpbGVuID0gZWxlbWVudHMubGVuZ3RoO1xyXG5cdFx0dmFyIGkgPSAwO1xyXG5cclxuXHRcdGZvciAoOyBpIDwgaWxlbjsgKytpKSB7XHJcblx0XHRcdGVsZW1lbnRzW2ldLnRyYW5zaXRpb24oZWFzaW5nVmFsdWUpO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmIChtZXRhLmRhdGFzZXQpIHtcclxuXHRcdFx0bWV0YS5kYXRhc2V0LnRyYW5zaXRpb24oZWFzaW5nVmFsdWUpO1xyXG5cdFx0fVxyXG5cdH0sXHJcblxyXG5cdGRyYXc6IGZ1bmN0aW9uKCkge1xyXG5cdFx0dmFyIG1ldGEgPSB0aGlzLmdldE1ldGEoKTtcclxuXHRcdHZhciBlbGVtZW50cyA9IG1ldGEuZGF0YSB8fCBbXTtcclxuXHRcdHZhciBpbGVuID0gZWxlbWVudHMubGVuZ3RoO1xyXG5cdFx0dmFyIGkgPSAwO1xyXG5cclxuXHRcdGlmIChtZXRhLmRhdGFzZXQpIHtcclxuXHRcdFx0bWV0YS5kYXRhc2V0LmRyYXcoKTtcclxuXHRcdH1cclxuXHJcblx0XHRmb3IgKDsgaSA8IGlsZW47ICsraSkge1xyXG5cdFx0XHRlbGVtZW50c1tpXS5kcmF3KCk7XHJcblx0XHR9XHJcblx0fSxcclxuXHJcblx0LyoqXHJcblx0ICogUmV0dXJucyBhIHNldCBvZiBwcmVkZWZpbmVkIHN0eWxlIHByb3BlcnRpZXMgdGhhdCBzaG91bGQgYmUgdXNlZCB0byByZXByZXNlbnQgdGhlIGRhdGFzZXRcclxuXHQgKiBvciB0aGUgZGF0YSBpZiB0aGUgaW5kZXggaXMgc3BlY2lmaWVkXHJcblx0ICogQHBhcmFtIHtudW1iZXJ9IGluZGV4IC0gZGF0YSBpbmRleFxyXG5cdCAqIEByZXR1cm4ge0lTdHlsZUludGVyZmFjZX0gc3R5bGUgb2JqZWN0XHJcblx0ICovXHJcblx0Z2V0U3R5bGU6IGZ1bmN0aW9uKGluZGV4KSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0dmFyIG1ldGEgPSBtZS5nZXRNZXRhKCk7XHJcblx0XHR2YXIgZGF0YXNldCA9IG1ldGEuZGF0YXNldDtcclxuXHRcdHZhciBzdHlsZTtcclxuXHJcblx0XHRtZS5fY29uZmlndXJlKCk7XHJcblx0XHRpZiAoZGF0YXNldCAmJiBpbmRleCA9PT0gdW5kZWZpbmVkKSB7XHJcblx0XHRcdHN0eWxlID0gbWUuX3Jlc29sdmVEYXRhc2V0RWxlbWVudE9wdGlvbnMoZGF0YXNldCB8fCB7fSk7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRpbmRleCA9IGluZGV4IHx8IDA7XHJcblx0XHRcdHN0eWxlID0gbWUuX3Jlc29sdmVEYXRhRWxlbWVudE9wdGlvbnMobWV0YS5kYXRhW2luZGV4XSB8fCB7fSwgaW5kZXgpO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmIChzdHlsZS5maWxsID09PSBmYWxzZSB8fCBzdHlsZS5maWxsID09PSBudWxsKSB7XHJcblx0XHRcdHN0eWxlLmJhY2tncm91bmRDb2xvciA9IHN0eWxlLmJvcmRlckNvbG9yO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiBzdHlsZTtcclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBAcHJpdmF0ZVxyXG5cdCAqL1xyXG5cdF9yZXNvbHZlRGF0YXNldEVsZW1lbnRPcHRpb25zOiBmdW5jdGlvbihlbGVtZW50LCBob3Zlcikge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHRcdHZhciBjaGFydCA9IG1lLmNoYXJ0O1xyXG5cdFx0dmFyIGRhdGFzZXRPcHRzID0gbWUuX2NvbmZpZztcclxuXHRcdHZhciBjdXN0b20gPSBlbGVtZW50LmN1c3RvbSB8fCB7fTtcclxuXHRcdHZhciBvcHRpb25zID0gY2hhcnQub3B0aW9ucy5lbGVtZW50c1ttZS5kYXRhc2V0RWxlbWVudFR5cGUucHJvdG90eXBlLl90eXBlXSB8fCB7fTtcclxuXHRcdHZhciBlbGVtZW50T3B0aW9ucyA9IG1lLl9kYXRhc2V0RWxlbWVudE9wdGlvbnM7XHJcblx0XHR2YXIgdmFsdWVzID0ge307XHJcblx0XHR2YXIgaSwgaWxlbiwga2V5LCByZWFkS2V5O1xyXG5cclxuXHRcdC8vIFNjcmlwdGFibGUgb3B0aW9uc1xyXG5cdFx0dmFyIGNvbnRleHQgPSB7XHJcblx0XHRcdGNoYXJ0OiBjaGFydCxcclxuXHRcdFx0ZGF0YXNldDogbWUuZ2V0RGF0YXNldCgpLFxyXG5cdFx0XHRkYXRhc2V0SW5kZXg6IG1lLmluZGV4LFxyXG5cdFx0XHRob3ZlcjogaG92ZXJcclxuXHRcdH07XHJcblxyXG5cdFx0Zm9yIChpID0gMCwgaWxlbiA9IGVsZW1lbnRPcHRpb25zLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xyXG5cdFx0XHRrZXkgPSBlbGVtZW50T3B0aW9uc1tpXTtcclxuXHRcdFx0cmVhZEtleSA9IGhvdmVyID8gJ2hvdmVyJyArIGtleS5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIGtleS5zbGljZSgxKSA6IGtleTtcclxuXHRcdFx0dmFsdWVzW2tleV0gPSByZXNvbHZlKFtcclxuXHRcdFx0XHRjdXN0b21bcmVhZEtleV0sXHJcblx0XHRcdFx0ZGF0YXNldE9wdHNbcmVhZEtleV0sXHJcblx0XHRcdFx0b3B0aW9uc1tyZWFkS2V5XVxyXG5cdFx0XHRdLCBjb250ZXh0KTtcclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gdmFsdWVzO1xyXG5cdH0sXHJcblxyXG5cdC8qKlxyXG5cdCAqIEBwcml2YXRlXHJcblx0ICovXHJcblx0X3Jlc29sdmVEYXRhRWxlbWVudE9wdGlvbnM6IGZ1bmN0aW9uKGVsZW1lbnQsIGluZGV4KSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0dmFyIGN1c3RvbSA9IGVsZW1lbnQgJiYgZWxlbWVudC5jdXN0b207XHJcblx0XHR2YXIgY2FjaGVkID0gbWUuX2NhY2hlZERhdGFPcHRzO1xyXG5cdFx0aWYgKGNhY2hlZCAmJiAhY3VzdG9tKSB7XHJcblx0XHRcdHJldHVybiBjYWNoZWQ7XHJcblx0XHR9XHJcblx0XHR2YXIgY2hhcnQgPSBtZS5jaGFydDtcclxuXHRcdHZhciBkYXRhc2V0T3B0cyA9IG1lLl9jb25maWc7XHJcblx0XHR2YXIgb3B0aW9ucyA9IGNoYXJ0Lm9wdGlvbnMuZWxlbWVudHNbbWUuZGF0YUVsZW1lbnRUeXBlLnByb3RvdHlwZS5fdHlwZV0gfHwge307XHJcblx0XHR2YXIgZWxlbWVudE9wdGlvbnMgPSBtZS5fZGF0YUVsZW1lbnRPcHRpb25zO1xyXG5cdFx0dmFyIHZhbHVlcyA9IHt9O1xyXG5cclxuXHRcdC8vIFNjcmlwdGFibGUgb3B0aW9uc1xyXG5cdFx0dmFyIGNvbnRleHQgPSB7XHJcblx0XHRcdGNoYXJ0OiBjaGFydCxcclxuXHRcdFx0ZGF0YUluZGV4OiBpbmRleCxcclxuXHRcdFx0ZGF0YXNldDogbWUuZ2V0RGF0YXNldCgpLFxyXG5cdFx0XHRkYXRhc2V0SW5kZXg6IG1lLmluZGV4XHJcblx0XHR9O1xyXG5cclxuXHRcdC8vIGByZXNvbHZlYCBzZXRzIGNhY2hlYWJsZSB0byBgZmFsc2VgIGlmIGFueSBvcHRpb24gaXMgaW5kZXhlZCBvciBzY3JpcHRlZFxyXG5cdFx0dmFyIGluZm8gPSB7Y2FjaGVhYmxlOiAhY3VzdG9tfTtcclxuXHJcblx0XHR2YXIga2V5cywgaSwgaWxlbiwga2V5O1xyXG5cclxuXHRcdGN1c3RvbSA9IGN1c3RvbSB8fCB7fTtcclxuXHJcblx0XHRpZiAoaGVscGVycyQxLmlzQXJyYXkoZWxlbWVudE9wdGlvbnMpKSB7XHJcblx0XHRcdGZvciAoaSA9IDAsIGlsZW4gPSBlbGVtZW50T3B0aW9ucy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcclxuXHRcdFx0XHRrZXkgPSBlbGVtZW50T3B0aW9uc1tpXTtcclxuXHRcdFx0XHR2YWx1ZXNba2V5XSA9IHJlc29sdmUoW1xyXG5cdFx0XHRcdFx0Y3VzdG9tW2tleV0sXHJcblx0XHRcdFx0XHRkYXRhc2V0T3B0c1trZXldLFxyXG5cdFx0XHRcdFx0b3B0aW9uc1trZXldXHJcblx0XHRcdFx0XSwgY29udGV4dCwgaW5kZXgsIGluZm8pO1xyXG5cdFx0XHR9XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRrZXlzID0gT2JqZWN0LmtleXMoZWxlbWVudE9wdGlvbnMpO1xyXG5cdFx0XHRmb3IgKGkgPSAwLCBpbGVuID0ga2V5cy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcclxuXHRcdFx0XHRrZXkgPSBrZXlzW2ldO1xyXG5cdFx0XHRcdHZhbHVlc1trZXldID0gcmVzb2x2ZShbXHJcblx0XHRcdFx0XHRjdXN0b21ba2V5XSxcclxuXHRcdFx0XHRcdGRhdGFzZXRPcHRzW2VsZW1lbnRPcHRpb25zW2tleV1dLFxyXG5cdFx0XHRcdFx0ZGF0YXNldE9wdHNba2V5XSxcclxuXHRcdFx0XHRcdG9wdGlvbnNba2V5XVxyXG5cdFx0XHRcdF0sIGNvbnRleHQsIGluZGV4LCBpbmZvKTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdGlmIChpbmZvLmNhY2hlYWJsZSkge1xyXG5cdFx0XHRtZS5fY2FjaGVkRGF0YU9wdHMgPSBPYmplY3QuZnJlZXplKHZhbHVlcyk7XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIHZhbHVlcztcclxuXHR9LFxyXG5cclxuXHRyZW1vdmVIb3ZlclN0eWxlOiBmdW5jdGlvbihlbGVtZW50KSB7XHJcblx0XHRoZWxwZXJzJDEubWVyZ2UoZWxlbWVudC5fbW9kZWwsIGVsZW1lbnQuJHByZXZpb3VzU3R5bGUgfHwge30pO1xyXG5cdFx0ZGVsZXRlIGVsZW1lbnQuJHByZXZpb3VzU3R5bGU7XHJcblx0fSxcclxuXHJcblx0c2V0SG92ZXJTdHlsZTogZnVuY3Rpb24oZWxlbWVudCkge1xyXG5cdFx0dmFyIGRhdGFzZXQgPSB0aGlzLmNoYXJ0LmRhdGEuZGF0YXNldHNbZWxlbWVudC5fZGF0YXNldEluZGV4XTtcclxuXHRcdHZhciBpbmRleCA9IGVsZW1lbnQuX2luZGV4O1xyXG5cdFx0dmFyIGN1c3RvbSA9IGVsZW1lbnQuY3VzdG9tIHx8IHt9O1xyXG5cdFx0dmFyIG1vZGVsID0gZWxlbWVudC5fbW9kZWw7XHJcblx0XHR2YXIgZ2V0SG92ZXJDb2xvciA9IGhlbHBlcnMkMS5nZXRIb3ZlckNvbG9yO1xyXG5cclxuXHRcdGVsZW1lbnQuJHByZXZpb3VzU3R5bGUgPSB7XHJcblx0XHRcdGJhY2tncm91bmRDb2xvcjogbW9kZWwuYmFja2dyb3VuZENvbG9yLFxyXG5cdFx0XHRib3JkZXJDb2xvcjogbW9kZWwuYm9yZGVyQ29sb3IsXHJcblx0XHRcdGJvcmRlcldpZHRoOiBtb2RlbC5ib3JkZXJXaWR0aFxyXG5cdFx0fTtcclxuXHJcblx0XHRtb2RlbC5iYWNrZ3JvdW5kQ29sb3IgPSByZXNvbHZlKFtjdXN0b20uaG92ZXJCYWNrZ3JvdW5kQ29sb3IsIGRhdGFzZXQuaG92ZXJCYWNrZ3JvdW5kQ29sb3IsIGdldEhvdmVyQ29sb3IobW9kZWwuYmFja2dyb3VuZENvbG9yKV0sIHVuZGVmaW5lZCwgaW5kZXgpO1xyXG5cdFx0bW9kZWwuYm9yZGVyQ29sb3IgPSByZXNvbHZlKFtjdXN0b20uaG92ZXJCb3JkZXJDb2xvciwgZGF0YXNldC5ob3ZlckJvcmRlckNvbG9yLCBnZXRIb3ZlckNvbG9yKG1vZGVsLmJvcmRlckNvbG9yKV0sIHVuZGVmaW5lZCwgaW5kZXgpO1xyXG5cdFx0bW9kZWwuYm9yZGVyV2lkdGggPSByZXNvbHZlKFtjdXN0b20uaG92ZXJCb3JkZXJXaWR0aCwgZGF0YXNldC5ob3ZlckJvcmRlcldpZHRoLCBtb2RlbC5ib3JkZXJXaWR0aF0sIHVuZGVmaW5lZCwgaW5kZXgpO1xyXG5cdH0sXHJcblxyXG5cdC8qKlxyXG5cdCAqIEBwcml2YXRlXHJcblx0ICovXHJcblx0X3JlbW92ZURhdGFzZXRIb3ZlclN0eWxlOiBmdW5jdGlvbigpIHtcclxuXHRcdHZhciBlbGVtZW50ID0gdGhpcy5nZXRNZXRhKCkuZGF0YXNldDtcclxuXHJcblx0XHRpZiAoZWxlbWVudCkge1xyXG5cdFx0XHR0aGlzLnJlbW92ZUhvdmVyU3R5bGUoZWxlbWVudCk7XHJcblx0XHR9XHJcblx0fSxcclxuXHJcblx0LyoqXHJcblx0ICogQHByaXZhdGVcclxuXHQgKi9cclxuXHRfc2V0RGF0YXNldEhvdmVyU3R5bGU6IGZ1bmN0aW9uKCkge1xyXG5cdFx0dmFyIGVsZW1lbnQgPSB0aGlzLmdldE1ldGEoKS5kYXRhc2V0O1xyXG5cdFx0dmFyIHByZXYgPSB7fTtcclxuXHRcdHZhciBpLCBpbGVuLCBrZXksIGtleXMsIGhvdmVyT3B0aW9ucywgbW9kZWw7XHJcblxyXG5cdFx0aWYgKCFlbGVtZW50KSB7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHJcblx0XHRtb2RlbCA9IGVsZW1lbnQuX21vZGVsO1xyXG5cdFx0aG92ZXJPcHRpb25zID0gdGhpcy5fcmVzb2x2ZURhdGFzZXRFbGVtZW50T3B0aW9ucyhlbGVtZW50LCB0cnVlKTtcclxuXHJcblx0XHRrZXlzID0gT2JqZWN0LmtleXMoaG92ZXJPcHRpb25zKTtcclxuXHRcdGZvciAoaSA9IDAsIGlsZW4gPSBrZXlzLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xyXG5cdFx0XHRrZXkgPSBrZXlzW2ldO1xyXG5cdFx0XHRwcmV2W2tleV0gPSBtb2RlbFtrZXldO1xyXG5cdFx0XHRtb2RlbFtrZXldID0gaG92ZXJPcHRpb25zW2tleV07XHJcblx0XHR9XHJcblxyXG5cdFx0ZWxlbWVudC4kcHJldmlvdXNTdHlsZSA9IHByZXY7XHJcblx0fSxcclxuXHJcblx0LyoqXHJcblx0ICogQHByaXZhdGVcclxuXHQgKi9cclxuXHRyZXN5bmNFbGVtZW50czogZnVuY3Rpb24oKSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0dmFyIG1ldGEgPSBtZS5nZXRNZXRhKCk7XHJcblx0XHR2YXIgZGF0YSA9IG1lLmdldERhdGFzZXQoKS5kYXRhO1xyXG5cdFx0dmFyIG51bU1ldGEgPSBtZXRhLmRhdGEubGVuZ3RoO1xyXG5cdFx0dmFyIG51bURhdGEgPSBkYXRhLmxlbmd0aDtcclxuXHJcblx0XHRpZiAobnVtRGF0YSA8IG51bU1ldGEpIHtcclxuXHRcdFx0bWV0YS5kYXRhLnNwbGljZShudW1EYXRhLCBudW1NZXRhIC0gbnVtRGF0YSk7XHJcblx0XHR9IGVsc2UgaWYgKG51bURhdGEgPiBudW1NZXRhKSB7XHJcblx0XHRcdG1lLmluc2VydEVsZW1lbnRzKG51bU1ldGEsIG51bURhdGEgLSBudW1NZXRhKTtcclxuXHRcdH1cclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBAcHJpdmF0ZVxyXG5cdCAqL1xyXG5cdGluc2VydEVsZW1lbnRzOiBmdW5jdGlvbihzdGFydCwgY291bnQpIHtcclxuXHRcdGZvciAodmFyIGkgPSAwOyBpIDwgY291bnQ7ICsraSkge1xyXG5cdFx0XHR0aGlzLmFkZEVsZW1lbnRBbmRSZXNldChzdGFydCArIGkpO1xyXG5cdFx0fVxyXG5cdH0sXHJcblxyXG5cdC8qKlxyXG5cdCAqIEBwcml2YXRlXHJcblx0ICovXHJcblx0b25EYXRhUHVzaDogZnVuY3Rpb24oKSB7XHJcblx0XHR2YXIgY291bnQgPSBhcmd1bWVudHMubGVuZ3RoO1xyXG5cdFx0dGhpcy5pbnNlcnRFbGVtZW50cyh0aGlzLmdldERhdGFzZXQoKS5kYXRhLmxlbmd0aCAtIGNvdW50LCBjb3VudCk7XHJcblx0fSxcclxuXHJcblx0LyoqXHJcblx0ICogQHByaXZhdGVcclxuXHQgKi9cclxuXHRvbkRhdGFQb3A6IGZ1bmN0aW9uKCkge1xyXG5cdFx0dGhpcy5nZXRNZXRhKCkuZGF0YS5wb3AoKTtcclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBAcHJpdmF0ZVxyXG5cdCAqL1xyXG5cdG9uRGF0YVNoaWZ0OiBmdW5jdGlvbigpIHtcclxuXHRcdHRoaXMuZ2V0TWV0YSgpLmRhdGEuc2hpZnQoKTtcclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBAcHJpdmF0ZVxyXG5cdCAqL1xyXG5cdG9uRGF0YVNwbGljZTogZnVuY3Rpb24oc3RhcnQsIGNvdW50KSB7XHJcblx0XHR0aGlzLmdldE1ldGEoKS5kYXRhLnNwbGljZShzdGFydCwgY291bnQpO1xyXG5cdFx0dGhpcy5pbnNlcnRFbGVtZW50cyhzdGFydCwgYXJndW1lbnRzLmxlbmd0aCAtIDIpO1xyXG5cdH0sXHJcblxyXG5cdC8qKlxyXG5cdCAqIEBwcml2YXRlXHJcblx0ICovXHJcblx0b25EYXRhVW5zaGlmdDogZnVuY3Rpb24oKSB7XHJcblx0XHR0aGlzLmluc2VydEVsZW1lbnRzKDAsIGFyZ3VtZW50cy5sZW5ndGgpO1xyXG5cdH1cclxufSk7XHJcblxyXG5EYXRhc2V0Q29udHJvbGxlci5leHRlbmQgPSBoZWxwZXJzJDEuaW5oZXJpdHM7XHJcblxyXG52YXIgY29yZV9kYXRhc2V0Q29udHJvbGxlciA9IERhdGFzZXRDb250cm9sbGVyO1xuXG52YXIgVEFVID0gTWF0aC5QSSAqIDI7XHJcblxyXG5jb3JlX2RlZmF1bHRzLl9zZXQoJ2dsb2JhbCcsIHtcclxuXHRlbGVtZW50czoge1xyXG5cdFx0YXJjOiB7XHJcblx0XHRcdGJhY2tncm91bmRDb2xvcjogY29yZV9kZWZhdWx0cy5nbG9iYWwuZGVmYXVsdENvbG9yLFxyXG5cdFx0XHRib3JkZXJDb2xvcjogJyNmZmYnLFxyXG5cdFx0XHRib3JkZXJXaWR0aDogMixcclxuXHRcdFx0Ym9yZGVyQWxpZ246ICdjZW50ZXInXHJcblx0XHR9XHJcblx0fVxyXG59KTtcclxuXHJcbmZ1bmN0aW9uIGNsaXBBcmMoY3R4LCBhcmMpIHtcclxuXHR2YXIgc3RhcnRBbmdsZSA9IGFyYy5zdGFydEFuZ2xlO1xyXG5cdHZhciBlbmRBbmdsZSA9IGFyYy5lbmRBbmdsZTtcclxuXHR2YXIgcGl4ZWxNYXJnaW4gPSBhcmMucGl4ZWxNYXJnaW47XHJcblx0dmFyIGFuZ2xlTWFyZ2luID0gcGl4ZWxNYXJnaW4gLyBhcmMub3V0ZXJSYWRpdXM7XHJcblx0dmFyIHggPSBhcmMueDtcclxuXHR2YXIgeSA9IGFyYy55O1xyXG5cclxuXHQvLyBEcmF3IGFuIGlubmVyIGJvcmRlciBieSBjbGlwaW5nIHRoZSBhcmMgYW5kIGRyYXdpbmcgYSBkb3VibGUtd2lkdGggYm9yZGVyXHJcblx0Ly8gRW5sYXJnZSB0aGUgY2xpcHBpbmcgYXJjIGJ5IDAuMzMgcGl4ZWxzIHRvIGVsaW1pbmF0ZSBnbGl0Y2hlcyBiZXR3ZWVuIGJvcmRlcnNcclxuXHRjdHguYmVnaW5QYXRoKCk7XHJcblx0Y3R4LmFyYyh4LCB5LCBhcmMub3V0ZXJSYWRpdXMsIHN0YXJ0QW5nbGUgLSBhbmdsZU1hcmdpbiwgZW5kQW5nbGUgKyBhbmdsZU1hcmdpbik7XHJcblx0aWYgKGFyYy5pbm5lclJhZGl1cyA+IHBpeGVsTWFyZ2luKSB7XHJcblx0XHRhbmdsZU1hcmdpbiA9IHBpeGVsTWFyZ2luIC8gYXJjLmlubmVyUmFkaXVzO1xyXG5cdFx0Y3R4LmFyYyh4LCB5LCBhcmMuaW5uZXJSYWRpdXMgLSBwaXhlbE1hcmdpbiwgZW5kQW5nbGUgKyBhbmdsZU1hcmdpbiwgc3RhcnRBbmdsZSAtIGFuZ2xlTWFyZ2luLCB0cnVlKTtcclxuXHR9IGVsc2Uge1xyXG5cdFx0Y3R4LmFyYyh4LCB5LCBwaXhlbE1hcmdpbiwgZW5kQW5nbGUgKyBNYXRoLlBJIC8gMiwgc3RhcnRBbmdsZSAtIE1hdGguUEkgLyAyKTtcclxuXHR9XHJcblx0Y3R4LmNsb3NlUGF0aCgpO1xyXG5cdGN0eC5jbGlwKCk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGRyYXdGdWxsQ2lyY2xlQm9yZGVycyhjdHgsIHZtLCBhcmMsIGlubmVyKSB7XHJcblx0dmFyIGVuZEFuZ2xlID0gYXJjLmVuZEFuZ2xlO1xyXG5cdHZhciBpO1xyXG5cclxuXHRpZiAoaW5uZXIpIHtcclxuXHRcdGFyYy5lbmRBbmdsZSA9IGFyYy5zdGFydEFuZ2xlICsgVEFVO1xyXG5cdFx0Y2xpcEFyYyhjdHgsIGFyYyk7XHJcblx0XHRhcmMuZW5kQW5nbGUgPSBlbmRBbmdsZTtcclxuXHRcdGlmIChhcmMuZW5kQW5nbGUgPT09IGFyYy5zdGFydEFuZ2xlICYmIGFyYy5mdWxsQ2lyY2xlcykge1xyXG5cdFx0XHRhcmMuZW5kQW5nbGUgKz0gVEFVO1xyXG5cdFx0XHRhcmMuZnVsbENpcmNsZXMtLTtcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdGN0eC5iZWdpblBhdGgoKTtcclxuXHRjdHguYXJjKGFyYy54LCBhcmMueSwgYXJjLmlubmVyUmFkaXVzLCBhcmMuc3RhcnRBbmdsZSArIFRBVSwgYXJjLnN0YXJ0QW5nbGUsIHRydWUpO1xyXG5cdGZvciAoaSA9IDA7IGkgPCBhcmMuZnVsbENpcmNsZXM7ICsraSkge1xyXG5cdFx0Y3R4LnN0cm9rZSgpO1xyXG5cdH1cclxuXHJcblx0Y3R4LmJlZ2luUGF0aCgpO1xyXG5cdGN0eC5hcmMoYXJjLngsIGFyYy55LCB2bS5vdXRlclJhZGl1cywgYXJjLnN0YXJ0QW5nbGUsIGFyYy5zdGFydEFuZ2xlICsgVEFVKTtcclxuXHRmb3IgKGkgPSAwOyBpIDwgYXJjLmZ1bGxDaXJjbGVzOyArK2kpIHtcclxuXHRcdGN0eC5zdHJva2UoKTtcclxuXHR9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGRyYXdCb3JkZXIoY3R4LCB2bSwgYXJjKSB7XHJcblx0dmFyIGlubmVyID0gdm0uYm9yZGVyQWxpZ24gPT09ICdpbm5lcic7XHJcblxyXG5cdGlmIChpbm5lcikge1xyXG5cdFx0Y3R4LmxpbmVXaWR0aCA9IHZtLmJvcmRlcldpZHRoICogMjtcclxuXHRcdGN0eC5saW5lSm9pbiA9ICdyb3VuZCc7XHJcblx0fSBlbHNlIHtcclxuXHRcdGN0eC5saW5lV2lkdGggPSB2bS5ib3JkZXJXaWR0aDtcclxuXHRcdGN0eC5saW5lSm9pbiA9ICdiZXZlbCc7XHJcblx0fVxyXG5cclxuXHRpZiAoYXJjLmZ1bGxDaXJjbGVzKSB7XHJcblx0XHRkcmF3RnVsbENpcmNsZUJvcmRlcnMoY3R4LCB2bSwgYXJjLCBpbm5lcik7XHJcblx0fVxyXG5cclxuXHRpZiAoaW5uZXIpIHtcclxuXHRcdGNsaXBBcmMoY3R4LCBhcmMpO1xyXG5cdH1cclxuXHJcblx0Y3R4LmJlZ2luUGF0aCgpO1xyXG5cdGN0eC5hcmMoYXJjLngsIGFyYy55LCB2bS5vdXRlclJhZGl1cywgYXJjLnN0YXJ0QW5nbGUsIGFyYy5lbmRBbmdsZSk7XHJcblx0Y3R4LmFyYyhhcmMueCwgYXJjLnksIGFyYy5pbm5lclJhZGl1cywgYXJjLmVuZEFuZ2xlLCBhcmMuc3RhcnRBbmdsZSwgdHJ1ZSk7XHJcblx0Y3R4LmNsb3NlUGF0aCgpO1xyXG5cdGN0eC5zdHJva2UoKTtcclxufVxyXG5cclxudmFyIGVsZW1lbnRfYXJjID0gY29yZV9lbGVtZW50LmV4dGVuZCh7XHJcblx0X3R5cGU6ICdhcmMnLFxyXG5cclxuXHRpbkxhYmVsUmFuZ2U6IGZ1bmN0aW9uKG1vdXNlWCkge1xyXG5cdFx0dmFyIHZtID0gdGhpcy5fdmlldztcclxuXHJcblx0XHRpZiAodm0pIHtcclxuXHRcdFx0cmV0dXJuIChNYXRoLnBvdyhtb3VzZVggLSB2bS54LCAyKSA8IE1hdGgucG93KHZtLnJhZGl1cyArIHZtLmhvdmVyUmFkaXVzLCAyKSk7XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gZmFsc2U7XHJcblx0fSxcclxuXHJcblx0aW5SYW5nZTogZnVuY3Rpb24oY2hhcnRYLCBjaGFydFkpIHtcclxuXHRcdHZhciB2bSA9IHRoaXMuX3ZpZXc7XHJcblxyXG5cdFx0aWYgKHZtKSB7XHJcblx0XHRcdHZhciBwb2ludFJlbGF0aXZlUG9zaXRpb24gPSBoZWxwZXJzJDEuZ2V0QW5nbGVGcm9tUG9pbnQodm0sIHt4OiBjaGFydFgsIHk6IGNoYXJ0WX0pO1xyXG5cdFx0XHR2YXIgYW5nbGUgPSBwb2ludFJlbGF0aXZlUG9zaXRpb24uYW5nbGU7XHJcblx0XHRcdHZhciBkaXN0YW5jZSA9IHBvaW50UmVsYXRpdmVQb3NpdGlvbi5kaXN0YW5jZTtcclxuXHJcblx0XHRcdC8vIFNhbml0aXNlIGFuZ2xlIHJhbmdlXHJcblx0XHRcdHZhciBzdGFydEFuZ2xlID0gdm0uc3RhcnRBbmdsZTtcclxuXHRcdFx0dmFyIGVuZEFuZ2xlID0gdm0uZW5kQW5nbGU7XHJcblx0XHRcdHdoaWxlIChlbmRBbmdsZSA8IHN0YXJ0QW5nbGUpIHtcclxuXHRcdFx0XHRlbmRBbmdsZSArPSBUQVU7XHJcblx0XHRcdH1cclxuXHRcdFx0d2hpbGUgKGFuZ2xlID4gZW5kQW5nbGUpIHtcclxuXHRcdFx0XHRhbmdsZSAtPSBUQVU7XHJcblx0XHRcdH1cclxuXHRcdFx0d2hpbGUgKGFuZ2xlIDwgc3RhcnRBbmdsZSkge1xyXG5cdFx0XHRcdGFuZ2xlICs9IFRBVTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Ly8gQ2hlY2sgaWYgd2l0aGluIHRoZSByYW5nZSBvZiB0aGUgb3Blbi9jbG9zZSBhbmdsZVxyXG5cdFx0XHR2YXIgYmV0d2VlbkFuZ2xlcyA9IChhbmdsZSA+PSBzdGFydEFuZ2xlICYmIGFuZ2xlIDw9IGVuZEFuZ2xlKTtcclxuXHRcdFx0dmFyIHdpdGhpblJhZGl1cyA9IChkaXN0YW5jZSA+PSB2bS5pbm5lclJhZGl1cyAmJiBkaXN0YW5jZSA8PSB2bS5vdXRlclJhZGl1cyk7XHJcblxyXG5cdFx0XHRyZXR1cm4gKGJldHdlZW5BbmdsZXMgJiYgd2l0aGluUmFkaXVzKTtcclxuXHRcdH1cclxuXHRcdHJldHVybiBmYWxzZTtcclxuXHR9LFxyXG5cclxuXHRnZXRDZW50ZXJQb2ludDogZnVuY3Rpb24oKSB7XHJcblx0XHR2YXIgdm0gPSB0aGlzLl92aWV3O1xyXG5cdFx0dmFyIGhhbGZBbmdsZSA9ICh2bS5zdGFydEFuZ2xlICsgdm0uZW5kQW5nbGUpIC8gMjtcclxuXHRcdHZhciBoYWxmUmFkaXVzID0gKHZtLmlubmVyUmFkaXVzICsgdm0ub3V0ZXJSYWRpdXMpIC8gMjtcclxuXHRcdHJldHVybiB7XHJcblx0XHRcdHg6IHZtLnggKyBNYXRoLmNvcyhoYWxmQW5nbGUpICogaGFsZlJhZGl1cyxcclxuXHRcdFx0eTogdm0ueSArIE1hdGguc2luKGhhbGZBbmdsZSkgKiBoYWxmUmFkaXVzXHJcblx0XHR9O1xyXG5cdH0sXHJcblxyXG5cdGdldEFyZWE6IGZ1bmN0aW9uKCkge1xyXG5cdFx0dmFyIHZtID0gdGhpcy5fdmlldztcclxuXHRcdHJldHVybiBNYXRoLlBJICogKCh2bS5lbmRBbmdsZSAtIHZtLnN0YXJ0QW5nbGUpIC8gKDIgKiBNYXRoLlBJKSkgKiAoTWF0aC5wb3codm0ub3V0ZXJSYWRpdXMsIDIpIC0gTWF0aC5wb3codm0uaW5uZXJSYWRpdXMsIDIpKTtcclxuXHR9LFxyXG5cclxuXHR0b29sdGlwUG9zaXRpb246IGZ1bmN0aW9uKCkge1xyXG5cdFx0dmFyIHZtID0gdGhpcy5fdmlldztcclxuXHRcdHZhciBjZW50cmVBbmdsZSA9IHZtLnN0YXJ0QW5nbGUgKyAoKHZtLmVuZEFuZ2xlIC0gdm0uc3RhcnRBbmdsZSkgLyAyKTtcclxuXHRcdHZhciByYW5nZUZyb21DZW50cmUgPSAodm0ub3V0ZXJSYWRpdXMgLSB2bS5pbm5lclJhZGl1cykgLyAyICsgdm0uaW5uZXJSYWRpdXM7XHJcblxyXG5cdFx0cmV0dXJuIHtcclxuXHRcdFx0eDogdm0ueCArIChNYXRoLmNvcyhjZW50cmVBbmdsZSkgKiByYW5nZUZyb21DZW50cmUpLFxyXG5cdFx0XHR5OiB2bS55ICsgKE1hdGguc2luKGNlbnRyZUFuZ2xlKSAqIHJhbmdlRnJvbUNlbnRyZSlcclxuXHRcdH07XHJcblx0fSxcclxuXHJcblx0ZHJhdzogZnVuY3Rpb24oKSB7XHJcblx0XHR2YXIgY3R4ID0gdGhpcy5fY2hhcnQuY3R4O1xyXG5cdFx0dmFyIHZtID0gdGhpcy5fdmlldztcclxuXHRcdHZhciBwaXhlbE1hcmdpbiA9ICh2bS5ib3JkZXJBbGlnbiA9PT0gJ2lubmVyJykgPyAwLjMzIDogMDtcclxuXHRcdHZhciBhcmMgPSB7XHJcblx0XHRcdHg6IHZtLngsXHJcblx0XHRcdHk6IHZtLnksXHJcblx0XHRcdGlubmVyUmFkaXVzOiB2bS5pbm5lclJhZGl1cyxcclxuXHRcdFx0b3V0ZXJSYWRpdXM6IE1hdGgubWF4KHZtLm91dGVyUmFkaXVzIC0gcGl4ZWxNYXJnaW4sIDApLFxyXG5cdFx0XHRwaXhlbE1hcmdpbjogcGl4ZWxNYXJnaW4sXHJcblx0XHRcdHN0YXJ0QW5nbGU6IHZtLnN0YXJ0QW5nbGUsXHJcblx0XHRcdGVuZEFuZ2xlOiB2bS5lbmRBbmdsZSxcclxuXHRcdFx0ZnVsbENpcmNsZXM6IE1hdGguZmxvb3Iodm0uY2lyY3VtZmVyZW5jZSAvIFRBVSlcclxuXHRcdH07XHJcblx0XHR2YXIgaTtcclxuXHJcblx0XHRjdHguc2F2ZSgpO1xyXG5cclxuXHRcdGN0eC5maWxsU3R5bGUgPSB2bS5iYWNrZ3JvdW5kQ29sb3I7XHJcblx0XHRjdHguc3Ryb2tlU3R5bGUgPSB2bS5ib3JkZXJDb2xvcjtcclxuXHJcblx0XHRpZiAoYXJjLmZ1bGxDaXJjbGVzKSB7XHJcblx0XHRcdGFyYy5lbmRBbmdsZSA9IGFyYy5zdGFydEFuZ2xlICsgVEFVO1xyXG5cdFx0XHRjdHguYmVnaW5QYXRoKCk7XHJcblx0XHRcdGN0eC5hcmMoYXJjLngsIGFyYy55LCBhcmMub3V0ZXJSYWRpdXMsIGFyYy5zdGFydEFuZ2xlLCBhcmMuZW5kQW5nbGUpO1xyXG5cdFx0XHRjdHguYXJjKGFyYy54LCBhcmMueSwgYXJjLmlubmVyUmFkaXVzLCBhcmMuZW5kQW5nbGUsIGFyYy5zdGFydEFuZ2xlLCB0cnVlKTtcclxuXHRcdFx0Y3R4LmNsb3NlUGF0aCgpO1xyXG5cdFx0XHRmb3IgKGkgPSAwOyBpIDwgYXJjLmZ1bGxDaXJjbGVzOyArK2kpIHtcclxuXHRcdFx0XHRjdHguZmlsbCgpO1xyXG5cdFx0XHR9XHJcblx0XHRcdGFyYy5lbmRBbmdsZSA9IGFyYy5zdGFydEFuZ2xlICsgdm0uY2lyY3VtZmVyZW5jZSAlIFRBVTtcclxuXHRcdH1cclxuXHJcblx0XHRjdHguYmVnaW5QYXRoKCk7XHJcblx0XHRjdHguYXJjKGFyYy54LCBhcmMueSwgYXJjLm91dGVyUmFkaXVzLCBhcmMuc3RhcnRBbmdsZSwgYXJjLmVuZEFuZ2xlKTtcclxuXHRcdGN0eC5hcmMoYXJjLngsIGFyYy55LCBhcmMuaW5uZXJSYWRpdXMsIGFyYy5lbmRBbmdsZSwgYXJjLnN0YXJ0QW5nbGUsIHRydWUpO1xyXG5cdFx0Y3R4LmNsb3NlUGF0aCgpO1xyXG5cdFx0Y3R4LmZpbGwoKTtcclxuXHJcblx0XHRpZiAodm0uYm9yZGVyV2lkdGgpIHtcclxuXHRcdFx0ZHJhd0JvcmRlcihjdHgsIHZtLCBhcmMpO1xyXG5cdFx0fVxyXG5cclxuXHRcdGN0eC5yZXN0b3JlKCk7XHJcblx0fVxyXG59KTtcblxudmFyIHZhbHVlT3JEZWZhdWx0JDEgPSBoZWxwZXJzJDEudmFsdWVPckRlZmF1bHQ7XHJcblxyXG52YXIgZGVmYXVsdENvbG9yID0gY29yZV9kZWZhdWx0cy5nbG9iYWwuZGVmYXVsdENvbG9yO1xyXG5cclxuY29yZV9kZWZhdWx0cy5fc2V0KCdnbG9iYWwnLCB7XHJcblx0ZWxlbWVudHM6IHtcclxuXHRcdGxpbmU6IHtcclxuXHRcdFx0dGVuc2lvbjogMC40LFxyXG5cdFx0XHRiYWNrZ3JvdW5kQ29sb3I6IGRlZmF1bHRDb2xvcixcclxuXHRcdFx0Ym9yZGVyV2lkdGg6IDMsXHJcblx0XHRcdGJvcmRlckNvbG9yOiBkZWZhdWx0Q29sb3IsXHJcblx0XHRcdGJvcmRlckNhcFN0eWxlOiAnYnV0dCcsXHJcblx0XHRcdGJvcmRlckRhc2g6IFtdLFxyXG5cdFx0XHRib3JkZXJEYXNoT2Zmc2V0OiAwLjAsXHJcblx0XHRcdGJvcmRlckpvaW5TdHlsZTogJ21pdGVyJyxcclxuXHRcdFx0Y2FwQmV6aWVyUG9pbnRzOiB0cnVlLFxyXG5cdFx0XHRmaWxsOiB0cnVlLCAvLyBkbyB3ZSBmaWxsIGluIHRoZSBhcmVhIGJldHdlZW4gdGhlIGxpbmUgYW5kIGl0cyBiYXNlIGF4aXNcclxuXHRcdH1cclxuXHR9XHJcbn0pO1xyXG5cclxudmFyIGVsZW1lbnRfbGluZSA9IGNvcmVfZWxlbWVudC5leHRlbmQoe1xyXG5cdF90eXBlOiAnbGluZScsXHJcblxyXG5cdGRyYXc6IGZ1bmN0aW9uKCkge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHRcdHZhciB2bSA9IG1lLl92aWV3O1xyXG5cdFx0dmFyIGN0eCA9IG1lLl9jaGFydC5jdHg7XHJcblx0XHR2YXIgc3BhbkdhcHMgPSB2bS5zcGFuR2FwcztcclxuXHRcdHZhciBwb2ludHMgPSBtZS5fY2hpbGRyZW4uc2xpY2UoKTsgLy8gY2xvbmUgYXJyYXlcclxuXHRcdHZhciBnbG9iYWxEZWZhdWx0cyA9IGNvcmVfZGVmYXVsdHMuZ2xvYmFsO1xyXG5cdFx0dmFyIGdsb2JhbE9wdGlvbkxpbmVFbGVtZW50cyA9IGdsb2JhbERlZmF1bHRzLmVsZW1lbnRzLmxpbmU7XHJcblx0XHR2YXIgbGFzdERyYXduSW5kZXggPSAtMTtcclxuXHRcdHZhciBjbG9zZVBhdGggPSBtZS5fbG9vcDtcclxuXHRcdHZhciBpbmRleCwgcHJldmlvdXMsIGN1cnJlbnRWTTtcclxuXHJcblx0XHRpZiAoIXBvaW50cy5sZW5ndGgpIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmIChtZS5fbG9vcCkge1xyXG5cdFx0XHRmb3IgKGluZGV4ID0gMDsgaW5kZXggPCBwb2ludHMubGVuZ3RoOyArK2luZGV4KSB7XHJcblx0XHRcdFx0cHJldmlvdXMgPSBoZWxwZXJzJDEucHJldmlvdXNJdGVtKHBvaW50cywgaW5kZXgpO1xyXG5cdFx0XHRcdC8vIElmIHRoZSBsaW5lIGhhcyBhbiBvcGVuIHBhdGgsIHNoaWZ0IHRoZSBwb2ludCBhcnJheVxyXG5cdFx0XHRcdGlmICghcG9pbnRzW2luZGV4XS5fdmlldy5za2lwICYmIHByZXZpb3VzLl92aWV3LnNraXApIHtcclxuXHRcdFx0XHRcdHBvaW50cyA9IHBvaW50cy5zbGljZShpbmRleCkuY29uY2F0KHBvaW50cy5zbGljZSgwLCBpbmRleCkpO1xyXG5cdFx0XHRcdFx0Y2xvc2VQYXRoID0gc3BhbkdhcHM7XHJcblx0XHRcdFx0XHRicmVhaztcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdFx0Ly8gSWYgdGhlIGxpbmUgaGFzIGEgY2xvc2UgcGF0aCwgYWRkIHRoZSBmaXJzdCBwb2ludCBhZ2FpblxyXG5cdFx0XHRpZiAoY2xvc2VQYXRoKSB7XHJcblx0XHRcdFx0cG9pbnRzLnB1c2gocG9pbnRzWzBdKTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdGN0eC5zYXZlKCk7XHJcblxyXG5cdFx0Ly8gU3Ryb2tlIExpbmUgT3B0aW9uc1xyXG5cdFx0Y3R4LmxpbmVDYXAgPSB2bS5ib3JkZXJDYXBTdHlsZSB8fCBnbG9iYWxPcHRpb25MaW5lRWxlbWVudHMuYm9yZGVyQ2FwU3R5bGU7XHJcblxyXG5cdFx0Ly8gSUUgOSBhbmQgMTAgZG8gbm90IHN1cHBvcnQgbGluZSBkYXNoXHJcblx0XHRpZiAoY3R4LnNldExpbmVEYXNoKSB7XHJcblx0XHRcdGN0eC5zZXRMaW5lRGFzaCh2bS5ib3JkZXJEYXNoIHx8IGdsb2JhbE9wdGlvbkxpbmVFbGVtZW50cy5ib3JkZXJEYXNoKTtcclxuXHRcdH1cclxuXHJcblx0XHRjdHgubGluZURhc2hPZmZzZXQgPSB2YWx1ZU9yRGVmYXVsdCQxKHZtLmJvcmRlckRhc2hPZmZzZXQsIGdsb2JhbE9wdGlvbkxpbmVFbGVtZW50cy5ib3JkZXJEYXNoT2Zmc2V0KTtcclxuXHRcdGN0eC5saW5lSm9pbiA9IHZtLmJvcmRlckpvaW5TdHlsZSB8fCBnbG9iYWxPcHRpb25MaW5lRWxlbWVudHMuYm9yZGVySm9pblN0eWxlO1xyXG5cdFx0Y3R4LmxpbmVXaWR0aCA9IHZhbHVlT3JEZWZhdWx0JDEodm0uYm9yZGVyV2lkdGgsIGdsb2JhbE9wdGlvbkxpbmVFbGVtZW50cy5ib3JkZXJXaWR0aCk7XHJcblx0XHRjdHguc3Ryb2tlU3R5bGUgPSB2bS5ib3JkZXJDb2xvciB8fCBnbG9iYWxEZWZhdWx0cy5kZWZhdWx0Q29sb3I7XHJcblxyXG5cdFx0Ly8gU3Ryb2tlIExpbmVcclxuXHRcdGN0eC5iZWdpblBhdGgoKTtcclxuXHJcblx0XHQvLyBGaXJzdCBwb2ludCBtb3ZlcyB0byBpdCdzIHN0YXJ0aW5nIHBvc2l0aW9uIG5vIG1hdHRlciB3aGF0XHJcblx0XHRjdXJyZW50Vk0gPSBwb2ludHNbMF0uX3ZpZXc7XHJcblx0XHRpZiAoIWN1cnJlbnRWTS5za2lwKSB7XHJcblx0XHRcdGN0eC5tb3ZlVG8oY3VycmVudFZNLngsIGN1cnJlbnRWTS55KTtcclxuXHRcdFx0bGFzdERyYXduSW5kZXggPSAwO1xyXG5cdFx0fVxyXG5cclxuXHRcdGZvciAoaW5kZXggPSAxOyBpbmRleCA8IHBvaW50cy5sZW5ndGg7ICsraW5kZXgpIHtcclxuXHRcdFx0Y3VycmVudFZNID0gcG9pbnRzW2luZGV4XS5fdmlldztcclxuXHRcdFx0cHJldmlvdXMgPSBsYXN0RHJhd25JbmRleCA9PT0gLTEgPyBoZWxwZXJzJDEucHJldmlvdXNJdGVtKHBvaW50cywgaW5kZXgpIDogcG9pbnRzW2xhc3REcmF3bkluZGV4XTtcclxuXHJcblx0XHRcdGlmICghY3VycmVudFZNLnNraXApIHtcclxuXHRcdFx0XHRpZiAoKGxhc3REcmF3bkluZGV4ICE9PSAoaW5kZXggLSAxKSAmJiAhc3BhbkdhcHMpIHx8IGxhc3REcmF3bkluZGV4ID09PSAtMSkge1xyXG5cdFx0XHRcdFx0Ly8gVGhlcmUgd2FzIGEgZ2FwIGFuZCB0aGlzIGlzIHRoZSBmaXJzdCBwb2ludCBhZnRlciB0aGUgZ2FwXHJcblx0XHRcdFx0XHRjdHgubW92ZVRvKGN1cnJlbnRWTS54LCBjdXJyZW50Vk0ueSk7XHJcblx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdC8vIExpbmUgdG8gbmV4dCBwb2ludFxyXG5cdFx0XHRcdFx0aGVscGVycyQxLmNhbnZhcy5saW5lVG8oY3R4LCBwcmV2aW91cy5fdmlldywgY3VycmVudFZNKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0bGFzdERyYXduSW5kZXggPSBpbmRleDtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdGlmIChjbG9zZVBhdGgpIHtcclxuXHRcdFx0Y3R4LmNsb3NlUGF0aCgpO1xyXG5cdFx0fVxyXG5cclxuXHRcdGN0eC5zdHJva2UoKTtcclxuXHRcdGN0eC5yZXN0b3JlKCk7XHJcblx0fVxyXG59KTtcblxudmFyIHZhbHVlT3JEZWZhdWx0JDIgPSBoZWxwZXJzJDEudmFsdWVPckRlZmF1bHQ7XHJcblxyXG52YXIgZGVmYXVsdENvbG9yJDEgPSBjb3JlX2RlZmF1bHRzLmdsb2JhbC5kZWZhdWx0Q29sb3I7XHJcblxyXG5jb3JlX2RlZmF1bHRzLl9zZXQoJ2dsb2JhbCcsIHtcclxuXHRlbGVtZW50czoge1xyXG5cdFx0cG9pbnQ6IHtcclxuXHRcdFx0cmFkaXVzOiAzLFxyXG5cdFx0XHRwb2ludFN0eWxlOiAnY2lyY2xlJyxcclxuXHRcdFx0YmFja2dyb3VuZENvbG9yOiBkZWZhdWx0Q29sb3IkMSxcclxuXHRcdFx0Ym9yZGVyQ29sb3I6IGRlZmF1bHRDb2xvciQxLFxyXG5cdFx0XHRib3JkZXJXaWR0aDogMSxcclxuXHRcdFx0Ly8gSG92ZXJcclxuXHRcdFx0aGl0UmFkaXVzOiAxLFxyXG5cdFx0XHRob3ZlclJhZGl1czogNCxcclxuXHRcdFx0aG92ZXJCb3JkZXJXaWR0aDogMVxyXG5cdFx0fVxyXG5cdH1cclxufSk7XHJcblxyXG5mdW5jdGlvbiB4UmFuZ2UobW91c2VYKSB7XHJcblx0dmFyIHZtID0gdGhpcy5fdmlldztcclxuXHRyZXR1cm4gdm0gPyAoTWF0aC5hYnMobW91c2VYIC0gdm0ueCkgPCB2bS5yYWRpdXMgKyB2bS5oaXRSYWRpdXMpIDogZmFsc2U7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHlSYW5nZShtb3VzZVkpIHtcclxuXHR2YXIgdm0gPSB0aGlzLl92aWV3O1xyXG5cdHJldHVybiB2bSA/IChNYXRoLmFicyhtb3VzZVkgLSB2bS55KSA8IHZtLnJhZGl1cyArIHZtLmhpdFJhZGl1cykgOiBmYWxzZTtcclxufVxyXG5cclxudmFyIGVsZW1lbnRfcG9pbnQgPSBjb3JlX2VsZW1lbnQuZXh0ZW5kKHtcclxuXHRfdHlwZTogJ3BvaW50JyxcclxuXHJcblx0aW5SYW5nZTogZnVuY3Rpb24obW91c2VYLCBtb3VzZVkpIHtcclxuXHRcdHZhciB2bSA9IHRoaXMuX3ZpZXc7XHJcblx0XHRyZXR1cm4gdm0gPyAoKE1hdGgucG93KG1vdXNlWCAtIHZtLngsIDIpICsgTWF0aC5wb3cobW91c2VZIC0gdm0ueSwgMikpIDwgTWF0aC5wb3codm0uaGl0UmFkaXVzICsgdm0ucmFkaXVzLCAyKSkgOiBmYWxzZTtcclxuXHR9LFxyXG5cclxuXHRpbkxhYmVsUmFuZ2U6IHhSYW5nZSxcclxuXHRpblhSYW5nZTogeFJhbmdlLFxyXG5cdGluWVJhbmdlOiB5UmFuZ2UsXHJcblxyXG5cdGdldENlbnRlclBvaW50OiBmdW5jdGlvbigpIHtcclxuXHRcdHZhciB2bSA9IHRoaXMuX3ZpZXc7XHJcblx0XHRyZXR1cm4ge1xyXG5cdFx0XHR4OiB2bS54LFxyXG5cdFx0XHR5OiB2bS55XHJcblx0XHR9O1xyXG5cdH0sXHJcblxyXG5cdGdldEFyZWE6IGZ1bmN0aW9uKCkge1xyXG5cdFx0cmV0dXJuIE1hdGguUEkgKiBNYXRoLnBvdyh0aGlzLl92aWV3LnJhZGl1cywgMik7XHJcblx0fSxcclxuXHJcblx0dG9vbHRpcFBvc2l0aW9uOiBmdW5jdGlvbigpIHtcclxuXHRcdHZhciB2bSA9IHRoaXMuX3ZpZXc7XHJcblx0XHRyZXR1cm4ge1xyXG5cdFx0XHR4OiB2bS54LFxyXG5cdFx0XHR5OiB2bS55LFxyXG5cdFx0XHRwYWRkaW5nOiB2bS5yYWRpdXMgKyB2bS5ib3JkZXJXaWR0aFxyXG5cdFx0fTtcclxuXHR9LFxyXG5cclxuXHRkcmF3OiBmdW5jdGlvbihjaGFydEFyZWEpIHtcclxuXHRcdHZhciB2bSA9IHRoaXMuX3ZpZXc7XHJcblx0XHR2YXIgY3R4ID0gdGhpcy5fY2hhcnQuY3R4O1xyXG5cdFx0dmFyIHBvaW50U3R5bGUgPSB2bS5wb2ludFN0eWxlO1xyXG5cdFx0dmFyIHJvdGF0aW9uID0gdm0ucm90YXRpb247XHJcblx0XHR2YXIgcmFkaXVzID0gdm0ucmFkaXVzO1xyXG5cdFx0dmFyIHggPSB2bS54O1xyXG5cdFx0dmFyIHkgPSB2bS55O1xyXG5cdFx0dmFyIGdsb2JhbERlZmF1bHRzID0gY29yZV9kZWZhdWx0cy5nbG9iYWw7XHJcblx0XHR2YXIgZGVmYXVsdENvbG9yID0gZ2xvYmFsRGVmYXVsdHMuZGVmYXVsdENvbG9yOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXNoYWRvd1xyXG5cclxuXHRcdGlmICh2bS5za2lwKSB7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBDbGlwcGluZyBmb3IgUG9pbnRzLlxyXG5cdFx0aWYgKGNoYXJ0QXJlYSA9PT0gdW5kZWZpbmVkIHx8IGhlbHBlcnMkMS5jYW52YXMuX2lzUG9pbnRJbkFyZWEodm0sIGNoYXJ0QXJlYSkpIHtcclxuXHRcdFx0Y3R4LnN0cm9rZVN0eWxlID0gdm0uYm9yZGVyQ29sb3IgfHwgZGVmYXVsdENvbG9yO1xyXG5cdFx0XHRjdHgubGluZVdpZHRoID0gdmFsdWVPckRlZmF1bHQkMih2bS5ib3JkZXJXaWR0aCwgZ2xvYmFsRGVmYXVsdHMuZWxlbWVudHMucG9pbnQuYm9yZGVyV2lkdGgpO1xyXG5cdFx0XHRjdHguZmlsbFN0eWxlID0gdm0uYmFja2dyb3VuZENvbG9yIHx8IGRlZmF1bHRDb2xvcjtcclxuXHRcdFx0aGVscGVycyQxLmNhbnZhcy5kcmF3UG9pbnQoY3R4LCBwb2ludFN0eWxlLCByYWRpdXMsIHgsIHksIHJvdGF0aW9uKTtcclxuXHRcdH1cclxuXHR9XHJcbn0pO1xuXG52YXIgZGVmYXVsdENvbG9yJDIgPSBjb3JlX2RlZmF1bHRzLmdsb2JhbC5kZWZhdWx0Q29sb3I7XHJcblxyXG5jb3JlX2RlZmF1bHRzLl9zZXQoJ2dsb2JhbCcsIHtcclxuXHRlbGVtZW50czoge1xyXG5cdFx0cmVjdGFuZ2xlOiB7XHJcblx0XHRcdGJhY2tncm91bmRDb2xvcjogZGVmYXVsdENvbG9yJDIsXHJcblx0XHRcdGJvcmRlckNvbG9yOiBkZWZhdWx0Q29sb3IkMixcclxuXHRcdFx0Ym9yZGVyU2tpcHBlZDogJ2JvdHRvbScsXHJcblx0XHRcdGJvcmRlcldpZHRoOiAwXHJcblx0XHR9XHJcblx0fVxyXG59KTtcclxuXHJcbmZ1bmN0aW9uIGlzVmVydGljYWwodm0pIHtcclxuXHRyZXR1cm4gdm0gJiYgdm0ud2lkdGggIT09IHVuZGVmaW5lZDtcclxufVxyXG5cclxuLyoqXHJcbiAqIEhlbHBlciBmdW5jdGlvbiB0byBnZXQgdGhlIGJvdW5kcyBvZiB0aGUgYmFyIHJlZ2FyZGxlc3Mgb2YgdGhlIG9yaWVudGF0aW9uXHJcbiAqIEBwYXJhbSBiYXIge0NoYXJ0LkVsZW1lbnQuUmVjdGFuZ2xlfSB0aGUgYmFyXHJcbiAqIEByZXR1cm4ge0JvdW5kc30gYm91bmRzIG9mIHRoZSBiYXJcclxuICogQHByaXZhdGVcclxuICovXHJcbmZ1bmN0aW9uIGdldEJhckJvdW5kcyh2bSkge1xyXG5cdHZhciB4MSwgeDIsIHkxLCB5MiwgaGFsZjtcclxuXHJcblx0aWYgKGlzVmVydGljYWwodm0pKSB7XHJcblx0XHRoYWxmID0gdm0ud2lkdGggLyAyO1xyXG5cdFx0eDEgPSB2bS54IC0gaGFsZjtcclxuXHRcdHgyID0gdm0ueCArIGhhbGY7XHJcblx0XHR5MSA9IE1hdGgubWluKHZtLnksIHZtLmJhc2UpO1xyXG5cdFx0eTIgPSBNYXRoLm1heCh2bS55LCB2bS5iYXNlKTtcclxuXHR9IGVsc2Uge1xyXG5cdFx0aGFsZiA9IHZtLmhlaWdodCAvIDI7XHJcblx0XHR4MSA9IE1hdGgubWluKHZtLngsIHZtLmJhc2UpO1xyXG5cdFx0eDIgPSBNYXRoLm1heCh2bS54LCB2bS5iYXNlKTtcclxuXHRcdHkxID0gdm0ueSAtIGhhbGY7XHJcblx0XHR5MiA9IHZtLnkgKyBoYWxmO1xyXG5cdH1cclxuXHJcblx0cmV0dXJuIHtcclxuXHRcdGxlZnQ6IHgxLFxyXG5cdFx0dG9wOiB5MSxcclxuXHRcdHJpZ2h0OiB4MixcclxuXHRcdGJvdHRvbTogeTJcclxuXHR9O1xyXG59XHJcblxyXG5mdW5jdGlvbiBzd2FwKG9yaWcsIHYxLCB2Mikge1xyXG5cdHJldHVybiBvcmlnID09PSB2MSA/IHYyIDogb3JpZyA9PT0gdjIgPyB2MSA6IG9yaWc7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHBhcnNlQm9yZGVyU2tpcHBlZCh2bSkge1xyXG5cdHZhciBlZGdlID0gdm0uYm9yZGVyU2tpcHBlZDtcclxuXHR2YXIgcmVzID0ge307XHJcblxyXG5cdGlmICghZWRnZSkge1xyXG5cdFx0cmV0dXJuIHJlcztcclxuXHR9XHJcblxyXG5cdGlmICh2bS5ob3Jpem9udGFsKSB7XHJcblx0XHRpZiAodm0uYmFzZSA+IHZtLngpIHtcclxuXHRcdFx0ZWRnZSA9IHN3YXAoZWRnZSwgJ2xlZnQnLCAncmlnaHQnKTtcclxuXHRcdH1cclxuXHR9IGVsc2UgaWYgKHZtLmJhc2UgPCB2bS55KSB7XHJcblx0XHRlZGdlID0gc3dhcChlZGdlLCAnYm90dG9tJywgJ3RvcCcpO1xyXG5cdH1cclxuXHJcblx0cmVzW2VkZ2VdID0gdHJ1ZTtcclxuXHRyZXR1cm4gcmVzO1xyXG59XHJcblxyXG5mdW5jdGlvbiBwYXJzZUJvcmRlcldpZHRoKHZtLCBtYXhXLCBtYXhIKSB7XHJcblx0dmFyIHZhbHVlID0gdm0uYm9yZGVyV2lkdGg7XHJcblx0dmFyIHNraXAgPSBwYXJzZUJvcmRlclNraXBwZWQodm0pO1xyXG5cdHZhciB0LCByLCBiLCBsO1xyXG5cclxuXHRpZiAoaGVscGVycyQxLmlzT2JqZWN0KHZhbHVlKSkge1xyXG5cdFx0dCA9ICt2YWx1ZS50b3AgfHwgMDtcclxuXHRcdHIgPSArdmFsdWUucmlnaHQgfHwgMDtcclxuXHRcdGIgPSArdmFsdWUuYm90dG9tIHx8IDA7XHJcblx0XHRsID0gK3ZhbHVlLmxlZnQgfHwgMDtcclxuXHR9IGVsc2Uge1xyXG5cdFx0dCA9IHIgPSBiID0gbCA9ICt2YWx1ZSB8fCAwO1xyXG5cdH1cclxuXHJcblx0cmV0dXJuIHtcclxuXHRcdHQ6IHNraXAudG9wIHx8ICh0IDwgMCkgPyAwIDogdCA+IG1heEggPyBtYXhIIDogdCxcclxuXHRcdHI6IHNraXAucmlnaHQgfHwgKHIgPCAwKSA/IDAgOiByID4gbWF4VyA/IG1heFcgOiByLFxyXG5cdFx0Yjogc2tpcC5ib3R0b20gfHwgKGIgPCAwKSA/IDAgOiBiID4gbWF4SCA/IG1heEggOiBiLFxyXG5cdFx0bDogc2tpcC5sZWZ0IHx8IChsIDwgMCkgPyAwIDogbCA+IG1heFcgPyBtYXhXIDogbFxyXG5cdH07XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGJvdW5kaW5nUmVjdHModm0pIHtcclxuXHR2YXIgYm91bmRzID0gZ2V0QmFyQm91bmRzKHZtKTtcclxuXHR2YXIgd2lkdGggPSBib3VuZHMucmlnaHQgLSBib3VuZHMubGVmdDtcclxuXHR2YXIgaGVpZ2h0ID0gYm91bmRzLmJvdHRvbSAtIGJvdW5kcy50b3A7XHJcblx0dmFyIGJvcmRlciA9IHBhcnNlQm9yZGVyV2lkdGgodm0sIHdpZHRoIC8gMiwgaGVpZ2h0IC8gMik7XHJcblxyXG5cdHJldHVybiB7XHJcblx0XHRvdXRlcjoge1xyXG5cdFx0XHR4OiBib3VuZHMubGVmdCxcclxuXHRcdFx0eTogYm91bmRzLnRvcCxcclxuXHRcdFx0dzogd2lkdGgsXHJcblx0XHRcdGg6IGhlaWdodFxyXG5cdFx0fSxcclxuXHRcdGlubmVyOiB7XHJcblx0XHRcdHg6IGJvdW5kcy5sZWZ0ICsgYm9yZGVyLmwsXHJcblx0XHRcdHk6IGJvdW5kcy50b3AgKyBib3JkZXIudCxcclxuXHRcdFx0dzogd2lkdGggLSBib3JkZXIubCAtIGJvcmRlci5yLFxyXG5cdFx0XHRoOiBoZWlnaHQgLSBib3JkZXIudCAtIGJvcmRlci5iXHJcblx0XHR9XHJcblx0fTtcclxufVxyXG5cclxuZnVuY3Rpb24gaW5SYW5nZSh2bSwgeCwgeSkge1xyXG5cdHZhciBza2lwWCA9IHggPT09IG51bGw7XHJcblx0dmFyIHNraXBZID0geSA9PT0gbnVsbDtcclxuXHR2YXIgYm91bmRzID0gIXZtIHx8IChza2lwWCAmJiBza2lwWSkgPyBmYWxzZSA6IGdldEJhckJvdW5kcyh2bSk7XHJcblxyXG5cdHJldHVybiBib3VuZHNcclxuXHRcdCYmIChza2lwWCB8fCB4ID49IGJvdW5kcy5sZWZ0ICYmIHggPD0gYm91bmRzLnJpZ2h0KVxyXG5cdFx0JiYgKHNraXBZIHx8IHkgPj0gYm91bmRzLnRvcCAmJiB5IDw9IGJvdW5kcy5ib3R0b20pO1xyXG59XHJcblxyXG52YXIgZWxlbWVudF9yZWN0YW5nbGUgPSBjb3JlX2VsZW1lbnQuZXh0ZW5kKHtcclxuXHRfdHlwZTogJ3JlY3RhbmdsZScsXHJcblxyXG5cdGRyYXc6IGZ1bmN0aW9uKCkge1xyXG5cdFx0dmFyIGN0eCA9IHRoaXMuX2NoYXJ0LmN0eDtcclxuXHRcdHZhciB2bSA9IHRoaXMuX3ZpZXc7XHJcblx0XHR2YXIgcmVjdHMgPSBib3VuZGluZ1JlY3RzKHZtKTtcclxuXHRcdHZhciBvdXRlciA9IHJlY3RzLm91dGVyO1xyXG5cdFx0dmFyIGlubmVyID0gcmVjdHMuaW5uZXI7XHJcblxyXG5cdFx0Y3R4LmZpbGxTdHlsZSA9IHZtLmJhY2tncm91bmRDb2xvcjtcclxuXHRcdGN0eC5maWxsUmVjdChvdXRlci54LCBvdXRlci55LCBvdXRlci53LCBvdXRlci5oKTtcclxuXHJcblx0XHRpZiAob3V0ZXIudyA9PT0gaW5uZXIudyAmJiBvdXRlci5oID09PSBpbm5lci5oKSB7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHJcblx0XHRjdHguc2F2ZSgpO1xyXG5cdFx0Y3R4LmJlZ2luUGF0aCgpO1xyXG5cdFx0Y3R4LnJlY3Qob3V0ZXIueCwgb3V0ZXIueSwgb3V0ZXIudywgb3V0ZXIuaCk7XHJcblx0XHRjdHguY2xpcCgpO1xyXG5cdFx0Y3R4LmZpbGxTdHlsZSA9IHZtLmJvcmRlckNvbG9yO1xyXG5cdFx0Y3R4LnJlY3QoaW5uZXIueCwgaW5uZXIueSwgaW5uZXIudywgaW5uZXIuaCk7XHJcblx0XHRjdHguZmlsbCgnZXZlbm9kZCcpO1xyXG5cdFx0Y3R4LnJlc3RvcmUoKTtcclxuXHR9LFxyXG5cclxuXHRoZWlnaHQ6IGZ1bmN0aW9uKCkge1xyXG5cdFx0dmFyIHZtID0gdGhpcy5fdmlldztcclxuXHRcdHJldHVybiB2bS5iYXNlIC0gdm0ueTtcclxuXHR9LFxyXG5cclxuXHRpblJhbmdlOiBmdW5jdGlvbihtb3VzZVgsIG1vdXNlWSkge1xyXG5cdFx0cmV0dXJuIGluUmFuZ2UodGhpcy5fdmlldywgbW91c2VYLCBtb3VzZVkpO1xyXG5cdH0sXHJcblxyXG5cdGluTGFiZWxSYW5nZTogZnVuY3Rpb24obW91c2VYLCBtb3VzZVkpIHtcclxuXHRcdHZhciB2bSA9IHRoaXMuX3ZpZXc7XHJcblx0XHRyZXR1cm4gaXNWZXJ0aWNhbCh2bSlcclxuXHRcdFx0PyBpblJhbmdlKHZtLCBtb3VzZVgsIG51bGwpXHJcblx0XHRcdDogaW5SYW5nZSh2bSwgbnVsbCwgbW91c2VZKTtcclxuXHR9LFxyXG5cclxuXHRpblhSYW5nZTogZnVuY3Rpb24obW91c2VYKSB7XHJcblx0XHRyZXR1cm4gaW5SYW5nZSh0aGlzLl92aWV3LCBtb3VzZVgsIG51bGwpO1xyXG5cdH0sXHJcblxyXG5cdGluWVJhbmdlOiBmdW5jdGlvbihtb3VzZVkpIHtcclxuXHRcdHJldHVybiBpblJhbmdlKHRoaXMuX3ZpZXcsIG51bGwsIG1vdXNlWSk7XHJcblx0fSxcclxuXHJcblx0Z2V0Q2VudGVyUG9pbnQ6IGZ1bmN0aW9uKCkge1xyXG5cdFx0dmFyIHZtID0gdGhpcy5fdmlldztcclxuXHRcdHZhciB4LCB5O1xyXG5cdFx0aWYgKGlzVmVydGljYWwodm0pKSB7XHJcblx0XHRcdHggPSB2bS54O1xyXG5cdFx0XHR5ID0gKHZtLnkgKyB2bS5iYXNlKSAvIDI7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHR4ID0gKHZtLnggKyB2bS5iYXNlKSAvIDI7XHJcblx0XHRcdHkgPSB2bS55O1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiB7eDogeCwgeTogeX07XHJcblx0fSxcclxuXHJcblx0Z2V0QXJlYTogZnVuY3Rpb24oKSB7XHJcblx0XHR2YXIgdm0gPSB0aGlzLl92aWV3O1xyXG5cclxuXHRcdHJldHVybiBpc1ZlcnRpY2FsKHZtKVxyXG5cdFx0XHQ/IHZtLndpZHRoICogTWF0aC5hYnModm0ueSAtIHZtLmJhc2UpXHJcblx0XHRcdDogdm0uaGVpZ2h0ICogTWF0aC5hYnModm0ueCAtIHZtLmJhc2UpO1xyXG5cdH0sXHJcblxyXG5cdHRvb2x0aXBQb3NpdGlvbjogZnVuY3Rpb24oKSB7XHJcblx0XHR2YXIgdm0gPSB0aGlzLl92aWV3O1xyXG5cdFx0cmV0dXJuIHtcclxuXHRcdFx0eDogdm0ueCxcclxuXHRcdFx0eTogdm0ueVxyXG5cdFx0fTtcclxuXHR9XHJcbn0pO1xuXG52YXIgZWxlbWVudHMgPSB7fTtcclxudmFyIEFyYyA9IGVsZW1lbnRfYXJjO1xyXG52YXIgTGluZSA9IGVsZW1lbnRfbGluZTtcclxudmFyIFBvaW50ID0gZWxlbWVudF9wb2ludDtcclxudmFyIFJlY3RhbmdsZSA9IGVsZW1lbnRfcmVjdGFuZ2xlO1xuZWxlbWVudHMuQXJjID0gQXJjO1xuZWxlbWVudHMuTGluZSA9IExpbmU7XG5lbGVtZW50cy5Qb2ludCA9IFBvaW50O1xuZWxlbWVudHMuUmVjdGFuZ2xlID0gUmVjdGFuZ2xlO1xuXG52YXIgZGVwcmVjYXRlZCA9IGhlbHBlcnMkMS5fZGVwcmVjYXRlZDtcclxudmFyIHZhbHVlT3JEZWZhdWx0JDMgPSBoZWxwZXJzJDEudmFsdWVPckRlZmF1bHQ7XHJcblxyXG5jb3JlX2RlZmF1bHRzLl9zZXQoJ2JhcicsIHtcclxuXHRob3Zlcjoge1xyXG5cdFx0bW9kZTogJ2xhYmVsJ1xyXG5cdH0sXHJcblxyXG5cdHNjYWxlczoge1xyXG5cdFx0eEF4ZXM6IFt7XHJcblx0XHRcdHR5cGU6ICdjYXRlZ29yeScsXHJcblx0XHRcdG9mZnNldDogdHJ1ZSxcclxuXHRcdFx0Z3JpZExpbmVzOiB7XHJcblx0XHRcdFx0b2Zmc2V0R3JpZExpbmVzOiB0cnVlXHJcblx0XHRcdH1cclxuXHRcdH1dLFxyXG5cclxuXHRcdHlBeGVzOiBbe1xyXG5cdFx0XHR0eXBlOiAnbGluZWFyJ1xyXG5cdFx0fV1cclxuXHR9XHJcbn0pO1xyXG5cclxuY29yZV9kZWZhdWx0cy5fc2V0KCdnbG9iYWwnLCB7XHJcblx0ZGF0YXNldHM6IHtcclxuXHRcdGJhcjoge1xyXG5cdFx0XHRjYXRlZ29yeVBlcmNlbnRhZ2U6IDAuOCxcclxuXHRcdFx0YmFyUGVyY2VudGFnZTogMC45XHJcblx0XHR9XHJcblx0fVxyXG59KTtcclxuXHJcbi8qKlxyXG4gKiBDb21wdXRlcyB0aGUgXCJvcHRpbWFsXCIgc2FtcGxlIHNpemUgdG8gbWFpbnRhaW4gYmFycyBlcXVhbGx5IHNpemVkIHdoaWxlIHByZXZlbnRpbmcgb3ZlcmxhcC5cclxuICogQHByaXZhdGVcclxuICovXHJcbmZ1bmN0aW9uIGNvbXB1dGVNaW5TYW1wbGVTaXplKHNjYWxlLCBwaXhlbHMpIHtcclxuXHR2YXIgbWluID0gc2NhbGUuX2xlbmd0aDtcclxuXHR2YXIgcHJldiwgY3VyciwgaSwgaWxlbjtcclxuXHJcblx0Zm9yIChpID0gMSwgaWxlbiA9IHBpeGVscy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcclxuXHRcdG1pbiA9IE1hdGgubWluKG1pbiwgTWF0aC5hYnMocGl4ZWxzW2ldIC0gcGl4ZWxzW2kgLSAxXSkpO1xyXG5cdH1cclxuXHJcblx0Zm9yIChpID0gMCwgaWxlbiA9IHNjYWxlLmdldFRpY2tzKCkubGVuZ3RoOyBpIDwgaWxlbjsgKytpKSB7XHJcblx0XHRjdXJyID0gc2NhbGUuZ2V0UGl4ZWxGb3JUaWNrKGkpO1xyXG5cdFx0bWluID0gaSA+IDAgPyBNYXRoLm1pbihtaW4sIE1hdGguYWJzKGN1cnIgLSBwcmV2KSkgOiBtaW47XHJcblx0XHRwcmV2ID0gY3VycjtcclxuXHR9XHJcblxyXG5cdHJldHVybiBtaW47XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBDb21wdXRlcyBhbiBcImlkZWFsXCIgY2F0ZWdvcnkgYmFzZWQgb24gdGhlIGFic29sdXRlIGJhciB0aGlja25lc3Mgb3IsIGlmIHVuZGVmaW5lZCBvciBudWxsLFxyXG4gKiB1c2VzIHRoZSBzbWFsbGVzdCBpbnRlcnZhbCAoc2VlIGNvbXB1dGVNaW5TYW1wbGVTaXplKSB0aGF0IHByZXZlbnRzIGJhciBvdmVybGFwcGluZy4gVGhpc1xyXG4gKiBtb2RlIGN1cnJlbnRseSBhbHdheXMgZ2VuZXJhdGVzIGJhcnMgZXF1YWxseSBzaXplZCAodW50aWwgd2UgaW50cm9kdWNlIHNjcmlwdGFibGUgb3B0aW9ucz8pLlxyXG4gKiBAcHJpdmF0ZVxyXG4gKi9cclxuZnVuY3Rpb24gY29tcHV0ZUZpdENhdGVnb3J5VHJhaXRzKGluZGV4LCBydWxlciwgb3B0aW9ucykge1xyXG5cdHZhciB0aGlja25lc3MgPSBvcHRpb25zLmJhclRoaWNrbmVzcztcclxuXHR2YXIgY291bnQgPSBydWxlci5zdGFja0NvdW50O1xyXG5cdHZhciBjdXJyID0gcnVsZXIucGl4ZWxzW2luZGV4XTtcclxuXHR2YXIgbWluID0gaGVscGVycyQxLmlzTnVsbE9yVW5kZWYodGhpY2tuZXNzKVxyXG5cdFx0PyBjb21wdXRlTWluU2FtcGxlU2l6ZShydWxlci5zY2FsZSwgcnVsZXIucGl4ZWxzKVxyXG5cdFx0OiAtMTtcclxuXHR2YXIgc2l6ZSwgcmF0aW87XHJcblxyXG5cdGlmIChoZWxwZXJzJDEuaXNOdWxsT3JVbmRlZih0aGlja25lc3MpKSB7XHJcblx0XHRzaXplID0gbWluICogb3B0aW9ucy5jYXRlZ29yeVBlcmNlbnRhZ2U7XHJcblx0XHRyYXRpbyA9IG9wdGlvbnMuYmFyUGVyY2VudGFnZTtcclxuXHR9IGVsc2Uge1xyXG5cdFx0Ly8gV2hlbiBiYXIgdGhpY2tuZXNzIGlzIGVuZm9yY2VkLCBjYXRlZ29yeSBhbmQgYmFyIHBlcmNlbnRhZ2VzIGFyZSBpZ25vcmVkLlxyXG5cdFx0Ly8gTm90ZShTQik6IHdlIGNvdWxkIGFkZCBzdXBwb3J0IGZvciByZWxhdGl2ZSBiYXIgdGhpY2tuZXNzIChlLmcuIGJhclRoaWNrbmVzczogJzUwJScpXHJcblx0XHQvLyBhbmQgZGVwcmVjYXRlIGJhclBlcmNlbnRhZ2Ugc2luY2UgdGhpcyB2YWx1ZSBpcyBpZ25vcmVkIHdoZW4gdGhpY2tuZXNzIGlzIGFic29sdXRlLlxyXG5cdFx0c2l6ZSA9IHRoaWNrbmVzcyAqIGNvdW50O1xyXG5cdFx0cmF0aW8gPSAxO1xyXG5cdH1cclxuXHJcblx0cmV0dXJuIHtcclxuXHRcdGNodW5rOiBzaXplIC8gY291bnQsXHJcblx0XHRyYXRpbzogcmF0aW8sXHJcblx0XHRzdGFydDogY3VyciAtIChzaXplIC8gMilcclxuXHR9O1xyXG59XHJcblxyXG4vKipcclxuICogQ29tcHV0ZXMgYW4gXCJvcHRpbWFsXCIgY2F0ZWdvcnkgdGhhdCBnbG9iYWxseSBhcnJhbmdlcyBiYXJzIHNpZGUgYnkgc2lkZSAobm8gZ2FwIHdoZW5cclxuICogcGVyY2VudGFnZSBvcHRpb25zIGFyZSAxKSwgYmFzZWQgb24gdGhlIHByZXZpb3VzIGFuZCBmb2xsb3dpbmcgY2F0ZWdvcmllcy4gVGhpcyBtb2RlXHJcbiAqIGdlbmVyYXRlcyBiYXJzIHdpdGggZGlmZmVyZW50IHdpZHRocyB3aGVuIGRhdGEgYXJlIG5vdCBldmVubHkgc3BhY2VkLlxyXG4gKiBAcHJpdmF0ZVxyXG4gKi9cclxuZnVuY3Rpb24gY29tcHV0ZUZsZXhDYXRlZ29yeVRyYWl0cyhpbmRleCwgcnVsZXIsIG9wdGlvbnMpIHtcclxuXHR2YXIgcGl4ZWxzID0gcnVsZXIucGl4ZWxzO1xyXG5cdHZhciBjdXJyID0gcGl4ZWxzW2luZGV4XTtcclxuXHR2YXIgcHJldiA9IGluZGV4ID4gMCA/IHBpeGVsc1tpbmRleCAtIDFdIDogbnVsbDtcclxuXHR2YXIgbmV4dCA9IGluZGV4IDwgcGl4ZWxzLmxlbmd0aCAtIDEgPyBwaXhlbHNbaW5kZXggKyAxXSA6IG51bGw7XHJcblx0dmFyIHBlcmNlbnQgPSBvcHRpb25zLmNhdGVnb3J5UGVyY2VudGFnZTtcclxuXHR2YXIgc3RhcnQsIHNpemU7XHJcblxyXG5cdGlmIChwcmV2ID09PSBudWxsKSB7XHJcblx0XHQvLyBmaXJzdCBkYXRhOiBpdHMgc2l6ZSBpcyBkb3VibGUgYmFzZWQgb24gdGhlIG5leHQgcG9pbnQgb3IsXHJcblx0XHQvLyBpZiBpdCdzIGFsc28gdGhlIGxhc3QgZGF0YSwgd2UgdXNlIHRoZSBzY2FsZSBzaXplLlxyXG5cdFx0cHJldiA9IGN1cnIgLSAobmV4dCA9PT0gbnVsbCA/IHJ1bGVyLmVuZCAtIHJ1bGVyLnN0YXJ0IDogbmV4dCAtIGN1cnIpO1xyXG5cdH1cclxuXHJcblx0aWYgKG5leHQgPT09IG51bGwpIHtcclxuXHRcdC8vIGxhc3QgZGF0YTogaXRzIHNpemUgaXMgYWxzbyBkb3VibGUgYmFzZWQgb24gdGhlIHByZXZpb3VzIHBvaW50LlxyXG5cdFx0bmV4dCA9IGN1cnIgKyBjdXJyIC0gcHJldjtcclxuXHR9XHJcblxyXG5cdHN0YXJ0ID0gY3VyciAtIChjdXJyIC0gTWF0aC5taW4ocHJldiwgbmV4dCkpIC8gMiAqIHBlcmNlbnQ7XHJcblx0c2l6ZSA9IE1hdGguYWJzKG5leHQgLSBwcmV2KSAvIDIgKiBwZXJjZW50O1xyXG5cclxuXHRyZXR1cm4ge1xyXG5cdFx0Y2h1bms6IHNpemUgLyBydWxlci5zdGFja0NvdW50LFxyXG5cdFx0cmF0aW86IG9wdGlvbnMuYmFyUGVyY2VudGFnZSxcclxuXHRcdHN0YXJ0OiBzdGFydFxyXG5cdH07XHJcbn1cclxuXHJcbnZhciBjb250cm9sbGVyX2JhciA9IGNvcmVfZGF0YXNldENvbnRyb2xsZXIuZXh0ZW5kKHtcclxuXHJcblx0ZGF0YUVsZW1lbnRUeXBlOiBlbGVtZW50cy5SZWN0YW5nbGUsXHJcblxyXG5cdC8qKlxyXG5cdCAqIEBwcml2YXRlXHJcblx0ICovXHJcblx0X2RhdGFFbGVtZW50T3B0aW9uczogW1xyXG5cdFx0J2JhY2tncm91bmRDb2xvcicsXHJcblx0XHQnYm9yZGVyQ29sb3InLFxyXG5cdFx0J2JvcmRlclNraXBwZWQnLFxyXG5cdFx0J2JvcmRlcldpZHRoJyxcclxuXHRcdCdiYXJQZXJjZW50YWdlJyxcclxuXHRcdCdiYXJUaGlja25lc3MnLFxyXG5cdFx0J2NhdGVnb3J5UGVyY2VudGFnZScsXHJcblx0XHQnbWF4QmFyVGhpY2tuZXNzJyxcclxuXHRcdCdtaW5CYXJMZW5ndGgnXHJcblx0XSxcclxuXHJcblx0aW5pdGlhbGl6ZTogZnVuY3Rpb24oKSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0dmFyIG1ldGEsIHNjYWxlT3B0cztcclxuXHJcblx0XHRjb3JlX2RhdGFzZXRDb250cm9sbGVyLnByb3RvdHlwZS5pbml0aWFsaXplLmFwcGx5KG1lLCBhcmd1bWVudHMpO1xyXG5cclxuXHRcdG1ldGEgPSBtZS5nZXRNZXRhKCk7XHJcblx0XHRtZXRhLnN0YWNrID0gbWUuZ2V0RGF0YXNldCgpLnN0YWNrO1xyXG5cdFx0bWV0YS5iYXIgPSB0cnVlO1xyXG5cclxuXHRcdHNjYWxlT3B0cyA9IG1lLl9nZXRJbmRleFNjYWxlKCkub3B0aW9ucztcclxuXHRcdGRlcHJlY2F0ZWQoJ2JhciBjaGFydCcsIHNjYWxlT3B0cy5iYXJQZXJjZW50YWdlLCAnc2NhbGVzLlt4L3ldQXhlcy5iYXJQZXJjZW50YWdlJywgJ2RhdGFzZXQuYmFyUGVyY2VudGFnZScpO1xyXG5cdFx0ZGVwcmVjYXRlZCgnYmFyIGNoYXJ0Jywgc2NhbGVPcHRzLmJhclRoaWNrbmVzcywgJ3NjYWxlcy5beC95XUF4ZXMuYmFyVGhpY2tuZXNzJywgJ2RhdGFzZXQuYmFyVGhpY2tuZXNzJyk7XHJcblx0XHRkZXByZWNhdGVkKCdiYXIgY2hhcnQnLCBzY2FsZU9wdHMuY2F0ZWdvcnlQZXJjZW50YWdlLCAnc2NhbGVzLlt4L3ldQXhlcy5jYXRlZ29yeVBlcmNlbnRhZ2UnLCAnZGF0YXNldC5jYXRlZ29yeVBlcmNlbnRhZ2UnKTtcclxuXHRcdGRlcHJlY2F0ZWQoJ2JhciBjaGFydCcsIG1lLl9nZXRWYWx1ZVNjYWxlKCkub3B0aW9ucy5taW5CYXJMZW5ndGgsICdzY2FsZXMuW3gveV1BeGVzLm1pbkJhckxlbmd0aCcsICdkYXRhc2V0Lm1pbkJhckxlbmd0aCcpO1xyXG5cdFx0ZGVwcmVjYXRlZCgnYmFyIGNoYXJ0Jywgc2NhbGVPcHRzLm1heEJhclRoaWNrbmVzcywgJ3NjYWxlcy5beC95XUF4ZXMubWF4QmFyVGhpY2tuZXNzJywgJ2RhdGFzZXQubWF4QmFyVGhpY2tuZXNzJyk7XHJcblx0fSxcclxuXHJcblx0dXBkYXRlOiBmdW5jdGlvbihyZXNldCkge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHRcdHZhciByZWN0cyA9IG1lLmdldE1ldGEoKS5kYXRhO1xyXG5cdFx0dmFyIGksIGlsZW47XHJcblxyXG5cdFx0bWUuX3J1bGVyID0gbWUuZ2V0UnVsZXIoKTtcclxuXHJcblx0XHRmb3IgKGkgPSAwLCBpbGVuID0gcmVjdHMubGVuZ3RoOyBpIDwgaWxlbjsgKytpKSB7XHJcblx0XHRcdG1lLnVwZGF0ZUVsZW1lbnQocmVjdHNbaV0sIGksIHJlc2V0KTtcclxuXHRcdH1cclxuXHR9LFxyXG5cclxuXHR1cGRhdGVFbGVtZW50OiBmdW5jdGlvbihyZWN0YW5nbGUsIGluZGV4LCByZXNldCkge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHRcdHZhciBtZXRhID0gbWUuZ2V0TWV0YSgpO1xyXG5cdFx0dmFyIGRhdGFzZXQgPSBtZS5nZXREYXRhc2V0KCk7XHJcblx0XHR2YXIgb3B0aW9ucyA9IG1lLl9yZXNvbHZlRGF0YUVsZW1lbnRPcHRpb25zKHJlY3RhbmdsZSwgaW5kZXgpO1xyXG5cclxuXHRcdHJlY3RhbmdsZS5feFNjYWxlID0gbWUuZ2V0U2NhbGVGb3JJZChtZXRhLnhBeGlzSUQpO1xyXG5cdFx0cmVjdGFuZ2xlLl95U2NhbGUgPSBtZS5nZXRTY2FsZUZvcklkKG1ldGEueUF4aXNJRCk7XHJcblx0XHRyZWN0YW5nbGUuX2RhdGFzZXRJbmRleCA9IG1lLmluZGV4O1xyXG5cdFx0cmVjdGFuZ2xlLl9pbmRleCA9IGluZGV4O1xyXG5cdFx0cmVjdGFuZ2xlLl9tb2RlbCA9IHtcclxuXHRcdFx0YmFja2dyb3VuZENvbG9yOiBvcHRpb25zLmJhY2tncm91bmRDb2xvcixcclxuXHRcdFx0Ym9yZGVyQ29sb3I6IG9wdGlvbnMuYm9yZGVyQ29sb3IsXHJcblx0XHRcdGJvcmRlclNraXBwZWQ6IG9wdGlvbnMuYm9yZGVyU2tpcHBlZCxcclxuXHRcdFx0Ym9yZGVyV2lkdGg6IG9wdGlvbnMuYm9yZGVyV2lkdGgsXHJcblx0XHRcdGRhdGFzZXRMYWJlbDogZGF0YXNldC5sYWJlbCxcclxuXHRcdFx0bGFiZWw6IG1lLmNoYXJ0LmRhdGEubGFiZWxzW2luZGV4XVxyXG5cdFx0fTtcclxuXHJcblx0XHRpZiAoaGVscGVycyQxLmlzQXJyYXkoZGF0YXNldC5kYXRhW2luZGV4XSkpIHtcclxuXHRcdFx0cmVjdGFuZ2xlLl9tb2RlbC5ib3JkZXJTa2lwcGVkID0gbnVsbDtcclxuXHRcdH1cclxuXHJcblx0XHRtZS5fdXBkYXRlRWxlbWVudEdlb21ldHJ5KHJlY3RhbmdsZSwgaW5kZXgsIHJlc2V0LCBvcHRpb25zKTtcclxuXHJcblx0XHRyZWN0YW5nbGUucGl2b3QoKTtcclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBAcHJpdmF0ZVxyXG5cdCAqL1xyXG5cdF91cGRhdGVFbGVtZW50R2VvbWV0cnk6IGZ1bmN0aW9uKHJlY3RhbmdsZSwgaW5kZXgsIHJlc2V0LCBvcHRpb25zKSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0dmFyIG1vZGVsID0gcmVjdGFuZ2xlLl9tb2RlbDtcclxuXHRcdHZhciB2c2NhbGUgPSBtZS5fZ2V0VmFsdWVTY2FsZSgpO1xyXG5cdFx0dmFyIGJhc2UgPSB2c2NhbGUuZ2V0QmFzZVBpeGVsKCk7XHJcblx0XHR2YXIgaG9yaXpvbnRhbCA9IHZzY2FsZS5pc0hvcml6b250YWwoKTtcclxuXHRcdHZhciBydWxlciA9IG1lLl9ydWxlciB8fCBtZS5nZXRSdWxlcigpO1xyXG5cdFx0dmFyIHZwaXhlbHMgPSBtZS5jYWxjdWxhdGVCYXJWYWx1ZVBpeGVscyhtZS5pbmRleCwgaW5kZXgsIG9wdGlvbnMpO1xyXG5cdFx0dmFyIGlwaXhlbHMgPSBtZS5jYWxjdWxhdGVCYXJJbmRleFBpeGVscyhtZS5pbmRleCwgaW5kZXgsIHJ1bGVyLCBvcHRpb25zKTtcclxuXHJcblx0XHRtb2RlbC5ob3Jpem9udGFsID0gaG9yaXpvbnRhbDtcclxuXHRcdG1vZGVsLmJhc2UgPSByZXNldCA/IGJhc2UgOiB2cGl4ZWxzLmJhc2U7XHJcblx0XHRtb2RlbC54ID0gaG9yaXpvbnRhbCA/IHJlc2V0ID8gYmFzZSA6IHZwaXhlbHMuaGVhZCA6IGlwaXhlbHMuY2VudGVyO1xyXG5cdFx0bW9kZWwueSA9IGhvcml6b250YWwgPyBpcGl4ZWxzLmNlbnRlciA6IHJlc2V0ID8gYmFzZSA6IHZwaXhlbHMuaGVhZDtcclxuXHRcdG1vZGVsLmhlaWdodCA9IGhvcml6b250YWwgPyBpcGl4ZWxzLnNpemUgOiB1bmRlZmluZWQ7XHJcblx0XHRtb2RlbC53aWR0aCA9IGhvcml6b250YWwgPyB1bmRlZmluZWQgOiBpcGl4ZWxzLnNpemU7XHJcblx0fSxcclxuXHJcblx0LyoqXHJcblx0ICogUmV0dXJucyB0aGUgc3RhY2tzIGJhc2VkIG9uIGdyb3VwcyBhbmQgYmFyIHZpc2liaWxpdHkuXHJcblx0ICogQHBhcmFtIHtudW1iZXJ9IFtsYXN0XSAtIFRoZSBkYXRhc2V0IGluZGV4XHJcblx0ICogQHJldHVybnMge3N0cmluZ1tdfSBUaGUgbGlzdCBvZiBzdGFjayBJRHNcclxuXHQgKiBAcHJpdmF0ZVxyXG5cdCAqL1xyXG5cdF9nZXRTdGFja3M6IGZ1bmN0aW9uKGxhc3QpIHtcclxuXHRcdHZhciBtZSA9IHRoaXM7XHJcblx0XHR2YXIgc2NhbGUgPSBtZS5fZ2V0SW5kZXhTY2FsZSgpO1xyXG5cdFx0dmFyIG1ldGFzZXRzID0gc2NhbGUuX2dldE1hdGNoaW5nVmlzaWJsZU1ldGFzKG1lLl90eXBlKTtcclxuXHRcdHZhciBzdGFja2VkID0gc2NhbGUub3B0aW9ucy5zdGFja2VkO1xyXG5cdFx0dmFyIGlsZW4gPSBtZXRhc2V0cy5sZW5ndGg7XHJcblx0XHR2YXIgc3RhY2tzID0gW107XHJcblx0XHR2YXIgaSwgbWV0YTtcclxuXHJcblx0XHRmb3IgKGkgPSAwOyBpIDwgaWxlbjsgKytpKSB7XHJcblx0XHRcdG1ldGEgPSBtZXRhc2V0c1tpXTtcclxuXHRcdFx0Ly8gc3RhY2tlZCAgIHwgbWV0YS5zdGFja1xyXG5cdFx0XHQvLyAgICAgICAgICAgfCBmb3VuZCB8IG5vdCBmb3VuZCB8IHVuZGVmaW5lZFxyXG5cdFx0XHQvLyBmYWxzZSAgICAgfCAgIHggICB8ICAgICB4ICAgICB8ICAgICB4XHJcblx0XHRcdC8vIHRydWUgICAgICB8ICAgICAgIHwgICAgIHggICAgIHxcclxuXHRcdFx0Ly8gdW5kZWZpbmVkIHwgICAgICAgfCAgICAgeCAgICAgfCAgICAgeFxyXG5cdFx0XHRpZiAoc3RhY2tlZCA9PT0gZmFsc2UgfHwgc3RhY2tzLmluZGV4T2YobWV0YS5zdGFjaykgPT09IC0xIHx8XHJcblx0XHRcdFx0KHN0YWNrZWQgPT09IHVuZGVmaW5lZCAmJiBtZXRhLnN0YWNrID09PSB1bmRlZmluZWQpKSB7XHJcblx0XHRcdFx0c3RhY2tzLnB1c2gobWV0YS5zdGFjayk7XHJcblx0XHRcdH1cclxuXHRcdFx0aWYgKG1ldGEuaW5kZXggPT09IGxhc3QpIHtcclxuXHRcdFx0XHRicmVhaztcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiBzdGFja3M7XHJcblx0fSxcclxuXHJcblx0LyoqXHJcblx0ICogUmV0dXJucyB0aGUgZWZmZWN0aXZlIG51bWJlciBvZiBzdGFja3MgYmFzZWQgb24gZ3JvdXBzIGFuZCBiYXIgdmlzaWJpbGl0eS5cclxuXHQgKiBAcHJpdmF0ZVxyXG5cdCAqL1xyXG5cdGdldFN0YWNrQ291bnQ6IGZ1bmN0aW9uKCkge1xyXG5cdFx0cmV0dXJuIHRoaXMuX2dldFN0YWNrcygpLmxlbmd0aDtcclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBSZXR1cm5zIHRoZSBzdGFjayBpbmRleCBmb3IgdGhlIGdpdmVuIGRhdGFzZXQgYmFzZWQgb24gZ3JvdXBzIGFuZCBiYXIgdmlzaWJpbGl0eS5cclxuXHQgKiBAcGFyYW0ge251bWJlcn0gW2RhdGFzZXRJbmRleF0gLSBUaGUgZGF0YXNldCBpbmRleFxyXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBbbmFtZV0gLSBUaGUgc3RhY2sgbmFtZSB0byBmaW5kXHJcblx0ICogQHJldHVybnMge251bWJlcn0gVGhlIHN0YWNrIGluZGV4XHJcblx0ICogQHByaXZhdGVcclxuXHQgKi9cclxuXHRnZXRTdGFja0luZGV4OiBmdW5jdGlvbihkYXRhc2V0SW5kZXgsIG5hbWUpIHtcclxuXHRcdHZhciBzdGFja3MgPSB0aGlzLl9nZXRTdGFja3MoZGF0YXNldEluZGV4KTtcclxuXHRcdHZhciBpbmRleCA9IChuYW1lICE9PSB1bmRlZmluZWQpXHJcblx0XHRcdD8gc3RhY2tzLmluZGV4T2YobmFtZSlcclxuXHRcdFx0OiAtMTsgLy8gaW5kZXhPZiByZXR1cm5zIC0xIGlmIGVsZW1lbnQgaXMgbm90IHByZXNlbnRcclxuXHJcblx0XHRyZXR1cm4gKGluZGV4ID09PSAtMSlcclxuXHRcdFx0PyBzdGFja3MubGVuZ3RoIC0gMVxyXG5cdFx0XHQ6IGluZGV4O1xyXG5cdH0sXHJcblxyXG5cdC8qKlxyXG5cdCAqIEBwcml2YXRlXHJcblx0ICovXHJcblx0Z2V0UnVsZXI6IGZ1bmN0aW9uKCkge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHRcdHZhciBzY2FsZSA9IG1lLl9nZXRJbmRleFNjYWxlKCk7XHJcblx0XHR2YXIgcGl4ZWxzID0gW107XHJcblx0XHR2YXIgaSwgaWxlbjtcclxuXHJcblx0XHRmb3IgKGkgPSAwLCBpbGVuID0gbWUuZ2V0TWV0YSgpLmRhdGEubGVuZ3RoOyBpIDwgaWxlbjsgKytpKSB7XHJcblx0XHRcdHBpeGVscy5wdXNoKHNjYWxlLmdldFBpeGVsRm9yVmFsdWUobnVsbCwgaSwgbWUuaW5kZXgpKTtcclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4ge1xyXG5cdFx0XHRwaXhlbHM6IHBpeGVscyxcclxuXHRcdFx0c3RhcnQ6IHNjYWxlLl9zdGFydFBpeGVsLFxyXG5cdFx0XHRlbmQ6IHNjYWxlLl9lbmRQaXhlbCxcclxuXHRcdFx0c3RhY2tDb3VudDogbWUuZ2V0U3RhY2tDb3VudCgpLFxyXG5cdFx0XHRzY2FsZTogc2NhbGVcclxuXHRcdH07XHJcblx0fSxcclxuXHJcblx0LyoqXHJcblx0ICogTm90ZTogcGl4ZWwgdmFsdWVzIGFyZSBub3QgY2xhbXBlZCB0byB0aGUgc2NhbGUgYXJlYS5cclxuXHQgKiBAcHJpdmF0ZVxyXG5cdCAqL1xyXG5cdGNhbGN1bGF0ZUJhclZhbHVlUGl4ZWxzOiBmdW5jdGlvbihkYXRhc2V0SW5kZXgsIGluZGV4LCBvcHRpb25zKSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0dmFyIGNoYXJ0ID0gbWUuY2hhcnQ7XHJcblx0XHR2YXIgc2NhbGUgPSBtZS5fZ2V0VmFsdWVTY2FsZSgpO1xyXG5cdFx0dmFyIGlzSG9yaXpvbnRhbCA9IHNjYWxlLmlzSG9yaXpvbnRhbCgpO1xyXG5cdFx0dmFyIGRhdGFzZXRzID0gY2hhcnQuZGF0YS5kYXRhc2V0cztcclxuXHRcdHZhciBtZXRhc2V0cyA9IHNjYWxlLl9nZXRNYXRjaGluZ1Zpc2libGVNZXRhcyhtZS5fdHlwZSk7XHJcblx0XHR2YXIgdmFsdWUgPSBzY2FsZS5fcGFyc2VWYWx1ZShkYXRhc2V0c1tkYXRhc2V0SW5kZXhdLmRhdGFbaW5kZXhdKTtcclxuXHRcdHZhciBtaW5CYXJMZW5ndGggPSBvcHRpb25zLm1pbkJhckxlbmd0aDtcclxuXHRcdHZhciBzdGFja2VkID0gc2NhbGUub3B0aW9ucy5zdGFja2VkO1xyXG5cdFx0dmFyIHN0YWNrID0gbWUuZ2V0TWV0YSgpLnN0YWNrO1xyXG5cdFx0dmFyIHN0YXJ0ID0gdmFsdWUuc3RhcnQgPT09IHVuZGVmaW5lZCA/IDAgOiB2YWx1ZS5tYXggPj0gMCAmJiB2YWx1ZS5taW4gPj0gMCA/IHZhbHVlLm1pbiA6IHZhbHVlLm1heDtcclxuXHRcdHZhciBsZW5ndGggPSB2YWx1ZS5zdGFydCA9PT0gdW5kZWZpbmVkID8gdmFsdWUuZW5kIDogdmFsdWUubWF4ID49IDAgJiYgdmFsdWUubWluID49IDAgPyB2YWx1ZS5tYXggLSB2YWx1ZS5taW4gOiB2YWx1ZS5taW4gLSB2YWx1ZS5tYXg7XHJcblx0XHR2YXIgaWxlbiA9IG1ldGFzZXRzLmxlbmd0aDtcclxuXHRcdHZhciBpLCBpbWV0YSwgaXZhbHVlLCBiYXNlLCBoZWFkLCBzaXplLCBzdGFja0xlbmd0aDtcclxuXHJcblx0XHRpZiAoc3RhY2tlZCB8fCAoc3RhY2tlZCA9PT0gdW5kZWZpbmVkICYmIHN0YWNrICE9PSB1bmRlZmluZWQpKSB7XHJcblx0XHRcdGZvciAoaSA9IDA7IGkgPCBpbGVuOyArK2kpIHtcclxuXHRcdFx0XHRpbWV0YSA9IG1ldGFzZXRzW2ldO1xyXG5cclxuXHRcdFx0XHRpZiAoaW1ldGEuaW5kZXggPT09IGRhdGFzZXRJbmRleCkge1xyXG5cdFx0XHRcdFx0YnJlYWs7XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRpZiAoaW1ldGEuc3RhY2sgPT09IHN0YWNrKSB7XHJcblx0XHRcdFx0XHRzdGFja0xlbmd0aCA9IHNjYWxlLl9wYXJzZVZhbHVlKGRhdGFzZXRzW2ltZXRhLmluZGV4XS5kYXRhW2luZGV4XSk7XHJcblx0XHRcdFx0XHRpdmFsdWUgPSBzdGFja0xlbmd0aC5zdGFydCA9PT0gdW5kZWZpbmVkID8gc3RhY2tMZW5ndGguZW5kIDogc3RhY2tMZW5ndGgubWluID49IDAgJiYgc3RhY2tMZW5ndGgubWF4ID49IDAgPyBzdGFja0xlbmd0aC5tYXggOiBzdGFja0xlbmd0aC5taW47XHJcblxyXG5cdFx0XHRcdFx0aWYgKCh2YWx1ZS5taW4gPCAwICYmIGl2YWx1ZSA8IDApIHx8ICh2YWx1ZS5tYXggPj0gMCAmJiBpdmFsdWUgPiAwKSkge1xyXG5cdFx0XHRcdFx0XHRzdGFydCArPSBpdmFsdWU7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0YmFzZSA9IHNjYWxlLmdldFBpeGVsRm9yVmFsdWUoc3RhcnQpO1xyXG5cdFx0aGVhZCA9IHNjYWxlLmdldFBpeGVsRm9yVmFsdWUoc3RhcnQgKyBsZW5ndGgpO1xyXG5cdFx0c2l6ZSA9IGhlYWQgLSBiYXNlO1xyXG5cclxuXHRcdGlmIChtaW5CYXJMZW5ndGggIT09IHVuZGVmaW5lZCAmJiBNYXRoLmFicyhzaXplKSA8IG1pbkJhckxlbmd0aCkge1xyXG5cdFx0XHRzaXplID0gbWluQmFyTGVuZ3RoO1xyXG5cdFx0XHRpZiAobGVuZ3RoID49IDAgJiYgIWlzSG9yaXpvbnRhbCB8fCBsZW5ndGggPCAwICYmIGlzSG9yaXpvbnRhbCkge1xyXG5cdFx0XHRcdGhlYWQgPSBiYXNlIC0gbWluQmFyTGVuZ3RoO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdGhlYWQgPSBiYXNlICsgbWluQmFyTGVuZ3RoO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIHtcclxuXHRcdFx0c2l6ZTogc2l6ZSxcclxuXHRcdFx0YmFzZTogYmFzZSxcclxuXHRcdFx0aGVhZDogaGVhZCxcclxuXHRcdFx0Y2VudGVyOiBoZWFkICsgc2l6ZSAvIDJcclxuXHRcdH07XHJcblx0fSxcclxuXHJcblx0LyoqXHJcblx0ICogQHByaXZhdGVcclxuXHQgKi9cclxuXHRjYWxjdWxhdGVCYXJJbmRleFBpeGVsczogZnVuY3Rpb24oZGF0YXNldEluZGV4LCBpbmRleCwgcnVsZXIsIG9wdGlvbnMpIHtcclxuXHRcdHZhciBtZSA9IHRoaXM7XHJcblx0XHR2YXIgcmFuZ2UgPSBvcHRpb25zLmJhclRoaWNrbmVzcyA9PT0gJ2ZsZXgnXHJcblx0XHRcdD8gY29tcHV0ZUZsZXhDYXRlZ29yeVRyYWl0cyhpbmRleCwgcnVsZXIsIG9wdGlvbnMpXHJcblx0XHRcdDogY29tcHV0ZUZpdENhdGVnb3J5VHJhaXRzKGluZGV4LCBydWxlciwgb3B0aW9ucyk7XHJcblxyXG5cdFx0dmFyIHN0YWNrSW5kZXggPSBtZS5nZXRTdGFja0luZGV4KGRhdGFzZXRJbmRleCwgbWUuZ2V0TWV0YSgpLnN0YWNrKTtcclxuXHRcdHZhciBjZW50ZXIgPSByYW5nZS5zdGFydCArIChyYW5nZS5jaHVuayAqIHN0YWNrSW5kZXgpICsgKHJhbmdlLmNodW5rIC8gMik7XHJcblx0XHR2YXIgc2l6ZSA9IE1hdGgubWluKFxyXG5cdFx0XHR2YWx1ZU9yRGVmYXVsdCQzKG9wdGlvbnMubWF4QmFyVGhpY2tuZXNzLCBJbmZpbml0eSksXHJcblx0XHRcdHJhbmdlLmNodW5rICogcmFuZ2UucmF0aW8pO1xyXG5cclxuXHRcdHJldHVybiB7XHJcblx0XHRcdGJhc2U6IGNlbnRlciAtIHNpemUgLyAyLFxyXG5cdFx0XHRoZWFkOiBjZW50ZXIgKyBzaXplIC8gMixcclxuXHRcdFx0Y2VudGVyOiBjZW50ZXIsXHJcblx0XHRcdHNpemU6IHNpemVcclxuXHRcdH07XHJcblx0fSxcclxuXHJcblx0ZHJhdzogZnVuY3Rpb24oKSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0dmFyIGNoYXJ0ID0gbWUuY2hhcnQ7XHJcblx0XHR2YXIgc2NhbGUgPSBtZS5fZ2V0VmFsdWVTY2FsZSgpO1xyXG5cdFx0dmFyIHJlY3RzID0gbWUuZ2V0TWV0YSgpLmRhdGE7XHJcblx0XHR2YXIgZGF0YXNldCA9IG1lLmdldERhdGFzZXQoKTtcclxuXHRcdHZhciBpbGVuID0gcmVjdHMubGVuZ3RoO1xyXG5cdFx0dmFyIGkgPSAwO1xyXG5cclxuXHRcdGhlbHBlcnMkMS5jYW52YXMuY2xpcEFyZWEoY2hhcnQuY3R4LCBjaGFydC5jaGFydEFyZWEpO1xyXG5cclxuXHRcdGZvciAoOyBpIDwgaWxlbjsgKytpKSB7XHJcblx0XHRcdHZhciB2YWwgPSBzY2FsZS5fcGFyc2VWYWx1ZShkYXRhc2V0LmRhdGFbaV0pO1xyXG5cdFx0XHRpZiAoIWlzTmFOKHZhbC5taW4pICYmICFpc05hTih2YWwubWF4KSkge1xyXG5cdFx0XHRcdHJlY3RzW2ldLmRyYXcoKTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdGhlbHBlcnMkMS5jYW52YXMudW5jbGlwQXJlYShjaGFydC5jdHgpO1xyXG5cdH0sXHJcblxyXG5cdC8qKlxyXG5cdCAqIEBwcml2YXRlXHJcblx0ICovXHJcblx0X3Jlc29sdmVEYXRhRWxlbWVudE9wdGlvbnM6IGZ1bmN0aW9uKCkge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHRcdHZhciB2YWx1ZXMgPSBoZWxwZXJzJDEuZXh0ZW5kKHt9LCBjb3JlX2RhdGFzZXRDb250cm9sbGVyLnByb3RvdHlwZS5fcmVzb2x2ZURhdGFFbGVtZW50T3B0aW9ucy5hcHBseShtZSwgYXJndW1lbnRzKSk7XHJcblx0XHR2YXIgaW5kZXhPcHRzID0gbWUuX2dldEluZGV4U2NhbGUoKS5vcHRpb25zO1xyXG5cdFx0dmFyIHZhbHVlT3B0cyA9IG1lLl9nZXRWYWx1ZVNjYWxlKCkub3B0aW9ucztcclxuXHJcblx0XHR2YWx1ZXMuYmFyUGVyY2VudGFnZSA9IHZhbHVlT3JEZWZhdWx0JDMoaW5kZXhPcHRzLmJhclBlcmNlbnRhZ2UsIHZhbHVlcy5iYXJQZXJjZW50YWdlKTtcclxuXHRcdHZhbHVlcy5iYXJUaGlja25lc3MgPSB2YWx1ZU9yRGVmYXVsdCQzKGluZGV4T3B0cy5iYXJUaGlja25lc3MsIHZhbHVlcy5iYXJUaGlja25lc3MpO1xyXG5cdFx0dmFsdWVzLmNhdGVnb3J5UGVyY2VudGFnZSA9IHZhbHVlT3JEZWZhdWx0JDMoaW5kZXhPcHRzLmNhdGVnb3J5UGVyY2VudGFnZSwgdmFsdWVzLmNhdGVnb3J5UGVyY2VudGFnZSk7XHJcblx0XHR2YWx1ZXMubWF4QmFyVGhpY2tuZXNzID0gdmFsdWVPckRlZmF1bHQkMyhpbmRleE9wdHMubWF4QmFyVGhpY2tuZXNzLCB2YWx1ZXMubWF4QmFyVGhpY2tuZXNzKTtcclxuXHRcdHZhbHVlcy5taW5CYXJMZW5ndGggPSB2YWx1ZU9yRGVmYXVsdCQzKHZhbHVlT3B0cy5taW5CYXJMZW5ndGgsIHZhbHVlcy5taW5CYXJMZW5ndGgpO1xyXG5cclxuXHRcdHJldHVybiB2YWx1ZXM7XHJcblx0fVxyXG5cclxufSk7XG5cbnZhciB2YWx1ZU9yRGVmYXVsdCQ0ID0gaGVscGVycyQxLnZhbHVlT3JEZWZhdWx0O1xyXG52YXIgcmVzb2x2ZSQxID0gaGVscGVycyQxLm9wdGlvbnMucmVzb2x2ZTtcclxuXHJcbmNvcmVfZGVmYXVsdHMuX3NldCgnYnViYmxlJywge1xyXG5cdGhvdmVyOiB7XHJcblx0XHRtb2RlOiAnc2luZ2xlJ1xyXG5cdH0sXHJcblxyXG5cdHNjYWxlczoge1xyXG5cdFx0eEF4ZXM6IFt7XHJcblx0XHRcdHR5cGU6ICdsaW5lYXInLCAvLyBidWJibGUgc2hvdWxkIHByb2JhYmx5IHVzZSBhIGxpbmVhciBzY2FsZSBieSBkZWZhdWx0XHJcblx0XHRcdHBvc2l0aW9uOiAnYm90dG9tJyxcclxuXHRcdFx0aWQ6ICd4LWF4aXMtMCcgLy8gbmVlZCBhbiBJRCBzbyBkYXRhc2V0cyBjYW4gcmVmZXJlbmNlIHRoZSBzY2FsZVxyXG5cdFx0fV0sXHJcblx0XHR5QXhlczogW3tcclxuXHRcdFx0dHlwZTogJ2xpbmVhcicsXHJcblx0XHRcdHBvc2l0aW9uOiAnbGVmdCcsXHJcblx0XHRcdGlkOiAneS1heGlzLTAnXHJcblx0XHR9XVxyXG5cdH0sXHJcblxyXG5cdHRvb2x0aXBzOiB7XHJcblx0XHRjYWxsYmFja3M6IHtcclxuXHRcdFx0dGl0bGU6IGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdC8vIFRpdGxlIGRvZXNuJ3QgbWFrZSBzZW5zZSBmb3Igc2NhdHRlciBzaW5jZSB3ZSBmb3JtYXQgdGhlIGRhdGEgYXMgYSBwb2ludFxyXG5cdFx0XHRcdHJldHVybiAnJztcclxuXHRcdFx0fSxcclxuXHRcdFx0bGFiZWw6IGZ1bmN0aW9uKGl0ZW0sIGRhdGEpIHtcclxuXHRcdFx0XHR2YXIgZGF0YXNldExhYmVsID0gZGF0YS5kYXRhc2V0c1tpdGVtLmRhdGFzZXRJbmRleF0ubGFiZWwgfHwgJyc7XHJcblx0XHRcdFx0dmFyIGRhdGFQb2ludCA9IGRhdGEuZGF0YXNldHNbaXRlbS5kYXRhc2V0SW5kZXhdLmRhdGFbaXRlbS5pbmRleF07XHJcblx0XHRcdFx0cmV0dXJuIGRhdGFzZXRMYWJlbCArICc6ICgnICsgaXRlbS54TGFiZWwgKyAnLCAnICsgaXRlbS55TGFiZWwgKyAnLCAnICsgZGF0YVBvaW50LnIgKyAnKSc7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHR9XHJcbn0pO1xyXG5cclxudmFyIGNvbnRyb2xsZXJfYnViYmxlID0gY29yZV9kYXRhc2V0Q29udHJvbGxlci5leHRlbmQoe1xyXG5cdC8qKlxyXG5cdCAqIEBwcm90ZWN0ZWRcclxuXHQgKi9cclxuXHRkYXRhRWxlbWVudFR5cGU6IGVsZW1lbnRzLlBvaW50LFxyXG5cclxuXHQvKipcclxuXHQgKiBAcHJpdmF0ZVxyXG5cdCAqL1xyXG5cdF9kYXRhRWxlbWVudE9wdGlvbnM6IFtcclxuXHRcdCdiYWNrZ3JvdW5kQ29sb3InLFxyXG5cdFx0J2JvcmRlckNvbG9yJyxcclxuXHRcdCdib3JkZXJXaWR0aCcsXHJcblx0XHQnaG92ZXJCYWNrZ3JvdW5kQ29sb3InLFxyXG5cdFx0J2hvdmVyQm9yZGVyQ29sb3InLFxyXG5cdFx0J2hvdmVyQm9yZGVyV2lkdGgnLFxyXG5cdFx0J2hvdmVyUmFkaXVzJyxcclxuXHRcdCdoaXRSYWRpdXMnLFxyXG5cdFx0J3BvaW50U3R5bGUnLFxyXG5cdFx0J3JvdGF0aW9uJ1xyXG5cdF0sXHJcblxyXG5cdC8qKlxyXG5cdCAqIEBwcm90ZWN0ZWRcclxuXHQgKi9cclxuXHR1cGRhdGU6IGZ1bmN0aW9uKHJlc2V0KSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0dmFyIG1ldGEgPSBtZS5nZXRNZXRhKCk7XHJcblx0XHR2YXIgcG9pbnRzID0gbWV0YS5kYXRhO1xyXG5cclxuXHRcdC8vIFVwZGF0ZSBQb2ludHNcclxuXHRcdGhlbHBlcnMkMS5lYWNoKHBvaW50cywgZnVuY3Rpb24ocG9pbnQsIGluZGV4KSB7XHJcblx0XHRcdG1lLnVwZGF0ZUVsZW1lbnQocG9pbnQsIGluZGV4LCByZXNldCk7XHJcblx0XHR9KTtcclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBAcHJvdGVjdGVkXHJcblx0ICovXHJcblx0dXBkYXRlRWxlbWVudDogZnVuY3Rpb24ocG9pbnQsIGluZGV4LCByZXNldCkge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHRcdHZhciBtZXRhID0gbWUuZ2V0TWV0YSgpO1xyXG5cdFx0dmFyIGN1c3RvbSA9IHBvaW50LmN1c3RvbSB8fCB7fTtcclxuXHRcdHZhciB4U2NhbGUgPSBtZS5nZXRTY2FsZUZvcklkKG1ldGEueEF4aXNJRCk7XHJcblx0XHR2YXIgeVNjYWxlID0gbWUuZ2V0U2NhbGVGb3JJZChtZXRhLnlBeGlzSUQpO1xyXG5cdFx0dmFyIG9wdGlvbnMgPSBtZS5fcmVzb2x2ZURhdGFFbGVtZW50T3B0aW9ucyhwb2ludCwgaW5kZXgpO1xyXG5cdFx0dmFyIGRhdGEgPSBtZS5nZXREYXRhc2V0KCkuZGF0YVtpbmRleF07XHJcblx0XHR2YXIgZHNJbmRleCA9IG1lLmluZGV4O1xyXG5cclxuXHRcdHZhciB4ID0gcmVzZXQgPyB4U2NhbGUuZ2V0UGl4ZWxGb3JEZWNpbWFsKDAuNSkgOiB4U2NhbGUuZ2V0UGl4ZWxGb3JWYWx1ZSh0eXBlb2YgZGF0YSA9PT0gJ29iamVjdCcgPyBkYXRhIDogTmFOLCBpbmRleCwgZHNJbmRleCk7XHJcblx0XHR2YXIgeSA9IHJlc2V0ID8geVNjYWxlLmdldEJhc2VQaXhlbCgpIDogeVNjYWxlLmdldFBpeGVsRm9yVmFsdWUoZGF0YSwgaW5kZXgsIGRzSW5kZXgpO1xyXG5cclxuXHRcdHBvaW50Ll94U2NhbGUgPSB4U2NhbGU7XHJcblx0XHRwb2ludC5feVNjYWxlID0geVNjYWxlO1xyXG5cdFx0cG9pbnQuX29wdGlvbnMgPSBvcHRpb25zO1xyXG5cdFx0cG9pbnQuX2RhdGFzZXRJbmRleCA9IGRzSW5kZXg7XHJcblx0XHRwb2ludC5faW5kZXggPSBpbmRleDtcclxuXHRcdHBvaW50Ll9tb2RlbCA9IHtcclxuXHRcdFx0YmFja2dyb3VuZENvbG9yOiBvcHRpb25zLmJhY2tncm91bmRDb2xvcixcclxuXHRcdFx0Ym9yZGVyQ29sb3I6IG9wdGlvbnMuYm9yZGVyQ29sb3IsXHJcblx0XHRcdGJvcmRlcldpZHRoOiBvcHRpb25zLmJvcmRlcldpZHRoLFxyXG5cdFx0XHRoaXRSYWRpdXM6IG9wdGlvbnMuaGl0UmFkaXVzLFxyXG5cdFx0XHRwb2ludFN0eWxlOiBvcHRpb25zLnBvaW50U3R5bGUsXHJcblx0XHRcdHJvdGF0aW9uOiBvcHRpb25zLnJvdGF0aW9uLFxyXG5cdFx0XHRyYWRpdXM6IHJlc2V0ID8gMCA6IG9wdGlvbnMucmFkaXVzLFxyXG5cdFx0XHRza2lwOiBjdXN0b20uc2tpcCB8fCBpc05hTih4KSB8fCBpc05hTih5KSxcclxuXHRcdFx0eDogeCxcclxuXHRcdFx0eTogeSxcclxuXHRcdH07XHJcblxyXG5cdFx0cG9pbnQucGl2b3QoKTtcclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBAcHJvdGVjdGVkXHJcblx0ICovXHJcblx0c2V0SG92ZXJTdHlsZTogZnVuY3Rpb24ocG9pbnQpIHtcclxuXHRcdHZhciBtb2RlbCA9IHBvaW50Ll9tb2RlbDtcclxuXHRcdHZhciBvcHRpb25zID0gcG9pbnQuX29wdGlvbnM7XHJcblx0XHR2YXIgZ2V0SG92ZXJDb2xvciA9IGhlbHBlcnMkMS5nZXRIb3ZlckNvbG9yO1xyXG5cclxuXHRcdHBvaW50LiRwcmV2aW91c1N0eWxlID0ge1xyXG5cdFx0XHRiYWNrZ3JvdW5kQ29sb3I6IG1vZGVsLmJhY2tncm91bmRDb2xvcixcclxuXHRcdFx0Ym9yZGVyQ29sb3I6IG1vZGVsLmJvcmRlckNvbG9yLFxyXG5cdFx0XHRib3JkZXJXaWR0aDogbW9kZWwuYm9yZGVyV2lkdGgsXHJcblx0XHRcdHJhZGl1czogbW9kZWwucmFkaXVzXHJcblx0XHR9O1xyXG5cclxuXHRcdG1vZGVsLmJhY2tncm91bmRDb2xvciA9IHZhbHVlT3JEZWZhdWx0JDQob3B0aW9ucy5ob3ZlckJhY2tncm91bmRDb2xvciwgZ2V0SG92ZXJDb2xvcihvcHRpb25zLmJhY2tncm91bmRDb2xvcikpO1xyXG5cdFx0bW9kZWwuYm9yZGVyQ29sb3IgPSB2YWx1ZU9yRGVmYXVsdCQ0KG9wdGlvbnMuaG92ZXJCb3JkZXJDb2xvciwgZ2V0SG92ZXJDb2xvcihvcHRpb25zLmJvcmRlckNvbG9yKSk7XHJcblx0XHRtb2RlbC5ib3JkZXJXaWR0aCA9IHZhbHVlT3JEZWZhdWx0JDQob3B0aW9ucy5ob3ZlckJvcmRlcldpZHRoLCBvcHRpb25zLmJvcmRlcldpZHRoKTtcclxuXHRcdG1vZGVsLnJhZGl1cyA9IG9wdGlvbnMucmFkaXVzICsgb3B0aW9ucy5ob3ZlclJhZGl1cztcclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBAcHJpdmF0ZVxyXG5cdCAqL1xyXG5cdF9yZXNvbHZlRGF0YUVsZW1lbnRPcHRpb25zOiBmdW5jdGlvbihwb2ludCwgaW5kZXgpIHtcclxuXHRcdHZhciBtZSA9IHRoaXM7XHJcblx0XHR2YXIgY2hhcnQgPSBtZS5jaGFydDtcclxuXHRcdHZhciBkYXRhc2V0ID0gbWUuZ2V0RGF0YXNldCgpO1xyXG5cdFx0dmFyIGN1c3RvbSA9IHBvaW50LmN1c3RvbSB8fCB7fTtcclxuXHRcdHZhciBkYXRhID0gZGF0YXNldC5kYXRhW2luZGV4XSB8fCB7fTtcclxuXHRcdHZhciB2YWx1ZXMgPSBjb3JlX2RhdGFzZXRDb250cm9sbGVyLnByb3RvdHlwZS5fcmVzb2x2ZURhdGFFbGVtZW50T3B0aW9ucy5hcHBseShtZSwgYXJndW1lbnRzKTtcclxuXHJcblx0XHQvLyBTY3JpcHRhYmxlIG9wdGlvbnNcclxuXHRcdHZhciBjb250ZXh0ID0ge1xyXG5cdFx0XHRjaGFydDogY2hhcnQsXHJcblx0XHRcdGRhdGFJbmRleDogaW5kZXgsXHJcblx0XHRcdGRhdGFzZXQ6IGRhdGFzZXQsXHJcblx0XHRcdGRhdGFzZXRJbmRleDogbWUuaW5kZXhcclxuXHRcdH07XHJcblxyXG5cdFx0Ly8gSW4gY2FzZSB2YWx1ZXMgd2VyZSBjYWNoZWQgKGFuZCB0aHVzIGZyb3plbiksIHdlIG5lZWQgdG8gY2xvbmUgdGhlIHZhbHVlc1xyXG5cdFx0aWYgKG1lLl9jYWNoZWREYXRhT3B0cyA9PT0gdmFsdWVzKSB7XHJcblx0XHRcdHZhbHVlcyA9IGhlbHBlcnMkMS5leHRlbmQoe30sIHZhbHVlcyk7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gQ3VzdG9tIHJhZGl1cyByZXNvbHV0aW9uXHJcblx0XHR2YWx1ZXMucmFkaXVzID0gcmVzb2x2ZSQxKFtcclxuXHRcdFx0Y3VzdG9tLnJhZGl1cyxcclxuXHRcdFx0ZGF0YS5yLFxyXG5cdFx0XHRtZS5fY29uZmlnLnJhZGl1cyxcclxuXHRcdFx0Y2hhcnQub3B0aW9ucy5lbGVtZW50cy5wb2ludC5yYWRpdXNcclxuXHRcdF0sIGNvbnRleHQsIGluZGV4KTtcclxuXHJcblx0XHRyZXR1cm4gdmFsdWVzO1xyXG5cdH1cclxufSk7XG5cbnZhciB2YWx1ZU9yRGVmYXVsdCQ1ID0gaGVscGVycyQxLnZhbHVlT3JEZWZhdWx0O1xyXG5cclxudmFyIFBJJDEgPSBNYXRoLlBJO1xyXG52YXIgRE9VQkxFX1BJJDEgPSBQSSQxICogMjtcclxudmFyIEhBTEZfUEkkMSA9IFBJJDEgLyAyO1xyXG5cclxuY29yZV9kZWZhdWx0cy5fc2V0KCdkb3VnaG51dCcsIHtcclxuXHRhbmltYXRpb246IHtcclxuXHRcdC8vIEJvb2xlYW4gLSBXaGV0aGVyIHdlIGFuaW1hdGUgdGhlIHJvdGF0aW9uIG9mIHRoZSBEb3VnaG51dFxyXG5cdFx0YW5pbWF0ZVJvdGF0ZTogdHJ1ZSxcclxuXHRcdC8vIEJvb2xlYW4gLSBXaGV0aGVyIHdlIGFuaW1hdGUgc2NhbGluZyB0aGUgRG91Z2hudXQgZnJvbSB0aGUgY2VudHJlXHJcblx0XHRhbmltYXRlU2NhbGU6IGZhbHNlXHJcblx0fSxcclxuXHRob3Zlcjoge1xyXG5cdFx0bW9kZTogJ3NpbmdsZSdcclxuXHR9LFxyXG5cdGxlZ2VuZENhbGxiYWNrOiBmdW5jdGlvbihjaGFydCkge1xyXG5cdFx0dmFyIGxpc3QgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd1bCcpO1xyXG5cdFx0dmFyIGRhdGEgPSBjaGFydC5kYXRhO1xyXG5cdFx0dmFyIGRhdGFzZXRzID0gZGF0YS5kYXRhc2V0cztcclxuXHRcdHZhciBsYWJlbHMgPSBkYXRhLmxhYmVscztcclxuXHRcdHZhciBpLCBpbGVuLCBsaXN0SXRlbSwgbGlzdEl0ZW1TcGFuO1xyXG5cclxuXHRcdGxpc3Quc2V0QXR0cmlidXRlKCdjbGFzcycsIGNoYXJ0LmlkICsgJy1sZWdlbmQnKTtcclxuXHRcdGlmIChkYXRhc2V0cy5sZW5ndGgpIHtcclxuXHRcdFx0Zm9yIChpID0gMCwgaWxlbiA9IGRhdGFzZXRzWzBdLmRhdGEubGVuZ3RoOyBpIDwgaWxlbjsgKytpKSB7XHJcblx0XHRcdFx0bGlzdEl0ZW0gPSBsaXN0LmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2xpJykpO1xyXG5cdFx0XHRcdGxpc3RJdGVtU3BhbiA9IGxpc3RJdGVtLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKSk7XHJcblx0XHRcdFx0bGlzdEl0ZW1TcGFuLnN0eWxlLmJhY2tncm91bmRDb2xvciA9IGRhdGFzZXRzWzBdLmJhY2tncm91bmRDb2xvcltpXTtcclxuXHRcdFx0XHRpZiAobGFiZWxzW2ldKSB7XHJcblx0XHRcdFx0XHRsaXN0SXRlbS5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShsYWJlbHNbaV0pKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gbGlzdC5vdXRlckhUTUw7XHJcblx0fSxcclxuXHRsZWdlbmQ6IHtcclxuXHRcdGxhYmVsczoge1xyXG5cdFx0XHRnZW5lcmF0ZUxhYmVsczogZnVuY3Rpb24oY2hhcnQpIHtcclxuXHRcdFx0XHR2YXIgZGF0YSA9IGNoYXJ0LmRhdGE7XHJcblx0XHRcdFx0aWYgKGRhdGEubGFiZWxzLmxlbmd0aCAmJiBkYXRhLmRhdGFzZXRzLmxlbmd0aCkge1xyXG5cdFx0XHRcdFx0cmV0dXJuIGRhdGEubGFiZWxzLm1hcChmdW5jdGlvbihsYWJlbCwgaSkge1xyXG5cdFx0XHRcdFx0XHR2YXIgbWV0YSA9IGNoYXJ0LmdldERhdGFzZXRNZXRhKDApO1xyXG5cdFx0XHRcdFx0XHR2YXIgc3R5bGUgPSBtZXRhLmNvbnRyb2xsZXIuZ2V0U3R5bGUoaSk7XHJcblxyXG5cdFx0XHRcdFx0XHRyZXR1cm4ge1xyXG5cdFx0XHRcdFx0XHRcdHRleHQ6IGxhYmVsLFxyXG5cdFx0XHRcdFx0XHRcdGZpbGxTdHlsZTogc3R5bGUuYmFja2dyb3VuZENvbG9yLFxyXG5cdFx0XHRcdFx0XHRcdHN0cm9rZVN0eWxlOiBzdHlsZS5ib3JkZXJDb2xvcixcclxuXHRcdFx0XHRcdFx0XHRsaW5lV2lkdGg6IHN0eWxlLmJvcmRlcldpZHRoLFxyXG5cdFx0XHRcdFx0XHRcdGhpZGRlbjogaXNOYU4oZGF0YS5kYXRhc2V0c1swXS5kYXRhW2ldKSB8fCBtZXRhLmRhdGFbaV0uaGlkZGVuLFxyXG5cclxuXHRcdFx0XHRcdFx0XHQvLyBFeHRyYSBkYXRhIHVzZWQgZm9yIHRvZ2dsaW5nIHRoZSBjb3JyZWN0IGl0ZW1cclxuXHRcdFx0XHRcdFx0XHRpbmRleDogaVxyXG5cdFx0XHRcdFx0XHR9O1xyXG5cdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdHJldHVybiBbXTtcclxuXHRcdFx0fVxyXG5cdFx0fSxcclxuXHJcblx0XHRvbkNsaWNrOiBmdW5jdGlvbihlLCBsZWdlbmRJdGVtKSB7XHJcblx0XHRcdHZhciBpbmRleCA9IGxlZ2VuZEl0ZW0uaW5kZXg7XHJcblx0XHRcdHZhciBjaGFydCA9IHRoaXMuY2hhcnQ7XHJcblx0XHRcdHZhciBpLCBpbGVuLCBtZXRhO1xyXG5cclxuXHRcdFx0Zm9yIChpID0gMCwgaWxlbiA9IChjaGFydC5kYXRhLmRhdGFzZXRzIHx8IFtdKS5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcclxuXHRcdFx0XHRtZXRhID0gY2hhcnQuZ2V0RGF0YXNldE1ldGEoaSk7XHJcblx0XHRcdFx0Ly8gdG9nZ2xlIHZpc2liaWxpdHkgb2YgaW5kZXggaWYgZXhpc3RzXHJcblx0XHRcdFx0aWYgKG1ldGEuZGF0YVtpbmRleF0pIHtcclxuXHRcdFx0XHRcdG1ldGEuZGF0YVtpbmRleF0uaGlkZGVuID0gIW1ldGEuZGF0YVtpbmRleF0uaGlkZGVuO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Y2hhcnQudXBkYXRlKCk7XHJcblx0XHR9XHJcblx0fSxcclxuXHJcblx0Ly8gVGhlIHBlcmNlbnRhZ2Ugb2YgdGhlIGNoYXJ0IHRoYXQgd2UgY3V0IG91dCBvZiB0aGUgbWlkZGxlLlxyXG5cdGN1dG91dFBlcmNlbnRhZ2U6IDUwLFxyXG5cclxuXHQvLyBUaGUgcm90YXRpb24gb2YgdGhlIGNoYXJ0LCB3aGVyZSB0aGUgZmlyc3QgZGF0YSBhcmMgYmVnaW5zLlxyXG5cdHJvdGF0aW9uOiAtSEFMRl9QSSQxLFxyXG5cclxuXHQvLyBUaGUgdG90YWwgY2lyY3VtZmVyZW5jZSBvZiB0aGUgY2hhcnQuXHJcblx0Y2lyY3VtZmVyZW5jZTogRE9VQkxFX1BJJDEsXHJcblxyXG5cdC8vIE5lZWQgdG8gb3ZlcnJpZGUgdGhlc2UgdG8gZ2l2ZSBhIG5pY2UgZGVmYXVsdFxyXG5cdHRvb2x0aXBzOiB7XHJcblx0XHRjYWxsYmFja3M6IHtcclxuXHRcdFx0dGl0bGU6IGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdHJldHVybiAnJztcclxuXHRcdFx0fSxcclxuXHRcdFx0bGFiZWw6IGZ1bmN0aW9uKHRvb2x0aXBJdGVtLCBkYXRhKSB7XHJcblx0XHRcdFx0dmFyIGRhdGFMYWJlbCA9IGRhdGEubGFiZWxzW3Rvb2x0aXBJdGVtLmluZGV4XTtcclxuXHRcdFx0XHR2YXIgdmFsdWUgPSAnOiAnICsgZGF0YS5kYXRhc2V0c1t0b29sdGlwSXRlbS5kYXRhc2V0SW5kZXhdLmRhdGFbdG9vbHRpcEl0ZW0uaW5kZXhdO1xyXG5cclxuXHRcdFx0XHRpZiAoaGVscGVycyQxLmlzQXJyYXkoZGF0YUxhYmVsKSkge1xyXG5cdFx0XHRcdFx0Ly8gc2hvdyB2YWx1ZSBvbiBmaXJzdCBsaW5lIG9mIG11bHRpbGluZSBsYWJlbFxyXG5cdFx0XHRcdFx0Ly8gbmVlZCB0byBjbG9uZSBiZWNhdXNlIHdlIGFyZSBjaGFuZ2luZyB0aGUgdmFsdWVcclxuXHRcdFx0XHRcdGRhdGFMYWJlbCA9IGRhdGFMYWJlbC5zbGljZSgpO1xyXG5cdFx0XHRcdFx0ZGF0YUxhYmVsWzBdICs9IHZhbHVlO1xyXG5cdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRkYXRhTGFiZWwgKz0gdmFsdWU7XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRyZXR1cm4gZGF0YUxhYmVsO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0fVxyXG59KTtcclxuXHJcbnZhciBjb250cm9sbGVyX2RvdWdobnV0ID0gY29yZV9kYXRhc2V0Q29udHJvbGxlci5leHRlbmQoe1xyXG5cclxuXHRkYXRhRWxlbWVudFR5cGU6IGVsZW1lbnRzLkFyYyxcclxuXHJcblx0bGlua1NjYWxlczogaGVscGVycyQxLm5vb3AsXHJcblxyXG5cdC8qKlxyXG5cdCAqIEBwcml2YXRlXHJcblx0ICovXHJcblx0X2RhdGFFbGVtZW50T3B0aW9uczogW1xyXG5cdFx0J2JhY2tncm91bmRDb2xvcicsXHJcblx0XHQnYm9yZGVyQ29sb3InLFxyXG5cdFx0J2JvcmRlcldpZHRoJyxcclxuXHRcdCdib3JkZXJBbGlnbicsXHJcblx0XHQnaG92ZXJCYWNrZ3JvdW5kQ29sb3InLFxyXG5cdFx0J2hvdmVyQm9yZGVyQ29sb3InLFxyXG5cdFx0J2hvdmVyQm9yZGVyV2lkdGgnLFxyXG5cdF0sXHJcblxyXG5cdC8vIEdldCBpbmRleCBvZiB0aGUgZGF0YXNldCBpbiByZWxhdGlvbiB0byB0aGUgdmlzaWJsZSBkYXRhc2V0cy4gVGhpcyBhbGxvd3MgZGV0ZXJtaW5pbmcgdGhlIGlubmVyIGFuZCBvdXRlciByYWRpdXMgY29ycmVjdGx5XHJcblx0Z2V0UmluZ0luZGV4OiBmdW5jdGlvbihkYXRhc2V0SW5kZXgpIHtcclxuXHRcdHZhciByaW5nSW5kZXggPSAwO1xyXG5cclxuXHRcdGZvciAodmFyIGogPSAwOyBqIDwgZGF0YXNldEluZGV4OyArK2opIHtcclxuXHRcdFx0aWYgKHRoaXMuY2hhcnQuaXNEYXRhc2V0VmlzaWJsZShqKSkge1xyXG5cdFx0XHRcdCsrcmluZ0luZGV4O1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIHJpbmdJbmRleDtcclxuXHR9LFxyXG5cclxuXHR1cGRhdGU6IGZ1bmN0aW9uKHJlc2V0KSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0dmFyIGNoYXJ0ID0gbWUuY2hhcnQ7XHJcblx0XHR2YXIgY2hhcnRBcmVhID0gY2hhcnQuY2hhcnRBcmVhO1xyXG5cdFx0dmFyIG9wdHMgPSBjaGFydC5vcHRpb25zO1xyXG5cdFx0dmFyIHJhdGlvWCA9IDE7XHJcblx0XHR2YXIgcmF0aW9ZID0gMTtcclxuXHRcdHZhciBvZmZzZXRYID0gMDtcclxuXHRcdHZhciBvZmZzZXRZID0gMDtcclxuXHRcdHZhciBtZXRhID0gbWUuZ2V0TWV0YSgpO1xyXG5cdFx0dmFyIGFyY3MgPSBtZXRhLmRhdGE7XHJcblx0XHR2YXIgY3V0b3V0ID0gb3B0cy5jdXRvdXRQZXJjZW50YWdlIC8gMTAwIHx8IDA7XHJcblx0XHR2YXIgY2lyY3VtZmVyZW5jZSA9IG9wdHMuY2lyY3VtZmVyZW5jZTtcclxuXHRcdHZhciBjaGFydFdlaWdodCA9IG1lLl9nZXRSaW5nV2VpZ2h0KG1lLmluZGV4KTtcclxuXHRcdHZhciBtYXhXaWR0aCwgbWF4SGVpZ2h0LCBpLCBpbGVuO1xyXG5cclxuXHRcdC8vIElmIHRoZSBjaGFydCdzIGNpcmN1bWZlcmVuY2UgaXNuJ3QgYSBmdWxsIGNpcmNsZSwgY2FsY3VsYXRlIHNpemUgYXMgYSByYXRpbyBvZiB0aGUgd2lkdGgvaGVpZ2h0IG9mIHRoZSBhcmNcclxuXHRcdGlmIChjaXJjdW1mZXJlbmNlIDwgRE9VQkxFX1BJJDEpIHtcclxuXHRcdFx0dmFyIHN0YXJ0QW5nbGUgPSBvcHRzLnJvdGF0aW9uICUgRE9VQkxFX1BJJDE7XHJcblx0XHRcdHN0YXJ0QW5nbGUgKz0gc3RhcnRBbmdsZSA+PSBQSSQxID8gLURPVUJMRV9QSSQxIDogc3RhcnRBbmdsZSA8IC1QSSQxID8gRE9VQkxFX1BJJDEgOiAwO1xyXG5cdFx0XHR2YXIgZW5kQW5nbGUgPSBzdGFydEFuZ2xlICsgY2lyY3VtZmVyZW5jZTtcclxuXHRcdFx0dmFyIHN0YXJ0WCA9IE1hdGguY29zKHN0YXJ0QW5nbGUpO1xyXG5cdFx0XHR2YXIgc3RhcnRZID0gTWF0aC5zaW4oc3RhcnRBbmdsZSk7XHJcblx0XHRcdHZhciBlbmRYID0gTWF0aC5jb3MoZW5kQW5nbGUpO1xyXG5cdFx0XHR2YXIgZW5kWSA9IE1hdGguc2luKGVuZEFuZ2xlKTtcclxuXHRcdFx0dmFyIGNvbnRhaW5zMCA9IChzdGFydEFuZ2xlIDw9IDAgJiYgZW5kQW5nbGUgPj0gMCkgfHwgZW5kQW5nbGUgPj0gRE9VQkxFX1BJJDE7XHJcblx0XHRcdHZhciBjb250YWluczkwID0gKHN0YXJ0QW5nbGUgPD0gSEFMRl9QSSQxICYmIGVuZEFuZ2xlID49IEhBTEZfUEkkMSkgfHwgZW5kQW5nbGUgPj0gRE9VQkxFX1BJJDEgKyBIQUxGX1BJJDE7XHJcblx0XHRcdHZhciBjb250YWluczE4MCA9IHN0YXJ0QW5nbGUgPT09IC1QSSQxIHx8IGVuZEFuZ2xlID49IFBJJDE7XHJcblx0XHRcdHZhciBjb250YWluczI3MCA9IChzdGFydEFuZ2xlIDw9IC1IQUxGX1BJJDEgJiYgZW5kQW5nbGUgPj0gLUhBTEZfUEkkMSkgfHwgZW5kQW5nbGUgPj0gUEkkMSArIEhBTEZfUEkkMTtcclxuXHRcdFx0dmFyIG1pblggPSBjb250YWluczE4MCA/IC0xIDogTWF0aC5taW4oc3RhcnRYLCBzdGFydFggKiBjdXRvdXQsIGVuZFgsIGVuZFggKiBjdXRvdXQpO1xyXG5cdFx0XHR2YXIgbWluWSA9IGNvbnRhaW5zMjcwID8gLTEgOiBNYXRoLm1pbihzdGFydFksIHN0YXJ0WSAqIGN1dG91dCwgZW5kWSwgZW5kWSAqIGN1dG91dCk7XHJcblx0XHRcdHZhciBtYXhYID0gY29udGFpbnMwID8gMSA6IE1hdGgubWF4KHN0YXJ0WCwgc3RhcnRYICogY3V0b3V0LCBlbmRYLCBlbmRYICogY3V0b3V0KTtcclxuXHRcdFx0dmFyIG1heFkgPSBjb250YWluczkwID8gMSA6IE1hdGgubWF4KHN0YXJ0WSwgc3RhcnRZICogY3V0b3V0LCBlbmRZLCBlbmRZICogY3V0b3V0KTtcclxuXHRcdFx0cmF0aW9YID0gKG1heFggLSBtaW5YKSAvIDI7XHJcblx0XHRcdHJhdGlvWSA9IChtYXhZIC0gbWluWSkgLyAyO1xyXG5cdFx0XHRvZmZzZXRYID0gLShtYXhYICsgbWluWCkgLyAyO1xyXG5cdFx0XHRvZmZzZXRZID0gLShtYXhZICsgbWluWSkgLyAyO1xyXG5cdFx0fVxyXG5cclxuXHRcdGZvciAoaSA9IDAsIGlsZW4gPSBhcmNzLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xyXG5cdFx0XHRhcmNzW2ldLl9vcHRpb25zID0gbWUuX3Jlc29sdmVEYXRhRWxlbWVudE9wdGlvbnMoYXJjc1tpXSwgaSk7XHJcblx0XHR9XHJcblxyXG5cdFx0Y2hhcnQuYm9yZGVyV2lkdGggPSBtZS5nZXRNYXhCb3JkZXJXaWR0aCgpO1xyXG5cdFx0bWF4V2lkdGggPSAoY2hhcnRBcmVhLnJpZ2h0IC0gY2hhcnRBcmVhLmxlZnQgLSBjaGFydC5ib3JkZXJXaWR0aCkgLyByYXRpb1g7XHJcblx0XHRtYXhIZWlnaHQgPSAoY2hhcnRBcmVhLmJvdHRvbSAtIGNoYXJ0QXJlYS50b3AgLSBjaGFydC5ib3JkZXJXaWR0aCkgLyByYXRpb1k7XHJcblx0XHRjaGFydC5vdXRlclJhZGl1cyA9IE1hdGgubWF4KE1hdGgubWluKG1heFdpZHRoLCBtYXhIZWlnaHQpIC8gMiwgMCk7XHJcblx0XHRjaGFydC5pbm5lclJhZGl1cyA9IE1hdGgubWF4KGNoYXJ0Lm91dGVyUmFkaXVzICogY3V0b3V0LCAwKTtcclxuXHRcdGNoYXJ0LnJhZGl1c0xlbmd0aCA9IChjaGFydC5vdXRlclJhZGl1cyAtIGNoYXJ0LmlubmVyUmFkaXVzKSAvIChtZS5fZ2V0VmlzaWJsZURhdGFzZXRXZWlnaHRUb3RhbCgpIHx8IDEpO1xyXG5cdFx0Y2hhcnQub2Zmc2V0WCA9IG9mZnNldFggKiBjaGFydC5vdXRlclJhZGl1cztcclxuXHRcdGNoYXJ0Lm9mZnNldFkgPSBvZmZzZXRZICogY2hhcnQub3V0ZXJSYWRpdXM7XHJcblxyXG5cdFx0bWV0YS50b3RhbCA9IG1lLmNhbGN1bGF0ZVRvdGFsKCk7XHJcblxyXG5cdFx0bWUub3V0ZXJSYWRpdXMgPSBjaGFydC5vdXRlclJhZGl1cyAtIGNoYXJ0LnJhZGl1c0xlbmd0aCAqIG1lLl9nZXRSaW5nV2VpZ2h0T2Zmc2V0KG1lLmluZGV4KTtcclxuXHRcdG1lLmlubmVyUmFkaXVzID0gTWF0aC5tYXgobWUub3V0ZXJSYWRpdXMgLSBjaGFydC5yYWRpdXNMZW5ndGggKiBjaGFydFdlaWdodCwgMCk7XHJcblxyXG5cdFx0Zm9yIChpID0gMCwgaWxlbiA9IGFyY3MubGVuZ3RoOyBpIDwgaWxlbjsgKytpKSB7XHJcblx0XHRcdG1lLnVwZGF0ZUVsZW1lbnQoYXJjc1tpXSwgaSwgcmVzZXQpO1xyXG5cdFx0fVxyXG5cdH0sXHJcblxyXG5cdHVwZGF0ZUVsZW1lbnQ6IGZ1bmN0aW9uKGFyYywgaW5kZXgsIHJlc2V0KSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0dmFyIGNoYXJ0ID0gbWUuY2hhcnQ7XHJcblx0XHR2YXIgY2hhcnRBcmVhID0gY2hhcnQuY2hhcnRBcmVhO1xyXG5cdFx0dmFyIG9wdHMgPSBjaGFydC5vcHRpb25zO1xyXG5cdFx0dmFyIGFuaW1hdGlvbk9wdHMgPSBvcHRzLmFuaW1hdGlvbjtcclxuXHRcdHZhciBjZW50ZXJYID0gKGNoYXJ0QXJlYS5sZWZ0ICsgY2hhcnRBcmVhLnJpZ2h0KSAvIDI7XHJcblx0XHR2YXIgY2VudGVyWSA9IChjaGFydEFyZWEudG9wICsgY2hhcnRBcmVhLmJvdHRvbSkgLyAyO1xyXG5cdFx0dmFyIHN0YXJ0QW5nbGUgPSBvcHRzLnJvdGF0aW9uOyAvLyBub24gcmVzZXQgY2FzZSBoYW5kbGVkIGxhdGVyXHJcblx0XHR2YXIgZW5kQW5nbGUgPSBvcHRzLnJvdGF0aW9uOyAvLyBub24gcmVzZXQgY2FzZSBoYW5kbGVkIGxhdGVyXHJcblx0XHR2YXIgZGF0YXNldCA9IG1lLmdldERhdGFzZXQoKTtcclxuXHRcdHZhciBjaXJjdW1mZXJlbmNlID0gcmVzZXQgJiYgYW5pbWF0aW9uT3B0cy5hbmltYXRlUm90YXRlID8gMCA6IGFyYy5oaWRkZW4gPyAwIDogbWUuY2FsY3VsYXRlQ2lyY3VtZmVyZW5jZShkYXRhc2V0LmRhdGFbaW5kZXhdKSAqIChvcHRzLmNpcmN1bWZlcmVuY2UgLyBET1VCTEVfUEkkMSk7XHJcblx0XHR2YXIgaW5uZXJSYWRpdXMgPSByZXNldCAmJiBhbmltYXRpb25PcHRzLmFuaW1hdGVTY2FsZSA/IDAgOiBtZS5pbm5lclJhZGl1cztcclxuXHRcdHZhciBvdXRlclJhZGl1cyA9IHJlc2V0ICYmIGFuaW1hdGlvbk9wdHMuYW5pbWF0ZVNjYWxlID8gMCA6IG1lLm91dGVyUmFkaXVzO1xyXG5cdFx0dmFyIG9wdGlvbnMgPSBhcmMuX29wdGlvbnMgfHwge307XHJcblxyXG5cdFx0aGVscGVycyQxLmV4dGVuZChhcmMsIHtcclxuXHRcdFx0Ly8gVXRpbGl0eVxyXG5cdFx0XHRfZGF0YXNldEluZGV4OiBtZS5pbmRleCxcclxuXHRcdFx0X2luZGV4OiBpbmRleCxcclxuXHJcblx0XHRcdC8vIERlc2lyZWQgdmlldyBwcm9wZXJ0aWVzXHJcblx0XHRcdF9tb2RlbDoge1xyXG5cdFx0XHRcdGJhY2tncm91bmRDb2xvcjogb3B0aW9ucy5iYWNrZ3JvdW5kQ29sb3IsXHJcblx0XHRcdFx0Ym9yZGVyQ29sb3I6IG9wdGlvbnMuYm9yZGVyQ29sb3IsXHJcblx0XHRcdFx0Ym9yZGVyV2lkdGg6IG9wdGlvbnMuYm9yZGVyV2lkdGgsXHJcblx0XHRcdFx0Ym9yZGVyQWxpZ246IG9wdGlvbnMuYm9yZGVyQWxpZ24sXHJcblx0XHRcdFx0eDogY2VudGVyWCArIGNoYXJ0Lm9mZnNldFgsXHJcblx0XHRcdFx0eTogY2VudGVyWSArIGNoYXJ0Lm9mZnNldFksXHJcblx0XHRcdFx0c3RhcnRBbmdsZTogc3RhcnRBbmdsZSxcclxuXHRcdFx0XHRlbmRBbmdsZTogZW5kQW5nbGUsXHJcblx0XHRcdFx0Y2lyY3VtZmVyZW5jZTogY2lyY3VtZmVyZW5jZSxcclxuXHRcdFx0XHRvdXRlclJhZGl1czogb3V0ZXJSYWRpdXMsXHJcblx0XHRcdFx0aW5uZXJSYWRpdXM6IGlubmVyUmFkaXVzLFxyXG5cdFx0XHRcdGxhYmVsOiBoZWxwZXJzJDEudmFsdWVBdEluZGV4T3JEZWZhdWx0KGRhdGFzZXQubGFiZWwsIGluZGV4LCBjaGFydC5kYXRhLmxhYmVsc1tpbmRleF0pXHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cclxuXHRcdHZhciBtb2RlbCA9IGFyYy5fbW9kZWw7XHJcblxyXG5cdFx0Ly8gU2V0IGNvcnJlY3QgYW5nbGVzIGlmIG5vdCByZXNldHRpbmdcclxuXHRcdGlmICghcmVzZXQgfHwgIWFuaW1hdGlvbk9wdHMuYW5pbWF0ZVJvdGF0ZSkge1xyXG5cdFx0XHRpZiAoaW5kZXggPT09IDApIHtcclxuXHRcdFx0XHRtb2RlbC5zdGFydEFuZ2xlID0gb3B0cy5yb3RhdGlvbjtcclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRtb2RlbC5zdGFydEFuZ2xlID0gbWUuZ2V0TWV0YSgpLmRhdGFbaW5kZXggLSAxXS5fbW9kZWwuZW5kQW5nbGU7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdG1vZGVsLmVuZEFuZ2xlID0gbW9kZWwuc3RhcnRBbmdsZSArIG1vZGVsLmNpcmN1bWZlcmVuY2U7XHJcblx0XHR9XHJcblxyXG5cdFx0YXJjLnBpdm90KCk7XHJcblx0fSxcclxuXHJcblx0Y2FsY3VsYXRlVG90YWw6IGZ1bmN0aW9uKCkge1xyXG5cdFx0dmFyIGRhdGFzZXQgPSB0aGlzLmdldERhdGFzZXQoKTtcclxuXHRcdHZhciBtZXRhID0gdGhpcy5nZXRNZXRhKCk7XHJcblx0XHR2YXIgdG90YWwgPSAwO1xyXG5cdFx0dmFyIHZhbHVlO1xyXG5cclxuXHRcdGhlbHBlcnMkMS5lYWNoKG1ldGEuZGF0YSwgZnVuY3Rpb24oZWxlbWVudCwgaW5kZXgpIHtcclxuXHRcdFx0dmFsdWUgPSBkYXRhc2V0LmRhdGFbaW5kZXhdO1xyXG5cdFx0XHRpZiAoIWlzTmFOKHZhbHVlKSAmJiAhZWxlbWVudC5oaWRkZW4pIHtcclxuXHRcdFx0XHR0b3RhbCArPSBNYXRoLmFicyh2YWx1ZSk7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cclxuXHRcdC8qIGlmICh0b3RhbCA9PT0gMCkge1xyXG5cdFx0XHR0b3RhbCA9IE5hTjtcclxuXHRcdH0qL1xyXG5cclxuXHRcdHJldHVybiB0b3RhbDtcclxuXHR9LFxyXG5cclxuXHRjYWxjdWxhdGVDaXJjdW1mZXJlbmNlOiBmdW5jdGlvbih2YWx1ZSkge1xyXG5cdFx0dmFyIHRvdGFsID0gdGhpcy5nZXRNZXRhKCkudG90YWw7XHJcblx0XHRpZiAodG90YWwgPiAwICYmICFpc05hTih2YWx1ZSkpIHtcclxuXHRcdFx0cmV0dXJuIERPVUJMRV9QSSQxICogKE1hdGguYWJzKHZhbHVlKSAvIHRvdGFsKTtcclxuXHRcdH1cclxuXHRcdHJldHVybiAwO1xyXG5cdH0sXHJcblxyXG5cdC8vIGdldHMgdGhlIG1heCBib3JkZXIgb3IgaG92ZXIgd2lkdGggdG8gcHJvcGVybHkgc2NhbGUgcGllIGNoYXJ0c1xyXG5cdGdldE1heEJvcmRlcldpZHRoOiBmdW5jdGlvbihhcmNzKSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0dmFyIG1heCA9IDA7XHJcblx0XHR2YXIgY2hhcnQgPSBtZS5jaGFydDtcclxuXHRcdHZhciBpLCBpbGVuLCBtZXRhLCBhcmMsIGNvbnRyb2xsZXIsIG9wdGlvbnMsIGJvcmRlcldpZHRoLCBob3ZlcldpZHRoO1xyXG5cclxuXHRcdGlmICghYXJjcykge1xyXG5cdFx0XHQvLyBGaW5kIHRoZSBvdXRtb3N0IHZpc2libGUgZGF0YXNldFxyXG5cdFx0XHRmb3IgKGkgPSAwLCBpbGVuID0gY2hhcnQuZGF0YS5kYXRhc2V0cy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcclxuXHRcdFx0XHRpZiAoY2hhcnQuaXNEYXRhc2V0VmlzaWJsZShpKSkge1xyXG5cdFx0XHRcdFx0bWV0YSA9IGNoYXJ0LmdldERhdGFzZXRNZXRhKGkpO1xyXG5cdFx0XHRcdFx0YXJjcyA9IG1ldGEuZGF0YTtcclxuXHRcdFx0XHRcdGlmIChpICE9PSBtZS5pbmRleCkge1xyXG5cdFx0XHRcdFx0XHRjb250cm9sbGVyID0gbWV0YS5jb250cm9sbGVyO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0YnJlYWs7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKCFhcmNzKSB7XHJcblx0XHRcdHJldHVybiAwO1xyXG5cdFx0fVxyXG5cclxuXHRcdGZvciAoaSA9IDAsIGlsZW4gPSBhcmNzLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xyXG5cdFx0XHRhcmMgPSBhcmNzW2ldO1xyXG5cdFx0XHRpZiAoY29udHJvbGxlcikge1xyXG5cdFx0XHRcdGNvbnRyb2xsZXIuX2NvbmZpZ3VyZSgpO1xyXG5cdFx0XHRcdG9wdGlvbnMgPSBjb250cm9sbGVyLl9yZXNvbHZlRGF0YUVsZW1lbnRPcHRpb25zKGFyYywgaSk7XHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0b3B0aW9ucyA9IGFyYy5fb3B0aW9ucztcclxuXHRcdFx0fVxyXG5cdFx0XHRpZiAob3B0aW9ucy5ib3JkZXJBbGlnbiAhPT0gJ2lubmVyJykge1xyXG5cdFx0XHRcdGJvcmRlcldpZHRoID0gb3B0aW9ucy5ib3JkZXJXaWR0aDtcclxuXHRcdFx0XHRob3ZlcldpZHRoID0gb3B0aW9ucy5ob3ZlckJvcmRlcldpZHRoO1xyXG5cclxuXHRcdFx0XHRtYXggPSBib3JkZXJXaWR0aCA+IG1heCA/IGJvcmRlcldpZHRoIDogbWF4O1xyXG5cdFx0XHRcdG1heCA9IGhvdmVyV2lkdGggPiBtYXggPyBob3ZlcldpZHRoIDogbWF4O1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gbWF4O1xyXG5cdH0sXHJcblxyXG5cdC8qKlxyXG5cdCAqIEBwcm90ZWN0ZWRcclxuXHQgKi9cclxuXHRzZXRIb3ZlclN0eWxlOiBmdW5jdGlvbihhcmMpIHtcclxuXHRcdHZhciBtb2RlbCA9IGFyYy5fbW9kZWw7XHJcblx0XHR2YXIgb3B0aW9ucyA9IGFyYy5fb3B0aW9ucztcclxuXHRcdHZhciBnZXRIb3ZlckNvbG9yID0gaGVscGVycyQxLmdldEhvdmVyQ29sb3I7XHJcblxyXG5cdFx0YXJjLiRwcmV2aW91c1N0eWxlID0ge1xyXG5cdFx0XHRiYWNrZ3JvdW5kQ29sb3I6IG1vZGVsLmJhY2tncm91bmRDb2xvcixcclxuXHRcdFx0Ym9yZGVyQ29sb3I6IG1vZGVsLmJvcmRlckNvbG9yLFxyXG5cdFx0XHRib3JkZXJXaWR0aDogbW9kZWwuYm9yZGVyV2lkdGgsXHJcblx0XHR9O1xyXG5cclxuXHRcdG1vZGVsLmJhY2tncm91bmRDb2xvciA9IHZhbHVlT3JEZWZhdWx0JDUob3B0aW9ucy5ob3ZlckJhY2tncm91bmRDb2xvciwgZ2V0SG92ZXJDb2xvcihvcHRpb25zLmJhY2tncm91bmRDb2xvcikpO1xyXG5cdFx0bW9kZWwuYm9yZGVyQ29sb3IgPSB2YWx1ZU9yRGVmYXVsdCQ1KG9wdGlvbnMuaG92ZXJCb3JkZXJDb2xvciwgZ2V0SG92ZXJDb2xvcihvcHRpb25zLmJvcmRlckNvbG9yKSk7XHJcblx0XHRtb2RlbC5ib3JkZXJXaWR0aCA9IHZhbHVlT3JEZWZhdWx0JDUob3B0aW9ucy5ob3ZlckJvcmRlcldpZHRoLCBvcHRpb25zLmJvcmRlcldpZHRoKTtcclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBHZXQgcmFkaXVzIGxlbmd0aCBvZmZzZXQgb2YgdGhlIGRhdGFzZXQgaW4gcmVsYXRpb24gdG8gdGhlIHZpc2libGUgZGF0YXNldHMgd2VpZ2h0cy4gVGhpcyBhbGxvd3MgZGV0ZXJtaW5pbmcgdGhlIGlubmVyIGFuZCBvdXRlciByYWRpdXMgY29ycmVjdGx5XHJcblx0ICogQHByaXZhdGVcclxuXHQgKi9cclxuXHRfZ2V0UmluZ1dlaWdodE9mZnNldDogZnVuY3Rpb24oZGF0YXNldEluZGV4KSB7XHJcblx0XHR2YXIgcmluZ1dlaWdodE9mZnNldCA9IDA7XHJcblxyXG5cdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCBkYXRhc2V0SW5kZXg7ICsraSkge1xyXG5cdFx0XHRpZiAodGhpcy5jaGFydC5pc0RhdGFzZXRWaXNpYmxlKGkpKSB7XHJcblx0XHRcdFx0cmluZ1dlaWdodE9mZnNldCArPSB0aGlzLl9nZXRSaW5nV2VpZ2h0KGkpO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIHJpbmdXZWlnaHRPZmZzZXQ7XHJcblx0fSxcclxuXHJcblx0LyoqXHJcblx0ICogQHByaXZhdGVcclxuXHQgKi9cclxuXHRfZ2V0UmluZ1dlaWdodDogZnVuY3Rpb24oZGF0YVNldEluZGV4KSB7XHJcblx0XHRyZXR1cm4gTWF0aC5tYXgodmFsdWVPckRlZmF1bHQkNSh0aGlzLmNoYXJ0LmRhdGEuZGF0YXNldHNbZGF0YVNldEluZGV4XS53ZWlnaHQsIDEpLCAwKTtcclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBSZXR1cm5zIHRoZSBzdW0gb2YgYWxsIHZpc2liaWxlIGRhdGEgc2V0IHdlaWdodHMuICBUaGlzIHZhbHVlIGNhbiBiZSAwLlxyXG5cdCAqIEBwcml2YXRlXHJcblx0ICovXHJcblx0X2dldFZpc2libGVEYXRhc2V0V2VpZ2h0VG90YWw6IGZ1bmN0aW9uKCkge1xyXG5cdFx0cmV0dXJuIHRoaXMuX2dldFJpbmdXZWlnaHRPZmZzZXQodGhpcy5jaGFydC5kYXRhLmRhdGFzZXRzLmxlbmd0aCk7XHJcblx0fVxyXG59KTtcblxuY29yZV9kZWZhdWx0cy5fc2V0KCdob3Jpem9udGFsQmFyJywge1xyXG5cdGhvdmVyOiB7XHJcblx0XHRtb2RlOiAnaW5kZXgnLFxyXG5cdFx0YXhpczogJ3knXHJcblx0fSxcclxuXHJcblx0c2NhbGVzOiB7XHJcblx0XHR4QXhlczogW3tcclxuXHRcdFx0dHlwZTogJ2xpbmVhcicsXHJcblx0XHRcdHBvc2l0aW9uOiAnYm90dG9tJ1xyXG5cdFx0fV0sXHJcblxyXG5cdFx0eUF4ZXM6IFt7XHJcblx0XHRcdHR5cGU6ICdjYXRlZ29yeScsXHJcblx0XHRcdHBvc2l0aW9uOiAnbGVmdCcsXHJcblx0XHRcdG9mZnNldDogdHJ1ZSxcclxuXHRcdFx0Z3JpZExpbmVzOiB7XHJcblx0XHRcdFx0b2Zmc2V0R3JpZExpbmVzOiB0cnVlXHJcblx0XHRcdH1cclxuXHRcdH1dXHJcblx0fSxcclxuXHJcblx0ZWxlbWVudHM6IHtcclxuXHRcdHJlY3RhbmdsZToge1xyXG5cdFx0XHRib3JkZXJTa2lwcGVkOiAnbGVmdCdcclxuXHRcdH1cclxuXHR9LFxyXG5cclxuXHR0b29sdGlwczoge1xyXG5cdFx0bW9kZTogJ2luZGV4JyxcclxuXHRcdGF4aXM6ICd5J1xyXG5cdH1cclxufSk7XHJcblxyXG5jb3JlX2RlZmF1bHRzLl9zZXQoJ2dsb2JhbCcsIHtcclxuXHRkYXRhc2V0czoge1xyXG5cdFx0aG9yaXpvbnRhbEJhcjoge1xyXG5cdFx0XHRjYXRlZ29yeVBlcmNlbnRhZ2U6IDAuOCxcclxuXHRcdFx0YmFyUGVyY2VudGFnZTogMC45XHJcblx0XHR9XHJcblx0fVxyXG59KTtcclxuXHJcbnZhciBjb250cm9sbGVyX2hvcml6b250YWxCYXIgPSBjb250cm9sbGVyX2Jhci5leHRlbmQoe1xyXG5cdC8qKlxyXG5cdCAqIEBwcml2YXRlXHJcblx0ICovXHJcblx0X2dldFZhbHVlU2NhbGVJZDogZnVuY3Rpb24oKSB7XHJcblx0XHRyZXR1cm4gdGhpcy5nZXRNZXRhKCkueEF4aXNJRDtcclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBAcHJpdmF0ZVxyXG5cdCAqL1xyXG5cdF9nZXRJbmRleFNjYWxlSWQ6IGZ1bmN0aW9uKCkge1xyXG5cdFx0cmV0dXJuIHRoaXMuZ2V0TWV0YSgpLnlBeGlzSUQ7XHJcblx0fVxyXG59KTtcblxudmFyIHZhbHVlT3JEZWZhdWx0JDYgPSBoZWxwZXJzJDEudmFsdWVPckRlZmF1bHQ7XHJcbnZhciByZXNvbHZlJDIgPSBoZWxwZXJzJDEub3B0aW9ucy5yZXNvbHZlO1xyXG52YXIgaXNQb2ludEluQXJlYSA9IGhlbHBlcnMkMS5jYW52YXMuX2lzUG9pbnRJbkFyZWE7XHJcblxyXG5jb3JlX2RlZmF1bHRzLl9zZXQoJ2xpbmUnLCB7XHJcblx0c2hvd0xpbmVzOiB0cnVlLFxyXG5cdHNwYW5HYXBzOiBmYWxzZSxcclxuXHJcblx0aG92ZXI6IHtcclxuXHRcdG1vZGU6ICdsYWJlbCdcclxuXHR9LFxyXG5cclxuXHRzY2FsZXM6IHtcclxuXHRcdHhBeGVzOiBbe1xyXG5cdFx0XHR0eXBlOiAnY2F0ZWdvcnknLFxyXG5cdFx0XHRpZDogJ3gtYXhpcy0wJ1xyXG5cdFx0fV0sXHJcblx0XHR5QXhlczogW3tcclxuXHRcdFx0dHlwZTogJ2xpbmVhcicsXHJcblx0XHRcdGlkOiAneS1heGlzLTAnXHJcblx0XHR9XVxyXG5cdH1cclxufSk7XHJcblxyXG5mdW5jdGlvbiBzY2FsZUNsaXAoc2NhbGUsIGhhbGZCb3JkZXJXaWR0aCkge1xyXG5cdHZhciB0aWNrT3B0cyA9IHNjYWxlICYmIHNjYWxlLm9wdGlvbnMudGlja3MgfHwge307XHJcblx0dmFyIHJldmVyc2UgPSB0aWNrT3B0cy5yZXZlcnNlO1xyXG5cdHZhciBtaW4gPSB0aWNrT3B0cy5taW4gPT09IHVuZGVmaW5lZCA/IGhhbGZCb3JkZXJXaWR0aCA6IDA7XHJcblx0dmFyIG1heCA9IHRpY2tPcHRzLm1heCA9PT0gdW5kZWZpbmVkID8gaGFsZkJvcmRlcldpZHRoIDogMDtcclxuXHRyZXR1cm4ge1xyXG5cdFx0c3RhcnQ6IHJldmVyc2UgPyBtYXggOiBtaW4sXHJcblx0XHRlbmQ6IHJldmVyc2UgPyBtaW4gOiBtYXhcclxuXHR9O1xyXG59XHJcblxyXG5mdW5jdGlvbiBkZWZhdWx0Q2xpcCh4U2NhbGUsIHlTY2FsZSwgYm9yZGVyV2lkdGgpIHtcclxuXHR2YXIgaGFsZkJvcmRlcldpZHRoID0gYm9yZGVyV2lkdGggLyAyO1xyXG5cdHZhciB4ID0gc2NhbGVDbGlwKHhTY2FsZSwgaGFsZkJvcmRlcldpZHRoKTtcclxuXHR2YXIgeSA9IHNjYWxlQ2xpcCh5U2NhbGUsIGhhbGZCb3JkZXJXaWR0aCk7XHJcblxyXG5cdHJldHVybiB7XHJcblx0XHR0b3A6IHkuZW5kLFxyXG5cdFx0cmlnaHQ6IHguZW5kLFxyXG5cdFx0Ym90dG9tOiB5LnN0YXJ0LFxyXG5cdFx0bGVmdDogeC5zdGFydFxyXG5cdH07XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHRvQ2xpcCh2YWx1ZSkge1xyXG5cdHZhciB0LCByLCBiLCBsO1xyXG5cclxuXHRpZiAoaGVscGVycyQxLmlzT2JqZWN0KHZhbHVlKSkge1xyXG5cdFx0dCA9IHZhbHVlLnRvcDtcclxuXHRcdHIgPSB2YWx1ZS5yaWdodDtcclxuXHRcdGIgPSB2YWx1ZS5ib3R0b207XHJcblx0XHRsID0gdmFsdWUubGVmdDtcclxuXHR9IGVsc2Uge1xyXG5cdFx0dCA9IHIgPSBiID0gbCA9IHZhbHVlO1xyXG5cdH1cclxuXHJcblx0cmV0dXJuIHtcclxuXHRcdHRvcDogdCxcclxuXHRcdHJpZ2h0OiByLFxyXG5cdFx0Ym90dG9tOiBiLFxyXG5cdFx0bGVmdDogbFxyXG5cdH07XHJcbn1cclxuXHJcblxyXG52YXIgY29udHJvbGxlcl9saW5lID0gY29yZV9kYXRhc2V0Q29udHJvbGxlci5leHRlbmQoe1xyXG5cclxuXHRkYXRhc2V0RWxlbWVudFR5cGU6IGVsZW1lbnRzLkxpbmUsXHJcblxyXG5cdGRhdGFFbGVtZW50VHlwZTogZWxlbWVudHMuUG9pbnQsXHJcblxyXG5cdC8qKlxyXG5cdCAqIEBwcml2YXRlXHJcblx0ICovXHJcblx0X2RhdGFzZXRFbGVtZW50T3B0aW9uczogW1xyXG5cdFx0J2JhY2tncm91bmRDb2xvcicsXHJcblx0XHQnYm9yZGVyQ2FwU3R5bGUnLFxyXG5cdFx0J2JvcmRlckNvbG9yJyxcclxuXHRcdCdib3JkZXJEYXNoJyxcclxuXHRcdCdib3JkZXJEYXNoT2Zmc2V0JyxcclxuXHRcdCdib3JkZXJKb2luU3R5bGUnLFxyXG5cdFx0J2JvcmRlcldpZHRoJyxcclxuXHRcdCdjdWJpY0ludGVycG9sYXRpb25Nb2RlJyxcclxuXHRcdCdmaWxsJ1xyXG5cdF0sXHJcblxyXG5cdC8qKlxyXG5cdCAqIEBwcml2YXRlXHJcblx0ICovXHJcblx0X2RhdGFFbGVtZW50T3B0aW9uczoge1xyXG5cdFx0YmFja2dyb3VuZENvbG9yOiAncG9pbnRCYWNrZ3JvdW5kQ29sb3InLFxyXG5cdFx0Ym9yZGVyQ29sb3I6ICdwb2ludEJvcmRlckNvbG9yJyxcclxuXHRcdGJvcmRlcldpZHRoOiAncG9pbnRCb3JkZXJXaWR0aCcsXHJcblx0XHRoaXRSYWRpdXM6ICdwb2ludEhpdFJhZGl1cycsXHJcblx0XHRob3ZlckJhY2tncm91bmRDb2xvcjogJ3BvaW50SG92ZXJCYWNrZ3JvdW5kQ29sb3InLFxyXG5cdFx0aG92ZXJCb3JkZXJDb2xvcjogJ3BvaW50SG92ZXJCb3JkZXJDb2xvcicsXHJcblx0XHRob3ZlckJvcmRlcldpZHRoOiAncG9pbnRIb3ZlckJvcmRlcldpZHRoJyxcclxuXHRcdGhvdmVyUmFkaXVzOiAncG9pbnRIb3ZlclJhZGl1cycsXHJcblx0XHRwb2ludFN0eWxlOiAncG9pbnRTdHlsZScsXHJcblx0XHRyYWRpdXM6ICdwb2ludFJhZGl1cycsXHJcblx0XHRyb3RhdGlvbjogJ3BvaW50Um90YXRpb24nXHJcblx0fSxcclxuXHJcblx0dXBkYXRlOiBmdW5jdGlvbihyZXNldCkge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHRcdHZhciBtZXRhID0gbWUuZ2V0TWV0YSgpO1xyXG5cdFx0dmFyIGxpbmUgPSBtZXRhLmRhdGFzZXQ7XHJcblx0XHR2YXIgcG9pbnRzID0gbWV0YS5kYXRhIHx8IFtdO1xyXG5cdFx0dmFyIG9wdGlvbnMgPSBtZS5jaGFydC5vcHRpb25zO1xyXG5cdFx0dmFyIGNvbmZpZyA9IG1lLl9jb25maWc7XHJcblx0XHR2YXIgc2hvd0xpbmUgPSBtZS5fc2hvd0xpbmUgPSB2YWx1ZU9yRGVmYXVsdCQ2KGNvbmZpZy5zaG93TGluZSwgb3B0aW9ucy5zaG93TGluZXMpO1xyXG5cdFx0dmFyIGksIGlsZW47XHJcblxyXG5cdFx0bWUuX3hTY2FsZSA9IG1lLmdldFNjYWxlRm9ySWQobWV0YS54QXhpc0lEKTtcclxuXHRcdG1lLl95U2NhbGUgPSBtZS5nZXRTY2FsZUZvcklkKG1ldGEueUF4aXNJRCk7XHJcblxyXG5cdFx0Ly8gVXBkYXRlIExpbmVcclxuXHRcdGlmIChzaG93TGluZSkge1xyXG5cdFx0XHQvLyBDb21wYXRpYmlsaXR5OiBJZiB0aGUgcHJvcGVydGllcyBhcmUgZGVmaW5lZCB3aXRoIG9ubHkgdGhlIG9sZCBuYW1lLCB1c2UgdGhvc2UgdmFsdWVzXHJcblx0XHRcdGlmIChjb25maWcudGVuc2lvbiAhPT0gdW5kZWZpbmVkICYmIGNvbmZpZy5saW5lVGVuc2lvbiA9PT0gdW5kZWZpbmVkKSB7XHJcblx0XHRcdFx0Y29uZmlnLmxpbmVUZW5zaW9uID0gY29uZmlnLnRlbnNpb247XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIFV0aWxpdHlcclxuXHRcdFx0bGluZS5fc2NhbGUgPSBtZS5feVNjYWxlO1xyXG5cdFx0XHRsaW5lLl9kYXRhc2V0SW5kZXggPSBtZS5pbmRleDtcclxuXHRcdFx0Ly8gRGF0YVxyXG5cdFx0XHRsaW5lLl9jaGlsZHJlbiA9IHBvaW50cztcclxuXHRcdFx0Ly8gTW9kZWxcclxuXHRcdFx0bGluZS5fbW9kZWwgPSBtZS5fcmVzb2x2ZURhdGFzZXRFbGVtZW50T3B0aW9ucyhsaW5lKTtcclxuXHJcblx0XHRcdGxpbmUucGl2b3QoKTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBVcGRhdGUgUG9pbnRzXHJcblx0XHRmb3IgKGkgPSAwLCBpbGVuID0gcG9pbnRzLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xyXG5cdFx0XHRtZS51cGRhdGVFbGVtZW50KHBvaW50c1tpXSwgaSwgcmVzZXQpO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmIChzaG93TGluZSAmJiBsaW5lLl9tb2RlbC50ZW5zaW9uICE9PSAwKSB7XHJcblx0XHRcdG1lLnVwZGF0ZUJlemllckNvbnRyb2xQb2ludHMoKTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBOb3cgcGl2b3QgdGhlIHBvaW50IGZvciBhbmltYXRpb25cclxuXHRcdGZvciAoaSA9IDAsIGlsZW4gPSBwb2ludHMubGVuZ3RoOyBpIDwgaWxlbjsgKytpKSB7XHJcblx0XHRcdHBvaW50c1tpXS5waXZvdCgpO1xyXG5cdFx0fVxyXG5cdH0sXHJcblxyXG5cdHVwZGF0ZUVsZW1lbnQ6IGZ1bmN0aW9uKHBvaW50LCBpbmRleCwgcmVzZXQpIHtcclxuXHRcdHZhciBtZSA9IHRoaXM7XHJcblx0XHR2YXIgbWV0YSA9IG1lLmdldE1ldGEoKTtcclxuXHRcdHZhciBjdXN0b20gPSBwb2ludC5jdXN0b20gfHwge307XHJcblx0XHR2YXIgZGF0YXNldCA9IG1lLmdldERhdGFzZXQoKTtcclxuXHRcdHZhciBkYXRhc2V0SW5kZXggPSBtZS5pbmRleDtcclxuXHRcdHZhciB2YWx1ZSA9IGRhdGFzZXQuZGF0YVtpbmRleF07XHJcblx0XHR2YXIgeFNjYWxlID0gbWUuX3hTY2FsZTtcclxuXHRcdHZhciB5U2NhbGUgPSBtZS5feVNjYWxlO1xyXG5cdFx0dmFyIGxpbmVNb2RlbCA9IG1ldGEuZGF0YXNldC5fbW9kZWw7XHJcblx0XHR2YXIgeCwgeTtcclxuXHJcblx0XHR2YXIgb3B0aW9ucyA9IG1lLl9yZXNvbHZlRGF0YUVsZW1lbnRPcHRpb25zKHBvaW50LCBpbmRleCk7XHJcblxyXG5cdFx0eCA9IHhTY2FsZS5nZXRQaXhlbEZvclZhbHVlKHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgPyB2YWx1ZSA6IE5hTiwgaW5kZXgsIGRhdGFzZXRJbmRleCk7XHJcblx0XHR5ID0gcmVzZXQgPyB5U2NhbGUuZ2V0QmFzZVBpeGVsKCkgOiBtZS5jYWxjdWxhdGVQb2ludFkodmFsdWUsIGluZGV4LCBkYXRhc2V0SW5kZXgpO1xyXG5cclxuXHRcdC8vIFV0aWxpdHlcclxuXHRcdHBvaW50Ll94U2NhbGUgPSB4U2NhbGU7XHJcblx0XHRwb2ludC5feVNjYWxlID0geVNjYWxlO1xyXG5cdFx0cG9pbnQuX29wdGlvbnMgPSBvcHRpb25zO1xyXG5cdFx0cG9pbnQuX2RhdGFzZXRJbmRleCA9IGRhdGFzZXRJbmRleDtcclxuXHRcdHBvaW50Ll9pbmRleCA9IGluZGV4O1xyXG5cclxuXHRcdC8vIERlc2lyZWQgdmlldyBwcm9wZXJ0aWVzXHJcblx0XHRwb2ludC5fbW9kZWwgPSB7XHJcblx0XHRcdHg6IHgsXHJcblx0XHRcdHk6IHksXHJcblx0XHRcdHNraXA6IGN1c3RvbS5za2lwIHx8IGlzTmFOKHgpIHx8IGlzTmFOKHkpLFxyXG5cdFx0XHQvLyBBcHBlYXJhbmNlXHJcblx0XHRcdHJhZGl1czogb3B0aW9ucy5yYWRpdXMsXHJcblx0XHRcdHBvaW50U3R5bGU6IG9wdGlvbnMucG9pbnRTdHlsZSxcclxuXHRcdFx0cm90YXRpb246IG9wdGlvbnMucm90YXRpb24sXHJcblx0XHRcdGJhY2tncm91bmRDb2xvcjogb3B0aW9ucy5iYWNrZ3JvdW5kQ29sb3IsXHJcblx0XHRcdGJvcmRlckNvbG9yOiBvcHRpb25zLmJvcmRlckNvbG9yLFxyXG5cdFx0XHRib3JkZXJXaWR0aDogb3B0aW9ucy5ib3JkZXJXaWR0aCxcclxuXHRcdFx0dGVuc2lvbjogdmFsdWVPckRlZmF1bHQkNihjdXN0b20udGVuc2lvbiwgbGluZU1vZGVsID8gbGluZU1vZGVsLnRlbnNpb24gOiAwKSxcclxuXHRcdFx0c3RlcHBlZExpbmU6IGxpbmVNb2RlbCA/IGxpbmVNb2RlbC5zdGVwcGVkTGluZSA6IGZhbHNlLFxyXG5cdFx0XHQvLyBUb29sdGlwXHJcblx0XHRcdGhpdFJhZGl1czogb3B0aW9ucy5oaXRSYWRpdXNcclxuXHRcdH07XHJcblx0fSxcclxuXHJcblx0LyoqXHJcblx0ICogQHByaXZhdGVcclxuXHQgKi9cclxuXHRfcmVzb2x2ZURhdGFzZXRFbGVtZW50T3B0aW9uczogZnVuY3Rpb24oZWxlbWVudCkge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHRcdHZhciBjb25maWcgPSBtZS5fY29uZmlnO1xyXG5cdFx0dmFyIGN1c3RvbSA9IGVsZW1lbnQuY3VzdG9tIHx8IHt9O1xyXG5cdFx0dmFyIG9wdGlvbnMgPSBtZS5jaGFydC5vcHRpb25zO1xyXG5cdFx0dmFyIGxpbmVPcHRpb25zID0gb3B0aW9ucy5lbGVtZW50cy5saW5lO1xyXG5cdFx0dmFyIHZhbHVlcyA9IGNvcmVfZGF0YXNldENvbnRyb2xsZXIucHJvdG90eXBlLl9yZXNvbHZlRGF0YXNldEVsZW1lbnRPcHRpb25zLmFwcGx5KG1lLCBhcmd1bWVudHMpO1xyXG5cclxuXHRcdC8vIFRoZSBkZWZhdWx0IGJlaGF2aW9yIG9mIGxpbmVzIGlzIHRvIGJyZWFrIGF0IG51bGwgdmFsdWVzLCBhY2NvcmRpbmdcclxuXHRcdC8vIHRvIGh0dHBzOi8vZ2l0aHViLmNvbS9jaGFydGpzL0NoYXJ0LmpzL2lzc3Vlcy8yNDM1I2lzc3VlY29tbWVudC0yMTY3MTgxNThcclxuXHRcdC8vIFRoaXMgb3B0aW9uIGdpdmVzIGxpbmVzIHRoZSBhYmlsaXR5IHRvIHNwYW4gZ2Fwc1xyXG5cdFx0dmFsdWVzLnNwYW5HYXBzID0gdmFsdWVPckRlZmF1bHQkNihjb25maWcuc3BhbkdhcHMsIG9wdGlvbnMuc3BhbkdhcHMpO1xyXG5cdFx0dmFsdWVzLnRlbnNpb24gPSB2YWx1ZU9yRGVmYXVsdCQ2KGNvbmZpZy5saW5lVGVuc2lvbiwgbGluZU9wdGlvbnMudGVuc2lvbik7XHJcblx0XHR2YWx1ZXMuc3RlcHBlZExpbmUgPSByZXNvbHZlJDIoW2N1c3RvbS5zdGVwcGVkTGluZSwgY29uZmlnLnN0ZXBwZWRMaW5lLCBsaW5lT3B0aW9ucy5zdGVwcGVkXSk7XHJcblx0XHR2YWx1ZXMuY2xpcCA9IHRvQ2xpcCh2YWx1ZU9yRGVmYXVsdCQ2KGNvbmZpZy5jbGlwLCBkZWZhdWx0Q2xpcChtZS5feFNjYWxlLCBtZS5feVNjYWxlLCB2YWx1ZXMuYm9yZGVyV2lkdGgpKSk7XHJcblxyXG5cdFx0cmV0dXJuIHZhbHVlcztcclxuXHR9LFxyXG5cclxuXHRjYWxjdWxhdGVQb2ludFk6IGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgZGF0YXNldEluZGV4KSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0dmFyIGNoYXJ0ID0gbWUuY2hhcnQ7XHJcblx0XHR2YXIgeVNjYWxlID0gbWUuX3lTY2FsZTtcclxuXHRcdHZhciBzdW1Qb3MgPSAwO1xyXG5cdFx0dmFyIHN1bU5lZyA9IDA7XHJcblx0XHR2YXIgaSwgZHMsIGRzTWV0YSwgc3RhY2tlZFJpZ2h0VmFsdWUsIHJpZ2h0VmFsdWUsIG1ldGFzZXRzLCBpbGVuO1xyXG5cclxuXHRcdGlmICh5U2NhbGUub3B0aW9ucy5zdGFja2VkKSB7XHJcblx0XHRcdHJpZ2h0VmFsdWUgPSAreVNjYWxlLmdldFJpZ2h0VmFsdWUodmFsdWUpO1xyXG5cdFx0XHRtZXRhc2V0cyA9IGNoYXJ0Ll9nZXRTb3J0ZWRWaXNpYmxlRGF0YXNldE1ldGFzKCk7XHJcblx0XHRcdGlsZW4gPSBtZXRhc2V0cy5sZW5ndGg7XHJcblxyXG5cdFx0XHRmb3IgKGkgPSAwOyBpIDwgaWxlbjsgKytpKSB7XHJcblx0XHRcdFx0ZHNNZXRhID0gbWV0YXNldHNbaV07XHJcblx0XHRcdFx0aWYgKGRzTWV0YS5pbmRleCA9PT0gZGF0YXNldEluZGV4KSB7XHJcblx0XHRcdFx0XHRicmVhaztcclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdGRzID0gY2hhcnQuZGF0YS5kYXRhc2V0c1tkc01ldGEuaW5kZXhdO1xyXG5cdFx0XHRcdGlmIChkc01ldGEudHlwZSA9PT0gJ2xpbmUnICYmIGRzTWV0YS55QXhpc0lEID09PSB5U2NhbGUuaWQpIHtcclxuXHRcdFx0XHRcdHN0YWNrZWRSaWdodFZhbHVlID0gK3lTY2FsZS5nZXRSaWdodFZhbHVlKGRzLmRhdGFbaW5kZXhdKTtcclxuXHRcdFx0XHRcdGlmIChzdGFja2VkUmlnaHRWYWx1ZSA8IDApIHtcclxuXHRcdFx0XHRcdFx0c3VtTmVnICs9IHN0YWNrZWRSaWdodFZhbHVlIHx8IDA7XHJcblx0XHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0XHRzdW1Qb3MgKz0gc3RhY2tlZFJpZ2h0VmFsdWUgfHwgMDtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdGlmIChyaWdodFZhbHVlIDwgMCkge1xyXG5cdFx0XHRcdHJldHVybiB5U2NhbGUuZ2V0UGl4ZWxGb3JWYWx1ZShzdW1OZWcgKyByaWdodFZhbHVlKTtcclxuXHRcdFx0fVxyXG5cdFx0XHRyZXR1cm4geVNjYWxlLmdldFBpeGVsRm9yVmFsdWUoc3VtUG9zICsgcmlnaHRWYWx1ZSk7XHJcblx0XHR9XHJcblx0XHRyZXR1cm4geVNjYWxlLmdldFBpeGVsRm9yVmFsdWUodmFsdWUpO1xyXG5cdH0sXHJcblxyXG5cdHVwZGF0ZUJlemllckNvbnRyb2xQb2ludHM6IGZ1bmN0aW9uKCkge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHRcdHZhciBjaGFydCA9IG1lLmNoYXJ0O1xyXG5cdFx0dmFyIG1ldGEgPSBtZS5nZXRNZXRhKCk7XHJcblx0XHR2YXIgbGluZU1vZGVsID0gbWV0YS5kYXRhc2V0Ll9tb2RlbDtcclxuXHRcdHZhciBhcmVhID0gY2hhcnQuY2hhcnRBcmVhO1xyXG5cdFx0dmFyIHBvaW50cyA9IG1ldGEuZGF0YSB8fCBbXTtcclxuXHRcdHZhciBpLCBpbGVuLCBtb2RlbCwgY29udHJvbFBvaW50cztcclxuXHJcblx0XHQvLyBPbmx5IGNvbnNpZGVyIHBvaW50cyB0aGF0IGFyZSBkcmF3biBpbiBjYXNlIHRoZSBzcGFuR2FwcyBvcHRpb24gaXMgdXNlZFxyXG5cdFx0aWYgKGxpbmVNb2RlbC5zcGFuR2Fwcykge1xyXG5cdFx0XHRwb2ludHMgPSBwb2ludHMuZmlsdGVyKGZ1bmN0aW9uKHB0KSB7XHJcblx0XHRcdFx0cmV0dXJuICFwdC5fbW9kZWwuc2tpcDtcclxuXHRcdFx0fSk7XHJcblx0XHR9XHJcblxyXG5cdFx0ZnVuY3Rpb24gY2FwQ29udHJvbFBvaW50KHB0LCBtaW4sIG1heCkge1xyXG5cdFx0XHRyZXR1cm4gTWF0aC5tYXgoTWF0aC5taW4ocHQsIG1heCksIG1pbik7XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKGxpbmVNb2RlbC5jdWJpY0ludGVycG9sYXRpb25Nb2RlID09PSAnbW9ub3RvbmUnKSB7XHJcblx0XHRcdGhlbHBlcnMkMS5zcGxpbmVDdXJ2ZU1vbm90b25lKHBvaW50cyk7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRmb3IgKGkgPSAwLCBpbGVuID0gcG9pbnRzLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xyXG5cdFx0XHRcdG1vZGVsID0gcG9pbnRzW2ldLl9tb2RlbDtcclxuXHRcdFx0XHRjb250cm9sUG9pbnRzID0gaGVscGVycyQxLnNwbGluZUN1cnZlKFxyXG5cdFx0XHRcdFx0aGVscGVycyQxLnByZXZpb3VzSXRlbShwb2ludHMsIGkpLl9tb2RlbCxcclxuXHRcdFx0XHRcdG1vZGVsLFxyXG5cdFx0XHRcdFx0aGVscGVycyQxLm5leHRJdGVtKHBvaW50cywgaSkuX21vZGVsLFxyXG5cdFx0XHRcdFx0bGluZU1vZGVsLnRlbnNpb25cclxuXHRcdFx0XHQpO1xyXG5cdFx0XHRcdG1vZGVsLmNvbnRyb2xQb2ludFByZXZpb3VzWCA9IGNvbnRyb2xQb2ludHMucHJldmlvdXMueDtcclxuXHRcdFx0XHRtb2RlbC5jb250cm9sUG9pbnRQcmV2aW91c1kgPSBjb250cm9sUG9pbnRzLnByZXZpb3VzLnk7XHJcblx0XHRcdFx0bW9kZWwuY29udHJvbFBvaW50TmV4dFggPSBjb250cm9sUG9pbnRzLm5leHQueDtcclxuXHRcdFx0XHRtb2RlbC5jb250cm9sUG9pbnROZXh0WSA9IGNvbnRyb2xQb2ludHMubmV4dC55O1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKGNoYXJ0Lm9wdGlvbnMuZWxlbWVudHMubGluZS5jYXBCZXppZXJQb2ludHMpIHtcclxuXHRcdFx0Zm9yIChpID0gMCwgaWxlbiA9IHBvaW50cy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcclxuXHRcdFx0XHRtb2RlbCA9IHBvaW50c1tpXS5fbW9kZWw7XHJcblx0XHRcdFx0aWYgKGlzUG9pbnRJbkFyZWEobW9kZWwsIGFyZWEpKSB7XHJcblx0XHRcdFx0XHRpZiAoaSA+IDAgJiYgaXNQb2ludEluQXJlYShwb2ludHNbaSAtIDFdLl9tb2RlbCwgYXJlYSkpIHtcclxuXHRcdFx0XHRcdFx0bW9kZWwuY29udHJvbFBvaW50UHJldmlvdXNYID0gY2FwQ29udHJvbFBvaW50KG1vZGVsLmNvbnRyb2xQb2ludFByZXZpb3VzWCwgYXJlYS5sZWZ0LCBhcmVhLnJpZ2h0KTtcclxuXHRcdFx0XHRcdFx0bW9kZWwuY29udHJvbFBvaW50UHJldmlvdXNZID0gY2FwQ29udHJvbFBvaW50KG1vZGVsLmNvbnRyb2xQb2ludFByZXZpb3VzWSwgYXJlYS50b3AsIGFyZWEuYm90dG9tKTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdGlmIChpIDwgcG9pbnRzLmxlbmd0aCAtIDEgJiYgaXNQb2ludEluQXJlYShwb2ludHNbaSArIDFdLl9tb2RlbCwgYXJlYSkpIHtcclxuXHRcdFx0XHRcdFx0bW9kZWwuY29udHJvbFBvaW50TmV4dFggPSBjYXBDb250cm9sUG9pbnQobW9kZWwuY29udHJvbFBvaW50TmV4dFgsIGFyZWEubGVmdCwgYXJlYS5yaWdodCk7XHJcblx0XHRcdFx0XHRcdG1vZGVsLmNvbnRyb2xQb2ludE5leHRZID0gY2FwQ29udHJvbFBvaW50KG1vZGVsLmNvbnRyb2xQb2ludE5leHRZLCBhcmVhLnRvcCwgYXJlYS5ib3R0b20pO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdH0sXHJcblxyXG5cdGRyYXc6IGZ1bmN0aW9uKCkge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHRcdHZhciBjaGFydCA9IG1lLmNoYXJ0O1xyXG5cdFx0dmFyIG1ldGEgPSBtZS5nZXRNZXRhKCk7XHJcblx0XHR2YXIgcG9pbnRzID0gbWV0YS5kYXRhIHx8IFtdO1xyXG5cdFx0dmFyIGFyZWEgPSBjaGFydC5jaGFydEFyZWE7XHJcblx0XHR2YXIgY2FudmFzID0gY2hhcnQuY2FudmFzO1xyXG5cdFx0dmFyIGkgPSAwO1xyXG5cdFx0dmFyIGlsZW4gPSBwb2ludHMubGVuZ3RoO1xyXG5cdFx0dmFyIGNsaXA7XHJcblxyXG5cdFx0aWYgKG1lLl9zaG93TGluZSkge1xyXG5cdFx0XHRjbGlwID0gbWV0YS5kYXRhc2V0Ll9tb2RlbC5jbGlwO1xyXG5cclxuXHRcdFx0aGVscGVycyQxLmNhbnZhcy5jbGlwQXJlYShjaGFydC5jdHgsIHtcclxuXHRcdFx0XHRsZWZ0OiBjbGlwLmxlZnQgPT09IGZhbHNlID8gMCA6IGFyZWEubGVmdCAtIGNsaXAubGVmdCxcclxuXHRcdFx0XHRyaWdodDogY2xpcC5yaWdodCA9PT0gZmFsc2UgPyBjYW52YXMud2lkdGggOiBhcmVhLnJpZ2h0ICsgY2xpcC5yaWdodCxcclxuXHRcdFx0XHR0b3A6IGNsaXAudG9wID09PSBmYWxzZSA/IDAgOiBhcmVhLnRvcCAtIGNsaXAudG9wLFxyXG5cdFx0XHRcdGJvdHRvbTogY2xpcC5ib3R0b20gPT09IGZhbHNlID8gY2FudmFzLmhlaWdodCA6IGFyZWEuYm90dG9tICsgY2xpcC5ib3R0b21cclxuXHRcdFx0fSk7XHJcblxyXG5cdFx0XHRtZXRhLmRhdGFzZXQuZHJhdygpO1xyXG5cclxuXHRcdFx0aGVscGVycyQxLmNhbnZhcy51bmNsaXBBcmVhKGNoYXJ0LmN0eCk7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gRHJhdyB0aGUgcG9pbnRzXHJcblx0XHRmb3IgKDsgaSA8IGlsZW47ICsraSkge1xyXG5cdFx0XHRwb2ludHNbaV0uZHJhdyhhcmVhKTtcclxuXHRcdH1cclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBAcHJvdGVjdGVkXHJcblx0ICovXHJcblx0c2V0SG92ZXJTdHlsZTogZnVuY3Rpb24ocG9pbnQpIHtcclxuXHRcdHZhciBtb2RlbCA9IHBvaW50Ll9tb2RlbDtcclxuXHRcdHZhciBvcHRpb25zID0gcG9pbnQuX29wdGlvbnM7XHJcblx0XHR2YXIgZ2V0SG92ZXJDb2xvciA9IGhlbHBlcnMkMS5nZXRIb3ZlckNvbG9yO1xyXG5cclxuXHRcdHBvaW50LiRwcmV2aW91c1N0eWxlID0ge1xyXG5cdFx0XHRiYWNrZ3JvdW5kQ29sb3I6IG1vZGVsLmJhY2tncm91bmRDb2xvcixcclxuXHRcdFx0Ym9yZGVyQ29sb3I6IG1vZGVsLmJvcmRlckNvbG9yLFxyXG5cdFx0XHRib3JkZXJXaWR0aDogbW9kZWwuYm9yZGVyV2lkdGgsXHJcblx0XHRcdHJhZGl1czogbW9kZWwucmFkaXVzXHJcblx0XHR9O1xyXG5cclxuXHRcdG1vZGVsLmJhY2tncm91bmRDb2xvciA9IHZhbHVlT3JEZWZhdWx0JDYob3B0aW9ucy5ob3ZlckJhY2tncm91bmRDb2xvciwgZ2V0SG92ZXJDb2xvcihvcHRpb25zLmJhY2tncm91bmRDb2xvcikpO1xyXG5cdFx0bW9kZWwuYm9yZGVyQ29sb3IgPSB2YWx1ZU9yRGVmYXVsdCQ2KG9wdGlvbnMuaG92ZXJCb3JkZXJDb2xvciwgZ2V0SG92ZXJDb2xvcihvcHRpb25zLmJvcmRlckNvbG9yKSk7XHJcblx0XHRtb2RlbC5ib3JkZXJXaWR0aCA9IHZhbHVlT3JEZWZhdWx0JDYob3B0aW9ucy5ob3ZlckJvcmRlcldpZHRoLCBvcHRpb25zLmJvcmRlcldpZHRoKTtcclxuXHRcdG1vZGVsLnJhZGl1cyA9IHZhbHVlT3JEZWZhdWx0JDYob3B0aW9ucy5ob3ZlclJhZGl1cywgb3B0aW9ucy5yYWRpdXMpO1xyXG5cdH0sXHJcbn0pO1xuXG52YXIgcmVzb2x2ZSQzID0gaGVscGVycyQxLm9wdGlvbnMucmVzb2x2ZTtcclxuXHJcbmNvcmVfZGVmYXVsdHMuX3NldCgncG9sYXJBcmVhJywge1xyXG5cdHNjYWxlOiB7XHJcblx0XHR0eXBlOiAncmFkaWFsTGluZWFyJyxcclxuXHRcdGFuZ2xlTGluZXM6IHtcclxuXHRcdFx0ZGlzcGxheTogZmFsc2VcclxuXHRcdH0sXHJcblx0XHRncmlkTGluZXM6IHtcclxuXHRcdFx0Y2lyY3VsYXI6IHRydWVcclxuXHRcdH0sXHJcblx0XHRwb2ludExhYmVsczoge1xyXG5cdFx0XHRkaXNwbGF5OiBmYWxzZVxyXG5cdFx0fSxcclxuXHRcdHRpY2tzOiB7XHJcblx0XHRcdGJlZ2luQXRaZXJvOiB0cnVlXHJcblx0XHR9XHJcblx0fSxcclxuXHJcblx0Ly8gQm9vbGVhbiAtIFdoZXRoZXIgdG8gYW5pbWF0ZSB0aGUgcm90YXRpb24gb2YgdGhlIGNoYXJ0XHJcblx0YW5pbWF0aW9uOiB7XHJcblx0XHRhbmltYXRlUm90YXRlOiB0cnVlLFxyXG5cdFx0YW5pbWF0ZVNjYWxlOiB0cnVlXHJcblx0fSxcclxuXHJcblx0c3RhcnRBbmdsZTogLTAuNSAqIE1hdGguUEksXHJcblx0bGVnZW5kQ2FsbGJhY2s6IGZ1bmN0aW9uKGNoYXJ0KSB7XHJcblx0XHR2YXIgbGlzdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3VsJyk7XHJcblx0XHR2YXIgZGF0YSA9IGNoYXJ0LmRhdGE7XHJcblx0XHR2YXIgZGF0YXNldHMgPSBkYXRhLmRhdGFzZXRzO1xyXG5cdFx0dmFyIGxhYmVscyA9IGRhdGEubGFiZWxzO1xyXG5cdFx0dmFyIGksIGlsZW4sIGxpc3RJdGVtLCBsaXN0SXRlbVNwYW47XHJcblxyXG5cdFx0bGlzdC5zZXRBdHRyaWJ1dGUoJ2NsYXNzJywgY2hhcnQuaWQgKyAnLWxlZ2VuZCcpO1xyXG5cdFx0aWYgKGRhdGFzZXRzLmxlbmd0aCkge1xyXG5cdFx0XHRmb3IgKGkgPSAwLCBpbGVuID0gZGF0YXNldHNbMF0uZGF0YS5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcclxuXHRcdFx0XHRsaXN0SXRlbSA9IGxpc3QuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnbGknKSk7XHJcblx0XHRcdFx0bGlzdEl0ZW1TcGFuID0gbGlzdEl0ZW0uYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpKTtcclxuXHRcdFx0XHRsaXN0SXRlbVNwYW4uc3R5bGUuYmFja2dyb3VuZENvbG9yID0gZGF0YXNldHNbMF0uYmFja2dyb3VuZENvbG9yW2ldO1xyXG5cdFx0XHRcdGlmIChsYWJlbHNbaV0pIHtcclxuXHRcdFx0XHRcdGxpc3RJdGVtLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKGxhYmVsc1tpXSkpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiBsaXN0Lm91dGVySFRNTDtcclxuXHR9LFxyXG5cdGxlZ2VuZDoge1xyXG5cdFx0bGFiZWxzOiB7XHJcblx0XHRcdGdlbmVyYXRlTGFiZWxzOiBmdW5jdGlvbihjaGFydCkge1xyXG5cdFx0XHRcdHZhciBkYXRhID0gY2hhcnQuZGF0YTtcclxuXHRcdFx0XHRpZiAoZGF0YS5sYWJlbHMubGVuZ3RoICYmIGRhdGEuZGF0YXNldHMubGVuZ3RoKSB7XHJcblx0XHRcdFx0XHRyZXR1cm4gZGF0YS5sYWJlbHMubWFwKGZ1bmN0aW9uKGxhYmVsLCBpKSB7XHJcblx0XHRcdFx0XHRcdHZhciBtZXRhID0gY2hhcnQuZ2V0RGF0YXNldE1ldGEoMCk7XHJcblx0XHRcdFx0XHRcdHZhciBzdHlsZSA9IG1ldGEuY29udHJvbGxlci5nZXRTdHlsZShpKTtcclxuXHJcblx0XHRcdFx0XHRcdHJldHVybiB7XHJcblx0XHRcdFx0XHRcdFx0dGV4dDogbGFiZWwsXHJcblx0XHRcdFx0XHRcdFx0ZmlsbFN0eWxlOiBzdHlsZS5iYWNrZ3JvdW5kQ29sb3IsXHJcblx0XHRcdFx0XHRcdFx0c3Ryb2tlU3R5bGU6IHN0eWxlLmJvcmRlckNvbG9yLFxyXG5cdFx0XHRcdFx0XHRcdGxpbmVXaWR0aDogc3R5bGUuYm9yZGVyV2lkdGgsXHJcblx0XHRcdFx0XHRcdFx0aGlkZGVuOiBpc05hTihkYXRhLmRhdGFzZXRzWzBdLmRhdGFbaV0pIHx8IG1ldGEuZGF0YVtpXS5oaWRkZW4sXHJcblxyXG5cdFx0XHRcdFx0XHRcdC8vIEV4dHJhIGRhdGEgdXNlZCBmb3IgdG9nZ2xpbmcgdGhlIGNvcnJlY3QgaXRlbVxyXG5cdFx0XHRcdFx0XHRcdGluZGV4OiBpXHJcblx0XHRcdFx0XHRcdH07XHJcblx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0cmV0dXJuIFtdO1xyXG5cdFx0XHR9XHJcblx0XHR9LFxyXG5cclxuXHRcdG9uQ2xpY2s6IGZ1bmN0aW9uKGUsIGxlZ2VuZEl0ZW0pIHtcclxuXHRcdFx0dmFyIGluZGV4ID0gbGVnZW5kSXRlbS5pbmRleDtcclxuXHRcdFx0dmFyIGNoYXJ0ID0gdGhpcy5jaGFydDtcclxuXHRcdFx0dmFyIGksIGlsZW4sIG1ldGE7XHJcblxyXG5cdFx0XHRmb3IgKGkgPSAwLCBpbGVuID0gKGNoYXJ0LmRhdGEuZGF0YXNldHMgfHwgW10pLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xyXG5cdFx0XHRcdG1ldGEgPSBjaGFydC5nZXREYXRhc2V0TWV0YShpKTtcclxuXHRcdFx0XHRtZXRhLmRhdGFbaW5kZXhdLmhpZGRlbiA9ICFtZXRhLmRhdGFbaW5kZXhdLmhpZGRlbjtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Y2hhcnQudXBkYXRlKCk7XHJcblx0XHR9XHJcblx0fSxcclxuXHJcblx0Ly8gTmVlZCB0byBvdmVycmlkZSB0aGVzZSB0byBnaXZlIGEgbmljZSBkZWZhdWx0XHJcblx0dG9vbHRpcHM6IHtcclxuXHRcdGNhbGxiYWNrczoge1xyXG5cdFx0XHR0aXRsZTogZnVuY3Rpb24oKSB7XHJcblx0XHRcdFx0cmV0dXJuICcnO1xyXG5cdFx0XHR9LFxyXG5cdFx0XHRsYWJlbDogZnVuY3Rpb24oaXRlbSwgZGF0YSkge1xyXG5cdFx0XHRcdHJldHVybiBkYXRhLmxhYmVsc1tpdGVtLmluZGV4XSArICc6ICcgKyBpdGVtLnlMYWJlbDtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdH1cclxufSk7XHJcblxyXG52YXIgY29udHJvbGxlcl9wb2xhckFyZWEgPSBjb3JlX2RhdGFzZXRDb250cm9sbGVyLmV4dGVuZCh7XHJcblxyXG5cdGRhdGFFbGVtZW50VHlwZTogZWxlbWVudHMuQXJjLFxyXG5cclxuXHRsaW5rU2NhbGVzOiBoZWxwZXJzJDEubm9vcCxcclxuXHJcblx0LyoqXHJcblx0ICogQHByaXZhdGVcclxuXHQgKi9cclxuXHRfZGF0YUVsZW1lbnRPcHRpb25zOiBbXHJcblx0XHQnYmFja2dyb3VuZENvbG9yJyxcclxuXHRcdCdib3JkZXJDb2xvcicsXHJcblx0XHQnYm9yZGVyV2lkdGgnLFxyXG5cdFx0J2JvcmRlckFsaWduJyxcclxuXHRcdCdob3ZlckJhY2tncm91bmRDb2xvcicsXHJcblx0XHQnaG92ZXJCb3JkZXJDb2xvcicsXHJcblx0XHQnaG92ZXJCb3JkZXJXaWR0aCcsXHJcblx0XSxcclxuXHJcblx0LyoqXHJcblx0ICogQHByaXZhdGVcclxuXHQgKi9cclxuXHRfZ2V0SW5kZXhTY2FsZUlkOiBmdW5jdGlvbigpIHtcclxuXHRcdHJldHVybiB0aGlzLmNoYXJ0LnNjYWxlLmlkO1xyXG5cdH0sXHJcblxyXG5cdC8qKlxyXG5cdCAqIEBwcml2YXRlXHJcblx0ICovXHJcblx0X2dldFZhbHVlU2NhbGVJZDogZnVuY3Rpb24oKSB7XHJcblx0XHRyZXR1cm4gdGhpcy5jaGFydC5zY2FsZS5pZDtcclxuXHR9LFxyXG5cclxuXHR1cGRhdGU6IGZ1bmN0aW9uKHJlc2V0KSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0dmFyIGRhdGFzZXQgPSBtZS5nZXREYXRhc2V0KCk7XHJcblx0XHR2YXIgbWV0YSA9IG1lLmdldE1ldGEoKTtcclxuXHRcdHZhciBzdGFydCA9IG1lLmNoYXJ0Lm9wdGlvbnMuc3RhcnRBbmdsZSB8fCAwO1xyXG5cdFx0dmFyIHN0YXJ0cyA9IG1lLl9zdGFydHMgPSBbXTtcclxuXHRcdHZhciBhbmdsZXMgPSBtZS5fYW5nbGVzID0gW107XHJcblx0XHR2YXIgYXJjcyA9IG1ldGEuZGF0YTtcclxuXHRcdHZhciBpLCBpbGVuLCBhbmdsZTtcclxuXHJcblx0XHRtZS5fdXBkYXRlUmFkaXVzKCk7XHJcblxyXG5cdFx0bWV0YS5jb3VudCA9IG1lLmNvdW50VmlzaWJsZUVsZW1lbnRzKCk7XHJcblxyXG5cdFx0Zm9yIChpID0gMCwgaWxlbiA9IGRhdGFzZXQuZGF0YS5sZW5ndGg7IGkgPCBpbGVuOyBpKyspIHtcclxuXHRcdFx0c3RhcnRzW2ldID0gc3RhcnQ7XHJcblx0XHRcdGFuZ2xlID0gbWUuX2NvbXB1dGVBbmdsZShpKTtcclxuXHRcdFx0YW5nbGVzW2ldID0gYW5nbGU7XHJcblx0XHRcdHN0YXJ0ICs9IGFuZ2xlO1xyXG5cdFx0fVxyXG5cclxuXHRcdGZvciAoaSA9IDAsIGlsZW4gPSBhcmNzLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xyXG5cdFx0XHRhcmNzW2ldLl9vcHRpb25zID0gbWUuX3Jlc29sdmVEYXRhRWxlbWVudE9wdGlvbnMoYXJjc1tpXSwgaSk7XHJcblx0XHRcdG1lLnVwZGF0ZUVsZW1lbnQoYXJjc1tpXSwgaSwgcmVzZXQpO1xyXG5cdFx0fVxyXG5cdH0sXHJcblxyXG5cdC8qKlxyXG5cdCAqIEBwcml2YXRlXHJcblx0ICovXHJcblx0X3VwZGF0ZVJhZGl1czogZnVuY3Rpb24oKSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0dmFyIGNoYXJ0ID0gbWUuY2hhcnQ7XHJcblx0XHR2YXIgY2hhcnRBcmVhID0gY2hhcnQuY2hhcnRBcmVhO1xyXG5cdFx0dmFyIG9wdHMgPSBjaGFydC5vcHRpb25zO1xyXG5cdFx0dmFyIG1pblNpemUgPSBNYXRoLm1pbihjaGFydEFyZWEucmlnaHQgLSBjaGFydEFyZWEubGVmdCwgY2hhcnRBcmVhLmJvdHRvbSAtIGNoYXJ0QXJlYS50b3ApO1xyXG5cclxuXHRcdGNoYXJ0Lm91dGVyUmFkaXVzID0gTWF0aC5tYXgobWluU2l6ZSAvIDIsIDApO1xyXG5cdFx0Y2hhcnQuaW5uZXJSYWRpdXMgPSBNYXRoLm1heChvcHRzLmN1dG91dFBlcmNlbnRhZ2UgPyAoY2hhcnQub3V0ZXJSYWRpdXMgLyAxMDApICogKG9wdHMuY3V0b3V0UGVyY2VudGFnZSkgOiAxLCAwKTtcclxuXHRcdGNoYXJ0LnJhZGl1c0xlbmd0aCA9IChjaGFydC5vdXRlclJhZGl1cyAtIGNoYXJ0LmlubmVyUmFkaXVzKSAvIGNoYXJ0LmdldFZpc2libGVEYXRhc2V0Q291bnQoKTtcclxuXHJcblx0XHRtZS5vdXRlclJhZGl1cyA9IGNoYXJ0Lm91dGVyUmFkaXVzIC0gKGNoYXJ0LnJhZGl1c0xlbmd0aCAqIG1lLmluZGV4KTtcclxuXHRcdG1lLmlubmVyUmFkaXVzID0gbWUub3V0ZXJSYWRpdXMgLSBjaGFydC5yYWRpdXNMZW5ndGg7XHJcblx0fSxcclxuXHJcblx0dXBkYXRlRWxlbWVudDogZnVuY3Rpb24oYXJjLCBpbmRleCwgcmVzZXQpIHtcclxuXHRcdHZhciBtZSA9IHRoaXM7XHJcblx0XHR2YXIgY2hhcnQgPSBtZS5jaGFydDtcclxuXHRcdHZhciBkYXRhc2V0ID0gbWUuZ2V0RGF0YXNldCgpO1xyXG5cdFx0dmFyIG9wdHMgPSBjaGFydC5vcHRpb25zO1xyXG5cdFx0dmFyIGFuaW1hdGlvbk9wdHMgPSBvcHRzLmFuaW1hdGlvbjtcclxuXHRcdHZhciBzY2FsZSA9IGNoYXJ0LnNjYWxlO1xyXG5cdFx0dmFyIGxhYmVscyA9IGNoYXJ0LmRhdGEubGFiZWxzO1xyXG5cclxuXHRcdHZhciBjZW50ZXJYID0gc2NhbGUueENlbnRlcjtcclxuXHRcdHZhciBjZW50ZXJZID0gc2NhbGUueUNlbnRlcjtcclxuXHJcblx0XHQvLyB2YXIgbmVnSGFsZlBJID0gLTAuNSAqIE1hdGguUEk7XHJcblx0XHR2YXIgZGF0YXNldFN0YXJ0QW5nbGUgPSBvcHRzLnN0YXJ0QW5nbGU7XHJcblx0XHR2YXIgZGlzdGFuY2UgPSBhcmMuaGlkZGVuID8gMCA6IHNjYWxlLmdldERpc3RhbmNlRnJvbUNlbnRlckZvclZhbHVlKGRhdGFzZXQuZGF0YVtpbmRleF0pO1xyXG5cdFx0dmFyIHN0YXJ0QW5nbGUgPSBtZS5fc3RhcnRzW2luZGV4XTtcclxuXHRcdHZhciBlbmRBbmdsZSA9IHN0YXJ0QW5nbGUgKyAoYXJjLmhpZGRlbiA/IDAgOiBtZS5fYW5nbGVzW2luZGV4XSk7XHJcblxyXG5cdFx0dmFyIHJlc2V0UmFkaXVzID0gYW5pbWF0aW9uT3B0cy5hbmltYXRlU2NhbGUgPyAwIDogc2NhbGUuZ2V0RGlzdGFuY2VGcm9tQ2VudGVyRm9yVmFsdWUoZGF0YXNldC5kYXRhW2luZGV4XSk7XHJcblx0XHR2YXIgb3B0aW9ucyA9IGFyYy5fb3B0aW9ucyB8fCB7fTtcclxuXHJcblx0XHRoZWxwZXJzJDEuZXh0ZW5kKGFyYywge1xyXG5cdFx0XHQvLyBVdGlsaXR5XHJcblx0XHRcdF9kYXRhc2V0SW5kZXg6IG1lLmluZGV4LFxyXG5cdFx0XHRfaW5kZXg6IGluZGV4LFxyXG5cdFx0XHRfc2NhbGU6IHNjYWxlLFxyXG5cclxuXHRcdFx0Ly8gRGVzaXJlZCB2aWV3IHByb3BlcnRpZXNcclxuXHRcdFx0X21vZGVsOiB7XHJcblx0XHRcdFx0YmFja2dyb3VuZENvbG9yOiBvcHRpb25zLmJhY2tncm91bmRDb2xvcixcclxuXHRcdFx0XHRib3JkZXJDb2xvcjogb3B0aW9ucy5ib3JkZXJDb2xvcixcclxuXHRcdFx0XHRib3JkZXJXaWR0aDogb3B0aW9ucy5ib3JkZXJXaWR0aCxcclxuXHRcdFx0XHRib3JkZXJBbGlnbjogb3B0aW9ucy5ib3JkZXJBbGlnbixcclxuXHRcdFx0XHR4OiBjZW50ZXJYLFxyXG5cdFx0XHRcdHk6IGNlbnRlclksXHJcblx0XHRcdFx0aW5uZXJSYWRpdXM6IDAsXHJcblx0XHRcdFx0b3V0ZXJSYWRpdXM6IHJlc2V0ID8gcmVzZXRSYWRpdXMgOiBkaXN0YW5jZSxcclxuXHRcdFx0XHRzdGFydEFuZ2xlOiByZXNldCAmJiBhbmltYXRpb25PcHRzLmFuaW1hdGVSb3RhdGUgPyBkYXRhc2V0U3RhcnRBbmdsZSA6IHN0YXJ0QW5nbGUsXHJcblx0XHRcdFx0ZW5kQW5nbGU6IHJlc2V0ICYmIGFuaW1hdGlvbk9wdHMuYW5pbWF0ZVJvdGF0ZSA/IGRhdGFzZXRTdGFydEFuZ2xlIDogZW5kQW5nbGUsXHJcblx0XHRcdFx0bGFiZWw6IGhlbHBlcnMkMS52YWx1ZUF0SW5kZXhPckRlZmF1bHQobGFiZWxzLCBpbmRleCwgbGFiZWxzW2luZGV4XSlcclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblxyXG5cdFx0YXJjLnBpdm90KCk7XHJcblx0fSxcclxuXHJcblx0Y291bnRWaXNpYmxlRWxlbWVudHM6IGZ1bmN0aW9uKCkge1xyXG5cdFx0dmFyIGRhdGFzZXQgPSB0aGlzLmdldERhdGFzZXQoKTtcclxuXHRcdHZhciBtZXRhID0gdGhpcy5nZXRNZXRhKCk7XHJcblx0XHR2YXIgY291bnQgPSAwO1xyXG5cclxuXHRcdGhlbHBlcnMkMS5lYWNoKG1ldGEuZGF0YSwgZnVuY3Rpb24oZWxlbWVudCwgaW5kZXgpIHtcclxuXHRcdFx0aWYgKCFpc05hTihkYXRhc2V0LmRhdGFbaW5kZXhdKSAmJiAhZWxlbWVudC5oaWRkZW4pIHtcclxuXHRcdFx0XHRjb3VudCsrO1xyXG5cdFx0XHR9XHJcblx0XHR9KTtcclxuXHJcblx0XHRyZXR1cm4gY291bnQ7XHJcblx0fSxcclxuXHJcblx0LyoqXHJcblx0ICogQHByb3RlY3RlZFxyXG5cdCAqL1xyXG5cdHNldEhvdmVyU3R5bGU6IGZ1bmN0aW9uKGFyYykge1xyXG5cdFx0dmFyIG1vZGVsID0gYXJjLl9tb2RlbDtcclxuXHRcdHZhciBvcHRpb25zID0gYXJjLl9vcHRpb25zO1xyXG5cdFx0dmFyIGdldEhvdmVyQ29sb3IgPSBoZWxwZXJzJDEuZ2V0SG92ZXJDb2xvcjtcclxuXHRcdHZhciB2YWx1ZU9yRGVmYXVsdCA9IGhlbHBlcnMkMS52YWx1ZU9yRGVmYXVsdDtcclxuXHJcblx0XHRhcmMuJHByZXZpb3VzU3R5bGUgPSB7XHJcblx0XHRcdGJhY2tncm91bmRDb2xvcjogbW9kZWwuYmFja2dyb3VuZENvbG9yLFxyXG5cdFx0XHRib3JkZXJDb2xvcjogbW9kZWwuYm9yZGVyQ29sb3IsXHJcblx0XHRcdGJvcmRlcldpZHRoOiBtb2RlbC5ib3JkZXJXaWR0aCxcclxuXHRcdH07XHJcblxyXG5cdFx0bW9kZWwuYmFja2dyb3VuZENvbG9yID0gdmFsdWVPckRlZmF1bHQob3B0aW9ucy5ob3ZlckJhY2tncm91bmRDb2xvciwgZ2V0SG92ZXJDb2xvcihvcHRpb25zLmJhY2tncm91bmRDb2xvcikpO1xyXG5cdFx0bW9kZWwuYm9yZGVyQ29sb3IgPSB2YWx1ZU9yRGVmYXVsdChvcHRpb25zLmhvdmVyQm9yZGVyQ29sb3IsIGdldEhvdmVyQ29sb3Iob3B0aW9ucy5ib3JkZXJDb2xvcikpO1xyXG5cdFx0bW9kZWwuYm9yZGVyV2lkdGggPSB2YWx1ZU9yRGVmYXVsdChvcHRpb25zLmhvdmVyQm9yZGVyV2lkdGgsIG9wdGlvbnMuYm9yZGVyV2lkdGgpO1xyXG5cdH0sXHJcblxyXG5cdC8qKlxyXG5cdCAqIEBwcml2YXRlXHJcblx0ICovXHJcblx0X2NvbXB1dGVBbmdsZTogZnVuY3Rpb24oaW5kZXgpIHtcclxuXHRcdHZhciBtZSA9IHRoaXM7XHJcblx0XHR2YXIgY291bnQgPSB0aGlzLmdldE1ldGEoKS5jb3VudDtcclxuXHRcdHZhciBkYXRhc2V0ID0gbWUuZ2V0RGF0YXNldCgpO1xyXG5cdFx0dmFyIG1ldGEgPSBtZS5nZXRNZXRhKCk7XHJcblxyXG5cdFx0aWYgKGlzTmFOKGRhdGFzZXQuZGF0YVtpbmRleF0pIHx8IG1ldGEuZGF0YVtpbmRleF0uaGlkZGVuKSB7XHJcblx0XHRcdHJldHVybiAwO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIFNjcmlwdGFibGUgb3B0aW9uc1xyXG5cdFx0dmFyIGNvbnRleHQgPSB7XHJcblx0XHRcdGNoYXJ0OiBtZS5jaGFydCxcclxuXHRcdFx0ZGF0YUluZGV4OiBpbmRleCxcclxuXHRcdFx0ZGF0YXNldDogZGF0YXNldCxcclxuXHRcdFx0ZGF0YXNldEluZGV4OiBtZS5pbmRleFxyXG5cdFx0fTtcclxuXHJcblx0XHRyZXR1cm4gcmVzb2x2ZSQzKFtcclxuXHRcdFx0bWUuY2hhcnQub3B0aW9ucy5lbGVtZW50cy5hcmMuYW5nbGUsXHJcblx0XHRcdCgyICogTWF0aC5QSSkgLyBjb3VudFxyXG5cdFx0XSwgY29udGV4dCwgaW5kZXgpO1xyXG5cdH1cclxufSk7XG5cbmNvcmVfZGVmYXVsdHMuX3NldCgncGllJywgaGVscGVycyQxLmNsb25lKGNvcmVfZGVmYXVsdHMuZG91Z2hudXQpKTtcclxuY29yZV9kZWZhdWx0cy5fc2V0KCdwaWUnLCB7XHJcblx0Y3V0b3V0UGVyY2VudGFnZTogMFxyXG59KTtcclxuXHJcbi8vIFBpZSBjaGFydHMgYXJlIERvdWdobnV0IGNoYXJ0IHdpdGggZGlmZmVyZW50IGRlZmF1bHRzXHJcbnZhciBjb250cm9sbGVyX3BpZSA9IGNvbnRyb2xsZXJfZG91Z2hudXQ7XG5cbnZhciB2YWx1ZU9yRGVmYXVsdCQ3ID0gaGVscGVycyQxLnZhbHVlT3JEZWZhdWx0O1xyXG5cclxuY29yZV9kZWZhdWx0cy5fc2V0KCdyYWRhcicsIHtcclxuXHRzcGFuR2FwczogZmFsc2UsXHJcblx0c2NhbGU6IHtcclxuXHRcdHR5cGU6ICdyYWRpYWxMaW5lYXInXHJcblx0fSxcclxuXHRlbGVtZW50czoge1xyXG5cdFx0bGluZToge1xyXG5cdFx0XHRmaWxsOiAnc3RhcnQnLFxyXG5cdFx0XHR0ZW5zaW9uOiAwIC8vIG5vIGJlemllciBpbiByYWRhclxyXG5cdFx0fVxyXG5cdH1cclxufSk7XHJcblxyXG52YXIgY29udHJvbGxlcl9yYWRhciA9IGNvcmVfZGF0YXNldENvbnRyb2xsZXIuZXh0ZW5kKHtcclxuXHRkYXRhc2V0RWxlbWVudFR5cGU6IGVsZW1lbnRzLkxpbmUsXHJcblxyXG5cdGRhdGFFbGVtZW50VHlwZTogZWxlbWVudHMuUG9pbnQsXHJcblxyXG5cdGxpbmtTY2FsZXM6IGhlbHBlcnMkMS5ub29wLFxyXG5cclxuXHQvKipcclxuXHQgKiBAcHJpdmF0ZVxyXG5cdCAqL1xyXG5cdF9kYXRhc2V0RWxlbWVudE9wdGlvbnM6IFtcclxuXHRcdCdiYWNrZ3JvdW5kQ29sb3InLFxyXG5cdFx0J2JvcmRlcldpZHRoJyxcclxuXHRcdCdib3JkZXJDb2xvcicsXHJcblx0XHQnYm9yZGVyQ2FwU3R5bGUnLFxyXG5cdFx0J2JvcmRlckRhc2gnLFxyXG5cdFx0J2JvcmRlckRhc2hPZmZzZXQnLFxyXG5cdFx0J2JvcmRlckpvaW5TdHlsZScsXHJcblx0XHQnZmlsbCdcclxuXHRdLFxyXG5cclxuXHQvKipcclxuXHQgKiBAcHJpdmF0ZVxyXG5cdCAqL1xyXG5cdF9kYXRhRWxlbWVudE9wdGlvbnM6IHtcclxuXHRcdGJhY2tncm91bmRDb2xvcjogJ3BvaW50QmFja2dyb3VuZENvbG9yJyxcclxuXHRcdGJvcmRlckNvbG9yOiAncG9pbnRCb3JkZXJDb2xvcicsXHJcblx0XHRib3JkZXJXaWR0aDogJ3BvaW50Qm9yZGVyV2lkdGgnLFxyXG5cdFx0aGl0UmFkaXVzOiAncG9pbnRIaXRSYWRpdXMnLFxyXG5cdFx0aG92ZXJCYWNrZ3JvdW5kQ29sb3I6ICdwb2ludEhvdmVyQmFja2dyb3VuZENvbG9yJyxcclxuXHRcdGhvdmVyQm9yZGVyQ29sb3I6ICdwb2ludEhvdmVyQm9yZGVyQ29sb3InLFxyXG5cdFx0aG92ZXJCb3JkZXJXaWR0aDogJ3BvaW50SG92ZXJCb3JkZXJXaWR0aCcsXHJcblx0XHRob3ZlclJhZGl1czogJ3BvaW50SG92ZXJSYWRpdXMnLFxyXG5cdFx0cG9pbnRTdHlsZTogJ3BvaW50U3R5bGUnLFxyXG5cdFx0cmFkaXVzOiAncG9pbnRSYWRpdXMnLFxyXG5cdFx0cm90YXRpb246ICdwb2ludFJvdGF0aW9uJ1xyXG5cdH0sXHJcblxyXG5cdC8qKlxyXG5cdCAqIEBwcml2YXRlXHJcblx0ICovXHJcblx0X2dldEluZGV4U2NhbGVJZDogZnVuY3Rpb24oKSB7XHJcblx0XHRyZXR1cm4gdGhpcy5jaGFydC5zY2FsZS5pZDtcclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBAcHJpdmF0ZVxyXG5cdCAqL1xyXG5cdF9nZXRWYWx1ZVNjYWxlSWQ6IGZ1bmN0aW9uKCkge1xyXG5cdFx0cmV0dXJuIHRoaXMuY2hhcnQuc2NhbGUuaWQ7XHJcblx0fSxcclxuXHJcblx0dXBkYXRlOiBmdW5jdGlvbihyZXNldCkge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHRcdHZhciBtZXRhID0gbWUuZ2V0TWV0YSgpO1xyXG5cdFx0dmFyIGxpbmUgPSBtZXRhLmRhdGFzZXQ7XHJcblx0XHR2YXIgcG9pbnRzID0gbWV0YS5kYXRhIHx8IFtdO1xyXG5cdFx0dmFyIHNjYWxlID0gbWUuY2hhcnQuc2NhbGU7XHJcblx0XHR2YXIgY29uZmlnID0gbWUuX2NvbmZpZztcclxuXHRcdHZhciBpLCBpbGVuO1xyXG5cclxuXHRcdC8vIENvbXBhdGliaWxpdHk6IElmIHRoZSBwcm9wZXJ0aWVzIGFyZSBkZWZpbmVkIHdpdGggb25seSB0aGUgb2xkIG5hbWUsIHVzZSB0aG9zZSB2YWx1ZXNcclxuXHRcdGlmIChjb25maWcudGVuc2lvbiAhPT0gdW5kZWZpbmVkICYmIGNvbmZpZy5saW5lVGVuc2lvbiA9PT0gdW5kZWZpbmVkKSB7XHJcblx0XHRcdGNvbmZpZy5saW5lVGVuc2lvbiA9IGNvbmZpZy50ZW5zaW9uO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIFV0aWxpdHlcclxuXHRcdGxpbmUuX3NjYWxlID0gc2NhbGU7XHJcblx0XHRsaW5lLl9kYXRhc2V0SW5kZXggPSBtZS5pbmRleDtcclxuXHRcdC8vIERhdGFcclxuXHRcdGxpbmUuX2NoaWxkcmVuID0gcG9pbnRzO1xyXG5cdFx0bGluZS5fbG9vcCA9IHRydWU7XHJcblx0XHQvLyBNb2RlbFxyXG5cdFx0bGluZS5fbW9kZWwgPSBtZS5fcmVzb2x2ZURhdGFzZXRFbGVtZW50T3B0aW9ucyhsaW5lKTtcclxuXHJcblx0XHRsaW5lLnBpdm90KCk7XHJcblxyXG5cdFx0Ly8gVXBkYXRlIFBvaW50c1xyXG5cdFx0Zm9yIChpID0gMCwgaWxlbiA9IHBvaW50cy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcclxuXHRcdFx0bWUudXBkYXRlRWxlbWVudChwb2ludHNbaV0sIGksIHJlc2V0KTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBVcGRhdGUgYmV6aWVyIGNvbnRyb2wgcG9pbnRzXHJcblx0XHRtZS51cGRhdGVCZXppZXJDb250cm9sUG9pbnRzKCk7XHJcblxyXG5cdFx0Ly8gTm93IHBpdm90IHRoZSBwb2ludCBmb3IgYW5pbWF0aW9uXHJcblx0XHRmb3IgKGkgPSAwLCBpbGVuID0gcG9pbnRzLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xyXG5cdFx0XHRwb2ludHNbaV0ucGl2b3QoKTtcclxuXHRcdH1cclxuXHR9LFxyXG5cclxuXHR1cGRhdGVFbGVtZW50OiBmdW5jdGlvbihwb2ludCwgaW5kZXgsIHJlc2V0KSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0dmFyIGN1c3RvbSA9IHBvaW50LmN1c3RvbSB8fCB7fTtcclxuXHRcdHZhciBkYXRhc2V0ID0gbWUuZ2V0RGF0YXNldCgpO1xyXG5cdFx0dmFyIHNjYWxlID0gbWUuY2hhcnQuc2NhbGU7XHJcblx0XHR2YXIgcG9pbnRQb3NpdGlvbiA9IHNjYWxlLmdldFBvaW50UG9zaXRpb25Gb3JWYWx1ZShpbmRleCwgZGF0YXNldC5kYXRhW2luZGV4XSk7XHJcblx0XHR2YXIgb3B0aW9ucyA9IG1lLl9yZXNvbHZlRGF0YUVsZW1lbnRPcHRpb25zKHBvaW50LCBpbmRleCk7XHJcblx0XHR2YXIgbGluZU1vZGVsID0gbWUuZ2V0TWV0YSgpLmRhdGFzZXQuX21vZGVsO1xyXG5cdFx0dmFyIHggPSByZXNldCA/IHNjYWxlLnhDZW50ZXIgOiBwb2ludFBvc2l0aW9uLng7XHJcblx0XHR2YXIgeSA9IHJlc2V0ID8gc2NhbGUueUNlbnRlciA6IHBvaW50UG9zaXRpb24ueTtcclxuXHJcblx0XHQvLyBVdGlsaXR5XHJcblx0XHRwb2ludC5fc2NhbGUgPSBzY2FsZTtcclxuXHRcdHBvaW50Ll9vcHRpb25zID0gb3B0aW9ucztcclxuXHRcdHBvaW50Ll9kYXRhc2V0SW5kZXggPSBtZS5pbmRleDtcclxuXHRcdHBvaW50Ll9pbmRleCA9IGluZGV4O1xyXG5cclxuXHRcdC8vIERlc2lyZWQgdmlldyBwcm9wZXJ0aWVzXHJcblx0XHRwb2ludC5fbW9kZWwgPSB7XHJcblx0XHRcdHg6IHgsIC8vIHZhbHVlIG5vdCB1c2VkIGluIGRhdGFzZXQgc2NhbGUsIGJ1dCB3ZSB3YW50IGEgY29uc2lzdGVudCBBUEkgYmV0d2VlbiBzY2FsZXNcclxuXHRcdFx0eTogeSxcclxuXHRcdFx0c2tpcDogY3VzdG9tLnNraXAgfHwgaXNOYU4oeCkgfHwgaXNOYU4oeSksXHJcblx0XHRcdC8vIEFwcGVhcmFuY2VcclxuXHRcdFx0cmFkaXVzOiBvcHRpb25zLnJhZGl1cyxcclxuXHRcdFx0cG9pbnRTdHlsZTogb3B0aW9ucy5wb2ludFN0eWxlLFxyXG5cdFx0XHRyb3RhdGlvbjogb3B0aW9ucy5yb3RhdGlvbixcclxuXHRcdFx0YmFja2dyb3VuZENvbG9yOiBvcHRpb25zLmJhY2tncm91bmRDb2xvcixcclxuXHRcdFx0Ym9yZGVyQ29sb3I6IG9wdGlvbnMuYm9yZGVyQ29sb3IsXHJcblx0XHRcdGJvcmRlcldpZHRoOiBvcHRpb25zLmJvcmRlcldpZHRoLFxyXG5cdFx0XHR0ZW5zaW9uOiB2YWx1ZU9yRGVmYXVsdCQ3KGN1c3RvbS50ZW5zaW9uLCBsaW5lTW9kZWwgPyBsaW5lTW9kZWwudGVuc2lvbiA6IDApLFxyXG5cclxuXHRcdFx0Ly8gVG9vbHRpcFxyXG5cdFx0XHRoaXRSYWRpdXM6IG9wdGlvbnMuaGl0UmFkaXVzXHJcblx0XHR9O1xyXG5cdH0sXHJcblxyXG5cdC8qKlxyXG5cdCAqIEBwcml2YXRlXHJcblx0ICovXHJcblx0X3Jlc29sdmVEYXRhc2V0RWxlbWVudE9wdGlvbnM6IGZ1bmN0aW9uKCkge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHRcdHZhciBjb25maWcgPSBtZS5fY29uZmlnO1xyXG5cdFx0dmFyIG9wdGlvbnMgPSBtZS5jaGFydC5vcHRpb25zO1xyXG5cdFx0dmFyIHZhbHVlcyA9IGNvcmVfZGF0YXNldENvbnRyb2xsZXIucHJvdG90eXBlLl9yZXNvbHZlRGF0YXNldEVsZW1lbnRPcHRpb25zLmFwcGx5KG1lLCBhcmd1bWVudHMpO1xyXG5cclxuXHRcdHZhbHVlcy5zcGFuR2FwcyA9IHZhbHVlT3JEZWZhdWx0JDcoY29uZmlnLnNwYW5HYXBzLCBvcHRpb25zLnNwYW5HYXBzKTtcclxuXHRcdHZhbHVlcy50ZW5zaW9uID0gdmFsdWVPckRlZmF1bHQkNyhjb25maWcubGluZVRlbnNpb24sIG9wdGlvbnMuZWxlbWVudHMubGluZS50ZW5zaW9uKTtcclxuXHJcblx0XHRyZXR1cm4gdmFsdWVzO1xyXG5cdH0sXHJcblxyXG5cdHVwZGF0ZUJlemllckNvbnRyb2xQb2ludHM6IGZ1bmN0aW9uKCkge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHRcdHZhciBtZXRhID0gbWUuZ2V0TWV0YSgpO1xyXG5cdFx0dmFyIGFyZWEgPSBtZS5jaGFydC5jaGFydEFyZWE7XHJcblx0XHR2YXIgcG9pbnRzID0gbWV0YS5kYXRhIHx8IFtdO1xyXG5cdFx0dmFyIGksIGlsZW4sIG1vZGVsLCBjb250cm9sUG9pbnRzO1xyXG5cclxuXHRcdC8vIE9ubHkgY29uc2lkZXIgcG9pbnRzIHRoYXQgYXJlIGRyYXduIGluIGNhc2UgdGhlIHNwYW5HYXBzIG9wdGlvbiBpcyB1c2VkXHJcblx0XHRpZiAobWV0YS5kYXRhc2V0Ll9tb2RlbC5zcGFuR2Fwcykge1xyXG5cdFx0XHRwb2ludHMgPSBwb2ludHMuZmlsdGVyKGZ1bmN0aW9uKHB0KSB7XHJcblx0XHRcdFx0cmV0dXJuICFwdC5fbW9kZWwuc2tpcDtcclxuXHRcdFx0fSk7XHJcblx0XHR9XHJcblxyXG5cdFx0ZnVuY3Rpb24gY2FwQ29udHJvbFBvaW50KHB0LCBtaW4sIG1heCkge1xyXG5cdFx0XHRyZXR1cm4gTWF0aC5tYXgoTWF0aC5taW4ocHQsIG1heCksIG1pbik7XHJcblx0XHR9XHJcblxyXG5cdFx0Zm9yIChpID0gMCwgaWxlbiA9IHBvaW50cy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcclxuXHRcdFx0bW9kZWwgPSBwb2ludHNbaV0uX21vZGVsO1xyXG5cdFx0XHRjb250cm9sUG9pbnRzID0gaGVscGVycyQxLnNwbGluZUN1cnZlKFxyXG5cdFx0XHRcdGhlbHBlcnMkMS5wcmV2aW91c0l0ZW0ocG9pbnRzLCBpLCB0cnVlKS5fbW9kZWwsXHJcblx0XHRcdFx0bW9kZWwsXHJcblx0XHRcdFx0aGVscGVycyQxLm5leHRJdGVtKHBvaW50cywgaSwgdHJ1ZSkuX21vZGVsLFxyXG5cdFx0XHRcdG1vZGVsLnRlbnNpb25cclxuXHRcdFx0KTtcclxuXHJcblx0XHRcdC8vIFByZXZlbnQgdGhlIGJlemllciBnb2luZyBvdXRzaWRlIG9mIHRoZSBib3VuZHMgb2YgdGhlIGdyYXBoXHJcblx0XHRcdG1vZGVsLmNvbnRyb2xQb2ludFByZXZpb3VzWCA9IGNhcENvbnRyb2xQb2ludChjb250cm9sUG9pbnRzLnByZXZpb3VzLngsIGFyZWEubGVmdCwgYXJlYS5yaWdodCk7XHJcblx0XHRcdG1vZGVsLmNvbnRyb2xQb2ludFByZXZpb3VzWSA9IGNhcENvbnRyb2xQb2ludChjb250cm9sUG9pbnRzLnByZXZpb3VzLnksIGFyZWEudG9wLCBhcmVhLmJvdHRvbSk7XHJcblx0XHRcdG1vZGVsLmNvbnRyb2xQb2ludE5leHRYID0gY2FwQ29udHJvbFBvaW50KGNvbnRyb2xQb2ludHMubmV4dC54LCBhcmVhLmxlZnQsIGFyZWEucmlnaHQpO1xyXG5cdFx0XHRtb2RlbC5jb250cm9sUG9pbnROZXh0WSA9IGNhcENvbnRyb2xQb2ludChjb250cm9sUG9pbnRzLm5leHQueSwgYXJlYS50b3AsIGFyZWEuYm90dG9tKTtcclxuXHRcdH1cclxuXHR9LFxyXG5cclxuXHRzZXRIb3ZlclN0eWxlOiBmdW5jdGlvbihwb2ludCkge1xyXG5cdFx0dmFyIG1vZGVsID0gcG9pbnQuX21vZGVsO1xyXG5cdFx0dmFyIG9wdGlvbnMgPSBwb2ludC5fb3B0aW9ucztcclxuXHRcdHZhciBnZXRIb3ZlckNvbG9yID0gaGVscGVycyQxLmdldEhvdmVyQ29sb3I7XHJcblxyXG5cdFx0cG9pbnQuJHByZXZpb3VzU3R5bGUgPSB7XHJcblx0XHRcdGJhY2tncm91bmRDb2xvcjogbW9kZWwuYmFja2dyb3VuZENvbG9yLFxyXG5cdFx0XHRib3JkZXJDb2xvcjogbW9kZWwuYm9yZGVyQ29sb3IsXHJcblx0XHRcdGJvcmRlcldpZHRoOiBtb2RlbC5ib3JkZXJXaWR0aCxcclxuXHRcdFx0cmFkaXVzOiBtb2RlbC5yYWRpdXNcclxuXHRcdH07XHJcblxyXG5cdFx0bW9kZWwuYmFja2dyb3VuZENvbG9yID0gdmFsdWVPckRlZmF1bHQkNyhvcHRpb25zLmhvdmVyQmFja2dyb3VuZENvbG9yLCBnZXRIb3ZlckNvbG9yKG9wdGlvbnMuYmFja2dyb3VuZENvbG9yKSk7XHJcblx0XHRtb2RlbC5ib3JkZXJDb2xvciA9IHZhbHVlT3JEZWZhdWx0JDcob3B0aW9ucy5ob3ZlckJvcmRlckNvbG9yLCBnZXRIb3ZlckNvbG9yKG9wdGlvbnMuYm9yZGVyQ29sb3IpKTtcclxuXHRcdG1vZGVsLmJvcmRlcldpZHRoID0gdmFsdWVPckRlZmF1bHQkNyhvcHRpb25zLmhvdmVyQm9yZGVyV2lkdGgsIG9wdGlvbnMuYm9yZGVyV2lkdGgpO1xyXG5cdFx0bW9kZWwucmFkaXVzID0gdmFsdWVPckRlZmF1bHQkNyhvcHRpb25zLmhvdmVyUmFkaXVzLCBvcHRpb25zLnJhZGl1cyk7XHJcblx0fVxyXG59KTtcblxuY29yZV9kZWZhdWx0cy5fc2V0KCdzY2F0dGVyJywge1xyXG5cdGhvdmVyOiB7XHJcblx0XHRtb2RlOiAnc2luZ2xlJ1xyXG5cdH0sXHJcblxyXG5cdHNjYWxlczoge1xyXG5cdFx0eEF4ZXM6IFt7XHJcblx0XHRcdGlkOiAneC1heGlzLTEnLCAgICAvLyBuZWVkIGFuIElEIHNvIGRhdGFzZXRzIGNhbiByZWZlcmVuY2UgdGhlIHNjYWxlXHJcblx0XHRcdHR5cGU6ICdsaW5lYXInLCAgICAvLyBzY2F0dGVyIHNob3VsZCBub3QgdXNlIGEgY2F0ZWdvcnkgYXhpc1xyXG5cdFx0XHRwb3NpdGlvbjogJ2JvdHRvbSdcclxuXHRcdH1dLFxyXG5cdFx0eUF4ZXM6IFt7XHJcblx0XHRcdGlkOiAneS1heGlzLTEnLFxyXG5cdFx0XHR0eXBlOiAnbGluZWFyJyxcclxuXHRcdFx0cG9zaXRpb246ICdsZWZ0J1xyXG5cdFx0fV1cclxuXHR9LFxyXG5cclxuXHR0b29sdGlwczoge1xyXG5cdFx0Y2FsbGJhY2tzOiB7XHJcblx0XHRcdHRpdGxlOiBmdW5jdGlvbigpIHtcclxuXHRcdFx0XHRyZXR1cm4gJyc7ICAgICAvLyBkb2Vzbid0IG1ha2Ugc2Vuc2UgZm9yIHNjYXR0ZXIgc2luY2UgZGF0YSBhcmUgZm9ybWF0dGVkIGFzIGEgcG9pbnRcclxuXHRcdFx0fSxcclxuXHRcdFx0bGFiZWw6IGZ1bmN0aW9uKGl0ZW0pIHtcclxuXHRcdFx0XHRyZXR1cm4gJygnICsgaXRlbS54TGFiZWwgKyAnLCAnICsgaXRlbS55TGFiZWwgKyAnKSc7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHR9XHJcbn0pO1xyXG5cclxuY29yZV9kZWZhdWx0cy5fc2V0KCdnbG9iYWwnLCB7XHJcblx0ZGF0YXNldHM6IHtcclxuXHRcdHNjYXR0ZXI6IHtcclxuXHRcdFx0c2hvd0xpbmU6IGZhbHNlXHJcblx0XHR9XHJcblx0fVxyXG59KTtcclxuXHJcbi8vIFNjYXR0ZXIgY2hhcnRzIHVzZSBsaW5lIGNvbnRyb2xsZXJzXHJcbnZhciBjb250cm9sbGVyX3NjYXR0ZXIgPSBjb250cm9sbGVyX2xpbmU7XG5cbi8vIE5PVEUgZXhwb3J0IGEgbWFwIGluIHdoaWNoIHRoZSBrZXkgcmVwcmVzZW50cyB0aGUgY29udHJvbGxlciB0eXBlLCBub3RcclxuLy8gdGhlIGNsYXNzLCBhbmQgc28gbXVzdCBiZSBDYW1lbENhc2UgaW4gb3JkZXIgdG8gYmUgY29ycmVjdGx5IHJldHJpZXZlZFxyXG4vLyBieSB0aGUgY29udHJvbGxlciBpbiBjb3JlLmNvbnRyb2xsZXIuanMgKGBjb250cm9sbGVyc1ttZXRhLnR5cGVdYCkuXHJcblxyXG52YXIgY29udHJvbGxlcnMgPSB7XHJcblx0YmFyOiBjb250cm9sbGVyX2JhcixcclxuXHRidWJibGU6IGNvbnRyb2xsZXJfYnViYmxlLFxyXG5cdGRvdWdobnV0OiBjb250cm9sbGVyX2RvdWdobnV0LFxyXG5cdGhvcml6b250YWxCYXI6IGNvbnRyb2xsZXJfaG9yaXpvbnRhbEJhcixcclxuXHRsaW5lOiBjb250cm9sbGVyX2xpbmUsXHJcblx0cG9sYXJBcmVhOiBjb250cm9sbGVyX3BvbGFyQXJlYSxcclxuXHRwaWU6IGNvbnRyb2xsZXJfcGllLFxyXG5cdHJhZGFyOiBjb250cm9sbGVyX3JhZGFyLFxyXG5cdHNjYXR0ZXI6IGNvbnRyb2xsZXJfc2NhdHRlclxyXG59O1xuXG4vKipcclxuICogSGVscGVyIGZ1bmN0aW9uIHRvIGdldCByZWxhdGl2ZSBwb3NpdGlvbiBmb3IgYW4gZXZlbnRcclxuICogQHBhcmFtIHtFdmVudHxJRXZlbnR9IGV2ZW50IC0gVGhlIGV2ZW50IHRvIGdldCB0aGUgcG9zaXRpb24gZm9yXHJcbiAqIEBwYXJhbSB7Q2hhcnR9IGNoYXJ0IC0gVGhlIGNoYXJ0XHJcbiAqIEByZXR1cm5zIHtvYmplY3R9IHRoZSBldmVudCBwb3NpdGlvblxyXG4gKi9cclxuZnVuY3Rpb24gZ2V0UmVsYXRpdmVQb3NpdGlvbihlLCBjaGFydCkge1xyXG5cdGlmIChlLm5hdGl2ZSkge1xyXG5cdFx0cmV0dXJuIHtcclxuXHRcdFx0eDogZS54LFxyXG5cdFx0XHR5OiBlLnlcclxuXHRcdH07XHJcblx0fVxyXG5cclxuXHRyZXR1cm4gaGVscGVycyQxLmdldFJlbGF0aXZlUG9zaXRpb24oZSwgY2hhcnQpO1xyXG59XHJcblxyXG4vKipcclxuICogSGVscGVyIGZ1bmN0aW9uIHRvIHRyYXZlcnNlIGFsbCBvZiB0aGUgdmlzaWJsZSBlbGVtZW50cyBpbiB0aGUgY2hhcnRcclxuICogQHBhcmFtIHtDaGFydH0gY2hhcnQgLSB0aGUgY2hhcnRcclxuICogQHBhcmFtIHtmdW5jdGlvbn0gaGFuZGxlciAtIHRoZSBjYWxsYmFjayB0byBleGVjdXRlIGZvciBlYWNoIHZpc2libGUgaXRlbVxyXG4gKi9cclxuZnVuY3Rpb24gcGFyc2VWaXNpYmxlSXRlbXMoY2hhcnQsIGhhbmRsZXIpIHtcclxuXHR2YXIgbWV0YXNldHMgPSBjaGFydC5fZ2V0U29ydGVkVmlzaWJsZURhdGFzZXRNZXRhcygpO1xyXG5cdHZhciBtZXRhZGF0YSwgaSwgaiwgaWxlbiwgamxlbiwgZWxlbWVudDtcclxuXHJcblx0Zm9yIChpID0gMCwgaWxlbiA9IG1ldGFzZXRzLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xyXG5cdFx0bWV0YWRhdGEgPSBtZXRhc2V0c1tpXS5kYXRhO1xyXG5cdFx0Zm9yIChqID0gMCwgamxlbiA9IG1ldGFkYXRhLmxlbmd0aDsgaiA8IGpsZW47ICsraikge1xyXG5cdFx0XHRlbGVtZW50ID0gbWV0YWRhdGFbal07XHJcblx0XHRcdGlmICghZWxlbWVudC5fdmlldy5za2lwKSB7XHJcblx0XHRcdFx0aGFuZGxlcihlbGVtZW50KTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdH1cclxufVxyXG5cclxuLyoqXHJcbiAqIEhlbHBlciBmdW5jdGlvbiB0byBnZXQgdGhlIGl0ZW1zIHRoYXQgaW50ZXJzZWN0IHRoZSBldmVudCBwb3NpdGlvblxyXG4gKiBAcGFyYW0ge0NoYXJ0RWxlbWVudFtdfSBpdGVtcyAtIGVsZW1lbnRzIHRvIGZpbHRlclxyXG4gKiBAcGFyYW0ge29iamVjdH0gcG9zaXRpb24gLSB0aGUgcG9pbnQgdG8gYmUgbmVhcmVzdCB0b1xyXG4gKiBAcmV0dXJuIHtDaGFydEVsZW1lbnRbXX0gdGhlIG5lYXJlc3QgaXRlbXNcclxuICovXHJcbmZ1bmN0aW9uIGdldEludGVyc2VjdEl0ZW1zKGNoYXJ0LCBwb3NpdGlvbikge1xyXG5cdHZhciBlbGVtZW50cyA9IFtdO1xyXG5cclxuXHRwYXJzZVZpc2libGVJdGVtcyhjaGFydCwgZnVuY3Rpb24oZWxlbWVudCkge1xyXG5cdFx0aWYgKGVsZW1lbnQuaW5SYW5nZShwb3NpdGlvbi54LCBwb3NpdGlvbi55KSkge1xyXG5cdFx0XHRlbGVtZW50cy5wdXNoKGVsZW1lbnQpO1xyXG5cdFx0fVxyXG5cdH0pO1xyXG5cclxuXHRyZXR1cm4gZWxlbWVudHM7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBIZWxwZXIgZnVuY3Rpb24gdG8gZ2V0IHRoZSBpdGVtcyBuZWFyZXN0IHRvIHRoZSBldmVudCBwb3NpdGlvbiBjb25zaWRlcmluZyBhbGwgdmlzaWJsZSBpdGVtcyBpbiB0ZWggY2hhcnRcclxuICogQHBhcmFtIHtDaGFydH0gY2hhcnQgLSB0aGUgY2hhcnQgdG8gbG9vayBhdCBlbGVtZW50cyBmcm9tXHJcbiAqIEBwYXJhbSB7b2JqZWN0fSBwb3NpdGlvbiAtIHRoZSBwb2ludCB0byBiZSBuZWFyZXN0IHRvXHJcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gaW50ZXJzZWN0IC0gaWYgdHJ1ZSwgb25seSBjb25zaWRlciBpdGVtcyB0aGF0IGludGVyc2VjdCB0aGUgcG9zaXRpb25cclxuICogQHBhcmFtIHtmdW5jdGlvbn0gZGlzdGFuY2VNZXRyaWMgLSBmdW5jdGlvbiB0byBwcm92aWRlIHRoZSBkaXN0YW5jZSBiZXR3ZWVuIHBvaW50c1xyXG4gKiBAcmV0dXJuIHtDaGFydEVsZW1lbnRbXX0gdGhlIG5lYXJlc3QgaXRlbXNcclxuICovXHJcbmZ1bmN0aW9uIGdldE5lYXJlc3RJdGVtcyhjaGFydCwgcG9zaXRpb24sIGludGVyc2VjdCwgZGlzdGFuY2VNZXRyaWMpIHtcclxuXHR2YXIgbWluRGlzdGFuY2UgPSBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFk7XHJcblx0dmFyIG5lYXJlc3RJdGVtcyA9IFtdO1xyXG5cclxuXHRwYXJzZVZpc2libGVJdGVtcyhjaGFydCwgZnVuY3Rpb24oZWxlbWVudCkge1xyXG5cdFx0aWYgKGludGVyc2VjdCAmJiAhZWxlbWVudC5pblJhbmdlKHBvc2l0aW9uLngsIHBvc2l0aW9uLnkpKSB7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHJcblx0XHR2YXIgY2VudGVyID0gZWxlbWVudC5nZXRDZW50ZXJQb2ludCgpO1xyXG5cdFx0dmFyIGRpc3RhbmNlID0gZGlzdGFuY2VNZXRyaWMocG9zaXRpb24sIGNlbnRlcik7XHJcblx0XHRpZiAoZGlzdGFuY2UgPCBtaW5EaXN0YW5jZSkge1xyXG5cdFx0XHRuZWFyZXN0SXRlbXMgPSBbZWxlbWVudF07XHJcblx0XHRcdG1pbkRpc3RhbmNlID0gZGlzdGFuY2U7XHJcblx0XHR9IGVsc2UgaWYgKGRpc3RhbmNlID09PSBtaW5EaXN0YW5jZSkge1xyXG5cdFx0XHQvLyBDYW4gaGF2ZSBtdWx0aXBsZSBpdGVtcyBhdCB0aGUgc2FtZSBkaXN0YW5jZSBpbiB3aGljaCBjYXNlIHdlIHNvcnQgYnkgc2l6ZVxyXG5cdFx0XHRuZWFyZXN0SXRlbXMucHVzaChlbGVtZW50KTtcclxuXHRcdH1cclxuXHR9KTtcclxuXHJcblx0cmV0dXJuIG5lYXJlc3RJdGVtcztcclxufVxyXG5cclxuLyoqXHJcbiAqIEdldCBhIGRpc3RhbmNlIG1ldHJpYyBmdW5jdGlvbiBmb3IgdHdvIHBvaW50cyBiYXNlZCBvbiB0aGVcclxuICogYXhpcyBtb2RlIHNldHRpbmdcclxuICogQHBhcmFtIHtzdHJpbmd9IGF4aXMgLSB0aGUgYXhpcyBtb2RlLiB4fHl8eHlcclxuICovXHJcbmZ1bmN0aW9uIGdldERpc3RhbmNlTWV0cmljRm9yQXhpcyhheGlzKSB7XHJcblx0dmFyIHVzZVggPSBheGlzLmluZGV4T2YoJ3gnKSAhPT0gLTE7XHJcblx0dmFyIHVzZVkgPSBheGlzLmluZGV4T2YoJ3knKSAhPT0gLTE7XHJcblxyXG5cdHJldHVybiBmdW5jdGlvbihwdDEsIHB0Mikge1xyXG5cdFx0dmFyIGRlbHRhWCA9IHVzZVggPyBNYXRoLmFicyhwdDEueCAtIHB0Mi54KSA6IDA7XHJcblx0XHR2YXIgZGVsdGFZID0gdXNlWSA/IE1hdGguYWJzKHB0MS55IC0gcHQyLnkpIDogMDtcclxuXHRcdHJldHVybiBNYXRoLnNxcnQoTWF0aC5wb3coZGVsdGFYLCAyKSArIE1hdGgucG93KGRlbHRhWSwgMikpO1xyXG5cdH07XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGluZGV4TW9kZShjaGFydCwgZSwgb3B0aW9ucykge1xyXG5cdHZhciBwb3NpdGlvbiA9IGdldFJlbGF0aXZlUG9zaXRpb24oZSwgY2hhcnQpO1xyXG5cdC8vIERlZmF1bHQgYXhpcyBmb3IgaW5kZXggbW9kZSBpcyAneCcgdG8gbWF0Y2ggb2xkIGJlaGF2aW91clxyXG5cdG9wdGlvbnMuYXhpcyA9IG9wdGlvbnMuYXhpcyB8fCAneCc7XHJcblx0dmFyIGRpc3RhbmNlTWV0cmljID0gZ2V0RGlzdGFuY2VNZXRyaWNGb3JBeGlzKG9wdGlvbnMuYXhpcyk7XHJcblx0dmFyIGl0ZW1zID0gb3B0aW9ucy5pbnRlcnNlY3QgPyBnZXRJbnRlcnNlY3RJdGVtcyhjaGFydCwgcG9zaXRpb24pIDogZ2V0TmVhcmVzdEl0ZW1zKGNoYXJ0LCBwb3NpdGlvbiwgZmFsc2UsIGRpc3RhbmNlTWV0cmljKTtcclxuXHR2YXIgZWxlbWVudHMgPSBbXTtcclxuXHJcblx0aWYgKCFpdGVtcy5sZW5ndGgpIHtcclxuXHRcdHJldHVybiBbXTtcclxuXHR9XHJcblxyXG5cdGNoYXJ0Ll9nZXRTb3J0ZWRWaXNpYmxlRGF0YXNldE1ldGFzKCkuZm9yRWFjaChmdW5jdGlvbihtZXRhKSB7XHJcblx0XHR2YXIgZWxlbWVudCA9IG1ldGEuZGF0YVtpdGVtc1swXS5faW5kZXhdO1xyXG5cclxuXHRcdC8vIGRvbid0IGNvdW50IGl0ZW1zIHRoYXQgYXJlIHNraXBwZWQgKG51bGwgZGF0YSlcclxuXHRcdGlmIChlbGVtZW50ICYmICFlbGVtZW50Ll92aWV3LnNraXApIHtcclxuXHRcdFx0ZWxlbWVudHMucHVzaChlbGVtZW50KTtcclxuXHRcdH1cclxuXHR9KTtcclxuXHJcblx0cmV0dXJuIGVsZW1lbnRzO1xyXG59XHJcblxyXG4vKipcclxuICogQGludGVyZmFjZSBJSW50ZXJhY3Rpb25PcHRpb25zXHJcbiAqL1xyXG4vKipcclxuICogSWYgdHJ1ZSwgb25seSBjb25zaWRlciBpdGVtcyB0aGF0IGludGVyc2VjdCB0aGUgcG9pbnRcclxuICogQG5hbWUgSUludGVyZmFjZU9wdGlvbnMjYm9vbGVhblxyXG4gKiBAdHlwZSBCb29sZWFuXHJcbiAqL1xyXG5cclxuLyoqXHJcbiAqIENvbnRhaW5zIGludGVyYWN0aW9uIHJlbGF0ZWQgZnVuY3Rpb25zXHJcbiAqIEBuYW1lc3BhY2UgQ2hhcnQuSW50ZXJhY3Rpb25cclxuICovXHJcbnZhciBjb3JlX2ludGVyYWN0aW9uID0ge1xyXG5cdC8vIEhlbHBlciBmdW5jdGlvbiBmb3IgZGlmZmVyZW50IG1vZGVzXHJcblx0bW9kZXM6IHtcclxuXHRcdHNpbmdsZTogZnVuY3Rpb24oY2hhcnQsIGUpIHtcclxuXHRcdFx0dmFyIHBvc2l0aW9uID0gZ2V0UmVsYXRpdmVQb3NpdGlvbihlLCBjaGFydCk7XHJcblx0XHRcdHZhciBlbGVtZW50cyA9IFtdO1xyXG5cclxuXHRcdFx0cGFyc2VWaXNpYmxlSXRlbXMoY2hhcnQsIGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuXHRcdFx0XHRpZiAoZWxlbWVudC5pblJhbmdlKHBvc2l0aW9uLngsIHBvc2l0aW9uLnkpKSB7XHJcblx0XHRcdFx0XHRlbGVtZW50cy5wdXNoKGVsZW1lbnQpO1xyXG5cdFx0XHRcdFx0cmV0dXJuIGVsZW1lbnRzO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSk7XHJcblxyXG5cdFx0XHRyZXR1cm4gZWxlbWVudHMuc2xpY2UoMCwgMSk7XHJcblx0XHR9LFxyXG5cclxuXHRcdC8qKlxyXG5cdFx0ICogQGZ1bmN0aW9uIENoYXJ0LkludGVyYWN0aW9uLm1vZGVzLmxhYmVsXHJcblx0XHQgKiBAZGVwcmVjYXRlZCBzaW5jZSB2ZXJzaW9uIDIuNC4wXHJcblx0XHQgKiBAdG9kbyByZW1vdmUgYXQgdmVyc2lvbiAzXHJcblx0XHQgKiBAcHJpdmF0ZVxyXG5cdFx0ICovXHJcblx0XHRsYWJlbDogaW5kZXhNb2RlLFxyXG5cclxuXHRcdC8qKlxyXG5cdFx0ICogUmV0dXJucyBpdGVtcyBhdCB0aGUgc2FtZSBpbmRleC4gSWYgdGhlIG9wdGlvbnMuaW50ZXJzZWN0IHBhcmFtZXRlciBpcyB0cnVlLCB3ZSBvbmx5IHJldHVybiBpdGVtcyBpZiB3ZSBpbnRlcnNlY3Qgc29tZXRoaW5nXHJcblx0XHQgKiBJZiB0aGUgb3B0aW9ucy5pbnRlcnNlY3QgbW9kZSBpcyBmYWxzZSwgd2UgZmluZCB0aGUgbmVhcmVzdCBpdGVtIGFuZCByZXR1cm4gdGhlIGl0ZW1zIGF0IHRoZSBzYW1lIGluZGV4IGFzIHRoYXQgaXRlbVxyXG5cdFx0ICogQGZ1bmN0aW9uIENoYXJ0LkludGVyYWN0aW9uLm1vZGVzLmluZGV4XHJcblx0XHQgKiBAc2luY2UgdjIuNC4wXHJcblx0XHQgKiBAcGFyYW0ge0NoYXJ0fSBjaGFydCAtIHRoZSBjaGFydCB3ZSBhcmUgcmV0dXJuaW5nIGl0ZW1zIGZyb21cclxuXHRcdCAqIEBwYXJhbSB7RXZlbnR9IGUgLSB0aGUgZXZlbnQgd2UgYXJlIGZpbmQgdGhpbmdzIGF0XHJcblx0XHQgKiBAcGFyYW0ge0lJbnRlcmFjdGlvbk9wdGlvbnN9IG9wdGlvbnMgLSBvcHRpb25zIHRvIHVzZSBkdXJpbmcgaW50ZXJhY3Rpb25cclxuXHRcdCAqIEByZXR1cm4ge0NoYXJ0LkVsZW1lbnRbXX0gQXJyYXkgb2YgZWxlbWVudHMgdGhhdCBhcmUgdW5kZXIgdGhlIHBvaW50LiBJZiBub25lIGFyZSBmb3VuZCwgYW4gZW1wdHkgYXJyYXkgaXMgcmV0dXJuZWRcclxuXHRcdCAqL1xyXG5cdFx0aW5kZXg6IGluZGV4TW9kZSxcclxuXHJcblx0XHQvKipcclxuXHRcdCAqIFJldHVybnMgaXRlbXMgaW4gdGhlIHNhbWUgZGF0YXNldC4gSWYgdGhlIG9wdGlvbnMuaW50ZXJzZWN0IHBhcmFtZXRlciBpcyB0cnVlLCB3ZSBvbmx5IHJldHVybiBpdGVtcyBpZiB3ZSBpbnRlcnNlY3Qgc29tZXRoaW5nXHJcblx0XHQgKiBJZiB0aGUgb3B0aW9ucy5pbnRlcnNlY3QgaXMgZmFsc2UsIHdlIGZpbmQgdGhlIG5lYXJlc3QgaXRlbSBhbmQgcmV0dXJuIHRoZSBpdGVtcyBpbiB0aGF0IGRhdGFzZXRcclxuXHRcdCAqIEBmdW5jdGlvbiBDaGFydC5JbnRlcmFjdGlvbi5tb2Rlcy5kYXRhc2V0XHJcblx0XHQgKiBAcGFyYW0ge0NoYXJ0fSBjaGFydCAtIHRoZSBjaGFydCB3ZSBhcmUgcmV0dXJuaW5nIGl0ZW1zIGZyb21cclxuXHRcdCAqIEBwYXJhbSB7RXZlbnR9IGUgLSB0aGUgZXZlbnQgd2UgYXJlIGZpbmQgdGhpbmdzIGF0XHJcblx0XHQgKiBAcGFyYW0ge0lJbnRlcmFjdGlvbk9wdGlvbnN9IG9wdGlvbnMgLSBvcHRpb25zIHRvIHVzZSBkdXJpbmcgaW50ZXJhY3Rpb25cclxuXHRcdCAqIEByZXR1cm4ge0NoYXJ0LkVsZW1lbnRbXX0gQXJyYXkgb2YgZWxlbWVudHMgdGhhdCBhcmUgdW5kZXIgdGhlIHBvaW50LiBJZiBub25lIGFyZSBmb3VuZCwgYW4gZW1wdHkgYXJyYXkgaXMgcmV0dXJuZWRcclxuXHRcdCAqL1xyXG5cdFx0ZGF0YXNldDogZnVuY3Rpb24oY2hhcnQsIGUsIG9wdGlvbnMpIHtcclxuXHRcdFx0dmFyIHBvc2l0aW9uID0gZ2V0UmVsYXRpdmVQb3NpdGlvbihlLCBjaGFydCk7XHJcblx0XHRcdG9wdGlvbnMuYXhpcyA9IG9wdGlvbnMuYXhpcyB8fCAneHknO1xyXG5cdFx0XHR2YXIgZGlzdGFuY2VNZXRyaWMgPSBnZXREaXN0YW5jZU1ldHJpY0ZvckF4aXMob3B0aW9ucy5heGlzKTtcclxuXHRcdFx0dmFyIGl0ZW1zID0gb3B0aW9ucy5pbnRlcnNlY3QgPyBnZXRJbnRlcnNlY3RJdGVtcyhjaGFydCwgcG9zaXRpb24pIDogZ2V0TmVhcmVzdEl0ZW1zKGNoYXJ0LCBwb3NpdGlvbiwgZmFsc2UsIGRpc3RhbmNlTWV0cmljKTtcclxuXHJcblx0XHRcdGlmIChpdGVtcy5sZW5ndGggPiAwKSB7XHJcblx0XHRcdFx0aXRlbXMgPSBjaGFydC5nZXREYXRhc2V0TWV0YShpdGVtc1swXS5fZGF0YXNldEluZGV4KS5kYXRhO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRyZXR1cm4gaXRlbXM7XHJcblx0XHR9LFxyXG5cclxuXHRcdC8qKlxyXG5cdFx0ICogQGZ1bmN0aW9uIENoYXJ0LkludGVyYWN0aW9uLm1vZGVzLngtYXhpc1xyXG5cdFx0ICogQGRlcHJlY2F0ZWQgc2luY2UgdmVyc2lvbiAyLjQuMC4gVXNlIGluZGV4IG1vZGUgYW5kIGludGVyc2VjdCA9PSB0cnVlXHJcblx0XHQgKiBAdG9kbyByZW1vdmUgYXQgdmVyc2lvbiAzXHJcblx0XHQgKiBAcHJpdmF0ZVxyXG5cdFx0ICovXHJcblx0XHQneC1heGlzJzogZnVuY3Rpb24oY2hhcnQsIGUpIHtcclxuXHRcdFx0cmV0dXJuIGluZGV4TW9kZShjaGFydCwgZSwge2ludGVyc2VjdDogZmFsc2V9KTtcclxuXHRcdH0sXHJcblxyXG5cdFx0LyoqXHJcblx0XHQgKiBQb2ludCBtb2RlIHJldHVybnMgYWxsIGVsZW1lbnRzIHRoYXQgaGl0IHRlc3QgYmFzZWQgb24gdGhlIGV2ZW50IHBvc2l0aW9uXHJcblx0XHQgKiBvZiB0aGUgZXZlbnRcclxuXHRcdCAqIEBmdW5jdGlvbiBDaGFydC5JbnRlcmFjdGlvbi5tb2Rlcy5pbnRlcnNlY3RcclxuXHRcdCAqIEBwYXJhbSB7Q2hhcnR9IGNoYXJ0IC0gdGhlIGNoYXJ0IHdlIGFyZSByZXR1cm5pbmcgaXRlbXMgZnJvbVxyXG5cdFx0ICogQHBhcmFtIHtFdmVudH0gZSAtIHRoZSBldmVudCB3ZSBhcmUgZmluZCB0aGluZ3MgYXRcclxuXHRcdCAqIEByZXR1cm4ge0NoYXJ0LkVsZW1lbnRbXX0gQXJyYXkgb2YgZWxlbWVudHMgdGhhdCBhcmUgdW5kZXIgdGhlIHBvaW50LiBJZiBub25lIGFyZSBmb3VuZCwgYW4gZW1wdHkgYXJyYXkgaXMgcmV0dXJuZWRcclxuXHRcdCAqL1xyXG5cdFx0cG9pbnQ6IGZ1bmN0aW9uKGNoYXJ0LCBlKSB7XHJcblx0XHRcdHZhciBwb3NpdGlvbiA9IGdldFJlbGF0aXZlUG9zaXRpb24oZSwgY2hhcnQpO1xyXG5cdFx0XHRyZXR1cm4gZ2V0SW50ZXJzZWN0SXRlbXMoY2hhcnQsIHBvc2l0aW9uKTtcclxuXHRcdH0sXHJcblxyXG5cdFx0LyoqXHJcblx0XHQgKiBuZWFyZXN0IG1vZGUgcmV0dXJucyB0aGUgZWxlbWVudCBjbG9zZXN0IHRvIHRoZSBwb2ludFxyXG5cdFx0ICogQGZ1bmN0aW9uIENoYXJ0LkludGVyYWN0aW9uLm1vZGVzLmludGVyc2VjdFxyXG5cdFx0ICogQHBhcmFtIHtDaGFydH0gY2hhcnQgLSB0aGUgY2hhcnQgd2UgYXJlIHJldHVybmluZyBpdGVtcyBmcm9tXHJcblx0XHQgKiBAcGFyYW0ge0V2ZW50fSBlIC0gdGhlIGV2ZW50IHdlIGFyZSBmaW5kIHRoaW5ncyBhdFxyXG5cdFx0ICogQHBhcmFtIHtJSW50ZXJhY3Rpb25PcHRpb25zfSBvcHRpb25zIC0gb3B0aW9ucyB0byB1c2VcclxuXHRcdCAqIEByZXR1cm4ge0NoYXJ0LkVsZW1lbnRbXX0gQXJyYXkgb2YgZWxlbWVudHMgdGhhdCBhcmUgdW5kZXIgdGhlIHBvaW50LiBJZiBub25lIGFyZSBmb3VuZCwgYW4gZW1wdHkgYXJyYXkgaXMgcmV0dXJuZWRcclxuXHRcdCAqL1xyXG5cdFx0bmVhcmVzdDogZnVuY3Rpb24oY2hhcnQsIGUsIG9wdGlvbnMpIHtcclxuXHRcdFx0dmFyIHBvc2l0aW9uID0gZ2V0UmVsYXRpdmVQb3NpdGlvbihlLCBjaGFydCk7XHJcblx0XHRcdG9wdGlvbnMuYXhpcyA9IG9wdGlvbnMuYXhpcyB8fCAneHknO1xyXG5cdFx0XHR2YXIgZGlzdGFuY2VNZXRyaWMgPSBnZXREaXN0YW5jZU1ldHJpY0ZvckF4aXMob3B0aW9ucy5heGlzKTtcclxuXHRcdFx0cmV0dXJuIGdldE5lYXJlc3RJdGVtcyhjaGFydCwgcG9zaXRpb24sIG9wdGlvbnMuaW50ZXJzZWN0LCBkaXN0YW5jZU1ldHJpYyk7XHJcblx0XHR9LFxyXG5cclxuXHRcdC8qKlxyXG5cdFx0ICogeCBtb2RlIHJldHVybnMgdGhlIGVsZW1lbnRzIHRoYXQgaGl0LXRlc3QgYXQgdGhlIGN1cnJlbnQgeCBjb29yZGluYXRlXHJcblx0XHQgKiBAZnVuY3Rpb24gQ2hhcnQuSW50ZXJhY3Rpb24ubW9kZXMueFxyXG5cdFx0ICogQHBhcmFtIHtDaGFydH0gY2hhcnQgLSB0aGUgY2hhcnQgd2UgYXJlIHJldHVybmluZyBpdGVtcyBmcm9tXHJcblx0XHQgKiBAcGFyYW0ge0V2ZW50fSBlIC0gdGhlIGV2ZW50IHdlIGFyZSBmaW5kIHRoaW5ncyBhdFxyXG5cdFx0ICogQHBhcmFtIHtJSW50ZXJhY3Rpb25PcHRpb25zfSBvcHRpb25zIC0gb3B0aW9ucyB0byB1c2VcclxuXHRcdCAqIEByZXR1cm4ge0NoYXJ0LkVsZW1lbnRbXX0gQXJyYXkgb2YgZWxlbWVudHMgdGhhdCBhcmUgdW5kZXIgdGhlIHBvaW50LiBJZiBub25lIGFyZSBmb3VuZCwgYW4gZW1wdHkgYXJyYXkgaXMgcmV0dXJuZWRcclxuXHRcdCAqL1xyXG5cdFx0eDogZnVuY3Rpb24oY2hhcnQsIGUsIG9wdGlvbnMpIHtcclxuXHRcdFx0dmFyIHBvc2l0aW9uID0gZ2V0UmVsYXRpdmVQb3NpdGlvbihlLCBjaGFydCk7XHJcblx0XHRcdHZhciBpdGVtcyA9IFtdO1xyXG5cdFx0XHR2YXIgaW50ZXJzZWN0c0l0ZW0gPSBmYWxzZTtcclxuXHJcblx0XHRcdHBhcnNlVmlzaWJsZUl0ZW1zKGNoYXJ0LCBmdW5jdGlvbihlbGVtZW50KSB7XHJcblx0XHRcdFx0aWYgKGVsZW1lbnQuaW5YUmFuZ2UocG9zaXRpb24ueCkpIHtcclxuXHRcdFx0XHRcdGl0ZW1zLnB1c2goZWxlbWVudCk7XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRpZiAoZWxlbWVudC5pblJhbmdlKHBvc2l0aW9uLngsIHBvc2l0aW9uLnkpKSB7XHJcblx0XHRcdFx0XHRpbnRlcnNlY3RzSXRlbSA9IHRydWU7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9KTtcclxuXHJcblx0XHRcdC8vIElmIHdlIHdhbnQgdG8gdHJpZ2dlciBvbiBhbiBpbnRlcnNlY3QgYW5kIHdlIGRvbid0IGhhdmUgYW55IGl0ZW1zXHJcblx0XHRcdC8vIHRoYXQgaW50ZXJzZWN0IHRoZSBwb3NpdGlvbiwgcmV0dXJuIG5vdGhpbmdcclxuXHRcdFx0aWYgKG9wdGlvbnMuaW50ZXJzZWN0ICYmICFpbnRlcnNlY3RzSXRlbSkge1xyXG5cdFx0XHRcdGl0ZW1zID0gW107XHJcblx0XHRcdH1cclxuXHRcdFx0cmV0dXJuIGl0ZW1zO1xyXG5cdFx0fSxcclxuXHJcblx0XHQvKipcclxuXHRcdCAqIHkgbW9kZSByZXR1cm5zIHRoZSBlbGVtZW50cyB0aGF0IGhpdC10ZXN0IGF0IHRoZSBjdXJyZW50IHkgY29vcmRpbmF0ZVxyXG5cdFx0ICogQGZ1bmN0aW9uIENoYXJ0LkludGVyYWN0aW9uLm1vZGVzLnlcclxuXHRcdCAqIEBwYXJhbSB7Q2hhcnR9IGNoYXJ0IC0gdGhlIGNoYXJ0IHdlIGFyZSByZXR1cm5pbmcgaXRlbXMgZnJvbVxyXG5cdFx0ICogQHBhcmFtIHtFdmVudH0gZSAtIHRoZSBldmVudCB3ZSBhcmUgZmluZCB0aGluZ3MgYXRcclxuXHRcdCAqIEBwYXJhbSB7SUludGVyYWN0aW9uT3B0aW9uc30gb3B0aW9ucyAtIG9wdGlvbnMgdG8gdXNlXHJcblx0XHQgKiBAcmV0dXJuIHtDaGFydC5FbGVtZW50W119IEFycmF5IG9mIGVsZW1lbnRzIHRoYXQgYXJlIHVuZGVyIHRoZSBwb2ludC4gSWYgbm9uZSBhcmUgZm91bmQsIGFuIGVtcHR5IGFycmF5IGlzIHJldHVybmVkXHJcblx0XHQgKi9cclxuXHRcdHk6IGZ1bmN0aW9uKGNoYXJ0LCBlLCBvcHRpb25zKSB7XHJcblx0XHRcdHZhciBwb3NpdGlvbiA9IGdldFJlbGF0aXZlUG9zaXRpb24oZSwgY2hhcnQpO1xyXG5cdFx0XHR2YXIgaXRlbXMgPSBbXTtcclxuXHRcdFx0dmFyIGludGVyc2VjdHNJdGVtID0gZmFsc2U7XHJcblxyXG5cdFx0XHRwYXJzZVZpc2libGVJdGVtcyhjaGFydCwgZnVuY3Rpb24oZWxlbWVudCkge1xyXG5cdFx0XHRcdGlmIChlbGVtZW50LmluWVJhbmdlKHBvc2l0aW9uLnkpKSB7XHJcblx0XHRcdFx0XHRpdGVtcy5wdXNoKGVsZW1lbnQpO1xyXG5cdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0aWYgKGVsZW1lbnQuaW5SYW5nZShwb3NpdGlvbi54LCBwb3NpdGlvbi55KSkge1xyXG5cdFx0XHRcdFx0aW50ZXJzZWN0c0l0ZW0gPSB0cnVlO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSk7XHJcblxyXG5cdFx0XHQvLyBJZiB3ZSB3YW50IHRvIHRyaWdnZXIgb24gYW4gaW50ZXJzZWN0IGFuZCB3ZSBkb24ndCBoYXZlIGFueSBpdGVtc1xyXG5cdFx0XHQvLyB0aGF0IGludGVyc2VjdCB0aGUgcG9zaXRpb24sIHJldHVybiBub3RoaW5nXHJcblx0XHRcdGlmIChvcHRpb25zLmludGVyc2VjdCAmJiAhaW50ZXJzZWN0c0l0ZW0pIHtcclxuXHRcdFx0XHRpdGVtcyA9IFtdO1xyXG5cdFx0XHR9XHJcblx0XHRcdHJldHVybiBpdGVtcztcclxuXHRcdH1cclxuXHR9XHJcbn07XG5cbnZhciBleHRlbmQgPSBoZWxwZXJzJDEuZXh0ZW5kO1xyXG5cclxuZnVuY3Rpb24gZmlsdGVyQnlQb3NpdGlvbihhcnJheSwgcG9zaXRpb24pIHtcclxuXHRyZXR1cm4gaGVscGVycyQxLndoZXJlKGFycmF5LCBmdW5jdGlvbih2KSB7XHJcblx0XHRyZXR1cm4gdi5wb3MgPT09IHBvc2l0aW9uO1xyXG5cdH0pO1xyXG59XHJcblxyXG5mdW5jdGlvbiBzb3J0QnlXZWlnaHQoYXJyYXksIHJldmVyc2UpIHtcclxuXHRyZXR1cm4gYXJyYXkuc29ydChmdW5jdGlvbihhLCBiKSB7XHJcblx0XHR2YXIgdjAgPSByZXZlcnNlID8gYiA6IGE7XHJcblx0XHR2YXIgdjEgPSByZXZlcnNlID8gYSA6IGI7XHJcblx0XHRyZXR1cm4gdjAud2VpZ2h0ID09PSB2MS53ZWlnaHQgP1xyXG5cdFx0XHR2MC5pbmRleCAtIHYxLmluZGV4IDpcclxuXHRcdFx0djAud2VpZ2h0IC0gdjEud2VpZ2h0O1xyXG5cdH0pO1xyXG59XHJcblxyXG5mdW5jdGlvbiB3cmFwQm94ZXMoYm94ZXMpIHtcclxuXHR2YXIgbGF5b3V0Qm94ZXMgPSBbXTtcclxuXHR2YXIgaSwgaWxlbiwgYm94O1xyXG5cclxuXHRmb3IgKGkgPSAwLCBpbGVuID0gKGJveGVzIHx8IFtdKS5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcclxuXHRcdGJveCA9IGJveGVzW2ldO1xyXG5cdFx0bGF5b3V0Qm94ZXMucHVzaCh7XHJcblx0XHRcdGluZGV4OiBpLFxyXG5cdFx0XHRib3g6IGJveCxcclxuXHRcdFx0cG9zOiBib3gucG9zaXRpb24sXHJcblx0XHRcdGhvcml6b250YWw6IGJveC5pc0hvcml6b250YWwoKSxcclxuXHRcdFx0d2VpZ2h0OiBib3gud2VpZ2h0XHJcblx0XHR9KTtcclxuXHR9XHJcblx0cmV0dXJuIGxheW91dEJveGVzO1xyXG59XHJcblxyXG5mdW5jdGlvbiBzZXRMYXlvdXREaW1zKGxheW91dHMsIHBhcmFtcykge1xyXG5cdHZhciBpLCBpbGVuLCBsYXlvdXQ7XHJcblx0Zm9yIChpID0gMCwgaWxlbiA9IGxheW91dHMubGVuZ3RoOyBpIDwgaWxlbjsgKytpKSB7XHJcblx0XHRsYXlvdXQgPSBsYXlvdXRzW2ldO1xyXG5cdFx0Ly8gc3RvcmUgd2lkdGggdXNlZCBpbnN0ZWFkIG9mIGNoYXJ0QXJlYS53IGluIGZpdEJveGVzXHJcblx0XHRsYXlvdXQud2lkdGggPSBsYXlvdXQuaG9yaXpvbnRhbFxyXG5cdFx0XHQ/IGxheW91dC5ib3guZnVsbFdpZHRoICYmIHBhcmFtcy5hdmFpbGFibGVXaWR0aFxyXG5cdFx0XHQ6IHBhcmFtcy52Qm94TWF4V2lkdGg7XHJcblx0XHQvLyBzdG9yZSBoZWlnaHQgdXNlZCBpbnN0ZWFkIG9mIGNoYXJ0QXJlYS5oIGluIGZpdEJveGVzXHJcblx0XHRsYXlvdXQuaGVpZ2h0ID0gbGF5b3V0Lmhvcml6b250YWwgJiYgcGFyYW1zLmhCb3hNYXhIZWlnaHQ7XHJcblx0fVxyXG59XHJcblxyXG5mdW5jdGlvbiBidWlsZExheW91dEJveGVzKGJveGVzKSB7XHJcblx0dmFyIGxheW91dEJveGVzID0gd3JhcEJveGVzKGJveGVzKTtcclxuXHR2YXIgbGVmdCA9IHNvcnRCeVdlaWdodChmaWx0ZXJCeVBvc2l0aW9uKGxheW91dEJveGVzLCAnbGVmdCcpLCB0cnVlKTtcclxuXHR2YXIgcmlnaHQgPSBzb3J0QnlXZWlnaHQoZmlsdGVyQnlQb3NpdGlvbihsYXlvdXRCb3hlcywgJ3JpZ2h0JykpO1xyXG5cdHZhciB0b3AgPSBzb3J0QnlXZWlnaHQoZmlsdGVyQnlQb3NpdGlvbihsYXlvdXRCb3hlcywgJ3RvcCcpLCB0cnVlKTtcclxuXHR2YXIgYm90dG9tID0gc29ydEJ5V2VpZ2h0KGZpbHRlckJ5UG9zaXRpb24obGF5b3V0Qm94ZXMsICdib3R0b20nKSk7XHJcblxyXG5cdHJldHVybiB7XHJcblx0XHRsZWZ0QW5kVG9wOiBsZWZ0LmNvbmNhdCh0b3ApLFxyXG5cdFx0cmlnaHRBbmRCb3R0b206IHJpZ2h0LmNvbmNhdChib3R0b20pLFxyXG5cdFx0Y2hhcnRBcmVhOiBmaWx0ZXJCeVBvc2l0aW9uKGxheW91dEJveGVzLCAnY2hhcnRBcmVhJyksXHJcblx0XHR2ZXJ0aWNhbDogbGVmdC5jb25jYXQocmlnaHQpLFxyXG5cdFx0aG9yaXpvbnRhbDogdG9wLmNvbmNhdChib3R0b20pXHJcblx0fTtcclxufVxyXG5cclxuZnVuY3Rpb24gZ2V0Q29tYmluZWRNYXgobWF4UGFkZGluZywgY2hhcnRBcmVhLCBhLCBiKSB7XHJcblx0cmV0dXJuIE1hdGgubWF4KG1heFBhZGRpbmdbYV0sIGNoYXJ0QXJlYVthXSkgKyBNYXRoLm1heChtYXhQYWRkaW5nW2JdLCBjaGFydEFyZWFbYl0pO1xyXG59XHJcblxyXG5mdW5jdGlvbiB1cGRhdGVEaW1zKGNoYXJ0QXJlYSwgcGFyYW1zLCBsYXlvdXQpIHtcclxuXHR2YXIgYm94ID0gbGF5b3V0LmJveDtcclxuXHR2YXIgbWF4UGFkZGluZyA9IGNoYXJ0QXJlYS5tYXhQYWRkaW5nO1xyXG5cdHZhciBuZXdXaWR0aCwgbmV3SGVpZ2h0O1xyXG5cclxuXHRpZiAobGF5b3V0LnNpemUpIHtcclxuXHRcdC8vIHRoaXMgbGF5b3V0IHdhcyBhbHJlYWR5IGNvdW50ZWQgZm9yLCBsZXRzIGZpcnN0IHJlZHVjZSBvbGQgc2l6ZVxyXG5cdFx0Y2hhcnRBcmVhW2xheW91dC5wb3NdIC09IGxheW91dC5zaXplO1xyXG5cdH1cclxuXHRsYXlvdXQuc2l6ZSA9IGxheW91dC5ob3Jpem9udGFsID8gYm94LmhlaWdodCA6IGJveC53aWR0aDtcclxuXHRjaGFydEFyZWFbbGF5b3V0LnBvc10gKz0gbGF5b3V0LnNpemU7XHJcblxyXG5cdGlmIChib3guZ2V0UGFkZGluZykge1xyXG5cdFx0dmFyIGJveFBhZGRpbmcgPSBib3guZ2V0UGFkZGluZygpO1xyXG5cdFx0bWF4UGFkZGluZy50b3AgPSBNYXRoLm1heChtYXhQYWRkaW5nLnRvcCwgYm94UGFkZGluZy50b3ApO1xyXG5cdFx0bWF4UGFkZGluZy5sZWZ0ID0gTWF0aC5tYXgobWF4UGFkZGluZy5sZWZ0LCBib3hQYWRkaW5nLmxlZnQpO1xyXG5cdFx0bWF4UGFkZGluZy5ib3R0b20gPSBNYXRoLm1heChtYXhQYWRkaW5nLmJvdHRvbSwgYm94UGFkZGluZy5ib3R0b20pO1xyXG5cdFx0bWF4UGFkZGluZy5yaWdodCA9IE1hdGgubWF4KG1heFBhZGRpbmcucmlnaHQsIGJveFBhZGRpbmcucmlnaHQpO1xyXG5cdH1cclxuXHJcblx0bmV3V2lkdGggPSBwYXJhbXMub3V0ZXJXaWR0aCAtIGdldENvbWJpbmVkTWF4KG1heFBhZGRpbmcsIGNoYXJ0QXJlYSwgJ2xlZnQnLCAncmlnaHQnKTtcclxuXHRuZXdIZWlnaHQgPSBwYXJhbXMub3V0ZXJIZWlnaHQgLSBnZXRDb21iaW5lZE1heChtYXhQYWRkaW5nLCBjaGFydEFyZWEsICd0b3AnLCAnYm90dG9tJyk7XHJcblxyXG5cdGlmIChuZXdXaWR0aCAhPT0gY2hhcnRBcmVhLncgfHwgbmV3SGVpZ2h0ICE9PSBjaGFydEFyZWEuaCkge1xyXG5cdFx0Y2hhcnRBcmVhLncgPSBuZXdXaWR0aDtcclxuXHRcdGNoYXJ0QXJlYS5oID0gbmV3SGVpZ2h0O1xyXG5cclxuXHRcdC8vIHJldHVybiB0cnVlIGlmIGNoYXJ0IGFyZWEgY2hhbmdlZCBpbiBsYXlvdXQncyBkaXJlY3Rpb25cclxuXHRcdHZhciBzaXplcyA9IGxheW91dC5ob3Jpem9udGFsID8gW25ld1dpZHRoLCBjaGFydEFyZWEud10gOiBbbmV3SGVpZ2h0LCBjaGFydEFyZWEuaF07XHJcblx0XHRyZXR1cm4gc2l6ZXNbMF0gIT09IHNpemVzWzFdICYmICghaXNOYU4oc2l6ZXNbMF0pIHx8ICFpc05hTihzaXplc1sxXSkpO1xyXG5cdH1cclxufVxyXG5cclxuZnVuY3Rpb24gaGFuZGxlTWF4UGFkZGluZyhjaGFydEFyZWEpIHtcclxuXHR2YXIgbWF4UGFkZGluZyA9IGNoYXJ0QXJlYS5tYXhQYWRkaW5nO1xyXG5cclxuXHRmdW5jdGlvbiB1cGRhdGVQb3MocG9zKSB7XHJcblx0XHR2YXIgY2hhbmdlID0gTWF0aC5tYXgobWF4UGFkZGluZ1twb3NdIC0gY2hhcnRBcmVhW3Bvc10sIDApO1xyXG5cdFx0Y2hhcnRBcmVhW3Bvc10gKz0gY2hhbmdlO1xyXG5cdFx0cmV0dXJuIGNoYW5nZTtcclxuXHR9XHJcblx0Y2hhcnRBcmVhLnkgKz0gdXBkYXRlUG9zKCd0b3AnKTtcclxuXHRjaGFydEFyZWEueCArPSB1cGRhdGVQb3MoJ2xlZnQnKTtcclxuXHR1cGRhdGVQb3MoJ3JpZ2h0Jyk7XHJcblx0dXBkYXRlUG9zKCdib3R0b20nKTtcclxufVxyXG5cclxuZnVuY3Rpb24gZ2V0TWFyZ2lucyhob3Jpem9udGFsLCBjaGFydEFyZWEpIHtcclxuXHR2YXIgbWF4UGFkZGluZyA9IGNoYXJ0QXJlYS5tYXhQYWRkaW5nO1xyXG5cclxuXHRmdW5jdGlvbiBtYXJnaW5Gb3JQb3NpdGlvbnMocG9zaXRpb25zKSB7XHJcblx0XHR2YXIgbWFyZ2luID0ge2xlZnQ6IDAsIHRvcDogMCwgcmlnaHQ6IDAsIGJvdHRvbTogMH07XHJcblx0XHRwb3NpdGlvbnMuZm9yRWFjaChmdW5jdGlvbihwb3MpIHtcclxuXHRcdFx0bWFyZ2luW3Bvc10gPSBNYXRoLm1heChjaGFydEFyZWFbcG9zXSwgbWF4UGFkZGluZ1twb3NdKTtcclxuXHRcdH0pO1xyXG5cdFx0cmV0dXJuIG1hcmdpbjtcclxuXHR9XHJcblxyXG5cdHJldHVybiBob3Jpem9udGFsXHJcblx0XHQ/IG1hcmdpbkZvclBvc2l0aW9ucyhbJ2xlZnQnLCAncmlnaHQnXSlcclxuXHRcdDogbWFyZ2luRm9yUG9zaXRpb25zKFsndG9wJywgJ2JvdHRvbSddKTtcclxufVxyXG5cclxuZnVuY3Rpb24gZml0Qm94ZXMoYm94ZXMsIGNoYXJ0QXJlYSwgcGFyYW1zKSB7XHJcblx0dmFyIHJlZml0Qm94ZXMgPSBbXTtcclxuXHR2YXIgaSwgaWxlbiwgbGF5b3V0LCBib3gsIHJlZml0LCBjaGFuZ2VkO1xyXG5cclxuXHRmb3IgKGkgPSAwLCBpbGVuID0gYm94ZXMubGVuZ3RoOyBpIDwgaWxlbjsgKytpKSB7XHJcblx0XHRsYXlvdXQgPSBib3hlc1tpXTtcclxuXHRcdGJveCA9IGxheW91dC5ib3g7XHJcblxyXG5cdFx0Ym94LnVwZGF0ZShcclxuXHRcdFx0bGF5b3V0LndpZHRoIHx8IGNoYXJ0QXJlYS53LFxyXG5cdFx0XHRsYXlvdXQuaGVpZ2h0IHx8IGNoYXJ0QXJlYS5oLFxyXG5cdFx0XHRnZXRNYXJnaW5zKGxheW91dC5ob3Jpem9udGFsLCBjaGFydEFyZWEpXHJcblx0XHQpO1xyXG5cdFx0aWYgKHVwZGF0ZURpbXMoY2hhcnRBcmVhLCBwYXJhbXMsIGxheW91dCkpIHtcclxuXHRcdFx0Y2hhbmdlZCA9IHRydWU7XHJcblx0XHRcdGlmIChyZWZpdEJveGVzLmxlbmd0aCkge1xyXG5cdFx0XHRcdC8vIERpbWVuc2lvbnMgY2hhbmdlZCBhbmQgdGhlcmUgd2VyZSBub24gZnVsbCB3aWR0aCBib3hlcyBiZWZvcmUgdGhpc1xyXG5cdFx0XHRcdC8vIC0+IHdlIGhhdmUgdG8gcmVmaXQgdGhvc2VcclxuXHRcdFx0XHRyZWZpdCA9IHRydWU7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHRcdGlmICghYm94LmZ1bGxXaWR0aCkgeyAvLyBmdWxsV2lkdGggYm94ZXMgZG9uJ3QgbmVlZCB0byBiZSByZS1maXR0ZWQgaW4gYW55IGNhc2VcclxuXHRcdFx0cmVmaXRCb3hlcy5wdXNoKGxheW91dCk7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRyZXR1cm4gcmVmaXQgPyBmaXRCb3hlcyhyZWZpdEJveGVzLCBjaGFydEFyZWEsIHBhcmFtcykgfHwgY2hhbmdlZCA6IGNoYW5nZWQ7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHBsYWNlQm94ZXMoYm94ZXMsIGNoYXJ0QXJlYSwgcGFyYW1zKSB7XHJcblx0dmFyIHVzZXJQYWRkaW5nID0gcGFyYW1zLnBhZGRpbmc7XHJcblx0dmFyIHggPSBjaGFydEFyZWEueDtcclxuXHR2YXIgeSA9IGNoYXJ0QXJlYS55O1xyXG5cdHZhciBpLCBpbGVuLCBsYXlvdXQsIGJveDtcclxuXHJcblx0Zm9yIChpID0gMCwgaWxlbiA9IGJveGVzLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xyXG5cdFx0bGF5b3V0ID0gYm94ZXNbaV07XHJcblx0XHRib3ggPSBsYXlvdXQuYm94O1xyXG5cdFx0aWYgKGxheW91dC5ob3Jpem9udGFsKSB7XHJcblx0XHRcdGJveC5sZWZ0ID0gYm94LmZ1bGxXaWR0aCA/IHVzZXJQYWRkaW5nLmxlZnQgOiBjaGFydEFyZWEubGVmdDtcclxuXHRcdFx0Ym94LnJpZ2h0ID0gYm94LmZ1bGxXaWR0aCA/IHBhcmFtcy5vdXRlcldpZHRoIC0gdXNlclBhZGRpbmcucmlnaHQgOiBjaGFydEFyZWEubGVmdCArIGNoYXJ0QXJlYS53O1xyXG5cdFx0XHRib3gudG9wID0geTtcclxuXHRcdFx0Ym94LmJvdHRvbSA9IHkgKyBib3guaGVpZ2h0O1xyXG5cdFx0XHRib3gud2lkdGggPSBib3gucmlnaHQgLSBib3gubGVmdDtcclxuXHRcdFx0eSA9IGJveC5ib3R0b207XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRib3gubGVmdCA9IHg7XHJcblx0XHRcdGJveC5yaWdodCA9IHggKyBib3gud2lkdGg7XHJcblx0XHRcdGJveC50b3AgPSBjaGFydEFyZWEudG9wO1xyXG5cdFx0XHRib3guYm90dG9tID0gY2hhcnRBcmVhLnRvcCArIGNoYXJ0QXJlYS5oO1xyXG5cdFx0XHRib3guaGVpZ2h0ID0gYm94LmJvdHRvbSAtIGJveC50b3A7XHJcblx0XHRcdHggPSBib3gucmlnaHQ7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRjaGFydEFyZWEueCA9IHg7XHJcblx0Y2hhcnRBcmVhLnkgPSB5O1xyXG59XHJcblxyXG5jb3JlX2RlZmF1bHRzLl9zZXQoJ2dsb2JhbCcsIHtcclxuXHRsYXlvdXQ6IHtcclxuXHRcdHBhZGRpbmc6IHtcclxuXHRcdFx0dG9wOiAwLFxyXG5cdFx0XHRyaWdodDogMCxcclxuXHRcdFx0Ym90dG9tOiAwLFxyXG5cdFx0XHRsZWZ0OiAwXHJcblx0XHR9XHJcblx0fVxyXG59KTtcclxuXHJcbi8qKlxyXG4gKiBAaW50ZXJmYWNlIElMYXlvdXRJdGVtXHJcbiAqIEBwcm9wIHtzdHJpbmd9IHBvc2l0aW9uIC0gVGhlIHBvc2l0aW9uIG9mIHRoZSBpdGVtIGluIHRoZSBjaGFydCBsYXlvdXQuIFBvc3NpYmxlIHZhbHVlcyBhcmVcclxuICogJ2xlZnQnLCAndG9wJywgJ3JpZ2h0JywgJ2JvdHRvbScsIGFuZCAnY2hhcnRBcmVhJ1xyXG4gKiBAcHJvcCB7bnVtYmVyfSB3ZWlnaHQgLSBUaGUgd2VpZ2h0IHVzZWQgdG8gc29ydCB0aGUgaXRlbS4gSGlnaGVyIHdlaWdodHMgYXJlIGZ1cnRoZXIgYXdheSBmcm9tIHRoZSBjaGFydCBhcmVhXHJcbiAqIEBwcm9wIHtib29sZWFufSBmdWxsV2lkdGggLSBpZiB0cnVlLCBhbmQgdGhlIGl0ZW0gaXMgaG9yaXpvbnRhbCwgdGhlbiBwdXNoIHZlcnRpY2FsIGJveGVzIGRvd25cclxuICogQHByb3Age2Z1bmN0aW9ufSBpc0hvcml6b250YWwgLSByZXR1cm5zIHRydWUgaWYgdGhlIGxheW91dCBpdGVtIGlzIGhvcml6b250YWwgKGllLiB0b3Agb3IgYm90dG9tKVxyXG4gKiBAcHJvcCB7ZnVuY3Rpb259IHVwZGF0ZSAtIFRha2VzIHR3byBwYXJhbWV0ZXJzOiB3aWR0aCBhbmQgaGVpZ2h0LiBSZXR1cm5zIHNpemUgb2YgaXRlbVxyXG4gKiBAcHJvcCB7ZnVuY3Rpb259IGdldFBhZGRpbmcgLSAgUmV0dXJucyBhbiBvYmplY3Qgd2l0aCBwYWRkaW5nIG9uIHRoZSBlZGdlc1xyXG4gKiBAcHJvcCB7bnVtYmVyfSB3aWR0aCAtIFdpZHRoIG9mIGl0ZW0uIE11c3QgYmUgdmFsaWQgYWZ0ZXIgdXBkYXRlKClcclxuICogQHByb3Age251bWJlcn0gaGVpZ2h0IC0gSGVpZ2h0IG9mIGl0ZW0uIE11c3QgYmUgdmFsaWQgYWZ0ZXIgdXBkYXRlKClcclxuICogQHByb3Age251bWJlcn0gbGVmdCAtIExlZnQgZWRnZSBvZiB0aGUgaXRlbS4gU2V0IGJ5IGxheW91dCBzeXN0ZW0gYW5kIGNhbm5vdCBiZSB1c2VkIGluIHVwZGF0ZVxyXG4gKiBAcHJvcCB7bnVtYmVyfSB0b3AgLSBUb3AgZWRnZSBvZiB0aGUgaXRlbS4gU2V0IGJ5IGxheW91dCBzeXN0ZW0gYW5kIGNhbm5vdCBiZSB1c2VkIGluIHVwZGF0ZVxyXG4gKiBAcHJvcCB7bnVtYmVyfSByaWdodCAtIFJpZ2h0IGVkZ2Ugb2YgdGhlIGl0ZW0uIFNldCBieSBsYXlvdXQgc3lzdGVtIGFuZCBjYW5ub3QgYmUgdXNlZCBpbiB1cGRhdGVcclxuICogQHByb3Age251bWJlcn0gYm90dG9tIC0gQm90dG9tIGVkZ2Ugb2YgdGhlIGl0ZW0uIFNldCBieSBsYXlvdXQgc3lzdGVtIGFuZCBjYW5ub3QgYmUgdXNlZCBpbiB1cGRhdGVcclxuICovXHJcblxyXG4vLyBUaGUgbGF5b3V0IHNlcnZpY2UgaXMgdmVyeSBzZWxmIGV4cGxhbmF0b3J5LiAgSXQncyByZXNwb25zaWJsZSBmb3IgdGhlIGxheW91dCB3aXRoaW4gYSBjaGFydC5cclxuLy8gU2NhbGVzLCBMZWdlbmRzIGFuZCBQbHVnaW5zIGFsbCByZWx5IG9uIHRoZSBsYXlvdXQgc2VydmljZSBhbmQgY2FuIGVhc2lseSByZWdpc3RlciB0byBiZSBwbGFjZWQgYW55d2hlcmUgdGhleSBuZWVkXHJcbi8vIEl0IGlzIHRoaXMgc2VydmljZSdzIHJlc3BvbnNpYmlsaXR5IG9mIGNhcnJ5aW5nIG91dCB0aGF0IGxheW91dC5cclxudmFyIGNvcmVfbGF5b3V0cyA9IHtcclxuXHRkZWZhdWx0czoge30sXHJcblxyXG5cdC8qKlxyXG5cdCAqIFJlZ2lzdGVyIGEgYm94IHRvIGEgY2hhcnQuXHJcblx0ICogQSBib3ggaXMgc2ltcGx5IGEgcmVmZXJlbmNlIHRvIGFuIG9iamVjdCB0aGF0IHJlcXVpcmVzIGxheW91dC4gZWcuIFNjYWxlcywgTGVnZW5kLCBUaXRsZS5cclxuXHQgKiBAcGFyYW0ge0NoYXJ0fSBjaGFydCAtIHRoZSBjaGFydCB0byB1c2VcclxuXHQgKiBAcGFyYW0ge0lMYXlvdXRJdGVtfSBpdGVtIC0gdGhlIGl0ZW0gdG8gYWRkIHRvIGJlIGxheWVkIG91dFxyXG5cdCAqL1xyXG5cdGFkZEJveDogZnVuY3Rpb24oY2hhcnQsIGl0ZW0pIHtcclxuXHRcdGlmICghY2hhcnQuYm94ZXMpIHtcclxuXHRcdFx0Y2hhcnQuYm94ZXMgPSBbXTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBpbml0aWFsaXplIGl0ZW0gd2l0aCBkZWZhdWx0IHZhbHVlc1xyXG5cdFx0aXRlbS5mdWxsV2lkdGggPSBpdGVtLmZ1bGxXaWR0aCB8fCBmYWxzZTtcclxuXHRcdGl0ZW0ucG9zaXRpb24gPSBpdGVtLnBvc2l0aW9uIHx8ICd0b3AnO1xyXG5cdFx0aXRlbS53ZWlnaHQgPSBpdGVtLndlaWdodCB8fCAwO1xyXG5cdFx0aXRlbS5fbGF5ZXJzID0gaXRlbS5fbGF5ZXJzIHx8IGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRyZXR1cm4gW3tcclxuXHRcdFx0XHR6OiAwLFxyXG5cdFx0XHRcdGRyYXc6IGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdFx0aXRlbS5kcmF3LmFwcGx5KGl0ZW0sIGFyZ3VtZW50cyk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XTtcclxuXHRcdH07XHJcblxyXG5cdFx0Y2hhcnQuYm94ZXMucHVzaChpdGVtKTtcclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBSZW1vdmUgYSBsYXlvdXRJdGVtIGZyb20gYSBjaGFydFxyXG5cdCAqIEBwYXJhbSB7Q2hhcnR9IGNoYXJ0IC0gdGhlIGNoYXJ0IHRvIHJlbW92ZSB0aGUgYm94IGZyb21cclxuXHQgKiBAcGFyYW0ge0lMYXlvdXRJdGVtfSBsYXlvdXRJdGVtIC0gdGhlIGl0ZW0gdG8gcmVtb3ZlIGZyb20gdGhlIGxheW91dFxyXG5cdCAqL1xyXG5cdHJlbW92ZUJveDogZnVuY3Rpb24oY2hhcnQsIGxheW91dEl0ZW0pIHtcclxuXHRcdHZhciBpbmRleCA9IGNoYXJ0LmJveGVzID8gY2hhcnQuYm94ZXMuaW5kZXhPZihsYXlvdXRJdGVtKSA6IC0xO1xyXG5cdFx0aWYgKGluZGV4ICE9PSAtMSkge1xyXG5cdFx0XHRjaGFydC5ib3hlcy5zcGxpY2UoaW5kZXgsIDEpO1xyXG5cdFx0fVxyXG5cdH0sXHJcblxyXG5cdC8qKlxyXG5cdCAqIFNldHMgKG9yIHVwZGF0ZXMpIG9wdGlvbnMgb24gdGhlIGdpdmVuIGBpdGVtYC5cclxuXHQgKiBAcGFyYW0ge0NoYXJ0fSBjaGFydCAtIHRoZSBjaGFydCBpbiB3aGljaCB0aGUgaXRlbSBsaXZlcyAob3Igd2lsbCBiZSBhZGRlZCB0bylcclxuXHQgKiBAcGFyYW0ge0lMYXlvdXRJdGVtfSBpdGVtIC0gdGhlIGl0ZW0gdG8gY29uZmlndXJlIHdpdGggdGhlIGdpdmVuIG9wdGlvbnNcclxuXHQgKiBAcGFyYW0ge29iamVjdH0gb3B0aW9ucyAtIHRoZSBuZXcgaXRlbSBvcHRpb25zLlxyXG5cdCAqL1xyXG5cdGNvbmZpZ3VyZTogZnVuY3Rpb24oY2hhcnQsIGl0ZW0sIG9wdGlvbnMpIHtcclxuXHRcdHZhciBwcm9wcyA9IFsnZnVsbFdpZHRoJywgJ3Bvc2l0aW9uJywgJ3dlaWdodCddO1xyXG5cdFx0dmFyIGlsZW4gPSBwcm9wcy5sZW5ndGg7XHJcblx0XHR2YXIgaSA9IDA7XHJcblx0XHR2YXIgcHJvcDtcclxuXHJcblx0XHRmb3IgKDsgaSA8IGlsZW47ICsraSkge1xyXG5cdFx0XHRwcm9wID0gcHJvcHNbaV07XHJcblx0XHRcdGlmIChvcHRpb25zLmhhc093blByb3BlcnR5KHByb3ApKSB7XHJcblx0XHRcdFx0aXRlbVtwcm9wXSA9IG9wdGlvbnNbcHJvcF07XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBGaXRzIGJveGVzIG9mIHRoZSBnaXZlbiBjaGFydCBpbnRvIHRoZSBnaXZlbiBzaXplIGJ5IGhhdmluZyBlYWNoIGJveCBtZWFzdXJlIGl0c2VsZlxyXG5cdCAqIHRoZW4gcnVubmluZyBhIGZpdHRpbmcgYWxnb3JpdGhtXHJcblx0ICogQHBhcmFtIHtDaGFydH0gY2hhcnQgLSB0aGUgY2hhcnRcclxuXHQgKiBAcGFyYW0ge251bWJlcn0gd2lkdGggLSB0aGUgd2lkdGggdG8gZml0IGludG9cclxuXHQgKiBAcGFyYW0ge251bWJlcn0gaGVpZ2h0IC0gdGhlIGhlaWdodCB0byBmaXQgaW50b1xyXG5cdCAqL1xyXG5cdHVwZGF0ZTogZnVuY3Rpb24oY2hhcnQsIHdpZHRoLCBoZWlnaHQpIHtcclxuXHRcdGlmICghY2hhcnQpIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdHZhciBsYXlvdXRPcHRpb25zID0gY2hhcnQub3B0aW9ucy5sYXlvdXQgfHwge307XHJcblx0XHR2YXIgcGFkZGluZyA9IGhlbHBlcnMkMS5vcHRpb25zLnRvUGFkZGluZyhsYXlvdXRPcHRpb25zLnBhZGRpbmcpO1xyXG5cclxuXHRcdHZhciBhdmFpbGFibGVXaWR0aCA9IHdpZHRoIC0gcGFkZGluZy53aWR0aDtcclxuXHRcdHZhciBhdmFpbGFibGVIZWlnaHQgPSBoZWlnaHQgLSBwYWRkaW5nLmhlaWdodDtcclxuXHRcdHZhciBib3hlcyA9IGJ1aWxkTGF5b3V0Qm94ZXMoY2hhcnQuYm94ZXMpO1xyXG5cdFx0dmFyIHZlcnRpY2FsQm94ZXMgPSBib3hlcy52ZXJ0aWNhbDtcclxuXHRcdHZhciBob3Jpem9udGFsQm94ZXMgPSBib3hlcy5ob3Jpem9udGFsO1xyXG5cclxuXHRcdC8vIEVzc2VudGlhbGx5IHdlIG5vdyBoYXZlIGFueSBudW1iZXIgb2YgYm94ZXMgb24gZWFjaCBvZiB0aGUgNCBzaWRlcy5cclxuXHRcdC8vIE91ciBjYW52YXMgbG9va3MgbGlrZSB0aGUgZm9sbG93aW5nLlxyXG5cdFx0Ly8gVGhlIGFyZWFzIEwxIGFuZCBMMiBhcmUgdGhlIGxlZnQgYXhlcy4gUjEgaXMgdGhlIHJpZ2h0IGF4aXMsIFQxIGlzIHRoZSB0b3AgYXhpcyBhbmRcclxuXHRcdC8vIEIxIGlzIHRoZSBib3R0b20gYXhpc1xyXG5cdFx0Ly8gVGhlcmUgYXJlIGFsc28gNCBxdWFkcmFudC1saWtlIGxvY2F0aW9ucyAobGVmdCB0byByaWdodCBpbnN0ZWFkIG9mIGNsb2Nrd2lzZSkgcmVzZXJ2ZWQgZm9yIGNoYXJ0IG92ZXJsYXlzXHJcblx0XHQvLyBUaGVzZSBsb2NhdGlvbnMgYXJlIHNpbmdsZS1ib3ggbG9jYXRpb25zIG9ubHksIHdoZW4gdHJ5aW5nIHRvIHJlZ2lzdGVyIGEgY2hhcnRBcmVhIGxvY2F0aW9uIHRoYXQgaXMgYWxyZWFkeSB0YWtlbixcclxuXHRcdC8vIGFuIGVycm9yIHdpbGwgYmUgdGhyb3duLlxyXG5cdFx0Ly9cclxuXHRcdC8vIHwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfFxyXG5cdFx0Ly8gfCAgICAgICAgICAgICAgICAgIFQxIChGdWxsIFdpZHRoKSAgICAgICAgICAgICAgICAgICB8XHJcblx0XHQvLyB8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXxcclxuXHRcdC8vIHwgICAgfCAgICB8ICAgICAgICAgICAgICAgICBUMiAgICAgICAgICAgICAgICAgIHwgICAgfFxyXG5cdFx0Ly8gfCAgICB8LS0tLXwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfC0tLS18XHJcblx0XHQvLyB8ICAgIHwgICAgfCBDMSB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBDMiB8ICAgIHxcclxuXHRcdC8vIHwgICAgfCAgICB8LS0tLXwgICAgICAgICAgICAgICAgICAgICAgICAgICB8LS0tLXwgICAgfFxyXG5cdFx0Ly8gfCAgICB8ICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICB8XHJcblx0XHQvLyB8IEwxIHwgTDIgfCAgICAgICAgICAgQ2hhcnRBcmVhIChDMCkgICAgICAgICAgICB8IFIxIHxcclxuXHRcdC8vIHwgICAgfCAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgICAgfFxyXG5cdFx0Ly8gfCAgICB8ICAgIHwtLS0tfCAgICAgICAgICAgICAgICAgICAgICAgICAgIHwtLS0tfCAgICB8XHJcblx0XHQvLyB8ICAgIHwgICAgfCBDMyB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBDNCB8ICAgIHxcclxuXHRcdC8vIHwgICAgfC0tLS18LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwtLS0tfFxyXG5cdFx0Ly8gfCAgICB8ICAgIHwgICAgICAgICAgICAgICAgIEIxICAgICAgICAgICAgICAgICAgfCAgICB8XHJcblx0XHQvLyB8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXxcclxuXHRcdC8vIHwgICAgICAgICAgICAgICAgICBCMiAoRnVsbCBXaWR0aCkgICAgICAgICAgICAgICAgICAgfFxyXG5cdFx0Ly8gfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18XHJcblx0XHQvL1xyXG5cclxuXHRcdHZhciBwYXJhbXMgPSBPYmplY3QuZnJlZXplKHtcclxuXHRcdFx0b3V0ZXJXaWR0aDogd2lkdGgsXHJcblx0XHRcdG91dGVySGVpZ2h0OiBoZWlnaHQsXHJcblx0XHRcdHBhZGRpbmc6IHBhZGRpbmcsXHJcblx0XHRcdGF2YWlsYWJsZVdpZHRoOiBhdmFpbGFibGVXaWR0aCxcclxuXHRcdFx0dkJveE1heFdpZHRoOiBhdmFpbGFibGVXaWR0aCAvIDIgLyB2ZXJ0aWNhbEJveGVzLmxlbmd0aCxcclxuXHRcdFx0aEJveE1heEhlaWdodDogYXZhaWxhYmxlSGVpZ2h0IC8gMlxyXG5cdFx0fSk7XHJcblx0XHR2YXIgY2hhcnRBcmVhID0gZXh0ZW5kKHtcclxuXHRcdFx0bWF4UGFkZGluZzogZXh0ZW5kKHt9LCBwYWRkaW5nKSxcclxuXHRcdFx0dzogYXZhaWxhYmxlV2lkdGgsXHJcblx0XHRcdGg6IGF2YWlsYWJsZUhlaWdodCxcclxuXHRcdFx0eDogcGFkZGluZy5sZWZ0LFxyXG5cdFx0XHR5OiBwYWRkaW5nLnRvcFxyXG5cdFx0fSwgcGFkZGluZyk7XHJcblxyXG5cdFx0c2V0TGF5b3V0RGltcyh2ZXJ0aWNhbEJveGVzLmNvbmNhdChob3Jpem9udGFsQm94ZXMpLCBwYXJhbXMpO1xyXG5cclxuXHRcdC8vIEZpcnN0IGZpdCB2ZXJ0aWNhbCBib3hlc1xyXG5cdFx0Zml0Qm94ZXModmVydGljYWxCb3hlcywgY2hhcnRBcmVhLCBwYXJhbXMpO1xyXG5cclxuXHRcdC8vIFRoZW4gZml0IGhvcml6b250YWwgYm94ZXNcclxuXHRcdGlmIChmaXRCb3hlcyhob3Jpem9udGFsQm94ZXMsIGNoYXJ0QXJlYSwgcGFyYW1zKSkge1xyXG5cdFx0XHQvLyBpZiB0aGUgYXJlYSBjaGFuZ2VkLCByZS1maXQgdmVydGljYWwgYm94ZXNcclxuXHRcdFx0Zml0Qm94ZXModmVydGljYWxCb3hlcywgY2hhcnRBcmVhLCBwYXJhbXMpO1xyXG5cdFx0fVxyXG5cclxuXHRcdGhhbmRsZU1heFBhZGRpbmcoY2hhcnRBcmVhKTtcclxuXHJcblx0XHQvLyBGaW5hbGx5IHBsYWNlIHRoZSBib3hlcyB0byBjb3JyZWN0IGNvb3JkaW5hdGVzXHJcblx0XHRwbGFjZUJveGVzKGJveGVzLmxlZnRBbmRUb3AsIGNoYXJ0QXJlYSwgcGFyYW1zKTtcclxuXHJcblx0XHQvLyBNb3ZlIHRvIG9wcG9zaXRlIHNpZGUgb2YgY2hhcnRcclxuXHRcdGNoYXJ0QXJlYS54ICs9IGNoYXJ0QXJlYS53O1xyXG5cdFx0Y2hhcnRBcmVhLnkgKz0gY2hhcnRBcmVhLmg7XHJcblxyXG5cdFx0cGxhY2VCb3hlcyhib3hlcy5yaWdodEFuZEJvdHRvbSwgY2hhcnRBcmVhLCBwYXJhbXMpO1xyXG5cclxuXHRcdGNoYXJ0LmNoYXJ0QXJlYSA9IHtcclxuXHRcdFx0bGVmdDogY2hhcnRBcmVhLmxlZnQsXHJcblx0XHRcdHRvcDogY2hhcnRBcmVhLnRvcCxcclxuXHRcdFx0cmlnaHQ6IGNoYXJ0QXJlYS5sZWZ0ICsgY2hhcnRBcmVhLncsXHJcblx0XHRcdGJvdHRvbTogY2hhcnRBcmVhLnRvcCArIGNoYXJ0QXJlYS5oXHJcblx0XHR9O1xyXG5cclxuXHRcdC8vIEZpbmFsbHkgdXBkYXRlIGJveGVzIGluIGNoYXJ0QXJlYSAocmFkaWFsIHNjYWxlIGZvciBleGFtcGxlKVxyXG5cdFx0aGVscGVycyQxLmVhY2goYm94ZXMuY2hhcnRBcmVhLCBmdW5jdGlvbihsYXlvdXQpIHtcclxuXHRcdFx0dmFyIGJveCA9IGxheW91dC5ib3g7XHJcblx0XHRcdGV4dGVuZChib3gsIGNoYXJ0LmNoYXJ0QXJlYSk7XHJcblx0XHRcdGJveC51cGRhdGUoY2hhcnRBcmVhLncsIGNoYXJ0QXJlYS5oKTtcclxuXHRcdH0pO1xyXG5cdH1cclxufTtcblxuLyoqXHJcbiAqIFBsYXRmb3JtIGZhbGxiYWNrIGltcGxlbWVudGF0aW9uIChtaW5pbWFsKS5cclxuICogQHNlZSBodHRwczovL2dpdGh1Yi5jb20vY2hhcnRqcy9DaGFydC5qcy9wdWxsLzQ1OTEjaXNzdWVjb21tZW50LTMxOTU3NTkzOVxyXG4gKi9cclxuXHJcbnZhciBwbGF0Zm9ybV9iYXNpYyA9IHtcclxuXHRhY3F1aXJlQ29udGV4dDogZnVuY3Rpb24oaXRlbSkge1xyXG5cdFx0aWYgKGl0ZW0gJiYgaXRlbS5jYW52YXMpIHtcclxuXHRcdFx0Ly8gU3VwcG9ydCBmb3IgYW55IG9iamVjdCBhc3NvY2lhdGVkIHRvIGEgY2FudmFzIChpbmNsdWRpbmcgYSBjb250ZXh0MmQpXHJcblx0XHRcdGl0ZW0gPSBpdGVtLmNhbnZhcztcclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gaXRlbSAmJiBpdGVtLmdldENvbnRleHQoJzJkJykgfHwgbnVsbDtcclxuXHR9XHJcbn07XG5cbnZhciBwbGF0Zm9ybV9kb20gPSBcIi8qXFxyXFxuICogRE9NIGVsZW1lbnQgcmVuZGVyaW5nIGRldGVjdGlvblxcclxcbiAqIGh0dHBzOi8vZGF2aWR3YWxzaC5uYW1lL2RldGVjdC1ub2RlLWluc2VydGlvblxcclxcbiAqL1xcclxcbkBrZXlmcmFtZXMgY2hhcnRqcy1yZW5kZXItYW5pbWF0aW9uIHtcXHJcXG5cXHRmcm9tIHsgb3BhY2l0eTogMC45OTsgfVxcclxcblxcdHRvIHsgb3BhY2l0eTogMTsgfVxcclxcbn1cXHJcXG5cXHJcXG4uY2hhcnRqcy1yZW5kZXItbW9uaXRvciB7XFxyXFxuXFx0YW5pbWF0aW9uOiBjaGFydGpzLXJlbmRlci1hbmltYXRpb24gMC4wMDFzO1xcclxcbn1cXHJcXG5cXHJcXG4vKlxcclxcbiAqIERPTSBlbGVtZW50IHJlc2l6aW5nIGRldGVjdGlvblxcclxcbiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9tYXJjai9jc3MtZWxlbWVudC1xdWVyaWVzXFxyXFxuICovXFxyXFxuLmNoYXJ0anMtc2l6ZS1tb25pdG9yLFxcclxcbi5jaGFydGpzLXNpemUtbW9uaXRvci1leHBhbmQsXFxyXFxuLmNoYXJ0anMtc2l6ZS1tb25pdG9yLXNocmluayB7XFxyXFxuXFx0cG9zaXRpb246IGFic29sdXRlO1xcclxcblxcdGRpcmVjdGlvbjogbHRyO1xcclxcblxcdGxlZnQ6IDA7XFxyXFxuXFx0dG9wOiAwO1xcclxcblxcdHJpZ2h0OiAwO1xcclxcblxcdGJvdHRvbTogMDtcXHJcXG5cXHRvdmVyZmxvdzogaGlkZGVuO1xcclxcblxcdHBvaW50ZXItZXZlbnRzOiBub25lO1xcclxcblxcdHZpc2liaWxpdHk6IGhpZGRlbjtcXHJcXG5cXHR6LWluZGV4OiAtMTtcXHJcXG59XFxyXFxuXFxyXFxuLmNoYXJ0anMtc2l6ZS1tb25pdG9yLWV4cGFuZCA+IGRpdiB7XFxyXFxuXFx0cG9zaXRpb246IGFic29sdXRlO1xcclxcblxcdHdpZHRoOiAxMDAwMDAwcHg7XFxyXFxuXFx0aGVpZ2h0OiAxMDAwMDAwcHg7XFxyXFxuXFx0bGVmdDogMDtcXHJcXG5cXHR0b3A6IDA7XFxyXFxufVxcclxcblxcclxcbi5jaGFydGpzLXNpemUtbW9uaXRvci1zaHJpbmsgPiBkaXYge1xcclxcblxcdHBvc2l0aW9uOiBhYnNvbHV0ZTtcXHJcXG5cXHR3aWR0aDogMjAwJTtcXHJcXG5cXHRoZWlnaHQ6IDIwMCU7XFxyXFxuXFx0bGVmdDogMDtcXHJcXG5cXHR0b3A6IDA7XFxyXFxufVxcclxcblwiO1xuXG52YXIgcGxhdGZvcm1fZG9tJDEgPSAvKiNfX1BVUkVfXyovT2JqZWN0LmZyZWV6ZSh7XG5fX3Byb3RvX186IG51bGwsXG4nZGVmYXVsdCc6IHBsYXRmb3JtX2RvbVxufSk7XG5cbnZhciBzdHlsZXNoZWV0ID0gZ2V0Q2pzRXhwb3J0RnJvbU5hbWVzcGFjZShwbGF0Zm9ybV9kb20kMSk7XG5cbnZhciBFWFBBTkRPX0tFWSA9ICckY2hhcnRqcyc7XHJcbnZhciBDU1NfUFJFRklYID0gJ2NoYXJ0anMtJztcclxudmFyIENTU19TSVpFX01PTklUT1IgPSBDU1NfUFJFRklYICsgJ3NpemUtbW9uaXRvcic7XHJcbnZhciBDU1NfUkVOREVSX01PTklUT1IgPSBDU1NfUFJFRklYICsgJ3JlbmRlci1tb25pdG9yJztcclxudmFyIENTU19SRU5ERVJfQU5JTUFUSU9OID0gQ1NTX1BSRUZJWCArICdyZW5kZXItYW5pbWF0aW9uJztcclxudmFyIEFOSU1BVElPTl9TVEFSVF9FVkVOVFMgPSBbJ2FuaW1hdGlvbnN0YXJ0JywgJ3dlYmtpdEFuaW1hdGlvblN0YXJ0J107XHJcblxyXG4vKipcclxuICogRE9NIGV2ZW50IHR5cGVzIC0+IENoYXJ0LmpzIGV2ZW50IHR5cGVzLlxyXG4gKiBOb3RlOiBvbmx5IGV2ZW50cyB3aXRoIGRpZmZlcmVudCB0eXBlcyBhcmUgbWFwcGVkLlxyXG4gKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0V2ZW50c1xyXG4gKi9cclxudmFyIEVWRU5UX1RZUEVTID0ge1xyXG5cdHRvdWNoc3RhcnQ6ICdtb3VzZWRvd24nLFxyXG5cdHRvdWNobW92ZTogJ21vdXNlbW92ZScsXHJcblx0dG91Y2hlbmQ6ICdtb3VzZXVwJyxcclxuXHRwb2ludGVyZW50ZXI6ICdtb3VzZWVudGVyJyxcclxuXHRwb2ludGVyZG93bjogJ21vdXNlZG93bicsXHJcblx0cG9pbnRlcm1vdmU6ICdtb3VzZW1vdmUnLFxyXG5cdHBvaW50ZXJ1cDogJ21vdXNldXAnLFxyXG5cdHBvaW50ZXJsZWF2ZTogJ21vdXNlb3V0JyxcclxuXHRwb2ludGVyb3V0OiAnbW91c2VvdXQnXHJcbn07XHJcblxyXG4vKipcclxuICogVGhlIFwidXNlZFwiIHNpemUgaXMgdGhlIGZpbmFsIHZhbHVlIG9mIGEgZGltZW5zaW9uIHByb3BlcnR5IGFmdGVyIGFsbCBjYWxjdWxhdGlvbnMgaGF2ZVxyXG4gKiBiZWVuIHBlcmZvcm1lZC4gVGhpcyBtZXRob2QgdXNlcyB0aGUgY29tcHV0ZWQgc3R5bGUgb2YgYGVsZW1lbnRgIGJ1dCByZXR1cm5zIHVuZGVmaW5lZFxyXG4gKiBpZiB0aGUgY29tcHV0ZWQgc3R5bGUgaXMgbm90IGV4cHJlc3NlZCBpbiBwaXhlbHMuIFRoYXQgY2FuIGhhcHBlbiBpbiBzb21lIGNhc2VzIHdoZXJlXHJcbiAqIGBlbGVtZW50YCBoYXMgYSBzaXplIHJlbGF0aXZlIHRvIGl0cyBwYXJlbnQgYW5kIHRoaXMgbGFzdCBvbmUgaXMgbm90IHlldCBkaXNwbGF5ZWQsXHJcbiAqIGZvciBleGFtcGxlIGJlY2F1c2Ugb2YgYGRpc3BsYXk6IG5vbmVgIG9uIGEgcGFyZW50IG5vZGUuXHJcbiAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQ1NTL3VzZWRfdmFsdWVcclxuICogQHJldHVybnMge251bWJlcn0gU2l6ZSBpbiBwaXhlbHMgb3IgdW5kZWZpbmVkIGlmIHVua25vd24uXHJcbiAqL1xyXG5mdW5jdGlvbiByZWFkVXNlZFNpemUoZWxlbWVudCwgcHJvcGVydHkpIHtcclxuXHR2YXIgdmFsdWUgPSBoZWxwZXJzJDEuZ2V0U3R5bGUoZWxlbWVudCwgcHJvcGVydHkpO1xyXG5cdHZhciBtYXRjaGVzID0gdmFsdWUgJiYgdmFsdWUubWF0Y2goL14oXFxkKykoXFwuXFxkKyk/cHgkLyk7XHJcblx0cmV0dXJuIG1hdGNoZXMgPyBOdW1iZXIobWF0Y2hlc1sxXSkgOiB1bmRlZmluZWQ7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBJbml0aWFsaXplcyB0aGUgY2FudmFzIHN0eWxlIGFuZCByZW5kZXIgc2l6ZSB3aXRob3V0IG1vZGlmeWluZyB0aGUgY2FudmFzIGRpc3BsYXkgc2l6ZSxcclxuICogc2luY2UgcmVzcG9uc2l2ZW5lc3MgaXMgaGFuZGxlZCBieSB0aGUgY29udHJvbGxlci5yZXNpemUoKSBtZXRob2QuIFRoZSBjb25maWcgaXMgdXNlZFxyXG4gKiB0byBkZXRlcm1pbmUgdGhlIGFzcGVjdCByYXRpbyB0byBhcHBseSBpbiBjYXNlIG5vIGV4cGxpY2l0IGhlaWdodCBoYXMgYmVlbiBzcGVjaWZpZWQuXHJcbiAqL1xyXG5mdW5jdGlvbiBpbml0Q2FudmFzKGNhbnZhcywgY29uZmlnKSB7XHJcblx0dmFyIHN0eWxlID0gY2FudmFzLnN0eWxlO1xyXG5cclxuXHQvLyBOT1RFKFNCKSBjYW52YXMuZ2V0QXR0cmlidXRlKCd3aWR0aCcpICE9PSBjYW52YXMud2lkdGg6IGluIHRoZSBmaXJzdCBjYXNlIGl0XHJcblx0Ly8gcmV0dXJucyBudWxsIG9yICcnIGlmIG5vIGV4cGxpY2l0IHZhbHVlIGhhcyBiZWVuIHNldCB0byB0aGUgY2FudmFzIGF0dHJpYnV0ZS5cclxuXHR2YXIgcmVuZGVySGVpZ2h0ID0gY2FudmFzLmdldEF0dHJpYnV0ZSgnaGVpZ2h0Jyk7XHJcblx0dmFyIHJlbmRlcldpZHRoID0gY2FudmFzLmdldEF0dHJpYnV0ZSgnd2lkdGgnKTtcclxuXHJcblx0Ly8gQ2hhcnQuanMgbW9kaWZpZXMgc29tZSBjYW52YXMgdmFsdWVzIHRoYXQgd2Ugd2FudCB0byByZXN0b3JlIG9uIGRlc3Ryb3lcclxuXHRjYW52YXNbRVhQQU5ET19LRVldID0ge1xyXG5cdFx0aW5pdGlhbDoge1xyXG5cdFx0XHRoZWlnaHQ6IHJlbmRlckhlaWdodCxcclxuXHRcdFx0d2lkdGg6IHJlbmRlcldpZHRoLFxyXG5cdFx0XHRzdHlsZToge1xyXG5cdFx0XHRcdGRpc3BsYXk6IHN0eWxlLmRpc3BsYXksXHJcblx0XHRcdFx0aGVpZ2h0OiBzdHlsZS5oZWlnaHQsXHJcblx0XHRcdFx0d2lkdGg6IHN0eWxlLndpZHRoXHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHR9O1xyXG5cclxuXHQvLyBGb3JjZSBjYW52YXMgdG8gZGlzcGxheSBhcyBibG9jayB0byBhdm9pZCBleHRyYSBzcGFjZSBjYXVzZWQgYnkgaW5saW5lXHJcblx0Ly8gZWxlbWVudHMsIHdoaWNoIHdvdWxkIGludGVyZmVyZSB3aXRoIHRoZSByZXNwb25zaXZlIHJlc2l6ZSBwcm9jZXNzLlxyXG5cdC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9jaGFydGpzL0NoYXJ0LmpzL2lzc3Vlcy8yNTM4XHJcblx0c3R5bGUuZGlzcGxheSA9IHN0eWxlLmRpc3BsYXkgfHwgJ2Jsb2NrJztcclxuXHJcblx0aWYgKHJlbmRlcldpZHRoID09PSBudWxsIHx8IHJlbmRlcldpZHRoID09PSAnJykge1xyXG5cdFx0dmFyIGRpc3BsYXlXaWR0aCA9IHJlYWRVc2VkU2l6ZShjYW52YXMsICd3aWR0aCcpO1xyXG5cdFx0aWYgKGRpc3BsYXlXaWR0aCAhPT0gdW5kZWZpbmVkKSB7XHJcblx0XHRcdGNhbnZhcy53aWR0aCA9IGRpc3BsYXlXaWR0aDtcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdGlmIChyZW5kZXJIZWlnaHQgPT09IG51bGwgfHwgcmVuZGVySGVpZ2h0ID09PSAnJykge1xyXG5cdFx0aWYgKGNhbnZhcy5zdHlsZS5oZWlnaHQgPT09ICcnKSB7XHJcblx0XHRcdC8vIElmIG5vIGV4cGxpY2l0IHJlbmRlciBoZWlnaHQgYW5kIHN0eWxlIGhlaWdodCwgbGV0J3MgYXBwbHkgdGhlIGFzcGVjdCByYXRpbyxcclxuXHRcdFx0Ly8gd2hpY2ggb25lIGNhbiBiZSBzcGVjaWZpZWQgYnkgdGhlIHVzZXIgYnV0IGFsc28gYnkgY2hhcnRzIGFzIGRlZmF1bHQgb3B0aW9uXHJcblx0XHRcdC8vIChpLmUuIG9wdGlvbnMuYXNwZWN0UmF0aW8pLiBJZiBub3Qgc3BlY2lmaWVkLCB1c2UgY2FudmFzIGFzcGVjdCByYXRpbyBvZiAyLlxyXG5cdFx0XHRjYW52YXMuaGVpZ2h0ID0gY2FudmFzLndpZHRoIC8gKGNvbmZpZy5vcHRpb25zLmFzcGVjdFJhdGlvIHx8IDIpO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0dmFyIGRpc3BsYXlIZWlnaHQgPSByZWFkVXNlZFNpemUoY2FudmFzLCAnaGVpZ2h0Jyk7XHJcblx0XHRcdGlmIChkaXNwbGF5V2lkdGggIT09IHVuZGVmaW5lZCkge1xyXG5cdFx0XHRcdGNhbnZhcy5oZWlnaHQgPSBkaXNwbGF5SGVpZ2h0O1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRyZXR1cm4gY2FudmFzO1xyXG59XHJcblxyXG4vKipcclxuICogRGV0ZWN0cyBzdXBwb3J0IGZvciBvcHRpb25zIG9iamVjdCBhcmd1bWVudCBpbiBhZGRFdmVudExpc3RlbmVyLlxyXG4gKiBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvRXZlbnRUYXJnZXQvYWRkRXZlbnRMaXN0ZW5lciNTYWZlbHlfZGV0ZWN0aW5nX29wdGlvbl9zdXBwb3J0XHJcbiAqIEBwcml2YXRlXHJcbiAqL1xyXG52YXIgc3VwcG9ydHNFdmVudExpc3RlbmVyT3B0aW9ucyA9IChmdW5jdGlvbigpIHtcclxuXHR2YXIgc3VwcG9ydHMgPSBmYWxzZTtcclxuXHR0cnkge1xyXG5cdFx0dmFyIG9wdGlvbnMgPSBPYmplY3QuZGVmaW5lUHJvcGVydHkoe30sICdwYXNzaXZlJywge1xyXG5cdFx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZ2V0dGVyLXJldHVyblxyXG5cdFx0XHRnZXQ6IGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdHN1cHBvcnRzID0gdHJ1ZTtcclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblx0XHR3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignZScsIG51bGwsIG9wdGlvbnMpO1xyXG5cdH0gY2F0Y2ggKGUpIHtcclxuXHRcdC8vIGNvbnRpbnVlIHJlZ2FyZGxlc3Mgb2YgZXJyb3JcclxuXHR9XHJcblx0cmV0dXJuIHN1cHBvcnRzO1xyXG59KCkpO1xyXG5cclxuLy8gRGVmYXVsdCBwYXNzaXZlIHRvIHRydWUgYXMgZXhwZWN0ZWQgYnkgQ2hyb21lIGZvciAndG91Y2hzdGFydCcgYW5kICd0b3VjaGVuZCcgZXZlbnRzLlxyXG4vLyBodHRwczovL2dpdGh1Yi5jb20vY2hhcnRqcy9DaGFydC5qcy9pc3N1ZXMvNDI4N1xyXG52YXIgZXZlbnRMaXN0ZW5lck9wdGlvbnMgPSBzdXBwb3J0c0V2ZW50TGlzdGVuZXJPcHRpb25zID8ge3Bhc3NpdmU6IHRydWV9IDogZmFsc2U7XHJcblxyXG5mdW5jdGlvbiBhZGRMaXN0ZW5lcihub2RlLCB0eXBlLCBsaXN0ZW5lcikge1xyXG5cdG5vZGUuYWRkRXZlbnRMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lciwgZXZlbnRMaXN0ZW5lck9wdGlvbnMpO1xyXG59XHJcblxyXG5mdW5jdGlvbiByZW1vdmVMaXN0ZW5lcihub2RlLCB0eXBlLCBsaXN0ZW5lcikge1xyXG5cdG5vZGUucmVtb3ZlRXZlbnRMaXN0ZW5lcih0eXBlLCBsaXN0ZW5lciwgZXZlbnRMaXN0ZW5lck9wdGlvbnMpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBjcmVhdGVFdmVudCh0eXBlLCBjaGFydCwgeCwgeSwgbmF0aXZlRXZlbnQpIHtcclxuXHRyZXR1cm4ge1xyXG5cdFx0dHlwZTogdHlwZSxcclxuXHRcdGNoYXJ0OiBjaGFydCxcclxuXHRcdG5hdGl2ZTogbmF0aXZlRXZlbnQgfHwgbnVsbCxcclxuXHRcdHg6IHggIT09IHVuZGVmaW5lZCA/IHggOiBudWxsLFxyXG5cdFx0eTogeSAhPT0gdW5kZWZpbmVkID8geSA6IG51bGwsXHJcblx0fTtcclxufVxyXG5cclxuZnVuY3Rpb24gZnJvbU5hdGl2ZUV2ZW50KGV2ZW50LCBjaGFydCkge1xyXG5cdHZhciB0eXBlID0gRVZFTlRfVFlQRVNbZXZlbnQudHlwZV0gfHwgZXZlbnQudHlwZTtcclxuXHR2YXIgcG9zID0gaGVscGVycyQxLmdldFJlbGF0aXZlUG9zaXRpb24oZXZlbnQsIGNoYXJ0KTtcclxuXHRyZXR1cm4gY3JlYXRlRXZlbnQodHlwZSwgY2hhcnQsIHBvcy54LCBwb3MueSwgZXZlbnQpO1xyXG59XHJcblxyXG5mdW5jdGlvbiB0aHJvdHRsZWQoZm4sIHRoaXNBcmcpIHtcclxuXHR2YXIgdGlja2luZyA9IGZhbHNlO1xyXG5cdHZhciBhcmdzID0gW107XHJcblxyXG5cdHJldHVybiBmdW5jdGlvbigpIHtcclxuXHRcdGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpO1xyXG5cdFx0dGhpc0FyZyA9IHRoaXNBcmcgfHwgdGhpcztcclxuXHJcblx0XHRpZiAoIXRpY2tpbmcpIHtcclxuXHRcdFx0dGlja2luZyA9IHRydWU7XHJcblx0XHRcdGhlbHBlcnMkMS5yZXF1ZXN0QW5pbUZyYW1lLmNhbGwod2luZG93LCBmdW5jdGlvbigpIHtcclxuXHRcdFx0XHR0aWNraW5nID0gZmFsc2U7XHJcblx0XHRcdFx0Zm4uYXBwbHkodGhpc0FyZywgYXJncyk7XHJcblx0XHRcdH0pO1xyXG5cdFx0fVxyXG5cdH07XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGNyZWF0ZURpdihjbHMpIHtcclxuXHR2YXIgZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcclxuXHRlbC5jbGFzc05hbWUgPSBjbHMgfHwgJyc7XHJcblx0cmV0dXJuIGVsO1xyXG59XHJcblxyXG4vLyBJbXBsZW1lbnRhdGlvbiBiYXNlZCBvbiBodHRwczovL2dpdGh1Yi5jb20vbWFyY2ovY3NzLWVsZW1lbnQtcXVlcmllc1xyXG5mdW5jdGlvbiBjcmVhdGVSZXNpemVyKGhhbmRsZXIpIHtcclxuXHR2YXIgbWF4U2l6ZSA9IDEwMDAwMDA7XHJcblxyXG5cdC8vIE5PVEUoU0IpIERvbid0IHVzZSBpbm5lckhUTUwgYmVjYXVzZSBpdCBjb3VsZCBiZSBjb25zaWRlcmVkIHVuc2FmZS5cclxuXHQvLyBodHRwczovL2dpdGh1Yi5jb20vY2hhcnRqcy9DaGFydC5qcy9pc3N1ZXMvNTkwMlxyXG5cdHZhciByZXNpemVyID0gY3JlYXRlRGl2KENTU19TSVpFX01PTklUT1IpO1xyXG5cdHZhciBleHBhbmQgPSBjcmVhdGVEaXYoQ1NTX1NJWkVfTU9OSVRPUiArICctZXhwYW5kJyk7XHJcblx0dmFyIHNocmluayA9IGNyZWF0ZURpdihDU1NfU0laRV9NT05JVE9SICsgJy1zaHJpbmsnKTtcclxuXHJcblx0ZXhwYW5kLmFwcGVuZENoaWxkKGNyZWF0ZURpdigpKTtcclxuXHRzaHJpbmsuYXBwZW5kQ2hpbGQoY3JlYXRlRGl2KCkpO1xyXG5cclxuXHRyZXNpemVyLmFwcGVuZENoaWxkKGV4cGFuZCk7XHJcblx0cmVzaXplci5hcHBlbmRDaGlsZChzaHJpbmspO1xyXG5cdHJlc2l6ZXIuX3Jlc2V0ID0gZnVuY3Rpb24oKSB7XHJcblx0XHRleHBhbmQuc2Nyb2xsTGVmdCA9IG1heFNpemU7XHJcblx0XHRleHBhbmQuc2Nyb2xsVG9wID0gbWF4U2l6ZTtcclxuXHRcdHNocmluay5zY3JvbGxMZWZ0ID0gbWF4U2l6ZTtcclxuXHRcdHNocmluay5zY3JvbGxUb3AgPSBtYXhTaXplO1xyXG5cdH07XHJcblxyXG5cdHZhciBvblNjcm9sbCA9IGZ1bmN0aW9uKCkge1xyXG5cdFx0cmVzaXplci5fcmVzZXQoKTtcclxuXHRcdGhhbmRsZXIoKTtcclxuXHR9O1xyXG5cclxuXHRhZGRMaXN0ZW5lcihleHBhbmQsICdzY3JvbGwnLCBvblNjcm9sbC5iaW5kKGV4cGFuZCwgJ2V4cGFuZCcpKTtcclxuXHRhZGRMaXN0ZW5lcihzaHJpbmssICdzY3JvbGwnLCBvblNjcm9sbC5iaW5kKHNocmluaywgJ3NocmluaycpKTtcclxuXHJcblx0cmV0dXJuIHJlc2l6ZXI7XHJcbn1cclxuXHJcbi8vIGh0dHBzOi8vZGF2aWR3YWxzaC5uYW1lL2RldGVjdC1ub2RlLWluc2VydGlvblxyXG5mdW5jdGlvbiB3YXRjaEZvclJlbmRlcihub2RlLCBoYW5kbGVyKSB7XHJcblx0dmFyIGV4cGFuZG8gPSBub2RlW0VYUEFORE9fS0VZXSB8fCAobm9kZVtFWFBBTkRPX0tFWV0gPSB7fSk7XHJcblx0dmFyIHByb3h5ID0gZXhwYW5kby5yZW5kZXJQcm94eSA9IGZ1bmN0aW9uKGUpIHtcclxuXHRcdGlmIChlLmFuaW1hdGlvbk5hbWUgPT09IENTU19SRU5ERVJfQU5JTUFUSU9OKSB7XHJcblx0XHRcdGhhbmRsZXIoKTtcclxuXHRcdH1cclxuXHR9O1xyXG5cclxuXHRoZWxwZXJzJDEuZWFjaChBTklNQVRJT05fU1RBUlRfRVZFTlRTLCBmdW5jdGlvbih0eXBlKSB7XHJcblx0XHRhZGRMaXN0ZW5lcihub2RlLCB0eXBlLCBwcm94eSk7XHJcblx0fSk7XHJcblxyXG5cdC8vICM0NzM3OiBDaHJvbWUgbWlnaHQgc2tpcCB0aGUgQ1NTIGFuaW1hdGlvbiB3aGVuIHRoZSBDU1NfUkVOREVSX01PTklUT1IgY2xhc3NcclxuXHQvLyBpcyByZW1vdmVkIHRoZW4gYWRkZWQgYmFjayBpbW1lZGlhdGVseSAoc2FtZSBhbmltYXRpb24gZnJhbWU/KS4gQWNjZXNzaW5nIHRoZVxyXG5cdC8vIGBvZmZzZXRQYXJlbnRgIHByb3BlcnR5IHdpbGwgZm9yY2UgYSByZWZsb3cgYW5kIHJlLWV2YWx1YXRlIHRoZSBDU1MgYW5pbWF0aW9uLlxyXG5cdC8vIGh0dHBzOi8vZ2lzdC5naXRodWIuY29tL3BhdWxpcmlzaC81ZDUyZmIwODFiMzU3MGM4MWUzYSNib3gtbWV0cmljc1xyXG5cdC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9jaGFydGpzL0NoYXJ0LmpzL2lzc3Vlcy80NzM3XHJcblx0ZXhwYW5kby5yZWZsb3cgPSAhIW5vZGUub2Zmc2V0UGFyZW50O1xyXG5cclxuXHRub2RlLmNsYXNzTGlzdC5hZGQoQ1NTX1JFTkRFUl9NT05JVE9SKTtcclxufVxyXG5cclxuZnVuY3Rpb24gdW53YXRjaEZvclJlbmRlcihub2RlKSB7XHJcblx0dmFyIGV4cGFuZG8gPSBub2RlW0VYUEFORE9fS0VZXSB8fCB7fTtcclxuXHR2YXIgcHJveHkgPSBleHBhbmRvLnJlbmRlclByb3h5O1xyXG5cclxuXHRpZiAocHJveHkpIHtcclxuXHRcdGhlbHBlcnMkMS5lYWNoKEFOSU1BVElPTl9TVEFSVF9FVkVOVFMsIGZ1bmN0aW9uKHR5cGUpIHtcclxuXHRcdFx0cmVtb3ZlTGlzdGVuZXIobm9kZSwgdHlwZSwgcHJveHkpO1xyXG5cdFx0fSk7XHJcblxyXG5cdFx0ZGVsZXRlIGV4cGFuZG8ucmVuZGVyUHJveHk7XHJcblx0fVxyXG5cclxuXHRub2RlLmNsYXNzTGlzdC5yZW1vdmUoQ1NTX1JFTkRFUl9NT05JVE9SKTtcclxufVxyXG5cclxuZnVuY3Rpb24gYWRkUmVzaXplTGlzdGVuZXIobm9kZSwgbGlzdGVuZXIsIGNoYXJ0KSB7XHJcblx0dmFyIGV4cGFuZG8gPSBub2RlW0VYUEFORE9fS0VZXSB8fCAobm9kZVtFWFBBTkRPX0tFWV0gPSB7fSk7XHJcblxyXG5cdC8vIExldCdzIGtlZXAgdHJhY2sgb2YgdGhpcyBhZGRlZCByZXNpemVyIGFuZCB0aHVzIGF2b2lkIERPTSBxdWVyeSB3aGVuIHJlbW92aW5nIGl0LlxyXG5cdHZhciByZXNpemVyID0gZXhwYW5kby5yZXNpemVyID0gY3JlYXRlUmVzaXplcih0aHJvdHRsZWQoZnVuY3Rpb24oKSB7XHJcblx0XHRpZiAoZXhwYW5kby5yZXNpemVyKSB7XHJcblx0XHRcdHZhciBjb250YWluZXIgPSBjaGFydC5vcHRpb25zLm1haW50YWluQXNwZWN0UmF0aW8gJiYgbm9kZS5wYXJlbnROb2RlO1xyXG5cdFx0XHR2YXIgdyA9IGNvbnRhaW5lciA/IGNvbnRhaW5lci5jbGllbnRXaWR0aCA6IDA7XHJcblx0XHRcdGxpc3RlbmVyKGNyZWF0ZUV2ZW50KCdyZXNpemUnLCBjaGFydCkpO1xyXG5cdFx0XHRpZiAoY29udGFpbmVyICYmIGNvbnRhaW5lci5jbGllbnRXaWR0aCA8IHcgJiYgY2hhcnQuY2FudmFzKSB7XHJcblx0XHRcdFx0Ly8gSWYgdGhlIGNvbnRhaW5lciBzaXplIHNocmFuayBkdXJpbmcgY2hhcnQgcmVzaXplLCBsZXQncyBhc3N1bWVcclxuXHRcdFx0XHQvLyBzY3JvbGxiYXIgYXBwZWFyZWQuIFNvIHdlIHJlc2l6ZSBhZ2FpbiB3aXRoIHRoZSBzY3JvbGxiYXIgdmlzaWJsZSAtXHJcblx0XHRcdFx0Ly8gZWZmZWN0aXZlbHkgbWFraW5nIGNoYXJ0IHNtYWxsZXIgYW5kIHRoZSBzY3JvbGxiYXIgaGlkZGVuIGFnYWluLlxyXG5cdFx0XHRcdC8vIEJlY2F1c2Ugd2UgYXJlIGluc2lkZSBgdGhyb3R0bGVkYCwgYW5kIGN1cnJlbnRseSBgdGlja2luZ2AsIHNjcm9sbFxyXG5cdFx0XHRcdC8vIGV2ZW50cyBhcmUgaWdub3JlZCBkdXJpbmcgdGhpcyB3aG9sZSAyIHJlc2l6ZSBwcm9jZXNzLlxyXG5cdFx0XHRcdC8vIElmIHdlIGFzc3VtZWQgd3JvbmcgYW5kIHNvbWV0aGluZyBlbHNlIGhhcHBlbmVkLCB3ZSBhcmUgcmVzaXppbmdcclxuXHRcdFx0XHQvLyB0d2ljZSBpbiBhIGZyYW1lIChwb3RlbnRpYWwgcGVyZm9ybWFuY2UgaXNzdWUpXHJcblx0XHRcdFx0bGlzdGVuZXIoY3JlYXRlRXZlbnQoJ3Jlc2l6ZScsIGNoYXJ0KSk7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHR9KSk7XHJcblxyXG5cdC8vIFRoZSByZXNpemVyIG5lZWRzIHRvIGJlIGF0dGFjaGVkIHRvIHRoZSBub2RlIHBhcmVudCwgc28gd2UgZmlyc3QgbmVlZCB0byBiZVxyXG5cdC8vIHN1cmUgdGhhdCBgbm9kZWAgaXMgYXR0YWNoZWQgdG8gdGhlIERPTSBiZWZvcmUgaW5qZWN0aW5nIHRoZSByZXNpemVyIGVsZW1lbnQuXHJcblx0d2F0Y2hGb3JSZW5kZXIobm9kZSwgZnVuY3Rpb24oKSB7XHJcblx0XHRpZiAoZXhwYW5kby5yZXNpemVyKSB7XHJcblx0XHRcdHZhciBjb250YWluZXIgPSBub2RlLnBhcmVudE5vZGU7XHJcblx0XHRcdGlmIChjb250YWluZXIgJiYgY29udGFpbmVyICE9PSByZXNpemVyLnBhcmVudE5vZGUpIHtcclxuXHRcdFx0XHRjb250YWluZXIuaW5zZXJ0QmVmb3JlKHJlc2l6ZXIsIGNvbnRhaW5lci5maXJzdENoaWxkKTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Ly8gVGhlIGNvbnRhaW5lciBzaXplIG1pZ2h0IGhhdmUgY2hhbmdlZCwgbGV0J3MgcmVzZXQgdGhlIHJlc2l6ZXIgc3RhdGUuXHJcblx0XHRcdHJlc2l6ZXIuX3Jlc2V0KCk7XHJcblx0XHR9XHJcblx0fSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHJlbW92ZVJlc2l6ZUxpc3RlbmVyKG5vZGUpIHtcclxuXHR2YXIgZXhwYW5kbyA9IG5vZGVbRVhQQU5ET19LRVldIHx8IHt9O1xyXG5cdHZhciByZXNpemVyID0gZXhwYW5kby5yZXNpemVyO1xyXG5cclxuXHRkZWxldGUgZXhwYW5kby5yZXNpemVyO1xyXG5cdHVud2F0Y2hGb3JSZW5kZXIobm9kZSk7XHJcblxyXG5cdGlmIChyZXNpemVyICYmIHJlc2l6ZXIucGFyZW50Tm9kZSkge1xyXG5cdFx0cmVzaXplci5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHJlc2l6ZXIpO1xyXG5cdH1cclxufVxyXG5cclxuLyoqXHJcbiAqIEluamVjdHMgQ1NTIHN0eWxlcyBpbmxpbmUgaWYgdGhlIHN0eWxlcyBhcmUgbm90IGFscmVhZHkgcHJlc2VudC5cclxuICogQHBhcmFtIHtIVE1MRG9jdW1lbnR8U2hhZG93Um9vdH0gcm9vdE5vZGUgLSB0aGUgbm9kZSB0byBjb250YWluIHRoZSA8c3R5bGU+LlxyXG4gKiBAcGFyYW0ge3N0cmluZ30gY3NzIC0gdGhlIENTUyB0byBiZSBpbmplY3RlZC5cclxuICovXHJcbmZ1bmN0aW9uIGluamVjdENTUyhyb290Tm9kZSwgY3NzKSB7XHJcblx0Ly8gaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xLzM5MjIxMzlcclxuXHR2YXIgZXhwYW5kbyA9IHJvb3ROb2RlW0VYUEFORE9fS0VZXSB8fCAocm9vdE5vZGVbRVhQQU5ET19LRVldID0ge30pO1xyXG5cdGlmICghZXhwYW5kby5jb250YWluc1N0eWxlcykge1xyXG5cdFx0ZXhwYW5kby5jb250YWluc1N0eWxlcyA9IHRydWU7XHJcblx0XHRjc3MgPSAnLyogQ2hhcnQuanMgKi9cXG4nICsgY3NzO1xyXG5cdFx0dmFyIHN0eWxlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3R5bGUnKTtcclxuXHRcdHN0eWxlLnNldEF0dHJpYnV0ZSgndHlwZScsICd0ZXh0L2NzcycpO1xyXG5cdFx0c3R5bGUuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoY3NzKSk7XHJcblx0XHRyb290Tm9kZS5hcHBlbmRDaGlsZChzdHlsZSk7XHJcblx0fVxyXG59XHJcblxyXG52YXIgcGxhdGZvcm1fZG9tJDIgPSB7XHJcblx0LyoqXHJcblx0ICogV2hlbiBgdHJ1ZWAsIHByZXZlbnRzIHRoZSBhdXRvbWF0aWMgaW5qZWN0aW9uIG9mIHRoZSBzdHlsZXNoZWV0IHJlcXVpcmVkIHRvXHJcblx0ICogY29ycmVjdGx5IGRldGVjdCB3aGVuIHRoZSBjaGFydCBpcyBhZGRlZCB0byB0aGUgRE9NIGFuZCB0aGVuIHJlc2l6ZWQuIFRoaXNcclxuXHQgKiBzd2l0Y2ggaGFzIGJlZW4gYWRkZWQgdG8gYWxsb3cgZXh0ZXJuYWwgc3R5bGVzaGVldCAoYGRpc3QvQ2hhcnQoLm1pbik/LmpzYClcclxuXHQgKiB0byBiZSBtYW51YWxseSBpbXBvcnRlZCB0byBtYWtlIHRoaXMgbGlicmFyeSBjb21wYXRpYmxlIHdpdGggYW55IENTUC5cclxuXHQgKiBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2NoYXJ0anMvQ2hhcnQuanMvaXNzdWVzLzUyMDhcclxuXHQgKi9cclxuXHRkaXNhYmxlQ1NTSW5qZWN0aW9uOiBmYWxzZSxcclxuXHJcblx0LyoqXHJcblx0ICogVGhpcyBwcm9wZXJ0eSBob2xkcyB3aGV0aGVyIHRoaXMgcGxhdGZvcm0gaXMgZW5hYmxlZCBmb3IgdGhlIGN1cnJlbnQgZW52aXJvbm1lbnQuXHJcblx0ICogQ3VycmVudGx5IHVzZWQgYnkgcGxhdGZvcm0uanMgdG8gc2VsZWN0IHRoZSBwcm9wZXIgaW1wbGVtZW50YXRpb24uXHJcblx0ICogQHByaXZhdGVcclxuXHQgKi9cclxuXHRfZW5hYmxlZDogdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIGRvY3VtZW50ICE9PSAndW5kZWZpbmVkJyxcclxuXHJcblx0LyoqXHJcblx0ICogSW5pdGlhbGl6ZXMgcmVzb3VyY2VzIHRoYXQgZGVwZW5kIG9uIHBsYXRmb3JtIG9wdGlvbnMuXHJcblx0ICogQHBhcmFtIHtIVE1MQ2FudmFzRWxlbWVudH0gY2FudmFzIC0gVGhlIENhbnZhcyBlbGVtZW50LlxyXG5cdCAqIEBwcml2YXRlXHJcblx0ICovXHJcblx0X2Vuc3VyZUxvYWRlZDogZnVuY3Rpb24oY2FudmFzKSB7XHJcblx0XHRpZiAoIXRoaXMuZGlzYWJsZUNTU0luamVjdGlvbikge1xyXG5cdFx0XHQvLyBJZiB0aGUgY2FudmFzIGlzIGluIGEgc2hhZG93IERPTSwgdGhlbiB0aGUgc3R5bGVzIG11c3QgYWxzbyBiZSBpbnNlcnRlZFxyXG5cdFx0XHQvLyBpbnRvIHRoZSBzYW1lIHNoYWRvdyBET00uXHJcblx0XHRcdC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9jaGFydGpzL0NoYXJ0LmpzL2lzc3Vlcy81NzYzXHJcblx0XHRcdHZhciByb290ID0gY2FudmFzLmdldFJvb3ROb2RlID8gY2FudmFzLmdldFJvb3ROb2RlKCkgOiBkb2N1bWVudDtcclxuXHRcdFx0dmFyIHRhcmdldE5vZGUgPSByb290Lmhvc3QgPyByb290IDogZG9jdW1lbnQuaGVhZDtcclxuXHRcdFx0aW5qZWN0Q1NTKHRhcmdldE5vZGUsIHN0eWxlc2hlZXQpO1xyXG5cdFx0fVxyXG5cdH0sXHJcblxyXG5cdGFjcXVpcmVDb250ZXh0OiBmdW5jdGlvbihpdGVtLCBjb25maWcpIHtcclxuXHRcdGlmICh0eXBlb2YgaXRlbSA9PT0gJ3N0cmluZycpIHtcclxuXHRcdFx0aXRlbSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGl0ZW0pO1xyXG5cdFx0fSBlbHNlIGlmIChpdGVtLmxlbmd0aCkge1xyXG5cdFx0XHQvLyBTdXBwb3J0IGZvciBhcnJheSBiYXNlZCBxdWVyaWVzIChzdWNoIGFzIGpRdWVyeSlcclxuXHRcdFx0aXRlbSA9IGl0ZW1bMF07XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKGl0ZW0gJiYgaXRlbS5jYW52YXMpIHtcclxuXHRcdFx0Ly8gU3VwcG9ydCBmb3IgYW55IG9iamVjdCBhc3NvY2lhdGVkIHRvIGEgY2FudmFzIChpbmNsdWRpbmcgYSBjb250ZXh0MmQpXHJcblx0XHRcdGl0ZW0gPSBpdGVtLmNhbnZhcztcclxuXHRcdH1cclxuXHJcblx0XHQvLyBUbyBwcmV2ZW50IGNhbnZhcyBmaW5nZXJwcmludGluZywgc29tZSBhZGQtb25zIHVuZGVmaW5lIHRoZSBnZXRDb250ZXh0XHJcblx0XHQvLyBtZXRob2QsIGZvciBleGFtcGxlOiBodHRwczovL2dpdGh1Yi5jb20va2thcHNuZXIvQ2FudmFzQmxvY2tlclxyXG5cdFx0Ly8gaHR0cHM6Ly9naXRodWIuY29tL2NoYXJ0anMvQ2hhcnQuanMvaXNzdWVzLzI4MDdcclxuXHRcdHZhciBjb250ZXh0ID0gaXRlbSAmJiBpdGVtLmdldENvbnRleHQgJiYgaXRlbS5nZXRDb250ZXh0KCcyZCcpO1xyXG5cclxuXHRcdC8vIGBpbnN0YW5jZW9mIEhUTUxDYW52YXNFbGVtZW50L0NhbnZhc1JlbmRlcmluZ0NvbnRleHQyRGAgZmFpbHMgd2hlbiB0aGUgaXRlbSBpc1xyXG5cdFx0Ly8gaW5zaWRlIGFuIGlmcmFtZSBvciB3aGVuIHJ1bm5pbmcgaW4gYSBwcm90ZWN0ZWQgZW52aXJvbm1lbnQuIFdlIGNvdWxkIGd1ZXNzIHRoZVxyXG5cdFx0Ly8gdHlwZXMgZnJvbSB0aGVpciB0b1N0cmluZygpIHZhbHVlIGJ1dCBsZXQncyBrZWVwIHRoaW5ncyBmbGV4aWJsZSBhbmQgYXNzdW1lIGl0J3NcclxuXHRcdC8vIGEgc3VmZmljaWVudCBjb25kaXRpb24gaWYgdGhlIGl0ZW0gaGFzIGEgY29udGV4dDJEIHdoaWNoIGhhcyBpdGVtIGFzIGBjYW52YXNgLlxyXG5cdFx0Ly8gaHR0cHM6Ly9naXRodWIuY29tL2NoYXJ0anMvQ2hhcnQuanMvaXNzdWVzLzM4ODdcclxuXHRcdC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9jaGFydGpzL0NoYXJ0LmpzL2lzc3Vlcy80MTAyXHJcblx0XHQvLyBodHRwczovL2dpdGh1Yi5jb20vY2hhcnRqcy9DaGFydC5qcy9pc3N1ZXMvNDE1MlxyXG5cdFx0aWYgKGNvbnRleHQgJiYgY29udGV4dC5jYW52YXMgPT09IGl0ZW0pIHtcclxuXHRcdFx0Ly8gTG9hZCBwbGF0Zm9ybSByZXNvdXJjZXMgb24gZmlyc3QgY2hhcnQgY3JlYXRpb24sIHRvIG1ha2UgaXQgcG9zc2libGUgdG9cclxuXHRcdFx0Ly8gaW1wb3J0IHRoZSBsaWJyYXJ5IGJlZm9yZSBzZXR0aW5nIHBsYXRmb3JtIG9wdGlvbnMuXHJcblx0XHRcdHRoaXMuX2Vuc3VyZUxvYWRlZChpdGVtKTtcclxuXHRcdFx0aW5pdENhbnZhcyhpdGVtLCBjb25maWcpO1xyXG5cdFx0XHRyZXR1cm4gY29udGV4dDtcclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gbnVsbDtcclxuXHR9LFxyXG5cclxuXHRyZWxlYXNlQ29udGV4dDogZnVuY3Rpb24oY29udGV4dCkge1xyXG5cdFx0dmFyIGNhbnZhcyA9IGNvbnRleHQuY2FudmFzO1xyXG5cdFx0aWYgKCFjYW52YXNbRVhQQU5ET19LRVldKSB7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHJcblx0XHR2YXIgaW5pdGlhbCA9IGNhbnZhc1tFWFBBTkRPX0tFWV0uaW5pdGlhbDtcclxuXHRcdFsnaGVpZ2h0JywgJ3dpZHRoJ10uZm9yRWFjaChmdW5jdGlvbihwcm9wKSB7XHJcblx0XHRcdHZhciB2YWx1ZSA9IGluaXRpYWxbcHJvcF07XHJcblx0XHRcdGlmIChoZWxwZXJzJDEuaXNOdWxsT3JVbmRlZih2YWx1ZSkpIHtcclxuXHRcdFx0XHRjYW52YXMucmVtb3ZlQXR0cmlidXRlKHByb3ApO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdGNhbnZhcy5zZXRBdHRyaWJ1dGUocHJvcCwgdmFsdWUpO1xyXG5cdFx0XHR9XHJcblx0XHR9KTtcclxuXHJcblx0XHRoZWxwZXJzJDEuZWFjaChpbml0aWFsLnN0eWxlIHx8IHt9LCBmdW5jdGlvbih2YWx1ZSwga2V5KSB7XHJcblx0XHRcdGNhbnZhcy5zdHlsZVtrZXldID0gdmFsdWU7XHJcblx0XHR9KTtcclxuXHJcblx0XHQvLyBUaGUgY2FudmFzIHJlbmRlciBzaXplIG1pZ2h0IGhhdmUgYmVlbiBjaGFuZ2VkIChhbmQgdGh1cyB0aGUgc3RhdGUgc3RhY2sgZGlzY2FyZGVkKSxcclxuXHRcdC8vIHdlIGNhbid0IHVzZSBzYXZlKCkgYW5kIHJlc3RvcmUoKSB0byByZXN0b3JlIHRoZSBpbml0aWFsIHN0YXRlLiBTbyBtYWtlIHN1cmUgdGhhdCBhdFxyXG5cdFx0Ly8gbGVhc3QgdGhlIGNhbnZhcyBjb250ZXh0IGlzIHJlc2V0IHRvIHRoZSBkZWZhdWx0IHN0YXRlIGJ5IHNldHRpbmcgdGhlIGNhbnZhcyB3aWR0aC5cclxuXHRcdC8vIGh0dHBzOi8vd3d3LnczLm9yZy9UUi8yMDExL1dELWh0bWw1LTIwMTEwNTI1L3RoZS1jYW52YXMtZWxlbWVudC5odG1sXHJcblx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tc2VsZi1hc3NpZ25cclxuXHRcdGNhbnZhcy53aWR0aCA9IGNhbnZhcy53aWR0aDtcclxuXHJcblx0XHRkZWxldGUgY2FudmFzW0VYUEFORE9fS0VZXTtcclxuXHR9LFxyXG5cclxuXHRhZGRFdmVudExpc3RlbmVyOiBmdW5jdGlvbihjaGFydCwgdHlwZSwgbGlzdGVuZXIpIHtcclxuXHRcdHZhciBjYW52YXMgPSBjaGFydC5jYW52YXM7XHJcblx0XHRpZiAodHlwZSA9PT0gJ3Jlc2l6ZScpIHtcclxuXHRcdFx0Ly8gTm90ZTogdGhlIHJlc2l6ZSBldmVudCBpcyBub3Qgc3VwcG9ydGVkIG9uIGFsbCBicm93c2Vycy5cclxuXHRcdFx0YWRkUmVzaXplTGlzdGVuZXIoY2FudmFzLCBsaXN0ZW5lciwgY2hhcnQpO1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblxyXG5cdFx0dmFyIGV4cGFuZG8gPSBsaXN0ZW5lcltFWFBBTkRPX0tFWV0gfHwgKGxpc3RlbmVyW0VYUEFORE9fS0VZXSA9IHt9KTtcclxuXHRcdHZhciBwcm94aWVzID0gZXhwYW5kby5wcm94aWVzIHx8IChleHBhbmRvLnByb3hpZXMgPSB7fSk7XHJcblx0XHR2YXIgcHJveHkgPSBwcm94aWVzW2NoYXJ0LmlkICsgJ18nICsgdHlwZV0gPSBmdW5jdGlvbihldmVudCkge1xyXG5cdFx0XHRsaXN0ZW5lcihmcm9tTmF0aXZlRXZlbnQoZXZlbnQsIGNoYXJ0KSk7XHJcblx0XHR9O1xyXG5cclxuXHRcdGFkZExpc3RlbmVyKGNhbnZhcywgdHlwZSwgcHJveHkpO1xyXG5cdH0sXHJcblxyXG5cdHJlbW92ZUV2ZW50TGlzdGVuZXI6IGZ1bmN0aW9uKGNoYXJ0LCB0eXBlLCBsaXN0ZW5lcikge1xyXG5cdFx0dmFyIGNhbnZhcyA9IGNoYXJ0LmNhbnZhcztcclxuXHRcdGlmICh0eXBlID09PSAncmVzaXplJykge1xyXG5cdFx0XHQvLyBOb3RlOiB0aGUgcmVzaXplIGV2ZW50IGlzIG5vdCBzdXBwb3J0ZWQgb24gYWxsIGJyb3dzZXJzLlxyXG5cdFx0XHRyZW1vdmVSZXNpemVMaXN0ZW5lcihjYW52YXMpO1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblxyXG5cdFx0dmFyIGV4cGFuZG8gPSBsaXN0ZW5lcltFWFBBTkRPX0tFWV0gfHwge307XHJcblx0XHR2YXIgcHJveGllcyA9IGV4cGFuZG8ucHJveGllcyB8fCB7fTtcclxuXHRcdHZhciBwcm94eSA9IHByb3hpZXNbY2hhcnQuaWQgKyAnXycgKyB0eXBlXTtcclxuXHRcdGlmICghcHJveHkpIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJlbW92ZUxpc3RlbmVyKGNhbnZhcywgdHlwZSwgcHJveHkpO1xyXG5cdH1cclxufTtcclxuXHJcbi8vIERFUFJFQ0FUSU9OU1xyXG5cclxuLyoqXHJcbiAqIFByb3ZpZGVkIGZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5LCB1c2UgRXZlbnRUYXJnZXQuYWRkRXZlbnRMaXN0ZW5lciBpbnN0ZWFkLlxyXG4gKiBFdmVudFRhcmdldC5hZGRFdmVudExpc3RlbmVyIGNvbXBhdGliaWxpdHk6IENocm9tZSwgT3BlcmEgNywgU2FmYXJpLCBGRjEuNSssIElFOStcclxuICogQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvRXZlbnRUYXJnZXQvYWRkRXZlbnRMaXN0ZW5lclxyXG4gKiBAZnVuY3Rpb24gQ2hhcnQuaGVscGVycy5hZGRFdmVudFxyXG4gKiBAZGVwcmVjYXRlZCBzaW5jZSB2ZXJzaW9uIDIuNy4wXHJcbiAqIEB0b2RvIHJlbW92ZSBhdCB2ZXJzaW9uIDNcclxuICogQHByaXZhdGVcclxuICovXHJcbmhlbHBlcnMkMS5hZGRFdmVudCA9IGFkZExpc3RlbmVyO1xyXG5cclxuLyoqXHJcbiAqIFByb3ZpZGVkIGZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5LCB1c2UgRXZlbnRUYXJnZXQucmVtb3ZlRXZlbnRMaXN0ZW5lciBpbnN0ZWFkLlxyXG4gKiBFdmVudFRhcmdldC5yZW1vdmVFdmVudExpc3RlbmVyIGNvbXBhdGliaWxpdHk6IENocm9tZSwgT3BlcmEgNywgU2FmYXJpLCBGRjEuNSssIElFOStcclxuICogQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvRXZlbnRUYXJnZXQvcmVtb3ZlRXZlbnRMaXN0ZW5lclxyXG4gKiBAZnVuY3Rpb24gQ2hhcnQuaGVscGVycy5yZW1vdmVFdmVudFxyXG4gKiBAZGVwcmVjYXRlZCBzaW5jZSB2ZXJzaW9uIDIuNy4wXHJcbiAqIEB0b2RvIHJlbW92ZSBhdCB2ZXJzaW9uIDNcclxuICogQHByaXZhdGVcclxuICovXHJcbmhlbHBlcnMkMS5yZW1vdmVFdmVudCA9IHJlbW92ZUxpc3RlbmVyO1xuXG4vLyBAVE9ETyBNYWtlIHBvc3NpYmxlIHRvIHNlbGVjdCBhbm90aGVyIHBsYXRmb3JtIGF0IGJ1aWxkIHRpbWUuXHJcbnZhciBpbXBsZW1lbnRhdGlvbiA9IHBsYXRmb3JtX2RvbSQyLl9lbmFibGVkID8gcGxhdGZvcm1fZG9tJDIgOiBwbGF0Zm9ybV9iYXNpYztcclxuXHJcbi8qKlxyXG4gKiBAbmFtZXNwYWNlIENoYXJ0LnBsYXRmb3JtXHJcbiAqIEBzZWUgaHR0cHM6Ly9jaGFydGpzLmdpdGJvb2tzLmlvL3Byb3Bvc2Fscy9jb250ZW50L1BsYXRmb3JtLmh0bWxcclxuICogQHNpbmNlIDIuNC4wXHJcbiAqL1xyXG52YXIgcGxhdGZvcm0gPSBoZWxwZXJzJDEuZXh0ZW5kKHtcclxuXHQvKipcclxuXHQgKiBAc2luY2UgMi43LjBcclxuXHQgKi9cclxuXHRpbml0aWFsaXplOiBmdW5jdGlvbigpIHt9LFxyXG5cclxuXHQvKipcclxuXHQgKiBDYWxsZWQgYXQgY2hhcnQgY29uc3RydWN0aW9uIHRpbWUsIHJldHVybnMgYSBjb250ZXh0MmQgaW5zdGFuY2UgaW1wbGVtZW50aW5nXHJcblx0ICogdGhlIFtXM0MgQ2FudmFzIDJEIENvbnRleHQgQVBJIHN0YW5kYXJkXXtAbGluayBodHRwczovL3d3dy53My5vcmcvVFIvMmRjb250ZXh0L30uXHJcblx0ICogQHBhcmFtIHsqfSBpdGVtIC0gVGhlIG5hdGl2ZSBpdGVtIGZyb20gd2hpY2ggdG8gYWNxdWlyZSBjb250ZXh0IChwbGF0Zm9ybSBzcGVjaWZpYylcclxuXHQgKiBAcGFyYW0ge29iamVjdH0gb3B0aW9ucyAtIFRoZSBjaGFydCBvcHRpb25zXHJcblx0ICogQHJldHVybnMge0NhbnZhc1JlbmRlcmluZ0NvbnRleHQyRH0gY29udGV4dDJkIGluc3RhbmNlXHJcblx0ICovXHJcblx0YWNxdWlyZUNvbnRleHQ6IGZ1bmN0aW9uKCkge30sXHJcblxyXG5cdC8qKlxyXG5cdCAqIENhbGxlZCBhdCBjaGFydCBkZXN0cnVjdGlvbiB0aW1lLCByZWxlYXNlcyBhbnkgcmVzb3VyY2VzIGFzc29jaWF0ZWQgdG8gdGhlIGNvbnRleHRcclxuXHQgKiBwcmV2aW91c2x5IHJldHVybmVkIGJ5IHRoZSBhY3F1aXJlQ29udGV4dCgpIG1ldGhvZC5cclxuXHQgKiBAcGFyYW0ge0NhbnZhc1JlbmRlcmluZ0NvbnRleHQyRH0gY29udGV4dCAtIFRoZSBjb250ZXh0MmQgaW5zdGFuY2VcclxuXHQgKiBAcmV0dXJucyB7Ym9vbGVhbn0gdHJ1ZSBpZiB0aGUgbWV0aG9kIHN1Y2NlZWRlZCwgZWxzZSBmYWxzZVxyXG5cdCAqL1xyXG5cdHJlbGVhc2VDb250ZXh0OiBmdW5jdGlvbigpIHt9LFxyXG5cclxuXHQvKipcclxuXHQgKiBSZWdpc3RlcnMgdGhlIHNwZWNpZmllZCBsaXN0ZW5lciBvbiB0aGUgZ2l2ZW4gY2hhcnQuXHJcblx0ICogQHBhcmFtIHtDaGFydH0gY2hhcnQgLSBDaGFydCBmcm9tIHdoaWNoIHRvIGxpc3RlbiBmb3IgZXZlbnRcclxuXHQgKiBAcGFyYW0ge3N0cmluZ30gdHlwZSAtIFRoZSAoe0BsaW5rIElFdmVudH0pIHR5cGUgdG8gbGlzdGVuIGZvclxyXG5cdCAqIEBwYXJhbSB7ZnVuY3Rpb259IGxpc3RlbmVyIC0gUmVjZWl2ZXMgYSBub3RpZmljYXRpb24gKGFuIG9iamVjdCB0aGF0IGltcGxlbWVudHNcclxuXHQgKiB0aGUge0BsaW5rIElFdmVudH0gaW50ZXJmYWNlKSB3aGVuIGFuIGV2ZW50IG9mIHRoZSBzcGVjaWZpZWQgdHlwZSBvY2N1cnMuXHJcblx0ICovXHJcblx0YWRkRXZlbnRMaXN0ZW5lcjogZnVuY3Rpb24oKSB7fSxcclxuXHJcblx0LyoqXHJcblx0ICogUmVtb3ZlcyB0aGUgc3BlY2lmaWVkIGxpc3RlbmVyIHByZXZpb3VzbHkgcmVnaXN0ZXJlZCB3aXRoIGFkZEV2ZW50TGlzdGVuZXIuXHJcblx0ICogQHBhcmFtIHtDaGFydH0gY2hhcnQgLSBDaGFydCBmcm9tIHdoaWNoIHRvIHJlbW92ZSB0aGUgbGlzdGVuZXJcclxuXHQgKiBAcGFyYW0ge3N0cmluZ30gdHlwZSAtIFRoZSAoe0BsaW5rIElFdmVudH0pIHR5cGUgdG8gcmVtb3ZlXHJcblx0ICogQHBhcmFtIHtmdW5jdGlvbn0gbGlzdGVuZXIgLSBUaGUgbGlzdGVuZXIgZnVuY3Rpb24gdG8gcmVtb3ZlIGZyb20gdGhlIGV2ZW50IHRhcmdldC5cclxuXHQgKi9cclxuXHRyZW1vdmVFdmVudExpc3RlbmVyOiBmdW5jdGlvbigpIHt9XHJcblxyXG59LCBpbXBsZW1lbnRhdGlvbik7XG5cbmNvcmVfZGVmYXVsdHMuX3NldCgnZ2xvYmFsJywge1xyXG5cdHBsdWdpbnM6IHt9XHJcbn0pO1xyXG5cclxuLyoqXHJcbiAqIFRoZSBwbHVnaW4gc2VydmljZSBzaW5nbGV0b25cclxuICogQG5hbWVzcGFjZSBDaGFydC5wbHVnaW5zXHJcbiAqIEBzaW5jZSAyLjEuMFxyXG4gKi9cclxudmFyIGNvcmVfcGx1Z2lucyA9IHtcclxuXHQvKipcclxuXHQgKiBHbG9iYWxseSByZWdpc3RlcmVkIHBsdWdpbnMuXHJcblx0ICogQHByaXZhdGVcclxuXHQgKi9cclxuXHRfcGx1Z2luczogW10sXHJcblxyXG5cdC8qKlxyXG5cdCAqIFRoaXMgaWRlbnRpZmllciBpcyB1c2VkIHRvIGludmFsaWRhdGUgdGhlIGRlc2NyaXB0b3JzIGNhY2hlIGF0dGFjaGVkIHRvIGVhY2ggY2hhcnRcclxuXHQgKiB3aGVuIGEgZ2xvYmFsIHBsdWdpbiBpcyByZWdpc3RlcmVkIG9yIHVucmVnaXN0ZXJlZC4gSW4gdGhpcyBjYXNlLCB0aGUgY2FjaGUgSUQgaXNcclxuXHQgKiBpbmNyZW1lbnRlZCBhbmQgZGVzY3JpcHRvcnMgYXJlIHJlZ2VuZXJhdGVkIGR1cmluZyBmb2xsb3dpbmcgQVBJIGNhbGxzLlxyXG5cdCAqIEBwcml2YXRlXHJcblx0ICovXHJcblx0X2NhY2hlSWQ6IDAsXHJcblxyXG5cdC8qKlxyXG5cdCAqIFJlZ2lzdGVycyB0aGUgZ2l2ZW4gcGx1Z2luKHMpIGlmIG5vdCBhbHJlYWR5IHJlZ2lzdGVyZWQuXHJcblx0ICogQHBhcmFtIHtJUGx1Z2luW118SVBsdWdpbn0gcGx1Z2lucyBwbHVnaW4gaW5zdGFuY2UocykuXHJcblx0ICovXHJcblx0cmVnaXN0ZXI6IGZ1bmN0aW9uKHBsdWdpbnMpIHtcclxuXHRcdHZhciBwID0gdGhpcy5fcGx1Z2lucztcclxuXHRcdChbXSkuY29uY2F0KHBsdWdpbnMpLmZvckVhY2goZnVuY3Rpb24ocGx1Z2luKSB7XHJcblx0XHRcdGlmIChwLmluZGV4T2YocGx1Z2luKSA9PT0gLTEpIHtcclxuXHRcdFx0XHRwLnB1c2gocGx1Z2luKTtcclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblxyXG5cdFx0dGhpcy5fY2FjaGVJZCsrO1xyXG5cdH0sXHJcblxyXG5cdC8qKlxyXG5cdCAqIFVucmVnaXN0ZXJzIHRoZSBnaXZlbiBwbHVnaW4ocykgb25seSBpZiByZWdpc3RlcmVkLlxyXG5cdCAqIEBwYXJhbSB7SVBsdWdpbltdfElQbHVnaW59IHBsdWdpbnMgcGx1Z2luIGluc3RhbmNlKHMpLlxyXG5cdCAqL1xyXG5cdHVucmVnaXN0ZXI6IGZ1bmN0aW9uKHBsdWdpbnMpIHtcclxuXHRcdHZhciBwID0gdGhpcy5fcGx1Z2lucztcclxuXHRcdChbXSkuY29uY2F0KHBsdWdpbnMpLmZvckVhY2goZnVuY3Rpb24ocGx1Z2luKSB7XHJcblx0XHRcdHZhciBpZHggPSBwLmluZGV4T2YocGx1Z2luKTtcclxuXHRcdFx0aWYgKGlkeCAhPT0gLTEpIHtcclxuXHRcdFx0XHRwLnNwbGljZShpZHgsIDEpO1xyXG5cdFx0XHR9XHJcblx0XHR9KTtcclxuXHJcblx0XHR0aGlzLl9jYWNoZUlkKys7XHJcblx0fSxcclxuXHJcblx0LyoqXHJcblx0ICogUmVtb3ZlIGFsbCByZWdpc3RlcmVkIHBsdWdpbnMuXHJcblx0ICogQHNpbmNlIDIuMS41XHJcblx0ICovXHJcblx0Y2xlYXI6IGZ1bmN0aW9uKCkge1xyXG5cdFx0dGhpcy5fcGx1Z2lucyA9IFtdO1xyXG5cdFx0dGhpcy5fY2FjaGVJZCsrO1xyXG5cdH0sXHJcblxyXG5cdC8qKlxyXG5cdCAqIFJldHVybnMgdGhlIG51bWJlciBvZiByZWdpc3RlcmVkIHBsdWdpbnM/XHJcblx0ICogQHJldHVybnMge251bWJlcn1cclxuXHQgKiBAc2luY2UgMi4xLjVcclxuXHQgKi9cclxuXHRjb3VudDogZnVuY3Rpb24oKSB7XHJcblx0XHRyZXR1cm4gdGhpcy5fcGx1Z2lucy5sZW5ndGg7XHJcblx0fSxcclxuXHJcblx0LyoqXHJcblx0ICogUmV0dXJucyBhbGwgcmVnaXN0ZXJlZCBwbHVnaW4gaW5zdGFuY2VzLlxyXG5cdCAqIEByZXR1cm5zIHtJUGx1Z2luW119IGFycmF5IG9mIHBsdWdpbiBvYmplY3RzLlxyXG5cdCAqIEBzaW5jZSAyLjEuNVxyXG5cdCAqL1xyXG5cdGdldEFsbDogZnVuY3Rpb24oKSB7XHJcblx0XHRyZXR1cm4gdGhpcy5fcGx1Z2lucztcclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBDYWxscyBlbmFibGVkIHBsdWdpbnMgZm9yIGBjaGFydGAgb24gdGhlIHNwZWNpZmllZCBob29rIGFuZCB3aXRoIHRoZSBnaXZlbiBhcmdzLlxyXG5cdCAqIFRoaXMgbWV0aG9kIGltbWVkaWF0ZWx5IHJldHVybnMgYXMgc29vbiBhcyBhIHBsdWdpbiBleHBsaWNpdGx5IHJldHVybnMgZmFsc2UuIFRoZVxyXG5cdCAqIHJldHVybmVkIHZhbHVlIGNhbiBiZSB1c2VkLCBmb3IgaW5zdGFuY2UsIHRvIGludGVycnVwdCB0aGUgY3VycmVudCBhY3Rpb24uXHJcblx0ICogQHBhcmFtIHtDaGFydH0gY2hhcnQgLSBUaGUgY2hhcnQgaW5zdGFuY2UgZm9yIHdoaWNoIHBsdWdpbnMgc2hvdWxkIGJlIGNhbGxlZC5cclxuXHQgKiBAcGFyYW0ge3N0cmluZ30gaG9vayAtIFRoZSBuYW1lIG9mIHRoZSBwbHVnaW4gbWV0aG9kIHRvIGNhbGwgKGUuZy4gJ2JlZm9yZVVwZGF0ZScpLlxyXG5cdCAqIEBwYXJhbSB7QXJyYXl9IFthcmdzXSAtIEV4dHJhIGFyZ3VtZW50cyB0byBhcHBseSB0byB0aGUgaG9vayBjYWxsLlxyXG5cdCAqIEByZXR1cm5zIHtib29sZWFufSBmYWxzZSBpZiBhbnkgb2YgdGhlIHBsdWdpbnMgcmV0dXJuIGZhbHNlLCBlbHNlIHJldHVybnMgdHJ1ZS5cclxuXHQgKi9cclxuXHRub3RpZnk6IGZ1bmN0aW9uKGNoYXJ0LCBob29rLCBhcmdzKSB7XHJcblx0XHR2YXIgZGVzY3JpcHRvcnMgPSB0aGlzLmRlc2NyaXB0b3JzKGNoYXJ0KTtcclxuXHRcdHZhciBpbGVuID0gZGVzY3JpcHRvcnMubGVuZ3RoO1xyXG5cdFx0dmFyIGksIGRlc2NyaXB0b3IsIHBsdWdpbiwgcGFyYW1zLCBtZXRob2Q7XHJcblxyXG5cdFx0Zm9yIChpID0gMDsgaSA8IGlsZW47ICsraSkge1xyXG5cdFx0XHRkZXNjcmlwdG9yID0gZGVzY3JpcHRvcnNbaV07XHJcblx0XHRcdHBsdWdpbiA9IGRlc2NyaXB0b3IucGx1Z2luO1xyXG5cdFx0XHRtZXRob2QgPSBwbHVnaW5baG9va107XHJcblx0XHRcdGlmICh0eXBlb2YgbWV0aG9kID09PSAnZnVuY3Rpb24nKSB7XHJcblx0XHRcdFx0cGFyYW1zID0gW2NoYXJ0XS5jb25jYXQoYXJncyB8fCBbXSk7XHJcblx0XHRcdFx0cGFyYW1zLnB1c2goZGVzY3JpcHRvci5vcHRpb25zKTtcclxuXHRcdFx0XHRpZiAobWV0aG9kLmFwcGx5KHBsdWdpbiwgcGFyYW1zKSA9PT0gZmFsc2UpIHtcclxuXHRcdFx0XHRcdHJldHVybiBmYWxzZTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gdHJ1ZTtcclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBSZXR1cm5zIGRlc2NyaXB0b3JzIG9mIGVuYWJsZWQgcGx1Z2lucyBmb3IgdGhlIGdpdmVuIGNoYXJ0LlxyXG5cdCAqIEByZXR1cm5zIHtvYmplY3RbXX0gW3sgcGx1Z2luLCBvcHRpb25zIH1dXHJcblx0ICogQHByaXZhdGVcclxuXHQgKi9cclxuXHRkZXNjcmlwdG9yczogZnVuY3Rpb24oY2hhcnQpIHtcclxuXHRcdHZhciBjYWNoZSA9IGNoYXJ0LiRwbHVnaW5zIHx8IChjaGFydC4kcGx1Z2lucyA9IHt9KTtcclxuXHRcdGlmIChjYWNoZS5pZCA9PT0gdGhpcy5fY2FjaGVJZCkge1xyXG5cdFx0XHRyZXR1cm4gY2FjaGUuZGVzY3JpcHRvcnM7XHJcblx0XHR9XHJcblxyXG5cdFx0dmFyIHBsdWdpbnMgPSBbXTtcclxuXHRcdHZhciBkZXNjcmlwdG9ycyA9IFtdO1xyXG5cdFx0dmFyIGNvbmZpZyA9IChjaGFydCAmJiBjaGFydC5jb25maWcpIHx8IHt9O1xyXG5cdFx0dmFyIG9wdGlvbnMgPSAoY29uZmlnLm9wdGlvbnMgJiYgY29uZmlnLm9wdGlvbnMucGx1Z2lucykgfHwge307XHJcblxyXG5cdFx0dGhpcy5fcGx1Z2lucy5jb25jYXQoY29uZmlnLnBsdWdpbnMgfHwgW10pLmZvckVhY2goZnVuY3Rpb24ocGx1Z2luKSB7XHJcblx0XHRcdHZhciBpZHggPSBwbHVnaW5zLmluZGV4T2YocGx1Z2luKTtcclxuXHRcdFx0aWYgKGlkeCAhPT0gLTEpIHtcclxuXHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdHZhciBpZCA9IHBsdWdpbi5pZDtcclxuXHRcdFx0dmFyIG9wdHMgPSBvcHRpb25zW2lkXTtcclxuXHRcdFx0aWYgKG9wdHMgPT09IGZhbHNlKSB7XHJcblx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRpZiAob3B0cyA9PT0gdHJ1ZSkge1xyXG5cdFx0XHRcdG9wdHMgPSBoZWxwZXJzJDEuY2xvbmUoY29yZV9kZWZhdWx0cy5nbG9iYWwucGx1Z2luc1tpZF0pO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRwbHVnaW5zLnB1c2gocGx1Z2luKTtcclxuXHRcdFx0ZGVzY3JpcHRvcnMucHVzaCh7XHJcblx0XHRcdFx0cGx1Z2luOiBwbHVnaW4sXHJcblx0XHRcdFx0b3B0aW9uczogb3B0cyB8fCB7fVxyXG5cdFx0XHR9KTtcclxuXHRcdH0pO1xyXG5cclxuXHRcdGNhY2hlLmRlc2NyaXB0b3JzID0gZGVzY3JpcHRvcnM7XHJcblx0XHRjYWNoZS5pZCA9IHRoaXMuX2NhY2hlSWQ7XHJcblx0XHRyZXR1cm4gZGVzY3JpcHRvcnM7XHJcblx0fSxcclxuXHJcblx0LyoqXHJcblx0ICogSW52YWxpZGF0ZXMgY2FjaGUgZm9yIHRoZSBnaXZlbiBjaGFydDogZGVzY3JpcHRvcnMgaG9sZCBhIHJlZmVyZW5jZSBvbiBwbHVnaW4gb3B0aW9uLFxyXG5cdCAqIGJ1dCBpbiBzb21lIGNhc2VzLCB0aGlzIHJlZmVyZW5jZSBjYW4gYmUgY2hhbmdlZCBieSB0aGUgdXNlciB3aGVuIHVwZGF0aW5nIG9wdGlvbnMuXHJcblx0ICogaHR0cHM6Ly9naXRodWIuY29tL2NoYXJ0anMvQ2hhcnQuanMvaXNzdWVzLzUxMTEjaXNzdWVjb21tZW50LTM1NTkzNDE2N1xyXG5cdCAqIEBwcml2YXRlXHJcblx0ICovXHJcblx0X2ludmFsaWRhdGU6IGZ1bmN0aW9uKGNoYXJ0KSB7XHJcblx0XHRkZWxldGUgY2hhcnQuJHBsdWdpbnM7XHJcblx0fVxyXG59O1xuXG52YXIgY29yZV9zY2FsZVNlcnZpY2UgPSB7XHJcblx0Ly8gU2NhbGUgcmVnaXN0cmF0aW9uIG9iamVjdC4gRXh0ZW5zaW9ucyBjYW4gcmVnaXN0ZXIgbmV3IHNjYWxlIHR5cGVzIChzdWNoIGFzIGxvZyBvciBEQiBzY2FsZXMpIGFuZCB0aGVuXHJcblx0Ly8gdXNlIHRoZSBuZXcgY2hhcnQgb3B0aW9ucyB0byBncmFiIHRoZSBjb3JyZWN0IHNjYWxlXHJcblx0Y29uc3RydWN0b3JzOiB7fSxcclxuXHQvLyBVc2UgYSByZWdpc3RyYXRpb24gZnVuY3Rpb24gc28gdGhhdCB3ZSBjYW4gbW92ZSB0byBhbiBFUzYgbWFwIHdoZW4gd2Ugbm8gbG9uZ2VyIG5lZWQgdG8gc3VwcG9ydFxyXG5cdC8vIG9sZCBicm93c2Vyc1xyXG5cclxuXHQvLyBTY2FsZSBjb25maWcgZGVmYXVsdHNcclxuXHRkZWZhdWx0czoge30sXHJcblx0cmVnaXN0ZXJTY2FsZVR5cGU6IGZ1bmN0aW9uKHR5cGUsIHNjYWxlQ29uc3RydWN0b3IsIHNjYWxlRGVmYXVsdHMpIHtcclxuXHRcdHRoaXMuY29uc3RydWN0b3JzW3R5cGVdID0gc2NhbGVDb25zdHJ1Y3RvcjtcclxuXHRcdHRoaXMuZGVmYXVsdHNbdHlwZV0gPSBoZWxwZXJzJDEuY2xvbmUoc2NhbGVEZWZhdWx0cyk7XHJcblx0fSxcclxuXHRnZXRTY2FsZUNvbnN0cnVjdG9yOiBmdW5jdGlvbih0eXBlKSB7XHJcblx0XHRyZXR1cm4gdGhpcy5jb25zdHJ1Y3RvcnMuaGFzT3duUHJvcGVydHkodHlwZSkgPyB0aGlzLmNvbnN0cnVjdG9yc1t0eXBlXSA6IHVuZGVmaW5lZDtcclxuXHR9LFxyXG5cdGdldFNjYWxlRGVmYXVsdHM6IGZ1bmN0aW9uKHR5cGUpIHtcclxuXHRcdC8vIFJldHVybiB0aGUgc2NhbGUgZGVmYXVsdHMgbWVyZ2VkIHdpdGggdGhlIGdsb2JhbCBzZXR0aW5ncyBzbyB0aGF0IHdlIGFsd2F5cyB1c2UgdGhlIGxhdGVzdCBvbmVzXHJcblx0XHRyZXR1cm4gdGhpcy5kZWZhdWx0cy5oYXNPd25Qcm9wZXJ0eSh0eXBlKSA/IGhlbHBlcnMkMS5tZXJnZShPYmplY3QuY3JlYXRlKG51bGwpLCBbY29yZV9kZWZhdWx0cy5zY2FsZSwgdGhpcy5kZWZhdWx0c1t0eXBlXV0pIDoge307XHJcblx0fSxcclxuXHR1cGRhdGVTY2FsZURlZmF1bHRzOiBmdW5jdGlvbih0eXBlLCBhZGRpdGlvbnMpIHtcclxuXHRcdHZhciBtZSA9IHRoaXM7XHJcblx0XHRpZiAobWUuZGVmYXVsdHMuaGFzT3duUHJvcGVydHkodHlwZSkpIHtcclxuXHRcdFx0bWUuZGVmYXVsdHNbdHlwZV0gPSBoZWxwZXJzJDEuZXh0ZW5kKG1lLmRlZmF1bHRzW3R5cGVdLCBhZGRpdGlvbnMpO1xyXG5cdFx0fVxyXG5cdH0sXHJcblx0YWRkU2NhbGVzVG9MYXlvdXQ6IGZ1bmN0aW9uKGNoYXJ0KSB7XHJcblx0XHQvLyBBZGRzIGVhY2ggc2NhbGUgdG8gdGhlIGNoYXJ0LmJveGVzIGFycmF5IHRvIGJlIHNpemVkIGFjY29yZGluZ2x5XHJcblx0XHRoZWxwZXJzJDEuZWFjaChjaGFydC5zY2FsZXMsIGZ1bmN0aW9uKHNjYWxlKSB7XHJcblx0XHRcdC8vIFNldCBJTGF5b3V0SXRlbSBwYXJhbWV0ZXJzIGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eVxyXG5cdFx0XHRzY2FsZS5mdWxsV2lkdGggPSBzY2FsZS5vcHRpb25zLmZ1bGxXaWR0aDtcclxuXHRcdFx0c2NhbGUucG9zaXRpb24gPSBzY2FsZS5vcHRpb25zLnBvc2l0aW9uO1xyXG5cdFx0XHRzY2FsZS53ZWlnaHQgPSBzY2FsZS5vcHRpb25zLndlaWdodDtcclxuXHRcdFx0Y29yZV9sYXlvdXRzLmFkZEJveChjaGFydCwgc2NhbGUpO1xyXG5cdFx0fSk7XHJcblx0fVxyXG59O1xuXG52YXIgdmFsdWVPckRlZmF1bHQkOCA9IGhlbHBlcnMkMS52YWx1ZU9yRGVmYXVsdDtcclxudmFyIGdldFJ0bEhlbHBlciA9IGhlbHBlcnMkMS5ydGwuZ2V0UnRsQWRhcHRlcjtcclxuXHJcbmNvcmVfZGVmYXVsdHMuX3NldCgnZ2xvYmFsJywge1xyXG5cdHRvb2x0aXBzOiB7XHJcblx0XHRlbmFibGVkOiB0cnVlLFxyXG5cdFx0Y3VzdG9tOiBudWxsLFxyXG5cdFx0bW9kZTogJ25lYXJlc3QnLFxyXG5cdFx0cG9zaXRpb246ICdhdmVyYWdlJyxcclxuXHRcdGludGVyc2VjdDogdHJ1ZSxcclxuXHRcdGJhY2tncm91bmRDb2xvcjogJ3JnYmEoMCwwLDAsMC44KScsXHJcblx0XHR0aXRsZUZvbnRTdHlsZTogJ2JvbGQnLFxyXG5cdFx0dGl0bGVTcGFjaW5nOiAyLFxyXG5cdFx0dGl0bGVNYXJnaW5Cb3R0b206IDYsXHJcblx0XHR0aXRsZUZvbnRDb2xvcjogJyNmZmYnLFxyXG5cdFx0dGl0bGVBbGlnbjogJ2xlZnQnLFxyXG5cdFx0Ym9keVNwYWNpbmc6IDIsXHJcblx0XHRib2R5Rm9udENvbG9yOiAnI2ZmZicsXHJcblx0XHRib2R5QWxpZ246ICdsZWZ0JyxcclxuXHRcdGZvb3RlckZvbnRTdHlsZTogJ2JvbGQnLFxyXG5cdFx0Zm9vdGVyU3BhY2luZzogMixcclxuXHRcdGZvb3Rlck1hcmdpblRvcDogNixcclxuXHRcdGZvb3RlckZvbnRDb2xvcjogJyNmZmYnLFxyXG5cdFx0Zm9vdGVyQWxpZ246ICdsZWZ0JyxcclxuXHRcdHlQYWRkaW5nOiA2LFxyXG5cdFx0eFBhZGRpbmc6IDYsXHJcblx0XHRjYXJldFBhZGRpbmc6IDIsXHJcblx0XHRjYXJldFNpemU6IDUsXHJcblx0XHRjb3JuZXJSYWRpdXM6IDYsXHJcblx0XHRtdWx0aUtleUJhY2tncm91bmQ6ICcjZmZmJyxcclxuXHRcdGRpc3BsYXlDb2xvcnM6IHRydWUsXHJcblx0XHRib3JkZXJDb2xvcjogJ3JnYmEoMCwwLDAsMCknLFxyXG5cdFx0Ym9yZGVyV2lkdGg6IDAsXHJcblx0XHRjYWxsYmFja3M6IHtcclxuXHRcdFx0Ly8gQXJncyBhcmU6ICh0b29sdGlwSXRlbXMsIGRhdGEpXHJcblx0XHRcdGJlZm9yZVRpdGxlOiBoZWxwZXJzJDEubm9vcCxcclxuXHRcdFx0dGl0bGU6IGZ1bmN0aW9uKHRvb2x0aXBJdGVtcywgZGF0YSkge1xyXG5cdFx0XHRcdHZhciB0aXRsZSA9ICcnO1xyXG5cdFx0XHRcdHZhciBsYWJlbHMgPSBkYXRhLmxhYmVscztcclxuXHRcdFx0XHR2YXIgbGFiZWxDb3VudCA9IGxhYmVscyA/IGxhYmVscy5sZW5ndGggOiAwO1xyXG5cclxuXHRcdFx0XHRpZiAodG9vbHRpcEl0ZW1zLmxlbmd0aCA+IDApIHtcclxuXHRcdFx0XHRcdHZhciBpdGVtID0gdG9vbHRpcEl0ZW1zWzBdO1xyXG5cdFx0XHRcdFx0aWYgKGl0ZW0ubGFiZWwpIHtcclxuXHRcdFx0XHRcdFx0dGl0bGUgPSBpdGVtLmxhYmVsO1xyXG5cdFx0XHRcdFx0fSBlbHNlIGlmIChpdGVtLnhMYWJlbCkge1xyXG5cdFx0XHRcdFx0XHR0aXRsZSA9IGl0ZW0ueExhYmVsO1xyXG5cdFx0XHRcdFx0fSBlbHNlIGlmIChsYWJlbENvdW50ID4gMCAmJiBpdGVtLmluZGV4IDwgbGFiZWxDb3VudCkge1xyXG5cdFx0XHRcdFx0XHR0aXRsZSA9IGxhYmVsc1tpdGVtLmluZGV4XTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdHJldHVybiB0aXRsZTtcclxuXHRcdFx0fSxcclxuXHRcdFx0YWZ0ZXJUaXRsZTogaGVscGVycyQxLm5vb3AsXHJcblxyXG5cdFx0XHQvLyBBcmdzIGFyZTogKHRvb2x0aXBJdGVtcywgZGF0YSlcclxuXHRcdFx0YmVmb3JlQm9keTogaGVscGVycyQxLm5vb3AsXHJcblxyXG5cdFx0XHQvLyBBcmdzIGFyZTogKHRvb2x0aXBJdGVtLCBkYXRhKVxyXG5cdFx0XHRiZWZvcmVMYWJlbDogaGVscGVycyQxLm5vb3AsXHJcblx0XHRcdGxhYmVsOiBmdW5jdGlvbih0b29sdGlwSXRlbSwgZGF0YSkge1xyXG5cdFx0XHRcdHZhciBsYWJlbCA9IGRhdGEuZGF0YXNldHNbdG9vbHRpcEl0ZW0uZGF0YXNldEluZGV4XS5sYWJlbCB8fCAnJztcclxuXHJcblx0XHRcdFx0aWYgKGxhYmVsKSB7XHJcblx0XHRcdFx0XHRsYWJlbCArPSAnOiAnO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRpZiAoIWhlbHBlcnMkMS5pc051bGxPclVuZGVmKHRvb2x0aXBJdGVtLnZhbHVlKSkge1xyXG5cdFx0XHRcdFx0bGFiZWwgKz0gdG9vbHRpcEl0ZW0udmFsdWU7XHJcblx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdGxhYmVsICs9IHRvb2x0aXBJdGVtLnlMYWJlbDtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0cmV0dXJuIGxhYmVsO1xyXG5cdFx0XHR9LFxyXG5cdFx0XHRsYWJlbENvbG9yOiBmdW5jdGlvbih0b29sdGlwSXRlbSwgY2hhcnQpIHtcclxuXHRcdFx0XHR2YXIgbWV0YSA9IGNoYXJ0LmdldERhdGFzZXRNZXRhKHRvb2x0aXBJdGVtLmRhdGFzZXRJbmRleCk7XHJcblx0XHRcdFx0dmFyIGFjdGl2ZUVsZW1lbnQgPSBtZXRhLmRhdGFbdG9vbHRpcEl0ZW0uaW5kZXhdO1xyXG5cdFx0XHRcdHZhciB2aWV3ID0gYWN0aXZlRWxlbWVudC5fdmlldztcclxuXHRcdFx0XHRyZXR1cm4ge1xyXG5cdFx0XHRcdFx0Ym9yZGVyQ29sb3I6IHZpZXcuYm9yZGVyQ29sb3IsXHJcblx0XHRcdFx0XHRiYWNrZ3JvdW5kQ29sb3I6IHZpZXcuYmFja2dyb3VuZENvbG9yXHJcblx0XHRcdFx0fTtcclxuXHRcdFx0fSxcclxuXHRcdFx0bGFiZWxUZXh0Q29sb3I6IGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdHJldHVybiB0aGlzLl9vcHRpb25zLmJvZHlGb250Q29sb3I7XHJcblx0XHRcdH0sXHJcblx0XHRcdGFmdGVyTGFiZWw6IGhlbHBlcnMkMS5ub29wLFxyXG5cclxuXHRcdFx0Ly8gQXJncyBhcmU6ICh0b29sdGlwSXRlbXMsIGRhdGEpXHJcblx0XHRcdGFmdGVyQm9keTogaGVscGVycyQxLm5vb3AsXHJcblxyXG5cdFx0XHQvLyBBcmdzIGFyZTogKHRvb2x0aXBJdGVtcywgZGF0YSlcclxuXHRcdFx0YmVmb3JlRm9vdGVyOiBoZWxwZXJzJDEubm9vcCxcclxuXHRcdFx0Zm9vdGVyOiBoZWxwZXJzJDEubm9vcCxcclxuXHRcdFx0YWZ0ZXJGb290ZXI6IGhlbHBlcnMkMS5ub29wXHJcblx0XHR9XHJcblx0fVxyXG59KTtcclxuXHJcbnZhciBwb3NpdGlvbmVycyA9IHtcclxuXHQvKipcclxuXHQgKiBBdmVyYWdlIG1vZGUgcGxhY2VzIHRoZSB0b29sdGlwIGF0IHRoZSBhdmVyYWdlIHBvc2l0aW9uIG9mIHRoZSBlbGVtZW50cyBzaG93blxyXG5cdCAqIEBmdW5jdGlvbiBDaGFydC5Ub29sdGlwLnBvc2l0aW9uZXJzLmF2ZXJhZ2VcclxuXHQgKiBAcGFyYW0gZWxlbWVudHMge0NoYXJ0RWxlbWVudFtdfSB0aGUgZWxlbWVudHMgYmVpbmcgZGlzcGxheWVkIGluIHRoZSB0b29sdGlwXHJcblx0ICogQHJldHVybnMge29iamVjdH0gdG9vbHRpcCBwb3NpdGlvblxyXG5cdCAqL1xyXG5cdGF2ZXJhZ2U6IGZ1bmN0aW9uKGVsZW1lbnRzKSB7XHJcblx0XHRpZiAoIWVsZW1lbnRzLmxlbmd0aCkge1xyXG5cdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHR9XHJcblxyXG5cdFx0dmFyIGksIGxlbjtcclxuXHRcdHZhciB4ID0gMDtcclxuXHRcdHZhciB5ID0gMDtcclxuXHRcdHZhciBjb3VudCA9IDA7XHJcblxyXG5cdFx0Zm9yIChpID0gMCwgbGVuID0gZWxlbWVudHMubGVuZ3RoOyBpIDwgbGVuOyArK2kpIHtcclxuXHRcdFx0dmFyIGVsID0gZWxlbWVudHNbaV07XHJcblx0XHRcdGlmIChlbCAmJiBlbC5oYXNWYWx1ZSgpKSB7XHJcblx0XHRcdFx0dmFyIHBvcyA9IGVsLnRvb2x0aXBQb3NpdGlvbigpO1xyXG5cdFx0XHRcdHggKz0gcG9zLng7XHJcblx0XHRcdFx0eSArPSBwb3MueTtcclxuXHRcdFx0XHQrK2NvdW50O1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIHtcclxuXHRcdFx0eDogeCAvIGNvdW50LFxyXG5cdFx0XHR5OiB5IC8gY291bnRcclxuXHRcdH07XHJcblx0fSxcclxuXHJcblx0LyoqXHJcblx0ICogR2V0cyB0aGUgdG9vbHRpcCBwb3NpdGlvbiBuZWFyZXN0IG9mIHRoZSBpdGVtIG5lYXJlc3QgdG8gdGhlIGV2ZW50IHBvc2l0aW9uXHJcblx0ICogQGZ1bmN0aW9uIENoYXJ0LlRvb2x0aXAucG9zaXRpb25lcnMubmVhcmVzdFxyXG5cdCAqIEBwYXJhbSBlbGVtZW50cyB7Q2hhcnQuRWxlbWVudFtdfSB0aGUgdG9vbHRpcCBlbGVtZW50c1xyXG5cdCAqIEBwYXJhbSBldmVudFBvc2l0aW9uIHtvYmplY3R9IHRoZSBwb3NpdGlvbiBvZiB0aGUgZXZlbnQgaW4gY2FudmFzIGNvb3JkaW5hdGVzXHJcblx0ICogQHJldHVybnMge29iamVjdH0gdGhlIHRvb2x0aXAgcG9zaXRpb25cclxuXHQgKi9cclxuXHRuZWFyZXN0OiBmdW5jdGlvbihlbGVtZW50cywgZXZlbnRQb3NpdGlvbikge1xyXG5cdFx0dmFyIHggPSBldmVudFBvc2l0aW9uLng7XHJcblx0XHR2YXIgeSA9IGV2ZW50UG9zaXRpb24ueTtcclxuXHRcdHZhciBtaW5EaXN0YW5jZSA9IE51bWJlci5QT1NJVElWRV9JTkZJTklUWTtcclxuXHRcdHZhciBpLCBsZW4sIG5lYXJlc3RFbGVtZW50O1xyXG5cclxuXHRcdGZvciAoaSA9IDAsIGxlbiA9IGVsZW1lbnRzLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XHJcblx0XHRcdHZhciBlbCA9IGVsZW1lbnRzW2ldO1xyXG5cdFx0XHRpZiAoZWwgJiYgZWwuaGFzVmFsdWUoKSkge1xyXG5cdFx0XHRcdHZhciBjZW50ZXIgPSBlbC5nZXRDZW50ZXJQb2ludCgpO1xyXG5cdFx0XHRcdHZhciBkID0gaGVscGVycyQxLmRpc3RhbmNlQmV0d2VlblBvaW50cyhldmVudFBvc2l0aW9uLCBjZW50ZXIpO1xyXG5cclxuXHRcdFx0XHRpZiAoZCA8IG1pbkRpc3RhbmNlKSB7XHJcblx0XHRcdFx0XHRtaW5EaXN0YW5jZSA9IGQ7XHJcblx0XHRcdFx0XHRuZWFyZXN0RWxlbWVudCA9IGVsO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdGlmIChuZWFyZXN0RWxlbWVudCkge1xyXG5cdFx0XHR2YXIgdHAgPSBuZWFyZXN0RWxlbWVudC50b29sdGlwUG9zaXRpb24oKTtcclxuXHRcdFx0eCA9IHRwLng7XHJcblx0XHRcdHkgPSB0cC55O1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiB7XHJcblx0XHRcdHg6IHgsXHJcblx0XHRcdHk6IHlcclxuXHRcdH07XHJcblx0fVxyXG59O1xyXG5cclxuLy8gSGVscGVyIHRvIHB1c2ggb3IgY29uY2F0IGJhc2VkIG9uIGlmIHRoZSAybmQgcGFyYW1ldGVyIGlzIGFuIGFycmF5IG9yIG5vdFxyXG5mdW5jdGlvbiBwdXNoT3JDb25jYXQoYmFzZSwgdG9QdXNoKSB7XHJcblx0aWYgKHRvUHVzaCkge1xyXG5cdFx0aWYgKGhlbHBlcnMkMS5pc0FycmF5KHRvUHVzaCkpIHtcclxuXHRcdFx0Ly8gYmFzZSA9IGJhc2UuY29uY2F0KHRvUHVzaCk7XHJcblx0XHRcdEFycmF5LnByb3RvdHlwZS5wdXNoLmFwcGx5KGJhc2UsIHRvUHVzaCk7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRiYXNlLnB1c2godG9QdXNoKTtcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdHJldHVybiBiYXNlO1xyXG59XHJcblxyXG4vKipcclxuICogUmV0dXJucyBhcnJheSBvZiBzdHJpbmdzIHNwbGl0IGJ5IG5ld2xpbmVcclxuICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlIC0gVGhlIHZhbHVlIHRvIHNwbGl0IGJ5IG5ld2xpbmUuXHJcbiAqIEByZXR1cm5zIHtzdHJpbmdbXX0gdmFsdWUgaWYgbmV3bGluZSBwcmVzZW50IC0gUmV0dXJuZWQgZnJvbSBTdHJpbmcgc3BsaXQoKSBtZXRob2RcclxuICogQGZ1bmN0aW9uXHJcbiAqL1xyXG5mdW5jdGlvbiBzcGxpdE5ld2xpbmVzKHN0cikge1xyXG5cdGlmICgodHlwZW9mIHN0ciA9PT0gJ3N0cmluZycgfHwgc3RyIGluc3RhbmNlb2YgU3RyaW5nKSAmJiBzdHIuaW5kZXhPZignXFxuJykgPiAtMSkge1xyXG5cdFx0cmV0dXJuIHN0ci5zcGxpdCgnXFxuJyk7XHJcblx0fVxyXG5cdHJldHVybiBzdHI7XHJcbn1cclxuXHJcblxyXG4vKipcclxuICogUHJpdmF0ZSBoZWxwZXIgdG8gY3JlYXRlIGEgdG9vbHRpcCBpdGVtIG1vZGVsXHJcbiAqIEBwYXJhbSBlbGVtZW50IC0gdGhlIGNoYXJ0IGVsZW1lbnQgKHBvaW50LCBhcmMsIGJhcikgdG8gY3JlYXRlIHRoZSB0b29sdGlwIGl0ZW0gZm9yXHJcbiAqIEByZXR1cm4gbmV3IHRvb2x0aXAgaXRlbVxyXG4gKi9cclxuZnVuY3Rpb24gY3JlYXRlVG9vbHRpcEl0ZW0oZWxlbWVudCkge1xyXG5cdHZhciB4U2NhbGUgPSBlbGVtZW50Ll94U2NhbGU7XHJcblx0dmFyIHlTY2FsZSA9IGVsZW1lbnQuX3lTY2FsZSB8fCBlbGVtZW50Ll9zY2FsZTsgLy8gaGFuZGxlIHJhZGFyIHx8IHBvbGFyQXJlYSBjaGFydHNcclxuXHR2YXIgaW5kZXggPSBlbGVtZW50Ll9pbmRleDtcclxuXHR2YXIgZGF0YXNldEluZGV4ID0gZWxlbWVudC5fZGF0YXNldEluZGV4O1xyXG5cdHZhciBjb250cm9sbGVyID0gZWxlbWVudC5fY2hhcnQuZ2V0RGF0YXNldE1ldGEoZGF0YXNldEluZGV4KS5jb250cm9sbGVyO1xyXG5cdHZhciBpbmRleFNjYWxlID0gY29udHJvbGxlci5fZ2V0SW5kZXhTY2FsZSgpO1xyXG5cdHZhciB2YWx1ZVNjYWxlID0gY29udHJvbGxlci5fZ2V0VmFsdWVTY2FsZSgpO1xyXG5cclxuXHRyZXR1cm4ge1xyXG5cdFx0eExhYmVsOiB4U2NhbGUgPyB4U2NhbGUuZ2V0TGFiZWxGb3JJbmRleChpbmRleCwgZGF0YXNldEluZGV4KSA6ICcnLFxyXG5cdFx0eUxhYmVsOiB5U2NhbGUgPyB5U2NhbGUuZ2V0TGFiZWxGb3JJbmRleChpbmRleCwgZGF0YXNldEluZGV4KSA6ICcnLFxyXG5cdFx0bGFiZWw6IGluZGV4U2NhbGUgPyAnJyArIGluZGV4U2NhbGUuZ2V0TGFiZWxGb3JJbmRleChpbmRleCwgZGF0YXNldEluZGV4KSA6ICcnLFxyXG5cdFx0dmFsdWU6IHZhbHVlU2NhbGUgPyAnJyArIHZhbHVlU2NhbGUuZ2V0TGFiZWxGb3JJbmRleChpbmRleCwgZGF0YXNldEluZGV4KSA6ICcnLFxyXG5cdFx0aW5kZXg6IGluZGV4LFxyXG5cdFx0ZGF0YXNldEluZGV4OiBkYXRhc2V0SW5kZXgsXHJcblx0XHR4OiBlbGVtZW50Ll9tb2RlbC54LFxyXG5cdFx0eTogZWxlbWVudC5fbW9kZWwueVxyXG5cdH07XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBIZWxwZXIgdG8gZ2V0IHRoZSByZXNldCBtb2RlbCBmb3IgdGhlIHRvb2x0aXBcclxuICogQHBhcmFtIHRvb2x0aXBPcHRzIHtvYmplY3R9IHRoZSB0b29sdGlwIG9wdGlvbnNcclxuICovXHJcbmZ1bmN0aW9uIGdldEJhc2VNb2RlbCh0b29sdGlwT3B0cykge1xyXG5cdHZhciBnbG9iYWxEZWZhdWx0cyA9IGNvcmVfZGVmYXVsdHMuZ2xvYmFsO1xyXG5cclxuXHRyZXR1cm4ge1xyXG5cdFx0Ly8gUG9zaXRpb25pbmdcclxuXHRcdHhQYWRkaW5nOiB0b29sdGlwT3B0cy54UGFkZGluZyxcclxuXHRcdHlQYWRkaW5nOiB0b29sdGlwT3B0cy55UGFkZGluZyxcclxuXHRcdHhBbGlnbjogdG9vbHRpcE9wdHMueEFsaWduLFxyXG5cdFx0eUFsaWduOiB0b29sdGlwT3B0cy55QWxpZ24sXHJcblxyXG5cdFx0Ly8gRHJhd2luZyBkaXJlY3Rpb24gYW5kIHRleHQgZGlyZWN0aW9uXHJcblx0XHRydGw6IHRvb2x0aXBPcHRzLnJ0bCxcclxuXHRcdHRleHREaXJlY3Rpb246IHRvb2x0aXBPcHRzLnRleHREaXJlY3Rpb24sXHJcblxyXG5cdFx0Ly8gQm9keVxyXG5cdFx0Ym9keUZvbnRDb2xvcjogdG9vbHRpcE9wdHMuYm9keUZvbnRDb2xvcixcclxuXHRcdF9ib2R5Rm9udEZhbWlseTogdmFsdWVPckRlZmF1bHQkOCh0b29sdGlwT3B0cy5ib2R5Rm9udEZhbWlseSwgZ2xvYmFsRGVmYXVsdHMuZGVmYXVsdEZvbnRGYW1pbHkpLFxyXG5cdFx0X2JvZHlGb250U3R5bGU6IHZhbHVlT3JEZWZhdWx0JDgodG9vbHRpcE9wdHMuYm9keUZvbnRTdHlsZSwgZ2xvYmFsRGVmYXVsdHMuZGVmYXVsdEZvbnRTdHlsZSksXHJcblx0XHRfYm9keUFsaWduOiB0b29sdGlwT3B0cy5ib2R5QWxpZ24sXHJcblx0XHRib2R5Rm9udFNpemU6IHZhbHVlT3JEZWZhdWx0JDgodG9vbHRpcE9wdHMuYm9keUZvbnRTaXplLCBnbG9iYWxEZWZhdWx0cy5kZWZhdWx0Rm9udFNpemUpLFxyXG5cdFx0Ym9keVNwYWNpbmc6IHRvb2x0aXBPcHRzLmJvZHlTcGFjaW5nLFxyXG5cclxuXHRcdC8vIFRpdGxlXHJcblx0XHR0aXRsZUZvbnRDb2xvcjogdG9vbHRpcE9wdHMudGl0bGVGb250Q29sb3IsXHJcblx0XHRfdGl0bGVGb250RmFtaWx5OiB2YWx1ZU9yRGVmYXVsdCQ4KHRvb2x0aXBPcHRzLnRpdGxlRm9udEZhbWlseSwgZ2xvYmFsRGVmYXVsdHMuZGVmYXVsdEZvbnRGYW1pbHkpLFxyXG5cdFx0X3RpdGxlRm9udFN0eWxlOiB2YWx1ZU9yRGVmYXVsdCQ4KHRvb2x0aXBPcHRzLnRpdGxlRm9udFN0eWxlLCBnbG9iYWxEZWZhdWx0cy5kZWZhdWx0Rm9udFN0eWxlKSxcclxuXHRcdHRpdGxlRm9udFNpemU6IHZhbHVlT3JEZWZhdWx0JDgodG9vbHRpcE9wdHMudGl0bGVGb250U2l6ZSwgZ2xvYmFsRGVmYXVsdHMuZGVmYXVsdEZvbnRTaXplKSxcclxuXHRcdF90aXRsZUFsaWduOiB0b29sdGlwT3B0cy50aXRsZUFsaWduLFxyXG5cdFx0dGl0bGVTcGFjaW5nOiB0b29sdGlwT3B0cy50aXRsZVNwYWNpbmcsXHJcblx0XHR0aXRsZU1hcmdpbkJvdHRvbTogdG9vbHRpcE9wdHMudGl0bGVNYXJnaW5Cb3R0b20sXHJcblxyXG5cdFx0Ly8gRm9vdGVyXHJcblx0XHRmb290ZXJGb250Q29sb3I6IHRvb2x0aXBPcHRzLmZvb3RlckZvbnRDb2xvcixcclxuXHRcdF9mb290ZXJGb250RmFtaWx5OiB2YWx1ZU9yRGVmYXVsdCQ4KHRvb2x0aXBPcHRzLmZvb3RlckZvbnRGYW1pbHksIGdsb2JhbERlZmF1bHRzLmRlZmF1bHRGb250RmFtaWx5KSxcclxuXHRcdF9mb290ZXJGb250U3R5bGU6IHZhbHVlT3JEZWZhdWx0JDgodG9vbHRpcE9wdHMuZm9vdGVyRm9udFN0eWxlLCBnbG9iYWxEZWZhdWx0cy5kZWZhdWx0Rm9udFN0eWxlKSxcclxuXHRcdGZvb3RlckZvbnRTaXplOiB2YWx1ZU9yRGVmYXVsdCQ4KHRvb2x0aXBPcHRzLmZvb3RlckZvbnRTaXplLCBnbG9iYWxEZWZhdWx0cy5kZWZhdWx0Rm9udFNpemUpLFxyXG5cdFx0X2Zvb3RlckFsaWduOiB0b29sdGlwT3B0cy5mb290ZXJBbGlnbixcclxuXHRcdGZvb3RlclNwYWNpbmc6IHRvb2x0aXBPcHRzLmZvb3RlclNwYWNpbmcsXHJcblx0XHRmb290ZXJNYXJnaW5Ub3A6IHRvb2x0aXBPcHRzLmZvb3Rlck1hcmdpblRvcCxcclxuXHJcblx0XHQvLyBBcHBlYXJhbmNlXHJcblx0XHRjYXJldFNpemU6IHRvb2x0aXBPcHRzLmNhcmV0U2l6ZSxcclxuXHRcdGNvcm5lclJhZGl1czogdG9vbHRpcE9wdHMuY29ybmVyUmFkaXVzLFxyXG5cdFx0YmFja2dyb3VuZENvbG9yOiB0b29sdGlwT3B0cy5iYWNrZ3JvdW5kQ29sb3IsXHJcblx0XHRvcGFjaXR5OiAwLFxyXG5cdFx0bGVnZW5kQ29sb3JCYWNrZ3JvdW5kOiB0b29sdGlwT3B0cy5tdWx0aUtleUJhY2tncm91bmQsXHJcblx0XHRkaXNwbGF5Q29sb3JzOiB0b29sdGlwT3B0cy5kaXNwbGF5Q29sb3JzLFxyXG5cdFx0Ym9yZGVyQ29sb3I6IHRvb2x0aXBPcHRzLmJvcmRlckNvbG9yLFxyXG5cdFx0Ym9yZGVyV2lkdGg6IHRvb2x0aXBPcHRzLmJvcmRlcldpZHRoXHJcblx0fTtcclxufVxyXG5cclxuLyoqXHJcbiAqIEdldCB0aGUgc2l6ZSBvZiB0aGUgdG9vbHRpcFxyXG4gKi9cclxuZnVuY3Rpb24gZ2V0VG9vbHRpcFNpemUodG9vbHRpcCwgbW9kZWwpIHtcclxuXHR2YXIgY3R4ID0gdG9vbHRpcC5fY2hhcnQuY3R4O1xyXG5cclxuXHR2YXIgaGVpZ2h0ID0gbW9kZWwueVBhZGRpbmcgKiAyOyAvLyBUb29sdGlwIFBhZGRpbmdcclxuXHR2YXIgd2lkdGggPSAwO1xyXG5cclxuXHQvLyBDb3VudCBvZiBhbGwgbGluZXMgaW4gdGhlIGJvZHlcclxuXHR2YXIgYm9keSA9IG1vZGVsLmJvZHk7XHJcblx0dmFyIGNvbWJpbmVkQm9keUxlbmd0aCA9IGJvZHkucmVkdWNlKGZ1bmN0aW9uKGNvdW50LCBib2R5SXRlbSkge1xyXG5cdFx0cmV0dXJuIGNvdW50ICsgYm9keUl0ZW0uYmVmb3JlLmxlbmd0aCArIGJvZHlJdGVtLmxpbmVzLmxlbmd0aCArIGJvZHlJdGVtLmFmdGVyLmxlbmd0aDtcclxuXHR9LCAwKTtcclxuXHRjb21iaW5lZEJvZHlMZW5ndGggKz0gbW9kZWwuYmVmb3JlQm9keS5sZW5ndGggKyBtb2RlbC5hZnRlckJvZHkubGVuZ3RoO1xyXG5cclxuXHR2YXIgdGl0bGVMaW5lQ291bnQgPSBtb2RlbC50aXRsZS5sZW5ndGg7XHJcblx0dmFyIGZvb3RlckxpbmVDb3VudCA9IG1vZGVsLmZvb3Rlci5sZW5ndGg7XHJcblx0dmFyIHRpdGxlRm9udFNpemUgPSBtb2RlbC50aXRsZUZvbnRTaXplO1xyXG5cdHZhciBib2R5Rm9udFNpemUgPSBtb2RlbC5ib2R5Rm9udFNpemU7XHJcblx0dmFyIGZvb3RlckZvbnRTaXplID0gbW9kZWwuZm9vdGVyRm9udFNpemU7XHJcblxyXG5cdGhlaWdodCArPSB0aXRsZUxpbmVDb3VudCAqIHRpdGxlRm9udFNpemU7IC8vIFRpdGxlIExpbmVzXHJcblx0aGVpZ2h0ICs9IHRpdGxlTGluZUNvdW50ID8gKHRpdGxlTGluZUNvdW50IC0gMSkgKiBtb2RlbC50aXRsZVNwYWNpbmcgOiAwOyAvLyBUaXRsZSBMaW5lIFNwYWNpbmdcclxuXHRoZWlnaHQgKz0gdGl0bGVMaW5lQ291bnQgPyBtb2RlbC50aXRsZU1hcmdpbkJvdHRvbSA6IDA7IC8vIFRpdGxlJ3MgYm90dG9tIE1hcmdpblxyXG5cdGhlaWdodCArPSBjb21iaW5lZEJvZHlMZW5ndGggKiBib2R5Rm9udFNpemU7IC8vIEJvZHkgTGluZXNcclxuXHRoZWlnaHQgKz0gY29tYmluZWRCb2R5TGVuZ3RoID8gKGNvbWJpbmVkQm9keUxlbmd0aCAtIDEpICogbW9kZWwuYm9keVNwYWNpbmcgOiAwOyAvLyBCb2R5IExpbmUgU3BhY2luZ1xyXG5cdGhlaWdodCArPSBmb290ZXJMaW5lQ291bnQgPyBtb2RlbC5mb290ZXJNYXJnaW5Ub3AgOiAwOyAvLyBGb290ZXIgTWFyZ2luXHJcblx0aGVpZ2h0ICs9IGZvb3RlckxpbmVDb3VudCAqIChmb290ZXJGb250U2l6ZSk7IC8vIEZvb3RlciBMaW5lc1xyXG5cdGhlaWdodCArPSBmb290ZXJMaW5lQ291bnQgPyAoZm9vdGVyTGluZUNvdW50IC0gMSkgKiBtb2RlbC5mb290ZXJTcGFjaW5nIDogMDsgLy8gRm9vdGVyIExpbmUgU3BhY2luZ1xyXG5cclxuXHQvLyBUaXRsZSB3aWR0aFxyXG5cdHZhciB3aWR0aFBhZGRpbmcgPSAwO1xyXG5cdHZhciBtYXhMaW5lV2lkdGggPSBmdW5jdGlvbihsaW5lKSB7XHJcblx0XHR3aWR0aCA9IE1hdGgubWF4KHdpZHRoLCBjdHgubWVhc3VyZVRleHQobGluZSkud2lkdGggKyB3aWR0aFBhZGRpbmcpO1xyXG5cdH07XHJcblxyXG5cdGN0eC5mb250ID0gaGVscGVycyQxLmZvbnRTdHJpbmcodGl0bGVGb250U2l6ZSwgbW9kZWwuX3RpdGxlRm9udFN0eWxlLCBtb2RlbC5fdGl0bGVGb250RmFtaWx5KTtcclxuXHRoZWxwZXJzJDEuZWFjaChtb2RlbC50aXRsZSwgbWF4TGluZVdpZHRoKTtcclxuXHJcblx0Ly8gQm9keSB3aWR0aFxyXG5cdGN0eC5mb250ID0gaGVscGVycyQxLmZvbnRTdHJpbmcoYm9keUZvbnRTaXplLCBtb2RlbC5fYm9keUZvbnRTdHlsZSwgbW9kZWwuX2JvZHlGb250RmFtaWx5KTtcclxuXHRoZWxwZXJzJDEuZWFjaChtb2RlbC5iZWZvcmVCb2R5LmNvbmNhdChtb2RlbC5hZnRlckJvZHkpLCBtYXhMaW5lV2lkdGgpO1xyXG5cclxuXHQvLyBCb2R5IGxpbmVzIG1heSBpbmNsdWRlIHNvbWUgZXh0cmEgd2lkdGggZHVlIHRvIHRoZSBjb2xvciBib3hcclxuXHR3aWR0aFBhZGRpbmcgPSBtb2RlbC5kaXNwbGF5Q29sb3JzID8gKGJvZHlGb250U2l6ZSArIDIpIDogMDtcclxuXHRoZWxwZXJzJDEuZWFjaChib2R5LCBmdW5jdGlvbihib2R5SXRlbSkge1xyXG5cdFx0aGVscGVycyQxLmVhY2goYm9keUl0ZW0uYmVmb3JlLCBtYXhMaW5lV2lkdGgpO1xyXG5cdFx0aGVscGVycyQxLmVhY2goYm9keUl0ZW0ubGluZXMsIG1heExpbmVXaWR0aCk7XHJcblx0XHRoZWxwZXJzJDEuZWFjaChib2R5SXRlbS5hZnRlciwgbWF4TGluZVdpZHRoKTtcclxuXHR9KTtcclxuXHJcblx0Ly8gUmVzZXQgYmFjayB0byAwXHJcblx0d2lkdGhQYWRkaW5nID0gMDtcclxuXHJcblx0Ly8gRm9vdGVyIHdpZHRoXHJcblx0Y3R4LmZvbnQgPSBoZWxwZXJzJDEuZm9udFN0cmluZyhmb290ZXJGb250U2l6ZSwgbW9kZWwuX2Zvb3RlckZvbnRTdHlsZSwgbW9kZWwuX2Zvb3RlckZvbnRGYW1pbHkpO1xyXG5cdGhlbHBlcnMkMS5lYWNoKG1vZGVsLmZvb3RlciwgbWF4TGluZVdpZHRoKTtcclxuXHJcblx0Ly8gQWRkIHBhZGRpbmdcclxuXHR3aWR0aCArPSAyICogbW9kZWwueFBhZGRpbmc7XHJcblxyXG5cdHJldHVybiB7XHJcblx0XHR3aWR0aDogd2lkdGgsXHJcblx0XHRoZWlnaHQ6IGhlaWdodFxyXG5cdH07XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBIZWxwZXIgdG8gZ2V0IHRoZSBhbGlnbm1lbnQgb2YgYSB0b29sdGlwIGdpdmVuIHRoZSBzaXplXHJcbiAqL1xyXG5mdW5jdGlvbiBkZXRlcm1pbmVBbGlnbm1lbnQodG9vbHRpcCwgc2l6ZSkge1xyXG5cdHZhciBtb2RlbCA9IHRvb2x0aXAuX21vZGVsO1xyXG5cdHZhciBjaGFydCA9IHRvb2x0aXAuX2NoYXJ0O1xyXG5cdHZhciBjaGFydEFyZWEgPSB0b29sdGlwLl9jaGFydC5jaGFydEFyZWE7XHJcblx0dmFyIHhBbGlnbiA9ICdjZW50ZXInO1xyXG5cdHZhciB5QWxpZ24gPSAnY2VudGVyJztcclxuXHJcblx0aWYgKG1vZGVsLnkgPCBzaXplLmhlaWdodCkge1xyXG5cdFx0eUFsaWduID0gJ3RvcCc7XHJcblx0fSBlbHNlIGlmIChtb2RlbC55ID4gKGNoYXJ0LmhlaWdodCAtIHNpemUuaGVpZ2h0KSkge1xyXG5cdFx0eUFsaWduID0gJ2JvdHRvbSc7XHJcblx0fVxyXG5cclxuXHR2YXIgbGYsIHJmOyAvLyBmdW5jdGlvbnMgdG8gZGV0ZXJtaW5lIGxlZnQsIHJpZ2h0IGFsaWdubWVudFxyXG5cdHZhciBvbGYsIG9yZjsgLy8gZnVuY3Rpb25zIHRvIGRldGVybWluZSBpZiBsZWZ0L3JpZ2h0IGFsaWdubWVudCBjYXVzZXMgdG9vbHRpcCB0byBnbyBvdXRzaWRlIGNoYXJ0XHJcblx0dmFyIHlmOyAvLyBmdW5jdGlvbiB0byBnZXQgdGhlIHkgYWxpZ25tZW50IGlmIHRoZSB0b29sdGlwIGdvZXMgb3V0c2lkZSBvZiB0aGUgbGVmdCBvciByaWdodCBlZGdlc1xyXG5cdHZhciBtaWRYID0gKGNoYXJ0QXJlYS5sZWZ0ICsgY2hhcnRBcmVhLnJpZ2h0KSAvIDI7XHJcblx0dmFyIG1pZFkgPSAoY2hhcnRBcmVhLnRvcCArIGNoYXJ0QXJlYS5ib3R0b20pIC8gMjtcclxuXHJcblx0aWYgKHlBbGlnbiA9PT0gJ2NlbnRlcicpIHtcclxuXHRcdGxmID0gZnVuY3Rpb24oeCkge1xyXG5cdFx0XHRyZXR1cm4geCA8PSBtaWRYO1xyXG5cdFx0fTtcclxuXHRcdHJmID0gZnVuY3Rpb24oeCkge1xyXG5cdFx0XHRyZXR1cm4geCA+IG1pZFg7XHJcblx0XHR9O1xyXG5cdH0gZWxzZSB7XHJcblx0XHRsZiA9IGZ1bmN0aW9uKHgpIHtcclxuXHRcdFx0cmV0dXJuIHggPD0gKHNpemUud2lkdGggLyAyKTtcclxuXHRcdH07XHJcblx0XHRyZiA9IGZ1bmN0aW9uKHgpIHtcclxuXHRcdFx0cmV0dXJuIHggPj0gKGNoYXJ0LndpZHRoIC0gKHNpemUud2lkdGggLyAyKSk7XHJcblx0XHR9O1xyXG5cdH1cclxuXHJcblx0b2xmID0gZnVuY3Rpb24oeCkge1xyXG5cdFx0cmV0dXJuIHggKyBzaXplLndpZHRoICsgbW9kZWwuY2FyZXRTaXplICsgbW9kZWwuY2FyZXRQYWRkaW5nID4gY2hhcnQud2lkdGg7XHJcblx0fTtcclxuXHRvcmYgPSBmdW5jdGlvbih4KSB7XHJcblx0XHRyZXR1cm4geCAtIHNpemUud2lkdGggLSBtb2RlbC5jYXJldFNpemUgLSBtb2RlbC5jYXJldFBhZGRpbmcgPCAwO1xyXG5cdH07XHJcblx0eWYgPSBmdW5jdGlvbih5KSB7XHJcblx0XHRyZXR1cm4geSA8PSBtaWRZID8gJ3RvcCcgOiAnYm90dG9tJztcclxuXHR9O1xyXG5cclxuXHRpZiAobGYobW9kZWwueCkpIHtcclxuXHRcdHhBbGlnbiA9ICdsZWZ0JztcclxuXHJcblx0XHQvLyBJcyB0b29sdGlwIHRvbyB3aWRlIGFuZCBnb2VzIG92ZXIgdGhlIHJpZ2h0IHNpZGUgb2YgdGhlIGNoYXJ0Lj9cclxuXHRcdGlmIChvbGYobW9kZWwueCkpIHtcclxuXHRcdFx0eEFsaWduID0gJ2NlbnRlcic7XHJcblx0XHRcdHlBbGlnbiA9IHlmKG1vZGVsLnkpO1xyXG5cdFx0fVxyXG5cdH0gZWxzZSBpZiAocmYobW9kZWwueCkpIHtcclxuXHRcdHhBbGlnbiA9ICdyaWdodCc7XHJcblxyXG5cdFx0Ly8gSXMgdG9vbHRpcCB0b28gd2lkZSBhbmQgZ29lcyBvdXRzaWRlIGxlZnQgZWRnZSBvZiBjYW52YXM/XHJcblx0XHRpZiAob3JmKG1vZGVsLngpKSB7XHJcblx0XHRcdHhBbGlnbiA9ICdjZW50ZXInO1xyXG5cdFx0XHR5QWxpZ24gPSB5Zihtb2RlbC55KTtcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdHZhciBvcHRzID0gdG9vbHRpcC5fb3B0aW9ucztcclxuXHRyZXR1cm4ge1xyXG5cdFx0eEFsaWduOiBvcHRzLnhBbGlnbiA/IG9wdHMueEFsaWduIDogeEFsaWduLFxyXG5cdFx0eUFsaWduOiBvcHRzLnlBbGlnbiA/IG9wdHMueUFsaWduIDogeUFsaWduXHJcblx0fTtcclxufVxyXG5cclxuLyoqXHJcbiAqIEhlbHBlciB0byBnZXQgdGhlIGxvY2F0aW9uIGEgdG9vbHRpcCBuZWVkcyB0byBiZSBwbGFjZWQgYXQgZ2l2ZW4gdGhlIGluaXRpYWwgcG9zaXRpb24gKHZpYSB0aGUgdm0pIGFuZCB0aGUgc2l6ZSBhbmQgYWxpZ25tZW50XHJcbiAqL1xyXG5mdW5jdGlvbiBnZXRCYWNrZ3JvdW5kUG9pbnQodm0sIHNpemUsIGFsaWdubWVudCwgY2hhcnQpIHtcclxuXHQvLyBCYWNrZ3JvdW5kIFBvc2l0aW9uXHJcblx0dmFyIHggPSB2bS54O1xyXG5cdHZhciB5ID0gdm0ueTtcclxuXHJcblx0dmFyIGNhcmV0U2l6ZSA9IHZtLmNhcmV0U2l6ZTtcclxuXHR2YXIgY2FyZXRQYWRkaW5nID0gdm0uY2FyZXRQYWRkaW5nO1xyXG5cdHZhciBjb3JuZXJSYWRpdXMgPSB2bS5jb3JuZXJSYWRpdXM7XHJcblx0dmFyIHhBbGlnbiA9IGFsaWdubWVudC54QWxpZ247XHJcblx0dmFyIHlBbGlnbiA9IGFsaWdubWVudC55QWxpZ247XHJcblx0dmFyIHBhZGRpbmdBbmRTaXplID0gY2FyZXRTaXplICsgY2FyZXRQYWRkaW5nO1xyXG5cdHZhciByYWRpdXNBbmRQYWRkaW5nID0gY29ybmVyUmFkaXVzICsgY2FyZXRQYWRkaW5nO1xyXG5cclxuXHRpZiAoeEFsaWduID09PSAncmlnaHQnKSB7XHJcblx0XHR4IC09IHNpemUud2lkdGg7XHJcblx0fSBlbHNlIGlmICh4QWxpZ24gPT09ICdjZW50ZXInKSB7XHJcblx0XHR4IC09IChzaXplLndpZHRoIC8gMik7XHJcblx0XHRpZiAoeCArIHNpemUud2lkdGggPiBjaGFydC53aWR0aCkge1xyXG5cdFx0XHR4ID0gY2hhcnQud2lkdGggLSBzaXplLndpZHRoO1xyXG5cdFx0fVxyXG5cdFx0aWYgKHggPCAwKSB7XHJcblx0XHRcdHggPSAwO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0aWYgKHlBbGlnbiA9PT0gJ3RvcCcpIHtcclxuXHRcdHkgKz0gcGFkZGluZ0FuZFNpemU7XHJcblx0fSBlbHNlIGlmICh5QWxpZ24gPT09ICdib3R0b20nKSB7XHJcblx0XHR5IC09IHNpemUuaGVpZ2h0ICsgcGFkZGluZ0FuZFNpemU7XHJcblx0fSBlbHNlIHtcclxuXHRcdHkgLT0gKHNpemUuaGVpZ2h0IC8gMik7XHJcblx0fVxyXG5cclxuXHRpZiAoeUFsaWduID09PSAnY2VudGVyJykge1xyXG5cdFx0aWYgKHhBbGlnbiA9PT0gJ2xlZnQnKSB7XHJcblx0XHRcdHggKz0gcGFkZGluZ0FuZFNpemU7XHJcblx0XHR9IGVsc2UgaWYgKHhBbGlnbiA9PT0gJ3JpZ2h0Jykge1xyXG5cdFx0XHR4IC09IHBhZGRpbmdBbmRTaXplO1xyXG5cdFx0fVxyXG5cdH0gZWxzZSBpZiAoeEFsaWduID09PSAnbGVmdCcpIHtcclxuXHRcdHggLT0gcmFkaXVzQW5kUGFkZGluZztcclxuXHR9IGVsc2UgaWYgKHhBbGlnbiA9PT0gJ3JpZ2h0Jykge1xyXG5cdFx0eCArPSByYWRpdXNBbmRQYWRkaW5nO1xyXG5cdH1cclxuXHJcblx0cmV0dXJuIHtcclxuXHRcdHg6IHgsXHJcblx0XHR5OiB5XHJcblx0fTtcclxufVxyXG5cclxuZnVuY3Rpb24gZ2V0QWxpZ25lZFgodm0sIGFsaWduKSB7XHJcblx0cmV0dXJuIGFsaWduID09PSAnY2VudGVyJ1xyXG5cdFx0PyB2bS54ICsgdm0ud2lkdGggLyAyXHJcblx0XHQ6IGFsaWduID09PSAncmlnaHQnXHJcblx0XHRcdD8gdm0ueCArIHZtLndpZHRoIC0gdm0ueFBhZGRpbmdcclxuXHRcdFx0OiB2bS54ICsgdm0ueFBhZGRpbmc7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBIZWxwZXIgdG8gYnVpbGQgYmVmb3JlIGFuZCBhZnRlciBib2R5IGxpbmVzXHJcbiAqL1xyXG5mdW5jdGlvbiBnZXRCZWZvcmVBZnRlckJvZHlMaW5lcyhjYWxsYmFjaykge1xyXG5cdHJldHVybiBwdXNoT3JDb25jYXQoW10sIHNwbGl0TmV3bGluZXMoY2FsbGJhY2spKTtcclxufVxyXG5cclxudmFyIGV4cG9ydHMkNCA9IGNvcmVfZWxlbWVudC5leHRlbmQoe1xyXG5cdGluaXRpYWxpemU6IGZ1bmN0aW9uKCkge1xyXG5cdFx0dGhpcy5fbW9kZWwgPSBnZXRCYXNlTW9kZWwodGhpcy5fb3B0aW9ucyk7XHJcblx0XHR0aGlzLl9sYXN0QWN0aXZlID0gW107XHJcblx0fSxcclxuXHJcblx0Ly8gR2V0IHRoZSB0aXRsZVxyXG5cdC8vIEFyZ3MgYXJlOiAodG9vbHRpcEl0ZW0sIGRhdGEpXHJcblx0Z2V0VGl0bGU6IGZ1bmN0aW9uKCkge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHRcdHZhciBvcHRzID0gbWUuX29wdGlvbnM7XHJcblx0XHR2YXIgY2FsbGJhY2tzID0gb3B0cy5jYWxsYmFja3M7XHJcblxyXG5cdFx0dmFyIGJlZm9yZVRpdGxlID0gY2FsbGJhY2tzLmJlZm9yZVRpdGxlLmFwcGx5KG1lLCBhcmd1bWVudHMpO1xyXG5cdFx0dmFyIHRpdGxlID0gY2FsbGJhY2tzLnRpdGxlLmFwcGx5KG1lLCBhcmd1bWVudHMpO1xyXG5cdFx0dmFyIGFmdGVyVGl0bGUgPSBjYWxsYmFja3MuYWZ0ZXJUaXRsZS5hcHBseShtZSwgYXJndW1lbnRzKTtcclxuXHJcblx0XHR2YXIgbGluZXMgPSBbXTtcclxuXHRcdGxpbmVzID0gcHVzaE9yQ29uY2F0KGxpbmVzLCBzcGxpdE5ld2xpbmVzKGJlZm9yZVRpdGxlKSk7XHJcblx0XHRsaW5lcyA9IHB1c2hPckNvbmNhdChsaW5lcywgc3BsaXROZXdsaW5lcyh0aXRsZSkpO1xyXG5cdFx0bGluZXMgPSBwdXNoT3JDb25jYXQobGluZXMsIHNwbGl0TmV3bGluZXMoYWZ0ZXJUaXRsZSkpO1xyXG5cclxuXHRcdHJldHVybiBsaW5lcztcclxuXHR9LFxyXG5cclxuXHQvLyBBcmdzIGFyZTogKHRvb2x0aXBJdGVtLCBkYXRhKVxyXG5cdGdldEJlZm9yZUJvZHk6IGZ1bmN0aW9uKCkge1xyXG5cdFx0cmV0dXJuIGdldEJlZm9yZUFmdGVyQm9keUxpbmVzKHRoaXMuX29wdGlvbnMuY2FsbGJhY2tzLmJlZm9yZUJvZHkuYXBwbHkodGhpcywgYXJndW1lbnRzKSk7XHJcblx0fSxcclxuXHJcblx0Ly8gQXJncyBhcmU6ICh0b29sdGlwSXRlbSwgZGF0YSlcclxuXHRnZXRCb2R5OiBmdW5jdGlvbih0b29sdGlwSXRlbXMsIGRhdGEpIHtcclxuXHRcdHZhciBtZSA9IHRoaXM7XHJcblx0XHR2YXIgY2FsbGJhY2tzID0gbWUuX29wdGlvbnMuY2FsbGJhY2tzO1xyXG5cdFx0dmFyIGJvZHlJdGVtcyA9IFtdO1xyXG5cclxuXHRcdGhlbHBlcnMkMS5lYWNoKHRvb2x0aXBJdGVtcywgZnVuY3Rpb24odG9vbHRpcEl0ZW0pIHtcclxuXHRcdFx0dmFyIGJvZHlJdGVtID0ge1xyXG5cdFx0XHRcdGJlZm9yZTogW10sXHJcblx0XHRcdFx0bGluZXM6IFtdLFxyXG5cdFx0XHRcdGFmdGVyOiBbXVxyXG5cdFx0XHR9O1xyXG5cdFx0XHRwdXNoT3JDb25jYXQoYm9keUl0ZW0uYmVmb3JlLCBzcGxpdE5ld2xpbmVzKGNhbGxiYWNrcy5iZWZvcmVMYWJlbC5jYWxsKG1lLCB0b29sdGlwSXRlbSwgZGF0YSkpKTtcclxuXHRcdFx0cHVzaE9yQ29uY2F0KGJvZHlJdGVtLmxpbmVzLCBjYWxsYmFja3MubGFiZWwuY2FsbChtZSwgdG9vbHRpcEl0ZW0sIGRhdGEpKTtcclxuXHRcdFx0cHVzaE9yQ29uY2F0KGJvZHlJdGVtLmFmdGVyLCBzcGxpdE5ld2xpbmVzKGNhbGxiYWNrcy5hZnRlckxhYmVsLmNhbGwobWUsIHRvb2x0aXBJdGVtLCBkYXRhKSkpO1xyXG5cclxuXHRcdFx0Ym9keUl0ZW1zLnB1c2goYm9keUl0ZW0pO1xyXG5cdFx0fSk7XHJcblxyXG5cdFx0cmV0dXJuIGJvZHlJdGVtcztcclxuXHR9LFxyXG5cclxuXHQvLyBBcmdzIGFyZTogKHRvb2x0aXBJdGVtLCBkYXRhKVxyXG5cdGdldEFmdGVyQm9keTogZnVuY3Rpb24oKSB7XHJcblx0XHRyZXR1cm4gZ2V0QmVmb3JlQWZ0ZXJCb2R5TGluZXModGhpcy5fb3B0aW9ucy5jYWxsYmFja3MuYWZ0ZXJCb2R5LmFwcGx5KHRoaXMsIGFyZ3VtZW50cykpO1xyXG5cdH0sXHJcblxyXG5cdC8vIEdldCB0aGUgZm9vdGVyIGFuZCBiZWZvcmVGb290ZXIgYW5kIGFmdGVyRm9vdGVyIGxpbmVzXHJcblx0Ly8gQXJncyBhcmU6ICh0b29sdGlwSXRlbSwgZGF0YSlcclxuXHRnZXRGb290ZXI6IGZ1bmN0aW9uKCkge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHRcdHZhciBjYWxsYmFja3MgPSBtZS5fb3B0aW9ucy5jYWxsYmFja3M7XHJcblxyXG5cdFx0dmFyIGJlZm9yZUZvb3RlciA9IGNhbGxiYWNrcy5iZWZvcmVGb290ZXIuYXBwbHkobWUsIGFyZ3VtZW50cyk7XHJcblx0XHR2YXIgZm9vdGVyID0gY2FsbGJhY2tzLmZvb3Rlci5hcHBseShtZSwgYXJndW1lbnRzKTtcclxuXHRcdHZhciBhZnRlckZvb3RlciA9IGNhbGxiYWNrcy5hZnRlckZvb3Rlci5hcHBseShtZSwgYXJndW1lbnRzKTtcclxuXHJcblx0XHR2YXIgbGluZXMgPSBbXTtcclxuXHRcdGxpbmVzID0gcHVzaE9yQ29uY2F0KGxpbmVzLCBzcGxpdE5ld2xpbmVzKGJlZm9yZUZvb3RlcikpO1xyXG5cdFx0bGluZXMgPSBwdXNoT3JDb25jYXQobGluZXMsIHNwbGl0TmV3bGluZXMoZm9vdGVyKSk7XHJcblx0XHRsaW5lcyA9IHB1c2hPckNvbmNhdChsaW5lcywgc3BsaXROZXdsaW5lcyhhZnRlckZvb3RlcikpO1xyXG5cclxuXHRcdHJldHVybiBsaW5lcztcclxuXHR9LFxyXG5cclxuXHR1cGRhdGU6IGZ1bmN0aW9uKGNoYW5nZWQpIHtcclxuXHRcdHZhciBtZSA9IHRoaXM7XHJcblx0XHR2YXIgb3B0cyA9IG1lLl9vcHRpb25zO1xyXG5cclxuXHRcdC8vIE5lZWQgdG8gcmVnZW5lcmF0ZSB0aGUgbW9kZWwgYmVjYXVzZSBpdHMgZmFzdGVyIHRoYW4gdXNpbmcgZXh0ZW5kIGFuZCBpdCBpcyBuZWNlc3NhcnkgZHVlIHRvIHRoZSBvcHRpbWl6YXRpb24gaW4gQ2hhcnQuRWxlbWVudC50cmFuc2l0aW9uXHJcblx0XHQvLyB0aGF0IGRvZXMgX3ZpZXcgPSBfbW9kZWwgaWYgZWFzZSA9PT0gMS4gVGhpcyBjYXVzZXMgdGhlIDJuZCB0b29sdGlwIHVwZGF0ZSB0byBzZXQgcHJvcGVydGllcyBpbiBib3RoIHRoZSB2aWV3IGFuZCBtb2RlbCBhdCB0aGUgc2FtZSB0aW1lXHJcblx0XHQvLyB3aGljaCBicmVha3MgYW55IGFuaW1hdGlvbnMuXHJcblx0XHR2YXIgZXhpc3RpbmdNb2RlbCA9IG1lLl9tb2RlbDtcclxuXHRcdHZhciBtb2RlbCA9IG1lLl9tb2RlbCA9IGdldEJhc2VNb2RlbChvcHRzKTtcclxuXHRcdHZhciBhY3RpdmUgPSBtZS5fYWN0aXZlO1xyXG5cclxuXHRcdHZhciBkYXRhID0gbWUuX2RhdGE7XHJcblxyXG5cdFx0Ly8gSW4gdGhlIGNhc2Ugd2hlcmUgYWN0aXZlLmxlbmd0aCA9PT0gMCB3ZSBuZWVkIHRvIGtlZXAgdGhlc2UgYXQgZXhpc3RpbmcgdmFsdWVzIGZvciBnb29kIGFuaW1hdGlvbnNcclxuXHRcdHZhciBhbGlnbm1lbnQgPSB7XHJcblx0XHRcdHhBbGlnbjogZXhpc3RpbmdNb2RlbC54QWxpZ24sXHJcblx0XHRcdHlBbGlnbjogZXhpc3RpbmdNb2RlbC55QWxpZ25cclxuXHRcdH07XHJcblx0XHR2YXIgYmFja2dyb3VuZFBvaW50ID0ge1xyXG5cdFx0XHR4OiBleGlzdGluZ01vZGVsLngsXHJcblx0XHRcdHk6IGV4aXN0aW5nTW9kZWwueVxyXG5cdFx0fTtcclxuXHRcdHZhciB0b29sdGlwU2l6ZSA9IHtcclxuXHRcdFx0d2lkdGg6IGV4aXN0aW5nTW9kZWwud2lkdGgsXHJcblx0XHRcdGhlaWdodDogZXhpc3RpbmdNb2RlbC5oZWlnaHRcclxuXHRcdH07XHJcblx0XHR2YXIgdG9vbHRpcFBvc2l0aW9uID0ge1xyXG5cdFx0XHR4OiBleGlzdGluZ01vZGVsLmNhcmV0WCxcclxuXHRcdFx0eTogZXhpc3RpbmdNb2RlbC5jYXJldFlcclxuXHRcdH07XHJcblxyXG5cdFx0dmFyIGksIGxlbjtcclxuXHJcblx0XHRpZiAoYWN0aXZlLmxlbmd0aCkge1xyXG5cdFx0XHRtb2RlbC5vcGFjaXR5ID0gMTtcclxuXHJcblx0XHRcdHZhciBsYWJlbENvbG9ycyA9IFtdO1xyXG5cdFx0XHR2YXIgbGFiZWxUZXh0Q29sb3JzID0gW107XHJcblx0XHRcdHRvb2x0aXBQb3NpdGlvbiA9IHBvc2l0aW9uZXJzW29wdHMucG9zaXRpb25dLmNhbGwobWUsIGFjdGl2ZSwgbWUuX2V2ZW50UG9zaXRpb24pO1xyXG5cclxuXHRcdFx0dmFyIHRvb2x0aXBJdGVtcyA9IFtdO1xyXG5cdFx0XHRmb3IgKGkgPSAwLCBsZW4gPSBhY3RpdmUubGVuZ3RoOyBpIDwgbGVuOyArK2kpIHtcclxuXHRcdFx0XHR0b29sdGlwSXRlbXMucHVzaChjcmVhdGVUb29sdGlwSXRlbShhY3RpdmVbaV0pKTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Ly8gSWYgdGhlIHVzZXIgcHJvdmlkZWQgYSBmaWx0ZXIgZnVuY3Rpb24sIHVzZSBpdCB0byBtb2RpZnkgdGhlIHRvb2x0aXAgaXRlbXNcclxuXHRcdFx0aWYgKG9wdHMuZmlsdGVyKSB7XHJcblx0XHRcdFx0dG9vbHRpcEl0ZW1zID0gdG9vbHRpcEl0ZW1zLmZpbHRlcihmdW5jdGlvbihhKSB7XHJcblx0XHRcdFx0XHRyZXR1cm4gb3B0cy5maWx0ZXIoYSwgZGF0YSk7XHJcblx0XHRcdFx0fSk7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIElmIHRoZSB1c2VyIHByb3ZpZGVkIGEgc29ydGluZyBmdW5jdGlvbiwgdXNlIGl0IHRvIG1vZGlmeSB0aGUgdG9vbHRpcCBpdGVtc1xyXG5cdFx0XHRpZiAob3B0cy5pdGVtU29ydCkge1xyXG5cdFx0XHRcdHRvb2x0aXBJdGVtcyA9IHRvb2x0aXBJdGVtcy5zb3J0KGZ1bmN0aW9uKGEsIGIpIHtcclxuXHRcdFx0XHRcdHJldHVybiBvcHRzLml0ZW1Tb3J0KGEsIGIsIGRhdGEpO1xyXG5cdFx0XHRcdH0pO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBEZXRlcm1pbmUgY29sb3JzIGZvciBib3hlc1xyXG5cdFx0XHRoZWxwZXJzJDEuZWFjaCh0b29sdGlwSXRlbXMsIGZ1bmN0aW9uKHRvb2x0aXBJdGVtKSB7XHJcblx0XHRcdFx0bGFiZWxDb2xvcnMucHVzaChvcHRzLmNhbGxiYWNrcy5sYWJlbENvbG9yLmNhbGwobWUsIHRvb2x0aXBJdGVtLCBtZS5fY2hhcnQpKTtcclxuXHRcdFx0XHRsYWJlbFRleHRDb2xvcnMucHVzaChvcHRzLmNhbGxiYWNrcy5sYWJlbFRleHRDb2xvci5jYWxsKG1lLCB0b29sdGlwSXRlbSwgbWUuX2NoYXJ0KSk7XHJcblx0XHRcdH0pO1xyXG5cclxuXHJcblx0XHRcdC8vIEJ1aWxkIHRoZSBUZXh0IExpbmVzXHJcblx0XHRcdG1vZGVsLnRpdGxlID0gbWUuZ2V0VGl0bGUodG9vbHRpcEl0ZW1zLCBkYXRhKTtcclxuXHRcdFx0bW9kZWwuYmVmb3JlQm9keSA9IG1lLmdldEJlZm9yZUJvZHkodG9vbHRpcEl0ZW1zLCBkYXRhKTtcclxuXHRcdFx0bW9kZWwuYm9keSA9IG1lLmdldEJvZHkodG9vbHRpcEl0ZW1zLCBkYXRhKTtcclxuXHRcdFx0bW9kZWwuYWZ0ZXJCb2R5ID0gbWUuZ2V0QWZ0ZXJCb2R5KHRvb2x0aXBJdGVtcywgZGF0YSk7XHJcblx0XHRcdG1vZGVsLmZvb3RlciA9IG1lLmdldEZvb3Rlcih0b29sdGlwSXRlbXMsIGRhdGEpO1xyXG5cclxuXHRcdFx0Ly8gSW5pdGlhbCBwb3NpdGlvbmluZyBhbmQgY29sb3JzXHJcblx0XHRcdG1vZGVsLnggPSB0b29sdGlwUG9zaXRpb24ueDtcclxuXHRcdFx0bW9kZWwueSA9IHRvb2x0aXBQb3NpdGlvbi55O1xyXG5cdFx0XHRtb2RlbC5jYXJldFBhZGRpbmcgPSBvcHRzLmNhcmV0UGFkZGluZztcclxuXHRcdFx0bW9kZWwubGFiZWxDb2xvcnMgPSBsYWJlbENvbG9ycztcclxuXHRcdFx0bW9kZWwubGFiZWxUZXh0Q29sb3JzID0gbGFiZWxUZXh0Q29sb3JzO1xyXG5cclxuXHRcdFx0Ly8gZGF0YSBwb2ludHNcclxuXHRcdFx0bW9kZWwuZGF0YVBvaW50cyA9IHRvb2x0aXBJdGVtcztcclxuXHJcblx0XHRcdC8vIFdlIG5lZWQgdG8gZGV0ZXJtaW5lIGFsaWdubWVudCBvZiB0aGUgdG9vbHRpcFxyXG5cdFx0XHR0b29sdGlwU2l6ZSA9IGdldFRvb2x0aXBTaXplKHRoaXMsIG1vZGVsKTtcclxuXHRcdFx0YWxpZ25tZW50ID0gZGV0ZXJtaW5lQWxpZ25tZW50KHRoaXMsIHRvb2x0aXBTaXplKTtcclxuXHRcdFx0Ly8gRmluYWwgU2l6ZSBhbmQgUG9zaXRpb25cclxuXHRcdFx0YmFja2dyb3VuZFBvaW50ID0gZ2V0QmFja2dyb3VuZFBvaW50KG1vZGVsLCB0b29sdGlwU2l6ZSwgYWxpZ25tZW50LCBtZS5fY2hhcnQpO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0bW9kZWwub3BhY2l0eSA9IDA7XHJcblx0XHR9XHJcblxyXG5cdFx0bW9kZWwueEFsaWduID0gYWxpZ25tZW50LnhBbGlnbjtcclxuXHRcdG1vZGVsLnlBbGlnbiA9IGFsaWdubWVudC55QWxpZ247XHJcblx0XHRtb2RlbC54ID0gYmFja2dyb3VuZFBvaW50Lng7XHJcblx0XHRtb2RlbC55ID0gYmFja2dyb3VuZFBvaW50Lnk7XHJcblx0XHRtb2RlbC53aWR0aCA9IHRvb2x0aXBTaXplLndpZHRoO1xyXG5cdFx0bW9kZWwuaGVpZ2h0ID0gdG9vbHRpcFNpemUuaGVpZ2h0O1xyXG5cclxuXHRcdC8vIFBvaW50IHdoZXJlIHRoZSBjYXJldCBvbiB0aGUgdG9vbHRpcCBwb2ludHMgdG9cclxuXHRcdG1vZGVsLmNhcmV0WCA9IHRvb2x0aXBQb3NpdGlvbi54O1xyXG5cdFx0bW9kZWwuY2FyZXRZID0gdG9vbHRpcFBvc2l0aW9uLnk7XHJcblxyXG5cdFx0bWUuX21vZGVsID0gbW9kZWw7XHJcblxyXG5cdFx0aWYgKGNoYW5nZWQgJiYgb3B0cy5jdXN0b20pIHtcclxuXHRcdFx0b3B0cy5jdXN0b20uY2FsbChtZSwgbW9kZWwpO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiBtZTtcclxuXHR9LFxyXG5cclxuXHRkcmF3Q2FyZXQ6IGZ1bmN0aW9uKHRvb2x0aXBQb2ludCwgc2l6ZSkge1xyXG5cdFx0dmFyIGN0eCA9IHRoaXMuX2NoYXJ0LmN0eDtcclxuXHRcdHZhciB2bSA9IHRoaXMuX3ZpZXc7XHJcblx0XHR2YXIgY2FyZXRQb3NpdGlvbiA9IHRoaXMuZ2V0Q2FyZXRQb3NpdGlvbih0b29sdGlwUG9pbnQsIHNpemUsIHZtKTtcclxuXHJcblx0XHRjdHgubGluZVRvKGNhcmV0UG9zaXRpb24ueDEsIGNhcmV0UG9zaXRpb24ueTEpO1xyXG5cdFx0Y3R4LmxpbmVUbyhjYXJldFBvc2l0aW9uLngyLCBjYXJldFBvc2l0aW9uLnkyKTtcclxuXHRcdGN0eC5saW5lVG8oY2FyZXRQb3NpdGlvbi54MywgY2FyZXRQb3NpdGlvbi55Myk7XHJcblx0fSxcclxuXHRnZXRDYXJldFBvc2l0aW9uOiBmdW5jdGlvbih0b29sdGlwUG9pbnQsIHNpemUsIHZtKSB7XHJcblx0XHR2YXIgeDEsIHgyLCB4MywgeTEsIHkyLCB5MztcclxuXHRcdHZhciBjYXJldFNpemUgPSB2bS5jYXJldFNpemU7XHJcblx0XHR2YXIgY29ybmVyUmFkaXVzID0gdm0uY29ybmVyUmFkaXVzO1xyXG5cdFx0dmFyIHhBbGlnbiA9IHZtLnhBbGlnbjtcclxuXHRcdHZhciB5QWxpZ24gPSB2bS55QWxpZ247XHJcblx0XHR2YXIgcHRYID0gdG9vbHRpcFBvaW50Lng7XHJcblx0XHR2YXIgcHRZID0gdG9vbHRpcFBvaW50Lnk7XHJcblx0XHR2YXIgd2lkdGggPSBzaXplLndpZHRoO1xyXG5cdFx0dmFyIGhlaWdodCA9IHNpemUuaGVpZ2h0O1xyXG5cclxuXHRcdGlmICh5QWxpZ24gPT09ICdjZW50ZXInKSB7XHJcblx0XHRcdHkyID0gcHRZICsgKGhlaWdodCAvIDIpO1xyXG5cclxuXHRcdFx0aWYgKHhBbGlnbiA9PT0gJ2xlZnQnKSB7XHJcblx0XHRcdFx0eDEgPSBwdFg7XHJcblx0XHRcdFx0eDIgPSB4MSAtIGNhcmV0U2l6ZTtcclxuXHRcdFx0XHR4MyA9IHgxO1xyXG5cclxuXHRcdFx0XHR5MSA9IHkyICsgY2FyZXRTaXplO1xyXG5cdFx0XHRcdHkzID0geTIgLSBjYXJldFNpemU7XHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0eDEgPSBwdFggKyB3aWR0aDtcclxuXHRcdFx0XHR4MiA9IHgxICsgY2FyZXRTaXplO1xyXG5cdFx0XHRcdHgzID0geDE7XHJcblxyXG5cdFx0XHRcdHkxID0geTIgLSBjYXJldFNpemU7XHJcblx0XHRcdFx0eTMgPSB5MiArIGNhcmV0U2l6ZTtcclxuXHRcdFx0fVxyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0aWYgKHhBbGlnbiA9PT0gJ2xlZnQnKSB7XHJcblx0XHRcdFx0eDIgPSBwdFggKyBjb3JuZXJSYWRpdXMgKyAoY2FyZXRTaXplKTtcclxuXHRcdFx0XHR4MSA9IHgyIC0gY2FyZXRTaXplO1xyXG5cdFx0XHRcdHgzID0geDIgKyBjYXJldFNpemU7XHJcblx0XHRcdH0gZWxzZSBpZiAoeEFsaWduID09PSAncmlnaHQnKSB7XHJcblx0XHRcdFx0eDIgPSBwdFggKyB3aWR0aCAtIGNvcm5lclJhZGl1cyAtIGNhcmV0U2l6ZTtcclxuXHRcdFx0XHR4MSA9IHgyIC0gY2FyZXRTaXplO1xyXG5cdFx0XHRcdHgzID0geDIgKyBjYXJldFNpemU7XHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0eDIgPSB2bS5jYXJldFg7XHJcblx0XHRcdFx0eDEgPSB4MiAtIGNhcmV0U2l6ZTtcclxuXHRcdFx0XHR4MyA9IHgyICsgY2FyZXRTaXplO1xyXG5cdFx0XHR9XHJcblx0XHRcdGlmICh5QWxpZ24gPT09ICd0b3AnKSB7XHJcblx0XHRcdFx0eTEgPSBwdFk7XHJcblx0XHRcdFx0eTIgPSB5MSAtIGNhcmV0U2l6ZTtcclxuXHRcdFx0XHR5MyA9IHkxO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdHkxID0gcHRZICsgaGVpZ2h0O1xyXG5cdFx0XHRcdHkyID0geTEgKyBjYXJldFNpemU7XHJcblx0XHRcdFx0eTMgPSB5MTtcclxuXHRcdFx0XHQvLyBpbnZlcnQgZHJhd2luZyBvcmRlclxyXG5cdFx0XHRcdHZhciB0bXAgPSB4MztcclxuXHRcdFx0XHR4MyA9IHgxO1xyXG5cdFx0XHRcdHgxID0gdG1wO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0XHRyZXR1cm4ge3gxOiB4MSwgeDI6IHgyLCB4MzogeDMsIHkxOiB5MSwgeTI6IHkyLCB5MzogeTN9O1xyXG5cdH0sXHJcblxyXG5cdGRyYXdUaXRsZTogZnVuY3Rpb24ocHQsIHZtLCBjdHgpIHtcclxuXHRcdHZhciB0aXRsZSA9IHZtLnRpdGxlO1xyXG5cdFx0dmFyIGxlbmd0aCA9IHRpdGxlLmxlbmd0aDtcclxuXHRcdHZhciB0aXRsZUZvbnRTaXplLCB0aXRsZVNwYWNpbmcsIGk7XHJcblxyXG5cdFx0aWYgKGxlbmd0aCkge1xyXG5cdFx0XHR2YXIgcnRsSGVscGVyID0gZ2V0UnRsSGVscGVyKHZtLnJ0bCwgdm0ueCwgdm0ud2lkdGgpO1xyXG5cclxuXHRcdFx0cHQueCA9IGdldEFsaWduZWRYKHZtLCB2bS5fdGl0bGVBbGlnbik7XHJcblxyXG5cdFx0XHRjdHgudGV4dEFsaWduID0gcnRsSGVscGVyLnRleHRBbGlnbih2bS5fdGl0bGVBbGlnbik7XHJcblx0XHRcdGN0eC50ZXh0QmFzZWxpbmUgPSAnbWlkZGxlJztcclxuXHJcblx0XHRcdHRpdGxlRm9udFNpemUgPSB2bS50aXRsZUZvbnRTaXplO1xyXG5cdFx0XHR0aXRsZVNwYWNpbmcgPSB2bS50aXRsZVNwYWNpbmc7XHJcblxyXG5cdFx0XHRjdHguZmlsbFN0eWxlID0gdm0udGl0bGVGb250Q29sb3I7XHJcblx0XHRcdGN0eC5mb250ID0gaGVscGVycyQxLmZvbnRTdHJpbmcodGl0bGVGb250U2l6ZSwgdm0uX3RpdGxlRm9udFN0eWxlLCB2bS5fdGl0bGVGb250RmFtaWx5KTtcclxuXHJcblx0XHRcdGZvciAoaSA9IDA7IGkgPCBsZW5ndGg7ICsraSkge1xyXG5cdFx0XHRcdGN0eC5maWxsVGV4dCh0aXRsZVtpXSwgcnRsSGVscGVyLngocHQueCksIHB0LnkgKyB0aXRsZUZvbnRTaXplIC8gMik7XHJcblx0XHRcdFx0cHQueSArPSB0aXRsZUZvbnRTaXplICsgdGl0bGVTcGFjaW5nOyAvLyBMaW5lIEhlaWdodCBhbmQgc3BhY2luZ1xyXG5cclxuXHRcdFx0XHRpZiAoaSArIDEgPT09IGxlbmd0aCkge1xyXG5cdFx0XHRcdFx0cHQueSArPSB2bS50aXRsZU1hcmdpbkJvdHRvbSAtIHRpdGxlU3BhY2luZzsgLy8gSWYgTGFzdCwgYWRkIG1hcmdpbiwgcmVtb3ZlIHNwYWNpbmdcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHR9LFxyXG5cclxuXHRkcmF3Qm9keTogZnVuY3Rpb24ocHQsIHZtLCBjdHgpIHtcclxuXHRcdHZhciBib2R5Rm9udFNpemUgPSB2bS5ib2R5Rm9udFNpemU7XHJcblx0XHR2YXIgYm9keVNwYWNpbmcgPSB2bS5ib2R5U3BhY2luZztcclxuXHRcdHZhciBib2R5QWxpZ24gPSB2bS5fYm9keUFsaWduO1xyXG5cdFx0dmFyIGJvZHkgPSB2bS5ib2R5O1xyXG5cdFx0dmFyIGRyYXdDb2xvckJveGVzID0gdm0uZGlzcGxheUNvbG9ycztcclxuXHRcdHZhciB4TGluZVBhZGRpbmcgPSAwO1xyXG5cdFx0dmFyIGNvbG9yWCA9IGRyYXdDb2xvckJveGVzID8gZ2V0QWxpZ25lZFgodm0sICdsZWZ0JykgOiAwO1xyXG5cclxuXHRcdHZhciBydGxIZWxwZXIgPSBnZXRSdGxIZWxwZXIodm0ucnRsLCB2bS54LCB2bS53aWR0aCk7XHJcblxyXG5cdFx0dmFyIGZpbGxMaW5lT2ZUZXh0ID0gZnVuY3Rpb24obGluZSkge1xyXG5cdFx0XHRjdHguZmlsbFRleHQobGluZSwgcnRsSGVscGVyLngocHQueCArIHhMaW5lUGFkZGluZyksIHB0LnkgKyBib2R5Rm9udFNpemUgLyAyKTtcclxuXHRcdFx0cHQueSArPSBib2R5Rm9udFNpemUgKyBib2R5U3BhY2luZztcclxuXHRcdH07XHJcblxyXG5cdFx0dmFyIGJvZHlJdGVtLCB0ZXh0Q29sb3IsIGxhYmVsQ29sb3JzLCBsaW5lcywgaSwgaiwgaWxlbiwgamxlbjtcclxuXHRcdHZhciBib2R5QWxpZ25Gb3JDYWxjdWxhdGlvbiA9IHJ0bEhlbHBlci50ZXh0QWxpZ24oYm9keUFsaWduKTtcclxuXHJcblx0XHRjdHgudGV4dEFsaWduID0gYm9keUFsaWduO1xyXG5cdFx0Y3R4LnRleHRCYXNlbGluZSA9ICdtaWRkbGUnO1xyXG5cdFx0Y3R4LmZvbnQgPSBoZWxwZXJzJDEuZm9udFN0cmluZyhib2R5Rm9udFNpemUsIHZtLl9ib2R5Rm9udFN0eWxlLCB2bS5fYm9keUZvbnRGYW1pbHkpO1xyXG5cclxuXHRcdHB0LnggPSBnZXRBbGlnbmVkWCh2bSwgYm9keUFsaWduRm9yQ2FsY3VsYXRpb24pO1xyXG5cclxuXHRcdC8vIEJlZm9yZSBib2R5IGxpbmVzXHJcblx0XHRjdHguZmlsbFN0eWxlID0gdm0uYm9keUZvbnRDb2xvcjtcclxuXHRcdGhlbHBlcnMkMS5lYWNoKHZtLmJlZm9yZUJvZHksIGZpbGxMaW5lT2ZUZXh0KTtcclxuXHJcblx0XHR4TGluZVBhZGRpbmcgPSBkcmF3Q29sb3JCb3hlcyAmJiBib2R5QWxpZ25Gb3JDYWxjdWxhdGlvbiAhPT0gJ3JpZ2h0J1xyXG5cdFx0XHQ/IGJvZHlBbGlnbiA9PT0gJ2NlbnRlcicgPyAoYm9keUZvbnRTaXplIC8gMiArIDEpIDogKGJvZHlGb250U2l6ZSArIDIpXHJcblx0XHRcdDogMDtcclxuXHJcblx0XHQvLyBEcmF3IGJvZHkgbGluZXMgbm93XHJcblx0XHRmb3IgKGkgPSAwLCBpbGVuID0gYm9keS5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcclxuXHRcdFx0Ym9keUl0ZW0gPSBib2R5W2ldO1xyXG5cdFx0XHR0ZXh0Q29sb3IgPSB2bS5sYWJlbFRleHRDb2xvcnNbaV07XHJcblx0XHRcdGxhYmVsQ29sb3JzID0gdm0ubGFiZWxDb2xvcnNbaV07XHJcblxyXG5cdFx0XHRjdHguZmlsbFN0eWxlID0gdGV4dENvbG9yO1xyXG5cdFx0XHRoZWxwZXJzJDEuZWFjaChib2R5SXRlbS5iZWZvcmUsIGZpbGxMaW5lT2ZUZXh0KTtcclxuXHJcblx0XHRcdGxpbmVzID0gYm9keUl0ZW0ubGluZXM7XHJcblx0XHRcdGZvciAoaiA9IDAsIGpsZW4gPSBsaW5lcy5sZW5ndGg7IGogPCBqbGVuOyArK2opIHtcclxuXHRcdFx0XHQvLyBEcmF3IExlZ2VuZC1saWtlIGJveGVzIGlmIG5lZWRlZFxyXG5cdFx0XHRcdGlmIChkcmF3Q29sb3JCb3hlcykge1xyXG5cdFx0XHRcdFx0dmFyIHJ0bENvbG9yWCA9IHJ0bEhlbHBlci54KGNvbG9yWCk7XHJcblxyXG5cdFx0XHRcdFx0Ly8gRmlsbCBhIHdoaXRlIHJlY3Qgc28gdGhhdCBjb2xvdXJzIG1lcmdlIG5pY2VseSBpZiB0aGUgb3BhY2l0eSBpcyA8IDFcclxuXHRcdFx0XHRcdGN0eC5maWxsU3R5bGUgPSB2bS5sZWdlbmRDb2xvckJhY2tncm91bmQ7XHJcblx0XHRcdFx0XHRjdHguZmlsbFJlY3QocnRsSGVscGVyLmxlZnRGb3JMdHIocnRsQ29sb3JYLCBib2R5Rm9udFNpemUpLCBwdC55LCBib2R5Rm9udFNpemUsIGJvZHlGb250U2l6ZSk7XHJcblxyXG5cdFx0XHRcdFx0Ly8gQm9yZGVyXHJcblx0XHRcdFx0XHRjdHgubGluZVdpZHRoID0gMTtcclxuXHRcdFx0XHRcdGN0eC5zdHJva2VTdHlsZSA9IGxhYmVsQ29sb3JzLmJvcmRlckNvbG9yO1xyXG5cdFx0XHRcdFx0Y3R4LnN0cm9rZVJlY3QocnRsSGVscGVyLmxlZnRGb3JMdHIocnRsQ29sb3JYLCBib2R5Rm9udFNpemUpLCBwdC55LCBib2R5Rm9udFNpemUsIGJvZHlGb250U2l6ZSk7XHJcblxyXG5cdFx0XHRcdFx0Ly8gSW5uZXIgc3F1YXJlXHJcblx0XHRcdFx0XHRjdHguZmlsbFN0eWxlID0gbGFiZWxDb2xvcnMuYmFja2dyb3VuZENvbG9yO1xyXG5cdFx0XHRcdFx0Y3R4LmZpbGxSZWN0KHJ0bEhlbHBlci5sZWZ0Rm9yTHRyKHJ0bEhlbHBlci54UGx1cyhydGxDb2xvclgsIDEpLCBib2R5Rm9udFNpemUgLSAyKSwgcHQueSArIDEsIGJvZHlGb250U2l6ZSAtIDIsIGJvZHlGb250U2l6ZSAtIDIpO1xyXG5cdFx0XHRcdFx0Y3R4LmZpbGxTdHlsZSA9IHRleHRDb2xvcjtcclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdGZpbGxMaW5lT2ZUZXh0KGxpbmVzW2pdKTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0aGVscGVycyQxLmVhY2goYm9keUl0ZW0uYWZ0ZXIsIGZpbGxMaW5lT2ZUZXh0KTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBSZXNldCBiYWNrIHRvIDAgZm9yIGFmdGVyIGJvZHlcclxuXHRcdHhMaW5lUGFkZGluZyA9IDA7XHJcblxyXG5cdFx0Ly8gQWZ0ZXIgYm9keSBsaW5lc1xyXG5cdFx0aGVscGVycyQxLmVhY2godm0uYWZ0ZXJCb2R5LCBmaWxsTGluZU9mVGV4dCk7XHJcblx0XHRwdC55IC09IGJvZHlTcGFjaW5nOyAvLyBSZW1vdmUgbGFzdCBib2R5IHNwYWNpbmdcclxuXHR9LFxyXG5cclxuXHRkcmF3Rm9vdGVyOiBmdW5jdGlvbihwdCwgdm0sIGN0eCkge1xyXG5cdFx0dmFyIGZvb3RlciA9IHZtLmZvb3RlcjtcclxuXHRcdHZhciBsZW5ndGggPSBmb290ZXIubGVuZ3RoO1xyXG5cdFx0dmFyIGZvb3RlckZvbnRTaXplLCBpO1xyXG5cclxuXHRcdGlmIChsZW5ndGgpIHtcclxuXHRcdFx0dmFyIHJ0bEhlbHBlciA9IGdldFJ0bEhlbHBlcih2bS5ydGwsIHZtLngsIHZtLndpZHRoKTtcclxuXHJcblx0XHRcdHB0LnggPSBnZXRBbGlnbmVkWCh2bSwgdm0uX2Zvb3RlckFsaWduKTtcclxuXHRcdFx0cHQueSArPSB2bS5mb290ZXJNYXJnaW5Ub3A7XHJcblxyXG5cdFx0XHRjdHgudGV4dEFsaWduID0gcnRsSGVscGVyLnRleHRBbGlnbih2bS5fZm9vdGVyQWxpZ24pO1xyXG5cdFx0XHRjdHgudGV4dEJhc2VsaW5lID0gJ21pZGRsZSc7XHJcblxyXG5cdFx0XHRmb290ZXJGb250U2l6ZSA9IHZtLmZvb3RlckZvbnRTaXplO1xyXG5cclxuXHRcdFx0Y3R4LmZpbGxTdHlsZSA9IHZtLmZvb3RlckZvbnRDb2xvcjtcclxuXHRcdFx0Y3R4LmZvbnQgPSBoZWxwZXJzJDEuZm9udFN0cmluZyhmb290ZXJGb250U2l6ZSwgdm0uX2Zvb3RlckZvbnRTdHlsZSwgdm0uX2Zvb3RlckZvbnRGYW1pbHkpO1xyXG5cclxuXHRcdFx0Zm9yIChpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7XHJcblx0XHRcdFx0Y3R4LmZpbGxUZXh0KGZvb3RlcltpXSwgcnRsSGVscGVyLngocHQueCksIHB0LnkgKyBmb290ZXJGb250U2l6ZSAvIDIpO1xyXG5cdFx0XHRcdHB0LnkgKz0gZm9vdGVyRm9udFNpemUgKyB2bS5mb290ZXJTcGFjaW5nO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0fSxcclxuXHJcblx0ZHJhd0JhY2tncm91bmQ6IGZ1bmN0aW9uKHB0LCB2bSwgY3R4LCB0b29sdGlwU2l6ZSkge1xyXG5cdFx0Y3R4LmZpbGxTdHlsZSA9IHZtLmJhY2tncm91bmRDb2xvcjtcclxuXHRcdGN0eC5zdHJva2VTdHlsZSA9IHZtLmJvcmRlckNvbG9yO1xyXG5cdFx0Y3R4LmxpbmVXaWR0aCA9IHZtLmJvcmRlcldpZHRoO1xyXG5cdFx0dmFyIHhBbGlnbiA9IHZtLnhBbGlnbjtcclxuXHRcdHZhciB5QWxpZ24gPSB2bS55QWxpZ247XHJcblx0XHR2YXIgeCA9IHB0Lng7XHJcblx0XHR2YXIgeSA9IHB0Lnk7XHJcblx0XHR2YXIgd2lkdGggPSB0b29sdGlwU2l6ZS53aWR0aDtcclxuXHRcdHZhciBoZWlnaHQgPSB0b29sdGlwU2l6ZS5oZWlnaHQ7XHJcblx0XHR2YXIgcmFkaXVzID0gdm0uY29ybmVyUmFkaXVzO1xyXG5cclxuXHRcdGN0eC5iZWdpblBhdGgoKTtcclxuXHRcdGN0eC5tb3ZlVG8oeCArIHJhZGl1cywgeSk7XHJcblx0XHRpZiAoeUFsaWduID09PSAndG9wJykge1xyXG5cdFx0XHR0aGlzLmRyYXdDYXJldChwdCwgdG9vbHRpcFNpemUpO1xyXG5cdFx0fVxyXG5cdFx0Y3R4LmxpbmVUbyh4ICsgd2lkdGggLSByYWRpdXMsIHkpO1xyXG5cdFx0Y3R4LnF1YWRyYXRpY0N1cnZlVG8oeCArIHdpZHRoLCB5LCB4ICsgd2lkdGgsIHkgKyByYWRpdXMpO1xyXG5cdFx0aWYgKHlBbGlnbiA9PT0gJ2NlbnRlcicgJiYgeEFsaWduID09PSAncmlnaHQnKSB7XHJcblx0XHRcdHRoaXMuZHJhd0NhcmV0KHB0LCB0b29sdGlwU2l6ZSk7XHJcblx0XHR9XHJcblx0XHRjdHgubGluZVRvKHggKyB3aWR0aCwgeSArIGhlaWdodCAtIHJhZGl1cyk7XHJcblx0XHRjdHgucXVhZHJhdGljQ3VydmVUbyh4ICsgd2lkdGgsIHkgKyBoZWlnaHQsIHggKyB3aWR0aCAtIHJhZGl1cywgeSArIGhlaWdodCk7XHJcblx0XHRpZiAoeUFsaWduID09PSAnYm90dG9tJykge1xyXG5cdFx0XHR0aGlzLmRyYXdDYXJldChwdCwgdG9vbHRpcFNpemUpO1xyXG5cdFx0fVxyXG5cdFx0Y3R4LmxpbmVUbyh4ICsgcmFkaXVzLCB5ICsgaGVpZ2h0KTtcclxuXHRcdGN0eC5xdWFkcmF0aWNDdXJ2ZVRvKHgsIHkgKyBoZWlnaHQsIHgsIHkgKyBoZWlnaHQgLSByYWRpdXMpO1xyXG5cdFx0aWYgKHlBbGlnbiA9PT0gJ2NlbnRlcicgJiYgeEFsaWduID09PSAnbGVmdCcpIHtcclxuXHRcdFx0dGhpcy5kcmF3Q2FyZXQocHQsIHRvb2x0aXBTaXplKTtcclxuXHRcdH1cclxuXHRcdGN0eC5saW5lVG8oeCwgeSArIHJhZGl1cyk7XHJcblx0XHRjdHgucXVhZHJhdGljQ3VydmVUbyh4LCB5LCB4ICsgcmFkaXVzLCB5KTtcclxuXHRcdGN0eC5jbG9zZVBhdGgoKTtcclxuXHJcblx0XHRjdHguZmlsbCgpO1xyXG5cclxuXHRcdGlmICh2bS5ib3JkZXJXaWR0aCA+IDApIHtcclxuXHRcdFx0Y3R4LnN0cm9rZSgpO1xyXG5cdFx0fVxyXG5cdH0sXHJcblxyXG5cdGRyYXc6IGZ1bmN0aW9uKCkge1xyXG5cdFx0dmFyIGN0eCA9IHRoaXMuX2NoYXJ0LmN0eDtcclxuXHRcdHZhciB2bSA9IHRoaXMuX3ZpZXc7XHJcblxyXG5cdFx0aWYgKHZtLm9wYWNpdHkgPT09IDApIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdHZhciB0b29sdGlwU2l6ZSA9IHtcclxuXHRcdFx0d2lkdGg6IHZtLndpZHRoLFxyXG5cdFx0XHRoZWlnaHQ6IHZtLmhlaWdodFxyXG5cdFx0fTtcclxuXHRcdHZhciBwdCA9IHtcclxuXHRcdFx0eDogdm0ueCxcclxuXHRcdFx0eTogdm0ueVxyXG5cdFx0fTtcclxuXHJcblx0XHQvLyBJRTExL0VkZ2UgZG9lcyBub3QgbGlrZSB2ZXJ5IHNtYWxsIG9wYWNpdGllcywgc28gc25hcCB0byAwXHJcblx0XHR2YXIgb3BhY2l0eSA9IE1hdGguYWJzKHZtLm9wYWNpdHkgPCAxZS0zKSA/IDAgOiB2bS5vcGFjaXR5O1xyXG5cclxuXHRcdC8vIFRydXRoeS9mYWxzZXkgdmFsdWUgZm9yIGVtcHR5IHRvb2x0aXBcclxuXHRcdHZhciBoYXNUb29sdGlwQ29udGVudCA9IHZtLnRpdGxlLmxlbmd0aCB8fCB2bS5iZWZvcmVCb2R5Lmxlbmd0aCB8fCB2bS5ib2R5Lmxlbmd0aCB8fCB2bS5hZnRlckJvZHkubGVuZ3RoIHx8IHZtLmZvb3Rlci5sZW5ndGg7XHJcblxyXG5cdFx0aWYgKHRoaXMuX29wdGlvbnMuZW5hYmxlZCAmJiBoYXNUb29sdGlwQ29udGVudCkge1xyXG5cdFx0XHRjdHguc2F2ZSgpO1xyXG5cdFx0XHRjdHguZ2xvYmFsQWxwaGEgPSBvcGFjaXR5O1xyXG5cclxuXHRcdFx0Ly8gRHJhdyBCYWNrZ3JvdW5kXHJcblx0XHRcdHRoaXMuZHJhd0JhY2tncm91bmQocHQsIHZtLCBjdHgsIHRvb2x0aXBTaXplKTtcclxuXHJcblx0XHRcdC8vIERyYXcgVGl0bGUsIEJvZHksIGFuZCBGb290ZXJcclxuXHRcdFx0cHQueSArPSB2bS55UGFkZGluZztcclxuXHJcblx0XHRcdGhlbHBlcnMkMS5ydGwub3ZlcnJpZGVUZXh0RGlyZWN0aW9uKGN0eCwgdm0udGV4dERpcmVjdGlvbik7XHJcblxyXG5cdFx0XHQvLyBUaXRsZXNcclxuXHRcdFx0dGhpcy5kcmF3VGl0bGUocHQsIHZtLCBjdHgpO1xyXG5cclxuXHRcdFx0Ly8gQm9keVxyXG5cdFx0XHR0aGlzLmRyYXdCb2R5KHB0LCB2bSwgY3R4KTtcclxuXHJcblx0XHRcdC8vIEZvb3RlclxyXG5cdFx0XHR0aGlzLmRyYXdGb290ZXIocHQsIHZtLCBjdHgpO1xyXG5cclxuXHRcdFx0aGVscGVycyQxLnJ0bC5yZXN0b3JlVGV4dERpcmVjdGlvbihjdHgsIHZtLnRleHREaXJlY3Rpb24pO1xyXG5cclxuXHRcdFx0Y3R4LnJlc3RvcmUoKTtcclxuXHRcdH1cclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBIYW5kbGUgYW4gZXZlbnRcclxuXHQgKiBAcHJpdmF0ZVxyXG5cdCAqIEBwYXJhbSB7SUV2ZW50fSBldmVudCAtIFRoZSBldmVudCB0byBoYW5kbGVcclxuXHQgKiBAcmV0dXJucyB7Ym9vbGVhbn0gdHJ1ZSBpZiB0aGUgdG9vbHRpcCBjaGFuZ2VkXHJcblx0ICovXHJcblx0aGFuZGxlRXZlbnQ6IGZ1bmN0aW9uKGUpIHtcclxuXHRcdHZhciBtZSA9IHRoaXM7XHJcblx0XHR2YXIgb3B0aW9ucyA9IG1lLl9vcHRpb25zO1xyXG5cdFx0dmFyIGNoYW5nZWQgPSBmYWxzZTtcclxuXHJcblx0XHRtZS5fbGFzdEFjdGl2ZSA9IG1lLl9sYXN0QWN0aXZlIHx8IFtdO1xyXG5cclxuXHRcdC8vIEZpbmQgQWN0aXZlIEVsZW1lbnRzIGZvciB0b29sdGlwc1xyXG5cdFx0aWYgKGUudHlwZSA9PT0gJ21vdXNlb3V0Jykge1xyXG5cdFx0XHRtZS5fYWN0aXZlID0gW107XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRtZS5fYWN0aXZlID0gbWUuX2NoYXJ0LmdldEVsZW1lbnRzQXRFdmVudEZvck1vZGUoZSwgb3B0aW9ucy5tb2RlLCBvcHRpb25zKTtcclxuXHRcdFx0aWYgKG9wdGlvbnMucmV2ZXJzZSkge1xyXG5cdFx0XHRcdG1lLl9hY3RpdmUucmV2ZXJzZSgpO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gUmVtZW1iZXIgTGFzdCBBY3RpdmVzXHJcblx0XHRjaGFuZ2VkID0gIWhlbHBlcnMkMS5hcnJheUVxdWFscyhtZS5fYWN0aXZlLCBtZS5fbGFzdEFjdGl2ZSk7XHJcblxyXG5cdFx0Ly8gT25seSBoYW5kbGUgdGFyZ2V0IGV2ZW50IG9uIHRvb2x0aXAgY2hhbmdlXHJcblx0XHRpZiAoY2hhbmdlZCkge1xyXG5cdFx0XHRtZS5fbGFzdEFjdGl2ZSA9IG1lLl9hY3RpdmU7XHJcblxyXG5cdFx0XHRpZiAob3B0aW9ucy5lbmFibGVkIHx8IG9wdGlvbnMuY3VzdG9tKSB7XHJcblx0XHRcdFx0bWUuX2V2ZW50UG9zaXRpb24gPSB7XHJcblx0XHRcdFx0XHR4OiBlLngsXHJcblx0XHRcdFx0XHR5OiBlLnlcclxuXHRcdFx0XHR9O1xyXG5cclxuXHRcdFx0XHRtZS51cGRhdGUodHJ1ZSk7XHJcblx0XHRcdFx0bWUucGl2b3QoKTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiBjaGFuZ2VkO1xyXG5cdH1cclxufSk7XHJcblxyXG4vKipcclxuICogQG5hbWVzcGFjZSBDaGFydC5Ub29sdGlwLnBvc2l0aW9uZXJzXHJcbiAqL1xyXG52YXIgcG9zaXRpb25lcnNfMSA9IHBvc2l0aW9uZXJzO1xyXG5cclxudmFyIGNvcmVfdG9vbHRpcCA9IGV4cG9ydHMkNDtcbmNvcmVfdG9vbHRpcC5wb3NpdGlvbmVycyA9IHBvc2l0aW9uZXJzXzE7XG5cbnZhciB2YWx1ZU9yRGVmYXVsdCQ5ID0gaGVscGVycyQxLnZhbHVlT3JEZWZhdWx0O1xyXG5cclxuY29yZV9kZWZhdWx0cy5fc2V0KCdnbG9iYWwnLCB7XHJcblx0ZWxlbWVudHM6IHt9LFxyXG5cdGV2ZW50czogW1xyXG5cdFx0J21vdXNlbW92ZScsXHJcblx0XHQnbW91c2VvdXQnLFxyXG5cdFx0J2NsaWNrJyxcclxuXHRcdCd0b3VjaHN0YXJ0JyxcclxuXHRcdCd0b3VjaG1vdmUnXHJcblx0XSxcclxuXHRob3Zlcjoge1xyXG5cdFx0b25Ib3ZlcjogbnVsbCxcclxuXHRcdG1vZGU6ICduZWFyZXN0JyxcclxuXHRcdGludGVyc2VjdDogdHJ1ZSxcclxuXHRcdGFuaW1hdGlvbkR1cmF0aW9uOiA0MDBcclxuXHR9LFxyXG5cdG9uQ2xpY2s6IG51bGwsXHJcblx0bWFpbnRhaW5Bc3BlY3RSYXRpbzogdHJ1ZSxcclxuXHRyZXNwb25zaXZlOiB0cnVlLFxyXG5cdHJlc3BvbnNpdmVBbmltYXRpb25EdXJhdGlvbjogMFxyXG59KTtcclxuXHJcbi8qKlxyXG4gKiBSZWN1cnNpdmVseSBtZXJnZSB0aGUgZ2l2ZW4gY29uZmlnIG9iamVjdHMgcmVwcmVzZW50aW5nIHRoZSBgc2NhbGVzYCBvcHRpb25cclxuICogYnkgaW5jb3Jwb3JhdGluZyBzY2FsZSBkZWZhdWx0cyBpbiBgeEF4ZXNgIGFuZCBgeUF4ZXNgIGFycmF5IGl0ZW1zLCB0aGVuXHJcbiAqIHJldHVybnMgYSBkZWVwIGNvcHkgb2YgdGhlIHJlc3VsdCwgdGh1cyBkb2Vzbid0IGFsdGVyIGlucHV0cy5cclxuICovXHJcbmZ1bmN0aW9uIG1lcmdlU2NhbGVDb25maWcoLyogY29uZmlnIG9iamVjdHMgLi4uICovKSB7XHJcblx0cmV0dXJuIGhlbHBlcnMkMS5tZXJnZShPYmplY3QuY3JlYXRlKG51bGwpLCBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cyksIHtcclxuXHRcdG1lcmdlcjogZnVuY3Rpb24oa2V5LCB0YXJnZXQsIHNvdXJjZSwgb3B0aW9ucykge1xyXG5cdFx0XHRpZiAoa2V5ID09PSAneEF4ZXMnIHx8IGtleSA9PT0gJ3lBeGVzJykge1xyXG5cdFx0XHRcdHZhciBzbGVuID0gc291cmNlW2tleV0ubGVuZ3RoO1xyXG5cdFx0XHRcdHZhciBpLCB0eXBlLCBzY2FsZTtcclxuXHJcblx0XHRcdFx0aWYgKCF0YXJnZXRba2V5XSkge1xyXG5cdFx0XHRcdFx0dGFyZ2V0W2tleV0gPSBbXTtcclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdGZvciAoaSA9IDA7IGkgPCBzbGVuOyArK2kpIHtcclxuXHRcdFx0XHRcdHNjYWxlID0gc291cmNlW2tleV1baV07XHJcblx0XHRcdFx0XHR0eXBlID0gdmFsdWVPckRlZmF1bHQkOShzY2FsZS50eXBlLCBrZXkgPT09ICd4QXhlcycgPyAnY2F0ZWdvcnknIDogJ2xpbmVhcicpO1xyXG5cclxuXHRcdFx0XHRcdGlmIChpID49IHRhcmdldFtrZXldLmxlbmd0aCkge1xyXG5cdFx0XHRcdFx0XHR0YXJnZXRba2V5XS5wdXNoKHt9KTtcclxuXHRcdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0XHRpZiAoIXRhcmdldFtrZXldW2ldLnR5cGUgfHwgKHNjYWxlLnR5cGUgJiYgc2NhbGUudHlwZSAhPT0gdGFyZ2V0W2tleV1baV0udHlwZSkpIHtcclxuXHRcdFx0XHRcdFx0Ly8gbmV3L3VudHlwZWQgc2NhbGUgb3IgdHlwZSBjaGFuZ2VkOiBsZXQncyBhcHBseSB0aGUgbmV3IGRlZmF1bHRzXHJcblx0XHRcdFx0XHRcdC8vIHRoZW4gbWVyZ2Ugc291cmNlIHNjYWxlIHRvIGNvcnJlY3RseSBvdmVyd3JpdGUgdGhlIGRlZmF1bHRzLlxyXG5cdFx0XHRcdFx0XHRoZWxwZXJzJDEubWVyZ2UodGFyZ2V0W2tleV1baV0sIFtjb3JlX3NjYWxlU2VydmljZS5nZXRTY2FsZURlZmF1bHRzKHR5cGUpLCBzY2FsZV0pO1xyXG5cdFx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdFx0Ly8gc2NhbGVzIHR5cGUgYXJlIHRoZSBzYW1lXHJcblx0XHRcdFx0XHRcdGhlbHBlcnMkMS5tZXJnZSh0YXJnZXRba2V5XVtpXSwgc2NhbGUpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRoZWxwZXJzJDEuX21lcmdlcihrZXksIHRhcmdldCwgc291cmNlLCBvcHRpb25zKTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdH0pO1xyXG59XHJcblxyXG4vKipcclxuICogUmVjdXJzaXZlbHkgbWVyZ2UgdGhlIGdpdmVuIGNvbmZpZyBvYmplY3RzIGFzIHRoZSByb290IG9wdGlvbnMgYnkgaGFuZGxpbmdcclxuICogZGVmYXVsdCBzY2FsZSBvcHRpb25zIGZvciB0aGUgYHNjYWxlc2AgYW5kIGBzY2FsZWAgcHJvcGVydGllcywgdGhlbiByZXR1cm5zXHJcbiAqIGEgZGVlcCBjb3B5IG9mIHRoZSByZXN1bHQsIHRodXMgZG9lc24ndCBhbHRlciBpbnB1dHMuXHJcbiAqL1xyXG5mdW5jdGlvbiBtZXJnZUNvbmZpZygvKiBjb25maWcgb2JqZWN0cyAuLi4gKi8pIHtcclxuXHRyZXR1cm4gaGVscGVycyQxLm1lcmdlKE9iamVjdC5jcmVhdGUobnVsbCksIFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzKSwge1xyXG5cdFx0bWVyZ2VyOiBmdW5jdGlvbihrZXksIHRhcmdldCwgc291cmNlLCBvcHRpb25zKSB7XHJcblx0XHRcdHZhciB0dmFsID0gdGFyZ2V0W2tleV0gfHwgT2JqZWN0LmNyZWF0ZShudWxsKTtcclxuXHRcdFx0dmFyIHN2YWwgPSBzb3VyY2Vba2V5XTtcclxuXHJcblx0XHRcdGlmIChrZXkgPT09ICdzY2FsZXMnKSB7XHJcblx0XHRcdFx0Ly8gc2NhbGUgY29uZmlnIG1lcmdpbmcgaXMgY29tcGxleC4gQWRkIG91ciBvd24gZnVuY3Rpb24gaGVyZSBmb3IgdGhhdFxyXG5cdFx0XHRcdHRhcmdldFtrZXldID0gbWVyZ2VTY2FsZUNvbmZpZyh0dmFsLCBzdmFsKTtcclxuXHRcdFx0fSBlbHNlIGlmIChrZXkgPT09ICdzY2FsZScpIHtcclxuXHRcdFx0XHQvLyB1c2VkIGluIHBvbGFyIGFyZWEgJiByYWRhciBjaGFydHMgc2luY2UgdGhlcmUgaXMgb25seSBvbmUgc2NhbGVcclxuXHRcdFx0XHR0YXJnZXRba2V5XSA9IGhlbHBlcnMkMS5tZXJnZSh0dmFsLCBbY29yZV9zY2FsZVNlcnZpY2UuZ2V0U2NhbGVEZWZhdWx0cyhzdmFsLnR5cGUpLCBzdmFsXSk7XHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0aGVscGVycyQxLl9tZXJnZXIoa2V5LCB0YXJnZXQsIHNvdXJjZSwgb3B0aW9ucyk7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHR9KTtcclxufVxyXG5cclxuZnVuY3Rpb24gaW5pdENvbmZpZyhjb25maWcpIHtcclxuXHRjb25maWcgPSBjb25maWcgfHwgT2JqZWN0LmNyZWF0ZShudWxsKTtcclxuXHJcblx0Ly8gRG8gTk9UIHVzZSBtZXJnZUNvbmZpZyBmb3IgdGhlIGRhdGEgb2JqZWN0IGJlY2F1c2UgdGhpcyBtZXRob2QgbWVyZ2VzIGFycmF5c1xyXG5cdC8vIGFuZCBzbyB3b3VsZCBjaGFuZ2UgcmVmZXJlbmNlcyB0byBsYWJlbHMgYW5kIGRhdGFzZXRzLCBwcmV2ZW50aW5nIGRhdGEgdXBkYXRlcy5cclxuXHR2YXIgZGF0YSA9IGNvbmZpZy5kYXRhID0gY29uZmlnLmRhdGEgfHwge307XHJcblx0ZGF0YS5kYXRhc2V0cyA9IGRhdGEuZGF0YXNldHMgfHwgW107XHJcblx0ZGF0YS5sYWJlbHMgPSBkYXRhLmxhYmVscyB8fCBbXTtcclxuXHJcblx0Y29uZmlnLm9wdGlvbnMgPSBtZXJnZUNvbmZpZyhcclxuXHRcdGNvcmVfZGVmYXVsdHMuZ2xvYmFsLFxyXG5cdFx0Y29yZV9kZWZhdWx0c1tjb25maWcudHlwZV0sXHJcblx0XHRjb25maWcub3B0aW9ucyB8fCB7fSk7XHJcblxyXG5cdHJldHVybiBjb25maWc7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHVwZGF0ZUNvbmZpZyhjaGFydCkge1xyXG5cdHZhciBuZXdPcHRpb25zID0gY2hhcnQub3B0aW9ucztcclxuXHJcblx0aGVscGVycyQxLmVhY2goY2hhcnQuc2NhbGVzLCBmdW5jdGlvbihzY2FsZSkge1xyXG5cdFx0Y29yZV9sYXlvdXRzLnJlbW92ZUJveChjaGFydCwgc2NhbGUpO1xyXG5cdH0pO1xyXG5cclxuXHRuZXdPcHRpb25zID0gbWVyZ2VDb25maWcoXHJcblx0XHRjb3JlX2RlZmF1bHRzLmdsb2JhbCxcclxuXHRcdGNvcmVfZGVmYXVsdHNbY2hhcnQuY29uZmlnLnR5cGVdLFxyXG5cdFx0bmV3T3B0aW9ucyk7XHJcblxyXG5cdGNoYXJ0Lm9wdGlvbnMgPSBjaGFydC5jb25maWcub3B0aW9ucyA9IG5ld09wdGlvbnM7XHJcblx0Y2hhcnQuZW5zdXJlU2NhbGVzSGF2ZUlEcygpO1xyXG5cdGNoYXJ0LmJ1aWxkT3JVcGRhdGVTY2FsZXMoKTtcclxuXHJcblx0Ly8gVG9vbHRpcFxyXG5cdGNoYXJ0LnRvb2x0aXAuX29wdGlvbnMgPSBuZXdPcHRpb25zLnRvb2x0aXBzO1xyXG5cdGNoYXJ0LnRvb2x0aXAuaW5pdGlhbGl6ZSgpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBuZXh0QXZhaWxhYmxlU2NhbGVJZChheGVzT3B0cywgcHJlZml4LCBpbmRleCkge1xyXG5cdHZhciBpZDtcclxuXHR2YXIgaGFzSWQgPSBmdW5jdGlvbihvYmopIHtcclxuXHRcdHJldHVybiBvYmouaWQgPT09IGlkO1xyXG5cdH07XHJcblxyXG5cdGRvIHtcclxuXHRcdGlkID0gcHJlZml4ICsgaW5kZXgrKztcclxuXHR9IHdoaWxlIChoZWxwZXJzJDEuZmluZEluZGV4KGF4ZXNPcHRzLCBoYXNJZCkgPj0gMCk7XHJcblxyXG5cdHJldHVybiBpZDtcclxufVxyXG5cclxuZnVuY3Rpb24gcG9zaXRpb25Jc0hvcml6b250YWwocG9zaXRpb24pIHtcclxuXHRyZXR1cm4gcG9zaXRpb24gPT09ICd0b3AnIHx8IHBvc2l0aW9uID09PSAnYm90dG9tJztcclxufVxyXG5cclxuZnVuY3Rpb24gY29tcGFyZTJMZXZlbChsMSwgbDIpIHtcclxuXHRyZXR1cm4gZnVuY3Rpb24oYSwgYikge1xyXG5cdFx0cmV0dXJuIGFbbDFdID09PSBiW2wxXVxyXG5cdFx0XHQ/IGFbbDJdIC0gYltsMl1cclxuXHRcdFx0OiBhW2wxXSAtIGJbbDFdO1xyXG5cdH07XHJcbn1cclxuXHJcbnZhciBDaGFydCA9IGZ1bmN0aW9uKGl0ZW0sIGNvbmZpZykge1xyXG5cdHRoaXMuY29uc3RydWN0KGl0ZW0sIGNvbmZpZyk7XHJcblx0cmV0dXJuIHRoaXM7XHJcbn07XHJcblxyXG5oZWxwZXJzJDEuZXh0ZW5kKENoYXJ0LnByb3RvdHlwZSwgLyoqIEBsZW5kcyBDaGFydCAqLyB7XHJcblx0LyoqXHJcblx0ICogQHByaXZhdGVcclxuXHQgKi9cclxuXHRjb25zdHJ1Y3Q6IGZ1bmN0aW9uKGl0ZW0sIGNvbmZpZykge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHJcblx0XHRjb25maWcgPSBpbml0Q29uZmlnKGNvbmZpZyk7XHJcblxyXG5cdFx0dmFyIGNvbnRleHQgPSBwbGF0Zm9ybS5hY3F1aXJlQ29udGV4dChpdGVtLCBjb25maWcpO1xyXG5cdFx0dmFyIGNhbnZhcyA9IGNvbnRleHQgJiYgY29udGV4dC5jYW52YXM7XHJcblx0XHR2YXIgaGVpZ2h0ID0gY2FudmFzICYmIGNhbnZhcy5oZWlnaHQ7XHJcblx0XHR2YXIgd2lkdGggPSBjYW52YXMgJiYgY2FudmFzLndpZHRoO1xyXG5cclxuXHRcdG1lLmlkID0gaGVscGVycyQxLnVpZCgpO1xyXG5cdFx0bWUuY3R4ID0gY29udGV4dDtcclxuXHRcdG1lLmNhbnZhcyA9IGNhbnZhcztcclxuXHRcdG1lLmNvbmZpZyA9IGNvbmZpZztcclxuXHRcdG1lLndpZHRoID0gd2lkdGg7XHJcblx0XHRtZS5oZWlnaHQgPSBoZWlnaHQ7XHJcblx0XHRtZS5hc3BlY3RSYXRpbyA9IGhlaWdodCA/IHdpZHRoIC8gaGVpZ2h0IDogbnVsbDtcclxuXHRcdG1lLm9wdGlvbnMgPSBjb25maWcub3B0aW9ucztcclxuXHRcdG1lLl9idWZmZXJlZFJlbmRlciA9IGZhbHNlO1xyXG5cdFx0bWUuX2xheWVycyA9IFtdO1xyXG5cclxuXHRcdC8qKlxyXG5cdFx0ICogUHJvdmlkZWQgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHksIENoYXJ0IGFuZCBDaGFydC5Db250cm9sbGVyIGhhdmUgYmVlbiBtZXJnZWQsXHJcblx0XHQgKiB0aGUgXCJpbnN0YW5jZVwiIHN0aWxsIG5lZWQgdG8gYmUgZGVmaW5lZCBzaW5jZSBpdCBtaWdodCBiZSBjYWxsZWQgZnJvbSBwbHVnaW5zLlxyXG5cdFx0ICogQHByb3AgQ2hhcnQjY2hhcnRcclxuXHRcdCAqIEBkZXByZWNhdGVkIHNpbmNlIHZlcnNpb24gMi42LjBcclxuXHRcdCAqIEB0b2RvIHJlbW92ZSBhdCB2ZXJzaW9uIDNcclxuXHRcdCAqIEBwcml2YXRlXHJcblx0XHQgKi9cclxuXHRcdG1lLmNoYXJ0ID0gbWU7XHJcblx0XHRtZS5jb250cm9sbGVyID0gbWU7IC8vIGNoYXJ0LmNoYXJ0LmNvbnRyb2xsZXIgI2luY2VwdGlvblxyXG5cclxuXHRcdC8vIEFkZCB0aGUgY2hhcnQgaW5zdGFuY2UgdG8gdGhlIGdsb2JhbCBuYW1lc3BhY2VcclxuXHRcdENoYXJ0Lmluc3RhbmNlc1ttZS5pZF0gPSBtZTtcclxuXHJcblx0XHQvLyBEZWZpbmUgYWxpYXMgdG8gdGhlIGNvbmZpZyBkYXRhOiBgY2hhcnQuZGF0YSA9PT0gY2hhcnQuY29uZmlnLmRhdGFgXHJcblx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkobWUsICdkYXRhJywge1xyXG5cdFx0XHRnZXQ6IGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdHJldHVybiBtZS5jb25maWcuZGF0YTtcclxuXHRcdFx0fSxcclxuXHRcdFx0c2V0OiBmdW5jdGlvbih2YWx1ZSkge1xyXG5cdFx0XHRcdG1lLmNvbmZpZy5kYXRhID0gdmFsdWU7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cclxuXHRcdGlmICghY29udGV4dCB8fCAhY2FudmFzKSB7XHJcblx0XHRcdC8vIFRoZSBnaXZlbiBpdGVtIGlzIG5vdCBhIGNvbXBhdGlibGUgY29udGV4dDJkIGVsZW1lbnQsIGxldCdzIHJldHVybiBiZWZvcmUgZmluYWxpemluZ1xyXG5cdFx0XHQvLyB0aGUgY2hhcnQgaW5pdGlhbGl6YXRpb24gYnV0IGFmdGVyIHNldHRpbmcgYmFzaWMgY2hhcnQgLyBjb250cm9sbGVyIHByb3BlcnRpZXMgdGhhdFxyXG5cdFx0XHQvLyBjYW4gaGVscCB0byBmaWd1cmUgb3V0IHRoYXQgdGhlIGNoYXJ0IGlzIG5vdCB2YWxpZCAoZS5nIGNoYXJ0LmNhbnZhcyAhPT0gbnVsbCk7XHJcblx0XHRcdC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9jaGFydGpzL0NoYXJ0LmpzL2lzc3Vlcy8yODA3XHJcblx0XHRcdGNvbnNvbGUuZXJyb3IoXCJGYWlsZWQgdG8gY3JlYXRlIGNoYXJ0OiBjYW4ndCBhY3F1aXJlIGNvbnRleHQgZnJvbSB0aGUgZ2l2ZW4gaXRlbVwiKTtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdG1lLmluaXRpYWxpemUoKTtcclxuXHRcdG1lLnVwZGF0ZSgpO1xyXG5cdH0sXHJcblxyXG5cdC8qKlxyXG5cdCAqIEBwcml2YXRlXHJcblx0ICovXHJcblx0aW5pdGlhbGl6ZTogZnVuY3Rpb24oKSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cclxuXHRcdC8vIEJlZm9yZSBpbml0IHBsdWdpbiBub3RpZmljYXRpb25cclxuXHRcdGNvcmVfcGx1Z2lucy5ub3RpZnkobWUsICdiZWZvcmVJbml0Jyk7XHJcblxyXG5cdFx0aGVscGVycyQxLnJldGluYVNjYWxlKG1lLCBtZS5vcHRpb25zLmRldmljZVBpeGVsUmF0aW8pO1xyXG5cclxuXHRcdG1lLmJpbmRFdmVudHMoKTtcclxuXHJcblx0XHRpZiAobWUub3B0aW9ucy5yZXNwb25zaXZlKSB7XHJcblx0XHRcdC8vIEluaXRpYWwgcmVzaXplIGJlZm9yZSBjaGFydCBkcmF3cyAobXVzdCBiZSBzaWxlbnQgdG8gcHJlc2VydmUgaW5pdGlhbCBhbmltYXRpb25zKS5cclxuXHRcdFx0bWUucmVzaXplKHRydWUpO1xyXG5cdFx0fVxyXG5cclxuXHRcdG1lLmluaXRUb29sVGlwKCk7XHJcblxyXG5cdFx0Ly8gQWZ0ZXIgaW5pdCBwbHVnaW4gbm90aWZpY2F0aW9uXHJcblx0XHRjb3JlX3BsdWdpbnMubm90aWZ5KG1lLCAnYWZ0ZXJJbml0Jyk7XHJcblxyXG5cdFx0cmV0dXJuIG1lO1xyXG5cdH0sXHJcblxyXG5cdGNsZWFyOiBmdW5jdGlvbigpIHtcclxuXHRcdGhlbHBlcnMkMS5jYW52YXMuY2xlYXIodGhpcyk7XHJcblx0XHRyZXR1cm4gdGhpcztcclxuXHR9LFxyXG5cclxuXHRzdG9wOiBmdW5jdGlvbigpIHtcclxuXHRcdC8vIFN0b3BzIGFueSBjdXJyZW50IGFuaW1hdGlvbiBsb29wIG9jY3VycmluZ1xyXG5cdFx0Y29yZV9hbmltYXRpb25zLmNhbmNlbEFuaW1hdGlvbih0aGlzKTtcclxuXHRcdHJldHVybiB0aGlzO1xyXG5cdH0sXHJcblxyXG5cdHJlc2l6ZTogZnVuY3Rpb24oc2lsZW50KSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0dmFyIG9wdGlvbnMgPSBtZS5vcHRpb25zO1xyXG5cdFx0dmFyIGNhbnZhcyA9IG1lLmNhbnZhcztcclxuXHRcdHZhciBhc3BlY3RSYXRpbyA9IChvcHRpb25zLm1haW50YWluQXNwZWN0UmF0aW8gJiYgbWUuYXNwZWN0UmF0aW8pIHx8IG51bGw7XHJcblxyXG5cdFx0Ly8gdGhlIGNhbnZhcyByZW5kZXIgd2lkdGggYW5kIGhlaWdodCB3aWxsIGJlIGNhc3RlZCB0byBpbnRlZ2VycyBzbyBtYWtlIHN1cmUgdGhhdFxyXG5cdFx0Ly8gdGhlIGNhbnZhcyBkaXNwbGF5IHN0eWxlIHVzZXMgdGhlIHNhbWUgaW50ZWdlciB2YWx1ZXMgdG8gYXZvaWQgYmx1cnJpbmcgZWZmZWN0LlxyXG5cclxuXHRcdC8vIFNldCB0byAwIGluc3RlYWQgb2YgY2FudmFzLnNpemUgYmVjYXVzZSB0aGUgc2l6ZSBkZWZhdWx0cyB0byAzMDB4MTUwIGlmIHRoZSBlbGVtZW50IGlzIGNvbGxhcHNlZFxyXG5cdFx0dmFyIG5ld1dpZHRoID0gTWF0aC5tYXgoMCwgTWF0aC5mbG9vcihoZWxwZXJzJDEuZ2V0TWF4aW11bVdpZHRoKGNhbnZhcykpKTtcclxuXHRcdHZhciBuZXdIZWlnaHQgPSBNYXRoLm1heCgwLCBNYXRoLmZsb29yKGFzcGVjdFJhdGlvID8gbmV3V2lkdGggLyBhc3BlY3RSYXRpbyA6IGhlbHBlcnMkMS5nZXRNYXhpbXVtSGVpZ2h0KGNhbnZhcykpKTtcclxuXHJcblx0XHRpZiAobWUud2lkdGggPT09IG5ld1dpZHRoICYmIG1lLmhlaWdodCA9PT0gbmV3SGVpZ2h0KSB7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHJcblx0XHRjYW52YXMud2lkdGggPSBtZS53aWR0aCA9IG5ld1dpZHRoO1xyXG5cdFx0Y2FudmFzLmhlaWdodCA9IG1lLmhlaWdodCA9IG5ld0hlaWdodDtcclxuXHRcdGNhbnZhcy5zdHlsZS53aWR0aCA9IG5ld1dpZHRoICsgJ3B4JztcclxuXHRcdGNhbnZhcy5zdHlsZS5oZWlnaHQgPSBuZXdIZWlnaHQgKyAncHgnO1xyXG5cclxuXHRcdGhlbHBlcnMkMS5yZXRpbmFTY2FsZShtZSwgb3B0aW9ucy5kZXZpY2VQaXhlbFJhdGlvKTtcclxuXHJcblx0XHRpZiAoIXNpbGVudCkge1xyXG5cdFx0XHQvLyBOb3RpZnkgYW55IHBsdWdpbnMgYWJvdXQgdGhlIHJlc2l6ZVxyXG5cdFx0XHR2YXIgbmV3U2l6ZSA9IHt3aWR0aDogbmV3V2lkdGgsIGhlaWdodDogbmV3SGVpZ2h0fTtcclxuXHRcdFx0Y29yZV9wbHVnaW5zLm5vdGlmeShtZSwgJ3Jlc2l6ZScsIFtuZXdTaXplXSk7XHJcblxyXG5cdFx0XHQvLyBOb3RpZnkgb2YgcmVzaXplXHJcblx0XHRcdGlmIChvcHRpb25zLm9uUmVzaXplKSB7XHJcblx0XHRcdFx0b3B0aW9ucy5vblJlc2l6ZShtZSwgbmV3U2l6ZSk7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdG1lLnN0b3AoKTtcclxuXHRcdFx0bWUudXBkYXRlKHtcclxuXHRcdFx0XHRkdXJhdGlvbjogb3B0aW9ucy5yZXNwb25zaXZlQW5pbWF0aW9uRHVyYXRpb25cclxuXHRcdFx0fSk7XHJcblx0XHR9XHJcblx0fSxcclxuXHJcblx0ZW5zdXJlU2NhbGVzSGF2ZUlEczogZnVuY3Rpb24oKSB7XHJcblx0XHR2YXIgb3B0aW9ucyA9IHRoaXMub3B0aW9ucztcclxuXHRcdHZhciBzY2FsZXNPcHRpb25zID0gb3B0aW9ucy5zY2FsZXMgfHwge307XHJcblx0XHR2YXIgc2NhbGVPcHRpb25zID0gb3B0aW9ucy5zY2FsZTtcclxuXHJcblx0XHRoZWxwZXJzJDEuZWFjaChzY2FsZXNPcHRpb25zLnhBeGVzLCBmdW5jdGlvbih4QXhpc09wdGlvbnMsIGluZGV4KSB7XHJcblx0XHRcdGlmICgheEF4aXNPcHRpb25zLmlkKSB7XHJcblx0XHRcdFx0eEF4aXNPcHRpb25zLmlkID0gbmV4dEF2YWlsYWJsZVNjYWxlSWQoc2NhbGVzT3B0aW9ucy54QXhlcywgJ3gtYXhpcy0nLCBpbmRleCk7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cclxuXHRcdGhlbHBlcnMkMS5lYWNoKHNjYWxlc09wdGlvbnMueUF4ZXMsIGZ1bmN0aW9uKHlBeGlzT3B0aW9ucywgaW5kZXgpIHtcclxuXHRcdFx0aWYgKCF5QXhpc09wdGlvbnMuaWQpIHtcclxuXHRcdFx0XHR5QXhpc09wdGlvbnMuaWQgPSBuZXh0QXZhaWxhYmxlU2NhbGVJZChzY2FsZXNPcHRpb25zLnlBeGVzLCAneS1heGlzLScsIGluZGV4KTtcclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblxyXG5cdFx0aWYgKHNjYWxlT3B0aW9ucykge1xyXG5cdFx0XHRzY2FsZU9wdGlvbnMuaWQgPSBzY2FsZU9wdGlvbnMuaWQgfHwgJ3NjYWxlJztcclxuXHRcdH1cclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBCdWlsZHMgYSBtYXAgb2Ygc2NhbGUgSUQgdG8gc2NhbGUgb2JqZWN0IGZvciBmdXR1cmUgbG9va3VwLlxyXG5cdCAqL1xyXG5cdGJ1aWxkT3JVcGRhdGVTY2FsZXM6IGZ1bmN0aW9uKCkge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHRcdHZhciBvcHRpb25zID0gbWUub3B0aW9ucztcclxuXHRcdHZhciBzY2FsZXMgPSBtZS5zY2FsZXMgfHwge307XHJcblx0XHR2YXIgaXRlbXMgPSBbXTtcclxuXHRcdHZhciB1cGRhdGVkID0gT2JqZWN0LmtleXMoc2NhbGVzKS5yZWR1Y2UoZnVuY3Rpb24ob2JqLCBpZCkge1xyXG5cdFx0XHRvYmpbaWRdID0gZmFsc2U7XHJcblx0XHRcdHJldHVybiBvYmo7XHJcblx0XHR9LCB7fSk7XHJcblxyXG5cdFx0aWYgKG9wdGlvbnMuc2NhbGVzKSB7XHJcblx0XHRcdGl0ZW1zID0gaXRlbXMuY29uY2F0KFxyXG5cdFx0XHRcdChvcHRpb25zLnNjYWxlcy54QXhlcyB8fCBbXSkubWFwKGZ1bmN0aW9uKHhBeGlzT3B0aW9ucykge1xyXG5cdFx0XHRcdFx0cmV0dXJuIHtvcHRpb25zOiB4QXhpc09wdGlvbnMsIGR0eXBlOiAnY2F0ZWdvcnknLCBkcG9zaXRpb246ICdib3R0b20nfTtcclxuXHRcdFx0XHR9KSxcclxuXHRcdFx0XHQob3B0aW9ucy5zY2FsZXMueUF4ZXMgfHwgW10pLm1hcChmdW5jdGlvbih5QXhpc09wdGlvbnMpIHtcclxuXHRcdFx0XHRcdHJldHVybiB7b3B0aW9uczogeUF4aXNPcHRpb25zLCBkdHlwZTogJ2xpbmVhcicsIGRwb3NpdGlvbjogJ2xlZnQnfTtcclxuXHRcdFx0XHR9KVxyXG5cdFx0XHQpO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmIChvcHRpb25zLnNjYWxlKSB7XHJcblx0XHRcdGl0ZW1zLnB1c2goe1xyXG5cdFx0XHRcdG9wdGlvbnM6IG9wdGlvbnMuc2NhbGUsXHJcblx0XHRcdFx0ZHR5cGU6ICdyYWRpYWxMaW5lYXInLFxyXG5cdFx0XHRcdGlzRGVmYXVsdDogdHJ1ZSxcclxuXHRcdFx0XHRkcG9zaXRpb246ICdjaGFydEFyZWEnXHJcblx0XHRcdH0pO1xyXG5cdFx0fVxyXG5cclxuXHRcdGhlbHBlcnMkMS5lYWNoKGl0ZW1zLCBmdW5jdGlvbihpdGVtKSB7XHJcblx0XHRcdHZhciBzY2FsZU9wdGlvbnMgPSBpdGVtLm9wdGlvbnM7XHJcblx0XHRcdHZhciBpZCA9IHNjYWxlT3B0aW9ucy5pZDtcclxuXHRcdFx0dmFyIHNjYWxlVHlwZSA9IHZhbHVlT3JEZWZhdWx0JDkoc2NhbGVPcHRpb25zLnR5cGUsIGl0ZW0uZHR5cGUpO1xyXG5cclxuXHRcdFx0aWYgKHBvc2l0aW9uSXNIb3Jpem9udGFsKHNjYWxlT3B0aW9ucy5wb3NpdGlvbikgIT09IHBvc2l0aW9uSXNIb3Jpem9udGFsKGl0ZW0uZHBvc2l0aW9uKSkge1xyXG5cdFx0XHRcdHNjYWxlT3B0aW9ucy5wb3NpdGlvbiA9IGl0ZW0uZHBvc2l0aW9uO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHR1cGRhdGVkW2lkXSA9IHRydWU7XHJcblx0XHRcdHZhciBzY2FsZSA9IG51bGw7XHJcblx0XHRcdGlmIChpZCBpbiBzY2FsZXMgJiYgc2NhbGVzW2lkXS50eXBlID09PSBzY2FsZVR5cGUpIHtcclxuXHRcdFx0XHRzY2FsZSA9IHNjYWxlc1tpZF07XHJcblx0XHRcdFx0c2NhbGUub3B0aW9ucyA9IHNjYWxlT3B0aW9ucztcclxuXHRcdFx0XHRzY2FsZS5jdHggPSBtZS5jdHg7XHJcblx0XHRcdFx0c2NhbGUuY2hhcnQgPSBtZTtcclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHR2YXIgc2NhbGVDbGFzcyA9IGNvcmVfc2NhbGVTZXJ2aWNlLmdldFNjYWxlQ29uc3RydWN0b3Ioc2NhbGVUeXBlKTtcclxuXHRcdFx0XHRpZiAoIXNjYWxlQ2xhc3MpIHtcclxuXHRcdFx0XHRcdHJldHVybjtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0c2NhbGUgPSBuZXcgc2NhbGVDbGFzcyh7XHJcblx0XHRcdFx0XHRpZDogaWQsXHJcblx0XHRcdFx0XHR0eXBlOiBzY2FsZVR5cGUsXHJcblx0XHRcdFx0XHRvcHRpb25zOiBzY2FsZU9wdGlvbnMsXHJcblx0XHRcdFx0XHRjdHg6IG1lLmN0eCxcclxuXHRcdFx0XHRcdGNoYXJ0OiBtZVxyXG5cdFx0XHRcdH0pO1xyXG5cdFx0XHRcdHNjYWxlc1tzY2FsZS5pZF0gPSBzY2FsZTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0c2NhbGUubWVyZ2VUaWNrc09wdGlvbnMoKTtcclxuXHJcblx0XHRcdC8vIFRPRE8oU0IpOiBJIHRoaW5rIHdlIHNob3VsZCBiZSBhYmxlIHRvIHJlbW92ZSB0aGlzIGN1c3RvbSBjYXNlIChvcHRpb25zLnNjYWxlKVxyXG5cdFx0XHQvLyBhbmQgY29uc2lkZXIgaXQgYXMgYSByZWd1bGFyIHNjYWxlIHBhcnQgb2YgdGhlIFwic2NhbGVzXCJcIiBtYXAgb25seSEgVGhpcyB3b3VsZFxyXG5cdFx0XHQvLyBtYWtlIHRoZSBsb2dpYyBlYXNpZXIgYW5kIHJlbW92ZSBzb21lIHVzZWxlc3M/IGN1c3RvbSBjb2RlLlxyXG5cdFx0XHRpZiAoaXRlbS5pc0RlZmF1bHQpIHtcclxuXHRcdFx0XHRtZS5zY2FsZSA9IHNjYWxlO1xyXG5cdFx0XHR9XHJcblx0XHR9KTtcclxuXHRcdC8vIGNsZWFyIHVwIGRpc2NhcmRlZCBzY2FsZXNcclxuXHRcdGhlbHBlcnMkMS5lYWNoKHVwZGF0ZWQsIGZ1bmN0aW9uKGhhc1VwZGF0ZWQsIGlkKSB7XHJcblx0XHRcdGlmICghaGFzVXBkYXRlZCkge1xyXG5cdFx0XHRcdGRlbGV0ZSBzY2FsZXNbaWRdO1xyXG5cdFx0XHR9XHJcblx0XHR9KTtcclxuXHJcblx0XHRtZS5zY2FsZXMgPSBzY2FsZXM7XHJcblxyXG5cdFx0Y29yZV9zY2FsZVNlcnZpY2UuYWRkU2NhbGVzVG9MYXlvdXQodGhpcyk7XHJcblx0fSxcclxuXHJcblx0YnVpbGRPclVwZGF0ZUNvbnRyb2xsZXJzOiBmdW5jdGlvbigpIHtcclxuXHRcdHZhciBtZSA9IHRoaXM7XHJcblx0XHR2YXIgbmV3Q29udHJvbGxlcnMgPSBbXTtcclxuXHRcdHZhciBkYXRhc2V0cyA9IG1lLmRhdGEuZGF0YXNldHM7XHJcblx0XHR2YXIgaSwgaWxlbjtcclxuXHJcblx0XHRmb3IgKGkgPSAwLCBpbGVuID0gZGF0YXNldHMubGVuZ3RoOyBpIDwgaWxlbjsgaSsrKSB7XHJcblx0XHRcdHZhciBkYXRhc2V0ID0gZGF0YXNldHNbaV07XHJcblx0XHRcdHZhciBtZXRhID0gbWUuZ2V0RGF0YXNldE1ldGEoaSk7XHJcblx0XHRcdHZhciB0eXBlID0gZGF0YXNldC50eXBlIHx8IG1lLmNvbmZpZy50eXBlO1xyXG5cclxuXHRcdFx0aWYgKG1ldGEudHlwZSAmJiBtZXRhLnR5cGUgIT09IHR5cGUpIHtcclxuXHRcdFx0XHRtZS5kZXN0cm95RGF0YXNldE1ldGEoaSk7XHJcblx0XHRcdFx0bWV0YSA9IG1lLmdldERhdGFzZXRNZXRhKGkpO1xyXG5cdFx0XHR9XHJcblx0XHRcdG1ldGEudHlwZSA9IHR5cGU7XHJcblx0XHRcdG1ldGEub3JkZXIgPSBkYXRhc2V0Lm9yZGVyIHx8IDA7XHJcblx0XHRcdG1ldGEuaW5kZXggPSBpO1xyXG5cclxuXHRcdFx0aWYgKG1ldGEuY29udHJvbGxlcikge1xyXG5cdFx0XHRcdG1ldGEuY29udHJvbGxlci51cGRhdGVJbmRleChpKTtcclxuXHRcdFx0XHRtZXRhLmNvbnRyb2xsZXIubGlua1NjYWxlcygpO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdHZhciBDb250cm9sbGVyQ2xhc3MgPSBjb250cm9sbGVyc1ttZXRhLnR5cGVdO1xyXG5cdFx0XHRcdGlmIChDb250cm9sbGVyQ2xhc3MgPT09IHVuZGVmaW5lZCkge1xyXG5cdFx0XHRcdFx0dGhyb3cgbmV3IEVycm9yKCdcIicgKyBtZXRhLnR5cGUgKyAnXCIgaXMgbm90IGEgY2hhcnQgdHlwZS4nKTtcclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdG1ldGEuY29udHJvbGxlciA9IG5ldyBDb250cm9sbGVyQ2xhc3MobWUsIGkpO1xyXG5cdFx0XHRcdG5ld0NvbnRyb2xsZXJzLnB1c2gobWV0YS5jb250cm9sbGVyKTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiBuZXdDb250cm9sbGVycztcclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBSZXNldCB0aGUgZWxlbWVudHMgb2YgYWxsIGRhdGFzZXRzXHJcblx0ICogQHByaXZhdGVcclxuXHQgKi9cclxuXHRyZXNldEVsZW1lbnRzOiBmdW5jdGlvbigpIHtcclxuXHRcdHZhciBtZSA9IHRoaXM7XHJcblx0XHRoZWxwZXJzJDEuZWFjaChtZS5kYXRhLmRhdGFzZXRzLCBmdW5jdGlvbihkYXRhc2V0LCBkYXRhc2V0SW5kZXgpIHtcclxuXHRcdFx0bWUuZ2V0RGF0YXNldE1ldGEoZGF0YXNldEluZGV4KS5jb250cm9sbGVyLnJlc2V0KCk7XHJcblx0XHR9LCBtZSk7XHJcblx0fSxcclxuXHJcblx0LyoqXHJcblx0KiBSZXNldHMgdGhlIGNoYXJ0IGJhY2sgdG8gaXQncyBzdGF0ZSBiZWZvcmUgdGhlIGluaXRpYWwgYW5pbWF0aW9uXHJcblx0Ki9cclxuXHRyZXNldDogZnVuY3Rpb24oKSB7XHJcblx0XHR0aGlzLnJlc2V0RWxlbWVudHMoKTtcclxuXHRcdHRoaXMudG9vbHRpcC5pbml0aWFsaXplKCk7XHJcblx0fSxcclxuXHJcblx0dXBkYXRlOiBmdW5jdGlvbihjb25maWcpIHtcclxuXHRcdHZhciBtZSA9IHRoaXM7XHJcblx0XHR2YXIgaSwgaWxlbjtcclxuXHJcblx0XHRpZiAoIWNvbmZpZyB8fCB0eXBlb2YgY29uZmlnICE9PSAnb2JqZWN0Jykge1xyXG5cdFx0XHQvLyBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eVxyXG5cdFx0XHRjb25maWcgPSB7XHJcblx0XHRcdFx0ZHVyYXRpb246IGNvbmZpZyxcclxuXHRcdFx0XHRsYXp5OiBhcmd1bWVudHNbMV1cclxuXHRcdFx0fTtcclxuXHRcdH1cclxuXHJcblx0XHR1cGRhdGVDb25maWcobWUpO1xyXG5cclxuXHRcdC8vIHBsdWdpbnMgb3B0aW9ucyByZWZlcmVuY2VzIG1pZ2h0IGhhdmUgY2hhbmdlLCBsZXQncyBpbnZhbGlkYXRlIHRoZSBjYWNoZVxyXG5cdFx0Ly8gaHR0cHM6Ly9naXRodWIuY29tL2NoYXJ0anMvQ2hhcnQuanMvaXNzdWVzLzUxMTEjaXNzdWVjb21tZW50LTM1NTkzNDE2N1xyXG5cdFx0Y29yZV9wbHVnaW5zLl9pbnZhbGlkYXRlKG1lKTtcclxuXHJcblx0XHRpZiAoY29yZV9wbHVnaW5zLm5vdGlmeShtZSwgJ2JlZm9yZVVwZGF0ZScpID09PSBmYWxzZSkge1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gSW4gY2FzZSB0aGUgZW50aXJlIGRhdGEgb2JqZWN0IGNoYW5nZWRcclxuXHRcdG1lLnRvb2x0aXAuX2RhdGEgPSBtZS5kYXRhO1xyXG5cclxuXHRcdC8vIE1ha2Ugc3VyZSBkYXRhc2V0IGNvbnRyb2xsZXJzIGFyZSB1cGRhdGVkIGFuZCBuZXcgY29udHJvbGxlcnMgYXJlIHJlc2V0XHJcblx0XHR2YXIgbmV3Q29udHJvbGxlcnMgPSBtZS5idWlsZE9yVXBkYXRlQ29udHJvbGxlcnMoKTtcclxuXHJcblx0XHQvLyBNYWtlIHN1cmUgYWxsIGRhdGFzZXQgY29udHJvbGxlcnMgaGF2ZSBjb3JyZWN0IG1ldGEgZGF0YSBjb3VudHNcclxuXHRcdGZvciAoaSA9IDAsIGlsZW4gPSBtZS5kYXRhLmRhdGFzZXRzLmxlbmd0aDsgaSA8IGlsZW47IGkrKykge1xyXG5cdFx0XHRtZS5nZXREYXRhc2V0TWV0YShpKS5jb250cm9sbGVyLmJ1aWxkT3JVcGRhdGVFbGVtZW50cygpO1xyXG5cdFx0fVxyXG5cclxuXHRcdG1lLnVwZGF0ZUxheW91dCgpO1xyXG5cclxuXHRcdC8vIENhbiBvbmx5IHJlc2V0IHRoZSBuZXcgY29udHJvbGxlcnMgYWZ0ZXIgdGhlIHNjYWxlcyBoYXZlIGJlZW4gdXBkYXRlZFxyXG5cdFx0aWYgKG1lLm9wdGlvbnMuYW5pbWF0aW9uICYmIG1lLm9wdGlvbnMuYW5pbWF0aW9uLmR1cmF0aW9uKSB7XHJcblx0XHRcdGhlbHBlcnMkMS5lYWNoKG5ld0NvbnRyb2xsZXJzLCBmdW5jdGlvbihjb250cm9sbGVyKSB7XHJcblx0XHRcdFx0Y29udHJvbGxlci5yZXNldCgpO1xyXG5cdFx0XHR9KTtcclxuXHRcdH1cclxuXHJcblx0XHRtZS51cGRhdGVEYXRhc2V0cygpO1xyXG5cclxuXHRcdC8vIE5lZWQgdG8gcmVzZXQgdG9vbHRpcCBpbiBjYXNlIGl0IGlzIGRpc3BsYXllZCB3aXRoIGVsZW1lbnRzIHRoYXQgYXJlIHJlbW92ZWRcclxuXHRcdC8vIGFmdGVyIHVwZGF0ZS5cclxuXHRcdG1lLnRvb2x0aXAuaW5pdGlhbGl6ZSgpO1xyXG5cclxuXHRcdC8vIExhc3QgYWN0aXZlIGNvbnRhaW5zIGl0ZW1zIHRoYXQgd2VyZSBwcmV2aW91c2x5IGluIHRoZSB0b29sdGlwLlxyXG5cdFx0Ly8gV2hlbiB3ZSByZXNldCB0aGUgdG9vbHRpcCwgd2UgbmVlZCB0byBjbGVhciBpdFxyXG5cdFx0bWUubGFzdEFjdGl2ZSA9IFtdO1xyXG5cclxuXHRcdC8vIERvIHRoaXMgYmVmb3JlIHJlbmRlciBzbyB0aGF0IGFueSBwbHVnaW5zIHRoYXQgbmVlZCBmaW5hbCBzY2FsZSB1cGRhdGVzIGNhbiB1c2UgaXRcclxuXHRcdGNvcmVfcGx1Z2lucy5ub3RpZnkobWUsICdhZnRlclVwZGF0ZScpO1xyXG5cclxuXHRcdG1lLl9sYXllcnMuc29ydChjb21wYXJlMkxldmVsKCd6JywgJ19pZHgnKSk7XHJcblxyXG5cdFx0aWYgKG1lLl9idWZmZXJlZFJlbmRlcikge1xyXG5cdFx0XHRtZS5fYnVmZmVyZWRSZXF1ZXN0ID0ge1xyXG5cdFx0XHRcdGR1cmF0aW9uOiBjb25maWcuZHVyYXRpb24sXHJcblx0XHRcdFx0ZWFzaW5nOiBjb25maWcuZWFzaW5nLFxyXG5cdFx0XHRcdGxhenk6IGNvbmZpZy5sYXp5XHJcblx0XHRcdH07XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRtZS5yZW5kZXIoY29uZmlnKTtcclxuXHRcdH1cclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBVcGRhdGVzIHRoZSBjaGFydCBsYXlvdXQgdW5sZXNzIGEgcGx1Z2luIHJldHVybnMgYGZhbHNlYCB0byB0aGUgYGJlZm9yZUxheW91dGBcclxuXHQgKiBob29rLCBpbiB3aGljaCBjYXNlLCBwbHVnaW5zIHdpbGwgbm90IGJlIGNhbGxlZCBvbiBgYWZ0ZXJMYXlvdXRgLlxyXG5cdCAqIEBwcml2YXRlXHJcblx0ICovXHJcblx0dXBkYXRlTGF5b3V0OiBmdW5jdGlvbigpIHtcclxuXHRcdHZhciBtZSA9IHRoaXM7XHJcblxyXG5cdFx0aWYgKGNvcmVfcGx1Z2lucy5ub3RpZnkobWUsICdiZWZvcmVMYXlvdXQnKSA9PT0gZmFsc2UpIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdGNvcmVfbGF5b3V0cy51cGRhdGUodGhpcywgdGhpcy53aWR0aCwgdGhpcy5oZWlnaHQpO1xyXG5cclxuXHRcdG1lLl9sYXllcnMgPSBbXTtcclxuXHRcdGhlbHBlcnMkMS5lYWNoKG1lLmJveGVzLCBmdW5jdGlvbihib3gpIHtcclxuXHRcdFx0Ly8gX2NvbmZpZ3VyZSBpcyBjYWxsZWQgdHdpY2UsIG9uY2UgaW4gY29yZS5zY2FsZS51cGRhdGUgYW5kIG9uY2UgaGVyZS5cclxuXHRcdFx0Ly8gSGVyZSB0aGUgYm94ZXMgYXJlIGZ1bGx5IHVwZGF0ZWQgYW5kIGF0IHRoZWlyIGZpbmFsIHBvc2l0aW9ucy5cclxuXHRcdFx0aWYgKGJveC5fY29uZmlndXJlKSB7XHJcblx0XHRcdFx0Ym94Ll9jb25maWd1cmUoKTtcclxuXHRcdFx0fVxyXG5cdFx0XHRtZS5fbGF5ZXJzLnB1c2guYXBwbHkobWUuX2xheWVycywgYm94Ll9sYXllcnMoKSk7XHJcblx0XHR9LCBtZSk7XHJcblxyXG5cdFx0bWUuX2xheWVycy5mb3JFYWNoKGZ1bmN0aW9uKGl0ZW0sIGluZGV4KSB7XHJcblx0XHRcdGl0ZW0uX2lkeCA9IGluZGV4O1xyXG5cdFx0fSk7XHJcblxyXG5cdFx0LyoqXHJcblx0XHQgKiBQcm92aWRlZCBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSwgdXNlIGBhZnRlckxheW91dGAgaW5zdGVhZC5cclxuXHRcdCAqIEBtZXRob2QgSVBsdWdpbiNhZnRlclNjYWxlVXBkYXRlXHJcblx0XHQgKiBAZGVwcmVjYXRlZCBzaW5jZSB2ZXJzaW9uIDIuNS4wXHJcblx0XHQgKiBAdG9kbyByZW1vdmUgYXQgdmVyc2lvbiAzXHJcblx0XHQgKiBAcHJpdmF0ZVxyXG5cdFx0ICovXHJcblx0XHRjb3JlX3BsdWdpbnMubm90aWZ5KG1lLCAnYWZ0ZXJTY2FsZVVwZGF0ZScpO1xyXG5cdFx0Y29yZV9wbHVnaW5zLm5vdGlmeShtZSwgJ2FmdGVyTGF5b3V0Jyk7XHJcblx0fSxcclxuXHJcblx0LyoqXHJcblx0ICogVXBkYXRlcyBhbGwgZGF0YXNldHMgdW5sZXNzIGEgcGx1Z2luIHJldHVybnMgYGZhbHNlYCB0byB0aGUgYGJlZm9yZURhdGFzZXRzVXBkYXRlYFxyXG5cdCAqIGhvb2ssIGluIHdoaWNoIGNhc2UsIHBsdWdpbnMgd2lsbCBub3QgYmUgY2FsbGVkIG9uIGBhZnRlckRhdGFzZXRzVXBkYXRlYC5cclxuXHQgKiBAcHJpdmF0ZVxyXG5cdCAqL1xyXG5cdHVwZGF0ZURhdGFzZXRzOiBmdW5jdGlvbigpIHtcclxuXHRcdHZhciBtZSA9IHRoaXM7XHJcblxyXG5cdFx0aWYgKGNvcmVfcGx1Z2lucy5ub3RpZnkobWUsICdiZWZvcmVEYXRhc2V0c1VwZGF0ZScpID09PSBmYWxzZSkge1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblxyXG5cdFx0Zm9yICh2YXIgaSA9IDAsIGlsZW4gPSBtZS5kYXRhLmRhdGFzZXRzLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xyXG5cdFx0XHRtZS51cGRhdGVEYXRhc2V0KGkpO1xyXG5cdFx0fVxyXG5cclxuXHRcdGNvcmVfcGx1Z2lucy5ub3RpZnkobWUsICdhZnRlckRhdGFzZXRzVXBkYXRlJyk7XHJcblx0fSxcclxuXHJcblx0LyoqXHJcblx0ICogVXBkYXRlcyBkYXRhc2V0IGF0IGluZGV4IHVubGVzcyBhIHBsdWdpbiByZXR1cm5zIGBmYWxzZWAgdG8gdGhlIGBiZWZvcmVEYXRhc2V0VXBkYXRlYFxyXG5cdCAqIGhvb2ssIGluIHdoaWNoIGNhc2UsIHBsdWdpbnMgd2lsbCBub3QgYmUgY2FsbGVkIG9uIGBhZnRlckRhdGFzZXRVcGRhdGVgLlxyXG5cdCAqIEBwcml2YXRlXHJcblx0ICovXHJcblx0dXBkYXRlRGF0YXNldDogZnVuY3Rpb24oaW5kZXgpIHtcclxuXHRcdHZhciBtZSA9IHRoaXM7XHJcblx0XHR2YXIgbWV0YSA9IG1lLmdldERhdGFzZXRNZXRhKGluZGV4KTtcclxuXHRcdHZhciBhcmdzID0ge1xyXG5cdFx0XHRtZXRhOiBtZXRhLFxyXG5cdFx0XHRpbmRleDogaW5kZXhcclxuXHRcdH07XHJcblxyXG5cdFx0aWYgKGNvcmVfcGx1Z2lucy5ub3RpZnkobWUsICdiZWZvcmVEYXRhc2V0VXBkYXRlJywgW2FyZ3NdKSA9PT0gZmFsc2UpIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdG1ldGEuY29udHJvbGxlci5fdXBkYXRlKCk7XHJcblxyXG5cdFx0Y29yZV9wbHVnaW5zLm5vdGlmeShtZSwgJ2FmdGVyRGF0YXNldFVwZGF0ZScsIFthcmdzXSk7XHJcblx0fSxcclxuXHJcblx0cmVuZGVyOiBmdW5jdGlvbihjb25maWcpIHtcclxuXHRcdHZhciBtZSA9IHRoaXM7XHJcblxyXG5cdFx0aWYgKCFjb25maWcgfHwgdHlwZW9mIGNvbmZpZyAhPT0gJ29iamVjdCcpIHtcclxuXHRcdFx0Ly8gYmFja3dhcmRzIGNvbXBhdGliaWxpdHlcclxuXHRcdFx0Y29uZmlnID0ge1xyXG5cdFx0XHRcdGR1cmF0aW9uOiBjb25maWcsXHJcblx0XHRcdFx0bGF6eTogYXJndW1lbnRzWzFdXHJcblx0XHRcdH07XHJcblx0XHR9XHJcblxyXG5cdFx0dmFyIGFuaW1hdGlvbk9wdGlvbnMgPSBtZS5vcHRpb25zLmFuaW1hdGlvbjtcclxuXHRcdHZhciBkdXJhdGlvbiA9IHZhbHVlT3JEZWZhdWx0JDkoY29uZmlnLmR1cmF0aW9uLCBhbmltYXRpb25PcHRpb25zICYmIGFuaW1hdGlvbk9wdGlvbnMuZHVyYXRpb24pO1xyXG5cdFx0dmFyIGxhenkgPSBjb25maWcubGF6eTtcclxuXHJcblx0XHRpZiAoY29yZV9wbHVnaW5zLm5vdGlmeShtZSwgJ2JlZm9yZVJlbmRlcicpID09PSBmYWxzZSkge1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblxyXG5cdFx0dmFyIG9uQ29tcGxldGUgPSBmdW5jdGlvbihhbmltYXRpb24pIHtcclxuXHRcdFx0Y29yZV9wbHVnaW5zLm5vdGlmeShtZSwgJ2FmdGVyUmVuZGVyJyk7XHJcblx0XHRcdGhlbHBlcnMkMS5jYWxsYmFjayhhbmltYXRpb25PcHRpb25zICYmIGFuaW1hdGlvbk9wdGlvbnMub25Db21wbGV0ZSwgW2FuaW1hdGlvbl0sIG1lKTtcclxuXHRcdH07XHJcblxyXG5cdFx0aWYgKGFuaW1hdGlvbk9wdGlvbnMgJiYgZHVyYXRpb24pIHtcclxuXHRcdFx0dmFyIGFuaW1hdGlvbiA9IG5ldyBjb3JlX2FuaW1hdGlvbih7XHJcblx0XHRcdFx0bnVtU3RlcHM6IGR1cmF0aW9uIC8gMTYuNjYsIC8vIDYwIGZwc1xyXG5cdFx0XHRcdGVhc2luZzogY29uZmlnLmVhc2luZyB8fCBhbmltYXRpb25PcHRpb25zLmVhc2luZyxcclxuXHJcblx0XHRcdFx0cmVuZGVyOiBmdW5jdGlvbihjaGFydCwgYW5pbWF0aW9uT2JqZWN0KSB7XHJcblx0XHRcdFx0XHR2YXIgZWFzaW5nRnVuY3Rpb24gPSBoZWxwZXJzJDEuZWFzaW5nLmVmZmVjdHNbYW5pbWF0aW9uT2JqZWN0LmVhc2luZ107XHJcblx0XHRcdFx0XHR2YXIgY3VycmVudFN0ZXAgPSBhbmltYXRpb25PYmplY3QuY3VycmVudFN0ZXA7XHJcblx0XHRcdFx0XHR2YXIgc3RlcERlY2ltYWwgPSBjdXJyZW50U3RlcCAvIGFuaW1hdGlvbk9iamVjdC5udW1TdGVwcztcclxuXHJcblx0XHRcdFx0XHRjaGFydC5kcmF3KGVhc2luZ0Z1bmN0aW9uKHN0ZXBEZWNpbWFsKSwgc3RlcERlY2ltYWwsIGN1cnJlbnRTdGVwKTtcclxuXHRcdFx0XHR9LFxyXG5cclxuXHRcdFx0XHRvbkFuaW1hdGlvblByb2dyZXNzOiBhbmltYXRpb25PcHRpb25zLm9uUHJvZ3Jlc3MsXHJcblx0XHRcdFx0b25BbmltYXRpb25Db21wbGV0ZTogb25Db21wbGV0ZVxyXG5cdFx0XHR9KTtcclxuXHJcblx0XHRcdGNvcmVfYW5pbWF0aW9ucy5hZGRBbmltYXRpb24obWUsIGFuaW1hdGlvbiwgZHVyYXRpb24sIGxhenkpO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0bWUuZHJhdygpO1xyXG5cclxuXHRcdFx0Ly8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9jaGFydGpzL0NoYXJ0LmpzL2lzc3Vlcy8zNzgxXHJcblx0XHRcdG9uQ29tcGxldGUobmV3IGNvcmVfYW5pbWF0aW9uKHtudW1TdGVwczogMCwgY2hhcnQ6IG1lfSkpO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiBtZTtcclxuXHR9LFxyXG5cclxuXHRkcmF3OiBmdW5jdGlvbihlYXNpbmdWYWx1ZSkge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHRcdHZhciBpLCBsYXllcnM7XHJcblxyXG5cdFx0bWUuY2xlYXIoKTtcclxuXHJcblx0XHRpZiAoaGVscGVycyQxLmlzTnVsbE9yVW5kZWYoZWFzaW5nVmFsdWUpKSB7XHJcblx0XHRcdGVhc2luZ1ZhbHVlID0gMTtcclxuXHRcdH1cclxuXHJcblx0XHRtZS50cmFuc2l0aW9uKGVhc2luZ1ZhbHVlKTtcclxuXHJcblx0XHRpZiAobWUud2lkdGggPD0gMCB8fCBtZS5oZWlnaHQgPD0gMCkge1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKGNvcmVfcGx1Z2lucy5ub3RpZnkobWUsICdiZWZvcmVEcmF3JywgW2Vhc2luZ1ZhbHVlXSkgPT09IGZhbHNlKSB7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBCZWNhdXNlIG9mIHBsdWdpbiBob29rcyAoYmVmb3JlL2FmdGVyRGF0YXNldHNEcmF3KSwgZGF0YXNldHMgY2FuJ3RcclxuXHRcdC8vIGN1cnJlbnRseSBiZSBwYXJ0IG9mIGxheWVycy4gSW5zdGVhZCwgd2UgZHJhd1xyXG5cdFx0Ly8gbGF5ZXJzIDw9IDAgYmVmb3JlKGRlZmF1bHQsIGJhY2t3YXJkIGNvbXBhdCksIGFuZCB0aGUgcmVzdCBhZnRlclxyXG5cdFx0bGF5ZXJzID0gbWUuX2xheWVycztcclxuXHRcdGZvciAoaSA9IDA7IGkgPCBsYXllcnMubGVuZ3RoICYmIGxheWVyc1tpXS56IDw9IDA7ICsraSkge1xyXG5cdFx0XHRsYXllcnNbaV0uZHJhdyhtZS5jaGFydEFyZWEpO1xyXG5cdFx0fVxyXG5cclxuXHRcdG1lLmRyYXdEYXRhc2V0cyhlYXNpbmdWYWx1ZSk7XHJcblxyXG5cdFx0Ly8gUmVzdCBvZiBsYXllcnNcclxuXHRcdGZvciAoOyBpIDwgbGF5ZXJzLmxlbmd0aDsgKytpKSB7XHJcblx0XHRcdGxheWVyc1tpXS5kcmF3KG1lLmNoYXJ0QXJlYSk7XHJcblx0XHR9XHJcblxyXG5cdFx0bWUuX2RyYXdUb29sdGlwKGVhc2luZ1ZhbHVlKTtcclxuXHJcblx0XHRjb3JlX3BsdWdpbnMubm90aWZ5KG1lLCAnYWZ0ZXJEcmF3JywgW2Vhc2luZ1ZhbHVlXSk7XHJcblx0fSxcclxuXHJcblx0LyoqXHJcblx0ICogQHByaXZhdGVcclxuXHQgKi9cclxuXHR0cmFuc2l0aW9uOiBmdW5jdGlvbihlYXNpbmdWYWx1ZSkge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHJcblx0XHRmb3IgKHZhciBpID0gMCwgaWxlbiA9IChtZS5kYXRhLmRhdGFzZXRzIHx8IFtdKS5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcclxuXHRcdFx0aWYgKG1lLmlzRGF0YXNldFZpc2libGUoaSkpIHtcclxuXHRcdFx0XHRtZS5nZXREYXRhc2V0TWV0YShpKS5jb250cm9sbGVyLnRyYW5zaXRpb24oZWFzaW5nVmFsdWUpO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0bWUudG9vbHRpcC50cmFuc2l0aW9uKGVhc2luZ1ZhbHVlKTtcclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBAcHJpdmF0ZVxyXG5cdCAqL1xyXG5cdF9nZXRTb3J0ZWREYXRhc2V0TWV0YXM6IGZ1bmN0aW9uKGZpbHRlclZpc2libGUpIHtcclxuXHRcdHZhciBtZSA9IHRoaXM7XHJcblx0XHR2YXIgZGF0YXNldHMgPSBtZS5kYXRhLmRhdGFzZXRzIHx8IFtdO1xyXG5cdFx0dmFyIHJlc3VsdCA9IFtdO1xyXG5cdFx0dmFyIGksIGlsZW47XHJcblxyXG5cdFx0Zm9yIChpID0gMCwgaWxlbiA9IGRhdGFzZXRzLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xyXG5cdFx0XHRpZiAoIWZpbHRlclZpc2libGUgfHwgbWUuaXNEYXRhc2V0VmlzaWJsZShpKSkge1xyXG5cdFx0XHRcdHJlc3VsdC5wdXNoKG1lLmdldERhdGFzZXRNZXRhKGkpKTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdHJlc3VsdC5zb3J0KGNvbXBhcmUyTGV2ZWwoJ29yZGVyJywgJ2luZGV4JykpO1xyXG5cclxuXHRcdHJldHVybiByZXN1bHQ7XHJcblx0fSxcclxuXHJcblx0LyoqXHJcblx0ICogQHByaXZhdGVcclxuXHQgKi9cclxuXHRfZ2V0U29ydGVkVmlzaWJsZURhdGFzZXRNZXRhczogZnVuY3Rpb24oKSB7XHJcblx0XHRyZXR1cm4gdGhpcy5fZ2V0U29ydGVkRGF0YXNldE1ldGFzKHRydWUpO1xyXG5cdH0sXHJcblxyXG5cdC8qKlxyXG5cdCAqIERyYXdzIGFsbCBkYXRhc2V0cyB1bmxlc3MgYSBwbHVnaW4gcmV0dXJucyBgZmFsc2VgIHRvIHRoZSBgYmVmb3JlRGF0YXNldHNEcmF3YFxyXG5cdCAqIGhvb2ssIGluIHdoaWNoIGNhc2UsIHBsdWdpbnMgd2lsbCBub3QgYmUgY2FsbGVkIG9uIGBhZnRlckRhdGFzZXRzRHJhd2AuXHJcblx0ICogQHByaXZhdGVcclxuXHQgKi9cclxuXHRkcmF3RGF0YXNldHM6IGZ1bmN0aW9uKGVhc2luZ1ZhbHVlKSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0dmFyIG1ldGFzZXRzLCBpO1xyXG5cclxuXHRcdGlmIChjb3JlX3BsdWdpbnMubm90aWZ5KG1lLCAnYmVmb3JlRGF0YXNldHNEcmF3JywgW2Vhc2luZ1ZhbHVlXSkgPT09IGZhbHNlKSB7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHJcblx0XHRtZXRhc2V0cyA9IG1lLl9nZXRTb3J0ZWRWaXNpYmxlRGF0YXNldE1ldGFzKCk7XHJcblx0XHRmb3IgKGkgPSBtZXRhc2V0cy5sZW5ndGggLSAxOyBpID49IDA7IC0taSkge1xyXG5cdFx0XHRtZS5kcmF3RGF0YXNldChtZXRhc2V0c1tpXSwgZWFzaW5nVmFsdWUpO1xyXG5cdFx0fVxyXG5cclxuXHRcdGNvcmVfcGx1Z2lucy5ub3RpZnkobWUsICdhZnRlckRhdGFzZXRzRHJhdycsIFtlYXNpbmdWYWx1ZV0pO1xyXG5cdH0sXHJcblxyXG5cdC8qKlxyXG5cdCAqIERyYXdzIGRhdGFzZXQgYXQgaW5kZXggdW5sZXNzIGEgcGx1Z2luIHJldHVybnMgYGZhbHNlYCB0byB0aGUgYGJlZm9yZURhdGFzZXREcmF3YFxyXG5cdCAqIGhvb2ssIGluIHdoaWNoIGNhc2UsIHBsdWdpbnMgd2lsbCBub3QgYmUgY2FsbGVkIG9uIGBhZnRlckRhdGFzZXREcmF3YC5cclxuXHQgKiBAcHJpdmF0ZVxyXG5cdCAqL1xyXG5cdGRyYXdEYXRhc2V0OiBmdW5jdGlvbihtZXRhLCBlYXNpbmdWYWx1ZSkge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHRcdHZhciBhcmdzID0ge1xyXG5cdFx0XHRtZXRhOiBtZXRhLFxyXG5cdFx0XHRpbmRleDogbWV0YS5pbmRleCxcclxuXHRcdFx0ZWFzaW5nVmFsdWU6IGVhc2luZ1ZhbHVlXHJcblx0XHR9O1xyXG5cclxuXHRcdGlmIChjb3JlX3BsdWdpbnMubm90aWZ5KG1lLCAnYmVmb3JlRGF0YXNldERyYXcnLCBbYXJnc10pID09PSBmYWxzZSkge1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblxyXG5cdFx0bWV0YS5jb250cm9sbGVyLmRyYXcoZWFzaW5nVmFsdWUpO1xyXG5cclxuXHRcdGNvcmVfcGx1Z2lucy5ub3RpZnkobWUsICdhZnRlckRhdGFzZXREcmF3JywgW2FyZ3NdKTtcclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBEcmF3cyB0b29sdGlwIHVubGVzcyBhIHBsdWdpbiByZXR1cm5zIGBmYWxzZWAgdG8gdGhlIGBiZWZvcmVUb29sdGlwRHJhd2BcclxuXHQgKiBob29rLCBpbiB3aGljaCBjYXNlLCBwbHVnaW5zIHdpbGwgbm90IGJlIGNhbGxlZCBvbiBgYWZ0ZXJUb29sdGlwRHJhd2AuXHJcblx0ICogQHByaXZhdGVcclxuXHQgKi9cclxuXHRfZHJhd1Rvb2x0aXA6IGZ1bmN0aW9uKGVhc2luZ1ZhbHVlKSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0dmFyIHRvb2x0aXAgPSBtZS50b29sdGlwO1xyXG5cdFx0dmFyIGFyZ3MgPSB7XHJcblx0XHRcdHRvb2x0aXA6IHRvb2x0aXAsXHJcblx0XHRcdGVhc2luZ1ZhbHVlOiBlYXNpbmdWYWx1ZVxyXG5cdFx0fTtcclxuXHJcblx0XHRpZiAoY29yZV9wbHVnaW5zLm5vdGlmeShtZSwgJ2JlZm9yZVRvb2x0aXBEcmF3JywgW2FyZ3NdKSA9PT0gZmFsc2UpIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdHRvb2x0aXAuZHJhdygpO1xyXG5cclxuXHRcdGNvcmVfcGx1Z2lucy5ub3RpZnkobWUsICdhZnRlclRvb2x0aXBEcmF3JywgW2FyZ3NdKTtcclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBHZXQgdGhlIHNpbmdsZSBlbGVtZW50IHRoYXQgd2FzIGNsaWNrZWQgb25cclxuXHQgKiBAcmV0dXJuIEFuIG9iamVjdCBjb250YWluaW5nIHRoZSBkYXRhc2V0IGluZGV4IGFuZCBlbGVtZW50IGluZGV4IG9mIHRoZSBtYXRjaGluZyBlbGVtZW50LiBBbHNvIGNvbnRhaW5zIHRoZSByZWN0YW5nbGUgdGhhdCB3YXMgZHJhd1xyXG5cdCAqL1xyXG5cdGdldEVsZW1lbnRBdEV2ZW50OiBmdW5jdGlvbihlKSB7XHJcblx0XHRyZXR1cm4gY29yZV9pbnRlcmFjdGlvbi5tb2Rlcy5zaW5nbGUodGhpcywgZSk7XHJcblx0fSxcclxuXHJcblx0Z2V0RWxlbWVudHNBdEV2ZW50OiBmdW5jdGlvbihlKSB7XHJcblx0XHRyZXR1cm4gY29yZV9pbnRlcmFjdGlvbi5tb2Rlcy5sYWJlbCh0aGlzLCBlLCB7aW50ZXJzZWN0OiB0cnVlfSk7XHJcblx0fSxcclxuXHJcblx0Z2V0RWxlbWVudHNBdFhBeGlzOiBmdW5jdGlvbihlKSB7XHJcblx0XHRyZXR1cm4gY29yZV9pbnRlcmFjdGlvbi5tb2Rlc1sneC1heGlzJ10odGhpcywgZSwge2ludGVyc2VjdDogdHJ1ZX0pO1xyXG5cdH0sXHJcblxyXG5cdGdldEVsZW1lbnRzQXRFdmVudEZvck1vZGU6IGZ1bmN0aW9uKGUsIG1vZGUsIG9wdGlvbnMpIHtcclxuXHRcdHZhciBtZXRob2QgPSBjb3JlX2ludGVyYWN0aW9uLm1vZGVzW21vZGVdO1xyXG5cdFx0aWYgKHR5cGVvZiBtZXRob2QgPT09ICdmdW5jdGlvbicpIHtcclxuXHRcdFx0cmV0dXJuIG1ldGhvZCh0aGlzLCBlLCBvcHRpb25zKTtcclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gW107XHJcblx0fSxcclxuXHJcblx0Z2V0RGF0YXNldEF0RXZlbnQ6IGZ1bmN0aW9uKGUpIHtcclxuXHRcdHJldHVybiBjb3JlX2ludGVyYWN0aW9uLm1vZGVzLmRhdGFzZXQodGhpcywgZSwge2ludGVyc2VjdDogdHJ1ZX0pO1xyXG5cdH0sXHJcblxyXG5cdGdldERhdGFzZXRNZXRhOiBmdW5jdGlvbihkYXRhc2V0SW5kZXgpIHtcclxuXHRcdHZhciBtZSA9IHRoaXM7XHJcblx0XHR2YXIgZGF0YXNldCA9IG1lLmRhdGEuZGF0YXNldHNbZGF0YXNldEluZGV4XTtcclxuXHRcdGlmICghZGF0YXNldC5fbWV0YSkge1xyXG5cdFx0XHRkYXRhc2V0Ll9tZXRhID0ge307XHJcblx0XHR9XHJcblxyXG5cdFx0dmFyIG1ldGEgPSBkYXRhc2V0Ll9tZXRhW21lLmlkXTtcclxuXHRcdGlmICghbWV0YSkge1xyXG5cdFx0XHRtZXRhID0gZGF0YXNldC5fbWV0YVttZS5pZF0gPSB7XHJcblx0XHRcdFx0dHlwZTogbnVsbCxcclxuXHRcdFx0XHRkYXRhOiBbXSxcclxuXHRcdFx0XHRkYXRhc2V0OiBudWxsLFxyXG5cdFx0XHRcdGNvbnRyb2xsZXI6IG51bGwsXHJcblx0XHRcdFx0aGlkZGVuOiBudWxsLFx0XHRcdC8vIFNlZSBpc0RhdGFzZXRWaXNpYmxlKCkgY29tbWVudFxyXG5cdFx0XHRcdHhBeGlzSUQ6IG51bGwsXHJcblx0XHRcdFx0eUF4aXNJRDogbnVsbCxcclxuXHRcdFx0XHRvcmRlcjogZGF0YXNldC5vcmRlciB8fCAwLFxyXG5cdFx0XHRcdGluZGV4OiBkYXRhc2V0SW5kZXhcclxuXHRcdFx0fTtcclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gbWV0YTtcclxuXHR9LFxyXG5cclxuXHRnZXRWaXNpYmxlRGF0YXNldENvdW50OiBmdW5jdGlvbigpIHtcclxuXHRcdHZhciBjb3VudCA9IDA7XHJcblx0XHRmb3IgKHZhciBpID0gMCwgaWxlbiA9IHRoaXMuZGF0YS5kYXRhc2V0cy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcclxuXHRcdFx0aWYgKHRoaXMuaXNEYXRhc2V0VmlzaWJsZShpKSkge1xyXG5cdFx0XHRcdGNvdW50Kys7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHRcdHJldHVybiBjb3VudDtcclxuXHR9LFxyXG5cclxuXHRpc0RhdGFzZXRWaXNpYmxlOiBmdW5jdGlvbihkYXRhc2V0SW5kZXgpIHtcclxuXHRcdHZhciBtZXRhID0gdGhpcy5nZXREYXRhc2V0TWV0YShkYXRhc2V0SW5kZXgpO1xyXG5cclxuXHRcdC8vIG1ldGEuaGlkZGVuIGlzIGEgcGVyIGNoYXJ0IGRhdGFzZXQgaGlkZGVuIGZsYWcgb3ZlcnJpZGUgd2l0aCAzIHN0YXRlczogaWYgdHJ1ZSBvciBmYWxzZSxcclxuXHRcdC8vIHRoZSBkYXRhc2V0LmhpZGRlbiB2YWx1ZSBpcyBpZ25vcmVkLCBlbHNlIGlmIG51bGwsIHRoZSBkYXRhc2V0IGhpZGRlbiBzdGF0ZSBpcyByZXR1cm5lZC5cclxuXHRcdHJldHVybiB0eXBlb2YgbWV0YS5oaWRkZW4gPT09ICdib29sZWFuJyA/ICFtZXRhLmhpZGRlbiA6ICF0aGlzLmRhdGEuZGF0YXNldHNbZGF0YXNldEluZGV4XS5oaWRkZW47XHJcblx0fSxcclxuXHJcblx0Z2VuZXJhdGVMZWdlbmQ6IGZ1bmN0aW9uKCkge1xyXG5cdFx0cmV0dXJuIHRoaXMub3B0aW9ucy5sZWdlbmRDYWxsYmFjayh0aGlzKTtcclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBAcHJpdmF0ZVxyXG5cdCAqL1xyXG5cdGRlc3Ryb3lEYXRhc2V0TWV0YTogZnVuY3Rpb24oZGF0YXNldEluZGV4KSB7XHJcblx0XHR2YXIgaWQgPSB0aGlzLmlkO1xyXG5cdFx0dmFyIGRhdGFzZXQgPSB0aGlzLmRhdGEuZGF0YXNldHNbZGF0YXNldEluZGV4XTtcclxuXHRcdHZhciBtZXRhID0gZGF0YXNldC5fbWV0YSAmJiBkYXRhc2V0Ll9tZXRhW2lkXTtcclxuXHJcblx0XHRpZiAobWV0YSkge1xyXG5cdFx0XHRtZXRhLmNvbnRyb2xsZXIuZGVzdHJveSgpO1xyXG5cdFx0XHRkZWxldGUgZGF0YXNldC5fbWV0YVtpZF07XHJcblx0XHR9XHJcblx0fSxcclxuXHJcblx0ZGVzdHJveTogZnVuY3Rpb24oKSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0dmFyIGNhbnZhcyA9IG1lLmNhbnZhcztcclxuXHRcdHZhciBpLCBpbGVuO1xyXG5cclxuXHRcdG1lLnN0b3AoKTtcclxuXHJcblx0XHQvLyBkYXRhc2V0IGNvbnRyb2xsZXJzIG5lZWQgdG8gY2xlYW51cCBhc3NvY2lhdGVkIGRhdGFcclxuXHRcdGZvciAoaSA9IDAsIGlsZW4gPSBtZS5kYXRhLmRhdGFzZXRzLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xyXG5cdFx0XHRtZS5kZXN0cm95RGF0YXNldE1ldGEoaSk7XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKGNhbnZhcykge1xyXG5cdFx0XHRtZS51bmJpbmRFdmVudHMoKTtcclxuXHRcdFx0aGVscGVycyQxLmNhbnZhcy5jbGVhcihtZSk7XHJcblx0XHRcdHBsYXRmb3JtLnJlbGVhc2VDb250ZXh0KG1lLmN0eCk7XHJcblx0XHRcdG1lLmNhbnZhcyA9IG51bGw7XHJcblx0XHRcdG1lLmN0eCA9IG51bGw7XHJcblx0XHR9XHJcblxyXG5cdFx0Y29yZV9wbHVnaW5zLm5vdGlmeShtZSwgJ2Rlc3Ryb3knKTtcclxuXHJcblx0XHRkZWxldGUgQ2hhcnQuaW5zdGFuY2VzW21lLmlkXTtcclxuXHR9LFxyXG5cclxuXHR0b0Jhc2U2NEltYWdlOiBmdW5jdGlvbigpIHtcclxuXHRcdHJldHVybiB0aGlzLmNhbnZhcy50b0RhdGFVUkwuYXBwbHkodGhpcy5jYW52YXMsIGFyZ3VtZW50cyk7XHJcblx0fSxcclxuXHJcblx0aW5pdFRvb2xUaXA6IGZ1bmN0aW9uKCkge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHRcdG1lLnRvb2x0aXAgPSBuZXcgY29yZV90b29sdGlwKHtcclxuXHRcdFx0X2NoYXJ0OiBtZSxcclxuXHRcdFx0X2NoYXJ0SW5zdGFuY2U6IG1lLCAvLyBkZXByZWNhdGVkLCBiYWNrd2FyZCBjb21wYXRpYmlsaXR5XHJcblx0XHRcdF9kYXRhOiBtZS5kYXRhLFxyXG5cdFx0XHRfb3B0aW9uczogbWUub3B0aW9ucy50b29sdGlwc1xyXG5cdFx0fSwgbWUpO1xyXG5cdH0sXHJcblxyXG5cdC8qKlxyXG5cdCAqIEBwcml2YXRlXHJcblx0ICovXHJcblx0YmluZEV2ZW50czogZnVuY3Rpb24oKSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0dmFyIGxpc3RlbmVycyA9IG1lLl9saXN0ZW5lcnMgPSB7fTtcclxuXHRcdHZhciBsaXN0ZW5lciA9IGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRtZS5ldmVudEhhbmRsZXIuYXBwbHkobWUsIGFyZ3VtZW50cyk7XHJcblx0XHR9O1xyXG5cclxuXHRcdGhlbHBlcnMkMS5lYWNoKG1lLm9wdGlvbnMuZXZlbnRzLCBmdW5jdGlvbih0eXBlKSB7XHJcblx0XHRcdHBsYXRmb3JtLmFkZEV2ZW50TGlzdGVuZXIobWUsIHR5cGUsIGxpc3RlbmVyKTtcclxuXHRcdFx0bGlzdGVuZXJzW3R5cGVdID0gbGlzdGVuZXI7XHJcblx0XHR9KTtcclxuXHJcblx0XHQvLyBFbGVtZW50cyB1c2VkIHRvIGRldGVjdCBzaXplIGNoYW5nZSBzaG91bGQgbm90IGJlIGluamVjdGVkIGZvciBub24gcmVzcG9uc2l2ZSBjaGFydHMuXHJcblx0XHQvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2NoYXJ0anMvQ2hhcnQuanMvaXNzdWVzLzIyMTBcclxuXHRcdGlmIChtZS5vcHRpb25zLnJlc3BvbnNpdmUpIHtcclxuXHRcdFx0bGlzdGVuZXIgPSBmdW5jdGlvbigpIHtcclxuXHRcdFx0XHRtZS5yZXNpemUoKTtcclxuXHRcdFx0fTtcclxuXHJcblx0XHRcdHBsYXRmb3JtLmFkZEV2ZW50TGlzdGVuZXIobWUsICdyZXNpemUnLCBsaXN0ZW5lcik7XHJcblx0XHRcdGxpc3RlbmVycy5yZXNpemUgPSBsaXN0ZW5lcjtcclxuXHRcdH1cclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBAcHJpdmF0ZVxyXG5cdCAqL1xyXG5cdHVuYmluZEV2ZW50czogZnVuY3Rpb24oKSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0dmFyIGxpc3RlbmVycyA9IG1lLl9saXN0ZW5lcnM7XHJcblx0XHRpZiAoIWxpc3RlbmVycykge1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblxyXG5cdFx0ZGVsZXRlIG1lLl9saXN0ZW5lcnM7XHJcblx0XHRoZWxwZXJzJDEuZWFjaChsaXN0ZW5lcnMsIGZ1bmN0aW9uKGxpc3RlbmVyLCB0eXBlKSB7XHJcblx0XHRcdHBsYXRmb3JtLnJlbW92ZUV2ZW50TGlzdGVuZXIobWUsIHR5cGUsIGxpc3RlbmVyKTtcclxuXHRcdH0pO1xyXG5cdH0sXHJcblxyXG5cdHVwZGF0ZUhvdmVyU3R5bGU6IGZ1bmN0aW9uKGVsZW1lbnRzLCBtb2RlLCBlbmFibGVkKSB7XHJcblx0XHR2YXIgcHJlZml4ID0gZW5hYmxlZCA/ICdzZXQnIDogJ3JlbW92ZSc7XHJcblx0XHR2YXIgZWxlbWVudCwgaSwgaWxlbjtcclxuXHJcblx0XHRmb3IgKGkgPSAwLCBpbGVuID0gZWxlbWVudHMubGVuZ3RoOyBpIDwgaWxlbjsgKytpKSB7XHJcblx0XHRcdGVsZW1lbnQgPSBlbGVtZW50c1tpXTtcclxuXHRcdFx0aWYgKGVsZW1lbnQpIHtcclxuXHRcdFx0XHR0aGlzLmdldERhdGFzZXRNZXRhKGVsZW1lbnQuX2RhdGFzZXRJbmRleCkuY29udHJvbGxlcltwcmVmaXggKyAnSG92ZXJTdHlsZSddKGVsZW1lbnQpO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKG1vZGUgPT09ICdkYXRhc2V0Jykge1xyXG5cdFx0XHR0aGlzLmdldERhdGFzZXRNZXRhKGVsZW1lbnRzWzBdLl9kYXRhc2V0SW5kZXgpLmNvbnRyb2xsZXJbJ18nICsgcHJlZml4ICsgJ0RhdGFzZXRIb3ZlclN0eWxlJ10oKTtcclxuXHRcdH1cclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBAcHJpdmF0ZVxyXG5cdCAqL1xyXG5cdGV2ZW50SGFuZGxlcjogZnVuY3Rpb24oZSkge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHRcdHZhciB0b29sdGlwID0gbWUudG9vbHRpcDtcclxuXHJcblx0XHRpZiAoY29yZV9wbHVnaW5zLm5vdGlmeShtZSwgJ2JlZm9yZUV2ZW50JywgW2VdKSA9PT0gZmFsc2UpIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIEJ1ZmZlciBhbnkgdXBkYXRlIGNhbGxzIHNvIHRoYXQgcmVuZGVycyBkbyBub3Qgb2NjdXJcclxuXHRcdG1lLl9idWZmZXJlZFJlbmRlciA9IHRydWU7XHJcblx0XHRtZS5fYnVmZmVyZWRSZXF1ZXN0ID0gbnVsbDtcclxuXHJcblx0XHR2YXIgY2hhbmdlZCA9IG1lLmhhbmRsZUV2ZW50KGUpO1xyXG5cdFx0Ly8gZm9yIHNtb290aCB0b29sdGlwIGFuaW1hdGlvbnMgaXNzdWUgIzQ5ODlcclxuXHRcdC8vIHRoZSB0b29sdGlwIHNob3VsZCBiZSB0aGUgc291cmNlIG9mIGNoYW5nZVxyXG5cdFx0Ly8gQW5pbWF0aW9uIGNoZWNrIHdvcmthcm91bmQ6XHJcblx0XHQvLyB0b29sdGlwLl9zdGFydCB3aWxsIGJlIG51bGwgd2hlbiB0b29sdGlwIGlzbid0IGFuaW1hdGluZ1xyXG5cdFx0aWYgKHRvb2x0aXApIHtcclxuXHRcdFx0Y2hhbmdlZCA9IHRvb2x0aXAuX3N0YXJ0XHJcblx0XHRcdFx0PyB0b29sdGlwLmhhbmRsZUV2ZW50KGUpXHJcblx0XHRcdFx0OiBjaGFuZ2VkIHwgdG9vbHRpcC5oYW5kbGVFdmVudChlKTtcclxuXHRcdH1cclxuXHJcblx0XHRjb3JlX3BsdWdpbnMubm90aWZ5KG1lLCAnYWZ0ZXJFdmVudCcsIFtlXSk7XHJcblxyXG5cdFx0dmFyIGJ1ZmZlcmVkUmVxdWVzdCA9IG1lLl9idWZmZXJlZFJlcXVlc3Q7XHJcblx0XHRpZiAoYnVmZmVyZWRSZXF1ZXN0KSB7XHJcblx0XHRcdC8vIElmIHdlIGhhdmUgYW4gdXBkYXRlIHRoYXQgd2FzIHRyaWdnZXJlZCwgd2UgbmVlZCB0byBkbyBhIG5vcm1hbCByZW5kZXJcclxuXHRcdFx0bWUucmVuZGVyKGJ1ZmZlcmVkUmVxdWVzdCk7XHJcblx0XHR9IGVsc2UgaWYgKGNoYW5nZWQgJiYgIW1lLmFuaW1hdGluZykge1xyXG5cdFx0XHQvLyBJZiBlbnRlcmluZywgbGVhdmluZywgb3IgY2hhbmdpbmcgZWxlbWVudHMsIGFuaW1hdGUgdGhlIGNoYW5nZSB2aWEgcGl2b3RcclxuXHRcdFx0bWUuc3RvcCgpO1xyXG5cclxuXHRcdFx0Ly8gV2Ugb25seSBuZWVkIHRvIHJlbmRlciBhdCB0aGlzIHBvaW50LiBVcGRhdGluZyB3aWxsIGNhdXNlIHNjYWxlcyB0byBiZVxyXG5cdFx0XHQvLyByZWNvbXB1dGVkIGdlbmVyYXRpbmcgZmxpY2tlciAmIHVzaW5nIG1vcmUgbWVtb3J5IHRoYW4gbmVjZXNzYXJ5LlxyXG5cdFx0XHRtZS5yZW5kZXIoe1xyXG5cdFx0XHRcdGR1cmF0aW9uOiBtZS5vcHRpb25zLmhvdmVyLmFuaW1hdGlvbkR1cmF0aW9uLFxyXG5cdFx0XHRcdGxhenk6IHRydWVcclxuXHRcdFx0fSk7XHJcblx0XHR9XHJcblxyXG5cdFx0bWUuX2J1ZmZlcmVkUmVuZGVyID0gZmFsc2U7XHJcblx0XHRtZS5fYnVmZmVyZWRSZXF1ZXN0ID0gbnVsbDtcclxuXHJcblx0XHRyZXR1cm4gbWU7XHJcblx0fSxcclxuXHJcblx0LyoqXHJcblx0ICogSGFuZGxlIGFuIGV2ZW50XHJcblx0ICogQHByaXZhdGVcclxuXHQgKiBAcGFyYW0ge0lFdmVudH0gZXZlbnQgdGhlIGV2ZW50IHRvIGhhbmRsZVxyXG5cdCAqIEByZXR1cm4ge2Jvb2xlYW59IHRydWUgaWYgdGhlIGNoYXJ0IG5lZWRzIHRvIHJlLXJlbmRlclxyXG5cdCAqL1xyXG5cdGhhbmRsZUV2ZW50OiBmdW5jdGlvbihlKSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0dmFyIG9wdGlvbnMgPSBtZS5vcHRpb25zIHx8IHt9O1xyXG5cdFx0dmFyIGhvdmVyT3B0aW9ucyA9IG9wdGlvbnMuaG92ZXI7XHJcblx0XHR2YXIgY2hhbmdlZCA9IGZhbHNlO1xyXG5cclxuXHRcdG1lLmxhc3RBY3RpdmUgPSBtZS5sYXN0QWN0aXZlIHx8IFtdO1xyXG5cclxuXHRcdC8vIEZpbmQgQWN0aXZlIEVsZW1lbnRzIGZvciBob3ZlciBhbmQgdG9vbHRpcHNcclxuXHRcdGlmIChlLnR5cGUgPT09ICdtb3VzZW91dCcpIHtcclxuXHRcdFx0bWUuYWN0aXZlID0gW107XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRtZS5hY3RpdmUgPSBtZS5nZXRFbGVtZW50c0F0RXZlbnRGb3JNb2RlKGUsIGhvdmVyT3B0aW9ucy5tb2RlLCBob3Zlck9wdGlvbnMpO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIEludm9rZSBvbkhvdmVyIGhvb2tcclxuXHRcdC8vIE5lZWQgdG8gY2FsbCB3aXRoIG5hdGl2ZSBldmVudCBoZXJlIHRvIG5vdCBicmVhayBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eVxyXG5cdFx0aGVscGVycyQxLmNhbGxiYWNrKG9wdGlvbnMub25Ib3ZlciB8fCBvcHRpb25zLmhvdmVyLm9uSG92ZXIsIFtlLm5hdGl2ZSwgbWUuYWN0aXZlXSwgbWUpO1xyXG5cclxuXHRcdGlmIChlLnR5cGUgPT09ICdtb3VzZXVwJyB8fCBlLnR5cGUgPT09ICdjbGljaycpIHtcclxuXHRcdFx0aWYgKG9wdGlvbnMub25DbGljaykge1xyXG5cdFx0XHRcdC8vIFVzZSBlLm5hdGl2ZSBoZXJlIGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eVxyXG5cdFx0XHRcdG9wdGlvbnMub25DbGljay5jYWxsKG1lLCBlLm5hdGl2ZSwgbWUuYWN0aXZlKTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdC8vIFJlbW92ZSBzdHlsaW5nIGZvciBsYXN0IGFjdGl2ZSAoZXZlbiBpZiBpdCBtYXkgc3RpbGwgYmUgYWN0aXZlKVxyXG5cdFx0aWYgKG1lLmxhc3RBY3RpdmUubGVuZ3RoKSB7XHJcblx0XHRcdG1lLnVwZGF0ZUhvdmVyU3R5bGUobWUubGFzdEFjdGl2ZSwgaG92ZXJPcHRpb25zLm1vZGUsIGZhbHNlKTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBCdWlsdCBpbiBob3ZlciBzdHlsaW5nXHJcblx0XHRpZiAobWUuYWN0aXZlLmxlbmd0aCAmJiBob3Zlck9wdGlvbnMubW9kZSkge1xyXG5cdFx0XHRtZS51cGRhdGVIb3ZlclN0eWxlKG1lLmFjdGl2ZSwgaG92ZXJPcHRpb25zLm1vZGUsIHRydWUpO1xyXG5cdFx0fVxyXG5cclxuXHRcdGNoYW5nZWQgPSAhaGVscGVycyQxLmFycmF5RXF1YWxzKG1lLmFjdGl2ZSwgbWUubGFzdEFjdGl2ZSk7XHJcblxyXG5cdFx0Ly8gUmVtZW1iZXIgTGFzdCBBY3RpdmVzXHJcblx0XHRtZS5sYXN0QWN0aXZlID0gbWUuYWN0aXZlO1xyXG5cclxuXHRcdHJldHVybiBjaGFuZ2VkO1xyXG5cdH1cclxufSk7XHJcblxyXG4vKipcclxuICogTk9URShTQikgV2UgYWN0dWFsbHkgZG9uJ3QgdXNlIHRoaXMgY29udGFpbmVyIGFueW1vcmUgYnV0IHdlIG5lZWQgdG8ga2VlcCBpdFxyXG4gKiBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eS4gVGhvdWdoLCBpdCBjYW4gc3RpbGwgYmUgdXNlZnVsIGZvciBwbHVnaW5zIHRoYXRcclxuICogd291bGQgbmVlZCB0byB3b3JrIG9uIG11bHRpcGxlIGNoYXJ0cz8hXHJcbiAqL1xyXG5DaGFydC5pbnN0YW5jZXMgPSB7fTtcclxuXHJcbnZhciBjb3JlX2NvbnRyb2xsZXIgPSBDaGFydDtcclxuXHJcbi8vIERFUFJFQ0FUSU9OU1xyXG5cclxuLyoqXHJcbiAqIFByb3ZpZGVkIGZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5LCB1c2UgQ2hhcnQgaW5zdGVhZC5cclxuICogQGNsYXNzIENoYXJ0LkNvbnRyb2xsZXJcclxuICogQGRlcHJlY2F0ZWQgc2luY2UgdmVyc2lvbiAyLjZcclxuICogQHRvZG8gcmVtb3ZlIGF0IHZlcnNpb24gM1xyXG4gKiBAcHJpdmF0ZVxyXG4gKi9cclxuQ2hhcnQuQ29udHJvbGxlciA9IENoYXJ0O1xyXG5cclxuLyoqXHJcbiAqIFByb3ZpZGVkIGZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5LCBub3QgYXZhaWxhYmxlIGFueW1vcmUuXHJcbiAqIEBuYW1lc3BhY2UgQ2hhcnRcclxuICogQGRlcHJlY2F0ZWQgc2luY2UgdmVyc2lvbiAyLjhcclxuICogQHRvZG8gcmVtb3ZlIGF0IHZlcnNpb24gM1xyXG4gKiBAcHJpdmF0ZVxyXG4gKi9cclxuQ2hhcnQudHlwZXMgPSB7fTtcclxuXHJcbi8qKlxyXG4gKiBQcm92aWRlZCBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSwgbm90IGF2YWlsYWJsZSBhbnltb3JlLlxyXG4gKiBAbmFtZXNwYWNlIENoYXJ0LmhlbHBlcnMuY29uZmlnTWVyZ2VcclxuICogQGRlcHJlY2F0ZWQgc2luY2UgdmVyc2lvbiAyLjguMFxyXG4gKiBAdG9kbyByZW1vdmUgYXQgdmVyc2lvbiAzXHJcbiAqIEBwcml2YXRlXHJcbiAqL1xyXG5oZWxwZXJzJDEuY29uZmlnTWVyZ2UgPSBtZXJnZUNvbmZpZztcclxuXHJcbi8qKlxyXG4gKiBQcm92aWRlZCBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSwgbm90IGF2YWlsYWJsZSBhbnltb3JlLlxyXG4gKiBAbmFtZXNwYWNlIENoYXJ0LmhlbHBlcnMuc2NhbGVNZXJnZVxyXG4gKiBAZGVwcmVjYXRlZCBzaW5jZSB2ZXJzaW9uIDIuOC4wXHJcbiAqIEB0b2RvIHJlbW92ZSBhdCB2ZXJzaW9uIDNcclxuICogQHByaXZhdGVcclxuICovXHJcbmhlbHBlcnMkMS5zY2FsZU1lcmdlID0gbWVyZ2VTY2FsZUNvbmZpZztcblxudmFyIGNvcmVfaGVscGVycyA9IGZ1bmN0aW9uKCkge1xyXG5cclxuXHQvLyAtLSBCYXNpYyBqcyB1dGlsaXR5IG1ldGhvZHNcclxuXHJcblx0aGVscGVycyQxLndoZXJlID0gZnVuY3Rpb24oY29sbGVjdGlvbiwgZmlsdGVyQ2FsbGJhY2spIHtcclxuXHRcdGlmIChoZWxwZXJzJDEuaXNBcnJheShjb2xsZWN0aW9uKSAmJiBBcnJheS5wcm90b3R5cGUuZmlsdGVyKSB7XHJcblx0XHRcdHJldHVybiBjb2xsZWN0aW9uLmZpbHRlcihmaWx0ZXJDYWxsYmFjayk7XHJcblx0XHR9XHJcblx0XHR2YXIgZmlsdGVyZWQgPSBbXTtcclxuXHJcblx0XHRoZWxwZXJzJDEuZWFjaChjb2xsZWN0aW9uLCBmdW5jdGlvbihpdGVtKSB7XHJcblx0XHRcdGlmIChmaWx0ZXJDYWxsYmFjayhpdGVtKSkge1xyXG5cdFx0XHRcdGZpbHRlcmVkLnB1c2goaXRlbSk7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cclxuXHRcdHJldHVybiBmaWx0ZXJlZDtcclxuXHR9O1xyXG5cdGhlbHBlcnMkMS5maW5kSW5kZXggPSBBcnJheS5wcm90b3R5cGUuZmluZEluZGV4ID9cclxuXHRcdGZ1bmN0aW9uKGFycmF5LCBjYWxsYmFjaywgc2NvcGUpIHtcclxuXHRcdFx0cmV0dXJuIGFycmF5LmZpbmRJbmRleChjYWxsYmFjaywgc2NvcGUpO1xyXG5cdFx0fSA6XHJcblx0XHRmdW5jdGlvbihhcnJheSwgY2FsbGJhY2ssIHNjb3BlKSB7XHJcblx0XHRcdHNjb3BlID0gc2NvcGUgPT09IHVuZGVmaW5lZCA/IGFycmF5IDogc2NvcGU7XHJcblx0XHRcdGZvciAodmFyIGkgPSAwLCBpbGVuID0gYXJyYXkubGVuZ3RoOyBpIDwgaWxlbjsgKytpKSB7XHJcblx0XHRcdFx0aWYgKGNhbGxiYWNrLmNhbGwoc2NvcGUsIGFycmF5W2ldLCBpLCBhcnJheSkpIHtcclxuXHRcdFx0XHRcdHJldHVybiBpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0XHRyZXR1cm4gLTE7XHJcblx0XHR9O1xyXG5cdGhlbHBlcnMkMS5maW5kTmV4dFdoZXJlID0gZnVuY3Rpb24oYXJyYXlUb1NlYXJjaCwgZmlsdGVyQ2FsbGJhY2ssIHN0YXJ0SW5kZXgpIHtcclxuXHRcdC8vIERlZmF1bHQgdG8gc3RhcnQgb2YgdGhlIGFycmF5XHJcblx0XHRpZiAoaGVscGVycyQxLmlzTnVsbE9yVW5kZWYoc3RhcnRJbmRleCkpIHtcclxuXHRcdFx0c3RhcnRJbmRleCA9IC0xO1xyXG5cdFx0fVxyXG5cdFx0Zm9yICh2YXIgaSA9IHN0YXJ0SW5kZXggKyAxOyBpIDwgYXJyYXlUb1NlYXJjaC5sZW5ndGg7IGkrKykge1xyXG5cdFx0XHR2YXIgY3VycmVudEl0ZW0gPSBhcnJheVRvU2VhcmNoW2ldO1xyXG5cdFx0XHRpZiAoZmlsdGVyQ2FsbGJhY2soY3VycmVudEl0ZW0pKSB7XHJcblx0XHRcdFx0cmV0dXJuIGN1cnJlbnRJdGVtO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0fTtcclxuXHRoZWxwZXJzJDEuZmluZFByZXZpb3VzV2hlcmUgPSBmdW5jdGlvbihhcnJheVRvU2VhcmNoLCBmaWx0ZXJDYWxsYmFjaywgc3RhcnRJbmRleCkge1xyXG5cdFx0Ly8gRGVmYXVsdCB0byBlbmQgb2YgdGhlIGFycmF5XHJcblx0XHRpZiAoaGVscGVycyQxLmlzTnVsbE9yVW5kZWYoc3RhcnRJbmRleCkpIHtcclxuXHRcdFx0c3RhcnRJbmRleCA9IGFycmF5VG9TZWFyY2gubGVuZ3RoO1xyXG5cdFx0fVxyXG5cdFx0Zm9yICh2YXIgaSA9IHN0YXJ0SW5kZXggLSAxOyBpID49IDA7IGktLSkge1xyXG5cdFx0XHR2YXIgY3VycmVudEl0ZW0gPSBhcnJheVRvU2VhcmNoW2ldO1xyXG5cdFx0XHRpZiAoZmlsdGVyQ2FsbGJhY2soY3VycmVudEl0ZW0pKSB7XHJcblx0XHRcdFx0cmV0dXJuIGN1cnJlbnRJdGVtO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0fTtcclxuXHJcblx0Ly8gLS0gTWF0aCBtZXRob2RzXHJcblx0aGVscGVycyQxLmlzTnVtYmVyID0gZnVuY3Rpb24obikge1xyXG5cdFx0cmV0dXJuICFpc05hTihwYXJzZUZsb2F0KG4pKSAmJiBpc0Zpbml0ZShuKTtcclxuXHR9O1xyXG5cdGhlbHBlcnMkMS5hbG1vc3RFcXVhbHMgPSBmdW5jdGlvbih4LCB5LCBlcHNpbG9uKSB7XHJcblx0XHRyZXR1cm4gTWF0aC5hYnMoeCAtIHkpIDwgZXBzaWxvbjtcclxuXHR9O1xyXG5cdGhlbHBlcnMkMS5hbG1vc3RXaG9sZSA9IGZ1bmN0aW9uKHgsIGVwc2lsb24pIHtcclxuXHRcdHZhciByb3VuZGVkID0gTWF0aC5yb3VuZCh4KTtcclxuXHRcdHJldHVybiAoKHJvdW5kZWQgLSBlcHNpbG9uKSA8PSB4KSAmJiAoKHJvdW5kZWQgKyBlcHNpbG9uKSA+PSB4KTtcclxuXHR9O1xyXG5cdGhlbHBlcnMkMS5tYXggPSBmdW5jdGlvbihhcnJheSkge1xyXG5cdFx0cmV0dXJuIGFycmF5LnJlZHVjZShmdW5jdGlvbihtYXgsIHZhbHVlKSB7XHJcblx0XHRcdGlmICghaXNOYU4odmFsdWUpKSB7XHJcblx0XHRcdFx0cmV0dXJuIE1hdGgubWF4KG1heCwgdmFsdWUpO1xyXG5cdFx0XHR9XHJcblx0XHRcdHJldHVybiBtYXg7XHJcblx0XHR9LCBOdW1iZXIuTkVHQVRJVkVfSU5GSU5JVFkpO1xyXG5cdH07XHJcblx0aGVscGVycyQxLm1pbiA9IGZ1bmN0aW9uKGFycmF5KSB7XHJcblx0XHRyZXR1cm4gYXJyYXkucmVkdWNlKGZ1bmN0aW9uKG1pbiwgdmFsdWUpIHtcclxuXHRcdFx0aWYgKCFpc05hTih2YWx1ZSkpIHtcclxuXHRcdFx0XHRyZXR1cm4gTWF0aC5taW4obWluLCB2YWx1ZSk7XHJcblx0XHRcdH1cclxuXHRcdFx0cmV0dXJuIG1pbjtcclxuXHRcdH0sIE51bWJlci5QT1NJVElWRV9JTkZJTklUWSk7XHJcblx0fTtcclxuXHRoZWxwZXJzJDEuc2lnbiA9IE1hdGguc2lnbiA/XHJcblx0XHRmdW5jdGlvbih4KSB7XHJcblx0XHRcdHJldHVybiBNYXRoLnNpZ24oeCk7XHJcblx0XHR9IDpcclxuXHRcdGZ1bmN0aW9uKHgpIHtcclxuXHRcdFx0eCA9ICt4OyAvLyBjb252ZXJ0IHRvIGEgbnVtYmVyXHJcblx0XHRcdGlmICh4ID09PSAwIHx8IGlzTmFOKHgpKSB7XHJcblx0XHRcdFx0cmV0dXJuIHg7XHJcblx0XHRcdH1cclxuXHRcdFx0cmV0dXJuIHggPiAwID8gMSA6IC0xO1xyXG5cdFx0fTtcclxuXHRoZWxwZXJzJDEudG9SYWRpYW5zID0gZnVuY3Rpb24oZGVncmVlcykge1xyXG5cdFx0cmV0dXJuIGRlZ3JlZXMgKiAoTWF0aC5QSSAvIDE4MCk7XHJcblx0fTtcclxuXHRoZWxwZXJzJDEudG9EZWdyZWVzID0gZnVuY3Rpb24ocmFkaWFucykge1xyXG5cdFx0cmV0dXJuIHJhZGlhbnMgKiAoMTgwIC8gTWF0aC5QSSk7XHJcblx0fTtcclxuXHJcblx0LyoqXHJcblx0ICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGRlY2ltYWwgcGxhY2VzXHJcblx0ICogaS5lLiB0aGUgbnVtYmVyIG9mIGRpZ2l0cyBhZnRlciB0aGUgZGVjaW1hbCBwb2ludCwgb2YgdGhlIHZhbHVlIG9mIHRoaXMgTnVtYmVyLlxyXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSB4IC0gQSBudW1iZXIuXHJcblx0ICogQHJldHVybnMge251bWJlcn0gVGhlIG51bWJlciBvZiBkZWNpbWFsIHBsYWNlcy5cclxuXHQgKiBAcHJpdmF0ZVxyXG5cdCAqL1xyXG5cdGhlbHBlcnMkMS5fZGVjaW1hbFBsYWNlcyA9IGZ1bmN0aW9uKHgpIHtcclxuXHRcdGlmICghaGVscGVycyQxLmlzRmluaXRlKHgpKSB7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHRcdHZhciBlID0gMTtcclxuXHRcdHZhciBwID0gMDtcclxuXHRcdHdoaWxlIChNYXRoLnJvdW5kKHggKiBlKSAvIGUgIT09IHgpIHtcclxuXHRcdFx0ZSAqPSAxMDtcclxuXHRcdFx0cCsrO1xyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIHA7XHJcblx0fTtcclxuXHJcblx0Ly8gR2V0cyB0aGUgYW5nbGUgZnJvbSB2ZXJ0aWNhbCB1cHJpZ2h0IHRvIHRoZSBwb2ludCBhYm91dCBhIGNlbnRyZS5cclxuXHRoZWxwZXJzJDEuZ2V0QW5nbGVGcm9tUG9pbnQgPSBmdW5jdGlvbihjZW50cmVQb2ludCwgYW5nbGVQb2ludCkge1xyXG5cdFx0dmFyIGRpc3RhbmNlRnJvbVhDZW50ZXIgPSBhbmdsZVBvaW50LnggLSBjZW50cmVQb2ludC54O1xyXG5cdFx0dmFyIGRpc3RhbmNlRnJvbVlDZW50ZXIgPSBhbmdsZVBvaW50LnkgLSBjZW50cmVQb2ludC55O1xyXG5cdFx0dmFyIHJhZGlhbERpc3RhbmNlRnJvbUNlbnRlciA9IE1hdGguc3FydChkaXN0YW5jZUZyb21YQ2VudGVyICogZGlzdGFuY2VGcm9tWENlbnRlciArIGRpc3RhbmNlRnJvbVlDZW50ZXIgKiBkaXN0YW5jZUZyb21ZQ2VudGVyKTtcclxuXHJcblx0XHR2YXIgYW5nbGUgPSBNYXRoLmF0YW4yKGRpc3RhbmNlRnJvbVlDZW50ZXIsIGRpc3RhbmNlRnJvbVhDZW50ZXIpO1xyXG5cclxuXHRcdGlmIChhbmdsZSA8ICgtMC41ICogTWF0aC5QSSkpIHtcclxuXHRcdFx0YW5nbGUgKz0gMi4wICogTWF0aC5QSTsgLy8gbWFrZSBzdXJlIHRoZSByZXR1cm5lZCBhbmdsZSBpcyBpbiB0aGUgcmFuZ2Ugb2YgKC1QSS8yLCAzUEkvMl1cclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4ge1xyXG5cdFx0XHRhbmdsZTogYW5nbGUsXHJcblx0XHRcdGRpc3RhbmNlOiByYWRpYWxEaXN0YW5jZUZyb21DZW50ZXJcclxuXHRcdH07XHJcblx0fTtcclxuXHRoZWxwZXJzJDEuZGlzdGFuY2VCZXR3ZWVuUG9pbnRzID0gZnVuY3Rpb24ocHQxLCBwdDIpIHtcclxuXHRcdHJldHVybiBNYXRoLnNxcnQoTWF0aC5wb3cocHQyLnggLSBwdDEueCwgMikgKyBNYXRoLnBvdyhwdDIueSAtIHB0MS55LCAyKSk7XHJcblx0fTtcclxuXHJcblx0LyoqXHJcblx0ICogUHJvdmlkZWQgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHksIG5vdCBhdmFpbGFibGUgYW55bW9yZVxyXG5cdCAqIEBmdW5jdGlvbiBDaGFydC5oZWxwZXJzLmFsaWFzUGl4ZWxcclxuXHQgKiBAZGVwcmVjYXRlZCBzaW5jZSB2ZXJzaW9uIDIuOC4wXHJcblx0ICogQHRvZG8gcmVtb3ZlIGF0IHZlcnNpb24gM1xyXG5cdCAqL1xyXG5cdGhlbHBlcnMkMS5hbGlhc1BpeGVsID0gZnVuY3Rpb24ocGl4ZWxXaWR0aCkge1xyXG5cdFx0cmV0dXJuIChwaXhlbFdpZHRoICUgMiA9PT0gMCkgPyAwIDogMC41O1xyXG5cdH07XHJcblxyXG5cdC8qKlxyXG5cdCAqIFJldHVybnMgdGhlIGFsaWduZWQgcGl4ZWwgdmFsdWUgdG8gYXZvaWQgYW50aS1hbGlhc2luZyBibHVyXHJcblx0ICogQHBhcmFtIHtDaGFydH0gY2hhcnQgLSBUaGUgY2hhcnQgaW5zdGFuY2UuXHJcblx0ICogQHBhcmFtIHtudW1iZXJ9IHBpeGVsIC0gQSBwaXhlbCB2YWx1ZS5cclxuXHQgKiBAcGFyYW0ge251bWJlcn0gd2lkdGggLSBUaGUgd2lkdGggb2YgdGhlIGVsZW1lbnQuXHJcblx0ICogQHJldHVybnMge251bWJlcn0gVGhlIGFsaWduZWQgcGl4ZWwgdmFsdWUuXHJcblx0ICogQHByaXZhdGVcclxuXHQgKi9cclxuXHRoZWxwZXJzJDEuX2FsaWduUGl4ZWwgPSBmdW5jdGlvbihjaGFydCwgcGl4ZWwsIHdpZHRoKSB7XHJcblx0XHR2YXIgZGV2aWNlUGl4ZWxSYXRpbyA9IGNoYXJ0LmN1cnJlbnREZXZpY2VQaXhlbFJhdGlvO1xyXG5cdFx0dmFyIGhhbGZXaWR0aCA9IHdpZHRoIC8gMjtcclxuXHRcdHJldHVybiBNYXRoLnJvdW5kKChwaXhlbCAtIGhhbGZXaWR0aCkgKiBkZXZpY2VQaXhlbFJhdGlvKSAvIGRldmljZVBpeGVsUmF0aW8gKyBoYWxmV2lkdGg7XHJcblx0fTtcclxuXHJcblx0aGVscGVycyQxLnNwbGluZUN1cnZlID0gZnVuY3Rpb24oZmlyc3RQb2ludCwgbWlkZGxlUG9pbnQsIGFmdGVyUG9pbnQsIHQpIHtcclxuXHRcdC8vIFByb3BzIHRvIFJvYiBTcGVuY2VyIGF0IHNjYWxlZCBpbm5vdmF0aW9uIGZvciBoaXMgcG9zdCBvbiBzcGxpbmluZyBiZXR3ZWVuIHBvaW50c1xyXG5cdFx0Ly8gaHR0cDovL3NjYWxlZGlubm92YXRpb24uY29tL2FuYWx5dGljcy9zcGxpbmVzL2Fib3V0U3BsaW5lcy5odG1sXHJcblxyXG5cdFx0Ly8gVGhpcyBmdW5jdGlvbiBtdXN0IGFsc28gcmVzcGVjdCBcInNraXBwZWRcIiBwb2ludHNcclxuXHJcblx0XHR2YXIgcHJldmlvdXMgPSBmaXJzdFBvaW50LnNraXAgPyBtaWRkbGVQb2ludCA6IGZpcnN0UG9pbnQ7XHJcblx0XHR2YXIgY3VycmVudCA9IG1pZGRsZVBvaW50O1xyXG5cdFx0dmFyIG5leHQgPSBhZnRlclBvaW50LnNraXAgPyBtaWRkbGVQb2ludCA6IGFmdGVyUG9pbnQ7XHJcblxyXG5cdFx0dmFyIGQwMSA9IE1hdGguc3FydChNYXRoLnBvdyhjdXJyZW50LnggLSBwcmV2aW91cy54LCAyKSArIE1hdGgucG93KGN1cnJlbnQueSAtIHByZXZpb3VzLnksIDIpKTtcclxuXHRcdHZhciBkMTIgPSBNYXRoLnNxcnQoTWF0aC5wb3cobmV4dC54IC0gY3VycmVudC54LCAyKSArIE1hdGgucG93KG5leHQueSAtIGN1cnJlbnQueSwgMikpO1xyXG5cclxuXHRcdHZhciBzMDEgPSBkMDEgLyAoZDAxICsgZDEyKTtcclxuXHRcdHZhciBzMTIgPSBkMTIgLyAoZDAxICsgZDEyKTtcclxuXHJcblx0XHQvLyBJZiBhbGwgcG9pbnRzIGFyZSB0aGUgc2FtZSwgczAxICYgczAyIHdpbGwgYmUgaW5mXHJcblx0XHRzMDEgPSBpc05hTihzMDEpID8gMCA6IHMwMTtcclxuXHRcdHMxMiA9IGlzTmFOKHMxMikgPyAwIDogczEyO1xyXG5cclxuXHRcdHZhciBmYSA9IHQgKiBzMDE7IC8vIHNjYWxpbmcgZmFjdG9yIGZvciB0cmlhbmdsZSBUYVxyXG5cdFx0dmFyIGZiID0gdCAqIHMxMjtcclxuXHJcblx0XHRyZXR1cm4ge1xyXG5cdFx0XHRwcmV2aW91czoge1xyXG5cdFx0XHRcdHg6IGN1cnJlbnQueCAtIGZhICogKG5leHQueCAtIHByZXZpb3VzLngpLFxyXG5cdFx0XHRcdHk6IGN1cnJlbnQueSAtIGZhICogKG5leHQueSAtIHByZXZpb3VzLnkpXHJcblx0XHRcdH0sXHJcblx0XHRcdG5leHQ6IHtcclxuXHRcdFx0XHR4OiBjdXJyZW50LnggKyBmYiAqIChuZXh0LnggLSBwcmV2aW91cy54KSxcclxuXHRcdFx0XHR5OiBjdXJyZW50LnkgKyBmYiAqIChuZXh0LnkgLSBwcmV2aW91cy55KVxyXG5cdFx0XHR9XHJcblx0XHR9O1xyXG5cdH07XHJcblx0aGVscGVycyQxLkVQU0lMT04gPSBOdW1iZXIuRVBTSUxPTiB8fCAxZS0xNDtcclxuXHRoZWxwZXJzJDEuc3BsaW5lQ3VydmVNb25vdG9uZSA9IGZ1bmN0aW9uKHBvaW50cykge1xyXG5cdFx0Ly8gVGhpcyBmdW5jdGlvbiBjYWxjdWxhdGVzIELDqXppZXIgY29udHJvbCBwb2ludHMgaW4gYSBzaW1pbGFyIHdheSB0aGFuIHxzcGxpbmVDdXJ2ZXwsXHJcblx0XHQvLyBidXQgcHJlc2VydmVzIG1vbm90b25pY2l0eSBvZiB0aGUgcHJvdmlkZWQgZGF0YSBhbmQgZW5zdXJlcyBubyBsb2NhbCBleHRyZW11bXMgYXJlIGFkZGVkXHJcblx0XHQvLyBiZXR3ZWVuIHRoZSBkYXRhc2V0IGRpc2NyZXRlIHBvaW50cyBkdWUgdG8gdGhlIGludGVycG9sYXRpb24uXHJcblx0XHQvLyBTZWUgOiBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9Nb25vdG9uZV9jdWJpY19pbnRlcnBvbGF0aW9uXHJcblxyXG5cdFx0dmFyIHBvaW50c1dpdGhUYW5nZW50cyA9IChwb2ludHMgfHwgW10pLm1hcChmdW5jdGlvbihwb2ludCkge1xyXG5cdFx0XHRyZXR1cm4ge1xyXG5cdFx0XHRcdG1vZGVsOiBwb2ludC5fbW9kZWwsXHJcblx0XHRcdFx0ZGVsdGFLOiAwLFxyXG5cdFx0XHRcdG1LOiAwXHJcblx0XHRcdH07XHJcblx0XHR9KTtcclxuXHJcblx0XHQvLyBDYWxjdWxhdGUgc2xvcGVzIChkZWx0YUspIGFuZCBpbml0aWFsaXplIHRhbmdlbnRzIChtSylcclxuXHRcdHZhciBwb2ludHNMZW4gPSBwb2ludHNXaXRoVGFuZ2VudHMubGVuZ3RoO1xyXG5cdFx0dmFyIGksIHBvaW50QmVmb3JlLCBwb2ludEN1cnJlbnQsIHBvaW50QWZ0ZXI7XHJcblx0XHRmb3IgKGkgPSAwOyBpIDwgcG9pbnRzTGVuOyArK2kpIHtcclxuXHRcdFx0cG9pbnRDdXJyZW50ID0gcG9pbnRzV2l0aFRhbmdlbnRzW2ldO1xyXG5cdFx0XHRpZiAocG9pbnRDdXJyZW50Lm1vZGVsLnNraXApIHtcclxuXHRcdFx0XHRjb250aW51ZTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0cG9pbnRCZWZvcmUgPSBpID4gMCA/IHBvaW50c1dpdGhUYW5nZW50c1tpIC0gMV0gOiBudWxsO1xyXG5cdFx0XHRwb2ludEFmdGVyID0gaSA8IHBvaW50c0xlbiAtIDEgPyBwb2ludHNXaXRoVGFuZ2VudHNbaSArIDFdIDogbnVsbDtcclxuXHRcdFx0aWYgKHBvaW50QWZ0ZXIgJiYgIXBvaW50QWZ0ZXIubW9kZWwuc2tpcCkge1xyXG5cdFx0XHRcdHZhciBzbG9wZURlbHRhWCA9IChwb2ludEFmdGVyLm1vZGVsLnggLSBwb2ludEN1cnJlbnQubW9kZWwueCk7XHJcblxyXG5cdFx0XHRcdC8vIEluIHRoZSBjYXNlIG9mIHR3byBwb2ludHMgdGhhdCBhcHBlYXIgYXQgdGhlIHNhbWUgeCBwaXhlbCwgc2xvcGVEZWx0YVggaXMgMFxyXG5cdFx0XHRcdHBvaW50Q3VycmVudC5kZWx0YUsgPSBzbG9wZURlbHRhWCAhPT0gMCA/IChwb2ludEFmdGVyLm1vZGVsLnkgLSBwb2ludEN1cnJlbnQubW9kZWwueSkgLyBzbG9wZURlbHRhWCA6IDA7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdGlmICghcG9pbnRCZWZvcmUgfHwgcG9pbnRCZWZvcmUubW9kZWwuc2tpcCkge1xyXG5cdFx0XHRcdHBvaW50Q3VycmVudC5tSyA9IHBvaW50Q3VycmVudC5kZWx0YUs7XHJcblx0XHRcdH0gZWxzZSBpZiAoIXBvaW50QWZ0ZXIgfHwgcG9pbnRBZnRlci5tb2RlbC5za2lwKSB7XHJcblx0XHRcdFx0cG9pbnRDdXJyZW50Lm1LID0gcG9pbnRCZWZvcmUuZGVsdGFLO1xyXG5cdFx0XHR9IGVsc2UgaWYgKHRoaXMuc2lnbihwb2ludEJlZm9yZS5kZWx0YUspICE9PSB0aGlzLnNpZ24ocG9pbnRDdXJyZW50LmRlbHRhSykpIHtcclxuXHRcdFx0XHRwb2ludEN1cnJlbnQubUsgPSAwO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdHBvaW50Q3VycmVudC5tSyA9IChwb2ludEJlZm9yZS5kZWx0YUsgKyBwb2ludEN1cnJlbnQuZGVsdGFLKSAvIDI7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHQvLyBBZGp1c3QgdGFuZ2VudHMgdG8gZW5zdXJlIG1vbm90b25pYyBwcm9wZXJ0aWVzXHJcblx0XHR2YXIgYWxwaGFLLCBiZXRhSywgdGF1Sywgc3F1YXJlZE1hZ25pdHVkZTtcclxuXHRcdGZvciAoaSA9IDA7IGkgPCBwb2ludHNMZW4gLSAxOyArK2kpIHtcclxuXHRcdFx0cG9pbnRDdXJyZW50ID0gcG9pbnRzV2l0aFRhbmdlbnRzW2ldO1xyXG5cdFx0XHRwb2ludEFmdGVyID0gcG9pbnRzV2l0aFRhbmdlbnRzW2kgKyAxXTtcclxuXHRcdFx0aWYgKHBvaW50Q3VycmVudC5tb2RlbC5za2lwIHx8IHBvaW50QWZ0ZXIubW9kZWwuc2tpcCkge1xyXG5cdFx0XHRcdGNvbnRpbnVlO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRpZiAoaGVscGVycyQxLmFsbW9zdEVxdWFscyhwb2ludEN1cnJlbnQuZGVsdGFLLCAwLCB0aGlzLkVQU0lMT04pKSB7XHJcblx0XHRcdFx0cG9pbnRDdXJyZW50Lm1LID0gcG9pbnRBZnRlci5tSyA9IDA7XHJcblx0XHRcdFx0Y29udGludWU7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdGFscGhhSyA9IHBvaW50Q3VycmVudC5tSyAvIHBvaW50Q3VycmVudC5kZWx0YUs7XHJcblx0XHRcdGJldGFLID0gcG9pbnRBZnRlci5tSyAvIHBvaW50Q3VycmVudC5kZWx0YUs7XHJcblx0XHRcdHNxdWFyZWRNYWduaXR1ZGUgPSBNYXRoLnBvdyhhbHBoYUssIDIpICsgTWF0aC5wb3coYmV0YUssIDIpO1xyXG5cdFx0XHRpZiAoc3F1YXJlZE1hZ25pdHVkZSA8PSA5KSB7XHJcblx0XHRcdFx0Y29udGludWU7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdHRhdUsgPSAzIC8gTWF0aC5zcXJ0KHNxdWFyZWRNYWduaXR1ZGUpO1xyXG5cdFx0XHRwb2ludEN1cnJlbnQubUsgPSBhbHBoYUsgKiB0YXVLICogcG9pbnRDdXJyZW50LmRlbHRhSztcclxuXHRcdFx0cG9pbnRBZnRlci5tSyA9IGJldGFLICogdGF1SyAqIHBvaW50Q3VycmVudC5kZWx0YUs7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gQ29tcHV0ZSBjb250cm9sIHBvaW50c1xyXG5cdFx0dmFyIGRlbHRhWDtcclxuXHRcdGZvciAoaSA9IDA7IGkgPCBwb2ludHNMZW47ICsraSkge1xyXG5cdFx0XHRwb2ludEN1cnJlbnQgPSBwb2ludHNXaXRoVGFuZ2VudHNbaV07XHJcblx0XHRcdGlmIChwb2ludEN1cnJlbnQubW9kZWwuc2tpcCkge1xyXG5cdFx0XHRcdGNvbnRpbnVlO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRwb2ludEJlZm9yZSA9IGkgPiAwID8gcG9pbnRzV2l0aFRhbmdlbnRzW2kgLSAxXSA6IG51bGw7XHJcblx0XHRcdHBvaW50QWZ0ZXIgPSBpIDwgcG9pbnRzTGVuIC0gMSA/IHBvaW50c1dpdGhUYW5nZW50c1tpICsgMV0gOiBudWxsO1xyXG5cdFx0XHRpZiAocG9pbnRCZWZvcmUgJiYgIXBvaW50QmVmb3JlLm1vZGVsLnNraXApIHtcclxuXHRcdFx0XHRkZWx0YVggPSAocG9pbnRDdXJyZW50Lm1vZGVsLnggLSBwb2ludEJlZm9yZS5tb2RlbC54KSAvIDM7XHJcblx0XHRcdFx0cG9pbnRDdXJyZW50Lm1vZGVsLmNvbnRyb2xQb2ludFByZXZpb3VzWCA9IHBvaW50Q3VycmVudC5tb2RlbC54IC0gZGVsdGFYO1xyXG5cdFx0XHRcdHBvaW50Q3VycmVudC5tb2RlbC5jb250cm9sUG9pbnRQcmV2aW91c1kgPSBwb2ludEN1cnJlbnQubW9kZWwueSAtIGRlbHRhWCAqIHBvaW50Q3VycmVudC5tSztcclxuXHRcdFx0fVxyXG5cdFx0XHRpZiAocG9pbnRBZnRlciAmJiAhcG9pbnRBZnRlci5tb2RlbC5za2lwKSB7XHJcblx0XHRcdFx0ZGVsdGFYID0gKHBvaW50QWZ0ZXIubW9kZWwueCAtIHBvaW50Q3VycmVudC5tb2RlbC54KSAvIDM7XHJcblx0XHRcdFx0cG9pbnRDdXJyZW50Lm1vZGVsLmNvbnRyb2xQb2ludE5leHRYID0gcG9pbnRDdXJyZW50Lm1vZGVsLnggKyBkZWx0YVg7XHJcblx0XHRcdFx0cG9pbnRDdXJyZW50Lm1vZGVsLmNvbnRyb2xQb2ludE5leHRZID0gcG9pbnRDdXJyZW50Lm1vZGVsLnkgKyBkZWx0YVggKiBwb2ludEN1cnJlbnQubUs7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHR9O1xyXG5cdGhlbHBlcnMkMS5uZXh0SXRlbSA9IGZ1bmN0aW9uKGNvbGxlY3Rpb24sIGluZGV4LCBsb29wKSB7XHJcblx0XHRpZiAobG9vcCkge1xyXG5cdFx0XHRyZXR1cm4gaW5kZXggPj0gY29sbGVjdGlvbi5sZW5ndGggLSAxID8gY29sbGVjdGlvblswXSA6IGNvbGxlY3Rpb25baW5kZXggKyAxXTtcclxuXHRcdH1cclxuXHRcdHJldHVybiBpbmRleCA+PSBjb2xsZWN0aW9uLmxlbmd0aCAtIDEgPyBjb2xsZWN0aW9uW2NvbGxlY3Rpb24ubGVuZ3RoIC0gMV0gOiBjb2xsZWN0aW9uW2luZGV4ICsgMV07XHJcblx0fTtcclxuXHRoZWxwZXJzJDEucHJldmlvdXNJdGVtID0gZnVuY3Rpb24oY29sbGVjdGlvbiwgaW5kZXgsIGxvb3ApIHtcclxuXHRcdGlmIChsb29wKSB7XHJcblx0XHRcdHJldHVybiBpbmRleCA8PSAwID8gY29sbGVjdGlvbltjb2xsZWN0aW9uLmxlbmd0aCAtIDFdIDogY29sbGVjdGlvbltpbmRleCAtIDFdO1xyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIGluZGV4IDw9IDAgPyBjb2xsZWN0aW9uWzBdIDogY29sbGVjdGlvbltpbmRleCAtIDFdO1xyXG5cdH07XHJcblx0Ly8gSW1wbGVtZW50YXRpb24gb2YgdGhlIG5pY2UgbnVtYmVyIGFsZ29yaXRobSB1c2VkIGluIGRldGVybWluaW5nIHdoZXJlIGF4aXMgbGFiZWxzIHdpbGwgZ29cclxuXHRoZWxwZXJzJDEubmljZU51bSA9IGZ1bmN0aW9uKHJhbmdlLCByb3VuZCkge1xyXG5cdFx0dmFyIGV4cG9uZW50ID0gTWF0aC5mbG9vcihoZWxwZXJzJDEubG9nMTAocmFuZ2UpKTtcclxuXHRcdHZhciBmcmFjdGlvbiA9IHJhbmdlIC8gTWF0aC5wb3coMTAsIGV4cG9uZW50KTtcclxuXHRcdHZhciBuaWNlRnJhY3Rpb247XHJcblxyXG5cdFx0aWYgKHJvdW5kKSB7XHJcblx0XHRcdGlmIChmcmFjdGlvbiA8IDEuNSkge1xyXG5cdFx0XHRcdG5pY2VGcmFjdGlvbiA9IDE7XHJcblx0XHRcdH0gZWxzZSBpZiAoZnJhY3Rpb24gPCAzKSB7XHJcblx0XHRcdFx0bmljZUZyYWN0aW9uID0gMjtcclxuXHRcdFx0fSBlbHNlIGlmIChmcmFjdGlvbiA8IDcpIHtcclxuXHRcdFx0XHRuaWNlRnJhY3Rpb24gPSA1O1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdG5pY2VGcmFjdGlvbiA9IDEwO1xyXG5cdFx0XHR9XHJcblx0XHR9IGVsc2UgaWYgKGZyYWN0aW9uIDw9IDEuMCkge1xyXG5cdFx0XHRuaWNlRnJhY3Rpb24gPSAxO1xyXG5cdFx0fSBlbHNlIGlmIChmcmFjdGlvbiA8PSAyKSB7XHJcblx0XHRcdG5pY2VGcmFjdGlvbiA9IDI7XHJcblx0XHR9IGVsc2UgaWYgKGZyYWN0aW9uIDw9IDUpIHtcclxuXHRcdFx0bmljZUZyYWN0aW9uID0gNTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdG5pY2VGcmFjdGlvbiA9IDEwO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiBuaWNlRnJhY3Rpb24gKiBNYXRoLnBvdygxMCwgZXhwb25lbnQpO1xyXG5cdH07XHJcblx0Ly8gUmVxdWVzdCBhbmltYXRpb24gcG9seWZpbGwgLSBodHRwczovL3d3dy5wYXVsaXJpc2guY29tLzIwMTEvcmVxdWVzdGFuaW1hdGlvbmZyYW1lLWZvci1zbWFydC1hbmltYXRpbmcvXHJcblx0aGVscGVycyQxLnJlcXVlc3RBbmltRnJhbWUgPSAoZnVuY3Rpb24oKSB7XHJcblx0XHRpZiAodHlwZW9mIHdpbmRvdyA9PT0gJ3VuZGVmaW5lZCcpIHtcclxuXHRcdFx0cmV0dXJuIGZ1bmN0aW9uKGNhbGxiYWNrKSB7XHJcblx0XHRcdFx0Y2FsbGJhY2soKTtcclxuXHRcdFx0fTtcclxuXHRcdH1cclxuXHRcdHJldHVybiB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lIHx8XHJcblx0XHRcdHdpbmRvdy53ZWJraXRSZXF1ZXN0QW5pbWF0aW9uRnJhbWUgfHxcclxuXHRcdFx0d2luZG93Lm1velJlcXVlc3RBbmltYXRpb25GcmFtZSB8fFxyXG5cdFx0XHR3aW5kb3cub1JlcXVlc3RBbmltYXRpb25GcmFtZSB8fFxyXG5cdFx0XHR3aW5kb3cubXNSZXF1ZXN0QW5pbWF0aW9uRnJhbWUgfHxcclxuXHRcdFx0ZnVuY3Rpb24oY2FsbGJhY2spIHtcclxuXHRcdFx0XHRyZXR1cm4gd2luZG93LnNldFRpbWVvdXQoY2FsbGJhY2ssIDEwMDAgLyA2MCk7XHJcblx0XHRcdH07XHJcblx0fSgpKTtcclxuXHQvLyAtLSBET00gbWV0aG9kc1xyXG5cdGhlbHBlcnMkMS5nZXRSZWxhdGl2ZVBvc2l0aW9uID0gZnVuY3Rpb24oZXZ0LCBjaGFydCkge1xyXG5cdFx0dmFyIG1vdXNlWCwgbW91c2VZO1xyXG5cdFx0dmFyIGUgPSBldnQub3JpZ2luYWxFdmVudCB8fCBldnQ7XHJcblx0XHR2YXIgY2FudmFzID0gZXZ0LnRhcmdldCB8fCBldnQuc3JjRWxlbWVudDtcclxuXHRcdHZhciBib3VuZGluZ1JlY3QgPSBjYW52YXMuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XHJcblxyXG5cdFx0dmFyIHRvdWNoZXMgPSBlLnRvdWNoZXM7XHJcblx0XHRpZiAodG91Y2hlcyAmJiB0b3VjaGVzLmxlbmd0aCA+IDApIHtcclxuXHRcdFx0bW91c2VYID0gdG91Y2hlc1swXS5jbGllbnRYO1xyXG5cdFx0XHRtb3VzZVkgPSB0b3VjaGVzWzBdLmNsaWVudFk7XHJcblxyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0bW91c2VYID0gZS5jbGllbnRYO1xyXG5cdFx0XHRtb3VzZVkgPSBlLmNsaWVudFk7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gU2NhbGUgbW91c2UgY29vcmRpbmF0ZXMgaW50byBjYW52YXMgY29vcmRpbmF0ZXNcclxuXHRcdC8vIGJ5IGZvbGxvd2luZyB0aGUgcGF0dGVybiBsYWlkIG91dCBieSAnamVycnlqJyBpbiB0aGUgY29tbWVudHMgb2ZcclxuXHRcdC8vIGh0dHBzOi8vd3d3Lmh0bWw1Y2FudmFzdHV0b3JpYWxzLmNvbS9hZHZhbmNlZC9odG1sNS1jYW52YXMtbW91c2UtY29vcmRpbmF0ZXMvXHJcblx0XHR2YXIgcGFkZGluZ0xlZnQgPSBwYXJzZUZsb2F0KGhlbHBlcnMkMS5nZXRTdHlsZShjYW52YXMsICdwYWRkaW5nLWxlZnQnKSk7XHJcblx0XHR2YXIgcGFkZGluZ1RvcCA9IHBhcnNlRmxvYXQoaGVscGVycyQxLmdldFN0eWxlKGNhbnZhcywgJ3BhZGRpbmctdG9wJykpO1xyXG5cdFx0dmFyIHBhZGRpbmdSaWdodCA9IHBhcnNlRmxvYXQoaGVscGVycyQxLmdldFN0eWxlKGNhbnZhcywgJ3BhZGRpbmctcmlnaHQnKSk7XHJcblx0XHR2YXIgcGFkZGluZ0JvdHRvbSA9IHBhcnNlRmxvYXQoaGVscGVycyQxLmdldFN0eWxlKGNhbnZhcywgJ3BhZGRpbmctYm90dG9tJykpO1xyXG5cdFx0dmFyIHdpZHRoID0gYm91bmRpbmdSZWN0LnJpZ2h0IC0gYm91bmRpbmdSZWN0LmxlZnQgLSBwYWRkaW5nTGVmdCAtIHBhZGRpbmdSaWdodDtcclxuXHRcdHZhciBoZWlnaHQgPSBib3VuZGluZ1JlY3QuYm90dG9tIC0gYm91bmRpbmdSZWN0LnRvcCAtIHBhZGRpbmdUb3AgLSBwYWRkaW5nQm90dG9tO1xyXG5cclxuXHRcdC8vIFdlIGRpdmlkZSBieSB0aGUgY3VycmVudCBkZXZpY2UgcGl4ZWwgcmF0aW8sIGJlY2F1c2UgdGhlIGNhbnZhcyBpcyBzY2FsZWQgdXAgYnkgdGhhdCBhbW91bnQgaW4gZWFjaCBkaXJlY3Rpb24uIEhvd2V2ZXJcclxuXHRcdC8vIHRoZSBiYWNrZW5kIG1vZGVsIGlzIGluIHVuc2NhbGVkIGNvb3JkaW5hdGVzLiBTaW5jZSB3ZSBhcmUgZ29pbmcgdG8gZGVhbCB3aXRoIG91ciBtb2RlbCBjb29yZGluYXRlcywgd2UgZ28gYmFjayBoZXJlXHJcblx0XHRtb3VzZVggPSBNYXRoLnJvdW5kKChtb3VzZVggLSBib3VuZGluZ1JlY3QubGVmdCAtIHBhZGRpbmdMZWZ0KSAvICh3aWR0aCkgKiBjYW52YXMud2lkdGggLyBjaGFydC5jdXJyZW50RGV2aWNlUGl4ZWxSYXRpbyk7XHJcblx0XHRtb3VzZVkgPSBNYXRoLnJvdW5kKChtb3VzZVkgLSBib3VuZGluZ1JlY3QudG9wIC0gcGFkZGluZ1RvcCkgLyAoaGVpZ2h0KSAqIGNhbnZhcy5oZWlnaHQgLyBjaGFydC5jdXJyZW50RGV2aWNlUGl4ZWxSYXRpbyk7XHJcblxyXG5cdFx0cmV0dXJuIHtcclxuXHRcdFx0eDogbW91c2VYLFxyXG5cdFx0XHR5OiBtb3VzZVlcclxuXHRcdH07XHJcblxyXG5cdH07XHJcblxyXG5cdC8vIFByaXZhdGUgaGVscGVyIGZ1bmN0aW9uIHRvIGNvbnZlcnQgbWF4LXdpZHRoL21heC1oZWlnaHQgdmFsdWVzIHRoYXQgbWF5IGJlIHBlcmNlbnRhZ2VzIGludG8gYSBudW1iZXJcclxuXHRmdW5jdGlvbiBwYXJzZU1heFN0eWxlKHN0eWxlVmFsdWUsIG5vZGUsIHBhcmVudFByb3BlcnR5KSB7XHJcblx0XHR2YXIgdmFsdWVJblBpeGVscztcclxuXHRcdGlmICh0eXBlb2Ygc3R5bGVWYWx1ZSA9PT0gJ3N0cmluZycpIHtcclxuXHRcdFx0dmFsdWVJblBpeGVscyA9IHBhcnNlSW50KHN0eWxlVmFsdWUsIDEwKTtcclxuXHJcblx0XHRcdGlmIChzdHlsZVZhbHVlLmluZGV4T2YoJyUnKSAhPT0gLTEpIHtcclxuXHRcdFx0XHQvLyBwZXJjZW50YWdlICogc2l6ZSBpbiBkaW1lbnNpb25cclxuXHRcdFx0XHR2YWx1ZUluUGl4ZWxzID0gdmFsdWVJblBpeGVscyAvIDEwMCAqIG5vZGUucGFyZW50Tm9kZVtwYXJlbnRQcm9wZXJ0eV07XHJcblx0XHRcdH1cclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdHZhbHVlSW5QaXhlbHMgPSBzdHlsZVZhbHVlO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiB2YWx1ZUluUGl4ZWxzO1xyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0ICogUmV0dXJucyBpZiB0aGUgZ2l2ZW4gdmFsdWUgY29udGFpbnMgYW4gZWZmZWN0aXZlIGNvbnN0cmFpbnQuXHJcblx0ICogQHByaXZhdGVcclxuXHQgKi9cclxuXHRmdW5jdGlvbiBpc0NvbnN0cmFpbmVkVmFsdWUodmFsdWUpIHtcclxuXHRcdHJldHVybiB2YWx1ZSAhPT0gdW5kZWZpbmVkICYmIHZhbHVlICE9PSBudWxsICYmIHZhbHVlICE9PSAnbm9uZSc7XHJcblx0fVxyXG5cclxuXHQvKipcclxuXHQgKiBSZXR1cm5zIHRoZSBtYXggd2lkdGggb3IgaGVpZ2h0IG9mIHRoZSBnaXZlbiBET00gbm9kZSBpbiBhIGNyb3NzLWJyb3dzZXIgY29tcGF0aWJsZSBmYXNoaW9uXHJcblx0ICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZG9tTm9kZSAtIHRoZSBub2RlIHRvIGNoZWNrIHRoZSBjb25zdHJhaW50IG9uXHJcblx0ICogQHBhcmFtIHtzdHJpbmd9IG1heFN0eWxlIC0gdGhlIHN0eWxlIHRoYXQgZGVmaW5lcyB0aGUgbWF4aW11bSBmb3IgdGhlIGRpcmVjdGlvbiB3ZSBhcmUgdXNpbmcgKCdtYXgtd2lkdGgnIC8gJ21heC1oZWlnaHQnKVxyXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBwZXJjZW50YWdlUHJvcGVydHkgLSBwcm9wZXJ0eSBvZiBwYXJlbnQgdG8gdXNlIHdoZW4gY2FsY3VsYXRpbmcgd2lkdGggYXMgYSBwZXJjZW50YWdlXHJcblx0ICogQHNlZSB7QGxpbmsgaHR0cHM6Ly93d3cubmF0aGFuYWVsam9uZXMuY29tL2Jsb2cvMjAxMy9yZWFkaW5nLW1heC13aWR0aC1jcm9zcy1icm93c2VyfVxyXG5cdCAqL1xyXG5cdGZ1bmN0aW9uIGdldENvbnN0cmFpbnREaW1lbnNpb24oZG9tTm9kZSwgbWF4U3R5bGUsIHBlcmNlbnRhZ2VQcm9wZXJ0eSkge1xyXG5cdFx0dmFyIHZpZXcgPSBkb2N1bWVudC5kZWZhdWx0VmlldztcclxuXHRcdHZhciBwYXJlbnROb2RlID0gaGVscGVycyQxLl9nZXRQYXJlbnROb2RlKGRvbU5vZGUpO1xyXG5cdFx0dmFyIGNvbnN0cmFpbmVkTm9kZSA9IHZpZXcuZ2V0Q29tcHV0ZWRTdHlsZShkb21Ob2RlKVttYXhTdHlsZV07XHJcblx0XHR2YXIgY29uc3RyYWluZWRDb250YWluZXIgPSB2aWV3LmdldENvbXB1dGVkU3R5bGUocGFyZW50Tm9kZSlbbWF4U3R5bGVdO1xyXG5cdFx0dmFyIGhhc0NOb2RlID0gaXNDb25zdHJhaW5lZFZhbHVlKGNvbnN0cmFpbmVkTm9kZSk7XHJcblx0XHR2YXIgaGFzQ0NvbnRhaW5lciA9IGlzQ29uc3RyYWluZWRWYWx1ZShjb25zdHJhaW5lZENvbnRhaW5lcik7XHJcblx0XHR2YXIgaW5maW5pdHkgPSBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFk7XHJcblxyXG5cdFx0aWYgKGhhc0NOb2RlIHx8IGhhc0NDb250YWluZXIpIHtcclxuXHRcdFx0cmV0dXJuIE1hdGgubWluKFxyXG5cdFx0XHRcdGhhc0NOb2RlID8gcGFyc2VNYXhTdHlsZShjb25zdHJhaW5lZE5vZGUsIGRvbU5vZGUsIHBlcmNlbnRhZ2VQcm9wZXJ0eSkgOiBpbmZpbml0eSxcclxuXHRcdFx0XHRoYXNDQ29udGFpbmVyID8gcGFyc2VNYXhTdHlsZShjb25zdHJhaW5lZENvbnRhaW5lciwgcGFyZW50Tm9kZSwgcGVyY2VudGFnZVByb3BlcnR5KSA6IGluZmluaXR5KTtcclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gJ25vbmUnO1xyXG5cdH1cclxuXHQvLyByZXR1cm5zIE51bWJlciBvciB1bmRlZmluZWQgaWYgbm8gY29uc3RyYWludFxyXG5cdGhlbHBlcnMkMS5nZXRDb25zdHJhaW50V2lkdGggPSBmdW5jdGlvbihkb21Ob2RlKSB7XHJcblx0XHRyZXR1cm4gZ2V0Q29uc3RyYWludERpbWVuc2lvbihkb21Ob2RlLCAnbWF4LXdpZHRoJywgJ2NsaWVudFdpZHRoJyk7XHJcblx0fTtcclxuXHQvLyByZXR1cm5zIE51bWJlciBvciB1bmRlZmluZWQgaWYgbm8gY29uc3RyYWludFxyXG5cdGhlbHBlcnMkMS5nZXRDb25zdHJhaW50SGVpZ2h0ID0gZnVuY3Rpb24oZG9tTm9kZSkge1xyXG5cdFx0cmV0dXJuIGdldENvbnN0cmFpbnREaW1lbnNpb24oZG9tTm9kZSwgJ21heC1oZWlnaHQnLCAnY2xpZW50SGVpZ2h0Jyk7XHJcblx0fTtcclxuXHQvKipcclxuXHQgKiBAcHJpdmF0ZVxyXG4gXHQgKi9cclxuXHRoZWxwZXJzJDEuX2NhbGN1bGF0ZVBhZGRpbmcgPSBmdW5jdGlvbihjb250YWluZXIsIHBhZGRpbmcsIHBhcmVudERpbWVuc2lvbikge1xyXG5cdFx0cGFkZGluZyA9IGhlbHBlcnMkMS5nZXRTdHlsZShjb250YWluZXIsIHBhZGRpbmcpO1xyXG5cclxuXHRcdHJldHVybiBwYWRkaW5nLmluZGV4T2YoJyUnKSA+IC0xID8gcGFyZW50RGltZW5zaW9uICogcGFyc2VJbnQocGFkZGluZywgMTApIC8gMTAwIDogcGFyc2VJbnQocGFkZGluZywgMTApO1xyXG5cdH07XHJcblx0LyoqXHJcblx0ICogQHByaXZhdGVcclxuXHQgKi9cclxuXHRoZWxwZXJzJDEuX2dldFBhcmVudE5vZGUgPSBmdW5jdGlvbihkb21Ob2RlKSB7XHJcblx0XHR2YXIgcGFyZW50ID0gZG9tTm9kZS5wYXJlbnROb2RlO1xyXG5cdFx0aWYgKHBhcmVudCAmJiBwYXJlbnQudG9TdHJpbmcoKSA9PT0gJ1tvYmplY3QgU2hhZG93Um9vdF0nKSB7XHJcblx0XHRcdHBhcmVudCA9IHBhcmVudC5ob3N0O1xyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIHBhcmVudDtcclxuXHR9O1xyXG5cdGhlbHBlcnMkMS5nZXRNYXhpbXVtV2lkdGggPSBmdW5jdGlvbihkb21Ob2RlKSB7XHJcblx0XHR2YXIgY29udGFpbmVyID0gaGVscGVycyQxLl9nZXRQYXJlbnROb2RlKGRvbU5vZGUpO1xyXG5cdFx0aWYgKCFjb250YWluZXIpIHtcclxuXHRcdFx0cmV0dXJuIGRvbU5vZGUuY2xpZW50V2lkdGg7XHJcblx0XHR9XHJcblxyXG5cdFx0dmFyIGNsaWVudFdpZHRoID0gY29udGFpbmVyLmNsaWVudFdpZHRoO1xyXG5cdFx0dmFyIHBhZGRpbmdMZWZ0ID0gaGVscGVycyQxLl9jYWxjdWxhdGVQYWRkaW5nKGNvbnRhaW5lciwgJ3BhZGRpbmctbGVmdCcsIGNsaWVudFdpZHRoKTtcclxuXHRcdHZhciBwYWRkaW5nUmlnaHQgPSBoZWxwZXJzJDEuX2NhbGN1bGF0ZVBhZGRpbmcoY29udGFpbmVyLCAncGFkZGluZy1yaWdodCcsIGNsaWVudFdpZHRoKTtcclxuXHJcblx0XHR2YXIgdyA9IGNsaWVudFdpZHRoIC0gcGFkZGluZ0xlZnQgLSBwYWRkaW5nUmlnaHQ7XHJcblx0XHR2YXIgY3cgPSBoZWxwZXJzJDEuZ2V0Q29uc3RyYWludFdpZHRoKGRvbU5vZGUpO1xyXG5cdFx0cmV0dXJuIGlzTmFOKGN3KSA/IHcgOiBNYXRoLm1pbih3LCBjdyk7XHJcblx0fTtcclxuXHRoZWxwZXJzJDEuZ2V0TWF4aW11bUhlaWdodCA9IGZ1bmN0aW9uKGRvbU5vZGUpIHtcclxuXHRcdHZhciBjb250YWluZXIgPSBoZWxwZXJzJDEuX2dldFBhcmVudE5vZGUoZG9tTm9kZSk7XHJcblx0XHRpZiAoIWNvbnRhaW5lcikge1xyXG5cdFx0XHRyZXR1cm4gZG9tTm9kZS5jbGllbnRIZWlnaHQ7XHJcblx0XHR9XHJcblxyXG5cdFx0dmFyIGNsaWVudEhlaWdodCA9IGNvbnRhaW5lci5jbGllbnRIZWlnaHQ7XHJcblx0XHR2YXIgcGFkZGluZ1RvcCA9IGhlbHBlcnMkMS5fY2FsY3VsYXRlUGFkZGluZyhjb250YWluZXIsICdwYWRkaW5nLXRvcCcsIGNsaWVudEhlaWdodCk7XHJcblx0XHR2YXIgcGFkZGluZ0JvdHRvbSA9IGhlbHBlcnMkMS5fY2FsY3VsYXRlUGFkZGluZyhjb250YWluZXIsICdwYWRkaW5nLWJvdHRvbScsIGNsaWVudEhlaWdodCk7XHJcblxyXG5cdFx0dmFyIGggPSBjbGllbnRIZWlnaHQgLSBwYWRkaW5nVG9wIC0gcGFkZGluZ0JvdHRvbTtcclxuXHRcdHZhciBjaCA9IGhlbHBlcnMkMS5nZXRDb25zdHJhaW50SGVpZ2h0KGRvbU5vZGUpO1xyXG5cdFx0cmV0dXJuIGlzTmFOKGNoKSA/IGggOiBNYXRoLm1pbihoLCBjaCk7XHJcblx0fTtcclxuXHRoZWxwZXJzJDEuZ2V0U3R5bGUgPSBmdW5jdGlvbihlbCwgcHJvcGVydHkpIHtcclxuXHRcdHJldHVybiBlbC5jdXJyZW50U3R5bGUgP1xyXG5cdFx0XHRlbC5jdXJyZW50U3R5bGVbcHJvcGVydHldIDpcclxuXHRcdFx0ZG9jdW1lbnQuZGVmYXVsdFZpZXcuZ2V0Q29tcHV0ZWRTdHlsZShlbCwgbnVsbCkuZ2V0UHJvcGVydHlWYWx1ZShwcm9wZXJ0eSk7XHJcblx0fTtcclxuXHRoZWxwZXJzJDEucmV0aW5hU2NhbGUgPSBmdW5jdGlvbihjaGFydCwgZm9yY2VSYXRpbykge1xyXG5cdFx0dmFyIHBpeGVsUmF0aW8gPSBjaGFydC5jdXJyZW50RGV2aWNlUGl4ZWxSYXRpbyA9IGZvcmNlUmF0aW8gfHwgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnICYmIHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvKSB8fCAxO1xyXG5cdFx0aWYgKHBpeGVsUmF0aW8gPT09IDEpIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdHZhciBjYW52YXMgPSBjaGFydC5jYW52YXM7XHJcblx0XHR2YXIgaGVpZ2h0ID0gY2hhcnQuaGVpZ2h0O1xyXG5cdFx0dmFyIHdpZHRoID0gY2hhcnQud2lkdGg7XHJcblxyXG5cdFx0Y2FudmFzLmhlaWdodCA9IGhlaWdodCAqIHBpeGVsUmF0aW87XHJcblx0XHRjYW52YXMud2lkdGggPSB3aWR0aCAqIHBpeGVsUmF0aW87XHJcblx0XHRjaGFydC5jdHguc2NhbGUocGl4ZWxSYXRpbywgcGl4ZWxSYXRpbyk7XHJcblxyXG5cdFx0Ly8gSWYgbm8gc3R5bGUgaGFzIGJlZW4gc2V0IG9uIHRoZSBjYW52YXMsIHRoZSByZW5kZXIgc2l6ZSBpcyB1c2VkIGFzIGRpc3BsYXkgc2l6ZSxcclxuXHRcdC8vIG1ha2luZyB0aGUgY2hhcnQgdmlzdWFsbHkgYmlnZ2VyLCBzbyBsZXQncyBlbmZvcmNlIGl0IHRvIHRoZSBcImNvcnJlY3RcIiB2YWx1ZXMuXHJcblx0XHQvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2NoYXJ0anMvQ2hhcnQuanMvaXNzdWVzLzM1NzVcclxuXHRcdGlmICghY2FudmFzLnN0eWxlLmhlaWdodCAmJiAhY2FudmFzLnN0eWxlLndpZHRoKSB7XHJcblx0XHRcdGNhbnZhcy5zdHlsZS5oZWlnaHQgPSBoZWlnaHQgKyAncHgnO1xyXG5cdFx0XHRjYW52YXMuc3R5bGUud2lkdGggPSB3aWR0aCArICdweCc7XHJcblx0XHR9XHJcblx0fTtcclxuXHQvLyAtLSBDYW52YXMgbWV0aG9kc1xyXG5cdGhlbHBlcnMkMS5mb250U3RyaW5nID0gZnVuY3Rpb24ocGl4ZWxTaXplLCBmb250U3R5bGUsIGZvbnRGYW1pbHkpIHtcclxuXHRcdHJldHVybiBmb250U3R5bGUgKyAnICcgKyBwaXhlbFNpemUgKyAncHggJyArIGZvbnRGYW1pbHk7XHJcblx0fTtcclxuXHRoZWxwZXJzJDEubG9uZ2VzdFRleHQgPSBmdW5jdGlvbihjdHgsIGZvbnQsIGFycmF5T2ZUaGluZ3MsIGNhY2hlKSB7XHJcblx0XHRjYWNoZSA9IGNhY2hlIHx8IHt9O1xyXG5cdFx0dmFyIGRhdGEgPSBjYWNoZS5kYXRhID0gY2FjaGUuZGF0YSB8fCB7fTtcclxuXHRcdHZhciBnYyA9IGNhY2hlLmdhcmJhZ2VDb2xsZWN0ID0gY2FjaGUuZ2FyYmFnZUNvbGxlY3QgfHwgW107XHJcblxyXG5cdFx0aWYgKGNhY2hlLmZvbnQgIT09IGZvbnQpIHtcclxuXHRcdFx0ZGF0YSA9IGNhY2hlLmRhdGEgPSB7fTtcclxuXHRcdFx0Z2MgPSBjYWNoZS5nYXJiYWdlQ29sbGVjdCA9IFtdO1xyXG5cdFx0XHRjYWNoZS5mb250ID0gZm9udDtcclxuXHRcdH1cclxuXHJcblx0XHRjdHguZm9udCA9IGZvbnQ7XHJcblx0XHR2YXIgbG9uZ2VzdCA9IDA7XHJcblx0XHR2YXIgaWxlbiA9IGFycmF5T2ZUaGluZ3MubGVuZ3RoO1xyXG5cdFx0dmFyIGksIGosIGpsZW4sIHRoaW5nLCBuZXN0ZWRUaGluZztcclxuXHRcdGZvciAoaSA9IDA7IGkgPCBpbGVuOyBpKyspIHtcclxuXHRcdFx0dGhpbmcgPSBhcnJheU9mVGhpbmdzW2ldO1xyXG5cclxuXHRcdFx0Ly8gVW5kZWZpbmVkIHN0cmluZ3MgYW5kIGFycmF5cyBzaG91bGQgbm90IGJlIG1lYXN1cmVkXHJcblx0XHRcdGlmICh0aGluZyAhPT0gdW5kZWZpbmVkICYmIHRoaW5nICE9PSBudWxsICYmIGhlbHBlcnMkMS5pc0FycmF5KHRoaW5nKSAhPT0gdHJ1ZSkge1xyXG5cdFx0XHRcdGxvbmdlc3QgPSBoZWxwZXJzJDEubWVhc3VyZVRleHQoY3R4LCBkYXRhLCBnYywgbG9uZ2VzdCwgdGhpbmcpO1xyXG5cdFx0XHR9IGVsc2UgaWYgKGhlbHBlcnMkMS5pc0FycmF5KHRoaW5nKSkge1xyXG5cdFx0XHRcdC8vIGlmIGl0IGlzIGFuIGFycmF5IGxldHMgbWVhc3VyZSBlYWNoIGVsZW1lbnRcclxuXHRcdFx0XHQvLyB0byBkbyBtYXliZSBzaW1wbGlmeSB0aGlzIGZ1bmN0aW9uIGEgYml0IHNvIHdlIGNhbiBkbyB0aGlzIG1vcmUgcmVjdXJzaXZlbHk/XHJcblx0XHRcdFx0Zm9yIChqID0gMCwgamxlbiA9IHRoaW5nLmxlbmd0aDsgaiA8IGpsZW47IGorKykge1xyXG5cdFx0XHRcdFx0bmVzdGVkVGhpbmcgPSB0aGluZ1tqXTtcclxuXHRcdFx0XHRcdC8vIFVuZGVmaW5lZCBzdHJpbmdzIGFuZCBhcnJheXMgc2hvdWxkIG5vdCBiZSBtZWFzdXJlZFxyXG5cdFx0XHRcdFx0aWYgKG5lc3RlZFRoaW5nICE9PSB1bmRlZmluZWQgJiYgbmVzdGVkVGhpbmcgIT09IG51bGwgJiYgIWhlbHBlcnMkMS5pc0FycmF5KG5lc3RlZFRoaW5nKSkge1xyXG5cdFx0XHRcdFx0XHRsb25nZXN0ID0gaGVscGVycyQxLm1lYXN1cmVUZXh0KGN0eCwgZGF0YSwgZ2MsIGxvbmdlc3QsIG5lc3RlZFRoaW5nKTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHR2YXIgZ2NMZW4gPSBnYy5sZW5ndGggLyAyO1xyXG5cdFx0aWYgKGdjTGVuID4gYXJyYXlPZlRoaW5ncy5sZW5ndGgpIHtcclxuXHRcdFx0Zm9yIChpID0gMDsgaSA8IGdjTGVuOyBpKyspIHtcclxuXHRcdFx0XHRkZWxldGUgZGF0YVtnY1tpXV07XHJcblx0XHRcdH1cclxuXHRcdFx0Z2Muc3BsaWNlKDAsIGdjTGVuKTtcclxuXHRcdH1cclxuXHRcdHJldHVybiBsb25nZXN0O1xyXG5cdH07XHJcblx0aGVscGVycyQxLm1lYXN1cmVUZXh0ID0gZnVuY3Rpb24oY3R4LCBkYXRhLCBnYywgbG9uZ2VzdCwgc3RyaW5nKSB7XHJcblx0XHR2YXIgdGV4dFdpZHRoID0gZGF0YVtzdHJpbmddO1xyXG5cdFx0aWYgKCF0ZXh0V2lkdGgpIHtcclxuXHRcdFx0dGV4dFdpZHRoID0gZGF0YVtzdHJpbmddID0gY3R4Lm1lYXN1cmVUZXh0KHN0cmluZykud2lkdGg7XHJcblx0XHRcdGdjLnB1c2goc3RyaW5nKTtcclxuXHRcdH1cclxuXHRcdGlmICh0ZXh0V2lkdGggPiBsb25nZXN0KSB7XHJcblx0XHRcdGxvbmdlc3QgPSB0ZXh0V2lkdGg7XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gbG9uZ2VzdDtcclxuXHR9O1xyXG5cclxuXHQvKipcclxuXHQgKiBAZGVwcmVjYXRlZFxyXG5cdCAqL1xyXG5cdGhlbHBlcnMkMS5udW1iZXJPZkxhYmVsTGluZXMgPSBmdW5jdGlvbihhcnJheU9mVGhpbmdzKSB7XHJcblx0XHR2YXIgbnVtYmVyT2ZMaW5lcyA9IDE7XHJcblx0XHRoZWxwZXJzJDEuZWFjaChhcnJheU9mVGhpbmdzLCBmdW5jdGlvbih0aGluZykge1xyXG5cdFx0XHRpZiAoaGVscGVycyQxLmlzQXJyYXkodGhpbmcpKSB7XHJcblx0XHRcdFx0aWYgKHRoaW5nLmxlbmd0aCA+IG51bWJlck9mTGluZXMpIHtcclxuXHRcdFx0XHRcdG51bWJlck9mTGluZXMgPSB0aGluZy5sZW5ndGg7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHR9KTtcclxuXHRcdHJldHVybiBudW1iZXJPZkxpbmVzO1xyXG5cdH07XHJcblxyXG5cdGhlbHBlcnMkMS5jb2xvciA9ICFjaGFydGpzQ29sb3IgP1xyXG5cdFx0ZnVuY3Rpb24odmFsdWUpIHtcclxuXHRcdFx0Y29uc29sZS5lcnJvcignQ29sb3IuanMgbm90IGZvdW5kIScpO1xyXG5cdFx0XHRyZXR1cm4gdmFsdWU7XHJcblx0XHR9IDpcclxuXHRcdGZ1bmN0aW9uKHZhbHVlKSB7XHJcblx0XHRcdC8qIGdsb2JhbCBDYW52YXNHcmFkaWVudCAqL1xyXG5cdFx0XHRpZiAodmFsdWUgaW5zdGFuY2VvZiBDYW52YXNHcmFkaWVudCkge1xyXG5cdFx0XHRcdHZhbHVlID0gY29yZV9kZWZhdWx0cy5nbG9iYWwuZGVmYXVsdENvbG9yO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRyZXR1cm4gY2hhcnRqc0NvbG9yKHZhbHVlKTtcclxuXHRcdH07XHJcblxyXG5cdGhlbHBlcnMkMS5nZXRIb3ZlckNvbG9yID0gZnVuY3Rpb24oY29sb3JWYWx1ZSkge1xyXG5cdFx0LyogZ2xvYmFsIENhbnZhc1BhdHRlcm4gKi9cclxuXHRcdHJldHVybiAoY29sb3JWYWx1ZSBpbnN0YW5jZW9mIENhbnZhc1BhdHRlcm4gfHwgY29sb3JWYWx1ZSBpbnN0YW5jZW9mIENhbnZhc0dyYWRpZW50KSA/XHJcblx0XHRcdGNvbG9yVmFsdWUgOlxyXG5cdFx0XHRoZWxwZXJzJDEuY29sb3IoY29sb3JWYWx1ZSkuc2F0dXJhdGUoMC41KS5kYXJrZW4oMC4xKS5yZ2JTdHJpbmcoKTtcclxuXHR9O1xyXG59O1xuXG5mdW5jdGlvbiBhYnN0cmFjdCgpIHtcclxuXHR0aHJvdyBuZXcgRXJyb3IoXHJcblx0XHQnVGhpcyBtZXRob2QgaXMgbm90IGltcGxlbWVudGVkOiBlaXRoZXIgbm8gYWRhcHRlciBjYW4gJyArXHJcblx0XHQnYmUgZm91bmQgb3IgYW4gaW5jb21wbGV0ZSBpbnRlZ3JhdGlvbiB3YXMgcHJvdmlkZWQuJ1xyXG5cdCk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBEYXRlIGFkYXB0ZXIgKGN1cnJlbnQgdXNlZCBieSB0aGUgdGltZSBzY2FsZSlcclxuICogQG5hbWVzcGFjZSBDaGFydC5fYWRhcHRlcnMuX2RhdGVcclxuICogQG1lbWJlcm9mIENoYXJ0Ll9hZGFwdGVyc1xyXG4gKiBAcHJpdmF0ZVxyXG4gKi9cclxuXHJcbi8qKlxyXG4gKiBDdXJyZW50bHkgc3VwcG9ydGVkIHVuaXQgc3RyaW5nIHZhbHVlcy5cclxuICogQHR5cGVkZWYgeygnbWlsbGlzZWNvbmQnfCdzZWNvbmQnfCdtaW51dGUnfCdob3VyJ3wnZGF5J3wnd2Vlayd8J21vbnRoJ3wncXVhcnRlcid8J3llYXInKX1cclxuICogQG1lbWJlcm9mIENoYXJ0Ll9hZGFwdGVycy5fZGF0ZVxyXG4gKiBAbmFtZSBVbml0XHJcbiAqL1xyXG5cclxuLyoqXHJcbiAqIEBjbGFzc1xyXG4gKi9cclxuZnVuY3Rpb24gRGF0ZUFkYXB0ZXIob3B0aW9ucykge1xyXG5cdHRoaXMub3B0aW9ucyA9IG9wdGlvbnMgfHwge307XHJcbn1cclxuXHJcbmhlbHBlcnMkMS5leHRlbmQoRGF0ZUFkYXB0ZXIucHJvdG90eXBlLCAvKiogQGxlbmRzIERhdGVBZGFwdGVyICovIHtcclxuXHQvKipcclxuXHQgKiBSZXR1cm5zIGEgbWFwIG9mIHRpbWUgZm9ybWF0cyBmb3IgdGhlIHN1cHBvcnRlZCBmb3JtYXR0aW5nIHVuaXRzIGRlZmluZWRcclxuXHQgKiBpbiBVbml0IGFzIHdlbGwgYXMgJ2RhdGV0aW1lJyByZXByZXNlbnRpbmcgYSBkZXRhaWxlZCBkYXRlL3RpbWUgc3RyaW5nLlxyXG5cdCAqIEByZXR1cm5zIHt7c3RyaW5nOiBzdHJpbmd9fVxyXG5cdCAqL1xyXG5cdGZvcm1hdHM6IGFic3RyYWN0LFxyXG5cclxuXHQvKipcclxuXHQgKiBQYXJzZXMgdGhlIGdpdmVuIGB2YWx1ZWAgYW5kIHJldHVybiB0aGUgYXNzb2NpYXRlZCB0aW1lc3RhbXAuXHJcblx0ICogQHBhcmFtIHthbnl9IHZhbHVlIC0gdGhlIHZhbHVlIHRvIHBhcnNlICh1c3VhbGx5IGNvbWVzIGZyb20gdGhlIGRhdGEpXHJcblx0ICogQHBhcmFtIHtzdHJpbmd9IFtmb3JtYXRdIC0gdGhlIGV4cGVjdGVkIGRhdGEgZm9ybWF0XHJcblx0ICogQHJldHVybnMgeyhudW1iZXJ8bnVsbCl9XHJcblx0ICogQGZ1bmN0aW9uXHJcblx0ICovXHJcblx0cGFyc2U6IGFic3RyYWN0LFxyXG5cclxuXHQvKipcclxuXHQgKiBSZXR1cm5zIHRoZSBmb3JtYXR0ZWQgZGF0ZSBpbiB0aGUgc3BlY2lmaWVkIGBmb3JtYXRgIGZvciBhIGdpdmVuIGB0aW1lc3RhbXBgLlxyXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSB0aW1lc3RhbXAgLSB0aGUgdGltZXN0YW1wIHRvIGZvcm1hdFxyXG5cdCAqIEBwYXJhbSB7c3RyaW5nfSBmb3JtYXQgLSB0aGUgZGF0ZS90aW1lIHRva2VuXHJcblx0ICogQHJldHVybiB7c3RyaW5nfVxyXG5cdCAqIEBmdW5jdGlvblxyXG5cdCAqL1xyXG5cdGZvcm1hdDogYWJzdHJhY3QsXHJcblxyXG5cdC8qKlxyXG5cdCAqIEFkZHMgdGhlIHNwZWNpZmllZCBgYW1vdW50YCBvZiBgdW5pdGAgdG8gdGhlIGdpdmVuIGB0aW1lc3RhbXBgLlxyXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSB0aW1lc3RhbXAgLSB0aGUgaW5wdXQgdGltZXN0YW1wXHJcblx0ICogQHBhcmFtIHtudW1iZXJ9IGFtb3VudCAtIHRoZSBhbW91bnQgdG8gYWRkXHJcblx0ICogQHBhcmFtIHtVbml0fSB1bml0IC0gdGhlIHVuaXQgYXMgc3RyaW5nXHJcblx0ICogQHJldHVybiB7bnVtYmVyfVxyXG5cdCAqIEBmdW5jdGlvblxyXG5cdCAqL1xyXG5cdGFkZDogYWJzdHJhY3QsXHJcblxyXG5cdC8qKlxyXG5cdCAqIFJldHVybnMgdGhlIG51bWJlciBvZiBgdW5pdGAgYmV0d2VlbiB0aGUgZ2l2ZW4gdGltZXN0YW1wcy5cclxuXHQgKiBAcGFyYW0ge251bWJlcn0gbWF4IC0gdGhlIGlucHV0IHRpbWVzdGFtcCAocmVmZXJlbmNlKVxyXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBtaW4gLSB0aGUgdGltZXN0YW1wIHRvIHN1YnN0cmFjdFxyXG5cdCAqIEBwYXJhbSB7VW5pdH0gdW5pdCAtIHRoZSB1bml0IGFzIHN0cmluZ1xyXG5cdCAqIEByZXR1cm4ge251bWJlcn1cclxuXHQgKiBAZnVuY3Rpb25cclxuXHQgKi9cclxuXHRkaWZmOiBhYnN0cmFjdCxcclxuXHJcblx0LyoqXHJcblx0ICogUmV0dXJucyBzdGFydCBvZiBgdW5pdGAgZm9yIHRoZSBnaXZlbiBgdGltZXN0YW1wYC5cclxuXHQgKiBAcGFyYW0ge251bWJlcn0gdGltZXN0YW1wIC0gdGhlIGlucHV0IHRpbWVzdGFtcFxyXG5cdCAqIEBwYXJhbSB7VW5pdH0gdW5pdCAtIHRoZSB1bml0IGFzIHN0cmluZ1xyXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBbd2Vla2RheV0gLSB0aGUgSVNPIGRheSBvZiB0aGUgd2VlayB3aXRoIDEgYmVpbmcgTW9uZGF5XHJcblx0ICogYW5kIDcgYmVpbmcgU3VuZGF5IChvbmx5IG5lZWRlZCBpZiBwYXJhbSAqdW5pdCogaXMgYGlzb1dlZWtgKS5cclxuXHQgKiBAZnVuY3Rpb25cclxuXHQgKi9cclxuXHRzdGFydE9mOiBhYnN0cmFjdCxcclxuXHJcblx0LyoqXHJcblx0ICogUmV0dXJucyBlbmQgb2YgYHVuaXRgIGZvciB0aGUgZ2l2ZW4gYHRpbWVzdGFtcGAuXHJcblx0ICogQHBhcmFtIHtudW1iZXJ9IHRpbWVzdGFtcCAtIHRoZSBpbnB1dCB0aW1lc3RhbXBcclxuXHQgKiBAcGFyYW0ge1VuaXR9IHVuaXQgLSB0aGUgdW5pdCBhcyBzdHJpbmdcclxuXHQgKiBAZnVuY3Rpb25cclxuXHQgKi9cclxuXHRlbmRPZjogYWJzdHJhY3QsXHJcblxyXG5cdC8vIERFUFJFQ0FUSU9OU1xyXG5cclxuXHQvKipcclxuXHQgKiBQcm92aWRlZCBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSBmb3Igc2NhbGUuZ2V0VmFsdWVGb3JQaXhlbCgpLFxyXG5cdCAqIHRoaXMgbWV0aG9kIHNob3VsZCBiZSBvdmVycmlkZGVuIG9ubHkgYnkgdGhlIG1vbWVudCBhZGFwdGVyLlxyXG5cdCAqIEBkZXByZWNhdGVkIHNpbmNlIHZlcnNpb24gMi44LjBcclxuXHQgKiBAdG9kbyByZW1vdmUgYXQgdmVyc2lvbiAzXHJcblx0ICogQHByaXZhdGVcclxuXHQgKi9cclxuXHRfY3JlYXRlOiBmdW5jdGlvbih2YWx1ZSkge1xyXG5cdFx0cmV0dXJuIHZhbHVlO1xyXG5cdH1cclxufSk7XHJcblxyXG5EYXRlQWRhcHRlci5vdmVycmlkZSA9IGZ1bmN0aW9uKG1lbWJlcnMpIHtcclxuXHRoZWxwZXJzJDEuZXh0ZW5kKERhdGVBZGFwdGVyLnByb3RvdHlwZSwgbWVtYmVycyk7XHJcbn07XHJcblxyXG52YXIgX2RhdGUgPSBEYXRlQWRhcHRlcjtcblxudmFyIGNvcmVfYWRhcHRlcnMgPSB7XG5cdF9kYXRlOiBfZGF0ZVxufTtcblxuLyoqXHJcbiAqIE5hbWVzcGFjZSB0byBob2xkIHN0YXRpYyB0aWNrIGdlbmVyYXRpb24gZnVuY3Rpb25zXHJcbiAqIEBuYW1lc3BhY2UgQ2hhcnQuVGlja3NcclxuICovXHJcbnZhciBjb3JlX3RpY2tzID0ge1xyXG5cdC8qKlxyXG5cdCAqIE5hbWVzcGFjZSB0byBob2xkIGZvcm1hdHRlcnMgZm9yIGRpZmZlcmVudCB0eXBlcyBvZiB0aWNrc1xyXG5cdCAqIEBuYW1lc3BhY2UgQ2hhcnQuVGlja3MuZm9ybWF0dGVyc1xyXG5cdCAqL1xyXG5cdGZvcm1hdHRlcnM6IHtcclxuXHRcdC8qKlxyXG5cdFx0ICogRm9ybWF0dGVyIGZvciB2YWx1ZSBsYWJlbHNcclxuXHRcdCAqIEBtZXRob2QgQ2hhcnQuVGlja3MuZm9ybWF0dGVycy52YWx1ZXNcclxuXHRcdCAqIEBwYXJhbSB2YWx1ZSB0aGUgdmFsdWUgdG8gZGlzcGxheVxyXG5cdFx0ICogQHJldHVybiB7c3RyaW5nfHN0cmluZ1tdfSB0aGUgbGFiZWwgdG8gZGlzcGxheVxyXG5cdFx0ICovXHJcblx0XHR2YWx1ZXM6IGZ1bmN0aW9uKHZhbHVlKSB7XHJcblx0XHRcdHJldHVybiBoZWxwZXJzJDEuaXNBcnJheSh2YWx1ZSkgPyB2YWx1ZSA6ICcnICsgdmFsdWU7XHJcblx0XHR9LFxyXG5cclxuXHRcdC8qKlxyXG5cdFx0ICogRm9ybWF0dGVyIGZvciBsaW5lYXIgbnVtZXJpYyB0aWNrc1xyXG5cdFx0ICogQG1ldGhvZCBDaGFydC5UaWNrcy5mb3JtYXR0ZXJzLmxpbmVhclxyXG5cdFx0ICogQHBhcmFtIHRpY2tWYWx1ZSB7bnVtYmVyfSB0aGUgdmFsdWUgdG8gYmUgZm9ybWF0dGVkXHJcblx0XHQgKiBAcGFyYW0gaW5kZXgge251bWJlcn0gdGhlIHBvc2l0aW9uIG9mIHRoZSB0aWNrVmFsdWUgcGFyYW1ldGVyIGluIHRoZSB0aWNrcyBhcnJheVxyXG5cdFx0ICogQHBhcmFtIHRpY2tzIHtudW1iZXJbXX0gdGhlIGxpc3Qgb2YgdGlja3MgYmVpbmcgY29udmVydGVkXHJcblx0XHQgKiBAcmV0dXJuIHtzdHJpbmd9IHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgdGlja1ZhbHVlIHBhcmFtZXRlclxyXG5cdFx0ICovXHJcblx0XHRsaW5lYXI6IGZ1bmN0aW9uKHRpY2tWYWx1ZSwgaW5kZXgsIHRpY2tzKSB7XHJcblx0XHRcdC8vIElmIHdlIGhhdmUgbG90cyBvZiB0aWNrcywgZG9uJ3QgdXNlIHRoZSBvbmVzXHJcblx0XHRcdHZhciBkZWx0YSA9IHRpY2tzLmxlbmd0aCA+IDMgPyB0aWNrc1syXSAtIHRpY2tzWzFdIDogdGlja3NbMV0gLSB0aWNrc1swXTtcclxuXHJcblx0XHRcdC8vIElmIHdlIGhhdmUgYSBudW1iZXIgbGlrZSAyLjUgYXMgdGhlIGRlbHRhLCBmaWd1cmUgb3V0IGhvdyBtYW55IGRlY2ltYWwgcGxhY2VzIHdlIG5lZWRcclxuXHRcdFx0aWYgKE1hdGguYWJzKGRlbHRhKSA+IDEpIHtcclxuXHRcdFx0XHRpZiAodGlja1ZhbHVlICE9PSBNYXRoLmZsb29yKHRpY2tWYWx1ZSkpIHtcclxuXHRcdFx0XHRcdC8vIG5vdCBhbiBpbnRlZ2VyXHJcblx0XHRcdFx0XHRkZWx0YSA9IHRpY2tWYWx1ZSAtIE1hdGguZmxvb3IodGlja1ZhbHVlKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdHZhciBsb2dEZWx0YSA9IGhlbHBlcnMkMS5sb2cxMChNYXRoLmFicyhkZWx0YSkpO1xyXG5cdFx0XHR2YXIgdGlja1N0cmluZyA9ICcnO1xyXG5cclxuXHRcdFx0aWYgKHRpY2tWYWx1ZSAhPT0gMCkge1xyXG5cdFx0XHRcdHZhciBtYXhUaWNrID0gTWF0aC5tYXgoTWF0aC5hYnModGlja3NbMF0pLCBNYXRoLmFicyh0aWNrc1t0aWNrcy5sZW5ndGggLSAxXSkpO1xyXG5cdFx0XHRcdGlmIChtYXhUaWNrIDwgMWUtNCkgeyAvLyBhbGwgdGlja3MgYXJlIHNtYWxsIG51bWJlcnM7IHVzZSBzY2llbnRpZmljIG5vdGF0aW9uXHJcblx0XHRcdFx0XHR2YXIgbG9nVGljayA9IGhlbHBlcnMkMS5sb2cxMChNYXRoLmFicyh0aWNrVmFsdWUpKTtcclxuXHRcdFx0XHRcdHZhciBudW1FeHBvbmVudGlhbCA9IE1hdGguZmxvb3IobG9nVGljaykgLSBNYXRoLmZsb29yKGxvZ0RlbHRhKTtcclxuXHRcdFx0XHRcdG51bUV4cG9uZW50aWFsID0gTWF0aC5tYXgoTWF0aC5taW4obnVtRXhwb25lbnRpYWwsIDIwKSwgMCk7XHJcblx0XHRcdFx0XHR0aWNrU3RyaW5nID0gdGlja1ZhbHVlLnRvRXhwb25lbnRpYWwobnVtRXhwb25lbnRpYWwpO1xyXG5cdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHR2YXIgbnVtRGVjaW1hbCA9IC0xICogTWF0aC5mbG9vcihsb2dEZWx0YSk7XHJcblx0XHRcdFx0XHRudW1EZWNpbWFsID0gTWF0aC5tYXgoTWF0aC5taW4obnVtRGVjaW1hbCwgMjApLCAwKTsgLy8gdG9GaXhlZCBoYXMgYSBtYXggb2YgMjAgZGVjaW1hbCBwbGFjZXNcclxuXHRcdFx0XHRcdHRpY2tTdHJpbmcgPSB0aWNrVmFsdWUudG9GaXhlZChudW1EZWNpbWFsKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0dGlja1N0cmluZyA9ICcwJzsgLy8gbmV2ZXIgc2hvdyBkZWNpbWFsIHBsYWNlcyBmb3IgMFxyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRyZXR1cm4gdGlja1N0cmluZztcclxuXHRcdH0sXHJcblxyXG5cdFx0bG9nYXJpdGhtaWM6IGZ1bmN0aW9uKHRpY2tWYWx1ZSwgaW5kZXgsIHRpY2tzKSB7XHJcblx0XHRcdHZhciByZW1haW4gPSB0aWNrVmFsdWUgLyAoTWF0aC5wb3coMTAsIE1hdGguZmxvb3IoaGVscGVycyQxLmxvZzEwKHRpY2tWYWx1ZSkpKSk7XHJcblxyXG5cdFx0XHRpZiAodGlja1ZhbHVlID09PSAwKSB7XHJcblx0XHRcdFx0cmV0dXJuICcwJztcclxuXHRcdFx0fSBlbHNlIGlmIChyZW1haW4gPT09IDEgfHwgcmVtYWluID09PSAyIHx8IHJlbWFpbiA9PT0gNSB8fCBpbmRleCA9PT0gMCB8fCBpbmRleCA9PT0gdGlja3MubGVuZ3RoIC0gMSkge1xyXG5cdFx0XHRcdHJldHVybiB0aWNrVmFsdWUudG9FeHBvbmVudGlhbCgpO1xyXG5cdFx0XHR9XHJcblx0XHRcdHJldHVybiAnJztcclxuXHRcdH1cclxuXHR9XHJcbn07XG5cbnZhciBpc0FycmF5ID0gaGVscGVycyQxLmlzQXJyYXk7XHJcbnZhciBpc051bGxPclVuZGVmID0gaGVscGVycyQxLmlzTnVsbE9yVW5kZWY7XHJcbnZhciB2YWx1ZU9yRGVmYXVsdCRhID0gaGVscGVycyQxLnZhbHVlT3JEZWZhdWx0O1xyXG52YXIgdmFsdWVBdEluZGV4T3JEZWZhdWx0ID0gaGVscGVycyQxLnZhbHVlQXRJbmRleE9yRGVmYXVsdDtcclxuXHJcbmNvcmVfZGVmYXVsdHMuX3NldCgnc2NhbGUnLCB7XHJcblx0ZGlzcGxheTogdHJ1ZSxcclxuXHRwb3NpdGlvbjogJ2xlZnQnLFxyXG5cdG9mZnNldDogZmFsc2UsXHJcblxyXG5cdC8vIGdyaWQgbGluZSBzZXR0aW5nc1xyXG5cdGdyaWRMaW5lczoge1xyXG5cdFx0ZGlzcGxheTogdHJ1ZSxcclxuXHRcdGNvbG9yOiAncmdiYSgwLDAsMCwwLjEpJyxcclxuXHRcdGxpbmVXaWR0aDogMSxcclxuXHRcdGRyYXdCb3JkZXI6IHRydWUsXHJcblx0XHRkcmF3T25DaGFydEFyZWE6IHRydWUsXHJcblx0XHRkcmF3VGlja3M6IHRydWUsXHJcblx0XHR0aWNrTWFya0xlbmd0aDogMTAsXHJcblx0XHR6ZXJvTGluZVdpZHRoOiAxLFxyXG5cdFx0emVyb0xpbmVDb2xvcjogJ3JnYmEoMCwwLDAsMC4yNSknLFxyXG5cdFx0emVyb0xpbmVCb3JkZXJEYXNoOiBbXSxcclxuXHRcdHplcm9MaW5lQm9yZGVyRGFzaE9mZnNldDogMC4wLFxyXG5cdFx0b2Zmc2V0R3JpZExpbmVzOiBmYWxzZSxcclxuXHRcdGJvcmRlckRhc2g6IFtdLFxyXG5cdFx0Ym9yZGVyRGFzaE9mZnNldDogMC4wXHJcblx0fSxcclxuXHJcblx0Ly8gc2NhbGUgbGFiZWxcclxuXHRzY2FsZUxhYmVsOiB7XHJcblx0XHQvLyBkaXNwbGF5IHByb3BlcnR5XHJcblx0XHRkaXNwbGF5OiBmYWxzZSxcclxuXHJcblx0XHQvLyBhY3R1YWwgbGFiZWxcclxuXHRcdGxhYmVsU3RyaW5nOiAnJyxcclxuXHJcblx0XHQvLyB0b3AvYm90dG9tIHBhZGRpbmdcclxuXHRcdHBhZGRpbmc6IHtcclxuXHRcdFx0dG9wOiA0LFxyXG5cdFx0XHRib3R0b206IDRcclxuXHRcdH1cclxuXHR9LFxyXG5cclxuXHQvLyBsYWJlbCBzZXR0aW5nc1xyXG5cdHRpY2tzOiB7XHJcblx0XHRiZWdpbkF0WmVybzogZmFsc2UsXHJcblx0XHRtaW5Sb3RhdGlvbjogMCxcclxuXHRcdG1heFJvdGF0aW9uOiA1MCxcclxuXHRcdG1pcnJvcjogZmFsc2UsXHJcblx0XHRwYWRkaW5nOiAwLFxyXG5cdFx0cmV2ZXJzZTogZmFsc2UsXHJcblx0XHRkaXNwbGF5OiB0cnVlLFxyXG5cdFx0YXV0b1NraXA6IHRydWUsXHJcblx0XHRhdXRvU2tpcFBhZGRpbmc6IDAsXHJcblx0XHRsYWJlbE9mZnNldDogMCxcclxuXHRcdC8vIFdlIHBhc3MgdGhyb3VnaCBhcnJheXMgdG8gYmUgcmVuZGVyZWQgYXMgbXVsdGlsaW5lIGxhYmVscywgd2UgY29udmVydCBPdGhlcnMgdG8gc3RyaW5ncyBoZXJlLlxyXG5cdFx0Y2FsbGJhY2s6IGNvcmVfdGlja3MuZm9ybWF0dGVycy52YWx1ZXMsXHJcblx0XHRtaW5vcjoge30sXHJcblx0XHRtYWpvcjoge31cclxuXHR9XHJcbn0pO1xyXG5cclxuLyoqIFJldHVybnMgYSBuZXcgYXJyYXkgY29udGFpbmluZyBudW1JdGVtcyBmcm9tIGFyciAqL1xyXG5mdW5jdGlvbiBzYW1wbGUoYXJyLCBudW1JdGVtcykge1xyXG5cdHZhciByZXN1bHQgPSBbXTtcclxuXHR2YXIgaW5jcmVtZW50ID0gYXJyLmxlbmd0aCAvIG51bUl0ZW1zO1xyXG5cdHZhciBpID0gMDtcclxuXHR2YXIgbGVuID0gYXJyLmxlbmd0aDtcclxuXHJcblx0Zm9yICg7IGkgPCBsZW47IGkgKz0gaW5jcmVtZW50KSB7XHJcblx0XHRyZXN1bHQucHVzaChhcnJbTWF0aC5mbG9vcihpKV0pO1xyXG5cdH1cclxuXHRyZXR1cm4gcmVzdWx0O1xyXG59XHJcblxyXG5mdW5jdGlvbiBnZXRQaXhlbEZvckdyaWRMaW5lKHNjYWxlLCBpbmRleCwgb2Zmc2V0R3JpZExpbmVzKSB7XHJcblx0dmFyIGxlbmd0aCA9IHNjYWxlLmdldFRpY2tzKCkubGVuZ3RoO1xyXG5cdHZhciB2YWxpZEluZGV4ID0gTWF0aC5taW4oaW5kZXgsIGxlbmd0aCAtIDEpO1xyXG5cdHZhciBsaW5lVmFsdWUgPSBzY2FsZS5nZXRQaXhlbEZvclRpY2sodmFsaWRJbmRleCk7XHJcblx0dmFyIHN0YXJ0ID0gc2NhbGUuX3N0YXJ0UGl4ZWw7XHJcblx0dmFyIGVuZCA9IHNjYWxlLl9lbmRQaXhlbDtcclxuXHR2YXIgZXBzaWxvbiA9IDFlLTY7IC8vIDFlLTYgaXMgbWFyZ2luIGluIHBpeGVscyBmb3IgYWNjdW11bGF0ZWQgZXJyb3IuXHJcblx0dmFyIG9mZnNldDtcclxuXHJcblx0aWYgKG9mZnNldEdyaWRMaW5lcykge1xyXG5cdFx0aWYgKGxlbmd0aCA9PT0gMSkge1xyXG5cdFx0XHRvZmZzZXQgPSBNYXRoLm1heChsaW5lVmFsdWUgLSBzdGFydCwgZW5kIC0gbGluZVZhbHVlKTtcclxuXHRcdH0gZWxzZSBpZiAoaW5kZXggPT09IDApIHtcclxuXHRcdFx0b2Zmc2V0ID0gKHNjYWxlLmdldFBpeGVsRm9yVGljaygxKSAtIGxpbmVWYWx1ZSkgLyAyO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0b2Zmc2V0ID0gKGxpbmVWYWx1ZSAtIHNjYWxlLmdldFBpeGVsRm9yVGljayh2YWxpZEluZGV4IC0gMSkpIC8gMjtcclxuXHRcdH1cclxuXHRcdGxpbmVWYWx1ZSArPSB2YWxpZEluZGV4IDwgaW5kZXggPyBvZmZzZXQgOiAtb2Zmc2V0O1xyXG5cclxuXHRcdC8vIFJldHVybiB1bmRlZmluZWQgaWYgdGhlIHBpeGVsIGlzIG91dCBvZiB0aGUgcmFuZ2VcclxuXHRcdGlmIChsaW5lVmFsdWUgPCBzdGFydCAtIGVwc2lsb24gfHwgbGluZVZhbHVlID4gZW5kICsgZXBzaWxvbikge1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblx0fVxyXG5cdHJldHVybiBsaW5lVmFsdWU7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGdhcmJhZ2VDb2xsZWN0KGNhY2hlcywgbGVuZ3RoKSB7XHJcblx0aGVscGVycyQxLmVhY2goY2FjaGVzLCBmdW5jdGlvbihjYWNoZSkge1xyXG5cdFx0dmFyIGdjID0gY2FjaGUuZ2M7XHJcblx0XHR2YXIgZ2NMZW4gPSBnYy5sZW5ndGggLyAyO1xyXG5cdFx0dmFyIGk7XHJcblx0XHRpZiAoZ2NMZW4gPiBsZW5ndGgpIHtcclxuXHRcdFx0Zm9yIChpID0gMDsgaSA8IGdjTGVuOyArK2kpIHtcclxuXHRcdFx0XHRkZWxldGUgY2FjaGUuZGF0YVtnY1tpXV07XHJcblx0XHRcdH1cclxuXHRcdFx0Z2Muc3BsaWNlKDAsIGdjTGVuKTtcclxuXHRcdH1cclxuXHR9KTtcclxufVxyXG5cclxuLyoqXHJcbiAqIFJldHVybnMge3dpZHRoLCBoZWlnaHQsIG9mZnNldH0gb2JqZWN0cyBmb3IgdGhlIGZpcnN0LCBsYXN0LCB3aWRlc3QsIGhpZ2hlc3QgdGlja1xyXG4gKiBsYWJlbHMgd2hlcmUgb2Zmc2V0IGluZGljYXRlcyB0aGUgYW5jaG9yIHBvaW50IG9mZnNldCBmcm9tIHRoZSB0b3AgaW4gcGl4ZWxzLlxyXG4gKi9cclxuZnVuY3Rpb24gY29tcHV0ZUxhYmVsU2l6ZXMoY3R4LCB0aWNrRm9udHMsIHRpY2tzLCBjYWNoZXMpIHtcclxuXHR2YXIgbGVuZ3RoID0gdGlja3MubGVuZ3RoO1xyXG5cdHZhciB3aWR0aHMgPSBbXTtcclxuXHR2YXIgaGVpZ2h0cyA9IFtdO1xyXG5cdHZhciBvZmZzZXRzID0gW107XHJcblx0dmFyIHdpZGVzdExhYmVsU2l6ZSA9IDA7XHJcblx0dmFyIGhpZ2hlc3RMYWJlbFNpemUgPSAwO1xyXG5cdHZhciBpLCBqLCBqbGVuLCBsYWJlbCwgdGlja0ZvbnQsIGZvbnRTdHJpbmcsIGNhY2hlLCBsaW5lSGVpZ2h0LCB3aWR0aCwgaGVpZ2h0LCBuZXN0ZWRMYWJlbCwgd2lkZXN0LCBoaWdoZXN0O1xyXG5cclxuXHRmb3IgKGkgPSAwOyBpIDwgbGVuZ3RoOyArK2kpIHtcclxuXHRcdGxhYmVsID0gdGlja3NbaV0ubGFiZWw7XHJcblx0XHR0aWNrRm9udCA9IHRpY2tzW2ldLm1ham9yID8gdGlja0ZvbnRzLm1ham9yIDogdGlja0ZvbnRzLm1pbm9yO1xyXG5cdFx0Y3R4LmZvbnQgPSBmb250U3RyaW5nID0gdGlja0ZvbnQuc3RyaW5nO1xyXG5cdFx0Y2FjaGUgPSBjYWNoZXNbZm9udFN0cmluZ10gPSBjYWNoZXNbZm9udFN0cmluZ10gfHwge2RhdGE6IHt9LCBnYzogW119O1xyXG5cdFx0bGluZUhlaWdodCA9IHRpY2tGb250LmxpbmVIZWlnaHQ7XHJcblx0XHR3aWR0aCA9IGhlaWdodCA9IDA7XHJcblx0XHQvLyBVbmRlZmluZWQgbGFiZWxzIGFuZCBhcnJheXMgc2hvdWxkIG5vdCBiZSBtZWFzdXJlZFxyXG5cdFx0aWYgKCFpc051bGxPclVuZGVmKGxhYmVsKSAmJiAhaXNBcnJheShsYWJlbCkpIHtcclxuXHRcdFx0d2lkdGggPSBoZWxwZXJzJDEubWVhc3VyZVRleHQoY3R4LCBjYWNoZS5kYXRhLCBjYWNoZS5nYywgd2lkdGgsIGxhYmVsKTtcclxuXHRcdFx0aGVpZ2h0ID0gbGluZUhlaWdodDtcclxuXHRcdH0gZWxzZSBpZiAoaXNBcnJheShsYWJlbCkpIHtcclxuXHRcdFx0Ly8gaWYgaXQgaXMgYW4gYXJyYXkgbGV0J3MgbWVhc3VyZSBlYWNoIGVsZW1lbnRcclxuXHRcdFx0Zm9yIChqID0gMCwgamxlbiA9IGxhYmVsLmxlbmd0aDsgaiA8IGpsZW47ICsraikge1xyXG5cdFx0XHRcdG5lc3RlZExhYmVsID0gbGFiZWxbal07XHJcblx0XHRcdFx0Ly8gVW5kZWZpbmVkIGxhYmVscyBhbmQgYXJyYXlzIHNob3VsZCBub3QgYmUgbWVhc3VyZWRcclxuXHRcdFx0XHRpZiAoIWlzTnVsbE9yVW5kZWYobmVzdGVkTGFiZWwpICYmICFpc0FycmF5KG5lc3RlZExhYmVsKSkge1xyXG5cdFx0XHRcdFx0d2lkdGggPSBoZWxwZXJzJDEubWVhc3VyZVRleHQoY3R4LCBjYWNoZS5kYXRhLCBjYWNoZS5nYywgd2lkdGgsIG5lc3RlZExhYmVsKTtcclxuXHRcdFx0XHRcdGhlaWdodCArPSBsaW5lSGVpZ2h0O1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdFx0d2lkdGhzLnB1c2god2lkdGgpO1xyXG5cdFx0aGVpZ2h0cy5wdXNoKGhlaWdodCk7XHJcblx0XHRvZmZzZXRzLnB1c2gobGluZUhlaWdodCAvIDIpO1xyXG5cdFx0d2lkZXN0TGFiZWxTaXplID0gTWF0aC5tYXgod2lkdGgsIHdpZGVzdExhYmVsU2l6ZSk7XHJcblx0XHRoaWdoZXN0TGFiZWxTaXplID0gTWF0aC5tYXgoaGVpZ2h0LCBoaWdoZXN0TGFiZWxTaXplKTtcclxuXHR9XHJcblx0Z2FyYmFnZUNvbGxlY3QoY2FjaGVzLCBsZW5ndGgpO1xyXG5cclxuXHR3aWRlc3QgPSB3aWR0aHMuaW5kZXhPZih3aWRlc3RMYWJlbFNpemUpO1xyXG5cdGhpZ2hlc3QgPSBoZWlnaHRzLmluZGV4T2YoaGlnaGVzdExhYmVsU2l6ZSk7XHJcblxyXG5cdGZ1bmN0aW9uIHZhbHVlQXQoaWR4KSB7XHJcblx0XHRyZXR1cm4ge1xyXG5cdFx0XHR3aWR0aDogd2lkdGhzW2lkeF0gfHwgMCxcclxuXHRcdFx0aGVpZ2h0OiBoZWlnaHRzW2lkeF0gfHwgMCxcclxuXHRcdFx0b2Zmc2V0OiBvZmZzZXRzW2lkeF0gfHwgMFxyXG5cdFx0fTtcclxuXHR9XHJcblxyXG5cdHJldHVybiB7XHJcblx0XHRmaXJzdDogdmFsdWVBdCgwKSxcclxuXHRcdGxhc3Q6IHZhbHVlQXQobGVuZ3RoIC0gMSksXHJcblx0XHR3aWRlc3Q6IHZhbHVlQXQod2lkZXN0KSxcclxuXHRcdGhpZ2hlc3Q6IHZhbHVlQXQoaGlnaGVzdClcclxuXHR9O1xyXG59XHJcblxyXG5mdW5jdGlvbiBnZXRUaWNrTWFya0xlbmd0aChvcHRpb25zKSB7XHJcblx0cmV0dXJuIG9wdGlvbnMuZHJhd1RpY2tzID8gb3B0aW9ucy50aWNrTWFya0xlbmd0aCA6IDA7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGdldFNjYWxlTGFiZWxIZWlnaHQob3B0aW9ucykge1xyXG5cdHZhciBmb250LCBwYWRkaW5nO1xyXG5cclxuXHRpZiAoIW9wdGlvbnMuZGlzcGxheSkge1xyXG5cdFx0cmV0dXJuIDA7XHJcblx0fVxyXG5cclxuXHRmb250ID0gaGVscGVycyQxLm9wdGlvbnMuX3BhcnNlRm9udChvcHRpb25zKTtcclxuXHRwYWRkaW5nID0gaGVscGVycyQxLm9wdGlvbnMudG9QYWRkaW5nKG9wdGlvbnMucGFkZGluZyk7XHJcblxyXG5cdHJldHVybiBmb250LmxpbmVIZWlnaHQgKyBwYWRkaW5nLmhlaWdodDtcclxufVxyXG5cclxuZnVuY3Rpb24gcGFyc2VGb250T3B0aW9ucyhvcHRpb25zLCBuZXN0ZWRPcHRzKSB7XHJcblx0cmV0dXJuIGhlbHBlcnMkMS5leHRlbmQoaGVscGVycyQxLm9wdGlvbnMuX3BhcnNlRm9udCh7XHJcblx0XHRmb250RmFtaWx5OiB2YWx1ZU9yRGVmYXVsdCRhKG5lc3RlZE9wdHMuZm9udEZhbWlseSwgb3B0aW9ucy5mb250RmFtaWx5KSxcclxuXHRcdGZvbnRTaXplOiB2YWx1ZU9yRGVmYXVsdCRhKG5lc3RlZE9wdHMuZm9udFNpemUsIG9wdGlvbnMuZm9udFNpemUpLFxyXG5cdFx0Zm9udFN0eWxlOiB2YWx1ZU9yRGVmYXVsdCRhKG5lc3RlZE9wdHMuZm9udFN0eWxlLCBvcHRpb25zLmZvbnRTdHlsZSksXHJcblx0XHRsaW5lSGVpZ2h0OiB2YWx1ZU9yRGVmYXVsdCRhKG5lc3RlZE9wdHMubGluZUhlaWdodCwgb3B0aW9ucy5saW5lSGVpZ2h0KVxyXG5cdH0pLCB7XHJcblx0XHRjb2xvcjogaGVscGVycyQxLm9wdGlvbnMucmVzb2x2ZShbbmVzdGVkT3B0cy5mb250Q29sb3IsIG9wdGlvbnMuZm9udENvbG9yLCBjb3JlX2RlZmF1bHRzLmdsb2JhbC5kZWZhdWx0Rm9udENvbG9yXSlcclxuXHR9KTtcclxufVxyXG5cclxuZnVuY3Rpb24gcGFyc2VUaWNrRm9udE9wdGlvbnMob3B0aW9ucykge1xyXG5cdHZhciBtaW5vciA9IHBhcnNlRm9udE9wdGlvbnMob3B0aW9ucywgb3B0aW9ucy5taW5vcik7XHJcblx0dmFyIG1ham9yID0gb3B0aW9ucy5tYWpvci5lbmFibGVkID8gcGFyc2VGb250T3B0aW9ucyhvcHRpb25zLCBvcHRpb25zLm1ham9yKSA6IG1pbm9yO1xyXG5cclxuXHRyZXR1cm4ge21pbm9yOiBtaW5vciwgbWFqb3I6IG1ham9yfTtcclxufVxyXG5cclxuZnVuY3Rpb24gbm9uU2tpcHBlZCh0aWNrc1RvRmlsdGVyKSB7XHJcblx0dmFyIGZpbHRlcmVkID0gW107XHJcblx0dmFyIGl0ZW0sIGluZGV4LCBsZW47XHJcblx0Zm9yIChpbmRleCA9IDAsIGxlbiA9IHRpY2tzVG9GaWx0ZXIubGVuZ3RoOyBpbmRleCA8IGxlbjsgKytpbmRleCkge1xyXG5cdFx0aXRlbSA9IHRpY2tzVG9GaWx0ZXJbaW5kZXhdO1xyXG5cdFx0aWYgKHR5cGVvZiBpdGVtLl9pbmRleCAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuXHRcdFx0ZmlsdGVyZWQucHVzaChpdGVtKTtcclxuXHRcdH1cclxuXHR9XHJcblx0cmV0dXJuIGZpbHRlcmVkO1xyXG59XHJcblxyXG5mdW5jdGlvbiBnZXRFdmVuU3BhY2luZyhhcnIpIHtcclxuXHR2YXIgbGVuID0gYXJyLmxlbmd0aDtcclxuXHR2YXIgaSwgZGlmZjtcclxuXHJcblx0aWYgKGxlbiA8IDIpIHtcclxuXHRcdHJldHVybiBmYWxzZTtcclxuXHR9XHJcblxyXG5cdGZvciAoZGlmZiA9IGFyclswXSwgaSA9IDE7IGkgPCBsZW47ICsraSkge1xyXG5cdFx0aWYgKGFycltpXSAtIGFycltpIC0gMV0gIT09IGRpZmYpIHtcclxuXHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0fVxyXG5cdH1cclxuXHRyZXR1cm4gZGlmZjtcclxufVxyXG5cclxuZnVuY3Rpb24gY2FsY3VsYXRlU3BhY2luZyhtYWpvckluZGljZXMsIHRpY2tzLCBheGlzTGVuZ3RoLCB0aWNrc0xpbWl0KSB7XHJcblx0dmFyIGV2ZW5NYWpvclNwYWNpbmcgPSBnZXRFdmVuU3BhY2luZyhtYWpvckluZGljZXMpO1xyXG5cdHZhciBzcGFjaW5nID0gKHRpY2tzLmxlbmd0aCAtIDEpIC8gdGlja3NMaW1pdDtcclxuXHR2YXIgZmFjdG9ycywgZmFjdG9yLCBpLCBpbGVuO1xyXG5cclxuXHQvLyBJZiB0aGUgbWFqb3IgdGlja3MgYXJlIGV2ZW5seSBzcGFjZWQgYXBhcnQsIHBsYWNlIHRoZSBtaW5vciB0aWNrc1xyXG5cdC8vIHNvIHRoYXQgdGhleSBkaXZpZGUgdGhlIG1ham9yIHRpY2tzIGludG8gZXZlbiBjaHVua3NcclxuXHRpZiAoIWV2ZW5NYWpvclNwYWNpbmcpIHtcclxuXHRcdHJldHVybiBNYXRoLm1heChzcGFjaW5nLCAxKTtcclxuXHR9XHJcblxyXG5cdGZhY3RvcnMgPSBoZWxwZXJzJDEubWF0aC5fZmFjdG9yaXplKGV2ZW5NYWpvclNwYWNpbmcpO1xyXG5cdGZvciAoaSA9IDAsIGlsZW4gPSBmYWN0b3JzLmxlbmd0aCAtIDE7IGkgPCBpbGVuOyBpKyspIHtcclxuXHRcdGZhY3RvciA9IGZhY3RvcnNbaV07XHJcblx0XHRpZiAoZmFjdG9yID4gc3BhY2luZykge1xyXG5cdFx0XHRyZXR1cm4gZmFjdG9yO1xyXG5cdFx0fVxyXG5cdH1cclxuXHRyZXR1cm4gTWF0aC5tYXgoc3BhY2luZywgMSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGdldE1ham9ySW5kaWNlcyh0aWNrcykge1xyXG5cdHZhciByZXN1bHQgPSBbXTtcclxuXHR2YXIgaSwgaWxlbjtcclxuXHRmb3IgKGkgPSAwLCBpbGVuID0gdGlja3MubGVuZ3RoOyBpIDwgaWxlbjsgaSsrKSB7XHJcblx0XHRpZiAodGlja3NbaV0ubWFqb3IpIHtcclxuXHRcdFx0cmVzdWx0LnB1c2goaSk7XHJcblx0XHR9XHJcblx0fVxyXG5cdHJldHVybiByZXN1bHQ7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHNraXBNYWpvcnModGlja3MsIG1ham9ySW5kaWNlcywgc3BhY2luZykge1xyXG5cdHZhciBjb3VudCA9IDA7XHJcblx0dmFyIG5leHQgPSBtYWpvckluZGljZXNbMF07XHJcblx0dmFyIGksIHRpY2s7XHJcblxyXG5cdHNwYWNpbmcgPSBNYXRoLmNlaWwoc3BhY2luZyk7XHJcblx0Zm9yIChpID0gMDsgaSA8IHRpY2tzLmxlbmd0aDsgaSsrKSB7XHJcblx0XHR0aWNrID0gdGlja3NbaV07XHJcblx0XHRpZiAoaSA9PT0gbmV4dCkge1xyXG5cdFx0XHR0aWNrLl9pbmRleCA9IGk7XHJcblx0XHRcdGNvdW50Kys7XHJcblx0XHRcdG5leHQgPSBtYWpvckluZGljZXNbY291bnQgKiBzcGFjaW5nXTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdGRlbGV0ZSB0aWNrLmxhYmVsO1xyXG5cdFx0fVxyXG5cdH1cclxufVxyXG5cclxuZnVuY3Rpb24gc2tpcCh0aWNrcywgc3BhY2luZywgbWFqb3JTdGFydCwgbWFqb3JFbmQpIHtcclxuXHR2YXIgc3RhcnQgPSB2YWx1ZU9yRGVmYXVsdCRhKG1ham9yU3RhcnQsIDApO1xyXG5cdHZhciBlbmQgPSBNYXRoLm1pbih2YWx1ZU9yRGVmYXVsdCRhKG1ham9yRW5kLCB0aWNrcy5sZW5ndGgpLCB0aWNrcy5sZW5ndGgpO1xyXG5cdHZhciBjb3VudCA9IDA7XHJcblx0dmFyIGxlbmd0aCwgaSwgdGljaywgbmV4dDtcclxuXHJcblx0c3BhY2luZyA9IE1hdGguY2VpbChzcGFjaW5nKTtcclxuXHRpZiAobWFqb3JFbmQpIHtcclxuXHRcdGxlbmd0aCA9IG1ham9yRW5kIC0gbWFqb3JTdGFydDtcclxuXHRcdHNwYWNpbmcgPSBsZW5ndGggLyBNYXRoLmZsb29yKGxlbmd0aCAvIHNwYWNpbmcpO1xyXG5cdH1cclxuXHJcblx0bmV4dCA9IHN0YXJ0O1xyXG5cclxuXHR3aGlsZSAobmV4dCA8IDApIHtcclxuXHRcdGNvdW50Kys7XHJcblx0XHRuZXh0ID0gTWF0aC5yb3VuZChzdGFydCArIGNvdW50ICogc3BhY2luZyk7XHJcblx0fVxyXG5cclxuXHRmb3IgKGkgPSBNYXRoLm1heChzdGFydCwgMCk7IGkgPCBlbmQ7IGkrKykge1xyXG5cdFx0dGljayA9IHRpY2tzW2ldO1xyXG5cdFx0aWYgKGkgPT09IG5leHQpIHtcclxuXHRcdFx0dGljay5faW5kZXggPSBpO1xyXG5cdFx0XHRjb3VudCsrO1xyXG5cdFx0XHRuZXh0ID0gTWF0aC5yb3VuZChzdGFydCArIGNvdW50ICogc3BhY2luZyk7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRkZWxldGUgdGljay5sYWJlbDtcclxuXHRcdH1cclxuXHR9XHJcbn1cclxuXHJcbnZhciBTY2FsZSA9IGNvcmVfZWxlbWVudC5leHRlbmQoe1xyXG5cclxuXHR6ZXJvTGluZUluZGV4OiAwLFxyXG5cclxuXHQvKipcclxuXHQgKiBHZXQgdGhlIHBhZGRpbmcgbmVlZGVkIGZvciB0aGUgc2NhbGVcclxuXHQgKiBAbWV0aG9kIGdldFBhZGRpbmdcclxuXHQgKiBAcHJpdmF0ZVxyXG5cdCAqIEByZXR1cm5zIHtQYWRkaW5nfSB0aGUgbmVjZXNzYXJ5IHBhZGRpbmdcclxuXHQgKi9cclxuXHRnZXRQYWRkaW5nOiBmdW5jdGlvbigpIHtcclxuXHRcdHZhciBtZSA9IHRoaXM7XHJcblx0XHRyZXR1cm4ge1xyXG5cdFx0XHRsZWZ0OiBtZS5wYWRkaW5nTGVmdCB8fCAwLFxyXG5cdFx0XHR0b3A6IG1lLnBhZGRpbmdUb3AgfHwgMCxcclxuXHRcdFx0cmlnaHQ6IG1lLnBhZGRpbmdSaWdodCB8fCAwLFxyXG5cdFx0XHRib3R0b206IG1lLnBhZGRpbmdCb3R0b20gfHwgMFxyXG5cdFx0fTtcclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBSZXR1cm5zIHRoZSBzY2FsZSB0aWNrIG9iamVjdHMgKHtsYWJlbCwgbWFqb3J9KVxyXG5cdCAqIEBzaW5jZSAyLjdcclxuXHQgKi9cclxuXHRnZXRUaWNrczogZnVuY3Rpb24oKSB7XHJcblx0XHRyZXR1cm4gdGhpcy5fdGlja3M7XHJcblx0fSxcclxuXHJcblx0LyoqXHJcblx0KiBAcHJpdmF0ZVxyXG5cdCovXHJcblx0X2dldExhYmVsczogZnVuY3Rpb24oKSB7XHJcblx0XHR2YXIgZGF0YSA9IHRoaXMuY2hhcnQuZGF0YTtcclxuXHRcdHJldHVybiB0aGlzLm9wdGlvbnMubGFiZWxzIHx8ICh0aGlzLmlzSG9yaXpvbnRhbCgpID8gZGF0YS54TGFiZWxzIDogZGF0YS55TGFiZWxzKSB8fCBkYXRhLmxhYmVscyB8fCBbXTtcclxuXHR9LFxyXG5cclxuXHQvLyBUaGVzZSBtZXRob2RzIGFyZSBvcmRlcmVkIGJ5IGxpZmVjeWxlLiBVdGlsaXRpZXMgdGhlbiBmb2xsb3cuXHJcblx0Ly8gQW55IGZ1bmN0aW9uIGRlZmluZWQgaGVyZSBpcyBpbmhlcml0ZWQgYnkgYWxsIHNjYWxlIHR5cGVzLlxyXG5cdC8vIEFueSBmdW5jdGlvbiBjYW4gYmUgZXh0ZW5kZWQgYnkgdGhlIHNjYWxlIHR5cGVcclxuXHJcblx0LyoqXHJcblx0ICogUHJvdmlkZWQgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHksIG5vdCBhdmFpbGFibGUgYW55bW9yZVxyXG5cdCAqIEBmdW5jdGlvbiBDaGFydC5TY2FsZS5tZXJnZVRpY2tzT3B0aW9uc1xyXG5cdCAqIEBkZXByZWNhdGVkIHNpbmNlIHZlcnNpb24gMi44LjBcclxuXHQgKiBAdG9kbyByZW1vdmUgYXQgdmVyc2lvbiAzXHJcblx0ICovXHJcblx0bWVyZ2VUaWNrc09wdGlvbnM6IGZ1bmN0aW9uKCkge1xyXG5cdFx0Ly8gbm9vcFxyXG5cdH0sXHJcblxyXG5cdGJlZm9yZVVwZGF0ZTogZnVuY3Rpb24oKSB7XHJcblx0XHRoZWxwZXJzJDEuY2FsbGJhY2sodGhpcy5vcHRpb25zLmJlZm9yZVVwZGF0ZSwgW3RoaXNdKTtcclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBAcGFyYW0ge251bWJlcn0gbWF4V2lkdGggLSB0aGUgbWF4IHdpZHRoIGluIHBpeGVsc1xyXG5cdCAqIEBwYXJhbSB7bnVtYmVyfSBtYXhIZWlnaHQgLSB0aGUgbWF4IGhlaWdodCBpbiBwaXhlbHNcclxuXHQgKiBAcGFyYW0ge29iamVjdH0gbWFyZ2lucyAtIHRoZSBzcGFjZSBiZXR3ZWVuIHRoZSBlZGdlIG9mIHRoZSBvdGhlciBzY2FsZXMgYW5kIGVkZ2Ugb2YgdGhlIGNoYXJ0XHJcblx0ICogICBUaGlzIHNwYWNlIGNvbWVzIGZyb20gdHdvIHNvdXJjZXM6XHJcblx0ICogICAgIC0gcGFkZGluZyAtIHNwYWNlIHRoYXQncyByZXF1aXJlZCB0byBzaG93IHRoZSBsYWJlbHMgYXQgdGhlIGVkZ2VzIG9mIHRoZSBzY2FsZVxyXG5cdCAqICAgICAtIHRoaWNrbmVzcyBvZiBzY2FsZXMgb3IgbGVnZW5kcyBpbiBhbm90aGVyIG9yaWVudGF0aW9uXHJcblx0ICovXHJcblx0dXBkYXRlOiBmdW5jdGlvbihtYXhXaWR0aCwgbWF4SGVpZ2h0LCBtYXJnaW5zKSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0dmFyIHRpY2tPcHRzID0gbWUub3B0aW9ucy50aWNrcztcclxuXHRcdHZhciBzYW1wbGVTaXplID0gdGlja09wdHMuc2FtcGxlU2l6ZTtcclxuXHRcdHZhciBpLCBpbGVuLCBsYWJlbHMsIHRpY2tzLCBzYW1wbGluZ0VuYWJsZWQ7XHJcblxyXG5cdFx0Ly8gVXBkYXRlIExpZmVjeWNsZSAtIFByb2JhYmx5IGRvbid0IHdhbnQgdG8gZXZlciBleHRlbmQgb3Igb3ZlcndyaXRlIHRoaXMgZnVuY3Rpb24gOylcclxuXHRcdG1lLmJlZm9yZVVwZGF0ZSgpO1xyXG5cclxuXHRcdC8vIEFic29yYiB0aGUgbWFzdGVyIG1lYXN1cmVtZW50c1xyXG5cdFx0bWUubWF4V2lkdGggPSBtYXhXaWR0aDtcclxuXHRcdG1lLm1heEhlaWdodCA9IG1heEhlaWdodDtcclxuXHRcdG1lLm1hcmdpbnMgPSBoZWxwZXJzJDEuZXh0ZW5kKHtcclxuXHRcdFx0bGVmdDogMCxcclxuXHRcdFx0cmlnaHQ6IDAsXHJcblx0XHRcdHRvcDogMCxcclxuXHRcdFx0Ym90dG9tOiAwXHJcblx0XHR9LCBtYXJnaW5zKTtcclxuXHJcblx0XHRtZS5fdGlja3MgPSBudWxsO1xyXG5cdFx0bWUudGlja3MgPSBudWxsO1xyXG5cdFx0bWUuX2xhYmVsU2l6ZXMgPSBudWxsO1xyXG5cdFx0bWUuX21heExhYmVsTGluZXMgPSAwO1xyXG5cdFx0bWUubG9uZ2VzdExhYmVsV2lkdGggPSAwO1xyXG5cdFx0bWUubG9uZ2VzdFRleHRDYWNoZSA9IG1lLmxvbmdlc3RUZXh0Q2FjaGUgfHwge307XHJcblx0XHRtZS5fZ3JpZExpbmVJdGVtcyA9IG51bGw7XHJcblx0XHRtZS5fbGFiZWxJdGVtcyA9IG51bGw7XHJcblxyXG5cdFx0Ly8gRGltZW5zaW9uc1xyXG5cdFx0bWUuYmVmb3JlU2V0RGltZW5zaW9ucygpO1xyXG5cdFx0bWUuc2V0RGltZW5zaW9ucygpO1xyXG5cdFx0bWUuYWZ0ZXJTZXREaW1lbnNpb25zKCk7XHJcblxyXG5cdFx0Ly8gRGF0YSBtaW4vbWF4XHJcblx0XHRtZS5iZWZvcmVEYXRhTGltaXRzKCk7XHJcblx0XHRtZS5kZXRlcm1pbmVEYXRhTGltaXRzKCk7XHJcblx0XHRtZS5hZnRlckRhdGFMaW1pdHMoKTtcclxuXHJcblx0XHQvLyBUaWNrcyAtIGB0aGlzLnRpY2tzYCBpcyBub3cgREVQUkVDQVRFRCFcclxuXHRcdC8vIEludGVybmFsIHRpY2tzIGFyZSBub3cgc3RvcmVkIGFzIG9iamVjdHMgaW4gdGhlIFBSSVZBVEUgYHRoaXMuX3RpY2tzYCBtZW1iZXJcclxuXHRcdC8vIGFuZCBtdXN0IG5vdCBiZSBhY2Nlc3NlZCBkaXJlY3RseSBmcm9tIG91dHNpZGUgdGhpcyBjbGFzcy4gYHRoaXMudGlja3NgIGJlaW5nXHJcblx0XHQvLyBhcm91bmQgZm9yIGxvbmcgdGltZSBhbmQgbm90IG1hcmtlZCBhcyBwcml2YXRlLCB3ZSBjYW4ndCBjaGFuZ2UgaXRzIHN0cnVjdHVyZVxyXG5cdFx0Ly8gd2l0aG91dCB1bmV4cGVjdGVkIGJyZWFraW5nIGNoYW5nZXMuIElmIHlvdSBuZWVkIHRvIGFjY2VzcyB0aGUgc2NhbGUgdGlja3MsXHJcblx0XHQvLyB1c2Ugc2NhbGUuZ2V0VGlja3MoKSBpbnN0ZWFkLlxyXG5cclxuXHRcdG1lLmJlZm9yZUJ1aWxkVGlja3MoKTtcclxuXHJcblx0XHQvLyBOZXcgaW1wbGVtZW50YXRpb25zIHNob3VsZCByZXR1cm4gYW4gYXJyYXkgb2Ygb2JqZWN0cyBidXQgZm9yIEJBQ0tXQVJEIENPTVBBVCxcclxuXHRcdC8vIHdlIHN0aWxsIHN1cHBvcnQgbm8gcmV0dXJuIChgdGhpcy50aWNrc2AgaW50ZXJuYWxseSBzZXQgYnkgY2FsbGluZyB0aGlzIG1ldGhvZCkuXHJcblx0XHR0aWNrcyA9IG1lLmJ1aWxkVGlja3MoKSB8fCBbXTtcclxuXHJcblx0XHQvLyBBbGxvdyBtb2RpZmljYXRpb24gb2YgdGlja3MgaW4gY2FsbGJhY2suXHJcblx0XHR0aWNrcyA9IG1lLmFmdGVyQnVpbGRUaWNrcyh0aWNrcykgfHwgdGlja3M7XHJcblxyXG5cdFx0Ly8gRW5zdXJlIHRpY2tzIGNvbnRhaW5zIHRpY2tzIGluIG5ldyB0aWNrIGZvcm1hdFxyXG5cdFx0aWYgKCghdGlja3MgfHwgIXRpY2tzLmxlbmd0aCkgJiYgbWUudGlja3MpIHtcclxuXHRcdFx0dGlja3MgPSBbXTtcclxuXHRcdFx0Zm9yIChpID0gMCwgaWxlbiA9IG1lLnRpY2tzLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xyXG5cdFx0XHRcdHRpY2tzLnB1c2goe1xyXG5cdFx0XHRcdFx0dmFsdWU6IG1lLnRpY2tzW2ldLFxyXG5cdFx0XHRcdFx0bWFqb3I6IGZhbHNlXHJcblx0XHRcdFx0fSk7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHRtZS5fdGlja3MgPSB0aWNrcztcclxuXHJcblx0XHQvLyBDb21wdXRlIHRpY2sgcm90YXRpb24gYW5kIGZpdCB1c2luZyBhIHNhbXBsZWQgc3Vic2V0IG9mIGxhYmVsc1xyXG5cdFx0Ly8gV2UgZ2VuZXJhbGx5IGRvbid0IG5lZWQgdG8gY29tcHV0ZSB0aGUgc2l6ZSBvZiBldmVyeSBzaW5nbGUgbGFiZWwgZm9yIGRldGVybWluaW5nIHNjYWxlIHNpemVcclxuXHRcdHNhbXBsaW5nRW5hYmxlZCA9IHNhbXBsZVNpemUgPCB0aWNrcy5sZW5ndGg7XHJcblx0XHRsYWJlbHMgPSBtZS5fY29udmVydFRpY2tzVG9MYWJlbHMoc2FtcGxpbmdFbmFibGVkID8gc2FtcGxlKHRpY2tzLCBzYW1wbGVTaXplKSA6IHRpY2tzKTtcclxuXHJcblx0XHQvLyBfY29uZmlndXJlIGlzIGNhbGxlZCB0d2ljZSwgb25jZSBoZXJlLCBvbmNlIGZyb20gY29yZS5jb250cm9sbGVyLnVwZGF0ZUxheW91dC5cclxuXHRcdC8vIEhlcmUgd2UgaGF2ZW4ndCBiZWVuIHBvc2l0aW9uZWQgeWV0LCBidXQgZGltZW5zaW9ucyBhcmUgY29ycmVjdC5cclxuXHRcdC8vIFZhcmlhYmxlcyBzZXQgaW4gX2NvbmZpZ3VyZSBhcmUgbmVlZGVkIGZvciBjYWxjdWxhdGVUaWNrUm90YXRpb24sIGFuZFxyXG5cdFx0Ly8gaXQncyBvayB0aGF0IGNvb3JkaW5hdGVzIGFyZSBub3QgY29ycmVjdCB0aGVyZSwgb25seSBkaW1lbnNpb25zIG1hdHRlci5cclxuXHRcdG1lLl9jb25maWd1cmUoKTtcclxuXHJcblx0XHQvLyBUaWNrIFJvdGF0aW9uXHJcblx0XHRtZS5iZWZvcmVDYWxjdWxhdGVUaWNrUm90YXRpb24oKTtcclxuXHRcdG1lLmNhbGN1bGF0ZVRpY2tSb3RhdGlvbigpO1xyXG5cdFx0bWUuYWZ0ZXJDYWxjdWxhdGVUaWNrUm90YXRpb24oKTtcclxuXHJcblx0XHRtZS5iZWZvcmVGaXQoKTtcclxuXHRcdG1lLmZpdCgpO1xyXG5cdFx0bWUuYWZ0ZXJGaXQoKTtcclxuXHJcblx0XHQvLyBBdXRvLXNraXBcclxuXHRcdG1lLl90aWNrc1RvRHJhdyA9IHRpY2tPcHRzLmRpc3BsYXkgJiYgKHRpY2tPcHRzLmF1dG9Ta2lwIHx8IHRpY2tPcHRzLnNvdXJjZSA9PT0gJ2F1dG8nKSA/IG1lLl9hdXRvU2tpcCh0aWNrcykgOiB0aWNrcztcclxuXHJcblx0XHRpZiAoc2FtcGxpbmdFbmFibGVkKSB7XHJcblx0XHRcdC8vIEdlbmVyYXRlIGxhYmVscyB1c2luZyBhbGwgbm9uLXNraXBwZWQgdGlja3NcclxuXHRcdFx0bGFiZWxzID0gbWUuX2NvbnZlcnRUaWNrc1RvTGFiZWxzKG1lLl90aWNrc1RvRHJhdyk7XHJcblx0XHR9XHJcblxyXG5cdFx0bWUudGlja3MgPSBsYWJlbHM7ICAgLy8gQkFDS1dBUkQgQ09NUEFUSUJJTElUWVxyXG5cclxuXHRcdC8vIElNUE9SVEFOVDogYWZ0ZXIgdGhpcyBwb2ludCwgd2UgY29uc2lkZXIgdGhhdCBgdGhpcy50aWNrc2Agd2lsbCBORVZFUiBjaGFuZ2UhXHJcblxyXG5cdFx0bWUuYWZ0ZXJVcGRhdGUoKTtcclxuXHJcblx0XHQvLyBUT0RPKHYzKTogcmVtb3ZlIG1pblNpemUgYXMgYSBwdWJsaWMgcHJvcGVydHkgYW5kIHJldHVybiB2YWx1ZSBmcm9tIGFsbCBsYXlvdXQgYm94ZXMuIEl0IGlzIHVudXNlZFxyXG5cdFx0Ly8gbWFrZSBtYXhXaWR0aCBhbmQgbWF4SGVpZ2h0IHByaXZhdGVcclxuXHRcdHJldHVybiBtZS5taW5TaXplO1xyXG5cdH0sXHJcblxyXG5cdC8qKlxyXG5cdCAqIEBwcml2YXRlXHJcblx0ICovXHJcblx0X2NvbmZpZ3VyZTogZnVuY3Rpb24oKSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0dmFyIHJldmVyc2VQaXhlbHMgPSBtZS5vcHRpb25zLnRpY2tzLnJldmVyc2U7XHJcblx0XHR2YXIgc3RhcnRQaXhlbCwgZW5kUGl4ZWw7XHJcblxyXG5cdFx0aWYgKG1lLmlzSG9yaXpvbnRhbCgpKSB7XHJcblx0XHRcdHN0YXJ0UGl4ZWwgPSBtZS5sZWZ0O1xyXG5cdFx0XHRlbmRQaXhlbCA9IG1lLnJpZ2h0O1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0c3RhcnRQaXhlbCA9IG1lLnRvcDtcclxuXHRcdFx0ZW5kUGl4ZWwgPSBtZS5ib3R0b207XHJcblx0XHRcdC8vIGJ5IGRlZmF1bHQgdmVydGljYWwgc2NhbGVzIGFyZSBmcm9tIGJvdHRvbSB0byB0b3AsIHNvIHBpeGVscyBhcmUgcmV2ZXJzZWRcclxuXHRcdFx0cmV2ZXJzZVBpeGVscyA9ICFyZXZlcnNlUGl4ZWxzO1xyXG5cdFx0fVxyXG5cdFx0bWUuX3N0YXJ0UGl4ZWwgPSBzdGFydFBpeGVsO1xyXG5cdFx0bWUuX2VuZFBpeGVsID0gZW5kUGl4ZWw7XHJcblx0XHRtZS5fcmV2ZXJzZVBpeGVscyA9IHJldmVyc2VQaXhlbHM7XHJcblx0XHRtZS5fbGVuZ3RoID0gZW5kUGl4ZWwgLSBzdGFydFBpeGVsO1xyXG5cdH0sXHJcblxyXG5cdGFmdGVyVXBkYXRlOiBmdW5jdGlvbigpIHtcclxuXHRcdGhlbHBlcnMkMS5jYWxsYmFjayh0aGlzLm9wdGlvbnMuYWZ0ZXJVcGRhdGUsIFt0aGlzXSk7XHJcblx0fSxcclxuXHJcblx0Ly9cclxuXHJcblx0YmVmb3JlU2V0RGltZW5zaW9uczogZnVuY3Rpb24oKSB7XHJcblx0XHRoZWxwZXJzJDEuY2FsbGJhY2sodGhpcy5vcHRpb25zLmJlZm9yZVNldERpbWVuc2lvbnMsIFt0aGlzXSk7XHJcblx0fSxcclxuXHRzZXREaW1lbnNpb25zOiBmdW5jdGlvbigpIHtcclxuXHRcdHZhciBtZSA9IHRoaXM7XHJcblx0XHQvLyBTZXQgdGhlIHVuY29uc3RyYWluZWQgZGltZW5zaW9uIGJlZm9yZSBsYWJlbCByb3RhdGlvblxyXG5cdFx0aWYgKG1lLmlzSG9yaXpvbnRhbCgpKSB7XHJcblx0XHRcdC8vIFJlc2V0IHBvc2l0aW9uIGJlZm9yZSBjYWxjdWxhdGluZyByb3RhdGlvblxyXG5cdFx0XHRtZS53aWR0aCA9IG1lLm1heFdpZHRoO1xyXG5cdFx0XHRtZS5sZWZ0ID0gMDtcclxuXHRcdFx0bWUucmlnaHQgPSBtZS53aWR0aDtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdG1lLmhlaWdodCA9IG1lLm1heEhlaWdodDtcclxuXHJcblx0XHRcdC8vIFJlc2V0IHBvc2l0aW9uIGJlZm9yZSBjYWxjdWxhdGluZyByb3RhdGlvblxyXG5cdFx0XHRtZS50b3AgPSAwO1xyXG5cdFx0XHRtZS5ib3R0b20gPSBtZS5oZWlnaHQ7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gUmVzZXQgcGFkZGluZ1xyXG5cdFx0bWUucGFkZGluZ0xlZnQgPSAwO1xyXG5cdFx0bWUucGFkZGluZ1RvcCA9IDA7XHJcblx0XHRtZS5wYWRkaW5nUmlnaHQgPSAwO1xyXG5cdFx0bWUucGFkZGluZ0JvdHRvbSA9IDA7XHJcblx0fSxcclxuXHRhZnRlclNldERpbWVuc2lvbnM6IGZ1bmN0aW9uKCkge1xyXG5cdFx0aGVscGVycyQxLmNhbGxiYWNrKHRoaXMub3B0aW9ucy5hZnRlclNldERpbWVuc2lvbnMsIFt0aGlzXSk7XHJcblx0fSxcclxuXHJcblx0Ly8gRGF0YSBsaW1pdHNcclxuXHRiZWZvcmVEYXRhTGltaXRzOiBmdW5jdGlvbigpIHtcclxuXHRcdGhlbHBlcnMkMS5jYWxsYmFjayh0aGlzLm9wdGlvbnMuYmVmb3JlRGF0YUxpbWl0cywgW3RoaXNdKTtcclxuXHR9LFxyXG5cdGRldGVybWluZURhdGFMaW1pdHM6IGhlbHBlcnMkMS5ub29wLFxyXG5cdGFmdGVyRGF0YUxpbWl0czogZnVuY3Rpb24oKSB7XHJcblx0XHRoZWxwZXJzJDEuY2FsbGJhY2sodGhpcy5vcHRpb25zLmFmdGVyRGF0YUxpbWl0cywgW3RoaXNdKTtcclxuXHR9LFxyXG5cclxuXHQvL1xyXG5cdGJlZm9yZUJ1aWxkVGlja3M6IGZ1bmN0aW9uKCkge1xyXG5cdFx0aGVscGVycyQxLmNhbGxiYWNrKHRoaXMub3B0aW9ucy5iZWZvcmVCdWlsZFRpY2tzLCBbdGhpc10pO1xyXG5cdH0sXHJcblx0YnVpbGRUaWNrczogaGVscGVycyQxLm5vb3AsXHJcblx0YWZ0ZXJCdWlsZFRpY2tzOiBmdW5jdGlvbih0aWNrcykge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHRcdC8vIHRpY2tzIGlzIGVtcHR5IGZvciBvbGQgYXhpcyBpbXBsZW1lbnRhdGlvbnMgaGVyZVxyXG5cdFx0aWYgKGlzQXJyYXkodGlja3MpICYmIHRpY2tzLmxlbmd0aCkge1xyXG5cdFx0XHRyZXR1cm4gaGVscGVycyQxLmNhbGxiYWNrKG1lLm9wdGlvbnMuYWZ0ZXJCdWlsZFRpY2tzLCBbbWUsIHRpY2tzXSk7XHJcblx0XHR9XHJcblx0XHQvLyBTdXBwb3J0IG9sZCBpbXBsZW1lbnRhdGlvbnMgKHRoYXQgbW9kaWZpZWQgYHRoaXMudGlja3NgIGRpcmVjdGx5IGluIGJ1aWxkVGlja3MpXHJcblx0XHRtZS50aWNrcyA9IGhlbHBlcnMkMS5jYWxsYmFjayhtZS5vcHRpb25zLmFmdGVyQnVpbGRUaWNrcywgW21lLCBtZS50aWNrc10pIHx8IG1lLnRpY2tzO1xyXG5cdFx0cmV0dXJuIHRpY2tzO1xyXG5cdH0sXHJcblxyXG5cdGJlZm9yZVRpY2tUb0xhYmVsQ29udmVyc2lvbjogZnVuY3Rpb24oKSB7XHJcblx0XHRoZWxwZXJzJDEuY2FsbGJhY2sodGhpcy5vcHRpb25zLmJlZm9yZVRpY2tUb0xhYmVsQ29udmVyc2lvbiwgW3RoaXNdKTtcclxuXHR9LFxyXG5cdGNvbnZlcnRUaWNrc1RvTGFiZWxzOiBmdW5jdGlvbigpIHtcclxuXHRcdHZhciBtZSA9IHRoaXM7XHJcblx0XHQvLyBDb252ZXJ0IHRpY2tzIHRvIHN0cmluZ3NcclxuXHRcdHZhciB0aWNrT3B0cyA9IG1lLm9wdGlvbnMudGlja3M7XHJcblx0XHRtZS50aWNrcyA9IG1lLnRpY2tzLm1hcCh0aWNrT3B0cy51c2VyQ2FsbGJhY2sgfHwgdGlja09wdHMuY2FsbGJhY2ssIHRoaXMpO1xyXG5cdH0sXHJcblx0YWZ0ZXJUaWNrVG9MYWJlbENvbnZlcnNpb246IGZ1bmN0aW9uKCkge1xyXG5cdFx0aGVscGVycyQxLmNhbGxiYWNrKHRoaXMub3B0aW9ucy5hZnRlclRpY2tUb0xhYmVsQ29udmVyc2lvbiwgW3RoaXNdKTtcclxuXHR9LFxyXG5cclxuXHQvL1xyXG5cclxuXHRiZWZvcmVDYWxjdWxhdGVUaWNrUm90YXRpb246IGZ1bmN0aW9uKCkge1xyXG5cdFx0aGVscGVycyQxLmNhbGxiYWNrKHRoaXMub3B0aW9ucy5iZWZvcmVDYWxjdWxhdGVUaWNrUm90YXRpb24sIFt0aGlzXSk7XHJcblx0fSxcclxuXHRjYWxjdWxhdGVUaWNrUm90YXRpb246IGZ1bmN0aW9uKCkge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHRcdHZhciBvcHRpb25zID0gbWUub3B0aW9ucztcclxuXHRcdHZhciB0aWNrT3B0cyA9IG9wdGlvbnMudGlja3M7XHJcblx0XHR2YXIgbnVtVGlja3MgPSBtZS5nZXRUaWNrcygpLmxlbmd0aDtcclxuXHRcdHZhciBtaW5Sb3RhdGlvbiA9IHRpY2tPcHRzLm1pblJvdGF0aW9uIHx8IDA7XHJcblx0XHR2YXIgbWF4Um90YXRpb24gPSB0aWNrT3B0cy5tYXhSb3RhdGlvbjtcclxuXHRcdHZhciBsYWJlbFJvdGF0aW9uID0gbWluUm90YXRpb247XHJcblx0XHR2YXIgbGFiZWxTaXplcywgbWF4TGFiZWxXaWR0aCwgbWF4TGFiZWxIZWlnaHQsIG1heFdpZHRoLCB0aWNrV2lkdGgsIG1heEhlaWdodCwgbWF4TGFiZWxEaWFnb25hbDtcclxuXHJcblx0XHRpZiAoIW1lLl9pc1Zpc2libGUoKSB8fCAhdGlja09wdHMuZGlzcGxheSB8fCBtaW5Sb3RhdGlvbiA+PSBtYXhSb3RhdGlvbiB8fCBudW1UaWNrcyA8PSAxIHx8ICFtZS5pc0hvcml6b250YWwoKSkge1xyXG5cdFx0XHRtZS5sYWJlbFJvdGF0aW9uID0gbWluUm90YXRpb247XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHJcblx0XHRsYWJlbFNpemVzID0gbWUuX2dldExhYmVsU2l6ZXMoKTtcclxuXHRcdG1heExhYmVsV2lkdGggPSBsYWJlbFNpemVzLndpZGVzdC53aWR0aDtcclxuXHRcdG1heExhYmVsSGVpZ2h0ID0gbGFiZWxTaXplcy5oaWdoZXN0LmhlaWdodCAtIGxhYmVsU2l6ZXMuaGlnaGVzdC5vZmZzZXQ7XHJcblxyXG5cdFx0Ly8gRXN0aW1hdGUgdGhlIHdpZHRoIG9mIGVhY2ggZ3JpZCBiYXNlZCBvbiB0aGUgY2FudmFzIHdpZHRoLCB0aGUgbWF4aW11bVxyXG5cdFx0Ly8gbGFiZWwgd2lkdGggYW5kIHRoZSBudW1iZXIgb2YgdGljayBpbnRlcnZhbHNcclxuXHRcdG1heFdpZHRoID0gTWF0aC5taW4obWUubWF4V2lkdGgsIG1lLmNoYXJ0LndpZHRoIC0gbWF4TGFiZWxXaWR0aCk7XHJcblx0XHR0aWNrV2lkdGggPSBvcHRpb25zLm9mZnNldCA/IG1lLm1heFdpZHRoIC8gbnVtVGlja3MgOiBtYXhXaWR0aCAvIChudW1UaWNrcyAtIDEpO1xyXG5cclxuXHRcdC8vIEFsbG93IDMgcGl4ZWxzIHgyIHBhZGRpbmcgZWl0aGVyIHNpZGUgZm9yIGxhYmVsIHJlYWRhYmlsaXR5XHJcblx0XHRpZiAobWF4TGFiZWxXaWR0aCArIDYgPiB0aWNrV2lkdGgpIHtcclxuXHRcdFx0dGlja1dpZHRoID0gbWF4V2lkdGggLyAobnVtVGlja3MgLSAob3B0aW9ucy5vZmZzZXQgPyAwLjUgOiAxKSk7XHJcblx0XHRcdG1heEhlaWdodCA9IG1lLm1heEhlaWdodCAtIGdldFRpY2tNYXJrTGVuZ3RoKG9wdGlvbnMuZ3JpZExpbmVzKVxyXG5cdFx0XHRcdC0gdGlja09wdHMucGFkZGluZyAtIGdldFNjYWxlTGFiZWxIZWlnaHQob3B0aW9ucy5zY2FsZUxhYmVsKTtcclxuXHRcdFx0bWF4TGFiZWxEaWFnb25hbCA9IE1hdGguc3FydChtYXhMYWJlbFdpZHRoICogbWF4TGFiZWxXaWR0aCArIG1heExhYmVsSGVpZ2h0ICogbWF4TGFiZWxIZWlnaHQpO1xyXG5cdFx0XHRsYWJlbFJvdGF0aW9uID0gaGVscGVycyQxLnRvRGVncmVlcyhNYXRoLm1pbihcclxuXHRcdFx0XHRNYXRoLmFzaW4oTWF0aC5taW4oKGxhYmVsU2l6ZXMuaGlnaGVzdC5oZWlnaHQgKyA2KSAvIHRpY2tXaWR0aCwgMSkpLFxyXG5cdFx0XHRcdE1hdGguYXNpbihNYXRoLm1pbihtYXhIZWlnaHQgLyBtYXhMYWJlbERpYWdvbmFsLCAxKSkgLSBNYXRoLmFzaW4obWF4TGFiZWxIZWlnaHQgLyBtYXhMYWJlbERpYWdvbmFsKVxyXG5cdFx0XHQpKTtcclxuXHRcdFx0bGFiZWxSb3RhdGlvbiA9IE1hdGgubWF4KG1pblJvdGF0aW9uLCBNYXRoLm1pbihtYXhSb3RhdGlvbiwgbGFiZWxSb3RhdGlvbikpO1xyXG5cdFx0fVxyXG5cclxuXHRcdG1lLmxhYmVsUm90YXRpb24gPSBsYWJlbFJvdGF0aW9uO1xyXG5cdH0sXHJcblx0YWZ0ZXJDYWxjdWxhdGVUaWNrUm90YXRpb246IGZ1bmN0aW9uKCkge1xyXG5cdFx0aGVscGVycyQxLmNhbGxiYWNrKHRoaXMub3B0aW9ucy5hZnRlckNhbGN1bGF0ZVRpY2tSb3RhdGlvbiwgW3RoaXNdKTtcclxuXHR9LFxyXG5cclxuXHQvL1xyXG5cclxuXHRiZWZvcmVGaXQ6IGZ1bmN0aW9uKCkge1xyXG5cdFx0aGVscGVycyQxLmNhbGxiYWNrKHRoaXMub3B0aW9ucy5iZWZvcmVGaXQsIFt0aGlzXSk7XHJcblx0fSxcclxuXHRmaXQ6IGZ1bmN0aW9uKCkge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHRcdC8vIFJlc2V0XHJcblx0XHR2YXIgbWluU2l6ZSA9IG1lLm1pblNpemUgPSB7XHJcblx0XHRcdHdpZHRoOiAwLFxyXG5cdFx0XHRoZWlnaHQ6IDBcclxuXHRcdH07XHJcblxyXG5cdFx0dmFyIGNoYXJ0ID0gbWUuY2hhcnQ7XHJcblx0XHR2YXIgb3B0cyA9IG1lLm9wdGlvbnM7XHJcblx0XHR2YXIgdGlja09wdHMgPSBvcHRzLnRpY2tzO1xyXG5cdFx0dmFyIHNjYWxlTGFiZWxPcHRzID0gb3B0cy5zY2FsZUxhYmVsO1xyXG5cdFx0dmFyIGdyaWRMaW5lT3B0cyA9IG9wdHMuZ3JpZExpbmVzO1xyXG5cdFx0dmFyIGRpc3BsYXkgPSBtZS5faXNWaXNpYmxlKCk7XHJcblx0XHR2YXIgaXNCb3R0b20gPSBvcHRzLnBvc2l0aW9uID09PSAnYm90dG9tJztcclxuXHRcdHZhciBpc0hvcml6b250YWwgPSBtZS5pc0hvcml6b250YWwoKTtcclxuXHJcblx0XHQvLyBXaWR0aFxyXG5cdFx0aWYgKGlzSG9yaXpvbnRhbCkge1xyXG5cdFx0XHRtaW5TaXplLndpZHRoID0gbWUubWF4V2lkdGg7XHJcblx0XHR9IGVsc2UgaWYgKGRpc3BsYXkpIHtcclxuXHRcdFx0bWluU2l6ZS53aWR0aCA9IGdldFRpY2tNYXJrTGVuZ3RoKGdyaWRMaW5lT3B0cykgKyBnZXRTY2FsZUxhYmVsSGVpZ2h0KHNjYWxlTGFiZWxPcHRzKTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBoZWlnaHRcclxuXHRcdGlmICghaXNIb3Jpem9udGFsKSB7XHJcblx0XHRcdG1pblNpemUuaGVpZ2h0ID0gbWUubWF4SGVpZ2h0OyAvLyBmaWxsIGFsbCB0aGUgaGVpZ2h0XHJcblx0XHR9IGVsc2UgaWYgKGRpc3BsYXkpIHtcclxuXHRcdFx0bWluU2l6ZS5oZWlnaHQgPSBnZXRUaWNrTWFya0xlbmd0aChncmlkTGluZU9wdHMpICsgZ2V0U2NhbGVMYWJlbEhlaWdodChzY2FsZUxhYmVsT3B0cyk7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gRG9uJ3QgYm90aGVyIGZpdHRpbmcgdGhlIHRpY2tzIGlmIHdlIGFyZSBub3Qgc2hvd2luZyB0aGUgbGFiZWxzXHJcblx0XHRpZiAodGlja09wdHMuZGlzcGxheSAmJiBkaXNwbGF5KSB7XHJcblx0XHRcdHZhciB0aWNrRm9udHMgPSBwYXJzZVRpY2tGb250T3B0aW9ucyh0aWNrT3B0cyk7XHJcblx0XHRcdHZhciBsYWJlbFNpemVzID0gbWUuX2dldExhYmVsU2l6ZXMoKTtcclxuXHRcdFx0dmFyIGZpcnN0TGFiZWxTaXplID0gbGFiZWxTaXplcy5maXJzdDtcclxuXHRcdFx0dmFyIGxhc3RMYWJlbFNpemUgPSBsYWJlbFNpemVzLmxhc3Q7XHJcblx0XHRcdHZhciB3aWRlc3RMYWJlbFNpemUgPSBsYWJlbFNpemVzLndpZGVzdDtcclxuXHRcdFx0dmFyIGhpZ2hlc3RMYWJlbFNpemUgPSBsYWJlbFNpemVzLmhpZ2hlc3Q7XHJcblx0XHRcdHZhciBsaW5lU3BhY2UgPSB0aWNrRm9udHMubWlub3IubGluZUhlaWdodCAqIDAuNDtcclxuXHRcdFx0dmFyIHRpY2tQYWRkaW5nID0gdGlja09wdHMucGFkZGluZztcclxuXHJcblx0XHRcdGlmIChpc0hvcml6b250YWwpIHtcclxuXHRcdFx0XHQvLyBBIGhvcml6b250YWwgYXhpcyBpcyBtb3JlIGNvbnN0cmFpbmVkIGJ5IHRoZSBoZWlnaHQuXHJcblx0XHRcdFx0dmFyIGlzUm90YXRlZCA9IG1lLmxhYmVsUm90YXRpb24gIT09IDA7XHJcblx0XHRcdFx0dmFyIGFuZ2xlUmFkaWFucyA9IGhlbHBlcnMkMS50b1JhZGlhbnMobWUubGFiZWxSb3RhdGlvbik7XHJcblx0XHRcdFx0dmFyIGNvc1JvdGF0aW9uID0gTWF0aC5jb3MoYW5nbGVSYWRpYW5zKTtcclxuXHRcdFx0XHR2YXIgc2luUm90YXRpb24gPSBNYXRoLnNpbihhbmdsZVJhZGlhbnMpO1xyXG5cclxuXHRcdFx0XHR2YXIgbGFiZWxIZWlnaHQgPSBzaW5Sb3RhdGlvbiAqIHdpZGVzdExhYmVsU2l6ZS53aWR0aFxyXG5cdFx0XHRcdFx0KyBjb3NSb3RhdGlvbiAqIChoaWdoZXN0TGFiZWxTaXplLmhlaWdodCAtIChpc1JvdGF0ZWQgPyBoaWdoZXN0TGFiZWxTaXplLm9mZnNldCA6IDApKVxyXG5cdFx0XHRcdFx0KyAoaXNSb3RhdGVkID8gMCA6IGxpbmVTcGFjZSk7IC8vIHBhZGRpbmdcclxuXHJcblx0XHRcdFx0bWluU2l6ZS5oZWlnaHQgPSBNYXRoLm1pbihtZS5tYXhIZWlnaHQsIG1pblNpemUuaGVpZ2h0ICsgbGFiZWxIZWlnaHQgKyB0aWNrUGFkZGluZyk7XHJcblxyXG5cdFx0XHRcdHZhciBvZmZzZXRMZWZ0ID0gbWUuZ2V0UGl4ZWxGb3JUaWNrKDApIC0gbWUubGVmdDtcclxuXHRcdFx0XHR2YXIgb2Zmc2V0UmlnaHQgPSBtZS5yaWdodCAtIG1lLmdldFBpeGVsRm9yVGljayhtZS5nZXRUaWNrcygpLmxlbmd0aCAtIDEpO1xyXG5cdFx0XHRcdHZhciBwYWRkaW5nTGVmdCwgcGFkZGluZ1JpZ2h0O1xyXG5cclxuXHRcdFx0XHQvLyBFbnN1cmUgdGhhdCBvdXIgdGlja3MgYXJlIGFsd2F5cyBpbnNpZGUgdGhlIGNhbnZhcy4gV2hlbiByb3RhdGVkLCB0aWNrcyBhcmUgcmlnaHQgYWxpZ25lZFxyXG5cdFx0XHRcdC8vIHdoaWNoIG1lYW5zIHRoYXQgdGhlIHJpZ2h0IHBhZGRpbmcgaXMgZG9taW5hdGVkIGJ5IHRoZSBmb250IGhlaWdodFxyXG5cdFx0XHRcdGlmIChpc1JvdGF0ZWQpIHtcclxuXHRcdFx0XHRcdHBhZGRpbmdMZWZ0ID0gaXNCb3R0b20gP1xyXG5cdFx0XHRcdFx0XHRjb3NSb3RhdGlvbiAqIGZpcnN0TGFiZWxTaXplLndpZHRoICsgc2luUm90YXRpb24gKiBmaXJzdExhYmVsU2l6ZS5vZmZzZXQgOlxyXG5cdFx0XHRcdFx0XHRzaW5Sb3RhdGlvbiAqIChmaXJzdExhYmVsU2l6ZS5oZWlnaHQgLSBmaXJzdExhYmVsU2l6ZS5vZmZzZXQpO1xyXG5cdFx0XHRcdFx0cGFkZGluZ1JpZ2h0ID0gaXNCb3R0b20gP1xyXG5cdFx0XHRcdFx0XHRzaW5Sb3RhdGlvbiAqIChsYXN0TGFiZWxTaXplLmhlaWdodCAtIGxhc3RMYWJlbFNpemUub2Zmc2V0KSA6XHJcblx0XHRcdFx0XHRcdGNvc1JvdGF0aW9uICogbGFzdExhYmVsU2l6ZS53aWR0aCArIHNpblJvdGF0aW9uICogbGFzdExhYmVsU2l6ZS5vZmZzZXQ7XHJcblx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdHBhZGRpbmdMZWZ0ID0gZmlyc3RMYWJlbFNpemUud2lkdGggLyAyO1xyXG5cdFx0XHRcdFx0cGFkZGluZ1JpZ2h0ID0gbGFzdExhYmVsU2l6ZS53aWR0aCAvIDI7XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHQvLyBBZGp1c3QgcGFkZGluZyB0YWtpbmcgaW50byBhY2NvdW50IGNoYW5nZXMgaW4gb2Zmc2V0c1xyXG5cdFx0XHRcdC8vIGFuZCBhZGQgMyBweCB0byBtb3ZlIGF3YXkgZnJvbSBjYW52YXMgZWRnZXNcclxuXHRcdFx0XHRtZS5wYWRkaW5nTGVmdCA9IE1hdGgubWF4KChwYWRkaW5nTGVmdCAtIG9mZnNldExlZnQpICogbWUud2lkdGggLyAobWUud2lkdGggLSBvZmZzZXRMZWZ0KSwgMCkgKyAzO1xyXG5cdFx0XHRcdG1lLnBhZGRpbmdSaWdodCA9IE1hdGgubWF4KChwYWRkaW5nUmlnaHQgLSBvZmZzZXRSaWdodCkgKiBtZS53aWR0aCAvIChtZS53aWR0aCAtIG9mZnNldFJpZ2h0KSwgMCkgKyAzO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdC8vIEEgdmVydGljYWwgYXhpcyBpcyBtb3JlIGNvbnN0cmFpbmVkIGJ5IHRoZSB3aWR0aC4gTGFiZWxzIGFyZSB0aGVcclxuXHRcdFx0XHQvLyBkb21pbmFudCBmYWN0b3IgaGVyZSwgc28gZ2V0IHRoYXQgbGVuZ3RoIGZpcnN0IGFuZCBhY2NvdW50IGZvciBwYWRkaW5nXHJcblx0XHRcdFx0dmFyIGxhYmVsV2lkdGggPSB0aWNrT3B0cy5taXJyb3IgPyAwIDpcclxuXHRcdFx0XHRcdC8vIHVzZSBsaW5lU3BhY2UgZm9yIGNvbnNpc3RlbmN5IHdpdGggaG9yaXpvbnRhbCBheGlzXHJcblx0XHRcdFx0XHQvLyB0aWNrUGFkZGluZyBpcyBub3QgaW1wbGVtZW50ZWQgZm9yIGhvcml6b250YWxcclxuXHRcdFx0XHRcdHdpZGVzdExhYmVsU2l6ZS53aWR0aCArIHRpY2tQYWRkaW5nICsgbGluZVNwYWNlO1xyXG5cclxuXHRcdFx0XHRtaW5TaXplLndpZHRoID0gTWF0aC5taW4obWUubWF4V2lkdGgsIG1pblNpemUud2lkdGggKyBsYWJlbFdpZHRoKTtcclxuXHJcblx0XHRcdFx0bWUucGFkZGluZ1RvcCA9IGZpcnN0TGFiZWxTaXplLmhlaWdodCAvIDI7XHJcblx0XHRcdFx0bWUucGFkZGluZ0JvdHRvbSA9IGxhc3RMYWJlbFNpemUuaGVpZ2h0IC8gMjtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdG1lLmhhbmRsZU1hcmdpbnMoKTtcclxuXHJcblx0XHRpZiAoaXNIb3Jpem9udGFsKSB7XHJcblx0XHRcdG1lLndpZHRoID0gbWUuX2xlbmd0aCA9IGNoYXJ0LndpZHRoIC0gbWUubWFyZ2lucy5sZWZ0IC0gbWUubWFyZ2lucy5yaWdodDtcclxuXHRcdFx0bWUuaGVpZ2h0ID0gbWluU2l6ZS5oZWlnaHQ7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRtZS53aWR0aCA9IG1pblNpemUud2lkdGg7XHJcblx0XHRcdG1lLmhlaWdodCA9IG1lLl9sZW5ndGggPSBjaGFydC5oZWlnaHQgLSBtZS5tYXJnaW5zLnRvcCAtIG1lLm1hcmdpbnMuYm90dG9tO1xyXG5cdFx0fVxyXG5cdH0sXHJcblxyXG5cdC8qKlxyXG5cdCAqIEhhbmRsZSBtYXJnaW5zIGFuZCBwYWRkaW5nIGludGVyYWN0aW9uc1xyXG5cdCAqIEBwcml2YXRlXHJcblx0ICovXHJcblx0aGFuZGxlTWFyZ2luczogZnVuY3Rpb24oKSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0aWYgKG1lLm1hcmdpbnMpIHtcclxuXHRcdFx0bWUubWFyZ2lucy5sZWZ0ID0gTWF0aC5tYXgobWUucGFkZGluZ0xlZnQsIG1lLm1hcmdpbnMubGVmdCk7XHJcblx0XHRcdG1lLm1hcmdpbnMudG9wID0gTWF0aC5tYXgobWUucGFkZGluZ1RvcCwgbWUubWFyZ2lucy50b3ApO1xyXG5cdFx0XHRtZS5tYXJnaW5zLnJpZ2h0ID0gTWF0aC5tYXgobWUucGFkZGluZ1JpZ2h0LCBtZS5tYXJnaW5zLnJpZ2h0KTtcclxuXHRcdFx0bWUubWFyZ2lucy5ib3R0b20gPSBNYXRoLm1heChtZS5wYWRkaW5nQm90dG9tLCBtZS5tYXJnaW5zLmJvdHRvbSk7XHJcblx0XHR9XHJcblx0fSxcclxuXHJcblx0YWZ0ZXJGaXQ6IGZ1bmN0aW9uKCkge1xyXG5cdFx0aGVscGVycyQxLmNhbGxiYWNrKHRoaXMub3B0aW9ucy5hZnRlckZpdCwgW3RoaXNdKTtcclxuXHR9LFxyXG5cclxuXHQvLyBTaGFyZWQgTWV0aG9kc1xyXG5cdGlzSG9yaXpvbnRhbDogZnVuY3Rpb24oKSB7XHJcblx0XHR2YXIgcG9zID0gdGhpcy5vcHRpb25zLnBvc2l0aW9uO1xyXG5cdFx0cmV0dXJuIHBvcyA9PT0gJ3RvcCcgfHwgcG9zID09PSAnYm90dG9tJztcclxuXHR9LFxyXG5cdGlzRnVsbFdpZHRoOiBmdW5jdGlvbigpIHtcclxuXHRcdHJldHVybiB0aGlzLm9wdGlvbnMuZnVsbFdpZHRoO1xyXG5cdH0sXHJcblxyXG5cdC8vIEdldCB0aGUgY29ycmVjdCB2YWx1ZS4gTmFOIGJhZCBpbnB1dHMsIElmIHRoZSB2YWx1ZSB0eXBlIGlzIG9iamVjdCBnZXQgdGhlIHggb3IgeSBiYXNlZCBvbiB3aGV0aGVyIHdlIGFyZSBob3Jpem9udGFsIG9yIG5vdFxyXG5cdGdldFJpZ2h0VmFsdWU6IGZ1bmN0aW9uKHJhd1ZhbHVlKSB7XHJcblx0XHQvLyBOdWxsIGFuZCB1bmRlZmluZWQgdmFsdWVzIGZpcnN0XHJcblx0XHRpZiAoaXNOdWxsT3JVbmRlZihyYXdWYWx1ZSkpIHtcclxuXHRcdFx0cmV0dXJuIE5hTjtcclxuXHRcdH1cclxuXHRcdC8vIGlzTmFOKG9iamVjdCkgcmV0dXJucyB0cnVlLCBzbyBtYWtlIHN1cmUgTmFOIGlzIGNoZWNraW5nIGZvciBhIG51bWJlcjsgRGlzY2FyZCBJbmZpbml0ZSB2YWx1ZXNcclxuXHRcdGlmICgodHlwZW9mIHJhd1ZhbHVlID09PSAnbnVtYmVyJyB8fCByYXdWYWx1ZSBpbnN0YW5jZW9mIE51bWJlcikgJiYgIWlzRmluaXRlKHJhd1ZhbHVlKSkge1xyXG5cdFx0XHRyZXR1cm4gTmFOO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIElmIGl0IGlzIGluIGZhY3QgYW4gb2JqZWN0LCBkaXZlIGluIG9uZSBtb3JlIGxldmVsXHJcblx0XHRpZiAocmF3VmFsdWUpIHtcclxuXHRcdFx0aWYgKHRoaXMuaXNIb3Jpem9udGFsKCkpIHtcclxuXHRcdFx0XHRpZiAocmF3VmFsdWUueCAhPT0gdW5kZWZpbmVkKSB7XHJcblx0XHRcdFx0XHRyZXR1cm4gdGhpcy5nZXRSaWdodFZhbHVlKHJhd1ZhbHVlLngpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSBlbHNlIGlmIChyYXdWYWx1ZS55ICE9PSB1bmRlZmluZWQpIHtcclxuXHRcdFx0XHRyZXR1cm4gdGhpcy5nZXRSaWdodFZhbHVlKHJhd1ZhbHVlLnkpO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gVmFsdWUgaXMgZ29vZCwgcmV0dXJuIGl0XHJcblx0XHRyZXR1cm4gcmF3VmFsdWU7XHJcblx0fSxcclxuXHJcblx0X2NvbnZlcnRUaWNrc1RvTGFiZWxzOiBmdW5jdGlvbih0aWNrcykge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHRcdHZhciBsYWJlbHMsIGksIGlsZW47XHJcblxyXG5cdFx0bWUudGlja3MgPSB0aWNrcy5tYXAoZnVuY3Rpb24odGljaykge1xyXG5cdFx0XHRyZXR1cm4gdGljay52YWx1ZTtcclxuXHRcdH0pO1xyXG5cclxuXHRcdG1lLmJlZm9yZVRpY2tUb0xhYmVsQ29udmVyc2lvbigpO1xyXG5cclxuXHRcdC8vIE5ldyBpbXBsZW1lbnRhdGlvbnMgc2hvdWxkIHJldHVybiB0aGUgZm9ybWF0dGVkIHRpY2sgbGFiZWxzIGJ1dCBmb3IgQkFDS1dBUkRcclxuXHRcdC8vIENPTVBBVCwgd2Ugc3RpbGwgc3VwcG9ydCBubyByZXR1cm4gKGB0aGlzLnRpY2tzYCBpbnRlcm5hbGx5IGNoYW5nZWQgYnkgY2FsbGluZ1xyXG5cdFx0Ly8gdGhpcyBtZXRob2QgYW5kIHN1cHBvc2VkIHRvIGNvbnRhaW4gb25seSBzdHJpbmcgdmFsdWVzKS5cclxuXHRcdGxhYmVscyA9IG1lLmNvbnZlcnRUaWNrc1RvTGFiZWxzKHRpY2tzKSB8fCBtZS50aWNrcztcclxuXHJcblx0XHRtZS5hZnRlclRpY2tUb0xhYmVsQ29udmVyc2lvbigpO1xyXG5cclxuXHRcdC8vIEJBQ0tXQVJEIENPTVBBVDogc3luY2hyb25pemUgYF90aWNrc2Agd2l0aCBsYWJlbHMgKHNvIHBvdGVudGlhbGx5IGB0aGlzLnRpY2tzYClcclxuXHRcdGZvciAoaSA9IDAsIGlsZW4gPSB0aWNrcy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcclxuXHRcdFx0dGlja3NbaV0ubGFiZWwgPSBsYWJlbHNbaV07XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIGxhYmVscztcclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBAcHJpdmF0ZVxyXG5cdCAqL1xyXG5cdF9nZXRMYWJlbFNpemVzOiBmdW5jdGlvbigpIHtcclxuXHRcdHZhciBtZSA9IHRoaXM7XHJcblx0XHR2YXIgbGFiZWxTaXplcyA9IG1lLl9sYWJlbFNpemVzO1xyXG5cclxuXHRcdGlmICghbGFiZWxTaXplcykge1xyXG5cdFx0XHRtZS5fbGFiZWxTaXplcyA9IGxhYmVsU2l6ZXMgPSBjb21wdXRlTGFiZWxTaXplcyhtZS5jdHgsIHBhcnNlVGlja0ZvbnRPcHRpb25zKG1lLm9wdGlvbnMudGlja3MpLCBtZS5nZXRUaWNrcygpLCBtZS5sb25nZXN0VGV4dENhY2hlKTtcclxuXHRcdFx0bWUubG9uZ2VzdExhYmVsV2lkdGggPSBsYWJlbFNpemVzLndpZGVzdC53aWR0aDtcclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gbGFiZWxTaXplcztcclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBAcHJpdmF0ZVxyXG5cdCAqL1xyXG5cdF9wYXJzZVZhbHVlOiBmdW5jdGlvbih2YWx1ZSkge1xyXG5cdFx0dmFyIHN0YXJ0LCBlbmQsIG1pbiwgbWF4O1xyXG5cclxuXHRcdGlmIChpc0FycmF5KHZhbHVlKSkge1xyXG5cdFx0XHRzdGFydCA9ICt0aGlzLmdldFJpZ2h0VmFsdWUodmFsdWVbMF0pO1xyXG5cdFx0XHRlbmQgPSArdGhpcy5nZXRSaWdodFZhbHVlKHZhbHVlWzFdKTtcclxuXHRcdFx0bWluID0gTWF0aC5taW4oc3RhcnQsIGVuZCk7XHJcblx0XHRcdG1heCA9IE1hdGgubWF4KHN0YXJ0LCBlbmQpO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0dmFsdWUgPSArdGhpcy5nZXRSaWdodFZhbHVlKHZhbHVlKTtcclxuXHRcdFx0c3RhcnQgPSB1bmRlZmluZWQ7XHJcblx0XHRcdGVuZCA9IHZhbHVlO1xyXG5cdFx0XHRtaW4gPSB2YWx1ZTtcclxuXHRcdFx0bWF4ID0gdmFsdWU7XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIHtcclxuXHRcdFx0bWluOiBtaW4sXHJcblx0XHRcdG1heDogbWF4LFxyXG5cdFx0XHRzdGFydDogc3RhcnQsXHJcblx0XHRcdGVuZDogZW5kXHJcblx0XHR9O1xyXG5cdH0sXHJcblxyXG5cdC8qKlxyXG5cdCogQHByaXZhdGVcclxuXHQqL1xyXG5cdF9nZXRTY2FsZUxhYmVsOiBmdW5jdGlvbihyYXdWYWx1ZSkge1xyXG5cdFx0dmFyIHYgPSB0aGlzLl9wYXJzZVZhbHVlKHJhd1ZhbHVlKTtcclxuXHRcdGlmICh2LnN0YXJ0ICE9PSB1bmRlZmluZWQpIHtcclxuXHRcdFx0cmV0dXJuICdbJyArIHYuc3RhcnQgKyAnLCAnICsgdi5lbmQgKyAnXSc7XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuICt0aGlzLmdldFJpZ2h0VmFsdWUocmF3VmFsdWUpO1xyXG5cdH0sXHJcblxyXG5cdC8qKlxyXG5cdCAqIFVzZWQgdG8gZ2V0IHRoZSB2YWx1ZSB0byBkaXNwbGF5IGluIHRoZSB0b29sdGlwIGZvciB0aGUgZGF0YSBhdCB0aGUgZ2l2ZW4gaW5kZXhcclxuXHQgKiBAcGFyYW0gaW5kZXhcclxuXHQgKiBAcGFyYW0gZGF0YXNldEluZGV4XHJcblx0ICovXHJcblx0Z2V0TGFiZWxGb3JJbmRleDogaGVscGVycyQxLm5vb3AsXHJcblxyXG5cdC8qKlxyXG5cdCAqIFJldHVybnMgdGhlIGxvY2F0aW9uIG9mIHRoZSBnaXZlbiBkYXRhIHBvaW50LiBWYWx1ZSBjYW4gZWl0aGVyIGJlIGFuIGluZGV4IG9yIGEgbnVtZXJpY2FsIHZhbHVlXHJcblx0ICogVGhlIGNvb3JkaW5hdGUgKDAsIDApIGlzIGF0IHRoZSB1cHBlci1sZWZ0IGNvcm5lciBvZiB0aGUgY2FudmFzXHJcblx0ICogQHBhcmFtIHZhbHVlXHJcblx0ICogQHBhcmFtIGluZGV4XHJcblx0ICogQHBhcmFtIGRhdGFzZXRJbmRleFxyXG5cdCAqL1xyXG5cdGdldFBpeGVsRm9yVmFsdWU6IGhlbHBlcnMkMS5ub29wLFxyXG5cclxuXHQvKipcclxuXHQgKiBVc2VkIHRvIGdldCB0aGUgZGF0YSB2YWx1ZSBmcm9tIGEgZ2l2ZW4gcGl4ZWwuIFRoaXMgaXMgdGhlIGludmVyc2Ugb2YgZ2V0UGl4ZWxGb3JWYWx1ZVxyXG5cdCAqIFRoZSBjb29yZGluYXRlICgwLCAwKSBpcyBhdCB0aGUgdXBwZXItbGVmdCBjb3JuZXIgb2YgdGhlIGNhbnZhc1xyXG5cdCAqIEBwYXJhbSBwaXhlbFxyXG5cdCAqL1xyXG5cdGdldFZhbHVlRm9yUGl4ZWw6IGhlbHBlcnMkMS5ub29wLFxyXG5cclxuXHQvKipcclxuXHQgKiBSZXR1cm5zIHRoZSBsb2NhdGlvbiBvZiB0aGUgdGljayBhdCB0aGUgZ2l2ZW4gaW5kZXhcclxuXHQgKiBUaGUgY29vcmRpbmF0ZSAoMCwgMCkgaXMgYXQgdGhlIHVwcGVyLWxlZnQgY29ybmVyIG9mIHRoZSBjYW52YXNcclxuXHQgKi9cclxuXHRnZXRQaXhlbEZvclRpY2s6IGZ1bmN0aW9uKGluZGV4KSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0dmFyIG9mZnNldCA9IG1lLm9wdGlvbnMub2Zmc2V0O1xyXG5cdFx0dmFyIG51bVRpY2tzID0gbWUuX3RpY2tzLmxlbmd0aDtcclxuXHRcdHZhciB0aWNrV2lkdGggPSAxIC8gTWF0aC5tYXgobnVtVGlja3MgLSAob2Zmc2V0ID8gMCA6IDEpLCAxKTtcclxuXHJcblx0XHRyZXR1cm4gaW5kZXggPCAwIHx8IGluZGV4ID4gbnVtVGlja3MgLSAxXHJcblx0XHRcdD8gbnVsbFxyXG5cdFx0XHQ6IG1lLmdldFBpeGVsRm9yRGVjaW1hbChpbmRleCAqIHRpY2tXaWR0aCArIChvZmZzZXQgPyB0aWNrV2lkdGggLyAyIDogMCkpO1xyXG5cdH0sXHJcblxyXG5cdC8qKlxyXG5cdCAqIFV0aWxpdHkgZm9yIGdldHRpbmcgdGhlIHBpeGVsIGxvY2F0aW9uIG9mIGEgcGVyY2VudGFnZSBvZiBzY2FsZVxyXG5cdCAqIFRoZSBjb29yZGluYXRlICgwLCAwKSBpcyBhdCB0aGUgdXBwZXItbGVmdCBjb3JuZXIgb2YgdGhlIGNhbnZhc1xyXG5cdCAqL1xyXG5cdGdldFBpeGVsRm9yRGVjaW1hbDogZnVuY3Rpb24oZGVjaW1hbCkge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHJcblx0XHRpZiAobWUuX3JldmVyc2VQaXhlbHMpIHtcclxuXHRcdFx0ZGVjaW1hbCA9IDEgLSBkZWNpbWFsO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiBtZS5fc3RhcnRQaXhlbCArIGRlY2ltYWwgKiBtZS5fbGVuZ3RoO1xyXG5cdH0sXHJcblxyXG5cdGdldERlY2ltYWxGb3JQaXhlbDogZnVuY3Rpb24ocGl4ZWwpIHtcclxuXHRcdHZhciBkZWNpbWFsID0gKHBpeGVsIC0gdGhpcy5fc3RhcnRQaXhlbCkgLyB0aGlzLl9sZW5ndGg7XHJcblx0XHRyZXR1cm4gdGhpcy5fcmV2ZXJzZVBpeGVscyA/IDEgLSBkZWNpbWFsIDogZGVjaW1hbDtcclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBSZXR1cm5zIHRoZSBwaXhlbCBmb3IgdGhlIG1pbmltdW0gY2hhcnQgdmFsdWVcclxuXHQgKiBUaGUgY29vcmRpbmF0ZSAoMCwgMCkgaXMgYXQgdGhlIHVwcGVyLWxlZnQgY29ybmVyIG9mIHRoZSBjYW52YXNcclxuXHQgKi9cclxuXHRnZXRCYXNlUGl4ZWw6IGZ1bmN0aW9uKCkge1xyXG5cdFx0cmV0dXJuIHRoaXMuZ2V0UGl4ZWxGb3JWYWx1ZSh0aGlzLmdldEJhc2VWYWx1ZSgpKTtcclxuXHR9LFxyXG5cclxuXHRnZXRCYXNlVmFsdWU6IGZ1bmN0aW9uKCkge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHRcdHZhciBtaW4gPSBtZS5taW47XHJcblx0XHR2YXIgbWF4ID0gbWUubWF4O1xyXG5cclxuXHRcdHJldHVybiBtZS5iZWdpbkF0WmVybyA/IDAgOlxyXG5cdFx0XHRtaW4gPCAwICYmIG1heCA8IDAgPyBtYXggOlxyXG5cdFx0XHRtaW4gPiAwICYmIG1heCA+IDAgPyBtaW4gOlxyXG5cdFx0XHQwO1xyXG5cdH0sXHJcblxyXG5cdC8qKlxyXG5cdCAqIFJldHVybnMgYSBzdWJzZXQgb2YgdGlja3MgdG8gYmUgcGxvdHRlZCB0byBhdm9pZCBvdmVybGFwcGluZyBsYWJlbHMuXHJcblx0ICogQHByaXZhdGVcclxuXHQgKi9cclxuXHRfYXV0b1NraXA6IGZ1bmN0aW9uKHRpY2tzKSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0dmFyIHRpY2tPcHRzID0gbWUub3B0aW9ucy50aWNrcztcclxuXHRcdHZhciBheGlzTGVuZ3RoID0gbWUuX2xlbmd0aDtcclxuXHRcdHZhciB0aWNrc0xpbWl0ID0gdGlja09wdHMubWF4VGlja3NMaW1pdCB8fCBheGlzTGVuZ3RoIC8gbWUuX3RpY2tTaXplKCkgKyAxO1xyXG5cdFx0dmFyIG1ham9ySW5kaWNlcyA9IHRpY2tPcHRzLm1ham9yLmVuYWJsZWQgPyBnZXRNYWpvckluZGljZXModGlja3MpIDogW107XHJcblx0XHR2YXIgbnVtTWFqb3JJbmRpY2VzID0gbWFqb3JJbmRpY2VzLmxlbmd0aDtcclxuXHRcdHZhciBmaXJzdCA9IG1ham9ySW5kaWNlc1swXTtcclxuXHRcdHZhciBsYXN0ID0gbWFqb3JJbmRpY2VzW251bU1ham9ySW5kaWNlcyAtIDFdO1xyXG5cdFx0dmFyIGksIGlsZW4sIHNwYWNpbmcsIGF2Z01ham9yU3BhY2luZztcclxuXHJcblx0XHQvLyBJZiB0aGVyZSBhcmUgdG9vIG1hbnkgbWFqb3IgdGlja3MgdG8gZGlzcGxheSB0aGVtIGFsbFxyXG5cdFx0aWYgKG51bU1ham9ySW5kaWNlcyA+IHRpY2tzTGltaXQpIHtcclxuXHRcdFx0c2tpcE1ham9ycyh0aWNrcywgbWFqb3JJbmRpY2VzLCBudW1NYWpvckluZGljZXMgLyB0aWNrc0xpbWl0KTtcclxuXHRcdFx0cmV0dXJuIG5vblNraXBwZWQodGlja3MpO1xyXG5cdFx0fVxyXG5cclxuXHRcdHNwYWNpbmcgPSBjYWxjdWxhdGVTcGFjaW5nKG1ham9ySW5kaWNlcywgdGlja3MsIGF4aXNMZW5ndGgsIHRpY2tzTGltaXQpO1xyXG5cclxuXHRcdGlmIChudW1NYWpvckluZGljZXMgPiAwKSB7XHJcblx0XHRcdGZvciAoaSA9IDAsIGlsZW4gPSBudW1NYWpvckluZGljZXMgLSAxOyBpIDwgaWxlbjsgaSsrKSB7XHJcblx0XHRcdFx0c2tpcCh0aWNrcywgc3BhY2luZywgbWFqb3JJbmRpY2VzW2ldLCBtYWpvckluZGljZXNbaSArIDFdKTtcclxuXHRcdFx0fVxyXG5cdFx0XHRhdmdNYWpvclNwYWNpbmcgPSBudW1NYWpvckluZGljZXMgPiAxID8gKGxhc3QgLSBmaXJzdCkgLyAobnVtTWFqb3JJbmRpY2VzIC0gMSkgOiBudWxsO1xyXG5cdFx0XHRza2lwKHRpY2tzLCBzcGFjaW5nLCBoZWxwZXJzJDEuaXNOdWxsT3JVbmRlZihhdmdNYWpvclNwYWNpbmcpID8gMCA6IGZpcnN0IC0gYXZnTWFqb3JTcGFjaW5nLCBmaXJzdCk7XHJcblx0XHRcdHNraXAodGlja3MsIHNwYWNpbmcsIGxhc3QsIGhlbHBlcnMkMS5pc051bGxPclVuZGVmKGF2Z01ham9yU3BhY2luZykgPyB0aWNrcy5sZW5ndGggOiBsYXN0ICsgYXZnTWFqb3JTcGFjaW5nKTtcclxuXHRcdFx0cmV0dXJuIG5vblNraXBwZWQodGlja3MpO1xyXG5cdFx0fVxyXG5cdFx0c2tpcCh0aWNrcywgc3BhY2luZyk7XHJcblx0XHRyZXR1cm4gbm9uU2tpcHBlZCh0aWNrcyk7XHJcblx0fSxcclxuXHJcblx0LyoqXHJcblx0ICogQHByaXZhdGVcclxuXHQgKi9cclxuXHRfdGlja1NpemU6IGZ1bmN0aW9uKCkge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHRcdHZhciBvcHRpb25UaWNrcyA9IG1lLm9wdGlvbnMudGlja3M7XHJcblxyXG5cdFx0Ly8gQ2FsY3VsYXRlIHNwYWNlIG5lZWRlZCBieSBsYWJlbCBpbiBheGlzIGRpcmVjdGlvbi5cclxuXHRcdHZhciByb3QgPSBoZWxwZXJzJDEudG9SYWRpYW5zKG1lLmxhYmVsUm90YXRpb24pO1xyXG5cdFx0dmFyIGNvcyA9IE1hdGguYWJzKE1hdGguY29zKHJvdCkpO1xyXG5cdFx0dmFyIHNpbiA9IE1hdGguYWJzKE1hdGguc2luKHJvdCkpO1xyXG5cclxuXHRcdHZhciBsYWJlbFNpemVzID0gbWUuX2dldExhYmVsU2l6ZXMoKTtcclxuXHRcdHZhciBwYWRkaW5nID0gb3B0aW9uVGlja3MuYXV0b1NraXBQYWRkaW5nIHx8IDA7XHJcblx0XHR2YXIgdyA9IGxhYmVsU2l6ZXMgPyBsYWJlbFNpemVzLndpZGVzdC53aWR0aCArIHBhZGRpbmcgOiAwO1xyXG5cdFx0dmFyIGggPSBsYWJlbFNpemVzID8gbGFiZWxTaXplcy5oaWdoZXN0LmhlaWdodCArIHBhZGRpbmcgOiAwO1xyXG5cclxuXHRcdC8vIENhbGN1bGF0ZSBzcGFjZSBuZWVkZWQgZm9yIDEgdGljayBpbiBheGlzIGRpcmVjdGlvbi5cclxuXHRcdHJldHVybiBtZS5pc0hvcml6b250YWwoKVxyXG5cdFx0XHQ/IGggKiBjb3MgPiB3ICogc2luID8gdyAvIGNvcyA6IGggLyBzaW5cclxuXHRcdFx0OiBoICogc2luIDwgdyAqIGNvcyA/IGggLyBjb3MgOiB3IC8gc2luO1xyXG5cdH0sXHJcblxyXG5cdC8qKlxyXG5cdCAqIEBwcml2YXRlXHJcblx0ICovXHJcblx0X2lzVmlzaWJsZTogZnVuY3Rpb24oKSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0dmFyIGNoYXJ0ID0gbWUuY2hhcnQ7XHJcblx0XHR2YXIgZGlzcGxheSA9IG1lLm9wdGlvbnMuZGlzcGxheTtcclxuXHRcdHZhciBpLCBpbGVuLCBtZXRhO1xyXG5cclxuXHRcdGlmIChkaXNwbGF5ICE9PSAnYXV0bycpIHtcclxuXHRcdFx0cmV0dXJuICEhZGlzcGxheTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBXaGVuICdhdXRvJywgdGhlIHNjYWxlIGlzIHZpc2libGUgaWYgYXQgbGVhc3Qgb25lIGFzc29jaWF0ZWQgZGF0YXNldCBpcyB2aXNpYmxlLlxyXG5cdFx0Zm9yIChpID0gMCwgaWxlbiA9IGNoYXJ0LmRhdGEuZGF0YXNldHMubGVuZ3RoOyBpIDwgaWxlbjsgKytpKSB7XHJcblx0XHRcdGlmIChjaGFydC5pc0RhdGFzZXRWaXNpYmxlKGkpKSB7XHJcblx0XHRcdFx0bWV0YSA9IGNoYXJ0LmdldERhdGFzZXRNZXRhKGkpO1xyXG5cdFx0XHRcdGlmIChtZXRhLnhBeGlzSUQgPT09IG1lLmlkIHx8IG1ldGEueUF4aXNJRCA9PT0gbWUuaWQpIHtcclxuXHRcdFx0XHRcdHJldHVybiB0cnVlO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiBmYWxzZTtcclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBAcHJpdmF0ZVxyXG5cdCAqL1xyXG5cdF9jb21wdXRlR3JpZExpbmVJdGVtczogZnVuY3Rpb24oY2hhcnRBcmVhKSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0dmFyIGNoYXJ0ID0gbWUuY2hhcnQ7XHJcblx0XHR2YXIgb3B0aW9ucyA9IG1lLm9wdGlvbnM7XHJcblx0XHR2YXIgZ3JpZExpbmVzID0gb3B0aW9ucy5ncmlkTGluZXM7XHJcblx0XHR2YXIgcG9zaXRpb24gPSBvcHRpb25zLnBvc2l0aW9uO1xyXG5cdFx0dmFyIG9mZnNldEdyaWRMaW5lcyA9IGdyaWRMaW5lcy5vZmZzZXRHcmlkTGluZXM7XHJcblx0XHR2YXIgaXNIb3Jpem9udGFsID0gbWUuaXNIb3Jpem9udGFsKCk7XHJcblx0XHR2YXIgdGlja3MgPSBtZS5fdGlja3NUb0RyYXc7XHJcblx0XHR2YXIgdGlja3NMZW5ndGggPSB0aWNrcy5sZW5ndGggKyAob2Zmc2V0R3JpZExpbmVzID8gMSA6IDApO1xyXG5cclxuXHRcdHZhciB0bCA9IGdldFRpY2tNYXJrTGVuZ3RoKGdyaWRMaW5lcyk7XHJcblx0XHR2YXIgaXRlbXMgPSBbXTtcclxuXHRcdHZhciBheGlzV2lkdGggPSBncmlkTGluZXMuZHJhd0JvcmRlciA/IHZhbHVlQXRJbmRleE9yRGVmYXVsdChncmlkTGluZXMubGluZVdpZHRoLCAwLCAwKSA6IDA7XHJcblx0XHR2YXIgYXhpc0hhbGZXaWR0aCA9IGF4aXNXaWR0aCAvIDI7XHJcblx0XHR2YXIgYWxpZ25QaXhlbCA9IGhlbHBlcnMkMS5fYWxpZ25QaXhlbDtcclxuXHRcdHZhciBhbGlnbkJvcmRlclZhbHVlID0gZnVuY3Rpb24ocGl4ZWwpIHtcclxuXHRcdFx0cmV0dXJuIGFsaWduUGl4ZWwoY2hhcnQsIHBpeGVsLCBheGlzV2lkdGgpO1xyXG5cdFx0fTtcclxuXHRcdHZhciBib3JkZXJWYWx1ZSwgaSwgdGljaywgbGluZVZhbHVlLCBhbGlnbmVkTGluZVZhbHVlO1xyXG5cdFx0dmFyIHR4MSwgdHkxLCB0eDIsIHR5MiwgeDEsIHkxLCB4MiwgeTIsIGxpbmVXaWR0aCwgbGluZUNvbG9yLCBib3JkZXJEYXNoLCBib3JkZXJEYXNoT2Zmc2V0O1xyXG5cclxuXHRcdGlmIChwb3NpdGlvbiA9PT0gJ3RvcCcpIHtcclxuXHRcdFx0Ym9yZGVyVmFsdWUgPSBhbGlnbkJvcmRlclZhbHVlKG1lLmJvdHRvbSk7XHJcblx0XHRcdHR5MSA9IG1lLmJvdHRvbSAtIHRsO1xyXG5cdFx0XHR0eTIgPSBib3JkZXJWYWx1ZSAtIGF4aXNIYWxmV2lkdGg7XHJcblx0XHRcdHkxID0gYWxpZ25Cb3JkZXJWYWx1ZShjaGFydEFyZWEudG9wKSArIGF4aXNIYWxmV2lkdGg7XHJcblx0XHRcdHkyID0gY2hhcnRBcmVhLmJvdHRvbTtcclxuXHRcdH0gZWxzZSBpZiAocG9zaXRpb24gPT09ICdib3R0b20nKSB7XHJcblx0XHRcdGJvcmRlclZhbHVlID0gYWxpZ25Cb3JkZXJWYWx1ZShtZS50b3ApO1xyXG5cdFx0XHR5MSA9IGNoYXJ0QXJlYS50b3A7XHJcblx0XHRcdHkyID0gYWxpZ25Cb3JkZXJWYWx1ZShjaGFydEFyZWEuYm90dG9tKSAtIGF4aXNIYWxmV2lkdGg7XHJcblx0XHRcdHR5MSA9IGJvcmRlclZhbHVlICsgYXhpc0hhbGZXaWR0aDtcclxuXHRcdFx0dHkyID0gbWUudG9wICsgdGw7XHJcblx0XHR9IGVsc2UgaWYgKHBvc2l0aW9uID09PSAnbGVmdCcpIHtcclxuXHRcdFx0Ym9yZGVyVmFsdWUgPSBhbGlnbkJvcmRlclZhbHVlKG1lLnJpZ2h0KTtcclxuXHRcdFx0dHgxID0gbWUucmlnaHQgLSB0bDtcclxuXHRcdFx0dHgyID0gYm9yZGVyVmFsdWUgLSBheGlzSGFsZldpZHRoO1xyXG5cdFx0XHR4MSA9IGFsaWduQm9yZGVyVmFsdWUoY2hhcnRBcmVhLmxlZnQpICsgYXhpc0hhbGZXaWR0aDtcclxuXHRcdFx0eDIgPSBjaGFydEFyZWEucmlnaHQ7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRib3JkZXJWYWx1ZSA9IGFsaWduQm9yZGVyVmFsdWUobWUubGVmdCk7XHJcblx0XHRcdHgxID0gY2hhcnRBcmVhLmxlZnQ7XHJcblx0XHRcdHgyID0gYWxpZ25Cb3JkZXJWYWx1ZShjaGFydEFyZWEucmlnaHQpIC0gYXhpc0hhbGZXaWR0aDtcclxuXHRcdFx0dHgxID0gYm9yZGVyVmFsdWUgKyBheGlzSGFsZldpZHRoO1xyXG5cdFx0XHR0eDIgPSBtZS5sZWZ0ICsgdGw7XHJcblx0XHR9XHJcblxyXG5cdFx0Zm9yIChpID0gMDsgaSA8IHRpY2tzTGVuZ3RoOyArK2kpIHtcclxuXHRcdFx0dGljayA9IHRpY2tzW2ldIHx8IHt9O1xyXG5cclxuXHRcdFx0Ly8gYXV0b3NraXBwZXIgc2tpcHBlZCB0aGlzIHRpY2sgKCM0NjM1KVxyXG5cdFx0XHRpZiAoaXNOdWxsT3JVbmRlZih0aWNrLmxhYmVsKSAmJiBpIDwgdGlja3MubGVuZ3RoKSB7XHJcblx0XHRcdFx0Y29udGludWU7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdGlmIChpID09PSBtZS56ZXJvTGluZUluZGV4ICYmIG9wdGlvbnMub2Zmc2V0ID09PSBvZmZzZXRHcmlkTGluZXMpIHtcclxuXHRcdFx0XHQvLyBEcmF3IHRoZSBmaXJzdCBpbmRleCBzcGVjaWFsbHlcclxuXHRcdFx0XHRsaW5lV2lkdGggPSBncmlkTGluZXMuemVyb0xpbmVXaWR0aDtcclxuXHRcdFx0XHRsaW5lQ29sb3IgPSBncmlkTGluZXMuemVyb0xpbmVDb2xvcjtcclxuXHRcdFx0XHRib3JkZXJEYXNoID0gZ3JpZExpbmVzLnplcm9MaW5lQm9yZGVyRGFzaCB8fCBbXTtcclxuXHRcdFx0XHRib3JkZXJEYXNoT2Zmc2V0ID0gZ3JpZExpbmVzLnplcm9MaW5lQm9yZGVyRGFzaE9mZnNldCB8fCAwLjA7XHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0bGluZVdpZHRoID0gdmFsdWVBdEluZGV4T3JEZWZhdWx0KGdyaWRMaW5lcy5saW5lV2lkdGgsIGksIDEpO1xyXG5cdFx0XHRcdGxpbmVDb2xvciA9IHZhbHVlQXRJbmRleE9yRGVmYXVsdChncmlkTGluZXMuY29sb3IsIGksICdyZ2JhKDAsMCwwLDAuMSknKTtcclxuXHRcdFx0XHRib3JkZXJEYXNoID0gZ3JpZExpbmVzLmJvcmRlckRhc2ggfHwgW107XHJcblx0XHRcdFx0Ym9yZGVyRGFzaE9mZnNldCA9IGdyaWRMaW5lcy5ib3JkZXJEYXNoT2Zmc2V0IHx8IDAuMDtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0bGluZVZhbHVlID0gZ2V0UGl4ZWxGb3JHcmlkTGluZShtZSwgdGljay5faW5kZXggfHwgaSwgb2Zmc2V0R3JpZExpbmVzKTtcclxuXHJcblx0XHRcdC8vIFNraXAgaWYgdGhlIHBpeGVsIGlzIG91dCBvZiB0aGUgcmFuZ2VcclxuXHRcdFx0aWYgKGxpbmVWYWx1ZSA9PT0gdW5kZWZpbmVkKSB7XHJcblx0XHRcdFx0Y29udGludWU7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdGFsaWduZWRMaW5lVmFsdWUgPSBhbGlnblBpeGVsKGNoYXJ0LCBsaW5lVmFsdWUsIGxpbmVXaWR0aCk7XHJcblxyXG5cdFx0XHRpZiAoaXNIb3Jpem9udGFsKSB7XHJcblx0XHRcdFx0dHgxID0gdHgyID0geDEgPSB4MiA9IGFsaWduZWRMaW5lVmFsdWU7XHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0dHkxID0gdHkyID0geTEgPSB5MiA9IGFsaWduZWRMaW5lVmFsdWU7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdGl0ZW1zLnB1c2goe1xyXG5cdFx0XHRcdHR4MTogdHgxLFxyXG5cdFx0XHRcdHR5MTogdHkxLFxyXG5cdFx0XHRcdHR4MjogdHgyLFxyXG5cdFx0XHRcdHR5MjogdHkyLFxyXG5cdFx0XHRcdHgxOiB4MSxcclxuXHRcdFx0XHR5MTogeTEsXHJcblx0XHRcdFx0eDI6IHgyLFxyXG5cdFx0XHRcdHkyOiB5MixcclxuXHRcdFx0XHR3aWR0aDogbGluZVdpZHRoLFxyXG5cdFx0XHRcdGNvbG9yOiBsaW5lQ29sb3IsXHJcblx0XHRcdFx0Ym9yZGVyRGFzaDogYm9yZGVyRGFzaCxcclxuXHRcdFx0XHRib3JkZXJEYXNoT2Zmc2V0OiBib3JkZXJEYXNoT2Zmc2V0LFxyXG5cdFx0XHR9KTtcclxuXHRcdH1cclxuXHJcblx0XHRpdGVtcy50aWNrc0xlbmd0aCA9IHRpY2tzTGVuZ3RoO1xyXG5cdFx0aXRlbXMuYm9yZGVyVmFsdWUgPSBib3JkZXJWYWx1ZTtcclxuXHJcblx0XHRyZXR1cm4gaXRlbXM7XHJcblx0fSxcclxuXHJcblx0LyoqXHJcblx0ICogQHByaXZhdGVcclxuXHQgKi9cclxuXHRfY29tcHV0ZUxhYmVsSXRlbXM6IGZ1bmN0aW9uKCkge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHRcdHZhciBvcHRpb25zID0gbWUub3B0aW9ucztcclxuXHRcdHZhciBvcHRpb25UaWNrcyA9IG9wdGlvbnMudGlja3M7XHJcblx0XHR2YXIgcG9zaXRpb24gPSBvcHRpb25zLnBvc2l0aW9uO1xyXG5cdFx0dmFyIGlzTWlycm9yZWQgPSBvcHRpb25UaWNrcy5taXJyb3I7XHJcblx0XHR2YXIgaXNIb3Jpem9udGFsID0gbWUuaXNIb3Jpem9udGFsKCk7XHJcblx0XHR2YXIgdGlja3MgPSBtZS5fdGlja3NUb0RyYXc7XHJcblx0XHR2YXIgZm9udHMgPSBwYXJzZVRpY2tGb250T3B0aW9ucyhvcHRpb25UaWNrcyk7XHJcblx0XHR2YXIgdGlja1BhZGRpbmcgPSBvcHRpb25UaWNrcy5wYWRkaW5nO1xyXG5cdFx0dmFyIHRsID0gZ2V0VGlja01hcmtMZW5ndGgob3B0aW9ucy5ncmlkTGluZXMpO1xyXG5cdFx0dmFyIHJvdGF0aW9uID0gLWhlbHBlcnMkMS50b1JhZGlhbnMobWUubGFiZWxSb3RhdGlvbik7XHJcblx0XHR2YXIgaXRlbXMgPSBbXTtcclxuXHRcdHZhciBpLCBpbGVuLCB0aWNrLCBsYWJlbCwgeCwgeSwgdGV4dEFsaWduLCBwaXhlbCwgZm9udCwgbGluZUhlaWdodCwgbGluZUNvdW50LCB0ZXh0T2Zmc2V0O1xyXG5cclxuXHRcdGlmIChwb3NpdGlvbiA9PT0gJ3RvcCcpIHtcclxuXHRcdFx0eSA9IG1lLmJvdHRvbSAtIHRsIC0gdGlja1BhZGRpbmc7XHJcblx0XHRcdHRleHRBbGlnbiA9ICFyb3RhdGlvbiA/ICdjZW50ZXInIDogJ2xlZnQnO1xyXG5cdFx0fSBlbHNlIGlmIChwb3NpdGlvbiA9PT0gJ2JvdHRvbScpIHtcclxuXHRcdFx0eSA9IG1lLnRvcCArIHRsICsgdGlja1BhZGRpbmc7XHJcblx0XHRcdHRleHRBbGlnbiA9ICFyb3RhdGlvbiA/ICdjZW50ZXInIDogJ3JpZ2h0JztcclxuXHRcdH0gZWxzZSBpZiAocG9zaXRpb24gPT09ICdsZWZ0Jykge1xyXG5cdFx0XHR4ID0gbWUucmlnaHQgLSAoaXNNaXJyb3JlZCA/IDAgOiB0bCkgLSB0aWNrUGFkZGluZztcclxuXHRcdFx0dGV4dEFsaWduID0gaXNNaXJyb3JlZCA/ICdsZWZ0JyA6ICdyaWdodCc7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHR4ID0gbWUubGVmdCArIChpc01pcnJvcmVkID8gMCA6IHRsKSArIHRpY2tQYWRkaW5nO1xyXG5cdFx0XHR0ZXh0QWxpZ24gPSBpc01pcnJvcmVkID8gJ3JpZ2h0JyA6ICdsZWZ0JztcclxuXHRcdH1cclxuXHJcblx0XHRmb3IgKGkgPSAwLCBpbGVuID0gdGlja3MubGVuZ3RoOyBpIDwgaWxlbjsgKytpKSB7XHJcblx0XHRcdHRpY2sgPSB0aWNrc1tpXTtcclxuXHRcdFx0bGFiZWwgPSB0aWNrLmxhYmVsO1xyXG5cclxuXHRcdFx0Ly8gYXV0b3NraXBwZXIgc2tpcHBlZCB0aGlzIHRpY2sgKCM0NjM1KVxyXG5cdFx0XHRpZiAoaXNOdWxsT3JVbmRlZihsYWJlbCkpIHtcclxuXHRcdFx0XHRjb250aW51ZTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0cGl4ZWwgPSBtZS5nZXRQaXhlbEZvclRpY2sodGljay5faW5kZXggfHwgaSkgKyBvcHRpb25UaWNrcy5sYWJlbE9mZnNldDtcclxuXHRcdFx0Zm9udCA9IHRpY2subWFqb3IgPyBmb250cy5tYWpvciA6IGZvbnRzLm1pbm9yO1xyXG5cdFx0XHRsaW5lSGVpZ2h0ID0gZm9udC5saW5lSGVpZ2h0O1xyXG5cdFx0XHRsaW5lQ291bnQgPSBpc0FycmF5KGxhYmVsKSA/IGxhYmVsLmxlbmd0aCA6IDE7XHJcblxyXG5cdFx0XHRpZiAoaXNIb3Jpem9udGFsKSB7XHJcblx0XHRcdFx0eCA9IHBpeGVsO1xyXG5cdFx0XHRcdHRleHRPZmZzZXQgPSBwb3NpdGlvbiA9PT0gJ3RvcCdcclxuXHRcdFx0XHRcdD8gKCghcm90YXRpb24gPyAwLjUgOiAxKSAtIGxpbmVDb3VudCkgKiBsaW5lSGVpZ2h0XHJcblx0XHRcdFx0XHQ6ICghcm90YXRpb24gPyAwLjUgOiAwKSAqIGxpbmVIZWlnaHQ7XHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0eSA9IHBpeGVsO1xyXG5cdFx0XHRcdHRleHRPZmZzZXQgPSAoMSAtIGxpbmVDb3VudCkgKiBsaW5lSGVpZ2h0IC8gMjtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0aXRlbXMucHVzaCh7XHJcblx0XHRcdFx0eDogeCxcclxuXHRcdFx0XHR5OiB5LFxyXG5cdFx0XHRcdHJvdGF0aW9uOiByb3RhdGlvbixcclxuXHRcdFx0XHRsYWJlbDogbGFiZWwsXHJcblx0XHRcdFx0Zm9udDogZm9udCxcclxuXHRcdFx0XHR0ZXh0T2Zmc2V0OiB0ZXh0T2Zmc2V0LFxyXG5cdFx0XHRcdHRleHRBbGlnbjogdGV4dEFsaWduXHJcblx0XHRcdH0pO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiBpdGVtcztcclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBAcHJpdmF0ZVxyXG5cdCAqL1xyXG5cdF9kcmF3R3JpZDogZnVuY3Rpb24oY2hhcnRBcmVhKSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0dmFyIGdyaWRMaW5lcyA9IG1lLm9wdGlvbnMuZ3JpZExpbmVzO1xyXG5cclxuXHRcdGlmICghZ3JpZExpbmVzLmRpc3BsYXkpIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdHZhciBjdHggPSBtZS5jdHg7XHJcblx0XHR2YXIgY2hhcnQgPSBtZS5jaGFydDtcclxuXHRcdHZhciBhbGlnblBpeGVsID0gaGVscGVycyQxLl9hbGlnblBpeGVsO1xyXG5cdFx0dmFyIGF4aXNXaWR0aCA9IGdyaWRMaW5lcy5kcmF3Qm9yZGVyID8gdmFsdWVBdEluZGV4T3JEZWZhdWx0KGdyaWRMaW5lcy5saW5lV2lkdGgsIDAsIDApIDogMDtcclxuXHRcdHZhciBpdGVtcyA9IG1lLl9ncmlkTGluZUl0ZW1zIHx8IChtZS5fZ3JpZExpbmVJdGVtcyA9IG1lLl9jb21wdXRlR3JpZExpbmVJdGVtcyhjaGFydEFyZWEpKTtcclxuXHRcdHZhciB3aWR0aCwgY29sb3IsIGksIGlsZW4sIGl0ZW07XHJcblxyXG5cdFx0Zm9yIChpID0gMCwgaWxlbiA9IGl0ZW1zLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xyXG5cdFx0XHRpdGVtID0gaXRlbXNbaV07XHJcblx0XHRcdHdpZHRoID0gaXRlbS53aWR0aDtcclxuXHRcdFx0Y29sb3IgPSBpdGVtLmNvbG9yO1xyXG5cclxuXHRcdFx0aWYgKHdpZHRoICYmIGNvbG9yKSB7XHJcblx0XHRcdFx0Y3R4LnNhdmUoKTtcclxuXHRcdFx0XHRjdHgubGluZVdpZHRoID0gd2lkdGg7XHJcblx0XHRcdFx0Y3R4LnN0cm9rZVN0eWxlID0gY29sb3I7XHJcblx0XHRcdFx0aWYgKGN0eC5zZXRMaW5lRGFzaCkge1xyXG5cdFx0XHRcdFx0Y3R4LnNldExpbmVEYXNoKGl0ZW0uYm9yZGVyRGFzaCk7XHJcblx0XHRcdFx0XHRjdHgubGluZURhc2hPZmZzZXQgPSBpdGVtLmJvcmRlckRhc2hPZmZzZXQ7XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRjdHguYmVnaW5QYXRoKCk7XHJcblxyXG5cdFx0XHRcdGlmIChncmlkTGluZXMuZHJhd1RpY2tzKSB7XHJcblx0XHRcdFx0XHRjdHgubW92ZVRvKGl0ZW0udHgxLCBpdGVtLnR5MSk7XHJcblx0XHRcdFx0XHRjdHgubGluZVRvKGl0ZW0udHgyLCBpdGVtLnR5Mik7XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRpZiAoZ3JpZExpbmVzLmRyYXdPbkNoYXJ0QXJlYSkge1xyXG5cdFx0XHRcdFx0Y3R4Lm1vdmVUbyhpdGVtLngxLCBpdGVtLnkxKTtcclxuXHRcdFx0XHRcdGN0eC5saW5lVG8oaXRlbS54MiwgaXRlbS55Mik7XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRjdHguc3Ryb2tlKCk7XHJcblx0XHRcdFx0Y3R4LnJlc3RvcmUoKTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdGlmIChheGlzV2lkdGgpIHtcclxuXHRcdFx0Ly8gRHJhdyB0aGUgbGluZSBhdCB0aGUgZWRnZSBvZiB0aGUgYXhpc1xyXG5cdFx0XHR2YXIgZmlyc3RMaW5lV2lkdGggPSBheGlzV2lkdGg7XHJcblx0XHRcdHZhciBsYXN0TGluZVdpZHRoID0gdmFsdWVBdEluZGV4T3JEZWZhdWx0KGdyaWRMaW5lcy5saW5lV2lkdGgsIGl0ZW1zLnRpY2tzTGVuZ3RoIC0gMSwgMSk7XHJcblx0XHRcdHZhciBib3JkZXJWYWx1ZSA9IGl0ZW1zLmJvcmRlclZhbHVlO1xyXG5cdFx0XHR2YXIgeDEsIHgyLCB5MSwgeTI7XHJcblxyXG5cdFx0XHRpZiAobWUuaXNIb3Jpem9udGFsKCkpIHtcclxuXHRcdFx0XHR4MSA9IGFsaWduUGl4ZWwoY2hhcnQsIG1lLmxlZnQsIGZpcnN0TGluZVdpZHRoKSAtIGZpcnN0TGluZVdpZHRoIC8gMjtcclxuXHRcdFx0XHR4MiA9IGFsaWduUGl4ZWwoY2hhcnQsIG1lLnJpZ2h0LCBsYXN0TGluZVdpZHRoKSArIGxhc3RMaW5lV2lkdGggLyAyO1xyXG5cdFx0XHRcdHkxID0geTIgPSBib3JkZXJWYWx1ZTtcclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHR5MSA9IGFsaWduUGl4ZWwoY2hhcnQsIG1lLnRvcCwgZmlyc3RMaW5lV2lkdGgpIC0gZmlyc3RMaW5lV2lkdGggLyAyO1xyXG5cdFx0XHRcdHkyID0gYWxpZ25QaXhlbChjaGFydCwgbWUuYm90dG9tLCBsYXN0TGluZVdpZHRoKSArIGxhc3RMaW5lV2lkdGggLyAyO1xyXG5cdFx0XHRcdHgxID0geDIgPSBib3JkZXJWYWx1ZTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Y3R4LmxpbmVXaWR0aCA9IGF4aXNXaWR0aDtcclxuXHRcdFx0Y3R4LnN0cm9rZVN0eWxlID0gdmFsdWVBdEluZGV4T3JEZWZhdWx0KGdyaWRMaW5lcy5jb2xvciwgMCk7XHJcblx0XHRcdGN0eC5iZWdpblBhdGgoKTtcclxuXHRcdFx0Y3R4Lm1vdmVUbyh4MSwgeTEpO1xyXG5cdFx0XHRjdHgubGluZVRvKHgyLCB5Mik7XHJcblx0XHRcdGN0eC5zdHJva2UoKTtcclxuXHRcdH1cclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBAcHJpdmF0ZVxyXG5cdCAqL1xyXG5cdF9kcmF3TGFiZWxzOiBmdW5jdGlvbigpIHtcclxuXHRcdHZhciBtZSA9IHRoaXM7XHJcblx0XHR2YXIgb3B0aW9uVGlja3MgPSBtZS5vcHRpb25zLnRpY2tzO1xyXG5cclxuXHRcdGlmICghb3B0aW9uVGlja3MuZGlzcGxheSkge1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblxyXG5cdFx0dmFyIGN0eCA9IG1lLmN0eDtcclxuXHRcdHZhciBpdGVtcyA9IG1lLl9sYWJlbEl0ZW1zIHx8IChtZS5fbGFiZWxJdGVtcyA9IG1lLl9jb21wdXRlTGFiZWxJdGVtcygpKTtcclxuXHRcdHZhciBpLCBqLCBpbGVuLCBqbGVuLCBpdGVtLCB0aWNrRm9udCwgbGFiZWwsIHk7XHJcblxyXG5cdFx0Zm9yIChpID0gMCwgaWxlbiA9IGl0ZW1zLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xyXG5cdFx0XHRpdGVtID0gaXRlbXNbaV07XHJcblx0XHRcdHRpY2tGb250ID0gaXRlbS5mb250O1xyXG5cclxuXHRcdFx0Ly8gTWFrZSBzdXJlIHdlIGRyYXcgdGV4dCBpbiB0aGUgY29ycmVjdCBjb2xvciBhbmQgZm9udFxyXG5cdFx0XHRjdHguc2F2ZSgpO1xyXG5cdFx0XHRjdHgudHJhbnNsYXRlKGl0ZW0ueCwgaXRlbS55KTtcclxuXHRcdFx0Y3R4LnJvdGF0ZShpdGVtLnJvdGF0aW9uKTtcclxuXHRcdFx0Y3R4LmZvbnQgPSB0aWNrRm9udC5zdHJpbmc7XHJcblx0XHRcdGN0eC5maWxsU3R5bGUgPSB0aWNrRm9udC5jb2xvcjtcclxuXHRcdFx0Y3R4LnRleHRCYXNlbGluZSA9ICdtaWRkbGUnO1xyXG5cdFx0XHRjdHgudGV4dEFsaWduID0gaXRlbS50ZXh0QWxpZ247XHJcblxyXG5cdFx0XHRsYWJlbCA9IGl0ZW0ubGFiZWw7XHJcblx0XHRcdHkgPSBpdGVtLnRleHRPZmZzZXQ7XHJcblx0XHRcdGlmIChpc0FycmF5KGxhYmVsKSkge1xyXG5cdFx0XHRcdGZvciAoaiA9IDAsIGpsZW4gPSBsYWJlbC5sZW5ndGg7IGogPCBqbGVuOyArK2opIHtcclxuXHRcdFx0XHRcdC8vIFdlIGp1c3QgbWFrZSBzdXJlIHRoZSBtdWx0aWxpbmUgZWxlbWVudCBpcyBhIHN0cmluZyBoZXJlLi5cclxuXHRcdFx0XHRcdGN0eC5maWxsVGV4dCgnJyArIGxhYmVsW2pdLCAwLCB5KTtcclxuXHRcdFx0XHRcdHkgKz0gdGlja0ZvbnQubGluZUhlaWdodDtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0Y3R4LmZpbGxUZXh0KGxhYmVsLCAwLCB5KTtcclxuXHRcdFx0fVxyXG5cdFx0XHRjdHgucmVzdG9yZSgpO1xyXG5cdFx0fVxyXG5cdH0sXHJcblxyXG5cdC8qKlxyXG5cdCAqIEBwcml2YXRlXHJcblx0ICovXHJcblx0X2RyYXdUaXRsZTogZnVuY3Rpb24oKSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0dmFyIGN0eCA9IG1lLmN0eDtcclxuXHRcdHZhciBvcHRpb25zID0gbWUub3B0aW9ucztcclxuXHRcdHZhciBzY2FsZUxhYmVsID0gb3B0aW9ucy5zY2FsZUxhYmVsO1xyXG5cclxuXHRcdGlmICghc2NhbGVMYWJlbC5kaXNwbGF5KSB7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHJcblx0XHR2YXIgc2NhbGVMYWJlbEZvbnRDb2xvciA9IHZhbHVlT3JEZWZhdWx0JGEoc2NhbGVMYWJlbC5mb250Q29sb3IsIGNvcmVfZGVmYXVsdHMuZ2xvYmFsLmRlZmF1bHRGb250Q29sb3IpO1xyXG5cdFx0dmFyIHNjYWxlTGFiZWxGb250ID0gaGVscGVycyQxLm9wdGlvbnMuX3BhcnNlRm9udChzY2FsZUxhYmVsKTtcclxuXHRcdHZhciBzY2FsZUxhYmVsUGFkZGluZyA9IGhlbHBlcnMkMS5vcHRpb25zLnRvUGFkZGluZyhzY2FsZUxhYmVsLnBhZGRpbmcpO1xyXG5cdFx0dmFyIGhhbGZMaW5lSGVpZ2h0ID0gc2NhbGVMYWJlbEZvbnQubGluZUhlaWdodCAvIDI7XHJcblx0XHR2YXIgcG9zaXRpb24gPSBvcHRpb25zLnBvc2l0aW9uO1xyXG5cdFx0dmFyIHJvdGF0aW9uID0gMDtcclxuXHRcdHZhciBzY2FsZUxhYmVsWCwgc2NhbGVMYWJlbFk7XHJcblxyXG5cdFx0aWYgKG1lLmlzSG9yaXpvbnRhbCgpKSB7XHJcblx0XHRcdHNjYWxlTGFiZWxYID0gbWUubGVmdCArIG1lLndpZHRoIC8gMjsgLy8gbWlkcG9pbnQgb2YgdGhlIHdpZHRoXHJcblx0XHRcdHNjYWxlTGFiZWxZID0gcG9zaXRpb24gPT09ICdib3R0b20nXHJcblx0XHRcdFx0PyBtZS5ib3R0b20gLSBoYWxmTGluZUhlaWdodCAtIHNjYWxlTGFiZWxQYWRkaW5nLmJvdHRvbVxyXG5cdFx0XHRcdDogbWUudG9wICsgaGFsZkxpbmVIZWlnaHQgKyBzY2FsZUxhYmVsUGFkZGluZy50b3A7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHR2YXIgaXNMZWZ0ID0gcG9zaXRpb24gPT09ICdsZWZ0JztcclxuXHRcdFx0c2NhbGVMYWJlbFggPSBpc0xlZnRcclxuXHRcdFx0XHQ/IG1lLmxlZnQgKyBoYWxmTGluZUhlaWdodCArIHNjYWxlTGFiZWxQYWRkaW5nLnRvcFxyXG5cdFx0XHRcdDogbWUucmlnaHQgLSBoYWxmTGluZUhlaWdodCAtIHNjYWxlTGFiZWxQYWRkaW5nLnRvcDtcclxuXHRcdFx0c2NhbGVMYWJlbFkgPSBtZS50b3AgKyBtZS5oZWlnaHQgLyAyO1xyXG5cdFx0XHRyb3RhdGlvbiA9IGlzTGVmdCA/IC0wLjUgKiBNYXRoLlBJIDogMC41ICogTWF0aC5QSTtcclxuXHRcdH1cclxuXHJcblx0XHRjdHguc2F2ZSgpO1xyXG5cdFx0Y3R4LnRyYW5zbGF0ZShzY2FsZUxhYmVsWCwgc2NhbGVMYWJlbFkpO1xyXG5cdFx0Y3R4LnJvdGF0ZShyb3RhdGlvbik7XHJcblx0XHRjdHgudGV4dEFsaWduID0gJ2NlbnRlcic7XHJcblx0XHRjdHgudGV4dEJhc2VsaW5lID0gJ21pZGRsZSc7XHJcblx0XHRjdHguZmlsbFN0eWxlID0gc2NhbGVMYWJlbEZvbnRDb2xvcjsgLy8gcmVuZGVyIGluIGNvcnJlY3QgY29sb3VyXHJcblx0XHRjdHguZm9udCA9IHNjYWxlTGFiZWxGb250LnN0cmluZztcclxuXHRcdGN0eC5maWxsVGV4dChzY2FsZUxhYmVsLmxhYmVsU3RyaW5nLCAwLCAwKTtcclxuXHRcdGN0eC5yZXN0b3JlKCk7XHJcblx0fSxcclxuXHJcblx0ZHJhdzogZnVuY3Rpb24oY2hhcnRBcmVhKSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cclxuXHRcdGlmICghbWUuX2lzVmlzaWJsZSgpKSB7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHJcblx0XHRtZS5fZHJhd0dyaWQoY2hhcnRBcmVhKTtcclxuXHRcdG1lLl9kcmF3VGl0bGUoKTtcclxuXHRcdG1lLl9kcmF3TGFiZWxzKCk7XHJcblx0fSxcclxuXHJcblx0LyoqXHJcblx0ICogQHByaXZhdGVcclxuXHQgKi9cclxuXHRfbGF5ZXJzOiBmdW5jdGlvbigpIHtcclxuXHRcdHZhciBtZSA9IHRoaXM7XHJcblx0XHR2YXIgb3B0cyA9IG1lLm9wdGlvbnM7XHJcblx0XHR2YXIgdHogPSBvcHRzLnRpY2tzICYmIG9wdHMudGlja3MueiB8fCAwO1xyXG5cdFx0dmFyIGd6ID0gb3B0cy5ncmlkTGluZXMgJiYgb3B0cy5ncmlkTGluZXMueiB8fCAwO1xyXG5cclxuXHRcdGlmICghbWUuX2lzVmlzaWJsZSgpIHx8IHR6ID09PSBneiB8fCBtZS5kcmF3ICE9PSBtZS5fZHJhdykge1xyXG5cdFx0XHQvLyBiYWNrd2FyZCBjb21wYXRpYmlsaXR5OiBkcmF3IGhhcyBiZWVuIG92ZXJyaWRkZW4gYnkgY3VzdG9tIHNjYWxlXHJcblx0XHRcdHJldHVybiBbe1xyXG5cdFx0XHRcdHo6IHR6LFxyXG5cdFx0XHRcdGRyYXc6IGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdFx0bWUuZHJhdy5hcHBseShtZSwgYXJndW1lbnRzKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1dO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiBbe1xyXG5cdFx0XHR6OiBneixcclxuXHRcdFx0ZHJhdzogZnVuY3Rpb24oKSB7XHJcblx0XHRcdFx0bWUuX2RyYXdHcmlkLmFwcGx5KG1lLCBhcmd1bWVudHMpO1xyXG5cdFx0XHRcdG1lLl9kcmF3VGl0bGUuYXBwbHkobWUsIGFyZ3VtZW50cyk7XHJcblx0XHRcdH1cclxuXHRcdH0sIHtcclxuXHRcdFx0ejogdHosXHJcblx0XHRcdGRyYXc6IGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdG1lLl9kcmF3TGFiZWxzLmFwcGx5KG1lLCBhcmd1bWVudHMpO1xyXG5cdFx0XHR9XHJcblx0XHR9XTtcclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBAcHJpdmF0ZVxyXG5cdCAqL1xyXG5cdF9nZXRNYXRjaGluZ1Zpc2libGVNZXRhczogZnVuY3Rpb24odHlwZSkge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHRcdHZhciBpc0hvcml6b250YWwgPSBtZS5pc0hvcml6b250YWwoKTtcclxuXHRcdHJldHVybiBtZS5jaGFydC5fZ2V0U29ydGVkVmlzaWJsZURhdGFzZXRNZXRhcygpXHJcblx0XHRcdC5maWx0ZXIoZnVuY3Rpb24obWV0YSkge1xyXG5cdFx0XHRcdHJldHVybiAoIXR5cGUgfHwgbWV0YS50eXBlID09PSB0eXBlKVxyXG5cdFx0XHRcdFx0JiYgKGlzSG9yaXpvbnRhbCA/IG1ldGEueEF4aXNJRCA9PT0gbWUuaWQgOiBtZXRhLnlBeGlzSUQgPT09IG1lLmlkKTtcclxuXHRcdFx0fSk7XHJcblx0fVxyXG59KTtcclxuXHJcblNjYWxlLnByb3RvdHlwZS5fZHJhdyA9IFNjYWxlLnByb3RvdHlwZS5kcmF3O1xyXG5cclxudmFyIGNvcmVfc2NhbGUgPSBTY2FsZTtcblxudmFyIGlzTnVsbE9yVW5kZWYkMSA9IGhlbHBlcnMkMS5pc051bGxPclVuZGVmO1xyXG5cclxudmFyIGRlZmF1bHRDb25maWcgPSB7XHJcblx0cG9zaXRpb246ICdib3R0b20nXHJcbn07XHJcblxyXG52YXIgc2NhbGVfY2F0ZWdvcnkgPSBjb3JlX3NjYWxlLmV4dGVuZCh7XHJcblx0ZGV0ZXJtaW5lRGF0YUxpbWl0czogZnVuY3Rpb24oKSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0dmFyIGxhYmVscyA9IG1lLl9nZXRMYWJlbHMoKTtcclxuXHRcdHZhciB0aWNrc09wdHMgPSBtZS5vcHRpb25zLnRpY2tzO1xyXG5cdFx0dmFyIG1pbiA9IHRpY2tzT3B0cy5taW47XHJcblx0XHR2YXIgbWF4ID0gdGlja3NPcHRzLm1heDtcclxuXHRcdHZhciBtaW5JbmRleCA9IDA7XHJcblx0XHR2YXIgbWF4SW5kZXggPSBsYWJlbHMubGVuZ3RoIC0gMTtcclxuXHRcdHZhciBmaW5kSW5kZXg7XHJcblxyXG5cdFx0aWYgKG1pbiAhPT0gdW5kZWZpbmVkKSB7XHJcblx0XHRcdC8vIHVzZXIgc3BlY2lmaWVkIG1pbiB2YWx1ZVxyXG5cdFx0XHRmaW5kSW5kZXggPSBsYWJlbHMuaW5kZXhPZihtaW4pO1xyXG5cdFx0XHRpZiAoZmluZEluZGV4ID49IDApIHtcclxuXHRcdFx0XHRtaW5JbmRleCA9IGZpbmRJbmRleDtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdGlmIChtYXggIT09IHVuZGVmaW5lZCkge1xyXG5cdFx0XHQvLyB1c2VyIHNwZWNpZmllZCBtYXggdmFsdWVcclxuXHRcdFx0ZmluZEluZGV4ID0gbGFiZWxzLmluZGV4T2YobWF4KTtcclxuXHRcdFx0aWYgKGZpbmRJbmRleCA+PSAwKSB7XHJcblx0XHRcdFx0bWF4SW5kZXggPSBmaW5kSW5kZXg7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHRtZS5taW5JbmRleCA9IG1pbkluZGV4O1xyXG5cdFx0bWUubWF4SW5kZXggPSBtYXhJbmRleDtcclxuXHRcdG1lLm1pbiA9IGxhYmVsc1ttaW5JbmRleF07XHJcblx0XHRtZS5tYXggPSBsYWJlbHNbbWF4SW5kZXhdO1xyXG5cdH0sXHJcblxyXG5cdGJ1aWxkVGlja3M6IGZ1bmN0aW9uKCkge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHRcdHZhciBsYWJlbHMgPSBtZS5fZ2V0TGFiZWxzKCk7XHJcblx0XHR2YXIgbWluSW5kZXggPSBtZS5taW5JbmRleDtcclxuXHRcdHZhciBtYXhJbmRleCA9IG1lLm1heEluZGV4O1xyXG5cclxuXHRcdC8vIElmIHdlIGFyZSB2aWV3aW5nIHNvbWUgc3Vic2V0IG9mIGxhYmVscywgc2xpY2UgdGhlIG9yaWdpbmFsIGFycmF5XHJcblx0XHRtZS50aWNrcyA9IChtaW5JbmRleCA9PT0gMCAmJiBtYXhJbmRleCA9PT0gbGFiZWxzLmxlbmd0aCAtIDEpID8gbGFiZWxzIDogbGFiZWxzLnNsaWNlKG1pbkluZGV4LCBtYXhJbmRleCArIDEpO1xyXG5cdH0sXHJcblxyXG5cdGdldExhYmVsRm9ySW5kZXg6IGZ1bmN0aW9uKGluZGV4LCBkYXRhc2V0SW5kZXgpIHtcclxuXHRcdHZhciBtZSA9IHRoaXM7XHJcblx0XHR2YXIgY2hhcnQgPSBtZS5jaGFydDtcclxuXHJcblx0XHRpZiAoY2hhcnQuZ2V0RGF0YXNldE1ldGEoZGF0YXNldEluZGV4KS5jb250cm9sbGVyLl9nZXRWYWx1ZVNjYWxlSWQoKSA9PT0gbWUuaWQpIHtcclxuXHRcdFx0cmV0dXJuIG1lLmdldFJpZ2h0VmFsdWUoY2hhcnQuZGF0YS5kYXRhc2V0c1tkYXRhc2V0SW5kZXhdLmRhdGFbaW5kZXhdKTtcclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gbWUuX2dldExhYmVscygpW2luZGV4XTtcclxuXHR9LFxyXG5cclxuXHRfY29uZmlndXJlOiBmdW5jdGlvbigpIHtcclxuXHRcdHZhciBtZSA9IHRoaXM7XHJcblx0XHR2YXIgb2Zmc2V0ID0gbWUub3B0aW9ucy5vZmZzZXQ7XHJcblx0XHR2YXIgdGlja3MgPSBtZS50aWNrcztcclxuXHJcblx0XHRjb3JlX3NjYWxlLnByb3RvdHlwZS5fY29uZmlndXJlLmNhbGwobWUpO1xyXG5cclxuXHRcdGlmICghbWUuaXNIb3Jpem9udGFsKCkpIHtcclxuXHRcdFx0Ly8gRm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHksIHZlcnRpY2FsIGNhdGVnb3J5IHNjYWxlIHJldmVyc2UgaXMgaW52ZXJ0ZWQuXHJcblx0XHRcdG1lLl9yZXZlcnNlUGl4ZWxzID0gIW1lLl9yZXZlcnNlUGl4ZWxzO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmICghdGlja3MpIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdG1lLl9zdGFydFZhbHVlID0gbWUubWluSW5kZXggLSAob2Zmc2V0ID8gMC41IDogMCk7XHJcblx0XHRtZS5fdmFsdWVSYW5nZSA9IE1hdGgubWF4KHRpY2tzLmxlbmd0aCAtIChvZmZzZXQgPyAwIDogMSksIDEpO1xyXG5cdH0sXHJcblxyXG5cdC8vIFVzZWQgdG8gZ2V0IGRhdGEgdmFsdWUgbG9jYXRpb25zLiAgVmFsdWUgY2FuIGVpdGhlciBiZSBhbiBpbmRleCBvciBhIG51bWVyaWNhbCB2YWx1ZVxyXG5cdGdldFBpeGVsRm9yVmFsdWU6IGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgZGF0YXNldEluZGV4KSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0dmFyIHZhbHVlQ2F0ZWdvcnksIGxhYmVscywgaWR4O1xyXG5cclxuXHRcdGlmICghaXNOdWxsT3JVbmRlZiQxKGluZGV4KSAmJiAhaXNOdWxsT3JVbmRlZiQxKGRhdGFzZXRJbmRleCkpIHtcclxuXHRcdFx0dmFsdWUgPSBtZS5jaGFydC5kYXRhLmRhdGFzZXRzW2RhdGFzZXRJbmRleF0uZGF0YVtpbmRleF07XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gSWYgdmFsdWUgaXMgYSBkYXRhIG9iamVjdCwgdGhlbiBpbmRleCBpcyB0aGUgaW5kZXggaW4gdGhlIGRhdGEgYXJyYXksXHJcblx0XHQvLyBub3QgdGhlIGluZGV4IG9mIHRoZSBzY2FsZS4gV2UgbmVlZCB0byBjaGFuZ2UgdGhhdC5cclxuXHRcdGlmICghaXNOdWxsT3JVbmRlZiQxKHZhbHVlKSkge1xyXG5cdFx0XHR2YWx1ZUNhdGVnb3J5ID0gbWUuaXNIb3Jpem9udGFsKCkgPyB2YWx1ZS54IDogdmFsdWUueTtcclxuXHRcdH1cclxuXHRcdGlmICh2YWx1ZUNhdGVnb3J5ICE9PSB1bmRlZmluZWQgfHwgKHZhbHVlICE9PSB1bmRlZmluZWQgJiYgaXNOYU4oaW5kZXgpKSkge1xyXG5cdFx0XHRsYWJlbHMgPSBtZS5fZ2V0TGFiZWxzKCk7XHJcblx0XHRcdHZhbHVlID0gaGVscGVycyQxLnZhbHVlT3JEZWZhdWx0KHZhbHVlQ2F0ZWdvcnksIHZhbHVlKTtcclxuXHRcdFx0aWR4ID0gbGFiZWxzLmluZGV4T2YodmFsdWUpO1xyXG5cdFx0XHRpbmRleCA9IGlkeCAhPT0gLTEgPyBpZHggOiBpbmRleDtcclxuXHRcdFx0aWYgKGlzTmFOKGluZGV4KSkge1xyXG5cdFx0XHRcdGluZGV4ID0gdmFsdWU7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHRcdHJldHVybiBtZS5nZXRQaXhlbEZvckRlY2ltYWwoKGluZGV4IC0gbWUuX3N0YXJ0VmFsdWUpIC8gbWUuX3ZhbHVlUmFuZ2UpO1xyXG5cdH0sXHJcblxyXG5cdGdldFBpeGVsRm9yVGljazogZnVuY3Rpb24oaW5kZXgpIHtcclxuXHRcdHZhciB0aWNrcyA9IHRoaXMudGlja3M7XHJcblx0XHRyZXR1cm4gaW5kZXggPCAwIHx8IGluZGV4ID4gdGlja3MubGVuZ3RoIC0gMVxyXG5cdFx0XHQ/IG51bGxcclxuXHRcdFx0OiB0aGlzLmdldFBpeGVsRm9yVmFsdWUodGlja3NbaW5kZXhdLCBpbmRleCArIHRoaXMubWluSW5kZXgpO1xyXG5cdH0sXHJcblxyXG5cdGdldFZhbHVlRm9yUGl4ZWw6IGZ1bmN0aW9uKHBpeGVsKSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0dmFyIHZhbHVlID0gTWF0aC5yb3VuZChtZS5fc3RhcnRWYWx1ZSArIG1lLmdldERlY2ltYWxGb3JQaXhlbChwaXhlbCkgKiBtZS5fdmFsdWVSYW5nZSk7XHJcblx0XHRyZXR1cm4gTWF0aC5taW4oTWF0aC5tYXgodmFsdWUsIDApLCBtZS50aWNrcy5sZW5ndGggLSAxKTtcclxuXHR9LFxyXG5cclxuXHRnZXRCYXNlUGl4ZWw6IGZ1bmN0aW9uKCkge1xyXG5cdFx0cmV0dXJuIHRoaXMuYm90dG9tO1xyXG5cdH1cclxufSk7XHJcblxyXG4vLyBJTlRFUk5BTDogc3RhdGljIGRlZmF1bHQgb3B0aW9ucywgcmVnaXN0ZXJlZCBpbiBzcmMvaW5kZXguanNcclxudmFyIF9kZWZhdWx0cyA9IGRlZmF1bHRDb25maWc7XG5zY2FsZV9jYXRlZ29yeS5fZGVmYXVsdHMgPSBfZGVmYXVsdHM7XG5cbnZhciBub29wID0gaGVscGVycyQxLm5vb3A7XHJcbnZhciBpc051bGxPclVuZGVmJDIgPSBoZWxwZXJzJDEuaXNOdWxsT3JVbmRlZjtcclxuXHJcbi8qKlxyXG4gKiBHZW5lcmF0ZSBhIHNldCBvZiBsaW5lYXIgdGlja3NcclxuICogQHBhcmFtIGdlbmVyYXRpb25PcHRpb25zIHRoZSBvcHRpb25zIHVzZWQgdG8gZ2VuZXJhdGUgdGhlIHRpY2tzXHJcbiAqIEBwYXJhbSBkYXRhUmFuZ2UgdGhlIHJhbmdlIG9mIHRoZSBkYXRhXHJcbiAqIEByZXR1cm5zIHtudW1iZXJbXX0gYXJyYXkgb2YgdGljayB2YWx1ZXNcclxuICovXHJcbmZ1bmN0aW9uIGdlbmVyYXRlVGlja3MoZ2VuZXJhdGlvbk9wdGlvbnMsIGRhdGFSYW5nZSkge1xyXG5cdHZhciB0aWNrcyA9IFtdO1xyXG5cdC8vIFRvIGdldCBhIFwibmljZVwiIHZhbHVlIGZvciB0aGUgdGljayBzcGFjaW5nLCB3ZSB3aWxsIHVzZSB0aGUgYXBwcm9wcmlhdGVseSBuYW1lZFxyXG5cdC8vIFwibmljZSBudW1iZXJcIiBhbGdvcml0aG0uIFNlZSBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy84NTA2ODgxL25pY2UtbGFiZWwtYWxnb3JpdGhtLWZvci1jaGFydHMtd2l0aC1taW5pbXVtLXRpY2tzXHJcblx0Ly8gZm9yIGRldGFpbHMuXHJcblxyXG5cdHZhciBNSU5fU1BBQ0lORyA9IDFlLTE0O1xyXG5cdHZhciBzdGVwU2l6ZSA9IGdlbmVyYXRpb25PcHRpb25zLnN0ZXBTaXplO1xyXG5cdHZhciB1bml0ID0gc3RlcFNpemUgfHwgMTtcclxuXHR2YXIgbWF4TnVtU3BhY2VzID0gZ2VuZXJhdGlvbk9wdGlvbnMubWF4VGlja3MgLSAxO1xyXG5cdHZhciBtaW4gPSBnZW5lcmF0aW9uT3B0aW9ucy5taW47XHJcblx0dmFyIG1heCA9IGdlbmVyYXRpb25PcHRpb25zLm1heDtcclxuXHR2YXIgcHJlY2lzaW9uID0gZ2VuZXJhdGlvbk9wdGlvbnMucHJlY2lzaW9uO1xyXG5cdHZhciBybWluID0gZGF0YVJhbmdlLm1pbjtcclxuXHR2YXIgcm1heCA9IGRhdGFSYW5nZS5tYXg7XHJcblx0dmFyIHNwYWNpbmcgPSBoZWxwZXJzJDEubmljZU51bSgocm1heCAtIHJtaW4pIC8gbWF4TnVtU3BhY2VzIC8gdW5pdCkgKiB1bml0O1xyXG5cdHZhciBmYWN0b3IsIG5pY2VNaW4sIG5pY2VNYXgsIG51bVNwYWNlcztcclxuXHJcblx0Ly8gQmV5b25kIE1JTl9TUEFDSU5HIGZsb2F0aW5nIHBvaW50IG51bWJlcnMgYmVpbmcgdG8gbG9zZSBwcmVjaXNpb25cclxuXHQvLyBzdWNoIHRoYXQgd2UgY2FuJ3QgZG8gdGhlIG1hdGggbmVjZXNzYXJ5IHRvIGdlbmVyYXRlIHRpY2tzXHJcblx0aWYgKHNwYWNpbmcgPCBNSU5fU1BBQ0lORyAmJiBpc051bGxPclVuZGVmJDIobWluKSAmJiBpc051bGxPclVuZGVmJDIobWF4KSkge1xyXG5cdFx0cmV0dXJuIFtybWluLCBybWF4XTtcclxuXHR9XHJcblxyXG5cdG51bVNwYWNlcyA9IE1hdGguY2VpbChybWF4IC8gc3BhY2luZykgLSBNYXRoLmZsb29yKHJtaW4gLyBzcGFjaW5nKTtcclxuXHRpZiAobnVtU3BhY2VzID4gbWF4TnVtU3BhY2VzKSB7XHJcblx0XHQvLyBJZiB0aGUgY2FsY3VsYXRlZCBudW0gb2Ygc3BhY2VzIGV4Y2VlZHMgbWF4TnVtU3BhY2VzLCByZWNhbGN1bGF0ZSBpdFxyXG5cdFx0c3BhY2luZyA9IGhlbHBlcnMkMS5uaWNlTnVtKG51bVNwYWNlcyAqIHNwYWNpbmcgLyBtYXhOdW1TcGFjZXMgLyB1bml0KSAqIHVuaXQ7XHJcblx0fVxyXG5cclxuXHRpZiAoc3RlcFNpemUgfHwgaXNOdWxsT3JVbmRlZiQyKHByZWNpc2lvbikpIHtcclxuXHRcdC8vIElmIGEgcHJlY2lzaW9uIGlzIG5vdCBzcGVjaWZpZWQsIGNhbGN1bGF0ZSBmYWN0b3IgYmFzZWQgb24gc3BhY2luZ1xyXG5cdFx0ZmFjdG9yID0gTWF0aC5wb3coMTAsIGhlbHBlcnMkMS5fZGVjaW1hbFBsYWNlcyhzcGFjaW5nKSk7XHJcblx0fSBlbHNlIHtcclxuXHRcdC8vIElmIHRoZSB1c2VyIHNwZWNpZmllZCBhIHByZWNpc2lvbiwgcm91bmQgdG8gdGhhdCBudW1iZXIgb2YgZGVjaW1hbCBwbGFjZXNcclxuXHRcdGZhY3RvciA9IE1hdGgucG93KDEwLCBwcmVjaXNpb24pO1xyXG5cdFx0c3BhY2luZyA9IE1hdGguY2VpbChzcGFjaW5nICogZmFjdG9yKSAvIGZhY3RvcjtcclxuXHR9XHJcblxyXG5cdG5pY2VNaW4gPSBNYXRoLmZsb29yKHJtaW4gLyBzcGFjaW5nKSAqIHNwYWNpbmc7XHJcblx0bmljZU1heCA9IE1hdGguY2VpbChybWF4IC8gc3BhY2luZykgKiBzcGFjaW5nO1xyXG5cclxuXHQvLyBJZiBtaW4sIG1heCBhbmQgc3RlcFNpemUgaXMgc2V0IGFuZCB0aGV5IG1ha2UgYW4gZXZlbmx5IHNwYWNlZCBzY2FsZSB1c2UgaXQuXHJcblx0aWYgKHN0ZXBTaXplKSB7XHJcblx0XHQvLyBJZiB2ZXJ5IGNsb3NlIHRvIG91ciB3aG9sZSBudW1iZXIsIHVzZSBpdC5cclxuXHRcdGlmICghaXNOdWxsT3JVbmRlZiQyKG1pbikgJiYgaGVscGVycyQxLmFsbW9zdFdob2xlKG1pbiAvIHNwYWNpbmcsIHNwYWNpbmcgLyAxMDAwKSkge1xyXG5cdFx0XHRuaWNlTWluID0gbWluO1xyXG5cdFx0fVxyXG5cdFx0aWYgKCFpc051bGxPclVuZGVmJDIobWF4KSAmJiBoZWxwZXJzJDEuYWxtb3N0V2hvbGUobWF4IC8gc3BhY2luZywgc3BhY2luZyAvIDEwMDApKSB7XHJcblx0XHRcdG5pY2VNYXggPSBtYXg7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRudW1TcGFjZXMgPSAobmljZU1heCAtIG5pY2VNaW4pIC8gc3BhY2luZztcclxuXHQvLyBJZiB2ZXJ5IGNsb3NlIHRvIG91ciByb3VuZGVkIHZhbHVlLCB1c2UgaXQuXHJcblx0aWYgKGhlbHBlcnMkMS5hbG1vc3RFcXVhbHMobnVtU3BhY2VzLCBNYXRoLnJvdW5kKG51bVNwYWNlcyksIHNwYWNpbmcgLyAxMDAwKSkge1xyXG5cdFx0bnVtU3BhY2VzID0gTWF0aC5yb3VuZChudW1TcGFjZXMpO1xyXG5cdH0gZWxzZSB7XHJcblx0XHRudW1TcGFjZXMgPSBNYXRoLmNlaWwobnVtU3BhY2VzKTtcclxuXHR9XHJcblxyXG5cdG5pY2VNaW4gPSBNYXRoLnJvdW5kKG5pY2VNaW4gKiBmYWN0b3IpIC8gZmFjdG9yO1xyXG5cdG5pY2VNYXggPSBNYXRoLnJvdW5kKG5pY2VNYXggKiBmYWN0b3IpIC8gZmFjdG9yO1xyXG5cdHRpY2tzLnB1c2goaXNOdWxsT3JVbmRlZiQyKG1pbikgPyBuaWNlTWluIDogbWluKTtcclxuXHRmb3IgKHZhciBqID0gMTsgaiA8IG51bVNwYWNlczsgKytqKSB7XHJcblx0XHR0aWNrcy5wdXNoKE1hdGgucm91bmQoKG5pY2VNaW4gKyBqICogc3BhY2luZykgKiBmYWN0b3IpIC8gZmFjdG9yKTtcclxuXHR9XHJcblx0dGlja3MucHVzaChpc051bGxPclVuZGVmJDIobWF4KSA/IG5pY2VNYXggOiBtYXgpO1xyXG5cclxuXHRyZXR1cm4gdGlja3M7XHJcbn1cclxuXHJcbnZhciBzY2FsZV9saW5lYXJiYXNlID0gY29yZV9zY2FsZS5leHRlbmQoe1xyXG5cdGdldFJpZ2h0VmFsdWU6IGZ1bmN0aW9uKHZhbHVlKSB7XHJcblx0XHRpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xyXG5cdFx0XHRyZXR1cm4gK3ZhbHVlO1xyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIGNvcmVfc2NhbGUucHJvdG90eXBlLmdldFJpZ2h0VmFsdWUuY2FsbCh0aGlzLCB2YWx1ZSk7XHJcblx0fSxcclxuXHJcblx0aGFuZGxlVGlja1JhbmdlT3B0aW9uczogZnVuY3Rpb24oKSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0dmFyIG9wdHMgPSBtZS5vcHRpb25zO1xyXG5cdFx0dmFyIHRpY2tPcHRzID0gb3B0cy50aWNrcztcclxuXHJcblx0XHQvLyBJZiB3ZSBhcmUgZm9yY2luZyBpdCB0byBiZWdpbiBhdCAwLCBidXQgMCB3aWxsIGFscmVhZHkgYmUgcmVuZGVyZWQgb24gdGhlIGNoYXJ0LFxyXG5cdFx0Ly8gZG8gbm90aGluZyBzaW5jZSB0aGF0IHdvdWxkIG1ha2UgdGhlIGNoYXJ0IHdlaXJkLiBJZiB0aGUgdXNlciByZWFsbHkgd2FudHMgYSB3ZWlyZCBjaGFydFxyXG5cdFx0Ly8gYXhpcywgdGhleSBjYW4gbWFudWFsbHkgb3ZlcnJpZGUgaXRcclxuXHRcdGlmICh0aWNrT3B0cy5iZWdpbkF0WmVybykge1xyXG5cdFx0XHR2YXIgbWluU2lnbiA9IGhlbHBlcnMkMS5zaWduKG1lLm1pbik7XHJcblx0XHRcdHZhciBtYXhTaWduID0gaGVscGVycyQxLnNpZ24obWUubWF4KTtcclxuXHJcblx0XHRcdGlmIChtaW5TaWduIDwgMCAmJiBtYXhTaWduIDwgMCkge1xyXG5cdFx0XHRcdC8vIG1vdmUgdGhlIHRvcCB1cCB0byAwXHJcblx0XHRcdFx0bWUubWF4ID0gMDtcclxuXHRcdFx0fSBlbHNlIGlmIChtaW5TaWduID4gMCAmJiBtYXhTaWduID4gMCkge1xyXG5cdFx0XHRcdC8vIG1vdmUgdGhlIGJvdHRvbSBkb3duIHRvIDBcclxuXHRcdFx0XHRtZS5taW4gPSAwO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0dmFyIHNldE1pbiA9IHRpY2tPcHRzLm1pbiAhPT0gdW5kZWZpbmVkIHx8IHRpY2tPcHRzLnN1Z2dlc3RlZE1pbiAhPT0gdW5kZWZpbmVkO1xyXG5cdFx0dmFyIHNldE1heCA9IHRpY2tPcHRzLm1heCAhPT0gdW5kZWZpbmVkIHx8IHRpY2tPcHRzLnN1Z2dlc3RlZE1heCAhPT0gdW5kZWZpbmVkO1xyXG5cclxuXHRcdGlmICh0aWNrT3B0cy5taW4gIT09IHVuZGVmaW5lZCkge1xyXG5cdFx0XHRtZS5taW4gPSB0aWNrT3B0cy5taW47XHJcblx0XHR9IGVsc2UgaWYgKHRpY2tPcHRzLnN1Z2dlc3RlZE1pbiAhPT0gdW5kZWZpbmVkKSB7XHJcblx0XHRcdGlmIChtZS5taW4gPT09IG51bGwpIHtcclxuXHRcdFx0XHRtZS5taW4gPSB0aWNrT3B0cy5zdWdnZXN0ZWRNaW47XHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0bWUubWluID0gTWF0aC5taW4obWUubWluLCB0aWNrT3B0cy5zdWdnZXN0ZWRNaW4pO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKHRpY2tPcHRzLm1heCAhPT0gdW5kZWZpbmVkKSB7XHJcblx0XHRcdG1lLm1heCA9IHRpY2tPcHRzLm1heDtcclxuXHRcdH0gZWxzZSBpZiAodGlja09wdHMuc3VnZ2VzdGVkTWF4ICE9PSB1bmRlZmluZWQpIHtcclxuXHRcdFx0aWYgKG1lLm1heCA9PT0gbnVsbCkge1xyXG5cdFx0XHRcdG1lLm1heCA9IHRpY2tPcHRzLnN1Z2dlc3RlZE1heDtcclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRtZS5tYXggPSBNYXRoLm1heChtZS5tYXgsIHRpY2tPcHRzLnN1Z2dlc3RlZE1heCk7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHRpZiAoc2V0TWluICE9PSBzZXRNYXgpIHtcclxuXHRcdFx0Ly8gV2Ugc2V0IHRoZSBtaW4gb3IgdGhlIG1heCBidXQgbm90IGJvdGguXHJcblx0XHRcdC8vIFNvIGVuc3VyZSB0aGF0IG91ciByYW5nZSBpcyBnb29kXHJcblx0XHRcdC8vIEludmVydGVkIG9yIDAgbGVuZ3RoIHJhbmdlIGNhbiBoYXBwZW4gd2hlblxyXG5cdFx0XHQvLyB0aWNrcy5taW4gaXMgc2V0LCBhbmQgbm8gZGF0YXNldHMgYXJlIHZpc2libGVcclxuXHRcdFx0aWYgKG1lLm1pbiA+PSBtZS5tYXgpIHtcclxuXHRcdFx0XHRpZiAoc2V0TWluKSB7XHJcblx0XHRcdFx0XHRtZS5tYXggPSBtZS5taW4gKyAxO1xyXG5cdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRtZS5taW4gPSBtZS5tYXggLSAxO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdGlmIChtZS5taW4gPT09IG1lLm1heCkge1xyXG5cdFx0XHRtZS5tYXgrKztcclxuXHJcblx0XHRcdGlmICghdGlja09wdHMuYmVnaW5BdFplcm8pIHtcclxuXHRcdFx0XHRtZS5taW4tLTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdH0sXHJcblxyXG5cdGdldFRpY2tMaW1pdDogZnVuY3Rpb24oKSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0dmFyIHRpY2tPcHRzID0gbWUub3B0aW9ucy50aWNrcztcclxuXHRcdHZhciBzdGVwU2l6ZSA9IHRpY2tPcHRzLnN0ZXBTaXplO1xyXG5cdFx0dmFyIG1heFRpY2tzTGltaXQgPSB0aWNrT3B0cy5tYXhUaWNrc0xpbWl0O1xyXG5cdFx0dmFyIG1heFRpY2tzO1xyXG5cclxuXHRcdGlmIChzdGVwU2l6ZSkge1xyXG5cdFx0XHRtYXhUaWNrcyA9IE1hdGguY2VpbChtZS5tYXggLyBzdGVwU2l6ZSkgLSBNYXRoLmZsb29yKG1lLm1pbiAvIHN0ZXBTaXplKSArIDE7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRtYXhUaWNrcyA9IG1lLl9jb21wdXRlVGlja0xpbWl0KCk7XHJcblx0XHRcdG1heFRpY2tzTGltaXQgPSBtYXhUaWNrc0xpbWl0IHx8IDExO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmIChtYXhUaWNrc0xpbWl0KSB7XHJcblx0XHRcdG1heFRpY2tzID0gTWF0aC5taW4obWF4VGlja3NMaW1pdCwgbWF4VGlja3MpO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiBtYXhUaWNrcztcclxuXHR9LFxyXG5cclxuXHRfY29tcHV0ZVRpY2tMaW1pdDogZnVuY3Rpb24oKSB7XHJcblx0XHRyZXR1cm4gTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZO1xyXG5cdH0sXHJcblxyXG5cdGhhbmRsZURpcmVjdGlvbmFsQ2hhbmdlczogbm9vcCxcclxuXHJcblx0YnVpbGRUaWNrczogZnVuY3Rpb24oKSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0dmFyIG9wdHMgPSBtZS5vcHRpb25zO1xyXG5cdFx0dmFyIHRpY2tPcHRzID0gb3B0cy50aWNrcztcclxuXHJcblx0XHQvLyBGaWd1cmUgb3V0IHdoYXQgdGhlIG1heCBudW1iZXIgb2YgdGlja3Mgd2UgY2FuIHN1cHBvcnQgaXQgaXMgYmFzZWQgb24gdGhlIHNpemUgb2ZcclxuXHRcdC8vIHRoZSBheGlzIGFyZWEuIEZvciBub3csIHdlIHNheSB0aGF0IHRoZSBtaW5pbXVtIHRpY2sgc3BhY2luZyBpbiBwaXhlbHMgbXVzdCBiZSA0MFxyXG5cdFx0Ly8gV2UgYWxzbyBsaW1pdCB0aGUgbWF4aW11bSBudW1iZXIgb2YgdGlja3MgdG8gMTEgd2hpY2ggZ2l2ZXMgYSBuaWNlIDEwIHNxdWFyZXMgb25cclxuXHRcdC8vIHRoZSBncmFwaC4gTWFrZSBzdXJlIHdlIGFsd2F5cyBoYXZlIGF0IGxlYXN0IDIgdGlja3NcclxuXHRcdHZhciBtYXhUaWNrcyA9IG1lLmdldFRpY2tMaW1pdCgpO1xyXG5cdFx0bWF4VGlja3MgPSBNYXRoLm1heCgyLCBtYXhUaWNrcyk7XHJcblxyXG5cdFx0dmFyIG51bWVyaWNHZW5lcmF0b3JPcHRpb25zID0ge1xyXG5cdFx0XHRtYXhUaWNrczogbWF4VGlja3MsXHJcblx0XHRcdG1pbjogdGlja09wdHMubWluLFxyXG5cdFx0XHRtYXg6IHRpY2tPcHRzLm1heCxcclxuXHRcdFx0cHJlY2lzaW9uOiB0aWNrT3B0cy5wcmVjaXNpb24sXHJcblx0XHRcdHN0ZXBTaXplOiBoZWxwZXJzJDEudmFsdWVPckRlZmF1bHQodGlja09wdHMuZml4ZWRTdGVwU2l6ZSwgdGlja09wdHMuc3RlcFNpemUpXHJcblx0XHR9O1xyXG5cdFx0dmFyIHRpY2tzID0gbWUudGlja3MgPSBnZW5lcmF0ZVRpY2tzKG51bWVyaWNHZW5lcmF0b3JPcHRpb25zLCBtZSk7XHJcblxyXG5cdFx0bWUuaGFuZGxlRGlyZWN0aW9uYWxDaGFuZ2VzKCk7XHJcblxyXG5cdFx0Ly8gQXQgdGhpcyBwb2ludCwgd2UgbmVlZCB0byB1cGRhdGUgb3VyIG1heCBhbmQgbWluIGdpdmVuIHRoZSB0aWNrIHZhbHVlcyBzaW5jZSB3ZSBoYXZlIGV4cGFuZGVkIHRoZVxyXG5cdFx0Ly8gcmFuZ2Ugb2YgdGhlIHNjYWxlXHJcblx0XHRtZS5tYXggPSBoZWxwZXJzJDEubWF4KHRpY2tzKTtcclxuXHRcdG1lLm1pbiA9IGhlbHBlcnMkMS5taW4odGlja3MpO1xyXG5cclxuXHRcdGlmICh0aWNrT3B0cy5yZXZlcnNlKSB7XHJcblx0XHRcdHRpY2tzLnJldmVyc2UoKTtcclxuXHJcblx0XHRcdG1lLnN0YXJ0ID0gbWUubWF4O1xyXG5cdFx0XHRtZS5lbmQgPSBtZS5taW47XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRtZS5zdGFydCA9IG1lLm1pbjtcclxuXHRcdFx0bWUuZW5kID0gbWUubWF4O1xyXG5cdFx0fVxyXG5cdH0sXHJcblxyXG5cdGNvbnZlcnRUaWNrc1RvTGFiZWxzOiBmdW5jdGlvbigpIHtcclxuXHRcdHZhciBtZSA9IHRoaXM7XHJcblx0XHRtZS50aWNrc0FzTnVtYmVycyA9IG1lLnRpY2tzLnNsaWNlKCk7XHJcblx0XHRtZS56ZXJvTGluZUluZGV4ID0gbWUudGlja3MuaW5kZXhPZigwKTtcclxuXHJcblx0XHRjb3JlX3NjYWxlLnByb3RvdHlwZS5jb252ZXJ0VGlja3NUb0xhYmVscy5jYWxsKG1lKTtcclxuXHR9LFxyXG5cclxuXHRfY29uZmlndXJlOiBmdW5jdGlvbigpIHtcclxuXHRcdHZhciBtZSA9IHRoaXM7XHJcblx0XHR2YXIgdGlja3MgPSBtZS5nZXRUaWNrcygpO1xyXG5cdFx0dmFyIHN0YXJ0ID0gbWUubWluO1xyXG5cdFx0dmFyIGVuZCA9IG1lLm1heDtcclxuXHRcdHZhciBvZmZzZXQ7XHJcblxyXG5cdFx0Y29yZV9zY2FsZS5wcm90b3R5cGUuX2NvbmZpZ3VyZS5jYWxsKG1lKTtcclxuXHJcblx0XHRpZiAobWUub3B0aW9ucy5vZmZzZXQgJiYgdGlja3MubGVuZ3RoKSB7XHJcblx0XHRcdG9mZnNldCA9IChlbmQgLSBzdGFydCkgLyBNYXRoLm1heCh0aWNrcy5sZW5ndGggLSAxLCAxKSAvIDI7XHJcblx0XHRcdHN0YXJ0IC09IG9mZnNldDtcclxuXHRcdFx0ZW5kICs9IG9mZnNldDtcclxuXHRcdH1cclxuXHRcdG1lLl9zdGFydFZhbHVlID0gc3RhcnQ7XHJcblx0XHRtZS5fZW5kVmFsdWUgPSBlbmQ7XHJcblx0XHRtZS5fdmFsdWVSYW5nZSA9IGVuZCAtIHN0YXJ0O1xyXG5cdH1cclxufSk7XG5cbnZhciBkZWZhdWx0Q29uZmlnJDEgPSB7XHJcblx0cG9zaXRpb246ICdsZWZ0JyxcclxuXHR0aWNrczoge1xyXG5cdFx0Y2FsbGJhY2s6IGNvcmVfdGlja3MuZm9ybWF0dGVycy5saW5lYXJcclxuXHR9XHJcbn07XHJcblxyXG52YXIgREVGQVVMVF9NSU4gPSAwO1xyXG52YXIgREVGQVVMVF9NQVggPSAxO1xyXG5cclxuZnVuY3Rpb24gZ2V0T3JDcmVhdGVTdGFjayhzdGFja3MsIHN0YWNrZWQsIG1ldGEpIHtcclxuXHR2YXIga2V5ID0gW1xyXG5cdFx0bWV0YS50eXBlLFxyXG5cdFx0Ly8gd2UgaGF2ZSBhIHNlcGFyYXRlIHN0YWNrIGZvciBzdGFjaz11bmRlZmluZWQgZGF0YXNldHMgd2hlbiB0aGUgb3B0cy5zdGFja2VkIGlzIHVuZGVmaW5lZFxyXG5cdFx0c3RhY2tlZCA9PT0gdW5kZWZpbmVkICYmIG1ldGEuc3RhY2sgPT09IHVuZGVmaW5lZCA/IG1ldGEuaW5kZXggOiAnJyxcclxuXHRcdG1ldGEuc3RhY2tcclxuXHRdLmpvaW4oJy4nKTtcclxuXHJcblx0aWYgKHN0YWNrc1trZXldID09PSB1bmRlZmluZWQpIHtcclxuXHRcdHN0YWNrc1trZXldID0ge1xyXG5cdFx0XHRwb3M6IFtdLFxyXG5cdFx0XHRuZWc6IFtdXHJcblx0XHR9O1xyXG5cdH1cclxuXHJcblx0cmV0dXJuIHN0YWNrc1trZXldO1xyXG59XHJcblxyXG5mdW5jdGlvbiBzdGFja0RhdGEoc2NhbGUsIHN0YWNrcywgbWV0YSwgZGF0YSkge1xyXG5cdHZhciBvcHRzID0gc2NhbGUub3B0aW9ucztcclxuXHR2YXIgc3RhY2tlZCA9IG9wdHMuc3RhY2tlZDtcclxuXHR2YXIgc3RhY2sgPSBnZXRPckNyZWF0ZVN0YWNrKHN0YWNrcywgc3RhY2tlZCwgbWV0YSk7XHJcblx0dmFyIHBvcyA9IHN0YWNrLnBvcztcclxuXHR2YXIgbmVnID0gc3RhY2submVnO1xyXG5cdHZhciBpbGVuID0gZGF0YS5sZW5ndGg7XHJcblx0dmFyIGksIHZhbHVlO1xyXG5cclxuXHRmb3IgKGkgPSAwOyBpIDwgaWxlbjsgKytpKSB7XHJcblx0XHR2YWx1ZSA9IHNjYWxlLl9wYXJzZVZhbHVlKGRhdGFbaV0pO1xyXG5cdFx0aWYgKGlzTmFOKHZhbHVlLm1pbikgfHwgaXNOYU4odmFsdWUubWF4KSB8fCBtZXRhLmRhdGFbaV0uaGlkZGVuKSB7XHJcblx0XHRcdGNvbnRpbnVlO1xyXG5cdFx0fVxyXG5cclxuXHRcdHBvc1tpXSA9IHBvc1tpXSB8fCAwO1xyXG5cdFx0bmVnW2ldID0gbmVnW2ldIHx8IDA7XHJcblxyXG5cdFx0aWYgKG9wdHMucmVsYXRpdmVQb2ludHMpIHtcclxuXHRcdFx0cG9zW2ldID0gMTAwO1xyXG5cdFx0fSBlbHNlIGlmICh2YWx1ZS5taW4gPCAwIHx8IHZhbHVlLm1heCA8IDApIHtcclxuXHRcdFx0bmVnW2ldICs9IHZhbHVlLm1pbjtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdHBvc1tpXSArPSB2YWx1ZS5tYXg7XHJcblx0XHR9XHJcblx0fVxyXG59XHJcblxyXG5mdW5jdGlvbiB1cGRhdGVNaW5NYXgoc2NhbGUsIG1ldGEsIGRhdGEpIHtcclxuXHR2YXIgaWxlbiA9IGRhdGEubGVuZ3RoO1xyXG5cdHZhciBpLCB2YWx1ZTtcclxuXHJcblx0Zm9yIChpID0gMDsgaSA8IGlsZW47ICsraSkge1xyXG5cdFx0dmFsdWUgPSBzY2FsZS5fcGFyc2VWYWx1ZShkYXRhW2ldKTtcclxuXHRcdGlmIChpc05hTih2YWx1ZS5taW4pIHx8IGlzTmFOKHZhbHVlLm1heCkgfHwgbWV0YS5kYXRhW2ldLmhpZGRlbikge1xyXG5cdFx0XHRjb250aW51ZTtcclxuXHRcdH1cclxuXHJcblx0XHRzY2FsZS5taW4gPSBNYXRoLm1pbihzY2FsZS5taW4sIHZhbHVlLm1pbik7XHJcblx0XHRzY2FsZS5tYXggPSBNYXRoLm1heChzY2FsZS5tYXgsIHZhbHVlLm1heCk7XHJcblx0fVxyXG59XHJcblxyXG52YXIgc2NhbGVfbGluZWFyID0gc2NhbGVfbGluZWFyYmFzZS5leHRlbmQoe1xyXG5cdGRldGVybWluZURhdGFMaW1pdHM6IGZ1bmN0aW9uKCkge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHRcdHZhciBvcHRzID0gbWUub3B0aW9ucztcclxuXHRcdHZhciBjaGFydCA9IG1lLmNoYXJ0O1xyXG5cdFx0dmFyIGRhdGFzZXRzID0gY2hhcnQuZGF0YS5kYXRhc2V0cztcclxuXHRcdHZhciBtZXRhc2V0cyA9IG1lLl9nZXRNYXRjaGluZ1Zpc2libGVNZXRhcygpO1xyXG5cdFx0dmFyIGhhc1N0YWNrcyA9IG9wdHMuc3RhY2tlZDtcclxuXHRcdHZhciBzdGFja3MgPSB7fTtcclxuXHRcdHZhciBpbGVuID0gbWV0YXNldHMubGVuZ3RoO1xyXG5cdFx0dmFyIGksIG1ldGEsIGRhdGEsIHZhbHVlcztcclxuXHJcblx0XHRtZS5taW4gPSBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFk7XHJcblx0XHRtZS5tYXggPSBOdW1iZXIuTkVHQVRJVkVfSU5GSU5JVFk7XHJcblxyXG5cdFx0aWYgKGhhc1N0YWNrcyA9PT0gdW5kZWZpbmVkKSB7XHJcblx0XHRcdGZvciAoaSA9IDA7ICFoYXNTdGFja3MgJiYgaSA8IGlsZW47ICsraSkge1xyXG5cdFx0XHRcdG1ldGEgPSBtZXRhc2V0c1tpXTtcclxuXHRcdFx0XHRoYXNTdGFja3MgPSBtZXRhLnN0YWNrICE9PSB1bmRlZmluZWQ7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHRmb3IgKGkgPSAwOyBpIDwgaWxlbjsgKytpKSB7XHJcblx0XHRcdG1ldGEgPSBtZXRhc2V0c1tpXTtcclxuXHRcdFx0ZGF0YSA9IGRhdGFzZXRzW21ldGEuaW5kZXhdLmRhdGE7XHJcblx0XHRcdGlmIChoYXNTdGFja3MpIHtcclxuXHRcdFx0XHRzdGFja0RhdGEobWUsIHN0YWNrcywgbWV0YSwgZGF0YSk7XHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0dXBkYXRlTWluTWF4KG1lLCBtZXRhLCBkYXRhKTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdGhlbHBlcnMkMS5lYWNoKHN0YWNrcywgZnVuY3Rpb24oc3RhY2tWYWx1ZXMpIHtcclxuXHRcdFx0dmFsdWVzID0gc3RhY2tWYWx1ZXMucG9zLmNvbmNhdChzdGFja1ZhbHVlcy5uZWcpO1xyXG5cdFx0XHRtZS5taW4gPSBNYXRoLm1pbihtZS5taW4sIGhlbHBlcnMkMS5taW4odmFsdWVzKSk7XHJcblx0XHRcdG1lLm1heCA9IE1hdGgubWF4KG1lLm1heCwgaGVscGVycyQxLm1heCh2YWx1ZXMpKTtcclxuXHRcdH0pO1xyXG5cclxuXHRcdG1lLm1pbiA9IGhlbHBlcnMkMS5pc0Zpbml0ZShtZS5taW4pICYmICFpc05hTihtZS5taW4pID8gbWUubWluIDogREVGQVVMVF9NSU47XHJcblx0XHRtZS5tYXggPSBoZWxwZXJzJDEuaXNGaW5pdGUobWUubWF4KSAmJiAhaXNOYU4obWUubWF4KSA/IG1lLm1heCA6IERFRkFVTFRfTUFYO1xyXG5cclxuXHRcdC8vIENvbW1vbiBiYXNlIGltcGxlbWVudGF0aW9uIHRvIGhhbmRsZSB0aWNrcy5taW4sIHRpY2tzLm1heCwgdGlja3MuYmVnaW5BdFplcm9cclxuXHRcdG1lLmhhbmRsZVRpY2tSYW5nZU9wdGlvbnMoKTtcclxuXHR9LFxyXG5cclxuXHQvLyBSZXR1cm5zIHRoZSBtYXhpbXVtIG51bWJlciBvZiB0aWNrcyBiYXNlZCBvbiB0aGUgc2NhbGUgZGltZW5zaW9uXHJcblx0X2NvbXB1dGVUaWNrTGltaXQ6IGZ1bmN0aW9uKCkge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHRcdHZhciB0aWNrRm9udDtcclxuXHJcblx0XHRpZiAobWUuaXNIb3Jpem9udGFsKCkpIHtcclxuXHRcdFx0cmV0dXJuIE1hdGguY2VpbChtZS53aWR0aCAvIDQwKTtcclxuXHRcdH1cclxuXHRcdHRpY2tGb250ID0gaGVscGVycyQxLm9wdGlvbnMuX3BhcnNlRm9udChtZS5vcHRpb25zLnRpY2tzKTtcclxuXHRcdHJldHVybiBNYXRoLmNlaWwobWUuaGVpZ2h0IC8gdGlja0ZvbnQubGluZUhlaWdodCk7XHJcblx0fSxcclxuXHJcblx0Ly8gQ2FsbGVkIGFmdGVyIHRoZSB0aWNrcyBhcmUgYnVpbHQuIFdlIG5lZWRcclxuXHRoYW5kbGVEaXJlY3Rpb25hbENoYW5nZXM6IGZ1bmN0aW9uKCkge1xyXG5cdFx0aWYgKCF0aGlzLmlzSG9yaXpvbnRhbCgpKSB7XHJcblx0XHRcdC8vIFdlIGFyZSBpbiBhIHZlcnRpY2FsIG9yaWVudGF0aW9uLiBUaGUgdG9wIHZhbHVlIGlzIHRoZSBoaWdoZXN0LiBTbyByZXZlcnNlIHRoZSBhcnJheVxyXG5cdFx0XHR0aGlzLnRpY2tzLnJldmVyc2UoKTtcclxuXHRcdH1cclxuXHR9LFxyXG5cclxuXHRnZXRMYWJlbEZvckluZGV4OiBmdW5jdGlvbihpbmRleCwgZGF0YXNldEluZGV4KSB7XHJcblx0XHRyZXR1cm4gdGhpcy5fZ2V0U2NhbGVMYWJlbCh0aGlzLmNoYXJ0LmRhdGEuZGF0YXNldHNbZGF0YXNldEluZGV4XS5kYXRhW2luZGV4XSk7XHJcblx0fSxcclxuXHJcblx0Ly8gVXRpbHNcclxuXHRnZXRQaXhlbEZvclZhbHVlOiBmdW5jdGlvbih2YWx1ZSkge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHRcdHJldHVybiBtZS5nZXRQaXhlbEZvckRlY2ltYWwoKCttZS5nZXRSaWdodFZhbHVlKHZhbHVlKSAtIG1lLl9zdGFydFZhbHVlKSAvIG1lLl92YWx1ZVJhbmdlKTtcclxuXHR9LFxyXG5cclxuXHRnZXRWYWx1ZUZvclBpeGVsOiBmdW5jdGlvbihwaXhlbCkge1xyXG5cdFx0cmV0dXJuIHRoaXMuX3N0YXJ0VmFsdWUgKyB0aGlzLmdldERlY2ltYWxGb3JQaXhlbChwaXhlbCkgKiB0aGlzLl92YWx1ZVJhbmdlO1xyXG5cdH0sXHJcblxyXG5cdGdldFBpeGVsRm9yVGljazogZnVuY3Rpb24oaW5kZXgpIHtcclxuXHRcdHZhciB0aWNrcyA9IHRoaXMudGlja3NBc051bWJlcnM7XHJcblx0XHRpZiAoaW5kZXggPCAwIHx8IGluZGV4ID4gdGlja3MubGVuZ3RoIC0gMSkge1xyXG5cdFx0XHRyZXR1cm4gbnVsbDtcclxuXHRcdH1cclxuXHRcdHJldHVybiB0aGlzLmdldFBpeGVsRm9yVmFsdWUodGlja3NbaW5kZXhdKTtcclxuXHR9XHJcbn0pO1xyXG5cclxuLy8gSU5URVJOQUw6IHN0YXRpYyBkZWZhdWx0IG9wdGlvbnMsIHJlZ2lzdGVyZWQgaW4gc3JjL2luZGV4LmpzXHJcbnZhciBfZGVmYXVsdHMkMSA9IGRlZmF1bHRDb25maWckMTtcbnNjYWxlX2xpbmVhci5fZGVmYXVsdHMgPSBfZGVmYXVsdHMkMTtcblxudmFyIHZhbHVlT3JEZWZhdWx0JGIgPSBoZWxwZXJzJDEudmFsdWVPckRlZmF1bHQ7XHJcbnZhciBsb2cxMCA9IGhlbHBlcnMkMS5tYXRoLmxvZzEwO1xyXG5cclxuLyoqXHJcbiAqIEdlbmVyYXRlIGEgc2V0IG9mIGxvZ2FyaXRobWljIHRpY2tzXHJcbiAqIEBwYXJhbSBnZW5lcmF0aW9uT3B0aW9ucyB0aGUgb3B0aW9ucyB1c2VkIHRvIGdlbmVyYXRlIHRoZSB0aWNrc1xyXG4gKiBAcGFyYW0gZGF0YVJhbmdlIHRoZSByYW5nZSBvZiB0aGUgZGF0YVxyXG4gKiBAcmV0dXJucyB7bnVtYmVyW119IGFycmF5IG9mIHRpY2sgdmFsdWVzXHJcbiAqL1xyXG5mdW5jdGlvbiBnZW5lcmF0ZVRpY2tzJDEoZ2VuZXJhdGlvbk9wdGlvbnMsIGRhdGFSYW5nZSkge1xyXG5cdHZhciB0aWNrcyA9IFtdO1xyXG5cclxuXHR2YXIgdGlja1ZhbCA9IHZhbHVlT3JEZWZhdWx0JGIoZ2VuZXJhdGlvbk9wdGlvbnMubWluLCBNYXRoLnBvdygxMCwgTWF0aC5mbG9vcihsb2cxMChkYXRhUmFuZ2UubWluKSkpKTtcclxuXHJcblx0dmFyIGVuZEV4cCA9IE1hdGguZmxvb3IobG9nMTAoZGF0YVJhbmdlLm1heCkpO1xyXG5cdHZhciBlbmRTaWduaWZpY2FuZCA9IE1hdGguY2VpbChkYXRhUmFuZ2UubWF4IC8gTWF0aC5wb3coMTAsIGVuZEV4cCkpO1xyXG5cdHZhciBleHAsIHNpZ25pZmljYW5kO1xyXG5cclxuXHRpZiAodGlja1ZhbCA9PT0gMCkge1xyXG5cdFx0ZXhwID0gTWF0aC5mbG9vcihsb2cxMChkYXRhUmFuZ2UubWluTm90WmVybykpO1xyXG5cdFx0c2lnbmlmaWNhbmQgPSBNYXRoLmZsb29yKGRhdGFSYW5nZS5taW5Ob3RaZXJvIC8gTWF0aC5wb3coMTAsIGV4cCkpO1xyXG5cclxuXHRcdHRpY2tzLnB1c2godGlja1ZhbCk7XHJcblx0XHR0aWNrVmFsID0gc2lnbmlmaWNhbmQgKiBNYXRoLnBvdygxMCwgZXhwKTtcclxuXHR9IGVsc2Uge1xyXG5cdFx0ZXhwID0gTWF0aC5mbG9vcihsb2cxMCh0aWNrVmFsKSk7XHJcblx0XHRzaWduaWZpY2FuZCA9IE1hdGguZmxvb3IodGlja1ZhbCAvIE1hdGgucG93KDEwLCBleHApKTtcclxuXHR9XHJcblx0dmFyIHByZWNpc2lvbiA9IGV4cCA8IDAgPyBNYXRoLnBvdygxMCwgTWF0aC5hYnMoZXhwKSkgOiAxO1xyXG5cclxuXHRkbyB7XHJcblx0XHR0aWNrcy5wdXNoKHRpY2tWYWwpO1xyXG5cclxuXHRcdCsrc2lnbmlmaWNhbmQ7XHJcblx0XHRpZiAoc2lnbmlmaWNhbmQgPT09IDEwKSB7XHJcblx0XHRcdHNpZ25pZmljYW5kID0gMTtcclxuXHRcdFx0KytleHA7XHJcblx0XHRcdHByZWNpc2lvbiA9IGV4cCA+PSAwID8gMSA6IHByZWNpc2lvbjtcclxuXHRcdH1cclxuXHJcblx0XHR0aWNrVmFsID0gTWF0aC5yb3VuZChzaWduaWZpY2FuZCAqIE1hdGgucG93KDEwLCBleHApICogcHJlY2lzaW9uKSAvIHByZWNpc2lvbjtcclxuXHR9IHdoaWxlIChleHAgPCBlbmRFeHAgfHwgKGV4cCA9PT0gZW5kRXhwICYmIHNpZ25pZmljYW5kIDwgZW5kU2lnbmlmaWNhbmQpKTtcclxuXHJcblx0dmFyIGxhc3RUaWNrID0gdmFsdWVPckRlZmF1bHQkYihnZW5lcmF0aW9uT3B0aW9ucy5tYXgsIHRpY2tWYWwpO1xyXG5cdHRpY2tzLnB1c2gobGFzdFRpY2spO1xyXG5cclxuXHRyZXR1cm4gdGlja3M7XHJcbn1cclxuXHJcbnZhciBkZWZhdWx0Q29uZmlnJDIgPSB7XHJcblx0cG9zaXRpb246ICdsZWZ0JyxcclxuXHJcblx0Ly8gbGFiZWwgc2V0dGluZ3NcclxuXHR0aWNrczoge1xyXG5cdFx0Y2FsbGJhY2s6IGNvcmVfdGlja3MuZm9ybWF0dGVycy5sb2dhcml0aG1pY1xyXG5cdH1cclxufTtcclxuXHJcbi8vIFRPRE8odjMpOiBjaGFuZ2UgdGhpcyB0byBwb3NpdGl2ZU9yRGVmYXVsdFxyXG5mdW5jdGlvbiBub25OZWdhdGl2ZU9yRGVmYXVsdCh2YWx1ZSwgZGVmYXVsdFZhbHVlKSB7XHJcblx0cmV0dXJuIGhlbHBlcnMkMS5pc0Zpbml0ZSh2YWx1ZSkgJiYgdmFsdWUgPj0gMCA/IHZhbHVlIDogZGVmYXVsdFZhbHVlO1xyXG59XHJcblxyXG52YXIgc2NhbGVfbG9nYXJpdGhtaWMgPSBjb3JlX3NjYWxlLmV4dGVuZCh7XHJcblx0ZGV0ZXJtaW5lRGF0YUxpbWl0czogZnVuY3Rpb24oKSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0dmFyIG9wdHMgPSBtZS5vcHRpb25zO1xyXG5cdFx0dmFyIGNoYXJ0ID0gbWUuY2hhcnQ7XHJcblx0XHR2YXIgZGF0YXNldHMgPSBjaGFydC5kYXRhLmRhdGFzZXRzO1xyXG5cdFx0dmFyIGlzSG9yaXpvbnRhbCA9IG1lLmlzSG9yaXpvbnRhbCgpO1xyXG5cdFx0ZnVuY3Rpb24gSURNYXRjaGVzKG1ldGEpIHtcclxuXHRcdFx0cmV0dXJuIGlzSG9yaXpvbnRhbCA/IG1ldGEueEF4aXNJRCA9PT0gbWUuaWQgOiBtZXRhLnlBeGlzSUQgPT09IG1lLmlkO1xyXG5cdFx0fVxyXG5cdFx0dmFyIGRhdGFzZXRJbmRleCwgbWV0YSwgdmFsdWUsIGRhdGEsIGksIGlsZW47XHJcblxyXG5cdFx0Ly8gQ2FsY3VsYXRlIFJhbmdlXHJcblx0XHRtZS5taW4gPSBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFk7XHJcblx0XHRtZS5tYXggPSBOdW1iZXIuTkVHQVRJVkVfSU5GSU5JVFk7XHJcblx0XHRtZS5taW5Ob3RaZXJvID0gTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZO1xyXG5cclxuXHRcdHZhciBoYXNTdGFja3MgPSBvcHRzLnN0YWNrZWQ7XHJcblx0XHRpZiAoaGFzU3RhY2tzID09PSB1bmRlZmluZWQpIHtcclxuXHRcdFx0Zm9yIChkYXRhc2V0SW5kZXggPSAwOyBkYXRhc2V0SW5kZXggPCBkYXRhc2V0cy5sZW5ndGg7IGRhdGFzZXRJbmRleCsrKSB7XHJcblx0XHRcdFx0bWV0YSA9IGNoYXJ0LmdldERhdGFzZXRNZXRhKGRhdGFzZXRJbmRleCk7XHJcblx0XHRcdFx0aWYgKGNoYXJ0LmlzRGF0YXNldFZpc2libGUoZGF0YXNldEluZGV4KSAmJiBJRE1hdGNoZXMobWV0YSkgJiZcclxuXHRcdFx0XHRcdG1ldGEuc3RhY2sgIT09IHVuZGVmaW5lZCkge1xyXG5cdFx0XHRcdFx0aGFzU3RhY2tzID0gdHJ1ZTtcclxuXHRcdFx0XHRcdGJyZWFrO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdGlmIChvcHRzLnN0YWNrZWQgfHwgaGFzU3RhY2tzKSB7XHJcblx0XHRcdHZhciB2YWx1ZXNQZXJTdGFjayA9IHt9O1xyXG5cclxuXHRcdFx0Zm9yIChkYXRhc2V0SW5kZXggPSAwOyBkYXRhc2V0SW5kZXggPCBkYXRhc2V0cy5sZW5ndGg7IGRhdGFzZXRJbmRleCsrKSB7XHJcblx0XHRcdFx0bWV0YSA9IGNoYXJ0LmdldERhdGFzZXRNZXRhKGRhdGFzZXRJbmRleCk7XHJcblx0XHRcdFx0dmFyIGtleSA9IFtcclxuXHRcdFx0XHRcdG1ldGEudHlwZSxcclxuXHRcdFx0XHRcdC8vIHdlIGhhdmUgYSBzZXBhcmF0ZSBzdGFjayBmb3Igc3RhY2s9dW5kZWZpbmVkIGRhdGFzZXRzIHdoZW4gdGhlIG9wdHMuc3RhY2tlZCBpcyB1bmRlZmluZWRcclxuXHRcdFx0XHRcdCgob3B0cy5zdGFja2VkID09PSB1bmRlZmluZWQgJiYgbWV0YS5zdGFjayA9PT0gdW5kZWZpbmVkKSA/IGRhdGFzZXRJbmRleCA6ICcnKSxcclxuXHRcdFx0XHRcdG1ldGEuc3RhY2tcclxuXHRcdFx0XHRdLmpvaW4oJy4nKTtcclxuXHJcblx0XHRcdFx0aWYgKGNoYXJ0LmlzRGF0YXNldFZpc2libGUoZGF0YXNldEluZGV4KSAmJiBJRE1hdGNoZXMobWV0YSkpIHtcclxuXHRcdFx0XHRcdGlmICh2YWx1ZXNQZXJTdGFja1trZXldID09PSB1bmRlZmluZWQpIHtcclxuXHRcdFx0XHRcdFx0dmFsdWVzUGVyU3RhY2tba2V5XSA9IFtdO1xyXG5cdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRcdGRhdGEgPSBkYXRhc2V0c1tkYXRhc2V0SW5kZXhdLmRhdGE7XHJcblx0XHRcdFx0XHRmb3IgKGkgPSAwLCBpbGVuID0gZGF0YS5sZW5ndGg7IGkgPCBpbGVuOyBpKyspIHtcclxuXHRcdFx0XHRcdFx0dmFyIHZhbHVlcyA9IHZhbHVlc1BlclN0YWNrW2tleV07XHJcblx0XHRcdFx0XHRcdHZhbHVlID0gbWUuX3BhcnNlVmFsdWUoZGF0YVtpXSk7XHJcblx0XHRcdFx0XHRcdC8vIGludmFsaWQsIGhpZGRlbiBhbmQgbmVnYXRpdmUgdmFsdWVzIGFyZSBpZ25vcmVkXHJcblx0XHRcdFx0XHRcdGlmIChpc05hTih2YWx1ZS5taW4pIHx8IGlzTmFOKHZhbHVlLm1heCkgfHwgbWV0YS5kYXRhW2ldLmhpZGRlbiB8fCB2YWx1ZS5taW4gPCAwIHx8IHZhbHVlLm1heCA8IDApIHtcclxuXHRcdFx0XHRcdFx0XHRjb250aW51ZTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHR2YWx1ZXNbaV0gPSB2YWx1ZXNbaV0gfHwgMDtcclxuXHRcdFx0XHRcdFx0dmFsdWVzW2ldICs9IHZhbHVlLm1heDtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdGhlbHBlcnMkMS5lYWNoKHZhbHVlc1BlclN0YWNrLCBmdW5jdGlvbih2YWx1ZXNGb3JUeXBlKSB7XHJcblx0XHRcdFx0aWYgKHZhbHVlc0ZvclR5cGUubGVuZ3RoID4gMCkge1xyXG5cdFx0XHRcdFx0dmFyIG1pblZhbCA9IGhlbHBlcnMkMS5taW4odmFsdWVzRm9yVHlwZSk7XHJcblx0XHRcdFx0XHR2YXIgbWF4VmFsID0gaGVscGVycyQxLm1heCh2YWx1ZXNGb3JUeXBlKTtcclxuXHRcdFx0XHRcdG1lLm1pbiA9IE1hdGgubWluKG1lLm1pbiwgbWluVmFsKTtcclxuXHRcdFx0XHRcdG1lLm1heCA9IE1hdGgubWF4KG1lLm1heCwgbWF4VmFsKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH0pO1xyXG5cclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdGZvciAoZGF0YXNldEluZGV4ID0gMDsgZGF0YXNldEluZGV4IDwgZGF0YXNldHMubGVuZ3RoOyBkYXRhc2V0SW5kZXgrKykge1xyXG5cdFx0XHRcdG1ldGEgPSBjaGFydC5nZXREYXRhc2V0TWV0YShkYXRhc2V0SW5kZXgpO1xyXG5cdFx0XHRcdGlmIChjaGFydC5pc0RhdGFzZXRWaXNpYmxlKGRhdGFzZXRJbmRleCkgJiYgSURNYXRjaGVzKG1ldGEpKSB7XHJcblx0XHRcdFx0XHRkYXRhID0gZGF0YXNldHNbZGF0YXNldEluZGV4XS5kYXRhO1xyXG5cdFx0XHRcdFx0Zm9yIChpID0gMCwgaWxlbiA9IGRhdGEubGVuZ3RoOyBpIDwgaWxlbjsgaSsrKSB7XHJcblx0XHRcdFx0XHRcdHZhbHVlID0gbWUuX3BhcnNlVmFsdWUoZGF0YVtpXSk7XHJcblx0XHRcdFx0XHRcdC8vIGludmFsaWQsIGhpZGRlbiBhbmQgbmVnYXRpdmUgdmFsdWVzIGFyZSBpZ25vcmVkXHJcblx0XHRcdFx0XHRcdGlmIChpc05hTih2YWx1ZS5taW4pIHx8IGlzTmFOKHZhbHVlLm1heCkgfHwgbWV0YS5kYXRhW2ldLmhpZGRlbiB8fCB2YWx1ZS5taW4gPCAwIHx8IHZhbHVlLm1heCA8IDApIHtcclxuXHRcdFx0XHRcdFx0XHRjb250aW51ZTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRcdFx0bWUubWluID0gTWF0aC5taW4odmFsdWUubWluLCBtZS5taW4pO1xyXG5cdFx0XHRcdFx0XHRtZS5tYXggPSBNYXRoLm1heCh2YWx1ZS5tYXgsIG1lLm1heCk7XHJcblxyXG5cdFx0XHRcdFx0XHRpZiAodmFsdWUubWluICE9PSAwKSB7XHJcblx0XHRcdFx0XHRcdFx0bWUubWluTm90WmVybyA9IE1hdGgubWluKHZhbHVlLm1pbiwgbWUubWluTm90WmVybyk7XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHRtZS5taW4gPSBoZWxwZXJzJDEuaXNGaW5pdGUobWUubWluKSA/IG1lLm1pbiA6IG51bGw7XHJcblx0XHRtZS5tYXggPSBoZWxwZXJzJDEuaXNGaW5pdGUobWUubWF4KSA/IG1lLm1heCA6IG51bGw7XHJcblx0XHRtZS5taW5Ob3RaZXJvID0gaGVscGVycyQxLmlzRmluaXRlKG1lLm1pbk5vdFplcm8pID8gbWUubWluTm90WmVybyA6IG51bGw7XHJcblxyXG5cdFx0Ly8gQ29tbW9uIGJhc2UgaW1wbGVtZW50YXRpb24gdG8gaGFuZGxlIHRpY2tzLm1pbiwgdGlja3MubWF4XHJcblx0XHR0aGlzLmhhbmRsZVRpY2tSYW5nZU9wdGlvbnMoKTtcclxuXHR9LFxyXG5cclxuXHRoYW5kbGVUaWNrUmFuZ2VPcHRpb25zOiBmdW5jdGlvbigpIHtcclxuXHRcdHZhciBtZSA9IHRoaXM7XHJcblx0XHR2YXIgdGlja09wdHMgPSBtZS5vcHRpb25zLnRpY2tzO1xyXG5cdFx0dmFyIERFRkFVTFRfTUlOID0gMTtcclxuXHRcdHZhciBERUZBVUxUX01BWCA9IDEwO1xyXG5cclxuXHRcdG1lLm1pbiA9IG5vbk5lZ2F0aXZlT3JEZWZhdWx0KHRpY2tPcHRzLm1pbiwgbWUubWluKTtcclxuXHRcdG1lLm1heCA9IG5vbk5lZ2F0aXZlT3JEZWZhdWx0KHRpY2tPcHRzLm1heCwgbWUubWF4KTtcclxuXHJcblx0XHRpZiAobWUubWluID09PSBtZS5tYXgpIHtcclxuXHRcdFx0aWYgKG1lLm1pbiAhPT0gMCAmJiBtZS5taW4gIT09IG51bGwpIHtcclxuXHRcdFx0XHRtZS5taW4gPSBNYXRoLnBvdygxMCwgTWF0aC5mbG9vcihsb2cxMChtZS5taW4pKSAtIDEpO1xyXG5cdFx0XHRcdG1lLm1heCA9IE1hdGgucG93KDEwLCBNYXRoLmZsb29yKGxvZzEwKG1lLm1heCkpICsgMSk7XHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0bWUubWluID0gREVGQVVMVF9NSU47XHJcblx0XHRcdFx0bWUubWF4ID0gREVGQVVMVF9NQVg7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHRcdGlmIChtZS5taW4gPT09IG51bGwpIHtcclxuXHRcdFx0bWUubWluID0gTWF0aC5wb3coMTAsIE1hdGguZmxvb3IobG9nMTAobWUubWF4KSkgLSAxKTtcclxuXHRcdH1cclxuXHRcdGlmIChtZS5tYXggPT09IG51bGwpIHtcclxuXHRcdFx0bWUubWF4ID0gbWUubWluICE9PSAwXHJcblx0XHRcdFx0PyBNYXRoLnBvdygxMCwgTWF0aC5mbG9vcihsb2cxMChtZS5taW4pKSArIDEpXHJcblx0XHRcdFx0OiBERUZBVUxUX01BWDtcclxuXHRcdH1cclxuXHRcdGlmIChtZS5taW5Ob3RaZXJvID09PSBudWxsKSB7XHJcblx0XHRcdGlmIChtZS5taW4gPiAwKSB7XHJcblx0XHRcdFx0bWUubWluTm90WmVybyA9IG1lLm1pbjtcclxuXHRcdFx0fSBlbHNlIGlmIChtZS5tYXggPCAxKSB7XHJcblx0XHRcdFx0bWUubWluTm90WmVybyA9IE1hdGgucG93KDEwLCBNYXRoLmZsb29yKGxvZzEwKG1lLm1heCkpKTtcclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRtZS5taW5Ob3RaZXJvID0gREVGQVVMVF9NSU47XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHR9LFxyXG5cclxuXHRidWlsZFRpY2tzOiBmdW5jdGlvbigpIHtcclxuXHRcdHZhciBtZSA9IHRoaXM7XHJcblx0XHR2YXIgdGlja09wdHMgPSBtZS5vcHRpb25zLnRpY2tzO1xyXG5cdFx0dmFyIHJldmVyc2UgPSAhbWUuaXNIb3Jpem9udGFsKCk7XHJcblxyXG5cdFx0dmFyIGdlbmVyYXRpb25PcHRpb25zID0ge1xyXG5cdFx0XHRtaW46IG5vbk5lZ2F0aXZlT3JEZWZhdWx0KHRpY2tPcHRzLm1pbiksXHJcblx0XHRcdG1heDogbm9uTmVnYXRpdmVPckRlZmF1bHQodGlja09wdHMubWF4KVxyXG5cdFx0fTtcclxuXHRcdHZhciB0aWNrcyA9IG1lLnRpY2tzID0gZ2VuZXJhdGVUaWNrcyQxKGdlbmVyYXRpb25PcHRpb25zLCBtZSk7XHJcblxyXG5cdFx0Ly8gQXQgdGhpcyBwb2ludCwgd2UgbmVlZCB0byB1cGRhdGUgb3VyIG1heCBhbmQgbWluIGdpdmVuIHRoZSB0aWNrIHZhbHVlcyBzaW5jZSB3ZSBoYXZlIGV4cGFuZGVkIHRoZVxyXG5cdFx0Ly8gcmFuZ2Ugb2YgdGhlIHNjYWxlXHJcblx0XHRtZS5tYXggPSBoZWxwZXJzJDEubWF4KHRpY2tzKTtcclxuXHRcdG1lLm1pbiA9IGhlbHBlcnMkMS5taW4odGlja3MpO1xyXG5cclxuXHRcdGlmICh0aWNrT3B0cy5yZXZlcnNlKSB7XHJcblx0XHRcdHJldmVyc2UgPSAhcmV2ZXJzZTtcclxuXHRcdFx0bWUuc3RhcnQgPSBtZS5tYXg7XHJcblx0XHRcdG1lLmVuZCA9IG1lLm1pbjtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdG1lLnN0YXJ0ID0gbWUubWluO1xyXG5cdFx0XHRtZS5lbmQgPSBtZS5tYXg7XHJcblx0XHR9XHJcblx0XHRpZiAocmV2ZXJzZSkge1xyXG5cdFx0XHR0aWNrcy5yZXZlcnNlKCk7XHJcblx0XHR9XHJcblx0fSxcclxuXHJcblx0Y29udmVydFRpY2tzVG9MYWJlbHM6IGZ1bmN0aW9uKCkge1xyXG5cdFx0dGhpcy50aWNrVmFsdWVzID0gdGhpcy50aWNrcy5zbGljZSgpO1xyXG5cclxuXHRcdGNvcmVfc2NhbGUucHJvdG90eXBlLmNvbnZlcnRUaWNrc1RvTGFiZWxzLmNhbGwodGhpcyk7XHJcblx0fSxcclxuXHJcblx0Ly8gR2V0IHRoZSBjb3JyZWN0IHRvb2x0aXAgbGFiZWxcclxuXHRnZXRMYWJlbEZvckluZGV4OiBmdW5jdGlvbihpbmRleCwgZGF0YXNldEluZGV4KSB7XHJcblx0XHRyZXR1cm4gdGhpcy5fZ2V0U2NhbGVMYWJlbCh0aGlzLmNoYXJ0LmRhdGEuZGF0YXNldHNbZGF0YXNldEluZGV4XS5kYXRhW2luZGV4XSk7XHJcblx0fSxcclxuXHJcblx0Z2V0UGl4ZWxGb3JUaWNrOiBmdW5jdGlvbihpbmRleCkge1xyXG5cdFx0dmFyIHRpY2tzID0gdGhpcy50aWNrVmFsdWVzO1xyXG5cdFx0aWYgKGluZGV4IDwgMCB8fCBpbmRleCA+IHRpY2tzLmxlbmd0aCAtIDEpIHtcclxuXHRcdFx0cmV0dXJuIG51bGw7XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gdGhpcy5nZXRQaXhlbEZvclZhbHVlKHRpY2tzW2luZGV4XSk7XHJcblx0fSxcclxuXHJcblx0LyoqXHJcblx0ICogUmV0dXJucyB0aGUgdmFsdWUgb2YgdGhlIGZpcnN0IHRpY2suXHJcblx0ICogQHBhcmFtIHtudW1iZXJ9IHZhbHVlIC0gVGhlIG1pbmltdW0gbm90IHplcm8gdmFsdWUuXHJcblx0ICogQHJldHVybiB7bnVtYmVyfSBUaGUgZmlyc3QgdGljayB2YWx1ZS5cclxuXHQgKiBAcHJpdmF0ZVxyXG5cdCAqL1xyXG5cdF9nZXRGaXJzdFRpY2tWYWx1ZTogZnVuY3Rpb24odmFsdWUpIHtcclxuXHRcdHZhciBleHAgPSBNYXRoLmZsb29yKGxvZzEwKHZhbHVlKSk7XHJcblx0XHR2YXIgc2lnbmlmaWNhbmQgPSBNYXRoLmZsb29yKHZhbHVlIC8gTWF0aC5wb3coMTAsIGV4cCkpO1xyXG5cclxuXHRcdHJldHVybiBzaWduaWZpY2FuZCAqIE1hdGgucG93KDEwLCBleHApO1xyXG5cdH0sXHJcblxyXG5cdF9jb25maWd1cmU6IGZ1bmN0aW9uKCkge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHRcdHZhciBzdGFydCA9IG1lLm1pbjtcclxuXHRcdHZhciBvZmZzZXQgPSAwO1xyXG5cclxuXHRcdGNvcmVfc2NhbGUucHJvdG90eXBlLl9jb25maWd1cmUuY2FsbChtZSk7XHJcblxyXG5cdFx0aWYgKHN0YXJ0ID09PSAwKSB7XHJcblx0XHRcdHN0YXJ0ID0gbWUuX2dldEZpcnN0VGlja1ZhbHVlKG1lLm1pbk5vdFplcm8pO1xyXG5cdFx0XHRvZmZzZXQgPSB2YWx1ZU9yRGVmYXVsdCRiKG1lLm9wdGlvbnMudGlja3MuZm9udFNpemUsIGNvcmVfZGVmYXVsdHMuZ2xvYmFsLmRlZmF1bHRGb250U2l6ZSkgLyBtZS5fbGVuZ3RoO1xyXG5cdFx0fVxyXG5cclxuXHRcdG1lLl9zdGFydFZhbHVlID0gbG9nMTAoc3RhcnQpO1xyXG5cdFx0bWUuX3ZhbHVlT2Zmc2V0ID0gb2Zmc2V0O1xyXG5cdFx0bWUuX3ZhbHVlUmFuZ2UgPSAobG9nMTAobWUubWF4KSAtIGxvZzEwKHN0YXJ0KSkgLyAoMSAtIG9mZnNldCk7XHJcblx0fSxcclxuXHJcblx0Z2V0UGl4ZWxGb3JWYWx1ZTogZnVuY3Rpb24odmFsdWUpIHtcclxuXHRcdHZhciBtZSA9IHRoaXM7XHJcblx0XHR2YXIgZGVjaW1hbCA9IDA7XHJcblxyXG5cdFx0dmFsdWUgPSArbWUuZ2V0UmlnaHRWYWx1ZSh2YWx1ZSk7XHJcblxyXG5cdFx0aWYgKHZhbHVlID4gbWUubWluICYmIHZhbHVlID4gMCkge1xyXG5cdFx0XHRkZWNpbWFsID0gKGxvZzEwKHZhbHVlKSAtIG1lLl9zdGFydFZhbHVlKSAvIG1lLl92YWx1ZVJhbmdlICsgbWUuX3ZhbHVlT2Zmc2V0O1xyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIG1lLmdldFBpeGVsRm9yRGVjaW1hbChkZWNpbWFsKTtcclxuXHR9LFxyXG5cclxuXHRnZXRWYWx1ZUZvclBpeGVsOiBmdW5jdGlvbihwaXhlbCkge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHRcdHZhciBkZWNpbWFsID0gbWUuZ2V0RGVjaW1hbEZvclBpeGVsKHBpeGVsKTtcclxuXHRcdHJldHVybiBkZWNpbWFsID09PSAwICYmIG1lLm1pbiA9PT0gMFxyXG5cdFx0XHQ/IDBcclxuXHRcdFx0OiBNYXRoLnBvdygxMCwgbWUuX3N0YXJ0VmFsdWUgKyAoZGVjaW1hbCAtIG1lLl92YWx1ZU9mZnNldCkgKiBtZS5fdmFsdWVSYW5nZSk7XHJcblx0fVxyXG59KTtcclxuXHJcbi8vIElOVEVSTkFMOiBzdGF0aWMgZGVmYXVsdCBvcHRpb25zLCByZWdpc3RlcmVkIGluIHNyYy9pbmRleC5qc1xyXG52YXIgX2RlZmF1bHRzJDIgPSBkZWZhdWx0Q29uZmlnJDI7XG5zY2FsZV9sb2dhcml0aG1pYy5fZGVmYXVsdHMgPSBfZGVmYXVsdHMkMjtcblxudmFyIHZhbHVlT3JEZWZhdWx0JGMgPSBoZWxwZXJzJDEudmFsdWVPckRlZmF1bHQ7XHJcbnZhciB2YWx1ZUF0SW5kZXhPckRlZmF1bHQkMSA9IGhlbHBlcnMkMS52YWx1ZUF0SW5kZXhPckRlZmF1bHQ7XHJcbnZhciByZXNvbHZlJDQgPSBoZWxwZXJzJDEub3B0aW9ucy5yZXNvbHZlO1xyXG5cclxudmFyIGRlZmF1bHRDb25maWckMyA9IHtcclxuXHRkaXNwbGF5OiB0cnVlLFxyXG5cclxuXHQvLyBCb29sZWFuIC0gV2hldGhlciB0byBhbmltYXRlIHNjYWxpbmcgdGhlIGNoYXJ0IGZyb20gdGhlIGNlbnRyZVxyXG5cdGFuaW1hdGU6IHRydWUsXHJcblx0cG9zaXRpb246ICdjaGFydEFyZWEnLFxyXG5cclxuXHRhbmdsZUxpbmVzOiB7XHJcblx0XHRkaXNwbGF5OiB0cnVlLFxyXG5cdFx0Y29sb3I6ICdyZ2JhKDAsMCwwLDAuMSknLFxyXG5cdFx0bGluZVdpZHRoOiAxLFxyXG5cdFx0Ym9yZGVyRGFzaDogW10sXHJcblx0XHRib3JkZXJEYXNoT2Zmc2V0OiAwLjBcclxuXHR9LFxyXG5cclxuXHRncmlkTGluZXM6IHtcclxuXHRcdGNpcmN1bGFyOiBmYWxzZVxyXG5cdH0sXHJcblxyXG5cdC8vIGxhYmVsIHNldHRpbmdzXHJcblx0dGlja3M6IHtcclxuXHRcdC8vIEJvb2xlYW4gLSBTaG93IGEgYmFja2Ryb3AgdG8gdGhlIHNjYWxlIGxhYmVsXHJcblx0XHRzaG93TGFiZWxCYWNrZHJvcDogdHJ1ZSxcclxuXHJcblx0XHQvLyBTdHJpbmcgLSBUaGUgY29sb3VyIG9mIHRoZSBsYWJlbCBiYWNrZHJvcFxyXG5cdFx0YmFja2Ryb3BDb2xvcjogJ3JnYmEoMjU1LDI1NSwyNTUsMC43NSknLFxyXG5cclxuXHRcdC8vIE51bWJlciAtIFRoZSBiYWNrZHJvcCBwYWRkaW5nIGFib3ZlICYgYmVsb3cgdGhlIGxhYmVsIGluIHBpeGVsc1xyXG5cdFx0YmFja2Ryb3BQYWRkaW5nWTogMixcclxuXHJcblx0XHQvLyBOdW1iZXIgLSBUaGUgYmFja2Ryb3AgcGFkZGluZyB0byB0aGUgc2lkZSBvZiB0aGUgbGFiZWwgaW4gcGl4ZWxzXHJcblx0XHRiYWNrZHJvcFBhZGRpbmdYOiAyLFxyXG5cclxuXHRcdGNhbGxiYWNrOiBjb3JlX3RpY2tzLmZvcm1hdHRlcnMubGluZWFyXHJcblx0fSxcclxuXHJcblx0cG9pbnRMYWJlbHM6IHtcclxuXHRcdC8vIEJvb2xlYW4gLSBpZiB0cnVlLCBzaG93IHBvaW50IGxhYmVsc1xyXG5cdFx0ZGlzcGxheTogdHJ1ZSxcclxuXHJcblx0XHQvLyBOdW1iZXIgLSBQb2ludCBsYWJlbCBmb250IHNpemUgaW4gcGl4ZWxzXHJcblx0XHRmb250U2l6ZTogMTAsXHJcblxyXG5cdFx0Ly8gRnVuY3Rpb24gLSBVc2VkIHRvIGNvbnZlcnQgcG9pbnQgbGFiZWxzXHJcblx0XHRjYWxsYmFjazogZnVuY3Rpb24obGFiZWwpIHtcclxuXHRcdFx0cmV0dXJuIGxhYmVsO1xyXG5cdFx0fVxyXG5cdH1cclxufTtcclxuXHJcbmZ1bmN0aW9uIGdldFRpY2tCYWNrZHJvcEhlaWdodChvcHRzKSB7XHJcblx0dmFyIHRpY2tPcHRzID0gb3B0cy50aWNrcztcclxuXHJcblx0aWYgKHRpY2tPcHRzLmRpc3BsYXkgJiYgb3B0cy5kaXNwbGF5KSB7XHJcblx0XHRyZXR1cm4gdmFsdWVPckRlZmF1bHQkYyh0aWNrT3B0cy5mb250U2l6ZSwgY29yZV9kZWZhdWx0cy5nbG9iYWwuZGVmYXVsdEZvbnRTaXplKSArIHRpY2tPcHRzLmJhY2tkcm9wUGFkZGluZ1kgKiAyO1xyXG5cdH1cclxuXHRyZXR1cm4gMDtcclxufVxyXG5cclxuZnVuY3Rpb24gbWVhc3VyZUxhYmVsU2l6ZShjdHgsIGxpbmVIZWlnaHQsIGxhYmVsKSB7XHJcblx0aWYgKGhlbHBlcnMkMS5pc0FycmF5KGxhYmVsKSkge1xyXG5cdFx0cmV0dXJuIHtcclxuXHRcdFx0dzogaGVscGVycyQxLmxvbmdlc3RUZXh0KGN0eCwgY3R4LmZvbnQsIGxhYmVsKSxcclxuXHRcdFx0aDogbGFiZWwubGVuZ3RoICogbGluZUhlaWdodFxyXG5cdFx0fTtcclxuXHR9XHJcblxyXG5cdHJldHVybiB7XHJcblx0XHR3OiBjdHgubWVhc3VyZVRleHQobGFiZWwpLndpZHRoLFxyXG5cdFx0aDogbGluZUhlaWdodFxyXG5cdH07XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGRldGVybWluZUxpbWl0cyhhbmdsZSwgcG9zLCBzaXplLCBtaW4sIG1heCkge1xyXG5cdGlmIChhbmdsZSA9PT0gbWluIHx8IGFuZ2xlID09PSBtYXgpIHtcclxuXHRcdHJldHVybiB7XHJcblx0XHRcdHN0YXJ0OiBwb3MgLSAoc2l6ZSAvIDIpLFxyXG5cdFx0XHRlbmQ6IHBvcyArIChzaXplIC8gMilcclxuXHRcdH07XHJcblx0fSBlbHNlIGlmIChhbmdsZSA8IG1pbiB8fCBhbmdsZSA+IG1heCkge1xyXG5cdFx0cmV0dXJuIHtcclxuXHRcdFx0c3RhcnQ6IHBvcyAtIHNpemUsXHJcblx0XHRcdGVuZDogcG9zXHJcblx0XHR9O1xyXG5cdH1cclxuXHJcblx0cmV0dXJuIHtcclxuXHRcdHN0YXJ0OiBwb3MsXHJcblx0XHRlbmQ6IHBvcyArIHNpemVcclxuXHR9O1xyXG59XHJcblxyXG4vKipcclxuICogSGVscGVyIGZ1bmN0aW9uIHRvIGZpdCBhIHJhZGlhbCBsaW5lYXIgc2NhbGUgd2l0aCBwb2ludCBsYWJlbHNcclxuICovXHJcbmZ1bmN0aW9uIGZpdFdpdGhQb2ludExhYmVscyhzY2FsZSkge1xyXG5cclxuXHQvLyBSaWdodCwgdGhpcyBpcyByZWFsbHkgY29uZnVzaW5nIGFuZCB0aGVyZSBpcyBhIGxvdCBvZiBtYXRocyBnb2luZyBvbiBoZXJlXHJcblx0Ly8gVGhlIGdpc3Qgb2YgdGhlIHByb2JsZW0gaXMgaGVyZTogaHR0cHM6Ly9naXN0LmdpdGh1Yi5jb20vbm5uaWNrLzY5NmNjOWM1NWY0YjBiZWI4ZmU5XHJcblx0Ly9cclxuXHQvLyBSZWFjdGlvbjogaHR0cHM6Ly9kbC5kcm9wYm94dXNlcmNvbnRlbnQuY29tL3UvMzQ2MDEzNjMvdG9vbXVjaHNjaWVuY2UuZ2lmXHJcblx0Ly9cclxuXHQvLyBTb2x1dGlvbjpcclxuXHQvL1xyXG5cdC8vIFdlIGFzc3VtZSB0aGUgcmFkaXVzIG9mIHRoZSBwb2x5Z29uIGlzIGhhbGYgdGhlIHNpemUgb2YgdGhlIGNhbnZhcyBhdCBmaXJzdFxyXG5cdC8vIGF0IGVhY2ggaW5kZXggd2UgY2hlY2sgaWYgdGhlIHRleHQgb3ZlcmxhcHMuXHJcblx0Ly9cclxuXHQvLyBXaGVyZSBpdCBkb2VzLCB3ZSBzdG9yZSB0aGF0IGFuZ2xlIGFuZCB0aGF0IGluZGV4LlxyXG5cdC8vXHJcblx0Ly8gQWZ0ZXIgZmluZGluZyB0aGUgbGFyZ2VzdCBpbmRleCBhbmQgYW5nbGUgd2UgY2FsY3VsYXRlIGhvdyBtdWNoIHdlIG5lZWQgdG8gcmVtb3ZlXHJcblx0Ly8gZnJvbSB0aGUgc2hhcGUgcmFkaXVzIHRvIG1vdmUgdGhlIHBvaW50IGlud2FyZHMgYnkgdGhhdCB4LlxyXG5cdC8vXHJcblx0Ly8gV2UgYXZlcmFnZSB0aGUgbGVmdCBhbmQgcmlnaHQgZGlzdGFuY2VzIHRvIGdldCB0aGUgbWF4aW11bSBzaGFwZSByYWRpdXMgdGhhdCBjYW4gZml0IGluIHRoZSBib3hcclxuXHQvLyBhbG9uZyB3aXRoIGxhYmVscy5cclxuXHQvL1xyXG5cdC8vIE9uY2Ugd2UgaGF2ZSB0aGF0LCB3ZSBjYW4gZmluZCB0aGUgY2VudHJlIHBvaW50IGZvciB0aGUgY2hhcnQsIGJ5IHRha2luZyB0aGUgeCB0ZXh0IHByb3RydXNpb25cclxuXHQvLyBvbiBlYWNoIHNpZGUsIHJlbW92aW5nIHRoYXQgZnJvbSB0aGUgc2l6ZSwgaGFsdmluZyBpdCBhbmQgYWRkaW5nIHRoZSBsZWZ0IHggcHJvdHJ1c2lvbiB3aWR0aC5cclxuXHQvL1xyXG5cdC8vIFRoaXMgd2lsbCBtZWFuIHdlIGhhdmUgYSBzaGFwZSBmaXR0ZWQgdG8gdGhlIGNhbnZhcywgYXMgbGFyZ2UgYXMgaXQgY2FuIGJlIHdpdGggdGhlIGxhYmVsc1xyXG5cdC8vIGFuZCBwb3NpdGlvbiBpdCBpbiB0aGUgbW9zdCBzcGFjZSBlZmZpY2llbnQgbWFubmVyXHJcblx0Ly9cclxuXHQvLyBodHRwczovL2RsLmRyb3Bib3h1c2VyY29udGVudC5jb20vdS8zNDYwMTM2My95ZWFoc2NpZW5jZS5naWZcclxuXHJcblx0dmFyIHBsRm9udCA9IGhlbHBlcnMkMS5vcHRpb25zLl9wYXJzZUZvbnQoc2NhbGUub3B0aW9ucy5wb2ludExhYmVscyk7XHJcblxyXG5cdC8vIEdldCBtYXhpbXVtIHJhZGl1cyBvZiB0aGUgcG9seWdvbi4gRWl0aGVyIGhhbGYgdGhlIGhlaWdodCAobWludXMgdGhlIHRleHQgd2lkdGgpIG9yIGhhbGYgdGhlIHdpZHRoLlxyXG5cdC8vIFVzZSB0aGlzIHRvIGNhbGN1bGF0ZSB0aGUgb2Zmc2V0ICsgY2hhbmdlLiAtIE1ha2Ugc3VyZSBML1IgcHJvdHJ1c2lvbiBpcyBhdCBsZWFzdCAwIHRvIHN0b3AgaXNzdWVzIHdpdGggY2VudHJlIHBvaW50c1xyXG5cdHZhciBmdXJ0aGVzdExpbWl0cyA9IHtcclxuXHRcdGw6IDAsXHJcblx0XHRyOiBzY2FsZS53aWR0aCxcclxuXHRcdHQ6IDAsXHJcblx0XHRiOiBzY2FsZS5oZWlnaHQgLSBzY2FsZS5wYWRkaW5nVG9wXHJcblx0fTtcclxuXHR2YXIgZnVydGhlc3RBbmdsZXMgPSB7fTtcclxuXHR2YXIgaSwgdGV4dFNpemUsIHBvaW50UG9zaXRpb247XHJcblxyXG5cdHNjYWxlLmN0eC5mb250ID0gcGxGb250LnN0cmluZztcclxuXHRzY2FsZS5fcG9pbnRMYWJlbFNpemVzID0gW107XHJcblxyXG5cdHZhciB2YWx1ZUNvdW50ID0gc2NhbGUuY2hhcnQuZGF0YS5sYWJlbHMubGVuZ3RoO1xyXG5cdGZvciAoaSA9IDA7IGkgPCB2YWx1ZUNvdW50OyBpKyspIHtcclxuXHRcdHBvaW50UG9zaXRpb24gPSBzY2FsZS5nZXRQb2ludFBvc2l0aW9uKGksIHNjYWxlLmRyYXdpbmdBcmVhICsgNSk7XHJcblx0XHR0ZXh0U2l6ZSA9IG1lYXN1cmVMYWJlbFNpemUoc2NhbGUuY3R4LCBwbEZvbnQubGluZUhlaWdodCwgc2NhbGUucG9pbnRMYWJlbHNbaV0pO1xyXG5cdFx0c2NhbGUuX3BvaW50TGFiZWxTaXplc1tpXSA9IHRleHRTaXplO1xyXG5cclxuXHRcdC8vIEFkZCBxdWFydGVyIGNpcmNsZSB0byBtYWtlIGRlZ3JlZSAwIG1lYW4gdG9wIG9mIGNpcmNsZVxyXG5cdFx0dmFyIGFuZ2xlUmFkaWFucyA9IHNjYWxlLmdldEluZGV4QW5nbGUoaSk7XHJcblx0XHR2YXIgYW5nbGUgPSBoZWxwZXJzJDEudG9EZWdyZWVzKGFuZ2xlUmFkaWFucykgJSAzNjA7XHJcblx0XHR2YXIgaExpbWl0cyA9IGRldGVybWluZUxpbWl0cyhhbmdsZSwgcG9pbnRQb3NpdGlvbi54LCB0ZXh0U2l6ZS53LCAwLCAxODApO1xyXG5cdFx0dmFyIHZMaW1pdHMgPSBkZXRlcm1pbmVMaW1pdHMoYW5nbGUsIHBvaW50UG9zaXRpb24ueSwgdGV4dFNpemUuaCwgOTAsIDI3MCk7XHJcblxyXG5cdFx0aWYgKGhMaW1pdHMuc3RhcnQgPCBmdXJ0aGVzdExpbWl0cy5sKSB7XHJcblx0XHRcdGZ1cnRoZXN0TGltaXRzLmwgPSBoTGltaXRzLnN0YXJ0O1xyXG5cdFx0XHRmdXJ0aGVzdEFuZ2xlcy5sID0gYW5nbGVSYWRpYW5zO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmIChoTGltaXRzLmVuZCA+IGZ1cnRoZXN0TGltaXRzLnIpIHtcclxuXHRcdFx0ZnVydGhlc3RMaW1pdHMuciA9IGhMaW1pdHMuZW5kO1xyXG5cdFx0XHRmdXJ0aGVzdEFuZ2xlcy5yID0gYW5nbGVSYWRpYW5zO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmICh2TGltaXRzLnN0YXJ0IDwgZnVydGhlc3RMaW1pdHMudCkge1xyXG5cdFx0XHRmdXJ0aGVzdExpbWl0cy50ID0gdkxpbWl0cy5zdGFydDtcclxuXHRcdFx0ZnVydGhlc3RBbmdsZXMudCA9IGFuZ2xlUmFkaWFucztcclxuXHRcdH1cclxuXHJcblx0XHRpZiAodkxpbWl0cy5lbmQgPiBmdXJ0aGVzdExpbWl0cy5iKSB7XHJcblx0XHRcdGZ1cnRoZXN0TGltaXRzLmIgPSB2TGltaXRzLmVuZDtcclxuXHRcdFx0ZnVydGhlc3RBbmdsZXMuYiA9IGFuZ2xlUmFkaWFucztcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdHNjYWxlLnNldFJlZHVjdGlvbnMoc2NhbGUuZHJhd2luZ0FyZWEsIGZ1cnRoZXN0TGltaXRzLCBmdXJ0aGVzdEFuZ2xlcyk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGdldFRleHRBbGlnbkZvckFuZ2xlKGFuZ2xlKSB7XHJcblx0aWYgKGFuZ2xlID09PSAwIHx8IGFuZ2xlID09PSAxODApIHtcclxuXHRcdHJldHVybiAnY2VudGVyJztcclxuXHR9IGVsc2UgaWYgKGFuZ2xlIDwgMTgwKSB7XHJcblx0XHRyZXR1cm4gJ2xlZnQnO1xyXG5cdH1cclxuXHJcblx0cmV0dXJuICdyaWdodCc7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGZpbGxUZXh0KGN0eCwgdGV4dCwgcG9zaXRpb24sIGxpbmVIZWlnaHQpIHtcclxuXHR2YXIgeSA9IHBvc2l0aW9uLnkgKyBsaW5lSGVpZ2h0IC8gMjtcclxuXHR2YXIgaSwgaWxlbjtcclxuXHJcblx0aWYgKGhlbHBlcnMkMS5pc0FycmF5KHRleHQpKSB7XHJcblx0XHRmb3IgKGkgPSAwLCBpbGVuID0gdGV4dC5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcclxuXHRcdFx0Y3R4LmZpbGxUZXh0KHRleHRbaV0sIHBvc2l0aW9uLngsIHkpO1xyXG5cdFx0XHR5ICs9IGxpbmVIZWlnaHQ7XHJcblx0XHR9XHJcblx0fSBlbHNlIHtcclxuXHRcdGN0eC5maWxsVGV4dCh0ZXh0LCBwb3NpdGlvbi54LCB5KTtcclxuXHR9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGFkanVzdFBvaW50UG9zaXRpb25Gb3JMYWJlbEhlaWdodChhbmdsZSwgdGV4dFNpemUsIHBvc2l0aW9uKSB7XHJcblx0aWYgKGFuZ2xlID09PSA5MCB8fCBhbmdsZSA9PT0gMjcwKSB7XHJcblx0XHRwb3NpdGlvbi55IC09ICh0ZXh0U2l6ZS5oIC8gMik7XHJcblx0fSBlbHNlIGlmIChhbmdsZSA+IDI3MCB8fCBhbmdsZSA8IDkwKSB7XHJcblx0XHRwb3NpdGlvbi55IC09IHRleHRTaXplLmg7XHJcblx0fVxyXG59XHJcblxyXG5mdW5jdGlvbiBkcmF3UG9pbnRMYWJlbHMoc2NhbGUpIHtcclxuXHR2YXIgY3R4ID0gc2NhbGUuY3R4O1xyXG5cdHZhciBvcHRzID0gc2NhbGUub3B0aW9ucztcclxuXHR2YXIgcG9pbnRMYWJlbE9wdHMgPSBvcHRzLnBvaW50TGFiZWxzO1xyXG5cdHZhciB0aWNrQmFja2Ryb3BIZWlnaHQgPSBnZXRUaWNrQmFja2Ryb3BIZWlnaHQob3B0cyk7XHJcblx0dmFyIG91dGVyRGlzdGFuY2UgPSBzY2FsZS5nZXREaXN0YW5jZUZyb21DZW50ZXJGb3JWYWx1ZShvcHRzLnRpY2tzLnJldmVyc2UgPyBzY2FsZS5taW4gOiBzY2FsZS5tYXgpO1xyXG5cdHZhciBwbEZvbnQgPSBoZWxwZXJzJDEub3B0aW9ucy5fcGFyc2VGb250KHBvaW50TGFiZWxPcHRzKTtcclxuXHJcblx0Y3R4LnNhdmUoKTtcclxuXHJcblx0Y3R4LmZvbnQgPSBwbEZvbnQuc3RyaW5nO1xyXG5cdGN0eC50ZXh0QmFzZWxpbmUgPSAnbWlkZGxlJztcclxuXHJcblx0Zm9yICh2YXIgaSA9IHNjYWxlLmNoYXJ0LmRhdGEubGFiZWxzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XHJcblx0XHQvLyBFeHRyYSBwaXhlbHMgb3V0IGZvciBzb21lIGxhYmVsIHNwYWNpbmdcclxuXHRcdHZhciBleHRyYSA9IChpID09PSAwID8gdGlja0JhY2tkcm9wSGVpZ2h0IC8gMiA6IDApO1xyXG5cdFx0dmFyIHBvaW50TGFiZWxQb3NpdGlvbiA9IHNjYWxlLmdldFBvaW50UG9zaXRpb24oaSwgb3V0ZXJEaXN0YW5jZSArIGV4dHJhICsgNSk7XHJcblxyXG5cdFx0Ly8gS2VlcCB0aGlzIGluIGxvb3Agc2luY2Ugd2UgbWF5IHN1cHBvcnQgYXJyYXkgcHJvcGVydGllcyBoZXJlXHJcblx0XHR2YXIgcG9pbnRMYWJlbEZvbnRDb2xvciA9IHZhbHVlQXRJbmRleE9yRGVmYXVsdCQxKHBvaW50TGFiZWxPcHRzLmZvbnRDb2xvciwgaSwgY29yZV9kZWZhdWx0cy5nbG9iYWwuZGVmYXVsdEZvbnRDb2xvcik7XHJcblx0XHRjdHguZmlsbFN0eWxlID0gcG9pbnRMYWJlbEZvbnRDb2xvcjtcclxuXHJcblx0XHR2YXIgYW5nbGVSYWRpYW5zID0gc2NhbGUuZ2V0SW5kZXhBbmdsZShpKTtcclxuXHRcdHZhciBhbmdsZSA9IGhlbHBlcnMkMS50b0RlZ3JlZXMoYW5nbGVSYWRpYW5zKTtcclxuXHRcdGN0eC50ZXh0QWxpZ24gPSBnZXRUZXh0QWxpZ25Gb3JBbmdsZShhbmdsZSk7XHJcblx0XHRhZGp1c3RQb2ludFBvc2l0aW9uRm9yTGFiZWxIZWlnaHQoYW5nbGUsIHNjYWxlLl9wb2ludExhYmVsU2l6ZXNbaV0sIHBvaW50TGFiZWxQb3NpdGlvbik7XHJcblx0XHRmaWxsVGV4dChjdHgsIHNjYWxlLnBvaW50TGFiZWxzW2ldLCBwb2ludExhYmVsUG9zaXRpb24sIHBsRm9udC5saW5lSGVpZ2h0KTtcclxuXHR9XHJcblx0Y3R4LnJlc3RvcmUoKTtcclxufVxyXG5cclxuZnVuY3Rpb24gZHJhd1JhZGl1c0xpbmUoc2NhbGUsIGdyaWRMaW5lT3B0cywgcmFkaXVzLCBpbmRleCkge1xyXG5cdHZhciBjdHggPSBzY2FsZS5jdHg7XHJcblx0dmFyIGNpcmN1bGFyID0gZ3JpZExpbmVPcHRzLmNpcmN1bGFyO1xyXG5cdHZhciB2YWx1ZUNvdW50ID0gc2NhbGUuY2hhcnQuZGF0YS5sYWJlbHMubGVuZ3RoO1xyXG5cdHZhciBsaW5lQ29sb3IgPSB2YWx1ZUF0SW5kZXhPckRlZmF1bHQkMShncmlkTGluZU9wdHMuY29sb3IsIGluZGV4IC0gMSk7XHJcblx0dmFyIGxpbmVXaWR0aCA9IHZhbHVlQXRJbmRleE9yRGVmYXVsdCQxKGdyaWRMaW5lT3B0cy5saW5lV2lkdGgsIGluZGV4IC0gMSk7XHJcblx0dmFyIHBvaW50UG9zaXRpb247XHJcblxyXG5cdGlmICgoIWNpcmN1bGFyICYmICF2YWx1ZUNvdW50KSB8fCAhbGluZUNvbG9yIHx8ICFsaW5lV2lkdGgpIHtcclxuXHRcdHJldHVybjtcclxuXHR9XHJcblxyXG5cdGN0eC5zYXZlKCk7XHJcblx0Y3R4LnN0cm9rZVN0eWxlID0gbGluZUNvbG9yO1xyXG5cdGN0eC5saW5lV2lkdGggPSBsaW5lV2lkdGg7XHJcblx0aWYgKGN0eC5zZXRMaW5lRGFzaCkge1xyXG5cdFx0Y3R4LnNldExpbmVEYXNoKGdyaWRMaW5lT3B0cy5ib3JkZXJEYXNoIHx8IFtdKTtcclxuXHRcdGN0eC5saW5lRGFzaE9mZnNldCA9IGdyaWRMaW5lT3B0cy5ib3JkZXJEYXNoT2Zmc2V0IHx8IDAuMDtcclxuXHR9XHJcblxyXG5cdGN0eC5iZWdpblBhdGgoKTtcclxuXHRpZiAoY2lyY3VsYXIpIHtcclxuXHRcdC8vIERyYXcgY2lyY3VsYXIgYXJjcyBiZXR3ZWVuIHRoZSBwb2ludHNcclxuXHRcdGN0eC5hcmMoc2NhbGUueENlbnRlciwgc2NhbGUueUNlbnRlciwgcmFkaXVzLCAwLCBNYXRoLlBJICogMik7XHJcblx0fSBlbHNlIHtcclxuXHRcdC8vIERyYXcgc3RyYWlnaHQgbGluZXMgY29ubmVjdGluZyBlYWNoIGluZGV4XHJcblx0XHRwb2ludFBvc2l0aW9uID0gc2NhbGUuZ2V0UG9pbnRQb3NpdGlvbigwLCByYWRpdXMpO1xyXG5cdFx0Y3R4Lm1vdmVUbyhwb2ludFBvc2l0aW9uLngsIHBvaW50UG9zaXRpb24ueSk7XHJcblxyXG5cdFx0Zm9yICh2YXIgaSA9IDE7IGkgPCB2YWx1ZUNvdW50OyBpKyspIHtcclxuXHRcdFx0cG9pbnRQb3NpdGlvbiA9IHNjYWxlLmdldFBvaW50UG9zaXRpb24oaSwgcmFkaXVzKTtcclxuXHRcdFx0Y3R4LmxpbmVUbyhwb2ludFBvc2l0aW9uLngsIHBvaW50UG9zaXRpb24ueSk7XHJcblx0XHR9XHJcblx0fVxyXG5cdGN0eC5jbG9zZVBhdGgoKTtcclxuXHRjdHguc3Ryb2tlKCk7XHJcblx0Y3R4LnJlc3RvcmUoKTtcclxufVxyXG5cclxuZnVuY3Rpb24gbnVtYmVyT3JaZXJvKHBhcmFtKSB7XHJcblx0cmV0dXJuIGhlbHBlcnMkMS5pc051bWJlcihwYXJhbSkgPyBwYXJhbSA6IDA7XHJcbn1cclxuXHJcbnZhciBzY2FsZV9yYWRpYWxMaW5lYXIgPSBzY2FsZV9saW5lYXJiYXNlLmV4dGVuZCh7XHJcblx0c2V0RGltZW5zaW9uczogZnVuY3Rpb24oKSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cclxuXHRcdC8vIFNldCB0aGUgdW5jb25zdHJhaW5lZCBkaW1lbnNpb24gYmVmb3JlIGxhYmVsIHJvdGF0aW9uXHJcblx0XHRtZS53aWR0aCA9IG1lLm1heFdpZHRoO1xyXG5cdFx0bWUuaGVpZ2h0ID0gbWUubWF4SGVpZ2h0O1xyXG5cdFx0bWUucGFkZGluZ1RvcCA9IGdldFRpY2tCYWNrZHJvcEhlaWdodChtZS5vcHRpb25zKSAvIDI7XHJcblx0XHRtZS54Q2VudGVyID0gTWF0aC5mbG9vcihtZS53aWR0aCAvIDIpO1xyXG5cdFx0bWUueUNlbnRlciA9IE1hdGguZmxvb3IoKG1lLmhlaWdodCAtIG1lLnBhZGRpbmdUb3ApIC8gMik7XHJcblx0XHRtZS5kcmF3aW5nQXJlYSA9IE1hdGgubWluKG1lLmhlaWdodCAtIG1lLnBhZGRpbmdUb3AsIG1lLndpZHRoKSAvIDI7XHJcblx0fSxcclxuXHJcblx0ZGV0ZXJtaW5lRGF0YUxpbWl0czogZnVuY3Rpb24oKSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0dmFyIGNoYXJ0ID0gbWUuY2hhcnQ7XHJcblx0XHR2YXIgbWluID0gTnVtYmVyLlBPU0lUSVZFX0lORklOSVRZO1xyXG5cdFx0dmFyIG1heCA9IE51bWJlci5ORUdBVElWRV9JTkZJTklUWTtcclxuXHJcblx0XHRoZWxwZXJzJDEuZWFjaChjaGFydC5kYXRhLmRhdGFzZXRzLCBmdW5jdGlvbihkYXRhc2V0LCBkYXRhc2V0SW5kZXgpIHtcclxuXHRcdFx0aWYgKGNoYXJ0LmlzRGF0YXNldFZpc2libGUoZGF0YXNldEluZGV4KSkge1xyXG5cdFx0XHRcdHZhciBtZXRhID0gY2hhcnQuZ2V0RGF0YXNldE1ldGEoZGF0YXNldEluZGV4KTtcclxuXHJcblx0XHRcdFx0aGVscGVycyQxLmVhY2goZGF0YXNldC5kYXRhLCBmdW5jdGlvbihyYXdWYWx1ZSwgaW5kZXgpIHtcclxuXHRcdFx0XHRcdHZhciB2YWx1ZSA9ICttZS5nZXRSaWdodFZhbHVlKHJhd1ZhbHVlKTtcclxuXHRcdFx0XHRcdGlmIChpc05hTih2YWx1ZSkgfHwgbWV0YS5kYXRhW2luZGV4XS5oaWRkZW4pIHtcclxuXHRcdFx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRcdG1pbiA9IE1hdGgubWluKHZhbHVlLCBtaW4pO1xyXG5cdFx0XHRcdFx0bWF4ID0gTWF0aC5tYXgodmFsdWUsIG1heCk7XHJcblx0XHRcdFx0fSk7XHJcblx0XHRcdH1cclxuXHRcdH0pO1xyXG5cclxuXHRcdG1lLm1pbiA9IChtaW4gPT09IE51bWJlci5QT1NJVElWRV9JTkZJTklUWSA/IDAgOiBtaW4pO1xyXG5cdFx0bWUubWF4ID0gKG1heCA9PT0gTnVtYmVyLk5FR0FUSVZFX0lORklOSVRZID8gMCA6IG1heCk7XHJcblxyXG5cdFx0Ly8gQ29tbW9uIGJhc2UgaW1wbGVtZW50YXRpb24gdG8gaGFuZGxlIHRpY2tzLm1pbiwgdGlja3MubWF4LCB0aWNrcy5iZWdpbkF0WmVyb1xyXG5cdFx0bWUuaGFuZGxlVGlja1JhbmdlT3B0aW9ucygpO1xyXG5cdH0sXHJcblxyXG5cdC8vIFJldHVybnMgdGhlIG1heGltdW0gbnVtYmVyIG9mIHRpY2tzIGJhc2VkIG9uIHRoZSBzY2FsZSBkaW1lbnNpb25cclxuXHRfY29tcHV0ZVRpY2tMaW1pdDogZnVuY3Rpb24oKSB7XHJcblx0XHRyZXR1cm4gTWF0aC5jZWlsKHRoaXMuZHJhd2luZ0FyZWEgLyBnZXRUaWNrQmFja2Ryb3BIZWlnaHQodGhpcy5vcHRpb25zKSk7XHJcblx0fSxcclxuXHJcblx0Y29udmVydFRpY2tzVG9MYWJlbHM6IGZ1bmN0aW9uKCkge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHJcblx0XHRzY2FsZV9saW5lYXJiYXNlLnByb3RvdHlwZS5jb252ZXJ0VGlja3NUb0xhYmVscy5jYWxsKG1lKTtcclxuXHJcblx0XHQvLyBQb2ludCBsYWJlbHNcclxuXHRcdG1lLnBvaW50TGFiZWxzID0gbWUuY2hhcnQuZGF0YS5sYWJlbHMubWFwKGZ1bmN0aW9uKCkge1xyXG5cdFx0XHR2YXIgbGFiZWwgPSBoZWxwZXJzJDEuY2FsbGJhY2sobWUub3B0aW9ucy5wb2ludExhYmVscy5jYWxsYmFjaywgYXJndW1lbnRzLCBtZSk7XHJcblx0XHRcdHJldHVybiBsYWJlbCB8fCBsYWJlbCA9PT0gMCA/IGxhYmVsIDogJyc7XHJcblx0XHR9KTtcclxuXHR9LFxyXG5cclxuXHRnZXRMYWJlbEZvckluZGV4OiBmdW5jdGlvbihpbmRleCwgZGF0YXNldEluZGV4KSB7XHJcblx0XHRyZXR1cm4gK3RoaXMuZ2V0UmlnaHRWYWx1ZSh0aGlzLmNoYXJ0LmRhdGEuZGF0YXNldHNbZGF0YXNldEluZGV4XS5kYXRhW2luZGV4XSk7XHJcblx0fSxcclxuXHJcblx0Zml0OiBmdW5jdGlvbigpIHtcclxuXHRcdHZhciBtZSA9IHRoaXM7XHJcblx0XHR2YXIgb3B0cyA9IG1lLm9wdGlvbnM7XHJcblxyXG5cdFx0aWYgKG9wdHMuZGlzcGxheSAmJiBvcHRzLnBvaW50TGFiZWxzLmRpc3BsYXkpIHtcclxuXHRcdFx0Zml0V2l0aFBvaW50TGFiZWxzKG1lKTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdG1lLnNldENlbnRlclBvaW50KDAsIDAsIDAsIDApO1xyXG5cdFx0fVxyXG5cdH0sXHJcblxyXG5cdC8qKlxyXG5cdCAqIFNldCByYWRpdXMgcmVkdWN0aW9ucyBhbmQgZGV0ZXJtaW5lIG5ldyByYWRpdXMgYW5kIGNlbnRlciBwb2ludFxyXG5cdCAqIEBwcml2YXRlXHJcblx0ICovXHJcblx0c2V0UmVkdWN0aW9uczogZnVuY3Rpb24obGFyZ2VzdFBvc3NpYmxlUmFkaXVzLCBmdXJ0aGVzdExpbWl0cywgZnVydGhlc3RBbmdsZXMpIHtcclxuXHRcdHZhciBtZSA9IHRoaXM7XHJcblx0XHR2YXIgcmFkaXVzUmVkdWN0aW9uTGVmdCA9IGZ1cnRoZXN0TGltaXRzLmwgLyBNYXRoLnNpbihmdXJ0aGVzdEFuZ2xlcy5sKTtcclxuXHRcdHZhciByYWRpdXNSZWR1Y3Rpb25SaWdodCA9IE1hdGgubWF4KGZ1cnRoZXN0TGltaXRzLnIgLSBtZS53aWR0aCwgMCkgLyBNYXRoLnNpbihmdXJ0aGVzdEFuZ2xlcy5yKTtcclxuXHRcdHZhciByYWRpdXNSZWR1Y3Rpb25Ub3AgPSAtZnVydGhlc3RMaW1pdHMudCAvIE1hdGguY29zKGZ1cnRoZXN0QW5nbGVzLnQpO1xyXG5cdFx0dmFyIHJhZGl1c1JlZHVjdGlvbkJvdHRvbSA9IC1NYXRoLm1heChmdXJ0aGVzdExpbWl0cy5iIC0gKG1lLmhlaWdodCAtIG1lLnBhZGRpbmdUb3ApLCAwKSAvIE1hdGguY29zKGZ1cnRoZXN0QW5nbGVzLmIpO1xyXG5cclxuXHRcdHJhZGl1c1JlZHVjdGlvbkxlZnQgPSBudW1iZXJPclplcm8ocmFkaXVzUmVkdWN0aW9uTGVmdCk7XHJcblx0XHRyYWRpdXNSZWR1Y3Rpb25SaWdodCA9IG51bWJlck9yWmVybyhyYWRpdXNSZWR1Y3Rpb25SaWdodCk7XHJcblx0XHRyYWRpdXNSZWR1Y3Rpb25Ub3AgPSBudW1iZXJPclplcm8ocmFkaXVzUmVkdWN0aW9uVG9wKTtcclxuXHRcdHJhZGl1c1JlZHVjdGlvbkJvdHRvbSA9IG51bWJlck9yWmVybyhyYWRpdXNSZWR1Y3Rpb25Cb3R0b20pO1xyXG5cclxuXHRcdG1lLmRyYXdpbmdBcmVhID0gTWF0aC5taW4oXHJcblx0XHRcdE1hdGguZmxvb3IobGFyZ2VzdFBvc3NpYmxlUmFkaXVzIC0gKHJhZGl1c1JlZHVjdGlvbkxlZnQgKyByYWRpdXNSZWR1Y3Rpb25SaWdodCkgLyAyKSxcclxuXHRcdFx0TWF0aC5mbG9vcihsYXJnZXN0UG9zc2libGVSYWRpdXMgLSAocmFkaXVzUmVkdWN0aW9uVG9wICsgcmFkaXVzUmVkdWN0aW9uQm90dG9tKSAvIDIpKTtcclxuXHRcdG1lLnNldENlbnRlclBvaW50KHJhZGl1c1JlZHVjdGlvbkxlZnQsIHJhZGl1c1JlZHVjdGlvblJpZ2h0LCByYWRpdXNSZWR1Y3Rpb25Ub3AsIHJhZGl1c1JlZHVjdGlvbkJvdHRvbSk7XHJcblx0fSxcclxuXHJcblx0c2V0Q2VudGVyUG9pbnQ6IGZ1bmN0aW9uKGxlZnRNb3ZlbWVudCwgcmlnaHRNb3ZlbWVudCwgdG9wTW92ZW1lbnQsIGJvdHRvbU1vdmVtZW50KSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0dmFyIG1heFJpZ2h0ID0gbWUud2lkdGggLSByaWdodE1vdmVtZW50IC0gbWUuZHJhd2luZ0FyZWE7XHJcblx0XHR2YXIgbWF4TGVmdCA9IGxlZnRNb3ZlbWVudCArIG1lLmRyYXdpbmdBcmVhO1xyXG5cdFx0dmFyIG1heFRvcCA9IHRvcE1vdmVtZW50ICsgbWUuZHJhd2luZ0FyZWE7XHJcblx0XHR2YXIgbWF4Qm90dG9tID0gKG1lLmhlaWdodCAtIG1lLnBhZGRpbmdUb3ApIC0gYm90dG9tTW92ZW1lbnQgLSBtZS5kcmF3aW5nQXJlYTtcclxuXHJcblx0XHRtZS54Q2VudGVyID0gTWF0aC5mbG9vcigoKG1heExlZnQgKyBtYXhSaWdodCkgLyAyKSArIG1lLmxlZnQpO1xyXG5cdFx0bWUueUNlbnRlciA9IE1hdGguZmxvb3IoKChtYXhUb3AgKyBtYXhCb3R0b20pIC8gMikgKyBtZS50b3AgKyBtZS5wYWRkaW5nVG9wKTtcclxuXHR9LFxyXG5cclxuXHRnZXRJbmRleEFuZ2xlOiBmdW5jdGlvbihpbmRleCkge1xyXG5cdFx0dmFyIGNoYXJ0ID0gdGhpcy5jaGFydDtcclxuXHRcdHZhciBhbmdsZU11bHRpcGxpZXIgPSAzNjAgLyBjaGFydC5kYXRhLmxhYmVscy5sZW5ndGg7XHJcblx0XHR2YXIgb3B0aW9ucyA9IGNoYXJ0Lm9wdGlvbnMgfHwge307XHJcblx0XHR2YXIgc3RhcnRBbmdsZSA9IG9wdGlvbnMuc3RhcnRBbmdsZSB8fCAwO1xyXG5cclxuXHRcdC8vIFN0YXJ0IGZyb20gdGhlIHRvcCBpbnN0ZWFkIG9mIHJpZ2h0LCBzbyByZW1vdmUgYSBxdWFydGVyIG9mIHRoZSBjaXJjbGVcclxuXHRcdHZhciBhbmdsZSA9IChpbmRleCAqIGFuZ2xlTXVsdGlwbGllciArIHN0YXJ0QW5nbGUpICUgMzYwO1xyXG5cclxuXHRcdHJldHVybiAoYW5nbGUgPCAwID8gYW5nbGUgKyAzNjAgOiBhbmdsZSkgKiBNYXRoLlBJICogMiAvIDM2MDtcclxuXHR9LFxyXG5cclxuXHRnZXREaXN0YW5jZUZyb21DZW50ZXJGb3JWYWx1ZTogZnVuY3Rpb24odmFsdWUpIHtcclxuXHRcdHZhciBtZSA9IHRoaXM7XHJcblxyXG5cdFx0aWYgKGhlbHBlcnMkMS5pc051bGxPclVuZGVmKHZhbHVlKSkge1xyXG5cdFx0XHRyZXR1cm4gTmFOO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIFRha2UgaW50byBhY2NvdW50IGhhbGYgZm9udCBzaXplICsgdGhlIHlQYWRkaW5nIG9mIHRoZSB0b3AgdmFsdWVcclxuXHRcdHZhciBzY2FsaW5nRmFjdG9yID0gbWUuZHJhd2luZ0FyZWEgLyAobWUubWF4IC0gbWUubWluKTtcclxuXHRcdGlmIChtZS5vcHRpb25zLnRpY2tzLnJldmVyc2UpIHtcclxuXHRcdFx0cmV0dXJuIChtZS5tYXggLSB2YWx1ZSkgKiBzY2FsaW5nRmFjdG9yO1xyXG5cdFx0fVxyXG5cdFx0cmV0dXJuICh2YWx1ZSAtIG1lLm1pbikgKiBzY2FsaW5nRmFjdG9yO1xyXG5cdH0sXHJcblxyXG5cdGdldFBvaW50UG9zaXRpb246IGZ1bmN0aW9uKGluZGV4LCBkaXN0YW5jZUZyb21DZW50ZXIpIHtcclxuXHRcdHZhciBtZSA9IHRoaXM7XHJcblx0XHR2YXIgdGhpc0FuZ2xlID0gbWUuZ2V0SW5kZXhBbmdsZShpbmRleCkgLSAoTWF0aC5QSSAvIDIpO1xyXG5cdFx0cmV0dXJuIHtcclxuXHRcdFx0eDogTWF0aC5jb3ModGhpc0FuZ2xlKSAqIGRpc3RhbmNlRnJvbUNlbnRlciArIG1lLnhDZW50ZXIsXHJcblx0XHRcdHk6IE1hdGguc2luKHRoaXNBbmdsZSkgKiBkaXN0YW5jZUZyb21DZW50ZXIgKyBtZS55Q2VudGVyXHJcblx0XHR9O1xyXG5cdH0sXHJcblxyXG5cdGdldFBvaW50UG9zaXRpb25Gb3JWYWx1ZTogZnVuY3Rpb24oaW5kZXgsIHZhbHVlKSB7XHJcblx0XHRyZXR1cm4gdGhpcy5nZXRQb2ludFBvc2l0aW9uKGluZGV4LCB0aGlzLmdldERpc3RhbmNlRnJvbUNlbnRlckZvclZhbHVlKHZhbHVlKSk7XHJcblx0fSxcclxuXHJcblx0Z2V0QmFzZVBvc2l0aW9uOiBmdW5jdGlvbihpbmRleCkge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHRcdHZhciBtaW4gPSBtZS5taW47XHJcblx0XHR2YXIgbWF4ID0gbWUubWF4O1xyXG5cclxuXHRcdHJldHVybiBtZS5nZXRQb2ludFBvc2l0aW9uRm9yVmFsdWUoaW5kZXggfHwgMCxcclxuXHRcdFx0bWUuYmVnaW5BdFplcm8gPyAwIDpcclxuXHRcdFx0bWluIDwgMCAmJiBtYXggPCAwID8gbWF4IDpcclxuXHRcdFx0bWluID4gMCAmJiBtYXggPiAwID8gbWluIDpcclxuXHRcdFx0MCk7XHJcblx0fSxcclxuXHJcblx0LyoqXHJcblx0ICogQHByaXZhdGVcclxuXHQgKi9cclxuXHRfZHJhd0dyaWQ6IGZ1bmN0aW9uKCkge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHRcdHZhciBjdHggPSBtZS5jdHg7XHJcblx0XHR2YXIgb3B0cyA9IG1lLm9wdGlvbnM7XHJcblx0XHR2YXIgZ3JpZExpbmVPcHRzID0gb3B0cy5ncmlkTGluZXM7XHJcblx0XHR2YXIgYW5nbGVMaW5lT3B0cyA9IG9wdHMuYW5nbGVMaW5lcztcclxuXHRcdHZhciBsaW5lV2lkdGggPSB2YWx1ZU9yRGVmYXVsdCRjKGFuZ2xlTGluZU9wdHMubGluZVdpZHRoLCBncmlkTGluZU9wdHMubGluZVdpZHRoKTtcclxuXHRcdHZhciBsaW5lQ29sb3IgPSB2YWx1ZU9yRGVmYXVsdCRjKGFuZ2xlTGluZU9wdHMuY29sb3IsIGdyaWRMaW5lT3B0cy5jb2xvcik7XHJcblx0XHR2YXIgaSwgb2Zmc2V0LCBwb3NpdGlvbjtcclxuXHJcblx0XHRpZiAob3B0cy5wb2ludExhYmVscy5kaXNwbGF5KSB7XHJcblx0XHRcdGRyYXdQb2ludExhYmVscyhtZSk7XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKGdyaWRMaW5lT3B0cy5kaXNwbGF5KSB7XHJcblx0XHRcdGhlbHBlcnMkMS5lYWNoKG1lLnRpY2tzLCBmdW5jdGlvbihsYWJlbCwgaW5kZXgpIHtcclxuXHRcdFx0XHRpZiAoaW5kZXggIT09IDApIHtcclxuXHRcdFx0XHRcdG9mZnNldCA9IG1lLmdldERpc3RhbmNlRnJvbUNlbnRlckZvclZhbHVlKG1lLnRpY2tzQXNOdW1iZXJzW2luZGV4XSk7XHJcblx0XHRcdFx0XHRkcmF3UmFkaXVzTGluZShtZSwgZ3JpZExpbmVPcHRzLCBvZmZzZXQsIGluZGV4KTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH0pO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmIChhbmdsZUxpbmVPcHRzLmRpc3BsYXkgJiYgbGluZVdpZHRoICYmIGxpbmVDb2xvcikge1xyXG5cdFx0XHRjdHguc2F2ZSgpO1xyXG5cdFx0XHRjdHgubGluZVdpZHRoID0gbGluZVdpZHRoO1xyXG5cdFx0XHRjdHguc3Ryb2tlU3R5bGUgPSBsaW5lQ29sb3I7XHJcblx0XHRcdGlmIChjdHguc2V0TGluZURhc2gpIHtcclxuXHRcdFx0XHRjdHguc2V0TGluZURhc2gocmVzb2x2ZSQ0KFthbmdsZUxpbmVPcHRzLmJvcmRlckRhc2gsIGdyaWRMaW5lT3B0cy5ib3JkZXJEYXNoLCBbXV0pKTtcclxuXHRcdFx0XHRjdHgubGluZURhc2hPZmZzZXQgPSByZXNvbHZlJDQoW2FuZ2xlTGluZU9wdHMuYm9yZGVyRGFzaE9mZnNldCwgZ3JpZExpbmVPcHRzLmJvcmRlckRhc2hPZmZzZXQsIDAuMF0pO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRmb3IgKGkgPSBtZS5jaGFydC5kYXRhLmxhYmVscy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xyXG5cdFx0XHRcdG9mZnNldCA9IG1lLmdldERpc3RhbmNlRnJvbUNlbnRlckZvclZhbHVlKG9wdHMudGlja3MucmV2ZXJzZSA/IG1lLm1pbiA6IG1lLm1heCk7XHJcblx0XHRcdFx0cG9zaXRpb24gPSBtZS5nZXRQb2ludFBvc2l0aW9uKGksIG9mZnNldCk7XHJcblx0XHRcdFx0Y3R4LmJlZ2luUGF0aCgpO1xyXG5cdFx0XHRcdGN0eC5tb3ZlVG8obWUueENlbnRlciwgbWUueUNlbnRlcik7XHJcblx0XHRcdFx0Y3R4LmxpbmVUbyhwb3NpdGlvbi54LCBwb3NpdGlvbi55KTtcclxuXHRcdFx0XHRjdHguc3Ryb2tlKCk7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdGN0eC5yZXN0b3JlKCk7XHJcblx0XHR9XHJcblx0fSxcclxuXHJcblx0LyoqXHJcblx0ICogQHByaXZhdGVcclxuXHQgKi9cclxuXHRfZHJhd0xhYmVsczogZnVuY3Rpb24oKSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0dmFyIGN0eCA9IG1lLmN0eDtcclxuXHRcdHZhciBvcHRzID0gbWUub3B0aW9ucztcclxuXHRcdHZhciB0aWNrT3B0cyA9IG9wdHMudGlja3M7XHJcblxyXG5cdFx0aWYgKCF0aWNrT3B0cy5kaXNwbGF5KSB7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHJcblx0XHR2YXIgc3RhcnRBbmdsZSA9IG1lLmdldEluZGV4QW5nbGUoMCk7XHJcblx0XHR2YXIgdGlja0ZvbnQgPSBoZWxwZXJzJDEub3B0aW9ucy5fcGFyc2VGb250KHRpY2tPcHRzKTtcclxuXHRcdHZhciB0aWNrRm9udENvbG9yID0gdmFsdWVPckRlZmF1bHQkYyh0aWNrT3B0cy5mb250Q29sb3IsIGNvcmVfZGVmYXVsdHMuZ2xvYmFsLmRlZmF1bHRGb250Q29sb3IpO1xyXG5cdFx0dmFyIG9mZnNldCwgd2lkdGg7XHJcblxyXG5cdFx0Y3R4LnNhdmUoKTtcclxuXHRcdGN0eC5mb250ID0gdGlja0ZvbnQuc3RyaW5nO1xyXG5cdFx0Y3R4LnRyYW5zbGF0ZShtZS54Q2VudGVyLCBtZS55Q2VudGVyKTtcclxuXHRcdGN0eC5yb3RhdGUoc3RhcnRBbmdsZSk7XHJcblx0XHRjdHgudGV4dEFsaWduID0gJ2NlbnRlcic7XHJcblx0XHRjdHgudGV4dEJhc2VsaW5lID0gJ21pZGRsZSc7XHJcblxyXG5cdFx0aGVscGVycyQxLmVhY2gobWUudGlja3MsIGZ1bmN0aW9uKGxhYmVsLCBpbmRleCkge1xyXG5cdFx0XHRpZiAoaW5kZXggPT09IDAgJiYgIXRpY2tPcHRzLnJldmVyc2UpIHtcclxuXHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdG9mZnNldCA9IG1lLmdldERpc3RhbmNlRnJvbUNlbnRlckZvclZhbHVlKG1lLnRpY2tzQXNOdW1iZXJzW2luZGV4XSk7XHJcblxyXG5cdFx0XHRpZiAodGlja09wdHMuc2hvd0xhYmVsQmFja2Ryb3ApIHtcclxuXHRcdFx0XHR3aWR0aCA9IGN0eC5tZWFzdXJlVGV4dChsYWJlbCkud2lkdGg7XHJcblx0XHRcdFx0Y3R4LmZpbGxTdHlsZSA9IHRpY2tPcHRzLmJhY2tkcm9wQ29sb3I7XHJcblxyXG5cdFx0XHRcdGN0eC5maWxsUmVjdChcclxuXHRcdFx0XHRcdC13aWR0aCAvIDIgLSB0aWNrT3B0cy5iYWNrZHJvcFBhZGRpbmdYLFxyXG5cdFx0XHRcdFx0LW9mZnNldCAtIHRpY2tGb250LnNpemUgLyAyIC0gdGlja09wdHMuYmFja2Ryb3BQYWRkaW5nWSxcclxuXHRcdFx0XHRcdHdpZHRoICsgdGlja09wdHMuYmFja2Ryb3BQYWRkaW5nWCAqIDIsXHJcblx0XHRcdFx0XHR0aWNrRm9udC5zaXplICsgdGlja09wdHMuYmFja2Ryb3BQYWRkaW5nWSAqIDJcclxuXHRcdFx0XHQpO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRjdHguZmlsbFN0eWxlID0gdGlja0ZvbnRDb2xvcjtcclxuXHRcdFx0Y3R4LmZpbGxUZXh0KGxhYmVsLCAwLCAtb2Zmc2V0KTtcclxuXHRcdH0pO1xyXG5cclxuXHRcdGN0eC5yZXN0b3JlKCk7XHJcblx0fSxcclxuXHJcblx0LyoqXHJcblx0ICogQHByaXZhdGVcclxuXHQgKi9cclxuXHRfZHJhd1RpdGxlOiBoZWxwZXJzJDEubm9vcFxyXG59KTtcclxuXHJcbi8vIElOVEVSTkFMOiBzdGF0aWMgZGVmYXVsdCBvcHRpb25zLCByZWdpc3RlcmVkIGluIHNyYy9pbmRleC5qc1xyXG52YXIgX2RlZmF1bHRzJDMgPSBkZWZhdWx0Q29uZmlnJDM7XG5zY2FsZV9yYWRpYWxMaW5lYXIuX2RlZmF1bHRzID0gX2RlZmF1bHRzJDM7XG5cbnZhciBkZXByZWNhdGVkJDEgPSBoZWxwZXJzJDEuX2RlcHJlY2F0ZWQ7XHJcbnZhciByZXNvbHZlJDUgPSBoZWxwZXJzJDEub3B0aW9ucy5yZXNvbHZlO1xyXG52YXIgdmFsdWVPckRlZmF1bHQkZCA9IGhlbHBlcnMkMS52YWx1ZU9yRGVmYXVsdDtcclxuXHJcbi8vIEludGVnZXIgY29uc3RhbnRzIGFyZSBmcm9tIHRoZSBFUzYgc3BlYy5cclxudmFyIE1JTl9JTlRFR0VSID0gTnVtYmVyLk1JTl9TQUZFX0lOVEVHRVIgfHwgLTkwMDcxOTkyNTQ3NDA5OTE7XHJcbnZhciBNQVhfSU5URUdFUiA9IE51bWJlci5NQVhfU0FGRV9JTlRFR0VSIHx8IDkwMDcxOTkyNTQ3NDA5OTE7XHJcblxyXG52YXIgSU5URVJWQUxTID0ge1xyXG5cdG1pbGxpc2Vjb25kOiB7XHJcblx0XHRjb21tb246IHRydWUsXHJcblx0XHRzaXplOiAxLFxyXG5cdFx0c3RlcHM6IDEwMDBcclxuXHR9LFxyXG5cdHNlY29uZDoge1xyXG5cdFx0Y29tbW9uOiB0cnVlLFxyXG5cdFx0c2l6ZTogMTAwMCxcclxuXHRcdHN0ZXBzOiA2MFxyXG5cdH0sXHJcblx0bWludXRlOiB7XHJcblx0XHRjb21tb246IHRydWUsXHJcblx0XHRzaXplOiA2MDAwMCxcclxuXHRcdHN0ZXBzOiA2MFxyXG5cdH0sXHJcblx0aG91cjoge1xyXG5cdFx0Y29tbW9uOiB0cnVlLFxyXG5cdFx0c2l6ZTogMzYwMDAwMCxcclxuXHRcdHN0ZXBzOiAyNFxyXG5cdH0sXHJcblx0ZGF5OiB7XHJcblx0XHRjb21tb246IHRydWUsXHJcblx0XHRzaXplOiA4NjQwMDAwMCxcclxuXHRcdHN0ZXBzOiAzMFxyXG5cdH0sXHJcblx0d2Vlazoge1xyXG5cdFx0Y29tbW9uOiBmYWxzZSxcclxuXHRcdHNpemU6IDYwNDgwMDAwMCxcclxuXHRcdHN0ZXBzOiA0XHJcblx0fSxcclxuXHRtb250aDoge1xyXG5cdFx0Y29tbW9uOiB0cnVlLFxyXG5cdFx0c2l6ZTogMi42MjhlOSxcclxuXHRcdHN0ZXBzOiAxMlxyXG5cdH0sXHJcblx0cXVhcnRlcjoge1xyXG5cdFx0Y29tbW9uOiBmYWxzZSxcclxuXHRcdHNpemU6IDcuODg0ZTksXHJcblx0XHRzdGVwczogNFxyXG5cdH0sXHJcblx0eWVhcjoge1xyXG5cdFx0Y29tbW9uOiB0cnVlLFxyXG5cdFx0c2l6ZTogMy4xNTRlMTBcclxuXHR9XHJcbn07XHJcblxyXG52YXIgVU5JVFMgPSBPYmplY3Qua2V5cyhJTlRFUlZBTFMpO1xyXG5cclxuZnVuY3Rpb24gc29ydGVyKGEsIGIpIHtcclxuXHRyZXR1cm4gYSAtIGI7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGFycmF5VW5pcXVlKGl0ZW1zKSB7XHJcblx0dmFyIGhhc2ggPSB7fTtcclxuXHR2YXIgb3V0ID0gW107XHJcblx0dmFyIGksIGlsZW4sIGl0ZW07XHJcblxyXG5cdGZvciAoaSA9IDAsIGlsZW4gPSBpdGVtcy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcclxuXHRcdGl0ZW0gPSBpdGVtc1tpXTtcclxuXHRcdGlmICghaGFzaFtpdGVtXSkge1xyXG5cdFx0XHRoYXNoW2l0ZW1dID0gdHJ1ZTtcclxuXHRcdFx0b3V0LnB1c2goaXRlbSk7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRyZXR1cm4gb3V0O1xyXG59XHJcblxyXG5mdW5jdGlvbiBnZXRNaW4ob3B0aW9ucykge1xyXG5cdHJldHVybiBoZWxwZXJzJDEudmFsdWVPckRlZmF1bHQob3B0aW9ucy50aW1lLm1pbiwgb3B0aW9ucy50aWNrcy5taW4pO1xyXG59XHJcblxyXG5mdW5jdGlvbiBnZXRNYXgob3B0aW9ucykge1xyXG5cdHJldHVybiBoZWxwZXJzJDEudmFsdWVPckRlZmF1bHQob3B0aW9ucy50aW1lLm1heCwgb3B0aW9ucy50aWNrcy5tYXgpO1xyXG59XHJcblxyXG4vKipcclxuICogUmV0dXJucyBhbiBhcnJheSBvZiB7dGltZSwgcG9zfSBvYmplY3RzIHVzZWQgdG8gaW50ZXJwb2xhdGUgYSBzcGVjaWZpYyBgdGltZWAgb3IgcG9zaXRpb25cclxuICogKGBwb3NgKSBvbiB0aGUgc2NhbGUsIGJ5IHNlYXJjaGluZyBlbnRyaWVzIGJlZm9yZSBhbmQgYWZ0ZXIgdGhlIHJlcXVlc3RlZCB2YWx1ZS4gYHBvc2AgaXNcclxuICogYSBkZWNpbWFsIGJldHdlZW4gMCBhbmQgMTogMCBiZWluZyB0aGUgc3RhcnQgb2YgdGhlIHNjYWxlIChsZWZ0IG9yIHRvcCkgYW5kIDEgdGhlIG90aGVyXHJcbiAqIGV4dHJlbWl0eSAobGVmdCArIHdpZHRoIG9yIHRvcCArIGhlaWdodCkuIE5vdGUgdGhhdCBpdCB3b3VsZCBiZSBtb3JlIG9wdGltaXplZCB0byBkaXJlY3RseVxyXG4gKiBzdG9yZSBwcmUtY29tcHV0ZWQgcGl4ZWxzLCBidXQgdGhlIHNjYWxlIGRpbWVuc2lvbnMgYXJlIG5vdCBndWFyYW50ZWVkIGF0IHRoZSB0aW1lIHdlIG5lZWRcclxuICogdG8gY3JlYXRlIHRoZSBsb29rdXAgdGFibGUuIFRoZSB0YWJsZSBBTFdBWVMgY29udGFpbnMgYXQgbGVhc3QgdHdvIGl0ZW1zOiBtaW4gYW5kIG1heC5cclxuICpcclxuICogQHBhcmFtIHtudW1iZXJbXX0gdGltZXN0YW1wcyAtIHRpbWVzdGFtcHMgc29ydGVkIGZyb20gbG93ZXN0IHRvIGhpZ2hlc3QuXHJcbiAqIEBwYXJhbSB7c3RyaW5nfSBkaXN0cmlidXRpb24gLSBJZiAnbGluZWFyJywgdGltZXN0YW1wcyB3aWxsIGJlIHNwcmVhZCBsaW5lYXJseSBhbG9uZyB0aGUgbWluXHJcbiAqIGFuZCBtYXggcmFuZ2UsIHNvIGJhc2ljYWxseSwgdGhlIHRhYmxlIHdpbGwgY29udGFpbnMgb25seSB0d28gaXRlbXM6IHttaW4sIDB9IGFuZCB7bWF4LCAxfS5cclxuICogSWYgJ3NlcmllcycsIHRpbWVzdGFtcHMgd2lsbCBiZSBwb3NpdGlvbmVkIGF0IHRoZSBzYW1lIGRpc3RhbmNlIGZyb20gZWFjaCBvdGhlci4gSW4gdGhpc1xyXG4gKiBjYXNlLCBvbmx5IHRpbWVzdGFtcHMgdGhhdCBicmVhayB0aGUgdGltZSBsaW5lYXJpdHkgYXJlIHJlZ2lzdGVyZWQsIG1lYW5pbmcgdGhhdCBpbiB0aGVcclxuICogYmVzdCBjYXNlLCBhbGwgdGltZXN0YW1wcyBhcmUgbGluZWFyLCB0aGUgdGFibGUgY29udGFpbnMgb25seSBtaW4gYW5kIG1heC5cclxuICovXHJcbmZ1bmN0aW9uIGJ1aWxkTG9va3VwVGFibGUodGltZXN0YW1wcywgbWluLCBtYXgsIGRpc3RyaWJ1dGlvbikge1xyXG5cdGlmIChkaXN0cmlidXRpb24gPT09ICdsaW5lYXInIHx8ICF0aW1lc3RhbXBzLmxlbmd0aCkge1xyXG5cdFx0cmV0dXJuIFtcclxuXHRcdFx0e3RpbWU6IG1pbiwgcG9zOiAwfSxcclxuXHRcdFx0e3RpbWU6IG1heCwgcG9zOiAxfVxyXG5cdFx0XTtcclxuXHR9XHJcblxyXG5cdHZhciB0YWJsZSA9IFtdO1xyXG5cdHZhciBpdGVtcyA9IFttaW5dO1xyXG5cdHZhciBpLCBpbGVuLCBwcmV2LCBjdXJyLCBuZXh0O1xyXG5cclxuXHRmb3IgKGkgPSAwLCBpbGVuID0gdGltZXN0YW1wcy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcclxuXHRcdGN1cnIgPSB0aW1lc3RhbXBzW2ldO1xyXG5cdFx0aWYgKGN1cnIgPiBtaW4gJiYgY3VyciA8IG1heCkge1xyXG5cdFx0XHRpdGVtcy5wdXNoKGN1cnIpO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0aXRlbXMucHVzaChtYXgpO1xyXG5cclxuXHRmb3IgKGkgPSAwLCBpbGVuID0gaXRlbXMubGVuZ3RoOyBpIDwgaWxlbjsgKytpKSB7XHJcblx0XHRuZXh0ID0gaXRlbXNbaSArIDFdO1xyXG5cdFx0cHJldiA9IGl0ZW1zW2kgLSAxXTtcclxuXHRcdGN1cnIgPSBpdGVtc1tpXTtcclxuXHJcblx0XHQvLyBvbmx5IGFkZCBwb2ludHMgdGhhdCBicmVha3MgdGhlIHNjYWxlIGxpbmVhcml0eVxyXG5cdFx0aWYgKHByZXYgPT09IHVuZGVmaW5lZCB8fCBuZXh0ID09PSB1bmRlZmluZWQgfHwgTWF0aC5yb3VuZCgobmV4dCArIHByZXYpIC8gMikgIT09IGN1cnIpIHtcclxuXHRcdFx0dGFibGUucHVzaCh7dGltZTogY3VyciwgcG9zOiBpIC8gKGlsZW4gLSAxKX0pO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0cmV0dXJuIHRhYmxlO1xyXG59XHJcblxyXG4vLyBAc2VlIGFkYXB0ZWQgZnJvbSBodHRwczovL3d3dy5hbnVqZ2FraGFyLmNvbS8yMDE0LzAzLzAxL2JpbmFyeS1zZWFyY2gtaW4tamF2YXNjcmlwdC9cclxuZnVuY3Rpb24gbG9va3VwKHRhYmxlLCBrZXksIHZhbHVlKSB7XHJcblx0dmFyIGxvID0gMDtcclxuXHR2YXIgaGkgPSB0YWJsZS5sZW5ndGggLSAxO1xyXG5cdHZhciBtaWQsIGkwLCBpMTtcclxuXHJcblx0d2hpbGUgKGxvID49IDAgJiYgbG8gPD0gaGkpIHtcclxuXHRcdG1pZCA9IChsbyArIGhpKSA+PiAxO1xyXG5cdFx0aTAgPSB0YWJsZVttaWQgLSAxXSB8fCBudWxsO1xyXG5cdFx0aTEgPSB0YWJsZVttaWRdO1xyXG5cclxuXHRcdGlmICghaTApIHtcclxuXHRcdFx0Ly8gZ2l2ZW4gdmFsdWUgaXMgb3V0c2lkZSB0YWJsZSAoYmVmb3JlIGZpcnN0IGl0ZW0pXHJcblx0XHRcdHJldHVybiB7bG86IG51bGwsIGhpOiBpMX07XHJcblx0XHR9IGVsc2UgaWYgKGkxW2tleV0gPCB2YWx1ZSkge1xyXG5cdFx0XHRsbyA9IG1pZCArIDE7XHJcblx0XHR9IGVsc2UgaWYgKGkwW2tleV0gPiB2YWx1ZSkge1xyXG5cdFx0XHRoaSA9IG1pZCAtIDE7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRyZXR1cm4ge2xvOiBpMCwgaGk6IGkxfTtcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdC8vIGdpdmVuIHZhbHVlIGlzIG91dHNpZGUgdGFibGUgKGFmdGVyIGxhc3QgaXRlbSlcclxuXHRyZXR1cm4ge2xvOiBpMSwgaGk6IG51bGx9O1xyXG59XHJcblxyXG4vKipcclxuICogTGluZWFybHkgaW50ZXJwb2xhdGVzIHRoZSBnaXZlbiBzb3VyY2UgYHZhbHVlYCB1c2luZyB0aGUgdGFibGUgaXRlbXMgYHNrZXlgIHZhbHVlcyBhbmRcclxuICogcmV0dXJucyB0aGUgYXNzb2NpYXRlZCBgdGtleWAgdmFsdWUuIEZvciBleGFtcGxlLCBpbnRlcnBvbGF0ZSh0YWJsZSwgJ3RpbWUnLCA0MiwgJ3BvcycpXHJcbiAqIHJldHVybnMgdGhlIHBvc2l0aW9uIGZvciBhIHRpbWVzdGFtcCBlcXVhbCB0byA0Mi4gSWYgdmFsdWUgaXMgb3V0IG9mIGJvdW5kcywgdmFsdWVzIGF0XHJcbiAqIGluZGV4IFswLCAxXSBvciBbbiAtIDEsIG5dIGFyZSB1c2VkIGZvciB0aGUgaW50ZXJwb2xhdGlvbi5cclxuICovXHJcbmZ1bmN0aW9uIGludGVycG9sYXRlJDEodGFibGUsIHNrZXksIHN2YWwsIHRrZXkpIHtcclxuXHR2YXIgcmFuZ2UgPSBsb29rdXAodGFibGUsIHNrZXksIHN2YWwpO1xyXG5cclxuXHQvLyBOb3RlOiB0aGUgbG9va3VwIHRhYmxlIEFMV0FZUyBjb250YWlucyBhdCBsZWFzdCAyIGl0ZW1zIChtaW4gYW5kIG1heClcclxuXHR2YXIgcHJldiA9ICFyYW5nZS5sbyA/IHRhYmxlWzBdIDogIXJhbmdlLmhpID8gdGFibGVbdGFibGUubGVuZ3RoIC0gMl0gOiByYW5nZS5sbztcclxuXHR2YXIgbmV4dCA9ICFyYW5nZS5sbyA/IHRhYmxlWzFdIDogIXJhbmdlLmhpID8gdGFibGVbdGFibGUubGVuZ3RoIC0gMV0gOiByYW5nZS5oaTtcclxuXHJcblx0dmFyIHNwYW4gPSBuZXh0W3NrZXldIC0gcHJldltza2V5XTtcclxuXHR2YXIgcmF0aW8gPSBzcGFuID8gKHN2YWwgLSBwcmV2W3NrZXldKSAvIHNwYW4gOiAwO1xyXG5cdHZhciBvZmZzZXQgPSAobmV4dFt0a2V5XSAtIHByZXZbdGtleV0pICogcmF0aW87XHJcblxyXG5cdHJldHVybiBwcmV2W3RrZXldICsgb2Zmc2V0O1xyXG59XHJcblxyXG5mdW5jdGlvbiB0b1RpbWVzdGFtcChzY2FsZSwgaW5wdXQpIHtcclxuXHR2YXIgYWRhcHRlciA9IHNjYWxlLl9hZGFwdGVyO1xyXG5cdHZhciBvcHRpb25zID0gc2NhbGUub3B0aW9ucy50aW1lO1xyXG5cdHZhciBwYXJzZXIgPSBvcHRpb25zLnBhcnNlcjtcclxuXHR2YXIgZm9ybWF0ID0gcGFyc2VyIHx8IG9wdGlvbnMuZm9ybWF0O1xyXG5cdHZhciB2YWx1ZSA9IGlucHV0O1xyXG5cclxuXHRpZiAodHlwZW9mIHBhcnNlciA9PT0gJ2Z1bmN0aW9uJykge1xyXG5cdFx0dmFsdWUgPSBwYXJzZXIodmFsdWUpO1xyXG5cdH1cclxuXHJcblx0Ly8gT25seSBwYXJzZSBpZiBpdHMgbm90IGEgdGltZXN0YW1wIGFscmVhZHlcclxuXHRpZiAoIWhlbHBlcnMkMS5pc0Zpbml0ZSh2YWx1ZSkpIHtcclxuXHRcdHZhbHVlID0gdHlwZW9mIGZvcm1hdCA9PT0gJ3N0cmluZydcclxuXHRcdFx0PyBhZGFwdGVyLnBhcnNlKHZhbHVlLCBmb3JtYXQpXHJcblx0XHRcdDogYWRhcHRlci5wYXJzZSh2YWx1ZSk7XHJcblx0fVxyXG5cclxuXHRpZiAodmFsdWUgIT09IG51bGwpIHtcclxuXHRcdHJldHVybiArdmFsdWU7XHJcblx0fVxyXG5cclxuXHQvLyBMYWJlbHMgYXJlIGluIGFuIGluY29tcGF0aWJsZSBmb3JtYXQgYW5kIG5vIGBwYXJzZXJgIGhhcyBiZWVuIHByb3ZpZGVkLlxyXG5cdC8vIFRoZSB1c2VyIG1pZ2h0IHN0aWxsIHVzZSB0aGUgZGVwcmVjYXRlZCBgZm9ybWF0YCBvcHRpb24gZm9yIHBhcnNpbmcuXHJcblx0aWYgKCFwYXJzZXIgJiYgdHlwZW9mIGZvcm1hdCA9PT0gJ2Z1bmN0aW9uJykge1xyXG5cdFx0dmFsdWUgPSBmb3JtYXQoaW5wdXQpO1xyXG5cclxuXHRcdC8vIGBmb3JtYXRgIGNvdWxkIHJldHVybiBzb21ldGhpbmcgZWxzZSB0aGFuIGEgdGltZXN0YW1wLCBpZiBzbywgcGFyc2UgaXRcclxuXHRcdGlmICghaGVscGVycyQxLmlzRmluaXRlKHZhbHVlKSkge1xyXG5cdFx0XHR2YWx1ZSA9IGFkYXB0ZXIucGFyc2UodmFsdWUpO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0cmV0dXJuIHZhbHVlO1xyXG59XHJcblxyXG5mdW5jdGlvbiBwYXJzZShzY2FsZSwgaW5wdXQpIHtcclxuXHRpZiAoaGVscGVycyQxLmlzTnVsbE9yVW5kZWYoaW5wdXQpKSB7XHJcblx0XHRyZXR1cm4gbnVsbDtcclxuXHR9XHJcblxyXG5cdHZhciBvcHRpb25zID0gc2NhbGUub3B0aW9ucy50aW1lO1xyXG5cdHZhciB2YWx1ZSA9IHRvVGltZXN0YW1wKHNjYWxlLCBzY2FsZS5nZXRSaWdodFZhbHVlKGlucHV0KSk7XHJcblx0aWYgKHZhbHVlID09PSBudWxsKSB7XHJcblx0XHRyZXR1cm4gdmFsdWU7XHJcblx0fVxyXG5cclxuXHRpZiAob3B0aW9ucy5yb3VuZCkge1xyXG5cdFx0dmFsdWUgPSArc2NhbGUuX2FkYXB0ZXIuc3RhcnRPZih2YWx1ZSwgb3B0aW9ucy5yb3VuZCk7XHJcblx0fVxyXG5cclxuXHRyZXR1cm4gdmFsdWU7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBGaWd1cmVzIG91dCB3aGF0IHVuaXQgcmVzdWx0cyBpbiBhbiBhcHByb3ByaWF0ZSBudW1iZXIgb2YgYXV0by1nZW5lcmF0ZWQgdGlja3NcclxuICovXHJcbmZ1bmN0aW9uIGRldGVybWluZVVuaXRGb3JBdXRvVGlja3MobWluVW5pdCwgbWluLCBtYXgsIGNhcGFjaXR5KSB7XHJcblx0dmFyIGlsZW4gPSBVTklUUy5sZW5ndGg7XHJcblx0dmFyIGksIGludGVydmFsLCBmYWN0b3I7XHJcblxyXG5cdGZvciAoaSA9IFVOSVRTLmluZGV4T2YobWluVW5pdCk7IGkgPCBpbGVuIC0gMTsgKytpKSB7XHJcblx0XHRpbnRlcnZhbCA9IElOVEVSVkFMU1tVTklUU1tpXV07XHJcblx0XHRmYWN0b3IgPSBpbnRlcnZhbC5zdGVwcyA/IGludGVydmFsLnN0ZXBzIDogTUFYX0lOVEVHRVI7XHJcblxyXG5cdFx0aWYgKGludGVydmFsLmNvbW1vbiAmJiBNYXRoLmNlaWwoKG1heCAtIG1pbikgLyAoZmFjdG9yICogaW50ZXJ2YWwuc2l6ZSkpIDw9IGNhcGFjaXR5KSB7XHJcblx0XHRcdHJldHVybiBVTklUU1tpXTtcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdHJldHVybiBVTklUU1tpbGVuIC0gMV07XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBGaWd1cmVzIG91dCB3aGF0IHVuaXQgdG8gZm9ybWF0IGEgc2V0IG9mIHRpY2tzIHdpdGhcclxuICovXHJcbmZ1bmN0aW9uIGRldGVybWluZVVuaXRGb3JGb3JtYXR0aW5nKHNjYWxlLCBudW1UaWNrcywgbWluVW5pdCwgbWluLCBtYXgpIHtcclxuXHR2YXIgaSwgdW5pdDtcclxuXHJcblx0Zm9yIChpID0gVU5JVFMubGVuZ3RoIC0gMTsgaSA+PSBVTklUUy5pbmRleE9mKG1pblVuaXQpOyBpLS0pIHtcclxuXHRcdHVuaXQgPSBVTklUU1tpXTtcclxuXHRcdGlmIChJTlRFUlZBTFNbdW5pdF0uY29tbW9uICYmIHNjYWxlLl9hZGFwdGVyLmRpZmYobWF4LCBtaW4sIHVuaXQpID49IG51bVRpY2tzIC0gMSkge1xyXG5cdFx0XHRyZXR1cm4gdW5pdDtcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdHJldHVybiBVTklUU1ttaW5Vbml0ID8gVU5JVFMuaW5kZXhPZihtaW5Vbml0KSA6IDBdO1xyXG59XHJcblxyXG5mdW5jdGlvbiBkZXRlcm1pbmVNYWpvclVuaXQodW5pdCkge1xyXG5cdGZvciAodmFyIGkgPSBVTklUUy5pbmRleE9mKHVuaXQpICsgMSwgaWxlbiA9IFVOSVRTLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xyXG5cdFx0aWYgKElOVEVSVkFMU1tVTklUU1tpXV0uY29tbW9uKSB7XHJcblx0XHRcdHJldHVybiBVTklUU1tpXTtcclxuXHRcdH1cclxuXHR9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBHZW5lcmF0ZXMgYSBtYXhpbXVtIG9mIGBjYXBhY2l0eWAgdGltZXN0YW1wcyBiZXR3ZWVuIG1pbiBhbmQgbWF4LCByb3VuZGVkIHRvIHRoZVxyXG4gKiBgbWlub3JgIHVuaXQgdXNpbmcgdGhlIGdpdmVuIHNjYWxlIHRpbWUgYG9wdGlvbnNgLlxyXG4gKiBJbXBvcnRhbnQ6IHRoaXMgbWV0aG9kIGNhbiByZXR1cm4gdGlja3Mgb3V0c2lkZSB0aGUgbWluIGFuZCBtYXggcmFuZ2UsIGl0J3MgdGhlXHJcbiAqIHJlc3BvbnNpYmlsaXR5IG9mIHRoZSBjYWxsaW5nIGNvZGUgdG8gY2xhbXAgdmFsdWVzIGlmIG5lZWRlZC5cclxuICovXHJcbmZ1bmN0aW9uIGdlbmVyYXRlKHNjYWxlLCBtaW4sIG1heCwgY2FwYWNpdHkpIHtcclxuXHR2YXIgYWRhcHRlciA9IHNjYWxlLl9hZGFwdGVyO1xyXG5cdHZhciBvcHRpb25zID0gc2NhbGUub3B0aW9ucztcclxuXHR2YXIgdGltZU9wdHMgPSBvcHRpb25zLnRpbWU7XHJcblx0dmFyIG1pbm9yID0gdGltZU9wdHMudW5pdCB8fCBkZXRlcm1pbmVVbml0Rm9yQXV0b1RpY2tzKHRpbWVPcHRzLm1pblVuaXQsIG1pbiwgbWF4LCBjYXBhY2l0eSk7XHJcblx0dmFyIHN0ZXBTaXplID0gcmVzb2x2ZSQ1KFt0aW1lT3B0cy5zdGVwU2l6ZSwgdGltZU9wdHMudW5pdFN0ZXBTaXplLCAxXSk7XHJcblx0dmFyIHdlZWtkYXkgPSBtaW5vciA9PT0gJ3dlZWsnID8gdGltZU9wdHMuaXNvV2Vla2RheSA6IGZhbHNlO1xyXG5cdHZhciBmaXJzdCA9IG1pbjtcclxuXHR2YXIgdGlja3MgPSBbXTtcclxuXHR2YXIgdGltZTtcclxuXHJcblx0Ly8gRm9yICd3ZWVrJyB1bml0LCBoYW5kbGUgdGhlIGZpcnN0IGRheSBvZiB3ZWVrIG9wdGlvblxyXG5cdGlmICh3ZWVrZGF5KSB7XHJcblx0XHRmaXJzdCA9ICthZGFwdGVyLnN0YXJ0T2YoZmlyc3QsICdpc29XZWVrJywgd2Vla2RheSk7XHJcblx0fVxyXG5cclxuXHQvLyBBbGlnbiBmaXJzdCB0aWNrcyBvbiB1bml0XHJcblx0Zmlyc3QgPSArYWRhcHRlci5zdGFydE9mKGZpcnN0LCB3ZWVrZGF5ID8gJ2RheScgOiBtaW5vcik7XHJcblxyXG5cdC8vIFByZXZlbnQgYnJvd3NlciBmcm9tIGZyZWV6aW5nIGluIGNhc2UgdXNlciBvcHRpb25zIHJlcXVlc3QgbWlsbGlvbnMgb2YgbWlsbGlzZWNvbmRzXHJcblx0aWYgKGFkYXB0ZXIuZGlmZihtYXgsIG1pbiwgbWlub3IpID4gMTAwMDAwICogc3RlcFNpemUpIHtcclxuXHRcdHRocm93IG1pbiArICcgYW5kICcgKyBtYXggKyAnIGFyZSB0b28gZmFyIGFwYXJ0IHdpdGggc3RlcFNpemUgb2YgJyArIHN0ZXBTaXplICsgJyAnICsgbWlub3I7XHJcblx0fVxyXG5cclxuXHRmb3IgKHRpbWUgPSBmaXJzdDsgdGltZSA8IG1heDsgdGltZSA9ICthZGFwdGVyLmFkZCh0aW1lLCBzdGVwU2l6ZSwgbWlub3IpKSB7XHJcblx0XHR0aWNrcy5wdXNoKHRpbWUpO1xyXG5cdH1cclxuXHJcblx0aWYgKHRpbWUgPT09IG1heCB8fCBvcHRpb25zLmJvdW5kcyA9PT0gJ3RpY2tzJykge1xyXG5cdFx0dGlja3MucHVzaCh0aW1lKTtcclxuXHR9XHJcblxyXG5cdHJldHVybiB0aWNrcztcclxufVxyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgdGhlIHN0YXJ0IGFuZCBlbmQgb2Zmc2V0cyBmcm9tIGVkZ2VzIGluIHRoZSBmb3JtIG9mIHtzdGFydCwgZW5kfVxyXG4gKiB3aGVyZSBlYWNoIHZhbHVlIGlzIGEgcmVsYXRpdmUgd2lkdGggdG8gdGhlIHNjYWxlIGFuZCByYW5nZXMgYmV0d2VlbiAwIGFuZCAxLlxyXG4gKiBUaGV5IGFkZCBleHRyYSBtYXJnaW5zIG9uIHRoZSBib3RoIHNpZGVzIGJ5IHNjYWxpbmcgZG93biB0aGUgb3JpZ2luYWwgc2NhbGUuXHJcbiAqIE9mZnNldHMgYXJlIGFkZGVkIHdoZW4gdGhlIGBvZmZzZXRgIG9wdGlvbiBpcyB0cnVlLlxyXG4gKi9cclxuZnVuY3Rpb24gY29tcHV0ZU9mZnNldHModGFibGUsIHRpY2tzLCBtaW4sIG1heCwgb3B0aW9ucykge1xyXG5cdHZhciBzdGFydCA9IDA7XHJcblx0dmFyIGVuZCA9IDA7XHJcblx0dmFyIGZpcnN0LCBsYXN0O1xyXG5cclxuXHRpZiAob3B0aW9ucy5vZmZzZXQgJiYgdGlja3MubGVuZ3RoKSB7XHJcblx0XHRmaXJzdCA9IGludGVycG9sYXRlJDEodGFibGUsICd0aW1lJywgdGlja3NbMF0sICdwb3MnKTtcclxuXHRcdGlmICh0aWNrcy5sZW5ndGggPT09IDEpIHtcclxuXHRcdFx0c3RhcnQgPSAxIC0gZmlyc3Q7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRzdGFydCA9IChpbnRlcnBvbGF0ZSQxKHRhYmxlLCAndGltZScsIHRpY2tzWzFdLCAncG9zJykgLSBmaXJzdCkgLyAyO1xyXG5cdFx0fVxyXG5cdFx0bGFzdCA9IGludGVycG9sYXRlJDEodGFibGUsICd0aW1lJywgdGlja3NbdGlja3MubGVuZ3RoIC0gMV0sICdwb3MnKTtcclxuXHRcdGlmICh0aWNrcy5sZW5ndGggPT09IDEpIHtcclxuXHRcdFx0ZW5kID0gbGFzdDtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdGVuZCA9IChsYXN0IC0gaW50ZXJwb2xhdGUkMSh0YWJsZSwgJ3RpbWUnLCB0aWNrc1t0aWNrcy5sZW5ndGggLSAyXSwgJ3BvcycpKSAvIDI7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRyZXR1cm4ge3N0YXJ0OiBzdGFydCwgZW5kOiBlbmQsIGZhY3RvcjogMSAvIChzdGFydCArIDEgKyBlbmQpfTtcclxufVxyXG5cclxuZnVuY3Rpb24gc2V0TWFqb3JUaWNrcyhzY2FsZSwgdGlja3MsIG1hcCwgbWFqb3JVbml0KSB7XHJcblx0dmFyIGFkYXB0ZXIgPSBzY2FsZS5fYWRhcHRlcjtcclxuXHR2YXIgZmlyc3QgPSArYWRhcHRlci5zdGFydE9mKHRpY2tzWzBdLnZhbHVlLCBtYWpvclVuaXQpO1xyXG5cdHZhciBsYXN0ID0gdGlja3NbdGlja3MubGVuZ3RoIC0gMV0udmFsdWU7XHJcblx0dmFyIG1ham9yLCBpbmRleDtcclxuXHJcblx0Zm9yIChtYWpvciA9IGZpcnN0OyBtYWpvciA8PSBsYXN0OyBtYWpvciA9ICthZGFwdGVyLmFkZChtYWpvciwgMSwgbWFqb3JVbml0KSkge1xyXG5cdFx0aW5kZXggPSBtYXBbbWFqb3JdO1xyXG5cdFx0aWYgKGluZGV4ID49IDApIHtcclxuXHRcdFx0dGlja3NbaW5kZXhdLm1ham9yID0gdHJ1ZTtcclxuXHRcdH1cclxuXHR9XHJcblx0cmV0dXJuIHRpY2tzO1xyXG59XHJcblxyXG5mdW5jdGlvbiB0aWNrc0Zyb21UaW1lc3RhbXBzKHNjYWxlLCB2YWx1ZXMsIG1ham9yVW5pdCkge1xyXG5cdHZhciB0aWNrcyA9IFtdO1xyXG5cdHZhciBtYXAgPSB7fTtcclxuXHR2YXIgaWxlbiA9IHZhbHVlcy5sZW5ndGg7XHJcblx0dmFyIGksIHZhbHVlO1xyXG5cclxuXHRmb3IgKGkgPSAwOyBpIDwgaWxlbjsgKytpKSB7XHJcblx0XHR2YWx1ZSA9IHZhbHVlc1tpXTtcclxuXHRcdG1hcFt2YWx1ZV0gPSBpO1xyXG5cclxuXHRcdHRpY2tzLnB1c2goe1xyXG5cdFx0XHR2YWx1ZTogdmFsdWUsXHJcblx0XHRcdG1ham9yOiBmYWxzZVxyXG5cdFx0fSk7XHJcblx0fVxyXG5cclxuXHQvLyBXZSBzZXQgdGhlIG1ham9yIHRpY2tzIHNlcGFyYXRlbHkgZnJvbSB0aGUgYWJvdmUgbG9vcCBiZWNhdXNlIGNhbGxpbmcgc3RhcnRPZiBmb3IgZXZlcnkgdGlja1xyXG5cdC8vIGlzIGV4cGVuc2l2ZSB3aGVuIHRoZXJlIGlzIGEgbGFyZ2UgbnVtYmVyIG9mIHRpY2tzXHJcblx0cmV0dXJuIChpbGVuID09PSAwIHx8ICFtYWpvclVuaXQpID8gdGlja3MgOiBzZXRNYWpvclRpY2tzKHNjYWxlLCB0aWNrcywgbWFwLCBtYWpvclVuaXQpO1xyXG59XHJcblxyXG52YXIgZGVmYXVsdENvbmZpZyQ0ID0ge1xyXG5cdHBvc2l0aW9uOiAnYm90dG9tJyxcclxuXHJcblx0LyoqXHJcblx0ICogRGF0YSBkaXN0cmlidXRpb24gYWxvbmcgdGhlIHNjYWxlOlxyXG5cdCAqIC0gJ2xpbmVhcic6IGRhdGEgYXJlIHNwcmVhZCBhY2NvcmRpbmcgdG8gdGhlaXIgdGltZSAoZGlzdGFuY2VzIGNhbiB2YXJ5KSxcclxuXHQgKiAtICdzZXJpZXMnOiBkYXRhIGFyZSBzcHJlYWQgYXQgdGhlIHNhbWUgZGlzdGFuY2UgZnJvbSBlYWNoIG90aGVyLlxyXG5cdCAqIEBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2NoYXJ0anMvQ2hhcnQuanMvcHVsbC80NTA3XHJcblx0ICogQHNpbmNlIDIuNy4wXHJcblx0ICovXHJcblx0ZGlzdHJpYnV0aW9uOiAnbGluZWFyJyxcclxuXHJcblx0LyoqXHJcblx0ICogU2NhbGUgYm91bmRhcnkgc3RyYXRlZ3kgKGJ5cGFzc2VkIGJ5IG1pbi9tYXggdGltZSBvcHRpb25zKVxyXG5cdCAqIC0gYGRhdGFgOiBtYWtlIHN1cmUgZGF0YSBhcmUgZnVsbHkgdmlzaWJsZSwgdGlja3Mgb3V0c2lkZSBhcmUgcmVtb3ZlZFxyXG5cdCAqIC0gYHRpY2tzYDogbWFrZSBzdXJlIHRpY2tzIGFyZSBmdWxseSB2aXNpYmxlLCBkYXRhIG91dHNpZGUgYXJlIHRydW5jYXRlZFxyXG5cdCAqIEBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2NoYXJ0anMvQ2hhcnQuanMvcHVsbC80NTU2XHJcblx0ICogQHNpbmNlIDIuNy4wXHJcblx0ICovXHJcblx0Ym91bmRzOiAnZGF0YScsXHJcblxyXG5cdGFkYXB0ZXJzOiB7fSxcclxuXHR0aW1lOiB7XHJcblx0XHRwYXJzZXI6IGZhbHNlLCAvLyBmYWxzZSA9PSBhIHBhdHRlcm4gc3RyaW5nIGZyb20gaHR0cHM6Ly9tb21lbnRqcy5jb20vZG9jcy8jL3BhcnNpbmcvc3RyaW5nLWZvcm1hdC8gb3IgYSBjdXN0b20gY2FsbGJhY2sgdGhhdCBjb252ZXJ0cyBpdHMgYXJndW1lbnQgdG8gYSBtb21lbnRcclxuXHRcdHVuaXQ6IGZhbHNlLCAvLyBmYWxzZSA9PSBhdXRvbWF0aWMgb3Igb3ZlcnJpZGUgd2l0aCB3ZWVrLCBtb250aCwgeWVhciwgZXRjLlxyXG5cdFx0cm91bmQ6IGZhbHNlLCAvLyBub25lLCBvciBvdmVycmlkZSB3aXRoIHdlZWssIG1vbnRoLCB5ZWFyLCBldGMuXHJcblx0XHRkaXNwbGF5Rm9ybWF0OiBmYWxzZSwgLy8gREVQUkVDQVRFRFxyXG5cdFx0aXNvV2Vla2RheTogZmFsc2UsIC8vIG92ZXJyaWRlIHdlZWsgc3RhcnQgZGF5IC0gc2VlIGh0dHBzOi8vbW9tZW50anMuY29tL2RvY3MvIy9nZXQtc2V0L2lzby13ZWVrZGF5L1xyXG5cdFx0bWluVW5pdDogJ21pbGxpc2Vjb25kJyxcclxuXHRcdGRpc3BsYXlGb3JtYXRzOiB7fVxyXG5cdH0sXHJcblx0dGlja3M6IHtcclxuXHRcdGF1dG9Ta2lwOiBmYWxzZSxcclxuXHJcblx0XHQvKipcclxuXHRcdCAqIFRpY2tzIGdlbmVyYXRpb24gaW5wdXQgdmFsdWVzOlxyXG5cdFx0ICogLSAnYXV0byc6IGdlbmVyYXRlcyBcIm9wdGltYWxcIiB0aWNrcyBiYXNlZCBvbiBzY2FsZSBzaXplIGFuZCB0aW1lIG9wdGlvbnMuXHJcblx0XHQgKiAtICdkYXRhJzogZ2VuZXJhdGVzIHRpY2tzIGZyb20gZGF0YSAoaW5jbHVkaW5nIGxhYmVscyBmcm9tIGRhdGEge3R8eHx5fSBvYmplY3RzKS5cclxuXHRcdCAqIC0gJ2xhYmVscyc6IGdlbmVyYXRlcyB0aWNrcyBmcm9tIHVzZXIgZ2l2ZW4gYGRhdGEubGFiZWxzYCB2YWx1ZXMgT05MWS5cclxuXHRcdCAqIEBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2NoYXJ0anMvQ2hhcnQuanMvcHVsbC80NTA3XHJcblx0XHQgKiBAc2luY2UgMi43LjBcclxuXHRcdCAqL1xyXG5cdFx0c291cmNlOiAnYXV0bycsXHJcblxyXG5cdFx0bWFqb3I6IHtcclxuXHRcdFx0ZW5hYmxlZDogZmFsc2VcclxuXHRcdH1cclxuXHR9XHJcbn07XHJcblxyXG52YXIgc2NhbGVfdGltZSA9IGNvcmVfc2NhbGUuZXh0ZW5kKHtcclxuXHRpbml0aWFsaXplOiBmdW5jdGlvbigpIHtcclxuXHRcdHRoaXMubWVyZ2VUaWNrc09wdGlvbnMoKTtcclxuXHRcdGNvcmVfc2NhbGUucHJvdG90eXBlLmluaXRpYWxpemUuY2FsbCh0aGlzKTtcclxuXHR9LFxyXG5cclxuXHR1cGRhdGU6IGZ1bmN0aW9uKCkge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHRcdHZhciBvcHRpb25zID0gbWUub3B0aW9ucztcclxuXHRcdHZhciB0aW1lID0gb3B0aW9ucy50aW1lIHx8IChvcHRpb25zLnRpbWUgPSB7fSk7XHJcblx0XHR2YXIgYWRhcHRlciA9IG1lLl9hZGFwdGVyID0gbmV3IGNvcmVfYWRhcHRlcnMuX2RhdGUob3B0aW9ucy5hZGFwdGVycy5kYXRlKTtcclxuXHJcblx0XHQvLyBERVBSRUNBVElPTlM6IG91dHB1dCBhIG1lc3NhZ2Ugb25seSBvbmUgdGltZSBwZXIgdXBkYXRlXHJcblx0XHRkZXByZWNhdGVkJDEoJ3RpbWUgc2NhbGUnLCB0aW1lLmZvcm1hdCwgJ3RpbWUuZm9ybWF0JywgJ3RpbWUucGFyc2VyJyk7XHJcblx0XHRkZXByZWNhdGVkJDEoJ3RpbWUgc2NhbGUnLCB0aW1lLm1pbiwgJ3RpbWUubWluJywgJ3RpY2tzLm1pbicpO1xyXG5cdFx0ZGVwcmVjYXRlZCQxKCd0aW1lIHNjYWxlJywgdGltZS5tYXgsICd0aW1lLm1heCcsICd0aWNrcy5tYXgnKTtcclxuXHJcblx0XHQvLyBCYWNrd2FyZCBjb21wYXRpYmlsaXR5OiBiZWZvcmUgaW50cm9kdWNpbmcgYWRhcHRlciwgYGRpc3BsYXlGb3JtYXRzYCB3YXNcclxuXHRcdC8vIHN1cHBvc2VkIHRvIGNvbnRhaW4gKmFsbCogdW5pdC9zdHJpbmcgcGFpcnMgYnV0IHRoaXMgY2FuJ3QgYmUgcmVzb2x2ZWRcclxuXHRcdC8vIHdoZW4gbG9hZGluZyB0aGUgc2NhbGUgKGFkYXB0ZXJzIGFyZSBsb2FkZWQgYWZ0ZXJ3YXJkKSwgc28gbGV0J3MgcG9wdWxhdGVcclxuXHRcdC8vIG1pc3NpbmcgZm9ybWF0cyBvbiB1cGRhdGVcclxuXHRcdGhlbHBlcnMkMS5tZXJnZUlmKHRpbWUuZGlzcGxheUZvcm1hdHMsIGFkYXB0ZXIuZm9ybWF0cygpKTtcclxuXHJcblx0XHRyZXR1cm4gY29yZV9zY2FsZS5wcm90b3R5cGUudXBkYXRlLmFwcGx5KG1lLCBhcmd1bWVudHMpO1xyXG5cdH0sXHJcblxyXG5cdC8qKlxyXG5cdCAqIEFsbG93cyBkYXRhIHRvIGJlIHJlZmVyZW5jZWQgdmlhICd0JyBhdHRyaWJ1dGVcclxuXHQgKi9cclxuXHRnZXRSaWdodFZhbHVlOiBmdW5jdGlvbihyYXdWYWx1ZSkge1xyXG5cdFx0aWYgKHJhd1ZhbHVlICYmIHJhd1ZhbHVlLnQgIT09IHVuZGVmaW5lZCkge1xyXG5cdFx0XHRyYXdWYWx1ZSA9IHJhd1ZhbHVlLnQ7XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gY29yZV9zY2FsZS5wcm90b3R5cGUuZ2V0UmlnaHRWYWx1ZS5jYWxsKHRoaXMsIHJhd1ZhbHVlKTtcclxuXHR9LFxyXG5cclxuXHRkZXRlcm1pbmVEYXRhTGltaXRzOiBmdW5jdGlvbigpIHtcclxuXHRcdHZhciBtZSA9IHRoaXM7XHJcblx0XHR2YXIgY2hhcnQgPSBtZS5jaGFydDtcclxuXHRcdHZhciBhZGFwdGVyID0gbWUuX2FkYXB0ZXI7XHJcblx0XHR2YXIgb3B0aW9ucyA9IG1lLm9wdGlvbnM7XHJcblx0XHR2YXIgdW5pdCA9IG9wdGlvbnMudGltZS51bml0IHx8ICdkYXknO1xyXG5cdFx0dmFyIG1pbiA9IE1BWF9JTlRFR0VSO1xyXG5cdFx0dmFyIG1heCA9IE1JTl9JTlRFR0VSO1xyXG5cdFx0dmFyIHRpbWVzdGFtcHMgPSBbXTtcclxuXHRcdHZhciBkYXRhc2V0cyA9IFtdO1xyXG5cdFx0dmFyIGxhYmVscyA9IFtdO1xyXG5cdFx0dmFyIGksIGosIGlsZW4sIGpsZW4sIGRhdGEsIHRpbWVzdGFtcCwgbGFiZWxzQWRkZWQ7XHJcblx0XHR2YXIgZGF0YUxhYmVscyA9IG1lLl9nZXRMYWJlbHMoKTtcclxuXHJcblx0XHRmb3IgKGkgPSAwLCBpbGVuID0gZGF0YUxhYmVscy5sZW5ndGg7IGkgPCBpbGVuOyArK2kpIHtcclxuXHRcdFx0bGFiZWxzLnB1c2gocGFyc2UobWUsIGRhdGFMYWJlbHNbaV0pKTtcclxuXHRcdH1cclxuXHJcblx0XHRmb3IgKGkgPSAwLCBpbGVuID0gKGNoYXJ0LmRhdGEuZGF0YXNldHMgfHwgW10pLmxlbmd0aDsgaSA8IGlsZW47ICsraSkge1xyXG5cdFx0XHRpZiAoY2hhcnQuaXNEYXRhc2V0VmlzaWJsZShpKSkge1xyXG5cdFx0XHRcdGRhdGEgPSBjaGFydC5kYXRhLmRhdGFzZXRzW2ldLmRhdGE7XHJcblxyXG5cdFx0XHRcdC8vIExldCdzIGNvbnNpZGVyIHRoYXQgYWxsIGRhdGEgaGF2ZSB0aGUgc2FtZSBmb3JtYXQuXHJcblx0XHRcdFx0aWYgKGhlbHBlcnMkMS5pc09iamVjdChkYXRhWzBdKSkge1xyXG5cdFx0XHRcdFx0ZGF0YXNldHNbaV0gPSBbXTtcclxuXHJcblx0XHRcdFx0XHRmb3IgKGogPSAwLCBqbGVuID0gZGF0YS5sZW5ndGg7IGogPCBqbGVuOyArK2opIHtcclxuXHRcdFx0XHRcdFx0dGltZXN0YW1wID0gcGFyc2UobWUsIGRhdGFbal0pO1xyXG5cdFx0XHRcdFx0XHR0aW1lc3RhbXBzLnB1c2godGltZXN0YW1wKTtcclxuXHRcdFx0XHRcdFx0ZGF0YXNldHNbaV1bal0gPSB0aW1lc3RhbXA7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdGRhdGFzZXRzW2ldID0gbGFiZWxzLnNsaWNlKDApO1xyXG5cdFx0XHRcdFx0aWYgKCFsYWJlbHNBZGRlZCkge1xyXG5cdFx0XHRcdFx0XHR0aW1lc3RhbXBzID0gdGltZXN0YW1wcy5jb25jYXQobGFiZWxzKTtcclxuXHRcdFx0XHRcdFx0bGFiZWxzQWRkZWQgPSB0cnVlO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRkYXRhc2V0c1tpXSA9IFtdO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKGxhYmVscy5sZW5ndGgpIHtcclxuXHRcdFx0bWluID0gTWF0aC5taW4obWluLCBsYWJlbHNbMF0pO1xyXG5cdFx0XHRtYXggPSBNYXRoLm1heChtYXgsIGxhYmVsc1tsYWJlbHMubGVuZ3RoIC0gMV0pO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmICh0aW1lc3RhbXBzLmxlbmd0aCkge1xyXG5cdFx0XHR0aW1lc3RhbXBzID0gaWxlbiA+IDEgPyBhcnJheVVuaXF1ZSh0aW1lc3RhbXBzKS5zb3J0KHNvcnRlcikgOiB0aW1lc3RhbXBzLnNvcnQoc29ydGVyKTtcclxuXHRcdFx0bWluID0gTWF0aC5taW4obWluLCB0aW1lc3RhbXBzWzBdKTtcclxuXHRcdFx0bWF4ID0gTWF0aC5tYXgobWF4LCB0aW1lc3RhbXBzW3RpbWVzdGFtcHMubGVuZ3RoIC0gMV0pO1xyXG5cdFx0fVxyXG5cclxuXHRcdG1pbiA9IHBhcnNlKG1lLCBnZXRNaW4ob3B0aW9ucykpIHx8IG1pbjtcclxuXHRcdG1heCA9IHBhcnNlKG1lLCBnZXRNYXgob3B0aW9ucykpIHx8IG1heDtcclxuXHJcblx0XHQvLyBJbiBjYXNlIHRoZXJlIGlzIG5vIHZhbGlkIG1pbi9tYXgsIHNldCBsaW1pdHMgYmFzZWQgb24gdW5pdCB0aW1lIG9wdGlvblxyXG5cdFx0bWluID0gbWluID09PSBNQVhfSU5URUdFUiA/ICthZGFwdGVyLnN0YXJ0T2YoRGF0ZS5ub3coKSwgdW5pdCkgOiBtaW47XHJcblx0XHRtYXggPSBtYXggPT09IE1JTl9JTlRFR0VSID8gK2FkYXB0ZXIuZW5kT2YoRGF0ZS5ub3coKSwgdW5pdCkgKyAxIDogbWF4O1xyXG5cclxuXHRcdC8vIE1ha2Ugc3VyZSB0aGF0IG1heCBpcyBzdHJpY3RseSBoaWdoZXIgdGhhbiBtaW4gKHJlcXVpcmVkIGJ5IHRoZSBsb29rdXAgdGFibGUpXHJcblx0XHRtZS5taW4gPSBNYXRoLm1pbihtaW4sIG1heCk7XHJcblx0XHRtZS5tYXggPSBNYXRoLm1heChtaW4gKyAxLCBtYXgpO1xyXG5cclxuXHRcdC8vIFBSSVZBVEVcclxuXHRcdG1lLl90YWJsZSA9IFtdO1xyXG5cdFx0bWUuX3RpbWVzdGFtcHMgPSB7XHJcblx0XHRcdGRhdGE6IHRpbWVzdGFtcHMsXHJcblx0XHRcdGRhdGFzZXRzOiBkYXRhc2V0cyxcclxuXHRcdFx0bGFiZWxzOiBsYWJlbHNcclxuXHRcdH07XHJcblx0fSxcclxuXHJcblx0YnVpbGRUaWNrczogZnVuY3Rpb24oKSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0dmFyIG1pbiA9IG1lLm1pbjtcclxuXHRcdHZhciBtYXggPSBtZS5tYXg7XHJcblx0XHR2YXIgb3B0aW9ucyA9IG1lLm9wdGlvbnM7XHJcblx0XHR2YXIgdGlja09wdHMgPSBvcHRpb25zLnRpY2tzO1xyXG5cdFx0dmFyIHRpbWVPcHRzID0gb3B0aW9ucy50aW1lO1xyXG5cdFx0dmFyIHRpbWVzdGFtcHMgPSBtZS5fdGltZXN0YW1wcztcclxuXHRcdHZhciB0aWNrcyA9IFtdO1xyXG5cdFx0dmFyIGNhcGFjaXR5ID0gbWUuZ2V0TGFiZWxDYXBhY2l0eShtaW4pO1xyXG5cdFx0dmFyIHNvdXJjZSA9IHRpY2tPcHRzLnNvdXJjZTtcclxuXHRcdHZhciBkaXN0cmlidXRpb24gPSBvcHRpb25zLmRpc3RyaWJ1dGlvbjtcclxuXHRcdHZhciBpLCBpbGVuLCB0aW1lc3RhbXA7XHJcblxyXG5cdFx0aWYgKHNvdXJjZSA9PT0gJ2RhdGEnIHx8IChzb3VyY2UgPT09ICdhdXRvJyAmJiBkaXN0cmlidXRpb24gPT09ICdzZXJpZXMnKSkge1xyXG5cdFx0XHR0aW1lc3RhbXBzID0gdGltZXN0YW1wcy5kYXRhO1xyXG5cdFx0fSBlbHNlIGlmIChzb3VyY2UgPT09ICdsYWJlbHMnKSB7XHJcblx0XHRcdHRpbWVzdGFtcHMgPSB0aW1lc3RhbXBzLmxhYmVscztcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdHRpbWVzdGFtcHMgPSBnZW5lcmF0ZShtZSwgbWluLCBtYXgsIGNhcGFjaXR5KTtcclxuXHRcdH1cclxuXHJcblx0XHRpZiAob3B0aW9ucy5ib3VuZHMgPT09ICd0aWNrcycgJiYgdGltZXN0YW1wcy5sZW5ndGgpIHtcclxuXHRcdFx0bWluID0gdGltZXN0YW1wc1swXTtcclxuXHRcdFx0bWF4ID0gdGltZXN0YW1wc1t0aW1lc3RhbXBzLmxlbmd0aCAtIDFdO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIEVuZm9yY2UgbGltaXRzIHdpdGggdXNlciBtaW4vbWF4IG9wdGlvbnNcclxuXHRcdG1pbiA9IHBhcnNlKG1lLCBnZXRNaW4ob3B0aW9ucykpIHx8IG1pbjtcclxuXHRcdG1heCA9IHBhcnNlKG1lLCBnZXRNYXgob3B0aW9ucykpIHx8IG1heDtcclxuXHJcblx0XHQvLyBSZW1vdmUgdGlja3Mgb3V0c2lkZSB0aGUgbWluL21heCByYW5nZVxyXG5cdFx0Zm9yIChpID0gMCwgaWxlbiA9IHRpbWVzdGFtcHMubGVuZ3RoOyBpIDwgaWxlbjsgKytpKSB7XHJcblx0XHRcdHRpbWVzdGFtcCA9IHRpbWVzdGFtcHNbaV07XHJcblx0XHRcdGlmICh0aW1lc3RhbXAgPj0gbWluICYmIHRpbWVzdGFtcCA8PSBtYXgpIHtcclxuXHRcdFx0XHR0aWNrcy5wdXNoKHRpbWVzdGFtcCk7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHRtZS5taW4gPSBtaW47XHJcblx0XHRtZS5tYXggPSBtYXg7XHJcblxyXG5cdFx0Ly8gUFJJVkFURVxyXG5cdFx0Ly8gZGV0ZXJtaW5lVW5pdEZvckZvcm1hdHRpbmcgcmVsaWVzIG9uIHRoZSBudW1iZXIgb2YgdGlja3Mgc28gd2UgZG9uJ3QgdXNlIGl0IHdoZW5cclxuXHRcdC8vIGF1dG9Ta2lwIGlzIGVuYWJsZWQgYmVjYXVzZSB3ZSBkb24ndCB5ZXQga25vdyB3aGF0IHRoZSBmaW5hbCBudW1iZXIgb2YgdGlja3Mgd2lsbCBiZVxyXG5cdFx0bWUuX3VuaXQgPSB0aW1lT3B0cy51bml0IHx8ICh0aWNrT3B0cy5hdXRvU2tpcFxyXG5cdFx0XHQ/IGRldGVybWluZVVuaXRGb3JBdXRvVGlja3ModGltZU9wdHMubWluVW5pdCwgbWUubWluLCBtZS5tYXgsIGNhcGFjaXR5KVxyXG5cdFx0XHQ6IGRldGVybWluZVVuaXRGb3JGb3JtYXR0aW5nKG1lLCB0aWNrcy5sZW5ndGgsIHRpbWVPcHRzLm1pblVuaXQsIG1lLm1pbiwgbWUubWF4KSk7XHJcblx0XHRtZS5fbWFqb3JVbml0ID0gIXRpY2tPcHRzLm1ham9yLmVuYWJsZWQgfHwgbWUuX3VuaXQgPT09ICd5ZWFyJyA/IHVuZGVmaW5lZFxyXG5cdFx0XHQ6IGRldGVybWluZU1ham9yVW5pdChtZS5fdW5pdCk7XHJcblx0XHRtZS5fdGFibGUgPSBidWlsZExvb2t1cFRhYmxlKG1lLl90aW1lc3RhbXBzLmRhdGEsIG1pbiwgbWF4LCBkaXN0cmlidXRpb24pO1xyXG5cdFx0bWUuX29mZnNldHMgPSBjb21wdXRlT2Zmc2V0cyhtZS5fdGFibGUsIHRpY2tzLCBtaW4sIG1heCwgb3B0aW9ucyk7XHJcblxyXG5cdFx0aWYgKHRpY2tPcHRzLnJldmVyc2UpIHtcclxuXHRcdFx0dGlja3MucmV2ZXJzZSgpO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiB0aWNrc0Zyb21UaW1lc3RhbXBzKG1lLCB0aWNrcywgbWUuX21ham9yVW5pdCk7XHJcblx0fSxcclxuXHJcblx0Z2V0TGFiZWxGb3JJbmRleDogZnVuY3Rpb24oaW5kZXgsIGRhdGFzZXRJbmRleCkge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHRcdHZhciBhZGFwdGVyID0gbWUuX2FkYXB0ZXI7XHJcblx0XHR2YXIgZGF0YSA9IG1lLmNoYXJ0LmRhdGE7XHJcblx0XHR2YXIgdGltZU9wdHMgPSBtZS5vcHRpb25zLnRpbWU7XHJcblx0XHR2YXIgbGFiZWwgPSBkYXRhLmxhYmVscyAmJiBpbmRleCA8IGRhdGEubGFiZWxzLmxlbmd0aCA/IGRhdGEubGFiZWxzW2luZGV4XSA6ICcnO1xyXG5cdFx0dmFyIHZhbHVlID0gZGF0YS5kYXRhc2V0c1tkYXRhc2V0SW5kZXhdLmRhdGFbaW5kZXhdO1xyXG5cclxuXHRcdGlmIChoZWxwZXJzJDEuaXNPYmplY3QodmFsdWUpKSB7XHJcblx0XHRcdGxhYmVsID0gbWUuZ2V0UmlnaHRWYWx1ZSh2YWx1ZSk7XHJcblx0XHR9XHJcblx0XHRpZiAodGltZU9wdHMudG9vbHRpcEZvcm1hdCkge1xyXG5cdFx0XHRyZXR1cm4gYWRhcHRlci5mb3JtYXQodG9UaW1lc3RhbXAobWUsIGxhYmVsKSwgdGltZU9wdHMudG9vbHRpcEZvcm1hdCk7XHJcblx0XHR9XHJcblx0XHRpZiAodHlwZW9mIGxhYmVsID09PSAnc3RyaW5nJykge1xyXG5cdFx0XHRyZXR1cm4gbGFiZWw7XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gYWRhcHRlci5mb3JtYXQodG9UaW1lc3RhbXAobWUsIGxhYmVsKSwgdGltZU9wdHMuZGlzcGxheUZvcm1hdHMuZGF0ZXRpbWUpO1xyXG5cdH0sXHJcblxyXG5cdC8qKlxyXG5cdCAqIEZ1bmN0aW9uIHRvIGZvcm1hdCBhbiBpbmRpdmlkdWFsIHRpY2sgbWFya1xyXG5cdCAqIEBwcml2YXRlXHJcblx0ICovXHJcblx0dGlja0Zvcm1hdEZ1bmN0aW9uOiBmdW5jdGlvbih0aW1lLCBpbmRleCwgdGlja3MsIGZvcm1hdCkge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHRcdHZhciBhZGFwdGVyID0gbWUuX2FkYXB0ZXI7XHJcblx0XHR2YXIgb3B0aW9ucyA9IG1lLm9wdGlvbnM7XHJcblx0XHR2YXIgZm9ybWF0cyA9IG9wdGlvbnMudGltZS5kaXNwbGF5Rm9ybWF0cztcclxuXHRcdHZhciBtaW5vckZvcm1hdCA9IGZvcm1hdHNbbWUuX3VuaXRdO1xyXG5cdFx0dmFyIG1ham9yVW5pdCA9IG1lLl9tYWpvclVuaXQ7XHJcblx0XHR2YXIgbWFqb3JGb3JtYXQgPSBmb3JtYXRzW21ham9yVW5pdF07XHJcblx0XHR2YXIgdGljayA9IHRpY2tzW2luZGV4XTtcclxuXHRcdHZhciB0aWNrT3B0cyA9IG9wdGlvbnMudGlja3M7XHJcblx0XHR2YXIgbWFqb3IgPSBtYWpvclVuaXQgJiYgbWFqb3JGb3JtYXQgJiYgdGljayAmJiB0aWNrLm1ham9yO1xyXG5cdFx0dmFyIGxhYmVsID0gYWRhcHRlci5mb3JtYXQodGltZSwgZm9ybWF0ID8gZm9ybWF0IDogbWFqb3IgPyBtYWpvckZvcm1hdCA6IG1pbm9yRm9ybWF0KTtcclxuXHRcdHZhciBuZXN0ZWRUaWNrT3B0cyA9IG1ham9yID8gdGlja09wdHMubWFqb3IgOiB0aWNrT3B0cy5taW5vcjtcclxuXHRcdHZhciBmb3JtYXR0ZXIgPSByZXNvbHZlJDUoW1xyXG5cdFx0XHRuZXN0ZWRUaWNrT3B0cy5jYWxsYmFjayxcclxuXHRcdFx0bmVzdGVkVGlja09wdHMudXNlckNhbGxiYWNrLFxyXG5cdFx0XHR0aWNrT3B0cy5jYWxsYmFjayxcclxuXHRcdFx0dGlja09wdHMudXNlckNhbGxiYWNrXHJcblx0XHRdKTtcclxuXHJcblx0XHRyZXR1cm4gZm9ybWF0dGVyID8gZm9ybWF0dGVyKGxhYmVsLCBpbmRleCwgdGlja3MpIDogbGFiZWw7XHJcblx0fSxcclxuXHJcblx0Y29udmVydFRpY2tzVG9MYWJlbHM6IGZ1bmN0aW9uKHRpY2tzKSB7XHJcblx0XHR2YXIgbGFiZWxzID0gW107XHJcblx0XHR2YXIgaSwgaWxlbjtcclxuXHJcblx0XHRmb3IgKGkgPSAwLCBpbGVuID0gdGlja3MubGVuZ3RoOyBpIDwgaWxlbjsgKytpKSB7XHJcblx0XHRcdGxhYmVscy5wdXNoKHRoaXMudGlja0Zvcm1hdEZ1bmN0aW9uKHRpY2tzW2ldLnZhbHVlLCBpLCB0aWNrcykpO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiBsYWJlbHM7XHJcblx0fSxcclxuXHJcblx0LyoqXHJcblx0ICogQHByaXZhdGVcclxuXHQgKi9cclxuXHRnZXRQaXhlbEZvck9mZnNldDogZnVuY3Rpb24odGltZSkge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHRcdHZhciBvZmZzZXRzID0gbWUuX29mZnNldHM7XHJcblx0XHR2YXIgcG9zID0gaW50ZXJwb2xhdGUkMShtZS5fdGFibGUsICd0aW1lJywgdGltZSwgJ3BvcycpO1xyXG5cdFx0cmV0dXJuIG1lLmdldFBpeGVsRm9yRGVjaW1hbCgob2Zmc2V0cy5zdGFydCArIHBvcykgKiBvZmZzZXRzLmZhY3Rvcik7XHJcblx0fSxcclxuXHJcblx0Z2V0UGl4ZWxGb3JWYWx1ZTogZnVuY3Rpb24odmFsdWUsIGluZGV4LCBkYXRhc2V0SW5kZXgpIHtcclxuXHRcdHZhciBtZSA9IHRoaXM7XHJcblx0XHR2YXIgdGltZSA9IG51bGw7XHJcblxyXG5cdFx0aWYgKGluZGV4ICE9PSB1bmRlZmluZWQgJiYgZGF0YXNldEluZGV4ICE9PSB1bmRlZmluZWQpIHtcclxuXHRcdFx0dGltZSA9IG1lLl90aW1lc3RhbXBzLmRhdGFzZXRzW2RhdGFzZXRJbmRleF1baW5kZXhdO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmICh0aW1lID09PSBudWxsKSB7XHJcblx0XHRcdHRpbWUgPSBwYXJzZShtZSwgdmFsdWUpO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmICh0aW1lICE9PSBudWxsKSB7XHJcblx0XHRcdHJldHVybiBtZS5nZXRQaXhlbEZvck9mZnNldCh0aW1lKTtcclxuXHRcdH1cclxuXHR9LFxyXG5cclxuXHRnZXRQaXhlbEZvclRpY2s6IGZ1bmN0aW9uKGluZGV4KSB7XHJcblx0XHR2YXIgdGlja3MgPSB0aGlzLmdldFRpY2tzKCk7XHJcblx0XHRyZXR1cm4gaW5kZXggPj0gMCAmJiBpbmRleCA8IHRpY2tzLmxlbmd0aCA/XHJcblx0XHRcdHRoaXMuZ2V0UGl4ZWxGb3JPZmZzZXQodGlja3NbaW5kZXhdLnZhbHVlKSA6XHJcblx0XHRcdG51bGw7XHJcblx0fSxcclxuXHJcblx0Z2V0VmFsdWVGb3JQaXhlbDogZnVuY3Rpb24ocGl4ZWwpIHtcclxuXHRcdHZhciBtZSA9IHRoaXM7XHJcblx0XHR2YXIgb2Zmc2V0cyA9IG1lLl9vZmZzZXRzO1xyXG5cdFx0dmFyIHBvcyA9IG1lLmdldERlY2ltYWxGb3JQaXhlbChwaXhlbCkgLyBvZmZzZXRzLmZhY3RvciAtIG9mZnNldHMuZW5kO1xyXG5cdFx0dmFyIHRpbWUgPSBpbnRlcnBvbGF0ZSQxKG1lLl90YWJsZSwgJ3BvcycsIHBvcywgJ3RpbWUnKTtcclxuXHJcblx0XHQvLyBERVBSRUNBVElPTiwgd2Ugc2hvdWxkIHJldHVybiB0aW1lIGRpcmVjdGx5XHJcblx0XHRyZXR1cm4gbWUuX2FkYXB0ZXIuX2NyZWF0ZSh0aW1lKTtcclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBAcHJpdmF0ZVxyXG5cdCAqL1xyXG5cdF9nZXRMYWJlbFNpemU6IGZ1bmN0aW9uKGxhYmVsKSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0dmFyIHRpY2tzT3B0cyA9IG1lLm9wdGlvbnMudGlja3M7XHJcblx0XHR2YXIgdGlja0xhYmVsV2lkdGggPSBtZS5jdHgubWVhc3VyZVRleHQobGFiZWwpLndpZHRoO1xyXG5cdFx0dmFyIGFuZ2xlID0gaGVscGVycyQxLnRvUmFkaWFucyhtZS5pc0hvcml6b250YWwoKSA/IHRpY2tzT3B0cy5tYXhSb3RhdGlvbiA6IHRpY2tzT3B0cy5taW5Sb3RhdGlvbik7XHJcblx0XHR2YXIgY29zUm90YXRpb24gPSBNYXRoLmNvcyhhbmdsZSk7XHJcblx0XHR2YXIgc2luUm90YXRpb24gPSBNYXRoLnNpbihhbmdsZSk7XHJcblx0XHR2YXIgdGlja0ZvbnRTaXplID0gdmFsdWVPckRlZmF1bHQkZCh0aWNrc09wdHMuZm9udFNpemUsIGNvcmVfZGVmYXVsdHMuZ2xvYmFsLmRlZmF1bHRGb250U2l6ZSk7XHJcblxyXG5cdFx0cmV0dXJuIHtcclxuXHRcdFx0dzogKHRpY2tMYWJlbFdpZHRoICogY29zUm90YXRpb24pICsgKHRpY2tGb250U2l6ZSAqIHNpblJvdGF0aW9uKSxcclxuXHRcdFx0aDogKHRpY2tMYWJlbFdpZHRoICogc2luUm90YXRpb24pICsgKHRpY2tGb250U2l6ZSAqIGNvc1JvdGF0aW9uKVxyXG5cdFx0fTtcclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBDcnVkZSBhcHByb3hpbWF0aW9uIG9mIHdoYXQgdGhlIGxhYmVsIHdpZHRoIG1pZ2h0IGJlXHJcblx0ICogQHByaXZhdGVcclxuXHQgKi9cclxuXHRnZXRMYWJlbFdpZHRoOiBmdW5jdGlvbihsYWJlbCkge1xyXG5cdFx0cmV0dXJuIHRoaXMuX2dldExhYmVsU2l6ZShsYWJlbCkudztcclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBAcHJpdmF0ZVxyXG5cdCAqL1xyXG5cdGdldExhYmVsQ2FwYWNpdHk6IGZ1bmN0aW9uKGV4YW1wbGVUaW1lKSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0dmFyIHRpbWVPcHRzID0gbWUub3B0aW9ucy50aW1lO1xyXG5cdFx0dmFyIGRpc3BsYXlGb3JtYXRzID0gdGltZU9wdHMuZGlzcGxheUZvcm1hdHM7XHJcblxyXG5cdFx0Ly8gcGljayB0aGUgbG9uZ2VzdCBmb3JtYXQgKG1pbGxpc2Vjb25kcykgZm9yIGd1ZXN0aW1hdGlvblxyXG5cdFx0dmFyIGZvcm1hdCA9IGRpc3BsYXlGb3JtYXRzW3RpbWVPcHRzLnVuaXRdIHx8IGRpc3BsYXlGb3JtYXRzLm1pbGxpc2Vjb25kO1xyXG5cdFx0dmFyIGV4YW1wbGVMYWJlbCA9IG1lLnRpY2tGb3JtYXRGdW5jdGlvbihleGFtcGxlVGltZSwgMCwgdGlja3NGcm9tVGltZXN0YW1wcyhtZSwgW2V4YW1wbGVUaW1lXSwgbWUuX21ham9yVW5pdCksIGZvcm1hdCk7XHJcblx0XHR2YXIgc2l6ZSA9IG1lLl9nZXRMYWJlbFNpemUoZXhhbXBsZUxhYmVsKTtcclxuXHRcdHZhciBjYXBhY2l0eSA9IE1hdGguZmxvb3IobWUuaXNIb3Jpem9udGFsKCkgPyBtZS53aWR0aCAvIHNpemUudyA6IG1lLmhlaWdodCAvIHNpemUuaCk7XHJcblxyXG5cdFx0aWYgKG1lLm9wdGlvbnMub2Zmc2V0KSB7XHJcblx0XHRcdGNhcGFjaXR5LS07XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIGNhcGFjaXR5ID4gMCA/IGNhcGFjaXR5IDogMTtcclxuXHR9XHJcbn0pO1xyXG5cclxuLy8gSU5URVJOQUw6IHN0YXRpYyBkZWZhdWx0IG9wdGlvbnMsIHJlZ2lzdGVyZWQgaW4gc3JjL2luZGV4LmpzXHJcbnZhciBfZGVmYXVsdHMkNCA9IGRlZmF1bHRDb25maWckNDtcbnNjYWxlX3RpbWUuX2RlZmF1bHRzID0gX2RlZmF1bHRzJDQ7XG5cbnZhciBzY2FsZXMgPSB7XHJcblx0Y2F0ZWdvcnk6IHNjYWxlX2NhdGVnb3J5LFxyXG5cdGxpbmVhcjogc2NhbGVfbGluZWFyLFxyXG5cdGxvZ2FyaXRobWljOiBzY2FsZV9sb2dhcml0aG1pYyxcclxuXHRyYWRpYWxMaW5lYXI6IHNjYWxlX3JhZGlhbExpbmVhcixcclxuXHR0aW1lOiBzY2FsZV90aW1lXHJcbn07XG5cbnZhciBGT1JNQVRTID0ge1xyXG5cdGRhdGV0aW1lOiAnTU1NIEQsIFlZWVksIGg6bW06c3MgYScsXHJcblx0bWlsbGlzZWNvbmQ6ICdoOm1tOnNzLlNTUyBhJyxcclxuXHRzZWNvbmQ6ICdoOm1tOnNzIGEnLFxyXG5cdG1pbnV0ZTogJ2g6bW0gYScsXHJcblx0aG91cjogJ2hBJyxcclxuXHRkYXk6ICdNTU0gRCcsXHJcblx0d2VlazogJ2xsJyxcclxuXHRtb250aDogJ01NTSBZWVlZJyxcclxuXHRxdWFydGVyOiAnW1FdUSAtIFlZWVknLFxyXG5cdHllYXI6ICdZWVlZJ1xyXG59O1xyXG5cclxuY29yZV9hZGFwdGVycy5fZGF0ZS5vdmVycmlkZSh0eXBlb2YgbW9tZW50ID09PSAnZnVuY3Rpb24nID8ge1xyXG5cdF9pZDogJ21vbWVudCcsIC8vIERFQlVHIE9OTFlcclxuXHJcblx0Zm9ybWF0czogZnVuY3Rpb24oKSB7XHJcblx0XHRyZXR1cm4gRk9STUFUUztcclxuXHR9LFxyXG5cclxuXHRwYXJzZTogZnVuY3Rpb24odmFsdWUsIGZvcm1hdCkge1xyXG5cdFx0aWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgJiYgdHlwZW9mIGZvcm1hdCA9PT0gJ3N0cmluZycpIHtcclxuXHRcdFx0dmFsdWUgPSBtb21lbnQodmFsdWUsIGZvcm1hdCk7XHJcblx0XHR9IGVsc2UgaWYgKCEodmFsdWUgaW5zdGFuY2VvZiBtb21lbnQpKSB7XHJcblx0XHRcdHZhbHVlID0gbW9tZW50KHZhbHVlKTtcclxuXHRcdH1cclxuXHRcdHJldHVybiB2YWx1ZS5pc1ZhbGlkKCkgPyB2YWx1ZS52YWx1ZU9mKCkgOiBudWxsO1xyXG5cdH0sXHJcblxyXG5cdGZvcm1hdDogZnVuY3Rpb24odGltZSwgZm9ybWF0KSB7XHJcblx0XHRyZXR1cm4gbW9tZW50KHRpbWUpLmZvcm1hdChmb3JtYXQpO1xyXG5cdH0sXHJcblxyXG5cdGFkZDogZnVuY3Rpb24odGltZSwgYW1vdW50LCB1bml0KSB7XHJcblx0XHRyZXR1cm4gbW9tZW50KHRpbWUpLmFkZChhbW91bnQsIHVuaXQpLnZhbHVlT2YoKTtcclxuXHR9LFxyXG5cclxuXHRkaWZmOiBmdW5jdGlvbihtYXgsIG1pbiwgdW5pdCkge1xyXG5cdFx0cmV0dXJuIG1vbWVudChtYXgpLmRpZmYobW9tZW50KG1pbiksIHVuaXQpO1xyXG5cdH0sXHJcblxyXG5cdHN0YXJ0T2Y6IGZ1bmN0aW9uKHRpbWUsIHVuaXQsIHdlZWtkYXkpIHtcclxuXHRcdHRpbWUgPSBtb21lbnQodGltZSk7XHJcblx0XHRpZiAodW5pdCA9PT0gJ2lzb1dlZWsnKSB7XHJcblx0XHRcdHJldHVybiB0aW1lLmlzb1dlZWtkYXkod2Vla2RheSkudmFsdWVPZigpO1xyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIHRpbWUuc3RhcnRPZih1bml0KS52YWx1ZU9mKCk7XHJcblx0fSxcclxuXHJcblx0ZW5kT2Y6IGZ1bmN0aW9uKHRpbWUsIHVuaXQpIHtcclxuXHRcdHJldHVybiBtb21lbnQodGltZSkuZW5kT2YodW5pdCkudmFsdWVPZigpO1xyXG5cdH0sXHJcblxyXG5cdC8vIERFUFJFQ0FUSU9OU1xyXG5cclxuXHQvKipcclxuXHQgKiBQcm92aWRlZCBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSB3aXRoIHNjYWxlLmdldFZhbHVlRm9yUGl4ZWwoKS5cclxuXHQgKiBAZGVwcmVjYXRlZCBzaW5jZSB2ZXJzaW9uIDIuOC4wXHJcblx0ICogQHRvZG8gcmVtb3ZlIGF0IHZlcnNpb24gM1xyXG5cdCAqIEBwcml2YXRlXHJcblx0ICovXHJcblx0X2NyZWF0ZTogZnVuY3Rpb24odGltZSkge1xyXG5cdFx0cmV0dXJuIG1vbWVudCh0aW1lKTtcclxuXHR9LFxyXG59IDoge30pO1xuXG5jb3JlX2RlZmF1bHRzLl9zZXQoJ2dsb2JhbCcsIHtcclxuXHRwbHVnaW5zOiB7XHJcblx0XHRmaWxsZXI6IHtcclxuXHRcdFx0cHJvcGFnYXRlOiB0cnVlXHJcblx0XHR9XHJcblx0fVxyXG59KTtcclxuXHJcbnZhciBtYXBwZXJzID0ge1xyXG5cdGRhdGFzZXQ6IGZ1bmN0aW9uKHNvdXJjZSkge1xyXG5cdFx0dmFyIGluZGV4ID0gc291cmNlLmZpbGw7XHJcblx0XHR2YXIgY2hhcnQgPSBzb3VyY2UuY2hhcnQ7XHJcblx0XHR2YXIgbWV0YSA9IGNoYXJ0LmdldERhdGFzZXRNZXRhKGluZGV4KTtcclxuXHRcdHZhciB2aXNpYmxlID0gbWV0YSAmJiBjaGFydC5pc0RhdGFzZXRWaXNpYmxlKGluZGV4KTtcclxuXHRcdHZhciBwb2ludHMgPSAodmlzaWJsZSAmJiBtZXRhLmRhdGFzZXQuX2NoaWxkcmVuKSB8fCBbXTtcclxuXHRcdHZhciBsZW5ndGggPSBwb2ludHMubGVuZ3RoIHx8IDA7XHJcblxyXG5cdFx0cmV0dXJuICFsZW5ndGggPyBudWxsIDogZnVuY3Rpb24ocG9pbnQsIGkpIHtcclxuXHRcdFx0cmV0dXJuIChpIDwgbGVuZ3RoICYmIHBvaW50c1tpXS5fdmlldykgfHwgbnVsbDtcclxuXHRcdH07XHJcblx0fSxcclxuXHJcblx0Ym91bmRhcnk6IGZ1bmN0aW9uKHNvdXJjZSkge1xyXG5cdFx0dmFyIGJvdW5kYXJ5ID0gc291cmNlLmJvdW5kYXJ5O1xyXG5cdFx0dmFyIHggPSBib3VuZGFyeSA/IGJvdW5kYXJ5LnggOiBudWxsO1xyXG5cdFx0dmFyIHkgPSBib3VuZGFyeSA/IGJvdW5kYXJ5LnkgOiBudWxsO1xyXG5cclxuXHRcdGlmIChoZWxwZXJzJDEuaXNBcnJheShib3VuZGFyeSkpIHtcclxuXHRcdFx0cmV0dXJuIGZ1bmN0aW9uKHBvaW50LCBpKSB7XHJcblx0XHRcdFx0cmV0dXJuIGJvdW5kYXJ5W2ldO1xyXG5cdFx0XHR9O1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiBmdW5jdGlvbihwb2ludCkge1xyXG5cdFx0XHRyZXR1cm4ge1xyXG5cdFx0XHRcdHg6IHggPT09IG51bGwgPyBwb2ludC54IDogeCxcclxuXHRcdFx0XHR5OiB5ID09PSBudWxsID8gcG9pbnQueSA6IHksXHJcblx0XHRcdH07XHJcblx0XHR9O1xyXG5cdH1cclxufTtcclxuXHJcbi8vIEB0b2RvIGlmIChmaWxsWzBdID09PSAnIycpXHJcbmZ1bmN0aW9uIGRlY29kZUZpbGwoZWwsIGluZGV4LCBjb3VudCkge1xyXG5cdHZhciBtb2RlbCA9IGVsLl9tb2RlbCB8fCB7fTtcclxuXHR2YXIgZmlsbCA9IG1vZGVsLmZpbGw7XHJcblx0dmFyIHRhcmdldDtcclxuXHJcblx0aWYgKGZpbGwgPT09IHVuZGVmaW5lZCkge1xyXG5cdFx0ZmlsbCA9ICEhbW9kZWwuYmFja2dyb3VuZENvbG9yO1xyXG5cdH1cclxuXHJcblx0aWYgKGZpbGwgPT09IGZhbHNlIHx8IGZpbGwgPT09IG51bGwpIHtcclxuXHRcdHJldHVybiBmYWxzZTtcclxuXHR9XHJcblxyXG5cdGlmIChmaWxsID09PSB0cnVlKSB7XHJcblx0XHRyZXR1cm4gJ29yaWdpbic7XHJcblx0fVxyXG5cclxuXHR0YXJnZXQgPSBwYXJzZUZsb2F0KGZpbGwsIDEwKTtcclxuXHRpZiAoaXNGaW5pdGUodGFyZ2V0KSAmJiBNYXRoLmZsb29yKHRhcmdldCkgPT09IHRhcmdldCkge1xyXG5cdFx0aWYgKGZpbGxbMF0gPT09ICctJyB8fCBmaWxsWzBdID09PSAnKycpIHtcclxuXHRcdFx0dGFyZ2V0ID0gaW5kZXggKyB0YXJnZXQ7XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKHRhcmdldCA9PT0gaW5kZXggfHwgdGFyZ2V0IDwgMCB8fCB0YXJnZXQgPj0gY291bnQpIHtcclxuXHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiB0YXJnZXQ7XHJcblx0fVxyXG5cclxuXHRzd2l0Y2ggKGZpbGwpIHtcclxuXHQvLyBjb21wYXRpYmlsaXR5XHJcblx0Y2FzZSAnYm90dG9tJzpcclxuXHRcdHJldHVybiAnc3RhcnQnO1xyXG5cdGNhc2UgJ3RvcCc6XHJcblx0XHRyZXR1cm4gJ2VuZCc7XHJcblx0Y2FzZSAnemVybyc6XHJcblx0XHRyZXR1cm4gJ29yaWdpbic7XHJcblx0Ly8gc3VwcG9ydGVkIGJvdW5kYXJpZXNcclxuXHRjYXNlICdvcmlnaW4nOlxyXG5cdGNhc2UgJ3N0YXJ0JzpcclxuXHRjYXNlICdlbmQnOlxyXG5cdFx0cmV0dXJuIGZpbGw7XHJcblx0Ly8gaW52YWxpZCBmaWxsIHZhbHVlc1xyXG5cdGRlZmF1bHQ6XHJcblx0XHRyZXR1cm4gZmFsc2U7XHJcblx0fVxyXG59XHJcblxyXG5mdW5jdGlvbiBjb21wdXRlTGluZWFyQm91bmRhcnkoc291cmNlKSB7XHJcblx0dmFyIG1vZGVsID0gc291cmNlLmVsLl9tb2RlbCB8fCB7fTtcclxuXHR2YXIgc2NhbGUgPSBzb3VyY2UuZWwuX3NjYWxlIHx8IHt9O1xyXG5cdHZhciBmaWxsID0gc291cmNlLmZpbGw7XHJcblx0dmFyIHRhcmdldCA9IG51bGw7XHJcblx0dmFyIGhvcml6b250YWw7XHJcblxyXG5cdGlmIChpc0Zpbml0ZShmaWxsKSkge1xyXG5cdFx0cmV0dXJuIG51bGw7XHJcblx0fVxyXG5cclxuXHQvLyBCYWNrd2FyZCBjb21wYXRpYmlsaXR5OiB1bnRpbCB2Mywgd2Ugc3RpbGwgbmVlZCB0byBzdXBwb3J0IGJvdW5kYXJ5IHZhbHVlcyBzZXQgb25cclxuXHQvLyB0aGUgbW9kZWwgKHNjYWxlVG9wLCBzY2FsZUJvdHRvbSBhbmQgc2NhbGVaZXJvKSBiZWNhdXNlIHNvbWUgZXh0ZXJuYWwgcGx1Z2lucyBhbmRcclxuXHQvLyBjb250cm9sbGVycyBtaWdodCBzdGlsbCB1c2UgaXQgKGUuZy4gdGhlIFNtaXRoIGNoYXJ0KS5cclxuXHJcblx0aWYgKGZpbGwgPT09ICdzdGFydCcpIHtcclxuXHRcdHRhcmdldCA9IG1vZGVsLnNjYWxlQm90dG9tID09PSB1bmRlZmluZWQgPyBzY2FsZS5ib3R0b20gOiBtb2RlbC5zY2FsZUJvdHRvbTtcclxuXHR9IGVsc2UgaWYgKGZpbGwgPT09ICdlbmQnKSB7XHJcblx0XHR0YXJnZXQgPSBtb2RlbC5zY2FsZVRvcCA9PT0gdW5kZWZpbmVkID8gc2NhbGUudG9wIDogbW9kZWwuc2NhbGVUb3A7XHJcblx0fSBlbHNlIGlmIChtb2RlbC5zY2FsZVplcm8gIT09IHVuZGVmaW5lZCkge1xyXG5cdFx0dGFyZ2V0ID0gbW9kZWwuc2NhbGVaZXJvO1xyXG5cdH0gZWxzZSBpZiAoc2NhbGUuZ2V0QmFzZVBpeGVsKSB7XHJcblx0XHR0YXJnZXQgPSBzY2FsZS5nZXRCYXNlUGl4ZWwoKTtcclxuXHR9XHJcblxyXG5cdGlmICh0YXJnZXQgIT09IHVuZGVmaW5lZCAmJiB0YXJnZXQgIT09IG51bGwpIHtcclxuXHRcdGlmICh0YXJnZXQueCAhPT0gdW5kZWZpbmVkICYmIHRhcmdldC55ICE9PSB1bmRlZmluZWQpIHtcclxuXHRcdFx0cmV0dXJuIHRhcmdldDtcclxuXHRcdH1cclxuXHJcblx0XHRpZiAoaGVscGVycyQxLmlzRmluaXRlKHRhcmdldCkpIHtcclxuXHRcdFx0aG9yaXpvbnRhbCA9IHNjYWxlLmlzSG9yaXpvbnRhbCgpO1xyXG5cdFx0XHRyZXR1cm4ge1xyXG5cdFx0XHRcdHg6IGhvcml6b250YWwgPyB0YXJnZXQgOiBudWxsLFxyXG5cdFx0XHRcdHk6IGhvcml6b250YWwgPyBudWxsIDogdGFyZ2V0XHJcblx0XHRcdH07XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRyZXR1cm4gbnVsbDtcclxufVxyXG5cclxuZnVuY3Rpb24gY29tcHV0ZUNpcmN1bGFyQm91bmRhcnkoc291cmNlKSB7XHJcblx0dmFyIHNjYWxlID0gc291cmNlLmVsLl9zY2FsZTtcclxuXHR2YXIgb3B0aW9ucyA9IHNjYWxlLm9wdGlvbnM7XHJcblx0dmFyIGxlbmd0aCA9IHNjYWxlLmNoYXJ0LmRhdGEubGFiZWxzLmxlbmd0aDtcclxuXHR2YXIgZmlsbCA9IHNvdXJjZS5maWxsO1xyXG5cdHZhciB0YXJnZXQgPSBbXTtcclxuXHR2YXIgc3RhcnQsIGVuZCwgY2VudGVyLCBpLCBwb2ludDtcclxuXHJcblx0aWYgKCFsZW5ndGgpIHtcclxuXHRcdHJldHVybiBudWxsO1xyXG5cdH1cclxuXHJcblx0c3RhcnQgPSBvcHRpb25zLnRpY2tzLnJldmVyc2UgPyBzY2FsZS5tYXggOiBzY2FsZS5taW47XHJcblx0ZW5kID0gb3B0aW9ucy50aWNrcy5yZXZlcnNlID8gc2NhbGUubWluIDogc2NhbGUubWF4O1xyXG5cdGNlbnRlciA9IHNjYWxlLmdldFBvaW50UG9zaXRpb25Gb3JWYWx1ZSgwLCBzdGFydCk7XHJcblx0Zm9yIChpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7XHJcblx0XHRwb2ludCA9IGZpbGwgPT09ICdzdGFydCcgfHwgZmlsbCA9PT0gJ2VuZCdcclxuXHRcdFx0PyBzY2FsZS5nZXRQb2ludFBvc2l0aW9uRm9yVmFsdWUoaSwgZmlsbCA9PT0gJ3N0YXJ0JyA/IHN0YXJ0IDogZW5kKVxyXG5cdFx0XHQ6IHNjYWxlLmdldEJhc2VQb3NpdGlvbihpKTtcclxuXHRcdGlmIChvcHRpb25zLmdyaWRMaW5lcy5jaXJjdWxhcikge1xyXG5cdFx0XHRwb2ludC5jeCA9IGNlbnRlci54O1xyXG5cdFx0XHRwb2ludC5jeSA9IGNlbnRlci55O1xyXG5cdFx0XHRwb2ludC5hbmdsZSA9IHNjYWxlLmdldEluZGV4QW5nbGUoaSkgLSBNYXRoLlBJIC8gMjtcclxuXHRcdH1cclxuXHRcdHRhcmdldC5wdXNoKHBvaW50KTtcclxuXHR9XHJcblx0cmV0dXJuIHRhcmdldDtcclxufVxyXG5cclxuZnVuY3Rpb24gY29tcHV0ZUJvdW5kYXJ5KHNvdXJjZSkge1xyXG5cdHZhciBzY2FsZSA9IHNvdXJjZS5lbC5fc2NhbGUgfHwge307XHJcblxyXG5cdGlmIChzY2FsZS5nZXRQb2ludFBvc2l0aW9uRm9yVmFsdWUpIHtcclxuXHRcdHJldHVybiBjb21wdXRlQ2lyY3VsYXJCb3VuZGFyeShzb3VyY2UpO1xyXG5cdH1cclxuXHRyZXR1cm4gY29tcHV0ZUxpbmVhckJvdW5kYXJ5KHNvdXJjZSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHJlc29sdmVUYXJnZXQoc291cmNlcywgaW5kZXgsIHByb3BhZ2F0ZSkge1xyXG5cdHZhciBzb3VyY2UgPSBzb3VyY2VzW2luZGV4XTtcclxuXHR2YXIgZmlsbCA9IHNvdXJjZS5maWxsO1xyXG5cdHZhciB2aXNpdGVkID0gW2luZGV4XTtcclxuXHR2YXIgdGFyZ2V0O1xyXG5cclxuXHRpZiAoIXByb3BhZ2F0ZSkge1xyXG5cdFx0cmV0dXJuIGZpbGw7XHJcblx0fVxyXG5cclxuXHR3aGlsZSAoZmlsbCAhPT0gZmFsc2UgJiYgdmlzaXRlZC5pbmRleE9mKGZpbGwpID09PSAtMSkge1xyXG5cdFx0aWYgKCFpc0Zpbml0ZShmaWxsKSkge1xyXG5cdFx0XHRyZXR1cm4gZmlsbDtcclxuXHRcdH1cclxuXHJcblx0XHR0YXJnZXQgPSBzb3VyY2VzW2ZpbGxdO1xyXG5cdFx0aWYgKCF0YXJnZXQpIHtcclxuXHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmICh0YXJnZXQudmlzaWJsZSkge1xyXG5cdFx0XHRyZXR1cm4gZmlsbDtcclxuXHRcdH1cclxuXHJcblx0XHR2aXNpdGVkLnB1c2goZmlsbCk7XHJcblx0XHRmaWxsID0gdGFyZ2V0LmZpbGw7XHJcblx0fVxyXG5cclxuXHRyZXR1cm4gZmFsc2U7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGNyZWF0ZU1hcHBlcihzb3VyY2UpIHtcclxuXHR2YXIgZmlsbCA9IHNvdXJjZS5maWxsO1xyXG5cdHZhciB0eXBlID0gJ2RhdGFzZXQnO1xyXG5cclxuXHRpZiAoZmlsbCA9PT0gZmFsc2UpIHtcclxuXHRcdHJldHVybiBudWxsO1xyXG5cdH1cclxuXHJcblx0aWYgKCFpc0Zpbml0ZShmaWxsKSkge1xyXG5cdFx0dHlwZSA9ICdib3VuZGFyeSc7XHJcblx0fVxyXG5cclxuXHRyZXR1cm4gbWFwcGVyc1t0eXBlXShzb3VyY2UpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBpc0RyYXdhYmxlKHBvaW50KSB7XHJcblx0cmV0dXJuIHBvaW50ICYmICFwb2ludC5za2lwO1xyXG59XHJcblxyXG5mdW5jdGlvbiBkcmF3QXJlYShjdHgsIGN1cnZlMCwgY3VydmUxLCBsZW4wLCBsZW4xKSB7XHJcblx0dmFyIGksIGN4LCBjeSwgcjtcclxuXHJcblx0aWYgKCFsZW4wIHx8ICFsZW4xKSB7XHJcblx0XHRyZXR1cm47XHJcblx0fVxyXG5cclxuXHQvLyBidWlsZGluZyBmaXJzdCBhcmVhIGN1cnZlIChub3JtYWwpXHJcblx0Y3R4Lm1vdmVUbyhjdXJ2ZTBbMF0ueCwgY3VydmUwWzBdLnkpO1xyXG5cdGZvciAoaSA9IDE7IGkgPCBsZW4wOyArK2kpIHtcclxuXHRcdGhlbHBlcnMkMS5jYW52YXMubGluZVRvKGN0eCwgY3VydmUwW2kgLSAxXSwgY3VydmUwW2ldKTtcclxuXHR9XHJcblxyXG5cdGlmIChjdXJ2ZTFbMF0uYW5nbGUgIT09IHVuZGVmaW5lZCkge1xyXG5cdFx0Y3ggPSBjdXJ2ZTFbMF0uY3g7XHJcblx0XHRjeSA9IGN1cnZlMVswXS5jeTtcclxuXHRcdHIgPSBNYXRoLnNxcnQoTWF0aC5wb3coY3VydmUxWzBdLnggLSBjeCwgMikgKyBNYXRoLnBvdyhjdXJ2ZTFbMF0ueSAtIGN5LCAyKSk7XHJcblx0XHRmb3IgKGkgPSBsZW4xIC0gMTsgaSA+IDA7IC0taSkge1xyXG5cdFx0XHRjdHguYXJjKGN4LCBjeSwgciwgY3VydmUxW2ldLmFuZ2xlLCBjdXJ2ZTFbaSAtIDFdLmFuZ2xlLCB0cnVlKTtcclxuXHRcdH1cclxuXHRcdHJldHVybjtcclxuXHR9XHJcblxyXG5cdC8vIGpvaW5pbmcgdGhlIHR3byBhcmVhIGN1cnZlc1xyXG5cdGN0eC5saW5lVG8oY3VydmUxW2xlbjEgLSAxXS54LCBjdXJ2ZTFbbGVuMSAtIDFdLnkpO1xyXG5cclxuXHQvLyBidWlsZGluZyBvcHBvc2l0ZSBhcmVhIGN1cnZlIChyZXZlcnNlKVxyXG5cdGZvciAoaSA9IGxlbjEgLSAxOyBpID4gMDsgLS1pKSB7XHJcblx0XHRoZWxwZXJzJDEuY2FudmFzLmxpbmVUbyhjdHgsIGN1cnZlMVtpXSwgY3VydmUxW2kgLSAxXSwgdHJ1ZSk7XHJcblx0fVxyXG59XHJcblxyXG5mdW5jdGlvbiBkb0ZpbGwoY3R4LCBwb2ludHMsIG1hcHBlciwgdmlldywgY29sb3IsIGxvb3ApIHtcclxuXHR2YXIgY291bnQgPSBwb2ludHMubGVuZ3RoO1xyXG5cdHZhciBzcGFuID0gdmlldy5zcGFuR2FwcztcclxuXHR2YXIgY3VydmUwID0gW107XHJcblx0dmFyIGN1cnZlMSA9IFtdO1xyXG5cdHZhciBsZW4wID0gMDtcclxuXHR2YXIgbGVuMSA9IDA7XHJcblx0dmFyIGksIGlsZW4sIGluZGV4LCBwMCwgcDEsIGQwLCBkMSwgbG9vcE9mZnNldDtcclxuXHJcblx0Y3R4LmJlZ2luUGF0aCgpO1xyXG5cclxuXHRmb3IgKGkgPSAwLCBpbGVuID0gY291bnQ7IGkgPCBpbGVuOyArK2kpIHtcclxuXHRcdGluZGV4ID0gaSAlIGNvdW50O1xyXG5cdFx0cDAgPSBwb2ludHNbaW5kZXhdLl92aWV3O1xyXG5cdFx0cDEgPSBtYXBwZXIocDAsIGluZGV4LCB2aWV3KTtcclxuXHRcdGQwID0gaXNEcmF3YWJsZShwMCk7XHJcblx0XHRkMSA9IGlzRHJhd2FibGUocDEpO1xyXG5cclxuXHRcdGlmIChsb29wICYmIGxvb3BPZmZzZXQgPT09IHVuZGVmaW5lZCAmJiBkMCkge1xyXG5cdFx0XHRsb29wT2Zmc2V0ID0gaSArIDE7XHJcblx0XHRcdGlsZW4gPSBjb3VudCArIGxvb3BPZmZzZXQ7XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKGQwICYmIGQxKSB7XHJcblx0XHRcdGxlbjAgPSBjdXJ2ZTAucHVzaChwMCk7XHJcblx0XHRcdGxlbjEgPSBjdXJ2ZTEucHVzaChwMSk7XHJcblx0XHR9IGVsc2UgaWYgKGxlbjAgJiYgbGVuMSkge1xyXG5cdFx0XHRpZiAoIXNwYW4pIHtcclxuXHRcdFx0XHRkcmF3QXJlYShjdHgsIGN1cnZlMCwgY3VydmUxLCBsZW4wLCBsZW4xKTtcclxuXHRcdFx0XHRsZW4wID0gbGVuMSA9IDA7XHJcblx0XHRcdFx0Y3VydmUwID0gW107XHJcblx0XHRcdFx0Y3VydmUxID0gW107XHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0aWYgKGQwKSB7XHJcblx0XHRcdFx0XHRjdXJ2ZTAucHVzaChwMCk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdGlmIChkMSkge1xyXG5cdFx0XHRcdFx0Y3VydmUxLnB1c2gocDEpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0ZHJhd0FyZWEoY3R4LCBjdXJ2ZTAsIGN1cnZlMSwgbGVuMCwgbGVuMSk7XHJcblxyXG5cdGN0eC5jbG9zZVBhdGgoKTtcclxuXHRjdHguZmlsbFN0eWxlID0gY29sb3I7XHJcblx0Y3R4LmZpbGwoKTtcclxufVxyXG5cclxudmFyIHBsdWdpbl9maWxsZXIgPSB7XHJcblx0aWQ6ICdmaWxsZXInLFxyXG5cclxuXHRhZnRlckRhdGFzZXRzVXBkYXRlOiBmdW5jdGlvbihjaGFydCwgb3B0aW9ucykge1xyXG5cdFx0dmFyIGNvdW50ID0gKGNoYXJ0LmRhdGEuZGF0YXNldHMgfHwgW10pLmxlbmd0aDtcclxuXHRcdHZhciBwcm9wYWdhdGUgPSBvcHRpb25zLnByb3BhZ2F0ZTtcclxuXHRcdHZhciBzb3VyY2VzID0gW107XHJcblx0XHR2YXIgbWV0YSwgaSwgZWwsIHNvdXJjZTtcclxuXHJcblx0XHRmb3IgKGkgPSAwOyBpIDwgY291bnQ7ICsraSkge1xyXG5cdFx0XHRtZXRhID0gY2hhcnQuZ2V0RGF0YXNldE1ldGEoaSk7XHJcblx0XHRcdGVsID0gbWV0YS5kYXRhc2V0O1xyXG5cdFx0XHRzb3VyY2UgPSBudWxsO1xyXG5cclxuXHRcdFx0aWYgKGVsICYmIGVsLl9tb2RlbCAmJiBlbCBpbnN0YW5jZW9mIGVsZW1lbnRzLkxpbmUpIHtcclxuXHRcdFx0XHRzb3VyY2UgPSB7XHJcblx0XHRcdFx0XHR2aXNpYmxlOiBjaGFydC5pc0RhdGFzZXRWaXNpYmxlKGkpLFxyXG5cdFx0XHRcdFx0ZmlsbDogZGVjb2RlRmlsbChlbCwgaSwgY291bnQpLFxyXG5cdFx0XHRcdFx0Y2hhcnQ6IGNoYXJ0LFxyXG5cdFx0XHRcdFx0ZWw6IGVsXHJcblx0XHRcdFx0fTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0bWV0YS4kZmlsbGVyID0gc291cmNlO1xyXG5cdFx0XHRzb3VyY2VzLnB1c2goc291cmNlKTtcclxuXHRcdH1cclxuXHJcblx0XHRmb3IgKGkgPSAwOyBpIDwgY291bnQ7ICsraSkge1xyXG5cdFx0XHRzb3VyY2UgPSBzb3VyY2VzW2ldO1xyXG5cdFx0XHRpZiAoIXNvdXJjZSkge1xyXG5cdFx0XHRcdGNvbnRpbnVlO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRzb3VyY2UuZmlsbCA9IHJlc29sdmVUYXJnZXQoc291cmNlcywgaSwgcHJvcGFnYXRlKTtcclxuXHRcdFx0c291cmNlLmJvdW5kYXJ5ID0gY29tcHV0ZUJvdW5kYXJ5KHNvdXJjZSk7XHJcblx0XHRcdHNvdXJjZS5tYXBwZXIgPSBjcmVhdGVNYXBwZXIoc291cmNlKTtcclxuXHRcdH1cclxuXHR9LFxyXG5cclxuXHRiZWZvcmVEYXRhc2V0c0RyYXc6IGZ1bmN0aW9uKGNoYXJ0KSB7XHJcblx0XHR2YXIgbWV0YXNldHMgPSBjaGFydC5fZ2V0U29ydGVkVmlzaWJsZURhdGFzZXRNZXRhcygpO1xyXG5cdFx0dmFyIGN0eCA9IGNoYXJ0LmN0eDtcclxuXHRcdHZhciBtZXRhLCBpLCBlbCwgdmlldywgcG9pbnRzLCBtYXBwZXIsIGNvbG9yO1xyXG5cclxuXHRcdGZvciAoaSA9IG1ldGFzZXRzLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7XHJcblx0XHRcdG1ldGEgPSBtZXRhc2V0c1tpXS4kZmlsbGVyO1xyXG5cclxuXHRcdFx0aWYgKCFtZXRhIHx8ICFtZXRhLnZpc2libGUpIHtcclxuXHRcdFx0XHRjb250aW51ZTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0ZWwgPSBtZXRhLmVsO1xyXG5cdFx0XHR2aWV3ID0gZWwuX3ZpZXc7XHJcblx0XHRcdHBvaW50cyA9IGVsLl9jaGlsZHJlbiB8fCBbXTtcclxuXHRcdFx0bWFwcGVyID0gbWV0YS5tYXBwZXI7XHJcblx0XHRcdGNvbG9yID0gdmlldy5iYWNrZ3JvdW5kQ29sb3IgfHwgY29yZV9kZWZhdWx0cy5nbG9iYWwuZGVmYXVsdENvbG9yO1xyXG5cclxuXHRcdFx0aWYgKG1hcHBlciAmJiBjb2xvciAmJiBwb2ludHMubGVuZ3RoKSB7XHJcblx0XHRcdFx0aGVscGVycyQxLmNhbnZhcy5jbGlwQXJlYShjdHgsIGNoYXJ0LmNoYXJ0QXJlYSk7XHJcblx0XHRcdFx0ZG9GaWxsKGN0eCwgcG9pbnRzLCBtYXBwZXIsIHZpZXcsIGNvbG9yLCBlbC5fbG9vcCk7XHJcblx0XHRcdFx0aGVscGVycyQxLmNhbnZhcy51bmNsaXBBcmVhKGN0eCk7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHR9XHJcbn07XG5cbnZhciBnZXRSdGxIZWxwZXIkMSA9IGhlbHBlcnMkMS5ydGwuZ2V0UnRsQWRhcHRlcjtcclxudmFyIG5vb3AkMSA9IGhlbHBlcnMkMS5ub29wO1xyXG52YXIgdmFsdWVPckRlZmF1bHQkZSA9IGhlbHBlcnMkMS52YWx1ZU9yRGVmYXVsdDtcclxuXHJcbmNvcmVfZGVmYXVsdHMuX3NldCgnZ2xvYmFsJywge1xyXG5cdGxlZ2VuZDoge1xyXG5cdFx0ZGlzcGxheTogdHJ1ZSxcclxuXHRcdHBvc2l0aW9uOiAndG9wJyxcclxuXHRcdGFsaWduOiAnY2VudGVyJyxcclxuXHRcdGZ1bGxXaWR0aDogdHJ1ZSxcclxuXHRcdHJldmVyc2U6IGZhbHNlLFxyXG5cdFx0d2VpZ2h0OiAxMDAwLFxyXG5cclxuXHRcdC8vIGEgY2FsbGJhY2sgdGhhdCB3aWxsIGhhbmRsZVxyXG5cdFx0b25DbGljazogZnVuY3Rpb24oZSwgbGVnZW5kSXRlbSkge1xyXG5cdFx0XHR2YXIgaW5kZXggPSBsZWdlbmRJdGVtLmRhdGFzZXRJbmRleDtcclxuXHRcdFx0dmFyIGNpID0gdGhpcy5jaGFydDtcclxuXHRcdFx0dmFyIG1ldGEgPSBjaS5nZXREYXRhc2V0TWV0YShpbmRleCk7XHJcblxyXG5cdFx0XHQvLyBTZWUgY29udHJvbGxlci5pc0RhdGFzZXRWaXNpYmxlIGNvbW1lbnRcclxuXHRcdFx0bWV0YS5oaWRkZW4gPSBtZXRhLmhpZGRlbiA9PT0gbnVsbCA/ICFjaS5kYXRhLmRhdGFzZXRzW2luZGV4XS5oaWRkZW4gOiBudWxsO1xyXG5cclxuXHRcdFx0Ly8gV2UgaGlkIGEgZGF0YXNldCAuLi4gcmVyZW5kZXIgdGhlIGNoYXJ0XHJcblx0XHRcdGNpLnVwZGF0ZSgpO1xyXG5cdFx0fSxcclxuXHJcblx0XHRvbkhvdmVyOiBudWxsLFxyXG5cdFx0b25MZWF2ZTogbnVsbCxcclxuXHJcblx0XHRsYWJlbHM6IHtcclxuXHRcdFx0Ym94V2lkdGg6IDQwLFxyXG5cdFx0XHRwYWRkaW5nOiAxMCxcclxuXHRcdFx0Ly8gR2VuZXJhdGVzIGxhYmVscyBzaG93biBpbiB0aGUgbGVnZW5kXHJcblx0XHRcdC8vIFZhbGlkIHByb3BlcnRpZXMgdG8gcmV0dXJuOlxyXG5cdFx0XHQvLyB0ZXh0IDogdGV4dCB0byBkaXNwbGF5XHJcblx0XHRcdC8vIGZpbGxTdHlsZSA6IGZpbGwgb2YgY29sb3VyZWQgYm94XHJcblx0XHRcdC8vIHN0cm9rZVN0eWxlOiBzdHJva2Ugb2YgY29sb3VyZWQgYm94XHJcblx0XHRcdC8vIGhpZGRlbiA6IGlmIHRoaXMgbGVnZW5kIGl0ZW0gcmVmZXJzIHRvIGEgaGlkZGVuIGl0ZW1cclxuXHRcdFx0Ly8gbGluZUNhcCA6IGNhcCBzdHlsZSBmb3IgbGluZVxyXG5cdFx0XHQvLyBsaW5lRGFzaFxyXG5cdFx0XHQvLyBsaW5lRGFzaE9mZnNldCA6XHJcblx0XHRcdC8vIGxpbmVKb2luIDpcclxuXHRcdFx0Ly8gbGluZVdpZHRoIDpcclxuXHRcdFx0Z2VuZXJhdGVMYWJlbHM6IGZ1bmN0aW9uKGNoYXJ0KSB7XHJcblx0XHRcdFx0dmFyIGRhdGFzZXRzID0gY2hhcnQuZGF0YS5kYXRhc2V0cztcclxuXHRcdFx0XHR2YXIgb3B0aW9ucyA9IGNoYXJ0Lm9wdGlvbnMubGVnZW5kIHx8IHt9O1xyXG5cdFx0XHRcdHZhciB1c2VQb2ludFN0eWxlID0gb3B0aW9ucy5sYWJlbHMgJiYgb3B0aW9ucy5sYWJlbHMudXNlUG9pbnRTdHlsZTtcclxuXHJcblx0XHRcdFx0cmV0dXJuIGNoYXJ0Ll9nZXRTb3J0ZWREYXRhc2V0TWV0YXMoKS5tYXAoZnVuY3Rpb24obWV0YSkge1xyXG5cdFx0XHRcdFx0dmFyIHN0eWxlID0gbWV0YS5jb250cm9sbGVyLmdldFN0eWxlKHVzZVBvaW50U3R5bGUgPyAwIDogdW5kZWZpbmVkKTtcclxuXHJcblx0XHRcdFx0XHRyZXR1cm4ge1xyXG5cdFx0XHRcdFx0XHR0ZXh0OiBkYXRhc2V0c1ttZXRhLmluZGV4XS5sYWJlbCxcclxuXHRcdFx0XHRcdFx0ZmlsbFN0eWxlOiBzdHlsZS5iYWNrZ3JvdW5kQ29sb3IsXHJcblx0XHRcdFx0XHRcdGhpZGRlbjogIWNoYXJ0LmlzRGF0YXNldFZpc2libGUobWV0YS5pbmRleCksXHJcblx0XHRcdFx0XHRcdGxpbmVDYXA6IHN0eWxlLmJvcmRlckNhcFN0eWxlLFxyXG5cdFx0XHRcdFx0XHRsaW5lRGFzaDogc3R5bGUuYm9yZGVyRGFzaCxcclxuXHRcdFx0XHRcdFx0bGluZURhc2hPZmZzZXQ6IHN0eWxlLmJvcmRlckRhc2hPZmZzZXQsXHJcblx0XHRcdFx0XHRcdGxpbmVKb2luOiBzdHlsZS5ib3JkZXJKb2luU3R5bGUsXHJcblx0XHRcdFx0XHRcdGxpbmVXaWR0aDogc3R5bGUuYm9yZGVyV2lkdGgsXHJcblx0XHRcdFx0XHRcdHN0cm9rZVN0eWxlOiBzdHlsZS5ib3JkZXJDb2xvcixcclxuXHRcdFx0XHRcdFx0cG9pbnRTdHlsZTogc3R5bGUucG9pbnRTdHlsZSxcclxuXHRcdFx0XHRcdFx0cm90YXRpb246IHN0eWxlLnJvdGF0aW9uLFxyXG5cclxuXHRcdFx0XHRcdFx0Ly8gQmVsb3cgaXMgZXh0cmEgZGF0YSB1c2VkIGZvciB0b2dnbGluZyB0aGUgZGF0YXNldHNcclxuXHRcdFx0XHRcdFx0ZGF0YXNldEluZGV4OiBtZXRhLmluZGV4XHJcblx0XHRcdFx0XHR9O1xyXG5cdFx0XHRcdH0sIHRoaXMpO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0fSxcclxuXHJcblx0bGVnZW5kQ2FsbGJhY2s6IGZ1bmN0aW9uKGNoYXJ0KSB7XHJcblx0XHR2YXIgbGlzdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3VsJyk7XHJcblx0XHR2YXIgZGF0YXNldHMgPSBjaGFydC5kYXRhLmRhdGFzZXRzO1xyXG5cdFx0dmFyIGksIGlsZW4sIGxpc3RJdGVtLCBsaXN0SXRlbVNwYW47XHJcblxyXG5cdFx0bGlzdC5zZXRBdHRyaWJ1dGUoJ2NsYXNzJywgY2hhcnQuaWQgKyAnLWxlZ2VuZCcpO1xyXG5cclxuXHRcdGZvciAoaSA9IDAsIGlsZW4gPSBkYXRhc2V0cy5sZW5ndGg7IGkgPCBpbGVuOyBpKyspIHtcclxuXHRcdFx0bGlzdEl0ZW0gPSBsaXN0LmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2xpJykpO1xyXG5cdFx0XHRsaXN0SXRlbVNwYW4gPSBsaXN0SXRlbS5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJykpO1xyXG5cdFx0XHRsaXN0SXRlbVNwYW4uc3R5bGUuYmFja2dyb3VuZENvbG9yID0gZGF0YXNldHNbaV0uYmFja2dyb3VuZENvbG9yO1xyXG5cdFx0XHRpZiAoZGF0YXNldHNbaV0ubGFiZWwpIHtcclxuXHRcdFx0XHRsaXN0SXRlbS5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShkYXRhc2V0c1tpXS5sYWJlbCkpO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIGxpc3Qub3V0ZXJIVE1MO1xyXG5cdH1cclxufSk7XHJcblxyXG4vKipcclxuICogSGVscGVyIGZ1bmN0aW9uIHRvIGdldCB0aGUgYm94IHdpZHRoIGJhc2VkIG9uIHRoZSB1c2VQb2ludFN0eWxlIG9wdGlvblxyXG4gKiBAcGFyYW0ge29iamVjdH0gbGFiZWxvcHRzIC0gdGhlIGxhYmVsIG9wdGlvbnMgb24gdGhlIGxlZ2VuZFxyXG4gKiBAcGFyYW0ge251bWJlcn0gZm9udFNpemUgLSB0aGUgbGFiZWwgZm9udCBzaXplXHJcbiAqIEByZXR1cm4ge251bWJlcn0gd2lkdGggb2YgdGhlIGNvbG9yIGJveCBhcmVhXHJcbiAqL1xyXG5mdW5jdGlvbiBnZXRCb3hXaWR0aChsYWJlbE9wdHMsIGZvbnRTaXplKSB7XHJcblx0cmV0dXJuIGxhYmVsT3B0cy51c2VQb2ludFN0eWxlICYmIGxhYmVsT3B0cy5ib3hXaWR0aCA+IGZvbnRTaXplID9cclxuXHRcdGZvbnRTaXplIDpcclxuXHRcdGxhYmVsT3B0cy5ib3hXaWR0aDtcclxufVxyXG5cclxuLyoqXHJcbiAqIElNUE9SVEFOVDogdGhpcyBjbGFzcyBpcyBleHBvc2VkIHB1YmxpY2x5IGFzIENoYXJ0LkxlZ2VuZCwgYmFja3dhcmQgY29tcGF0aWJpbGl0eSByZXF1aXJlZCFcclxuICovXHJcbnZhciBMZWdlbmQgPSBjb3JlX2VsZW1lbnQuZXh0ZW5kKHtcclxuXHJcblx0aW5pdGlhbGl6ZTogZnVuY3Rpb24oY29uZmlnKSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0aGVscGVycyQxLmV4dGVuZChtZSwgY29uZmlnKTtcclxuXHJcblx0XHQvLyBDb250YWlucyBoaXQgYm94ZXMgZm9yIGVhY2ggZGF0YXNldCAoaW4gZGF0YXNldCBvcmRlcilcclxuXHRcdG1lLmxlZ2VuZEhpdEJveGVzID0gW107XHJcblxyXG5cdFx0LyoqXHJcbiBcdFx0ICogQHByaXZhdGVcclxuIFx0XHQgKi9cclxuXHRcdG1lLl9ob3ZlcmVkSXRlbSA9IG51bGw7XHJcblxyXG5cdFx0Ly8gQXJlIHdlIGluIGRvdWdobnV0IG1vZGUgd2hpY2ggaGFzIGEgZGlmZmVyZW50IGRhdGEgdHlwZVxyXG5cdFx0bWUuZG91Z2hudXRNb2RlID0gZmFsc2U7XHJcblx0fSxcclxuXHJcblx0Ly8gVGhlc2UgbWV0aG9kcyBhcmUgb3JkZXJlZCBieSBsaWZlY3ljbGUuIFV0aWxpdGllcyB0aGVuIGZvbGxvdy5cclxuXHQvLyBBbnkgZnVuY3Rpb24gZGVmaW5lZCBoZXJlIGlzIGluaGVyaXRlZCBieSBhbGwgbGVnZW5kIHR5cGVzLlxyXG5cdC8vIEFueSBmdW5jdGlvbiBjYW4gYmUgZXh0ZW5kZWQgYnkgdGhlIGxlZ2VuZCB0eXBlXHJcblxyXG5cdGJlZm9yZVVwZGF0ZTogbm9vcCQxLFxyXG5cdHVwZGF0ZTogZnVuY3Rpb24obWF4V2lkdGgsIG1heEhlaWdodCwgbWFyZ2lucykge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHJcblx0XHQvLyBVcGRhdGUgTGlmZWN5Y2xlIC0gUHJvYmFibHkgZG9uJ3Qgd2FudCB0byBldmVyIGV4dGVuZCBvciBvdmVyd3JpdGUgdGhpcyBmdW5jdGlvbiA7KVxyXG5cdFx0bWUuYmVmb3JlVXBkYXRlKCk7XHJcblxyXG5cdFx0Ly8gQWJzb3JiIHRoZSBtYXN0ZXIgbWVhc3VyZW1lbnRzXHJcblx0XHRtZS5tYXhXaWR0aCA9IG1heFdpZHRoO1xyXG5cdFx0bWUubWF4SGVpZ2h0ID0gbWF4SGVpZ2h0O1xyXG5cdFx0bWUubWFyZ2lucyA9IG1hcmdpbnM7XHJcblxyXG5cdFx0Ly8gRGltZW5zaW9uc1xyXG5cdFx0bWUuYmVmb3JlU2V0RGltZW5zaW9ucygpO1xyXG5cdFx0bWUuc2V0RGltZW5zaW9ucygpO1xyXG5cdFx0bWUuYWZ0ZXJTZXREaW1lbnNpb25zKCk7XHJcblx0XHQvLyBMYWJlbHNcclxuXHRcdG1lLmJlZm9yZUJ1aWxkTGFiZWxzKCk7XHJcblx0XHRtZS5idWlsZExhYmVscygpO1xyXG5cdFx0bWUuYWZ0ZXJCdWlsZExhYmVscygpO1xyXG5cclxuXHRcdC8vIEZpdFxyXG5cdFx0bWUuYmVmb3JlRml0KCk7XHJcblx0XHRtZS5maXQoKTtcclxuXHRcdG1lLmFmdGVyRml0KCk7XHJcblx0XHQvL1xyXG5cdFx0bWUuYWZ0ZXJVcGRhdGUoKTtcclxuXHJcblx0XHRyZXR1cm4gbWUubWluU2l6ZTtcclxuXHR9LFxyXG5cdGFmdGVyVXBkYXRlOiBub29wJDEsXHJcblxyXG5cdC8vXHJcblxyXG5cdGJlZm9yZVNldERpbWVuc2lvbnM6IG5vb3AkMSxcclxuXHRzZXREaW1lbnNpb25zOiBmdW5jdGlvbigpIHtcclxuXHRcdHZhciBtZSA9IHRoaXM7XHJcblx0XHQvLyBTZXQgdGhlIHVuY29uc3RyYWluZWQgZGltZW5zaW9uIGJlZm9yZSBsYWJlbCByb3RhdGlvblxyXG5cdFx0aWYgKG1lLmlzSG9yaXpvbnRhbCgpKSB7XHJcblx0XHRcdC8vIFJlc2V0IHBvc2l0aW9uIGJlZm9yZSBjYWxjdWxhdGluZyByb3RhdGlvblxyXG5cdFx0XHRtZS53aWR0aCA9IG1lLm1heFdpZHRoO1xyXG5cdFx0XHRtZS5sZWZ0ID0gMDtcclxuXHRcdFx0bWUucmlnaHQgPSBtZS53aWR0aDtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdG1lLmhlaWdodCA9IG1lLm1heEhlaWdodDtcclxuXHJcblx0XHRcdC8vIFJlc2V0IHBvc2l0aW9uIGJlZm9yZSBjYWxjdWxhdGluZyByb3RhdGlvblxyXG5cdFx0XHRtZS50b3AgPSAwO1xyXG5cdFx0XHRtZS5ib3R0b20gPSBtZS5oZWlnaHQ7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gUmVzZXQgcGFkZGluZ1xyXG5cdFx0bWUucGFkZGluZ0xlZnQgPSAwO1xyXG5cdFx0bWUucGFkZGluZ1RvcCA9IDA7XHJcblx0XHRtZS5wYWRkaW5nUmlnaHQgPSAwO1xyXG5cdFx0bWUucGFkZGluZ0JvdHRvbSA9IDA7XHJcblxyXG5cdFx0Ly8gUmVzZXQgbWluU2l6ZVxyXG5cdFx0bWUubWluU2l6ZSA9IHtcclxuXHRcdFx0d2lkdGg6IDAsXHJcblx0XHRcdGhlaWdodDogMFxyXG5cdFx0fTtcclxuXHR9LFxyXG5cdGFmdGVyU2V0RGltZW5zaW9uczogbm9vcCQxLFxyXG5cclxuXHQvL1xyXG5cclxuXHRiZWZvcmVCdWlsZExhYmVsczogbm9vcCQxLFxyXG5cdGJ1aWxkTGFiZWxzOiBmdW5jdGlvbigpIHtcclxuXHRcdHZhciBtZSA9IHRoaXM7XHJcblx0XHR2YXIgbGFiZWxPcHRzID0gbWUub3B0aW9ucy5sYWJlbHMgfHwge307XHJcblx0XHR2YXIgbGVnZW5kSXRlbXMgPSBoZWxwZXJzJDEuY2FsbGJhY2sobGFiZWxPcHRzLmdlbmVyYXRlTGFiZWxzLCBbbWUuY2hhcnRdLCBtZSkgfHwgW107XHJcblxyXG5cdFx0aWYgKGxhYmVsT3B0cy5maWx0ZXIpIHtcclxuXHRcdFx0bGVnZW5kSXRlbXMgPSBsZWdlbmRJdGVtcy5maWx0ZXIoZnVuY3Rpb24oaXRlbSkge1xyXG5cdFx0XHRcdHJldHVybiBsYWJlbE9wdHMuZmlsdGVyKGl0ZW0sIG1lLmNoYXJ0LmRhdGEpO1xyXG5cdFx0XHR9KTtcclxuXHRcdH1cclxuXHJcblx0XHRpZiAobWUub3B0aW9ucy5yZXZlcnNlKSB7XHJcblx0XHRcdGxlZ2VuZEl0ZW1zLnJldmVyc2UoKTtcclxuXHRcdH1cclxuXHJcblx0XHRtZS5sZWdlbmRJdGVtcyA9IGxlZ2VuZEl0ZW1zO1xyXG5cdH0sXHJcblx0YWZ0ZXJCdWlsZExhYmVsczogbm9vcCQxLFxyXG5cclxuXHQvL1xyXG5cclxuXHRiZWZvcmVGaXQ6IG5vb3AkMSxcclxuXHRmaXQ6IGZ1bmN0aW9uKCkge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHRcdHZhciBvcHRzID0gbWUub3B0aW9ucztcclxuXHRcdHZhciBsYWJlbE9wdHMgPSBvcHRzLmxhYmVscztcclxuXHRcdHZhciBkaXNwbGF5ID0gb3B0cy5kaXNwbGF5O1xyXG5cclxuXHRcdHZhciBjdHggPSBtZS5jdHg7XHJcblxyXG5cdFx0dmFyIGxhYmVsRm9udCA9IGhlbHBlcnMkMS5vcHRpb25zLl9wYXJzZUZvbnQobGFiZWxPcHRzKTtcclxuXHRcdHZhciBmb250U2l6ZSA9IGxhYmVsRm9udC5zaXplO1xyXG5cclxuXHRcdC8vIFJlc2V0IGhpdCBib3hlc1xyXG5cdFx0dmFyIGhpdGJveGVzID0gbWUubGVnZW5kSGl0Qm94ZXMgPSBbXTtcclxuXHJcblx0XHR2YXIgbWluU2l6ZSA9IG1lLm1pblNpemU7XHJcblx0XHR2YXIgaXNIb3Jpem9udGFsID0gbWUuaXNIb3Jpem9udGFsKCk7XHJcblxyXG5cdFx0aWYgKGlzSG9yaXpvbnRhbCkge1xyXG5cdFx0XHRtaW5TaXplLndpZHRoID0gbWUubWF4V2lkdGg7IC8vIGZpbGwgYWxsIHRoZSB3aWR0aFxyXG5cdFx0XHRtaW5TaXplLmhlaWdodCA9IGRpc3BsYXkgPyAxMCA6IDA7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRtaW5TaXplLndpZHRoID0gZGlzcGxheSA/IDEwIDogMDtcclxuXHRcdFx0bWluU2l6ZS5oZWlnaHQgPSBtZS5tYXhIZWlnaHQ7IC8vIGZpbGwgYWxsIHRoZSBoZWlnaHRcclxuXHRcdH1cclxuXHJcblx0XHQvLyBJbmNyZWFzZSBzaXplcyBoZXJlXHJcblx0XHRpZiAoIWRpc3BsYXkpIHtcclxuXHRcdFx0bWUud2lkdGggPSBtaW5TaXplLndpZHRoID0gbWUuaGVpZ2h0ID0gbWluU2l6ZS5oZWlnaHQgPSAwO1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblx0XHRjdHguZm9udCA9IGxhYmVsRm9udC5zdHJpbmc7XHJcblxyXG5cdFx0aWYgKGlzSG9yaXpvbnRhbCkge1xyXG5cdFx0XHQvLyBMYWJlbHNcclxuXHJcblx0XHRcdC8vIFdpZHRoIG9mIGVhY2ggbGluZSBvZiBsZWdlbmQgYm94ZXMuIExhYmVscyB3cmFwIG9udG8gbXVsdGlwbGUgbGluZXMgd2hlbiB0aGVyZSBhcmUgdG9vIG1hbnkgdG8gZml0IG9uIG9uZVxyXG5cdFx0XHR2YXIgbGluZVdpZHRocyA9IG1lLmxpbmVXaWR0aHMgPSBbMF07XHJcblx0XHRcdHZhciB0b3RhbEhlaWdodCA9IDA7XHJcblxyXG5cdFx0XHRjdHgudGV4dEFsaWduID0gJ2xlZnQnO1xyXG5cdFx0XHRjdHgudGV4dEJhc2VsaW5lID0gJ21pZGRsZSc7XHJcblxyXG5cdFx0XHRoZWxwZXJzJDEuZWFjaChtZS5sZWdlbmRJdGVtcywgZnVuY3Rpb24obGVnZW5kSXRlbSwgaSkge1xyXG5cdFx0XHRcdHZhciBib3hXaWR0aCA9IGdldEJveFdpZHRoKGxhYmVsT3B0cywgZm9udFNpemUpO1xyXG5cdFx0XHRcdHZhciB3aWR0aCA9IGJveFdpZHRoICsgKGZvbnRTaXplIC8gMikgKyBjdHgubWVhc3VyZVRleHQobGVnZW5kSXRlbS50ZXh0KS53aWR0aDtcclxuXHJcblx0XHRcdFx0aWYgKGkgPT09IDAgfHwgbGluZVdpZHRoc1tsaW5lV2lkdGhzLmxlbmd0aCAtIDFdICsgd2lkdGggKyAyICogbGFiZWxPcHRzLnBhZGRpbmcgPiBtaW5TaXplLndpZHRoKSB7XHJcblx0XHRcdFx0XHR0b3RhbEhlaWdodCArPSBmb250U2l6ZSArIGxhYmVsT3B0cy5wYWRkaW5nO1xyXG5cdFx0XHRcdFx0bGluZVdpZHRoc1tsaW5lV2lkdGhzLmxlbmd0aCAtIChpID4gMCA/IDAgOiAxKV0gPSAwO1xyXG5cdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0Ly8gU3RvcmUgdGhlIGhpdGJveCB3aWR0aCBhbmQgaGVpZ2h0IGhlcmUuIEZpbmFsIHBvc2l0aW9uIHdpbGwgYmUgdXBkYXRlZCBpbiBgZHJhd2BcclxuXHRcdFx0XHRoaXRib3hlc1tpXSA9IHtcclxuXHRcdFx0XHRcdGxlZnQ6IDAsXHJcblx0XHRcdFx0XHR0b3A6IDAsXHJcblx0XHRcdFx0XHR3aWR0aDogd2lkdGgsXHJcblx0XHRcdFx0XHRoZWlnaHQ6IGZvbnRTaXplXHJcblx0XHRcdFx0fTtcclxuXHJcblx0XHRcdFx0bGluZVdpZHRoc1tsaW5lV2lkdGhzLmxlbmd0aCAtIDFdICs9IHdpZHRoICsgbGFiZWxPcHRzLnBhZGRpbmc7XHJcblx0XHRcdH0pO1xyXG5cclxuXHRcdFx0bWluU2l6ZS5oZWlnaHQgKz0gdG90YWxIZWlnaHQ7XHJcblxyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0dmFyIHZQYWRkaW5nID0gbGFiZWxPcHRzLnBhZGRpbmc7XHJcblx0XHRcdHZhciBjb2x1bW5XaWR0aHMgPSBtZS5jb2x1bW5XaWR0aHMgPSBbXTtcclxuXHRcdFx0dmFyIGNvbHVtbkhlaWdodHMgPSBtZS5jb2x1bW5IZWlnaHRzID0gW107XHJcblx0XHRcdHZhciB0b3RhbFdpZHRoID0gbGFiZWxPcHRzLnBhZGRpbmc7XHJcblx0XHRcdHZhciBjdXJyZW50Q29sV2lkdGggPSAwO1xyXG5cdFx0XHR2YXIgY3VycmVudENvbEhlaWdodCA9IDA7XHJcblxyXG5cdFx0XHRoZWxwZXJzJDEuZWFjaChtZS5sZWdlbmRJdGVtcywgZnVuY3Rpb24obGVnZW5kSXRlbSwgaSkge1xyXG5cdFx0XHRcdHZhciBib3hXaWR0aCA9IGdldEJveFdpZHRoKGxhYmVsT3B0cywgZm9udFNpemUpO1xyXG5cdFx0XHRcdHZhciBpdGVtV2lkdGggPSBib3hXaWR0aCArIChmb250U2l6ZSAvIDIpICsgY3R4Lm1lYXN1cmVUZXh0KGxlZ2VuZEl0ZW0udGV4dCkud2lkdGg7XHJcblxyXG5cdFx0XHRcdC8vIElmIHRvbyB0YWxsLCBnbyB0byBuZXcgY29sdW1uXHJcblx0XHRcdFx0aWYgKGkgPiAwICYmIGN1cnJlbnRDb2xIZWlnaHQgKyBmb250U2l6ZSArIDIgKiB2UGFkZGluZyA+IG1pblNpemUuaGVpZ2h0KSB7XHJcblx0XHRcdFx0XHR0b3RhbFdpZHRoICs9IGN1cnJlbnRDb2xXaWR0aCArIGxhYmVsT3B0cy5wYWRkaW5nO1xyXG5cdFx0XHRcdFx0Y29sdW1uV2lkdGhzLnB1c2goY3VycmVudENvbFdpZHRoKTsgLy8gcHJldmlvdXMgY29sdW1uIHdpZHRoXHJcblx0XHRcdFx0XHRjb2x1bW5IZWlnaHRzLnB1c2goY3VycmVudENvbEhlaWdodCk7XHJcblx0XHRcdFx0XHRjdXJyZW50Q29sV2lkdGggPSAwO1xyXG5cdFx0XHRcdFx0Y3VycmVudENvbEhlaWdodCA9IDA7XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHQvLyBHZXQgbWF4IHdpZHRoXHJcblx0XHRcdFx0Y3VycmVudENvbFdpZHRoID0gTWF0aC5tYXgoY3VycmVudENvbFdpZHRoLCBpdGVtV2lkdGgpO1xyXG5cdFx0XHRcdGN1cnJlbnRDb2xIZWlnaHQgKz0gZm9udFNpemUgKyB2UGFkZGluZztcclxuXHJcblx0XHRcdFx0Ly8gU3RvcmUgdGhlIGhpdGJveCB3aWR0aCBhbmQgaGVpZ2h0IGhlcmUuIEZpbmFsIHBvc2l0aW9uIHdpbGwgYmUgdXBkYXRlZCBpbiBgZHJhd2BcclxuXHRcdFx0XHRoaXRib3hlc1tpXSA9IHtcclxuXHRcdFx0XHRcdGxlZnQ6IDAsXHJcblx0XHRcdFx0XHR0b3A6IDAsXHJcblx0XHRcdFx0XHR3aWR0aDogaXRlbVdpZHRoLFxyXG5cdFx0XHRcdFx0aGVpZ2h0OiBmb250U2l6ZVxyXG5cdFx0XHRcdH07XHJcblx0XHRcdH0pO1xyXG5cclxuXHRcdFx0dG90YWxXaWR0aCArPSBjdXJyZW50Q29sV2lkdGg7XHJcblx0XHRcdGNvbHVtbldpZHRocy5wdXNoKGN1cnJlbnRDb2xXaWR0aCk7XHJcblx0XHRcdGNvbHVtbkhlaWdodHMucHVzaChjdXJyZW50Q29sSGVpZ2h0KTtcclxuXHRcdFx0bWluU2l6ZS53aWR0aCArPSB0b3RhbFdpZHRoO1xyXG5cdFx0fVxyXG5cclxuXHRcdG1lLndpZHRoID0gbWluU2l6ZS53aWR0aDtcclxuXHRcdG1lLmhlaWdodCA9IG1pblNpemUuaGVpZ2h0O1xyXG5cdH0sXHJcblx0YWZ0ZXJGaXQ6IG5vb3AkMSxcclxuXHJcblx0Ly8gU2hhcmVkIE1ldGhvZHNcclxuXHRpc0hvcml6b250YWw6IGZ1bmN0aW9uKCkge1xyXG5cdFx0cmV0dXJuIHRoaXMub3B0aW9ucy5wb3NpdGlvbiA9PT0gJ3RvcCcgfHwgdGhpcy5vcHRpb25zLnBvc2l0aW9uID09PSAnYm90dG9tJztcclxuXHR9LFxyXG5cclxuXHQvLyBBY3R1YWxseSBkcmF3IHRoZSBsZWdlbmQgb24gdGhlIGNhbnZhc1xyXG5cdGRyYXc6IGZ1bmN0aW9uKCkge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHRcdHZhciBvcHRzID0gbWUub3B0aW9ucztcclxuXHRcdHZhciBsYWJlbE9wdHMgPSBvcHRzLmxhYmVscztcclxuXHRcdHZhciBnbG9iYWxEZWZhdWx0cyA9IGNvcmVfZGVmYXVsdHMuZ2xvYmFsO1xyXG5cdFx0dmFyIGRlZmF1bHRDb2xvciA9IGdsb2JhbERlZmF1bHRzLmRlZmF1bHRDb2xvcjtcclxuXHRcdHZhciBsaW5lRGVmYXVsdCA9IGdsb2JhbERlZmF1bHRzLmVsZW1lbnRzLmxpbmU7XHJcblx0XHR2YXIgbGVnZW5kSGVpZ2h0ID0gbWUuaGVpZ2h0O1xyXG5cdFx0dmFyIGNvbHVtbkhlaWdodHMgPSBtZS5jb2x1bW5IZWlnaHRzO1xyXG5cdFx0dmFyIGxlZ2VuZFdpZHRoID0gbWUud2lkdGg7XHJcblx0XHR2YXIgbGluZVdpZHRocyA9IG1lLmxpbmVXaWR0aHM7XHJcblxyXG5cdFx0aWYgKCFvcHRzLmRpc3BsYXkpIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdHZhciBydGxIZWxwZXIgPSBnZXRSdGxIZWxwZXIkMShvcHRzLnJ0bCwgbWUubGVmdCwgbWUubWluU2l6ZS53aWR0aCk7XHJcblx0XHR2YXIgY3R4ID0gbWUuY3R4O1xyXG5cdFx0dmFyIGZvbnRDb2xvciA9IHZhbHVlT3JEZWZhdWx0JGUobGFiZWxPcHRzLmZvbnRDb2xvciwgZ2xvYmFsRGVmYXVsdHMuZGVmYXVsdEZvbnRDb2xvcik7XHJcblx0XHR2YXIgbGFiZWxGb250ID0gaGVscGVycyQxLm9wdGlvbnMuX3BhcnNlRm9udChsYWJlbE9wdHMpO1xyXG5cdFx0dmFyIGZvbnRTaXplID0gbGFiZWxGb250LnNpemU7XHJcblx0XHR2YXIgY3Vyc29yO1xyXG5cclxuXHRcdC8vIENhbnZhcyBzZXR1cFxyXG5cdFx0Y3R4LnRleHRBbGlnbiA9IHJ0bEhlbHBlci50ZXh0QWxpZ24oJ2xlZnQnKTtcclxuXHRcdGN0eC50ZXh0QmFzZWxpbmUgPSAnbWlkZGxlJztcclxuXHRcdGN0eC5saW5lV2lkdGggPSAwLjU7XHJcblx0XHRjdHguc3Ryb2tlU3R5bGUgPSBmb250Q29sb3I7IC8vIGZvciBzdHJpa2V0aHJvdWdoIGVmZmVjdFxyXG5cdFx0Y3R4LmZpbGxTdHlsZSA9IGZvbnRDb2xvcjsgLy8gcmVuZGVyIGluIGNvcnJlY3QgY29sb3VyXHJcblx0XHRjdHguZm9udCA9IGxhYmVsRm9udC5zdHJpbmc7XHJcblxyXG5cdFx0dmFyIGJveFdpZHRoID0gZ2V0Qm94V2lkdGgobGFiZWxPcHRzLCBmb250U2l6ZSk7XHJcblx0XHR2YXIgaGl0Ym94ZXMgPSBtZS5sZWdlbmRIaXRCb3hlcztcclxuXHJcblx0XHQvLyBjdXJyZW50IHBvc2l0aW9uXHJcblx0XHR2YXIgZHJhd0xlZ2VuZEJveCA9IGZ1bmN0aW9uKHgsIHksIGxlZ2VuZEl0ZW0pIHtcclxuXHRcdFx0aWYgKGlzTmFOKGJveFdpZHRoKSB8fCBib3hXaWR0aCA8PSAwKSB7XHJcblx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBTZXQgdGhlIGN0eCBmb3IgdGhlIGJveFxyXG5cdFx0XHRjdHguc2F2ZSgpO1xyXG5cclxuXHRcdFx0dmFyIGxpbmVXaWR0aCA9IHZhbHVlT3JEZWZhdWx0JGUobGVnZW5kSXRlbS5saW5lV2lkdGgsIGxpbmVEZWZhdWx0LmJvcmRlcldpZHRoKTtcclxuXHRcdFx0Y3R4LmZpbGxTdHlsZSA9IHZhbHVlT3JEZWZhdWx0JGUobGVnZW5kSXRlbS5maWxsU3R5bGUsIGRlZmF1bHRDb2xvcik7XHJcblx0XHRcdGN0eC5saW5lQ2FwID0gdmFsdWVPckRlZmF1bHQkZShsZWdlbmRJdGVtLmxpbmVDYXAsIGxpbmVEZWZhdWx0LmJvcmRlckNhcFN0eWxlKTtcclxuXHRcdFx0Y3R4LmxpbmVEYXNoT2Zmc2V0ID0gdmFsdWVPckRlZmF1bHQkZShsZWdlbmRJdGVtLmxpbmVEYXNoT2Zmc2V0LCBsaW5lRGVmYXVsdC5ib3JkZXJEYXNoT2Zmc2V0KTtcclxuXHRcdFx0Y3R4LmxpbmVKb2luID0gdmFsdWVPckRlZmF1bHQkZShsZWdlbmRJdGVtLmxpbmVKb2luLCBsaW5lRGVmYXVsdC5ib3JkZXJKb2luU3R5bGUpO1xyXG5cdFx0XHRjdHgubGluZVdpZHRoID0gbGluZVdpZHRoO1xyXG5cdFx0XHRjdHguc3Ryb2tlU3R5bGUgPSB2YWx1ZU9yRGVmYXVsdCRlKGxlZ2VuZEl0ZW0uc3Ryb2tlU3R5bGUsIGRlZmF1bHRDb2xvcik7XHJcblxyXG5cdFx0XHRpZiAoY3R4LnNldExpbmVEYXNoKSB7XHJcblx0XHRcdFx0Ly8gSUUgOSBhbmQgMTAgZG8gbm90IHN1cHBvcnQgbGluZSBkYXNoXHJcblx0XHRcdFx0Y3R4LnNldExpbmVEYXNoKHZhbHVlT3JEZWZhdWx0JGUobGVnZW5kSXRlbS5saW5lRGFzaCwgbGluZURlZmF1bHQuYm9yZGVyRGFzaCkpO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRpZiAobGFiZWxPcHRzICYmIGxhYmVsT3B0cy51c2VQb2ludFN0eWxlKSB7XHJcblx0XHRcdFx0Ly8gUmVjYWxjdWxhdGUgeCBhbmQgeSBmb3IgZHJhd1BvaW50KCkgYmVjYXVzZSBpdHMgZXhwZWN0aW5nXHJcblx0XHRcdFx0Ly8geCBhbmQgeSB0byBiZSBjZW50ZXIgb2YgZmlndXJlIChpbnN0ZWFkIG9mIHRvcCBsZWZ0KVxyXG5cdFx0XHRcdHZhciByYWRpdXMgPSBib3hXaWR0aCAqIE1hdGguU1FSVDIgLyAyO1xyXG5cdFx0XHRcdHZhciBjZW50ZXJYID0gcnRsSGVscGVyLnhQbHVzKHgsIGJveFdpZHRoIC8gMik7XHJcblx0XHRcdFx0dmFyIGNlbnRlclkgPSB5ICsgZm9udFNpemUgLyAyO1xyXG5cclxuXHRcdFx0XHQvLyBEcmF3IHBvaW50U3R5bGUgYXMgbGVnZW5kIHN5bWJvbFxyXG5cdFx0XHRcdGhlbHBlcnMkMS5jYW52YXMuZHJhd1BvaW50KGN0eCwgbGVnZW5kSXRlbS5wb2ludFN0eWxlLCByYWRpdXMsIGNlbnRlclgsIGNlbnRlclksIGxlZ2VuZEl0ZW0ucm90YXRpb24pO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdC8vIERyYXcgYm94IGFzIGxlZ2VuZCBzeW1ib2xcclxuXHRcdFx0XHRjdHguZmlsbFJlY3QocnRsSGVscGVyLmxlZnRGb3JMdHIoeCwgYm94V2lkdGgpLCB5LCBib3hXaWR0aCwgZm9udFNpemUpO1xyXG5cdFx0XHRcdGlmIChsaW5lV2lkdGggIT09IDApIHtcclxuXHRcdFx0XHRcdGN0eC5zdHJva2VSZWN0KHJ0bEhlbHBlci5sZWZ0Rm9yTHRyKHgsIGJveFdpZHRoKSwgeSwgYm94V2lkdGgsIGZvbnRTaXplKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdGN0eC5yZXN0b3JlKCk7XHJcblx0XHR9O1xyXG5cclxuXHRcdHZhciBmaWxsVGV4dCA9IGZ1bmN0aW9uKHgsIHksIGxlZ2VuZEl0ZW0sIHRleHRXaWR0aCkge1xyXG5cdFx0XHR2YXIgaGFsZkZvbnRTaXplID0gZm9udFNpemUgLyAyO1xyXG5cdFx0XHR2YXIgeExlZnQgPSBydGxIZWxwZXIueFBsdXMoeCwgYm94V2lkdGggKyBoYWxmRm9udFNpemUpO1xyXG5cdFx0XHR2YXIgeU1pZGRsZSA9IHkgKyBoYWxmRm9udFNpemU7XHJcblxyXG5cdFx0XHRjdHguZmlsbFRleHQobGVnZW5kSXRlbS50ZXh0LCB4TGVmdCwgeU1pZGRsZSk7XHJcblxyXG5cdFx0XHRpZiAobGVnZW5kSXRlbS5oaWRkZW4pIHtcclxuXHRcdFx0XHQvLyBTdHJpa2V0aHJvdWdoIHRoZSB0ZXh0IGlmIGhpZGRlblxyXG5cdFx0XHRcdGN0eC5iZWdpblBhdGgoKTtcclxuXHRcdFx0XHRjdHgubGluZVdpZHRoID0gMjtcclxuXHRcdFx0XHRjdHgubW92ZVRvKHhMZWZ0LCB5TWlkZGxlKTtcclxuXHRcdFx0XHRjdHgubGluZVRvKHJ0bEhlbHBlci54UGx1cyh4TGVmdCwgdGV4dFdpZHRoKSwgeU1pZGRsZSk7XHJcblx0XHRcdFx0Y3R4LnN0cm9rZSgpO1xyXG5cdFx0XHR9XHJcblx0XHR9O1xyXG5cclxuXHRcdHZhciBhbGlnbm1lbnRPZmZzZXQgPSBmdW5jdGlvbihkaW1lbnNpb24sIGJsb2NrU2l6ZSkge1xyXG5cdFx0XHRzd2l0Y2ggKG9wdHMuYWxpZ24pIHtcclxuXHRcdFx0Y2FzZSAnc3RhcnQnOlxyXG5cdFx0XHRcdHJldHVybiBsYWJlbE9wdHMucGFkZGluZztcclxuXHRcdFx0Y2FzZSAnZW5kJzpcclxuXHRcdFx0XHRyZXR1cm4gZGltZW5zaW9uIC0gYmxvY2tTaXplO1xyXG5cdFx0XHRkZWZhdWx0OiAvLyBjZW50ZXJcclxuXHRcdFx0XHRyZXR1cm4gKGRpbWVuc2lvbiAtIGJsb2NrU2l6ZSArIGxhYmVsT3B0cy5wYWRkaW5nKSAvIDI7XHJcblx0XHRcdH1cclxuXHRcdH07XHJcblxyXG5cdFx0Ly8gSG9yaXpvbnRhbFxyXG5cdFx0dmFyIGlzSG9yaXpvbnRhbCA9IG1lLmlzSG9yaXpvbnRhbCgpO1xyXG5cdFx0aWYgKGlzSG9yaXpvbnRhbCkge1xyXG5cdFx0XHRjdXJzb3IgPSB7XHJcblx0XHRcdFx0eDogbWUubGVmdCArIGFsaWdubWVudE9mZnNldChsZWdlbmRXaWR0aCwgbGluZVdpZHRoc1swXSksXHJcblx0XHRcdFx0eTogbWUudG9wICsgbGFiZWxPcHRzLnBhZGRpbmcsXHJcblx0XHRcdFx0bGluZTogMFxyXG5cdFx0XHR9O1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0Y3Vyc29yID0ge1xyXG5cdFx0XHRcdHg6IG1lLmxlZnQgKyBsYWJlbE9wdHMucGFkZGluZyxcclxuXHRcdFx0XHR5OiBtZS50b3AgKyBhbGlnbm1lbnRPZmZzZXQobGVnZW5kSGVpZ2h0LCBjb2x1bW5IZWlnaHRzWzBdKSxcclxuXHRcdFx0XHRsaW5lOiAwXHJcblx0XHRcdH07XHJcblx0XHR9XHJcblxyXG5cdFx0aGVscGVycyQxLnJ0bC5vdmVycmlkZVRleHREaXJlY3Rpb24obWUuY3R4LCBvcHRzLnRleHREaXJlY3Rpb24pO1xyXG5cclxuXHRcdHZhciBpdGVtSGVpZ2h0ID0gZm9udFNpemUgKyBsYWJlbE9wdHMucGFkZGluZztcclxuXHRcdGhlbHBlcnMkMS5lYWNoKG1lLmxlZ2VuZEl0ZW1zLCBmdW5jdGlvbihsZWdlbmRJdGVtLCBpKSB7XHJcblx0XHRcdHZhciB0ZXh0V2lkdGggPSBjdHgubWVhc3VyZVRleHQobGVnZW5kSXRlbS50ZXh0KS53aWR0aDtcclxuXHRcdFx0dmFyIHdpZHRoID0gYm94V2lkdGggKyAoZm9udFNpemUgLyAyKSArIHRleHRXaWR0aDtcclxuXHRcdFx0dmFyIHggPSBjdXJzb3IueDtcclxuXHRcdFx0dmFyIHkgPSBjdXJzb3IueTtcclxuXHJcblx0XHRcdHJ0bEhlbHBlci5zZXRXaWR0aChtZS5taW5TaXplLndpZHRoKTtcclxuXHJcblx0XHRcdC8vIFVzZSAobWUubGVmdCArIG1lLm1pblNpemUud2lkdGgpIGFuZCAobWUudG9wICsgbWUubWluU2l6ZS5oZWlnaHQpXHJcblx0XHRcdC8vIGluc3RlYWQgb2YgbWUucmlnaHQgYW5kIG1lLmJvdHRvbSBiZWNhdXNlIG1lLndpZHRoIGFuZCBtZS5oZWlnaHRcclxuXHRcdFx0Ly8gbWF5IGhhdmUgYmVlbiBjaGFuZ2VkIHNpbmNlIG1lLm1pblNpemUgd2FzIGNhbGN1bGF0ZWRcclxuXHRcdFx0aWYgKGlzSG9yaXpvbnRhbCkge1xyXG5cdFx0XHRcdGlmIChpID4gMCAmJiB4ICsgd2lkdGggKyBsYWJlbE9wdHMucGFkZGluZyA+IG1lLmxlZnQgKyBtZS5taW5TaXplLndpZHRoKSB7XHJcblx0XHRcdFx0XHR5ID0gY3Vyc29yLnkgKz0gaXRlbUhlaWdodDtcclxuXHRcdFx0XHRcdGN1cnNvci5saW5lKys7XHJcblx0XHRcdFx0XHR4ID0gY3Vyc29yLnggPSBtZS5sZWZ0ICsgYWxpZ25tZW50T2Zmc2V0KGxlZ2VuZFdpZHRoLCBsaW5lV2lkdGhzW2N1cnNvci5saW5lXSk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9IGVsc2UgaWYgKGkgPiAwICYmIHkgKyBpdGVtSGVpZ2h0ID4gbWUudG9wICsgbWUubWluU2l6ZS5oZWlnaHQpIHtcclxuXHRcdFx0XHR4ID0gY3Vyc29yLnggPSB4ICsgbWUuY29sdW1uV2lkdGhzW2N1cnNvci5saW5lXSArIGxhYmVsT3B0cy5wYWRkaW5nO1xyXG5cdFx0XHRcdGN1cnNvci5saW5lKys7XHJcblx0XHRcdFx0eSA9IGN1cnNvci55ID0gbWUudG9wICsgYWxpZ25tZW50T2Zmc2V0KGxlZ2VuZEhlaWdodCwgY29sdW1uSGVpZ2h0c1tjdXJzb3IubGluZV0pO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHR2YXIgcmVhbFggPSBydGxIZWxwZXIueCh4KTtcclxuXHJcblx0XHRcdGRyYXdMZWdlbmRCb3gocmVhbFgsIHksIGxlZ2VuZEl0ZW0pO1xyXG5cclxuXHRcdFx0aGl0Ym94ZXNbaV0ubGVmdCA9IHJ0bEhlbHBlci5sZWZ0Rm9yTHRyKHJlYWxYLCBoaXRib3hlc1tpXS53aWR0aCk7XHJcblx0XHRcdGhpdGJveGVzW2ldLnRvcCA9IHk7XHJcblxyXG5cdFx0XHQvLyBGaWxsIHRoZSBhY3R1YWwgbGFiZWxcclxuXHRcdFx0ZmlsbFRleHQocmVhbFgsIHksIGxlZ2VuZEl0ZW0sIHRleHRXaWR0aCk7XHJcblxyXG5cdFx0XHRpZiAoaXNIb3Jpem9udGFsKSB7XHJcblx0XHRcdFx0Y3Vyc29yLnggKz0gd2lkdGggKyBsYWJlbE9wdHMucGFkZGluZztcclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRjdXJzb3IueSArPSBpdGVtSGVpZ2h0O1xyXG5cdFx0XHR9XHJcblx0XHR9KTtcclxuXHJcblx0XHRoZWxwZXJzJDEucnRsLnJlc3RvcmVUZXh0RGlyZWN0aW9uKG1lLmN0eCwgb3B0cy50ZXh0RGlyZWN0aW9uKTtcclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBAcHJpdmF0ZVxyXG5cdCAqL1xyXG5cdF9nZXRMZWdlbmRJdGVtQXQ6IGZ1bmN0aW9uKHgsIHkpIHtcclxuXHRcdHZhciBtZSA9IHRoaXM7XHJcblx0XHR2YXIgaSwgaGl0Qm94LCBsaDtcclxuXHJcblx0XHRpZiAoeCA+PSBtZS5sZWZ0ICYmIHggPD0gbWUucmlnaHQgJiYgeSA+PSBtZS50b3AgJiYgeSA8PSBtZS5ib3R0b20pIHtcclxuXHRcdFx0Ly8gU2VlIGlmIHdlIGFyZSB0b3VjaGluZyBvbmUgb2YgdGhlIGRhdGFzZXQgYm94ZXNcclxuXHRcdFx0bGggPSBtZS5sZWdlbmRIaXRCb3hlcztcclxuXHRcdFx0Zm9yIChpID0gMDsgaSA8IGxoLmxlbmd0aDsgKytpKSB7XHJcblx0XHRcdFx0aGl0Qm94ID0gbGhbaV07XHJcblxyXG5cdFx0XHRcdGlmICh4ID49IGhpdEJveC5sZWZ0ICYmIHggPD0gaGl0Qm94LmxlZnQgKyBoaXRCb3gud2lkdGggJiYgeSA+PSBoaXRCb3gudG9wICYmIHkgPD0gaGl0Qm94LnRvcCArIGhpdEJveC5oZWlnaHQpIHtcclxuXHRcdFx0XHRcdC8vIFRvdWNoaW5nIGFuIGVsZW1lbnRcclxuXHRcdFx0XHRcdHJldHVybiBtZS5sZWdlbmRJdGVtc1tpXTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gbnVsbDtcclxuXHR9LFxyXG5cclxuXHQvKipcclxuXHQgKiBIYW5kbGUgYW4gZXZlbnRcclxuXHQgKiBAcHJpdmF0ZVxyXG5cdCAqIEBwYXJhbSB7SUV2ZW50fSBldmVudCAtIFRoZSBldmVudCB0byBoYW5kbGVcclxuXHQgKi9cclxuXHRoYW5kbGVFdmVudDogZnVuY3Rpb24oZSkge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHRcdHZhciBvcHRzID0gbWUub3B0aW9ucztcclxuXHRcdHZhciB0eXBlID0gZS50eXBlID09PSAnbW91c2V1cCcgPyAnY2xpY2snIDogZS50eXBlO1xyXG5cdFx0dmFyIGhvdmVyZWRJdGVtO1xyXG5cclxuXHRcdGlmICh0eXBlID09PSAnbW91c2Vtb3ZlJykge1xyXG5cdFx0XHRpZiAoIW9wdHMub25Ib3ZlciAmJiAhb3B0cy5vbkxlYXZlKSB7XHJcblx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHR9XHJcblx0XHR9IGVsc2UgaWYgKHR5cGUgPT09ICdjbGljaycpIHtcclxuXHRcdFx0aWYgKCFvcHRzLm9uQ2xpY2spIHtcclxuXHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdH1cclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBDaGFydCBldmVudCBhbHJlYWR5IGhhcyByZWxhdGl2ZSBwb3NpdGlvbiBpbiBpdFxyXG5cdFx0aG92ZXJlZEl0ZW0gPSBtZS5fZ2V0TGVnZW5kSXRlbUF0KGUueCwgZS55KTtcclxuXHJcblx0XHRpZiAodHlwZSA9PT0gJ2NsaWNrJykge1xyXG5cdFx0XHRpZiAoaG92ZXJlZEl0ZW0gJiYgb3B0cy5vbkNsaWNrKSB7XHJcblx0XHRcdFx0Ly8gdXNlIGUubmF0aXZlIGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eVxyXG5cdFx0XHRcdG9wdHMub25DbGljay5jYWxsKG1lLCBlLm5hdGl2ZSwgaG92ZXJlZEl0ZW0pO1xyXG5cdFx0XHR9XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRpZiAob3B0cy5vbkxlYXZlICYmIGhvdmVyZWRJdGVtICE9PSBtZS5faG92ZXJlZEl0ZW0pIHtcclxuXHRcdFx0XHRpZiAobWUuX2hvdmVyZWRJdGVtKSB7XHJcblx0XHRcdFx0XHRvcHRzLm9uTGVhdmUuY2FsbChtZSwgZS5uYXRpdmUsIG1lLl9ob3ZlcmVkSXRlbSk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdG1lLl9ob3ZlcmVkSXRlbSA9IGhvdmVyZWRJdGVtO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRpZiAob3B0cy5vbkhvdmVyICYmIGhvdmVyZWRJdGVtKSB7XHJcblx0XHRcdFx0Ly8gdXNlIGUubmF0aXZlIGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eVxyXG5cdFx0XHRcdG9wdHMub25Ib3Zlci5jYWxsKG1lLCBlLm5hdGl2ZSwgaG92ZXJlZEl0ZW0pO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0fVxyXG59KTtcclxuXHJcbmZ1bmN0aW9uIGNyZWF0ZU5ld0xlZ2VuZEFuZEF0dGFjaChjaGFydCwgbGVnZW5kT3B0cykge1xyXG5cdHZhciBsZWdlbmQgPSBuZXcgTGVnZW5kKHtcclxuXHRcdGN0eDogY2hhcnQuY3R4LFxyXG5cdFx0b3B0aW9uczogbGVnZW5kT3B0cyxcclxuXHRcdGNoYXJ0OiBjaGFydFxyXG5cdH0pO1xyXG5cclxuXHRjb3JlX2xheW91dHMuY29uZmlndXJlKGNoYXJ0LCBsZWdlbmQsIGxlZ2VuZE9wdHMpO1xyXG5cdGNvcmVfbGF5b3V0cy5hZGRCb3goY2hhcnQsIGxlZ2VuZCk7XHJcblx0Y2hhcnQubGVnZW5kID0gbGVnZW5kO1xyXG59XHJcblxyXG52YXIgcGx1Z2luX2xlZ2VuZCA9IHtcclxuXHRpZDogJ2xlZ2VuZCcsXHJcblxyXG5cdC8qKlxyXG5cdCAqIEJhY2t3YXJkIGNvbXBhdGliaWxpdHk6IHNpbmNlIDIuMS41LCB0aGUgbGVnZW5kIGlzIHJlZ2lzdGVyZWQgYXMgYSBwbHVnaW4sIG1ha2luZ1xyXG5cdCAqIENoYXJ0LkxlZ2VuZCBvYnNvbGV0ZS4gVG8gYXZvaWQgYSBicmVha2luZyBjaGFuZ2UsIHdlIGV4cG9ydCB0aGUgTGVnZW5kIGFzIHBhcnQgb2ZcclxuXHQgKiB0aGUgcGx1Z2luLCB3aGljaCBvbmUgd2lsbCBiZSByZS1leHBvc2VkIGluIHRoZSBjaGFydC5qcyBmaWxlLlxyXG5cdCAqIGh0dHBzOi8vZ2l0aHViLmNvbS9jaGFydGpzL0NoYXJ0LmpzL3B1bGwvMjY0MFxyXG5cdCAqIEBwcml2YXRlXHJcblx0ICovXHJcblx0X2VsZW1lbnQ6IExlZ2VuZCxcclxuXHJcblx0YmVmb3JlSW5pdDogZnVuY3Rpb24oY2hhcnQpIHtcclxuXHRcdHZhciBsZWdlbmRPcHRzID0gY2hhcnQub3B0aW9ucy5sZWdlbmQ7XHJcblxyXG5cdFx0aWYgKGxlZ2VuZE9wdHMpIHtcclxuXHRcdFx0Y3JlYXRlTmV3TGVnZW5kQW5kQXR0YWNoKGNoYXJ0LCBsZWdlbmRPcHRzKTtcclxuXHRcdH1cclxuXHR9LFxyXG5cclxuXHRiZWZvcmVVcGRhdGU6IGZ1bmN0aW9uKGNoYXJ0KSB7XHJcblx0XHR2YXIgbGVnZW5kT3B0cyA9IGNoYXJ0Lm9wdGlvbnMubGVnZW5kO1xyXG5cdFx0dmFyIGxlZ2VuZCA9IGNoYXJ0LmxlZ2VuZDtcclxuXHJcblx0XHRpZiAobGVnZW5kT3B0cykge1xyXG5cdFx0XHRoZWxwZXJzJDEubWVyZ2VJZihsZWdlbmRPcHRzLCBjb3JlX2RlZmF1bHRzLmdsb2JhbC5sZWdlbmQpO1xyXG5cclxuXHRcdFx0aWYgKGxlZ2VuZCkge1xyXG5cdFx0XHRcdGNvcmVfbGF5b3V0cy5jb25maWd1cmUoY2hhcnQsIGxlZ2VuZCwgbGVnZW5kT3B0cyk7XHJcblx0XHRcdFx0bGVnZW5kLm9wdGlvbnMgPSBsZWdlbmRPcHRzO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdGNyZWF0ZU5ld0xlZ2VuZEFuZEF0dGFjaChjaGFydCwgbGVnZW5kT3B0cyk7XHJcblx0XHRcdH1cclxuXHRcdH0gZWxzZSBpZiAobGVnZW5kKSB7XHJcblx0XHRcdGNvcmVfbGF5b3V0cy5yZW1vdmVCb3goY2hhcnQsIGxlZ2VuZCk7XHJcblx0XHRcdGRlbGV0ZSBjaGFydC5sZWdlbmQ7XHJcblx0XHR9XHJcblx0fSxcclxuXHJcblx0YWZ0ZXJFdmVudDogZnVuY3Rpb24oY2hhcnQsIGUpIHtcclxuXHRcdHZhciBsZWdlbmQgPSBjaGFydC5sZWdlbmQ7XHJcblx0XHRpZiAobGVnZW5kKSB7XHJcblx0XHRcdGxlZ2VuZC5oYW5kbGVFdmVudChlKTtcclxuXHRcdH1cclxuXHR9XHJcbn07XG5cbnZhciBub29wJDIgPSBoZWxwZXJzJDEubm9vcDtcclxuXHJcbmNvcmVfZGVmYXVsdHMuX3NldCgnZ2xvYmFsJywge1xyXG5cdHRpdGxlOiB7XHJcblx0XHRkaXNwbGF5OiBmYWxzZSxcclxuXHRcdGZvbnRTdHlsZTogJ2JvbGQnLFxyXG5cdFx0ZnVsbFdpZHRoOiB0cnVlLFxyXG5cdFx0cGFkZGluZzogMTAsXHJcblx0XHRwb3NpdGlvbjogJ3RvcCcsXHJcblx0XHR0ZXh0OiAnJyxcclxuXHRcdHdlaWdodDogMjAwMCAgICAgICAgIC8vIGJ5IGRlZmF1bHQgZ3JlYXRlciB0aGFuIGxlZ2VuZCAoMTAwMCkgdG8gYmUgYWJvdmVcclxuXHR9XHJcbn0pO1xyXG5cclxuLyoqXHJcbiAqIElNUE9SVEFOVDogdGhpcyBjbGFzcyBpcyBleHBvc2VkIHB1YmxpY2x5IGFzIENoYXJ0LkxlZ2VuZCwgYmFja3dhcmQgY29tcGF0aWJpbGl0eSByZXF1aXJlZCFcclxuICovXHJcbnZhciBUaXRsZSA9IGNvcmVfZWxlbWVudC5leHRlbmQoe1xyXG5cdGluaXRpYWxpemU6IGZ1bmN0aW9uKGNvbmZpZykge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHRcdGhlbHBlcnMkMS5leHRlbmQobWUsIGNvbmZpZyk7XHJcblxyXG5cdFx0Ly8gQ29udGFpbnMgaGl0IGJveGVzIGZvciBlYWNoIGRhdGFzZXQgKGluIGRhdGFzZXQgb3JkZXIpXHJcblx0XHRtZS5sZWdlbmRIaXRCb3hlcyA9IFtdO1xyXG5cdH0sXHJcblxyXG5cdC8vIFRoZXNlIG1ldGhvZHMgYXJlIG9yZGVyZWQgYnkgbGlmZWN5Y2xlLiBVdGlsaXRpZXMgdGhlbiBmb2xsb3cuXHJcblxyXG5cdGJlZm9yZVVwZGF0ZTogbm9vcCQyLFxyXG5cdHVwZGF0ZTogZnVuY3Rpb24obWF4V2lkdGgsIG1heEhlaWdodCwgbWFyZ2lucykge1xyXG5cdFx0dmFyIG1lID0gdGhpcztcclxuXHJcblx0XHQvLyBVcGRhdGUgTGlmZWN5Y2xlIC0gUHJvYmFibHkgZG9uJ3Qgd2FudCB0byBldmVyIGV4dGVuZCBvciBvdmVyd3JpdGUgdGhpcyBmdW5jdGlvbiA7KVxyXG5cdFx0bWUuYmVmb3JlVXBkYXRlKCk7XHJcblxyXG5cdFx0Ly8gQWJzb3JiIHRoZSBtYXN0ZXIgbWVhc3VyZW1lbnRzXHJcblx0XHRtZS5tYXhXaWR0aCA9IG1heFdpZHRoO1xyXG5cdFx0bWUubWF4SGVpZ2h0ID0gbWF4SGVpZ2h0O1xyXG5cdFx0bWUubWFyZ2lucyA9IG1hcmdpbnM7XHJcblxyXG5cdFx0Ly8gRGltZW5zaW9uc1xyXG5cdFx0bWUuYmVmb3JlU2V0RGltZW5zaW9ucygpO1xyXG5cdFx0bWUuc2V0RGltZW5zaW9ucygpO1xyXG5cdFx0bWUuYWZ0ZXJTZXREaW1lbnNpb25zKCk7XHJcblx0XHQvLyBMYWJlbHNcclxuXHRcdG1lLmJlZm9yZUJ1aWxkTGFiZWxzKCk7XHJcblx0XHRtZS5idWlsZExhYmVscygpO1xyXG5cdFx0bWUuYWZ0ZXJCdWlsZExhYmVscygpO1xyXG5cclxuXHRcdC8vIEZpdFxyXG5cdFx0bWUuYmVmb3JlRml0KCk7XHJcblx0XHRtZS5maXQoKTtcclxuXHRcdG1lLmFmdGVyRml0KCk7XHJcblx0XHQvL1xyXG5cdFx0bWUuYWZ0ZXJVcGRhdGUoKTtcclxuXHJcblx0XHRyZXR1cm4gbWUubWluU2l6ZTtcclxuXHJcblx0fSxcclxuXHRhZnRlclVwZGF0ZTogbm9vcCQyLFxyXG5cclxuXHQvL1xyXG5cclxuXHRiZWZvcmVTZXREaW1lbnNpb25zOiBub29wJDIsXHJcblx0c2V0RGltZW5zaW9uczogZnVuY3Rpb24oKSB7XHJcblx0XHR2YXIgbWUgPSB0aGlzO1xyXG5cdFx0Ly8gU2V0IHRoZSB1bmNvbnN0cmFpbmVkIGRpbWVuc2lvbiBiZWZvcmUgbGFiZWwgcm90YXRpb25cclxuXHRcdGlmIChtZS5pc0hvcml6b250YWwoKSkge1xyXG5cdFx0XHQvLyBSZXNldCBwb3NpdGlvbiBiZWZvcmUgY2FsY3VsYXRpbmcgcm90YXRpb25cclxuXHRcdFx0bWUud2lkdGggPSBtZS5tYXhXaWR0aDtcclxuXHRcdFx0bWUubGVmdCA9IDA7XHJcblx0XHRcdG1lLnJpZ2h0ID0gbWUud2lkdGg7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRtZS5oZWlnaHQgPSBtZS5tYXhIZWlnaHQ7XHJcblxyXG5cdFx0XHQvLyBSZXNldCBwb3NpdGlvbiBiZWZvcmUgY2FsY3VsYXRpbmcgcm90YXRpb25cclxuXHRcdFx0bWUudG9wID0gMDtcclxuXHRcdFx0bWUuYm90dG9tID0gbWUuaGVpZ2h0O1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIFJlc2V0IHBhZGRpbmdcclxuXHRcdG1lLnBhZGRpbmdMZWZ0ID0gMDtcclxuXHRcdG1lLnBhZGRpbmdUb3AgPSAwO1xyXG5cdFx0bWUucGFkZGluZ1JpZ2h0ID0gMDtcclxuXHRcdG1lLnBhZGRpbmdCb3R0b20gPSAwO1xyXG5cclxuXHRcdC8vIFJlc2V0IG1pblNpemVcclxuXHRcdG1lLm1pblNpemUgPSB7XHJcblx0XHRcdHdpZHRoOiAwLFxyXG5cdFx0XHRoZWlnaHQ6IDBcclxuXHRcdH07XHJcblx0fSxcclxuXHRhZnRlclNldERpbWVuc2lvbnM6IG5vb3AkMixcclxuXHJcblx0Ly9cclxuXHJcblx0YmVmb3JlQnVpbGRMYWJlbHM6IG5vb3AkMixcclxuXHRidWlsZExhYmVsczogbm9vcCQyLFxyXG5cdGFmdGVyQnVpbGRMYWJlbHM6IG5vb3AkMixcclxuXHJcblx0Ly9cclxuXHJcblx0YmVmb3JlRml0OiBub29wJDIsXHJcblx0Zml0OiBmdW5jdGlvbigpIHtcclxuXHRcdHZhciBtZSA9IHRoaXM7XHJcblx0XHR2YXIgb3B0cyA9IG1lLm9wdGlvbnM7XHJcblx0XHR2YXIgbWluU2l6ZSA9IG1lLm1pblNpemUgPSB7fTtcclxuXHRcdHZhciBpc0hvcml6b250YWwgPSBtZS5pc0hvcml6b250YWwoKTtcclxuXHRcdHZhciBsaW5lQ291bnQsIHRleHRTaXplO1xyXG5cclxuXHRcdGlmICghb3B0cy5kaXNwbGF5KSB7XHJcblx0XHRcdG1lLndpZHRoID0gbWluU2l6ZS53aWR0aCA9IG1lLmhlaWdodCA9IG1pblNpemUuaGVpZ2h0ID0gMDtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdGxpbmVDb3VudCA9IGhlbHBlcnMkMS5pc0FycmF5KG9wdHMudGV4dCkgPyBvcHRzLnRleHQubGVuZ3RoIDogMTtcclxuXHRcdHRleHRTaXplID0gbGluZUNvdW50ICogaGVscGVycyQxLm9wdGlvbnMuX3BhcnNlRm9udChvcHRzKS5saW5lSGVpZ2h0ICsgb3B0cy5wYWRkaW5nICogMjtcclxuXHJcblx0XHRtZS53aWR0aCA9IG1pblNpemUud2lkdGggPSBpc0hvcml6b250YWwgPyBtZS5tYXhXaWR0aCA6IHRleHRTaXplO1xyXG5cdFx0bWUuaGVpZ2h0ID0gbWluU2l6ZS5oZWlnaHQgPSBpc0hvcml6b250YWwgPyB0ZXh0U2l6ZSA6IG1lLm1heEhlaWdodDtcclxuXHR9LFxyXG5cdGFmdGVyRml0OiBub29wJDIsXHJcblxyXG5cdC8vIFNoYXJlZCBNZXRob2RzXHJcblx0aXNIb3Jpem9udGFsOiBmdW5jdGlvbigpIHtcclxuXHRcdHZhciBwb3MgPSB0aGlzLm9wdGlvbnMucG9zaXRpb247XHJcblx0XHRyZXR1cm4gcG9zID09PSAndG9wJyB8fCBwb3MgPT09ICdib3R0b20nO1xyXG5cdH0sXHJcblxyXG5cdC8vIEFjdHVhbGx5IGRyYXcgdGhlIHRpdGxlIGJsb2NrIG9uIHRoZSBjYW52YXNcclxuXHRkcmF3OiBmdW5jdGlvbigpIHtcclxuXHRcdHZhciBtZSA9IHRoaXM7XHJcblx0XHR2YXIgY3R4ID0gbWUuY3R4O1xyXG5cdFx0dmFyIG9wdHMgPSBtZS5vcHRpb25zO1xyXG5cclxuXHRcdGlmICghb3B0cy5kaXNwbGF5KSB7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHJcblx0XHR2YXIgZm9udE9wdHMgPSBoZWxwZXJzJDEub3B0aW9ucy5fcGFyc2VGb250KG9wdHMpO1xyXG5cdFx0dmFyIGxpbmVIZWlnaHQgPSBmb250T3B0cy5saW5lSGVpZ2h0O1xyXG5cdFx0dmFyIG9mZnNldCA9IGxpbmVIZWlnaHQgLyAyICsgb3B0cy5wYWRkaW5nO1xyXG5cdFx0dmFyIHJvdGF0aW9uID0gMDtcclxuXHRcdHZhciB0b3AgPSBtZS50b3A7XHJcblx0XHR2YXIgbGVmdCA9IG1lLmxlZnQ7XHJcblx0XHR2YXIgYm90dG9tID0gbWUuYm90dG9tO1xyXG5cdFx0dmFyIHJpZ2h0ID0gbWUucmlnaHQ7XHJcblx0XHR2YXIgbWF4V2lkdGgsIHRpdGxlWCwgdGl0bGVZO1xyXG5cclxuXHRcdGN0eC5maWxsU3R5bGUgPSBoZWxwZXJzJDEudmFsdWVPckRlZmF1bHQob3B0cy5mb250Q29sb3IsIGNvcmVfZGVmYXVsdHMuZ2xvYmFsLmRlZmF1bHRGb250Q29sb3IpOyAvLyByZW5kZXIgaW4gY29ycmVjdCBjb2xvdXJcclxuXHRcdGN0eC5mb250ID0gZm9udE9wdHMuc3RyaW5nO1xyXG5cclxuXHRcdC8vIEhvcml6b250YWxcclxuXHRcdGlmIChtZS5pc0hvcml6b250YWwoKSkge1xyXG5cdFx0XHR0aXRsZVggPSBsZWZ0ICsgKChyaWdodCAtIGxlZnQpIC8gMik7IC8vIG1pZHBvaW50IG9mIHRoZSB3aWR0aFxyXG5cdFx0XHR0aXRsZVkgPSB0b3AgKyBvZmZzZXQ7XHJcblx0XHRcdG1heFdpZHRoID0gcmlnaHQgLSBsZWZ0O1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0dGl0bGVYID0gb3B0cy5wb3NpdGlvbiA9PT0gJ2xlZnQnID8gbGVmdCArIG9mZnNldCA6IHJpZ2h0IC0gb2Zmc2V0O1xyXG5cdFx0XHR0aXRsZVkgPSB0b3AgKyAoKGJvdHRvbSAtIHRvcCkgLyAyKTtcclxuXHRcdFx0bWF4V2lkdGggPSBib3R0b20gLSB0b3A7XHJcblx0XHRcdHJvdGF0aW9uID0gTWF0aC5QSSAqIChvcHRzLnBvc2l0aW9uID09PSAnbGVmdCcgPyAtMC41IDogMC41KTtcclxuXHRcdH1cclxuXHJcblx0XHRjdHguc2F2ZSgpO1xyXG5cdFx0Y3R4LnRyYW5zbGF0ZSh0aXRsZVgsIHRpdGxlWSk7XHJcblx0XHRjdHgucm90YXRlKHJvdGF0aW9uKTtcclxuXHRcdGN0eC50ZXh0QWxpZ24gPSAnY2VudGVyJztcclxuXHRcdGN0eC50ZXh0QmFzZWxpbmUgPSAnbWlkZGxlJztcclxuXHJcblx0XHR2YXIgdGV4dCA9IG9wdHMudGV4dDtcclxuXHRcdGlmIChoZWxwZXJzJDEuaXNBcnJheSh0ZXh0KSkge1xyXG5cdFx0XHR2YXIgeSA9IDA7XHJcblx0XHRcdGZvciAodmFyIGkgPSAwOyBpIDwgdGV4dC5sZW5ndGg7ICsraSkge1xyXG5cdFx0XHRcdGN0eC5maWxsVGV4dCh0ZXh0W2ldLCAwLCB5LCBtYXhXaWR0aCk7XHJcblx0XHRcdFx0eSArPSBsaW5lSGVpZ2h0O1xyXG5cdFx0XHR9XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRjdHguZmlsbFRleHQodGV4dCwgMCwgMCwgbWF4V2lkdGgpO1xyXG5cdFx0fVxyXG5cclxuXHRcdGN0eC5yZXN0b3JlKCk7XHJcblx0fVxyXG59KTtcclxuXHJcbmZ1bmN0aW9uIGNyZWF0ZU5ld1RpdGxlQmxvY2tBbmRBdHRhY2goY2hhcnQsIHRpdGxlT3B0cykge1xyXG5cdHZhciB0aXRsZSA9IG5ldyBUaXRsZSh7XHJcblx0XHRjdHg6IGNoYXJ0LmN0eCxcclxuXHRcdG9wdGlvbnM6IHRpdGxlT3B0cyxcclxuXHRcdGNoYXJ0OiBjaGFydFxyXG5cdH0pO1xyXG5cclxuXHRjb3JlX2xheW91dHMuY29uZmlndXJlKGNoYXJ0LCB0aXRsZSwgdGl0bGVPcHRzKTtcclxuXHRjb3JlX2xheW91dHMuYWRkQm94KGNoYXJ0LCB0aXRsZSk7XHJcblx0Y2hhcnQudGl0bGVCbG9jayA9IHRpdGxlO1xyXG59XHJcblxyXG52YXIgcGx1Z2luX3RpdGxlID0ge1xyXG5cdGlkOiAndGl0bGUnLFxyXG5cclxuXHQvKipcclxuXHQgKiBCYWNrd2FyZCBjb21wYXRpYmlsaXR5OiBzaW5jZSAyLjEuNSwgdGhlIHRpdGxlIGlzIHJlZ2lzdGVyZWQgYXMgYSBwbHVnaW4sIG1ha2luZ1xyXG5cdCAqIENoYXJ0LlRpdGxlIG9ic29sZXRlLiBUbyBhdm9pZCBhIGJyZWFraW5nIGNoYW5nZSwgd2UgZXhwb3J0IHRoZSBUaXRsZSBhcyBwYXJ0IG9mXHJcblx0ICogdGhlIHBsdWdpbiwgd2hpY2ggb25lIHdpbGwgYmUgcmUtZXhwb3NlZCBpbiB0aGUgY2hhcnQuanMgZmlsZS5cclxuXHQgKiBodHRwczovL2dpdGh1Yi5jb20vY2hhcnRqcy9DaGFydC5qcy9wdWxsLzI2NDBcclxuXHQgKiBAcHJpdmF0ZVxyXG5cdCAqL1xyXG5cdF9lbGVtZW50OiBUaXRsZSxcclxuXHJcblx0YmVmb3JlSW5pdDogZnVuY3Rpb24oY2hhcnQpIHtcclxuXHRcdHZhciB0aXRsZU9wdHMgPSBjaGFydC5vcHRpb25zLnRpdGxlO1xyXG5cclxuXHRcdGlmICh0aXRsZU9wdHMpIHtcclxuXHRcdFx0Y3JlYXRlTmV3VGl0bGVCbG9ja0FuZEF0dGFjaChjaGFydCwgdGl0bGVPcHRzKTtcclxuXHRcdH1cclxuXHR9LFxyXG5cclxuXHRiZWZvcmVVcGRhdGU6IGZ1bmN0aW9uKGNoYXJ0KSB7XHJcblx0XHR2YXIgdGl0bGVPcHRzID0gY2hhcnQub3B0aW9ucy50aXRsZTtcclxuXHRcdHZhciB0aXRsZUJsb2NrID0gY2hhcnQudGl0bGVCbG9jaztcclxuXHJcblx0XHRpZiAodGl0bGVPcHRzKSB7XHJcblx0XHRcdGhlbHBlcnMkMS5tZXJnZUlmKHRpdGxlT3B0cywgY29yZV9kZWZhdWx0cy5nbG9iYWwudGl0bGUpO1xyXG5cclxuXHRcdFx0aWYgKHRpdGxlQmxvY2spIHtcclxuXHRcdFx0XHRjb3JlX2xheW91dHMuY29uZmlndXJlKGNoYXJ0LCB0aXRsZUJsb2NrLCB0aXRsZU9wdHMpO1xyXG5cdFx0XHRcdHRpdGxlQmxvY2sub3B0aW9ucyA9IHRpdGxlT3B0cztcclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRjcmVhdGVOZXdUaXRsZUJsb2NrQW5kQXR0YWNoKGNoYXJ0LCB0aXRsZU9wdHMpO1xyXG5cdFx0XHR9XHJcblx0XHR9IGVsc2UgaWYgKHRpdGxlQmxvY2spIHtcclxuXHRcdFx0Y29yZV9sYXlvdXRzLnJlbW92ZUJveChjaGFydCwgdGl0bGVCbG9jayk7XHJcblx0XHRcdGRlbGV0ZSBjaGFydC50aXRsZUJsb2NrO1xyXG5cdFx0fVxyXG5cdH1cclxufTtcblxudmFyIHBsdWdpbnMgPSB7fTtcclxudmFyIGZpbGxlciA9IHBsdWdpbl9maWxsZXI7XHJcbnZhciBsZWdlbmQgPSBwbHVnaW5fbGVnZW5kO1xyXG52YXIgdGl0bGUgPSBwbHVnaW5fdGl0bGU7XG5wbHVnaW5zLmZpbGxlciA9IGZpbGxlcjtcbnBsdWdpbnMubGVnZW5kID0gbGVnZW5kO1xucGx1Z2lucy50aXRsZSA9IHRpdGxlO1xuXG4vKipcclxuICogQG5hbWVzcGFjZSBDaGFydFxyXG4gKi9cclxuXHJcblxyXG5jb3JlX2NvbnRyb2xsZXIuaGVscGVycyA9IGhlbHBlcnMkMTtcclxuXHJcbi8vIEB0b2RvIGRpc3BhdGNoIHRoZXNlIGhlbHBlcnMgaW50byBhcHByb3ByaWF0ZWQgaGVscGVycy9oZWxwZXJzLiogZmlsZSBhbmQgd3JpdGUgdW5pdCB0ZXN0cyFcclxuY29yZV9oZWxwZXJzKCk7XHJcblxyXG5jb3JlX2NvbnRyb2xsZXIuX2FkYXB0ZXJzID0gY29yZV9hZGFwdGVycztcclxuY29yZV9jb250cm9sbGVyLkFuaW1hdGlvbiA9IGNvcmVfYW5pbWF0aW9uO1xyXG5jb3JlX2NvbnRyb2xsZXIuYW5pbWF0aW9uU2VydmljZSA9IGNvcmVfYW5pbWF0aW9ucztcclxuY29yZV9jb250cm9sbGVyLmNvbnRyb2xsZXJzID0gY29udHJvbGxlcnM7XHJcbmNvcmVfY29udHJvbGxlci5EYXRhc2V0Q29udHJvbGxlciA9IGNvcmVfZGF0YXNldENvbnRyb2xsZXI7XHJcbmNvcmVfY29udHJvbGxlci5kZWZhdWx0cyA9IGNvcmVfZGVmYXVsdHM7XHJcbmNvcmVfY29udHJvbGxlci5FbGVtZW50ID0gY29yZV9lbGVtZW50O1xyXG5jb3JlX2NvbnRyb2xsZXIuZWxlbWVudHMgPSBlbGVtZW50cztcclxuY29yZV9jb250cm9sbGVyLkludGVyYWN0aW9uID0gY29yZV9pbnRlcmFjdGlvbjtcclxuY29yZV9jb250cm9sbGVyLmxheW91dHMgPSBjb3JlX2xheW91dHM7XHJcbmNvcmVfY29udHJvbGxlci5wbGF0Zm9ybSA9IHBsYXRmb3JtO1xyXG5jb3JlX2NvbnRyb2xsZXIucGx1Z2lucyA9IGNvcmVfcGx1Z2lucztcclxuY29yZV9jb250cm9sbGVyLlNjYWxlID0gY29yZV9zY2FsZTtcclxuY29yZV9jb250cm9sbGVyLnNjYWxlU2VydmljZSA9IGNvcmVfc2NhbGVTZXJ2aWNlO1xyXG5jb3JlX2NvbnRyb2xsZXIuVGlja3MgPSBjb3JlX3RpY2tzO1xyXG5jb3JlX2NvbnRyb2xsZXIuVG9vbHRpcCA9IGNvcmVfdG9vbHRpcDtcclxuXHJcbi8vIFJlZ2lzdGVyIGJ1aWx0LWluIHNjYWxlc1xyXG5cclxuY29yZV9jb250cm9sbGVyLmhlbHBlcnMuZWFjaChzY2FsZXMsIGZ1bmN0aW9uKHNjYWxlLCB0eXBlKSB7XHJcblx0Y29yZV9jb250cm9sbGVyLnNjYWxlU2VydmljZS5yZWdpc3RlclNjYWxlVHlwZSh0eXBlLCBzY2FsZSwgc2NhbGUuX2RlZmF1bHRzKTtcclxufSk7XHJcblxyXG4vLyBMb2FkIHRvIHJlZ2lzdGVyIGJ1aWx0LWluIGFkYXB0ZXJzIChhcyBzaWRlIGVmZmVjdHMpXHJcblxyXG5cclxuLy8gTG9hZGluZyBidWlsdC1pbiBwbHVnaW5zXHJcblxyXG5mb3IgKHZhciBrIGluIHBsdWdpbnMpIHtcclxuXHRpZiAocGx1Z2lucy5oYXNPd25Qcm9wZXJ0eShrKSkge1xyXG5cdFx0Y29yZV9jb250cm9sbGVyLnBsdWdpbnMucmVnaXN0ZXIocGx1Z2luc1trXSk7XHJcblx0fVxyXG59XHJcblxyXG5jb3JlX2NvbnRyb2xsZXIucGxhdGZvcm0uaW5pdGlhbGl6ZSgpO1xyXG5cclxudmFyIHNyYyA9IGNvcmVfY29udHJvbGxlcjtcclxuaWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnKSB7XHJcblx0d2luZG93LkNoYXJ0ID0gY29yZV9jb250cm9sbGVyO1xyXG59XHJcblxyXG4vLyBERVBSRUNBVElPTlNcclxuXHJcbi8qKlxyXG4gKiBQcm92aWRlZCBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSwgbm90IGF2YWlsYWJsZSBhbnltb3JlXHJcbiAqIEBuYW1lc3BhY2UgQ2hhcnQuQ2hhcnRcclxuICogQGRlcHJlY2F0ZWQgc2luY2UgdmVyc2lvbiAyLjguMFxyXG4gKiBAdG9kbyByZW1vdmUgYXQgdmVyc2lvbiAzXHJcbiAqIEBwcml2YXRlXHJcbiAqL1xyXG5jb3JlX2NvbnRyb2xsZXIuQ2hhcnQgPSBjb3JlX2NvbnRyb2xsZXI7XHJcblxyXG4vKipcclxuICogUHJvdmlkZWQgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHksIG5vdCBhdmFpbGFibGUgYW55bW9yZVxyXG4gKiBAbmFtZXNwYWNlIENoYXJ0LkxlZ2VuZFxyXG4gKiBAZGVwcmVjYXRlZCBzaW5jZSB2ZXJzaW9uIDIuMS41XHJcbiAqIEB0b2RvIHJlbW92ZSBhdCB2ZXJzaW9uIDNcclxuICogQHByaXZhdGVcclxuICovXHJcbmNvcmVfY29udHJvbGxlci5MZWdlbmQgPSBwbHVnaW5zLmxlZ2VuZC5fZWxlbWVudDtcclxuXHJcbi8qKlxyXG4gKiBQcm92aWRlZCBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSwgbm90IGF2YWlsYWJsZSBhbnltb3JlXHJcbiAqIEBuYW1lc3BhY2UgQ2hhcnQuVGl0bGVcclxuICogQGRlcHJlY2F0ZWQgc2luY2UgdmVyc2lvbiAyLjEuNVxyXG4gKiBAdG9kbyByZW1vdmUgYXQgdmVyc2lvbiAzXHJcbiAqIEBwcml2YXRlXHJcbiAqL1xyXG5jb3JlX2NvbnRyb2xsZXIuVGl0bGUgPSBwbHVnaW5zLnRpdGxlLl9lbGVtZW50O1xyXG5cclxuLyoqXHJcbiAqIFByb3ZpZGVkIGZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5LCB1c2UgQ2hhcnQucGx1Z2lucyBpbnN0ZWFkXHJcbiAqIEBuYW1lc3BhY2UgQ2hhcnQucGx1Z2luU2VydmljZVxyXG4gKiBAZGVwcmVjYXRlZCBzaW5jZSB2ZXJzaW9uIDIuMS41XHJcbiAqIEB0b2RvIHJlbW92ZSBhdCB2ZXJzaW9uIDNcclxuICogQHByaXZhdGVcclxuICovXHJcbmNvcmVfY29udHJvbGxlci5wbHVnaW5TZXJ2aWNlID0gY29yZV9jb250cm9sbGVyLnBsdWdpbnM7XHJcblxyXG4vKipcclxuICogUHJvdmlkZWQgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHksIGluaGVyaXRpbmcgZnJvbSBDaGFydC5QbHVnaW5nQmFzZSBoYXMgbm9cclxuICogZWZmZWN0LCBpbnN0ZWFkIHNpbXBseSBjcmVhdGUvcmVnaXN0ZXIgcGx1Z2lucyB2aWEgcGxhaW4gSmF2YVNjcmlwdCBvYmplY3RzLlxyXG4gKiBAaW50ZXJmYWNlIENoYXJ0LlBsdWdpbkJhc2VcclxuICogQGRlcHJlY2F0ZWQgc2luY2UgdmVyc2lvbiAyLjUuMFxyXG4gKiBAdG9kbyByZW1vdmUgYXQgdmVyc2lvbiAzXHJcbiAqIEBwcml2YXRlXHJcbiAqL1xyXG5jb3JlX2NvbnRyb2xsZXIuUGx1Z2luQmFzZSA9IGNvcmVfY29udHJvbGxlci5FbGVtZW50LmV4dGVuZCh7fSk7XHJcblxyXG4vKipcclxuICogUHJvdmlkZWQgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHksIHVzZSBDaGFydC5oZWxwZXJzLmNhbnZhcyBpbnN0ZWFkLlxyXG4gKiBAbmFtZXNwYWNlIENoYXJ0LmNhbnZhc0hlbHBlcnNcclxuICogQGRlcHJlY2F0ZWQgc2luY2UgdmVyc2lvbiAyLjYuMFxyXG4gKiBAdG9kbyByZW1vdmUgYXQgdmVyc2lvbiAzXHJcbiAqIEBwcml2YXRlXHJcbiAqL1xyXG5jb3JlX2NvbnRyb2xsZXIuY2FudmFzSGVscGVycyA9IGNvcmVfY29udHJvbGxlci5oZWxwZXJzLmNhbnZhcztcclxuXHJcbi8qKlxyXG4gKiBQcm92aWRlZCBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSwgdXNlIENoYXJ0LmxheW91dHMgaW5zdGVhZC5cclxuICogQG5hbWVzcGFjZSBDaGFydC5sYXlvdXRTZXJ2aWNlXHJcbiAqIEBkZXByZWNhdGVkIHNpbmNlIHZlcnNpb24gMi43LjNcclxuICogQHRvZG8gcmVtb3ZlIGF0IHZlcnNpb24gM1xyXG4gKiBAcHJpdmF0ZVxyXG4gKi9cclxuY29yZV9jb250cm9sbGVyLmxheW91dFNlcnZpY2UgPSBjb3JlX2NvbnRyb2xsZXIubGF5b3V0cztcclxuXHJcbi8qKlxyXG4gKiBQcm92aWRlZCBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSwgbm90IGF2YWlsYWJsZSBhbnltb3JlLlxyXG4gKiBAbmFtZXNwYWNlIENoYXJ0LkxpbmVhclNjYWxlQmFzZVxyXG4gKiBAZGVwcmVjYXRlZCBzaW5jZSB2ZXJzaW9uIDIuOFxyXG4gKiBAdG9kbyByZW1vdmUgYXQgdmVyc2lvbiAzXHJcbiAqIEBwcml2YXRlXHJcbiAqL1xyXG5jb3JlX2NvbnRyb2xsZXIuTGluZWFyU2NhbGVCYXNlID0gc2NhbGVfbGluZWFyYmFzZTtcclxuXHJcbi8qKlxyXG4gKiBQcm92aWRlZCBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eSwgaW5zdGVhZCB3ZSBzaG91bGQgY3JlYXRlIGEgbmV3IENoYXJ0XHJcbiAqIGJ5IHNldHRpbmcgdGhlIHR5cGUgaW4gdGhlIGNvbmZpZyAoYG5ldyBDaGFydChpZCwge3R5cGU6ICd7Y2hhcnQtdHlwZX0nfWApLlxyXG4gKiBAZGVwcmVjYXRlZCBzaW5jZSB2ZXJzaW9uIDIuOC4wXHJcbiAqIEB0b2RvIHJlbW92ZSBhdCB2ZXJzaW9uIDNcclxuICovXHJcbmNvcmVfY29udHJvbGxlci5oZWxwZXJzLmVhY2goXHJcblx0W1xyXG5cdFx0J0JhcicsXHJcblx0XHQnQnViYmxlJyxcclxuXHRcdCdEb3VnaG51dCcsXHJcblx0XHQnTGluZScsXHJcblx0XHQnUG9sYXJBcmVhJyxcclxuXHRcdCdSYWRhcicsXHJcblx0XHQnU2NhdHRlcidcclxuXHRdLFxyXG5cdGZ1bmN0aW9uKGtsYXNzKSB7XHJcblx0XHRjb3JlX2NvbnRyb2xsZXJba2xhc3NdID0gZnVuY3Rpb24oY3R4LCBjZmcpIHtcclxuXHRcdFx0cmV0dXJuIG5ldyBjb3JlX2NvbnRyb2xsZXIoY3R4LCBjb3JlX2NvbnRyb2xsZXIuaGVscGVycy5tZXJnZShjZmcgfHwge30sIHtcclxuXHRcdFx0XHR0eXBlOiBrbGFzcy5jaGFyQXQoMCkudG9Mb3dlckNhc2UoKSArIGtsYXNzLnNsaWNlKDEpXHJcblx0XHRcdH0pKTtcclxuXHRcdH07XHJcblx0fVxyXG4pO1xuXG5yZXR1cm4gc3JjO1xuXG59KSkpO1xuIl0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./node_modules/chart.js/dist/Chart.js\n");
/***/ }),
/***/ "./node_modules/jquery-autocomplete/jquery.autocomplete.js":
/*!*****************************************************************!*\
!*** ./node_modules/jquery-autocomplete/jquery.autocomplete.js ***!
\*****************************************************************/
/***/ (() => {
eval("/**\r\n * @preserve jQuery Autocomplete plugin v1.2.6\r\n * @homepage http://xdsoft.net/jqplugins/autocomplete/\r\n * @license MIT - MIT-LICENSE.txt\r\n * (c) 2014, Chupurnov Valeriy <chupurnov@gmail.com>\r\n */\r\n(function ($) {\r\n\t'use strict';\r\n\tvar\tARROWLEFT = 37,\r\n\t\tARROWRIGHT = 39,\r\n\t\tARROWUP = 38,\r\n\t\tARROWDOWN = 40,\r\n\t\tTAB = 9,\r\n\t\tCTRLKEY = 17,\r\n\t\tSHIFTKEY = 16,\r\n\t\tDEL = 46,\r\n\t\tENTER = 13,\r\n\t\tESC = 27,\r\n\t\tBACKSPACE = 8,\r\n\t\tAKEY = 65,\r\n\t\tCKEY = 67,\r\n\t\tVKEY = 86,\r\n\t\tZKEY = 90,\r\n\t\tYKEY = 89,\r\n\t\tdefaultSetting = {},\r\n\t\t//currentInput = false,\r\n\t\tctrlDown = false,\r\n\t\tshiftDown = false,\r\n\t\tpublics = {},\r\n\t\taccent_map = {\r\n\t\t\t'ẚ':'a','Á':'a','á':'a','À':'a','à':'a','Ă':'a','ă':'a','Ắ':'a','ắ':'a','Ằ':'a','ằ':'a','Ẵ':'a','ẵ':'a','Ẳ':'a',\r\n\t\t\t'Ẫ':'a','ẫ':'a','Ẩ':'a','ẩ':'a','Ǎ':'a','ǎ':'a','Å':'a','å':'a','Ǻ':'a','ǻ':'a','Ä':'a','ä':'a','Ǟ':'a','ǟ':'a',\r\n\t\t\t'Ã':'a','ã':'a','Ȧ':'a','ȧ':'a','Ǡ':'a','ǡ':'a','Ą':'a','ą':'a','Ā':'a','ā':'a','Ả':'a','ả':'a','Ȁ':'a','ȁ':'a',\r\n\t\t\t'Ȃ':'a','ȃ':'a','Ạ':'a','ạ':'a','Ặ':'a','ặ':'a','Ậ':'a','ậ':'a','Ḁ':'a','ḁ':'a','Ⱥ':'a','ⱥ':'a','Ǽ':'a','ǽ':'a',\r\n\t\t\t'Ǣ':'a','ǣ':'a','Ḃ':'b','ḃ':'b','Ḅ':'b','ḅ':'b','Ḇ':'b','ḇ':'b','Ƀ':'b','ƀ':'b','ᵬ':'b','Ɓ':'b','ɓ':'b','Ƃ':'b',\r\n\t\t\t'ƃ':'b','Ć':'c','ć':'c','Ĉ':'c','ĉ':'c','Č':'c','č':'c','Ċ':'c','ċ':'c','Ç':'c','ç':'c','Ḉ':'c','ḉ':'c','Ȼ':'c',\r\n\t\t\t'ȼ':'c','Ƈ':'c','ƈ':'c','ɕ':'c','Ď':'d','ď':'d','Ḋ':'d','ḋ':'d','Ḑ':'d','ḑ':'d','Ḍ':'d','ḍ':'d','Ḓ':'d','ḓ':'d',\r\n\t\t\t'Ḏ':'d','ḏ':'d','Đ':'d','đ':'d','ᵭ':'d','Ɖ':'d','ɖ':'d','Ɗ':'d','ɗ':'d','Ƌ':'d','ƌ':'d','ȡ':'d','ð':'d','É':'e',\r\n\t\t\t'Ə':'e','Ǝ':'e','ǝ':'e','é':'e','È':'e','è':'e','Ĕ':'e','ĕ':'e','Ê':'e','ê':'e','Ế':'e','ế':'e','Ề':'e','ề':'e',\r\n\t\t\t'Ễ':'e','ễ':'e','Ể':'e','ể':'e','Ě':'e','ě':'e','Ë':'e','ë':'e','Ẽ':'e','ẽ':'e','Ė':'e','ė':'e','Ȩ':'e','ȩ':'e',\r\n\t\t\t'Ḝ':'e','ḝ':'e','Ę':'e','ę':'e','Ē':'e','ē':'e','Ḗ':'e','ḗ':'e','Ḕ':'e','ḕ':'e','Ẻ':'e','ẻ':'e','Ȅ':'e','ȅ':'e',\r\n\t\t\t'Ȇ':'e','ȇ':'e','Ẹ':'e','ẹ':'e','Ệ':'e','ệ':'e','Ḙ':'e','ḙ':'e','Ḛ':'e','ḛ':'e','Ɇ':'e','ɇ':'e','ɚ':'e','ɝ':'e',\r\n\t\t\t'Ḟ':'f','ḟ':'f','ᵮ':'f','Ƒ':'f','ƒ':'f','Ǵ':'g','ǵ':'g','Ğ':'g','ğ':'g','Ĝ':'g','ĝ':'g','Ǧ':'g','ǧ':'g','Ġ':'g',\r\n\t\t\t'ġ':'g','Ģ':'g','ģ':'g','Ḡ':'g','ḡ':'g','Ǥ':'g','ǥ':'g','Ɠ':'g','ɠ':'g','Ĥ':'h','ĥ':'h','Ȟ':'h','ȟ':'h','Ḧ':'h',\r\n\t\t\t'ḧ':'h','Ḣ':'h','ḣ':'h','Ḩ':'h','ḩ':'h','Ḥ':'h','ḥ':'h','Ḫ':'h','ḫ':'h','H':'h','̱':'h','ẖ':'h','Ħ':'h','ħ':'h',\r\n\t\t\t'Ⱨ':'h','ⱨ':'h','Í':'i','í':'i','Ì':'i','ì':'i','Ĭ':'i','ĭ':'i','Î':'i','î':'i','Ǐ':'i','ǐ':'i','Ï':'i','ï':'i',\r\n\t\t\t'Ḯ':'i','ḯ':'i','Ĩ':'i','ĩ':'i','İ':'i','i':'i','Į':'i','į':'i','Ī':'i','ī':'i','Ỉ':'i','ỉ':'i','Ȉ':'i','ȉ':'i',\r\n\t\t\t'Ȋ':'i','ȋ':'i','Ị':'i','ị':'i','Ḭ':'i','ḭ':'i','I':'i','ı':'i','Ɨ':'i','ɨ':'i','Ĵ':'j','ĵ':'j','J':'j','̌':'j',\r\n\t\t\t'ǰ':'j','ȷ':'j','Ɉ':'j','ɉ':'j','ʝ':'j','ɟ':'j','ʄ':'j','Ḱ':'k','ḱ':'k','Ǩ':'k','ǩ':'k','Ķ':'k','ķ':'k','Ḳ':'k',\r\n\t\t\t'ḳ':'k','Ḵ':'k','ḵ':'k','Ƙ':'k','ƙ':'k','Ⱪ':'k','ⱪ':'k','Ĺ':'a','ĺ':'l','Ľ':'l','ľ':'l','Ļ':'l','ļ':'l','Ḷ':'l',\r\n\t\t\t'ḷ':'l','Ḹ':'l','ḹ':'l','Ḽ':'l','ḽ':'l','Ḻ':'l','ḻ':'l','Ł':'l','ł':'l','̣':'l','Ŀ':'l',\r\n\t\t\t'ŀ':'l','Ƚ':'l','ƚ':'l','Ⱡ':'l','ⱡ':'l','Ɫ':'l','ɫ':'l','ɬ':'l','ɭ':'l','ȴ':'l','Ḿ':'m','ḿ':'m','Ṁ':'m','ṁ':'m',\r\n\t\t\t'Ṃ':'m','ṃ':'m','ɱ':'m','Ń':'n','ń':'n','Ǹ':'n','ǹ':'n','Ň':'n','ň':'n','Ñ':'n','ñ':'n','Ṅ':'n','ṅ':'n','Ņ':'n',\r\n\t\t\t'ņ':'n','Ṇ':'n','ṇ':'n','Ṋ':'n','ṋ':'n','Ṉ':'n','ṉ':'n','Ɲ':'n','ɲ':'n','Ƞ':'n','ƞ':'n','ɳ':'n','ȵ':'n','N':'n',\r\n\t\t\t'̈':'n','n':'n','Ó':'o','ó':'o','Ò':'o','ò':'o','Ŏ':'o','ŏ':'o','Ô':'o','ô':'o','Ố':'o','ố':'o','Ồ':'o',\r\n\t\t\t'ồ':'o','Ỗ':'o','ỗ':'o','Ổ':'o','ổ':'o','Ǒ':'o','ǒ':'o','Ö':'o','ö':'o','Ȫ':'o','ȫ':'o','Ő':'o','ő':'o','Õ':'o',\r\n\t\t\t'õ':'o','Ṍ':'o','ṍ':'o','Ṏ':'o','ṏ':'o','Ȭ':'o','ȭ':'o','Ȯ':'o','ȯ':'o','Ȱ':'o','ȱ':'o','Ø':'o','ø':'o','Ǿ':'o',\r\n\t\t\t'ǿ':'o','Ǫ':'o','ǫ':'o','Ǭ':'o','ǭ':'o','Ō':'o','ō':'o','Ṓ':'o','ṓ':'o','Ṑ':'o','ṑ':'o','Ỏ':'o','ỏ':'o','Ȍ':'o',\r\n\t\t\t'ȍ':'o','Ȏ':'o','ȏ':'o','Ơ':'o','ơ':'o','Ớ':'o','ớ':'o','Ờ':'o','ờ':'o','Ỡ':'o','ỡ':'o','Ở':'o','ở':'o','Ợ':'o',\r\n\t\t\t'ợ':'o','Ọ':'o','ọ':'o','Ộ':'o','ộ':'o','Ɵ':'o','ɵ':'o','Ṕ':'p','ṕ':'p','Ṗ':'p','ṗ':'p','Ᵽ':'p','Ƥ':'p','ƥ':'p',\r\n\t\t\t'P':'p','̃':'p','p':'p','ʠ':'q','Ɋ':'q','ɋ':'q','Ŕ':'r','ŕ':'r','Ř':'r','ř':'r','Ṙ':'r','ṙ':'r','Ŗ':'r',\r\n\t\t\t'ŗ':'r','Ȑ':'r','ȑ':'r','Ȓ':'r','ȓ':'r','Ṛ':'r','ṛ':'r','Ṝ':'r','ṝ':'r','Ṟ':'r','ṟ':'r','Ɍ':'r','ɍ':'r','ᵲ':'r',\r\n\t\t\t'ɼ':'r','Ɽ':'r','ɽ':'r','ɾ':'r','ᵳ':'r','ß':'s','Ś':'s','ś':'s','Ṥ':'s','ṥ':'s','Ŝ':'s','ŝ':'s','Š':'s','š':'s',\r\n\t\t\t'Ṧ':'s','ṧ':'s','Ṡ':'s','ṡ':'s','ẛ':'s','Ş':'s','ş':'s','Ṣ':'s','ṣ':'s','Ṩ':'s','ṩ':'s','Ș':'s','ș':'s','ʂ':'s',\r\n\t\t\t'S':'s','̩':'s','s':'s','Þ':'t','þ':'t','Ť':'t','ť':'t','T':'t','ẗ':'t','Ṫ':'t','ṫ':'t','Ţ':'t','ţ':'t','Ṭ':'t',\r\n\t\t\t'ṭ':'t','Ț':'t','ț':'t','Ṱ':'t','ṱ':'t','Ṯ':'t','ṯ':'t','Ŧ':'t','ŧ':'t','Ⱦ':'t','ⱦ':'t','ᵵ':'t',\r\n\t\t\t'ƫ':'t','Ƭ':'t','ƭ':'t','Ʈ':'t','ʈ':'t','ȶ':'t','Ú':'u','ú':'u','Ù':'u','ù':'u','Ŭ':'u','ŭ':'u','Û':'u','û':'u',\r\n\t\t\t'Ǔ':'u','ǔ':'u','Ů':'u','ů':'u','Ü':'u','ü':'u','Ǘ':'u','ǘ':'u','Ǜ':'u','ǜ':'u','Ǚ':'u','ǚ':'u','Ǖ':'u','ǖ':'u',\r\n\t\t\t'Ű':'u','ű':'u','Ũ':'u','ũ':'u','Ṹ':'u','ṹ':'u','Ų':'u','ų':'u','Ū':'u','ū':'u','Ṻ':'u','ṻ':'u','Ủ':'u','ủ':'u',\r\n\t\t\t'Ȕ':'u','ȕ':'u','Ȗ':'u','ȗ':'u','Ư':'u','ư':'u','Ứ':'u','ứ':'u','Ừ':'u','ừ':'u','Ữ':'u','ữ':'u','Ử':'u','ử':'u',\r\n\t\t\t'Ự':'u','ự':'u','Ụ':'u','ụ':'u','Ṳ':'u','ṳ':'u','Ṷ':'u','ṷ':'u','Ṵ':'u','ṵ':'u','Ʉ':'u','ʉ':'u','Ṽ':'v','ṽ':'v',\r\n\t\t\t'Ṿ':'v','ṿ':'v','Ʋ':'v','ʋ':'v','Ẃ':'w','ẃ':'w','Ẁ':'w','ẁ':'w','Ŵ':'w','ŵ':'w','W':'w','̊':'w','ẘ':'w','Ẅ':'w',\r\n\t\t\t'ẅ':'w','Ẇ':'w','ẇ':'w','Ẉ':'w','ẉ':'w','Ẍ':'x','ẍ':'x','Ẋ':'x','ẋ':'x','Ý':'y','ý':'y','Ỳ':'y','ỳ':'y','Ŷ':'y',\r\n\t\t\t'ŷ':'y','Y':'y','ẙ':'y','Ÿ':'y','ÿ':'y','Ỹ':'y','ỹ':'y','Ẏ':'y','ẏ':'y','Ȳ':'y','ȳ':'y','Ỷ':'y','ỷ':'y',\r\n\t\t\t'Ỵ':'y','ỵ':'y','ʏ':'y','Ɏ':'y','ɏ':'y','Ƴ':'y','ƴ':'y','Ź':'z','ź':'z','Ẑ':'z','ẑ':'z','Ž':'z','ž':'z','Ż':'z',\r\n\t\t\t'ż':'z','Ẓ':'z','ẓ':'z','Ẕ':'z','ẕ':'z','Ƶ':'z','ƶ':'z','Ȥ':'z','ȥ':'z','ʐ':'z','ʑ':'z','Ⱬ':'z','ⱬ':'z','Ǯ':'z',\r\n\t\t\t'ǯ':'z','ƺ':'z','':'2','':'6','':'B','':'F','':'J','':'N','':'R','':'V','':'Z','':'b','':'f','':'j',\r\n\t\t\t'':'n','':'r','':'v','':'z','':'1','':'5','':'9','':'A','':'E','':'I','':'M','':'Q','':'U','':'Y',\r\n\t\t\t'':'a','':'e','':'i','':'m','':'q','':'u','':'y','':'0','':'4','':'8','':'D','':'H','':'L','':'P',\r\n\t\t\t'':'T','':'X','':'d','':'h','':'l','':'p','':'t','':'x','':'3','':'7','':'C','':'G','':'K','':'O',\r\n\t\t\t'':'S','':'W','':'c','':'g','':'k','':'o','':'s','':'w','ẳ':'a','Â':'a','â':'a','Ấ':'a','ấ':'a','Ầ':'a','ầ':'a'\r\n\t\t};\r\n\r\n\tif (window.getComputedStyle === undefined) {\r\n\t\twindow.getComputedStyle = (function () {\r\n\t\t\tfunction getPixelSize(element, style, property, fontSize) {\r\n\t\t\t\tvar\tsizeWithSuffix = style[property],\r\n\t\t\t\t\tsize = parseFloat(sizeWithSuffix),\r\n\t\t\t\t\tsuffix = sizeWithSuffix.split(/\\d/)[0],\r\n\t\t\t\t\trootSize;\r\n\r\n\t\t\t\tfontSize = fontSize !== null ? fontSize : /%|em/.test(suffix) && element.parentElement ? getPixelSize(element.parentElement, element.parentElement.currentStyle, 'fontSize', null) : 16;\r\n\t\t\t\trootSize = property === 'fontSize' ? fontSize : /width/i.test(property) ? element.clientWidth : element.clientHeight;\r\n\r\n\t\t\t\treturn (suffix === 'em') ? size * fontSize : (suffix === 'in') ? size * 96 : (suffix === 'pt') ? size * 96 / 72 : (suffix === '%') ? size / 100 * rootSize : size;\r\n\t\t\t}\r\n\r\n\t\t\tfunction setShortStyleProperty(style, property) {\r\n\t\t\t\tvar\tborderSuffix = property === 'border' ? 'Width' : '',\r\n\t\t\t\t\tt = property + 'Top' + borderSuffix,\r\n\t\t\t\t\tr = property + 'Right' + borderSuffix,\r\n\t\t\t\t\tb = property + 'Bottom' + borderSuffix,\r\n\t\t\t\t\tl = property + 'Left' + borderSuffix;\r\n\r\n\t\t\t\tstyle[property] = (style[t] === style[r] === style[b] === style[l] ? [style[t]]\r\n\t\t\t\t\t: style[t] === style[b] && style[l] === style[r] ? [style[t], style[r]]\r\n\t\t\t\t\t\t: style[l] === style[r] ? [style[t], style[r], style[b]]\r\n\t\t\t\t\t\t\t: [style[t], style[r], style[b], style[l]]).join(' ');\r\n\t\t\t}\r\n\r\n\t\t\tfunction CSSStyleDeclaration(element) {\r\n\t\t\t\tvar\tcurrentStyle = element.currentStyle,\r\n\t\t\t\t\tstyle = this,\r\n\t\t\t\t\tproperty,\r\n\t\t\t\t\tfontSize = getPixelSize(element, currentStyle, 'fontSize', null);\r\n\t\t\t\t\r\n\t\t\t\tfor (property in currentStyle) {\r\n\t\t\t\t\tif (Object.prototype.hasOwnProperty.call(currentStyle, property)) {\r\n\t\t\t\t\t\tif (/width|height|margin.|padding.|border.+W/.test(property) && style[property] !== 'auto') {\r\n\t\t\t\t\t\t\tstyle[property] = getPixelSize(element, currentStyle, property, fontSize) + 'px';\r\n\t\t\t\t\t\t} else if (property === 'styleFloat') {\r\n\t\t\t\t\t\t\tstyle.float = currentStyle[property];\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tstyle[property] = currentStyle[property];\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\tsetShortStyleProperty(style, 'margin');\r\n\t\t\t\tsetShortStyleProperty(style, 'padding');\r\n\t\t\t\tsetShortStyleProperty(style, 'border');\r\n\r\n\t\t\t\tstyle.fontSize = fontSize + 'px';\r\n\r\n\t\t\t\treturn style;\r\n\t\t\t}\r\n\r\n\t\t\tCSSStyleDeclaration.prototype = {\r\n\t\t\t\tconstructor: CSSStyleDeclaration,\r\n\t\t\t\tgetPropertyPriority: function () {},\r\n\t\t\t\tgetPropertyValue: function (prop) {\r\n\t\t\t\t\treturn this[prop] || '';\r\n\t\t\t\t},\r\n\t\t\t\titem: function () {},\r\n\t\t\t\tremoveProperty: function () {},\r\n\t\t\t\tsetProperty: function () {},\r\n\t\t\t\tgetPropertyCSSValue: function () {}\r\n\t\t\t};\r\n\r\n\t\t\tfunction getComputedStyle(element) {\r\n\t\t\t\treturn new CSSStyleDeclaration(element);\r\n\t\t\t}\r\n\r\n\t\t\treturn getComputedStyle;\r\n\t\t}(this));\r\n\t}\r\n\r\n\r\n\t$(document)\r\n\t\t.on('keydown.xdsoftctrl', function (e) {\r\n\t\t\tif (e.keyCode === CTRLKEY) {\r\n\t\t\t\tctrlDown = true;\r\n\t\t\t}\r\n\t\t\tif (e.keyCode === SHIFTKEY) {\r\n\t\t\t\tctrlDown = true;\r\n\t\t\t}\r\n\t\t})\r\n\t\t.on('keyup.xdsoftctrl', function (e) {\r\n\t\t\tif (e.keyCode === CTRLKEY) {\r\n\t\t\t\tctrlDown = false;\r\n\t\t\t}\r\n\t\t\tif (e.keyCode === SHIFTKEY) {\r\n\t\t\t\tctrlDown = false;\r\n\t\t\t}\r\n\t\t});\r\n\t\r\n\tfunction accentReplace (s) {\r\n\t\tif (!s) { return ''; }\r\n\t\tvar ret = '',i;\r\n\t\tfor (i=0; i < s.length; i+=1) {\r\n\t\t\tret += accent_map[s.charAt(i)] || s.charAt(i);\r\n\t\t}\r\n\t\treturn ret;\r\n\t}\r\n\t\r\n\tfunction escapeRegExp (str) {\r\n\t\treturn str.replace(/[\\-\\[\\]\\/\\{\\}\\(\\)\\*\\+\\?\\.\\\\\\^\\$\\|]/g, \"\\\\$&\");\r\n\t}\r\n\t\r\n\tfunction getCaretPosition(input) {\r\n\t\tif (!input) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tif (input.selectionStart) {\r\n\t\t\treturn input.selectionStart;\r\n\t\t}\r\n\t\tif (document.selection) {\r\n\t\t\tinput.focus();\r\n\t\t\tvar sel = document.selection.createRange(),\r\n\t\t\t\tselLen = document.selection.createRange().text.length;\r\n\t\t\tsel.moveStart('character', -input.value.length);\r\n\t\t\treturn sel.text.length - selLen;\r\n\t\t}\r\n\t}\r\n\r\n\tfunction setCaretPosition(input, pos) {\r\n\t\tif (input.setSelectionRange) {\r\n\t\t\tinput.focus();\r\n\t\t\tinput.setSelectionRange(pos, pos);\r\n\t\t} else if (input.createTextRange) {\r\n\t\t\tvar range = input.createTextRange();\r\n\t\t\trange.collapse(true);\r\n\t\t\trange.moveEnd('character', pos);\r\n\t\t\trange.moveStart('character', pos);\r\n\t\t\trange.select();\r\n\t\t}\r\n\t}\r\n\r\n\tfunction isset(value) {\r\n\t\treturn value !== undefined;\r\n\t}\r\n\r\n\tfunction safe_call(callback, args, callback2, defaultValue) {\r\n\t\tif (isset(callback) && !$.isArray(callback)) {\r\n\t\t\treturn $.isFunction(callback) ? callback.apply(this,args):defaultValue;\r\n\t\t}\r\n\t\tif(isset(callback2)) {\r\n\t\t\treturn safe_call.call(this,callback2,args);\r\n\t\t}\r\n\t\treturn defaultValue;\r\n\t};\r\n\r\n\tfunction __safe( callbackName,source,args,defaultValue ){\r\n\t\tvar undefinedVar;\r\n\t\treturn safe_call.call( this, (isset(this.source[source])&&\r\n\t\t\tObject.prototype.hasOwnProperty.call(this.source[source], callbackName)) ? this.source[source][callbackName] : undefinedVar, args, function(){\r\n\t\t\treturn safe_call.call(this,\r\n\t\t\t\t\tisset(this[callbackName][source])?\r\n\t\t\t\t\t\tthis[callbackName][source]:(\r\n\t\t\t\t\t\t\tisset(this[callbackName][0])?\r\n\t\t\t\t\t\t\t\tthis[callbackName][0]:(\r\n\t\t\t\t\t\t\t\t\tObject.prototype.hasOwnProperty.call(this, callbackName)?\r\n\t\t\t\t\t\t\t\t\t\tthis[callbackName]:\r\n\t\t\t\t\t\t\t\t\t\tundefinedVar\r\n\t\t\t\t\t\t\t\t)\r\n\t\t\t\t\t\t),\r\n\t\t\t\t\targs,\r\n\t\t\t\t\tdefaultSetting[callbackName][source]||defaultSetting[callbackName][0]||defaultSetting[callbackName],\r\n\t\t\t\t\tdefaultValue\r\n\t\t\t);\r\n\t\t},defaultValue);\r\n\t};\r\n\r\n\tfunction __get( property,source ){\r\n\t\tif(!isset(source))\r\n\t\t\tsource = 0;\r\n\t\t\r\n\t\tif( $.isArray(this.source) && isset(this.source[source]) && isset(this.source[source][property]))\r\n\t\t\treturn this.source[source][property];\r\n\t\t\t\r\n\t\tif( isset(this[property]) ){\r\n\t\t\tif( $.isArray(this[property]) ){\r\n\t\t\t\tif( isset(this[property][source]) )\r\n\t\t\t\t\treturn this[property][source];\r\n\t\t\t\tif( isset(this[property][0]) )\r\n\t\t\t\t\treturn this[property][0];\r\n\t\t\t\treturn null;\r\n\t\t\t}\r\n\t\t\treturn this[property];\r\n\t\t}\r\n\t\t\r\n\t\treturn null;\r\n\t};\r\n\r\n\tfunction loadRemote( url,sourceObject,done,debug ){\r\n\t\t if (sourceObject.xhr) {\r\n\t\t\tsourceObject.xhr.abort();\r\n\t\t }\r\n\t\t sourceObject.xhr = $.ajax($.extend(true,{\r\n\t\t\turl : url,\r\n\t\t\ttype : 'GET' ,\r\n\t\t\tasync:true,\r\n\t\t\tcache :false,\r\n\t\t\tdataType : 'json'\r\n\t\t },sourceObject.ajax))\r\n\t\t \r\n\t\t .done(function( data ){\r\n\t\t\tdone&&done.apply(this,$.makeArray(arguments));\r\n\t\t })\r\n\t\t \r\n\t\t .fail(function( jqXHR, textStatus ){\r\n\t\t\tif( debug )\r\n\t\t\t\tconsole.log(\"Request failed: \" + textStatus);\r\n\t\t });\r\n\t}\r\n\r\n\r\n\tfunction findRight( data,query ){\r\n\t\tvar right = false,source;\r\n\t\t\r\n\t\tfor (source = 0;source < data.length;source += 1) {\r\n\t\t\tif( right = __safe.call(this,\"findRight\",source,[data[source],query,source]) ){\r\n\t\t\t\treturn {right:right,source:source};\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\treturn false;\r\n\t}\r\n\r\n\tfunction processData( data,query ){\r\n\t\tvar source;\r\n\t\tpreparseData\r\n\t\t\t.call( this,data,query );\r\n\t\t\r\n\t\tfor (source = 0;source < data.length;source += 1) {\r\n\t\t\tdata[source] = __safe.call(this,\r\n\t\t\t\t'filter',\r\n\t\t\t\tsource,\r\n\t\t\t\t[data[source], query, source],\r\n\t\t\t\tdata[source]\r\n\t\t\t);\r\n\t\t}\r\n\t};\r\n\r\n\r\n\tfunction collectData( query,datasource,callback ){\r\n\t\tvar options = this,source;\r\n\t\t\r\n\t\tif( $.isFunction(options.source) ){\r\n\t\t\t\toptions.source.apply(options,[query,function(items){\r\n\t\t\t\t\tdatasource = [items];\r\n\t\t\t\t\tsafe_call.call(options,callback,[query]);\r\n\t\t\t\t},datasource,0]);\r\n\t\t}else{\r\n\t\t\tfor (source = 0;source < options.source.length;source += 1) {\r\n\t\t\t\tif ($.isArray(options.source[source])) {\r\n\t\t\t\t\tdatasource[source] = options.source[source];\r\n\t\t\t\t} else if ($.isFunction(options.source[source])) {\r\n\t\t\t\t\t(function (source) {\r\n\t\t\t\t\t\toptions.source[source].apply(options,[query, function(items){\r\n\t\t\t\t\t\t\tif (!datasource[source]) {\r\n\t\t\t\t\t\t\t\tdatasource[source] = [];\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\tif (items && $.isArray(items)) {\r\n\t\t\t\t\t\t\t\tswitch (options.appendMethod) {\r\n\t\t\t\t\t\t\t\t\tcase 'replace':\r\n\t\t\t\t\t\t\t\t\t\tdatasource[source] = items;\r\n\t\t\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\t\t\t\tdefault:\r\n\t\t\t\t\t\t\t\t\t\tdatasource[source] = datasource[source].concat(items);\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t\r\n\t\t\t\t\t\t\tsafe_call.call(options,callback,[query]);\r\n\t\t\t\t\t\t}, datasource,source]);\r\n\t\t\t\t\t}(source));\r\n\t\t\t\t} else {\r\n\t\t\t\t\tswitch (options.source[source].type) {\r\n\t\t\t\t\t\tcase 'remote':\r\n\t\t\t\t\t\t\tif (isset(options.source[source].url)) {\r\n\t\t\t\t\t\t\t\tif (!isset(options.source[source].minLength) || query.length >= options.source[source].minLength){\r\n\t\t\t\t\t\t\t\t\tvar url = __safe.call(options,'replace',source,[options.source[source].url,query],'');\r\n\t\t\t\t\t\t\t\t\tif (!datasource[source]) {\r\n\t\t\t\t\t\t\t\t\t\tdatasource[source] = [];\r\n\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t\t(function (source) {\r\n\t\t\t\t\t\t\t\t\t\tloadRemote(url,options.source[source], function(resp){\r\n\t\t\t\t\t\t\t\t\t\t\tdatasource[source] = resp;\r\n\t\t\t\t\t\t\t\t\t\t\tsafe_call.call(options,callback,[query]);\r\n\t\t\t\t\t\t\t\t\t\t},options.debug);\r\n\t\t\t\t\t\t\t\t\t}(source));\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\tdefault:\r\n\t\t\t\t\t\t\tif( isset(options.source[source]['data']) ){\r\n\t\t\t\t\t\t\t\tdatasource[source] = options.source[source]['data'];\r\n\t\t\t\t\t\t\t}else{\r\n\t\t\t\t\t\t\t\tdatasource[source] = options.source[source];\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\tsafe_call.call(options,callback,[query]);\r\n\t};\r\n\r\n\tfunction preparseData( data,query ){\r\n\t\tfor( var source=0;source<data.length;source++ ){\r\n\t\t\tdata[source] = __safe.call(this,\r\n\t\t\t\t'preparse',\r\n\t\t\t\tsource,\r\n\t\t\t\t[data[source],query],\r\n\t\t\t\tdata[source]\r\n\t\t\t);\r\n\t\t}\r\n\t};\r\n\r\n\tfunction renderData( data,query ){\r\n\t\tvar source, i, $div, $divs = [];\r\n\t\t\r\n\t\tfor (source = 0;source < data.length;source += 1) {\r\n\t\t\tfor (i = 0;i < data[source].length;i += 1) {\r\n\t\t\t\tif( $divs.length>=this.limit )\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t\t\r\n\t\t\t\t$div = $(__safe.call(this,\r\n\t\t\t\t\t'render',source,\r\n\t\t\t\t\t[data[source][i],source,i,query],\r\n\t\t\t\t\t''\r\n\t\t\t\t));\r\n\t\t\t\t\r\n\t\t\t\t$div.data('source',source);\r\n\t\t\t\t$div.data('pid',i);\r\n\t\t\t\t$div.data('item',data[source][i]);\r\n\t\t\t\t\r\n\t\t\t\t$divs.push($div);\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\treturn $divs;\r\n\t};\r\n\r\n\tfunction getItem( $div,dataset ){\r\n\t\tif( isset($div.data('source')) && \r\n\t\t\tisset($div.data('pid')) && \r\n\t\t\tisset(dataset[$div.data('source')]) && \r\n\t\t\tisset(dataset[$div.data('source')][$div.data('pid')]) \r\n\t\t){\r\n\t\t\treturn dataset[$div.data('source')][$div.data('pid')];\r\n\t\t}\r\n\t\treturn false;\r\n\t};\r\n\r\n\tfunction getValue( $div,dataset ){\r\n\t\tvar item = getItem($div,dataset);\r\n\t\t\r\n\t\tif( item ){\r\n\t\t\treturn __safe.call(this,\r\n\t\t\t\t'getValue',$div.data('source'),\r\n\t\t\t\t[item,$div.data('source')]\r\n\t\t\t);\r\n\t\t}else{\r\n\t\t\tif( isset($div.data('value')) ){\r\n\t\t\t\treturn decodeURIComponent($div.data('value'));\r\n\t\t\t}else{\r\n\t\t\t\treturn $div.html();\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n\r\n\tdefaultSetting = {\r\n\t\tminLength: 0,\r\n\t\tvalueKey: 'value',\r\n\t\ttitleKey: 'title',\r\n\t\thighlight: true,\r\n\r\n\t\tshowHint: true,\r\n\r\n\t\tdropdownWidth: '100%',\r\n\t\tdropdownStyle: {},\r\n\t\titemStyle: {},\r\n\t\thintStyle: false,\r\n\t\tstyle: false,\r\n\r\n\t\tdebug: true,\r\n\t\topenOnFocus: false,\r\n\t\tcloseOnBlur: true,\r\n\r\n\t\tautoselect: false,\r\n\t\t\r\n\t\taccents: true,\r\n\t\treplaceAccentsForRemote: true,\r\n\t\t\r\n\t\tlimit: 20,\r\n\t\tvisibleLimit: 20,\r\n\t\tvisibleHeight: 0,\r\n\t\tdefaultHeightItem: 30,\r\n\r\n\t\ttimeoutUpdate: 10,\r\n\r\n\t\tget: function (property, source) {\r\n\t\t\treturn __get.call(this,property,source);\r\n\t\t},\r\n\t\t\r\n\t\treplace: [\r\n\t\t\tfunction (url, query) {\r\n\t\t\t\tif (this.replaceAccentsForRemote) {\r\n\t\t\t\t\tquery = accentReplace(query);\r\n\t\t\t\t}\r\n\t\t\t\treturn url.replace('%QUERY%',encodeURIComponent(query));\r\n\t\t\t}\r\n\t\t],\r\n\t\t\r\n\t\tequal:function( value,query ){\r\n\t\t\treturn query.toLowerCase()==value.substr(0,query.length).toLowerCase();\r\n\t\t},\r\n\t\t\r\n\t\tfindRight:[\r\n\t\t\tfunction(items,query,source){\r\n\t\t\t\tvar results = [],value = '',i;\r\n\t\t\t\tif (items) {\r\n\t\t\t\t\tfor (i = 0;i < items.length;i += 1) {\r\n\t\t\t\t\t\tvalue = __safe.call(this,'getValue',source,[items[i],source]);\r\n\t\t\t\t\t\tif (__safe.call(this, 'equal', source, [value,query,source], false)) {\r\n\t\t\t\t\t\t\treturn items[i];\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\t\t\t\t\r\n\t\t\t\t}\r\n\t\t\t\treturn false;\r\n\t\t\t}\r\n\t\t],\r\n\t\t\r\n\t\tvalid:[\r\n\t\t\tfunction (value, query) {\r\n\t\t\t\tif (this.accents) {\r\n\t\t\t\t\tvalue = accentReplace(value);\r\n\t\t\t\t\tquery = accentReplace(query);\r\n\t\t\t\t}\r\n\t\t\t\treturn value.toLowerCase().indexOf(query.toLowerCase())!=-1;\r\n\t\t\t\t\r\n\t\t\t}\r\n\t\t],\r\n\t\t\r\n\t\tfilter:[\r\n\t\t\tfunction (items, query, source) {\r\n\t\t\t\tvar results = [], value = '',i;\r\n\t\t\t\tif (items) {\t\t\t\t\t\r\n\t\t\t\t\tfor (i = 0;i < items.length;i += 1) {\r\n\t\t\t\t\t\tvalue = isset(items[i][this.get('valueKey', source)]) ? items[i][this.get('valueKey', source)] : items[i].toString();\r\n\t\t\t\t\t\tif (__safe.call(this, 'valid', source, [value, query])) {\r\n\t\t\t\t\t\t\tresults.push(items[i]); \r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\treturn results;\r\n\t\t\t}\r\n\t\t],\r\n\t\t\r\n\t\tpreparse:function(items){\r\n\t\t\treturn items;\r\n\t\t},\r\n\t\t\r\n\t\tgetValue: [\r\n\t\t\tfunction (item, source) {\r\n\t\t\t\treturn isset(item[this.get('valueKey',source)])?item[this.get('valueKey',source)]:item.toString();\r\n\t\t\t}\r\n\t\t],\r\n\t\t\r\n\t\tgetTitle: [\r\n\t\t\tfunction (item, source) {\r\n\t\t\t\treturn isset(item[this.get('titleKey',source)])?item[this.get('titleKey',source)]:item.toString();\r\n\t\t\t}\r\n\t\t],\r\n\t\t\r\n\t\trender: [\r\n\t\t\tfunction (item, source, pid, query) {\r\n\t\t\t\tvar value = __safe.call(this, \"getValue\", source, [item, source], defaultSetting.getValue[0].call(this, item, source)),\r\n\t\t\t\t\ttitle = __safe.call(this, \"getTitle\", source, [item, source], defaultSetting.getTitle[0].call(this, item, source)),\r\n\t\t\t\t\t_value = '',\r\n\t\t\t\t\t_query = '',\r\n\t\t\t\t\t_title = '',\r\n\t\t\t\t\thilite_hints = '',\r\n\t\t\t\t\thighlighted = '',\r\n\t\t\t\t\tc, h, i,\r\n\t\t\t\t\tspos = 0;\r\n\t\t\t\t\t\r\n\t\t\t\tif (this.highlight) {\r\n\t\t\t\t\tif (!this.accents) {\r\n\t\t\t\t\t\ttitle = title.replace(new RegExp('('+escapeRegExp(query)+')','i'),'<b>$1</b>');\r\n\t\t\t\t\t}else{\r\n\t\t\t\t\t\t_title = accentReplace(title).toLowerCase().replace(/[<>]+/g, ''),\r\n\t\t\t\t\t\t_query = accentReplace(query).toLowerCase().replace(/[<>]+/g, '');\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\thilite_hints = _title.replace(new RegExp(escapeRegExp(_query), 'g'), '<'+_query+'>');\r\n\t\t\t\t\t\tfor (i=0;i < hilite_hints.length;i += 1) {\r\n\t\t\t\t\t\t\tc = title.charAt(spos);\r\n\t\t\t\t\t\t\th = hilite_hints.charAt(i);\r\n\t\t\t\t\t\t\tif (h === '<') {\r\n\t\t\t\t\t\t\t\thighlighted += '<b>';\r\n\t\t\t\t\t\t\t} else if (h === '>') {\r\n\t\t\t\t\t\t\t\thighlighted += '</b>';\r\n\t\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t\tspos += 1;\r\n\t\t\t\t\t\t\t\thighlighted += c;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\ttitle = highlighted;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\t\t\r\n\t\t\t\treturn '<div '+(value==query?'class=\"active\"':'')+' data-value=\"'+encodeURIComponent(value)+'\">'\r\n\t\t\t\t\t\t\t+title+\r\n\t\t\t\t\t\t'</div>';\r\n\t\t\t}\r\n\t\t],\r\n\t\tappendMethod: 'concat', // supported merge and replace \r\n\t\tsource:[],\r\n\t\tafterSelected: function() {\r\n }\r\n\t};\r\n\tfunction init( that,options ){\r\n\t\tif( $(that).hasClass('xdsoft_input') )\r\n\t\t\t\treturn;\r\n\t\t\r\n\t\tvar $box = $('<div class=\"xdsoft_autocomplete\"></div>'),\r\n\t\t\t$dropdown = $('<div class=\"xdsoft_autocomplete_dropdown\"></div>'),\r\n\t\t\t$hint = $('<input readonly class=\"xdsoft_autocomplete_hint\"/>'),\r\n\t\t\t$input = $(that),\r\n\t\t\ttimer1 = 0,\r\n\t\t\tintervalForVisibility,\r\n\t\t\tdataset = [],\r\n\t\t\tiOpen\t= false,\r\n\t\t\tvalue = '',\r\n\t\t\tcurrentValue = '',\r\n\t\t\tcurrentSelect = '',\r\n\t\t\tactive = null,\r\n\t\t\tpos = 0;\r\n\t\t\r\n\t\t//it can be used to access settings\r\n\t\t$input.data('autocomplete_options', options);\r\n\t\t\r\n\t\t$dropdown\r\n\t\t\t.on('mousedown', function(e) {\r\n\t\t\t\te.preventDefault();\r\n\t\t\t\te.stopPropagation();\r\n\t\t\t})\r\n\t\t\t.on('updatescroll.xdsoft', function() {\r\n\t\t\t\tvar _act = $dropdown.find('.active');\r\n\t\t\t\tif (!_act.length) {\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t\t\r\n\t\t\t\tvar top = _act.position().top,\r\n\t\t\t\t\tactHght = _act.outerHeight(true),\r\n\t\t\t\t\tscrlTop = $dropdown.scrollTop(),\r\n\t\t\t\t\thght = $dropdown.height();\r\n\t\t\t\t\t\r\n\t\t\t\tif (top <0) {\r\n\t\t\t\t\t$dropdown.scrollTop(scrlTop-Math.abs(top));\r\n\t\t\t\t} else if (top+actHght>hght) {\r\n\t\t\t\t\t$dropdown.scrollTop(scrlTop+top+actHght-hght);\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t\r\n\t\t$box\r\n\t\t\t.css({\r\n\t\t\t\t'display':$input.css('display'),\r\n\t\t\t\t'width':$input.css('width')\r\n\t\t\t});\r\n\t\t\r\n\t\tif( options.style )\r\n\t\t\t$box.css(options.style);\r\n\t\t\t\r\n\t\t$input\r\n\t\t\t.addClass('xdsoft_input')\r\n\t\t\t.attr('autocomplete','off');\r\n\t\t\r\n\t\tvar xDown = null;\r\n\t\tvar yDown = null;\r\n\t\tvar isSwipe = false;\r\n\t\t$dropdown\r\n\t\t\t.on('mousemove','div',function(){\r\n\t\t\t\tif( $(this).hasClass('active') )\r\n\t\t\t\t\treturn true;\r\n\t\t\t\t$dropdown.find('div').removeClass('active');\r\n\t\t\t\t$(this).addClass('active');\r\n\t\t\t})\r\n\t\t\t.on('mousedown','div',function(e){\r\n\t\t\t\t$dropdown.find('div').removeClass('active');\r\n\t\t\t\t$(this).addClass('active');\r\n\t\t\t\t$input.trigger('pick.xdsoft');\r\n\t\t\t})\r\n\t\t\t.on('touchstart','div',function(e){\r\n\t\t\t\txDown = e.originalEvent.touches[0].clientX;\r\n\t\t\t\tyDown = e.originalEvent.touches[0].clientY;\r\n\t\t\t})\r\n\t\t\t.on('touchend','div',function(e){\r\n\t\t\t\tif(isSwipe === false) {\r\n\t\t\t\t\t$dropdown.find('div').removeClass('active');\r\n\t\t\t\t\t$(this).addClass('active');\r\n\t\t\t\t\t$input.trigger('pick.xdsoft');\r\n\t\t\t\t}\r\n\r\n\t\t\t\tisSwipe = false;\r\n\t\t\t})\r\n\t\t\t.on('touchmove','div',function(e){\r\n\t\t\t\tif ( ! xDown || ! yDown ) {\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tvar xUp = e.originalEvent.touches[0].clientX;\r\n\t\t\t\tvar yUp = e.originalEvent.touches[0].clientY;\r\n\r\n\t\t\t\tvar xDiff = xDown - xUp;\r\n\t\t\t\tvar yDiff = yDown - yUp;\r\n\r\n\t\t\t\tif ( Math.abs( xDiff ) > Math.abs( yDiff ) ) {\r\n\t\t\t\t\tif ( xDiff > 0 ) {\r\n\t\t\t\t\t\tisSwipe = 'left';\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tisSwipe = 'right';\r\n\t\t\t\t\t}\r\n\t\t\t\t} else {\r\n\t\t\t\t\tif ( yDiff > 0 ) {\r\n\t\t\t\t\t\tisSwipe = 'top';\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tisSwipe = 'bottm';\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\txDown = null;\r\n\t\t\t\tyDown = null;\r\n\t\t\t});\r\n\r\n\t\tfunction manageData(){\r\n\t\t\tif ($input.val()!=currentValue){\r\n\t\t\t\tcurrentValue = $input.val();\r\n\t\t\t} else {\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tif (currentValue.length < options.minLength) {\r\n\t\t\t\t$input.trigger('close.xdsoft');\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tcollectData.call(options,currentValue,dataset,function( query ){\r\n\t\t\t\tif (query != currentValue) {\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t\tvar right;\t\r\n\t\t\t\tprocessData.call(options, dataset,query);\r\n\r\n\t\t\t\t$input.trigger('updateContent.xdsoft');\r\n\r\n\t\t\t\tif (options.showHint && currentValue.length && currentValue.length<=$input.prop('size') && (right = findRight.call(options,dataset,currentValue))) {\r\n\t\t\t\t\tvar title \t= __safe.call(options,'getTitle',right.source,[right.right,right.source]);\r\n\t\t\t\t\ttitle = query + title.substr(query.length);\r\n\t\t\t\t\t$hint.val(title);\r\n\t\t\t\t} else {\r\n\t\t\t\t\t$hint.val('');\r\n\t\t\t\t}\r\n\t\t\t});\r\n\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tfunction manageKey (event) {\r\n\t\t\tvar key = event.keyCode, right;\r\n\t\t\t\r\n\t\t\tswitch( key ){\r\n\t\t\t\tcase AKEY: case CKEY: case VKEY: case ZKEY: case YKEY:\r\n\t\t\t\t\tif (event.shiftKey || event.ctrlKey) {\r\n\t\t\t\t\t\treturn true;\r\n\t\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\t\tcase SHIFTKEY:\t\r\n\t\t\t\tcase CTRLKEY:\r\n\t\t\t\t\treturn true;\r\n\t\t\t\tbreak;\r\n\t\t\t\tcase ARROWRIGHT:\t\r\n\t\t\t\tcase ARROWLEFT:\r\n\t\t\t\t\tif (ctrlDown || shiftDown || event.shiftKey || event.ctrlKey) {\r\n\t\t\t\t\t\treturn true;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tvalue = $input.val();\r\n\t\t\t\t\tpos = getCaretPosition($input[0]);\r\n\t\t\t\t\tif (key === ARROWRIGHT && pos === value.length) {\r\n\t\t\t\t\t\tif (right = findRight.call(options, dataset, value)){\r\n\t\t\t\t\t\t\t$input.trigger('pick.xdsoft', [\r\n\t\t\t\t\t\t\t\t__safe.call(options,\r\n\t\t\t\t\t\t\t\t\t'getValue', right.source,\r\n\t\t\t\t\t\t\t\t\t[right.right, right.source]\r\n\t\t\t\t\t\t\t\t)\r\n\t\t\t\t\t\t\t]);\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t$input.trigger('pick.xdsoft');\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tevent.preventDefault();\r\n\t\t\t\t\t\treturn false;\r\n\t\t\t\t\t}\r\n\t\t\t\t\treturn true;\r\n\t\t\t\tcase TAB:\r\n\t\t\t\treturn true;\r\n\t\t\t\tcase ENTER:\r\n\t\t\t\t\tif (iOpen) {\r\n\t\t\t\t\t\t$input.trigger('pick.xdsoft');\r\n\t\t\t\t\t\tevent.preventDefault();\r\n\t\t\t\t\t\treturn false;\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\treturn true;\r\n\t\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\t\tcase ESC:\r\n\t\t\t\t\t$input\r\n\t\t\t\t\t\t.val(currentValue)\r\n\t\t\t\t\t\t.trigger('close.xdsoft');\r\n\t\t\t\t\tevent.preventDefault();\r\n\t\t\t\t\treturn false;\r\n\t\t\t\tcase ARROWDOWN:\r\n\t\t\t\tcase ARROWUP:\r\n\t\t\t\t\tif (!iOpen) {\r\n\t\t\t\t\t\t$input.trigger('open.xdsoft');\r\n\t\t\t\t\t\t$input.trigger('updateContent.xdsoft');\r\n\t\t\t\t\t\tevent.preventDefault();\r\n\t\t\t\t\t\treturn false;\r\n\t\t\t\t\t}\r\n\t\t\t\t\t\r\n\t\t\t\t\tactive = $dropdown.find('div.active');\r\n\t\t\t\t\t\r\n\t\t\t\t\tvar next = key==ARROWDOWN?'next':'prev', timepick = true;\r\n\t\t\t\t\t\r\n\t\t\t\t\tif( active.length ){\r\n\t\t\t\t\t\tactive.removeClass('active');\r\n\t\t\t\t\t\tif( active[next]().length ){\r\n\t\t\t\t\t\t\tactive[next]().addClass('active');\r\n\t\t\t\t\t\t}else{\r\n\t\t\t\t\t\t\t$input.val(currentValue);\r\n\t\t\t\t\t\t\ttimepick = false;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}else{\r\n\t\t\t\t\t\t$dropdown.children().eq(key==ARROWDOWN?0:-1).addClass('active');\r\n\t\t\t\t\t}\r\n\t\t\t\t\t\r\n\t\t\t\t\tif( timepick ){\r\n\t\t\t\t\t\t$input.trigger('timepick.xdsoft');\r\n\t\t\t\t\t}\r\n\t\t\t\t\t\r\n\t\t\t\t\t$dropdown\r\n\t\t\t\t\t\t.trigger('updatescroll.xdsoft');\r\n\t\t\t\t\t\r\n\t\t\t\t\tevent.preventDefault();\r\n\t\t\t\t\treturn false;\t\r\n\t\t\t}\r\n\t\t\treturn;\r\n\t\t}\r\n\t\t\r\n\t\t$input\r\n\t\t\t.data('xdsoft_autocomplete',dataset)\r\n\t\t\t.after($box)\r\n\t\t\t.on('pick.xdsoft', function( event,_value ){\r\n\r\n\t\t\t\t$input.trigger('timepick.xdsoft',_value);\r\n\t\t\t\t\r\n\t\t\t\tcurrentSelect = currentValue = $input.val();\r\n\t\t\t\t\r\n\t\t\t\t$input.trigger('close.xdsoft');\r\n\t\t\t\t\r\n\t\t\t\t//currentInput = false;\r\n\t\t\t\t\r\n\t\t\t\tactive = $dropdown.find('div.active').eq(0);\r\n\t\t\t\t\t\t\t\r\n\t\t\t\tif( !active.length )\r\n\t\t\t\t\tactive = $dropdown.children().first();\r\n\t\t\t\t\t\r\n\t\t\t\t$input.trigger('selected.xdsoft',[getItem(active,dataset)]);\r\n\t\t\t\t\r\n\t\t\t\tif (options.afterSelected)\r\n\t\t\t\t\toptions.afterSelected();\r\n\t\t\t})\r\n\t\t\t.on('timepick.xdsoft', function( event,_value ){\r\n\t\t\t\tactive = $dropdown.find('div.active');\r\n\t\t\t\t\t\t\t\r\n\t\t\t\tif( !active.length )\r\n\t\t\t\t\tactive = $dropdown.children().first();\r\n\t\t\t\t\r\n\t\t\t\tif( active.length ){\r\n\t\t\t\t\tif( !isset(_value) ){\r\n\t\t\t\t\t\t$input.val(getValue.call(options,active,dataset));\r\n\t\t\t\t\t}else{\r\n\t\t\t\t\t\t$input.val(_value);\r\n\t\t\t\t\t}\r\n\t\t\t\t\t$input.trigger('autocompleted.xdsoft',[getItem(active,dataset)]);\r\n\t\t\t\t\t$hint.val('');\r\n\t\t\t\t\tsetCaretPosition($input[0],$input.val().length);\r\n\t\t\t\t}\r\n\t\t\t})\r\n\t\t\t.on('keydown.xdsoft input.xdsoft cut.xdsoft paste.xdsoft', function( event ){\r\n\t\t\t\tvar ret = manageKey(event);\r\n\t\t\t\t\r\n\t\t\t\tif (ret === false || ret === true) {\r\n\t\t\t\t\treturn ret;\r\n\t\t\t\t}\r\n\t\t\t\t\r\n\t\t\t\tsetTimeout(function(){\r\n\t\t\t\t\tmanageData();\r\n\t\t\t\t},1);\r\n\t\t\t\t\r\n\t\t\t\tmanageData();\r\n\t\t\t})\r\n\t\t\t.on('change.xdsoft', function( event ){\r\n\t\t\t\tcurrentValue = $input.val();\r\n\t\t\t});\r\n\t\t\r\n\t\tcurrentValue = $input.val();\r\n\t\t\r\n\t\tcollectData.call(options, $input.val(),dataset,function( query ){\r\n\t\t\tprocessData.call(options,dataset,query);\r\n\t\t});\r\n\t\t\r\n\t\tif( options.openOnFocus ){\r\n\t\t\t$input.on('focusin.xdsoft',function(){\r\n\t\t\t\t$input.trigger('open.xdsoft');\r\n\t\t\t\t$input.trigger('updateContent.xdsoft');\r\n\t\t\t});\r\n\t\t}\r\n\t\t\r\n\t\tif( options.closeOnBlur )\r\n\t\t\t$input.on('focusout.xdsoft',function(){\r\n\t\t\t\t$input.trigger('close.xdsoft');\r\n\t\t\t});\r\n\t\t\t\r\n\t\t$box\r\n\t\t\t.append($input)\r\n\t\t\t.append($dropdown);\r\n\r\n\r\n\t\tvar olderBackground = false,\r\n\t\t\ttimerUpdate = 0;\r\n\t\t\r\n\t\t$input\r\n\t\t\t.on('updateHelperPosition.xdsoft',function(){\r\n\t\t\t\tclearTimeout(timerUpdate);\r\n\t\t\t\ttimerUpdate = setTimeout(function(){\r\n\t\t\t\t\t$box.css({\r\n\t\t\t\t\t\t'display':$input.css('display'),\r\n\t\t\t\t\t\t'width':$input.css('width')\r\n\t\t\t\t\t});\r\n\t\t\t\t\t$dropdown.css($.extend(true,{\r\n\t\t\t\t\t\tleft:$input.position().left,\r\n\t\t\t\t\t\ttop:$input.position().top + parseInt($input.css('marginTop'))+parseInt($input[0].offsetHeight),\r\n\t\t\t\t\t\tmarginLeft:$input.css('marginLeft'),\r\n\t\t\t\t\t\tmarginRight:$input.css('marginRight'),\r\n\t\t\t\t\t\twidth:options.dropdownWidth=='100%'?$input[0].offsetWidth:options.dropdownWidth\r\n\t\t\t\t\t},options.dropdownStyle));\r\n\t\t\t\t\t\r\n\t\t\t\t\tif (options.showHint) {\r\n\t\t\t\t\t\tvar style = getComputedStyle($input[0], \"\");\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t$hint[0].style.cssText = style.cssText;\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t$hint.css({\r\n\t\t\t\t\t\t\t'box-sizing':style.boxSizing,\r\n\t\t\t\t\t\t\tborderStyle:'solid',\r\n\t\t\t\t\t\t\tborderCollapse:style.borderCollapse,\r\n\t\t\t\t\t\t\tborderLeftWidth:style.borderLeftWidth,\r\n\t\t\t\t\t\t\tborderRightWidth:style.borderRightWidth,\r\n\t\t\t\t\t\t\tborderTopWidth:style.borderTopWidth,\r\n\t\t\t\t\t\t\tborderBottomWidth:style.borderBottomWidth,\r\n\t\t\t\t\t\t\tpaddingBottom:style.paddingBottom,\r\n\t\t\t\t\t\t\tmarginBottom:style.marginBottom,\r\n\t\t\t\t\t\t\tpaddingTop:style.paddingTop,\r\n\t\t\t\t\t\t\tmarginTop:style.marginTop,\r\n\t\t\t\t\t\t\tpaddingLeft:style.paddingLeft,\r\n\t\t\t\t\t\t\tmarginLeft:style.marginLeft,\r\n\t\t\t\t\t\t\tpaddingRight:style.paddingRight,\r\n\t\t\t\t\t\t\tmarginRight:style.marginRight,\r\n\t\t\t\t\t\t\tmaxHeight:style.maxHeight,\r\n\t\t\t\t\t\t\tminHeight:style.minHeight,\r\n\t\t\t\t\t\t\tmaxWidth:style.maxWidth,\r\n\t\t\t\t\t\t\tminWidth:style.minWidth,\r\n\t\t\t\t\t\t\twidth:style.width,\r\n\t\t\t\t\t\t\tletterSpacing:style.letterSpacing,\r\n\t\t\t\t\t\t\tlineHeight:style.lineHeight,\r\n\t\t\t\t\t\t\toutlineWidth:style.outlineWidth,\r\n\t\t\t\t\t\t\tfontFamily:style.fontFamily,\r\n\t\t\t\t\t\t\tfontVariant:style.fontVariant,\r\n\t\t\t\t\t\t\tfontStyle:$input.css('fontStyle'),\r\n\t\t\t\t\t\t\tfontSize:$input.css('fontSize'),\r\n\t\t\t\t\t\t\tfontWeight:$input.css('fontWeight'),\r\n\t\t\t\t\t\t\tflex:style.flex,\r\n\t\t\t\t\t\t\tjustifyContent:style.justifyContent,\r\n\t\t\t\t\t\t\tborderRadius:style.borderRadius,\r\n\t\t\t\t\t\t\t'-webkit-box-shadow':'none',\r\n\t\t\t\t\t\t\t'box-shadow':'none'\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t$input.css('font-size',$input.css('fontSize'))// fix bug with em font size\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t$hint.innerHeight($input.innerHeight());\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t$hint.css($.extend(true,{\r\n\t\t\t\t\t\t\tposition:'absolute',\r\n\t\t\t\t\t\t\tzIndex:'1',\r\n\t\t\t\t\t\t\tborderColor:'transparent',\r\n\t\t\t\t\t\t\toutlineColor:'transparent',\r\n\t\t\t\t\t\t\tleft:$input.position().left,\r\n\t\t\t\t\t\t\ttop:$input.position().top,\r\n\t\t\t\t\t\t\tbackground:$input.css('background')\r\n\t\t\t\t\t\t},options.hintStyle));\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\tif( olderBackground!==false ){\r\n\t\t\t\t\t\t\t$hint.css('background',olderBackground);\r\n\t\t\t\t\t\t}else{\r\n\t\t\t\t\t\t\tolderBackground = $input.css('background');\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\r\n\t\t\t\t\t\ttry{\r\n\t\t\t\t\t\t\t$input[0].style.setProperty('background', 'transparent', 'important');\r\n\t\t\t\t\t\t} catch(e) {\r\n\t\t\t\t\t\t\t$input.css('background','transparent')\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t$box\r\n\t\t\t\t\t\t\t.append($hint);\r\n\t\t\t\t\t}\r\n\t\t\t\t}, options.timeoutUpdate||1);\r\n\t\t\t});\r\n\t\t\r\n\t\tif ($input.is(':visible')) {\r\n\t\t\t$input\r\n\t\t\t\t.trigger('updateHelperPosition.xdsoft');\r\n\t\t} else {\r\n\t\t\tintervalForVisibility = setInterval(function () {\r\n\t\t\t\tif ($input.is(':visible')) {\r\n\t\t\t\t\t$input\r\n\t\t\t\t\t\t.trigger('updateHelperPosition.xdsoft');\r\n\t\t\t\t\tclearInterval(intervalForVisibility);\r\n\t\t\t\t}\r\n\t\t\t},100);\r\n\t\t}\r\n\t\t\r\n\t\t$(window).on('resize',function () {\r\n\t\t\t$box.css({\r\n\t\t\t\t'width':'auto'\r\n\t\t\t});\r\n\t\t\t$input\r\n\t\t\t\t.trigger('updateHelperPosition.xdsoft');\r\n\t\t})\r\n\t\t\r\n\t\t$input\t\r\n\t\t\t.on('close.xdsoft',function(){\r\n\t\t\t\tif (!iOpen) {\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t$dropdown\r\n\t\t\t\t\t.hide();\r\n\r\n\t\t\t\t$hint\r\n\t\t\t\t\t.val('');\t\r\n\r\n\t\t\t\tif (!options.autoselect) {\r\n\t\t\t\t\t$input.val(currentValue);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tiOpen = false;\r\n\r\n\t\t\t\t//currentInput = false;\r\n\t\t\t})\r\n\t\t\t\r\n\t\t\t.on('updateContent.xdsoft',function(){\r\n\t\t\t\tvar out = renderData.call(options,dataset,$input.val()),\r\n\t\t\t\t\thght = 10;\r\n\t\t\t\t\r\n\t\t\t\tif (out.length) {\r\n\t\t\t\t\t$input.trigger('open.xdsoft');\r\n\t\t\t\t} else {\r\n\t\t\t\t\t$input.trigger('close.xdsoft');\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t$(out).each(function(){\r\n\t\t\t\t\tthis.css($.extend(true,{\r\n\t\t\t\t\t\tpaddingLeft:$input.css('paddingLeft'),\r\n\t\t\t\t\t\tpaddingRight:$input.css('paddingRight')\r\n\t\t\t\t\t},options.itemStyle));\r\n\t\t\t\t});\r\n\r\n\t\t\t\t$dropdown\r\n\t\t\t\t\t.html(out);\r\n\t\t\t\t\t\r\n\t\t\t\tif (options.visibleHeight){\r\n\t\t\t\t\thght = options.visibleHeight;\r\n\t\t\t\t} else {\r\n\t\t\t\t\thght = options.visibleLimit * ((out[0] ? out[0].outerHeight(true) : 0) || options.defaultHeightItem) + 5;\r\n\t\t\t\t}\r\n\t\t\t\t\r\n\t\t\t\t$dropdown\r\n\t\t\t\t\t.css('maxHeight', hght+'px')\r\n\t\t\t})\r\n\t\t\t\r\n\t\t\t.on('open.xdsoft',function(){\r\n\t\t\t\tif( iOpen )\r\n\t\t\t\t\treturn;\r\n\t\t\t\t\r\n\t\t\t\t$dropdown\r\n\t\t\t\t\t.show();\r\n\r\n\t\t\t\tiOpen = true;\r\n\t\t\t\t\t\r\n\t\t\t\t//currentInput = $input;\r\n\t\t\t})\r\n\t\t\t.on('destroy.xdsoft',function(){\r\n\t\t\t\t$input.removeClass('xdsoft');\r\n\t\t\t\t$box.after($input);\r\n\t\t\t\t$box.remove();\r\n\t\t\t\tclearTimeout(timer1);\r\n\t\t\t\tclearTimeout(intervalForVisibility);\r\n\t\t\t\t//currentInput = false;\r\n\t\t\t\t$input.data('xdsoft_autocomplete',null);\r\n\t\t\t\t$input\r\n\t\t\t\t\t.off('.xdsoft')\r\n\t\t\t});\r\n\t};\r\n\t\r\n\tpublics = {\r\n\t\tdestroy: function () {\r\n\t\t\treturn this.trigger('destroy.xdsoft');\r\n\t\t},\r\n\t\tupdate: function () {\r\n\t\t\treturn this.trigger('updateHelperPosition.xdsoft');\t\r\n\t\t},\r\n\t\toptions: function (_options) {\r\n\t\t\tif (this.data('autocomplete_options') && $.isPlainObject(_options)) {\r\n\t\t\t\tthis.data('autocomplete_options', $.extend(true, this.data('autocomplete_options'), _options));\r\n\t\t\t}\r\n\t\t\treturn this;\r\n\t\t},\r\n\t\tsetSource: function (_newsource, id) {\r\n\t\t\tif(this.data('autocomplete_options') && ($.isPlainObject(_newsource) || $.isFunction(_newsource) || $.isArray(_newsource))) {\r\n\t\t\t\tvar options = this.data('autocomplete_options'), \r\n\t\t\t\t\tdataset = this.data('xdsoft_autocomplete'),\r\n\t\t\t\t\tsource \t= options.source;\r\n\t\t\t\tif (id!==undefined && !isNaN(id)) {\r\n\t\t\t\t\tif ($.isPlainObject(_newsource) || $.isArray(_newsource)) {\r\n\t\t\t\t\t\tsource[id] = $.extend(true,$.isArray(_newsource) ? [] : {}, _newsource);\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tsource[id] = _newsource;\r\n\t\t\t\t\t}\r\n\t\t\t\t} else {\r\n\t\t\t\t\tif ($.isFunction(_newsource)) {\r\n\t\t\t\t\t\tthis.data('autocomplete_options').source = _newsource;\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\t$.extend(true, source, _newsource);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\t\r\n\t\t\t\tcollectData.call(options, this.val(), dataset,function( query ){\r\n\t\t\t\t\tprocessData.call(options,dataset,query);\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t\treturn this;\r\n\t\t},\r\n\t\tgetSource: function (id) {\r\n\t\t\tif (this.data('autocomplete_options')) {\r\n\t\t\t\tvar source = this.data('autocomplete_options').source;\r\n\t\t\t\tif (id!==undefined && !isNaN(id) &&source[id]) {\r\n\t\t\t\t\treturn source[id];\r\n\t\t\t\t} else {\r\n\t\t\t\t\treturn source;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturn null;\r\n\t\t} \r\n\t};\r\n\t\r\n\t$.fn.autocomplete = function(_options, _second, _third){\r\n\t\tif ($.type(_options) === 'string' && publics[_options]) {\r\n\t\t\treturn publics[_options].call(this, _second, _third);\r\n\t\t}\r\n\t\treturn this.each(function () {\r\n\t\t\tvar options = $.extend(true, {}, defaultSetting, _options);\r\n\t\t\tinit(this, options);\r\n\t\t});\r\n\t};\r\n}(jQuery));\r\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvanF1ZXJ5LWF1dG9jb21wbGV0ZS9qcXVlcnkuYXV0b2NvbXBsZXRlLmpzIiwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1Q0FBdUM7QUFDdkM7QUFDQTtBQUNBLEtBQUs7QUFDTCx3QkFBd0I7QUFDeEIsa0NBQWtDO0FBQ2xDLCtCQUErQjtBQUMvQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBLFlBQVksY0FBYztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQ0FBaUMsRUFBRTtBQUNuQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQixxQkFBcUI7QUFDdkM7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQixxQkFBcUI7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTCxHQUFHO0FBQ0gsbUJBQW1CLCtCQUErQjtBQUNsRDtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1AsTUFBTTtBQUNOLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1gsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9CQUFvQixtQkFBbUI7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCLHFCQUFxQjtBQUN2QyxjQUFjLHdCQUF3QjtBQUN0QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CO0FBQ25CLGVBQWU7QUFDZjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsaUJBQWlCO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLGlCQUFpQjtBQUNqQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLHdCQUF3QjtBQUN2QztBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTCxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ04sS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpRUFBaUU7QUFDakUsT0FBTztBQUNQO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtDQUFrQztBQUNsQztBQUNBLEdBQUc7QUFDSDtBQUNBLENBQUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvanF1ZXJ5LWF1dG9jb21wbGV0ZS9qcXVlcnkuYXV0b2NvbXBsZXRlLmpzPzJiOWIiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXHJcbiAqIEBwcmVzZXJ2ZSBqUXVlcnkgQXV0b2NvbXBsZXRlIHBsdWdpbiB2MS4yLjZcclxuICogQGhvbWVwYWdlIGh0dHA6Ly94ZHNvZnQubmV0L2pxcGx1Z2lucy9hdXRvY29tcGxldGUvXHJcbiAqIEBsaWNlbnNlIE1JVCAtIE1JVC1MSUNFTlNFLnR4dFxyXG4gKiAoYykgMjAxNCwgQ2h1cHVybm92IFZhbGVyaXkgPGNodXB1cm5vdkBnbWFpbC5jb20+XHJcbiAqL1xyXG4oZnVuY3Rpb24gKCQpIHtcclxuXHQndXNlIHN0cmljdCc7XHJcblx0dmFyXHRBUlJPV0xFRlQgPSAzNyxcclxuXHRcdEFSUk9XUklHSFQgPSAzOSxcclxuXHRcdEFSUk9XVVAgPSAzOCxcclxuXHRcdEFSUk9XRE9XTiA9IDQwLFxyXG5cdFx0VEFCID0gOSxcclxuXHRcdENUUkxLRVkgPSAxNyxcclxuXHRcdFNISUZUS0VZID0gMTYsXHJcblx0XHRERUwgPSA0NixcclxuXHRcdEVOVEVSID0gMTMsXHJcblx0XHRFU0MgPSAyNyxcclxuXHRcdEJBQ0tTUEFDRSA9IDgsXHJcblx0XHRBS0VZID0gNjUsXHJcblx0XHRDS0VZID0gNjcsXHJcblx0XHRWS0VZID0gODYsXHJcblx0XHRaS0VZID0gOTAsXHJcblx0XHRZS0VZID0gODksXHJcblx0XHRkZWZhdWx0U2V0dGluZyA9IHt9LFxyXG5cdFx0Ly9jdXJyZW50SW5wdXQgPSBmYWxzZSxcclxuXHRcdGN0cmxEb3duID0gZmFsc2UsXHJcblx0XHRzaGlmdERvd24gPSBmYWxzZSxcclxuXHRcdHB1YmxpY3MgPSB7fSxcclxuXHRcdGFjY2VudF9tYXAgPSB7XHJcblx0XHRcdCfhuponOidhJywnw4EnOidhJywnw6EnOidhJywnw4AnOidhJywnw6AnOidhJywnxIInOidhJywnxIMnOidhJywn4bquJzonYScsJ+G6ryc6J2EnLCfhurAnOidhJywn4bqxJzonYScsJ+G6tCc6J2EnLCfhurUnOidhJywn4bqyJzonYScsXHJcblx0XHRcdCfhuqonOidhJywn4bqrJzonYScsJ+G6qCc6J2EnLCfhuqknOidhJywnx40nOidhJywnx44nOidhJywnw4UnOidhJywnw6UnOidhJywnx7onOidhJywnx7snOidhJywnw4QnOidhJywnw6QnOidhJywnx54nOidhJywnx58nOidhJyxcclxuXHRcdFx0J8ODJzonYScsJ8OjJzonYScsJ8imJzonYScsJ8inJzonYScsJ8egJzonYScsJ8ehJzonYScsJ8SEJzonYScsJ8SFJzonYScsJ8SAJzonYScsJ8SBJzonYScsJ+G6oic6J2EnLCfhuqMnOidhJywnyIAnOidhJywnyIEnOidhJyxcclxuXHRcdFx0J8iCJzonYScsJ8iDJzonYScsJ+G6oCc6J2EnLCfhuqEnOidhJywn4bq2JzonYScsJ+G6tyc6J2EnLCfhuqwnOidhJywn4bqtJzonYScsJ+G4gCc6J2EnLCfhuIEnOidhJywnyLonOidhJywn4rGlJzonYScsJ8e8JzonYScsJ8e9JzonYScsXHJcblx0XHRcdCfHoic6J2EnLCfHoyc6J2EnLCfhuIInOidiJywn4biDJzonYicsJ+G4hCc6J2InLCfhuIUnOidiJywn4biGJzonYicsJ+G4hyc6J2InLCfJgyc6J2InLCfGgCc6J2InLCfhtawnOidiJywnxoEnOidiJywnyZMnOidiJywnxoInOidiJyxcclxuXHRcdFx0J8aDJzonYicsJ8SGJzonYycsJ8SHJzonYycsJ8SIJzonYycsJ8SJJzonYycsJ8SMJzonYycsJ8SNJzonYycsJ8SKJzonYycsJ8SLJzonYycsJ8OHJzonYycsJ8OnJzonYycsJ+G4iCc6J2MnLCfhuIknOidjJywnyLsnOidjJyxcclxuXHRcdFx0J8i8JzonYycsJ8aHJzonYycsJ8aIJzonYycsJ8mVJzonYycsJ8SOJzonZCcsJ8SPJzonZCcsJ+G4iic6J2QnLCfhuIsnOidkJywn4biQJzonZCcsJ+G4kSc6J2QnLCfhuIwnOidkJywn4biNJzonZCcsJ+G4kic6J2QnLCfhuJMnOidkJyxcclxuXHRcdFx0J+G4jic6J2QnLCfhuI8nOidkJywnxJAnOidkJywnxJEnOidkJywn4bWtJzonZCcsJ8aJJzonZCcsJ8mWJzonZCcsJ8aKJzonZCcsJ8mXJzonZCcsJ8aLJzonZCcsJ8aMJzonZCcsJ8ihJzonZCcsJ8OwJzonZCcsJ8OJJzonZScsXHJcblx0XHRcdCfGjyc6J2UnLCfGjic6J2UnLCfHnSc6J2UnLCfDqSc6J2UnLCfDiCc6J2UnLCfDqCc6J2UnLCfElCc6J2UnLCfElSc6J2UnLCfDiic6J2UnLCfDqic6J2UnLCfhur4nOidlJywn4bq/JzonZScsJ+G7gCc6J2UnLCfhu4EnOidlJyxcclxuXHRcdFx0J+G7hCc6J2UnLCfhu4UnOidlJywn4buCJzonZScsJ+G7gyc6J2UnLCfEmic6J2UnLCfEmyc6J2UnLCfDiyc6J2UnLCfDqyc6J2UnLCfhurwnOidlJywn4bq9JzonZScsJ8SWJzonZScsJ8SXJzonZScsJ8ioJzonZScsJ8ipJzonZScsXHJcblx0XHRcdCfhuJwnOidlJywn4bidJzonZScsJ8SYJzonZScsJ8SZJzonZScsJ8SSJzonZScsJ8STJzonZScsJ+G4lic6J2UnLCfhuJcnOidlJywn4biUJzonZScsJ+G4lSc6J2UnLCfhuronOidlJywn4bq7JzonZScsJ8iEJzonZScsJ8iFJzonZScsXHJcblx0XHRcdCfIhic6J2UnLCfIhyc6J2UnLCfhurgnOidlJywn4bq5JzonZScsJ+G7hic6J2UnLCfhu4cnOidlJywn4biYJzonZScsJ+G4mSc6J2UnLCfhuJonOidlJywn4bibJzonZScsJ8mGJzonZScsJ8mHJzonZScsJ8maJzonZScsJ8mdJzonZScsXHJcblx0XHRcdCfhuJ4nOidmJywn4bifJzonZicsJ+G1ric6J2YnLCfGkSc6J2YnLCfGkic6J2YnLCfHtCc6J2cnLCfHtSc6J2cnLCfEnic6J2cnLCfEnyc6J2cnLCfEnCc6J2cnLCfEnSc6J2cnLCfHpic6J2cnLCfHpyc6J2cnLCfEoCc6J2cnLFxyXG5cdFx0XHQnxKEnOidnJywnxKInOidnJywnxKMnOidnJywn4bigJzonZycsJ+G4oSc6J2cnLCfHpCc6J2cnLCfHpSc6J2cnLCfGkyc6J2cnLCfJoCc6J2cnLCfEpCc6J2gnLCfEpSc6J2gnLCfInic6J2gnLCfInyc6J2gnLCfhuKYnOidoJyxcclxuXHRcdFx0J+G4pyc6J2gnLCfhuKInOidoJywn4bijJzonaCcsJ+G4qCc6J2gnLCfhuKknOidoJywn4bikJzonaCcsJ+G4pSc6J2gnLCfhuKonOidoJywn4birJzonaCcsJ0gnOidoJywnzLEnOidoJywn4bqWJzonaCcsJ8SmJzonaCcsJ8SnJzonaCcsXHJcblx0XHRcdCfisacnOidoJywn4rGoJzonaCcsJ8ONJzonaScsJ8OtJzonaScsJ8OMJzonaScsJ8OsJzonaScsJ8SsJzonaScsJ8StJzonaScsJ8OOJzonaScsJ8OuJzonaScsJ8ePJzonaScsJ8eQJzonaScsJ8OPJzonaScsJ8OvJzonaScsXHJcblx0XHRcdCfhuK4nOidpJywn4bivJzonaScsJ8SoJzonaScsJ8SpJzonaScsJ8SwJzonaScsJ2knOidpJywnxK4nOidpJywnxK8nOidpJywnxKonOidpJywnxKsnOidpJywn4buIJzonaScsJ+G7iSc6J2knLCfIiCc6J2knLCfIiSc6J2knLFxyXG5cdFx0XHQnyIonOidpJywnyIsnOidpJywn4buKJzonaScsJ+G7iyc6J2knLCfhuKwnOidpJywn4bitJzonaScsJ0knOidpJywnxLEnOidpJywnxpcnOidpJywnyagnOidpJywnxLQnOidqJywnxLUnOidqJywnSic6J2onLCfMjCc6J2onLFxyXG5cdFx0XHQnx7AnOidqJywnyLcnOidqJywnyYgnOidqJywnyYknOidqJywnyp0nOidqJywnyZ8nOidqJywnyoQnOidqJywn4biwJzonaycsJ+G4sSc6J2snLCfHqCc6J2snLCfHqSc6J2snLCfEtic6J2snLCfEtyc6J2snLCfhuLInOidrJyxcclxuXHRcdFx0J+G4syc6J2snLCfhuLQnOidrJywn4bi1JzonaycsJ8aYJzonaycsJ8aZJzonaycsJ+KxqSc6J2snLCfisaonOidrJywnxLknOidhJywnxLonOidsJywnxL0nOidsJywnxL4nOidsJywnxLsnOidsJywnxLwnOidsJywn4bi2JzonbCcsXHJcblx0XHRcdCfhuLcnOidsJywn4bi4JzonbCcsJ+G4uSc6J2wnLCfhuLwnOidsJywn4bi9JzonbCcsJ+G4uic6J2wnLCfhuLsnOidsJywnxYEnOidsJywnxYInOidsJywnzKMnOidsJywnxL8nOidsJyxcclxuXHRcdFx0J8WAJzonbCcsJ8i9JzonbCcsJ8aaJzonbCcsJ+KxoCc6J2wnLCfisaEnOidsJywn4rGiJzonbCcsJ8mrJzonbCcsJ8msJzonbCcsJ8mtJzonbCcsJ8i0JzonbCcsJ+G4vic6J20nLCfhuL8nOidtJywn4bmAJzonbScsJ+G5gSc6J20nLFxyXG5cdFx0XHQn4bmCJzonbScsJ+G5gyc6J20nLCfJsSc6J20nLCfFgyc6J24nLCfFhCc6J24nLCfHuCc6J24nLCfHuSc6J24nLCfFhyc6J24nLCfFiCc6J24nLCfDkSc6J24nLCfDsSc6J24nLCfhuYQnOiduJywn4bmFJzonbicsJ8WFJzonbicsXHJcblx0XHRcdCfFhic6J24nLCfhuYYnOiduJywn4bmHJzonbicsJ+G5iic6J24nLCfhuYsnOiduJywn4bmIJzonbicsJ+G5iSc6J24nLCfGnSc6J24nLCfJsic6J24nLCfIoCc6J24nLCfGnic6J24nLCfJsyc6J24nLCfItSc6J24nLCdOJzonbicsXHJcblx0XHRcdCfMiCc6J24nLCduJzonbicsJ8OTJzonbycsJ8OzJzonbycsJ8OSJzonbycsJ8OyJzonbycsJ8WOJzonbycsJ8WPJzonbycsJ8OUJzonbycsJ8O0JzonbycsJ+G7kCc6J28nLCfhu5EnOidvJywn4buSJzonbycsXHJcblx0XHRcdCfhu5MnOidvJywn4buWJzonbycsJ+G7lyc6J28nLCfhu5QnOidvJywn4buVJzonbycsJ8eRJzonbycsJ8eSJzonbycsJ8OWJzonbycsJ8O2JzonbycsJ8iqJzonbycsJ8irJzonbycsJ8WQJzonbycsJ8WRJzonbycsJ8OVJzonbycsXHJcblx0XHRcdCfDtSc6J28nLCfhuYwnOidvJywn4bmNJzonbycsJ+G5jic6J28nLCfhuY8nOidvJywnyKwnOidvJywnyK0nOidvJywnyK4nOidvJywnyK8nOidvJywnyLAnOidvJywnyLEnOidvJywnw5gnOidvJywnw7gnOidvJywnx74nOidvJyxcclxuXHRcdFx0J8e/JzonbycsJ8eqJzonbycsJ8erJzonbycsJ8esJzonbycsJ8etJzonbycsJ8WMJzonbycsJ8WNJzonbycsJ+G5kic6J28nLCfhuZMnOidvJywn4bmQJzonbycsJ+G5kSc6J28nLCfhu44nOidvJywn4buPJzonbycsJ8iMJzonbycsXHJcblx0XHRcdCfIjSc6J28nLCfIjic6J28nLCfIjyc6J28nLCfGoCc6J28nLCfGoSc6J28nLCfhu5onOidvJywn4bubJzonbycsJ+G7nCc6J28nLCfhu50nOidvJywn4bugJzonbycsJ+G7oSc6J28nLCfhu54nOidvJywn4bufJzonbycsJ+G7oic6J28nLFxyXG5cdFx0XHQn4bujJzonbycsJ+G7jCc6J28nLCfhu40nOidvJywn4buYJzonbycsJ+G7mSc6J28nLCfGnyc6J28nLCfJtSc6J28nLCfhuZQnOidwJywn4bmVJzoncCcsJ+G5lic6J3AnLCfhuZcnOidwJywn4rGjJzoncCcsJ8akJzoncCcsJ8alJzoncCcsXHJcblx0XHRcdCdQJzoncCcsJ8yDJzoncCcsJ3AnOidwJywnyqAnOidxJywnyYonOidxJywnyYsnOidxJywnxZQnOidyJywnxZUnOidyJywnxZgnOidyJywnxZknOidyJywn4bmYJzoncicsJ+G5mSc6J3InLCfFlic6J3InLFxyXG5cdFx0XHQnxZcnOidyJywnyJAnOidyJywnyJEnOidyJywnyJInOidyJywnyJMnOidyJywn4bmaJzoncicsJ+G5myc6J3InLCfhuZwnOidyJywn4bmdJzoncicsJ+G5nic6J3InLCfhuZ8nOidyJywnyYwnOidyJywnyY0nOidyJywn4bWyJzoncicsXHJcblx0XHRcdCfJvCc6J3InLCfisaQnOidyJywnyb0nOidyJywnyb4nOidyJywn4bWzJzoncicsJ8OfJzoncycsJ8WaJzoncycsJ8WbJzoncycsJ+G5pCc6J3MnLCfhuaUnOidzJywnxZwnOidzJywnxZ0nOidzJywnxaAnOidzJywnxaEnOidzJyxcclxuXHRcdFx0J+G5pic6J3MnLCfhuacnOidzJywn4bmgJzoncycsJ+G5oSc6J3MnLCfhupsnOidzJywnxZ4nOidzJywnxZ8nOidzJywn4bmiJzoncycsJ+G5oyc6J3MnLCfhuagnOidzJywn4bmpJzoncycsJ8iYJzoncycsJ8iZJzoncycsJ8qCJzoncycsXHJcblx0XHRcdCdTJzoncycsJ8ypJzoncycsJ3MnOidzJywnw54nOid0Jywnw74nOid0JywnxaQnOid0JywnxaUnOid0JywnVCc6J3QnLCfhupcnOid0Jywn4bmqJzondCcsJ+G5qyc6J3QnLCfFoic6J3QnLCfFoyc6J3QnLCfhuawnOid0JyxcclxuXHRcdFx0J+G5rSc6J3QnLCfImic6J3QnLCfImyc6J3QnLCfhubAnOid0Jywn4bmxJzondCcsJ+G5ric6J3QnLCfhua8nOid0JywnxaYnOid0JywnxacnOid0JywnyL4nOid0Jywn4rGmJzondCcsJ+G1tSc6J3QnLFxyXG5cdFx0XHQnxqsnOid0JywnxqwnOid0Jywnxq0nOid0Jywnxq4nOid0JywnyognOid0JywnyLYnOid0Jywnw5onOid1Jywnw7onOid1Jywnw5knOid1Jywnw7knOid1JywnxawnOid1Jywnxa0nOid1Jywnw5snOid1Jywnw7snOid1JyxcclxuXHRcdFx0J8eTJzondScsJ8eUJzondScsJ8WuJzondScsJ8WvJzondScsJ8OcJzondScsJ8O8JzondScsJ8eXJzondScsJ8eYJzondScsJ8ebJzondScsJ8ecJzondScsJ8eZJzondScsJ8eaJzondScsJ8eVJzondScsJ8eWJzondScsXHJcblx0XHRcdCfFsCc6J3UnLCfFsSc6J3UnLCfFqCc6J3UnLCfFqSc6J3UnLCfhubgnOid1Jywn4bm5JzondScsJ8WyJzondScsJ8WzJzondScsJ8WqJzondScsJ8WrJzondScsJ+G5uic6J3UnLCfhubsnOid1Jywn4bumJzondScsJ+G7pyc6J3UnLFxyXG5cdFx0XHQnyJQnOid1JywnyJUnOid1JywnyJYnOid1JywnyJcnOid1Jywnxq8nOid1JywnxrAnOid1Jywn4buoJzondScsJ+G7qSc6J3UnLCfhu6onOid1Jywn4burJzondScsJ+G7ric6J3UnLCfhu68nOid1Jywn4busJzondScsJ+G7rSc6J3UnLFxyXG5cdFx0XHQn4buwJzondScsJ+G7sSc6J3UnLCfhu6QnOid1Jywn4bulJzondScsJ+G5sic6J3UnLCfhubMnOid1Jywn4bm2JzondScsJ+G5tyc6J3UnLCfhubQnOid1Jywn4bm1JzondScsJ8mEJzondScsJ8qJJzondScsJ+G5vCc6J3YnLCfhub0nOid2JyxcclxuXHRcdFx0J+G5vic6J3YnLCfhub8nOid2JywnxrInOid2JywnyosnOid2Jywn4bqCJzondycsJ+G6gyc6J3cnLCfhuoAnOid3Jywn4bqBJzondycsJ8W0JzondycsJ8W1JzondycsJ1cnOid3JywnzIonOid3Jywn4bqYJzondycsJ+G6hCc6J3cnLFxyXG5cdFx0XHQn4bqFJzondycsJ+G6hic6J3cnLCfhuocnOid3Jywn4bqIJzondycsJ+G6iSc6J3cnLCfhuownOid4Jywn4bqNJzoneCcsJ+G6iic6J3gnLCfhuosnOid4Jywnw50nOid5Jywnw70nOid5Jywn4buyJzoneScsJ+G7syc6J3knLCfFtic6J3knLFxyXG5cdFx0XHQnxbcnOid5JywnWSc6J3knLCfhupknOid5JywnxbgnOid5Jywnw78nOid5Jywn4bu4JzoneScsJ+G7uSc6J3knLCfhuo4nOid5Jywn4bqPJzoneScsJ8iyJzoneScsJ8izJzoneScsJ+G7tic6J3knLCfhu7cnOid5JyxcclxuXHRcdFx0J+G7tCc6J3knLCfhu7UnOid5Jywnyo8nOid5JywnyY4nOid5JywnyY8nOid5JywnxrMnOid5JywnxrQnOid5JywnxbknOid6JywnxbonOid6Jywn4bqQJzoneicsJ+G6kSc6J3onLCfFvSc6J3onLCfFvic6J3onLCfFuyc6J3onLFxyXG5cdFx0XHQnxbwnOid6Jywn4bqSJzoneicsJ+G6kyc6J3onLCfhupQnOid6Jywn4bqVJzoneicsJ8a1JzoneicsJ8a2JzoneicsJ8ikJzoneicsJ8ilJzoneicsJ8qQJzoneicsJ8qRJzoneicsJ+Kxqyc6J3onLCfisawnOid6Jywnx64nOid6JyxcclxuXHRcdFx0J8evJzoneicsJ8a6JzoneicsJ++8kic6JzInLCfvvJYnOic2Jywn77yiJzonQicsJ++8pic6J0YnLCfvvKonOidKJywn77yuJzonTicsJ++8sic6J1InLCfvvLYnOidWJywn77y6JzonWicsJ++9gic6J2InLCfvvYYnOidmJywn772KJzonaicsXHJcblx0XHRcdCfvvY4nOiduJywn772SJzoncicsJ++9lic6J3YnLCfvvZonOid6Jywn77yRJzonMScsJ++8lSc6JzUnLCfvvJknOic5Jywn77yhJzonQScsJ++8pSc6J0UnLCfvvKknOidJJywn77ytJzonTScsJ++8sSc6J1EnLCfvvLUnOidVJywn77y5JzonWScsXHJcblx0XHRcdCfvvYEnOidhJywn772FJzonZScsJ++9iSc6J2knLCfvvY0nOidtJywn772RJzoncScsJ++9lSc6J3UnLCfvvZknOid5Jywn77yQJzonMCcsJ++8lCc6JzQnLCfvvJgnOic4Jywn77ykJzonRCcsJ++8qCc6J0gnLCfvvKwnOidMJywn77ywJzonUCcsXHJcblx0XHRcdCfvvLQnOidUJywn77y4JzonWCcsJ++9hCc6J2QnLCfvvYgnOidoJywn772MJzonbCcsJ++9kCc6J3AnLCfvvZQnOid0Jywn772YJzoneCcsJ++8kyc6JzMnLCfvvJcnOic3Jywn77yjJzonQycsJ++8pyc6J0cnLCfvvKsnOidLJywn77yvJzonTycsXHJcblx0XHRcdCfvvLMnOidTJywn77y3JzonVycsJ++9gyc6J2MnLCfvvYcnOidnJywn772LJzonaycsJ++9jyc6J28nLCfvvZMnOidzJywn772XJzondycsJ+G6syc6J2EnLCfDgic6J2EnLCfDoic6J2EnLCfhuqQnOidhJywn4bqlJzonYScsJ+G6pic6J2EnLCfhuqcnOidhJ1xyXG5cdFx0fTtcclxuXHJcblx0aWYgKHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlID09PSB1bmRlZmluZWQpIHtcclxuXHRcdHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlID0gKGZ1bmN0aW9uICgpIHtcclxuXHRcdFx0ZnVuY3Rpb24gZ2V0UGl4ZWxTaXplKGVsZW1lbnQsIHN0eWxlLCBwcm9wZXJ0eSwgZm9udFNpemUpIHtcclxuXHRcdFx0XHR2YXJcdHNpemVXaXRoU3VmZml4ID0gc3R5bGVbcHJvcGVydHldLFxyXG5cdFx0XHRcdFx0c2l6ZSA9IHBhcnNlRmxvYXQoc2l6ZVdpdGhTdWZmaXgpLFxyXG5cdFx0XHRcdFx0c3VmZml4ID0gc2l6ZVdpdGhTdWZmaXguc3BsaXQoL1xcZC8pWzBdLFxyXG5cdFx0XHRcdFx0cm9vdFNpemU7XHJcblxyXG5cdFx0XHRcdGZvbnRTaXplID0gZm9udFNpemUgIT09IG51bGwgPyBmb250U2l6ZSA6IC8lfGVtLy50ZXN0KHN1ZmZpeCkgJiYgZWxlbWVudC5wYXJlbnRFbGVtZW50ID8gZ2V0UGl4ZWxTaXplKGVsZW1lbnQucGFyZW50RWxlbWVudCwgZWxlbWVudC5wYXJlbnRFbGVtZW50LmN1cnJlbnRTdHlsZSwgJ2ZvbnRTaXplJywgbnVsbCkgOiAxNjtcclxuXHRcdFx0XHRyb290U2l6ZSA9IHByb3BlcnR5ID09PSAnZm9udFNpemUnID8gZm9udFNpemUgOiAvd2lkdGgvaS50ZXN0KHByb3BlcnR5KSA/IGVsZW1lbnQuY2xpZW50V2lkdGggOiBlbGVtZW50LmNsaWVudEhlaWdodDtcclxuXHJcblx0XHRcdFx0cmV0dXJuIChzdWZmaXggPT09ICdlbScpID8gc2l6ZSAqIGZvbnRTaXplIDogKHN1ZmZpeCA9PT0gJ2luJykgPyBzaXplICogOTYgOiAoc3VmZml4ID09PSAncHQnKSA/IHNpemUgKiA5NiAvIDcyIDogKHN1ZmZpeCA9PT0gJyUnKSA/IHNpemUgLyAxMDAgKiByb290U2l6ZSA6IHNpemU7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdGZ1bmN0aW9uIHNldFNob3J0U3R5bGVQcm9wZXJ0eShzdHlsZSwgcHJvcGVydHkpIHtcclxuXHRcdFx0XHR2YXJcdGJvcmRlclN1ZmZpeCA9IHByb3BlcnR5ID09PSAnYm9yZGVyJyA/ICdXaWR0aCcgOiAnJyxcclxuXHRcdFx0XHRcdHQgPSBwcm9wZXJ0eSArICdUb3AnICsgYm9yZGVyU3VmZml4LFxyXG5cdFx0XHRcdFx0ciA9IHByb3BlcnR5ICsgJ1JpZ2h0JyArIGJvcmRlclN1ZmZpeCxcclxuXHRcdFx0XHRcdGIgPSBwcm9wZXJ0eSArICdCb3R0b20nICsgYm9yZGVyU3VmZml4LFxyXG5cdFx0XHRcdFx0bCA9IHByb3BlcnR5ICsgJ0xlZnQnICsgYm9yZGVyU3VmZml4O1xyXG5cclxuXHRcdFx0XHRzdHlsZVtwcm9wZXJ0eV0gPSAoc3R5bGVbdF0gPT09IHN0eWxlW3JdID09PSBzdHlsZVtiXSA9PT0gc3R5bGVbbF0gPyBbc3R5bGVbdF1dXHJcblx0XHRcdFx0XHQ6IHN0eWxlW3RdID09PSBzdHlsZVtiXSAmJiBzdHlsZVtsXSA9PT0gc3R5bGVbcl0gPyBbc3R5bGVbdF0sIHN0eWxlW3JdXVxyXG5cdFx0XHRcdFx0XHQ6IHN0eWxlW2xdID09PSBzdHlsZVtyXSA/IFtzdHlsZVt0XSwgc3R5bGVbcl0sIHN0eWxlW2JdXVxyXG5cdFx0XHRcdFx0XHRcdDogW3N0eWxlW3RdLCBzdHlsZVtyXSwgc3R5bGVbYl0sIHN0eWxlW2xdXSkuam9pbignICcpO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRmdW5jdGlvbiBDU1NTdHlsZURlY2xhcmF0aW9uKGVsZW1lbnQpIHtcclxuXHRcdFx0XHR2YXJcdGN1cnJlbnRTdHlsZSA9IGVsZW1lbnQuY3VycmVudFN0eWxlLFxyXG5cdFx0XHRcdFx0c3R5bGUgPSB0aGlzLFxyXG5cdFx0XHRcdFx0cHJvcGVydHksXHJcblx0XHRcdFx0XHRmb250U2l6ZSA9IGdldFBpeGVsU2l6ZShlbGVtZW50LCBjdXJyZW50U3R5bGUsICdmb250U2l6ZScsIG51bGwpO1xyXG5cdFx0XHRcdFxyXG5cdFx0XHRcdGZvciAocHJvcGVydHkgaW4gY3VycmVudFN0eWxlKSB7XHJcblx0XHRcdFx0XHRpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGN1cnJlbnRTdHlsZSwgcHJvcGVydHkpKSB7XHJcblx0XHRcdFx0XHRcdGlmICgvd2lkdGh8aGVpZ2h0fG1hcmdpbi58cGFkZGluZy58Ym9yZGVyLitXLy50ZXN0KHByb3BlcnR5KSAmJiBzdHlsZVtwcm9wZXJ0eV0gIT09ICdhdXRvJykge1xyXG5cdFx0XHRcdFx0XHRcdHN0eWxlW3Byb3BlcnR5XSA9IGdldFBpeGVsU2l6ZShlbGVtZW50LCBjdXJyZW50U3R5bGUsIHByb3BlcnR5LCBmb250U2l6ZSkgKyAncHgnO1xyXG5cdFx0XHRcdFx0XHR9IGVsc2UgaWYgKHByb3BlcnR5ID09PSAnc3R5bGVGbG9hdCcpIHtcclxuXHRcdFx0XHRcdFx0XHRzdHlsZS5mbG9hdCA9IGN1cnJlbnRTdHlsZVtwcm9wZXJ0eV07XHJcblx0XHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdFx0c3R5bGVbcHJvcGVydHldID0gY3VycmVudFN0eWxlW3Byb3BlcnR5XTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0c2V0U2hvcnRTdHlsZVByb3BlcnR5KHN0eWxlLCAnbWFyZ2luJyk7XHJcblx0XHRcdFx0c2V0U2hvcnRTdHlsZVByb3BlcnR5KHN0eWxlLCAncGFkZGluZycpO1xyXG5cdFx0XHRcdHNldFNob3J0U3R5bGVQcm9wZXJ0eShzdHlsZSwgJ2JvcmRlcicpO1xyXG5cclxuXHRcdFx0XHRzdHlsZS5mb250U2l6ZSA9IGZvbnRTaXplICsgJ3B4JztcclxuXHJcblx0XHRcdFx0cmV0dXJuIHN0eWxlO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRDU1NTdHlsZURlY2xhcmF0aW9uLnByb3RvdHlwZSA9IHtcclxuXHRcdFx0XHRjb25zdHJ1Y3RvcjogQ1NTU3R5bGVEZWNsYXJhdGlvbixcclxuXHRcdFx0XHRnZXRQcm9wZXJ0eVByaW9yaXR5OiBmdW5jdGlvbiAoKSB7fSxcclxuXHRcdFx0XHRnZXRQcm9wZXJ0eVZhbHVlOiBmdW5jdGlvbiAocHJvcCkge1xyXG5cdFx0XHRcdFx0cmV0dXJuIHRoaXNbcHJvcF0gfHwgJyc7XHJcblx0XHRcdFx0fSxcclxuXHRcdFx0XHRpdGVtOiBmdW5jdGlvbiAoKSB7fSxcclxuXHRcdFx0XHRyZW1vdmVQcm9wZXJ0eTogZnVuY3Rpb24gKCkge30sXHJcblx0XHRcdFx0c2V0UHJvcGVydHk6IGZ1bmN0aW9uICgpIHt9LFxyXG5cdFx0XHRcdGdldFByb3BlcnR5Q1NTVmFsdWU6IGZ1bmN0aW9uICgpIHt9XHJcblx0XHRcdH07XHJcblxyXG5cdFx0XHRmdW5jdGlvbiBnZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpIHtcclxuXHRcdFx0XHRyZXR1cm4gbmV3IENTU1N0eWxlRGVjbGFyYXRpb24oZWxlbWVudCk7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdHJldHVybiBnZXRDb21wdXRlZFN0eWxlO1xyXG5cdFx0fSh0aGlzKSk7XHJcblx0fVxyXG5cclxuXHJcblx0JChkb2N1bWVudClcclxuXHRcdC5vbigna2V5ZG93bi54ZHNvZnRjdHJsJywgZnVuY3Rpb24gKGUpIHtcclxuXHRcdFx0aWYgKGUua2V5Q29kZSA9PT0gQ1RSTEtFWSkge1xyXG5cdFx0XHRcdGN0cmxEb3duID0gdHJ1ZTtcclxuXHRcdFx0fVxyXG5cdFx0XHRpZiAoZS5rZXlDb2RlID09PSBTSElGVEtFWSkge1xyXG5cdFx0XHRcdGN0cmxEb3duID0gdHJ1ZTtcclxuXHRcdFx0fVxyXG5cdFx0fSlcclxuXHRcdC5vbigna2V5dXAueGRzb2Z0Y3RybCcsIGZ1bmN0aW9uIChlKSB7XHJcblx0XHRcdGlmIChlLmtleUNvZGUgPT09IENUUkxLRVkpIHtcclxuXHRcdFx0XHRjdHJsRG93biA9IGZhbHNlO1xyXG5cdFx0XHR9XHJcblx0XHRcdGlmIChlLmtleUNvZGUgPT09IFNISUZUS0VZKSB7XHJcblx0XHRcdFx0Y3RybERvd24gPSBmYWxzZTtcclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblx0XHJcblx0ZnVuY3Rpb24gYWNjZW50UmVwbGFjZSAocykge1xyXG5cdFx0aWYgKCFzKSB7IHJldHVybiAnJzsgfVxyXG5cdFx0dmFyIHJldCA9ICcnLGk7XHJcblx0XHRmb3IgKGk9MDsgaSA8IHMubGVuZ3RoOyBpKz0xKSB7XHJcblx0XHRcdHJldCArPSBhY2NlbnRfbWFwW3MuY2hhckF0KGkpXSB8fCBzLmNoYXJBdChpKTtcclxuXHRcdH1cclxuXHRcdHJldHVybiByZXQ7XHJcblx0fVxyXG5cdFxyXG5cdGZ1bmN0aW9uIGVzY2FwZVJlZ0V4cCAoc3RyKSB7XHJcblx0XHRyZXR1cm4gc3RyLnJlcGxhY2UoL1tcXC1cXFtcXF1cXC9cXHtcXH1cXChcXClcXCpcXCtcXD9cXC5cXFxcXFxeXFwkXFx8XS9nLCBcIlxcXFwkJlwiKTtcclxuXHR9XHJcblx0XHJcblx0ZnVuY3Rpb24gZ2V0Q2FyZXRQb3NpdGlvbihpbnB1dCkge1xyXG5cdFx0aWYgKCFpbnB1dCkge1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblx0XHRpZiAoaW5wdXQuc2VsZWN0aW9uU3RhcnQpIHtcclxuXHRcdFx0cmV0dXJuIGlucHV0LnNlbGVjdGlvblN0YXJ0O1xyXG5cdFx0fVxyXG5cdFx0aWYgKGRvY3VtZW50LnNlbGVjdGlvbikge1xyXG5cdFx0XHRpbnB1dC5mb2N1cygpO1xyXG5cdFx0XHR2YXIgc2VsID0gZG9jdW1lbnQuc2VsZWN0aW9uLmNyZWF0ZVJhbmdlKCksXHJcblx0XHRcdFx0c2VsTGVuID0gZG9jdW1lbnQuc2VsZWN0aW9uLmNyZWF0ZVJhbmdlKCkudGV4dC5sZW5ndGg7XHJcblx0XHRcdHNlbC5tb3ZlU3RhcnQoJ2NoYXJhY3RlcicsIC1pbnB1dC52YWx1ZS5sZW5ndGgpO1xyXG5cdFx0XHRyZXR1cm4gc2VsLnRleHQubGVuZ3RoIC0gc2VsTGVuO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0ZnVuY3Rpb24gc2V0Q2FyZXRQb3NpdGlvbihpbnB1dCwgcG9zKSB7XHJcblx0XHRpZiAoaW5wdXQuc2V0U2VsZWN0aW9uUmFuZ2UpIHtcclxuXHRcdFx0aW5wdXQuZm9jdXMoKTtcclxuXHRcdFx0aW5wdXQuc2V0U2VsZWN0aW9uUmFuZ2UocG9zLCBwb3MpO1xyXG5cdFx0fSBlbHNlIGlmIChpbnB1dC5jcmVhdGVUZXh0UmFuZ2UpIHtcclxuXHRcdFx0dmFyIHJhbmdlID0gaW5wdXQuY3JlYXRlVGV4dFJhbmdlKCk7XHJcblx0XHRcdHJhbmdlLmNvbGxhcHNlKHRydWUpO1xyXG5cdFx0XHRyYW5nZS5tb3ZlRW5kKCdjaGFyYWN0ZXInLCBwb3MpO1xyXG5cdFx0XHRyYW5nZS5tb3ZlU3RhcnQoJ2NoYXJhY3RlcicsIHBvcyk7XHJcblx0XHRcdHJhbmdlLnNlbGVjdCgpO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0ZnVuY3Rpb24gaXNzZXQodmFsdWUpIHtcclxuXHRcdHJldHVybiB2YWx1ZSAhPT0gdW5kZWZpbmVkO1xyXG5cdH1cclxuXHJcblx0ZnVuY3Rpb24gc2FmZV9jYWxsKGNhbGxiYWNrLCBhcmdzLCBjYWxsYmFjazIsIGRlZmF1bHRWYWx1ZSkge1xyXG5cdFx0aWYgKGlzc2V0KGNhbGxiYWNrKSAmJiAhJC5pc0FycmF5KGNhbGxiYWNrKSkge1xyXG5cdFx0XHRyZXR1cm4gJC5pc0Z1bmN0aW9uKGNhbGxiYWNrKSA/IGNhbGxiYWNrLmFwcGx5KHRoaXMsYXJncyk6ZGVmYXVsdFZhbHVlO1xyXG5cdFx0fVxyXG5cdFx0aWYoaXNzZXQoY2FsbGJhY2syKSkge1xyXG5cdFx0XHRyZXR1cm4gc2FmZV9jYWxsLmNhbGwodGhpcyxjYWxsYmFjazIsYXJncyk7XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gZGVmYXVsdFZhbHVlO1xyXG5cdH07XHJcblxyXG5cdGZ1bmN0aW9uIF9fc2FmZSggY2FsbGJhY2tOYW1lLHNvdXJjZSxhcmdzLGRlZmF1bHRWYWx1ZSApe1xyXG5cdFx0dmFyIHVuZGVmaW5lZFZhcjtcclxuXHRcdHJldHVybiBzYWZlX2NhbGwuY2FsbCggdGhpcywgKGlzc2V0KHRoaXMuc291cmNlW3NvdXJjZV0pJiZcclxuXHRcdFx0T2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHRoaXMuc291cmNlW3NvdXJjZV0sIGNhbGxiYWNrTmFtZSkpID8gdGhpcy5zb3VyY2Vbc291cmNlXVtjYWxsYmFja05hbWVdIDogdW5kZWZpbmVkVmFyLCBhcmdzLCBmdW5jdGlvbigpe1xyXG5cdFx0XHRyZXR1cm4gc2FmZV9jYWxsLmNhbGwodGhpcyxcclxuXHRcdFx0XHRcdGlzc2V0KHRoaXNbY2FsbGJhY2tOYW1lXVtzb3VyY2VdKT9cclxuXHRcdFx0XHRcdFx0dGhpc1tjYWxsYmFja05hbWVdW3NvdXJjZV06KFxyXG5cdFx0XHRcdFx0XHRcdGlzc2V0KHRoaXNbY2FsbGJhY2tOYW1lXVswXSk/XHJcblx0XHRcdFx0XHRcdFx0XHR0aGlzW2NhbGxiYWNrTmFtZV1bMF06KFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodGhpcywgY2FsbGJhY2tOYW1lKT9cclxuXHRcdFx0XHRcdFx0XHRcdFx0XHR0aGlzW2NhbGxiYWNrTmFtZV06XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0dW5kZWZpbmVkVmFyXHJcblx0XHRcdFx0XHRcdFx0XHQpXHJcblx0XHRcdFx0XHRcdCksXHJcblx0XHRcdFx0XHRhcmdzLFxyXG5cdFx0XHRcdFx0ZGVmYXVsdFNldHRpbmdbY2FsbGJhY2tOYW1lXVtzb3VyY2VdfHxkZWZhdWx0U2V0dGluZ1tjYWxsYmFja05hbWVdWzBdfHxkZWZhdWx0U2V0dGluZ1tjYWxsYmFja05hbWVdLFxyXG5cdFx0XHRcdFx0ZGVmYXVsdFZhbHVlXHJcblx0XHRcdCk7XHJcblx0XHR9LGRlZmF1bHRWYWx1ZSk7XHJcblx0fTtcclxuXHJcblx0ZnVuY3Rpb24gX19nZXQoIHByb3BlcnR5LHNvdXJjZSApe1xyXG5cdFx0aWYoIWlzc2V0KHNvdXJjZSkpXHJcblx0XHRcdHNvdXJjZSA9IDA7XHJcblx0XHRcclxuXHRcdGlmKCAkLmlzQXJyYXkodGhpcy5zb3VyY2UpICYmIGlzc2V0KHRoaXMuc291cmNlW3NvdXJjZV0pICYmIGlzc2V0KHRoaXMuc291cmNlW3NvdXJjZV1bcHJvcGVydHldKSlcclxuXHRcdFx0cmV0dXJuIHRoaXMuc291cmNlW3NvdXJjZV1bcHJvcGVydHldO1xyXG5cdFx0XHRcclxuXHRcdGlmKCBpc3NldCh0aGlzW3Byb3BlcnR5XSkgKXtcclxuXHRcdFx0aWYoICQuaXNBcnJheSh0aGlzW3Byb3BlcnR5XSkgKXtcclxuXHRcdFx0XHRpZiggaXNzZXQodGhpc1twcm9wZXJ0eV1bc291cmNlXSkgKVxyXG5cdFx0XHRcdFx0cmV0dXJuIHRoaXNbcHJvcGVydHldW3NvdXJjZV07XHJcblx0XHRcdFx0aWYoIGlzc2V0KHRoaXNbcHJvcGVydHldWzBdKSApXHJcblx0XHRcdFx0XHRyZXR1cm4gdGhpc1twcm9wZXJ0eV1bMF07XHJcblx0XHRcdFx0cmV0dXJuIG51bGw7XHJcblx0XHRcdH1cclxuXHRcdFx0cmV0dXJuIHRoaXNbcHJvcGVydHldO1xyXG5cdFx0fVxyXG5cdFx0XHJcblx0XHRyZXR1cm4gbnVsbDtcclxuXHR9O1xyXG5cclxuXHRmdW5jdGlvbiBsb2FkUmVtb3RlKCB1cmwsc291cmNlT2JqZWN0LGRvbmUsZGVidWcgKXtcclxuXHRcdCBpZiAoc291cmNlT2JqZWN0Lnhocikge1xyXG5cdFx0XHRzb3VyY2VPYmplY3QueGhyLmFib3J0KCk7XHJcblx0XHQgfVxyXG5cdFx0IHNvdXJjZU9iamVjdC54aHIgPSAkLmFqYXgoJC5leHRlbmQodHJ1ZSx7XHJcblx0XHRcdHVybCA6IHVybCxcclxuXHRcdFx0dHlwZSAgOiAnR0VUJyAsXHJcblx0XHRcdGFzeW5jOnRydWUsXHJcblx0XHRcdGNhY2hlIDpmYWxzZSxcclxuXHRcdFx0ZGF0YVR5cGUgOiAnanNvbidcclxuXHRcdCB9LHNvdXJjZU9iamVjdC5hamF4KSlcclxuXHRcdCBcclxuXHRcdCAuZG9uZShmdW5jdGlvbiggZGF0YSApe1xyXG5cdFx0XHRkb25lJiZkb25lLmFwcGx5KHRoaXMsJC5tYWtlQXJyYXkoYXJndW1lbnRzKSk7XHJcblx0XHQgfSlcclxuXHRcdCBcclxuXHRcdCAuZmFpbChmdW5jdGlvbigganFYSFIsIHRleHRTdGF0dXMgKXtcclxuXHRcdFx0aWYoIGRlYnVnIClcclxuXHRcdFx0XHRjb25zb2xlLmxvZyhcIlJlcXVlc3QgZmFpbGVkOiBcIiArIHRleHRTdGF0dXMpO1xyXG5cdFx0IH0pO1xyXG5cdH1cclxuXHJcblxyXG5cdGZ1bmN0aW9uIGZpbmRSaWdodCggZGF0YSxxdWVyeSApe1xyXG5cdFx0dmFyIHJpZ2h0ID0gZmFsc2Usc291cmNlO1xyXG5cdFx0XHJcblx0XHRmb3IgKHNvdXJjZSA9IDA7c291cmNlIDwgZGF0YS5sZW5ndGg7c291cmNlICs9IDEpIHtcclxuXHRcdFx0aWYoIHJpZ2h0ID0gX19zYWZlLmNhbGwodGhpcyxcImZpbmRSaWdodFwiLHNvdXJjZSxbZGF0YVtzb3VyY2VdLHF1ZXJ5LHNvdXJjZV0pICl7XHJcblx0XHRcdFx0cmV0dXJuIHtyaWdodDpyaWdodCxzb3VyY2U6c291cmNlfTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdFx0XHJcblx0XHRyZXR1cm4gZmFsc2U7XHJcblx0fVxyXG5cclxuXHRmdW5jdGlvbiBwcm9jZXNzRGF0YSggZGF0YSxxdWVyeSApe1xyXG5cdFx0dmFyIHNvdXJjZTtcclxuXHRcdHByZXBhcnNlRGF0YVxyXG5cdFx0XHQuY2FsbCggdGhpcyxkYXRhLHF1ZXJ5ICk7XHJcblx0XHRcclxuXHRcdGZvciAoc291cmNlID0gMDtzb3VyY2UgPCBkYXRhLmxlbmd0aDtzb3VyY2UgKz0gMSkge1xyXG5cdFx0XHRkYXRhW3NvdXJjZV0gPSBfX3NhZmUuY2FsbCh0aGlzLFxyXG5cdFx0XHRcdCdmaWx0ZXInLFxyXG5cdFx0XHRcdHNvdXJjZSxcclxuXHRcdFx0XHRbZGF0YVtzb3VyY2VdLCBxdWVyeSwgc291cmNlXSxcclxuXHRcdFx0XHRkYXRhW3NvdXJjZV1cclxuXHRcdFx0KTtcclxuXHRcdH1cclxuXHR9O1xyXG5cclxuXHJcblx0ZnVuY3Rpb24gY29sbGVjdERhdGEoIHF1ZXJ5LGRhdGFzb3VyY2UsY2FsbGJhY2sgKXtcclxuXHRcdHZhciBvcHRpb25zID0gdGhpcyxzb3VyY2U7XHJcblx0XHRcclxuXHRcdGlmKCAkLmlzRnVuY3Rpb24ob3B0aW9ucy5zb3VyY2UpICl7XHJcblx0XHRcdFx0b3B0aW9ucy5zb3VyY2UuYXBwbHkob3B0aW9ucyxbcXVlcnksZnVuY3Rpb24oaXRlbXMpe1xyXG5cdFx0XHRcdFx0ZGF0YXNvdXJjZSA9IFtpdGVtc107XHJcblx0XHRcdFx0XHRzYWZlX2NhbGwuY2FsbChvcHRpb25zLGNhbGxiYWNrLFtxdWVyeV0pO1xyXG5cdFx0XHRcdH0sZGF0YXNvdXJjZSwwXSk7XHJcblx0XHR9ZWxzZXtcclxuXHRcdFx0Zm9yIChzb3VyY2UgPSAwO3NvdXJjZSA8IG9wdGlvbnMuc291cmNlLmxlbmd0aDtzb3VyY2UgKz0gMSkge1xyXG5cdFx0XHRcdGlmICgkLmlzQXJyYXkob3B0aW9ucy5zb3VyY2Vbc291cmNlXSkpIHtcclxuXHRcdFx0XHRcdGRhdGFzb3VyY2Vbc291cmNlXSA9IG9wdGlvbnMuc291cmNlW3NvdXJjZV07XHJcblx0XHRcdFx0fSBlbHNlIGlmICgkLmlzRnVuY3Rpb24ob3B0aW9ucy5zb3VyY2Vbc291cmNlXSkpIHtcclxuXHRcdFx0XHRcdChmdW5jdGlvbiAoc291cmNlKSB7XHJcblx0XHRcdFx0XHRcdG9wdGlvbnMuc291cmNlW3NvdXJjZV0uYXBwbHkob3B0aW9ucyxbcXVlcnksIGZ1bmN0aW9uKGl0ZW1zKXtcclxuXHRcdFx0XHRcdFx0XHRpZiAoIWRhdGFzb3VyY2Vbc291cmNlXSkge1xyXG5cdFx0XHRcdFx0XHRcdFx0ZGF0YXNvdXJjZVtzb3VyY2VdID0gW107XHJcblx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdFx0XHJcblx0XHRcdFx0XHRcdFx0aWYgKGl0ZW1zICYmICQuaXNBcnJheShpdGVtcykpIHtcclxuXHRcdFx0XHRcdFx0XHRcdHN3aXRjaCAob3B0aW9ucy5hcHBlbmRNZXRob2QpIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0Y2FzZSAncmVwbGFjZSc6XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0ZGF0YXNvdXJjZVtzb3VyY2VdID0gaXRlbXM7XHJcblx0XHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRkZWZhdWx0OlxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdGRhdGFzb3VyY2Vbc291cmNlXSA9IGRhdGFzb3VyY2Vbc291cmNlXS5jb25jYXQoaXRlbXMpO1xyXG5cdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0XHRcdFxyXG5cdFx0XHRcdFx0XHRcdHNhZmVfY2FsbC5jYWxsKG9wdGlvbnMsY2FsbGJhY2ssW3F1ZXJ5XSk7XHJcblx0XHRcdFx0XHRcdH0sIGRhdGFzb3VyY2Usc291cmNlXSk7XHJcblx0XHRcdFx0XHR9KHNvdXJjZSkpO1xyXG5cdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRzd2l0Y2ggKG9wdGlvbnMuc291cmNlW3NvdXJjZV0udHlwZSkge1xyXG5cdFx0XHRcdFx0XHRjYXNlICdyZW1vdGUnOlxyXG5cdFx0XHRcdFx0XHRcdGlmIChpc3NldChvcHRpb25zLnNvdXJjZVtzb3VyY2VdLnVybCkpIHtcclxuXHRcdFx0XHRcdFx0XHRcdGlmICghaXNzZXQob3B0aW9ucy5zb3VyY2Vbc291cmNlXS5taW5MZW5ndGgpIHx8IHF1ZXJ5Lmxlbmd0aCA+PSBvcHRpb25zLnNvdXJjZVtzb3VyY2VdLm1pbkxlbmd0aCl7XHJcblx0XHRcdFx0XHRcdFx0XHRcdHZhciB1cmwgPSBfX3NhZmUuY2FsbChvcHRpb25zLCdyZXBsYWNlJyxzb3VyY2UsW29wdGlvbnMuc291cmNlW3NvdXJjZV0udXJsLHF1ZXJ5XSwnJyk7XHJcblx0XHRcdFx0XHRcdFx0XHRcdGlmICghZGF0YXNvdXJjZVtzb3VyY2VdKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0ZGF0YXNvdXJjZVtzb3VyY2VdID0gW107XHJcblx0XHRcdFx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0XHRcdFx0KGZ1bmN0aW9uIChzb3VyY2UpIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRsb2FkUmVtb3RlKHVybCxvcHRpb25zLnNvdXJjZVtzb3VyY2VdLCBmdW5jdGlvbihyZXNwKXtcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdGRhdGFzb3VyY2Vbc291cmNlXSA9IHJlc3A7XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRzYWZlX2NhbGwuY2FsbChvcHRpb25zLGNhbGxiYWNrLFtxdWVyeV0pO1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdH0sb3B0aW9ucy5kZWJ1Zyk7XHJcblx0XHRcdFx0XHRcdFx0XHRcdH0oc291cmNlKSk7XHJcblx0XHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRicmVhaztcclxuXHRcdFx0XHRcdFx0ZGVmYXVsdDpcclxuXHRcdFx0XHRcdFx0XHRpZiggaXNzZXQob3B0aW9ucy5zb3VyY2Vbc291cmNlXVsnZGF0YSddKSApe1xyXG5cdFx0XHRcdFx0XHRcdFx0ZGF0YXNvdXJjZVtzb3VyY2VdID0gb3B0aW9ucy5zb3VyY2Vbc291cmNlXVsnZGF0YSddO1xyXG5cdFx0XHRcdFx0XHRcdH1lbHNle1xyXG5cdFx0XHRcdFx0XHRcdFx0ZGF0YXNvdXJjZVtzb3VyY2VdID0gb3B0aW9ucy5zb3VyY2Vbc291cmNlXTtcclxuXHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0XHRzYWZlX2NhbGwuY2FsbChvcHRpb25zLGNhbGxiYWNrLFtxdWVyeV0pO1xyXG5cdH07XHJcblxyXG5cdGZ1bmN0aW9uIHByZXBhcnNlRGF0YSggZGF0YSxxdWVyeSApe1xyXG5cdFx0Zm9yKCB2YXIgc291cmNlPTA7c291cmNlPGRhdGEubGVuZ3RoO3NvdXJjZSsrICl7XHJcblx0XHRcdGRhdGFbc291cmNlXSA9IF9fc2FmZS5jYWxsKHRoaXMsXHJcblx0XHRcdFx0J3ByZXBhcnNlJyxcclxuXHRcdFx0XHRzb3VyY2UsXHJcblx0XHRcdFx0W2RhdGFbc291cmNlXSxxdWVyeV0sXHJcblx0XHRcdFx0ZGF0YVtzb3VyY2VdXHJcblx0XHRcdCk7XHJcblx0XHR9XHJcblx0fTtcclxuXHJcblx0ZnVuY3Rpb24gcmVuZGVyRGF0YSggZGF0YSxxdWVyeSApe1xyXG5cdFx0dmFyICBzb3VyY2UsIGksICRkaXYsICRkaXZzID0gW107XHJcblx0XHRcclxuXHRcdGZvciAoc291cmNlID0gMDtzb3VyY2UgPCBkYXRhLmxlbmd0aDtzb3VyY2UgKz0gMSkge1xyXG5cdFx0XHRmb3IgKGkgPSAwO2kgPCBkYXRhW3NvdXJjZV0ubGVuZ3RoO2kgKz0gMSkge1xyXG5cdFx0XHRcdGlmKCAkZGl2cy5sZW5ndGg+PXRoaXMubGltaXQgKVxyXG5cdFx0XHRcdFx0YnJlYWs7XHJcblx0XHRcdFx0XHRcclxuXHRcdFx0XHQkZGl2ID0gJChfX3NhZmUuY2FsbCh0aGlzLFxyXG5cdFx0XHRcdFx0J3JlbmRlcicsc291cmNlLFxyXG5cdFx0XHRcdFx0W2RhdGFbc291cmNlXVtpXSxzb3VyY2UsaSxxdWVyeV0sXHJcblx0XHRcdFx0XHQnJ1xyXG5cdFx0XHRcdCkpO1xyXG5cdFx0XHRcdFxyXG5cdFx0XHRcdCRkaXYuZGF0YSgnc291cmNlJyxzb3VyY2UpO1xyXG5cdFx0XHRcdCRkaXYuZGF0YSgncGlkJyxpKTtcclxuXHRcdFx0XHQkZGl2LmRhdGEoJ2l0ZW0nLGRhdGFbc291cmNlXVtpXSk7XHJcblx0XHRcdFx0XHJcblx0XHRcdFx0JGRpdnMucHVzaCgkZGl2KTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdFx0XHJcblx0XHRyZXR1cm4gJGRpdnM7XHJcblx0fTtcclxuXHJcblx0ZnVuY3Rpb24gZ2V0SXRlbSggJGRpdixkYXRhc2V0ICl7XHJcblx0XHRpZiggaXNzZXQoJGRpdi5kYXRhKCdzb3VyY2UnKSkgJiYgXHJcblx0XHRcdGlzc2V0KCRkaXYuZGF0YSgncGlkJykpICYmIFxyXG5cdFx0XHRpc3NldChkYXRhc2V0WyRkaXYuZGF0YSgnc291cmNlJyldKSAmJiBcclxuXHRcdFx0aXNzZXQoZGF0YXNldFskZGl2LmRhdGEoJ3NvdXJjZScpXVskZGl2LmRhdGEoJ3BpZCcpXSkgXHJcblx0XHQpe1xyXG5cdFx0XHRyZXR1cm4gZGF0YXNldFskZGl2LmRhdGEoJ3NvdXJjZScpXVskZGl2LmRhdGEoJ3BpZCcpXTtcclxuXHRcdH1cclxuXHRcdHJldHVybiBmYWxzZTtcclxuXHR9O1xyXG5cclxuXHRmdW5jdGlvbiBnZXRWYWx1ZSggJGRpdixkYXRhc2V0ICl7XHJcblx0XHR2YXIgaXRlbSA9IGdldEl0ZW0oJGRpdixkYXRhc2V0KTtcclxuXHRcdFxyXG5cdFx0aWYoIGl0ZW0gKXtcclxuXHRcdFx0cmV0dXJuIF9fc2FmZS5jYWxsKHRoaXMsXHJcblx0XHRcdFx0J2dldFZhbHVlJywkZGl2LmRhdGEoJ3NvdXJjZScpLFxyXG5cdFx0XHRcdFtpdGVtLCRkaXYuZGF0YSgnc291cmNlJyldXHJcblx0XHRcdCk7XHJcblx0XHR9ZWxzZXtcclxuXHRcdFx0aWYoIGlzc2V0KCRkaXYuZGF0YSgndmFsdWUnKSkgKXtcclxuXHRcdFx0XHRyZXR1cm4gZGVjb2RlVVJJQ29tcG9uZW50KCRkaXYuZGF0YSgndmFsdWUnKSk7XHJcblx0XHRcdH1lbHNle1xyXG5cdFx0XHRcdHJldHVybiAkZGl2Lmh0bWwoKTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdH07XHJcblxyXG5cdGRlZmF1bHRTZXR0aW5nID0ge1xyXG5cdFx0bWluTGVuZ3RoOiAwLFxyXG5cdFx0dmFsdWVLZXk6ICd2YWx1ZScsXHJcblx0XHR0aXRsZUtleTogJ3RpdGxlJyxcclxuXHRcdGhpZ2hsaWdodDogdHJ1ZSxcclxuXHJcblx0XHRzaG93SGludDogdHJ1ZSxcclxuXHJcblx0XHRkcm9wZG93bldpZHRoOiAnMTAwJScsXHJcblx0XHRkcm9wZG93blN0eWxlOiB7fSxcclxuXHRcdGl0ZW1TdHlsZToge30sXHJcblx0XHRoaW50U3R5bGU6IGZhbHNlLFxyXG5cdFx0c3R5bGU6IGZhbHNlLFxyXG5cclxuXHRcdGRlYnVnOiB0cnVlLFxyXG5cdFx0b3Blbk9uRm9jdXM6IGZhbHNlLFxyXG5cdFx0Y2xvc2VPbkJsdXI6IHRydWUsXHJcblxyXG5cdFx0YXV0b3NlbGVjdDogZmFsc2UsXHJcblx0XHRcclxuXHRcdGFjY2VudHM6IHRydWUsXHJcblx0XHRyZXBsYWNlQWNjZW50c0ZvclJlbW90ZTogdHJ1ZSxcclxuXHRcdFxyXG5cdFx0bGltaXQ6IDIwLFxyXG5cdFx0dmlzaWJsZUxpbWl0OiAyMCxcclxuXHRcdHZpc2libGVIZWlnaHQ6IDAsXHJcblx0XHRkZWZhdWx0SGVpZ2h0SXRlbTogMzAsXHJcblxyXG5cdFx0dGltZW91dFVwZGF0ZTogMTAsXHJcblxyXG5cdFx0Z2V0OiBmdW5jdGlvbiAocHJvcGVydHksIHNvdXJjZSkge1xyXG5cdFx0XHRyZXR1cm4gX19nZXQuY2FsbCh0aGlzLHByb3BlcnR5LHNvdXJjZSk7XHJcblx0XHR9LFxyXG5cdFx0XHJcblx0XHRyZXBsYWNlOiBbXHJcblx0XHRcdGZ1bmN0aW9uICh1cmwsIHF1ZXJ5KSB7XHJcblx0XHRcdFx0aWYgKHRoaXMucmVwbGFjZUFjY2VudHNGb3JSZW1vdGUpIHtcclxuXHRcdFx0XHRcdHF1ZXJ5ID0gYWNjZW50UmVwbGFjZShxdWVyeSk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdHJldHVybiB1cmwucmVwbGFjZSgnJVFVRVJZJScsZW5jb2RlVVJJQ29tcG9uZW50KHF1ZXJ5KSk7XHJcblx0XHRcdH1cclxuXHRcdF0sXHJcblx0XHRcclxuXHRcdGVxdWFsOmZ1bmN0aW9uKCB2YWx1ZSxxdWVyeSApe1xyXG5cdFx0XHRyZXR1cm4gcXVlcnkudG9Mb3dlckNhc2UoKT09dmFsdWUuc3Vic3RyKDAscXVlcnkubGVuZ3RoKS50b0xvd2VyQ2FzZSgpO1xyXG5cdFx0fSxcclxuXHRcdFxyXG5cdFx0ZmluZFJpZ2h0OltcclxuXHRcdFx0ZnVuY3Rpb24oaXRlbXMscXVlcnksc291cmNlKXtcclxuXHRcdFx0XHR2YXIgcmVzdWx0cyA9IFtdLHZhbHVlID0gJycsaTtcclxuXHRcdFx0XHRpZiAoaXRlbXMpIHtcclxuXHRcdFx0XHRcdGZvciAoaSA9IDA7aSA8IGl0ZW1zLmxlbmd0aDtpICs9IDEpIHtcclxuXHRcdFx0XHRcdFx0dmFsdWUgPSBfX3NhZmUuY2FsbCh0aGlzLCdnZXRWYWx1ZScsc291cmNlLFtpdGVtc1tpXSxzb3VyY2VdKTtcclxuXHRcdFx0XHRcdFx0aWYgKF9fc2FmZS5jYWxsKHRoaXMsICdlcXVhbCcsIHNvdXJjZSwgW3ZhbHVlLHF1ZXJ5LHNvdXJjZV0sIGZhbHNlKSkge1xyXG5cdFx0XHRcdFx0XHRcdHJldHVybiBpdGVtc1tpXTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0fVx0XHRcdFx0XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdHJldHVybiBmYWxzZTtcclxuXHRcdFx0fVxyXG5cdFx0XSxcclxuXHRcdFxyXG5cdFx0dmFsaWQ6W1xyXG5cdFx0XHRmdW5jdGlvbiAodmFsdWUsIHF1ZXJ5KSB7XHJcblx0XHRcdFx0aWYgKHRoaXMuYWNjZW50cykge1xyXG5cdFx0XHRcdFx0dmFsdWUgPSBhY2NlbnRSZXBsYWNlKHZhbHVlKTtcclxuXHRcdFx0XHRcdHF1ZXJ5ID0gYWNjZW50UmVwbGFjZShxdWVyeSk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdHJldHVybiB2YWx1ZS50b0xvd2VyQ2FzZSgpLmluZGV4T2YocXVlcnkudG9Mb3dlckNhc2UoKSkhPS0xO1xyXG5cdFx0XHRcdFxyXG5cdFx0XHR9XHJcblx0XHRdLFxyXG5cdFx0XHJcblx0XHRmaWx0ZXI6W1xyXG5cdFx0XHRmdW5jdGlvbiAoaXRlbXMsIHF1ZXJ5LCBzb3VyY2UpIHtcclxuXHRcdFx0XHR2YXIgcmVzdWx0cyA9IFtdLCB2YWx1ZSA9ICcnLGk7XHJcblx0XHRcdFx0aWYgKGl0ZW1zKSB7XHRcdFx0XHRcdFxyXG5cdFx0XHRcdFx0Zm9yIChpID0gMDtpIDwgaXRlbXMubGVuZ3RoO2kgKz0gMSkge1xyXG5cdFx0XHRcdFx0XHR2YWx1ZSA9IGlzc2V0KGl0ZW1zW2ldW3RoaXMuZ2V0KCd2YWx1ZUtleScsIHNvdXJjZSldKSA/IGl0ZW1zW2ldW3RoaXMuZ2V0KCd2YWx1ZUtleScsIHNvdXJjZSldIDogaXRlbXNbaV0udG9TdHJpbmcoKTtcclxuXHRcdFx0XHRcdFx0aWYgKF9fc2FmZS5jYWxsKHRoaXMsICd2YWxpZCcsIHNvdXJjZSwgW3ZhbHVlLCBxdWVyeV0pKSB7XHJcblx0XHRcdFx0XHRcdFx0cmVzdWx0cy5wdXNoKGl0ZW1zW2ldKTsgXHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0cmV0dXJuIHJlc3VsdHM7XHJcblx0XHRcdH1cclxuXHRcdF0sXHJcblx0XHRcclxuXHRcdHByZXBhcnNlOmZ1bmN0aW9uKGl0ZW1zKXtcclxuXHRcdFx0cmV0dXJuIGl0ZW1zO1xyXG5cdFx0fSxcclxuXHRcdFxyXG5cdFx0Z2V0VmFsdWU6IFtcclxuXHRcdFx0ZnVuY3Rpb24gKGl0ZW0sIHNvdXJjZSkge1xyXG5cdFx0XHRcdHJldHVybiBpc3NldChpdGVtW3RoaXMuZ2V0KCd2YWx1ZUtleScsc291cmNlKV0pP2l0ZW1bdGhpcy5nZXQoJ3ZhbHVlS2V5Jyxzb3VyY2UpXTppdGVtLnRvU3RyaW5nKCk7XHJcblx0XHRcdH1cclxuXHRcdF0sXHJcblx0XHRcclxuXHRcdGdldFRpdGxlOiBbXHJcblx0XHRcdGZ1bmN0aW9uIChpdGVtLCBzb3VyY2UpIHtcclxuXHRcdFx0XHRyZXR1cm4gaXNzZXQoaXRlbVt0aGlzLmdldCgndGl0bGVLZXknLHNvdXJjZSldKT9pdGVtW3RoaXMuZ2V0KCd0aXRsZUtleScsc291cmNlKV06aXRlbS50b1N0cmluZygpO1xyXG5cdFx0XHR9XHJcblx0XHRdLFxyXG5cdFx0XHJcblx0XHRyZW5kZXI6IFtcclxuXHRcdFx0ZnVuY3Rpb24gKGl0ZW0sIHNvdXJjZSwgcGlkLCBxdWVyeSkge1xyXG5cdFx0XHRcdHZhciB2YWx1ZSA9IF9fc2FmZS5jYWxsKHRoaXMsIFwiZ2V0VmFsdWVcIiwgc291cmNlLCBbaXRlbSwgc291cmNlXSwgZGVmYXVsdFNldHRpbmcuZ2V0VmFsdWVbMF0uY2FsbCh0aGlzLCBpdGVtLCBzb3VyY2UpKSxcclxuXHRcdFx0XHRcdHRpdGxlID0gX19zYWZlLmNhbGwodGhpcywgXCJnZXRUaXRsZVwiLCBzb3VyY2UsIFtpdGVtLCBzb3VyY2VdLCBkZWZhdWx0U2V0dGluZy5nZXRUaXRsZVswXS5jYWxsKHRoaXMsIGl0ZW0sIHNvdXJjZSkpLFxyXG5cdFx0XHRcdFx0X3ZhbHVlID0gJycsXHJcblx0XHRcdFx0XHRfcXVlcnkgPSAnJyxcclxuXHRcdFx0XHRcdF90aXRsZSA9ICcnLFxyXG5cdFx0XHRcdFx0aGlsaXRlX2hpbnRzID0gJycsXHJcblx0XHRcdFx0XHRoaWdobGlnaHRlZCA9ICcnLFxyXG5cdFx0XHRcdFx0YywgaCwgaSxcclxuXHRcdFx0XHRcdHNwb3MgPSAwO1xyXG5cdFx0XHRcdFx0XHJcblx0XHRcdFx0aWYgKHRoaXMuaGlnaGxpZ2h0KSB7XHJcblx0XHRcdFx0XHRpZiAoIXRoaXMuYWNjZW50cykge1xyXG5cdFx0XHRcdFx0XHR0aXRsZSA9IHRpdGxlLnJlcGxhY2UobmV3IFJlZ0V4cCgnKCcrZXNjYXBlUmVnRXhwKHF1ZXJ5KSsnKScsJ2knKSwnPGI+JDE8L2I+Jyk7XHJcblx0XHRcdFx0XHR9ZWxzZXtcclxuXHRcdFx0XHRcdFx0X3RpdGxlID0gYWNjZW50UmVwbGFjZSh0aXRsZSkudG9Mb3dlckNhc2UoKS5yZXBsYWNlKC9bPD5dKy9nLCAnJyksXHJcblx0XHRcdFx0XHRcdF9xdWVyeSA9IGFjY2VudFJlcGxhY2UocXVlcnkpLnRvTG93ZXJDYXNlKCkucmVwbGFjZSgvWzw+XSsvZywgJycpO1xyXG5cdFx0XHRcdFx0XHRcclxuXHRcdFx0XHRcdFx0aGlsaXRlX2hpbnRzID0gX3RpdGxlLnJlcGxhY2UobmV3IFJlZ0V4cChlc2NhcGVSZWdFeHAoX3F1ZXJ5KSwgJ2cnKSwgJzwnK19xdWVyeSsnPicpO1xyXG5cdFx0XHRcdFx0XHRmb3IgKGk9MDtpIDwgaGlsaXRlX2hpbnRzLmxlbmd0aDtpICs9IDEpIHtcclxuXHRcdFx0XHRcdFx0XHRjID0gdGl0bGUuY2hhckF0KHNwb3MpO1xyXG5cdFx0XHRcdFx0XHRcdGggPSBoaWxpdGVfaGludHMuY2hhckF0KGkpO1xyXG5cdFx0XHRcdFx0XHRcdGlmIChoID09PSAnPCcpIHtcclxuXHRcdFx0XHRcdFx0XHRcdGhpZ2hsaWdodGVkICs9ICc8Yj4nO1xyXG5cdFx0XHRcdFx0XHRcdH0gZWxzZSBpZiAoaCA9PT0gJz4nKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRoaWdobGlnaHRlZCArPSAnPC9iPic7XHJcblx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdFx0XHRcdHNwb3MgKz0gMTtcclxuXHRcdFx0XHRcdFx0XHRcdGhpZ2hsaWdodGVkICs9IGM7XHJcblx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdHRpdGxlID0gaGlnaGxpZ2h0ZWQ7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHJcblx0XHRcdFx0cmV0dXJuICc8ZGl2ICcrKHZhbHVlPT1xdWVyeT8nY2xhc3M9XCJhY3RpdmVcIic6JycpKycgZGF0YS12YWx1ZT1cIicrZW5jb2RlVVJJQ29tcG9uZW50KHZhbHVlKSsnXCI+J1xyXG5cdFx0XHRcdFx0XHRcdCt0aXRsZStcclxuXHRcdFx0XHRcdFx0JzwvZGl2Pic7XHJcblx0XHRcdH1cclxuXHRcdF0sXHJcblx0XHRhcHBlbmRNZXRob2Q6ICdjb25jYXQnLCAvLyBzdXBwb3J0ZWQgbWVyZ2UgYW5kIHJlcGxhY2UgXHJcblx0XHRzb3VyY2U6W10sXHJcblx0XHRhZnRlclNlbGVjdGVkOiBmdW5jdGlvbigpIHtcclxuICAgICAgICB9XHJcblx0fTtcclxuXHRmdW5jdGlvbiBpbml0KCB0aGF0LG9wdGlvbnMgKXtcclxuXHRcdGlmKCAkKHRoYXQpLmhhc0NsYXNzKCd4ZHNvZnRfaW5wdXQnKSApXHJcblx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHJcblx0XHR2YXIgJGJveCA9ICQoJzxkaXYgY2xhc3M9XCJ4ZHNvZnRfYXV0b2NvbXBsZXRlXCI+PC9kaXY+JyksXHJcblx0XHRcdCRkcm9wZG93biA9ICQoJzxkaXYgY2xhc3M9XCJ4ZHNvZnRfYXV0b2NvbXBsZXRlX2Ryb3Bkb3duXCI+PC9kaXY+JyksXHJcblx0XHRcdCRoaW50ID0gJCgnPGlucHV0IHJlYWRvbmx5IGNsYXNzPVwieGRzb2Z0X2F1dG9jb21wbGV0ZV9oaW50XCIvPicpLFxyXG5cdFx0XHQkaW5wdXQgPSAkKHRoYXQpLFxyXG5cdFx0XHR0aW1lcjEgPSAwLFxyXG5cdFx0XHRpbnRlcnZhbEZvclZpc2liaWxpdHksXHJcblx0XHRcdGRhdGFzZXQgPSBbXSxcclxuXHRcdFx0aU9wZW5cdD0gZmFsc2UsXHJcblx0XHRcdHZhbHVlID0gJycsXHJcblx0XHRcdGN1cnJlbnRWYWx1ZSA9ICcnLFxyXG5cdFx0XHRjdXJyZW50U2VsZWN0ID0gJycsXHJcblx0XHRcdGFjdGl2ZSA9IG51bGwsXHJcblx0XHRcdHBvcyA9IDA7XHJcblx0XHRcclxuXHRcdC8vaXQgY2FuIGJlIHVzZWQgdG8gYWNjZXNzIHNldHRpbmdzXHJcblx0XHQkaW5wdXQuZGF0YSgnYXV0b2NvbXBsZXRlX29wdGlvbnMnLCBvcHRpb25zKTtcclxuXHRcdFxyXG5cdFx0JGRyb3Bkb3duXHJcblx0XHRcdC5vbignbW91c2Vkb3duJywgZnVuY3Rpb24oZSkge1xyXG5cdFx0XHRcdGUucHJldmVudERlZmF1bHQoKTtcclxuXHRcdFx0XHRlLnN0b3BQcm9wYWdhdGlvbigpO1xyXG5cdFx0XHR9KVxyXG5cdFx0XHQub24oJ3VwZGF0ZXNjcm9sbC54ZHNvZnQnLCBmdW5jdGlvbigpIHtcclxuXHRcdFx0XHR2YXIgX2FjdCA9ICRkcm9wZG93bi5maW5kKCcuYWN0aXZlJyk7XHJcblx0XHRcdFx0aWYgKCFfYWN0Lmxlbmd0aCkge1xyXG5cdFx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRcclxuXHRcdFx0XHR2YXIgdG9wID0gX2FjdC5wb3NpdGlvbigpLnRvcCxcclxuXHRcdFx0XHRcdGFjdEhnaHQgPSBfYWN0Lm91dGVySGVpZ2h0KHRydWUpLFxyXG5cdFx0XHRcdFx0c2NybFRvcCA9ICRkcm9wZG93bi5zY3JvbGxUb3AoKSxcclxuXHRcdFx0XHRcdGhnaHQgPSAkZHJvcGRvd24uaGVpZ2h0KCk7XHJcblx0XHRcdFx0XHRcclxuXHRcdFx0XHRpZiAodG9wIDwwKSB7XHJcblx0XHRcdFx0XHQkZHJvcGRvd24uc2Nyb2xsVG9wKHNjcmxUb3AtTWF0aC5hYnModG9wKSk7XHJcblx0XHRcdFx0fSBlbHNlIGlmICh0b3ArYWN0SGdodD5oZ2h0KSB7XHJcblx0XHRcdFx0XHQkZHJvcGRvd24uc2Nyb2xsVG9wKHNjcmxUb3ArdG9wK2FjdEhnaHQtaGdodCk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9KTtcclxuXHRcdFxyXG5cdFx0JGJveFxyXG5cdFx0XHQuY3NzKHtcclxuXHRcdFx0XHQnZGlzcGxheSc6JGlucHV0LmNzcygnZGlzcGxheScpLFxyXG5cdFx0XHRcdCd3aWR0aCc6JGlucHV0LmNzcygnd2lkdGgnKVxyXG5cdFx0XHR9KTtcclxuXHRcdFxyXG5cdFx0aWYoIG9wdGlvbnMuc3R5bGUgKVxyXG5cdFx0XHQkYm94LmNzcyhvcHRpb25zLnN0eWxlKTtcclxuXHRcdFx0XHJcblx0XHQkaW5wdXRcclxuXHRcdFx0LmFkZENsYXNzKCd4ZHNvZnRfaW5wdXQnKVxyXG5cdFx0XHQuYXR0cignYXV0b2NvbXBsZXRlJywnb2ZmJyk7XHJcblx0XHRcclxuXHRcdHZhciB4RG93biA9IG51bGw7XHJcblx0XHR2YXIgeURvd24gPSBudWxsO1xyXG5cdFx0dmFyIGlzU3dpcGUgPSBmYWxzZTtcclxuXHRcdCRkcm9wZG93blxyXG5cdFx0XHQub24oJ21vdXNlbW92ZScsJ2RpdicsZnVuY3Rpb24oKXtcclxuXHRcdFx0XHRpZiggJCh0aGlzKS5oYXNDbGFzcygnYWN0aXZlJykgKVxyXG5cdFx0XHRcdFx0cmV0dXJuIHRydWU7XHJcblx0XHRcdFx0JGRyb3Bkb3duLmZpbmQoJ2RpdicpLnJlbW92ZUNsYXNzKCdhY3RpdmUnKTtcclxuXHRcdFx0XHQkKHRoaXMpLmFkZENsYXNzKCdhY3RpdmUnKTtcclxuXHRcdFx0fSlcclxuXHRcdFx0Lm9uKCdtb3VzZWRvd24nLCdkaXYnLGZ1bmN0aW9uKGUpe1xyXG5cdFx0XHRcdCRkcm9wZG93bi5maW5kKCdkaXYnKS5yZW1vdmVDbGFzcygnYWN0aXZlJyk7XHJcblx0XHRcdFx0JCh0aGlzKS5hZGRDbGFzcygnYWN0aXZlJyk7XHJcblx0XHRcdFx0JGlucHV0LnRyaWdnZXIoJ3BpY2sueGRzb2Z0Jyk7XHJcblx0XHRcdH0pXHJcblx0XHRcdC5vbigndG91Y2hzdGFydCcsJ2RpdicsZnVuY3Rpb24oZSl7XHJcblx0XHRcdFx0eERvd24gPSBlLm9yaWdpbmFsRXZlbnQudG91Y2hlc1swXS5jbGllbnRYO1xyXG5cdFx0XHRcdHlEb3duID0gZS5vcmlnaW5hbEV2ZW50LnRvdWNoZXNbMF0uY2xpZW50WTtcclxuXHRcdFx0fSlcclxuXHRcdFx0Lm9uKCd0b3VjaGVuZCcsJ2RpdicsZnVuY3Rpb24oZSl7XHJcblx0XHRcdFx0aWYoaXNTd2lwZSA9PT0gZmFsc2UpIHtcclxuXHRcdFx0XHRcdCRkcm9wZG93bi5maW5kKCdkaXYnKS5yZW1vdmVDbGFzcygnYWN0aXZlJyk7XHJcblx0XHRcdFx0XHQkKHRoaXMpLmFkZENsYXNzKCdhY3RpdmUnKTtcclxuXHRcdFx0XHRcdCRpbnB1dC50cmlnZ2VyKCdwaWNrLnhkc29mdCcpO1xyXG5cdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0aXNTd2lwZSA9IGZhbHNlO1xyXG5cdFx0XHR9KVxyXG5cdFx0XHQub24oJ3RvdWNobW92ZScsJ2RpdicsZnVuY3Rpb24oZSl7XHJcblx0XHRcdFx0aWYgKCAhIHhEb3duIHx8ICEgeURvd24gKSB7XHJcblx0XHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHR2YXIgeFVwID0gZS5vcmlnaW5hbEV2ZW50LnRvdWNoZXNbMF0uY2xpZW50WDtcclxuXHRcdFx0XHR2YXIgeVVwID0gZS5vcmlnaW5hbEV2ZW50LnRvdWNoZXNbMF0uY2xpZW50WTtcclxuXHJcblx0XHRcdFx0dmFyIHhEaWZmID0geERvd24gLSB4VXA7XHJcblx0XHRcdFx0dmFyIHlEaWZmID0geURvd24gLSB5VXA7XHJcblxyXG5cdFx0XHRcdGlmICggTWF0aC5hYnMoIHhEaWZmICkgPiBNYXRoLmFicyggeURpZmYgKSApIHtcclxuXHRcdFx0XHRcdGlmICggeERpZmYgPiAwICkge1xyXG5cdFx0XHRcdFx0XHRpc1N3aXBlID0gJ2xlZnQnO1xyXG5cdFx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdFx0aXNTd2lwZSA9ICdyaWdodCc7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdGlmICggeURpZmYgPiAwICkge1xyXG5cdFx0XHRcdFx0XHRpc1N3aXBlID0gJ3RvcCc7XHJcblx0XHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0XHRpc1N3aXBlID0gJ2JvdHRtJztcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdHhEb3duID0gbnVsbDtcclxuXHRcdFx0XHR5RG93biA9IG51bGw7XHJcblx0XHRcdH0pO1xyXG5cclxuXHRcdGZ1bmN0aW9uIG1hbmFnZURhdGEoKXtcclxuXHRcdFx0aWYgKCRpbnB1dC52YWwoKSE9Y3VycmVudFZhbHVlKXtcclxuXHRcdFx0XHRjdXJyZW50VmFsdWUgPSAkaW5wdXQudmFsKCk7XHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHR9XHJcblx0XHRcdGlmIChjdXJyZW50VmFsdWUubGVuZ3RoIDwgb3B0aW9ucy5taW5MZW5ndGgpIHtcclxuXHRcdFx0XHQkaW5wdXQudHJpZ2dlcignY2xvc2UueGRzb2Z0Jyk7XHJcblx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHR9XHJcblx0XHRcdGNvbGxlY3REYXRhLmNhbGwob3B0aW9ucyxjdXJyZW50VmFsdWUsZGF0YXNldCxmdW5jdGlvbiggcXVlcnkgKXtcclxuXHRcdFx0XHRpZiAocXVlcnkgIT0gY3VycmVudFZhbHVlKSB7XHJcblx0XHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdHZhciByaWdodDtcdFxyXG5cdFx0XHRcdHByb2Nlc3NEYXRhLmNhbGwob3B0aW9ucywgZGF0YXNldCxxdWVyeSk7XHJcblxyXG5cdFx0XHRcdCRpbnB1dC50cmlnZ2VyKCd1cGRhdGVDb250ZW50Lnhkc29mdCcpO1xyXG5cclxuXHRcdFx0XHRpZiAob3B0aW9ucy5zaG93SGludCAmJiBjdXJyZW50VmFsdWUubGVuZ3RoICYmIGN1cnJlbnRWYWx1ZS5sZW5ndGg8PSRpbnB1dC5wcm9wKCdzaXplJykgJiYgKHJpZ2h0ID0gZmluZFJpZ2h0LmNhbGwob3B0aW9ucyxkYXRhc2V0LGN1cnJlbnRWYWx1ZSkpKSB7XHJcblx0XHRcdFx0XHR2YXIgdGl0bGUgXHQ9ICBfX3NhZmUuY2FsbChvcHRpb25zLCdnZXRUaXRsZScscmlnaHQuc291cmNlLFtyaWdodC5yaWdodCxyaWdodC5zb3VyY2VdKTtcclxuXHRcdFx0XHRcdHRpdGxlID0gcXVlcnkgKyB0aXRsZS5zdWJzdHIocXVlcnkubGVuZ3RoKTtcclxuXHRcdFx0XHRcdCRoaW50LnZhbCh0aXRsZSk7XHJcblx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdCRoaW50LnZhbCgnJyk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9KTtcclxuXHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHJcblx0XHRmdW5jdGlvbiBtYW5hZ2VLZXkgKGV2ZW50KSB7XHJcblx0XHRcdHZhciBrZXkgPSBldmVudC5rZXlDb2RlLCByaWdodDtcclxuXHRcdFx0XHJcblx0XHRcdHN3aXRjaCgga2V5ICl7XHJcblx0XHRcdFx0Y2FzZSBBS0VZOiBjYXNlIENLRVk6IGNhc2UgVktFWTogY2FzZSBaS0VZOiBjYXNlIFlLRVk6XHJcblx0XHRcdFx0XHRpZiAoZXZlbnQuc2hpZnRLZXkgfHwgZXZlbnQuY3RybEtleSkge1xyXG5cdFx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHRicmVhaztcclxuXHRcdFx0XHRjYXNlIFNISUZUS0VZOlx0XHJcblx0XHRcdFx0Y2FzZSBDVFJMS0VZOlxyXG5cdFx0XHRcdFx0cmV0dXJuIHRydWU7XHJcblx0XHRcdFx0YnJlYWs7XHJcblx0XHRcdFx0Y2FzZSBBUlJPV1JJR0hUOlx0XHJcblx0XHRcdFx0Y2FzZSBBUlJPV0xFRlQ6XHJcblx0XHRcdFx0XHRpZiAoY3RybERvd24gfHwgc2hpZnREb3duIHx8IGV2ZW50LnNoaWZ0S2V5IHx8IGV2ZW50LmN0cmxLZXkpIHtcclxuXHRcdFx0XHRcdFx0cmV0dXJuIHRydWU7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHR2YWx1ZSA9ICRpbnB1dC52YWwoKTtcclxuXHRcdFx0XHRcdHBvcyA9IGdldENhcmV0UG9zaXRpb24oJGlucHV0WzBdKTtcclxuXHRcdFx0XHRcdGlmIChrZXkgPT09IEFSUk9XUklHSFQgJiYgcG9zID09PSB2YWx1ZS5sZW5ndGgpIHtcclxuXHRcdFx0XHRcdFx0aWYgKHJpZ2h0ID0gZmluZFJpZ2h0LmNhbGwob3B0aW9ucywgZGF0YXNldCwgdmFsdWUpKXtcclxuXHRcdFx0XHRcdFx0XHQkaW5wdXQudHJpZ2dlcigncGljay54ZHNvZnQnLCBbXHJcblx0XHRcdFx0XHRcdFx0XHRfX3NhZmUuY2FsbChvcHRpb25zLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHQnZ2V0VmFsdWUnLCByaWdodC5zb3VyY2UsXHJcblx0XHRcdFx0XHRcdFx0XHRcdFtyaWdodC5yaWdodCwgcmlnaHQuc291cmNlXVxyXG5cdFx0XHRcdFx0XHRcdFx0KVxyXG5cdFx0XHRcdFx0XHRcdF0pO1xyXG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0XHRcdCRpbnB1dC50cmlnZ2VyKCdwaWNrLnhkc29mdCcpO1xyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcblx0XHRcdFx0XHRcdHJldHVybiBmYWxzZTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdHJldHVybiB0cnVlO1xyXG5cdFx0XHRcdGNhc2UgVEFCOlxyXG5cdFx0XHRcdHJldHVybiB0cnVlO1xyXG5cdFx0XHRcdGNhc2UgRU5URVI6XHJcblx0XHRcdFx0XHRpZiAoaU9wZW4pIHtcclxuXHRcdFx0XHRcdFx0JGlucHV0LnRyaWdnZXIoJ3BpY2sueGRzb2Z0Jyk7XHJcblx0XHRcdFx0XHRcdGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcblx0XHRcdFx0XHRcdHJldHVybiBmYWxzZTtcclxuXHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdHJldHVybiB0cnVlO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdGJyZWFrO1xyXG5cdFx0XHRcdGNhc2UgRVNDOlxyXG5cdFx0XHRcdFx0JGlucHV0XHJcblx0XHRcdFx0XHRcdC52YWwoY3VycmVudFZhbHVlKVxyXG5cdFx0XHRcdFx0XHQudHJpZ2dlcignY2xvc2UueGRzb2Z0Jyk7XHJcblx0XHRcdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0XHRcdGNhc2UgQVJST1dET1dOOlxyXG5cdFx0XHRcdGNhc2UgQVJST1dVUDpcclxuXHRcdFx0XHRcdGlmICghaU9wZW4pIHtcclxuXHRcdFx0XHRcdFx0JGlucHV0LnRyaWdnZXIoJ29wZW4ueGRzb2Z0Jyk7XHJcblx0XHRcdFx0XHRcdCRpbnB1dC50cmlnZ2VyKCd1cGRhdGVDb250ZW50Lnhkc29mdCcpO1xyXG5cdFx0XHRcdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cdFx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcclxuXHRcdFx0XHRcdGFjdGl2ZSA9ICRkcm9wZG93bi5maW5kKCdkaXYuYWN0aXZlJyk7XHJcblx0XHRcdFx0XHRcclxuXHRcdFx0XHRcdHZhciBuZXh0ID0ga2V5PT1BUlJPV0RPV04/J25leHQnOidwcmV2JywgdGltZXBpY2sgPSB0cnVlO1xyXG5cdFx0XHRcdFx0XHJcblx0XHRcdFx0XHRpZiggYWN0aXZlLmxlbmd0aCApe1xyXG5cdFx0XHRcdFx0XHRhY3RpdmUucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xyXG5cdFx0XHRcdFx0XHRpZiggYWN0aXZlW25leHRdKCkubGVuZ3RoICl7XHJcblx0XHRcdFx0XHRcdFx0YWN0aXZlW25leHRdKCkuYWRkQ2xhc3MoJ2FjdGl2ZScpO1xyXG5cdFx0XHRcdFx0XHR9ZWxzZXtcclxuXHRcdFx0XHRcdFx0XHQkaW5wdXQudmFsKGN1cnJlbnRWYWx1ZSk7XHJcblx0XHRcdFx0XHRcdFx0dGltZXBpY2sgPSBmYWxzZTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0fWVsc2V7XHJcblx0XHRcdFx0XHRcdCRkcm9wZG93bi5jaGlsZHJlbigpLmVxKGtleT09QVJST1dET1dOPzA6LTEpLmFkZENsYXNzKCdhY3RpdmUnKTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFxyXG5cdFx0XHRcdFx0aWYoIHRpbWVwaWNrICl7XHJcblx0XHRcdFx0XHRcdCRpbnB1dC50cmlnZ2VyKCd0aW1lcGljay54ZHNvZnQnKTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFxyXG5cdFx0XHRcdFx0JGRyb3Bkb3duXHJcblx0XHRcdFx0XHRcdC50cmlnZ2VyKCd1cGRhdGVzY3JvbGwueGRzb2Z0Jyk7XHJcblx0XHRcdFx0XHRcclxuXHRcdFx0XHRcdGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcblx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XHRcclxuXHRcdFx0fVxyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblx0XHRcclxuXHRcdCRpbnB1dFxyXG5cdFx0XHQuZGF0YSgneGRzb2Z0X2F1dG9jb21wbGV0ZScsZGF0YXNldClcclxuXHRcdFx0LmFmdGVyKCRib3gpXHJcblx0XHRcdC5vbigncGljay54ZHNvZnQnLCBmdW5jdGlvbiggZXZlbnQsX3ZhbHVlICl7XHJcblxyXG5cdFx0XHRcdCRpbnB1dC50cmlnZ2VyKCd0aW1lcGljay54ZHNvZnQnLF92YWx1ZSk7XHJcblx0XHRcdFx0XHJcblx0XHRcdFx0Y3VycmVudFNlbGVjdCA9IGN1cnJlbnRWYWx1ZSA9ICRpbnB1dC52YWwoKTtcclxuXHRcdFx0XHRcclxuXHRcdFx0XHQkaW5wdXQudHJpZ2dlcignY2xvc2UueGRzb2Z0Jyk7XHJcblx0XHRcdFx0XHJcblx0XHRcdFx0Ly9jdXJyZW50SW5wdXQgPSBmYWxzZTtcclxuXHRcdFx0XHRcclxuXHRcdFx0XHRhY3RpdmUgPSAkZHJvcGRvd24uZmluZCgnZGl2LmFjdGl2ZScpLmVxKDApO1xyXG5cdFx0XHRcdFx0XHRcdFxyXG5cdFx0XHRcdGlmKCAhYWN0aXZlLmxlbmd0aCApXHJcblx0XHRcdFx0XHRhY3RpdmUgPSAkZHJvcGRvd24uY2hpbGRyZW4oKS5maXJzdCgpO1xyXG5cdFx0XHRcdFx0XHJcblx0XHRcdFx0JGlucHV0LnRyaWdnZXIoJ3NlbGVjdGVkLnhkc29mdCcsW2dldEl0ZW0oYWN0aXZlLGRhdGFzZXQpXSk7XHJcblx0XHRcdFx0XHJcblx0XHRcdFx0aWYgKG9wdGlvbnMuYWZ0ZXJTZWxlY3RlZClcclxuXHRcdFx0XHRcdG9wdGlvbnMuYWZ0ZXJTZWxlY3RlZCgpO1xyXG5cdFx0XHR9KVxyXG5cdFx0XHQub24oJ3RpbWVwaWNrLnhkc29mdCcsIGZ1bmN0aW9uKCBldmVudCxfdmFsdWUgKXtcclxuXHRcdFx0XHRhY3RpdmUgPSAkZHJvcGRvd24uZmluZCgnZGl2LmFjdGl2ZScpO1xyXG5cdFx0XHRcdFx0XHRcdFxyXG5cdFx0XHRcdGlmKCAhYWN0aXZlLmxlbmd0aCApXHJcblx0XHRcdFx0XHRhY3RpdmUgPSAkZHJvcGRvd24uY2hpbGRyZW4oKS5maXJzdCgpO1xyXG5cdFx0XHRcdFxyXG5cdFx0XHRcdGlmKCBhY3RpdmUubGVuZ3RoICl7XHJcblx0XHRcdFx0XHRpZiggIWlzc2V0KF92YWx1ZSkgKXtcclxuXHRcdFx0XHRcdFx0JGlucHV0LnZhbChnZXRWYWx1ZS5jYWxsKG9wdGlvbnMsYWN0aXZlLGRhdGFzZXQpKTtcclxuXHRcdFx0XHRcdH1lbHNle1xyXG5cdFx0XHRcdFx0XHQkaW5wdXQudmFsKF92YWx1ZSk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHQkaW5wdXQudHJpZ2dlcignYXV0b2NvbXBsZXRlZC54ZHNvZnQnLFtnZXRJdGVtKGFjdGl2ZSxkYXRhc2V0KV0pO1xyXG5cdFx0XHRcdFx0JGhpbnQudmFsKCcnKTtcclxuXHRcdFx0XHRcdHNldENhcmV0UG9zaXRpb24oJGlucHV0WzBdLCRpbnB1dC52YWwoKS5sZW5ndGgpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSlcclxuXHRcdFx0Lm9uKCdrZXlkb3duLnhkc29mdCBpbnB1dC54ZHNvZnQgY3V0Lnhkc29mdCBwYXN0ZS54ZHNvZnQnLCBmdW5jdGlvbiggZXZlbnQgKXtcclxuXHRcdFx0XHR2YXIgcmV0ID0gbWFuYWdlS2V5KGV2ZW50KTtcclxuXHRcdFx0XHRcclxuXHRcdFx0XHRpZiAocmV0ID09PSBmYWxzZSB8fCByZXQgPT09IHRydWUpIHtcclxuXHRcdFx0XHRcdHJldHVybiByZXQ7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdFxyXG5cdFx0XHRcdHNldFRpbWVvdXQoZnVuY3Rpb24oKXtcclxuXHRcdFx0XHRcdG1hbmFnZURhdGEoKTtcclxuXHRcdFx0XHR9LDEpO1xyXG5cdFx0XHRcdFxyXG5cdFx0XHRcdG1hbmFnZURhdGEoKTtcclxuXHRcdFx0fSlcclxuXHRcdFx0Lm9uKCdjaGFuZ2UueGRzb2Z0JywgZnVuY3Rpb24oIGV2ZW50ICl7XHJcblx0XHRcdFx0Y3VycmVudFZhbHVlID0gJGlucHV0LnZhbCgpO1xyXG5cdFx0XHR9KTtcclxuXHRcdFxyXG5cdFx0Y3VycmVudFZhbHVlID0gJGlucHV0LnZhbCgpO1xyXG5cdFx0XHJcblx0XHRjb2xsZWN0RGF0YS5jYWxsKG9wdGlvbnMsICRpbnB1dC52YWwoKSxkYXRhc2V0LGZ1bmN0aW9uKCBxdWVyeSApe1xyXG5cdFx0XHRwcm9jZXNzRGF0YS5jYWxsKG9wdGlvbnMsZGF0YXNldCxxdWVyeSk7XHJcblx0XHR9KTtcclxuXHRcdFxyXG5cdFx0aWYoIG9wdGlvbnMub3Blbk9uRm9jdXMgKXtcclxuXHRcdFx0JGlucHV0Lm9uKCdmb2N1c2luLnhkc29mdCcsZnVuY3Rpb24oKXtcclxuXHRcdFx0XHQkaW5wdXQudHJpZ2dlcignb3Blbi54ZHNvZnQnKTtcclxuXHRcdFx0XHQkaW5wdXQudHJpZ2dlcigndXBkYXRlQ29udGVudC54ZHNvZnQnKTtcclxuXHRcdFx0fSk7XHJcblx0XHR9XHJcblx0XHRcclxuXHRcdGlmKCBvcHRpb25zLmNsb3NlT25CbHVyIClcclxuXHRcdFx0JGlucHV0Lm9uKCdmb2N1c291dC54ZHNvZnQnLGZ1bmN0aW9uKCl7XHJcblx0XHRcdFx0JGlucHV0LnRyaWdnZXIoJ2Nsb3NlLnhkc29mdCcpO1xyXG5cdFx0XHR9KTtcclxuXHRcdFx0XHJcblx0XHQkYm94XHJcblx0XHRcdC5hcHBlbmQoJGlucHV0KVxyXG5cdFx0XHQuYXBwZW5kKCRkcm9wZG93bik7XHJcblxyXG5cclxuXHRcdHZhciBvbGRlckJhY2tncm91bmQgPSBmYWxzZSxcclxuXHRcdFx0dGltZXJVcGRhdGUgPSAwO1xyXG5cdFx0XHJcblx0XHQkaW5wdXRcclxuXHRcdFx0Lm9uKCd1cGRhdGVIZWxwZXJQb3NpdGlvbi54ZHNvZnQnLGZ1bmN0aW9uKCl7XHJcblx0XHRcdFx0Y2xlYXJUaW1lb3V0KHRpbWVyVXBkYXRlKTtcclxuXHRcdFx0XHR0aW1lclVwZGF0ZSA9IHNldFRpbWVvdXQoZnVuY3Rpb24oKXtcclxuXHRcdFx0XHRcdCRib3guY3NzKHtcclxuXHRcdFx0XHRcdFx0J2Rpc3BsYXknOiRpbnB1dC5jc3MoJ2Rpc3BsYXknKSxcclxuXHRcdFx0XHRcdFx0J3dpZHRoJzokaW5wdXQuY3NzKCd3aWR0aCcpXHJcblx0XHRcdFx0XHR9KTtcclxuXHRcdFx0XHRcdCRkcm9wZG93bi5jc3MoJC5leHRlbmQodHJ1ZSx7XHJcblx0XHRcdFx0XHRcdGxlZnQ6JGlucHV0LnBvc2l0aW9uKCkubGVmdCxcclxuXHRcdFx0XHRcdFx0dG9wOiRpbnB1dC5wb3NpdGlvbigpLnRvcCArIHBhcnNlSW50KCRpbnB1dC5jc3MoJ21hcmdpblRvcCcpKStwYXJzZUludCgkaW5wdXRbMF0ub2Zmc2V0SGVpZ2h0KSxcclxuXHRcdFx0XHRcdFx0bWFyZ2luTGVmdDokaW5wdXQuY3NzKCdtYXJnaW5MZWZ0JyksXHJcblx0XHRcdFx0XHRcdG1hcmdpblJpZ2h0OiRpbnB1dC5jc3MoJ21hcmdpblJpZ2h0JyksXHJcblx0XHRcdFx0XHRcdHdpZHRoOm9wdGlvbnMuZHJvcGRvd25XaWR0aD09JzEwMCUnPyRpbnB1dFswXS5vZmZzZXRXaWR0aDpvcHRpb25zLmRyb3Bkb3duV2lkdGhcclxuXHRcdFx0XHRcdH0sb3B0aW9ucy5kcm9wZG93blN0eWxlKSk7XHJcblx0XHRcdFx0XHRcclxuXHRcdFx0XHRcdGlmIChvcHRpb25zLnNob3dIaW50KSB7XHJcblx0XHRcdFx0XHRcdHZhciBzdHlsZSA9IGdldENvbXB1dGVkU3R5bGUoJGlucHV0WzBdLCBcIlwiKTtcclxuXHRcdFx0XHRcdFx0XHJcblx0XHRcdFx0XHRcdCRoaW50WzBdLnN0eWxlLmNzc1RleHQgPSBzdHlsZS5jc3NUZXh0O1xyXG5cdFx0XHRcdFx0XHRcclxuXHRcdFx0XHRcdFx0JGhpbnQuY3NzKHtcclxuXHRcdFx0XHRcdFx0XHQnYm94LXNpemluZyc6c3R5bGUuYm94U2l6aW5nLFxyXG5cdFx0XHRcdFx0XHRcdGJvcmRlclN0eWxlOidzb2xpZCcsXHJcblx0XHRcdFx0XHRcdFx0Ym9yZGVyQ29sbGFwc2U6c3R5bGUuYm9yZGVyQ29sbGFwc2UsXHJcblx0XHRcdFx0XHRcdFx0Ym9yZGVyTGVmdFdpZHRoOnN0eWxlLmJvcmRlckxlZnRXaWR0aCxcclxuXHRcdFx0XHRcdFx0XHRib3JkZXJSaWdodFdpZHRoOnN0eWxlLmJvcmRlclJpZ2h0V2lkdGgsXHJcblx0XHRcdFx0XHRcdFx0Ym9yZGVyVG9wV2lkdGg6c3R5bGUuYm9yZGVyVG9wV2lkdGgsXHJcblx0XHRcdFx0XHRcdFx0Ym9yZGVyQm90dG9tV2lkdGg6c3R5bGUuYm9yZGVyQm90dG9tV2lkdGgsXHJcblx0XHRcdFx0XHRcdFx0cGFkZGluZ0JvdHRvbTpzdHlsZS5wYWRkaW5nQm90dG9tLFxyXG5cdFx0XHRcdFx0XHRcdG1hcmdpbkJvdHRvbTpzdHlsZS5tYXJnaW5Cb3R0b20sXHJcblx0XHRcdFx0XHRcdFx0cGFkZGluZ1RvcDpzdHlsZS5wYWRkaW5nVG9wLFxyXG5cdFx0XHRcdFx0XHRcdG1hcmdpblRvcDpzdHlsZS5tYXJnaW5Ub3AsXHJcblx0XHRcdFx0XHRcdFx0cGFkZGluZ0xlZnQ6c3R5bGUucGFkZGluZ0xlZnQsXHJcblx0XHRcdFx0XHRcdFx0bWFyZ2luTGVmdDpzdHlsZS5tYXJnaW5MZWZ0LFxyXG5cdFx0XHRcdFx0XHRcdHBhZGRpbmdSaWdodDpzdHlsZS5wYWRkaW5nUmlnaHQsXHJcblx0XHRcdFx0XHRcdFx0bWFyZ2luUmlnaHQ6c3R5bGUubWFyZ2luUmlnaHQsXHJcblx0XHRcdFx0XHRcdFx0bWF4SGVpZ2h0OnN0eWxlLm1heEhlaWdodCxcclxuXHRcdFx0XHRcdFx0XHRtaW5IZWlnaHQ6c3R5bGUubWluSGVpZ2h0LFxyXG5cdFx0XHRcdFx0XHRcdG1heFdpZHRoOnN0eWxlLm1heFdpZHRoLFxyXG5cdFx0XHRcdFx0XHRcdG1pbldpZHRoOnN0eWxlLm1pbldpZHRoLFxyXG5cdFx0XHRcdFx0XHRcdHdpZHRoOnN0eWxlLndpZHRoLFxyXG5cdFx0XHRcdFx0XHRcdGxldHRlclNwYWNpbmc6c3R5bGUubGV0dGVyU3BhY2luZyxcclxuXHRcdFx0XHRcdFx0XHRsaW5lSGVpZ2h0OnN0eWxlLmxpbmVIZWlnaHQsXHJcblx0XHRcdFx0XHRcdFx0b3V0bGluZVdpZHRoOnN0eWxlLm91dGxpbmVXaWR0aCxcclxuXHRcdFx0XHRcdFx0XHRmb250RmFtaWx5OnN0eWxlLmZvbnRGYW1pbHksXHJcblx0XHRcdFx0XHRcdFx0Zm9udFZhcmlhbnQ6c3R5bGUuZm9udFZhcmlhbnQsXHJcblx0XHRcdFx0XHRcdFx0Zm9udFN0eWxlOiRpbnB1dC5jc3MoJ2ZvbnRTdHlsZScpLFxyXG5cdFx0XHRcdFx0XHRcdGZvbnRTaXplOiRpbnB1dC5jc3MoJ2ZvbnRTaXplJyksXHJcblx0XHRcdFx0XHRcdFx0Zm9udFdlaWdodDokaW5wdXQuY3NzKCdmb250V2VpZ2h0JyksXHJcblx0XHRcdFx0XHRcdFx0ZmxleDpzdHlsZS5mbGV4LFxyXG5cdFx0XHRcdFx0XHRcdGp1c3RpZnlDb250ZW50OnN0eWxlLmp1c3RpZnlDb250ZW50LFxyXG5cdFx0XHRcdFx0XHRcdGJvcmRlclJhZGl1czpzdHlsZS5ib3JkZXJSYWRpdXMsXHJcblx0XHRcdFx0XHRcdFx0Jy13ZWJraXQtYm94LXNoYWRvdyc6J25vbmUnLFxyXG5cdFx0XHRcdFx0XHRcdCdib3gtc2hhZG93Jzonbm9uZSdcclxuXHRcdFx0XHRcdFx0fSk7XHJcblx0XHRcdFx0XHRcdFxyXG5cdFx0XHRcdFx0XHQkaW5wdXQuY3NzKCdmb250LXNpemUnLCRpbnB1dC5jc3MoJ2ZvbnRTaXplJykpLy8gZml4IGJ1ZyB3aXRoIGVtIGZvbnQgc2l6ZVxyXG5cdFx0XHRcdFx0XHRcclxuXHRcdFx0XHRcdFx0JGhpbnQuaW5uZXJIZWlnaHQoJGlucHV0LmlubmVySGVpZ2h0KCkpO1xyXG5cdFx0XHRcdFx0XHRcclxuXHRcdFx0XHRcdFx0JGhpbnQuY3NzKCQuZXh0ZW5kKHRydWUse1xyXG5cdFx0XHRcdFx0XHRcdHBvc2l0aW9uOidhYnNvbHV0ZScsXHJcblx0XHRcdFx0XHRcdFx0ekluZGV4OicxJyxcclxuXHRcdFx0XHRcdFx0XHRib3JkZXJDb2xvcjondHJhbnNwYXJlbnQnLFxyXG5cdFx0XHRcdFx0XHRcdG91dGxpbmVDb2xvcjondHJhbnNwYXJlbnQnLFxyXG5cdFx0XHRcdFx0XHRcdGxlZnQ6JGlucHV0LnBvc2l0aW9uKCkubGVmdCxcclxuXHRcdFx0XHRcdFx0XHR0b3A6JGlucHV0LnBvc2l0aW9uKCkudG9wLFxyXG5cdFx0XHRcdFx0XHRcdGJhY2tncm91bmQ6JGlucHV0LmNzcygnYmFja2dyb3VuZCcpXHJcblx0XHRcdFx0XHRcdH0sb3B0aW9ucy5oaW50U3R5bGUpKTtcclxuXHRcdFx0XHRcdFx0XHJcblx0XHRcdFx0XHRcdFxyXG5cdFx0XHRcdFx0XHRpZiggb2xkZXJCYWNrZ3JvdW5kIT09ZmFsc2UgKXtcclxuXHRcdFx0XHRcdFx0XHQkaGludC5jc3MoJ2JhY2tncm91bmQnLG9sZGVyQmFja2dyb3VuZCk7XHJcblx0XHRcdFx0XHRcdH1lbHNle1xyXG5cdFx0XHRcdFx0XHRcdG9sZGVyQmFja2dyb3VuZCA9ICRpbnB1dC5jc3MoJ2JhY2tncm91bmQnKTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcclxuXHRcdFx0XHRcdFx0dHJ5e1xyXG5cdFx0XHRcdFx0XHRcdCRpbnB1dFswXS5zdHlsZS5zZXRQcm9wZXJ0eSgnYmFja2dyb3VuZCcsICd0cmFuc3BhcmVudCcsICdpbXBvcnRhbnQnKTtcclxuXHRcdFx0XHRcdFx0fSBjYXRjaChlKSB7XHJcblx0XHRcdFx0XHRcdFx0JGlucHV0LmNzcygnYmFja2dyb3VuZCcsJ3RyYW5zcGFyZW50JylcclxuXHRcdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRcdFx0JGJveFxyXG5cdFx0XHRcdFx0XHRcdC5hcHBlbmQoJGhpbnQpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH0sIG9wdGlvbnMudGltZW91dFVwZGF0ZXx8MSk7XHJcblx0XHRcdH0pO1xyXG5cdFx0XHJcblx0XHRpZiAoJGlucHV0LmlzKCc6dmlzaWJsZScpKSB7XHJcblx0XHRcdCRpbnB1dFxyXG5cdFx0XHRcdC50cmlnZ2VyKCd1cGRhdGVIZWxwZXJQb3NpdGlvbi54ZHNvZnQnKTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdGludGVydmFsRm9yVmlzaWJpbGl0eSA9IHNldEludGVydmFsKGZ1bmN0aW9uICgpIHtcclxuXHRcdFx0XHRpZiAoJGlucHV0LmlzKCc6dmlzaWJsZScpKSB7XHJcblx0XHRcdFx0XHQkaW5wdXRcclxuXHRcdFx0XHRcdFx0LnRyaWdnZXIoJ3VwZGF0ZUhlbHBlclBvc2l0aW9uLnhkc29mdCcpO1xyXG5cdFx0XHRcdFx0Y2xlYXJJbnRlcnZhbChpbnRlcnZhbEZvclZpc2liaWxpdHkpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSwxMDApO1xyXG5cdFx0fVxyXG5cdFx0XHJcblx0XHQkKHdpbmRvdykub24oJ3Jlc2l6ZScsZnVuY3Rpb24gKCkge1xyXG5cdFx0XHQkYm94LmNzcyh7XHJcblx0XHRcdFx0J3dpZHRoJzonYXV0bydcclxuXHRcdFx0fSk7XHJcblx0XHRcdCRpbnB1dFxyXG5cdFx0XHRcdC50cmlnZ2VyKCd1cGRhdGVIZWxwZXJQb3NpdGlvbi54ZHNvZnQnKTtcclxuXHRcdH0pXHJcblx0XHRcclxuXHRcdCRpbnB1dFx0XHJcblx0XHRcdC5vbignY2xvc2UueGRzb2Z0JyxmdW5jdGlvbigpe1xyXG5cdFx0XHRcdGlmICghaU9wZW4pIHtcclxuXHRcdFx0XHRcdHJldHVybjtcclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdCRkcm9wZG93blxyXG5cdFx0XHRcdFx0LmhpZGUoKTtcclxuXHJcblx0XHRcdFx0JGhpbnRcclxuXHRcdFx0XHRcdC52YWwoJycpO1x0XHJcblxyXG5cdFx0XHRcdGlmICghb3B0aW9ucy5hdXRvc2VsZWN0KSB7XHJcblx0XHRcdFx0XHQkaW5wdXQudmFsKGN1cnJlbnRWYWx1ZSk7XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRpT3BlbiA9IGZhbHNlO1xyXG5cclxuXHRcdFx0XHQvL2N1cnJlbnRJbnB1dCA9IGZhbHNlO1xyXG5cdFx0XHR9KVxyXG5cdFx0XHRcclxuXHRcdFx0Lm9uKCd1cGRhdGVDb250ZW50Lnhkc29mdCcsZnVuY3Rpb24oKXtcclxuXHRcdFx0XHR2YXIgb3V0ID0gcmVuZGVyRGF0YS5jYWxsKG9wdGlvbnMsZGF0YXNldCwkaW5wdXQudmFsKCkpLFxyXG5cdFx0XHRcdFx0aGdodCA9IDEwO1xyXG5cdFx0XHRcdFxyXG5cdFx0XHRcdGlmIChvdXQubGVuZ3RoKSB7XHJcblx0XHRcdFx0XHQkaW5wdXQudHJpZ2dlcignb3Blbi54ZHNvZnQnKTtcclxuXHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0JGlucHV0LnRyaWdnZXIoJ2Nsb3NlLnhkc29mdCcpO1xyXG5cdFx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0JChvdXQpLmVhY2goZnVuY3Rpb24oKXtcclxuXHRcdFx0XHRcdHRoaXMuY3NzKCQuZXh0ZW5kKHRydWUse1xyXG5cdFx0XHRcdFx0XHRwYWRkaW5nTGVmdDokaW5wdXQuY3NzKCdwYWRkaW5nTGVmdCcpLFxyXG5cdFx0XHRcdFx0XHRwYWRkaW5nUmlnaHQ6JGlucHV0LmNzcygncGFkZGluZ1JpZ2h0JylcclxuXHRcdFx0XHRcdH0sb3B0aW9ucy5pdGVtU3R5bGUpKTtcclxuXHRcdFx0XHR9KTtcclxuXHJcblx0XHRcdFx0JGRyb3Bkb3duXHJcblx0XHRcdFx0XHQuaHRtbChvdXQpO1xyXG5cdFx0XHRcdFx0XHJcblx0XHRcdFx0aWYgKG9wdGlvbnMudmlzaWJsZUhlaWdodCl7XHJcblx0XHRcdFx0XHRoZ2h0ID0gb3B0aW9ucy52aXNpYmxlSGVpZ2h0O1xyXG5cdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRoZ2h0ID0gb3B0aW9ucy52aXNpYmxlTGltaXQgKiAoKG91dFswXSA/IG91dFswXS5vdXRlckhlaWdodCh0cnVlKSA6IDApIHx8IG9wdGlvbnMuZGVmYXVsdEhlaWdodEl0ZW0pICsgNTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0XHJcblx0XHRcdFx0JGRyb3Bkb3duXHJcblx0XHRcdFx0XHQuY3NzKCdtYXhIZWlnaHQnLCBoZ2h0KydweCcpXHJcblx0XHRcdH0pXHJcblx0XHRcdFxyXG5cdFx0XHQub24oJ29wZW4ueGRzb2Z0JyxmdW5jdGlvbigpe1xyXG5cdFx0XHRcdGlmKCBpT3BlbiApXHJcblx0XHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdFx0XHJcblx0XHRcdFx0JGRyb3Bkb3duXHJcblx0XHRcdFx0XHQuc2hvdygpO1xyXG5cclxuXHRcdFx0XHRpT3BlbiA9IHRydWU7XHJcblx0XHRcdFx0XHRcclxuXHRcdFx0XHQvL2N1cnJlbnRJbnB1dCA9ICRpbnB1dDtcclxuXHRcdFx0fSlcclxuXHRcdFx0Lm9uKCdkZXN0cm95Lnhkc29mdCcsZnVuY3Rpb24oKXtcclxuXHRcdFx0XHQkaW5wdXQucmVtb3ZlQ2xhc3MoJ3hkc29mdCcpO1xyXG5cdFx0XHRcdCRib3guYWZ0ZXIoJGlucHV0KTtcclxuXHRcdFx0XHQkYm94LnJlbW92ZSgpO1xyXG5cdFx0XHRcdGNsZWFyVGltZW91dCh0aW1lcjEpO1xyXG5cdFx0XHRcdGNsZWFyVGltZW91dChpbnRlcnZhbEZvclZpc2liaWxpdHkpO1xyXG5cdFx0XHRcdC8vY3VycmVudElucHV0ID0gZmFsc2U7XHJcblx0XHRcdFx0JGlucHV0LmRhdGEoJ3hkc29mdF9hdXRvY29tcGxldGUnLG51bGwpO1xyXG5cdFx0XHRcdCRpbnB1dFxyXG5cdFx0XHRcdFx0Lm9mZignLnhkc29mdCcpXHJcblx0XHRcdH0pO1xyXG5cdH07XHJcblx0XHJcblx0cHVibGljcyA9IHtcclxuXHRcdGRlc3Ryb3k6IGZ1bmN0aW9uICgpIHtcclxuXHRcdFx0cmV0dXJuIHRoaXMudHJpZ2dlcignZGVzdHJveS54ZHNvZnQnKTtcclxuXHRcdH0sXHJcblx0XHR1cGRhdGU6IGZ1bmN0aW9uICgpIHtcclxuXHRcdFx0cmV0dXJuIHRoaXMudHJpZ2dlcigndXBkYXRlSGVscGVyUG9zaXRpb24ueGRzb2Z0Jyk7XHRcclxuXHRcdH0sXHJcblx0XHRvcHRpb25zOiBmdW5jdGlvbiAoX29wdGlvbnMpIHtcclxuXHRcdFx0aWYgKHRoaXMuZGF0YSgnYXV0b2NvbXBsZXRlX29wdGlvbnMnKSAmJiAkLmlzUGxhaW5PYmplY3QoX29wdGlvbnMpKSB7XHJcblx0XHRcdFx0dGhpcy5kYXRhKCdhdXRvY29tcGxldGVfb3B0aW9ucycsICQuZXh0ZW5kKHRydWUsIHRoaXMuZGF0YSgnYXV0b2NvbXBsZXRlX29wdGlvbnMnKSwgX29wdGlvbnMpKTtcclxuXHRcdFx0fVxyXG5cdFx0XHRyZXR1cm4gdGhpcztcclxuXHRcdH0sXHJcblx0XHRzZXRTb3VyY2U6IGZ1bmN0aW9uIChfbmV3c291cmNlLCBpZCkge1xyXG5cdFx0XHRpZih0aGlzLmRhdGEoJ2F1dG9jb21wbGV0ZV9vcHRpb25zJykgJiYgKCQuaXNQbGFpbk9iamVjdChfbmV3c291cmNlKSB8fCAkLmlzRnVuY3Rpb24oX25ld3NvdXJjZSkgfHwgJC5pc0FycmF5KF9uZXdzb3VyY2UpKSkge1xyXG5cdFx0XHRcdHZhciBvcHRpb25zID0gdGhpcy5kYXRhKCdhdXRvY29tcGxldGVfb3B0aW9ucycpLCBcclxuXHRcdFx0XHRcdGRhdGFzZXQgPSB0aGlzLmRhdGEoJ3hkc29mdF9hdXRvY29tcGxldGUnKSxcclxuXHRcdFx0XHRcdHNvdXJjZSBcdD0gb3B0aW9ucy5zb3VyY2U7XHJcblx0XHRcdFx0aWYgKGlkIT09dW5kZWZpbmVkICYmICFpc05hTihpZCkpIHtcclxuXHRcdFx0XHRcdGlmICgkLmlzUGxhaW5PYmplY3QoX25ld3NvdXJjZSkgfHwgJC5pc0FycmF5KF9uZXdzb3VyY2UpKSB7XHJcblx0XHRcdFx0XHRcdHNvdXJjZVtpZF0gPSAgJC5leHRlbmQodHJ1ZSwkLmlzQXJyYXkoX25ld3NvdXJjZSkgPyBbXSA6IHt9LCBfbmV3c291cmNlKTtcclxuXHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdHNvdXJjZVtpZF0gPSAgX25ld3NvdXJjZTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0aWYgKCQuaXNGdW5jdGlvbihfbmV3c291cmNlKSkge1xyXG5cdFx0XHRcdFx0XHR0aGlzLmRhdGEoJ2F1dG9jb21wbGV0ZV9vcHRpb25zJykuc291cmNlID0gX25ld3NvdXJjZTtcclxuXHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdCQuZXh0ZW5kKHRydWUsIHNvdXJjZSwgX25ld3NvdXJjZSk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdFxyXG5cdFx0XHRcdGNvbGxlY3REYXRhLmNhbGwob3B0aW9ucywgdGhpcy52YWwoKSwgZGF0YXNldCxmdW5jdGlvbiggcXVlcnkgKXtcclxuXHRcdFx0XHRcdHByb2Nlc3NEYXRhLmNhbGwob3B0aW9ucyxkYXRhc2V0LHF1ZXJ5KTtcclxuXHRcdFx0XHR9KTtcclxuXHRcdFx0fVxyXG5cdFx0XHRyZXR1cm4gdGhpcztcclxuXHRcdH0sXHJcblx0XHRnZXRTb3VyY2U6IGZ1bmN0aW9uIChpZCkge1xyXG5cdFx0XHRpZiAodGhpcy5kYXRhKCdhdXRvY29tcGxldGVfb3B0aW9ucycpKSB7XHJcblx0XHRcdFx0dmFyIHNvdXJjZSA9IHRoaXMuZGF0YSgnYXV0b2NvbXBsZXRlX29wdGlvbnMnKS5zb3VyY2U7XHJcblx0XHRcdFx0aWYgKGlkIT09dW5kZWZpbmVkICYmICFpc05hTihpZCkgJiZzb3VyY2VbaWRdKSB7XHJcblx0XHRcdFx0XHRyZXR1cm4gc291cmNlW2lkXTtcclxuXHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0cmV0dXJuIHNvdXJjZTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdFx0cmV0dXJuIG51bGw7XHJcblx0XHR9IFxyXG5cdH07XHJcblx0XHJcblx0JC5mbi5hdXRvY29tcGxldGUgPSBmdW5jdGlvbihfb3B0aW9ucywgX3NlY29uZCwgX3RoaXJkKXtcclxuXHRcdGlmICgkLnR5cGUoX29wdGlvbnMpID09PSAnc3RyaW5nJyAmJiBwdWJsaWNzW19vcHRpb25zXSkge1xyXG5cdFx0XHRyZXR1cm4gcHVibGljc1tfb3B0aW9uc10uY2FsbCh0aGlzLCBfc2Vjb25kLCBfdGhpcmQpO1xyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7XHJcblx0XHRcdHZhciBvcHRpb25zID0gJC5leHRlbmQodHJ1ZSwge30sIGRlZmF1bHRTZXR0aW5nLCBfb3B0aW9ucyk7XHJcblx0XHRcdGluaXQodGhpcywgb3B0aW9ucyk7XHJcblx0XHR9KTtcclxuXHR9O1xyXG59KGpRdWVyeSkpO1xyXG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/jquery-autocomplete/jquery.autocomplete.js\n");
/***/ }),
/***/ "./node_modules/jquery/dist/jquery.js":
/*!********************************************!*\
!*** ./node_modules/jquery/dist/jquery.js ***!
\********************************************/
/***/ (function(module, exports) {
eval("var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!\n * jQuery JavaScript Library v3.6.0\n * https://jquery.com/\n *\n * Includes Sizzle.js\n * https://sizzlejs.com/\n *\n * Copyright OpenJS Foundation and other contributors\n * Released under the MIT license\n * https://jquery.org/license\n *\n * Date: 2021-03-02T17:08Z\n */\n( function( global, factory ) {\n\n\t\"use strict\";\n\n\tif ( true && typeof module.exports === \"object\" ) {\n\n\t\t// For CommonJS and CommonJS-like environments where a proper `window`\n\t\t// is present, execute the factory and get jQuery.\n\t\t// For environments that do not have a `window` with a `document`\n\t\t// (such as Node.js), expose a factory as module.exports.\n\t\t// This accentuates the need for the creation of a real `window`.\n\t\t// e.g. var jQuery = require(\"jquery\")(window);\n\t\t// See ticket #14549 for more info.\n\t\tmodule.exports = global.document ?\n\t\t\tfactory( global, true ) :\n\t\t\tfunction( w ) {\n\t\t\t\tif ( !w.document ) {\n\t\t\t\t\tthrow new Error( \"jQuery requires a window with a document\" );\n\t\t\t\t}\n\t\t\t\treturn factory( w );\n\t\t\t};\n\t} else {\n\t\tfactory( global );\n\t}\n\n// Pass this if window is not defined yet\n} )( typeof window !== \"undefined\" ? window : this, function( window, noGlobal ) {\n\n// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1\n// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode\n// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common\n// enough that all such attempts are guarded in a try block.\n\"use strict\";\n\nvar arr = [];\n\nvar getProto = Object.getPrototypeOf;\n\nvar slice = arr.slice;\n\nvar flat = arr.flat ? function( array ) {\n\treturn arr.flat.call( array );\n} : function( array ) {\n\treturn arr.concat.apply( [], array );\n};\n\n\nvar push = arr.push;\n\nvar indexOf = arr.indexOf;\n\nvar class2type = {};\n\nvar toString = class2type.toString;\n\nvar hasOwn = class2type.hasOwnProperty;\n\nvar fnToString = hasOwn.toString;\n\nvar ObjectFunctionString = fnToString.call( Object );\n\nvar support = {};\n\nvar isFunction = function isFunction( obj ) {\n\n\t\t// Support: Chrome <=57, Firefox <=52\n\t\t// In some browsers, typeof returns \"function\" for HTML <object> elements\n\t\t// (i.e., `typeof document.createElement( \"object\" ) === \"function\"`).\n\t\t// We don't want to classify *any* DOM node as a function.\n\t\t// Support: QtWeb <=3.8.5, WebKit <=534.34, wkhtmltopdf tool <=0.12.5\n\t\t// Plus for old WebKit, typeof returns \"function\" for HTML collections\n\t\t// (e.g., `typeof document.getElementsByTagName(\"div\") === \"function\"`). (gh-4756)\n\t\treturn typeof obj === \"function\" && typeof obj.nodeType !== \"number\" &&\n\t\t\ttypeof obj.item !== \"function\";\n\t};\n\n\nvar isWindow = function isWindow( obj ) {\n\t\treturn obj != null && obj === obj.window;\n\t};\n\n\nvar document = window.document;\n\n\n\n\tvar preservedScriptAttributes = {\n\t\ttype: true,\n\t\tsrc: true,\n\t\tnonce: true,\n\t\tnoModule: true\n\t};\n\n\tfunction DOMEval( code, node, doc ) {\n\t\tdoc = doc || document;\n\n\t\tvar i, val,\n\t\t\tscript = doc.createElement( \"script\" );\n\n\t\tscript.text = code;\n\t\tif ( node ) {\n\t\t\tfor ( i in preservedScriptAttributes ) {\n\n\t\t\t\t// Support: Firefox 64+, Edge 18+\n\t\t\t\t// Some browsers don't support the \"nonce\" property on scripts.\n\t\t\t\t// On the other hand, just using `getAttribute` is not enough as\n\t\t\t\t// the `nonce` attribute is reset to an empty string whenever it\n\t\t\t\t// becomes browsing-context connected.\n\t\t\t\t// See https://github.com/whatwg/html/issues/2369\n\t\t\t\t// See https://html.spec.whatwg.org/#nonce-attributes\n\t\t\t\t// The `node.getAttribute` check was added for the sake of\n\t\t\t\t// `jQuery.globalEval` so that it can fake a nonce-containing node\n\t\t\t\t// via an object.\n\t\t\t\tval = node[ i ] || node.getAttribute && node.getAttribute( i );\n\t\t\t\tif ( val ) {\n\t\t\t\t\tscript.setAttribute( i, val );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tdoc.head.appendChild( script ).parentNode.removeChild( script );\n\t}\n\n\nfunction toType( obj ) {\n\tif ( obj == null ) {\n\t\treturn obj + \"\";\n\t}\n\n\t// Support: Android <=2.3 only (functionish RegExp)\n\treturn typeof obj === \"object\" || typeof obj === \"function\" ?\n\t\tclass2type[ toString.call( obj ) ] || \"object\" :\n\t\ttypeof obj;\n}\n/* global Symbol */\n// Defining this global in .eslintrc.json would create a danger of using the global\n// unguarded in another place, it seems safer to define global only for this module\n\n\n\nvar\n\tversion = \"3.6.0\",\n\n\t// Define a local copy of jQuery\n\tjQuery = function( selector, context ) {\n\n\t\t// The jQuery object is actually just the init constructor 'enhanced'\n\t\t// Need init if jQuery is called (just allow error to be thrown if not included)\n\t\treturn new jQuery.fn.init( selector, context );\n\t};\n\njQuery.fn = jQuery.prototype = {\n\n\t// The current version of jQuery being used\n\tjquery: version,\n\n\tconstructor: jQuery,\n\n\t// The default length of a jQuery object is 0\n\tlength: 0,\n\n\ttoArray: function() {\n\t\treturn slice.call( this );\n\t},\n\n\t// Get the Nth element in the matched element set OR\n\t// Get the whole matched element set as a clean array\n\tget: function( num ) {\n\n\t\t// Return all the elements in a clean array\n\t\tif ( num == null ) {\n\t\t\treturn slice.call( this );\n\t\t}\n\n\t\t// Return just the one element from the set\n\t\treturn num < 0 ? this[ num + this.length ] : this[ num ];\n\t},\n\n\t// Take an array of elements and push it onto the stack\n\t// (returning the new matched element set)\n\tpushStack: function( elems ) {\n\n\t\t// Build a new jQuery matched element set\n\t\tvar ret = jQuery.merge( this.constructor(), elems );\n\n\t\t// Add the old object onto the stack (as a reference)\n\t\tret.prevObject = this;\n\n\t\t// Return the newly-formed element set\n\t\treturn ret;\n\t},\n\n\t// Execute a callback for every element in the matched set.\n\teach: function( callback ) {\n\t\treturn jQuery.each( this, callback );\n\t},\n\n\tmap: function( callback ) {\n\t\treturn this.pushStack( jQuery.map( this, function( elem, i ) {\n\t\t\treturn callback.call( elem, i, elem );\n\t\t} ) );\n\t},\n\n\tslice: function() {\n\t\treturn this.pushStack( slice.apply( this, arguments ) );\n\t},\n\n\tfirst: function() {\n\t\treturn this.eq( 0 );\n\t},\n\n\tlast: function() {\n\t\treturn this.eq( -1 );\n\t},\n\n\teven: function() {\n\t\treturn this.pushStack( jQuery.grep( this, function( _elem, i ) {\n\t\t\treturn ( i + 1 ) % 2;\n\t\t} ) );\n\t},\n\n\todd: function() {\n\t\treturn this.pushStack( jQuery.grep( this, function( _elem, i ) {\n\t\t\treturn i % 2;\n\t\t} ) );\n\t},\n\n\teq: function( i ) {\n\t\tvar len = this.length,\n\t\t\tj = +i + ( i < 0 ? len : 0 );\n\t\treturn this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );\n\t},\n\n\tend: function() {\n\t\treturn this.prevObject || this.constructor();\n\t},\n\n\t// For internal use only.\n\t// Behaves like an Array's method, not like a jQuery method.\n\tpush: push,\n\tsort: arr.sort,\n\tsplice: arr.splice\n};\n\njQuery.extend = jQuery.fn.extend = function() {\n\tvar options, name, src, copy, copyIsArray, clone,\n\t\ttarget = arguments[ 0 ] || {},\n\t\ti = 1,\n\t\tlength = arguments.length,\n\t\tdeep = false;\n\n\t// Handle a deep copy situation\n\tif ( typeof target === \"boolean\" ) {\n\t\tdeep = target;\n\n\t\t// Skip the boolean and the target\n\t\ttarget = arguments[ i ] || {};\n\t\ti++;\n\t}\n\n\t// Handle case when target is a string or something (possible in deep copy)\n\tif ( typeof target !== \"object\" && !isFunction( target ) ) {\n\t\ttarget = {};\n\t}\n\n\t// Extend jQuery itself if only one argument is passed\n\tif ( i === length ) {\n\t\ttarget = this;\n\t\ti--;\n\t}\n\n\tfor ( ; i < length; i++ ) {\n\n\t\t// Only deal with non-null/undefined values\n\t\tif ( ( options = arguments[ i ] ) != null ) {\n\n\t\t\t// Extend the base object\n\t\t\tfor ( name in options ) {\n\t\t\t\tcopy = options[ name ];\n\n\t\t\t\t// Prevent Object.prototype pollution\n\t\t\t\t// Prevent never-ending loop\n\t\t\t\tif ( name === \"__proto__\" || target === copy ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Recurse if we're merging plain objects or arrays\n\t\t\t\tif ( deep && copy && ( jQuery.isPlainObject( copy ) ||\n\t\t\t\t\t( copyIsArray = Array.isArray( copy ) ) ) ) {\n\t\t\t\t\tsrc = target[ name ];\n\n\t\t\t\t\t// Ensure proper type for the source value\n\t\t\t\t\tif ( copyIsArray && !Array.isArray( src ) ) {\n\t\t\t\t\t\tclone = [];\n\t\t\t\t\t} else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) {\n\t\t\t\t\t\tclone = {};\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclone = src;\n\t\t\t\t\t}\n\t\t\t\t\tcopyIsArray = false;\n\n\t\t\t\t\t// Never move original objects, clone them\n\t\t\t\t\ttarget[ name ] = jQuery.extend( deep, clone, copy );\n\n\t\t\t\t// Don't bring in undefined values\n\t\t\t\t} else if ( copy !== undefined ) {\n\t\t\t\t\ttarget[ name ] = copy;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Return the modified object\n\treturn target;\n};\n\njQuery.extend( {\n\n\t// Unique for each copy of jQuery on the page\n\texpando: \"jQuery\" + ( version + Math.random() ).replace( /\\D/g, \"\" ),\n\n\t// Assume jQuery is ready without the ready module\n\tisReady: true,\n\n\terror: function( msg ) {\n\t\tthrow new Error( msg );\n\t},\n\n\tnoop: function() {},\n\n\tisPlainObject: function( obj ) {\n\t\tvar proto, Ctor;\n\n\t\t// Detect obvious negatives\n\t\t// Use toString instead of jQuery.type to catch host objects\n\t\tif ( !obj || toString.call( obj ) !== \"[object Object]\" ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tproto = getProto( obj );\n\n\t\t// Objects with no prototype (e.g., `Object.create( null )`) are plain\n\t\tif ( !proto ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Objects with prototype are plain iff they were constructed by a global Object function\n\t\tCtor = hasOwn.call( proto, \"constructor\" ) && proto.constructor;\n\t\treturn typeof Ctor === \"function\" && fnToString.call( Ctor ) === ObjectFunctionString;\n\t},\n\n\tisEmptyObject: function( obj ) {\n\t\tvar name;\n\n\t\tfor ( name in obj ) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t},\n\n\t// Evaluates a script in a provided context; falls back to the global one\n\t// if not specified.\n\tglobalEval: function( code, options, doc ) {\n\t\tDOMEval( code, { nonce: options && options.nonce }, doc );\n\t},\n\n\teach: function( obj, callback ) {\n\t\tvar length, i = 0;\n\n\t\tif ( isArrayLike( obj ) ) {\n\t\t\tlength = obj.length;\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tif ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tfor ( i in obj ) {\n\t\t\t\tif ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn obj;\n\t},\n\n\t// results is for internal usage only\n\tmakeArray: function( arr, results ) {\n\t\tvar ret = results || [];\n\n\t\tif ( arr != null ) {\n\t\t\tif ( isArrayLike( Object( arr ) ) ) {\n\t\t\t\tjQuery.merge( ret,\n\t\t\t\t\ttypeof arr === \"string\" ?\n\t\t\t\t\t\t[ arr ] : arr\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tpush.call( ret, arr );\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\tinArray: function( elem, arr, i ) {\n\t\treturn arr == null ? -1 : indexOf.call( arr, elem, i );\n\t},\n\n\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t// push.apply(_, arraylike) throws on ancient WebKit\n\tmerge: function( first, second ) {\n\t\tvar len = +second.length,\n\t\t\tj = 0,\n\t\t\ti = first.length;\n\n\t\tfor ( ; j < len; j++ ) {\n\t\t\tfirst[ i++ ] = second[ j ];\n\t\t}\n\n\t\tfirst.length = i;\n\n\t\treturn first;\n\t},\n\n\tgrep: function( elems, callback, invert ) {\n\t\tvar callbackInverse,\n\t\t\tmatches = [],\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\tcallbackExpect = !invert;\n\n\t\t// Go through the array, only saving the items\n\t\t// that pass the validator function\n\t\tfor ( ; i < length; i++ ) {\n\t\t\tcallbackInverse = !callback( elems[ i ], i );\n\t\t\tif ( callbackInverse !== callbackExpect ) {\n\t\t\t\tmatches.push( elems[ i ] );\n\t\t\t}\n\t\t}\n\n\t\treturn matches;\n\t},\n\n\t// arg is for internal usage only\n\tmap: function( elems, callback, arg ) {\n\t\tvar length, value,\n\t\t\ti = 0,\n\t\t\tret = [];\n\n\t\t// Go through the array, translating each of the items to their new values\n\t\tif ( isArrayLike( elems ) ) {\n\t\t\tlength = elems.length;\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Go through every key on the object,\n\t\t} else {\n\t\t\tfor ( i in elems ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Flatten any nested arrays\n\t\treturn flat( ret );\n\t},\n\n\t// A global GUID counter for objects\n\tguid: 1,\n\n\t// jQuery.support is not used in Core but other projects attach their\n\t// properties to it so it needs to exist.\n\tsupport: support\n} );\n\nif ( typeof Symbol === \"function\" ) {\n\tjQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];\n}\n\n// Populate the class2type map\njQuery.each( \"Boolean Number String Function Array Date RegExp Object Error Symbol\".split( \" \" ),\n\tfunction( _i, name ) {\n\t\tclass2type[ \"[object \" + name + \"]\" ] = name.toLowerCase();\n\t} );\n\nfunction isArrayLike( obj ) {\n\n\t// Support: real iOS 8.2 only (not reproducible in simulator)\n\t// `in` check used to prevent JIT error (gh-2145)\n\t// hasOwn isn't used here due to false negatives\n\t// regarding Nodelist length in IE\n\tvar length = !!obj && \"length\" in obj && obj.length,\n\t\ttype = toType( obj );\n\n\tif ( isFunction( obj ) || isWindow( obj ) ) {\n\t\treturn false;\n\t}\n\n\treturn type === \"array\" || length === 0 ||\n\t\ttypeof length === \"number\" && length > 0 && ( length - 1 ) in obj;\n}\nvar Sizzle =\n/*!\n * Sizzle CSS Selector Engine v2.3.6\n * https://sizzlejs.com/\n *\n * Copyright JS Foundation and other contributors\n * Released under the MIT license\n * https://js.foundation/\n *\n * Date: 2021-02-16\n */\n( function( window ) {\nvar i,\n\tsupport,\n\tExpr,\n\tgetText,\n\tisXML,\n\ttokenize,\n\tcompile,\n\tselect,\n\toutermostContext,\n\tsortInput,\n\thasDuplicate,\n\n\t// Local document vars\n\tsetDocument,\n\tdocument,\n\tdocElem,\n\tdocumentIsHTML,\n\trbuggyQSA,\n\trbuggyMatches,\n\tmatches,\n\tcontains,\n\n\t// Instance-specific data\n\texpando = \"sizzle\" + 1 * new Date(),\n\tpreferredDoc = window.document,\n\tdirruns = 0,\n\tdone = 0,\n\tclassCache = createCache(),\n\ttokenCache = createCache(),\n\tcompilerCache = createCache(),\n\tnonnativeSelectorCache = createCache(),\n\tsortOrder = function( a, b ) {\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t}\n\t\treturn 0;\n\t},\n\n\t// Instance methods\n\thasOwn = ( {} ).hasOwnProperty,\n\tarr = [],\n\tpop = arr.pop,\n\tpushNative = arr.push,\n\tpush = arr.push,\n\tslice = arr.slice,\n\n\t// Use a stripped-down indexOf as it's faster than native\n\t// https://jsperf.com/thor-indexof-vs-for/5\n\tindexOf = function( list, elem ) {\n\t\tvar i = 0,\n\t\t\tlen = list.length;\n\t\tfor ( ; i < len; i++ ) {\n\t\t\tif ( list[ i ] === elem ) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t},\n\n\tbooleans = \"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|\" +\n\t\t\"ismap|loop|multiple|open|readonly|required|scoped\",\n\n\t// Regular expressions\n\n\t// http://www.w3.org/TR/css3-selectors/#whitespace\n\twhitespace = \"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",\n\n\t// https://www.w3.org/TR/css-syntax-3/#ident-token-diagram\n\tidentifier = \"(?:\\\\\\\\[\\\\da-fA-F]{1,6}\" + whitespace +\n\t\t\"?|\\\\\\\\[^\\\\r\\\\n\\\\f]|[\\\\w-]|[^\\0-\\\\x7f])+\",\n\n\t// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors\n\tattributes = \"\\\\[\" + whitespace + \"*(\" + identifier + \")(?:\" + whitespace +\n\n\t\t// Operator (capture 2)\n\t\t\"*([*^$|!~]?=)\" + whitespace +\n\n\t\t// \"Attribute values must be CSS identifiers [capture 5]\n\t\t// or strings [capture 3 or capture 4]\"\n\t\t\"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\" + identifier + \"))|)\" +\n\t\twhitespace + \"*\\\\]\",\n\n\tpseudos = \":(\" + identifier + \")(?:\\\\((\" +\n\n\t\t// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:\n\t\t// 1. quoted (capture 3; capture 4 or capture 5)\n\t\t\"('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|\" +\n\n\t\t// 2. simple (capture 6)\n\t\t\"((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\" + attributes + \")*)|\" +\n\n\t\t// 3. anything else (capture 2)\n\t\t\".*\" +\n\t\t\")\\\\)|)\",\n\n\t// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter\n\trwhitespace = new RegExp( whitespace + \"+\", \"g\" ),\n\trtrim = new RegExp( \"^\" + whitespace + \"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\" +\n\t\twhitespace + \"+$\", \"g\" ),\n\n\trcomma = new RegExp( \"^\" + whitespace + \"*,\" + whitespace + \"*\" ),\n\trcombinators = new RegExp( \"^\" + whitespace + \"*([>+~]|\" + whitespace + \")\" + whitespace +\n\t\t\"*\" ),\n\trdescend = new RegExp( whitespace + \"|>\" ),\n\n\trpseudo = new RegExp( pseudos ),\n\tridentifier = new RegExp( \"^\" + identifier + \"$\" ),\n\n\tmatchExpr = {\n\t\t\"ID\": new RegExp( \"^#(\" + identifier + \")\" ),\n\t\t\"CLASS\": new RegExp( \"^\\\\.(\" + identifier + \")\" ),\n\t\t\"TAG\": new RegExp( \"^(\" + identifier + \"|[*])\" ),\n\t\t\"ATTR\": new RegExp( \"^\" + attributes ),\n\t\t\"PSEUDO\": new RegExp( \"^\" + pseudos ),\n\t\t\"CHILD\": new RegExp( \"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\" +\n\t\t\twhitespace + \"*(even|odd|(([+-]|)(\\\\d*)n|)\" + whitespace + \"*(?:([+-]|)\" +\n\t\t\twhitespace + \"*(\\\\d+)|))\" + whitespace + \"*\\\\)|)\", \"i\" ),\n\t\t\"bool\": new RegExp( \"^(?:\" + booleans + \")$\", \"i\" ),\n\n\t\t// For use in libraries implementing .is()\n\t\t// We use this for POS matching in `select`\n\t\t\"needsContext\": new RegExp( \"^\" + whitespace +\n\t\t\t\"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\" + whitespace +\n\t\t\t\"*((?:-\\\\d)?\\\\d*)\" + whitespace + \"*\\\\)|)(?=[^-]|$)\", \"i\" )\n\t},\n\n\trhtml = /HTML$/i,\n\trinputs = /^(?:input|select|textarea|button)$/i,\n\trheader = /^h\\d$/i,\n\n\trnative = /^[^{]+\\{\\s*\\[native \\w/,\n\n\t// Easily-parseable/retrievable ID or TAG or CLASS selectors\n\trquickExpr = /^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,\n\n\trsibling = /[+~]/,\n\n\t// CSS escapes\n\t// http://www.w3.org/TR/CSS21/syndata.html#escaped-characters\n\trunescape = new RegExp( \"\\\\\\\\[\\\\da-fA-F]{1,6}\" + whitespace + \"?|\\\\\\\\([^\\\\r\\\\n\\\\f])\", \"g\" ),\n\tfunescape = function( escape, nonHex ) {\n\t\tvar high = \"0x\" + escape.slice( 1 ) - 0x10000;\n\n\t\treturn nonHex ?\n\n\t\t\t// Strip the backslash prefix from a non-hex escape sequence\n\t\t\tnonHex :\n\n\t\t\t// Replace a hexadecimal escape sequence with the encoded Unicode code point\n\t\t\t// Support: IE <=11+\n\t\t\t// For values outside the Basic Multilingual Plane (BMP), manually construct a\n\t\t\t// surrogate pair\n\t\t\thigh < 0 ?\n\t\t\t\tString.fromCharCode( high + 0x10000 ) :\n\t\t\t\tString.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );\n\t},\n\n\t// CSS string/identifier serialization\n\t// https://drafts.csswg.org/cssom/#common-serializing-idioms\n\trcssescape = /([\\0-\\x1f\\x7f]|^-?\\d)|^-$|[^\\0-\\x1f\\x7f-\\uFFFF\\w-]/g,\n\tfcssescape = function( ch, asCodePoint ) {\n\t\tif ( asCodePoint ) {\n\n\t\t\t// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER\n\t\t\tif ( ch === \"\\0\" ) {\n\t\t\t\treturn \"\\uFFFD\";\n\t\t\t}\n\n\t\t\t// Control characters and (dependent upon position) numbers get escaped as code points\n\t\t\treturn ch.slice( 0, -1 ) + \"\\\\\" +\n\t\t\t\tch.charCodeAt( ch.length - 1 ).toString( 16 ) + \" \";\n\t\t}\n\n\t\t// Other potentially-special ASCII characters get backslash-escaped\n\t\treturn \"\\\\\" + ch;\n\t},\n\n\t// Used for iframes\n\t// See setDocument()\n\t// Removing the function wrapper causes a \"Permission Denied\"\n\t// error in IE\n\tunloadHandler = function() {\n\t\tsetDocument();\n\t},\n\n\tinDisabledFieldset = addCombinator(\n\t\tfunction( elem ) {\n\t\t\treturn elem.disabled === true && elem.nodeName.toLowerCase() === \"fieldset\";\n\t\t},\n\t\t{ dir: \"parentNode\", next: \"legend\" }\n\t);\n\n// Optimize for push.apply( _, NodeList )\ntry {\n\tpush.apply(\n\t\t( arr = slice.call( preferredDoc.childNodes ) ),\n\t\tpreferredDoc.childNodes\n\t);\n\n\t// Support: Android<4.0\n\t// Detect silently failing push.apply\n\t// eslint-disable-next-line no-unused-expressions\n\tarr[ preferredDoc.childNodes.length ].nodeType;\n} catch ( e ) {\n\tpush = { apply: arr.length ?\n\n\t\t// Leverage slice if possible\n\t\tfunction( target, els ) {\n\t\t\tpushNative.apply( target, slice.call( els ) );\n\t\t} :\n\n\t\t// Support: IE<9\n\t\t// Otherwise append directly\n\t\tfunction( target, els ) {\n\t\t\tvar j = target.length,\n\t\t\t\ti = 0;\n\n\t\t\t// Can't trust NodeList.length\n\t\t\twhile ( ( target[ j++ ] = els[ i++ ] ) ) {}\n\t\t\ttarget.length = j - 1;\n\t\t}\n\t};\n}\n\nfunction Sizzle( selector, context, results, seed ) {\n\tvar m, i, elem, nid, match, groups, newSelector,\n\t\tnewContext = context && context.ownerDocument,\n\n\t\t// nodeType defaults to 9, since context defaults to document\n\t\tnodeType = context ? context.nodeType : 9;\n\n\tresults = results || [];\n\n\t// Return early from calls with invalid selector or context\n\tif ( typeof selector !== \"string\" || !selector ||\n\t\tnodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {\n\n\t\treturn results;\n\t}\n\n\t// Try to shortcut find operations (as opposed to filters) in HTML documents\n\tif ( !seed ) {\n\t\tsetDocument( context );\n\t\tcontext = context || document;\n\n\t\tif ( documentIsHTML ) {\n\n\t\t\t// If the selector is sufficiently simple, try using a \"get*By*\" DOM method\n\t\t\t// (excepting DocumentFragment context, where the methods don't exist)\n\t\t\tif ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) {\n\n\t\t\t\t// ID selector\n\t\t\t\tif ( ( m = match[ 1 ] ) ) {\n\n\t\t\t\t\t// Document context\n\t\t\t\t\tif ( nodeType === 9 ) {\n\t\t\t\t\t\tif ( ( elem = context.getElementById( m ) ) ) {\n\n\t\t\t\t\t\t\t// Support: IE, Opera, Webkit\n\t\t\t\t\t\t\t// TODO: identify versions\n\t\t\t\t\t\t\t// getElementById can match elements by name instead of ID\n\t\t\t\t\t\t\tif ( elem.id === m ) {\n\t\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t// Element context\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// Support: IE, Opera, Webkit\n\t\t\t\t\t\t// TODO: identify versions\n\t\t\t\t\t\t// getElementById can match elements by name instead of ID\n\t\t\t\t\t\tif ( newContext && ( elem = newContext.getElementById( m ) ) &&\n\t\t\t\t\t\t\tcontains( context, elem ) &&\n\t\t\t\t\t\t\telem.id === m ) {\n\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t// Type selector\n\t\t\t\t} else if ( match[ 2 ] ) {\n\t\t\t\t\tpush.apply( results, context.getElementsByTagName( selector ) );\n\t\t\t\t\treturn results;\n\n\t\t\t\t// Class selector\n\t\t\t\t} else if ( ( m = match[ 3 ] ) && support.getElementsByClassName &&\n\t\t\t\t\tcontext.getElementsByClassName ) {\n\n\t\t\t\t\tpush.apply( results, context.getElementsByClassName( m ) );\n\t\t\t\t\treturn results;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Take advantage of querySelectorAll\n\t\t\tif ( support.qsa &&\n\t\t\t\t!nonnativeSelectorCache[ selector + \" \" ] &&\n\t\t\t\t( !rbuggyQSA || !rbuggyQSA.test( selector ) ) &&\n\n\t\t\t\t// Support: IE 8 only\n\t\t\t\t// Exclude object elements\n\t\t\t\t( nodeType !== 1 || context.nodeName.toLowerCase() !== \"object\" ) ) {\n\n\t\t\t\tnewSelector = selector;\n\t\t\t\tnewContext = context;\n\n\t\t\t\t// qSA considers elements outside a scoping root when evaluating child or\n\t\t\t\t// descendant combinators, which is not what we want.\n\t\t\t\t// In such cases, we work around the behavior by prefixing every selector in the\n\t\t\t\t// list with an ID selector referencing the scope context.\n\t\t\t\t// The technique has to be used as well when a leading combinator is used\n\t\t\t\t// as such selectors are not recognized by querySelectorAll.\n\t\t\t\t// Thanks to Andrew Dupont for this technique.\n\t\t\t\tif ( nodeType === 1 &&\n\t\t\t\t\t( rdescend.test( selector ) || rcombinators.test( selector ) ) ) {\n\n\t\t\t\t\t// Expand context for sibling selectors\n\t\t\t\t\tnewContext = rsibling.test( selector ) && testContext( context.parentNode ) ||\n\t\t\t\t\t\tcontext;\n\n\t\t\t\t\t// We can use :scope instead of the ID hack if the browser\n\t\t\t\t\t// supports it & if we're not changing the context.\n\t\t\t\t\tif ( newContext !== context || !support.scope ) {\n\n\t\t\t\t\t\t// Capture the context ID, setting it first if necessary\n\t\t\t\t\t\tif ( ( nid = context.getAttribute( \"id\" ) ) ) {\n\t\t\t\t\t\t\tnid = nid.replace( rcssescape, fcssescape );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tcontext.setAttribute( \"id\", ( nid = expando ) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prefix every selector in the list\n\t\t\t\t\tgroups = tokenize( selector );\n\t\t\t\t\ti = groups.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tgroups[ i ] = ( nid ? \"#\" + nid : \":scope\" ) + \" \" +\n\t\t\t\t\t\t\ttoSelector( groups[ i ] );\n\t\t\t\t\t}\n\t\t\t\t\tnewSelector = groups.join( \",\" );\n\t\t\t\t}\n\n\t\t\t\ttry {\n\t\t\t\t\tpush.apply( results,\n\t\t\t\t\t\tnewContext.querySelectorAll( newSelector )\n\t\t\t\t\t);\n\t\t\t\t\treturn results;\n\t\t\t\t} catch ( qsaError ) {\n\t\t\t\t\tnonnativeSelectorCache( selector, true );\n\t\t\t\t} finally {\n\t\t\t\t\tif ( nid === expando ) {\n\t\t\t\t\t\tcontext.removeAttribute( \"id\" );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// All others\n\treturn select( selector.replace( rtrim, \"$1\" ), context, results, seed );\n}\n\n/**\n * Create key-value caches of limited size\n * @returns {function(string, object)} Returns the Object data after storing it on itself with\n *\tproperty name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)\n *\tdeleting the oldest entry\n */\nfunction createCache() {\n\tvar keys = [];\n\n\tfunction cache( key, value ) {\n\n\t\t// Use (key + \" \") to avoid collision with native prototype properties (see Issue #157)\n\t\tif ( keys.push( key + \" \" ) > Expr.cacheLength ) {\n\n\t\t\t// Only keep the most recent entries\n\t\t\tdelete cache[ keys.shift() ];\n\t\t}\n\t\treturn ( cache[ key + \" \" ] = value );\n\t}\n\treturn cache;\n}\n\n/**\n * Mark a function for special use by Sizzle\n * @param {Function} fn The function to mark\n */\nfunction markFunction( fn ) {\n\tfn[ expando ] = true;\n\treturn fn;\n}\n\n/**\n * Support testing using an element\n * @param {Function} fn Passed the created element and returns a boolean result\n */\nfunction assert( fn ) {\n\tvar el = document.createElement( \"fieldset\" );\n\n\ttry {\n\t\treturn !!fn( el );\n\t} catch ( e ) {\n\t\treturn false;\n\t} finally {\n\n\t\t// Remove from its parent by default\n\t\tif ( el.parentNode ) {\n\t\t\tel.parentNode.removeChild( el );\n\t\t}\n\n\t\t// release memory in IE\n\t\tel = null;\n\t}\n}\n\n/**\n * Adds the same handler for all of the specified attrs\n * @param {String} attrs Pipe-separated list of attributes\n * @param {Function} handler The method that will be applied\n */\nfunction addHandle( attrs, handler ) {\n\tvar arr = attrs.split( \"|\" ),\n\t\ti = arr.length;\n\n\twhile ( i-- ) {\n\t\tExpr.attrHandle[ arr[ i ] ] = handler;\n\t}\n}\n\n/**\n * Checks document order of two siblings\n * @param {Element} a\n * @param {Element} b\n * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b\n */\nfunction siblingCheck( a, b ) {\n\tvar cur = b && a,\n\t\tdiff = cur && a.nodeType === 1 && b.nodeType === 1 &&\n\t\t\ta.sourceIndex - b.sourceIndex;\n\n\t// Use IE sourceIndex if available on both nodes\n\tif ( diff ) {\n\t\treturn diff;\n\t}\n\n\t// Check if b follows a\n\tif ( cur ) {\n\t\twhile ( ( cur = cur.nextSibling ) ) {\n\t\t\tif ( cur === b ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn a ? 1 : -1;\n}\n\n/**\n * Returns a function to use in pseudos for input types\n * @param {String} type\n */\nfunction createInputPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn name === \"input\" && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for buttons\n * @param {String} type\n */\nfunction createButtonPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn ( name === \"input\" || name === \"button\" ) && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for :enabled/:disabled\n * @param {Boolean} disabled true for :disabled; false for :enabled\n */\nfunction createDisabledPseudo( disabled ) {\n\n\t// Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable\n\treturn function( elem ) {\n\n\t\t// Only certain elements can match :enabled or :disabled\n\t\t// https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled\n\t\t// https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled\n\t\tif ( \"form\" in elem ) {\n\n\t\t\t// Check for inherited disabledness on relevant non-disabled elements:\n\t\t\t// * listed form-associated elements in a disabled fieldset\n\t\t\t// https://html.spec.whatwg.org/multipage/forms.html#category-listed\n\t\t\t// https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled\n\t\t\t// * option elements in a disabled optgroup\n\t\t\t// https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled\n\t\t\t// All such elements have a \"form\" property.\n\t\t\tif ( elem.parentNode && elem.disabled === false ) {\n\n\t\t\t\t// Option elements defer to a parent optgroup if present\n\t\t\t\tif ( \"label\" in elem ) {\n\t\t\t\t\tif ( \"label\" in elem.parentNode ) {\n\t\t\t\t\t\treturn elem.parentNode.disabled === disabled;\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn elem.disabled === disabled;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Support: IE 6 - 11\n\t\t\t\t// Use the isDisabled shortcut property to check for disabled fieldset ancestors\n\t\t\t\treturn elem.isDisabled === disabled ||\n\n\t\t\t\t\t// Where there is no isDisabled, check manually\n\t\t\t\t\t/* jshint -W018 */\n\t\t\t\t\telem.isDisabled !== !disabled &&\n\t\t\t\t\tinDisabledFieldset( elem ) === disabled;\n\t\t\t}\n\n\t\t\treturn elem.disabled === disabled;\n\n\t\t// Try to winnow out elements that can't be disabled before trusting the disabled property.\n\t\t// Some victims get caught in our net (label, legend, menu, track), but it shouldn't\n\t\t// even exist on them, let alone have a boolean value.\n\t\t} else if ( \"label\" in elem ) {\n\t\t\treturn elem.disabled === disabled;\n\t\t}\n\n\t\t// Remaining elements are neither :enabled nor :disabled\n\t\treturn false;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for positionals\n * @param {Function} fn\n */\nfunction createPositionalPseudo( fn ) {\n\treturn markFunction( function( argument ) {\n\t\targument = +argument;\n\t\treturn markFunction( function( seed, matches ) {\n\t\t\tvar j,\n\t\t\t\tmatchIndexes = fn( [], seed.length, argument ),\n\t\t\t\ti = matchIndexes.length;\n\n\t\t\t// Match elements found at the specified indexes\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( seed[ ( j = matchIndexes[ i ] ) ] ) {\n\t\t\t\t\tseed[ j ] = !( matches[ j ] = seed[ j ] );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t} );\n}\n\n/**\n * Checks a node for validity as a Sizzle context\n * @param {Element|Object=} context\n * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value\n */\nfunction testContext( context ) {\n\treturn context && typeof context.getElementsByTagName !== \"undefined\" && context;\n}\n\n// Expose support vars for convenience\nsupport = Sizzle.support = {};\n\n/**\n * Detects XML nodes\n * @param {Element|Object} elem An element or a document\n * @returns {Boolean} True iff elem is a non-HTML XML node\n */\nisXML = Sizzle.isXML = function( elem ) {\n\tvar namespace = elem && elem.namespaceURI,\n\t\tdocElem = elem && ( elem.ownerDocument || elem ).documentElement;\n\n\t// Support: IE <=8\n\t// Assume HTML when documentElement doesn't yet exist, such as inside loading iframes\n\t// https://bugs.jquery.com/ticket/4833\n\treturn !rhtml.test( namespace || docElem && docElem.nodeName || \"HTML\" );\n};\n\n/**\n * Sets document-related variables once based on the current document\n * @param {Element|Object} [doc] An element or document object to use to set the document\n * @returns {Object} Returns the current document\n */\nsetDocument = Sizzle.setDocument = function( node ) {\n\tvar hasCompare, subWindow,\n\t\tdoc = node ? node.ownerDocument || node : preferredDoc;\n\n\t// Return early if doc is invalid or already selected\n\t// Support: IE 11+, Edge 17 - 18+\n\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t// two documents; shallow comparisons work.\n\t// eslint-disable-next-line eqeqeq\n\tif ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) {\n\t\treturn document;\n\t}\n\n\t// Update global variables\n\tdocument = doc;\n\tdocElem = document.documentElement;\n\tdocumentIsHTML = !isXML( document );\n\n\t// Support: IE 9 - 11+, Edge 12 - 18+\n\t// Accessing iframe documents after unload throws \"permission denied\" errors (jQuery #13936)\n\t// Support: IE 11+, Edge 17 - 18+\n\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t// two documents; shallow comparisons work.\n\t// eslint-disable-next-line eqeqeq\n\tif ( preferredDoc != document &&\n\t\t( subWindow = document.defaultView ) && subWindow.top !== subWindow ) {\n\n\t\t// Support: IE 11, Edge\n\t\tif ( subWindow.addEventListener ) {\n\t\t\tsubWindow.addEventListener( \"unload\", unloadHandler, false );\n\n\t\t// Support: IE 9 - 10 only\n\t\t} else if ( subWindow.attachEvent ) {\n\t\t\tsubWindow.attachEvent( \"onunload\", unloadHandler );\n\t\t}\n\t}\n\n\t// Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only,\n\t// Safari 4 - 5 only, Opera <=11.6 - 12.x only\n\t// IE/Edge & older browsers don't support the :scope pseudo-class.\n\t// Support: Safari 6.0 only\n\t// Safari 6.0 supports :scope but it's an alias of :root there.\n\tsupport.scope = assert( function( el ) {\n\t\tdocElem.appendChild( el ).appendChild( document.createElement( \"div\" ) );\n\t\treturn typeof el.querySelectorAll !== \"undefined\" &&\n\t\t\t!el.querySelectorAll( \":scope fieldset div\" ).length;\n\t} );\n\n\t/* Attributes\n\t---------------------------------------------------------------------- */\n\n\t// Support: IE<8\n\t// Verify that getAttribute really returns attributes and not properties\n\t// (excepting IE8 booleans)\n\tsupport.attributes = assert( function( el ) {\n\t\tel.className = \"i\";\n\t\treturn !el.getAttribute( \"className\" );\n\t} );\n\n\t/* getElement(s)By*\n\t---------------------------------------------------------------------- */\n\n\t// Check if getElementsByTagName(\"*\") returns only elements\n\tsupport.getElementsByTagName = assert( function( el ) {\n\t\tel.appendChild( document.createComment( \"\" ) );\n\t\treturn !el.getElementsByTagName( \"*\" ).length;\n\t} );\n\n\t// Support: IE<9\n\tsupport.getElementsByClassName = rnative.test( document.getElementsByClassName );\n\n\t// Support: IE<10\n\t// Check if getElementById returns elements by name\n\t// The broken getElementById methods don't pick up programmatically-set names,\n\t// so use a roundabout getElementsByName test\n\tsupport.getById = assert( function( el ) {\n\t\tdocElem.appendChild( el ).id = expando;\n\t\treturn !document.getElementsByName || !document.getElementsByName( expando ).length;\n\t} );\n\n\t// ID filter and find\n\tif ( support.getById ) {\n\t\tExpr.filter[ \"ID\" ] = function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn elem.getAttribute( \"id\" ) === attrId;\n\t\t\t};\n\t\t};\n\t\tExpr.find[ \"ID\" ] = function( id, context ) {\n\t\t\tif ( typeof context.getElementById !== \"undefined\" && documentIsHTML ) {\n\t\t\t\tvar elem = context.getElementById( id );\n\t\t\t\treturn elem ? [ elem ] : [];\n\t\t\t}\n\t\t};\n\t} else {\n\t\tExpr.filter[ \"ID\" ] = function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\tvar node = typeof elem.getAttributeNode !== \"undefined\" &&\n\t\t\t\t\telem.getAttributeNode( \"id\" );\n\t\t\t\treturn node && node.value === attrId;\n\t\t\t};\n\t\t};\n\n\t\t// Support: IE 6 - 7 only\n\t\t// getElementById is not reliable as a find shortcut\n\t\tExpr.find[ \"ID\" ] = function( id, context ) {\n\t\t\tif ( typeof context.getElementById !== \"undefined\" && documentIsHTML ) {\n\t\t\t\tvar node, i, elems,\n\t\t\t\t\telem = context.getElementById( id );\n\n\t\t\t\tif ( elem ) {\n\n\t\t\t\t\t// Verify the id attribute\n\t\t\t\t\tnode = elem.getAttributeNode( \"id\" );\n\t\t\t\t\tif ( node && node.value === id ) {\n\t\t\t\t\t\treturn [ elem ];\n\t\t\t\t\t}\n\n\t\t\t\t\t// Fall back on getElementsByName\n\t\t\t\t\telems = context.getElementsByName( id );\n\t\t\t\t\ti = 0;\n\t\t\t\t\twhile ( ( elem = elems[ i++ ] ) ) {\n\t\t\t\t\t\tnode = elem.getAttributeNode( \"id\" );\n\t\t\t\t\t\tif ( node && node.value === id ) {\n\t\t\t\t\t\t\treturn [ elem ];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn [];\n\t\t\t}\n\t\t};\n\t}\n\n\t// Tag\n\tExpr.find[ \"TAG\" ] = support.getElementsByTagName ?\n\t\tfunction( tag, context ) {\n\t\t\tif ( typeof context.getElementsByTagName !== \"undefined\" ) {\n\t\t\t\treturn context.getElementsByTagName( tag );\n\n\t\t\t// DocumentFragment nodes don't have gEBTN\n\t\t\t} else if ( support.qsa ) {\n\t\t\t\treturn context.querySelectorAll( tag );\n\t\t\t}\n\t\t} :\n\n\t\tfunction( tag, context ) {\n\t\t\tvar elem,\n\t\t\t\ttmp = [],\n\t\t\t\ti = 0,\n\n\t\t\t\t// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too\n\t\t\t\tresults = context.getElementsByTagName( tag );\n\n\t\t\t// Filter out possible comments\n\t\t\tif ( tag === \"*\" ) {\n\t\t\t\twhile ( ( elem = results[ i++ ] ) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\ttmp.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn tmp;\n\t\t\t}\n\t\t\treturn results;\n\t\t};\n\n\t// Class\n\tExpr.find[ \"CLASS\" ] = support.getElementsByClassName && function( className, context ) {\n\t\tif ( typeof context.getElementsByClassName !== \"undefined\" && documentIsHTML ) {\n\t\t\treturn context.getElementsByClassName( className );\n\t\t}\n\t};\n\n\t/* QSA/matchesSelector\n\t---------------------------------------------------------------------- */\n\n\t// QSA and matchesSelector support\n\n\t// matchesSelector(:active) reports false when true (IE9/Opera 11.5)\n\trbuggyMatches = [];\n\n\t// qSa(:focus) reports false when true (Chrome 21)\n\t// We allow this because of a bug in IE8/9 that throws an error\n\t// whenever `document.activeElement` is accessed on an iframe\n\t// So, we allow :focus to pass through QSA all the time to avoid the IE error\n\t// See https://bugs.jquery.com/ticket/13378\n\trbuggyQSA = [];\n\n\tif ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) {\n\n\t\t// Build QSA regex\n\t\t// Regex strategy adopted from Diego Perini\n\t\tassert( function( el ) {\n\n\t\t\tvar input;\n\n\t\t\t// Select is set to empty string on purpose\n\t\t\t// This is to test IE's treatment of not explicitly\n\t\t\t// setting a boolean content attribute,\n\t\t\t// since its presence should be enough\n\t\t\t// https://bugs.jquery.com/ticket/12359\n\t\t\tdocElem.appendChild( el ).innerHTML = \"<a id='\" + expando + \"'></a>\" +\n\t\t\t\t\"<select id='\" + expando + \"-\\r\\\\' msallowcapture=''>\" +\n\t\t\t\t\"<option selected=''></option></select>\";\n\n\t\t\t// Support: IE8, Opera 11-12.16\n\t\t\t// Nothing should be selected when empty strings follow ^= or $= or *=\n\t\t\t// The test attribute must be unknown in Opera but \"safe\" for WinRT\n\t\t\t// https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section\n\t\t\tif ( el.querySelectorAll( \"[msallowcapture^='']\" ).length ) {\n\t\t\t\trbuggyQSA.push( \"[*^$]=\" + whitespace + \"*(?:''|\\\"\\\")\" );\n\t\t\t}\n\n\t\t\t// Support: IE8\n\t\t\t// Boolean attributes and \"value\" are not treated correctly\n\t\t\tif ( !el.querySelectorAll( \"[selected]\" ).length ) {\n\t\t\t\trbuggyQSA.push( \"\\\\[\" + whitespace + \"*(?:value|\" + booleans + \")\" );\n\t\t\t}\n\n\t\t\t// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+\n\t\t\tif ( !el.querySelectorAll( \"[id~=\" + expando + \"-]\" ).length ) {\n\t\t\t\trbuggyQSA.push( \"~=\" );\n\t\t\t}\n\n\t\t\t// Support: IE 11+, Edge 15 - 18+\n\t\t\t// IE 11/Edge don't find elements on a `[name='']` query in some cases.\n\t\t\t// Adding a temporary attribute to the document before the selection works\n\t\t\t// around the issue.\n\t\t\t// Interestingly, IE 10 & older don't seem to have the issue.\n\t\t\tinput = document.createElement( \"input\" );\n\t\t\tinput.setAttribute( \"name\", \"\" );\n\t\t\tel.appendChild( input );\n\t\t\tif ( !el.querySelectorAll( \"[name='']\" ).length ) {\n\t\t\t\trbuggyQSA.push( \"\\\\[\" + whitespace + \"*name\" + whitespace + \"*=\" +\n\t\t\t\t\twhitespace + \"*(?:''|\\\"\\\")\" );\n\t\t\t}\n\n\t\t\t// Webkit/Opera - :checked should return selected option elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( !el.querySelectorAll( \":checked\" ).length ) {\n\t\t\t\trbuggyQSA.push( \":checked\" );\n\t\t\t}\n\n\t\t\t// Support: Safari 8+, iOS 8+\n\t\t\t// https://bugs.webkit.org/show_bug.cgi?id=136851\n\t\t\t// In-page `selector#id sibling-combinator selector` fails\n\t\t\tif ( !el.querySelectorAll( \"a#\" + expando + \"+*\" ).length ) {\n\t\t\t\trbuggyQSA.push( \".#.+[+~]\" );\n\t\t\t}\n\n\t\t\t// Support: Firefox <=3.6 - 5 only\n\t\t\t// Old Firefox doesn't throw on a badly-escaped identifier.\n\t\t\tel.querySelectorAll( \"\\\\\\f\" );\n\t\t\trbuggyQSA.push( \"[\\\\r\\\\n\\\\f]\" );\n\t\t} );\n\n\t\tassert( function( el ) {\n\t\t\tel.innerHTML = \"<a href='' disabled='disabled'></a>\" +\n\t\t\t\t\"<select disabled='disabled'><option/></select>\";\n\n\t\t\t// Support: Windows 8 Native Apps\n\t\t\t// The type and name attributes are restricted during .innerHTML assignment\n\t\t\tvar input = document.createElement( \"input\" );\n\t\t\tinput.setAttribute( \"type\", \"hidden\" );\n\t\t\tel.appendChild( input ).setAttribute( \"name\", \"D\" );\n\n\t\t\t// Support: IE8\n\t\t\t// Enforce case-sensitivity of name attribute\n\t\t\tif ( el.querySelectorAll( \"[name=d]\" ).length ) {\n\t\t\t\trbuggyQSA.push( \"name\" + whitespace + \"*[*^$|!~]?=\" );\n\t\t\t}\n\n\t\t\t// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( el.querySelectorAll( \":enabled\" ).length !== 2 ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\n\t\t\t// Support: IE9-11+\n\t\t\t// IE's :disabled selector does not pick up the children of disabled fieldsets\n\t\t\tdocElem.appendChild( el ).disabled = true;\n\t\t\tif ( el.querySelectorAll( \":disabled\" ).length !== 2 ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\n\t\t\t// Support: Opera 10 - 11 only\n\t\t\t// Opera 10-11 does not throw on post-comma invalid pseudos\n\t\t\tel.querySelectorAll( \"*,:x\" );\n\t\t\trbuggyQSA.push( \",.*:\" );\n\t\t} );\n\t}\n\n\tif ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches ||\n\t\tdocElem.webkitMatchesSelector ||\n\t\tdocElem.mozMatchesSelector ||\n\t\tdocElem.oMatchesSelector ||\n\t\tdocElem.msMatchesSelector ) ) ) ) {\n\n\t\tassert( function( el ) {\n\n\t\t\t// Check to see if it's possible to do matchesSelector\n\t\t\t// on a disconnected node (IE 9)\n\t\t\tsupport.disconnectedMatch = matches.call( el, \"*\" );\n\n\t\t\t// This should fail with an exception\n\t\t\t// Gecko does not error, returns false instead\n\t\t\tmatches.call( el, \"[s!='']:x\" );\n\t\t\trbuggyMatches.push( \"!=\", pseudos );\n\t\t} );\n\t}\n\n\trbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( \"|\" ) );\n\trbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( \"|\" ) );\n\n\t/* Contains\n\t---------------------------------------------------------------------- */\n\thasCompare = rnative.test( docElem.compareDocumentPosition );\n\n\t// Element contains another\n\t// Purposefully self-exclusive\n\t// As in, an element does not contain itself\n\tcontains = hasCompare || rnative.test( docElem.contains ) ?\n\t\tfunction( a, b ) {\n\t\t\tvar adown = a.nodeType === 9 ? a.documentElement : a,\n\t\t\t\tbup = b && b.parentNode;\n\t\t\treturn a === bup || !!( bup && bup.nodeType === 1 && (\n\t\t\t\tadown.contains ?\n\t\t\t\t\tadown.contains( bup ) :\n\t\t\t\t\ta.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16\n\t\t\t) );\n\t\t} :\n\t\tfunction( a, b ) {\n\t\t\tif ( b ) {\n\t\t\t\twhile ( ( b = b.parentNode ) ) {\n\t\t\t\t\tif ( b === a ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n\n\t/* Sorting\n\t---------------------------------------------------------------------- */\n\n\t// Document order sorting\n\tsortOrder = hasCompare ?\n\tfunction( a, b ) {\n\n\t\t// Flag for duplicate removal\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\t// Sort on method existence if only one input has compareDocumentPosition\n\t\tvar compare = !a.compareDocumentPosition - !b.compareDocumentPosition;\n\t\tif ( compare ) {\n\t\t\treturn compare;\n\t\t}\n\n\t\t// Calculate position if both inputs belong to the same document\n\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t// two documents; shallow comparisons work.\n\t\t// eslint-disable-next-line eqeqeq\n\t\tcompare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ?\n\t\t\ta.compareDocumentPosition( b ) :\n\n\t\t\t// Otherwise we know they are disconnected\n\t\t\t1;\n\n\t\t// Disconnected nodes\n\t\tif ( compare & 1 ||\n\t\t\t( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) {\n\n\t\t\t// Choose the first element that is related to our preferred document\n\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t\t// two documents; shallow comparisons work.\n\t\t\t// eslint-disable-next-line eqeqeq\n\t\t\tif ( a == document || a.ownerDocument == preferredDoc &&\n\t\t\t\tcontains( preferredDoc, a ) ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\n\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t\t// two documents; shallow comparisons work.\n\t\t\t// eslint-disable-next-line eqeqeq\n\t\t\tif ( b == document || b.ownerDocument == preferredDoc &&\n\t\t\t\tcontains( preferredDoc, b ) ) {\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\t// Maintain original order\n\t\t\treturn sortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\t\t}\n\n\t\treturn compare & 4 ? -1 : 1;\n\t} :\n\tfunction( a, b ) {\n\n\t\t// Exit early if the nodes are identical\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\taup = a.parentNode,\n\t\t\tbup = b.parentNode,\n\t\t\tap = [ a ],\n\t\t\tbp = [ b ];\n\n\t\t// Parentless nodes are either documents or disconnected\n\t\tif ( !aup || !bup ) {\n\n\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t\t// two documents; shallow comparisons work.\n\t\t\t/* eslint-disable eqeqeq */\n\t\t\treturn a == document ? -1 :\n\t\t\t\tb == document ? 1 :\n\t\t\t\t/* eslint-enable eqeqeq */\n\t\t\t\taup ? -1 :\n\t\t\t\tbup ? 1 :\n\t\t\t\tsortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\n\t\t// If the nodes are siblings, we can do a quick check\n\t\t} else if ( aup === bup ) {\n\t\t\treturn siblingCheck( a, b );\n\t\t}\n\n\t\t// Otherwise we need full lists of their ancestors for comparison\n\t\tcur = a;\n\t\twhile ( ( cur = cur.parentNode ) ) {\n\t\t\tap.unshift( cur );\n\t\t}\n\t\tcur = b;\n\t\twhile ( ( cur = cur.parentNode ) ) {\n\t\t\tbp.unshift( cur );\n\t\t}\n\n\t\t// Walk down the tree looking for a discrepancy\n\t\twhile ( ap[ i ] === bp[ i ] ) {\n\t\t\ti++;\n\t\t}\n\n\t\treturn i ?\n\n\t\t\t// Do a sibling check if the nodes have a common ancestor\n\t\t\tsiblingCheck( ap[ i ], bp[ i ] ) :\n\n\t\t\t// Otherwise nodes in our document sort first\n\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t\t// two documents; shallow comparisons work.\n\t\t\t/* eslint-disable eqeqeq */\n\t\t\tap[ i ] == preferredDoc ? -1 :\n\t\t\tbp[ i ] == preferredDoc ? 1 :\n\t\t\t/* eslint-enable eqeqeq */\n\t\t\t0;\n\t};\n\n\treturn document;\n};\n\nSizzle.matches = function( expr, elements ) {\n\treturn Sizzle( expr, null, null, elements );\n};\n\nSizzle.matchesSelector = function( elem, expr ) {\n\tsetDocument( elem );\n\n\tif ( support.matchesSelector && documentIsHTML &&\n\t\t!nonnativeSelectorCache[ expr + \" \" ] &&\n\t\t( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&\n\t\t( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {\n\n\t\ttry {\n\t\t\tvar ret = matches.call( elem, expr );\n\n\t\t\t// IE 9's matchesSelector returns false on disconnected nodes\n\t\t\tif ( ret || support.disconnectedMatch ||\n\n\t\t\t\t// As well, disconnected nodes are said to be in a document\n\t\t\t\t// fragment in IE 9\n\t\t\t\telem.document && elem.document.nodeType !== 11 ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t} catch ( e ) {\n\t\t\tnonnativeSelectorCache( expr, true );\n\t\t}\n\t}\n\n\treturn Sizzle( expr, document, null, [ elem ] ).length > 0;\n};\n\nSizzle.contains = function( context, elem ) {\n\n\t// Set document vars if needed\n\t// Support: IE 11+, Edge 17 - 18+\n\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t// two documents; shallow comparisons work.\n\t// eslint-disable-next-line eqeqeq\n\tif ( ( context.ownerDocument || context ) != document ) {\n\t\tsetDocument( context );\n\t}\n\treturn contains( context, elem );\n};\n\nSizzle.attr = function( elem, name ) {\n\n\t// Set document vars if needed\n\t// Support: IE 11+, Edge 17 - 18+\n\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t// two documents; shallow comparisons work.\n\t// eslint-disable-next-line eqeqeq\n\tif ( ( elem.ownerDocument || elem ) != document ) {\n\t\tsetDocument( elem );\n\t}\n\n\tvar fn = Expr.attrHandle[ name.toLowerCase() ],\n\n\t\t// Don't get fooled by Object.prototype properties (jQuery #13807)\n\t\tval = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?\n\t\t\tfn( elem, name, !documentIsHTML ) :\n\t\t\tundefined;\n\n\treturn val !== undefined ?\n\t\tval :\n\t\tsupport.attributes || !documentIsHTML ?\n\t\t\telem.getAttribute( name ) :\n\t\t\t( val = elem.getAttributeNode( name ) ) && val.specified ?\n\t\t\t\tval.value :\n\t\t\t\tnull;\n};\n\nSizzle.escape = function( sel ) {\n\treturn ( sel + \"\" ).replace( rcssescape, fcssescape );\n};\n\nSizzle.error = function( msg ) {\n\tthrow new Error( \"Syntax error, unrecognized expression: \" + msg );\n};\n\n/**\n * Document sorting and removing duplicates\n * @param {ArrayLike} results\n */\nSizzle.uniqueSort = function( results ) {\n\tvar elem,\n\t\tduplicates = [],\n\t\tj = 0,\n\t\ti = 0;\n\n\t// Unless we *know* we can detect duplicates, assume their presence\n\thasDuplicate = !support.detectDuplicates;\n\tsortInput = !support.sortStable && results.slice( 0 );\n\tresults.sort( sortOrder );\n\n\tif ( hasDuplicate ) {\n\t\twhile ( ( elem = results[ i++ ] ) ) {\n\t\t\tif ( elem === results[ i ] ) {\n\t\t\t\tj = duplicates.push( i );\n\t\t\t}\n\t\t}\n\t\twhile ( j-- ) {\n\t\t\tresults.splice( duplicates[ j ], 1 );\n\t\t}\n\t}\n\n\t// Clear input after sorting to release objects\n\t// See https://github.com/jquery/sizzle/pull/225\n\tsortInput = null;\n\n\treturn results;\n};\n\n/**\n * Utility function for retrieving the text value of an array of DOM nodes\n * @param {Array|Element} elem\n */\ngetText = Sizzle.getText = function( elem ) {\n\tvar node,\n\t\tret = \"\",\n\t\ti = 0,\n\t\tnodeType = elem.nodeType;\n\n\tif ( !nodeType ) {\n\n\t\t// If no nodeType, this is expected to be an array\n\t\twhile ( ( node = elem[ i++ ] ) ) {\n\n\t\t\t// Do not traverse comment nodes\n\t\t\tret += getText( node );\n\t\t}\n\t} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {\n\n\t\t// Use textContent for elements\n\t\t// innerText usage removed for consistency of new lines (jQuery #11153)\n\t\tif ( typeof elem.textContent === \"string\" ) {\n\t\t\treturn elem.textContent;\n\t\t} else {\n\n\t\t\t// Traverse its children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tret += getText( elem );\n\t\t\t}\n\t\t}\n\t} else if ( nodeType === 3 || nodeType === 4 ) {\n\t\treturn elem.nodeValue;\n\t}\n\n\t// Do not include comment or processing instruction nodes\n\n\treturn ret;\n};\n\nExpr = Sizzle.selectors = {\n\n\t// Can be adjusted by the user\n\tcacheLength: 50,\n\n\tcreatePseudo: markFunction,\n\n\tmatch: matchExpr,\n\n\tattrHandle: {},\n\n\tfind: {},\n\n\trelative: {\n\t\t\">\": { dir: \"parentNode\", first: true },\n\t\t\" \": { dir: \"parentNode\" },\n\t\t\"+\": { dir: \"previousSibling\", first: true },\n\t\t\"~\": { dir: \"previousSibling\" }\n\t},\n\n\tpreFilter: {\n\t\t\"ATTR\": function( match ) {\n\t\t\tmatch[ 1 ] = match[ 1 ].replace( runescape, funescape );\n\n\t\t\t// Move the given value to match[3] whether quoted or unquoted\n\t\t\tmatch[ 3 ] = ( match[ 3 ] || match[ 4 ] ||\n\t\t\t\tmatch[ 5 ] || \"\" ).replace( runescape, funescape );\n\n\t\t\tif ( match[ 2 ] === \"~=\" ) {\n\t\t\t\tmatch[ 3 ] = \" \" + match[ 3 ] + \" \";\n\t\t\t}\n\n\t\t\treturn match.slice( 0, 4 );\n\t\t},\n\n\t\t\"CHILD\": function( match ) {\n\n\t\t\t/* matches from matchExpr[\"CHILD\"]\n\t\t\t\t1 type (only|nth|...)\n\t\t\t\t2 what (child|of-type)\n\t\t\t\t3 argument (even|odd|\\d*|\\d*n([+-]\\d+)?|...)\n\t\t\t\t4 xn-component of xn+y argument ([+-]?\\d*n|)\n\t\t\t\t5 sign of xn-component\n\t\t\t\t6 x of xn-component\n\t\t\t\t7 sign of y-component\n\t\t\t\t8 y of y-component\n\t\t\t*/\n\t\t\tmatch[ 1 ] = match[ 1 ].toLowerCase();\n\n\t\t\tif ( match[ 1 ].slice( 0, 3 ) === \"nth\" ) {\n\n\t\t\t\t// nth-* requires argument\n\t\t\t\tif ( !match[ 3 ] ) {\n\t\t\t\t\tSizzle.error( match[ 0 ] );\n\t\t\t\t}\n\n\t\t\t\t// numeric x and y parameters for Expr.filter.CHILD\n\t\t\t\t// remember that false/true cast respectively to 0/1\n\t\t\t\tmatch[ 4 ] = +( match[ 4 ] ?\n\t\t\t\t\tmatch[ 5 ] + ( match[ 6 ] || 1 ) :\n\t\t\t\t\t2 * ( match[ 3 ] === \"even\" || match[ 3 ] === \"odd\" ) );\n\t\t\t\tmatch[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === \"odd\" );\n\n\t\t\t\t// other types prohibit arguments\n\t\t\t} else if ( match[ 3 ] ) {\n\t\t\t\tSizzle.error( match[ 0 ] );\n\t\t\t}\n\n\t\t\treturn match;\n\t\t},\n\n\t\t\"PSEUDO\": function( match ) {\n\t\t\tvar excess,\n\t\t\t\tunquoted = !match[ 6 ] && match[ 2 ];\n\n\t\t\tif ( matchExpr[ \"CHILD\" ].test( match[ 0 ] ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t// Accept quoted arguments as-is\n\t\t\tif ( match[ 3 ] ) {\n\t\t\t\tmatch[ 2 ] = match[ 4 ] || match[ 5 ] || \"\";\n\n\t\t\t// Strip excess characters from unquoted arguments\n\t\t\t} else if ( unquoted && rpseudo.test( unquoted ) &&\n\n\t\t\t\t// Get excess from tokenize (recursively)\n\t\t\t\t( excess = tokenize( unquoted, true ) ) &&\n\n\t\t\t\t// advance to the next closing parenthesis\n\t\t\t\t( excess = unquoted.indexOf( \")\", unquoted.length - excess ) - unquoted.length ) ) {\n\n\t\t\t\t// excess is a negative index\n\t\t\t\tmatch[ 0 ] = match[ 0 ].slice( 0, excess );\n\t\t\t\tmatch[ 2 ] = unquoted.slice( 0, excess );\n\t\t\t}\n\n\t\t\t// Return only captures needed by the pseudo filter method (type and argument)\n\t\t\treturn match.slice( 0, 3 );\n\t\t}\n\t},\n\n\tfilter: {\n\n\t\t\"TAG\": function( nodeNameSelector ) {\n\t\t\tvar nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn nodeNameSelector === \"*\" ?\n\t\t\t\tfunction() {\n\t\t\t\t\treturn true;\n\t\t\t\t} :\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === nodeName;\n\t\t\t\t};\n\t\t},\n\n\t\t\"CLASS\": function( className ) {\n\t\t\tvar pattern = classCache[ className + \" \" ];\n\n\t\t\treturn pattern ||\n\t\t\t\t( pattern = new RegExp( \"(^|\" + whitespace +\n\t\t\t\t\t\")\" + className + \"(\" + whitespace + \"|$)\" ) ) && classCache(\n\t\t\t\t\t\tclassName, function( elem ) {\n\t\t\t\t\t\t\treturn pattern.test(\n\t\t\t\t\t\t\t\ttypeof elem.className === \"string\" && elem.className ||\n\t\t\t\t\t\t\t\ttypeof elem.getAttribute !== \"undefined\" &&\n\t\t\t\t\t\t\t\t\telem.getAttribute( \"class\" ) ||\n\t\t\t\t\t\t\t\t\"\"\n\t\t\t\t\t\t\t);\n\t\t\t\t} );\n\t\t},\n\n\t\t\"ATTR\": function( name, operator, check ) {\n\t\t\treturn function( elem ) {\n\t\t\t\tvar result = Sizzle.attr( elem, name );\n\n\t\t\t\tif ( result == null ) {\n\t\t\t\t\treturn operator === \"!=\";\n\t\t\t\t}\n\t\t\t\tif ( !operator ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tresult += \"\";\n\n\t\t\t\t/* eslint-disable max-len */\n\n\t\t\t\treturn operator === \"=\" ? result === check :\n\t\t\t\t\toperator === \"!=\" ? result !== check :\n\t\t\t\t\toperator === \"^=\" ? check && result.indexOf( check ) === 0 :\n\t\t\t\t\toperator === \"*=\" ? check && result.indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"$=\" ? check && result.slice( -check.length ) === check :\n\t\t\t\t\toperator === \"~=\" ? ( \" \" + result.replace( rwhitespace, \" \" ) + \" \" ).indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"|=\" ? result === check || result.slice( 0, check.length + 1 ) === check + \"-\" :\n\t\t\t\t\tfalse;\n\t\t\t\t/* eslint-enable max-len */\n\n\t\t\t};\n\t\t},\n\n\t\t\"CHILD\": function( type, what, _argument, first, last ) {\n\t\t\tvar simple = type.slice( 0, 3 ) !== \"nth\",\n\t\t\t\tforward = type.slice( -4 ) !== \"last\",\n\t\t\t\tofType = what === \"of-type\";\n\n\t\t\treturn first === 1 && last === 0 ?\n\n\t\t\t\t// Shortcut for :nth-*(n)\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn !!elem.parentNode;\n\t\t\t\t} :\n\n\t\t\t\tfunction( elem, _context, xml ) {\n\t\t\t\t\tvar cache, uniqueCache, outerCache, node, nodeIndex, start,\n\t\t\t\t\t\tdir = simple !== forward ? \"nextSibling\" : \"previousSibling\",\n\t\t\t\t\t\tparent = elem.parentNode,\n\t\t\t\t\t\tname = ofType && elem.nodeName.toLowerCase(),\n\t\t\t\t\t\tuseCache = !xml && !ofType,\n\t\t\t\t\t\tdiff = false;\n\n\t\t\t\t\tif ( parent ) {\n\n\t\t\t\t\t\t// :(first|last|only)-(child|of-type)\n\t\t\t\t\t\tif ( simple ) {\n\t\t\t\t\t\t\twhile ( dir ) {\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\twhile ( ( node = node[ dir ] ) ) {\n\t\t\t\t\t\t\t\t\tif ( ofType ?\n\t\t\t\t\t\t\t\t\t\tnode.nodeName.toLowerCase() === name :\n\t\t\t\t\t\t\t\t\t\tnode.nodeType === 1 ) {\n\n\t\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Reverse direction for :only-* (if we haven't yet done so)\n\t\t\t\t\t\t\t\tstart = dir = type === \"only\" && !start && \"nextSibling\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tstart = [ forward ? parent.firstChild : parent.lastChild ];\n\n\t\t\t\t\t\t// non-xml :nth-child(...) stores cache data on `parent`\n\t\t\t\t\t\tif ( forward && useCache ) {\n\n\t\t\t\t\t\t\t// Seek `elem` from a previously-cached index\n\n\t\t\t\t\t\t\t// ...in a gzip-friendly way\n\t\t\t\t\t\t\tnode = parent;\n\t\t\t\t\t\t\touterCache = node[ expando ] || ( node[ expando ] = {} );\n\n\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t( outerCache[ node.uniqueID ] = {} );\n\n\t\t\t\t\t\t\tcache = uniqueCache[ type ] || [];\n\t\t\t\t\t\t\tnodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];\n\t\t\t\t\t\t\tdiff = nodeIndex && cache[ 2 ];\n\t\t\t\t\t\t\tnode = nodeIndex && parent.childNodes[ nodeIndex ];\n\n\t\t\t\t\t\t\twhile ( ( node = ++nodeIndex && node && node[ dir ] ||\n\n\t\t\t\t\t\t\t\t// Fallback to seeking `elem` from the start\n\t\t\t\t\t\t\t\t( diff = nodeIndex = 0 ) || start.pop() ) ) {\n\n\t\t\t\t\t\t\t\t// When found, cache indexes on `parent` and break\n\t\t\t\t\t\t\t\tif ( node.nodeType === 1 && ++diff && node === elem ) {\n\t\t\t\t\t\t\t\t\tuniqueCache[ type ] = [ dirruns, nodeIndex, diff ];\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// Use previously-cached element index if available\n\t\t\t\t\t\t\tif ( useCache ) {\n\n\t\t\t\t\t\t\t\t// ...in a gzip-friendly way\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\touterCache = node[ expando ] || ( node[ expando ] = {} );\n\n\t\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t\t( outerCache[ node.uniqueID ] = {} );\n\n\t\t\t\t\t\t\t\tcache = uniqueCache[ type ] || [];\n\t\t\t\t\t\t\t\tnodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];\n\t\t\t\t\t\t\t\tdiff = nodeIndex;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// xml :nth-child(...)\n\t\t\t\t\t\t\t// or :nth-last-child(...) or :nth(-last)?-of-type(...)\n\t\t\t\t\t\t\tif ( diff === false ) {\n\n\t\t\t\t\t\t\t\t// Use the same loop as above to seek `elem` from the start\n\t\t\t\t\t\t\t\twhile ( ( node = ++nodeIndex && node && node[ dir ] ||\n\t\t\t\t\t\t\t\t\t( diff = nodeIndex = 0 ) || start.pop() ) ) {\n\n\t\t\t\t\t\t\t\t\tif ( ( ofType ?\n\t\t\t\t\t\t\t\t\t\tnode.nodeName.toLowerCase() === name :\n\t\t\t\t\t\t\t\t\t\tnode.nodeType === 1 ) &&\n\t\t\t\t\t\t\t\t\t\t++diff ) {\n\n\t\t\t\t\t\t\t\t\t\t// Cache the index of each encountered element\n\t\t\t\t\t\t\t\t\t\tif ( useCache ) {\n\t\t\t\t\t\t\t\t\t\t\touterCache = node[ expando ] ||\n\t\t\t\t\t\t\t\t\t\t\t\t( node[ expando ] = {} );\n\n\t\t\t\t\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t\t\t\t\t( outerCache[ node.uniqueID ] = {} );\n\n\t\t\t\t\t\t\t\t\t\t\tuniqueCache[ type ] = [ dirruns, diff ];\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tif ( node === elem ) {\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Incorporate the offset, then check against cycle size\n\t\t\t\t\t\tdiff -= last;\n\t\t\t\t\t\treturn diff === first || ( diff % first === 0 && diff / first >= 0 );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t},\n\n\t\t\"PSEUDO\": function( pseudo, argument ) {\n\n\t\t\t// pseudo-class names are case-insensitive\n\t\t\t// http://www.w3.org/TR/selectors/#pseudo-classes\n\t\t\t// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters\n\t\t\t// Remember that setFilters inherits from pseudos\n\t\t\tvar args,\n\t\t\t\tfn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||\n\t\t\t\t\tSizzle.error( \"unsupported pseudo: \" + pseudo );\n\n\t\t\t// The user may use createPseudo to indicate that\n\t\t\t// arguments are needed to create the filter function\n\t\t\t// just as Sizzle does\n\t\t\tif ( fn[ expando ] ) {\n\t\t\t\treturn fn( argument );\n\t\t\t}\n\n\t\t\t// But maintain support for old signatures\n\t\t\tif ( fn.length > 1 ) {\n\t\t\t\targs = [ pseudo, pseudo, \"\", argument ];\n\t\t\t\treturn Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?\n\t\t\t\t\tmarkFunction( function( seed, matches ) {\n\t\t\t\t\t\tvar idx,\n\t\t\t\t\t\t\tmatched = fn( seed, argument ),\n\t\t\t\t\t\t\ti = matched.length;\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tidx = indexOf( seed, matched[ i ] );\n\t\t\t\t\t\t\tseed[ idx ] = !( matches[ idx ] = matched[ i ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t} ) :\n\t\t\t\t\tfunction( elem ) {\n\t\t\t\t\t\treturn fn( elem, 0, args );\n\t\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn fn;\n\t\t}\n\t},\n\n\tpseudos: {\n\n\t\t// Potentially complex pseudos\n\t\t\"not\": markFunction( function( selector ) {\n\n\t\t\t// Trim the selector passed to compile\n\t\t\t// to avoid treating leading and trailing\n\t\t\t// spaces as combinators\n\t\t\tvar input = [],\n\t\t\t\tresults = [],\n\t\t\t\tmatcher = compile( selector.replace( rtrim, \"$1\" ) );\n\n\t\t\treturn matcher[ expando ] ?\n\t\t\t\tmarkFunction( function( seed, matches, _context, xml ) {\n\t\t\t\t\tvar elem,\n\t\t\t\t\t\tunmatched = matcher( seed, null, xml, [] ),\n\t\t\t\t\t\ti = seed.length;\n\n\t\t\t\t\t// Match elements unmatched by `matcher`\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( ( elem = unmatched[ i ] ) ) {\n\t\t\t\t\t\t\tseed[ i ] = !( matches[ i ] = elem );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} ) :\n\t\t\t\tfunction( elem, _context, xml ) {\n\t\t\t\t\tinput[ 0 ] = elem;\n\t\t\t\t\tmatcher( input, null, xml, results );\n\n\t\t\t\t\t// Don't keep the element (issue #299)\n\t\t\t\t\tinput[ 0 ] = null;\n\t\t\t\t\treturn !results.pop();\n\t\t\t\t};\n\t\t} ),\n\n\t\t\"has\": markFunction( function( selector ) {\n\t\t\treturn function( elem ) {\n\t\t\t\treturn Sizzle( selector, elem ).length > 0;\n\t\t\t};\n\t\t} ),\n\n\t\t\"contains\": markFunction( function( text ) {\n\t\t\ttext = text.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn ( elem.textContent || getText( elem ) ).indexOf( text ) > -1;\n\t\t\t};\n\t\t} ),\n\n\t\t// \"Whether an element is represented by a :lang() selector\n\t\t// is based solely on the element's language value\n\t\t// being equal to the identifier C,\n\t\t// or beginning with the identifier C immediately followed by \"-\".\n\t\t// The matching of C against the element's language value is performed case-insensitively.\n\t\t// The identifier C does not have to be a valid language name.\"\n\t\t// http://www.w3.org/TR/selectors/#lang-pseudo\n\t\t\"lang\": markFunction( function( lang ) {\n\n\t\t\t// lang value must be a valid identifier\n\t\t\tif ( !ridentifier.test( lang || \"\" ) ) {\n\t\t\t\tSizzle.error( \"unsupported lang: \" + lang );\n\t\t\t}\n\t\t\tlang = lang.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn function( elem ) {\n\t\t\t\tvar elemLang;\n\t\t\t\tdo {\n\t\t\t\t\tif ( ( elemLang = documentIsHTML ?\n\t\t\t\t\t\telem.lang :\n\t\t\t\t\t\telem.getAttribute( \"xml:lang\" ) || elem.getAttribute( \"lang\" ) ) ) {\n\n\t\t\t\t\t\telemLang = elemLang.toLowerCase();\n\t\t\t\t\t\treturn elemLang === lang || elemLang.indexOf( lang + \"-\" ) === 0;\n\t\t\t\t\t}\n\t\t\t\t} while ( ( elem = elem.parentNode ) && elem.nodeType === 1 );\n\t\t\t\treturn false;\n\t\t\t};\n\t\t} ),\n\n\t\t// Miscellaneous\n\t\t\"target\": function( elem ) {\n\t\t\tvar hash = window.location && window.location.hash;\n\t\t\treturn hash && hash.slice( 1 ) === elem.id;\n\t\t},\n\n\t\t\"root\": function( elem ) {\n\t\t\treturn elem === docElem;\n\t\t},\n\n\t\t\"focus\": function( elem ) {\n\t\t\treturn elem === document.activeElement &&\n\t\t\t\t( !document.hasFocus || document.hasFocus() ) &&\n\t\t\t\t!!( elem.type || elem.href || ~elem.tabIndex );\n\t\t},\n\n\t\t// Boolean properties\n\t\t\"enabled\": createDisabledPseudo( false ),\n\t\t\"disabled\": createDisabledPseudo( true ),\n\n\t\t\"checked\": function( elem ) {\n\n\t\t\t// In CSS3, :checked should return both checked and selected elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\tvar nodeName = elem.nodeName.toLowerCase();\n\t\t\treturn ( nodeName === \"input\" && !!elem.checked ) ||\n\t\t\t\t( nodeName === \"option\" && !!elem.selected );\n\t\t},\n\n\t\t\"selected\": function( elem ) {\n\n\t\t\t// Accessing this property makes selected-by-default\n\t\t\t// options in Safari work properly\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\t// eslint-disable-next-line no-unused-expressions\n\t\t\t\telem.parentNode.selectedIndex;\n\t\t\t}\n\n\t\t\treturn elem.selected === true;\n\t\t},\n\n\t\t// Contents\n\t\t\"empty\": function( elem ) {\n\n\t\t\t// http://www.w3.org/TR/selectors/#empty-pseudo\n\t\t\t// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),\n\t\t\t// but not by others (comment: 8; processing instruction: 7; etc.)\n\t\t\t// nodeType < 6 works because attributes (2) do not appear as children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tif ( elem.nodeType < 6 ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\n\t\t\"parent\": function( elem ) {\n\t\t\treturn !Expr.pseudos[ \"empty\" ]( elem );\n\t\t},\n\n\t\t// Element/input types\n\t\t\"header\": function( elem ) {\n\t\t\treturn rheader.test( elem.nodeName );\n\t\t},\n\n\t\t\"input\": function( elem ) {\n\t\t\treturn rinputs.test( elem.nodeName );\n\t\t},\n\n\t\t\"button\": function( elem ) {\n\t\t\tvar name = elem.nodeName.toLowerCase();\n\t\t\treturn name === \"input\" && elem.type === \"button\" || name === \"button\";\n\t\t},\n\n\t\t\"text\": function( elem ) {\n\t\t\tvar attr;\n\t\t\treturn elem.nodeName.toLowerCase() === \"input\" &&\n\t\t\t\telem.type === \"text\" &&\n\n\t\t\t\t// Support: IE<8\n\t\t\t\t// New HTML5 attribute values (e.g., \"search\") appear with elem.type === \"text\"\n\t\t\t\t( ( attr = elem.getAttribute( \"type\" ) ) == null ||\n\t\t\t\t\tattr.toLowerCase() === \"text\" );\n\t\t},\n\n\t\t// Position-in-collection\n\t\t\"first\": createPositionalPseudo( function() {\n\t\t\treturn [ 0 ];\n\t\t} ),\n\n\t\t\"last\": createPositionalPseudo( function( _matchIndexes, length ) {\n\t\t\treturn [ length - 1 ];\n\t\t} ),\n\n\t\t\"eq\": createPositionalPseudo( function( _matchIndexes, length, argument ) {\n\t\t\treturn [ argument < 0 ? argument + length : argument ];\n\t\t} ),\n\n\t\t\"even\": createPositionalPseudo( function( matchIndexes, length ) {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t} ),\n\n\t\t\"odd\": createPositionalPseudo( function( matchIndexes, length ) {\n\t\t\tvar i = 1;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t} ),\n\n\t\t\"lt\": createPositionalPseudo( function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ?\n\t\t\t\targument + length :\n\t\t\t\targument > length ?\n\t\t\t\t\tlength :\n\t\t\t\t\targument;\n\t\t\tfor ( ; --i >= 0; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t} ),\n\n\t\t\"gt\": createPositionalPseudo( function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; ++i < length; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t} )\n\t}\n};\n\nExpr.pseudos[ \"nth\" ] = Expr.pseudos[ \"eq\" ];\n\n// Add button/input type pseudos\nfor ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {\n\tExpr.pseudos[ i ] = createInputPseudo( i );\n}\nfor ( i in { submit: true, reset: true } ) {\n\tExpr.pseudos[ i ] = createButtonPseudo( i );\n}\n\n// Easy API for creating new setFilters\nfunction setFilters() {}\nsetFilters.prototype = Expr.filters = Expr.pseudos;\nExpr.setFilters = new setFilters();\n\ntokenize = Sizzle.tokenize = function( selector, parseOnly ) {\n\tvar matched, match, tokens, type,\n\t\tsoFar, groups, preFilters,\n\t\tcached = tokenCache[ selector + \" \" ];\n\n\tif ( cached ) {\n\t\treturn parseOnly ? 0 : cached.slice( 0 );\n\t}\n\n\tsoFar = selector;\n\tgroups = [];\n\tpreFilters = Expr.preFilter;\n\n\twhile ( soFar ) {\n\n\t\t// Comma and first run\n\t\tif ( !matched || ( match = rcomma.exec( soFar ) ) ) {\n\t\t\tif ( match ) {\n\n\t\t\t\t// Don't consume trailing commas as valid\n\t\t\t\tsoFar = soFar.slice( match[ 0 ].length ) || soFar;\n\t\t\t}\n\t\t\tgroups.push( ( tokens = [] ) );\n\t\t}\n\n\t\tmatched = false;\n\n\t\t// Combinators\n\t\tif ( ( match = rcombinators.exec( soFar ) ) ) {\n\t\t\tmatched = match.shift();\n\t\t\ttokens.push( {\n\t\t\t\tvalue: matched,\n\n\t\t\t\t// Cast descendant combinators to space\n\t\t\t\ttype: match[ 0 ].replace( rtrim, \" \" )\n\t\t\t} );\n\t\t\tsoFar = soFar.slice( matched.length );\n\t\t}\n\n\t\t// Filters\n\t\tfor ( type in Expr.filter ) {\n\t\t\tif ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] ||\n\t\t\t\t( match = preFilters[ type ]( match ) ) ) ) {\n\t\t\t\tmatched = match.shift();\n\t\t\t\ttokens.push( {\n\t\t\t\t\tvalue: matched,\n\t\t\t\t\ttype: type,\n\t\t\t\t\tmatches: match\n\t\t\t\t} );\n\t\t\t\tsoFar = soFar.slice( matched.length );\n\t\t\t}\n\t\t}\n\n\t\tif ( !matched ) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Return the length of the invalid excess\n\t// if we're just parsing\n\t// Otherwise, throw an error or return tokens\n\treturn parseOnly ?\n\t\tsoFar.length :\n\t\tsoFar ?\n\t\t\tSizzle.error( selector ) :\n\n\t\t\t// Cache the tokens\n\t\t\ttokenCache( selector, groups ).slice( 0 );\n};\n\nfunction toSelector( tokens ) {\n\tvar i = 0,\n\t\tlen = tokens.length,\n\t\tselector = \"\";\n\tfor ( ; i < len; i++ ) {\n\t\tselector += tokens[ i ].value;\n\t}\n\treturn selector;\n}\n\nfunction addCombinator( matcher, combinator, base ) {\n\tvar dir = combinator.dir,\n\t\tskip = combinator.next,\n\t\tkey = skip || dir,\n\t\tcheckNonElements = base && key === \"parentNode\",\n\t\tdoneName = done++;\n\n\treturn combinator.first ?\n\n\t\t// Check against closest ancestor/preceding element\n\t\tfunction( elem, context, xml ) {\n\t\t\twhile ( ( elem = elem[ dir ] ) ) {\n\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\treturn matcher( elem, context, xml );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t} :\n\n\t\t// Check against all ancestor/preceding elements\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar oldCache, uniqueCache, outerCache,\n\t\t\t\tnewCache = [ dirruns, doneName ];\n\n\t\t\t// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching\n\t\t\tif ( xml ) {\n\t\t\t\twhile ( ( elem = elem[ dir ] ) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\twhile ( ( elem = elem[ dir ] ) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\touterCache = elem[ expando ] || ( elem[ expando ] = {} );\n\n\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\tuniqueCache = outerCache[ elem.uniqueID ] ||\n\t\t\t\t\t\t\t( outerCache[ elem.uniqueID ] = {} );\n\n\t\t\t\t\t\tif ( skip && skip === elem.nodeName.toLowerCase() ) {\n\t\t\t\t\t\t\telem = elem[ dir ] || elem;\n\t\t\t\t\t\t} else if ( ( oldCache = uniqueCache[ key ] ) &&\n\t\t\t\t\t\t\toldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {\n\n\t\t\t\t\t\t\t// Assign to newCache so results back-propagate to previous elements\n\t\t\t\t\t\t\treturn ( newCache[ 2 ] = oldCache[ 2 ] );\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// Reuse newcache so results back-propagate to previous elements\n\t\t\t\t\t\t\tuniqueCache[ key ] = newCache;\n\n\t\t\t\t\t\t\t// A match means we're done; a fail means we have to keep checking\n\t\t\t\t\t\t\tif ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) {\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n}\n\nfunction elementMatcher( matchers ) {\n\treturn matchers.length > 1 ?\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar i = matchers.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( !matchers[ i ]( elem, context, xml ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t} :\n\t\tmatchers[ 0 ];\n}\n\nfunction multipleContexts( selector, contexts, results ) {\n\tvar i = 0,\n\t\tlen = contexts.length;\n\tfor ( ; i < len; i++ ) {\n\t\tSizzle( selector, contexts[ i ], results );\n\t}\n\treturn results;\n}\n\nfunction condense( unmatched, map, filter, context, xml ) {\n\tvar elem,\n\t\tnewUnmatched = [],\n\t\ti = 0,\n\t\tlen = unmatched.length,\n\t\tmapped = map != null;\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( ( elem = unmatched[ i ] ) ) {\n\t\t\tif ( !filter || filter( elem, context, xml ) ) {\n\t\t\t\tnewUnmatched.push( elem );\n\t\t\t\tif ( mapped ) {\n\t\t\t\t\tmap.push( i );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn newUnmatched;\n}\n\nfunction setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {\n\tif ( postFilter && !postFilter[ expando ] ) {\n\t\tpostFilter = setMatcher( postFilter );\n\t}\n\tif ( postFinder && !postFinder[ expando ] ) {\n\t\tpostFinder = setMatcher( postFinder, postSelector );\n\t}\n\treturn markFunction( function( seed, results, context, xml ) {\n\t\tvar temp, i, elem,\n\t\t\tpreMap = [],\n\t\t\tpostMap = [],\n\t\t\tpreexisting = results.length,\n\n\t\t\t// Get initial elements from seed or context\n\t\t\telems = seed || multipleContexts(\n\t\t\t\tselector || \"*\",\n\t\t\t\tcontext.nodeType ? [ context ] : context,\n\t\t\t\t[]\n\t\t\t),\n\n\t\t\t// Prefilter to get matcher input, preserving a map for seed-results synchronization\n\t\t\tmatcherIn = preFilter && ( seed || !selector ) ?\n\t\t\t\tcondense( elems, preMap, preFilter, context, xml ) :\n\t\t\t\telems,\n\n\t\t\tmatcherOut = matcher ?\n\n\t\t\t\t// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,\n\t\t\t\tpostFinder || ( seed ? preFilter : preexisting || postFilter ) ?\n\n\t\t\t\t\t// ...intermediate processing is necessary\n\t\t\t\t\t[] :\n\n\t\t\t\t\t// ...otherwise use results directly\n\t\t\t\t\tresults :\n\t\t\t\tmatcherIn;\n\n\t\t// Find primary matches\n\t\tif ( matcher ) {\n\t\t\tmatcher( matcherIn, matcherOut, context, xml );\n\t\t}\n\n\t\t// Apply postFilter\n\t\tif ( postFilter ) {\n\t\t\ttemp = condense( matcherOut, postMap );\n\t\t\tpostFilter( temp, [], context, xml );\n\n\t\t\t// Un-match failing elements by moving them back to matcherIn\n\t\t\ti = temp.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( ( elem = temp[ i ] ) ) {\n\t\t\t\t\tmatcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( seed ) {\n\t\t\tif ( postFinder || preFilter ) {\n\t\t\t\tif ( postFinder ) {\n\n\t\t\t\t\t// Get the final matcherOut by condensing this intermediate into postFinder contexts\n\t\t\t\t\ttemp = [];\n\t\t\t\t\ti = matcherOut.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( ( elem = matcherOut[ i ] ) ) {\n\n\t\t\t\t\t\t\t// Restore matcherIn since elem is not yet a final match\n\t\t\t\t\t\t\ttemp.push( ( matcherIn[ i ] = elem ) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tpostFinder( null, ( matcherOut = [] ), temp, xml );\n\t\t\t\t}\n\n\t\t\t\t// Move matched elements from seed to results to keep them synchronized\n\t\t\t\ti = matcherOut.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tif ( ( elem = matcherOut[ i ] ) &&\n\t\t\t\t\t\t( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) {\n\n\t\t\t\t\t\tseed[ temp ] = !( results[ temp ] = elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Add elements to results, through postFinder if defined\n\t\t} else {\n\t\t\tmatcherOut = condense(\n\t\t\t\tmatcherOut === results ?\n\t\t\t\t\tmatcherOut.splice( preexisting, matcherOut.length ) :\n\t\t\t\t\tmatcherOut\n\t\t\t);\n\t\t\tif ( postFinder ) {\n\t\t\t\tpostFinder( null, results, matcherOut, xml );\n\t\t\t} else {\n\t\t\t\tpush.apply( results, matcherOut );\n\t\t\t}\n\t\t}\n\t} );\n}\n\nfunction matcherFromTokens( tokens ) {\n\tvar checkContext, matcher, j,\n\t\tlen = tokens.length,\n\t\tleadingRelative = Expr.relative[ tokens[ 0 ].type ],\n\t\timplicitRelative = leadingRelative || Expr.relative[ \" \" ],\n\t\ti = leadingRelative ? 1 : 0,\n\n\t\t// The foundational matcher ensures that elements are reachable from top-level context(s)\n\t\tmatchContext = addCombinator( function( elem ) {\n\t\t\treturn elem === checkContext;\n\t\t}, implicitRelative, true ),\n\t\tmatchAnyContext = addCombinator( function( elem ) {\n\t\t\treturn indexOf( checkContext, elem ) > -1;\n\t\t}, implicitRelative, true ),\n\t\tmatchers = [ function( elem, context, xml ) {\n\t\t\tvar ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (\n\t\t\t\t( checkContext = context ).nodeType ?\n\t\t\t\t\tmatchContext( elem, context, xml ) :\n\t\t\t\t\tmatchAnyContext( elem, context, xml ) );\n\n\t\t\t// Avoid hanging onto element (issue #299)\n\t\t\tcheckContext = null;\n\t\t\treturn ret;\n\t\t} ];\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) {\n\t\t\tmatchers = [ addCombinator( elementMatcher( matchers ), matcher ) ];\n\t\t} else {\n\t\t\tmatcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches );\n\n\t\t\t// Return special upon seeing a positional matcher\n\t\t\tif ( matcher[ expando ] ) {\n\n\t\t\t\t// Find the next relative operator (if any) for proper handling\n\t\t\t\tj = ++i;\n\t\t\t\tfor ( ; j < len; j++ ) {\n\t\t\t\t\tif ( Expr.relative[ tokens[ j ].type ] ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn setMatcher(\n\t\t\t\t\ti > 1 && elementMatcher( matchers ),\n\t\t\t\t\ti > 1 && toSelector(\n\n\t\t\t\t\t// If the preceding token was a descendant combinator, insert an implicit any-element `*`\n\t\t\t\t\ttokens\n\t\t\t\t\t\t.slice( 0, i - 1 )\n\t\t\t\t\t\t.concat( { value: tokens[ i - 2 ].type === \" \" ? \"*\" : \"\" } )\n\t\t\t\t\t).replace( rtrim, \"$1\" ),\n\t\t\t\t\tmatcher,\n\t\t\t\t\ti < j && matcherFromTokens( tokens.slice( i, j ) ),\n\t\t\t\t\tj < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ),\n\t\t\t\t\tj < len && toSelector( tokens )\n\t\t\t\t);\n\t\t\t}\n\t\t\tmatchers.push( matcher );\n\t\t}\n\t}\n\n\treturn elementMatcher( matchers );\n}\n\nfunction matcherFromGroupMatchers( elementMatchers, setMatchers ) {\n\tvar bySet = setMatchers.length > 0,\n\t\tbyElement = elementMatchers.length > 0,\n\t\tsuperMatcher = function( seed, context, xml, results, outermost ) {\n\t\t\tvar elem, j, matcher,\n\t\t\t\tmatchedCount = 0,\n\t\t\t\ti = \"0\",\n\t\t\t\tunmatched = seed && [],\n\t\t\t\tsetMatched = [],\n\t\t\t\tcontextBackup = outermostContext,\n\n\t\t\t\t// We must always have either seed elements or outermost context\n\t\t\t\telems = seed || byElement && Expr.find[ \"TAG\" ]( \"*\", outermost ),\n\n\t\t\t\t// Use integer dirruns iff this is the outermost matcher\n\t\t\t\tdirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ),\n\t\t\t\tlen = elems.length;\n\n\t\t\tif ( outermost ) {\n\n\t\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t\t\t// two documents; shallow comparisons work.\n\t\t\t\t// eslint-disable-next-line eqeqeq\n\t\t\t\toutermostContext = context == document || context || outermost;\n\t\t\t}\n\n\t\t\t// Add elements passing elementMatchers directly to results\n\t\t\t// Support: IE<9, Safari\n\t\t\t// Tolerate NodeList properties (IE: \"length\"; Safari: <number>) matching elements by id\n\t\t\tfor ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) {\n\t\t\t\tif ( byElement && elem ) {\n\t\t\t\t\tj = 0;\n\n\t\t\t\t\t// Support: IE 11+, Edge 17 - 18+\n\t\t\t\t\t// IE/Edge sometimes throw a \"Permission denied\" error when strict-comparing\n\t\t\t\t\t// two documents; shallow comparisons work.\n\t\t\t\t\t// eslint-disable-next-line eqeqeq\n\t\t\t\t\tif ( !context && elem.ownerDocument != document ) {\n\t\t\t\t\t\tsetDocument( elem );\n\t\t\t\t\t\txml = !documentIsHTML;\n\t\t\t\t\t}\n\t\t\t\t\twhile ( ( matcher = elementMatchers[ j++ ] ) ) {\n\t\t\t\t\t\tif ( matcher( elem, context || document, xml ) ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( outermost ) {\n\t\t\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Track unmatched elements for set filters\n\t\t\t\tif ( bySet ) {\n\n\t\t\t\t\t// They will have gone through all possible matchers\n\t\t\t\t\tif ( ( elem = !matcher && elem ) ) {\n\t\t\t\t\t\tmatchedCount--;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Lengthen the array for every element, matched or not\n\t\t\t\t\tif ( seed ) {\n\t\t\t\t\t\tunmatched.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// `i` is now the count of elements visited above, and adding it to `matchedCount`\n\t\t\t// makes the latter nonnegative.\n\t\t\tmatchedCount += i;\n\n\t\t\t// Apply set filters to unmatched elements\n\t\t\t// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`\n\t\t\t// equals `i`), unless we didn't visit _any_ elements in the above loop because we have\n\t\t\t// no element matchers and no seed.\n\t\t\t// Incrementing an initially-string \"0\" `i` allows `i` to remain a string only in that\n\t\t\t// case, which will result in a \"00\" `matchedCount` that differs from `i` but is also\n\t\t\t// numerically zero.\n\t\t\tif ( bySet && i !== matchedCount ) {\n\t\t\t\tj = 0;\n\t\t\t\twhile ( ( matcher = setMatchers[ j++ ] ) ) {\n\t\t\t\t\tmatcher( unmatched, setMatched, context, xml );\n\t\t\t\t}\n\n\t\t\t\tif ( seed ) {\n\n\t\t\t\t\t// Reintegrate element matches to eliminate the need for sorting\n\t\t\t\t\tif ( matchedCount > 0 ) {\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tif ( !( unmatched[ i ] || setMatched[ i ] ) ) {\n\t\t\t\t\t\t\t\tsetMatched[ i ] = pop.call( results );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Discard index placeholder values to get only actual matches\n\t\t\t\t\tsetMatched = condense( setMatched );\n\t\t\t\t}\n\n\t\t\t\t// Add matches to results\n\t\t\t\tpush.apply( results, setMatched );\n\n\t\t\t\t// Seedless set matches succeeding multiple successful matchers stipulate sorting\n\t\t\t\tif ( outermost && !seed && setMatched.length > 0 &&\n\t\t\t\t\t( matchedCount + setMatchers.length ) > 1 ) {\n\n\t\t\t\t\tSizzle.uniqueSort( results );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Override manipulation of globals by nested matchers\n\t\t\tif ( outermost ) {\n\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\toutermostContext = contextBackup;\n\t\t\t}\n\n\t\t\treturn unmatched;\n\t\t};\n\n\treturn bySet ?\n\t\tmarkFunction( superMatcher ) :\n\t\tsuperMatcher;\n}\n\ncompile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {\n\tvar i,\n\t\tsetMatchers = [],\n\t\telementMatchers = [],\n\t\tcached = compilerCache[ selector + \" \" ];\n\n\tif ( !cached ) {\n\n\t\t// Generate a function of recursive functions that can be used to check each element\n\t\tif ( !match ) {\n\t\t\tmatch = tokenize( selector );\n\t\t}\n\t\ti = match.length;\n\t\twhile ( i-- ) {\n\t\t\tcached = matcherFromTokens( match[ i ] );\n\t\t\tif ( cached[ expando ] ) {\n\t\t\t\tsetMatchers.push( cached );\n\t\t\t} else {\n\t\t\t\telementMatchers.push( cached );\n\t\t\t}\n\t\t}\n\n\t\t// Cache the compiled function\n\t\tcached = compilerCache(\n\t\t\tselector,\n\t\t\tmatcherFromGroupMatchers( elementMatchers, setMatchers )\n\t\t);\n\n\t\t// Save selector and tokenization\n\t\tcached.selector = selector;\n\t}\n\treturn cached;\n};\n\n/**\n * A low-level selection function that works with Sizzle's compiled\n * selector functions\n * @param {String|Function} selector A selector or a pre-compiled\n * selector function built with Sizzle.compile\n * @param {Element} context\n * @param {Array} [results]\n * @param {Array} [seed] A set of elements to match against\n */\nselect = Sizzle.select = function( selector, context, results, seed ) {\n\tvar i, tokens, token, type, find,\n\t\tcompiled = typeof selector === \"function\" && selector,\n\t\tmatch = !seed && tokenize( ( selector = compiled.selector || selector ) );\n\n\tresults = results || [];\n\n\t// Try to minimize operations if there is only one selector in the list and no seed\n\t// (the latter of which guarantees us context)\n\tif ( match.length === 1 ) {\n\n\t\t// Reduce context if the leading compound selector is an ID\n\t\ttokens = match[ 0 ] = match[ 0 ].slice( 0 );\n\t\tif ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === \"ID\" &&\n\t\t\tcontext.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) {\n\n\t\t\tcontext = ( Expr.find[ \"ID\" ]( token.matches[ 0 ]\n\t\t\t\t.replace( runescape, funescape ), context ) || [] )[ 0 ];\n\t\t\tif ( !context ) {\n\t\t\t\treturn results;\n\n\t\t\t// Precompiled matchers will still verify ancestry, so step up a level\n\t\t\t} else if ( compiled ) {\n\t\t\t\tcontext = context.parentNode;\n\t\t\t}\n\n\t\t\tselector = selector.slice( tokens.shift().value.length );\n\t\t}\n\n\t\t// Fetch a seed set for right-to-left matching\n\t\ti = matchExpr[ \"needsContext\" ].test( selector ) ? 0 : tokens.length;\n\t\twhile ( i-- ) {\n\t\t\ttoken = tokens[ i ];\n\n\t\t\t// Abort if we hit a combinator\n\t\t\tif ( Expr.relative[ ( type = token.type ) ] ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( ( find = Expr.find[ type ] ) ) {\n\n\t\t\t\t// Search, expanding context for leading sibling combinators\n\t\t\t\tif ( ( seed = find(\n\t\t\t\t\ttoken.matches[ 0 ].replace( runescape, funescape ),\n\t\t\t\t\trsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) ||\n\t\t\t\t\t\tcontext\n\t\t\t\t) ) ) {\n\n\t\t\t\t\t// If seed is empty or no tokens remain, we can return early\n\t\t\t\t\ttokens.splice( i, 1 );\n\t\t\t\t\tselector = seed.length && toSelector( tokens );\n\t\t\t\t\tif ( !selector ) {\n\t\t\t\t\t\tpush.apply( results, seed );\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Compile and execute a filtering function if one is not provided\n\t// Provide `match` to avoid retokenization if we modified the selector above\n\t( compiled || compile( selector, match ) )(\n\t\tseed,\n\t\tcontext,\n\t\t!documentIsHTML,\n\t\tresults,\n\t\t!context || rsibling.test( selector ) && testContext( context.parentNode ) || context\n\t);\n\treturn results;\n};\n\n// One-time assignments\n\n// Sort stability\nsupport.sortStable = expando.split( \"\" ).sort( sortOrder ).join( \"\" ) === expando;\n\n// Support: Chrome 14-35+\n// Always assume duplicates if they aren't passed to the comparison function\nsupport.detectDuplicates = !!hasDuplicate;\n\n// Initialize against the default document\nsetDocument();\n\n// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)\n// Detached nodes confoundingly follow *each other*\nsupport.sortDetached = assert( function( el ) {\n\n\t// Should return 1, but returns 4 (following)\n\treturn el.compareDocumentPosition( document.createElement( \"fieldset\" ) ) & 1;\n} );\n\n// Support: IE<8\n// Prevent attribute/property \"interpolation\"\n// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx\nif ( !assert( function( el ) {\n\tel.innerHTML = \"<a href='#'></a>\";\n\treturn el.firstChild.getAttribute( \"href\" ) === \"#\";\n} ) ) {\n\taddHandle( \"type|href|height|width\", function( elem, name, isXML ) {\n\t\tif ( !isXML ) {\n\t\t\treturn elem.getAttribute( name, name.toLowerCase() === \"type\" ? 1 : 2 );\n\t\t}\n\t} );\n}\n\n// Support: IE<9\n// Use defaultValue in place of getAttribute(\"value\")\nif ( !support.attributes || !assert( function( el ) {\n\tel.innerHTML = \"<input/>\";\n\tel.firstChild.setAttribute( \"value\", \"\" );\n\treturn el.firstChild.getAttribute( \"value\" ) === \"\";\n} ) ) {\n\taddHandle( \"value\", function( elem, _name, isXML ) {\n\t\tif ( !isXML && elem.nodeName.toLowerCase() === \"input\" ) {\n\t\t\treturn elem.defaultValue;\n\t\t}\n\t} );\n}\n\n// Support: IE<9\n// Use getAttributeNode to fetch booleans when getAttribute lies\nif ( !assert( function( el ) {\n\treturn el.getAttribute( \"disabled\" ) == null;\n} ) ) {\n\taddHandle( booleans, function( elem, name, isXML ) {\n\t\tvar val;\n\t\tif ( !isXML ) {\n\t\t\treturn elem[ name ] === true ? name.toLowerCase() :\n\t\t\t\t( val = elem.getAttributeNode( name ) ) && val.specified ?\n\t\t\t\t\tval.value :\n\t\t\t\t\tnull;\n\t\t}\n\t} );\n}\n\nreturn Sizzle;\n\n} )( window );\n\n\n\njQuery.find = Sizzle;\njQuery.expr = Sizzle.selectors;\n\n// Deprecated\njQuery.expr[ \":\" ] = jQuery.expr.pseudos;\njQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;\njQuery.text = Sizzle.getText;\njQuery.isXMLDoc = Sizzle.isXML;\njQuery.contains = Sizzle.contains;\njQuery.escapeSelector = Sizzle.escape;\n\n\n\n\nvar dir = function( elem, dir, until ) {\n\tvar matched = [],\n\t\ttruncate = until !== undefined;\n\n\twhile ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {\n\t\tif ( elem.nodeType === 1 ) {\n\t\t\tif ( truncate && jQuery( elem ).is( until ) ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tmatched.push( elem );\n\t\t}\n\t}\n\treturn matched;\n};\n\n\nvar siblings = function( n, elem ) {\n\tvar matched = [];\n\n\tfor ( ; n; n = n.nextSibling ) {\n\t\tif ( n.nodeType === 1 && n !== elem ) {\n\t\t\tmatched.push( n );\n\t\t}\n\t}\n\n\treturn matched;\n};\n\n\nvar rneedsContext = jQuery.expr.match.needsContext;\n\n\n\nfunction nodeName( elem, name ) {\n\n\treturn elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();\n\n}\nvar rsingleTag = ( /^<([a-z][^\\/\\0>:\\x20\\t\\r\\n\\f]*)[\\x20\\t\\r\\n\\f]*\\/?>(?:<\\/\\1>|)$/i );\n\n\n\n// Implement the identical functionality for filter and not\nfunction winnow( elements, qualifier, not ) {\n\tif ( isFunction( qualifier ) ) {\n\t\treturn jQuery.grep( elements, function( elem, i ) {\n\t\t\treturn !!qualifier.call( elem, i, elem ) !== not;\n\t\t} );\n\t}\n\n\t// Single element\n\tif ( qualifier.nodeType ) {\n\t\treturn jQuery.grep( elements, function( elem ) {\n\t\t\treturn ( elem === qualifier ) !== not;\n\t\t} );\n\t}\n\n\t// Arraylike of elements (jQuery, arguments, Array)\n\tif ( typeof qualifier !== \"string\" ) {\n\t\treturn jQuery.grep( elements, function( elem ) {\n\t\t\treturn ( indexOf.call( qualifier, elem ) > -1 ) !== not;\n\t\t} );\n\t}\n\n\t// Filtered directly for both simple and complex selectors\n\treturn jQuery.filter( qualifier, elements, not );\n}\n\njQuery.filter = function( expr, elems, not ) {\n\tvar elem = elems[ 0 ];\n\n\tif ( not ) {\n\t\texpr = \":not(\" + expr + \")\";\n\t}\n\n\tif ( elems.length === 1 && elem.nodeType === 1 ) {\n\t\treturn jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];\n\t}\n\n\treturn jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {\n\t\treturn elem.nodeType === 1;\n\t} ) );\n};\n\njQuery.fn.extend( {\n\tfind: function( selector ) {\n\t\tvar i, ret,\n\t\t\tlen = this.length,\n\t\t\tself = this;\n\n\t\tif ( typeof selector !== \"string\" ) {\n\t\t\treturn this.pushStack( jQuery( selector ).filter( function() {\n\t\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\t\tif ( jQuery.contains( self[ i ], this ) ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} ) );\n\t\t}\n\n\t\tret = this.pushStack( [] );\n\n\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\tjQuery.find( selector, self[ i ], ret );\n\t\t}\n\n\t\treturn len > 1 ? jQuery.uniqueSort( ret ) : ret;\n\t},\n\tfilter: function( selector ) {\n\t\treturn this.pushStack( winnow( this, selector || [], false ) );\n\t},\n\tnot: function( selector ) {\n\t\treturn this.pushStack( winnow( this, selector || [], true ) );\n\t},\n\tis: function( selector ) {\n\t\treturn !!winnow(\n\t\t\tthis,\n\n\t\t\t// If this is a positional/relative selector, check membership in the returned set\n\t\t\t// so $(\"p:first\").is(\"p:last\") won't return true for a doc with two \"p\".\n\t\t\ttypeof selector === \"string\" && rneedsContext.test( selector ) ?\n\t\t\t\tjQuery( selector ) :\n\t\t\t\tselector || [],\n\t\t\tfalse\n\t\t).length;\n\t}\n} );\n\n\n// Initialize a jQuery object\n\n\n// A central reference to the root jQuery(document)\nvar rootjQuery,\n\n\t// A simple way to check for HTML strings\n\t// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)\n\t// Strict HTML recognition (#11290: must start with <)\n\t// Shortcut simple #id case for speed\n\trquickExpr = /^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]+))$/,\n\n\tinit = jQuery.fn.init = function( selector, context, root ) {\n\t\tvar match, elem;\n\n\t\t// HANDLE: $(\"\"), $(null), $(undefined), $(false)\n\t\tif ( !selector ) {\n\t\t\treturn this;\n\t\t}\n\n\t\t// Method init() accepts an alternate rootjQuery\n\t\t// so migrate can support jQuery.sub (gh-2101)\n\t\troot = root || rootjQuery;\n\n\t\t// Handle HTML strings\n\t\tif ( typeof selector === \"string\" ) {\n\t\t\tif ( selector[ 0 ] === \"<\" &&\n\t\t\t\tselector[ selector.length - 1 ] === \">\" &&\n\t\t\t\tselector.length >= 3 ) {\n\n\t\t\t\t// Assume that strings that start and end with <> are HTML and skip the regex check\n\t\t\t\tmatch = [ null, selector, null ];\n\n\t\t\t} else {\n\t\t\t\tmatch = rquickExpr.exec( selector );\n\t\t\t}\n\n\t\t\t// Match html or make sure no context is specified for #id\n\t\t\tif ( match && ( match[ 1 ] || !context ) ) {\n\n\t\t\t\t// HANDLE: $(html) -> $(array)\n\t\t\t\tif ( match[ 1 ] ) {\n\t\t\t\t\tcontext = context instanceof jQuery ? context[ 0 ] : context;\n\n\t\t\t\t\t// Option to run scripts is true for back-compat\n\t\t\t\t\t// Intentionally let the error be thrown if parseHTML is not present\n\t\t\t\t\tjQuery.merge( this, jQuery.parseHTML(\n\t\t\t\t\t\tmatch[ 1 ],\n\t\t\t\t\t\tcontext && context.nodeType ? context.ownerDocument || context : document,\n\t\t\t\t\t\ttrue\n\t\t\t\t\t) );\n\n\t\t\t\t\t// HANDLE: $(html, props)\n\t\t\t\t\tif ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {\n\t\t\t\t\t\tfor ( match in context ) {\n\n\t\t\t\t\t\t\t// Properties of context are called as methods if possible\n\t\t\t\t\t\t\tif ( isFunction( this[ match ] ) ) {\n\t\t\t\t\t\t\t\tthis[ match ]( context[ match ] );\n\n\t\t\t\t\t\t\t// ...and otherwise set as attributes\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.attr( match, context[ match ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t// HANDLE: $(#id)\n\t\t\t\t} else {\n\t\t\t\t\telem = document.getElementById( match[ 2 ] );\n\n\t\t\t\t\tif ( elem ) {\n\n\t\t\t\t\t\t// Inject the element directly into the jQuery object\n\t\t\t\t\t\tthis[ 0 ] = elem;\n\t\t\t\t\t\tthis.length = 1;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\n\t\t\t// HANDLE: $(expr, $(...))\n\t\t\t} else if ( !context || context.jquery ) {\n\t\t\t\treturn ( context || root ).find( selector );\n\n\t\t\t// HANDLE: $(expr, context)\n\t\t\t// (which is just equivalent to: $(context).find(expr)\n\t\t\t} else {\n\t\t\t\treturn this.constructor( context ).find( selector );\n\t\t\t}\n\n\t\t// HANDLE: $(DOMElement)\n\t\t} else if ( selector.nodeType ) {\n\t\t\tthis[ 0 ] = selector;\n\t\t\tthis.length = 1;\n\t\t\treturn this;\n\n\t\t// HANDLE: $(function)\n\t\t// Shortcut for document ready\n\t\t} else if ( isFunction( selector ) ) {\n\t\t\treturn root.ready !== undefined ?\n\t\t\t\troot.ready( selector ) :\n\n\t\t\t\t// Execute immediately if ready is not present\n\t\t\t\tselector( jQuery );\n\t\t}\n\n\t\treturn jQuery.makeArray( selector, this );\n\t};\n\n// Give the init function the jQuery prototype for later instantiation\ninit.prototype = jQuery.fn;\n\n// Initialize central reference\nrootjQuery = jQuery( document );\n\n\nvar rparentsprev = /^(?:parents|prev(?:Until|All))/,\n\n\t// Methods guaranteed to produce a unique set when starting from a unique set\n\tguaranteedUnique = {\n\t\tchildren: true,\n\t\tcontents: true,\n\t\tnext: true,\n\t\tprev: true\n\t};\n\njQuery.fn.extend( {\n\thas: function( target ) {\n\t\tvar targets = jQuery( target, this ),\n\t\t\tl = targets.length;\n\n\t\treturn this.filter( function() {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tif ( jQuery.contains( this, targets[ i ] ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t},\n\n\tclosest: function( selectors, context ) {\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tmatched = [],\n\t\t\ttargets = typeof selectors !== \"string\" && jQuery( selectors );\n\n\t\t// Positional selectors never match, since there's no _selection_ context\n\t\tif ( !rneedsContext.test( selectors ) ) {\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tfor ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {\n\n\t\t\t\t\t// Always skip document fragments\n\t\t\t\t\tif ( cur.nodeType < 11 && ( targets ?\n\t\t\t\t\t\ttargets.index( cur ) > -1 :\n\n\t\t\t\t\t\t// Don't pass non-elements to Sizzle\n\t\t\t\t\t\tcur.nodeType === 1 &&\n\t\t\t\t\t\t\tjQuery.find.matchesSelector( cur, selectors ) ) ) {\n\n\t\t\t\t\t\tmatched.push( cur );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );\n\t},\n\n\t// Determine the position of an element within the set\n\tindex: function( elem ) {\n\n\t\t// No argument, return index in parent\n\t\tif ( !elem ) {\n\t\t\treturn ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;\n\t\t}\n\n\t\t// Index in selector\n\t\tif ( typeof elem === \"string\" ) {\n\t\t\treturn indexOf.call( jQuery( elem ), this[ 0 ] );\n\t\t}\n\n\t\t// Locate the position of the desired element\n\t\treturn indexOf.call( this,\n\n\t\t\t// If it receives a jQuery object, the first element is used\n\t\t\telem.jquery ? elem[ 0 ] : elem\n\t\t);\n\t},\n\n\tadd: function( selector, context ) {\n\t\treturn this.pushStack(\n\t\t\tjQuery.uniqueSort(\n\t\t\t\tjQuery.merge( this.get(), jQuery( selector, context ) )\n\t\t\t)\n\t\t);\n\t},\n\n\taddBack: function( selector ) {\n\t\treturn this.add( selector == null ?\n\t\t\tthis.prevObject : this.prevObject.filter( selector )\n\t\t);\n\t}\n} );\n\nfunction sibling( cur, dir ) {\n\twhile ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}\n\treturn cur;\n}\n\njQuery.each( {\n\tparent: function( elem ) {\n\t\tvar parent = elem.parentNode;\n\t\treturn parent && parent.nodeType !== 11 ? parent : null;\n\t},\n\tparents: function( elem ) {\n\t\treturn dir( elem, \"parentNode\" );\n\t},\n\tparentsUntil: function( elem, _i, until ) {\n\t\treturn dir( elem, \"parentNode\", until );\n\t},\n\tnext: function( elem ) {\n\t\treturn sibling( elem, \"nextSibling\" );\n\t},\n\tprev: function( elem ) {\n\t\treturn sibling( elem, \"previousSibling\" );\n\t},\n\tnextAll: function( elem ) {\n\t\treturn dir( elem, \"nextSibling\" );\n\t},\n\tprevAll: function( elem ) {\n\t\treturn dir( elem, \"previousSibling\" );\n\t},\n\tnextUntil: function( elem, _i, until ) {\n\t\treturn dir( elem, \"nextSibling\", until );\n\t},\n\tprevUntil: function( elem, _i, until ) {\n\t\treturn dir( elem, \"previousSibling\", until );\n\t},\n\tsiblings: function( elem ) {\n\t\treturn siblings( ( elem.parentNode || {} ).firstChild, elem );\n\t},\n\tchildren: function( elem ) {\n\t\treturn siblings( elem.firstChild );\n\t},\n\tcontents: function( elem ) {\n\t\tif ( elem.contentDocument != null &&\n\n\t\t\t// Support: IE 11+\n\t\t\t// <object> elements with no `data` attribute has an object\n\t\t\t// `contentDocument` with a `null` prototype.\n\t\t\tgetProto( elem.contentDocument ) ) {\n\n\t\t\treturn elem.contentDocument;\n\t\t}\n\n\t\t// Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only\n\t\t// Treat the template element as a regular one in browsers that\n\t\t// don't support it.\n\t\tif ( nodeName( elem, \"template\" ) ) {\n\t\t\telem = elem.content || elem;\n\t\t}\n\n\t\treturn jQuery.merge( [], elem.childNodes );\n\t}\n}, function( name, fn ) {\n\tjQuery.fn[ name ] = function( until, selector ) {\n\t\tvar matched = jQuery.map( this, fn, until );\n\n\t\tif ( name.slice( -5 ) !== \"Until\" ) {\n\t\t\tselector = until;\n\t\t}\n\n\t\tif ( selector && typeof selector === \"string\" ) {\n\t\t\tmatched = jQuery.filter( selector, matched );\n\t\t}\n\n\t\tif ( this.length > 1 ) {\n\n\t\t\t// Remove duplicates\n\t\t\tif ( !guaranteedUnique[ name ] ) {\n\t\t\t\tjQuery.uniqueSort( matched );\n\t\t\t}\n\n\t\t\t// Reverse order for parents* and prev-derivatives\n\t\t\tif ( rparentsprev.test( name ) ) {\n\t\t\t\tmatched.reverse();\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched );\n\t};\n} );\nvar rnothtmlwhite = ( /[^\\x20\\t\\r\\n\\f]+/g );\n\n\n\n// Convert String-formatted options into Object-formatted ones\nfunction createOptions( options ) {\n\tvar object = {};\n\tjQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {\n\t\tobject[ flag ] = true;\n\t} );\n\treturn object;\n}\n\n/*\n * Create a callback list using the following parameters:\n *\n *\toptions: an optional list of space-separated options that will change how\n *\t\t\tthe callback list behaves or a more traditional option object\n *\n * By default a callback list will act like an event callback list and can be\n * \"fired\" multiple times.\n *\n * Possible options:\n *\n *\tonce:\t\t\twill ensure the callback list can only be fired once (like a Deferred)\n *\n *\tmemory:\t\t\twill keep track of previous values and will call any callback added\n *\t\t\t\t\tafter the list has been fired right away with the latest \"memorized\"\n *\t\t\t\t\tvalues (like a Deferred)\n *\n *\tunique:\t\t\twill ensure a callback can only be added once (no duplicate in the list)\n *\n *\tstopOnFalse:\tinterrupt callings when a callback returns false\n *\n */\njQuery.Callbacks = function( options ) {\n\n\t// Convert options from String-formatted to Object-formatted if needed\n\t// (we check in cache first)\n\toptions = typeof options === \"string\" ?\n\t\tcreateOptions( options ) :\n\t\tjQuery.extend( {}, options );\n\n\tvar // Flag to know if list is currently firing\n\t\tfiring,\n\n\t\t// Last fire value for non-forgettable lists\n\t\tmemory,\n\n\t\t// Flag to know if list was already fired\n\t\tfired,\n\n\t\t// Flag to prevent firing\n\t\tlocked,\n\n\t\t// Actual callback list\n\t\tlist = [],\n\n\t\t// Queue of execution data for repeatable lists\n\t\tqueue = [],\n\n\t\t// Index of currently firing callback (modified by add/remove as needed)\n\t\tfiringIndex = -1,\n\n\t\t// Fire callbacks\n\t\tfire = function() {\n\n\t\t\t// Enforce single-firing\n\t\t\tlocked = locked || options.once;\n\n\t\t\t// Execute callbacks for all pending executions,\n\t\t\t// respecting firingIndex overrides and runtime changes\n\t\t\tfired = firing = true;\n\t\t\tfor ( ; queue.length; firingIndex = -1 ) {\n\t\t\t\tmemory = queue.shift();\n\t\t\t\twhile ( ++firingIndex < list.length ) {\n\n\t\t\t\t\t// Run callback and check for early termination\n\t\t\t\t\tif ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&\n\t\t\t\t\t\toptions.stopOnFalse ) {\n\n\t\t\t\t\t\t// Jump to end and forget the data so .add doesn't re-fire\n\t\t\t\t\t\tfiringIndex = list.length;\n\t\t\t\t\t\tmemory = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Forget the data if we're done with it\n\t\t\tif ( !options.memory ) {\n\t\t\t\tmemory = false;\n\t\t\t}\n\n\t\t\tfiring = false;\n\n\t\t\t// Clean up if we're done firing for good\n\t\t\tif ( locked ) {\n\n\t\t\t\t// Keep an empty list if we have data for future add calls\n\t\t\t\tif ( memory ) {\n\t\t\t\t\tlist = [];\n\n\t\t\t\t// Otherwise, this object is spent\n\t\t\t\t} else {\n\t\t\t\t\tlist = \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t// Actual Callbacks object\n\t\tself = {\n\n\t\t\t// Add a callback or a collection of callbacks to the list\n\t\t\tadd: function() {\n\t\t\t\tif ( list ) {\n\n\t\t\t\t\t// If we have memory from a past run, we should fire after adding\n\t\t\t\t\tif ( memory && !firing ) {\n\t\t\t\t\t\tfiringIndex = list.length - 1;\n\t\t\t\t\t\tqueue.push( memory );\n\t\t\t\t\t}\n\n\t\t\t\t\t( function add( args ) {\n\t\t\t\t\t\tjQuery.each( args, function( _, arg ) {\n\t\t\t\t\t\t\tif ( isFunction( arg ) ) {\n\t\t\t\t\t\t\t\tif ( !options.unique || !self.has( arg ) ) {\n\t\t\t\t\t\t\t\t\tlist.push( arg );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if ( arg && arg.length && toType( arg ) !== \"string\" ) {\n\n\t\t\t\t\t\t\t\t// Inspect recursively\n\t\t\t\t\t\t\t\tadd( arg );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} );\n\t\t\t\t\t} )( arguments );\n\n\t\t\t\t\tif ( memory && !firing ) {\n\t\t\t\t\t\tfire();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Remove a callback from the list\n\t\t\tremove: function() {\n\t\t\t\tjQuery.each( arguments, function( _, arg ) {\n\t\t\t\t\tvar index;\n\t\t\t\t\twhile ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {\n\t\t\t\t\t\tlist.splice( index, 1 );\n\n\t\t\t\t\t\t// Handle firing indexes\n\t\t\t\t\t\tif ( index <= firingIndex ) {\n\t\t\t\t\t\t\tfiringIndex--;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Check if a given callback is in the list.\n\t\t\t// If no argument is given, return whether or not list has callbacks attached.\n\t\t\thas: function( fn ) {\n\t\t\t\treturn fn ?\n\t\t\t\t\tjQuery.inArray( fn, list ) > -1 :\n\t\t\t\t\tlist.length > 0;\n\t\t\t},\n\n\t\t\t// Remove all callbacks from the list\n\t\t\tempty: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\tlist = [];\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Disable .fire and .add\n\t\t\t// Abort any current/pending executions\n\t\t\t// Clear all callbacks and values\n\t\t\tdisable: function() {\n\t\t\t\tlocked = queue = [];\n\t\t\t\tlist = memory = \"\";\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tdisabled: function() {\n\t\t\t\treturn !list;\n\t\t\t},\n\n\t\t\t// Disable .fire\n\t\t\t// Also disable .add unless we have memory (since it would have no effect)\n\t\t\t// Abort any pending executions\n\t\t\tlock: function() {\n\t\t\t\tlocked = queue = [];\n\t\t\t\tif ( !memory && !firing ) {\n\t\t\t\t\tlist = memory = \"\";\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tlocked: function() {\n\t\t\t\treturn !!locked;\n\t\t\t},\n\n\t\t\t// Call all callbacks with the given context and arguments\n\t\t\tfireWith: function( context, args ) {\n\t\t\t\tif ( !locked ) {\n\t\t\t\t\targs = args || [];\n\t\t\t\t\targs = [ context, args.slice ? args.slice() : args ];\n\t\t\t\t\tqueue.push( args );\n\t\t\t\t\tif ( !firing ) {\n\t\t\t\t\t\tfire();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Call all the callbacks with the given arguments\n\t\t\tfire: function() {\n\t\t\t\tself.fireWith( this, arguments );\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// To know if the callbacks have already been called at least once\n\t\t\tfired: function() {\n\t\t\t\treturn !!fired;\n\t\t\t}\n\t\t};\n\n\treturn self;\n};\n\n\nfunction Identity( v ) {\n\treturn v;\n}\nfunction Thrower( ex ) {\n\tthrow ex;\n}\n\nfunction adoptValue( value, resolve, reject, noValue ) {\n\tvar method;\n\n\ttry {\n\n\t\t// Check for promise aspect first to privilege synchronous behavior\n\t\tif ( value && isFunction( ( method = value.promise ) ) ) {\n\t\t\tmethod.call( value ).done( resolve ).fail( reject );\n\n\t\t// Other thenables\n\t\t} else if ( value && isFunction( ( method = value.then ) ) ) {\n\t\t\tmethod.call( value, resolve, reject );\n\n\t\t// Other non-thenables\n\t\t} else {\n\n\t\t\t// Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:\n\t\t\t// * false: [ value ].slice( 0 ) => resolve( value )\n\t\t\t// * true: [ value ].slice( 1 ) => resolve()\n\t\t\tresolve.apply( undefined, [ value ].slice( noValue ) );\n\t\t}\n\n\t// For Promises/A+, convert exceptions into rejections\n\t// Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in\n\t// Deferred#then to conditionally suppress rejection.\n\t} catch ( value ) {\n\n\t\t// Support: Android 4.0 only\n\t\t// Strict mode functions invoked without .call/.apply get global-object context\n\t\treject.apply( undefined, [ value ] );\n\t}\n}\n\njQuery.extend( {\n\n\tDeferred: function( func ) {\n\t\tvar tuples = [\n\n\t\t\t\t// action, add listener, callbacks,\n\t\t\t\t// ... .then handlers, argument index, [final state]\n\t\t\t\t[ \"notify\", \"progress\", jQuery.Callbacks( \"memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"memory\" ), 2 ],\n\t\t\t\t[ \"resolve\", \"done\", jQuery.Callbacks( \"once memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"once memory\" ), 0, \"resolved\" ],\n\t\t\t\t[ \"reject\", \"fail\", jQuery.Callbacks( \"once memory\" ),\n\t\t\t\t\tjQuery.Callbacks( \"once memory\" ), 1, \"rejected\" ]\n\t\t\t],\n\t\t\tstate = \"pending\",\n\t\t\tpromise = {\n\t\t\t\tstate: function() {\n\t\t\t\t\treturn state;\n\t\t\t\t},\n\t\t\t\talways: function() {\n\t\t\t\t\tdeferred.done( arguments ).fail( arguments );\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\t\t\t\t\"catch\": function( fn ) {\n\t\t\t\t\treturn promise.then( null, fn );\n\t\t\t\t},\n\n\t\t\t\t// Keep pipe for back-compat\n\t\t\t\tpipe: function( /* fnDone, fnFail, fnProgress */ ) {\n\t\t\t\t\tvar fns = arguments;\n\n\t\t\t\t\treturn jQuery.Deferred( function( newDefer ) {\n\t\t\t\t\t\tjQuery.each( tuples, function( _i, tuple ) {\n\n\t\t\t\t\t\t\t// Map tuples (progress, done, fail) to arguments (done, fail, progress)\n\t\t\t\t\t\t\tvar fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];\n\n\t\t\t\t\t\t\t// deferred.progress(function() { bind to newDefer or newDefer.notify })\n\t\t\t\t\t\t\t// deferred.done(function() { bind to newDefer or newDefer.resolve })\n\t\t\t\t\t\t\t// deferred.fail(function() { bind to newDefer or newDefer.reject })\n\t\t\t\t\t\t\tdeferred[ tuple[ 1 ] ]( function() {\n\t\t\t\t\t\t\t\tvar returned = fn && fn.apply( this, arguments );\n\t\t\t\t\t\t\t\tif ( returned && isFunction( returned.promise ) ) {\n\t\t\t\t\t\t\t\t\treturned.promise()\n\t\t\t\t\t\t\t\t\t\t.progress( newDefer.notify )\n\t\t\t\t\t\t\t\t\t\t.done( newDefer.resolve )\n\t\t\t\t\t\t\t\t\t\t.fail( newDefer.reject );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tnewDefer[ tuple[ 0 ] + \"With\" ](\n\t\t\t\t\t\t\t\t\t\tthis,\n\t\t\t\t\t\t\t\t\t\tfn ? [ returned ] : arguments\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t} );\n\t\t\t\t\t\tfns = null;\n\t\t\t\t\t} ).promise();\n\t\t\t\t},\n\t\t\t\tthen: function( onFulfilled, onRejected, onProgress ) {\n\t\t\t\t\tvar maxDepth = 0;\n\t\t\t\t\tfunction resolve( depth, deferred, handler, special ) {\n\t\t\t\t\t\treturn function() {\n\t\t\t\t\t\t\tvar that = this,\n\t\t\t\t\t\t\t\targs = arguments,\n\t\t\t\t\t\t\t\tmightThrow = function() {\n\t\t\t\t\t\t\t\t\tvar returned, then;\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.3\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-59\n\t\t\t\t\t\t\t\t\t// Ignore double-resolution attempts\n\t\t\t\t\t\t\t\t\tif ( depth < maxDepth ) {\n\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\treturned = handler.apply( that, args );\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.1\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-48\n\t\t\t\t\t\t\t\t\tif ( returned === deferred.promise() ) {\n\t\t\t\t\t\t\t\t\t\tthrow new TypeError( \"Thenable self-resolution\" );\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Support: Promises/A+ sections 2.3.3.1, 3.5\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-54\n\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-75\n\t\t\t\t\t\t\t\t\t// Retrieve `then` only once\n\t\t\t\t\t\t\t\t\tthen = returned &&\n\n\t\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.4\n\t\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-64\n\t\t\t\t\t\t\t\t\t\t// Only check objects and functions for thenability\n\t\t\t\t\t\t\t\t\t\t( typeof returned === \"object\" ||\n\t\t\t\t\t\t\t\t\t\t\ttypeof returned === \"function\" ) &&\n\t\t\t\t\t\t\t\t\t\treturned.then;\n\n\t\t\t\t\t\t\t\t\t// Handle a returned thenable\n\t\t\t\t\t\t\t\t\tif ( isFunction( then ) ) {\n\n\t\t\t\t\t\t\t\t\t\t// Special processors (notify) just wait for resolution\n\t\t\t\t\t\t\t\t\t\tif ( special ) {\n\t\t\t\t\t\t\t\t\t\t\tthen.call(\n\t\t\t\t\t\t\t\t\t\t\t\treturned,\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Thrower, special )\n\t\t\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\t\t\t\t// Normal processors (resolve) also hook into progress\n\t\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\t\t// ...and disregard older resolution values\n\t\t\t\t\t\t\t\t\t\t\tmaxDepth++;\n\n\t\t\t\t\t\t\t\t\t\t\tthen.call(\n\t\t\t\t\t\t\t\t\t\t\t\treturned,\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Thrower, special ),\n\t\t\t\t\t\t\t\t\t\t\t\tresolve( maxDepth, deferred, Identity,\n\t\t\t\t\t\t\t\t\t\t\t\t\tdeferred.notifyWith )\n\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Handle all other returned values\n\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\t// Only substitute handlers pass on context\n\t\t\t\t\t\t\t\t\t\t// and multiple values (non-spec behavior)\n\t\t\t\t\t\t\t\t\t\tif ( handler !== Identity ) {\n\t\t\t\t\t\t\t\t\t\t\tthat = undefined;\n\t\t\t\t\t\t\t\t\t\t\targs = [ returned ];\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t// Process the value(s)\n\t\t\t\t\t\t\t\t\t\t// Default process is resolve\n\t\t\t\t\t\t\t\t\t\t( special || deferred.resolveWith )( that, args );\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t},\n\n\t\t\t\t\t\t\t\t// Only normal processors (resolve) catch and reject exceptions\n\t\t\t\t\t\t\t\tprocess = special ?\n\t\t\t\t\t\t\t\t\tmightThrow :\n\t\t\t\t\t\t\t\t\tfunction() {\n\t\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\t\tmightThrow();\n\t\t\t\t\t\t\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\t\t\t\t\t\t\tif ( jQuery.Deferred.exceptionHook ) {\n\t\t\t\t\t\t\t\t\t\t\t\tjQuery.Deferred.exceptionHook( e,\n\t\t\t\t\t\t\t\t\t\t\t\t\tprocess.stackTrace );\n\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.4.1\n\t\t\t\t\t\t\t\t\t\t\t// https://promisesaplus.com/#point-61\n\t\t\t\t\t\t\t\t\t\t\t// Ignore post-resolution exceptions\n\t\t\t\t\t\t\t\t\t\t\tif ( depth + 1 >= maxDepth ) {\n\n\t\t\t\t\t\t\t\t\t\t\t\t// Only substitute handlers pass on context\n\t\t\t\t\t\t\t\t\t\t\t\t// and multiple values (non-spec behavior)\n\t\t\t\t\t\t\t\t\t\t\t\tif ( handler !== Thrower ) {\n\t\t\t\t\t\t\t\t\t\t\t\t\tthat = undefined;\n\t\t\t\t\t\t\t\t\t\t\t\t\targs = [ e ];\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t\tdeferred.rejectWith( that, args );\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\t// Support: Promises/A+ section 2.3.3.3.1\n\t\t\t\t\t\t\t// https://promisesaplus.com/#point-57\n\t\t\t\t\t\t\t// Re-resolve promises immediately to dodge false rejection from\n\t\t\t\t\t\t\t// subsequent errors\n\t\t\t\t\t\t\tif ( depth ) {\n\t\t\t\t\t\t\t\tprocess();\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t// Call an optional hook to record the stack, in case of exception\n\t\t\t\t\t\t\t\t// since it's otherwise lost when execution goes async\n\t\t\t\t\t\t\t\tif ( jQuery.Deferred.getStackHook ) {\n\t\t\t\t\t\t\t\t\tprocess.stackTrace = jQuery.Deferred.getStackHook();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\twindow.setTimeout( process );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\treturn jQuery.Deferred( function( newDefer ) {\n\n\t\t\t\t\t\t// progress_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 0 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tisFunction( onProgress ) ?\n\t\t\t\t\t\t\t\t\tonProgress :\n\t\t\t\t\t\t\t\t\tIdentity,\n\t\t\t\t\t\t\t\tnewDefer.notifyWith\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// fulfilled_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 1 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tisFunction( onFulfilled ) ?\n\t\t\t\t\t\t\t\t\tonFulfilled :\n\t\t\t\t\t\t\t\t\tIdentity\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// rejected_handlers.add( ... )\n\t\t\t\t\t\ttuples[ 2 ][ 3 ].add(\n\t\t\t\t\t\t\tresolve(\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\tnewDefer,\n\t\t\t\t\t\t\t\tisFunction( onRejected ) ?\n\t\t\t\t\t\t\t\t\tonRejected :\n\t\t\t\t\t\t\t\t\tThrower\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\t\t\t\t\t} ).promise();\n\t\t\t\t},\n\n\t\t\t\t// Get a promise for this deferred\n\t\t\t\t// If obj is provided, the promise aspect is added to the object\n\t\t\t\tpromise: function( obj ) {\n\t\t\t\t\treturn obj != null ? jQuery.extend( obj, promise ) : promise;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdeferred = {};\n\n\t\t// Add list-specific methods\n\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\tvar list = tuple[ 2 ],\n\t\t\t\tstateString = tuple[ 5 ];\n\n\t\t\t// promise.progress = list.add\n\t\t\t// promise.done = list.add\n\t\t\t// promise.fail = list.add\n\t\t\tpromise[ tuple[ 1 ] ] = list.add;\n\n\t\t\t// Handle state\n\t\t\tif ( stateString ) {\n\t\t\t\tlist.add(\n\t\t\t\t\tfunction() {\n\n\t\t\t\t\t\t// state = \"resolved\" (i.e., fulfilled)\n\t\t\t\t\t\t// state = \"rejected\"\n\t\t\t\t\t\tstate = stateString;\n\t\t\t\t\t},\n\n\t\t\t\t\t// rejected_callbacks.disable\n\t\t\t\t\t// fulfilled_callbacks.disable\n\t\t\t\t\ttuples[ 3 - i ][ 2 ].disable,\n\n\t\t\t\t\t// rejected_handlers.disable\n\t\t\t\t\t// fulfilled_handlers.disable\n\t\t\t\t\ttuples[ 3 - i ][ 3 ].disable,\n\n\t\t\t\t\t// progress_callbacks.lock\n\t\t\t\t\ttuples[ 0 ][ 2 ].lock,\n\n\t\t\t\t\t// progress_handlers.lock\n\t\t\t\t\ttuples[ 0 ][ 3 ].lock\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// progress_handlers.fire\n\t\t\t// fulfilled_handlers.fire\n\t\t\t// rejected_handlers.fire\n\t\t\tlist.add( tuple[ 3 ].fire );\n\n\t\t\t// deferred.notify = function() { deferred.notifyWith(...) }\n\t\t\t// deferred.resolve = function() { deferred.resolveWith(...) }\n\t\t\t// deferred.reject = function() { deferred.rejectWith(...) }\n\t\t\tdeferred[ tuple[ 0 ] ] = function() {\n\t\t\t\tdeferred[ tuple[ 0 ] + \"With\" ]( this === deferred ? undefined : this, arguments );\n\t\t\t\treturn this;\n\t\t\t};\n\n\t\t\t// deferred.notifyWith = list.fireWith\n\t\t\t// deferred.resolveWith = list.fireWith\n\t\t\t// deferred.rejectWith = list.fireWith\n\t\t\tdeferred[ tuple[ 0 ] + \"With\" ] = list.fireWith;\n\t\t} );\n\n\t\t// Make the deferred a promise\n\t\tpromise.promise( deferred );\n\n\t\t// Call given func if any\n\t\tif ( func ) {\n\t\t\tfunc.call( deferred, deferred );\n\t\t}\n\n\t\t// All done!\n\t\treturn deferred;\n\t},\n\n\t// Deferred helper\n\twhen: function( singleValue ) {\n\t\tvar\n\n\t\t\t// count of uncompleted subordinates\n\t\t\tremaining = arguments.length,\n\n\t\t\t// count of unprocessed arguments\n\t\t\ti = remaining,\n\n\t\t\t// subordinate fulfillment data\n\t\t\tresolveContexts = Array( i ),\n\t\t\tresolveValues = slice.call( arguments ),\n\n\t\t\t// the primary Deferred\n\t\t\tprimary = jQuery.Deferred(),\n\n\t\t\t// subordinate callback factory\n\t\t\tupdateFunc = function( i ) {\n\t\t\t\treturn function( value ) {\n\t\t\t\t\tresolveContexts[ i ] = this;\n\t\t\t\t\tresolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;\n\t\t\t\t\tif ( !( --remaining ) ) {\n\t\t\t\t\t\tprimary.resolveWith( resolveContexts, resolveValues );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t};\n\n\t\t// Single- and empty arguments are adopted like Promise.resolve\n\t\tif ( remaining <= 1 ) {\n\t\t\tadoptValue( singleValue, primary.done( updateFunc( i ) ).resolve, primary.reject,\n\t\t\t\t!remaining );\n\n\t\t\t// Use .then() to unwrap secondary thenables (cf. gh-3000)\n\t\t\tif ( primary.state() === \"pending\" ||\n\t\t\t\tisFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {\n\n\t\t\t\treturn primary.then();\n\t\t\t}\n\t\t}\n\n\t\t// Multiple arguments are aggregated like Promise.all array elements\n\t\twhile ( i-- ) {\n\t\t\tadoptValue( resolveValues[ i ], updateFunc( i ), primary.reject );\n\t\t}\n\n\t\treturn primary.promise();\n\t}\n} );\n\n\n// These usually indicate a programmer mistake during development,\n// warn about them ASAP rather than swallowing them by default.\nvar rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;\n\njQuery.Deferred.exceptionHook = function( error, stack ) {\n\n\t// Support: IE 8 - 9 only\n\t// Console exists when dev tools are open, which can happen at any time\n\tif ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {\n\t\twindow.console.warn( \"jQuery.Deferred exception: \" + error.message, error.stack, stack );\n\t}\n};\n\n\n\n\njQuery.readyException = function( error ) {\n\twindow.setTimeout( function() {\n\t\tthrow error;\n\t} );\n};\n\n\n\n\n// The deferred used on DOM ready\nvar readyList = jQuery.Deferred();\n\njQuery.fn.ready = function( fn ) {\n\n\treadyList\n\t\t.then( fn )\n\n\t\t// Wrap jQuery.readyException in a function so that the lookup\n\t\t// happens at the time of error handling instead of callback\n\t\t// registration.\n\t\t.catch( function( error ) {\n\t\t\tjQuery.readyException( error );\n\t\t} );\n\n\treturn this;\n};\n\njQuery.extend( {\n\n\t// Is the DOM ready to be used? Set to true once it occurs.\n\tisReady: false,\n\n\t// A counter to track how many items to wait for before\n\t// the ready event fires. See #6781\n\treadyWait: 1,\n\n\t// Handle when the DOM is ready\n\tready: function( wait ) {\n\n\t\t// Abort if there are pending holds or we're already ready\n\t\tif ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Remember that the DOM is ready\n\t\tjQuery.isReady = true;\n\n\t\t// If a normal DOM Ready event fired, decrement, and wait if need be\n\t\tif ( wait !== true && --jQuery.readyWait > 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If there are functions bound, to execute\n\t\treadyList.resolveWith( document, [ jQuery ] );\n\t}\n} );\n\njQuery.ready.then = readyList.then;\n\n// The ready event handler and self cleanup method\nfunction completed() {\n\tdocument.removeEventListener( \"DOMContentLoaded\", completed );\n\twindow.removeEventListener( \"load\", completed );\n\tjQuery.ready();\n}\n\n// Catch cases where $(document).ready() is called\n// after the browser event has already occurred.\n// Support: IE <=9 - 10 only\n// Older IE sometimes signals \"interactive\" too soon\nif ( document.readyState === \"complete\" ||\n\t( document.readyState !== \"loading\" && !document.documentElement.doScroll ) ) {\n\n\t// Handle it asynchronously to allow scripts the opportunity to delay ready\n\twindow.setTimeout( jQuery.ready );\n\n} else {\n\n\t// Use the handy event callback\n\tdocument.addEventListener( \"DOMContentLoaded\", completed );\n\n\t// A fallback to window.onload, that will always work\n\twindow.addEventListener( \"load\", completed );\n}\n\n\n\n\n// Multifunctional method to get and set values of a collection\n// The value/s can optionally be executed if it's a function\nvar access = function( elems, fn, key, value, chainable, emptyGet, raw ) {\n\tvar i = 0,\n\t\tlen = elems.length,\n\t\tbulk = key == null;\n\n\t// Sets many values\n\tif ( toType( key ) === \"object\" ) {\n\t\tchainable = true;\n\t\tfor ( i in key ) {\n\t\t\taccess( elems, fn, i, key[ i ], true, emptyGet, raw );\n\t\t}\n\n\t// Sets one value\n\t} else if ( value !== undefined ) {\n\t\tchainable = true;\n\n\t\tif ( !isFunction( value ) ) {\n\t\t\traw = true;\n\t\t}\n\n\t\tif ( bulk ) {\n\n\t\t\t// Bulk operations run against the entire set\n\t\t\tif ( raw ) {\n\t\t\t\tfn.call( elems, value );\n\t\t\t\tfn = null;\n\n\t\t\t// ...except when executing function values\n\t\t\t} else {\n\t\t\t\tbulk = fn;\n\t\t\t\tfn = function( elem, _key, value ) {\n\t\t\t\t\treturn bulk.call( jQuery( elem ), value );\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tif ( fn ) {\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\tfn(\n\t\t\t\t\telems[ i ], key, raw ?\n\t\t\t\t\t\tvalue :\n\t\t\t\t\t\tvalue.call( elems[ i ], i, fn( elems[ i ], key ) )\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( chainable ) {\n\t\treturn elems;\n\t}\n\n\t// Gets\n\tif ( bulk ) {\n\t\treturn fn.call( elems );\n\t}\n\n\treturn len ? fn( elems[ 0 ], key ) : emptyGet;\n};\n\n\n// Matches dashed string for camelizing\nvar rmsPrefix = /^-ms-/,\n\trdashAlpha = /-([a-z])/g;\n\n// Used by camelCase as callback to replace()\nfunction fcamelCase( _all, letter ) {\n\treturn letter.toUpperCase();\n}\n\n// Convert dashed to camelCase; used by the css and data modules\n// Support: IE <=9 - 11, Edge 12 - 15\n// Microsoft forgot to hump their vendor prefix (#9572)\nfunction camelCase( string ) {\n\treturn string.replace( rmsPrefix, \"ms-\" ).replace( rdashAlpha, fcamelCase );\n}\nvar acceptData = function( owner ) {\n\n\t// Accepts only:\n\t// - Node\n\t// - Node.ELEMENT_NODE\n\t// - Node.DOCUMENT_NODE\n\t// - Object\n\t// - Any\n\treturn owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );\n};\n\n\n\n\nfunction Data() {\n\tthis.expando = jQuery.expando + Data.uid++;\n}\n\nData.uid = 1;\n\nData.prototype = {\n\n\tcache: function( owner ) {\n\n\t\t// Check if the owner object already has a cache\n\t\tvar value = owner[ this.expando ];\n\n\t\t// If not, create one\n\t\tif ( !value ) {\n\t\t\tvalue = {};\n\n\t\t\t// We can accept data for non-element nodes in modern browsers,\n\t\t\t// but we should not, see #8335.\n\t\t\t// Always return an empty object.\n\t\t\tif ( acceptData( owner ) ) {\n\n\t\t\t\t// If it is a node unlikely to be stringify-ed or looped over\n\t\t\t\t// use plain assignment\n\t\t\t\tif ( owner.nodeType ) {\n\t\t\t\t\towner[ this.expando ] = value;\n\n\t\t\t\t// Otherwise secure it in a non-enumerable property\n\t\t\t\t// configurable must be true to allow the property to be\n\t\t\t\t// deleted when data is removed\n\t\t\t\t} else {\n\t\t\t\t\tObject.defineProperty( owner, this.expando, {\n\t\t\t\t\t\tvalue: value,\n\t\t\t\t\t\tconfigurable: true\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn value;\n\t},\n\tset: function( owner, data, value ) {\n\t\tvar prop,\n\t\t\tcache = this.cache( owner );\n\n\t\t// Handle: [ owner, key, value ] args\n\t\t// Always use camelCase key (gh-2257)\n\t\tif ( typeof data === \"string\" ) {\n\t\t\tcache[ camelCase( data ) ] = value;\n\n\t\t// Handle: [ owner, { properties } ] args\n\t\t} else {\n\n\t\t\t// Copy the properties one-by-one to the cache object\n\t\t\tfor ( prop in data ) {\n\t\t\t\tcache[ camelCase( prop ) ] = data[ prop ];\n\t\t\t}\n\t\t}\n\t\treturn cache;\n\t},\n\tget: function( owner, key ) {\n\t\treturn key === undefined ?\n\t\t\tthis.cache( owner ) :\n\n\t\t\t// Always use camelCase key (gh-2257)\n\t\t\towner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ];\n\t},\n\taccess: function( owner, key, value ) {\n\n\t\t// In cases where either:\n\t\t//\n\t\t// 1. No key was specified\n\t\t// 2. A string key was specified, but no value provided\n\t\t//\n\t\t// Take the \"read\" path and allow the get method to determine\n\t\t// which value to return, respectively either:\n\t\t//\n\t\t// 1. The entire cache object\n\t\t// 2. The data stored at the key\n\t\t//\n\t\tif ( key === undefined ||\n\t\t\t\t( ( key && typeof key === \"string\" ) && value === undefined ) ) {\n\n\t\t\treturn this.get( owner, key );\n\t\t}\n\n\t\t// When the key is not a string, or both a key and value\n\t\t// are specified, set or extend (existing objects) with either:\n\t\t//\n\t\t// 1. An object of properties\n\t\t// 2. A key and value\n\t\t//\n\t\tthis.set( owner, key, value );\n\n\t\t// Since the \"set\" path can have two possible entry points\n\t\t// return the expected data based on which path was taken[*]\n\t\treturn value !== undefined ? value : key;\n\t},\n\tremove: function( owner, key ) {\n\t\tvar i,\n\t\t\tcache = owner[ this.expando ];\n\n\t\tif ( cache === undefined ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( key !== undefined ) {\n\n\t\t\t// Support array or space separated string of keys\n\t\t\tif ( Array.isArray( key ) ) {\n\n\t\t\t\t// If key is an array of keys...\n\t\t\t\t// We always set camelCase keys, so remove that.\n\t\t\t\tkey = key.map( camelCase );\n\t\t\t} else {\n\t\t\t\tkey = camelCase( key );\n\n\t\t\t\t// If a key with the spaces exists, use it.\n\t\t\t\t// Otherwise, create an array by matching non-whitespace\n\t\t\t\tkey = key in cache ?\n\t\t\t\t\t[ key ] :\n\t\t\t\t\t( key.match( rnothtmlwhite ) || [] );\n\t\t\t}\n\n\t\t\ti = key.length;\n\n\t\t\twhile ( i-- ) {\n\t\t\t\tdelete cache[ key[ i ] ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove the expando if there's no more data\n\t\tif ( key === undefined || jQuery.isEmptyObject( cache ) ) {\n\n\t\t\t// Support: Chrome <=35 - 45\n\t\t\t// Webkit & Blink performance suffers when deleting properties\n\t\t\t// from DOM nodes, so set to undefined instead\n\t\t\t// https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)\n\t\t\tif ( owner.nodeType ) {\n\t\t\t\towner[ this.expando ] = undefined;\n\t\t\t} else {\n\t\t\t\tdelete owner[ this.expando ];\n\t\t\t}\n\t\t}\n\t},\n\thasData: function( owner ) {\n\t\tvar cache = owner[ this.expando ];\n\t\treturn cache !== undefined && !jQuery.isEmptyObject( cache );\n\t}\n};\nvar dataPriv = new Data();\n\nvar dataUser = new Data();\n\n\n\n//\tImplementation Summary\n//\n//\t1. Enforce API surface and semantic compatibility with 1.9.x branch\n//\t2. Improve the module's maintainability by reducing the storage\n//\t\tpaths to a single mechanism.\n//\t3. Use the same single mechanism to support \"private\" and \"user\" data.\n//\t4. _Never_ expose \"private\" data to user code (TODO: Drop _data, _removeData)\n//\t5. Avoid exposing implementation details on user objects (eg. expando properties)\n//\t6. Provide a clear path for implementation upgrade to WeakMap in 2014\n\nvar rbrace = /^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,\n\trmultiDash = /[A-Z]/g;\n\nfunction getData( data ) {\n\tif ( data === \"true\" ) {\n\t\treturn true;\n\t}\n\n\tif ( data === \"false\" ) {\n\t\treturn false;\n\t}\n\n\tif ( data === \"null\" ) {\n\t\treturn null;\n\t}\n\n\t// Only convert to a number if it doesn't change the string\n\tif ( data === +data + \"\" ) {\n\t\treturn +data;\n\t}\n\n\tif ( rbrace.test( data ) ) {\n\t\treturn JSON.parse( data );\n\t}\n\n\treturn data;\n}\n\nfunction dataAttr( elem, key, data ) {\n\tvar name;\n\n\t// If nothing was found internally, try to fetch any\n\t// data from the HTML5 data-* attribute\n\tif ( data === undefined && elem.nodeType === 1 ) {\n\t\tname = \"data-\" + key.replace( rmultiDash, \"-$&\" ).toLowerCase();\n\t\tdata = elem.getAttribute( name );\n\n\t\tif ( typeof data === \"string\" ) {\n\t\t\ttry {\n\t\t\t\tdata = getData( data );\n\t\t\t} catch ( e ) {}\n\n\t\t\t// Make sure we set the data so it isn't changed later\n\t\t\tdataUser.set( elem, key, data );\n\t\t} else {\n\t\t\tdata = undefined;\n\t\t}\n\t}\n\treturn data;\n}\n\njQuery.extend( {\n\thasData: function( elem ) {\n\t\treturn dataUser.hasData( elem ) || dataPriv.hasData( elem );\n\t},\n\n\tdata: function( elem, name, data ) {\n\t\treturn dataUser.access( elem, name, data );\n\t},\n\n\tremoveData: function( elem, name ) {\n\t\tdataUser.remove( elem, name );\n\t},\n\n\t// TODO: Now that all calls to _data and _removeData have been replaced\n\t// with direct calls to dataPriv methods, these can be deprecated.\n\t_data: function( elem, name, data ) {\n\t\treturn dataPriv.access( elem, name, data );\n\t},\n\n\t_removeData: function( elem, name ) {\n\t\tdataPriv.remove( elem, name );\n\t}\n} );\n\njQuery.fn.extend( {\n\tdata: function( key, value ) {\n\t\tvar i, name, data,\n\t\t\telem = this[ 0 ],\n\t\t\tattrs = elem && elem.attributes;\n\n\t\t// Gets all values\n\t\tif ( key === undefined ) {\n\t\t\tif ( this.length ) {\n\t\t\t\tdata = dataUser.get( elem );\n\n\t\t\t\tif ( elem.nodeType === 1 && !dataPriv.get( elem, \"hasDataAttrs\" ) ) {\n\t\t\t\t\ti = attrs.length;\n\t\t\t\t\twhile ( i-- ) {\n\n\t\t\t\t\t\t// Support: IE 11 only\n\t\t\t\t\t\t// The attrs elements can be null (#14894)\n\t\t\t\t\t\tif ( attrs[ i ] ) {\n\t\t\t\t\t\t\tname = attrs[ i ].name;\n\t\t\t\t\t\t\tif ( name.indexOf( \"data-\" ) === 0 ) {\n\t\t\t\t\t\t\t\tname = camelCase( name.slice( 5 ) );\n\t\t\t\t\t\t\t\tdataAttr( elem, name, data[ name ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tdataPriv.set( elem, \"hasDataAttrs\", true );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn data;\n\t\t}\n\n\t\t// Sets multiple values\n\t\tif ( typeof key === \"object\" ) {\n\t\t\treturn this.each( function() {\n\t\t\t\tdataUser.set( this, key );\n\t\t\t} );\n\t\t}\n\n\t\treturn access( this, function( value ) {\n\t\t\tvar data;\n\n\t\t\t// The calling jQuery object (element matches) is not empty\n\t\t\t// (and therefore has an element appears at this[ 0 ]) and the\n\t\t\t// `value` parameter was not undefined. An empty jQuery object\n\t\t\t// will result in `undefined` for elem = this[ 0 ] which will\n\t\t\t// throw an exception if an attempt to read a data cache is made.\n\t\t\tif ( elem && value === undefined ) {\n\n\t\t\t\t// Attempt to get data from the cache\n\t\t\t\t// The key will always be camelCased in Data\n\t\t\t\tdata = dataUser.get( elem, key );\n\t\t\t\tif ( data !== undefined ) {\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\n\t\t\t\t// Attempt to \"discover\" the data in\n\t\t\t\t// HTML5 custom data-* attrs\n\t\t\t\tdata = dataAttr( elem, key );\n\t\t\t\tif ( data !== undefined ) {\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\n\t\t\t\t// We tried really hard, but the data doesn't exist.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Set the data...\n\t\t\tthis.each( function() {\n\n\t\t\t\t// We always store the camelCased key\n\t\t\t\tdataUser.set( this, key, value );\n\t\t\t} );\n\t\t}, null, value, arguments.length > 1, null, true );\n\t},\n\n\tremoveData: function( key ) {\n\t\treturn this.each( function() {\n\t\t\tdataUser.remove( this, key );\n\t\t} );\n\t}\n} );\n\n\njQuery.extend( {\n\tqueue: function( elem, type, data ) {\n\t\tvar queue;\n\n\t\tif ( elem ) {\n\t\t\ttype = ( type || \"fx\" ) + \"queue\";\n\t\t\tqueue = dataPriv.get( elem, type );\n\n\t\t\t// Speed up dequeue by getting out quickly if this is just a lookup\n\t\t\tif ( data ) {\n\t\t\t\tif ( !queue || Array.isArray( data ) ) {\n\t\t\t\t\tqueue = dataPriv.access( elem, type, jQuery.makeArray( data ) );\n\t\t\t\t} else {\n\t\t\t\t\tqueue.push( data );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn queue || [];\n\t\t}\n\t},\n\n\tdequeue: function( elem, type ) {\n\t\ttype = type || \"fx\";\n\n\t\tvar queue = jQuery.queue( elem, type ),\n\t\t\tstartLength = queue.length,\n\t\t\tfn = queue.shift(),\n\t\t\thooks = jQuery._queueHooks( elem, type ),\n\t\t\tnext = function() {\n\t\t\t\tjQuery.dequeue( elem, type );\n\t\t\t};\n\n\t\t// If the fx queue is dequeued, always remove the progress sentinel\n\t\tif ( fn === \"inprogress\" ) {\n\t\t\tfn = queue.shift();\n\t\t\tstartLength--;\n\t\t}\n\n\t\tif ( fn ) {\n\n\t\t\t// Add a progress sentinel to prevent the fx queue from being\n\t\t\t// automatically dequeued\n\t\t\tif ( type === \"fx\" ) {\n\t\t\t\tqueue.unshift( \"inprogress\" );\n\t\t\t}\n\n\t\t\t// Clear up the last queue stop function\n\t\t\tdelete hooks.stop;\n\t\t\tfn.call( elem, next, hooks );\n\t\t}\n\n\t\tif ( !startLength && hooks ) {\n\t\t\thooks.empty.fire();\n\t\t}\n\t},\n\n\t// Not public - generate a queueHooks object, or return the current one\n\t_queueHooks: function( elem, type ) {\n\t\tvar key = type + \"queueHooks\";\n\t\treturn dataPriv.get( elem, key ) || dataPriv.access( elem, key, {\n\t\t\tempty: jQuery.Callbacks( \"once memory\" ).add( function() {\n\t\t\t\tdataPriv.remove( elem, [ type + \"queue\", key ] );\n\t\t\t} )\n\t\t} );\n\t}\n} );\n\njQuery.fn.extend( {\n\tqueue: function( type, data ) {\n\t\tvar setter = 2;\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tdata = type;\n\t\t\ttype = \"fx\";\n\t\t\tsetter--;\n\t\t}\n\n\t\tif ( arguments.length < setter ) {\n\t\t\treturn jQuery.queue( this[ 0 ], type );\n\t\t}\n\n\t\treturn data === undefined ?\n\t\t\tthis :\n\t\t\tthis.each( function() {\n\t\t\t\tvar queue = jQuery.queue( this, type, data );\n\n\t\t\t\t// Ensure a hooks for this queue\n\t\t\t\tjQuery._queueHooks( this, type );\n\n\t\t\t\tif ( type === \"fx\" && queue[ 0 ] !== \"inprogress\" ) {\n\t\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t\t}\n\t\t\t} );\n\t},\n\tdequeue: function( type ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.dequeue( this, type );\n\t\t} );\n\t},\n\tclearQueue: function( type ) {\n\t\treturn this.queue( type || \"fx\", [] );\n\t},\n\n\t// Get a promise resolved when queues of a certain type\n\t// are emptied (fx is the type by default)\n\tpromise: function( type, obj ) {\n\t\tvar tmp,\n\t\t\tcount = 1,\n\t\t\tdefer = jQuery.Deferred(),\n\t\t\telements = this,\n\t\t\ti = this.length,\n\t\t\tresolve = function() {\n\t\t\t\tif ( !( --count ) ) {\n\t\t\t\t\tdefer.resolveWith( elements, [ elements ] );\n\t\t\t\t}\n\t\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tobj = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\ttype = type || \"fx\";\n\n\t\twhile ( i-- ) {\n\t\t\ttmp = dataPriv.get( elements[ i ], type + \"queueHooks\" );\n\t\t\tif ( tmp && tmp.empty ) {\n\t\t\t\tcount++;\n\t\t\t\ttmp.empty.add( resolve );\n\t\t\t}\n\t\t}\n\t\tresolve();\n\t\treturn defer.promise( obj );\n\t}\n} );\nvar pnum = ( /[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/ ).source;\n\nvar rcssNum = new RegExp( \"^(?:([+-])=|)(\" + pnum + \")([a-z%]*)$\", \"i\" );\n\n\nvar cssExpand = [ \"Top\", \"Right\", \"Bottom\", \"Left\" ];\n\nvar documentElement = document.documentElement;\n\n\n\n\tvar isAttached = function( elem ) {\n\t\t\treturn jQuery.contains( elem.ownerDocument, elem );\n\t\t},\n\t\tcomposed = { composed: true };\n\n\t// Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only\n\t// Check attachment across shadow DOM boundaries when possible (gh-3504)\n\t// Support: iOS 10.0-10.2 only\n\t// Early iOS 10 versions support `attachShadow` but not `getRootNode`,\n\t// leading to errors. We need to check for `getRootNode`.\n\tif ( documentElement.getRootNode ) {\n\t\tisAttached = function( elem ) {\n\t\t\treturn jQuery.contains( elem.ownerDocument, elem ) ||\n\t\t\t\telem.getRootNode( composed ) === elem.ownerDocument;\n\t\t};\n\t}\nvar isHiddenWithinTree = function( elem, el ) {\n\n\t\t// isHiddenWithinTree might be called from jQuery#filter function;\n\t\t// in that case, element will be second argument\n\t\telem = el || elem;\n\n\t\t// Inline style trumps all\n\t\treturn elem.style.display === \"none\" ||\n\t\t\telem.style.display === \"\" &&\n\n\t\t\t// Otherwise, check computed style\n\t\t\t// Support: Firefox <=43 - 45\n\t\t\t// Disconnected elements can have computed display: none, so first confirm that elem is\n\t\t\t// in the document.\n\t\t\tisAttached( elem ) &&\n\n\t\t\tjQuery.css( elem, \"display\" ) === \"none\";\n\t};\n\n\n\nfunction adjustCSS( elem, prop, valueParts, tween ) {\n\tvar adjusted, scale,\n\t\tmaxIterations = 20,\n\t\tcurrentValue = tween ?\n\t\t\tfunction() {\n\t\t\t\treturn tween.cur();\n\t\t\t} :\n\t\t\tfunction() {\n\t\t\t\treturn jQuery.css( elem, prop, \"\" );\n\t\t\t},\n\t\tinitial = currentValue(),\n\t\tunit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" ),\n\n\t\t// Starting value computation is required for potential unit mismatches\n\t\tinitialInUnit = elem.nodeType &&\n\t\t\t( jQuery.cssNumber[ prop ] || unit !== \"px\" && +initial ) &&\n\t\t\trcssNum.exec( jQuery.css( elem, prop ) );\n\n\tif ( initialInUnit && initialInUnit[ 3 ] !== unit ) {\n\n\t\t// Support: Firefox <=54\n\t\t// Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144)\n\t\tinitial = initial / 2;\n\n\t\t// Trust units reported by jQuery.css\n\t\tunit = unit || initialInUnit[ 3 ];\n\n\t\t// Iteratively approximate from a nonzero starting point\n\t\tinitialInUnit = +initial || 1;\n\n\t\twhile ( maxIterations-- ) {\n\n\t\t\t// Evaluate and update our best guess (doubling guesses that zero out).\n\t\t\t// Finish if the scale equals or crosses 1 (making the old*new product non-positive).\n\t\t\tjQuery.style( elem, prop, initialInUnit + unit );\n\t\t\tif ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) {\n\t\t\t\tmaxIterations = 0;\n\t\t\t}\n\t\t\tinitialInUnit = initialInUnit / scale;\n\n\t\t}\n\n\t\tinitialInUnit = initialInUnit * 2;\n\t\tjQuery.style( elem, prop, initialInUnit + unit );\n\n\t\t// Make sure we update the tween properties later on\n\t\tvalueParts = valueParts || [];\n\t}\n\n\tif ( valueParts ) {\n\t\tinitialInUnit = +initialInUnit || +initial || 0;\n\n\t\t// Apply relative offset (+=/-=) if specified\n\t\tadjusted = valueParts[ 1 ] ?\n\t\t\tinitialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :\n\t\t\t+valueParts[ 2 ];\n\t\tif ( tween ) {\n\t\t\ttween.unit = unit;\n\t\t\ttween.start = initialInUnit;\n\t\t\ttween.end = adjusted;\n\t\t}\n\t}\n\treturn adjusted;\n}\n\n\nvar defaultDisplayMap = {};\n\nfunction getDefaultDisplay( elem ) {\n\tvar temp,\n\t\tdoc = elem.ownerDocument,\n\t\tnodeName = elem.nodeName,\n\t\tdisplay = defaultDisplayMap[ nodeName ];\n\n\tif ( display ) {\n\t\treturn display;\n\t}\n\n\ttemp = doc.body.appendChild( doc.createElement( nodeName ) );\n\tdisplay = jQuery.css( temp, \"display\" );\n\n\ttemp.parentNode.removeChild( temp );\n\n\tif ( display === \"none\" ) {\n\t\tdisplay = \"block\";\n\t}\n\tdefaultDisplayMap[ nodeName ] = display;\n\n\treturn display;\n}\n\nfunction showHide( elements, show ) {\n\tvar display, elem,\n\t\tvalues = [],\n\t\tindex = 0,\n\t\tlength = elements.length;\n\n\t// Determine new display value for elements that need to change\n\tfor ( ; index < length; index++ ) {\n\t\telem = elements[ index ];\n\t\tif ( !elem.style ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tdisplay = elem.style.display;\n\t\tif ( show ) {\n\n\t\t\t// Since we force visibility upon cascade-hidden elements, an immediate (and slow)\n\t\t\t// check is required in this first loop unless we have a nonempty display value (either\n\t\t\t// inline or about-to-be-restored)\n\t\t\tif ( display === \"none\" ) {\n\t\t\t\tvalues[ index ] = dataPriv.get( elem, \"display\" ) || null;\n\t\t\t\tif ( !values[ index ] ) {\n\t\t\t\t\telem.style.display = \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( elem.style.display === \"\" && isHiddenWithinTree( elem ) ) {\n\t\t\t\tvalues[ index ] = getDefaultDisplay( elem );\n\t\t\t}\n\t\t} else {\n\t\t\tif ( display !== \"none\" ) {\n\t\t\t\tvalues[ index ] = \"none\";\n\n\t\t\t\t// Remember what we're overwriting\n\t\t\t\tdataPriv.set( elem, \"display\", display );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Set the display of the elements in a second loop to avoid constant reflow\n\tfor ( index = 0; index < length; index++ ) {\n\t\tif ( values[ index ] != null ) {\n\t\t\telements[ index ].style.display = values[ index ];\n\t\t}\n\t}\n\n\treturn elements;\n}\n\njQuery.fn.extend( {\n\tshow: function() {\n\t\treturn showHide( this, true );\n\t},\n\thide: function() {\n\t\treturn showHide( this );\n\t},\n\ttoggle: function( state ) {\n\t\tif ( typeof state === \"boolean\" ) {\n\t\t\treturn state ? this.show() : this.hide();\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tif ( isHiddenWithinTree( this ) ) {\n\t\t\t\tjQuery( this ).show();\n\t\t\t} else {\n\t\t\t\tjQuery( this ).hide();\n\t\t\t}\n\t\t} );\n\t}\n} );\nvar rcheckableType = ( /^(?:checkbox|radio)$/i );\n\nvar rtagName = ( /<([a-z][^\\/\\0>\\x20\\t\\r\\n\\f]*)/i );\n\nvar rscriptType = ( /^$|^module$|\\/(?:java|ecma)script/i );\n\n\n\n( function() {\n\tvar fragment = document.createDocumentFragment(),\n\t\tdiv = fragment.appendChild( document.createElement( \"div\" ) ),\n\t\tinput = document.createElement( \"input\" );\n\n\t// Support: Android 4.0 - 4.3 only\n\t// Check state lost if the name is set (#11217)\n\t// Support: Windows Web Apps (WWA)\n\t// `name` and `type` must use .setAttribute for WWA (#14901)\n\tinput.setAttribute( \"type\", \"radio\" );\n\tinput.setAttribute( \"checked\", \"checked\" );\n\tinput.setAttribute( \"name\", \"t\" );\n\n\tdiv.appendChild( input );\n\n\t// Support: Android <=4.1 only\n\t// Older WebKit doesn't clone checked state correctly in fragments\n\tsupport.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;\n\n\t// Support: IE <=11 only\n\t// Make sure textarea (and checkbox) defaultValue is properly cloned\n\tdiv.innerHTML = \"<textarea>x</textarea>\";\n\tsupport.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;\n\n\t// Support: IE <=9 only\n\t// IE <=9 replaces <option> tags with their contents when inserted outside of\n\t// the select element.\n\tdiv.innerHTML = \"<option></option>\";\n\tsupport.option = !!div.lastChild;\n} )();\n\n\n// We have to close these tags to support XHTML (#13200)\nvar wrapMap = {\n\n\t// XHTML parsers do not magically insert elements in the\n\t// same way that tag soup parsers do. So we cannot shorten\n\t// this by omitting <tbody> or other required elements.\n\tthead: [ 1, \"<table>\", \"</table>\" ],\n\tcol: [ 2, \"<table><colgroup>\", \"</colgroup></table>\" ],\n\ttr: [ 2, \"<table><tbody>\", \"</tbody></table>\" ],\n\ttd: [ 3, \"<table><tbody><tr>\", \"</tr></tbody></table>\" ],\n\n\t_default: [ 0, \"\", \"\" ]\n};\n\nwrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;\nwrapMap.th = wrapMap.td;\n\n// Support: IE <=9 only\nif ( !support.option ) {\n\twrapMap.optgroup = wrapMap.option = [ 1, \"<select multiple='multiple'>\", \"</select>\" ];\n}\n\n\nfunction getAll( context, tag ) {\n\n\t// Support: IE <=9 - 11 only\n\t// Use typeof to avoid zero-argument method invocation on host objects (#15151)\n\tvar ret;\n\n\tif ( typeof context.getElementsByTagName !== \"undefined\" ) {\n\t\tret = context.getElementsByTagName( tag || \"*\" );\n\n\t} else if ( typeof context.querySelectorAll !== \"undefined\" ) {\n\t\tret = context.querySelectorAll( tag || \"*\" );\n\n\t} else {\n\t\tret = [];\n\t}\n\n\tif ( tag === undefined || tag && nodeName( context, tag ) ) {\n\t\treturn jQuery.merge( [ context ], ret );\n\t}\n\n\treturn ret;\n}\n\n\n// Mark scripts as having already been evaluated\nfunction setGlobalEval( elems, refElements ) {\n\tvar i = 0,\n\t\tl = elems.length;\n\n\tfor ( ; i < l; i++ ) {\n\t\tdataPriv.set(\n\t\t\telems[ i ],\n\t\t\t\"globalEval\",\n\t\t\t!refElements || dataPriv.get( refElements[ i ], \"globalEval\" )\n\t\t);\n\t}\n}\n\n\nvar rhtml = /<|&#?\\w+;/;\n\nfunction buildFragment( elems, context, scripts, selection, ignored ) {\n\tvar elem, tmp, tag, wrap, attached, j,\n\t\tfragment = context.createDocumentFragment(),\n\t\tnodes = [],\n\t\ti = 0,\n\t\tl = elems.length;\n\n\tfor ( ; i < l; i++ ) {\n\t\telem = elems[ i ];\n\n\t\tif ( elem || elem === 0 ) {\n\n\t\t\t// Add nodes directly\n\t\t\tif ( toType( elem ) === \"object\" ) {\n\n\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\tjQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );\n\n\t\t\t// Convert non-html into a text node\n\t\t\t} else if ( !rhtml.test( elem ) ) {\n\t\t\t\tnodes.push( context.createTextNode( elem ) );\n\n\t\t\t// Convert html into DOM nodes\n\t\t\t} else {\n\t\t\t\ttmp = tmp || fragment.appendChild( context.createElement( \"div\" ) );\n\n\t\t\t\t// Deserialize a standard representation\n\t\t\t\ttag = ( rtagName.exec( elem ) || [ \"\", \"\" ] )[ 1 ].toLowerCase();\n\t\t\t\twrap = wrapMap[ tag ] || wrapMap._default;\n\t\t\t\ttmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];\n\n\t\t\t\t// Descend through wrappers to the right content\n\t\t\t\tj = wrap[ 0 ];\n\t\t\t\twhile ( j-- ) {\n\t\t\t\t\ttmp = tmp.lastChild;\n\t\t\t\t}\n\n\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\tjQuery.merge( nodes, tmp.childNodes );\n\n\t\t\t\t// Remember the top-level container\n\t\t\t\ttmp = fragment.firstChild;\n\n\t\t\t\t// Ensure the created nodes are orphaned (#12392)\n\t\t\t\ttmp.textContent = \"\";\n\t\t\t}\n\t\t}\n\t}\n\n\t// Remove wrapper from fragment\n\tfragment.textContent = \"\";\n\n\ti = 0;\n\twhile ( ( elem = nodes[ i++ ] ) ) {\n\n\t\t// Skip elements already in the context collection (trac-4087)\n\t\tif ( selection && jQuery.inArray( elem, selection ) > -1 ) {\n\t\t\tif ( ignored ) {\n\t\t\t\tignored.push( elem );\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tattached = isAttached( elem );\n\n\t\t// Append to fragment\n\t\ttmp = getAll( fragment.appendChild( elem ), \"script\" );\n\n\t\t// Preserve script evaluation history\n\t\tif ( attached ) {\n\t\t\tsetGlobalEval( tmp );\n\t\t}\n\n\t\t// Capture executables\n\t\tif ( scripts ) {\n\t\t\tj = 0;\n\t\t\twhile ( ( elem = tmp[ j++ ] ) ) {\n\t\t\t\tif ( rscriptType.test( elem.type || \"\" ) ) {\n\t\t\t\t\tscripts.push( elem );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn fragment;\n}\n\n\nvar rtypenamespace = /^([^.]*)(?:\\.(.+)|)/;\n\nfunction returnTrue() {\n\treturn true;\n}\n\nfunction returnFalse() {\n\treturn false;\n}\n\n// Support: IE <=9 - 11+\n// focus() and blur() are asynchronous, except when they are no-op.\n// So expect focus to be synchronous when the element is already active,\n// and blur to be synchronous when the element is not already active.\n// (focus and blur are always synchronous in other supported browsers,\n// this just defines when we can count on it).\nfunction expectSync( elem, type ) {\n\treturn ( elem === safeActiveElement() ) === ( type === \"focus\" );\n}\n\n// Support: IE <=9 only\n// Accessing document.activeElement can throw unexpectedly\n// https://bugs.jquery.com/ticket/13393\nfunction safeActiveElement() {\n\ttry {\n\t\treturn document.activeElement;\n\t} catch ( err ) { }\n}\n\nfunction on( elem, types, selector, data, fn, one ) {\n\tvar origFn, type;\n\n\t// Types can be a map of types/handlers\n\tif ( typeof types === \"object\" ) {\n\n\t\t// ( types-Object, selector, data )\n\t\tif ( typeof selector !== \"string\" ) {\n\n\t\t\t// ( types-Object, data )\n\t\t\tdata = data || selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tfor ( type in types ) {\n\t\t\ton( elem, type, selector, data, types[ type ], one );\n\t\t}\n\t\treturn elem;\n\t}\n\n\tif ( data == null && fn == null ) {\n\n\t\t// ( types, fn )\n\t\tfn = selector;\n\t\tdata = selector = undefined;\n\t} else if ( fn == null ) {\n\t\tif ( typeof selector === \"string\" ) {\n\n\t\t\t// ( types, selector, fn )\n\t\t\tfn = data;\n\t\t\tdata = undefined;\n\t\t} else {\n\n\t\t\t// ( types, data, fn )\n\t\t\tfn = data;\n\t\t\tdata = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t}\n\tif ( fn === false ) {\n\t\tfn = returnFalse;\n\t} else if ( !fn ) {\n\t\treturn elem;\n\t}\n\n\tif ( one === 1 ) {\n\t\torigFn = fn;\n\t\tfn = function( event ) {\n\n\t\t\t// Can use an empty set, since event contains the info\n\t\t\tjQuery().off( event );\n\t\t\treturn origFn.apply( this, arguments );\n\t\t};\n\n\t\t// Use same guid so caller can remove using origFn\n\t\tfn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );\n\t}\n\treturn elem.each( function() {\n\t\tjQuery.event.add( this, types, fn, data, selector );\n\t} );\n}\n\n/*\n * Helper functions for managing events -- not part of the public interface.\n * Props to Dean Edwards' addEvent library for many of the ideas.\n */\njQuery.event = {\n\n\tglobal: {},\n\n\tadd: function( elem, types, handler, data, selector ) {\n\n\t\tvar handleObjIn, eventHandle, tmp,\n\t\t\tevents, t, handleObj,\n\t\t\tspecial, handlers, type, namespaces, origType,\n\t\t\telemData = dataPriv.get( elem );\n\n\t\t// Only attach events to objects that accept data\n\t\tif ( !acceptData( elem ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Caller can pass in an object of custom data in lieu of the handler\n\t\tif ( handler.handler ) {\n\t\t\thandleObjIn = handler;\n\t\t\thandler = handleObjIn.handler;\n\t\t\tselector = handleObjIn.selector;\n\t\t}\n\n\t\t// Ensure that invalid selectors throw exceptions at attach time\n\t\t// Evaluate against documentElement in case elem is a non-element node (e.g., document)\n\t\tif ( selector ) {\n\t\t\tjQuery.find.matchesSelector( documentElement, selector );\n\t\t}\n\n\t\t// Make sure that the handler has a unique ID, used to find/remove it later\n\t\tif ( !handler.guid ) {\n\t\t\thandler.guid = jQuery.guid++;\n\t\t}\n\n\t\t// Init the element's event structure and main handler, if this is the first\n\t\tif ( !( events = elemData.events ) ) {\n\t\t\tevents = elemData.events = Object.create( null );\n\t\t}\n\t\tif ( !( eventHandle = elemData.handle ) ) {\n\t\t\teventHandle = elemData.handle = function( e ) {\n\n\t\t\t\t// Discard the second event of a jQuery.event.trigger() and\n\t\t\t\t// when an event is called after a page has unloaded\n\t\t\t\treturn typeof jQuery !== \"undefined\" && jQuery.event.triggered !== e.type ?\n\t\t\t\t\tjQuery.event.dispatch.apply( elem, arguments ) : undefined;\n\t\t\t};\n\t\t}\n\n\t\t// Handle multiple events separated by a space\n\t\ttypes = ( types || \"\" ).match( rnothtmlwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[ t ] ) || [];\n\t\t\ttype = origType = tmp[ 1 ];\n\t\t\tnamespaces = ( tmp[ 2 ] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// There *must* be a type, no attaching namespace-only handlers\n\t\t\tif ( !type ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// If event changes its type, use the special event handlers for the changed type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// If selector defined, determine special event api type, otherwise given type\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\n\t\t\t// Update special based on newly reset type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// handleObj is passed to all event handlers\n\t\t\thandleObj = jQuery.extend( {\n\t\t\t\ttype: type,\n\t\t\t\torigType: origType,\n\t\t\t\tdata: data,\n\t\t\t\thandler: handler,\n\t\t\t\tguid: handler.guid,\n\t\t\t\tselector: selector,\n\t\t\t\tneedsContext: selector && jQuery.expr.match.needsContext.test( selector ),\n\t\t\t\tnamespace: namespaces.join( \".\" )\n\t\t\t}, handleObjIn );\n\n\t\t\t// Init the event handler queue if we're the first\n\t\t\tif ( !( handlers = events[ type ] ) ) {\n\t\t\t\thandlers = events[ type ] = [];\n\t\t\t\thandlers.delegateCount = 0;\n\n\t\t\t\t// Only use addEventListener if the special events handler returns false\n\t\t\t\tif ( !special.setup ||\n\t\t\t\t\tspecial.setup.call( elem, data, namespaces, eventHandle ) === false ) {\n\n\t\t\t\t\tif ( elem.addEventListener ) {\n\t\t\t\t\t\telem.addEventListener( type, eventHandle );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( special.add ) {\n\t\t\t\tspecial.add.call( elem, handleObj );\n\n\t\t\t\tif ( !handleObj.handler.guid ) {\n\t\t\t\t\thandleObj.handler.guid = handler.guid;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add to the element's handler list, delegates in front\n\t\t\tif ( selector ) {\n\t\t\t\thandlers.splice( handlers.delegateCount++, 0, handleObj );\n\t\t\t} else {\n\t\t\t\thandlers.push( handleObj );\n\t\t\t}\n\n\t\t\t// Keep track of which events have ever been used, for event optimization\n\t\t\tjQuery.event.global[ type ] = true;\n\t\t}\n\n\t},\n\n\t// Detach an event or set of events from an element\n\tremove: function( elem, types, handler, selector, mappedTypes ) {\n\n\t\tvar j, origCount, tmp,\n\t\t\tevents, t, handleObj,\n\t\t\tspecial, handlers, type, namespaces, origType,\n\t\t\telemData = dataPriv.hasData( elem ) && dataPriv.get( elem );\n\n\t\tif ( !elemData || !( events = elemData.events ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Once for each type.namespace in types; type may be omitted\n\t\ttypes = ( types || \"\" ).match( rnothtmlwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[ t ] ) || [];\n\t\t\ttype = origType = tmp[ 1 ];\n\t\t\tnamespaces = ( tmp[ 2 ] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// Unbind all events (on this namespace, if provided) for the element\n\t\t\tif ( !type ) {\n\t\t\t\tfor ( type in events ) {\n\t\t\t\t\tjQuery.event.remove( elem, type + types[ t ], handler, selector, true );\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\t\t\thandlers = events[ type ] || [];\n\t\t\ttmp = tmp[ 2 ] &&\n\t\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join( \"\\\\.(?:.*\\\\.|)\" ) + \"(\\\\.|$)\" );\n\n\t\t\t// Remove matching events\n\t\t\torigCount = j = handlers.length;\n\t\t\twhile ( j-- ) {\n\t\t\t\thandleObj = handlers[ j ];\n\n\t\t\t\tif ( ( mappedTypes || origType === handleObj.origType ) &&\n\t\t\t\t\t( !handler || handler.guid === handleObj.guid ) &&\n\t\t\t\t\t( !tmp || tmp.test( handleObj.namespace ) ) &&\n\t\t\t\t\t( !selector || selector === handleObj.selector ||\n\t\t\t\t\t\tselector === \"**\" && handleObj.selector ) ) {\n\t\t\t\t\thandlers.splice( j, 1 );\n\n\t\t\t\t\tif ( handleObj.selector ) {\n\t\t\t\t\t\thandlers.delegateCount--;\n\t\t\t\t\t}\n\t\t\t\t\tif ( special.remove ) {\n\t\t\t\t\t\tspecial.remove.call( elem, handleObj );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove generic event handler if we removed something and no more handlers exist\n\t\t\t// (avoids potential for endless recursion during removal of special event handlers)\n\t\t\tif ( origCount && !handlers.length ) {\n\t\t\t\tif ( !special.teardown ||\n\t\t\t\t\tspecial.teardown.call( elem, namespaces, elemData.handle ) === false ) {\n\n\t\t\t\t\tjQuery.removeEvent( elem, type, elemData.handle );\n\t\t\t\t}\n\n\t\t\t\tdelete events[ type ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove data and the expando if it's no longer used\n\t\tif ( jQuery.isEmptyObject( events ) ) {\n\t\t\tdataPriv.remove( elem, \"handle events\" );\n\t\t}\n\t},\n\n\tdispatch: function( nativeEvent ) {\n\n\t\tvar i, j, ret, matched, handleObj, handlerQueue,\n\t\t\targs = new Array( arguments.length ),\n\n\t\t\t// Make a writable jQuery.Event from the native event object\n\t\t\tevent = jQuery.event.fix( nativeEvent ),\n\n\t\t\thandlers = (\n\t\t\t\tdataPriv.get( this, \"events\" ) || Object.create( null )\n\t\t\t)[ event.type ] || [],\n\t\t\tspecial = jQuery.event.special[ event.type ] || {};\n\n\t\t// Use the fix-ed jQuery.Event rather than the (read-only) native event\n\t\targs[ 0 ] = event;\n\n\t\tfor ( i = 1; i < arguments.length; i++ ) {\n\t\t\targs[ i ] = arguments[ i ];\n\t\t}\n\n\t\tevent.delegateTarget = this;\n\n\t\t// Call the preDispatch hook for the mapped type, and let it bail if desired\n\t\tif ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine handlers\n\t\thandlerQueue = jQuery.event.handlers.call( this, event, handlers );\n\n\t\t// Run delegates first; they may want to stop propagation beneath us\n\t\ti = 0;\n\t\twhile ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {\n\t\t\tevent.currentTarget = matched.elem;\n\n\t\t\tj = 0;\n\t\t\twhile ( ( handleObj = matched.handlers[ j++ ] ) &&\n\t\t\t\t!event.isImmediatePropagationStopped() ) {\n\n\t\t\t\t// If the event is namespaced, then each handler is only invoked if it is\n\t\t\t\t// specially universal or its namespaces are a superset of the event's.\n\t\t\t\tif ( !event.rnamespace || handleObj.namespace === false ||\n\t\t\t\t\tevent.rnamespace.test( handleObj.namespace ) ) {\n\n\t\t\t\t\tevent.handleObj = handleObj;\n\t\t\t\t\tevent.data = handleObj.data;\n\n\t\t\t\t\tret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||\n\t\t\t\t\t\thandleObj.handler ).apply( matched.elem, args );\n\n\t\t\t\t\tif ( ret !== undefined ) {\n\t\t\t\t\t\tif ( ( event.result = ret ) === false ) {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Call the postDispatch hook for the mapped type\n\t\tif ( special.postDispatch ) {\n\t\t\tspecial.postDispatch.call( this, event );\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\thandlers: function( event, handlers ) {\n\t\tvar i, handleObj, sel, matchedHandlers, matchedSelectors,\n\t\t\thandlerQueue = [],\n\t\t\tdelegateCount = handlers.delegateCount,\n\t\t\tcur = event.target;\n\n\t\t// Find delegate handlers\n\t\tif ( delegateCount &&\n\n\t\t\t// Support: IE <=9\n\t\t\t// Black-hole SVG <use> instance trees (trac-13180)\n\t\t\tcur.nodeType &&\n\n\t\t\t// Support: Firefox <=42\n\t\t\t// Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)\n\t\t\t// https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click\n\t\t\t// Support: IE 11 only\n\t\t\t// ...but not arrow key \"clicks\" of radio inputs, which can have `button` -1 (gh-2343)\n\t\t\t!( event.type === \"click\" && event.button >= 1 ) ) {\n\n\t\t\tfor ( ; cur !== this; cur = cur.parentNode || this ) {\n\n\t\t\t\t// Don't check non-elements (#13208)\n\t\t\t\t// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)\n\t\t\t\tif ( cur.nodeType === 1 && !( event.type === \"click\" && cur.disabled === true ) ) {\n\t\t\t\t\tmatchedHandlers = [];\n\t\t\t\t\tmatchedSelectors = {};\n\t\t\t\t\tfor ( i = 0; i < delegateCount; i++ ) {\n\t\t\t\t\t\thandleObj = handlers[ i ];\n\n\t\t\t\t\t\t// Don't conflict with Object.prototype properties (#13203)\n\t\t\t\t\t\tsel = handleObj.selector + \" \";\n\n\t\t\t\t\t\tif ( matchedSelectors[ sel ] === undefined ) {\n\t\t\t\t\t\t\tmatchedSelectors[ sel ] = handleObj.needsContext ?\n\t\t\t\t\t\t\t\tjQuery( sel, this ).index( cur ) > -1 :\n\t\t\t\t\t\t\t\tjQuery.find( sel, this, null, [ cur ] ).length;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( matchedSelectors[ sel ] ) {\n\t\t\t\t\t\t\tmatchedHandlers.push( handleObj );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( matchedHandlers.length ) {\n\t\t\t\t\t\thandlerQueue.push( { elem: cur, handlers: matchedHandlers } );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Add the remaining (directly-bound) handlers\n\t\tcur = this;\n\t\tif ( delegateCount < handlers.length ) {\n\t\t\thandlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );\n\t\t}\n\n\t\treturn handlerQueue;\n\t},\n\n\taddProp: function( name, hook ) {\n\t\tObject.defineProperty( jQuery.Event.prototype, name, {\n\t\t\tenumerable: true,\n\t\t\tconfigurable: true,\n\n\t\t\tget: isFunction( hook ) ?\n\t\t\t\tfunction() {\n\t\t\t\t\tif ( this.originalEvent ) {\n\t\t\t\t\t\treturn hook( this.originalEvent );\n\t\t\t\t\t}\n\t\t\t\t} :\n\t\t\t\tfunction() {\n\t\t\t\t\tif ( this.originalEvent ) {\n\t\t\t\t\t\treturn this.originalEvent[ name ];\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\tset: function( value ) {\n\t\t\t\tObject.defineProperty( this, name, {\n\t\t\t\t\tenumerable: true,\n\t\t\t\t\tconfigurable: true,\n\t\t\t\t\twritable: true,\n\t\t\t\t\tvalue: value\n\t\t\t\t} );\n\t\t\t}\n\t\t} );\n\t},\n\n\tfix: function( originalEvent ) {\n\t\treturn originalEvent[ jQuery.expando ] ?\n\t\t\toriginalEvent :\n\t\t\tnew jQuery.Event( originalEvent );\n\t},\n\n\tspecial: {\n\t\tload: {\n\n\t\t\t// Prevent triggered image.load events from bubbling to window.load\n\t\t\tnoBubble: true\n\t\t},\n\t\tclick: {\n\n\t\t\t// Utilize native event to ensure correct state for checkable inputs\n\t\t\tsetup: function( data ) {\n\n\t\t\t\t// For mutual compressibility with _default, replace `this` access with a local var.\n\t\t\t\t// `|| data` is dead code meant only to preserve the variable through minification.\n\t\t\t\tvar el = this || data;\n\n\t\t\t\t// Claim the first handler\n\t\t\t\tif ( rcheckableType.test( el.type ) &&\n\t\t\t\t\tel.click && nodeName( el, \"input\" ) ) {\n\n\t\t\t\t\t// dataPriv.set( el, \"click\", ... )\n\t\t\t\t\tleverageNative( el, \"click\", returnTrue );\n\t\t\t\t}\n\n\t\t\t\t// Return false to allow normal processing in the caller\n\t\t\t\treturn false;\n\t\t\t},\n\t\t\ttrigger: function( data ) {\n\n\t\t\t\t// For mutual compressibility with _default, replace `this` access with a local var.\n\t\t\t\t// `|| data` is dead code meant only to preserve the variable through minification.\n\t\t\t\tvar el = this || data;\n\n\t\t\t\t// Force setup before triggering a click\n\t\t\t\tif ( rcheckableType.test( el.type ) &&\n\t\t\t\t\tel.click && nodeName( el, \"input\" ) ) {\n\n\t\t\t\t\tleverageNative( el, \"click\" );\n\t\t\t\t}\n\n\t\t\t\t// Return non-false to allow normal event-path propagation\n\t\t\t\treturn true;\n\t\t\t},\n\n\t\t\t// For cross-browser consistency, suppress native .click() on links\n\t\t\t// Also prevent it if we're currently inside a leveraged native-event stack\n\t\t\t_default: function( event ) {\n\t\t\t\tvar target = event.target;\n\t\t\t\treturn rcheckableType.test( target.type ) &&\n\t\t\t\t\ttarget.click && nodeName( target, \"input\" ) &&\n\t\t\t\t\tdataPriv.get( target, \"click\" ) ||\n\t\t\t\t\tnodeName( target, \"a\" );\n\t\t\t}\n\t\t},\n\n\t\tbeforeunload: {\n\t\t\tpostDispatch: function( event ) {\n\n\t\t\t\t// Support: Firefox 20+\n\t\t\t\t// Firefox doesn't alert if the returnValue field is not set.\n\t\t\t\tif ( event.result !== undefined && event.originalEvent ) {\n\t\t\t\t\tevent.originalEvent.returnValue = event.result;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n};\n\n// Ensure the presence of an event listener that handles manually-triggered\n// synthetic events by interrupting progress until reinvoked in response to\n// *native* events that it fires directly, ensuring that state changes have\n// already occurred before other listeners are invoked.\nfunction leverageNative( el, type, expectSync ) {\n\n\t// Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add\n\tif ( !expectSync ) {\n\t\tif ( dataPriv.get( el, type ) === undefined ) {\n\t\t\tjQuery.event.add( el, type, returnTrue );\n\t\t}\n\t\treturn;\n\t}\n\n\t// Register the controller as a special universal handler for all event namespaces\n\tdataPriv.set( el, type, false );\n\tjQuery.event.add( el, type, {\n\t\tnamespace: false,\n\t\thandler: function( event ) {\n\t\t\tvar notAsync, result,\n\t\t\t\tsaved = dataPriv.get( this, type );\n\n\t\t\tif ( ( event.isTrigger & 1 ) && this[ type ] ) {\n\n\t\t\t\t// Interrupt processing of the outer synthetic .trigger()ed event\n\t\t\t\t// Saved data should be false in such cases, but might be a leftover capture object\n\t\t\t\t// from an async native handler (gh-4350)\n\t\t\t\tif ( !saved.length ) {\n\n\t\t\t\t\t// Store arguments for use when handling the inner native event\n\t\t\t\t\t// There will always be at least one argument (an event object), so this array\n\t\t\t\t\t// will not be confused with a leftover capture object.\n\t\t\t\t\tsaved = slice.call( arguments );\n\t\t\t\t\tdataPriv.set( this, type, saved );\n\n\t\t\t\t\t// Trigger the native event and capture its result\n\t\t\t\t\t// Support: IE <=9 - 11+\n\t\t\t\t\t// focus() and blur() are asynchronous\n\t\t\t\t\tnotAsync = expectSync( this, type );\n\t\t\t\t\tthis[ type ]();\n\t\t\t\t\tresult = dataPriv.get( this, type );\n\t\t\t\t\tif ( saved !== result || notAsync ) {\n\t\t\t\t\t\tdataPriv.set( this, type, false );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresult = {};\n\t\t\t\t\t}\n\t\t\t\t\tif ( saved !== result ) {\n\n\t\t\t\t\t\t// Cancel the outer synthetic event\n\t\t\t\t\t\tevent.stopImmediatePropagation();\n\t\t\t\t\t\tevent.preventDefault();\n\n\t\t\t\t\t\t// Support: Chrome 86+\n\t\t\t\t\t\t// In Chrome, if an element having a focusout handler is blurred by\n\t\t\t\t\t\t// clicking outside of it, it invokes the handler synchronously. If\n\t\t\t\t\t\t// that handler calls `.remove()` on the element, the data is cleared,\n\t\t\t\t\t\t// leaving `result` undefined. We need to guard against this.\n\t\t\t\t\t\treturn result && result.value;\n\t\t\t\t\t}\n\n\t\t\t\t// If this is an inner synthetic event for an event with a bubbling surrogate\n\t\t\t\t// (focus or blur), assume that the surrogate already propagated from triggering the\n\t\t\t\t// native event and prevent that from happening again here.\n\t\t\t\t// This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the\n\t\t\t\t// bubbling surrogate propagates *after* the non-bubbling base), but that seems\n\t\t\t\t// less bad than duplication.\n\t\t\t\t} else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) {\n\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t}\n\n\t\t\t// If this is a native event triggered above, everything is now in order\n\t\t\t// Fire an inner synthetic event with the original arguments\n\t\t\t} else if ( saved.length ) {\n\n\t\t\t\t// ...and capture the result\n\t\t\t\tdataPriv.set( this, type, {\n\t\t\t\t\tvalue: jQuery.event.trigger(\n\n\t\t\t\t\t\t// Support: IE <=9 - 11+\n\t\t\t\t\t\t// Extend with the prototype to reset the above stopImmediatePropagation()\n\t\t\t\t\t\tjQuery.extend( saved[ 0 ], jQuery.Event.prototype ),\n\t\t\t\t\t\tsaved.slice( 1 ),\n\t\t\t\t\t\tthis\n\t\t\t\t\t)\n\t\t\t\t} );\n\n\t\t\t\t// Abort handling of the native event\n\t\t\t\tevent.stopImmediatePropagation();\n\t\t\t}\n\t\t}\n\t} );\n}\n\njQuery.removeEvent = function( elem, type, handle ) {\n\n\t// This \"if\" is needed for plain objects\n\tif ( elem.removeEventListener ) {\n\t\telem.removeEventListener( type, handle );\n\t}\n};\n\njQuery.Event = function( src, props ) {\n\n\t// Allow instantiation without the 'new' keyword\n\tif ( !( this instanceof jQuery.Event ) ) {\n\t\treturn new jQuery.Event( src, props );\n\t}\n\n\t// Event object\n\tif ( src && src.type ) {\n\t\tthis.originalEvent = src;\n\t\tthis.type = src.type;\n\n\t\t// Events bubbling up the document may have been marked as prevented\n\t\t// by a handler lower down the tree; reflect the correct value.\n\t\tthis.isDefaultPrevented = src.defaultPrevented ||\n\t\t\t\tsrc.defaultPrevented === undefined &&\n\n\t\t\t\t// Support: Android <=2.3 only\n\t\t\t\tsrc.returnValue === false ?\n\t\t\treturnTrue :\n\t\t\treturnFalse;\n\n\t\t// Create target properties\n\t\t// Support: Safari <=6 - 7 only\n\t\t// Target should not be a text node (#504, #13143)\n\t\tthis.target = ( src.target && src.target.nodeType === 3 ) ?\n\t\t\tsrc.target.parentNode :\n\t\t\tsrc.target;\n\n\t\tthis.currentTarget = src.currentTarget;\n\t\tthis.relatedTarget = src.relatedTarget;\n\n\t// Event type\n\t} else {\n\t\tthis.type = src;\n\t}\n\n\t// Put explicitly provided properties onto the event object\n\tif ( props ) {\n\t\tjQuery.extend( this, props );\n\t}\n\n\t// Create a timestamp if incoming event doesn't have one\n\tthis.timeStamp = src && src.timeStamp || Date.now();\n\n\t// Mark it as fixed\n\tthis[ jQuery.expando ] = true;\n};\n\n// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding\n// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html\njQuery.Event.prototype = {\n\tconstructor: jQuery.Event,\n\tisDefaultPrevented: returnFalse,\n\tisPropagationStopped: returnFalse,\n\tisImmediatePropagationStopped: returnFalse,\n\tisSimulated: false,\n\n\tpreventDefault: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isDefaultPrevented = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.preventDefault();\n\t\t}\n\t},\n\tstopPropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isPropagationStopped = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.stopPropagation();\n\t\t}\n\t},\n\tstopImmediatePropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isImmediatePropagationStopped = returnTrue;\n\n\t\tif ( e && !this.isSimulated ) {\n\t\t\te.stopImmediatePropagation();\n\t\t}\n\n\t\tthis.stopPropagation();\n\t}\n};\n\n// Includes all common event props including KeyEvent and MouseEvent specific props\njQuery.each( {\n\taltKey: true,\n\tbubbles: true,\n\tcancelable: true,\n\tchangedTouches: true,\n\tctrlKey: true,\n\tdetail: true,\n\teventPhase: true,\n\tmetaKey: true,\n\tpageX: true,\n\tpageY: true,\n\tshiftKey: true,\n\tview: true,\n\t\"char\": true,\n\tcode: true,\n\tcharCode: true,\n\tkey: true,\n\tkeyCode: true,\n\tbutton: true,\n\tbuttons: true,\n\tclientX: true,\n\tclientY: true,\n\toffsetX: true,\n\toffsetY: true,\n\tpointerId: true,\n\tpointerType: true,\n\tscreenX: true,\n\tscreenY: true,\n\ttargetTouches: true,\n\ttoElement: true,\n\ttouches: true,\n\twhich: true\n}, jQuery.event.addProp );\n\njQuery.each( { focus: \"focusin\", blur: \"focusout\" }, function( type, delegateType ) {\n\tjQuery.event.special[ type ] = {\n\n\t\t// Utilize native event if possible so blur/focus sequence is correct\n\t\tsetup: function() {\n\n\t\t\t// Claim the first handler\n\t\t\t// dataPriv.set( this, \"focus\", ... )\n\t\t\t// dataPriv.set( this, \"blur\", ... )\n\t\t\tleverageNative( this, type, expectSync );\n\n\t\t\t// Return false to allow normal processing in the caller\n\t\t\treturn false;\n\t\t},\n\t\ttrigger: function() {\n\n\t\t\t// Force setup before trigger\n\t\t\tleverageNative( this, type );\n\n\t\t\t// Return non-false to allow normal event-path propagation\n\t\t\treturn true;\n\t\t},\n\n\t\t// Suppress native focus or blur as it's already being fired\n\t\t// in leverageNative.\n\t\t_default: function() {\n\t\t\treturn true;\n\t\t},\n\n\t\tdelegateType: delegateType\n\t};\n} );\n\n// Create mouseenter/leave events using mouseover/out and event-time checks\n// so that event delegation works in jQuery.\n// Do the same for pointerenter/pointerleave and pointerover/pointerout\n//\n// Support: Safari 7 only\n// Safari sends mouseenter too often; see:\n// https://bugs.chromium.org/p/chromium/issues/detail?id=470258\n// for the description of the bug (it existed in older Chrome versions as well).\njQuery.each( {\n\tmouseenter: \"mouseover\",\n\tmouseleave: \"mouseout\",\n\tpointerenter: \"pointerover\",\n\tpointerleave: \"pointerout\"\n}, function( orig, fix ) {\n\tjQuery.event.special[ orig ] = {\n\t\tdelegateType: fix,\n\t\tbindType: fix,\n\n\t\thandle: function( event ) {\n\t\t\tvar ret,\n\t\t\t\ttarget = this,\n\t\t\t\trelated = event.relatedTarget,\n\t\t\t\thandleObj = event.handleObj;\n\n\t\t\t// For mouseenter/leave call the handler if related is outside the target.\n\t\t\t// NB: No relatedTarget if the mouse left/entered the browser window\n\t\t\tif ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {\n\t\t\t\tevent.type = handleObj.origType;\n\t\t\t\tret = handleObj.handler.apply( this, arguments );\n\t\t\t\tevent.type = fix;\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\t};\n} );\n\njQuery.fn.extend( {\n\n\ton: function( types, selector, data, fn ) {\n\t\treturn on( this, types, selector, data, fn );\n\t},\n\tone: function( types, selector, data, fn ) {\n\t\treturn on( this, types, selector, data, fn, 1 );\n\t},\n\toff: function( types, selector, fn ) {\n\t\tvar handleObj, type;\n\t\tif ( types && types.preventDefault && types.handleObj ) {\n\n\t\t\t// ( event ) dispatched jQuery.Event\n\t\t\thandleObj = types.handleObj;\n\t\t\tjQuery( types.delegateTarget ).off(\n\t\t\t\thandleObj.namespace ?\n\t\t\t\t\thandleObj.origType + \".\" + handleObj.namespace :\n\t\t\t\t\thandleObj.origType,\n\t\t\t\thandleObj.selector,\n\t\t\t\thandleObj.handler\n\t\t\t);\n\t\t\treturn this;\n\t\t}\n\t\tif ( typeof types === \"object\" ) {\n\n\t\t\t// ( types-object [, selector] )\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.off( type, selector, types[ type ] );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\t\tif ( selector === false || typeof selector === \"function\" ) {\n\n\t\t\t// ( types [, fn] )\n\t\t\tfn = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.remove( this, types, fn, selector );\n\t\t} );\n\t}\n} );\n\n\nvar\n\n\t// Support: IE <=10 - 11, Edge 12 - 13 only\n\t// In IE/Edge using regex groups here causes severe slowdowns.\n\t// See https://connect.microsoft.com/IE/feedback/details/1736512/\n\trnoInnerhtml = /<script|<style|<link/i,\n\n\t// checked=\"checked\" or checked\n\trchecked = /checked\\s*(?:[^=]|=\\s*.checked.)/i,\n\trcleanScript = /^\\s*<!(?:\\[CDATA\\[|--)|(?:\\]\\]|--)>\\s*$/g;\n\n// Prefer a tbody over its parent table for containing new rows\nfunction manipulationTarget( elem, content ) {\n\tif ( nodeName( elem, \"table\" ) &&\n\t\tnodeName( content.nodeType !== 11 ? content : content.firstChild, \"tr\" ) ) {\n\n\t\treturn jQuery( elem ).children( \"tbody\" )[ 0 ] || elem;\n\t}\n\n\treturn elem;\n}\n\n// Replace/restore the type attribute of script elements for safe DOM manipulation\nfunction disableScript( elem ) {\n\telem.type = ( elem.getAttribute( \"type\" ) !== null ) + \"/\" + elem.type;\n\treturn elem;\n}\nfunction restoreScript( elem ) {\n\tif ( ( elem.type || \"\" ).slice( 0, 5 ) === \"true/\" ) {\n\t\telem.type = elem.type.slice( 5 );\n\t} else {\n\t\telem.removeAttribute( \"type\" );\n\t}\n\n\treturn elem;\n}\n\nfunction cloneCopyEvent( src, dest ) {\n\tvar i, l, type, pdataOld, udataOld, udataCur, events;\n\n\tif ( dest.nodeType !== 1 ) {\n\t\treturn;\n\t}\n\n\t// 1. Copy private data: events, handlers, etc.\n\tif ( dataPriv.hasData( src ) ) {\n\t\tpdataOld = dataPriv.get( src );\n\t\tevents = pdataOld.events;\n\n\t\tif ( events ) {\n\t\t\tdataPriv.remove( dest, \"handle events\" );\n\n\t\t\tfor ( type in events ) {\n\t\t\t\tfor ( i = 0, l = events[ type ].length; i < l; i++ ) {\n\t\t\t\t\tjQuery.event.add( dest, type, events[ type ][ i ] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// 2. Copy user data\n\tif ( dataUser.hasData( src ) ) {\n\t\tudataOld = dataUser.access( src );\n\t\tudataCur = jQuery.extend( {}, udataOld );\n\n\t\tdataUser.set( dest, udataCur );\n\t}\n}\n\n// Fix IE bugs, see support tests\nfunction fixInput( src, dest ) {\n\tvar nodeName = dest.nodeName.toLowerCase();\n\n\t// Fails to persist the checked state of a cloned checkbox or radio button.\n\tif ( nodeName === \"input\" && rcheckableType.test( src.type ) ) {\n\t\tdest.checked = src.checked;\n\n\t// Fails to return the selected option to the default selected state when cloning options\n\t} else if ( nodeName === \"input\" || nodeName === \"textarea\" ) {\n\t\tdest.defaultValue = src.defaultValue;\n\t}\n}\n\nfunction domManip( collection, args, callback, ignored ) {\n\n\t// Flatten any nested arrays\n\targs = flat( args );\n\n\tvar fragment, first, scripts, hasScripts, node, doc,\n\t\ti = 0,\n\t\tl = collection.length,\n\t\tiNoClone = l - 1,\n\t\tvalue = args[ 0 ],\n\t\tvalueIsFunction = isFunction( value );\n\n\t// We can't cloneNode fragments that contain checked, in WebKit\n\tif ( valueIsFunction ||\n\t\t\t( l > 1 && typeof value === \"string\" &&\n\t\t\t\t!support.checkClone && rchecked.test( value ) ) ) {\n\t\treturn collection.each( function( index ) {\n\t\t\tvar self = collection.eq( index );\n\t\t\tif ( valueIsFunction ) {\n\t\t\t\targs[ 0 ] = value.call( this, index, self.html() );\n\t\t\t}\n\t\t\tdomManip( self, args, callback, ignored );\n\t\t} );\n\t}\n\n\tif ( l ) {\n\t\tfragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );\n\t\tfirst = fragment.firstChild;\n\n\t\tif ( fragment.childNodes.length === 1 ) {\n\t\t\tfragment = first;\n\t\t}\n\n\t\t// Require either new content or an interest in ignored elements to invoke the callback\n\t\tif ( first || ignored ) {\n\t\t\tscripts = jQuery.map( getAll( fragment, \"script\" ), disableScript );\n\t\t\thasScripts = scripts.length;\n\n\t\t\t// Use the original fragment for the last item\n\t\t\t// instead of the first because it can end up\n\t\t\t// being emptied incorrectly in certain situations (#8070).\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tnode = fragment;\n\n\t\t\t\tif ( i !== iNoClone ) {\n\t\t\t\t\tnode = jQuery.clone( node, true, true );\n\n\t\t\t\t\t// Keep references to cloned scripts for later restoration\n\t\t\t\t\tif ( hasScripts ) {\n\n\t\t\t\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\t\t\tjQuery.merge( scripts, getAll( node, \"script\" ) );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tcallback.call( collection[ i ], node, i );\n\t\t\t}\n\n\t\t\tif ( hasScripts ) {\n\t\t\t\tdoc = scripts[ scripts.length - 1 ].ownerDocument;\n\n\t\t\t\t// Reenable scripts\n\t\t\t\tjQuery.map( scripts, restoreScript );\n\n\t\t\t\t// Evaluate executable scripts on first document insertion\n\t\t\t\tfor ( i = 0; i < hasScripts; i++ ) {\n\t\t\t\t\tnode = scripts[ i ];\n\t\t\t\t\tif ( rscriptType.test( node.type || \"\" ) &&\n\t\t\t\t\t\t!dataPriv.access( node, \"globalEval\" ) &&\n\t\t\t\t\t\tjQuery.contains( doc, node ) ) {\n\n\t\t\t\t\t\tif ( node.src && ( node.type || \"\" ).toLowerCase() !== \"module\" ) {\n\n\t\t\t\t\t\t\t// Optional AJAX dependency, but won't run scripts if not present\n\t\t\t\t\t\t\tif ( jQuery._evalUrl && !node.noModule ) {\n\t\t\t\t\t\t\t\tjQuery._evalUrl( node.src, {\n\t\t\t\t\t\t\t\t\tnonce: node.nonce || node.getAttribute( \"nonce\" )\n\t\t\t\t\t\t\t\t}, doc );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tDOMEval( node.textContent.replace( rcleanScript, \"\" ), node, doc );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn collection;\n}\n\nfunction remove( elem, selector, keepData ) {\n\tvar node,\n\t\tnodes = selector ? jQuery.filter( selector, elem ) : elem,\n\t\ti = 0;\n\n\tfor ( ; ( node = nodes[ i ] ) != null; i++ ) {\n\t\tif ( !keepData && node.nodeType === 1 ) {\n\t\t\tjQuery.cleanData( getAll( node ) );\n\t\t}\n\n\t\tif ( node.parentNode ) {\n\t\t\tif ( keepData && isAttached( node ) ) {\n\t\t\t\tsetGlobalEval( getAll( node, \"script\" ) );\n\t\t\t}\n\t\t\tnode.parentNode.removeChild( node );\n\t\t}\n\t}\n\n\treturn elem;\n}\n\njQuery.extend( {\n\thtmlPrefilter: function( html ) {\n\t\treturn html;\n\t},\n\n\tclone: function( elem, dataAndEvents, deepDataAndEvents ) {\n\t\tvar i, l, srcElements, destElements,\n\t\t\tclone = elem.cloneNode( true ),\n\t\t\tinPage = isAttached( elem );\n\n\t\t// Fix IE cloning issues\n\t\tif ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&\n\t\t\t\t!jQuery.isXMLDoc( elem ) ) {\n\n\t\t\t// We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2\n\t\t\tdestElements = getAll( clone );\n\t\t\tsrcElements = getAll( elem );\n\n\t\t\tfor ( i = 0, l = srcElements.length; i < l; i++ ) {\n\t\t\t\tfixInput( srcElements[ i ], destElements[ i ] );\n\t\t\t}\n\t\t}\n\n\t\t// Copy the events from the original to the clone\n\t\tif ( dataAndEvents ) {\n\t\t\tif ( deepDataAndEvents ) {\n\t\t\t\tsrcElements = srcElements || getAll( elem );\n\t\t\t\tdestElements = destElements || getAll( clone );\n\n\t\t\t\tfor ( i = 0, l = srcElements.length; i < l; i++ ) {\n\t\t\t\t\tcloneCopyEvent( srcElements[ i ], destElements[ i ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcloneCopyEvent( elem, clone );\n\t\t\t}\n\t\t}\n\n\t\t// Preserve script evaluation history\n\t\tdestElements = getAll( clone, \"script\" );\n\t\tif ( destElements.length > 0 ) {\n\t\t\tsetGlobalEval( destElements, !inPage && getAll( elem, \"script\" ) );\n\t\t}\n\n\t\t// Return the cloned set\n\t\treturn clone;\n\t},\n\n\tcleanData: function( elems ) {\n\t\tvar data, elem, type,\n\t\t\tspecial = jQuery.event.special,\n\t\t\ti = 0;\n\n\t\tfor ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {\n\t\t\tif ( acceptData( elem ) ) {\n\t\t\t\tif ( ( data = elem[ dataPriv.expando ] ) ) {\n\t\t\t\t\tif ( data.events ) {\n\t\t\t\t\t\tfor ( type in data.events ) {\n\t\t\t\t\t\t\tif ( special[ type ] ) {\n\t\t\t\t\t\t\t\tjQuery.event.remove( elem, type );\n\n\t\t\t\t\t\t\t// This is a shortcut to avoid jQuery.event.remove's overhead\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.removeEvent( elem, type, data.handle );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Support: Chrome <=35 - 45+\n\t\t\t\t\t// Assign undefined instead of using delete, see Data#remove\n\t\t\t\t\telem[ dataPriv.expando ] = undefined;\n\t\t\t\t}\n\t\t\t\tif ( elem[ dataUser.expando ] ) {\n\n\t\t\t\t\t// Support: Chrome <=35 - 45+\n\t\t\t\t\t// Assign undefined instead of using delete, see Data#remove\n\t\t\t\t\telem[ dataUser.expando ] = undefined;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n} );\n\njQuery.fn.extend( {\n\tdetach: function( selector ) {\n\t\treturn remove( this, selector, true );\n\t},\n\n\tremove: function( selector ) {\n\t\treturn remove( this, selector );\n\t},\n\n\ttext: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\treturn value === undefined ?\n\t\t\t\tjQuery.text( this ) :\n\t\t\t\tthis.empty().each( function() {\n\t\t\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\t\t\tthis.textContent = value;\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t}, null, value, arguments.length );\n\t},\n\n\tappend: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.appendChild( elem );\n\t\t\t}\n\t\t} );\n\t},\n\n\tprepend: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.insertBefore( elem, target.firstChild );\n\t\t\t}\n\t\t} );\n\t},\n\n\tbefore: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this );\n\t\t\t}\n\t\t} );\n\t},\n\n\tafter: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this.nextSibling );\n\t\t\t}\n\t\t} );\n\t},\n\n\tempty: function() {\n\t\tvar elem,\n\t\t\ti = 0;\n\n\t\tfor ( ; ( elem = this[ i ] ) != null; i++ ) {\n\t\t\tif ( elem.nodeType === 1 ) {\n\n\t\t\t\t// Prevent memory leaks\n\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\n\t\t\t\t// Remove any remaining nodes\n\t\t\t\telem.textContent = \"\";\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tclone: function( dataAndEvents, deepDataAndEvents ) {\n\t\tdataAndEvents = dataAndEvents == null ? false : dataAndEvents;\n\t\tdeepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;\n\n\t\treturn this.map( function() {\n\t\t\treturn jQuery.clone( this, dataAndEvents, deepDataAndEvents );\n\t\t} );\n\t},\n\n\thtml: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\tvar elem = this[ 0 ] || {},\n\t\t\t\ti = 0,\n\t\t\t\tl = this.length;\n\n\t\t\tif ( value === undefined && elem.nodeType === 1 ) {\n\t\t\t\treturn elem.innerHTML;\n\t\t\t}\n\n\t\t\t// See if we can take a shortcut and just use innerHTML\n\t\t\tif ( typeof value === \"string\" && !rnoInnerhtml.test( value ) &&\n\t\t\t\t!wrapMap[ ( rtagName.exec( value ) || [ \"\", \"\" ] )[ 1 ].toLowerCase() ] ) {\n\n\t\t\t\tvalue = jQuery.htmlPrefilter( value );\n\n\t\t\t\ttry {\n\t\t\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\t\t\telem = this[ i ] || {};\n\n\t\t\t\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\t\t\t\t\t\t\telem.innerHTML = value;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\telem = 0;\n\n\t\t\t\t// If using innerHTML throws an exception, use the fallback method\n\t\t\t\t} catch ( e ) {}\n\t\t\t}\n\n\t\t\tif ( elem ) {\n\t\t\t\tthis.empty().append( value );\n\t\t\t}\n\t\t}, null, value, arguments.length );\n\t},\n\n\treplaceWith: function() {\n\t\tvar ignored = [];\n\n\t\t// Make the changes, replacing each non-ignored context element with the new content\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tvar parent = this.parentNode;\n\n\t\t\tif ( jQuery.inArray( this, ignored ) < 0 ) {\n\t\t\t\tjQuery.cleanData( getAll( this ) );\n\t\t\t\tif ( parent ) {\n\t\t\t\t\tparent.replaceChild( elem, this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Force callback invocation\n\t\t}, ignored );\n\t}\n} );\n\njQuery.each( {\n\tappendTo: \"append\",\n\tprependTo: \"prepend\",\n\tinsertBefore: \"before\",\n\tinsertAfter: \"after\",\n\treplaceAll: \"replaceWith\"\n}, function( name, original ) {\n\tjQuery.fn[ name ] = function( selector ) {\n\t\tvar elems,\n\t\t\tret = [],\n\t\t\tinsert = jQuery( selector ),\n\t\t\tlast = insert.length - 1,\n\t\t\ti = 0;\n\n\t\tfor ( ; i <= last; i++ ) {\n\t\t\telems = i === last ? this : this.clone( true );\n\t\t\tjQuery( insert[ i ] )[ original ]( elems );\n\n\t\t\t// Support: Android <=4.0 only, PhantomJS 1 only\n\t\t\t// .get() because push.apply(_, arraylike) throws on ancient WebKit\n\t\t\tpush.apply( ret, elems.get() );\n\t\t}\n\n\t\treturn this.pushStack( ret );\n\t};\n} );\nvar rnumnonpx = new RegExp( \"^(\" + pnum + \")(?!px)[a-z%]+$\", \"i\" );\n\nvar getStyles = function( elem ) {\n\n\t\t// Support: IE <=11 only, Firefox <=30 (#15098, #14150)\n\t\t// IE throws on elements created in popups\n\t\t// FF meanwhile throws on frame elements through \"defaultView.getComputedStyle\"\n\t\tvar view = elem.ownerDocument.defaultView;\n\n\t\tif ( !view || !view.opener ) {\n\t\t\tview = window;\n\t\t}\n\n\t\treturn view.getComputedStyle( elem );\n\t};\n\nvar swap = function( elem, options, callback ) {\n\tvar ret, name,\n\t\told = {};\n\n\t// Remember the old values, and insert the new ones\n\tfor ( name in options ) {\n\t\told[ name ] = elem.style[ name ];\n\t\telem.style[ name ] = options[ name ];\n\t}\n\n\tret = callback.call( elem );\n\n\t// Revert the old values\n\tfor ( name in options ) {\n\t\telem.style[ name ] = old[ name ];\n\t}\n\n\treturn ret;\n};\n\n\nvar rboxStyle = new RegExp( cssExpand.join( \"|\" ), \"i\" );\n\n\n\n( function() {\n\n\t// Executing both pixelPosition & boxSizingReliable tests require only one layout\n\t// so they're executed at the same time to save the second computation.\n\tfunction computeStyleTests() {\n\n\t\t// This is a singleton, we need to execute it only once\n\t\tif ( !div ) {\n\t\t\treturn;\n\t\t}\n\n\t\tcontainer.style.cssText = \"position:absolute;left:-11111px;width:60px;\" +\n\t\t\t\"margin-top:1px;padding:0;border:0\";\n\t\tdiv.style.cssText =\n\t\t\t\"position:relative;display:block;box-sizing:border-box;overflow:scroll;\" +\n\t\t\t\"margin:auto;border:1px;padding:1px;\" +\n\t\t\t\"width:60%;top:1%\";\n\t\tdocumentElement.appendChild( container ).appendChild( div );\n\n\t\tvar divStyle = window.getComputedStyle( div );\n\t\tpixelPositionVal = divStyle.top !== \"1%\";\n\n\t\t// Support: Android 4.0 - 4.3 only, Firefox <=3 - 44\n\t\treliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12;\n\n\t\t// Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3\n\t\t// Some styles come back with percentage values, even though they shouldn't\n\t\tdiv.style.right = \"60%\";\n\t\tpixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36;\n\n\t\t// Support: IE 9 - 11 only\n\t\t// Detect misreporting of content dimensions for box-sizing:border-box elements\n\t\tboxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36;\n\n\t\t// Support: IE 9 only\n\t\t// Detect overflow:scroll screwiness (gh-3699)\n\t\t// Support: Chrome <=64\n\t\t// Don't get tricked when zoom affects offsetWidth (gh-4029)\n\t\tdiv.style.position = \"absolute\";\n\t\tscrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12;\n\n\t\tdocumentElement.removeChild( container );\n\n\t\t// Nullify the div so it wouldn't be stored in the memory and\n\t\t// it will also be a sign that checks already performed\n\t\tdiv = null;\n\t}\n\n\tfunction roundPixelMeasures( measure ) {\n\t\treturn Math.round( parseFloat( measure ) );\n\t}\n\n\tvar pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal,\n\t\treliableTrDimensionsVal, reliableMarginLeftVal,\n\t\tcontainer = document.createElement( \"div\" ),\n\t\tdiv = document.createElement( \"div\" );\n\n\t// Finish early in limited (non-browser) environments\n\tif ( !div.style ) {\n\t\treturn;\n\t}\n\n\t// Support: IE <=9 - 11 only\n\t// Style of cloned element affects source element cloned (#8908)\n\tdiv.style.backgroundClip = \"content-box\";\n\tdiv.cloneNode( true ).style.backgroundClip = \"\";\n\tsupport.clearCloneStyle = div.style.backgroundClip === \"content-box\";\n\n\tjQuery.extend( support, {\n\t\tboxSizingReliable: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn boxSizingReliableVal;\n\t\t},\n\t\tpixelBoxStyles: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn pixelBoxStylesVal;\n\t\t},\n\t\tpixelPosition: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn pixelPositionVal;\n\t\t},\n\t\treliableMarginLeft: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn reliableMarginLeftVal;\n\t\t},\n\t\tscrollboxSize: function() {\n\t\t\tcomputeStyleTests();\n\t\t\treturn scrollboxSizeVal;\n\t\t},\n\n\t\t// Support: IE 9 - 11+, Edge 15 - 18+\n\t\t// IE/Edge misreport `getComputedStyle` of table rows with width/height\n\t\t// set in CSS while `offset*` properties report correct values.\n\t\t// Behavior in IE 9 is more subtle than in newer versions & it passes\n\t\t// some versions of this test; make sure not to make it pass there!\n\t\t//\n\t\t// Support: Firefox 70+\n\t\t// Only Firefox includes border widths\n\t\t// in computed dimensions. (gh-4529)\n\t\treliableTrDimensions: function() {\n\t\t\tvar table, tr, trChild, trStyle;\n\t\t\tif ( reliableTrDimensionsVal == null ) {\n\t\t\t\ttable = document.createElement( \"table\" );\n\t\t\t\ttr = document.createElement( \"tr\" );\n\t\t\t\ttrChild = document.createElement( \"div\" );\n\n\t\t\t\ttable.style.cssText = \"position:absolute;left:-11111px;border-collapse:separate\";\n\t\t\t\ttr.style.cssText = \"border:1px solid\";\n\n\t\t\t\t// Support: Chrome 86+\n\t\t\t\t// Height set through cssText does not get applied.\n\t\t\t\t// Computed height then comes back as 0.\n\t\t\t\ttr.style.height = \"1px\";\n\t\t\t\ttrChild.style.height = \"9px\";\n\n\t\t\t\t// Support: Android 8 Chrome 86+\n\t\t\t\t// In our bodyBackground.html iframe,\n\t\t\t\t// display for all div elements is set to \"inline\",\n\t\t\t\t// which causes a problem only in Android 8 Chrome 86.\n\t\t\t\t// Ensuring the div is display: block\n\t\t\t\t// gets around this issue.\n\t\t\t\ttrChild.style.display = \"block\";\n\n\t\t\t\tdocumentElement\n\t\t\t\t\t.appendChild( table )\n\t\t\t\t\t.appendChild( tr )\n\t\t\t\t\t.appendChild( trChild );\n\n\t\t\t\ttrStyle = window.getComputedStyle( tr );\n\t\t\t\treliableTrDimensionsVal = ( parseInt( trStyle.height, 10 ) +\n\t\t\t\t\tparseInt( trStyle.borderTopWidth, 10 ) +\n\t\t\t\t\tparseInt( trStyle.borderBottomWidth, 10 ) ) === tr.offsetHeight;\n\n\t\t\t\tdocumentElement.removeChild( table );\n\t\t\t}\n\t\t\treturn reliableTrDimensionsVal;\n\t\t}\n\t} );\n} )();\n\n\nfunction curCSS( elem, name, computed ) {\n\tvar width, minWidth, maxWidth, ret,\n\n\t\t// Support: Firefox 51+\n\t\t// Retrieving style before computed somehow\n\t\t// fixes an issue with getting wrong values\n\t\t// on detached elements\n\t\tstyle = elem.style;\n\n\tcomputed = computed || getStyles( elem );\n\n\t// getPropertyValue is needed for:\n\t// .css('filter') (IE 9 only, #12537)\n\t// .css('--customProperty) (#3144)\n\tif ( computed ) {\n\t\tret = computed.getPropertyValue( name ) || computed[ name ];\n\n\t\tif ( ret === \"\" && !isAttached( elem ) ) {\n\t\t\tret = jQuery.style( elem, name );\n\t\t}\n\n\t\t// A tribute to the \"awesome hack by Dean Edwards\"\n\t\t// Android Browser returns percentage for some values,\n\t\t// but width seems to be reliably pixels.\n\t\t// This is against the CSSOM draft spec:\n\t\t// https://drafts.csswg.org/cssom/#resolved-values\n\t\tif ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) {\n\n\t\t\t// Remember the original values\n\t\t\twidth = style.width;\n\t\t\tminWidth = style.minWidth;\n\t\t\tmaxWidth = style.maxWidth;\n\n\t\t\t// Put in the new values to get a computed value out\n\t\t\tstyle.minWidth = style.maxWidth = style.width = ret;\n\t\t\tret = computed.width;\n\n\t\t\t// Revert the changed values\n\t\t\tstyle.width = width;\n\t\t\tstyle.minWidth = minWidth;\n\t\t\tstyle.maxWidth = maxWidth;\n\t\t}\n\t}\n\n\treturn ret !== undefined ?\n\n\t\t// Support: IE <=9 - 11 only\n\t\t// IE returns zIndex value as an integer.\n\t\tret + \"\" :\n\t\tret;\n}\n\n\nfunction addGetHookIf( conditionFn, hookFn ) {\n\n\t// Define the hook, we'll check on the first run if it's really needed.\n\treturn {\n\t\tget: function() {\n\t\t\tif ( conditionFn() ) {\n\n\t\t\t\t// Hook not needed (or it's not possible to use it due\n\t\t\t\t// to missing dependency), remove it.\n\t\t\t\tdelete this.get;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Hook needed; redefine it so that the support test is not executed again.\n\t\t\treturn ( this.get = hookFn ).apply( this, arguments );\n\t\t}\n\t};\n}\n\n\nvar cssPrefixes = [ \"Webkit\", \"Moz\", \"ms\" ],\n\temptyStyle = document.createElement( \"div\" ).style,\n\tvendorProps = {};\n\n// Return a vendor-prefixed property or undefined\nfunction vendorPropName( name ) {\n\n\t// Check for vendor prefixed names\n\tvar capName = name[ 0 ].toUpperCase() + name.slice( 1 ),\n\t\ti = cssPrefixes.length;\n\n\twhile ( i-- ) {\n\t\tname = cssPrefixes[ i ] + capName;\n\t\tif ( name in emptyStyle ) {\n\t\t\treturn name;\n\t\t}\n\t}\n}\n\n// Return a potentially-mapped jQuery.cssProps or vendor prefixed property\nfunction finalPropName( name ) {\n\tvar final = jQuery.cssProps[ name ] || vendorProps[ name ];\n\n\tif ( final ) {\n\t\treturn final;\n\t}\n\tif ( name in emptyStyle ) {\n\t\treturn name;\n\t}\n\treturn vendorProps[ name ] = vendorPropName( name ) || name;\n}\n\n\nvar\n\n\t// Swappable if display is none or starts with table\n\t// except \"table\", \"table-cell\", or \"table-caption\"\n\t// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display\n\trdisplayswap = /^(none|table(?!-c[ea]).+)/,\n\trcustomProp = /^--/,\n\tcssShow = { position: \"absolute\", visibility: \"hidden\", display: \"block\" },\n\tcssNormalTransform = {\n\t\tletterSpacing: \"0\",\n\t\tfontWeight: \"400\"\n\t};\n\nfunction setPositiveNumber( _elem, value, subtract ) {\n\n\t// Any relative (+/-) values have already been\n\t// normalized at this point\n\tvar matches = rcssNum.exec( value );\n\treturn matches ?\n\n\t\t// Guard against undefined \"subtract\", e.g., when used as in cssHooks\n\t\tMath.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || \"px\" ) :\n\t\tvalue;\n}\n\nfunction boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) {\n\tvar i = dimension === \"width\" ? 1 : 0,\n\t\textra = 0,\n\t\tdelta = 0;\n\n\t// Adjustment may not be necessary\n\tif ( box === ( isBorderBox ? \"border\" : \"content\" ) ) {\n\t\treturn 0;\n\t}\n\n\tfor ( ; i < 4; i += 2 ) {\n\n\t\t// Both box models exclude margin\n\t\tif ( box === \"margin\" ) {\n\t\t\tdelta += jQuery.css( elem, box + cssExpand[ i ], true, styles );\n\t\t}\n\n\t\t// If we get here with a content-box, we're seeking \"padding\" or \"border\" or \"margin\"\n\t\tif ( !isBorderBox ) {\n\n\t\t\t// Add padding\n\t\t\tdelta += jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\n\t\t\t// For \"border\" or \"margin\", add border\n\t\t\tif ( box !== \"padding\" ) {\n\t\t\t\tdelta += jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\n\t\t\t// But still keep track of it otherwise\n\t\t\t} else {\n\t\t\t\textra += jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\n\t\t// If we get here with a border-box (content + padding + border), we're seeking \"content\" or\n\t\t// \"padding\" or \"margin\"\n\t\t} else {\n\n\t\t\t// For \"content\", subtract padding\n\t\t\tif ( box === \"content\" ) {\n\t\t\t\tdelta -= jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\t\t\t}\n\n\t\t\t// For \"content\" or \"padding\", subtract border\n\t\t\tif ( box !== \"margin\" ) {\n\t\t\t\tdelta -= jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\t\t}\n\t}\n\n\t// Account for positive content-box scroll gutter when requested by providing computedVal\n\tif ( !isBorderBox && computedVal >= 0 ) {\n\n\t\t// offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border\n\t\t// Assuming integer scroll gutter, subtract the rest and round down\n\t\tdelta += Math.max( 0, Math.ceil(\n\t\t\telem[ \"offset\" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -\n\t\t\tcomputedVal -\n\t\t\tdelta -\n\t\t\textra -\n\t\t\t0.5\n\n\t\t// If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter\n\t\t// Use an explicit zero to avoid NaN (gh-3964)\n\t\t) ) || 0;\n\t}\n\n\treturn delta;\n}\n\nfunction getWidthOrHeight( elem, dimension, extra ) {\n\n\t// Start with computed style\n\tvar styles = getStyles( elem ),\n\n\t\t// To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322).\n\t\t// Fake content-box until we know it's needed to know the true value.\n\t\tboxSizingNeeded = !support.boxSizingReliable() || extra,\n\t\tisBorderBox = boxSizingNeeded &&\n\t\t\tjQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\",\n\t\tvalueIsBorderBox = isBorderBox,\n\n\t\tval = curCSS( elem, dimension, styles ),\n\t\toffsetProp = \"offset\" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 );\n\n\t// Support: Firefox <=54\n\t// Return a confounding non-pixel value or feign ignorance, as appropriate.\n\tif ( rnumnonpx.test( val ) ) {\n\t\tif ( !extra ) {\n\t\t\treturn val;\n\t\t}\n\t\tval = \"auto\";\n\t}\n\n\n\t// Support: IE 9 - 11 only\n\t// Use offsetWidth/offsetHeight for when box sizing is unreliable.\n\t// In those cases, the computed value can be trusted to be border-box.\n\tif ( ( !support.boxSizingReliable() && isBorderBox ||\n\n\t\t// Support: IE 10 - 11+, Edge 15 - 18+\n\t\t// IE/Edge misreport `getComputedStyle` of table rows with width/height\n\t\t// set in CSS while `offset*` properties report correct values.\n\t\t// Interestingly, in some cases IE 9 doesn't suffer from this issue.\n\t\t!support.reliableTrDimensions() && nodeName( elem, \"tr\" ) ||\n\n\t\t// Fall back to offsetWidth/offsetHeight when value is \"auto\"\n\t\t// This happens for inline elements with no explicit setting (gh-3571)\n\t\tval === \"auto\" ||\n\n\t\t// Support: Android <=4.1 - 4.3 only\n\t\t// Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602)\n\t\t!parseFloat( val ) && jQuery.css( elem, \"display\", false, styles ) === \"inline\" ) &&\n\n\t\t// Make sure the element is visible & connected\n\t\telem.getClientRects().length ) {\n\n\t\tisBorderBox = jQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\";\n\n\t\t// Where available, offsetWidth/offsetHeight approximate border box dimensions.\n\t\t// Where not available (e.g., SVG), assume unreliable box-sizing and interpret the\n\t\t// retrieved value as a content box dimension.\n\t\tvalueIsBorderBox = offsetProp in elem;\n\t\tif ( valueIsBorderBox ) {\n\t\t\tval = elem[ offsetProp ];\n\t\t}\n\t}\n\n\t// Normalize \"\" and auto\n\tval = parseFloat( val ) || 0;\n\n\t// Adjust for the element's box model\n\treturn ( val +\n\t\tboxModelAdjustment(\n\t\t\telem,\n\t\t\tdimension,\n\t\t\textra || ( isBorderBox ? \"border\" : \"content\" ),\n\t\t\tvalueIsBorderBox,\n\t\t\tstyles,\n\n\t\t\t// Provide the current computed size to request scroll gutter calculation (gh-3589)\n\t\t\tval\n\t\t)\n\t) + \"px\";\n}\n\njQuery.extend( {\n\n\t// Add in style property hooks for overriding the default\n\t// behavior of getting and setting a style property\n\tcssHooks: {\n\t\topacity: {\n\t\t\tget: function( elem, computed ) {\n\t\t\t\tif ( computed ) {\n\n\t\t\t\t\t// We should always get a number back from opacity\n\t\t\t\t\tvar ret = curCSS( elem, \"opacity\" );\n\t\t\t\t\treturn ret === \"\" ? \"1\" : ret;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\t// Don't automatically add \"px\" to these possibly-unitless properties\n\tcssNumber: {\n\t\t\"animationIterationCount\": true,\n\t\t\"columnCount\": true,\n\t\t\"fillOpacity\": true,\n\t\t\"flexGrow\": true,\n\t\t\"flexShrink\": true,\n\t\t\"fontWeight\": true,\n\t\t\"gridArea\": true,\n\t\t\"gridColumn\": true,\n\t\t\"gridColumnEnd\": true,\n\t\t\"gridColumnStart\": true,\n\t\t\"gridRow\": true,\n\t\t\"gridRowEnd\": true,\n\t\t\"gridRowStart\": true,\n\t\t\"lineHeight\": true,\n\t\t\"opacity\": true,\n\t\t\"order\": true,\n\t\t\"orphans\": true,\n\t\t\"widows\": true,\n\t\t\"zIndex\": true,\n\t\t\"zoom\": true\n\t},\n\n\t// Add in properties whose names you wish to fix before\n\t// setting or getting the value\n\tcssProps: {},\n\n\t// Get and set the style property on a DOM Node\n\tstyle: function( elem, name, value, extra ) {\n\n\t\t// Don't set styles on text and comment nodes\n\t\tif ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Make sure that we're working with the right name\n\t\tvar ret, type, hooks,\n\t\t\torigName = camelCase( name ),\n\t\t\tisCustomProp = rcustomProp.test( name ),\n\t\t\tstyle = elem.style;\n\n\t\t// Make sure that we're working with the right name. We don't\n\t\t// want to query the value if it is a CSS custom property\n\t\t// since they are user-defined.\n\t\tif ( !isCustomProp ) {\n\t\t\tname = finalPropName( origName );\n\t\t}\n\n\t\t// Gets hook for the prefixed version, then unprefixed version\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// Check if we're setting a value\n\t\tif ( value !== undefined ) {\n\t\t\ttype = typeof value;\n\n\t\t\t// Convert \"+=\" or \"-=\" to relative numbers (#7345)\n\t\t\tif ( type === \"string\" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {\n\t\t\t\tvalue = adjustCSS( elem, name, ret );\n\n\t\t\t\t// Fixes bug #9237\n\t\t\t\ttype = \"number\";\n\t\t\t}\n\n\t\t\t// Make sure that null and NaN values aren't set (#7116)\n\t\t\tif ( value == null || value !== value ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If a number was passed in, add the unit (except for certain CSS properties)\n\t\t\t// The isCustomProp check can be removed in jQuery 4.0 when we only auto-append\n\t\t\t// \"px\" to a few hardcoded values.\n\t\t\tif ( type === \"number\" && !isCustomProp ) {\n\t\t\t\tvalue += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? \"\" : \"px\" );\n\t\t\t}\n\n\t\t\t// background-* props affect original clone's values\n\t\t\tif ( !support.clearCloneStyle && value === \"\" && name.indexOf( \"background\" ) === 0 ) {\n\t\t\t\tstyle[ name ] = \"inherit\";\n\t\t\t}\n\n\t\t\t// If a hook was provided, use that value, otherwise just set the specified value\n\t\t\tif ( !hooks || !( \"set\" in hooks ) ||\n\t\t\t\t( value = hooks.set( elem, value, extra ) ) !== undefined ) {\n\n\t\t\t\tif ( isCustomProp ) {\n\t\t\t\t\tstyle.setProperty( name, value );\n\t\t\t\t} else {\n\t\t\t\t\tstyle[ name ] = value;\n\t\t\t\t}\n\t\t\t}\n\n\t\t} else {\n\n\t\t\t// If a hook was provided get the non-computed value from there\n\t\t\tif ( hooks && \"get\" in hooks &&\n\t\t\t\t( ret = hooks.get( elem, false, extra ) ) !== undefined ) {\n\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\t// Otherwise just get the value from the style object\n\t\t\treturn style[ name ];\n\t\t}\n\t},\n\n\tcss: function( elem, name, extra, styles ) {\n\t\tvar val, num, hooks,\n\t\t\torigName = camelCase( name ),\n\t\t\tisCustomProp = rcustomProp.test( name );\n\n\t\t// Make sure that we're working with the right name. We don't\n\t\t// want to modify the value if it is a CSS custom property\n\t\t// since they are user-defined.\n\t\tif ( !isCustomProp ) {\n\t\t\tname = finalPropName( origName );\n\t\t}\n\n\t\t// Try prefixed name followed by the unprefixed name\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// If a hook was provided get the computed value from there\n\t\tif ( hooks && \"get\" in hooks ) {\n\t\t\tval = hooks.get( elem, true, extra );\n\t\t}\n\n\t\t// Otherwise, if a way to get the computed value exists, use that\n\t\tif ( val === undefined ) {\n\t\t\tval = curCSS( elem, name, styles );\n\t\t}\n\n\t\t// Convert \"normal\" to computed value\n\t\tif ( val === \"normal\" && name in cssNormalTransform ) {\n\t\t\tval = cssNormalTransform[ name ];\n\t\t}\n\n\t\t// Make numeric if forced or a qualifier was provided and val looks numeric\n\t\tif ( extra === \"\" || extra ) {\n\t\t\tnum = parseFloat( val );\n\t\t\treturn extra === true || isFinite( num ) ? num || 0 : val;\n\t\t}\n\n\t\treturn val;\n\t}\n} );\n\njQuery.each( [ \"height\", \"width\" ], function( _i, dimension ) {\n\tjQuery.cssHooks[ dimension ] = {\n\t\tget: function( elem, computed, extra ) {\n\t\t\tif ( computed ) {\n\n\t\t\t\t// Certain elements can have dimension info if we invisibly show them\n\t\t\t\t// but it must have a current display style that would benefit\n\t\t\t\treturn rdisplayswap.test( jQuery.css( elem, \"display\" ) ) &&\n\n\t\t\t\t\t// Support: Safari 8+\n\t\t\t\t\t// Table columns in Safari have non-zero offsetWidth & zero\n\t\t\t\t\t// getBoundingClientRect().width unless display is changed.\n\t\t\t\t\t// Support: IE <=11 only\n\t\t\t\t\t// Running getBoundingClientRect on a disconnected node\n\t\t\t\t\t// in IE throws an error.\n\t\t\t\t\t( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?\n\t\t\t\t\tswap( elem, cssShow, function() {\n\t\t\t\t\t\treturn getWidthOrHeight( elem, dimension, extra );\n\t\t\t\t\t} ) :\n\t\t\t\t\tgetWidthOrHeight( elem, dimension, extra );\n\t\t\t}\n\t\t},\n\n\t\tset: function( elem, value, extra ) {\n\t\t\tvar matches,\n\t\t\t\tstyles = getStyles( elem ),\n\n\t\t\t\t// Only read styles.position if the test has a chance to fail\n\t\t\t\t// to avoid forcing a reflow.\n\t\t\t\tscrollboxSizeBuggy = !support.scrollboxSize() &&\n\t\t\t\t\tstyles.position === \"absolute\",\n\n\t\t\t\t// To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991)\n\t\t\t\tboxSizingNeeded = scrollboxSizeBuggy || extra,\n\t\t\t\tisBorderBox = boxSizingNeeded &&\n\t\t\t\t\tjQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\",\n\t\t\t\tsubtract = extra ?\n\t\t\t\t\tboxModelAdjustment(\n\t\t\t\t\t\telem,\n\t\t\t\t\t\tdimension,\n\t\t\t\t\t\textra,\n\t\t\t\t\t\tisBorderBox,\n\t\t\t\t\t\tstyles\n\t\t\t\t\t) :\n\t\t\t\t\t0;\n\n\t\t\t// Account for unreliable border-box dimensions by comparing offset* to computed and\n\t\t\t// faking a content-box to get border and padding (gh-3699)\n\t\t\tif ( isBorderBox && scrollboxSizeBuggy ) {\n\t\t\t\tsubtract -= Math.ceil(\n\t\t\t\t\telem[ \"offset\" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -\n\t\t\t\t\tparseFloat( styles[ dimension ] ) -\n\t\t\t\t\tboxModelAdjustment( elem, dimension, \"border\", false, styles ) -\n\t\t\t\t\t0.5\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Convert to pixels if value adjustment is needed\n\t\t\tif ( subtract && ( matches = rcssNum.exec( value ) ) &&\n\t\t\t\t( matches[ 3 ] || \"px\" ) !== \"px\" ) {\n\n\t\t\t\telem.style[ dimension ] = value;\n\t\t\t\tvalue = jQuery.css( elem, dimension );\n\t\t\t}\n\n\t\t\treturn setPositiveNumber( elem, value, subtract );\n\t\t}\n\t};\n} );\n\njQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,\n\tfunction( elem, computed ) {\n\t\tif ( computed ) {\n\t\t\treturn ( parseFloat( curCSS( elem, \"marginLeft\" ) ) ||\n\t\t\t\telem.getBoundingClientRect().left -\n\t\t\t\t\tswap( elem, { marginLeft: 0 }, function() {\n\t\t\t\t\t\treturn elem.getBoundingClientRect().left;\n\t\t\t\t\t} )\n\t\t\t) + \"px\";\n\t\t}\n\t}\n);\n\n// These hooks are used by animate to expand properties\njQuery.each( {\n\tmargin: \"\",\n\tpadding: \"\",\n\tborder: \"Width\"\n}, function( prefix, suffix ) {\n\tjQuery.cssHooks[ prefix + suffix ] = {\n\t\texpand: function( value ) {\n\t\t\tvar i = 0,\n\t\t\t\texpanded = {},\n\n\t\t\t\t// Assumes a single number if not a string\n\t\t\t\tparts = typeof value === \"string\" ? value.split( \" \" ) : [ value ];\n\n\t\t\tfor ( ; i < 4; i++ ) {\n\t\t\t\texpanded[ prefix + cssExpand[ i ] + suffix ] =\n\t\t\t\t\tparts[ i ] || parts[ i - 2 ] || parts[ 0 ];\n\t\t\t}\n\n\t\t\treturn expanded;\n\t\t}\n\t};\n\n\tif ( prefix !== \"margin\" ) {\n\t\tjQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;\n\t}\n} );\n\njQuery.fn.extend( {\n\tcss: function( name, value ) {\n\t\treturn access( this, function( elem, name, value ) {\n\t\t\tvar styles, len,\n\t\t\t\tmap = {},\n\t\t\t\ti = 0;\n\n\t\t\tif ( Array.isArray( name ) ) {\n\t\t\t\tstyles = getStyles( elem );\n\t\t\t\tlen = name.length;\n\n\t\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\t\tmap[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );\n\t\t\t\t}\n\n\t\t\t\treturn map;\n\t\t\t}\n\n\t\t\treturn value !== undefined ?\n\t\t\t\tjQuery.style( elem, name, value ) :\n\t\t\t\tjQuery.css( elem, name );\n\t\t}, name, value, arguments.length > 1 );\n\t}\n} );\n\n\nfunction Tween( elem, options, prop, end, easing ) {\n\treturn new Tween.prototype.init( elem, options, prop, end, easing );\n}\njQuery.Tween = Tween;\n\nTween.prototype = {\n\tconstructor: Tween,\n\tinit: function( elem, options, prop, end, easing, unit ) {\n\t\tthis.elem = elem;\n\t\tthis.prop = prop;\n\t\tthis.easing = easing || jQuery.easing._default;\n\t\tthis.options = options;\n\t\tthis.start = this.now = this.cur();\n\t\tthis.end = end;\n\t\tthis.unit = unit || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" );\n\t},\n\tcur: function() {\n\t\tvar hooks = Tween.propHooks[ this.prop ];\n\n\t\treturn hooks && hooks.get ?\n\t\t\thooks.get( this ) :\n\t\t\tTween.propHooks._default.get( this );\n\t},\n\trun: function( percent ) {\n\t\tvar eased,\n\t\t\thooks = Tween.propHooks[ this.prop ];\n\n\t\tif ( this.options.duration ) {\n\t\t\tthis.pos = eased = jQuery.easing[ this.easing ](\n\t\t\t\tpercent, this.options.duration * percent, 0, 1, this.options.duration\n\t\t\t);\n\t\t} else {\n\t\t\tthis.pos = eased = percent;\n\t\t}\n\t\tthis.now = ( this.end - this.start ) * eased + this.start;\n\n\t\tif ( this.options.step ) {\n\t\t\tthis.options.step.call( this.elem, this.now, this );\n\t\t}\n\n\t\tif ( hooks && hooks.set ) {\n\t\t\thooks.set( this );\n\t\t} else {\n\t\t\tTween.propHooks._default.set( this );\n\t\t}\n\t\treturn this;\n\t}\n};\n\nTween.prototype.init.prototype = Tween.prototype;\n\nTween.propHooks = {\n\t_default: {\n\t\tget: function( tween ) {\n\t\t\tvar result;\n\n\t\t\t// Use a property on the element directly when it is not a DOM element,\n\t\t\t// or when there is no matching style property that exists.\n\t\t\tif ( tween.elem.nodeType !== 1 ||\n\t\t\t\ttween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {\n\t\t\t\treturn tween.elem[ tween.prop ];\n\t\t\t}\n\n\t\t\t// Passing an empty string as a 3rd parameter to .css will automatically\n\t\t\t// attempt a parseFloat and fallback to a string if the parse fails.\n\t\t\t// Simple values such as \"10px\" are parsed to Float;\n\t\t\t// complex values such as \"rotate(1rad)\" are returned as-is.\n\t\t\tresult = jQuery.css( tween.elem, tween.prop, \"\" );\n\n\t\t\t// Empty strings, null, undefined and \"auto\" are converted to 0.\n\t\t\treturn !result || result === \"auto\" ? 0 : result;\n\t\t},\n\t\tset: function( tween ) {\n\n\t\t\t// Use step hook for back compat.\n\t\t\t// Use cssHook if its there.\n\t\t\t// Use .style if available and use plain properties where available.\n\t\t\tif ( jQuery.fx.step[ tween.prop ] ) {\n\t\t\t\tjQuery.fx.step[ tween.prop ]( tween );\n\t\t\t} else if ( tween.elem.nodeType === 1 && (\n\t\t\t\tjQuery.cssHooks[ tween.prop ] ||\n\t\t\t\t\ttween.elem.style[ finalPropName( tween.prop ) ] != null ) ) {\n\t\t\t\tjQuery.style( tween.elem, tween.prop, tween.now + tween.unit );\n\t\t\t} else {\n\t\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t\t}\n\t\t}\n\t}\n};\n\n// Support: IE <=9 only\n// Panic based approach to setting things on disconnected nodes\nTween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {\n\tset: function( tween ) {\n\t\tif ( tween.elem.nodeType && tween.elem.parentNode ) {\n\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t}\n\t}\n};\n\njQuery.easing = {\n\tlinear: function( p ) {\n\t\treturn p;\n\t},\n\tswing: function( p ) {\n\t\treturn 0.5 - Math.cos( p * Math.PI ) / 2;\n\t},\n\t_default: \"swing\"\n};\n\njQuery.fx = Tween.prototype.init;\n\n// Back compat <1.8 extension point\njQuery.fx.step = {};\n\n\n\n\nvar\n\tfxNow, inProgress,\n\trfxtypes = /^(?:toggle|show|hide)$/,\n\trrun = /queueHooks$/;\n\nfunction schedule() {\n\tif ( inProgress ) {\n\t\tif ( document.hidden === false && window.requestAnimationFrame ) {\n\t\t\twindow.requestAnimationFrame( schedule );\n\t\t} else {\n\t\t\twindow.setTimeout( schedule, jQuery.fx.interval );\n\t\t}\n\n\t\tjQuery.fx.tick();\n\t}\n}\n\n// Animations created synchronously will run synchronously\nfunction createFxNow() {\n\twindow.setTimeout( function() {\n\t\tfxNow = undefined;\n\t} );\n\treturn ( fxNow = Date.now() );\n}\n\n// Generate parameters to create a standard animation\nfunction genFx( type, includeWidth ) {\n\tvar which,\n\t\ti = 0,\n\t\tattrs = { height: type };\n\n\t// If we include width, step value is 1 to do all cssExpand values,\n\t// otherwise step value is 2 to skip over Left and Right\n\tincludeWidth = includeWidth ? 1 : 0;\n\tfor ( ; i < 4; i += 2 - includeWidth ) {\n\t\twhich = cssExpand[ i ];\n\t\tattrs[ \"margin\" + which ] = attrs[ \"padding\" + which ] = type;\n\t}\n\n\tif ( includeWidth ) {\n\t\tattrs.opacity = attrs.width = type;\n\t}\n\n\treturn attrs;\n}\n\nfunction createTween( value, prop, animation ) {\n\tvar tween,\n\t\tcollection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ \"*\" ] ),\n\t\tindex = 0,\n\t\tlength = collection.length;\n\tfor ( ; index < length; index++ ) {\n\t\tif ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {\n\n\t\t\t// We're done with this property\n\t\t\treturn tween;\n\t\t}\n\t}\n}\n\nfunction defaultPrefilter( elem, props, opts ) {\n\tvar prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,\n\t\tisBox = \"width\" in props || \"height\" in props,\n\t\tanim = this,\n\t\torig = {},\n\t\tstyle = elem.style,\n\t\thidden = elem.nodeType && isHiddenWithinTree( elem ),\n\t\tdataShow = dataPriv.get( elem, \"fxshow\" );\n\n\t// Queue-skipping animations hijack the fx hooks\n\tif ( !opts.queue ) {\n\t\thooks = jQuery._queueHooks( elem, \"fx\" );\n\t\tif ( hooks.unqueued == null ) {\n\t\t\thooks.unqueued = 0;\n\t\t\toldfire = hooks.empty.fire;\n\t\t\thooks.empty.fire = function() {\n\t\t\t\tif ( !hooks.unqueued ) {\n\t\t\t\t\toldfire();\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\thooks.unqueued++;\n\n\t\tanim.always( function() {\n\n\t\t\t// Ensure the complete handler is called before this completes\n\t\t\tanim.always( function() {\n\t\t\t\thooks.unqueued--;\n\t\t\t\tif ( !jQuery.queue( elem, \"fx\" ).length ) {\n\t\t\t\t\thooks.empty.fire();\n\t\t\t\t}\n\t\t\t} );\n\t\t} );\n\t}\n\n\t// Detect show/hide animations\n\tfor ( prop in props ) {\n\t\tvalue = props[ prop ];\n\t\tif ( rfxtypes.test( value ) ) {\n\t\t\tdelete props[ prop ];\n\t\t\ttoggle = toggle || value === \"toggle\";\n\t\t\tif ( value === ( hidden ? \"hide\" : \"show\" ) ) {\n\n\t\t\t\t// Pretend to be hidden if this is a \"show\" and\n\t\t\t\t// there is still data from a stopped show/hide\n\t\t\t\tif ( value === \"show\" && dataShow && dataShow[ prop ] !== undefined ) {\n\t\t\t\t\thidden = true;\n\n\t\t\t\t// Ignore all other no-op show/hide data\n\t\t\t\t} else {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\torig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );\n\t\t}\n\t}\n\n\t// Bail out if this is a no-op like .hide().hide()\n\tpropTween = !jQuery.isEmptyObject( props );\n\tif ( !propTween && jQuery.isEmptyObject( orig ) ) {\n\t\treturn;\n\t}\n\n\t// Restrict \"overflow\" and \"display\" styles during box animations\n\tif ( isBox && elem.nodeType === 1 ) {\n\n\t\t// Support: IE <=9 - 11, Edge 12 - 15\n\t\t// Record all 3 overflow attributes because IE does not infer the shorthand\n\t\t// from identically-valued overflowX and overflowY and Edge just mirrors\n\t\t// the overflowX value there.\n\t\topts.overflow = [ style.overflow, style.overflowX, style.overflowY ];\n\n\t\t// Identify a display type, preferring old show/hide data over the CSS cascade\n\t\trestoreDisplay = dataShow && dataShow.display;\n\t\tif ( restoreDisplay == null ) {\n\t\t\trestoreDisplay = dataPriv.get( elem, \"display\" );\n\t\t}\n\t\tdisplay = jQuery.css( elem, \"display\" );\n\t\tif ( display === \"none\" ) {\n\t\t\tif ( restoreDisplay ) {\n\t\t\t\tdisplay = restoreDisplay;\n\t\t\t} else {\n\n\t\t\t\t// Get nonempty value(s) by temporarily forcing visibility\n\t\t\t\tshowHide( [ elem ], true );\n\t\t\t\trestoreDisplay = elem.style.display || restoreDisplay;\n\t\t\t\tdisplay = jQuery.css( elem, \"display\" );\n\t\t\t\tshowHide( [ elem ] );\n\t\t\t}\n\t\t}\n\n\t\t// Animate inline elements as inline-block\n\t\tif ( display === \"inline\" || display === \"inline-block\" && restoreDisplay != null ) {\n\t\t\tif ( jQuery.css( elem, \"float\" ) === \"none\" ) {\n\n\t\t\t\t// Restore the original display value at the end of pure show/hide animations\n\t\t\t\tif ( !propTween ) {\n\t\t\t\t\tanim.done( function() {\n\t\t\t\t\t\tstyle.display = restoreDisplay;\n\t\t\t\t\t} );\n\t\t\t\t\tif ( restoreDisplay == null ) {\n\t\t\t\t\t\tdisplay = style.display;\n\t\t\t\t\t\trestoreDisplay = display === \"none\" ? \"\" : display;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tstyle.display = \"inline-block\";\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( opts.overflow ) {\n\t\tstyle.overflow = \"hidden\";\n\t\tanim.always( function() {\n\t\t\tstyle.overflow = opts.overflow[ 0 ];\n\t\t\tstyle.overflowX = opts.overflow[ 1 ];\n\t\t\tstyle.overflowY = opts.overflow[ 2 ];\n\t\t} );\n\t}\n\n\t// Implement show/hide animations\n\tpropTween = false;\n\tfor ( prop in orig ) {\n\n\t\t// General show/hide setup for this element animation\n\t\tif ( !propTween ) {\n\t\t\tif ( dataShow ) {\n\t\t\t\tif ( \"hidden\" in dataShow ) {\n\t\t\t\t\thidden = dataShow.hidden;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tdataShow = dataPriv.access( elem, \"fxshow\", { display: restoreDisplay } );\n\t\t\t}\n\n\t\t\t// Store hidden/visible for toggle so `.stop().toggle()` \"reverses\"\n\t\t\tif ( toggle ) {\n\t\t\t\tdataShow.hidden = !hidden;\n\t\t\t}\n\n\t\t\t// Show elements before animating them\n\t\t\tif ( hidden ) {\n\t\t\t\tshowHide( [ elem ], true );\n\t\t\t}\n\n\t\t\t/* eslint-disable no-loop-func */\n\n\t\t\tanim.done( function() {\n\n\t\t\t\t/* eslint-enable no-loop-func */\n\n\t\t\t\t// The final step of a \"hide\" animation is actually hiding the element\n\t\t\t\tif ( !hidden ) {\n\t\t\t\t\tshowHide( [ elem ] );\n\t\t\t\t}\n\t\t\t\tdataPriv.remove( elem, \"fxshow\" );\n\t\t\t\tfor ( prop in orig ) {\n\t\t\t\t\tjQuery.style( elem, prop, orig[ prop ] );\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\n\t\t// Per-property setup\n\t\tpropTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );\n\t\tif ( !( prop in dataShow ) ) {\n\t\t\tdataShow[ prop ] = propTween.start;\n\t\t\tif ( hidden ) {\n\t\t\t\tpropTween.end = propTween.start;\n\t\t\t\tpropTween.start = 0;\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction propFilter( props, specialEasing ) {\n\tvar index, name, easing, value, hooks;\n\n\t// camelCase, specialEasing and expand cssHook pass\n\tfor ( index in props ) {\n\t\tname = camelCase( index );\n\t\teasing = specialEasing[ name ];\n\t\tvalue = props[ index ];\n\t\tif ( Array.isArray( value ) ) {\n\t\t\teasing = value[ 1 ];\n\t\t\tvalue = props[ index ] = value[ 0 ];\n\t\t}\n\n\t\tif ( index !== name ) {\n\t\t\tprops[ name ] = value;\n\t\t\tdelete props[ index ];\n\t\t}\n\n\t\thooks = jQuery.cssHooks[ name ];\n\t\tif ( hooks && \"expand\" in hooks ) {\n\t\t\tvalue = hooks.expand( value );\n\t\t\tdelete props[ name ];\n\n\t\t\t// Not quite $.extend, this won't overwrite existing keys.\n\t\t\t// Reusing 'index' because we have the correct \"name\"\n\t\t\tfor ( index in value ) {\n\t\t\t\tif ( !( index in props ) ) {\n\t\t\t\t\tprops[ index ] = value[ index ];\n\t\t\t\t\tspecialEasing[ index ] = easing;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tspecialEasing[ name ] = easing;\n\t\t}\n\t}\n}\n\nfunction Animation( elem, properties, options ) {\n\tvar result,\n\t\tstopped,\n\t\tindex = 0,\n\t\tlength = Animation.prefilters.length,\n\t\tdeferred = jQuery.Deferred().always( function() {\n\n\t\t\t// Don't match elem in the :animated selector\n\t\t\tdelete tick.elem;\n\t\t} ),\n\t\ttick = function() {\n\t\t\tif ( stopped ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvar currentTime = fxNow || createFxNow(),\n\t\t\t\tremaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),\n\n\t\t\t\t// Support: Android 2.3 only\n\t\t\t\t// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)\n\t\t\t\ttemp = remaining / animation.duration || 0,\n\t\t\t\tpercent = 1 - temp,\n\t\t\t\tindex = 0,\n\t\t\t\tlength = animation.tweens.length;\n\n\t\t\tfor ( ; index < length; index++ ) {\n\t\t\t\tanimation.tweens[ index ].run( percent );\n\t\t\t}\n\n\t\t\tdeferred.notifyWith( elem, [ animation, percent, remaining ] );\n\n\t\t\t// If there's more to do, yield\n\t\t\tif ( percent < 1 && length ) {\n\t\t\t\treturn remaining;\n\t\t\t}\n\n\t\t\t// If this was an empty animation, synthesize a final progress notification\n\t\t\tif ( !length ) {\n\t\t\t\tdeferred.notifyWith( elem, [ animation, 1, 0 ] );\n\t\t\t}\n\n\t\t\t// Resolve the animation and report its conclusion\n\t\t\tdeferred.resolveWith( elem, [ animation ] );\n\t\t\treturn false;\n\t\t},\n\t\tanimation = deferred.promise( {\n\t\t\telem: elem,\n\t\t\tprops: jQuery.extend( {}, properties ),\n\t\t\topts: jQuery.extend( true, {\n\t\t\t\tspecialEasing: {},\n\t\t\t\teasing: jQuery.easing._default\n\t\t\t}, options ),\n\t\t\toriginalProperties: properties,\n\t\t\toriginalOptions: options,\n\t\t\tstartTime: fxNow || createFxNow(),\n\t\t\tduration: options.duration,\n\t\t\ttweens: [],\n\t\t\tcreateTween: function( prop, end ) {\n\t\t\t\tvar tween = jQuery.Tween( elem, animation.opts, prop, end,\n\t\t\t\t\tanimation.opts.specialEasing[ prop ] || animation.opts.easing );\n\t\t\t\tanimation.tweens.push( tween );\n\t\t\t\treturn tween;\n\t\t\t},\n\t\t\tstop: function( gotoEnd ) {\n\t\t\t\tvar index = 0,\n\n\t\t\t\t\t// If we are going to the end, we want to run all the tweens\n\t\t\t\t\t// otherwise we skip this part\n\t\t\t\t\tlength = gotoEnd ? animation.tweens.length : 0;\n\t\t\t\tif ( stopped ) {\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t\tstopped = true;\n\t\t\t\tfor ( ; index < length; index++ ) {\n\t\t\t\t\tanimation.tweens[ index ].run( 1 );\n\t\t\t\t}\n\n\t\t\t\t// Resolve when we played the last frame; otherwise, reject\n\t\t\t\tif ( gotoEnd ) {\n\t\t\t\t\tdeferred.notifyWith( elem, [ animation, 1, 0 ] );\n\t\t\t\t\tdeferred.resolveWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t} else {\n\t\t\t\t\tdeferred.rejectWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t}\n\t\t} ),\n\t\tprops = animation.props;\n\n\tpropFilter( props, animation.opts.specialEasing );\n\n\tfor ( ; index < length; index++ ) {\n\t\tresult = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );\n\t\tif ( result ) {\n\t\t\tif ( isFunction( result.stop ) ) {\n\t\t\t\tjQuery._queueHooks( animation.elem, animation.opts.queue ).stop =\n\t\t\t\t\tresult.stop.bind( result );\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t}\n\n\tjQuery.map( props, createTween, animation );\n\n\tif ( isFunction( animation.opts.start ) ) {\n\t\tanimation.opts.start.call( elem, animation );\n\t}\n\n\t// Attach callbacks from options\n\tanimation\n\t\t.progress( animation.opts.progress )\n\t\t.done( animation.opts.done, animation.opts.complete )\n\t\t.fail( animation.opts.fail )\n\t\t.always( animation.opts.always );\n\n\tjQuery.fx.timer(\n\t\tjQuery.extend( tick, {\n\t\t\telem: elem,\n\t\t\tanim: animation,\n\t\t\tqueue: animation.opts.queue\n\t\t} )\n\t);\n\n\treturn animation;\n}\n\njQuery.Animation = jQuery.extend( Animation, {\n\n\ttweeners: {\n\t\t\"*\": [ function( prop, value ) {\n\t\t\tvar tween = this.createTween( prop, value );\n\t\t\tadjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );\n\t\t\treturn tween;\n\t\t} ]\n\t},\n\n\ttweener: function( props, callback ) {\n\t\tif ( isFunction( props ) ) {\n\t\t\tcallback = props;\n\t\t\tprops = [ \"*\" ];\n\t\t} else {\n\t\t\tprops = props.match( rnothtmlwhite );\n\t\t}\n\n\t\tvar prop,\n\t\t\tindex = 0,\n\t\t\tlength = props.length;\n\n\t\tfor ( ; index < length; index++ ) {\n\t\t\tprop = props[ index ];\n\t\t\tAnimation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];\n\t\t\tAnimation.tweeners[ prop ].unshift( callback );\n\t\t}\n\t},\n\n\tprefilters: [ defaultPrefilter ],\n\n\tprefilter: function( callback, prepend ) {\n\t\tif ( prepend ) {\n\t\t\tAnimation.prefilters.unshift( callback );\n\t\t} else {\n\t\t\tAnimation.prefilters.push( callback );\n\t\t}\n\t}\n} );\n\njQuery.speed = function( speed, easing, fn ) {\n\tvar opt = speed && typeof speed === \"object\" ? jQuery.extend( {}, speed ) : {\n\t\tcomplete: fn || !fn && easing ||\n\t\t\tisFunction( speed ) && speed,\n\t\tduration: speed,\n\t\teasing: fn && easing || easing && !isFunction( easing ) && easing\n\t};\n\n\t// Go to the end state if fx are off\n\tif ( jQuery.fx.off ) {\n\t\topt.duration = 0;\n\n\t} else {\n\t\tif ( typeof opt.duration !== \"number\" ) {\n\t\t\tif ( opt.duration in jQuery.fx.speeds ) {\n\t\t\t\topt.duration = jQuery.fx.speeds[ opt.duration ];\n\n\t\t\t} else {\n\t\t\t\topt.duration = jQuery.fx.speeds._default;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Normalize opt.queue - true/undefined/null -> \"fx\"\n\tif ( opt.queue == null || opt.queue === true ) {\n\t\topt.queue = \"fx\";\n\t}\n\n\t// Queueing\n\topt.old = opt.complete;\n\n\topt.complete = function() {\n\t\tif ( isFunction( opt.old ) ) {\n\t\t\topt.old.call( this );\n\t\t}\n\n\t\tif ( opt.queue ) {\n\t\t\tjQuery.dequeue( this, opt.queue );\n\t\t}\n\t};\n\n\treturn opt;\n};\n\njQuery.fn.extend( {\n\tfadeTo: function( speed, to, easing, callback ) {\n\n\t\t// Show any hidden elements after setting opacity to 0\n\t\treturn this.filter( isHiddenWithinTree ).css( \"opacity\", 0 ).show()\n\n\t\t\t// Animate to the value specified\n\t\t\t.end().animate( { opacity: to }, speed, easing, callback );\n\t},\n\tanimate: function( prop, speed, easing, callback ) {\n\t\tvar empty = jQuery.isEmptyObject( prop ),\n\t\t\toptall = jQuery.speed( speed, easing, callback ),\n\t\t\tdoAnimation = function() {\n\n\t\t\t\t// Operate on a copy of prop so per-property easing won't be lost\n\t\t\t\tvar anim = Animation( this, jQuery.extend( {}, prop ), optall );\n\n\t\t\t\t// Empty animations, or finishing resolves immediately\n\t\t\t\tif ( empty || dataPriv.get( this, \"finish\" ) ) {\n\t\t\t\t\tanim.stop( true );\n\t\t\t\t}\n\t\t\t};\n\n\t\tdoAnimation.finish = doAnimation;\n\n\t\treturn empty || optall.queue === false ?\n\t\t\tthis.each( doAnimation ) :\n\t\t\tthis.queue( optall.queue, doAnimation );\n\t},\n\tstop: function( type, clearQueue, gotoEnd ) {\n\t\tvar stopQueue = function( hooks ) {\n\t\t\tvar stop = hooks.stop;\n\t\t\tdelete hooks.stop;\n\t\t\tstop( gotoEnd );\n\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tgotoEnd = clearQueue;\n\t\t\tclearQueue = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\tif ( clearQueue ) {\n\t\t\tthis.queue( type || \"fx\", [] );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar dequeue = true,\n\t\t\t\tindex = type != null && type + \"queueHooks\",\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tdata = dataPriv.get( this );\n\n\t\t\tif ( index ) {\n\t\t\t\tif ( data[ index ] && data[ index ].stop ) {\n\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( index in data ) {\n\t\t\t\t\tif ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {\n\t\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this &&\n\t\t\t\t\t( type == null || timers[ index ].queue === type ) ) {\n\n\t\t\t\t\ttimers[ index ].anim.stop( gotoEnd );\n\t\t\t\t\tdequeue = false;\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Start the next in the queue if the last step wasn't forced.\n\t\t\t// Timers currently will call their complete callbacks, which\n\t\t\t// will dequeue but only if they were gotoEnd.\n\t\t\tif ( dequeue || !gotoEnd ) {\n\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t}\n\t\t} );\n\t},\n\tfinish: function( type ) {\n\t\tif ( type !== false ) {\n\t\t\ttype = type || \"fx\";\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tvar index,\n\t\t\t\tdata = dataPriv.get( this ),\n\t\t\t\tqueue = data[ type + \"queue\" ],\n\t\t\t\thooks = data[ type + \"queueHooks\" ],\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tlength = queue ? queue.length : 0;\n\n\t\t\t// Enable finishing flag on private data\n\t\t\tdata.finish = true;\n\n\t\t\t// Empty the queue first\n\t\t\tjQuery.queue( this, type, [] );\n\n\t\t\tif ( hooks && hooks.stop ) {\n\t\t\t\thooks.stop.call( this, true );\n\t\t\t}\n\n\t\t\t// Look for any active animations, and finish them\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this && timers[ index ].queue === type ) {\n\t\t\t\t\ttimers[ index ].anim.stop( true );\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Look for any animations in the old queue and finish them\n\t\t\tfor ( index = 0; index < length; index++ ) {\n\t\t\t\tif ( queue[ index ] && queue[ index ].finish ) {\n\t\t\t\t\tqueue[ index ].finish.call( this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Turn off finishing flag\n\t\t\tdelete data.finish;\n\t\t} );\n\t}\n} );\n\njQuery.each( [ \"toggle\", \"show\", \"hide\" ], function( _i, name ) {\n\tvar cssFn = jQuery.fn[ name ];\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn speed == null || typeof speed === \"boolean\" ?\n\t\t\tcssFn.apply( this, arguments ) :\n\t\t\tthis.animate( genFx( name, true ), speed, easing, callback );\n\t};\n} );\n\n// Generate shortcuts for custom animations\njQuery.each( {\n\tslideDown: genFx( \"show\" ),\n\tslideUp: genFx( \"hide\" ),\n\tslideToggle: genFx( \"toggle\" ),\n\tfadeIn: { opacity: \"show\" },\n\tfadeOut: { opacity: \"hide\" },\n\tfadeToggle: { opacity: \"toggle\" }\n}, function( name, props ) {\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn this.animate( props, speed, easing, callback );\n\t};\n} );\n\njQuery.timers = [];\njQuery.fx.tick = function() {\n\tvar timer,\n\t\ti = 0,\n\t\ttimers = jQuery.timers;\n\n\tfxNow = Date.now();\n\n\tfor ( ; i < timers.length; i++ ) {\n\t\ttimer = timers[ i ];\n\n\t\t// Run the timer and safely remove it when done (allowing for external removal)\n\t\tif ( !timer() && timers[ i ] === timer ) {\n\t\t\ttimers.splice( i--, 1 );\n\t\t}\n\t}\n\n\tif ( !timers.length ) {\n\t\tjQuery.fx.stop();\n\t}\n\tfxNow = undefined;\n};\n\njQuery.fx.timer = function( timer ) {\n\tjQuery.timers.push( timer );\n\tjQuery.fx.start();\n};\n\njQuery.fx.interval = 13;\njQuery.fx.start = function() {\n\tif ( inProgress ) {\n\t\treturn;\n\t}\n\n\tinProgress = true;\n\tschedule();\n};\n\njQuery.fx.stop = function() {\n\tinProgress = null;\n};\n\njQuery.fx.speeds = {\n\tslow: 600,\n\tfast: 200,\n\n\t// Default speed\n\t_default: 400\n};\n\n\n// Based off of the plugin by Clint Helfers, with permission.\n// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/\njQuery.fn.delay = function( time, type ) {\n\ttime = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;\n\ttype = type || \"fx\";\n\n\treturn this.queue( type, function( next, hooks ) {\n\t\tvar timeout = window.setTimeout( next, time );\n\t\thooks.stop = function() {\n\t\t\twindow.clearTimeout( timeout );\n\t\t};\n\t} );\n};\n\n\n( function() {\n\tvar input = document.createElement( \"input\" ),\n\t\tselect = document.createElement( \"select\" ),\n\t\topt = select.appendChild( document.createElement( \"option\" ) );\n\n\tinput.type = \"checkbox\";\n\n\t// Support: Android <=4.3 only\n\t// Default value for a checkbox should be \"on\"\n\tsupport.checkOn = input.value !== \"\";\n\n\t// Support: IE <=11 only\n\t// Must access selectedIndex to make default options select\n\tsupport.optSelected = opt.selected;\n\n\t// Support: IE <=11 only\n\t// An input loses its value after becoming a radio\n\tinput = document.createElement( \"input\" );\n\tinput.value = \"t\";\n\tinput.type = \"radio\";\n\tsupport.radioValue = input.value === \"t\";\n} )();\n\n\nvar boolHook,\n\tattrHandle = jQuery.expr.attrHandle;\n\njQuery.fn.extend( {\n\tattr: function( name, value ) {\n\t\treturn access( this, jQuery.attr, name, value, arguments.length > 1 );\n\t},\n\n\tremoveAttr: function( name ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.removeAttr( this, name );\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tattr: function( elem, name, value ) {\n\t\tvar ret, hooks,\n\t\t\tnType = elem.nodeType;\n\n\t\t// Don't get/set attributes on text, comment and attribute nodes\n\t\tif ( nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Fallback to prop when attributes are not supported\n\t\tif ( typeof elem.getAttribute === \"undefined\" ) {\n\t\t\treturn jQuery.prop( elem, name, value );\n\t\t}\n\n\t\t// Attribute hooks are determined by the lowercase version\n\t\t// Grab necessary hook if one is defined\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\t\t\thooks = jQuery.attrHooks[ name.toLowerCase() ] ||\n\t\t\t\t( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\tif ( value === null ) {\n\t\t\t\tjQuery.removeAttr( elem, name );\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( hooks && \"set\" in hooks &&\n\t\t\t\t( ret = hooks.set( elem, value, name ) ) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\telem.setAttribute( name, value + \"\" );\n\t\t\treturn value;\n\t\t}\n\n\t\tif ( hooks && \"get\" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {\n\t\t\treturn ret;\n\t\t}\n\n\t\tret = jQuery.find.attr( elem, name );\n\n\t\t// Non-existent attributes return null, we normalize to undefined\n\t\treturn ret == null ? undefined : ret;\n\t},\n\n\tattrHooks: {\n\t\ttype: {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tif ( !support.radioValue && value === \"radio\" &&\n\t\t\t\t\tnodeName( elem, \"input\" ) ) {\n\t\t\t\t\tvar val = elem.value;\n\t\t\t\t\telem.setAttribute( \"type\", value );\n\t\t\t\t\tif ( val ) {\n\t\t\t\t\t\telem.value = val;\n\t\t\t\t\t}\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\tremoveAttr: function( elem, value ) {\n\t\tvar name,\n\t\t\ti = 0,\n\n\t\t\t// Attribute names can contain non-HTML whitespace characters\n\t\t\t// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2\n\t\t\tattrNames = value && value.match( rnothtmlwhite );\n\n\t\tif ( attrNames && elem.nodeType === 1 ) {\n\t\t\twhile ( ( name = attrNames[ i++ ] ) ) {\n\t\t\t\telem.removeAttribute( name );\n\t\t\t}\n\t\t}\n\t}\n} );\n\n// Hooks for boolean attributes\nboolHook = {\n\tset: function( elem, value, name ) {\n\t\tif ( value === false ) {\n\n\t\t\t// Remove boolean attributes when set to false\n\t\t\tjQuery.removeAttr( elem, name );\n\t\t} else {\n\t\t\telem.setAttribute( name, name );\n\t\t}\n\t\treturn name;\n\t}\n};\n\njQuery.each( jQuery.expr.match.bool.source.match( /\\w+/g ), function( _i, name ) {\n\tvar getter = attrHandle[ name ] || jQuery.find.attr;\n\n\tattrHandle[ name ] = function( elem, name, isXML ) {\n\t\tvar ret, handle,\n\t\t\tlowercaseName = name.toLowerCase();\n\n\t\tif ( !isXML ) {\n\n\t\t\t// Avoid an infinite loop by temporarily removing this function from the getter\n\t\t\thandle = attrHandle[ lowercaseName ];\n\t\t\tattrHandle[ lowercaseName ] = ret;\n\t\t\tret = getter( elem, name, isXML ) != null ?\n\t\t\t\tlowercaseName :\n\t\t\t\tnull;\n\t\t\tattrHandle[ lowercaseName ] = handle;\n\t\t}\n\t\treturn ret;\n\t};\n} );\n\n\n\n\nvar rfocusable = /^(?:input|select|textarea|button)$/i,\n\trclickable = /^(?:a|area)$/i;\n\njQuery.fn.extend( {\n\tprop: function( name, value ) {\n\t\treturn access( this, jQuery.prop, name, value, arguments.length > 1 );\n\t},\n\n\tremoveProp: function( name ) {\n\t\treturn this.each( function() {\n\t\t\tdelete this[ jQuery.propFix[ name ] || name ];\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tprop: function( elem, name, value ) {\n\t\tvar ret, hooks,\n\t\t\tnType = elem.nodeType;\n\n\t\t// Don't get/set properties on text, comment and attribute nodes\n\t\tif ( nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\n\t\t\t// Fix name and attach hooks\n\t\t\tname = jQuery.propFix[ name ] || name;\n\t\t\thooks = jQuery.propHooks[ name ];\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\tif ( hooks && \"set\" in hooks &&\n\t\t\t\t( ret = hooks.set( elem, value, name ) ) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\treturn ( elem[ name ] = value );\n\t\t}\n\n\t\tif ( hooks && \"get\" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {\n\t\t\treturn ret;\n\t\t}\n\n\t\treturn elem[ name ];\n\t},\n\n\tpropHooks: {\n\t\ttabIndex: {\n\t\t\tget: function( elem ) {\n\n\t\t\t\t// Support: IE <=9 - 11 only\n\t\t\t\t// elem.tabIndex doesn't always return the\n\t\t\t\t// correct value when it hasn't been explicitly set\n\t\t\t\t// https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/\n\t\t\t\t// Use proper attribute retrieval(#12072)\n\t\t\t\tvar tabindex = jQuery.find.attr( elem, \"tabindex\" );\n\n\t\t\t\tif ( tabindex ) {\n\t\t\t\t\treturn parseInt( tabindex, 10 );\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\trfocusable.test( elem.nodeName ) ||\n\t\t\t\t\trclickable.test( elem.nodeName ) &&\n\t\t\t\t\telem.href\n\t\t\t\t) {\n\t\t\t\t\treturn 0;\n\t\t\t\t}\n\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t},\n\n\tpropFix: {\n\t\t\"for\": \"htmlFor\",\n\t\t\"class\": \"className\"\n\t}\n} );\n\n// Support: IE <=11 only\n// Accessing the selectedIndex property\n// forces the browser to respect setting selected\n// on the option\n// The getter ensures a default option is selected\n// when in an optgroup\n// eslint rule \"no-unused-expressions\" is disabled for this code\n// since it considers such accessions noop\nif ( !support.optSelected ) {\n\tjQuery.propHooks.selected = {\n\t\tget: function( elem ) {\n\n\t\t\t/* eslint no-unused-expressions: \"off\" */\n\n\t\t\tvar parent = elem.parentNode;\n\t\t\tif ( parent && parent.parentNode ) {\n\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t}\n\t\t\treturn null;\n\t\t},\n\t\tset: function( elem ) {\n\n\t\t\t/* eslint no-unused-expressions: \"off\" */\n\n\t\t\tvar parent = elem.parentNode;\n\t\t\tif ( parent ) {\n\t\t\t\tparent.selectedIndex;\n\n\t\t\t\tif ( parent.parentNode ) {\n\t\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\njQuery.each( [\n\t\"tabIndex\",\n\t\"readOnly\",\n\t\"maxLength\",\n\t\"cellSpacing\",\n\t\"cellPadding\",\n\t\"rowSpan\",\n\t\"colSpan\",\n\t\"useMap\",\n\t\"frameBorder\",\n\t\"contentEditable\"\n], function() {\n\tjQuery.propFix[ this.toLowerCase() ] = this;\n} );\n\n\n\n\n\t// Strip and collapse whitespace according to HTML spec\n\t// https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace\n\tfunction stripAndCollapse( value ) {\n\t\tvar tokens = value.match( rnothtmlwhite ) || [];\n\t\treturn tokens.join( \" \" );\n\t}\n\n\nfunction getClass( elem ) {\n\treturn elem.getAttribute && elem.getAttribute( \"class\" ) || \"\";\n}\n\nfunction classesToArray( value ) {\n\tif ( Array.isArray( value ) ) {\n\t\treturn value;\n\t}\n\tif ( typeof value === \"string\" ) {\n\t\treturn value.match( rnothtmlwhite ) || [];\n\t}\n\treturn [];\n}\n\njQuery.fn.extend( {\n\taddClass: function( value ) {\n\t\tvar classes, elem, cur, curValue, clazz, j, finalValue,\n\t\t\ti = 0;\n\n\t\tif ( isFunction( value ) ) {\n\t\t\treturn this.each( function( j ) {\n\t\t\t\tjQuery( this ).addClass( value.call( this, j, getClass( this ) ) );\n\t\t\t} );\n\t\t}\n\n\t\tclasses = classesToArray( value );\n\n\t\tif ( classes.length ) {\n\t\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\t\tcurValue = getClass( elem );\n\t\t\t\tcur = elem.nodeType === 1 && ( \" \" + stripAndCollapse( curValue ) + \" \" );\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( ( clazz = classes[ j++ ] ) ) {\n\t\t\t\t\t\tif ( cur.indexOf( \" \" + clazz + \" \" ) < 0 ) {\n\t\t\t\t\t\t\tcur += clazz + \" \";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = stripAndCollapse( cur );\n\t\t\t\t\tif ( curValue !== finalValue ) {\n\t\t\t\t\t\telem.setAttribute( \"class\", finalValue );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tremoveClass: function( value ) {\n\t\tvar classes, elem, cur, curValue, clazz, j, finalValue,\n\t\t\ti = 0;\n\n\t\tif ( isFunction( value ) ) {\n\t\t\treturn this.each( function( j ) {\n\t\t\t\tjQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );\n\t\t\t} );\n\t\t}\n\n\t\tif ( !arguments.length ) {\n\t\t\treturn this.attr( \"class\", \"\" );\n\t\t}\n\n\t\tclasses = classesToArray( value );\n\n\t\tif ( classes.length ) {\n\t\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\t\tcurValue = getClass( elem );\n\n\t\t\t\t// This expression is here for better compressibility (see addClass)\n\t\t\t\tcur = elem.nodeType === 1 && ( \" \" + stripAndCollapse( curValue ) + \" \" );\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( ( clazz = classes[ j++ ] ) ) {\n\n\t\t\t\t\t\t// Remove *all* instances\n\t\t\t\t\t\twhile ( cur.indexOf( \" \" + clazz + \" \" ) > -1 ) {\n\t\t\t\t\t\t\tcur = cur.replace( \" \" + clazz + \" \", \" \" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = stripAndCollapse( cur );\n\t\t\t\t\tif ( curValue !== finalValue ) {\n\t\t\t\t\t\telem.setAttribute( \"class\", finalValue );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\ttoggleClass: function( value, stateVal ) {\n\t\tvar type = typeof value,\n\t\t\tisValidValue = type === \"string\" || Array.isArray( value );\n\n\t\tif ( typeof stateVal === \"boolean\" && isValidValue ) {\n\t\t\treturn stateVal ? this.addClass( value ) : this.removeClass( value );\n\t\t}\n\n\t\tif ( isFunction( value ) ) {\n\t\t\treturn this.each( function( i ) {\n\t\t\t\tjQuery( this ).toggleClass(\n\t\t\t\t\tvalue.call( this, i, getClass( this ), stateVal ),\n\t\t\t\t\tstateVal\n\t\t\t\t);\n\t\t\t} );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar className, i, self, classNames;\n\n\t\t\tif ( isValidValue ) {\n\n\t\t\t\t// Toggle individual class names\n\t\t\t\ti = 0;\n\t\t\t\tself = jQuery( this );\n\t\t\t\tclassNames = classesToArray( value );\n\n\t\t\t\twhile ( ( className = classNames[ i++ ] ) ) {\n\n\t\t\t\t\t// Check each className given, space separated list\n\t\t\t\t\tif ( self.hasClass( className ) ) {\n\t\t\t\t\t\tself.removeClass( className );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tself.addClass( className );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Toggle whole class name\n\t\t\t} else if ( value === undefined || type === \"boolean\" ) {\n\t\t\t\tclassName = getClass( this );\n\t\t\t\tif ( className ) {\n\n\t\t\t\t\t// Store className if set\n\t\t\t\t\tdataPriv.set( this, \"__className__\", className );\n\t\t\t\t}\n\n\t\t\t\t// If the element has a class name or if we're passed `false`,\n\t\t\t\t// then remove the whole classname (if there was one, the above saved it).\n\t\t\t\t// Otherwise bring back whatever was previously saved (if anything),\n\t\t\t\t// falling back to the empty string if nothing was stored.\n\t\t\t\tif ( this.setAttribute ) {\n\t\t\t\t\tthis.setAttribute( \"class\",\n\t\t\t\t\t\tclassName || value === false ?\n\t\t\t\t\t\t\t\"\" :\n\t\t\t\t\t\t\tdataPriv.get( this, \"__className__\" ) || \"\"\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t},\n\n\thasClass: function( selector ) {\n\t\tvar className, elem,\n\t\t\ti = 0;\n\n\t\tclassName = \" \" + selector + \" \";\n\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\tif ( elem.nodeType === 1 &&\n\t\t\t\t( \" \" + stripAndCollapse( getClass( elem ) ) + \" \" ).indexOf( className ) > -1 ) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n} );\n\n\n\n\nvar rreturn = /\\r/g;\n\njQuery.fn.extend( {\n\tval: function( value ) {\n\t\tvar hooks, ret, valueIsFunction,\n\t\t\telem = this[ 0 ];\n\n\t\tif ( !arguments.length ) {\n\t\t\tif ( elem ) {\n\t\t\t\thooks = jQuery.valHooks[ elem.type ] ||\n\t\t\t\t\tjQuery.valHooks[ elem.nodeName.toLowerCase() ];\n\n\t\t\t\tif ( hooks &&\n\t\t\t\t\t\"get\" in hooks &&\n\t\t\t\t\t( ret = hooks.get( elem, \"value\" ) ) !== undefined\n\t\t\t\t) {\n\t\t\t\t\treturn ret;\n\t\t\t\t}\n\n\t\t\t\tret = elem.value;\n\n\t\t\t\t// Handle most common string cases\n\t\t\t\tif ( typeof ret === \"string\" ) {\n\t\t\t\t\treturn ret.replace( rreturn, \"\" );\n\t\t\t\t}\n\n\t\t\t\t// Handle cases where value is null/undef or number\n\t\t\t\treturn ret == null ? \"\" : ret;\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tvalueIsFunction = isFunction( value );\n\n\t\treturn this.each( function( i ) {\n\t\t\tvar val;\n\n\t\t\tif ( this.nodeType !== 1 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( valueIsFunction ) {\n\t\t\t\tval = value.call( this, i, jQuery( this ).val() );\n\t\t\t} else {\n\t\t\t\tval = value;\n\t\t\t}\n\n\t\t\t// Treat null/undefined as \"\"; convert numbers to string\n\t\t\tif ( val == null ) {\n\t\t\t\tval = \"\";\n\n\t\t\t} else if ( typeof val === \"number\" ) {\n\t\t\t\tval += \"\";\n\n\t\t\t} else if ( Array.isArray( val ) ) {\n\t\t\t\tval = jQuery.map( val, function( value ) {\n\t\t\t\t\treturn value == null ? \"\" : value + \"\";\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\thooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];\n\n\t\t\t// If set returns undefined, fall back to normal setting\n\t\t\tif ( !hooks || !( \"set\" in hooks ) || hooks.set( this, val, \"value\" ) === undefined ) {\n\t\t\t\tthis.value = val;\n\t\t\t}\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tvalHooks: {\n\t\toption: {\n\t\t\tget: function( elem ) {\n\n\t\t\t\tvar val = jQuery.find.attr( elem, \"value\" );\n\t\t\t\treturn val != null ?\n\t\t\t\t\tval :\n\n\t\t\t\t\t// Support: IE <=10 - 11 only\n\t\t\t\t\t// option.text throws exceptions (#14686, #14858)\n\t\t\t\t\t// Strip and collapse whitespace\n\t\t\t\t\t// https://html.spec.whatwg.org/#strip-and-collapse-whitespace\n\t\t\t\t\tstripAndCollapse( jQuery.text( elem ) );\n\t\t\t}\n\t\t},\n\t\tselect: {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar value, option, i,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tindex = elem.selectedIndex,\n\t\t\t\t\tone = elem.type === \"select-one\",\n\t\t\t\t\tvalues = one ? null : [],\n\t\t\t\t\tmax = one ? index + 1 : options.length;\n\n\t\t\t\tif ( index < 0 ) {\n\t\t\t\t\ti = max;\n\n\t\t\t\t} else {\n\t\t\t\t\ti = one ? index : 0;\n\t\t\t\t}\n\n\t\t\t\t// Loop through all the selected options\n\t\t\t\tfor ( ; i < max; i++ ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t// IE8-9 doesn't update selected after form reset (#2551)\n\t\t\t\t\tif ( ( option.selected || i === index ) &&\n\n\t\t\t\t\t\t\t// Don't return options that are disabled or in a disabled optgroup\n\t\t\t\t\t\t\t!option.disabled &&\n\t\t\t\t\t\t\t( !option.parentNode.disabled ||\n\t\t\t\t\t\t\t\t!nodeName( option.parentNode, \"optgroup\" ) ) ) {\n\n\t\t\t\t\t\t// Get the specific value for the option\n\t\t\t\t\t\tvalue = jQuery( option ).val();\n\n\t\t\t\t\t\t// We don't need an array for one selects\n\t\t\t\t\t\tif ( one ) {\n\t\t\t\t\t\t\treturn value;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Multi-Selects return an array\n\t\t\t\t\t\tvalues.push( value );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\t\t\t},\n\n\t\t\tset: function( elem, value ) {\n\t\t\t\tvar optionSet, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tvalues = jQuery.makeArray( value ),\n\t\t\t\t\ti = options.length;\n\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t/* eslint-disable no-cond-assign */\n\n\t\t\t\t\tif ( option.selected =\n\t\t\t\t\t\tjQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1\n\t\t\t\t\t) {\n\t\t\t\t\t\toptionSet = true;\n\t\t\t\t\t}\n\n\t\t\t\t\t/* eslint-enable no-cond-assign */\n\t\t\t\t}\n\n\t\t\t\t// Force browsers to behave consistently when non-matching value is set\n\t\t\t\tif ( !optionSet ) {\n\t\t\t\t\telem.selectedIndex = -1;\n\t\t\t\t}\n\t\t\t\treturn values;\n\t\t\t}\n\t\t}\n\t}\n} );\n\n// Radios and checkboxes getter/setter\njQuery.each( [ \"radio\", \"checkbox\" ], function() {\n\tjQuery.valHooks[ this ] = {\n\t\tset: function( elem, value ) {\n\t\t\tif ( Array.isArray( value ) ) {\n\t\t\t\treturn ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );\n\t\t\t}\n\t\t}\n\t};\n\tif ( !support.checkOn ) {\n\t\tjQuery.valHooks[ this ].get = function( elem ) {\n\t\t\treturn elem.getAttribute( \"value\" ) === null ? \"on\" : elem.value;\n\t\t};\n\t}\n} );\n\n\n\n\n// Return jQuery for attributes-only inclusion\n\n\nsupport.focusin = \"onfocusin\" in window;\n\n\nvar rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,\n\tstopPropagationCallback = function( e ) {\n\t\te.stopPropagation();\n\t};\n\njQuery.extend( jQuery.event, {\n\n\ttrigger: function( event, data, elem, onlyHandlers ) {\n\n\t\tvar i, cur, tmp, bubbleType, ontype, handle, special, lastElement,\n\t\t\teventPath = [ elem || document ],\n\t\t\ttype = hasOwn.call( event, \"type\" ) ? event.type : event,\n\t\t\tnamespaces = hasOwn.call( event, \"namespace\" ) ? event.namespace.split( \".\" ) : [];\n\n\t\tcur = lastElement = tmp = elem = elem || document;\n\n\t\t// Don't do events on text and comment nodes\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 8 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// focus/blur morphs to focusin/out; ensure we're not firing them right now\n\t\tif ( rfocusMorph.test( type + jQuery.event.triggered ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( type.indexOf( \".\" ) > -1 ) {\n\n\t\t\t// Namespaced trigger; create a regexp to match event type in handle()\n\t\t\tnamespaces = type.split( \".\" );\n\t\t\ttype = namespaces.shift();\n\t\t\tnamespaces.sort();\n\t\t}\n\t\tontype = type.indexOf( \":\" ) < 0 && \"on\" + type;\n\n\t\t// Caller can pass in a jQuery.Event object, Object, or just an event type string\n\t\tevent = event[ jQuery.expando ] ?\n\t\t\tevent :\n\t\t\tnew jQuery.Event( type, typeof event === \"object\" && event );\n\n\t\t// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)\n\t\tevent.isTrigger = onlyHandlers ? 2 : 3;\n\t\tevent.namespace = namespaces.join( \".\" );\n\t\tevent.rnamespace = event.namespace ?\n\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join( \"\\\\.(?:.*\\\\.|)\" ) + \"(\\\\.|$)\" ) :\n\t\t\tnull;\n\n\t\t// Clean up the event in case it is being reused\n\t\tevent.result = undefined;\n\t\tif ( !event.target ) {\n\t\t\tevent.target = elem;\n\t\t}\n\n\t\t// Clone any incoming data and prepend the event, creating the handler arg list\n\t\tdata = data == null ?\n\t\t\t[ event ] :\n\t\t\tjQuery.makeArray( data, [ event ] );\n\n\t\t// Allow special events to draw outside the lines\n\t\tspecial = jQuery.event.special[ type ] || {};\n\t\tif ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine event propagation path in advance, per W3C events spec (#9951)\n\t\t// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)\n\t\tif ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) {\n\n\t\t\tbubbleType = special.delegateType || type;\n\t\t\tif ( !rfocusMorph.test( bubbleType + type ) ) {\n\t\t\t\tcur = cur.parentNode;\n\t\t\t}\n\t\t\tfor ( ; cur; cur = cur.parentNode ) {\n\t\t\t\teventPath.push( cur );\n\t\t\t\ttmp = cur;\n\t\t\t}\n\n\t\t\t// Only add window if we got to document (e.g., not plain obj or detached DOM)\n\t\t\tif ( tmp === ( elem.ownerDocument || document ) ) {\n\t\t\t\teventPath.push( tmp.defaultView || tmp.parentWindow || window );\n\t\t\t}\n\t\t}\n\n\t\t// Fire handlers on the event path\n\t\ti = 0;\n\t\twhile ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {\n\t\t\tlastElement = cur;\n\t\t\tevent.type = i > 1 ?\n\t\t\t\tbubbleType :\n\t\t\t\tspecial.bindType || type;\n\n\t\t\t// jQuery handler\n\t\t\thandle = ( dataPriv.get( cur, \"events\" ) || Object.create( null ) )[ event.type ] &&\n\t\t\t\tdataPriv.get( cur, \"handle\" );\n\t\t\tif ( handle ) {\n\t\t\t\thandle.apply( cur, data );\n\t\t\t}\n\n\t\t\t// Native handler\n\t\t\thandle = ontype && cur[ ontype ];\n\t\t\tif ( handle && handle.apply && acceptData( cur ) ) {\n\t\t\t\tevent.result = handle.apply( cur, data );\n\t\t\t\tif ( event.result === false ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tevent.type = type;\n\n\t\t// If nobody prevented the default action, do it now\n\t\tif ( !onlyHandlers && !event.isDefaultPrevented() ) {\n\n\t\t\tif ( ( !special._default ||\n\t\t\t\tspecial._default.apply( eventPath.pop(), data ) === false ) &&\n\t\t\t\tacceptData( elem ) ) {\n\n\t\t\t\t// Call a native DOM method on the target with the same name as the event.\n\t\t\t\t// Don't do default actions on window, that's where global variables be (#6170)\n\t\t\t\tif ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) {\n\n\t\t\t\t\t// Don't re-trigger an onFOO event when we call its FOO() method\n\t\t\t\t\ttmp = elem[ ontype ];\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = null;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prevent re-triggering of the same event, since we already bubbled it above\n\t\t\t\t\tjQuery.event.triggered = type;\n\n\t\t\t\t\tif ( event.isPropagationStopped() ) {\n\t\t\t\t\t\tlastElement.addEventListener( type, stopPropagationCallback );\n\t\t\t\t\t}\n\n\t\t\t\t\telem[ type ]();\n\n\t\t\t\t\tif ( event.isPropagationStopped() ) {\n\t\t\t\t\t\tlastElement.removeEventListener( type, stopPropagationCallback );\n\t\t\t\t\t}\n\n\t\t\t\t\tjQuery.event.triggered = undefined;\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = tmp;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\t// Piggyback on a donor event to simulate a different one\n\t// Used only for `focus(in | out)` events\n\tsimulate: function( type, elem, event ) {\n\t\tvar e = jQuery.extend(\n\t\t\tnew jQuery.Event(),\n\t\t\tevent,\n\t\t\t{\n\t\t\t\ttype: type,\n\t\t\t\tisSimulated: true\n\t\t\t}\n\t\t);\n\n\t\tjQuery.event.trigger( e, null, elem );\n\t}\n\n} );\n\njQuery.fn.extend( {\n\n\ttrigger: function( type, data ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.trigger( type, data, this );\n\t\t} );\n\t},\n\ttriggerHandler: function( type, data ) {\n\t\tvar elem = this[ 0 ];\n\t\tif ( elem ) {\n\t\t\treturn jQuery.event.trigger( type, data, elem, true );\n\t\t}\n\t}\n} );\n\n\n// Support: Firefox <=44\n// Firefox doesn't have focus(in | out) events\n// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787\n//\n// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1\n// focus(in | out) events fire after focus & blur events,\n// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order\n// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857\nif ( !support.focusin ) {\n\tjQuery.each( { focus: \"focusin\", blur: \"focusout\" }, function( orig, fix ) {\n\n\t\t// Attach a single capturing handler on the document while someone wants focusin/focusout\n\t\tvar handler = function( event ) {\n\t\t\tjQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );\n\t\t};\n\n\t\tjQuery.event.special[ fix ] = {\n\t\t\tsetup: function() {\n\n\t\t\t\t// Handle: regular nodes (via `this.ownerDocument`), window\n\t\t\t\t// (via `this.document`) & document (via `this`).\n\t\t\t\tvar doc = this.ownerDocument || this.document || this,\n\t\t\t\t\tattaches = dataPriv.access( doc, fix );\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.addEventListener( orig, handler, true );\n\t\t\t\t}\n\t\t\t\tdataPriv.access( doc, fix, ( attaches || 0 ) + 1 );\n\t\t\t},\n\t\t\tteardown: function() {\n\t\t\t\tvar doc = this.ownerDocument || this.document || this,\n\t\t\t\t\tattaches = dataPriv.access( doc, fix ) - 1;\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.removeEventListener( orig, handler, true );\n\t\t\t\t\tdataPriv.remove( doc, fix );\n\n\t\t\t\t} else {\n\t\t\t\t\tdataPriv.access( doc, fix, attaches );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t} );\n}\nvar location = window.location;\n\nvar nonce = { guid: Date.now() };\n\nvar rquery = ( /\\?/ );\n\n\n\n// Cross-browser xml parsing\njQuery.parseXML = function( data ) {\n\tvar xml, parserErrorElem;\n\tif ( !data || typeof data !== \"string\" ) {\n\t\treturn null;\n\t}\n\n\t// Support: IE 9 - 11 only\n\t// IE throws on parseFromString with invalid input.\n\ttry {\n\t\txml = ( new window.DOMParser() ).parseFromString( data, \"text/xml\" );\n\t} catch ( e ) {}\n\n\tparserErrorElem = xml && xml.getElementsByTagName( \"parsererror\" )[ 0 ];\n\tif ( !xml || parserErrorElem ) {\n\t\tjQuery.error( \"Invalid XML: \" + (\n\t\t\tparserErrorElem ?\n\t\t\t\tjQuery.map( parserErrorElem.childNodes, function( el ) {\n\t\t\t\t\treturn el.textContent;\n\t\t\t\t} ).join( \"\\n\" ) :\n\t\t\t\tdata\n\t\t) );\n\t}\n\treturn xml;\n};\n\n\nvar\n\trbracket = /\\[\\]$/,\n\trCRLF = /\\r?\\n/g,\n\trsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,\n\trsubmittable = /^(?:input|select|textarea|keygen)/i;\n\nfunction buildParams( prefix, obj, traditional, add ) {\n\tvar name;\n\n\tif ( Array.isArray( obj ) ) {\n\n\t\t// Serialize array item.\n\t\tjQuery.each( obj, function( i, v ) {\n\t\t\tif ( traditional || rbracket.test( prefix ) ) {\n\n\t\t\t\t// Treat each array item as a scalar.\n\t\t\t\tadd( prefix, v );\n\n\t\t\t} else {\n\n\t\t\t\t// Item is non-scalar (array or object), encode its numeric index.\n\t\t\t\tbuildParams(\n\t\t\t\t\tprefix + \"[\" + ( typeof v === \"object\" && v != null ? i : \"\" ) + \"]\",\n\t\t\t\t\tv,\n\t\t\t\t\ttraditional,\n\t\t\t\t\tadd\n\t\t\t\t);\n\t\t\t}\n\t\t} );\n\n\t} else if ( !traditional && toType( obj ) === \"object\" ) {\n\n\t\t// Serialize object item.\n\t\tfor ( name in obj ) {\n\t\t\tbuildParams( prefix + \"[\" + name + \"]\", obj[ name ], traditional, add );\n\t\t}\n\n\t} else {\n\n\t\t// Serialize scalar item.\n\t\tadd( prefix, obj );\n\t}\n}\n\n// Serialize an array of form elements or a set of\n// key/values into a query string\njQuery.param = function( a, traditional ) {\n\tvar prefix,\n\t\ts = [],\n\t\tadd = function( key, valueOrFunction ) {\n\n\t\t\t// If value is a function, invoke it and use its return value\n\t\t\tvar value = isFunction( valueOrFunction ) ?\n\t\t\t\tvalueOrFunction() :\n\t\t\t\tvalueOrFunction;\n\n\t\t\ts[ s.length ] = encodeURIComponent( key ) + \"=\" +\n\t\t\t\tencodeURIComponent( value == null ? \"\" : value );\n\t\t};\n\n\tif ( a == null ) {\n\t\treturn \"\";\n\t}\n\n\t// If an array was passed in, assume that it is an array of form elements.\n\tif ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {\n\n\t\t// Serialize the form elements\n\t\tjQuery.each( a, function() {\n\t\t\tadd( this.name, this.value );\n\t\t} );\n\n\t} else {\n\n\t\t// If traditional, encode the \"old\" way (the way 1.3.2 or older\n\t\t// did it), otherwise encode params recursively.\n\t\tfor ( prefix in a ) {\n\t\t\tbuildParams( prefix, a[ prefix ], traditional, add );\n\t\t}\n\t}\n\n\t// Return the resulting serialization\n\treturn s.join( \"&\" );\n};\n\njQuery.fn.extend( {\n\tserialize: function() {\n\t\treturn jQuery.param( this.serializeArray() );\n\t},\n\tserializeArray: function() {\n\t\treturn this.map( function() {\n\n\t\t\t// Can add propHook for \"elements\" to filter or add form elements\n\t\t\tvar elements = jQuery.prop( this, \"elements\" );\n\t\t\treturn elements ? jQuery.makeArray( elements ) : this;\n\t\t} ).filter( function() {\n\t\t\tvar type = this.type;\n\n\t\t\t// Use .is( \":disabled\" ) so that fieldset[disabled] works\n\t\t\treturn this.name && !jQuery( this ).is( \":disabled\" ) &&\n\t\t\t\trsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&\n\t\t\t\t( this.checked || !rcheckableType.test( type ) );\n\t\t} ).map( function( _i, elem ) {\n\t\t\tvar val = jQuery( this ).val();\n\n\t\t\tif ( val == null ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\tif ( Array.isArray( val ) ) {\n\t\t\t\treturn jQuery.map( val, function( val ) {\n\t\t\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t} ).get();\n\t}\n} );\n\n\nvar\n\tr20 = /%20/g,\n\trhash = /#.*$/,\n\trantiCache = /([?&])_=[^&]*/,\n\trheaders = /^(.*?):[ \\t]*([^\\r\\n]*)$/mg,\n\n\t// #7653, #8125, #8152: local protocol detection\n\trlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,\n\trnoContent = /^(?:GET|HEAD)$/,\n\trprotocol = /^\\/\\//,\n\n\t/* Prefilters\n\t * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)\n\t * 2) These are called:\n\t * - BEFORE asking for a transport\n\t * - AFTER param serialization (s.data is a string if s.processData is true)\n\t * 3) key is the dataType\n\t * 4) the catchall symbol \"*\" can be used\n\t * 5) execution will start with transport dataType and THEN continue down to \"*\" if needed\n\t */\n\tprefilters = {},\n\n\t/* Transports bindings\n\t * 1) key is the dataType\n\t * 2) the catchall symbol \"*\" can be used\n\t * 3) selection will start with transport dataType and THEN go to \"*\" if needed\n\t */\n\ttransports = {},\n\n\t// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression\n\tallTypes = \"*/\".concat( \"*\" ),\n\n\t// Anchor tag for parsing the document origin\n\toriginAnchor = document.createElement( \"a\" );\n\noriginAnchor.href = location.href;\n\n// Base \"constructor\" for jQuery.ajaxPrefilter and jQuery.ajaxTransport\nfunction addToPrefiltersOrTransports( structure ) {\n\n\t// dataTypeExpression is optional and defaults to \"*\"\n\treturn function( dataTypeExpression, func ) {\n\n\t\tif ( typeof dataTypeExpression !== \"string\" ) {\n\t\t\tfunc = dataTypeExpression;\n\t\t\tdataTypeExpression = \"*\";\n\t\t}\n\n\t\tvar dataType,\n\t\t\ti = 0,\n\t\t\tdataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];\n\n\t\tif ( isFunction( func ) ) {\n\n\t\t\t// For each dataType in the dataTypeExpression\n\t\t\twhile ( ( dataType = dataTypes[ i++ ] ) ) {\n\n\t\t\t\t// Prepend if requested\n\t\t\t\tif ( dataType[ 0 ] === \"+\" ) {\n\t\t\t\t\tdataType = dataType.slice( 1 ) || \"*\";\n\t\t\t\t\t( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );\n\n\t\t\t\t// Otherwise append\n\t\t\t\t} else {\n\t\t\t\t\t( structure[ dataType ] = structure[ dataType ] || [] ).push( func );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n// Base inspection function for prefilters and transports\nfunction inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {\n\n\tvar inspected = {},\n\t\tseekingTransport = ( structure === transports );\n\n\tfunction inspect( dataType ) {\n\t\tvar selected;\n\t\tinspected[ dataType ] = true;\n\t\tjQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {\n\t\t\tvar dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );\n\t\t\tif ( typeof dataTypeOrTransport === \"string\" &&\n\t\t\t\t!seekingTransport && !inspected[ dataTypeOrTransport ] ) {\n\n\t\t\t\toptions.dataTypes.unshift( dataTypeOrTransport );\n\t\t\t\tinspect( dataTypeOrTransport );\n\t\t\t\treturn false;\n\t\t\t} else if ( seekingTransport ) {\n\t\t\t\treturn !( selected = dataTypeOrTransport );\n\t\t\t}\n\t\t} );\n\t\treturn selected;\n\t}\n\n\treturn inspect( options.dataTypes[ 0 ] ) || !inspected[ \"*\" ] && inspect( \"*\" );\n}\n\n// A special extend for ajax options\n// that takes \"flat\" options (not to be deep extended)\n// Fixes #9887\nfunction ajaxExtend( target, src ) {\n\tvar key, deep,\n\t\tflatOptions = jQuery.ajaxSettings.flatOptions || {};\n\n\tfor ( key in src ) {\n\t\tif ( src[ key ] !== undefined ) {\n\t\t\t( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];\n\t\t}\n\t}\n\tif ( deep ) {\n\t\tjQuery.extend( true, target, deep );\n\t}\n\n\treturn target;\n}\n\n/* Handles responses to an ajax request:\n * - finds the right dataType (mediates between content-type and expected dataType)\n * - returns the corresponding response\n */\nfunction ajaxHandleResponses( s, jqXHR, responses ) {\n\n\tvar ct, type, finalDataType, firstDataType,\n\t\tcontents = s.contents,\n\t\tdataTypes = s.dataTypes;\n\n\t// Remove auto dataType and get content-type in the process\n\twhile ( dataTypes[ 0 ] === \"*\" ) {\n\t\tdataTypes.shift();\n\t\tif ( ct === undefined ) {\n\t\t\tct = s.mimeType || jqXHR.getResponseHeader( \"Content-Type\" );\n\t\t}\n\t}\n\n\t// Check if we're dealing with a known content-type\n\tif ( ct ) {\n\t\tfor ( type in contents ) {\n\t\t\tif ( contents[ type ] && contents[ type ].test( ct ) ) {\n\t\t\t\tdataTypes.unshift( type );\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check to see if we have a response for the expected dataType\n\tif ( dataTypes[ 0 ] in responses ) {\n\t\tfinalDataType = dataTypes[ 0 ];\n\t} else {\n\n\t\t// Try convertible dataTypes\n\t\tfor ( type in responses ) {\n\t\t\tif ( !dataTypes[ 0 ] || s.converters[ type + \" \" + dataTypes[ 0 ] ] ) {\n\t\t\t\tfinalDataType = type;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( !firstDataType ) {\n\t\t\t\tfirstDataType = type;\n\t\t\t}\n\t\t}\n\n\t\t// Or just use first one\n\t\tfinalDataType = finalDataType || firstDataType;\n\t}\n\n\t// If we found a dataType\n\t// We add the dataType to the list if needed\n\t// and return the corresponding response\n\tif ( finalDataType ) {\n\t\tif ( finalDataType !== dataTypes[ 0 ] ) {\n\t\t\tdataTypes.unshift( finalDataType );\n\t\t}\n\t\treturn responses[ finalDataType ];\n\t}\n}\n\n/* Chain conversions given the request and the original response\n * Also sets the responseXXX fields on the jqXHR instance\n */\nfunction ajaxConvert( s, response, jqXHR, isSuccess ) {\n\tvar conv2, current, conv, tmp, prev,\n\t\tconverters = {},\n\n\t\t// Work with a copy of dataTypes in case we need to modify it for conversion\n\t\tdataTypes = s.dataTypes.slice();\n\n\t// Create converters map with lowercased keys\n\tif ( dataTypes[ 1 ] ) {\n\t\tfor ( conv in s.converters ) {\n\t\t\tconverters[ conv.toLowerCase() ] = s.converters[ conv ];\n\t\t}\n\t}\n\n\tcurrent = dataTypes.shift();\n\n\t// Convert to each sequential dataType\n\twhile ( current ) {\n\n\t\tif ( s.responseFields[ current ] ) {\n\t\t\tjqXHR[ s.responseFields[ current ] ] = response;\n\t\t}\n\n\t\t// Apply the dataFilter if provided\n\t\tif ( !prev && isSuccess && s.dataFilter ) {\n\t\t\tresponse = s.dataFilter( response, s.dataType );\n\t\t}\n\n\t\tprev = current;\n\t\tcurrent = dataTypes.shift();\n\n\t\tif ( current ) {\n\n\t\t\t// There's only work to do if current dataType is non-auto\n\t\t\tif ( current === \"*\" ) {\n\n\t\t\t\tcurrent = prev;\n\n\t\t\t// Convert response if prev dataType is non-auto and differs from current\n\t\t\t} else if ( prev !== \"*\" && prev !== current ) {\n\n\t\t\t\t// Seek a direct converter\n\t\t\t\tconv = converters[ prev + \" \" + current ] || converters[ \"* \" + current ];\n\n\t\t\t\t// If none found, seek a pair\n\t\t\t\tif ( !conv ) {\n\t\t\t\t\tfor ( conv2 in converters ) {\n\n\t\t\t\t\t\t// If conv2 outputs current\n\t\t\t\t\t\ttmp = conv2.split( \" \" );\n\t\t\t\t\t\tif ( tmp[ 1 ] === current ) {\n\n\t\t\t\t\t\t\t// If prev can be converted to accepted input\n\t\t\t\t\t\t\tconv = converters[ prev + \" \" + tmp[ 0 ] ] ||\n\t\t\t\t\t\t\t\tconverters[ \"* \" + tmp[ 0 ] ];\n\t\t\t\t\t\t\tif ( conv ) {\n\n\t\t\t\t\t\t\t\t// Condense equivalence converters\n\t\t\t\t\t\t\t\tif ( conv === true ) {\n\t\t\t\t\t\t\t\t\tconv = converters[ conv2 ];\n\n\t\t\t\t\t\t\t\t// Otherwise, insert the intermediate dataType\n\t\t\t\t\t\t\t\t} else if ( converters[ conv2 ] !== true ) {\n\t\t\t\t\t\t\t\t\tcurrent = tmp[ 0 ];\n\t\t\t\t\t\t\t\t\tdataTypes.unshift( tmp[ 1 ] );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Apply converter (if not an equivalence)\n\t\t\t\tif ( conv !== true ) {\n\n\t\t\t\t\t// Unless errors are allowed to bubble, catch and return them\n\t\t\t\t\tif ( conv && s.throws ) {\n\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tstate: \"parsererror\",\n\t\t\t\t\t\t\t\terror: conv ? e : \"No conversion from \" + prev + \" to \" + current\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { state: \"success\", data: response };\n}\n\njQuery.extend( {\n\n\t// Counter for holding the number of active queries\n\tactive: 0,\n\n\t// Last-Modified header cache for next request\n\tlastModified: {},\n\tetag: {},\n\n\tajaxSettings: {\n\t\turl: location.href,\n\t\ttype: \"GET\",\n\t\tisLocal: rlocalProtocol.test( location.protocol ),\n\t\tglobal: true,\n\t\tprocessData: true,\n\t\tasync: true,\n\t\tcontentType: \"application/x-www-form-urlencoded; charset=UTF-8\",\n\n\t\t/*\n\t\ttimeout: 0,\n\t\tdata: null,\n\t\tdataType: null,\n\t\tusername: null,\n\t\tpassword: null,\n\t\tcache: null,\n\t\tthrows: false,\n\t\ttraditional: false,\n\t\theaders: {},\n\t\t*/\n\n\t\taccepts: {\n\t\t\t\"*\": allTypes,\n\t\t\ttext: \"text/plain\",\n\t\t\thtml: \"text/html\",\n\t\t\txml: \"application/xml, text/xml\",\n\t\t\tjson: \"application/json, text/javascript\"\n\t\t},\n\n\t\tcontents: {\n\t\t\txml: /\\bxml\\b/,\n\t\t\thtml: /\\bhtml/,\n\t\t\tjson: /\\bjson\\b/\n\t\t},\n\n\t\tresponseFields: {\n\t\t\txml: \"responseXML\",\n\t\t\ttext: \"responseText\",\n\t\t\tjson: \"responseJSON\"\n\t\t},\n\n\t\t// Data converters\n\t\t// Keys separate source (or catchall \"*\") and destination types with a single space\n\t\tconverters: {\n\n\t\t\t// Convert anything to text\n\t\t\t\"* text\": String,\n\n\t\t\t// Text to html (true = no transformation)\n\t\t\t\"text html\": true,\n\n\t\t\t// Evaluate text as a json expression\n\t\t\t\"text json\": JSON.parse,\n\n\t\t\t// Parse text as xml\n\t\t\t\"text xml\": jQuery.parseXML\n\t\t},\n\n\t\t// For options that shouldn't be deep extended:\n\t\t// you can add your own custom options here if\n\t\t// and when you create one that shouldn't be\n\t\t// deep extended (see ajaxExtend)\n\t\tflatOptions: {\n\t\t\turl: true,\n\t\t\tcontext: true\n\t\t}\n\t},\n\n\t// Creates a full fledged settings object into target\n\t// with both ajaxSettings and settings fields.\n\t// If target is omitted, writes into ajaxSettings.\n\tajaxSetup: function( target, settings ) {\n\t\treturn settings ?\n\n\t\t\t// Building a settings object\n\t\t\tajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :\n\n\t\t\t// Extending ajaxSettings\n\t\t\tajaxExtend( jQuery.ajaxSettings, target );\n\t},\n\n\tajaxPrefilter: addToPrefiltersOrTransports( prefilters ),\n\tajaxTransport: addToPrefiltersOrTransports( transports ),\n\n\t// Main method\n\tajax: function( url, options ) {\n\n\t\t// If url is an object, simulate pre-1.5 signature\n\t\tif ( typeof url === \"object\" ) {\n\t\t\toptions = url;\n\t\t\turl = undefined;\n\t\t}\n\n\t\t// Force options to be an object\n\t\toptions = options || {};\n\n\t\tvar transport,\n\n\t\t\t// URL without anti-cache param\n\t\t\tcacheURL,\n\n\t\t\t// Response headers\n\t\t\tresponseHeadersString,\n\t\t\tresponseHeaders,\n\n\t\t\t// timeout handle\n\t\t\ttimeoutTimer,\n\n\t\t\t// Url cleanup var\n\t\t\turlAnchor,\n\n\t\t\t// Request state (becomes false upon send and true upon completion)\n\t\t\tcompleted,\n\n\t\t\t// To know if global events are to be dispatched\n\t\t\tfireGlobals,\n\n\t\t\t// Loop variable\n\t\t\ti,\n\n\t\t\t// uncached part of the url\n\t\t\tuncached,\n\n\t\t\t// Create the final options object\n\t\t\ts = jQuery.ajaxSetup( {}, options ),\n\n\t\t\t// Callbacks context\n\t\t\tcallbackContext = s.context || s,\n\n\t\t\t// Context for global events is callbackContext if it is a DOM node or jQuery collection\n\t\t\tglobalEventContext = s.context &&\n\t\t\t\t( callbackContext.nodeType || callbackContext.jquery ) ?\n\t\t\t\tjQuery( callbackContext ) :\n\t\t\t\tjQuery.event,\n\n\t\t\t// Deferreds\n\t\t\tdeferred = jQuery.Deferred(),\n\t\t\tcompleteDeferred = jQuery.Callbacks( \"once memory\" ),\n\n\t\t\t// Status-dependent callbacks\n\t\t\tstatusCode = s.statusCode || {},\n\n\t\t\t// Headers (they are sent all at once)\n\t\t\trequestHeaders = {},\n\t\t\trequestHeadersNames = {},\n\n\t\t\t// Default abort message\n\t\t\tstrAbort = \"canceled\",\n\n\t\t\t// Fake xhr\n\t\t\tjqXHR = {\n\t\t\t\treadyState: 0,\n\n\t\t\t\t// Builds headers hashtable if needed\n\t\t\t\tgetResponseHeader: function( key ) {\n\t\t\t\t\tvar match;\n\t\t\t\t\tif ( completed ) {\n\t\t\t\t\t\tif ( !responseHeaders ) {\n\t\t\t\t\t\t\tresponseHeaders = {};\n\t\t\t\t\t\t\twhile ( ( match = rheaders.exec( responseHeadersString ) ) ) {\n\t\t\t\t\t\t\t\tresponseHeaders[ match[ 1 ].toLowerCase() + \" \" ] =\n\t\t\t\t\t\t\t\t\t( responseHeaders[ match[ 1 ].toLowerCase() + \" \" ] || [] )\n\t\t\t\t\t\t\t\t\t\t.concat( match[ 2 ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmatch = responseHeaders[ key.toLowerCase() + \" \" ];\n\t\t\t\t\t}\n\t\t\t\t\treturn match == null ? null : match.join( \", \" );\n\t\t\t\t},\n\n\t\t\t\t// Raw string\n\t\t\t\tgetAllResponseHeaders: function() {\n\t\t\t\t\treturn completed ? responseHeadersString : null;\n\t\t\t\t},\n\n\t\t\t\t// Caches the header\n\t\t\t\tsetRequestHeader: function( name, value ) {\n\t\t\t\t\tif ( completed == null ) {\n\t\t\t\t\t\tname = requestHeadersNames[ name.toLowerCase() ] =\n\t\t\t\t\t\t\trequestHeadersNames[ name.toLowerCase() ] || name;\n\t\t\t\t\t\trequestHeaders[ name ] = value;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Overrides response content-type header\n\t\t\t\toverrideMimeType: function( type ) {\n\t\t\t\t\tif ( completed == null ) {\n\t\t\t\t\t\ts.mimeType = type;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Status-dependent callbacks\n\t\t\t\tstatusCode: function( map ) {\n\t\t\t\t\tvar code;\n\t\t\t\t\tif ( map ) {\n\t\t\t\t\t\tif ( completed ) {\n\n\t\t\t\t\t\t\t// Execute the appropriate callbacks\n\t\t\t\t\t\t\tjqXHR.always( map[ jqXHR.status ] );\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// Lazy-add the new callbacks in a way that preserves old ones\n\t\t\t\t\t\t\tfor ( code in map ) {\n\t\t\t\t\t\t\t\tstatusCode[ code ] = [ statusCode[ code ], map[ code ] ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Cancel the request\n\t\t\t\tabort: function( statusText ) {\n\t\t\t\t\tvar finalText = statusText || strAbort;\n\t\t\t\t\tif ( transport ) {\n\t\t\t\t\t\ttransport.abort( finalText );\n\t\t\t\t\t}\n\t\t\t\t\tdone( 0, finalText );\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t};\n\n\t\t// Attach deferreds\n\t\tdeferred.promise( jqXHR );\n\n\t\t// Add protocol if not provided (prefilters might expect it)\n\t\t// Handle falsy url in the settings object (#10093: consistency with old signature)\n\t\t// We also use the url parameter if available\n\t\ts.url = ( ( url || s.url || location.href ) + \"\" )\n\t\t\t.replace( rprotocol, location.protocol + \"//\" );\n\n\t\t// Alias method option to type as per ticket #12004\n\t\ts.type = options.method || options.type || s.method || s.type;\n\n\t\t// Extract dataTypes list\n\t\ts.dataTypes = ( s.dataType || \"*\" ).toLowerCase().match( rnothtmlwhite ) || [ \"\" ];\n\n\t\t// A cross-domain request is in order when the origin doesn't match the current origin.\n\t\tif ( s.crossDomain == null ) {\n\t\t\turlAnchor = document.createElement( \"a\" );\n\n\t\t\t// Support: IE <=8 - 11, Edge 12 - 15\n\t\t\t// IE throws exception on accessing the href property if url is malformed,\n\t\t\t// e.g. http://example.com:80x/\n\t\t\ttry {\n\t\t\t\turlAnchor.href = s.url;\n\n\t\t\t\t// Support: IE <=8 - 11 only\n\t\t\t\t// Anchor's host property isn't correctly set when s.url is relative\n\t\t\t\turlAnchor.href = urlAnchor.href;\n\t\t\t\ts.crossDomain = originAnchor.protocol + \"//\" + originAnchor.host !==\n\t\t\t\t\turlAnchor.protocol + \"//\" + urlAnchor.host;\n\t\t\t} catch ( e ) {\n\n\t\t\t\t// If there is an error parsing the URL, assume it is crossDomain,\n\t\t\t\t// it can be rejected by the transport if it is invalid\n\t\t\t\ts.crossDomain = true;\n\t\t\t}\n\t\t}\n\n\t\t// Convert data if not already a string\n\t\tif ( s.data && s.processData && typeof s.data !== \"string\" ) {\n\t\t\ts.data = jQuery.param( s.data, s.traditional );\n\t\t}\n\n\t\t// Apply prefilters\n\t\tinspectPrefiltersOrTransports( prefilters, s, options, jqXHR );\n\n\t\t// If request was aborted inside a prefilter, stop there\n\t\tif ( completed ) {\n\t\t\treturn jqXHR;\n\t\t}\n\n\t\t// We can fire global events as of now if asked to\n\t\t// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)\n\t\tfireGlobals = jQuery.event && s.global;\n\n\t\t// Watch for a new set of requests\n\t\tif ( fireGlobals && jQuery.active++ === 0 ) {\n\t\t\tjQuery.event.trigger( \"ajaxStart\" );\n\t\t}\n\n\t\t// Uppercase the type\n\t\ts.type = s.type.toUpperCase();\n\n\t\t// Determine if request has content\n\t\ts.hasContent = !rnoContent.test( s.type );\n\n\t\t// Save the URL in case we're toying with the If-Modified-Since\n\t\t// and/or If-None-Match header later on\n\t\t// Remove hash to simplify url manipulation\n\t\tcacheURL = s.url.replace( rhash, \"\" );\n\n\t\t// More options handling for requests with no content\n\t\tif ( !s.hasContent ) {\n\n\t\t\t// Remember the hash so we can put it back\n\t\t\tuncached = s.url.slice( cacheURL.length );\n\n\t\t\t// If data is available and should be processed, append data to url\n\t\t\tif ( s.data && ( s.processData || typeof s.data === \"string\" ) ) {\n\t\t\t\tcacheURL += ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + s.data;\n\n\t\t\t\t// #9682: remove data so that it's not used in an eventual retry\n\t\t\t\tdelete s.data;\n\t\t\t}\n\n\t\t\t// Add or update anti-cache param if needed\n\t\t\tif ( s.cache === false ) {\n\t\t\t\tcacheURL = cacheURL.replace( rantiCache, \"$1\" );\n\t\t\t\tuncached = ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + \"_=\" + ( nonce.guid++ ) +\n\t\t\t\t\tuncached;\n\t\t\t}\n\n\t\t\t// Put hash and anti-cache on the URL that will be requested (gh-1732)\n\t\t\ts.url = cacheURL + uncached;\n\n\t\t// Change '%20' to '+' if this is encoded form body content (gh-2658)\n\t\t} else if ( s.data && s.processData &&\n\t\t\t( s.contentType || \"\" ).indexOf( \"application/x-www-form-urlencoded\" ) === 0 ) {\n\t\t\ts.data = s.data.replace( r20, \"+\" );\n\t\t}\n\n\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\tif ( s.ifModified ) {\n\t\t\tif ( jQuery.lastModified[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-Modified-Since\", jQuery.lastModified[ cacheURL ] );\n\t\t\t}\n\t\t\tif ( jQuery.etag[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-None-Match\", jQuery.etag[ cacheURL ] );\n\t\t\t}\n\t\t}\n\n\t\t// Set the correct header, if data is being sent\n\t\tif ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {\n\t\t\tjqXHR.setRequestHeader( \"Content-Type\", s.contentType );\n\t\t}\n\n\t\t// Set the Accepts header for the server, depending on the dataType\n\t\tjqXHR.setRequestHeader(\n\t\t\t\"Accept\",\n\t\t\ts.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?\n\t\t\t\ts.accepts[ s.dataTypes[ 0 ] ] +\n\t\t\t\t\t( s.dataTypes[ 0 ] !== \"*\" ? \", \" + allTypes + \"; q=0.01\" : \"\" ) :\n\t\t\t\ts.accepts[ \"*\" ]\n\t\t);\n\n\t\t// Check for headers option\n\t\tfor ( i in s.headers ) {\n\t\t\tjqXHR.setRequestHeader( i, s.headers[ i ] );\n\t\t}\n\n\t\t// Allow custom headers/mimetypes and early abort\n\t\tif ( s.beforeSend &&\n\t\t\t( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {\n\n\t\t\t// Abort if not done already and return\n\t\t\treturn jqXHR.abort();\n\t\t}\n\n\t\t// Aborting is no longer a cancellation\n\t\tstrAbort = \"abort\";\n\n\t\t// Install callbacks on deferreds\n\t\tcompleteDeferred.add( s.complete );\n\t\tjqXHR.done( s.success );\n\t\tjqXHR.fail( s.error );\n\n\t\t// Get transport\n\t\ttransport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );\n\n\t\t// If no transport, we auto-abort\n\t\tif ( !transport ) {\n\t\t\tdone( -1, \"No Transport\" );\n\t\t} else {\n\t\t\tjqXHR.readyState = 1;\n\n\t\t\t// Send global event\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxSend\", [ jqXHR, s ] );\n\t\t\t}\n\n\t\t\t// If request was aborted inside ajaxSend, stop there\n\t\t\tif ( completed ) {\n\t\t\t\treturn jqXHR;\n\t\t\t}\n\n\t\t\t// Timeout\n\t\t\tif ( s.async && s.timeout > 0 ) {\n\t\t\t\ttimeoutTimer = window.setTimeout( function() {\n\t\t\t\t\tjqXHR.abort( \"timeout\" );\n\t\t\t\t}, s.timeout );\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tcompleted = false;\n\t\t\t\ttransport.send( requestHeaders, done );\n\t\t\t} catch ( e ) {\n\n\t\t\t\t// Rethrow post-completion exceptions\n\t\t\t\tif ( completed ) {\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\n\t\t\t\t// Propagate others as results\n\t\t\t\tdone( -1, e );\n\t\t\t}\n\t\t}\n\n\t\t// Callback for when everything is done\n\t\tfunction done( status, nativeStatusText, responses, headers ) {\n\t\t\tvar isSuccess, success, error, response, modified,\n\t\t\t\tstatusText = nativeStatusText;\n\n\t\t\t// Ignore repeat invocations\n\t\t\tif ( completed ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tcompleted = true;\n\n\t\t\t// Clear timeout if it exists\n\t\t\tif ( timeoutTimer ) {\n\t\t\t\twindow.clearTimeout( timeoutTimer );\n\t\t\t}\n\n\t\t\t// Dereference transport for early garbage collection\n\t\t\t// (no matter how long the jqXHR object will be used)\n\t\t\ttransport = undefined;\n\n\t\t\t// Cache response headers\n\t\t\tresponseHeadersString = headers || \"\";\n\n\t\t\t// Set readyState\n\t\t\tjqXHR.readyState = status > 0 ? 4 : 0;\n\n\t\t\t// Determine if successful\n\t\t\tisSuccess = status >= 200 && status < 300 || status === 304;\n\n\t\t\t// Get response data\n\t\t\tif ( responses ) {\n\t\t\t\tresponse = ajaxHandleResponses( s, jqXHR, responses );\n\t\t\t}\n\n\t\t\t// Use a noop converter for missing script but not if jsonp\n\t\t\tif ( !isSuccess &&\n\t\t\t\tjQuery.inArray( \"script\", s.dataTypes ) > -1 &&\n\t\t\t\tjQuery.inArray( \"json\", s.dataTypes ) < 0 ) {\n\t\t\t\ts.converters[ \"text script\" ] = function() {};\n\t\t\t}\n\n\t\t\t// Convert no matter what (that way responseXXX fields are always set)\n\t\t\tresponse = ajaxConvert( s, response, jqXHR, isSuccess );\n\n\t\t\t// If successful, handle type chaining\n\t\t\tif ( isSuccess ) {\n\n\t\t\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\t\t\tif ( s.ifModified ) {\n\t\t\t\t\tmodified = jqXHR.getResponseHeader( \"Last-Modified\" );\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.lastModified[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t\tmodified = jqXHR.getResponseHeader( \"etag\" );\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.etag[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// if no content\n\t\t\t\tif ( status === 204 || s.type === \"HEAD\" ) {\n\t\t\t\t\tstatusText = \"nocontent\";\n\n\t\t\t\t// if not modified\n\t\t\t\t} else if ( status === 304 ) {\n\t\t\t\t\tstatusText = \"notmodified\";\n\n\t\t\t\t// If we have data, let's convert it\n\t\t\t\t} else {\n\t\t\t\t\tstatusText = response.state;\n\t\t\t\t\tsuccess = response.data;\n\t\t\t\t\terror = response.error;\n\t\t\t\t\tisSuccess = !error;\n\t\t\t\t}\n\t\t\t} else {\n\n\t\t\t\t// Extract error from statusText and normalize for non-aborts\n\t\t\t\terror = statusText;\n\t\t\t\tif ( status || !statusText ) {\n\t\t\t\t\tstatusText = \"error\";\n\t\t\t\t\tif ( status < 0 ) {\n\t\t\t\t\t\tstatus = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Set data for the fake xhr object\n\t\t\tjqXHR.status = status;\n\t\t\tjqXHR.statusText = ( nativeStatusText || statusText ) + \"\";\n\n\t\t\t// Success/Error\n\t\t\tif ( isSuccess ) {\n\t\t\t\tdeferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );\n\t\t\t} else {\n\t\t\t\tdeferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );\n\t\t\t}\n\n\t\t\t// Status-dependent callbacks\n\t\t\tjqXHR.statusCode( statusCode );\n\t\t\tstatusCode = undefined;\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( isSuccess ? \"ajaxSuccess\" : \"ajaxError\",\n\t\t\t\t\t[ jqXHR, s, isSuccess ? success : error ] );\n\t\t\t}\n\n\t\t\t// Complete\n\t\t\tcompleteDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxComplete\", [ jqXHR, s ] );\n\n\t\t\t\t// Handle the global AJAX counter\n\t\t\t\tif ( !( --jQuery.active ) ) {\n\t\t\t\t\tjQuery.event.trigger( \"ajaxStop\" );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn jqXHR;\n\t},\n\n\tgetJSON: function( url, data, callback ) {\n\t\treturn jQuery.get( url, data, callback, \"json\" );\n\t},\n\n\tgetScript: function( url, callback ) {\n\t\treturn jQuery.get( url, undefined, callback, \"script\" );\n\t}\n} );\n\njQuery.each( [ \"get\", \"post\" ], function( _i, method ) {\n\tjQuery[ method ] = function( url, data, callback, type ) {\n\n\t\t// Shift arguments if data argument was omitted\n\t\tif ( isFunction( data ) ) {\n\t\t\ttype = type || callback;\n\t\t\tcallback = data;\n\t\t\tdata = undefined;\n\t\t}\n\n\t\t// The url can be an options object (which then must have .url)\n\t\treturn jQuery.ajax( jQuery.extend( {\n\t\t\turl: url,\n\t\t\ttype: method,\n\t\t\tdataType: type,\n\t\t\tdata: data,\n\t\t\tsuccess: callback\n\t\t}, jQuery.isPlainObject( url ) && url ) );\n\t};\n} );\n\njQuery.ajaxPrefilter( function( s ) {\n\tvar i;\n\tfor ( i in s.headers ) {\n\t\tif ( i.toLowerCase() === \"content-type\" ) {\n\t\t\ts.contentType = s.headers[ i ] || \"\";\n\t\t}\n\t}\n} );\n\n\njQuery._evalUrl = function( url, options, doc ) {\n\treturn jQuery.ajax( {\n\t\turl: url,\n\n\t\t// Make this explicit, since user can override this through ajaxSetup (#11264)\n\t\ttype: \"GET\",\n\t\tdataType: \"script\",\n\t\tcache: true,\n\t\tasync: false,\n\t\tglobal: false,\n\n\t\t// Only evaluate the response if it is successful (gh-4126)\n\t\t// dataFilter is not invoked for failure responses, so using it instead\n\t\t// of the default converter is kludgy but it works.\n\t\tconverters: {\n\t\t\t\"text script\": function() {}\n\t\t},\n\t\tdataFilter: function( response ) {\n\t\t\tjQuery.globalEval( response, options, doc );\n\t\t}\n\t} );\n};\n\n\njQuery.fn.extend( {\n\twrapAll: function( html ) {\n\t\tvar wrap;\n\n\t\tif ( this[ 0 ] ) {\n\t\t\tif ( isFunction( html ) ) {\n\t\t\t\thtml = html.call( this[ 0 ] );\n\t\t\t}\n\n\t\t\t// The elements to wrap the target around\n\t\t\twrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );\n\n\t\t\tif ( this[ 0 ].parentNode ) {\n\t\t\t\twrap.insertBefore( this[ 0 ] );\n\t\t\t}\n\n\t\t\twrap.map( function() {\n\t\t\t\tvar elem = this;\n\n\t\t\t\twhile ( elem.firstElementChild ) {\n\t\t\t\t\telem = elem.firstElementChild;\n\t\t\t\t}\n\n\t\t\t\treturn elem;\n\t\t\t} ).append( this );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\twrapInner: function( html ) {\n\t\tif ( isFunction( html ) ) {\n\t\t\treturn this.each( function( i ) {\n\t\t\t\tjQuery( this ).wrapInner( html.call( this, i ) );\n\t\t\t} );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar self = jQuery( this ),\n\t\t\t\tcontents = self.contents();\n\n\t\t\tif ( contents.length ) {\n\t\t\t\tcontents.wrapAll( html );\n\n\t\t\t} else {\n\t\t\t\tself.append( html );\n\t\t\t}\n\t\t} );\n\t},\n\n\twrap: function( html ) {\n\t\tvar htmlIsFunction = isFunction( html );\n\n\t\treturn this.each( function( i ) {\n\t\t\tjQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html );\n\t\t} );\n\t},\n\n\tunwrap: function( selector ) {\n\t\tthis.parent( selector ).not( \"body\" ).each( function() {\n\t\t\tjQuery( this ).replaceWith( this.childNodes );\n\t\t} );\n\t\treturn this;\n\t}\n} );\n\n\njQuery.expr.pseudos.hidden = function( elem ) {\n\treturn !jQuery.expr.pseudos.visible( elem );\n};\njQuery.expr.pseudos.visible = function( elem ) {\n\treturn !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );\n};\n\n\n\n\njQuery.ajaxSettings.xhr = function() {\n\ttry {\n\t\treturn new window.XMLHttpRequest();\n\t} catch ( e ) {}\n};\n\nvar xhrSuccessStatus = {\n\n\t\t// File protocol always yields status code 0, assume 200\n\t\t0: 200,\n\n\t\t// Support: IE <=9 only\n\t\t// #1450: sometimes IE returns 1223 when it should be 204\n\t\t1223: 204\n\t},\n\txhrSupported = jQuery.ajaxSettings.xhr();\n\nsupport.cors = !!xhrSupported && ( \"withCredentials\" in xhrSupported );\nsupport.ajax = xhrSupported = !!xhrSupported;\n\njQuery.ajaxTransport( function( options ) {\n\tvar callback, errorCallback;\n\n\t// Cross domain only allowed if supported through XMLHttpRequest\n\tif ( support.cors || xhrSupported && !options.crossDomain ) {\n\t\treturn {\n\t\t\tsend: function( headers, complete ) {\n\t\t\t\tvar i,\n\t\t\t\t\txhr = options.xhr();\n\n\t\t\t\txhr.open(\n\t\t\t\t\toptions.type,\n\t\t\t\t\toptions.url,\n\t\t\t\t\toptions.async,\n\t\t\t\t\toptions.username,\n\t\t\t\t\toptions.password\n\t\t\t\t);\n\n\t\t\t\t// Apply custom fields if provided\n\t\t\t\tif ( options.xhrFields ) {\n\t\t\t\t\tfor ( i in options.xhrFields ) {\n\t\t\t\t\t\txhr[ i ] = options.xhrFields[ i ];\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Override mime type if needed\n\t\t\t\tif ( options.mimeType && xhr.overrideMimeType ) {\n\t\t\t\t\txhr.overrideMimeType( options.mimeType );\n\t\t\t\t}\n\n\t\t\t\t// X-Requested-With header\n\t\t\t\t// For cross-domain requests, seeing as conditions for a preflight are\n\t\t\t\t// akin to a jigsaw puzzle, we simply never set it to be sure.\n\t\t\t\t// (it can always be set on a per-request basis or even using ajaxSetup)\n\t\t\t\t// For same-domain requests, won't change header if already provided.\n\t\t\t\tif ( !options.crossDomain && !headers[ \"X-Requested-With\" ] ) {\n\t\t\t\t\theaders[ \"X-Requested-With\" ] = \"XMLHttpRequest\";\n\t\t\t\t}\n\n\t\t\t\t// Set headers\n\t\t\t\tfor ( i in headers ) {\n\t\t\t\t\txhr.setRequestHeader( i, headers[ i ] );\n\t\t\t\t}\n\n\t\t\t\t// Callback\n\t\t\t\tcallback = function( type ) {\n\t\t\t\t\treturn function() {\n\t\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\t\tcallback = errorCallback = xhr.onload =\n\t\t\t\t\t\t\t\txhr.onerror = xhr.onabort = xhr.ontimeout =\n\t\t\t\t\t\t\t\t\txhr.onreadystatechange = null;\n\n\t\t\t\t\t\t\tif ( type === \"abort\" ) {\n\t\t\t\t\t\t\t\txhr.abort();\n\t\t\t\t\t\t\t} else if ( type === \"error\" ) {\n\n\t\t\t\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t\t\t\t// On a manual native abort, IE9 throws\n\t\t\t\t\t\t\t\t// errors on any property access that is not readyState\n\t\t\t\t\t\t\t\tif ( typeof xhr.status !== \"number\" ) {\n\t\t\t\t\t\t\t\t\tcomplete( 0, \"error\" );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tcomplete(\n\n\t\t\t\t\t\t\t\t\t\t// File: protocol always yields status 0; see #8605, #14207\n\t\t\t\t\t\t\t\t\t\txhr.status,\n\t\t\t\t\t\t\t\t\t\txhr.statusText\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tcomplete(\n\t\t\t\t\t\t\t\t\txhrSuccessStatus[ xhr.status ] || xhr.status,\n\t\t\t\t\t\t\t\t\txhr.statusText,\n\n\t\t\t\t\t\t\t\t\t// Support: IE <=9 only\n\t\t\t\t\t\t\t\t\t// IE9 has no XHR2 but throws on binary (trac-11426)\n\t\t\t\t\t\t\t\t\t// For XHR2 non-text, let the caller handle it (gh-2498)\n\t\t\t\t\t\t\t\t\t( xhr.responseType || \"text\" ) !== \"text\" ||\n\t\t\t\t\t\t\t\t\ttypeof xhr.responseText !== \"string\" ?\n\t\t\t\t\t\t\t\t\t\t{ binary: xhr.response } :\n\t\t\t\t\t\t\t\t\t\t{ text: xhr.responseText },\n\t\t\t\t\t\t\t\t\txhr.getAllResponseHeaders()\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t};\n\n\t\t\t\t// Listen to events\n\t\t\t\txhr.onload = callback();\n\t\t\t\terrorCallback = xhr.onerror = xhr.ontimeout = callback( \"error\" );\n\n\t\t\t\t// Support: IE 9 only\n\t\t\t\t// Use onreadystatechange to replace onabort\n\t\t\t\t// to handle uncaught aborts\n\t\t\t\tif ( xhr.onabort !== undefined ) {\n\t\t\t\t\txhr.onabort = errorCallback;\n\t\t\t\t} else {\n\t\t\t\t\txhr.onreadystatechange = function() {\n\n\t\t\t\t\t\t// Check readyState before timeout as it changes\n\t\t\t\t\t\tif ( xhr.readyState === 4 ) {\n\n\t\t\t\t\t\t\t// Allow onerror to be called first,\n\t\t\t\t\t\t\t// but that will not handle a native abort\n\t\t\t\t\t\t\t// Also, save errorCallback to a variable\n\t\t\t\t\t\t\t// as xhr.onerror cannot be accessed\n\t\t\t\t\t\t\twindow.setTimeout( function() {\n\t\t\t\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\t\t\t\terrorCallback();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\t// Create the abort callback\n\t\t\t\tcallback = callback( \"abort\" );\n\n\t\t\t\ttry {\n\n\t\t\t\t\t// Do send the request (this may raise an exception)\n\t\t\t\t\txhr.send( options.hasContent && options.data || null );\n\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\t// #14683: Only rethrow if this hasn't been notified as an error yet\n\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\tthrow e;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tabort: function() {\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n} );\n\n\n\n\n// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)\njQuery.ajaxPrefilter( function( s ) {\n\tif ( s.crossDomain ) {\n\t\ts.contents.script = false;\n\t}\n} );\n\n// Install script dataType\njQuery.ajaxSetup( {\n\taccepts: {\n\t\tscript: \"text/javascript, application/javascript, \" +\n\t\t\t\"application/ecmascript, application/x-ecmascript\"\n\t},\n\tcontents: {\n\t\tscript: /\\b(?:java|ecma)script\\b/\n\t},\n\tconverters: {\n\t\t\"text script\": function( text ) {\n\t\t\tjQuery.globalEval( text );\n\t\t\treturn text;\n\t\t}\n\t}\n} );\n\n// Handle cache's special case and crossDomain\njQuery.ajaxPrefilter( \"script\", function( s ) {\n\tif ( s.cache === undefined ) {\n\t\ts.cache = false;\n\t}\n\tif ( s.crossDomain ) {\n\t\ts.type = \"GET\";\n\t}\n} );\n\n// Bind script tag hack transport\njQuery.ajaxTransport( \"script\", function( s ) {\n\n\t// This transport only deals with cross domain or forced-by-attrs requests\n\tif ( s.crossDomain || s.scriptAttrs ) {\n\t\tvar script, callback;\n\t\treturn {\n\t\t\tsend: function( _, complete ) {\n\t\t\t\tscript = jQuery( \"<script>\" )\n\t\t\t\t\t.attr( s.scriptAttrs || {} )\n\t\t\t\t\t.prop( { charset: s.scriptCharset, src: s.url } )\n\t\t\t\t\t.on( \"load error\", callback = function( evt ) {\n\t\t\t\t\t\tscript.remove();\n\t\t\t\t\t\tcallback = null;\n\t\t\t\t\t\tif ( evt ) {\n\t\t\t\t\t\t\tcomplete( evt.type === \"error\" ? 404 : 200, evt.type );\n\t\t\t\t\t\t}\n\t\t\t\t\t} );\n\n\t\t\t\t// Use native DOM manipulation to avoid our domManip AJAX trickery\n\t\t\t\tdocument.head.appendChild( script[ 0 ] );\n\t\t\t},\n\t\t\tabort: function() {\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n} );\n\n\n\n\nvar oldCallbacks = [],\n\trjsonp = /(=)\\?(?=&|$)|\\?\\?/;\n\n// Default jsonp settings\njQuery.ajaxSetup( {\n\tjsonp: \"callback\",\n\tjsonpCallback: function() {\n\t\tvar callback = oldCallbacks.pop() || ( jQuery.expando + \"_\" + ( nonce.guid++ ) );\n\t\tthis[ callback ] = true;\n\t\treturn callback;\n\t}\n} );\n\n// Detect, normalize options and install callbacks for jsonp requests\njQuery.ajaxPrefilter( \"json jsonp\", function( s, originalSettings, jqXHR ) {\n\n\tvar callbackName, overwritten, responseContainer,\n\t\tjsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?\n\t\t\t\"url\" :\n\t\t\ttypeof s.data === \"string\" &&\n\t\t\t\t( s.contentType || \"\" )\n\t\t\t\t\t.indexOf( \"application/x-www-form-urlencoded\" ) === 0 &&\n\t\t\t\trjsonp.test( s.data ) && \"data\"\n\t\t);\n\n\t// Handle iff the expected data type is \"jsonp\" or we have a parameter to set\n\tif ( jsonProp || s.dataTypes[ 0 ] === \"jsonp\" ) {\n\n\t\t// Get callback name, remembering preexisting value associated with it\n\t\tcallbackName = s.jsonpCallback = isFunction( s.jsonpCallback ) ?\n\t\t\ts.jsonpCallback() :\n\t\t\ts.jsonpCallback;\n\n\t\t// Insert callback into url or form data\n\t\tif ( jsonProp ) {\n\t\t\ts[ jsonProp ] = s[ jsonProp ].replace( rjsonp, \"$1\" + callbackName );\n\t\t} else if ( s.jsonp !== false ) {\n\t\t\ts.url += ( rquery.test( s.url ) ? \"&\" : \"?\" ) + s.jsonp + \"=\" + callbackName;\n\t\t}\n\n\t\t// Use data converter to retrieve json after script execution\n\t\ts.converters[ \"script json\" ] = function() {\n\t\t\tif ( !responseContainer ) {\n\t\t\t\tjQuery.error( callbackName + \" was not called\" );\n\t\t\t}\n\t\t\treturn responseContainer[ 0 ];\n\t\t};\n\n\t\t// Force json dataType\n\t\ts.dataTypes[ 0 ] = \"json\";\n\n\t\t// Install callback\n\t\toverwritten = window[ callbackName ];\n\t\twindow[ callbackName ] = function() {\n\t\t\tresponseContainer = arguments;\n\t\t};\n\n\t\t// Clean-up function (fires after converters)\n\t\tjqXHR.always( function() {\n\n\t\t\t// If previous value didn't exist - remove it\n\t\t\tif ( overwritten === undefined ) {\n\t\t\t\tjQuery( window ).removeProp( callbackName );\n\n\t\t\t// Otherwise restore preexisting value\n\t\t\t} else {\n\t\t\t\twindow[ callbackName ] = overwritten;\n\t\t\t}\n\n\t\t\t// Save back as free\n\t\t\tif ( s[ callbackName ] ) {\n\n\t\t\t\t// Make sure that re-using the options doesn't screw things around\n\t\t\t\ts.jsonpCallback = originalSettings.jsonpCallback;\n\n\t\t\t\t// Save the callback name for future use\n\t\t\t\toldCallbacks.push( callbackName );\n\t\t\t}\n\n\t\t\t// Call if it was a function and we have a response\n\t\t\tif ( responseContainer && isFunction( overwritten ) ) {\n\t\t\t\toverwritten( responseContainer[ 0 ] );\n\t\t\t}\n\n\t\t\tresponseContainer = overwritten = undefined;\n\t\t} );\n\n\t\t// Delegate to script\n\t\treturn \"script\";\n\t}\n} );\n\n\n\n\n// Support: Safari 8 only\n// In Safari 8 documents created via document.implementation.createHTMLDocument\n// collapse sibling forms: the second one becomes a child of the first one.\n// Because of that, this security measure has to be disabled in Safari 8.\n// https://bugs.webkit.org/show_bug.cgi?id=137337\nsupport.createHTMLDocument = ( function() {\n\tvar body = document.implementation.createHTMLDocument( \"\" ).body;\n\tbody.innerHTML = \"<form></form><form></form>\";\n\treturn body.childNodes.length === 2;\n} )();\n\n\n// Argument \"data\" should be string of html\n// context (optional): If specified, the fragment will be created in this context,\n// defaults to document\n// keepScripts (optional): If true, will include scripts passed in the html string\njQuery.parseHTML = function( data, context, keepScripts ) {\n\tif ( typeof data !== \"string\" ) {\n\t\treturn [];\n\t}\n\tif ( typeof context === \"boolean\" ) {\n\t\tkeepScripts = context;\n\t\tcontext = false;\n\t}\n\n\tvar base, parsed, scripts;\n\n\tif ( !context ) {\n\n\t\t// Stop scripts or inline event handlers from being executed immediately\n\t\t// by using document.implementation\n\t\tif ( support.createHTMLDocument ) {\n\t\t\tcontext = document.implementation.createHTMLDocument( \"\" );\n\n\t\t\t// Set the base href for the created document\n\t\t\t// so any parsed elements with URLs\n\t\t\t// are based on the document's URL (gh-2965)\n\t\t\tbase = context.createElement( \"base\" );\n\t\t\tbase.href = document.location.href;\n\t\t\tcontext.head.appendChild( base );\n\t\t} else {\n\t\t\tcontext = document;\n\t\t}\n\t}\n\n\tparsed = rsingleTag.exec( data );\n\tscripts = !keepScripts && [];\n\n\t// Single tag\n\tif ( parsed ) {\n\t\treturn [ context.createElement( parsed[ 1 ] ) ];\n\t}\n\n\tparsed = buildFragment( [ data ], context, scripts );\n\n\tif ( scripts && scripts.length ) {\n\t\tjQuery( scripts ).remove();\n\t}\n\n\treturn jQuery.merge( [], parsed.childNodes );\n};\n\n\n/**\n * Load a url into a page\n */\njQuery.fn.load = function( url, params, callback ) {\n\tvar selector, type, response,\n\t\tself = this,\n\t\toff = url.indexOf( \" \" );\n\n\tif ( off > -1 ) {\n\t\tselector = stripAndCollapse( url.slice( off ) );\n\t\turl = url.slice( 0, off );\n\t}\n\n\t// If it's a function\n\tif ( isFunction( params ) ) {\n\n\t\t// We assume that it's the callback\n\t\tcallback = params;\n\t\tparams = undefined;\n\n\t// Otherwise, build a param string\n\t} else if ( params && typeof params === \"object\" ) {\n\t\ttype = \"POST\";\n\t}\n\n\t// If we have elements to modify, make the request\n\tif ( self.length > 0 ) {\n\t\tjQuery.ajax( {\n\t\t\turl: url,\n\n\t\t\t// If \"type\" variable is undefined, then \"GET\" method will be used.\n\t\t\t// Make value of this field explicit since\n\t\t\t// user can override it through ajaxSetup method\n\t\t\ttype: type || \"GET\",\n\t\t\tdataType: \"html\",\n\t\t\tdata: params\n\t\t} ).done( function( responseText ) {\n\n\t\t\t// Save response for use in complete callback\n\t\t\tresponse = arguments;\n\n\t\t\tself.html( selector ?\n\n\t\t\t\t// If a selector was specified, locate the right elements in a dummy div\n\t\t\t\t// Exclude scripts to avoid IE 'Permission Denied' errors\n\t\t\t\tjQuery( \"<div>\" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :\n\n\t\t\t\t// Otherwise use the full result\n\t\t\t\tresponseText );\n\n\t\t// If the request succeeds, this function gets \"data\", \"status\", \"jqXHR\"\n\t\t// but they are ignored because response was set above.\n\t\t// If it fails, this function gets \"jqXHR\", \"status\", \"error\"\n\t\t} ).always( callback && function( jqXHR, status ) {\n\t\t\tself.each( function() {\n\t\t\t\tcallback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );\n\t\t\t} );\n\t\t} );\n\t}\n\n\treturn this;\n};\n\n\n\n\njQuery.expr.pseudos.animated = function( elem ) {\n\treturn jQuery.grep( jQuery.timers, function( fn ) {\n\t\treturn elem === fn.elem;\n\t} ).length;\n};\n\n\n\n\njQuery.offset = {\n\tsetOffset: function( elem, options, i ) {\n\t\tvar curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,\n\t\t\tposition = jQuery.css( elem, \"position\" ),\n\t\t\tcurElem = jQuery( elem ),\n\t\t\tprops = {};\n\n\t\t// Set position first, in-case top/left are set even on static elem\n\t\tif ( position === \"static\" ) {\n\t\t\telem.style.position = \"relative\";\n\t\t}\n\n\t\tcurOffset = curElem.offset();\n\t\tcurCSSTop = jQuery.css( elem, \"top\" );\n\t\tcurCSSLeft = jQuery.css( elem, \"left\" );\n\t\tcalculatePosition = ( position === \"absolute\" || position === \"fixed\" ) &&\n\t\t\t( curCSSTop + curCSSLeft ).indexOf( \"auto\" ) > -1;\n\n\t\t// Need to be able to calculate position if either\n\t\t// top or left is auto and position is either absolute or fixed\n\t\tif ( calculatePosition ) {\n\t\t\tcurPosition = curElem.position();\n\t\t\tcurTop = curPosition.top;\n\t\t\tcurLeft = curPosition.left;\n\n\t\t} else {\n\t\t\tcurTop = parseFloat( curCSSTop ) || 0;\n\t\t\tcurLeft = parseFloat( curCSSLeft ) || 0;\n\t\t}\n\n\t\tif ( isFunction( options ) ) {\n\n\t\t\t// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)\n\t\t\toptions = options.call( elem, i, jQuery.extend( {}, curOffset ) );\n\t\t}\n\n\t\tif ( options.top != null ) {\n\t\t\tprops.top = ( options.top - curOffset.top ) + curTop;\n\t\t}\n\t\tif ( options.left != null ) {\n\t\t\tprops.left = ( options.left - curOffset.left ) + curLeft;\n\t\t}\n\n\t\tif ( \"using\" in options ) {\n\t\t\toptions.using.call( elem, props );\n\n\t\t} else {\n\t\t\tcurElem.css( props );\n\t\t}\n\t}\n};\n\njQuery.fn.extend( {\n\n\t// offset() relates an element's border box to the document origin\n\toffset: function( options ) {\n\n\t\t// Preserve chaining for setter\n\t\tif ( arguments.length ) {\n\t\t\treturn options === undefined ?\n\t\t\t\tthis :\n\t\t\t\tthis.each( function( i ) {\n\t\t\t\t\tjQuery.offset.setOffset( this, options, i );\n\t\t\t\t} );\n\t\t}\n\n\t\tvar rect, win,\n\t\t\telem = this[ 0 ];\n\n\t\tif ( !elem ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Return zeros for disconnected and hidden (display: none) elements (gh-2310)\n\t\t// Support: IE <=11 only\n\t\t// Running getBoundingClientRect on a\n\t\t// disconnected node in IE throws an error\n\t\tif ( !elem.getClientRects().length ) {\n\t\t\treturn { top: 0, left: 0 };\n\t\t}\n\n\t\t// Get document-relative position by adding viewport scroll to viewport-relative gBCR\n\t\trect = elem.getBoundingClientRect();\n\t\twin = elem.ownerDocument.defaultView;\n\t\treturn {\n\t\t\ttop: rect.top + win.pageYOffset,\n\t\t\tleft: rect.left + win.pageXOffset\n\t\t};\n\t},\n\n\t// position() relates an element's margin box to its offset parent's padding box\n\t// This corresponds to the behavior of CSS absolute positioning\n\tposition: function() {\n\t\tif ( !this[ 0 ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar offsetParent, offset, doc,\n\t\t\telem = this[ 0 ],\n\t\t\tparentOffset = { top: 0, left: 0 };\n\n\t\t// position:fixed elements are offset from the viewport, which itself always has zero offset\n\t\tif ( jQuery.css( elem, \"position\" ) === \"fixed\" ) {\n\n\t\t\t// Assume position:fixed implies availability of getBoundingClientRect\n\t\t\toffset = elem.getBoundingClientRect();\n\n\t\t} else {\n\t\t\toffset = this.offset();\n\n\t\t\t// Account for the *real* offset parent, which can be the document or its root element\n\t\t\t// when a statically positioned element is identified\n\t\t\tdoc = elem.ownerDocument;\n\t\t\toffsetParent = elem.offsetParent || doc.documentElement;\n\t\t\twhile ( offsetParent &&\n\t\t\t\t( offsetParent === doc.body || offsetParent === doc.documentElement ) &&\n\t\t\t\tjQuery.css( offsetParent, \"position\" ) === \"static\" ) {\n\n\t\t\t\toffsetParent = offsetParent.parentNode;\n\t\t\t}\n\t\t\tif ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) {\n\n\t\t\t\t// Incorporate borders into its offset, since they are outside its content origin\n\t\t\t\tparentOffset = jQuery( offsetParent ).offset();\n\t\t\t\tparentOffset.top += jQuery.css( offsetParent, \"borderTopWidth\", true );\n\t\t\t\tparentOffset.left += jQuery.css( offsetParent, \"borderLeftWidth\", true );\n\t\t\t}\n\t\t}\n\n\t\t// Subtract parent offsets and element margins\n\t\treturn {\n\t\t\ttop: offset.top - parentOffset.top - jQuery.css( elem, \"marginTop\", true ),\n\t\t\tleft: offset.left - parentOffset.left - jQuery.css( elem, \"marginLeft\", true )\n\t\t};\n\t},\n\n\t// This method will return documentElement in the following cases:\n\t// 1) For the element inside the iframe without offsetParent, this method will return\n\t// documentElement of the parent window\n\t// 2) For the hidden or detached element\n\t// 3) For body or html element, i.e. in case of the html node - it will return itself\n\t//\n\t// but those exceptions were never presented as a real life use-cases\n\t// and might be considered as more preferable results.\n\t//\n\t// This logic, however, is not guaranteed and can change at any point in the future\n\toffsetParent: function() {\n\t\treturn this.map( function() {\n\t\t\tvar offsetParent = this.offsetParent;\n\n\t\t\twhile ( offsetParent && jQuery.css( offsetParent, \"position\" ) === \"static\" ) {\n\t\t\t\toffsetParent = offsetParent.offsetParent;\n\t\t\t}\n\n\t\t\treturn offsetParent || documentElement;\n\t\t} );\n\t}\n} );\n\n// Create scrollLeft and scrollTop methods\njQuery.each( { scrollLeft: \"pageXOffset\", scrollTop: \"pageYOffset\" }, function( method, prop ) {\n\tvar top = \"pageYOffset\" === prop;\n\n\tjQuery.fn[ method ] = function( val ) {\n\t\treturn access( this, function( elem, method, val ) {\n\n\t\t\t// Coalesce documents and windows\n\t\t\tvar win;\n\t\t\tif ( isWindow( elem ) ) {\n\t\t\t\twin = elem;\n\t\t\t} else if ( elem.nodeType === 9 ) {\n\t\t\t\twin = elem.defaultView;\n\t\t\t}\n\n\t\t\tif ( val === undefined ) {\n\t\t\t\treturn win ? win[ prop ] : elem[ method ];\n\t\t\t}\n\n\t\t\tif ( win ) {\n\t\t\t\twin.scrollTo(\n\t\t\t\t\t!top ? val : win.pageXOffset,\n\t\t\t\t\ttop ? val : win.pageYOffset\n\t\t\t\t);\n\n\t\t\t} else {\n\t\t\t\telem[ method ] = val;\n\t\t\t}\n\t\t}, method, val, arguments.length );\n\t};\n} );\n\n// Support: Safari <=7 - 9.1, Chrome <=37 - 49\n// Add the top/left cssHooks using jQuery.fn.position\n// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084\n// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347\n// getComputedStyle returns percent when specified for top/left/bottom/right;\n// rather than make the css module depend on the offset module, just check for it here\njQuery.each( [ \"top\", \"left\" ], function( _i, prop ) {\n\tjQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,\n\t\tfunction( elem, computed ) {\n\t\t\tif ( computed ) {\n\t\t\t\tcomputed = curCSS( elem, prop );\n\n\t\t\t\t// If curCSS returns percentage, fallback to offset\n\t\t\t\treturn rnumnonpx.test( computed ) ?\n\t\t\t\t\tjQuery( elem ).position()[ prop ] + \"px\" :\n\t\t\t\t\tcomputed;\n\t\t\t}\n\t\t}\n\t);\n} );\n\n\n// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods\njQuery.each( { Height: \"height\", Width: \"width\" }, function( name, type ) {\n\tjQuery.each( {\n\t\tpadding: \"inner\" + name,\n\t\tcontent: type,\n\t\t\"\": \"outer\" + name\n\t}, function( defaultExtra, funcName ) {\n\n\t\t// Margin is only for outerHeight, outerWidth\n\t\tjQuery.fn[ funcName ] = function( margin, value ) {\n\t\t\tvar chainable = arguments.length && ( defaultExtra || typeof margin !== \"boolean\" ),\n\t\t\t\textra = defaultExtra || ( margin === true || value === true ? \"margin\" : \"border\" );\n\n\t\t\treturn access( this, function( elem, type, value ) {\n\t\t\t\tvar doc;\n\n\t\t\t\tif ( isWindow( elem ) ) {\n\n\t\t\t\t\t// $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)\n\t\t\t\t\treturn funcName.indexOf( \"outer\" ) === 0 ?\n\t\t\t\t\t\telem[ \"inner\" + name ] :\n\t\t\t\t\t\telem.document.documentElement[ \"client\" + name ];\n\t\t\t\t}\n\n\t\t\t\t// Get document width or height\n\t\t\t\tif ( elem.nodeType === 9 ) {\n\t\t\t\t\tdoc = elem.documentElement;\n\n\t\t\t\t\t// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],\n\t\t\t\t\t// whichever is greatest\n\t\t\t\t\treturn Math.max(\n\t\t\t\t\t\telem.body[ \"scroll\" + name ], doc[ \"scroll\" + name ],\n\t\t\t\t\t\telem.body[ \"offset\" + name ], doc[ \"offset\" + name ],\n\t\t\t\t\t\tdoc[ \"client\" + name ]\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn value === undefined ?\n\n\t\t\t\t\t// Get width or height on the element, requesting but not forcing parseFloat\n\t\t\t\t\tjQuery.css( elem, type, extra ) :\n\n\t\t\t\t\t// Set width or height on the element\n\t\t\t\t\tjQuery.style( elem, type, value, extra );\n\t\t\t}, type, chainable ? margin : undefined, chainable );\n\t\t};\n\t} );\n} );\n\n\njQuery.each( [\n\t\"ajaxStart\",\n\t\"ajaxStop\",\n\t\"ajaxComplete\",\n\t\"ajaxError\",\n\t\"ajaxSuccess\",\n\t\"ajaxSend\"\n], function( _i, type ) {\n\tjQuery.fn[ type ] = function( fn ) {\n\t\treturn this.on( type, fn );\n\t};\n} );\n\n\n\n\njQuery.fn.extend( {\n\n\tbind: function( types, data, fn ) {\n\t\treturn this.on( types, null, data, fn );\n\t},\n\tunbind: function( types, fn ) {\n\t\treturn this.off( types, null, fn );\n\t},\n\n\tdelegate: function( selector, types, data, fn ) {\n\t\treturn this.on( types, selector, data, fn );\n\t},\n\tundelegate: function( selector, types, fn ) {\n\n\t\t// ( namespace ) or ( selector, types [, fn] )\n\t\treturn arguments.length === 1 ?\n\t\t\tthis.off( selector, \"**\" ) :\n\t\t\tthis.off( types, selector || \"**\", fn );\n\t},\n\n\thover: function( fnOver, fnOut ) {\n\t\treturn this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );\n\t}\n} );\n\njQuery.each(\n\t( \"blur focus focusin focusout resize scroll click dblclick \" +\n\t\"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave \" +\n\t\"change select submit keydown keypress keyup contextmenu\" ).split( \" \" ),\n\tfunction( _i, name ) {\n\n\t\t// Handle event binding\n\t\tjQuery.fn[ name ] = function( data, fn ) {\n\t\t\treturn arguments.length > 0 ?\n\t\t\t\tthis.on( name, null, data, fn ) :\n\t\t\t\tthis.trigger( name );\n\t\t};\n\t}\n);\n\n\n\n\n// Support: Android <=4.0 only\n// Make sure we trim BOM and NBSP\nvar rtrim = /^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g;\n\n// Bind a function to a context, optionally partially applying any\n// arguments.\n// jQuery.proxy is deprecated to promote standards (specifically Function#bind)\n// However, it is not slated for removal any time soon\njQuery.proxy = function( fn, context ) {\n\tvar tmp, args, proxy;\n\n\tif ( typeof context === \"string\" ) {\n\t\ttmp = fn[ context ];\n\t\tcontext = fn;\n\t\tfn = tmp;\n\t}\n\n\t// Quick check to determine if target is callable, in the spec\n\t// this throws a TypeError, but we will just return undefined.\n\tif ( !isFunction( fn ) ) {\n\t\treturn undefined;\n\t}\n\n\t// Simulated bind\n\targs = slice.call( arguments, 2 );\n\tproxy = function() {\n\t\treturn fn.apply( context || this, args.concat( slice.call( arguments ) ) );\n\t};\n\n\t// Set the guid of unique handler to the same of original handler, so it can be removed\n\tproxy.guid = fn.guid = fn.guid || jQuery.guid++;\n\n\treturn proxy;\n};\n\njQuery.holdReady = function( hold ) {\n\tif ( hold ) {\n\t\tjQuery.readyWait++;\n\t} else {\n\t\tjQuery.ready( true );\n\t}\n};\njQuery.isArray = Array.isArray;\njQuery.parseJSON = JSON.parse;\njQuery.nodeName = nodeName;\njQuery.isFunction = isFunction;\njQuery.isWindow = isWindow;\njQuery.camelCase = camelCase;\njQuery.type = toType;\n\njQuery.now = Date.now;\n\njQuery.isNumeric = function( obj ) {\n\n\t// As of jQuery 3.0, isNumeric is limited to\n\t// strings and numbers (primitives or objects)\n\t// that can be coerced to finite numbers (gh-2662)\n\tvar type = jQuery.type( obj );\n\treturn ( type === \"number\" || type === \"string\" ) &&\n\n\t\t// parseFloat NaNs numeric-cast false positives (\"\")\n\t\t// ...but misinterprets leading-number strings, particularly hex literals (\"0x...\")\n\t\t// subtraction forces infinities to NaN\n\t\t!isNaN( obj - parseFloat( obj ) );\n};\n\njQuery.trim = function( text ) {\n\treturn text == null ?\n\t\t\"\" :\n\t\t( text + \"\" ).replace( rtrim, \"\" );\n};\n\n\n\n// Register as a named AMD module, since jQuery can be concatenated with other\n// files that may use define, but not via a proper concatenation script that\n// understands anonymous AMD modules. A named AMD is safest and most robust\n// way to register. Lowercase jquery is used because AMD module names are\n// derived from file names, and jQuery is normally delivered in a lowercase\n// file name. Do this after creating the global so that if an AMD module wants\n// to call noConflict to hide this version of jQuery, it will work.\n\n// Note that for maximum portability, libraries that are not jQuery should\n// declare themselves as anonymous modules, and avoid setting a global if an\n// AMD loader is present. jQuery is a special case. For more information, see\n// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon\n\nif ( true ) {\n\t!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = (function() {\n\t\treturn jQuery;\n\t}).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__),\n\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n}\n\n\n\n\nvar\n\n\t// Map over jQuery in case of overwrite\n\t_jQuery = window.jQuery,\n\n\t// Map over the $ in case of overwrite\n\t_$ = window.$;\n\njQuery.noConflict = function( deep ) {\n\tif ( window.$ === jQuery ) {\n\t\twindow.$ = _$;\n\t}\n\n\tif ( deep && window.jQuery === jQuery ) {\n\t\twindow.jQuery = _jQuery;\n\t}\n\n\treturn jQuery;\n};\n\n// Expose jQuery and $ identifiers, even in AMD\n// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)\n// and CommonJS for browser emulators (#13566)\nif ( typeof noGlobal === \"undefined\" ) {\n\twindow.jQuery = window.$ = jQuery;\n}\n\n\n\n\nreturn jQuery;\n} );\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9ub2RlX21vZHVsZXMvanF1ZXJ5L2Rpc3QvanF1ZXJ5LmpzIiwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsTUFBTSxLQUEwQjs7QUFFaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBOzs7QUFHQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBOzs7QUFHQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQUlBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0osRUFBRTs7QUFFRjtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0osRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0osRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSwrQkFBK0I7QUFDL0I7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLFNBQVMsWUFBWTs7QUFFckI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxFQUFFOztBQUVGLG9CQUFvQjs7QUFFcEI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUYsOENBQThDO0FBQzlDO0FBQ0E7QUFDQSxtQkFBbUIsaUNBQWlDO0FBQ3BELEVBQUU7O0FBRUY7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsV0FBVyxZQUFZO0FBQ3ZCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxVQUFVLFNBQVM7QUFDbkI7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxVQUFVLFlBQVk7QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLFlBQVk7QUFDdkI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxJQUFJO0FBQ0o7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQSxlQUFlO0FBQ2Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsVUFBVSxTQUFTO0FBQ25CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLGtDQUFrQyxJQUFJO0FBQ3RDOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLDJCQUEyQjtBQUMzQjs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTs7QUFFQSxnQkFBZ0IsSUFBSTs7QUFFcEI7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsMENBQTBDLElBQUk7QUFDOUM7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNILElBQUk7QUFDSjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0YsVUFBVTs7QUFFVjtBQUNBO0FBQ0E7QUFDQSxJQUFJOztBQUVKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBOztBQUVBO0FBQ0EsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxNQUFNO0FBQ047QUFDQTs7QUFFQTtBQUNBLE1BQU07QUFDTjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsYUFBYSwwQkFBMEI7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxXQUFXLFVBQVU7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsV0FBVyxVQUFVO0FBQ3JCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsV0FBVyxRQUFRO0FBQ25CLFdBQVcsVUFBVTtBQUNyQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsV0FBVyxTQUFTO0FBQ3BCLFdBQVcsU0FBUztBQUNwQixhQUFhLFFBQVE7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFdBQVcsUUFBUTtBQUNuQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsV0FBVyxRQUFRO0FBQ25CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxXQUFXLFNBQVMsNkJBQTZCO0FBQ2pEO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsV0FBVyxVQUFVO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0EsV0FBVyxpQkFBaUI7QUFDNUIsYUFBYSx3QkFBd0I7QUFDckM7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsV0FBVyxnQkFBZ0I7QUFDM0IsYUFBYSxTQUFTO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFdBQVcsZ0JBQWdCO0FBQzNCLGFBQWEsUUFBUTtBQUNyQjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUI7QUFDbkI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQkFBbUI7QUFDbkI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLElBQUk7O0FBRUo7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTs7QUFFSjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CO0FBQ3BCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQjtBQUNuQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsbUJBQW1CO0FBQ25CO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsV0FBVyxXQUFXO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsV0FBVyxlQUFlO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJOztBQUVKO0FBQ0EsaUNBQWlDLE1BQU07QUFDdkM7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBOztBQUVBLGVBQWU7O0FBRWYsU0FBUzs7QUFFVDtBQUNBLFNBQVMsZ0NBQWdDO0FBQ3pDLFNBQVMsbUJBQW1CO0FBQzVCLFNBQVMscUNBQXFDO0FBQzlDLFNBQVM7QUFDVCxFQUFFOztBQUVGO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsR0FBRzs7QUFFSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ04sR0FBRzs7QUFFSDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsTUFBTTs7QUFFTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLDhEQUE4RDs7QUFFOUQ7QUFDQTtBQUNBO0FBQ0EsMkNBQTJDOztBQUUzQztBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxRQUFROztBQUVSO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLCtEQUErRDs7QUFFL0Q7QUFDQTtBQUNBO0FBQ0EsNENBQTRDOztBQUU1QztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLG1DQUFtQzs7QUFFbkM7QUFDQTtBQUNBO0FBQ0EsK0NBQStDOztBQUUvQztBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEVBQUU7O0FBRUY7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTs7QUFFSjtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7O0FBRUo7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7O0FBRUo7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0EsSUFBSTs7QUFFSjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHOztBQUVIO0FBQ0E7O0FBRUE7QUFDQSxrRUFBa0UsVUFBVTtBQUM1RSx1Q0FBdUMsMkJBQTJCO0FBQ2xFO0FBQ0EsaUNBQWlDLE1BQU07QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQSxJQUFJOztBQUVKO0FBQ0E7QUFDQSxJQUFJOztBQUVKO0FBQ0E7QUFDQSxJQUFJOztBQUVKO0FBQ0E7QUFDQSxXQUFXLFlBQVk7QUFDdkI7QUFDQTtBQUNBO0FBQ0EsSUFBSTs7QUFFSjtBQUNBO0FBQ0EsV0FBVyxZQUFZO0FBQ3ZCO0FBQ0E7QUFDQTtBQUNBLElBQUk7O0FBRUo7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxVQUFVO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBLElBQUk7O0FBRUo7QUFDQTtBQUNBLFdBQVcsY0FBYztBQUN6QjtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLGFBQWEsdUVBQXVFO0FBQ3BGO0FBQ0E7QUFDQSxhQUFhLDRCQUE0QjtBQUN6QztBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTLFNBQVM7QUFDbEI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJOztBQUVKO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsNkRBQTZEOztBQUU3RDtBQUNBO0FBQ0E7QUFDQSwwQ0FBMEM7O0FBRTFDO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7O0FBRUE7QUFDQTtBQUNBLFFBQVE7O0FBRVI7QUFDQTs7QUFFQSxvQ0FBb0M7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxTQUFTLFNBQVM7QUFDbEI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLFNBQVMsU0FBUztBQUNsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsSUFBSTs7QUFFSixTQUFTLFNBQVM7QUFDbEI7QUFDQTtBQUNBLElBQUk7QUFDSjs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxZQUFZLFNBQVM7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLGlEQUFpRDtBQUNsRTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQSxzQkFBc0I7QUFDdEI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxrREFBa0Q7QUFDbEQsV0FBVyw0Q0FBNEM7QUFDdkQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsdUJBQXVCO0FBQ3ZCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLGlCQUFpQjtBQUM1QjtBQUNBLFdBQVcsU0FBUztBQUNwQixXQUFXLE9BQU87QUFDbEIsV0FBVyxPQUFPO0FBQ2xCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBOztBQUVBLEVBQUU7Ozs7QUFJRjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQUtBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTs7QUFFQSxTQUFTLEdBQUc7QUFDWjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOzs7QUFHQTs7OztBQUlBOztBQUVBOztBQUVBO0FBQ0E7Ozs7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxpQkFBaUIsU0FBUztBQUMxQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTs7QUFFQSxlQUFlLFNBQVM7QUFDeEI7QUFDQTs7QUFFQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOzs7QUFHRjs7O0FBR0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0EsTUFBTTtBQUNOOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7OztBQUdBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxXQUFXLE9BQU87QUFDbEI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0osRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFdBQVcsT0FBTztBQUNsQiwyQkFBMkIsd0JBQXdCOztBQUVuRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQSwyQ0FBMkM7QUFDM0MsRUFBRTtBQUNGO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsQ0FBQztBQUNEO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7Ozs7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQjs7QUFFbkI7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsV0FBVyxjQUFjO0FBQ3pCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUzs7QUFFVDtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1IsT0FBTzs7QUFFUDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTs7QUFFSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBLElBQUk7O0FBRUo7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTs7QUFFSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJOztBQUVKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQSxJQUFJOztBQUVKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0EsSUFBSTs7QUFFSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTs7QUFFSjtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7O0FBRUo7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxJQUFJO0FBQ0o7O0FBRUE7QUFDQSxJQUFJOztBQUVKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEseUNBQXlDLHFDQUFxQztBQUM5RSxxQ0FBcUMsc0NBQXNDO0FBQzNFLHFDQUFxQyxxQ0FBcUM7QUFDMUU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVCxRQUFRO0FBQ1I7QUFDQSxPQUFPO0FBQ1AsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLFlBQVk7O0FBRVo7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsV0FBVzs7QUFFWDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTOztBQUVUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7O0FBRVo7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7O0FBRVQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1AsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE1BQU07O0FBRU47QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLHFDQUFxQztBQUNyQyxzQ0FBc0M7QUFDdEMscUNBQXFDO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTs7QUFFSjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsRUFBRTs7O0FBR0Y7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUFLQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7Ozs7O0FBS0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJOztBQUVKO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLEVBQUU7O0FBRUY7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7Ozs7O0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsV0FBVyxTQUFTO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxnQ0FBZ0M7QUFDaEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FBS0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBOztBQUVBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSx3QkFBd0IsYUFBYTtBQUNyQyxJQUFJOztBQUVKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEVBQUU7QUFDRjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLG9CQUFvQixTQUFTO0FBQzdCOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsR0FBRztBQUNILEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0EsRUFBRTs7O0FBR0Y7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTCxJQUFJO0FBQ0o7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTCxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKLEVBQUU7QUFDRjtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGOztBQUVBOzs7QUFHQTs7QUFFQTs7OztBQUlBO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsZUFBZTs7QUFFZjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7Ozs7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsU0FBUyxnQkFBZ0I7QUFDekI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0Esa0JBQWtCLGdCQUFnQjtBQUNsQztBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0EsRUFBRTtBQUNGOztBQUVBOztBQUVBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOzs7QUFHRjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsR0FBRztBQUNIOztBQUVBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxTQUFTLE9BQU87QUFDaEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBLHNCQUFzQjs7QUFFdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLFNBQVMsT0FBTztBQUNoQjs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7O0FBR0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsSUFBSTs7QUFFSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxXQUFXOztBQUVYOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJOztBQUVKO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLEVBQUU7O0FBRUY7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsNENBQTRDO0FBQzVDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLGVBQWUsc0JBQXNCO0FBQ3JDO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSwwQkFBMEI7QUFDMUI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLGdFQUFnRTtBQUNoRTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLFdBQVcsY0FBYzs7QUFFekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQixtQkFBbUI7QUFDckM7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJCQUEyQix1Q0FBdUM7QUFDbEU7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0Esd0JBQXdCLHVEQUF1RDtBQUMvRTs7QUFFQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0EsSUFBSTtBQUNKLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxJQUFJOztBQUVKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNLCtDQUErQztBQUNyRDtBQUNBOztBQUVBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNOztBQUVOO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSx1Q0FBdUM7QUFDdkM7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7O0FBRUQsZUFBZSxvQ0FBb0M7QUFDbkQ7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRztBQUNIOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQ0FBc0M7QUFDdEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGOztBQUVBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBLEVBQUU7OztBQUdGOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLDRDQUE0QyxPQUFPO0FBQ25EO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsOEJBQThCOztBQUU5QjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLE9BQU87QUFDbEI7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxpQkFBaUIsZ0JBQWdCO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsU0FBUywrQkFBK0I7QUFDeEM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLHdDQUF3QyxPQUFPO0FBQy9DO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLHlDQUF5QyxPQUFPO0FBQ2hEO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsVUFBVSxxQ0FBcUM7QUFDL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTixHQUFHO0FBQ0gsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0osRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0osRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSixFQUFFOztBQUVGO0FBQ0E7QUFDQTs7QUFFQSxVQUFVLDhCQUE4QjtBQUN4Qzs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLElBQUk7QUFDSixFQUFFOztBQUVGO0FBQ0E7QUFDQSw2QkFBNkI7QUFDN0I7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0EsYUFBYSxPQUFPO0FBQ3BCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBLE1BQU07QUFDTjs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsRUFBRTs7QUFFRjtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHO0FBQ0g7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsVUFBVSxXQUFXO0FBQ3JCO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEVBQUU7QUFDRjs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOzs7QUFHQTs7OztBQUlBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSwrQ0FBK0MsY0FBYyxXQUFXO0FBQ3hFLG1CQUFtQixVQUFVO0FBQzdCO0FBQ0Esc0JBQXNCLGNBQWMsc0JBQXNCLGdCQUFnQjtBQUMxRSxnQkFBZ0IsV0FBVyxZQUFZO0FBQ3ZDLGNBQWM7QUFDZDs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUNBQWlDO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLDZDQUE2QyxjQUFjO0FBQzNEOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsRUFBRTs7O0FBR0Y7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsbUJBQW1CO0FBQ25CO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhLDhEQUE4RDtBQUMzRTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxTQUFTLE9BQU87O0FBRWhCO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsSUFBSTs7QUFFSjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0EsYUFBYTs7QUFFYjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTs7QUFFQSxJQUFJOztBQUVKO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG1CQUFtQixlQUFlO0FBQ2xDO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCOztBQUVqQjtBQUNBOztBQUVBLFdBQVcsT0FBTztBQUNsQjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7O0FBRUE7QUFDQTtBQUNBOztBQUVBLFlBQVksU0FBUztBQUNyQjtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0EsRUFBRTs7O0FBR0Y7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOzs7OztBQUtBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZOztBQUVaO0FBQ0E7QUFDQTtBQUNBLFNBQVMsT0FBTztBQUNoQjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVMsZ0JBQWdCO0FBQ3pCOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXO0FBQ1g7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTCxJQUFJO0FBQ0o7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTCxrREFBa0QsMEJBQTBCO0FBQzVFOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsV0FBVyxnQkFBZ0I7QUFDM0I7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBLDJCQUEyQjtBQUMzQjtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSxnQkFBZ0I7QUFDNUI7QUFDQTs7QUFFQSw4Q0FBOEM7QUFDOUM7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKOztBQUVBOztBQUVBLFNBQVMsZ0JBQWdCO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUEsVUFBVSxnQkFBZ0I7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGOztBQUVBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0EsaUVBQWlFO0FBQ2pFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLEdBQUc7QUFDSDtBQUNBO0FBQ0E7O0FBRUEsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxxQkFBcUIsYUFBYTtBQUNsQyxFQUFFO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxpREFBaUQ7O0FBRWpEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBLGdDQUFnQyxTQUFTO0FBQ3pDO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0osRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGdDQUFnQyxTQUFTO0FBQ3pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxvQkFBb0IsZ0JBQWdCO0FBQ3BDO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxpQkFBaUI7QUFDNUIsWUFBWSxpQkFBaUI7QUFDN0IsZUFBZTtBQUNmLENBQUM7QUFDRDtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsU0FBUyxtQkFBbUI7QUFDNUI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7OztBQUdBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7O0FBR0Y7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7Ozs7QUFLRjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7Ozs7QUFLRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsT0FBTztBQUNQO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0osRUFBRTs7QUFFRjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEVBQUU7Ozs7O0FBS0Y7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTs7QUFFQSxrQ0FBa0M7QUFDbEM7QUFDQTs7QUFFQSxLQUFLO0FBQ0w7O0FBRUEsS0FBSztBQUNMO0FBQ0E7QUFDQSxNQUFNO0FBQ047O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLE1BQU07QUFDTjtBQUNBOztBQUVBO0FBQ0EsWUFBWSxTQUFTO0FBQ3JCOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsSUFBSTs7QUFFSjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOzs7OztBQUtGOzs7QUFHQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsdUNBQXVDO0FBQ3ZDO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQSwwQkFBMEI7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSwrQ0FBK0M7QUFDL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSw0Q0FBNEM7QUFDNUM7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLEtBQUs7QUFDaEI7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUEsRUFBRTs7QUFFRjs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0osRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7OztBQUdGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixvQ0FBb0M7O0FBRXBEO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQSxjQUFjOztBQUVkOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ047QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7O0FBRUosR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsSUFBSTs7QUFFSixHQUFHOztBQUVIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsY0FBYztBQUNkLE1BQU07QUFDTjs7QUFFQSxZQUFZO0FBQ1osSUFBSTtBQUNKO0FBQ0EsRUFBRTs7O0FBR0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7O0FBRWhCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0I7O0FBRWhCLGlEQUFpRDtBQUNqRDs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxtQkFBbUI7QUFDbkI7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0EseURBQXlEO0FBQ3pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjs7QUFFakI7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxVQUFVO0FBQ1Y7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLGlCQUFpQjtBQUNqQixTQUFTOztBQUVUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbURBQW1EOztBQUVuRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7O0FBRUg7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHOztBQUVIO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsR0FBRzs7QUFFSDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBLDJCQUEyQjs7QUFFM0I7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGtDQUFrQzs7QUFFbEM7QUFDQSxzQkFBc0I7QUFDdEIsMkJBQTJCOztBQUUzQjtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxRQUFROztBQUVSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHVEQUF1RDtBQUN2RDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsTUFBTTtBQUNOOztBQUVBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxLQUFLOztBQUVMO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7O0FBR0Y7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDs7O0FBR0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSxLQUFLO0FBQ0w7QUFDQTtBQUNBLElBQUk7QUFDSixFQUFFOztBQUVGO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLElBQUk7QUFDSixFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0EsRUFBRTs7O0FBR0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQUtBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFDSDs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxTQUFTOztBQUVUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7O0FBRUEsb0RBQW9EO0FBQ3BEO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWSx1QkFBdUI7QUFDbkMsWUFBWSx3QkFBd0I7QUFDcEM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0EsTUFBTTs7QUFFTjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTs7QUFFSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7Ozs7O0FBS0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBO0FBQ0EsRUFBRTtBQUNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0M7QUFDaEMsY0FBYyx1Q0FBdUM7QUFDckQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsT0FBTzs7QUFFUDtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7Ozs7QUFLRjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxJQUFJOztBQUVKO0FBQ0E7QUFDQTtBQUNBLEVBQUU7Ozs7O0FBS0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7O0FBR0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxHQUFHO0FBQ0g7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJOztBQUVKO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQSxLQUFLO0FBQ0wsSUFBSTtBQUNKOztBQUVBO0FBQ0E7Ozs7O0FBS0E7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIOzs7OztBQUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQSxJQUFJO0FBQ0o7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0EscURBQXFEO0FBQ3JEOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLG9CQUFvQjs7QUFFcEI7QUFDQTs7QUFFQTtBQUNBOztBQUVBLElBQUk7QUFDSjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLElBQUk7QUFDSjtBQUNBLEVBQUU7O0FBRUY7QUFDQSxlQUFlLHFEQUFxRDtBQUNwRTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsS0FBSztBQUNMO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQSxFQUFFOztBQUVGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOzs7QUFHRjtBQUNBLGVBQWUsa0NBQWtDO0FBQ2pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0EsR0FBRztBQUNILEVBQUU7OztBQUdGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxFQUFFOzs7OztBQUtGOztBQUVBO0FBQ0E7QUFDQSxFQUFFO0FBQ0Y7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBLEVBQUU7QUFDRjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEVBQUU7O0FBRUY7QUFDQTtBQUNBO0FBQ0EsRUFBRTs7QUFFRjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FBS0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsR0FBRztBQUNIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUEsS0FBSyxJQUEwQztBQUMvQyxDQUFDLGlDQUFrQixFQUFFLG1DQUFFO0FBQ3ZCO0FBQ0EsRUFBRTtBQUFBLGtHQUFFO0FBQ0o7Ozs7O0FBS0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUFLQTtBQUNBLEVBQUUiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vLi9ub2RlX21vZHVsZXMvanF1ZXJ5L2Rpc3QvanF1ZXJ5LmpzPzgyNjIiXSwic291cmNlc0NvbnRlbnQiOlsiLyohXG4gKiBqUXVlcnkgSmF2YVNjcmlwdCBMaWJyYXJ5IHYzLjYuMFxuICogaHR0cHM6Ly9qcXVlcnkuY29tL1xuICpcbiAqIEluY2x1ZGVzIFNpenpsZS5qc1xuICogaHR0cHM6Ly9zaXp6bGVqcy5jb20vXG4gKlxuICogQ29weXJpZ2h0IE9wZW5KUyBGb3VuZGF0aW9uIGFuZCBvdGhlciBjb250cmlidXRvcnNcbiAqIFJlbGVhc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZVxuICogaHR0cHM6Ly9qcXVlcnkub3JnL2xpY2Vuc2VcbiAqXG4gKiBEYXRlOiAyMDIxLTAzLTAyVDE3OjA4WlxuICovXG4oIGZ1bmN0aW9uKCBnbG9iYWwsIGZhY3RvcnkgKSB7XG5cblx0XCJ1c2Ugc3RyaWN0XCI7XG5cblx0aWYgKCB0eXBlb2YgbW9kdWxlID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBtb2R1bGUuZXhwb3J0cyA9PT0gXCJvYmplY3RcIiApIHtcblxuXHRcdC8vIEZvciBDb21tb25KUyBhbmQgQ29tbW9uSlMtbGlrZSBlbnZpcm9ubWVudHMgd2hlcmUgYSBwcm9wZXIgYHdpbmRvd2Bcblx0XHQvLyBpcyBwcmVzZW50LCBleGVjdXRlIHRoZSBmYWN0b3J5IGFuZCBnZXQgalF1ZXJ5LlxuXHRcdC8vIEZvciBlbnZpcm9ubWVudHMgdGhhdCBkbyBub3QgaGF2ZSBhIGB3aW5kb3dgIHdpdGggYSBgZG9jdW1lbnRgXG5cdFx0Ly8gKHN1Y2ggYXMgTm9kZS5qcyksIGV4cG9zZSBhIGZhY3RvcnkgYXMgbW9kdWxlLmV4cG9ydHMuXG5cdFx0Ly8gVGhpcyBhY2NlbnR1YXRlcyB0aGUgbmVlZCBmb3IgdGhlIGNyZWF0aW9uIG9mIGEgcmVhbCBgd2luZG93YC5cblx0XHQvLyBlLmcuIHZhciBqUXVlcnkgPSByZXF1aXJlKFwianF1ZXJ5XCIpKHdpbmRvdyk7XG5cdFx0Ly8gU2VlIHRpY2tldCAjMTQ1NDkgZm9yIG1vcmUgaW5mby5cblx0XHRtb2R1bGUuZXhwb3J0cyA9IGdsb2JhbC5kb2N1bWVudCA/XG5cdFx0XHRmYWN0b3J5KCBnbG9iYWwsIHRydWUgKSA6XG5cdFx0XHRmdW5jdGlvbiggdyApIHtcblx0XHRcdFx0aWYgKCAhdy5kb2N1bWVudCApIHtcblx0XHRcdFx0XHR0aHJvdyBuZXcgRXJyb3IoIFwialF1ZXJ5IHJlcXVpcmVzIGEgd2luZG93IHdpdGggYSBkb2N1bWVudFwiICk7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIGZhY3RvcnkoIHcgKTtcblx0XHRcdH07XG5cdH0gZWxzZSB7XG5cdFx0ZmFjdG9yeSggZ2xvYmFsICk7XG5cdH1cblxuLy8gUGFzcyB0aGlzIGlmIHdpbmRvdyBpcyBub3QgZGVmaW5lZCB5ZXRcbn0gKSggdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHRoaXMsIGZ1bmN0aW9uKCB3aW5kb3csIG5vR2xvYmFsICkge1xuXG4vLyBFZGdlIDw9IDEyIC0gMTMrLCBGaXJlZm94IDw9MTggLSA0NSssIElFIDEwIC0gMTEsIFNhZmFyaSA1LjEgLSA5KywgaU9TIDYgLSA5LjFcbi8vIHRocm93IGV4Y2VwdGlvbnMgd2hlbiBub24tc3RyaWN0IGNvZGUgKGUuZy4sIEFTUC5ORVQgNC41KSBhY2Nlc3NlcyBzdHJpY3QgbW9kZVxuLy8gYXJndW1lbnRzLmNhbGxlZS5jYWxsZXIgKHRyYWMtMTMzMzUpLiBCdXQgYXMgb2YgalF1ZXJ5IDMuMCAoMjAxNiksIHN0cmljdCBtb2RlIHNob3VsZCBiZSBjb21tb25cbi8vIGVub3VnaCB0aGF0IGFsbCBzdWNoIGF0dGVtcHRzIGFyZSBndWFyZGVkIGluIGEgdHJ5IGJsb2NrLlxuXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciBhcnIgPSBbXTtcblxudmFyIGdldFByb3RvID0gT2JqZWN0LmdldFByb3RvdHlwZU9mO1xuXG52YXIgc2xpY2UgPSBhcnIuc2xpY2U7XG5cbnZhciBmbGF0ID0gYXJyLmZsYXQgPyBmdW5jdGlvbiggYXJyYXkgKSB7XG5cdHJldHVybiBhcnIuZmxhdC5jYWxsKCBhcnJheSApO1xufSA6IGZ1bmN0aW9uKCBhcnJheSApIHtcblx0cmV0dXJuIGFyci5jb25jYXQuYXBwbHkoIFtdLCBhcnJheSApO1xufTtcblxuXG52YXIgcHVzaCA9IGFyci5wdXNoO1xuXG52YXIgaW5kZXhPZiA9IGFyci5pbmRleE9mO1xuXG52YXIgY2xhc3MydHlwZSA9IHt9O1xuXG52YXIgdG9TdHJpbmcgPSBjbGFzczJ0eXBlLnRvU3RyaW5nO1xuXG52YXIgaGFzT3duID0gY2xhc3MydHlwZS5oYXNPd25Qcm9wZXJ0eTtcblxudmFyIGZuVG9TdHJpbmcgPSBoYXNPd24udG9TdHJpbmc7XG5cbnZhciBPYmplY3RGdW5jdGlvblN0cmluZyA9IGZuVG9TdHJpbmcuY2FsbCggT2JqZWN0ICk7XG5cbnZhciBzdXBwb3J0ID0ge307XG5cbnZhciBpc0Z1bmN0aW9uID0gZnVuY3Rpb24gaXNGdW5jdGlvbiggb2JqICkge1xuXG5cdFx0Ly8gU3VwcG9ydDogQ2hyb21lIDw9NTcsIEZpcmVmb3ggPD01MlxuXHRcdC8vIEluIHNvbWUgYnJvd3NlcnMsIHR5cGVvZiByZXR1cm5zIFwiZnVuY3Rpb25cIiBmb3IgSFRNTCA8b2JqZWN0PiBlbGVtZW50c1xuXHRcdC8vIChpLmUuLCBgdHlwZW9mIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwib2JqZWN0XCIgKSA9PT0gXCJmdW5jdGlvblwiYCkuXG5cdFx0Ly8gV2UgZG9uJ3Qgd2FudCB0byBjbGFzc2lmeSAqYW55KiBET00gbm9kZSBhcyBhIGZ1bmN0aW9uLlxuXHRcdC8vIFN1cHBvcnQ6IFF0V2ViIDw9My44LjUsIFdlYktpdCA8PTUzNC4zNCwgd2todG1sdG9wZGYgdG9vbCA8PTAuMTIuNVxuXHRcdC8vIFBsdXMgZm9yIG9sZCBXZWJLaXQsIHR5cGVvZiByZXR1cm5zIFwiZnVuY3Rpb25cIiBmb3IgSFRNTCBjb2xsZWN0aW9uc1xuXHRcdC8vIChlLmcuLCBgdHlwZW9mIGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKFwiZGl2XCIpID09PSBcImZ1bmN0aW9uXCJgKS4gKGdoLTQ3NTYpXG5cdFx0cmV0dXJuIHR5cGVvZiBvYmogPT09IFwiZnVuY3Rpb25cIiAmJiB0eXBlb2Ygb2JqLm5vZGVUeXBlICE9PSBcIm51bWJlclwiICYmXG5cdFx0XHR0eXBlb2Ygb2JqLml0ZW0gIT09IFwiZnVuY3Rpb25cIjtcblx0fTtcblxuXG52YXIgaXNXaW5kb3cgPSBmdW5jdGlvbiBpc1dpbmRvdyggb2JqICkge1xuXHRcdHJldHVybiBvYmogIT0gbnVsbCAmJiBvYmogPT09IG9iai53aW5kb3c7XG5cdH07XG5cblxudmFyIGRvY3VtZW50ID0gd2luZG93LmRvY3VtZW50O1xuXG5cblxuXHR2YXIgcHJlc2VydmVkU2NyaXB0QXR0cmlidXRlcyA9IHtcblx0XHR0eXBlOiB0cnVlLFxuXHRcdHNyYzogdHJ1ZSxcblx0XHRub25jZTogdHJ1ZSxcblx0XHRub01vZHVsZTogdHJ1ZVxuXHR9O1xuXG5cdGZ1bmN0aW9uIERPTUV2YWwoIGNvZGUsIG5vZGUsIGRvYyApIHtcblx0XHRkb2MgPSBkb2MgfHwgZG9jdW1lbnQ7XG5cblx0XHR2YXIgaSwgdmFsLFxuXHRcdFx0c2NyaXB0ID0gZG9jLmNyZWF0ZUVsZW1lbnQoIFwic2NyaXB0XCIgKTtcblxuXHRcdHNjcmlwdC50ZXh0ID0gY29kZTtcblx0XHRpZiAoIG5vZGUgKSB7XG5cdFx0XHRmb3IgKCBpIGluIHByZXNlcnZlZFNjcmlwdEF0dHJpYnV0ZXMgKSB7XG5cblx0XHRcdFx0Ly8gU3VwcG9ydDogRmlyZWZveCA2NCssIEVkZ2UgMTgrXG5cdFx0XHRcdC8vIFNvbWUgYnJvd3NlcnMgZG9uJ3Qgc3VwcG9ydCB0aGUgXCJub25jZVwiIHByb3BlcnR5IG9uIHNjcmlwdHMuXG5cdFx0XHRcdC8vIE9uIHRoZSBvdGhlciBoYW5kLCBqdXN0IHVzaW5nIGBnZXRBdHRyaWJ1dGVgIGlzIG5vdCBlbm91Z2ggYXNcblx0XHRcdFx0Ly8gdGhlIGBub25jZWAgYXR0cmlidXRlIGlzIHJlc2V0IHRvIGFuIGVtcHR5IHN0cmluZyB3aGVuZXZlciBpdFxuXHRcdFx0XHQvLyBiZWNvbWVzIGJyb3dzaW5nLWNvbnRleHQgY29ubmVjdGVkLlxuXHRcdFx0XHQvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL3doYXR3Zy9odG1sL2lzc3Vlcy8yMzY5XG5cdFx0XHRcdC8vIFNlZSBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnLyNub25jZS1hdHRyaWJ1dGVzXG5cdFx0XHRcdC8vIFRoZSBgbm9kZS5nZXRBdHRyaWJ1dGVgIGNoZWNrIHdhcyBhZGRlZCBmb3IgdGhlIHNha2Ugb2Zcblx0XHRcdFx0Ly8gYGpRdWVyeS5nbG9iYWxFdmFsYCBzbyB0aGF0IGl0IGNhbiBmYWtlIGEgbm9uY2UtY29udGFpbmluZyBub2RlXG5cdFx0XHRcdC8vIHZpYSBhbiBvYmplY3QuXG5cdFx0XHRcdHZhbCA9IG5vZGVbIGkgXSB8fCBub2RlLmdldEF0dHJpYnV0ZSAmJiBub2RlLmdldEF0dHJpYnV0ZSggaSApO1xuXHRcdFx0XHRpZiAoIHZhbCApIHtcblx0XHRcdFx0XHRzY3JpcHQuc2V0QXR0cmlidXRlKCBpLCB2YWwgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0XHRkb2MuaGVhZC5hcHBlbmRDaGlsZCggc2NyaXB0ICkucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCggc2NyaXB0ICk7XG5cdH1cblxuXG5mdW5jdGlvbiB0b1R5cGUoIG9iaiApIHtcblx0aWYgKCBvYmogPT0gbnVsbCApIHtcblx0XHRyZXR1cm4gb2JqICsgXCJcIjtcblx0fVxuXG5cdC8vIFN1cHBvcnQ6IEFuZHJvaWQgPD0yLjMgb25seSAoZnVuY3Rpb25pc2ggUmVnRXhwKVxuXHRyZXR1cm4gdHlwZW9mIG9iaiA9PT0gXCJvYmplY3RcIiB8fCB0eXBlb2Ygb2JqID09PSBcImZ1bmN0aW9uXCIgP1xuXHRcdGNsYXNzMnR5cGVbIHRvU3RyaW5nLmNhbGwoIG9iaiApIF0gfHwgXCJvYmplY3RcIiA6XG5cdFx0dHlwZW9mIG9iajtcbn1cbi8qIGdsb2JhbCBTeW1ib2wgKi9cbi8vIERlZmluaW5nIHRoaXMgZ2xvYmFsIGluIC5lc2xpbnRyYy5qc29uIHdvdWxkIGNyZWF0ZSBhIGRhbmdlciBvZiB1c2luZyB0aGUgZ2xvYmFsXG4vLyB1bmd1YXJkZWQgaW4gYW5vdGhlciBwbGFjZSwgaXQgc2VlbXMgc2FmZXIgdG8gZGVmaW5lIGdsb2JhbCBvbmx5IGZvciB0aGlzIG1vZHVsZVxuXG5cblxudmFyXG5cdHZlcnNpb24gPSBcIjMuNi4wXCIsXG5cblx0Ly8gRGVmaW5lIGEgbG9jYWwgY29weSBvZiBqUXVlcnlcblx0alF1ZXJ5ID0gZnVuY3Rpb24oIHNlbGVjdG9yLCBjb250ZXh0ICkge1xuXG5cdFx0Ly8gVGhlIGpRdWVyeSBvYmplY3QgaXMgYWN0dWFsbHkganVzdCB0aGUgaW5pdCBjb25zdHJ1Y3RvciAnZW5oYW5jZWQnXG5cdFx0Ly8gTmVlZCBpbml0IGlmIGpRdWVyeSBpcyBjYWxsZWQgKGp1c3QgYWxsb3cgZXJyb3IgdG8gYmUgdGhyb3duIGlmIG5vdCBpbmNsdWRlZClcblx0XHRyZXR1cm4gbmV3IGpRdWVyeS5mbi5pbml0KCBzZWxlY3RvciwgY29udGV4dCApO1xuXHR9O1xuXG5qUXVlcnkuZm4gPSBqUXVlcnkucHJvdG90eXBlID0ge1xuXG5cdC8vIFRoZSBjdXJyZW50IHZlcnNpb24gb2YgalF1ZXJ5IGJlaW5nIHVzZWRcblx0anF1ZXJ5OiB2ZXJzaW9uLFxuXG5cdGNvbnN0cnVjdG9yOiBqUXVlcnksXG5cblx0Ly8gVGhlIGRlZmF1bHQgbGVuZ3RoIG9mIGEgalF1ZXJ5IG9iamVjdCBpcyAwXG5cdGxlbmd0aDogMCxcblxuXHR0b0FycmF5OiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gc2xpY2UuY2FsbCggdGhpcyApO1xuXHR9LFxuXG5cdC8vIEdldCB0aGUgTnRoIGVsZW1lbnQgaW4gdGhlIG1hdGNoZWQgZWxlbWVudCBzZXQgT1Jcblx0Ly8gR2V0IHRoZSB3aG9sZSBtYXRjaGVkIGVsZW1lbnQgc2V0IGFzIGEgY2xlYW4gYXJyYXlcblx0Z2V0OiBmdW5jdGlvbiggbnVtICkge1xuXG5cdFx0Ly8gUmV0dXJuIGFsbCB0aGUgZWxlbWVudHMgaW4gYSBjbGVhbiBhcnJheVxuXHRcdGlmICggbnVtID09IG51bGwgKSB7XG5cdFx0XHRyZXR1cm4gc2xpY2UuY2FsbCggdGhpcyApO1xuXHRcdH1cblxuXHRcdC8vIFJldHVybiBqdXN0IHRoZSBvbmUgZWxlbWVudCBmcm9tIHRoZSBzZXRcblx0XHRyZXR1cm4gbnVtIDwgMCA/IHRoaXNbIG51bSArIHRoaXMubGVuZ3RoIF0gOiB0aGlzWyBudW0gXTtcblx0fSxcblxuXHQvLyBUYWtlIGFuIGFycmF5IG9mIGVsZW1lbnRzIGFuZCBwdXNoIGl0IG9udG8gdGhlIHN0YWNrXG5cdC8vIChyZXR1cm5pbmcgdGhlIG5ldyBtYXRjaGVkIGVsZW1lbnQgc2V0KVxuXHRwdXNoU3RhY2s6IGZ1bmN0aW9uKCBlbGVtcyApIHtcblxuXHRcdC8vIEJ1aWxkIGEgbmV3IGpRdWVyeSBtYXRjaGVkIGVsZW1lbnQgc2V0XG5cdFx0dmFyIHJldCA9IGpRdWVyeS5tZXJnZSggdGhpcy5jb25zdHJ1Y3RvcigpLCBlbGVtcyApO1xuXG5cdFx0Ly8gQWRkIHRoZSBvbGQgb2JqZWN0IG9udG8gdGhlIHN0YWNrIChhcyBhIHJlZmVyZW5jZSlcblx0XHRyZXQucHJldk9iamVjdCA9IHRoaXM7XG5cblx0XHQvLyBSZXR1cm4gdGhlIG5ld2x5LWZvcm1lZCBlbGVtZW50IHNldFxuXHRcdHJldHVybiByZXQ7XG5cdH0sXG5cblx0Ly8gRXhlY3V0ZSBhIGNhbGxiYWNrIGZvciBldmVyeSBlbGVtZW50IGluIHRoZSBtYXRjaGVkIHNldC5cblx0ZWFjaDogZnVuY3Rpb24oIGNhbGxiYWNrICkge1xuXHRcdHJldHVybiBqUXVlcnkuZWFjaCggdGhpcywgY2FsbGJhY2sgKTtcblx0fSxcblxuXHRtYXA6IGZ1bmN0aW9uKCBjYWxsYmFjayApIHtcblx0XHRyZXR1cm4gdGhpcy5wdXNoU3RhY2soIGpRdWVyeS5tYXAoIHRoaXMsIGZ1bmN0aW9uKCBlbGVtLCBpICkge1xuXHRcdFx0cmV0dXJuIGNhbGxiYWNrLmNhbGwoIGVsZW0sIGksIGVsZW0gKTtcblx0XHR9ICkgKTtcblx0fSxcblxuXHRzbGljZTogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHRoaXMucHVzaFN0YWNrKCBzbGljZS5hcHBseSggdGhpcywgYXJndW1lbnRzICkgKTtcblx0fSxcblxuXHRmaXJzdDogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHRoaXMuZXEoIDAgKTtcblx0fSxcblxuXHRsYXN0OiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy5lcSggLTEgKTtcblx0fSxcblxuXHRldmVuOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy5wdXNoU3RhY2soIGpRdWVyeS5ncmVwKCB0aGlzLCBmdW5jdGlvbiggX2VsZW0sIGkgKSB7XG5cdFx0XHRyZXR1cm4gKCBpICsgMSApICUgMjtcblx0XHR9ICkgKTtcblx0fSxcblxuXHRvZGQ6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayggalF1ZXJ5LmdyZXAoIHRoaXMsIGZ1bmN0aW9uKCBfZWxlbSwgaSApIHtcblx0XHRcdHJldHVybiBpICUgMjtcblx0XHR9ICkgKTtcblx0fSxcblxuXHRlcTogZnVuY3Rpb24oIGkgKSB7XG5cdFx0dmFyIGxlbiA9IHRoaXMubGVuZ3RoLFxuXHRcdFx0aiA9ICtpICsgKCBpIDwgMCA/IGxlbiA6IDAgKTtcblx0XHRyZXR1cm4gdGhpcy5wdXNoU3RhY2soIGogPj0gMCAmJiBqIDwgbGVuID8gWyB0aGlzWyBqIF0gXSA6IFtdICk7XG5cdH0sXG5cblx0ZW5kOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy5wcmV2T2JqZWN0IHx8IHRoaXMuY29uc3RydWN0b3IoKTtcblx0fSxcblxuXHQvLyBGb3IgaW50ZXJuYWwgdXNlIG9ubHkuXG5cdC8vIEJlaGF2ZXMgbGlrZSBhbiBBcnJheSdzIG1ldGhvZCwgbm90IGxpa2UgYSBqUXVlcnkgbWV0aG9kLlxuXHRwdXNoOiBwdXNoLFxuXHRzb3J0OiBhcnIuc29ydCxcblx0c3BsaWNlOiBhcnIuc3BsaWNlXG59O1xuXG5qUXVlcnkuZXh0ZW5kID0galF1ZXJ5LmZuLmV4dGVuZCA9IGZ1bmN0aW9uKCkge1xuXHR2YXIgb3B0aW9ucywgbmFtZSwgc3JjLCBjb3B5LCBjb3B5SXNBcnJheSwgY2xvbmUsXG5cdFx0dGFyZ2V0ID0gYXJndW1lbnRzWyAwIF0gfHwge30sXG5cdFx0aSA9IDEsXG5cdFx0bGVuZ3RoID0gYXJndW1lbnRzLmxlbmd0aCxcblx0XHRkZWVwID0gZmFsc2U7XG5cblx0Ly8gSGFuZGxlIGEgZGVlcCBjb3B5IHNpdHVhdGlvblxuXHRpZiAoIHR5cGVvZiB0YXJnZXQgPT09IFwiYm9vbGVhblwiICkge1xuXHRcdGRlZXAgPSB0YXJnZXQ7XG5cblx0XHQvLyBTa2lwIHRoZSBib29sZWFuIGFuZCB0aGUgdGFyZ2V0XG5cdFx0dGFyZ2V0ID0gYXJndW1lbnRzWyBpIF0gfHwge307XG5cdFx0aSsrO1xuXHR9XG5cblx0Ly8gSGFuZGxlIGNhc2Ugd2hlbiB0YXJnZXQgaXMgYSBzdHJpbmcgb3Igc29tZXRoaW5nIChwb3NzaWJsZSBpbiBkZWVwIGNvcHkpXG5cdGlmICggdHlwZW9mIHRhcmdldCAhPT0gXCJvYmplY3RcIiAmJiAhaXNGdW5jdGlvbiggdGFyZ2V0ICkgKSB7XG5cdFx0dGFyZ2V0ID0ge307XG5cdH1cblxuXHQvLyBFeHRlbmQgalF1ZXJ5IGl0c2VsZiBpZiBvbmx5IG9uZSBhcmd1bWVudCBpcyBwYXNzZWRcblx0aWYgKCBpID09PSBsZW5ndGggKSB7XG5cdFx0dGFyZ2V0ID0gdGhpcztcblx0XHRpLS07XG5cdH1cblxuXHRmb3IgKCA7IGkgPCBsZW5ndGg7IGkrKyApIHtcblxuXHRcdC8vIE9ubHkgZGVhbCB3aXRoIG5vbi1udWxsL3VuZGVmaW5lZCB2YWx1ZXNcblx0XHRpZiAoICggb3B0aW9ucyA9IGFyZ3VtZW50c1sgaSBdICkgIT0gbnVsbCApIHtcblxuXHRcdFx0Ly8gRXh0ZW5kIHRoZSBiYXNlIG9iamVjdFxuXHRcdFx0Zm9yICggbmFtZSBpbiBvcHRpb25zICkge1xuXHRcdFx0XHRjb3B5ID0gb3B0aW9uc1sgbmFtZSBdO1xuXG5cdFx0XHRcdC8vIFByZXZlbnQgT2JqZWN0LnByb3RvdHlwZSBwb2xsdXRpb25cblx0XHRcdFx0Ly8gUHJldmVudCBuZXZlci1lbmRpbmcgbG9vcFxuXHRcdFx0XHRpZiAoIG5hbWUgPT09IFwiX19wcm90b19fXCIgfHwgdGFyZ2V0ID09PSBjb3B5ICkge1xuXHRcdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gUmVjdXJzZSBpZiB3ZSdyZSBtZXJnaW5nIHBsYWluIG9iamVjdHMgb3IgYXJyYXlzXG5cdFx0XHRcdGlmICggZGVlcCAmJiBjb3B5ICYmICggalF1ZXJ5LmlzUGxhaW5PYmplY3QoIGNvcHkgKSB8fFxuXHRcdFx0XHRcdCggY29weUlzQXJyYXkgPSBBcnJheS5pc0FycmF5KCBjb3B5ICkgKSApICkge1xuXHRcdFx0XHRcdHNyYyA9IHRhcmdldFsgbmFtZSBdO1xuXG5cdFx0XHRcdFx0Ly8gRW5zdXJlIHByb3BlciB0eXBlIGZvciB0aGUgc291cmNlIHZhbHVlXG5cdFx0XHRcdFx0aWYgKCBjb3B5SXNBcnJheSAmJiAhQXJyYXkuaXNBcnJheSggc3JjICkgKSB7XG5cdFx0XHRcdFx0XHRjbG9uZSA9IFtdO1xuXHRcdFx0XHRcdH0gZWxzZSBpZiAoICFjb3B5SXNBcnJheSAmJiAhalF1ZXJ5LmlzUGxhaW5PYmplY3QoIHNyYyApICkge1xuXHRcdFx0XHRcdFx0Y2xvbmUgPSB7fTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0Y2xvbmUgPSBzcmM7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGNvcHlJc0FycmF5ID0gZmFsc2U7XG5cblx0XHRcdFx0XHQvLyBOZXZlciBtb3ZlIG9yaWdpbmFsIG9iamVjdHMsIGNsb25lIHRoZW1cblx0XHRcdFx0XHR0YXJnZXRbIG5hbWUgXSA9IGpRdWVyeS5leHRlbmQoIGRlZXAsIGNsb25lLCBjb3B5ICk7XG5cblx0XHRcdFx0Ly8gRG9uJ3QgYnJpbmcgaW4gdW5kZWZpbmVkIHZhbHVlc1xuXHRcdFx0XHR9IGVsc2UgaWYgKCBjb3B5ICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdFx0dGFyZ2V0WyBuYW1lIF0gPSBjb3B5O1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0Ly8gUmV0dXJuIHRoZSBtb2RpZmllZCBvYmplY3Rcblx0cmV0dXJuIHRhcmdldDtcbn07XG5cbmpRdWVyeS5leHRlbmQoIHtcblxuXHQvLyBVbmlxdWUgZm9yIGVhY2ggY29weSBvZiBqUXVlcnkgb24gdGhlIHBhZ2Vcblx0ZXhwYW5kbzogXCJqUXVlcnlcIiArICggdmVyc2lvbiArIE1hdGgucmFuZG9tKCkgKS5yZXBsYWNlKCAvXFxEL2csIFwiXCIgKSxcblxuXHQvLyBBc3N1bWUgalF1ZXJ5IGlzIHJlYWR5IHdpdGhvdXQgdGhlIHJlYWR5IG1vZHVsZVxuXHRpc1JlYWR5OiB0cnVlLFxuXG5cdGVycm9yOiBmdW5jdGlvbiggbXNnICkge1xuXHRcdHRocm93IG5ldyBFcnJvciggbXNnICk7XG5cdH0sXG5cblx0bm9vcDogZnVuY3Rpb24oKSB7fSxcblxuXHRpc1BsYWluT2JqZWN0OiBmdW5jdGlvbiggb2JqICkge1xuXHRcdHZhciBwcm90bywgQ3RvcjtcblxuXHRcdC8vIERldGVjdCBvYnZpb3VzIG5lZ2F0aXZlc1xuXHRcdC8vIFVzZSB0b1N0cmluZyBpbnN0ZWFkIG9mIGpRdWVyeS50eXBlIHRvIGNhdGNoIGhvc3Qgb2JqZWN0c1xuXHRcdGlmICggIW9iaiB8fCB0b1N0cmluZy5jYWxsKCBvYmogKSAhPT0gXCJbb2JqZWN0IE9iamVjdF1cIiApIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cblx0XHRwcm90byA9IGdldFByb3RvKCBvYmogKTtcblxuXHRcdC8vIE9iamVjdHMgd2l0aCBubyBwcm90b3R5cGUgKGUuZy4sIGBPYmplY3QuY3JlYXRlKCBudWxsIClgKSBhcmUgcGxhaW5cblx0XHRpZiAoICFwcm90byApIHtcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH1cblxuXHRcdC8vIE9iamVjdHMgd2l0aCBwcm90b3R5cGUgYXJlIHBsYWluIGlmZiB0aGV5IHdlcmUgY29uc3RydWN0ZWQgYnkgYSBnbG9iYWwgT2JqZWN0IGZ1bmN0aW9uXG5cdFx0Q3RvciA9IGhhc093bi5jYWxsKCBwcm90bywgXCJjb25zdHJ1Y3RvclwiICkgJiYgcHJvdG8uY29uc3RydWN0b3I7XG5cdFx0cmV0dXJuIHR5cGVvZiBDdG9yID09PSBcImZ1bmN0aW9uXCIgJiYgZm5Ub1N0cmluZy5jYWxsKCBDdG9yICkgPT09IE9iamVjdEZ1bmN0aW9uU3RyaW5nO1xuXHR9LFxuXG5cdGlzRW1wdHlPYmplY3Q6IGZ1bmN0aW9uKCBvYmogKSB7XG5cdFx0dmFyIG5hbWU7XG5cblx0XHRmb3IgKCBuYW1lIGluIG9iaiApIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0cmV0dXJuIHRydWU7XG5cdH0sXG5cblx0Ly8gRXZhbHVhdGVzIGEgc2NyaXB0IGluIGEgcHJvdmlkZWQgY29udGV4dDsgZmFsbHMgYmFjayB0byB0aGUgZ2xvYmFsIG9uZVxuXHQvLyBpZiBub3Qgc3BlY2lmaWVkLlxuXHRnbG9iYWxFdmFsOiBmdW5jdGlvbiggY29kZSwgb3B0aW9ucywgZG9jICkge1xuXHRcdERPTUV2YWwoIGNvZGUsIHsgbm9uY2U6IG9wdGlvbnMgJiYgb3B0aW9ucy5ub25jZSB9LCBkb2MgKTtcblx0fSxcblxuXHRlYWNoOiBmdW5jdGlvbiggb2JqLCBjYWxsYmFjayApIHtcblx0XHR2YXIgbGVuZ3RoLCBpID0gMDtcblxuXHRcdGlmICggaXNBcnJheUxpa2UoIG9iaiApICkge1xuXHRcdFx0bGVuZ3RoID0gb2JqLmxlbmd0aDtcblx0XHRcdGZvciAoIDsgaSA8IGxlbmd0aDsgaSsrICkge1xuXHRcdFx0XHRpZiAoIGNhbGxiYWNrLmNhbGwoIG9ialsgaSBdLCBpLCBvYmpbIGkgXSApID09PSBmYWxzZSApIHtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHRmb3IgKCBpIGluIG9iaiApIHtcblx0XHRcdFx0aWYgKCBjYWxsYmFjay5jYWxsKCBvYmpbIGkgXSwgaSwgb2JqWyBpIF0gKSA9PT0gZmFsc2UgKSB7XG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gb2JqO1xuXHR9LFxuXG5cdC8vIHJlc3VsdHMgaXMgZm9yIGludGVybmFsIHVzYWdlIG9ubHlcblx0bWFrZUFycmF5OiBmdW5jdGlvbiggYXJyLCByZXN1bHRzICkge1xuXHRcdHZhciByZXQgPSByZXN1bHRzIHx8IFtdO1xuXG5cdFx0aWYgKCBhcnIgIT0gbnVsbCApIHtcblx0XHRcdGlmICggaXNBcnJheUxpa2UoIE9iamVjdCggYXJyICkgKSApIHtcblx0XHRcdFx0alF1ZXJ5Lm1lcmdlKCByZXQsXG5cdFx0XHRcdFx0dHlwZW9mIGFyciA9PT0gXCJzdHJpbmdcIiA/XG5cdFx0XHRcdFx0XHRbIGFyciBdIDogYXJyXG5cdFx0XHRcdCk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRwdXNoLmNhbGwoIHJldCwgYXJyICk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHJldDtcblx0fSxcblxuXHRpbkFycmF5OiBmdW5jdGlvbiggZWxlbSwgYXJyLCBpICkge1xuXHRcdHJldHVybiBhcnIgPT0gbnVsbCA/IC0xIDogaW5kZXhPZi5jYWxsKCBhcnIsIGVsZW0sIGkgKTtcblx0fSxcblxuXHQvLyBTdXBwb3J0OiBBbmRyb2lkIDw9NC4wIG9ubHksIFBoYW50b21KUyAxIG9ubHlcblx0Ly8gcHVzaC5hcHBseShfLCBhcnJheWxpa2UpIHRocm93cyBvbiBhbmNpZW50IFdlYktpdFxuXHRtZXJnZTogZnVuY3Rpb24oIGZpcnN0LCBzZWNvbmQgKSB7XG5cdFx0dmFyIGxlbiA9ICtzZWNvbmQubGVuZ3RoLFxuXHRcdFx0aiA9IDAsXG5cdFx0XHRpID0gZmlyc3QubGVuZ3RoO1xuXG5cdFx0Zm9yICggOyBqIDwgbGVuOyBqKysgKSB7XG5cdFx0XHRmaXJzdFsgaSsrIF0gPSBzZWNvbmRbIGogXTtcblx0XHR9XG5cblx0XHRmaXJzdC5sZW5ndGggPSBpO1xuXG5cdFx0cmV0dXJuIGZpcnN0O1xuXHR9LFxuXG5cdGdyZXA6IGZ1bmN0aW9uKCBlbGVtcywgY2FsbGJhY2ssIGludmVydCApIHtcblx0XHR2YXIgY2FsbGJhY2tJbnZlcnNlLFxuXHRcdFx0bWF0Y2hlcyA9IFtdLFxuXHRcdFx0aSA9IDAsXG5cdFx0XHRsZW5ndGggPSBlbGVtcy5sZW5ndGgsXG5cdFx0XHRjYWxsYmFja0V4cGVjdCA9ICFpbnZlcnQ7XG5cblx0XHQvLyBHbyB0aHJvdWdoIHRoZSBhcnJheSwgb25seSBzYXZpbmcgdGhlIGl0ZW1zXG5cdFx0Ly8gdGhhdCBwYXNzIHRoZSB2YWxpZGF0b3IgZnVuY3Rpb25cblx0XHRmb3IgKCA7IGkgPCBsZW5ndGg7IGkrKyApIHtcblx0XHRcdGNhbGxiYWNrSW52ZXJzZSA9ICFjYWxsYmFjayggZWxlbXNbIGkgXSwgaSApO1xuXHRcdFx0aWYgKCBjYWxsYmFja0ludmVyc2UgIT09IGNhbGxiYWNrRXhwZWN0ICkge1xuXHRcdFx0XHRtYXRjaGVzLnB1c2goIGVsZW1zWyBpIF0gKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gbWF0Y2hlcztcblx0fSxcblxuXHQvLyBhcmcgaXMgZm9yIGludGVybmFsIHVzYWdlIG9ubHlcblx0bWFwOiBmdW5jdGlvbiggZWxlbXMsIGNhbGxiYWNrLCBhcmcgKSB7XG5cdFx0dmFyIGxlbmd0aCwgdmFsdWUsXG5cdFx0XHRpID0gMCxcblx0XHRcdHJldCA9IFtdO1xuXG5cdFx0Ly8gR28gdGhyb3VnaCB0aGUgYXJyYXksIHRyYW5zbGF0aW5nIGVhY2ggb2YgdGhlIGl0ZW1zIHRvIHRoZWlyIG5ldyB2YWx1ZXNcblx0XHRpZiAoIGlzQXJyYXlMaWtlKCBlbGVtcyApICkge1xuXHRcdFx0bGVuZ3RoID0gZWxlbXMubGVuZ3RoO1xuXHRcdFx0Zm9yICggOyBpIDwgbGVuZ3RoOyBpKysgKSB7XG5cdFx0XHRcdHZhbHVlID0gY2FsbGJhY2soIGVsZW1zWyBpIF0sIGksIGFyZyApO1xuXG5cdFx0XHRcdGlmICggdmFsdWUgIT0gbnVsbCApIHtcblx0XHRcdFx0XHRyZXQucHVzaCggdmFsdWUgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0Ly8gR28gdGhyb3VnaCBldmVyeSBrZXkgb24gdGhlIG9iamVjdCxcblx0XHR9IGVsc2Uge1xuXHRcdFx0Zm9yICggaSBpbiBlbGVtcyApIHtcblx0XHRcdFx0dmFsdWUgPSBjYWxsYmFjayggZWxlbXNbIGkgXSwgaSwgYXJnICk7XG5cblx0XHRcdFx0aWYgKCB2YWx1ZSAhPSBudWxsICkge1xuXHRcdFx0XHRcdHJldC5wdXNoKCB2YWx1ZSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gRmxhdHRlbiBhbnkgbmVzdGVkIGFycmF5c1xuXHRcdHJldHVybiBmbGF0KCByZXQgKTtcblx0fSxcblxuXHQvLyBBIGdsb2JhbCBHVUlEIGNvdW50ZXIgZm9yIG9iamVjdHNcblx0Z3VpZDogMSxcblxuXHQvLyBqUXVlcnkuc3VwcG9ydCBpcyBub3QgdXNlZCBpbiBDb3JlIGJ1dCBvdGhlciBwcm9qZWN0cyBhdHRhY2ggdGhlaXJcblx0Ly8gcHJvcGVydGllcyB0byBpdCBzbyBpdCBuZWVkcyB0byBleGlzdC5cblx0c3VwcG9ydDogc3VwcG9ydFxufSApO1xuXG5pZiAoIHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiApIHtcblx0alF1ZXJ5LmZuWyBTeW1ib2wuaXRlcmF0b3IgXSA9IGFyclsgU3ltYm9sLml0ZXJhdG9yIF07XG59XG5cbi8vIFBvcHVsYXRlIHRoZSBjbGFzczJ0eXBlIG1hcFxualF1ZXJ5LmVhY2goIFwiQm9vbGVhbiBOdW1iZXIgU3RyaW5nIEZ1bmN0aW9uIEFycmF5IERhdGUgUmVnRXhwIE9iamVjdCBFcnJvciBTeW1ib2xcIi5zcGxpdCggXCIgXCIgKSxcblx0ZnVuY3Rpb24oIF9pLCBuYW1lICkge1xuXHRcdGNsYXNzMnR5cGVbIFwiW29iamVjdCBcIiArIG5hbWUgKyBcIl1cIiBdID0gbmFtZS50b0xvd2VyQ2FzZSgpO1xuXHR9ICk7XG5cbmZ1bmN0aW9uIGlzQXJyYXlMaWtlKCBvYmogKSB7XG5cblx0Ly8gU3VwcG9ydDogcmVhbCBpT1MgOC4yIG9ubHkgKG5vdCByZXByb2R1Y2libGUgaW4gc2ltdWxhdG9yKVxuXHQvLyBgaW5gIGNoZWNrIHVzZWQgdG8gcHJldmVudCBKSVQgZXJyb3IgKGdoLTIxNDUpXG5cdC8vIGhhc093biBpc24ndCB1c2VkIGhlcmUgZHVlIHRvIGZhbHNlIG5lZ2F0aXZlc1xuXHQvLyByZWdhcmRpbmcgTm9kZWxpc3QgbGVuZ3RoIGluIElFXG5cdHZhciBsZW5ndGggPSAhIW9iaiAmJiBcImxlbmd0aFwiIGluIG9iaiAmJiBvYmoubGVuZ3RoLFxuXHRcdHR5cGUgPSB0b1R5cGUoIG9iaiApO1xuXG5cdGlmICggaXNGdW5jdGlvbiggb2JqICkgfHwgaXNXaW5kb3coIG9iaiApICkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG5cdHJldHVybiB0eXBlID09PSBcImFycmF5XCIgfHwgbGVuZ3RoID09PSAwIHx8XG5cdFx0dHlwZW9mIGxlbmd0aCA9PT0gXCJudW1iZXJcIiAmJiBsZW5ndGggPiAwICYmICggbGVuZ3RoIC0gMSApIGluIG9iajtcbn1cbnZhciBTaXp6bGUgPVxuLyohXG4gKiBTaXp6bGUgQ1NTIFNlbGVjdG9yIEVuZ2luZSB2Mi4zLjZcbiAqIGh0dHBzOi8vc2l6emxlanMuY29tL1xuICpcbiAqIENvcHlyaWdodCBKUyBGb3VuZGF0aW9uIGFuZCBvdGhlciBjb250cmlidXRvcnNcbiAqIFJlbGVhc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZVxuICogaHR0cHM6Ly9qcy5mb3VuZGF0aW9uL1xuICpcbiAqIERhdGU6IDIwMjEtMDItMTZcbiAqL1xuKCBmdW5jdGlvbiggd2luZG93ICkge1xudmFyIGksXG5cdHN1cHBvcnQsXG5cdEV4cHIsXG5cdGdldFRleHQsXG5cdGlzWE1MLFxuXHR0b2tlbml6ZSxcblx0Y29tcGlsZSxcblx0c2VsZWN0LFxuXHRvdXRlcm1vc3RDb250ZXh0LFxuXHRzb3J0SW5wdXQsXG5cdGhhc0R1cGxpY2F0ZSxcblxuXHQvLyBMb2NhbCBkb2N1bWVudCB2YXJzXG5cdHNldERvY3VtZW50LFxuXHRkb2N1bWVudCxcblx0ZG9jRWxlbSxcblx0ZG9jdW1lbnRJc0hUTUwsXG5cdHJidWdneVFTQSxcblx0cmJ1Z2d5TWF0Y2hlcyxcblx0bWF0Y2hlcyxcblx0Y29udGFpbnMsXG5cblx0Ly8gSW5zdGFuY2Utc3BlY2lmaWMgZGF0YVxuXHRleHBhbmRvID0gXCJzaXp6bGVcIiArIDEgKiBuZXcgRGF0ZSgpLFxuXHRwcmVmZXJyZWREb2MgPSB3aW5kb3cuZG9jdW1lbnQsXG5cdGRpcnJ1bnMgPSAwLFxuXHRkb25lID0gMCxcblx0Y2xhc3NDYWNoZSA9IGNyZWF0ZUNhY2hlKCksXG5cdHRva2VuQ2FjaGUgPSBjcmVhdGVDYWNoZSgpLFxuXHRjb21waWxlckNhY2hlID0gY3JlYXRlQ2FjaGUoKSxcblx0bm9ubmF0aXZlU2VsZWN0b3JDYWNoZSA9IGNyZWF0ZUNhY2hlKCksXG5cdHNvcnRPcmRlciA9IGZ1bmN0aW9uKCBhLCBiICkge1xuXHRcdGlmICggYSA9PT0gYiApIHtcblx0XHRcdGhhc0R1cGxpY2F0ZSA9IHRydWU7XG5cdFx0fVxuXHRcdHJldHVybiAwO1xuXHR9LFxuXG5cdC8vIEluc3RhbmNlIG1ldGhvZHNcblx0aGFzT3duID0gKCB7fSApLmhhc093blByb3BlcnR5LFxuXHRhcnIgPSBbXSxcblx0cG9wID0gYXJyLnBvcCxcblx0cHVzaE5hdGl2ZSA9IGFyci5wdXNoLFxuXHRwdXNoID0gYXJyLnB1c2gsXG5cdHNsaWNlID0gYXJyLnNsaWNlLFxuXG5cdC8vIFVzZSBhIHN0cmlwcGVkLWRvd24gaW5kZXhPZiBhcyBpdCdzIGZhc3RlciB0aGFuIG5hdGl2ZVxuXHQvLyBodHRwczovL2pzcGVyZi5jb20vdGhvci1pbmRleG9mLXZzLWZvci81XG5cdGluZGV4T2YgPSBmdW5jdGlvbiggbGlzdCwgZWxlbSApIHtcblx0XHR2YXIgaSA9IDAsXG5cdFx0XHRsZW4gPSBsaXN0Lmxlbmd0aDtcblx0XHRmb3IgKCA7IGkgPCBsZW47IGkrKyApIHtcblx0XHRcdGlmICggbGlzdFsgaSBdID09PSBlbGVtICkge1xuXHRcdFx0XHRyZXR1cm4gaTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIC0xO1xuXHR9LFxuXG5cdGJvb2xlYW5zID0gXCJjaGVja2VkfHNlbGVjdGVkfGFzeW5jfGF1dG9mb2N1c3xhdXRvcGxheXxjb250cm9sc3xkZWZlcnxkaXNhYmxlZHxoaWRkZW58XCIgK1xuXHRcdFwiaXNtYXB8bG9vcHxtdWx0aXBsZXxvcGVufHJlYWRvbmx5fHJlcXVpcmVkfHNjb3BlZFwiLFxuXG5cdC8vIFJlZ3VsYXIgZXhwcmVzc2lvbnNcblxuXHQvLyBodHRwOi8vd3d3LnczLm9yZy9UUi9jc3MzLXNlbGVjdG9ycy8jd2hpdGVzcGFjZVxuXHR3aGl0ZXNwYWNlID0gXCJbXFxcXHgyMFxcXFx0XFxcXHJcXFxcblxcXFxmXVwiLFxuXG5cdC8vIGh0dHBzOi8vd3d3LnczLm9yZy9UUi9jc3Mtc3ludGF4LTMvI2lkZW50LXRva2VuLWRpYWdyYW1cblx0aWRlbnRpZmllciA9IFwiKD86XFxcXFxcXFxbXFxcXGRhLWZBLUZdezEsNn1cIiArIHdoaXRlc3BhY2UgK1xuXHRcdFwiP3xcXFxcXFxcXFteXFxcXHJcXFxcblxcXFxmXXxbXFxcXHctXXxbXlxcMC1cXFxceDdmXSkrXCIsXG5cblx0Ly8gQXR0cmlidXRlIHNlbGVjdG9yczogaHR0cDovL3d3dy53My5vcmcvVFIvc2VsZWN0b3JzLyNhdHRyaWJ1dGUtc2VsZWN0b3JzXG5cdGF0dHJpYnV0ZXMgPSBcIlxcXFxbXCIgKyB3aGl0ZXNwYWNlICsgXCIqKFwiICsgaWRlbnRpZmllciArIFwiKSg/OlwiICsgd2hpdGVzcGFjZSArXG5cblx0XHQvLyBPcGVyYXRvciAoY2FwdHVyZSAyKVxuXHRcdFwiKihbKl4kfCF+XT89KVwiICsgd2hpdGVzcGFjZSArXG5cblx0XHQvLyBcIkF0dHJpYnV0ZSB2YWx1ZXMgbXVzdCBiZSBDU1MgaWRlbnRpZmllcnMgW2NhcHR1cmUgNV1cblx0XHQvLyBvciBzdHJpbmdzIFtjYXB0dXJlIDMgb3IgY2FwdHVyZSA0XVwiXG5cdFx0XCIqKD86JygoPzpcXFxcXFxcXC58W15cXFxcXFxcXCddKSopJ3xcXFwiKCg/OlxcXFxcXFxcLnxbXlxcXFxcXFxcXFxcIl0pKilcXFwifChcIiArIGlkZW50aWZpZXIgKyBcIikpfClcIiArXG5cdFx0d2hpdGVzcGFjZSArIFwiKlxcXFxdXCIsXG5cblx0cHNldWRvcyA9IFwiOihcIiArIGlkZW50aWZpZXIgKyBcIikoPzpcXFxcKChcIiArXG5cblx0XHQvLyBUbyByZWR1Y2UgdGhlIG51bWJlciBvZiBzZWxlY3RvcnMgbmVlZGluZyB0b2tlbml6ZSBpbiB0aGUgcHJlRmlsdGVyLCBwcmVmZXIgYXJndW1lbnRzOlxuXHRcdC8vIDEuIHF1b3RlZCAoY2FwdHVyZSAzOyBjYXB0dXJlIDQgb3IgY2FwdHVyZSA1KVxuXHRcdFwiKCcoKD86XFxcXFxcXFwufFteXFxcXFxcXFwnXSkqKSd8XFxcIigoPzpcXFxcXFxcXC58W15cXFxcXFxcXFxcXCJdKSopXFxcIil8XCIgK1xuXG5cdFx0Ly8gMi4gc2ltcGxlIChjYXB0dXJlIDYpXG5cdFx0XCIoKD86XFxcXFxcXFwufFteXFxcXFxcXFwoKVtcXFxcXV18XCIgKyBhdHRyaWJ1dGVzICsgXCIpKil8XCIgK1xuXG5cdFx0Ly8gMy4gYW55dGhpbmcgZWxzZSAoY2FwdHVyZSAyKVxuXHRcdFwiLipcIiArXG5cdFx0XCIpXFxcXCl8KVwiLFxuXG5cdC8vIExlYWRpbmcgYW5kIG5vbi1lc2NhcGVkIHRyYWlsaW5nIHdoaXRlc3BhY2UsIGNhcHR1cmluZyBzb21lIG5vbi13aGl0ZXNwYWNlIGNoYXJhY3RlcnMgcHJlY2VkaW5nIHRoZSBsYXR0ZXJcblx0cndoaXRlc3BhY2UgPSBuZXcgUmVnRXhwKCB3aGl0ZXNwYWNlICsgXCIrXCIsIFwiZ1wiICksXG5cdHJ0cmltID0gbmV3IFJlZ0V4cCggXCJeXCIgKyB3aGl0ZXNwYWNlICsgXCIrfCgoPzpefFteXFxcXFxcXFxdKSg/OlxcXFxcXFxcLikqKVwiICtcblx0XHR3aGl0ZXNwYWNlICsgXCIrJFwiLCBcImdcIiApLFxuXG5cdHJjb21tYSA9IG5ldyBSZWdFeHAoIFwiXlwiICsgd2hpdGVzcGFjZSArIFwiKixcIiArIHdoaXRlc3BhY2UgKyBcIipcIiApLFxuXHRyY29tYmluYXRvcnMgPSBuZXcgUmVnRXhwKCBcIl5cIiArIHdoaXRlc3BhY2UgKyBcIiooWz4rfl18XCIgKyB3aGl0ZXNwYWNlICsgXCIpXCIgKyB3aGl0ZXNwYWNlICtcblx0XHRcIipcIiApLFxuXHRyZGVzY2VuZCA9IG5ldyBSZWdFeHAoIHdoaXRlc3BhY2UgKyBcInw+XCIgKSxcblxuXHRycHNldWRvID0gbmV3IFJlZ0V4cCggcHNldWRvcyApLFxuXHRyaWRlbnRpZmllciA9IG5ldyBSZWdFeHAoIFwiXlwiICsgaWRlbnRpZmllciArIFwiJFwiICksXG5cblx0bWF0Y2hFeHByID0ge1xuXHRcdFwiSURcIjogbmV3IFJlZ0V4cCggXCJeIyhcIiArIGlkZW50aWZpZXIgKyBcIilcIiApLFxuXHRcdFwiQ0xBU1NcIjogbmV3IFJlZ0V4cCggXCJeXFxcXC4oXCIgKyBpZGVudGlmaWVyICsgXCIpXCIgKSxcblx0XHRcIlRBR1wiOiBuZXcgUmVnRXhwKCBcIl4oXCIgKyBpZGVudGlmaWVyICsgXCJ8WypdKVwiICksXG5cdFx0XCJBVFRSXCI6IG5ldyBSZWdFeHAoIFwiXlwiICsgYXR0cmlidXRlcyApLFxuXHRcdFwiUFNFVURPXCI6IG5ldyBSZWdFeHAoIFwiXlwiICsgcHNldWRvcyApLFxuXHRcdFwiQ0hJTERcIjogbmV3IFJlZ0V4cCggXCJeOihvbmx5fGZpcnN0fGxhc3R8bnRofG50aC1sYXN0KS0oY2hpbGR8b2YtdHlwZSkoPzpcXFxcKFwiICtcblx0XHRcdHdoaXRlc3BhY2UgKyBcIiooZXZlbnxvZGR8KChbKy1dfCkoXFxcXGQqKW58KVwiICsgd2hpdGVzcGFjZSArIFwiKig/OihbKy1dfClcIiArXG5cdFx0XHR3aGl0ZXNwYWNlICsgXCIqKFxcXFxkKyl8KSlcIiArIHdoaXRlc3BhY2UgKyBcIipcXFxcKXwpXCIsIFwiaVwiICksXG5cdFx0XCJib29sXCI6IG5ldyBSZWdFeHAoIFwiXig/OlwiICsgYm9vbGVhbnMgKyBcIikkXCIsIFwiaVwiICksXG5cblx0XHQvLyBGb3IgdXNlIGluIGxpYnJhcmllcyBpbXBsZW1lbnRpbmcgLmlzKClcblx0XHQvLyBXZSB1c2UgdGhpcyBmb3IgUE9TIG1hdGNoaW5nIGluIGBzZWxlY3RgXG5cdFx0XCJuZWVkc0NvbnRleHRcIjogbmV3IFJlZ0V4cCggXCJeXCIgKyB3aGl0ZXNwYWNlICtcblx0XHRcdFwiKls+K35dfDooZXZlbnxvZGR8ZXF8Z3R8bHR8bnRofGZpcnN0fGxhc3QpKD86XFxcXChcIiArIHdoaXRlc3BhY2UgK1xuXHRcdFx0XCIqKCg/Oi1cXFxcZCk/XFxcXGQqKVwiICsgd2hpdGVzcGFjZSArIFwiKlxcXFwpfCkoPz1bXi1dfCQpXCIsIFwiaVwiIClcblx0fSxcblxuXHRyaHRtbCA9IC9IVE1MJC9pLFxuXHRyaW5wdXRzID0gL14oPzppbnB1dHxzZWxlY3R8dGV4dGFyZWF8YnV0dG9uKSQvaSxcblx0cmhlYWRlciA9IC9eaFxcZCQvaSxcblxuXHRybmF0aXZlID0gL15bXntdK1xce1xccypcXFtuYXRpdmUgXFx3LyxcblxuXHQvLyBFYXNpbHktcGFyc2VhYmxlL3JldHJpZXZhYmxlIElEIG9yIFRBRyBvciBDTEFTUyBzZWxlY3RvcnNcblx0cnF1aWNrRXhwciA9IC9eKD86IyhbXFx3LV0rKXwoXFx3Kyl8XFwuKFtcXHctXSspKSQvLFxuXG5cdHJzaWJsaW5nID0gL1srfl0vLFxuXG5cdC8vIENTUyBlc2NhcGVzXG5cdC8vIGh0dHA6Ly93d3cudzMub3JnL1RSL0NTUzIxL3N5bmRhdGEuaHRtbCNlc2NhcGVkLWNoYXJhY3RlcnNcblx0cnVuZXNjYXBlID0gbmV3IFJlZ0V4cCggXCJcXFxcXFxcXFtcXFxcZGEtZkEtRl17MSw2fVwiICsgd2hpdGVzcGFjZSArIFwiP3xcXFxcXFxcXChbXlxcXFxyXFxcXG5cXFxcZl0pXCIsIFwiZ1wiICksXG5cdGZ1bmVzY2FwZSA9IGZ1bmN0aW9uKCBlc2NhcGUsIG5vbkhleCApIHtcblx0XHR2YXIgaGlnaCA9IFwiMHhcIiArIGVzY2FwZS5zbGljZSggMSApIC0gMHgxMDAwMDtcblxuXHRcdHJldHVybiBub25IZXggP1xuXG5cdFx0XHQvLyBTdHJpcCB0aGUgYmFja3NsYXNoIHByZWZpeCBmcm9tIGEgbm9uLWhleCBlc2NhcGUgc2VxdWVuY2Vcblx0XHRcdG5vbkhleCA6XG5cblx0XHRcdC8vIFJlcGxhY2UgYSBoZXhhZGVjaW1hbCBlc2NhcGUgc2VxdWVuY2Ugd2l0aCB0aGUgZW5jb2RlZCBVbmljb2RlIGNvZGUgcG9pbnRcblx0XHRcdC8vIFN1cHBvcnQ6IElFIDw9MTErXG5cdFx0XHQvLyBGb3IgdmFsdWVzIG91dHNpZGUgdGhlIEJhc2ljIE11bHRpbGluZ3VhbCBQbGFuZSAoQk1QKSwgbWFudWFsbHkgY29uc3RydWN0IGFcblx0XHRcdC8vIHN1cnJvZ2F0ZSBwYWlyXG5cdFx0XHRoaWdoIDwgMCA/XG5cdFx0XHRcdFN0cmluZy5mcm9tQ2hhckNvZGUoIGhpZ2ggKyAweDEwMDAwICkgOlxuXHRcdFx0XHRTdHJpbmcuZnJvbUNoYXJDb2RlKCBoaWdoID4+IDEwIHwgMHhEODAwLCBoaWdoICYgMHgzRkYgfCAweERDMDAgKTtcblx0fSxcblxuXHQvLyBDU1Mgc3RyaW5nL2lkZW50aWZpZXIgc2VyaWFsaXphdGlvblxuXHQvLyBodHRwczovL2RyYWZ0cy5jc3N3Zy5vcmcvY3Nzb20vI2NvbW1vbi1zZXJpYWxpemluZy1pZGlvbXNcblx0cmNzc2VzY2FwZSA9IC8oW1xcMC1cXHgxZlxceDdmXXxeLT9cXGQpfF4tJHxbXlxcMC1cXHgxZlxceDdmLVxcdUZGRkZcXHctXS9nLFxuXHRmY3NzZXNjYXBlID0gZnVuY3Rpb24oIGNoLCBhc0NvZGVQb2ludCApIHtcblx0XHRpZiAoIGFzQ29kZVBvaW50ICkge1xuXG5cdFx0XHQvLyBVKzAwMDAgTlVMTCBiZWNvbWVzIFUrRkZGRCBSRVBMQUNFTUVOVCBDSEFSQUNURVJcblx0XHRcdGlmICggY2ggPT09IFwiXFwwXCIgKSB7XG5cdFx0XHRcdHJldHVybiBcIlxcdUZGRkRcIjtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQ29udHJvbCBjaGFyYWN0ZXJzIGFuZCAoZGVwZW5kZW50IHVwb24gcG9zaXRpb24pIG51bWJlcnMgZ2V0IGVzY2FwZWQgYXMgY29kZSBwb2ludHNcblx0XHRcdHJldHVybiBjaC5zbGljZSggMCwgLTEgKSArIFwiXFxcXFwiICtcblx0XHRcdFx0Y2guY2hhckNvZGVBdCggY2gubGVuZ3RoIC0gMSApLnRvU3RyaW5nKCAxNiApICsgXCIgXCI7XG5cdFx0fVxuXG5cdFx0Ly8gT3RoZXIgcG90ZW50aWFsbHktc3BlY2lhbCBBU0NJSSBjaGFyYWN0ZXJzIGdldCBiYWNrc2xhc2gtZXNjYXBlZFxuXHRcdHJldHVybiBcIlxcXFxcIiArIGNoO1xuXHR9LFxuXG5cdC8vIFVzZWQgZm9yIGlmcmFtZXNcblx0Ly8gU2VlIHNldERvY3VtZW50KClcblx0Ly8gUmVtb3ZpbmcgdGhlIGZ1bmN0aW9uIHdyYXBwZXIgY2F1c2VzIGEgXCJQZXJtaXNzaW9uIERlbmllZFwiXG5cdC8vIGVycm9yIGluIElFXG5cdHVubG9hZEhhbmRsZXIgPSBmdW5jdGlvbigpIHtcblx0XHRzZXREb2N1bWVudCgpO1xuXHR9LFxuXG5cdGluRGlzYWJsZWRGaWVsZHNldCA9IGFkZENvbWJpbmF0b3IoXG5cdFx0ZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4gZWxlbS5kaXNhYmxlZCA9PT0gdHJ1ZSAmJiBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgPT09IFwiZmllbGRzZXRcIjtcblx0XHR9LFxuXHRcdHsgZGlyOiBcInBhcmVudE5vZGVcIiwgbmV4dDogXCJsZWdlbmRcIiB9XG5cdCk7XG5cbi8vIE9wdGltaXplIGZvciBwdXNoLmFwcGx5KCBfLCBOb2RlTGlzdCApXG50cnkge1xuXHRwdXNoLmFwcGx5KFxuXHRcdCggYXJyID0gc2xpY2UuY2FsbCggcHJlZmVycmVkRG9jLmNoaWxkTm9kZXMgKSApLFxuXHRcdHByZWZlcnJlZERvYy5jaGlsZE5vZGVzXG5cdCk7XG5cblx0Ly8gU3VwcG9ydDogQW5kcm9pZDw0LjBcblx0Ly8gRGV0ZWN0IHNpbGVudGx5IGZhaWxpbmcgcHVzaC5hcHBseVxuXHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLWV4cHJlc3Npb25zXG5cdGFyclsgcHJlZmVycmVkRG9jLmNoaWxkTm9kZXMubGVuZ3RoIF0ubm9kZVR5cGU7XG59IGNhdGNoICggZSApIHtcblx0cHVzaCA9IHsgYXBwbHk6IGFyci5sZW5ndGggP1xuXG5cdFx0Ly8gTGV2ZXJhZ2Ugc2xpY2UgaWYgcG9zc2libGVcblx0XHRmdW5jdGlvbiggdGFyZ2V0LCBlbHMgKSB7XG5cdFx0XHRwdXNoTmF0aXZlLmFwcGx5KCB0YXJnZXQsIHNsaWNlLmNhbGwoIGVscyApICk7XG5cdFx0fSA6XG5cblx0XHQvLyBTdXBwb3J0OiBJRTw5XG5cdFx0Ly8gT3RoZXJ3aXNlIGFwcGVuZCBkaXJlY3RseVxuXHRcdGZ1bmN0aW9uKCB0YXJnZXQsIGVscyApIHtcblx0XHRcdHZhciBqID0gdGFyZ2V0Lmxlbmd0aCxcblx0XHRcdFx0aSA9IDA7XG5cblx0XHRcdC8vIENhbid0IHRydXN0IE5vZGVMaXN0Lmxlbmd0aFxuXHRcdFx0d2hpbGUgKCAoIHRhcmdldFsgaisrIF0gPSBlbHNbIGkrKyBdICkgKSB7fVxuXHRcdFx0dGFyZ2V0Lmxlbmd0aCA9IGogLSAxO1xuXHRcdH1cblx0fTtcbn1cblxuZnVuY3Rpb24gU2l6emxlKCBzZWxlY3RvciwgY29udGV4dCwgcmVzdWx0cywgc2VlZCApIHtcblx0dmFyIG0sIGksIGVsZW0sIG5pZCwgbWF0Y2gsIGdyb3VwcywgbmV3U2VsZWN0b3IsXG5cdFx0bmV3Q29udGV4dCA9IGNvbnRleHQgJiYgY29udGV4dC5vd25lckRvY3VtZW50LFxuXG5cdFx0Ly8gbm9kZVR5cGUgZGVmYXVsdHMgdG8gOSwgc2luY2UgY29udGV4dCBkZWZhdWx0cyB0byBkb2N1bWVudFxuXHRcdG5vZGVUeXBlID0gY29udGV4dCA/IGNvbnRleHQubm9kZVR5cGUgOiA5O1xuXG5cdHJlc3VsdHMgPSByZXN1bHRzIHx8IFtdO1xuXG5cdC8vIFJldHVybiBlYXJseSBmcm9tIGNhbGxzIHdpdGggaW52YWxpZCBzZWxlY3RvciBvciBjb250ZXh0XG5cdGlmICggdHlwZW9mIHNlbGVjdG9yICE9PSBcInN0cmluZ1wiIHx8ICFzZWxlY3RvciB8fFxuXHRcdG5vZGVUeXBlICE9PSAxICYmIG5vZGVUeXBlICE9PSA5ICYmIG5vZGVUeXBlICE9PSAxMSApIHtcblxuXHRcdHJldHVybiByZXN1bHRzO1xuXHR9XG5cblx0Ly8gVHJ5IHRvIHNob3J0Y3V0IGZpbmQgb3BlcmF0aW9ucyAoYXMgb3Bwb3NlZCB0byBmaWx0ZXJzKSBpbiBIVE1MIGRvY3VtZW50c1xuXHRpZiAoICFzZWVkICkge1xuXHRcdHNldERvY3VtZW50KCBjb250ZXh0ICk7XG5cdFx0Y29udGV4dCA9IGNvbnRleHQgfHwgZG9jdW1lbnQ7XG5cblx0XHRpZiAoIGRvY3VtZW50SXNIVE1MICkge1xuXG5cdFx0XHQvLyBJZiB0aGUgc2VsZWN0b3IgaXMgc3VmZmljaWVudGx5IHNpbXBsZSwgdHJ5IHVzaW5nIGEgXCJnZXQqQnkqXCIgRE9NIG1ldGhvZFxuXHRcdFx0Ly8gKGV4Y2VwdGluZyBEb2N1bWVudEZyYWdtZW50IGNvbnRleHQsIHdoZXJlIHRoZSBtZXRob2RzIGRvbid0IGV4aXN0KVxuXHRcdFx0aWYgKCBub2RlVHlwZSAhPT0gMTEgJiYgKCBtYXRjaCA9IHJxdWlja0V4cHIuZXhlYyggc2VsZWN0b3IgKSApICkge1xuXG5cdFx0XHRcdC8vIElEIHNlbGVjdG9yXG5cdFx0XHRcdGlmICggKCBtID0gbWF0Y2hbIDEgXSApICkge1xuXG5cdFx0XHRcdFx0Ly8gRG9jdW1lbnQgY29udGV4dFxuXHRcdFx0XHRcdGlmICggbm9kZVR5cGUgPT09IDkgKSB7XG5cdFx0XHRcdFx0XHRpZiAoICggZWxlbSA9IGNvbnRleHQuZ2V0RWxlbWVudEJ5SWQoIG0gKSApICkge1xuXG5cdFx0XHRcdFx0XHRcdC8vIFN1cHBvcnQ6IElFLCBPcGVyYSwgV2Via2l0XG5cdFx0XHRcdFx0XHRcdC8vIFRPRE86IGlkZW50aWZ5IHZlcnNpb25zXG5cdFx0XHRcdFx0XHRcdC8vIGdldEVsZW1lbnRCeUlkIGNhbiBtYXRjaCBlbGVtZW50cyBieSBuYW1lIGluc3RlYWQgb2YgSURcblx0XHRcdFx0XHRcdFx0aWYgKCBlbGVtLmlkID09PSBtICkge1xuXHRcdFx0XHRcdFx0XHRcdHJlc3VsdHMucHVzaCggZWxlbSApO1xuXHRcdFx0XHRcdFx0XHRcdHJldHVybiByZXN1bHRzO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gcmVzdWx0cztcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIEVsZW1lbnQgY29udGV4dFxuXHRcdFx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0XHRcdC8vIFN1cHBvcnQ6IElFLCBPcGVyYSwgV2Via2l0XG5cdFx0XHRcdFx0XHQvLyBUT0RPOiBpZGVudGlmeSB2ZXJzaW9uc1xuXHRcdFx0XHRcdFx0Ly8gZ2V0RWxlbWVudEJ5SWQgY2FuIG1hdGNoIGVsZW1lbnRzIGJ5IG5hbWUgaW5zdGVhZCBvZiBJRFxuXHRcdFx0XHRcdFx0aWYgKCBuZXdDb250ZXh0ICYmICggZWxlbSA9IG5ld0NvbnRleHQuZ2V0RWxlbWVudEJ5SWQoIG0gKSApICYmXG5cdFx0XHRcdFx0XHRcdGNvbnRhaW5zKCBjb250ZXh0LCBlbGVtICkgJiZcblx0XHRcdFx0XHRcdFx0ZWxlbS5pZCA9PT0gbSApIHtcblxuXHRcdFx0XHRcdFx0XHRyZXN1bHRzLnB1c2goIGVsZW0gKTtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIHJlc3VsdHM7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIFR5cGUgc2VsZWN0b3Jcblx0XHRcdFx0fSBlbHNlIGlmICggbWF0Y2hbIDIgXSApIHtcblx0XHRcdFx0XHRwdXNoLmFwcGx5KCByZXN1bHRzLCBjb250ZXh0LmdldEVsZW1lbnRzQnlUYWdOYW1lKCBzZWxlY3RvciApICk7XG5cdFx0XHRcdFx0cmV0dXJuIHJlc3VsdHM7XG5cblx0XHRcdFx0Ly8gQ2xhc3Mgc2VsZWN0b3Jcblx0XHRcdFx0fSBlbHNlIGlmICggKCBtID0gbWF0Y2hbIDMgXSApICYmIHN1cHBvcnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSAmJlxuXHRcdFx0XHRcdGNvbnRleHQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSApIHtcblxuXHRcdFx0XHRcdHB1c2guYXBwbHkoIHJlc3VsdHMsIGNvbnRleHQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSggbSApICk7XG5cdFx0XHRcdFx0cmV0dXJuIHJlc3VsdHM7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Ly8gVGFrZSBhZHZhbnRhZ2Ugb2YgcXVlcnlTZWxlY3RvckFsbFxuXHRcdFx0aWYgKCBzdXBwb3J0LnFzYSAmJlxuXHRcdFx0XHQhbm9ubmF0aXZlU2VsZWN0b3JDYWNoZVsgc2VsZWN0b3IgKyBcIiBcIiBdICYmXG5cdFx0XHRcdCggIXJidWdneVFTQSB8fCAhcmJ1Z2d5UVNBLnRlc3QoIHNlbGVjdG9yICkgKSAmJlxuXG5cdFx0XHRcdC8vIFN1cHBvcnQ6IElFIDggb25seVxuXHRcdFx0XHQvLyBFeGNsdWRlIG9iamVjdCBlbGVtZW50c1xuXHRcdFx0XHQoIG5vZGVUeXBlICE9PSAxIHx8IGNvbnRleHQubm9kZU5hbWUudG9Mb3dlckNhc2UoKSAhPT0gXCJvYmplY3RcIiApICkge1xuXG5cdFx0XHRcdG5ld1NlbGVjdG9yID0gc2VsZWN0b3I7XG5cdFx0XHRcdG5ld0NvbnRleHQgPSBjb250ZXh0O1xuXG5cdFx0XHRcdC8vIHFTQSBjb25zaWRlcnMgZWxlbWVudHMgb3V0c2lkZSBhIHNjb3Bpbmcgcm9vdCB3aGVuIGV2YWx1YXRpbmcgY2hpbGQgb3Jcblx0XHRcdFx0Ly8gZGVzY2VuZGFudCBjb21iaW5hdG9ycywgd2hpY2ggaXMgbm90IHdoYXQgd2Ugd2FudC5cblx0XHRcdFx0Ly8gSW4gc3VjaCBjYXNlcywgd2Ugd29yayBhcm91bmQgdGhlIGJlaGF2aW9yIGJ5IHByZWZpeGluZyBldmVyeSBzZWxlY3RvciBpbiB0aGVcblx0XHRcdFx0Ly8gbGlzdCB3aXRoIGFuIElEIHNlbGVjdG9yIHJlZmVyZW5jaW5nIHRoZSBzY29wZSBjb250ZXh0LlxuXHRcdFx0XHQvLyBUaGUgdGVjaG5pcXVlIGhhcyB0byBiZSB1c2VkIGFzIHdlbGwgd2hlbiBhIGxlYWRpbmcgY29tYmluYXRvciBpcyB1c2VkXG5cdFx0XHRcdC8vIGFzIHN1Y2ggc2VsZWN0b3JzIGFyZSBub3QgcmVjb2duaXplZCBieSBxdWVyeVNlbGVjdG9yQWxsLlxuXHRcdFx0XHQvLyBUaGFua3MgdG8gQW5kcmV3IER1cG9udCBmb3IgdGhpcyB0ZWNobmlxdWUuXG5cdFx0XHRcdGlmICggbm9kZVR5cGUgPT09IDEgJiZcblx0XHRcdFx0XHQoIHJkZXNjZW5kLnRlc3QoIHNlbGVjdG9yICkgfHwgcmNvbWJpbmF0b3JzLnRlc3QoIHNlbGVjdG9yICkgKSApIHtcblxuXHRcdFx0XHRcdC8vIEV4cGFuZCBjb250ZXh0IGZvciBzaWJsaW5nIHNlbGVjdG9yc1xuXHRcdFx0XHRcdG5ld0NvbnRleHQgPSByc2libGluZy50ZXN0KCBzZWxlY3RvciApICYmIHRlc3RDb250ZXh0KCBjb250ZXh0LnBhcmVudE5vZGUgKSB8fFxuXHRcdFx0XHRcdFx0Y29udGV4dDtcblxuXHRcdFx0XHRcdC8vIFdlIGNhbiB1c2UgOnNjb3BlIGluc3RlYWQgb2YgdGhlIElEIGhhY2sgaWYgdGhlIGJyb3dzZXJcblx0XHRcdFx0XHQvLyBzdXBwb3J0cyBpdCAmIGlmIHdlJ3JlIG5vdCBjaGFuZ2luZyB0aGUgY29udGV4dC5cblx0XHRcdFx0XHRpZiAoIG5ld0NvbnRleHQgIT09IGNvbnRleHQgfHwgIXN1cHBvcnQuc2NvcGUgKSB7XG5cblx0XHRcdFx0XHRcdC8vIENhcHR1cmUgdGhlIGNvbnRleHQgSUQsIHNldHRpbmcgaXQgZmlyc3QgaWYgbmVjZXNzYXJ5XG5cdFx0XHRcdFx0XHRpZiAoICggbmlkID0gY29udGV4dC5nZXRBdHRyaWJ1dGUoIFwiaWRcIiApICkgKSB7XG5cdFx0XHRcdFx0XHRcdG5pZCA9IG5pZC5yZXBsYWNlKCByY3NzZXNjYXBlLCBmY3NzZXNjYXBlICk7XG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRjb250ZXh0LnNldEF0dHJpYnV0ZSggXCJpZFwiLCAoIG5pZCA9IGV4cGFuZG8gKSApO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIFByZWZpeCBldmVyeSBzZWxlY3RvciBpbiB0aGUgbGlzdFxuXHRcdFx0XHRcdGdyb3VwcyA9IHRva2VuaXplKCBzZWxlY3RvciApO1xuXHRcdFx0XHRcdGkgPSBncm91cHMubGVuZ3RoO1xuXHRcdFx0XHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0XHRcdFx0Z3JvdXBzWyBpIF0gPSAoIG5pZCA/IFwiI1wiICsgbmlkIDogXCI6c2NvcGVcIiApICsgXCIgXCIgK1xuXHRcdFx0XHRcdFx0XHR0b1NlbGVjdG9yKCBncm91cHNbIGkgXSApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRuZXdTZWxlY3RvciA9IGdyb3Vwcy5qb2luKCBcIixcIiApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0dHJ5IHtcblx0XHRcdFx0XHRwdXNoLmFwcGx5KCByZXN1bHRzLFxuXHRcdFx0XHRcdFx0bmV3Q29udGV4dC5xdWVyeVNlbGVjdG9yQWxsKCBuZXdTZWxlY3RvciApXG5cdFx0XHRcdFx0KTtcblx0XHRcdFx0XHRyZXR1cm4gcmVzdWx0cztcblx0XHRcdFx0fSBjYXRjaCAoIHFzYUVycm9yICkge1xuXHRcdFx0XHRcdG5vbm5hdGl2ZVNlbGVjdG9yQ2FjaGUoIHNlbGVjdG9yLCB0cnVlICk7XG5cdFx0XHRcdH0gZmluYWxseSB7XG5cdFx0XHRcdFx0aWYgKCBuaWQgPT09IGV4cGFuZG8gKSB7XG5cdFx0XHRcdFx0XHRjb250ZXh0LnJlbW92ZUF0dHJpYnV0ZSggXCJpZFwiICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0Ly8gQWxsIG90aGVyc1xuXHRyZXR1cm4gc2VsZWN0KCBzZWxlY3Rvci5yZXBsYWNlKCBydHJpbSwgXCIkMVwiICksIGNvbnRleHQsIHJlc3VsdHMsIHNlZWQgKTtcbn1cblxuLyoqXG4gKiBDcmVhdGUga2V5LXZhbHVlIGNhY2hlcyBvZiBsaW1pdGVkIHNpemVcbiAqIEByZXR1cm5zIHtmdW5jdGlvbihzdHJpbmcsIG9iamVjdCl9IFJldHVybnMgdGhlIE9iamVjdCBkYXRhIGFmdGVyIHN0b3JpbmcgaXQgb24gaXRzZWxmIHdpdGhcbiAqXHRwcm9wZXJ0eSBuYW1lIHRoZSAoc3BhY2Utc3VmZml4ZWQpIHN0cmluZyBhbmQgKGlmIHRoZSBjYWNoZSBpcyBsYXJnZXIgdGhhbiBFeHByLmNhY2hlTGVuZ3RoKVxuICpcdGRlbGV0aW5nIHRoZSBvbGRlc3QgZW50cnlcbiAqL1xuZnVuY3Rpb24gY3JlYXRlQ2FjaGUoKSB7XG5cdHZhciBrZXlzID0gW107XG5cblx0ZnVuY3Rpb24gY2FjaGUoIGtleSwgdmFsdWUgKSB7XG5cblx0XHQvLyBVc2UgKGtleSArIFwiIFwiKSB0byBhdm9pZCBjb2xsaXNpb24gd2l0aCBuYXRpdmUgcHJvdG90eXBlIHByb3BlcnRpZXMgKHNlZSBJc3N1ZSAjMTU3KVxuXHRcdGlmICgga2V5cy5wdXNoKCBrZXkgKyBcIiBcIiApID4gRXhwci5jYWNoZUxlbmd0aCApIHtcblxuXHRcdFx0Ly8gT25seSBrZWVwIHRoZSBtb3N0IHJlY2VudCBlbnRyaWVzXG5cdFx0XHRkZWxldGUgY2FjaGVbIGtleXMuc2hpZnQoKSBdO1xuXHRcdH1cblx0XHRyZXR1cm4gKCBjYWNoZVsga2V5ICsgXCIgXCIgXSA9IHZhbHVlICk7XG5cdH1cblx0cmV0dXJuIGNhY2hlO1xufVxuXG4vKipcbiAqIE1hcmsgYSBmdW5jdGlvbiBmb3Igc3BlY2lhbCB1c2UgYnkgU2l6emxlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiBUaGUgZnVuY3Rpb24gdG8gbWFya1xuICovXG5mdW5jdGlvbiBtYXJrRnVuY3Rpb24oIGZuICkge1xuXHRmblsgZXhwYW5kbyBdID0gdHJ1ZTtcblx0cmV0dXJuIGZuO1xufVxuXG4vKipcbiAqIFN1cHBvcnQgdGVzdGluZyB1c2luZyBhbiBlbGVtZW50XG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiBQYXNzZWQgdGhlIGNyZWF0ZWQgZWxlbWVudCBhbmQgcmV0dXJucyBhIGJvb2xlYW4gcmVzdWx0XG4gKi9cbmZ1bmN0aW9uIGFzc2VydCggZm4gKSB7XG5cdHZhciBlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiZmllbGRzZXRcIiApO1xuXG5cdHRyeSB7XG5cdFx0cmV0dXJuICEhZm4oIGVsICk7XG5cdH0gY2F0Y2ggKCBlICkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fSBmaW5hbGx5IHtcblxuXHRcdC8vIFJlbW92ZSBmcm9tIGl0cyBwYXJlbnQgYnkgZGVmYXVsdFxuXHRcdGlmICggZWwucGFyZW50Tm9kZSApIHtcblx0XHRcdGVsLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoIGVsICk7XG5cdFx0fVxuXG5cdFx0Ly8gcmVsZWFzZSBtZW1vcnkgaW4gSUVcblx0XHRlbCA9IG51bGw7XG5cdH1cbn1cblxuLyoqXG4gKiBBZGRzIHRoZSBzYW1lIGhhbmRsZXIgZm9yIGFsbCBvZiB0aGUgc3BlY2lmaWVkIGF0dHJzXG4gKiBAcGFyYW0ge1N0cmluZ30gYXR0cnMgUGlwZS1zZXBhcmF0ZWQgbGlzdCBvZiBhdHRyaWJ1dGVzXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBoYW5kbGVyIFRoZSBtZXRob2QgdGhhdCB3aWxsIGJlIGFwcGxpZWRcbiAqL1xuZnVuY3Rpb24gYWRkSGFuZGxlKCBhdHRycywgaGFuZGxlciApIHtcblx0dmFyIGFyciA9IGF0dHJzLnNwbGl0KCBcInxcIiApLFxuXHRcdGkgPSBhcnIubGVuZ3RoO1xuXG5cdHdoaWxlICggaS0tICkge1xuXHRcdEV4cHIuYXR0ckhhbmRsZVsgYXJyWyBpIF0gXSA9IGhhbmRsZXI7XG5cdH1cbn1cblxuLyoqXG4gKiBDaGVja3MgZG9jdW1lbnQgb3JkZXIgb2YgdHdvIHNpYmxpbmdzXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGFcbiAqIEBwYXJhbSB7RWxlbWVudH0gYlxuICogQHJldHVybnMge051bWJlcn0gUmV0dXJucyBsZXNzIHRoYW4gMCBpZiBhIHByZWNlZGVzIGIsIGdyZWF0ZXIgdGhhbiAwIGlmIGEgZm9sbG93cyBiXG4gKi9cbmZ1bmN0aW9uIHNpYmxpbmdDaGVjayggYSwgYiApIHtcblx0dmFyIGN1ciA9IGIgJiYgYSxcblx0XHRkaWZmID0gY3VyICYmIGEubm9kZVR5cGUgPT09IDEgJiYgYi5ub2RlVHlwZSA9PT0gMSAmJlxuXHRcdFx0YS5zb3VyY2VJbmRleCAtIGIuc291cmNlSW5kZXg7XG5cblx0Ly8gVXNlIElFIHNvdXJjZUluZGV4IGlmIGF2YWlsYWJsZSBvbiBib3RoIG5vZGVzXG5cdGlmICggZGlmZiApIHtcblx0XHRyZXR1cm4gZGlmZjtcblx0fVxuXG5cdC8vIENoZWNrIGlmIGIgZm9sbG93cyBhXG5cdGlmICggY3VyICkge1xuXHRcdHdoaWxlICggKCBjdXIgPSBjdXIubmV4dFNpYmxpbmcgKSApIHtcblx0XHRcdGlmICggY3VyID09PSBiICkge1xuXHRcdFx0XHRyZXR1cm4gLTE7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIGEgPyAxIDogLTE7XG59XG5cbi8qKlxuICogUmV0dXJucyBhIGZ1bmN0aW9uIHRvIHVzZSBpbiBwc2V1ZG9zIGZvciBpbnB1dCB0eXBlc1xuICogQHBhcmFtIHtTdHJpbmd9IHR5cGVcbiAqL1xuZnVuY3Rpb24gY3JlYXRlSW5wdXRQc2V1ZG8oIHR5cGUgKSB7XG5cdHJldHVybiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHR2YXIgbmFtZSA9IGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtcblx0XHRyZXR1cm4gbmFtZSA9PT0gXCJpbnB1dFwiICYmIGVsZW0udHlwZSA9PT0gdHlwZTtcblx0fTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgZnVuY3Rpb24gdG8gdXNlIGluIHBzZXVkb3MgZm9yIGJ1dHRvbnNcbiAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUJ1dHRvblBzZXVkbyggdHlwZSApIHtcblx0cmV0dXJuIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdHZhciBuYW1lID0gZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1xuXHRcdHJldHVybiAoIG5hbWUgPT09IFwiaW5wdXRcIiB8fCBuYW1lID09PSBcImJ1dHRvblwiICkgJiYgZWxlbS50eXBlID09PSB0eXBlO1xuXHR9O1xufVxuXG4vKipcbiAqIFJldHVybnMgYSBmdW5jdGlvbiB0byB1c2UgaW4gcHNldWRvcyBmb3IgOmVuYWJsZWQvOmRpc2FibGVkXG4gKiBAcGFyYW0ge0Jvb2xlYW59IGRpc2FibGVkIHRydWUgZm9yIDpkaXNhYmxlZDsgZmFsc2UgZm9yIDplbmFibGVkXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZURpc2FibGVkUHNldWRvKCBkaXNhYmxlZCApIHtcblxuXHQvLyBLbm93biA6ZGlzYWJsZWQgZmFsc2UgcG9zaXRpdmVzOiBmaWVsZHNldFtkaXNhYmxlZF0gPiBsZWdlbmQ6bnRoLW9mLXR5cGUobisyKSA6Y2FuLWRpc2FibGVcblx0cmV0dXJuIGZ1bmN0aW9uKCBlbGVtICkge1xuXG5cdFx0Ly8gT25seSBjZXJ0YWluIGVsZW1lbnRzIGNhbiBtYXRjaCA6ZW5hYmxlZCBvciA6ZGlzYWJsZWRcblx0XHQvLyBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9zY3JpcHRpbmcuaHRtbCNzZWxlY3Rvci1lbmFibGVkXG5cdFx0Ly8gaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2Uvc2NyaXB0aW5nLmh0bWwjc2VsZWN0b3ItZGlzYWJsZWRcblx0XHRpZiAoIFwiZm9ybVwiIGluIGVsZW0gKSB7XG5cblx0XHRcdC8vIENoZWNrIGZvciBpbmhlcml0ZWQgZGlzYWJsZWRuZXNzIG9uIHJlbGV2YW50IG5vbi1kaXNhYmxlZCBlbGVtZW50czpcblx0XHRcdC8vICogbGlzdGVkIGZvcm0tYXNzb2NpYXRlZCBlbGVtZW50cyBpbiBhIGRpc2FibGVkIGZpZWxkc2V0XG5cdFx0XHQvLyAgIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL2Zvcm1zLmh0bWwjY2F0ZWdvcnktbGlzdGVkXG5cdFx0XHQvLyAgIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL2Zvcm1zLmh0bWwjY29uY2VwdC1mZS1kaXNhYmxlZFxuXHRcdFx0Ly8gKiBvcHRpb24gZWxlbWVudHMgaW4gYSBkaXNhYmxlZCBvcHRncm91cFxuXHRcdFx0Ly8gICBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9mb3Jtcy5odG1sI2NvbmNlcHQtb3B0aW9uLWRpc2FibGVkXG5cdFx0XHQvLyBBbGwgc3VjaCBlbGVtZW50cyBoYXZlIGEgXCJmb3JtXCIgcHJvcGVydHkuXG5cdFx0XHRpZiAoIGVsZW0ucGFyZW50Tm9kZSAmJiBlbGVtLmRpc2FibGVkID09PSBmYWxzZSApIHtcblxuXHRcdFx0XHQvLyBPcHRpb24gZWxlbWVudHMgZGVmZXIgdG8gYSBwYXJlbnQgb3B0Z3JvdXAgaWYgcHJlc2VudFxuXHRcdFx0XHRpZiAoIFwibGFiZWxcIiBpbiBlbGVtICkge1xuXHRcdFx0XHRcdGlmICggXCJsYWJlbFwiIGluIGVsZW0ucGFyZW50Tm9kZSApIHtcblx0XHRcdFx0XHRcdHJldHVybiBlbGVtLnBhcmVudE5vZGUuZGlzYWJsZWQgPT09IGRpc2FibGVkO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gZWxlbS5kaXNhYmxlZCA9PT0gZGlzYWJsZWQ7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gU3VwcG9ydDogSUUgNiAtIDExXG5cdFx0XHRcdC8vIFVzZSB0aGUgaXNEaXNhYmxlZCBzaG9ydGN1dCBwcm9wZXJ0eSB0byBjaGVjayBmb3IgZGlzYWJsZWQgZmllbGRzZXQgYW5jZXN0b3JzXG5cdFx0XHRcdHJldHVybiBlbGVtLmlzRGlzYWJsZWQgPT09IGRpc2FibGVkIHx8XG5cblx0XHRcdFx0XHQvLyBXaGVyZSB0aGVyZSBpcyBubyBpc0Rpc2FibGVkLCBjaGVjayBtYW51YWxseVxuXHRcdFx0XHRcdC8qIGpzaGludCAtVzAxOCAqL1xuXHRcdFx0XHRcdGVsZW0uaXNEaXNhYmxlZCAhPT0gIWRpc2FibGVkICYmXG5cdFx0XHRcdFx0aW5EaXNhYmxlZEZpZWxkc2V0KCBlbGVtICkgPT09IGRpc2FibGVkO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gZWxlbS5kaXNhYmxlZCA9PT0gZGlzYWJsZWQ7XG5cblx0XHQvLyBUcnkgdG8gd2lubm93IG91dCBlbGVtZW50cyB0aGF0IGNhbid0IGJlIGRpc2FibGVkIGJlZm9yZSB0cnVzdGluZyB0aGUgZGlzYWJsZWQgcHJvcGVydHkuXG5cdFx0Ly8gU29tZSB2aWN0aW1zIGdldCBjYXVnaHQgaW4gb3VyIG5ldCAobGFiZWwsIGxlZ2VuZCwgbWVudSwgdHJhY2spLCBidXQgaXQgc2hvdWxkbid0XG5cdFx0Ly8gZXZlbiBleGlzdCBvbiB0aGVtLCBsZXQgYWxvbmUgaGF2ZSBhIGJvb2xlYW4gdmFsdWUuXG5cdFx0fSBlbHNlIGlmICggXCJsYWJlbFwiIGluIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4gZWxlbS5kaXNhYmxlZCA9PT0gZGlzYWJsZWQ7XG5cdFx0fVxuXG5cdFx0Ly8gUmVtYWluaW5nIGVsZW1lbnRzIGFyZSBuZWl0aGVyIDplbmFibGVkIG5vciA6ZGlzYWJsZWRcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH07XG59XG5cbi8qKlxuICogUmV0dXJucyBhIGZ1bmN0aW9uIHRvIHVzZSBpbiBwc2V1ZG9zIGZvciBwb3NpdGlvbmFsc1xuICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlUG9zaXRpb25hbFBzZXVkbyggZm4gKSB7XG5cdHJldHVybiBtYXJrRnVuY3Rpb24oIGZ1bmN0aW9uKCBhcmd1bWVudCApIHtcblx0XHRhcmd1bWVudCA9ICthcmd1bWVudDtcblx0XHRyZXR1cm4gbWFya0Z1bmN0aW9uKCBmdW5jdGlvbiggc2VlZCwgbWF0Y2hlcyApIHtcblx0XHRcdHZhciBqLFxuXHRcdFx0XHRtYXRjaEluZGV4ZXMgPSBmbiggW10sIHNlZWQubGVuZ3RoLCBhcmd1bWVudCApLFxuXHRcdFx0XHRpID0gbWF0Y2hJbmRleGVzLmxlbmd0aDtcblxuXHRcdFx0Ly8gTWF0Y2ggZWxlbWVudHMgZm91bmQgYXQgdGhlIHNwZWNpZmllZCBpbmRleGVzXG5cdFx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdFx0aWYgKCBzZWVkWyAoIGogPSBtYXRjaEluZGV4ZXNbIGkgXSApIF0gKSB7XG5cdFx0XHRcdFx0c2VlZFsgaiBdID0gISggbWF0Y2hlc1sgaiBdID0gc2VlZFsgaiBdICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9ICk7XG5cdH0gKTtcbn1cblxuLyoqXG4gKiBDaGVja3MgYSBub2RlIGZvciB2YWxpZGl0eSBhcyBhIFNpenpsZSBjb250ZXh0XG4gKiBAcGFyYW0ge0VsZW1lbnR8T2JqZWN0PX0gY29udGV4dFxuICogQHJldHVybnMge0VsZW1lbnR8T2JqZWN0fEJvb2xlYW59IFRoZSBpbnB1dCBub2RlIGlmIGFjY2VwdGFibGUsIG90aGVyd2lzZSBhIGZhbHN5IHZhbHVlXG4gKi9cbmZ1bmN0aW9uIHRlc3RDb250ZXh0KCBjb250ZXh0ICkge1xuXHRyZXR1cm4gY29udGV4dCAmJiB0eXBlb2YgY29udGV4dC5nZXRFbGVtZW50c0J5VGFnTmFtZSAhPT0gXCJ1bmRlZmluZWRcIiAmJiBjb250ZXh0O1xufVxuXG4vLyBFeHBvc2Ugc3VwcG9ydCB2YXJzIGZvciBjb252ZW5pZW5jZVxuc3VwcG9ydCA9IFNpenpsZS5zdXBwb3J0ID0ge307XG5cbi8qKlxuICogRGV0ZWN0cyBYTUwgbm9kZXNcbiAqIEBwYXJhbSB7RWxlbWVudHxPYmplY3R9IGVsZW0gQW4gZWxlbWVudCBvciBhIGRvY3VtZW50XG4gKiBAcmV0dXJucyB7Qm9vbGVhbn0gVHJ1ZSBpZmYgZWxlbSBpcyBhIG5vbi1IVE1MIFhNTCBub2RlXG4gKi9cbmlzWE1MID0gU2l6emxlLmlzWE1MID0gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdHZhciBuYW1lc3BhY2UgPSBlbGVtICYmIGVsZW0ubmFtZXNwYWNlVVJJLFxuXHRcdGRvY0VsZW0gPSBlbGVtICYmICggZWxlbS5vd25lckRvY3VtZW50IHx8IGVsZW0gKS5kb2N1bWVudEVsZW1lbnQ7XG5cblx0Ly8gU3VwcG9ydDogSUUgPD04XG5cdC8vIEFzc3VtZSBIVE1MIHdoZW4gZG9jdW1lbnRFbGVtZW50IGRvZXNuJ3QgeWV0IGV4aXN0LCBzdWNoIGFzIGluc2lkZSBsb2FkaW5nIGlmcmFtZXNcblx0Ly8gaHR0cHM6Ly9idWdzLmpxdWVyeS5jb20vdGlja2V0LzQ4MzNcblx0cmV0dXJuICFyaHRtbC50ZXN0KCBuYW1lc3BhY2UgfHwgZG9jRWxlbSAmJiBkb2NFbGVtLm5vZGVOYW1lIHx8IFwiSFRNTFwiICk7XG59O1xuXG4vKipcbiAqIFNldHMgZG9jdW1lbnQtcmVsYXRlZCB2YXJpYWJsZXMgb25jZSBiYXNlZCBvbiB0aGUgY3VycmVudCBkb2N1bWVudFxuICogQHBhcmFtIHtFbGVtZW50fE9iamVjdH0gW2RvY10gQW4gZWxlbWVudCBvciBkb2N1bWVudCBvYmplY3QgdG8gdXNlIHRvIHNldCB0aGUgZG9jdW1lbnRcbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGN1cnJlbnQgZG9jdW1lbnRcbiAqL1xuc2V0RG9jdW1lbnQgPSBTaXp6bGUuc2V0RG9jdW1lbnQgPSBmdW5jdGlvbiggbm9kZSApIHtcblx0dmFyIGhhc0NvbXBhcmUsIHN1YldpbmRvdyxcblx0XHRkb2MgPSBub2RlID8gbm9kZS5vd25lckRvY3VtZW50IHx8IG5vZGUgOiBwcmVmZXJyZWREb2M7XG5cblx0Ly8gUmV0dXJuIGVhcmx5IGlmIGRvYyBpcyBpbnZhbGlkIG9yIGFscmVhZHkgc2VsZWN0ZWRcblx0Ly8gU3VwcG9ydDogSUUgMTErLCBFZGdlIDE3IC0gMTgrXG5cdC8vIElFL0VkZ2Ugc29tZXRpbWVzIHRocm93IGEgXCJQZXJtaXNzaW9uIGRlbmllZFwiIGVycm9yIHdoZW4gc3RyaWN0LWNvbXBhcmluZ1xuXHQvLyB0d28gZG9jdW1lbnRzOyBzaGFsbG93IGNvbXBhcmlzb25zIHdvcmsuXG5cdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBlcWVxZXFcblx0aWYgKCBkb2MgPT0gZG9jdW1lbnQgfHwgZG9jLm5vZGVUeXBlICE9PSA5IHx8ICFkb2MuZG9jdW1lbnRFbGVtZW50ICkge1xuXHRcdHJldHVybiBkb2N1bWVudDtcblx0fVxuXG5cdC8vIFVwZGF0ZSBnbG9iYWwgdmFyaWFibGVzXG5cdGRvY3VtZW50ID0gZG9jO1xuXHRkb2NFbGVtID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50O1xuXHRkb2N1bWVudElzSFRNTCA9ICFpc1hNTCggZG9jdW1lbnQgKTtcblxuXHQvLyBTdXBwb3J0OiBJRSA5IC0gMTErLCBFZGdlIDEyIC0gMTgrXG5cdC8vIEFjY2Vzc2luZyBpZnJhbWUgZG9jdW1lbnRzIGFmdGVyIHVubG9hZCB0aHJvd3MgXCJwZXJtaXNzaW9uIGRlbmllZFwiIGVycm9ycyAoalF1ZXJ5ICMxMzkzNilcblx0Ly8gU3VwcG9ydDogSUUgMTErLCBFZGdlIDE3IC0gMTgrXG5cdC8vIElFL0VkZ2Ugc29tZXRpbWVzIHRocm93IGEgXCJQZXJtaXNzaW9uIGRlbmllZFwiIGVycm9yIHdoZW4gc3RyaWN0LWNvbXBhcmluZ1xuXHQvLyB0d28gZG9jdW1lbnRzOyBzaGFsbG93IGNvbXBhcmlzb25zIHdvcmsuXG5cdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBlcWVxZXFcblx0aWYgKCBwcmVmZXJyZWREb2MgIT0gZG9jdW1lbnQgJiZcblx0XHQoIHN1YldpbmRvdyA9IGRvY3VtZW50LmRlZmF1bHRWaWV3ICkgJiYgc3ViV2luZG93LnRvcCAhPT0gc3ViV2luZG93ICkge1xuXG5cdFx0Ly8gU3VwcG9ydDogSUUgMTEsIEVkZ2Vcblx0XHRpZiAoIHN1YldpbmRvdy5hZGRFdmVudExpc3RlbmVyICkge1xuXHRcdFx0c3ViV2luZG93LmFkZEV2ZW50TGlzdGVuZXIoIFwidW5sb2FkXCIsIHVubG9hZEhhbmRsZXIsIGZhbHNlICk7XG5cblx0XHQvLyBTdXBwb3J0OiBJRSA5IC0gMTAgb25seVxuXHRcdH0gZWxzZSBpZiAoIHN1YldpbmRvdy5hdHRhY2hFdmVudCApIHtcblx0XHRcdHN1YldpbmRvdy5hdHRhY2hFdmVudCggXCJvbnVubG9hZFwiLCB1bmxvYWRIYW5kbGVyICk7XG5cdFx0fVxuXHR9XG5cblx0Ly8gU3VwcG9ydDogSUUgOCAtIDExKywgRWRnZSAxMiAtIDE4KywgQ2hyb21lIDw9MTYgLSAyNSBvbmx5LCBGaXJlZm94IDw9My42IC0gMzEgb25seSxcblx0Ly8gU2FmYXJpIDQgLSA1IG9ubHksIE9wZXJhIDw9MTEuNiAtIDEyLnggb25seVxuXHQvLyBJRS9FZGdlICYgb2xkZXIgYnJvd3NlcnMgZG9uJ3Qgc3VwcG9ydCB0aGUgOnNjb3BlIHBzZXVkby1jbGFzcy5cblx0Ly8gU3VwcG9ydDogU2FmYXJpIDYuMCBvbmx5XG5cdC8vIFNhZmFyaSA2LjAgc3VwcG9ydHMgOnNjb3BlIGJ1dCBpdCdzIGFuIGFsaWFzIG9mIDpyb290IHRoZXJlLlxuXHRzdXBwb3J0LnNjb3BlID0gYXNzZXJ0KCBmdW5jdGlvbiggZWwgKSB7XG5cdFx0ZG9jRWxlbS5hcHBlbmRDaGlsZCggZWwgKS5hcHBlbmRDaGlsZCggZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJkaXZcIiApICk7XG5cdFx0cmV0dXJuIHR5cGVvZiBlbC5xdWVyeVNlbGVjdG9yQWxsICE9PSBcInVuZGVmaW5lZFwiICYmXG5cdFx0XHQhZWwucXVlcnlTZWxlY3RvckFsbCggXCI6c2NvcGUgZmllbGRzZXQgZGl2XCIgKS5sZW5ndGg7XG5cdH0gKTtcblxuXHQvKiBBdHRyaWJ1dGVzXG5cdC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cblxuXHQvLyBTdXBwb3J0OiBJRTw4XG5cdC8vIFZlcmlmeSB0aGF0IGdldEF0dHJpYnV0ZSByZWFsbHkgcmV0dXJucyBhdHRyaWJ1dGVzIGFuZCBub3QgcHJvcGVydGllc1xuXHQvLyAoZXhjZXB0aW5nIElFOCBib29sZWFucylcblx0c3VwcG9ydC5hdHRyaWJ1dGVzID0gYXNzZXJ0KCBmdW5jdGlvbiggZWwgKSB7XG5cdFx0ZWwuY2xhc3NOYW1lID0gXCJpXCI7XG5cdFx0cmV0dXJuICFlbC5nZXRBdHRyaWJ1dGUoIFwiY2xhc3NOYW1lXCIgKTtcblx0fSApO1xuXG5cdC8qIGdldEVsZW1lbnQocylCeSpcblx0LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG5cdC8vIENoZWNrIGlmIGdldEVsZW1lbnRzQnlUYWdOYW1lKFwiKlwiKSByZXR1cm5zIG9ubHkgZWxlbWVudHNcblx0c3VwcG9ydC5nZXRFbGVtZW50c0J5VGFnTmFtZSA9IGFzc2VydCggZnVuY3Rpb24oIGVsICkge1xuXHRcdGVsLmFwcGVuZENoaWxkKCBkb2N1bWVudC5jcmVhdGVDb21tZW50KCBcIlwiICkgKTtcblx0XHRyZXR1cm4gIWVsLmdldEVsZW1lbnRzQnlUYWdOYW1lKCBcIipcIiApLmxlbmd0aDtcblx0fSApO1xuXG5cdC8vIFN1cHBvcnQ6IElFPDlcblx0c3VwcG9ydC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lID0gcm5hdGl2ZS50ZXN0KCBkb2N1bWVudC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lICk7XG5cblx0Ly8gU3VwcG9ydDogSUU8MTBcblx0Ly8gQ2hlY2sgaWYgZ2V0RWxlbWVudEJ5SWQgcmV0dXJucyBlbGVtZW50cyBieSBuYW1lXG5cdC8vIFRoZSBicm9rZW4gZ2V0RWxlbWVudEJ5SWQgbWV0aG9kcyBkb24ndCBwaWNrIHVwIHByb2dyYW1tYXRpY2FsbHktc2V0IG5hbWVzLFxuXHQvLyBzbyB1c2UgYSByb3VuZGFib3V0IGdldEVsZW1lbnRzQnlOYW1lIHRlc3Rcblx0c3VwcG9ydC5nZXRCeUlkID0gYXNzZXJ0KCBmdW5jdGlvbiggZWwgKSB7XG5cdFx0ZG9jRWxlbS5hcHBlbmRDaGlsZCggZWwgKS5pZCA9IGV4cGFuZG87XG5cdFx0cmV0dXJuICFkb2N1bWVudC5nZXRFbGVtZW50c0J5TmFtZSB8fCAhZG9jdW1lbnQuZ2V0RWxlbWVudHNCeU5hbWUoIGV4cGFuZG8gKS5sZW5ndGg7XG5cdH0gKTtcblxuXHQvLyBJRCBmaWx0ZXIgYW5kIGZpbmRcblx0aWYgKCBzdXBwb3J0LmdldEJ5SWQgKSB7XG5cdFx0RXhwci5maWx0ZXJbIFwiSURcIiBdID0gZnVuY3Rpb24oIGlkICkge1xuXHRcdFx0dmFyIGF0dHJJZCA9IGlkLnJlcGxhY2UoIHJ1bmVzY2FwZSwgZnVuZXNjYXBlICk7XG5cdFx0XHRyZXR1cm4gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRcdHJldHVybiBlbGVtLmdldEF0dHJpYnV0ZSggXCJpZFwiICkgPT09IGF0dHJJZDtcblx0XHRcdH07XG5cdFx0fTtcblx0XHRFeHByLmZpbmRbIFwiSURcIiBdID0gZnVuY3Rpb24oIGlkLCBjb250ZXh0ICkge1xuXHRcdFx0aWYgKCB0eXBlb2YgY29udGV4dC5nZXRFbGVtZW50QnlJZCAhPT0gXCJ1bmRlZmluZWRcIiAmJiBkb2N1bWVudElzSFRNTCApIHtcblx0XHRcdFx0dmFyIGVsZW0gPSBjb250ZXh0LmdldEVsZW1lbnRCeUlkKCBpZCApO1xuXHRcdFx0XHRyZXR1cm4gZWxlbSA/IFsgZWxlbSBdIDogW107XG5cdFx0XHR9XG5cdFx0fTtcblx0fSBlbHNlIHtcblx0XHRFeHByLmZpbHRlclsgXCJJRFwiIF0gPSAgZnVuY3Rpb24oIGlkICkge1xuXHRcdFx0dmFyIGF0dHJJZCA9IGlkLnJlcGxhY2UoIHJ1bmVzY2FwZSwgZnVuZXNjYXBlICk7XG5cdFx0XHRyZXR1cm4gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRcdHZhciBub2RlID0gdHlwZW9mIGVsZW0uZ2V0QXR0cmlidXRlTm9kZSAhPT0gXCJ1bmRlZmluZWRcIiAmJlxuXHRcdFx0XHRcdGVsZW0uZ2V0QXR0cmlidXRlTm9kZSggXCJpZFwiICk7XG5cdFx0XHRcdHJldHVybiBub2RlICYmIG5vZGUudmFsdWUgPT09IGF0dHJJZDtcblx0XHRcdH07XG5cdFx0fTtcblxuXHRcdC8vIFN1cHBvcnQ6IElFIDYgLSA3IG9ubHlcblx0XHQvLyBnZXRFbGVtZW50QnlJZCBpcyBub3QgcmVsaWFibGUgYXMgYSBmaW5kIHNob3J0Y3V0XG5cdFx0RXhwci5maW5kWyBcIklEXCIgXSA9IGZ1bmN0aW9uKCBpZCwgY29udGV4dCApIHtcblx0XHRcdGlmICggdHlwZW9mIGNvbnRleHQuZ2V0RWxlbWVudEJ5SWQgIT09IFwidW5kZWZpbmVkXCIgJiYgZG9jdW1lbnRJc0hUTUwgKSB7XG5cdFx0XHRcdHZhciBub2RlLCBpLCBlbGVtcyxcblx0XHRcdFx0XHRlbGVtID0gY29udGV4dC5nZXRFbGVtZW50QnlJZCggaWQgKTtcblxuXHRcdFx0XHRpZiAoIGVsZW0gKSB7XG5cblx0XHRcdFx0XHQvLyBWZXJpZnkgdGhlIGlkIGF0dHJpYnV0ZVxuXHRcdFx0XHRcdG5vZGUgPSBlbGVtLmdldEF0dHJpYnV0ZU5vZGUoIFwiaWRcIiApO1xuXHRcdFx0XHRcdGlmICggbm9kZSAmJiBub2RlLnZhbHVlID09PSBpZCApIHtcblx0XHRcdFx0XHRcdHJldHVybiBbIGVsZW0gXTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHQvLyBGYWxsIGJhY2sgb24gZ2V0RWxlbWVudHNCeU5hbWVcblx0XHRcdFx0XHRlbGVtcyA9IGNvbnRleHQuZ2V0RWxlbWVudHNCeU5hbWUoIGlkICk7XG5cdFx0XHRcdFx0aSA9IDA7XG5cdFx0XHRcdFx0d2hpbGUgKCAoIGVsZW0gPSBlbGVtc1sgaSsrIF0gKSApIHtcblx0XHRcdFx0XHRcdG5vZGUgPSBlbGVtLmdldEF0dHJpYnV0ZU5vZGUoIFwiaWRcIiApO1xuXHRcdFx0XHRcdFx0aWYgKCBub2RlICYmIG5vZGUudmFsdWUgPT09IGlkICkge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gWyBlbGVtIF07XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0dXJuIFtdO1xuXHRcdFx0fVxuXHRcdH07XG5cdH1cblxuXHQvLyBUYWdcblx0RXhwci5maW5kWyBcIlRBR1wiIF0gPSBzdXBwb3J0LmdldEVsZW1lbnRzQnlUYWdOYW1lID9cblx0XHRmdW5jdGlvbiggdGFnLCBjb250ZXh0ICkge1xuXHRcdFx0aWYgKCB0eXBlb2YgY29udGV4dC5nZXRFbGVtZW50c0J5VGFnTmFtZSAhPT0gXCJ1bmRlZmluZWRcIiApIHtcblx0XHRcdFx0cmV0dXJuIGNvbnRleHQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIHRhZyApO1xuXG5cdFx0XHQvLyBEb2N1bWVudEZyYWdtZW50IG5vZGVzIGRvbid0IGhhdmUgZ0VCVE5cblx0XHRcdH0gZWxzZSBpZiAoIHN1cHBvcnQucXNhICkge1xuXHRcdFx0XHRyZXR1cm4gY29udGV4dC5xdWVyeVNlbGVjdG9yQWxsKCB0YWcgKTtcblx0XHRcdH1cblx0XHR9IDpcblxuXHRcdGZ1bmN0aW9uKCB0YWcsIGNvbnRleHQgKSB7XG5cdFx0XHR2YXIgZWxlbSxcblx0XHRcdFx0dG1wID0gW10sXG5cdFx0XHRcdGkgPSAwLFxuXG5cdFx0XHRcdC8vIEJ5IGhhcHB5IGNvaW5jaWRlbmNlLCBhIChicm9rZW4pIGdFQlROIGFwcGVhcnMgb24gRG9jdW1lbnRGcmFnbWVudCBub2RlcyB0b29cblx0XHRcdFx0cmVzdWx0cyA9IGNvbnRleHQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIHRhZyApO1xuXG5cdFx0XHQvLyBGaWx0ZXIgb3V0IHBvc3NpYmxlIGNvbW1lbnRzXG5cdFx0XHRpZiAoIHRhZyA9PT0gXCIqXCIgKSB7XG5cdFx0XHRcdHdoaWxlICggKCBlbGVtID0gcmVzdWx0c1sgaSsrIF0gKSApIHtcblx0XHRcdFx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDEgKSB7XG5cdFx0XHRcdFx0XHR0bXAucHVzaCggZWxlbSApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHRcdHJldHVybiB0bXA7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gcmVzdWx0cztcblx0XHR9O1xuXG5cdC8vIENsYXNzXG5cdEV4cHIuZmluZFsgXCJDTEFTU1wiIF0gPSBzdXBwb3J0LmdldEVsZW1lbnRzQnlDbGFzc05hbWUgJiYgZnVuY3Rpb24oIGNsYXNzTmFtZSwgY29udGV4dCApIHtcblx0XHRpZiAoIHR5cGVvZiBjb250ZXh0LmdldEVsZW1lbnRzQnlDbGFzc05hbWUgIT09IFwidW5kZWZpbmVkXCIgJiYgZG9jdW1lbnRJc0hUTUwgKSB7XG5cdFx0XHRyZXR1cm4gY29udGV4dC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKCBjbGFzc05hbWUgKTtcblx0XHR9XG5cdH07XG5cblx0LyogUVNBL21hdGNoZXNTZWxlY3RvclxuXHQtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cblx0Ly8gUVNBIGFuZCBtYXRjaGVzU2VsZWN0b3Igc3VwcG9ydFxuXG5cdC8vIG1hdGNoZXNTZWxlY3Rvcig6YWN0aXZlKSByZXBvcnRzIGZhbHNlIHdoZW4gdHJ1ZSAoSUU5L09wZXJhIDExLjUpXG5cdHJidWdneU1hdGNoZXMgPSBbXTtcblxuXHQvLyBxU2EoOmZvY3VzKSByZXBvcnRzIGZhbHNlIHdoZW4gdHJ1ZSAoQ2hyb21lIDIxKVxuXHQvLyBXZSBhbGxvdyB0aGlzIGJlY2F1c2Ugb2YgYSBidWcgaW4gSUU4LzkgdGhhdCB0aHJvd3MgYW4gZXJyb3Jcblx0Ly8gd2hlbmV2ZXIgYGRvY3VtZW50LmFjdGl2ZUVsZW1lbnRgIGlzIGFjY2Vzc2VkIG9uIGFuIGlmcmFtZVxuXHQvLyBTbywgd2UgYWxsb3cgOmZvY3VzIHRvIHBhc3MgdGhyb3VnaCBRU0EgYWxsIHRoZSB0aW1lIHRvIGF2b2lkIHRoZSBJRSBlcnJvclxuXHQvLyBTZWUgaHR0cHM6Ly9idWdzLmpxdWVyeS5jb20vdGlja2V0LzEzMzc4XG5cdHJidWdneVFTQSA9IFtdO1xuXG5cdGlmICggKCBzdXBwb3J0LnFzYSA9IHJuYXRpdmUudGVzdCggZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCApICkgKSB7XG5cblx0XHQvLyBCdWlsZCBRU0EgcmVnZXhcblx0XHQvLyBSZWdleCBzdHJhdGVneSBhZG9wdGVkIGZyb20gRGllZ28gUGVyaW5pXG5cdFx0YXNzZXJ0KCBmdW5jdGlvbiggZWwgKSB7XG5cblx0XHRcdHZhciBpbnB1dDtcblxuXHRcdFx0Ly8gU2VsZWN0IGlzIHNldCB0byBlbXB0eSBzdHJpbmcgb24gcHVycG9zZVxuXHRcdFx0Ly8gVGhpcyBpcyB0byB0ZXN0IElFJ3MgdHJlYXRtZW50IG9mIG5vdCBleHBsaWNpdGx5XG5cdFx0XHQvLyBzZXR0aW5nIGEgYm9vbGVhbiBjb250ZW50IGF0dHJpYnV0ZSxcblx0XHRcdC8vIHNpbmNlIGl0cyBwcmVzZW5jZSBzaG91bGQgYmUgZW5vdWdoXG5cdFx0XHQvLyBodHRwczovL2J1Z3MuanF1ZXJ5LmNvbS90aWNrZXQvMTIzNTlcblx0XHRcdGRvY0VsZW0uYXBwZW5kQ2hpbGQoIGVsICkuaW5uZXJIVE1MID0gXCI8YSBpZD0nXCIgKyBleHBhbmRvICsgXCInPjwvYT5cIiArXG5cdFx0XHRcdFwiPHNlbGVjdCBpZD0nXCIgKyBleHBhbmRvICsgXCItXFxyXFxcXCcgbXNhbGxvd2NhcHR1cmU9Jyc+XCIgK1xuXHRcdFx0XHRcIjxvcHRpb24gc2VsZWN0ZWQ9Jyc+PC9vcHRpb24+PC9zZWxlY3Q+XCI7XG5cblx0XHRcdC8vIFN1cHBvcnQ6IElFOCwgT3BlcmEgMTEtMTIuMTZcblx0XHRcdC8vIE5vdGhpbmcgc2hvdWxkIGJlIHNlbGVjdGVkIHdoZW4gZW1wdHkgc3RyaW5ncyBmb2xsb3cgXj0gb3IgJD0gb3IgKj1cblx0XHRcdC8vIFRoZSB0ZXN0IGF0dHJpYnV0ZSBtdXN0IGJlIHVua25vd24gaW4gT3BlcmEgYnV0IFwic2FmZVwiIGZvciBXaW5SVFxuXHRcdFx0Ly8gaHR0cHM6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9pZS9oaDQ2NTM4OC5hc3B4I2F0dHJpYnV0ZV9zZWN0aW9uXG5cdFx0XHRpZiAoIGVsLnF1ZXJ5U2VsZWN0b3JBbGwoIFwiW21zYWxsb3djYXB0dXJlXj0nJ11cIiApLmxlbmd0aCApIHtcblx0XHRcdFx0cmJ1Z2d5UVNBLnB1c2goIFwiWypeJF09XCIgKyB3aGl0ZXNwYWNlICsgXCIqKD86Jyd8XFxcIlxcXCIpXCIgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gU3VwcG9ydDogSUU4XG5cdFx0XHQvLyBCb29sZWFuIGF0dHJpYnV0ZXMgYW5kIFwidmFsdWVcIiBhcmUgbm90IHRyZWF0ZWQgY29ycmVjdGx5XG5cdFx0XHRpZiAoICFlbC5xdWVyeVNlbGVjdG9yQWxsKCBcIltzZWxlY3RlZF1cIiApLmxlbmd0aCApIHtcblx0XHRcdFx0cmJ1Z2d5UVNBLnB1c2goIFwiXFxcXFtcIiArIHdoaXRlc3BhY2UgKyBcIiooPzp2YWx1ZXxcIiArIGJvb2xlYW5zICsgXCIpXCIgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gU3VwcG9ydDogQ2hyb21lPDI5LCBBbmRyb2lkPDQuNCwgU2FmYXJpPDcuMCssIGlPUzw3LjArLCBQaGFudG9tSlM8MS45LjgrXG5cdFx0XHRpZiAoICFlbC5xdWVyeVNlbGVjdG9yQWxsKCBcIltpZH49XCIgKyBleHBhbmRvICsgXCItXVwiICkubGVuZ3RoICkge1xuXHRcdFx0XHRyYnVnZ3lRU0EucHVzaCggXCJ+PVwiICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFN1cHBvcnQ6IElFIDExKywgRWRnZSAxNSAtIDE4K1xuXHRcdFx0Ly8gSUUgMTEvRWRnZSBkb24ndCBmaW5kIGVsZW1lbnRzIG9uIGEgYFtuYW1lPScnXWAgcXVlcnkgaW4gc29tZSBjYXNlcy5cblx0XHRcdC8vIEFkZGluZyBhIHRlbXBvcmFyeSBhdHRyaWJ1dGUgdG8gdGhlIGRvY3VtZW50IGJlZm9yZSB0aGUgc2VsZWN0aW9uIHdvcmtzXG5cdFx0XHQvLyBhcm91bmQgdGhlIGlzc3VlLlxuXHRcdFx0Ly8gSW50ZXJlc3RpbmdseSwgSUUgMTAgJiBvbGRlciBkb24ndCBzZWVtIHRvIGhhdmUgdGhlIGlzc3VlLlxuXHRcdFx0aW5wdXQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImlucHV0XCIgKTtcblx0XHRcdGlucHV0LnNldEF0dHJpYnV0ZSggXCJuYW1lXCIsIFwiXCIgKTtcblx0XHRcdGVsLmFwcGVuZENoaWxkKCBpbnB1dCApO1xuXHRcdFx0aWYgKCAhZWwucXVlcnlTZWxlY3RvckFsbCggXCJbbmFtZT0nJ11cIiApLmxlbmd0aCApIHtcblx0XHRcdFx0cmJ1Z2d5UVNBLnB1c2goIFwiXFxcXFtcIiArIHdoaXRlc3BhY2UgKyBcIipuYW1lXCIgKyB3aGl0ZXNwYWNlICsgXCIqPVwiICtcblx0XHRcdFx0XHR3aGl0ZXNwYWNlICsgXCIqKD86Jyd8XFxcIlxcXCIpXCIgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gV2Via2l0L09wZXJhIC0gOmNoZWNrZWQgc2hvdWxkIHJldHVybiBzZWxlY3RlZCBvcHRpb24gZWxlbWVudHNcblx0XHRcdC8vIGh0dHA6Ly93d3cudzMub3JnL1RSLzIwMTEvUkVDLWNzczMtc2VsZWN0b3JzLTIwMTEwOTI5LyNjaGVja2VkXG5cdFx0XHQvLyBJRTggdGhyb3dzIGVycm9yIGhlcmUgYW5kIHdpbGwgbm90IHNlZSBsYXRlciB0ZXN0c1xuXHRcdFx0aWYgKCAhZWwucXVlcnlTZWxlY3RvckFsbCggXCI6Y2hlY2tlZFwiICkubGVuZ3RoICkge1xuXHRcdFx0XHRyYnVnZ3lRU0EucHVzaCggXCI6Y2hlY2tlZFwiICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFN1cHBvcnQ6IFNhZmFyaSA4KywgaU9TIDgrXG5cdFx0XHQvLyBodHRwczovL2J1Z3Mud2Via2l0Lm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MTM2ODUxXG5cdFx0XHQvLyBJbi1wYWdlIGBzZWxlY3RvciNpZCBzaWJsaW5nLWNvbWJpbmF0b3Igc2VsZWN0b3JgIGZhaWxzXG5cdFx0XHRpZiAoICFlbC5xdWVyeVNlbGVjdG9yQWxsKCBcImEjXCIgKyBleHBhbmRvICsgXCIrKlwiICkubGVuZ3RoICkge1xuXHRcdFx0XHRyYnVnZ3lRU0EucHVzaCggXCIuIy4rWyt+XVwiICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFN1cHBvcnQ6IEZpcmVmb3ggPD0zLjYgLSA1IG9ubHlcblx0XHRcdC8vIE9sZCBGaXJlZm94IGRvZXNuJ3QgdGhyb3cgb24gYSBiYWRseS1lc2NhcGVkIGlkZW50aWZpZXIuXG5cdFx0XHRlbC5xdWVyeVNlbGVjdG9yQWxsKCBcIlxcXFxcXGZcIiApO1xuXHRcdFx0cmJ1Z2d5UVNBLnB1c2goIFwiW1xcXFxyXFxcXG5cXFxcZl1cIiApO1xuXHRcdH0gKTtcblxuXHRcdGFzc2VydCggZnVuY3Rpb24oIGVsICkge1xuXHRcdFx0ZWwuaW5uZXJIVE1MID0gXCI8YSBocmVmPScnIGRpc2FibGVkPSdkaXNhYmxlZCc+PC9hPlwiICtcblx0XHRcdFx0XCI8c2VsZWN0IGRpc2FibGVkPSdkaXNhYmxlZCc+PG9wdGlvbi8+PC9zZWxlY3Q+XCI7XG5cblx0XHRcdC8vIFN1cHBvcnQ6IFdpbmRvd3MgOCBOYXRpdmUgQXBwc1xuXHRcdFx0Ly8gVGhlIHR5cGUgYW5kIG5hbWUgYXR0cmlidXRlcyBhcmUgcmVzdHJpY3RlZCBkdXJpbmcgLmlubmVySFRNTCBhc3NpZ25tZW50XG5cdFx0XHR2YXIgaW5wdXQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImlucHV0XCIgKTtcblx0XHRcdGlucHV0LnNldEF0dHJpYnV0ZSggXCJ0eXBlXCIsIFwiaGlkZGVuXCIgKTtcblx0XHRcdGVsLmFwcGVuZENoaWxkKCBpbnB1dCApLnNldEF0dHJpYnV0ZSggXCJuYW1lXCIsIFwiRFwiICk7XG5cblx0XHRcdC8vIFN1cHBvcnQ6IElFOFxuXHRcdFx0Ly8gRW5mb3JjZSBjYXNlLXNlbnNpdGl2aXR5IG9mIG5hbWUgYXR0cmlidXRlXG5cdFx0XHRpZiAoIGVsLnF1ZXJ5U2VsZWN0b3JBbGwoIFwiW25hbWU9ZF1cIiApLmxlbmd0aCApIHtcblx0XHRcdFx0cmJ1Z2d5UVNBLnB1c2goIFwibmFtZVwiICsgd2hpdGVzcGFjZSArIFwiKlsqXiR8IX5dPz1cIiApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBGRiAzLjUgLSA6ZW5hYmxlZC86ZGlzYWJsZWQgYW5kIGhpZGRlbiBlbGVtZW50cyAoaGlkZGVuIGVsZW1lbnRzIGFyZSBzdGlsbCBlbmFibGVkKVxuXHRcdFx0Ly8gSUU4IHRocm93cyBlcnJvciBoZXJlIGFuZCB3aWxsIG5vdCBzZWUgbGF0ZXIgdGVzdHNcblx0XHRcdGlmICggZWwucXVlcnlTZWxlY3RvckFsbCggXCI6ZW5hYmxlZFwiICkubGVuZ3RoICE9PSAyICkge1xuXHRcdFx0XHRyYnVnZ3lRU0EucHVzaCggXCI6ZW5hYmxlZFwiLCBcIjpkaXNhYmxlZFwiICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFN1cHBvcnQ6IElFOS0xMStcblx0XHRcdC8vIElFJ3MgOmRpc2FibGVkIHNlbGVjdG9yIGRvZXMgbm90IHBpY2sgdXAgdGhlIGNoaWxkcmVuIG9mIGRpc2FibGVkIGZpZWxkc2V0c1xuXHRcdFx0ZG9jRWxlbS5hcHBlbmRDaGlsZCggZWwgKS5kaXNhYmxlZCA9IHRydWU7XG5cdFx0XHRpZiAoIGVsLnF1ZXJ5U2VsZWN0b3JBbGwoIFwiOmRpc2FibGVkXCIgKS5sZW5ndGggIT09IDIgKSB7XG5cdFx0XHRcdHJidWdneVFTQS5wdXNoKCBcIjplbmFibGVkXCIsIFwiOmRpc2FibGVkXCIgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gU3VwcG9ydDogT3BlcmEgMTAgLSAxMSBvbmx5XG5cdFx0XHQvLyBPcGVyYSAxMC0xMSBkb2VzIG5vdCB0aHJvdyBvbiBwb3N0LWNvbW1hIGludmFsaWQgcHNldWRvc1xuXHRcdFx0ZWwucXVlcnlTZWxlY3RvckFsbCggXCIqLDp4XCIgKTtcblx0XHRcdHJidWdneVFTQS5wdXNoKCBcIiwuKjpcIiApO1xuXHRcdH0gKTtcblx0fVxuXG5cdGlmICggKCBzdXBwb3J0Lm1hdGNoZXNTZWxlY3RvciA9IHJuYXRpdmUudGVzdCggKCBtYXRjaGVzID0gZG9jRWxlbS5tYXRjaGVzIHx8XG5cdFx0ZG9jRWxlbS53ZWJraXRNYXRjaGVzU2VsZWN0b3IgfHxcblx0XHRkb2NFbGVtLm1vek1hdGNoZXNTZWxlY3RvciB8fFxuXHRcdGRvY0VsZW0ub01hdGNoZXNTZWxlY3RvciB8fFxuXHRcdGRvY0VsZW0ubXNNYXRjaGVzU2VsZWN0b3IgKSApICkgKSB7XG5cblx0XHRhc3NlcnQoIGZ1bmN0aW9uKCBlbCApIHtcblxuXHRcdFx0Ly8gQ2hlY2sgdG8gc2VlIGlmIGl0J3MgcG9zc2libGUgdG8gZG8gbWF0Y2hlc1NlbGVjdG9yXG5cdFx0XHQvLyBvbiBhIGRpc2Nvbm5lY3RlZCBub2RlIChJRSA5KVxuXHRcdFx0c3VwcG9ydC5kaXNjb25uZWN0ZWRNYXRjaCA9IG1hdGNoZXMuY2FsbCggZWwsIFwiKlwiICk7XG5cblx0XHRcdC8vIFRoaXMgc2hvdWxkIGZhaWwgd2l0aCBhbiBleGNlcHRpb25cblx0XHRcdC8vIEdlY2tvIGRvZXMgbm90IGVycm9yLCByZXR1cm5zIGZhbHNlIGluc3RlYWRcblx0XHRcdG1hdGNoZXMuY2FsbCggZWwsIFwiW3MhPScnXTp4XCIgKTtcblx0XHRcdHJidWdneU1hdGNoZXMucHVzaCggXCIhPVwiLCBwc2V1ZG9zICk7XG5cdFx0fSApO1xuXHR9XG5cblx0cmJ1Z2d5UVNBID0gcmJ1Z2d5UVNBLmxlbmd0aCAmJiBuZXcgUmVnRXhwKCByYnVnZ3lRU0Euam9pbiggXCJ8XCIgKSApO1xuXHRyYnVnZ3lNYXRjaGVzID0gcmJ1Z2d5TWF0Y2hlcy5sZW5ndGggJiYgbmV3IFJlZ0V4cCggcmJ1Z2d5TWF0Y2hlcy5qb2luKCBcInxcIiApICk7XG5cblx0LyogQ29udGFpbnNcblx0LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXHRoYXNDb21wYXJlID0gcm5hdGl2ZS50ZXN0KCBkb2NFbGVtLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uICk7XG5cblx0Ly8gRWxlbWVudCBjb250YWlucyBhbm90aGVyXG5cdC8vIFB1cnBvc2VmdWxseSBzZWxmLWV4Y2x1c2l2ZVxuXHQvLyBBcyBpbiwgYW4gZWxlbWVudCBkb2VzIG5vdCBjb250YWluIGl0c2VsZlxuXHRjb250YWlucyA9IGhhc0NvbXBhcmUgfHwgcm5hdGl2ZS50ZXN0KCBkb2NFbGVtLmNvbnRhaW5zICkgP1xuXHRcdGZ1bmN0aW9uKCBhLCBiICkge1xuXHRcdFx0dmFyIGFkb3duID0gYS5ub2RlVHlwZSA9PT0gOSA/IGEuZG9jdW1lbnRFbGVtZW50IDogYSxcblx0XHRcdFx0YnVwID0gYiAmJiBiLnBhcmVudE5vZGU7XG5cdFx0XHRyZXR1cm4gYSA9PT0gYnVwIHx8ICEhKCBidXAgJiYgYnVwLm5vZGVUeXBlID09PSAxICYmIChcblx0XHRcdFx0YWRvd24uY29udGFpbnMgP1xuXHRcdFx0XHRcdGFkb3duLmNvbnRhaW5zKCBidXAgKSA6XG5cdFx0XHRcdFx0YS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbiAmJiBhLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKCBidXAgKSAmIDE2XG5cdFx0XHQpICk7XG5cdFx0fSA6XG5cdFx0ZnVuY3Rpb24oIGEsIGIgKSB7XG5cdFx0XHRpZiAoIGIgKSB7XG5cdFx0XHRcdHdoaWxlICggKCBiID0gYi5wYXJlbnROb2RlICkgKSB7XG5cdFx0XHRcdFx0aWYgKCBiID09PSBhICkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fTtcblxuXHQvKiBTb3J0aW5nXG5cdC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cblxuXHQvLyBEb2N1bWVudCBvcmRlciBzb3J0aW5nXG5cdHNvcnRPcmRlciA9IGhhc0NvbXBhcmUgP1xuXHRmdW5jdGlvbiggYSwgYiApIHtcblxuXHRcdC8vIEZsYWcgZm9yIGR1cGxpY2F0ZSByZW1vdmFsXG5cdFx0aWYgKCBhID09PSBiICkge1xuXHRcdFx0aGFzRHVwbGljYXRlID0gdHJ1ZTtcblx0XHRcdHJldHVybiAwO1xuXHRcdH1cblxuXHRcdC8vIFNvcnQgb24gbWV0aG9kIGV4aXN0ZW5jZSBpZiBvbmx5IG9uZSBpbnB1dCBoYXMgY29tcGFyZURvY3VtZW50UG9zaXRpb25cblx0XHR2YXIgY29tcGFyZSA9ICFhLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uIC0gIWIuY29tcGFyZURvY3VtZW50UG9zaXRpb247XG5cdFx0aWYgKCBjb21wYXJlICkge1xuXHRcdFx0cmV0dXJuIGNvbXBhcmU7XG5cdFx0fVxuXG5cdFx0Ly8gQ2FsY3VsYXRlIHBvc2l0aW9uIGlmIGJvdGggaW5wdXRzIGJlbG9uZyB0byB0aGUgc2FtZSBkb2N1bWVudFxuXHRcdC8vIFN1cHBvcnQ6IElFIDExKywgRWRnZSAxNyAtIDE4K1xuXHRcdC8vIElFL0VkZ2Ugc29tZXRpbWVzIHRocm93IGEgXCJQZXJtaXNzaW9uIGRlbmllZFwiIGVycm9yIHdoZW4gc3RyaWN0LWNvbXBhcmluZ1xuXHRcdC8vIHR3byBkb2N1bWVudHM7IHNoYWxsb3cgY29tcGFyaXNvbnMgd29yay5cblx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZXFlcWVxXG5cdFx0Y29tcGFyZSA9ICggYS5vd25lckRvY3VtZW50IHx8IGEgKSA9PSAoIGIub3duZXJEb2N1bWVudCB8fCBiICkgP1xuXHRcdFx0YS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbiggYiApIDpcblxuXHRcdFx0Ly8gT3RoZXJ3aXNlIHdlIGtub3cgdGhleSBhcmUgZGlzY29ubmVjdGVkXG5cdFx0XHQxO1xuXG5cdFx0Ly8gRGlzY29ubmVjdGVkIG5vZGVzXG5cdFx0aWYgKCBjb21wYXJlICYgMSB8fFxuXHRcdFx0KCAhc3VwcG9ydC5zb3J0RGV0YWNoZWQgJiYgYi5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbiggYSApID09PSBjb21wYXJlICkgKSB7XG5cblx0XHRcdC8vIENob29zZSB0aGUgZmlyc3QgZWxlbWVudCB0aGF0IGlzIHJlbGF0ZWQgdG8gb3VyIHByZWZlcnJlZCBkb2N1bWVudFxuXHRcdFx0Ly8gU3VwcG9ydDogSUUgMTErLCBFZGdlIDE3IC0gMTgrXG5cdFx0XHQvLyBJRS9FZGdlIHNvbWV0aW1lcyB0aHJvdyBhIFwiUGVybWlzc2lvbiBkZW5pZWRcIiBlcnJvciB3aGVuIHN0cmljdC1jb21wYXJpbmdcblx0XHRcdC8vIHR3byBkb2N1bWVudHM7IHNoYWxsb3cgY29tcGFyaXNvbnMgd29yay5cblx0XHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBlcWVxZXFcblx0XHRcdGlmICggYSA9PSBkb2N1bWVudCB8fCBhLm93bmVyRG9jdW1lbnQgPT0gcHJlZmVycmVkRG9jICYmXG5cdFx0XHRcdGNvbnRhaW5zKCBwcmVmZXJyZWREb2MsIGEgKSApIHtcblx0XHRcdFx0cmV0dXJuIC0xO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBTdXBwb3J0OiBJRSAxMSssIEVkZ2UgMTcgLSAxOCtcblx0XHRcdC8vIElFL0VkZ2Ugc29tZXRpbWVzIHRocm93IGEgXCJQZXJtaXNzaW9uIGRlbmllZFwiIGVycm9yIHdoZW4gc3RyaWN0LWNvbXBhcmluZ1xuXHRcdFx0Ly8gdHdvIGRvY3VtZW50czsgc2hhbGxvdyBjb21wYXJpc29ucyB3b3JrLlxuXHRcdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGVxZXFlcVxuXHRcdFx0aWYgKCBiID09IGRvY3VtZW50IHx8IGIub3duZXJEb2N1bWVudCA9PSBwcmVmZXJyZWREb2MgJiZcblx0XHRcdFx0Y29udGFpbnMoIHByZWZlcnJlZERvYywgYiApICkge1xuXHRcdFx0XHRyZXR1cm4gMTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gTWFpbnRhaW4gb3JpZ2luYWwgb3JkZXJcblx0XHRcdHJldHVybiBzb3J0SW5wdXQgP1xuXHRcdFx0XHQoIGluZGV4T2YoIHNvcnRJbnB1dCwgYSApIC0gaW5kZXhPZiggc29ydElucHV0LCBiICkgKSA6XG5cdFx0XHRcdDA7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGNvbXBhcmUgJiA0ID8gLTEgOiAxO1xuXHR9IDpcblx0ZnVuY3Rpb24oIGEsIGIgKSB7XG5cblx0XHQvLyBFeGl0IGVhcmx5IGlmIHRoZSBub2RlcyBhcmUgaWRlbnRpY2FsXG5cdFx0aWYgKCBhID09PSBiICkge1xuXHRcdFx0aGFzRHVwbGljYXRlID0gdHJ1ZTtcblx0XHRcdHJldHVybiAwO1xuXHRcdH1cblxuXHRcdHZhciBjdXIsXG5cdFx0XHRpID0gMCxcblx0XHRcdGF1cCA9IGEucGFyZW50Tm9kZSxcblx0XHRcdGJ1cCA9IGIucGFyZW50Tm9kZSxcblx0XHRcdGFwID0gWyBhIF0sXG5cdFx0XHRicCA9IFsgYiBdO1xuXG5cdFx0Ly8gUGFyZW50bGVzcyBub2RlcyBhcmUgZWl0aGVyIGRvY3VtZW50cyBvciBkaXNjb25uZWN0ZWRcblx0XHRpZiAoICFhdXAgfHwgIWJ1cCApIHtcblxuXHRcdFx0Ly8gU3VwcG9ydDogSUUgMTErLCBFZGdlIDE3IC0gMTgrXG5cdFx0XHQvLyBJRS9FZGdlIHNvbWV0aW1lcyB0aHJvdyBhIFwiUGVybWlzc2lvbiBkZW5pZWRcIiBlcnJvciB3aGVuIHN0cmljdC1jb21wYXJpbmdcblx0XHRcdC8vIHR3byBkb2N1bWVudHM7IHNoYWxsb3cgY29tcGFyaXNvbnMgd29yay5cblx0XHRcdC8qIGVzbGludC1kaXNhYmxlIGVxZXFlcSAqL1xuXHRcdFx0cmV0dXJuIGEgPT0gZG9jdW1lbnQgPyAtMSA6XG5cdFx0XHRcdGIgPT0gZG9jdW1lbnQgPyAxIDpcblx0XHRcdFx0LyogZXNsaW50LWVuYWJsZSBlcWVxZXEgKi9cblx0XHRcdFx0YXVwID8gLTEgOlxuXHRcdFx0XHRidXAgPyAxIDpcblx0XHRcdFx0c29ydElucHV0ID9cblx0XHRcdFx0KCBpbmRleE9mKCBzb3J0SW5wdXQsIGEgKSAtIGluZGV4T2YoIHNvcnRJbnB1dCwgYiApICkgOlxuXHRcdFx0XHQwO1xuXG5cdFx0Ly8gSWYgdGhlIG5vZGVzIGFyZSBzaWJsaW5ncywgd2UgY2FuIGRvIGEgcXVpY2sgY2hlY2tcblx0XHR9IGVsc2UgaWYgKCBhdXAgPT09IGJ1cCApIHtcblx0XHRcdHJldHVybiBzaWJsaW5nQ2hlY2soIGEsIGIgKTtcblx0XHR9XG5cblx0XHQvLyBPdGhlcndpc2Ugd2UgbmVlZCBmdWxsIGxpc3RzIG9mIHRoZWlyIGFuY2VzdG9ycyBmb3IgY29tcGFyaXNvblxuXHRcdGN1ciA9IGE7XG5cdFx0d2hpbGUgKCAoIGN1ciA9IGN1ci5wYXJlbnROb2RlICkgKSB7XG5cdFx0XHRhcC51bnNoaWZ0KCBjdXIgKTtcblx0XHR9XG5cdFx0Y3VyID0gYjtcblx0XHR3aGlsZSAoICggY3VyID0gY3VyLnBhcmVudE5vZGUgKSApIHtcblx0XHRcdGJwLnVuc2hpZnQoIGN1ciApO1xuXHRcdH1cblxuXHRcdC8vIFdhbGsgZG93biB0aGUgdHJlZSBsb29raW5nIGZvciBhIGRpc2NyZXBhbmN5XG5cdFx0d2hpbGUgKCBhcFsgaSBdID09PSBicFsgaSBdICkge1xuXHRcdFx0aSsrO1xuXHRcdH1cblxuXHRcdHJldHVybiBpID9cblxuXHRcdFx0Ly8gRG8gYSBzaWJsaW5nIGNoZWNrIGlmIHRoZSBub2RlcyBoYXZlIGEgY29tbW9uIGFuY2VzdG9yXG5cdFx0XHRzaWJsaW5nQ2hlY2soIGFwWyBpIF0sIGJwWyBpIF0gKSA6XG5cblx0XHRcdC8vIE90aGVyd2lzZSBub2RlcyBpbiBvdXIgZG9jdW1lbnQgc29ydCBmaXJzdFxuXHRcdFx0Ly8gU3VwcG9ydDogSUUgMTErLCBFZGdlIDE3IC0gMTgrXG5cdFx0XHQvLyBJRS9FZGdlIHNvbWV0aW1lcyB0aHJvdyBhIFwiUGVybWlzc2lvbiBkZW5pZWRcIiBlcnJvciB3aGVuIHN0cmljdC1jb21wYXJpbmdcblx0XHRcdC8vIHR3byBkb2N1bWVudHM7IHNoYWxsb3cgY29tcGFyaXNvbnMgd29yay5cblx0XHRcdC8qIGVzbGludC1kaXNhYmxlIGVxZXFlcSAqL1xuXHRcdFx0YXBbIGkgXSA9PSBwcmVmZXJyZWREb2MgPyAtMSA6XG5cdFx0XHRicFsgaSBdID09IHByZWZlcnJlZERvYyA/IDEgOlxuXHRcdFx0LyogZXNsaW50LWVuYWJsZSBlcWVxZXEgKi9cblx0XHRcdDA7XG5cdH07XG5cblx0cmV0dXJuIGRvY3VtZW50O1xufTtcblxuU2l6emxlLm1hdGNoZXMgPSBmdW5jdGlvbiggZXhwciwgZWxlbWVudHMgKSB7XG5cdHJldHVybiBTaXp6bGUoIGV4cHIsIG51bGwsIG51bGwsIGVsZW1lbnRzICk7XG59O1xuXG5TaXp6bGUubWF0Y2hlc1NlbGVjdG9yID0gZnVuY3Rpb24oIGVsZW0sIGV4cHIgKSB7XG5cdHNldERvY3VtZW50KCBlbGVtICk7XG5cblx0aWYgKCBzdXBwb3J0Lm1hdGNoZXNTZWxlY3RvciAmJiBkb2N1bWVudElzSFRNTCAmJlxuXHRcdCFub25uYXRpdmVTZWxlY3RvckNhY2hlWyBleHByICsgXCIgXCIgXSAmJlxuXHRcdCggIXJidWdneU1hdGNoZXMgfHwgIXJidWdneU1hdGNoZXMudGVzdCggZXhwciApICkgJiZcblx0XHQoICFyYnVnZ3lRU0EgICAgIHx8ICFyYnVnZ3lRU0EudGVzdCggZXhwciApICkgKSB7XG5cblx0XHR0cnkge1xuXHRcdFx0dmFyIHJldCA9IG1hdGNoZXMuY2FsbCggZWxlbSwgZXhwciApO1xuXG5cdFx0XHQvLyBJRSA5J3MgbWF0Y2hlc1NlbGVjdG9yIHJldHVybnMgZmFsc2Ugb24gZGlzY29ubmVjdGVkIG5vZGVzXG5cdFx0XHRpZiAoIHJldCB8fCBzdXBwb3J0LmRpc2Nvbm5lY3RlZE1hdGNoIHx8XG5cblx0XHRcdFx0Ly8gQXMgd2VsbCwgZGlzY29ubmVjdGVkIG5vZGVzIGFyZSBzYWlkIHRvIGJlIGluIGEgZG9jdW1lbnRcblx0XHRcdFx0Ly8gZnJhZ21lbnQgaW4gSUUgOVxuXHRcdFx0XHRlbGVtLmRvY3VtZW50ICYmIGVsZW0uZG9jdW1lbnQubm9kZVR5cGUgIT09IDExICkge1xuXHRcdFx0XHRyZXR1cm4gcmV0O1xuXHRcdFx0fVxuXHRcdH0gY2F0Y2ggKCBlICkge1xuXHRcdFx0bm9ubmF0aXZlU2VsZWN0b3JDYWNoZSggZXhwciwgdHJ1ZSApO1xuXHRcdH1cblx0fVxuXG5cdHJldHVybiBTaXp6bGUoIGV4cHIsIGRvY3VtZW50LCBudWxsLCBbIGVsZW0gXSApLmxlbmd0aCA+IDA7XG59O1xuXG5TaXp6bGUuY29udGFpbnMgPSBmdW5jdGlvbiggY29udGV4dCwgZWxlbSApIHtcblxuXHQvLyBTZXQgZG9jdW1lbnQgdmFycyBpZiBuZWVkZWRcblx0Ly8gU3VwcG9ydDogSUUgMTErLCBFZGdlIDE3IC0gMTgrXG5cdC8vIElFL0VkZ2Ugc29tZXRpbWVzIHRocm93IGEgXCJQZXJtaXNzaW9uIGRlbmllZFwiIGVycm9yIHdoZW4gc3RyaWN0LWNvbXBhcmluZ1xuXHQvLyB0d28gZG9jdW1lbnRzOyBzaGFsbG93IGNvbXBhcmlzb25zIHdvcmsuXG5cdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBlcWVxZXFcblx0aWYgKCAoIGNvbnRleHQub3duZXJEb2N1bWVudCB8fCBjb250ZXh0ICkgIT0gZG9jdW1lbnQgKSB7XG5cdFx0c2V0RG9jdW1lbnQoIGNvbnRleHQgKTtcblx0fVxuXHRyZXR1cm4gY29udGFpbnMoIGNvbnRleHQsIGVsZW0gKTtcbn07XG5cblNpenpsZS5hdHRyID0gZnVuY3Rpb24oIGVsZW0sIG5hbWUgKSB7XG5cblx0Ly8gU2V0IGRvY3VtZW50IHZhcnMgaWYgbmVlZGVkXG5cdC8vIFN1cHBvcnQ6IElFIDExKywgRWRnZSAxNyAtIDE4K1xuXHQvLyBJRS9FZGdlIHNvbWV0aW1lcyB0aHJvdyBhIFwiUGVybWlzc2lvbiBkZW5pZWRcIiBlcnJvciB3aGVuIHN0cmljdC1jb21wYXJpbmdcblx0Ly8gdHdvIGRvY3VtZW50czsgc2hhbGxvdyBjb21wYXJpc29ucyB3b3JrLlxuXHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZXFlcWVxXG5cdGlmICggKCBlbGVtLm93bmVyRG9jdW1lbnQgfHwgZWxlbSApICE9IGRvY3VtZW50ICkge1xuXHRcdHNldERvY3VtZW50KCBlbGVtICk7XG5cdH1cblxuXHR2YXIgZm4gPSBFeHByLmF0dHJIYW5kbGVbIG5hbWUudG9Mb3dlckNhc2UoKSBdLFxuXG5cdFx0Ly8gRG9uJ3QgZ2V0IGZvb2xlZCBieSBPYmplY3QucHJvdG90eXBlIHByb3BlcnRpZXMgKGpRdWVyeSAjMTM4MDcpXG5cdFx0dmFsID0gZm4gJiYgaGFzT3duLmNhbGwoIEV4cHIuYXR0ckhhbmRsZSwgbmFtZS50b0xvd2VyQ2FzZSgpICkgP1xuXHRcdFx0Zm4oIGVsZW0sIG5hbWUsICFkb2N1bWVudElzSFRNTCApIDpcblx0XHRcdHVuZGVmaW5lZDtcblxuXHRyZXR1cm4gdmFsICE9PSB1bmRlZmluZWQgP1xuXHRcdHZhbCA6XG5cdFx0c3VwcG9ydC5hdHRyaWJ1dGVzIHx8ICFkb2N1bWVudElzSFRNTCA/XG5cdFx0XHRlbGVtLmdldEF0dHJpYnV0ZSggbmFtZSApIDpcblx0XHRcdCggdmFsID0gZWxlbS5nZXRBdHRyaWJ1dGVOb2RlKCBuYW1lICkgKSAmJiB2YWwuc3BlY2lmaWVkID9cblx0XHRcdFx0dmFsLnZhbHVlIDpcblx0XHRcdFx0bnVsbDtcbn07XG5cblNpenpsZS5lc2NhcGUgPSBmdW5jdGlvbiggc2VsICkge1xuXHRyZXR1cm4gKCBzZWwgKyBcIlwiICkucmVwbGFjZSggcmNzc2VzY2FwZSwgZmNzc2VzY2FwZSApO1xufTtcblxuU2l6emxlLmVycm9yID0gZnVuY3Rpb24oIG1zZyApIHtcblx0dGhyb3cgbmV3IEVycm9yKCBcIlN5bnRheCBlcnJvciwgdW5yZWNvZ25pemVkIGV4cHJlc3Npb246IFwiICsgbXNnICk7XG59O1xuXG4vKipcbiAqIERvY3VtZW50IHNvcnRpbmcgYW5kIHJlbW92aW5nIGR1cGxpY2F0ZXNcbiAqIEBwYXJhbSB7QXJyYXlMaWtlfSByZXN1bHRzXG4gKi9cblNpenpsZS51bmlxdWVTb3J0ID0gZnVuY3Rpb24oIHJlc3VsdHMgKSB7XG5cdHZhciBlbGVtLFxuXHRcdGR1cGxpY2F0ZXMgPSBbXSxcblx0XHRqID0gMCxcblx0XHRpID0gMDtcblxuXHQvLyBVbmxlc3Mgd2UgKmtub3cqIHdlIGNhbiBkZXRlY3QgZHVwbGljYXRlcywgYXNzdW1lIHRoZWlyIHByZXNlbmNlXG5cdGhhc0R1cGxpY2F0ZSA9ICFzdXBwb3J0LmRldGVjdER1cGxpY2F0ZXM7XG5cdHNvcnRJbnB1dCA9ICFzdXBwb3J0LnNvcnRTdGFibGUgJiYgcmVzdWx0cy5zbGljZSggMCApO1xuXHRyZXN1bHRzLnNvcnQoIHNvcnRPcmRlciApO1xuXG5cdGlmICggaGFzRHVwbGljYXRlICkge1xuXHRcdHdoaWxlICggKCBlbGVtID0gcmVzdWx0c1sgaSsrIF0gKSApIHtcblx0XHRcdGlmICggZWxlbSA9PT0gcmVzdWx0c1sgaSBdICkge1xuXHRcdFx0XHRqID0gZHVwbGljYXRlcy5wdXNoKCBpICk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHdoaWxlICggai0tICkge1xuXHRcdFx0cmVzdWx0cy5zcGxpY2UoIGR1cGxpY2F0ZXNbIGogXSwgMSApO1xuXHRcdH1cblx0fVxuXG5cdC8vIENsZWFyIGlucHV0IGFmdGVyIHNvcnRpbmcgdG8gcmVsZWFzZSBvYmplY3RzXG5cdC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vanF1ZXJ5L3NpenpsZS9wdWxsLzIyNVxuXHRzb3J0SW5wdXQgPSBudWxsO1xuXG5cdHJldHVybiByZXN1bHRzO1xufTtcblxuLyoqXG4gKiBVdGlsaXR5IGZ1bmN0aW9uIGZvciByZXRyaWV2aW5nIHRoZSB0ZXh0IHZhbHVlIG9mIGFuIGFycmF5IG9mIERPTSBub2Rlc1xuICogQHBhcmFtIHtBcnJheXxFbGVtZW50fSBlbGVtXG4gKi9cbmdldFRleHQgPSBTaXp6bGUuZ2V0VGV4dCA9IGZ1bmN0aW9uKCBlbGVtICkge1xuXHR2YXIgbm9kZSxcblx0XHRyZXQgPSBcIlwiLFxuXHRcdGkgPSAwLFxuXHRcdG5vZGVUeXBlID0gZWxlbS5ub2RlVHlwZTtcblxuXHRpZiAoICFub2RlVHlwZSApIHtcblxuXHRcdC8vIElmIG5vIG5vZGVUeXBlLCB0aGlzIGlzIGV4cGVjdGVkIHRvIGJlIGFuIGFycmF5XG5cdFx0d2hpbGUgKCAoIG5vZGUgPSBlbGVtWyBpKysgXSApICkge1xuXG5cdFx0XHQvLyBEbyBub3QgdHJhdmVyc2UgY29tbWVudCBub2Rlc1xuXHRcdFx0cmV0ICs9IGdldFRleHQoIG5vZGUgKTtcblx0XHR9XG5cdH0gZWxzZSBpZiAoIG5vZGVUeXBlID09PSAxIHx8IG5vZGVUeXBlID09PSA5IHx8IG5vZGVUeXBlID09PSAxMSApIHtcblxuXHRcdC8vIFVzZSB0ZXh0Q29udGVudCBmb3IgZWxlbWVudHNcblx0XHQvLyBpbm5lclRleHQgdXNhZ2UgcmVtb3ZlZCBmb3IgY29uc2lzdGVuY3kgb2YgbmV3IGxpbmVzIChqUXVlcnkgIzExMTUzKVxuXHRcdGlmICggdHlwZW9mIGVsZW0udGV4dENvbnRlbnQgPT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHRyZXR1cm4gZWxlbS50ZXh0Q29udGVudDtcblx0XHR9IGVsc2Uge1xuXG5cdFx0XHQvLyBUcmF2ZXJzZSBpdHMgY2hpbGRyZW5cblx0XHRcdGZvciAoIGVsZW0gPSBlbGVtLmZpcnN0Q2hpbGQ7IGVsZW07IGVsZW0gPSBlbGVtLm5leHRTaWJsaW5nICkge1xuXHRcdFx0XHRyZXQgKz0gZ2V0VGV4dCggZWxlbSApO1xuXHRcdFx0fVxuXHRcdH1cblx0fSBlbHNlIGlmICggbm9kZVR5cGUgPT09IDMgfHwgbm9kZVR5cGUgPT09IDQgKSB7XG5cdFx0cmV0dXJuIGVsZW0ubm9kZVZhbHVlO1xuXHR9XG5cblx0Ly8gRG8gbm90IGluY2x1ZGUgY29tbWVudCBvciBwcm9jZXNzaW5nIGluc3RydWN0aW9uIG5vZGVzXG5cblx0cmV0dXJuIHJldDtcbn07XG5cbkV4cHIgPSBTaXp6bGUuc2VsZWN0b3JzID0ge1xuXG5cdC8vIENhbiBiZSBhZGp1c3RlZCBieSB0aGUgdXNlclxuXHRjYWNoZUxlbmd0aDogNTAsXG5cblx0Y3JlYXRlUHNldWRvOiBtYXJrRnVuY3Rpb24sXG5cblx0bWF0Y2g6IG1hdGNoRXhwcixcblxuXHRhdHRySGFuZGxlOiB7fSxcblxuXHRmaW5kOiB7fSxcblxuXHRyZWxhdGl2ZToge1xuXHRcdFwiPlwiOiB7IGRpcjogXCJwYXJlbnROb2RlXCIsIGZpcnN0OiB0cnVlIH0sXG5cdFx0XCIgXCI6IHsgZGlyOiBcInBhcmVudE5vZGVcIiB9LFxuXHRcdFwiK1wiOiB7IGRpcjogXCJwcmV2aW91c1NpYmxpbmdcIiwgZmlyc3Q6IHRydWUgfSxcblx0XHRcIn5cIjogeyBkaXI6IFwicHJldmlvdXNTaWJsaW5nXCIgfVxuXHR9LFxuXG5cdHByZUZpbHRlcjoge1xuXHRcdFwiQVRUUlwiOiBmdW5jdGlvbiggbWF0Y2ggKSB7XG5cdFx0XHRtYXRjaFsgMSBdID0gbWF0Y2hbIDEgXS5yZXBsYWNlKCBydW5lc2NhcGUsIGZ1bmVzY2FwZSApO1xuXG5cdFx0XHQvLyBNb3ZlIHRoZSBnaXZlbiB2YWx1ZSB0byBtYXRjaFszXSB3aGV0aGVyIHF1b3RlZCBvciB1bnF1b3RlZFxuXHRcdFx0bWF0Y2hbIDMgXSA9ICggbWF0Y2hbIDMgXSB8fCBtYXRjaFsgNCBdIHx8XG5cdFx0XHRcdG1hdGNoWyA1IF0gfHwgXCJcIiApLnJlcGxhY2UoIHJ1bmVzY2FwZSwgZnVuZXNjYXBlICk7XG5cblx0XHRcdGlmICggbWF0Y2hbIDIgXSA9PT0gXCJ+PVwiICkge1xuXHRcdFx0XHRtYXRjaFsgMyBdID0gXCIgXCIgKyBtYXRjaFsgMyBdICsgXCIgXCI7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBtYXRjaC5zbGljZSggMCwgNCApO1xuXHRcdH0sXG5cblx0XHRcIkNISUxEXCI6IGZ1bmN0aW9uKCBtYXRjaCApIHtcblxuXHRcdFx0LyogbWF0Y2hlcyBmcm9tIG1hdGNoRXhwcltcIkNISUxEXCJdXG5cdFx0XHRcdDEgdHlwZSAob25seXxudGh8Li4uKVxuXHRcdFx0XHQyIHdoYXQgKGNoaWxkfG9mLXR5cGUpXG5cdFx0XHRcdDMgYXJndW1lbnQgKGV2ZW58b2RkfFxcZCp8XFxkKm4oWystXVxcZCspP3wuLi4pXG5cdFx0XHRcdDQgeG4tY29tcG9uZW50IG9mIHhuK3kgYXJndW1lbnQgKFsrLV0/XFxkKm58KVxuXHRcdFx0XHQ1IHNpZ24gb2YgeG4tY29tcG9uZW50XG5cdFx0XHRcdDYgeCBvZiB4bi1jb21wb25lbnRcblx0XHRcdFx0NyBzaWduIG9mIHktY29tcG9uZW50XG5cdFx0XHRcdDggeSBvZiB5LWNvbXBvbmVudFxuXHRcdFx0Ki9cblx0XHRcdG1hdGNoWyAxIF0gPSBtYXRjaFsgMSBdLnRvTG93ZXJDYXNlKCk7XG5cblx0XHRcdGlmICggbWF0Y2hbIDEgXS5zbGljZSggMCwgMyApID09PSBcIm50aFwiICkge1xuXG5cdFx0XHRcdC8vIG50aC0qIHJlcXVpcmVzIGFyZ3VtZW50XG5cdFx0XHRcdGlmICggIW1hdGNoWyAzIF0gKSB7XG5cdFx0XHRcdFx0U2l6emxlLmVycm9yKCBtYXRjaFsgMCBdICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBudW1lcmljIHggYW5kIHkgcGFyYW1ldGVycyBmb3IgRXhwci5maWx0ZXIuQ0hJTERcblx0XHRcdFx0Ly8gcmVtZW1iZXIgdGhhdCBmYWxzZS90cnVlIGNhc3QgcmVzcGVjdGl2ZWx5IHRvIDAvMVxuXHRcdFx0XHRtYXRjaFsgNCBdID0gKyggbWF0Y2hbIDQgXSA/XG5cdFx0XHRcdFx0bWF0Y2hbIDUgXSArICggbWF0Y2hbIDYgXSB8fCAxICkgOlxuXHRcdFx0XHRcdDIgKiAoIG1hdGNoWyAzIF0gPT09IFwiZXZlblwiIHx8IG1hdGNoWyAzIF0gPT09IFwib2RkXCIgKSApO1xuXHRcdFx0XHRtYXRjaFsgNSBdID0gKyggKCBtYXRjaFsgNyBdICsgbWF0Y2hbIDggXSApIHx8IG1hdGNoWyAzIF0gPT09IFwib2RkXCIgKTtcblxuXHRcdFx0XHQvLyBvdGhlciB0eXBlcyBwcm9oaWJpdCBhcmd1bWVudHNcblx0XHRcdH0gZWxzZSBpZiAoIG1hdGNoWyAzIF0gKSB7XG5cdFx0XHRcdFNpenpsZS5lcnJvciggbWF0Y2hbIDAgXSApO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gbWF0Y2g7XG5cdFx0fSxcblxuXHRcdFwiUFNFVURPXCI6IGZ1bmN0aW9uKCBtYXRjaCApIHtcblx0XHRcdHZhciBleGNlc3MsXG5cdFx0XHRcdHVucXVvdGVkID0gIW1hdGNoWyA2IF0gJiYgbWF0Y2hbIDIgXTtcblxuXHRcdFx0aWYgKCBtYXRjaEV4cHJbIFwiQ0hJTERcIiBdLnRlc3QoIG1hdGNoWyAwIF0gKSApIHtcblx0XHRcdFx0cmV0dXJuIG51bGw7XG5cdFx0XHR9XG5cblx0XHRcdC8vIEFjY2VwdCBxdW90ZWQgYXJndW1lbnRzIGFzLWlzXG5cdFx0XHRpZiAoIG1hdGNoWyAzIF0gKSB7XG5cdFx0XHRcdG1hdGNoWyAyIF0gPSBtYXRjaFsgNCBdIHx8IG1hdGNoWyA1IF0gfHwgXCJcIjtcblxuXHRcdFx0Ly8gU3RyaXAgZXhjZXNzIGNoYXJhY3RlcnMgZnJvbSB1bnF1b3RlZCBhcmd1bWVudHNcblx0XHRcdH0gZWxzZSBpZiAoIHVucXVvdGVkICYmIHJwc2V1ZG8udGVzdCggdW5xdW90ZWQgKSAmJlxuXG5cdFx0XHRcdC8vIEdldCBleGNlc3MgZnJvbSB0b2tlbml6ZSAocmVjdXJzaXZlbHkpXG5cdFx0XHRcdCggZXhjZXNzID0gdG9rZW5pemUoIHVucXVvdGVkLCB0cnVlICkgKSAmJlxuXG5cdFx0XHRcdC8vIGFkdmFuY2UgdG8gdGhlIG5leHQgY2xvc2luZyBwYXJlbnRoZXNpc1xuXHRcdFx0XHQoIGV4Y2VzcyA9IHVucXVvdGVkLmluZGV4T2YoIFwiKVwiLCB1bnF1b3RlZC5sZW5ndGggLSBleGNlc3MgKSAtIHVucXVvdGVkLmxlbmd0aCApICkge1xuXG5cdFx0XHRcdC8vIGV4Y2VzcyBpcyBhIG5lZ2F0aXZlIGluZGV4XG5cdFx0XHRcdG1hdGNoWyAwIF0gPSBtYXRjaFsgMCBdLnNsaWNlKCAwLCBleGNlc3MgKTtcblx0XHRcdFx0bWF0Y2hbIDIgXSA9IHVucXVvdGVkLnNsaWNlKCAwLCBleGNlc3MgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gUmV0dXJuIG9ubHkgY2FwdHVyZXMgbmVlZGVkIGJ5IHRoZSBwc2V1ZG8gZmlsdGVyIG1ldGhvZCAodHlwZSBhbmQgYXJndW1lbnQpXG5cdFx0XHRyZXR1cm4gbWF0Y2guc2xpY2UoIDAsIDMgKTtcblx0XHR9XG5cdH0sXG5cblx0ZmlsdGVyOiB7XG5cblx0XHRcIlRBR1wiOiBmdW5jdGlvbiggbm9kZU5hbWVTZWxlY3RvciApIHtcblx0XHRcdHZhciBub2RlTmFtZSA9IG5vZGVOYW1lU2VsZWN0b3IucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKS50b0xvd2VyQ2FzZSgpO1xuXHRcdFx0cmV0dXJuIG5vZGVOYW1lU2VsZWN0b3IgPT09IFwiKlwiID9cblx0XHRcdFx0ZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHRcdH0gOlxuXHRcdFx0XHRmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdFx0XHRyZXR1cm4gZWxlbS5ub2RlTmFtZSAmJiBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgPT09IG5vZGVOYW1lO1xuXHRcdFx0XHR9O1xuXHRcdH0sXG5cblx0XHRcIkNMQVNTXCI6IGZ1bmN0aW9uKCBjbGFzc05hbWUgKSB7XG5cdFx0XHR2YXIgcGF0dGVybiA9IGNsYXNzQ2FjaGVbIGNsYXNzTmFtZSArIFwiIFwiIF07XG5cblx0XHRcdHJldHVybiBwYXR0ZXJuIHx8XG5cdFx0XHRcdCggcGF0dGVybiA9IG5ldyBSZWdFeHAoIFwiKF58XCIgKyB3aGl0ZXNwYWNlICtcblx0XHRcdFx0XHRcIilcIiArIGNsYXNzTmFtZSArIFwiKFwiICsgd2hpdGVzcGFjZSArIFwifCQpXCIgKSApICYmIGNsYXNzQ2FjaGUoXG5cdFx0XHRcdFx0XHRjbGFzc05hbWUsIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gcGF0dGVybi50ZXN0KFxuXHRcdFx0XHRcdFx0XHRcdHR5cGVvZiBlbGVtLmNsYXNzTmFtZSA9PT0gXCJzdHJpbmdcIiAmJiBlbGVtLmNsYXNzTmFtZSB8fFxuXHRcdFx0XHRcdFx0XHRcdHR5cGVvZiBlbGVtLmdldEF0dHJpYnV0ZSAhPT0gXCJ1bmRlZmluZWRcIiAmJlxuXHRcdFx0XHRcdFx0XHRcdFx0ZWxlbS5nZXRBdHRyaWJ1dGUoIFwiY2xhc3NcIiApIHx8XG5cdFx0XHRcdFx0XHRcdFx0XCJcIlxuXHRcdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHR9ICk7XG5cdFx0fSxcblxuXHRcdFwiQVRUUlwiOiBmdW5jdGlvbiggbmFtZSwgb3BlcmF0b3IsIGNoZWNrICkge1xuXHRcdFx0cmV0dXJuIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHR2YXIgcmVzdWx0ID0gU2l6emxlLmF0dHIoIGVsZW0sIG5hbWUgKTtcblxuXHRcdFx0XHRpZiAoIHJlc3VsdCA9PSBudWxsICkge1xuXHRcdFx0XHRcdHJldHVybiBvcGVyYXRvciA9PT0gXCIhPVwiO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlmICggIW9wZXJhdG9yICkge1xuXHRcdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmVzdWx0ICs9IFwiXCI7XG5cblx0XHRcdFx0LyogZXNsaW50LWRpc2FibGUgbWF4LWxlbiAqL1xuXG5cdFx0XHRcdHJldHVybiBvcGVyYXRvciA9PT0gXCI9XCIgPyByZXN1bHQgPT09IGNoZWNrIDpcblx0XHRcdFx0XHRvcGVyYXRvciA9PT0gXCIhPVwiID8gcmVzdWx0ICE9PSBjaGVjayA6XG5cdFx0XHRcdFx0b3BlcmF0b3IgPT09IFwiXj1cIiA/IGNoZWNrICYmIHJlc3VsdC5pbmRleE9mKCBjaGVjayApID09PSAwIDpcblx0XHRcdFx0XHRvcGVyYXRvciA9PT0gXCIqPVwiID8gY2hlY2sgJiYgcmVzdWx0LmluZGV4T2YoIGNoZWNrICkgPiAtMSA6XG5cdFx0XHRcdFx0b3BlcmF0b3IgPT09IFwiJD1cIiA/IGNoZWNrICYmIHJlc3VsdC5zbGljZSggLWNoZWNrLmxlbmd0aCApID09PSBjaGVjayA6XG5cdFx0XHRcdFx0b3BlcmF0b3IgPT09IFwifj1cIiA/ICggXCIgXCIgKyByZXN1bHQucmVwbGFjZSggcndoaXRlc3BhY2UsIFwiIFwiICkgKyBcIiBcIiApLmluZGV4T2YoIGNoZWNrICkgPiAtMSA6XG5cdFx0XHRcdFx0b3BlcmF0b3IgPT09IFwifD1cIiA/IHJlc3VsdCA9PT0gY2hlY2sgfHwgcmVzdWx0LnNsaWNlKCAwLCBjaGVjay5sZW5ndGggKyAxICkgPT09IGNoZWNrICsgXCItXCIgOlxuXHRcdFx0XHRcdGZhbHNlO1xuXHRcdFx0XHQvKiBlc2xpbnQtZW5hYmxlIG1heC1sZW4gKi9cblxuXHRcdFx0fTtcblx0XHR9LFxuXG5cdFx0XCJDSElMRFwiOiBmdW5jdGlvbiggdHlwZSwgd2hhdCwgX2FyZ3VtZW50LCBmaXJzdCwgbGFzdCApIHtcblx0XHRcdHZhciBzaW1wbGUgPSB0eXBlLnNsaWNlKCAwLCAzICkgIT09IFwibnRoXCIsXG5cdFx0XHRcdGZvcndhcmQgPSB0eXBlLnNsaWNlKCAtNCApICE9PSBcImxhc3RcIixcblx0XHRcdFx0b2ZUeXBlID0gd2hhdCA9PT0gXCJvZi10eXBlXCI7XG5cblx0XHRcdHJldHVybiBmaXJzdCA9PT0gMSAmJiBsYXN0ID09PSAwID9cblxuXHRcdFx0XHQvLyBTaG9ydGN1dCBmb3IgOm50aC0qKG4pXG5cdFx0XHRcdGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHRcdHJldHVybiAhIWVsZW0ucGFyZW50Tm9kZTtcblx0XHRcdFx0fSA6XG5cblx0XHRcdFx0ZnVuY3Rpb24oIGVsZW0sIF9jb250ZXh0LCB4bWwgKSB7XG5cdFx0XHRcdFx0dmFyIGNhY2hlLCB1bmlxdWVDYWNoZSwgb3V0ZXJDYWNoZSwgbm9kZSwgbm9kZUluZGV4LCBzdGFydCxcblx0XHRcdFx0XHRcdGRpciA9IHNpbXBsZSAhPT0gZm9yd2FyZCA/IFwibmV4dFNpYmxpbmdcIiA6IFwicHJldmlvdXNTaWJsaW5nXCIsXG5cdFx0XHRcdFx0XHRwYXJlbnQgPSBlbGVtLnBhcmVudE5vZGUsXG5cdFx0XHRcdFx0XHRuYW1lID0gb2ZUeXBlICYmIGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKSxcblx0XHRcdFx0XHRcdHVzZUNhY2hlID0gIXhtbCAmJiAhb2ZUeXBlLFxuXHRcdFx0XHRcdFx0ZGlmZiA9IGZhbHNlO1xuXG5cdFx0XHRcdFx0aWYgKCBwYXJlbnQgKSB7XG5cblx0XHRcdFx0XHRcdC8vIDooZmlyc3R8bGFzdHxvbmx5KS0oY2hpbGR8b2YtdHlwZSlcblx0XHRcdFx0XHRcdGlmICggc2ltcGxlICkge1xuXHRcdFx0XHRcdFx0XHR3aGlsZSAoIGRpciApIHtcblx0XHRcdFx0XHRcdFx0XHRub2RlID0gZWxlbTtcblx0XHRcdFx0XHRcdFx0XHR3aGlsZSAoICggbm9kZSA9IG5vZGVbIGRpciBdICkgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRpZiAoIG9mVHlwZSA/XG5cdFx0XHRcdFx0XHRcdFx0XHRcdG5vZGUubm9kZU5hbWUudG9Mb3dlckNhc2UoKSA9PT0gbmFtZSA6XG5cdFx0XHRcdFx0XHRcdFx0XHRcdG5vZGUubm9kZVR5cGUgPT09IDEgKSB7XG5cblx0XHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHRcdC8vIFJldmVyc2UgZGlyZWN0aW9uIGZvciA6b25seS0qIChpZiB3ZSBoYXZlbid0IHlldCBkb25lIHNvKVxuXHRcdFx0XHRcdFx0XHRcdHN0YXJ0ID0gZGlyID0gdHlwZSA9PT0gXCJvbmx5XCIgJiYgIXN0YXJ0ICYmIFwibmV4dFNpYmxpbmdcIjtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0c3RhcnQgPSBbIGZvcndhcmQgPyBwYXJlbnQuZmlyc3RDaGlsZCA6IHBhcmVudC5sYXN0Q2hpbGQgXTtcblxuXHRcdFx0XHRcdFx0Ly8gbm9uLXhtbCA6bnRoLWNoaWxkKC4uLikgc3RvcmVzIGNhY2hlIGRhdGEgb24gYHBhcmVudGBcblx0XHRcdFx0XHRcdGlmICggZm9yd2FyZCAmJiB1c2VDYWNoZSApIHtcblxuXHRcdFx0XHRcdFx0XHQvLyBTZWVrIGBlbGVtYCBmcm9tIGEgcHJldmlvdXNseS1jYWNoZWQgaW5kZXhcblxuXHRcdFx0XHRcdFx0XHQvLyAuLi5pbiBhIGd6aXAtZnJpZW5kbHkgd2F5XG5cdFx0XHRcdFx0XHRcdG5vZGUgPSBwYXJlbnQ7XG5cdFx0XHRcdFx0XHRcdG91dGVyQ2FjaGUgPSBub2RlWyBleHBhbmRvIF0gfHwgKCBub2RlWyBleHBhbmRvIF0gPSB7fSApO1xuXG5cdFx0XHRcdFx0XHRcdC8vIFN1cHBvcnQ6IElFIDw5IG9ubHlcblx0XHRcdFx0XHRcdFx0Ly8gRGVmZW5kIGFnYWluc3QgY2xvbmVkIGF0dHJvcGVydGllcyAoalF1ZXJ5IGdoLTE3MDkpXG5cdFx0XHRcdFx0XHRcdHVuaXF1ZUNhY2hlID0gb3V0ZXJDYWNoZVsgbm9kZS51bmlxdWVJRCBdIHx8XG5cdFx0XHRcdFx0XHRcdFx0KCBvdXRlckNhY2hlWyBub2RlLnVuaXF1ZUlEIF0gPSB7fSApO1xuXG5cdFx0XHRcdFx0XHRcdGNhY2hlID0gdW5pcXVlQ2FjaGVbIHR5cGUgXSB8fCBbXTtcblx0XHRcdFx0XHRcdFx0bm9kZUluZGV4ID0gY2FjaGVbIDAgXSA9PT0gZGlycnVucyAmJiBjYWNoZVsgMSBdO1xuXHRcdFx0XHRcdFx0XHRkaWZmID0gbm9kZUluZGV4ICYmIGNhY2hlWyAyIF07XG5cdFx0XHRcdFx0XHRcdG5vZGUgPSBub2RlSW5kZXggJiYgcGFyZW50LmNoaWxkTm9kZXNbIG5vZGVJbmRleCBdO1xuXG5cdFx0XHRcdFx0XHRcdHdoaWxlICggKCBub2RlID0gKytub2RlSW5kZXggJiYgbm9kZSAmJiBub2RlWyBkaXIgXSB8fFxuXG5cdFx0XHRcdFx0XHRcdFx0Ly8gRmFsbGJhY2sgdG8gc2Vla2luZyBgZWxlbWAgZnJvbSB0aGUgc3RhcnRcblx0XHRcdFx0XHRcdFx0XHQoIGRpZmYgPSBub2RlSW5kZXggPSAwICkgfHwgc3RhcnQucG9wKCkgKSApIHtcblxuXHRcdFx0XHRcdFx0XHRcdC8vIFdoZW4gZm91bmQsIGNhY2hlIGluZGV4ZXMgb24gYHBhcmVudGAgYW5kIGJyZWFrXG5cdFx0XHRcdFx0XHRcdFx0aWYgKCBub2RlLm5vZGVUeXBlID09PSAxICYmICsrZGlmZiAmJiBub2RlID09PSBlbGVtICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0dW5pcXVlQ2FjaGVbIHR5cGUgXSA9IFsgZGlycnVucywgbm9kZUluZGV4LCBkaWZmIF07XG5cdFx0XHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdFx0XHQvLyBVc2UgcHJldmlvdXNseS1jYWNoZWQgZWxlbWVudCBpbmRleCBpZiBhdmFpbGFibGVcblx0XHRcdFx0XHRcdFx0aWYgKCB1c2VDYWNoZSApIHtcblxuXHRcdFx0XHRcdFx0XHRcdC8vIC4uLmluIGEgZ3ppcC1mcmllbmRseSB3YXlcblx0XHRcdFx0XHRcdFx0XHRub2RlID0gZWxlbTtcblx0XHRcdFx0XHRcdFx0XHRvdXRlckNhY2hlID0gbm9kZVsgZXhwYW5kbyBdIHx8ICggbm9kZVsgZXhwYW5kbyBdID0ge30gKTtcblxuXHRcdFx0XHRcdFx0XHRcdC8vIFN1cHBvcnQ6IElFIDw5IG9ubHlcblx0XHRcdFx0XHRcdFx0XHQvLyBEZWZlbmQgYWdhaW5zdCBjbG9uZWQgYXR0cm9wZXJ0aWVzIChqUXVlcnkgZ2gtMTcwOSlcblx0XHRcdFx0XHRcdFx0XHR1bmlxdWVDYWNoZSA9IG91dGVyQ2FjaGVbIG5vZGUudW5pcXVlSUQgXSB8fFxuXHRcdFx0XHRcdFx0XHRcdFx0KCBvdXRlckNhY2hlWyBub2RlLnVuaXF1ZUlEIF0gPSB7fSApO1xuXG5cdFx0XHRcdFx0XHRcdFx0Y2FjaGUgPSB1bmlxdWVDYWNoZVsgdHlwZSBdIHx8IFtdO1xuXHRcdFx0XHRcdFx0XHRcdG5vZGVJbmRleCA9IGNhY2hlWyAwIF0gPT09IGRpcnJ1bnMgJiYgY2FjaGVbIDEgXTtcblx0XHRcdFx0XHRcdFx0XHRkaWZmID0gbm9kZUluZGV4O1xuXHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdFx0Ly8geG1sIDpudGgtY2hpbGQoLi4uKVxuXHRcdFx0XHRcdFx0XHQvLyBvciA6bnRoLWxhc3QtY2hpbGQoLi4uKSBvciA6bnRoKC1sYXN0KT8tb2YtdHlwZSguLi4pXG5cdFx0XHRcdFx0XHRcdGlmICggZGlmZiA9PT0gZmFsc2UgKSB7XG5cblx0XHRcdFx0XHRcdFx0XHQvLyBVc2UgdGhlIHNhbWUgbG9vcCBhcyBhYm92ZSB0byBzZWVrIGBlbGVtYCBmcm9tIHRoZSBzdGFydFxuXHRcdFx0XHRcdFx0XHRcdHdoaWxlICggKCBub2RlID0gKytub2RlSW5kZXggJiYgbm9kZSAmJiBub2RlWyBkaXIgXSB8fFxuXHRcdFx0XHRcdFx0XHRcdFx0KCBkaWZmID0gbm9kZUluZGV4ID0gMCApIHx8IHN0YXJ0LnBvcCgpICkgKSB7XG5cblx0XHRcdFx0XHRcdFx0XHRcdGlmICggKCBvZlR5cGUgP1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRub2RlLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgPT09IG5hbWUgOlxuXHRcdFx0XHRcdFx0XHRcdFx0XHRub2RlLm5vZGVUeXBlID09PSAxICkgJiZcblx0XHRcdFx0XHRcdFx0XHRcdFx0KytkaWZmICkge1xuXG5cdFx0XHRcdFx0XHRcdFx0XHRcdC8vIENhY2hlIHRoZSBpbmRleCBvZiBlYWNoIGVuY291bnRlcmVkIGVsZW1lbnRcblx0XHRcdFx0XHRcdFx0XHRcdFx0aWYgKCB1c2VDYWNoZSApIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRvdXRlckNhY2hlID0gbm9kZVsgZXhwYW5kbyBdIHx8XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHQoIG5vZGVbIGV4cGFuZG8gXSA9IHt9ICk7XG5cblx0XHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBJRSA8OSBvbmx5XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gRGVmZW5kIGFnYWluc3QgY2xvbmVkIGF0dHJvcGVydGllcyAoalF1ZXJ5IGdoLTE3MDkpXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0dW5pcXVlQ2FjaGUgPSBvdXRlckNhY2hlWyBub2RlLnVuaXF1ZUlEIF0gfHxcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCggb3V0ZXJDYWNoZVsgbm9kZS51bmlxdWVJRCBdID0ge30gKTtcblxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdHVuaXF1ZUNhY2hlWyB0eXBlIF0gPSBbIGRpcnJ1bnMsIGRpZmYgXTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdFx0XHRcdGlmICggbm9kZSA9PT0gZWxlbSApIHtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHQvLyBJbmNvcnBvcmF0ZSB0aGUgb2Zmc2V0LCB0aGVuIGNoZWNrIGFnYWluc3QgY3ljbGUgc2l6ZVxuXHRcdFx0XHRcdFx0ZGlmZiAtPSBsYXN0O1xuXHRcdFx0XHRcdFx0cmV0dXJuIGRpZmYgPT09IGZpcnN0IHx8ICggZGlmZiAlIGZpcnN0ID09PSAwICYmIGRpZmYgLyBmaXJzdCA+PSAwICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9O1xuXHRcdH0sXG5cblx0XHRcIlBTRVVET1wiOiBmdW5jdGlvbiggcHNldWRvLCBhcmd1bWVudCApIHtcblxuXHRcdFx0Ly8gcHNldWRvLWNsYXNzIG5hbWVzIGFyZSBjYXNlLWluc2Vuc2l0aXZlXG5cdFx0XHQvLyBodHRwOi8vd3d3LnczLm9yZy9UUi9zZWxlY3RvcnMvI3BzZXVkby1jbGFzc2VzXG5cdFx0XHQvLyBQcmlvcml0aXplIGJ5IGNhc2Ugc2Vuc2l0aXZpdHkgaW4gY2FzZSBjdXN0b20gcHNldWRvcyBhcmUgYWRkZWQgd2l0aCB1cHBlcmNhc2UgbGV0dGVyc1xuXHRcdFx0Ly8gUmVtZW1iZXIgdGhhdCBzZXRGaWx0ZXJzIGluaGVyaXRzIGZyb20gcHNldWRvc1xuXHRcdFx0dmFyIGFyZ3MsXG5cdFx0XHRcdGZuID0gRXhwci5wc2V1ZG9zWyBwc2V1ZG8gXSB8fCBFeHByLnNldEZpbHRlcnNbIHBzZXVkby50b0xvd2VyQ2FzZSgpIF0gfHxcblx0XHRcdFx0XHRTaXp6bGUuZXJyb3IoIFwidW5zdXBwb3J0ZWQgcHNldWRvOiBcIiArIHBzZXVkbyApO1xuXG5cdFx0XHQvLyBUaGUgdXNlciBtYXkgdXNlIGNyZWF0ZVBzZXVkbyB0byBpbmRpY2F0ZSB0aGF0XG5cdFx0XHQvLyBhcmd1bWVudHMgYXJlIG5lZWRlZCB0byBjcmVhdGUgdGhlIGZpbHRlciBmdW5jdGlvblxuXHRcdFx0Ly8ganVzdCBhcyBTaXp6bGUgZG9lc1xuXHRcdFx0aWYgKCBmblsgZXhwYW5kbyBdICkge1xuXHRcdFx0XHRyZXR1cm4gZm4oIGFyZ3VtZW50ICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIEJ1dCBtYWludGFpbiBzdXBwb3J0IGZvciBvbGQgc2lnbmF0dXJlc1xuXHRcdFx0aWYgKCBmbi5sZW5ndGggPiAxICkge1xuXHRcdFx0XHRhcmdzID0gWyBwc2V1ZG8sIHBzZXVkbywgXCJcIiwgYXJndW1lbnQgXTtcblx0XHRcdFx0cmV0dXJuIEV4cHIuc2V0RmlsdGVycy5oYXNPd25Qcm9wZXJ0eSggcHNldWRvLnRvTG93ZXJDYXNlKCkgKSA/XG5cdFx0XHRcdFx0bWFya0Z1bmN0aW9uKCBmdW5jdGlvbiggc2VlZCwgbWF0Y2hlcyApIHtcblx0XHRcdFx0XHRcdHZhciBpZHgsXG5cdFx0XHRcdFx0XHRcdG1hdGNoZWQgPSBmbiggc2VlZCwgYXJndW1lbnQgKSxcblx0XHRcdFx0XHRcdFx0aSA9IG1hdGNoZWQubGVuZ3RoO1xuXHRcdFx0XHRcdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHRcdFx0XHRcdGlkeCA9IGluZGV4T2YoIHNlZWQsIG1hdGNoZWRbIGkgXSApO1xuXHRcdFx0XHRcdFx0XHRzZWVkWyBpZHggXSA9ICEoIG1hdGNoZXNbIGlkeCBdID0gbWF0Y2hlZFsgaSBdICk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fSApIDpcblx0XHRcdFx0XHRmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdFx0XHRcdHJldHVybiBmbiggZWxlbSwgMCwgYXJncyApO1xuXHRcdFx0XHRcdH07XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBmbjtcblx0XHR9XG5cdH0sXG5cblx0cHNldWRvczoge1xuXG5cdFx0Ly8gUG90ZW50aWFsbHkgY29tcGxleCBwc2V1ZG9zXG5cdFx0XCJub3RcIjogbWFya0Z1bmN0aW9uKCBmdW5jdGlvbiggc2VsZWN0b3IgKSB7XG5cblx0XHRcdC8vIFRyaW0gdGhlIHNlbGVjdG9yIHBhc3NlZCB0byBjb21waWxlXG5cdFx0XHQvLyB0byBhdm9pZCB0cmVhdGluZyBsZWFkaW5nIGFuZCB0cmFpbGluZ1xuXHRcdFx0Ly8gc3BhY2VzIGFzIGNvbWJpbmF0b3JzXG5cdFx0XHR2YXIgaW5wdXQgPSBbXSxcblx0XHRcdFx0cmVzdWx0cyA9IFtdLFxuXHRcdFx0XHRtYXRjaGVyID0gY29tcGlsZSggc2VsZWN0b3IucmVwbGFjZSggcnRyaW0sIFwiJDFcIiApICk7XG5cblx0XHRcdHJldHVybiBtYXRjaGVyWyBleHBhbmRvIF0gP1xuXHRcdFx0XHRtYXJrRnVuY3Rpb24oIGZ1bmN0aW9uKCBzZWVkLCBtYXRjaGVzLCBfY29udGV4dCwgeG1sICkge1xuXHRcdFx0XHRcdHZhciBlbGVtLFxuXHRcdFx0XHRcdFx0dW5tYXRjaGVkID0gbWF0Y2hlciggc2VlZCwgbnVsbCwgeG1sLCBbXSApLFxuXHRcdFx0XHRcdFx0aSA9IHNlZWQubGVuZ3RoO1xuXG5cdFx0XHRcdFx0Ly8gTWF0Y2ggZWxlbWVudHMgdW5tYXRjaGVkIGJ5IGBtYXRjaGVyYFxuXHRcdFx0XHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0XHRcdFx0aWYgKCAoIGVsZW0gPSB1bm1hdGNoZWRbIGkgXSApICkge1xuXHRcdFx0XHRcdFx0XHRzZWVkWyBpIF0gPSAhKCBtYXRjaGVzWyBpIF0gPSBlbGVtICk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9ICkgOlxuXHRcdFx0XHRmdW5jdGlvbiggZWxlbSwgX2NvbnRleHQsIHhtbCApIHtcblx0XHRcdFx0XHRpbnB1dFsgMCBdID0gZWxlbTtcblx0XHRcdFx0XHRtYXRjaGVyKCBpbnB1dCwgbnVsbCwgeG1sLCByZXN1bHRzICk7XG5cblx0XHRcdFx0XHQvLyBEb24ndCBrZWVwIHRoZSBlbGVtZW50IChpc3N1ZSAjMjk5KVxuXHRcdFx0XHRcdGlucHV0WyAwIF0gPSBudWxsO1xuXHRcdFx0XHRcdHJldHVybiAhcmVzdWx0cy5wb3AoKTtcblx0XHRcdFx0fTtcblx0XHR9ICksXG5cblx0XHRcImhhc1wiOiBtYXJrRnVuY3Rpb24oIGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcblx0XHRcdHJldHVybiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdFx0cmV0dXJuIFNpenpsZSggc2VsZWN0b3IsIGVsZW0gKS5sZW5ndGggPiAwO1xuXHRcdFx0fTtcblx0XHR9ICksXG5cblx0XHRcImNvbnRhaW5zXCI6IG1hcmtGdW5jdGlvbiggZnVuY3Rpb24oIHRleHQgKSB7XG5cdFx0XHR0ZXh0ID0gdGV4dC5yZXBsYWNlKCBydW5lc2NhcGUsIGZ1bmVzY2FwZSApO1xuXHRcdFx0cmV0dXJuIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHRyZXR1cm4gKCBlbGVtLnRleHRDb250ZW50IHx8IGdldFRleHQoIGVsZW0gKSApLmluZGV4T2YoIHRleHQgKSA+IC0xO1xuXHRcdFx0fTtcblx0XHR9ICksXG5cblx0XHQvLyBcIldoZXRoZXIgYW4gZWxlbWVudCBpcyByZXByZXNlbnRlZCBieSBhIDpsYW5nKCkgc2VsZWN0b3Jcblx0XHQvLyBpcyBiYXNlZCBzb2xlbHkgb24gdGhlIGVsZW1lbnQncyBsYW5ndWFnZSB2YWx1ZVxuXHRcdC8vIGJlaW5nIGVxdWFsIHRvIHRoZSBpZGVudGlmaWVyIEMsXG5cdFx0Ly8gb3IgYmVnaW5uaW5nIHdpdGggdGhlIGlkZW50aWZpZXIgQyBpbW1lZGlhdGVseSBmb2xsb3dlZCBieSBcIi1cIi5cblx0XHQvLyBUaGUgbWF0Y2hpbmcgb2YgQyBhZ2FpbnN0IHRoZSBlbGVtZW50J3MgbGFuZ3VhZ2UgdmFsdWUgaXMgcGVyZm9ybWVkIGNhc2UtaW5zZW5zaXRpdmVseS5cblx0XHQvLyBUaGUgaWRlbnRpZmllciBDIGRvZXMgbm90IGhhdmUgdG8gYmUgYSB2YWxpZCBsYW5ndWFnZSBuYW1lLlwiXG5cdFx0Ly8gaHR0cDovL3d3dy53My5vcmcvVFIvc2VsZWN0b3JzLyNsYW5nLXBzZXVkb1xuXHRcdFwibGFuZ1wiOiBtYXJrRnVuY3Rpb24oIGZ1bmN0aW9uKCBsYW5nICkge1xuXG5cdFx0XHQvLyBsYW5nIHZhbHVlIG11c3QgYmUgYSB2YWxpZCBpZGVudGlmaWVyXG5cdFx0XHRpZiAoICFyaWRlbnRpZmllci50ZXN0KCBsYW5nIHx8IFwiXCIgKSApIHtcblx0XHRcdFx0U2l6emxlLmVycm9yKCBcInVuc3VwcG9ydGVkIGxhbmc6IFwiICsgbGFuZyApO1xuXHRcdFx0fVxuXHRcdFx0bGFuZyA9IGxhbmcucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKS50b0xvd2VyQ2FzZSgpO1xuXHRcdFx0cmV0dXJuIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHR2YXIgZWxlbUxhbmc7XG5cdFx0XHRcdGRvIHtcblx0XHRcdFx0XHRpZiAoICggZWxlbUxhbmcgPSBkb2N1bWVudElzSFRNTCA/XG5cdFx0XHRcdFx0XHRlbGVtLmxhbmcgOlxuXHRcdFx0XHRcdFx0ZWxlbS5nZXRBdHRyaWJ1dGUoIFwieG1sOmxhbmdcIiApIHx8IGVsZW0uZ2V0QXR0cmlidXRlKCBcImxhbmdcIiApICkgKSB7XG5cblx0XHRcdFx0XHRcdGVsZW1MYW5nID0gZWxlbUxhbmcudG9Mb3dlckNhc2UoKTtcblx0XHRcdFx0XHRcdHJldHVybiBlbGVtTGFuZyA9PT0gbGFuZyB8fCBlbGVtTGFuZy5pbmRleE9mKCBsYW5nICsgXCItXCIgKSA9PT0gMDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0gd2hpbGUgKCAoIGVsZW0gPSBlbGVtLnBhcmVudE5vZGUgKSAmJiBlbGVtLm5vZGVUeXBlID09PSAxICk7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH07XG5cdFx0fSApLFxuXG5cdFx0Ly8gTWlzY2VsbGFuZW91c1xuXHRcdFwidGFyZ2V0XCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0dmFyIGhhc2ggPSB3aW5kb3cubG9jYXRpb24gJiYgd2luZG93LmxvY2F0aW9uLmhhc2g7XG5cdFx0XHRyZXR1cm4gaGFzaCAmJiBoYXNoLnNsaWNlKCAxICkgPT09IGVsZW0uaWQ7XG5cdFx0fSxcblxuXHRcdFwicm9vdFwiOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybiBlbGVtID09PSBkb2NFbGVtO1xuXHRcdH0sXG5cblx0XHRcImZvY3VzXCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0cmV0dXJuIGVsZW0gPT09IGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQgJiZcblx0XHRcdFx0KCAhZG9jdW1lbnQuaGFzRm9jdXMgfHwgZG9jdW1lbnQuaGFzRm9jdXMoKSApICYmXG5cdFx0XHRcdCEhKCBlbGVtLnR5cGUgfHwgZWxlbS5ocmVmIHx8IH5lbGVtLnRhYkluZGV4ICk7XG5cdFx0fSxcblxuXHRcdC8vIEJvb2xlYW4gcHJvcGVydGllc1xuXHRcdFwiZW5hYmxlZFwiOiBjcmVhdGVEaXNhYmxlZFBzZXVkbyggZmFsc2UgKSxcblx0XHRcImRpc2FibGVkXCI6IGNyZWF0ZURpc2FibGVkUHNldWRvKCB0cnVlICksXG5cblx0XHRcImNoZWNrZWRcIjogZnVuY3Rpb24oIGVsZW0gKSB7XG5cblx0XHRcdC8vIEluIENTUzMsIDpjaGVja2VkIHNob3VsZCByZXR1cm4gYm90aCBjaGVja2VkIGFuZCBzZWxlY3RlZCBlbGVtZW50c1xuXHRcdFx0Ly8gaHR0cDovL3d3dy53My5vcmcvVFIvMjAxMS9SRUMtY3NzMy1zZWxlY3RvcnMtMjAxMTA5MjkvI2NoZWNrZWRcblx0XHRcdHZhciBub2RlTmFtZSA9IGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtcblx0XHRcdHJldHVybiAoIG5vZGVOYW1lID09PSBcImlucHV0XCIgJiYgISFlbGVtLmNoZWNrZWQgKSB8fFxuXHRcdFx0XHQoIG5vZGVOYW1lID09PSBcIm9wdGlvblwiICYmICEhZWxlbS5zZWxlY3RlZCApO1xuXHRcdH0sXG5cblx0XHRcInNlbGVjdGVkXCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXG5cdFx0XHQvLyBBY2Nlc3NpbmcgdGhpcyBwcm9wZXJ0eSBtYWtlcyBzZWxlY3RlZC1ieS1kZWZhdWx0XG5cdFx0XHQvLyBvcHRpb25zIGluIFNhZmFyaSB3b3JrIHByb3Blcmx5XG5cdFx0XHRpZiAoIGVsZW0ucGFyZW50Tm9kZSApIHtcblx0XHRcdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVudXNlZC1leHByZXNzaW9uc1xuXHRcdFx0XHRlbGVtLnBhcmVudE5vZGUuc2VsZWN0ZWRJbmRleDtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIGVsZW0uc2VsZWN0ZWQgPT09IHRydWU7XG5cdFx0fSxcblxuXHRcdC8vIENvbnRlbnRzXG5cdFx0XCJlbXB0eVwiOiBmdW5jdGlvbiggZWxlbSApIHtcblxuXHRcdFx0Ly8gaHR0cDovL3d3dy53My5vcmcvVFIvc2VsZWN0b3JzLyNlbXB0eS1wc2V1ZG9cblx0XHRcdC8vIDplbXB0eSBpcyBuZWdhdGVkIGJ5IGVsZW1lbnQgKDEpIG9yIGNvbnRlbnQgbm9kZXMgKHRleHQ6IDM7IGNkYXRhOiA0OyBlbnRpdHkgcmVmOiA1KSxcblx0XHRcdC8vICAgYnV0IG5vdCBieSBvdGhlcnMgKGNvbW1lbnQ6IDg7IHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb246IDc7IGV0Yy4pXG5cdFx0XHQvLyBub2RlVHlwZSA8IDYgd29ya3MgYmVjYXVzZSBhdHRyaWJ1dGVzICgyKSBkbyBub3QgYXBwZWFyIGFzIGNoaWxkcmVuXG5cdFx0XHRmb3IgKCBlbGVtID0gZWxlbS5maXJzdENoaWxkOyBlbGVtOyBlbGVtID0gZWxlbS5uZXh0U2libGluZyApIHtcblx0XHRcdFx0aWYgKCBlbGVtLm5vZGVUeXBlIDwgNiApIHtcblx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH0sXG5cblx0XHRcInBhcmVudFwiOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybiAhRXhwci5wc2V1ZG9zWyBcImVtcHR5XCIgXSggZWxlbSApO1xuXHRcdH0sXG5cblx0XHQvLyBFbGVtZW50L2lucHV0IHR5cGVzXG5cdFx0XCJoZWFkZXJcIjogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4gcmhlYWRlci50ZXN0KCBlbGVtLm5vZGVOYW1lICk7XG5cdFx0fSxcblxuXHRcdFwiaW5wdXRcIjogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4gcmlucHV0cy50ZXN0KCBlbGVtLm5vZGVOYW1lICk7XG5cdFx0fSxcblxuXHRcdFwiYnV0dG9uXCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0dmFyIG5hbWUgPSBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7XG5cdFx0XHRyZXR1cm4gbmFtZSA9PT0gXCJpbnB1dFwiICYmIGVsZW0udHlwZSA9PT0gXCJidXR0b25cIiB8fCBuYW1lID09PSBcImJ1dHRvblwiO1xuXHRcdH0sXG5cblx0XHRcInRleHRcIjogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHR2YXIgYXR0cjtcblx0XHRcdHJldHVybiBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgPT09IFwiaW5wdXRcIiAmJlxuXHRcdFx0XHRlbGVtLnR5cGUgPT09IFwidGV4dFwiICYmXG5cblx0XHRcdFx0Ly8gU3VwcG9ydDogSUU8OFxuXHRcdFx0XHQvLyBOZXcgSFRNTDUgYXR0cmlidXRlIHZhbHVlcyAoZS5nLiwgXCJzZWFyY2hcIikgYXBwZWFyIHdpdGggZWxlbS50eXBlID09PSBcInRleHRcIlxuXHRcdFx0XHQoICggYXR0ciA9IGVsZW0uZ2V0QXR0cmlidXRlKCBcInR5cGVcIiApICkgPT0gbnVsbCB8fFxuXHRcdFx0XHRcdGF0dHIudG9Mb3dlckNhc2UoKSA9PT0gXCJ0ZXh0XCIgKTtcblx0XHR9LFxuXG5cdFx0Ly8gUG9zaXRpb24taW4tY29sbGVjdGlvblxuXHRcdFwiZmlyc3RcIjogY3JlYXRlUG9zaXRpb25hbFBzZXVkbyggZnVuY3Rpb24oKSB7XG5cdFx0XHRyZXR1cm4gWyAwIF07XG5cdFx0fSApLFxuXG5cdFx0XCJsYXN0XCI6IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oIGZ1bmN0aW9uKCBfbWF0Y2hJbmRleGVzLCBsZW5ndGggKSB7XG5cdFx0XHRyZXR1cm4gWyBsZW5ndGggLSAxIF07XG5cdFx0fSApLFxuXG5cdFx0XCJlcVwiOiBjcmVhdGVQb3NpdGlvbmFsUHNldWRvKCBmdW5jdGlvbiggX21hdGNoSW5kZXhlcywgbGVuZ3RoLCBhcmd1bWVudCApIHtcblx0XHRcdHJldHVybiBbIGFyZ3VtZW50IDwgMCA/IGFyZ3VtZW50ICsgbGVuZ3RoIDogYXJndW1lbnQgXTtcblx0XHR9ICksXG5cblx0XHRcImV2ZW5cIjogY3JlYXRlUG9zaXRpb25hbFBzZXVkbyggZnVuY3Rpb24oIG1hdGNoSW5kZXhlcywgbGVuZ3RoICkge1xuXHRcdFx0dmFyIGkgPSAwO1xuXHRcdFx0Zm9yICggOyBpIDwgbGVuZ3RoOyBpICs9IDIgKSB7XG5cdFx0XHRcdG1hdGNoSW5kZXhlcy5wdXNoKCBpICk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gbWF0Y2hJbmRleGVzO1xuXHRcdH0gKSxcblxuXHRcdFwib2RkXCI6IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oIGZ1bmN0aW9uKCBtYXRjaEluZGV4ZXMsIGxlbmd0aCApIHtcblx0XHRcdHZhciBpID0gMTtcblx0XHRcdGZvciAoIDsgaSA8IGxlbmd0aDsgaSArPSAyICkge1xuXHRcdFx0XHRtYXRjaEluZGV4ZXMucHVzaCggaSApO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIG1hdGNoSW5kZXhlcztcblx0XHR9ICksXG5cblx0XHRcImx0XCI6IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oIGZ1bmN0aW9uKCBtYXRjaEluZGV4ZXMsIGxlbmd0aCwgYXJndW1lbnQgKSB7XG5cdFx0XHR2YXIgaSA9IGFyZ3VtZW50IDwgMCA/XG5cdFx0XHRcdGFyZ3VtZW50ICsgbGVuZ3RoIDpcblx0XHRcdFx0YXJndW1lbnQgPiBsZW5ndGggP1xuXHRcdFx0XHRcdGxlbmd0aCA6XG5cdFx0XHRcdFx0YXJndW1lbnQ7XG5cdFx0XHRmb3IgKCA7IC0taSA+PSAwOyApIHtcblx0XHRcdFx0bWF0Y2hJbmRleGVzLnB1c2goIGkgKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBtYXRjaEluZGV4ZXM7XG5cdFx0fSApLFxuXG5cdFx0XCJndFwiOiBjcmVhdGVQb3NpdGlvbmFsUHNldWRvKCBmdW5jdGlvbiggbWF0Y2hJbmRleGVzLCBsZW5ndGgsIGFyZ3VtZW50ICkge1xuXHRcdFx0dmFyIGkgPSBhcmd1bWVudCA8IDAgPyBhcmd1bWVudCArIGxlbmd0aCA6IGFyZ3VtZW50O1xuXHRcdFx0Zm9yICggOyArK2kgPCBsZW5ndGg7ICkge1xuXHRcdFx0XHRtYXRjaEluZGV4ZXMucHVzaCggaSApO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIG1hdGNoSW5kZXhlcztcblx0XHR9IClcblx0fVxufTtcblxuRXhwci5wc2V1ZG9zWyBcIm50aFwiIF0gPSBFeHByLnBzZXVkb3NbIFwiZXFcIiBdO1xuXG4vLyBBZGQgYnV0dG9uL2lucHV0IHR5cGUgcHNldWRvc1xuZm9yICggaSBpbiB7IHJhZGlvOiB0cnVlLCBjaGVja2JveDogdHJ1ZSwgZmlsZTogdHJ1ZSwgcGFzc3dvcmQ6IHRydWUsIGltYWdlOiB0cnVlIH0gKSB7XG5cdEV4cHIucHNldWRvc1sgaSBdID0gY3JlYXRlSW5wdXRQc2V1ZG8oIGkgKTtcbn1cbmZvciAoIGkgaW4geyBzdWJtaXQ6IHRydWUsIHJlc2V0OiB0cnVlIH0gKSB7XG5cdEV4cHIucHNldWRvc1sgaSBdID0gY3JlYXRlQnV0dG9uUHNldWRvKCBpICk7XG59XG5cbi8vIEVhc3kgQVBJIGZvciBjcmVhdGluZyBuZXcgc2V0RmlsdGVyc1xuZnVuY3Rpb24gc2V0RmlsdGVycygpIHt9XG5zZXRGaWx0ZXJzLnByb3RvdHlwZSA9IEV4cHIuZmlsdGVycyA9IEV4cHIucHNldWRvcztcbkV4cHIuc2V0RmlsdGVycyA9IG5ldyBzZXRGaWx0ZXJzKCk7XG5cbnRva2VuaXplID0gU2l6emxlLnRva2VuaXplID0gZnVuY3Rpb24oIHNlbGVjdG9yLCBwYXJzZU9ubHkgKSB7XG5cdHZhciBtYXRjaGVkLCBtYXRjaCwgdG9rZW5zLCB0eXBlLFxuXHRcdHNvRmFyLCBncm91cHMsIHByZUZpbHRlcnMsXG5cdFx0Y2FjaGVkID0gdG9rZW5DYWNoZVsgc2VsZWN0b3IgKyBcIiBcIiBdO1xuXG5cdGlmICggY2FjaGVkICkge1xuXHRcdHJldHVybiBwYXJzZU9ubHkgPyAwIDogY2FjaGVkLnNsaWNlKCAwICk7XG5cdH1cblxuXHRzb0ZhciA9IHNlbGVjdG9yO1xuXHRncm91cHMgPSBbXTtcblx0cHJlRmlsdGVycyA9IEV4cHIucHJlRmlsdGVyO1xuXG5cdHdoaWxlICggc29GYXIgKSB7XG5cblx0XHQvLyBDb21tYSBhbmQgZmlyc3QgcnVuXG5cdFx0aWYgKCAhbWF0Y2hlZCB8fCAoIG1hdGNoID0gcmNvbW1hLmV4ZWMoIHNvRmFyICkgKSApIHtcblx0XHRcdGlmICggbWF0Y2ggKSB7XG5cblx0XHRcdFx0Ly8gRG9uJ3QgY29uc3VtZSB0cmFpbGluZyBjb21tYXMgYXMgdmFsaWRcblx0XHRcdFx0c29GYXIgPSBzb0Zhci5zbGljZSggbWF0Y2hbIDAgXS5sZW5ndGggKSB8fCBzb0Zhcjtcblx0XHRcdH1cblx0XHRcdGdyb3Vwcy5wdXNoKCAoIHRva2VucyA9IFtdICkgKTtcblx0XHR9XG5cblx0XHRtYXRjaGVkID0gZmFsc2U7XG5cblx0XHQvLyBDb21iaW5hdG9yc1xuXHRcdGlmICggKCBtYXRjaCA9IHJjb21iaW5hdG9ycy5leGVjKCBzb0ZhciApICkgKSB7XG5cdFx0XHRtYXRjaGVkID0gbWF0Y2guc2hpZnQoKTtcblx0XHRcdHRva2Vucy5wdXNoKCB7XG5cdFx0XHRcdHZhbHVlOiBtYXRjaGVkLFxuXG5cdFx0XHRcdC8vIENhc3QgZGVzY2VuZGFudCBjb21iaW5hdG9ycyB0byBzcGFjZVxuXHRcdFx0XHR0eXBlOiBtYXRjaFsgMCBdLnJlcGxhY2UoIHJ0cmltLCBcIiBcIiApXG5cdFx0XHR9ICk7XG5cdFx0XHRzb0ZhciA9IHNvRmFyLnNsaWNlKCBtYXRjaGVkLmxlbmd0aCApO1xuXHRcdH1cblxuXHRcdC8vIEZpbHRlcnNcblx0XHRmb3IgKCB0eXBlIGluIEV4cHIuZmlsdGVyICkge1xuXHRcdFx0aWYgKCAoIG1hdGNoID0gbWF0Y2hFeHByWyB0eXBlIF0uZXhlYyggc29GYXIgKSApICYmICggIXByZUZpbHRlcnNbIHR5cGUgXSB8fFxuXHRcdFx0XHQoIG1hdGNoID0gcHJlRmlsdGVyc1sgdHlwZSBdKCBtYXRjaCApICkgKSApIHtcblx0XHRcdFx0bWF0Y2hlZCA9IG1hdGNoLnNoaWZ0KCk7XG5cdFx0XHRcdHRva2Vucy5wdXNoKCB7XG5cdFx0XHRcdFx0dmFsdWU6IG1hdGNoZWQsXG5cdFx0XHRcdFx0dHlwZTogdHlwZSxcblx0XHRcdFx0XHRtYXRjaGVzOiBtYXRjaFxuXHRcdFx0XHR9ICk7XG5cdFx0XHRcdHNvRmFyID0gc29GYXIuc2xpY2UoIG1hdGNoZWQubGVuZ3RoICk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aWYgKCAhbWF0Y2hlZCApIHtcblx0XHRcdGJyZWFrO1xuXHRcdH1cblx0fVxuXG5cdC8vIFJldHVybiB0aGUgbGVuZ3RoIG9mIHRoZSBpbnZhbGlkIGV4Y2Vzc1xuXHQvLyBpZiB3ZSdyZSBqdXN0IHBhcnNpbmdcblx0Ly8gT3RoZXJ3aXNlLCB0aHJvdyBhbiBlcnJvciBvciByZXR1cm4gdG9rZW5zXG5cdHJldHVybiBwYXJzZU9ubHkgP1xuXHRcdHNvRmFyLmxlbmd0aCA6XG5cdFx0c29GYXIgP1xuXHRcdFx0U2l6emxlLmVycm9yKCBzZWxlY3RvciApIDpcblxuXHRcdFx0Ly8gQ2FjaGUgdGhlIHRva2Vuc1xuXHRcdFx0dG9rZW5DYWNoZSggc2VsZWN0b3IsIGdyb3VwcyApLnNsaWNlKCAwICk7XG59O1xuXG5mdW5jdGlvbiB0b1NlbGVjdG9yKCB0b2tlbnMgKSB7XG5cdHZhciBpID0gMCxcblx0XHRsZW4gPSB0b2tlbnMubGVuZ3RoLFxuXHRcdHNlbGVjdG9yID0gXCJcIjtcblx0Zm9yICggOyBpIDwgbGVuOyBpKysgKSB7XG5cdFx0c2VsZWN0b3IgKz0gdG9rZW5zWyBpIF0udmFsdWU7XG5cdH1cblx0cmV0dXJuIHNlbGVjdG9yO1xufVxuXG5mdW5jdGlvbiBhZGRDb21iaW5hdG9yKCBtYXRjaGVyLCBjb21iaW5hdG9yLCBiYXNlICkge1xuXHR2YXIgZGlyID0gY29tYmluYXRvci5kaXIsXG5cdFx0c2tpcCA9IGNvbWJpbmF0b3IubmV4dCxcblx0XHRrZXkgPSBza2lwIHx8IGRpcixcblx0XHRjaGVja05vbkVsZW1lbnRzID0gYmFzZSAmJiBrZXkgPT09IFwicGFyZW50Tm9kZVwiLFxuXHRcdGRvbmVOYW1lID0gZG9uZSsrO1xuXG5cdHJldHVybiBjb21iaW5hdG9yLmZpcnN0ID9cblxuXHRcdC8vIENoZWNrIGFnYWluc3QgY2xvc2VzdCBhbmNlc3Rvci9wcmVjZWRpbmcgZWxlbWVudFxuXHRcdGZ1bmN0aW9uKCBlbGVtLCBjb250ZXh0LCB4bWwgKSB7XG5cdFx0XHR3aGlsZSAoICggZWxlbSA9IGVsZW1bIGRpciBdICkgKSB7XG5cdFx0XHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gMSB8fCBjaGVja05vbkVsZW1lbnRzICkge1xuXHRcdFx0XHRcdHJldHVybiBtYXRjaGVyKCBlbGVtLCBjb250ZXh0LCB4bWwgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH0gOlxuXG5cdFx0Ly8gQ2hlY2sgYWdhaW5zdCBhbGwgYW5jZXN0b3IvcHJlY2VkaW5nIGVsZW1lbnRzXG5cdFx0ZnVuY3Rpb24oIGVsZW0sIGNvbnRleHQsIHhtbCApIHtcblx0XHRcdHZhciBvbGRDYWNoZSwgdW5pcXVlQ2FjaGUsIG91dGVyQ2FjaGUsXG5cdFx0XHRcdG5ld0NhY2hlID0gWyBkaXJydW5zLCBkb25lTmFtZSBdO1xuXG5cdFx0XHQvLyBXZSBjYW4ndCBzZXQgYXJiaXRyYXJ5IGRhdGEgb24gWE1MIG5vZGVzLCBzbyB0aGV5IGRvbid0IGJlbmVmaXQgZnJvbSBjb21iaW5hdG9yIGNhY2hpbmdcblx0XHRcdGlmICggeG1sICkge1xuXHRcdFx0XHR3aGlsZSAoICggZWxlbSA9IGVsZW1bIGRpciBdICkgKSB7XG5cdFx0XHRcdFx0aWYgKCBlbGVtLm5vZGVUeXBlID09PSAxIHx8IGNoZWNrTm9uRWxlbWVudHMgKSB7XG5cdFx0XHRcdFx0XHRpZiAoIG1hdGNoZXIoIGVsZW0sIGNvbnRleHQsIHhtbCApICkge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHdoaWxlICggKCBlbGVtID0gZWxlbVsgZGlyIF0gKSApIHtcblx0XHRcdFx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDEgfHwgY2hlY2tOb25FbGVtZW50cyApIHtcblx0XHRcdFx0XHRcdG91dGVyQ2FjaGUgPSBlbGVtWyBleHBhbmRvIF0gfHwgKCBlbGVtWyBleHBhbmRvIF0gPSB7fSApO1xuXG5cdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBJRSA8OSBvbmx5XG5cdFx0XHRcdFx0XHQvLyBEZWZlbmQgYWdhaW5zdCBjbG9uZWQgYXR0cm9wZXJ0aWVzIChqUXVlcnkgZ2gtMTcwOSlcblx0XHRcdFx0XHRcdHVuaXF1ZUNhY2hlID0gb3V0ZXJDYWNoZVsgZWxlbS51bmlxdWVJRCBdIHx8XG5cdFx0XHRcdFx0XHRcdCggb3V0ZXJDYWNoZVsgZWxlbS51bmlxdWVJRCBdID0ge30gKTtcblxuXHRcdFx0XHRcdFx0aWYgKCBza2lwICYmIHNraXAgPT09IGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKSApIHtcblx0XHRcdFx0XHRcdFx0ZWxlbSA9IGVsZW1bIGRpciBdIHx8IGVsZW07XG5cdFx0XHRcdFx0XHR9IGVsc2UgaWYgKCAoIG9sZENhY2hlID0gdW5pcXVlQ2FjaGVbIGtleSBdICkgJiZcblx0XHRcdFx0XHRcdFx0b2xkQ2FjaGVbIDAgXSA9PT0gZGlycnVucyAmJiBvbGRDYWNoZVsgMSBdID09PSBkb25lTmFtZSApIHtcblxuXHRcdFx0XHRcdFx0XHQvLyBBc3NpZ24gdG8gbmV3Q2FjaGUgc28gcmVzdWx0cyBiYWNrLXByb3BhZ2F0ZSB0byBwcmV2aW91cyBlbGVtZW50c1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gKCBuZXdDYWNoZVsgMiBdID0gb2xkQ2FjaGVbIDIgXSApO1xuXHRcdFx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdFx0XHQvLyBSZXVzZSBuZXdjYWNoZSBzbyByZXN1bHRzIGJhY2stcHJvcGFnYXRlIHRvIHByZXZpb3VzIGVsZW1lbnRzXG5cdFx0XHRcdFx0XHRcdHVuaXF1ZUNhY2hlWyBrZXkgXSA9IG5ld0NhY2hlO1xuXG5cdFx0XHRcdFx0XHRcdC8vIEEgbWF0Y2ggbWVhbnMgd2UncmUgZG9uZTsgYSBmYWlsIG1lYW5zIHdlIGhhdmUgdG8ga2VlcCBjaGVja2luZ1xuXHRcdFx0XHRcdFx0XHRpZiAoICggbmV3Q2FjaGVbIDIgXSA9IG1hdGNoZXIoIGVsZW0sIGNvbnRleHQsIHhtbCApICkgKSB7XG5cdFx0XHRcdFx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9O1xufVxuXG5mdW5jdGlvbiBlbGVtZW50TWF0Y2hlciggbWF0Y2hlcnMgKSB7XG5cdHJldHVybiBtYXRjaGVycy5sZW5ndGggPiAxID9cblx0XHRmdW5jdGlvbiggZWxlbSwgY29udGV4dCwgeG1sICkge1xuXHRcdFx0dmFyIGkgPSBtYXRjaGVycy5sZW5ndGg7XG5cdFx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdFx0aWYgKCAhbWF0Y2hlcnNbIGkgXSggZWxlbSwgY29udGV4dCwgeG1sICkgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9IDpcblx0XHRtYXRjaGVyc1sgMCBdO1xufVxuXG5mdW5jdGlvbiBtdWx0aXBsZUNvbnRleHRzKCBzZWxlY3RvciwgY29udGV4dHMsIHJlc3VsdHMgKSB7XG5cdHZhciBpID0gMCxcblx0XHRsZW4gPSBjb250ZXh0cy5sZW5ndGg7XG5cdGZvciAoIDsgaSA8IGxlbjsgaSsrICkge1xuXHRcdFNpenpsZSggc2VsZWN0b3IsIGNvbnRleHRzWyBpIF0sIHJlc3VsdHMgKTtcblx0fVxuXHRyZXR1cm4gcmVzdWx0cztcbn1cblxuZnVuY3Rpb24gY29uZGVuc2UoIHVubWF0Y2hlZCwgbWFwLCBmaWx0ZXIsIGNvbnRleHQsIHhtbCApIHtcblx0dmFyIGVsZW0sXG5cdFx0bmV3VW5tYXRjaGVkID0gW10sXG5cdFx0aSA9IDAsXG5cdFx0bGVuID0gdW5tYXRjaGVkLmxlbmd0aCxcblx0XHRtYXBwZWQgPSBtYXAgIT0gbnVsbDtcblxuXHRmb3IgKCA7IGkgPCBsZW47IGkrKyApIHtcblx0XHRpZiAoICggZWxlbSA9IHVubWF0Y2hlZFsgaSBdICkgKSB7XG5cdFx0XHRpZiAoICFmaWx0ZXIgfHwgZmlsdGVyKCBlbGVtLCBjb250ZXh0LCB4bWwgKSApIHtcblx0XHRcdFx0bmV3VW5tYXRjaGVkLnB1c2goIGVsZW0gKTtcblx0XHRcdFx0aWYgKCBtYXBwZWQgKSB7XG5cdFx0XHRcdFx0bWFwLnB1c2goIGkgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHJldHVybiBuZXdVbm1hdGNoZWQ7XG59XG5cbmZ1bmN0aW9uIHNldE1hdGNoZXIoIHByZUZpbHRlciwgc2VsZWN0b3IsIG1hdGNoZXIsIHBvc3RGaWx0ZXIsIHBvc3RGaW5kZXIsIHBvc3RTZWxlY3RvciApIHtcblx0aWYgKCBwb3N0RmlsdGVyICYmICFwb3N0RmlsdGVyWyBleHBhbmRvIF0gKSB7XG5cdFx0cG9zdEZpbHRlciA9IHNldE1hdGNoZXIoIHBvc3RGaWx0ZXIgKTtcblx0fVxuXHRpZiAoIHBvc3RGaW5kZXIgJiYgIXBvc3RGaW5kZXJbIGV4cGFuZG8gXSApIHtcblx0XHRwb3N0RmluZGVyID0gc2V0TWF0Y2hlciggcG9zdEZpbmRlciwgcG9zdFNlbGVjdG9yICk7XG5cdH1cblx0cmV0dXJuIG1hcmtGdW5jdGlvbiggZnVuY3Rpb24oIHNlZWQsIHJlc3VsdHMsIGNvbnRleHQsIHhtbCApIHtcblx0XHR2YXIgdGVtcCwgaSwgZWxlbSxcblx0XHRcdHByZU1hcCA9IFtdLFxuXHRcdFx0cG9zdE1hcCA9IFtdLFxuXHRcdFx0cHJlZXhpc3RpbmcgPSByZXN1bHRzLmxlbmd0aCxcblxuXHRcdFx0Ly8gR2V0IGluaXRpYWwgZWxlbWVudHMgZnJvbSBzZWVkIG9yIGNvbnRleHRcblx0XHRcdGVsZW1zID0gc2VlZCB8fCBtdWx0aXBsZUNvbnRleHRzKFxuXHRcdFx0XHRzZWxlY3RvciB8fCBcIipcIixcblx0XHRcdFx0Y29udGV4dC5ub2RlVHlwZSA/IFsgY29udGV4dCBdIDogY29udGV4dCxcblx0XHRcdFx0W11cblx0XHRcdCksXG5cblx0XHRcdC8vIFByZWZpbHRlciB0byBnZXQgbWF0Y2hlciBpbnB1dCwgcHJlc2VydmluZyBhIG1hcCBmb3Igc2VlZC1yZXN1bHRzIHN5bmNocm9uaXphdGlvblxuXHRcdFx0bWF0Y2hlckluID0gcHJlRmlsdGVyICYmICggc2VlZCB8fCAhc2VsZWN0b3IgKSA/XG5cdFx0XHRcdGNvbmRlbnNlKCBlbGVtcywgcHJlTWFwLCBwcmVGaWx0ZXIsIGNvbnRleHQsIHhtbCApIDpcblx0XHRcdFx0ZWxlbXMsXG5cblx0XHRcdG1hdGNoZXJPdXQgPSBtYXRjaGVyID9cblxuXHRcdFx0XHQvLyBJZiB3ZSBoYXZlIGEgcG9zdEZpbmRlciwgb3IgZmlsdGVyZWQgc2VlZCwgb3Igbm9uLXNlZWQgcG9zdEZpbHRlciBvciBwcmVleGlzdGluZyByZXN1bHRzLFxuXHRcdFx0XHRwb3N0RmluZGVyIHx8ICggc2VlZCA/IHByZUZpbHRlciA6IHByZWV4aXN0aW5nIHx8IHBvc3RGaWx0ZXIgKSA/XG5cblx0XHRcdFx0XHQvLyAuLi5pbnRlcm1lZGlhdGUgcHJvY2Vzc2luZyBpcyBuZWNlc3Nhcnlcblx0XHRcdFx0XHRbXSA6XG5cblx0XHRcdFx0XHQvLyAuLi5vdGhlcndpc2UgdXNlIHJlc3VsdHMgZGlyZWN0bHlcblx0XHRcdFx0XHRyZXN1bHRzIDpcblx0XHRcdFx0bWF0Y2hlckluO1xuXG5cdFx0Ly8gRmluZCBwcmltYXJ5IG1hdGNoZXNcblx0XHRpZiAoIG1hdGNoZXIgKSB7XG5cdFx0XHRtYXRjaGVyKCBtYXRjaGVySW4sIG1hdGNoZXJPdXQsIGNvbnRleHQsIHhtbCApO1xuXHRcdH1cblxuXHRcdC8vIEFwcGx5IHBvc3RGaWx0ZXJcblx0XHRpZiAoIHBvc3RGaWx0ZXIgKSB7XG5cdFx0XHR0ZW1wID0gY29uZGVuc2UoIG1hdGNoZXJPdXQsIHBvc3RNYXAgKTtcblx0XHRcdHBvc3RGaWx0ZXIoIHRlbXAsIFtdLCBjb250ZXh0LCB4bWwgKTtcblxuXHRcdFx0Ly8gVW4tbWF0Y2ggZmFpbGluZyBlbGVtZW50cyBieSBtb3ZpbmcgdGhlbSBiYWNrIHRvIG1hdGNoZXJJblxuXHRcdFx0aSA9IHRlbXAubGVuZ3RoO1xuXHRcdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHRcdGlmICggKCBlbGVtID0gdGVtcFsgaSBdICkgKSB7XG5cdFx0XHRcdFx0bWF0Y2hlck91dFsgcG9zdE1hcFsgaSBdIF0gPSAhKCBtYXRjaGVySW5bIHBvc3RNYXBbIGkgXSBdID0gZWxlbSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aWYgKCBzZWVkICkge1xuXHRcdFx0aWYgKCBwb3N0RmluZGVyIHx8IHByZUZpbHRlciApIHtcblx0XHRcdFx0aWYgKCBwb3N0RmluZGVyICkge1xuXG5cdFx0XHRcdFx0Ly8gR2V0IHRoZSBmaW5hbCBtYXRjaGVyT3V0IGJ5IGNvbmRlbnNpbmcgdGhpcyBpbnRlcm1lZGlhdGUgaW50byBwb3N0RmluZGVyIGNvbnRleHRzXG5cdFx0XHRcdFx0dGVtcCA9IFtdO1xuXHRcdFx0XHRcdGkgPSBtYXRjaGVyT3V0Lmxlbmd0aDtcblx0XHRcdFx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdFx0XHRcdGlmICggKCBlbGVtID0gbWF0Y2hlck91dFsgaSBdICkgKSB7XG5cblx0XHRcdFx0XHRcdFx0Ly8gUmVzdG9yZSBtYXRjaGVySW4gc2luY2UgZWxlbSBpcyBub3QgeWV0IGEgZmluYWwgbWF0Y2hcblx0XHRcdFx0XHRcdFx0dGVtcC5wdXNoKCAoIG1hdGNoZXJJblsgaSBdID0gZWxlbSApICk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHBvc3RGaW5kZXIoIG51bGwsICggbWF0Y2hlck91dCA9IFtdICksIHRlbXAsIHhtbCApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gTW92ZSBtYXRjaGVkIGVsZW1lbnRzIGZyb20gc2VlZCB0byByZXN1bHRzIHRvIGtlZXAgdGhlbSBzeW5jaHJvbml6ZWRcblx0XHRcdFx0aSA9IG1hdGNoZXJPdXQubGVuZ3RoO1xuXHRcdFx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdFx0XHRpZiAoICggZWxlbSA9IG1hdGNoZXJPdXRbIGkgXSApICYmXG5cdFx0XHRcdFx0XHQoIHRlbXAgPSBwb3N0RmluZGVyID8gaW5kZXhPZiggc2VlZCwgZWxlbSApIDogcHJlTWFwWyBpIF0gKSA+IC0xICkge1xuXG5cdFx0XHRcdFx0XHRzZWVkWyB0ZW1wIF0gPSAhKCByZXN1bHRzWyB0ZW1wIF0gPSBlbGVtICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHQvLyBBZGQgZWxlbWVudHMgdG8gcmVzdWx0cywgdGhyb3VnaCBwb3N0RmluZGVyIGlmIGRlZmluZWRcblx0XHR9IGVsc2Uge1xuXHRcdFx0bWF0Y2hlck91dCA9IGNvbmRlbnNlKFxuXHRcdFx0XHRtYXRjaGVyT3V0ID09PSByZXN1bHRzID9cblx0XHRcdFx0XHRtYXRjaGVyT3V0LnNwbGljZSggcHJlZXhpc3RpbmcsIG1hdGNoZXJPdXQubGVuZ3RoICkgOlxuXHRcdFx0XHRcdG1hdGNoZXJPdXRcblx0XHRcdCk7XG5cdFx0XHRpZiAoIHBvc3RGaW5kZXIgKSB7XG5cdFx0XHRcdHBvc3RGaW5kZXIoIG51bGwsIHJlc3VsdHMsIG1hdGNoZXJPdXQsIHhtbCApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0cHVzaC5hcHBseSggcmVzdWx0cywgbWF0Y2hlck91dCApO1xuXHRcdFx0fVxuXHRcdH1cblx0fSApO1xufVxuXG5mdW5jdGlvbiBtYXRjaGVyRnJvbVRva2VucyggdG9rZW5zICkge1xuXHR2YXIgY2hlY2tDb250ZXh0LCBtYXRjaGVyLCBqLFxuXHRcdGxlbiA9IHRva2Vucy5sZW5ndGgsXG5cdFx0bGVhZGluZ1JlbGF0aXZlID0gRXhwci5yZWxhdGl2ZVsgdG9rZW5zWyAwIF0udHlwZSBdLFxuXHRcdGltcGxpY2l0UmVsYXRpdmUgPSBsZWFkaW5nUmVsYXRpdmUgfHwgRXhwci5yZWxhdGl2ZVsgXCIgXCIgXSxcblx0XHRpID0gbGVhZGluZ1JlbGF0aXZlID8gMSA6IDAsXG5cblx0XHQvLyBUaGUgZm91bmRhdGlvbmFsIG1hdGNoZXIgZW5zdXJlcyB0aGF0IGVsZW1lbnRzIGFyZSByZWFjaGFibGUgZnJvbSB0b3AtbGV2ZWwgY29udGV4dChzKVxuXHRcdG1hdGNoQ29udGV4dCA9IGFkZENvbWJpbmF0b3IoIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0cmV0dXJuIGVsZW0gPT09IGNoZWNrQ29udGV4dDtcblx0XHR9LCBpbXBsaWNpdFJlbGF0aXZlLCB0cnVlICksXG5cdFx0bWF0Y2hBbnlDb250ZXh0ID0gYWRkQ29tYmluYXRvciggZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4gaW5kZXhPZiggY2hlY2tDb250ZXh0LCBlbGVtICkgPiAtMTtcblx0XHR9LCBpbXBsaWNpdFJlbGF0aXZlLCB0cnVlICksXG5cdFx0bWF0Y2hlcnMgPSBbIGZ1bmN0aW9uKCBlbGVtLCBjb250ZXh0LCB4bWwgKSB7XG5cdFx0XHR2YXIgcmV0ID0gKCAhbGVhZGluZ1JlbGF0aXZlICYmICggeG1sIHx8IGNvbnRleHQgIT09IG91dGVybW9zdENvbnRleHQgKSApIHx8IChcblx0XHRcdFx0KCBjaGVja0NvbnRleHQgPSBjb250ZXh0ICkubm9kZVR5cGUgP1xuXHRcdFx0XHRcdG1hdGNoQ29udGV4dCggZWxlbSwgY29udGV4dCwgeG1sICkgOlxuXHRcdFx0XHRcdG1hdGNoQW55Q29udGV4dCggZWxlbSwgY29udGV4dCwgeG1sICkgKTtcblxuXHRcdFx0Ly8gQXZvaWQgaGFuZ2luZyBvbnRvIGVsZW1lbnQgKGlzc3VlICMyOTkpXG5cdFx0XHRjaGVja0NvbnRleHQgPSBudWxsO1xuXHRcdFx0cmV0dXJuIHJldDtcblx0XHR9IF07XG5cblx0Zm9yICggOyBpIDwgbGVuOyBpKysgKSB7XG5cdFx0aWYgKCAoIG1hdGNoZXIgPSBFeHByLnJlbGF0aXZlWyB0b2tlbnNbIGkgXS50eXBlIF0gKSApIHtcblx0XHRcdG1hdGNoZXJzID0gWyBhZGRDb21iaW5hdG9yKCBlbGVtZW50TWF0Y2hlciggbWF0Y2hlcnMgKSwgbWF0Y2hlciApIF07XG5cdFx0fSBlbHNlIHtcblx0XHRcdG1hdGNoZXIgPSBFeHByLmZpbHRlclsgdG9rZW5zWyBpIF0udHlwZSBdLmFwcGx5KCBudWxsLCB0b2tlbnNbIGkgXS5tYXRjaGVzICk7XG5cblx0XHRcdC8vIFJldHVybiBzcGVjaWFsIHVwb24gc2VlaW5nIGEgcG9zaXRpb25hbCBtYXRjaGVyXG5cdFx0XHRpZiAoIG1hdGNoZXJbIGV4cGFuZG8gXSApIHtcblxuXHRcdFx0XHQvLyBGaW5kIHRoZSBuZXh0IHJlbGF0aXZlIG9wZXJhdG9yIChpZiBhbnkpIGZvciBwcm9wZXIgaGFuZGxpbmdcblx0XHRcdFx0aiA9ICsraTtcblx0XHRcdFx0Zm9yICggOyBqIDwgbGVuOyBqKysgKSB7XG5cdFx0XHRcdFx0aWYgKCBFeHByLnJlbGF0aXZlWyB0b2tlbnNbIGogXS50eXBlIF0gKSB7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHNldE1hdGNoZXIoXG5cdFx0XHRcdFx0aSA+IDEgJiYgZWxlbWVudE1hdGNoZXIoIG1hdGNoZXJzICksXG5cdFx0XHRcdFx0aSA+IDEgJiYgdG9TZWxlY3RvcihcblxuXHRcdFx0XHRcdC8vIElmIHRoZSBwcmVjZWRpbmcgdG9rZW4gd2FzIGEgZGVzY2VuZGFudCBjb21iaW5hdG9yLCBpbnNlcnQgYW4gaW1wbGljaXQgYW55LWVsZW1lbnQgYCpgXG5cdFx0XHRcdFx0dG9rZW5zXG5cdFx0XHRcdFx0XHQuc2xpY2UoIDAsIGkgLSAxIClcblx0XHRcdFx0XHRcdC5jb25jYXQoIHsgdmFsdWU6IHRva2Vuc1sgaSAtIDIgXS50eXBlID09PSBcIiBcIiA/IFwiKlwiIDogXCJcIiB9IClcblx0XHRcdFx0XHQpLnJlcGxhY2UoIHJ0cmltLCBcIiQxXCIgKSxcblx0XHRcdFx0XHRtYXRjaGVyLFxuXHRcdFx0XHRcdGkgPCBqICYmIG1hdGNoZXJGcm9tVG9rZW5zKCB0b2tlbnMuc2xpY2UoIGksIGogKSApLFxuXHRcdFx0XHRcdGogPCBsZW4gJiYgbWF0Y2hlckZyb21Ub2tlbnMoICggdG9rZW5zID0gdG9rZW5zLnNsaWNlKCBqICkgKSApLFxuXHRcdFx0XHRcdGogPCBsZW4gJiYgdG9TZWxlY3RvciggdG9rZW5zIClcblx0XHRcdFx0KTtcblx0XHRcdH1cblx0XHRcdG1hdGNoZXJzLnB1c2goIG1hdGNoZXIgKTtcblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gZWxlbWVudE1hdGNoZXIoIG1hdGNoZXJzICk7XG59XG5cbmZ1bmN0aW9uIG1hdGNoZXJGcm9tR3JvdXBNYXRjaGVycyggZWxlbWVudE1hdGNoZXJzLCBzZXRNYXRjaGVycyApIHtcblx0dmFyIGJ5U2V0ID0gc2V0TWF0Y2hlcnMubGVuZ3RoID4gMCxcblx0XHRieUVsZW1lbnQgPSBlbGVtZW50TWF0Y2hlcnMubGVuZ3RoID4gMCxcblx0XHRzdXBlck1hdGNoZXIgPSBmdW5jdGlvbiggc2VlZCwgY29udGV4dCwgeG1sLCByZXN1bHRzLCBvdXRlcm1vc3QgKSB7XG5cdFx0XHR2YXIgZWxlbSwgaiwgbWF0Y2hlcixcblx0XHRcdFx0bWF0Y2hlZENvdW50ID0gMCxcblx0XHRcdFx0aSA9IFwiMFwiLFxuXHRcdFx0XHR1bm1hdGNoZWQgPSBzZWVkICYmIFtdLFxuXHRcdFx0XHRzZXRNYXRjaGVkID0gW10sXG5cdFx0XHRcdGNvbnRleHRCYWNrdXAgPSBvdXRlcm1vc3RDb250ZXh0LFxuXG5cdFx0XHRcdC8vIFdlIG11c3QgYWx3YXlzIGhhdmUgZWl0aGVyIHNlZWQgZWxlbWVudHMgb3Igb3V0ZXJtb3N0IGNvbnRleHRcblx0XHRcdFx0ZWxlbXMgPSBzZWVkIHx8IGJ5RWxlbWVudCAmJiBFeHByLmZpbmRbIFwiVEFHXCIgXSggXCIqXCIsIG91dGVybW9zdCApLFxuXG5cdFx0XHRcdC8vIFVzZSBpbnRlZ2VyIGRpcnJ1bnMgaWZmIHRoaXMgaXMgdGhlIG91dGVybW9zdCBtYXRjaGVyXG5cdFx0XHRcdGRpcnJ1bnNVbmlxdWUgPSAoIGRpcnJ1bnMgKz0gY29udGV4dEJhY2t1cCA9PSBudWxsID8gMSA6IE1hdGgucmFuZG9tKCkgfHwgMC4xICksXG5cdFx0XHRcdGxlbiA9IGVsZW1zLmxlbmd0aDtcblxuXHRcdFx0aWYgKCBvdXRlcm1vc3QgKSB7XG5cblx0XHRcdFx0Ly8gU3VwcG9ydDogSUUgMTErLCBFZGdlIDE3IC0gMTgrXG5cdFx0XHRcdC8vIElFL0VkZ2Ugc29tZXRpbWVzIHRocm93IGEgXCJQZXJtaXNzaW9uIGRlbmllZFwiIGVycm9yIHdoZW4gc3RyaWN0LWNvbXBhcmluZ1xuXHRcdFx0XHQvLyB0d28gZG9jdW1lbnRzOyBzaGFsbG93IGNvbXBhcmlzb25zIHdvcmsuXG5cdFx0XHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBlcWVxZXFcblx0XHRcdFx0b3V0ZXJtb3N0Q29udGV4dCA9IGNvbnRleHQgPT0gZG9jdW1lbnQgfHwgY29udGV4dCB8fCBvdXRlcm1vc3Q7XG5cdFx0XHR9XG5cblx0XHRcdC8vIEFkZCBlbGVtZW50cyBwYXNzaW5nIGVsZW1lbnRNYXRjaGVycyBkaXJlY3RseSB0byByZXN1bHRzXG5cdFx0XHQvLyBTdXBwb3J0OiBJRTw5LCBTYWZhcmlcblx0XHRcdC8vIFRvbGVyYXRlIE5vZGVMaXN0IHByb3BlcnRpZXMgKElFOiBcImxlbmd0aFwiOyBTYWZhcmk6IDxudW1iZXI+KSBtYXRjaGluZyBlbGVtZW50cyBieSBpZFxuXHRcdFx0Zm9yICggOyBpICE9PSBsZW4gJiYgKCBlbGVtID0gZWxlbXNbIGkgXSApICE9IG51bGw7IGkrKyApIHtcblx0XHRcdFx0aWYgKCBieUVsZW1lbnQgJiYgZWxlbSApIHtcblx0XHRcdFx0XHRqID0gMDtcblxuXHRcdFx0XHRcdC8vIFN1cHBvcnQ6IElFIDExKywgRWRnZSAxNyAtIDE4K1xuXHRcdFx0XHRcdC8vIElFL0VkZ2Ugc29tZXRpbWVzIHRocm93IGEgXCJQZXJtaXNzaW9uIGRlbmllZFwiIGVycm9yIHdoZW4gc3RyaWN0LWNvbXBhcmluZ1xuXHRcdFx0XHRcdC8vIHR3byBkb2N1bWVudHM7IHNoYWxsb3cgY29tcGFyaXNvbnMgd29yay5cblx0XHRcdFx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZXFlcWVxXG5cdFx0XHRcdFx0aWYgKCAhY29udGV4dCAmJiBlbGVtLm93bmVyRG9jdW1lbnQgIT0gZG9jdW1lbnQgKSB7XG5cdFx0XHRcdFx0XHRzZXREb2N1bWVudCggZWxlbSApO1xuXHRcdFx0XHRcdFx0eG1sID0gIWRvY3VtZW50SXNIVE1MO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHR3aGlsZSAoICggbWF0Y2hlciA9IGVsZW1lbnRNYXRjaGVyc1sgaisrIF0gKSApIHtcblx0XHRcdFx0XHRcdGlmICggbWF0Y2hlciggZWxlbSwgY29udGV4dCB8fCBkb2N1bWVudCwgeG1sICkgKSB7XG5cdFx0XHRcdFx0XHRcdHJlc3VsdHMucHVzaCggZWxlbSApO1xuXHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0aWYgKCBvdXRlcm1vc3QgKSB7XG5cdFx0XHRcdFx0XHRkaXJydW5zID0gZGlycnVuc1VuaXF1ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBUcmFjayB1bm1hdGNoZWQgZWxlbWVudHMgZm9yIHNldCBmaWx0ZXJzXG5cdFx0XHRcdGlmICggYnlTZXQgKSB7XG5cblx0XHRcdFx0XHQvLyBUaGV5IHdpbGwgaGF2ZSBnb25lIHRocm91Z2ggYWxsIHBvc3NpYmxlIG1hdGNoZXJzXG5cdFx0XHRcdFx0aWYgKCAoIGVsZW0gPSAhbWF0Y2hlciAmJiBlbGVtICkgKSB7XG5cdFx0XHRcdFx0XHRtYXRjaGVkQ291bnQtLTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHQvLyBMZW5ndGhlbiB0aGUgYXJyYXkgZm9yIGV2ZXJ5IGVsZW1lbnQsIG1hdGNoZWQgb3Igbm90XG5cdFx0XHRcdFx0aWYgKCBzZWVkICkge1xuXHRcdFx0XHRcdFx0dW5tYXRjaGVkLnB1c2goIGVsZW0gKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Ly8gYGlgIGlzIG5vdyB0aGUgY291bnQgb2YgZWxlbWVudHMgdmlzaXRlZCBhYm92ZSwgYW5kIGFkZGluZyBpdCB0byBgbWF0Y2hlZENvdW50YFxuXHRcdFx0Ly8gbWFrZXMgdGhlIGxhdHRlciBub25uZWdhdGl2ZS5cblx0XHRcdG1hdGNoZWRDb3VudCArPSBpO1xuXG5cdFx0XHQvLyBBcHBseSBzZXQgZmlsdGVycyB0byB1bm1hdGNoZWQgZWxlbWVudHNcblx0XHRcdC8vIE5PVEU6IFRoaXMgY2FuIGJlIHNraXBwZWQgaWYgdGhlcmUgYXJlIG5vIHVubWF0Y2hlZCBlbGVtZW50cyAoaS5lLiwgYG1hdGNoZWRDb3VudGBcblx0XHRcdC8vIGVxdWFscyBgaWApLCB1bmxlc3Mgd2UgZGlkbid0IHZpc2l0IF9hbnlfIGVsZW1lbnRzIGluIHRoZSBhYm92ZSBsb29wIGJlY2F1c2Ugd2UgaGF2ZVxuXHRcdFx0Ly8gbm8gZWxlbWVudCBtYXRjaGVycyBhbmQgbm8gc2VlZC5cblx0XHRcdC8vIEluY3JlbWVudGluZyBhbiBpbml0aWFsbHktc3RyaW5nIFwiMFwiIGBpYCBhbGxvd3MgYGlgIHRvIHJlbWFpbiBhIHN0cmluZyBvbmx5IGluIHRoYXRcblx0XHRcdC8vIGNhc2UsIHdoaWNoIHdpbGwgcmVzdWx0IGluIGEgXCIwMFwiIGBtYXRjaGVkQ291bnRgIHRoYXQgZGlmZmVycyBmcm9tIGBpYCBidXQgaXMgYWxzb1xuXHRcdFx0Ly8gbnVtZXJpY2FsbHkgemVyby5cblx0XHRcdGlmICggYnlTZXQgJiYgaSAhPT0gbWF0Y2hlZENvdW50ICkge1xuXHRcdFx0XHRqID0gMDtcblx0XHRcdFx0d2hpbGUgKCAoIG1hdGNoZXIgPSBzZXRNYXRjaGVyc1sgaisrIF0gKSApIHtcblx0XHRcdFx0XHRtYXRjaGVyKCB1bm1hdGNoZWQsIHNldE1hdGNoZWQsIGNvbnRleHQsIHhtbCApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0aWYgKCBzZWVkICkge1xuXG5cdFx0XHRcdFx0Ly8gUmVpbnRlZ3JhdGUgZWxlbWVudCBtYXRjaGVzIHRvIGVsaW1pbmF0ZSB0aGUgbmVlZCBmb3Igc29ydGluZ1xuXHRcdFx0XHRcdGlmICggbWF0Y2hlZENvdW50ID4gMCApIHtcblx0XHRcdFx0XHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0XHRcdFx0XHRpZiAoICEoIHVubWF0Y2hlZFsgaSBdIHx8IHNldE1hdGNoZWRbIGkgXSApICkge1xuXHRcdFx0XHRcdFx0XHRcdHNldE1hdGNoZWRbIGkgXSA9IHBvcC5jYWxsKCByZXN1bHRzICk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHQvLyBEaXNjYXJkIGluZGV4IHBsYWNlaG9sZGVyIHZhbHVlcyB0byBnZXQgb25seSBhY3R1YWwgbWF0Y2hlc1xuXHRcdFx0XHRcdHNldE1hdGNoZWQgPSBjb25kZW5zZSggc2V0TWF0Y2hlZCApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gQWRkIG1hdGNoZXMgdG8gcmVzdWx0c1xuXHRcdFx0XHRwdXNoLmFwcGx5KCByZXN1bHRzLCBzZXRNYXRjaGVkICk7XG5cblx0XHRcdFx0Ly8gU2VlZGxlc3Mgc2V0IG1hdGNoZXMgc3VjY2VlZGluZyBtdWx0aXBsZSBzdWNjZXNzZnVsIG1hdGNoZXJzIHN0aXB1bGF0ZSBzb3J0aW5nXG5cdFx0XHRcdGlmICggb3V0ZXJtb3N0ICYmICFzZWVkICYmIHNldE1hdGNoZWQubGVuZ3RoID4gMCAmJlxuXHRcdFx0XHRcdCggbWF0Y2hlZENvdW50ICsgc2V0TWF0Y2hlcnMubGVuZ3RoICkgPiAxICkge1xuXG5cdFx0XHRcdFx0U2l6emxlLnVuaXF1ZVNvcnQoIHJlc3VsdHMgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBPdmVycmlkZSBtYW5pcHVsYXRpb24gb2YgZ2xvYmFscyBieSBuZXN0ZWQgbWF0Y2hlcnNcblx0XHRcdGlmICggb3V0ZXJtb3N0ICkge1xuXHRcdFx0XHRkaXJydW5zID0gZGlycnVuc1VuaXF1ZTtcblx0XHRcdFx0b3V0ZXJtb3N0Q29udGV4dCA9IGNvbnRleHRCYWNrdXA7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiB1bm1hdGNoZWQ7XG5cdFx0fTtcblxuXHRyZXR1cm4gYnlTZXQgP1xuXHRcdG1hcmtGdW5jdGlvbiggc3VwZXJNYXRjaGVyICkgOlxuXHRcdHN1cGVyTWF0Y2hlcjtcbn1cblxuY29tcGlsZSA9IFNpenpsZS5jb21waWxlID0gZnVuY3Rpb24oIHNlbGVjdG9yLCBtYXRjaCAvKiBJbnRlcm5hbCBVc2UgT25seSAqLyApIHtcblx0dmFyIGksXG5cdFx0c2V0TWF0Y2hlcnMgPSBbXSxcblx0XHRlbGVtZW50TWF0Y2hlcnMgPSBbXSxcblx0XHRjYWNoZWQgPSBjb21waWxlckNhY2hlWyBzZWxlY3RvciArIFwiIFwiIF07XG5cblx0aWYgKCAhY2FjaGVkICkge1xuXG5cdFx0Ly8gR2VuZXJhdGUgYSBmdW5jdGlvbiBvZiByZWN1cnNpdmUgZnVuY3Rpb25zIHRoYXQgY2FuIGJlIHVzZWQgdG8gY2hlY2sgZWFjaCBlbGVtZW50XG5cdFx0aWYgKCAhbWF0Y2ggKSB7XG5cdFx0XHRtYXRjaCA9IHRva2VuaXplKCBzZWxlY3RvciApO1xuXHRcdH1cblx0XHRpID0gbWF0Y2gubGVuZ3RoO1xuXHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0Y2FjaGVkID0gbWF0Y2hlckZyb21Ub2tlbnMoIG1hdGNoWyBpIF0gKTtcblx0XHRcdGlmICggY2FjaGVkWyBleHBhbmRvIF0gKSB7XG5cdFx0XHRcdHNldE1hdGNoZXJzLnB1c2goIGNhY2hlZCApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0ZWxlbWVudE1hdGNoZXJzLnB1c2goIGNhY2hlZCApO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIENhY2hlIHRoZSBjb21waWxlZCBmdW5jdGlvblxuXHRcdGNhY2hlZCA9IGNvbXBpbGVyQ2FjaGUoXG5cdFx0XHRzZWxlY3Rvcixcblx0XHRcdG1hdGNoZXJGcm9tR3JvdXBNYXRjaGVycyggZWxlbWVudE1hdGNoZXJzLCBzZXRNYXRjaGVycyApXG5cdFx0KTtcblxuXHRcdC8vIFNhdmUgc2VsZWN0b3IgYW5kIHRva2VuaXphdGlvblxuXHRcdGNhY2hlZC5zZWxlY3RvciA9IHNlbGVjdG9yO1xuXHR9XG5cdHJldHVybiBjYWNoZWQ7XG59O1xuXG4vKipcbiAqIEEgbG93LWxldmVsIHNlbGVjdGlvbiBmdW5jdGlvbiB0aGF0IHdvcmtzIHdpdGggU2l6emxlJ3MgY29tcGlsZWRcbiAqICBzZWxlY3RvciBmdW5jdGlvbnNcbiAqIEBwYXJhbSB7U3RyaW5nfEZ1bmN0aW9ufSBzZWxlY3RvciBBIHNlbGVjdG9yIG9yIGEgcHJlLWNvbXBpbGVkXG4gKiAgc2VsZWN0b3IgZnVuY3Rpb24gYnVpbHQgd2l0aCBTaXp6bGUuY29tcGlsZVxuICogQHBhcmFtIHtFbGVtZW50fSBjb250ZXh0XG4gKiBAcGFyYW0ge0FycmF5fSBbcmVzdWx0c11cbiAqIEBwYXJhbSB7QXJyYXl9IFtzZWVkXSBBIHNldCBvZiBlbGVtZW50cyB0byBtYXRjaCBhZ2FpbnN0XG4gKi9cbnNlbGVjdCA9IFNpenpsZS5zZWxlY3QgPSBmdW5jdGlvbiggc2VsZWN0b3IsIGNvbnRleHQsIHJlc3VsdHMsIHNlZWQgKSB7XG5cdHZhciBpLCB0b2tlbnMsIHRva2VuLCB0eXBlLCBmaW5kLFxuXHRcdGNvbXBpbGVkID0gdHlwZW9mIHNlbGVjdG9yID09PSBcImZ1bmN0aW9uXCIgJiYgc2VsZWN0b3IsXG5cdFx0bWF0Y2ggPSAhc2VlZCAmJiB0b2tlbml6ZSggKCBzZWxlY3RvciA9IGNvbXBpbGVkLnNlbGVjdG9yIHx8IHNlbGVjdG9yICkgKTtcblxuXHRyZXN1bHRzID0gcmVzdWx0cyB8fCBbXTtcblxuXHQvLyBUcnkgdG8gbWluaW1pemUgb3BlcmF0aW9ucyBpZiB0aGVyZSBpcyBvbmx5IG9uZSBzZWxlY3RvciBpbiB0aGUgbGlzdCBhbmQgbm8gc2VlZFxuXHQvLyAodGhlIGxhdHRlciBvZiB3aGljaCBndWFyYW50ZWVzIHVzIGNvbnRleHQpXG5cdGlmICggbWF0Y2gubGVuZ3RoID09PSAxICkge1xuXG5cdFx0Ly8gUmVkdWNlIGNvbnRleHQgaWYgdGhlIGxlYWRpbmcgY29tcG91bmQgc2VsZWN0b3IgaXMgYW4gSURcblx0XHR0b2tlbnMgPSBtYXRjaFsgMCBdID0gbWF0Y2hbIDAgXS5zbGljZSggMCApO1xuXHRcdGlmICggdG9rZW5zLmxlbmd0aCA+IDIgJiYgKCB0b2tlbiA9IHRva2Vuc1sgMCBdICkudHlwZSA9PT0gXCJJRFwiICYmXG5cdFx0XHRjb250ZXh0Lm5vZGVUeXBlID09PSA5ICYmIGRvY3VtZW50SXNIVE1MICYmIEV4cHIucmVsYXRpdmVbIHRva2Vuc1sgMSBdLnR5cGUgXSApIHtcblxuXHRcdFx0Y29udGV4dCA9ICggRXhwci5maW5kWyBcIklEXCIgXSggdG9rZW4ubWF0Y2hlc1sgMCBdXG5cdFx0XHRcdC5yZXBsYWNlKCBydW5lc2NhcGUsIGZ1bmVzY2FwZSApLCBjb250ZXh0ICkgfHwgW10gKVsgMCBdO1xuXHRcdFx0aWYgKCAhY29udGV4dCApIHtcblx0XHRcdFx0cmV0dXJuIHJlc3VsdHM7XG5cblx0XHRcdC8vIFByZWNvbXBpbGVkIG1hdGNoZXJzIHdpbGwgc3RpbGwgdmVyaWZ5IGFuY2VzdHJ5LCBzbyBzdGVwIHVwIGEgbGV2ZWxcblx0XHRcdH0gZWxzZSBpZiAoIGNvbXBpbGVkICkge1xuXHRcdFx0XHRjb250ZXh0ID0gY29udGV4dC5wYXJlbnROb2RlO1xuXHRcdFx0fVxuXG5cdFx0XHRzZWxlY3RvciA9IHNlbGVjdG9yLnNsaWNlKCB0b2tlbnMuc2hpZnQoKS52YWx1ZS5sZW5ndGggKTtcblx0XHR9XG5cblx0XHQvLyBGZXRjaCBhIHNlZWQgc2V0IGZvciByaWdodC10by1sZWZ0IG1hdGNoaW5nXG5cdFx0aSA9IG1hdGNoRXhwclsgXCJuZWVkc0NvbnRleHRcIiBdLnRlc3QoIHNlbGVjdG9yICkgPyAwIDogdG9rZW5zLmxlbmd0aDtcblx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdHRva2VuID0gdG9rZW5zWyBpIF07XG5cblx0XHRcdC8vIEFib3J0IGlmIHdlIGhpdCBhIGNvbWJpbmF0b3Jcblx0XHRcdGlmICggRXhwci5yZWxhdGl2ZVsgKCB0eXBlID0gdG9rZW4udHlwZSApIF0gKSB7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0fVxuXHRcdFx0aWYgKCAoIGZpbmQgPSBFeHByLmZpbmRbIHR5cGUgXSApICkge1xuXG5cdFx0XHRcdC8vIFNlYXJjaCwgZXhwYW5kaW5nIGNvbnRleHQgZm9yIGxlYWRpbmcgc2libGluZyBjb21iaW5hdG9yc1xuXHRcdFx0XHRpZiAoICggc2VlZCA9IGZpbmQoXG5cdFx0XHRcdFx0dG9rZW4ubWF0Y2hlc1sgMCBdLnJlcGxhY2UoIHJ1bmVzY2FwZSwgZnVuZXNjYXBlICksXG5cdFx0XHRcdFx0cnNpYmxpbmcudGVzdCggdG9rZW5zWyAwIF0udHlwZSApICYmIHRlc3RDb250ZXh0KCBjb250ZXh0LnBhcmVudE5vZGUgKSB8fFxuXHRcdFx0XHRcdFx0Y29udGV4dFxuXHRcdFx0XHQpICkgKSB7XG5cblx0XHRcdFx0XHQvLyBJZiBzZWVkIGlzIGVtcHR5IG9yIG5vIHRva2VucyByZW1haW4sIHdlIGNhbiByZXR1cm4gZWFybHlcblx0XHRcdFx0XHR0b2tlbnMuc3BsaWNlKCBpLCAxICk7XG5cdFx0XHRcdFx0c2VsZWN0b3IgPSBzZWVkLmxlbmd0aCAmJiB0b1NlbGVjdG9yKCB0b2tlbnMgKTtcblx0XHRcdFx0XHRpZiAoICFzZWxlY3RvciApIHtcblx0XHRcdFx0XHRcdHB1c2guYXBwbHkoIHJlc3VsdHMsIHNlZWQgKTtcblx0XHRcdFx0XHRcdHJldHVybiByZXN1bHRzO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0Ly8gQ29tcGlsZSBhbmQgZXhlY3V0ZSBhIGZpbHRlcmluZyBmdW5jdGlvbiBpZiBvbmUgaXMgbm90IHByb3ZpZGVkXG5cdC8vIFByb3ZpZGUgYG1hdGNoYCB0byBhdm9pZCByZXRva2VuaXphdGlvbiBpZiB3ZSBtb2RpZmllZCB0aGUgc2VsZWN0b3IgYWJvdmVcblx0KCBjb21waWxlZCB8fCBjb21waWxlKCBzZWxlY3RvciwgbWF0Y2ggKSApKFxuXHRcdHNlZWQsXG5cdFx0Y29udGV4dCxcblx0XHQhZG9jdW1lbnRJc0hUTUwsXG5cdFx0cmVzdWx0cyxcblx0XHQhY29udGV4dCB8fCByc2libGluZy50ZXN0KCBzZWxlY3RvciApICYmIHRlc3RDb250ZXh0KCBjb250ZXh0LnBhcmVudE5vZGUgKSB8fCBjb250ZXh0XG5cdCk7XG5cdHJldHVybiByZXN1bHRzO1xufTtcblxuLy8gT25lLXRpbWUgYXNzaWdubWVudHNcblxuLy8gU29ydCBzdGFiaWxpdHlcbnN1cHBvcnQuc29ydFN0YWJsZSA9IGV4cGFuZG8uc3BsaXQoIFwiXCIgKS5zb3J0KCBzb3J0T3JkZXIgKS5qb2luKCBcIlwiICkgPT09IGV4cGFuZG87XG5cbi8vIFN1cHBvcnQ6IENocm9tZSAxNC0zNStcbi8vIEFsd2F5cyBhc3N1bWUgZHVwbGljYXRlcyBpZiB0aGV5IGFyZW4ndCBwYXNzZWQgdG8gdGhlIGNvbXBhcmlzb24gZnVuY3Rpb25cbnN1cHBvcnQuZGV0ZWN0RHVwbGljYXRlcyA9ICEhaGFzRHVwbGljYXRlO1xuXG4vLyBJbml0aWFsaXplIGFnYWluc3QgdGhlIGRlZmF1bHQgZG9jdW1lbnRcbnNldERvY3VtZW50KCk7XG5cbi8vIFN1cHBvcnQ6IFdlYmtpdDw1MzcuMzIgLSBTYWZhcmkgNi4wLjMvQ2hyb21lIDI1IChmaXhlZCBpbiBDaHJvbWUgMjcpXG4vLyBEZXRhY2hlZCBub2RlcyBjb25mb3VuZGluZ2x5IGZvbGxvdyAqZWFjaCBvdGhlcipcbnN1cHBvcnQuc29ydERldGFjaGVkID0gYXNzZXJ0KCBmdW5jdGlvbiggZWwgKSB7XG5cblx0Ly8gU2hvdWxkIHJldHVybiAxLCBidXQgcmV0dXJucyA0IChmb2xsb3dpbmcpXG5cdHJldHVybiBlbC5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbiggZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJmaWVsZHNldFwiICkgKSAmIDE7XG59ICk7XG5cbi8vIFN1cHBvcnQ6IElFPDhcbi8vIFByZXZlbnQgYXR0cmlidXRlL3Byb3BlcnR5IFwiaW50ZXJwb2xhdGlvblwiXG4vLyBodHRwczovL21zZG4ubWljcm9zb2Z0LmNvbS9lbi11cy9saWJyYXJ5L21zNTM2NDI5JTI4VlMuODUlMjkuYXNweFxuaWYgKCAhYXNzZXJ0KCBmdW5jdGlvbiggZWwgKSB7XG5cdGVsLmlubmVySFRNTCA9IFwiPGEgaHJlZj0nIyc+PC9hPlwiO1xuXHRyZXR1cm4gZWwuZmlyc3RDaGlsZC5nZXRBdHRyaWJ1dGUoIFwiaHJlZlwiICkgPT09IFwiI1wiO1xufSApICkge1xuXHRhZGRIYW5kbGUoIFwidHlwZXxocmVmfGhlaWdodHx3aWR0aFwiLCBmdW5jdGlvbiggZWxlbSwgbmFtZSwgaXNYTUwgKSB7XG5cdFx0aWYgKCAhaXNYTUwgKSB7XG5cdFx0XHRyZXR1cm4gZWxlbS5nZXRBdHRyaWJ1dGUoIG5hbWUsIG5hbWUudG9Mb3dlckNhc2UoKSA9PT0gXCJ0eXBlXCIgPyAxIDogMiApO1xuXHRcdH1cblx0fSApO1xufVxuXG4vLyBTdXBwb3J0OiBJRTw5XG4vLyBVc2UgZGVmYXVsdFZhbHVlIGluIHBsYWNlIG9mIGdldEF0dHJpYnV0ZShcInZhbHVlXCIpXG5pZiAoICFzdXBwb3J0LmF0dHJpYnV0ZXMgfHwgIWFzc2VydCggZnVuY3Rpb24oIGVsICkge1xuXHRlbC5pbm5lckhUTUwgPSBcIjxpbnB1dC8+XCI7XG5cdGVsLmZpcnN0Q2hpbGQuc2V0QXR0cmlidXRlKCBcInZhbHVlXCIsIFwiXCIgKTtcblx0cmV0dXJuIGVsLmZpcnN0Q2hpbGQuZ2V0QXR0cmlidXRlKCBcInZhbHVlXCIgKSA9PT0gXCJcIjtcbn0gKSApIHtcblx0YWRkSGFuZGxlKCBcInZhbHVlXCIsIGZ1bmN0aW9uKCBlbGVtLCBfbmFtZSwgaXNYTUwgKSB7XG5cdFx0aWYgKCAhaXNYTUwgJiYgZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpID09PSBcImlucHV0XCIgKSB7XG5cdFx0XHRyZXR1cm4gZWxlbS5kZWZhdWx0VmFsdWU7XG5cdFx0fVxuXHR9ICk7XG59XG5cbi8vIFN1cHBvcnQ6IElFPDlcbi8vIFVzZSBnZXRBdHRyaWJ1dGVOb2RlIHRvIGZldGNoIGJvb2xlYW5zIHdoZW4gZ2V0QXR0cmlidXRlIGxpZXNcbmlmICggIWFzc2VydCggZnVuY3Rpb24oIGVsICkge1xuXHRyZXR1cm4gZWwuZ2V0QXR0cmlidXRlKCBcImRpc2FibGVkXCIgKSA9PSBudWxsO1xufSApICkge1xuXHRhZGRIYW5kbGUoIGJvb2xlYW5zLCBmdW5jdGlvbiggZWxlbSwgbmFtZSwgaXNYTUwgKSB7XG5cdFx0dmFyIHZhbDtcblx0XHRpZiAoICFpc1hNTCApIHtcblx0XHRcdHJldHVybiBlbGVtWyBuYW1lIF0gPT09IHRydWUgPyBuYW1lLnRvTG93ZXJDYXNlKCkgOlxuXHRcdFx0XHQoIHZhbCA9IGVsZW0uZ2V0QXR0cmlidXRlTm9kZSggbmFtZSApICkgJiYgdmFsLnNwZWNpZmllZCA/XG5cdFx0XHRcdFx0dmFsLnZhbHVlIDpcblx0XHRcdFx0XHRudWxsO1xuXHRcdH1cblx0fSApO1xufVxuXG5yZXR1cm4gU2l6emxlO1xuXG59ICkoIHdpbmRvdyApO1xuXG5cblxualF1ZXJ5LmZpbmQgPSBTaXp6bGU7XG5qUXVlcnkuZXhwciA9IFNpenpsZS5zZWxlY3RvcnM7XG5cbi8vIERlcHJlY2F0ZWRcbmpRdWVyeS5leHByWyBcIjpcIiBdID0galF1ZXJ5LmV4cHIucHNldWRvcztcbmpRdWVyeS51bmlxdWVTb3J0ID0galF1ZXJ5LnVuaXF1ZSA9IFNpenpsZS51bmlxdWVTb3J0O1xualF1ZXJ5LnRleHQgPSBTaXp6bGUuZ2V0VGV4dDtcbmpRdWVyeS5pc1hNTERvYyA9IFNpenpsZS5pc1hNTDtcbmpRdWVyeS5jb250YWlucyA9IFNpenpsZS5jb250YWlucztcbmpRdWVyeS5lc2NhcGVTZWxlY3RvciA9IFNpenpsZS5lc2NhcGU7XG5cblxuXG5cbnZhciBkaXIgPSBmdW5jdGlvbiggZWxlbSwgZGlyLCB1bnRpbCApIHtcblx0dmFyIG1hdGNoZWQgPSBbXSxcblx0XHR0cnVuY2F0ZSA9IHVudGlsICE9PSB1bmRlZmluZWQ7XG5cblx0d2hpbGUgKCAoIGVsZW0gPSBlbGVtWyBkaXIgXSApICYmIGVsZW0ubm9kZVR5cGUgIT09IDkgKSB7XG5cdFx0aWYgKCBlbGVtLm5vZGVUeXBlID09PSAxICkge1xuXHRcdFx0aWYgKCB0cnVuY2F0ZSAmJiBqUXVlcnkoIGVsZW0gKS5pcyggdW50aWwgKSApIHtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0XHRtYXRjaGVkLnB1c2goIGVsZW0gKTtcblx0XHR9XG5cdH1cblx0cmV0dXJuIG1hdGNoZWQ7XG59O1xuXG5cbnZhciBzaWJsaW5ncyA9IGZ1bmN0aW9uKCBuLCBlbGVtICkge1xuXHR2YXIgbWF0Y2hlZCA9IFtdO1xuXG5cdGZvciAoIDsgbjsgbiA9IG4ubmV4dFNpYmxpbmcgKSB7XG5cdFx0aWYgKCBuLm5vZGVUeXBlID09PSAxICYmIG4gIT09IGVsZW0gKSB7XG5cdFx0XHRtYXRjaGVkLnB1c2goIG4gKTtcblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gbWF0Y2hlZDtcbn07XG5cblxudmFyIHJuZWVkc0NvbnRleHQgPSBqUXVlcnkuZXhwci5tYXRjaC5uZWVkc0NvbnRleHQ7XG5cblxuXG5mdW5jdGlvbiBub2RlTmFtZSggZWxlbSwgbmFtZSApIHtcblxuXHRyZXR1cm4gZWxlbS5ub2RlTmFtZSAmJiBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgPT09IG5hbWUudG9Mb3dlckNhc2UoKTtcblxufVxudmFyIHJzaW5nbGVUYWcgPSAoIC9ePChbYS16XVteXFwvXFwwPjpcXHgyMFxcdFxcclxcblxcZl0qKVtcXHgyMFxcdFxcclxcblxcZl0qXFwvPz4oPzo8XFwvXFwxPnwpJC9pICk7XG5cblxuXG4vLyBJbXBsZW1lbnQgdGhlIGlkZW50aWNhbCBmdW5jdGlvbmFsaXR5IGZvciBmaWx0ZXIgYW5kIG5vdFxuZnVuY3Rpb24gd2lubm93KCBlbGVtZW50cywgcXVhbGlmaWVyLCBub3QgKSB7XG5cdGlmICggaXNGdW5jdGlvbiggcXVhbGlmaWVyICkgKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5ncmVwKCBlbGVtZW50cywgZnVuY3Rpb24oIGVsZW0sIGkgKSB7XG5cdFx0XHRyZXR1cm4gISFxdWFsaWZpZXIuY2FsbCggZWxlbSwgaSwgZWxlbSApICE9PSBub3Q7XG5cdFx0fSApO1xuXHR9XG5cblx0Ly8gU2luZ2xlIGVsZW1lbnRcblx0aWYgKCBxdWFsaWZpZXIubm9kZVR5cGUgKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5ncmVwKCBlbGVtZW50cywgZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4gKCBlbGVtID09PSBxdWFsaWZpZXIgKSAhPT0gbm90O1xuXHRcdH0gKTtcblx0fVxuXG5cdC8vIEFycmF5bGlrZSBvZiBlbGVtZW50cyAoalF1ZXJ5LCBhcmd1bWVudHMsIEFycmF5KVxuXHRpZiAoIHR5cGVvZiBxdWFsaWZpZXIgIT09IFwic3RyaW5nXCIgKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5ncmVwKCBlbGVtZW50cywgZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4gKCBpbmRleE9mLmNhbGwoIHF1YWxpZmllciwgZWxlbSApID4gLTEgKSAhPT0gbm90O1xuXHRcdH0gKTtcblx0fVxuXG5cdC8vIEZpbHRlcmVkIGRpcmVjdGx5IGZvciBib3RoIHNpbXBsZSBhbmQgY29tcGxleCBzZWxlY3RvcnNcblx0cmV0dXJuIGpRdWVyeS5maWx0ZXIoIHF1YWxpZmllciwgZWxlbWVudHMsIG5vdCApO1xufVxuXG5qUXVlcnkuZmlsdGVyID0gZnVuY3Rpb24oIGV4cHIsIGVsZW1zLCBub3QgKSB7XG5cdHZhciBlbGVtID0gZWxlbXNbIDAgXTtcblxuXHRpZiAoIG5vdCApIHtcblx0XHRleHByID0gXCI6bm90KFwiICsgZXhwciArIFwiKVwiO1xuXHR9XG5cblx0aWYgKCBlbGVtcy5sZW5ndGggPT09IDEgJiYgZWxlbS5ub2RlVHlwZSA9PT0gMSApIHtcblx0XHRyZXR1cm4galF1ZXJ5LmZpbmQubWF0Y2hlc1NlbGVjdG9yKCBlbGVtLCBleHByICkgPyBbIGVsZW0gXSA6IFtdO1xuXHR9XG5cblx0cmV0dXJuIGpRdWVyeS5maW5kLm1hdGNoZXMoIGV4cHIsIGpRdWVyeS5ncmVwKCBlbGVtcywgZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0cmV0dXJuIGVsZW0ubm9kZVR5cGUgPT09IDE7XG5cdH0gKSApO1xufTtcblxualF1ZXJ5LmZuLmV4dGVuZCgge1xuXHRmaW5kOiBmdW5jdGlvbiggc2VsZWN0b3IgKSB7XG5cdFx0dmFyIGksIHJldCxcblx0XHRcdGxlbiA9IHRoaXMubGVuZ3RoLFxuXHRcdFx0c2VsZiA9IHRoaXM7XG5cblx0XHRpZiAoIHR5cGVvZiBzZWxlY3RvciAhPT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayggalF1ZXJ5KCBzZWxlY3RvciApLmZpbHRlciggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGZvciAoIGkgPSAwOyBpIDwgbGVuOyBpKysgKSB7XG5cdFx0XHRcdFx0aWYgKCBqUXVlcnkuY29udGFpbnMoIHNlbGZbIGkgXSwgdGhpcyApICkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9ICkgKTtcblx0XHR9XG5cblx0XHRyZXQgPSB0aGlzLnB1c2hTdGFjayggW10gKTtcblxuXHRcdGZvciAoIGkgPSAwOyBpIDwgbGVuOyBpKysgKSB7XG5cdFx0XHRqUXVlcnkuZmluZCggc2VsZWN0b3IsIHNlbGZbIGkgXSwgcmV0ICk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGxlbiA+IDEgPyBqUXVlcnkudW5pcXVlU29ydCggcmV0ICkgOiByZXQ7XG5cdH0sXG5cdGZpbHRlcjogZnVuY3Rpb24oIHNlbGVjdG9yICkge1xuXHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayggd2lubm93KCB0aGlzLCBzZWxlY3RvciB8fCBbXSwgZmFsc2UgKSApO1xuXHR9LFxuXHRub3Q6IGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcblx0XHRyZXR1cm4gdGhpcy5wdXNoU3RhY2soIHdpbm5vdyggdGhpcywgc2VsZWN0b3IgfHwgW10sIHRydWUgKSApO1xuXHR9LFxuXHRpczogZnVuY3Rpb24oIHNlbGVjdG9yICkge1xuXHRcdHJldHVybiAhIXdpbm5vdyhcblx0XHRcdHRoaXMsXG5cblx0XHRcdC8vIElmIHRoaXMgaXMgYSBwb3NpdGlvbmFsL3JlbGF0aXZlIHNlbGVjdG9yLCBjaGVjayBtZW1iZXJzaGlwIGluIHRoZSByZXR1cm5lZCBzZXRcblx0XHRcdC8vIHNvICQoXCJwOmZpcnN0XCIpLmlzKFwicDpsYXN0XCIpIHdvbid0IHJldHVybiB0cnVlIGZvciBhIGRvYyB3aXRoIHR3byBcInBcIi5cblx0XHRcdHR5cGVvZiBzZWxlY3RvciA9PT0gXCJzdHJpbmdcIiAmJiBybmVlZHNDb250ZXh0LnRlc3QoIHNlbGVjdG9yICkgP1xuXHRcdFx0XHRqUXVlcnkoIHNlbGVjdG9yICkgOlxuXHRcdFx0XHRzZWxlY3RvciB8fCBbXSxcblx0XHRcdGZhbHNlXG5cdFx0KS5sZW5ndGg7XG5cdH1cbn0gKTtcblxuXG4vLyBJbml0aWFsaXplIGEgalF1ZXJ5IG9iamVjdFxuXG5cbi8vIEEgY2VudHJhbCByZWZlcmVuY2UgdG8gdGhlIHJvb3QgalF1ZXJ5KGRvY3VtZW50KVxudmFyIHJvb3RqUXVlcnksXG5cblx0Ly8gQSBzaW1wbGUgd2F5IHRvIGNoZWNrIGZvciBIVE1MIHN0cmluZ3Ncblx0Ly8gUHJpb3JpdGl6ZSAjaWQgb3ZlciA8dGFnPiB0byBhdm9pZCBYU1MgdmlhIGxvY2F0aW9uLmhhc2ggKCM5NTIxKVxuXHQvLyBTdHJpY3QgSFRNTCByZWNvZ25pdGlvbiAoIzExMjkwOiBtdXN0IHN0YXJ0IHdpdGggPClcblx0Ly8gU2hvcnRjdXQgc2ltcGxlICNpZCBjYXNlIGZvciBzcGVlZFxuXHRycXVpY2tFeHByID0gL14oPzpcXHMqKDxbXFx3XFxXXSs+KVtePl0qfCMoW1xcdy1dKykpJC8sXG5cblx0aW5pdCA9IGpRdWVyeS5mbi5pbml0ID0gZnVuY3Rpb24oIHNlbGVjdG9yLCBjb250ZXh0LCByb290ICkge1xuXHRcdHZhciBtYXRjaCwgZWxlbTtcblxuXHRcdC8vIEhBTkRMRTogJChcIlwiKSwgJChudWxsKSwgJCh1bmRlZmluZWQpLCAkKGZhbHNlKVxuXHRcdGlmICggIXNlbGVjdG9yICkge1xuXHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0fVxuXG5cdFx0Ly8gTWV0aG9kIGluaXQoKSBhY2NlcHRzIGFuIGFsdGVybmF0ZSByb290alF1ZXJ5XG5cdFx0Ly8gc28gbWlncmF0ZSBjYW4gc3VwcG9ydCBqUXVlcnkuc3ViIChnaC0yMTAxKVxuXHRcdHJvb3QgPSByb290IHx8IHJvb3RqUXVlcnk7XG5cblx0XHQvLyBIYW5kbGUgSFRNTCBzdHJpbmdzXG5cdFx0aWYgKCB0eXBlb2Ygc2VsZWN0b3IgPT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHRpZiAoIHNlbGVjdG9yWyAwIF0gPT09IFwiPFwiICYmXG5cdFx0XHRcdHNlbGVjdG9yWyBzZWxlY3Rvci5sZW5ndGggLSAxIF0gPT09IFwiPlwiICYmXG5cdFx0XHRcdHNlbGVjdG9yLmxlbmd0aCA+PSAzICkge1xuXG5cdFx0XHRcdC8vIEFzc3VtZSB0aGF0IHN0cmluZ3MgdGhhdCBzdGFydCBhbmQgZW5kIHdpdGggPD4gYXJlIEhUTUwgYW5kIHNraXAgdGhlIHJlZ2V4IGNoZWNrXG5cdFx0XHRcdG1hdGNoID0gWyBudWxsLCBzZWxlY3RvciwgbnVsbCBdO1xuXG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRtYXRjaCA9IHJxdWlja0V4cHIuZXhlYyggc2VsZWN0b3IgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gTWF0Y2ggaHRtbCBvciBtYWtlIHN1cmUgbm8gY29udGV4dCBpcyBzcGVjaWZpZWQgZm9yICNpZFxuXHRcdFx0aWYgKCBtYXRjaCAmJiAoIG1hdGNoWyAxIF0gfHwgIWNvbnRleHQgKSApIHtcblxuXHRcdFx0XHQvLyBIQU5ETEU6ICQoaHRtbCkgLT4gJChhcnJheSlcblx0XHRcdFx0aWYgKCBtYXRjaFsgMSBdICkge1xuXHRcdFx0XHRcdGNvbnRleHQgPSBjb250ZXh0IGluc3RhbmNlb2YgalF1ZXJ5ID8gY29udGV4dFsgMCBdIDogY29udGV4dDtcblxuXHRcdFx0XHRcdC8vIE9wdGlvbiB0byBydW4gc2NyaXB0cyBpcyB0cnVlIGZvciBiYWNrLWNvbXBhdFxuXHRcdFx0XHRcdC8vIEludGVudGlvbmFsbHkgbGV0IHRoZSBlcnJvciBiZSB0aHJvd24gaWYgcGFyc2VIVE1MIGlzIG5vdCBwcmVzZW50XG5cdFx0XHRcdFx0alF1ZXJ5Lm1lcmdlKCB0aGlzLCBqUXVlcnkucGFyc2VIVE1MKFxuXHRcdFx0XHRcdFx0bWF0Y2hbIDEgXSxcblx0XHRcdFx0XHRcdGNvbnRleHQgJiYgY29udGV4dC5ub2RlVHlwZSA/IGNvbnRleHQub3duZXJEb2N1bWVudCB8fCBjb250ZXh0IDogZG9jdW1lbnQsXG5cdFx0XHRcdFx0XHR0cnVlXG5cdFx0XHRcdFx0KSApO1xuXG5cdFx0XHRcdFx0Ly8gSEFORExFOiAkKGh0bWwsIHByb3BzKVxuXHRcdFx0XHRcdGlmICggcnNpbmdsZVRhZy50ZXN0KCBtYXRjaFsgMSBdICkgJiYgalF1ZXJ5LmlzUGxhaW5PYmplY3QoIGNvbnRleHQgKSApIHtcblx0XHRcdFx0XHRcdGZvciAoIG1hdGNoIGluIGNvbnRleHQgKSB7XG5cblx0XHRcdFx0XHRcdFx0Ly8gUHJvcGVydGllcyBvZiBjb250ZXh0IGFyZSBjYWxsZWQgYXMgbWV0aG9kcyBpZiBwb3NzaWJsZVxuXHRcdFx0XHRcdFx0XHRpZiAoIGlzRnVuY3Rpb24oIHRoaXNbIG1hdGNoIF0gKSApIHtcblx0XHRcdFx0XHRcdFx0XHR0aGlzWyBtYXRjaCBdKCBjb250ZXh0WyBtYXRjaCBdICk7XG5cblx0XHRcdFx0XHRcdFx0Ly8gLi4uYW5kIG90aGVyd2lzZSBzZXQgYXMgYXR0cmlidXRlc1xuXHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRcdHRoaXMuYXR0ciggbWF0Y2gsIGNvbnRleHRbIG1hdGNoIF0gKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdHJldHVybiB0aGlzO1xuXG5cdFx0XHRcdC8vIEhBTkRMRTogJCgjaWQpXG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0ZWxlbSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCBtYXRjaFsgMiBdICk7XG5cblx0XHRcdFx0XHRpZiAoIGVsZW0gKSB7XG5cblx0XHRcdFx0XHRcdC8vIEluamVjdCB0aGUgZWxlbWVudCBkaXJlY3RseSBpbnRvIHRoZSBqUXVlcnkgb2JqZWN0XG5cdFx0XHRcdFx0XHR0aGlzWyAwIF0gPSBlbGVtO1xuXHRcdFx0XHRcdFx0dGhpcy5sZW5ndGggPSAxO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdFx0fVxuXG5cdFx0XHQvLyBIQU5ETEU6ICQoZXhwciwgJCguLi4pKVxuXHRcdFx0fSBlbHNlIGlmICggIWNvbnRleHQgfHwgY29udGV4dC5qcXVlcnkgKSB7XG5cdFx0XHRcdHJldHVybiAoIGNvbnRleHQgfHwgcm9vdCApLmZpbmQoIHNlbGVjdG9yICk7XG5cblx0XHRcdC8vIEhBTkRMRTogJChleHByLCBjb250ZXh0KVxuXHRcdFx0Ly8gKHdoaWNoIGlzIGp1c3QgZXF1aXZhbGVudCB0bzogJChjb250ZXh0KS5maW5kKGV4cHIpXG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRyZXR1cm4gdGhpcy5jb25zdHJ1Y3RvciggY29udGV4dCApLmZpbmQoIHNlbGVjdG9yICk7XG5cdFx0XHR9XG5cblx0XHQvLyBIQU5ETEU6ICQoRE9NRWxlbWVudClcblx0XHR9IGVsc2UgaWYgKCBzZWxlY3Rvci5ub2RlVHlwZSApIHtcblx0XHRcdHRoaXNbIDAgXSA9IHNlbGVjdG9yO1xuXHRcdFx0dGhpcy5sZW5ndGggPSAxO1xuXHRcdFx0cmV0dXJuIHRoaXM7XG5cblx0XHQvLyBIQU5ETEU6ICQoZnVuY3Rpb24pXG5cdFx0Ly8gU2hvcnRjdXQgZm9yIGRvY3VtZW50IHJlYWR5XG5cdFx0fSBlbHNlIGlmICggaXNGdW5jdGlvbiggc2VsZWN0b3IgKSApIHtcblx0XHRcdHJldHVybiByb290LnJlYWR5ICE9PSB1bmRlZmluZWQgP1xuXHRcdFx0XHRyb290LnJlYWR5KCBzZWxlY3RvciApIDpcblxuXHRcdFx0XHQvLyBFeGVjdXRlIGltbWVkaWF0ZWx5IGlmIHJlYWR5IGlzIG5vdCBwcmVzZW50XG5cdFx0XHRcdHNlbGVjdG9yKCBqUXVlcnkgKTtcblx0XHR9XG5cblx0XHRyZXR1cm4galF1ZXJ5Lm1ha2VBcnJheSggc2VsZWN0b3IsIHRoaXMgKTtcblx0fTtcblxuLy8gR2l2ZSB0aGUgaW5pdCBmdW5jdGlvbiB0aGUgalF1ZXJ5IHByb3RvdHlwZSBmb3IgbGF0ZXIgaW5zdGFudGlhdGlvblxuaW5pdC5wcm90b3R5cGUgPSBqUXVlcnkuZm47XG5cbi8vIEluaXRpYWxpemUgY2VudHJhbCByZWZlcmVuY2VcbnJvb3RqUXVlcnkgPSBqUXVlcnkoIGRvY3VtZW50ICk7XG5cblxudmFyIHJwYXJlbnRzcHJldiA9IC9eKD86cGFyZW50c3xwcmV2KD86VW50aWx8QWxsKSkvLFxuXG5cdC8vIE1ldGhvZHMgZ3VhcmFudGVlZCB0byBwcm9kdWNlIGEgdW5pcXVlIHNldCB3aGVuIHN0YXJ0aW5nIGZyb20gYSB1bmlxdWUgc2V0XG5cdGd1YXJhbnRlZWRVbmlxdWUgPSB7XG5cdFx0Y2hpbGRyZW46IHRydWUsXG5cdFx0Y29udGVudHM6IHRydWUsXG5cdFx0bmV4dDogdHJ1ZSxcblx0XHRwcmV2OiB0cnVlXG5cdH07XG5cbmpRdWVyeS5mbi5leHRlbmQoIHtcblx0aGFzOiBmdW5jdGlvbiggdGFyZ2V0ICkge1xuXHRcdHZhciB0YXJnZXRzID0galF1ZXJ5KCB0YXJnZXQsIHRoaXMgKSxcblx0XHRcdGwgPSB0YXJnZXRzLmxlbmd0aDtcblxuXHRcdHJldHVybiB0aGlzLmZpbHRlciggZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgaSA9IDA7XG5cdFx0XHRmb3IgKCA7IGkgPCBsOyBpKysgKSB7XG5cdFx0XHRcdGlmICggalF1ZXJ5LmNvbnRhaW5zKCB0aGlzLCB0YXJnZXRzWyBpIF0gKSApIHtcblx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0gKTtcblx0fSxcblxuXHRjbG9zZXN0OiBmdW5jdGlvbiggc2VsZWN0b3JzLCBjb250ZXh0ICkge1xuXHRcdHZhciBjdXIsXG5cdFx0XHRpID0gMCxcblx0XHRcdGwgPSB0aGlzLmxlbmd0aCxcblx0XHRcdG1hdGNoZWQgPSBbXSxcblx0XHRcdHRhcmdldHMgPSB0eXBlb2Ygc2VsZWN0b3JzICE9PSBcInN0cmluZ1wiICYmIGpRdWVyeSggc2VsZWN0b3JzICk7XG5cblx0XHQvLyBQb3NpdGlvbmFsIHNlbGVjdG9ycyBuZXZlciBtYXRjaCwgc2luY2UgdGhlcmUncyBubyBfc2VsZWN0aW9uXyBjb250ZXh0XG5cdFx0aWYgKCAhcm5lZWRzQ29udGV4dC50ZXN0KCBzZWxlY3RvcnMgKSApIHtcblx0XHRcdGZvciAoIDsgaSA8IGw7IGkrKyApIHtcblx0XHRcdFx0Zm9yICggY3VyID0gdGhpc1sgaSBdOyBjdXIgJiYgY3VyICE9PSBjb250ZXh0OyBjdXIgPSBjdXIucGFyZW50Tm9kZSApIHtcblxuXHRcdFx0XHRcdC8vIEFsd2F5cyBza2lwIGRvY3VtZW50IGZyYWdtZW50c1xuXHRcdFx0XHRcdGlmICggY3VyLm5vZGVUeXBlIDwgMTEgJiYgKCB0YXJnZXRzID9cblx0XHRcdFx0XHRcdHRhcmdldHMuaW5kZXgoIGN1ciApID4gLTEgOlxuXG5cdFx0XHRcdFx0XHQvLyBEb24ndCBwYXNzIG5vbi1lbGVtZW50cyB0byBTaXp6bGVcblx0XHRcdFx0XHRcdGN1ci5ub2RlVHlwZSA9PT0gMSAmJlxuXHRcdFx0XHRcdFx0XHRqUXVlcnkuZmluZC5tYXRjaGVzU2VsZWN0b3IoIGN1ciwgc2VsZWN0b3JzICkgKSApIHtcblxuXHRcdFx0XHRcdFx0bWF0Y2hlZC5wdXNoKCBjdXIgKTtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayggbWF0Y2hlZC5sZW5ndGggPiAxID8galF1ZXJ5LnVuaXF1ZVNvcnQoIG1hdGNoZWQgKSA6IG1hdGNoZWQgKTtcblx0fSxcblxuXHQvLyBEZXRlcm1pbmUgdGhlIHBvc2l0aW9uIG9mIGFuIGVsZW1lbnQgd2l0aGluIHRoZSBzZXRcblx0aW5kZXg6IGZ1bmN0aW9uKCBlbGVtICkge1xuXG5cdFx0Ly8gTm8gYXJndW1lbnQsIHJldHVybiBpbmRleCBpbiBwYXJlbnRcblx0XHRpZiAoICFlbGVtICkge1xuXHRcdFx0cmV0dXJuICggdGhpc1sgMCBdICYmIHRoaXNbIDAgXS5wYXJlbnROb2RlICkgPyB0aGlzLmZpcnN0KCkucHJldkFsbCgpLmxlbmd0aCA6IC0xO1xuXHRcdH1cblxuXHRcdC8vIEluZGV4IGluIHNlbGVjdG9yXG5cdFx0aWYgKCB0eXBlb2YgZWxlbSA9PT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdHJldHVybiBpbmRleE9mLmNhbGwoIGpRdWVyeSggZWxlbSApLCB0aGlzWyAwIF0gKTtcblx0XHR9XG5cblx0XHQvLyBMb2NhdGUgdGhlIHBvc2l0aW9uIG9mIHRoZSBkZXNpcmVkIGVsZW1lbnRcblx0XHRyZXR1cm4gaW5kZXhPZi5jYWxsKCB0aGlzLFxuXG5cdFx0XHQvLyBJZiBpdCByZWNlaXZlcyBhIGpRdWVyeSBvYmplY3QsIHRoZSBmaXJzdCBlbGVtZW50IGlzIHVzZWRcblx0XHRcdGVsZW0uanF1ZXJ5ID8gZWxlbVsgMCBdIDogZWxlbVxuXHRcdCk7XG5cdH0sXG5cblx0YWRkOiBmdW5jdGlvbiggc2VsZWN0b3IsIGNvbnRleHQgKSB7XG5cdFx0cmV0dXJuIHRoaXMucHVzaFN0YWNrKFxuXHRcdFx0alF1ZXJ5LnVuaXF1ZVNvcnQoXG5cdFx0XHRcdGpRdWVyeS5tZXJnZSggdGhpcy5nZXQoKSwgalF1ZXJ5KCBzZWxlY3RvciwgY29udGV4dCApIClcblx0XHRcdClcblx0XHQpO1xuXHR9LFxuXG5cdGFkZEJhY2s6IGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcblx0XHRyZXR1cm4gdGhpcy5hZGQoIHNlbGVjdG9yID09IG51bGwgP1xuXHRcdFx0dGhpcy5wcmV2T2JqZWN0IDogdGhpcy5wcmV2T2JqZWN0LmZpbHRlciggc2VsZWN0b3IgKVxuXHRcdCk7XG5cdH1cbn0gKTtcblxuZnVuY3Rpb24gc2libGluZyggY3VyLCBkaXIgKSB7XG5cdHdoaWxlICggKCBjdXIgPSBjdXJbIGRpciBdICkgJiYgY3VyLm5vZGVUeXBlICE9PSAxICkge31cblx0cmV0dXJuIGN1cjtcbn1cblxualF1ZXJ5LmVhY2goIHtcblx0cGFyZW50OiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHR2YXIgcGFyZW50ID0gZWxlbS5wYXJlbnROb2RlO1xuXHRcdHJldHVybiBwYXJlbnQgJiYgcGFyZW50Lm5vZGVUeXBlICE9PSAxMSA/IHBhcmVudCA6IG51bGw7XG5cdH0sXG5cdHBhcmVudHM6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdHJldHVybiBkaXIoIGVsZW0sIFwicGFyZW50Tm9kZVwiICk7XG5cdH0sXG5cdHBhcmVudHNVbnRpbDogZnVuY3Rpb24oIGVsZW0sIF9pLCB1bnRpbCApIHtcblx0XHRyZXR1cm4gZGlyKCBlbGVtLCBcInBhcmVudE5vZGVcIiwgdW50aWwgKTtcblx0fSxcblx0bmV4dDogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0cmV0dXJuIHNpYmxpbmcoIGVsZW0sIFwibmV4dFNpYmxpbmdcIiApO1xuXHR9LFxuXHRwcmV2OiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRyZXR1cm4gc2libGluZyggZWxlbSwgXCJwcmV2aW91c1NpYmxpbmdcIiApO1xuXHR9LFxuXHRuZXh0QWxsOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRyZXR1cm4gZGlyKCBlbGVtLCBcIm5leHRTaWJsaW5nXCIgKTtcblx0fSxcblx0cHJldkFsbDogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0cmV0dXJuIGRpciggZWxlbSwgXCJwcmV2aW91c1NpYmxpbmdcIiApO1xuXHR9LFxuXHRuZXh0VW50aWw6IGZ1bmN0aW9uKCBlbGVtLCBfaSwgdW50aWwgKSB7XG5cdFx0cmV0dXJuIGRpciggZWxlbSwgXCJuZXh0U2libGluZ1wiLCB1bnRpbCApO1xuXHR9LFxuXHRwcmV2VW50aWw6IGZ1bmN0aW9uKCBlbGVtLCBfaSwgdW50aWwgKSB7XG5cdFx0cmV0dXJuIGRpciggZWxlbSwgXCJwcmV2aW91c1NpYmxpbmdcIiwgdW50aWwgKTtcblx0fSxcblx0c2libGluZ3M6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdHJldHVybiBzaWJsaW5ncyggKCBlbGVtLnBhcmVudE5vZGUgfHwge30gKS5maXJzdENoaWxkLCBlbGVtICk7XG5cdH0sXG5cdGNoaWxkcmVuOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRyZXR1cm4gc2libGluZ3MoIGVsZW0uZmlyc3RDaGlsZCApO1xuXHR9LFxuXHRjb250ZW50czogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0aWYgKCBlbGVtLmNvbnRlbnREb2N1bWVudCAhPSBudWxsICYmXG5cblx0XHRcdC8vIFN1cHBvcnQ6IElFIDExK1xuXHRcdFx0Ly8gPG9iamVjdD4gZWxlbWVudHMgd2l0aCBubyBgZGF0YWAgYXR0cmlidXRlIGhhcyBhbiBvYmplY3Rcblx0XHRcdC8vIGBjb250ZW50RG9jdW1lbnRgIHdpdGggYSBgbnVsbGAgcHJvdG90eXBlLlxuXHRcdFx0Z2V0UHJvdG8oIGVsZW0uY29udGVudERvY3VtZW50ICkgKSB7XG5cblx0XHRcdHJldHVybiBlbGVtLmNvbnRlbnREb2N1bWVudDtcblx0XHR9XG5cblx0XHQvLyBTdXBwb3J0OiBJRSA5IC0gMTEgb25seSwgaU9TIDcgb25seSwgQW5kcm9pZCBCcm93c2VyIDw9NC4zIG9ubHlcblx0XHQvLyBUcmVhdCB0aGUgdGVtcGxhdGUgZWxlbWVudCBhcyBhIHJlZ3VsYXIgb25lIGluIGJyb3dzZXJzIHRoYXRcblx0XHQvLyBkb24ndCBzdXBwb3J0IGl0LlxuXHRcdGlmICggbm9kZU5hbWUoIGVsZW0sIFwidGVtcGxhdGVcIiApICkge1xuXHRcdFx0ZWxlbSA9IGVsZW0uY29udGVudCB8fCBlbGVtO1xuXHRcdH1cblxuXHRcdHJldHVybiBqUXVlcnkubWVyZ2UoIFtdLCBlbGVtLmNoaWxkTm9kZXMgKTtcblx0fVxufSwgZnVuY3Rpb24oIG5hbWUsIGZuICkge1xuXHRqUXVlcnkuZm5bIG5hbWUgXSA9IGZ1bmN0aW9uKCB1bnRpbCwgc2VsZWN0b3IgKSB7XG5cdFx0dmFyIG1hdGNoZWQgPSBqUXVlcnkubWFwKCB0aGlzLCBmbiwgdW50aWwgKTtcblxuXHRcdGlmICggbmFtZS5zbGljZSggLTUgKSAhPT0gXCJVbnRpbFwiICkge1xuXHRcdFx0c2VsZWN0b3IgPSB1bnRpbDtcblx0XHR9XG5cblx0XHRpZiAoIHNlbGVjdG9yICYmIHR5cGVvZiBzZWxlY3RvciA9PT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdG1hdGNoZWQgPSBqUXVlcnkuZmlsdGVyKCBzZWxlY3RvciwgbWF0Y2hlZCApO1xuXHRcdH1cblxuXHRcdGlmICggdGhpcy5sZW5ndGggPiAxICkge1xuXG5cdFx0XHQvLyBSZW1vdmUgZHVwbGljYXRlc1xuXHRcdFx0aWYgKCAhZ3VhcmFudGVlZFVuaXF1ZVsgbmFtZSBdICkge1xuXHRcdFx0XHRqUXVlcnkudW5pcXVlU29ydCggbWF0Y2hlZCApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBSZXZlcnNlIG9yZGVyIGZvciBwYXJlbnRzKiBhbmQgcHJldi1kZXJpdmF0aXZlc1xuXHRcdFx0aWYgKCBycGFyZW50c3ByZXYudGVzdCggbmFtZSApICkge1xuXHRcdFx0XHRtYXRjaGVkLnJldmVyc2UoKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcy5wdXNoU3RhY2soIG1hdGNoZWQgKTtcblx0fTtcbn0gKTtcbnZhciBybm90aHRtbHdoaXRlID0gKCAvW15cXHgyMFxcdFxcclxcblxcZl0rL2cgKTtcblxuXG5cbi8vIENvbnZlcnQgU3RyaW5nLWZvcm1hdHRlZCBvcHRpb25zIGludG8gT2JqZWN0LWZvcm1hdHRlZCBvbmVzXG5mdW5jdGlvbiBjcmVhdGVPcHRpb25zKCBvcHRpb25zICkge1xuXHR2YXIgb2JqZWN0ID0ge307XG5cdGpRdWVyeS5lYWNoKCBvcHRpb25zLm1hdGNoKCBybm90aHRtbHdoaXRlICkgfHwgW10sIGZ1bmN0aW9uKCBfLCBmbGFnICkge1xuXHRcdG9iamVjdFsgZmxhZyBdID0gdHJ1ZTtcblx0fSApO1xuXHRyZXR1cm4gb2JqZWN0O1xufVxuXG4vKlxuICogQ3JlYXRlIGEgY2FsbGJhY2sgbGlzdCB1c2luZyB0aGUgZm9sbG93aW5nIHBhcmFtZXRlcnM6XG4gKlxuICpcdG9wdGlvbnM6IGFuIG9wdGlvbmFsIGxpc3Qgb2Ygc3BhY2Utc2VwYXJhdGVkIG9wdGlvbnMgdGhhdCB3aWxsIGNoYW5nZSBob3dcbiAqXHRcdFx0dGhlIGNhbGxiYWNrIGxpc3QgYmVoYXZlcyBvciBhIG1vcmUgdHJhZGl0aW9uYWwgb3B0aW9uIG9iamVjdFxuICpcbiAqIEJ5IGRlZmF1bHQgYSBjYWxsYmFjayBsaXN0IHdpbGwgYWN0IGxpa2UgYW4gZXZlbnQgY2FsbGJhY2sgbGlzdCBhbmQgY2FuIGJlXG4gKiBcImZpcmVkXCIgbXVsdGlwbGUgdGltZXMuXG4gKlxuICogUG9zc2libGUgb3B0aW9uczpcbiAqXG4gKlx0b25jZTpcdFx0XHR3aWxsIGVuc3VyZSB0aGUgY2FsbGJhY2sgbGlzdCBjYW4gb25seSBiZSBmaXJlZCBvbmNlIChsaWtlIGEgRGVmZXJyZWQpXG4gKlxuICpcdG1lbW9yeTpcdFx0XHR3aWxsIGtlZXAgdHJhY2sgb2YgcHJldmlvdXMgdmFsdWVzIGFuZCB3aWxsIGNhbGwgYW55IGNhbGxiYWNrIGFkZGVkXG4gKlx0XHRcdFx0XHRhZnRlciB0aGUgbGlzdCBoYXMgYmVlbiBmaXJlZCByaWdodCBhd2F5IHdpdGggdGhlIGxhdGVzdCBcIm1lbW9yaXplZFwiXG4gKlx0XHRcdFx0XHR2YWx1ZXMgKGxpa2UgYSBEZWZlcnJlZClcbiAqXG4gKlx0dW5pcXVlOlx0XHRcdHdpbGwgZW5zdXJlIGEgY2FsbGJhY2sgY2FuIG9ubHkgYmUgYWRkZWQgb25jZSAobm8gZHVwbGljYXRlIGluIHRoZSBsaXN0KVxuICpcbiAqXHRzdG9wT25GYWxzZTpcdGludGVycnVwdCBjYWxsaW5ncyB3aGVuIGEgY2FsbGJhY2sgcmV0dXJucyBmYWxzZVxuICpcbiAqL1xualF1ZXJ5LkNhbGxiYWNrcyA9IGZ1bmN0aW9uKCBvcHRpb25zICkge1xuXG5cdC8vIENvbnZlcnQgb3B0aW9ucyBmcm9tIFN0cmluZy1mb3JtYXR0ZWQgdG8gT2JqZWN0LWZvcm1hdHRlZCBpZiBuZWVkZWRcblx0Ly8gKHdlIGNoZWNrIGluIGNhY2hlIGZpcnN0KVxuXHRvcHRpb25zID0gdHlwZW9mIG9wdGlvbnMgPT09IFwic3RyaW5nXCIgP1xuXHRcdGNyZWF0ZU9wdGlvbnMoIG9wdGlvbnMgKSA6XG5cdFx0alF1ZXJ5LmV4dGVuZCgge30sIG9wdGlvbnMgKTtcblxuXHR2YXIgLy8gRmxhZyB0byBrbm93IGlmIGxpc3QgaXMgY3VycmVudGx5IGZpcmluZ1xuXHRcdGZpcmluZyxcblxuXHRcdC8vIExhc3QgZmlyZSB2YWx1ZSBmb3Igbm9uLWZvcmdldHRhYmxlIGxpc3RzXG5cdFx0bWVtb3J5LFxuXG5cdFx0Ly8gRmxhZyB0byBrbm93IGlmIGxpc3Qgd2FzIGFscmVhZHkgZmlyZWRcblx0XHRmaXJlZCxcblxuXHRcdC8vIEZsYWcgdG8gcHJldmVudCBmaXJpbmdcblx0XHRsb2NrZWQsXG5cblx0XHQvLyBBY3R1YWwgY2FsbGJhY2sgbGlzdFxuXHRcdGxpc3QgPSBbXSxcblxuXHRcdC8vIFF1ZXVlIG9mIGV4ZWN1dGlvbiBkYXRhIGZvciByZXBlYXRhYmxlIGxpc3RzXG5cdFx0cXVldWUgPSBbXSxcblxuXHRcdC8vIEluZGV4IG9mIGN1cnJlbnRseSBmaXJpbmcgY2FsbGJhY2sgKG1vZGlmaWVkIGJ5IGFkZC9yZW1vdmUgYXMgbmVlZGVkKVxuXHRcdGZpcmluZ0luZGV4ID0gLTEsXG5cblx0XHQvLyBGaXJlIGNhbGxiYWNrc1xuXHRcdGZpcmUgPSBmdW5jdGlvbigpIHtcblxuXHRcdFx0Ly8gRW5mb3JjZSBzaW5nbGUtZmlyaW5nXG5cdFx0XHRsb2NrZWQgPSBsb2NrZWQgfHwgb3B0aW9ucy5vbmNlO1xuXG5cdFx0XHQvLyBFeGVjdXRlIGNhbGxiYWNrcyBmb3IgYWxsIHBlbmRpbmcgZXhlY3V0aW9ucyxcblx0XHRcdC8vIHJlc3BlY3RpbmcgZmlyaW5nSW5kZXggb3ZlcnJpZGVzIGFuZCBydW50aW1lIGNoYW5nZXNcblx0XHRcdGZpcmVkID0gZmlyaW5nID0gdHJ1ZTtcblx0XHRcdGZvciAoIDsgcXVldWUubGVuZ3RoOyBmaXJpbmdJbmRleCA9IC0xICkge1xuXHRcdFx0XHRtZW1vcnkgPSBxdWV1ZS5zaGlmdCgpO1xuXHRcdFx0XHR3aGlsZSAoICsrZmlyaW5nSW5kZXggPCBsaXN0Lmxlbmd0aCApIHtcblxuXHRcdFx0XHRcdC8vIFJ1biBjYWxsYmFjayBhbmQgY2hlY2sgZm9yIGVhcmx5IHRlcm1pbmF0aW9uXG5cdFx0XHRcdFx0aWYgKCBsaXN0WyBmaXJpbmdJbmRleCBdLmFwcGx5KCBtZW1vcnlbIDAgXSwgbWVtb3J5WyAxIF0gKSA9PT0gZmFsc2UgJiZcblx0XHRcdFx0XHRcdG9wdGlvbnMuc3RvcE9uRmFsc2UgKSB7XG5cblx0XHRcdFx0XHRcdC8vIEp1bXAgdG8gZW5kIGFuZCBmb3JnZXQgdGhlIGRhdGEgc28gLmFkZCBkb2Vzbid0IHJlLWZpcmVcblx0XHRcdFx0XHRcdGZpcmluZ0luZGV4ID0gbGlzdC5sZW5ndGg7XG5cdFx0XHRcdFx0XHRtZW1vcnkgPSBmYWxzZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Ly8gRm9yZ2V0IHRoZSBkYXRhIGlmIHdlJ3JlIGRvbmUgd2l0aCBpdFxuXHRcdFx0aWYgKCAhb3B0aW9ucy5tZW1vcnkgKSB7XG5cdFx0XHRcdG1lbW9yeSA9IGZhbHNlO1xuXHRcdFx0fVxuXG5cdFx0XHRmaXJpbmcgPSBmYWxzZTtcblxuXHRcdFx0Ly8gQ2xlYW4gdXAgaWYgd2UncmUgZG9uZSBmaXJpbmcgZm9yIGdvb2Rcblx0XHRcdGlmICggbG9ja2VkICkge1xuXG5cdFx0XHRcdC8vIEtlZXAgYW4gZW1wdHkgbGlzdCBpZiB3ZSBoYXZlIGRhdGEgZm9yIGZ1dHVyZSBhZGQgY2FsbHNcblx0XHRcdFx0aWYgKCBtZW1vcnkgKSB7XG5cdFx0XHRcdFx0bGlzdCA9IFtdO1xuXG5cdFx0XHRcdC8vIE90aGVyd2lzZSwgdGhpcyBvYmplY3QgaXMgc3BlbnRcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRsaXN0ID0gXCJcIjtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0sXG5cblx0XHQvLyBBY3R1YWwgQ2FsbGJhY2tzIG9iamVjdFxuXHRcdHNlbGYgPSB7XG5cblx0XHRcdC8vIEFkZCBhIGNhbGxiYWNrIG9yIGEgY29sbGVjdGlvbiBvZiBjYWxsYmFja3MgdG8gdGhlIGxpc3Rcblx0XHRcdGFkZDogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGlmICggbGlzdCApIHtcblxuXHRcdFx0XHRcdC8vIElmIHdlIGhhdmUgbWVtb3J5IGZyb20gYSBwYXN0IHJ1biwgd2Ugc2hvdWxkIGZpcmUgYWZ0ZXIgYWRkaW5nXG5cdFx0XHRcdFx0aWYgKCBtZW1vcnkgJiYgIWZpcmluZyApIHtcblx0XHRcdFx0XHRcdGZpcmluZ0luZGV4ID0gbGlzdC5sZW5ndGggLSAxO1xuXHRcdFx0XHRcdFx0cXVldWUucHVzaCggbWVtb3J5ICk7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0KCBmdW5jdGlvbiBhZGQoIGFyZ3MgKSB7XG5cdFx0XHRcdFx0XHRqUXVlcnkuZWFjaCggYXJncywgZnVuY3Rpb24oIF8sIGFyZyApIHtcblx0XHRcdFx0XHRcdFx0aWYgKCBpc0Z1bmN0aW9uKCBhcmcgKSApIHtcblx0XHRcdFx0XHRcdFx0XHRpZiAoICFvcHRpb25zLnVuaXF1ZSB8fCAhc2VsZi5oYXMoIGFyZyApICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0bGlzdC5wdXNoKCBhcmcgKTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH0gZWxzZSBpZiAoIGFyZyAmJiBhcmcubGVuZ3RoICYmIHRvVHlwZSggYXJnICkgIT09IFwic3RyaW5nXCIgKSB7XG5cblx0XHRcdFx0XHRcdFx0XHQvLyBJbnNwZWN0IHJlY3Vyc2l2ZWx5XG5cdFx0XHRcdFx0XHRcdFx0YWRkKCBhcmcgKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fSApO1xuXHRcdFx0XHRcdH0gKSggYXJndW1lbnRzICk7XG5cblx0XHRcdFx0XHRpZiAoIG1lbW9yeSAmJiAhZmlyaW5nICkge1xuXHRcdFx0XHRcdFx0ZmlyZSgpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdH0sXG5cblx0XHRcdC8vIFJlbW92ZSBhIGNhbGxiYWNrIGZyb20gdGhlIGxpc3Rcblx0XHRcdHJlbW92ZTogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGpRdWVyeS5lYWNoKCBhcmd1bWVudHMsIGZ1bmN0aW9uKCBfLCBhcmcgKSB7XG5cdFx0XHRcdFx0dmFyIGluZGV4O1xuXHRcdFx0XHRcdHdoaWxlICggKCBpbmRleCA9IGpRdWVyeS5pbkFycmF5KCBhcmcsIGxpc3QsIGluZGV4ICkgKSA+IC0xICkge1xuXHRcdFx0XHRcdFx0bGlzdC5zcGxpY2UoIGluZGV4LCAxICk7XG5cblx0XHRcdFx0XHRcdC8vIEhhbmRsZSBmaXJpbmcgaW5kZXhlc1xuXHRcdFx0XHRcdFx0aWYgKCBpbmRleCA8PSBmaXJpbmdJbmRleCApIHtcblx0XHRcdFx0XHRcdFx0ZmlyaW5nSW5kZXgtLTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0gKTtcblx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHR9LFxuXG5cdFx0XHQvLyBDaGVjayBpZiBhIGdpdmVuIGNhbGxiYWNrIGlzIGluIHRoZSBsaXN0LlxuXHRcdFx0Ly8gSWYgbm8gYXJndW1lbnQgaXMgZ2l2ZW4sIHJldHVybiB3aGV0aGVyIG9yIG5vdCBsaXN0IGhhcyBjYWxsYmFja3MgYXR0YWNoZWQuXG5cdFx0XHRoYXM6IGZ1bmN0aW9uKCBmbiApIHtcblx0XHRcdFx0cmV0dXJuIGZuID9cblx0XHRcdFx0XHRqUXVlcnkuaW5BcnJheSggZm4sIGxpc3QgKSA+IC0xIDpcblx0XHRcdFx0XHRsaXN0Lmxlbmd0aCA+IDA7XG5cdFx0XHR9LFxuXG5cdFx0XHQvLyBSZW1vdmUgYWxsIGNhbGxiYWNrcyBmcm9tIHRoZSBsaXN0XG5cdFx0XHRlbXB0eTogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGlmICggbGlzdCApIHtcblx0XHRcdFx0XHRsaXN0ID0gW107XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHR9LFxuXG5cdFx0XHQvLyBEaXNhYmxlIC5maXJlIGFuZCAuYWRkXG5cdFx0XHQvLyBBYm9ydCBhbnkgY3VycmVudC9wZW5kaW5nIGV4ZWN1dGlvbnNcblx0XHRcdC8vIENsZWFyIGFsbCBjYWxsYmFja3MgYW5kIHZhbHVlc1xuXHRcdFx0ZGlzYWJsZTogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGxvY2tlZCA9IHF1ZXVlID0gW107XG5cdFx0XHRcdGxpc3QgPSBtZW1vcnkgPSBcIlwiO1xuXHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdH0sXG5cdFx0XHRkaXNhYmxlZDogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHJldHVybiAhbGlzdDtcblx0XHRcdH0sXG5cblx0XHRcdC8vIERpc2FibGUgLmZpcmVcblx0XHRcdC8vIEFsc28gZGlzYWJsZSAuYWRkIHVubGVzcyB3ZSBoYXZlIG1lbW9yeSAoc2luY2UgaXQgd291bGQgaGF2ZSBubyBlZmZlY3QpXG5cdFx0XHQvLyBBYm9ydCBhbnkgcGVuZGluZyBleGVjdXRpb25zXG5cdFx0XHRsb2NrOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0bG9ja2VkID0gcXVldWUgPSBbXTtcblx0XHRcdFx0aWYgKCAhbWVtb3J5ICYmICFmaXJpbmcgKSB7XG5cdFx0XHRcdFx0bGlzdCA9IG1lbW9yeSA9IFwiXCI7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHR9LFxuXHRcdFx0bG9ja2VkOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0cmV0dXJuICEhbG9ja2VkO1xuXHRcdFx0fSxcblxuXHRcdFx0Ly8gQ2FsbCBhbGwgY2FsbGJhY2tzIHdpdGggdGhlIGdpdmVuIGNvbnRleHQgYW5kIGFyZ3VtZW50c1xuXHRcdFx0ZmlyZVdpdGg6IGZ1bmN0aW9uKCBjb250ZXh0LCBhcmdzICkge1xuXHRcdFx0XHRpZiAoICFsb2NrZWQgKSB7XG5cdFx0XHRcdFx0YXJncyA9IGFyZ3MgfHwgW107XG5cdFx0XHRcdFx0YXJncyA9IFsgY29udGV4dCwgYXJncy5zbGljZSA/IGFyZ3Muc2xpY2UoKSA6IGFyZ3MgXTtcblx0XHRcdFx0XHRxdWV1ZS5wdXNoKCBhcmdzICk7XG5cdFx0XHRcdFx0aWYgKCAhZmlyaW5nICkge1xuXHRcdFx0XHRcdFx0ZmlyZSgpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdH0sXG5cblx0XHRcdC8vIENhbGwgYWxsIHRoZSBjYWxsYmFja3Mgd2l0aCB0aGUgZ2l2ZW4gYXJndW1lbnRzXG5cdFx0XHRmaXJlOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0c2VsZi5maXJlV2l0aCggdGhpcywgYXJndW1lbnRzICk7XG5cdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0fSxcblxuXHRcdFx0Ly8gVG8ga25vdyBpZiB0aGUgY2FsbGJhY2tzIGhhdmUgYWxyZWFkeSBiZWVuIGNhbGxlZCBhdCBsZWFzdCBvbmNlXG5cdFx0XHRmaXJlZDogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHJldHVybiAhIWZpcmVkO1xuXHRcdFx0fVxuXHRcdH07XG5cblx0cmV0dXJuIHNlbGY7XG59O1xuXG5cbmZ1bmN0aW9uIElkZW50aXR5KCB2ICkge1xuXHRyZXR1cm4gdjtcbn1cbmZ1bmN0aW9uIFRocm93ZXIoIGV4ICkge1xuXHR0aHJvdyBleDtcbn1cblxuZnVuY3Rpb24gYWRvcHRWYWx1ZSggdmFsdWUsIHJlc29sdmUsIHJlamVjdCwgbm9WYWx1ZSApIHtcblx0dmFyIG1ldGhvZDtcblxuXHR0cnkge1xuXG5cdFx0Ly8gQ2hlY2sgZm9yIHByb21pc2UgYXNwZWN0IGZpcnN0IHRvIHByaXZpbGVnZSBzeW5jaHJvbm91cyBiZWhhdmlvclxuXHRcdGlmICggdmFsdWUgJiYgaXNGdW5jdGlvbiggKCBtZXRob2QgPSB2YWx1ZS5wcm9taXNlICkgKSApIHtcblx0XHRcdG1ldGhvZC5jYWxsKCB2YWx1ZSApLmRvbmUoIHJlc29sdmUgKS5mYWlsKCByZWplY3QgKTtcblxuXHRcdC8vIE90aGVyIHRoZW5hYmxlc1xuXHRcdH0gZWxzZSBpZiAoIHZhbHVlICYmIGlzRnVuY3Rpb24oICggbWV0aG9kID0gdmFsdWUudGhlbiApICkgKSB7XG5cdFx0XHRtZXRob2QuY2FsbCggdmFsdWUsIHJlc29sdmUsIHJlamVjdCApO1xuXG5cdFx0Ly8gT3RoZXIgbm9uLXRoZW5hYmxlc1xuXHRcdH0gZWxzZSB7XG5cblx0XHRcdC8vIENvbnRyb2wgYHJlc29sdmVgIGFyZ3VtZW50cyBieSBsZXR0aW5nIEFycmF5I3NsaWNlIGNhc3QgYm9vbGVhbiBgbm9WYWx1ZWAgdG8gaW50ZWdlcjpcblx0XHRcdC8vICogZmFsc2U6IFsgdmFsdWUgXS5zbGljZSggMCApID0+IHJlc29sdmUoIHZhbHVlIClcblx0XHRcdC8vICogdHJ1ZTogWyB2YWx1ZSBdLnNsaWNlKCAxICkgPT4gcmVzb2x2ZSgpXG5cdFx0XHRyZXNvbHZlLmFwcGx5KCB1bmRlZmluZWQsIFsgdmFsdWUgXS5zbGljZSggbm9WYWx1ZSApICk7XG5cdFx0fVxuXG5cdC8vIEZvciBQcm9taXNlcy9BKywgY29udmVydCBleGNlcHRpb25zIGludG8gcmVqZWN0aW9uc1xuXHQvLyBTaW5jZSBqUXVlcnkud2hlbiBkb2Vzbid0IHVud3JhcCB0aGVuYWJsZXMsIHdlIGNhbiBza2lwIHRoZSBleHRyYSBjaGVja3MgYXBwZWFyaW5nIGluXG5cdC8vIERlZmVycmVkI3RoZW4gdG8gY29uZGl0aW9uYWxseSBzdXBwcmVzcyByZWplY3Rpb24uXG5cdH0gY2F0Y2ggKCB2YWx1ZSApIHtcblxuXHRcdC8vIFN1cHBvcnQ6IEFuZHJvaWQgNC4wIG9ubHlcblx0XHQvLyBTdHJpY3QgbW9kZSBmdW5jdGlvbnMgaW52b2tlZCB3aXRob3V0IC5jYWxsLy5hcHBseSBnZXQgZ2xvYmFsLW9iamVjdCBjb250ZXh0XG5cdFx0cmVqZWN0LmFwcGx5KCB1bmRlZmluZWQsIFsgdmFsdWUgXSApO1xuXHR9XG59XG5cbmpRdWVyeS5leHRlbmQoIHtcblxuXHREZWZlcnJlZDogZnVuY3Rpb24oIGZ1bmMgKSB7XG5cdFx0dmFyIHR1cGxlcyA9IFtcblxuXHRcdFx0XHQvLyBhY3Rpb24sIGFkZCBsaXN0ZW5lciwgY2FsbGJhY2tzLFxuXHRcdFx0XHQvLyAuLi4gLnRoZW4gaGFuZGxlcnMsIGFyZ3VtZW50IGluZGV4LCBbZmluYWwgc3RhdGVdXG5cdFx0XHRcdFsgXCJub3RpZnlcIiwgXCJwcm9ncmVzc1wiLCBqUXVlcnkuQ2FsbGJhY2tzKCBcIm1lbW9yeVwiICksXG5cdFx0XHRcdFx0alF1ZXJ5LkNhbGxiYWNrcyggXCJtZW1vcnlcIiApLCAyIF0sXG5cdFx0XHRcdFsgXCJyZXNvbHZlXCIsIFwiZG9uZVwiLCBqUXVlcnkuQ2FsbGJhY2tzKCBcIm9uY2UgbWVtb3J5XCIgKSxcblx0XHRcdFx0XHRqUXVlcnkuQ2FsbGJhY2tzKCBcIm9uY2UgbWVtb3J5XCIgKSwgMCwgXCJyZXNvbHZlZFwiIF0sXG5cdFx0XHRcdFsgXCJyZWplY3RcIiwgXCJmYWlsXCIsIGpRdWVyeS5DYWxsYmFja3MoIFwib25jZSBtZW1vcnlcIiApLFxuXHRcdFx0XHRcdGpRdWVyeS5DYWxsYmFja3MoIFwib25jZSBtZW1vcnlcIiApLCAxLCBcInJlamVjdGVkXCIgXVxuXHRcdFx0XSxcblx0XHRcdHN0YXRlID0gXCJwZW5kaW5nXCIsXG5cdFx0XHRwcm9taXNlID0ge1xuXHRcdFx0XHRzdGF0ZTogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHN0YXRlO1xuXHRcdFx0XHR9LFxuXHRcdFx0XHRhbHdheXM6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdGRlZmVycmVkLmRvbmUoIGFyZ3VtZW50cyApLmZhaWwoIGFyZ3VtZW50cyApO1xuXHRcdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0XHR9LFxuXHRcdFx0XHRcImNhdGNoXCI6IGZ1bmN0aW9uKCBmbiApIHtcblx0XHRcdFx0XHRyZXR1cm4gcHJvbWlzZS50aGVuKCBudWxsLCBmbiApO1xuXHRcdFx0XHR9LFxuXG5cdFx0XHRcdC8vIEtlZXAgcGlwZSBmb3IgYmFjay1jb21wYXRcblx0XHRcdFx0cGlwZTogZnVuY3Rpb24oIC8qIGZuRG9uZSwgZm5GYWlsLCBmblByb2dyZXNzICovICkge1xuXHRcdFx0XHRcdHZhciBmbnMgPSBhcmd1bWVudHM7XG5cblx0XHRcdFx0XHRyZXR1cm4galF1ZXJ5LkRlZmVycmVkKCBmdW5jdGlvbiggbmV3RGVmZXIgKSB7XG5cdFx0XHRcdFx0XHRqUXVlcnkuZWFjaCggdHVwbGVzLCBmdW5jdGlvbiggX2ksIHR1cGxlICkge1xuXG5cdFx0XHRcdFx0XHRcdC8vIE1hcCB0dXBsZXMgKHByb2dyZXNzLCBkb25lLCBmYWlsKSB0byBhcmd1bWVudHMgKGRvbmUsIGZhaWwsIHByb2dyZXNzKVxuXHRcdFx0XHRcdFx0XHR2YXIgZm4gPSBpc0Z1bmN0aW9uKCBmbnNbIHR1cGxlWyA0IF0gXSApICYmIGZuc1sgdHVwbGVbIDQgXSBdO1xuXG5cdFx0XHRcdFx0XHRcdC8vIGRlZmVycmVkLnByb2dyZXNzKGZ1bmN0aW9uKCkgeyBiaW5kIHRvIG5ld0RlZmVyIG9yIG5ld0RlZmVyLm5vdGlmeSB9KVxuXHRcdFx0XHRcdFx0XHQvLyBkZWZlcnJlZC5kb25lKGZ1bmN0aW9uKCkgeyBiaW5kIHRvIG5ld0RlZmVyIG9yIG5ld0RlZmVyLnJlc29sdmUgfSlcblx0XHRcdFx0XHRcdFx0Ly8gZGVmZXJyZWQuZmFpbChmdW5jdGlvbigpIHsgYmluZCB0byBuZXdEZWZlciBvciBuZXdEZWZlci5yZWplY3QgfSlcblx0XHRcdFx0XHRcdFx0ZGVmZXJyZWRbIHR1cGxlWyAxIF0gXSggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0XHRcdFx0dmFyIHJldHVybmVkID0gZm4gJiYgZm4uYXBwbHkoIHRoaXMsIGFyZ3VtZW50cyApO1xuXHRcdFx0XHRcdFx0XHRcdGlmICggcmV0dXJuZWQgJiYgaXNGdW5jdGlvbiggcmV0dXJuZWQucHJvbWlzZSApICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuZWQucHJvbWlzZSgpXG5cdFx0XHRcdFx0XHRcdFx0XHRcdC5wcm9ncmVzcyggbmV3RGVmZXIubm90aWZ5IClcblx0XHRcdFx0XHRcdFx0XHRcdFx0LmRvbmUoIG5ld0RlZmVyLnJlc29sdmUgKVxuXHRcdFx0XHRcdFx0XHRcdFx0XHQuZmFpbCggbmV3RGVmZXIucmVqZWN0ICk7XG5cdFx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHRcdG5ld0RlZmVyWyB0dXBsZVsgMCBdICsgXCJXaXRoXCIgXShcblx0XHRcdFx0XHRcdFx0XHRcdFx0dGhpcyxcblx0XHRcdFx0XHRcdFx0XHRcdFx0Zm4gPyBbIHJldHVybmVkIF0gOiBhcmd1bWVudHNcblx0XHRcdFx0XHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9ICk7XG5cdFx0XHRcdFx0XHR9ICk7XG5cdFx0XHRcdFx0XHRmbnMgPSBudWxsO1xuXHRcdFx0XHRcdH0gKS5wcm9taXNlKCk7XG5cdFx0XHRcdH0sXG5cdFx0XHRcdHRoZW46IGZ1bmN0aW9uKCBvbkZ1bGZpbGxlZCwgb25SZWplY3RlZCwgb25Qcm9ncmVzcyApIHtcblx0XHRcdFx0XHR2YXIgbWF4RGVwdGggPSAwO1xuXHRcdFx0XHRcdGZ1bmN0aW9uIHJlc29sdmUoIGRlcHRoLCBkZWZlcnJlZCwgaGFuZGxlciwgc3BlY2lhbCApIHtcblx0XHRcdFx0XHRcdHJldHVybiBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdFx0dmFyIHRoYXQgPSB0aGlzLFxuXHRcdFx0XHRcdFx0XHRcdGFyZ3MgPSBhcmd1bWVudHMsXG5cdFx0XHRcdFx0XHRcdFx0bWlnaHRUaHJvdyA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdFx0XHRcdFx0dmFyIHJldHVybmVkLCB0aGVuO1xuXG5cdFx0XHRcdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBQcm9taXNlcy9BKyBzZWN0aW9uIDIuMy4zLjMuM1xuXHRcdFx0XHRcdFx0XHRcdFx0Ly8gaHR0cHM6Ly9wcm9taXNlc2FwbHVzLmNvbS8jcG9pbnQtNTlcblx0XHRcdFx0XHRcdFx0XHRcdC8vIElnbm9yZSBkb3VibGUtcmVzb2x1dGlvbiBhdHRlbXB0c1xuXHRcdFx0XHRcdFx0XHRcdFx0aWYgKCBkZXB0aCA8IG1heERlcHRoICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdFx0XHRcdHJldHVybmVkID0gaGFuZGxlci5hcHBseSggdGhhdCwgYXJncyApO1xuXG5cdFx0XHRcdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBQcm9taXNlcy9BKyBzZWN0aW9uIDIuMy4xXG5cdFx0XHRcdFx0XHRcdFx0XHQvLyBodHRwczovL3Byb21pc2VzYXBsdXMuY29tLyNwb2ludC00OFxuXHRcdFx0XHRcdFx0XHRcdFx0aWYgKCByZXR1cm5lZCA9PT0gZGVmZXJyZWQucHJvbWlzZSgpICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCBcIlRoZW5hYmxlIHNlbGYtcmVzb2x1dGlvblwiICk7XG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdFx0XHRcdC8vIFN1cHBvcnQ6IFByb21pc2VzL0ErIHNlY3Rpb25zIDIuMy4zLjEsIDMuNVxuXHRcdFx0XHRcdFx0XHRcdFx0Ly8gaHR0cHM6Ly9wcm9taXNlc2FwbHVzLmNvbS8jcG9pbnQtNTRcblx0XHRcdFx0XHRcdFx0XHRcdC8vIGh0dHBzOi8vcHJvbWlzZXNhcGx1cy5jb20vI3BvaW50LTc1XG5cdFx0XHRcdFx0XHRcdFx0XHQvLyBSZXRyaWV2ZSBgdGhlbmAgb25seSBvbmNlXG5cdFx0XHRcdFx0XHRcdFx0XHR0aGVuID0gcmV0dXJuZWQgJiZcblxuXHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBQcm9taXNlcy9BKyBzZWN0aW9uIDIuMy40XG5cdFx0XHRcdFx0XHRcdFx0XHRcdC8vIGh0dHBzOi8vcHJvbWlzZXNhcGx1cy5jb20vI3BvaW50LTY0XG5cdFx0XHRcdFx0XHRcdFx0XHRcdC8vIE9ubHkgY2hlY2sgb2JqZWN0cyBhbmQgZnVuY3Rpb25zIGZvciB0aGVuYWJpbGl0eVxuXHRcdFx0XHRcdFx0XHRcdFx0XHQoIHR5cGVvZiByZXR1cm5lZCA9PT0gXCJvYmplY3RcIiB8fFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdHR5cGVvZiByZXR1cm5lZCA9PT0gXCJmdW5jdGlvblwiICkgJiZcblx0XHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuZWQudGhlbjtcblxuXHRcdFx0XHRcdFx0XHRcdFx0Ly8gSGFuZGxlIGEgcmV0dXJuZWQgdGhlbmFibGVcblx0XHRcdFx0XHRcdFx0XHRcdGlmICggaXNGdW5jdGlvbiggdGhlbiApICkge1xuXG5cdFx0XHRcdFx0XHRcdFx0XHRcdC8vIFNwZWNpYWwgcHJvY2Vzc29ycyAobm90aWZ5KSBqdXN0IHdhaXQgZm9yIHJlc29sdXRpb25cblx0XHRcdFx0XHRcdFx0XHRcdFx0aWYgKCBzcGVjaWFsICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdHRoZW4uY2FsbChcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdHJldHVybmVkLFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0cmVzb2x2ZSggbWF4RGVwdGgsIGRlZmVycmVkLCBJZGVudGl0eSwgc3BlY2lhbCApLFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0cmVzb2x2ZSggbWF4RGVwdGgsIGRlZmVycmVkLCBUaHJvd2VyLCBzcGVjaWFsIClcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHQpO1xuXG5cdFx0XHRcdFx0XHRcdFx0XHRcdC8vIE5vcm1hbCBwcm9jZXNzb3JzIChyZXNvbHZlKSBhbHNvIGhvb2sgaW50byBwcm9ncmVzc1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gLi4uYW5kIGRpc3JlZ2FyZCBvbGRlciByZXNvbHV0aW9uIHZhbHVlc1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdG1heERlcHRoKys7XG5cblx0XHRcdFx0XHRcdFx0XHRcdFx0XHR0aGVuLmNhbGwoXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRyZXR1cm5lZCxcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdHJlc29sdmUoIG1heERlcHRoLCBkZWZlcnJlZCwgSWRlbnRpdHksIHNwZWNpYWwgKSxcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdHJlc29sdmUoIG1heERlcHRoLCBkZWZlcnJlZCwgVGhyb3dlciwgc3BlY2lhbCApLFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0cmVzb2x2ZSggbWF4RGVwdGgsIGRlZmVycmVkLCBJZGVudGl0eSxcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0ZGVmZXJyZWQubm90aWZ5V2l0aCApXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0KTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdFx0XHQvLyBIYW5kbGUgYWxsIG90aGVyIHJldHVybmVkIHZhbHVlc1xuXHRcdFx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBPbmx5IHN1YnN0aXR1dGUgaGFuZGxlcnMgcGFzcyBvbiBjb250ZXh0XG5cdFx0XHRcdFx0XHRcdFx0XHRcdC8vIGFuZCBtdWx0aXBsZSB2YWx1ZXMgKG5vbi1zcGVjIGJlaGF2aW9yKVxuXHRcdFx0XHRcdFx0XHRcdFx0XHRpZiAoIGhhbmRsZXIgIT09IElkZW50aXR5ICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdHRoYXQgPSB1bmRlZmluZWQ7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0YXJncyA9IFsgcmV0dXJuZWQgXTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdFx0XHRcdC8vIFByb2Nlc3MgdGhlIHZhbHVlKHMpXG5cdFx0XHRcdFx0XHRcdFx0XHRcdC8vIERlZmF1bHQgcHJvY2VzcyBpcyByZXNvbHZlXG5cdFx0XHRcdFx0XHRcdFx0XHRcdCggc3BlY2lhbCB8fCBkZWZlcnJlZC5yZXNvbHZlV2l0aCApKCB0aGF0LCBhcmdzICk7XG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0fSxcblxuXHRcdFx0XHRcdFx0XHRcdC8vIE9ubHkgbm9ybWFsIHByb2Nlc3NvcnMgKHJlc29sdmUpIGNhdGNoIGFuZCByZWplY3QgZXhjZXB0aW9uc1xuXHRcdFx0XHRcdFx0XHRcdHByb2Nlc3MgPSBzcGVjaWFsID9cblx0XHRcdFx0XHRcdFx0XHRcdG1pZ2h0VGhyb3cgOlxuXHRcdFx0XHRcdFx0XHRcdFx0ZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdHRyeSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0bWlnaHRUaHJvdygpO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR9IGNhdGNoICggZSApIHtcblxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdGlmICggalF1ZXJ5LkRlZmVycmVkLmV4Y2VwdGlvbkhvb2sgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRqUXVlcnkuRGVmZXJyZWQuZXhjZXB0aW9uSG9vayggZSxcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0cHJvY2Vzcy5zdGFja1RyYWNlICk7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gU3VwcG9ydDogUHJvbWlzZXMvQSsgc2VjdGlvbiAyLjMuMy4zLjQuMVxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8vIGh0dHBzOi8vcHJvbWlzZXNhcGx1cy5jb20vI3BvaW50LTYxXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gSWdub3JlIHBvc3QtcmVzb2x1dGlvbiBleGNlcHRpb25zXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0aWYgKCBkZXB0aCArIDEgPj0gbWF4RGVwdGggKSB7XG5cblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8vIE9ubHkgc3Vic3RpdHV0ZSBoYW5kbGVycyBwYXNzIG9uIGNvbnRleHRcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8vIGFuZCBtdWx0aXBsZSB2YWx1ZXMgKG5vbi1zcGVjIGJlaGF2aW9yKVxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0aWYgKCBoYW5kbGVyICE9PSBUaHJvd2VyICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHR0aGF0ID0gdW5kZWZpbmVkO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRhcmdzID0gWyBlIF07XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdGRlZmVycmVkLnJlamVjdFdpdGgoIHRoYXQsIGFyZ3MgKTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRcdH07XG5cblx0XHRcdFx0XHRcdFx0Ly8gU3VwcG9ydDogUHJvbWlzZXMvQSsgc2VjdGlvbiAyLjMuMy4zLjFcblx0XHRcdFx0XHRcdFx0Ly8gaHR0cHM6Ly9wcm9taXNlc2FwbHVzLmNvbS8jcG9pbnQtNTdcblx0XHRcdFx0XHRcdFx0Ly8gUmUtcmVzb2x2ZSBwcm9taXNlcyBpbW1lZGlhdGVseSB0byBkb2RnZSBmYWxzZSByZWplY3Rpb24gZnJvbVxuXHRcdFx0XHRcdFx0XHQvLyBzdWJzZXF1ZW50IGVycm9yc1xuXHRcdFx0XHRcdFx0XHRpZiAoIGRlcHRoICkge1xuXHRcdFx0XHRcdFx0XHRcdHByb2Nlc3MoKTtcblx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdFx0XHRcdC8vIENhbGwgYW4gb3B0aW9uYWwgaG9vayB0byByZWNvcmQgdGhlIHN0YWNrLCBpbiBjYXNlIG9mIGV4Y2VwdGlvblxuXHRcdFx0XHRcdFx0XHRcdC8vIHNpbmNlIGl0J3Mgb3RoZXJ3aXNlIGxvc3Qgd2hlbiBleGVjdXRpb24gZ29lcyBhc3luY1xuXHRcdFx0XHRcdFx0XHRcdGlmICggalF1ZXJ5LkRlZmVycmVkLmdldFN0YWNrSG9vayApIHtcblx0XHRcdFx0XHRcdFx0XHRcdHByb2Nlc3Muc3RhY2tUcmFjZSA9IGpRdWVyeS5EZWZlcnJlZC5nZXRTdGFja0hvb2soKTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0d2luZG93LnNldFRpbWVvdXQoIHByb2Nlc3MgKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRyZXR1cm4galF1ZXJ5LkRlZmVycmVkKCBmdW5jdGlvbiggbmV3RGVmZXIgKSB7XG5cblx0XHRcdFx0XHRcdC8vIHByb2dyZXNzX2hhbmRsZXJzLmFkZCggLi4uIClcblx0XHRcdFx0XHRcdHR1cGxlc1sgMCBdWyAzIF0uYWRkKFxuXHRcdFx0XHRcdFx0XHRyZXNvbHZlKFxuXHRcdFx0XHRcdFx0XHRcdDAsXG5cdFx0XHRcdFx0XHRcdFx0bmV3RGVmZXIsXG5cdFx0XHRcdFx0XHRcdFx0aXNGdW5jdGlvbiggb25Qcm9ncmVzcyApID9cblx0XHRcdFx0XHRcdFx0XHRcdG9uUHJvZ3Jlc3MgOlxuXHRcdFx0XHRcdFx0XHRcdFx0SWRlbnRpdHksXG5cdFx0XHRcdFx0XHRcdFx0bmV3RGVmZXIubm90aWZ5V2l0aFxuXHRcdFx0XHRcdFx0XHQpXG5cdFx0XHRcdFx0XHQpO1xuXG5cdFx0XHRcdFx0XHQvLyBmdWxmaWxsZWRfaGFuZGxlcnMuYWRkKCAuLi4gKVxuXHRcdFx0XHRcdFx0dHVwbGVzWyAxIF1bIDMgXS5hZGQoXG5cdFx0XHRcdFx0XHRcdHJlc29sdmUoXG5cdFx0XHRcdFx0XHRcdFx0MCxcblx0XHRcdFx0XHRcdFx0XHRuZXdEZWZlcixcblx0XHRcdFx0XHRcdFx0XHRpc0Z1bmN0aW9uKCBvbkZ1bGZpbGxlZCApID9cblx0XHRcdFx0XHRcdFx0XHRcdG9uRnVsZmlsbGVkIDpcblx0XHRcdFx0XHRcdFx0XHRcdElkZW50aXR5XG5cdFx0XHRcdFx0XHRcdClcblx0XHRcdFx0XHRcdCk7XG5cblx0XHRcdFx0XHRcdC8vIHJlamVjdGVkX2hhbmRsZXJzLmFkZCggLi4uIClcblx0XHRcdFx0XHRcdHR1cGxlc1sgMiBdWyAzIF0uYWRkKFxuXHRcdFx0XHRcdFx0XHRyZXNvbHZlKFxuXHRcdFx0XHRcdFx0XHRcdDAsXG5cdFx0XHRcdFx0XHRcdFx0bmV3RGVmZXIsXG5cdFx0XHRcdFx0XHRcdFx0aXNGdW5jdGlvbiggb25SZWplY3RlZCApID9cblx0XHRcdFx0XHRcdFx0XHRcdG9uUmVqZWN0ZWQgOlxuXHRcdFx0XHRcdFx0XHRcdFx0VGhyb3dlclxuXHRcdFx0XHRcdFx0XHQpXG5cdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdH0gKS5wcm9taXNlKCk7XG5cdFx0XHRcdH0sXG5cblx0XHRcdFx0Ly8gR2V0IGEgcHJvbWlzZSBmb3IgdGhpcyBkZWZlcnJlZFxuXHRcdFx0XHQvLyBJZiBvYmogaXMgcHJvdmlkZWQsIHRoZSBwcm9taXNlIGFzcGVjdCBpcyBhZGRlZCB0byB0aGUgb2JqZWN0XG5cdFx0XHRcdHByb21pc2U6IGZ1bmN0aW9uKCBvYmogKSB7XG5cdFx0XHRcdFx0cmV0dXJuIG9iaiAhPSBudWxsID8galF1ZXJ5LmV4dGVuZCggb2JqLCBwcm9taXNlICkgOiBwcm9taXNlO1xuXHRcdFx0XHR9XG5cdFx0XHR9LFxuXHRcdFx0ZGVmZXJyZWQgPSB7fTtcblxuXHRcdC8vIEFkZCBsaXN0LXNwZWNpZmljIG1ldGhvZHNcblx0XHRqUXVlcnkuZWFjaCggdHVwbGVzLCBmdW5jdGlvbiggaSwgdHVwbGUgKSB7XG5cdFx0XHR2YXIgbGlzdCA9IHR1cGxlWyAyIF0sXG5cdFx0XHRcdHN0YXRlU3RyaW5nID0gdHVwbGVbIDUgXTtcblxuXHRcdFx0Ly8gcHJvbWlzZS5wcm9ncmVzcyA9IGxpc3QuYWRkXG5cdFx0XHQvLyBwcm9taXNlLmRvbmUgPSBsaXN0LmFkZFxuXHRcdFx0Ly8gcHJvbWlzZS5mYWlsID0gbGlzdC5hZGRcblx0XHRcdHByb21pc2VbIHR1cGxlWyAxIF0gXSA9IGxpc3QuYWRkO1xuXG5cdFx0XHQvLyBIYW5kbGUgc3RhdGVcblx0XHRcdGlmICggc3RhdGVTdHJpbmcgKSB7XG5cdFx0XHRcdGxpc3QuYWRkKFxuXHRcdFx0XHRcdGZ1bmN0aW9uKCkge1xuXG5cdFx0XHRcdFx0XHQvLyBzdGF0ZSA9IFwicmVzb2x2ZWRcIiAoaS5lLiwgZnVsZmlsbGVkKVxuXHRcdFx0XHRcdFx0Ly8gc3RhdGUgPSBcInJlamVjdGVkXCJcblx0XHRcdFx0XHRcdHN0YXRlID0gc3RhdGVTdHJpbmc7XG5cdFx0XHRcdFx0fSxcblxuXHRcdFx0XHRcdC8vIHJlamVjdGVkX2NhbGxiYWNrcy5kaXNhYmxlXG5cdFx0XHRcdFx0Ly8gZnVsZmlsbGVkX2NhbGxiYWNrcy5kaXNhYmxlXG5cdFx0XHRcdFx0dHVwbGVzWyAzIC0gaSBdWyAyIF0uZGlzYWJsZSxcblxuXHRcdFx0XHRcdC8vIHJlamVjdGVkX2hhbmRsZXJzLmRpc2FibGVcblx0XHRcdFx0XHQvLyBmdWxmaWxsZWRfaGFuZGxlcnMuZGlzYWJsZVxuXHRcdFx0XHRcdHR1cGxlc1sgMyAtIGkgXVsgMyBdLmRpc2FibGUsXG5cblx0XHRcdFx0XHQvLyBwcm9ncmVzc19jYWxsYmFja3MubG9ja1xuXHRcdFx0XHRcdHR1cGxlc1sgMCBdWyAyIF0ubG9jayxcblxuXHRcdFx0XHRcdC8vIHByb2dyZXNzX2hhbmRsZXJzLmxvY2tcblx0XHRcdFx0XHR0dXBsZXNbIDAgXVsgMyBdLmxvY2tcblx0XHRcdFx0KTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gcHJvZ3Jlc3NfaGFuZGxlcnMuZmlyZVxuXHRcdFx0Ly8gZnVsZmlsbGVkX2hhbmRsZXJzLmZpcmVcblx0XHRcdC8vIHJlamVjdGVkX2hhbmRsZXJzLmZpcmVcblx0XHRcdGxpc3QuYWRkKCB0dXBsZVsgMyBdLmZpcmUgKTtcblxuXHRcdFx0Ly8gZGVmZXJyZWQubm90aWZ5ID0gZnVuY3Rpb24oKSB7IGRlZmVycmVkLm5vdGlmeVdpdGgoLi4uKSB9XG5cdFx0XHQvLyBkZWZlcnJlZC5yZXNvbHZlID0gZnVuY3Rpb24oKSB7IGRlZmVycmVkLnJlc29sdmVXaXRoKC4uLikgfVxuXHRcdFx0Ly8gZGVmZXJyZWQucmVqZWN0ID0gZnVuY3Rpb24oKSB7IGRlZmVycmVkLnJlamVjdFdpdGgoLi4uKSB9XG5cdFx0XHRkZWZlcnJlZFsgdHVwbGVbIDAgXSBdID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGRlZmVycmVkWyB0dXBsZVsgMCBdICsgXCJXaXRoXCIgXSggdGhpcyA9PT0gZGVmZXJyZWQgPyB1bmRlZmluZWQgOiB0aGlzLCBhcmd1bWVudHMgKTtcblx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHR9O1xuXG5cdFx0XHQvLyBkZWZlcnJlZC5ub3RpZnlXaXRoID0gbGlzdC5maXJlV2l0aFxuXHRcdFx0Ly8gZGVmZXJyZWQucmVzb2x2ZVdpdGggPSBsaXN0LmZpcmVXaXRoXG5cdFx0XHQvLyBkZWZlcnJlZC5yZWplY3RXaXRoID0gbGlzdC5maXJlV2l0aFxuXHRcdFx0ZGVmZXJyZWRbIHR1cGxlWyAwIF0gKyBcIldpdGhcIiBdID0gbGlzdC5maXJlV2l0aDtcblx0XHR9ICk7XG5cblx0XHQvLyBNYWtlIHRoZSBkZWZlcnJlZCBhIHByb21pc2Vcblx0XHRwcm9taXNlLnByb21pc2UoIGRlZmVycmVkICk7XG5cblx0XHQvLyBDYWxsIGdpdmVuIGZ1bmMgaWYgYW55XG5cdFx0aWYgKCBmdW5jICkge1xuXHRcdFx0ZnVuYy5jYWxsKCBkZWZlcnJlZCwgZGVmZXJyZWQgKTtcblx0XHR9XG5cblx0XHQvLyBBbGwgZG9uZSFcblx0XHRyZXR1cm4gZGVmZXJyZWQ7XG5cdH0sXG5cblx0Ly8gRGVmZXJyZWQgaGVscGVyXG5cdHdoZW46IGZ1bmN0aW9uKCBzaW5nbGVWYWx1ZSApIHtcblx0XHR2YXJcblxuXHRcdFx0Ly8gY291bnQgb2YgdW5jb21wbGV0ZWQgc3Vib3JkaW5hdGVzXG5cdFx0XHRyZW1haW5pbmcgPSBhcmd1bWVudHMubGVuZ3RoLFxuXG5cdFx0XHQvLyBjb3VudCBvZiB1bnByb2Nlc3NlZCBhcmd1bWVudHNcblx0XHRcdGkgPSByZW1haW5pbmcsXG5cblx0XHRcdC8vIHN1Ym9yZGluYXRlIGZ1bGZpbGxtZW50IGRhdGFcblx0XHRcdHJlc29sdmVDb250ZXh0cyA9IEFycmF5KCBpICksXG5cdFx0XHRyZXNvbHZlVmFsdWVzID0gc2xpY2UuY2FsbCggYXJndW1lbnRzICksXG5cblx0XHRcdC8vIHRoZSBwcmltYXJ5IERlZmVycmVkXG5cdFx0XHRwcmltYXJ5ID0galF1ZXJ5LkRlZmVycmVkKCksXG5cblx0XHRcdC8vIHN1Ym9yZGluYXRlIGNhbGxiYWNrIGZhY3Rvcnlcblx0XHRcdHVwZGF0ZUZ1bmMgPSBmdW5jdGlvbiggaSApIHtcblx0XHRcdFx0cmV0dXJuIGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHRcdFx0XHRyZXNvbHZlQ29udGV4dHNbIGkgXSA9IHRoaXM7XG5cdFx0XHRcdFx0cmVzb2x2ZVZhbHVlc1sgaSBdID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBzbGljZS5jYWxsKCBhcmd1bWVudHMgKSA6IHZhbHVlO1xuXHRcdFx0XHRcdGlmICggISggLS1yZW1haW5pbmcgKSApIHtcblx0XHRcdFx0XHRcdHByaW1hcnkucmVzb2x2ZVdpdGgoIHJlc29sdmVDb250ZXh0cywgcmVzb2x2ZVZhbHVlcyApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fTtcblx0XHRcdH07XG5cblx0XHQvLyBTaW5nbGUtIGFuZCBlbXB0eSBhcmd1bWVudHMgYXJlIGFkb3B0ZWQgbGlrZSBQcm9taXNlLnJlc29sdmVcblx0XHRpZiAoIHJlbWFpbmluZyA8PSAxICkge1xuXHRcdFx0YWRvcHRWYWx1ZSggc2luZ2xlVmFsdWUsIHByaW1hcnkuZG9uZSggdXBkYXRlRnVuYyggaSApICkucmVzb2x2ZSwgcHJpbWFyeS5yZWplY3QsXG5cdFx0XHRcdCFyZW1haW5pbmcgKTtcblxuXHRcdFx0Ly8gVXNlIC50aGVuKCkgdG8gdW53cmFwIHNlY29uZGFyeSB0aGVuYWJsZXMgKGNmLiBnaC0zMDAwKVxuXHRcdFx0aWYgKCBwcmltYXJ5LnN0YXRlKCkgPT09IFwicGVuZGluZ1wiIHx8XG5cdFx0XHRcdGlzRnVuY3Rpb24oIHJlc29sdmVWYWx1ZXNbIGkgXSAmJiByZXNvbHZlVmFsdWVzWyBpIF0udGhlbiApICkge1xuXG5cdFx0XHRcdHJldHVybiBwcmltYXJ5LnRoZW4oKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBNdWx0aXBsZSBhcmd1bWVudHMgYXJlIGFnZ3JlZ2F0ZWQgbGlrZSBQcm9taXNlLmFsbCBhcnJheSBlbGVtZW50c1xuXHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0YWRvcHRWYWx1ZSggcmVzb2x2ZVZhbHVlc1sgaSBdLCB1cGRhdGVGdW5jKCBpICksIHByaW1hcnkucmVqZWN0ICk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHByaW1hcnkucHJvbWlzZSgpO1xuXHR9XG59ICk7XG5cblxuLy8gVGhlc2UgdXN1YWxseSBpbmRpY2F0ZSBhIHByb2dyYW1tZXIgbWlzdGFrZSBkdXJpbmcgZGV2ZWxvcG1lbnQsXG4vLyB3YXJuIGFib3V0IHRoZW0gQVNBUCByYXRoZXIgdGhhbiBzd2FsbG93aW5nIHRoZW0gYnkgZGVmYXVsdC5cbnZhciByZXJyb3JOYW1lcyA9IC9eKEV2YWx8SW50ZXJuYWx8UmFuZ2V8UmVmZXJlbmNlfFN5bnRheHxUeXBlfFVSSSlFcnJvciQvO1xuXG5qUXVlcnkuRGVmZXJyZWQuZXhjZXB0aW9uSG9vayA9IGZ1bmN0aW9uKCBlcnJvciwgc3RhY2sgKSB7XG5cblx0Ly8gU3VwcG9ydDogSUUgOCAtIDkgb25seVxuXHQvLyBDb25zb2xlIGV4aXN0cyB3aGVuIGRldiB0b29scyBhcmUgb3Blbiwgd2hpY2ggY2FuIGhhcHBlbiBhdCBhbnkgdGltZVxuXHRpZiAoIHdpbmRvdy5jb25zb2xlICYmIHdpbmRvdy5jb25zb2xlLndhcm4gJiYgZXJyb3IgJiYgcmVycm9yTmFtZXMudGVzdCggZXJyb3IubmFtZSApICkge1xuXHRcdHdpbmRvdy5jb25zb2xlLndhcm4oIFwialF1ZXJ5LkRlZmVycmVkIGV4Y2VwdGlvbjogXCIgKyBlcnJvci5tZXNzYWdlLCBlcnJvci5zdGFjaywgc3RhY2sgKTtcblx0fVxufTtcblxuXG5cblxualF1ZXJ5LnJlYWR5RXhjZXB0aW9uID0gZnVuY3Rpb24oIGVycm9yICkge1xuXHR3aW5kb3cuc2V0VGltZW91dCggZnVuY3Rpb24oKSB7XG5cdFx0dGhyb3cgZXJyb3I7XG5cdH0gKTtcbn07XG5cblxuXG5cbi8vIFRoZSBkZWZlcnJlZCB1c2VkIG9uIERPTSByZWFkeVxudmFyIHJlYWR5TGlzdCA9IGpRdWVyeS5EZWZlcnJlZCgpO1xuXG5qUXVlcnkuZm4ucmVhZHkgPSBmdW5jdGlvbiggZm4gKSB7XG5cblx0cmVhZHlMaXN0XG5cdFx0LnRoZW4oIGZuIClcblxuXHRcdC8vIFdyYXAgalF1ZXJ5LnJlYWR5RXhjZXB0aW9uIGluIGEgZnVuY3Rpb24gc28gdGhhdCB0aGUgbG9va3VwXG5cdFx0Ly8gaGFwcGVucyBhdCB0aGUgdGltZSBvZiBlcnJvciBoYW5kbGluZyBpbnN0ZWFkIG9mIGNhbGxiYWNrXG5cdFx0Ly8gcmVnaXN0cmF0aW9uLlxuXHRcdC5jYXRjaCggZnVuY3Rpb24oIGVycm9yICkge1xuXHRcdFx0alF1ZXJ5LnJlYWR5RXhjZXB0aW9uKCBlcnJvciApO1xuXHRcdH0gKTtcblxuXHRyZXR1cm4gdGhpcztcbn07XG5cbmpRdWVyeS5leHRlbmQoIHtcblxuXHQvLyBJcyB0aGUgRE9NIHJlYWR5IHRvIGJlIHVzZWQ/IFNldCB0byB0cnVlIG9uY2UgaXQgb2NjdXJzLlxuXHRpc1JlYWR5OiBmYWxzZSxcblxuXHQvLyBBIGNvdW50ZXIgdG8gdHJhY2sgaG93IG1hbnkgaXRlbXMgdG8gd2FpdCBmb3IgYmVmb3JlXG5cdC8vIHRoZSByZWFkeSBldmVudCBmaXJlcy4gU2VlICM2NzgxXG5cdHJlYWR5V2FpdDogMSxcblxuXHQvLyBIYW5kbGUgd2hlbiB0aGUgRE9NIGlzIHJlYWR5XG5cdHJlYWR5OiBmdW5jdGlvbiggd2FpdCApIHtcblxuXHRcdC8vIEFib3J0IGlmIHRoZXJlIGFyZSBwZW5kaW5nIGhvbGRzIG9yIHdlJ3JlIGFscmVhZHkgcmVhZHlcblx0XHRpZiAoIHdhaXQgPT09IHRydWUgPyAtLWpRdWVyeS5yZWFkeVdhaXQgOiBqUXVlcnkuaXNSZWFkeSApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBSZW1lbWJlciB0aGF0IHRoZSBET00gaXMgcmVhZHlcblx0XHRqUXVlcnkuaXNSZWFkeSA9IHRydWU7XG5cblx0XHQvLyBJZiBhIG5vcm1hbCBET00gUmVhZHkgZXZlbnQgZmlyZWQsIGRlY3JlbWVudCwgYW5kIHdhaXQgaWYgbmVlZCBiZVxuXHRcdGlmICggd2FpdCAhPT0gdHJ1ZSAmJiAtLWpRdWVyeS5yZWFkeVdhaXQgPiAwICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIElmIHRoZXJlIGFyZSBmdW5jdGlvbnMgYm91bmQsIHRvIGV4ZWN1dGVcblx0XHRyZWFkeUxpc3QucmVzb2x2ZVdpdGgoIGRvY3VtZW50LCBbIGpRdWVyeSBdICk7XG5cdH1cbn0gKTtcblxualF1ZXJ5LnJlYWR5LnRoZW4gPSByZWFkeUxpc3QudGhlbjtcblxuLy8gVGhlIHJlYWR5IGV2ZW50IGhhbmRsZXIgYW5kIHNlbGYgY2xlYW51cCBtZXRob2RcbmZ1bmN0aW9uIGNvbXBsZXRlZCgpIHtcblx0ZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lciggXCJET01Db250ZW50TG9hZGVkXCIsIGNvbXBsZXRlZCApO1xuXHR3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lciggXCJsb2FkXCIsIGNvbXBsZXRlZCApO1xuXHRqUXVlcnkucmVhZHkoKTtcbn1cblxuLy8gQ2F0Y2ggY2FzZXMgd2hlcmUgJChkb2N1bWVudCkucmVhZHkoKSBpcyBjYWxsZWRcbi8vIGFmdGVyIHRoZSBicm93c2VyIGV2ZW50IGhhcyBhbHJlYWR5IG9jY3VycmVkLlxuLy8gU3VwcG9ydDogSUUgPD05IC0gMTAgb25seVxuLy8gT2xkZXIgSUUgc29tZXRpbWVzIHNpZ25hbHMgXCJpbnRlcmFjdGl2ZVwiIHRvbyBzb29uXG5pZiAoIGRvY3VtZW50LnJlYWR5U3RhdGUgPT09IFwiY29tcGxldGVcIiB8fFxuXHQoIGRvY3VtZW50LnJlYWR5U3RhdGUgIT09IFwibG9hZGluZ1wiICYmICFkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuZG9TY3JvbGwgKSApIHtcblxuXHQvLyBIYW5kbGUgaXQgYXN5bmNocm9ub3VzbHkgdG8gYWxsb3cgc2NyaXB0cyB0aGUgb3Bwb3J0dW5pdHkgdG8gZGVsYXkgcmVhZHlcblx0d2luZG93LnNldFRpbWVvdXQoIGpRdWVyeS5yZWFkeSApO1xuXG59IGVsc2Uge1xuXG5cdC8vIFVzZSB0aGUgaGFuZHkgZXZlbnQgY2FsbGJhY2tcblx0ZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lciggXCJET01Db250ZW50TG9hZGVkXCIsIGNvbXBsZXRlZCApO1xuXG5cdC8vIEEgZmFsbGJhY2sgdG8gd2luZG93Lm9ubG9hZCwgdGhhdCB3aWxsIGFsd2F5cyB3b3JrXG5cdHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCBcImxvYWRcIiwgY29tcGxldGVkICk7XG59XG5cblxuXG5cbi8vIE11bHRpZnVuY3Rpb25hbCBtZXRob2QgdG8gZ2V0IGFuZCBzZXQgdmFsdWVzIG9mIGEgY29sbGVjdGlvblxuLy8gVGhlIHZhbHVlL3MgY2FuIG9wdGlvbmFsbHkgYmUgZXhlY3V0ZWQgaWYgaXQncyBhIGZ1bmN0aW9uXG52YXIgYWNjZXNzID0gZnVuY3Rpb24oIGVsZW1zLCBmbiwga2V5LCB2YWx1ZSwgY2hhaW5hYmxlLCBlbXB0eUdldCwgcmF3ICkge1xuXHR2YXIgaSA9IDAsXG5cdFx0bGVuID0gZWxlbXMubGVuZ3RoLFxuXHRcdGJ1bGsgPSBrZXkgPT0gbnVsbDtcblxuXHQvLyBTZXRzIG1hbnkgdmFsdWVzXG5cdGlmICggdG9UeXBlKCBrZXkgKSA9PT0gXCJvYmplY3RcIiApIHtcblx0XHRjaGFpbmFibGUgPSB0cnVlO1xuXHRcdGZvciAoIGkgaW4ga2V5ICkge1xuXHRcdFx0YWNjZXNzKCBlbGVtcywgZm4sIGksIGtleVsgaSBdLCB0cnVlLCBlbXB0eUdldCwgcmF3ICk7XG5cdFx0fVxuXG5cdC8vIFNldHMgb25lIHZhbHVlXG5cdH0gZWxzZSBpZiAoIHZhbHVlICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0Y2hhaW5hYmxlID0gdHJ1ZTtcblxuXHRcdGlmICggIWlzRnVuY3Rpb24oIHZhbHVlICkgKSB7XG5cdFx0XHRyYXcgPSB0cnVlO1xuXHRcdH1cblxuXHRcdGlmICggYnVsayApIHtcblxuXHRcdFx0Ly8gQnVsayBvcGVyYXRpb25zIHJ1biBhZ2FpbnN0IHRoZSBlbnRpcmUgc2V0XG5cdFx0XHRpZiAoIHJhdyApIHtcblx0XHRcdFx0Zm4uY2FsbCggZWxlbXMsIHZhbHVlICk7XG5cdFx0XHRcdGZuID0gbnVsbDtcblxuXHRcdFx0Ly8gLi4uZXhjZXB0IHdoZW4gZXhlY3V0aW5nIGZ1bmN0aW9uIHZhbHVlc1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0YnVsayA9IGZuO1xuXHRcdFx0XHRmbiA9IGZ1bmN0aW9uKCBlbGVtLCBfa2V5LCB2YWx1ZSApIHtcblx0XHRcdFx0XHRyZXR1cm4gYnVsay5jYWxsKCBqUXVlcnkoIGVsZW0gKSwgdmFsdWUgKTtcblx0XHRcdFx0fTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoIGZuICkge1xuXHRcdFx0Zm9yICggOyBpIDwgbGVuOyBpKysgKSB7XG5cdFx0XHRcdGZuKFxuXHRcdFx0XHRcdGVsZW1zWyBpIF0sIGtleSwgcmF3ID9cblx0XHRcdFx0XHRcdHZhbHVlIDpcblx0XHRcdFx0XHRcdHZhbHVlLmNhbGwoIGVsZW1zWyBpIF0sIGksIGZuKCBlbGVtc1sgaSBdLCBrZXkgKSApXG5cdFx0XHRcdCk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0aWYgKCBjaGFpbmFibGUgKSB7XG5cdFx0cmV0dXJuIGVsZW1zO1xuXHR9XG5cblx0Ly8gR2V0c1xuXHRpZiAoIGJ1bGsgKSB7XG5cdFx0cmV0dXJuIGZuLmNhbGwoIGVsZW1zICk7XG5cdH1cblxuXHRyZXR1cm4gbGVuID8gZm4oIGVsZW1zWyAwIF0sIGtleSApIDogZW1wdHlHZXQ7XG59O1xuXG5cbi8vIE1hdGNoZXMgZGFzaGVkIHN0cmluZyBmb3IgY2FtZWxpemluZ1xudmFyIHJtc1ByZWZpeCA9IC9eLW1zLS8sXG5cdHJkYXNoQWxwaGEgPSAvLShbYS16XSkvZztcblxuLy8gVXNlZCBieSBjYW1lbENhc2UgYXMgY2FsbGJhY2sgdG8gcmVwbGFjZSgpXG5mdW5jdGlvbiBmY2FtZWxDYXNlKCBfYWxsLCBsZXR0ZXIgKSB7XG5cdHJldHVybiBsZXR0ZXIudG9VcHBlckNhc2UoKTtcbn1cblxuLy8gQ29udmVydCBkYXNoZWQgdG8gY2FtZWxDYXNlOyB1c2VkIGJ5IHRoZSBjc3MgYW5kIGRhdGEgbW9kdWxlc1xuLy8gU3VwcG9ydDogSUUgPD05IC0gMTEsIEVkZ2UgMTIgLSAxNVxuLy8gTWljcm9zb2Z0IGZvcmdvdCB0byBodW1wIHRoZWlyIHZlbmRvciBwcmVmaXggKCM5NTcyKVxuZnVuY3Rpb24gY2FtZWxDYXNlKCBzdHJpbmcgKSB7XG5cdHJldHVybiBzdHJpbmcucmVwbGFjZSggcm1zUHJlZml4LCBcIm1zLVwiICkucmVwbGFjZSggcmRhc2hBbHBoYSwgZmNhbWVsQ2FzZSApO1xufVxudmFyIGFjY2VwdERhdGEgPSBmdW5jdGlvbiggb3duZXIgKSB7XG5cblx0Ly8gQWNjZXB0cyBvbmx5OlxuXHQvLyAgLSBOb2RlXG5cdC8vICAgIC0gTm9kZS5FTEVNRU5UX05PREVcblx0Ly8gICAgLSBOb2RlLkRPQ1VNRU5UX05PREVcblx0Ly8gIC0gT2JqZWN0XG5cdC8vICAgIC0gQW55XG5cdHJldHVybiBvd25lci5ub2RlVHlwZSA9PT0gMSB8fCBvd25lci5ub2RlVHlwZSA9PT0gOSB8fCAhKCArb3duZXIubm9kZVR5cGUgKTtcbn07XG5cblxuXG5cbmZ1bmN0aW9uIERhdGEoKSB7XG5cdHRoaXMuZXhwYW5kbyA9IGpRdWVyeS5leHBhbmRvICsgRGF0YS51aWQrKztcbn1cblxuRGF0YS51aWQgPSAxO1xuXG5EYXRhLnByb3RvdHlwZSA9IHtcblxuXHRjYWNoZTogZnVuY3Rpb24oIG93bmVyICkge1xuXG5cdFx0Ly8gQ2hlY2sgaWYgdGhlIG93bmVyIG9iamVjdCBhbHJlYWR5IGhhcyBhIGNhY2hlXG5cdFx0dmFyIHZhbHVlID0gb3duZXJbIHRoaXMuZXhwYW5kbyBdO1xuXG5cdFx0Ly8gSWYgbm90LCBjcmVhdGUgb25lXG5cdFx0aWYgKCAhdmFsdWUgKSB7XG5cdFx0XHR2YWx1ZSA9IHt9O1xuXG5cdFx0XHQvLyBXZSBjYW4gYWNjZXB0IGRhdGEgZm9yIG5vbi1lbGVtZW50IG5vZGVzIGluIG1vZGVybiBicm93c2Vycyxcblx0XHRcdC8vIGJ1dCB3ZSBzaG91bGQgbm90LCBzZWUgIzgzMzUuXG5cdFx0XHQvLyBBbHdheXMgcmV0dXJuIGFuIGVtcHR5IG9iamVjdC5cblx0XHRcdGlmICggYWNjZXB0RGF0YSggb3duZXIgKSApIHtcblxuXHRcdFx0XHQvLyBJZiBpdCBpcyBhIG5vZGUgdW5saWtlbHkgdG8gYmUgc3RyaW5naWZ5LWVkIG9yIGxvb3BlZCBvdmVyXG5cdFx0XHRcdC8vIHVzZSBwbGFpbiBhc3NpZ25tZW50XG5cdFx0XHRcdGlmICggb3duZXIubm9kZVR5cGUgKSB7XG5cdFx0XHRcdFx0b3duZXJbIHRoaXMuZXhwYW5kbyBdID0gdmFsdWU7XG5cblx0XHRcdFx0Ly8gT3RoZXJ3aXNlIHNlY3VyZSBpdCBpbiBhIG5vbi1lbnVtZXJhYmxlIHByb3BlcnR5XG5cdFx0XHRcdC8vIGNvbmZpZ3VyYWJsZSBtdXN0IGJlIHRydWUgdG8gYWxsb3cgdGhlIHByb3BlcnR5IHRvIGJlXG5cdFx0XHRcdC8vIGRlbGV0ZWQgd2hlbiBkYXRhIGlzIHJlbW92ZWRcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoIG93bmVyLCB0aGlzLmV4cGFuZG8sIHtcblx0XHRcdFx0XHRcdHZhbHVlOiB2YWx1ZSxcblx0XHRcdFx0XHRcdGNvbmZpZ3VyYWJsZTogdHJ1ZVxuXHRcdFx0XHRcdH0gKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiB2YWx1ZTtcblx0fSxcblx0c2V0OiBmdW5jdGlvbiggb3duZXIsIGRhdGEsIHZhbHVlICkge1xuXHRcdHZhciBwcm9wLFxuXHRcdFx0Y2FjaGUgPSB0aGlzLmNhY2hlKCBvd25lciApO1xuXG5cdFx0Ly8gSGFuZGxlOiBbIG93bmVyLCBrZXksIHZhbHVlIF0gYXJnc1xuXHRcdC8vIEFsd2F5cyB1c2UgY2FtZWxDYXNlIGtleSAoZ2gtMjI1Nylcblx0XHRpZiAoIHR5cGVvZiBkYXRhID09PSBcInN0cmluZ1wiICkge1xuXHRcdFx0Y2FjaGVbIGNhbWVsQ2FzZSggZGF0YSApIF0gPSB2YWx1ZTtcblxuXHRcdC8vIEhhbmRsZTogWyBvd25lciwgeyBwcm9wZXJ0aWVzIH0gXSBhcmdzXG5cdFx0fSBlbHNlIHtcblxuXHRcdFx0Ly8gQ29weSB0aGUgcHJvcGVydGllcyBvbmUtYnktb25lIHRvIHRoZSBjYWNoZSBvYmplY3Rcblx0XHRcdGZvciAoIHByb3AgaW4gZGF0YSApIHtcblx0XHRcdFx0Y2FjaGVbIGNhbWVsQ2FzZSggcHJvcCApIF0gPSBkYXRhWyBwcm9wIF07XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiBjYWNoZTtcblx0fSxcblx0Z2V0OiBmdW5jdGlvbiggb3duZXIsIGtleSApIHtcblx0XHRyZXR1cm4ga2V5ID09PSB1bmRlZmluZWQgP1xuXHRcdFx0dGhpcy5jYWNoZSggb3duZXIgKSA6XG5cblx0XHRcdC8vIEFsd2F5cyB1c2UgY2FtZWxDYXNlIGtleSAoZ2gtMjI1Nylcblx0XHRcdG93bmVyWyB0aGlzLmV4cGFuZG8gXSAmJiBvd25lclsgdGhpcy5leHBhbmRvIF1bIGNhbWVsQ2FzZSgga2V5ICkgXTtcblx0fSxcblx0YWNjZXNzOiBmdW5jdGlvbiggb3duZXIsIGtleSwgdmFsdWUgKSB7XG5cblx0XHQvLyBJbiBjYXNlcyB3aGVyZSBlaXRoZXI6XG5cdFx0Ly9cblx0XHQvLyAgIDEuIE5vIGtleSB3YXMgc3BlY2lmaWVkXG5cdFx0Ly8gICAyLiBBIHN0cmluZyBrZXkgd2FzIHNwZWNpZmllZCwgYnV0IG5vIHZhbHVlIHByb3ZpZGVkXG5cdFx0Ly9cblx0XHQvLyBUYWtlIHRoZSBcInJlYWRcIiBwYXRoIGFuZCBhbGxvdyB0aGUgZ2V0IG1ldGhvZCB0byBkZXRlcm1pbmVcblx0XHQvLyB3aGljaCB2YWx1ZSB0byByZXR1cm4sIHJlc3BlY3RpdmVseSBlaXRoZXI6XG5cdFx0Ly9cblx0XHQvLyAgIDEuIFRoZSBlbnRpcmUgY2FjaGUgb2JqZWN0XG5cdFx0Ly8gICAyLiBUaGUgZGF0YSBzdG9yZWQgYXQgdGhlIGtleVxuXHRcdC8vXG5cdFx0aWYgKCBrZXkgPT09IHVuZGVmaW5lZCB8fFxuXHRcdFx0XHQoICgga2V5ICYmIHR5cGVvZiBrZXkgPT09IFwic3RyaW5nXCIgKSAmJiB2YWx1ZSA9PT0gdW5kZWZpbmVkICkgKSB7XG5cblx0XHRcdHJldHVybiB0aGlzLmdldCggb3duZXIsIGtleSApO1xuXHRcdH1cblxuXHRcdC8vIFdoZW4gdGhlIGtleSBpcyBub3QgYSBzdHJpbmcsIG9yIGJvdGggYSBrZXkgYW5kIHZhbHVlXG5cdFx0Ly8gYXJlIHNwZWNpZmllZCwgc2V0IG9yIGV4dGVuZCAoZXhpc3Rpbmcgb2JqZWN0cykgd2l0aCBlaXRoZXI6XG5cdFx0Ly9cblx0XHQvLyAgIDEuIEFuIG9iamVjdCBvZiBwcm9wZXJ0aWVzXG5cdFx0Ly8gICAyLiBBIGtleSBhbmQgdmFsdWVcblx0XHQvL1xuXHRcdHRoaXMuc2V0KCBvd25lciwga2V5LCB2YWx1ZSApO1xuXG5cdFx0Ly8gU2luY2UgdGhlIFwic2V0XCIgcGF0aCBjYW4gaGF2ZSB0d28gcG9zc2libGUgZW50cnkgcG9pbnRzXG5cdFx0Ly8gcmV0dXJuIHRoZSBleHBlY3RlZCBkYXRhIGJhc2VkIG9uIHdoaWNoIHBhdGggd2FzIHRha2VuWypdXG5cdFx0cmV0dXJuIHZhbHVlICE9PSB1bmRlZmluZWQgPyB2YWx1ZSA6IGtleTtcblx0fSxcblx0cmVtb3ZlOiBmdW5jdGlvbiggb3duZXIsIGtleSApIHtcblx0XHR2YXIgaSxcblx0XHRcdGNhY2hlID0gb3duZXJbIHRoaXMuZXhwYW5kbyBdO1xuXG5cdFx0aWYgKCBjYWNoZSA9PT0gdW5kZWZpbmVkICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGlmICgga2V5ICE9PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdC8vIFN1cHBvcnQgYXJyYXkgb3Igc3BhY2Ugc2VwYXJhdGVkIHN0cmluZyBvZiBrZXlzXG5cdFx0XHRpZiAoIEFycmF5LmlzQXJyYXkoIGtleSApICkge1xuXG5cdFx0XHRcdC8vIElmIGtleSBpcyBhbiBhcnJheSBvZiBrZXlzLi4uXG5cdFx0XHRcdC8vIFdlIGFsd2F5cyBzZXQgY2FtZWxDYXNlIGtleXMsIHNvIHJlbW92ZSB0aGF0LlxuXHRcdFx0XHRrZXkgPSBrZXkubWFwKCBjYW1lbENhc2UgKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGtleSA9IGNhbWVsQ2FzZSgga2V5ICk7XG5cblx0XHRcdFx0Ly8gSWYgYSBrZXkgd2l0aCB0aGUgc3BhY2VzIGV4aXN0cywgdXNlIGl0LlxuXHRcdFx0XHQvLyBPdGhlcndpc2UsIGNyZWF0ZSBhbiBhcnJheSBieSBtYXRjaGluZyBub24td2hpdGVzcGFjZVxuXHRcdFx0XHRrZXkgPSBrZXkgaW4gY2FjaGUgP1xuXHRcdFx0XHRcdFsga2V5IF0gOlxuXHRcdFx0XHRcdCgga2V5Lm1hdGNoKCBybm90aHRtbHdoaXRlICkgfHwgW10gKTtcblx0XHRcdH1cblxuXHRcdFx0aSA9IGtleS5sZW5ndGg7XG5cblx0XHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0XHRkZWxldGUgY2FjaGVbIGtleVsgaSBdIF07XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gUmVtb3ZlIHRoZSBleHBhbmRvIGlmIHRoZXJlJ3Mgbm8gbW9yZSBkYXRhXG5cdFx0aWYgKCBrZXkgPT09IHVuZGVmaW5lZCB8fCBqUXVlcnkuaXNFbXB0eU9iamVjdCggY2FjaGUgKSApIHtcblxuXHRcdFx0Ly8gU3VwcG9ydDogQ2hyb21lIDw9MzUgLSA0NVxuXHRcdFx0Ly8gV2Via2l0ICYgQmxpbmsgcGVyZm9ybWFuY2Ugc3VmZmVycyB3aGVuIGRlbGV0aW5nIHByb3BlcnRpZXNcblx0XHRcdC8vIGZyb20gRE9NIG5vZGVzLCBzbyBzZXQgdG8gdW5kZWZpbmVkIGluc3RlYWRcblx0XHRcdC8vIGh0dHBzOi8vYnVncy5jaHJvbWl1bS5vcmcvcC9jaHJvbWl1bS9pc3N1ZXMvZGV0YWlsP2lkPTM3ODYwNyAoYnVnIHJlc3RyaWN0ZWQpXG5cdFx0XHRpZiAoIG93bmVyLm5vZGVUeXBlICkge1xuXHRcdFx0XHRvd25lclsgdGhpcy5leHBhbmRvIF0gPSB1bmRlZmluZWQ7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRkZWxldGUgb3duZXJbIHRoaXMuZXhwYW5kbyBdO1xuXHRcdFx0fVxuXHRcdH1cblx0fSxcblx0aGFzRGF0YTogZnVuY3Rpb24oIG93bmVyICkge1xuXHRcdHZhciBjYWNoZSA9IG93bmVyWyB0aGlzLmV4cGFuZG8gXTtcblx0XHRyZXR1cm4gY2FjaGUgIT09IHVuZGVmaW5lZCAmJiAhalF1ZXJ5LmlzRW1wdHlPYmplY3QoIGNhY2hlICk7XG5cdH1cbn07XG52YXIgZGF0YVByaXYgPSBuZXcgRGF0YSgpO1xuXG52YXIgZGF0YVVzZXIgPSBuZXcgRGF0YSgpO1xuXG5cblxuLy9cdEltcGxlbWVudGF0aW9uIFN1bW1hcnlcbi8vXG4vL1x0MS4gRW5mb3JjZSBBUEkgc3VyZmFjZSBhbmQgc2VtYW50aWMgY29tcGF0aWJpbGl0eSB3aXRoIDEuOS54IGJyYW5jaFxuLy9cdDIuIEltcHJvdmUgdGhlIG1vZHVsZSdzIG1haW50YWluYWJpbGl0eSBieSByZWR1Y2luZyB0aGUgc3RvcmFnZVxuLy9cdFx0cGF0aHMgdG8gYSBzaW5nbGUgbWVjaGFuaXNtLlxuLy9cdDMuIFVzZSB0aGUgc2FtZSBzaW5nbGUgbWVjaGFuaXNtIHRvIHN1cHBvcnQgXCJwcml2YXRlXCIgYW5kIFwidXNlclwiIGRhdGEuXG4vL1x0NC4gX05ldmVyXyBleHBvc2UgXCJwcml2YXRlXCIgZGF0YSB0byB1c2VyIGNvZGUgKFRPRE86IERyb3AgX2RhdGEsIF9yZW1vdmVEYXRhKVxuLy9cdDUuIEF2b2lkIGV4cG9zaW5nIGltcGxlbWVudGF0aW9uIGRldGFpbHMgb24gdXNlciBvYmplY3RzIChlZy4gZXhwYW5kbyBwcm9wZXJ0aWVzKVxuLy9cdDYuIFByb3ZpZGUgYSBjbGVhciBwYXRoIGZvciBpbXBsZW1lbnRhdGlvbiB1cGdyYWRlIHRvIFdlYWtNYXAgaW4gMjAxNFxuXG52YXIgcmJyYWNlID0gL14oPzpcXHtbXFx3XFxXXSpcXH18XFxbW1xcd1xcV10qXFxdKSQvLFxuXHRybXVsdGlEYXNoID0gL1tBLVpdL2c7XG5cbmZ1bmN0aW9uIGdldERhdGEoIGRhdGEgKSB7XG5cdGlmICggZGF0YSA9PT0gXCJ0cnVlXCIgKSB7XG5cdFx0cmV0dXJuIHRydWU7XG5cdH1cblxuXHRpZiAoIGRhdGEgPT09IFwiZmFsc2VcIiApIHtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblxuXHRpZiAoIGRhdGEgPT09IFwibnVsbFwiICkge1xuXHRcdHJldHVybiBudWxsO1xuXHR9XG5cblx0Ly8gT25seSBjb252ZXJ0IHRvIGEgbnVtYmVyIGlmIGl0IGRvZXNuJ3QgY2hhbmdlIHRoZSBzdHJpbmdcblx0aWYgKCBkYXRhID09PSArZGF0YSArIFwiXCIgKSB7XG5cdFx0cmV0dXJuICtkYXRhO1xuXHR9XG5cblx0aWYgKCByYnJhY2UudGVzdCggZGF0YSApICkge1xuXHRcdHJldHVybiBKU09OLnBhcnNlKCBkYXRhICk7XG5cdH1cblxuXHRyZXR1cm4gZGF0YTtcbn1cblxuZnVuY3Rpb24gZGF0YUF0dHIoIGVsZW0sIGtleSwgZGF0YSApIHtcblx0dmFyIG5hbWU7XG5cblx0Ly8gSWYgbm90aGluZyB3YXMgZm91bmQgaW50ZXJuYWxseSwgdHJ5IHRvIGZldGNoIGFueVxuXHQvLyBkYXRhIGZyb20gdGhlIEhUTUw1IGRhdGEtKiBhdHRyaWJ1dGVcblx0aWYgKCBkYXRhID09PSB1bmRlZmluZWQgJiYgZWxlbS5ub2RlVHlwZSA9PT0gMSApIHtcblx0XHRuYW1lID0gXCJkYXRhLVwiICsga2V5LnJlcGxhY2UoIHJtdWx0aURhc2gsIFwiLSQmXCIgKS50b0xvd2VyQ2FzZSgpO1xuXHRcdGRhdGEgPSBlbGVtLmdldEF0dHJpYnV0ZSggbmFtZSApO1xuXG5cdFx0aWYgKCB0eXBlb2YgZGF0YSA9PT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdHRyeSB7XG5cdFx0XHRcdGRhdGEgPSBnZXREYXRhKCBkYXRhICk7XG5cdFx0XHR9IGNhdGNoICggZSApIHt9XG5cblx0XHRcdC8vIE1ha2Ugc3VyZSB3ZSBzZXQgdGhlIGRhdGEgc28gaXQgaXNuJ3QgY2hhbmdlZCBsYXRlclxuXHRcdFx0ZGF0YVVzZXIuc2V0KCBlbGVtLCBrZXksIGRhdGEgKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0ZGF0YSA9IHVuZGVmaW5lZDtcblx0XHR9XG5cdH1cblx0cmV0dXJuIGRhdGE7XG59XG5cbmpRdWVyeS5leHRlbmQoIHtcblx0aGFzRGF0YTogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0cmV0dXJuIGRhdGFVc2VyLmhhc0RhdGEoIGVsZW0gKSB8fCBkYXRhUHJpdi5oYXNEYXRhKCBlbGVtICk7XG5cdH0sXG5cblx0ZGF0YTogZnVuY3Rpb24oIGVsZW0sIG5hbWUsIGRhdGEgKSB7XG5cdFx0cmV0dXJuIGRhdGFVc2VyLmFjY2VzcyggZWxlbSwgbmFtZSwgZGF0YSApO1xuXHR9LFxuXG5cdHJlbW92ZURhdGE6IGZ1bmN0aW9uKCBlbGVtLCBuYW1lICkge1xuXHRcdGRhdGFVc2VyLnJlbW92ZSggZWxlbSwgbmFtZSApO1xuXHR9LFxuXG5cdC8vIFRPRE86IE5vdyB0aGF0IGFsbCBjYWxscyB0byBfZGF0YSBhbmQgX3JlbW92ZURhdGEgaGF2ZSBiZWVuIHJlcGxhY2VkXG5cdC8vIHdpdGggZGlyZWN0IGNhbGxzIHRvIGRhdGFQcml2IG1ldGhvZHMsIHRoZXNlIGNhbiBiZSBkZXByZWNhdGVkLlxuXHRfZGF0YTogZnVuY3Rpb24oIGVsZW0sIG5hbWUsIGRhdGEgKSB7XG5cdFx0cmV0dXJuIGRhdGFQcml2LmFjY2VzcyggZWxlbSwgbmFtZSwgZGF0YSApO1xuXHR9LFxuXG5cdF9yZW1vdmVEYXRhOiBmdW5jdGlvbiggZWxlbSwgbmFtZSApIHtcblx0XHRkYXRhUHJpdi5yZW1vdmUoIGVsZW0sIG5hbWUgKTtcblx0fVxufSApO1xuXG5qUXVlcnkuZm4uZXh0ZW5kKCB7XG5cdGRhdGE6IGZ1bmN0aW9uKCBrZXksIHZhbHVlICkge1xuXHRcdHZhciBpLCBuYW1lLCBkYXRhLFxuXHRcdFx0ZWxlbSA9IHRoaXNbIDAgXSxcblx0XHRcdGF0dHJzID0gZWxlbSAmJiBlbGVtLmF0dHJpYnV0ZXM7XG5cblx0XHQvLyBHZXRzIGFsbCB2YWx1ZXNcblx0XHRpZiAoIGtleSA9PT0gdW5kZWZpbmVkICkge1xuXHRcdFx0aWYgKCB0aGlzLmxlbmd0aCApIHtcblx0XHRcdFx0ZGF0YSA9IGRhdGFVc2VyLmdldCggZWxlbSApO1xuXG5cdFx0XHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gMSAmJiAhZGF0YVByaXYuZ2V0KCBlbGVtLCBcImhhc0RhdGFBdHRyc1wiICkgKSB7XG5cdFx0XHRcdFx0aSA9IGF0dHJzLmxlbmd0aDtcblx0XHRcdFx0XHR3aGlsZSAoIGktLSApIHtcblxuXHRcdFx0XHRcdFx0Ly8gU3VwcG9ydDogSUUgMTEgb25seVxuXHRcdFx0XHRcdFx0Ly8gVGhlIGF0dHJzIGVsZW1lbnRzIGNhbiBiZSBudWxsICgjMTQ4OTQpXG5cdFx0XHRcdFx0XHRpZiAoIGF0dHJzWyBpIF0gKSB7XG5cdFx0XHRcdFx0XHRcdG5hbWUgPSBhdHRyc1sgaSBdLm5hbWU7XG5cdFx0XHRcdFx0XHRcdGlmICggbmFtZS5pbmRleE9mKCBcImRhdGEtXCIgKSA9PT0gMCApIHtcblx0XHRcdFx0XHRcdFx0XHRuYW1lID0gY2FtZWxDYXNlKCBuYW1lLnNsaWNlKCA1ICkgKTtcblx0XHRcdFx0XHRcdFx0XHRkYXRhQXR0ciggZWxlbSwgbmFtZSwgZGF0YVsgbmFtZSBdICk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0ZGF0YVByaXYuc2V0KCBlbGVtLCBcImhhc0RhdGFBdHRyc1wiLCB0cnVlICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIGRhdGE7XG5cdFx0fVxuXG5cdFx0Ly8gU2V0cyBtdWx0aXBsZSB2YWx1ZXNcblx0XHRpZiAoIHR5cGVvZiBrZXkgPT09IFwib2JqZWN0XCIgKSB7XG5cdFx0XHRyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcblx0XHRcdFx0ZGF0YVVzZXIuc2V0KCB0aGlzLCBrZXkgKTtcblx0XHRcdH0gKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gYWNjZXNzKCB0aGlzLCBmdW5jdGlvbiggdmFsdWUgKSB7XG5cdFx0XHR2YXIgZGF0YTtcblxuXHRcdFx0Ly8gVGhlIGNhbGxpbmcgalF1ZXJ5IG9iamVjdCAoZWxlbWVudCBtYXRjaGVzKSBpcyBub3QgZW1wdHlcblx0XHRcdC8vIChhbmQgdGhlcmVmb3JlIGhhcyBhbiBlbGVtZW50IGFwcGVhcnMgYXQgdGhpc1sgMCBdKSBhbmQgdGhlXG5cdFx0XHQvLyBgdmFsdWVgIHBhcmFtZXRlciB3YXMgbm90IHVuZGVmaW5lZC4gQW4gZW1wdHkgalF1ZXJ5IG9iamVjdFxuXHRcdFx0Ly8gd2lsbCByZXN1bHQgaW4gYHVuZGVmaW5lZGAgZm9yIGVsZW0gPSB0aGlzWyAwIF0gd2hpY2ggd2lsbFxuXHRcdFx0Ly8gdGhyb3cgYW4gZXhjZXB0aW9uIGlmIGFuIGF0dGVtcHQgdG8gcmVhZCBhIGRhdGEgY2FjaGUgaXMgbWFkZS5cblx0XHRcdGlmICggZWxlbSAmJiB2YWx1ZSA9PT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRcdC8vIEF0dGVtcHQgdG8gZ2V0IGRhdGEgZnJvbSB0aGUgY2FjaGVcblx0XHRcdFx0Ly8gVGhlIGtleSB3aWxsIGFsd2F5cyBiZSBjYW1lbENhc2VkIGluIERhdGFcblx0XHRcdFx0ZGF0YSA9IGRhdGFVc2VyLmdldCggZWxlbSwga2V5ICk7XG5cdFx0XHRcdGlmICggZGF0YSAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHRcdHJldHVybiBkYXRhO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gQXR0ZW1wdCB0byBcImRpc2NvdmVyXCIgdGhlIGRhdGEgaW5cblx0XHRcdFx0Ly8gSFRNTDUgY3VzdG9tIGRhdGEtKiBhdHRyc1xuXHRcdFx0XHRkYXRhID0gZGF0YUF0dHIoIGVsZW0sIGtleSApO1xuXHRcdFx0XHRpZiAoIGRhdGEgIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0XHRyZXR1cm4gZGF0YTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIFdlIHRyaWVkIHJlYWxseSBoYXJkLCBidXQgdGhlIGRhdGEgZG9lc24ndCBleGlzdC5cblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBTZXQgdGhlIGRhdGEuLi5cblx0XHRcdHRoaXMuZWFjaCggZnVuY3Rpb24oKSB7XG5cblx0XHRcdFx0Ly8gV2UgYWx3YXlzIHN0b3JlIHRoZSBjYW1lbENhc2VkIGtleVxuXHRcdFx0XHRkYXRhVXNlci5zZXQoIHRoaXMsIGtleSwgdmFsdWUgKTtcblx0XHRcdH0gKTtcblx0XHR9LCBudWxsLCB2YWx1ZSwgYXJndW1lbnRzLmxlbmd0aCA+IDEsIG51bGwsIHRydWUgKTtcblx0fSxcblxuXHRyZW1vdmVEYXRhOiBmdW5jdGlvbigga2V5ICkge1xuXHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCkge1xuXHRcdFx0ZGF0YVVzZXIucmVtb3ZlKCB0aGlzLCBrZXkgKTtcblx0XHR9ICk7XG5cdH1cbn0gKTtcblxuXG5qUXVlcnkuZXh0ZW5kKCB7XG5cdHF1ZXVlOiBmdW5jdGlvbiggZWxlbSwgdHlwZSwgZGF0YSApIHtcblx0XHR2YXIgcXVldWU7XG5cblx0XHRpZiAoIGVsZW0gKSB7XG5cdFx0XHR0eXBlID0gKCB0eXBlIHx8IFwiZnhcIiApICsgXCJxdWV1ZVwiO1xuXHRcdFx0cXVldWUgPSBkYXRhUHJpdi5nZXQoIGVsZW0sIHR5cGUgKTtcblxuXHRcdFx0Ly8gU3BlZWQgdXAgZGVxdWV1ZSBieSBnZXR0aW5nIG91dCBxdWlja2x5IGlmIHRoaXMgaXMganVzdCBhIGxvb2t1cFxuXHRcdFx0aWYgKCBkYXRhICkge1xuXHRcdFx0XHRpZiAoICFxdWV1ZSB8fCBBcnJheS5pc0FycmF5KCBkYXRhICkgKSB7XG5cdFx0XHRcdFx0cXVldWUgPSBkYXRhUHJpdi5hY2Nlc3MoIGVsZW0sIHR5cGUsIGpRdWVyeS5tYWtlQXJyYXkoIGRhdGEgKSApO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHF1ZXVlLnB1c2goIGRhdGEgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHF1ZXVlIHx8IFtdO1xuXHRcdH1cblx0fSxcblxuXHRkZXF1ZXVlOiBmdW5jdGlvbiggZWxlbSwgdHlwZSApIHtcblx0XHR0eXBlID0gdHlwZSB8fCBcImZ4XCI7XG5cblx0XHR2YXIgcXVldWUgPSBqUXVlcnkucXVldWUoIGVsZW0sIHR5cGUgKSxcblx0XHRcdHN0YXJ0TGVuZ3RoID0gcXVldWUubGVuZ3RoLFxuXHRcdFx0Zm4gPSBxdWV1ZS5zaGlmdCgpLFxuXHRcdFx0aG9va3MgPSBqUXVlcnkuX3F1ZXVlSG9va3MoIGVsZW0sIHR5cGUgKSxcblx0XHRcdG5leHQgPSBmdW5jdGlvbigpIHtcblx0XHRcdFx0alF1ZXJ5LmRlcXVldWUoIGVsZW0sIHR5cGUgKTtcblx0XHRcdH07XG5cblx0XHQvLyBJZiB0aGUgZnggcXVldWUgaXMgZGVxdWV1ZWQsIGFsd2F5cyByZW1vdmUgdGhlIHByb2dyZXNzIHNlbnRpbmVsXG5cdFx0aWYgKCBmbiA9PT0gXCJpbnByb2dyZXNzXCIgKSB7XG5cdFx0XHRmbiA9IHF1ZXVlLnNoaWZ0KCk7XG5cdFx0XHRzdGFydExlbmd0aC0tO1xuXHRcdH1cblxuXHRcdGlmICggZm4gKSB7XG5cblx0XHRcdC8vIEFkZCBhIHByb2dyZXNzIHNlbnRpbmVsIHRvIHByZXZlbnQgdGhlIGZ4IHF1ZXVlIGZyb20gYmVpbmdcblx0XHRcdC8vIGF1dG9tYXRpY2FsbHkgZGVxdWV1ZWRcblx0XHRcdGlmICggdHlwZSA9PT0gXCJmeFwiICkge1xuXHRcdFx0XHRxdWV1ZS51bnNoaWZ0KCBcImlucHJvZ3Jlc3NcIiApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBDbGVhciB1cCB0aGUgbGFzdCBxdWV1ZSBzdG9wIGZ1bmN0aW9uXG5cdFx0XHRkZWxldGUgaG9va3Muc3RvcDtcblx0XHRcdGZuLmNhbGwoIGVsZW0sIG5leHQsIGhvb2tzICk7XG5cdFx0fVxuXG5cdFx0aWYgKCAhc3RhcnRMZW5ndGggJiYgaG9va3MgKSB7XG5cdFx0XHRob29rcy5lbXB0eS5maXJlKCk7XG5cdFx0fVxuXHR9LFxuXG5cdC8vIE5vdCBwdWJsaWMgLSBnZW5lcmF0ZSBhIHF1ZXVlSG9va3Mgb2JqZWN0LCBvciByZXR1cm4gdGhlIGN1cnJlbnQgb25lXG5cdF9xdWV1ZUhvb2tzOiBmdW5jdGlvbiggZWxlbSwgdHlwZSApIHtcblx0XHR2YXIga2V5ID0gdHlwZSArIFwicXVldWVIb29rc1wiO1xuXHRcdHJldHVybiBkYXRhUHJpdi5nZXQoIGVsZW0sIGtleSApIHx8IGRhdGFQcml2LmFjY2VzcyggZWxlbSwga2V5LCB7XG5cdFx0XHRlbXB0eTogalF1ZXJ5LkNhbGxiYWNrcyggXCJvbmNlIG1lbW9yeVwiICkuYWRkKCBmdW5jdGlvbigpIHtcblx0XHRcdFx0ZGF0YVByaXYucmVtb3ZlKCBlbGVtLCBbIHR5cGUgKyBcInF1ZXVlXCIsIGtleSBdICk7XG5cdFx0XHR9IClcblx0XHR9ICk7XG5cdH1cbn0gKTtcblxualF1ZXJ5LmZuLmV4dGVuZCgge1xuXHRxdWV1ZTogZnVuY3Rpb24oIHR5cGUsIGRhdGEgKSB7XG5cdFx0dmFyIHNldHRlciA9IDI7XG5cblx0XHRpZiAoIHR5cGVvZiB0eXBlICE9PSBcInN0cmluZ1wiICkge1xuXHRcdFx0ZGF0YSA9IHR5cGU7XG5cdFx0XHR0eXBlID0gXCJmeFwiO1xuXHRcdFx0c2V0dGVyLS07XG5cdFx0fVxuXG5cdFx0aWYgKCBhcmd1bWVudHMubGVuZ3RoIDwgc2V0dGVyICkge1xuXHRcdFx0cmV0dXJuIGpRdWVyeS5xdWV1ZSggdGhpc1sgMCBdLCB0eXBlICk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGRhdGEgPT09IHVuZGVmaW5lZCA/XG5cdFx0XHR0aGlzIDpcblx0XHRcdHRoaXMuZWFjaCggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHZhciBxdWV1ZSA9IGpRdWVyeS5xdWV1ZSggdGhpcywgdHlwZSwgZGF0YSApO1xuXG5cdFx0XHRcdC8vIEVuc3VyZSBhIGhvb2tzIGZvciB0aGlzIHF1ZXVlXG5cdFx0XHRcdGpRdWVyeS5fcXVldWVIb29rcyggdGhpcywgdHlwZSApO1xuXG5cdFx0XHRcdGlmICggdHlwZSA9PT0gXCJmeFwiICYmIHF1ZXVlWyAwIF0gIT09IFwiaW5wcm9ncmVzc1wiICkge1xuXHRcdFx0XHRcdGpRdWVyeS5kZXF1ZXVlKCB0aGlzLCB0eXBlICk7XG5cdFx0XHRcdH1cblx0XHRcdH0gKTtcblx0fSxcblx0ZGVxdWV1ZTogZnVuY3Rpb24oIHR5cGUgKSB7XG5cdFx0cmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24oKSB7XG5cdFx0XHRqUXVlcnkuZGVxdWV1ZSggdGhpcywgdHlwZSApO1xuXHRcdH0gKTtcblx0fSxcblx0Y2xlYXJRdWV1ZTogZnVuY3Rpb24oIHR5cGUgKSB7XG5cdFx0cmV0dXJuIHRoaXMucXVldWUoIHR5cGUgfHwgXCJmeFwiLCBbXSApO1xuXHR9LFxuXG5cdC8vIEdldCBhIHByb21pc2UgcmVzb2x2ZWQgd2hlbiBxdWV1ZXMgb2YgYSBjZXJ0YWluIHR5cGVcblx0Ly8gYXJlIGVtcHRpZWQgKGZ4IGlzIHRoZSB0eXBlIGJ5IGRlZmF1bHQpXG5cdHByb21pc2U6IGZ1bmN0aW9uKCB0eXBlLCBvYmogKSB7XG5cdFx0dmFyIHRtcCxcblx0XHRcdGNvdW50ID0gMSxcblx0XHRcdGRlZmVyID0galF1ZXJ5LkRlZmVycmVkKCksXG5cdFx0XHRlbGVtZW50cyA9IHRoaXMsXG5cdFx0XHRpID0gdGhpcy5sZW5ndGgsXG5cdFx0XHRyZXNvbHZlID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGlmICggISggLS1jb3VudCApICkge1xuXHRcdFx0XHRcdGRlZmVyLnJlc29sdmVXaXRoKCBlbGVtZW50cywgWyBlbGVtZW50cyBdICk7XG5cdFx0XHRcdH1cblx0XHRcdH07XG5cblx0XHRpZiAoIHR5cGVvZiB0eXBlICE9PSBcInN0cmluZ1wiICkge1xuXHRcdFx0b2JqID0gdHlwZTtcblx0XHRcdHR5cGUgPSB1bmRlZmluZWQ7XG5cdFx0fVxuXHRcdHR5cGUgPSB0eXBlIHx8IFwiZnhcIjtcblxuXHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0dG1wID0gZGF0YVByaXYuZ2V0KCBlbGVtZW50c1sgaSBdLCB0eXBlICsgXCJxdWV1ZUhvb2tzXCIgKTtcblx0XHRcdGlmICggdG1wICYmIHRtcC5lbXB0eSApIHtcblx0XHRcdFx0Y291bnQrKztcblx0XHRcdFx0dG1wLmVtcHR5LmFkZCggcmVzb2x2ZSApO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXNvbHZlKCk7XG5cdFx0cmV0dXJuIGRlZmVyLnByb21pc2UoIG9iaiApO1xuXHR9XG59ICk7XG52YXIgcG51bSA9ICggL1srLV0/KD86XFxkKlxcLnwpXFxkKyg/OltlRV1bKy1dP1xcZCt8KS8gKS5zb3VyY2U7XG5cbnZhciByY3NzTnVtID0gbmV3IFJlZ0V4cCggXCJeKD86KFsrLV0pPXwpKFwiICsgcG51bSArIFwiKShbYS16JV0qKSRcIiwgXCJpXCIgKTtcblxuXG52YXIgY3NzRXhwYW5kID0gWyBcIlRvcFwiLCBcIlJpZ2h0XCIsIFwiQm90dG9tXCIsIFwiTGVmdFwiIF07XG5cbnZhciBkb2N1bWVudEVsZW1lbnQgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7XG5cblxuXG5cdHZhciBpc0F0dGFjaGVkID0gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4galF1ZXJ5LmNvbnRhaW5zKCBlbGVtLm93bmVyRG9jdW1lbnQsIGVsZW0gKTtcblx0XHR9LFxuXHRcdGNvbXBvc2VkID0geyBjb21wb3NlZDogdHJ1ZSB9O1xuXG5cdC8vIFN1cHBvcnQ6IElFIDkgLSAxMSssIEVkZ2UgMTIgLSAxOCssIGlPUyAxMC4wIC0gMTAuMiBvbmx5XG5cdC8vIENoZWNrIGF0dGFjaG1lbnQgYWNyb3NzIHNoYWRvdyBET00gYm91bmRhcmllcyB3aGVuIHBvc3NpYmxlIChnaC0zNTA0KVxuXHQvLyBTdXBwb3J0OiBpT1MgMTAuMC0xMC4yIG9ubHlcblx0Ly8gRWFybHkgaU9TIDEwIHZlcnNpb25zIHN1cHBvcnQgYGF0dGFjaFNoYWRvd2AgYnV0IG5vdCBgZ2V0Um9vdE5vZGVgLFxuXHQvLyBsZWFkaW5nIHRvIGVycm9ycy4gV2UgbmVlZCB0byBjaGVjayBmb3IgYGdldFJvb3ROb2RlYC5cblx0aWYgKCBkb2N1bWVudEVsZW1lbnQuZ2V0Um9vdE5vZGUgKSB7XG5cdFx0aXNBdHRhY2hlZCA9IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0cmV0dXJuIGpRdWVyeS5jb250YWlucyggZWxlbS5vd25lckRvY3VtZW50LCBlbGVtICkgfHxcblx0XHRcdFx0ZWxlbS5nZXRSb290Tm9kZSggY29tcG9zZWQgKSA9PT0gZWxlbS5vd25lckRvY3VtZW50O1xuXHRcdH07XG5cdH1cbnZhciBpc0hpZGRlbldpdGhpblRyZWUgPSBmdW5jdGlvbiggZWxlbSwgZWwgKSB7XG5cblx0XHQvLyBpc0hpZGRlbldpdGhpblRyZWUgbWlnaHQgYmUgY2FsbGVkIGZyb20galF1ZXJ5I2ZpbHRlciBmdW5jdGlvbjtcblx0XHQvLyBpbiB0aGF0IGNhc2UsIGVsZW1lbnQgd2lsbCBiZSBzZWNvbmQgYXJndW1lbnRcblx0XHRlbGVtID0gZWwgfHwgZWxlbTtcblxuXHRcdC8vIElubGluZSBzdHlsZSB0cnVtcHMgYWxsXG5cdFx0cmV0dXJuIGVsZW0uc3R5bGUuZGlzcGxheSA9PT0gXCJub25lXCIgfHxcblx0XHRcdGVsZW0uc3R5bGUuZGlzcGxheSA9PT0gXCJcIiAmJlxuXG5cdFx0XHQvLyBPdGhlcndpc2UsIGNoZWNrIGNvbXB1dGVkIHN0eWxlXG5cdFx0XHQvLyBTdXBwb3J0OiBGaXJlZm94IDw9NDMgLSA0NVxuXHRcdFx0Ly8gRGlzY29ubmVjdGVkIGVsZW1lbnRzIGNhbiBoYXZlIGNvbXB1dGVkIGRpc3BsYXk6IG5vbmUsIHNvIGZpcnN0IGNvbmZpcm0gdGhhdCBlbGVtIGlzXG5cdFx0XHQvLyBpbiB0aGUgZG9jdW1lbnQuXG5cdFx0XHRpc0F0dGFjaGVkKCBlbGVtICkgJiZcblxuXHRcdFx0alF1ZXJ5LmNzcyggZWxlbSwgXCJkaXNwbGF5XCIgKSA9PT0gXCJub25lXCI7XG5cdH07XG5cblxuXG5mdW5jdGlvbiBhZGp1c3RDU1MoIGVsZW0sIHByb3AsIHZhbHVlUGFydHMsIHR3ZWVuICkge1xuXHR2YXIgYWRqdXN0ZWQsIHNjYWxlLFxuXHRcdG1heEl0ZXJhdGlvbnMgPSAyMCxcblx0XHRjdXJyZW50VmFsdWUgPSB0d2VlbiA/XG5cdFx0XHRmdW5jdGlvbigpIHtcblx0XHRcdFx0cmV0dXJuIHR3ZWVuLmN1cigpO1xuXHRcdFx0fSA6XG5cdFx0XHRmdW5jdGlvbigpIHtcblx0XHRcdFx0cmV0dXJuIGpRdWVyeS5jc3MoIGVsZW0sIHByb3AsIFwiXCIgKTtcblx0XHRcdH0sXG5cdFx0aW5pdGlhbCA9IGN1cnJlbnRWYWx1ZSgpLFxuXHRcdHVuaXQgPSB2YWx1ZVBhcnRzICYmIHZhbHVlUGFydHNbIDMgXSB8fCAoIGpRdWVyeS5jc3NOdW1iZXJbIHByb3AgXSA/IFwiXCIgOiBcInB4XCIgKSxcblxuXHRcdC8vIFN0YXJ0aW5nIHZhbHVlIGNvbXB1dGF0aW9uIGlzIHJlcXVpcmVkIGZvciBwb3RlbnRpYWwgdW5pdCBtaXNtYXRjaGVzXG5cdFx0aW5pdGlhbEluVW5pdCA9IGVsZW0ubm9kZVR5cGUgJiZcblx0XHRcdCggalF1ZXJ5LmNzc051bWJlclsgcHJvcCBdIHx8IHVuaXQgIT09IFwicHhcIiAmJiAraW5pdGlhbCApICYmXG5cdFx0XHRyY3NzTnVtLmV4ZWMoIGpRdWVyeS5jc3MoIGVsZW0sIHByb3AgKSApO1xuXG5cdGlmICggaW5pdGlhbEluVW5pdCAmJiBpbml0aWFsSW5Vbml0WyAzIF0gIT09IHVuaXQgKSB7XG5cblx0XHQvLyBTdXBwb3J0OiBGaXJlZm94IDw9NTRcblx0XHQvLyBIYWx2ZSB0aGUgaXRlcmF0aW9uIHRhcmdldCB2YWx1ZSB0byBwcmV2ZW50IGludGVyZmVyZW5jZSBmcm9tIENTUyB1cHBlciBib3VuZHMgKGdoLTIxNDQpXG5cdFx0aW5pdGlhbCA9IGluaXRpYWwgLyAyO1xuXG5cdFx0Ly8gVHJ1c3QgdW5pdHMgcmVwb3J0ZWQgYnkgalF1ZXJ5LmNzc1xuXHRcdHVuaXQgPSB1bml0IHx8IGluaXRpYWxJblVuaXRbIDMgXTtcblxuXHRcdC8vIEl0ZXJhdGl2ZWx5IGFwcHJveGltYXRlIGZyb20gYSBub256ZXJvIHN0YXJ0aW5nIHBvaW50XG5cdFx0aW5pdGlhbEluVW5pdCA9ICtpbml0aWFsIHx8IDE7XG5cblx0XHR3aGlsZSAoIG1heEl0ZXJhdGlvbnMtLSApIHtcblxuXHRcdFx0Ly8gRXZhbHVhdGUgYW5kIHVwZGF0ZSBvdXIgYmVzdCBndWVzcyAoZG91YmxpbmcgZ3Vlc3NlcyB0aGF0IHplcm8gb3V0KS5cblx0XHRcdC8vIEZpbmlzaCBpZiB0aGUgc2NhbGUgZXF1YWxzIG9yIGNyb3NzZXMgMSAobWFraW5nIHRoZSBvbGQqbmV3IHByb2R1Y3Qgbm9uLXBvc2l0aXZlKS5cblx0XHRcdGpRdWVyeS5zdHlsZSggZWxlbSwgcHJvcCwgaW5pdGlhbEluVW5pdCArIHVuaXQgKTtcblx0XHRcdGlmICggKCAxIC0gc2NhbGUgKSAqICggMSAtICggc2NhbGUgPSBjdXJyZW50VmFsdWUoKSAvIGluaXRpYWwgfHwgMC41ICkgKSA8PSAwICkge1xuXHRcdFx0XHRtYXhJdGVyYXRpb25zID0gMDtcblx0XHRcdH1cblx0XHRcdGluaXRpYWxJblVuaXQgPSBpbml0aWFsSW5Vbml0IC8gc2NhbGU7XG5cblx0XHR9XG5cblx0XHRpbml0aWFsSW5Vbml0ID0gaW5pdGlhbEluVW5pdCAqIDI7XG5cdFx0alF1ZXJ5LnN0eWxlKCBlbGVtLCBwcm9wLCBpbml0aWFsSW5Vbml0ICsgdW5pdCApO1xuXG5cdFx0Ly8gTWFrZSBzdXJlIHdlIHVwZGF0ZSB0aGUgdHdlZW4gcHJvcGVydGllcyBsYXRlciBvblxuXHRcdHZhbHVlUGFydHMgPSB2YWx1ZVBhcnRzIHx8IFtdO1xuXHR9XG5cblx0aWYgKCB2YWx1ZVBhcnRzICkge1xuXHRcdGluaXRpYWxJblVuaXQgPSAraW5pdGlhbEluVW5pdCB8fCAraW5pdGlhbCB8fCAwO1xuXG5cdFx0Ly8gQXBwbHkgcmVsYXRpdmUgb2Zmc2V0ICgrPS8tPSkgaWYgc3BlY2lmaWVkXG5cdFx0YWRqdXN0ZWQgPSB2YWx1ZVBhcnRzWyAxIF0gP1xuXHRcdFx0aW5pdGlhbEluVW5pdCArICggdmFsdWVQYXJ0c1sgMSBdICsgMSApICogdmFsdWVQYXJ0c1sgMiBdIDpcblx0XHRcdCt2YWx1ZVBhcnRzWyAyIF07XG5cdFx0aWYgKCB0d2VlbiApIHtcblx0XHRcdHR3ZWVuLnVuaXQgPSB1bml0O1xuXHRcdFx0dHdlZW4uc3RhcnQgPSBpbml0aWFsSW5Vbml0O1xuXHRcdFx0dHdlZW4uZW5kID0gYWRqdXN0ZWQ7XG5cdFx0fVxuXHR9XG5cdHJldHVybiBhZGp1c3RlZDtcbn1cblxuXG52YXIgZGVmYXVsdERpc3BsYXlNYXAgPSB7fTtcblxuZnVuY3Rpb24gZ2V0RGVmYXVsdERpc3BsYXkoIGVsZW0gKSB7XG5cdHZhciB0ZW1wLFxuXHRcdGRvYyA9IGVsZW0ub3duZXJEb2N1bWVudCxcblx0XHRub2RlTmFtZSA9IGVsZW0ubm9kZU5hbWUsXG5cdFx0ZGlzcGxheSA9IGRlZmF1bHREaXNwbGF5TWFwWyBub2RlTmFtZSBdO1xuXG5cdGlmICggZGlzcGxheSApIHtcblx0XHRyZXR1cm4gZGlzcGxheTtcblx0fVxuXG5cdHRlbXAgPSBkb2MuYm9keS5hcHBlbmRDaGlsZCggZG9jLmNyZWF0ZUVsZW1lbnQoIG5vZGVOYW1lICkgKTtcblx0ZGlzcGxheSA9IGpRdWVyeS5jc3MoIHRlbXAsIFwiZGlzcGxheVwiICk7XG5cblx0dGVtcC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKCB0ZW1wICk7XG5cblx0aWYgKCBkaXNwbGF5ID09PSBcIm5vbmVcIiApIHtcblx0XHRkaXNwbGF5ID0gXCJibG9ja1wiO1xuXHR9XG5cdGRlZmF1bHREaXNwbGF5TWFwWyBub2RlTmFtZSBdID0gZGlzcGxheTtcblxuXHRyZXR1cm4gZGlzcGxheTtcbn1cblxuZnVuY3Rpb24gc2hvd0hpZGUoIGVsZW1lbnRzLCBzaG93ICkge1xuXHR2YXIgZGlzcGxheSwgZWxlbSxcblx0XHR2YWx1ZXMgPSBbXSxcblx0XHRpbmRleCA9IDAsXG5cdFx0bGVuZ3RoID0gZWxlbWVudHMubGVuZ3RoO1xuXG5cdC8vIERldGVybWluZSBuZXcgZGlzcGxheSB2YWx1ZSBmb3IgZWxlbWVudHMgdGhhdCBuZWVkIHRvIGNoYW5nZVxuXHRmb3IgKCA7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrICkge1xuXHRcdGVsZW0gPSBlbGVtZW50c1sgaW5kZXggXTtcblx0XHRpZiAoICFlbGVtLnN0eWxlICkge1xuXHRcdFx0Y29udGludWU7XG5cdFx0fVxuXG5cdFx0ZGlzcGxheSA9IGVsZW0uc3R5bGUuZGlzcGxheTtcblx0XHRpZiAoIHNob3cgKSB7XG5cblx0XHRcdC8vIFNpbmNlIHdlIGZvcmNlIHZpc2liaWxpdHkgdXBvbiBjYXNjYWRlLWhpZGRlbiBlbGVtZW50cywgYW4gaW1tZWRpYXRlIChhbmQgc2xvdylcblx0XHRcdC8vIGNoZWNrIGlzIHJlcXVpcmVkIGluIHRoaXMgZmlyc3QgbG9vcCB1bmxlc3Mgd2UgaGF2ZSBhIG5vbmVtcHR5IGRpc3BsYXkgdmFsdWUgKGVpdGhlclxuXHRcdFx0Ly8gaW5saW5lIG9yIGFib3V0LXRvLWJlLXJlc3RvcmVkKVxuXHRcdFx0aWYgKCBkaXNwbGF5ID09PSBcIm5vbmVcIiApIHtcblx0XHRcdFx0dmFsdWVzWyBpbmRleCBdID0gZGF0YVByaXYuZ2V0KCBlbGVtLCBcImRpc3BsYXlcIiApIHx8IG51bGw7XG5cdFx0XHRcdGlmICggIXZhbHVlc1sgaW5kZXggXSApIHtcblx0XHRcdFx0XHRlbGVtLnN0eWxlLmRpc3BsYXkgPSBcIlwiO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRpZiAoIGVsZW0uc3R5bGUuZGlzcGxheSA9PT0gXCJcIiAmJiBpc0hpZGRlbldpdGhpblRyZWUoIGVsZW0gKSApIHtcblx0XHRcdFx0dmFsdWVzWyBpbmRleCBdID0gZ2V0RGVmYXVsdERpc3BsYXkoIGVsZW0gKTtcblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0aWYgKCBkaXNwbGF5ICE9PSBcIm5vbmVcIiApIHtcblx0XHRcdFx0dmFsdWVzWyBpbmRleCBdID0gXCJub25lXCI7XG5cblx0XHRcdFx0Ly8gUmVtZW1iZXIgd2hhdCB3ZSdyZSBvdmVyd3JpdGluZ1xuXHRcdFx0XHRkYXRhUHJpdi5zZXQoIGVsZW0sIFwiZGlzcGxheVwiLCBkaXNwbGF5ICk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0Ly8gU2V0IHRoZSBkaXNwbGF5IG9mIHRoZSBlbGVtZW50cyBpbiBhIHNlY29uZCBsb29wIHRvIGF2b2lkIGNvbnN0YW50IHJlZmxvd1xuXHRmb3IgKCBpbmRleCA9IDA7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrICkge1xuXHRcdGlmICggdmFsdWVzWyBpbmRleCBdICE9IG51bGwgKSB7XG5cdFx0XHRlbGVtZW50c1sgaW5kZXggXS5zdHlsZS5kaXNwbGF5ID0gdmFsdWVzWyBpbmRleCBdO1xuXHRcdH1cblx0fVxuXG5cdHJldHVybiBlbGVtZW50cztcbn1cblxualF1ZXJ5LmZuLmV4dGVuZCgge1xuXHRzaG93OiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gc2hvd0hpZGUoIHRoaXMsIHRydWUgKTtcblx0fSxcblx0aGlkZTogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHNob3dIaWRlKCB0aGlzICk7XG5cdH0sXG5cdHRvZ2dsZTogZnVuY3Rpb24oIHN0YXRlICkge1xuXHRcdGlmICggdHlwZW9mIHN0YXRlID09PSBcImJvb2xlYW5cIiApIHtcblx0XHRcdHJldHVybiBzdGF0ZSA/IHRoaXMuc2hvdygpIDogdGhpcy5oaWRlKCk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24oKSB7XG5cdFx0XHRpZiAoIGlzSGlkZGVuV2l0aGluVHJlZSggdGhpcyApICkge1xuXHRcdFx0XHRqUXVlcnkoIHRoaXMgKS5zaG93KCk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRqUXVlcnkoIHRoaXMgKS5oaWRlKCk7XG5cdFx0XHR9XG5cdFx0fSApO1xuXHR9XG59ICk7XG52YXIgcmNoZWNrYWJsZVR5cGUgPSAoIC9eKD86Y2hlY2tib3h8cmFkaW8pJC9pICk7XG5cbnZhciBydGFnTmFtZSA9ICggLzwoW2Etel1bXlxcL1xcMD5cXHgyMFxcdFxcclxcblxcZl0qKS9pICk7XG5cbnZhciByc2NyaXB0VHlwZSA9ICggL14kfF5tb2R1bGUkfFxcLyg/OmphdmF8ZWNtYSlzY3JpcHQvaSApO1xuXG5cblxuKCBmdW5jdGlvbigpIHtcblx0dmFyIGZyYWdtZW50ID0gZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpLFxuXHRcdGRpdiA9IGZyYWdtZW50LmFwcGVuZENoaWxkKCBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImRpdlwiICkgKSxcblx0XHRpbnB1dCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiaW5wdXRcIiApO1xuXG5cdC8vIFN1cHBvcnQ6IEFuZHJvaWQgNC4wIC0gNC4zIG9ubHlcblx0Ly8gQ2hlY2sgc3RhdGUgbG9zdCBpZiB0aGUgbmFtZSBpcyBzZXQgKCMxMTIxNylcblx0Ly8gU3VwcG9ydDogV2luZG93cyBXZWIgQXBwcyAoV1dBKVxuXHQvLyBgbmFtZWAgYW5kIGB0eXBlYCBtdXN0IHVzZSAuc2V0QXR0cmlidXRlIGZvciBXV0EgKCMxNDkwMSlcblx0aW5wdXQuc2V0QXR0cmlidXRlKCBcInR5cGVcIiwgXCJyYWRpb1wiICk7XG5cdGlucHV0LnNldEF0dHJpYnV0ZSggXCJjaGVja2VkXCIsIFwiY2hlY2tlZFwiICk7XG5cdGlucHV0LnNldEF0dHJpYnV0ZSggXCJuYW1lXCIsIFwidFwiICk7XG5cblx0ZGl2LmFwcGVuZENoaWxkKCBpbnB1dCApO1xuXG5cdC8vIFN1cHBvcnQ6IEFuZHJvaWQgPD00LjEgb25seVxuXHQvLyBPbGRlciBXZWJLaXQgZG9lc24ndCBjbG9uZSBjaGVja2VkIHN0YXRlIGNvcnJlY3RseSBpbiBmcmFnbWVudHNcblx0c3VwcG9ydC5jaGVja0Nsb25lID0gZGl2LmNsb25lTm9kZSggdHJ1ZSApLmNsb25lTm9kZSggdHJ1ZSApLmxhc3RDaGlsZC5jaGVja2VkO1xuXG5cdC8vIFN1cHBvcnQ6IElFIDw9MTEgb25seVxuXHQvLyBNYWtlIHN1cmUgdGV4dGFyZWEgKGFuZCBjaGVja2JveCkgZGVmYXVsdFZhbHVlIGlzIHByb3Blcmx5IGNsb25lZFxuXHRkaXYuaW5uZXJIVE1MID0gXCI8dGV4dGFyZWE+eDwvdGV4dGFyZWE+XCI7XG5cdHN1cHBvcnQubm9DbG9uZUNoZWNrZWQgPSAhIWRpdi5jbG9uZU5vZGUoIHRydWUgKS5sYXN0Q2hpbGQuZGVmYXVsdFZhbHVlO1xuXG5cdC8vIFN1cHBvcnQ6IElFIDw9OSBvbmx5XG5cdC8vIElFIDw9OSByZXBsYWNlcyA8b3B0aW9uPiB0YWdzIHdpdGggdGhlaXIgY29udGVudHMgd2hlbiBpbnNlcnRlZCBvdXRzaWRlIG9mXG5cdC8vIHRoZSBzZWxlY3QgZWxlbWVudC5cblx0ZGl2LmlubmVySFRNTCA9IFwiPG9wdGlvbj48L29wdGlvbj5cIjtcblx0c3VwcG9ydC5vcHRpb24gPSAhIWRpdi5sYXN0Q2hpbGQ7XG59ICkoKTtcblxuXG4vLyBXZSBoYXZlIHRvIGNsb3NlIHRoZXNlIHRhZ3MgdG8gc3VwcG9ydCBYSFRNTCAoIzEzMjAwKVxudmFyIHdyYXBNYXAgPSB7XG5cblx0Ly8gWEhUTUwgcGFyc2VycyBkbyBub3QgbWFnaWNhbGx5IGluc2VydCBlbGVtZW50cyBpbiB0aGVcblx0Ly8gc2FtZSB3YXkgdGhhdCB0YWcgc291cCBwYXJzZXJzIGRvLiBTbyB3ZSBjYW5ub3Qgc2hvcnRlblxuXHQvLyB0aGlzIGJ5IG9taXR0aW5nIDx0Ym9keT4gb3Igb3RoZXIgcmVxdWlyZWQgZWxlbWVudHMuXG5cdHRoZWFkOiBbIDEsIFwiPHRhYmxlPlwiLCBcIjwvdGFibGU+XCIgXSxcblx0Y29sOiBbIDIsIFwiPHRhYmxlPjxjb2xncm91cD5cIiwgXCI8L2NvbGdyb3VwPjwvdGFibGU+XCIgXSxcblx0dHI6IFsgMiwgXCI8dGFibGU+PHRib2R5PlwiLCBcIjwvdGJvZHk+PC90YWJsZT5cIiBdLFxuXHR0ZDogWyAzLCBcIjx0YWJsZT48dGJvZHk+PHRyPlwiLCBcIjwvdHI+PC90Ym9keT48L3RhYmxlPlwiIF0sXG5cblx0X2RlZmF1bHQ6IFsgMCwgXCJcIiwgXCJcIiBdXG59O1xuXG53cmFwTWFwLnRib2R5ID0gd3JhcE1hcC50Zm9vdCA9IHdyYXBNYXAuY29sZ3JvdXAgPSB3cmFwTWFwLmNhcHRpb24gPSB3cmFwTWFwLnRoZWFkO1xud3JhcE1hcC50aCA9IHdyYXBNYXAudGQ7XG5cbi8vIFN1cHBvcnQ6IElFIDw9OSBvbmx5XG5pZiAoICFzdXBwb3J0Lm9wdGlvbiApIHtcblx0d3JhcE1hcC5vcHRncm91cCA9IHdyYXBNYXAub3B0aW9uID0gWyAxLCBcIjxzZWxlY3QgbXVsdGlwbGU9J211bHRpcGxlJz5cIiwgXCI8L3NlbGVjdD5cIiBdO1xufVxuXG5cbmZ1bmN0aW9uIGdldEFsbCggY29udGV4dCwgdGFnICkge1xuXG5cdC8vIFN1cHBvcnQ6IElFIDw9OSAtIDExIG9ubHlcblx0Ly8gVXNlIHR5cGVvZiB0byBhdm9pZCB6ZXJvLWFyZ3VtZW50IG1ldGhvZCBpbnZvY2F0aW9uIG9uIGhvc3Qgb2JqZWN0cyAoIzE1MTUxKVxuXHR2YXIgcmV0O1xuXG5cdGlmICggdHlwZW9mIGNvbnRleHQuZ2V0RWxlbWVudHNCeVRhZ05hbWUgIT09IFwidW5kZWZpbmVkXCIgKSB7XG5cdFx0cmV0ID0gY29udGV4dC5nZXRFbGVtZW50c0J5VGFnTmFtZSggdGFnIHx8IFwiKlwiICk7XG5cblx0fSBlbHNlIGlmICggdHlwZW9mIGNvbnRleHQucXVlcnlTZWxlY3RvckFsbCAhPT0gXCJ1bmRlZmluZWRcIiApIHtcblx0XHRyZXQgPSBjb250ZXh0LnF1ZXJ5U2VsZWN0b3JBbGwoIHRhZyB8fCBcIipcIiApO1xuXG5cdH0gZWxzZSB7XG5cdFx0cmV0ID0gW107XG5cdH1cblxuXHRpZiAoIHRhZyA9PT0gdW5kZWZpbmVkIHx8IHRhZyAmJiBub2RlTmFtZSggY29udGV4dCwgdGFnICkgKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5tZXJnZSggWyBjb250ZXh0IF0sIHJldCApO1xuXHR9XG5cblx0cmV0dXJuIHJldDtcbn1cblxuXG4vLyBNYXJrIHNjcmlwdHMgYXMgaGF2aW5nIGFscmVhZHkgYmVlbiBldmFsdWF0ZWRcbmZ1bmN0aW9uIHNldEdsb2JhbEV2YWwoIGVsZW1zLCByZWZFbGVtZW50cyApIHtcblx0dmFyIGkgPSAwLFxuXHRcdGwgPSBlbGVtcy5sZW5ndGg7XG5cblx0Zm9yICggOyBpIDwgbDsgaSsrICkge1xuXHRcdGRhdGFQcml2LnNldChcblx0XHRcdGVsZW1zWyBpIF0sXG5cdFx0XHRcImdsb2JhbEV2YWxcIixcblx0XHRcdCFyZWZFbGVtZW50cyB8fCBkYXRhUHJpdi5nZXQoIHJlZkVsZW1lbnRzWyBpIF0sIFwiZ2xvYmFsRXZhbFwiIClcblx0XHQpO1xuXHR9XG59XG5cblxudmFyIHJodG1sID0gLzx8JiM/XFx3KzsvO1xuXG5mdW5jdGlvbiBidWlsZEZyYWdtZW50KCBlbGVtcywgY29udGV4dCwgc2NyaXB0cywgc2VsZWN0aW9uLCBpZ25vcmVkICkge1xuXHR2YXIgZWxlbSwgdG1wLCB0YWcsIHdyYXAsIGF0dGFjaGVkLCBqLFxuXHRcdGZyYWdtZW50ID0gY29udGV4dC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCksXG5cdFx0bm9kZXMgPSBbXSxcblx0XHRpID0gMCxcblx0XHRsID0gZWxlbXMubGVuZ3RoO1xuXG5cdGZvciAoIDsgaSA8IGw7IGkrKyApIHtcblx0XHRlbGVtID0gZWxlbXNbIGkgXTtcblxuXHRcdGlmICggZWxlbSB8fCBlbGVtID09PSAwICkge1xuXG5cdFx0XHQvLyBBZGQgbm9kZXMgZGlyZWN0bHlcblx0XHRcdGlmICggdG9UeXBlKCBlbGVtICkgPT09IFwib2JqZWN0XCIgKSB7XG5cblx0XHRcdFx0Ly8gU3VwcG9ydDogQW5kcm9pZCA8PTQuMCBvbmx5LCBQaGFudG9tSlMgMSBvbmx5XG5cdFx0XHRcdC8vIHB1c2guYXBwbHkoXywgYXJyYXlsaWtlKSB0aHJvd3Mgb24gYW5jaWVudCBXZWJLaXRcblx0XHRcdFx0alF1ZXJ5Lm1lcmdlKCBub2RlcywgZWxlbS5ub2RlVHlwZSA/IFsgZWxlbSBdIDogZWxlbSApO1xuXG5cdFx0XHQvLyBDb252ZXJ0IG5vbi1odG1sIGludG8gYSB0ZXh0IG5vZGVcblx0XHRcdH0gZWxzZSBpZiAoICFyaHRtbC50ZXN0KCBlbGVtICkgKSB7XG5cdFx0XHRcdG5vZGVzLnB1c2goIGNvbnRleHQuY3JlYXRlVGV4dE5vZGUoIGVsZW0gKSApO1xuXG5cdFx0XHQvLyBDb252ZXJ0IGh0bWwgaW50byBET00gbm9kZXNcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHRtcCA9IHRtcCB8fCBmcmFnbWVudC5hcHBlbmRDaGlsZCggY29udGV4dC5jcmVhdGVFbGVtZW50KCBcImRpdlwiICkgKTtcblxuXHRcdFx0XHQvLyBEZXNlcmlhbGl6ZSBhIHN0YW5kYXJkIHJlcHJlc2VudGF0aW9uXG5cdFx0XHRcdHRhZyA9ICggcnRhZ05hbWUuZXhlYyggZWxlbSApIHx8IFsgXCJcIiwgXCJcIiBdIClbIDEgXS50b0xvd2VyQ2FzZSgpO1xuXHRcdFx0XHR3cmFwID0gd3JhcE1hcFsgdGFnIF0gfHwgd3JhcE1hcC5fZGVmYXVsdDtcblx0XHRcdFx0dG1wLmlubmVySFRNTCA9IHdyYXBbIDEgXSArIGpRdWVyeS5odG1sUHJlZmlsdGVyKCBlbGVtICkgKyB3cmFwWyAyIF07XG5cblx0XHRcdFx0Ly8gRGVzY2VuZCB0aHJvdWdoIHdyYXBwZXJzIHRvIHRoZSByaWdodCBjb250ZW50XG5cdFx0XHRcdGogPSB3cmFwWyAwIF07XG5cdFx0XHRcdHdoaWxlICggai0tICkge1xuXHRcdFx0XHRcdHRtcCA9IHRtcC5sYXN0Q2hpbGQ7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBTdXBwb3J0OiBBbmRyb2lkIDw9NC4wIG9ubHksIFBoYW50b21KUyAxIG9ubHlcblx0XHRcdFx0Ly8gcHVzaC5hcHBseShfLCBhcnJheWxpa2UpIHRocm93cyBvbiBhbmNpZW50IFdlYktpdFxuXHRcdFx0XHRqUXVlcnkubWVyZ2UoIG5vZGVzLCB0bXAuY2hpbGROb2RlcyApO1xuXG5cdFx0XHRcdC8vIFJlbWVtYmVyIHRoZSB0b3AtbGV2ZWwgY29udGFpbmVyXG5cdFx0XHRcdHRtcCA9IGZyYWdtZW50LmZpcnN0Q2hpbGQ7XG5cblx0XHRcdFx0Ly8gRW5zdXJlIHRoZSBjcmVhdGVkIG5vZGVzIGFyZSBvcnBoYW5lZCAoIzEyMzkyKVxuXHRcdFx0XHR0bXAudGV4dENvbnRlbnQgPSBcIlwiO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC8vIFJlbW92ZSB3cmFwcGVyIGZyb20gZnJhZ21lbnRcblx0ZnJhZ21lbnQudGV4dENvbnRlbnQgPSBcIlwiO1xuXG5cdGkgPSAwO1xuXHR3aGlsZSAoICggZWxlbSA9IG5vZGVzWyBpKysgXSApICkge1xuXG5cdFx0Ly8gU2tpcCBlbGVtZW50cyBhbHJlYWR5IGluIHRoZSBjb250ZXh0IGNvbGxlY3Rpb24gKHRyYWMtNDA4Nylcblx0XHRpZiAoIHNlbGVjdGlvbiAmJiBqUXVlcnkuaW5BcnJheSggZWxlbSwgc2VsZWN0aW9uICkgPiAtMSApIHtcblx0XHRcdGlmICggaWdub3JlZCApIHtcblx0XHRcdFx0aWdub3JlZC5wdXNoKCBlbGVtICk7XG5cdFx0XHR9XG5cdFx0XHRjb250aW51ZTtcblx0XHR9XG5cblx0XHRhdHRhY2hlZCA9IGlzQXR0YWNoZWQoIGVsZW0gKTtcblxuXHRcdC8vIEFwcGVuZCB0byBmcmFnbWVudFxuXHRcdHRtcCA9IGdldEFsbCggZnJhZ21lbnQuYXBwZW5kQ2hpbGQoIGVsZW0gKSwgXCJzY3JpcHRcIiApO1xuXG5cdFx0Ly8gUHJlc2VydmUgc2NyaXB0IGV2YWx1YXRpb24gaGlzdG9yeVxuXHRcdGlmICggYXR0YWNoZWQgKSB7XG5cdFx0XHRzZXRHbG9iYWxFdmFsKCB0bXAgKTtcblx0XHR9XG5cblx0XHQvLyBDYXB0dXJlIGV4ZWN1dGFibGVzXG5cdFx0aWYgKCBzY3JpcHRzICkge1xuXHRcdFx0aiA9IDA7XG5cdFx0XHR3aGlsZSAoICggZWxlbSA9IHRtcFsgaisrIF0gKSApIHtcblx0XHRcdFx0aWYgKCByc2NyaXB0VHlwZS50ZXN0KCBlbGVtLnR5cGUgfHwgXCJcIiApICkge1xuXHRcdFx0XHRcdHNjcmlwdHMucHVzaCggZWxlbSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIGZyYWdtZW50O1xufVxuXG5cbnZhciBydHlwZW5hbWVzcGFjZSA9IC9eKFteLl0qKSg/OlxcLiguKyl8KS87XG5cbmZ1bmN0aW9uIHJldHVyblRydWUoKSB7XG5cdHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiByZXR1cm5GYWxzZSgpIHtcblx0cmV0dXJuIGZhbHNlO1xufVxuXG4vLyBTdXBwb3J0OiBJRSA8PTkgLSAxMStcbi8vIGZvY3VzKCkgYW5kIGJsdXIoKSBhcmUgYXN5bmNocm9ub3VzLCBleGNlcHQgd2hlbiB0aGV5IGFyZSBuby1vcC5cbi8vIFNvIGV4cGVjdCBmb2N1cyB0byBiZSBzeW5jaHJvbm91cyB3aGVuIHRoZSBlbGVtZW50IGlzIGFscmVhZHkgYWN0aXZlLFxuLy8gYW5kIGJsdXIgdG8gYmUgc3luY2hyb25vdXMgd2hlbiB0aGUgZWxlbWVudCBpcyBub3QgYWxyZWFkeSBhY3RpdmUuXG4vLyAoZm9jdXMgYW5kIGJsdXIgYXJlIGFsd2F5cyBzeW5jaHJvbm91cyBpbiBvdGhlciBzdXBwb3J0ZWQgYnJvd3NlcnMsXG4vLyB0aGlzIGp1c3QgZGVmaW5lcyB3aGVuIHdlIGNhbiBjb3VudCBvbiBpdCkuXG5mdW5jdGlvbiBleHBlY3RTeW5jKCBlbGVtLCB0eXBlICkge1xuXHRyZXR1cm4gKCBlbGVtID09PSBzYWZlQWN0aXZlRWxlbWVudCgpICkgPT09ICggdHlwZSA9PT0gXCJmb2N1c1wiICk7XG59XG5cbi8vIFN1cHBvcnQ6IElFIDw9OSBvbmx5XG4vLyBBY2Nlc3NpbmcgZG9jdW1lbnQuYWN0aXZlRWxlbWVudCBjYW4gdGhyb3cgdW5leHBlY3RlZGx5XG4vLyBodHRwczovL2J1Z3MuanF1ZXJ5LmNvbS90aWNrZXQvMTMzOTNcbmZ1bmN0aW9uIHNhZmVBY3RpdmVFbGVtZW50KCkge1xuXHR0cnkge1xuXHRcdHJldHVybiBkb2N1bWVudC5hY3RpdmVFbGVtZW50O1xuXHR9IGNhdGNoICggZXJyICkgeyB9XG59XG5cbmZ1bmN0aW9uIG9uKCBlbGVtLCB0eXBlcywgc2VsZWN0b3IsIGRhdGEsIGZuLCBvbmUgKSB7XG5cdHZhciBvcmlnRm4sIHR5cGU7XG5cblx0Ly8gVHlwZXMgY2FuIGJlIGEgbWFwIG9mIHR5cGVzL2hhbmRsZXJzXG5cdGlmICggdHlwZW9mIHR5cGVzID09PSBcIm9iamVjdFwiICkge1xuXG5cdFx0Ly8gKCB0eXBlcy1PYmplY3QsIHNlbGVjdG9yLCBkYXRhIClcblx0XHRpZiAoIHR5cGVvZiBzZWxlY3RvciAhPT0gXCJzdHJpbmdcIiApIHtcblxuXHRcdFx0Ly8gKCB0eXBlcy1PYmplY3QsIGRhdGEgKVxuXHRcdFx0ZGF0YSA9IGRhdGEgfHwgc2VsZWN0b3I7XG5cdFx0XHRzZWxlY3RvciA9IHVuZGVmaW5lZDtcblx0XHR9XG5cdFx0Zm9yICggdHlwZSBpbiB0eXBlcyApIHtcblx0XHRcdG9uKCBlbGVtLCB0eXBlLCBzZWxlY3RvciwgZGF0YSwgdHlwZXNbIHR5cGUgXSwgb25lICk7XG5cdFx0fVxuXHRcdHJldHVybiBlbGVtO1xuXHR9XG5cblx0aWYgKCBkYXRhID09IG51bGwgJiYgZm4gPT0gbnVsbCApIHtcblxuXHRcdC8vICggdHlwZXMsIGZuIClcblx0XHRmbiA9IHNlbGVjdG9yO1xuXHRcdGRhdGEgPSBzZWxlY3RvciA9IHVuZGVmaW5lZDtcblx0fSBlbHNlIGlmICggZm4gPT0gbnVsbCApIHtcblx0XHRpZiAoIHR5cGVvZiBzZWxlY3RvciA9PT0gXCJzdHJpbmdcIiApIHtcblxuXHRcdFx0Ly8gKCB0eXBlcywgc2VsZWN0b3IsIGZuIClcblx0XHRcdGZuID0gZGF0YTtcblx0XHRcdGRhdGEgPSB1bmRlZmluZWQ7XG5cdFx0fSBlbHNlIHtcblxuXHRcdFx0Ly8gKCB0eXBlcywgZGF0YSwgZm4gKVxuXHRcdFx0Zm4gPSBkYXRhO1xuXHRcdFx0ZGF0YSA9IHNlbGVjdG9yO1xuXHRcdFx0c2VsZWN0b3IgPSB1bmRlZmluZWQ7XG5cdFx0fVxuXHR9XG5cdGlmICggZm4gPT09IGZhbHNlICkge1xuXHRcdGZuID0gcmV0dXJuRmFsc2U7XG5cdH0gZWxzZSBpZiAoICFmbiApIHtcblx0XHRyZXR1cm4gZWxlbTtcblx0fVxuXG5cdGlmICggb25lID09PSAxICkge1xuXHRcdG9yaWdGbiA9IGZuO1xuXHRcdGZuID0gZnVuY3Rpb24oIGV2ZW50ICkge1xuXG5cdFx0XHQvLyBDYW4gdXNlIGFuIGVtcHR5IHNldCwgc2luY2UgZXZlbnQgY29udGFpbnMgdGhlIGluZm9cblx0XHRcdGpRdWVyeSgpLm9mZiggZXZlbnQgKTtcblx0XHRcdHJldHVybiBvcmlnRm4uYXBwbHkoIHRoaXMsIGFyZ3VtZW50cyApO1xuXHRcdH07XG5cblx0XHQvLyBVc2Ugc2FtZSBndWlkIHNvIGNhbGxlciBjYW4gcmVtb3ZlIHVzaW5nIG9yaWdGblxuXHRcdGZuLmd1aWQgPSBvcmlnRm4uZ3VpZCB8fCAoIG9yaWdGbi5ndWlkID0galF1ZXJ5Lmd1aWQrKyApO1xuXHR9XG5cdHJldHVybiBlbGVtLmVhY2goIGZ1bmN0aW9uKCkge1xuXHRcdGpRdWVyeS5ldmVudC5hZGQoIHRoaXMsIHR5cGVzLCBmbiwgZGF0YSwgc2VsZWN0b3IgKTtcblx0fSApO1xufVxuXG4vKlxuICogSGVscGVyIGZ1bmN0aW9ucyBmb3IgbWFuYWdpbmcgZXZlbnRzIC0tIG5vdCBwYXJ0IG9mIHRoZSBwdWJsaWMgaW50ZXJmYWNlLlxuICogUHJvcHMgdG8gRGVhbiBFZHdhcmRzJyBhZGRFdmVudCBsaWJyYXJ5IGZvciBtYW55IG9mIHRoZSBpZGVhcy5cbiAqL1xualF1ZXJ5LmV2ZW50ID0ge1xuXG5cdGdsb2JhbDoge30sXG5cblx0YWRkOiBmdW5jdGlvbiggZWxlbSwgdHlwZXMsIGhhbmRsZXIsIGRhdGEsIHNlbGVjdG9yICkge1xuXG5cdFx0dmFyIGhhbmRsZU9iakluLCBldmVudEhhbmRsZSwgdG1wLFxuXHRcdFx0ZXZlbnRzLCB0LCBoYW5kbGVPYmosXG5cdFx0XHRzcGVjaWFsLCBoYW5kbGVycywgdHlwZSwgbmFtZXNwYWNlcywgb3JpZ1R5cGUsXG5cdFx0XHRlbGVtRGF0YSA9IGRhdGFQcml2LmdldCggZWxlbSApO1xuXG5cdFx0Ly8gT25seSBhdHRhY2ggZXZlbnRzIHRvIG9iamVjdHMgdGhhdCBhY2NlcHQgZGF0YVxuXHRcdGlmICggIWFjY2VwdERhdGEoIGVsZW0gKSApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBDYWxsZXIgY2FuIHBhc3MgaW4gYW4gb2JqZWN0IG9mIGN1c3RvbSBkYXRhIGluIGxpZXUgb2YgdGhlIGhhbmRsZXJcblx0XHRpZiAoIGhhbmRsZXIuaGFuZGxlciApIHtcblx0XHRcdGhhbmRsZU9iakluID0gaGFuZGxlcjtcblx0XHRcdGhhbmRsZXIgPSBoYW5kbGVPYmpJbi5oYW5kbGVyO1xuXHRcdFx0c2VsZWN0b3IgPSBoYW5kbGVPYmpJbi5zZWxlY3Rvcjtcblx0XHR9XG5cblx0XHQvLyBFbnN1cmUgdGhhdCBpbnZhbGlkIHNlbGVjdG9ycyB0aHJvdyBleGNlcHRpb25zIGF0IGF0dGFjaCB0aW1lXG5cdFx0Ly8gRXZhbHVhdGUgYWdhaW5zdCBkb2N1bWVudEVsZW1lbnQgaW4gY2FzZSBlbGVtIGlzIGEgbm9uLWVsZW1lbnQgbm9kZSAoZS5nLiwgZG9jdW1lbnQpXG5cdFx0aWYgKCBzZWxlY3RvciApIHtcblx0XHRcdGpRdWVyeS5maW5kLm1hdGNoZXNTZWxlY3RvciggZG9jdW1lbnRFbGVtZW50LCBzZWxlY3RvciApO1xuXHRcdH1cblxuXHRcdC8vIE1ha2Ugc3VyZSB0aGF0IHRoZSBoYW5kbGVyIGhhcyBhIHVuaXF1ZSBJRCwgdXNlZCB0byBmaW5kL3JlbW92ZSBpdCBsYXRlclxuXHRcdGlmICggIWhhbmRsZXIuZ3VpZCApIHtcblx0XHRcdGhhbmRsZXIuZ3VpZCA9IGpRdWVyeS5ndWlkKys7XG5cdFx0fVxuXG5cdFx0Ly8gSW5pdCB0aGUgZWxlbWVudCdzIGV2ZW50IHN0cnVjdHVyZSBhbmQgbWFpbiBoYW5kbGVyLCBpZiB0aGlzIGlzIHRoZSBmaXJzdFxuXHRcdGlmICggISggZXZlbnRzID0gZWxlbURhdGEuZXZlbnRzICkgKSB7XG5cdFx0XHRldmVudHMgPSBlbGVtRGF0YS5ldmVudHMgPSBPYmplY3QuY3JlYXRlKCBudWxsICk7XG5cdFx0fVxuXHRcdGlmICggISggZXZlbnRIYW5kbGUgPSBlbGVtRGF0YS5oYW5kbGUgKSApIHtcblx0XHRcdGV2ZW50SGFuZGxlID0gZWxlbURhdGEuaGFuZGxlID0gZnVuY3Rpb24oIGUgKSB7XG5cblx0XHRcdFx0Ly8gRGlzY2FyZCB0aGUgc2Vjb25kIGV2ZW50IG9mIGEgalF1ZXJ5LmV2ZW50LnRyaWdnZXIoKSBhbmRcblx0XHRcdFx0Ly8gd2hlbiBhbiBldmVudCBpcyBjYWxsZWQgYWZ0ZXIgYSBwYWdlIGhhcyB1bmxvYWRlZFxuXHRcdFx0XHRyZXR1cm4gdHlwZW9mIGpRdWVyeSAhPT0gXCJ1bmRlZmluZWRcIiAmJiBqUXVlcnkuZXZlbnQudHJpZ2dlcmVkICE9PSBlLnR5cGUgP1xuXHRcdFx0XHRcdGpRdWVyeS5ldmVudC5kaXNwYXRjaC5hcHBseSggZWxlbSwgYXJndW1lbnRzICkgOiB1bmRlZmluZWQ7XG5cdFx0XHR9O1xuXHRcdH1cblxuXHRcdC8vIEhhbmRsZSBtdWx0aXBsZSBldmVudHMgc2VwYXJhdGVkIGJ5IGEgc3BhY2Vcblx0XHR0eXBlcyA9ICggdHlwZXMgfHwgXCJcIiApLm1hdGNoKCBybm90aHRtbHdoaXRlICkgfHwgWyBcIlwiIF07XG5cdFx0dCA9IHR5cGVzLmxlbmd0aDtcblx0XHR3aGlsZSAoIHQtLSApIHtcblx0XHRcdHRtcCA9IHJ0eXBlbmFtZXNwYWNlLmV4ZWMoIHR5cGVzWyB0IF0gKSB8fCBbXTtcblx0XHRcdHR5cGUgPSBvcmlnVHlwZSA9IHRtcFsgMSBdO1xuXHRcdFx0bmFtZXNwYWNlcyA9ICggdG1wWyAyIF0gfHwgXCJcIiApLnNwbGl0KCBcIi5cIiApLnNvcnQoKTtcblxuXHRcdFx0Ly8gVGhlcmUgKm11c3QqIGJlIGEgdHlwZSwgbm8gYXR0YWNoaW5nIG5hbWVzcGFjZS1vbmx5IGhhbmRsZXJzXG5cdFx0XHRpZiAoICF0eXBlICkge1xuXHRcdFx0XHRjb250aW51ZTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gSWYgZXZlbnQgY2hhbmdlcyBpdHMgdHlwZSwgdXNlIHRoZSBzcGVjaWFsIGV2ZW50IGhhbmRsZXJzIGZvciB0aGUgY2hhbmdlZCB0eXBlXG5cdFx0XHRzcGVjaWFsID0galF1ZXJ5LmV2ZW50LnNwZWNpYWxbIHR5cGUgXSB8fCB7fTtcblxuXHRcdFx0Ly8gSWYgc2VsZWN0b3IgZGVmaW5lZCwgZGV0ZXJtaW5lIHNwZWNpYWwgZXZlbnQgYXBpIHR5cGUsIG90aGVyd2lzZSBnaXZlbiB0eXBlXG5cdFx0XHR0eXBlID0gKCBzZWxlY3RvciA/IHNwZWNpYWwuZGVsZWdhdGVUeXBlIDogc3BlY2lhbC5iaW5kVHlwZSApIHx8IHR5cGU7XG5cblx0XHRcdC8vIFVwZGF0ZSBzcGVjaWFsIGJhc2VkIG9uIG5ld2x5IHJlc2V0IHR5cGVcblx0XHRcdHNwZWNpYWwgPSBqUXVlcnkuZXZlbnQuc3BlY2lhbFsgdHlwZSBdIHx8IHt9O1xuXG5cdFx0XHQvLyBoYW5kbGVPYmogaXMgcGFzc2VkIHRvIGFsbCBldmVudCBoYW5kbGVyc1xuXHRcdFx0aGFuZGxlT2JqID0galF1ZXJ5LmV4dGVuZCgge1xuXHRcdFx0XHR0eXBlOiB0eXBlLFxuXHRcdFx0XHRvcmlnVHlwZTogb3JpZ1R5cGUsXG5cdFx0XHRcdGRhdGE6IGRhdGEsXG5cdFx0XHRcdGhhbmRsZXI6IGhhbmRsZXIsXG5cdFx0XHRcdGd1aWQ6IGhhbmRsZXIuZ3VpZCxcblx0XHRcdFx0c2VsZWN0b3I6IHNlbGVjdG9yLFxuXHRcdFx0XHRuZWVkc0NvbnRleHQ6IHNlbGVjdG9yICYmIGpRdWVyeS5leHByLm1hdGNoLm5lZWRzQ29udGV4dC50ZXN0KCBzZWxlY3RvciApLFxuXHRcdFx0XHRuYW1lc3BhY2U6IG5hbWVzcGFjZXMuam9pbiggXCIuXCIgKVxuXHRcdFx0fSwgaGFuZGxlT2JqSW4gKTtcblxuXHRcdFx0Ly8gSW5pdCB0aGUgZXZlbnQgaGFuZGxlciBxdWV1ZSBpZiB3ZSdyZSB0aGUgZmlyc3Rcblx0XHRcdGlmICggISggaGFuZGxlcnMgPSBldmVudHNbIHR5cGUgXSApICkge1xuXHRcdFx0XHRoYW5kbGVycyA9IGV2ZW50c1sgdHlwZSBdID0gW107XG5cdFx0XHRcdGhhbmRsZXJzLmRlbGVnYXRlQ291bnQgPSAwO1xuXG5cdFx0XHRcdC8vIE9ubHkgdXNlIGFkZEV2ZW50TGlzdGVuZXIgaWYgdGhlIHNwZWNpYWwgZXZlbnRzIGhhbmRsZXIgcmV0dXJucyBmYWxzZVxuXHRcdFx0XHRpZiAoICFzcGVjaWFsLnNldHVwIHx8XG5cdFx0XHRcdFx0c3BlY2lhbC5zZXR1cC5jYWxsKCBlbGVtLCBkYXRhLCBuYW1lc3BhY2VzLCBldmVudEhhbmRsZSApID09PSBmYWxzZSApIHtcblxuXHRcdFx0XHRcdGlmICggZWxlbS5hZGRFdmVudExpc3RlbmVyICkge1xuXHRcdFx0XHRcdFx0ZWxlbS5hZGRFdmVudExpc3RlbmVyKCB0eXBlLCBldmVudEhhbmRsZSApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIHNwZWNpYWwuYWRkICkge1xuXHRcdFx0XHRzcGVjaWFsLmFkZC5jYWxsKCBlbGVtLCBoYW5kbGVPYmogKTtcblxuXHRcdFx0XHRpZiAoICFoYW5kbGVPYmouaGFuZGxlci5ndWlkICkge1xuXHRcdFx0XHRcdGhhbmRsZU9iai5oYW5kbGVyLmd1aWQgPSBoYW5kbGVyLmd1aWQ7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Ly8gQWRkIHRvIHRoZSBlbGVtZW50J3MgaGFuZGxlciBsaXN0LCBkZWxlZ2F0ZXMgaW4gZnJvbnRcblx0XHRcdGlmICggc2VsZWN0b3IgKSB7XG5cdFx0XHRcdGhhbmRsZXJzLnNwbGljZSggaGFuZGxlcnMuZGVsZWdhdGVDb3VudCsrLCAwLCBoYW5kbGVPYmogKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGhhbmRsZXJzLnB1c2goIGhhbmRsZU9iaiApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBLZWVwIHRyYWNrIG9mIHdoaWNoIGV2ZW50cyBoYXZlIGV2ZXIgYmVlbiB1c2VkLCBmb3IgZXZlbnQgb3B0aW1pemF0aW9uXG5cdFx0XHRqUXVlcnkuZXZlbnQuZ2xvYmFsWyB0eXBlIF0gPSB0cnVlO1xuXHRcdH1cblxuXHR9LFxuXG5cdC8vIERldGFjaCBhbiBldmVudCBvciBzZXQgb2YgZXZlbnRzIGZyb20gYW4gZWxlbWVudFxuXHRyZW1vdmU6IGZ1bmN0aW9uKCBlbGVtLCB0eXBlcywgaGFuZGxlciwgc2VsZWN0b3IsIG1hcHBlZFR5cGVzICkge1xuXG5cdFx0dmFyIGosIG9yaWdDb3VudCwgdG1wLFxuXHRcdFx0ZXZlbnRzLCB0LCBoYW5kbGVPYmosXG5cdFx0XHRzcGVjaWFsLCBoYW5kbGVycywgdHlwZSwgbmFtZXNwYWNlcywgb3JpZ1R5cGUsXG5cdFx0XHRlbGVtRGF0YSA9IGRhdGFQcml2Lmhhc0RhdGEoIGVsZW0gKSAmJiBkYXRhUHJpdi5nZXQoIGVsZW0gKTtcblxuXHRcdGlmICggIWVsZW1EYXRhIHx8ICEoIGV2ZW50cyA9IGVsZW1EYXRhLmV2ZW50cyApICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIE9uY2UgZm9yIGVhY2ggdHlwZS5uYW1lc3BhY2UgaW4gdHlwZXM7IHR5cGUgbWF5IGJlIG9taXR0ZWRcblx0XHR0eXBlcyA9ICggdHlwZXMgfHwgXCJcIiApLm1hdGNoKCBybm90aHRtbHdoaXRlICkgfHwgWyBcIlwiIF07XG5cdFx0dCA9IHR5cGVzLmxlbmd0aDtcblx0XHR3aGlsZSAoIHQtLSApIHtcblx0XHRcdHRtcCA9IHJ0eXBlbmFtZXNwYWNlLmV4ZWMoIHR5cGVzWyB0IF0gKSB8fCBbXTtcblx0XHRcdHR5cGUgPSBvcmlnVHlwZSA9IHRtcFsgMSBdO1xuXHRcdFx0bmFtZXNwYWNlcyA9ICggdG1wWyAyIF0gfHwgXCJcIiApLnNwbGl0KCBcIi5cIiApLnNvcnQoKTtcblxuXHRcdFx0Ly8gVW5iaW5kIGFsbCBldmVudHMgKG9uIHRoaXMgbmFtZXNwYWNlLCBpZiBwcm92aWRlZCkgZm9yIHRoZSBlbGVtZW50XG5cdFx0XHRpZiAoICF0eXBlICkge1xuXHRcdFx0XHRmb3IgKCB0eXBlIGluIGV2ZW50cyApIHtcblx0XHRcdFx0XHRqUXVlcnkuZXZlbnQucmVtb3ZlKCBlbGVtLCB0eXBlICsgdHlwZXNbIHQgXSwgaGFuZGxlciwgc2VsZWN0b3IsIHRydWUgKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRjb250aW51ZTtcblx0XHRcdH1cblxuXHRcdFx0c3BlY2lhbCA9IGpRdWVyeS5ldmVudC5zcGVjaWFsWyB0eXBlIF0gfHwge307XG5cdFx0XHR0eXBlID0gKCBzZWxlY3RvciA/IHNwZWNpYWwuZGVsZWdhdGVUeXBlIDogc3BlY2lhbC5iaW5kVHlwZSApIHx8IHR5cGU7XG5cdFx0XHRoYW5kbGVycyA9IGV2ZW50c1sgdHlwZSBdIHx8IFtdO1xuXHRcdFx0dG1wID0gdG1wWyAyIF0gJiZcblx0XHRcdFx0bmV3IFJlZ0V4cCggXCIoXnxcXFxcLilcIiArIG5hbWVzcGFjZXMuam9pbiggXCJcXFxcLig/Oi4qXFxcXC58KVwiICkgKyBcIihcXFxcLnwkKVwiICk7XG5cblx0XHRcdC8vIFJlbW92ZSBtYXRjaGluZyBldmVudHNcblx0XHRcdG9yaWdDb3VudCA9IGogPSBoYW5kbGVycy5sZW5ndGg7XG5cdFx0XHR3aGlsZSAoIGotLSApIHtcblx0XHRcdFx0aGFuZGxlT2JqID0gaGFuZGxlcnNbIGogXTtcblxuXHRcdFx0XHRpZiAoICggbWFwcGVkVHlwZXMgfHwgb3JpZ1R5cGUgPT09IGhhbmRsZU9iai5vcmlnVHlwZSApICYmXG5cdFx0XHRcdFx0KCAhaGFuZGxlciB8fCBoYW5kbGVyLmd1aWQgPT09IGhhbmRsZU9iai5ndWlkICkgJiZcblx0XHRcdFx0XHQoICF0bXAgfHwgdG1wLnRlc3QoIGhhbmRsZU9iai5uYW1lc3BhY2UgKSApICYmXG5cdFx0XHRcdFx0KCAhc2VsZWN0b3IgfHwgc2VsZWN0b3IgPT09IGhhbmRsZU9iai5zZWxlY3RvciB8fFxuXHRcdFx0XHRcdFx0c2VsZWN0b3IgPT09IFwiKipcIiAmJiBoYW5kbGVPYmouc2VsZWN0b3IgKSApIHtcblx0XHRcdFx0XHRoYW5kbGVycy5zcGxpY2UoIGosIDEgKTtcblxuXHRcdFx0XHRcdGlmICggaGFuZGxlT2JqLnNlbGVjdG9yICkge1xuXHRcdFx0XHRcdFx0aGFuZGxlcnMuZGVsZWdhdGVDb3VudC0tO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRpZiAoIHNwZWNpYWwucmVtb3ZlICkge1xuXHRcdFx0XHRcdFx0c3BlY2lhbC5yZW1vdmUuY2FsbCggZWxlbSwgaGFuZGxlT2JqICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIFJlbW92ZSBnZW5lcmljIGV2ZW50IGhhbmRsZXIgaWYgd2UgcmVtb3ZlZCBzb21ldGhpbmcgYW5kIG5vIG1vcmUgaGFuZGxlcnMgZXhpc3Rcblx0XHRcdC8vIChhdm9pZHMgcG90ZW50aWFsIGZvciBlbmRsZXNzIHJlY3Vyc2lvbiBkdXJpbmcgcmVtb3ZhbCBvZiBzcGVjaWFsIGV2ZW50IGhhbmRsZXJzKVxuXHRcdFx0aWYgKCBvcmlnQ291bnQgJiYgIWhhbmRsZXJzLmxlbmd0aCApIHtcblx0XHRcdFx0aWYgKCAhc3BlY2lhbC50ZWFyZG93biB8fFxuXHRcdFx0XHRcdHNwZWNpYWwudGVhcmRvd24uY2FsbCggZWxlbSwgbmFtZXNwYWNlcywgZWxlbURhdGEuaGFuZGxlICkgPT09IGZhbHNlICkge1xuXG5cdFx0XHRcdFx0alF1ZXJ5LnJlbW92ZUV2ZW50KCBlbGVtLCB0eXBlLCBlbGVtRGF0YS5oYW5kbGUgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGRlbGV0ZSBldmVudHNbIHR5cGUgXTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBSZW1vdmUgZGF0YSBhbmQgdGhlIGV4cGFuZG8gaWYgaXQncyBubyBsb25nZXIgdXNlZFxuXHRcdGlmICggalF1ZXJ5LmlzRW1wdHlPYmplY3QoIGV2ZW50cyApICkge1xuXHRcdFx0ZGF0YVByaXYucmVtb3ZlKCBlbGVtLCBcImhhbmRsZSBldmVudHNcIiApO1xuXHRcdH1cblx0fSxcblxuXHRkaXNwYXRjaDogZnVuY3Rpb24oIG5hdGl2ZUV2ZW50ICkge1xuXG5cdFx0dmFyIGksIGosIHJldCwgbWF0Y2hlZCwgaGFuZGxlT2JqLCBoYW5kbGVyUXVldWUsXG5cdFx0XHRhcmdzID0gbmV3IEFycmF5KCBhcmd1bWVudHMubGVuZ3RoICksXG5cblx0XHRcdC8vIE1ha2UgYSB3cml0YWJsZSBqUXVlcnkuRXZlbnQgZnJvbSB0aGUgbmF0aXZlIGV2ZW50IG9iamVjdFxuXHRcdFx0ZXZlbnQgPSBqUXVlcnkuZXZlbnQuZml4KCBuYXRpdmVFdmVudCApLFxuXG5cdFx0XHRoYW5kbGVycyA9IChcblx0XHRcdFx0ZGF0YVByaXYuZ2V0KCB0aGlzLCBcImV2ZW50c1wiICkgfHwgT2JqZWN0LmNyZWF0ZSggbnVsbCApXG5cdFx0XHQpWyBldmVudC50eXBlIF0gfHwgW10sXG5cdFx0XHRzcGVjaWFsID0galF1ZXJ5LmV2ZW50LnNwZWNpYWxbIGV2ZW50LnR5cGUgXSB8fCB7fTtcblxuXHRcdC8vIFVzZSB0aGUgZml4LWVkIGpRdWVyeS5FdmVudCByYXRoZXIgdGhhbiB0aGUgKHJlYWQtb25seSkgbmF0aXZlIGV2ZW50XG5cdFx0YXJnc1sgMCBdID0gZXZlbnQ7XG5cblx0XHRmb3IgKCBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKyApIHtcblx0XHRcdGFyZ3NbIGkgXSA9IGFyZ3VtZW50c1sgaSBdO1xuXHRcdH1cblxuXHRcdGV2ZW50LmRlbGVnYXRlVGFyZ2V0ID0gdGhpcztcblxuXHRcdC8vIENhbGwgdGhlIHByZURpc3BhdGNoIGhvb2sgZm9yIHRoZSBtYXBwZWQgdHlwZSwgYW5kIGxldCBpdCBiYWlsIGlmIGRlc2lyZWRcblx0XHRpZiAoIHNwZWNpYWwucHJlRGlzcGF0Y2ggJiYgc3BlY2lhbC5wcmVEaXNwYXRjaC5jYWxsKCB0aGlzLCBldmVudCApID09PSBmYWxzZSApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBEZXRlcm1pbmUgaGFuZGxlcnNcblx0XHRoYW5kbGVyUXVldWUgPSBqUXVlcnkuZXZlbnQuaGFuZGxlcnMuY2FsbCggdGhpcywgZXZlbnQsIGhhbmRsZXJzICk7XG5cblx0XHQvLyBSdW4gZGVsZWdhdGVzIGZpcnN0OyB0aGV5IG1heSB3YW50IHRvIHN0b3AgcHJvcGFnYXRpb24gYmVuZWF0aCB1c1xuXHRcdGkgPSAwO1xuXHRcdHdoaWxlICggKCBtYXRjaGVkID0gaGFuZGxlclF1ZXVlWyBpKysgXSApICYmICFldmVudC5pc1Byb3BhZ2F0aW9uU3RvcHBlZCgpICkge1xuXHRcdFx0ZXZlbnQuY3VycmVudFRhcmdldCA9IG1hdGNoZWQuZWxlbTtcblxuXHRcdFx0aiA9IDA7XG5cdFx0XHR3aGlsZSAoICggaGFuZGxlT2JqID0gbWF0Y2hlZC5oYW5kbGVyc1sgaisrIF0gKSAmJlxuXHRcdFx0XHQhZXZlbnQuaXNJbW1lZGlhdGVQcm9wYWdhdGlvblN0b3BwZWQoKSApIHtcblxuXHRcdFx0XHQvLyBJZiB0aGUgZXZlbnQgaXMgbmFtZXNwYWNlZCwgdGhlbiBlYWNoIGhhbmRsZXIgaXMgb25seSBpbnZva2VkIGlmIGl0IGlzXG5cdFx0XHRcdC8vIHNwZWNpYWxseSB1bml2ZXJzYWwgb3IgaXRzIG5hbWVzcGFjZXMgYXJlIGEgc3VwZXJzZXQgb2YgdGhlIGV2ZW50J3MuXG5cdFx0XHRcdGlmICggIWV2ZW50LnJuYW1lc3BhY2UgfHwgaGFuZGxlT2JqLm5hbWVzcGFjZSA9PT0gZmFsc2UgfHxcblx0XHRcdFx0XHRldmVudC5ybmFtZXNwYWNlLnRlc3QoIGhhbmRsZU9iai5uYW1lc3BhY2UgKSApIHtcblxuXHRcdFx0XHRcdGV2ZW50LmhhbmRsZU9iaiA9IGhhbmRsZU9iajtcblx0XHRcdFx0XHRldmVudC5kYXRhID0gaGFuZGxlT2JqLmRhdGE7XG5cblx0XHRcdFx0XHRyZXQgPSAoICggalF1ZXJ5LmV2ZW50LnNwZWNpYWxbIGhhbmRsZU9iai5vcmlnVHlwZSBdIHx8IHt9ICkuaGFuZGxlIHx8XG5cdFx0XHRcdFx0XHRoYW5kbGVPYmouaGFuZGxlciApLmFwcGx5KCBtYXRjaGVkLmVsZW0sIGFyZ3MgKTtcblxuXHRcdFx0XHRcdGlmICggcmV0ICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdFx0XHRpZiAoICggZXZlbnQucmVzdWx0ID0gcmV0ICkgPT09IGZhbHNlICkge1xuXHRcdFx0XHRcdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0XHRcdFx0XHRldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBDYWxsIHRoZSBwb3N0RGlzcGF0Y2ggaG9vayBmb3IgdGhlIG1hcHBlZCB0eXBlXG5cdFx0aWYgKCBzcGVjaWFsLnBvc3REaXNwYXRjaCApIHtcblx0XHRcdHNwZWNpYWwucG9zdERpc3BhdGNoLmNhbGwoIHRoaXMsIGV2ZW50ICk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGV2ZW50LnJlc3VsdDtcblx0fSxcblxuXHRoYW5kbGVyczogZnVuY3Rpb24oIGV2ZW50LCBoYW5kbGVycyApIHtcblx0XHR2YXIgaSwgaGFuZGxlT2JqLCBzZWwsIG1hdGNoZWRIYW5kbGVycywgbWF0Y2hlZFNlbGVjdG9ycyxcblx0XHRcdGhhbmRsZXJRdWV1ZSA9IFtdLFxuXHRcdFx0ZGVsZWdhdGVDb3VudCA9IGhhbmRsZXJzLmRlbGVnYXRlQ291bnQsXG5cdFx0XHRjdXIgPSBldmVudC50YXJnZXQ7XG5cblx0XHQvLyBGaW5kIGRlbGVnYXRlIGhhbmRsZXJzXG5cdFx0aWYgKCBkZWxlZ2F0ZUNvdW50ICYmXG5cblx0XHRcdC8vIFN1cHBvcnQ6IElFIDw9OVxuXHRcdFx0Ly8gQmxhY2staG9sZSBTVkcgPHVzZT4gaW5zdGFuY2UgdHJlZXMgKHRyYWMtMTMxODApXG5cdFx0XHRjdXIubm9kZVR5cGUgJiZcblxuXHRcdFx0Ly8gU3VwcG9ydDogRmlyZWZveCA8PTQyXG5cdFx0XHQvLyBTdXBwcmVzcyBzcGVjLXZpb2xhdGluZyBjbGlja3MgaW5kaWNhdGluZyBhIG5vbi1wcmltYXJ5IHBvaW50ZXIgYnV0dG9uICh0cmFjLTM4NjEpXG5cdFx0XHQvLyBodHRwczovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTMtRXZlbnRzLyNldmVudC10eXBlLWNsaWNrXG5cdFx0XHQvLyBTdXBwb3J0OiBJRSAxMSBvbmx5XG5cdFx0XHQvLyAuLi5idXQgbm90IGFycm93IGtleSBcImNsaWNrc1wiIG9mIHJhZGlvIGlucHV0cywgd2hpY2ggY2FuIGhhdmUgYGJ1dHRvbmAgLTEgKGdoLTIzNDMpXG5cdFx0XHQhKCBldmVudC50eXBlID09PSBcImNsaWNrXCIgJiYgZXZlbnQuYnV0dG9uID49IDEgKSApIHtcblxuXHRcdFx0Zm9yICggOyBjdXIgIT09IHRoaXM7IGN1ciA9IGN1ci5wYXJlbnROb2RlIHx8IHRoaXMgKSB7XG5cblx0XHRcdFx0Ly8gRG9uJ3QgY2hlY2sgbm9uLWVsZW1lbnRzICgjMTMyMDgpXG5cdFx0XHRcdC8vIERvbid0IHByb2Nlc3MgY2xpY2tzIG9uIGRpc2FibGVkIGVsZW1lbnRzICgjNjkxMSwgIzgxNjUsICMxMTM4MiwgIzExNzY0KVxuXHRcdFx0XHRpZiAoIGN1ci5ub2RlVHlwZSA9PT0gMSAmJiAhKCBldmVudC50eXBlID09PSBcImNsaWNrXCIgJiYgY3VyLmRpc2FibGVkID09PSB0cnVlICkgKSB7XG5cdFx0XHRcdFx0bWF0Y2hlZEhhbmRsZXJzID0gW107XG5cdFx0XHRcdFx0bWF0Y2hlZFNlbGVjdG9ycyA9IHt9O1xuXHRcdFx0XHRcdGZvciAoIGkgPSAwOyBpIDwgZGVsZWdhdGVDb3VudDsgaSsrICkge1xuXHRcdFx0XHRcdFx0aGFuZGxlT2JqID0gaGFuZGxlcnNbIGkgXTtcblxuXHRcdFx0XHRcdFx0Ly8gRG9uJ3QgY29uZmxpY3Qgd2l0aCBPYmplY3QucHJvdG90eXBlIHByb3BlcnRpZXMgKCMxMzIwMylcblx0XHRcdFx0XHRcdHNlbCA9IGhhbmRsZU9iai5zZWxlY3RvciArIFwiIFwiO1xuXG5cdFx0XHRcdFx0XHRpZiAoIG1hdGNoZWRTZWxlY3RvcnNbIHNlbCBdID09PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdFx0XHRcdG1hdGNoZWRTZWxlY3RvcnNbIHNlbCBdID0gaGFuZGxlT2JqLm5lZWRzQ29udGV4dCA/XG5cdFx0XHRcdFx0XHRcdFx0alF1ZXJ5KCBzZWwsIHRoaXMgKS5pbmRleCggY3VyICkgPiAtMSA6XG5cdFx0XHRcdFx0XHRcdFx0alF1ZXJ5LmZpbmQoIHNlbCwgdGhpcywgbnVsbCwgWyBjdXIgXSApLmxlbmd0aDtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdGlmICggbWF0Y2hlZFNlbGVjdG9yc1sgc2VsIF0gKSB7XG5cdFx0XHRcdFx0XHRcdG1hdGNoZWRIYW5kbGVycy5wdXNoKCBoYW5kbGVPYmogKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0aWYgKCBtYXRjaGVkSGFuZGxlcnMubGVuZ3RoICkge1xuXHRcdFx0XHRcdFx0aGFuZGxlclF1ZXVlLnB1c2goIHsgZWxlbTogY3VyLCBoYW5kbGVyczogbWF0Y2hlZEhhbmRsZXJzIH0gKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBBZGQgdGhlIHJlbWFpbmluZyAoZGlyZWN0bHktYm91bmQpIGhhbmRsZXJzXG5cdFx0Y3VyID0gdGhpcztcblx0XHRpZiAoIGRlbGVnYXRlQ291bnQgPCBoYW5kbGVycy5sZW5ndGggKSB7XG5cdFx0XHRoYW5kbGVyUXVldWUucHVzaCggeyBlbGVtOiBjdXIsIGhhbmRsZXJzOiBoYW5kbGVycy5zbGljZSggZGVsZWdhdGVDb3VudCApIH0gKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gaGFuZGxlclF1ZXVlO1xuXHR9LFxuXG5cdGFkZFByb3A6IGZ1bmN0aW9uKCBuYW1lLCBob29rICkge1xuXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eSggalF1ZXJ5LkV2ZW50LnByb3RvdHlwZSwgbmFtZSwge1xuXHRcdFx0ZW51bWVyYWJsZTogdHJ1ZSxcblx0XHRcdGNvbmZpZ3VyYWJsZTogdHJ1ZSxcblxuXHRcdFx0Z2V0OiBpc0Z1bmN0aW9uKCBob29rICkgP1xuXHRcdFx0XHRmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRpZiAoIHRoaXMub3JpZ2luYWxFdmVudCApIHtcblx0XHRcdFx0XHRcdHJldHVybiBob29rKCB0aGlzLm9yaWdpbmFsRXZlbnQgKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0gOlxuXHRcdFx0XHRmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRpZiAoIHRoaXMub3JpZ2luYWxFdmVudCApIHtcblx0XHRcdFx0XHRcdHJldHVybiB0aGlzLm9yaWdpbmFsRXZlbnRbIG5hbWUgXTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0sXG5cblx0XHRcdHNldDogZnVuY3Rpb24oIHZhbHVlICkge1xuXHRcdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoIHRoaXMsIG5hbWUsIHtcblx0XHRcdFx0XHRlbnVtZXJhYmxlOiB0cnVlLFxuXHRcdFx0XHRcdGNvbmZpZ3VyYWJsZTogdHJ1ZSxcblx0XHRcdFx0XHR3cml0YWJsZTogdHJ1ZSxcblx0XHRcdFx0XHR2YWx1ZTogdmFsdWVcblx0XHRcdFx0fSApO1xuXHRcdFx0fVxuXHRcdH0gKTtcblx0fSxcblxuXHRmaXg6IGZ1bmN0aW9uKCBvcmlnaW5hbEV2ZW50ICkge1xuXHRcdHJldHVybiBvcmlnaW5hbEV2ZW50WyBqUXVlcnkuZXhwYW5kbyBdID9cblx0XHRcdG9yaWdpbmFsRXZlbnQgOlxuXHRcdFx0bmV3IGpRdWVyeS5FdmVudCggb3JpZ2luYWxFdmVudCApO1xuXHR9LFxuXG5cdHNwZWNpYWw6IHtcblx0XHRsb2FkOiB7XG5cblx0XHRcdC8vIFByZXZlbnQgdHJpZ2dlcmVkIGltYWdlLmxvYWQgZXZlbnRzIGZyb20gYnViYmxpbmcgdG8gd2luZG93LmxvYWRcblx0XHRcdG5vQnViYmxlOiB0cnVlXG5cdFx0fSxcblx0XHRjbGljazoge1xuXG5cdFx0XHQvLyBVdGlsaXplIG5hdGl2ZSBldmVudCB0byBlbnN1cmUgY29ycmVjdCBzdGF0ZSBmb3IgY2hlY2thYmxlIGlucHV0c1xuXHRcdFx0c2V0dXA6IGZ1bmN0aW9uKCBkYXRhICkge1xuXG5cdFx0XHRcdC8vIEZvciBtdXR1YWwgY29tcHJlc3NpYmlsaXR5IHdpdGggX2RlZmF1bHQsIHJlcGxhY2UgYHRoaXNgIGFjY2VzcyB3aXRoIGEgbG9jYWwgdmFyLlxuXHRcdFx0XHQvLyBgfHwgZGF0YWAgaXMgZGVhZCBjb2RlIG1lYW50IG9ubHkgdG8gcHJlc2VydmUgdGhlIHZhcmlhYmxlIHRocm91Z2ggbWluaWZpY2F0aW9uLlxuXHRcdFx0XHR2YXIgZWwgPSB0aGlzIHx8IGRhdGE7XG5cblx0XHRcdFx0Ly8gQ2xhaW0gdGhlIGZpcnN0IGhhbmRsZXJcblx0XHRcdFx0aWYgKCByY2hlY2thYmxlVHlwZS50ZXN0KCBlbC50eXBlICkgJiZcblx0XHRcdFx0XHRlbC5jbGljayAmJiBub2RlTmFtZSggZWwsIFwiaW5wdXRcIiApICkge1xuXG5cdFx0XHRcdFx0Ly8gZGF0YVByaXYuc2V0KCBlbCwgXCJjbGlja1wiLCAuLi4gKVxuXHRcdFx0XHRcdGxldmVyYWdlTmF0aXZlKCBlbCwgXCJjbGlja1wiLCByZXR1cm5UcnVlICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBSZXR1cm4gZmFsc2UgdG8gYWxsb3cgbm9ybWFsIHByb2Nlc3NpbmcgaW4gdGhlIGNhbGxlclxuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHR9LFxuXHRcdFx0dHJpZ2dlcjogZnVuY3Rpb24oIGRhdGEgKSB7XG5cblx0XHRcdFx0Ly8gRm9yIG11dHVhbCBjb21wcmVzc2liaWxpdHkgd2l0aCBfZGVmYXVsdCwgcmVwbGFjZSBgdGhpc2AgYWNjZXNzIHdpdGggYSBsb2NhbCB2YXIuXG5cdFx0XHRcdC8vIGB8fCBkYXRhYCBpcyBkZWFkIGNvZGUgbWVhbnQgb25seSB0byBwcmVzZXJ2ZSB0aGUgdmFyaWFibGUgdGhyb3VnaCBtaW5pZmljYXRpb24uXG5cdFx0XHRcdHZhciBlbCA9IHRoaXMgfHwgZGF0YTtcblxuXHRcdFx0XHQvLyBGb3JjZSBzZXR1cCBiZWZvcmUgdHJpZ2dlcmluZyBhIGNsaWNrXG5cdFx0XHRcdGlmICggcmNoZWNrYWJsZVR5cGUudGVzdCggZWwudHlwZSApICYmXG5cdFx0XHRcdFx0ZWwuY2xpY2sgJiYgbm9kZU5hbWUoIGVsLCBcImlucHV0XCIgKSApIHtcblxuXHRcdFx0XHRcdGxldmVyYWdlTmF0aXZlKCBlbCwgXCJjbGlja1wiICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBSZXR1cm4gbm9uLWZhbHNlIHRvIGFsbG93IG5vcm1hbCBldmVudC1wYXRoIHByb3BhZ2F0aW9uXG5cdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0fSxcblxuXHRcdFx0Ly8gRm9yIGNyb3NzLWJyb3dzZXIgY29uc2lzdGVuY3ksIHN1cHByZXNzIG5hdGl2ZSAuY2xpY2soKSBvbiBsaW5rc1xuXHRcdFx0Ly8gQWxzbyBwcmV2ZW50IGl0IGlmIHdlJ3JlIGN1cnJlbnRseSBpbnNpZGUgYSBsZXZlcmFnZWQgbmF0aXZlLWV2ZW50IHN0YWNrXG5cdFx0XHRfZGVmYXVsdDogZnVuY3Rpb24oIGV2ZW50ICkge1xuXHRcdFx0XHR2YXIgdGFyZ2V0ID0gZXZlbnQudGFyZ2V0O1xuXHRcdFx0XHRyZXR1cm4gcmNoZWNrYWJsZVR5cGUudGVzdCggdGFyZ2V0LnR5cGUgKSAmJlxuXHRcdFx0XHRcdHRhcmdldC5jbGljayAmJiBub2RlTmFtZSggdGFyZ2V0LCBcImlucHV0XCIgKSAmJlxuXHRcdFx0XHRcdGRhdGFQcml2LmdldCggdGFyZ2V0LCBcImNsaWNrXCIgKSB8fFxuXHRcdFx0XHRcdG5vZGVOYW1lKCB0YXJnZXQsIFwiYVwiICk7XG5cdFx0XHR9XG5cdFx0fSxcblxuXHRcdGJlZm9yZXVubG9hZDoge1xuXHRcdFx0cG9zdERpc3BhdGNoOiBmdW5jdGlvbiggZXZlbnQgKSB7XG5cblx0XHRcdFx0Ly8gU3VwcG9ydDogRmlyZWZveCAyMCtcblx0XHRcdFx0Ly8gRmlyZWZveCBkb2Vzbid0IGFsZXJ0IGlmIHRoZSByZXR1cm5WYWx1ZSBmaWVsZCBpcyBub3Qgc2V0LlxuXHRcdFx0XHRpZiAoIGV2ZW50LnJlc3VsdCAhPT0gdW5kZWZpbmVkICYmIGV2ZW50Lm9yaWdpbmFsRXZlbnQgKSB7XG5cdFx0XHRcdFx0ZXZlbnQub3JpZ2luYWxFdmVudC5yZXR1cm5WYWx1ZSA9IGV2ZW50LnJlc3VsdDtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxufTtcblxuLy8gRW5zdXJlIHRoZSBwcmVzZW5jZSBvZiBhbiBldmVudCBsaXN0ZW5lciB0aGF0IGhhbmRsZXMgbWFudWFsbHktdHJpZ2dlcmVkXG4vLyBzeW50aGV0aWMgZXZlbnRzIGJ5IGludGVycnVwdGluZyBwcm9ncmVzcyB1bnRpbCByZWludm9rZWQgaW4gcmVzcG9uc2UgdG9cbi8vICpuYXRpdmUqIGV2ZW50cyB0aGF0IGl0IGZpcmVzIGRpcmVjdGx5LCBlbnN1cmluZyB0aGF0IHN0YXRlIGNoYW5nZXMgaGF2ZVxuLy8gYWxyZWFkeSBvY2N1cnJlZCBiZWZvcmUgb3RoZXIgbGlzdGVuZXJzIGFyZSBpbnZva2VkLlxuZnVuY3Rpb24gbGV2ZXJhZ2VOYXRpdmUoIGVsLCB0eXBlLCBleHBlY3RTeW5jICkge1xuXG5cdC8vIE1pc3NpbmcgZXhwZWN0U3luYyBpbmRpY2F0ZXMgYSB0cmlnZ2VyIGNhbGwsIHdoaWNoIG11c3QgZm9yY2Ugc2V0dXAgdGhyb3VnaCBqUXVlcnkuZXZlbnQuYWRkXG5cdGlmICggIWV4cGVjdFN5bmMgKSB7XG5cdFx0aWYgKCBkYXRhUHJpdi5nZXQoIGVsLCB0eXBlICkgPT09IHVuZGVmaW5lZCApIHtcblx0XHRcdGpRdWVyeS5ldmVudC5hZGQoIGVsLCB0eXBlLCByZXR1cm5UcnVlICk7XG5cdFx0fVxuXHRcdHJldHVybjtcblx0fVxuXG5cdC8vIFJlZ2lzdGVyIHRoZSBjb250cm9sbGVyIGFzIGEgc3BlY2lhbCB1bml2ZXJzYWwgaGFuZGxlciBmb3IgYWxsIGV2ZW50IG5hbWVzcGFjZXNcblx0ZGF0YVByaXYuc2V0KCBlbCwgdHlwZSwgZmFsc2UgKTtcblx0alF1ZXJ5LmV2ZW50LmFkZCggZWwsIHR5cGUsIHtcblx0XHRuYW1lc3BhY2U6IGZhbHNlLFxuXHRcdGhhbmRsZXI6IGZ1bmN0aW9uKCBldmVudCApIHtcblx0XHRcdHZhciBub3RBc3luYywgcmVzdWx0LFxuXHRcdFx0XHRzYXZlZCA9IGRhdGFQcml2LmdldCggdGhpcywgdHlwZSApO1xuXG5cdFx0XHRpZiAoICggZXZlbnQuaXNUcmlnZ2VyICYgMSApICYmIHRoaXNbIHR5cGUgXSApIHtcblxuXHRcdFx0XHQvLyBJbnRlcnJ1cHQgcHJvY2Vzc2luZyBvZiB0aGUgb3V0ZXIgc3ludGhldGljIC50cmlnZ2VyKCllZCBldmVudFxuXHRcdFx0XHQvLyBTYXZlZCBkYXRhIHNob3VsZCBiZSBmYWxzZSBpbiBzdWNoIGNhc2VzLCBidXQgbWlnaHQgYmUgYSBsZWZ0b3ZlciBjYXB0dXJlIG9iamVjdFxuXHRcdFx0XHQvLyBmcm9tIGFuIGFzeW5jIG5hdGl2ZSBoYW5kbGVyIChnaC00MzUwKVxuXHRcdFx0XHRpZiAoICFzYXZlZC5sZW5ndGggKSB7XG5cblx0XHRcdFx0XHQvLyBTdG9yZSBhcmd1bWVudHMgZm9yIHVzZSB3aGVuIGhhbmRsaW5nIHRoZSBpbm5lciBuYXRpdmUgZXZlbnRcblx0XHRcdFx0XHQvLyBUaGVyZSB3aWxsIGFsd2F5cyBiZSBhdCBsZWFzdCBvbmUgYXJndW1lbnQgKGFuIGV2ZW50IG9iamVjdCksIHNvIHRoaXMgYXJyYXlcblx0XHRcdFx0XHQvLyB3aWxsIG5vdCBiZSBjb25mdXNlZCB3aXRoIGEgbGVmdG92ZXIgY2FwdHVyZSBvYmplY3QuXG5cdFx0XHRcdFx0c2F2ZWQgPSBzbGljZS5jYWxsKCBhcmd1bWVudHMgKTtcblx0XHRcdFx0XHRkYXRhUHJpdi5zZXQoIHRoaXMsIHR5cGUsIHNhdmVkICk7XG5cblx0XHRcdFx0XHQvLyBUcmlnZ2VyIHRoZSBuYXRpdmUgZXZlbnQgYW5kIGNhcHR1cmUgaXRzIHJlc3VsdFxuXHRcdFx0XHRcdC8vIFN1cHBvcnQ6IElFIDw9OSAtIDExK1xuXHRcdFx0XHRcdC8vIGZvY3VzKCkgYW5kIGJsdXIoKSBhcmUgYXN5bmNocm9ub3VzXG5cdFx0XHRcdFx0bm90QXN5bmMgPSBleHBlY3RTeW5jKCB0aGlzLCB0eXBlICk7XG5cdFx0XHRcdFx0dGhpc1sgdHlwZSBdKCk7XG5cdFx0XHRcdFx0cmVzdWx0ID0gZGF0YVByaXYuZ2V0KCB0aGlzLCB0eXBlICk7XG5cdFx0XHRcdFx0aWYgKCBzYXZlZCAhPT0gcmVzdWx0IHx8IG5vdEFzeW5jICkge1xuXHRcdFx0XHRcdFx0ZGF0YVByaXYuc2V0KCB0aGlzLCB0eXBlLCBmYWxzZSApO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRyZXN1bHQgPSB7fTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0aWYgKCBzYXZlZCAhPT0gcmVzdWx0ICkge1xuXG5cdFx0XHRcdFx0XHQvLyBDYW5jZWwgdGhlIG91dGVyIHN5bnRoZXRpYyBldmVudFxuXHRcdFx0XHRcdFx0ZXZlbnQuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XG5cdFx0XHRcdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG5cdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBDaHJvbWUgODYrXG5cdFx0XHRcdFx0XHQvLyBJbiBDaHJvbWUsIGlmIGFuIGVsZW1lbnQgaGF2aW5nIGEgZm9jdXNvdXQgaGFuZGxlciBpcyBibHVycmVkIGJ5XG5cdFx0XHRcdFx0XHQvLyBjbGlja2luZyBvdXRzaWRlIG9mIGl0LCBpdCBpbnZva2VzIHRoZSBoYW5kbGVyIHN5bmNocm9ub3VzbHkuIElmXG5cdFx0XHRcdFx0XHQvLyB0aGF0IGhhbmRsZXIgY2FsbHMgYC5yZW1vdmUoKWAgb24gdGhlIGVsZW1lbnQsIHRoZSBkYXRhIGlzIGNsZWFyZWQsXG5cdFx0XHRcdFx0XHQvLyBsZWF2aW5nIGByZXN1bHRgIHVuZGVmaW5lZC4gV2UgbmVlZCB0byBndWFyZCBhZ2FpbnN0IHRoaXMuXG5cdFx0XHRcdFx0XHRyZXR1cm4gcmVzdWx0ICYmIHJlc3VsdC52YWx1ZTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gSWYgdGhpcyBpcyBhbiBpbm5lciBzeW50aGV0aWMgZXZlbnQgZm9yIGFuIGV2ZW50IHdpdGggYSBidWJibGluZyBzdXJyb2dhdGVcblx0XHRcdFx0Ly8gKGZvY3VzIG9yIGJsdXIpLCBhc3N1bWUgdGhhdCB0aGUgc3Vycm9nYXRlIGFscmVhZHkgcHJvcGFnYXRlZCBmcm9tIHRyaWdnZXJpbmcgdGhlXG5cdFx0XHRcdC8vIG5hdGl2ZSBldmVudCBhbmQgcHJldmVudCB0aGF0IGZyb20gaGFwcGVuaW5nIGFnYWluIGhlcmUuXG5cdFx0XHRcdC8vIFRoaXMgdGVjaG5pY2FsbHkgZ2V0cyB0aGUgb3JkZXJpbmcgd3Jvbmcgdy5yLnQuIHRvIGAudHJpZ2dlcigpYCAoaW4gd2hpY2ggdGhlXG5cdFx0XHRcdC8vIGJ1YmJsaW5nIHN1cnJvZ2F0ZSBwcm9wYWdhdGVzICphZnRlciogdGhlIG5vbi1idWJibGluZyBiYXNlKSwgYnV0IHRoYXQgc2VlbXNcblx0XHRcdFx0Ly8gbGVzcyBiYWQgdGhhbiBkdXBsaWNhdGlvbi5cblx0XHRcdFx0fSBlbHNlIGlmICggKCBqUXVlcnkuZXZlbnQuc3BlY2lhbFsgdHlwZSBdIHx8IHt9ICkuZGVsZWdhdGVUeXBlICkge1xuXHRcdFx0XHRcdGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuXHRcdFx0XHR9XG5cblx0XHRcdC8vIElmIHRoaXMgaXMgYSBuYXRpdmUgZXZlbnQgdHJpZ2dlcmVkIGFib3ZlLCBldmVyeXRoaW5nIGlzIG5vdyBpbiBvcmRlclxuXHRcdFx0Ly8gRmlyZSBhbiBpbm5lciBzeW50aGV0aWMgZXZlbnQgd2l0aCB0aGUgb3JpZ2luYWwgYXJndW1lbnRzXG5cdFx0XHR9IGVsc2UgaWYgKCBzYXZlZC5sZW5ndGggKSB7XG5cblx0XHRcdFx0Ly8gLi4uYW5kIGNhcHR1cmUgdGhlIHJlc3VsdFxuXHRcdFx0XHRkYXRhUHJpdi5zZXQoIHRoaXMsIHR5cGUsIHtcblx0XHRcdFx0XHR2YWx1ZTogalF1ZXJ5LmV2ZW50LnRyaWdnZXIoXG5cblx0XHRcdFx0XHRcdC8vIFN1cHBvcnQ6IElFIDw9OSAtIDExK1xuXHRcdFx0XHRcdFx0Ly8gRXh0ZW5kIHdpdGggdGhlIHByb3RvdHlwZSB0byByZXNldCB0aGUgYWJvdmUgc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKClcblx0XHRcdFx0XHRcdGpRdWVyeS5leHRlbmQoIHNhdmVkWyAwIF0sIGpRdWVyeS5FdmVudC5wcm90b3R5cGUgKSxcblx0XHRcdFx0XHRcdHNhdmVkLnNsaWNlKCAxICksXG5cdFx0XHRcdFx0XHR0aGlzXG5cdFx0XHRcdFx0KVxuXHRcdFx0XHR9ICk7XG5cblx0XHRcdFx0Ly8gQWJvcnQgaGFuZGxpbmcgb2YgdGhlIG5hdGl2ZSBldmVudFxuXHRcdFx0XHRldmVudC5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcblx0XHRcdH1cblx0XHR9XG5cdH0gKTtcbn1cblxualF1ZXJ5LnJlbW92ZUV2ZW50ID0gZnVuY3Rpb24oIGVsZW0sIHR5cGUsIGhhbmRsZSApIHtcblxuXHQvLyBUaGlzIFwiaWZcIiBpcyBuZWVkZWQgZm9yIHBsYWluIG9iamVjdHNcblx0aWYgKCBlbGVtLnJlbW92ZUV2ZW50TGlzdGVuZXIgKSB7XG5cdFx0ZWxlbS5yZW1vdmVFdmVudExpc3RlbmVyKCB0eXBlLCBoYW5kbGUgKTtcblx0fVxufTtcblxualF1ZXJ5LkV2ZW50ID0gZnVuY3Rpb24oIHNyYywgcHJvcHMgKSB7XG5cblx0Ly8gQWxsb3cgaW5zdGFudGlhdGlvbiB3aXRob3V0IHRoZSAnbmV3JyBrZXl3b3JkXG5cdGlmICggISggdGhpcyBpbnN0YW5jZW9mIGpRdWVyeS5FdmVudCApICkge1xuXHRcdHJldHVybiBuZXcgalF1ZXJ5LkV2ZW50KCBzcmMsIHByb3BzICk7XG5cdH1cblxuXHQvLyBFdmVudCBvYmplY3Rcblx0aWYgKCBzcmMgJiYgc3JjLnR5cGUgKSB7XG5cdFx0dGhpcy5vcmlnaW5hbEV2ZW50ID0gc3JjO1xuXHRcdHRoaXMudHlwZSA9IHNyYy50eXBlO1xuXG5cdFx0Ly8gRXZlbnRzIGJ1YmJsaW5nIHVwIHRoZSBkb2N1bWVudCBtYXkgaGF2ZSBiZWVuIG1hcmtlZCBhcyBwcmV2ZW50ZWRcblx0XHQvLyBieSBhIGhhbmRsZXIgbG93ZXIgZG93biB0aGUgdHJlZTsgcmVmbGVjdCB0aGUgY29ycmVjdCB2YWx1ZS5cblx0XHR0aGlzLmlzRGVmYXVsdFByZXZlbnRlZCA9IHNyYy5kZWZhdWx0UHJldmVudGVkIHx8XG5cdFx0XHRcdHNyYy5kZWZhdWx0UHJldmVudGVkID09PSB1bmRlZmluZWQgJiZcblxuXHRcdFx0XHQvLyBTdXBwb3J0OiBBbmRyb2lkIDw9Mi4zIG9ubHlcblx0XHRcdFx0c3JjLnJldHVyblZhbHVlID09PSBmYWxzZSA/XG5cdFx0XHRyZXR1cm5UcnVlIDpcblx0XHRcdHJldHVybkZhbHNlO1xuXG5cdFx0Ly8gQ3JlYXRlIHRhcmdldCBwcm9wZXJ0aWVzXG5cdFx0Ly8gU3VwcG9ydDogU2FmYXJpIDw9NiAtIDcgb25seVxuXHRcdC8vIFRhcmdldCBzaG91bGQgbm90IGJlIGEgdGV4dCBub2RlICgjNTA0LCAjMTMxNDMpXG5cdFx0dGhpcy50YXJnZXQgPSAoIHNyYy50YXJnZXQgJiYgc3JjLnRhcmdldC5ub2RlVHlwZSA9PT0gMyApID9cblx0XHRcdHNyYy50YXJnZXQucGFyZW50Tm9kZSA6XG5cdFx0XHRzcmMudGFyZ2V0O1xuXG5cdFx0dGhpcy5jdXJyZW50VGFyZ2V0ID0gc3JjLmN1cnJlbnRUYXJnZXQ7XG5cdFx0dGhpcy5yZWxhdGVkVGFyZ2V0ID0gc3JjLnJlbGF0ZWRUYXJnZXQ7XG5cblx0Ly8gRXZlbnQgdHlwZVxuXHR9IGVsc2Uge1xuXHRcdHRoaXMudHlwZSA9IHNyYztcblx0fVxuXG5cdC8vIFB1dCBleHBsaWNpdGx5IHByb3ZpZGVkIHByb3BlcnRpZXMgb250byB0aGUgZXZlbnQgb2JqZWN0XG5cdGlmICggcHJvcHMgKSB7XG5cdFx0alF1ZXJ5LmV4dGVuZCggdGhpcywgcHJvcHMgKTtcblx0fVxuXG5cdC8vIENyZWF0ZSBhIHRpbWVzdGFtcCBpZiBpbmNvbWluZyBldmVudCBkb2Vzbid0IGhhdmUgb25lXG5cdHRoaXMudGltZVN0YW1wID0gc3JjICYmIHNyYy50aW1lU3RhbXAgfHwgRGF0ZS5ub3coKTtcblxuXHQvLyBNYXJrIGl0IGFzIGZpeGVkXG5cdHRoaXNbIGpRdWVyeS5leHBhbmRvIF0gPSB0cnVlO1xufTtcblxuLy8galF1ZXJ5LkV2ZW50IGlzIGJhc2VkIG9uIERPTTMgRXZlbnRzIGFzIHNwZWNpZmllZCBieSB0aGUgRUNNQVNjcmlwdCBMYW5ndWFnZSBCaW5kaW5nXG4vLyBodHRwczovL3d3dy53My5vcmcvVFIvMjAwMy9XRC1ET00tTGV2ZWwtMy1FdmVudHMtMjAwMzAzMzEvZWNtYS1zY3JpcHQtYmluZGluZy5odG1sXG5qUXVlcnkuRXZlbnQucHJvdG90eXBlID0ge1xuXHRjb25zdHJ1Y3RvcjogalF1ZXJ5LkV2ZW50LFxuXHRpc0RlZmF1bHRQcmV2ZW50ZWQ6IHJldHVybkZhbHNlLFxuXHRpc1Byb3BhZ2F0aW9uU3RvcHBlZDogcmV0dXJuRmFsc2UsXG5cdGlzSW1tZWRpYXRlUHJvcGFnYXRpb25TdG9wcGVkOiByZXR1cm5GYWxzZSxcblx0aXNTaW11bGF0ZWQ6IGZhbHNlLFxuXG5cdHByZXZlbnREZWZhdWx0OiBmdW5jdGlvbigpIHtcblx0XHR2YXIgZSA9IHRoaXMub3JpZ2luYWxFdmVudDtcblxuXHRcdHRoaXMuaXNEZWZhdWx0UHJldmVudGVkID0gcmV0dXJuVHJ1ZTtcblxuXHRcdGlmICggZSAmJiAhdGhpcy5pc1NpbXVsYXRlZCApIHtcblx0XHRcdGUucHJldmVudERlZmF1bHQoKTtcblx0XHR9XG5cdH0sXG5cdHN0b3BQcm9wYWdhdGlvbjogZnVuY3Rpb24oKSB7XG5cdFx0dmFyIGUgPSB0aGlzLm9yaWdpbmFsRXZlbnQ7XG5cblx0XHR0aGlzLmlzUHJvcGFnYXRpb25TdG9wcGVkID0gcmV0dXJuVHJ1ZTtcblxuXHRcdGlmICggZSAmJiAhdGhpcy5pc1NpbXVsYXRlZCApIHtcblx0XHRcdGUuc3RvcFByb3BhZ2F0aW9uKCk7XG5cdFx0fVxuXHR9LFxuXHRzdG9wSW1tZWRpYXRlUHJvcGFnYXRpb246IGZ1bmN0aW9uKCkge1xuXHRcdHZhciBlID0gdGhpcy5vcmlnaW5hbEV2ZW50O1xuXG5cdFx0dGhpcy5pc0ltbWVkaWF0ZVByb3BhZ2F0aW9uU3RvcHBlZCA9IHJldHVyblRydWU7XG5cblx0XHRpZiAoIGUgJiYgIXRoaXMuaXNTaW11bGF0ZWQgKSB7XG5cdFx0XHRlLnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xuXHRcdH1cblxuXHRcdHRoaXMuc3RvcFByb3BhZ2F0aW9uKCk7XG5cdH1cbn07XG5cbi8vIEluY2x1ZGVzIGFsbCBjb21tb24gZXZlbnQgcHJvcHMgaW5jbHVkaW5nIEtleUV2ZW50IGFuZCBNb3VzZUV2ZW50IHNwZWNpZmljIHByb3BzXG5qUXVlcnkuZWFjaCgge1xuXHRhbHRLZXk6IHRydWUsXG5cdGJ1YmJsZXM6IHRydWUsXG5cdGNhbmNlbGFibGU6IHRydWUsXG5cdGNoYW5nZWRUb3VjaGVzOiB0cnVlLFxuXHRjdHJsS2V5OiB0cnVlLFxuXHRkZXRhaWw6IHRydWUsXG5cdGV2ZW50UGhhc2U6IHRydWUsXG5cdG1ldGFLZXk6IHRydWUsXG5cdHBhZ2VYOiB0cnVlLFxuXHRwYWdlWTogdHJ1ZSxcblx0c2hpZnRLZXk6IHRydWUsXG5cdHZpZXc6IHRydWUsXG5cdFwiY2hhclwiOiB0cnVlLFxuXHRjb2RlOiB0cnVlLFxuXHRjaGFyQ29kZTogdHJ1ZSxcblx0a2V5OiB0cnVlLFxuXHRrZXlDb2RlOiB0cnVlLFxuXHRidXR0b246IHRydWUsXG5cdGJ1dHRvbnM6IHRydWUsXG5cdGNsaWVudFg6IHRydWUsXG5cdGNsaWVudFk6IHRydWUsXG5cdG9mZnNldFg6IHRydWUsXG5cdG9mZnNldFk6IHRydWUsXG5cdHBvaW50ZXJJZDogdHJ1ZSxcblx0cG9pbnRlclR5cGU6IHRydWUsXG5cdHNjcmVlblg6IHRydWUsXG5cdHNjcmVlblk6IHRydWUsXG5cdHRhcmdldFRvdWNoZXM6IHRydWUsXG5cdHRvRWxlbWVudDogdHJ1ZSxcblx0dG91Y2hlczogdHJ1ZSxcblx0d2hpY2g6IHRydWVcbn0sIGpRdWVyeS5ldmVudC5hZGRQcm9wICk7XG5cbmpRdWVyeS5lYWNoKCB7IGZvY3VzOiBcImZvY3VzaW5cIiwgYmx1cjogXCJmb2N1c291dFwiIH0sIGZ1bmN0aW9uKCB0eXBlLCBkZWxlZ2F0ZVR5cGUgKSB7XG5cdGpRdWVyeS5ldmVudC5zcGVjaWFsWyB0eXBlIF0gPSB7XG5cblx0XHQvLyBVdGlsaXplIG5hdGl2ZSBldmVudCBpZiBwb3NzaWJsZSBzbyBibHVyL2ZvY3VzIHNlcXVlbmNlIGlzIGNvcnJlY3Rcblx0XHRzZXR1cDogZnVuY3Rpb24oKSB7XG5cblx0XHRcdC8vIENsYWltIHRoZSBmaXJzdCBoYW5kbGVyXG5cdFx0XHQvLyBkYXRhUHJpdi5zZXQoIHRoaXMsIFwiZm9jdXNcIiwgLi4uIClcblx0XHRcdC8vIGRhdGFQcml2LnNldCggdGhpcywgXCJibHVyXCIsIC4uLiApXG5cdFx0XHRsZXZlcmFnZU5hdGl2ZSggdGhpcywgdHlwZSwgZXhwZWN0U3luYyApO1xuXG5cdFx0XHQvLyBSZXR1cm4gZmFsc2UgdG8gYWxsb3cgbm9ybWFsIHByb2Nlc3NpbmcgaW4gdGhlIGNhbGxlclxuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH0sXG5cdFx0dHJpZ2dlcjogZnVuY3Rpb24oKSB7XG5cblx0XHRcdC8vIEZvcmNlIHNldHVwIGJlZm9yZSB0cmlnZ2VyXG5cdFx0XHRsZXZlcmFnZU5hdGl2ZSggdGhpcywgdHlwZSApO1xuXG5cdFx0XHQvLyBSZXR1cm4gbm9uLWZhbHNlIHRvIGFsbG93IG5vcm1hbCBldmVudC1wYXRoIHByb3BhZ2F0aW9uXG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9LFxuXG5cdFx0Ly8gU3VwcHJlc3MgbmF0aXZlIGZvY3VzIG9yIGJsdXIgYXMgaXQncyBhbHJlYWR5IGJlaW5nIGZpcmVkXG5cdFx0Ly8gaW4gbGV2ZXJhZ2VOYXRpdmUuXG5cdFx0X2RlZmF1bHQ6IGZ1bmN0aW9uKCkge1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fSxcblxuXHRcdGRlbGVnYXRlVHlwZTogZGVsZWdhdGVUeXBlXG5cdH07XG59ICk7XG5cbi8vIENyZWF0ZSBtb3VzZWVudGVyL2xlYXZlIGV2ZW50cyB1c2luZyBtb3VzZW92ZXIvb3V0IGFuZCBldmVudC10aW1lIGNoZWNrc1xuLy8gc28gdGhhdCBldmVudCBkZWxlZ2F0aW9uIHdvcmtzIGluIGpRdWVyeS5cbi8vIERvIHRoZSBzYW1lIGZvciBwb2ludGVyZW50ZXIvcG9pbnRlcmxlYXZlIGFuZCBwb2ludGVyb3Zlci9wb2ludGVyb3V0XG4vL1xuLy8gU3VwcG9ydDogU2FmYXJpIDcgb25seVxuLy8gU2FmYXJpIHNlbmRzIG1vdXNlZW50ZXIgdG9vIG9mdGVuOyBzZWU6XG4vLyBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvY2hyb21pdW0vaXNzdWVzL2RldGFpbD9pZD00NzAyNThcbi8vIGZvciB0aGUgZGVzY3JpcHRpb24gb2YgdGhlIGJ1ZyAoaXQgZXhpc3RlZCBpbiBvbGRlciBDaHJvbWUgdmVyc2lvbnMgYXMgd2VsbCkuXG5qUXVlcnkuZWFjaCgge1xuXHRtb3VzZWVudGVyOiBcIm1vdXNlb3ZlclwiLFxuXHRtb3VzZWxlYXZlOiBcIm1vdXNlb3V0XCIsXG5cdHBvaW50ZXJlbnRlcjogXCJwb2ludGVyb3ZlclwiLFxuXHRwb2ludGVybGVhdmU6IFwicG9pbnRlcm91dFwiXG59LCBmdW5jdGlvbiggb3JpZywgZml4ICkge1xuXHRqUXVlcnkuZXZlbnQuc3BlY2lhbFsgb3JpZyBdID0ge1xuXHRcdGRlbGVnYXRlVHlwZTogZml4LFxuXHRcdGJpbmRUeXBlOiBmaXgsXG5cblx0XHRoYW5kbGU6IGZ1bmN0aW9uKCBldmVudCApIHtcblx0XHRcdHZhciByZXQsXG5cdFx0XHRcdHRhcmdldCA9IHRoaXMsXG5cdFx0XHRcdHJlbGF0ZWQgPSBldmVudC5yZWxhdGVkVGFyZ2V0LFxuXHRcdFx0XHRoYW5kbGVPYmogPSBldmVudC5oYW5kbGVPYmo7XG5cblx0XHRcdC8vIEZvciBtb3VzZWVudGVyL2xlYXZlIGNhbGwgdGhlIGhhbmRsZXIgaWYgcmVsYXRlZCBpcyBvdXRzaWRlIHRoZSB0YXJnZXQuXG5cdFx0XHQvLyBOQjogTm8gcmVsYXRlZFRhcmdldCBpZiB0aGUgbW91c2UgbGVmdC9lbnRlcmVkIHRoZSBicm93c2VyIHdpbmRvd1xuXHRcdFx0aWYgKCAhcmVsYXRlZCB8fCAoIHJlbGF0ZWQgIT09IHRhcmdldCAmJiAhalF1ZXJ5LmNvbnRhaW5zKCB0YXJnZXQsIHJlbGF0ZWQgKSApICkge1xuXHRcdFx0XHRldmVudC50eXBlID0gaGFuZGxlT2JqLm9yaWdUeXBlO1xuXHRcdFx0XHRyZXQgPSBoYW5kbGVPYmouaGFuZGxlci5hcHBseSggdGhpcywgYXJndW1lbnRzICk7XG5cdFx0XHRcdGV2ZW50LnR5cGUgPSBmaXg7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gcmV0O1xuXHRcdH1cblx0fTtcbn0gKTtcblxualF1ZXJ5LmZuLmV4dGVuZCgge1xuXG5cdG9uOiBmdW5jdGlvbiggdHlwZXMsIHNlbGVjdG9yLCBkYXRhLCBmbiApIHtcblx0XHRyZXR1cm4gb24oIHRoaXMsIHR5cGVzLCBzZWxlY3RvciwgZGF0YSwgZm4gKTtcblx0fSxcblx0b25lOiBmdW5jdGlvbiggdHlwZXMsIHNlbGVjdG9yLCBkYXRhLCBmbiApIHtcblx0XHRyZXR1cm4gb24oIHRoaXMsIHR5cGVzLCBzZWxlY3RvciwgZGF0YSwgZm4sIDEgKTtcblx0fSxcblx0b2ZmOiBmdW5jdGlvbiggdHlwZXMsIHNlbGVjdG9yLCBmbiApIHtcblx0XHR2YXIgaGFuZGxlT2JqLCB0eXBlO1xuXHRcdGlmICggdHlwZXMgJiYgdHlwZXMucHJldmVudERlZmF1bHQgJiYgdHlwZXMuaGFuZGxlT2JqICkge1xuXG5cdFx0XHQvLyAoIGV2ZW50ICkgIGRpc3BhdGNoZWQgalF1ZXJ5LkV2ZW50XG5cdFx0XHRoYW5kbGVPYmogPSB0eXBlcy5oYW5kbGVPYmo7XG5cdFx0XHRqUXVlcnkoIHR5cGVzLmRlbGVnYXRlVGFyZ2V0ICkub2ZmKFxuXHRcdFx0XHRoYW5kbGVPYmoubmFtZXNwYWNlID9cblx0XHRcdFx0XHRoYW5kbGVPYmoub3JpZ1R5cGUgKyBcIi5cIiArIGhhbmRsZU9iai5uYW1lc3BhY2UgOlxuXHRcdFx0XHRcdGhhbmRsZU9iai5vcmlnVHlwZSxcblx0XHRcdFx0aGFuZGxlT2JqLnNlbGVjdG9yLFxuXHRcdFx0XHRoYW5kbGVPYmouaGFuZGxlclxuXHRcdFx0KTtcblx0XHRcdHJldHVybiB0aGlzO1xuXHRcdH1cblx0XHRpZiAoIHR5cGVvZiB0eXBlcyA9PT0gXCJvYmplY3RcIiApIHtcblxuXHRcdFx0Ly8gKCB0eXBlcy1vYmplY3QgWywgc2VsZWN0b3JdIClcblx0XHRcdGZvciAoIHR5cGUgaW4gdHlwZXMgKSB7XG5cdFx0XHRcdHRoaXMub2ZmKCB0eXBlLCBzZWxlY3RvciwgdHlwZXNbIHR5cGUgXSApO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0fVxuXHRcdGlmICggc2VsZWN0b3IgPT09IGZhbHNlIHx8IHR5cGVvZiBzZWxlY3RvciA9PT0gXCJmdW5jdGlvblwiICkge1xuXG5cdFx0XHQvLyAoIHR5cGVzIFssIGZuXSApXG5cdFx0XHRmbiA9IHNlbGVjdG9yO1xuXHRcdFx0c2VsZWN0b3IgPSB1bmRlZmluZWQ7XG5cdFx0fVxuXHRcdGlmICggZm4gPT09IGZhbHNlICkge1xuXHRcdFx0Zm4gPSByZXR1cm5GYWxzZTtcblx0XHR9XG5cdFx0cmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24oKSB7XG5cdFx0XHRqUXVlcnkuZXZlbnQucmVtb3ZlKCB0aGlzLCB0eXBlcywgZm4sIHNlbGVjdG9yICk7XG5cdFx0fSApO1xuXHR9XG59ICk7XG5cblxudmFyXG5cblx0Ly8gU3VwcG9ydDogSUUgPD0xMCAtIDExLCBFZGdlIDEyIC0gMTMgb25seVxuXHQvLyBJbiBJRS9FZGdlIHVzaW5nIHJlZ2V4IGdyb3VwcyBoZXJlIGNhdXNlcyBzZXZlcmUgc2xvd2Rvd25zLlxuXHQvLyBTZWUgaHR0cHM6Ly9jb25uZWN0Lm1pY3Jvc29mdC5jb20vSUUvZmVlZGJhY2svZGV0YWlscy8xNzM2NTEyL1xuXHRybm9Jbm5lcmh0bWwgPSAvPHNjcmlwdHw8c3R5bGV8PGxpbmsvaSxcblxuXHQvLyBjaGVja2VkPVwiY2hlY2tlZFwiIG9yIGNoZWNrZWRcblx0cmNoZWNrZWQgPSAvY2hlY2tlZFxccyooPzpbXj1dfD1cXHMqLmNoZWNrZWQuKS9pLFxuXHRyY2xlYW5TY3JpcHQgPSAvXlxccyo8ISg/OlxcW0NEQVRBXFxbfC0tKXwoPzpcXF1cXF18LS0pPlxccyokL2c7XG5cbi8vIFByZWZlciBhIHRib2R5IG92ZXIgaXRzIHBhcmVudCB0YWJsZSBmb3IgY29udGFpbmluZyBuZXcgcm93c1xuZnVuY3Rpb24gbWFuaXB1bGF0aW9uVGFyZ2V0KCBlbGVtLCBjb250ZW50ICkge1xuXHRpZiAoIG5vZGVOYW1lKCBlbGVtLCBcInRhYmxlXCIgKSAmJlxuXHRcdG5vZGVOYW1lKCBjb250ZW50Lm5vZGVUeXBlICE9PSAxMSA/IGNvbnRlbnQgOiBjb250ZW50LmZpcnN0Q2hpbGQsIFwidHJcIiApICkge1xuXG5cdFx0cmV0dXJuIGpRdWVyeSggZWxlbSApLmNoaWxkcmVuKCBcInRib2R5XCIgKVsgMCBdIHx8IGVsZW07XG5cdH1cblxuXHRyZXR1cm4gZWxlbTtcbn1cblxuLy8gUmVwbGFjZS9yZXN0b3JlIHRoZSB0eXBlIGF0dHJpYnV0ZSBvZiBzY3JpcHQgZWxlbWVudHMgZm9yIHNhZmUgRE9NIG1hbmlwdWxhdGlvblxuZnVuY3Rpb24gZGlzYWJsZVNjcmlwdCggZWxlbSApIHtcblx0ZWxlbS50eXBlID0gKCBlbGVtLmdldEF0dHJpYnV0ZSggXCJ0eXBlXCIgKSAhPT0gbnVsbCApICsgXCIvXCIgKyBlbGVtLnR5cGU7XG5cdHJldHVybiBlbGVtO1xufVxuZnVuY3Rpb24gcmVzdG9yZVNjcmlwdCggZWxlbSApIHtcblx0aWYgKCAoIGVsZW0udHlwZSB8fCBcIlwiICkuc2xpY2UoIDAsIDUgKSA9PT0gXCJ0cnVlL1wiICkge1xuXHRcdGVsZW0udHlwZSA9IGVsZW0udHlwZS5zbGljZSggNSApO1xuXHR9IGVsc2Uge1xuXHRcdGVsZW0ucmVtb3ZlQXR0cmlidXRlKCBcInR5cGVcIiApO1xuXHR9XG5cblx0cmV0dXJuIGVsZW07XG59XG5cbmZ1bmN0aW9uIGNsb25lQ29weUV2ZW50KCBzcmMsIGRlc3QgKSB7XG5cdHZhciBpLCBsLCB0eXBlLCBwZGF0YU9sZCwgdWRhdGFPbGQsIHVkYXRhQ3VyLCBldmVudHM7XG5cblx0aWYgKCBkZXN0Lm5vZGVUeXBlICE9PSAxICkge1xuXHRcdHJldHVybjtcblx0fVxuXG5cdC8vIDEuIENvcHkgcHJpdmF0ZSBkYXRhOiBldmVudHMsIGhhbmRsZXJzLCBldGMuXG5cdGlmICggZGF0YVByaXYuaGFzRGF0YSggc3JjICkgKSB7XG5cdFx0cGRhdGFPbGQgPSBkYXRhUHJpdi5nZXQoIHNyYyApO1xuXHRcdGV2ZW50cyA9IHBkYXRhT2xkLmV2ZW50cztcblxuXHRcdGlmICggZXZlbnRzICkge1xuXHRcdFx0ZGF0YVByaXYucmVtb3ZlKCBkZXN0LCBcImhhbmRsZSBldmVudHNcIiApO1xuXG5cdFx0XHRmb3IgKCB0eXBlIGluIGV2ZW50cyApIHtcblx0XHRcdFx0Zm9yICggaSA9IDAsIGwgPSBldmVudHNbIHR5cGUgXS5sZW5ndGg7IGkgPCBsOyBpKysgKSB7XG5cdFx0XHRcdFx0alF1ZXJ5LmV2ZW50LmFkZCggZGVzdCwgdHlwZSwgZXZlbnRzWyB0eXBlIF1bIGkgXSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0Ly8gMi4gQ29weSB1c2VyIGRhdGFcblx0aWYgKCBkYXRhVXNlci5oYXNEYXRhKCBzcmMgKSApIHtcblx0XHR1ZGF0YU9sZCA9IGRhdGFVc2VyLmFjY2Vzcyggc3JjICk7XG5cdFx0dWRhdGFDdXIgPSBqUXVlcnkuZXh0ZW5kKCB7fSwgdWRhdGFPbGQgKTtcblxuXHRcdGRhdGFVc2VyLnNldCggZGVzdCwgdWRhdGFDdXIgKTtcblx0fVxufVxuXG4vLyBGaXggSUUgYnVncywgc2VlIHN1cHBvcnQgdGVzdHNcbmZ1bmN0aW9uIGZpeElucHV0KCBzcmMsIGRlc3QgKSB7XG5cdHZhciBub2RlTmFtZSA9IGRlc3Qubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtcblxuXHQvLyBGYWlscyB0byBwZXJzaXN0IHRoZSBjaGVja2VkIHN0YXRlIG9mIGEgY2xvbmVkIGNoZWNrYm94IG9yIHJhZGlvIGJ1dHRvbi5cblx0aWYgKCBub2RlTmFtZSA9PT0gXCJpbnB1dFwiICYmIHJjaGVja2FibGVUeXBlLnRlc3QoIHNyYy50eXBlICkgKSB7XG5cdFx0ZGVzdC5jaGVja2VkID0gc3JjLmNoZWNrZWQ7XG5cblx0Ly8gRmFpbHMgdG8gcmV0dXJuIHRoZSBzZWxlY3RlZCBvcHRpb24gdG8gdGhlIGRlZmF1bHQgc2VsZWN0ZWQgc3RhdGUgd2hlbiBjbG9uaW5nIG9wdGlvbnNcblx0fSBlbHNlIGlmICggbm9kZU5hbWUgPT09IFwiaW5wdXRcIiB8fCBub2RlTmFtZSA9PT0gXCJ0ZXh0YXJlYVwiICkge1xuXHRcdGRlc3QuZGVmYXVsdFZhbHVlID0gc3JjLmRlZmF1bHRWYWx1ZTtcblx0fVxufVxuXG5mdW5jdGlvbiBkb21NYW5pcCggY29sbGVjdGlvbiwgYXJncywgY2FsbGJhY2ssIGlnbm9yZWQgKSB7XG5cblx0Ly8gRmxhdHRlbiBhbnkgbmVzdGVkIGFycmF5c1xuXHRhcmdzID0gZmxhdCggYXJncyApO1xuXG5cdHZhciBmcmFnbWVudCwgZmlyc3QsIHNjcmlwdHMsIGhhc1NjcmlwdHMsIG5vZGUsIGRvYyxcblx0XHRpID0gMCxcblx0XHRsID0gY29sbGVjdGlvbi5sZW5ndGgsXG5cdFx0aU5vQ2xvbmUgPSBsIC0gMSxcblx0XHR2YWx1ZSA9IGFyZ3NbIDAgXSxcblx0XHR2YWx1ZUlzRnVuY3Rpb24gPSBpc0Z1bmN0aW9uKCB2YWx1ZSApO1xuXG5cdC8vIFdlIGNhbid0IGNsb25lTm9kZSBmcmFnbWVudHMgdGhhdCBjb250YWluIGNoZWNrZWQsIGluIFdlYktpdFxuXHRpZiAoIHZhbHVlSXNGdW5jdGlvbiB8fFxuXHRcdFx0KCBsID4gMSAmJiB0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIgJiZcblx0XHRcdFx0IXN1cHBvcnQuY2hlY2tDbG9uZSAmJiByY2hlY2tlZC50ZXN0KCB2YWx1ZSApICkgKSB7XG5cdFx0cmV0dXJuIGNvbGxlY3Rpb24uZWFjaCggZnVuY3Rpb24oIGluZGV4ICkge1xuXHRcdFx0dmFyIHNlbGYgPSBjb2xsZWN0aW9uLmVxKCBpbmRleCApO1xuXHRcdFx0aWYgKCB2YWx1ZUlzRnVuY3Rpb24gKSB7XG5cdFx0XHRcdGFyZ3NbIDAgXSA9IHZhbHVlLmNhbGwoIHRoaXMsIGluZGV4LCBzZWxmLmh0bWwoKSApO1xuXHRcdFx0fVxuXHRcdFx0ZG9tTWFuaXAoIHNlbGYsIGFyZ3MsIGNhbGxiYWNrLCBpZ25vcmVkICk7XG5cdFx0fSApO1xuXHR9XG5cblx0aWYgKCBsICkge1xuXHRcdGZyYWdtZW50ID0gYnVpbGRGcmFnbWVudCggYXJncywgY29sbGVjdGlvblsgMCBdLm93bmVyRG9jdW1lbnQsIGZhbHNlLCBjb2xsZWN0aW9uLCBpZ25vcmVkICk7XG5cdFx0Zmlyc3QgPSBmcmFnbWVudC5maXJzdENoaWxkO1xuXG5cdFx0aWYgKCBmcmFnbWVudC5jaGlsZE5vZGVzLmxlbmd0aCA9PT0gMSApIHtcblx0XHRcdGZyYWdtZW50ID0gZmlyc3Q7XG5cdFx0fVxuXG5cdFx0Ly8gUmVxdWlyZSBlaXRoZXIgbmV3IGNvbnRlbnQgb3IgYW4gaW50ZXJlc3QgaW4gaWdub3JlZCBlbGVtZW50cyB0byBpbnZva2UgdGhlIGNhbGxiYWNrXG5cdFx0aWYgKCBmaXJzdCB8fCBpZ25vcmVkICkge1xuXHRcdFx0c2NyaXB0cyA9IGpRdWVyeS5tYXAoIGdldEFsbCggZnJhZ21lbnQsIFwic2NyaXB0XCIgKSwgZGlzYWJsZVNjcmlwdCApO1xuXHRcdFx0aGFzU2NyaXB0cyA9IHNjcmlwdHMubGVuZ3RoO1xuXG5cdFx0XHQvLyBVc2UgdGhlIG9yaWdpbmFsIGZyYWdtZW50IGZvciB0aGUgbGFzdCBpdGVtXG5cdFx0XHQvLyBpbnN0ZWFkIG9mIHRoZSBmaXJzdCBiZWNhdXNlIGl0IGNhbiBlbmQgdXBcblx0XHRcdC8vIGJlaW5nIGVtcHRpZWQgaW5jb3JyZWN0bHkgaW4gY2VydGFpbiBzaXR1YXRpb25zICgjODA3MCkuXG5cdFx0XHRmb3IgKCA7IGkgPCBsOyBpKysgKSB7XG5cdFx0XHRcdG5vZGUgPSBmcmFnbWVudDtcblxuXHRcdFx0XHRpZiAoIGkgIT09IGlOb0Nsb25lICkge1xuXHRcdFx0XHRcdG5vZGUgPSBqUXVlcnkuY2xvbmUoIG5vZGUsIHRydWUsIHRydWUgKTtcblxuXHRcdFx0XHRcdC8vIEtlZXAgcmVmZXJlbmNlcyB0byBjbG9uZWQgc2NyaXB0cyBmb3IgbGF0ZXIgcmVzdG9yYXRpb25cblx0XHRcdFx0XHRpZiAoIGhhc1NjcmlwdHMgKSB7XG5cblx0XHRcdFx0XHRcdC8vIFN1cHBvcnQ6IEFuZHJvaWQgPD00LjAgb25seSwgUGhhbnRvbUpTIDEgb25seVxuXHRcdFx0XHRcdFx0Ly8gcHVzaC5hcHBseShfLCBhcnJheWxpa2UpIHRocm93cyBvbiBhbmNpZW50IFdlYktpdFxuXHRcdFx0XHRcdFx0alF1ZXJ5Lm1lcmdlKCBzY3JpcHRzLCBnZXRBbGwoIG5vZGUsIFwic2NyaXB0XCIgKSApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHRcdGNhbGxiYWNrLmNhbGwoIGNvbGxlY3Rpb25bIGkgXSwgbm9kZSwgaSApO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIGhhc1NjcmlwdHMgKSB7XG5cdFx0XHRcdGRvYyA9IHNjcmlwdHNbIHNjcmlwdHMubGVuZ3RoIC0gMSBdLm93bmVyRG9jdW1lbnQ7XG5cblx0XHRcdFx0Ly8gUmVlbmFibGUgc2NyaXB0c1xuXHRcdFx0XHRqUXVlcnkubWFwKCBzY3JpcHRzLCByZXN0b3JlU2NyaXB0ICk7XG5cblx0XHRcdFx0Ly8gRXZhbHVhdGUgZXhlY3V0YWJsZSBzY3JpcHRzIG9uIGZpcnN0IGRvY3VtZW50IGluc2VydGlvblxuXHRcdFx0XHRmb3IgKCBpID0gMDsgaSA8IGhhc1NjcmlwdHM7IGkrKyApIHtcblx0XHRcdFx0XHRub2RlID0gc2NyaXB0c1sgaSBdO1xuXHRcdFx0XHRcdGlmICggcnNjcmlwdFR5cGUudGVzdCggbm9kZS50eXBlIHx8IFwiXCIgKSAmJlxuXHRcdFx0XHRcdFx0IWRhdGFQcml2LmFjY2Vzcyggbm9kZSwgXCJnbG9iYWxFdmFsXCIgKSAmJlxuXHRcdFx0XHRcdFx0alF1ZXJ5LmNvbnRhaW5zKCBkb2MsIG5vZGUgKSApIHtcblxuXHRcdFx0XHRcdFx0aWYgKCBub2RlLnNyYyAmJiAoIG5vZGUudHlwZSB8fCBcIlwiICkudG9Mb3dlckNhc2UoKSAgIT09IFwibW9kdWxlXCIgKSB7XG5cblx0XHRcdFx0XHRcdFx0Ly8gT3B0aW9uYWwgQUpBWCBkZXBlbmRlbmN5LCBidXQgd29uJ3QgcnVuIHNjcmlwdHMgaWYgbm90IHByZXNlbnRcblx0XHRcdFx0XHRcdFx0aWYgKCBqUXVlcnkuX2V2YWxVcmwgJiYgIW5vZGUubm9Nb2R1bGUgKSB7XG5cdFx0XHRcdFx0XHRcdFx0alF1ZXJ5Ll9ldmFsVXJsKCBub2RlLnNyYywge1xuXHRcdFx0XHRcdFx0XHRcdFx0bm9uY2U6IG5vZGUubm9uY2UgfHwgbm9kZS5nZXRBdHRyaWJ1dGUoIFwibm9uY2VcIiApXG5cdFx0XHRcdFx0XHRcdFx0fSwgZG9jICk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdERPTUV2YWwoIG5vZGUudGV4dENvbnRlbnQucmVwbGFjZSggcmNsZWFuU2NyaXB0LCBcIlwiICksIG5vZGUsIGRvYyApO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHJldHVybiBjb2xsZWN0aW9uO1xufVxuXG5mdW5jdGlvbiByZW1vdmUoIGVsZW0sIHNlbGVjdG9yLCBrZWVwRGF0YSApIHtcblx0dmFyIG5vZGUsXG5cdFx0bm9kZXMgPSBzZWxlY3RvciA/IGpRdWVyeS5maWx0ZXIoIHNlbGVjdG9yLCBlbGVtICkgOiBlbGVtLFxuXHRcdGkgPSAwO1xuXG5cdGZvciAoIDsgKCBub2RlID0gbm9kZXNbIGkgXSApICE9IG51bGw7IGkrKyApIHtcblx0XHRpZiAoICFrZWVwRGF0YSAmJiBub2RlLm5vZGVUeXBlID09PSAxICkge1xuXHRcdFx0alF1ZXJ5LmNsZWFuRGF0YSggZ2V0QWxsKCBub2RlICkgKTtcblx0XHR9XG5cblx0XHRpZiAoIG5vZGUucGFyZW50Tm9kZSApIHtcblx0XHRcdGlmICgga2VlcERhdGEgJiYgaXNBdHRhY2hlZCggbm9kZSApICkge1xuXHRcdFx0XHRzZXRHbG9iYWxFdmFsKCBnZXRBbGwoIG5vZGUsIFwic2NyaXB0XCIgKSApO1xuXHRcdFx0fVxuXHRcdFx0bm9kZS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKCBub2RlICk7XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIGVsZW07XG59XG5cbmpRdWVyeS5leHRlbmQoIHtcblx0aHRtbFByZWZpbHRlcjogZnVuY3Rpb24oIGh0bWwgKSB7XG5cdFx0cmV0dXJuIGh0bWw7XG5cdH0sXG5cblx0Y2xvbmU6IGZ1bmN0aW9uKCBlbGVtLCBkYXRhQW5kRXZlbnRzLCBkZWVwRGF0YUFuZEV2ZW50cyApIHtcblx0XHR2YXIgaSwgbCwgc3JjRWxlbWVudHMsIGRlc3RFbGVtZW50cyxcblx0XHRcdGNsb25lID0gZWxlbS5jbG9uZU5vZGUoIHRydWUgKSxcblx0XHRcdGluUGFnZSA9IGlzQXR0YWNoZWQoIGVsZW0gKTtcblxuXHRcdC8vIEZpeCBJRSBjbG9uaW5nIGlzc3Vlc1xuXHRcdGlmICggIXN1cHBvcnQubm9DbG9uZUNoZWNrZWQgJiYgKCBlbGVtLm5vZGVUeXBlID09PSAxIHx8IGVsZW0ubm9kZVR5cGUgPT09IDExICkgJiZcblx0XHRcdFx0IWpRdWVyeS5pc1hNTERvYyggZWxlbSApICkge1xuXG5cdFx0XHQvLyBXZSBlc2NoZXcgU2l6emxlIGhlcmUgZm9yIHBlcmZvcm1hbmNlIHJlYXNvbnM6IGh0dHBzOi8vanNwZXJmLmNvbS9nZXRhbGwtdnMtc2l6emxlLzJcblx0XHRcdGRlc3RFbGVtZW50cyA9IGdldEFsbCggY2xvbmUgKTtcblx0XHRcdHNyY0VsZW1lbnRzID0gZ2V0QWxsKCBlbGVtICk7XG5cblx0XHRcdGZvciAoIGkgPSAwLCBsID0gc3JjRWxlbWVudHMubGVuZ3RoOyBpIDwgbDsgaSsrICkge1xuXHRcdFx0XHRmaXhJbnB1dCggc3JjRWxlbWVudHNbIGkgXSwgZGVzdEVsZW1lbnRzWyBpIF0gKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBDb3B5IHRoZSBldmVudHMgZnJvbSB0aGUgb3JpZ2luYWwgdG8gdGhlIGNsb25lXG5cdFx0aWYgKCBkYXRhQW5kRXZlbnRzICkge1xuXHRcdFx0aWYgKCBkZWVwRGF0YUFuZEV2ZW50cyApIHtcblx0XHRcdFx0c3JjRWxlbWVudHMgPSBzcmNFbGVtZW50cyB8fCBnZXRBbGwoIGVsZW0gKTtcblx0XHRcdFx0ZGVzdEVsZW1lbnRzID0gZGVzdEVsZW1lbnRzIHx8IGdldEFsbCggY2xvbmUgKTtcblxuXHRcdFx0XHRmb3IgKCBpID0gMCwgbCA9IHNyY0VsZW1lbnRzLmxlbmd0aDsgaSA8IGw7IGkrKyApIHtcblx0XHRcdFx0XHRjbG9uZUNvcHlFdmVudCggc3JjRWxlbWVudHNbIGkgXSwgZGVzdEVsZW1lbnRzWyBpIF0gKTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Y2xvbmVDb3B5RXZlbnQoIGVsZW0sIGNsb25lICk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gUHJlc2VydmUgc2NyaXB0IGV2YWx1YXRpb24gaGlzdG9yeVxuXHRcdGRlc3RFbGVtZW50cyA9IGdldEFsbCggY2xvbmUsIFwic2NyaXB0XCIgKTtcblx0XHRpZiAoIGRlc3RFbGVtZW50cy5sZW5ndGggPiAwICkge1xuXHRcdFx0c2V0R2xvYmFsRXZhbCggZGVzdEVsZW1lbnRzLCAhaW5QYWdlICYmIGdldEFsbCggZWxlbSwgXCJzY3JpcHRcIiApICk7XG5cdFx0fVxuXG5cdFx0Ly8gUmV0dXJuIHRoZSBjbG9uZWQgc2V0XG5cdFx0cmV0dXJuIGNsb25lO1xuXHR9LFxuXG5cdGNsZWFuRGF0YTogZnVuY3Rpb24oIGVsZW1zICkge1xuXHRcdHZhciBkYXRhLCBlbGVtLCB0eXBlLFxuXHRcdFx0c3BlY2lhbCA9IGpRdWVyeS5ldmVudC5zcGVjaWFsLFxuXHRcdFx0aSA9IDA7XG5cblx0XHRmb3IgKCA7ICggZWxlbSA9IGVsZW1zWyBpIF0gKSAhPT0gdW5kZWZpbmVkOyBpKysgKSB7XG5cdFx0XHRpZiAoIGFjY2VwdERhdGEoIGVsZW0gKSApIHtcblx0XHRcdFx0aWYgKCAoIGRhdGEgPSBlbGVtWyBkYXRhUHJpdi5leHBhbmRvIF0gKSApIHtcblx0XHRcdFx0XHRpZiAoIGRhdGEuZXZlbnRzICkge1xuXHRcdFx0XHRcdFx0Zm9yICggdHlwZSBpbiBkYXRhLmV2ZW50cyApIHtcblx0XHRcdFx0XHRcdFx0aWYgKCBzcGVjaWFsWyB0eXBlIF0gKSB7XG5cdFx0XHRcdFx0XHRcdFx0alF1ZXJ5LmV2ZW50LnJlbW92ZSggZWxlbSwgdHlwZSApO1xuXG5cdFx0XHRcdFx0XHRcdC8vIFRoaXMgaXMgYSBzaG9ydGN1dCB0byBhdm9pZCBqUXVlcnkuZXZlbnQucmVtb3ZlJ3Mgb3ZlcmhlYWRcblx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHRqUXVlcnkucmVtb3ZlRXZlbnQoIGVsZW0sIHR5cGUsIGRhdGEuaGFuZGxlICk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHQvLyBTdXBwb3J0OiBDaHJvbWUgPD0zNSAtIDQ1K1xuXHRcdFx0XHRcdC8vIEFzc2lnbiB1bmRlZmluZWQgaW5zdGVhZCBvZiB1c2luZyBkZWxldGUsIHNlZSBEYXRhI3JlbW92ZVxuXHRcdFx0XHRcdGVsZW1bIGRhdGFQcml2LmV4cGFuZG8gXSA9IHVuZGVmaW5lZDtcblx0XHRcdFx0fVxuXHRcdFx0XHRpZiAoIGVsZW1bIGRhdGFVc2VyLmV4cGFuZG8gXSApIHtcblxuXHRcdFx0XHRcdC8vIFN1cHBvcnQ6IENocm9tZSA8PTM1IC0gNDUrXG5cdFx0XHRcdFx0Ly8gQXNzaWduIHVuZGVmaW5lZCBpbnN0ZWFkIG9mIHVzaW5nIGRlbGV0ZSwgc2VlIERhdGEjcmVtb3ZlXG5cdFx0XHRcdFx0ZWxlbVsgZGF0YVVzZXIuZXhwYW5kbyBdID0gdW5kZWZpbmVkO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG59ICk7XG5cbmpRdWVyeS5mbi5leHRlbmQoIHtcblx0ZGV0YWNoOiBmdW5jdGlvbiggc2VsZWN0b3IgKSB7XG5cdFx0cmV0dXJuIHJlbW92ZSggdGhpcywgc2VsZWN0b3IsIHRydWUgKTtcblx0fSxcblxuXHRyZW1vdmU6IGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcblx0XHRyZXR1cm4gcmVtb3ZlKCB0aGlzLCBzZWxlY3RvciApO1xuXHR9LFxuXG5cdHRleHQ6IGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHRyZXR1cm4gYWNjZXNzKCB0aGlzLCBmdW5jdGlvbiggdmFsdWUgKSB7XG5cdFx0XHRyZXR1cm4gdmFsdWUgPT09IHVuZGVmaW5lZCA/XG5cdFx0XHRcdGpRdWVyeS50ZXh0KCB0aGlzICkgOlxuXHRcdFx0XHR0aGlzLmVtcHR5KCkuZWFjaCggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0aWYgKCB0aGlzLm5vZGVUeXBlID09PSAxIHx8IHRoaXMubm9kZVR5cGUgPT09IDExIHx8IHRoaXMubm9kZVR5cGUgPT09IDkgKSB7XG5cdFx0XHRcdFx0XHR0aGlzLnRleHRDb250ZW50ID0gdmFsdWU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9ICk7XG5cdFx0fSwgbnVsbCwgdmFsdWUsIGFyZ3VtZW50cy5sZW5ndGggKTtcblx0fSxcblxuXHRhcHBlbmQ6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiBkb21NYW5pcCggdGhpcywgYXJndW1lbnRzLCBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdGlmICggdGhpcy5ub2RlVHlwZSA9PT0gMSB8fCB0aGlzLm5vZGVUeXBlID09PSAxMSB8fCB0aGlzLm5vZGVUeXBlID09PSA5ICkge1xuXHRcdFx0XHR2YXIgdGFyZ2V0ID0gbWFuaXB1bGF0aW9uVGFyZ2V0KCB0aGlzLCBlbGVtICk7XG5cdFx0XHRcdHRhcmdldC5hcHBlbmRDaGlsZCggZWxlbSApO1xuXHRcdFx0fVxuXHRcdH0gKTtcblx0fSxcblxuXHRwcmVwZW5kOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gZG9tTWFuaXAoIHRoaXMsIGFyZ3VtZW50cywgZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRpZiAoIHRoaXMubm9kZVR5cGUgPT09IDEgfHwgdGhpcy5ub2RlVHlwZSA9PT0gMTEgfHwgdGhpcy5ub2RlVHlwZSA9PT0gOSApIHtcblx0XHRcdFx0dmFyIHRhcmdldCA9IG1hbmlwdWxhdGlvblRhcmdldCggdGhpcywgZWxlbSApO1xuXHRcdFx0XHR0YXJnZXQuaW5zZXJ0QmVmb3JlKCBlbGVtLCB0YXJnZXQuZmlyc3RDaGlsZCApO1xuXHRcdFx0fVxuXHRcdH0gKTtcblx0fSxcblxuXHRiZWZvcmU6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiBkb21NYW5pcCggdGhpcywgYXJndW1lbnRzLCBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdGlmICggdGhpcy5wYXJlbnROb2RlICkge1xuXHRcdFx0XHR0aGlzLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKCBlbGVtLCB0aGlzICk7XG5cdFx0XHR9XG5cdFx0fSApO1xuXHR9LFxuXG5cdGFmdGVyOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gZG9tTWFuaXAoIHRoaXMsIGFyZ3VtZW50cywgZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRpZiAoIHRoaXMucGFyZW50Tm9kZSApIHtcblx0XHRcdFx0dGhpcy5wYXJlbnROb2RlLmluc2VydEJlZm9yZSggZWxlbSwgdGhpcy5uZXh0U2libGluZyApO1xuXHRcdFx0fVxuXHRcdH0gKTtcblx0fSxcblxuXHRlbXB0eTogZnVuY3Rpb24oKSB7XG5cdFx0dmFyIGVsZW0sXG5cdFx0XHRpID0gMDtcblxuXHRcdGZvciAoIDsgKCBlbGVtID0gdGhpc1sgaSBdICkgIT0gbnVsbDsgaSsrICkge1xuXHRcdFx0aWYgKCBlbGVtLm5vZGVUeXBlID09PSAxICkge1xuXG5cdFx0XHRcdC8vIFByZXZlbnQgbWVtb3J5IGxlYWtzXG5cdFx0XHRcdGpRdWVyeS5jbGVhbkRhdGEoIGdldEFsbCggZWxlbSwgZmFsc2UgKSApO1xuXG5cdFx0XHRcdC8vIFJlbW92ZSBhbnkgcmVtYWluaW5nIG5vZGVzXG5cdFx0XHRcdGVsZW0udGV4dENvbnRlbnQgPSBcIlwiO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzO1xuXHR9LFxuXG5cdGNsb25lOiBmdW5jdGlvbiggZGF0YUFuZEV2ZW50cywgZGVlcERhdGFBbmRFdmVudHMgKSB7XG5cdFx0ZGF0YUFuZEV2ZW50cyA9IGRhdGFBbmRFdmVudHMgPT0gbnVsbCA/IGZhbHNlIDogZGF0YUFuZEV2ZW50cztcblx0XHRkZWVwRGF0YUFuZEV2ZW50cyA9IGRlZXBEYXRhQW5kRXZlbnRzID09IG51bGwgPyBkYXRhQW5kRXZlbnRzIDogZGVlcERhdGFBbmRFdmVudHM7XG5cblx0XHRyZXR1cm4gdGhpcy5tYXAoIGZ1bmN0aW9uKCkge1xuXHRcdFx0cmV0dXJuIGpRdWVyeS5jbG9uZSggdGhpcywgZGF0YUFuZEV2ZW50cywgZGVlcERhdGFBbmRFdmVudHMgKTtcblx0XHR9ICk7XG5cdH0sXG5cblx0aHRtbDogZnVuY3Rpb24oIHZhbHVlICkge1xuXHRcdHJldHVybiBhY2Nlc3MoIHRoaXMsIGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHRcdHZhciBlbGVtID0gdGhpc1sgMCBdIHx8IHt9LFxuXHRcdFx0XHRpID0gMCxcblx0XHRcdFx0bCA9IHRoaXMubGVuZ3RoO1xuXG5cdFx0XHRpZiAoIHZhbHVlID09PSB1bmRlZmluZWQgJiYgZWxlbS5ub2RlVHlwZSA9PT0gMSApIHtcblx0XHRcdFx0cmV0dXJuIGVsZW0uaW5uZXJIVE1MO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBTZWUgaWYgd2UgY2FuIHRha2UgYSBzaG9ydGN1dCBhbmQganVzdCB1c2UgaW5uZXJIVE1MXG5cdFx0XHRpZiAoIHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiAmJiAhcm5vSW5uZXJodG1sLnRlc3QoIHZhbHVlICkgJiZcblx0XHRcdFx0IXdyYXBNYXBbICggcnRhZ05hbWUuZXhlYyggdmFsdWUgKSB8fCBbIFwiXCIsIFwiXCIgXSApWyAxIF0udG9Mb3dlckNhc2UoKSBdICkge1xuXG5cdFx0XHRcdHZhbHVlID0galF1ZXJ5Lmh0bWxQcmVmaWx0ZXIoIHZhbHVlICk7XG5cblx0XHRcdFx0dHJ5IHtcblx0XHRcdFx0XHRmb3IgKCA7IGkgPCBsOyBpKysgKSB7XG5cdFx0XHRcdFx0XHRlbGVtID0gdGhpc1sgaSBdIHx8IHt9O1xuXG5cdFx0XHRcdFx0XHQvLyBSZW1vdmUgZWxlbWVudCBub2RlcyBhbmQgcHJldmVudCBtZW1vcnkgbGVha3Ncblx0XHRcdFx0XHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gMSApIHtcblx0XHRcdFx0XHRcdFx0alF1ZXJ5LmNsZWFuRGF0YSggZ2V0QWxsKCBlbGVtLCBmYWxzZSApICk7XG5cdFx0XHRcdFx0XHRcdGVsZW0uaW5uZXJIVE1MID0gdmFsdWU7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0ZWxlbSA9IDA7XG5cblx0XHRcdFx0Ly8gSWYgdXNpbmcgaW5uZXJIVE1MIHRocm93cyBhbiBleGNlcHRpb24sIHVzZSB0aGUgZmFsbGJhY2sgbWV0aG9kXG5cdFx0XHRcdH0gY2F0Y2ggKCBlICkge31cblx0XHRcdH1cblxuXHRcdFx0aWYgKCBlbGVtICkge1xuXHRcdFx0XHR0aGlzLmVtcHR5KCkuYXBwZW5kKCB2YWx1ZSApO1xuXHRcdFx0fVxuXHRcdH0sIG51bGwsIHZhbHVlLCBhcmd1bWVudHMubGVuZ3RoICk7XG5cdH0sXG5cblx0cmVwbGFjZVdpdGg6IGZ1bmN0aW9uKCkge1xuXHRcdHZhciBpZ25vcmVkID0gW107XG5cblx0XHQvLyBNYWtlIHRoZSBjaGFuZ2VzLCByZXBsYWNpbmcgZWFjaCBub24taWdub3JlZCBjb250ZXh0IGVsZW1lbnQgd2l0aCB0aGUgbmV3IGNvbnRlbnRcblx0XHRyZXR1cm4gZG9tTWFuaXAoIHRoaXMsIGFyZ3VtZW50cywgZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHR2YXIgcGFyZW50ID0gdGhpcy5wYXJlbnROb2RlO1xuXG5cdFx0XHRpZiAoIGpRdWVyeS5pbkFycmF5KCB0aGlzLCBpZ25vcmVkICkgPCAwICkge1xuXHRcdFx0XHRqUXVlcnkuY2xlYW5EYXRhKCBnZXRBbGwoIHRoaXMgKSApO1xuXHRcdFx0XHRpZiAoIHBhcmVudCApIHtcblx0XHRcdFx0XHRwYXJlbnQucmVwbGFjZUNoaWxkKCBlbGVtLCB0aGlzICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdC8vIEZvcmNlIGNhbGxiYWNrIGludm9jYXRpb25cblx0XHR9LCBpZ25vcmVkICk7XG5cdH1cbn0gKTtcblxualF1ZXJ5LmVhY2goIHtcblx0YXBwZW5kVG86IFwiYXBwZW5kXCIsXG5cdHByZXBlbmRUbzogXCJwcmVwZW5kXCIsXG5cdGluc2VydEJlZm9yZTogXCJiZWZvcmVcIixcblx0aW5zZXJ0QWZ0ZXI6IFwiYWZ0ZXJcIixcblx0cmVwbGFjZUFsbDogXCJyZXBsYWNlV2l0aFwiXG59LCBmdW5jdGlvbiggbmFtZSwgb3JpZ2luYWwgKSB7XG5cdGpRdWVyeS5mblsgbmFtZSBdID0gZnVuY3Rpb24oIHNlbGVjdG9yICkge1xuXHRcdHZhciBlbGVtcyxcblx0XHRcdHJldCA9IFtdLFxuXHRcdFx0aW5zZXJ0ID0galF1ZXJ5KCBzZWxlY3RvciApLFxuXHRcdFx0bGFzdCA9IGluc2VydC5sZW5ndGggLSAxLFxuXHRcdFx0aSA9IDA7XG5cblx0XHRmb3IgKCA7IGkgPD0gbGFzdDsgaSsrICkge1xuXHRcdFx0ZWxlbXMgPSBpID09PSBsYXN0ID8gdGhpcyA6IHRoaXMuY2xvbmUoIHRydWUgKTtcblx0XHRcdGpRdWVyeSggaW5zZXJ0WyBpIF0gKVsgb3JpZ2luYWwgXSggZWxlbXMgKTtcblxuXHRcdFx0Ly8gU3VwcG9ydDogQW5kcm9pZCA8PTQuMCBvbmx5LCBQaGFudG9tSlMgMSBvbmx5XG5cdFx0XHQvLyAuZ2V0KCkgYmVjYXVzZSBwdXNoLmFwcGx5KF8sIGFycmF5bGlrZSkgdGhyb3dzIG9uIGFuY2llbnQgV2ViS2l0XG5cdFx0XHRwdXNoLmFwcGx5KCByZXQsIGVsZW1zLmdldCgpICk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXMucHVzaFN0YWNrKCByZXQgKTtcblx0fTtcbn0gKTtcbnZhciBybnVtbm9ucHggPSBuZXcgUmVnRXhwKCBcIl4oXCIgKyBwbnVtICsgXCIpKD8hcHgpW2EteiVdKyRcIiwgXCJpXCIgKTtcblxudmFyIGdldFN0eWxlcyA9IGZ1bmN0aW9uKCBlbGVtICkge1xuXG5cdFx0Ly8gU3VwcG9ydDogSUUgPD0xMSBvbmx5LCBGaXJlZm94IDw9MzAgKCMxNTA5OCwgIzE0MTUwKVxuXHRcdC8vIElFIHRocm93cyBvbiBlbGVtZW50cyBjcmVhdGVkIGluIHBvcHVwc1xuXHRcdC8vIEZGIG1lYW53aGlsZSB0aHJvd3Mgb24gZnJhbWUgZWxlbWVudHMgdGhyb3VnaCBcImRlZmF1bHRWaWV3LmdldENvbXB1dGVkU3R5bGVcIlxuXHRcdHZhciB2aWV3ID0gZWxlbS5vd25lckRvY3VtZW50LmRlZmF1bHRWaWV3O1xuXG5cdFx0aWYgKCAhdmlldyB8fCAhdmlldy5vcGVuZXIgKSB7XG5cdFx0XHR2aWV3ID0gd2luZG93O1xuXHRcdH1cblxuXHRcdHJldHVybiB2aWV3LmdldENvbXB1dGVkU3R5bGUoIGVsZW0gKTtcblx0fTtcblxudmFyIHN3YXAgPSBmdW5jdGlvbiggZWxlbSwgb3B0aW9ucywgY2FsbGJhY2sgKSB7XG5cdHZhciByZXQsIG5hbWUsXG5cdFx0b2xkID0ge307XG5cblx0Ly8gUmVtZW1iZXIgdGhlIG9sZCB2YWx1ZXMsIGFuZCBpbnNlcnQgdGhlIG5ldyBvbmVzXG5cdGZvciAoIG5hbWUgaW4gb3B0aW9ucyApIHtcblx0XHRvbGRbIG5hbWUgXSA9IGVsZW0uc3R5bGVbIG5hbWUgXTtcblx0XHRlbGVtLnN0eWxlWyBuYW1lIF0gPSBvcHRpb25zWyBuYW1lIF07XG5cdH1cblxuXHRyZXQgPSBjYWxsYmFjay5jYWxsKCBlbGVtICk7XG5cblx0Ly8gUmV2ZXJ0IHRoZSBvbGQgdmFsdWVzXG5cdGZvciAoIG5hbWUgaW4gb3B0aW9ucyApIHtcblx0XHRlbGVtLnN0eWxlWyBuYW1lIF0gPSBvbGRbIG5hbWUgXTtcblx0fVxuXG5cdHJldHVybiByZXQ7XG59O1xuXG5cbnZhciByYm94U3R5bGUgPSBuZXcgUmVnRXhwKCBjc3NFeHBhbmQuam9pbiggXCJ8XCIgKSwgXCJpXCIgKTtcblxuXG5cbiggZnVuY3Rpb24oKSB7XG5cblx0Ly8gRXhlY3V0aW5nIGJvdGggcGl4ZWxQb3NpdGlvbiAmIGJveFNpemluZ1JlbGlhYmxlIHRlc3RzIHJlcXVpcmUgb25seSBvbmUgbGF5b3V0XG5cdC8vIHNvIHRoZXkncmUgZXhlY3V0ZWQgYXQgdGhlIHNhbWUgdGltZSB0byBzYXZlIHRoZSBzZWNvbmQgY29tcHV0YXRpb24uXG5cdGZ1bmN0aW9uIGNvbXB1dGVTdHlsZVRlc3RzKCkge1xuXG5cdFx0Ly8gVGhpcyBpcyBhIHNpbmdsZXRvbiwgd2UgbmVlZCB0byBleGVjdXRlIGl0IG9ubHkgb25jZVxuXHRcdGlmICggIWRpdiApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRjb250YWluZXIuc3R5bGUuY3NzVGV4dCA9IFwicG9zaXRpb246YWJzb2x1dGU7bGVmdDotMTExMTFweDt3aWR0aDo2MHB4O1wiICtcblx0XHRcdFwibWFyZ2luLXRvcDoxcHg7cGFkZGluZzowO2JvcmRlcjowXCI7XG5cdFx0ZGl2LnN0eWxlLmNzc1RleHQgPVxuXHRcdFx0XCJwb3NpdGlvbjpyZWxhdGl2ZTtkaXNwbGF5OmJsb2NrO2JveC1zaXppbmc6Ym9yZGVyLWJveDtvdmVyZmxvdzpzY3JvbGw7XCIgK1xuXHRcdFx0XCJtYXJnaW46YXV0bztib3JkZXI6MXB4O3BhZGRpbmc6MXB4O1wiICtcblx0XHRcdFwid2lkdGg6NjAlO3RvcDoxJVwiO1xuXHRcdGRvY3VtZW50RWxlbWVudC5hcHBlbmRDaGlsZCggY29udGFpbmVyICkuYXBwZW5kQ2hpbGQoIGRpdiApO1xuXG5cdFx0dmFyIGRpdlN0eWxlID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUoIGRpdiApO1xuXHRcdHBpeGVsUG9zaXRpb25WYWwgPSBkaXZTdHlsZS50b3AgIT09IFwiMSVcIjtcblxuXHRcdC8vIFN1cHBvcnQ6IEFuZHJvaWQgNC4wIC0gNC4zIG9ubHksIEZpcmVmb3ggPD0zIC0gNDRcblx0XHRyZWxpYWJsZU1hcmdpbkxlZnRWYWwgPSByb3VuZFBpeGVsTWVhc3VyZXMoIGRpdlN0eWxlLm1hcmdpbkxlZnQgKSA9PT0gMTI7XG5cblx0XHQvLyBTdXBwb3J0OiBBbmRyb2lkIDQuMCAtIDQuMyBvbmx5LCBTYWZhcmkgPD05LjEgLSAxMC4xLCBpT1MgPD03LjAgLSA5LjNcblx0XHQvLyBTb21lIHN0eWxlcyBjb21lIGJhY2sgd2l0aCBwZXJjZW50YWdlIHZhbHVlcywgZXZlbiB0aG91Z2ggdGhleSBzaG91bGRuJ3Rcblx0XHRkaXYuc3R5bGUucmlnaHQgPSBcIjYwJVwiO1xuXHRcdHBpeGVsQm94U3R5bGVzVmFsID0gcm91bmRQaXhlbE1lYXN1cmVzKCBkaXZTdHlsZS5yaWdodCApID09PSAzNjtcblxuXHRcdC8vIFN1cHBvcnQ6IElFIDkgLSAxMSBvbmx5XG5cdFx0Ly8gRGV0ZWN0IG1pc3JlcG9ydGluZyBvZiBjb250ZW50IGRpbWVuc2lvbnMgZm9yIGJveC1zaXppbmc6Ym9yZGVyLWJveCBlbGVtZW50c1xuXHRcdGJveFNpemluZ1JlbGlhYmxlVmFsID0gcm91bmRQaXhlbE1lYXN1cmVzKCBkaXZTdHlsZS53aWR0aCApID09PSAzNjtcblxuXHRcdC8vIFN1cHBvcnQ6IElFIDkgb25seVxuXHRcdC8vIERldGVjdCBvdmVyZmxvdzpzY3JvbGwgc2NyZXdpbmVzcyAoZ2gtMzY5OSlcblx0XHQvLyBTdXBwb3J0OiBDaHJvbWUgPD02NFxuXHRcdC8vIERvbid0IGdldCB0cmlja2VkIHdoZW4gem9vbSBhZmZlY3RzIG9mZnNldFdpZHRoIChnaC00MDI5KVxuXHRcdGRpdi5zdHlsZS5wb3NpdGlvbiA9IFwiYWJzb2x1dGVcIjtcblx0XHRzY3JvbGxib3hTaXplVmFsID0gcm91bmRQaXhlbE1lYXN1cmVzKCBkaXYub2Zmc2V0V2lkdGggLyAzICkgPT09IDEyO1xuXG5cdFx0ZG9jdW1lbnRFbGVtZW50LnJlbW92ZUNoaWxkKCBjb250YWluZXIgKTtcblxuXHRcdC8vIE51bGxpZnkgdGhlIGRpdiBzbyBpdCB3b3VsZG4ndCBiZSBzdG9yZWQgaW4gdGhlIG1lbW9yeSBhbmRcblx0XHQvLyBpdCB3aWxsIGFsc28gYmUgYSBzaWduIHRoYXQgY2hlY2tzIGFscmVhZHkgcGVyZm9ybWVkXG5cdFx0ZGl2ID0gbnVsbDtcblx0fVxuXG5cdGZ1bmN0aW9uIHJvdW5kUGl4ZWxNZWFzdXJlcyggbWVhc3VyZSApIHtcblx0XHRyZXR1cm4gTWF0aC5yb3VuZCggcGFyc2VGbG9hdCggbWVhc3VyZSApICk7XG5cdH1cblxuXHR2YXIgcGl4ZWxQb3NpdGlvblZhbCwgYm94U2l6aW5nUmVsaWFibGVWYWwsIHNjcm9sbGJveFNpemVWYWwsIHBpeGVsQm94U3R5bGVzVmFsLFxuXHRcdHJlbGlhYmxlVHJEaW1lbnNpb25zVmFsLCByZWxpYWJsZU1hcmdpbkxlZnRWYWwsXG5cdFx0Y29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJkaXZcIiApLFxuXHRcdGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiZGl2XCIgKTtcblxuXHQvLyBGaW5pc2ggZWFybHkgaW4gbGltaXRlZCAobm9uLWJyb3dzZXIpIGVudmlyb25tZW50c1xuXHRpZiAoICFkaXYuc3R5bGUgKSB7XG5cdFx0cmV0dXJuO1xuXHR9XG5cblx0Ly8gU3VwcG9ydDogSUUgPD05IC0gMTEgb25seVxuXHQvLyBTdHlsZSBvZiBjbG9uZWQgZWxlbWVudCBhZmZlY3RzIHNvdXJjZSBlbGVtZW50IGNsb25lZCAoIzg5MDgpXG5cdGRpdi5zdHlsZS5iYWNrZ3JvdW5kQ2xpcCA9IFwiY29udGVudC1ib3hcIjtcblx0ZGl2LmNsb25lTm9kZSggdHJ1ZSApLnN0eWxlLmJhY2tncm91bmRDbGlwID0gXCJcIjtcblx0c3VwcG9ydC5jbGVhckNsb25lU3R5bGUgPSBkaXYuc3R5bGUuYmFja2dyb3VuZENsaXAgPT09IFwiY29udGVudC1ib3hcIjtcblxuXHRqUXVlcnkuZXh0ZW5kKCBzdXBwb3J0LCB7XG5cdFx0Ym94U2l6aW5nUmVsaWFibGU6IGZ1bmN0aW9uKCkge1xuXHRcdFx0Y29tcHV0ZVN0eWxlVGVzdHMoKTtcblx0XHRcdHJldHVybiBib3hTaXppbmdSZWxpYWJsZVZhbDtcblx0XHR9LFxuXHRcdHBpeGVsQm94U3R5bGVzOiBmdW5jdGlvbigpIHtcblx0XHRcdGNvbXB1dGVTdHlsZVRlc3RzKCk7XG5cdFx0XHRyZXR1cm4gcGl4ZWxCb3hTdHlsZXNWYWw7XG5cdFx0fSxcblx0XHRwaXhlbFBvc2l0aW9uOiBmdW5jdGlvbigpIHtcblx0XHRcdGNvbXB1dGVTdHlsZVRlc3RzKCk7XG5cdFx0XHRyZXR1cm4gcGl4ZWxQb3NpdGlvblZhbDtcblx0XHR9LFxuXHRcdHJlbGlhYmxlTWFyZ2luTGVmdDogZnVuY3Rpb24oKSB7XG5cdFx0XHRjb21wdXRlU3R5bGVUZXN0cygpO1xuXHRcdFx0cmV0dXJuIHJlbGlhYmxlTWFyZ2luTGVmdFZhbDtcblx0XHR9LFxuXHRcdHNjcm9sbGJveFNpemU6IGZ1bmN0aW9uKCkge1xuXHRcdFx0Y29tcHV0ZVN0eWxlVGVzdHMoKTtcblx0XHRcdHJldHVybiBzY3JvbGxib3hTaXplVmFsO1xuXHRcdH0sXG5cblx0XHQvLyBTdXBwb3J0OiBJRSA5IC0gMTErLCBFZGdlIDE1IC0gMTgrXG5cdFx0Ly8gSUUvRWRnZSBtaXNyZXBvcnQgYGdldENvbXB1dGVkU3R5bGVgIG9mIHRhYmxlIHJvd3Mgd2l0aCB3aWR0aC9oZWlnaHRcblx0XHQvLyBzZXQgaW4gQ1NTIHdoaWxlIGBvZmZzZXQqYCBwcm9wZXJ0aWVzIHJlcG9ydCBjb3JyZWN0IHZhbHVlcy5cblx0XHQvLyBCZWhhdmlvciBpbiBJRSA5IGlzIG1vcmUgc3VidGxlIHRoYW4gaW4gbmV3ZXIgdmVyc2lvbnMgJiBpdCBwYXNzZXNcblx0XHQvLyBzb21lIHZlcnNpb25zIG9mIHRoaXMgdGVzdDsgbWFrZSBzdXJlIG5vdCB0byBtYWtlIGl0IHBhc3MgdGhlcmUhXG5cdFx0Ly9cblx0XHQvLyBTdXBwb3J0OiBGaXJlZm94IDcwK1xuXHRcdC8vIE9ubHkgRmlyZWZveCBpbmNsdWRlcyBib3JkZXIgd2lkdGhzXG5cdFx0Ly8gaW4gY29tcHV0ZWQgZGltZW5zaW9ucy4gKGdoLTQ1MjkpXG5cdFx0cmVsaWFibGVUckRpbWVuc2lvbnM6IGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIHRhYmxlLCB0ciwgdHJDaGlsZCwgdHJTdHlsZTtcblx0XHRcdGlmICggcmVsaWFibGVUckRpbWVuc2lvbnNWYWwgPT0gbnVsbCApIHtcblx0XHRcdFx0dGFibGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcInRhYmxlXCIgKTtcblx0XHRcdFx0dHIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcInRyXCIgKTtcblx0XHRcdFx0dHJDaGlsZCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiZGl2XCIgKTtcblxuXHRcdFx0XHR0YWJsZS5zdHlsZS5jc3NUZXh0ID0gXCJwb3NpdGlvbjphYnNvbHV0ZTtsZWZ0Oi0xMTExMXB4O2JvcmRlci1jb2xsYXBzZTpzZXBhcmF0ZVwiO1xuXHRcdFx0XHR0ci5zdHlsZS5jc3NUZXh0ID0gXCJib3JkZXI6MXB4IHNvbGlkXCI7XG5cblx0XHRcdFx0Ly8gU3VwcG9ydDogQ2hyb21lIDg2K1xuXHRcdFx0XHQvLyBIZWlnaHQgc2V0IHRocm91Z2ggY3NzVGV4dCBkb2VzIG5vdCBnZXQgYXBwbGllZC5cblx0XHRcdFx0Ly8gQ29tcHV0ZWQgaGVpZ2h0IHRoZW4gY29tZXMgYmFjayBhcyAwLlxuXHRcdFx0XHR0ci5zdHlsZS5oZWlnaHQgPSBcIjFweFwiO1xuXHRcdFx0XHR0ckNoaWxkLnN0eWxlLmhlaWdodCA9IFwiOXB4XCI7XG5cblx0XHRcdFx0Ly8gU3VwcG9ydDogQW5kcm9pZCA4IENocm9tZSA4Nitcblx0XHRcdFx0Ly8gSW4gb3VyIGJvZHlCYWNrZ3JvdW5kLmh0bWwgaWZyYW1lLFxuXHRcdFx0XHQvLyBkaXNwbGF5IGZvciBhbGwgZGl2IGVsZW1lbnRzIGlzIHNldCB0byBcImlubGluZVwiLFxuXHRcdFx0XHQvLyB3aGljaCBjYXVzZXMgYSBwcm9ibGVtIG9ubHkgaW4gQW5kcm9pZCA4IENocm9tZSA4Ni5cblx0XHRcdFx0Ly8gRW5zdXJpbmcgdGhlIGRpdiBpcyBkaXNwbGF5OiBibG9ja1xuXHRcdFx0XHQvLyBnZXRzIGFyb3VuZCB0aGlzIGlzc3VlLlxuXHRcdFx0XHR0ckNoaWxkLnN0eWxlLmRpc3BsYXkgPSBcImJsb2NrXCI7XG5cblx0XHRcdFx0ZG9jdW1lbnRFbGVtZW50XG5cdFx0XHRcdFx0LmFwcGVuZENoaWxkKCB0YWJsZSApXG5cdFx0XHRcdFx0LmFwcGVuZENoaWxkKCB0ciApXG5cdFx0XHRcdFx0LmFwcGVuZENoaWxkKCB0ckNoaWxkICk7XG5cblx0XHRcdFx0dHJTdHlsZSA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKCB0ciApO1xuXHRcdFx0XHRyZWxpYWJsZVRyRGltZW5zaW9uc1ZhbCA9ICggcGFyc2VJbnQoIHRyU3R5bGUuaGVpZ2h0LCAxMCApICtcblx0XHRcdFx0XHRwYXJzZUludCggdHJTdHlsZS5ib3JkZXJUb3BXaWR0aCwgMTAgKSArXG5cdFx0XHRcdFx0cGFyc2VJbnQoIHRyU3R5bGUuYm9yZGVyQm90dG9tV2lkdGgsIDEwICkgKSA9PT0gdHIub2Zmc2V0SGVpZ2h0O1xuXG5cdFx0XHRcdGRvY3VtZW50RWxlbWVudC5yZW1vdmVDaGlsZCggdGFibGUgKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiByZWxpYWJsZVRyRGltZW5zaW9uc1ZhbDtcblx0XHR9XG5cdH0gKTtcbn0gKSgpO1xuXG5cbmZ1bmN0aW9uIGN1ckNTUyggZWxlbSwgbmFtZSwgY29tcHV0ZWQgKSB7XG5cdHZhciB3aWR0aCwgbWluV2lkdGgsIG1heFdpZHRoLCByZXQsXG5cblx0XHQvLyBTdXBwb3J0OiBGaXJlZm94IDUxK1xuXHRcdC8vIFJldHJpZXZpbmcgc3R5bGUgYmVmb3JlIGNvbXB1dGVkIHNvbWVob3dcblx0XHQvLyBmaXhlcyBhbiBpc3N1ZSB3aXRoIGdldHRpbmcgd3JvbmcgdmFsdWVzXG5cdFx0Ly8gb24gZGV0YWNoZWQgZWxlbWVudHNcblx0XHRzdHlsZSA9IGVsZW0uc3R5bGU7XG5cblx0Y29tcHV0ZWQgPSBjb21wdXRlZCB8fCBnZXRTdHlsZXMoIGVsZW0gKTtcblxuXHQvLyBnZXRQcm9wZXJ0eVZhbHVlIGlzIG5lZWRlZCBmb3I6XG5cdC8vICAgLmNzcygnZmlsdGVyJykgKElFIDkgb25seSwgIzEyNTM3KVxuXHQvLyAgIC5jc3MoJy0tY3VzdG9tUHJvcGVydHkpICgjMzE0NClcblx0aWYgKCBjb21wdXRlZCApIHtcblx0XHRyZXQgPSBjb21wdXRlZC5nZXRQcm9wZXJ0eVZhbHVlKCBuYW1lICkgfHwgY29tcHV0ZWRbIG5hbWUgXTtcblxuXHRcdGlmICggcmV0ID09PSBcIlwiICYmICFpc0F0dGFjaGVkKCBlbGVtICkgKSB7XG5cdFx0XHRyZXQgPSBqUXVlcnkuc3R5bGUoIGVsZW0sIG5hbWUgKTtcblx0XHR9XG5cblx0XHQvLyBBIHRyaWJ1dGUgdG8gdGhlIFwiYXdlc29tZSBoYWNrIGJ5IERlYW4gRWR3YXJkc1wiXG5cdFx0Ly8gQW5kcm9pZCBCcm93c2VyIHJldHVybnMgcGVyY2VudGFnZSBmb3Igc29tZSB2YWx1ZXMsXG5cdFx0Ly8gYnV0IHdpZHRoIHNlZW1zIHRvIGJlIHJlbGlhYmx5IHBpeGVscy5cblx0XHQvLyBUaGlzIGlzIGFnYWluc3QgdGhlIENTU09NIGRyYWZ0IHNwZWM6XG5cdFx0Ly8gaHR0cHM6Ly9kcmFmdHMuY3Nzd2cub3JnL2Nzc29tLyNyZXNvbHZlZC12YWx1ZXNcblx0XHRpZiAoICFzdXBwb3J0LnBpeGVsQm94U3R5bGVzKCkgJiYgcm51bW5vbnB4LnRlc3QoIHJldCApICYmIHJib3hTdHlsZS50ZXN0KCBuYW1lICkgKSB7XG5cblx0XHRcdC8vIFJlbWVtYmVyIHRoZSBvcmlnaW5hbCB2YWx1ZXNcblx0XHRcdHdpZHRoID0gc3R5bGUud2lkdGg7XG5cdFx0XHRtaW5XaWR0aCA9IHN0eWxlLm1pbldpZHRoO1xuXHRcdFx0bWF4V2lkdGggPSBzdHlsZS5tYXhXaWR0aDtcblxuXHRcdFx0Ly8gUHV0IGluIHRoZSBuZXcgdmFsdWVzIHRvIGdldCBhIGNvbXB1dGVkIHZhbHVlIG91dFxuXHRcdFx0c3R5bGUubWluV2lkdGggPSBzdHlsZS5tYXhXaWR0aCA9IHN0eWxlLndpZHRoID0gcmV0O1xuXHRcdFx0cmV0ID0gY29tcHV0ZWQud2lkdGg7XG5cblx0XHRcdC8vIFJldmVydCB0aGUgY2hhbmdlZCB2YWx1ZXNcblx0XHRcdHN0eWxlLndpZHRoID0gd2lkdGg7XG5cdFx0XHRzdHlsZS5taW5XaWR0aCA9IG1pbldpZHRoO1xuXHRcdFx0c3R5bGUubWF4V2lkdGggPSBtYXhXaWR0aDtcblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gcmV0ICE9PSB1bmRlZmluZWQgP1xuXG5cdFx0Ly8gU3VwcG9ydDogSUUgPD05IC0gMTEgb25seVxuXHRcdC8vIElFIHJldHVybnMgekluZGV4IHZhbHVlIGFzIGFuIGludGVnZXIuXG5cdFx0cmV0ICsgXCJcIiA6XG5cdFx0cmV0O1xufVxuXG5cbmZ1bmN0aW9uIGFkZEdldEhvb2tJZiggY29uZGl0aW9uRm4sIGhvb2tGbiApIHtcblxuXHQvLyBEZWZpbmUgdGhlIGhvb2ssIHdlJ2xsIGNoZWNrIG9uIHRoZSBmaXJzdCBydW4gaWYgaXQncyByZWFsbHkgbmVlZGVkLlxuXHRyZXR1cm4ge1xuXHRcdGdldDogZnVuY3Rpb24oKSB7XG5cdFx0XHRpZiAoIGNvbmRpdGlvbkZuKCkgKSB7XG5cblx0XHRcdFx0Ly8gSG9vayBub3QgbmVlZGVkIChvciBpdCdzIG5vdCBwb3NzaWJsZSB0byB1c2UgaXQgZHVlXG5cdFx0XHRcdC8vIHRvIG1pc3NpbmcgZGVwZW5kZW5jeSksIHJlbW92ZSBpdC5cblx0XHRcdFx0ZGVsZXRlIHRoaXMuZ2V0O1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdC8vIEhvb2sgbmVlZGVkOyByZWRlZmluZSBpdCBzbyB0aGF0IHRoZSBzdXBwb3J0IHRlc3QgaXMgbm90IGV4ZWN1dGVkIGFnYWluLlxuXHRcdFx0cmV0dXJuICggdGhpcy5nZXQgPSBob29rRm4gKS5hcHBseSggdGhpcywgYXJndW1lbnRzICk7XG5cdFx0fVxuXHR9O1xufVxuXG5cbnZhciBjc3NQcmVmaXhlcyA9IFsgXCJXZWJraXRcIiwgXCJNb3pcIiwgXCJtc1wiIF0sXG5cdGVtcHR5U3R5bGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImRpdlwiICkuc3R5bGUsXG5cdHZlbmRvclByb3BzID0ge307XG5cbi8vIFJldHVybiBhIHZlbmRvci1wcmVmaXhlZCBwcm9wZXJ0eSBvciB1bmRlZmluZWRcbmZ1bmN0aW9uIHZlbmRvclByb3BOYW1lKCBuYW1lICkge1xuXG5cdC8vIENoZWNrIGZvciB2ZW5kb3IgcHJlZml4ZWQgbmFtZXNcblx0dmFyIGNhcE5hbWUgPSBuYW1lWyAwIF0udG9VcHBlckNhc2UoKSArIG5hbWUuc2xpY2UoIDEgKSxcblx0XHRpID0gY3NzUHJlZml4ZXMubGVuZ3RoO1xuXG5cdHdoaWxlICggaS0tICkge1xuXHRcdG5hbWUgPSBjc3NQcmVmaXhlc1sgaSBdICsgY2FwTmFtZTtcblx0XHRpZiAoIG5hbWUgaW4gZW1wdHlTdHlsZSApIHtcblx0XHRcdHJldHVybiBuYW1lO1xuXHRcdH1cblx0fVxufVxuXG4vLyBSZXR1cm4gYSBwb3RlbnRpYWxseS1tYXBwZWQgalF1ZXJ5LmNzc1Byb3BzIG9yIHZlbmRvciBwcmVmaXhlZCBwcm9wZXJ0eVxuZnVuY3Rpb24gZmluYWxQcm9wTmFtZSggbmFtZSApIHtcblx0dmFyIGZpbmFsID0galF1ZXJ5LmNzc1Byb3BzWyBuYW1lIF0gfHwgdmVuZG9yUHJvcHNbIG5hbWUgXTtcblxuXHRpZiAoIGZpbmFsICkge1xuXHRcdHJldHVybiBmaW5hbDtcblx0fVxuXHRpZiAoIG5hbWUgaW4gZW1wdHlTdHlsZSApIHtcblx0XHRyZXR1cm4gbmFtZTtcblx0fVxuXHRyZXR1cm4gdmVuZG9yUHJvcHNbIG5hbWUgXSA9IHZlbmRvclByb3BOYW1lKCBuYW1lICkgfHwgbmFtZTtcbn1cblxuXG52YXJcblxuXHQvLyBTd2FwcGFibGUgaWYgZGlzcGxheSBpcyBub25lIG9yIHN0YXJ0cyB3aXRoIHRhYmxlXG5cdC8vIGV4Y2VwdCBcInRhYmxlXCIsIFwidGFibGUtY2VsbFwiLCBvciBcInRhYmxlLWNhcHRpb25cIlxuXHQvLyBTZWUgaGVyZSBmb3IgZGlzcGxheSB2YWx1ZXM6IGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvQ1NTL2Rpc3BsYXlcblx0cmRpc3BsYXlzd2FwID0gL14obm9uZXx0YWJsZSg/IS1jW2VhXSkuKykvLFxuXHRyY3VzdG9tUHJvcCA9IC9eLS0vLFxuXHRjc3NTaG93ID0geyBwb3NpdGlvbjogXCJhYnNvbHV0ZVwiLCB2aXNpYmlsaXR5OiBcImhpZGRlblwiLCBkaXNwbGF5OiBcImJsb2NrXCIgfSxcblx0Y3NzTm9ybWFsVHJhbnNmb3JtID0ge1xuXHRcdGxldHRlclNwYWNpbmc6IFwiMFwiLFxuXHRcdGZvbnRXZWlnaHQ6IFwiNDAwXCJcblx0fTtcblxuZnVuY3Rpb24gc2V0UG9zaXRpdmVOdW1iZXIoIF9lbGVtLCB2YWx1ZSwgc3VidHJhY3QgKSB7XG5cblx0Ly8gQW55IHJlbGF0aXZlICgrLy0pIHZhbHVlcyBoYXZlIGFscmVhZHkgYmVlblxuXHQvLyBub3JtYWxpemVkIGF0IHRoaXMgcG9pbnRcblx0dmFyIG1hdGNoZXMgPSByY3NzTnVtLmV4ZWMoIHZhbHVlICk7XG5cdHJldHVybiBtYXRjaGVzID9cblxuXHRcdC8vIEd1YXJkIGFnYWluc3QgdW5kZWZpbmVkIFwic3VidHJhY3RcIiwgZS5nLiwgd2hlbiB1c2VkIGFzIGluIGNzc0hvb2tzXG5cdFx0TWF0aC5tYXgoIDAsIG1hdGNoZXNbIDIgXSAtICggc3VidHJhY3QgfHwgMCApICkgKyAoIG1hdGNoZXNbIDMgXSB8fCBcInB4XCIgKSA6XG5cdFx0dmFsdWU7XG59XG5cbmZ1bmN0aW9uIGJveE1vZGVsQWRqdXN0bWVudCggZWxlbSwgZGltZW5zaW9uLCBib3gsIGlzQm9yZGVyQm94LCBzdHlsZXMsIGNvbXB1dGVkVmFsICkge1xuXHR2YXIgaSA9IGRpbWVuc2lvbiA9PT0gXCJ3aWR0aFwiID8gMSA6IDAsXG5cdFx0ZXh0cmEgPSAwLFxuXHRcdGRlbHRhID0gMDtcblxuXHQvLyBBZGp1c3RtZW50IG1heSBub3QgYmUgbmVjZXNzYXJ5XG5cdGlmICggYm94ID09PSAoIGlzQm9yZGVyQm94ID8gXCJib3JkZXJcIiA6IFwiY29udGVudFwiICkgKSB7XG5cdFx0cmV0dXJuIDA7XG5cdH1cblxuXHRmb3IgKCA7IGkgPCA0OyBpICs9IDIgKSB7XG5cblx0XHQvLyBCb3RoIGJveCBtb2RlbHMgZXhjbHVkZSBtYXJnaW5cblx0XHRpZiAoIGJveCA9PT0gXCJtYXJnaW5cIiApIHtcblx0XHRcdGRlbHRhICs9IGpRdWVyeS5jc3MoIGVsZW0sIGJveCArIGNzc0V4cGFuZFsgaSBdLCB0cnVlLCBzdHlsZXMgKTtcblx0XHR9XG5cblx0XHQvLyBJZiB3ZSBnZXQgaGVyZSB3aXRoIGEgY29udGVudC1ib3gsIHdlJ3JlIHNlZWtpbmcgXCJwYWRkaW5nXCIgb3IgXCJib3JkZXJcIiBvciBcIm1hcmdpblwiXG5cdFx0aWYgKCAhaXNCb3JkZXJCb3ggKSB7XG5cblx0XHRcdC8vIEFkZCBwYWRkaW5nXG5cdFx0XHRkZWx0YSArPSBqUXVlcnkuY3NzKCBlbGVtLCBcInBhZGRpbmdcIiArIGNzc0V4cGFuZFsgaSBdLCB0cnVlLCBzdHlsZXMgKTtcblxuXHRcdFx0Ly8gRm9yIFwiYm9yZGVyXCIgb3IgXCJtYXJnaW5cIiwgYWRkIGJvcmRlclxuXHRcdFx0aWYgKCBib3ggIT09IFwicGFkZGluZ1wiICkge1xuXHRcdFx0XHRkZWx0YSArPSBqUXVlcnkuY3NzKCBlbGVtLCBcImJvcmRlclwiICsgY3NzRXhwYW5kWyBpIF0gKyBcIldpZHRoXCIsIHRydWUsIHN0eWxlcyApO1xuXG5cdFx0XHQvLyBCdXQgc3RpbGwga2VlcCB0cmFjayBvZiBpdCBvdGhlcndpc2Vcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGV4dHJhICs9IGpRdWVyeS5jc3MoIGVsZW0sIFwiYm9yZGVyXCIgKyBjc3NFeHBhbmRbIGkgXSArIFwiV2lkdGhcIiwgdHJ1ZSwgc3R5bGVzICk7XG5cdFx0XHR9XG5cblx0XHQvLyBJZiB3ZSBnZXQgaGVyZSB3aXRoIGEgYm9yZGVyLWJveCAoY29udGVudCArIHBhZGRpbmcgKyBib3JkZXIpLCB3ZSdyZSBzZWVraW5nIFwiY29udGVudFwiIG9yXG5cdFx0Ly8gXCJwYWRkaW5nXCIgb3IgXCJtYXJnaW5cIlxuXHRcdH0gZWxzZSB7XG5cblx0XHRcdC8vIEZvciBcImNvbnRlbnRcIiwgc3VidHJhY3QgcGFkZGluZ1xuXHRcdFx0aWYgKCBib3ggPT09IFwiY29udGVudFwiICkge1xuXHRcdFx0XHRkZWx0YSAtPSBqUXVlcnkuY3NzKCBlbGVtLCBcInBhZGRpbmdcIiArIGNzc0V4cGFuZFsgaSBdLCB0cnVlLCBzdHlsZXMgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gRm9yIFwiY29udGVudFwiIG9yIFwicGFkZGluZ1wiLCBzdWJ0cmFjdCBib3JkZXJcblx0XHRcdGlmICggYm94ICE9PSBcIm1hcmdpblwiICkge1xuXHRcdFx0XHRkZWx0YSAtPSBqUXVlcnkuY3NzKCBlbGVtLCBcImJvcmRlclwiICsgY3NzRXhwYW5kWyBpIF0gKyBcIldpZHRoXCIsIHRydWUsIHN0eWxlcyApO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC8vIEFjY291bnQgZm9yIHBvc2l0aXZlIGNvbnRlbnQtYm94IHNjcm9sbCBndXR0ZXIgd2hlbiByZXF1ZXN0ZWQgYnkgcHJvdmlkaW5nIGNvbXB1dGVkVmFsXG5cdGlmICggIWlzQm9yZGVyQm94ICYmIGNvbXB1dGVkVmFsID49IDAgKSB7XG5cblx0XHQvLyBvZmZzZXRXaWR0aC9vZmZzZXRIZWlnaHQgaXMgYSByb3VuZGVkIHN1bSBvZiBjb250ZW50LCBwYWRkaW5nLCBzY3JvbGwgZ3V0dGVyLCBhbmQgYm9yZGVyXG5cdFx0Ly8gQXNzdW1pbmcgaW50ZWdlciBzY3JvbGwgZ3V0dGVyLCBzdWJ0cmFjdCB0aGUgcmVzdCBhbmQgcm91bmQgZG93blxuXHRcdGRlbHRhICs9IE1hdGgubWF4KCAwLCBNYXRoLmNlaWwoXG5cdFx0XHRlbGVtWyBcIm9mZnNldFwiICsgZGltZW5zaW9uWyAwIF0udG9VcHBlckNhc2UoKSArIGRpbWVuc2lvbi5zbGljZSggMSApIF0gLVxuXHRcdFx0Y29tcHV0ZWRWYWwgLVxuXHRcdFx0ZGVsdGEgLVxuXHRcdFx0ZXh0cmEgLVxuXHRcdFx0MC41XG5cblx0XHQvLyBJZiBvZmZzZXRXaWR0aC9vZmZzZXRIZWlnaHQgaXMgdW5rbm93biwgdGhlbiB3ZSBjYW4ndCBkZXRlcm1pbmUgY29udGVudC1ib3ggc2Nyb2xsIGd1dHRlclxuXHRcdC8vIFVzZSBhbiBleHBsaWNpdCB6ZXJvIHRvIGF2b2lkIE5hTiAoZ2gtMzk2NClcblx0XHQpICkgfHwgMDtcblx0fVxuXG5cdHJldHVybiBkZWx0YTtcbn1cblxuZnVuY3Rpb24gZ2V0V2lkdGhPckhlaWdodCggZWxlbSwgZGltZW5zaW9uLCBleHRyYSApIHtcblxuXHQvLyBTdGFydCB3aXRoIGNvbXB1dGVkIHN0eWxlXG5cdHZhciBzdHlsZXMgPSBnZXRTdHlsZXMoIGVsZW0gKSxcblxuXHRcdC8vIFRvIGF2b2lkIGZvcmNpbmcgYSByZWZsb3csIG9ubHkgZmV0Y2ggYm94U2l6aW5nIGlmIHdlIG5lZWQgaXQgKGdoLTQzMjIpLlxuXHRcdC8vIEZha2UgY29udGVudC1ib3ggdW50aWwgd2Uga25vdyBpdCdzIG5lZWRlZCB0byBrbm93IHRoZSB0cnVlIHZhbHVlLlxuXHRcdGJveFNpemluZ05lZWRlZCA9ICFzdXBwb3J0LmJveFNpemluZ1JlbGlhYmxlKCkgfHwgZXh0cmEsXG5cdFx0aXNCb3JkZXJCb3ggPSBib3hTaXppbmdOZWVkZWQgJiZcblx0XHRcdGpRdWVyeS5jc3MoIGVsZW0sIFwiYm94U2l6aW5nXCIsIGZhbHNlLCBzdHlsZXMgKSA9PT0gXCJib3JkZXItYm94XCIsXG5cdFx0dmFsdWVJc0JvcmRlckJveCA9IGlzQm9yZGVyQm94LFxuXG5cdFx0dmFsID0gY3VyQ1NTKCBlbGVtLCBkaW1lbnNpb24sIHN0eWxlcyApLFxuXHRcdG9mZnNldFByb3AgPSBcIm9mZnNldFwiICsgZGltZW5zaW9uWyAwIF0udG9VcHBlckNhc2UoKSArIGRpbWVuc2lvbi5zbGljZSggMSApO1xuXG5cdC8vIFN1cHBvcnQ6IEZpcmVmb3ggPD01NFxuXHQvLyBSZXR1cm4gYSBjb25mb3VuZGluZyBub24tcGl4ZWwgdmFsdWUgb3IgZmVpZ24gaWdub3JhbmNlLCBhcyBhcHByb3ByaWF0ZS5cblx0aWYgKCBybnVtbm9ucHgudGVzdCggdmFsICkgKSB7XG5cdFx0aWYgKCAhZXh0cmEgKSB7XG5cdFx0XHRyZXR1cm4gdmFsO1xuXHRcdH1cblx0XHR2YWwgPSBcImF1dG9cIjtcblx0fVxuXG5cblx0Ly8gU3VwcG9ydDogSUUgOSAtIDExIG9ubHlcblx0Ly8gVXNlIG9mZnNldFdpZHRoL29mZnNldEhlaWdodCBmb3Igd2hlbiBib3ggc2l6aW5nIGlzIHVucmVsaWFibGUuXG5cdC8vIEluIHRob3NlIGNhc2VzLCB0aGUgY29tcHV0ZWQgdmFsdWUgY2FuIGJlIHRydXN0ZWQgdG8gYmUgYm9yZGVyLWJveC5cblx0aWYgKCAoICFzdXBwb3J0LmJveFNpemluZ1JlbGlhYmxlKCkgJiYgaXNCb3JkZXJCb3ggfHxcblxuXHRcdC8vIFN1cHBvcnQ6IElFIDEwIC0gMTErLCBFZGdlIDE1IC0gMTgrXG5cdFx0Ly8gSUUvRWRnZSBtaXNyZXBvcnQgYGdldENvbXB1dGVkU3R5bGVgIG9mIHRhYmxlIHJvd3Mgd2l0aCB3aWR0aC9oZWlnaHRcblx0XHQvLyBzZXQgaW4gQ1NTIHdoaWxlIGBvZmZzZXQqYCBwcm9wZXJ0aWVzIHJlcG9ydCBjb3JyZWN0IHZhbHVlcy5cblx0XHQvLyBJbnRlcmVzdGluZ2x5LCBpbiBzb21lIGNhc2VzIElFIDkgZG9lc24ndCBzdWZmZXIgZnJvbSB0aGlzIGlzc3VlLlxuXHRcdCFzdXBwb3J0LnJlbGlhYmxlVHJEaW1lbnNpb25zKCkgJiYgbm9kZU5hbWUoIGVsZW0sIFwidHJcIiApIHx8XG5cblx0XHQvLyBGYWxsIGJhY2sgdG8gb2Zmc2V0V2lkdGgvb2Zmc2V0SGVpZ2h0IHdoZW4gdmFsdWUgaXMgXCJhdXRvXCJcblx0XHQvLyBUaGlzIGhhcHBlbnMgZm9yIGlubGluZSBlbGVtZW50cyB3aXRoIG5vIGV4cGxpY2l0IHNldHRpbmcgKGdoLTM1NzEpXG5cdFx0dmFsID09PSBcImF1dG9cIiB8fFxuXG5cdFx0Ly8gU3VwcG9ydDogQW5kcm9pZCA8PTQuMSAtIDQuMyBvbmx5XG5cdFx0Ly8gQWxzbyB1c2Ugb2Zmc2V0V2lkdGgvb2Zmc2V0SGVpZ2h0IGZvciBtaXNyZXBvcnRlZCBpbmxpbmUgZGltZW5zaW9ucyAoZ2gtMzYwMilcblx0XHQhcGFyc2VGbG9hdCggdmFsICkgJiYgalF1ZXJ5LmNzcyggZWxlbSwgXCJkaXNwbGF5XCIsIGZhbHNlLCBzdHlsZXMgKSA9PT0gXCJpbmxpbmVcIiApICYmXG5cblx0XHQvLyBNYWtlIHN1cmUgdGhlIGVsZW1lbnQgaXMgdmlzaWJsZSAmIGNvbm5lY3RlZFxuXHRcdGVsZW0uZ2V0Q2xpZW50UmVjdHMoKS5sZW5ndGggKSB7XG5cblx0XHRpc0JvcmRlckJveCA9IGpRdWVyeS5jc3MoIGVsZW0sIFwiYm94U2l6aW5nXCIsIGZhbHNlLCBzdHlsZXMgKSA9PT0gXCJib3JkZXItYm94XCI7XG5cblx0XHQvLyBXaGVyZSBhdmFpbGFibGUsIG9mZnNldFdpZHRoL29mZnNldEhlaWdodCBhcHByb3hpbWF0ZSBib3JkZXIgYm94IGRpbWVuc2lvbnMuXG5cdFx0Ly8gV2hlcmUgbm90IGF2YWlsYWJsZSAoZS5nLiwgU1ZHKSwgYXNzdW1lIHVucmVsaWFibGUgYm94LXNpemluZyBhbmQgaW50ZXJwcmV0IHRoZVxuXHRcdC8vIHJldHJpZXZlZCB2YWx1ZSBhcyBhIGNvbnRlbnQgYm94IGRpbWVuc2lvbi5cblx0XHR2YWx1ZUlzQm9yZGVyQm94ID0gb2Zmc2V0UHJvcCBpbiBlbGVtO1xuXHRcdGlmICggdmFsdWVJc0JvcmRlckJveCApIHtcblx0XHRcdHZhbCA9IGVsZW1bIG9mZnNldFByb3AgXTtcblx0XHR9XG5cdH1cblxuXHQvLyBOb3JtYWxpemUgXCJcIiBhbmQgYXV0b1xuXHR2YWwgPSBwYXJzZUZsb2F0KCB2YWwgKSB8fCAwO1xuXG5cdC8vIEFkanVzdCBmb3IgdGhlIGVsZW1lbnQncyBib3ggbW9kZWxcblx0cmV0dXJuICggdmFsICtcblx0XHRib3hNb2RlbEFkanVzdG1lbnQoXG5cdFx0XHRlbGVtLFxuXHRcdFx0ZGltZW5zaW9uLFxuXHRcdFx0ZXh0cmEgfHwgKCBpc0JvcmRlckJveCA/IFwiYm9yZGVyXCIgOiBcImNvbnRlbnRcIiApLFxuXHRcdFx0dmFsdWVJc0JvcmRlckJveCxcblx0XHRcdHN0eWxlcyxcblxuXHRcdFx0Ly8gUHJvdmlkZSB0aGUgY3VycmVudCBjb21wdXRlZCBzaXplIHRvIHJlcXVlc3Qgc2Nyb2xsIGd1dHRlciBjYWxjdWxhdGlvbiAoZ2gtMzU4OSlcblx0XHRcdHZhbFxuXHRcdClcblx0KSArIFwicHhcIjtcbn1cblxualF1ZXJ5LmV4dGVuZCgge1xuXG5cdC8vIEFkZCBpbiBzdHlsZSBwcm9wZXJ0eSBob29rcyBmb3Igb3ZlcnJpZGluZyB0aGUgZGVmYXVsdFxuXHQvLyBiZWhhdmlvciBvZiBnZXR0aW5nIGFuZCBzZXR0aW5nIGEgc3R5bGUgcHJvcGVydHlcblx0Y3NzSG9va3M6IHtcblx0XHRvcGFjaXR5OiB7XG5cdFx0XHRnZXQ6IGZ1bmN0aW9uKCBlbGVtLCBjb21wdXRlZCApIHtcblx0XHRcdFx0aWYgKCBjb21wdXRlZCApIHtcblxuXHRcdFx0XHRcdC8vIFdlIHNob3VsZCBhbHdheXMgZ2V0IGEgbnVtYmVyIGJhY2sgZnJvbSBvcGFjaXR5XG5cdFx0XHRcdFx0dmFyIHJldCA9IGN1ckNTUyggZWxlbSwgXCJvcGFjaXR5XCIgKTtcblx0XHRcdFx0XHRyZXR1cm4gcmV0ID09PSBcIlwiID8gXCIxXCIgOiByZXQ7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH0sXG5cblx0Ly8gRG9uJ3QgYXV0b21hdGljYWxseSBhZGQgXCJweFwiIHRvIHRoZXNlIHBvc3NpYmx5LXVuaXRsZXNzIHByb3BlcnRpZXNcblx0Y3NzTnVtYmVyOiB7XG5cdFx0XCJhbmltYXRpb25JdGVyYXRpb25Db3VudFwiOiB0cnVlLFxuXHRcdFwiY29sdW1uQ291bnRcIjogdHJ1ZSxcblx0XHRcImZpbGxPcGFjaXR5XCI6IHRydWUsXG5cdFx0XCJmbGV4R3Jvd1wiOiB0cnVlLFxuXHRcdFwiZmxleFNocmlua1wiOiB0cnVlLFxuXHRcdFwiZm9udFdlaWdodFwiOiB0cnVlLFxuXHRcdFwiZ3JpZEFyZWFcIjogdHJ1ZSxcblx0XHRcImdyaWRDb2x1bW5cIjogdHJ1ZSxcblx0XHRcImdyaWRDb2x1bW5FbmRcIjogdHJ1ZSxcblx0XHRcImdyaWRDb2x1bW5TdGFydFwiOiB0cnVlLFxuXHRcdFwiZ3JpZFJvd1wiOiB0cnVlLFxuXHRcdFwiZ3JpZFJvd0VuZFwiOiB0cnVlLFxuXHRcdFwiZ3JpZFJvd1N0YXJ0XCI6IHRydWUsXG5cdFx0XCJsaW5lSGVpZ2h0XCI6IHRydWUsXG5cdFx0XCJvcGFjaXR5XCI6IHRydWUsXG5cdFx0XCJvcmRlclwiOiB0cnVlLFxuXHRcdFwib3JwaGFuc1wiOiB0cnVlLFxuXHRcdFwid2lkb3dzXCI6IHRydWUsXG5cdFx0XCJ6SW5kZXhcIjogdHJ1ZSxcblx0XHRcInpvb21cIjogdHJ1ZVxuXHR9LFxuXG5cdC8vIEFkZCBpbiBwcm9wZXJ0aWVzIHdob3NlIG5hbWVzIHlvdSB3aXNoIHRvIGZpeCBiZWZvcmVcblx0Ly8gc2V0dGluZyBvciBnZXR0aW5nIHRoZSB2YWx1ZVxuXHRjc3NQcm9wczoge30sXG5cblx0Ly8gR2V0IGFuZCBzZXQgdGhlIHN0eWxlIHByb3BlcnR5IG9uIGEgRE9NIE5vZGVcblx0c3R5bGU6IGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCB2YWx1ZSwgZXh0cmEgKSB7XG5cblx0XHQvLyBEb24ndCBzZXQgc3R5bGVzIG9uIHRleHQgYW5kIGNvbW1lbnQgbm9kZXNcblx0XHRpZiAoICFlbGVtIHx8IGVsZW0ubm9kZVR5cGUgPT09IDMgfHwgZWxlbS5ub2RlVHlwZSA9PT0gOCB8fCAhZWxlbS5zdHlsZSApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBNYWtlIHN1cmUgdGhhdCB3ZSdyZSB3b3JraW5nIHdpdGggdGhlIHJpZ2h0IG5hbWVcblx0XHR2YXIgcmV0LCB0eXBlLCBob29rcyxcblx0XHRcdG9yaWdOYW1lID0gY2FtZWxDYXNlKCBuYW1lICksXG5cdFx0XHRpc0N1c3RvbVByb3AgPSByY3VzdG9tUHJvcC50ZXN0KCBuYW1lICksXG5cdFx0XHRzdHlsZSA9IGVsZW0uc3R5bGU7XG5cblx0XHQvLyBNYWtlIHN1cmUgdGhhdCB3ZSdyZSB3b3JraW5nIHdpdGggdGhlIHJpZ2h0IG5hbWUuIFdlIGRvbid0XG5cdFx0Ly8gd2FudCB0byBxdWVyeSB0aGUgdmFsdWUgaWYgaXQgaXMgYSBDU1MgY3VzdG9tIHByb3BlcnR5XG5cdFx0Ly8gc2luY2UgdGhleSBhcmUgdXNlci1kZWZpbmVkLlxuXHRcdGlmICggIWlzQ3VzdG9tUHJvcCApIHtcblx0XHRcdG5hbWUgPSBmaW5hbFByb3BOYW1lKCBvcmlnTmFtZSApO1xuXHRcdH1cblxuXHRcdC8vIEdldHMgaG9vayBmb3IgdGhlIHByZWZpeGVkIHZlcnNpb24sIHRoZW4gdW5wcmVmaXhlZCB2ZXJzaW9uXG5cdFx0aG9va3MgPSBqUXVlcnkuY3NzSG9va3NbIG5hbWUgXSB8fCBqUXVlcnkuY3NzSG9va3NbIG9yaWdOYW1lIF07XG5cblx0XHQvLyBDaGVjayBpZiB3ZSdyZSBzZXR0aW5nIGEgdmFsdWVcblx0XHRpZiAoIHZhbHVlICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHR0eXBlID0gdHlwZW9mIHZhbHVlO1xuXG5cdFx0XHQvLyBDb252ZXJ0IFwiKz1cIiBvciBcIi09XCIgdG8gcmVsYXRpdmUgbnVtYmVycyAoIzczNDUpXG5cdFx0XHRpZiAoIHR5cGUgPT09IFwic3RyaW5nXCIgJiYgKCByZXQgPSByY3NzTnVtLmV4ZWMoIHZhbHVlICkgKSAmJiByZXRbIDEgXSApIHtcblx0XHRcdFx0dmFsdWUgPSBhZGp1c3RDU1MoIGVsZW0sIG5hbWUsIHJldCApO1xuXG5cdFx0XHRcdC8vIEZpeGVzIGJ1ZyAjOTIzN1xuXHRcdFx0XHR0eXBlID0gXCJudW1iZXJcIjtcblx0XHRcdH1cblxuXHRcdFx0Ly8gTWFrZSBzdXJlIHRoYXQgbnVsbCBhbmQgTmFOIHZhbHVlcyBhcmVuJ3Qgc2V0ICgjNzExNilcblx0XHRcdGlmICggdmFsdWUgPT0gbnVsbCB8fCB2YWx1ZSAhPT0gdmFsdWUgKSB7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblxuXHRcdFx0Ly8gSWYgYSBudW1iZXIgd2FzIHBhc3NlZCBpbiwgYWRkIHRoZSB1bml0IChleGNlcHQgZm9yIGNlcnRhaW4gQ1NTIHByb3BlcnRpZXMpXG5cdFx0XHQvLyBUaGUgaXNDdXN0b21Qcm9wIGNoZWNrIGNhbiBiZSByZW1vdmVkIGluIGpRdWVyeSA0LjAgd2hlbiB3ZSBvbmx5IGF1dG8tYXBwZW5kXG5cdFx0XHQvLyBcInB4XCIgdG8gYSBmZXcgaGFyZGNvZGVkIHZhbHVlcy5cblx0XHRcdGlmICggdHlwZSA9PT0gXCJudW1iZXJcIiAmJiAhaXNDdXN0b21Qcm9wICkge1xuXHRcdFx0XHR2YWx1ZSArPSByZXQgJiYgcmV0WyAzIF0gfHwgKCBqUXVlcnkuY3NzTnVtYmVyWyBvcmlnTmFtZSBdID8gXCJcIiA6IFwicHhcIiApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBiYWNrZ3JvdW5kLSogcHJvcHMgYWZmZWN0IG9yaWdpbmFsIGNsb25lJ3MgdmFsdWVzXG5cdFx0XHRpZiAoICFzdXBwb3J0LmNsZWFyQ2xvbmVTdHlsZSAmJiB2YWx1ZSA9PT0gXCJcIiAmJiBuYW1lLmluZGV4T2YoIFwiYmFja2dyb3VuZFwiICkgPT09IDAgKSB7XG5cdFx0XHRcdHN0eWxlWyBuYW1lIF0gPSBcImluaGVyaXRcIjtcblx0XHRcdH1cblxuXHRcdFx0Ly8gSWYgYSBob29rIHdhcyBwcm92aWRlZCwgdXNlIHRoYXQgdmFsdWUsIG90aGVyd2lzZSBqdXN0IHNldCB0aGUgc3BlY2lmaWVkIHZhbHVlXG5cdFx0XHRpZiAoICFob29rcyB8fCAhKCBcInNldFwiIGluIGhvb2tzICkgfHxcblx0XHRcdFx0KCB2YWx1ZSA9IGhvb2tzLnNldCggZWxlbSwgdmFsdWUsIGV4dHJhICkgKSAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRcdGlmICggaXNDdXN0b21Qcm9wICkge1xuXHRcdFx0XHRcdHN0eWxlLnNldFByb3BlcnR5KCBuYW1lLCB2YWx1ZSApO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHN0eWxlWyBuYW1lIF0gPSB2YWx1ZTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0fSBlbHNlIHtcblxuXHRcdFx0Ly8gSWYgYSBob29rIHdhcyBwcm92aWRlZCBnZXQgdGhlIG5vbi1jb21wdXRlZCB2YWx1ZSBmcm9tIHRoZXJlXG5cdFx0XHRpZiAoIGhvb2tzICYmIFwiZ2V0XCIgaW4gaG9va3MgJiZcblx0XHRcdFx0KCByZXQgPSBob29rcy5nZXQoIGVsZW0sIGZhbHNlLCBleHRyYSApICkgIT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0XHRyZXR1cm4gcmV0O1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBPdGhlcndpc2UganVzdCBnZXQgdGhlIHZhbHVlIGZyb20gdGhlIHN0eWxlIG9iamVjdFxuXHRcdFx0cmV0dXJuIHN0eWxlWyBuYW1lIF07XG5cdFx0fVxuXHR9LFxuXG5cdGNzczogZnVuY3Rpb24oIGVsZW0sIG5hbWUsIGV4dHJhLCBzdHlsZXMgKSB7XG5cdFx0dmFyIHZhbCwgbnVtLCBob29rcyxcblx0XHRcdG9yaWdOYW1lID0gY2FtZWxDYXNlKCBuYW1lICksXG5cdFx0XHRpc0N1c3RvbVByb3AgPSByY3VzdG9tUHJvcC50ZXN0KCBuYW1lICk7XG5cblx0XHQvLyBNYWtlIHN1cmUgdGhhdCB3ZSdyZSB3b3JraW5nIHdpdGggdGhlIHJpZ2h0IG5hbWUuIFdlIGRvbid0XG5cdFx0Ly8gd2FudCB0byBtb2RpZnkgdGhlIHZhbHVlIGlmIGl0IGlzIGEgQ1NTIGN1c3RvbSBwcm9wZXJ0eVxuXHRcdC8vIHNpbmNlIHRoZXkgYXJlIHVzZXItZGVmaW5lZC5cblx0XHRpZiAoICFpc0N1c3RvbVByb3AgKSB7XG5cdFx0XHRuYW1lID0gZmluYWxQcm9wTmFtZSggb3JpZ05hbWUgKTtcblx0XHR9XG5cblx0XHQvLyBUcnkgcHJlZml4ZWQgbmFtZSBmb2xsb3dlZCBieSB0aGUgdW5wcmVmaXhlZCBuYW1lXG5cdFx0aG9va3MgPSBqUXVlcnkuY3NzSG9va3NbIG5hbWUgXSB8fCBqUXVlcnkuY3NzSG9va3NbIG9yaWdOYW1lIF07XG5cblx0XHQvLyBJZiBhIGhvb2sgd2FzIHByb3ZpZGVkIGdldCB0aGUgY29tcHV0ZWQgdmFsdWUgZnJvbSB0aGVyZVxuXHRcdGlmICggaG9va3MgJiYgXCJnZXRcIiBpbiBob29rcyApIHtcblx0XHRcdHZhbCA9IGhvb2tzLmdldCggZWxlbSwgdHJ1ZSwgZXh0cmEgKTtcblx0XHR9XG5cblx0XHQvLyBPdGhlcndpc2UsIGlmIGEgd2F5IHRvIGdldCB0aGUgY29tcHV0ZWQgdmFsdWUgZXhpc3RzLCB1c2UgdGhhdFxuXHRcdGlmICggdmFsID09PSB1bmRlZmluZWQgKSB7XG5cdFx0XHR2YWwgPSBjdXJDU1MoIGVsZW0sIG5hbWUsIHN0eWxlcyApO1xuXHRcdH1cblxuXHRcdC8vIENvbnZlcnQgXCJub3JtYWxcIiB0byBjb21wdXRlZCB2YWx1ZVxuXHRcdGlmICggdmFsID09PSBcIm5vcm1hbFwiICYmIG5hbWUgaW4gY3NzTm9ybWFsVHJhbnNmb3JtICkge1xuXHRcdFx0dmFsID0gY3NzTm9ybWFsVHJhbnNmb3JtWyBuYW1lIF07XG5cdFx0fVxuXG5cdFx0Ly8gTWFrZSBudW1lcmljIGlmIGZvcmNlZCBvciBhIHF1YWxpZmllciB3YXMgcHJvdmlkZWQgYW5kIHZhbCBsb29rcyBudW1lcmljXG5cdFx0aWYgKCBleHRyYSA9PT0gXCJcIiB8fCBleHRyYSApIHtcblx0XHRcdG51bSA9IHBhcnNlRmxvYXQoIHZhbCApO1xuXHRcdFx0cmV0dXJuIGV4dHJhID09PSB0cnVlIHx8IGlzRmluaXRlKCBudW0gKSA/IG51bSB8fCAwIDogdmFsO1xuXHRcdH1cblxuXHRcdHJldHVybiB2YWw7XG5cdH1cbn0gKTtcblxualF1ZXJ5LmVhY2goIFsgXCJoZWlnaHRcIiwgXCJ3aWR0aFwiIF0sIGZ1bmN0aW9uKCBfaSwgZGltZW5zaW9uICkge1xuXHRqUXVlcnkuY3NzSG9va3NbIGRpbWVuc2lvbiBdID0ge1xuXHRcdGdldDogZnVuY3Rpb24oIGVsZW0sIGNvbXB1dGVkLCBleHRyYSApIHtcblx0XHRcdGlmICggY29tcHV0ZWQgKSB7XG5cblx0XHRcdFx0Ly8gQ2VydGFpbiBlbGVtZW50cyBjYW4gaGF2ZSBkaW1lbnNpb24gaW5mbyBpZiB3ZSBpbnZpc2libHkgc2hvdyB0aGVtXG5cdFx0XHRcdC8vIGJ1dCBpdCBtdXN0IGhhdmUgYSBjdXJyZW50IGRpc3BsYXkgc3R5bGUgdGhhdCB3b3VsZCBiZW5lZml0XG5cdFx0XHRcdHJldHVybiByZGlzcGxheXN3YXAudGVzdCggalF1ZXJ5LmNzcyggZWxlbSwgXCJkaXNwbGF5XCIgKSApICYmXG5cblx0XHRcdFx0XHQvLyBTdXBwb3J0OiBTYWZhcmkgOCtcblx0XHRcdFx0XHQvLyBUYWJsZSBjb2x1bW5zIGluIFNhZmFyaSBoYXZlIG5vbi16ZXJvIG9mZnNldFdpZHRoICYgemVyb1xuXHRcdFx0XHRcdC8vIGdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLndpZHRoIHVubGVzcyBkaXNwbGF5IGlzIGNoYW5nZWQuXG5cdFx0XHRcdFx0Ly8gU3VwcG9ydDogSUUgPD0xMSBvbmx5XG5cdFx0XHRcdFx0Ly8gUnVubmluZyBnZXRCb3VuZGluZ0NsaWVudFJlY3Qgb24gYSBkaXNjb25uZWN0ZWQgbm9kZVxuXHRcdFx0XHRcdC8vIGluIElFIHRocm93cyBhbiBlcnJvci5cblx0XHRcdFx0XHQoICFlbGVtLmdldENsaWVudFJlY3RzKCkubGVuZ3RoIHx8ICFlbGVtLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLndpZHRoICkgP1xuXHRcdFx0XHRcdHN3YXAoIGVsZW0sIGNzc1Nob3csIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIGdldFdpZHRoT3JIZWlnaHQoIGVsZW0sIGRpbWVuc2lvbiwgZXh0cmEgKTtcblx0XHRcdFx0XHR9ICkgOlxuXHRcdFx0XHRcdGdldFdpZHRoT3JIZWlnaHQoIGVsZW0sIGRpbWVuc2lvbiwgZXh0cmEgKTtcblx0XHRcdH1cblx0XHR9LFxuXG5cdFx0c2V0OiBmdW5jdGlvbiggZWxlbSwgdmFsdWUsIGV4dHJhICkge1xuXHRcdFx0dmFyIG1hdGNoZXMsXG5cdFx0XHRcdHN0eWxlcyA9IGdldFN0eWxlcyggZWxlbSApLFxuXG5cdFx0XHRcdC8vIE9ubHkgcmVhZCBzdHlsZXMucG9zaXRpb24gaWYgdGhlIHRlc3QgaGFzIGEgY2hhbmNlIHRvIGZhaWxcblx0XHRcdFx0Ly8gdG8gYXZvaWQgZm9yY2luZyBhIHJlZmxvdy5cblx0XHRcdFx0c2Nyb2xsYm94U2l6ZUJ1Z2d5ID0gIXN1cHBvcnQuc2Nyb2xsYm94U2l6ZSgpICYmXG5cdFx0XHRcdFx0c3R5bGVzLnBvc2l0aW9uID09PSBcImFic29sdXRlXCIsXG5cblx0XHRcdFx0Ly8gVG8gYXZvaWQgZm9yY2luZyBhIHJlZmxvdywgb25seSBmZXRjaCBib3hTaXppbmcgaWYgd2UgbmVlZCBpdCAoZ2gtMzk5MSlcblx0XHRcdFx0Ym94U2l6aW5nTmVlZGVkID0gc2Nyb2xsYm94U2l6ZUJ1Z2d5IHx8IGV4dHJhLFxuXHRcdFx0XHRpc0JvcmRlckJveCA9IGJveFNpemluZ05lZWRlZCAmJlxuXHRcdFx0XHRcdGpRdWVyeS5jc3MoIGVsZW0sIFwiYm94U2l6aW5nXCIsIGZhbHNlLCBzdHlsZXMgKSA9PT0gXCJib3JkZXItYm94XCIsXG5cdFx0XHRcdHN1YnRyYWN0ID0gZXh0cmEgP1xuXHRcdFx0XHRcdGJveE1vZGVsQWRqdXN0bWVudChcblx0XHRcdFx0XHRcdGVsZW0sXG5cdFx0XHRcdFx0XHRkaW1lbnNpb24sXG5cdFx0XHRcdFx0XHRleHRyYSxcblx0XHRcdFx0XHRcdGlzQm9yZGVyQm94LFxuXHRcdFx0XHRcdFx0c3R5bGVzXG5cdFx0XHRcdFx0KSA6XG5cdFx0XHRcdFx0MDtcblxuXHRcdFx0Ly8gQWNjb3VudCBmb3IgdW5yZWxpYWJsZSBib3JkZXItYm94IGRpbWVuc2lvbnMgYnkgY29tcGFyaW5nIG9mZnNldCogdG8gY29tcHV0ZWQgYW5kXG5cdFx0XHQvLyBmYWtpbmcgYSBjb250ZW50LWJveCB0byBnZXQgYm9yZGVyIGFuZCBwYWRkaW5nIChnaC0zNjk5KVxuXHRcdFx0aWYgKCBpc0JvcmRlckJveCAmJiBzY3JvbGxib3hTaXplQnVnZ3kgKSB7XG5cdFx0XHRcdHN1YnRyYWN0IC09IE1hdGguY2VpbChcblx0XHRcdFx0XHRlbGVtWyBcIm9mZnNldFwiICsgZGltZW5zaW9uWyAwIF0udG9VcHBlckNhc2UoKSArIGRpbWVuc2lvbi5zbGljZSggMSApIF0gLVxuXHRcdFx0XHRcdHBhcnNlRmxvYXQoIHN0eWxlc1sgZGltZW5zaW9uIF0gKSAtXG5cdFx0XHRcdFx0Ym94TW9kZWxBZGp1c3RtZW50KCBlbGVtLCBkaW1lbnNpb24sIFwiYm9yZGVyXCIsIGZhbHNlLCBzdHlsZXMgKSAtXG5cdFx0XHRcdFx0MC41XG5cdFx0XHRcdCk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIENvbnZlcnQgdG8gcGl4ZWxzIGlmIHZhbHVlIGFkanVzdG1lbnQgaXMgbmVlZGVkXG5cdFx0XHRpZiAoIHN1YnRyYWN0ICYmICggbWF0Y2hlcyA9IHJjc3NOdW0uZXhlYyggdmFsdWUgKSApICYmXG5cdFx0XHRcdCggbWF0Y2hlc1sgMyBdIHx8IFwicHhcIiApICE9PSBcInB4XCIgKSB7XG5cblx0XHRcdFx0ZWxlbS5zdHlsZVsgZGltZW5zaW9uIF0gPSB2YWx1ZTtcblx0XHRcdFx0dmFsdWUgPSBqUXVlcnkuY3NzKCBlbGVtLCBkaW1lbnNpb24gKTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIHNldFBvc2l0aXZlTnVtYmVyKCBlbGVtLCB2YWx1ZSwgc3VidHJhY3QgKTtcblx0XHR9XG5cdH07XG59ICk7XG5cbmpRdWVyeS5jc3NIb29rcy5tYXJnaW5MZWZ0ID0gYWRkR2V0SG9va0lmKCBzdXBwb3J0LnJlbGlhYmxlTWFyZ2luTGVmdCxcblx0ZnVuY3Rpb24oIGVsZW0sIGNvbXB1dGVkICkge1xuXHRcdGlmICggY29tcHV0ZWQgKSB7XG5cdFx0XHRyZXR1cm4gKCBwYXJzZUZsb2F0KCBjdXJDU1MoIGVsZW0sIFwibWFyZ2luTGVmdFwiICkgKSB8fFxuXHRcdFx0XHRlbGVtLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLmxlZnQgLVxuXHRcdFx0XHRcdHN3YXAoIGVsZW0sIHsgbWFyZ2luTGVmdDogMCB9LCBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdHJldHVybiBlbGVtLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLmxlZnQ7XG5cdFx0XHRcdFx0fSApXG5cdFx0XHQpICsgXCJweFwiO1xuXHRcdH1cblx0fVxuKTtcblxuLy8gVGhlc2UgaG9va3MgYXJlIHVzZWQgYnkgYW5pbWF0ZSB0byBleHBhbmQgcHJvcGVydGllc1xualF1ZXJ5LmVhY2goIHtcblx0bWFyZ2luOiBcIlwiLFxuXHRwYWRkaW5nOiBcIlwiLFxuXHRib3JkZXI6IFwiV2lkdGhcIlxufSwgZnVuY3Rpb24oIHByZWZpeCwgc3VmZml4ICkge1xuXHRqUXVlcnkuY3NzSG9va3NbIHByZWZpeCArIHN1ZmZpeCBdID0ge1xuXHRcdGV4cGFuZDogZnVuY3Rpb24oIHZhbHVlICkge1xuXHRcdFx0dmFyIGkgPSAwLFxuXHRcdFx0XHRleHBhbmRlZCA9IHt9LFxuXG5cdFx0XHRcdC8vIEFzc3VtZXMgYSBzaW5nbGUgbnVtYmVyIGlmIG5vdCBhIHN0cmluZ1xuXHRcdFx0XHRwYXJ0cyA9IHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiA/IHZhbHVlLnNwbGl0KCBcIiBcIiApIDogWyB2YWx1ZSBdO1xuXG5cdFx0XHRmb3IgKCA7IGkgPCA0OyBpKysgKSB7XG5cdFx0XHRcdGV4cGFuZGVkWyBwcmVmaXggKyBjc3NFeHBhbmRbIGkgXSArIHN1ZmZpeCBdID1cblx0XHRcdFx0XHRwYXJ0c1sgaSBdIHx8IHBhcnRzWyBpIC0gMiBdIHx8IHBhcnRzWyAwIF07XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBleHBhbmRlZDtcblx0XHR9XG5cdH07XG5cblx0aWYgKCBwcmVmaXggIT09IFwibWFyZ2luXCIgKSB7XG5cdFx0alF1ZXJ5LmNzc0hvb2tzWyBwcmVmaXggKyBzdWZmaXggXS5zZXQgPSBzZXRQb3NpdGl2ZU51bWJlcjtcblx0fVxufSApO1xuXG5qUXVlcnkuZm4uZXh0ZW5kKCB7XG5cdGNzczogZnVuY3Rpb24oIG5hbWUsIHZhbHVlICkge1xuXHRcdHJldHVybiBhY2Nlc3MoIHRoaXMsIGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCB2YWx1ZSApIHtcblx0XHRcdHZhciBzdHlsZXMsIGxlbixcblx0XHRcdFx0bWFwID0ge30sXG5cdFx0XHRcdGkgPSAwO1xuXG5cdFx0XHRpZiAoIEFycmF5LmlzQXJyYXkoIG5hbWUgKSApIHtcblx0XHRcdFx0c3R5bGVzID0gZ2V0U3R5bGVzKCBlbGVtICk7XG5cdFx0XHRcdGxlbiA9IG5hbWUubGVuZ3RoO1xuXG5cdFx0XHRcdGZvciAoIDsgaSA8IGxlbjsgaSsrICkge1xuXHRcdFx0XHRcdG1hcFsgbmFtZVsgaSBdIF0gPSBqUXVlcnkuY3NzKCBlbGVtLCBuYW1lWyBpIF0sIGZhbHNlLCBzdHlsZXMgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHJldHVybiBtYXA7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiB2YWx1ZSAhPT0gdW5kZWZpbmVkID9cblx0XHRcdFx0alF1ZXJ5LnN0eWxlKCBlbGVtLCBuYW1lLCB2YWx1ZSApIDpcblx0XHRcdFx0alF1ZXJ5LmNzcyggZWxlbSwgbmFtZSApO1xuXHRcdH0sIG5hbWUsIHZhbHVlLCBhcmd1bWVudHMubGVuZ3RoID4gMSApO1xuXHR9XG59ICk7XG5cblxuZnVuY3Rpb24gVHdlZW4oIGVsZW0sIG9wdGlvbnMsIHByb3AsIGVuZCwgZWFzaW5nICkge1xuXHRyZXR1cm4gbmV3IFR3ZWVuLnByb3RvdHlwZS5pbml0KCBlbGVtLCBvcHRpb25zLCBwcm9wLCBlbmQsIGVhc2luZyApO1xufVxualF1ZXJ5LlR3ZWVuID0gVHdlZW47XG5cblR3ZWVuLnByb3RvdHlwZSA9IHtcblx0Y29uc3RydWN0b3I6IFR3ZWVuLFxuXHRpbml0OiBmdW5jdGlvbiggZWxlbSwgb3B0aW9ucywgcHJvcCwgZW5kLCBlYXNpbmcsIHVuaXQgKSB7XG5cdFx0dGhpcy5lbGVtID0gZWxlbTtcblx0XHR0aGlzLnByb3AgPSBwcm9wO1xuXHRcdHRoaXMuZWFzaW5nID0gZWFzaW5nIHx8IGpRdWVyeS5lYXNpbmcuX2RlZmF1bHQ7XG5cdFx0dGhpcy5vcHRpb25zID0gb3B0aW9ucztcblx0XHR0aGlzLnN0YXJ0ID0gdGhpcy5ub3cgPSB0aGlzLmN1cigpO1xuXHRcdHRoaXMuZW5kID0gZW5kO1xuXHRcdHRoaXMudW5pdCA9IHVuaXQgfHwgKCBqUXVlcnkuY3NzTnVtYmVyWyBwcm9wIF0gPyBcIlwiIDogXCJweFwiICk7XG5cdH0sXG5cdGN1cjogZnVuY3Rpb24oKSB7XG5cdFx0dmFyIGhvb2tzID0gVHdlZW4ucHJvcEhvb2tzWyB0aGlzLnByb3AgXTtcblxuXHRcdHJldHVybiBob29rcyAmJiBob29rcy5nZXQgP1xuXHRcdFx0aG9va3MuZ2V0KCB0aGlzICkgOlxuXHRcdFx0VHdlZW4ucHJvcEhvb2tzLl9kZWZhdWx0LmdldCggdGhpcyApO1xuXHR9LFxuXHRydW46IGZ1bmN0aW9uKCBwZXJjZW50ICkge1xuXHRcdHZhciBlYXNlZCxcblx0XHRcdGhvb2tzID0gVHdlZW4ucHJvcEhvb2tzWyB0aGlzLnByb3AgXTtcblxuXHRcdGlmICggdGhpcy5vcHRpb25zLmR1cmF0aW9uICkge1xuXHRcdFx0dGhpcy5wb3MgPSBlYXNlZCA9IGpRdWVyeS5lYXNpbmdbIHRoaXMuZWFzaW5nIF0oXG5cdFx0XHRcdHBlcmNlbnQsIHRoaXMub3B0aW9ucy5kdXJhdGlvbiAqIHBlcmNlbnQsIDAsIDEsIHRoaXMub3B0aW9ucy5kdXJhdGlvblxuXHRcdFx0KTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0dGhpcy5wb3MgPSBlYXNlZCA9IHBlcmNlbnQ7XG5cdFx0fVxuXHRcdHRoaXMubm93ID0gKCB0aGlzLmVuZCAtIHRoaXMuc3RhcnQgKSAqIGVhc2VkICsgdGhpcy5zdGFydDtcblxuXHRcdGlmICggdGhpcy5vcHRpb25zLnN0ZXAgKSB7XG5cdFx0XHR0aGlzLm9wdGlvbnMuc3RlcC5jYWxsKCB0aGlzLmVsZW0sIHRoaXMubm93LCB0aGlzICk7XG5cdFx0fVxuXG5cdFx0aWYgKCBob29rcyAmJiBob29rcy5zZXQgKSB7XG5cdFx0XHRob29rcy5zZXQoIHRoaXMgKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0VHdlZW4ucHJvcEhvb2tzLl9kZWZhdWx0LnNldCggdGhpcyApO1xuXHRcdH1cblx0XHRyZXR1cm4gdGhpcztcblx0fVxufTtcblxuVHdlZW4ucHJvdG90eXBlLmluaXQucHJvdG90eXBlID0gVHdlZW4ucHJvdG90eXBlO1xuXG5Ud2Vlbi5wcm9wSG9va3MgPSB7XG5cdF9kZWZhdWx0OiB7XG5cdFx0Z2V0OiBmdW5jdGlvbiggdHdlZW4gKSB7XG5cdFx0XHR2YXIgcmVzdWx0O1xuXG5cdFx0XHQvLyBVc2UgYSBwcm9wZXJ0eSBvbiB0aGUgZWxlbWVudCBkaXJlY3RseSB3aGVuIGl0IGlzIG5vdCBhIERPTSBlbGVtZW50LFxuXHRcdFx0Ly8gb3Igd2hlbiB0aGVyZSBpcyBubyBtYXRjaGluZyBzdHlsZSBwcm9wZXJ0eSB0aGF0IGV4aXN0cy5cblx0XHRcdGlmICggdHdlZW4uZWxlbS5ub2RlVHlwZSAhPT0gMSB8fFxuXHRcdFx0XHR0d2Vlbi5lbGVtWyB0d2Vlbi5wcm9wIF0gIT0gbnVsbCAmJiB0d2Vlbi5lbGVtLnN0eWxlWyB0d2Vlbi5wcm9wIF0gPT0gbnVsbCApIHtcblx0XHRcdFx0cmV0dXJuIHR3ZWVuLmVsZW1bIHR3ZWVuLnByb3AgXTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gUGFzc2luZyBhbiBlbXB0eSBzdHJpbmcgYXMgYSAzcmQgcGFyYW1ldGVyIHRvIC5jc3Mgd2lsbCBhdXRvbWF0aWNhbGx5XG5cdFx0XHQvLyBhdHRlbXB0IGEgcGFyc2VGbG9hdCBhbmQgZmFsbGJhY2sgdG8gYSBzdHJpbmcgaWYgdGhlIHBhcnNlIGZhaWxzLlxuXHRcdFx0Ly8gU2ltcGxlIHZhbHVlcyBzdWNoIGFzIFwiMTBweFwiIGFyZSBwYXJzZWQgdG8gRmxvYXQ7XG5cdFx0XHQvLyBjb21wbGV4IHZhbHVlcyBzdWNoIGFzIFwicm90YXRlKDFyYWQpXCIgYXJlIHJldHVybmVkIGFzLWlzLlxuXHRcdFx0cmVzdWx0ID0galF1ZXJ5LmNzcyggdHdlZW4uZWxlbSwgdHdlZW4ucHJvcCwgXCJcIiApO1xuXG5cdFx0XHQvLyBFbXB0eSBzdHJpbmdzLCBudWxsLCB1bmRlZmluZWQgYW5kIFwiYXV0b1wiIGFyZSBjb252ZXJ0ZWQgdG8gMC5cblx0XHRcdHJldHVybiAhcmVzdWx0IHx8IHJlc3VsdCA9PT0gXCJhdXRvXCIgPyAwIDogcmVzdWx0O1xuXHRcdH0sXG5cdFx0c2V0OiBmdW5jdGlvbiggdHdlZW4gKSB7XG5cblx0XHRcdC8vIFVzZSBzdGVwIGhvb2sgZm9yIGJhY2sgY29tcGF0LlxuXHRcdFx0Ly8gVXNlIGNzc0hvb2sgaWYgaXRzIHRoZXJlLlxuXHRcdFx0Ly8gVXNlIC5zdHlsZSBpZiBhdmFpbGFibGUgYW5kIHVzZSBwbGFpbiBwcm9wZXJ0aWVzIHdoZXJlIGF2YWlsYWJsZS5cblx0XHRcdGlmICggalF1ZXJ5LmZ4LnN0ZXBbIHR3ZWVuLnByb3AgXSApIHtcblx0XHRcdFx0alF1ZXJ5LmZ4LnN0ZXBbIHR3ZWVuLnByb3AgXSggdHdlZW4gKTtcblx0XHRcdH0gZWxzZSBpZiAoIHR3ZWVuLmVsZW0ubm9kZVR5cGUgPT09IDEgJiYgKFxuXHRcdFx0XHRqUXVlcnkuY3NzSG9va3NbIHR3ZWVuLnByb3AgXSB8fFxuXHRcdFx0XHRcdHR3ZWVuLmVsZW0uc3R5bGVbIGZpbmFsUHJvcE5hbWUoIHR3ZWVuLnByb3AgKSBdICE9IG51bGwgKSApIHtcblx0XHRcdFx0alF1ZXJ5LnN0eWxlKCB0d2Vlbi5lbGVtLCB0d2Vlbi5wcm9wLCB0d2Vlbi5ub3cgKyB0d2Vlbi51bml0ICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR0d2Vlbi5lbGVtWyB0d2Vlbi5wcm9wIF0gPSB0d2Vlbi5ub3c7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG59O1xuXG4vLyBTdXBwb3J0OiBJRSA8PTkgb25seVxuLy8gUGFuaWMgYmFzZWQgYXBwcm9hY2ggdG8gc2V0dGluZyB0aGluZ3Mgb24gZGlzY29ubmVjdGVkIG5vZGVzXG5Ud2Vlbi5wcm9wSG9va3Muc2Nyb2xsVG9wID0gVHdlZW4ucHJvcEhvb2tzLnNjcm9sbExlZnQgPSB7XG5cdHNldDogZnVuY3Rpb24oIHR3ZWVuICkge1xuXHRcdGlmICggdHdlZW4uZWxlbS5ub2RlVHlwZSAmJiB0d2Vlbi5lbGVtLnBhcmVudE5vZGUgKSB7XG5cdFx0XHR0d2Vlbi5lbGVtWyB0d2Vlbi5wcm9wIF0gPSB0d2Vlbi5ub3c7XG5cdFx0fVxuXHR9XG59O1xuXG5qUXVlcnkuZWFzaW5nID0ge1xuXHRsaW5lYXI6IGZ1bmN0aW9uKCBwICkge1xuXHRcdHJldHVybiBwO1xuXHR9LFxuXHRzd2luZzogZnVuY3Rpb24oIHAgKSB7XG5cdFx0cmV0dXJuIDAuNSAtIE1hdGguY29zKCBwICogTWF0aC5QSSApIC8gMjtcblx0fSxcblx0X2RlZmF1bHQ6IFwic3dpbmdcIlxufTtcblxualF1ZXJ5LmZ4ID0gVHdlZW4ucHJvdG90eXBlLmluaXQ7XG5cbi8vIEJhY2sgY29tcGF0IDwxLjggZXh0ZW5zaW9uIHBvaW50XG5qUXVlcnkuZnguc3RlcCA9IHt9O1xuXG5cblxuXG52YXJcblx0ZnhOb3csIGluUHJvZ3Jlc3MsXG5cdHJmeHR5cGVzID0gL14oPzp0b2dnbGV8c2hvd3xoaWRlKSQvLFxuXHRycnVuID0gL3F1ZXVlSG9va3MkLztcblxuZnVuY3Rpb24gc2NoZWR1bGUoKSB7XG5cdGlmICggaW5Qcm9ncmVzcyApIHtcblx0XHRpZiAoIGRvY3VtZW50LmhpZGRlbiA9PT0gZmFsc2UgJiYgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSApIHtcblx0XHRcdHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoIHNjaGVkdWxlICk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHdpbmRvdy5zZXRUaW1lb3V0KCBzY2hlZHVsZSwgalF1ZXJ5LmZ4LmludGVydmFsICk7XG5cdFx0fVxuXG5cdFx0alF1ZXJ5LmZ4LnRpY2soKTtcblx0fVxufVxuXG4vLyBBbmltYXRpb25zIGNyZWF0ZWQgc3luY2hyb25vdXNseSB3aWxsIHJ1biBzeW5jaHJvbm91c2x5XG5mdW5jdGlvbiBjcmVhdGVGeE5vdygpIHtcblx0d2luZG93LnNldFRpbWVvdXQoIGZ1bmN0aW9uKCkge1xuXHRcdGZ4Tm93ID0gdW5kZWZpbmVkO1xuXHR9ICk7XG5cdHJldHVybiAoIGZ4Tm93ID0gRGF0ZS5ub3coKSApO1xufVxuXG4vLyBHZW5lcmF0ZSBwYXJhbWV0ZXJzIHRvIGNyZWF0ZSBhIHN0YW5kYXJkIGFuaW1hdGlvblxuZnVuY3Rpb24gZ2VuRngoIHR5cGUsIGluY2x1ZGVXaWR0aCApIHtcblx0dmFyIHdoaWNoLFxuXHRcdGkgPSAwLFxuXHRcdGF0dHJzID0geyBoZWlnaHQ6IHR5cGUgfTtcblxuXHQvLyBJZiB3ZSBpbmNsdWRlIHdpZHRoLCBzdGVwIHZhbHVlIGlzIDEgdG8gZG8gYWxsIGNzc0V4cGFuZCB2YWx1ZXMsXG5cdC8vIG90aGVyd2lzZSBzdGVwIHZhbHVlIGlzIDIgdG8gc2tpcCBvdmVyIExlZnQgYW5kIFJpZ2h0XG5cdGluY2x1ZGVXaWR0aCA9IGluY2x1ZGVXaWR0aCA/IDEgOiAwO1xuXHRmb3IgKCA7IGkgPCA0OyBpICs9IDIgLSBpbmNsdWRlV2lkdGggKSB7XG5cdFx0d2hpY2ggPSBjc3NFeHBhbmRbIGkgXTtcblx0XHRhdHRyc1sgXCJtYXJnaW5cIiArIHdoaWNoIF0gPSBhdHRyc1sgXCJwYWRkaW5nXCIgKyB3aGljaCBdID0gdHlwZTtcblx0fVxuXG5cdGlmICggaW5jbHVkZVdpZHRoICkge1xuXHRcdGF0dHJzLm9wYWNpdHkgPSBhdHRycy53aWR0aCA9IHR5cGU7XG5cdH1cblxuXHRyZXR1cm4gYXR0cnM7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVR3ZWVuKCB2YWx1ZSwgcHJvcCwgYW5pbWF0aW9uICkge1xuXHR2YXIgdHdlZW4sXG5cdFx0Y29sbGVjdGlvbiA9ICggQW5pbWF0aW9uLnR3ZWVuZXJzWyBwcm9wIF0gfHwgW10gKS5jb25jYXQoIEFuaW1hdGlvbi50d2VlbmVyc1sgXCIqXCIgXSApLFxuXHRcdGluZGV4ID0gMCxcblx0XHRsZW5ndGggPSBjb2xsZWN0aW9uLmxlbmd0aDtcblx0Zm9yICggOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKyApIHtcblx0XHRpZiAoICggdHdlZW4gPSBjb2xsZWN0aW9uWyBpbmRleCBdLmNhbGwoIGFuaW1hdGlvbiwgcHJvcCwgdmFsdWUgKSApICkge1xuXG5cdFx0XHQvLyBXZSdyZSBkb25lIHdpdGggdGhpcyBwcm9wZXJ0eVxuXHRcdFx0cmV0dXJuIHR3ZWVuO1xuXHRcdH1cblx0fVxufVxuXG5mdW5jdGlvbiBkZWZhdWx0UHJlZmlsdGVyKCBlbGVtLCBwcm9wcywgb3B0cyApIHtcblx0dmFyIHByb3AsIHZhbHVlLCB0b2dnbGUsIGhvb2tzLCBvbGRmaXJlLCBwcm9wVHdlZW4sIHJlc3RvcmVEaXNwbGF5LCBkaXNwbGF5LFxuXHRcdGlzQm94ID0gXCJ3aWR0aFwiIGluIHByb3BzIHx8IFwiaGVpZ2h0XCIgaW4gcHJvcHMsXG5cdFx0YW5pbSA9IHRoaXMsXG5cdFx0b3JpZyA9IHt9LFxuXHRcdHN0eWxlID0gZWxlbS5zdHlsZSxcblx0XHRoaWRkZW4gPSBlbGVtLm5vZGVUeXBlICYmIGlzSGlkZGVuV2l0aGluVHJlZSggZWxlbSApLFxuXHRcdGRhdGFTaG93ID0gZGF0YVByaXYuZ2V0KCBlbGVtLCBcImZ4c2hvd1wiICk7XG5cblx0Ly8gUXVldWUtc2tpcHBpbmcgYW5pbWF0aW9ucyBoaWphY2sgdGhlIGZ4IGhvb2tzXG5cdGlmICggIW9wdHMucXVldWUgKSB7XG5cdFx0aG9va3MgPSBqUXVlcnkuX3F1ZXVlSG9va3MoIGVsZW0sIFwiZnhcIiApO1xuXHRcdGlmICggaG9va3MudW5xdWV1ZWQgPT0gbnVsbCApIHtcblx0XHRcdGhvb2tzLnVucXVldWVkID0gMDtcblx0XHRcdG9sZGZpcmUgPSBob29rcy5lbXB0eS5maXJlO1xuXHRcdFx0aG9va3MuZW1wdHkuZmlyZSA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRpZiAoICFob29rcy51bnF1ZXVlZCApIHtcblx0XHRcdFx0XHRvbGRmaXJlKCk7XG5cdFx0XHRcdH1cblx0XHRcdH07XG5cdFx0fVxuXHRcdGhvb2tzLnVucXVldWVkKys7XG5cblx0XHRhbmltLmFsd2F5cyggZnVuY3Rpb24oKSB7XG5cblx0XHRcdC8vIEVuc3VyZSB0aGUgY29tcGxldGUgaGFuZGxlciBpcyBjYWxsZWQgYmVmb3JlIHRoaXMgY29tcGxldGVzXG5cdFx0XHRhbmltLmFsd2F5cyggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGhvb2tzLnVucXVldWVkLS07XG5cdFx0XHRcdGlmICggIWpRdWVyeS5xdWV1ZSggZWxlbSwgXCJmeFwiICkubGVuZ3RoICkge1xuXHRcdFx0XHRcdGhvb2tzLmVtcHR5LmZpcmUoKTtcblx0XHRcdFx0fVxuXHRcdFx0fSApO1xuXHRcdH0gKTtcblx0fVxuXG5cdC8vIERldGVjdCBzaG93L2hpZGUgYW5pbWF0aW9uc1xuXHRmb3IgKCBwcm9wIGluIHByb3BzICkge1xuXHRcdHZhbHVlID0gcHJvcHNbIHByb3AgXTtcblx0XHRpZiAoIHJmeHR5cGVzLnRlc3QoIHZhbHVlICkgKSB7XG5cdFx0XHRkZWxldGUgcHJvcHNbIHByb3AgXTtcblx0XHRcdHRvZ2dsZSA9IHRvZ2dsZSB8fCB2YWx1ZSA9PT0gXCJ0b2dnbGVcIjtcblx0XHRcdGlmICggdmFsdWUgPT09ICggaGlkZGVuID8gXCJoaWRlXCIgOiBcInNob3dcIiApICkge1xuXG5cdFx0XHRcdC8vIFByZXRlbmQgdG8gYmUgaGlkZGVuIGlmIHRoaXMgaXMgYSBcInNob3dcIiBhbmRcblx0XHRcdFx0Ly8gdGhlcmUgaXMgc3RpbGwgZGF0YSBmcm9tIGEgc3RvcHBlZCBzaG93L2hpZGVcblx0XHRcdFx0aWYgKCB2YWx1ZSA9PT0gXCJzaG93XCIgJiYgZGF0YVNob3cgJiYgZGF0YVNob3dbIHByb3AgXSAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHRcdGhpZGRlbiA9IHRydWU7XG5cblx0XHRcdFx0Ly8gSWdub3JlIGFsbCBvdGhlciBuby1vcCBzaG93L2hpZGUgZGF0YVxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRvcmlnWyBwcm9wIF0gPSBkYXRhU2hvdyAmJiBkYXRhU2hvd1sgcHJvcCBdIHx8IGpRdWVyeS5zdHlsZSggZWxlbSwgcHJvcCApO1xuXHRcdH1cblx0fVxuXG5cdC8vIEJhaWwgb3V0IGlmIHRoaXMgaXMgYSBuby1vcCBsaWtlIC5oaWRlKCkuaGlkZSgpXG5cdHByb3BUd2VlbiA9ICFqUXVlcnkuaXNFbXB0eU9iamVjdCggcHJvcHMgKTtcblx0aWYgKCAhcHJvcFR3ZWVuICYmIGpRdWVyeS5pc0VtcHR5T2JqZWN0KCBvcmlnICkgKSB7XG5cdFx0cmV0dXJuO1xuXHR9XG5cblx0Ly8gUmVzdHJpY3QgXCJvdmVyZmxvd1wiIGFuZCBcImRpc3BsYXlcIiBzdHlsZXMgZHVyaW5nIGJveCBhbmltYXRpb25zXG5cdGlmICggaXNCb3ggJiYgZWxlbS5ub2RlVHlwZSA9PT0gMSApIHtcblxuXHRcdC8vIFN1cHBvcnQ6IElFIDw9OSAtIDExLCBFZGdlIDEyIC0gMTVcblx0XHQvLyBSZWNvcmQgYWxsIDMgb3ZlcmZsb3cgYXR0cmlidXRlcyBiZWNhdXNlIElFIGRvZXMgbm90IGluZmVyIHRoZSBzaG9ydGhhbmRcblx0XHQvLyBmcm9tIGlkZW50aWNhbGx5LXZhbHVlZCBvdmVyZmxvd1ggYW5kIG92ZXJmbG93WSBhbmQgRWRnZSBqdXN0IG1pcnJvcnNcblx0XHQvLyB0aGUgb3ZlcmZsb3dYIHZhbHVlIHRoZXJlLlxuXHRcdG9wdHMub3ZlcmZsb3cgPSBbIHN0eWxlLm92ZXJmbG93LCBzdHlsZS5vdmVyZmxvd1gsIHN0eWxlLm92ZXJmbG93WSBdO1xuXG5cdFx0Ly8gSWRlbnRpZnkgYSBkaXNwbGF5IHR5cGUsIHByZWZlcnJpbmcgb2xkIHNob3cvaGlkZSBkYXRhIG92ZXIgdGhlIENTUyBjYXNjYWRlXG5cdFx0cmVzdG9yZURpc3BsYXkgPSBkYXRhU2hvdyAmJiBkYXRhU2hvdy5kaXNwbGF5O1xuXHRcdGlmICggcmVzdG9yZURpc3BsYXkgPT0gbnVsbCApIHtcblx0XHRcdHJlc3RvcmVEaXNwbGF5ID0gZGF0YVByaXYuZ2V0KCBlbGVtLCBcImRpc3BsYXlcIiApO1xuXHRcdH1cblx0XHRkaXNwbGF5ID0galF1ZXJ5LmNzcyggZWxlbSwgXCJkaXNwbGF5XCIgKTtcblx0XHRpZiAoIGRpc3BsYXkgPT09IFwibm9uZVwiICkge1xuXHRcdFx0aWYgKCByZXN0b3JlRGlzcGxheSApIHtcblx0XHRcdFx0ZGlzcGxheSA9IHJlc3RvcmVEaXNwbGF5O1xuXHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHQvLyBHZXQgbm9uZW1wdHkgdmFsdWUocykgYnkgdGVtcG9yYXJpbHkgZm9yY2luZyB2aXNpYmlsaXR5XG5cdFx0XHRcdHNob3dIaWRlKCBbIGVsZW0gXSwgdHJ1ZSApO1xuXHRcdFx0XHRyZXN0b3JlRGlzcGxheSA9IGVsZW0uc3R5bGUuZGlzcGxheSB8fCByZXN0b3JlRGlzcGxheTtcblx0XHRcdFx0ZGlzcGxheSA9IGpRdWVyeS5jc3MoIGVsZW0sIFwiZGlzcGxheVwiICk7XG5cdFx0XHRcdHNob3dIaWRlKCBbIGVsZW0gXSApO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIEFuaW1hdGUgaW5saW5lIGVsZW1lbnRzIGFzIGlubGluZS1ibG9ja1xuXHRcdGlmICggZGlzcGxheSA9PT0gXCJpbmxpbmVcIiB8fCBkaXNwbGF5ID09PSBcImlubGluZS1ibG9ja1wiICYmIHJlc3RvcmVEaXNwbGF5ICE9IG51bGwgKSB7XG5cdFx0XHRpZiAoIGpRdWVyeS5jc3MoIGVsZW0sIFwiZmxvYXRcIiApID09PSBcIm5vbmVcIiApIHtcblxuXHRcdFx0XHQvLyBSZXN0b3JlIHRoZSBvcmlnaW5hbCBkaXNwbGF5IHZhbHVlIGF0IHRoZSBlbmQgb2YgcHVyZSBzaG93L2hpZGUgYW5pbWF0aW9uc1xuXHRcdFx0XHRpZiAoICFwcm9wVHdlZW4gKSB7XG5cdFx0XHRcdFx0YW5pbS5kb25lKCBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdHN0eWxlLmRpc3BsYXkgPSByZXN0b3JlRGlzcGxheTtcblx0XHRcdFx0XHR9ICk7XG5cdFx0XHRcdFx0aWYgKCByZXN0b3JlRGlzcGxheSA9PSBudWxsICkge1xuXHRcdFx0XHRcdFx0ZGlzcGxheSA9IHN0eWxlLmRpc3BsYXk7XG5cdFx0XHRcdFx0XHRyZXN0b3JlRGlzcGxheSA9IGRpc3BsYXkgPT09IFwibm9uZVwiID8gXCJcIiA6IGRpc3BsYXk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHRcdHN0eWxlLmRpc3BsYXkgPSBcImlubGluZS1ibG9ja1wiO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdGlmICggb3B0cy5vdmVyZmxvdyApIHtcblx0XHRzdHlsZS5vdmVyZmxvdyA9IFwiaGlkZGVuXCI7XG5cdFx0YW5pbS5hbHdheXMoIGZ1bmN0aW9uKCkge1xuXHRcdFx0c3R5bGUub3ZlcmZsb3cgPSBvcHRzLm92ZXJmbG93WyAwIF07XG5cdFx0XHRzdHlsZS5vdmVyZmxvd1ggPSBvcHRzLm92ZXJmbG93WyAxIF07XG5cdFx0XHRzdHlsZS5vdmVyZmxvd1kgPSBvcHRzLm92ZXJmbG93WyAyIF07XG5cdFx0fSApO1xuXHR9XG5cblx0Ly8gSW1wbGVtZW50IHNob3cvaGlkZSBhbmltYXRpb25zXG5cdHByb3BUd2VlbiA9IGZhbHNlO1xuXHRmb3IgKCBwcm9wIGluIG9yaWcgKSB7XG5cblx0XHQvLyBHZW5lcmFsIHNob3cvaGlkZSBzZXR1cCBmb3IgdGhpcyBlbGVtZW50IGFuaW1hdGlvblxuXHRcdGlmICggIXByb3BUd2VlbiApIHtcblx0XHRcdGlmICggZGF0YVNob3cgKSB7XG5cdFx0XHRcdGlmICggXCJoaWRkZW5cIiBpbiBkYXRhU2hvdyApIHtcblx0XHRcdFx0XHRoaWRkZW4gPSBkYXRhU2hvdy5oaWRkZW47XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGRhdGFTaG93ID0gZGF0YVByaXYuYWNjZXNzKCBlbGVtLCBcImZ4c2hvd1wiLCB7IGRpc3BsYXk6IHJlc3RvcmVEaXNwbGF5IH0gKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gU3RvcmUgaGlkZGVuL3Zpc2libGUgZm9yIHRvZ2dsZSBzbyBgLnN0b3AoKS50b2dnbGUoKWAgXCJyZXZlcnNlc1wiXG5cdFx0XHRpZiAoIHRvZ2dsZSApIHtcblx0XHRcdFx0ZGF0YVNob3cuaGlkZGVuID0gIWhpZGRlbjtcblx0XHRcdH1cblxuXHRcdFx0Ly8gU2hvdyBlbGVtZW50cyBiZWZvcmUgYW5pbWF0aW5nIHRoZW1cblx0XHRcdGlmICggaGlkZGVuICkge1xuXHRcdFx0XHRzaG93SGlkZSggWyBlbGVtIF0sIHRydWUgKTtcblx0XHRcdH1cblxuXHRcdFx0LyogZXNsaW50LWRpc2FibGUgbm8tbG9vcC1mdW5jICovXG5cblx0XHRcdGFuaW0uZG9uZSggZnVuY3Rpb24oKSB7XG5cblx0XHRcdFx0LyogZXNsaW50LWVuYWJsZSBuby1sb29wLWZ1bmMgKi9cblxuXHRcdFx0XHQvLyBUaGUgZmluYWwgc3RlcCBvZiBhIFwiaGlkZVwiIGFuaW1hdGlvbiBpcyBhY3R1YWxseSBoaWRpbmcgdGhlIGVsZW1lbnRcblx0XHRcdFx0aWYgKCAhaGlkZGVuICkge1xuXHRcdFx0XHRcdHNob3dIaWRlKCBbIGVsZW0gXSApO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGRhdGFQcml2LnJlbW92ZSggZWxlbSwgXCJmeHNob3dcIiApO1xuXHRcdFx0XHRmb3IgKCBwcm9wIGluIG9yaWcgKSB7XG5cdFx0XHRcdFx0alF1ZXJ5LnN0eWxlKCBlbGVtLCBwcm9wLCBvcmlnWyBwcm9wIF0gKTtcblx0XHRcdFx0fVxuXHRcdFx0fSApO1xuXHRcdH1cblxuXHRcdC8vIFBlci1wcm9wZXJ0eSBzZXR1cFxuXHRcdHByb3BUd2VlbiA9IGNyZWF0ZVR3ZWVuKCBoaWRkZW4gPyBkYXRhU2hvd1sgcHJvcCBdIDogMCwgcHJvcCwgYW5pbSApO1xuXHRcdGlmICggISggcHJvcCBpbiBkYXRhU2hvdyApICkge1xuXHRcdFx0ZGF0YVNob3dbIHByb3AgXSA9IHByb3BUd2Vlbi5zdGFydDtcblx0XHRcdGlmICggaGlkZGVuICkge1xuXHRcdFx0XHRwcm9wVHdlZW4uZW5kID0gcHJvcFR3ZWVuLnN0YXJ0O1xuXHRcdFx0XHRwcm9wVHdlZW4uc3RhcnQgPSAwO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxufVxuXG5mdW5jdGlvbiBwcm9wRmlsdGVyKCBwcm9wcywgc3BlY2lhbEVhc2luZyApIHtcblx0dmFyIGluZGV4LCBuYW1lLCBlYXNpbmcsIHZhbHVlLCBob29rcztcblxuXHQvLyBjYW1lbENhc2UsIHNwZWNpYWxFYXNpbmcgYW5kIGV4cGFuZCBjc3NIb29rIHBhc3Ncblx0Zm9yICggaW5kZXggaW4gcHJvcHMgKSB7XG5cdFx0bmFtZSA9IGNhbWVsQ2FzZSggaW5kZXggKTtcblx0XHRlYXNpbmcgPSBzcGVjaWFsRWFzaW5nWyBuYW1lIF07XG5cdFx0dmFsdWUgPSBwcm9wc1sgaW5kZXggXTtcblx0XHRpZiAoIEFycmF5LmlzQXJyYXkoIHZhbHVlICkgKSB7XG5cdFx0XHRlYXNpbmcgPSB2YWx1ZVsgMSBdO1xuXHRcdFx0dmFsdWUgPSBwcm9wc1sgaW5kZXggXSA9IHZhbHVlWyAwIF07XG5cdFx0fVxuXG5cdFx0aWYgKCBpbmRleCAhPT0gbmFtZSApIHtcblx0XHRcdHByb3BzWyBuYW1lIF0gPSB2YWx1ZTtcblx0XHRcdGRlbGV0ZSBwcm9wc1sgaW5kZXggXTtcblx0XHR9XG5cblx0XHRob29rcyA9IGpRdWVyeS5jc3NIb29rc1sgbmFtZSBdO1xuXHRcdGlmICggaG9va3MgJiYgXCJleHBhbmRcIiBpbiBob29rcyApIHtcblx0XHRcdHZhbHVlID0gaG9va3MuZXhwYW5kKCB2YWx1ZSApO1xuXHRcdFx0ZGVsZXRlIHByb3BzWyBuYW1lIF07XG5cblx0XHRcdC8vIE5vdCBxdWl0ZSAkLmV4dGVuZCwgdGhpcyB3b24ndCBvdmVyd3JpdGUgZXhpc3Rpbmcga2V5cy5cblx0XHRcdC8vIFJldXNpbmcgJ2luZGV4JyBiZWNhdXNlIHdlIGhhdmUgdGhlIGNvcnJlY3QgXCJuYW1lXCJcblx0XHRcdGZvciAoIGluZGV4IGluIHZhbHVlICkge1xuXHRcdFx0XHRpZiAoICEoIGluZGV4IGluIHByb3BzICkgKSB7XG5cdFx0XHRcdFx0cHJvcHNbIGluZGV4IF0gPSB2YWx1ZVsgaW5kZXggXTtcblx0XHRcdFx0XHRzcGVjaWFsRWFzaW5nWyBpbmRleCBdID0gZWFzaW5nO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSBlbHNlIHtcblx0XHRcdHNwZWNpYWxFYXNpbmdbIG5hbWUgXSA9IGVhc2luZztcblx0XHR9XG5cdH1cbn1cblxuZnVuY3Rpb24gQW5pbWF0aW9uKCBlbGVtLCBwcm9wZXJ0aWVzLCBvcHRpb25zICkge1xuXHR2YXIgcmVzdWx0LFxuXHRcdHN0b3BwZWQsXG5cdFx0aW5kZXggPSAwLFxuXHRcdGxlbmd0aCA9IEFuaW1hdGlvbi5wcmVmaWx0ZXJzLmxlbmd0aCxcblx0XHRkZWZlcnJlZCA9IGpRdWVyeS5EZWZlcnJlZCgpLmFsd2F5cyggZnVuY3Rpb24oKSB7XG5cblx0XHRcdC8vIERvbid0IG1hdGNoIGVsZW0gaW4gdGhlIDphbmltYXRlZCBzZWxlY3RvclxuXHRcdFx0ZGVsZXRlIHRpY2suZWxlbTtcblx0XHR9ICksXG5cdFx0dGljayA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0aWYgKCBzdG9wcGVkICkge1xuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHR9XG5cdFx0XHR2YXIgY3VycmVudFRpbWUgPSBmeE5vdyB8fCBjcmVhdGVGeE5vdygpLFxuXHRcdFx0XHRyZW1haW5pbmcgPSBNYXRoLm1heCggMCwgYW5pbWF0aW9uLnN0YXJ0VGltZSArIGFuaW1hdGlvbi5kdXJhdGlvbiAtIGN1cnJlbnRUaW1lICksXG5cblx0XHRcdFx0Ly8gU3VwcG9ydDogQW5kcm9pZCAyLjMgb25seVxuXHRcdFx0XHQvLyBBcmNoYWljIGNyYXNoIGJ1ZyB3b24ndCBhbGxvdyB1cyB0byB1c2UgYDEgLSAoIDAuNSB8fCAwIClgICgjMTI0OTcpXG5cdFx0XHRcdHRlbXAgPSByZW1haW5pbmcgLyBhbmltYXRpb24uZHVyYXRpb24gfHwgMCxcblx0XHRcdFx0cGVyY2VudCA9IDEgLSB0ZW1wLFxuXHRcdFx0XHRpbmRleCA9IDAsXG5cdFx0XHRcdGxlbmd0aCA9IGFuaW1hdGlvbi50d2VlbnMubGVuZ3RoO1xuXG5cdFx0XHRmb3IgKCA7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrICkge1xuXHRcdFx0XHRhbmltYXRpb24udHdlZW5zWyBpbmRleCBdLnJ1biggcGVyY2VudCApO1xuXHRcdFx0fVxuXG5cdFx0XHRkZWZlcnJlZC5ub3RpZnlXaXRoKCBlbGVtLCBbIGFuaW1hdGlvbiwgcGVyY2VudCwgcmVtYWluaW5nIF0gKTtcblxuXHRcdFx0Ly8gSWYgdGhlcmUncyBtb3JlIHRvIGRvLCB5aWVsZFxuXHRcdFx0aWYgKCBwZXJjZW50IDwgMSAmJiBsZW5ndGggKSB7XG5cdFx0XHRcdHJldHVybiByZW1haW5pbmc7XG5cdFx0XHR9XG5cblx0XHRcdC8vIElmIHRoaXMgd2FzIGFuIGVtcHR5IGFuaW1hdGlvbiwgc3ludGhlc2l6ZSBhIGZpbmFsIHByb2dyZXNzIG5vdGlmaWNhdGlvblxuXHRcdFx0aWYgKCAhbGVuZ3RoICkge1xuXHRcdFx0XHRkZWZlcnJlZC5ub3RpZnlXaXRoKCBlbGVtLCBbIGFuaW1hdGlvbiwgMSwgMCBdICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFJlc29sdmUgdGhlIGFuaW1hdGlvbiBhbmQgcmVwb3J0IGl0cyBjb25jbHVzaW9uXG5cdFx0XHRkZWZlcnJlZC5yZXNvbHZlV2l0aCggZWxlbSwgWyBhbmltYXRpb24gXSApO1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH0sXG5cdFx0YW5pbWF0aW9uID0gZGVmZXJyZWQucHJvbWlzZSgge1xuXHRcdFx0ZWxlbTogZWxlbSxcblx0XHRcdHByb3BzOiBqUXVlcnkuZXh0ZW5kKCB7fSwgcHJvcGVydGllcyApLFxuXHRcdFx0b3B0czogalF1ZXJ5LmV4dGVuZCggdHJ1ZSwge1xuXHRcdFx0XHRzcGVjaWFsRWFzaW5nOiB7fSxcblx0XHRcdFx0ZWFzaW5nOiBqUXVlcnkuZWFzaW5nLl9kZWZhdWx0XG5cdFx0XHR9LCBvcHRpb25zICksXG5cdFx0XHRvcmlnaW5hbFByb3BlcnRpZXM6IHByb3BlcnRpZXMsXG5cdFx0XHRvcmlnaW5hbE9wdGlvbnM6IG9wdGlvbnMsXG5cdFx0XHRzdGFydFRpbWU6IGZ4Tm93IHx8IGNyZWF0ZUZ4Tm93KCksXG5cdFx0XHRkdXJhdGlvbjogb3B0aW9ucy5kdXJhdGlvbixcblx0XHRcdHR3ZWVuczogW10sXG5cdFx0XHRjcmVhdGVUd2VlbjogZnVuY3Rpb24oIHByb3AsIGVuZCApIHtcblx0XHRcdFx0dmFyIHR3ZWVuID0galF1ZXJ5LlR3ZWVuKCBlbGVtLCBhbmltYXRpb24ub3B0cywgcHJvcCwgZW5kLFxuXHRcdFx0XHRcdGFuaW1hdGlvbi5vcHRzLnNwZWNpYWxFYXNpbmdbIHByb3AgXSB8fCBhbmltYXRpb24ub3B0cy5lYXNpbmcgKTtcblx0XHRcdFx0YW5pbWF0aW9uLnR3ZWVucy5wdXNoKCB0d2VlbiApO1xuXHRcdFx0XHRyZXR1cm4gdHdlZW47XG5cdFx0XHR9LFxuXHRcdFx0c3RvcDogZnVuY3Rpb24oIGdvdG9FbmQgKSB7XG5cdFx0XHRcdHZhciBpbmRleCA9IDAsXG5cblx0XHRcdFx0XHQvLyBJZiB3ZSBhcmUgZ29pbmcgdG8gdGhlIGVuZCwgd2Ugd2FudCB0byBydW4gYWxsIHRoZSB0d2VlbnNcblx0XHRcdFx0XHQvLyBvdGhlcndpc2Ugd2Ugc2tpcCB0aGlzIHBhcnRcblx0XHRcdFx0XHRsZW5ndGggPSBnb3RvRW5kID8gYW5pbWF0aW9uLnR3ZWVucy5sZW5ndGggOiAwO1xuXHRcdFx0XHRpZiAoIHN0b3BwZWQgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHRcdH1cblx0XHRcdFx0c3RvcHBlZCA9IHRydWU7XG5cdFx0XHRcdGZvciAoIDsgaW5kZXggPCBsZW5ndGg7IGluZGV4KysgKSB7XG5cdFx0XHRcdFx0YW5pbWF0aW9uLnR3ZWVuc1sgaW5kZXggXS5ydW4oIDEgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIFJlc29sdmUgd2hlbiB3ZSBwbGF5ZWQgdGhlIGxhc3QgZnJhbWU7IG90aGVyd2lzZSwgcmVqZWN0XG5cdFx0XHRcdGlmICggZ290b0VuZCApIHtcblx0XHRcdFx0XHRkZWZlcnJlZC5ub3RpZnlXaXRoKCBlbGVtLCBbIGFuaW1hdGlvbiwgMSwgMCBdICk7XG5cdFx0XHRcdFx0ZGVmZXJyZWQucmVzb2x2ZVdpdGgoIGVsZW0sIFsgYW5pbWF0aW9uLCBnb3RvRW5kIF0gKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRkZWZlcnJlZC5yZWplY3RXaXRoKCBlbGVtLCBbIGFuaW1hdGlvbiwgZ290b0VuZCBdICk7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHR9XG5cdFx0fSApLFxuXHRcdHByb3BzID0gYW5pbWF0aW9uLnByb3BzO1xuXG5cdHByb3BGaWx0ZXIoIHByb3BzLCBhbmltYXRpb24ub3B0cy5zcGVjaWFsRWFzaW5nICk7XG5cblx0Zm9yICggOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKyApIHtcblx0XHRyZXN1bHQgPSBBbmltYXRpb24ucHJlZmlsdGVyc1sgaW5kZXggXS5jYWxsKCBhbmltYXRpb24sIGVsZW0sIHByb3BzLCBhbmltYXRpb24ub3B0cyApO1xuXHRcdGlmICggcmVzdWx0ICkge1xuXHRcdFx0aWYgKCBpc0Z1bmN0aW9uKCByZXN1bHQuc3RvcCApICkge1xuXHRcdFx0XHRqUXVlcnkuX3F1ZXVlSG9va3MoIGFuaW1hdGlvbi5lbGVtLCBhbmltYXRpb24ub3B0cy5xdWV1ZSApLnN0b3AgPVxuXHRcdFx0XHRcdHJlc3VsdC5zdG9wLmJpbmQoIHJlc3VsdCApO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHR9XG5cdH1cblxuXHRqUXVlcnkubWFwKCBwcm9wcywgY3JlYXRlVHdlZW4sIGFuaW1hdGlvbiApO1xuXG5cdGlmICggaXNGdW5jdGlvbiggYW5pbWF0aW9uLm9wdHMuc3RhcnQgKSApIHtcblx0XHRhbmltYXRpb24ub3B0cy5zdGFydC5jYWxsKCBlbGVtLCBhbmltYXRpb24gKTtcblx0fVxuXG5cdC8vIEF0dGFjaCBjYWxsYmFja3MgZnJvbSBvcHRpb25zXG5cdGFuaW1hdGlvblxuXHRcdC5wcm9ncmVzcyggYW5pbWF0aW9uLm9wdHMucHJvZ3Jlc3MgKVxuXHRcdC5kb25lKCBhbmltYXRpb24ub3B0cy5kb25lLCBhbmltYXRpb24ub3B0cy5jb21wbGV0ZSApXG5cdFx0LmZhaWwoIGFuaW1hdGlvbi5vcHRzLmZhaWwgKVxuXHRcdC5hbHdheXMoIGFuaW1hdGlvbi5vcHRzLmFsd2F5cyApO1xuXG5cdGpRdWVyeS5meC50aW1lcihcblx0XHRqUXVlcnkuZXh0ZW5kKCB0aWNrLCB7XG5cdFx0XHRlbGVtOiBlbGVtLFxuXHRcdFx0YW5pbTogYW5pbWF0aW9uLFxuXHRcdFx0cXVldWU6IGFuaW1hdGlvbi5vcHRzLnF1ZXVlXG5cdFx0fSApXG5cdCk7XG5cblx0cmV0dXJuIGFuaW1hdGlvbjtcbn1cblxualF1ZXJ5LkFuaW1hdGlvbiA9IGpRdWVyeS5leHRlbmQoIEFuaW1hdGlvbiwge1xuXG5cdHR3ZWVuZXJzOiB7XG5cdFx0XCIqXCI6IFsgZnVuY3Rpb24oIHByb3AsIHZhbHVlICkge1xuXHRcdFx0dmFyIHR3ZWVuID0gdGhpcy5jcmVhdGVUd2VlbiggcHJvcCwgdmFsdWUgKTtcblx0XHRcdGFkanVzdENTUyggdHdlZW4uZWxlbSwgcHJvcCwgcmNzc051bS5leGVjKCB2YWx1ZSApLCB0d2VlbiApO1xuXHRcdFx0cmV0dXJuIHR3ZWVuO1xuXHRcdH0gXVxuXHR9LFxuXG5cdHR3ZWVuZXI6IGZ1bmN0aW9uKCBwcm9wcywgY2FsbGJhY2sgKSB7XG5cdFx0aWYgKCBpc0Z1bmN0aW9uKCBwcm9wcyApICkge1xuXHRcdFx0Y2FsbGJhY2sgPSBwcm9wcztcblx0XHRcdHByb3BzID0gWyBcIipcIiBdO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRwcm9wcyA9IHByb3BzLm1hdGNoKCBybm90aHRtbHdoaXRlICk7XG5cdFx0fVxuXG5cdFx0dmFyIHByb3AsXG5cdFx0XHRpbmRleCA9IDAsXG5cdFx0XHRsZW5ndGggPSBwcm9wcy5sZW5ndGg7XG5cblx0XHRmb3IgKCA7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrICkge1xuXHRcdFx0cHJvcCA9IHByb3BzWyBpbmRleCBdO1xuXHRcdFx0QW5pbWF0aW9uLnR3ZWVuZXJzWyBwcm9wIF0gPSBBbmltYXRpb24udHdlZW5lcnNbIHByb3AgXSB8fCBbXTtcblx0XHRcdEFuaW1hdGlvbi50d2VlbmVyc1sgcHJvcCBdLnVuc2hpZnQoIGNhbGxiYWNrICk7XG5cdFx0fVxuXHR9LFxuXG5cdHByZWZpbHRlcnM6IFsgZGVmYXVsdFByZWZpbHRlciBdLFxuXG5cdHByZWZpbHRlcjogZnVuY3Rpb24oIGNhbGxiYWNrLCBwcmVwZW5kICkge1xuXHRcdGlmICggcHJlcGVuZCApIHtcblx0XHRcdEFuaW1hdGlvbi5wcmVmaWx0ZXJzLnVuc2hpZnQoIGNhbGxiYWNrICk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdEFuaW1hdGlvbi5wcmVmaWx0ZXJzLnB1c2goIGNhbGxiYWNrICk7XG5cdFx0fVxuXHR9XG59ICk7XG5cbmpRdWVyeS5zcGVlZCA9IGZ1bmN0aW9uKCBzcGVlZCwgZWFzaW5nLCBmbiApIHtcblx0dmFyIG9wdCA9IHNwZWVkICYmIHR5cGVvZiBzcGVlZCA9PT0gXCJvYmplY3RcIiA/IGpRdWVyeS5leHRlbmQoIHt9LCBzcGVlZCApIDoge1xuXHRcdGNvbXBsZXRlOiBmbiB8fCAhZm4gJiYgZWFzaW5nIHx8XG5cdFx0XHRpc0Z1bmN0aW9uKCBzcGVlZCApICYmIHNwZWVkLFxuXHRcdGR1cmF0aW9uOiBzcGVlZCxcblx0XHRlYXNpbmc6IGZuICYmIGVhc2luZyB8fCBlYXNpbmcgJiYgIWlzRnVuY3Rpb24oIGVhc2luZyApICYmIGVhc2luZ1xuXHR9O1xuXG5cdC8vIEdvIHRvIHRoZSBlbmQgc3RhdGUgaWYgZnggYXJlIG9mZlxuXHRpZiAoIGpRdWVyeS5meC5vZmYgKSB7XG5cdFx0b3B0LmR1cmF0aW9uID0gMDtcblxuXHR9IGVsc2Uge1xuXHRcdGlmICggdHlwZW9mIG9wdC5kdXJhdGlvbiAhPT0gXCJudW1iZXJcIiApIHtcblx0XHRcdGlmICggb3B0LmR1cmF0aW9uIGluIGpRdWVyeS5meC5zcGVlZHMgKSB7XG5cdFx0XHRcdG9wdC5kdXJhdGlvbiA9IGpRdWVyeS5meC5zcGVlZHNbIG9wdC5kdXJhdGlvbiBdO1xuXG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRvcHQuZHVyYXRpb24gPSBqUXVlcnkuZnguc3BlZWRzLl9kZWZhdWx0O1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC8vIE5vcm1hbGl6ZSBvcHQucXVldWUgLSB0cnVlL3VuZGVmaW5lZC9udWxsIC0+IFwiZnhcIlxuXHRpZiAoIG9wdC5xdWV1ZSA9PSBudWxsIHx8IG9wdC5xdWV1ZSA9PT0gdHJ1ZSApIHtcblx0XHRvcHQucXVldWUgPSBcImZ4XCI7XG5cdH1cblxuXHQvLyBRdWV1ZWluZ1xuXHRvcHQub2xkID0gb3B0LmNvbXBsZXRlO1xuXG5cdG9wdC5jb21wbGV0ZSA9IGZ1bmN0aW9uKCkge1xuXHRcdGlmICggaXNGdW5jdGlvbiggb3B0Lm9sZCApICkge1xuXHRcdFx0b3B0Lm9sZC5jYWxsKCB0aGlzICk7XG5cdFx0fVxuXG5cdFx0aWYgKCBvcHQucXVldWUgKSB7XG5cdFx0XHRqUXVlcnkuZGVxdWV1ZSggdGhpcywgb3B0LnF1ZXVlICk7XG5cdFx0fVxuXHR9O1xuXG5cdHJldHVybiBvcHQ7XG59O1xuXG5qUXVlcnkuZm4uZXh0ZW5kKCB7XG5cdGZhZGVUbzogZnVuY3Rpb24oIHNwZWVkLCB0bywgZWFzaW5nLCBjYWxsYmFjayApIHtcblxuXHRcdC8vIFNob3cgYW55IGhpZGRlbiBlbGVtZW50cyBhZnRlciBzZXR0aW5nIG9wYWNpdHkgdG8gMFxuXHRcdHJldHVybiB0aGlzLmZpbHRlciggaXNIaWRkZW5XaXRoaW5UcmVlICkuY3NzKCBcIm9wYWNpdHlcIiwgMCApLnNob3coKVxuXG5cdFx0XHQvLyBBbmltYXRlIHRvIHRoZSB2YWx1ZSBzcGVjaWZpZWRcblx0XHRcdC5lbmQoKS5hbmltYXRlKCB7IG9wYWNpdHk6IHRvIH0sIHNwZWVkLCBlYXNpbmcsIGNhbGxiYWNrICk7XG5cdH0sXG5cdGFuaW1hdGU6IGZ1bmN0aW9uKCBwcm9wLCBzcGVlZCwgZWFzaW5nLCBjYWxsYmFjayApIHtcblx0XHR2YXIgZW1wdHkgPSBqUXVlcnkuaXNFbXB0eU9iamVjdCggcHJvcCApLFxuXHRcdFx0b3B0YWxsID0galF1ZXJ5LnNwZWVkKCBzcGVlZCwgZWFzaW5nLCBjYWxsYmFjayApLFxuXHRcdFx0ZG9BbmltYXRpb24gPSBmdW5jdGlvbigpIHtcblxuXHRcdFx0XHQvLyBPcGVyYXRlIG9uIGEgY29weSBvZiBwcm9wIHNvIHBlci1wcm9wZXJ0eSBlYXNpbmcgd29uJ3QgYmUgbG9zdFxuXHRcdFx0XHR2YXIgYW5pbSA9IEFuaW1hdGlvbiggdGhpcywgalF1ZXJ5LmV4dGVuZCgge30sIHByb3AgKSwgb3B0YWxsICk7XG5cblx0XHRcdFx0Ly8gRW1wdHkgYW5pbWF0aW9ucywgb3IgZmluaXNoaW5nIHJlc29sdmVzIGltbWVkaWF0ZWx5XG5cdFx0XHRcdGlmICggZW1wdHkgfHwgZGF0YVByaXYuZ2V0KCB0aGlzLCBcImZpbmlzaFwiICkgKSB7XG5cdFx0XHRcdFx0YW5pbS5zdG9wKCB0cnVlICk7XG5cdFx0XHRcdH1cblx0XHRcdH07XG5cblx0XHRkb0FuaW1hdGlvbi5maW5pc2ggPSBkb0FuaW1hdGlvbjtcblxuXHRcdHJldHVybiBlbXB0eSB8fCBvcHRhbGwucXVldWUgPT09IGZhbHNlID9cblx0XHRcdHRoaXMuZWFjaCggZG9BbmltYXRpb24gKSA6XG5cdFx0XHR0aGlzLnF1ZXVlKCBvcHRhbGwucXVldWUsIGRvQW5pbWF0aW9uICk7XG5cdH0sXG5cdHN0b3A6IGZ1bmN0aW9uKCB0eXBlLCBjbGVhclF1ZXVlLCBnb3RvRW5kICkge1xuXHRcdHZhciBzdG9wUXVldWUgPSBmdW5jdGlvbiggaG9va3MgKSB7XG5cdFx0XHR2YXIgc3RvcCA9IGhvb2tzLnN0b3A7XG5cdFx0XHRkZWxldGUgaG9va3Muc3RvcDtcblx0XHRcdHN0b3AoIGdvdG9FbmQgKTtcblx0XHR9O1xuXG5cdFx0aWYgKCB0eXBlb2YgdHlwZSAhPT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdGdvdG9FbmQgPSBjbGVhclF1ZXVlO1xuXHRcdFx0Y2xlYXJRdWV1ZSA9IHR5cGU7XG5cdFx0XHR0eXBlID0gdW5kZWZpbmVkO1xuXHRcdH1cblx0XHRpZiAoIGNsZWFyUXVldWUgKSB7XG5cdFx0XHR0aGlzLnF1ZXVlKCB0eXBlIHx8IFwiZnhcIiwgW10gKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcblx0XHRcdHZhciBkZXF1ZXVlID0gdHJ1ZSxcblx0XHRcdFx0aW5kZXggPSB0eXBlICE9IG51bGwgJiYgdHlwZSArIFwicXVldWVIb29rc1wiLFxuXHRcdFx0XHR0aW1lcnMgPSBqUXVlcnkudGltZXJzLFxuXHRcdFx0XHRkYXRhID0gZGF0YVByaXYuZ2V0KCB0aGlzICk7XG5cblx0XHRcdGlmICggaW5kZXggKSB7XG5cdFx0XHRcdGlmICggZGF0YVsgaW5kZXggXSAmJiBkYXRhWyBpbmRleCBdLnN0b3AgKSB7XG5cdFx0XHRcdFx0c3RvcFF1ZXVlKCBkYXRhWyBpbmRleCBdICk7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGZvciAoIGluZGV4IGluIGRhdGEgKSB7XG5cdFx0XHRcdFx0aWYgKCBkYXRhWyBpbmRleCBdICYmIGRhdGFbIGluZGV4IF0uc3RvcCAmJiBycnVuLnRlc3QoIGluZGV4ICkgKSB7XG5cdFx0XHRcdFx0XHRzdG9wUXVldWUoIGRhdGFbIGluZGV4IF0gKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Zm9yICggaW5kZXggPSB0aW1lcnMubGVuZ3RoOyBpbmRleC0tOyApIHtcblx0XHRcdFx0aWYgKCB0aW1lcnNbIGluZGV4IF0uZWxlbSA9PT0gdGhpcyAmJlxuXHRcdFx0XHRcdCggdHlwZSA9PSBudWxsIHx8IHRpbWVyc1sgaW5kZXggXS5xdWV1ZSA9PT0gdHlwZSApICkge1xuXG5cdFx0XHRcdFx0dGltZXJzWyBpbmRleCBdLmFuaW0uc3RvcCggZ290b0VuZCApO1xuXHRcdFx0XHRcdGRlcXVldWUgPSBmYWxzZTtcblx0XHRcdFx0XHR0aW1lcnMuc3BsaWNlKCBpbmRleCwgMSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIFN0YXJ0IHRoZSBuZXh0IGluIHRoZSBxdWV1ZSBpZiB0aGUgbGFzdCBzdGVwIHdhc24ndCBmb3JjZWQuXG5cdFx0XHQvLyBUaW1lcnMgY3VycmVudGx5IHdpbGwgY2FsbCB0aGVpciBjb21wbGV0ZSBjYWxsYmFja3MsIHdoaWNoXG5cdFx0XHQvLyB3aWxsIGRlcXVldWUgYnV0IG9ubHkgaWYgdGhleSB3ZXJlIGdvdG9FbmQuXG5cdFx0XHRpZiAoIGRlcXVldWUgfHwgIWdvdG9FbmQgKSB7XG5cdFx0XHRcdGpRdWVyeS5kZXF1ZXVlKCB0aGlzLCB0eXBlICk7XG5cdFx0XHR9XG5cdFx0fSApO1xuXHR9LFxuXHRmaW5pc2g6IGZ1bmN0aW9uKCB0eXBlICkge1xuXHRcdGlmICggdHlwZSAhPT0gZmFsc2UgKSB7XG5cdFx0XHR0eXBlID0gdHlwZSB8fCBcImZ4XCI7XG5cdFx0fVxuXHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIGluZGV4LFxuXHRcdFx0XHRkYXRhID0gZGF0YVByaXYuZ2V0KCB0aGlzICksXG5cdFx0XHRcdHF1ZXVlID0gZGF0YVsgdHlwZSArIFwicXVldWVcIiBdLFxuXHRcdFx0XHRob29rcyA9IGRhdGFbIHR5cGUgKyBcInF1ZXVlSG9va3NcIiBdLFxuXHRcdFx0XHR0aW1lcnMgPSBqUXVlcnkudGltZXJzLFxuXHRcdFx0XHRsZW5ndGggPSBxdWV1ZSA/IHF1ZXVlLmxlbmd0aCA6IDA7XG5cblx0XHRcdC8vIEVuYWJsZSBmaW5pc2hpbmcgZmxhZyBvbiBwcml2YXRlIGRhdGFcblx0XHRcdGRhdGEuZmluaXNoID0gdHJ1ZTtcblxuXHRcdFx0Ly8gRW1wdHkgdGhlIHF1ZXVlIGZpcnN0XG5cdFx0XHRqUXVlcnkucXVldWUoIHRoaXMsIHR5cGUsIFtdICk7XG5cblx0XHRcdGlmICggaG9va3MgJiYgaG9va3Muc3RvcCApIHtcblx0XHRcdFx0aG9va3Muc3RvcC5jYWxsKCB0aGlzLCB0cnVlICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIExvb2sgZm9yIGFueSBhY3RpdmUgYW5pbWF0aW9ucywgYW5kIGZpbmlzaCB0aGVtXG5cdFx0XHRmb3IgKCBpbmRleCA9IHRpbWVycy5sZW5ndGg7IGluZGV4LS07ICkge1xuXHRcdFx0XHRpZiAoIHRpbWVyc1sgaW5kZXggXS5lbGVtID09PSB0aGlzICYmIHRpbWVyc1sgaW5kZXggXS5xdWV1ZSA9PT0gdHlwZSApIHtcblx0XHRcdFx0XHR0aW1lcnNbIGluZGV4IF0uYW5pbS5zdG9wKCB0cnVlICk7XG5cdFx0XHRcdFx0dGltZXJzLnNwbGljZSggaW5kZXgsIDEgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBMb29rIGZvciBhbnkgYW5pbWF0aW9ucyBpbiB0aGUgb2xkIHF1ZXVlIGFuZCBmaW5pc2ggdGhlbVxuXHRcdFx0Zm9yICggaW5kZXggPSAwOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKyApIHtcblx0XHRcdFx0aWYgKCBxdWV1ZVsgaW5kZXggXSAmJiBxdWV1ZVsgaW5kZXggXS5maW5pc2ggKSB7XG5cdFx0XHRcdFx0cXVldWVbIGluZGV4IF0uZmluaXNoLmNhbGwoIHRoaXMgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBUdXJuIG9mZiBmaW5pc2hpbmcgZmxhZ1xuXHRcdFx0ZGVsZXRlIGRhdGEuZmluaXNoO1xuXHRcdH0gKTtcblx0fVxufSApO1xuXG5qUXVlcnkuZWFjaCggWyBcInRvZ2dsZVwiLCBcInNob3dcIiwgXCJoaWRlXCIgXSwgZnVuY3Rpb24oIF9pLCBuYW1lICkge1xuXHR2YXIgY3NzRm4gPSBqUXVlcnkuZm5bIG5hbWUgXTtcblx0alF1ZXJ5LmZuWyBuYW1lIF0gPSBmdW5jdGlvbiggc3BlZWQsIGVhc2luZywgY2FsbGJhY2sgKSB7XG5cdFx0cmV0dXJuIHNwZWVkID09IG51bGwgfHwgdHlwZW9mIHNwZWVkID09PSBcImJvb2xlYW5cIiA/XG5cdFx0XHRjc3NGbi5hcHBseSggdGhpcywgYXJndW1lbnRzICkgOlxuXHRcdFx0dGhpcy5hbmltYXRlKCBnZW5GeCggbmFtZSwgdHJ1ZSApLCBzcGVlZCwgZWFzaW5nLCBjYWxsYmFjayApO1xuXHR9O1xufSApO1xuXG4vLyBHZW5lcmF0ZSBzaG9ydGN1dHMgZm9yIGN1c3RvbSBhbmltYXRpb25zXG5qUXVlcnkuZWFjaCgge1xuXHRzbGlkZURvd246IGdlbkZ4KCBcInNob3dcIiApLFxuXHRzbGlkZVVwOiBnZW5GeCggXCJoaWRlXCIgKSxcblx0c2xpZGVUb2dnbGU6IGdlbkZ4KCBcInRvZ2dsZVwiICksXG5cdGZhZGVJbjogeyBvcGFjaXR5OiBcInNob3dcIiB9LFxuXHRmYWRlT3V0OiB7IG9wYWNpdHk6IFwiaGlkZVwiIH0sXG5cdGZhZGVUb2dnbGU6IHsgb3BhY2l0eTogXCJ0b2dnbGVcIiB9XG59LCBmdW5jdGlvbiggbmFtZSwgcHJvcHMgKSB7XG5cdGpRdWVyeS5mblsgbmFtZSBdID0gZnVuY3Rpb24oIHNwZWVkLCBlYXNpbmcsIGNhbGxiYWNrICkge1xuXHRcdHJldHVybiB0aGlzLmFuaW1hdGUoIHByb3BzLCBzcGVlZCwgZWFzaW5nLCBjYWxsYmFjayApO1xuXHR9O1xufSApO1xuXG5qUXVlcnkudGltZXJzID0gW107XG5qUXVlcnkuZngudGljayA9IGZ1bmN0aW9uKCkge1xuXHR2YXIgdGltZXIsXG5cdFx0aSA9IDAsXG5cdFx0dGltZXJzID0galF1ZXJ5LnRpbWVycztcblxuXHRmeE5vdyA9IERhdGUubm93KCk7XG5cblx0Zm9yICggOyBpIDwgdGltZXJzLmxlbmd0aDsgaSsrICkge1xuXHRcdHRpbWVyID0gdGltZXJzWyBpIF07XG5cblx0XHQvLyBSdW4gdGhlIHRpbWVyIGFuZCBzYWZlbHkgcmVtb3ZlIGl0IHdoZW4gZG9uZSAoYWxsb3dpbmcgZm9yIGV4dGVybmFsIHJlbW92YWwpXG5cdFx0aWYgKCAhdGltZXIoKSAmJiB0aW1lcnNbIGkgXSA9PT0gdGltZXIgKSB7XG5cdFx0XHR0aW1lcnMuc3BsaWNlKCBpLS0sIDEgKTtcblx0XHR9XG5cdH1cblxuXHRpZiAoICF0aW1lcnMubGVuZ3RoICkge1xuXHRcdGpRdWVyeS5meC5zdG9wKCk7XG5cdH1cblx0ZnhOb3cgPSB1bmRlZmluZWQ7XG59O1xuXG5qUXVlcnkuZngudGltZXIgPSBmdW5jdGlvbiggdGltZXIgKSB7XG5cdGpRdWVyeS50aW1lcnMucHVzaCggdGltZXIgKTtcblx0alF1ZXJ5LmZ4LnN0YXJ0KCk7XG59O1xuXG5qUXVlcnkuZnguaW50ZXJ2YWwgPSAxMztcbmpRdWVyeS5meC5zdGFydCA9IGZ1bmN0aW9uKCkge1xuXHRpZiAoIGluUHJvZ3Jlc3MgKSB7XG5cdFx0cmV0dXJuO1xuXHR9XG5cblx0aW5Qcm9ncmVzcyA9IHRydWU7XG5cdHNjaGVkdWxlKCk7XG59O1xuXG5qUXVlcnkuZnguc3RvcCA9IGZ1bmN0aW9uKCkge1xuXHRpblByb2dyZXNzID0gbnVsbDtcbn07XG5cbmpRdWVyeS5meC5zcGVlZHMgPSB7XG5cdHNsb3c6IDYwMCxcblx0ZmFzdDogMjAwLFxuXG5cdC8vIERlZmF1bHQgc3BlZWRcblx0X2RlZmF1bHQ6IDQwMFxufTtcblxuXG4vLyBCYXNlZCBvZmYgb2YgdGhlIHBsdWdpbiBieSBDbGludCBIZWxmZXJzLCB3aXRoIHBlcm1pc3Npb24uXG4vLyBodHRwczovL3dlYi5hcmNoaXZlLm9yZy93ZWIvMjAxMDAzMjQwMTQ3NDcvaHR0cDovL2JsaW5kc2lnbmFscy5jb20vaW5kZXgucGhwLzIwMDkvMDcvanF1ZXJ5LWRlbGF5L1xualF1ZXJ5LmZuLmRlbGF5ID0gZnVuY3Rpb24oIHRpbWUsIHR5cGUgKSB7XG5cdHRpbWUgPSBqUXVlcnkuZnggPyBqUXVlcnkuZnguc3BlZWRzWyB0aW1lIF0gfHwgdGltZSA6IHRpbWU7XG5cdHR5cGUgPSB0eXBlIHx8IFwiZnhcIjtcblxuXHRyZXR1cm4gdGhpcy5xdWV1ZSggdHlwZSwgZnVuY3Rpb24oIG5leHQsIGhvb2tzICkge1xuXHRcdHZhciB0aW1lb3V0ID0gd2luZG93LnNldFRpbWVvdXQoIG5leHQsIHRpbWUgKTtcblx0XHRob29rcy5zdG9wID0gZnVuY3Rpb24oKSB7XG5cdFx0XHR3aW5kb3cuY2xlYXJUaW1lb3V0KCB0aW1lb3V0ICk7XG5cdFx0fTtcblx0fSApO1xufTtcblxuXG4oIGZ1bmN0aW9uKCkge1xuXHR2YXIgaW5wdXQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImlucHV0XCIgKSxcblx0XHRzZWxlY3QgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcInNlbGVjdFwiICksXG5cdFx0b3B0ID0gc2VsZWN0LmFwcGVuZENoaWxkKCBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcIm9wdGlvblwiICkgKTtcblxuXHRpbnB1dC50eXBlID0gXCJjaGVja2JveFwiO1xuXG5cdC8vIFN1cHBvcnQ6IEFuZHJvaWQgPD00LjMgb25seVxuXHQvLyBEZWZhdWx0IHZhbHVlIGZvciBhIGNoZWNrYm94IHNob3VsZCBiZSBcIm9uXCJcblx0c3VwcG9ydC5jaGVja09uID0gaW5wdXQudmFsdWUgIT09IFwiXCI7XG5cblx0Ly8gU3VwcG9ydDogSUUgPD0xMSBvbmx5XG5cdC8vIE11c3QgYWNjZXNzIHNlbGVjdGVkSW5kZXggdG8gbWFrZSBkZWZhdWx0IG9wdGlvbnMgc2VsZWN0XG5cdHN1cHBvcnQub3B0U2VsZWN0ZWQgPSBvcHQuc2VsZWN0ZWQ7XG5cblx0Ly8gU3VwcG9ydDogSUUgPD0xMSBvbmx5XG5cdC8vIEFuIGlucHV0IGxvc2VzIGl0cyB2YWx1ZSBhZnRlciBiZWNvbWluZyBhIHJhZGlvXG5cdGlucHV0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJpbnB1dFwiICk7XG5cdGlucHV0LnZhbHVlID0gXCJ0XCI7XG5cdGlucHV0LnR5cGUgPSBcInJhZGlvXCI7XG5cdHN1cHBvcnQucmFkaW9WYWx1ZSA9IGlucHV0LnZhbHVlID09PSBcInRcIjtcbn0gKSgpO1xuXG5cbnZhciBib29sSG9vayxcblx0YXR0ckhhbmRsZSA9IGpRdWVyeS5leHByLmF0dHJIYW5kbGU7XG5cbmpRdWVyeS5mbi5leHRlbmQoIHtcblx0YXR0cjogZnVuY3Rpb24oIG5hbWUsIHZhbHVlICkge1xuXHRcdHJldHVybiBhY2Nlc3MoIHRoaXMsIGpRdWVyeS5hdHRyLCBuYW1lLCB2YWx1ZSwgYXJndW1lbnRzLmxlbmd0aCA+IDEgKTtcblx0fSxcblxuXHRyZW1vdmVBdHRyOiBmdW5jdGlvbiggbmFtZSApIHtcblx0XHRyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcblx0XHRcdGpRdWVyeS5yZW1vdmVBdHRyKCB0aGlzLCBuYW1lICk7XG5cdFx0fSApO1xuXHR9XG59ICk7XG5cbmpRdWVyeS5leHRlbmQoIHtcblx0YXR0cjogZnVuY3Rpb24oIGVsZW0sIG5hbWUsIHZhbHVlICkge1xuXHRcdHZhciByZXQsIGhvb2tzLFxuXHRcdFx0blR5cGUgPSBlbGVtLm5vZGVUeXBlO1xuXG5cdFx0Ly8gRG9uJ3QgZ2V0L3NldCBhdHRyaWJ1dGVzIG9uIHRleHQsIGNvbW1lbnQgYW5kIGF0dHJpYnV0ZSBub2Rlc1xuXHRcdGlmICggblR5cGUgPT09IDMgfHwgblR5cGUgPT09IDggfHwgblR5cGUgPT09IDIgKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gRmFsbGJhY2sgdG8gcHJvcCB3aGVuIGF0dHJpYnV0ZXMgYXJlIG5vdCBzdXBwb3J0ZWRcblx0XHRpZiAoIHR5cGVvZiBlbGVtLmdldEF0dHJpYnV0ZSA9PT0gXCJ1bmRlZmluZWRcIiApIHtcblx0XHRcdHJldHVybiBqUXVlcnkucHJvcCggZWxlbSwgbmFtZSwgdmFsdWUgKTtcblx0XHR9XG5cblx0XHQvLyBBdHRyaWJ1dGUgaG9va3MgYXJlIGRldGVybWluZWQgYnkgdGhlIGxvd2VyY2FzZSB2ZXJzaW9uXG5cdFx0Ly8gR3JhYiBuZWNlc3NhcnkgaG9vayBpZiBvbmUgaXMgZGVmaW5lZFxuXHRcdGlmICggblR5cGUgIT09IDEgfHwgIWpRdWVyeS5pc1hNTERvYyggZWxlbSApICkge1xuXHRcdFx0aG9va3MgPSBqUXVlcnkuYXR0ckhvb2tzWyBuYW1lLnRvTG93ZXJDYXNlKCkgXSB8fFxuXHRcdFx0XHQoIGpRdWVyeS5leHByLm1hdGNoLmJvb2wudGVzdCggbmFtZSApID8gYm9vbEhvb2sgOiB1bmRlZmluZWQgKTtcblx0XHR9XG5cblx0XHRpZiAoIHZhbHVlICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRpZiAoIHZhbHVlID09PSBudWxsICkge1xuXHRcdFx0XHRqUXVlcnkucmVtb3ZlQXR0ciggZWxlbSwgbmFtZSApO1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdGlmICggaG9va3MgJiYgXCJzZXRcIiBpbiBob29rcyAmJlxuXHRcdFx0XHQoIHJldCA9IGhvb2tzLnNldCggZWxlbSwgdmFsdWUsIG5hbWUgKSApICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdHJldHVybiByZXQ7XG5cdFx0XHR9XG5cblx0XHRcdGVsZW0uc2V0QXR0cmlidXRlKCBuYW1lLCB2YWx1ZSArIFwiXCIgKTtcblx0XHRcdHJldHVybiB2YWx1ZTtcblx0XHR9XG5cblx0XHRpZiAoIGhvb2tzICYmIFwiZ2V0XCIgaW4gaG9va3MgJiYgKCByZXQgPSBob29rcy5nZXQoIGVsZW0sIG5hbWUgKSApICE9PSBudWxsICkge1xuXHRcdFx0cmV0dXJuIHJldDtcblx0XHR9XG5cblx0XHRyZXQgPSBqUXVlcnkuZmluZC5hdHRyKCBlbGVtLCBuYW1lICk7XG5cblx0XHQvLyBOb24tZXhpc3RlbnQgYXR0cmlidXRlcyByZXR1cm4gbnVsbCwgd2Ugbm9ybWFsaXplIHRvIHVuZGVmaW5lZFxuXHRcdHJldHVybiByZXQgPT0gbnVsbCA/IHVuZGVmaW5lZCA6IHJldDtcblx0fSxcblxuXHRhdHRySG9va3M6IHtcblx0XHR0eXBlOiB7XG5cdFx0XHRzZXQ6IGZ1bmN0aW9uKCBlbGVtLCB2YWx1ZSApIHtcblx0XHRcdFx0aWYgKCAhc3VwcG9ydC5yYWRpb1ZhbHVlICYmIHZhbHVlID09PSBcInJhZGlvXCIgJiZcblx0XHRcdFx0XHRub2RlTmFtZSggZWxlbSwgXCJpbnB1dFwiICkgKSB7XG5cdFx0XHRcdFx0dmFyIHZhbCA9IGVsZW0udmFsdWU7XG5cdFx0XHRcdFx0ZWxlbS5zZXRBdHRyaWJ1dGUoIFwidHlwZVwiLCB2YWx1ZSApO1xuXHRcdFx0XHRcdGlmICggdmFsICkge1xuXHRcdFx0XHRcdFx0ZWxlbS52YWx1ZSA9IHZhbDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0cmV0dXJuIHZhbHVlO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9LFxuXG5cdHJlbW92ZUF0dHI6IGZ1bmN0aW9uKCBlbGVtLCB2YWx1ZSApIHtcblx0XHR2YXIgbmFtZSxcblx0XHRcdGkgPSAwLFxuXG5cdFx0XHQvLyBBdHRyaWJ1dGUgbmFtZXMgY2FuIGNvbnRhaW4gbm9uLUhUTUwgd2hpdGVzcGFjZSBjaGFyYWN0ZXJzXG5cdFx0XHQvLyBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9zeW50YXguaHRtbCNhdHRyaWJ1dGVzLTJcblx0XHRcdGF0dHJOYW1lcyA9IHZhbHVlICYmIHZhbHVlLm1hdGNoKCBybm90aHRtbHdoaXRlICk7XG5cblx0XHRpZiAoIGF0dHJOYW1lcyAmJiBlbGVtLm5vZGVUeXBlID09PSAxICkge1xuXHRcdFx0d2hpbGUgKCAoIG5hbWUgPSBhdHRyTmFtZXNbIGkrKyBdICkgKSB7XG5cdFx0XHRcdGVsZW0ucmVtb3ZlQXR0cmlidXRlKCBuYW1lICk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG59ICk7XG5cbi8vIEhvb2tzIGZvciBib29sZWFuIGF0dHJpYnV0ZXNcbmJvb2xIb29rID0ge1xuXHRzZXQ6IGZ1bmN0aW9uKCBlbGVtLCB2YWx1ZSwgbmFtZSApIHtcblx0XHRpZiAoIHZhbHVlID09PSBmYWxzZSApIHtcblxuXHRcdFx0Ly8gUmVtb3ZlIGJvb2xlYW4gYXR0cmlidXRlcyB3aGVuIHNldCB0byBmYWxzZVxuXHRcdFx0alF1ZXJ5LnJlbW92ZUF0dHIoIGVsZW0sIG5hbWUgKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0ZWxlbS5zZXRBdHRyaWJ1dGUoIG5hbWUsIG5hbWUgKTtcblx0XHR9XG5cdFx0cmV0dXJuIG5hbWU7XG5cdH1cbn07XG5cbmpRdWVyeS5lYWNoKCBqUXVlcnkuZXhwci5tYXRjaC5ib29sLnNvdXJjZS5tYXRjaCggL1xcdysvZyApLCBmdW5jdGlvbiggX2ksIG5hbWUgKSB7XG5cdHZhciBnZXR0ZXIgPSBhdHRySGFuZGxlWyBuYW1lIF0gfHwgalF1ZXJ5LmZpbmQuYXR0cjtcblxuXHRhdHRySGFuZGxlWyBuYW1lIF0gPSBmdW5jdGlvbiggZWxlbSwgbmFtZSwgaXNYTUwgKSB7XG5cdFx0dmFyIHJldCwgaGFuZGxlLFxuXHRcdFx0bG93ZXJjYXNlTmFtZSA9IG5hbWUudG9Mb3dlckNhc2UoKTtcblxuXHRcdGlmICggIWlzWE1MICkge1xuXG5cdFx0XHQvLyBBdm9pZCBhbiBpbmZpbml0ZSBsb29wIGJ5IHRlbXBvcmFyaWx5IHJlbW92aW5nIHRoaXMgZnVuY3Rpb24gZnJvbSB0aGUgZ2V0dGVyXG5cdFx0XHRoYW5kbGUgPSBhdHRySGFuZGxlWyBsb3dlcmNhc2VOYW1lIF07XG5cdFx0XHRhdHRySGFuZGxlWyBsb3dlcmNhc2VOYW1lIF0gPSByZXQ7XG5cdFx0XHRyZXQgPSBnZXR0ZXIoIGVsZW0sIG5hbWUsIGlzWE1MICkgIT0gbnVsbCA/XG5cdFx0XHRcdGxvd2VyY2FzZU5hbWUgOlxuXHRcdFx0XHRudWxsO1xuXHRcdFx0YXR0ckhhbmRsZVsgbG93ZXJjYXNlTmFtZSBdID0gaGFuZGxlO1xuXHRcdH1cblx0XHRyZXR1cm4gcmV0O1xuXHR9O1xufSApO1xuXG5cblxuXG52YXIgcmZvY3VzYWJsZSA9IC9eKD86aW5wdXR8c2VsZWN0fHRleHRhcmVhfGJ1dHRvbikkL2ksXG5cdHJjbGlja2FibGUgPSAvXig/OmF8YXJlYSkkL2k7XG5cbmpRdWVyeS5mbi5leHRlbmQoIHtcblx0cHJvcDogZnVuY3Rpb24oIG5hbWUsIHZhbHVlICkge1xuXHRcdHJldHVybiBhY2Nlc3MoIHRoaXMsIGpRdWVyeS5wcm9wLCBuYW1lLCB2YWx1ZSwgYXJndW1lbnRzLmxlbmd0aCA+IDEgKTtcblx0fSxcblxuXHRyZW1vdmVQcm9wOiBmdW5jdGlvbiggbmFtZSApIHtcblx0XHRyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcblx0XHRcdGRlbGV0ZSB0aGlzWyBqUXVlcnkucHJvcEZpeFsgbmFtZSBdIHx8IG5hbWUgXTtcblx0XHR9ICk7XG5cdH1cbn0gKTtcblxualF1ZXJ5LmV4dGVuZCgge1xuXHRwcm9wOiBmdW5jdGlvbiggZWxlbSwgbmFtZSwgdmFsdWUgKSB7XG5cdFx0dmFyIHJldCwgaG9va3MsXG5cdFx0XHRuVHlwZSA9IGVsZW0ubm9kZVR5cGU7XG5cblx0XHQvLyBEb24ndCBnZXQvc2V0IHByb3BlcnRpZXMgb24gdGV4dCwgY29tbWVudCBhbmQgYXR0cmlidXRlIG5vZGVzXG5cdFx0aWYgKCBuVHlwZSA9PT0gMyB8fCBuVHlwZSA9PT0gOCB8fCBuVHlwZSA9PT0gMiApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRpZiAoIG5UeXBlICE9PSAxIHx8ICFqUXVlcnkuaXNYTUxEb2MoIGVsZW0gKSApIHtcblxuXHRcdFx0Ly8gRml4IG5hbWUgYW5kIGF0dGFjaCBob29rc1xuXHRcdFx0bmFtZSA9IGpRdWVyeS5wcm9wRml4WyBuYW1lIF0gfHwgbmFtZTtcblx0XHRcdGhvb2tzID0galF1ZXJ5LnByb3BIb29rc1sgbmFtZSBdO1xuXHRcdH1cblxuXHRcdGlmICggdmFsdWUgIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdGlmICggaG9va3MgJiYgXCJzZXRcIiBpbiBob29rcyAmJlxuXHRcdFx0XHQoIHJldCA9IGhvb2tzLnNldCggZWxlbSwgdmFsdWUsIG5hbWUgKSApICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdHJldHVybiByZXQ7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiAoIGVsZW1bIG5hbWUgXSA9IHZhbHVlICk7XG5cdFx0fVxuXG5cdFx0aWYgKCBob29rcyAmJiBcImdldFwiIGluIGhvb2tzICYmICggcmV0ID0gaG9va3MuZ2V0KCBlbGVtLCBuYW1lICkgKSAhPT0gbnVsbCApIHtcblx0XHRcdHJldHVybiByZXQ7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGVsZW1bIG5hbWUgXTtcblx0fSxcblxuXHRwcm9wSG9va3M6IHtcblx0XHR0YWJJbmRleDoge1xuXHRcdFx0Z2V0OiBmdW5jdGlvbiggZWxlbSApIHtcblxuXHRcdFx0XHQvLyBTdXBwb3J0OiBJRSA8PTkgLSAxMSBvbmx5XG5cdFx0XHRcdC8vIGVsZW0udGFiSW5kZXggZG9lc24ndCBhbHdheXMgcmV0dXJuIHRoZVxuXHRcdFx0XHQvLyBjb3JyZWN0IHZhbHVlIHdoZW4gaXQgaGFzbid0IGJlZW4gZXhwbGljaXRseSBzZXRcblx0XHRcdFx0Ly8gaHR0cHM6Ly93ZWIuYXJjaGl2ZS5vcmcvd2ViLzIwMTQxMTE2MjMzMzQ3L2h0dHA6Ly9mbHVpZHByb2plY3Qub3JnL2Jsb2cvMjAwOC8wMS8wOS9nZXR0aW5nLXNldHRpbmctYW5kLXJlbW92aW5nLXRhYmluZGV4LXZhbHVlcy13aXRoLWphdmFzY3JpcHQvXG5cdFx0XHRcdC8vIFVzZSBwcm9wZXIgYXR0cmlidXRlIHJldHJpZXZhbCgjMTIwNzIpXG5cdFx0XHRcdHZhciB0YWJpbmRleCA9IGpRdWVyeS5maW5kLmF0dHIoIGVsZW0sIFwidGFiaW5kZXhcIiApO1xuXG5cdFx0XHRcdGlmICggdGFiaW5kZXggKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHBhcnNlSW50KCB0YWJpbmRleCwgMTAgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGlmIChcblx0XHRcdFx0XHRyZm9jdXNhYmxlLnRlc3QoIGVsZW0ubm9kZU5hbWUgKSB8fFxuXHRcdFx0XHRcdHJjbGlja2FibGUudGVzdCggZWxlbS5ub2RlTmFtZSApICYmXG5cdFx0XHRcdFx0ZWxlbS5ocmVmXG5cdFx0XHRcdCkge1xuXHRcdFx0XHRcdHJldHVybiAwO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0dXJuIC0xO1xuXHRcdFx0fVxuXHRcdH1cblx0fSxcblxuXHRwcm9wRml4OiB7XG5cdFx0XCJmb3JcIjogXCJodG1sRm9yXCIsXG5cdFx0XCJjbGFzc1wiOiBcImNsYXNzTmFtZVwiXG5cdH1cbn0gKTtcblxuLy8gU3VwcG9ydDogSUUgPD0xMSBvbmx5XG4vLyBBY2Nlc3NpbmcgdGhlIHNlbGVjdGVkSW5kZXggcHJvcGVydHlcbi8vIGZvcmNlcyB0aGUgYnJvd3NlciB0byByZXNwZWN0IHNldHRpbmcgc2VsZWN0ZWRcbi8vIG9uIHRoZSBvcHRpb25cbi8vIFRoZSBnZXR0ZXIgZW5zdXJlcyBhIGRlZmF1bHQgb3B0aW9uIGlzIHNlbGVjdGVkXG4vLyB3aGVuIGluIGFuIG9wdGdyb3VwXG4vLyBlc2xpbnQgcnVsZSBcIm5vLXVudXNlZC1leHByZXNzaW9uc1wiIGlzIGRpc2FibGVkIGZvciB0aGlzIGNvZGVcbi8vIHNpbmNlIGl0IGNvbnNpZGVycyBzdWNoIGFjY2Vzc2lvbnMgbm9vcFxuaWYgKCAhc3VwcG9ydC5vcHRTZWxlY3RlZCApIHtcblx0alF1ZXJ5LnByb3BIb29rcy5zZWxlY3RlZCA9IHtcblx0XHRnZXQ6IGZ1bmN0aW9uKCBlbGVtICkge1xuXG5cdFx0XHQvKiBlc2xpbnQgbm8tdW51c2VkLWV4cHJlc3Npb25zOiBcIm9mZlwiICovXG5cblx0XHRcdHZhciBwYXJlbnQgPSBlbGVtLnBhcmVudE5vZGU7XG5cdFx0XHRpZiAoIHBhcmVudCAmJiBwYXJlbnQucGFyZW50Tm9kZSApIHtcblx0XHRcdFx0cGFyZW50LnBhcmVudE5vZGUuc2VsZWN0ZWRJbmRleDtcblx0XHRcdH1cblx0XHRcdHJldHVybiBudWxsO1xuXHRcdH0sXG5cdFx0c2V0OiBmdW5jdGlvbiggZWxlbSApIHtcblxuXHRcdFx0LyogZXNsaW50IG5vLXVudXNlZC1leHByZXNzaW9uczogXCJvZmZcIiAqL1xuXG5cdFx0XHR2YXIgcGFyZW50ID0gZWxlbS5wYXJlbnROb2RlO1xuXHRcdFx0aWYgKCBwYXJlbnQgKSB7XG5cdFx0XHRcdHBhcmVudC5zZWxlY3RlZEluZGV4O1xuXG5cdFx0XHRcdGlmICggcGFyZW50LnBhcmVudE5vZGUgKSB7XG5cdFx0XHRcdFx0cGFyZW50LnBhcmVudE5vZGUuc2VsZWN0ZWRJbmRleDtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fTtcbn1cblxualF1ZXJ5LmVhY2goIFtcblx0XCJ0YWJJbmRleFwiLFxuXHRcInJlYWRPbmx5XCIsXG5cdFwibWF4TGVuZ3RoXCIsXG5cdFwiY2VsbFNwYWNpbmdcIixcblx0XCJjZWxsUGFkZGluZ1wiLFxuXHRcInJvd1NwYW5cIixcblx0XCJjb2xTcGFuXCIsXG5cdFwidXNlTWFwXCIsXG5cdFwiZnJhbWVCb3JkZXJcIixcblx0XCJjb250ZW50RWRpdGFibGVcIlxuXSwgZnVuY3Rpb24oKSB7XG5cdGpRdWVyeS5wcm9wRml4WyB0aGlzLnRvTG93ZXJDYXNlKCkgXSA9IHRoaXM7XG59ICk7XG5cblxuXG5cblx0Ly8gU3RyaXAgYW5kIGNvbGxhcHNlIHdoaXRlc3BhY2UgYWNjb3JkaW5nIHRvIEhUTUwgc3BlY1xuXHQvLyBodHRwczovL2luZnJhLnNwZWMud2hhdHdnLm9yZy8jc3RyaXAtYW5kLWNvbGxhcHNlLWFzY2lpLXdoaXRlc3BhY2Vcblx0ZnVuY3Rpb24gc3RyaXBBbmRDb2xsYXBzZSggdmFsdWUgKSB7XG5cdFx0dmFyIHRva2VucyA9IHZhbHVlLm1hdGNoKCBybm90aHRtbHdoaXRlICkgfHwgW107XG5cdFx0cmV0dXJuIHRva2Vucy5qb2luKCBcIiBcIiApO1xuXHR9XG5cblxuZnVuY3Rpb24gZ2V0Q2xhc3MoIGVsZW0gKSB7XG5cdHJldHVybiBlbGVtLmdldEF0dHJpYnV0ZSAmJiBlbGVtLmdldEF0dHJpYnV0ZSggXCJjbGFzc1wiICkgfHwgXCJcIjtcbn1cblxuZnVuY3Rpb24gY2xhc3Nlc1RvQXJyYXkoIHZhbHVlICkge1xuXHRpZiAoIEFycmF5LmlzQXJyYXkoIHZhbHVlICkgKSB7XG5cdFx0cmV0dXJuIHZhbHVlO1xuXHR9XG5cdGlmICggdHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiICkge1xuXHRcdHJldHVybiB2YWx1ZS5tYXRjaCggcm5vdGh0bWx3aGl0ZSApIHx8IFtdO1xuXHR9XG5cdHJldHVybiBbXTtcbn1cblxualF1ZXJ5LmZuLmV4dGVuZCgge1xuXHRhZGRDbGFzczogZnVuY3Rpb24oIHZhbHVlICkge1xuXHRcdHZhciBjbGFzc2VzLCBlbGVtLCBjdXIsIGN1clZhbHVlLCBjbGF6eiwgaiwgZmluYWxWYWx1ZSxcblx0XHRcdGkgPSAwO1xuXG5cdFx0aWYgKCBpc0Z1bmN0aW9uKCB2YWx1ZSApICkge1xuXHRcdFx0cmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24oIGogKSB7XG5cdFx0XHRcdGpRdWVyeSggdGhpcyApLmFkZENsYXNzKCB2YWx1ZS5jYWxsKCB0aGlzLCBqLCBnZXRDbGFzcyggdGhpcyApICkgKTtcblx0XHRcdH0gKTtcblx0XHR9XG5cblx0XHRjbGFzc2VzID0gY2xhc3Nlc1RvQXJyYXkoIHZhbHVlICk7XG5cblx0XHRpZiAoIGNsYXNzZXMubGVuZ3RoICkge1xuXHRcdFx0d2hpbGUgKCAoIGVsZW0gPSB0aGlzWyBpKysgXSApICkge1xuXHRcdFx0XHRjdXJWYWx1ZSA9IGdldENsYXNzKCBlbGVtICk7XG5cdFx0XHRcdGN1ciA9IGVsZW0ubm9kZVR5cGUgPT09IDEgJiYgKCBcIiBcIiArIHN0cmlwQW5kQ29sbGFwc2UoIGN1clZhbHVlICkgKyBcIiBcIiApO1xuXG5cdFx0XHRcdGlmICggY3VyICkge1xuXHRcdFx0XHRcdGogPSAwO1xuXHRcdFx0XHRcdHdoaWxlICggKCBjbGF6eiA9IGNsYXNzZXNbIGorKyBdICkgKSB7XG5cdFx0XHRcdFx0XHRpZiAoIGN1ci5pbmRleE9mKCBcIiBcIiArIGNsYXp6ICsgXCIgXCIgKSA8IDAgKSB7XG5cdFx0XHRcdFx0XHRcdGN1ciArPSBjbGF6eiArIFwiIFwiO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIE9ubHkgYXNzaWduIGlmIGRpZmZlcmVudCB0byBhdm9pZCB1bm5lZWRlZCByZW5kZXJpbmcuXG5cdFx0XHRcdFx0ZmluYWxWYWx1ZSA9IHN0cmlwQW5kQ29sbGFwc2UoIGN1ciApO1xuXHRcdFx0XHRcdGlmICggY3VyVmFsdWUgIT09IGZpbmFsVmFsdWUgKSB7XG5cdFx0XHRcdFx0XHRlbGVtLnNldEF0dHJpYnV0ZSggXCJjbGFzc1wiLCBmaW5hbFZhbHVlICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXM7XG5cdH0sXG5cblx0cmVtb3ZlQ2xhc3M6IGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHR2YXIgY2xhc3NlcywgZWxlbSwgY3VyLCBjdXJWYWx1ZSwgY2xhenosIGosIGZpbmFsVmFsdWUsXG5cdFx0XHRpID0gMDtcblxuXHRcdGlmICggaXNGdW5jdGlvbiggdmFsdWUgKSApIHtcblx0XHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCBqICkge1xuXHRcdFx0XHRqUXVlcnkoIHRoaXMgKS5yZW1vdmVDbGFzcyggdmFsdWUuY2FsbCggdGhpcywgaiwgZ2V0Q2xhc3MoIHRoaXMgKSApICk7XG5cdFx0XHR9ICk7XG5cdFx0fVxuXG5cdFx0aWYgKCAhYXJndW1lbnRzLmxlbmd0aCApIHtcblx0XHRcdHJldHVybiB0aGlzLmF0dHIoIFwiY2xhc3NcIiwgXCJcIiApO1xuXHRcdH1cblxuXHRcdGNsYXNzZXMgPSBjbGFzc2VzVG9BcnJheSggdmFsdWUgKTtcblxuXHRcdGlmICggY2xhc3Nlcy5sZW5ndGggKSB7XG5cdFx0XHR3aGlsZSAoICggZWxlbSA9IHRoaXNbIGkrKyBdICkgKSB7XG5cdFx0XHRcdGN1clZhbHVlID0gZ2V0Q2xhc3MoIGVsZW0gKTtcblxuXHRcdFx0XHQvLyBUaGlzIGV4cHJlc3Npb24gaXMgaGVyZSBmb3IgYmV0dGVyIGNvbXByZXNzaWJpbGl0eSAoc2VlIGFkZENsYXNzKVxuXHRcdFx0XHRjdXIgPSBlbGVtLm5vZGVUeXBlID09PSAxICYmICggXCIgXCIgKyBzdHJpcEFuZENvbGxhcHNlKCBjdXJWYWx1ZSApICsgXCIgXCIgKTtcblxuXHRcdFx0XHRpZiAoIGN1ciApIHtcblx0XHRcdFx0XHRqID0gMDtcblx0XHRcdFx0XHR3aGlsZSAoICggY2xhenogPSBjbGFzc2VzWyBqKysgXSApICkge1xuXG5cdFx0XHRcdFx0XHQvLyBSZW1vdmUgKmFsbCogaW5zdGFuY2VzXG5cdFx0XHRcdFx0XHR3aGlsZSAoIGN1ci5pbmRleE9mKCBcIiBcIiArIGNsYXp6ICsgXCIgXCIgKSA+IC0xICkge1xuXHRcdFx0XHRcdFx0XHRjdXIgPSBjdXIucmVwbGFjZSggXCIgXCIgKyBjbGF6eiArIFwiIFwiLCBcIiBcIiApO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIE9ubHkgYXNzaWduIGlmIGRpZmZlcmVudCB0byBhdm9pZCB1bm5lZWRlZCByZW5kZXJpbmcuXG5cdFx0XHRcdFx0ZmluYWxWYWx1ZSA9IHN0cmlwQW5kQ29sbGFwc2UoIGN1ciApO1xuXHRcdFx0XHRcdGlmICggY3VyVmFsdWUgIT09IGZpbmFsVmFsdWUgKSB7XG5cdFx0XHRcdFx0XHRlbGVtLnNldEF0dHJpYnV0ZSggXCJjbGFzc1wiLCBmaW5hbFZhbHVlICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXM7XG5cdH0sXG5cblx0dG9nZ2xlQ2xhc3M6IGZ1bmN0aW9uKCB2YWx1ZSwgc3RhdGVWYWwgKSB7XG5cdFx0dmFyIHR5cGUgPSB0eXBlb2YgdmFsdWUsXG5cdFx0XHRpc1ZhbGlkVmFsdWUgPSB0eXBlID09PSBcInN0cmluZ1wiIHx8IEFycmF5LmlzQXJyYXkoIHZhbHVlICk7XG5cblx0XHRpZiAoIHR5cGVvZiBzdGF0ZVZhbCA9PT0gXCJib29sZWFuXCIgJiYgaXNWYWxpZFZhbHVlICkge1xuXHRcdFx0cmV0dXJuIHN0YXRlVmFsID8gdGhpcy5hZGRDbGFzcyggdmFsdWUgKSA6IHRoaXMucmVtb3ZlQ2xhc3MoIHZhbHVlICk7XG5cdFx0fVxuXG5cdFx0aWYgKCBpc0Z1bmN0aW9uKCB2YWx1ZSApICkge1xuXHRcdFx0cmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24oIGkgKSB7XG5cdFx0XHRcdGpRdWVyeSggdGhpcyApLnRvZ2dsZUNsYXNzKFxuXHRcdFx0XHRcdHZhbHVlLmNhbGwoIHRoaXMsIGksIGdldENsYXNzKCB0aGlzICksIHN0YXRlVmFsICksXG5cdFx0XHRcdFx0c3RhdGVWYWxcblx0XHRcdFx0KTtcblx0XHRcdH0gKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcblx0XHRcdHZhciBjbGFzc05hbWUsIGksIHNlbGYsIGNsYXNzTmFtZXM7XG5cblx0XHRcdGlmICggaXNWYWxpZFZhbHVlICkge1xuXG5cdFx0XHRcdC8vIFRvZ2dsZSBpbmRpdmlkdWFsIGNsYXNzIG5hbWVzXG5cdFx0XHRcdGkgPSAwO1xuXHRcdFx0XHRzZWxmID0galF1ZXJ5KCB0aGlzICk7XG5cdFx0XHRcdGNsYXNzTmFtZXMgPSBjbGFzc2VzVG9BcnJheSggdmFsdWUgKTtcblxuXHRcdFx0XHR3aGlsZSAoICggY2xhc3NOYW1lID0gY2xhc3NOYW1lc1sgaSsrIF0gKSApIHtcblxuXHRcdFx0XHRcdC8vIENoZWNrIGVhY2ggY2xhc3NOYW1lIGdpdmVuLCBzcGFjZSBzZXBhcmF0ZWQgbGlzdFxuXHRcdFx0XHRcdGlmICggc2VsZi5oYXNDbGFzcyggY2xhc3NOYW1lICkgKSB7XG5cdFx0XHRcdFx0XHRzZWxmLnJlbW92ZUNsYXNzKCBjbGFzc05hbWUgKTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0c2VsZi5hZGRDbGFzcyggY2xhc3NOYW1lICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdC8vIFRvZ2dsZSB3aG9sZSBjbGFzcyBuYW1lXG5cdFx0XHR9IGVsc2UgaWYgKCB2YWx1ZSA9PT0gdW5kZWZpbmVkIHx8IHR5cGUgPT09IFwiYm9vbGVhblwiICkge1xuXHRcdFx0XHRjbGFzc05hbWUgPSBnZXRDbGFzcyggdGhpcyApO1xuXHRcdFx0XHRpZiAoIGNsYXNzTmFtZSApIHtcblxuXHRcdFx0XHRcdC8vIFN0b3JlIGNsYXNzTmFtZSBpZiBzZXRcblx0XHRcdFx0XHRkYXRhUHJpdi5zZXQoIHRoaXMsIFwiX19jbGFzc05hbWVfX1wiLCBjbGFzc05hbWUgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIElmIHRoZSBlbGVtZW50IGhhcyBhIGNsYXNzIG5hbWUgb3IgaWYgd2UncmUgcGFzc2VkIGBmYWxzZWAsXG5cdFx0XHRcdC8vIHRoZW4gcmVtb3ZlIHRoZSB3aG9sZSBjbGFzc25hbWUgKGlmIHRoZXJlIHdhcyBvbmUsIHRoZSBhYm92ZSBzYXZlZCBpdCkuXG5cdFx0XHRcdC8vIE90aGVyd2lzZSBicmluZyBiYWNrIHdoYXRldmVyIHdhcyBwcmV2aW91c2x5IHNhdmVkIChpZiBhbnl0aGluZyksXG5cdFx0XHRcdC8vIGZhbGxpbmcgYmFjayB0byB0aGUgZW1wdHkgc3RyaW5nIGlmIG5vdGhpbmcgd2FzIHN0b3JlZC5cblx0XHRcdFx0aWYgKCB0aGlzLnNldEF0dHJpYnV0ZSApIHtcblx0XHRcdFx0XHR0aGlzLnNldEF0dHJpYnV0ZSggXCJjbGFzc1wiLFxuXHRcdFx0XHRcdFx0Y2xhc3NOYW1lIHx8IHZhbHVlID09PSBmYWxzZSA/XG5cdFx0XHRcdFx0XHRcdFwiXCIgOlxuXHRcdFx0XHRcdFx0XHRkYXRhUHJpdi5nZXQoIHRoaXMsIFwiX19jbGFzc05hbWVfX1wiICkgfHwgXCJcIlxuXHRcdFx0XHRcdCk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9ICk7XG5cdH0sXG5cblx0aGFzQ2xhc3M6IGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcblx0XHR2YXIgY2xhc3NOYW1lLCBlbGVtLFxuXHRcdFx0aSA9IDA7XG5cblx0XHRjbGFzc05hbWUgPSBcIiBcIiArIHNlbGVjdG9yICsgXCIgXCI7XG5cdFx0d2hpbGUgKCAoIGVsZW0gPSB0aGlzWyBpKysgXSApICkge1xuXHRcdFx0aWYgKCBlbGVtLm5vZGVUeXBlID09PSAxICYmXG5cdFx0XHRcdCggXCIgXCIgKyBzdHJpcEFuZENvbGxhcHNlKCBnZXRDbGFzcyggZWxlbSApICkgKyBcIiBcIiApLmluZGV4T2YoIGNsYXNzTmFtZSApID4gLTEgKSB7XG5cdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiBmYWxzZTtcblx0fVxufSApO1xuXG5cblxuXG52YXIgcnJldHVybiA9IC9cXHIvZztcblxualF1ZXJ5LmZuLmV4dGVuZCgge1xuXHR2YWw6IGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHR2YXIgaG9va3MsIHJldCwgdmFsdWVJc0Z1bmN0aW9uLFxuXHRcdFx0ZWxlbSA9IHRoaXNbIDAgXTtcblxuXHRcdGlmICggIWFyZ3VtZW50cy5sZW5ndGggKSB7XG5cdFx0XHRpZiAoIGVsZW0gKSB7XG5cdFx0XHRcdGhvb2tzID0galF1ZXJ5LnZhbEhvb2tzWyBlbGVtLnR5cGUgXSB8fFxuXHRcdFx0XHRcdGpRdWVyeS52YWxIb29rc1sgZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpIF07XG5cblx0XHRcdFx0aWYgKCBob29rcyAmJlxuXHRcdFx0XHRcdFwiZ2V0XCIgaW4gaG9va3MgJiZcblx0XHRcdFx0XHQoIHJldCA9IGhvb2tzLmdldCggZWxlbSwgXCJ2YWx1ZVwiICkgKSAhPT0gdW5kZWZpbmVkXG5cdFx0XHRcdCkge1xuXHRcdFx0XHRcdHJldHVybiByZXQ7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZXQgPSBlbGVtLnZhbHVlO1xuXG5cdFx0XHRcdC8vIEhhbmRsZSBtb3N0IGNvbW1vbiBzdHJpbmcgY2FzZXNcblx0XHRcdFx0aWYgKCB0eXBlb2YgcmV0ID09PSBcInN0cmluZ1wiICkge1xuXHRcdFx0XHRcdHJldHVybiByZXQucmVwbGFjZSggcnJldHVybiwgXCJcIiApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gSGFuZGxlIGNhc2VzIHdoZXJlIHZhbHVlIGlzIG51bGwvdW5kZWYgb3IgbnVtYmVyXG5cdFx0XHRcdHJldHVybiByZXQgPT0gbnVsbCA/IFwiXCIgOiByZXQ7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHR2YWx1ZUlzRnVuY3Rpb24gPSBpc0Z1bmN0aW9uKCB2YWx1ZSApO1xuXG5cdFx0cmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24oIGkgKSB7XG5cdFx0XHR2YXIgdmFsO1xuXG5cdFx0XHRpZiAoIHRoaXMubm9kZVR5cGUgIT09IDEgKSB7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCB2YWx1ZUlzRnVuY3Rpb24gKSB7XG5cdFx0XHRcdHZhbCA9IHZhbHVlLmNhbGwoIHRoaXMsIGksIGpRdWVyeSggdGhpcyApLnZhbCgpICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR2YWwgPSB2YWx1ZTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gVHJlYXQgbnVsbC91bmRlZmluZWQgYXMgXCJcIjsgY29udmVydCBudW1iZXJzIHRvIHN0cmluZ1xuXHRcdFx0aWYgKCB2YWwgPT0gbnVsbCApIHtcblx0XHRcdFx0dmFsID0gXCJcIjtcblxuXHRcdFx0fSBlbHNlIGlmICggdHlwZW9mIHZhbCA9PT0gXCJudW1iZXJcIiApIHtcblx0XHRcdFx0dmFsICs9IFwiXCI7XG5cblx0XHRcdH0gZWxzZSBpZiAoIEFycmF5LmlzQXJyYXkoIHZhbCApICkge1xuXHRcdFx0XHR2YWwgPSBqUXVlcnkubWFwKCB2YWwsIGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHRcdFx0XHRyZXR1cm4gdmFsdWUgPT0gbnVsbCA/IFwiXCIgOiB2YWx1ZSArIFwiXCI7XG5cdFx0XHRcdH0gKTtcblx0XHRcdH1cblxuXHRcdFx0aG9va3MgPSBqUXVlcnkudmFsSG9va3NbIHRoaXMudHlwZSBdIHx8IGpRdWVyeS52YWxIb29rc1sgdGhpcy5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpIF07XG5cblx0XHRcdC8vIElmIHNldCByZXR1cm5zIHVuZGVmaW5lZCwgZmFsbCBiYWNrIHRvIG5vcm1hbCBzZXR0aW5nXG5cdFx0XHRpZiAoICFob29rcyB8fCAhKCBcInNldFwiIGluIGhvb2tzICkgfHwgaG9va3Muc2V0KCB0aGlzLCB2YWwsIFwidmFsdWVcIiApID09PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdHRoaXMudmFsdWUgPSB2YWw7XG5cdFx0XHR9XG5cdFx0fSApO1xuXHR9XG59ICk7XG5cbmpRdWVyeS5leHRlbmQoIHtcblx0dmFsSG9va3M6IHtcblx0XHRvcHRpb246IHtcblx0XHRcdGdldDogZnVuY3Rpb24oIGVsZW0gKSB7XG5cblx0XHRcdFx0dmFyIHZhbCA9IGpRdWVyeS5maW5kLmF0dHIoIGVsZW0sIFwidmFsdWVcIiApO1xuXHRcdFx0XHRyZXR1cm4gdmFsICE9IG51bGwgP1xuXHRcdFx0XHRcdHZhbCA6XG5cblx0XHRcdFx0XHQvLyBTdXBwb3J0OiBJRSA8PTEwIC0gMTEgb25seVxuXHRcdFx0XHRcdC8vIG9wdGlvbi50ZXh0IHRocm93cyBleGNlcHRpb25zICgjMTQ2ODYsICMxNDg1OClcblx0XHRcdFx0XHQvLyBTdHJpcCBhbmQgY29sbGFwc2Ugd2hpdGVzcGFjZVxuXHRcdFx0XHRcdC8vIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvI3N0cmlwLWFuZC1jb2xsYXBzZS13aGl0ZXNwYWNlXG5cdFx0XHRcdFx0c3RyaXBBbmRDb2xsYXBzZSggalF1ZXJ5LnRleHQoIGVsZW0gKSApO1xuXHRcdFx0fVxuXHRcdH0sXG5cdFx0c2VsZWN0OiB7XG5cdFx0XHRnZXQ6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHR2YXIgdmFsdWUsIG9wdGlvbiwgaSxcblx0XHRcdFx0XHRvcHRpb25zID0gZWxlbS5vcHRpb25zLFxuXHRcdFx0XHRcdGluZGV4ID0gZWxlbS5zZWxlY3RlZEluZGV4LFxuXHRcdFx0XHRcdG9uZSA9IGVsZW0udHlwZSA9PT0gXCJzZWxlY3Qtb25lXCIsXG5cdFx0XHRcdFx0dmFsdWVzID0gb25lID8gbnVsbCA6IFtdLFxuXHRcdFx0XHRcdG1heCA9IG9uZSA/IGluZGV4ICsgMSA6IG9wdGlvbnMubGVuZ3RoO1xuXG5cdFx0XHRcdGlmICggaW5kZXggPCAwICkge1xuXHRcdFx0XHRcdGkgPSBtYXg7XG5cblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRpID0gb25lID8gaW5kZXggOiAwO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gTG9vcCB0aHJvdWdoIGFsbCB0aGUgc2VsZWN0ZWQgb3B0aW9uc1xuXHRcdFx0XHRmb3IgKCA7IGkgPCBtYXg7IGkrKyApIHtcblx0XHRcdFx0XHRvcHRpb24gPSBvcHRpb25zWyBpIF07XG5cblx0XHRcdFx0XHQvLyBTdXBwb3J0OiBJRSA8PTkgb25seVxuXHRcdFx0XHRcdC8vIElFOC05IGRvZXNuJ3QgdXBkYXRlIHNlbGVjdGVkIGFmdGVyIGZvcm0gcmVzZXQgKCMyNTUxKVxuXHRcdFx0XHRcdGlmICggKCBvcHRpb24uc2VsZWN0ZWQgfHwgaSA9PT0gaW5kZXggKSAmJlxuXG5cdFx0XHRcdFx0XHRcdC8vIERvbid0IHJldHVybiBvcHRpb25zIHRoYXQgYXJlIGRpc2FibGVkIG9yIGluIGEgZGlzYWJsZWQgb3B0Z3JvdXBcblx0XHRcdFx0XHRcdFx0IW9wdGlvbi5kaXNhYmxlZCAmJlxuXHRcdFx0XHRcdFx0XHQoICFvcHRpb24ucGFyZW50Tm9kZS5kaXNhYmxlZCB8fFxuXHRcdFx0XHRcdFx0XHRcdCFub2RlTmFtZSggb3B0aW9uLnBhcmVudE5vZGUsIFwib3B0Z3JvdXBcIiApICkgKSB7XG5cblx0XHRcdFx0XHRcdC8vIEdldCB0aGUgc3BlY2lmaWMgdmFsdWUgZm9yIHRoZSBvcHRpb25cblx0XHRcdFx0XHRcdHZhbHVlID0galF1ZXJ5KCBvcHRpb24gKS52YWwoKTtcblxuXHRcdFx0XHRcdFx0Ly8gV2UgZG9uJ3QgbmVlZCBhbiBhcnJheSBmb3Igb25lIHNlbGVjdHNcblx0XHRcdFx0XHRcdGlmICggb25lICkge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gdmFsdWU7XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdC8vIE11bHRpLVNlbGVjdHMgcmV0dXJuIGFuIGFycmF5XG5cdFx0XHRcdFx0XHR2YWx1ZXMucHVzaCggdmFsdWUgKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZXR1cm4gdmFsdWVzO1xuXHRcdFx0fSxcblxuXHRcdFx0c2V0OiBmdW5jdGlvbiggZWxlbSwgdmFsdWUgKSB7XG5cdFx0XHRcdHZhciBvcHRpb25TZXQsIG9wdGlvbixcblx0XHRcdFx0XHRvcHRpb25zID0gZWxlbS5vcHRpb25zLFxuXHRcdFx0XHRcdHZhbHVlcyA9IGpRdWVyeS5tYWtlQXJyYXkoIHZhbHVlICksXG5cdFx0XHRcdFx0aSA9IG9wdGlvbnMubGVuZ3RoO1xuXG5cdFx0XHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0XHRcdG9wdGlvbiA9IG9wdGlvbnNbIGkgXTtcblxuXHRcdFx0XHRcdC8qIGVzbGludC1kaXNhYmxlIG5vLWNvbmQtYXNzaWduICovXG5cblx0XHRcdFx0XHRpZiAoIG9wdGlvbi5zZWxlY3RlZCA9XG5cdFx0XHRcdFx0XHRqUXVlcnkuaW5BcnJheSggalF1ZXJ5LnZhbEhvb2tzLm9wdGlvbi5nZXQoIG9wdGlvbiApLCB2YWx1ZXMgKSA+IC0xXG5cdFx0XHRcdFx0KSB7XG5cdFx0XHRcdFx0XHRvcHRpb25TZXQgPSB0cnVlO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8qIGVzbGludC1lbmFibGUgbm8tY29uZC1hc3NpZ24gKi9cblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIEZvcmNlIGJyb3dzZXJzIHRvIGJlaGF2ZSBjb25zaXN0ZW50bHkgd2hlbiBub24tbWF0Y2hpbmcgdmFsdWUgaXMgc2V0XG5cdFx0XHRcdGlmICggIW9wdGlvblNldCApIHtcblx0XHRcdFx0XHRlbGVtLnNlbGVjdGVkSW5kZXggPSAtMTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gdmFsdWVzO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxufSApO1xuXG4vLyBSYWRpb3MgYW5kIGNoZWNrYm94ZXMgZ2V0dGVyL3NldHRlclxualF1ZXJ5LmVhY2goIFsgXCJyYWRpb1wiLCBcImNoZWNrYm94XCIgXSwgZnVuY3Rpb24oKSB7XG5cdGpRdWVyeS52YWxIb29rc1sgdGhpcyBdID0ge1xuXHRcdHNldDogZnVuY3Rpb24oIGVsZW0sIHZhbHVlICkge1xuXHRcdFx0aWYgKCBBcnJheS5pc0FycmF5KCB2YWx1ZSApICkge1xuXHRcdFx0XHRyZXR1cm4gKCBlbGVtLmNoZWNrZWQgPSBqUXVlcnkuaW5BcnJheSggalF1ZXJ5KCBlbGVtICkudmFsKCksIHZhbHVlICkgPiAtMSApO1xuXHRcdFx0fVxuXHRcdH1cblx0fTtcblx0aWYgKCAhc3VwcG9ydC5jaGVja09uICkge1xuXHRcdGpRdWVyeS52YWxIb29rc1sgdGhpcyBdLmdldCA9IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0cmV0dXJuIGVsZW0uZ2V0QXR0cmlidXRlKCBcInZhbHVlXCIgKSA9PT0gbnVsbCA/IFwib25cIiA6IGVsZW0udmFsdWU7XG5cdFx0fTtcblx0fVxufSApO1xuXG5cblxuXG4vLyBSZXR1cm4galF1ZXJ5IGZvciBhdHRyaWJ1dGVzLW9ubHkgaW5jbHVzaW9uXG5cblxuc3VwcG9ydC5mb2N1c2luID0gXCJvbmZvY3VzaW5cIiBpbiB3aW5kb3c7XG5cblxudmFyIHJmb2N1c01vcnBoID0gL14oPzpmb2N1c2luZm9jdXN8Zm9jdXNvdXRibHVyKSQvLFxuXHRzdG9wUHJvcGFnYXRpb25DYWxsYmFjayA9IGZ1bmN0aW9uKCBlICkge1xuXHRcdGUuc3RvcFByb3BhZ2F0aW9uKCk7XG5cdH07XG5cbmpRdWVyeS5leHRlbmQoIGpRdWVyeS5ldmVudCwge1xuXG5cdHRyaWdnZXI6IGZ1bmN0aW9uKCBldmVudCwgZGF0YSwgZWxlbSwgb25seUhhbmRsZXJzICkge1xuXG5cdFx0dmFyIGksIGN1ciwgdG1wLCBidWJibGVUeXBlLCBvbnR5cGUsIGhhbmRsZSwgc3BlY2lhbCwgbGFzdEVsZW1lbnQsXG5cdFx0XHRldmVudFBhdGggPSBbIGVsZW0gfHwgZG9jdW1lbnQgXSxcblx0XHRcdHR5cGUgPSBoYXNPd24uY2FsbCggZXZlbnQsIFwidHlwZVwiICkgPyBldmVudC50eXBlIDogZXZlbnQsXG5cdFx0XHRuYW1lc3BhY2VzID0gaGFzT3duLmNhbGwoIGV2ZW50LCBcIm5hbWVzcGFjZVwiICkgPyBldmVudC5uYW1lc3BhY2Uuc3BsaXQoIFwiLlwiICkgOiBbXTtcblxuXHRcdGN1ciA9IGxhc3RFbGVtZW50ID0gdG1wID0gZWxlbSA9IGVsZW0gfHwgZG9jdW1lbnQ7XG5cblx0XHQvLyBEb24ndCBkbyBldmVudHMgb24gdGV4dCBhbmQgY29tbWVudCBub2Rlc1xuXHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gMyB8fCBlbGVtLm5vZGVUeXBlID09PSA4ICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIGZvY3VzL2JsdXIgbW9ycGhzIHRvIGZvY3VzaW4vb3V0OyBlbnN1cmUgd2UncmUgbm90IGZpcmluZyB0aGVtIHJpZ2h0IG5vd1xuXHRcdGlmICggcmZvY3VzTW9ycGgudGVzdCggdHlwZSArIGpRdWVyeS5ldmVudC50cmlnZ2VyZWQgKSApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRpZiAoIHR5cGUuaW5kZXhPZiggXCIuXCIgKSA+IC0xICkge1xuXG5cdFx0XHQvLyBOYW1lc3BhY2VkIHRyaWdnZXI7IGNyZWF0ZSBhIHJlZ2V4cCB0byBtYXRjaCBldmVudCB0eXBlIGluIGhhbmRsZSgpXG5cdFx0XHRuYW1lc3BhY2VzID0gdHlwZS5zcGxpdCggXCIuXCIgKTtcblx0XHRcdHR5cGUgPSBuYW1lc3BhY2VzLnNoaWZ0KCk7XG5cdFx0XHRuYW1lc3BhY2VzLnNvcnQoKTtcblx0XHR9XG5cdFx0b250eXBlID0gdHlwZS5pbmRleE9mKCBcIjpcIiApIDwgMCAmJiBcIm9uXCIgKyB0eXBlO1xuXG5cdFx0Ly8gQ2FsbGVyIGNhbiBwYXNzIGluIGEgalF1ZXJ5LkV2ZW50IG9iamVjdCwgT2JqZWN0LCBvciBqdXN0IGFuIGV2ZW50IHR5cGUgc3RyaW5nXG5cdFx0ZXZlbnQgPSBldmVudFsgalF1ZXJ5LmV4cGFuZG8gXSA/XG5cdFx0XHRldmVudCA6XG5cdFx0XHRuZXcgalF1ZXJ5LkV2ZW50KCB0eXBlLCB0eXBlb2YgZXZlbnQgPT09IFwib2JqZWN0XCIgJiYgZXZlbnQgKTtcblxuXHRcdC8vIFRyaWdnZXIgYml0bWFzazogJiAxIGZvciBuYXRpdmUgaGFuZGxlcnM7ICYgMiBmb3IgalF1ZXJ5IChhbHdheXMgdHJ1ZSlcblx0XHRldmVudC5pc1RyaWdnZXIgPSBvbmx5SGFuZGxlcnMgPyAyIDogMztcblx0XHRldmVudC5uYW1lc3BhY2UgPSBuYW1lc3BhY2VzLmpvaW4oIFwiLlwiICk7XG5cdFx0ZXZlbnQucm5hbWVzcGFjZSA9IGV2ZW50Lm5hbWVzcGFjZSA/XG5cdFx0XHRuZXcgUmVnRXhwKCBcIihefFxcXFwuKVwiICsgbmFtZXNwYWNlcy5qb2luKCBcIlxcXFwuKD86LipcXFxcLnwpXCIgKSArIFwiKFxcXFwufCQpXCIgKSA6XG5cdFx0XHRudWxsO1xuXG5cdFx0Ly8gQ2xlYW4gdXAgdGhlIGV2ZW50IGluIGNhc2UgaXQgaXMgYmVpbmcgcmV1c2VkXG5cdFx0ZXZlbnQucmVzdWx0ID0gdW5kZWZpbmVkO1xuXHRcdGlmICggIWV2ZW50LnRhcmdldCApIHtcblx0XHRcdGV2ZW50LnRhcmdldCA9IGVsZW07XG5cdFx0fVxuXG5cdFx0Ly8gQ2xvbmUgYW55IGluY29taW5nIGRhdGEgYW5kIHByZXBlbmQgdGhlIGV2ZW50LCBjcmVhdGluZyB0aGUgaGFuZGxlciBhcmcgbGlzdFxuXHRcdGRhdGEgPSBkYXRhID09IG51bGwgP1xuXHRcdFx0WyBldmVudCBdIDpcblx0XHRcdGpRdWVyeS5tYWtlQXJyYXkoIGRhdGEsIFsgZXZlbnQgXSApO1xuXG5cdFx0Ly8gQWxsb3cgc3BlY2lhbCBldmVudHMgdG8gZHJhdyBvdXRzaWRlIHRoZSBsaW5lc1xuXHRcdHNwZWNpYWwgPSBqUXVlcnkuZXZlbnQuc3BlY2lhbFsgdHlwZSBdIHx8IHt9O1xuXHRcdGlmICggIW9ubHlIYW5kbGVycyAmJiBzcGVjaWFsLnRyaWdnZXIgJiYgc3BlY2lhbC50cmlnZ2VyLmFwcGx5KCBlbGVtLCBkYXRhICkgPT09IGZhbHNlICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIERldGVybWluZSBldmVudCBwcm9wYWdhdGlvbiBwYXRoIGluIGFkdmFuY2UsIHBlciBXM0MgZXZlbnRzIHNwZWMgKCM5OTUxKVxuXHRcdC8vIEJ1YmJsZSB1cCB0byBkb2N1bWVudCwgdGhlbiB0byB3aW5kb3c7IHdhdGNoIGZvciBhIGdsb2JhbCBvd25lckRvY3VtZW50IHZhciAoIzk3MjQpXG5cdFx0aWYgKCAhb25seUhhbmRsZXJzICYmICFzcGVjaWFsLm5vQnViYmxlICYmICFpc1dpbmRvdyggZWxlbSApICkge1xuXG5cdFx0XHRidWJibGVUeXBlID0gc3BlY2lhbC5kZWxlZ2F0ZVR5cGUgfHwgdHlwZTtcblx0XHRcdGlmICggIXJmb2N1c01vcnBoLnRlc3QoIGJ1YmJsZVR5cGUgKyB0eXBlICkgKSB7XG5cdFx0XHRcdGN1ciA9IGN1ci5wYXJlbnROb2RlO1xuXHRcdFx0fVxuXHRcdFx0Zm9yICggOyBjdXI7IGN1ciA9IGN1ci5wYXJlbnROb2RlICkge1xuXHRcdFx0XHRldmVudFBhdGgucHVzaCggY3VyICk7XG5cdFx0XHRcdHRtcCA9IGN1cjtcblx0XHRcdH1cblxuXHRcdFx0Ly8gT25seSBhZGQgd2luZG93IGlmIHdlIGdvdCB0byBkb2N1bWVudCAoZS5nLiwgbm90IHBsYWluIG9iaiBvciBkZXRhY2hlZCBET00pXG5cdFx0XHRpZiAoIHRtcCA9PT0gKCBlbGVtLm93bmVyRG9jdW1lbnQgfHwgZG9jdW1lbnQgKSApIHtcblx0XHRcdFx0ZXZlbnRQYXRoLnB1c2goIHRtcC5kZWZhdWx0VmlldyB8fCB0bXAucGFyZW50V2luZG93IHx8IHdpbmRvdyApO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIEZpcmUgaGFuZGxlcnMgb24gdGhlIGV2ZW50IHBhdGhcblx0XHRpID0gMDtcblx0XHR3aGlsZSAoICggY3VyID0gZXZlbnRQYXRoWyBpKysgXSApICYmICFldmVudC5pc1Byb3BhZ2F0aW9uU3RvcHBlZCgpICkge1xuXHRcdFx0bGFzdEVsZW1lbnQgPSBjdXI7XG5cdFx0XHRldmVudC50eXBlID0gaSA+IDEgP1xuXHRcdFx0XHRidWJibGVUeXBlIDpcblx0XHRcdFx0c3BlY2lhbC5iaW5kVHlwZSB8fCB0eXBlO1xuXG5cdFx0XHQvLyBqUXVlcnkgaGFuZGxlclxuXHRcdFx0aGFuZGxlID0gKCBkYXRhUHJpdi5nZXQoIGN1ciwgXCJldmVudHNcIiApIHx8IE9iamVjdC5jcmVhdGUoIG51bGwgKSApWyBldmVudC50eXBlIF0gJiZcblx0XHRcdFx0ZGF0YVByaXYuZ2V0KCBjdXIsIFwiaGFuZGxlXCIgKTtcblx0XHRcdGlmICggaGFuZGxlICkge1xuXHRcdFx0XHRoYW5kbGUuYXBwbHkoIGN1ciwgZGF0YSApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBOYXRpdmUgaGFuZGxlclxuXHRcdFx0aGFuZGxlID0gb250eXBlICYmIGN1clsgb250eXBlIF07XG5cdFx0XHRpZiAoIGhhbmRsZSAmJiBoYW5kbGUuYXBwbHkgJiYgYWNjZXB0RGF0YSggY3VyICkgKSB7XG5cdFx0XHRcdGV2ZW50LnJlc3VsdCA9IGhhbmRsZS5hcHBseSggY3VyLCBkYXRhICk7XG5cdFx0XHRcdGlmICggZXZlbnQucmVzdWx0ID09PSBmYWxzZSApIHtcblx0XHRcdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGV2ZW50LnR5cGUgPSB0eXBlO1xuXG5cdFx0Ly8gSWYgbm9ib2R5IHByZXZlbnRlZCB0aGUgZGVmYXVsdCBhY3Rpb24sIGRvIGl0IG5vd1xuXHRcdGlmICggIW9ubHlIYW5kbGVycyAmJiAhZXZlbnQuaXNEZWZhdWx0UHJldmVudGVkKCkgKSB7XG5cblx0XHRcdGlmICggKCAhc3BlY2lhbC5fZGVmYXVsdCB8fFxuXHRcdFx0XHRzcGVjaWFsLl9kZWZhdWx0LmFwcGx5KCBldmVudFBhdGgucG9wKCksIGRhdGEgKSA9PT0gZmFsc2UgKSAmJlxuXHRcdFx0XHRhY2NlcHREYXRhKCBlbGVtICkgKSB7XG5cblx0XHRcdFx0Ly8gQ2FsbCBhIG5hdGl2ZSBET00gbWV0aG9kIG9uIHRoZSB0YXJnZXQgd2l0aCB0aGUgc2FtZSBuYW1lIGFzIHRoZSBldmVudC5cblx0XHRcdFx0Ly8gRG9uJ3QgZG8gZGVmYXVsdCBhY3Rpb25zIG9uIHdpbmRvdywgdGhhdCdzIHdoZXJlIGdsb2JhbCB2YXJpYWJsZXMgYmUgKCM2MTcwKVxuXHRcdFx0XHRpZiAoIG9udHlwZSAmJiBpc0Z1bmN0aW9uKCBlbGVtWyB0eXBlIF0gKSAmJiAhaXNXaW5kb3coIGVsZW0gKSApIHtcblxuXHRcdFx0XHRcdC8vIERvbid0IHJlLXRyaWdnZXIgYW4gb25GT08gZXZlbnQgd2hlbiB3ZSBjYWxsIGl0cyBGT08oKSBtZXRob2Rcblx0XHRcdFx0XHR0bXAgPSBlbGVtWyBvbnR5cGUgXTtcblxuXHRcdFx0XHRcdGlmICggdG1wICkge1xuXHRcdFx0XHRcdFx0ZWxlbVsgb250eXBlIF0gPSBudWxsO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIFByZXZlbnQgcmUtdHJpZ2dlcmluZyBvZiB0aGUgc2FtZSBldmVudCwgc2luY2Ugd2UgYWxyZWFkeSBidWJibGVkIGl0IGFib3ZlXG5cdFx0XHRcdFx0alF1ZXJ5LmV2ZW50LnRyaWdnZXJlZCA9IHR5cGU7XG5cblx0XHRcdFx0XHRpZiAoIGV2ZW50LmlzUHJvcGFnYXRpb25TdG9wcGVkKCkgKSB7XG5cdFx0XHRcdFx0XHRsYXN0RWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCB0eXBlLCBzdG9wUHJvcGFnYXRpb25DYWxsYmFjayApO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdGVsZW1bIHR5cGUgXSgpO1xuXG5cdFx0XHRcdFx0aWYgKCBldmVudC5pc1Byb3BhZ2F0aW9uU3RvcHBlZCgpICkge1xuXHRcdFx0XHRcdFx0bGFzdEVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lciggdHlwZSwgc3RvcFByb3BhZ2F0aW9uQ2FsbGJhY2sgKTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRqUXVlcnkuZXZlbnQudHJpZ2dlcmVkID0gdW5kZWZpbmVkO1xuXG5cdFx0XHRcdFx0aWYgKCB0bXAgKSB7XG5cdFx0XHRcdFx0XHRlbGVtWyBvbnR5cGUgXSA9IHRtcDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gZXZlbnQucmVzdWx0O1xuXHR9LFxuXG5cdC8vIFBpZ2d5YmFjayBvbiBhIGRvbm9yIGV2ZW50IHRvIHNpbXVsYXRlIGEgZGlmZmVyZW50IG9uZVxuXHQvLyBVc2VkIG9ubHkgZm9yIGBmb2N1cyhpbiB8IG91dClgIGV2ZW50c1xuXHRzaW11bGF0ZTogZnVuY3Rpb24oIHR5cGUsIGVsZW0sIGV2ZW50ICkge1xuXHRcdHZhciBlID0galF1ZXJ5LmV4dGVuZChcblx0XHRcdG5ldyBqUXVlcnkuRXZlbnQoKSxcblx0XHRcdGV2ZW50LFxuXHRcdFx0e1xuXHRcdFx0XHR0eXBlOiB0eXBlLFxuXHRcdFx0XHRpc1NpbXVsYXRlZDogdHJ1ZVxuXHRcdFx0fVxuXHRcdCk7XG5cblx0XHRqUXVlcnkuZXZlbnQudHJpZ2dlciggZSwgbnVsbCwgZWxlbSApO1xuXHR9XG5cbn0gKTtcblxualF1ZXJ5LmZuLmV4dGVuZCgge1xuXG5cdHRyaWdnZXI6IGZ1bmN0aW9uKCB0eXBlLCBkYXRhICkge1xuXHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCkge1xuXHRcdFx0alF1ZXJ5LmV2ZW50LnRyaWdnZXIoIHR5cGUsIGRhdGEsIHRoaXMgKTtcblx0XHR9ICk7XG5cdH0sXG5cdHRyaWdnZXJIYW5kbGVyOiBmdW5jdGlvbiggdHlwZSwgZGF0YSApIHtcblx0XHR2YXIgZWxlbSA9IHRoaXNbIDAgXTtcblx0XHRpZiAoIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4galF1ZXJ5LmV2ZW50LnRyaWdnZXIoIHR5cGUsIGRhdGEsIGVsZW0sIHRydWUgKTtcblx0XHR9XG5cdH1cbn0gKTtcblxuXG4vLyBTdXBwb3J0OiBGaXJlZm94IDw9NDRcbi8vIEZpcmVmb3ggZG9lc24ndCBoYXZlIGZvY3VzKGluIHwgb3V0KSBldmVudHNcbi8vIFJlbGF0ZWQgdGlja2V0IC0gaHR0cHM6Ly9idWd6aWxsYS5tb3ppbGxhLm9yZy9zaG93X2J1Zy5jZ2k/aWQ9Njg3Nzg3XG4vL1xuLy8gU3VwcG9ydDogQ2hyb21lIDw9NDggLSA0OSwgU2FmYXJpIDw9OS4wIC0gOS4xXG4vLyBmb2N1cyhpbiB8IG91dCkgZXZlbnRzIGZpcmUgYWZ0ZXIgZm9jdXMgJiBibHVyIGV2ZW50cyxcbi8vIHdoaWNoIGlzIHNwZWMgdmlvbGF0aW9uIC0gaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTMtRXZlbnRzLyNldmVudHMtZm9jdXNldmVudC1ldmVudC1vcmRlclxuLy8gUmVsYXRlZCB0aWNrZXQgLSBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvY2hyb21pdW0vaXNzdWVzL2RldGFpbD9pZD00NDk4NTdcbmlmICggIXN1cHBvcnQuZm9jdXNpbiApIHtcblx0alF1ZXJ5LmVhY2goIHsgZm9jdXM6IFwiZm9jdXNpblwiLCBibHVyOiBcImZvY3Vzb3V0XCIgfSwgZnVuY3Rpb24oIG9yaWcsIGZpeCApIHtcblxuXHRcdC8vIEF0dGFjaCBhIHNpbmdsZSBjYXB0dXJpbmcgaGFuZGxlciBvbiB0aGUgZG9jdW1lbnQgd2hpbGUgc29tZW9uZSB3YW50cyBmb2N1c2luL2ZvY3Vzb3V0XG5cdFx0dmFyIGhhbmRsZXIgPSBmdW5jdGlvbiggZXZlbnQgKSB7XG5cdFx0XHRqUXVlcnkuZXZlbnQuc2ltdWxhdGUoIGZpeCwgZXZlbnQudGFyZ2V0LCBqUXVlcnkuZXZlbnQuZml4KCBldmVudCApICk7XG5cdFx0fTtcblxuXHRcdGpRdWVyeS5ldmVudC5zcGVjaWFsWyBmaXggXSA9IHtcblx0XHRcdHNldHVwOiBmdW5jdGlvbigpIHtcblxuXHRcdFx0XHQvLyBIYW5kbGU6IHJlZ3VsYXIgbm9kZXMgKHZpYSBgdGhpcy5vd25lckRvY3VtZW50YCksIHdpbmRvd1xuXHRcdFx0XHQvLyAodmlhIGB0aGlzLmRvY3VtZW50YCkgJiBkb2N1bWVudCAodmlhIGB0aGlzYCkuXG5cdFx0XHRcdHZhciBkb2MgPSB0aGlzLm93bmVyRG9jdW1lbnQgfHwgdGhpcy5kb2N1bWVudCB8fCB0aGlzLFxuXHRcdFx0XHRcdGF0dGFjaGVzID0gZGF0YVByaXYuYWNjZXNzKCBkb2MsIGZpeCApO1xuXG5cdFx0XHRcdGlmICggIWF0dGFjaGVzICkge1xuXHRcdFx0XHRcdGRvYy5hZGRFdmVudExpc3RlbmVyKCBvcmlnLCBoYW5kbGVyLCB0cnVlICk7XG5cdFx0XHRcdH1cblx0XHRcdFx0ZGF0YVByaXYuYWNjZXNzKCBkb2MsIGZpeCwgKCBhdHRhY2hlcyB8fCAwICkgKyAxICk7XG5cdFx0XHR9LFxuXHRcdFx0dGVhcmRvd246IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHR2YXIgZG9jID0gdGhpcy5vd25lckRvY3VtZW50IHx8IHRoaXMuZG9jdW1lbnQgfHwgdGhpcyxcblx0XHRcdFx0XHRhdHRhY2hlcyA9IGRhdGFQcml2LmFjY2VzcyggZG9jLCBmaXggKSAtIDE7XG5cblx0XHRcdFx0aWYgKCAhYXR0YWNoZXMgKSB7XG5cdFx0XHRcdFx0ZG9jLnJlbW92ZUV2ZW50TGlzdGVuZXIoIG9yaWcsIGhhbmRsZXIsIHRydWUgKTtcblx0XHRcdFx0XHRkYXRhUHJpdi5yZW1vdmUoIGRvYywgZml4ICk7XG5cblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRkYXRhUHJpdi5hY2Nlc3MoIGRvYywgZml4LCBhdHRhY2hlcyApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fTtcblx0fSApO1xufVxudmFyIGxvY2F0aW9uID0gd2luZG93LmxvY2F0aW9uO1xuXG52YXIgbm9uY2UgPSB7IGd1aWQ6IERhdGUubm93KCkgfTtcblxudmFyIHJxdWVyeSA9ICggL1xcPy8gKTtcblxuXG5cbi8vIENyb3NzLWJyb3dzZXIgeG1sIHBhcnNpbmdcbmpRdWVyeS5wYXJzZVhNTCA9IGZ1bmN0aW9uKCBkYXRhICkge1xuXHR2YXIgeG1sLCBwYXJzZXJFcnJvckVsZW07XG5cdGlmICggIWRhdGEgfHwgdHlwZW9mIGRhdGEgIT09IFwic3RyaW5nXCIgKSB7XG5cdFx0cmV0dXJuIG51bGw7XG5cdH1cblxuXHQvLyBTdXBwb3J0OiBJRSA5IC0gMTEgb25seVxuXHQvLyBJRSB0aHJvd3Mgb24gcGFyc2VGcm9tU3RyaW5nIHdpdGggaW52YWxpZCBpbnB1dC5cblx0dHJ5IHtcblx0XHR4bWwgPSAoIG5ldyB3aW5kb3cuRE9NUGFyc2VyKCkgKS5wYXJzZUZyb21TdHJpbmcoIGRhdGEsIFwidGV4dC94bWxcIiApO1xuXHR9IGNhdGNoICggZSApIHt9XG5cblx0cGFyc2VyRXJyb3JFbGVtID0geG1sICYmIHhtbC5nZXRFbGVtZW50c0J5VGFnTmFtZSggXCJwYXJzZXJlcnJvclwiIClbIDAgXTtcblx0aWYgKCAheG1sIHx8IHBhcnNlckVycm9yRWxlbSApIHtcblx0XHRqUXVlcnkuZXJyb3IoIFwiSW52YWxpZCBYTUw6IFwiICsgKFxuXHRcdFx0cGFyc2VyRXJyb3JFbGVtID9cblx0XHRcdFx0alF1ZXJ5Lm1hcCggcGFyc2VyRXJyb3JFbGVtLmNoaWxkTm9kZXMsIGZ1bmN0aW9uKCBlbCApIHtcblx0XHRcdFx0XHRyZXR1cm4gZWwudGV4dENvbnRlbnQ7XG5cdFx0XHRcdH0gKS5qb2luKCBcIlxcblwiICkgOlxuXHRcdFx0XHRkYXRhXG5cdFx0KSApO1xuXHR9XG5cdHJldHVybiB4bWw7XG59O1xuXG5cbnZhclxuXHRyYnJhY2tldCA9IC9cXFtcXF0kLyxcblx0ckNSTEYgPSAvXFxyP1xcbi9nLFxuXHRyc3VibWl0dGVyVHlwZXMgPSAvXig/OnN1Ym1pdHxidXR0b258aW1hZ2V8cmVzZXR8ZmlsZSkkL2ksXG5cdHJzdWJtaXR0YWJsZSA9IC9eKD86aW5wdXR8c2VsZWN0fHRleHRhcmVhfGtleWdlbikvaTtcblxuZnVuY3Rpb24gYnVpbGRQYXJhbXMoIHByZWZpeCwgb2JqLCB0cmFkaXRpb25hbCwgYWRkICkge1xuXHR2YXIgbmFtZTtcblxuXHRpZiAoIEFycmF5LmlzQXJyYXkoIG9iaiApICkge1xuXG5cdFx0Ly8gU2VyaWFsaXplIGFycmF5IGl0ZW0uXG5cdFx0alF1ZXJ5LmVhY2goIG9iaiwgZnVuY3Rpb24oIGksIHYgKSB7XG5cdFx0XHRpZiAoIHRyYWRpdGlvbmFsIHx8IHJicmFja2V0LnRlc3QoIHByZWZpeCApICkge1xuXG5cdFx0XHRcdC8vIFRyZWF0IGVhY2ggYXJyYXkgaXRlbSBhcyBhIHNjYWxhci5cblx0XHRcdFx0YWRkKCBwcmVmaXgsIHYgKTtcblxuXHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHQvLyBJdGVtIGlzIG5vbi1zY2FsYXIgKGFycmF5IG9yIG9iamVjdCksIGVuY29kZSBpdHMgbnVtZXJpYyBpbmRleC5cblx0XHRcdFx0YnVpbGRQYXJhbXMoXG5cdFx0XHRcdFx0cHJlZml4ICsgXCJbXCIgKyAoIHR5cGVvZiB2ID09PSBcIm9iamVjdFwiICYmIHYgIT0gbnVsbCA/IGkgOiBcIlwiICkgKyBcIl1cIixcblx0XHRcdFx0XHR2LFxuXHRcdFx0XHRcdHRyYWRpdGlvbmFsLFxuXHRcdFx0XHRcdGFkZFxuXHRcdFx0XHQpO1xuXHRcdFx0fVxuXHRcdH0gKTtcblxuXHR9IGVsc2UgaWYgKCAhdHJhZGl0aW9uYWwgJiYgdG9UeXBlKCBvYmogKSA9PT0gXCJvYmplY3RcIiApIHtcblxuXHRcdC8vIFNlcmlhbGl6ZSBvYmplY3QgaXRlbS5cblx0XHRmb3IgKCBuYW1lIGluIG9iaiApIHtcblx0XHRcdGJ1aWxkUGFyYW1zKCBwcmVmaXggKyBcIltcIiArIG5hbWUgKyBcIl1cIiwgb2JqWyBuYW1lIF0sIHRyYWRpdGlvbmFsLCBhZGQgKTtcblx0XHR9XG5cblx0fSBlbHNlIHtcblxuXHRcdC8vIFNlcmlhbGl6ZSBzY2FsYXIgaXRlbS5cblx0XHRhZGQoIHByZWZpeCwgb2JqICk7XG5cdH1cbn1cblxuLy8gU2VyaWFsaXplIGFuIGFycmF5IG9mIGZvcm0gZWxlbWVudHMgb3IgYSBzZXQgb2Zcbi8vIGtleS92YWx1ZXMgaW50byBhIHF1ZXJ5IHN0cmluZ1xualF1ZXJ5LnBhcmFtID0gZnVuY3Rpb24oIGEsIHRyYWRpdGlvbmFsICkge1xuXHR2YXIgcHJlZml4LFxuXHRcdHMgPSBbXSxcblx0XHRhZGQgPSBmdW5jdGlvbigga2V5LCB2YWx1ZU9yRnVuY3Rpb24gKSB7XG5cblx0XHRcdC8vIElmIHZhbHVlIGlzIGEgZnVuY3Rpb24sIGludm9rZSBpdCBhbmQgdXNlIGl0cyByZXR1cm4gdmFsdWVcblx0XHRcdHZhciB2YWx1ZSA9IGlzRnVuY3Rpb24oIHZhbHVlT3JGdW5jdGlvbiApID9cblx0XHRcdFx0dmFsdWVPckZ1bmN0aW9uKCkgOlxuXHRcdFx0XHR2YWx1ZU9yRnVuY3Rpb247XG5cblx0XHRcdHNbIHMubGVuZ3RoIF0gPSBlbmNvZGVVUklDb21wb25lbnQoIGtleSApICsgXCI9XCIgK1xuXHRcdFx0XHRlbmNvZGVVUklDb21wb25lbnQoIHZhbHVlID09IG51bGwgPyBcIlwiIDogdmFsdWUgKTtcblx0XHR9O1xuXG5cdGlmICggYSA9PSBudWxsICkge1xuXHRcdHJldHVybiBcIlwiO1xuXHR9XG5cblx0Ly8gSWYgYW4gYXJyYXkgd2FzIHBhc3NlZCBpbiwgYXNzdW1lIHRoYXQgaXQgaXMgYW4gYXJyYXkgb2YgZm9ybSBlbGVtZW50cy5cblx0aWYgKCBBcnJheS5pc0FycmF5KCBhICkgfHwgKCBhLmpxdWVyeSAmJiAhalF1ZXJ5LmlzUGxhaW5PYmplY3QoIGEgKSApICkge1xuXG5cdFx0Ly8gU2VyaWFsaXplIHRoZSBmb3JtIGVsZW1lbnRzXG5cdFx0alF1ZXJ5LmVhY2goIGEsIGZ1bmN0aW9uKCkge1xuXHRcdFx0YWRkKCB0aGlzLm5hbWUsIHRoaXMudmFsdWUgKTtcblx0XHR9ICk7XG5cblx0fSBlbHNlIHtcblxuXHRcdC8vIElmIHRyYWRpdGlvbmFsLCBlbmNvZGUgdGhlIFwib2xkXCIgd2F5ICh0aGUgd2F5IDEuMy4yIG9yIG9sZGVyXG5cdFx0Ly8gZGlkIGl0KSwgb3RoZXJ3aXNlIGVuY29kZSBwYXJhbXMgcmVjdXJzaXZlbHkuXG5cdFx0Zm9yICggcHJlZml4IGluIGEgKSB7XG5cdFx0XHRidWlsZFBhcmFtcyggcHJlZml4LCBhWyBwcmVmaXggXSwgdHJhZGl0aW9uYWwsIGFkZCApO1xuXHRcdH1cblx0fVxuXG5cdC8vIFJldHVybiB0aGUgcmVzdWx0aW5nIHNlcmlhbGl6YXRpb25cblx0cmV0dXJuIHMuam9pbiggXCImXCIgKTtcbn07XG5cbmpRdWVyeS5mbi5leHRlbmQoIHtcblx0c2VyaWFsaXplOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4galF1ZXJ5LnBhcmFtKCB0aGlzLnNlcmlhbGl6ZUFycmF5KCkgKTtcblx0fSxcblx0c2VyaWFsaXplQXJyYXk6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLm1hcCggZnVuY3Rpb24oKSB7XG5cblx0XHRcdC8vIENhbiBhZGQgcHJvcEhvb2sgZm9yIFwiZWxlbWVudHNcIiB0byBmaWx0ZXIgb3IgYWRkIGZvcm0gZWxlbWVudHNcblx0XHRcdHZhciBlbGVtZW50cyA9IGpRdWVyeS5wcm9wKCB0aGlzLCBcImVsZW1lbnRzXCIgKTtcblx0XHRcdHJldHVybiBlbGVtZW50cyA/IGpRdWVyeS5tYWtlQXJyYXkoIGVsZW1lbnRzICkgOiB0aGlzO1xuXHRcdH0gKS5maWx0ZXIoIGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIHR5cGUgPSB0aGlzLnR5cGU7XG5cblx0XHRcdC8vIFVzZSAuaXMoIFwiOmRpc2FibGVkXCIgKSBzbyB0aGF0IGZpZWxkc2V0W2Rpc2FibGVkXSB3b3Jrc1xuXHRcdFx0cmV0dXJuIHRoaXMubmFtZSAmJiAhalF1ZXJ5KCB0aGlzICkuaXMoIFwiOmRpc2FibGVkXCIgKSAmJlxuXHRcdFx0XHRyc3VibWl0dGFibGUudGVzdCggdGhpcy5ub2RlTmFtZSApICYmICFyc3VibWl0dGVyVHlwZXMudGVzdCggdHlwZSApICYmXG5cdFx0XHRcdCggdGhpcy5jaGVja2VkIHx8ICFyY2hlY2thYmxlVHlwZS50ZXN0KCB0eXBlICkgKTtcblx0XHR9ICkubWFwKCBmdW5jdGlvbiggX2ksIGVsZW0gKSB7XG5cdFx0XHR2YXIgdmFsID0galF1ZXJ5KCB0aGlzICkudmFsKCk7XG5cblx0XHRcdGlmICggdmFsID09IG51bGwgKSB7XG5cdFx0XHRcdHJldHVybiBudWxsO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIEFycmF5LmlzQXJyYXkoIHZhbCApICkge1xuXHRcdFx0XHRyZXR1cm4galF1ZXJ5Lm1hcCggdmFsLCBmdW5jdGlvbiggdmFsICkge1xuXHRcdFx0XHRcdHJldHVybiB7IG5hbWU6IGVsZW0ubmFtZSwgdmFsdWU6IHZhbC5yZXBsYWNlKCByQ1JMRiwgXCJcXHJcXG5cIiApIH07XG5cdFx0XHRcdH0gKTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIHsgbmFtZTogZWxlbS5uYW1lLCB2YWx1ZTogdmFsLnJlcGxhY2UoIHJDUkxGLCBcIlxcclxcblwiICkgfTtcblx0XHR9ICkuZ2V0KCk7XG5cdH1cbn0gKTtcblxuXG52YXJcblx0cjIwID0gLyUyMC9nLFxuXHRyaGFzaCA9IC8jLiokLyxcblx0cmFudGlDYWNoZSA9IC8oWz8mXSlfPVteJl0qLyxcblx0cmhlYWRlcnMgPSAvXiguKj8pOlsgXFx0XSooW15cXHJcXG5dKikkL21nLFxuXG5cdC8vICM3NjUzLCAjODEyNSwgIzgxNTI6IGxvY2FsIHByb3RvY29sIGRldGVjdGlvblxuXHRybG9jYWxQcm90b2NvbCA9IC9eKD86YWJvdXR8YXBwfGFwcC1zdG9yYWdlfC4rLWV4dGVuc2lvbnxmaWxlfHJlc3x3aWRnZXQpOiQvLFxuXHRybm9Db250ZW50ID0gL14oPzpHRVR8SEVBRCkkLyxcblx0cnByb3RvY29sID0gL15cXC9cXC8vLFxuXG5cdC8qIFByZWZpbHRlcnNcblx0ICogMSkgVGhleSBhcmUgdXNlZnVsIHRvIGludHJvZHVjZSBjdXN0b20gZGF0YVR5cGVzIChzZWUgYWpheC9qc29ucC5qcyBmb3IgYW4gZXhhbXBsZSlcblx0ICogMikgVGhlc2UgYXJlIGNhbGxlZDpcblx0ICogICAgLSBCRUZPUkUgYXNraW5nIGZvciBhIHRyYW5zcG9ydFxuXHQgKiAgICAtIEFGVEVSIHBhcmFtIHNlcmlhbGl6YXRpb24gKHMuZGF0YSBpcyBhIHN0cmluZyBpZiBzLnByb2Nlc3NEYXRhIGlzIHRydWUpXG5cdCAqIDMpIGtleSBpcyB0aGUgZGF0YVR5cGVcblx0ICogNCkgdGhlIGNhdGNoYWxsIHN5bWJvbCBcIipcIiBjYW4gYmUgdXNlZFxuXHQgKiA1KSBleGVjdXRpb24gd2lsbCBzdGFydCB3aXRoIHRyYW5zcG9ydCBkYXRhVHlwZSBhbmQgVEhFTiBjb250aW51ZSBkb3duIHRvIFwiKlwiIGlmIG5lZWRlZFxuXHQgKi9cblx0cHJlZmlsdGVycyA9IHt9LFxuXG5cdC8qIFRyYW5zcG9ydHMgYmluZGluZ3Ncblx0ICogMSkga2V5IGlzIHRoZSBkYXRhVHlwZVxuXHQgKiAyKSB0aGUgY2F0Y2hhbGwgc3ltYm9sIFwiKlwiIGNhbiBiZSB1c2VkXG5cdCAqIDMpIHNlbGVjdGlvbiB3aWxsIHN0YXJ0IHdpdGggdHJhbnNwb3J0IGRhdGFUeXBlIGFuZCBUSEVOIGdvIHRvIFwiKlwiIGlmIG5lZWRlZFxuXHQgKi9cblx0dHJhbnNwb3J0cyA9IHt9LFxuXG5cdC8vIEF2b2lkIGNvbW1lbnQtcHJvbG9nIGNoYXIgc2VxdWVuY2UgKCMxMDA5OCk7IG11c3QgYXBwZWFzZSBsaW50IGFuZCBldmFkZSBjb21wcmVzc2lvblxuXHRhbGxUeXBlcyA9IFwiKi9cIi5jb25jYXQoIFwiKlwiICksXG5cblx0Ly8gQW5jaG9yIHRhZyBmb3IgcGFyc2luZyB0aGUgZG9jdW1lbnQgb3JpZ2luXG5cdG9yaWdpbkFuY2hvciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiYVwiICk7XG5cbm9yaWdpbkFuY2hvci5ocmVmID0gbG9jYXRpb24uaHJlZjtcblxuLy8gQmFzZSBcImNvbnN0cnVjdG9yXCIgZm9yIGpRdWVyeS5hamF4UHJlZmlsdGVyIGFuZCBqUXVlcnkuYWpheFRyYW5zcG9ydFxuZnVuY3Rpb24gYWRkVG9QcmVmaWx0ZXJzT3JUcmFuc3BvcnRzKCBzdHJ1Y3R1cmUgKSB7XG5cblx0Ly8gZGF0YVR5cGVFeHByZXNzaW9uIGlzIG9wdGlvbmFsIGFuZCBkZWZhdWx0cyB0byBcIipcIlxuXHRyZXR1cm4gZnVuY3Rpb24oIGRhdGFUeXBlRXhwcmVzc2lvbiwgZnVuYyApIHtcblxuXHRcdGlmICggdHlwZW9mIGRhdGFUeXBlRXhwcmVzc2lvbiAhPT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdGZ1bmMgPSBkYXRhVHlwZUV4cHJlc3Npb247XG5cdFx0XHRkYXRhVHlwZUV4cHJlc3Npb24gPSBcIipcIjtcblx0XHR9XG5cblx0XHR2YXIgZGF0YVR5cGUsXG5cdFx0XHRpID0gMCxcblx0XHRcdGRhdGFUeXBlcyA9IGRhdGFUeXBlRXhwcmVzc2lvbi50b0xvd2VyQ2FzZSgpLm1hdGNoKCBybm90aHRtbHdoaXRlICkgfHwgW107XG5cblx0XHRpZiAoIGlzRnVuY3Rpb24oIGZ1bmMgKSApIHtcblxuXHRcdFx0Ly8gRm9yIGVhY2ggZGF0YVR5cGUgaW4gdGhlIGRhdGFUeXBlRXhwcmVzc2lvblxuXHRcdFx0d2hpbGUgKCAoIGRhdGFUeXBlID0gZGF0YVR5cGVzWyBpKysgXSApICkge1xuXG5cdFx0XHRcdC8vIFByZXBlbmQgaWYgcmVxdWVzdGVkXG5cdFx0XHRcdGlmICggZGF0YVR5cGVbIDAgXSA9PT0gXCIrXCIgKSB7XG5cdFx0XHRcdFx0ZGF0YVR5cGUgPSBkYXRhVHlwZS5zbGljZSggMSApIHx8IFwiKlwiO1xuXHRcdFx0XHRcdCggc3RydWN0dXJlWyBkYXRhVHlwZSBdID0gc3RydWN0dXJlWyBkYXRhVHlwZSBdIHx8IFtdICkudW5zaGlmdCggZnVuYyApO1xuXG5cdFx0XHRcdC8vIE90aGVyd2lzZSBhcHBlbmRcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHQoIHN0cnVjdHVyZVsgZGF0YVR5cGUgXSA9IHN0cnVjdHVyZVsgZGF0YVR5cGUgXSB8fCBbXSApLnB1c2goIGZ1bmMgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fTtcbn1cblxuLy8gQmFzZSBpbnNwZWN0aW9uIGZ1bmN0aW9uIGZvciBwcmVmaWx0ZXJzIGFuZCB0cmFuc3BvcnRzXG5mdW5jdGlvbiBpbnNwZWN0UHJlZmlsdGVyc09yVHJhbnNwb3J0cyggc3RydWN0dXJlLCBvcHRpb25zLCBvcmlnaW5hbE9wdGlvbnMsIGpxWEhSICkge1xuXG5cdHZhciBpbnNwZWN0ZWQgPSB7fSxcblx0XHRzZWVraW5nVHJhbnNwb3J0ID0gKCBzdHJ1Y3R1cmUgPT09IHRyYW5zcG9ydHMgKTtcblxuXHRmdW5jdGlvbiBpbnNwZWN0KCBkYXRhVHlwZSApIHtcblx0XHR2YXIgc2VsZWN0ZWQ7XG5cdFx0aW5zcGVjdGVkWyBkYXRhVHlwZSBdID0gdHJ1ZTtcblx0XHRqUXVlcnkuZWFjaCggc3RydWN0dXJlWyBkYXRhVHlwZSBdIHx8IFtdLCBmdW5jdGlvbiggXywgcHJlZmlsdGVyT3JGYWN0b3J5ICkge1xuXHRcdFx0dmFyIGRhdGFUeXBlT3JUcmFuc3BvcnQgPSBwcmVmaWx0ZXJPckZhY3RvcnkoIG9wdGlvbnMsIG9yaWdpbmFsT3B0aW9ucywganFYSFIgKTtcblx0XHRcdGlmICggdHlwZW9mIGRhdGFUeXBlT3JUcmFuc3BvcnQgPT09IFwic3RyaW5nXCIgJiZcblx0XHRcdFx0IXNlZWtpbmdUcmFuc3BvcnQgJiYgIWluc3BlY3RlZFsgZGF0YVR5cGVPclRyYW5zcG9ydCBdICkge1xuXG5cdFx0XHRcdG9wdGlvbnMuZGF0YVR5cGVzLnVuc2hpZnQoIGRhdGFUeXBlT3JUcmFuc3BvcnQgKTtcblx0XHRcdFx0aW5zcGVjdCggZGF0YVR5cGVPclRyYW5zcG9ydCApO1xuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHR9IGVsc2UgaWYgKCBzZWVraW5nVHJhbnNwb3J0ICkge1xuXHRcdFx0XHRyZXR1cm4gISggc2VsZWN0ZWQgPSBkYXRhVHlwZU9yVHJhbnNwb3J0ICk7XG5cdFx0XHR9XG5cdFx0fSApO1xuXHRcdHJldHVybiBzZWxlY3RlZDtcblx0fVxuXG5cdHJldHVybiBpbnNwZWN0KCBvcHRpb25zLmRhdGFUeXBlc1sgMCBdICkgfHwgIWluc3BlY3RlZFsgXCIqXCIgXSAmJiBpbnNwZWN0KCBcIipcIiApO1xufVxuXG4vLyBBIHNwZWNpYWwgZXh0ZW5kIGZvciBhamF4IG9wdGlvbnNcbi8vIHRoYXQgdGFrZXMgXCJmbGF0XCIgb3B0aW9ucyAobm90IHRvIGJlIGRlZXAgZXh0ZW5kZWQpXG4vLyBGaXhlcyAjOTg4N1xuZnVuY3Rpb24gYWpheEV4dGVuZCggdGFyZ2V0LCBzcmMgKSB7XG5cdHZhciBrZXksIGRlZXAsXG5cdFx0ZmxhdE9wdGlvbnMgPSBqUXVlcnkuYWpheFNldHRpbmdzLmZsYXRPcHRpb25zIHx8IHt9O1xuXG5cdGZvciAoIGtleSBpbiBzcmMgKSB7XG5cdFx0aWYgKCBzcmNbIGtleSBdICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHQoIGZsYXRPcHRpb25zWyBrZXkgXSA/IHRhcmdldCA6ICggZGVlcCB8fCAoIGRlZXAgPSB7fSApICkgKVsga2V5IF0gPSBzcmNbIGtleSBdO1xuXHRcdH1cblx0fVxuXHRpZiAoIGRlZXAgKSB7XG5cdFx0alF1ZXJ5LmV4dGVuZCggdHJ1ZSwgdGFyZ2V0LCBkZWVwICk7XG5cdH1cblxuXHRyZXR1cm4gdGFyZ2V0O1xufVxuXG4vKiBIYW5kbGVzIHJlc3BvbnNlcyB0byBhbiBhamF4IHJlcXVlc3Q6XG4gKiAtIGZpbmRzIHRoZSByaWdodCBkYXRhVHlwZSAobWVkaWF0ZXMgYmV0d2VlbiBjb250ZW50LXR5cGUgYW5kIGV4cGVjdGVkIGRhdGFUeXBlKVxuICogLSByZXR1cm5zIHRoZSBjb3JyZXNwb25kaW5nIHJlc3BvbnNlXG4gKi9cbmZ1bmN0aW9uIGFqYXhIYW5kbGVSZXNwb25zZXMoIHMsIGpxWEhSLCByZXNwb25zZXMgKSB7XG5cblx0dmFyIGN0LCB0eXBlLCBmaW5hbERhdGFUeXBlLCBmaXJzdERhdGFUeXBlLFxuXHRcdGNvbnRlbnRzID0gcy5jb250ZW50cyxcblx0XHRkYXRhVHlwZXMgPSBzLmRhdGFUeXBlcztcblxuXHQvLyBSZW1vdmUgYXV0byBkYXRhVHlwZSBhbmQgZ2V0IGNvbnRlbnQtdHlwZSBpbiB0aGUgcHJvY2Vzc1xuXHR3aGlsZSAoIGRhdGFUeXBlc1sgMCBdID09PSBcIipcIiApIHtcblx0XHRkYXRhVHlwZXMuc2hpZnQoKTtcblx0XHRpZiAoIGN0ID09PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRjdCA9IHMubWltZVR5cGUgfHwganFYSFIuZ2V0UmVzcG9uc2VIZWFkZXIoIFwiQ29udGVudC1UeXBlXCIgKTtcblx0XHR9XG5cdH1cblxuXHQvLyBDaGVjayBpZiB3ZSdyZSBkZWFsaW5nIHdpdGggYSBrbm93biBjb250ZW50LXR5cGVcblx0aWYgKCBjdCApIHtcblx0XHRmb3IgKCB0eXBlIGluIGNvbnRlbnRzICkge1xuXHRcdFx0aWYgKCBjb250ZW50c1sgdHlwZSBdICYmIGNvbnRlbnRzWyB0eXBlIF0udGVzdCggY3QgKSApIHtcblx0XHRcdFx0ZGF0YVR5cGVzLnVuc2hpZnQoIHR5cGUgKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0Ly8gQ2hlY2sgdG8gc2VlIGlmIHdlIGhhdmUgYSByZXNwb25zZSBmb3IgdGhlIGV4cGVjdGVkIGRhdGFUeXBlXG5cdGlmICggZGF0YVR5cGVzWyAwIF0gaW4gcmVzcG9uc2VzICkge1xuXHRcdGZpbmFsRGF0YVR5cGUgPSBkYXRhVHlwZXNbIDAgXTtcblx0fSBlbHNlIHtcblxuXHRcdC8vIFRyeSBjb252ZXJ0aWJsZSBkYXRhVHlwZXNcblx0XHRmb3IgKCB0eXBlIGluIHJlc3BvbnNlcyApIHtcblx0XHRcdGlmICggIWRhdGFUeXBlc1sgMCBdIHx8IHMuY29udmVydGVyc1sgdHlwZSArIFwiIFwiICsgZGF0YVR5cGVzWyAwIF0gXSApIHtcblx0XHRcdFx0ZmluYWxEYXRhVHlwZSA9IHR5cGU7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0fVxuXHRcdFx0aWYgKCAhZmlyc3REYXRhVHlwZSApIHtcblx0XHRcdFx0Zmlyc3REYXRhVHlwZSA9IHR5cGU7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gT3IganVzdCB1c2UgZmlyc3Qgb25lXG5cdFx0ZmluYWxEYXRhVHlwZSA9IGZpbmFsRGF0YVR5cGUgfHwgZmlyc3REYXRhVHlwZTtcblx0fVxuXG5cdC8vIElmIHdlIGZvdW5kIGEgZGF0YVR5cGVcblx0Ly8gV2UgYWRkIHRoZSBkYXRhVHlwZSB0byB0aGUgbGlzdCBpZiBuZWVkZWRcblx0Ly8gYW5kIHJldHVybiB0aGUgY29ycmVzcG9uZGluZyByZXNwb25zZVxuXHRpZiAoIGZpbmFsRGF0YVR5cGUgKSB7XG5cdFx0aWYgKCBmaW5hbERhdGFUeXBlICE9PSBkYXRhVHlwZXNbIDAgXSApIHtcblx0XHRcdGRhdGFUeXBlcy51bnNoaWZ0KCBmaW5hbERhdGFUeXBlICk7XG5cdFx0fVxuXHRcdHJldHVybiByZXNwb25zZXNbIGZpbmFsRGF0YVR5cGUgXTtcblx0fVxufVxuXG4vKiBDaGFpbiBjb252ZXJzaW9ucyBnaXZlbiB0aGUgcmVxdWVzdCBhbmQgdGhlIG9yaWdpbmFsIHJlc3BvbnNlXG4gKiBBbHNvIHNldHMgdGhlIHJlc3BvbnNlWFhYIGZpZWxkcyBvbiB0aGUganFYSFIgaW5zdGFuY2VcbiAqL1xuZnVuY3Rpb24gYWpheENvbnZlcnQoIHMsIHJlc3BvbnNlLCBqcVhIUiwgaXNTdWNjZXNzICkge1xuXHR2YXIgY29udjIsIGN1cnJlbnQsIGNvbnYsIHRtcCwgcHJldixcblx0XHRjb252ZXJ0ZXJzID0ge30sXG5cblx0XHQvLyBXb3JrIHdpdGggYSBjb3B5IG9mIGRhdGFUeXBlcyBpbiBjYXNlIHdlIG5lZWQgdG8gbW9kaWZ5IGl0IGZvciBjb252ZXJzaW9uXG5cdFx0ZGF0YVR5cGVzID0gcy5kYXRhVHlwZXMuc2xpY2UoKTtcblxuXHQvLyBDcmVhdGUgY29udmVydGVycyBtYXAgd2l0aCBsb3dlcmNhc2VkIGtleXNcblx0aWYgKCBkYXRhVHlwZXNbIDEgXSApIHtcblx0XHRmb3IgKCBjb252IGluIHMuY29udmVydGVycyApIHtcblx0XHRcdGNvbnZlcnRlcnNbIGNvbnYudG9Mb3dlckNhc2UoKSBdID0gcy5jb252ZXJ0ZXJzWyBjb252IF07XG5cdFx0fVxuXHR9XG5cblx0Y3VycmVudCA9IGRhdGFUeXBlcy5zaGlmdCgpO1xuXG5cdC8vIENvbnZlcnQgdG8gZWFjaCBzZXF1ZW50aWFsIGRhdGFUeXBlXG5cdHdoaWxlICggY3VycmVudCApIHtcblxuXHRcdGlmICggcy5yZXNwb25zZUZpZWxkc1sgY3VycmVudCBdICkge1xuXHRcdFx0anFYSFJbIHMucmVzcG9uc2VGaWVsZHNbIGN1cnJlbnQgXSBdID0gcmVzcG9uc2U7XG5cdFx0fVxuXG5cdFx0Ly8gQXBwbHkgdGhlIGRhdGFGaWx0ZXIgaWYgcHJvdmlkZWRcblx0XHRpZiAoICFwcmV2ICYmIGlzU3VjY2VzcyAmJiBzLmRhdGFGaWx0ZXIgKSB7XG5cdFx0XHRyZXNwb25zZSA9IHMuZGF0YUZpbHRlciggcmVzcG9uc2UsIHMuZGF0YVR5cGUgKTtcblx0XHR9XG5cblx0XHRwcmV2ID0gY3VycmVudDtcblx0XHRjdXJyZW50ID0gZGF0YVR5cGVzLnNoaWZ0KCk7XG5cblx0XHRpZiAoIGN1cnJlbnQgKSB7XG5cblx0XHRcdC8vIFRoZXJlJ3Mgb25seSB3b3JrIHRvIGRvIGlmIGN1cnJlbnQgZGF0YVR5cGUgaXMgbm9uLWF1dG9cblx0XHRcdGlmICggY3VycmVudCA9PT0gXCIqXCIgKSB7XG5cblx0XHRcdFx0Y3VycmVudCA9IHByZXY7XG5cblx0XHRcdC8vIENvbnZlcnQgcmVzcG9uc2UgaWYgcHJldiBkYXRhVHlwZSBpcyBub24tYXV0byBhbmQgZGlmZmVycyBmcm9tIGN1cnJlbnRcblx0XHRcdH0gZWxzZSBpZiAoIHByZXYgIT09IFwiKlwiICYmIHByZXYgIT09IGN1cnJlbnQgKSB7XG5cblx0XHRcdFx0Ly8gU2VlayBhIGRpcmVjdCBjb252ZXJ0ZXJcblx0XHRcdFx0Y29udiA9IGNvbnZlcnRlcnNbIHByZXYgKyBcIiBcIiArIGN1cnJlbnQgXSB8fCBjb252ZXJ0ZXJzWyBcIiogXCIgKyBjdXJyZW50IF07XG5cblx0XHRcdFx0Ly8gSWYgbm9uZSBmb3VuZCwgc2VlayBhIHBhaXJcblx0XHRcdFx0aWYgKCAhY29udiApIHtcblx0XHRcdFx0XHRmb3IgKCBjb252MiBpbiBjb252ZXJ0ZXJzICkge1xuXG5cdFx0XHRcdFx0XHQvLyBJZiBjb252MiBvdXRwdXRzIGN1cnJlbnRcblx0XHRcdFx0XHRcdHRtcCA9IGNvbnYyLnNwbGl0KCBcIiBcIiApO1xuXHRcdFx0XHRcdFx0aWYgKCB0bXBbIDEgXSA9PT0gY3VycmVudCApIHtcblxuXHRcdFx0XHRcdFx0XHQvLyBJZiBwcmV2IGNhbiBiZSBjb252ZXJ0ZWQgdG8gYWNjZXB0ZWQgaW5wdXRcblx0XHRcdFx0XHRcdFx0Y29udiA9IGNvbnZlcnRlcnNbIHByZXYgKyBcIiBcIiArIHRtcFsgMCBdIF0gfHxcblx0XHRcdFx0XHRcdFx0XHRjb252ZXJ0ZXJzWyBcIiogXCIgKyB0bXBbIDAgXSBdO1xuXHRcdFx0XHRcdFx0XHRpZiAoIGNvbnYgKSB7XG5cblx0XHRcdFx0XHRcdFx0XHQvLyBDb25kZW5zZSBlcXVpdmFsZW5jZSBjb252ZXJ0ZXJzXG5cdFx0XHRcdFx0XHRcdFx0aWYgKCBjb252ID09PSB0cnVlICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0Y29udiA9IGNvbnZlcnRlcnNbIGNvbnYyIF07XG5cblx0XHRcdFx0XHRcdFx0XHQvLyBPdGhlcndpc2UsIGluc2VydCB0aGUgaW50ZXJtZWRpYXRlIGRhdGFUeXBlXG5cdFx0XHRcdFx0XHRcdFx0fSBlbHNlIGlmICggY29udmVydGVyc1sgY29udjIgXSAhPT0gdHJ1ZSApIHtcblx0XHRcdFx0XHRcdFx0XHRcdGN1cnJlbnQgPSB0bXBbIDAgXTtcblx0XHRcdFx0XHRcdFx0XHRcdGRhdGFUeXBlcy51bnNoaWZ0KCB0bXBbIDEgXSApO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIEFwcGx5IGNvbnZlcnRlciAoaWYgbm90IGFuIGVxdWl2YWxlbmNlKVxuXHRcdFx0XHRpZiAoIGNvbnYgIT09IHRydWUgKSB7XG5cblx0XHRcdFx0XHQvLyBVbmxlc3MgZXJyb3JzIGFyZSBhbGxvd2VkIHRvIGJ1YmJsZSwgY2F0Y2ggYW5kIHJldHVybiB0aGVtXG5cdFx0XHRcdFx0aWYgKCBjb252ICYmIHMudGhyb3dzICkge1xuXHRcdFx0XHRcdFx0cmVzcG9uc2UgPSBjb252KCByZXNwb25zZSApO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdFx0XHRyZXNwb25zZSA9IGNvbnYoIHJlc3BvbnNlICk7XG5cdFx0XHRcdFx0XHR9IGNhdGNoICggZSApIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0XHRcdFx0XHRzdGF0ZTogXCJwYXJzZXJlcnJvclwiLFxuXHRcdFx0XHRcdFx0XHRcdGVycm9yOiBjb252ID8gZSA6IFwiTm8gY29udmVyc2lvbiBmcm9tIFwiICsgcHJldiArIFwiIHRvIFwiICsgY3VycmVudFxuXHRcdFx0XHRcdFx0XHR9O1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHJldHVybiB7IHN0YXRlOiBcInN1Y2Nlc3NcIiwgZGF0YTogcmVzcG9uc2UgfTtcbn1cblxualF1ZXJ5LmV4dGVuZCgge1xuXG5cdC8vIENvdW50ZXIgZm9yIGhvbGRpbmcgdGhlIG51bWJlciBvZiBhY3RpdmUgcXVlcmllc1xuXHRhY3RpdmU6IDAsXG5cblx0Ly8gTGFzdC1Nb2RpZmllZCBoZWFkZXIgY2FjaGUgZm9yIG5leHQgcmVxdWVzdFxuXHRsYXN0TW9kaWZpZWQ6IHt9LFxuXHRldGFnOiB7fSxcblxuXHRhamF4U2V0dGluZ3M6IHtcblx0XHR1cmw6IGxvY2F0aW9uLmhyZWYsXG5cdFx0dHlwZTogXCJHRVRcIixcblx0XHRpc0xvY2FsOiBybG9jYWxQcm90b2NvbC50ZXN0KCBsb2NhdGlvbi5wcm90b2NvbCApLFxuXHRcdGdsb2JhbDogdHJ1ZSxcblx0XHRwcm9jZXNzRGF0YTogdHJ1ZSxcblx0XHRhc3luYzogdHJ1ZSxcblx0XHRjb250ZW50VHlwZTogXCJhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQ7IGNoYXJzZXQ9VVRGLThcIixcblxuXHRcdC8qXG5cdFx0dGltZW91dDogMCxcblx0XHRkYXRhOiBudWxsLFxuXHRcdGRhdGFUeXBlOiBudWxsLFxuXHRcdHVzZXJuYW1lOiBudWxsLFxuXHRcdHBhc3N3b3JkOiBudWxsLFxuXHRcdGNhY2hlOiBudWxsLFxuXHRcdHRocm93czogZmFsc2UsXG5cdFx0dHJhZGl0aW9uYWw6IGZhbHNlLFxuXHRcdGhlYWRlcnM6IHt9LFxuXHRcdCovXG5cblx0XHRhY2NlcHRzOiB7XG5cdFx0XHRcIipcIjogYWxsVHlwZXMsXG5cdFx0XHR0ZXh0OiBcInRleHQvcGxhaW5cIixcblx0XHRcdGh0bWw6IFwidGV4dC9odG1sXCIsXG5cdFx0XHR4bWw6IFwiYXBwbGljYXRpb24veG1sLCB0ZXh0L3htbFwiLFxuXHRcdFx0anNvbjogXCJhcHBsaWNhdGlvbi9qc29uLCB0ZXh0L2phdmFzY3JpcHRcIlxuXHRcdH0sXG5cblx0XHRjb250ZW50czoge1xuXHRcdFx0eG1sOiAvXFxieG1sXFxiLyxcblx0XHRcdGh0bWw6IC9cXGJodG1sLyxcblx0XHRcdGpzb246IC9cXGJqc29uXFxiL1xuXHRcdH0sXG5cblx0XHRyZXNwb25zZUZpZWxkczoge1xuXHRcdFx0eG1sOiBcInJlc3BvbnNlWE1MXCIsXG5cdFx0XHR0ZXh0OiBcInJlc3BvbnNlVGV4dFwiLFxuXHRcdFx0anNvbjogXCJyZXNwb25zZUpTT05cIlxuXHRcdH0sXG5cblx0XHQvLyBEYXRhIGNvbnZlcnRlcnNcblx0XHQvLyBLZXlzIHNlcGFyYXRlIHNvdXJjZSAob3IgY2F0Y2hhbGwgXCIqXCIpIGFuZCBkZXN0aW5hdGlvbiB0eXBlcyB3aXRoIGEgc2luZ2xlIHNwYWNlXG5cdFx0Y29udmVydGVyczoge1xuXG5cdFx0XHQvLyBDb252ZXJ0IGFueXRoaW5nIHRvIHRleHRcblx0XHRcdFwiKiB0ZXh0XCI6IFN0cmluZyxcblxuXHRcdFx0Ly8gVGV4dCB0byBodG1sICh0cnVlID0gbm8gdHJhbnNmb3JtYXRpb24pXG5cdFx0XHRcInRleHQgaHRtbFwiOiB0cnVlLFxuXG5cdFx0XHQvLyBFdmFsdWF0ZSB0ZXh0IGFzIGEganNvbiBleHByZXNzaW9uXG5cdFx0XHRcInRleHQganNvblwiOiBKU09OLnBhcnNlLFxuXG5cdFx0XHQvLyBQYXJzZSB0ZXh0IGFzIHhtbFxuXHRcdFx0XCJ0ZXh0IHhtbFwiOiBqUXVlcnkucGFyc2VYTUxcblx0XHR9LFxuXG5cdFx0Ly8gRm9yIG9wdGlvbnMgdGhhdCBzaG91bGRuJ3QgYmUgZGVlcCBleHRlbmRlZDpcblx0XHQvLyB5b3UgY2FuIGFkZCB5b3VyIG93biBjdXN0b20gb3B0aW9ucyBoZXJlIGlmXG5cdFx0Ly8gYW5kIHdoZW4geW91IGNyZWF0ZSBvbmUgdGhhdCBzaG91bGRuJ3QgYmVcblx0XHQvLyBkZWVwIGV4dGVuZGVkIChzZWUgYWpheEV4dGVuZClcblx0XHRmbGF0T3B0aW9uczoge1xuXHRcdFx0dXJsOiB0cnVlLFxuXHRcdFx0Y29udGV4dDogdHJ1ZVxuXHRcdH1cblx0fSxcblxuXHQvLyBDcmVhdGVzIGEgZnVsbCBmbGVkZ2VkIHNldHRpbmdzIG9iamVjdCBpbnRvIHRhcmdldFxuXHQvLyB3aXRoIGJvdGggYWpheFNldHRpbmdzIGFuZCBzZXR0aW5ncyBmaWVsZHMuXG5cdC8vIElmIHRhcmdldCBpcyBvbWl0dGVkLCB3cml0ZXMgaW50byBhamF4U2V0dGluZ3MuXG5cdGFqYXhTZXR1cDogZnVuY3Rpb24oIHRhcmdldCwgc2V0dGluZ3MgKSB7XG5cdFx0cmV0dXJuIHNldHRpbmdzID9cblxuXHRcdFx0Ly8gQnVpbGRpbmcgYSBzZXR0aW5ncyBvYmplY3Rcblx0XHRcdGFqYXhFeHRlbmQoIGFqYXhFeHRlbmQoIHRhcmdldCwgalF1ZXJ5LmFqYXhTZXR0aW5ncyApLCBzZXR0aW5ncyApIDpcblxuXHRcdFx0Ly8gRXh0ZW5kaW5nIGFqYXhTZXR0aW5nc1xuXHRcdFx0YWpheEV4dGVuZCggalF1ZXJ5LmFqYXhTZXR0aW5ncywgdGFyZ2V0ICk7XG5cdH0sXG5cblx0YWpheFByZWZpbHRlcjogYWRkVG9QcmVmaWx0ZXJzT3JUcmFuc3BvcnRzKCBwcmVmaWx0ZXJzICksXG5cdGFqYXhUcmFuc3BvcnQ6IGFkZFRvUHJlZmlsdGVyc09yVHJhbnNwb3J0cyggdHJhbnNwb3J0cyApLFxuXG5cdC8vIE1haW4gbWV0aG9kXG5cdGFqYXg6IGZ1bmN0aW9uKCB1cmwsIG9wdGlvbnMgKSB7XG5cblx0XHQvLyBJZiB1cmwgaXMgYW4gb2JqZWN0LCBzaW11bGF0ZSBwcmUtMS41IHNpZ25hdHVyZVxuXHRcdGlmICggdHlwZW9mIHVybCA9PT0gXCJvYmplY3RcIiApIHtcblx0XHRcdG9wdGlvbnMgPSB1cmw7XG5cdFx0XHR1cmwgPSB1bmRlZmluZWQ7XG5cdFx0fVxuXG5cdFx0Ly8gRm9yY2Ugb3B0aW9ucyB0byBiZSBhbiBvYmplY3Rcblx0XHRvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuXHRcdHZhciB0cmFuc3BvcnQsXG5cblx0XHRcdC8vIFVSTCB3aXRob3V0IGFudGktY2FjaGUgcGFyYW1cblx0XHRcdGNhY2hlVVJMLFxuXG5cdFx0XHQvLyBSZXNwb25zZSBoZWFkZXJzXG5cdFx0XHRyZXNwb25zZUhlYWRlcnNTdHJpbmcsXG5cdFx0XHRyZXNwb25zZUhlYWRlcnMsXG5cblx0XHRcdC8vIHRpbWVvdXQgaGFuZGxlXG5cdFx0XHR0aW1lb3V0VGltZXIsXG5cblx0XHRcdC8vIFVybCBjbGVhbnVwIHZhclxuXHRcdFx0dXJsQW5jaG9yLFxuXG5cdFx0XHQvLyBSZXF1ZXN0IHN0YXRlIChiZWNvbWVzIGZhbHNlIHVwb24gc2VuZCBhbmQgdHJ1ZSB1cG9uIGNvbXBsZXRpb24pXG5cdFx0XHRjb21wbGV0ZWQsXG5cblx0XHRcdC8vIFRvIGtub3cgaWYgZ2xvYmFsIGV2ZW50cyBhcmUgdG8gYmUgZGlzcGF0Y2hlZFxuXHRcdFx0ZmlyZUdsb2JhbHMsXG5cblx0XHRcdC8vIExvb3AgdmFyaWFibGVcblx0XHRcdGksXG5cblx0XHRcdC8vIHVuY2FjaGVkIHBhcnQgb2YgdGhlIHVybFxuXHRcdFx0dW5jYWNoZWQsXG5cblx0XHRcdC8vIENyZWF0ZSB0aGUgZmluYWwgb3B0aW9ucyBvYmplY3Rcblx0XHRcdHMgPSBqUXVlcnkuYWpheFNldHVwKCB7fSwgb3B0aW9ucyApLFxuXG5cdFx0XHQvLyBDYWxsYmFja3MgY29udGV4dFxuXHRcdFx0Y2FsbGJhY2tDb250ZXh0ID0gcy5jb250ZXh0IHx8IHMsXG5cblx0XHRcdC8vIENvbnRleHQgZm9yIGdsb2JhbCBldmVudHMgaXMgY2FsbGJhY2tDb250ZXh0IGlmIGl0IGlzIGEgRE9NIG5vZGUgb3IgalF1ZXJ5IGNvbGxlY3Rpb25cblx0XHRcdGdsb2JhbEV2ZW50Q29udGV4dCA9IHMuY29udGV4dCAmJlxuXHRcdFx0XHQoIGNhbGxiYWNrQ29udGV4dC5ub2RlVHlwZSB8fCBjYWxsYmFja0NvbnRleHQuanF1ZXJ5ICkgP1xuXHRcdFx0XHRqUXVlcnkoIGNhbGxiYWNrQ29udGV4dCApIDpcblx0XHRcdFx0alF1ZXJ5LmV2ZW50LFxuXG5cdFx0XHQvLyBEZWZlcnJlZHNcblx0XHRcdGRlZmVycmVkID0galF1ZXJ5LkRlZmVycmVkKCksXG5cdFx0XHRjb21wbGV0ZURlZmVycmVkID0galF1ZXJ5LkNhbGxiYWNrcyggXCJvbmNlIG1lbW9yeVwiICksXG5cblx0XHRcdC8vIFN0YXR1cy1kZXBlbmRlbnQgY2FsbGJhY2tzXG5cdFx0XHRzdGF0dXNDb2RlID0gcy5zdGF0dXNDb2RlIHx8IHt9LFxuXG5cdFx0XHQvLyBIZWFkZXJzICh0aGV5IGFyZSBzZW50IGFsbCBhdCBvbmNlKVxuXHRcdFx0cmVxdWVzdEhlYWRlcnMgPSB7fSxcblx0XHRcdHJlcXVlc3RIZWFkZXJzTmFtZXMgPSB7fSxcblxuXHRcdFx0Ly8gRGVmYXVsdCBhYm9ydCBtZXNzYWdlXG5cdFx0XHRzdHJBYm9ydCA9IFwiY2FuY2VsZWRcIixcblxuXHRcdFx0Ly8gRmFrZSB4aHJcblx0XHRcdGpxWEhSID0ge1xuXHRcdFx0XHRyZWFkeVN0YXRlOiAwLFxuXG5cdFx0XHRcdC8vIEJ1aWxkcyBoZWFkZXJzIGhhc2h0YWJsZSBpZiBuZWVkZWRcblx0XHRcdFx0Z2V0UmVzcG9uc2VIZWFkZXI6IGZ1bmN0aW9uKCBrZXkgKSB7XG5cdFx0XHRcdFx0dmFyIG1hdGNoO1xuXHRcdFx0XHRcdGlmICggY29tcGxldGVkICkge1xuXHRcdFx0XHRcdFx0aWYgKCAhcmVzcG9uc2VIZWFkZXJzICkge1xuXHRcdFx0XHRcdFx0XHRyZXNwb25zZUhlYWRlcnMgPSB7fTtcblx0XHRcdFx0XHRcdFx0d2hpbGUgKCAoIG1hdGNoID0gcmhlYWRlcnMuZXhlYyggcmVzcG9uc2VIZWFkZXJzU3RyaW5nICkgKSApIHtcblx0XHRcdFx0XHRcdFx0XHRyZXNwb25zZUhlYWRlcnNbIG1hdGNoWyAxIF0udG9Mb3dlckNhc2UoKSArIFwiIFwiIF0gPVxuXHRcdFx0XHRcdFx0XHRcdFx0KCByZXNwb25zZUhlYWRlcnNbIG1hdGNoWyAxIF0udG9Mb3dlckNhc2UoKSArIFwiIFwiIF0gfHwgW10gKVxuXHRcdFx0XHRcdFx0XHRcdFx0XHQuY29uY2F0KCBtYXRjaFsgMiBdICk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdG1hdGNoID0gcmVzcG9uc2VIZWFkZXJzWyBrZXkudG9Mb3dlckNhc2UoKSArIFwiIFwiIF07XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHJldHVybiBtYXRjaCA9PSBudWxsID8gbnVsbCA6IG1hdGNoLmpvaW4oIFwiLCBcIiApO1xuXHRcdFx0XHR9LFxuXG5cdFx0XHRcdC8vIFJhdyBzdHJpbmdcblx0XHRcdFx0Z2V0QWxsUmVzcG9uc2VIZWFkZXJzOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRyZXR1cm4gY29tcGxldGVkID8gcmVzcG9uc2VIZWFkZXJzU3RyaW5nIDogbnVsbDtcblx0XHRcdFx0fSxcblxuXHRcdFx0XHQvLyBDYWNoZXMgdGhlIGhlYWRlclxuXHRcdFx0XHRzZXRSZXF1ZXN0SGVhZGVyOiBmdW5jdGlvbiggbmFtZSwgdmFsdWUgKSB7XG5cdFx0XHRcdFx0aWYgKCBjb21wbGV0ZWQgPT0gbnVsbCApIHtcblx0XHRcdFx0XHRcdG5hbWUgPSByZXF1ZXN0SGVhZGVyc05hbWVzWyBuYW1lLnRvTG93ZXJDYXNlKCkgXSA9XG5cdFx0XHRcdFx0XHRcdHJlcXVlc3RIZWFkZXJzTmFtZXNbIG5hbWUudG9Mb3dlckNhc2UoKSBdIHx8IG5hbWU7XG5cdFx0XHRcdFx0XHRyZXF1ZXN0SGVhZGVyc1sgbmFtZSBdID0gdmFsdWU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0XHR9LFxuXG5cdFx0XHRcdC8vIE92ZXJyaWRlcyByZXNwb25zZSBjb250ZW50LXR5cGUgaGVhZGVyXG5cdFx0XHRcdG92ZXJyaWRlTWltZVR5cGU6IGZ1bmN0aW9uKCB0eXBlICkge1xuXHRcdFx0XHRcdGlmICggY29tcGxldGVkID09IG51bGwgKSB7XG5cdFx0XHRcdFx0XHRzLm1pbWVUeXBlID0gdHlwZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHRcdH0sXG5cblx0XHRcdFx0Ly8gU3RhdHVzLWRlcGVuZGVudCBjYWxsYmFja3Ncblx0XHRcdFx0c3RhdHVzQ29kZTogZnVuY3Rpb24oIG1hcCApIHtcblx0XHRcdFx0XHR2YXIgY29kZTtcblx0XHRcdFx0XHRpZiAoIG1hcCApIHtcblx0XHRcdFx0XHRcdGlmICggY29tcGxldGVkICkge1xuXG5cdFx0XHRcdFx0XHRcdC8vIEV4ZWN1dGUgdGhlIGFwcHJvcHJpYXRlIGNhbGxiYWNrc1xuXHRcdFx0XHRcdFx0XHRqcVhIUi5hbHdheXMoIG1hcFsganFYSFIuc3RhdHVzIF0gKTtcblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0XHRcdFx0Ly8gTGF6eS1hZGQgdGhlIG5ldyBjYWxsYmFja3MgaW4gYSB3YXkgdGhhdCBwcmVzZXJ2ZXMgb2xkIG9uZXNcblx0XHRcdFx0XHRcdFx0Zm9yICggY29kZSBpbiBtYXAgKSB7XG5cdFx0XHRcdFx0XHRcdFx0c3RhdHVzQ29kZVsgY29kZSBdID0gWyBzdGF0dXNDb2RlWyBjb2RlIF0sIG1hcFsgY29kZSBdIF07XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHRcdH0sXG5cblx0XHRcdFx0Ly8gQ2FuY2VsIHRoZSByZXF1ZXN0XG5cdFx0XHRcdGFib3J0OiBmdW5jdGlvbiggc3RhdHVzVGV4dCApIHtcblx0XHRcdFx0XHR2YXIgZmluYWxUZXh0ID0gc3RhdHVzVGV4dCB8fCBzdHJBYm9ydDtcblx0XHRcdFx0XHRpZiAoIHRyYW5zcG9ydCApIHtcblx0XHRcdFx0XHRcdHRyYW5zcG9ydC5hYm9ydCggZmluYWxUZXh0ICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGRvbmUoIDAsIGZpbmFsVGV4dCApO1xuXHRcdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0XHR9XG5cdFx0XHR9O1xuXG5cdFx0Ly8gQXR0YWNoIGRlZmVycmVkc1xuXHRcdGRlZmVycmVkLnByb21pc2UoIGpxWEhSICk7XG5cblx0XHQvLyBBZGQgcHJvdG9jb2wgaWYgbm90IHByb3ZpZGVkIChwcmVmaWx0ZXJzIG1pZ2h0IGV4cGVjdCBpdClcblx0XHQvLyBIYW5kbGUgZmFsc3kgdXJsIGluIHRoZSBzZXR0aW5ncyBvYmplY3QgKCMxMDA5MzogY29uc2lzdGVuY3kgd2l0aCBvbGQgc2lnbmF0dXJlKVxuXHRcdC8vIFdlIGFsc28gdXNlIHRoZSB1cmwgcGFyYW1ldGVyIGlmIGF2YWlsYWJsZVxuXHRcdHMudXJsID0gKCAoIHVybCB8fCBzLnVybCB8fCBsb2NhdGlvbi5ocmVmICkgKyBcIlwiIClcblx0XHRcdC5yZXBsYWNlKCBycHJvdG9jb2wsIGxvY2F0aW9uLnByb3RvY29sICsgXCIvL1wiICk7XG5cblx0XHQvLyBBbGlhcyBtZXRob2Qgb3B0aW9uIHRvIHR5cGUgYXMgcGVyIHRpY2tldCAjMTIwMDRcblx0XHRzLnR5cGUgPSBvcHRpb25zLm1ldGhvZCB8fCBvcHRpb25zLnR5cGUgfHwgcy5tZXRob2QgfHwgcy50eXBlO1xuXG5cdFx0Ly8gRXh0cmFjdCBkYXRhVHlwZXMgbGlzdFxuXHRcdHMuZGF0YVR5cGVzID0gKCBzLmRhdGFUeXBlIHx8IFwiKlwiICkudG9Mb3dlckNhc2UoKS5tYXRjaCggcm5vdGh0bWx3aGl0ZSApIHx8IFsgXCJcIiBdO1xuXG5cdFx0Ly8gQSBjcm9zcy1kb21haW4gcmVxdWVzdCBpcyBpbiBvcmRlciB3aGVuIHRoZSBvcmlnaW4gZG9lc24ndCBtYXRjaCB0aGUgY3VycmVudCBvcmlnaW4uXG5cdFx0aWYgKCBzLmNyb3NzRG9tYWluID09IG51bGwgKSB7XG5cdFx0XHR1cmxBbmNob3IgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImFcIiApO1xuXG5cdFx0XHQvLyBTdXBwb3J0OiBJRSA8PTggLSAxMSwgRWRnZSAxMiAtIDE1XG5cdFx0XHQvLyBJRSB0aHJvd3MgZXhjZXB0aW9uIG9uIGFjY2Vzc2luZyB0aGUgaHJlZiBwcm9wZXJ0eSBpZiB1cmwgaXMgbWFsZm9ybWVkLFxuXHRcdFx0Ly8gZS5nLiBodHRwOi8vZXhhbXBsZS5jb206ODB4L1xuXHRcdFx0dHJ5IHtcblx0XHRcdFx0dXJsQW5jaG9yLmhyZWYgPSBzLnVybDtcblxuXHRcdFx0XHQvLyBTdXBwb3J0OiBJRSA8PTggLSAxMSBvbmx5XG5cdFx0XHRcdC8vIEFuY2hvcidzIGhvc3QgcHJvcGVydHkgaXNuJ3QgY29ycmVjdGx5IHNldCB3aGVuIHMudXJsIGlzIHJlbGF0aXZlXG5cdFx0XHRcdHVybEFuY2hvci5ocmVmID0gdXJsQW5jaG9yLmhyZWY7XG5cdFx0XHRcdHMuY3Jvc3NEb21haW4gPSBvcmlnaW5BbmNob3IucHJvdG9jb2wgKyBcIi8vXCIgKyBvcmlnaW5BbmNob3IuaG9zdCAhPT1cblx0XHRcdFx0XHR1cmxBbmNob3IucHJvdG9jb2wgKyBcIi8vXCIgKyB1cmxBbmNob3IuaG9zdDtcblx0XHRcdH0gY2F0Y2ggKCBlICkge1xuXG5cdFx0XHRcdC8vIElmIHRoZXJlIGlzIGFuIGVycm9yIHBhcnNpbmcgdGhlIFVSTCwgYXNzdW1lIGl0IGlzIGNyb3NzRG9tYWluLFxuXHRcdFx0XHQvLyBpdCBjYW4gYmUgcmVqZWN0ZWQgYnkgdGhlIHRyYW5zcG9ydCBpZiBpdCBpcyBpbnZhbGlkXG5cdFx0XHRcdHMuY3Jvc3NEb21haW4gPSB0cnVlO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIENvbnZlcnQgZGF0YSBpZiBub3QgYWxyZWFkeSBhIHN0cmluZ1xuXHRcdGlmICggcy5kYXRhICYmIHMucHJvY2Vzc0RhdGEgJiYgdHlwZW9mIHMuZGF0YSAhPT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdHMuZGF0YSA9IGpRdWVyeS5wYXJhbSggcy5kYXRhLCBzLnRyYWRpdGlvbmFsICk7XG5cdFx0fVxuXG5cdFx0Ly8gQXBwbHkgcHJlZmlsdGVyc1xuXHRcdGluc3BlY3RQcmVmaWx0ZXJzT3JUcmFuc3BvcnRzKCBwcmVmaWx0ZXJzLCBzLCBvcHRpb25zLCBqcVhIUiApO1xuXG5cdFx0Ly8gSWYgcmVxdWVzdCB3YXMgYWJvcnRlZCBpbnNpZGUgYSBwcmVmaWx0ZXIsIHN0b3AgdGhlcmVcblx0XHRpZiAoIGNvbXBsZXRlZCApIHtcblx0XHRcdHJldHVybiBqcVhIUjtcblx0XHR9XG5cblx0XHQvLyBXZSBjYW4gZmlyZSBnbG9iYWwgZXZlbnRzIGFzIG9mIG5vdyBpZiBhc2tlZCB0b1xuXHRcdC8vIERvbid0IGZpcmUgZXZlbnRzIGlmIGpRdWVyeS5ldmVudCBpcyB1bmRlZmluZWQgaW4gYW4gQU1ELXVzYWdlIHNjZW5hcmlvICgjMTUxMTgpXG5cdFx0ZmlyZUdsb2JhbHMgPSBqUXVlcnkuZXZlbnQgJiYgcy5nbG9iYWw7XG5cblx0XHQvLyBXYXRjaCBmb3IgYSBuZXcgc2V0IG9mIHJlcXVlc3RzXG5cdFx0aWYgKCBmaXJlR2xvYmFscyAmJiBqUXVlcnkuYWN0aXZlKysgPT09IDAgKSB7XG5cdFx0XHRqUXVlcnkuZXZlbnQudHJpZ2dlciggXCJhamF4U3RhcnRcIiApO1xuXHRcdH1cblxuXHRcdC8vIFVwcGVyY2FzZSB0aGUgdHlwZVxuXHRcdHMudHlwZSA9IHMudHlwZS50b1VwcGVyQ2FzZSgpO1xuXG5cdFx0Ly8gRGV0ZXJtaW5lIGlmIHJlcXVlc3QgaGFzIGNvbnRlbnRcblx0XHRzLmhhc0NvbnRlbnQgPSAhcm5vQ29udGVudC50ZXN0KCBzLnR5cGUgKTtcblxuXHRcdC8vIFNhdmUgdGhlIFVSTCBpbiBjYXNlIHdlJ3JlIHRveWluZyB3aXRoIHRoZSBJZi1Nb2RpZmllZC1TaW5jZVxuXHRcdC8vIGFuZC9vciBJZi1Ob25lLU1hdGNoIGhlYWRlciBsYXRlciBvblxuXHRcdC8vIFJlbW92ZSBoYXNoIHRvIHNpbXBsaWZ5IHVybCBtYW5pcHVsYXRpb25cblx0XHRjYWNoZVVSTCA9IHMudXJsLnJlcGxhY2UoIHJoYXNoLCBcIlwiICk7XG5cblx0XHQvLyBNb3JlIG9wdGlvbnMgaGFuZGxpbmcgZm9yIHJlcXVlc3RzIHdpdGggbm8gY29udGVudFxuXHRcdGlmICggIXMuaGFzQ29udGVudCApIHtcblxuXHRcdFx0Ly8gUmVtZW1iZXIgdGhlIGhhc2ggc28gd2UgY2FuIHB1dCBpdCBiYWNrXG5cdFx0XHR1bmNhY2hlZCA9IHMudXJsLnNsaWNlKCBjYWNoZVVSTC5sZW5ndGggKTtcblxuXHRcdFx0Ly8gSWYgZGF0YSBpcyBhdmFpbGFibGUgYW5kIHNob3VsZCBiZSBwcm9jZXNzZWQsIGFwcGVuZCBkYXRhIHRvIHVybFxuXHRcdFx0aWYgKCBzLmRhdGEgJiYgKCBzLnByb2Nlc3NEYXRhIHx8IHR5cGVvZiBzLmRhdGEgPT09IFwic3RyaW5nXCIgKSApIHtcblx0XHRcdFx0Y2FjaGVVUkwgKz0gKCBycXVlcnkudGVzdCggY2FjaGVVUkwgKSA/IFwiJlwiIDogXCI/XCIgKSArIHMuZGF0YTtcblxuXHRcdFx0XHQvLyAjOTY4MjogcmVtb3ZlIGRhdGEgc28gdGhhdCBpdCdzIG5vdCB1c2VkIGluIGFuIGV2ZW50dWFsIHJldHJ5XG5cdFx0XHRcdGRlbGV0ZSBzLmRhdGE7XG5cdFx0XHR9XG5cblx0XHRcdC8vIEFkZCBvciB1cGRhdGUgYW50aS1jYWNoZSBwYXJhbSBpZiBuZWVkZWRcblx0XHRcdGlmICggcy5jYWNoZSA9PT0gZmFsc2UgKSB7XG5cdFx0XHRcdGNhY2hlVVJMID0gY2FjaGVVUkwucmVwbGFjZSggcmFudGlDYWNoZSwgXCIkMVwiICk7XG5cdFx0XHRcdHVuY2FjaGVkID0gKCBycXVlcnkudGVzdCggY2FjaGVVUkwgKSA/IFwiJlwiIDogXCI/XCIgKSArIFwiXz1cIiArICggbm9uY2UuZ3VpZCsrICkgK1xuXHRcdFx0XHRcdHVuY2FjaGVkO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBQdXQgaGFzaCBhbmQgYW50aS1jYWNoZSBvbiB0aGUgVVJMIHRoYXQgd2lsbCBiZSByZXF1ZXN0ZWQgKGdoLTE3MzIpXG5cdFx0XHRzLnVybCA9IGNhY2hlVVJMICsgdW5jYWNoZWQ7XG5cblx0XHQvLyBDaGFuZ2UgJyUyMCcgdG8gJysnIGlmIHRoaXMgaXMgZW5jb2RlZCBmb3JtIGJvZHkgY29udGVudCAoZ2gtMjY1OClcblx0XHR9IGVsc2UgaWYgKCBzLmRhdGEgJiYgcy5wcm9jZXNzRGF0YSAmJlxuXHRcdFx0KCBzLmNvbnRlbnRUeXBlIHx8IFwiXCIgKS5pbmRleE9mKCBcImFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZFwiICkgPT09IDAgKSB7XG5cdFx0XHRzLmRhdGEgPSBzLmRhdGEucmVwbGFjZSggcjIwLCBcIitcIiApO1xuXHRcdH1cblxuXHRcdC8vIFNldCB0aGUgSWYtTW9kaWZpZWQtU2luY2UgYW5kL29yIElmLU5vbmUtTWF0Y2ggaGVhZGVyLCBpZiBpbiBpZk1vZGlmaWVkIG1vZGUuXG5cdFx0aWYgKCBzLmlmTW9kaWZpZWQgKSB7XG5cdFx0XHRpZiAoIGpRdWVyeS5sYXN0TW9kaWZpZWRbIGNhY2hlVVJMIF0gKSB7XG5cdFx0XHRcdGpxWEhSLnNldFJlcXVlc3RIZWFkZXIoIFwiSWYtTW9kaWZpZWQtU2luY2VcIiwgalF1ZXJ5Lmxhc3RNb2RpZmllZFsgY2FjaGVVUkwgXSApO1xuXHRcdFx0fVxuXHRcdFx0aWYgKCBqUXVlcnkuZXRhZ1sgY2FjaGVVUkwgXSApIHtcblx0XHRcdFx0anFYSFIuc2V0UmVxdWVzdEhlYWRlciggXCJJZi1Ob25lLU1hdGNoXCIsIGpRdWVyeS5ldGFnWyBjYWNoZVVSTCBdICk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gU2V0IHRoZSBjb3JyZWN0IGhlYWRlciwgaWYgZGF0YSBpcyBiZWluZyBzZW50XG5cdFx0aWYgKCBzLmRhdGEgJiYgcy5oYXNDb250ZW50ICYmIHMuY29udGVudFR5cGUgIT09IGZhbHNlIHx8IG9wdGlvbnMuY29udGVudFR5cGUgKSB7XG5cdFx0XHRqcVhIUi5zZXRSZXF1ZXN0SGVhZGVyKCBcIkNvbnRlbnQtVHlwZVwiLCBzLmNvbnRlbnRUeXBlICk7XG5cdFx0fVxuXG5cdFx0Ly8gU2V0IHRoZSBBY2NlcHRzIGhlYWRlciBmb3IgdGhlIHNlcnZlciwgZGVwZW5kaW5nIG9uIHRoZSBkYXRhVHlwZVxuXHRcdGpxWEhSLnNldFJlcXVlc3RIZWFkZXIoXG5cdFx0XHRcIkFjY2VwdFwiLFxuXHRcdFx0cy5kYXRhVHlwZXNbIDAgXSAmJiBzLmFjY2VwdHNbIHMuZGF0YVR5cGVzWyAwIF0gXSA/XG5cdFx0XHRcdHMuYWNjZXB0c1sgcy5kYXRhVHlwZXNbIDAgXSBdICtcblx0XHRcdFx0XHQoIHMuZGF0YVR5cGVzWyAwIF0gIT09IFwiKlwiID8gXCIsIFwiICsgYWxsVHlwZXMgKyBcIjsgcT0wLjAxXCIgOiBcIlwiICkgOlxuXHRcdFx0XHRzLmFjY2VwdHNbIFwiKlwiIF1cblx0XHQpO1xuXG5cdFx0Ly8gQ2hlY2sgZm9yIGhlYWRlcnMgb3B0aW9uXG5cdFx0Zm9yICggaSBpbiBzLmhlYWRlcnMgKSB7XG5cdFx0XHRqcVhIUi5zZXRSZXF1ZXN0SGVhZGVyKCBpLCBzLmhlYWRlcnNbIGkgXSApO1xuXHRcdH1cblxuXHRcdC8vIEFsbG93IGN1c3RvbSBoZWFkZXJzL21pbWV0eXBlcyBhbmQgZWFybHkgYWJvcnRcblx0XHRpZiAoIHMuYmVmb3JlU2VuZCAmJlxuXHRcdFx0KCBzLmJlZm9yZVNlbmQuY2FsbCggY2FsbGJhY2tDb250ZXh0LCBqcVhIUiwgcyApID09PSBmYWxzZSB8fCBjb21wbGV0ZWQgKSApIHtcblxuXHRcdFx0Ly8gQWJvcnQgaWYgbm90IGRvbmUgYWxyZWFkeSBhbmQgcmV0dXJuXG5cdFx0XHRyZXR1cm4ganFYSFIuYWJvcnQoKTtcblx0XHR9XG5cblx0XHQvLyBBYm9ydGluZyBpcyBubyBsb25nZXIgYSBjYW5jZWxsYXRpb25cblx0XHRzdHJBYm9ydCA9IFwiYWJvcnRcIjtcblxuXHRcdC8vIEluc3RhbGwgY2FsbGJhY2tzIG9uIGRlZmVycmVkc1xuXHRcdGNvbXBsZXRlRGVmZXJyZWQuYWRkKCBzLmNvbXBsZXRlICk7XG5cdFx0anFYSFIuZG9uZSggcy5zdWNjZXNzICk7XG5cdFx0anFYSFIuZmFpbCggcy5lcnJvciApO1xuXG5cdFx0Ly8gR2V0IHRyYW5zcG9ydFxuXHRcdHRyYW5zcG9ydCA9IGluc3BlY3RQcmVmaWx0ZXJzT3JUcmFuc3BvcnRzKCB0cmFuc3BvcnRzLCBzLCBvcHRpb25zLCBqcVhIUiApO1xuXG5cdFx0Ly8gSWYgbm8gdHJhbnNwb3J0LCB3ZSBhdXRvLWFib3J0XG5cdFx0aWYgKCAhdHJhbnNwb3J0ICkge1xuXHRcdFx0ZG9uZSggLTEsIFwiTm8gVHJhbnNwb3J0XCIgKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0anFYSFIucmVhZHlTdGF0ZSA9IDE7XG5cblx0XHRcdC8vIFNlbmQgZ2xvYmFsIGV2ZW50XG5cdFx0XHRpZiAoIGZpcmVHbG9iYWxzICkge1xuXHRcdFx0XHRnbG9iYWxFdmVudENvbnRleHQudHJpZ2dlciggXCJhamF4U2VuZFwiLCBbIGpxWEhSLCBzIF0gKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gSWYgcmVxdWVzdCB3YXMgYWJvcnRlZCBpbnNpZGUgYWpheFNlbmQsIHN0b3AgdGhlcmVcblx0XHRcdGlmICggY29tcGxldGVkICkge1xuXHRcdFx0XHRyZXR1cm4ganFYSFI7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFRpbWVvdXRcblx0XHRcdGlmICggcy5hc3luYyAmJiBzLnRpbWVvdXQgPiAwICkge1xuXHRcdFx0XHR0aW1lb3V0VGltZXIgPSB3aW5kb3cuc2V0VGltZW91dCggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0anFYSFIuYWJvcnQoIFwidGltZW91dFwiICk7XG5cdFx0XHRcdH0sIHMudGltZW91dCApO1xuXHRcdFx0fVxuXG5cdFx0XHR0cnkge1xuXHRcdFx0XHRjb21wbGV0ZWQgPSBmYWxzZTtcblx0XHRcdFx0dHJhbnNwb3J0LnNlbmQoIHJlcXVlc3RIZWFkZXJzLCBkb25lICk7XG5cdFx0XHR9IGNhdGNoICggZSApIHtcblxuXHRcdFx0XHQvLyBSZXRocm93IHBvc3QtY29tcGxldGlvbiBleGNlcHRpb25zXG5cdFx0XHRcdGlmICggY29tcGxldGVkICkge1xuXHRcdFx0XHRcdHRocm93IGU7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBQcm9wYWdhdGUgb3RoZXJzIGFzIHJlc3VsdHNcblx0XHRcdFx0ZG9uZSggLTEsIGUgKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBDYWxsYmFjayBmb3Igd2hlbiBldmVyeXRoaW5nIGlzIGRvbmVcblx0XHRmdW5jdGlvbiBkb25lKCBzdGF0dXMsIG5hdGl2ZVN0YXR1c1RleHQsIHJlc3BvbnNlcywgaGVhZGVycyApIHtcblx0XHRcdHZhciBpc1N1Y2Nlc3MsIHN1Y2Nlc3MsIGVycm9yLCByZXNwb25zZSwgbW9kaWZpZWQsXG5cdFx0XHRcdHN0YXR1c1RleHQgPSBuYXRpdmVTdGF0dXNUZXh0O1xuXG5cdFx0XHQvLyBJZ25vcmUgcmVwZWF0IGludm9jYXRpb25zXG5cdFx0XHRpZiAoIGNvbXBsZXRlZCApIHtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHRjb21wbGV0ZWQgPSB0cnVlO1xuXG5cdFx0XHQvLyBDbGVhciB0aW1lb3V0IGlmIGl0IGV4aXN0c1xuXHRcdFx0aWYgKCB0aW1lb3V0VGltZXIgKSB7XG5cdFx0XHRcdHdpbmRvdy5jbGVhclRpbWVvdXQoIHRpbWVvdXRUaW1lciApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBEZXJlZmVyZW5jZSB0cmFuc3BvcnQgZm9yIGVhcmx5IGdhcmJhZ2UgY29sbGVjdGlvblxuXHRcdFx0Ly8gKG5vIG1hdHRlciBob3cgbG9uZyB0aGUganFYSFIgb2JqZWN0IHdpbGwgYmUgdXNlZClcblx0XHRcdHRyYW5zcG9ydCA9IHVuZGVmaW5lZDtcblxuXHRcdFx0Ly8gQ2FjaGUgcmVzcG9uc2UgaGVhZGVyc1xuXHRcdFx0cmVzcG9uc2VIZWFkZXJzU3RyaW5nID0gaGVhZGVycyB8fCBcIlwiO1xuXG5cdFx0XHQvLyBTZXQgcmVhZHlTdGF0ZVxuXHRcdFx0anFYSFIucmVhZHlTdGF0ZSA9IHN0YXR1cyA+IDAgPyA0IDogMDtcblxuXHRcdFx0Ly8gRGV0ZXJtaW5lIGlmIHN1Y2Nlc3NmdWxcblx0XHRcdGlzU3VjY2VzcyA9IHN0YXR1cyA+PSAyMDAgJiYgc3RhdHVzIDwgMzAwIHx8IHN0YXR1cyA9PT0gMzA0O1xuXG5cdFx0XHQvLyBHZXQgcmVzcG9uc2UgZGF0YVxuXHRcdFx0aWYgKCByZXNwb25zZXMgKSB7XG5cdFx0XHRcdHJlc3BvbnNlID0gYWpheEhhbmRsZVJlc3BvbnNlcyggcywganFYSFIsIHJlc3BvbnNlcyApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBVc2UgYSBub29wIGNvbnZlcnRlciBmb3IgbWlzc2luZyBzY3JpcHQgYnV0IG5vdCBpZiBqc29ucFxuXHRcdFx0aWYgKCAhaXNTdWNjZXNzICYmXG5cdFx0XHRcdGpRdWVyeS5pbkFycmF5KCBcInNjcmlwdFwiLCBzLmRhdGFUeXBlcyApID4gLTEgJiZcblx0XHRcdFx0alF1ZXJ5LmluQXJyYXkoIFwianNvblwiLCBzLmRhdGFUeXBlcyApIDwgMCApIHtcblx0XHRcdFx0cy5jb252ZXJ0ZXJzWyBcInRleHQgc2NyaXB0XCIgXSA9IGZ1bmN0aW9uKCkge307XG5cdFx0XHR9XG5cblx0XHRcdC8vIENvbnZlcnQgbm8gbWF0dGVyIHdoYXQgKHRoYXQgd2F5IHJlc3BvbnNlWFhYIGZpZWxkcyBhcmUgYWx3YXlzIHNldClcblx0XHRcdHJlc3BvbnNlID0gYWpheENvbnZlcnQoIHMsIHJlc3BvbnNlLCBqcVhIUiwgaXNTdWNjZXNzICk7XG5cblx0XHRcdC8vIElmIHN1Y2Nlc3NmdWwsIGhhbmRsZSB0eXBlIGNoYWluaW5nXG5cdFx0XHRpZiAoIGlzU3VjY2VzcyApIHtcblxuXHRcdFx0XHQvLyBTZXQgdGhlIElmLU1vZGlmaWVkLVNpbmNlIGFuZC9vciBJZi1Ob25lLU1hdGNoIGhlYWRlciwgaWYgaW4gaWZNb2RpZmllZCBtb2RlLlxuXHRcdFx0XHRpZiAoIHMuaWZNb2RpZmllZCApIHtcblx0XHRcdFx0XHRtb2RpZmllZCA9IGpxWEhSLmdldFJlc3BvbnNlSGVhZGVyKCBcIkxhc3QtTW9kaWZpZWRcIiApO1xuXHRcdFx0XHRcdGlmICggbW9kaWZpZWQgKSB7XG5cdFx0XHRcdFx0XHRqUXVlcnkubGFzdE1vZGlmaWVkWyBjYWNoZVVSTCBdID0gbW9kaWZpZWQ7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdG1vZGlmaWVkID0ganFYSFIuZ2V0UmVzcG9uc2VIZWFkZXIoIFwiZXRhZ1wiICk7XG5cdFx0XHRcdFx0aWYgKCBtb2RpZmllZCApIHtcblx0XHRcdFx0XHRcdGpRdWVyeS5ldGFnWyBjYWNoZVVSTCBdID0gbW9kaWZpZWQ7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gaWYgbm8gY29udGVudFxuXHRcdFx0XHRpZiAoIHN0YXR1cyA9PT0gMjA0IHx8IHMudHlwZSA9PT0gXCJIRUFEXCIgKSB7XG5cdFx0XHRcdFx0c3RhdHVzVGV4dCA9IFwibm9jb250ZW50XCI7XG5cblx0XHRcdFx0Ly8gaWYgbm90IG1vZGlmaWVkXG5cdFx0XHRcdH0gZWxzZSBpZiAoIHN0YXR1cyA9PT0gMzA0ICkge1xuXHRcdFx0XHRcdHN0YXR1c1RleHQgPSBcIm5vdG1vZGlmaWVkXCI7XG5cblx0XHRcdFx0Ly8gSWYgd2UgaGF2ZSBkYXRhLCBsZXQncyBjb252ZXJ0IGl0XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0c3RhdHVzVGV4dCA9IHJlc3BvbnNlLnN0YXRlO1xuXHRcdFx0XHRcdHN1Y2Nlc3MgPSByZXNwb25zZS5kYXRhO1xuXHRcdFx0XHRcdGVycm9yID0gcmVzcG9uc2UuZXJyb3I7XG5cdFx0XHRcdFx0aXNTdWNjZXNzID0gIWVycm9yO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdC8vIEV4dHJhY3QgZXJyb3IgZnJvbSBzdGF0dXNUZXh0IGFuZCBub3JtYWxpemUgZm9yIG5vbi1hYm9ydHNcblx0XHRcdFx0ZXJyb3IgPSBzdGF0dXNUZXh0O1xuXHRcdFx0XHRpZiAoIHN0YXR1cyB8fCAhc3RhdHVzVGV4dCApIHtcblx0XHRcdFx0XHRzdGF0dXNUZXh0ID0gXCJlcnJvclwiO1xuXHRcdFx0XHRcdGlmICggc3RhdHVzIDwgMCApIHtcblx0XHRcdFx0XHRcdHN0YXR1cyA9IDA7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIFNldCBkYXRhIGZvciB0aGUgZmFrZSB4aHIgb2JqZWN0XG5cdFx0XHRqcVhIUi5zdGF0dXMgPSBzdGF0dXM7XG5cdFx0XHRqcVhIUi5zdGF0dXNUZXh0ID0gKCBuYXRpdmVTdGF0dXNUZXh0IHx8IHN0YXR1c1RleHQgKSArIFwiXCI7XG5cblx0XHRcdC8vIFN1Y2Nlc3MvRXJyb3Jcblx0XHRcdGlmICggaXNTdWNjZXNzICkge1xuXHRcdFx0XHRkZWZlcnJlZC5yZXNvbHZlV2l0aCggY2FsbGJhY2tDb250ZXh0LCBbIHN1Y2Nlc3MsIHN0YXR1c1RleHQsIGpxWEhSIF0gKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGRlZmVycmVkLnJlamVjdFdpdGgoIGNhbGxiYWNrQ29udGV4dCwgWyBqcVhIUiwgc3RhdHVzVGV4dCwgZXJyb3IgXSApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBTdGF0dXMtZGVwZW5kZW50IGNhbGxiYWNrc1xuXHRcdFx0anFYSFIuc3RhdHVzQ29kZSggc3RhdHVzQ29kZSApO1xuXHRcdFx0c3RhdHVzQ29kZSA9IHVuZGVmaW5lZDtcblxuXHRcdFx0aWYgKCBmaXJlR2xvYmFscyApIHtcblx0XHRcdFx0Z2xvYmFsRXZlbnRDb250ZXh0LnRyaWdnZXIoIGlzU3VjY2VzcyA/IFwiYWpheFN1Y2Nlc3NcIiA6IFwiYWpheEVycm9yXCIsXG5cdFx0XHRcdFx0WyBqcVhIUiwgcywgaXNTdWNjZXNzID8gc3VjY2VzcyA6IGVycm9yIF0gKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQ29tcGxldGVcblx0XHRcdGNvbXBsZXRlRGVmZXJyZWQuZmlyZVdpdGgoIGNhbGxiYWNrQ29udGV4dCwgWyBqcVhIUiwgc3RhdHVzVGV4dCBdICk7XG5cblx0XHRcdGlmICggZmlyZUdsb2JhbHMgKSB7XG5cdFx0XHRcdGdsb2JhbEV2ZW50Q29udGV4dC50cmlnZ2VyKCBcImFqYXhDb21wbGV0ZVwiLCBbIGpxWEhSLCBzIF0gKTtcblxuXHRcdFx0XHQvLyBIYW5kbGUgdGhlIGdsb2JhbCBBSkFYIGNvdW50ZXJcblx0XHRcdFx0aWYgKCAhKCAtLWpRdWVyeS5hY3RpdmUgKSApIHtcblx0XHRcdFx0XHRqUXVlcnkuZXZlbnQudHJpZ2dlciggXCJhamF4U3RvcFwiICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4ganFYSFI7XG5cdH0sXG5cblx0Z2V0SlNPTjogZnVuY3Rpb24oIHVybCwgZGF0YSwgY2FsbGJhY2sgKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5nZXQoIHVybCwgZGF0YSwgY2FsbGJhY2ssIFwianNvblwiICk7XG5cdH0sXG5cblx0Z2V0U2NyaXB0OiBmdW5jdGlvbiggdXJsLCBjYWxsYmFjayApIHtcblx0XHRyZXR1cm4galF1ZXJ5LmdldCggdXJsLCB1bmRlZmluZWQsIGNhbGxiYWNrLCBcInNjcmlwdFwiICk7XG5cdH1cbn0gKTtcblxualF1ZXJ5LmVhY2goIFsgXCJnZXRcIiwgXCJwb3N0XCIgXSwgZnVuY3Rpb24oIF9pLCBtZXRob2QgKSB7XG5cdGpRdWVyeVsgbWV0aG9kIF0gPSBmdW5jdGlvbiggdXJsLCBkYXRhLCBjYWxsYmFjaywgdHlwZSApIHtcblxuXHRcdC8vIFNoaWZ0IGFyZ3VtZW50cyBpZiBkYXRhIGFyZ3VtZW50IHdhcyBvbWl0dGVkXG5cdFx0aWYgKCBpc0Z1bmN0aW9uKCBkYXRhICkgKSB7XG5cdFx0XHR0eXBlID0gdHlwZSB8fCBjYWxsYmFjaztcblx0XHRcdGNhbGxiYWNrID0gZGF0YTtcblx0XHRcdGRhdGEgPSB1bmRlZmluZWQ7XG5cdFx0fVxuXG5cdFx0Ly8gVGhlIHVybCBjYW4gYmUgYW4gb3B0aW9ucyBvYmplY3QgKHdoaWNoIHRoZW4gbXVzdCBoYXZlIC51cmwpXG5cdFx0cmV0dXJuIGpRdWVyeS5hamF4KCBqUXVlcnkuZXh0ZW5kKCB7XG5cdFx0XHR1cmw6IHVybCxcblx0XHRcdHR5cGU6IG1ldGhvZCxcblx0XHRcdGRhdGFUeXBlOiB0eXBlLFxuXHRcdFx0ZGF0YTogZGF0YSxcblx0XHRcdHN1Y2Nlc3M6IGNhbGxiYWNrXG5cdFx0fSwgalF1ZXJ5LmlzUGxhaW5PYmplY3QoIHVybCApICYmIHVybCApICk7XG5cdH07XG59ICk7XG5cbmpRdWVyeS5hamF4UHJlZmlsdGVyKCBmdW5jdGlvbiggcyApIHtcblx0dmFyIGk7XG5cdGZvciAoIGkgaW4gcy5oZWFkZXJzICkge1xuXHRcdGlmICggaS50b0xvd2VyQ2FzZSgpID09PSBcImNvbnRlbnQtdHlwZVwiICkge1xuXHRcdFx0cy5jb250ZW50VHlwZSA9IHMuaGVhZGVyc1sgaSBdIHx8IFwiXCI7XG5cdFx0fVxuXHR9XG59ICk7XG5cblxualF1ZXJ5Ll9ldmFsVXJsID0gZnVuY3Rpb24oIHVybCwgb3B0aW9ucywgZG9jICkge1xuXHRyZXR1cm4galF1ZXJ5LmFqYXgoIHtcblx0XHR1cmw6IHVybCxcblxuXHRcdC8vIE1ha2UgdGhpcyBleHBsaWNpdCwgc2luY2UgdXNlciBjYW4gb3ZlcnJpZGUgdGhpcyB0aHJvdWdoIGFqYXhTZXR1cCAoIzExMjY0KVxuXHRcdHR5cGU6IFwiR0VUXCIsXG5cdFx0ZGF0YVR5cGU6IFwic2NyaXB0XCIsXG5cdFx0Y2FjaGU6IHRydWUsXG5cdFx0YXN5bmM6IGZhbHNlLFxuXHRcdGdsb2JhbDogZmFsc2UsXG5cblx0XHQvLyBPbmx5IGV2YWx1YXRlIHRoZSByZXNwb25zZSBpZiBpdCBpcyBzdWNjZXNzZnVsIChnaC00MTI2KVxuXHRcdC8vIGRhdGFGaWx0ZXIgaXMgbm90IGludm9rZWQgZm9yIGZhaWx1cmUgcmVzcG9uc2VzLCBzbyB1c2luZyBpdCBpbnN0ZWFkXG5cdFx0Ly8gb2YgdGhlIGRlZmF1bHQgY29udmVydGVyIGlzIGtsdWRneSBidXQgaXQgd29ya3MuXG5cdFx0Y29udmVydGVyczoge1xuXHRcdFx0XCJ0ZXh0IHNjcmlwdFwiOiBmdW5jdGlvbigpIHt9XG5cdFx0fSxcblx0XHRkYXRhRmlsdGVyOiBmdW5jdGlvbiggcmVzcG9uc2UgKSB7XG5cdFx0XHRqUXVlcnkuZ2xvYmFsRXZhbCggcmVzcG9uc2UsIG9wdGlvbnMsIGRvYyApO1xuXHRcdH1cblx0fSApO1xufTtcblxuXG5qUXVlcnkuZm4uZXh0ZW5kKCB7XG5cdHdyYXBBbGw6IGZ1bmN0aW9uKCBodG1sICkge1xuXHRcdHZhciB3cmFwO1xuXG5cdFx0aWYgKCB0aGlzWyAwIF0gKSB7XG5cdFx0XHRpZiAoIGlzRnVuY3Rpb24oIGh0bWwgKSApIHtcblx0XHRcdFx0aHRtbCA9IGh0bWwuY2FsbCggdGhpc1sgMCBdICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFRoZSBlbGVtZW50cyB0byB3cmFwIHRoZSB0YXJnZXQgYXJvdW5kXG5cdFx0XHR3cmFwID0galF1ZXJ5KCBodG1sLCB0aGlzWyAwIF0ub3duZXJEb2N1bWVudCApLmVxKCAwICkuY2xvbmUoIHRydWUgKTtcblxuXHRcdFx0aWYgKCB0aGlzWyAwIF0ucGFyZW50Tm9kZSApIHtcblx0XHRcdFx0d3JhcC5pbnNlcnRCZWZvcmUoIHRoaXNbIDAgXSApO1xuXHRcdFx0fVxuXG5cdFx0XHR3cmFwLm1hcCggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHZhciBlbGVtID0gdGhpcztcblxuXHRcdFx0XHR3aGlsZSAoIGVsZW0uZmlyc3RFbGVtZW50Q2hpbGQgKSB7XG5cdFx0XHRcdFx0ZWxlbSA9IGVsZW0uZmlyc3RFbGVtZW50Q2hpbGQ7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZXR1cm4gZWxlbTtcblx0XHRcdH0gKS5hcHBlbmQoIHRoaXMgKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcztcblx0fSxcblxuXHR3cmFwSW5uZXI6IGZ1bmN0aW9uKCBodG1sICkge1xuXHRcdGlmICggaXNGdW5jdGlvbiggaHRtbCApICkge1xuXHRcdFx0cmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24oIGkgKSB7XG5cdFx0XHRcdGpRdWVyeSggdGhpcyApLndyYXBJbm5lciggaHRtbC5jYWxsKCB0aGlzLCBpICkgKTtcblx0XHRcdH0gKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcblx0XHRcdHZhciBzZWxmID0galF1ZXJ5KCB0aGlzICksXG5cdFx0XHRcdGNvbnRlbnRzID0gc2VsZi5jb250ZW50cygpO1xuXG5cdFx0XHRpZiAoIGNvbnRlbnRzLmxlbmd0aCApIHtcblx0XHRcdFx0Y29udGVudHMud3JhcEFsbCggaHRtbCApO1xuXG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRzZWxmLmFwcGVuZCggaHRtbCApO1xuXHRcdFx0fVxuXHRcdH0gKTtcblx0fSxcblxuXHR3cmFwOiBmdW5jdGlvbiggaHRtbCApIHtcblx0XHR2YXIgaHRtbElzRnVuY3Rpb24gPSBpc0Z1bmN0aW9uKCBodG1sICk7XG5cblx0XHRyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbiggaSApIHtcblx0XHRcdGpRdWVyeSggdGhpcyApLndyYXBBbGwoIGh0bWxJc0Z1bmN0aW9uID8gaHRtbC5jYWxsKCB0aGlzLCBpICkgOiBodG1sICk7XG5cdFx0fSApO1xuXHR9LFxuXG5cdHVud3JhcDogZnVuY3Rpb24oIHNlbGVjdG9yICkge1xuXHRcdHRoaXMucGFyZW50KCBzZWxlY3RvciApLm5vdCggXCJib2R5XCIgKS5lYWNoKCBmdW5jdGlvbigpIHtcblx0XHRcdGpRdWVyeSggdGhpcyApLnJlcGxhY2VXaXRoKCB0aGlzLmNoaWxkTm9kZXMgKTtcblx0XHR9ICk7XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cbn0gKTtcblxuXG5qUXVlcnkuZXhwci5wc2V1ZG9zLmhpZGRlbiA9IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRyZXR1cm4gIWpRdWVyeS5leHByLnBzZXVkb3MudmlzaWJsZSggZWxlbSApO1xufTtcbmpRdWVyeS5leHByLnBzZXVkb3MudmlzaWJsZSA9IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRyZXR1cm4gISEoIGVsZW0ub2Zmc2V0V2lkdGggfHwgZWxlbS5vZmZzZXRIZWlnaHQgfHwgZWxlbS5nZXRDbGllbnRSZWN0cygpLmxlbmd0aCApO1xufTtcblxuXG5cblxualF1ZXJ5LmFqYXhTZXR0aW5ncy54aHIgPSBmdW5jdGlvbigpIHtcblx0dHJ5IHtcblx0XHRyZXR1cm4gbmV3IHdpbmRvdy5YTUxIdHRwUmVxdWVzdCgpO1xuXHR9IGNhdGNoICggZSApIHt9XG59O1xuXG52YXIgeGhyU3VjY2Vzc1N0YXR1cyA9IHtcblxuXHRcdC8vIEZpbGUgcHJvdG9jb2wgYWx3YXlzIHlpZWxkcyBzdGF0dXMgY29kZSAwLCBhc3N1bWUgMjAwXG5cdFx0MDogMjAwLFxuXG5cdFx0Ly8gU3VwcG9ydDogSUUgPD05IG9ubHlcblx0XHQvLyAjMTQ1MDogc29tZXRpbWVzIElFIHJldHVybnMgMTIyMyB3aGVuIGl0IHNob3VsZCBiZSAyMDRcblx0XHQxMjIzOiAyMDRcblx0fSxcblx0eGhyU3VwcG9ydGVkID0galF1ZXJ5LmFqYXhTZXR0aW5ncy54aHIoKTtcblxuc3VwcG9ydC5jb3JzID0gISF4aHJTdXBwb3J0ZWQgJiYgKCBcIndpdGhDcmVkZW50aWFsc1wiIGluIHhoclN1cHBvcnRlZCApO1xuc3VwcG9ydC5hamF4ID0geGhyU3VwcG9ydGVkID0gISF4aHJTdXBwb3J0ZWQ7XG5cbmpRdWVyeS5hamF4VHJhbnNwb3J0KCBmdW5jdGlvbiggb3B0aW9ucyApIHtcblx0dmFyIGNhbGxiYWNrLCBlcnJvckNhbGxiYWNrO1xuXG5cdC8vIENyb3NzIGRvbWFpbiBvbmx5IGFsbG93ZWQgaWYgc3VwcG9ydGVkIHRocm91Z2ggWE1MSHR0cFJlcXVlc3Rcblx0aWYgKCBzdXBwb3J0LmNvcnMgfHwgeGhyU3VwcG9ydGVkICYmICFvcHRpb25zLmNyb3NzRG9tYWluICkge1xuXHRcdHJldHVybiB7XG5cdFx0XHRzZW5kOiBmdW5jdGlvbiggaGVhZGVycywgY29tcGxldGUgKSB7XG5cdFx0XHRcdHZhciBpLFxuXHRcdFx0XHRcdHhociA9IG9wdGlvbnMueGhyKCk7XG5cblx0XHRcdFx0eGhyLm9wZW4oXG5cdFx0XHRcdFx0b3B0aW9ucy50eXBlLFxuXHRcdFx0XHRcdG9wdGlvbnMudXJsLFxuXHRcdFx0XHRcdG9wdGlvbnMuYXN5bmMsXG5cdFx0XHRcdFx0b3B0aW9ucy51c2VybmFtZSxcblx0XHRcdFx0XHRvcHRpb25zLnBhc3N3b3JkXG5cdFx0XHRcdCk7XG5cblx0XHRcdFx0Ly8gQXBwbHkgY3VzdG9tIGZpZWxkcyBpZiBwcm92aWRlZFxuXHRcdFx0XHRpZiAoIG9wdGlvbnMueGhyRmllbGRzICkge1xuXHRcdFx0XHRcdGZvciAoIGkgaW4gb3B0aW9ucy54aHJGaWVsZHMgKSB7XG5cdFx0XHRcdFx0XHR4aHJbIGkgXSA9IG9wdGlvbnMueGhyRmllbGRzWyBpIF07XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gT3ZlcnJpZGUgbWltZSB0eXBlIGlmIG5lZWRlZFxuXHRcdFx0XHRpZiAoIG9wdGlvbnMubWltZVR5cGUgJiYgeGhyLm92ZXJyaWRlTWltZVR5cGUgKSB7XG5cdFx0XHRcdFx0eGhyLm92ZXJyaWRlTWltZVR5cGUoIG9wdGlvbnMubWltZVR5cGUgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIFgtUmVxdWVzdGVkLVdpdGggaGVhZGVyXG5cdFx0XHRcdC8vIEZvciBjcm9zcy1kb21haW4gcmVxdWVzdHMsIHNlZWluZyBhcyBjb25kaXRpb25zIGZvciBhIHByZWZsaWdodCBhcmVcblx0XHRcdFx0Ly8gYWtpbiB0byBhIGppZ3NhdyBwdXp6bGUsIHdlIHNpbXBseSBuZXZlciBzZXQgaXQgdG8gYmUgc3VyZS5cblx0XHRcdFx0Ly8gKGl0IGNhbiBhbHdheXMgYmUgc2V0IG9uIGEgcGVyLXJlcXVlc3QgYmFzaXMgb3IgZXZlbiB1c2luZyBhamF4U2V0dXApXG5cdFx0XHRcdC8vIEZvciBzYW1lLWRvbWFpbiByZXF1ZXN0cywgd29uJ3QgY2hhbmdlIGhlYWRlciBpZiBhbHJlYWR5IHByb3ZpZGVkLlxuXHRcdFx0XHRpZiAoICFvcHRpb25zLmNyb3NzRG9tYWluICYmICFoZWFkZXJzWyBcIlgtUmVxdWVzdGVkLVdpdGhcIiBdICkge1xuXHRcdFx0XHRcdGhlYWRlcnNbIFwiWC1SZXF1ZXN0ZWQtV2l0aFwiIF0gPSBcIlhNTEh0dHBSZXF1ZXN0XCI7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBTZXQgaGVhZGVyc1xuXHRcdFx0XHRmb3IgKCBpIGluIGhlYWRlcnMgKSB7XG5cdFx0XHRcdFx0eGhyLnNldFJlcXVlc3RIZWFkZXIoIGksIGhlYWRlcnNbIGkgXSApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gQ2FsbGJhY2tcblx0XHRcdFx0Y2FsbGJhY2sgPSBmdW5jdGlvbiggdHlwZSApIHtcblx0XHRcdFx0XHRyZXR1cm4gZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0XHRpZiAoIGNhbGxiYWNrICkge1xuXHRcdFx0XHRcdFx0XHRjYWxsYmFjayA9IGVycm9yQ2FsbGJhY2sgPSB4aHIub25sb2FkID1cblx0XHRcdFx0XHRcdFx0XHR4aHIub25lcnJvciA9IHhoci5vbmFib3J0ID0geGhyLm9udGltZW91dCA9XG5cdFx0XHRcdFx0XHRcdFx0XHR4aHIub25yZWFkeXN0YXRlY2hhbmdlID0gbnVsbDtcblxuXHRcdFx0XHRcdFx0XHRpZiAoIHR5cGUgPT09IFwiYWJvcnRcIiApIHtcblx0XHRcdFx0XHRcdFx0XHR4aHIuYWJvcnQoKTtcblx0XHRcdFx0XHRcdFx0fSBlbHNlIGlmICggdHlwZSA9PT0gXCJlcnJvclwiICkge1xuXG5cdFx0XHRcdFx0XHRcdFx0Ly8gU3VwcG9ydDogSUUgPD05IG9ubHlcblx0XHRcdFx0XHRcdFx0XHQvLyBPbiBhIG1hbnVhbCBuYXRpdmUgYWJvcnQsIElFOSB0aHJvd3Ncblx0XHRcdFx0XHRcdFx0XHQvLyBlcnJvcnMgb24gYW55IHByb3BlcnR5IGFjY2VzcyB0aGF0IGlzIG5vdCByZWFkeVN0YXRlXG5cdFx0XHRcdFx0XHRcdFx0aWYgKCB0eXBlb2YgeGhyLnN0YXR1cyAhPT0gXCJudW1iZXJcIiApIHtcblx0XHRcdFx0XHRcdFx0XHRcdGNvbXBsZXRlKCAwLCBcImVycm9yXCIgKTtcblx0XHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRcdFx0Y29tcGxldGUoXG5cblx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gRmlsZTogcHJvdG9jb2wgYWx3YXlzIHlpZWxkcyBzdGF0dXMgMDsgc2VlICM4NjA1LCAjMTQyMDdcblx0XHRcdFx0XHRcdFx0XHRcdFx0eGhyLnN0YXR1cyxcblx0XHRcdFx0XHRcdFx0XHRcdFx0eGhyLnN0YXR1c1RleHRcblx0XHRcdFx0XHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRcdGNvbXBsZXRlKFxuXHRcdFx0XHRcdFx0XHRcdFx0eGhyU3VjY2Vzc1N0YXR1c1sgeGhyLnN0YXR1cyBdIHx8IHhoci5zdGF0dXMsXG5cdFx0XHRcdFx0XHRcdFx0XHR4aHIuc3RhdHVzVGV4dCxcblxuXHRcdFx0XHRcdFx0XHRcdFx0Ly8gU3VwcG9ydDogSUUgPD05IG9ubHlcblx0XHRcdFx0XHRcdFx0XHRcdC8vIElFOSBoYXMgbm8gWEhSMiBidXQgdGhyb3dzIG9uIGJpbmFyeSAodHJhYy0xMTQyNilcblx0XHRcdFx0XHRcdFx0XHRcdC8vIEZvciBYSFIyIG5vbi10ZXh0LCBsZXQgdGhlIGNhbGxlciBoYW5kbGUgaXQgKGdoLTI0OTgpXG5cdFx0XHRcdFx0XHRcdFx0XHQoIHhoci5yZXNwb25zZVR5cGUgfHwgXCJ0ZXh0XCIgKSAhPT0gXCJ0ZXh0XCIgIHx8XG5cdFx0XHRcdFx0XHRcdFx0XHR0eXBlb2YgeGhyLnJlc3BvbnNlVGV4dCAhPT0gXCJzdHJpbmdcIiA/XG5cdFx0XHRcdFx0XHRcdFx0XHRcdHsgYmluYXJ5OiB4aHIucmVzcG9uc2UgfSA6XG5cdFx0XHRcdFx0XHRcdFx0XHRcdHsgdGV4dDogeGhyLnJlc3BvbnNlVGV4dCB9LFxuXHRcdFx0XHRcdFx0XHRcdFx0eGhyLmdldEFsbFJlc3BvbnNlSGVhZGVycygpXG5cdFx0XHRcdFx0XHRcdFx0KTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH07XG5cdFx0XHRcdH07XG5cblx0XHRcdFx0Ly8gTGlzdGVuIHRvIGV2ZW50c1xuXHRcdFx0XHR4aHIub25sb2FkID0gY2FsbGJhY2soKTtcblx0XHRcdFx0ZXJyb3JDYWxsYmFjayA9IHhoci5vbmVycm9yID0geGhyLm9udGltZW91dCA9IGNhbGxiYWNrKCBcImVycm9yXCIgKTtcblxuXHRcdFx0XHQvLyBTdXBwb3J0OiBJRSA5IG9ubHlcblx0XHRcdFx0Ly8gVXNlIG9ucmVhZHlzdGF0ZWNoYW5nZSB0byByZXBsYWNlIG9uYWJvcnRcblx0XHRcdFx0Ly8gdG8gaGFuZGxlIHVuY2F1Z2h0IGFib3J0c1xuXHRcdFx0XHRpZiAoIHhoci5vbmFib3J0ICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdFx0eGhyLm9uYWJvcnQgPSBlcnJvckNhbGxiYWNrO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHhoci5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBmdW5jdGlvbigpIHtcblxuXHRcdFx0XHRcdFx0Ly8gQ2hlY2sgcmVhZHlTdGF0ZSBiZWZvcmUgdGltZW91dCBhcyBpdCBjaGFuZ2VzXG5cdFx0XHRcdFx0XHRpZiAoIHhoci5yZWFkeVN0YXRlID09PSA0ICkge1xuXG5cdFx0XHRcdFx0XHRcdC8vIEFsbG93IG9uZXJyb3IgdG8gYmUgY2FsbGVkIGZpcnN0LFxuXHRcdFx0XHRcdFx0XHQvLyBidXQgdGhhdCB3aWxsIG5vdCBoYW5kbGUgYSBuYXRpdmUgYWJvcnRcblx0XHRcdFx0XHRcdFx0Ly8gQWxzbywgc2F2ZSBlcnJvckNhbGxiYWNrIHRvIGEgdmFyaWFibGVcblx0XHRcdFx0XHRcdFx0Ly8gYXMgeGhyLm9uZXJyb3IgY2Fubm90IGJlIGFjY2Vzc2VkXG5cdFx0XHRcdFx0XHRcdHdpbmRvdy5zZXRUaW1lb3V0KCBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdFx0XHRpZiAoIGNhbGxiYWNrICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0ZXJyb3JDYWxsYmFjaygpO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0fSApO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH07XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBDcmVhdGUgdGhlIGFib3J0IGNhbGxiYWNrXG5cdFx0XHRcdGNhbGxiYWNrID0gY2FsbGJhY2soIFwiYWJvcnRcIiApO1xuXG5cdFx0XHRcdHRyeSB7XG5cblx0XHRcdFx0XHQvLyBEbyBzZW5kIHRoZSByZXF1ZXN0ICh0aGlzIG1heSByYWlzZSBhbiBleGNlcHRpb24pXG5cdFx0XHRcdFx0eGhyLnNlbmQoIG9wdGlvbnMuaGFzQ29udGVudCAmJiBvcHRpb25zLmRhdGEgfHwgbnVsbCApO1xuXHRcdFx0XHR9IGNhdGNoICggZSApIHtcblxuXHRcdFx0XHRcdC8vICMxNDY4MzogT25seSByZXRocm93IGlmIHRoaXMgaGFzbid0IGJlZW4gbm90aWZpZWQgYXMgYW4gZXJyb3IgeWV0XG5cdFx0XHRcdFx0aWYgKCBjYWxsYmFjayApIHtcblx0XHRcdFx0XHRcdHRocm93IGU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9LFxuXG5cdFx0XHRhYm9ydDogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGlmICggY2FsbGJhY2sgKSB7XG5cdFx0XHRcdFx0Y2FsbGJhY2soKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH07XG5cdH1cbn0gKTtcblxuXG5cblxuLy8gUHJldmVudCBhdXRvLWV4ZWN1dGlvbiBvZiBzY3JpcHRzIHdoZW4gbm8gZXhwbGljaXQgZGF0YVR5cGUgd2FzIHByb3ZpZGVkIChTZWUgZ2gtMjQzMilcbmpRdWVyeS5hamF4UHJlZmlsdGVyKCBmdW5jdGlvbiggcyApIHtcblx0aWYgKCBzLmNyb3NzRG9tYWluICkge1xuXHRcdHMuY29udGVudHMuc2NyaXB0ID0gZmFsc2U7XG5cdH1cbn0gKTtcblxuLy8gSW5zdGFsbCBzY3JpcHQgZGF0YVR5cGVcbmpRdWVyeS5hamF4U2V0dXAoIHtcblx0YWNjZXB0czoge1xuXHRcdHNjcmlwdDogXCJ0ZXh0L2phdmFzY3JpcHQsIGFwcGxpY2F0aW9uL2phdmFzY3JpcHQsIFwiICtcblx0XHRcdFwiYXBwbGljYXRpb24vZWNtYXNjcmlwdCwgYXBwbGljYXRpb24veC1lY21hc2NyaXB0XCJcblx0fSxcblx0Y29udGVudHM6IHtcblx0XHRzY3JpcHQ6IC9cXGIoPzpqYXZhfGVjbWEpc2NyaXB0XFxiL1xuXHR9LFxuXHRjb252ZXJ0ZXJzOiB7XG5cdFx0XCJ0ZXh0IHNjcmlwdFwiOiBmdW5jdGlvbiggdGV4dCApIHtcblx0XHRcdGpRdWVyeS5nbG9iYWxFdmFsKCB0ZXh0ICk7XG5cdFx0XHRyZXR1cm4gdGV4dDtcblx0XHR9XG5cdH1cbn0gKTtcblxuLy8gSGFuZGxlIGNhY2hlJ3Mgc3BlY2lhbCBjYXNlIGFuZCBjcm9zc0RvbWFpblxualF1ZXJ5LmFqYXhQcmVmaWx0ZXIoIFwic2NyaXB0XCIsIGZ1bmN0aW9uKCBzICkge1xuXHRpZiAoIHMuY2FjaGUgPT09IHVuZGVmaW5lZCApIHtcblx0XHRzLmNhY2hlID0gZmFsc2U7XG5cdH1cblx0aWYgKCBzLmNyb3NzRG9tYWluICkge1xuXHRcdHMudHlwZSA9IFwiR0VUXCI7XG5cdH1cbn0gKTtcblxuLy8gQmluZCBzY3JpcHQgdGFnIGhhY2sgdHJhbnNwb3J0XG5qUXVlcnkuYWpheFRyYW5zcG9ydCggXCJzY3JpcHRcIiwgZnVuY3Rpb24oIHMgKSB7XG5cblx0Ly8gVGhpcyB0cmFuc3BvcnQgb25seSBkZWFscyB3aXRoIGNyb3NzIGRvbWFpbiBvciBmb3JjZWQtYnktYXR0cnMgcmVxdWVzdHNcblx0aWYgKCBzLmNyb3NzRG9tYWluIHx8IHMuc2NyaXB0QXR0cnMgKSB7XG5cdFx0dmFyIHNjcmlwdCwgY2FsbGJhY2s7XG5cdFx0cmV0dXJuIHtcblx0XHRcdHNlbmQ6IGZ1bmN0aW9uKCBfLCBjb21wbGV0ZSApIHtcblx0XHRcdFx0c2NyaXB0ID0galF1ZXJ5KCBcIjxzY3JpcHQ+XCIgKVxuXHRcdFx0XHRcdC5hdHRyKCBzLnNjcmlwdEF0dHJzIHx8IHt9IClcblx0XHRcdFx0XHQucHJvcCggeyBjaGFyc2V0OiBzLnNjcmlwdENoYXJzZXQsIHNyYzogcy51cmwgfSApXG5cdFx0XHRcdFx0Lm9uKCBcImxvYWQgZXJyb3JcIiwgY2FsbGJhY2sgPSBmdW5jdGlvbiggZXZ0ICkge1xuXHRcdFx0XHRcdFx0c2NyaXB0LnJlbW92ZSgpO1xuXHRcdFx0XHRcdFx0Y2FsbGJhY2sgPSBudWxsO1xuXHRcdFx0XHRcdFx0aWYgKCBldnQgKSB7XG5cdFx0XHRcdFx0XHRcdGNvbXBsZXRlKCBldnQudHlwZSA9PT0gXCJlcnJvclwiID8gNDA0IDogMjAwLCBldnQudHlwZSApO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0gKTtcblxuXHRcdFx0XHQvLyBVc2UgbmF0aXZlIERPTSBtYW5pcHVsYXRpb24gdG8gYXZvaWQgb3VyIGRvbU1hbmlwIEFKQVggdHJpY2tlcnlcblx0XHRcdFx0ZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZCggc2NyaXB0WyAwIF0gKTtcblx0XHRcdH0sXG5cdFx0XHRhYm9ydDogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGlmICggY2FsbGJhY2sgKSB7XG5cdFx0XHRcdFx0Y2FsbGJhY2soKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH07XG5cdH1cbn0gKTtcblxuXG5cblxudmFyIG9sZENhbGxiYWNrcyA9IFtdLFxuXHRyanNvbnAgPSAvKD0pXFw/KD89JnwkKXxcXD9cXD8vO1xuXG4vLyBEZWZhdWx0IGpzb25wIHNldHRpbmdzXG5qUXVlcnkuYWpheFNldHVwKCB7XG5cdGpzb25wOiBcImNhbGxiYWNrXCIsXG5cdGpzb25wQ2FsbGJhY2s6IGZ1bmN0aW9uKCkge1xuXHRcdHZhciBjYWxsYmFjayA9IG9sZENhbGxiYWNrcy5wb3AoKSB8fCAoIGpRdWVyeS5leHBhbmRvICsgXCJfXCIgKyAoIG5vbmNlLmd1aWQrKyApICk7XG5cdFx0dGhpc1sgY2FsbGJhY2sgXSA9IHRydWU7XG5cdFx0cmV0dXJuIGNhbGxiYWNrO1xuXHR9XG59ICk7XG5cbi8vIERldGVjdCwgbm9ybWFsaXplIG9wdGlvbnMgYW5kIGluc3RhbGwgY2FsbGJhY2tzIGZvciBqc29ucCByZXF1ZXN0c1xualF1ZXJ5LmFqYXhQcmVmaWx0ZXIoIFwianNvbiBqc29ucFwiLCBmdW5jdGlvbiggcywgb3JpZ2luYWxTZXR0aW5ncywganFYSFIgKSB7XG5cblx0dmFyIGNhbGxiYWNrTmFtZSwgb3ZlcndyaXR0ZW4sIHJlc3BvbnNlQ29udGFpbmVyLFxuXHRcdGpzb25Qcm9wID0gcy5qc29ucCAhPT0gZmFsc2UgJiYgKCByanNvbnAudGVzdCggcy51cmwgKSA/XG5cdFx0XHRcInVybFwiIDpcblx0XHRcdHR5cGVvZiBzLmRhdGEgPT09IFwic3RyaW5nXCIgJiZcblx0XHRcdFx0KCBzLmNvbnRlbnRUeXBlIHx8IFwiXCIgKVxuXHRcdFx0XHRcdC5pbmRleE9mKCBcImFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZFwiICkgPT09IDAgJiZcblx0XHRcdFx0cmpzb25wLnRlc3QoIHMuZGF0YSApICYmIFwiZGF0YVwiXG5cdFx0KTtcblxuXHQvLyBIYW5kbGUgaWZmIHRoZSBleHBlY3RlZCBkYXRhIHR5cGUgaXMgXCJqc29ucFwiIG9yIHdlIGhhdmUgYSBwYXJhbWV0ZXIgdG8gc2V0XG5cdGlmICgganNvblByb3AgfHwgcy5kYXRhVHlwZXNbIDAgXSA9PT0gXCJqc29ucFwiICkge1xuXG5cdFx0Ly8gR2V0IGNhbGxiYWNrIG5hbWUsIHJlbWVtYmVyaW5nIHByZWV4aXN0aW5nIHZhbHVlIGFzc29jaWF0ZWQgd2l0aCBpdFxuXHRcdGNhbGxiYWNrTmFtZSA9IHMuanNvbnBDYWxsYmFjayA9IGlzRnVuY3Rpb24oIHMuanNvbnBDYWxsYmFjayApID9cblx0XHRcdHMuanNvbnBDYWxsYmFjaygpIDpcblx0XHRcdHMuanNvbnBDYWxsYmFjaztcblxuXHRcdC8vIEluc2VydCBjYWxsYmFjayBpbnRvIHVybCBvciBmb3JtIGRhdGFcblx0XHRpZiAoIGpzb25Qcm9wICkge1xuXHRcdFx0c1sganNvblByb3AgXSA9IHNbIGpzb25Qcm9wIF0ucmVwbGFjZSggcmpzb25wLCBcIiQxXCIgKyBjYWxsYmFja05hbWUgKTtcblx0XHR9IGVsc2UgaWYgKCBzLmpzb25wICE9PSBmYWxzZSApIHtcblx0XHRcdHMudXJsICs9ICggcnF1ZXJ5LnRlc3QoIHMudXJsICkgPyBcIiZcIiA6IFwiP1wiICkgKyBzLmpzb25wICsgXCI9XCIgKyBjYWxsYmFja05hbWU7XG5cdFx0fVxuXG5cdFx0Ly8gVXNlIGRhdGEgY29udmVydGVyIHRvIHJldHJpZXZlIGpzb24gYWZ0ZXIgc2NyaXB0IGV4ZWN1dGlvblxuXHRcdHMuY29udmVydGVyc1sgXCJzY3JpcHQganNvblwiIF0gPSBmdW5jdGlvbigpIHtcblx0XHRcdGlmICggIXJlc3BvbnNlQ29udGFpbmVyICkge1xuXHRcdFx0XHRqUXVlcnkuZXJyb3IoIGNhbGxiYWNrTmFtZSArIFwiIHdhcyBub3QgY2FsbGVkXCIgKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiByZXNwb25zZUNvbnRhaW5lclsgMCBdO1xuXHRcdH07XG5cblx0XHQvLyBGb3JjZSBqc29uIGRhdGFUeXBlXG5cdFx0cy5kYXRhVHlwZXNbIDAgXSA9IFwianNvblwiO1xuXG5cdFx0Ly8gSW5zdGFsbCBjYWxsYmFja1xuXHRcdG92ZXJ3cml0dGVuID0gd2luZG93WyBjYWxsYmFja05hbWUgXTtcblx0XHR3aW5kb3dbIGNhbGxiYWNrTmFtZSBdID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRyZXNwb25zZUNvbnRhaW5lciA9IGFyZ3VtZW50cztcblx0XHR9O1xuXG5cdFx0Ly8gQ2xlYW4tdXAgZnVuY3Rpb24gKGZpcmVzIGFmdGVyIGNvbnZlcnRlcnMpXG5cdFx0anFYSFIuYWx3YXlzKCBmdW5jdGlvbigpIHtcblxuXHRcdFx0Ly8gSWYgcHJldmlvdXMgdmFsdWUgZGlkbid0IGV4aXN0IC0gcmVtb3ZlIGl0XG5cdFx0XHRpZiAoIG92ZXJ3cml0dGVuID09PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdGpRdWVyeSggd2luZG93ICkucmVtb3ZlUHJvcCggY2FsbGJhY2tOYW1lICk7XG5cblx0XHRcdC8vIE90aGVyd2lzZSByZXN0b3JlIHByZWV4aXN0aW5nIHZhbHVlXG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR3aW5kb3dbIGNhbGxiYWNrTmFtZSBdID0gb3ZlcndyaXR0ZW47XG5cdFx0XHR9XG5cblx0XHRcdC8vIFNhdmUgYmFjayBhcyBmcmVlXG5cdFx0XHRpZiAoIHNbIGNhbGxiYWNrTmFtZSBdICkge1xuXG5cdFx0XHRcdC8vIE1ha2Ugc3VyZSB0aGF0IHJlLXVzaW5nIHRoZSBvcHRpb25zIGRvZXNuJ3Qgc2NyZXcgdGhpbmdzIGFyb3VuZFxuXHRcdFx0XHRzLmpzb25wQ2FsbGJhY2sgPSBvcmlnaW5hbFNldHRpbmdzLmpzb25wQ2FsbGJhY2s7XG5cblx0XHRcdFx0Ly8gU2F2ZSB0aGUgY2FsbGJhY2sgbmFtZSBmb3IgZnV0dXJlIHVzZVxuXHRcdFx0XHRvbGRDYWxsYmFja3MucHVzaCggY2FsbGJhY2tOYW1lICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIENhbGwgaWYgaXQgd2FzIGEgZnVuY3Rpb24gYW5kIHdlIGhhdmUgYSByZXNwb25zZVxuXHRcdFx0aWYgKCByZXNwb25zZUNvbnRhaW5lciAmJiBpc0Z1bmN0aW9uKCBvdmVyd3JpdHRlbiApICkge1xuXHRcdFx0XHRvdmVyd3JpdHRlbiggcmVzcG9uc2VDb250YWluZXJbIDAgXSApO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXNwb25zZUNvbnRhaW5lciA9IG92ZXJ3cml0dGVuID0gdW5kZWZpbmVkO1xuXHRcdH0gKTtcblxuXHRcdC8vIERlbGVnYXRlIHRvIHNjcmlwdFxuXHRcdHJldHVybiBcInNjcmlwdFwiO1xuXHR9XG59ICk7XG5cblxuXG5cbi8vIFN1cHBvcnQ6IFNhZmFyaSA4IG9ubHlcbi8vIEluIFNhZmFyaSA4IGRvY3VtZW50cyBjcmVhdGVkIHZpYSBkb2N1bWVudC5pbXBsZW1lbnRhdGlvbi5jcmVhdGVIVE1MRG9jdW1lbnRcbi8vIGNvbGxhcHNlIHNpYmxpbmcgZm9ybXM6IHRoZSBzZWNvbmQgb25lIGJlY29tZXMgYSBjaGlsZCBvZiB0aGUgZmlyc3Qgb25lLlxuLy8gQmVjYXVzZSBvZiB0aGF0LCB0aGlzIHNlY3VyaXR5IG1lYXN1cmUgaGFzIHRvIGJlIGRpc2FibGVkIGluIFNhZmFyaSA4LlxuLy8gaHR0cHM6Ly9idWdzLndlYmtpdC5vcmcvc2hvd19idWcuY2dpP2lkPTEzNzMzN1xuc3VwcG9ydC5jcmVhdGVIVE1MRG9jdW1lbnQgPSAoIGZ1bmN0aW9uKCkge1xuXHR2YXIgYm9keSA9IGRvY3VtZW50LmltcGxlbWVudGF0aW9uLmNyZWF0ZUhUTUxEb2N1bWVudCggXCJcIiApLmJvZHk7XG5cdGJvZHkuaW5uZXJIVE1MID0gXCI8Zm9ybT48L2Zvcm0+PGZvcm0+PC9mb3JtPlwiO1xuXHRyZXR1cm4gYm9keS5jaGlsZE5vZGVzLmxlbmd0aCA9PT0gMjtcbn0gKSgpO1xuXG5cbi8vIEFyZ3VtZW50IFwiZGF0YVwiIHNob3VsZCBiZSBzdHJpbmcgb2YgaHRtbFxuLy8gY29udGV4dCAob3B0aW9uYWwpOiBJZiBzcGVjaWZpZWQsIHRoZSBmcmFnbWVudCB3aWxsIGJlIGNyZWF0ZWQgaW4gdGhpcyBjb250ZXh0LFxuLy8gZGVmYXVsdHMgdG8gZG9jdW1lbnRcbi8vIGtlZXBTY3JpcHRzIChvcHRpb25hbCk6IElmIHRydWUsIHdpbGwgaW5jbHVkZSBzY3JpcHRzIHBhc3NlZCBpbiB0aGUgaHRtbCBzdHJpbmdcbmpRdWVyeS5wYXJzZUhUTUwgPSBmdW5jdGlvbiggZGF0YSwgY29udGV4dCwga2VlcFNjcmlwdHMgKSB7XG5cdGlmICggdHlwZW9mIGRhdGEgIT09IFwic3RyaW5nXCIgKSB7XG5cdFx0cmV0dXJuIFtdO1xuXHR9XG5cdGlmICggdHlwZW9mIGNvbnRleHQgPT09IFwiYm9vbGVhblwiICkge1xuXHRcdGtlZXBTY3JpcHRzID0gY29udGV4dDtcblx0XHRjb250ZXh0ID0gZmFsc2U7XG5cdH1cblxuXHR2YXIgYmFzZSwgcGFyc2VkLCBzY3JpcHRzO1xuXG5cdGlmICggIWNvbnRleHQgKSB7XG5cblx0XHQvLyBTdG9wIHNjcmlwdHMgb3IgaW5saW5lIGV2ZW50IGhhbmRsZXJzIGZyb20gYmVpbmcgZXhlY3V0ZWQgaW1tZWRpYXRlbHlcblx0XHQvLyBieSB1c2luZyBkb2N1bWVudC5pbXBsZW1lbnRhdGlvblxuXHRcdGlmICggc3VwcG9ydC5jcmVhdGVIVE1MRG9jdW1lbnQgKSB7XG5cdFx0XHRjb250ZXh0ID0gZG9jdW1lbnQuaW1wbGVtZW50YXRpb24uY3JlYXRlSFRNTERvY3VtZW50KCBcIlwiICk7XG5cblx0XHRcdC8vIFNldCB0aGUgYmFzZSBocmVmIGZvciB0aGUgY3JlYXRlZCBkb2N1bWVudFxuXHRcdFx0Ly8gc28gYW55IHBhcnNlZCBlbGVtZW50cyB3aXRoIFVSTHNcblx0XHRcdC8vIGFyZSBiYXNlZCBvbiB0aGUgZG9jdW1lbnQncyBVUkwgKGdoLTI5NjUpXG5cdFx0XHRiYXNlID0gY29udGV4dC5jcmVhdGVFbGVtZW50KCBcImJhc2VcIiApO1xuXHRcdFx0YmFzZS5ocmVmID0gZG9jdW1lbnQubG9jYXRpb24uaHJlZjtcblx0XHRcdGNvbnRleHQuaGVhZC5hcHBlbmRDaGlsZCggYmFzZSApO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRjb250ZXh0ID0gZG9jdW1lbnQ7XG5cdFx0fVxuXHR9XG5cblx0cGFyc2VkID0gcnNpbmdsZVRhZy5leGVjKCBkYXRhICk7XG5cdHNjcmlwdHMgPSAha2VlcFNjcmlwdHMgJiYgW107XG5cblx0Ly8gU2luZ2xlIHRhZ1xuXHRpZiAoIHBhcnNlZCApIHtcblx0XHRyZXR1cm4gWyBjb250ZXh0LmNyZWF0ZUVsZW1lbnQoIHBhcnNlZFsgMSBdICkgXTtcblx0fVxuXG5cdHBhcnNlZCA9IGJ1aWxkRnJhZ21lbnQoIFsgZGF0YSBdLCBjb250ZXh0LCBzY3JpcHRzICk7XG5cblx0aWYgKCBzY3JpcHRzICYmIHNjcmlwdHMubGVuZ3RoICkge1xuXHRcdGpRdWVyeSggc2NyaXB0cyApLnJlbW92ZSgpO1xuXHR9XG5cblx0cmV0dXJuIGpRdWVyeS5tZXJnZSggW10sIHBhcnNlZC5jaGlsZE5vZGVzICk7XG59O1xuXG5cbi8qKlxuICogTG9hZCBhIHVybCBpbnRvIGEgcGFnZVxuICovXG5qUXVlcnkuZm4ubG9hZCA9IGZ1bmN0aW9uKCB1cmwsIHBhcmFtcywgY2FsbGJhY2sgKSB7XG5cdHZhciBzZWxlY3RvciwgdHlwZSwgcmVzcG9uc2UsXG5cdFx0c2VsZiA9IHRoaXMsXG5cdFx0b2ZmID0gdXJsLmluZGV4T2YoIFwiIFwiICk7XG5cblx0aWYgKCBvZmYgPiAtMSApIHtcblx0XHRzZWxlY3RvciA9IHN0cmlwQW5kQ29sbGFwc2UoIHVybC5zbGljZSggb2ZmICkgKTtcblx0XHR1cmwgPSB1cmwuc2xpY2UoIDAsIG9mZiApO1xuXHR9XG5cblx0Ly8gSWYgaXQncyBhIGZ1bmN0aW9uXG5cdGlmICggaXNGdW5jdGlvbiggcGFyYW1zICkgKSB7XG5cblx0XHQvLyBXZSBhc3N1bWUgdGhhdCBpdCdzIHRoZSBjYWxsYmFja1xuXHRcdGNhbGxiYWNrID0gcGFyYW1zO1xuXHRcdHBhcmFtcyA9IHVuZGVmaW5lZDtcblxuXHQvLyBPdGhlcndpc2UsIGJ1aWxkIGEgcGFyYW0gc3RyaW5nXG5cdH0gZWxzZSBpZiAoIHBhcmFtcyAmJiB0eXBlb2YgcGFyYW1zID09PSBcIm9iamVjdFwiICkge1xuXHRcdHR5cGUgPSBcIlBPU1RcIjtcblx0fVxuXG5cdC8vIElmIHdlIGhhdmUgZWxlbWVudHMgdG8gbW9kaWZ5LCBtYWtlIHRoZSByZXF1ZXN0XG5cdGlmICggc2VsZi5sZW5ndGggPiAwICkge1xuXHRcdGpRdWVyeS5hamF4KCB7XG5cdFx0XHR1cmw6IHVybCxcblxuXHRcdFx0Ly8gSWYgXCJ0eXBlXCIgdmFyaWFibGUgaXMgdW5kZWZpbmVkLCB0aGVuIFwiR0VUXCIgbWV0aG9kIHdpbGwgYmUgdXNlZC5cblx0XHRcdC8vIE1ha2UgdmFsdWUgb2YgdGhpcyBmaWVsZCBleHBsaWNpdCBzaW5jZVxuXHRcdFx0Ly8gdXNlciBjYW4gb3ZlcnJpZGUgaXQgdGhyb3VnaCBhamF4U2V0dXAgbWV0aG9kXG5cdFx0XHR0eXBlOiB0eXBlIHx8IFwiR0VUXCIsXG5cdFx0XHRkYXRhVHlwZTogXCJodG1sXCIsXG5cdFx0XHRkYXRhOiBwYXJhbXNcblx0XHR9ICkuZG9uZSggZnVuY3Rpb24oIHJlc3BvbnNlVGV4dCApIHtcblxuXHRcdFx0Ly8gU2F2ZSByZXNwb25zZSBmb3IgdXNlIGluIGNvbXBsZXRlIGNhbGxiYWNrXG5cdFx0XHRyZXNwb25zZSA9IGFyZ3VtZW50cztcblxuXHRcdFx0c2VsZi5odG1sKCBzZWxlY3RvciA/XG5cblx0XHRcdFx0Ly8gSWYgYSBzZWxlY3RvciB3YXMgc3BlY2lmaWVkLCBsb2NhdGUgdGhlIHJpZ2h0IGVsZW1lbnRzIGluIGEgZHVtbXkgZGl2XG5cdFx0XHRcdC8vIEV4Y2x1ZGUgc2NyaXB0cyB0byBhdm9pZCBJRSAnUGVybWlzc2lvbiBEZW5pZWQnIGVycm9yc1xuXHRcdFx0XHRqUXVlcnkoIFwiPGRpdj5cIiApLmFwcGVuZCggalF1ZXJ5LnBhcnNlSFRNTCggcmVzcG9uc2VUZXh0ICkgKS5maW5kKCBzZWxlY3RvciApIDpcblxuXHRcdFx0XHQvLyBPdGhlcndpc2UgdXNlIHRoZSBmdWxsIHJlc3VsdFxuXHRcdFx0XHRyZXNwb25zZVRleHQgKTtcblxuXHRcdC8vIElmIHRoZSByZXF1ZXN0IHN1Y2NlZWRzLCB0aGlzIGZ1bmN0aW9uIGdldHMgXCJkYXRhXCIsIFwic3RhdHVzXCIsIFwianFYSFJcIlxuXHRcdC8vIGJ1dCB0aGV5IGFyZSBpZ25vcmVkIGJlY2F1c2UgcmVzcG9uc2Ugd2FzIHNldCBhYm92ZS5cblx0XHQvLyBJZiBpdCBmYWlscywgdGhpcyBmdW5jdGlvbiBnZXRzIFwianFYSFJcIiwgXCJzdGF0dXNcIiwgXCJlcnJvclwiXG5cdFx0fSApLmFsd2F5cyggY2FsbGJhY2sgJiYgZnVuY3Rpb24oIGpxWEhSLCBzdGF0dXMgKSB7XG5cdFx0XHRzZWxmLmVhY2goIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRjYWxsYmFjay5hcHBseSggdGhpcywgcmVzcG9uc2UgfHwgWyBqcVhIUi5yZXNwb25zZVRleHQsIHN0YXR1cywganFYSFIgXSApO1xuXHRcdFx0fSApO1xuXHRcdH0gKTtcblx0fVxuXG5cdHJldHVybiB0aGlzO1xufTtcblxuXG5cblxualF1ZXJ5LmV4cHIucHNldWRvcy5hbmltYXRlZCA9IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRyZXR1cm4galF1ZXJ5LmdyZXAoIGpRdWVyeS50aW1lcnMsIGZ1bmN0aW9uKCBmbiApIHtcblx0XHRyZXR1cm4gZWxlbSA9PT0gZm4uZWxlbTtcblx0fSApLmxlbmd0aDtcbn07XG5cblxuXG5cbmpRdWVyeS5vZmZzZXQgPSB7XG5cdHNldE9mZnNldDogZnVuY3Rpb24oIGVsZW0sIG9wdGlvbnMsIGkgKSB7XG5cdFx0dmFyIGN1clBvc2l0aW9uLCBjdXJMZWZ0LCBjdXJDU1NUb3AsIGN1clRvcCwgY3VyT2Zmc2V0LCBjdXJDU1NMZWZ0LCBjYWxjdWxhdGVQb3NpdGlvbixcblx0XHRcdHBvc2l0aW9uID0galF1ZXJ5LmNzcyggZWxlbSwgXCJwb3NpdGlvblwiICksXG5cdFx0XHRjdXJFbGVtID0galF1ZXJ5KCBlbGVtICksXG5cdFx0XHRwcm9wcyA9IHt9O1xuXG5cdFx0Ly8gU2V0IHBvc2l0aW9uIGZpcnN0LCBpbi1jYXNlIHRvcC9sZWZ0IGFyZSBzZXQgZXZlbiBvbiBzdGF0aWMgZWxlbVxuXHRcdGlmICggcG9zaXRpb24gPT09IFwic3RhdGljXCIgKSB7XG5cdFx0XHRlbGVtLnN0eWxlLnBvc2l0aW9uID0gXCJyZWxhdGl2ZVwiO1xuXHRcdH1cblxuXHRcdGN1ck9mZnNldCA9IGN1ckVsZW0ub2Zmc2V0KCk7XG5cdFx0Y3VyQ1NTVG9wID0galF1ZXJ5LmNzcyggZWxlbSwgXCJ0b3BcIiApO1xuXHRcdGN1ckNTU0xlZnQgPSBqUXVlcnkuY3NzKCBlbGVtLCBcImxlZnRcIiApO1xuXHRcdGNhbGN1bGF0ZVBvc2l0aW9uID0gKCBwb3NpdGlvbiA9PT0gXCJhYnNvbHV0ZVwiIHx8IHBvc2l0aW9uID09PSBcImZpeGVkXCIgKSAmJlxuXHRcdFx0KCBjdXJDU1NUb3AgKyBjdXJDU1NMZWZ0ICkuaW5kZXhPZiggXCJhdXRvXCIgKSA+IC0xO1xuXG5cdFx0Ly8gTmVlZCB0byBiZSBhYmxlIHRvIGNhbGN1bGF0ZSBwb3NpdGlvbiBpZiBlaXRoZXJcblx0XHQvLyB0b3Agb3IgbGVmdCBpcyBhdXRvIGFuZCBwb3NpdGlvbiBpcyBlaXRoZXIgYWJzb2x1dGUgb3IgZml4ZWRcblx0XHRpZiAoIGNhbGN1bGF0ZVBvc2l0aW9uICkge1xuXHRcdFx0Y3VyUG9zaXRpb24gPSBjdXJFbGVtLnBvc2l0aW9uKCk7XG5cdFx0XHRjdXJUb3AgPSBjdXJQb3NpdGlvbi50b3A7XG5cdFx0XHRjdXJMZWZ0ID0gY3VyUG9zaXRpb24ubGVmdDtcblxuXHRcdH0gZWxzZSB7XG5cdFx0XHRjdXJUb3AgPSBwYXJzZUZsb2F0KCBjdXJDU1NUb3AgKSB8fCAwO1xuXHRcdFx0Y3VyTGVmdCA9IHBhcnNlRmxvYXQoIGN1ckNTU0xlZnQgKSB8fCAwO1xuXHRcdH1cblxuXHRcdGlmICggaXNGdW5jdGlvbiggb3B0aW9ucyApICkge1xuXG5cdFx0XHQvLyBVc2UgalF1ZXJ5LmV4dGVuZCBoZXJlIHRvIGFsbG93IG1vZGlmaWNhdGlvbiBvZiBjb29yZGluYXRlcyBhcmd1bWVudCAoZ2gtMTg0OClcblx0XHRcdG9wdGlvbnMgPSBvcHRpb25zLmNhbGwoIGVsZW0sIGksIGpRdWVyeS5leHRlbmQoIHt9LCBjdXJPZmZzZXQgKSApO1xuXHRcdH1cblxuXHRcdGlmICggb3B0aW9ucy50b3AgIT0gbnVsbCApIHtcblx0XHRcdHByb3BzLnRvcCA9ICggb3B0aW9ucy50b3AgLSBjdXJPZmZzZXQudG9wICkgKyBjdXJUb3A7XG5cdFx0fVxuXHRcdGlmICggb3B0aW9ucy5sZWZ0ICE9IG51bGwgKSB7XG5cdFx0XHRwcm9wcy5sZWZ0ID0gKCBvcHRpb25zLmxlZnQgLSBjdXJPZmZzZXQubGVmdCApICsgY3VyTGVmdDtcblx0XHR9XG5cblx0XHRpZiAoIFwidXNpbmdcIiBpbiBvcHRpb25zICkge1xuXHRcdFx0b3B0aW9ucy51c2luZy5jYWxsKCBlbGVtLCBwcm9wcyApO1xuXG5cdFx0fSBlbHNlIHtcblx0XHRcdGN1ckVsZW0uY3NzKCBwcm9wcyApO1xuXHRcdH1cblx0fVxufTtcblxualF1ZXJ5LmZuLmV4dGVuZCgge1xuXG5cdC8vIG9mZnNldCgpIHJlbGF0ZXMgYW4gZWxlbWVudCdzIGJvcmRlciBib3ggdG8gdGhlIGRvY3VtZW50IG9yaWdpblxuXHRvZmZzZXQ6IGZ1bmN0aW9uKCBvcHRpb25zICkge1xuXG5cdFx0Ly8gUHJlc2VydmUgY2hhaW5pbmcgZm9yIHNldHRlclxuXHRcdGlmICggYXJndW1lbnRzLmxlbmd0aCApIHtcblx0XHRcdHJldHVybiBvcHRpb25zID09PSB1bmRlZmluZWQgP1xuXHRcdFx0XHR0aGlzIDpcblx0XHRcdFx0dGhpcy5lYWNoKCBmdW5jdGlvbiggaSApIHtcblx0XHRcdFx0XHRqUXVlcnkub2Zmc2V0LnNldE9mZnNldCggdGhpcywgb3B0aW9ucywgaSApO1xuXHRcdFx0XHR9ICk7XG5cdFx0fVxuXG5cdFx0dmFyIHJlY3QsIHdpbixcblx0XHRcdGVsZW0gPSB0aGlzWyAwIF07XG5cblx0XHRpZiAoICFlbGVtICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIFJldHVybiB6ZXJvcyBmb3IgZGlzY29ubmVjdGVkIGFuZCBoaWRkZW4gKGRpc3BsYXk6IG5vbmUpIGVsZW1lbnRzIChnaC0yMzEwKVxuXHRcdC8vIFN1cHBvcnQ6IElFIDw9MTEgb25seVxuXHRcdC8vIFJ1bm5pbmcgZ2V0Qm91bmRpbmdDbGllbnRSZWN0IG9uIGFcblx0XHQvLyBkaXNjb25uZWN0ZWQgbm9kZSBpbiBJRSB0aHJvd3MgYW4gZXJyb3Jcblx0XHRpZiAoICFlbGVtLmdldENsaWVudFJlY3RzKCkubGVuZ3RoICkge1xuXHRcdFx0cmV0dXJuIHsgdG9wOiAwLCBsZWZ0OiAwIH07XG5cdFx0fVxuXG5cdFx0Ly8gR2V0IGRvY3VtZW50LXJlbGF0aXZlIHBvc2l0aW9uIGJ5IGFkZGluZyB2aWV3cG9ydCBzY3JvbGwgdG8gdmlld3BvcnQtcmVsYXRpdmUgZ0JDUlxuXHRcdHJlY3QgPSBlbGVtLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXHRcdHdpbiA9IGVsZW0ub3duZXJEb2N1bWVudC5kZWZhdWx0Vmlldztcblx0XHRyZXR1cm4ge1xuXHRcdFx0dG9wOiByZWN0LnRvcCArIHdpbi5wYWdlWU9mZnNldCxcblx0XHRcdGxlZnQ6IHJlY3QubGVmdCArIHdpbi5wYWdlWE9mZnNldFxuXHRcdH07XG5cdH0sXG5cblx0Ly8gcG9zaXRpb24oKSByZWxhdGVzIGFuIGVsZW1lbnQncyBtYXJnaW4gYm94IHRvIGl0cyBvZmZzZXQgcGFyZW50J3MgcGFkZGluZyBib3hcblx0Ly8gVGhpcyBjb3JyZXNwb25kcyB0byB0aGUgYmVoYXZpb3Igb2YgQ1NTIGFic29sdXRlIHBvc2l0aW9uaW5nXG5cdHBvc2l0aW9uOiBmdW5jdGlvbigpIHtcblx0XHRpZiAoICF0aGlzWyAwIF0gKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0dmFyIG9mZnNldFBhcmVudCwgb2Zmc2V0LCBkb2MsXG5cdFx0XHRlbGVtID0gdGhpc1sgMCBdLFxuXHRcdFx0cGFyZW50T2Zmc2V0ID0geyB0b3A6IDAsIGxlZnQ6IDAgfTtcblxuXHRcdC8vIHBvc2l0aW9uOmZpeGVkIGVsZW1lbnRzIGFyZSBvZmZzZXQgZnJvbSB0aGUgdmlld3BvcnQsIHdoaWNoIGl0c2VsZiBhbHdheXMgaGFzIHplcm8gb2Zmc2V0XG5cdFx0aWYgKCBqUXVlcnkuY3NzKCBlbGVtLCBcInBvc2l0aW9uXCIgKSA9PT0gXCJmaXhlZFwiICkge1xuXG5cdFx0XHQvLyBBc3N1bWUgcG9zaXRpb246Zml4ZWQgaW1wbGllcyBhdmFpbGFiaWxpdHkgb2YgZ2V0Qm91bmRpbmdDbGllbnRSZWN0XG5cdFx0XHRvZmZzZXQgPSBlbGVtLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXG5cdFx0fSBlbHNlIHtcblx0XHRcdG9mZnNldCA9IHRoaXMub2Zmc2V0KCk7XG5cblx0XHRcdC8vIEFjY291bnQgZm9yIHRoZSAqcmVhbCogb2Zmc2V0IHBhcmVudCwgd2hpY2ggY2FuIGJlIHRoZSBkb2N1bWVudCBvciBpdHMgcm9vdCBlbGVtZW50XG5cdFx0XHQvLyB3aGVuIGEgc3RhdGljYWxseSBwb3NpdGlvbmVkIGVsZW1lbnQgaXMgaWRlbnRpZmllZFxuXHRcdFx0ZG9jID0gZWxlbS5vd25lckRvY3VtZW50O1xuXHRcdFx0b2Zmc2V0UGFyZW50ID0gZWxlbS5vZmZzZXRQYXJlbnQgfHwgZG9jLmRvY3VtZW50RWxlbWVudDtcblx0XHRcdHdoaWxlICggb2Zmc2V0UGFyZW50ICYmXG5cdFx0XHRcdCggb2Zmc2V0UGFyZW50ID09PSBkb2MuYm9keSB8fCBvZmZzZXRQYXJlbnQgPT09IGRvYy5kb2N1bWVudEVsZW1lbnQgKSAmJlxuXHRcdFx0XHRqUXVlcnkuY3NzKCBvZmZzZXRQYXJlbnQsIFwicG9zaXRpb25cIiApID09PSBcInN0YXRpY1wiICkge1xuXG5cdFx0XHRcdG9mZnNldFBhcmVudCA9IG9mZnNldFBhcmVudC5wYXJlbnROb2RlO1xuXHRcdFx0fVxuXHRcdFx0aWYgKCBvZmZzZXRQYXJlbnQgJiYgb2Zmc2V0UGFyZW50ICE9PSBlbGVtICYmIG9mZnNldFBhcmVudC5ub2RlVHlwZSA9PT0gMSApIHtcblxuXHRcdFx0XHQvLyBJbmNvcnBvcmF0ZSBib3JkZXJzIGludG8gaXRzIG9mZnNldCwgc2luY2UgdGhleSBhcmUgb3V0c2lkZSBpdHMgY29udGVudCBvcmlnaW5cblx0XHRcdFx0cGFyZW50T2Zmc2V0ID0galF1ZXJ5KCBvZmZzZXRQYXJlbnQgKS5vZmZzZXQoKTtcblx0XHRcdFx0cGFyZW50T2Zmc2V0LnRvcCArPSBqUXVlcnkuY3NzKCBvZmZzZXRQYXJlbnQsIFwiYm9yZGVyVG9wV2lkdGhcIiwgdHJ1ZSApO1xuXHRcdFx0XHRwYXJlbnRPZmZzZXQubGVmdCArPSBqUXVlcnkuY3NzKCBvZmZzZXRQYXJlbnQsIFwiYm9yZGVyTGVmdFdpZHRoXCIsIHRydWUgKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBTdWJ0cmFjdCBwYXJlbnQgb2Zmc2V0cyBhbmQgZWxlbWVudCBtYXJnaW5zXG5cdFx0cmV0dXJuIHtcblx0XHRcdHRvcDogb2Zmc2V0LnRvcCAtIHBhcmVudE9mZnNldC50b3AgLSBqUXVlcnkuY3NzKCBlbGVtLCBcIm1hcmdpblRvcFwiLCB0cnVlICksXG5cdFx0XHRsZWZ0OiBvZmZzZXQubGVmdCAtIHBhcmVudE9mZnNldC5sZWZ0IC0galF1ZXJ5LmNzcyggZWxlbSwgXCJtYXJnaW5MZWZ0XCIsIHRydWUgKVxuXHRcdH07XG5cdH0sXG5cblx0Ly8gVGhpcyBtZXRob2Qgd2lsbCByZXR1cm4gZG9jdW1lbnRFbGVtZW50IGluIHRoZSBmb2xsb3dpbmcgY2FzZXM6XG5cdC8vIDEpIEZvciB0aGUgZWxlbWVudCBpbnNpZGUgdGhlIGlmcmFtZSB3aXRob3V0IG9mZnNldFBhcmVudCwgdGhpcyBtZXRob2Qgd2lsbCByZXR1cm5cblx0Ly8gICAgZG9jdW1lbnRFbGVtZW50IG9mIHRoZSBwYXJlbnQgd2luZG93XG5cdC8vIDIpIEZvciB0aGUgaGlkZGVuIG9yIGRldGFjaGVkIGVsZW1lbnRcblx0Ly8gMykgRm9yIGJvZHkgb3IgaHRtbCBlbGVtZW50LCBpLmUuIGluIGNhc2Ugb2YgdGhlIGh0bWwgbm9kZSAtIGl0IHdpbGwgcmV0dXJuIGl0c2VsZlxuXHQvL1xuXHQvLyBidXQgdGhvc2UgZXhjZXB0aW9ucyB3ZXJlIG5ldmVyIHByZXNlbnRlZCBhcyBhIHJlYWwgbGlmZSB1c2UtY2FzZXNcblx0Ly8gYW5kIG1pZ2h0IGJlIGNvbnNpZGVyZWQgYXMgbW9yZSBwcmVmZXJhYmxlIHJlc3VsdHMuXG5cdC8vXG5cdC8vIFRoaXMgbG9naWMsIGhvd2V2ZXIsIGlzIG5vdCBndWFyYW50ZWVkIGFuZCBjYW4gY2hhbmdlIGF0IGFueSBwb2ludCBpbiB0aGUgZnV0dXJlXG5cdG9mZnNldFBhcmVudDogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHRoaXMubWFwKCBmdW5jdGlvbigpIHtcblx0XHRcdHZhciBvZmZzZXRQYXJlbnQgPSB0aGlzLm9mZnNldFBhcmVudDtcblxuXHRcdFx0d2hpbGUgKCBvZmZzZXRQYXJlbnQgJiYgalF1ZXJ5LmNzcyggb2Zmc2V0UGFyZW50LCBcInBvc2l0aW9uXCIgKSA9PT0gXCJzdGF0aWNcIiApIHtcblx0XHRcdFx0b2Zmc2V0UGFyZW50ID0gb2Zmc2V0UGFyZW50Lm9mZnNldFBhcmVudDtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIG9mZnNldFBhcmVudCB8fCBkb2N1bWVudEVsZW1lbnQ7XG5cdFx0fSApO1xuXHR9XG59ICk7XG5cbi8vIENyZWF0ZSBzY3JvbGxMZWZ0IGFuZCBzY3JvbGxUb3AgbWV0aG9kc1xualF1ZXJ5LmVhY2goIHsgc2Nyb2xsTGVmdDogXCJwYWdlWE9mZnNldFwiLCBzY3JvbGxUb3A6IFwicGFnZVlPZmZzZXRcIiB9LCBmdW5jdGlvbiggbWV0aG9kLCBwcm9wICkge1xuXHR2YXIgdG9wID0gXCJwYWdlWU9mZnNldFwiID09PSBwcm9wO1xuXG5cdGpRdWVyeS5mblsgbWV0aG9kIF0gPSBmdW5jdGlvbiggdmFsICkge1xuXHRcdHJldHVybiBhY2Nlc3MoIHRoaXMsIGZ1bmN0aW9uKCBlbGVtLCBtZXRob2QsIHZhbCApIHtcblxuXHRcdFx0Ly8gQ29hbGVzY2UgZG9jdW1lbnRzIGFuZCB3aW5kb3dzXG5cdFx0XHR2YXIgd2luO1xuXHRcdFx0aWYgKCBpc1dpbmRvdyggZWxlbSApICkge1xuXHRcdFx0XHR3aW4gPSBlbGVtO1xuXHRcdFx0fSBlbHNlIGlmICggZWxlbS5ub2RlVHlwZSA9PT0gOSApIHtcblx0XHRcdFx0d2luID0gZWxlbS5kZWZhdWx0Vmlldztcblx0XHRcdH1cblxuXHRcdFx0aWYgKCB2YWwgPT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0cmV0dXJuIHdpbiA/IHdpblsgcHJvcCBdIDogZWxlbVsgbWV0aG9kIF07XG5cdFx0XHR9XG5cblx0XHRcdGlmICggd2luICkge1xuXHRcdFx0XHR3aW4uc2Nyb2xsVG8oXG5cdFx0XHRcdFx0IXRvcCA/IHZhbCA6IHdpbi5wYWdlWE9mZnNldCxcblx0XHRcdFx0XHR0b3AgPyB2YWwgOiB3aW4ucGFnZVlPZmZzZXRcblx0XHRcdFx0KTtcblxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0ZWxlbVsgbWV0aG9kIF0gPSB2YWw7XG5cdFx0XHR9XG5cdFx0fSwgbWV0aG9kLCB2YWwsIGFyZ3VtZW50cy5sZW5ndGggKTtcblx0fTtcbn0gKTtcblxuLy8gU3VwcG9ydDogU2FmYXJpIDw9NyAtIDkuMSwgQ2hyb21lIDw9MzcgLSA0OVxuLy8gQWRkIHRoZSB0b3AvbGVmdCBjc3NIb29rcyB1c2luZyBqUXVlcnkuZm4ucG9zaXRpb25cbi8vIFdlYmtpdCBidWc6IGh0dHBzOi8vYnVncy53ZWJraXQub3JnL3Nob3dfYnVnLmNnaT9pZD0yOTA4NFxuLy8gQmxpbmsgYnVnOiBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvY2hyb21pdW0vaXNzdWVzL2RldGFpbD9pZD01ODkzNDdcbi8vIGdldENvbXB1dGVkU3R5bGUgcmV0dXJucyBwZXJjZW50IHdoZW4gc3BlY2lmaWVkIGZvciB0b3AvbGVmdC9ib3R0b20vcmlnaHQ7XG4vLyByYXRoZXIgdGhhbiBtYWtlIHRoZSBjc3MgbW9kdWxlIGRlcGVuZCBvbiB0aGUgb2Zmc2V0IG1vZHVsZSwganVzdCBjaGVjayBmb3IgaXQgaGVyZVxualF1ZXJ5LmVhY2goIFsgXCJ0b3BcIiwgXCJsZWZ0XCIgXSwgZnVuY3Rpb24oIF9pLCBwcm9wICkge1xuXHRqUXVlcnkuY3NzSG9va3NbIHByb3AgXSA9IGFkZEdldEhvb2tJZiggc3VwcG9ydC5waXhlbFBvc2l0aW9uLFxuXHRcdGZ1bmN0aW9uKCBlbGVtLCBjb21wdXRlZCApIHtcblx0XHRcdGlmICggY29tcHV0ZWQgKSB7XG5cdFx0XHRcdGNvbXB1dGVkID0gY3VyQ1NTKCBlbGVtLCBwcm9wICk7XG5cblx0XHRcdFx0Ly8gSWYgY3VyQ1NTIHJldHVybnMgcGVyY2VudGFnZSwgZmFsbGJhY2sgdG8gb2Zmc2V0XG5cdFx0XHRcdHJldHVybiBybnVtbm9ucHgudGVzdCggY29tcHV0ZWQgKSA/XG5cdFx0XHRcdFx0alF1ZXJ5KCBlbGVtICkucG9zaXRpb24oKVsgcHJvcCBdICsgXCJweFwiIDpcblx0XHRcdFx0XHRjb21wdXRlZDtcblx0XHRcdH1cblx0XHR9XG5cdCk7XG59ICk7XG5cblxuLy8gQ3JlYXRlIGlubmVySGVpZ2h0LCBpbm5lcldpZHRoLCBoZWlnaHQsIHdpZHRoLCBvdXRlckhlaWdodCBhbmQgb3V0ZXJXaWR0aCBtZXRob2RzXG5qUXVlcnkuZWFjaCggeyBIZWlnaHQ6IFwiaGVpZ2h0XCIsIFdpZHRoOiBcIndpZHRoXCIgfSwgZnVuY3Rpb24oIG5hbWUsIHR5cGUgKSB7XG5cdGpRdWVyeS5lYWNoKCB7XG5cdFx0cGFkZGluZzogXCJpbm5lclwiICsgbmFtZSxcblx0XHRjb250ZW50OiB0eXBlLFxuXHRcdFwiXCI6IFwib3V0ZXJcIiArIG5hbWVcblx0fSwgZnVuY3Rpb24oIGRlZmF1bHRFeHRyYSwgZnVuY05hbWUgKSB7XG5cblx0XHQvLyBNYXJnaW4gaXMgb25seSBmb3Igb3V0ZXJIZWlnaHQsIG91dGVyV2lkdGhcblx0XHRqUXVlcnkuZm5bIGZ1bmNOYW1lIF0gPSBmdW5jdGlvbiggbWFyZ2luLCB2YWx1ZSApIHtcblx0XHRcdHZhciBjaGFpbmFibGUgPSBhcmd1bWVudHMubGVuZ3RoICYmICggZGVmYXVsdEV4dHJhIHx8IHR5cGVvZiBtYXJnaW4gIT09IFwiYm9vbGVhblwiICksXG5cdFx0XHRcdGV4dHJhID0gZGVmYXVsdEV4dHJhIHx8ICggbWFyZ2luID09PSB0cnVlIHx8IHZhbHVlID09PSB0cnVlID8gXCJtYXJnaW5cIiA6IFwiYm9yZGVyXCIgKTtcblxuXHRcdFx0cmV0dXJuIGFjY2VzcyggdGhpcywgZnVuY3Rpb24oIGVsZW0sIHR5cGUsIHZhbHVlICkge1xuXHRcdFx0XHR2YXIgZG9jO1xuXG5cdFx0XHRcdGlmICggaXNXaW5kb3coIGVsZW0gKSApIHtcblxuXHRcdFx0XHRcdC8vICQoIHdpbmRvdyApLm91dGVyV2lkdGgvSGVpZ2h0IHJldHVybiB3L2ggaW5jbHVkaW5nIHNjcm9sbGJhcnMgKGdoLTE3MjkpXG5cdFx0XHRcdFx0cmV0dXJuIGZ1bmNOYW1lLmluZGV4T2YoIFwib3V0ZXJcIiApID09PSAwID9cblx0XHRcdFx0XHRcdGVsZW1bIFwiaW5uZXJcIiArIG5hbWUgXSA6XG5cdFx0XHRcdFx0XHRlbGVtLmRvY3VtZW50LmRvY3VtZW50RWxlbWVudFsgXCJjbGllbnRcIiArIG5hbWUgXTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIEdldCBkb2N1bWVudCB3aWR0aCBvciBoZWlnaHRcblx0XHRcdFx0aWYgKCBlbGVtLm5vZGVUeXBlID09PSA5ICkge1xuXHRcdFx0XHRcdGRvYyA9IGVsZW0uZG9jdW1lbnRFbGVtZW50O1xuXG5cdFx0XHRcdFx0Ly8gRWl0aGVyIHNjcm9sbFtXaWR0aC9IZWlnaHRdIG9yIG9mZnNldFtXaWR0aC9IZWlnaHRdIG9yIGNsaWVudFtXaWR0aC9IZWlnaHRdLFxuXHRcdFx0XHRcdC8vIHdoaWNoZXZlciBpcyBncmVhdGVzdFxuXHRcdFx0XHRcdHJldHVybiBNYXRoLm1heChcblx0XHRcdFx0XHRcdGVsZW0uYm9keVsgXCJzY3JvbGxcIiArIG5hbWUgXSwgZG9jWyBcInNjcm9sbFwiICsgbmFtZSBdLFxuXHRcdFx0XHRcdFx0ZWxlbS5ib2R5WyBcIm9mZnNldFwiICsgbmFtZSBdLCBkb2NbIFwib2Zmc2V0XCIgKyBuYW1lIF0sXG5cdFx0XHRcdFx0XHRkb2NbIFwiY2xpZW50XCIgKyBuYW1lIF1cblx0XHRcdFx0XHQpO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0dXJuIHZhbHVlID09PSB1bmRlZmluZWQgP1xuXG5cdFx0XHRcdFx0Ly8gR2V0IHdpZHRoIG9yIGhlaWdodCBvbiB0aGUgZWxlbWVudCwgcmVxdWVzdGluZyBidXQgbm90IGZvcmNpbmcgcGFyc2VGbG9hdFxuXHRcdFx0XHRcdGpRdWVyeS5jc3MoIGVsZW0sIHR5cGUsIGV4dHJhICkgOlxuXG5cdFx0XHRcdFx0Ly8gU2V0IHdpZHRoIG9yIGhlaWdodCBvbiB0aGUgZWxlbWVudFxuXHRcdFx0XHRcdGpRdWVyeS5zdHlsZSggZWxlbSwgdHlwZSwgdmFsdWUsIGV4dHJhICk7XG5cdFx0XHR9LCB0eXBlLCBjaGFpbmFibGUgPyBtYXJnaW4gOiB1bmRlZmluZWQsIGNoYWluYWJsZSApO1xuXHRcdH07XG5cdH0gKTtcbn0gKTtcblxuXG5qUXVlcnkuZWFjaCggW1xuXHRcImFqYXhTdGFydFwiLFxuXHRcImFqYXhTdG9wXCIsXG5cdFwiYWpheENvbXBsZXRlXCIsXG5cdFwiYWpheEVycm9yXCIsXG5cdFwiYWpheFN1Y2Nlc3NcIixcblx0XCJhamF4U2VuZFwiXG5dLCBmdW5jdGlvbiggX2ksIHR5cGUgKSB7XG5cdGpRdWVyeS5mblsgdHlwZSBdID0gZnVuY3Rpb24oIGZuICkge1xuXHRcdHJldHVybiB0aGlzLm9uKCB0eXBlLCBmbiApO1xuXHR9O1xufSApO1xuXG5cblxuXG5qUXVlcnkuZm4uZXh0ZW5kKCB7XG5cblx0YmluZDogZnVuY3Rpb24oIHR5cGVzLCBkYXRhLCBmbiApIHtcblx0XHRyZXR1cm4gdGhpcy5vbiggdHlwZXMsIG51bGwsIGRhdGEsIGZuICk7XG5cdH0sXG5cdHVuYmluZDogZnVuY3Rpb24oIHR5cGVzLCBmbiApIHtcblx0XHRyZXR1cm4gdGhpcy5vZmYoIHR5cGVzLCBudWxsLCBmbiApO1xuXHR9LFxuXG5cdGRlbGVnYXRlOiBmdW5jdGlvbiggc2VsZWN0b3IsIHR5cGVzLCBkYXRhLCBmbiApIHtcblx0XHRyZXR1cm4gdGhpcy5vbiggdHlwZXMsIHNlbGVjdG9yLCBkYXRhLCBmbiApO1xuXHR9LFxuXHR1bmRlbGVnYXRlOiBmdW5jdGlvbiggc2VsZWN0b3IsIHR5cGVzLCBmbiApIHtcblxuXHRcdC8vICggbmFtZXNwYWNlICkgb3IgKCBzZWxlY3RvciwgdHlwZXMgWywgZm5dIClcblx0XHRyZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA9PT0gMSA/XG5cdFx0XHR0aGlzLm9mZiggc2VsZWN0b3IsIFwiKipcIiApIDpcblx0XHRcdHRoaXMub2ZmKCB0eXBlcywgc2VsZWN0b3IgfHwgXCIqKlwiLCBmbiApO1xuXHR9LFxuXG5cdGhvdmVyOiBmdW5jdGlvbiggZm5PdmVyLCBmbk91dCApIHtcblx0XHRyZXR1cm4gdGhpcy5tb3VzZWVudGVyKCBmbk92ZXIgKS5tb3VzZWxlYXZlKCBmbk91dCB8fCBmbk92ZXIgKTtcblx0fVxufSApO1xuXG5qUXVlcnkuZWFjaChcblx0KCBcImJsdXIgZm9jdXMgZm9jdXNpbiBmb2N1c291dCByZXNpemUgc2Nyb2xsIGNsaWNrIGRibGNsaWNrIFwiICtcblx0XCJtb3VzZWRvd24gbW91c2V1cCBtb3VzZW1vdmUgbW91c2VvdmVyIG1vdXNlb3V0IG1vdXNlZW50ZXIgbW91c2VsZWF2ZSBcIiArXG5cdFwiY2hhbmdlIHNlbGVjdCBzdWJtaXQga2V5ZG93biBrZXlwcmVzcyBrZXl1cCBjb250ZXh0bWVudVwiICkuc3BsaXQoIFwiIFwiICksXG5cdGZ1bmN0aW9uKCBfaSwgbmFtZSApIHtcblxuXHRcdC8vIEhhbmRsZSBldmVudCBiaW5kaW5nXG5cdFx0alF1ZXJ5LmZuWyBuYW1lIF0gPSBmdW5jdGlvbiggZGF0YSwgZm4gKSB7XG5cdFx0XHRyZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA+IDAgP1xuXHRcdFx0XHR0aGlzLm9uKCBuYW1lLCBudWxsLCBkYXRhLCBmbiApIDpcblx0XHRcdFx0dGhpcy50cmlnZ2VyKCBuYW1lICk7XG5cdFx0fTtcblx0fVxuKTtcblxuXG5cblxuLy8gU3VwcG9ydDogQW5kcm9pZCA8PTQuMCBvbmx5XG4vLyBNYWtlIHN1cmUgd2UgdHJpbSBCT00gYW5kIE5CU1BcbnZhciBydHJpbSA9IC9eW1xcc1xcdUZFRkZcXHhBMF0rfFtcXHNcXHVGRUZGXFx4QTBdKyQvZztcblxuLy8gQmluZCBhIGZ1bmN0aW9uIHRvIGEgY29udGV4dCwgb3B0aW9uYWxseSBwYXJ0aWFsbHkgYXBwbHlpbmcgYW55XG4vLyBhcmd1bWVudHMuXG4vLyBqUXVlcnkucHJveHkgaXMgZGVwcmVjYXRlZCB0byBwcm9tb3RlIHN0YW5kYXJkcyAoc3BlY2lmaWNhbGx5IEZ1bmN0aW9uI2JpbmQpXG4vLyBIb3dldmVyLCBpdCBpcyBub3Qgc2xhdGVkIGZvciByZW1vdmFsIGFueSB0aW1lIHNvb25cbmpRdWVyeS5wcm94eSA9IGZ1bmN0aW9uKCBmbiwgY29udGV4dCApIHtcblx0dmFyIHRtcCwgYXJncywgcHJveHk7XG5cblx0aWYgKCB0eXBlb2YgY29udGV4dCA9PT0gXCJzdHJpbmdcIiApIHtcblx0XHR0bXAgPSBmblsgY29udGV4dCBdO1xuXHRcdGNvbnRleHQgPSBmbjtcblx0XHRmbiA9IHRtcDtcblx0fVxuXG5cdC8vIFF1aWNrIGNoZWNrIHRvIGRldGVybWluZSBpZiB0YXJnZXQgaXMgY2FsbGFibGUsIGluIHRoZSBzcGVjXG5cdC8vIHRoaXMgdGhyb3dzIGEgVHlwZUVycm9yLCBidXQgd2Ugd2lsbCBqdXN0IHJldHVybiB1bmRlZmluZWQuXG5cdGlmICggIWlzRnVuY3Rpb24oIGZuICkgKSB7XG5cdFx0cmV0dXJuIHVuZGVmaW5lZDtcblx0fVxuXG5cdC8vIFNpbXVsYXRlZCBiaW5kXG5cdGFyZ3MgPSBzbGljZS5jYWxsKCBhcmd1bWVudHMsIDIgKTtcblx0cHJveHkgPSBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gZm4uYXBwbHkoIGNvbnRleHQgfHwgdGhpcywgYXJncy5jb25jYXQoIHNsaWNlLmNhbGwoIGFyZ3VtZW50cyApICkgKTtcblx0fTtcblxuXHQvLyBTZXQgdGhlIGd1aWQgb2YgdW5pcXVlIGhhbmRsZXIgdG8gdGhlIHNhbWUgb2Ygb3JpZ2luYWwgaGFuZGxlciwgc28gaXQgY2FuIGJlIHJlbW92ZWRcblx0cHJveHkuZ3VpZCA9IGZuLmd1aWQgPSBmbi5ndWlkIHx8IGpRdWVyeS5ndWlkKys7XG5cblx0cmV0dXJuIHByb3h5O1xufTtcblxualF1ZXJ5LmhvbGRSZWFkeSA9IGZ1bmN0aW9uKCBob2xkICkge1xuXHRpZiAoIGhvbGQgKSB7XG5cdFx0alF1ZXJ5LnJlYWR5V2FpdCsrO1xuXHR9IGVsc2Uge1xuXHRcdGpRdWVyeS5yZWFkeSggdHJ1ZSApO1xuXHR9XG59O1xualF1ZXJ5LmlzQXJyYXkgPSBBcnJheS5pc0FycmF5O1xualF1ZXJ5LnBhcnNlSlNPTiA9IEpTT04ucGFyc2U7XG5qUXVlcnkubm9kZU5hbWUgPSBub2RlTmFtZTtcbmpRdWVyeS5pc0Z1bmN0aW9uID0gaXNGdW5jdGlvbjtcbmpRdWVyeS5pc1dpbmRvdyA9IGlzV2luZG93O1xualF1ZXJ5LmNhbWVsQ2FzZSA9IGNhbWVsQ2FzZTtcbmpRdWVyeS50eXBlID0gdG9UeXBlO1xuXG5qUXVlcnkubm93ID0gRGF0ZS5ub3c7XG5cbmpRdWVyeS5pc051bWVyaWMgPSBmdW5jdGlvbiggb2JqICkge1xuXG5cdC8vIEFzIG9mIGpRdWVyeSAzLjAsIGlzTnVtZXJpYyBpcyBsaW1pdGVkIHRvXG5cdC8vIHN0cmluZ3MgYW5kIG51bWJlcnMgKHByaW1pdGl2ZXMgb3Igb2JqZWN0cylcblx0Ly8gdGhhdCBjYW4gYmUgY29lcmNlZCB0byBmaW5pdGUgbnVtYmVycyAoZ2gtMjY2Milcblx0dmFyIHR5cGUgPSBqUXVlcnkudHlwZSggb2JqICk7XG5cdHJldHVybiAoIHR5cGUgPT09IFwibnVtYmVyXCIgfHwgdHlwZSA9PT0gXCJzdHJpbmdcIiApICYmXG5cblx0XHQvLyBwYXJzZUZsb2F0IE5hTnMgbnVtZXJpYy1jYXN0IGZhbHNlIHBvc2l0aXZlcyAoXCJcIilcblx0XHQvLyAuLi5idXQgbWlzaW50ZXJwcmV0cyBsZWFkaW5nLW51bWJlciBzdHJpbmdzLCBwYXJ0aWN1bGFybHkgaGV4IGxpdGVyYWxzIChcIjB4Li4uXCIpXG5cdFx0Ly8gc3VidHJhY3Rpb24gZm9yY2VzIGluZmluaXRpZXMgdG8gTmFOXG5cdFx0IWlzTmFOKCBvYmogLSBwYXJzZUZsb2F0KCBvYmogKSApO1xufTtcblxualF1ZXJ5LnRyaW0gPSBmdW5jdGlvbiggdGV4dCApIHtcblx0cmV0dXJuIHRleHQgPT0gbnVsbCA/XG5cdFx0XCJcIiA6XG5cdFx0KCB0ZXh0ICsgXCJcIiApLnJlcGxhY2UoIHJ0cmltLCBcIlwiICk7XG59O1xuXG5cblxuLy8gUmVnaXN0ZXIgYXMgYSBuYW1lZCBBTUQgbW9kdWxlLCBzaW5jZSBqUXVlcnkgY2FuIGJlIGNvbmNhdGVuYXRlZCB3aXRoIG90aGVyXG4vLyBmaWxlcyB0aGF0IG1heSB1c2UgZGVmaW5lLCBidXQgbm90IHZpYSBhIHByb3BlciBjb25jYXRlbmF0aW9uIHNjcmlwdCB0aGF0XG4vLyB1bmRlcnN0YW5kcyBhbm9ueW1vdXMgQU1EIG1vZHVsZXMuIEEgbmFtZWQgQU1EIGlzIHNhZmVzdCBhbmQgbW9zdCByb2J1c3Rcbi8vIHdheSB0byByZWdpc3Rlci4gTG93ZXJjYXNlIGpxdWVyeSBpcyB1c2VkIGJlY2F1c2UgQU1EIG1vZHVsZSBuYW1lcyBhcmVcbi8vIGRlcml2ZWQgZnJvbSBmaWxlIG5hbWVzLCBhbmQgalF1ZXJ5IGlzIG5vcm1hbGx5IGRlbGl2ZXJlZCBpbiBhIGxvd2VyY2FzZVxuLy8gZmlsZSBuYW1lLiBEbyB0aGlzIGFmdGVyIGNyZWF0aW5nIHRoZSBnbG9iYWwgc28gdGhhdCBpZiBhbiBBTUQgbW9kdWxlIHdhbnRzXG4vLyB0byBjYWxsIG5vQ29uZmxpY3QgdG8gaGlkZSB0aGlzIHZlcnNpb24gb2YgalF1ZXJ5LCBpdCB3aWxsIHdvcmsuXG5cbi8vIE5vdGUgdGhhdCBmb3IgbWF4aW11bSBwb3J0YWJpbGl0eSwgbGlicmFyaWVzIHRoYXQgYXJlIG5vdCBqUXVlcnkgc2hvdWxkXG4vLyBkZWNsYXJlIHRoZW1zZWx2ZXMgYXMgYW5vbnltb3VzIG1vZHVsZXMsIGFuZCBhdm9pZCBzZXR0aW5nIGEgZ2xvYmFsIGlmIGFuXG4vLyBBTUQgbG9hZGVyIGlzIHByZXNlbnQuIGpRdWVyeSBpcyBhIHNwZWNpYWwgY2FzZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZVxuLy8gaHR0cHM6Ly9naXRodWIuY29tL2pyYnVya2UvcmVxdWlyZWpzL3dpa2kvVXBkYXRpbmctZXhpc3RpbmctbGlicmFyaWVzI3dpa2ktYW5vblxuXG5pZiAoIHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kICkge1xuXHRkZWZpbmUoIFwianF1ZXJ5XCIsIFtdLCBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4galF1ZXJ5O1xuXHR9ICk7XG59XG5cblxuXG5cbnZhclxuXG5cdC8vIE1hcCBvdmVyIGpRdWVyeSBpbiBjYXNlIG9mIG92ZXJ3cml0ZVxuXHRfalF1ZXJ5ID0gd2luZG93LmpRdWVyeSxcblxuXHQvLyBNYXAgb3ZlciB0aGUgJCBpbiBjYXNlIG9mIG92ZXJ3cml0ZVxuXHRfJCA9IHdpbmRvdy4kO1xuXG5qUXVlcnkubm9Db25mbGljdCA9IGZ1bmN0aW9uKCBkZWVwICkge1xuXHRpZiAoIHdpbmRvdy4kID09PSBqUXVlcnkgKSB7XG5cdFx0d2luZG93LiQgPSBfJDtcblx0fVxuXG5cdGlmICggZGVlcCAmJiB3aW5kb3cualF1ZXJ5ID09PSBqUXVlcnkgKSB7XG5cdFx0d2luZG93LmpRdWVyeSA9IF9qUXVlcnk7XG5cdH1cblxuXHRyZXR1cm4galF1ZXJ5O1xufTtcblxuLy8gRXhwb3NlIGpRdWVyeSBhbmQgJCBpZGVudGlmaWVycywgZXZlbiBpbiBBTURcbi8vICgjNzEwMiNjb21tZW50OjEwLCBodHRwczovL2dpdGh1Yi5jb20vanF1ZXJ5L2pxdWVyeS9wdWxsLzU1Nylcbi8vIGFuZCBDb21tb25KUyBmb3IgYnJvd3NlciBlbXVsYXRvcnMgKCMxMzU2NilcbmlmICggdHlwZW9mIG5vR2xvYmFsID09PSBcInVuZGVmaW5lZFwiICkge1xuXHR3aW5kb3cualF1ZXJ5ID0gd2luZG93LiQgPSBqUXVlcnk7XG59XG5cblxuXG5cbnJldHVybiBqUXVlcnk7XG59ICk7XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./node_modules/jquery/dist/jquery.js\n");
/***/ })
}]);