vendor: 4,313 bytes, lines 1-2
1/*! jQuery v2.2.4 | (c) jQuery Foundation | jquery.org/license */ 2!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=a.document,e=c.slice,f=c.concat,g=c.push,h=c.indexOf,i={},j=i.toString,k=i.hasOwnProperty,l={},m="2.2.4",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return e.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:e.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a){return n.each(this,a)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(e.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:g,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(n.isPlainObject(d)||(e=n.isArray(d)))?(e?(e=!1,f=c&&n.isArray(c)?c:[]):f=c&&n.isPlainObject(c)?c:{},g[b]=n.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){var b=a&&a.toString();return!n.isArray(a)&&b-parseFloat(b)+1>=0},isPlainObject:function(a){var b;if("object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;if(a.constructor&&!k.call(a,"constructor")&&!k.call(a.constructor.prototype||{},"isPrototypeOf"))return!1;for(b in a);return void 0===b||k.call(a,b)},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?i[j.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=n.trim(a),a&&(1===a.indexOf("use strict")?(b=d.createElement("script"),b.text=a,d.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(s(a)){for(c=a.length;c>d;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):g.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:h.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,g=0,h=[];if(s(a))for(d=a.length;d>g;g++)e=b(a[g],g,c),null!=e&&h.push(e);else for(g in a)e=b(a[g],g,c),null!=e&&h.push(e);return f.apply([],h)},guid:1,proxy:function(a,b){var c,d,f;return"string"==typeof b&&(c=a[b],b=a,a=c),n.isFunction(a)?(d=e.call(arguments,2),f=function(){return a.apply(b||this,d.concat(e.call(arguments)))},f.guid=a.guid=a.guid||n.guid++,f):void 0},now:Date.now,support:l}),"function"==typeof Symbol&&(n.fn[Symbol.iterator]=c[Symbol.iterator]),n.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){i["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=!!a&&"length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*ne
vendor: 13,028 bytes, line 2
2w Date,v=a.document,w=0,x=0,y=ga(),z=ga(),A=ga(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+M+"))|)"+L+"*\\]",O=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+N+")*)|.*)\\)|)",P=new RegExp(L+"+","g"),Q=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),R=new RegExp("^"+L+"*,"+L+"*"),S=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),T=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),U=new RegExp(O),V=new RegExp("^"+M+"$"),W={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M+"|[*])"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},X=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,Z=/^[^{]+\{\s*\[native \w/,$=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,_=/[+~]/,aa=/'|\\/g,ba=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),ca=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},da=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(ea){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fa(a,b,d,e){var f,h,j,k,l,o,r,s,w=b&&b.ownerDocument,x=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==x&&9!==x&&11!==x)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==x&&(o=$.exec(a)))if(f=o[1]){if(9===x){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(w&&(j=w.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(o[2])return H.apply(d,b.getElementsByTagName(a)),d;if((f=o[3])&&c.getElementsByClassName&&b.getElementsByClassName)return H.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==x)w=b,s=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(aa,"\\$&"):b.setAttribute("id",k=u),r=g(a),h=r.length,l=V.test(k)?"#"+k:"[id='"+k+"']";while(h--)r[h]=l+" "+qa(r[h]);s=r.join(","),w=_.test(a)&&oa(b.parentNode)||b}if(s)try{return H.apply(d,w.querySelectorAll(s)),d}catch(y){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(Q,"$1"),b,d,e)}function ga(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ha(a){return a[u]=!0,a}function ia(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ja(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function ka(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function la(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function na(a){return ha(function(b){return b=+b,ha(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function oa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=fa.support={},f=fa.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fa.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ia(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ia(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Z.test(n.getElementsByClassName),c.getById=ia(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return"undefined"!=typeof b.getElementsByClassName&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=Z.test(n.querySelectorAll))&&(ia(function(a){o.appendChild(a).innerHTML="<a id='"+u+"'></a><select id='"+u+"-\r\\' msallowcapture=''><option selected=''></option></select>",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ia(function(a){var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Z.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ia(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",O)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Z.test(o.compareDocumentPosition),t=b||Z.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return ka(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?ka(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},fa.matches=function(a,b){return fa(a,null,null,b)},fa.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(T,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fa(b,n,null,[a]).length>0},fa.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fa.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fa.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fa.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fa.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fa.selectors={cacheLength:50,createPseudo:ha,match:W,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ba,ca),a[3]=(a[3]||a[4]||a[5]||"").replace(ba,ca),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fa.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fa.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return W.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&U.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ba,ca).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fa.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(P," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fa.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ha(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ha(function(a){var b=[],c=[],d=h(a.replace(Q,"$1"));return d[u]?ha(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ha(function(a){return function(b){return fa(a,b).length>0}}),contains:ha(function(a){return a=a.replace(ba,ca),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ha(function(a){return V.test(a||"")||fa.error("unsupported lang: "+a),a=a.replace(ba,ca).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Y.test(a.nodeName)}
vendor: 68,237 bytes, lines 2-4
2,input:function(a){return X.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:na(function(){return[0]}),last:na(function(a,b){return[b-1]}),eq:na(function(a,b,c){return[0>c?c+b:c]}),even:na(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:na(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:na(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:na(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=la(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=ma(b);function pa(){}pa.prototype=d.filters=d.pseudos,d.setFilters=new pa,g=fa.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){c&&!(e=R.exec(h))||(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=S.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(Q," ")}),h=h.slice(c.length));for(g in d.filter)!(e=W[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?fa.error(a):z(a,i).slice(0)};function qa(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function ra(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j,k=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(j=b[u]||(b[u]={}),i=j[b.uniqueID]||(j[b.uniqueID]={}),(h=i[d])&&h[0]===w&&h[1]===f)return k[2]=h[2];if(i[d]=k,k[2]=a(b,c,g))return!0}}}function sa(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ta(a,b,c){for(var d=0,e=b.length;e>d;d++)fa(a,b[d],c);return c}function ua(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(c&&!c(f,d,e)||(g.push(f),j&&b.push(h)));return g}function va(a,b,c,d,e,f){return d&&!d[u]&&(d=va(d)),e&&!e[u]&&(e=va(e,f)),ha(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ta(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ua(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ua(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ua(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function wa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ra(function(a){return a===b},h,!0),l=ra(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[ra(sa(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return va(i>1&&sa(m),i>1&&qa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(Q,"$1"),c,e>i&&wa(a.slice(i,e)),f>e&&wa(a=a.slice(e)),f>e&&qa(a))}m.push(c)}return sa(m)}function xa(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=F.call(i));u=ua(u)}H.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&fa.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ha(f):f}return h=fa.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xa(e,d)),f.selector=a}return f},i=fa.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ba,ca),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=W.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ba,ca),_.test(j[0].type)&&oa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qa(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,!b||_.test(a)&&oa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ia(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ia(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||ja("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ia(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ja("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ia(function(a){return null==a.getAttribute("disabled")})||ja(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fa}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.uniqueSort=n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},v=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},w=n.expr.match.needsContext,x=/^<([\w-]+)\s*\/?>(?:<\/\1>|)$/,y=/^.[^:#\[\.,]*$/;function z(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(y.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return h.call(b,a)>-1!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;c>b;b++)if(n.contains(e[b],this))return!0}));for(b=0;c>b;b++)n.find(a,e[b],d);return d=this.pushStack(c>1?n.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(z(this,a||[],!1))},not:function(a){return this.pushStack(z(this,a||[],!0))},is:function(a){return!!z(this,"string"==typeof a&&w.test(a)?n(a):a||[],!1).length}});var A,B=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=n.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||A,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:B.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),x.test(e[1])&&n.isPlainObject(b))for(e in b)n.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&f.parentNode&&(this.length=1,this[0]=f),this.context=d,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?void 0!==c.ready?c.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};C.prototype=n.fn,A=n(d);var D=/^(?:parents|prev(?:Until|All))/,E={children:!0,contents:!0,next:!0,prev:!0};n.fn.extend({has:function(a){var b=n(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(n.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=w.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?h.call(n(a),this[0]):h.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.uniqueSort(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function F(a,b){while((a=a[b])&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return u(a,"parentNode")},parentsUntil:function(a,b,c){return u(a,"parentNode",c)},next:function(a){return F(a,"nextSibling")},prev:function(a){return F(a,"previousSibling")},nextAll:function(a){return u(a,"nextSibling")},prevAll:function(a){return u(a,"previousSibling")},nextUntil:function(a,b,c){return u(a,"nextSibling",c)},prevUntil:function(a,b,c){return u(a,"previousSibling",c)},siblings:function(a){return v((a.parentNode||{}).firstChild,a)},children:function(a){return v(a.firstChild)},contents:function(a){return a.contentDocument||n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(E[a]||n.uniqueSort(e),D.test(a)&&e.reverse()),this.pushStack(e)}});var G=/\S+/g;function H(a){var b={};return n.each(a.match(G)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?H(a):n.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h<f.length)f[h].apply(c[0],c[1])===!1&&a.stopOnFalse&&(h=f.length,c=!1)}a.memory||(c=!1),b=!1,e&&(f=c?[]:"")},j={add:function(){return f&&(c&&!b&&(h=f.length-1,g.push(c)),function d(b){n.each(b,function(b,c){n.isFunction(c)?a.unique&&j.has(c)||f.push(c):c&&c.length&&"string"!==n.type(c)&&d(c)})}(arguments),c&&!b&&i()),this},remove:function(){return n.each(arguments,function(a,b){var c;while((c=n.inArray(b,f,c))>-1)f.splice(c,1),h>=c&&h--}),this},has:function(a){return a?n.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().progress(c.notify).done(c.resolve).fail(c.reject):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=e.call(arguments),d=c.length,f=1!==d||a&&n.isFunction(a.promise)?d:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(d){b[a]=this,c[a]=arguments.length>1?e.call(arguments):d,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(d>1)for(i=new Array(d),j=new Array(d),k=new Array(d);d>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().progress(h(b,j,i)).done(h(b,k,c)).fail(g.reject):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(d,[n]),n.fn.triggerHandler&&(n(d).triggerHandler("ready"),n(d).off("ready"))))}});function J(){d.removeEventListener("DOMContentLoaded",J),a.removeEventListener("load",J),n.ready()}n.ready.promise=function(b){return I||(I=n.Deferred(),"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(n.ready):(d.addEventListener("DOMContentLoaded",J),a.addEventListener("load",J))),I.promise(b)},n.ready.promise();var K=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)K(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},L=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function M(){this.expando=n.expando+M.uid++}M.uid=1,M.prototype={register:function(a,b){var c=b||{};return a.nodeType?a[this.expando]=c:Object.defineProperty(a,this.expando,{value:c,writable:!0,configurable:!0}),a[this.expando]},cache:function(a){if(!L(a))return{};var b=a[this.expando];return b||(b={},L(a)&&(a.nodeType?a[this.expando]=b:Object.defineProperty(a,this.expando,{value:b,configurable:!0}))),b},set:function(a,b,c){var d,e=this.cache(a);if("string"==typeof b)e[b]=c;else for(d in b)e[d]=b[d];return e},get:function(a,b){return void 0===b?this.cache(a):a[this.expando]&&a[this.expando][b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,n.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=a[this.expando];if(void 0!==f){if(void 0===b)this.register(a);else{n.isArray(b)?d=b.concat(b.map(n.camelCase)):(e=n.camelCase(b),b in f?d=[b,e]:(d=e,d=d in f?[d]:d.match(G)||[])),c=d.length;while(c--)delete f[d[c]]}(void 0===b||n.isEmptyObject(f))&&(a.nodeType?a[this.expando]=void 0:delete a[this.expando])}},hasData:function(a){var b=a[this.expando];return void 0!==b&&!n.isEmptyObject(b)}};var N=new M,O=new M,P=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,Q=/[A-Z]/g;function R(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(Q,"-$&").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:P.test(c)?n.parseJSON(c):c; 3}catch(e){}O.set(a,b,c)}else c=void 0;return c}n.extend({hasData:function(a){return O.hasData(a)||N.hasData(a)},data:function(a,b,c){return O.access(a,b,c)},removeData:function(a,b){O.remove(a,b)},_data:function(a,b,c){return N.access(a,b,c)},_removeData:function(a,b){N.remove(a,b)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=O.get(f),1===f.nodeType&&!N.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),R(f,d,e[d])));N.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){O.set(this,a)}):K(this,function(b){var c,d;if(f&&void 0===b){if(c=O.get(f,a)||O.get(f,a.replace(Q,"-$&").toLowerCase()),void 0!==c)return c;if(d=n.camelCase(a),c=O.get(f,d),void 0!==c)return c;if(c=R(f,d,void 0),void 0!==c)return c}else d=n.camelCase(a),this.each(function(){var c=O.get(this,d);O.set(this,d,b),a.indexOf("-")>-1&&void 0!==c&&O.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){O.remove(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=N.get(a,b),c&&(!d||n.isArray(c)?d=N.access(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return N.get(a,c)||N.access(a,c,{empty:n.Callbacks("once memory").add(function(){N.remove(a,[b+"queue",c])})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?n.queue(this[0],a):void 0===b?this:this.each(function(){var c=n.queue(this,a,b);n._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&n.dequeue(this,a)})},dequeue:function(a){return this.each(function(){n.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=n.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=N.get(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var S=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,T=new RegExp("^(?:([+-])=|)("+S+")([a-z%]*)$","i"),U=["Top","Right","Bottom","Left"],V=function(a,b){return a=b||a,"none"===n.css(a,"display")||!n.contains(a.ownerDocument,a)};function W(a,b,c,d){var e,f=1,g=20,h=d?function(){return d.cur()}:function(){return n.css(a,b,"")},i=h(),j=c&&c[3]||(n.cssNumber[b]?"":"px"),k=(n.cssNumber[b]||"px"!==j&&+i)&&T.exec(n.css(a,b));if(k&&k[3]!==j){j=j||k[3],c=c||[],k=+i||1;do f=f||".5",k/=f,n.style(a,b,k+j);while(f!==(f=h()/i)&&1!==f&&--g)}return c&&(k=+k||+i||0,e=c[1]?k+(c[1]+1)*c[2]:+c[2],d&&(d.unit=j,d.start=k,d.end=e)),e}var X=/^(?:checkbox|radio)$/i,Y=/<([\w:-]+)/,Z=/^$|\/(?:java|ecma)script/i,$={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};$.optgroup=$.option,$.tbody=$.tfoot=$.colgroup=$.caption=$.thead,$.th=$.td;function _(a,b){var c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&n.nodeName(a,b)?n.merge([a],c):c}function aa(a,b){for(var c=0,d=a.length;d>c;c++)N.set(a[c],"globalEval",!b||N.get(b[c],"globalEval"))}var ba=/<|&#?\w+;/;function ca(a,b,c,d,e){for(var f,g,h,i,j,k,l=b.createDocumentFragment(),m=[],o=0,p=a.length;p>o;o++)if(f=a[o],f||0===f)if("object"===n.type(f))n.merge(m,f.nodeType?[f]:f);else if(ba.test(f)){g=g||l.appendChild(b.createElement("div")),h=(Y.exec(f)||["",""])[1].toLowerCase(),i=$[h]||$._default,g.innerHTML=i[1]+n.htmlPrefilter(f)+i[2],k=i[0];while(k--)g=g.lastChild;n.merge(m,g.childNodes),g=l.firstChild,g.textContent=""}else m.push(b.createTextNode(f));l.textContent="",o=0;while(f=m[o++])if(d&&n.inArray(f,d)>-1)e&&e.push(f);else if(j=n.contains(f.ownerDocument,f),g=_(l.appendChild(f),"script"),j&&aa(g),c){k=0;while(f=g[k++])Z.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),l.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="<textarea>x</textarea>",l.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var da=/^key/,ea=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,fa=/^([^.]*)(?:\.(.+)|)/;function ga(){return!0}function ha(){return!1}function ia(){try{return d.activeElement}catch(a){}}function ja(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)ja(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=ha;else if(!e)return a;return 1===f&&(g=e,e=function(a){return n().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=n.guid++)),a.each(function(){n.event.add(this,b,e,d,c)})}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=N.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=n.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return"undefined"!=typeof n&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(G)||[""],j=b.length;while(j--)h=fa.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o&&(l=n.event.special[o]||{},o=(e?l.delegateType:l.bindType)||o,l=n.event.special[o]||{},k=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[o])||(m=i[o]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(o,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),n.event.global[o]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=N.hasData(a)&&N.get(a);if(r&&(i=r.events)){b=(b||"").match(G)||[""],j=b.length;while(j--)if(h=fa.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=i[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete i[o])}else for(o in i)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(i)&&N.remove(a,"handle events")}},dispatch:function(a){a=n.event.fix(a);var b,c,d,f,g,h=[],i=e.call(arguments),j=(N.get(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())a.rnamespace&&!a.rnamespace.test(g.namespace)||(a.handleObj=g,a.data=g.data,d=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==d&&(a.result=d)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&("click"!==a.type||isNaN(a.button)||a.button<1))for(;i!==this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>-1:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},props:"altKey bubbles cancelable ctrlKey currentTarget detail eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,e,f,g=b.button;return null==a.pageX&&null!=b.clientX&&(c=a.target.ownerDocument||d,e=c.documentElement,f=c.body,a.pageX=b.clientX+(e&&e.scrollLeft||f&&f.scrollLeft||0)-(e&&e.clientLeft||f&&f.clientLeft||0),a.pageY=b.clientY+(e&&e.scrollTop||f&&f.scrollTop||0)-(e&&e.clientTop||f&&f.clientTop||0)),a.which||void 0===g||(a.which=1&g?1:2&g?3:4&g?2:0),a}},fix:function(a){if(a[n.expando])return a;var b,c,e,f=a.type,g=a,h=this.fixHooks[f];h||(this.fixHooks[f]=h=ea.test(f)?this.mouseHooks:da.test(f)?this.keyHooks:{}),e=h.props?this.props.concat(h.props):this.props,a=new n.Event(g),b=e.length;while(b--)c=e[b],a[c]=g[c];return a.target||(a.target=d),3===a.target.nodeType&&(a.target=a.target.parentNode),h.filter?h.filter(a,g):a},special:{load:{noBubble:!0},focus:{trigger:function(){return this!==ia()&&this.focus?(this.focus(),!1):void 0},delegateType:"focusin"},blur:{trigger:function(){return this===ia()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return"checkbox"===this.type&&this.click&&n.nodeName(this,"input")?(this.click(),!1):void 0},_default:function(a){return n.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}}},n.removeEvent=function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c)},n.Event=function(a,b){return this instanceof n.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?ga:ha):this.type=a,b&&n.extend(this,b),this.timeStamp=a&&a.timeStamp||n.now(),void(this[n.expando]=!0)):new n.Event(a,b)},n.Event.prototype={constructor:n.Event,isDefaultPrevented:ha,isPropagationStopped:ha,isImmediatePropagationStopped:ha,isSimulated:!1,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=ga,a&&!this.isSimulated&&a.preventDefault()},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=ga,a&&!this.isSimulated&&a.stopPropagation()},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=ga,a&&!this.isSimulated&&a.stopImmediatePropagation(),this.stopPropagation()}},n.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){n.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return e&&(e===d||n.contains(d,e))||(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),n.fn.extend({on:function(a,b,c,d){return ja(this,a,b,c,d)},one:function(a,b,c,d){return ja(this,a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,n(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return b!==!1&&"function"!=typeof b||(c=b,b=void 0),c===!1&&(c=ha),this.each(function(){n.event.remove(this,a,c,b)})}});var ka=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,la=/<script|<style|<link/i,ma=/checked\s*(?:[^=]|=\s*.checked.)/i,na=/^true\/(.*)/,oa=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;function pa(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function qa(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function ra(a){var b=na.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function sa(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(N.hasData(a)&&(f=N.access(a),g=N.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)n.event.add(b,e,j[e][c])}O.hasData(a)&&(h=O.access(a),i=n.extend({},h),O.set(b,i))}}function ta(a,b){var c=b.nodeName.toLowerCase();"input"===c&&X.test(a.type)?b.checked=a.checked:"input"!==c&&"textarea"!==c||(b.defaultValue=a.defaultValue)}function ua(a,b,c,d){b=f.apply([],b);var e,g,h,i,j,k,m=0,o=a.length,p=o-1,q=b[0],r=n.isFunction(q);if(r||o>1&&"string"==typeof q&&!l.checkClone&&ma.test(q))return a.each(function(e){var f=a.eq(e);r&&(b[0]=q.call(this,e,f.html())),ua(f,b,c,d)});if(o&&(e=ca(b,a[0].ownerDocument,!1,a,d),g=e.firstChild,1===e.childNodes.length&&(e=g),g||d)){for(h=n.map(_(e,"script"),qa),i=h.length;o>m;m++)j=e,m!==p&&(j=n.clone(j,!0,!0),i&&n.merge(h,_(j,"script"))),c.call(a[m],j,m);if(i)for(k=h[h.length-1].ownerDocument,n.map(h,ra),m=0;i>m;m++)j=h[m],Z.test(j.type||"")&&!N.access(j,"globalEval")&&n.contains(k,j)&&(j.src?n._evalUrl&&n._evalUrl(j.src):n.globalEval(j.textContent.replace(oa,"")))}return a}function va(a,b,c){for(var d,e=b?n.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||n.cleanData(_(d)),d.parentNode&&(c&&n.contains(d.ownerDocument,d)&&aa(_(d,"script")),d.parentNode.removeChild(d));return a}n.extend({htmlPrefilter:function(a){return a.replace(ka,"<$1></$2>")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=n.contains(a.ownerDocument,a);if(!(l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(g=_(h),f=_(a),d=0,e=f.length;e>d;d++)ta(f[d],g[d]);if(b)if(c)for(f=f||_(a),g=g||_(h),d=0,e=f.length;e>d;d++)sa(f[d],g[d]);else sa(a,h);return g=_(h,"script"),g.length>0&&aa(g,!i&&_(a,"script")),h},cleanData:function(a){for(var b,c,d,e=n.event.special,f=0;void 0!==(c=a[f]);f++)if(L(c)){if(b=c[N.expando]){if(b.events)for(d in b.events)e[d]?n.event.remove(c,d):n.removeEvent(c,d,b.handle);c[N.expando]=void 0}c[O.expando]&&(c[O.expando]=void 0)}}}),n.fn.extend({domManip:ua,detach:function(a){return va(this,a,!0)},remove:function(a){return va(this,a)},text:function(a){return K(this,function(a){return void 0===a?n.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=a)})},null,a,arguments.length)},append:function(){return ua(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=pa(this,a);b.appendChild(a)}})},prepend:function(){return ua(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=pa(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return ua(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return ua(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(n.cleanData(_(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return K(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!la.test(a)&&!$[(Y.exec(a)||["",""])[1].toLowerCase()]){a=n.htmlPrefilter(a);try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(_(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return ua(this,arguments,function(b){var c=this.parentNode;n.inArray(this,a)<0&&(n.cleanData(_(this)),c&&c.replaceChild(b,this))},a)}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=[],e=n(a),f=e.length-1,h=0;f>=h;h++)c=h===f?this:this.clone(!0),n(e[h])[b](c),g.apply(d,c.get());return this.pushStack(d)}});var wa,xa={HTML:"block",BODY:"block"};function ya(a,b){var c=n(b.createElement(a)).appendTo(b.body),d=n.css(c[0],"display");return c.detach(),d}function za(a){var b=d,c=xa[a];return c||(c=ya(a,b),"none"!==c&&c||(wa=(wa||n("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=wa[0].contentDocument,b.write(),b.close(),c=ya(a,b),wa.detach()),xa[a]=c),c}var Aa=/^margin/,Ba=new RegExp("^("+S+")(?!px)[a-z%]+$","i"),Ca=function(b){var c=b.ownerDocument.defaultView;return c&&c.opener||(c=a),c.getComputedStyle(b)},Da=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e},Ea=d.documentElement;!function(){var b,c,e,f,g=d.createElement("div"),h=d.createElement("div");if(h.style){h.style.backgroundClip="content-box",h.cloneNode(!0).style.backgroundClip="",l.clearCloneStyle="content-box"===h.style.backgroundClip,g.style.cssText="border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute",g.appendChild(h);function i(){h.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%",h.innerHTML="",Ea.appendChild(g);var d=a.getComputedStyle(h);b="1%"!==d.top,f="2px"===d.marginLeft,c="4px"===d.width,h.style.marginRight="50%",e="4px"===d.marginRight,Ea.removeChild(g)}n.extend(l,{pixelPosition:function(){return i(),b},boxSizingReliable:function(){return null==c&&i(),c},pixelMarginRight:function(){return null==c&&i(),e},reliableMarginLeft:function(){return null==c&&i(),f},reliableMarginRight:function(){var b,c=h.appendChild(d.createElement("div"));return c.style.cssText=h.style.cssText="-webkit-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",c.style.marginRight=c.style.width="0",h.style.width="1px",Ea.appendChild(g),b=!parseFloat(a.getComputedStyle(c).marginRight),Ea.removeChild(g),h.removeChild(c),b}})}}();function Fa(a,b,c){var d,e,f,g,h=a.style;return c=c||Ca(a),g=c?c.getPropertyValue(b)||c[b]:void 0,""!==g&&void 0!==g||n.contains(a.ownerDocument,a)||(g=n.style(a,b)),c&&!l.pixelMarginRight()&&Ba.test(g)&&Aa.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f),void 0!==g?g+"":g}function Ga(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}var Ha=/^(none|table(?!-c[ea]).+)/,Ia={position:"absolute",visibility:"hidden",display:"block"},Ja={letterSpacing:"0",fontWeight:"400"},Ka=["Webkit","O","Moz","ms"],La=d.createElement("div").style;function Ma(a){if(a in La)return a;var b=a[0].toUpperCase()+a.slice(1),c=Ka.length;while(c--)if(a=Ka[c]+b,a in La)return a}function Na(a,b,c){var d=T.exec(b);return d?Math.max(0,d[2]-(c||0))+(d[3]||"px"):b}function Oa(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=n.css(a,c+U[f],!0,e)),d?("content"===c&&(g-=n.css(a,"padding"+U[f],!0,e)),"margin"!==c&&(g-=n.css(a,"border"+U[f]+"Width",!0,e))):(g+=n.css(a,"padding"+U[f],!0,e),"padding"!==c&&(g+=n.css(a,"border"+U[f]+"Width",!0,e)));return g}function Pa(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=Ca(a),g="border-box"===n.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=Fa(a,b,f),(0>e||null==e)&&(e=a.style[b]),Ba.test(e))return e;d=g&&(l.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Oa(a,b,c||(g?"border":"content"),d,f)+"px"}function Qa(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=N.get(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&V(d)&&(f[g]=N.access(d,"olddisplay",za(d.nodeName)))):(e=V(d),"none"===c&&e||N.set(d,"olddisplay",e?c:n.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}n.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Fa(a,"opacity");return""===c?"1":c}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=n.camelCase(b),i=a.style;return b=n.cssProps[h]||(n.cssProps[h]=Ma(h)||h),g=n.cssHooks[b]||n.cssHooks[h],void 0===c?g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b]:(f=typeof c,"string"===f&&(e=T.exec(c))&&e[1]&&(c=W(a,b,e),f="number"),null!=c&&c===c&&("number"===f&&(c+=e&&e[3]||(n.cssNumber[h]?"":"px")),l.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),g&&"set"in g&&void 0===(c=g.set(a,c,d))||(i[b]=c)),void 0)}},css:function(a,b,c,d){var e,f,g,h=n.camelCase(b);return b=n.cssProps[h]||(n.cssProps[h]=Ma(h)||h),g=n.cssHooks[b]||n.cssHooks[h],g&&"get"in g&&(e=g.get(a,!0,c)),void 0===e&&(e=Fa(a,b,d)),"normal"===e&&b in Ja&&(e=Ja[b]),""===c||c?(f=parseFloat(e),c===!0||isFinite(f)?f||0:e):e}}),n.each(["height","width"],function(a,b){n.cssHooks[b]={get:function(a,c,d){return c?Ha.test(n.css(a,"display"))&&0===a.offsetWidth?Da(a,Ia,function(){return Pa(a,b,d)}):Pa(a,b,d):void 0},set:function(a,c,d){var e,f=d&&Ca(a),g=d&&Oa(a,b,d,"border-box"===n.css(a,"boxSizing",!1,f),f);return g&&(e=T.exec(c))&&"px"!==(e[3]||"px")&&(a.style[b]=c,c=n.css(a,b)),Na(a,c,g)}}}),n.cssHooks.marginLeft=Ga(l.reliableMarginLeft,function(a,b){return b?(parseFloat(Fa(a,"marginLeft"))||a.getBoundingClientRect().left-Da(a,{marginLeft:0},function(){return a.getBoundingClientRect().left}))+"px":void 0}),n.cssHooks.marginRight=Ga(l.reliableMarginRight,function(a,b){return b?Da(a,{display:"inline-block"},Fa,[a,"marginRight"]):void 0}),n.each({margin:"",padding:"",border:"Width"},function(a,b){n.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+U[d]+b]=f[d]||f[d-2]||f[0];return e}},Aa.test(a)||(n.cssHooks[a+b].set=Na)}),n.fn.extend({css:function(a,b){return K(this,function(a,b,c){var d,e,f={},g=0;if(n.isArray(b)){for(d=Ca(a),e=b.length;e>g;g++)f[b[g]]=n.css(a,b[g],!1,d);return f}return void 0!==c?n.style(a,b,c):n.css(a,b)},a,b,arguments.length>1)},show:function(){return Qa(this,!0)},hide:function(){return Qa(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){V(this)?n(this).show():n(this).hide()})}});function Ra(a,b,c,d,e){return new Ra.prototype.init(a,b,c,d,e)}n.Tween=Ra,Ra.prototype={constructor:Ra,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||n.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(n.cssNumber[c]?"":"px")},cur:function(){var a=Ra.propHooks[this.prop];return a&&a.get?a.get(this):Ra.propHooks._default.get(this)},run:function(a){var b,c=Ra.propHooks[this.prop];return this.options.duration?this.pos=b=n.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Ra.propHooks._default.set(this),this}},Ra.prototype.init.prototype=Ra.prototype,Ra.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=n.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){n.fx.step[a.prop]?n.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[n.cssProps[a.prop]]&&!n.cssHooks[a.prop]?a.elem[a.prop]=a.now:n.style(a.elem,a.prop,a.now+a.unit)}}},Ra.propHooks.scrollTop=Ra.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},n.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},n.fx=Ra.prototype.init,n.fx.step={};var Sa,Ta,Ua=/^(?:toggle|show|hide)$/,Va=/queueHooks$/;function Wa(){return a.setTimeout(function(){Sa=void 0}),Sa=n.now()}function Xa(a,b){var c,d=0,e={height:a};for(b=b?1:0;4>d;d+=2-b)c=U[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function Ya(a,b,c){for(var d,e=(_a.tweeners[b]||[]).concat(_a.tweeners["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function Za(a,b,c){var d,e,f,g,h,i,j,k,l=this,m={},o=a.style,p=a.nodeType&&V(a),q=N.get(a,"fxshow");c.queue||(h=n._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,l.always(function(){l.always(function(){h.unqueued--,n.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[o.overflow,o.overflowX,o.overflowY],j=n.css(a,"display"),k="none"===j?N.get(a,"olddisplay")||za(a.nodeName):j,"inline"===k&&"none"===n.css(a,"float")&&(o.display="inline-block")),c.overflow&&(o.overflow="hidden",l.always(function(){o.overflow=c.overflow[0],o.overflowX=c.overflow[1],o.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],Ua.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(p?"hide":"show")){if("show"!==e||!q||void 0===q[d])continue;p=!0}m[d]=q&&q[d]||n.style(a,d)}else j=void 0;if(n.isEmptyObject(m))"inline"===("none"===j?za(a.nodeName):j)&&(o.display=j);else{q?"hidden"in q&&(p=q.hidden):q=N.access(a,"fxshow",{}),f&&(q.hidden=!p),p?n(a).show():l.done(function(){n(a).hide()}),l.done(function(){var b;N.remove(a,"fxshow");for(b in m)n.style(a,b,m[b])});for(d in m)g=Ya(p?q[d]:0,d,l),d in q||(q[d]=g.start,p&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function $a(a,b){var c,d,e,f,g;for(c in a)if(d=n.camelCase(c),e=b[d],f=a[c],n.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=n.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function _a(a,b,c){var d,e,f=0,g=_a.prefilters.length,h=n.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=Sa||Wa(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:n.extend({},b),opts:n.extend(!0,{specialEasing:{},easing:n.easing._default},c),originalProperties:b,originalOptions:c,startTime:Sa||Wa(),duration:c.duration,tweens:[],createTween:function(b,c){var d=n.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?(h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j,b])):h.rejectWith(a,[j,b]),this}}),k=j.props;for($a(k,j.opts.specialEasing);g>f;f++)if(d=_a.prefilters[f].call(j,a,k,j.opts))return n.isFunction(d.stop)&&(n._queueHooks(j.elem,j.opts.queue).stop=n.proxy(d.stop,d)),d;return n.map(k,Ya,j),n.isFunction(j.opts.start)&&j.opts.start.call(a,j),n.fx.timer(n.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}n.Animation=n.extend(_a,{tweeners:{"*":[function(a,b){var c=this.createTween(a,b);return W(c.elem,a,T.exec(b),c),c}]},tweener:function(a,b){n.isFunction(a)?(b=a,a=["*"]):a=a.match(G);for(var c,d=0,e=a.length;e>d;d++)c=a[d],_a.tweeners[c]=_a.tweeners[c]||[],_a.tweeners[c].unshift(b)},prefilters:[Za],prefilter:function(a,b){b?_a.prefilters.unshift(a):_a.prefilters.push(a)}}),n.speed=function(a,b,c){var d=a&&"object"==typeof a?n.extend({},a):{complete:c||!c&&b||n.isFunction(a)&&a,duration:a,easing:c&&b||b&&!n.isFunction(b)&&b};return d.duration=n.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in n.fx.speeds?n.fx.speeds[d.duration]:n.fx.speeds._default,null!=d.queue&&d.queue!==!0||(d.queue="fx"),d.old=d.complete,d.complete=function(){n.isFunction(d.old)&&d.old.call(this),d.queue&&n.dequeue(this,d.queue)},d},n.fn.extend({fadeTo:function(a,b,c,d){return this.filter(V).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=n.isEmptyObject(a),f=n.speed(b,c,d),g=function(){var b=_a(this,n.extend({},a),f);(e||N.get(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=n.timers,g=N.get(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&Va.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));!b&&c||n.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=N.get(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=n.timers,g=d?d.length:0;for(c.finish=!0,n.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),n.each(["toggle","show","hide"],function(a,b){var c=n.fn[b];n.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(Xa(b,!0),a,d,e)}}),n.each({slideDown:Xa("show"),slideUp:Xa("hide"),slideToggle:Xa("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){n.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),n.timers=[],n.fx.tick=function(){var a,b=0,c=n.timers;for(Sa=n.now();b<c.length;b++)a=c[b],a()||c[b]!==a||c.splice(b--,1);c.length||n.fx.stop(),Sa=void 0},n.fx.timer=function(a){n.timers.push(a),a()?n.fx.start():n.timers.pop()},n.fx.interval=13,n.fx.start=function(){Ta||(Ta=a.setInterval(n.fx.tick,n.fx.interval))},n.fx.stop=function(){a.clearInterval(Ta),Ta=null},n.fx.speeds={slow:600,fast:200,_default:400},n.fn.delay=function(b,c){return b=n.fx?n.fx.speeds[b]||b:b,c=c||"fx",this.queue(c,function(c,d){var e=a.setTimeout(c,b);d.stop=function(){a.clearTimeout(e)}})},function(){var a=d.createElement("input"),b=d.createElement("select"),c=b.appendChild(d.createElement("option"));a.type="checkbox",l.checkOn=""!==a.value,l.optSelected=c.selected,b.disabled=!0,l.optDisabled=!c.disabled,a=d.createElement("input"),a.value="t",a.type="radio",l.radioValue="t"===a.value}();var ab,bb=n.expr.attrHandle;n.fn.extend({attr:function(a,b){return K(this,n.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){n.removeAttr(this,a)})}}),n.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?n.prop(a,b,c):(1===f&&n.isXMLDoc(a)||(b=b.toLowerCase(),e=n.attrHooks[b]||(n.expr.match.bool.test(b)?ab:void 0)),void 0!==c?null===c?void n.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=n.find.attr(a,b),null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!l.radioValue&&"radio"===b&&n.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(G);if(f&&1===a.nodeType)while(c=f[e++])d=n.propFix[c]||c,n.expr.match.bool.test(c)&&(a[d]=!1),a.removeAttribute(c)}}),ab={set:function(a,b,c){return b===!1?n.removeAttr(a,c):a.setAttribute(c,c),c}},n.each(n.expr.match.bool.source.match(/\w+/g),function(a,b){var c=bb[b]||n.find.attr;bb[b]=function(a,b,d){var e,f;return d||(f=bb[b],bb[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,bb[b]=f),e}});var cb=/^(?:input|select|textarea|button)$/i,db=/^(?:a|area)$/i;n.fn.extend({prop:function(a,b){return K(this,n.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[n.propFix[a]||a]})}}),n.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&n.isXMLDoc(a)||(b=n.propFix[b]||b,e=n.propHooks[b]), 4void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=n.find.attr(a,"tabindex");return b?parseInt(b,10):cb.test(a.nodeName)||db.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),l.optSelected||(n.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),n.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){n.propFix[this.toLowerCase()]=this});var eb=/[\t\r\n\f]/g;function fb(a){return a.getAttribute&&a.getAttribute("class")||""}n.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(n.isFunction(a))return this.each(function(b){n(this).addClass(a.call(this,b,fb(this)))});if("string"==typeof a&&a){b=a.match(G)||[];while(c=this[i++])if(e=fb(c),d=1===c.nodeType&&(" "+e+" ").replace(eb," ")){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=n.trim(d),e!==h&&c.setAttribute("class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(n.isFunction(a))return this.each(function(b){n(this).removeClass(a.call(this,b,fb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(G)||[];while(c=this[i++])if(e=fb(c),d=1===c.nodeType&&(" "+e+" ").replace(eb," ")){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=n.trim(d),e!==h&&c.setAttribute("class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):n.isFunction(a)?this.each(function(c){n(this).toggleClass(a.call(this,c,fb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=n(this),f=a.match(G)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=fb(this),b&&N.set(this,"__className__",b),this.setAttribute&&this.setAttribute("class",b||a===!1?"":N.get(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+fb(c)+" ").replace(eb," ").indexOf(b)>-1)return!0;return!1}});var gb=/\r/g,hb=/[\x20\t\r\n\f]+/g;n.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=n.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,n(this).val()):a,null==e?e="":"number"==typeof e?e+="":n.isArray(e)&&(e=n.map(e,function(a){return null==a?"":a+""})),b=n.valHooks[this.type]||n.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=n.valHooks[e.type]||n.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(gb,""):null==c?"":c)}}}),n.extend({valHooks:{option:{get:function(a){var b=n.find.attr(a,"value");return null!=b?b:n.trim(n.text(a)).replace(hb," ")}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],(c.selected||i===e)&&(l.optDisabled?!c.disabled:null===c.getAttribute("disabled"))&&(!c.parentNode.disabled||!n.nodeName(c.parentNode,"optgroup"))){if(b=n(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=n.makeArray(b),g=e.length;while(g--)d=e[g],(d.selected=n.inArray(n.valHooks.option.get(d),f)>-1)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),n.each(["radio","checkbox"],function(){n.valHooks[this]={set:function(a,b){return n.isArray(b)?a.checked=n.inArray(n(a).val(),b)>-1:void 0}},l.checkOn||(n.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var ib=/^(?:focusinfocus|focusoutblur)$/;n.extend(n.event,{trigger:function(b,c,e,f){var g,h,i,j,l,m,o,p=[e||d],q=k.call(b,"type")?b.type:b,r=k.call(b,"namespace")?b.namespace.split("."):[];if(h=i=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!ib.test(q+n.event.triggered)&&(q.indexOf(".")>-1&&(r=q.split("."),q=r.shift(),r.sort()),l=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=r.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:n.makeArray(c,[b]),o=n.event.special[q]||{},f||!o.trigger||o.trigger.apply(e,c)!==!1)){if(!f&&!o.noBubble&&!n.isWindow(e)){for(j=o.delegateType||q,ib.test(j+q)||(h=h.parentNode);h;h=h.parentNode)p.push(h),i=h;i===(e.ownerDocument||d)&&p.push(i.defaultView||i.parentWindow||a)}g=0;while((h=p[g++])&&!b.isPropagationStopped())b.type=g>1?j:o.bindType||q,m=(N.get(h,"events")||{})[b.type]&&N.get(h,"handle"),m&&m.apply(h,c),m=l&&h[l],m&&m.apply&&L(h)&&(b.result=m.apply(h,c),b.result===!1&&b.preventDefault());return b.type=q,f||b.isDefaultPrevented()||o._default&&o._default.apply(p.pop(),c)!==!1||!L(e)||l&&n.isFunction(e[q])&&!n.isWindow(e)&&(i=e[l],i&&(e[l]=null),n.event.triggered=q,e[q](),n.event.triggered=void 0,i&&(e[l]=i)),b.result}},simulate:function(a,b,c){var d=n.extend(new n.Event,c,{type:a,isSimulated:!0});n.event.trigger(d,null,b)}}),n.fn.extend({trigger:function(a,b){return this.each(function(){n.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?n.event.trigger(a,b,c,!0):void 0}}),n.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){n.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),n.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),l.focusin="onfocusin"in a,l.focusin||n.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){n.event.simulate(b,a.target,n.event.fix(a))};n.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=N.access(d,b);e||d.addEventListener(a,c,!0),N.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=N.access(d,b)-1;e?N.access(d,b,e):(d.removeEventListener(a,c,!0),N.remove(d,b))}}});var jb=a.location,kb=n.now(),lb=/\?/;n.parseJSON=function(a){return JSON.parse(a+"")},n.parseXML=function(b){var c;if(!b||"string"!=typeof b)return null;try{c=(new a.DOMParser).parseFromString(b,"text/xml")}catch(d){c=void 0}return c&&!c.getElementsByTagName("parsererror").length||n.error("Invalid XML: "+b),c};var mb=/#.*$/,nb=/([?&])_=[^&]*/,ob=/^(.*?):[ \t]*([^\r\n]*)$/gm,pb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,qb=/^(?:GET|HEAD)$/,rb=/^\/\//,sb={},tb={},ub="*/".concat("*"),vb=d.createElement("a");vb.href=jb.href;function wb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(G)||[];if(n.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function xb(a,b,c,d){var e={},f=a===tb;function g(h){var i;return e[h]=!0,n.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function yb(a,b){var c,d,e=n.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&n.extend(!0,a,d),a}function zb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Ab(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}n.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:jb.href,type:"GET",isLocal:pb.test(jb.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":ub,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":n.parseJSON,"text xml":n.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?yb(yb(a,n.ajaxSettings),b):yb(n.ajaxSettings,a)},ajaxPrefilter:wb(sb),ajaxTransport:wb(tb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var e,f,g,h,i,j,k,l,m=n.ajaxSetup({},c),o=m.context||m,p=m.context&&(o.nodeType||o.jquery)?n(o):n.event,q=n.Deferred(),r=n.Callbacks("once memory"),s=m.statusCode||{},t={},u={},v=0,w="canceled",x={readyState:0,getResponseHeader:function(a){var b;if(2===v){if(!h){h={};while(b=ob.exec(g))h[b[1].toLowerCase()]=b[2]}b=h[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===v?g:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return v||(a=u[c]=u[c]||a,t[a]=b),this},overrideMimeType:function(a){return v||(m.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>v)for(b in a)s[b]=[s[b],a[b]];else x.always(a[x.status]);return this},abort:function(a){var b=a||w;return e&&e.abort(b),z(0,b),this}};if(q.promise(x).complete=r.add,x.success=x.done,x.error=x.fail,m.url=((b||m.url||jb.href)+"").replace(mb,"").replace(rb,jb.protocol+"//"),m.type=c.method||c.type||m.method||m.type,m.dataTypes=n.trim(m.dataType||"*").toLowerCase().match(G)||[""],null==m.crossDomain){j=d.createElement("a");try{j.href=m.url,j.href=j.href,m.crossDomain=vb.protocol+"//"+vb.host!=j.protocol+"//"+j.host}catch(y){m.crossDomain=!0}}if(m.data&&m.processData&&"string"!=typeof m.data&&(m.data=n.param(m.data,m.traditional)),xb(sb,m,c,x),2===v)return x;k=n.event&&m.global,k&&0===n.active++&&n.event.trigger("ajaxStart"),m.type=m.type.toUpperCase(),m.hasContent=!qb.test(m.type),f=m.url,m.hasContent||(m.data&&(f=m.url+=(lb.test(f)?"&":"?")+m.data,delete m.data),m.cache===!1&&(m.url=nb.test(f)?f.replace(nb,"$1_="+kb++):f+(lb.test(f)?"&":"?")+"_="+kb++)),m.ifModified&&(n.lastModified[f]&&x.setRequestHeader("If-Modified-Since",n.lastModified[f]),n.etag[f]&&x.setRequestHeader("If-None-Match",n.etag[f])),(m.data&&m.hasContent&&m.contentType!==!1||c.contentType)&&x.setRequestHeader("Content-Type",m.contentType),x.setRequestHeader("Accept",m.dataTypes[0]&&m.accepts[m.dataTypes[0]]?m.accepts[m.dataTypes[0]]+("*"!==m.dataTypes[0]?", "+ub+"; q=0.01":""):m.accepts["*"]);for(l in m.headers)x.setRequestHeader(l,m.headers[l]);if(m.beforeSend&&(m.beforeSend.call(o,x,m)===!1||2===v))return x.abort();w="abort";for(l in{success:1,error:1,complete:1})x[l](m[l]);if(e=xb(tb,m,c,x)){if(x.readyState=1,k&&p.trigger("ajaxSend",[x,m]),2===v)return x;m.async&&m.timeout>0&&(i=a.setTimeout(function(){x.abort("timeout")},m.timeout));try{v=1,e.send(t,z)}catch(y){if(!(2>v))throw y;z(-1,y)}}else z(-1,"No Transport");function z(b,c,d,h){var j,l,t,u,w,y=c;2!==v&&(v=2,i&&a.clearTimeout(i),e=void 0,g=h||"",x.readyState=b>0?4:0,j=b>=200&&300>b||304===b,d&&(u=zb(m,x,d)),u=Ab(m,u,x,j),j?(m.ifModified&&(w=x.getResponseHeader("Last-Modified"),w&&(n.lastModified[f]=w),w=x.getResponseHeader("etag"),w&&(n.etag[f]=w)),204===b||"HEAD"===m.type?y="nocontent":304===b?y="notmodified":(y=u.state,l=u.data,t=u.error,j=!t)):(t=y,!b&&y||(y="error",0>b&&(b=0))),x.status=b,x.statusText=(c||y)+"",j?q.resolveWith(o,[l,y,x]):q.rejectWith(o,[x,y,t]),x.statusCode(s),s=void 0,k&&p.trigger(j?"ajaxSuccess":"ajaxError",[x,m,j?l:t]),r.fireWith(o,[x,y]),k&&(p.trigger("ajaxComplete",[x,m]),--n.active||n.event.trigger("ajaxStop")))}return x},getJSON:function(a,b,c){return n.get(a,b,c,"json")},getScript:function(a,b){return n.get(a,void 0,b,"script")}}),n.each(["get","post"],function(a,b){n[b]=function(a,c,d,e){return n.isFunction(c)&&(e=e||d,d=c,c=void 0),n.ajax(n.extend({url:a,type:b,dataType:e,data:c,success:d},n.isPlainObject(a)&&a))}}),n._evalUrl=function(a){return n.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},n.fn.extend({wrapAll:function(a){var b;return n.isFunction(a)?this.each(function(b){n(this).wrapAll(a.call(this,b))}):(this[0]&&(b=n(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this)},wrapInner:function(a){return n.isFunction(a)?this.each(function(b){n(this).wrapInner(a.call(this,b))}):this.each(function(){var b=n(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=n.isFunction(a);return this.each(function(c){n(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){n.nodeName(this,"body")||n(this).replaceWith(this.childNodes)}).end()}}),n.expr.filters.hidden=function(a){return!n.expr.filters.visible(a)},n.expr.filters.visible=function(a){return a.offsetWidth>0||a.offsetHeight>0||a.getClientRects().length>0};var Bb=/%20/g,Cb=/\[\]$/,Db=/\r?\n/g,Eb=/^(?:submit|button|image|reset|file)$/i,Fb=/^(?:input|select|textarea|keygen)/i;function Gb(a,b,c,d){var e;if(n.isArray(b))n.each(b,function(b,e){c||Cb.test(a)?d(a,e):Gb(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==n.type(b))d(a,b);else for(e in b)Gb(a+"["+e+"]",b[e],c,d)}n.param=function(a,b){var c,d=[],e=function(a,b){b=n.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=n.ajaxSettings&&n.ajaxSettings.traditional),n.isArray(a)||a.jquery&&!n.isPlainObject(a))n.each(a,function(){e(this.name,this.value)});else for(c in a)Gb(c,a[c],b,e);return d.join("&").replace(Bb,"+")},n.fn.extend({serialize:function(){return n.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=n.prop(this,"elements");return a?n.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!n(this).is(":disabled")&&Fb.test(this.nodeName)&&!Eb.test(a)&&(this.checked||!X.test(a))}).map(function(a,b){var c=n(this).val();return null==c?null:n.isArray(c)?n.map(c,function(a){return{name:b.name,value:a.replace(Db,"\r\n")}}):{name:b.name,value:c.replace(Db,"\r\n")}}).get()}}),n.ajaxSettings.xhr=function(){try{return new a.XMLHttpRequest}catch(b){}};var Hb={0:200,1223:204},Ib=n.ajaxSettings.xhr();l.cors=!!Ib&&"withCredentials"in Ib,l.ajax=Ib=!!Ib,n.ajaxTransport(function(b){var c,d;return l.cors||Ib&&!b.crossDomain?{send:function(e,f){var g,h=b.xhr();if(h.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(g in b.xhrFields)h[g]=b.xhrFields[g];b.mimeType&&h.overrideMimeType&&h.overrideMimeType(b.mimeType),b.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest");for(g in e)h.setRequestHeader(g,e[g]);c=function(a){return function(){c&&(c=d=h.onload=h.onerror=h.onabort=h.onreadystatechange=null,"abort"===a?h.abort():"error"===a?"number"!=typeof h.status?f(0,"error"):f(h.status,h.statusText):f(Hb[h.status]||h.status,h.statusText,"text"!==(h.responseType||"text")||"string"!=typeof h.responseText?{binary:h.response}:{text:h.responseText},h.getAllResponseHeaders()))}},h.onload=c(),d=h.onerror=c("error"),void 0!==h.onabort?h.onabort=d:h.onreadystatechange=function(){4===h.readyState&&a.setTimeout(function(){c&&d()})},c=c("abort");try{h.send(b.hasContent&&b.data||null)}catch(i){if(c)throw i}},abort:function(){c&&c()}}:void 0}),n.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(a){return n.globalEval(a),a}}}),n.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),n.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(e,f){b=n("<script>").prop({charset:a.scriptCharset,src:a.url}).on("load error",c=function(a){b.remove(),c=null,a&&f("error"===a.type?404:200,a.type)}),d.head.appendChild(b[0])},abort:function(){c&&c()}}}});var Jb=[],Kb=/(=)\?(?=&|$)|\?\?/;n.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=Jb.pop()||n.expando+"_"+kb++;return this[a]=!0,a}}),n.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(Kb.test(b.url)?"url":"string"==typeof b.data&&0===(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&Kb.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=n.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(Kb,"$1"+e):b.jsonp!==!1&&(b.url+=(lb.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||n.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){void 0===f?n(a).removeProp(e):a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,Jb.push(e)),g&&n.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),n.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||d;var e=x.exec(a),f=!c&&[];return e?[b.createElement(e[1])]:(e=ca([a],b,f),f&&f.length&&n(f).remove(),n.merge([],e.childNodes))};var Lb=n.fn.load;n.fn.load=function(a,b,c){if("string"!=typeof a&&Lb)return Lb.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>-1&&(d=n.trim(a.slice(h)),a=a.slice(0,h)),n.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(e="POST"),g.length>0&&n.ajax({url:a,type:e||"GET",dataType:"html",data:b}).done(function(a){f=arguments,g.html(d?n("<div>").append(n.parseHTML(a)).find(d):a)}).always(c&&function(a,b){g.each(function(){c.apply(this,f||[a.responseText,b,a])})}),this},n.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){n.fn[b]=function(a){return this.on(b,a)}}),n.expr.filters.animated=function(a){return n.grep(n.timers,function(b){return a===b.elem}).length};function Mb(a){return n.isWindow(a)?a:9===a.nodeType&&a.defaultView}n.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=n.css(a,"position"),l=n(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=n.css(a,"top"),i=n.css(a,"left"),j=("absolute"===k||"fixed"===k)&&(f+i).indexOf("auto")>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),n.isFunction(b)&&(b=b.call(a,c,n.extend({},h))),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},n.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){n.offset.setOffset(this,a,b)});var b,c,d=this[0],e={top:0,left:0},f=d&&d.ownerDocument;if(f)return b=f.documentElement,n.contains(b,d)?(e=d.getBoundingClientRect(),c=Mb(f),{top:e.top+c.pageYOffset-b.clientTop,left:e.left+c.pageXOffset-b.clientLeft}):e},position:function(){if(this[0]){var a,b,c=this[0],d={top:0,left:0};return"fixed"===n.css(c,"position")?b=c.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),n.nodeName(a[0],"html")||(d=a.offset()),d.top+=n.css(a[0],"borderTopWidth",!0),d.left+=n.css(a[0],"borderLeftWidth",!0)),{top:b.top-d.top-n.css(c,"marginTop",!0),left:b.left-d.left-n.css(c,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent;while(a&&"static"===n.css(a,"position"))a=a.offsetParent;return a||Ea})}}),n.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c="pageYOffset"===b;n.fn[a]=function(d){return K(this,function(a,d,e){var f=Mb(a);return void 0===e?f?f[b]:a[d]:void(f?f.scrollTo(c?f.pageXOffset:e,c?e:f.pageYOffset):a[d]=e)},a,d,arguments.length)}}),n.each(["top","left"],function(a,b){n.cssHooks[b]=Ga(l.pixelPosition,function(a,c){return c?(c=Fa(a,b),Ba.test(c)?n(a).position()[b]+"px":c):void 0})}),n.each({Height:"height",Width:"width"},function(a,b){n.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){n.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return K(this,function(b,c,d){var e;return n.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?n.css(b,c,g):n.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),n.fn.extend({bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)},size:function(){return this.length}}),n.fn.andSelf=n.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return n});var Nb=a.jQuery,Ob=a.$;return n.noConflict=function(b){return a.$===n&&(a.$=Ob),b&&a.jQuery===n&&(a.jQuery=Nb),n},b||(a.jQuery=a.$=n),n});
5/*! 6 * Bootstrap v3.3.7 (http://getbootstrap.com) 7 * Copyright 2011-2017 Twitter, Inc. 8 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 9 */ 10
vendor: 9,207 bytes, lines 11-310
11/*! 12 * Generated using the Bootstrap Customizer (http://getbootstrap.com/customize/?id=6f3f4c2de9461fbc76a0935b8ae1da40) 13 * Config saved to config.json and https://gist.github.com/6f3f4c2de9461fbc76a0935b8ae1da40 14 */ 15if (typeof jQuery === 'undefined') { 16 throw new Error('Bootstrap\'s JavaScript requires jQuery') 17} 18+function ($) { 19 'use strict'; 20 var version = $.fn.jquery.split(' ')[0].split('.') 21 if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1) || (version[0] > 3)) { 22 throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4') 23 } 24}(jQuery); 25 26/* ======================================================================== 27 * Bootstrap: dropdown.js v3.3.7 28 * http://getbootstrap.com/javascript/#dropdowns 29 * ======================================================================== 30 * Copyright 2011-2016 Twitter, Inc. 31 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 32 * ======================================================================== */ 33 34 35+function ($) { 36 'use strict'; 37 38 // DROPDOWN CLASS DEFINITION 39 // ========================= 40 41 var backdrop = '.dropdown-backdrop' 42 var toggle = '[data-toggle="dropdown"]' 43 var Dropdown = function (element) { 44 $(element).on('click.bs.dropdown', this.toggle) 45 } 46 47 Dropdown.VERSION = '3.3.7' 48 49 function getParent($this) { 50 var selector = $this.attr('data-target') 51 52 if (!selector) { 53 selector = $this.attr('href') 54 selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 55 } 56 57 var $parent = selector && $(selector) 58 59 return $parent && $parent.length ? $parent : $this.parent() 60 } 61 62 function clearMenus(e) { 63 if (e && e.which === 3) return 64 $(backdrop).remove() 65 $(toggle).each(function () { 66 var $this = $(this) 67 var $parent = getParent($this) 68 var relatedTarget = { relatedTarget: this } 69 70 if (!$parent.hasClass('open')) return 71 72 if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return 73 74 $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget)) 75 76 if (e.isDefaultPrevented()) return 77 78 $this.attr('aria-expanded', 'false') 79 $parent.removeClass('open').trigger($.Event('hidden.bs.dropdown', relatedTarget)) 80 }) 81 } 82 83 Dropdown.prototype.toggle = function (e) { 84 var $this = $(this) 85 86 if ($this.is('.disabled, :disabled')) return 87 88 var $parent = getParent($this) 89 var isActive = $parent.hasClass('open') 90 91 clearMenus() 92 93 if (!isActive) { 94 if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) { 95 // if mobile we use a backdrop because click events don't delegate 96 $(document.createElement('div')) 97 .addClass('dropdown-backdrop') 98 .insertAfter($(this)) 99 .on('click', clearMenus) 100 } 101 102 var relatedTarget = { relatedTarget: this } 103 $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget)) 104 105 if (e.isDefaultPrevented()) return 106 107 $this 108 .trigger('focus') 109 .attr('aria-expanded', 'true') 110 111 $parent 112 .toggleClass('open') 113 .trigger($.Event('shown.bs.dropdown', relatedTarget)) 114 } 115 116 return false 117 } 118 119 Dropdown.prototype.keydown = function (e) { 120 if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return 121 122 var $this = $(this) 123 124 e.preventDefault() 125 e.stopPropagation() 126 127 if ($this.is('.disabled, :disabled')) return 128 129 var $parent = getParent($this) 130 var isActive = $parent.hasClass('open') 131 132 if (!isActive && e.which != 27 || isActive && e.which == 27) { 133 if (e.which == 27) $parent.find(toggle).trigger('focus') 134 return $this.trigger('click') 135 } 136 137 var desc = ' li:not(.disabled):visible a' 138 var $items = $parent.find('.dropdown-menu' + desc) 139 140 if (!$items.length) return 141 142 var index = $items.index(e.target) 143 144 if (e.which == 38 && index > 0) index-- // up 145 if (e.which == 40 && index < $items.length - 1) index++ // down 146 if (!~index) index = 0 147 148 $items.eq(index).trigger('focus') 149 } 150 151 152 // DROPDOWN PLUGIN DEFINITION 153 // ========================== 154 155 function Plugin(option) { 156 return this.each(function () { 157 var $this = $(this) 158 var data = $this.data('bs.dropdown') 159 160 if (!data) $this.data('bs.dropdown', (data = new Dropdown(this))) 161 if (typeof option == 'string') data[option].call($this) 162 }) 163 } 164 165 var old = $.fn.dropdown 166 167 $.fn.dropdown = Plugin 168 $.fn.dropdown.Constructor = Dropdown 169 170 171 // DROPDOWN NO CONFLICT 172 // ==================== 173 174 $.fn.dropdown.noConflict = function () { 175 $.fn.dropdown = old 176 return this 177 } 178 179 180 // APPLY TO STANDARD DROPDOWN ELEMENTS 181 // =================================== 182 183 $(document) 184 .on('click.bs.dropdown.data-api', clearMenus) 185 .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() }) 186 .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle) 187 .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown) 188 .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown) 189 190}(jQuery); 191 192/* ======================================================================== 193 * Bootstrap: tooltip.js v3.3.7 194 * http://getbootstrap.com/javascript/#tooltip 195 * Inspired by the original jQuery.tipsy by Jason Frame 196 * ======================================================================== 197 * Copyright 2011-2016 Twitter, Inc. 198 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 199 * ======================================================================== */ 200 201 202+function ($) { 203 'use strict'; 204 205 // TOOLTIP PUBLIC CLASS DEFINITION 206 // =============================== 207 208 var Tooltip = function (element, options) { 209 this.type = null 210 this.options = null 211 this.enabled = null 212 this.timeout = null 213 this.hoverState = null 214 this.$element = null 215 this.inState = null 216 217 this.init('tooltip', element, options) 218 } 219 220 Tooltip.VERSION = '3.3.7' 221 222 Tooltip.TRANSITION_DURATION = 150 223 224 Tooltip.DEFAULTS = { 225 animation: true, 226 placement: 'top', 227 selector: false, 228 template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>', 229 trigger: 'hover focus', 230 title: '', 231 delay: 0, 232 html: false, 233 container: false, 234 viewport: { 235 selector: 'body', 236 padding: 0 237 } 238 } 239 240 Tooltip.prototype.init = function (type, element, options) { 241 this.enabled = true 242 this.type = type 243 this.$element = $(element) 244 this.options = this.getOptions(options) 245 this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport)) 246 this.inState = { click: false, hover: false, focus: false } 247 248 if (this.$element[0] instanceof document.constructor && !this.options.selector) { 249 throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!') 250 } 251 252 var triggers = this.options.trigger.split(' ') 253 254 for (var i = triggers.length; i--;) { 255 var trigger = triggers[i] 256 257 if (trigger == 'click') { 258 this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this)) 259 } else if (trigger != 'manual') { 260 var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin' 261 var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout' 262 263 this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this)) 264 this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this)) 265 } 266 } 267 268 this.options.selector ? 269 (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) : 270 this.fixTitle() 271 } 272 273 Tooltip.prototype.getDefaults = function () { 274 return Tooltip.DEFAULTS 275 } 276 277 Tooltip.prototype.getOptions = function (options) { 278 options = $.extend({}, this.getDefaults(), this.$element.data(), options) 279 280 if (options.delay && typeof options.delay == 'number') { 281 options.delay = { 282 show: options.delay, 283 hide: options.delay 284 } 285 } 286 287 return options 288 } 289 290 Tooltip.prototype.getDelegateOptions = function () { 291 var options = {} 292 var defaults = this.getDefaults() 293 294 this._options && $.each(this._options, function (key, value) { 295 if (defaults[key] != value) options[key] = value 296 }) 297 298 return options 299 } 300 301 Tooltip.prototype.enter = function (obj) { 302 var self = obj instanceof this.constructor ? 303 obj : $(obj.currentTarget).data('bs.' + this.type) 304 305 if (!self) { 306 self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) 307 $(obj.currentTarget).data('bs.' + this.type, self) 308 } 309 310 if (obj instanceof $.Event) {
vendor: 9,753 bytes, lines 311-589
311 self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true 312 } 313 314 if (self.tip().hasClass('in') || self.hoverState == 'in') { 315 self.hoverState = 'in' 316 return 317 } 318 319 clearTimeout(self.timeout) 320 321 self.hoverState = 'in' 322 323 if (!self.options.delay || !self.options.delay.show) return self.show() 324 325 self.timeout = setTimeout(function () { 326 if (self.hoverState == 'in') self.show() 327 }, self.options.delay.show) 328 } 329 330 Tooltip.prototype.isInStateTrue = function () { 331 for (var key in this.inState) { 332 if (this.inState[key]) return true 333 } 334 335 return false 336 } 337 338 Tooltip.prototype.leave = function (obj) { 339 var self = obj instanceof this.constructor ? 340 obj : $(obj.currentTarget).data('bs.' + this.type) 341 342 if (!self) { 343 self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) 344 $(obj.currentTarget).data('bs.' + this.type, self) 345 } 346 347 if (obj instanceof $.Event) { 348 self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false 349 } 350 351 if (self.isInStateTrue()) return 352 353 clearTimeout(self.timeout) 354 355 self.hoverState = 'out' 356 357 if (!self.options.delay || !self.options.delay.hide) return self.hide() 358 359 self.timeout = setTimeout(function () { 360 if (self.hoverState == 'out') self.hide() 361 }, self.options.delay.hide) 362 } 363 364 Tooltip.prototype.show = function () { 365 var e = $.Event('show.bs.' + this.type) 366 367 if (this.hasContent() && this.enabled) { 368 this.$element.trigger(e) 369 370 var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0]) 371 if (e.isDefaultPrevented() || !inDom) return 372 var that = this 373 374 var $tip = this.tip() 375 376 var tipId = this.getUID(this.type) 377 378 this.setContent() 379 $tip.attr('id', tipId) 380 this.$element.attr('aria-describedby', tipId) 381 382 if (this.options.animation) $tip.addClass('fade') 383 384 var placement = typeof this.options.placement == 'function' ? 385 this.options.placement.call(this, $tip[0], this.$element[0]) : 386 this.options.placement 387 388 var autoToken = /\s?auto?\s?/i 389 var autoPlace = autoToken.test(placement) 390 if (autoPlace) placement = placement.replace(autoToken, '') || 'top' 391 392 $tip 393 .detach() 394 .css({ top: 0, left: 0, display: 'block' }) 395 .addClass(placement) 396 .data('bs.' + this.type, this) 397 398 this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element) 399 this.$element.trigger('inserted.bs.' + this.type) 400 401 var pos = this.getPosition() 402 var actualWidth = $tip[0].offsetWidth 403 var actualHeight = $tip[0].offsetHeight 404 405 if (autoPlace) { 406 var orgPlacement = placement 407 var viewportDim = this.getPosition(this.$viewport) 408 409 placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top' : 410 placement == 'top' && pos.top - actualHeight < viewportDim.top ? 'bottom' : 411 placement == 'right' && pos.right + actualWidth > viewportDim.width ? 'left' : 412 placement == 'left' && pos.left - actualWidth < viewportDim.left ? 'right' : 413 placement 414 415 $tip 416 .removeClass(orgPlacement) 417 .addClass(placement) 418 } 419 420 var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight) 421 422 this.applyPlacement(calculatedOffset, placement) 423 424 var complete = function () { 425 var prevHoverState = that.hoverState 426 that.$element.trigger('shown.bs.' + that.type) 427 that.hoverState = null 428 429 if (prevHoverState == 'out') that.leave(that) 430 } 431 432 $.support.transition && this.$tip.hasClass('fade') ? 433 $tip 434 .one('bsTransitionEnd', complete) 435 .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : 436 complete() 437 } 438 } 439 440 Tooltip.prototype.applyPlacement = function (offset, placement) { 441 var $tip = this.tip() 442 var width = $tip[0].offsetWidth 443 var height = $tip[0].offsetHeight 444 445 // manually read margins because getBoundingClientRect includes difference 446 var marginTop = parseInt($tip.css('margin-top'), 10) 447 var marginLeft = parseInt($tip.css('margin-left'), 10) 448 449 // we must check for NaN for ie 8/9 450 if (isNaN(marginTop)) marginTop = 0 451 if (isNaN(marginLeft)) marginLeft = 0 452 453 offset.top += marginTop 454 offset.left += marginLeft 455 456 // $.fn.offset doesn't round pixel values 457 // so we use setOffset directly with our own function B-0 458 $.offset.setOffset($tip[0], $.extend({ 459 using: function (props) { 460 $tip.css({ 461 top: Math.round(props.top), 462 left: Math.round(props.left) 463 }) 464 } 465 }, offset), 0) 466 467 $tip.addClass('in') 468 469 // check to see if placing tip in new offset caused the tip to resize itself 470 var actualWidth = $tip[0].offsetWidth 471 var actualHeight = $tip[0].offsetHeight 472 473 if (placement == 'top' && actualHeight != height) { 474 offset.top = offset.top + height - actualHeight 475 } 476 477 var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight) 478 479 if (delta.left) offset.left += delta.left 480 else offset.top += delta.top 481 482 var isVertical = /top|bottom/.test(placement) 483 var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight 484 var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight' 485 486 $tip.offset(offset) 487 this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical) 488 } 489 490 Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) { 491 this.arrow() 492 .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%') 493 .css(isVertical ? 'top' : 'left', '') 494 } 495 496 Tooltip.prototype.setContent = function () { 497 var $tip = this.tip() 498 var title = this.getTitle() 499 500 $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title) 501 $tip.removeClass('fade in top bottom left right') 502 } 503 504 Tooltip.prototype.hide = function (callback) { 505 var that = this 506 var $tip = $(this.$tip) 507 var e = $.Event('hide.bs.' + this.type) 508 509 function complete() { 510 if (that.hoverState != 'in') $tip.detach() 511 if (that.$element) { // TODO: Check whether guarding this code with this `if` is really necessary. 512 that.$element 513 .removeAttr('aria-describedby') 514 .trigger('hidden.bs.' + that.type) 515 } 516 callback && callback() 517 } 518 519 this.$element.trigger(e) 520 521 if (e.isDefaultPrevented()) return 522 523 $tip.removeClass('in') 524 525 $.support.transition && $tip.hasClass('fade') ? 526 $tip 527 .one('bsTransitionEnd', complete) 528 .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : 529 complete() 530 531 this.hoverState = null 532 533 return this 534 } 535 536 Tooltip.prototype.fixTitle = function () { 537 var $e = this.$element 538 if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') { 539 $e.attr('data-original-title', $e.attr('title') || '').attr('title', '') 540 } 541 } 542 543 Tooltip.prototype.hasContent = function () { 544 return this.getTitle() 545 } 546 547 Tooltip.prototype.getPosition = function ($element) { 548 $element = $element || this.$element 549 550 var el = $element[0] 551 var isBody = el.tagName == 'BODY' 552 553 var elRect = el.getBoundingClientRect() 554 if (elRect.width == null) { 555 // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093 556 elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top }) 557 } 558 var isSvg = window.SVGElement && el instanceof window.SVGElement 559 // Avoid using $.offset() on SVGs since it gives incorrect results in jQuery 3. 560 // See https://github.com/twbs/bootstrap/issues/20280 561 var elOffset = isBody ? { top: 0, left: 0 } : (isSvg ? null : $element.offset()) 562 var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() } 563 var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null 564 565 return $.extend({}, elRect, scroll, outerDims, elOffset) 566 } 567 568 Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) { 569 return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } : 570 placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } : 571 placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } : 572 /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width } 573 574 } 575 576 Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) { 577 var delta = { top: 0, left: 0 } 578 if (!this.$viewport) return delta 579 580 var viewportPadding = this.options.viewport && this.options.viewport.padding || 0 581 var viewportDimensions = this.getPosition(this.$viewport) 582 583 if (/right|left/.test(placement)) { 584 var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll 585 var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight 586 if (topEdgeOffset < viewportDimensions.top) { // top overflow 587 delta.top = viewportDimensions.top - topEdgeOffset 588 } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow 589 delta.top = viewportDimensions.top + viewportDimensions.height - bottom
589EdgeOffset 590 } 591 } else { 592 var leftEdgeOffset = pos.left - viewportPadding 593 var rightEdgeOffset = pos.left + viewportPadding + actualWidth 594 if (leftEdgeOffset < viewportDimensions.left) { // left overflow 595 delta.left = viewportDimensions.left - leftEdgeOffset 596 } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow 597 delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset 598 } 599 } 600 601 return delta 602 } 603 604 Tooltip.prototype.getTitle = function () { 605 var title 606 var $e = this.$element 607 var o = this.options 608 609 title = $e.attr('data-original-title') 610 || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title) 611 612 return title 613 } 614 615 Tooltip.prototype.getUID = function (prefix) { 616 do prefix += ~~(Math.random() * 1000000) 617 while (document.getElementById(prefix)) 618 return prefix 619 } 620 621 Tooltip.prototype.tip = function () { 622 if (!this.$tip) { 623 this.$tip = $(this.options.template) 624 if (this.$tip.length != 1) { 625 throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!') 626 } 627 } 628 return this.$tip 629 } 630 631 Tooltip.prototype.arrow = function () { 632 return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow')) 633 } 634 635 Tooltip.prototype.enable = function () { 636 this.enabled = true 637 } 638 639 Tooltip.prototype.disable = function () { 640 this.enabled = false 641 } 642 643 Tooltip.prototype.toggleEnabled = function () { 644 this.enabled = !this.enabled 645 } 646 647 Tooltip.prototype.toggle = function (e) { 648 var self = this 649 if (e) { 650 self = $(e.currentTarget).data('bs.' + this.type) 651 if (!self) { 652 self = new this.constructor(e.currentTarget, this.getDelegateOptions()) 653 $(e.currentTarget).data('bs.' + this.type, self) 654 } 655 } 656 657 if (e) { 658 self.inState.click = !self.inState.click 659 if (self.isInStateTrue()) self.enter(self) 660 else self.leave(self) 661 } else { 662 self.tip().hasClass('in') ? self.leave(self) : self.enter(self) 663 } 664 } 665 666 Tooltip.prototype.destroy = function () { 667 var that = this 668 clearTimeout(this.timeout) 669 this.hide(function () { 670 that.$element.off('.' + that.type).removeData('bs.' + that.type) 671 if (that.$tip) { 672 that.$tip.detach() 673 } 674 that.$tip = null 675 that.$arrow = null 676 that.$viewport = null 677 that.$element = null 678 }) 679 } 680 681 682 // TOOLTIP PLUGIN DEFINITION 683 // ========================= 684 685 function Plugin(option) { 686 return this.each(function () { 687 var $this = $(this) 688 var data = $this.data('bs.tooltip') 689 var options = typeof option == 'object' && option 690 691 if (!data && /destroy|hide/.test(option)) return 692 if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options))) 693 if (typeof option == 'string') data[option]() 694 }) 695 } 696 697 var old = $.fn.tooltip 698 699 $.fn.tooltip = Plugin 700 $.fn.tooltip.Constructor = Tooltip 701 702 703 // TOOLTIP NO CONFLICT 704 // =================== 705 706 $.fn.tooltip.noConflict = function () { 707 $.fn.tooltip = old 708 return this 709 } 710 711}(jQuery); 712 713/** 714 * Featherlight - ultra slim jQuery lightbox 715 * Version 1.7.1 - http://noelboss.github.io/featherlight/ 716 * 717 * Copyright 2017, Noël Raoul Bossart (http://www.noelboss.com) 718 * MIT Licensed. 719**/ 720(function($) { 721 "use strict"; 722 723 if('undefined' === typeof $) { 724 if('console' in window){ window.console.info('Too much lightness, Featherlight needs jQuery.'); } 725 return; 726 } 727 728 /* Featherlight is exported as $.featherlight. 729 It is a function used to open a featherlight lightbox. 730 731 [tech] 732 Featherlight uses prototype inheritance. 733 Each opened lightbox will have a corresponding object. 734 That object may have some attributes that override the 735 prototype's. 736 Extensions created with Featherlight.extend will have their 737 own prototype that inherits from Featherlight's prototype, 738 thus attributes can be overriden either at the object level, 739 or at the extension level. 740 To create callbacks that chain themselves instead of overriding, 741 use chainCallbacks. 742 For those familiar with CoffeeScript, this correspond to 743 Featherlight being a class and the Gallery being a class 744 extending Featherlight. 745 The chainCallbacks is used since we don't have access to 746 CoffeeScript's `super`. 747 */ 748 749 function Featherlight($content, config) { 750 if(this instanceof Featherlight) { /* called with new */ 751 this.id = Featherlight.id++; 752 this.setup($content, config); 753 this.chainCallbacks(Featherlight._callbackChain); 754 } else { 755 var fl = new Featherlight($content, config); 756 fl.open(); 757 return fl; 758 } 759 } 760 761 var opened = [], 762 pruneOpened = function(remove) { 763 opened = $.grep(opened, function(fl) { 764 return fl !== remove && fl.$instance.closest('body').length > 0; 765 } ); 766 return opened; 767 }; 768 769 // Removes keys of `set` from `obj` and returns the removed key/values. 770 function slice(obj, set) { 771 var r = {}; 772 for (var key in obj) { 773 if (key in set) { 774 r[key] = obj[key]; 775 delete obj[key]; 776 } 777 } 778 return r; 779 } 780 781 // NOTE: List of available [iframe attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe). 782 var iFrameAttributeSet = { 783 allowfullscreen: 1, frameborder: 1, height: 1, longdesc: 1, marginheight: 1, marginwidth: 1, 784 name: 1, referrerpolicy: 1, scrolling: 1, sandbox: 1, src: 1, srcdoc: 1, width: 1 785 }; 786 787 // Converts camelCased attributes to dasherized versions for given prefix:
788 // parseAttrs({hello: 1, hellFrozeOver: 2}, 'hell') => {froze-over: 2} 789 function parseAttrs(obj, prefix) { 790 var attrs = {}, 791 regex = new RegExp('^' + prefix + '([A-Z])(.*)'); 792 for (var key in obj) { 793 var match = key.match(regex); 794 if (match) { 795 var dasherized = (match[1] + match[2].replace(/([A-Z])/g, '-$1')).toLowerCase(); 796 attrs[dasherized] = obj[key]; 797 } 798 } 799 return attrs; 800 } 801 802 /* document wide key handler */ 803 var eventMap = { keyup: 'onKeyUp', resize: 'onResize' }; 804 805 var globalEventHandler = function(event) { 806 $.each(Featherlight.opened().reverse(), function() { 807 if (!event.isDefaultPrevented()) { 808 if (false === this[eventMap[event.type]](event)) { 809 event.preventDefault(); event.stopPropagation(); return false; 810 } 811 } 812 }); 813 }; 814 815 var toggleGlobalEvents = function(set) { 816 if(set !== Featherlight._globalHandlerInstalled) { 817 Featherlight._globalHandlerInstalled = set; 818 var events = $.map(eventMap, function(_, name) { return name+'.'+Featherlight.prototype.namespace; } ).join(' '); 819 $(window)[set ? 'on' : 'off'](events, globalEventHandler); 820 } 821 }; 822 823 Featherlight.prototype = { 824 constructor: Featherlight, 825 /*** defaults ***/ 826 /* extend featherlight with defaults and methods */ 827 namespace: 'featherlight', /* Name of the events and css class prefix */ 828 targetAttr: 'data-featherlight', /* Attribute of the triggered element that contains the selector to the lightbox content */ 829 variant: null, /* Class that will be added to change look of the lightbox */ 830 resetCss: false, /* Reset all css */ 831 background: null, /* Custom DOM for the background, wrapper and the closebutton */ 832 openTrigger: 'click', /* Event that triggers the lightbox */ 833 closeTrigger: 'click', /* Event that triggers the closing of the lightbox */ 834 filter: null, /* Selector to filter events. Think $(...).on('click', filter, eventHandler) */ 835 root: 'body', /* Where to append featherlights */ 836 openSpeed: 250, /* Duration of opening animation */ 837 closeSpeed: 250, /* Duration of closing animation */ 838 closeOnClick: 'background', /* Close lightbox on click ('background', 'anywhere' or false) */ 839 closeOnEsc: true, /* Close lightbox when pressing esc */ 840 closeIcon: '✕', /* Close icon */ 841 loading: '', /* Content to show while initial content is loading */ 842 persist: false, /* If set, the content will persist and will be shown again when opened again. 'shared' is a special value when binding multiple elements for them to share the same content */ 843 otherClose: null, /* Selector for alternate close buttons (e.g. "a.close") */ 844 beforeOpen: $.noop, /* Called before open. can return false to prevent opening of lightbox. Gets event as parameter, this contains all data */ 845 beforeContent: $.noop, /* Called when content is loaded. Gets event as parameter, this contains all data */ 846 beforeClose: $.noop, /* Called before close. can return false to prevent opening of lightbox. Gets event as parameter, this contains all data */ 847 afterOpen: $.noop, /* Called after open. Gets event as parameter, this contains all data */ 848 afterContent: $.noop, /* Called after content is ready and has been set. Gets event as parameter, this contains all data */ 849 afterClose: $.noop, /* Called after close. Gets event as parameter, this contains all data */ 850 onKeyUp: $.noop, /* Called on key up for the frontmost featherlight */ 851 onResize: $.noop, /* Called after new content and when a window is resized */ 852 type: null, /* Specify type of lightbox. If unset, it will check for the targetAttrs value. */ 853 contentFilters: ['jquery', 'image', 'html', 'ajax', 'iframe', 'text'], /* List of content filters to use to determine the content */ 854 855 /*** methods ***/ 856 /* setup iterates over a single instance of featherlight and prepares the background and binds the events */ 857 setup: function(target, config){ 858 /* all arguments are optional */ 859 if (typeof target === 'object' && target instanceof $ === false && !config) { 860 config = target; 861 target = undefined; 862 } 863 864 var self = $.extend(this, config, {target: target}), 865 css = !self.resetCss ? self.namespace : self.namespace+'-reset', /* by adding -reset to the classname, we reset all the default css */ 866 $background = $(self.background || [ 867 '<div class="'+css+'-loading '+css+'">', 868 '<div class="'+css+'-content">', 869 '<button class="'+css+'-close-icon '+ self.namespace + '-close" aria-label="Close">', 870 self.closeIcon, 871 '</button>', 872 '<div class="'+self.namespace+'-inner">' + self.loading + '</div>', 873 '</div>', 874 '</div>'].join('')), 875 closeButtonSelector = '.'+self.namespace+'-close' + (self.otherClose ? ',' + self.otherClose : ''); 876 877 self.$instance = $background.clone().addClass(self.variant); /* clone DOM for the background, wrapper and the close button */ 878 879 /* close when click on background/anywhere/null or closebox */ 880 self.$instance.on(self.closeTrigger+'.'+self.namespace, function(event) { 881 var $target = $(event.target); 882 if( ('background' === self.closeOnClick && $target.is('.'+self.namespace)) 883 || 'anywhere' === self.closeOnClick 884 || $target.closest(closeButtonSelector).length ){ 885 self.close(event); 886 event.preventDefault(); 887 } 888 }); 889 890 return this; 891 }, 892
893 /* this method prepares the content and converts it into a jQuery object or a promise */ 894 getContent: function(){ 895 if(this.persist !== false && this.$content) { 896 return this.$content; 897 } 898 var self = this, 899 filters = this.constructor.contentFilters, 900 readTargetAttr = function(name){ return self.$currentTarget && self.$currentTarget.attr(name); }, 901 targetValue = readTargetAttr(self.targetAttr), 902 data = self.target || targetValue || ''; 903 904 /* Find which filter applies */ 905 var filter = filters[self.type]; /* check explicit type like {type: 'image'} */ 906 907 /* check explicit type like data-featherlight="image" */ 908 if(!filter && data in filters) { 909 filter = filters[data]; 910 data = self.target && targetValue; 911 } 912 data = data || readTargetAttr('href') || ''; 913 914 /* check explicity type & content like {image: 'photo.jpg'} */ 915 if(!filter) { 916 for(var filterName in filters) { 917 if(self[filterName]) { 918 filter = filters[filterName]; 919 data = self[filterName]; 920 } 921 } 922 } 923 924 /* otherwise it's implicit, run checks */ 925 if(!filter) { 926 var target = data; 927 data = null; 928 $.each(self.contentFilters, function() { 929 filter = filters[this]; 930 if(filter.test) { 931 data = filter.test(target); 932 } 933 if(!data && filter.regex && target.match && target.match(filter.regex)) { 934 data = target; 935 } 936 return !data; 937 }); 938 if(!data) { 939 if('console' in window){ window.console.error('Featherlight: no content filter found ' + (target ? ' for "' + target + '"' : ' (no target specified)')); } 940 return false; 941 } 942 } 943 /* Process it */ 944 return filter.process.call(self, data); 945 }, 946 947 /* sets the content of $instance to $content */ 948 setContent: function($content){ 949 var self = this; 950 /* we need a special class for the iframe */ 951 if($content.is('iframe')) { 952 self.$instance.addClass(self.namespace+'-iframe'); 953 } 954 955 self.$instance.removeClass(self.namespace+'-loading'); 956 957 /* replace content by appending to existing one before it is removed 958 this insures that featherlight-inner remain at the same relative 959 position to any other items added to featherlight-content */ 960 self.$instance.find('.'+self.namespace+'-inner') 961 .not($content) /* excluded new content, important if persisted */ 962 .slice(1).remove().end() /* In the unexpected event where there are many inner elements, remove all but the first one */ 963 .replaceWith($.contains(self.$instance[0], $content[0]) ? '' : $content); 964 965 self.$content = $content.addClass(self.namespace+'-inner'); 966 967 return self; 968 }, 969 970 /* opens the lightbox. "this" contains $instance with the lightbox, and with the config. 971 Returns a promise that is resolved after is successfully opened. */ 972 open: function(event){ 973 var self = this; 974 self.$instance.hide().appendTo(self.root); 975 if((!event || !event.isDefaultPrevented()) 976 && self.beforeOpen(event) !== false) { 977 978 if(event){ 979 event.preventDefault(); 980 } 981 var $content = self.getContent(); 982 983 if($content) { 984 opened.push(self); 985 986 toggleGlobalEvents(true); 987 988 self.$instance.fadeIn(self.openSpeed); 989 self.beforeContent(event); 990 991 /* Set content and show */ 992 return $.when($content) 993 .always(function($content){ 994 self.setContent($content); 995 self.afterContent(event); 996 }) 997 .then(self.$instance.promise()) 998 /* Call afterOpen after fadeIn is done */ 999 .done(function(){ self.afterOpen(event); }); 1000 } 1001 } 1002 self.$instance.detach(); 1003 return $.Deferred().reject().promise(); 1004 }, 1005 1006 /* closes the lightbox. "this" contains $instance with the lightbox, and with the config 1007 returns a promise, resolved after the lightbox is successfully closed. */ 1008 close: function(event){ 1009 var self = this, 1010 deferred = $.Deferred(); 1011 1012 if(self.beforeClose(event) === false) { 1013 deferred.reject(); 1014 } else { 1015 1016 if (0 === pruneOpened(self).length) { 1017 toggleGlobalEvents(false); 1018 } 1019 1020 self.$instance.fadeOut(self.closeSpeed,function(){ 1021 self.$instance.detach(); 1022 self.afterClose(event); 1023 deferred.resolve(); 1024 }); 1025 } 1026 return deferred.promise(); 1027 }, 1028 1029 /* resizes the content so it fits in visible area and keeps the same aspect ratio. 1030 Does nothing if either the width or the height is not specified. 1031 Called automatically on window resize. 1032 Override if you want different behavior. */ 1033 resize: function(w, h) { 1034 if (w && h) { 1035 /* Reset apparent image size first so container grows */ 1036 this.$content.css('width', '').css('height', ''); 1037 /* Calculate the worst ratio so that dimensions fit */ 1038 /* Note: -1 to avoid rounding errors */ 1039 var ratio = Math.max( 1040 w / (parseInt(this.$content.parent().css('width'),10)-1), 1041 h / (parseInt(this.$content.parent().css('height'),10)-1)); 1042 /* Resize content */ 1043 if (ratio > 1) { 1044 ratio = h / Math.floor(h / ratio); /* Round ratio down so height calc works */ 1045 this.$content.css('width', '' + w / ratio + 'px').css('height', '' + h / ratio + 'px'); 1046 } 1047 } 1048 }, 1049 1050 /* Utility function to chain callbacks 1051 [Warning: guru-level] 1052 Used be extensions that want to let users specify callbacks but 1053 also need themselves to use the callbacks. 1054 The argument 'chain' has callback names as keys and function(super, event) 1055 as values. That function is meant to call `super` at some point. 1056 */
1057 chainCallbacks: function(chain) { 1058 for (var name in chain) { 1059 this[name] = $.proxy(chain[name], this, $.proxy(this[name], this)); 1060 } 1061 } 1062 }; 1063 1064 $.extend(Featherlight, { 1065 id: 0, /* Used to id single featherlight instances */ 1066 autoBind: '[data-featherlight]', /* Will automatically bind elements matching this selector. Clear or set before onReady */ 1067 defaults: Featherlight.prototype, /* You can access and override all defaults using $.featherlight.defaults, which is just a synonym for $.featherlight.prototype */ 1068 /* Contains the logic to determine content */ 1069 contentFilters: { 1070 jquery: { 1071 regex: /^[#.]\w/, /* Anything that starts with a class name or identifiers */ 1072 test: function(elem) { return elem instanceof $ && elem; }, 1073 process: function(elem) { return this.persist !== false ? $(elem) : $(elem).clone(true); } 1074 }, 1075 image: { 1076 regex: /\.(png|jpg|jpeg|gif|tiff|bmp|svg)(\?\S*)?$/i, 1077 process: function(url) { 1078 var self = this, 1079 deferred = $.Deferred(), 1080 img = new Image(), 1081 $img = $('<img src="'+url+'" alt="" class="'+self.namespace+'-image" />'); 1082 img.onload = function() { 1083 /* Store naturalWidth & height for IE8 */ 1084 $img.naturalWidth = img.width; $img.naturalHeight = img.height; 1085 deferred.resolve( $img ); 1086 }; 1087 img.onerror = function() { deferred.reject($img); }; 1088 img.src = url; 1089 return deferred.promise(); 1090 } 1091 }, 1092 html: { 1093 regex: /^\s*<[\w!][^<]*>/, /* Anything that starts with some kind of valid tag */ 1094 process: function(html) { return $(html); } 1095 }, 1096 ajax: { 1097 regex: /./, /* At this point, any content is assumed to be an URL */ 1098 process: function(url) { 1099 var self = this, 1100 deferred = $.Deferred(); 1101 /* we are using load so one can specify a target with: url.html #targetelement */
1102 var $container = $('<div></div>').load(url, function(response, status){ 1103 if ( status !== "error" ) { 1104 deferred.resolve($container.contents()); 1105 } 1106 deferred.fail(); 1107 }); 1108 return deferred.promise(); 1109 } 1110 }, 1111 iframe: { 1112 process: function(url) { 1113 var deferred = new $.Deferred(); 1114 var $content = $('<iframe/>'); 1115 var css = parseAttrs(this, 'iframe'); 1116 var attrs = slice(css, iFrameAttributeSet); 1117 $content.hide() 1118 .attr('src', url) 1119 .attr(attrs) 1120 .css(css) 1121 .on('load', function() { deferred.resolve($content.show()); }) 1122 // We can't move an <iframe> and avoid reloading it, 1123 // so let's put it in place ourselves right now: 1124 .appendTo(this.$instance.find('.' + this.namespace + '-content')); 1125 return deferred.promise(); 1126 } 1127 }, 1128 text: { 1129 process: function(text) { return $('<div>', {text: text}); } 1130 } 1131 }, 1132 1133 functionAttributes: ['beforeOpen', 'afterOpen', 'beforeContent', 'afterContent', 'beforeClose', 'afterClose'], 1134 1135 /*** class methods ***/ 1136 /* read element's attributes starting with data-featherlight- */ 1137 readElementConfig: function(element, namespace) { 1138 var Klass = this, 1139 regexp = new RegExp('^data-' + namespace + '-(.*)'), 1140 config = {}; 1141 if (element && element.attributes) { 1142 $.each(element.attributes, function(){ 1143 var match = this.name.match(regexp); 1144 if (match) { 1145 var val = this.value, 1146 name = $.camelCase(match[1]); 1147 if ($.inArray(name, Klass.functionAttributes) >= 0) { /* jshint -W054 */ 1148 val = new Function(val); /* jshint +W054 */ 1149 } else { 1150 try { val = JSON.parse(val); } 1151 catch(e) {} 1152 } 1153 config[name] = val; 1154 } 1155 }); 1156 } 1157 return config; 1158 }, 1159 1160 /* Used to create a Featherlight extension 1161 [Warning: guru-level] 1162 Creates the extension's prototype that in turn 1163 inherits Featherlight's prototype. 1164 Could be used to extend an extension too... 1165 This is pretty high level wizardy, it comes pretty much straight 1166 from CoffeeScript and won't teach you anything about Featherlight 1167 as it's not really specific to this library. 1168 My suggestion: move along and keep your sanity. 1169 */ 1170 extend: function(child, defaults) { 1171 /* Setup class hierarchy, adapted from CoffeeScript */ 1172 var Ctor = function(){ this.constructor = child; }; 1173 Ctor.prototype = this.prototype; 1174 child.prototype = new Ctor(); 1175 child.__super__ = this.prototype; 1176 /* Copy class methods & attributes */ 1177 $.extend(child, this, defaults); 1178 child.defaults = child.prototype; 1179 return child; 1180 }, 1181 1182 attach: function($source, $content, config) { 1183 var Klass = this; 1184 if (typeof $content === 'object' && $content instanceof $ === false && !config) { 1185 config = $content; 1186 $content = undefined; 1187 } 1188 /* make a copy */ 1189 config = $.extend({}, config); 1190 1191 /* Only for openTrigger and namespace... */ 1192 var namespace = config.namespace || Klass.defaults.namespace, 1193 tempConfig = $.extend({}, Klass.defaults, Klass.readElementConfig($source[0], namespace), config), 1194 sharedPersist; 1195 var handler = function(event) { 1196 /* ... since we might as well compute the config on the actual target */ 1197 var elemConfig = $.extend( 1198 {$source: $source, $currentTarget: $(this)}, 1199 Klass.readElementConfig($source[0], tempConfig.namespace), 1200 Klass.readElementConfig(this, tempConfig.namespace), 1201 config); 1202 var fl = sharedPersist || $(this).data('featherlight-persisted') || new Klass($content, elemConfig); 1203 if(fl.persist === 'shared') { 1204 sharedPersist = fl; 1205 } else if(fl.persist !== false) { 1206 $(this).data('featherlight-persisted', fl); 1207 } 1208 elemConfig.$currentTarget.blur(); // Otherwise 'enter' key might trigger the dialog again 1209 fl.open(event); 1210 }; 1211 1212 $source.on(tempConfig.openTrigger+'.'+tempConfig.namespace, tempConfig.filter, handler); 1213 1214 return handler; 1215 }, 1216 1217 current: function() { 1218 var all = this.opened(); 1219 return all[all.length - 1] || null; 1220 }, 1221 1222 opened: function() { 1223 var klass = this; 1224 pruneOpened(); 1225 return $.grep(opened, function(fl) { return fl instanceof klass; } ); 1226 }, 1227 1228 close: function(event) { 1229 var cur = this.current(); 1230 if(cur) { return cur.close(event); } 1231 }, 1232 1233 /* Does the auto binding on startup. 1234 Meant only to be used by Featherlight and its extensions 1235 */ 1236 _onReady: function() { 1237 var Klass = this; 1238 if(Klass.autoBind){ 1239 /* Bind existing elements */ 1240 $(Klass.autoBind).each(function(){ 1241 Klass.attach($(this)); 1242 }); 1243 /* If a click propagates to the document level, then we have an item that was added later on */ 1244 $(document).on('click', Klass.autoBind, function(evt) { 1245 if (evt.isDefaultPrevented()) { 1246 return; 1247 } 1248 /* Bind featherlight */ 1249 var handler = Klass.attach($(evt.currentTarget)); 1250 /* Dispatch event directly */ 1251 handler(evt); 1252 }); 1253 } 1254 }, 1255 1256 /* Featherlight uses the onKeyUp callback to intercept the escape key. 1257 Private to Featherlight. 1258 */ 1259 _callbackChain: { 1260 onKeyUp: function(_super, event){ 1261 if(27 === event.keyCode) { 1262 if (this.closeOnEsc) { 1263 $.featherlight.close(event); 1264 } 1265 return false;
1266 } else { 1267 return _super(event); 1268 } 1269 }, 1270 1271 beforeOpen: function(_super, event) { 1272 // Remember focus: 1273 this._previouslyActive = document.activeElement; 1274 1275 // Disable tabbing: 1276 // See http://stackoverflow.com/questions/1599660/which-html-elements-can-receive-focus 1277 this._$previouslyTabbable = $("a, input, select, textarea, iframe, button, iframe, [contentEditable=true]") 1278 .not('[tabindex]') 1279 .not(this.$instance.find('button')); 1280 1281 this._$previouslyWithTabIndex = $('[tabindex]').not('[tabindex="-1"]'); 1282 this._previousWithTabIndices = this._$previouslyWithTabIndex.map(function(_i, elem) { 1283 return $(elem).attr('tabindex'); 1284 }); 1285 1286 this._$previouslyWithTabIndex.add(this._$previouslyTabbable).attr('tabindex', -1); 1287 1288 document.activeElement.blur(); 1289 return _super(event); 1290 }, 1291 1292 afterClose: function(_super, event) { 1293 var r = _super(event); 1294 var self = this; 1295 this._$previouslyTabbable.removeAttr('tabindex'); 1296 this._$previouslyWithTabIndex.each(function(i, elem) { 1297 $(elem).attr('tabindex', self._previousWithTabIndices[i]); 1298 }); 1299 this._previouslyActive.focus(); 1300 return r; 1301 }, 1302 1303 onResize: function(_super, event){ 1304 this.resize(this.$content.naturalWidth, this.$content.naturalHeight); 1305 return _super(event); 1306 }, 1307 1308 afterContent: function(_super, event){ 1309 var r = _super(event); 1310 this.$instance.find('[autofocus]:not([disabled])').focus(); 1311 this.onResize(event); 1312 return r; 1313 } 1314 } 1315 }); 1316 1317 $.featherlight = Featherlight; 1318 1319 /* bind jQuery elements to trigger featherlight */ 1320 $.fn.featherlight = function($content, config) { 1321 Featherlight.attach(this, $content, config); 1322 return this; 1323 }; 1324 1325 /* bind featherlight on ready if config autoBind is set */ 1326 $(document).ready(function(){ Featherlight._onReady(); }); 1327}(jQuery)); 1328 1329/** 1330 * Featherlight Gallery – an extension for the ultra slim jQuery lightbox 1331 * Version 1.7.1 - http://noelboss.github.io/featherlight/ 1332 * 1333 * Copyright 2017, Noël Raoul Bossart (http://www.noelboss.com) 1334 * MIT Licensed. 1335**/ 1336(function($) { 1337 "use strict"; 1338 1339 var warn = function(m) { 1340 if(window.console && window.console.warn) { 1341 window.console.warn('FeatherlightGallery: ' + m); 1342 } 1343 }; 1344 1345 if('undefined' === typeof $) { 1346 return warn('Too much lightness, Featherlight needs jQuery.'); 1347 } else if(!$.featherlight) { 1348 return warn('Load the featherlight plugin before the gallery plugin'); 1349 } 1350 1351 var isTouchAware = ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch, 1352 jQueryConstructor = $.event && $.event.special.swipeleft && $, 1353 hammerConstructor = window.Hammer && function($el){ 1354 var mc = new window.Hammer.Manager($el[0]); 1355 mc.add(new window.Hammer.Swipe()); 1356 return mc; 1357 }, 1358 swipeAwareConstructor = isTouchAware && (jQueryConstructor || hammerConstructor); 1359 if(isTouchAware && !swipeAwareConstructor) { 1360 warn('No compatible swipe library detected; one must be included before featherlightGallery for swipe motions to navigate the galleries.'); 1361 } 1362 1363 var callbackChain = { 1364 afterClose: function(_super, event) { 1365 var self = this; 1366 self.$instance.off('next.'+self.namespace+' previous.'+self.namespace); 1367 if (self._swiper) { 1368 self._swiper 1369 .off('swipeleft', self._swipeleft) /* See http://stackoverflow.com/questions/17367198/hammer-js-cant-remove-event-listener */ 1370 .off('swiperight', self._swiperight); 1371 self._swiper = null; 1372 } 1373 return _super(event); 1374 }, 1375 beforeOpen: function(_super, event){ 1376 var self = this; 1377 1378 self.$instance.on('next.'+self.namespace+' previous.'+self.namespace, function(event){ 1379 var offset = event.type === 'next' ? +1 : -1; 1380 self.navigateTo(self.currentNavigation() + offset); 1381 }); 1382 1383 if (swipeAwareConstructor) { 1384 self._swiper = swipeAwareConstructor(self.$instance) 1385 .on('swipeleft', self._swipeleft = function() { self.$instance.trigger('next'); }) 1386 .on('swiperight', self._swiperight = function() { self.$instance.trigger('previous'); }); 1387 1388 self.$instance 1389 .addClass(this.namespace+'-swipe-aware', swipeAwareConstructor); 1390 } 1391 1392 self.$instance.find('.'+self.namespace+'-content') 1393 .append(self.createNavigation('previous')) 1394 .append(self.createNavigation('next')); 1395 1396 return _super(event); 1397 }, 1398 beforeContent: function(_super, event) { 1399 var index = this.currentNavigation(); 1400 var len = this.slides().length; 1401 this.$instance 1402 .toggleClass(this.namespace+'-first-slide', index === 0) 1403 .toggleClass(this.namespace+'-last-slide', index === len - 1); 1404 return _super(event); 1405 }, 1406 onKeyUp: function(_super, event){ 1407 var dir = { 1408 37: 'previous', /* Left arrow */ 1409 39: 'next' /* Rigth arrow */ 1410 }[event.keyCode]; 1411 if(dir) { 1412 this.$instance.trigger(dir); 1413 return false;
1414 } else { 1415 return _super(event); 1416 } 1417 } 1418 }; 1419 1420 function FeatherlightGallery($source, config) { 1421 if(this instanceof FeatherlightGallery) { /* called with new */ 1422 $.featherlight.apply(this, arguments); 1423 this.chainCallbacks(callbackChain); 1424 } else { 1425 var flg = new FeatherlightGallery($.extend({$source: $source, $currentTarget: $source.first()}, config)); 1426 flg.open(); 1427 return flg; 1428 } 1429 } 1430 1431 $.featherlight.extend(FeatherlightGallery, { 1432 autoBind: '[data-featherlight-gallery]' 1433 }); 1434 1435 $.extend(FeatherlightGallery.prototype, { 1436 /** Additional settings for Gallery **/ 1437 previousIcon: '◀', /* Code that is used as previous icon */ 1438 nextIcon: '▶', /* Code that is used as next icon */ 1439 galleryFadeIn: 100, /* fadeIn speed when image is loaded */ 1440 galleryFadeOut: 300, /* fadeOut speed before image is loaded */ 1441 1442 slides: function() { 1443 if (this.filter) { 1444 return this.$source.find(this.filter); 1445 } 1446 return this.$source; 1447 }, 1448 1449 images: function() { 1450 warn('images is deprecated, please use slides instead'); 1451 return this.slides(); 1452 }, 1453 1454 currentNavigation: function() { 1455 return this.slides().index(this.$currentTarget); 1456 }, 1457 1458 navigateTo: function(index) { 1459 var self = this, 1460 source = self.slides(), 1461 len = source.length, 1462 $inner = self.$instance.find('.' + self.namespace + '-inner'); 1463 index = ((index % len) + len) % len; /* pin index to [0, len[ */ 1464 1465 self.$currentTarget = source.eq(index); 1466 self.beforeContent(); 1467 return $.when( 1468 self.getContent(), 1469 $inner.fadeTo(self.galleryFadeOut,0.2) 1470 ).always(function($newContent) { 1471 self.setContent($newContent); 1472 self.afterContent(); 1473 $newContent.fadeTo(self.galleryFadeIn,1); 1474 }); 1475 }, 1476 1477 createNavigation: function(target) { 1478 var self = this; 1479 return $('<span title="'+target+'" class="'+this.namespace+'-'+target+'"><span>'+this[target+'Icon']+'</span></span>').click(function(){ 1480 $(this).trigger(target+'.'+self.namespace); 1481 }); 1482 } 1483 }); 1484 1485 $.featherlightGallery = FeatherlightGallery; 1486 1487 /* extend jQuery with selector featherlight method $(elm).featherlight(config, elm); */ 1488 $.fn.featherlightGallery = function(config) { 1489 FeatherlightGallery.attach(this, config); 1490 return this; 1491 }; 1492 1493 /* bind featherlight on ready if config autoBind is set */ 1494 $(document).ready(function(){ FeatherlightGallery._onReady(); }); 1495 1496}(jQuery)); 1497 1498/** 1499 * @license jquery.panzoom.js v3.2.2 1500 * Updated: Sun Aug 28 2016 1501 * Add pan and zoom functionality to any element 1502 * Copyright (c) timmy willison 1503 * Released under the MIT license 1504 * https://github.com/timmywil/jquery.panzoom/blob/master/MIT-License.txt 1505 */ 1506 1507(function(global, factory) { 1508 // AMD 1509 if (typeof define === 'function' && define.amd) { 1510 define([ 'jquery' ], function(jQuery) { 1511 return factory(global, jQuery); 1512 }); 1513 // CommonJS/Browserify 1514 } else if (typeof exports === 'object') { 1515 factory(global, require('jquery')); 1516 // Global 1517 } else { 1518 factory(global, global.jQuery); 1519 } 1520}(typeof window !== 'undefined' ? window : this, function(window, $) { 1521 'use strict'; 1522 1523 var document = window.document; 1524 var datakey = '__pz__'; 1525 var slice = Array.prototype.slice; 1526 var rIE11 = /trident\/7./i; 1527 var supportsInputEvent = (function() { 1528 // IE11 returns a false positive 1529 if (rIE11.test(navigator.userAgent)) { 1530 return false; 1531 } 1532 var input = document.createElement('input'); 1533 input.setAttribute('oninput', 'return'); 1534 return typeof input.oninput === 'function'; 1535 })(); 1536 1537 // Regex 1538 var rupper = /([A-Z])/g; 1539 var rsvg = /^http:[\w\.\/]+svg$/; 1540 1541 var floating = '(\\-?\\d[\\d\\.e-]*)'; 1542 var commaSpace = '\\,?\\s*'; 1543 var rmatrix = new RegExp( 1544 '^matrix\\(' + 1545 floating + commaSpace + 1546 floating + commaSpace + 1547 floating + commaSpace + 1548 floating + commaSpace + 1549 floating + commaSpace + 1550 floating + '\\)$' 1551 ); 1552 1553 /** 1554 * Utility for determining transform matrix equality 1555 * Checks backwards to test translation first 1556 * @param {Array} first 1557 * @param {Array} second 1558 */ 1559 function matrixEquals(first, second) { 1560 var i = first.length; 1561 while(--i) { 1562 if (Math.round(+first[i]) !== Math.round(+second[i])) { 1563 return false;
1564 } 1565 } 1566 return true; 1567 } 1568 1569 /** 1570 * Creates the options object for reset functions 1571 * @param {Boolean|Object} opts See reset methods 1572 * @returns {Object} Returns the newly-created options object 1573 */ 1574 function createResetOptions(opts) { 1575 var options = { range: true, animate: true }; 1576 if (typeof opts === 'boolean') { 1577 options.animate = opts; 1578 } else { 1579 $.extend(options, opts); 1580 } 1581 return options; 1582 } 1583 1584 /** 1585 * Represent a transformation matrix with a 3x3 matrix for calculations 1586 * Matrix functions adapted from Louis Remi's jQuery.transform (https://github.com/louisremi/jquery.transform.js) 1587 * @param {Array|Number} a An array of six values representing a 2d transformation matrix 1588 */ 1589 function Matrix(a, b, c, d, e, f, g, h, i) { 1590 if ($.type(a) === 'array') { 1591 this.elements = [ 1592 +a[0], +a[2], +a[4], 1593 +a[1], +a[3], +a[5], 1594 0, 0, 1 1595 ]; 1596 } else { 1597 this.elements = [ 1598 a, b, c, 1599 d, e, f, 1600 g || 0, h || 0, i || 1 1601 ]; 1602 } 1603 } 1604 1605 Matrix.prototype = { 1606 /** 1607 * Multiply a 3x3 matrix by a similar matrix or a vector 1608 * @param {Matrix|Vector} matrix 1609 * @return {Matrix|Vector} Returns a vector if multiplying by a vector 1610 */ 1611 x: function(matrix) { 1612 var isVector = matrix instanceof Vector; 1613 1614 var a = this.elements, 1615 b = matrix.elements; 1616 1617 if (isVector && b.length === 3) { 1618 // b is actually a vector 1619 return new Vector( 1620 a[0] * b[0] + a[1] * b[1] + a[2] * b[2], 1621 a[3] * b[0] + a[4] * b[1] + a[5] * b[2], 1622 a[6] * b[0] + a[7] * b[1] + a[8] * b[2] 1623 ); 1624 } else if (b.length === a.length) { 1625 // b is a 3x3 matrix 1626 return new Matrix( 1627 a[0] * b[0] + a[1] * b[3] + a[2] * b[6], 1628 a[0] * b[1] + a[1] * b[4] + a[2] * b[7], 1629 a[0] * b[2] + a[1] * b[5] + a[2] * b[8], 1630 1631 a[3] * b[0] + a[4] * b[3] + a[5] * b[6], 1632 a[3] * b[1] + a[4] * b[4] + a[5] * b[7], 1633 a[3] * b[2] + a[4] * b[5] + a[5] * b[8], 1634 1635 a[6] * b[0] + a[7] * b[3] + a[8] * b[6], 1636 a[6] * b[1] + a[7] * b[4] + a[8] * b[7], 1637 a[6] * b[2] + a[7] * b[5] + a[8] * b[8] 1638 ); 1639 } 1640 return false; // fail 1641 }, 1642 /** 1643 * Generates an inverse of the current matrix 1644 * @returns {Matrix} 1645 */ 1646 inverse: function() { 1647 var d = 1 / this.determinant(), 1648 a = this.elements; 1649 return new Matrix( 1650 d * ( a[8] * a[4] - a[7] * a[5]), 1651 d * (-(a[8] * a[1] - a[7] * a[2])), 1652 d * ( a[5] * a[1] - a[4] * a[2]), 1653 1654 d * (-(a[8] * a[3] - a[6] * a[5])), 1655 d * ( a[8] * a[0] - a[6] * a[2]), 1656 d * (-(a[5] * a[0] - a[3] * a[2])), 1657 1658 d * ( a[7] * a[3] - a[6] * a[4]), 1659 d * (-(a[7] * a[0] - a[6] * a[1])), 1660 d * ( a[4] * a[0] - a[3] * a[1]) 1661 ); 1662 }, 1663 /** 1664 * Calculates the determinant of the current matrix 1665 * @returns {Number} 1666 */ 1667 determinant: function() { 1668 var a = this.elements; 1669 return a[0] * (a[8] * a[4] - a[7] * a[5]) - a[3] * (a[8] * a[1] - a[7] * a[2]) + a[6] * (a[5] * a[1] - a[4] * a[2]); 1670 } 1671 }; 1672 1673 /** 1674 * Create a vector containing three values 1675 */ 1676 function Vector(x, y, z) { 1677 this.elements = [ x, y, z ]; 1678 } 1679 1680 /** 1681 * Get the element at zero-indexed index i 1682 * @param {Number} i 1683 */ 1684 Vector.prototype.e = Matrix.prototype.e = function(i) { 1685 return this.elements[ i ]; 1686 }; 1687 1688 /** 1689 * Create a Panzoom object for a given element 1690 * @constructor 1691 * @param {Element} elem - Element to use pan and zoom 1692 * @param {Object} [options] - An object literal containing options to override default options 1693 * (See Panzoom.defaults for ones not listed below) 1694 * @param {jQuery} [options.$zoomIn] - zoom in buttons/links collection (you can also bind these yourself 1695 * e.g. $button.on('click', function(e) { e.preventDefault(); $elem.panzoom('zoomIn'); });) 1696 * @param {jQuery} [options.$zoomOut] - zoom out buttons/links collection on which to bind zoomOut 1697 * @param {jQuery} [options.$zoomRange] - zoom in/out with this range control 1698 * @param {jQuery} [options.$reset] - Reset buttons/links collection on which to bind the reset method 1699 * @param {Function} [options.on[Start|Change|Zoom|Pan|End|Reset] - Optional callbacks for panzoom events 1700 */ 1701 function Panzoom(elem, options) { 1702 1703 // Allow instantiation without `new` keyword 1704 if (!(this instanceof Panzoom)) { 1705 return new Panzoom(elem, options); 1706 } 1707 1708 // Sanity checks 1709 if (elem.nodeType !== 1) { 1710 $.error('Panzoom called on non-Element node'); 1711 } 1712 if (!$.contains(document, elem)) { 1713 $.error('Panzoom element must be attached to the document'); 1714 } 1715 1716 // Don't remake 1717 var d = $.data(elem, datakey); 1718 if (d) { 1719 return d; 1720 } 1721 1722 // Extend default with given object literal 1723 // Each instance gets its own options 1724 this.options = options = $.extend({}, Panzoom.defaults, options); 1725 this.elem = elem; 1726 var $elem = this.$elem = $(elem); 1727 this.$set = options.$set && options.$set.length ? options.$set : $elem; 1728 this.$doc = $(elem.ownerDocument || document); 1729 this.$parent = $elem.parent(); 1730 this.parent = this.$parent[0]; 1731 1732 // This is SVG if the namespace is SVG 1733 // However, while <svg> elements are SVG, we want to treat those like other elements 1734 this.isSVG = rsvg.test(elem.namespaceURI) && elem.nodeName.toLowerCase() !== 'svg'; 1735 1736 this.panning = false;
1737 1738 // Save the original transform value 1739 // Save the prefixed transform style key 1740 // Set the starting transform 1741 this._buildTransform(); 1742 1743 // Build the appropriately-prefixed transform style property name 1744 // De-camelcase 1745 this._transform = $.cssProps.transform.replace(rupper, '-$1').toLowerCase(); 1746 1747 // Build the transition value 1748 this._buildTransition(); 1749 1750 // Build containment dimensions 1751 this.resetDimensions(); 1752 1753 // Add zoom and reset buttons to `this` 1754 var $empty = $(); 1755 var self = this; 1756 $.each([ '$zoomIn', '$zoomOut', '$zoomRange', '$reset' ], function(i, name) { 1757 self[ name ] = options[ name ] || $empty; 1758 }); 1759 1760 this.enable(); 1761 1762 this.scale = this.getMatrix()[0]; 1763 this._checkPanWhenZoomed(); 1764 1765 // Save the instance 1766 $.data(elem, datakey, this); 1767 } 1768 1769 // Attach regex for possible use (immutable) 1770 Panzoom.rmatrix = rmatrix; 1771 1772 Panzoom.defaults = { 1773 // Should always be non-empty 1774 // Used to bind jQuery events without collisions 1775 // A guid is not added here as different instantiations/versions of panzoom 1776 // on the same element is not supported, so don't do it. 1777 eventNamespace: '.panzoom', 1778 1779 // Whether or not to transition the scale 1780 transition: true, 1781 1782 // Default cursor style for the element 1783 cursor: 'move', 1784 1785 // There may be some use cases for zooming without panning or vice versa 1786 disablePan: false, 1787 disableZoom: false, 1788 1789 // Pan only on the X or Y axes 1790 disableXAxis: false, 1791 disableYAxis: false, 1792 1793 // Set whether you'd like to pan on left (1), middle (2), or right click (3) 1794 which: 1, 1795 1796 // The increment at which to zoom 1797 // Should be a number greater than 0 1798 increment: 0.3, 1799 1800 // When no scale is passed, this option tells 1801 // the `zoom` method to increment 1802 // the scale *linearly* based on the increment option. 1803 // This often ends up looking like very little happened at larger zoom levels. 1804 // The default is to multiply/divide the scale based on the increment. 1805 linearZoom: false, 1806 1807 // Pan only when the scale is greater than minScale 1808 panOnlyWhenZoomed: false, 1809 1810 // min and max zoom scales 1811 minScale: 0.3, 1812 maxScale: 6, 1813 1814 // The default step for the range input 1815 // Precendence: default < HTML attribute < option setting 1816 rangeStep: 0.05, 1817 1818 // Animation duration (ms) 1819 duration: 200, 1820 // CSS easing used for scale transition 1821 easing: 'ease-in-out', 1822 1823 // Indicate that the element should be contained within it's parent when panning 1824 // Note: this does not affect zooming outside of the parent 1825 // Set this value to 'invert' to only allow panning outside of the parent element (basically the opposite of the normal use of contain) 1826 // 'invert' is useful for a large panzoom element where you don't want to show anything behind it 1827 contain: false 1828 }; 1829 1830 Panzoom.prototype = { 1831 constructor: Panzoom, 1832 1833 /** 1834 * @returns {Panzoom} Returns the instance 1835 */ 1836 instance: function() { 1837 return this; 1838 }, 1839 1840 /** 1841 * Enable or re-enable the panzoom instance 1842 */ 1843 enable: function() { 1844 // Unbind first 1845 this._initStyle(); 1846 this._bind(); 1847 this.disabled = false; 1848 }, 1849 1850 /** 1851 * Disable panzoom 1852 */ 1853 disable: function() { 1854 this.disabled = true; 1855 this._resetStyle(); 1856 this._unbind(); 1857 }, 1858 1859 /** 1860 * @returns {Boolean} Returns whether the current panzoom instance is disabled 1861 */ 1862 isDisabled: function() { 1863 return this.disabled; 1864 }, 1865 1866 /** 1867 * Destroy the panzoom instance 1868 */ 1869 destroy: function() { 1870 this.disable(); 1871 $.removeData(this.elem, datakey); 1872 }, 1873 1874 /** 1875 * Builds the restricing dimensions from the containment element 1876 * Also used with focal points 1877 * Call this method whenever the dimensions of the element or parent are changed 1878 */ 1879 resetDimensions: function() { 1880 // Reset container properties 1881 this.container = this.parent.getBoundingClientRect(); 1882 1883 // Set element properties 1884 var elem = this.elem; 1885 // getBoundingClientRect() works with SVG, offsetWidth does not 1886 var dims = elem.getBoundingClientRect(); 1887 var absScale = Math.abs(this.scale); 1888 this.dimensions = { 1889 width: dims.width, 1890 height: dims.height, 1891 left: $.css(elem, 'left', true) || 0, 1892 top: $.css(elem, 'top', true) || 0, 1893 // Borders and margins are scaled 1894 border: { 1895 top: $.css(elem, 'borderTopWidth', true) * absScale || 0, 1896 bottom: $.css(elem, 'borderBottomWidth', true) * absScale || 0, 1897 left: $.css(elem, 'borderLeftWidth', true) * absScale || 0, 1898 right: $.css(elem, 'borderRightWidth', true) * absScale || 0 1899 }, 1900 margin: { 1901 top: $.css(elem, 'marginTop', true) * absScale || 0, 1902 left: $.css(elem, 'marginLeft', true) * absScale || 0 1903 } 1904 }; 1905 }, 1906 1907 /** 1908 * Return the element to it's original transform matrix 1909 * @param {Boolean} [options] If a boolean is passed, animate the reset (default: true). If an options object is passed, simply pass that along to setMatr
1909ix. 1910 * @param {Boolean} [options.silent] Silence the reset event 1911 */ 1912 reset: function(options) { 1913 options = createResetOptions(options); 1914 // Reset the transform to its original value 1915 var matrix = this.setMatrix(this._origTransform, options); 1916 if (!options.silent) { 1917 this._trigger('reset', matrix); 1918 } 1919 }, 1920 1921 /** 1922 * Only resets zoom level 1923 * @param {Boolean|Object} [options] Whether to animate the reset (default: true) or an object of options to pass to zoom() 1924 */ 1925 resetZoom: function(options) { 1926 options = createResetOptions(options); 1927 var origMatrix = this.getMatrix(this._origTransform); 1928 options.dValue = origMatrix[ 3 ]; 1929 this.zoom(origMatrix[0], options); 1930 }, 1931 1932 /** 1933 * Only reset panning 1934 * @param {Boolean|Object} [options] Whether to animate the reset (default: true) or an object of options to pass to pan() 1935 */ 1936 resetPan: function(options) { 1937 var origMatrix = this.getMatrix(this._origTransform); 1938 this.pan(origMatrix[4], origMatrix[5], createResetOptions(options)); 1939 }, 1940 1941 /** 1942 * Sets a transform on the $set 1943 * For SVG, the style attribute takes precedence 1944 * and allows us to animate 1945 * @param {String} transform 1946 */ 1947 setTransform: function(transform) { 1948 var $set = this.$set; 1949 var i = $set.length; 1950 while(i--) { 1951 $.style($set[i], 'transform', transform); 1952
1953 // Support IE9-11, Edge 13-14+ 1954 // Set attribute alongside style attribute 1955 // since IE and Edge do not respect style settings on SVG 1956 // See https://css-tricks.com/transforms-on-svg-elements/ 1957 if (this.isSVG) { 1958 $set[i].setAttribute('transform', transform); 1959 } 1960 } 1961 }, 1962 1963 /** 1964 * Retrieving the transform is different for SVG 1965 * (unless a style transform is already present) 1966 * Uses the $set collection for retrieving the transform 1967 * @param {String} [transform] Pass in an transform value (like 'scale(1.1)') 1968 * to have it formatted into matrix format for use by Panzoom 1969 * @returns {String} Returns the current transform value of the element 1970 */ 1971 getTransform: function(transform) { 1972 var $set = this.$set; 1973 var transformElem = $set[0]; 1974 if (transform) { 1975 this.setTransform(transform); 1976 } else { 1977 1978 // IE and Edge still set the transform style properly 1979 // They just don't render it on SVG 1980 // So we get a correct value here 1981 transform = $.style(transformElem, 'transform'); 1982 1983 if (this.isSVG && (!transform || transform === 'none')) { 1984 transform = $.attr(transformElem, 'transform') || 'none'; 1985 } 1986 } 1987 1988 // Convert any transforms set by the user to matrix format 1989 // by setting to computed 1990 if (transform !== 'none' && !rmatrix.test(transform)) { 1991 1992 // Get computed and set for next time 1993 this.setTransform(transform = $.css(transformElem, 'transform')); 1994 } 1995 1996 return transform || 'none'; 1997 }, 1998 1999 /** 2000 * Retrieve the current transform matrix for $elem (or turn a transform into it's array values) 2001 * @param {String} [transform] matrix-formatted transform value 2002 * @returns {Array} Returns the current transform matrix split up into it's parts, or a default matrix 2003 */ 2004 getMatrix: function(transform) { 2005 var matrix = rmatrix.exec(transform || this.getTransform()); 2006 if (matrix) { 2007 matrix.shift(); 2008 } 2009 return matrix || [ 1, 0, 0, 1, 0, 0 ]; 2010 }, 2011 2012 /** 2013 * Given a matrix object, quickly set the current matrix of the element 2014 * @param {Array|String} matrix 2015 * @param {Object} [options] 2016 * @param {Boolean|String} [options.animate] Whether to animate the transform change, or 'skip' indicating that it is unnecessary to set 2017 * @param {Boolean} [options.contain] Override the global contain option 2018 * @param {Boolean} [options.range] If true, $zoomRange's value will be updated. 2019 * @param {Boolean} [options.silent] If true, the change event will not be triggered 2020 * @returns {Array} Returns the newly-set matrix 2021 */ 2022 setMatrix: function(matrix, options) { 2023 if (this.disabled) { return; } 2024 if (!options) { options = {}; } 2025 // Convert to array 2026 if (typeof matrix === 'string') { 2027 matrix = this.getMatrix(matrix); 2028 } 2029 var scale = +matrix[0]; 2030 var contain = typeof options.contain !== 'undefined' ? options.contain : this.options.contain; 2031 2032 // Apply containment 2033 if (contain) { 2034 var dims = options.dims; 2035 if (!dims) { 2036 this.resetDimensions(); 2037 dims = this.dimensions; 2038 } 2039 var spaceWLeft, spaceWRight, scaleDiff; 2040 var container = this.container; 2041 var width = dims.width; 2042 var height = dims.height; 2043 var conWidth = container.width; 2044 var conHeight = container.height; 2045 var zoomAspectW = conWidth / width; 2046 var zoomAspectH = conHeight / height; 2047 2048 // If the element is not naturally centered, 2049 // assume full space right 2050 if (this.$parent.css('textAlign') !== 'center' || $.css(this.elem, 'display') !== 'inline') { 2051 // offsetWidth gets us the width without the transform 2052 scaleDiff = (width - this.elem.offsetWidth) / 2; 2053 spaceWLeft = scaleDiff - dims.border.left; 2054 spaceWRight = width - conWidth - scaleDiff + dims.border.right; 2055 } else { 2056 spaceWLeft = spaceWRight = ((width - conWidth) / 2); 2057 } 2058 var spaceHTop = ((height - conHeight) / 2) + dims.border.top; 2059 var spaceHBottom = ((height - conHeight) / 2) - dims.border.top - dims.border.bottom; 2060 2061 if (contain === 'invert' || contain === 'automatic' && zoomAspectW < 1.01) { 2062 matrix[4] = Math.max(Math.min(matrix[4], spaceWLeft - dims.border.left), -spaceWRight); 2063 } else { 2064 matrix[4] = Math.min(Math.max(matrix[4], spaceWLeft), -spaceWRight); 2065 } 2066 2067 if (contain === 'invert' || (contain === 'automatic' && zoomAspectH < 1.01)) { 2068 matrix[5] = Math.max(Math.min(matrix[5], spaceHTop - dims.border.top), -spaceHBottom); 2069 } else { 2070 matrix[5] = Math.min(Math.max(matrix[5], spaceHTop), -spaceHBottom); 2071 } 2072 } 2073 2074 // Animate 2075 if (options.animate !== 'skip') { 2076 // Set transition 2077 this.transition(!options.animate); 2078 } 2079 2080 // Update range element 2081 if (options.range) { 2082 this.$zoomRange.val(scale); 2083 } 2084 2085 // Set the matrix on this.$set 2086 if (this.options.disableXAxis || this.options.disableYAxis) { 2087 var originalMatrix = this.getMatrix(); 2088 if (this.options.disableXAxis) { 2089 matrix[4] = originalMatrix[4]; 2090 } 2091 if (this.options.disableYAxis) { 2092 matrix[5] = originalMatrix[5]; 2093 } 2094 } 2095 this.setTransform('matrix(' + matrix.join(',') + ')'); 2096 2097 this.scale = scale; 2098 2099 // Disable/enable panning if zooming is at minimum and panOnlyWhenZoomed is true 2100 this._checkPanWhenZoomed(scale); 2101 2102 if (!options.silent) {
2103 this._trigger('change', matrix); 2104 } 2105 2106 return matrix; 2107 }, 2108 2109 /** 2110 * @returns {Boolean} Returns whether the panzoom element is currently being dragged 2111 */ 2112 isPanning: function() { 2113 return this.panning; 2114 }, 2115 2116 /** 2117 * Apply the current transition to the element, if allowed 2118 * @param {Boolean} [off] Indicates that the transition should be turned off 2119 */ 2120 transition: function(off) { 2121 if (!this._transition) { return; } 2122 var transition = off || !this.options.transition ? 'none' : this._transition; 2123 var $set = this.$set; 2124 var i = $set.length; 2125 while(i--) { 2126 // Avoid reflows when zooming 2127 if ($.style($set[i], 'transition') !== transition) { 2128 $.style($set[i], 'transition', transition); 2129 } 2130 } 2131 }, 2132 2133 /** 2134 * Pan the element to the specified translation X and Y 2135 * Note: this is not the same as setting jQuery#offset() or jQuery#position() 2136 * @param {Number} x 2137 * @param {Number} y 2138 * @param {Object} [options] These options are passed along to setMatrix 2139 * @param {Array} [options.matrix] The matrix being manipulated (if already known so it doesn't have to be retrieved again) 2140 * @param {Boolean} [options.silent] Silence the pan event. Note that this will also silence the setMatrix change event. 2141 * @param {Boolean} [options.relative] Make the x and y values relative to the existing matrix 2142 */ 2143 pan: function(x, y, options) { 2144 if (this.options.disablePan) { return; } 2145 if (!options) { options = {}; } 2146 var matrix = options.matrix; 2147 if (!matrix) { 2148 matrix = this.getMatrix(); 2149 } 2150 // Cast existing matrix values to numbers 2151 if (options.relative) { 2152 x += +matrix[4]; 2153 y += +matrix[5]; 2154 } 2155 matrix[4] = x; 2156 matrix[5] = y; 2157 this.setMatrix(matrix, options); 2158 if (!options.silent) { 2159 this._trigger('pan', matrix[4], matrix[5]); 2160 } 2161 }, 2162 2163 /** 2164 * Zoom in/out the element using the scale properties of a transform matrix 2165 * @param {Number|Boolean} [scale] The scale to which to zoom or a boolean indicating to transition a zoom out 2166 * @param {Object} [opts] All global options can be overwritten by this options object. For example, override the default increment. 2167 * @param {Boolean} [opts.noSetRange] Specify that the method should not set the $zoomRange value (as is the case when $zoomRange is calling zoom on change) 2168 * @param {jQuery.Event|Object} [opts.focal] A focal point on the panzoom element on which to zoom. 2169 * If an object, set the clientX and clientY properties to the position relative to the parent 2170 * @param {Boolean} [opts.animate] Whether to animate the zoom (defaults to true if scale is not a number, false otherwise) 2171 * @param {Boolean} [opts.silent] Silence the zoom event 2172 * @param {Array} [opts.matrix] Optionally pass the current matrix so it doesn't need to be retrieved 2173 * @param {Number} [opts.dValue] Think of a transform matrix as four values a, b, c, d 2174 * where a/d are the horizontal/vertical scale values and b/c are the skew values 2175 * (5 and 6 of matrix array are the tx/ty transform values). 2176 * Normally, the scale is set to both the a and d values of the matrix. 2177 * This option allows you to specify a different d value for the zoom. 2178 * For instance, to flip vertically, you could set -1 as the dValue. 2179 */ 2180 zoom: function(scale, opts) { 2181 // Shuffle arguments 2182 if (typeof scale === 'object') { 2183 opts = scale; 2184 scale = null; 2185 } else if (!opts) { 2186 opts = {}; 2187 } 2188 var options = $.extend({}, this.options, opts); 2189 // Check if disabled 2190 if (options.disableZoom) { return; } 2191 var animate = false; 2192 var matrix = options.matrix || this.getMatrix(); 2193 var startScale = +matrix[0]; 2194 2195 // Calculate zoom based on increment 2196 if (typeof scale !== 'number') { 2197 if (options.linearZoom) { 2198 scale = startScale + (options.increment * (scale ? -1 : 1)); 2199 } else { 2200 scale = scale ? (startScale / (1 + options.increment)) : (startScale * (1 + options.increment)); 2201 } 2202 animate = true; 2203 } 2204 2205 // Constrain scale 2206 scale = Math.max(Math.min(scale, options.maxScale), options.minScale); 2207 2208 // Calculate focal point based on scale 2209 var focal = options.focal; 2210 if (focal && !options.disablePan) { 2211 // Adapted from code by Florian Günther 2212 // https://github.com/florianguenther/zui53 2213 this.resetDimensions(); 2214 var dims = options.dims = this.dimensions; 2215 var clientX = focal.clientX; 2216 var clientY = focal.clientY; 2217 2218 // Adjust the focal point for transform-origin 50% 50% 2219 // SVG elements have a transform origin of 0 0 2220 if (!this.isSVG) { 2221 clientX -= (dims.width / startScale) / 2; 2222 clientY -= (dims.height / startScale) / 2; 2223 } 2224 2225 var clientV = new Vector(clientX, clientY, 1); 2226 var surfaceM = new Matrix(matrix); 2227 // Supply an offset manually if necessary 2228 var o = this.parentOffset || this.$parent.offset(); 2229 var offsetM = new Matrix(1, 0, o.left - this.$doc.scrollLeft(), 0, 1, o.top - this.$doc.scrollTop()); 2230 var surfaceV = surfaceM.inverse().x(offsetM.inverse().x(clientV)); 2231 var scaleBy = scale / matrix[0]; 2232 surfaceM = surfaceM.x(new Matrix([scaleBy, 0, 0, scaleBy, 0, 0])); 2233 clientV = offsetM.x(surfaceM.x(surfaceV));
2234 matrix[4] = +matrix[4] + (clientX - clientV.e(0)); 2235 matrix[5] = +matrix[5] + (clientY - clientV.e(1)); 2236 } 2237 2238 // Set the scale 2239 matrix[0] = scale; 2240 matrix[3] = typeof options.dValue === 'number' ? options.dValue : scale; 2241 2242 // Calling zoom may still pan the element 2243 this.setMatrix(matrix, { 2244 animate: typeof options.animate !== 'undefined' ? options.animate : animate, 2245 // Set the zoomRange value 2246 range: !options.noSetRange 2247 }); 2248 2249 // Trigger zoom event 2250 if (!options.silent) { 2251 this._trigger('zoom', matrix[0], options); 2252 } 2253 }, 2254 2255 /** 2256 * Get/set option on an existing instance 2257 * @returns {Array|undefined} If getting, returns an array of all values 2258 * on each instance for a given key. If setting, continue chaining by returning undefined. 2259 */ 2260 option: function(key, value) { 2261 var options; 2262 if (!key) { 2263 // Avoids returning direct reference 2264 return $.extend({}, this.options); 2265 } 2266 2267 if (typeof key === 'string') { 2268 if (arguments.length === 1) { 2269 return this.options[ key ] !== undefined ? 2270 this.options[ key ] : 2271 null; 2272 } 2273 options = {}; 2274 options[ key ] = value; 2275 } else { 2276 options = key; 2277 } 2278 2279 this._setOptions(options); 2280 }, 2281 2282 /** 2283 * Internally sets options 2284 * @param {Object} options - An object literal of options to set 2285 * @private 2286 */ 2287 _setOptions: function(options) { 2288 $.each(options, $.proxy(function(key, value) { 2289 switch(key) { 2290 case 'disablePan': 2291 this._resetStyle(); 2292 /* falls through */ 2293 case '$zoomIn': 2294 case '$zoomOut': 2295 case '$zoomRange': 2296 case '$reset': 2297 case 'disableZoom': 2298 case 'onStart': 2299 case 'onChange': 2300 case 'onZoom': 2301 case 'onPan': 2302 case 'onEnd': 2303 case 'onReset': 2304 case 'eventNamespace': 2305 this._unbind(); 2306 } 2307 this.options[ key ] = value; 2308 switch(key) { 2309 case 'disablePan': 2310 this._initStyle(); 2311 /* falls through */ 2312 case '$zoomIn': 2313 case '$zoomOut': 2314 case '$zoomRange': 2315 case '$reset': 2316 // Set these on the instance 2317 this[ key ] = value; 2318 /* falls through */ 2319 case 'disableZoom': 2320 case 'onStart': 2321 case 'onChange': 2322 case 'onZoom': 2323 case 'onPan': 2324 case 'onEnd': 2325 case 'onReset': 2326 case 'eventNamespace': 2327 this._bind(); 2328 break; 2329 case 'cursor':
2330 $.style(this.elem, 'cursor', value); 2331 break; 2332 case 'minScale': 2333 this.$zoomRange.attr('min', value); 2334 break; 2335 case 'maxScale': 2336 this.$zoomRange.attr('max', value); 2337 break; 2338 case 'rangeStep': 2339 this.$zoomRange.attr('step', value); 2340 break; 2341 case 'startTransform': 2342 this._buildTransform(); 2343 break; 2344 case 'duration': 2345 case 'easing': 2346 this._buildTransition(); 2347 /* falls through */ 2348 case 'transition': 2349 this.transition(); 2350 break; 2351 case 'panOnlyWhenZoomed': 2352 this._checkPanWhenZoomed(); 2353 break; 2354 case '$set': 2355 if (value instanceof $ && value.length) { 2356 this.$set = value; 2357 // Reset styles 2358 this._initStyle(); 2359 this._buildTransform(); 2360 } 2361 } 2362 }, this)); 2363 }, 2364 2365 /** 2366 * Disable/enable panning depending on whether the current scale 2367 * matches the minimum 2368 * @param {Number} [scale] 2369 * @private 2370 */ 2371 _checkPanWhenZoomed: function(scale) { 2372 var options = this.options; 2373 if (options.panOnlyWhenZoomed) { 2374 if (!scale) { 2375 scale = this.getMatrix()[0]; 2376 } 2377 var toDisable = scale <= options.minScale; 2378 if (options.disablePan !== toDisable) { 2379 this.option('disablePan', toDisable); 2380 } 2381 } 2382 }, 2383 2384 /** 2385 * Initialize base styles for the element and its parent 2386 * @private 2387 */ 2388 _initStyle: function() { 2389 var styles = { 2390 // Set the same default whether SVG or HTML 2391 // transform-origin cannot be changed to 50% 50% in IE9-11 or Edge 13-14+ 2392 'transform-origin': this.isSVG ? '0 0' : '50% 50%' 2393 }; 2394 // Set elem styles 2395 if (!this.options.disablePan) { 2396 styles.cursor = this.options.cursor; 2397 } 2398 this.$set.css(styles); 2399 2400 // Set parent to relative if set to static 2401 var $parent = this.$parent; 2402 // No need to add styles to the body 2403 if ($parent.length && !$.nodeName(this.parent, 'body')) { 2404 styles = { 2405 overflow: 'hidden' 2406 }; 2407 if ($parent.css('position') === 'static') { 2408 styles.position = 'relative'; 2409 } 2410 $parent.css(styles); 2411 } 2412 }, 2413 2414 /** 2415 * Undo any styles attached in this plugin 2416 * @private 2417 */ 2418 _resetStyle: function() { 2419 this.$elem.css({ 2420 'cursor': '', 2421 'transition': '' 2422 }); 2423 this.$parent.css({ 2424 'overflow': '', 2425 'position': '' 2426 }); 2427 }, 2428 2429 /** 2430 * Binds all necessary events 2431 * @private 2432 */ 2433 _bind: function() { 2434 var self = this; 2435 var options = this.options; 2436 var ns = options.eventNamespace; 2437 var str_down = 'mousedown' + ns + ' pointerdown' + ns + ' MSPointerDown' + ns; 2438 var str_start = 'touchstart' + ns + ' ' + str_down; 2439 var str_click = 'touchend' + ns + ' click' + ns + ' pointerup' + ns + ' MSPointerUp' + ns; 2440 var events = {}; 2441 var $reset = this.$reset; 2442 var $zoomRange = this.$zoomRange; 2443 2444 // Bind panzoom events from options 2445 $.each([ 'Start', 'Change', 'Zoom', 'Pan', 'End', 'Reset' ], function() { 2446 var m = options[ 'on' + this ]; 2447 if ($.isFunction(m)) { 2448 events[ 'panzoom' + this.toLowerCase() + ns ] = m; 2449 } 2450 }); 2451 2452 // Bind $elem drag and click/touchdown events 2453 // Bind touchstart if either panning or zooming is enabled 2454 if (!options.disablePan || !options.disableZoom) { 2455 events[ str_start ] = function(e) { 2456 var touches; 2457 if (e.type === 'touchstart' ? 2458 // Touch 2459 (touches = e.touches || e.originalEvent.touches) && 2460 ((touches.length === 1 && !options.disablePan) || touches.length === 2) : 2461 // Mouse/Pointer: Ignore unexpected click types 2462 // Support: IE10 only 2463 // IE10 does not support e.button for MSPointerDown, but does have e.which 2464 !options.disablePan && (e.which || e.originalEvent.which) === options.which) { 2465 2466 e.preventDefault(); 2467 e.stopPropagation(); 2468 self._startMove(e, touches); 2469 } 2470 }; 2471 // Prevent the contextmenu event 2472 // if we're binding to right-click 2473 if (options.which === 3) { 2474 events.contextmenu = false; 2475 } 2476 } 2477 this.$elem.on(events); 2478 2479 // Bind reset 2480 if ($reset.length) { 2481 $reset.on(str_click, function(e) { 2482 e.preventDefault(); 2483 self.reset(); 2484 }); 2485 } 2486 2487 // Set default attributes for the range input 2488 if ($zoomRange.length) { 2489 $zoomRange.attr({ 2490 // Only set the range step if explicit or 2491 // set the default if there is no attribute present 2492 step: options.rangeStep === Panzoom.defaults.rangeStep && 2493 $zoomRange.attr('step') || 2494 options.rangeStep, 2495 min: options.minScale,
2496 max: options.maxScale 2497 }).prop({ 2498 value: this.getMatrix()[0] 2499 }); 2500 } 2501 2502 // No bindings if zooming is disabled 2503 if (options.disableZoom) { 2504 return; 2505 } 2506 2507 var $zoomIn = this.$zoomIn; 2508 var $zoomOut = this.$zoomOut; 2509 2510 // Bind zoom in/out 2511 // Don't bind one without the other 2512 if ($zoomIn.length && $zoomOut.length) { 2513 // preventDefault cancels future mouse events on touch events 2514 $zoomIn.on(str_click, function(e) { 2515 e.preventDefault(); 2516 self.zoom(); 2517 }); 2518 $zoomOut.on(str_click, function(e) { 2519 e.preventDefault(); 2520 self.zoom(true); 2521 }); 2522 } 2523 2524 if ($zoomRange.length) { 2525 events = {}; 2526 // Cannot prevent default action here 2527 events[ str_down ] = function() { 2528 self.transition(true); 2529 }; 2530 // Zoom on input events if available and change events 2531 // See https://github.com/timmywil/jquery.panzoom/issues/90 2532 events[ (supportsInputEvent ? 'input' : 'change') + ns ] = function() { 2533 self.zoom(+this.value, { noSetRange: true }); 2534 }; 2535 $zoomRange.on(events); 2536 } 2537 }, 2538 2539 /** 2540 * Unbind all events 2541 * @private 2542 */ 2543 _unbind: function() { 2544 this.$elem 2545 .add(this.$zoomIn) 2546 .add(this.$zoomOut) 2547 .add(this.$reset) 2548 .off(this.options.eventNamespace); 2549 }, 2550 2551 /** 2552 * Builds the original transform value 2553 * @private 2554 */ 2555 _buildTransform: function() { 2556 // Save the original transform 2557 // Retrieving this also adds the correct prefixed style name 2558 // to jQuery's internal $.cssProps 2559 return this._origTransform = this.getTransform(this.options.startTransform); 2560 }, 2561 2562 /** 2563 * Set transition property for later use when zooming 2564 * @private 2565 */ 2566 _buildTransition: function() { 2567 if (this._transform) { 2568 var options = this.options; 2569 this._transition = this._transform + ' ' + options.duration + 'ms ' + options.easing; 2570 } 2571 }, 2572 2573 /** 2574 * Calculates the distance between two touch points 2575 * Remember pythagorean? 2576 * @param {Array} touches 2577 * @returns {Number} Returns the distance 2578 * @private 2579 */ 2580 _getDistance: function(touches) { 2581 var touch1 = touches[0]; 2582 var touch2 = touches[1]; 2583 return Math.sqrt(Math.pow(Math.abs(touch2.clientX - touch1.clientX), 2) + Math.pow(Math.abs(touch2.clientY - touch1.clientY), 2)); 2584 }, 2585 2586 /** 2587 * Constructs an approximated point in the middle of two touch points 2588 * @returns {Object}
2588 Returns an object containing pageX and pageY 2589 * @private 2590 */ 2591 _getMiddle: function(touches) { 2592 var touch1 = touches[0]; 2593 var touch2 = touches[1]; 2594 return { 2595 clientX: ((touch2.clientX - touch1.clientX) / 2) + touch1.clientX, 2596 clientY: ((touch2.clientY - touch1.clientY) / 2) + touch1.clientY 2597 }; 2598 }, 2599 2600 /** 2601 * Trigger a panzoom event on our element 2602 * The event is passed the Panzoom instance 2603 * @param {String|jQuery.Event} event 2604 * @param {Mixed} arg1[, arg2, arg3, ...] Arguments to append to the trigger 2605 * @private 2606 */ 2607 _trigger: function (event) { 2608 if (typeof event === 'string') { 2609 event = 'panzoom' + event; 2610 } 2611 this.$elem.triggerHandler(event, [this].concat(slice.call(arguments, 1))); 2612 }, 2613 2614 /** 2615 * Starts the pan 2616 * This is bound to mouse/touchmove on the element 2617 * @param {jQuery.Event} event An event with pageX, pageY, and possibly the touches list 2618 * @param {TouchList} [touches] The touches list if present 2619 * @private 2620 */ 2621 _startMove: function(event, touches) { 2622 if (this.panning) { 2623 return; 2624 } 2625 var moveEvent, endEvent, 2626 startDistance, startScale, startMiddle, 2627 startPageX, startPageY, touch; 2628 var self = this; 2629 var options = this.options; 2630 var ns = options.eventNamespace; 2631 var matrix = this.getMatrix(); 2632 var original = matrix.slice(0); 2633 var origPageX = +original[4]; 2634 var origPageY = +original[5]; 2635 var panOptions = { matrix: matrix, animate: 'skip' }; 2636 var type = event.type; 2637 2638 // Use proper events 2639 if (type === 'pointerdown') { 2640 moveEvent = 'pointermove'; 2641 endEvent = 'pointerup'; 2642 } else if (type === 'touchstart') { 2643 moveEvent = 'touchmove'; 2644 endEvent = 'touchend'; 2645 } else if (type === 'MSPointerDown') { 2646 moveEvent = 'MSPointerMove'; 2647 endEvent = 'MSPointerUp'; 2648 } else { 2649 moveEvent = 'mousemove'; 2650 endEvent = 'mouseup'; 2651 } 2652 2653 // Add namespace 2654 moveEvent += ns; 2655 endEvent += ns; 2656 2657 // Remove any transitions happening 2658 this.transition(true); 2659 2660 // Indicate that we are currently panning 2661 this.panning = true; 2662 2663 // Trigger start event 2664 this._trigger('start', event, touches); 2665 2666 var setStart = function(event, touches) { 2667 if (touches) { 2668 if (touches.length === 2) { 2669 if (startDistance != null) { 2670 return; 2671 } 2672 startDistance = self._getDistance(touches); 2673 startScale = +matrix[0]; 2674 startMiddle = self._getMiddle(touches); 2675 return; 2676 } 2677 if (startPageX != null) { 2678 return; 2679 } 2680 if ((touch = touches[0])) { 2681 startPageX = touch.pageX; 2682 startPageY = touch.pageY; 2683 } 2684 } 2685 if (startPageX != null) { 2686 return; 2687 } 2688 startPageX = event.pageX; 2689 startPageY = event.pageY; 2690 }; 2691 2692 setStart(event, touches); 2693 2694 var move = function(e) { 2695 var coords; 2696 e.preventDefault(); 2697 touches = e.touches || e.originalEvent.touches; 2698 setStart(e, touches); 2699 2700 if (touches) { 2701 if (touches.length === 2) { 2702 2703 // Calculate move on middle point 2704 var middle = self._getMiddle(touches); 2705 var diff = self._getDistance(touches) - startDistance; 2706 2707 // Set zoom 2708 self.zoom(diff * (options.increment / 100) + startScale, { 2709 focal: middle, 2710 matrix: matrix, 2711 animate: 'skip' 2712 }); 2713 2714 // Set pan 2715 self.pan( 2716 +matrix[4] + middle.clientX - startMiddle.clientX, 2717 +matrix[5] + middle.clientY - startMiddle.clientY, 2718 panOptions 2719 ); 2720 startMiddle = middle; 2721 return; 2722 } 2723 coords = touches[0] || { pageX: 0, pageY: 0 }; 2724 } 2725 2726 if (!coords) { 2727 coords = e; 2728 } 2729 2730 self.pan(
2731 origPageX + coords.pageX - startPageX, 2732 origPageY + coords.pageY - startPageY, 2733 panOptions 2734 ); 2735 }; 2736 2737 // Bind the handlers 2738 $(document) 2739 .off(ns) 2740 .on(moveEvent, move) 2741 .on(endEvent, function(e) { 2742 e.preventDefault(); 2743 // Unbind all document events 2744 $(this).off(ns); 2745 self.panning = false; 2746 // Trigger our end event 2747 // Simply set the type to "panzoomend" to pass through all end properties 2748 // jQuery's `not` is used here to compare Array equality 2749 e.type = 'panzoomend'; 2750 self._trigger(e, matrix, !matrixEquals(matrix, original)); 2751 }); 2752 } 2753 }; 2754 2755 // Add Panzoom as a static property 2756 $.Panzoom = Panzoom; 2757 2758 /** 2759 * Extend jQuery 2760 * @param {Object|String} options - The name of a method to call on the prototype 2761 * or an object literal of options 2762 * @returns {jQuery|Mixed} jQuery instance for regular chaining or the return value(s) of a panzoom method call 2763 */ 2764 $.fn.panzoom = function(options) { 2765 var instance, args, m, ret; 2766 2767 // Call methods widget-style 2768 if (typeof options === 'string') { 2769 ret = []; 2770 args = slice.call(arguments, 1); 2771 this.each(function() { 2772 instance = $.data(this, datakey); 2773 2774 if (!instance) { 2775 ret.push(undefined); 2776 2777 // Ignore methods beginning with `_` 2778 } else if (options.charAt(0) !== '_' && 2779 typeof (m = instance[ options ]) === 'function' && 2780 // If nothing is returned, do not add to return values 2781 (m = m.apply(instance, args)) !== undefined) { 2782 2783 ret.push(m); 2784 } 2785 }); 2786 2787 // Return an array of values for the jQuery instances 2788 // Or the value itself if there is only one 2789 // Or keep chaining 2790 return ret.length ? 2791 (ret.length === 1 ? ret[0] : ret) : 2792 this; 2793 } 2794 2795 return this.each(function() { new Panzoom(this, options); }); 2796 }; 2797 2798 return Panzoom; 2799})); 2800/* 2801 _ _ _ _ 2802 ___| (_) ___| | __ (_)___ 2803/ __| | |/ __| |/ / | / __| 2804\__ \ | | (__| < _ | \__ \ 2805|___/_|_|\___|_|\_(_)/ |___/ 2806 |__/ 2807 2808 Version: 1.6.0 2809 Author: Ken Wheeler 2810 Website: http://kenwheeler.github.io 2811 Docs: http://kenwheeler.github.io/slick 2812 Repo: http://github.com/kenwheeler/slick 2813 Issues: http://github.com/kenwheeler/slick/issues 2814 2815 */ 2816!function(a){"use strict";"function"==typeof define&&define.amd?define(["jquery"],a):"undefined"!=typeof exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){"use strict";var b=window.Slick||{};b=function(){function c(c,d){var f,e=this;e.defaults={accessibility:!0,adaptiveHeight:!1,appendArrows:a(c),appendDots:a(c),arrows:!0,asNavFor:null,prevArrow:'<button type="button" data-role="none" class="slick-prev" aria-label="Previous" tabindex="0" role="button">Previous</button>',nextArrow:'<button type="button" data-role="none" class="slick-next" aria-label="Next" tabindex="0" role="button">Next</button>',autoplay:!1,autoplaySpeed:3e3,centerMode:!1,centerPadding:"50px",cssEase:"ease",customPaging:function(b,c){return a('<button type="button" data-role="none" role="button" tabindex="0" />').text(c+1)},dots:!1,dotsClass:"slick-dots",draggable:!0,easing:"linear",edgeFriction:.35,fade:!1,focusOnSelect:!1,infinite:!0,initialSlide:0,lazyLoad:"ondemand",mobileFirst:!1,pauseOnHover:!0,pauseOnFocus:!0,pauseOnDotsHover:!1,respondTo:"window",responsive:null,rows:1,rtl:!1,slide:"",slidesPerRow:1,slidesToShow:1,slidesToScroll:1,speed:500,swipe:!0,swipeToSlide:!1,touchMove:!0,touchThreshold:5,useCSS:!0,useTransform:!0,variableWidth:!1,vertical:!1,verticalSwiping:!1,waitForAnimate:!0,zIndex:1e3},e.initials={animating:!1,dragging:!1,autoPlayTimer:null,currentDirection:0,currentLeft:null,currentSlide:0,direction:1,$dots:null,listWidth:null,listHeight:null,loadIndex:0,$nextArrow:null,$prevArrow:null,slideCount:null,slideWidth:null,$slideTrack:null,$slides:null,sliding:!1,slideOffset:0,swipeLeft:null,$list:null,touchObject:{},transformsEnabled:!1,unslicked:!1},a.extend(e,e.initials),e.activeBreakpoint=null,e.animType=null,e.animProp=null,e.breakpoints=[],e.breakpointSettings=[],e.cssTransitions=!1,e.focussed=!1,e.interrupted=!1,e.hidden="hidden",e.paused=!0,e.positionProp=null,e.respondTo=null,e.rowCount=1,e.shouldClick=!0,e.$slider=a(c),e.$slidesCache=null,e.transformType=null,e.transitionType=null,e.visibilityChange="visibilitychange",e.windowWidth=0,e.windowTimer=null,f=a(c).data("slick")||{},e.options=a.extend({},e.defaults,d,f),e.currentSlide=e.options.initialSlide,e.originalSettings=e.options,"undefined"!=typeof document.mozHidden?(e.hidden="mozHidden",e.visibilityChange="mozvisibilitychange"):"undefined"!=typeof document.webkitHidden&&(e.hidden="webkitHidden",e.visibilityChange="webkitvisibilitychange"),e.autoPlay=a.proxy(e.autoPlay,e),e.autoPlayClear=a.proxy(e.autoPlayClear,e),e.autoPlayIterator=a.proxy(e.autoPlayIterator,e),e.changeSlide=a.proxy(e.changeSlide,e),e.clickHandler=a.proxy(e.clickHandler,e),e.selectHandler=a.proxy(e.selectHandler,e),e.setPosition=a.proxy(e.setPosition,e),e.swipeHandler=a.proxy(e.swipeHandler,e),e.dragHandler=a.proxy(e.dragHandler,e),e.keyHandler=a.proxy(e.keyHandler,e),e.instanceUid=b++,e.htmlExpr=/^(?:\s*(<[\w\W]+>)[^>]*)$/,e.registerBreakpoints(),e.init(!0)}var b=0;return c}(),b.prototype.activateADA=function(){var a=this;a.$slideTrack.find(".slick-active").attr({"aria-hidden":"false"}).find("a, input, button, select").attr({tabindex:"0"})},b.prototype.addSlide=b.prototype.slickAdd=function(b,c,d){var e=this;if("boolean"==typeof c)d=c,c=null;else if(0>c||c>=e.slideCount)return!1;e.unload(),"number"==typeof c?0===c&&0===e.$slides.length?a(b).appendTo(e.$slideTrack):d?a(b).insertBefore(e.$slides.eq(c)):a(b).insertAfter(e.$slides.eq(c)):d===!0?a(b).prependTo(e.$slideTrack):a(b).appendTo(e.$slideTrack),e.$slides=e.$slideTrack.children(this.options.slide),e.$slideTrack.children(this.options.slide).detach(),e.$slideTrack.append(e.$slides),e.$slides.each(function(b,c){a(c).attr("data-slick-index",b)}),e.$slidesCache=e.$slides,e.reinit()},b.prototype.animateHeight=function(){var a=this;if(1===a.options.slidesToShow&&a.options.adaptiveHeight===!0&&a.options.vertical===!1){var b=a.$slides.eq(a.currentSlide).outerHeight(!0);a.$list.animate({height:b},a.options.speed)}},b.prototype.animateSlide=function(b,c){var d={},e=this;e.animateHeight(),e.options.rtl===!0&&e.options.vertical===!1&&(b=-b),e.transformsEnabled===!1?e.options.vertical===!1?e.$slideTrack.animate({left:b},e.options.speed,e.options.easing,c):e.$slideTrack.animate({top:b},e.options.speed,e.options.easing,c):e.cssTransitions===!1?(e.options.rtl===!0&&(e.currentLeft=-e.currentLeft),a({animStart:e.currentLeft}).animate({animStart:b},{duration:e.options.speed,easing:e.options.easing,step:function(a){a=Math.ceil(a),e.options.vertical===!1?(d[e.animType]="translate("+a+"px, 0px)",e.$slideTrack.css(d)):(d[e.animType]="translate(0px,"+a+"px)",e.$slideTrack.css(d))}
vendor: 6,412 bytes, line 2816
2816,complete:function(){c&&c.call()}})):(e.applyTransition(),b=Math.ceil(b),e.options.vertical===!1?d[e.animType]="translate3d("+b+"px, 0px, 0px)":d[e.animType]="translate3d(0px,"+b+"px, 0px)",e.$slideTrack.css(d),c&&setTimeout(function(){e.disableTransition(),c.call()},e.options.speed))},b.prototype.getNavTarget=function(){var b=this,c=b.options.asNavFor;return c&&null!==c&&(c=a(c).not(b.$slider)),c},b.prototype.asNavFor=function(b){var c=this,d=c.getNavTarget();null!==d&&"object"==typeof d&&d.each(function(){var c=a(this).slick("getSlick");c.unslicked||c.slideHandler(b,!0)})},b.prototype.applyTransition=function(a){var b=this,c={};b.options.fade===!1?c[b.transitionType]=b.transformType+" "+b.options.speed+"ms "+b.options.cssEase:c[b.transitionType]="opacity "+b.options.speed+"ms "+b.options.cssEase,b.options.fade===!1?b.$slideTrack.css(c):b.$slides.eq(a).css(c)},b.prototype.autoPlay=function(){var a=this;a.autoPlayClear(),a.slideCount>a.options.slidesToShow&&(a.autoPlayTimer=setInterval(a.autoPlayIterator,a.options.autoplaySpeed))},b.prototype.autoPlayClear=function(){var a=this;a.autoPlayTimer&&clearInterval(a.autoPlayTimer)},b.prototype.autoPlayIterator=function(){var a=this,b=a.currentSlide+a.options.slidesToScroll;a.paused||a.interrupted||a.focussed||(a.options.infinite===!1&&(1===a.direction&&a.currentSlide+1===a.slideCount-1?a.direction=0:0===a.direction&&(b=a.currentSlide-a.options.slidesToScroll,a.currentSlide-1===0&&(a.direction=1))),a.slideHandler(b))},b.prototype.buildArrows=function(){var b=this;b.options.arrows===!0&&(b.$prevArrow=a(b.options.prevArrow).addClass("slick-arrow"),b.$nextArrow=a(b.options.nextArrow).addClass("slick-arrow"),b.slideCount>b.options.slidesToShow?(b.$prevArrow.removeClass("slick-hidden").removeAttr("aria-hidden tabindex"),b.$nextArrow.removeClass("slick-hidden").removeAttr("aria-hidden tabindex"),b.htmlExpr.test(b.options.prevArrow)&&b.$prevArrow.prependTo(b.options.appendArrows),b.htmlExpr.test(b.options.nextArrow)&&b.$nextArrow.appendTo(b.options.appendArrows),b.options.infinite!==!0&&b.$prevArrow.addClass("slick-disabled").attr("aria-disabled","true")):b.$prevArrow.add(b.$nextArrow).addClass("slick-hidden").attr({"aria-disabled":"true",tabindex:"-1"}))},b.prototype.buildDots=function(){var c,d,b=this;if(b.options.dots===!0&&b.slideCount>b.options.slidesToShow){for(b.$slider.addClass("slick-dotted"),d=a("<ul />").addClass(b.options.dotsClass),c=0;c<=b.getDotCount();c+=1)d.append(a("<li />").append(b.options.customPaging.call(this,b,c)));b.$dots=d.appendTo(b.options.appendDots),b.$dots.find("li").first().addClass("slick-active").attr("aria-hidden","false")}},b.prototype.buildOut=function(){var b=this;b.$slides=b.$slider.children(b.options.slide+":not(.slick-cloned)").addClass("slick-slide"),b.slideCount=b.$slides.length,b.$slides.each(function(b,c){a(c).attr("data-slick-index",b).data("originalStyling",a(c).attr("style")||"")}),b.$slider.addClass("slick-slider"),b.$slideTrack=0===b.slideCount?a('<div class="slick-track"/>').appendTo(b.$slider):b.$slides.wrapAll('<div class="slick-track"/>').parent(),b.$list=b.$slideTrack.wrap('<div aria-live="polite" class="slick-list"/>').parent(),b.$slideTrack.css("opacity",0),(b.options.centerMode===!0||b.options.swipeToSlide===!0)&&(b.options.slidesToScroll=1),a("img[data-lazy]",b.$slider).not("[src]").addClass("slick-loading"),b.setupInfinite(),b.buildArrows(),b.buildDots(),b.updateDots(),b.setSlideClasses("number"==typeof b.currentSlide?b.currentSlide:0),b.options.draggable===!0&&b.$list.addClass("draggable")},b.prototype.buildRows=function(){var b,c,d,e,f,g,h,a=this;if(e=document.createDocumentFragment(),g=a.$slider.children(),a.options.rows>1){for(h=a.options.slidesPerRow*a.options.rows,f=Math.ceil(g.length/h),b=0;f>b;b++){var i=document.createElement("div");for(c=0;c<a.options.rows;c++){var j=document.createElement("div");for(d=0;d<a.options.slidesPerRow;d++){var k=b*h+(c*a.options.slidesPerRow+d);g.get(k)&&j.appendChild(g.get(k))}i.appendChild(j)}e.appendChild(i)}a.$slider.empty().append(e),a.$slider.children().children().children().css({width:100/a.options.slidesPerRow+"%",display:"inline-block"})}},b.prototype.checkResponsive=function(b,c){var e,f,g,d=this,h=!1,i=d.$slider.width(),j=window.innerWidth||a(window).width();if("window"===d.respondTo?g=j:"slider"===d.respondTo?g=i:"min"===d.respondTo&&(g=Math.min(j,i)),d.options.responsive&&d.options.responsive.length&&null!==d.options.responsive){f=null;for(e in d.breakpoints)d.breakpoints.hasOwnProperty(e)&&(d.originalSettings.mobileFirst===!1?g<d.breakpoints[e]&&(f=d.breakpoints[e]):g>d.breakpoints[e]&&(f=d.breakpoints[e]));null!==f?null!==d.activeBreakpoint?(f!==d.activeBreakpoint||c)&&(d.activeBreakpoint=f,"unslick"===d.breakpointSettings[f]?d.unslick(f):(d.options=a.extend({},d.originalSettings,d.breakpointSettings[f]),b===!0&&(d.currentSlide=d.options.initialSlide),d.refresh(b)),h=f):(d.activeBreakpoint=f,"unslick"===d.breakpointSettings[f]?d.unslick(f):(d.options=a.extend({},d.originalSettings,d.breakpointSettings[f]),b===!0&&(d.currentSlide=d.options.initialSlide),d.refresh(b)),h=f):null!==d.activeBreakpoint&&(d.activeBreakpoint=null,d.options=d.originalSettings,b===!0&&(d.currentSlide=d.options.initialSlide),d.refresh(b),h=f),b||h===!1||d.$slider.trigger("breakpoint",[d,h])}},b.prototype.changeSlide=function(b,c){var f,g,h,d=this,e=a(b.currentTarget);switch(e.is("a")&&b.preventDefault(),e.is("li")||(e=e.closest("li")),h=d.slideCount%d.options.slidesToScroll!==0,f=h?0:(d.slideCount-d.currentSlide)%d.options.slidesToScroll,b.data.message){case"previous":g=0===f?d.options.slidesToScroll:d.options.slidesToShow-f,d.slideCount>d.options.slidesToShow&&d.slideHandler(d.currentSlide-g,!1,c);break;case"next":g=0===f?d.options.slidesToScroll:f,d.slideCount>d.options.slidesToShow&&d.slideHandler(d.currentSlide+g,!1,c);break;case"index":var i=0===b.data.index?0:b.data.index||e.index()*d.options.slidesToScroll;d.slideHandler(d.checkNavigable(i),!1,c),e.children().trigger("focus");break;default:return}},b.prototype.checkNavigable=function(a){var c,d,b=this;if(c=b.getNavigableIndexes(),d=0,a>c[c.length-1])a=c[c.length-1];else for(var e in c){if(a<c[e]){a=d;break}d=c[e]}return a},b.prototype.cleanUpEvents=function(){var b=this;b.options.dots&&null!==b.$dots&&a("li",b.$dots).off("click.slick",b.changeSlide).off("mouseenter.slick",a.proxy(b.interrupt,b,!0)).off("mouseleave.
2816slick",a.proxy(b.interrupt,b,!1)),b.$slider.off("focus.slick blur.slick"),b.options.arrows===!0&&b.slideCount>b.options.slidesToShow&&(b.$prevArrow&&b.$prevArrow.off("click.slick",b.changeSlide),b.$nextArrow&&b.$nextArrow.off("click.slick",b.changeSlide)),b.$list.off("touchstart.slick mousedown.slick",b.swipeHandler),b.$list.off("touchmove.slick mousemove.slick",b.swipeHandler),b.$list.off("touchend.slick mouseup.slick",b.swipeHandler),b.$list.off("touchcancel.slick mouseleave.slick",b.swipeHandler),b.$list.off("click.slick",b.clickHandler),a(document).off(b.visibilityChange,b.visibility),b.cleanUpSlideEvents(),b.options.accessibility===!0&&b.$list.off("keydown.slick",b.keyHandler),b.options.focusOnSelect===!0&&a(b.$slideTrack).children().off("click.slick",b.selectHandler),a(window).off("orientationchange.slick.slick-"+b.instanceUid,b.orientationChange),a(window).off("resize.slick.slick-"+b.instanceUid,b.resize),a("[draggable!=true]",b.$slideTrack).off("dragstart",b.preventDefault),a(window).off("load.slick.slick-"+b.instanceUid,b.setPosition),a(document).off("ready.slick.slick-"+b.instanceUid,b.setPosition)},b.prototype.cleanUpSlideEvents=function(){var b=this;b.$list.off("mouseenter.slick",a.proxy(b.interrupt,b,!0)),b.$list.off("mouseleave.slick",a.proxy(b.interrupt,b,!1))},b.prototype.cleanUpRows=function(){var b,a=this;a.options.rows>1&&(b=a.$slides.children().children(),b.removeAttr("style"),a.$slider.empty().append(b))},b.prototype.clickHandler=function(a){var b=this;b.shouldClick===!1&&(a.stopImmediatePropagation(),a.stopPropagation(),a.preventDefault())},b.prototype.destroy=function(b){var c=this;c.autoPlayClear(),c.touchObject={},c.cleanUpEvents(),a(".slick-cloned",c.$slider).detach(),c.$dots&&c.$dots.remove(),c.$prevArrow&&c.$prevArrow.length&&(c.$prevArrow.removeClass("slick-disabled slick-arrow slick-hidden").removeAttr("aria-hidden aria-disabled tabindex").css("display",""),c.htmlExpr.test(c.options.prevArrow)&&c.$prevArrow.remove()),c.$nextArrow&&c.$nextArrow.length&&(c.$nextArrow.removeClass("slick-disabled slick-arrow slick-hidden").removeAttr("aria-hidden aria-disabled tabindex").css("display",""),c.htmlExpr.test(c.options.nextArrow)&&c.$nextArrow.remove()),c.$slides&&(c.$slides.removeClass("slick-slide slick-active slick-center slick-visible slick-current").removeAttr("aria-hidden").removeAttr("data-slick-index").each(function(){a(this).attr("style",a(this).data("originalStyling"))}),c.$slideTrack.children(this.options.slide).detach(),c.$slideTrack.detach(),c.$list.detach(),c.$slider.append(c.$slides)),c.cleanUpRows(),c.$slider.removeClass("slick-slider"),c.$slider.removeClass("slick-initialized"),c.$slider.removeClass("slick-dotted"),c.unslicked=!0,b||c.$slider.trigger("destroy",[c])},b.prototype.disableTransition=function(a){var b=this,c={};c[b.transitionType]="",b.options.fade===!1?b.$slideTrack.css(c):b.$slides.eq(a).css(c)},b.prototype.fadeSlide=function(a,b){var c=this;c.cssTransitions===!1?(c.$slides.eq(a).css({zIndex:c.options.zIndex}),c.$slides.eq(a).animate({opacity:1},c.options.speed,c.options.easing,b)):(c.applyTransition(a),c.$slides.eq(a).css({opacity:1,zIndex:c.options.zIndex}),b&&setTimeout(function(){c.disableTransition(a),b.call()},c.options.speed))},b.prototype.fadeSlideOut=function(a){var b=this;b.cssTransitions===!1?b.$slides.eq(a).animate({opacity:0,zIndex:b.options.zIndex-2},b.options.speed,b.options.easing):(b.applyTransition(a),b.$slides.eq(a).css({opacity:0,zIndex:b.options.zIndex-2}))},b.prototype.filterSlides=b.prototype.slickFilter=function(a){var b=this;null!==a&&(b.$slidesCache=b.$slides,b.unload(),b.$slideTrack.children(this.options.slide).detach(),b.$slidesCache.filter(a).appendTo(b.$slideTrack),b.reinit())},b.prototype.focusHandler=function(){var b=this;b.$slider.off("focus.slick blur.slick").on("focus.slick blur.slick","*:not(.slick-arrow)",function(c){c.stopImmediatePropagation();var d=a(this);setTimeout(function(){b.options.pauseOnFocus&&(b.focussed=d.is(":focus"),b.autoPlay())},0)})},b.prototype.getCurrent=b.prototype.slickCurrentSlide=function(){var a=this;return a.currentSlide},b.prototype.getDotCount=function(){var a=this,b=0,c=0,d=0;if(a.options.infinite===!0)for(;b<a.slideCount;)++d,b=c+a.options.slidesToScroll,c+=a.options.slidesToScroll<=a.options.slidesToShow?a.options.slidesToScroll:a.options.slidesToShow;else if(a.options.centerMode===!0)d=a.slideCount;else if(a.options.asNavFor)for(;b<a.slideCount;)++d,b=c+a.options.slidesToScroll,c+=a.options.slidesToScroll<=a.options.slidesToShow?a.options.slidesToScroll:a.options.slidesToShow;else d=1+Math.ceil((a.slideCount-a.options.slidesToShow)/a.options.slidesToScroll);return d-1},b.prototype.getLeft=function(a){var c,d,f,b=this,e=0;return b.slideOffset=0,d=b.$slides.first().outerHeight(!0),b.options.infinite===!0?(b.slideCount>b.options.slidesToShow&&(b.slideOffset=b.slideWidth*b.options.slidesToShow*-1,e=d*b.options.slidesToShow*-1),b.slideCount%b.options.slidesToScroll!==0&&a+b.options.slidesToScroll>b.slideCount&&b.slideCount>b.options.slidesToShow&&(a>b.slideCount?(b.slideOffset=(b.options.slidesToShow-(a-b.slideCount))*b.slideWidth*-1,e=(b.options.slidesToShow-(a-b.slideCount))*d*-1):(b.slideOffset=b.slideCount%b.options.slidesToScroll*b.slideWidth*-1,e=b.slideCount%b.options.slidesToScroll*d*-1))):a+b.o
2816ptions.slidesToShow>b.slideCount&&(b.slideOffset=(a+b.options.slidesToShow-b.slideCount)*b.slideWidth,e=(a+b.options.slidesToShow-b.slideCount)*d),b.slideCount<=b.options.slidesToShow&&(b.slideOffset=0,e=0),b.options.centerMode===!0&&b.options.infinite===!0?b.slideOffset+=b.slideWidth*Math.floor(b.options.slidesToShow/2)-b.slideWidth:b.options.centerMode===!0&&(b.slideOffset=0,b.slideOffset+=b.slideWidth*Math.floor(b.options.slidesToShow/2)),c=b.options.vertical===!1?a*b.slideWidth*-1+b.slideOffset:a*d*-1+e,b.options.variableWidth===!0&&(f=b.slideCount<=b.options.slidesToShow||b.options.infinite===!1?b.$slideTrack.children(".slick-slide").eq(a):b.$slideTrack.children(".slick-slide").eq(a+b.options.slidesToShow),c=b.options.rtl===!0?f[0]?-1*(b.$slideTrack.width()-f[0].offsetLeft-f.width()):0:f[0]?-1*f[0].offsetLeft:0,b.options.centerMode===!0&&(f=b.slideCount<=b.options.slidesToShow||b.options.infinite===!1?b.$slideTrack.children(".slick-slide").eq(a):b.$slideTrack.children(".slick-slide").eq(a+b.options.slidesToShow+1),c=b.options.rtl===!0?f[0]?-1*(b.$slideTrack.width()-f[0].offsetLeft-f.width()):0:f[0]?-1*f[0].offsetLeft:0,c+=(b.$list.width()-f.outerWidth())/2)),c},b.prototype.getOption=b.prototype.slickGetOption=function(a){var b=this;return b.options[a]},b.prototype.getNavigableIndexes=function(){var e,a=this,b=0,c=0,d=[];for(a.options.infinite===!1?e=a.slideCount:(b=-1*a.options.slidesToScroll,c=-1*a.options.slidesToScroll,e=2*a.slideCount);e>b;)d.push(b),b=c+a.options.slidesToScroll,c+=a.options.slidesToScroll<=a.options.slidesToShow?a.options.slidesToScroll:a.options.slidesToShow;return d},b.prototype.getSlick=function(){return this},b.prototype.getSlideCount=function(){var c,d,e,b=this;return e=b.options.centerMode===!0?b.slideWidth*Math.floor(b.options.slidesToShow/2):0,b.options.swipeToSlide===!0?(b.$slideTrack.find(".slick-slide").each(function(c,f){return f.offsetLeft-e+a(f).outerWidth()/2>-1*b.swipeLeft?(d=f,!1):void 0}),c=Math.abs(a(d).attr("data-slick-index")-b.currentSlide)||1):b.options.slidesToScroll},b.prototype.goTo=b.prototype.slickGoTo=function(a,b){var c=this;c.changeSlide({data:{message:"index",index:parseInt(a)}},b)},b.prototype.init=function(b){var c=this;a(c.$slider).hasClass("slick-initialized")||(a(c.$slider).addClass("slick-initialized"),c.buildRows(),c.buildOut(),c.setProps(),c.startLoad(),c.loadSlider(),c.initializeEvents(),c.updateArrows(),c.updateDots(),c.checkResponsive(!0),c.focusHandler()),b&&c.$slider.trigger("init",[c]),c.options.accessibility===!0&&c.initADA(),c.options.autoplay&&(c.paused=!1,c.autoPlay())},b.prototype.initADA=function(){var b=this;b.$slides.add(b.$slideTrack.find(".slick-cloned")).attr({"aria-hidden":"true",tabindex:"-1"}).find("a, input, button, select").attr({tabindex:"-1"}),b.$slideTrack.attr("role","listbox"),b.$slides.not(b.$slideTrack.find(".slick-cloned")).each(function(c){a(this).attr({role:"option","aria-describedby":"slick-slide"+b.instanceUid+c})}),null!==b.$dots&&b.$dots.attr("role","tablist").find("li").each(function(c){a(this).attr({role:"presentation","aria-selected":"false","aria-controls":"navigation"+b.instanceUid+c,id:"slick-slide"+b.instanceUid+c})}).first().attr("aria-selected","true").end().find("button").attr("role","button").end().closest("div").attr("role","toolbar"),b.activateADA()},b.prototype.initArrowEvents=function(){var a=this;a.options.arrows===!0&&a.slideCount>a.options.slidesToShow&&(a.$prevArrow.off("click.slick").on("click.slick",{message:"previous"},a.changeSlide),a.$nextArrow.off("click.slick").on("click.slick",{message:"next"},a.changeSlide))},b.prototype.initDotEvents=function(){var b=this;b.options.dots===!0&&b.slideCount>b.options.slidesToShow&&a("li",b.$dots).on("click.slick",{message:"index"},b.changeSlide),b.options.dots===!0&&b.options.pauseOnDotsHover===!0&&a("li",b.$dots).on("mouseenter.slick",a.proxy(b.interrupt,b,!0)).on("mouseleave.slick",a.proxy(b.interrupt,b,!1))},b.prototype.initSlideEvents=function(){var b=this;b.options.pauseOnHover&&(b.$list.on("mouseenter.slick",a.proxy(b.interrupt,b,!0)),b.$list.on("mouseleave.
2816slick",a.proxy(b.interrupt,b,!1)))},b.prototype.initializeEvents=function(){var b=this;b.initArrowEvents(),b.initDotEvents(),b.initSlideEvents(),b.$list.on("touchstart.slick mousedown.slick",{action:"start"},b.swipeHandler),b.$list.on("touchmove.slick mousemove.slick",{action:"move"},b.swipeHandler),b.$list.on("touchend.slick mouseup.slick",{action:"end"},b.swipeHandler),b.$list.on("touchcancel.slick mouseleave.slick",{action:"end"},b.swipeHandler),b.$list.on("click.slick",b.clickHandler),a(document).on(b.visibilityChange,a.proxy(b.visibility,b)),b.options.accessibility===!0&&b.$list.on("keydown.slick",b.keyHandler),b.options.focusOnSelect===!0&&a(b.$slideTrack).children().on("click.slick",b.selectHandler),a(window).on("orientationchange.slick.slick-"+b.instanceUid,a.proxy(b.orientationChange,b)),a(window).on("resize.slick.slick-"+b.instanceUid,a.proxy(b.resize,b)),a("[draggable!=true]",b.$slideTrack).on("dragstart",b.preventDefault),a(window).on("load.slick.slick-"+b.instanceUid,b.setPosition),a(document).on("ready.slick.slick-"+b.instanceUid,b.setPosition)},b.prototype.initUI=function(){var a=this;a.options.arrows===!0&&a.slideCount>a.options.slidesToShow&&(a.$prevArrow.show(),a.$nextArrow.show()),a.options.dots===!0&&a.slideCount>a.options.slidesToShow&&a.$dots.show()},b.prototype.keyHandler=function(a){var b=this;a.target.tagName.match("TEXTAREA|INPUT|SELECT")||(37===a.keyCode&&b.options.accessibility===!0?b.changeSlide({data:{message:b.options.rtl===!0?"next":"previous"}}):39===a.keyCode&&b.options.accessibility===!0&&b.changeSlide({data:{message:b.options.rtl===!0?"previous":"next"}}))},b.prototype.lazyLoad=function(){function g(c){a("img[data-lazy]",c).each(function(){var c=a(this),d=a(this).attr("data-lazy"),e=document.createElement("img");e.onload=function(){c.animate({opacity:0}
vendor: 11,311 bytes, lines 2816-2817
2816,100,function(){c.attr("src",d).animate({opacity:1},200,function(){c.removeAttr("data-lazy").removeClass("slick-loading")}),b.$slider.trigger("lazyLoaded",[b,c,d])})},e.onerror=function(){c.removeAttr("data-lazy").removeClass("slick-loading").addClass("slick-lazyload-error"),b.$slider.trigger("lazyLoadError",[b,c,d])},e.src=d})}var c,d,e,f,b=this;b.options.centerMode===!0?b.options.infinite===!0?(e=b.currentSlide+(b.options.slidesToShow/2+1),f=e+b.options.slidesToShow+2):(e=Math.max(0,b.currentSlide-(b.options.slidesToShow/2+1)),f=2+(b.options.slidesToShow/2+1)+b.currentSlide):(e=b.options.infinite?b.options.slidesToShow+b.currentSlide:b.currentSlide,f=Math.ceil(e+b.options.slidesToShow),b.options.fade===!0&&(e>0&&e--,f<=b.slideCount&&f++)),c=b.$slider.find(".slick-slide").slice(e,f),g(c),b.slideCount<=b.options.slidesToShow?(d=b.$slider.find(".slick-slide"),g(d)):b.currentSlide>=b.slideCount-b.options.slidesToShow?(d=b.$slider.find(".slick-cloned").slice(0,b.options.slidesToShow),g(d)):0===b.currentSlide&&(d=b.$slider.find(".slick-cloned").slice(-1*b.options.slidesToShow),g(d))},b.prototype.loadSlider=function(){var a=this;a.setPosition(),a.$slideTrack.css({opacity:1}),a.$slider.removeClass("slick-loading"),a.initUI(),"progressive"===a.options.lazyLoad&&a.progressiveLazyLoad()},b.prototype.next=b.prototype.slickNext=function(){var a=this;a.changeSlide({data:{message:"next"}})},b.prototype.orientationChange=function(){var a=this;a.checkResponsive(),a.setPosition()},b.prototype.pause=b.prototype.slickPause=function(){var a=this;a.autoPlayClear(),a.paused=!0},b.prototype.play=b.prototype.slickPlay=function(){var a=this;a.autoPlay(),a.options.autoplay=!0,a.paused=!1,a.focussed=!1,a.interrupted=!1},b.prototype.postSlide=function(a){var b=this;b.unslicked||(b.$slider.trigger("afterChange",[b,a]),b.animating=!1,b.setPosition(),b.swipeLeft=null,b.options.autoplay&&b.autoPlay(),b.options.accessibility===!0&&b.initADA())},b.prototype.prev=b.prototype.slickPrev=function(){var a=this;a.changeSlide({data:{message:"previous"}})},b.prototype.preventDefault=function(a){a.preventDefault()},b.prototype.progressiveLazyLoad=function(b){b=b||1;var e,f,g,c=this,d=a("img[data-lazy]",c.$slider);d.length?(e=d.first(),f=e.attr("data-lazy"),g=document.createElement("img"),g.onload=function(){e.attr("src",f).removeAttr("data-lazy").removeClass("slick-loading"),c.options.adaptiveHeight===!0&&c.setPosition(),c.$slider.trigger("lazyLoaded",[c,e,f]),c.progressiveLazyLoad()},g.onerror=function(){3>b?setTimeout(function(){c.progressiveLazyLoad(b+1)},500):(e.removeAttr("data-lazy").removeClass("slick-loading").addClass("slick-lazyload-error"),c.$slider.trigger("lazyLoadError",[c,e,f]),c.progressiveLazyLoad())},g.src=f):c.$slider.trigger("allImagesLoaded",[c])},b.prototype.refresh=function(b){var d,e,c=this;e=c.slideCount-c.options.slidesToShow,!c.options.infinite&&c.currentSlide>e&&(c.currentSlide=e),c.slideCount<=c.options.slidesToShow&&(c.currentSlide=0),d=c.currentSlide,c.destroy(!0),a.extend(c,c.initials,{currentSlide:d}),c.init(),b||c.changeSlide({data:{message:"index",index:d}},!1)},b.prototype.registerBreakpoints=function(){var c,d,e,b=this,f=b.options.responsive||null;if("array"===a.type(f)&&f.length){b.respondTo=b.options.respondTo||"window";for(c in f)if(e=b.breakpoints.length-1,d=f[c].breakpoint,f.hasOwnProperty(c)){for(;e>=0;)b.breakpoints[e]&&b.breakpoints[e]===d&&b.breakpoints.splice(e,1),e--;b.breakpoints.push(d),b.breakpointSettings[d]=f[c].settings}b.breakpoints.sort(function(a,c){return b.options.mobileFirst?a-c:c-a})}},b.prototype.reinit=function(){var b=this;b.$slides=b.$slideTrack.children(b.options.slide).addClass("slick-slide"),b.slideCount=b.$slides.length,b.currentSlide>=b.slideCount&&0!==b.currentSlide&&(b.currentSlide=b.currentSlide-b.options.slidesToScroll),b.slideCount<=b.options.slidesToShow&&(b.currentSlide=0),b.registerBreakpoints(),b.setProps(),b.setupInfinite(),b.buildArrows(),b.updateArrows(),b.initArrowEvents(),b.buildDots(),b.updateDots(),b.initDotEvents(),b.cleanUpSlideEvents(),b.initSlideEvents(),b.checkResponsive(!1,!0),b.options.focusOnSelect===!0&&a(b.$slideTrack).children().on("click.slick",b.selectHandler),b.setSlideClasses("number"==typeof b.currentSlide?b.currentSlide:0),b.setPosition(),b.focusHandler(),b.paused=!b.options.autoplay,b.autoPlay(),b.$slider.trigger("reInit",[b])},b.prototype.resize=function(){var b=this;a(window).width()!==b.windowWidth&&(clearTimeout(b.windowDelay),b.windowDelay=window.setTimeout(function(){b.windowWidth=a(window).width(),b.checkResponsive(),b.unslicked||b.setPosition()},50))},b.prototype.removeSlide=b.prototype.slickRemove=function(a,b,c){var d=this;return"boolean"==typeof a?(b=a,a=b===!0?0:d.slideCount-1):a=b===!0?--a:a,d.slideCount<1||0>a||a>d.slideCount-1?!1:(d.unload(),c===!0?d.$slideTrack.children().remove():d.$slideTrack.children(this.options.slide).eq(a).remove(),d.$slides=d.$slideTrack.children(this.options.slide),d.$slideTrack.children(this.options.slide).detach(),d.$slideTrack.append(d.$slides),d.$slidesCache=d.$slides,void d.reinit())},b.prototype.setCSS=function(a){var d,e,b=this,c={};b.options.rtl===!0&&(a=-a),d="left"==b.positionProp?Math.ceil(a)+"px":"0px",e="top"==b.positionProp?Math.ceil(a)+"px":"0px",c[b.positionProp]=a,b.transformsEnabled===!1?b.$slideTrack.css(c):(c={},b.cssTransitions===!1?(c[b.animType]="translate("+d+", "+e+")",b.$slideTrack.css(c)):(c[b.animType]="translate3d("+d+", "+e+", 0px)",b.$slideTrack.css(c)))},b.prototype.setDimensions=function(){var a=this;a.options.vertical===!1?a.options.centerMode===!0&&a.$list.css({padding:"0px "+a.options.centerPadding}):(a.$list.height(a.$slides.first().outerHeight(!0)*a.options.slidesToShow),a.options.centerMode===!0&&a.$list.css({padding:a.options.centerPadding+" 0px"})),a.listWidth=a.$list.width(),a.listHeight=a.$list.height(),a.options.vertical===!1&&a.options.variableWidth===!1?(a.slideWidth=Math.ceil(a.listWidth/a.options.slidesToShow),a.$slideTrack.width(Math.ceil(a.slideWidth*a.$slideTrack.children(".slick-slide").length))):a.options.variableWidth===!0?a.$slideTrack.width(5e3*a.slideCount):(a.slideWidth=Math.ceil(a.listWidth),a.$slideTrack.height(Math.ceil(a.$slides.first().outerHeight(!0)*a.$slideTrack.children(".slick-slide").length)));var b=a.$slides.first().outerWidth(!0)-a.$slides.first().width();a.options.variableWidth===!1&&a.$slideTrack.children(".slick-slide").width(a.slideWidth-b)},b.prototype.setFade=function(){var c,b=this;b.$slides.each(function(d,e){c=b.slideWidth*d*-1,b.options.rtl===!0?a(e).css({position:"relative",right:c,top:0,zIndex:b.options.zIndex-2,opacity:0}):a(e).css({position:"relative",left:c,top:0,zIndex:b.options.zIndex-2,opacity:0})}),b.$slides.eq(b.currentSlide).css({zIndex:b.options.zIndex-1,opacity:1})},b.prototype.setHeight=function(){var a=this;if(1===a.options.slidesToShow&&a.options.adaptiveHeight===!0&&a.options.vertical===!1){var b=a.$slides.eq(a.currentSlide).outerHeight(!0);a.$list.css("height",b)}},b.prototype.setOption=b.prototype.slickSetOption=function(){var c,d,e,f,h,b=this,g=!1;if("object"===a.type(arguments[0])?(e=arguments[0],g=arguments[1],h="multiple"):"string"===a.type(arguments[0])&&(e=arguments[0],f=arguments[1],g=arguments[2],"responsive"===arguments[0]&&"array"===a.type(arguments[1])?h="responsive":"undefined"!=typeof arguments[1]&&(h="single")),"single"===h)b.options[e]=f;else if("multiple"===h)a.each(e,function(a,c){b.options[a]=c});else if("responsive"===h)for(d in f)if("array"!==a.type(b.options.responsive))b.options.responsive=[f[d]];else{for(c=b.options.responsive.length-1;c>=0;)b.options.responsive[c].breakpoint===f[d].breakpoint&&b.options.responsive.splice(c,1),c--;b.options.responsive.push(f[d])}g&&(b.unload(),b.reinit())},b.prototype.setPosition=function(){var a=this;a.setDimensions(),a.setHeight(),a.options.fade===!1?a.setCSS(a.getLeft(a.currentSlide)):a.setFade(),a.$slider.trigger("setPosition",[a])},b.prototype.setProps=function(){var a=this,b=document.body.style;a.positionProp=a.options.vertical===!0?"top":"left","top"===a.positionProp?a.$slider.addClass("slick-vertical"):a.$slider.removeClass("slick-vertical"),(void 0!==b.WebkitTransition||void 0!==b.MozTransition||void 0!==b.msTransition)&&a.options.useCSS===!0&&(a.cssTransitions=!0),a.options.fade&&("number"==typeof a.options.zIndex?a.options.zIndex<3&&(a.options.zIndex=3):a.options.zIndex=a.defaults.zIndex),void 0!==b.OTransform&&(a.animType="OTransform",a.transformType="-o-transform",a.transitionType="OTransition",void 0===b.perspectiveProperty&&void 0===b.webkitPerspective&&(a.animType=!1)),void 0!==b.MozTransform&&(a.animType="MozTransform",a.transformType="-moz-transform",a.transitionType="MozTransition",void 0===b.perspectiveProperty&&void 0===b.MozPerspective&&(a.animType=!1)),void 0!==b.webkitTransform&&(a.animType="webkitTransform",a.transformType="-webkit-transform",a.transitionType="webkitTransition",void 0===b.perspectiveProperty&&void 0===b.webkitPerspective&&(a.animType=!1)),void 0!==b.msTransform&&(a.animType="msTransform",a.transformType="-ms-transform",a.transitionType="msTransition",void 0===b.msTransform&&(a.animType=!1)),void 0!==b.transform&&a.animType!==!1&&(a.animType="transform",a.transformType="transform",a.transitionType="transition"),a.transformsEnabled=a.options.useTransform&&null!==a.animType&&a.animType!==!1},b.prototype.setSlideClasses=function(a){var c,d,e,f,b=this;d=b.$slider.find(".slick-slide").removeClass("slick-active slick-center slick-current").attr("aria-hidden","true"),b.$slides.eq(a).addClass("slick-current"),b.options.centerMode===!0?(c=Math.floor(b.options.slidesToShow/2),b.options.infinite===!0&&(a>=c&&a<=b.slideCount-1-c?b.$slides.slice(a-c,a+c+1).addClass("slick-active").attr("aria-hidden","false"):(e=b.options.slidesToShow+a, 2817d.slice(e-c+1,e+c+2).addClass("slick-active").attr("aria-hidden","false")),0===a?d.eq(d.length-1-b.options.slidesToShow).addClass("slick-center"):a===b.slideCount-1&&d.eq(b.options.slidesToShow).addClass("slick-center")),b.$slides.eq(a).addClass("slick-center")):a>=0&&a<=b.slideCount-b.options.slidesToShow?b.$slides.slice(a,a+b.options.slidesToShow).addClass("slick-active").attr("aria-hidden","false"):d.length<=b.options.slidesToShow?d.addClass("slick-active").attr("aria-hidden","false"):(f=b.slideCount%b.options.slidesToShow,e=b.options.infinite===!0?b.options.slidesToShow+a:a,b.options.slidesToShow==b.options.slidesToScroll&&b.slideCount-a<b.options.slidesToShow?d.slice(e-(b.options.slidesToShow-f),e+f).addClass("slick-active").attr("aria-hidden","false"):d.slice(e,e+b.options.slidesToShow).addClass("slick-active").attr("aria-hidden","false")),"ondemand"===b.options.lazyLoad&&b.lazyLoad()},b.prototype.setupInfinite=function(){var c,d,e,b=this;if(b.options.fade===!0&&(b.options.centerMode=!1),b.options.infinite===!0&&b.options.fade===!1&&(d=null,b.slideCount>b.options.slidesToShow)){for(e=b.options.centerMode===!0?b.options.slidesToShow+1:b.options.slidesToShow,c=b.slideCount;c>b.slideCount-e;c-=1)d=c-1,a(b.$slides[d]).clone(!0).attr("id","").attr("data-slick-index",d-b.slideCount).prependTo(b.$slideTrack).addClass("slick-cloned");for(c=0;e>c;c+=1)d=c,a(b.$slides[d]).clone(!0).attr("id","").attr("data-slick-index",d+b.slideCount).appendTo(b.$slideTrack).addClass("slick-cloned");
2817b.$slideTrack.find(".slick-cloned").find("[id]").each(function(){a(this).attr("id","")})}},b.prototype.interrupt=function(a){var b=this;a||b.autoPlay(),b.interrupted=a},b.prototype.selectHandler=function(b){var c=this,d=a(b.target).is(".slick-slide")?a(b.target):a(b.target).parents(".slick-slide"),e=parseInt(d.attr("data-slick-index"));return e||(e=0),c.slideCount<=c.options.slidesToShow?(c.setSlideClasses(e),void c.asNavFor(e)):void c.slideHandler(e)},b.prototype.slideHandler=function(a,b,c){var d,e,f,g,j,h=null,i=this;return b=b||!1,i.animating===!0&&i.options.waitForAnimate===!0||i.options.fade===!0&&i.currentSlide===a||i.slideCount<=i.options.slidesToShow?void 0:(b===!1&&i.asNavFor(a),d=a,h=i.getLeft(d),g=i.getLeft(i.currentSlide),i.currentLeft=null===i.swipeLeft?g:i.swipeLeft,i.options.infinite===!1&&i.options.centerMode===!1&&(0>a||a>i.getDotCount()*i.options.slidesToScroll)?void(i.options.fade===!1&&(d=i.currentSlide,c!==!0?i.animateSlide(g,function(){i.postSlide(d)}):i.postSlide(d))):i.options.infinite===!1&&i.options.centerMode===!0&&(0>a||a>i.slideCount-i.options.slidesToScroll)?void(i.options.fade===!1&&(d=i.currentSlide,c!==!0?i.animateSlide(g,function(){i.postSlide(d)}):i.postSlide(d))):(i.options.autoplay&&clearInterval(i.autoPlayTimer),e=0>d?i.slideCount%i.options.slidesToScroll!==0?i.slideCount-i.slideCount%i.options.slidesToScroll:i.slideCount+d:d>=i.slideCount?i.slideCount%i.options.slidesToScroll!==0?0:d-i.slideCount:d,i.animating=!0,i.$slider.trigger("beforeChange",[i,i.currentSlide,e]),f=i.currentSlide,i.currentSlide=e,i.setSlideClasses(i.currentSlide),i.options.asNavFor&&(j=i.getNavTarget(),j=j.slick("getSlick"),j.slideCount<=j.options.slidesToShow&&j.setSlideClasses(i.currentSlide)),i.updateDots(),i.updateArrows(),i.options.fade===!0?(c!==!0?(i.fadeSlideOut(f),i.fadeSlide(e,function(){i.postSlide(e)})):i.postSlide(e),void i.animateHeight()):void(c!==!0?i.animateSlide(h,function(){i.postSlide(e)}):i.postSlide(e))))},b.prototype.startLoad=function(){var a=this;a.options.arrows===!0&&a.slideCount>a.options.slidesToShow&&(a.$prevArrow.hide(),a.$nextArrow.hide()),a.options.dots===!0&&a.slideCount>a.options.slidesToShow&&a.$dots.hide(),a.$slider.addClass("slick-loading")},b.prototype.swipeDirection=function(){var a,b,c,d,e=this;return a=e.touchObject.startX-e.touchObject.curX,b=e.touchObject.startY-e.touchObject.curY,c=Math.atan2(b,a),d=Math.round(180*c/Math.PI),0>d&&(d=360-Math.abs(d)),45>=d&&d>=0?e.options.rtl===!1?"left":"right":360>=d&&d>=315?e.options.rtl===!1?"left":"right":d>=135&&225>=d?e.options.rtl===!1?"right":"left":e.options.verticalSwiping===!0?d>=35&&135>=d?"down":"up":"vertical"},b.prototype.swipeEnd=function(a){var c,d,b=this;if(b.dragging=!1,b.interrupted=!1,b.shouldClick=b.touchObject.swipeLength>10?!1:!0,void 0===b.touchObject.curX)return!1;if(b.touchObject.edgeHit===!0&&b.$slider.trigger("edge",[b,b.swipeDirection()]),b.touchObject.swipeLength>=b.touchObject.minSwipe){switch(d=b.swipeDirection()){case"left":case"down":c=b.options.swipeToSlide?b.checkNavigable(b.currentSlide+b.getSlideCount()):b.currentSlide+b.getSlideCount(),b.currentDirection=0;break;case"right":case"up":c=b.options.swipeToSlide?b.checkNavigable(b.currentSlide-b.getSlideCount()):b.currentSlide-b.getSlideCount(),b.currentDirection=1}"vertical"!=d&&(b.slideHandler(c),b.touchObject={},b.$slider.trigger("swipe",[b,d]))}else b.touchObject.startX!==b.touchObject.curX&&(b.slideHandler(b.currentSlide),b.touchObject={})},b.prototype.swipeHandler=function(a){var b=this;if(!(b.options.swipe===!1||"ontouchend"in document&&b.options.swipe===!1||b.options.draggable===!1&&-1!==a.type.indexOf("mouse")))switch(b.touchObject.fingerCount=a.originalEvent&&void 0!==a.originalEvent.touches?a.originalEvent.touches.length:1,b.touchObject.minSwipe=b.listWidth/b.options.touchThreshold,b.options.verticalSwiping===!0&&(b.touchObject.minSwipe=b.listHeight/b.options.touchThreshold),a.data.action){case"start":b.swipeStart(a);break;case"move":b.swipeMove(a);break;case"end":b.swipeEnd(a)}},b.prototype.swipeMove=function(a){var d,e,f,g,h,b=this;return h=void 0!==a.originalEvent?a.originalEvent.touches:null,!b.dragging||h&&1!==h.length?!1:(d=b.getLeft(b.currentSlide),b.touchObject.curX=void 0!==h?h[0].pageX:a.clientX,b.touchObject.curY=void 0!==h?h[0].pageY:a.clientY,b.touchObject.swipeLength=Math.round(Math.sqrt(Math.pow(b.touchObject.curX-b.touchObject.startX,2))),b.options.verticalSwiping===!0&&(b.touchObject.swipeLength=Math.round(Math.sqrt(Math.pow(b.touchObject.curY-b.touchObject.startY,2)))),e=b.swipeDirection(),"vertical"!==e?(void 0!==a.originalEvent&&b.touchObject.swipeLength>
28174&&a.preventDefault(),g=(b.options.rtl===!1?1:-1)*(b.touchObject.curX>b.touchObject.startX?1:-1),b.options.verticalSwiping===!0&&(g=b.touchObject.curY>b.touchObject.startY?1:-1),f=b.touchObject.swipeLength,b.touchObject.edgeHit=!1,b.options.infinite===!1&&(0===b.currentSlide&&"right"===e||b.currentSlide>=b.getDotCount()&&"left"===e)&&(f=b.touchObject.swipeLength*b.options.edgeFriction,b.touchObject.edgeHit=!0),b.options.vertical===!1?b.swipeLeft=d+f*g:b.swipeLeft=d+f*(b.$list.height()/b.listWidth)*g,b.options.verticalSwiping===!0&&(b.swipeLeft=d+f*g),b.options.fade===!0||b.options.touchMove===!1?!1:b.animating===!0?(b.swipeLeft=null,!1):void b.setCSS(b.swipeLeft)):void 0)},b.prototype.swipeStart=function(a){var c,b=this;return b.interrupted=!0,1!==b.touchObject.fingerCount||b.slideCount<=b.options.slidesToShow?(b.touchObject={},!1):(void 0!==a.originalEvent&&void 0!==a.originalEvent.touches&&(c=a.originalEvent.touches[0]),b.touchObject.startX=b.touchObject.curX=void 0!==c?c.pageX:a.clientX,b.touchObject.startY=b.touchObject.curY=void 0!==c?c.pageY:a.clientY,void(b.dragging=!0))},b.prototype.unfilterSlides=b.prototype.slickUnfilter=function(){var a=this;null!==a.$slidesCache&&(a.unload(),a.$slideTrack.children(this.options.slide).detach(),a.$slidesCache.appendTo(a.$slideTrack),a.reinit())},b.prototype.unload=function(){var b=this;a(".slick-cloned",b.$slider).remove(),b.$dots&&b.$dots.remove(),b.$prevArrow&&b.htmlExpr.test(b.options.prevArrow)&&b.$prevArrow.remove(),b.$nextArrow&&b.htmlExpr.test(b.options.nextArrow)&&b.$nextArrow.remove(),b.$slides.removeClass("slick-slide slick-active slick-visible slick-current").attr("aria-hidden","true").css("width","")},b.prototype.unslick=function(a){var b=this;b.$slider.trigger("unslick",[b,a]),b.destroy()},b.prototype.updateArrows=function(){var b,a=this;b=Math.floor(a.options.slidesToShow/2),a.options.arrows===!0&&a.slideCount>a.options.slidesToShow&&!a.options.infinite&&(a.$prevArrow.removeClass("slick-disabled").attr("aria-disabled","false"),a.$nextArrow.removeClass("slick-disabled").attr("aria-disabled","false"),0===a.currentSlide?(a.$prevArrow.addClass("slick-disabled").attr("aria-disabled","true"),a.$nextArrow.removeClass("slick-disabled").attr("aria-disabled","false")):a.currentSlide>=a.slideCount-a.options.slidesToShow&&a.options.centerMode===!1?(a.$nextArrow.addClass("slick-disabled").attr("aria-disabled","true"),a.$prevArrow.removeClass("slick-disabled").attr("aria-disabled","false")):a.currentSlide>=a.slideCount-1&&a.options.centerMode===!0&&(a.$nextArrow.addClass("slick-disabled").attr("aria-disabled","true"),a.$prevArrow.removeClass("slick-disabled").attr("aria-disabled","false")))},b.prototype.updateDots=function(){var a=this;null!==a.$dots&&(a.$dots.find("li").removeClass("slick-active").attr("aria-hidden","true"),a.$dots.find("li").eq(Math.floor(a.currentSlide/a.options.slidesToScroll)).addClass("slick-active").attr("aria-hidden","false"))},b.prototype.visibility=function(){var a=this;a.options.autoplay&&(document[a.hidden]?a.interrupted=!0:a.interrupted=!1)},a.fn.slick=function(){var f,g,a=this,c=arguments[0],d=Array.prototype.slice.call(arguments,1),e=a.length;for(f=0;e>f;f++)if("object"==typeof c||"undefined"==typeof c?a[f].slick=new b(a[f],c):g=a[f].slick[c].apply(a[f].slick,d),"undefined"!=typeof g)return g;return a}}); 2818/*! 2819 * imagesLoaded PACKAGED v4.1.3 2820 * JavaScript is all like "You images are done yet or what?" 2821 * MIT License 2822 */ 2823 2824!function(e,t){"function"==typeof define&&define.amd?define("ev-emitter/ev-emitter",t):"object"==typeof module&&module.exports?module.exports=t():e.EvEmitter=t()}("undefined"!=typeof window?window:this,function(){function e(){}var t=e.prototype;return t.on=function(e,t){if(e&&t){var i=this._events=this._events||{},n=i[e]=i[e]||[];return-1==n.indexOf(t)&&n.push(t),this}},t.once=function(e,t){if(e&&t){this.on(e,t);var i=this._onceEvents=this._onceEvents||{},n=i[e]=i[e]||{};return n[t]=!0,this}},t.off=function(e,t){var i=this._events&&this._events[e];if(i&&i.length){var n=i.indexOf(t);return-1!=n&&i.splice(n,1),this}},t.emitEvent=function(e,t){var i=this._events&&this._events[e];if(i&&i.length){var n=0,o=i[n];t=t||[];for(var r=this._onceEvents&&this._onceEvents[e];o;){var s=r&&r[o];s&&(this.off(e,o),delete r[o]),o.apply(this,t),n+=s?0:1,o=i[n]}return this}},t.allOff=t.removeAllListeners=function(){delete this._events,delete this._onceEvents},e}),function(e,t){"use strict";"function"==typeof define&&define.amd?define(["ev-emitter/ev-emitter"],function(i){return t(e,i)}):"object"==typeof module&&module.exports?module.exports=t(e,require("ev-emitter")):e.imagesLoaded=t(e,e.EvEmitter)}("undefined"!=typeof window?window:this,function(e,t){function i(e,t){for(var i in t)e[i]=t[i];return e}function n(e){var t=[];if(Array.isArray(e))t=e;else if("number"==typeof e.length)for(var i=0;i<e.length;i++)t.push(e[i]);else t.push(e);return t}function o(e,t,r){return this instanceof o?("string"==typeof e&&(e=document.querySelectorAll(e)),this.elements=n(e),this.options=i({},this.options),"function"==typeof t?r=t:i(this.options,t),r&&this.on("always",r),this.getImages(),h&&(this.jqDeferred=new h.Deferred),void setTimeout(function(){this.check()}.bind(this))):new o(e,t,r)}function r(e){this.img=e}function s(e,t){this.url=e,this.element=t,this.img=new Image}var h=e.jQuery,a=e.console;o.prototype=Object.create(t.prototype),o.prototype.options={},o.prototype.getImages=function(){this.images=[],this.elements.forEac
2824h(this.addElementImages,this)},o.prototype.addElementImages=function(e){"IMG"==e.nodeName&&this.addImage(e),this.options.background===!0&&this.addElementBackgroundImages(e);var t=e.nodeType;if(t&&d[t]){for(var i=e.querySelectorAll("img"),n=0;n<i.length;n++){var o=i[n];this.addImage(o)}if("string"==typeof this.options.background){var r=e.querySelectorAll(this.options.background);for(n=0;n<r.length;n++){var s=r[n];this.addElementBackgroundImages(s)}}}};var d={1:!0,9:!0,11:!0};return o.prototype.addElementBackgroundImages=function(e){var t=getComputedStyle(e);if(t)for(var i=/url\((['"])?(.*?)\1\)/gi,n=i.exec(t.backgroundImage);null!==n;){var o=n&&n[2];o&&this.addBackground(o,e),n=i.exec(t.backgroundImage)}},o.prototype.addImage=function(e){var t=new r(e);this.images.push(t)},o.prototype.addBackground=function(e,t){var i=new s(e,t);this.images.push(i)},o.prototype.check=function(){function e(e,i,n){setTimeout(function(){t.progress(e,i,n)})}var t=this;return this.progressedCount=0,this.hasAnyBroken=!1,this.images.length?void this.images.forEach(function(t){t.once("progress",e),t.check()}):void this.complete()},o.prototype.progress=function(e,t,i){this.progressedCount++,this.hasAnyBroken=this.hasAnyBroken||!e.isLoaded,this.emitEvent("progress",[this,e,t]),this.jqDeferred&&this.jqDeferred.notify&&this.jqDeferred.notify(this,e),this.progressedCount==this.images.length&&this.complete(),this.options.debug&&a&&a.log("progress: "+i,e,t)},o.prototype.complete=function(){var e=this.hasAnyBroken?"fail":"done";if(this.isComplete=!0,this.emitEvent(e,[this]),this.emitEvent("always",[this]),this.jqDeferred){var t=this.hasAnyBroken?"reject":"resolve";this.jqDeferred[t](this)}},r.prototype=Object.create(t.prototype),r.prototype.check=function(){var e=this.getIsImageComplete();return e?void this.confirm(0!==this.img.naturalWidth,"naturalWidth"):(this.proxyImage=new Image,this.proxyImage.addEventListener("load",this),this.proxyImage.addEventListener("error",this),this.img.addEventListener("load",this),this.img.addEventListener("error",this),void(this.proxyImage.src=this.img.src))},r.prototype.getIsImageComplete=function(){return this.img.complete&&void 0!==this.img.naturalWidth},r.prototype.confirm=function(e,t){this.isLoaded=e,this.emitEvent("progress",[this,this.img,t])},r.prototype.handleEvent=function(e){var t="on"+e.type;this[t]&&this[t](e)},r.prototype.onload=function(){this.confirm(!0,"onload"),this.unbindEvents()},r.prototype.onerror=function(){this.confirm(!1,"onerror"),this.unbindEvents()},r.prototype.unbindEvents=function(){this.proxyImage.removeEventListener("load",this),this.proxyImage.removeEventListener("error",this),this.img.removeEventListener("load",this),this.img.removeEventListener("error",this)},s.prototype=Object.create(r.prototype),s.prototype.check=function(){this.img.addEventListener("load",this),this.img.addEventListener("error",this),this.img.src=this.url;var e=this.getIsImageComplete();e&&(this.confirm(0!==this.img.naturalWidth,"naturalWidth"),this.unbindEvents())},s.prototype.unbindEvents=function(){this.img.removeEventListener("load",this),this.img.removeEventListener("error",this)},s.prototype.confirm=function(e,t){this.isLoaded=e,this.emitEvent("progress",[this,this.element,t])},o.makeJQueryPlugin=function(t){t=t||e.jQuery,t&&(h=t,h.fn.imagesLoaded=function(e,t){var i=new o(this,e,t);return i.jqDeferred.promise(h(this))})},o.makeJQueryPlugin(),o}); 2825/*! 2826 * Masonry PACKAGED v4.2.0 2827 * Cascading grid layout library 2828 * http://masonry.desandro.com 2829 * MIT License 2830 * by David DeSandro 2831 */ 2832 2833/** 2834 * Bridget makes jQuery widgets 2835 * v2.0.1 2836 * MIT license 2837 */ 2838 2839/* jshint browser: true, strict: true, undef: true, unused: true */ 2840 2841( function( window, factory ) { 2842 // universal module definition 2843 /*jshint strict: false */ /* globals define, module, require */ 2844 if ( typeof define == 'function' && define.amd ) { 2845 // AMD 2846 define( 'jquery-bridget/jquery-bridget',[ 'jquery' ], function( jQuery ) { 2847 return factory( window, jQuery ); 2848 }); 2849 } else if ( typeof module == 'object' && module.exports ) { 2850 // CommonJS 2851 module.exports = factory( 2852 window, 2853 require('jquery') 2854 ); 2855 } else { 2856 // browser global 2857 window.jQueryBridget = factory( 2858 window, 2859 window.jQuery 2860 ); 2861 } 2862 2863}( window, function factory( window, jQuery ) { 2864'use strict'; 2865 2866// ----- utils ----- // 2867 2868var arraySlice = Array.prototype.slice; 2869 2870// helper function for logging errors 2871// $.error breaks jQuery chaining 2872var console = window.console; 2873var logError = typeof console == 'undefined' ? function() {} : 2874 function( message ) { 2875 console.error( message ); 2876 }; 2877 2878// ----- jQueryBridget ----- // 2879 2880function jQueryBridget( namespace, PluginClass, $ ) { 2881 $ = $ || jQuery || window.jQuery; 2882 if ( !$ ) { 2883 return; 2884 } 2885 2886 // add option method -> $().plugin('option', {...}) 2887 if ( !PluginClass.prototype.option ) { 2888 // option setter 2889 PluginClass.prototype.option = function( opts ) { 2890 // bail out if not an object 2891 if ( !$.isPlainObject( opts ) ){ 2892 return; 2893 } 2894 this.options = $.extend( true, this.options, opts ); 2895 }; 2896 } 2897 2898 // make jQuery plugin 2899 $.fn[ namespace ] = function( arg0 /*, arg1 */ ) { 2900 if ( typeof arg0 == 'string' ) { 2901 // method call $().plugin( 'methodName', { options } ) 2902 // shift arguments by 1 2903 var args = arraySlice.call( arguments, 1 ); 2904 return methodCall( this, arg0, args ); 2905 } 2906 // just $().plugin({ options }) 2907 plainCall( this, arg0 ); 2908 return this; 2909 }; 2910 2911 // $().plugin('methodName') 2912 function methodCall( $elems, methodName, args ) { 2913 var returnValue; 2914 var pluginMethodStr = '$().' + namespace + '("' + methodName + '")'; 2915 2916 $elems.each( function( i, elem ) { 2917 // get instance 2918 var instance = $.data( elem, namespace ); 2919 if ( !instance ) { 2920 logError( namespace + ' not initialized. Cannot call methods, i.e. ' + 2921 pluginMethodStr ); 2922 return; 2923 } 2924 2925 var method = instance[ methodName ]; 2926 if ( !method || methodName.charAt(0) == '_' ) { 2927 logError( pluginMethodStr + ' is not a valid method' ); 2928 return; 2929 } 2930 2931 // apply method, get return value 2932 var value = method.apply( instance, args ); 2933 // set return value if value is returned, use only first value 2934 returnValue = returnValue === undefined ? value : returnValue; 2935 }); 2936 2937 return returnValue !== undefined ? returnValue : $elems; 2938 } 2939 2940 function plainCall( $elems, options ) { 2941 $elems.each( function( i, elem ) { 2942 var instance = $.data( elem, namespace ); 2943 if ( instance ) { 2944 // set options & init 2945 instance.option( options ); 2946 instance._init(); 2947 } else { 2948 // initialize new instance 2949 instance = new PluginClass( elem, options ); 2950 $.data( elem, namespace, instance ); 2951 } 2952 }); 2953 } 2954 2955 updateJQuery( $ ); 2956 2957} 2958
vendor: 16,343 bytes, lines 2959-3627
2959// ----- updateJQuery ----- // 2960 2961// set $.bridget for v1 backwards compatibility 2962function updateJQuery( $ ) { 2963 if ( !$ || ( $ && $.bridget ) ) { 2964 return; 2965 } 2966 $.bridget = jQueryBridget; 2967} 2968 2969updateJQuery( jQuery || window.jQuery ); 2970 2971// ----- ----- // 2972 2973return jQueryBridget; 2974 2975})); 2976 2977/** 2978 * EvEmitter v1.0.3 2979 * Lil' event emitter 2980 * MIT License 2981 */ 2982 2983/* jshint unused: true, undef: true, strict: true */ 2984 2985( function( global, factory ) { 2986 // universal module definition 2987 /* jshint strict: false */ /* globals define, module, window */ 2988 if ( typeof define == 'function' && define.amd ) { 2989 // AMD - RequireJS 2990 define( 'ev-emitter/ev-emitter',factory ); 2991 } else if ( typeof module == 'object' && module.exports ) { 2992 // CommonJS - Browserify, Webpack 2993 module.exports = factory(); 2994 } else { 2995 // Browser globals 2996 global.EvEmitter = factory(); 2997 } 2998 2999}( typeof window != 'undefined' ? window : this, function() { 3000 3001 3002 3003function EvEmitter() {} 3004 3005var proto = EvEmitter.prototype; 3006 3007proto.on = function( eventName, listener ) { 3008 if ( !eventName || !listener ) { 3009 return; 3010 } 3011 // set events hash 3012 var events = this._events = this._events || {}; 3013 // set listeners array 3014 var listeners = events[ eventName ] = events[ eventName ] || []; 3015 // only add once 3016 if ( listeners.indexOf( listener ) == -1 ) { 3017 listeners.push( listener ); 3018 } 3019 3020 return this; 3021}; 3022 3023proto.once = function( eventName, listener ) { 3024 if ( !eventName || !listener ) { 3025 return; 3026 } 3027 // add event 3028 this.on( eventName, listener ); 3029 // set once flag 3030 // set onceEvents hash 3031 var onceEvents = this._onceEvents = this._onceEvents || {}; 3032 // set onceListeners object 3033 var onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {}; 3034 // set flag 3035 onceListeners[ listener ] = true; 3036 3037 return this; 3038}; 3039 3040proto.off = function( eventName, listener ) { 3041 var listeners = this._events && this._events[ eventName ]; 3042 if ( !listeners || !listeners.length ) { 3043 return; 3044 } 3045 var index = listeners.indexOf( listener ); 3046 if ( index != -1 ) { 3047 listeners.splice( index, 1 ); 3048 } 3049 3050 return this; 3051}; 3052 3053proto.emitEvent = function( eventName, args ) { 3054 var listeners = this._events && this._events[ eventName ]; 3055 if ( !listeners || !listeners.length ) { 3056 return; 3057 } 3058 var i = 0; 3059 var listener = listeners[i]; 3060 args = args || []; 3061 // once stuff 3062 var onceListeners = this._onceEvents && this._onceEvents[ eventName ]; 3063 3064 while ( listener ) { 3065 var isOnce = onceListeners && onceListeners[ listener ]; 3066 if ( isOnce ) { 3067 // remove listener 3068 // remove before trigger to prevent recursion 3069 this.off( eventName, listener ); 3070 // unset once flag 3071 delete onceListeners[ listener ]; 3072 } 3073 // trigger listener 3074 listener.apply( this, args ); 3075 // get next listener 3076 i += isOnce ? 0 : 1; 3077 listener = listeners[i]; 3078 } 3079 3080 return this; 3081}; 3082 3083return EvEmitter; 3084 3085})); 3086 3087/*! 3088 * getSize v2.0.2 3089 * measure size of elements 3090 * MIT license 3091 */ 3092 3093/*jshint browser: true, strict: true, undef: true, unused: true */ 3094/*global define: false, module: false, console: false */ 3095 3096( function( window, factory ) { 3097 'use strict'; 3098 3099 if ( typeof define == 'function' && define.amd ) { 3100 // AMD 3101 define( 'get-size/get-size',[],function() { 3102 return factory(); 3103 }); 3104 } else if ( typeof module == 'object' && module.exports ) { 3105 // CommonJS 3106 module.exports = factory(); 3107 } else { 3108 // browser global 3109 window.getSize = factory(); 3110 } 3111 3112})( window, function factory() { 3113'use strict'; 3114 3115// -------------------------- helpers -------------------------- // 3116 3117// get a number from a string, not a percentage 3118function getStyleSize( value ) { 3119 var num = parseFloat( value ); 3120 // not a percent like '100%', and a number 3121 var isValid = value.indexOf('%') == -1 && !isNaN( num ); 3122 return isValid && num; 3123} 3124 3125function noop() {} 3126 3127var logError = typeof console == 'undefined' ? noop : 3128 function( message ) { 3129 console.error( message ); 3130 }; 3131 3132// -------------------------- measurements -------------------------- // 3133 3134var measurements = [ 3135 'paddingLeft', 3136 'paddingRight', 3137 'paddingTop', 3138 'paddingBottom', 3139 'marginLeft', 3140 'marginRight', 3141 'marginTop', 3142 'marginBottom', 3143 'borderLeftWidth', 3144 'borderRightWidth', 3145 'borderTopWidth', 3146 'borderBottomWidth' 3147]; 3148 3149var measurementsLength = measurements.length; 3150 3151function getZeroSize() { 3152 var size = { 3153 width: 0, 3154 height: 0, 3155 innerWidth: 0, 3156 innerHeight: 0, 3157 outerWidth: 0, 3158 outerHeight: 0 3159 }; 3160 for ( var i=0; i < measurementsLength; i++ ) { 3161 var measurement = measurements[i]; 3162 size[ measurement ] = 0; 3163 } 3164 return size; 3165} 3166 3167// -------------------------- getStyle -------------------------- // 3168 3169/** 3170 * getStyle, get style of element, check for Firefox bug 3171 * https://bugzilla.mozilla.org/show_bug.cgi?id=548397 3172 */ 3173function getStyle( elem ) { 3174 var style = getComputedStyle( elem ); 3175 if ( !style ) { 3176 logError( 'Style returned ' + style + 3177 '. Are you running this code in a hidden iframe on Firefox? ' + 3178 'See http://bit.ly/getsizebug1' ); 3179 } 3180 return style; 3181} 3182 3183// -------------------------- setup -------------------------- // 3184 3185var isSetup = false; 3186 3187var isBoxSizeOuter; 3188 3189/** 3190 * setup 3191 * check isBoxSizerOuter 3192 * do on first getSize() rather than on page load for Firefox bug 3193 */ 3194function setup() { 3195 // setup once 3196 if ( isSetup ) { 3197 return; 3198 } 3199 isSetup = true; 3200 3201 // -------------------------- box sizing -------------------------- // 3202 3203 /** 3204 * WebKit measures the outer-width on style.width on border-box elems 3205 * IE & Firefox<29 measures the inner-width 3206 */ 3207 var div = document.createElement('div'); 3208 div.style.width = '200px'; 3209 div.style.padding = '1px 2px 3px 4px'; 3210 div.style.borderStyle = 'solid'; 3211 div.style.borderWidth = '1px 2px 3px 4px'; 3212 div.style.boxSizing = 'border-box'; 3213 3214 var body = document.body || document.documentElement; 3215 body.appendChild( div ); 3216 var style = getStyle( div ); 3217 3218 getSize.isBoxSizeOuter = isBoxSizeOuter = getStyleSize( style.width ) == 200; 3219 body.removeChild( div ); 3220 3221} 3222 3223// -------------------------- getSize -------------------------- // 3224 3225function getSize( elem ) { 3226 setup(); 3227 3228 // use querySeletor if elem is string 3229 if ( typeof elem == 'string' ) { 3230 elem = document.querySelector( elem ); 3231 } 3232 3233 // do not proceed on non-objects 3234 if ( !elem || typeof elem != 'object' || !elem.nodeType ) { 3235 return; 3236 } 3237 3238 var style = getStyle( elem ); 3239 3240 // if hidden, everything is 0 3241 if ( style.display == 'none' ) { 3242 return getZeroSize(); 3243 } 3244 3245 var size = {}; 3246 size.width = elem.offsetWidth; 3247 size.height = elem.offsetHeight; 3248 3249 var isBorderBox = size.isBorderBox = style.boxSizing == 'border-box'; 3250 3251 // get all measurements 3252 for ( var i=0; i < measurementsLength; i++ ) { 3253 var measurement = measurements[i]; 3254 var value = style[ measurement ]; 3255 var num = parseFloat( value ); 3256 // any 'auto', 'medium' value will be 0 3257 size[ measurement ] = !isNaN( num ) ? num : 0; 3258 } 3259 3260 var paddingWidth = size.paddingLeft + size.paddingRight; 3261 var paddingHeight = size.paddingTop + size.paddingBottom; 3262 var marginWidth = size.marginLeft + size.marginRight; 3263 var marginHeight = size.marginTop + size.marginBottom; 3264 var borderWidth = size.borderLeftWidth + size.borderRightWidth; 3265 var borderHeight = size.borderTopWidth + size.borderBottomWidth; 3266 3267 var isBorderBoxSizeOuter = isBorderBox && isBoxSizeOuter; 3268 3269 // overwrite width and height if we can get it from style 3270 var styleWidth = getStyleSize( style.width ); 3271 if ( styleWidth !== false ) { 3272 size.width = styleWidth + 3273 // add padding and border unless it's already including it 3274 ( isBorderBoxSizeOuter ? 0 : paddingWidth + borderWidth ); 3275 } 3276 3277 var styleHeight = getStyleSize( style.height ); 3278 if ( styleHeight !== false ) { 3279 size.height = styleHeight + 3280 // add padding and border unless it's already including it 3281 ( isBorderBoxSizeOuter ? 0 : paddingHeight + borderHeight ); 3282 } 3283 3284 size.innerWidth = size.width - ( paddingWidth + borderWidth ); 3285 size.innerHeight = size.height - ( paddingHeight + borderHeight ); 3286 3287 size.outerWidth = size.width + marginWidth; 3288 size.outerHeight = size.height + marginHeight; 3289 3290 return size; 3291} 3292 3293return getSize; 3294 3295}); 3296 3297/** 3298 * matchesSelector v2.0.2 3299 * matchesSelector( element, '.selector' ) 3300 * MIT license 3301 */ 3302 3303/*jshint browser: true, strict: true, undef: true, unused: true */ 3304 3305( function( window, factory ) { 3306 /*global define: false, module: false */ 3307 'use strict'; 3308 // universal module definition 3309 if ( typeof define == 'function' && define.amd ) { 3310 // AMD 3311 define( 'desandro-matches-selector/matches-selector',factory ); 3312 } else if ( typeof module == 'object' && module.exports ) { 3313 // CommonJS 3314 module.exports = factory(); 3315 } else { 3316 // browser global 3317 window.matchesSelector = factory(); 3318 } 3319 3320}( window, function factory() { 3321 'use strict'; 3322 3323 var matchesMethod = ( function() { 3324 var ElemProto = window.Element.prototype; 3325 // check for the standard method name first 3326 if ( ElemProto.matches ) { 3327 return 'matches'; 3328 } 3329 // check un-prefixed 3330 if ( ElemProto.matchesSelector ) { 3331 return 'matchesSelector'; 3332 } 3333 // check vendor prefixes 3334 var prefixes = [ 'webkit', 'moz', 'ms', 'o' ]; 3335 3336 for ( var i=0; i < prefixes.length; i++ ) { 3337 var prefix = prefixes[i]; 3338 var method = prefix + 'MatchesSelector'; 3339 if ( ElemProto[ method ] ) { 3340 return method; 3341 } 3342 } 3343 })(); 3344 3345 return function matchesSelector( elem, selector ) { 3346 return elem[ matchesMethod ]( selector ); 3347 }; 3348 3349})); 3350 3351/** 3352 * Fizzy UI utils v2.0.4 3353 * MIT license 3354 */ 3355 3356/*jshint browser: true, undef: true, unused: true, strict: true */ 3357 3358( function( window, factory ) { 3359 // universal module definition 3360 /*jshint strict: false */ /*globals define, module, require */ 3361 3362 if ( typeof define == 'function' && define.amd ) { 3363 // AMD 3364 define( 'fizzy-ui-utils/utils',[ 3365 'desandro-matches-selector/matches-selector' 3366 ], function( matchesSelector ) { 3367 return factory( window, matchesSelector ); 3368 }); 3369 } else if ( typeof module == 'object' && module.exports ) { 3370 // CommonJS 3371 module.exports = factory( 3372 window, 3373 require('desandro-matches-selector') 3374 ); 3375 } else { 3376 // browser global 3377 window.fizzyUIUtils = factory( 3378 window, 3379 window.matchesSelector 3380 ); 3381 } 3382 3383}( window, function factory( window, matchesSelector ) { 3384 3385 3386 3387var utils = {}; 3388 3389// ----- extend ----- // 3390 3391// extends objects 3392utils.extend = function( a, b ) { 3393 for ( var prop in b ) { 3394 a[ prop ] = b[ prop ]; 3395 } 3396 return a; 3397}; 3398 3399// ----- modulo ----- // 3400 3401utils.modulo = function( num, div ) { 3402 return ( ( num % div ) + div ) % div; 3403}; 3404 3405// ----- makeArray ----- // 3406 3407// turn element or nodeList into an array 3408utils.makeArray = function( obj ) { 3409 var ary = []; 3410 if ( Array.isArray( obj ) ) { 3411 // use object if already an array 3412 ary = obj; 3413 } else if ( obj && typeof obj == 'object' && 3414 typeof obj.length == 'number' ) { 3415 // convert nodeList to array 3416 for ( var i=0; i < obj.length; i++ ) { 3417 ary.push( obj[i] ); 3418 } 3419 } else { 3420 // array of single index 3421 ary.push( obj ); 3422 } 3423 return ary; 3424}; 3425 3426// ----- removeFrom ----- // 3427 3428utils.removeFrom = function( ary, obj ) { 3429 var index = ary.indexOf( obj ); 3430 if ( index != -1 ) { 3431 ary.splice( index, 1 ); 3432 } 3433}; 3434 3435// ----- getParent ----- // 3436 3437utils.getParent = function( elem, selector ) { 3438 while ( elem != document.body ) { 3439 elem = elem.parentNode; 3440 if ( matchesSelector( elem, selector ) ) { 3441 return elem; 3442 } 3443 } 3444}; 3445 3446// ----- getQueryElement ----- // 3447 3448// use element as selector string 3449utils.getQueryElement = function( elem ) { 3450 if ( typeof elem == 'string' ) { 3451 return document.querySelector( elem ); 3452 } 3453 return elem; 3454}; 3455 3456// ----- handleEvent ----- // 3457 3458// enable .ontype to trigger from .addEventListener( elem, 'type' ) 3459utils.handleEvent = function( event ) { 3460 var method = 'on' + event.type; 3461 if ( this[ method ] ) { 3462 this[ method ]( event ); 3463 } 3464}; 3465 3466// ----- filterFindElements ----- // 3467 3468utils.filterFindElements = function( elems, selector ) { 3469 // make array of elems 3470 elems = utils.makeArray( elems ); 3471 var ffElems = []; 3472 3473 elems.forEach( function( elem ) { 3474 // check that elem is an actual element 3475 if ( !( elem instanceof HTMLElement ) ) { 3476 return; 3477 } 3478 // add elem if no selector 3479 if ( !selector ) { 3480 ffElems.push( elem ); 3481 return; 3482 } 3483 // filter & find items if we have a selector 3484 // filter 3485 if ( matchesSelector( elem, selector ) ) { 3486 ffElems.push( elem ); 3487 } 3488 // find children 3489 var childElems = elem.querySelectorAll( selector ); 3490 // concat childElems to filterFound array 3491 for ( var i=0; i < childElems.length; i++ ) { 3492 ffElems.push( childElems[i] ); 3493 } 3494 }); 3495 3496 return ffElems; 3497}; 3498 3499// ----- debounceMethod ----- // 3500 3501utils.debounceMethod = function( _class, methodName, threshold ) { 3502 // original method 3503 var method = _class.prototype[ methodName ]; 3504 var timeoutName = methodName + 'Timeout'; 3505 3506 _class.prototype[ methodName ] = function() { 3507 var timeout = this[ timeoutName ]; 3508 if ( timeout ) { 3509 clearTimeout( timeout ); 3510 } 3511 var args = arguments; 3512 3513 var _this = this; 3514 this[ timeoutName ] = setTimeout( function() { 3515 method.apply( _this, args ); 3516 delete _this[ timeoutName ]; 3517 }, threshold || 100 ); 3518 }; 3519}; 3520 3521// ----- docReady ----- // 3522 3523utils.docReady = function( callback ) { 3524 var readyState = document.readyState; 3525 if ( readyState == 'complete' || readyState == 'interactive' ) { 3526 // do async to allow for other scripts to run. metafizzy/flickity#441 3527 setTimeout( callback ); 3528 } else { 3529 document.addEventListener( 'DOMContentLoaded', callback ); 3530 } 3531}; 3532 3533// ----- htmlInit ----- // 3534 3535// http://jamesroberts.name/blog/2010/02/22/string-functions-for-javascript-trim-to-camel-case-to-dashed-and-to-underscore/ 3536utils.toDashed = function( str ) { 3537 return str.replace( /(.)([A-Z])/g, function( match, $1, $2 ) { 3538 return $1 + '-' + $2; 3539 }).toLowerCase(); 3540}; 3541 3542var console = window.console; 3543/** 3544 * allow user to initialize classes via [data-namespace] or .js-namespace class 3545 * htmlInit( Widget, 'widgetName' ) 3546 * options are parsed from data-namespace-options 3547 */ 3548utils.htmlInit = function( WidgetClass, namespace ) { 3549 utils.docReady( function() { 3550 var dashedNamespace = utils.toDashed( namespace ); 3551 var dataAttr = 'data-' + dashedNamespace; 3552 var dataAttrElems = document.querySelectorAll( '[' + dataAttr + ']' ); 3553 var jsDashElems = document.querySelectorAll( '.js-' + dashedNamespace ); 3554 var elems = utils.makeArray( dataAttrElems ) 3555 .concat( utils.makeArray( jsDashElems ) ); 3556 var dataOptionsAttr = dataAttr + '-options'; 3557 var jQuery = window.jQuery; 3558 3559 elems.forEach( function( elem ) { 3560 var attr = elem.getAttribute( dataAttr ) || 3561 elem.getAttribute( dataOptionsAttr ); 3562 var options; 3563 try { 3564 options = attr && JSON.parse( attr ); 3565 } catch ( error ) { 3566 // log error, do not initialize 3567 if ( console ) { 3568 console.error( 'Error parsing ' + dataAttr + ' on ' + elem.className + 3569 ': ' + error ); 3570 } 3571 return; 3572 } 3573 // initialize 3574 var instance = new WidgetClass( elem, options ); 3575 // make available via $().data('namespace') 3576 if ( jQuery ) { 3577 jQuery.data( elem, namespace, instance ); 3578 } 3579 }); 3580 3581 }); 3582}; 3583 3584// ----- ----- // 3585 3586return utils; 3587 3588})); 3589 3590/** 3591 * Outlayer Item 3592 */ 3593 3594( function( window, factory ) { 3595 // universal module definition 3596 /* jshint strict: false */ /* globals define, module, require */ 3597 if ( typeof define == 'function' && define.amd ) { 3598 // AMD - RequireJS 3599 define( 'outlayer/item',[ 3600 'ev-emitter/ev-emitter', 3601 'get-size/get-size' 3602 ], 3603 factory 3604 ); 3605 } else if ( typeof module == 'object' && module.exports ) { 3606 // CommonJS - Browserify, Webpack 3607 module.exports = factory( 3608 require('ev-emitter'), 3609 require('get-size') 3610 ); 3611 } else { 3612 // browser global 3613 window.Outlayer = {}; 3614 window.Outlayer.Item = factory( 3615 window.EvEmitter, 3616 window.getSize 3617 ); 3618 } 3619 3620}( window, function factory( EvEmitter, getSize ) { 3621'use strict'; 3622 3623// ----- helpers ----- // 3624 3625function isEmptyObj( obj ) { 3626 for ( var prop in obj ) { 3627 return false;
vendor: 4,399 bytes, lines 3628-3784
3628 } 3629 prop = null; 3630 return true; 3631} 3632 3633// -------------------------- CSS3 support -------------------------- // 3634 3635 3636var docElemStyle = document.documentElement.style; 3637 3638var transitionProperty = typeof docElemStyle.transition == 'string' ? 3639 'transition' : 'WebkitTransition'; 3640var transformProperty = typeof docElemStyle.transform == 'string' ? 3641 'transform' : 'WebkitTransform'; 3642 3643var transitionEndEvent = { 3644 WebkitTransition: 'webkitTransitionEnd', 3645 transition: 'transitionend' 3646}[ transitionProperty ]; 3647 3648// cache all vendor properties that could have vendor prefix 3649var vendorProperties = { 3650 transform: transformProperty, 3651 transition: transitionProperty, 3652 transitionDuration: transitionProperty + 'Duration', 3653 transitionProperty: transitionProperty + 'Property', 3654 transitionDelay: transitionProperty + 'Delay' 3655}; 3656 3657// -------------------------- Item -------------------------- // 3658 3659function Item( element, layout ) { 3660 if ( !element ) { 3661 return; 3662 } 3663 3664 this.element = element; 3665 // parent layout class, i.e. Masonry, Isotope, or Packery 3666 this.layout = layout; 3667 this.position = { 3668 x: 0, 3669 y: 0 3670 }; 3671 3672 this._create(); 3673} 3674 3675// inherit EvEmitter 3676var proto = Item.prototype = Object.create( EvEmitter.prototype ); 3677proto.constructor = Item; 3678 3679proto._create = function() { 3680 // transition objects 3681 this._transn = { 3682 ingProperties: {}, 3683 clean: {}, 3684 onEnd: {} 3685 }; 3686 3687 this.css({ 3688 position: 'absolute' 3689 }); 3690}; 3691 3692// trigger specified handler for event type 3693proto.handleEvent = function( event ) { 3694 var method = 'on' + event.type; 3695 if ( this[ method ] ) { 3696 this[ method ]( event ); 3697 } 3698}; 3699 3700proto.getSize = function() { 3701 this.size = getSize( this.element ); 3702}; 3703 3704/** 3705 * apply CSS styles to element 3706 * @param {Object} style 3707 */ 3708proto.css = function( style ) { 3709 var elemStyle = this.element.style; 3710 3711 for ( var prop in style ) { 3712 // use vendor property if available 3713 var supportedProp = vendorProperties[ prop ] || prop; 3714 elemStyle[ supportedProp ] = style[ prop ]; 3715 } 3716}; 3717 3718 // measure position, and sets it 3719proto.getPosition = function() { 3720 var style = getComputedStyle( this.element ); 3721 var isOriginLeft = this.layout._getOption('originLeft'); 3722 var isOriginTop = this.layout._getOption('originTop'); 3723 var xValue = style[ isOriginLeft ? 'left' : 'right' ]; 3724 var yValue = style[ isOriginTop ? 'top' : 'bottom' ]; 3725 // convert percent to pixels 3726 var layoutSize = this.layout.size; 3727 var x = xValue.indexOf('%') != -1 ? 3728 ( parseFloat( xValue ) / 100 ) * layoutSize.width : parseInt( xValue, 10 ); 3729 var y = yValue.indexOf('%') != -1 ? 3730 ( parseFloat( yValue ) / 100 ) * layoutSize.height : parseInt( yValue, 10 ); 3731 3732 // clean up 'auto' or other non-integer values 3733 x = isNaN( x ) ? 0 : x; 3734 y = isNaN( y ) ? 0 : y; 3735 // remove padding from measurement 3736 x -= isOriginLeft ? layoutSize.paddingLeft : layoutSize.paddingRight; 3737 y -= isOriginTop ? layoutSize.paddingTop : layoutSize.paddingBottom; 3738 3739 this.position.x = x; 3740 this.position.y = y; 3741}; 3742 3743// set settled position, apply padding 3744proto.layoutPosition = function() { 3745 var layoutSize = this.layout.size; 3746 var style = {}; 3747 var isOriginLeft = this.layout._getOption('originLeft'); 3748 var isOriginTop = this.layout._getOption('originTop'); 3749 3750 // x 3751 var xPadding = isOriginLeft ? 'paddingLeft' : 'paddingRight'; 3752 var xProperty = isOriginLeft ? 'left' : 'right'; 3753 var xResetProperty = isOriginLeft ? 'right' : 'left'; 3754 3755 var x = this.position.x + layoutSize[ xPadding ]; 3756 // set in percentage or pixels 3757 style[ xProperty ] = this.getXValue( x ); 3758 // reset other property 3759 style[ xResetProperty ] = ''; 3760 3761 // y 3762 var yPadding = isOriginTop ? 'paddingTop' : 'paddingBottom'; 3763 var yProperty = isOriginTop ? 'top' : 'bottom'; 3764 var yResetProperty = isOriginTop ? 'bottom' : 'top'; 3765 3766 var y = this.position.y + layoutSize[ yPadding ]; 3767 // set in percentage or pixels 3768 style[ yProperty ] = this.getYValue( y ); 3769 // reset other property 3770 style[ yResetProperty ] = ''; 3771 3772 this.css( style ); 3773 this.emitEvent( 'layout', [ this ] ); 3774}; 3775 3776proto.getXValue = function( x ) { 3777 var isHorizontal = this.layout._getOption('horizontal'); 3778 return this.layout.options.percentPosition && !isHorizontal ? 3779 ( ( x / this.layout.size.width ) * 100 ) + '%' : x + 'px'; 3780}; 3781 3782proto.getYValue = function( y ) { 3783 var isHorizontal = this.layout._getOption('horizontal'); 3784 return this.layout.options.percentPosition && isHorizontal ?
vendor: 6,161 bytes, lines 3785-3996
3785 ( ( y / this.layout.size.height ) * 100 ) + '%' : y + 'px'; 3786}; 3787 3788proto._transitionTo = function( x, y ) { 3789 this.getPosition(); 3790 // get current x & y from top/left 3791 var curX = this.position.x; 3792 var curY = this.position.y; 3793 3794 var compareX = parseInt( x, 10 ); 3795 var compareY = parseInt( y, 10 ); 3796 var didNotMove = compareX === this.position.x && compareY === this.position.y; 3797 3798 // save end position 3799 this.setPosition( x, y ); 3800 3801 // if did not move and not transitioning, just go to layout 3802 if ( didNotMove && !this.isTransitioning ) { 3803 this.layoutPosition(); 3804 return; 3805 } 3806 3807 var transX = x - curX; 3808 var transY = y - curY; 3809 var transitionStyle = {}; 3810 transitionStyle.transform = this.getTranslate( transX, transY ); 3811 3812 this.transition({ 3813 to: transitionStyle, 3814 onTransitionEnd: { 3815 transform: this.layoutPosition 3816 }, 3817 isCleaning: true 3818 }); 3819}; 3820 3821proto.getTranslate = function( x, y ) { 3822 // flip cooridinates if origin on right or bottom 3823 var isOriginLeft = this.layout._getOption('originLeft'); 3824 var isOriginTop = this.layout._getOption('originTop'); 3825 x = isOriginLeft ? x : -x; 3826 y = isOriginTop ? y : -y; 3827 return 'translate3d(' + x + 'px, ' + y + 'px, 0)'; 3828}; 3829 3830// non transition + transform support 3831proto.goTo = function( x, y ) { 3832 this.setPosition( x, y ); 3833 this.layoutPosition(); 3834}; 3835 3836proto.moveTo = proto._transitionTo; 3837 3838proto.setPosition = function( x, y ) { 3839 this.position.x = parseInt( x, 10 ); 3840 this.position.y = parseInt( y, 10 ); 3841}; 3842 3843// ----- transition ----- // 3844 3845/** 3846 * @param {Object} style - CSS 3847 * @param {Function} onTransitionEnd 3848 */ 3849 3850// non transition, just trigger callback 3851proto._nonTransition = function( args ) { 3852 this.css( args.to ); 3853 if ( args.isCleaning ) { 3854 this._removeStyles( args.to ); 3855 } 3856 for ( var prop in args.onTransitionEnd ) { 3857 args.onTransitionEnd[ prop ].call( this ); 3858 } 3859}; 3860 3861/** 3862 * proper transition 3863 * @param {Object} args - arguments 3864 * @param {Object} to - style to transition to 3865 * @param {Object} from - style to start transition from 3866 * @param {Boolean} isCleaning - removes transition styles after transition 3867 * @param {Function} onTransitionEnd - callback 3868 */ 3869proto.transition = function( args ) { 3870 // redirect to nonTransition if no transition duration 3871 if ( !parseFloat( this.layout.options.transitionDuration ) ) { 3872 this._nonTransition( args ); 3873 return; 3874 } 3875 3876 var _transition = this._transn; 3877 // keep track of onTransitionEnd callback by css property 3878 for ( var prop in args.onTransitionEnd ) { 3879 _transition.onEnd[ prop ] = args.onTransitionEnd[ prop ]; 3880 } 3881 // keep track of properties that are transitioning 3882 for ( prop in args.to ) { 3883 _transition.ingProperties[ prop ] = true; 3884 // keep track of properties to clean up when transition is done 3885 if ( args.isCleaning ) { 3886 _transition.clean[ prop ] = true; 3887 } 3888 } 3889 3890 // set from styles 3891 if ( args.from ) { 3892 this.css( args.from ); 3893 // force redraw. http://blog.alexmaccaw.com/css-transitions 3894 var h = this.element.offsetHeight; 3895 // hack for JSHint to hush about unused var 3896 h = null; 3897 } 3898 // enable transition 3899 this.enableTransition( args.to ); 3900 // set styles that are transitioning 3901 this.css( args.to ); 3902 3903 this.isTransitioning = true; 3904 3905}; 3906 3907// dash before all cap letters, including first for 3908// WebkitTransform => -webkit-transform 3909function toDashedAll( str ) { 3910 return str.replace( /([A-Z])/g, function( $1 ) { 3911 return '-' + $1.toLowerCase(); 3912 }); 3913} 3914 3915var transitionProps = 'opacity,' + toDashedAll( transformProperty ); 3916 3917proto.enableTransition = function(/* style */) { 3918 // HACK changing transitionProperty during a transition 3919 // will cause transition to jump 3920 if ( this.isTransitioning ) { 3921 return; 3922 } 3923 3924 // make `transition: foo, bar, baz` from style object 3925 // HACK un-comment this when enableTransition can work 3926 // while a transition is happening 3927 // var transitionValues = []; 3928 // for ( var prop in style ) { 3929 // // dash-ify camelCased properties like WebkitTransition 3930 // prop = vendorProperties[ prop ] || prop; 3931 // transitionValues.push( toDashedAll( prop ) ); 3932 // } 3933 // munge number to millisecond, to match stagger 3934 var duration = this.layout.options.transitionDuration; 3935 duration = typeof duration == 'number' ? duration + 'ms' : duration; 3936 // enable transition styles 3937 this.css({ 3938 transitionProperty: transitionProps, 3939 transitionDuration: duration, 3940 transitionDelay: this.staggerDelay || 0 3941 }); 3942 // listen for transition end event 3943 this.element.addEventListener( transitionEndEvent, this, false ); 3944}; 3945 3946// ----- events ----- // 3947 3948proto.onwebkitTransitionEnd = function( event ) { 3949 this.ontransitionend( event ); 3950}; 3951 3952proto.onotransitionend = function( event ) { 3953 this.ontransitionend( event ); 3954}; 3955 3956// properties that I munge to make my life easier 3957var dashedVendorProperties = { 3958 '-webkit-transform': 'transform' 3959}; 3960 3961proto.ontransitionend = function( event ) { 3962 // disregard bubbled events from children 3963 if ( event.target !== this.element ) { 3964 return; 3965 } 3966 var _transition = this._transn; 3967 // get property name of transitioned property, convert to prefix-free 3968 var propertyName = dashedVendorProperties[ event.propertyName ] || event.propertyName; 3969 3970 // remove property that has completed transitioning 3971 delete _transition.ingProperties[ propertyName ]; 3972 // check if any properties are still transitioning 3973 if ( isEmptyObj( _transition.ingProperties ) ) { 3974 // all properties have completed transitioning 3975 this.disableTransition(); 3976 } 3977 // clean style 3978 if ( propertyName in _transition.clean ) { 3979 // clean up style 3980 this.element.style[ event.propertyName ] = ''; 3981 delete _transition.clean[ propertyName ]; 3982 } 3983 // trigger onTransitionEnd callback 3984 if ( propertyName in _transition.onEnd ) { 3985 var onTransitionEnd = _transition.onEnd[ propertyName ]; 3986 onTransitionEnd.call( this ); 3987 delete _transition.onEnd[ propertyName ]; 3988 } 3989 3990 this.emitEvent( 'transitionEnd', [ this ] ); 3991}; 3992 3993proto.disableTransition = function() { 3994 this.removeTransitionStyles(); 3995 this.element.removeEventListener( transitionEndEvent, this, false ); 3996 this.isTransitioning = false;
vendor: 3,262 bytes, lines 3997-4145
3997}; 3998 3999/** 4000 * removes style property from element 4001 * @param {Object} style 4002**/ 4003proto._removeStyles = function( style ) { 4004 // clean up transition styles 4005 var cleanStyle = {}; 4006 for ( var prop in style ) { 4007 cleanStyle[ prop ] = ''; 4008 } 4009 this.css( cleanStyle ); 4010}; 4011 4012var cleanTransitionStyle = { 4013 transitionProperty: '', 4014 transitionDuration: '', 4015 transitionDelay: '' 4016}; 4017 4018proto.removeTransitionStyles = function() { 4019 // remove transition 4020 this.css( cleanTransitionStyle ); 4021}; 4022 4023// ----- stagger ----- // 4024 4025proto.stagger = function( delay ) { 4026 delay = isNaN( delay ) ? 0 : delay; 4027 this.staggerDelay = delay + 'ms'; 4028}; 4029 4030// ----- show/hide/remove ----- // 4031 4032// remove element from DOM 4033proto.removeElem = function() { 4034 this.element.parentNode.removeChild( this.element ); 4035 // remove display: none 4036 this.css({ display: '' }); 4037 this.emitEvent( 'remove', [ this ] ); 4038}; 4039 4040proto.remove = function() { 4041 // just remove element if no transition support or no transition 4042 if ( !transitionProperty || !parseFloat( this.layout.options.transitionDuration ) ) { 4043 this.removeElem(); 4044 return; 4045 } 4046 4047 // start transition 4048 this.once( 'transitionEnd', function() { 4049 this.removeElem(); 4050 }); 4051 this.hide(); 4052}; 4053 4054proto.reveal = function() { 4055 delete this.isHidden; 4056 // remove display: none 4057 this.css({ display: '' }); 4058 4059 var options = this.layout.options; 4060 4061 var onTransitionEnd = {}; 4062 var transitionEndProperty = this.getHideRevealTransitionEndProperty('visibleStyle'); 4063 onTransitionEnd[ transitionEndProperty ] = this.onRevealTransitionEnd; 4064 4065 this.transition({ 4066 from: options.hiddenStyle, 4067 to: options.visibleStyle, 4068 isCleaning: true, 4069 onTransitionEnd: onTransitionEnd 4070 }); 4071}; 4072 4073proto.onRevealTransitionEnd = function() { 4074 // check if still visible 4075 // during transition, item may have been hidden 4076 if ( !this.isHidden ) { 4077 this.emitEvent('reveal'); 4078 } 4079}; 4080 4081/** 4082 * get style property use for hide/reveal transition end 4083 * @param {String} styleProperty - hiddenStyle/visibleStyle 4084 * @returns {String} 4085 */ 4086proto.getHideRevealTransitionEndProperty = function( styleProperty ) { 4087 var optionStyle = this.layout.options[ styleProperty ]; 4088 // use opacity 4089 if ( optionStyle.opacity ) { 4090 return 'opacity'; 4091 } 4092 // get first property 4093 for ( var prop in optionStyle ) { 4094 return prop; 4095 } 4096}; 4097 4098proto.hide = function() { 4099 // set flag 4100 this.isHidden = true; 4101 // remove display: none 4102 this.css({ display: '' }); 4103 4104 var options = this.layout.options; 4105 4106 var onTransitionEnd = {}; 4107 var transitionEndProperty = this.getHideRevealTransitionEndProperty('hiddenStyle'); 4108 onTransitionEnd[ transitionEndProperty ] = this.onHideTransitionEnd; 4109 4110 this.transition({ 4111 from: options.visibleStyle, 4112 to: options.hiddenStyle, 4113 // keep hidden stuff hidden 4114 isCleaning: true, 4115 onTransitionEnd: onTransitionEnd 4116 }); 4117}; 4118 4119proto.onHideTransitionEnd = function() { 4120 // check if still hidden 4121 // during transition, item may have been un-hidden 4122 if ( this.isHidden ) { 4123 this.css({ display: 'none' }); 4124 this.emitEvent('hide'); 4125 } 4126}; 4127 4128proto.destroy = function() { 4129 this.css({ 4130 position: '', 4131 left: '', 4132 right: '', 4133 top: '', 4134 bottom: '', 4135 transition: '', 4136 transform: '' 4137 }); 4138}; 4139 4140return Item; 4141 4142})); 4143 4144/*! 4145 * Outlayer v2.1.0
vendor: 22,051 bytes, lines 4145-5085
4145 4146 * the brains and guts of a layout library 4147 * MIT license 4148 */ 4149 4150( function( window, factory ) { 4151 'use strict'; 4152 // universal module definition 4153 /* jshint strict: false */ /* globals define, module, require */ 4154 if ( typeof define == 'function' && define.amd ) { 4155 // AMD - RequireJS 4156 define( 'outlayer/outlayer',[ 4157 'ev-emitter/ev-emitter', 4158 'get-size/get-size', 4159 'fizzy-ui-utils/utils', 4160 './item' 4161 ], 4162 function( EvEmitter, getSize, utils, Item ) { 4163 return factory( window, EvEmitter, getSize, utils, Item); 4164 } 4165 ); 4166 } else if ( typeof module == 'object' && module.exports ) { 4167 // CommonJS - Browserify, Webpack 4168 module.exports = factory( 4169 window, 4170 require('ev-emitter'), 4171 require('get-size'), 4172 require('fizzy-ui-utils'), 4173 require('./item') 4174 ); 4175 } else { 4176 // browser global 4177 window.Outlayer = factory( 4178 window, 4179 window.EvEmitter, 4180 window.getSize, 4181 window.fizzyUIUtils, 4182 window.Outlayer.Item 4183 ); 4184 } 4185 4186}( window, function factory( window, EvEmitter, getSize, utils, Item ) { 4187'use strict'; 4188 4189// ----- vars ----- // 4190 4191var console = window.console; 4192var jQuery = window.jQuery; 4193var noop = function() {}; 4194 4195// -------------------------- Outlayer -------------------------- // 4196 4197// globally unique identifiers 4198var GUID = 0; 4199// internal store of all Outlayer intances 4200var instances = {}; 4201 4202 4203/** 4204 * @param {Element, String} element 4205 * @param {Object} options 4206 * @constructor 4207 */ 4208function Outlayer( element, options ) { 4209 var queryElement = utils.getQueryElement( element ); 4210 if ( !queryElement ) { 4211 if ( console ) { 4212 console.error( 'Bad element for ' + this.constructor.namespace + 4213 ': ' + ( queryElement || element ) ); 4214 } 4215 return; 4216 } 4217 this.element = queryElement; 4218 // add jQuery 4219 if ( jQuery ) { 4220 this.$element = jQuery( this.element ); 4221 } 4222 4223 // options 4224 this.options = utils.extend( {}, this.constructor.defaults ); 4225 this.option( options ); 4226 4227 // add id for Outlayer.getFromElement 4228 var id = ++GUID; 4229 this.element.outlayerGUID = id; // expando 4230 instances[ id ] = this; // associate via id 4231 4232 // kick it off 4233 this._create(); 4234 4235 var isInitLayout = this._getOption('initLayout'); 4236 if ( isInitLayout ) { 4237 this.layout(); 4238 } 4239} 4240 4241// settings are for internal use only 4242Outlayer.namespace = 'outlayer'; 4243Outlayer.Item = Item; 4244 4245// default options 4246Outlayer.defaults = { 4247 containerStyle: { 4248 position: 'relative' 4249 }, 4250 initLayout: true, 4251 originLeft: true, 4252 originTop: true, 4253 resize: true, 4254 resizeContainer: true, 4255 // item options 4256 transitionDuration: '0.4s', 4257 hiddenStyle: { 4258 opacity: 0, 4259 transform: 'scale(0.001)' 4260 }, 4261 visibleStyle: { 4262 opacity: 1, 4263 transform: 'scale(1)' 4264 } 4265}; 4266 4267var proto = Outlayer.prototype; 4268// inherit EvEmitter 4269utils.extend( proto, EvEmitter.prototype ); 4270 4271/** 4272 * set options 4273 * @param {Object} opts 4274 */ 4275proto.option = function( opts ) { 4276 utils.extend( this.options, opts ); 4277}; 4278 4279/** 4280 * get backwards compatible option value, check old name 4281 */ 4282proto._getOption = function( option ) { 4283 var oldOption = this.constructor.compatOptions[ option ]; 4284 return oldOption && this.options[ oldOption ] !== undefined ? 4285 this.options[ oldOption ] : this.options[ option ]; 4286}; 4287 4288Outlayer.compatOptions = { 4289 // currentName: oldName 4290 initLayout: 'isInitLayout', 4291 horizontal: 'isHorizontal', 4292 layoutInstant: 'isLayoutInstant', 4293 originLeft: 'isOriginLeft', 4294 originTop: 'isOriginTop', 4295 resize: 'isResizeBound', 4296 resizeContainer: 'isResizingContainer' 4297}; 4298 4299proto._create = function() { 4300 // get items from children 4301 this.reloadItems(); 4302 // elements that affect layout, but are not laid out 4303 this.stamps = []; 4304 this.stamp( this.options.stamp ); 4305 // set container style 4306 utils.extend( this.element.style, this.options.containerStyle ); 4307 4308 // bind resize method 4309 var canBindResize = this._getOption('resize'); 4310 if ( canBindResize ) { 4311 this.bindResize(); 4312 } 4313}; 4314 4315// goes through all children again and gets bricks in proper order 4316proto.reloadItems = function() { 4317 // collection of item elements 4318 this.items = this._itemize( this.element.children ); 4319}; 4320 4321 4322/** 4323 * turn elements into Outlayer.Items to be used in layout 4324 * @param {Array or NodeList or HTMLElement} elems 4325 * @returns {Array} items - collection of new Outlayer Items 4326 */ 4327proto._itemize = function( elems ) { 4328 4329 var itemElems = this._filterFindItemElements( elems ); 4330 var Item = this.constructor.Item; 4331 4332 // create new Outlayer Items for collection 4333 var items = []; 4334 for ( var i=0; i < itemElems.length; i++ ) { 4335 var elem = itemElems[i]; 4336 var item = new Item( elem, this ); 4337 items.push( item ); 4338 } 4339 4340 return items; 4341}; 4342 4343/** 4344 * get item elements to be used in layout 4345 * @param {Array or NodeList or HTMLElement} elems 4346 * @returns {Array} items - item elements 4347 */ 4348proto._filterFindItemElements = function( elems ) { 4349 return utils.filterFindElements( elems, this.options.itemSelector ); 4350}; 4351 4352/** 4353 * getter method for getting item elements 4354 * @returns {Array} elems - collection of item elements 4355 */ 4356proto.getItemElements = function() { 4357 return this.items.map( function( item ) { 4358 return item.element; 4359 }); 4360}; 4361 4362// ----- init & layout ----- // 4363 4364/** 4365 * lays out all items 4366 */ 4367proto.layout = function() { 4368 this._resetLayout(); 4369 this._manageStamps(); 4370 4371 // don't animate first layout 4372 var layoutInstant = this._getOption('layoutInstant'); 4373 var isInstant = layoutInstant !== undefined ? 4374 layoutInstant : !this._isLayoutInited; 4375 this.layoutItems( this.items, isInstant ); 4376 4377 // flag for initalized 4378 this._isLayoutInited = true; 4379}; 4380 4381// _init is alias for layout 4382proto._init = proto.layout; 4383 4384/** 4385 * logic before any new layout 4386 */ 4387proto._resetLayout = function() { 4388 this.getSize(); 4389}; 4390 4391 4392proto.getSize = function() { 4393 this.size = getSize( this.element ); 4394}; 4395 4396/** 4397 * get measurement from option, for columnWidth, rowHeight, gutter 4398 * if option is String -> get element from selector string, & get size of element 4399 * if option is Element -> get size of element 4400 * else use option as a number 4401 * 4402 * @param {String} measurement 4403 * @param {String} size - width or height 4404 * @private 4405 */ 4406proto._getMeasurement = function( measurement, size ) { 4407 var option = this.options[ measurement ]; 4408 var elem; 4409 if ( !option ) { 4410 // default to 0 4411 this[ measurement ] = 0; 4412 } else { 4413 // use option as an element 4414 if ( typeof option == 'string' ) { 4415 elem = this.element.querySelector( option ); 4416 } else if ( option instanceof HTMLElement ) { 4417 elem = option; 4418 } 4419 // use size of element, if element 4420 this[ measurement ] = elem ? getSize( elem )[ size ] : option; 4421 } 4422}; 4423 4424/** 4425 * layout a collection of item elements 4426 * @api public 4427 */ 4428proto.layoutItems = function( items, isInstant ) { 4429 items = this._getItemsForLayout( items ); 4430 4431 this._layoutItems( items, isInstant ); 4432 4433 this._postLayout(); 4434}; 4435 4436/** 4437 * get the items to be laid out 4438 * you may want to skip over some items 4439 * @param {Array} items 4440 * @returns {Array} items 4441 */ 4442proto._getItemsForLayout = function( items ) { 4443 return items.filter( function( item ) { 4444 return !item.isIgnored; 4445 }); 4446}; 4447 4448/** 4449 * layout items 4450 * @param {Array} items 4451 * @param {Boolean} isInstant 4452 */ 4453proto._layoutItems = function( items, isInstant ) { 4454 this._emitCompleteOnItems( 'layout', items ); 4455 4456 if ( !items || !items.length ) { 4457 // no items, emit event with empty array 4458 return; 4459 } 4460 4461 var queue = []; 4462 4463 items.forEach( function( item ) { 4464 // get x/y object from method 4465 var position = this._getItemLayoutPosition( item ); 4466 // enqueue 4467 position.item = item; 4468 position.isInstant = isInstant || item.isLayoutInstant; 4469 queue.push( position ); 4470 }, this ); 4471 4472 this._processLayoutQueue( queue ); 4473}; 4474 4475/** 4476 * get item layout position 4477 * @param {Outlayer.Item} item 4478 * @returns {Object} x and y position 4479 */ 4480proto._getItemLayoutPosition = function( /* item */ ) { 4481 return { 4482 x: 0, 4483 y: 0 4484 }; 4485}; 4486 4487/** 4488 * iterate over array and position each item 4489 * Reason being - separating this logic prevents 'layout invalidation' 4490 * thx @paul_irish 4491 * @param {Array} queue 4492 */ 4493proto._processLayoutQueue = function( queue ) { 4494 this.updateStagger(); 4495 queue.forEach( function( obj, i ) { 4496 this._positionItem( obj.item, obj.x, obj.y, obj.isInstant, i ); 4497 }, this ); 4498}; 4499 4500// set stagger from option in milliseconds number 4501proto.updateStagger = function() { 4502 var stagger = this.options.stagger; 4503 if ( stagger === null || stagger === undefined ) { 4504 this.stagger = 0; 4505 return; 4506 } 4507 this.stagger = getMilliseconds( stagger ); 4508 return this.stagger; 4509}; 4510 4511/** 4512 * Sets position of item in DOM 4513 * @param {Outlayer.Item} item 4514 * @param {Number} x - horizontal position 4515 * @param {Number} y - vertical position 4516 * @param {Boolean} isInstant - disables transitions 4517 */ 4518proto._positionItem = function( item, x, y, isInstant, i ) { 4519 if ( isInstant ) { 4520 // if not transition, just set CSS 4521 item.goTo( x, y ); 4522 } else { 4523 item.stagger( i * this.stagger ); 4524 item.moveTo( x, y ); 4525 } 4526}; 4527 4528/** 4529 * Any logic you want to do after each layout, 4530 * i.e. size the container 4531 */ 4532proto._postLayout = function() { 4533 this.resizeContainer(); 4534}; 4535 4536proto.resizeContainer = function() { 4537 var isResizingContainer = this._getOption('resizeContainer'); 4538 if ( !isResizingContainer ) { 4539 return; 4540 } 4541 var size = this._getContainerSize(); 4542 if ( size ) { 4543 this._setContainerMeasure( size.width, true ); 4544 this._setContainerMeasure( size.height, false ); 4545 } 4546}; 4547 4548/** 4549 * Sets width or height of container if returned 4550 * @returns {Object} size 4551 * @param {Number} width 4552 * @param {Number} height 4553 */ 4554proto._getContainerSize = noop; 4555 4556/** 4557 * @param {Number} measure - size of width or height 4558 * @param {Boolean} isWidth 4559 */ 4560proto._setContainerMeasure = function( measure, isWidth ) { 4561 if ( measure === undefined ) { 4562 return; 4563 } 4564 4565 var elemSize = this.size; 4566 // add padding and border width if border box 4567 if ( elemSize.isBorderBox ) { 4568 measure += isWidth ? elemSize.paddingLeft + elemSize.paddingRight + 4569 elemSize.borderLeftWidth + elemSize.borderRightWidth : 4570 elemSize.paddingBottom + elemSize.paddingTop + 4571 elemSize.borderTopWidth + elemSize.borderBottomWidth; 4572 } 4573 4574 measure = Math.max( measure, 0 ); 4575 this.element.style[ isWidth ? 'width' : 'height' ] = measure + 'px'; 4576}; 4577 4578/** 4579 * emit eventComplete on a collection of items events 4580 * @param {String} eventName 4581 * @param {Array} items - Outlayer.Items 4582 */ 4583proto._emitCompleteOnItems = function( eventName, items ) { 4584 var _this = this; 4585 function onComplete() { 4586 _this.dispatchEvent( eventName + 'Complete', null, [ items ] ); 4587 } 4588 4589 var count = items.length; 4590 if ( !items || !count ) { 4591 onComplete(); 4592 return; 4593 } 4594 4595 var doneCount = 0; 4596 function tick() { 4597 doneCount++; 4598 if ( doneCount == count ) { 4599 onComplete(); 4600 } 4601 } 4602 4603 // bind callback 4604 items.forEach( function( item ) { 4605 item.once( eventName, tick ); 4606 }); 4607}; 4608 4609/** 4610 * emits events via EvEmitter and jQuery events 4611 * @param {String} type - name of event 4612 * @param {Event} event - original event 4613 * @param {Array} args - extra arguments 4614 */ 4615proto.dispatchEvent = function( type, event, args ) { 4616 // add original event to arguments 4617 var emitArgs = event ? [ event ].concat( args ) : args; 4618 this.emitEvent( type, emitArgs ); 4619 4620 if ( jQuery ) { 4621 // set this.$element 4622 this.$element = this.$element || jQuery( this.element ); 4623 if ( event ) { 4624 // create jQuery event 4625 var $event = jQuery.Event( event ); 4626 $event.type = type; 4627 this.$element.trigger( $event, args ); 4628 } else { 4629 // just trigger with type if no event available 4630 this.$element.trigger( type, args ); 4631 } 4632 } 4633}; 4634 4635// -------------------------- ignore & stamps -------------------------- // 4636 4637 4638/** 4639 * keep item in collection, but do not lay it out 4640 * ignored items do not get skipped in layout 4641 * @param {Element} elem 4642 */ 4643proto.ignore = function( elem ) { 4644 var item = this.getItem( elem ); 4645 if ( item ) { 4646 item.isIgnored = true; 4647 } 4648}; 4649 4650/** 4651 * return item to layout collection 4652 * @param {Element} elem 4653 */ 4654proto.unignore = function( elem ) { 4655 var item = this.getItem( elem ); 4656 if ( item ) { 4657 delete item.isIgnored; 4658 } 4659}; 4660 4661/** 4662 * adds elements to stamps 4663 * @param {NodeList, Array, Element, or String} elems 4664 */ 4665proto.stamp = function( elems ) { 4666 elems = this._find( elems ); 4667 if ( !elems ) { 4668 return; 4669 } 4670 4671 this.stamps = this.stamps.concat( elems ); 4672 // ignore 4673 elems.forEach( this.ignore, this ); 4674}; 4675 4676/** 4677 * removes elements to stamps 4678 * @param {NodeList, Array, or Element} elems 4679 */ 4680proto.unstamp = function( elems ) { 4681 elems = this._find( elems ); 4682 if ( !elems ){ 4683 return; 4684 } 4685 4686 elems.forEach( function( elem ) { 4687 // filter out removed stamp elements 4688 utils.removeFrom( this.stamps, elem ); 4689 this.unignore( elem ); 4690 }, this ); 4691}; 4692 4693/** 4694 * finds child elements 4695 * @param {NodeList, Array, Element, or String} elems 4696 * @returns {Array} elems 4697 */ 4698proto._find = function( elems ) { 4699 if ( !elems ) { 4700 return; 4701 } 4702 // if string, use argument as selector string 4703 if ( typeof elems == 'string' ) { 4704 elems = this.element.querySelectorAll( elems ); 4705 } 4706 elems = utils.makeArray( elems ); 4707 return elems; 4708}; 4709 4710proto._manageStamps = function() { 4711 if ( !this.stamps || !this.stamps.length ) { 4712 return; 4713 } 4714 4715 this._getBoundingRect(); 4716 4717 this.stamps.forEach( this._manageStamp, this ); 4718}; 4719 4720// update boundingLeft / Top 4721proto._getBoundingRect = function() { 4722 // get bounding rect for container element 4723 var boundingRect = this.element.getBoundingClientRect(); 4724 var size = this.size; 4725 this._boundingRect = { 4726 left: boundingRect.left + size.paddingLeft + size.borderLeftWidth, 4727 top: boundingRect.top + size.paddingTop + size.borderTopWidth, 4728 right: boundingRect.right - ( size.paddingRight + size.borderRightWidth ), 4729 bottom: boundingRect.bottom - ( size.paddingBottom + size.borderBottomWidth ) 4730 }; 4731}; 4732 4733/** 4734 * @param {Element} stamp 4735**/ 4736proto._manageStamp = noop; 4737 4738/** 4739 * get x/y position of element relative to container element 4740 * @param {Element} elem 4741 * @returns {Object} offset - has left, top, right, bottom 4742 */ 4743proto._getElementOffset = function( elem ) { 4744 var boundingRect = elem.getBoundingClientRect(); 4745 var thisRect = this._boundingRect; 4746 var size = getSize( elem ); 4747 var offset = { 4748 left: boundingRect.left - thisRect.left - size.marginLeft, 4749 top: boundingRect.top - thisRect.top - size.marginTop, 4750 right: thisRect.right - boundingRect.right - size.marginRight, 4751 bottom: thisRect.bottom - boundingRect.bottom - size.marginBottom 4752 }; 4753 return offset; 4754}; 4755 4756// -------------------------- resize -------------------------- // 4757 4758// enable event handlers for listeners 4759// i.e. resize -> onresize 4760proto.handleEvent = utils.handleEvent; 4761 4762/** 4763 * Bind layout to window resizing 4764 */ 4765proto.bindResize = function() { 4766 window.addEventListener( 'resize', this ); 4767 this.isResizeBound = true; 4768}; 4769 4770/** 4771 * Unbind layout to window resizing 4772 */ 4773proto.unbindResize = function() { 4774 window.removeEventListener( 'resize', this ); 4775 this.isResizeBound = false; 4776}; 4777 4778proto.onresize = function() { 4779 this.resize(); 4780}; 4781 4782utils.debounceMethod( Outlayer, 'onresize', 100 ); 4783 4784proto.resize = function() { 4785 // don't trigger if size did not change 4786 // or if resize was unbound. See #9 4787 if ( !this.isResizeBound || !this.needsResizeLayout() ) { 4788 return; 4789 } 4790 4791 this.layout(); 4792}; 4793 4794/** 4795 * check if layout is needed post layout 4796 * @returns Boolean 4797 */ 4798proto.needsResizeLayout = function() { 4799 var size = getSize( this.element ); 4800 // check that this.size and size are there 4801 // IE8 triggers resize on body size change, so they might not be 4802 var hasSizes = this.size && size; 4803 return hasSizes && size.innerWidth !== this.size.innerWidth; 4804}; 4805 4806// -------------------------- methods -------------------------- // 4807 4808/** 4809 * add items to Outlayer instance 4810 * @param {Array or NodeList or Element} elems 4811 * @returns {Array} items - Outlayer.Items 4812**/ 4813proto.addItems = function( elems ) { 4814 var items = this._itemize( elems ); 4815 // add items to collection 4816 if ( items.length ) { 4817 this.items = this.items.concat( items ); 4818 } 4819 return items; 4820}; 4821 4822/** 4823 * Layout newly-appended item elements 4824 * @param {Array or NodeList or Element} elems 4825 */ 4826proto.appended = function( elems ) { 4827 var items = this.addItems( elems ); 4828 if ( !items.length ) { 4829 return; 4830 } 4831 // layout and reveal just the new items 4832 this.layoutItems( items, true ); 4833 this.reveal( items ); 4834}; 4835 4836/** 4837 * Layout prepended elements 4838 * @param {Array or NodeList or Element} elems 4839 */ 4840proto.prepended = function( elems ) { 4841 var items = this._itemize( elems ); 4842 if ( !items.length ) { 4843 return; 4844 } 4845 // add items to beginning of collection 4846 var previousItems = this.items.slice(0); 4847 this.items = items.concat( previousItems ); 4848 // start new layout 4849 this._resetLayout(); 4850 this._manageStamps(); 4851 // layout new stuff without transition 4852 this.layoutItems( items, true ); 4853 this.reveal( items ); 4854 // layout previous items 4855 this.layoutItems( previousItems ); 4856}; 4857 4858/** 4859 * reveal a collection of items 4860 * @param {Array of Outlayer.Items} items 4861 */ 4862proto.reveal = function( items ) { 4863 this._emitCompleteOnItems( 'reveal', items ); 4864 if ( !items || !items.length ) { 4865 return; 4866 } 4867 var stagger = this.updateStagger(); 4868 items.forEach( function( item, i ) { 4869 item.stagger( i * stagger ); 4870 item.reveal(); 4871 }); 4872}; 4873 4874/** 4875 * hide a collection of items 4876 * @param {Array of Outlayer.Items} items 4877 */ 4878proto.hide = function( items ) { 4879 this._emitCompleteOnItems( 'hide', items ); 4880 if ( !items || !items.length ) { 4881 return; 4882 } 4883 var stagger = this.updateStagger(); 4884 items.forEach( function( item, i ) { 4885 item.stagger( i * stagger ); 4886 item.hide(); 4887 }); 4888}; 4889 4890/** 4891 * reveal item elements 4892 * @param {Array}, {Element}, {NodeList} items 4893 */ 4894proto.revealItemElements = function( elems ) { 4895 var items = this.getItems( elems ); 4896 this.reveal( items ); 4897}; 4898 4899/** 4900 * hide item elements 4901 * @param {Array}, {Element}, {NodeList} items 4902 */ 4903proto.hideItemElements = function( elems ) { 4904 var items = this.getItems( elems ); 4905 this.hide( items ); 4906}; 4907 4908/** 4909 * get Outlayer.Item, given an Element 4910 * @param {Element} elem 4911 * @param {Function} callback 4912 * @returns {Outlayer.Item} item 4913 */ 4914proto.getItem = function( elem ) { 4915 // loop through items to get the one that matches 4916 for ( var i=0; i < this.items.length; i++ ) { 4917 var item = this.items[i]; 4918 if ( item.element == elem ) { 4919 // return item 4920 return item; 4921 } 4922 } 4923}; 4924 4925/** 4926 * get collection of Outlayer.Items, given Elements 4927 * @param {Array} elems 4928 * @returns {Array} items - Outlayer.Items 4929 */ 4930proto.getItems = function( elems ) { 4931 elems = utils.makeArray( elems ); 4932 var items = []; 4933 elems.forEach( function( elem ) { 4934 var item = this.getItem( elem ); 4935 if ( item ) { 4936 items.push( item ); 4937 } 4938 }, this ); 4939 4940 return items; 4941}; 4942 4943/** 4944 * remove element(s) from instance and DOM 4945 * @param {Array or NodeList or Element} elems 4946 */ 4947proto.remove = function( elems ) { 4948 var removeItems = this.getItems( elems ); 4949 4950 this._emitCompleteOnItems( 'remove', removeItems ); 4951 4952 // bail if no items to remove 4953 if ( !removeItems || !removeItems.length ) { 4954 return; 4955 } 4956 4957 removeItems.forEach( function( item ) { 4958 item.remove(); 4959 // remove item from collection 4960 utils.removeFrom( this.items, item ); 4961 }, this ); 4962}; 4963 4964// ----- destroy ----- // 4965 4966// remove and disable Outlayer instance 4967proto.destroy = function() { 4968 // clean up dynamic styles 4969 var style = this.element.style; 4970 style.height = ''; 4971 style.position = ''; 4972 style.width = ''; 4973 // destroy items 4974 this.items.forEach( function( item ) { 4975 item.destroy(); 4976 }); 4977 4978 this.unbindResize(); 4979 4980 var id = this.element.outlayerGUID; 4981 delete instances[ id ]; // remove reference to instance by id 4982 delete this.element.outlayerGUID; 4983 // remove data for jQuery 4984 if ( jQuery ) { 4985 jQuery.removeData( this.element, this.constructor.namespace ); 4986 } 4987 4988}; 4989 4990// -------------------------- data -------------------------- // 4991 4992/** 4993 * get Outlayer instance from element 4994 * @param {Element} elem 4995 * @returns {Outlayer} 4996 */ 4997Outlayer.data = function( elem ) { 4998 elem = utils.getQueryElement( elem ); 4999 var id = elem && elem.outlayerGUID; 5000 return id && instances[ id ]; 5001}; 5002 5003 5004// -------------------------- create Outlayer class -------------------------- // 5005 5006/** 5007 * create a layout class 5008 * @param {String} namespace 5009 */ 5010Outlayer.create = function( namespace, options ) { 5011 // sub-class Outlayer 5012 var Layout = subclass( Outlayer ); 5013 // apply new options and compatOptions 5014 Layout.defaults = utils.extend( {}, Outlayer.defaults ); 5015 utils.extend( Layout.defaults, options ); 5016 Layout.compatOptions = utils.extend( {}, Outlayer.compatOptions ); 5017 5018 Layout.namespace = namespace; 5019 5020 Layout.data = Outlayer.data; 5021 5022 // sub-class Item 5023 Layout.Item = subclass( Item ); 5024 5025 // -------------------------- declarative -------------------------- // 5026 5027 utils.htmlInit( Layout, namespace ); 5028 5029 // -------------------------- jQuery bridge -------------------------- // 5030 5031 // make into jQuery plugin 5032 if ( jQuery && jQuery.bridget ) { 5033 jQuery.bridget( namespace, Layout ); 5034 } 5035 5036 return Layout; 5037}; 5038 5039function subclass( Parent ) { 5040 function SubClass() { 5041 Parent.apply( this, arguments ); 5042 } 5043 5044 SubClass.prototype = Object.create( Parent.prototype ); 5045 SubClass.prototype.constructor = SubClass; 5046 5047 return SubClass; 5048} 5049 5050// ----- helpers ----- // 5051 5052// how many milliseconds are in each unit 5053var msUnits = { 5054 ms: 1, 5055 s: 1000 5056}; 5057 5058// munge time-like parameter into millisecond number 5059// '0.4s' -> 40 5060function getMilliseconds( time ) { 5061 if ( typeof time == 'number' ) { 5062 return time; 5063 } 5064 var matches = time.match( /(^\d*\.?\d*)(\w*)/ ); 5065 var num = matches && matches[1]; 5066 var unit = matches && matches[2]; 5067 if ( !num.length ) { 5068 return 0; 5069 } 5070 num = parseFloat( num ); 5071 var mult = msUnits[ unit ] || 1; 5072 return num * mult; 5073} 5074 5075// ----- fin ----- // 5076 5077// back in global 5078Outlayer.Item = Item; 5079 5080return Outlayer; 5081 5082})); 5083 5084/*! 5085 * Masonry v4.2.
50850 5086 * Cascading grid layout library 5087 * http://masonry.desandro.com 5088 * MIT License 5089 * by David DeSandro 5090 */ 5091 5092( function( window, factory ) { 5093 // universal module definition 5094 /* jshint strict: false */ /*globals define, module, require */ 5095 if ( typeof define == 'function' && define.amd ) { 5096 // AMD 5097 define( [ 5098 'outlayer/outlayer', 5099 'get-size/get-size' 5100 ], 5101 factory ); 5102 } else if ( typeof module == 'object' && module.exports ) { 5103 // CommonJS 5104 module.exports = factory( 5105 require('outlayer'), 5106 require('get-size') 5107 ); 5108 } else { 5109 // browser global 5110 window.Masonry = factory( 5111 window.Outlayer, 5112 window.getSize 5113 ); 5114 } 5115 5116}( window, function factory( Outlayer, getSize ) { 5117 5118 5119 5120// -------------------------- masonryDefinition -------------------------- // 5121 5122 // create an Outlayer layout class 5123 var Masonry = Outlayer.create('masonry'); 5124 // isFitWidth -> fitWidth
vendor: 7,287 bytes, lines 5125-5347
5125 Masonry.compatOptions.fitWidth = 'isFitWidth'; 5126 5127 var proto = Masonry.prototype; 5128 5129 proto._resetLayout = function() { 5130 this.getSize(); 5131 this._getMeasurement( 'columnWidth', 'outerWidth' ); 5132 this._getMeasurement( 'gutter', 'outerWidth' ); 5133 this.measureColumns(); 5134 5135 // reset column Y 5136 this.colYs = []; 5137 for ( var i=0; i < this.cols; i++ ) { 5138 this.colYs.push( 0 ); 5139 } 5140 5141 this.maxY = 0; 5142 this.horizontalColIndex = 0; 5143 }; 5144 5145 proto.measureColumns = function() { 5146 this.getContainerWidth(); 5147 // if columnWidth is 0, default to outerWidth of first item 5148 if ( !this.columnWidth ) { 5149 var firstItem = this.items[0]; 5150 var firstItemElem = firstItem && firstItem.element; 5151 // columnWidth fall back to item of first element 5152 this.columnWidth = firstItemElem && getSize( firstItemElem ).outerWidth || 5153 // if first elem has no width, default to size of container 5154 this.containerWidth; 5155 } 5156 5157 var columnWidth = this.columnWidth += this.gutter; 5158 5159 // calculate columns 5160 var containerWidth = this.containerWidth + this.gutter; 5161 var cols = containerWidth / columnWidth; 5162 // fix rounding errors, typically with gutters 5163 var excess = columnWidth - containerWidth % columnWidth; 5164 // if overshoot is less than a pixel, round up, otherwise floor it 5165 var mathMethod = excess && excess < 1 ? 'round' : 'floor'; 5166 cols = Math[ mathMethod ]( cols ); 5167 this.cols = Math.max( cols, 1 ); 5168 }; 5169 5170 proto.getContainerWidth = function() { 5171 // container is parent if fit width 5172 var isFitWidth = this._getOption('fitWidth'); 5173 var container = isFitWidth ? this.element.parentNode : this.element; 5174 // check that this.size and size are there 5175 // IE8 triggers resize on body size change, so they might not be 5176 var size = getSize( container ); 5177 this.containerWidth = size && size.innerWidth; 5178 }; 5179 5180 proto._getItemLayoutPosition = function( item ) { 5181 item.getSize(); 5182 // how many columns does this brick span 5183 var remainder = item.size.outerWidth % this.columnWidth; 5184 var mathMethod = remainder && remainder < 1 ? 'round' : 'ceil'; 5185 // round if off by 1 pixel, otherwise use ceil 5186 var colSpan = Math[ mathMethod ]( item.size.outerWidth / this.columnWidth ); 5187 colSpan = Math.min( colSpan, this.cols ); 5188 // use horizontal or top column position 5189 var colPosMethod = this.options.horizontalOrder ? 5190 '_getHorizontalColPosition' : '_getTopColPosition'; 5191 var colPosition = this[ colPosMethod ]( colSpan, item ); 5192 // position the brick 5193 var position = { 5194 x: this.columnWidth * colPosition.col, 5195 y: colPosition.y 5196 }; 5197 // apply setHeight to necessary columns 5198 var setHeight = colPosition.y + item.size.outerHeight; 5199 var setMax = colSpan + colPosition.col; 5200 for ( var i = colPosition.col; i < setMax; i++ ) { 5201 this.colYs[i] = setHeight; 5202 } 5203 5204 return position; 5205 }; 5206 5207 proto._getTopColPosition = function( colSpan ) { 5208 var colGroup = this._getTopColGroup( colSpan ); 5209 // get the minimum Y value from the columns 5210 var minimumY = Math.min.apply( Math, colGroup ); 5211 5212 return { 5213 col: colGroup.indexOf( minimumY ), 5214 y: minimumY, 5215 }; 5216 }; 5217 5218 /** 5219 * @param {Number} colSpan - number of columns the element spans 5220 * @returns {Array} colGroup 5221 */ 5222 proto._getTopColGroup = function( colSpan ) { 5223 if ( colSpan < 2 ) { 5224 // if brick spans only one column, use all the column Ys 5225 return this.colYs; 5226 } 5227 5228 var colGroup = []; 5229 // how many different places could this brick fit horizontally 5230 var groupCount = this.cols + 1 - colSpan; 5231 // for each group potential horizontal position 5232 for ( var i = 0; i < groupCount; i++ ) { 5233 colGroup[i] = this._getColGroupY( i, colSpan ); 5234 } 5235 return colGroup; 5236 }; 5237 5238 proto._getColGroupY = function( col, colSpan ) { 5239 if ( colSpan < 2 ) { 5240 return this.colYs[ col ]; 5241 } 5242 // make an array of colY values for that one group 5243 var groupColYs = this.colYs.slice( col, col + colSpan ); 5244 // and get the max value of the array 5245 return Math.max.apply( Math, groupColYs ); 5246 }; 5247 5248 // get column position based on horizontal index. #873 5249 proto._getHorizontalColPosition = function( colSpan, item ) { 5250 var col = this.horizontalColIndex % this.cols; 5251 var isOver = colSpan > 1 && col + colSpan > this.cols; 5252 // shift to next row if item can't fit on current row 5253 col = isOver ? 0 : col; 5254 // don't let zero-size items take up space 5255 var hasSize = item.size.outerWidth && item.size.outerHeight; 5256 this.horizontalColIndex = hasSize ? col + colSpan : this.horizontalColIndex; 5257 5258 return { 5259 col: col, 5260 y: this._getColGroupY( col, colSpan ), 5261 }; 5262 }; 5263 5264 proto._manageStamp = function( stamp ) { 5265 var stampSize = getSize( stamp ); 5266 var offset = this._getElementOffset( stamp ); 5267 // get the columns that this stamp affects 5268 var isOriginLeft = this._getOption('originLeft'); 5269 var firstX = isOriginLeft ? offset.left : offset.right; 5270 var lastX = firstX + stampSize.outerWidth; 5271 var firstCol = Math.floor( firstX / this.columnWidth ); 5272 firstCol = Math.max( 0, firstCol ); 5273 var lastCol = Math.floor( lastX / this.columnWidth ); 5274 // lastCol should not go over if multiple of columnWidth #425 5275 lastCol -= lastX % this.columnWidth ? 0 : 1; 5276 lastCol = Math.min( this.cols - 1, lastCol ); 5277 // set colYs to bottom of the stamp 5278 5279 var isOriginTop = this._getOption('originTop'); 5280 var stampMaxY = ( isOriginTop ? offset.top : offset.bottom ) + 5281 stampSize.outerHeight; 5282 for ( var i = firstCol; i <= lastCol; i++ ) { 5283 this.colYs[i] = Math.max( stampMaxY, this.colYs[i] ); 5284 } 5285 }; 5286 5287 proto._getContainerSize = function() { 5288 this.maxY = Math.max.apply( Math, this.colYs ); 5289 var size = { 5290 height: this.maxY 5291 }; 5292 5293 if ( this._getOption('fitWidth') ) { 5294 size.width = this._getContainerFitWidth(); 5295 } 5296 5297 return size; 5298 }; 5299 5300 proto._getContainerFitWidth = function() { 5301 var unusedCols = 0; 5302 // count unused columns 5303 var i = this.cols; 5304 while ( --i ) { 5305 if ( this.colYs[i] !== 0 ) { 5306 break; 5307 } 5308 unusedCols++; 5309 } 5310 // fit container to columns that have been used 5311 return ( this.cols - unusedCols ) * this.columnWidth - this.gutter; 5312 }; 5313 5314 proto.needsResizeLayout = function() { 5315 var previousWidth = this.containerWidth; 5316 this.getContainerWidth(); 5317 return previousWidth != this.containerWidth; 5318 }; 5319 5320 return Masonry; 5321 5322})); 5323 5324// https://github.com/websanova/mousestopk 5325(function($) { 5326 $.event.special.mousestop = { 5327 setup: function(data) { 5328 $(this).data('mousestop', _data(data)) 5329 .bind('mouseenter.mousestop', _mouseenter) 5330 .bind('mouseleave.mousestop', _mouseleave) 5331 .bind('mousemove.mousestop', _mousemove); 5332 }, 5333 teardown: function() { 5334 $(this).removeData('mousestop') 5335 .unbind('.mousestop'); 5336 } 5337 }; 5338 5339 function _mouseenter() { 5340 var _self = this, 5341 data = $(this).data('mousestop'); 5342 5343 this.movement = true; 5344 5345 if(data.timeToStop) { 5346 this.timeToStopTimer = window.setTimeout(function() { 5347 _self.movement = false;
5348 window.clearTimeout(_self.timer); 5349 }, data.timeToStop); 5350 } 5351 } 5352 5353 function _mouseleave() { 5354 window.clearTimeout(this.timer); 5355 window.clearTimeout(this.timeToStopTimer); 5356 } 5357 5358 function _mousemove() { 5359 var $el = $(this), 5360 data = $el.data('mousestop'); 5361 5362 if(this.movement) { 5363 window.clearTimeout(this.timer); 5364 this.timer = window.setTimeout(function() { 5365 $el.trigger('mousestop'); 5366 }, data.delay); 5367 } 5368 } 5369 5370 function _data(data) { 5371 if($.isNumeric(data)) { 5372 data = {delay: data}; 5373 } 5374 else if(typeof data !== 'object') { 5375 data = {}; 5376 } 5377 5378 return $.extend({}, $.fn.mousestop.defaults, data); 5379 } 5380 5381 $.fn.mousestop = function(data, fn) { 5382 if (typeof data === 'function') { fn = data; } 5383 return arguments.length > 0 ? this.bind('mousestop', data, fn) : this.trigger('mousestop'); 5384 }; 5385 5386 $.fn.mousestop.defaults = { 5387 delay: 300, 5388 timeToStop: null 5389 }; 5390})(jQuery); 5391 5392/*! nanoScrollerJS - v0.8.7 - 2015 5393* http://jamesflorentino.github.com/nanoScrollerJS/ 5394* Copyright (c) 2015 James Florentino; Licensed MIT */ 5395(function(factory) { 5396 if (typeof define === 'function' && define.amd) { 5397 return define(['jquery'], function($) { 5398 return factory($, window, document); 5399 }); 5400 } else if (typeof exports === 'object') { 5401 return module.exports = factory(require('jquery'), window, document); 5402 } else { 5403 return factory(jQuery, window, document); 5404 } 5405})(function($, window, document) { 5406 "use strict"; 5407 var BROWSER_IS_IE7, BROWSER_SCROLLBAR_WIDTH, DOMSCROLL, DOWN, DRAG, ENTER, KEYDOWN, KEYUP, MOUSEDOWN, MOUSEENTER, MOUSEMOVE, MOUSEUP, MOUSEWHEEL, NanoScroll, PANEDOWN, RESIZE, SCROLL, SCROLLBAR, TOUCHMOVE, UP, WHEEL, cAF, defaults, getBrowserScrollbarWidth, hasTransform, isFFWithBuggyScrollbar, rAF, transform, _elementStyle, _prefixStyle, _vendor; 5408 defaults = { 5409 5410 /** 5411 a classname for the pane element. 5412 @property paneClass 5413 @type String 5414 @default 'nano-pane' 5415 */ 5416 paneClass: 'nano-pane', 5417 5418 /** 5419 a classname for the slider element. 5420 @property sliderClass 5421 @type String 5422 @default 'nano-slider' 5423 */ 5424 sliderClass: 'nano-slider', 5425 5426 /** 5427 a classname for the content element. 5428 @property contentClass 5429 @type String 5430 @default 'nano-content' 5431 */ 5432 contentClass: 'nano-content', 5433 5434 /** 5435 a classname for enabled mode 5436 @property enabledClass 5437 @type String 5438 @default 'has-scrollbar' 5439 */ 5440 enabledClass: 'has-scrollbar', 5441 5442 /** 5443 a classname for flashed mode 5444 @property flashedClass 5445 @type String 5446 @default 'flashed' 5447 */ 5448 flashedClass: 'flashed', 5449 5450 /** 5451 a classname for active mode 5452 @property activeClass 5453 @type String 5454 @default 'active' 5455 */ 5456 activeClass: 'active', 5457 5458 /** 5459 a setting to enable native scrolling in iOS devices. 5460 @property iOSNativeScrolling 5461 @type Boolean 5462 @default false 5463 */ 5464 iOSNativeScrolling: false, 5465 5466 /** 5467 a setting to prevent the rest of the page being 5468 scrolled when user scrolls the `.content` element. 5469 @property preventPageScrolling 5470 @type Boolean 5471 @default false 5472 */ 5473 preventPageScrolling: false, 5474 5475 /** 5476 a setting to disable binding to the resize event. 5477 @property disableResize 5478 @type Boolean 5479 @default false 5480 */ 5481 disableResize: false, 5482 5483 /** 5484 a setting to make the scrollbar always visible. 5485 @property alwaysVisible 5486 @type Boolean 5487 @default false 5488 */ 5489 alwaysVisible: false, 5490 5491 /** 5492 a default timeout for the `flash()` method. 5493 @property flashDelay 5494 @type Number 5495 @default 1500 5496 */ 5497 flashDelay: 1500, 5498 5499 /** 5500 a minimum height for the `.slider` element. 5501 @property sliderMinHeight 5502 @type Number 5503 @default 20 5504 */ 5505 sliderMinHeight: 20, 5506 5507 /** 5508 a maximum height for the `.slider` element. 5509 @property sliderMaxHeight 5510 @type Number 5511 @default null 5512 */ 5513 sliderMaxHeight: null, 5514 5515 /** 5516 an alternate document context. 5517 @property documentContext 5518 @type Document 5519 @default null 5520 */ 5521 documentContext: null, 5522 5523 /** 5524 an alternate window context. 5525 @property windowContext 5526 @type Window 5527 @default null 5528 */ 5529 windowContext: null 5530 }; 5531 5532 /** 5533 @property SCROLLBAR
5534 @type String 5535 @static 5536 @final 5537 @private 5538 */ 5539 SCROLLBAR = 'scrollbar'; 5540 5541 /** 5542 @property SCROLL 5543 @type String 5544 @static 5545 @final 5546 @private 5547 */ 5548 SCROLL = 'scroll'; 5549 5550 /** 5551 @property MOUSEDOWN 5552 @type String 5553 @final 5554 @private 5555 */ 5556 MOUSEDOWN = 'mousedown'; 5557 5558 /** 5559 @property MOUSEENTER 5560 @type String 5561 @final 5562 @private 5563 */ 5564 MOUSEENTER = 'mouseenter'; 5565 5566 /** 5567 @property MOUSEMOVE 5568 @type String 5569 @static 5570 @final 5571 @private 5572 */ 5573 MOUSEMOVE = 'mousemove'; 5574 5575 /** 5576 @property MOUSEWHEEL 5577 @type String 5578 @final 5579 @private 5580 */ 5581 MOUSEWHEEL = 'mousewheel'; 5582 5583 /** 5584 @property MOUSEUP 5585 @type String 5586 @static 5587 @final 5588 @private 5589 */ 5590 MOUSEUP = 'mouseup'; 5591 5592 /** 5593 @property RESIZE 5594 @type String 5595 @final 5596 @private 5597 */ 5598 RESIZE = 'resize'; 5599 5600 /** 5601 @property DRAG 5602 @type String 5603 @static 5604 @final 5605 @private 5606 */ 5607 DRAG = 'drag'; 5608 5609 /** 5610 @property ENTER 5611 @type String 5612 @static 5613 @final 5614 @private 5615 */ 5616 ENTER = 'enter'; 5617 5618 /** 5619 @property UP 5620 @type String 5621 @static 5622 @final 5623 @private 5624 */ 5625 UP = 'up'; 5626 5627 /** 5628 @property PANEDOWN 5629 @type String 5630 @static 5631 @final 5632 @private 5633 */ 5634 PANEDOWN = 'panedown'; 5635 5636 /** 5637 @property DOMSCROLL 5638 @type String 5639 @static 5640 @final 5641 @private 5642 */ 5643 DOMSCROLL = 'DOMMouseScroll'; 5644 5645 /** 5646 @property DOWN 5647 @type String 5648 @static 5649 @final 5650 @private 5651 */ 5652 DOWN = 'down'; 5653 5654 /** 5655 @property WHEEL 5656 @type String 5657 @static 5658 @final 5659 @private 5660 */ 5661 WHEEL = 'wheel'; 5662 5663 /** 5664 @property KEYDOWN 5665 @type String 5666 @static 5667 @final 5668 @private 5669 */ 5670 KEYDOWN = 'keydown'; 5671 5672 /** 5673 @property KEYUP 5674 @type String 5675 @static 5676 @final 5677 @private 5678 */ 5679 KEYUP = 'keyup'; 5680 5681 /** 5682 @property TOUCHMOVE 5683 @type String 5684 @static 5685 @final 5686 @private 5687 */ 5688 TOUCHMOVE = 'touchmove'; 5689 5690 /** 5691 @property BROWSER_IS_IE7 5692 @type Boolean 5693 @static 5694 @final 5695 @private 5696 */ 5697 BROWSER_IS_IE7 = window.navigator.appName === 'Microsoft Internet Explorer' && /msie 7./i.test(window.navigator.appVersion) && window.ActiveXObject; 5698 5699 /** 5700 @property BROWSER_SCROLLBAR_WIDTH 5701 @type Number 5702 @static 5703 @default null 5704 @private 5705 */ 5706 BROWSER_SCROLLBAR_WIDTH = null;
5707 rAF = window.requestAnimationFrame; 5708 cAF = window.cancelAnimationFrame; 5709 _elementStyle = document.createElement('div').style; 5710 _vendor = (function() { 5711 var i, transform, vendor, vendors, _i, _len; 5712 vendors = ['t', 'webkitT', 'MozT', 'msT', 'OT']; 5713 for (i = _i = 0, _len = vendors.length; _i < _len; i = ++_i) { 5714 vendor = vendors[i]; 5715 transform = vendors[i] + 'ransform'; 5716 if (transform in _elementStyle) { 5717 return vendors[i].substr(0, vendors[i].length - 1); 5718 } 5719 } 5720 return false; 5721 })(); 5722 _prefixStyle = function(style) { 5723 if (_vendor === false) { 5724 return false; 5725 } 5726 if (_vendor === '') { 5727 return style; 5728 } 5729 return _vendor + style.charAt(0).toUpperCase() + style.substr(1); 5730 }; 5731 transform = _prefixStyle('transform'); 5732 hasTransform = transform !== false; 5733 5734 /** 5735 Returns browser's native scrollbar width 5736 @method getBrowserScrollbarWidth 5737 @return {Number} the scrollbar width in pixels 5738 @static 5739 @private 5740 */ 5741 getBrowserScrollbarWidth = function() { 5742 var outer, outerStyle, scrollbarWidth; 5743 outer = document.createElement('div'); 5744 outerStyle = outer.style; 5745 outerStyle.position = 'absolute'; 5746 outerStyle.width = '100px'; 5747 outerStyle.height = '100px'; 5748 outerStyle.overflow = SCROLL; 5749 outerStyle.top = '-9999px'; 5750 document.body.appendChild(outer); 5751 scrollbarWidth = outer.offsetWidth - outer.clientWidth; 5752 document.body.removeChild(outer); 5753 return scrollbarWidth; 5754 }; 5755 isFFWithBuggyScrollbar = function() { 5756 var isOSXFF, ua, version; 5757 ua = window.navigator.userAgent; 5758 isOSXFF = /(?=.+Mac OS X)(?=.+Firefox)/.test(ua); 5759 if (!isOSXFF) { 5760 return false; 5761 } 5762 version = /Firefox\/\d{2}\./.exec(ua); 5763 if (version) { 5764 version = version[0].replace(/\D+/g, ''); 5765 } 5766 return isOSXFF && +version > 23; 5767 }; 5768 5769 /** 5770 @class NanoScroll 5771 @param element {HTMLElement|Node} the main element 5772 @param options {Object} nanoScroller's options 5773 @constructor 5774 */ 5775 NanoScroll = (function() { 5776 function NanoScroll(el, options) { 5777 this.el = el; 5778 this.options = options; 5779 BROWSER_SCROLLBAR_WIDTH || (BROWSER_SCROLLBAR_WIDTH = getBrowserScrollbarWidth()); 5780 this.$el = $(this.el); 5781 this.doc = $(this.options.documentContext || document); 5782 this.win = $(this.options.windowContext || window); 5783 this.body = this.doc.find('body'); 5784 this.$content = this.$el.children("." + this.options.contentClass); 5785 this.$content.attr('tabindex', this.options.tabIndex || 0); 5786 this.content = this.$content[0]; 5787 this.previousPosition = 0; 5788 if (this.options.iOSNativeScrolling && (this.el.style.WebkitOverflowScrolling != null)) { 5789 this.nativeScrolling(); 5790 } else { 5791 this.generate(); 5792 } 5793 this.createEvents(); 5794 this.addEvents(); 5795 this.reset(); 5796 } 5797 5798 5799 /** 5800 Prevents the rest of the page being scrolled 5801 when user scrolls the `.nano-content` element. 5802 @method preventScrolling 5803 @param event {Event} 5804 @param direction {String} Scroll direction (up or down) 5805 @private 5806 */ 5807 5808 NanoScroll.prototype.preventScrolling = function(e, direction) { 5809 if (!this.isActive) { 5810 return; 5811 } 5812 if (e.type === DOMSCROLL) { 5813 if (direction === DOWN && e.originalEvent.detail > 0 || direction === UP && e.originalEvent.detail < 0) { 5814 e.preventDefault(); 5815 } 5816 } else if (e.type === MOUSEWHEEL) { 5817 if (!e.originalEvent || !e.originalEvent.wheelDelta) { 5818 return; 5819 } 5820 if (direction === DOWN && e.originalEvent.wheelDelta < 0 || direction === UP && e.originalEvent.wheelDelta > 0) { 5821 e.preventDefault(); 5822 } 5823 } 5824 }; 5825 5826 5827 /** 5828 Enable iOS native scrolling
5829 @method nativeScrolling 5830 @private 5831 */ 5832 5833 NanoScroll.prototype.nativeScrolling = function() { 5834 this.$content.css({ 5835 WebkitOverflowScrolling: 'touch' 5836 }); 5837 this.iOSNativeScrolling = true; 5838 this.isActive = true; 5839 }; 5840 5841 5842 /** 5843 Updates those nanoScroller properties that 5844 are related to current scrollbar position. 5845 @method updateScrollValues 5846 @private 5847 */ 5848 5849 NanoScroll.prototype.updateScrollValues = function() { 5850 var content, direction; 5851 content = this.content; 5852 this.maxScrollTop = content.scrollHeight - content.clientHeight; 5853 this.prevScrollTop = this.contentScrollTop || 0; 5854 this.contentScrollTop = content.scrollTop; 5855 direction = this.contentScrollTop > this.previousPosition ? "down" : this.contentScrollTop < this.previousPosition ? "up" : "same"; 5856 this.previousPosition = this.contentScrollTop; 5857 if (direction !== "same") { 5858 this.$el.trigger('update', { 5859 position: this.contentScrollTop, 5860 maximum: this.maxScrollTop, 5861 direction: direction 5862 }); 5863 } 5864 if (!this.iOSNativeScrolling) { 5865 this.maxSliderTop = this.paneHeight - this.sliderHeight; 5866 this.sliderTop = this.maxScrollTop === 0 ? 0 : this.contentScrollTop * this.maxSliderTop / this.maxScrollTop; 5867 } 5868 }; 5869 5870 5871 /** 5872 Updates CSS styles for current scroll position. 5873 Uses CSS 2d transfroms and `window.requestAnimationFrame` if available. 5874 @method setOnScrollStyles 5875 @private 5876 */ 5877 5878 NanoScroll.prototype.setOnScrollStyles = function() { 5879 var cssValue; 5880 if (hasTransform) { 5881 cssValue = {}; 5882 cssValue[transform] = "translate(0, " + this.sliderTop + "px)"; 5883 } else { 5884 cssValue = { 5885 top: this.sliderTop 5886 }; 5887 } 5888 if (rAF) { 5889 if (cAF && this.scrollRAF) { 5890 cAF(this.scrollRAF); 5891 } 5892 this.scrollRAF = rAF((function(_this) { 5893 return function() { 5894 _this.scrollRAF = null; 5895 return _this.slider.css(cssValue); 5896 }; 5897 })(this)); 5898 } else { 5899 this.slider.css(cssValue); 5900 } 5901 }; 5902 5903 5904 /** 5905 Creates event related methods 5906 @method createEvents 5907 @private 5908 */ 5909 5910 NanoScroll.prototype.createEvents = function() { 5911 this.events = { 5912 down: (function(_this) { 5913 return function(e) { 5914 _this.isBeingDragged = true; 5915 _this.offsetY = e.pageY - _this.slider.offset().top; 5916 if (!_this.slider.is(e.target)) { 5917 _this.offsetY = 0; 5918 } 5919 _this.pane.addClass(_this.options.activeClass); 5920 _this.doc.bind(MOUSEMOVE, _this.events[DRAG]).bind(MOUSEUP, _this.events[UP]); 5921 _this.body.bind(MOUSEENTER, _this.events[ENTER]); 5922 return false; 5923 }; 5924 })(this), 5925 drag: (function(_this) { 5926 return function(e) { 5927 _this.sliderY = e.pageY - _this.$el.offset().top - _this.paneTop - (_this.offsetY || _this.sliderHeight * 0.5); 5928 _this.scroll(); 5929 if (_this.contentScrollTop >= _this.maxScrollTop && _this.prevScrollTop !== _this.maxScrollTop) { 5930 _this.$el.trigger('scrollend'); 5931 } else if (_this.contentScrollTop === 0 && _this.prevScrollTop !== 0) { 5932 _this.$el.trigger('scrolltop'); 5933 } 5934 return false; 5935 }; 5936 })(this), 5937 up: (function(_this) { 5938 return function(e) { 5939 _this.isBeingDragged = false; 5940 _this.pane.removeClass(_this.options.activeClass); 5941 _this.doc.unbind(MOUSEMOVE, _this.events[DRAG]).unbind(MOUSEUP, _this.events[UP]); 5942 _this.body.unbind(MOUSEENTER, _this.events[ENTER]); 5943 return false; 5944 }; 5945 })(this), 5946 resize: (function(_this) { 5947 return function(e) { 5948 _this.reset(); 5949 }; 5950 })(this), 5951 panedown: (function(_this) { 5952 return function(e) { 5953 _this.sliderY = (e.offsetY || e.originalEvent.layerY) - (_this.sliderHeight * 0.5); 5954 _this.scroll(); 5955 _this.events.down(e); 5956 return false;
5957 }; 5958 })(this), 5959 scroll: (function(_this) { 5960 return function(e) { 5961 _this.updateScrollValues(); 5962 if (_this.isBeingDragged) { 5963 return; 5964 } 5965 if (!_this.iOSNativeScrolling) { 5966 _this.sliderY = _this.sliderTop; 5967 _this.setOnScrollStyles(); 5968 } 5969 if (e == null) { 5970 return; 5971 } 5972 if (_this.contentScrollTop >= _this.maxScrollTop) { 5973 if (_this.options.preventPageScrolling) { 5974 _this.preventScrolling(e, DOWN); 5975 } 5976 if (_this.prevScrollTop !== _this.maxScrollTop) { 5977 _this.$el.trigger('scrollend'); 5978 } 5979 } else if (_this.contentScrollTop === 0) { 5980 if (_this.options.preventPageScrolling) { 5981 _this.preventScrolling(e, UP); 5982 } 5983 if (_this.prevScrollTop !== 0) { 5984 _this.$el.trigger('scrolltop'); 5985 } 5986 } 5987 }; 5988 })(this), 5989 wheel: (function(_this) { 5990 return function(e) { 5991 var delta; 5992 if (e == null) { 5993 return; 5994 } 5995 delta = e.delta || e.wheelDelta || (e.originalEvent && e.originalEvent.wheelDelta) || -e.detail || (e.originalEvent && -e.originalEvent.detail); 5996 if (delta) { 5997 _this.sliderY += -delta / 3; 5998 } 5999 _this.scroll(); 6000 return false; 6001 }; 6002 })(this), 6003 enter: (function(_this) { 6004 return function(e) { 6005 var _ref; 6006 if (!_this.isBeingDragged) { 6007 return; 6008 } 6009 if ((e.buttons || e.which) !== 1) { 6010 return (_ref = _this.events)[UP].apply(_ref, arguments); 6011 } 6012 }; 6013 })(this) 6014 }; 6015 }; 6016 6017 6018 /** 6019 Adds event listeners with jQuery. 6020 @method addEvents 6021 @private 6022 */ 6023 6024 NanoScroll.prototype.addEvents = function() { 6025 var events; 6026 this.removeEvents(); 6027 events = this.events; 6028 if (!this.options.disableResize) { 6029 this.win.bind(RESIZE, events[RESIZE]); 6030 } 6031 if (!this.iOSNativeScrolling) { 6032 this.slider.bind(MOUSEDOWN, events[DOWN]); 6033 this.pane.bind(MOUSEDOWN, events[PANEDOWN]).bind("" + MOUSEWHEEL + " " + DOMSCROLL, events[WHEEL]); 6034 } 6035 this.$content.bind("" + SCROLL + " " + MOUSEWHEEL + " " + DOMSCROLL + " " + TOUCHMOVE, events[SCROLL]); 6036 }; 6037 6038 6039 /** 6040 Removes event listeners with jQuery. 6041 @method removeEvents 6042 @private 6043 */ 6044 6045 NanoScroll.prototype.removeEvents = function() { 6046 var events; 6047 events = this.events; 6048 this.win.unbind(RESIZE, events[RESIZE]); 6049 if (!this.iOSNativeScrolling) { 6050 this.slider.unbind(); 6051 this.pane.unbind(); 6052 } 6053 this.$content.unbind("" + SCROLL + " " + MOUSEWHEEL + " " + DOMSCROLL + " " + TOUCHMOVE, events[SCROLL]); 6054 }; 6055 6056 6057 /** 6058 Generates nanoScroller's scrollbar and elements for it. 6059 @method generate 6060 @chainable 6061 @private 6062 */ 6063 6064 NanoScroll.prototype.generate = function() { 6065 var contentClass, cssRule, currentPadding, options, pane, paneClass, sliderClass; 6066 options = this.options; 6067 paneClass = options.paneClass, sliderClass = options.sliderClass, contentClass = options.contentClass; 6068 if (!(pane = this.$el.children("." + paneClass)).length && !pane.children("." + sliderClass).length) { 6069 this.$el.append("<div class=\"" + paneClass + "\"><div class=\"" + sliderClass + "\" /></div>"); 6070 } 6071 this.pane = this.$el.children("." + paneClass); 6072 this.slider = this.pane.find("." + sliderClass); 6073 if (BROWSER_SCROLLBAR_WIDTH === 0 && isFFWithBuggyScrollbar()) { 6074 currentPadding = window.getComputedStyle(this.content, null).getPropertyValue('padding-right').replace(/[^0-9.]+/g, ''); 6075 cssRule = { 6076 right: -14, 6077 paddingRight: +currentPadding + 14 6078 }; 6079 } else if (BROWSER_SCROLLBAR_WIDTH) { 6080 cssRule = { 6081 right: -BROWSER_SCROLLBAR_WIDTH 6082 }; 6083 this.$el.addClass(options.enabledClass); 6084 } 6085 if (cssRule != null) { 6086 this.$content.css(cssRule); 6087 } 6088 return this; 6089 }; 6090 6091 6092 /** 6093 @method restore 6094 @private 6095 */ 6096 6097 NanoScroll.prototype.restore = function() { 6098 this.stopped = false;
6099 if (!this.iOSNativeScrolling) { 6100 this.pane.show(); 6101 } 6102 this.addEvents(); 6103 }; 6104 6105 6106 /** 6107 Resets nanoScroller's scrollbar. 6108 @method reset 6109 @chainable 6110 @example 6111 $(".nano").nanoScroller(); 6112 */ 6113 6114 NanoScroll.prototype.reset = function() { 6115 var content, contentHeight, contentPosition, contentStyle, contentStyleOverflowY, paneBottom, paneHeight, paneOuterHeight, paneTop, parentMaxHeight, right, sliderHeight; 6116 if (this.iOSNativeScrolling) { 6117 this.contentHeight = this.content.scrollHeight; 6118 return; 6119 } 6120 if (!this.$el.find("." + this.options.paneClass).length) { 6121 this.generate().stop(); 6122 } 6123 if (this.stopped) { 6124 this.restore(); 6125 } 6126 content = this.content; 6127 contentStyle = content.style; 6128 contentStyleOverflowY = contentStyle.overflowY; 6129 if (BROWSER_IS_IE7) { 6130 this.$content.css({ 6131 height: this.$content.height() 6132 }); 6133 } 6134 contentHeight = content.scrollHeight + BROWSER_SCROLLBAR_WIDTH; 6135 parentMaxHeight = parseInt(this.$el.css("max-height"), 10); 6136 if (parentMaxHeight > 0) { 6137 this.$el.height(""); 6138 this.$el.height(content.scrollHeight > parentMaxHeight ? parentMaxHeight : content.scrollHeight); 6139 } 6140 paneHeight = this.pane.outerHeight(false); 6141 paneTop = parseInt(this.pane.css('top'), 10); 6142 paneBottom = parseInt(this.pane.css('bottom'), 10); 6143 paneOuterHeight = paneHeight + paneTop + paneBottom; 6144 sliderHeight = Math.round(paneOuterHeight / contentHeight * paneHeight); 6145 if (sliderHeight < this.options.sliderMinHeight) { 6146 sliderHeight = this.options.sliderMinHeight; 6147 } else if ((this.options.sliderMaxHeight != null) && sliderHeight > this.options.sliderMaxHeight) { 6148 sliderHeight = this.options.sliderMaxHeight; 6149 } 6150 if (contentStyleOverflowY === SCROLL && contentStyle.overflowX !== SCROLL) { 6151 sliderHeight += BROWSER_SCROLLBAR_WIDTH; 6152 } 6153 this.maxSliderTop = paneOuterHeight - sliderHeight; 6154 this.contentHeight = contentHeight; 6155 this.paneHeight = paneHeight; 6156 this.paneOuterHeight = paneOuterHeight; 6157 this.sliderHeight = sliderHeight; 6158 this.paneTop = paneTop; 6159 this.slider.height(sliderHeight); 6160 this.events.scroll(); 6161 this.pane.show(); 6162 this.isActive = true; 6163 if ((content.scrollHeight === content.clientHeight) || (this.pane.outerHeight(true) >= content.scrollHeight && contentStyleOverflowY !== SCROLL)) { 6164 this.pane.hide(); 6165 this.isActive = false; 6166 } else if (this.el.clientHeight === content.scrollHeight && contentStyleOverflowY === SCROLL) { 6167 this.slider.hide(); 6168 } else { 6169 this.slider.show(); 6170 } 6171 this.pane.css({ 6172 opacity: (this.options.alwaysVisible ? 1 : ''), 6173 visibility: (this.options.alwaysVisible ? 'visible' : '') 6174 }); 6175 contentPosition = this.$content.css('position'); 6176 if (contentPosition === 'static' || contentPosition === 'relative') { 6177 right = parseInt(this.$content.css('right'), 10); 6178 if (right) { 6179 this.$content.css({ 6180 right: '', 6181 marginRight: right 6182 }); 6183 } 6184 } 6185 return this; 6186 }; 6187 6188 6189 /** 6190 @method scroll 6191 @private 6192 @example 6193 $(".nano").nanoScroller({ scroll: 'top' }); 6194 */ 6195 6196 NanoScroll.prototype.scroll = function() { 6197 if (!this.isActive) { 6198 return; 6199 } 6200 this.sliderY = Math.max(0, this.sliderY); 6201 this.sliderY = Math.min(this.maxSliderTop, this.sliderY); 6202 this.$content.scrollTop(this.maxScrollTop * this.sliderY / this.maxSliderTop); 6203 if (!this.iOSNativeScrolling) { 6204 this.updateScrollValues(); 6205 this.setOnScrollStyles(); 6206 } 6207 return this; 6208 }; 6209 6210 6211 /** 6212 Scroll at the bottom with an offset value 6213 @method scrollBottom 6214 @param offsetY {Number} 6215 @chainable 6216 @example 6217 $(".nano").nanoScroller({ scrollBottom: value }); 6218 */ 6219 6220 NanoScroll.prototype.scrollBottom = function(offsetY) { 6221 if (!this.isActive) { 6222 return; 6223 } 6224 this.$content.scrollTop(this.contentHeight - this.$content.height() - offsetY).trigger(MOUSEWHEEL);
6225 this.stop().restore(); 6226 return this; 6227 }; 6228 6229 6230 /** 6231 Scroll at the top with an offset value 6232 @method scrollTop 6233 @param offsetY {Number} 6234 @chainable 6235 @example 6236 $(".nano").nanoScroller({ scrollTop: value }); 6237 */ 6238 6239 NanoScroll.prototype.scrollTop = function(offsetY) { 6240 if (!this.isActive) { 6241 return; 6242 } 6243 this.$content.scrollTop(+offsetY).trigger(MOUSEWHEEL); 6244 this.stop().restore(); 6245 return this; 6246 }; 6247 6248 6249 /** 6250 Scroll to an element 6251 @method scrollTo 6252 @param node {Node} A node to scroll to. 6253 @chainable 6254 @example 6255 $(".nano").nanoScroller({ scrollTo: $('#a_node') }); 6256 */ 6257 6258 NanoScroll.prototype.scrollTo = function(node) { 6259 if (!this.isActive) { 6260 return; 6261 } 6262 this.scrollTop(this.$el.find(node).get(0).offsetTop); 6263 return this; 6264 }; 6265 6266 6267 /** 6268 To stop the operation. 6269 This option will tell the plugin to disable all event bindings and hide the gadget scrollbar from the UI. 6270 @method stop 6271 @chainable 6272 @example 6273 $(".nano").nanoScroller({ stop: true }); 6274 */ 6275 6276 NanoScroll.prototype.stop = function() { 6277 if (cAF && this.scrollRAF) { 6278 cAF(this.scrollRAF); 6279 this.scrollRAF = null; 6280 } 6281 this.stopped = true; 6282 this.removeEvents(); 6283 if (!this.iOSNativeScrolling) { 6284 this.pane.hide(); 6285 } 6286 return this; 6287 }; 6288 6289 6290 /** 6291 Destroys nanoScroller and restores browser's native scrollbar. 6292 @method destroy 6293 @chainable 6294 @example 6295 $(".nano").nanoScroller({ destroy: true }); 6296 */ 6297 6298 NanoScroll.prototype.destroy = function() { 6299 if (!this.stopped) { 6300 this.stop(); 6301 } 6302 if (!this.iOSNativeScrolling && this.pane.length) { 6303 this.pane.remove(); 6304 } 6305 if (BROWSER_IS_IE7) { 6306 this.$content.height(''); 6307 } 6308 this.$content.removeAttr('tabindex'); 6309 if (this.$el.hasClass(this.options.enabledClass)) { 6310 this.$el.removeClass(this.options.enabledClass); 6311 this.$content.css({ 6312 right: '' 6313 }); 6314 } 6315 return this; 6316 }; 6317 6318 6319 /** 6320 To flash the scrollbar gadget for an amount of time defined in plugin settings (defaults to 1,5s). 6321 Useful if you want to show the user (e.g. on pageload) that there is more content waiting for him. 6322 @method flash 6323 @chainable 6324 @example 6325 $(".nano").nanoScroller({ flash: true }); 6326 */ 6327 6328 NanoScroll.prototype.flash = function() { 6329 if (this.iOSNativeScrolling) { 6330 return; 6331 } 6332 if (!this.isActive) { 6333 return; 6334 } 6335 this.reset(); 6336 this.pane.addClass(this.options.flashedClass); 6337 setTimeout((function(_this) { 6338 return function() { 6339 _this.pane.removeClass(_this.options.flashedClass); 6340 }; 6341 })(this), this.options.flashDelay); 6342 return this; 6343 }; 6344 6345 return NanoScroll; 6346 6347 })(); 6348 $.fn.nanoScroller = function(settings) { 6349 return this.each(function() { 6350 var options, scrollbar; 6351 if (!(scrollbar = this.nanoscroller)) { 6352 options = $.extend({}, defaults, settings); 6353 this.nanoscroller = scrollbar = new NanoScroll(this, options); 6354 } 6355 if (settings && typeof settings === "object") { 6356 $.extend(scrollbar.options, settings); 6357 if (settings.scrollBottom != null) { 6358 return scrollbar.scrollBottom(settings.scrollBottom); 6359 } 6360 if (settings.scrollTop != null) { 6361 return scrollbar.scrollTop(settings.scrollTop); 6362 } 6363 if (settings.scrollTo) { 6364 return scrollbar.scrollTo(settings.scrollTo); 6365 } 6366 if (settings.scroll === 'bottom') { 6367 return scrollbar.scrollBottom(0); 6368 } 6369 if (settings.scroll === 'top') { 6370 return scrollbar.scrollTop(0); 6371 } 6372 if (settings.scroll && settings.scroll instanceof $) { 6373 return scrollbar.scrollTo(settings.scroll); 6374 } 6375 if (settings.stop) { 6376 return scrollbar.stop(); 6377 } 6378 if (settings.destroy) { 6379 return scrollbar.destroy(); 6380 } 6381 if (settings.flash) { 6382 return scrollbar.flash(); 6383 } 6384 } 6385 return scrollbar.reset(); 6386 }); 6387 }; 6388 $.fn.nanoScroller.Constructor = NanoScroll; 6389}); 6390 6391//# sourceMappingURL=jquery.nanoscroller.js.map 6392 6393// Create cookie function 6394function createCookie(name,value,days) { 6395 if (days) { 6396 var date = new Date(); 6397 date.setTime(date.getTime()+(days*24*60*60*1000)); 6398 var expires = "; expires="+date.toGMTString(); 6399 } 6400 else var expires = ""; 6401 document.cookie = name+"="+value+expires+"; path=/"; 6402} 6403 6404// Delete cookie 6405function deleteCookie(name) { 6406 createCookie(name,"",-1); 6407} 6408 6409// To determine if a element is visble within the viewport - intended to be used in conjunctio with scrolling 6410function scrolledIntoView(elem) { 6411 var $elem = $(elem); 6412 var $window = $(window); 6413 var docViewTop = $window.scrollTop(); 6414 var docViewBottom = docViewTop + $window.outerHeight(); 6415 var elemTop = $elem.offset().top; 6416 var elemBottom = elemTop + $elem.height(); 6417 return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop)); 6418} 6419 6420function js_serialize(obj) { 6421 var str = []; 6422 for(var p in obj) 6423 if (obj.hasOwnProperty(p)) { 6424 str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p])); 6425 } 6426 return str.join("&"); 6427} 6428 6429 function addScript( url, callback ) { 6430 var script = document.createElement( 'script' ); 6431 if( callback ) script.onload = callback; 6432 script.type = 'text/javascript'; 6433 script.src = url; 6434 document.body.appendChild( script ); 6435} 6436 6437function isTouchDevice(){ 6438 return true == ("ontouchstart" in window || window.DocumentTouch && document instanceof DocumentTouch); 6439} 6440//---------------------------------------------------------------- 6441// Home - 6442//---------------------------------------------------------------- 6443KT.Home = { 6444 init: function() { 6445 6446 if ($('body.home').length) { 6447 6448 // Open search bar on hover 6449 $('#home-search-toggle').hover(function() { 6450 $('.home-feature__search').addClass('home-feature__search--open'); 6451 $('.home-feature__image').addClass('home-feature__image--search'); 6452 }); 6453 6454 $("#has_document").on('change', function() { 6455 if ($(this).is(":checked")) { 6456 $("#has_image").prop('checked', false); 6457 } 6458 }); 6459 $("#has_image").on('click', function() { 6460 if ($(this).is(":checked")) { 6461 $("#has_document").prop('checked', false); 6462 } 6463 }); 6464 6465 // Change background colour and font of nav based on scroll height 6466 6467 var targetOffset = $("#anchor-point").offset().top; 6468 6469 var $w = $(window).scroll(function() { 6470 if (($w.scrollTop() + 500) > targetOffset) { 6471 $('.navigation').addClass('navigation--scroll'); 6472 } else { 6473 $('.navigation').removeClass('navigation--scroll'); 6474 } 6475 }); 6476 6477 $('.home-feature__scroll').on('click', function() { 6478 $('html,body').animate({
6479 scrollTop: $('.summary-feature').position().top - 55 6480 }, 1000); 6481 }); 6482 6483 } 6484 } 6485} 6486 6487//---------------------------------------------------------------- 6488// Lightbox - using featherlight plugin, used for login and images 6489//---------------------------------------------------------------- 6490KT.Lightbox = { 6491 init: function() { 6492 6493 var configuration = { 6494 6495 } 6496 6497 $('[data-img-lightbox]').each(function(){ 6498 var $el = $(this); 6499 $el.featherlight($el.attr('href')); 6500 }); 6501 6502 $('[data-img-ightbox-gallery]').featherlightGallery({ 6503 afterContent: function() { 6504 this.$legend = this.$legend || $('<div class="legend"/>').insertAfter(this.$content); 6505 this.$legend.html(this.$currentTarget.data('content')); 6506 } 6507 }); 6508 6509 } 6510} 6511 6512KT.Navigation = { 6513 init: function() { 6514 6515 $('#menu-toggle').on('click', function(){ 6516 $('#navigation').addClass('navigation--open'); 6517 $('.navigation').addClass('navigation--open'); 6518 $('#close-menu').addClass('navigation--open'); 6519 $('#menu-toggle').addClass('navigation--open'); 6520 $('#login-toggle').addClass('navigation--open'); 6521 $('.navigation__actions').addClass('navigation--open'); 6522 $('.navigation__overlay').addClass('navigation__overlay--visible'); 6523 $('body').addClass('no-scroll'); 6524 }) 6525 6526 $('#close-menu').on('click', function(){ 6527 $('#navigation').removeClass('navigation--open'); 6528 $('.navigation').removeClass('navigation--open'); 6529 $('#close-menu').removeClass('navigation--open'); 6530 $('#menu-toggle').removeClass('navigation--open'); 6531 $('#login-toggle').removeClass('navigation--open'); 6532 $('.navigation__actions').removeClass('navigation--open'); 6533 $('.navigation__overlay').removeClass('navigation__overlay--visible'); 6534 $('body').removeClass('no-scroll'); 6535 }) 6536 6537 $('[data-login-trigger]').on('click', function(){ 6538 $.featherlight('#login-form', { 6539 namespace: 'featherlight', 6540 closeIcon: '', 6541 otherClose: '#close-lightbox', 6542 }); 6543 }); 6544 6545 $('[data-forgotten]').on('click', function(){ 6546 $('.lightbox_login__form').hide(); 6547 $('.lightbox_login__form--password').show(); 6548 }); 6549 6550 $('[data-forgotten-back]').on('click', function(){ 6551 $('.lightbox_login__form').show(); 6552 $('.lightbox_login__form--password').hide(); 6553 }); 6554 6555 } 6556} 6557//---------------------------------------------------------------- 6558// Custom <select> element - used for styling purposes 6559//---------------------------------------------------------------- 6560KT.Select = { 6561 // SELECT MENU ITEM ON FIRST LETTER KEYPRESS 6562 // //////////////////////////////////////// 6563 storage:{ 6564 letter: '', 6565 index: 0, 6566 letterArr: [] 6567 }, 6568 6569 getMenuItems: function(that){ 6570 "use strict" 6571 this.clearLetterState() 6572 6573 var $items = $(that).parent().find('.nano li:nth-of-type(n+2)') 6574 var itemsArr = Array.from($items) 6575 6576 var itemsObj = itemsArr.reduce(function(obj, item){ 6577 var firstLetter = item.innerText.toLowerCase().slice(0,1) 6578 if(obj[firstLetter] === undefined){ 6579 obj[firstLetter] = [] 6580 } 6581 obj[firstLetter].push(item.id) 6582 return obj 6583 }, {}) 6584 // console.table(itemsObj) 6585 return itemsObj 6586 }, 6587 6588 onKeyUpHover: function(obj){ 6589 "use strict" 6590 var that = this 6591 $(window).off("keyup") 6592 $(window).bind("keyup",function(e){ 6593 var keyPress = String.fromCharCode(e.keyCode).toLowerCase(); 6594 that.storage.letterArr = obj[keyPress] 6595 var idxArr = that.storage.letterArr 6596 6597 if(idxArr){ 6598 var idxId = that.letterState(keyPress) 6599 that.focusByElement(idxArr, idxId) 6600 } 6601 }) 6602 }, 6603 6604 letterState: function(letter){ 6605 "use strict" 6606 // resset index if different letter was pressed 6607 if(letter !== this.storage.letter){ 6608 this.storage.index = 0 6609 } 6610 this.storage.letter = letter 6611 6612 // array/index incressing or resseting 6613 var arrLength = this.storage.letterArr.length -1 6614 var lastIndex = this.storage.index 6615 if(this.storage.index < arrLength){ 6616 this.storage.index ++ 6617 } else { 6618 this.storage.index = 0 6619 } 6620 return lastIndex 6621 }, 6622 6623 focusByElement: function(letterIdsArr, index){ 6624 "use strict" 6625 var element = letterIdsArr[index] 6626 if(element){ 6627 document.getElementById(element).focus() 6628 } 6629 }, 6630 6631 clearLetterState: function(){ 6632 "use strict" 6633 this.storage.letter = '' 6634 this.storage.index = 0 6635 }, 6636 6637 initFocusByLetter: function(event){ 6638 "use strict" 6639 var getLettersIndex = this.getMenuItems(event) 6640 this.onKeyUpHover(getLettersIndex) 6641 }, 6642 6643 // INIT'ish and everything else... 6644 // /////////////////////////////// 6645 init: function() { 6646 "use strict" 6647 var that = this 6648 if ( $('[data-select]').length && !$('body').hasClass('isMobile') ){ 6649 var filterId = 0 6650 $('[data-select]').each(function(){ 6651 filterId ++ 6652 var $el = $(this); 6653 var $select = $el.find('select'); 6654 var label = ($el.data('label') && $el.data('label').length > 0 ? $el.data('label') : ''); 6655 6656 if ($el.find('dropdown').length > 0){ return; } 6657 6658 $el.append('<div class="dropdown"><div class="selected">'+label+$select.find('option:selected').text()+'</div><div class="nano"><div class="nano-content"><ul></ul></div></div></div>') 6659 var $dropdown = $el.find('.dropdown'); 6660 var $selected = $dropdown.find('.selected'); 6661 var $list = $dropdown.find('.nano'); 6662 6663 $select.find('option').each(function(index){ 6664 var selected = ''; 6665 if ( $(this).is(':selected')){ selected = "style='display:none;'"; } 6666 var li = '<li '+selected+' data-val="'+$(this).val()+'" id="idx'+filterId+index+'" tabindex="-1">'+$(this).text()+'</li>'; 6667 $dropdown.find('ul').append(li); 6668 }); 6669 // open menu 6670 $selected.click(function(){ 6671 // select item by pressing letter 6672 that.initFocusByLetter(this) 6673 6674 if ( $list.hasClass('open') ) { 6675 $list.removeClass('open'); 6676 $dropdown.removeClass('open'); 6677 $(".nano").nanoScroller({ destroy: true }); 6678 } else { 6679 $('.dropdown.open').removeClass('open'); 6680 $('.dropdown .nano.open').removeClass('open'); 6681 $list.addClass('open'); 6682 $dropdown.addClass('open'); 6683 6684 $(".nano").nanoScroller({ sliderMinHeight: 80, sliderMaxHeight: 80 }); 6685 $('.nano-slider').html('<span class="sTop"></span><span class="sMiddle"></span><span class="sBottom"></span>') 6686 } 6687 }); 6688 // click menu item 6689 $dropdown.find('ul li').on('click keyup', function(e){ 6690 if (e.which === 13 || e.type === 'click') { 6691 $select.find('option:selected').removeAttr('selected');
6692 $select.find('option[value="'+$(this).data('val')+'"]').attr('selected','selected'); 6693 6694 $dropdown.find('ul li').show(); 6695 $(this).hide(); 6696 $list.toggleClass('open'); 6697 $dropdown.toggleClass('open'); 6698 6699 // Assign new value and trigger change 6700 $select.val($(this).data('val')).trigger('change'); 6701 6702 // Trigger event 6703 var el = $select.get(0); 6704 var event = document.createEvent('Events'); 6705 event.initEvent('change', true, false); 6706 el.dispatchEvent(event); // goto collection.js 6707 } 6708 }); 6709 $select.hide(); 6710 6711 if ( $el.is('[data-select-layout]') ){ 6712 var width = 0; 6713 $el.find('li').each(function(){ 6714 if ($(this).outerWidth() > width){ 6715 width = $(this).outerWidth(); 6716 } 6717 }); 6718 $list.css('width',width); 6719 $el.addClass('rendered'); 6720 if ( $el.width() > $list.width() ){ 6721 $list.css('width',$el.outerWidth()); 6722 } 6723 } 6724 }); 6725 6726 if ( $('[data-select]').length ){ 6727 $(document).on('click', function(e){ 6728 // debugger // open menu click; li item click; 6729 var $el = $(e.target); 6730 if ( $el.parents('[data-select]').length === 0 ){ 6731 $('.dropdown.open').removeClass('open'); 6732 $('.dropdown .nano.open').removeClass('open'); 6733 } 6734 }); 6735 } 6736 } 6737 6738 if ( $('[data-mobile]').length ){ 6739 $('[data-mobile]').each(function(){ 6740 var $el = $(this); 6741 var $select = $el.find('select'); 6742 $select.change(function(){ 6743 // console.log($select.val()); 6744 window.location = $select.val(); 6745 }); 6746 }); 6747 } 6748 6749 } 6750} 6751 6752KT.Object = { 6753 init: function() { 6754 6755 var widnow_w = $(window).width(); 6756 6757 // image slider 6758 var slider = $('.slider').slick({ 6759 slidesToShow: 1, 6760 adaptiveHeight: true, 6761 centerMode: false, 6762 infinite: false, 6763 slide: '.slider__slide', 6764 arrows: true, 6765 draggable: false, 6766 prevArrow: '<button class="btn--icon icon-arrow-left prev">previous image</button>', 6767 nextArrow: '<button class="btn--icon icon-arrow-right next">next image</button>', 6768 appendArrows: '.slider__nav' 6769 }); 6770 6771 slider.on('beforeChange', function(event, slick, currentSlide, nextSlide){ 6772 if ( $('[data-slider-credits]').length > 0){ 6773 $('[data-slider-credits]').find('p').hide(); 6774 $('[data-slider-credits]').find('p:nth-child('+nextSlide+1+')').show(); 6775 } 6776 }); 6777 slider.on('afterChange', function(event, slick, currentSlide, nextSlide){ 6778 $('[data-count]').find('span').html(currentSlide+1); 6779 }); 6780 6781 // carousel for cards on mobile 6782 var slides_to_show = 1.2; 6783 if(widnow_w > 600){ slides_to_show = 3; } 6784 if(widnow_w > 800){ slides_to_show = 4; } 6785 $('.carousel').each(function(){ 6786 $(this).slick({ 6787 slidesToShow: slides_to_show, 6788 adaptiveHeight: true, 6789 centerMode: false, 6790 infinite: false, 6791 slide: '.carousel__item', 6792 arrows: true,
6793 prevArrow: false, 6794 nextArrow: '<button class="btn--carousel icon-arrow-right next"></button>', 6795 prevArrow: '<button class="btn--carousel icon-arrow-left prev"></button>', 6796 appendArrows: $(this).find('.carousel__nav') 6797 }); 6798 }); 6799 6800 } 6801} 6802KT.Panzoom = { 6803 setup: function(){ 6804 "use strict" 6805 this.$PZ_Page = $('[data-pan-zoom-page]') 6806 this.$PZ_Page_Stage = this.$PZ_Page.find('[data-pan-zoom-stage]') 6807 this.$PZ_Page_Images = this.$PZ_Page_Stage.find('img') 6808 this.$PZ_Page_Instance = this.$PZ_Page_Stage.panzoom({ // Plugin setup 6809 minScale: 1, 6810 increment: 0.3, 6811 duration: 400, // Animation duration (ms) 6812 $zoomIn: this.$PZ_Page.find('[data-zoom-in]'), 6813 $zoomOut: this.$PZ_Page.find('[data-zoom-out]') 6814 }) 6815 6816 this.$PZ_Lightbox = $('[data-pan-zoom-lightbox]') 6817 this.$PZ_Lightbox_Stage = this.$PZ_Lightbox.find('[data-pan-zoom-stage]') 6818 this.$PZ_Lightbox_Images = this.$PZ_Lightbox_Stage.find('img') 6819 this.$PZ_Lightbox_Instance = this.$PZ_Lightbox_Stage.panzoom({ // Plugin setup 6820 minScale: 0.5, 6821 increment: 0.3, 6822 duration: 400, // Animation duration (ms) 6823 $zoomIn: this.$PZ_Lightbox.find('[data-zoom-in]'), 6824 $zoomOut: this.$PZ_Lightbox.find('[data-zoom-out]') 6825 }) 6826 6827 this.currentImg = 1 6828 }, 6829 6830 6831 showCurrentImage: function(){ 6832 "use strict" 6833 $('[data-object-lightbox]').addClass('visible') 6834 $('body').addClass('no-scroll') 6835 6836 this.$PZ_Page_Stage.find('.slider__image').hide() 6837 var $next_img_page = this.$PZ_Page_Stage.find('.slider__image:nth-child('+(this.currentImg)+')') 6838 $next_img_page.attr('src', $next_img_page.data('src') ) 6839 $next_img_page.show() 6840 6841 this.$PZ_Lightbox_Stage.find('.slider__image').hide() 6842 var $next_img_lightbox = this.$PZ_Lightbox_Stage.find('.slider__image:nth-child('+(this.currentImg)+')') 6843 $next_img_lightbox.attr('src', $next_img_lightbox.data('src') ) 6844 $next_img_lightbox.show() 6845 6846 $('[data-gallery]').removeClass('visible') 6847 this.$PZ_Lightbox.addClass('visible') 6848 }, 6849 6850 6851 updateIndex: function($imgContainer){ 6852 "use strict" 6853 var $img = $imgContainer.find('img') 6854 this.currentImg = $img.data('index')+1 // cleaning: data-key no longer needed in markdown 6855 $('[data-count] span').html(this.currentImg) 6856 }, 6857 6858 6859 copyright: function(){ 6860 "use strict" 6861 $('[data-copyright]').hide() 6862 $('[data-copyright]:nth-child('+this.currentImg+')').show() 6863 }, 6864 6865 6866 prevNextImg: function(variant, direction){ 6867 "use strict" 6868 var $PZ, $PZ_Instance, $PZ_Stage, $PZ_Images 6869 var that = this 6870 6871 switch(variant){ 6872 case 'page': 6873 $PZ = this.$PZ_Page 6874 $PZ_Instance = this.$PZ_Page_Instance 6875 $PZ_Stage = this.$PZ_Page_Stage 6876 $PZ_Images = this.$PZ_Page_Images 6877 break 6878 case 'lightbox': 6879 $PZ = this.$PZ_Lightbox 6880 $PZ_Instance = this.$PZ_Lightbox_Instance 6881 $PZ_Stage = this.$PZ_Lightbox_Stage 6882 $PZ_Images = this.$PZ_Lightbox_Images 6883 break 6884 } 6885 6886 var element, childNumber 6887 switch(direction){ 6888 case 'prev': 6889 element = '[data-prev]' 6890 childNumber = -1 6891 break 6892 case 'next': 6893 element = '[data-next]' 6894 childNumber = +1 6895 break 6896 } 6897 6898 $PZ.find(element).on('click', function(){ 6899 if( direction === 'prev' && this.currentImg === 1 ){ return false } 6900 if( (direction === 'next' && this.currentImg === $PZ_Images.length) || this.currentImg > $PZ_Images.length){ return false } 6901 $($PZ).find('.slider__image:nth-child('+that.currentImg+')') 6902 .hide() 6903 $PZ_Instance.panzoom("reset") // reset zoom 6904 var $next_img = $($PZ_Stage).find('.slider__image:nth-child('+(this.currentImg + childNumber)+')') 6905 $next_img.attr('src', $next_img.data('src') ) 6906 .show() 6907 6908 this.updateIndex($next_img) 6909 this.copyright() 6910 }.bind(this)) 6911 }, 6912 6913 6914 init: function() { 6915 "use strict" 6916 this.setup() 6917 6918 // Pan zoom PAGE 6919 // //////////////// 6920 this.prevNextImg('page', 'prev') 6921 this.prevNextImg('page', 'next') 6922 6923 // Pan zoom LIGHT BOX 6924 // ///////////////// 6925 this.prevNextImg('lightbox', 'prev') 6926 this.prevNextImg('lightbox', 'next') 6927 6928 $('[data-fullscreen]').on('click', function(){ 6929 this.showCurrentImage() 6930 }.bind(this)) 6931 6932 $('[data-fullscreen-close]').on('click', function(){ 6933 this.showCurrentImage() 6934 $('[data-object-lightbox]').removeClass('visible') 6935 $('body').removeClass('no-scroll') 6936 }.bind(this)) 6937 6938 $('[data-bottom-close]').on('click', function(){ 6939 if ($(this).hasClass('collapsed')) { 6940 $('[data-object-lightbox]').removeClass('bottom-hidden') 6941 $(this).removeClass('collapsed') 6942 } else { 6943 $('[data-object-lightbox]').addClass('bottom-hidden') 6944 $(this).addClass('collapsed') 6945 } 6946 }.bind(this)) 6947 6948 // Gallery view - all images in panzoom mode 6949 // ////////////////////////////////////////// 6950 $('[data-gallery-toggle]').on('click', function(){ // open gallery 6951 this.$PZ_Lightbox.removeClass('visible') 6952 $('[data-gallery]').addClass('visible') 6953 }.bind(this)) 6954 6955 $('[data-gallery] .img').on('click', function(event){ // close gallery 6956 var $imgContainer = $(event.target.closest('.img')) 6957 this.updateIndex($imgContainer) 6958 this.showCurrentImage() 6959 this.copyright() 6960 6961 this.$PZ_Page_Instance.panzoom("reset") // reset zoom 6962 this.$PZ_Lightbox_Instance.panzoom("reset") // reset zoom 6963 }.bind(this)) 6964 6965 } 6966} 6967 6968 6969 6970$('[data-search-content-toggle]').on('click', function(){ 6971 var text = $(this).text(); 6972 $(this).toggleClass('active'); 6973 $(this).html($(this).attr('rel')).attr('rel', text); 6974 $(this).parents('.search-bar').toggleClass('search-bar--open'); 6975}); 6976//---------------------------------------------------------------- 6977// Collection 6978//---------------------------------------------------------------- 6979KT.Collection = { 6980 moreTags: function(){ 6981 $('[data-more-tags]').on('click', function(){ 6982 var $container = $('.tags') 6983 var $tag = $container.find('.tag') 6984 var $hidenTags = $container.find('.hidden') 6985 6986 var boxHeight = $container.height() 6987 var lineHeight = $tag.outerHeight(true) 6988 // console.log("it should by 0: " + boxHeight % lineHeight) 6989 6990 if($hidenTags.length == 0){ 6991 $container.find('[data-hidden]').toggleClass('hidden') 6992 var text = $(this).text() // toogle attr<->text 6993 $(this).html($(this).attr('rel')).attr('rel', text) 6994 } 6995 6996 for(var i=0; i < $hidenTags.length; i++){ 6997 var boxHeightExpand = $container.height() 6998 var heightAdded = boxHeightExpand - boxHeight 6999 7000 if((heightAdded / lineHeight) < 4){ 7001 $hidenTags.eq(i).toggleClass('hidden') 7002 } 7003 } 7004 7005 // update DOM variables 7006 // var boxHeight = $container.height() 7007 var $hidenTags = $container.find('.hidden') 7008 7009 if($hidenTags.length == 0){ 7010 var text = $(this).text() // toogle attr<->text 7011 $(this).html($(this).attr('rel')).attr('rel', text) 7012 } 7013 7014 }) 7015 }, 7016 7017 reduceTags: function(){ 7018 var isMobile = $('body').hasClass('mobile') 7019 if(isMobile){ 7020 var $container = $('.tags') 7021 var $tag = $container.find('.tag') 7022 var $visibleTags = $container.find('a:not(.hidden)') 7023 // console.log($visibleTags) 7024 // console.log($visibleTags.length) 7025 7026 var $visibleTags = $container.find('a:not(.hidden)') 7027 var boxHeight = $container.height() 7028 var lineHeight = $tag.outerHeight(true) 7029 // console.log("it should by 0: " + boxHeight % lineHeight) 7030 7031 for(var i=$visibleTags.length; i>0; i--){ 7032 var $visibleTags = $container.find('a:not(.hidden)') 7033 var boxHeightReduced = $container.height() 7034 // console.log(boxHeightReduced, 'boxHeightReduced') 7035 // console.log(lineHeight, 'boxHeight') 7036 // console.log(boxHeightReduced / lineHeight) 7037 7038 if((boxHeightReduced / lineHeight) > 4){ 7039 $visibleTags.eq(i).toggleClass('hidden') 7040 } 7041 } 7042 } 7043 }, 7044 7045 imageToggle: function($form){ 7046 $('#has_image_toggle').on('click', function(){ 7047 $('#has_image').attr('checked', true) 7048 $('#has_document').attr('checked', false) 7049 $form.submit() 7050 }) 7051 }, 7052 7053 documentToggle: function($form){ 7054 $('#has_document_toggle').on('click', function(){ 7055 $('#has_image').attr('checked', false) 7056 $('#has_document').attr('checked', true) 7057 $form.submit() 7058 }) 7059 }, 7060 7061 init: function() { 7062 this.moreTags() 7063 this.reduceTags() 7064 7065 // document or image toogle. Some day make it DRY(one function). 7066 var $dataCollectionSearch = $('[data-collection-search]') 7067 if ( $dataCollectionSearch.length ){ 7068 var $form = $dataCollectionSearch.find('form') 7069 7070 $dataCollectionSearch.find('select') 7071 .on('change', function(){ 7072 $form.submit() 7073 }) 7074 7075 this.documentToggle($form) 7076 this.imageToggle($form) 7077 } 7078 7079 } 7080} 7081 7082 7083//---------------------------------------------------------------- 7084// Ajax pagination 7085//---------------------------------------------------------------- 7086KT.AjaxPagination = { 7087 init: function() { 7088 7089 // Collection Objects 7090 if( $('[data-ajax-paginate]').length > 0 ){ 7091 KT.AjaxPagination.ajax_collection(); 7092 } 7093 7094 }, 7095 ajax_collection: function(){ 7096 7097 var $el = $('[data-ajax-paginate]').find('a');
7098 var $container = $('[data-ajax-grid]'); 7099 var $loader = $el.next('.loader'); 7100 var url = $el.attr('href'); 7101 7102 var $form = $('[data-collection-search]'); 7103 7104 var params = { 7105 page: $('[data-page]').data('page'), 7106 view_as: $('[data-view]').data('view') 7107 }; 7108 7109 $el.on('click', function(event){ 7110 event.preventDefault(); 7111 $el.hide(); 7112 $loader.addClass('visible'); 7113 params.page = params.page+1; 7114 7115 $.ajax({ 7116 url: url, 7117 ContentType: "application/json; charset=utf-8", 7118 data : params, 7119 type: 'POST' 7120 }).done(function(data){ 7121 data = JSON.parse(data); 7122 7123 var $html = $(data.html); 7124 $container.append($html); 7125 $loader.removeClass('visible'); 7126 // $html.imagesLoaded(function() { 7127 // $html.addClass('visible'); 7128 // }); 7129 if(data.load_more){ 7130 $el.show(); 7131 } else { 7132 $el.hide(); 7133 } 7134 7135 KT.AjaxPagination.update_url(params.page); 7136 }); 7137 }); 7138 7139 KT.AjaxPagination.scroll_to_top(); 7140 }, 7141 scroll_to_top: function(){ 7142 7143 var $backTop = $('.back-top'); 7144 7145 $(window).scroll(function() { 7146 7147 var st = $(this).scrollTop(); 7148 7149 //show / hide back to top 7150 if (st > 1000) { 7151 $backTop.show() 7152 } else { 7153 $backTop.hide() 7154 } 7155 }); 7156 7157 $backTop.on('click', function(e) { 7158 $('html,body').animate({ scrollTop: 0 }, 1000); 7159 }); 7160 7161 }, 7162 update_url: function(page_no){ 7163 if (history.pushState) { 7164 var newpathname = window.location.pathname; 7165 var pathArray = window.location.pathname.split('/'); 7166 if (window.location.pathname.indexOf('page/') < 0) { 7167 pathArray.push('page'); 7168 pathArray.push(page_no); 7169 newpathname = pathArray.join('/'); 7170 7171 } else { 7172 var index_page = pathArray.indexOf('page'); 7173 var index_page_no = index_page + 1; 7174 if (index_page > -1) { 7175 pathArray[index_page_no] = page_no; 7176 } 7177 newpathname = pathArray.join('/'); 7178 } 7179 var newurl = window.location.protocol + "//" + window.location.host + newpathname; 7180 window.history.pushState({}, '', newurl); 7181 window.location.pathname.split('/').indexOf('page') + 1; 7182 } 7183 } 7184} 7185KT.AjaxForm = { 7186 init: function() { 7187 var $ajaxForm = $('.ajax-form'); 7188 7189 $ajaxForm.on('submit', function(e) { console.log(e); 7190 e.preventDefault(); 7191 var $form = $(this); 7192 var url = $form.prop('action'); 7193 var formData = $form.serialize(); 7194 var $submit = $form.find('input[type="submit"]'); 7195 var sending = $submit.data('feedback'); 7196 var reset = $submit.data('reset'); 7197 var complete = $submit.data('complete'); 7198 var $message = $(this).find('.message'); 7199 $submit.val(sending); 7200 7201 var headers = {}; 7202 7203 if( $(this).data('type') == 'login' ){ 7204 headers = { "Access-Control-Allow-Origin": "*" }; 7205 } 7206 7207 $.ajax({ 7208 type: 'POST', 7209 url: url, 7210 data: formData, 7211 dataType: 'json', 7212 headers: headers, 7213 success: function(response) { 7214 7215 $form.find("input").removeClass("error").find("span.error").fadeOut(); 7216 7217 if (response.status == 1) { 7218 7219 if( $form.data('type') == 'login' ){ 7220 window.location = response.redirect; 7221 return; 7222 } 7223 7224 7225 if( $form.data('type') == 'forgotten' ){ 7226 7227 } 7228 7229 // Reset form 7230 $ajaxForm[0].reset(); 7231 7232 $('.form__field input, .form__field textarea').val(''); 7233 if ($('.selectize-input').length > 0){ 7234 var $select = $('select').selectize(); 7235 var control = $select[0].selectize; 7236 control.clear();
7237 } 7238 $submit.val(reset); 7239 // Display message 7240 $message.html(response.message); 7241 7242 7243 } else { 7244 7245 console.log($message); 7246 7247 $message.html(response.message); 7248 7249 // $('label').removeClass('failure').find("span").fadeOut("fast"); 7250 // $('input, textarea, .selectize-input').removeClass('error'); 7251 7252 // setTimeout(function(){ 7253 // if (reset) { 7254 // $submit.val(reset); 7255 // } 7256 // if (response.fields) { console.log(response.fields); 7257 // $.each(response.fields, function(id, value) { 7258 // var el = $("#" + id); 7259 // if (response.messages && response.messages[id].length > 0) { console.log(response.messages[id]) 7260 // var message = response.messages[id]; 7261 // if (el.length > 0) { console.log(el) 7262 // var feild = $(el).parents('.form__field'); 7263 // feild.find("label").addClass("failure").find('span').html(message).fadeIn("fast"); 7264 // el.addClass('error'); 7265 // } 7266 // } 7267 // else { 7268 // if (el.length > 0 && value == true) { console.log(el); console.log(id); console.log(value); 7269 // var feild = $(el).parents('.form__field'); 7270 // feild.closest("label").addClass("failure").find("mark").html(value).fadeIn("fast"); 7271 // feild.find('input, textarea, .selectize-input').addClass('error'); 7272 // feild.find('label span').fadeIn(); 7273 // } 7274 // } 7275 // el.on("focus", function(e) { 7276 // $(this).closest("label").removeClass("failure").find("span").fadeOut("fast"); 7277 // }); 7278 // $('input[name="'+id+'"]').on('change', function(){ 7279 // $('label#'+id+'').removeClass('failure').find("span").fadeOut("fast"); 7280 // }); 7281 // }); 7282 // } 7283 // }, 500); 7284 } 7285 }, 7286 error: function(xhr, ajaxOptions, thrownError) { 7287 console.log("Uncaught Error.\n" + thrownError); 7288 } 7289 }); 7290 }); 7291 } 7292} 7293KT.Masonry = { 7294 init: function() { 7295 7296 if ( $('[data-masonry-grid]').length ) { 7297 7298 var $grid = $('[data-masonry-grid]'); 7299 7300 console.log($grid); 7301 7302 $.each($grid, function(i,grid) { 7303 7304 var grid_options = $(grid).data('masonry-grid'); 7305 7306 var options = { 7307 transitionDuration: 0 7308 }; 7309 7310 if (grid_options.itemSelector){ options.itemSelector = grid_options.itemSelector; } 7311 if (grid_options.columnWidth){ options.columnWidth = grid_options.columnWidth; } 7312 if (grid_options.preserveOrder){ options.preserveOrder = grid_options.preserveOrder; } 7313 7314 var $items = $('[data-masonry-grid] > div'); 7315 7316 $grid.on('layoutComplete', function() { // console.log('layout layoutComplete ') 7317 $grid.find('.card').not('.visible').addClass('visible'); 7318 $('.loader.top').removeClass('visible'); 7319 }); 7320 7321 $(grid).imagesLoaded(function() { 7322 console.log('imagesLoaded'); 7323 7324 var first_card_h = $($items[0]).height(); 7325 7326 $(grid).css('min-height', first_card_h); 7327 7328 $(grid).masonry(options); 7329 7330 // Scroll down to last viewed item (this requires and id on the card used for position tracking in long paginated lists) 7331 if (window.location.hash.length > 2 ){ 7332 $('html,body').animate({ scrollTop: $(window.location.hash).offset().top }, 100); 7333 } 7334 7335 if ($('.load-more').length) 7336 $('.load-more').animate({"opacity": 1}, 200); 7337 }); 7338 }); 7339 } 7340 } 7341} 7342KT.SummaryMore = { 7343 init: function() { 7344 if($(".details__summary").length > 0) 7345 { 7346 7347 var isOpen = false 7348 var $moreBtn = $( '<span class="read-more-summary">more...</span>' ) 7349 var $details__summary = $(".details__summary") 7350 var $details__content = $('.details__summary:nth-of-type(1)') 7351 7352 // box hight CLOSED 7353 var $cssHeight = $details__summary["0"].clientHeight 7354 7355 // box hight OPENED (minus paddings) 7356 var $paddingTop = parseInt($('.details__summary').css('padding-top')) 7357 var $paddingBottom = parseInt($('.details__summary').css('padding-bottom')) 7358 var $realHeight = $details__summary["0"].scrollHeight - $paddingTop
7358- $paddingBottom 7359 7360 function handler(){ 7361 if(isOpen == false){ 7362 $details__summary 7363 .animate({"max-height": $realHeight}, "slow") 7364 7365 isOpen = true 7366 $(".read-more-summary").text("hide...") 7367 } else if(isOpen == true){ 7368 $details__summary 7369 .animate({"max-height": $cssHeight}, "slow") 7370 7371 isOpen = false 7372 $(".read-more-summary").text("more...") 7373 } 7374 } 7375 7376 if($realHeight > $cssHeight){ 7377 $details__content 7378 .after($moreBtn) 7379 7380 $(".read-more-summary").click(handler) 7381 } 7382 } 7383 } 7384} 7385 7386 7387KT.mouseStop = { 7388 init: function() { 7389 var $container = $('.object-image-lightbox') 7390 7391 function iconsToggle(arg){ 7392 $container.find('.zoom').toggle(arg) 7393 $container.find('[data-fullscreen-close]').toggle(arg) 7394 $container.find('.nav').toggle(arg) 7395 $container.find('[data-bottom-close]').toggle(arg) 7396 $container.find('[data-gallery-toggle]').toggle(arg) 7397 $container.find('.img span').toggle(arg) 7398 } 7399 7400 $container.mousestop({delay: 2000}, function() { iconsToggle(false) }) 7401 $container.mousemove(function() { iconsToggle(true) }) 7402 7403 } 7404} 7405 7406KT.nanoScroller = { 7407 init: function() { 7408 // nanoScrooler is initialized in select.js 7409 } 7410} 7411 7412$(function(){ 7413 7414 KT.Home.init(); 7415 KT.Masonry.init(); 7416 KT.Navigation.init(); 7417 KT.Select.init(); 7418 KT.Object.init(); 7419 KT.Collection.init(); 7420 KT.Panzoom.init(); 7421 KT.AjaxPagination.init(); 7422 KT.AjaxForm.init(); 7423 KT.SummaryMore.init(); 7424 KT.mouseStop.init(); 7425 KT.nanoScroller.init(); 7426 7427 if(isTouchDevice()===false){ 7428 $('[data-toggle="tooltip"]').tooltip(); 7429 } 7430 7431 $('[data-tooltip-hide]').on('click', function () { 7432 $(this).tooltip('hide') 7433 }); 7434 7435}); 7436 7437//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImpxdWVyeS5qcyIsImJvb3RzdHJhcF9jdXN0b20uanMiLCJmZWF0aGVybGlnaHQuanMiLCJmZWF0aGVybGlnaHQuZ2FsbGVyeS5qcyIsInBhbnpvb20uanMiLCJzbGljay5taW4uanMiLCJpbWFnZXNsb2FkZWQubWluLmpzIiwibWFzb25yeS5qcyIsIm1vdXNlc3RvcC5qcyIsIm5hbm9zY3JvbGxlci5qcyIsInVsdGlscy5qcyIsImhvbWUuanMiLCJsaWdodGJveC5qcyIsIm5hdmlnYXRpb24uanMiLCJzZWxlY3QuanMiLCJvYmplY3QuanMiLCJwYW4tem9vbS5qcyIsInNlYXJjaC5qcyIsImNvbGxlY3Rpb24uanMiLCJhamF4LXBhZ2luYXRpb24uanMiLCJhamF4LWZvcm0uanMiLCJzdW1tYXJ5LW1vcmUuanMiLCJtb3VzZVN0b3AuanMiLCJuYW5vU2Nyb2xsZXIuanMiLCJtYWluLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FDSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDbnNCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQ3ZtQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUN4S0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FB
7437Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDcnhDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUNOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FB
7437Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUNsOEVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUNuRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQ3grQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQzlDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDOUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQzdDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUNsTUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQ2pEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQ3JLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD
7437QTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQzFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUNyR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FiM0dBO0F
7437BQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FjaERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQzVDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJzaXRlLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLyohIGpRdWVyeSB2Mi4yLjQgfCAoYykgalF1ZXJ5IEZvdW5kYXRpb24gfCBqcXVlcnkub3JnL2xpY2Vuc2UgKi9cbiFmdW5jdGlvbihhLGIpe1wib2JqZWN0XCI9PXR5cGVvZiBtb2R1bGUmJlwib2JqZWN0XCI9PXR5cGVvZiBtb2R1bGUuZXhwb3J0cz9tb2R1bGUuZXhwb3J0cz1hLmRvY3VtZW50P2IoYSwhMCk6ZnVuY3Rpb24oYSl7aWYoIWEuZG9jdW1lbnQpdGhyb3cgbmV3IEVycm9yKFwialF1ZXJ5IHJlcXVpcmVzIGEgd2luZG93IHdpdGggYSBkb2N1bWVudFwiKTtyZXR1cm4gYihhKX06YihhKX0oXCJ1bmRlZmluZWRcIiE9dHlwZW9mIHdpbmRvdz93aW5kb3c6dGhpcyxmdW5jdGlvbihhLGIpe3ZhciBjPVtdLGQ9YS5kb2N1bWVudCxlPWMuc2xpY2UsZj1jLmNvbmNhdCxnPWMucHVzaCxoPWMuaW5kZXhPZixpPXt9LGo9aS50b1N0cmluZyxrPWkuaGFzT3duUHJvcGVydHksbD17fSxtPVwiMi4yLjRcIixuPWZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBuLmZuLmluaXQoYSxiKX0sbz0vXltcXHNcXHVGRUZGXFx4QTBdK3xbXFxzXFx1RkVGRlxceEEwXSskL2cscD0vXi1tcy0vLHE9Ly0oW1xcZGEtel0pL2dpLHI9ZnVuY3Rpb24oYSxiKXtyZXR1cm4gYi50b1VwcGVyQ2FzZSgpfTtuLmZuPW4ucHJvdG90eXBlPXtqcXVlcnk6bSxjb25zdHJ1Y3RvcjpuLHNlbGVjdG9yOlwiXCIsbGVuZ3RoOjAsdG9BcnJheTpmdW5jdGlvbigpe3JldHVybiBlLmNhbGwodGhpcyl9LGdldDpmdW5jdGlvbihhKXtyZXR1cm4gbnVsbCE9YT8wPmE/dGhpc1thK3RoaXMubGVuZ3RoXTp0aGlzW2FdOmUuY2FsbCh0aGlzKX0scHVzaFN0YWNrOmZ1bmN0aW9uKGEpe3ZhciBiPW4ubWVyZ2UodGhpcy5jb25zdHJ1Y3RvcigpLGEpO3JldHVybiBiLnByZXZPYmplY3Q9dGhpcyxiLmNvbnRleHQ9dGhpcy5jb250ZXh0LGJ9LGVhY2g6ZnVuY3Rpb24oYSl7cmV0dXJuIG4uZWFjaCh0aGlzLGEpfSxtYXA6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMucHVzaFN0YWNrKG4ubWFwKHRoaXMsZnVuY3Rpb24oYixjKXtyZXR1cm4gYS5jYWxsKGIsYyxiKX0pKX0sc2xpY2U6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5wdXNoU3RhY2soZS5hcHBseSh0aGlzLGFyZ3VtZW50cykpfSxmaXJzdDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmVxKDApfSxsYXN0OmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZXEoLTEpfSxlcTpmdW5jdGlvbihhKXt2YXIgYj10aGlzLmxlbmd0aCxjPSthKygwPmE/YjowKTtyZXR1cm4gdGhpcy5wdXNoU3RhY2soYz49MCYmYj5jP1t0aGlzW2NdXTpbXSl9LGVuZDpmdW5jdGlvbigpe3JldHVybiB0aGlzLnByZXZPYmplY3R8fHRoaXMuY29uc3RydWN0b3IoKX0scHVzaDpnLHNvcnQ6Yy5zb3J0LHNwbGljZTpjLnNwbGljZX0sbi5leHRlbmQ9bi5mbi5leHRlbmQ9ZnVuY3Rpb24oKXt2YXIgYSxiLGMsZCxlLGYsZz1hcmd1bWVudHNbMF18fHt9LGg9MSxpPWFyZ3VtZW50cy5sZW5ndGgsaj0hMTtmb3IoXCJib29sZWFuXCI9PXR5cGVvZiBnJiYoaj1nLGc9YXJndW1lbnRzW2hdfHx7fSxoKyspLFwib2JqZWN0XCI9PXR5cGVvZiBnfHxuLmlzRnVuY3Rpb24oZyl8fChnPXt9KSxoPT09aSYmKGc9dGhpcyxoLS0pO2k+aDtoKyspaWYobnVsbCE9KGE9YXJndW1lbnRzW2hdKSlmb3IoYiBpbiBhKWM9Z1tiXSxkPWFbYl0sZyE9PWQmJihqJiZkJiYobi5pc1BsYWluT2JqZWN0KGQpfHwoZT1uLmlzQXJyYXkoZCkpKT8oZT8oZT0hMSxmPWMmJm4uaXNBcnJheShjKT9jOltdKTpmPWMmJm4uaXNQbGFpbk9iamVjdChjKT9jOnt9LGdbYl09bi5leHRlbmQoaixmLGQpKTp2b2lkIDAhPT1kJiYoZ1tiXT1kKSk7cmV0dXJuIGd9LG4uZXh0ZW5kKHtleHBhbmRvOlwialF1ZXJ5XCIrKG0rTWF0aC5yYW5kb20oKSkucmVwbGFjZSgvXFxEL2csXCJcIiksaXNSZWFkeTohMCxlcnJvcjpmdW5jdGlvbihhKXt0aHJvdyBuZXcgRXJyb3IoYSl9LG5vb3A6ZnVuY3Rpb24oKXt9LGlzRnVuY3Rpb246ZnVuY3Rpb24oYSl7cmV0dXJuXCJmdW5jdGlvblwiPT09bi50eXBlKGEpfSxpc0FycmF5OkFycmF5LmlzQXJyYXksaXNXaW5kb3c6ZnVuY3Rpb24oYSl7cmV0dXJuIG51bGwhPWEmJmE9PT1hLndpbmRvd30saXNOdW1lcmljOmZ1bmN0aW9uKGEpe3ZhciBiPWEmJmEudG9TdHJpbmcoKTtyZXR1cm4hbi5pc0FycmF5KGEpJiZiLXBhcnNlRmxvYXQoYikrMT49MH0saXNQbGFpbk9iamVjdDpmdW5jdGlvbihhKXt2YXIgYjtpZihcIm9iamVjdFwiIT09bi50eXBlKGEpfHxhLm5vZGVUeXBlfHxuLmlzV2luZG93KGEpKXJldHVybiExO2lmKGEuY29uc3RydWN0b3ImJiFrLmNhbGwoYSxcImNvbnN0cnVjdG9yXCIpJiYhay5jYWxsKGEuY29uc3RydWN0b3IucHJvdG90eXBlfHx7fS
7437xcImlzUHJvdG90eXBlT2ZcIikpcmV0dXJuITE7Zm9yKGIgaW4gYSk7cmV0dXJuIHZvaWQgMD09PWJ8fGsuY2FsbChhLGIpfSxpc0VtcHR5T2JqZWN0OmZ1bmN0aW9uKGEpe3ZhciBiO2ZvcihiIGluIGEpcmV0dXJuITE7cmV0dXJuITB9LHR5cGU6ZnVuY3Rpb24oYSl7cmV0dXJuIG51bGw9PWE/YStcIlwiOlwib2JqZWN0XCI9PXR5cGVvZiBhfHxcImZ1bmN0aW9uXCI9PXR5cGVvZiBhP2lbai5jYWxsKGEpXXx8XCJvYmplY3RcIjp0eXBlb2YgYX0sZ2xvYmFsRXZhbDpmdW5jdGlvbihhKXt2YXIgYixjPWV2YWw7YT1uLnRyaW0oYSksYSYmKDE9PT1hLmluZGV4T2YoXCJ1c2Ugc3RyaWN0XCIpPyhiPWQuY3JlYXRlRWxlbWVudChcInNjcmlwdFwiKSxiLnRleHQ9YSxkLmhlYWQuYXBwZW5kQ2hpbGQoYikucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChiKSk6YyhhKSl9LGNhbWVsQ2FzZTpmdW5jdGlvbihhKXtyZXR1cm4gYS5yZXBsYWNlKHAsXCJtcy1cIikucmVwbGFjZShxLHIpfSxub2RlTmFtZTpmdW5jdGlvbihhLGIpe3JldHVybiBhLm5vZGVOYW1lJiZhLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk9PT1iLnRvTG93ZXJDYXNlKCl9LGVhY2g6ZnVuY3Rpb24oYSxiKXt2YXIgYyxkPTA7aWYocyhhKSl7Zm9yKGM9YS5sZW5ndGg7Yz5kO2QrKylpZihiLmNhbGwoYVtkXSxkLGFbZF0pPT09ITEpYnJlYWt9ZWxzZSBmb3IoZCBpbiBhKWlmKGIuY2FsbChhW2RdLGQsYVtkXSk9PT0hMSlicmVhaztyZXR1cm4gYX0sdHJpbTpmdW5jdGlvbihhKXtyZXR1cm4gbnVsbD09YT9cIlwiOihhK1wiXCIpLnJlcGxhY2UobyxcIlwiKX0sbWFrZUFycmF5OmZ1bmN0aW9uKGEsYil7dmFyIGM9Ynx8W107cmV0dXJuIG51bGwhPWEmJihzKE9iamVjdChhKSk/bi5tZXJnZShjLFwic3RyaW5nXCI9PXR5cGVvZiBhP1thXTphKTpnLmNhbGwoYyxhKSksY30saW5BcnJheTpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIG51bGw9PWI/LTE6aC5jYWxsKGIsYSxjKX0sbWVyZ2U6ZnVuY3Rpb24oYSxiKXtmb3IodmFyIGM9K2IubGVuZ3RoLGQ9MCxlPWEubGVuZ3RoO2M+ZDtkKyspYVtlKytdPWJbZF07cmV0dXJuIGEubGVuZ3RoPWUsYX0sZ3JlcDpmdW5jdGlvbihhLGIsYyl7Zm9yKHZhciBkLGU9W10sZj0wLGc9YS5sZW5ndGgsaD0hYztnPmY7ZisrKWQ9IWIoYVtmXSxmKSxkIT09aCYmZS5wdXNoKGFbZl0pO3JldHVybiBlfSxtYXA6ZnVuY3Rpb24oYSxiLGMpe3ZhciBkLGUsZz0wLGg9W107aWYocyhhKSlmb3IoZD1hLmxlbmd0aDtkPmc7ZysrKWU9YihhW2ddLGcsYyksbnVsbCE9ZSYmaC5wdXNoKGUpO2Vsc2UgZm9yKGcgaW4gYSllPWIoYVtnXSxnLGMpLG51bGwhPWUmJmgucHVzaChlKTtyZXR1cm4gZi5hcHBseShbXSxoKX0sZ3VpZDoxLHByb3h5OmZ1bmN0aW9uKGEsYil7dmFyIGMsZCxmO3JldHVyblwic3RyaW5nXCI9PXR5cGVvZiBiJiYoYz1hW2JdLGI9YSxhPWMpLG4uaXNGdW5jdGlvbihhKT8oZD1lLmNhbGwoYXJndW1lbnRzLDIpLGY9ZnVuY3Rpb24oKXtyZXR1cm4gYS5hcHBseShifHx0aGlzLGQuY29uY2F0KGUuY2FsbChhcmd1bWVudHMpKSl9LGYuZ3VpZD1hLmd1aWQ9YS5ndWlkfHxuLmd1aWQrKyxmKTp2b2lkIDB9LG5vdzpEYXRlLm5vdyxzdXBwb3J0Omx9KSxcImZ1bmN0aW9uXCI9PXR5cGVvZiBTeW1ib2wmJihuLmZuW1N5bWJvbC5pdGVyYXRvcl09Y1tTeW1ib2wuaXRlcmF0b3JdKSxuLmVhY2goXCJCb29sZWFuIE51bWJlciBTdHJpbmcgRnVuY3Rpb24gQXJyYXkgRGF0ZSBSZWdFeHAgT2JqZWN0IEVycm9yIFN5bWJvbFwiLnNwbGl0KFwiIFwiKSxmdW5jdGlvbihhLGIpe2lbXCJbb2JqZWN0IFwiK2IrXCJdXCJdPWIudG9Mb3dlckNhc2UoKX0pO2Z1bmN0aW9uIHMoYSl7dmFyIGI9ISFhJiZcImxlbmd0aFwiaW4gYSYmYS5sZW5ndGgsYz1uLnR5cGUoYSk7cmV0dXJuXCJmdW5jdGlvblwiPT09Y3x8bi5pc1dpbmRvdyhhKT8hMTpcImFycmF5XCI9PT1jfHwwPT09Ynx8XCJudW1iZXJcIj09dHlwZW9mIGImJmI+MCYmYi0xIGluIGF9dmFyIHQ9ZnVuY3Rpb24oYSl7dmFyIGIsYyxkLGUsZixnLGgsaSxqLGssbCxtLG4sbyxwLHEscixzLHQsdT1cInNpenpsZVwiKzEqbmV3IERhdGUsdj1hLmRvY3VtZW50LHc9MCx4PTAseT1nYSgpLHo9Z2EoKSxBPWdhKCksQj1mdW5jdGlvbihhLGIpe3JldHVybiBhPT09YiYmKGw9ITApLDB9LEM9MTw8MzEsRD17fS5oYXNPd25Qcm9wZXJ0eSxFPVtdLEY9RS5wb3AsRz1FLnB1c2gsSD1FLnB1c2gsST1FLnNsaWNlLEo9ZnVuY3Rpb24oYSxiKXtmb3IodmFyIGM9MCxkPWEubGVuZ3RoO2Q+YztjKyspaWYoYVtjXT09PWIpcmV0dXJuIGM7cmV0dXJuLTF9LEs9XCJjaGVja2VkfHNlbGVjdGVkfGFzeW5jfGF1dG9mb2N1c3xhdXRvcGxheXxjb250cm9sc3xkZWZlcnxkaXNhYmxlZHxoaWRkZW58aXNtYXB8bG9vcHxtdWx0aXBsZXxvcGVufHJlYWRvbmx5fHJlcXVpcmVkfHNjb3BlZFwiLEw9XCJbXFxcXHgyMFxcXFx0XFxcXHJcXFxcblxcXFxmXVwiLE09XCIoPzpcXFxcXFxcXC58W1xcXFx3LV18W15cXFxceDAwLVxcXFx4YTBdKStcIixOPVwiXFxcXFtcIitMK1wiKihcIitNK1wiKSg/OlwiK0wrXCIqKFsqXiR8IX5dPz0pXCIrTCtcIiooPzonKCg/OlxcXFxcXFxcLnxbXlxcXFxcXFxcJ10pKiknfFxcXCIoKD86XFxcXFxcXFwufFteXFxcXFxcXFxcXFwiXSkqKVxcXCJ8KFwiK00rXCIpKXwpXCIrTCtcIipcXFxcXVwiLE89XCI6KFwiK00rXCIpKD86XFxcXCgoKCcoKD86XFxcXFxcXFwufFteXFxcXFxcXFwnXSkqKSd8XFxcIigoPzpcXFxcXFxcXC58W15cXFxcXFxcXFxcXCJdKSopXFxcIil8KCg/OlxcXFxcXFxcLnxbXlxcXFxcXFxcKClbXFxcXF1dfFwiK04rXCIpKil8LiopXFxcXCl8KVwiLFA9bmV3IFJlZ0V4cChMK1wiK1wiLFwiZ1wiKSxRPW5ldyBSZWdFeHAoXCJeXCIrTCtcIit8KCg/Ol58W15cXFxcXFxcXF0pKD86XFxcXFxcXFwuKSopXCIrTCtcIiskXCIsXCJnXCIpLFI9bmV3IFJlZ0V4cChcIl5cIitMK1wiKixcIitMK1wiKlwiKSxTPW5ldyBSZWdFeHAoXCJeXCIrTCtcIiooWz4rfl18XCIrTCtcIilcIitMK1wiKlwiKSxUPW5ldyBSZWdFeHAoXCI9XCIrTCtcIiooW15cXFxcXSdcXFwiXSo/KVwiK0wrXCIqXFxcXF1cIixcImdcIiksVT1uZXcgUmVnRXhwKE8pLFY9bmV3IFJlZ0V4cChcIl5cIitNK1wiJFwiKSxXPXtJRDpuZXcgUmVnRXhwKFwiXiMoXCIrTStcIilcIiksQ0xBU1M6bmV3IFJlZ0V4cChcIl5cXFxcLihcIitNK1wiKVwiKSxUQUc6bmV3IFJlZ0V4cChcIl4oXCIrTStcInxbKl0pXCIpLEFUVFI6bmV3IFJlZ0V4cChcIl5cIitOKSxQU0VVRE86bmV3IFJlZ0V4cChcIl5cIitPKSxDSElMRDpuZXcgUmVnRXhwKFwiXjoob25seXxmaXJzdHxsYXN0fG50aHxudGgtbGFzdCktKGNoaWxkfG9mLXR5cGUpKD86XFxcXChcIitMK1wiKihldmVufG9kZHwoKFsrLV18KShcXFxcZCopbnwpXCIrTCtcIiooPzooWystXXwpXCIrTCtcIiooXFxcXGQrKXwpKVwiK0wrXCIqXFxcXCl8KVwiLFwiaVwiKSxib29sOm5ldyBSZWdFeHAoXCJeKD86XCIrSytcIikkXCIsXCJpXCIpLG5lZWRzQ29udGV4dDpuZXcgUmVnRXhwKFwiXl
7437wiK0wrXCIqWz4rfl18OihldmVufG9kZHxlcXxndHxsdHxudGh8Zmlyc3R8bGFzdCkoPzpcXFxcKFwiK0wrXCIqKCg/Oi1cXFxcZCk/XFxcXGQqKVwiK0wrXCIqXFxcXCl8KSg/PVteLV18JClcIixcImlcIil9LFg9L14oPzppbnB1dHxzZWxlY3R8dGV4dGFyZWF8YnV0dG9uKSQvaSxZPS9eaFxcZCQvaSxaPS9eW157XStcXHtcXHMqXFxbbmF0aXZlIFxcdy8sJD0vXig/OiMoW1xcdy1dKyl8KFxcdyspfFxcLihbXFx3LV0rKSkkLyxfPS9bK35dLyxhYT0vJ3xcXFxcL2csYmE9bmV3IFJlZ0V4cChcIlxcXFxcXFxcKFtcXFxcZGEtZl17MSw2fVwiK0wrXCI/fChcIitMK1wiKXwuKVwiLFwiaWdcIiksY2E9ZnVuY3Rpb24oYSxiLGMpe3ZhciBkPVwiMHhcIitiLTY1NTM2O3JldHVybiBkIT09ZHx8Yz9iOjA+ZD9TdHJpbmcuZnJvbUNoYXJDb2RlKGQrNjU1MzYpOlN0cmluZy5mcm9tQ2hhckNvZGUoZD4+MTB8NTUyOTYsMTAyMyZkfDU2MzIwKX0sZGE9ZnVuY3Rpb24oKXttKCl9O3RyeXtILmFwcGx5KEU9SS5jYWxsKHYuY2hpbGROb2Rlcyksdi5jaGlsZE5vZGVzKSxFW3YuY2hpbGROb2Rlcy5sZW5ndGhdLm5vZGVUeXBlfWNhdGNoKGVhKXtIPXthcHBseTpFLmxlbmd0aD9mdW5jdGlvbihhLGIpe0cuYXBwbHkoYSxJLmNhbGwoYikpfTpmdW5jdGlvbihhLGIpe3ZhciBjPWEubGVuZ3RoLGQ9MDt3aGlsZShhW2MrK109YltkKytdKTthLmxlbmd0aD1jLTF9fX1mdW5jdGlvbiBmYShhLGIsZCxlKXt2YXIgZixoLGosayxsLG8scixzLHc9YiYmYi5vd25lckRvY3VtZW50LHg9Yj9iLm5vZGVUeXBlOjk7aWYoZD1kfHxbXSxcInN0cmluZ1wiIT10eXBlb2YgYXx8IWF8fDEhPT14JiY5IT09eCYmMTEhPT14KXJldHVybiBkO2lmKCFlJiYoKGI/Yi5vd25lckRvY3VtZW50fHxiOnYpIT09biYmbShiKSxiPWJ8fG4scCkpe2lmKDExIT09eCYmKG89JC5leGVjKGEpKSlpZihmPW9bMV0pe2lmKDk9PT14KXtpZighKGo9Yi5nZXRFbGVtZW50QnlJZChmKSkpcmV0dXJuIGQ7aWYoai5pZD09PWYpcmV0dXJuIGQucHVzaChqKSxkfWVsc2UgaWYodyYmKGo9dy5nZXRFbGVtZW50QnlJZChmKSkmJnQoYixqKSYmai5pZD09PWYpcmV0dXJuIGQucHVzaChqKSxkfWVsc2V7aWYob1syXSlyZXR1cm4gSC5hcHBseShkLGIuZ2V0RWxlbWVudHNCeVRhZ05hbWUoYSkpLGQ7aWYoKGY9b1szXSkmJmMuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSYmYi5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKXJldHVybi
7437BILmFwcGx5KGQsYi5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKGYpKSxkfWlmKGMucXNhJiYhQVthK1wiIFwiXSYmKCFxfHwhcS50ZXN0KGEpKSl7aWYoMSE9PXgpdz1iLHM9YTtlbHNlIGlmKFwib2JqZWN0XCIhPT1iLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkpeyhrPWIuZ2V0QXR0cmlidXRlKFwiaWRcIikpP2s9ay5yZXBsYWNlKGFhLFwiXFxcXCQmXCIpOmIuc2V0QXR0cmlidXRlKFwiaWRcIixrPXUpLHI9ZyhhKSxoPXIubGVuZ3RoLGw9Vi50ZXN0KGspP1wiI1wiK2s6XCJbaWQ9J1wiK2srXCInXVwiO3doaWxlKGgtLSlyW2hdPWwrXCIgXCIrcWEocltoXSk7cz1yLmpvaW4oXCIsXCIpLHc9Xy50ZXN0KGEpJiZvYShiLnBhcmVudE5vZGUpfHxifWlmKHMpdHJ5e3JldHVybiBILmFwcGx5KGQsdy5xdWVyeVNlbGVjdG9yQWxsKHMpKSxkfWNhdGNoKHkpe31maW5hbGx5e2s9PT11JiZiLnJlbW92ZUF0dHJpYnV0ZShcImlkXCIpfX19cmV0dXJuIGkoYS5yZXBsYWNlKFEsXCIkMVwiKSxiLGQsZSl9ZnVuY3Rpb24gZ2EoKXt2YXIgYT1bXTtmdW5jdGlvbiBiKGMsZSl7cmV0dXJuIGEucHVzaChjK1wiIFwiKT5kLmNhY2hlTGVuZ3RoJiZkZWxldGUgYlthLnNoaWZ0KCldLGJbYytcIiBcIl09ZX1yZXR1cm4gYn1mdW5jdGlvbiBoYShhKXtyZXR1cm4gYVt1XT0hMCxhfWZ1bmN0aW9uIGlhKGEpe3ZhciBiPW4uY3JlYXRlRWxlbWVudChcImRpdlwiKTt0cnl7cmV0dXJuISFhKGIpfWNhdGNoKGMpe3JldHVybiExfWZpbmFsbHl7Yi5wYXJlbnROb2RlJiZiLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoYiksYj1udWxsfX1mdW5jdGlvbiBqYShhLGIpe3ZhciBjPWEuc3BsaXQoXCJ8XCIpLGU9Yy5sZW5ndGg7d2hpbGUoZS0tKWQuYXR0ckhhbmRsZVtjW2VdXT1ifWZ1bmN0aW9uIGthKGEsYil7dmFyIGM9YiYmYSxkPWMmJjE9PT1hLm5vZGVUeXBlJiYxPT09Yi5ub2RlVHlwZSYmKH5iLnNvdXJjZUluZGV4fHxDKS0ofmEuc291cmNlSW5kZXh8fEMpO2lmKGQpcmV0dXJuIGQ7aWYoYyl3aGlsZShjPWMubmV4dFNpYmxpbmcpaWYoYz09PWIpcmV0dXJuLTE7cmV0dXJuIGE/MTotMX1mdW5jdGlvbiBsYShhKXtyZXR1cm4gZnVuY3Rpb24oYil7dmFyIGM9Yi5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO3JldHVyblwiaW5wdXRcIj09PWMmJmIudHlwZT09PWF9fWZ1bmN0aW9uIG1hKGEpe3JldHVybiBmdW5jdGlvbihiKXt2YXIgYz1iLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7cmV0dXJuKFwiaW5wdXRcIj09PWN8fFwiYnV0dG9uXCI9PT1jKSYmYi50eXBlPT09YX19ZnVuY3Rpb24gbmEoYSl7cmV0dXJuIGhhKGZ1bmN0aW9uKGIpe3JldHVybiBiPStiLGhhKGZ1bmN0aW9uKGMsZCl7dmFyIGUsZj1hKFtdLGMubGVuZ3RoLGIpLGc9Zi5sZW5ndGg7d2hpbGUoZy0tKWNbZT1mW2ddXSYmKGNbZV09IShkW2VdPWNbZV0pKX0pfSl9ZnVuY3Rpb24gb2EoYSl7cmV0dXJuIGEmJlwidW5kZWZpbmVkXCIhPXR5cGVvZiBhLmdldEVsZW1lbnRzQnlUYWdOYW1lJiZhfWM9ZmEuc3VwcG9ydD17fSxmPWZhLmlzWE1MPWZ1bmN0aW9uKGEpe3ZhciBiPWEmJihhLm93bmVyRG9jdW1lbnR8fGEpLmRvY3VtZW50RWxlbWVudDtyZXR1cm4gYj9cIkhUTUxcIiE9PWIubm9kZU5hbWU6ITF9LG09ZmEuc2V0RG9jdW1lbnQ9ZnVuY3Rpb24oYSl7dmFyIGIsZSxnPWE/YS5vd25lckRvY3VtZW50fHxhOnY7cmV0dXJuIGchPT1uJiY5PT09Zy5ub2RlVHlwZSYmZy5kb2N1bWVudEVsZW1lbnQ/KG49ZyxvPW4uZG9jdW1lbnRFbGVtZW50LHA9IWYobiksKGU9bi5kZWZhdWx0VmlldykmJmUudG9wIT09ZSYmKGUuYWRkRXZlbnRMaXN0ZW5lcj9lLmFkZEV2ZW50TGlzdGVuZXIoXCJ1bmxvYWRcIixkYSwhMSk6ZS5hdHRhY2hFdmVudCYmZS5hdHRhY2hFdmVudChcIm9udW5sb2FkXCIsZGEpKSxjLmF0dHJpYnV0ZXM9aWEoZnVuY3Rpb24oYSl7cmV0dXJuIGEuY2xhc3NOYW1lPVwiaVwiLCFhLmdldEF0dHJpYnV0ZShcImNsYXNzTmFtZVwiKX0pLGMuZ2V0RWxlbWVudHNCeVRhZ05hbWU9aWEoZnVuY3Rpb24oYSl7cmV0dXJuIGEuYXBwZW5kQ2hpbGQobi5jcmVhdGVDb21tZW50KFwiXCIpKSwhYS5nZXRFbGVtZW50c0J5VGFnTmFtZShcIipcIikubGVuZ3RofSksYy5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lPVoudGVzdChuLmdldEVsZW1lbnRzQnlDbGFzc05hbWUpLGMuZ2V0QnlJZD1pYShmdW5jdGlvbihhKXtyZXR1cm4gby5hcHBlbmRDaGlsZChhKS5pZD11LCFuLmdldEVsZW1lbnRzQnlOYW1lfHwhbi5nZXRFbGVtZW50c0J5TmFtZSh1KS5sZW5ndGh9KSxjLmdldEJ5SWQ/KGQuZmluZC5JRD1mdW5jdGlvbihhLGIpe2lmKFwidW5kZWZpbmVkXCIhPXR5cGVvZiBiLmdldEVsZW1lbnRCeUlkJiZwKXt2YXIgYz1iLmdldEVsZW1lbnRCeUlkKGEpO3JldHVybiBjP1tjXTpbXX19LGQuZmlsdGVyLklEPWZ1bmN0aW9uKGEpe3ZhciBiPWEucmVwbGFjZShiYSxjYSk7cmV0dXJuIGZ1bmN0aW9uKGEpe3JldHVybiBhLmdldEF0dHJpYnV0ZShcImlkXCIpPT09Yn19KTooZGVsZXRlIGQuZmluZC5JRCxkLmZpbHRlci5JRD1mdW5jdGlvbihhKXt2YXIgYj1hLnJlcGxhY2UoYmEsY2EpO3JldHVybiBmdW5jdGlvbihhKXt2YXIgYz1cInVuZGVmaW5lZFwiIT10eXBlb2YgYS5nZXRBdHRyaWJ1dGVOb2RlJiZhLmdldEF0dHJpYnV0ZU5vZGUoXCJpZFwiKTtyZXR1cm4gYyYmYy52YWx1ZT09PWJ9fSksZC5maW5kLlRBRz1jLmdldEVsZW1lbnRzQnlUYWdOYW1lP2Z1bmN0aW9uKGEsYil7cmV0dXJuXCJ1bmRlZmluZWRcIiE9dHlwZW9mIGIuZ2V0RWxlbWVudHNCeVRhZ05hbWU/Yi5nZXRFbGVtZW50c0J5VGFnTmFtZShhKTpjLnFzYT9iLnF1ZXJ5U2VsZWN0b3JBbGwoYSk6dm9pZCAwfTpmdW5jdGlvbihhLGIpe3ZhciBjLGQ9W10sZT0wLGY9Yi5nZXRFbGVtZW50c0J5VGFnTmFtZShhKTtpZihcIipcIj09PWEpe3doaWxlKGM9ZltlKytdKTE9PT1jLm5vZGVUeXBlJiZkLnB1c2goYyk7cmV0dXJuIGR9cmV0dXJuIGZ9LGQuZmluZC5DTEFTUz1jLmdldEVsZW1lbnRzQnlDbGFzc05hbWUmJmZ1bmN0aW9uKGEsYil7cmV0dXJuXCJ1bmRlZmluZWRcIiE9dHlwZW9mIGIuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSYmcD9
7437iLmdldEVsZW1lbnRzQnlDbGFzc05hbWUoYSk6dm9pZCAwfSxyPVtdLHE9W10sKGMucXNhPVoudGVzdChuLnF1ZXJ5U2VsZWN0b3JBbGwpKSYmKGlhKGZ1bmN0aW9uKGEpe28uYXBwZW5kQ2hpbGQoYSkuaW5uZXJIVE1MPVwiPGEgaWQ9J1wiK3UrXCInPjwvYT48c2VsZWN0IGlkPSdcIit1K1wiLVxcclxcXFwnIG1zYWxsb3djYXB0dXJlPScnPjxvcHRpb24gc2VsZWN0ZWQ9Jyc+PC9vcHRpb24+PC9zZWxlY3Q+XCIsYS5xdWVyeVNlbGVjdG9yQWxsKFwiW21zYWxsb3djYXB0dXJlXj0nJ11cIikubGVuZ3RoJiZxLnB1c2goXCJbKl4kXT1cIitMK1wiKig/OicnfFxcXCJcXFwiKVwiKSxhLnF1ZXJ5U2VsZWN0b3JBbGwoXCJbc2VsZWN0ZWRdXCIpLmxlbmd0aHx8cS5wdXNoKFwiXFxcXFtcIitMK1wiKig/OnZhbHVlfFwiK0srXCIpXCIpLGEucXVlcnlTZWxlY3RvckFsbChcIltpZH49XCIrdStcIi1dXCIpLmxlbmd0aHx8cS5wdXNoKFwifj1cIiksYS5xdWVyeVNlbGVjdG9yQWxsKFwiOmNoZWNrZWRcIikubGVuZ3RofHxxLnB1c2goXCI6Y2hlY2tlZFwiKSxhLnF1ZXJ5U2VsZWN0b3JBbGwoXCJhI1wiK3UrXCIrKlwiKS5sZW5ndGh8fHEucHVzaChcIi4jLitbK35dXCIpfSksaWEoZnVuY3Rpb24oYSl7dmFyIGI9bi5jcmVhdGVFbGVtZW50KFwiaW5wdXRcIik7Yi5zZXRBdHRyaWJ1dGUoXCJ0eXBlXCIsXCJoaWRkZW5cIiksYS5hcHBlbmRDaGlsZChiKS5zZXRBdHRyaWJ1dGUoXCJuYW1lXCIsXCJEXCIpLGEucXVlcnlTZWxlY3RvckFsbChcIltuYW1lPWRdXCIpLmxlbmd0aCYmcS5wdXNoKFwibmFtZVwiK0wrXCIqWypeJHwhfl0/PVwiKSxhLnF1ZXJ5U2VsZWN0b3JBbGwoXCI6ZW5hYmxlZFwiKS5sZW5ndGh8fHEucHVzaChcIjplbmFibGVkXCIsXCI6ZGlzYWJsZWRcIiksYS5xdWVyeVNlbGVjdG9yQWxsKFwiKiw6eFwiKSxxLnB1c2goXCIsLio6XCIpfSkpLChjLm1hdGNoZXNTZWxlY3Rvcj1aLnRlc3Qocz1vLm1hdGNoZXN8fG8ud2Via2l0TWF0Y2hlc1NlbGVjdG9yfHxvLm1vek1hdGNoZXNTZWxlY3Rvcnx8by5vTWF0Y2hlc1NlbGVjdG9yfHxvLm1zTWF0Y2hlc1NlbGVjdG9yKSkmJmlhKGZ1bmN0aW9uKGEpe2MuZGlzY29ubmVjdGVkTWF0Y2g9cy5jYWxsKGEsXCJkaXZcIikscy5jYWxsKGEsXCJbcyE9JyddOnhcIiksci5wdXNoKFwiIT1cIixPKX0pLHE9cS5sZW5ndGgmJm5ldyBSZWdFeHAocS5qb2luKFwifFwiKSkscj1yLmxlbmd0aCYmbmV3IFJlZ0V4cChyLmpvaW4oXCJ8XCIpKSxiPVoudGVzdChvLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKSx0PWJ8fFoudGVzdChvLmNvbnRhaW5zKT9mdW5jdGlvbihhLGIpe3ZhciBjPTk9PT1hLm5vZGVUeXBlP2EuZG9jdW1lbnRFbGVtZW50OmEsZD1iJiZiLnBhcmVudE5vZGU7cmV0dXJuIGE9PT1kfHwhKCFkfHwxIT09ZC5ub2RlVHlwZXx8IShjLmNvbnRhaW5zP2MuY29udGFpbnMoZCk6YS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbiYmMTYmYS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbihkKSkpfTpmdW5jdGlvbihhLGIpe2lmKGIpd2hpbGUoYj1iLnBhcmVudE5vZGUpaWYoYj09PWEpcmV0dXJuITA7cmV0dXJuITF9LEI9Yj9mdW5jdGlvbihhLGIpe2lmKGE9PT1iKXJldHVybiBsPSEwLDA7dmFyIGQ9IWEuY29tcGFyZURvY3VtZW50UG9zaXRpb24tIWIuY29tcGFyZURvY3VtZW50UG9zaXRpb247cmV0dXJuIGQ/ZDooZD0oYS5vd25lckRvY3VtZW50fHxhKT09PShiLm93bmVyRG9jdW1lbnR8fGIpP2EuY29tcGFyZURvY3VtZW50UG9zaXRpb24oYik6MSwxJmR8fCFjLnNvcnREZXRhY2hlZCYmYi5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbihhKT09PWQ/YT09PW58fGEub3duZXJEb2N1bWVudD09PXYmJnQodixhKT8tMTpiPT09bnx8Yi5vd25lckRvY3VtZW50PT09diYmdCh2LGIpPzE6az9KKGssYSktSihrLGIpOjA6NCZkPy0xOjEpfTpmdW5jdGlvbihhLGIpe2lmKGE9PT1iKXJldHVybiBsPSEwLDA7dmFyIGMsZD0wLGU9YS5wYXJlbnROb2RlLGY9Yi5wYXJlbnROb2RlLGc9W2FdLGg9W2JdO2lmKCFlfHwhZilyZXR1cm4gYT09PW4/LTE6Yj09PW4/MTplPy0xOmY/MTprP0ooayxhKS1KKGssYik6MDtpZihlPT09ZilyZXR1cm4ga2EoYSxiKTtjPWE7d2hpbGUoYz1jLnBhcmVudE5vZGUpZy51bnNoaWZ0KGMpO2M9Yjt3aGlsZShjPWMucGFyZW50Tm9kZSloLnVuc2hpZnQoYyk7d2hpbGUoZ1tkXT09PWhbZF0pZCsrO3JldHVybiBkP2thKGdbZF0saFtkXSk6Z1tkXT09PXY/LTE6aFtkXT09PXY/MTowfSxuKTpufSxmYS5tYXRjaGVzPWZ1bmN0aW9uKGEsYil7cmV0dXJuIGZhKGEsbnVsbCxudWxsLGIpfSxmYS5tYXRjaGVzU2VsZWN0b3I9ZnVuY3Rpb24oYSxiKXtpZigoYS5vd25lckRvY3VtZW50fHxhKSE9PW4mJm0oYSksYj1iLnJlcGxhY2UoVCxcIj0nJDEnXVwiKSxjLm1hdGNoZXNTZWxlY3RvciYmcCYmIUFbYitcIiBcIl0mJighcnx8IXIudGVzdChiKSkmJighcXx8IXEudGVzdChiKSkpdHJ5e3ZhciBkPXMuY2FsbChhLGIpO2lmKGR8fGMuZGlzY29ubmVjdGVkTWF0Y2h8fGEuZG9jdW1lbnQmJjExIT09YS5kb2N1bWVudC5ub2RlVHlwZSlyZXR1cm4gZH1jYXRjaChlKXt9cmV0dXJuIGZhKGIsbixudWxsLFthXSkubGVuZ3RoPjB9LGZhLmNvbnRhaW5zPWZ1bmN0aW9uKGEsYil7cmV0dXJuKGEub3duZXJEb2N1bWVudHx8YSkhPT1uJiZtKGEpLHQoYSxiKX0sZmEuYXR0cj1mdW5jdGlvbihhLGIpeyhhLm93bmVyRG9jdW1lbnR8fGEpIT09biYmbShhKTt2YXIgZT1kLmF0dHJIYW5kbGVbYi50b0xvd2VyQ2FzZSgpXSxmPWUmJkQuY2FsbChkLmF0dHJIYW5kbGUsYi50b0xvd2VyQ2FzZSgpKT9lKGEsYiwhcCk6dm9pZCAwO3JldHVybiB2b2lkIDAhPT1mP2Y6Yy5hdHRyaWJ1dGVzfHwhcD9hLmdldEF0dHJpYnV0ZShiKTooZj1hLmdldEF0dHJpYnV0ZU5vZGUoYikpJiZmLnNwZWNpZmllZD9mLnZhbHVlOm51bGx9LGZhLmVycm9yPWZ1bmN0aW9uKGEpe3Rocm93IG5ldyBFcnJvcihcIlN5bnRheCBlcnJvciwgdW5yZWNvZ25pemVkIGV4cHJlc3Npb246IFwiK2EpfSxmYS51bmlxdWVTb3J0PWZ1bmN0aW9uKGEpe3ZhciBiLGQ9W10sZT0wLGY9MDtpZihsPSFjLmRldGVjdER1cGxpY2F0ZXMsaz0hYy5zb3J0U3RhYmxlJiZhLnNsaWNlKDApLGEuc29ydChCKSxsKXt3aGlsZShiPWFbZisrXSliPT09YVtmXSYmKGU9ZC5wdXNoKGYpKTt3aGlsZShlLS0pYS5zcGxpY2UoZFtlXSwxKX1yZXR1cm4gaz1udWxsLGF9LGU9ZmEuZ2V0VGV4dD1mdW5jdGlvbihhKXt2YXIgYixjPVwiXCIsZD0wLGY9YS5ub2RlVHlwZTtpZihmKXtpZigxPT09Znx8OT09PWZ8fDExPT09Zil7aWYoXCJzdHJpbmdcIj09dHlwZW9mIGEudGV4dENvbnRlbnQpcmV0dXJuIGEudGV4dENvbnRlbnQ7Zm9yKGE9YS5maXJzdENoaWxkO2E7YT1hLm5leHRTaWJsaW5nKWMrPWUoYSl9ZWxzZSBpZigzPT09Znx8ND09PWYpcmV0dXJuIGEubm9kZVZhbHVlfWVsc2Ugd2h
7437pbGUoYj1hW2QrK10pYys9ZShiKTtyZXR1cm4gY30sZD1mYS5zZWxlY3RvcnM9e2NhY2hlTGVuZ3RoOjUwLGNyZWF0ZVBzZXVkbzpoYSxtYXRjaDpXLGF0dHJIYW5kbGU6e30sZmluZDp7fSxyZWxhdGl2ZTp7XCI+XCI6e2RpcjpcInBhcmVudE5vZGVcIixmaXJzdDohMH0sXCIgXCI6e2RpcjpcInBhcmVudE5vZGVcIn0sXCIrXCI6e2RpcjpcInByZXZpb3VzU2libGluZ1wiLGZpcnN0OiEwfSxcIn5cIjp7ZGlyOlwicHJldmlvdXNTaWJsaW5nXCJ9fSxwcmVGaWx0ZXI6e0FUVFI6ZnVuY3Rpb24oYSl7cmV0dXJuIGFbMV09YVsxXS5yZXBsYWNlKGJhLGNhKSxhWzNdPShhWzNdfHxhWzRdfHxhWzVdfHxcIlwiKS5yZXBsYWNlKGJhLGNhKSxcIn49XCI9PT1hWzJdJiYoYVszXT1cIiBcIithWzNdK1wiIFwiKSxhLnNsaWNlKDAsNCl9LENISUxEOmZ1bmN0aW9uKGEpe3JldHVybiBhWzFdPWFbMV0udG9Mb3dlckNhc2UoKSxcIm50aFwiPT09YVsxXS5zbGljZSgwLDMpPyhhWzNdfHxmYS5lcnJvcihhWzBdKSxhWzRdPSsoYVs0XT9hWzVdKyhhWzZdfHwxKToyKihcImV2ZW5cIj09PWFbM118fFwib2RkXCI9PT1hWzNdKSksYVs1XT0rKGFbN10rYVs4XXx8XCJvZGRcIj09PWFbM10pKTphWzNdJiZmYS5lcnJvcihhWzBdKSxhfSxQU0VVRE86ZnVuY3Rpb24oYSl7dmFyIGIsYz0hYVs2XSYmYVsyXTtyZXR1cm4gVy5DSElMRC50ZXN0KGFbMF0pP251bGw6KGFbM10/YVsyXT1hWzRdfHxhWzVdfHxcIlwiOmMmJlUudGVzdChjKSYmKGI9ZyhjLCEwKSkmJihiPWMuaW5kZXhPZihcIilcIixjLmxlbmd0aC1iKS1jLmxlbmd0aCkmJihhWzBdPWFbMF0uc2xpY2UoMCxiKSxhWzJdPWMuc2xpY2UoMCxiKSksYS5zbGljZSgwLDMpKX19LGZpbHRlcjp7VEFHOmZ1bmN0aW9uKGEpe3ZhciBiPWEucmVwbGFjZShiYSxjYSkudG9Mb3dlckNhc2UoKTtyZXR1cm5cIipcIj09PWE/ZnVuY3Rpb24oKXtyZXR1cm4hMH06ZnVuY3Rpb24oYSl7cmV0dXJuIGEubm9kZU5hbWUmJmEubm9kZU5hbWUudG9Mb3dlckNhc2UoKT09PWJ9fSxDTEFTUzpmdW5jdGlvbihhKXt2YXIgYj15W2ErXCIgXCJdO3JldHVybiBifHwoYj1uZXcgUmVnRXhwKFwiKF58XCIrTCtcIilcIithK1wiKFwiK0wrXCJ8JClcIikpJiZ5KGEsZnVuY3Rpb24oYSl7cmV0dXJuIGIudGVzdChcInN0cmluZ1wiPT10eXBlb2YgYS5jbGFzc05hbWUmJmEuY2xhc3NOYW1lfHxcInVuZGVmaW5lZFwiIT10eXBlb2YgYS5nZXRBdHRyaWJ1dGUmJmEuZ2V0QXR0cmlidXRlKFwiY2xhc3NcIil8fFwiXCIpfSl9LEFUVFI6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBmdW5jdGlvbihkKXt2YXIgZT1mYS5hdHRyKGQsYSk7cmV0dXJuIG51bGw9PWU/XCIhPVwiPT09YjpiPyhlKz1cIlwiLFwiPVwiPT09Yj9lPT09YzpcIiE9XCI9PT1iP2UhPT1jOlwiXj1cIj09PWI/YyYmMD09PWUuaW5kZXhPZihjKTpcIio9XCI9PT1iP2MmJmUuaW5kZXhPZihjKT4tMTpcIiQ9XCI9PT1iP2MmJmUuc2xpY2UoLWMubGVuZ3RoKT09PWM6XCJ+PVwiPT09Yj8oXCIgXCIrZS5yZXBsYWNlKFAsXCIgXCIpK1wiIFwiKS5pbmRleE9mKGMpPi0xOlwifD1cIj09PWI/ZT09PWN8fGUuc2xpY2UoMCxjLmxlbmd0aCsxKT09PWMrXCItXCI6ITEpOiEwfX0sQ0hJTEQ6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgZj1cIm50aFwiIT09YS5zbGljZSgwLDMpLGc9XCJsYXN0XCIhPT1hLnNsaWNlKC00KSxoPVwib2YtdHlwZVwiPT09YjtyZXR1cm4gMT09PWQmJjA9PT1lP2Z1bmN0aW9uKGEpe3JldHVybiEhYS5wYXJlbnROb2RlfTpmdW5jdGlvbihiLGMsaSl7dmFyIGosayxsLG0sbixvLHA9ZiE9PWc/XCJuZXh0U2libGluZ1wiOlwicHJldmlvdXNTaWJsaW5nXCIscT1iLnBhcmVudE5vZGUscj1oJiZiLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkscz0haSYmIWgsdD0hMTtpZihxKXtpZihmKXt3aGlsZShwKXttPWI7d2hpbGUobT1tW3BdKWlmKGg/bS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpPT09cjoxPT09bS5ub2RlVHlwZSlyZXR1cm4hMTtvPXA9XCJvbmx5XCI9PT1hJiYhbyYmXCJuZXh0U2libGluZ1wifXJldHVybiEwfWlmKG89W2c/cS5maXJzdENoaWxkOnEubGFzdENoaWxkXSxnJiZzKXttPXEsbD1tW3VdfHwobVt1XT17fSksaz1sW20udW5pcXVlSURdfHwobFttLnVuaXF1ZUlEXT17fSksaj1rW2FdfHxbXSxuPWpbMF09PT13JiZqWzFdLHQ9biYmalsyXSxtPW4mJnEuY2hpbGROb2Rlc1tuXTt3aGlsZShtPSsrbiYmbSYmbVtwXXx8KHQ9bj0wKXx8by5wb3AoKSlpZigxPT09bS5ub2RlVHlwZSYmKyt0JiZtPT09Yil7a1thXT1bdyxuLHRdO2JyZWFrfX1lbHNlIGlmKHMmJihtPWIsbD1tW3VdfHwobVt1XT17fSksaz1sW20udW5pcXVlSURdfHwobFttLnVuaXF1ZUlEXT17fSksaj1rW2FdfHxbXSxuPWpbMF09PT13JiZqWzFdLHQ9biksdD09PSExKXdoaWxlKG09KytuJiZtJiZtW3BdfHwodD1uPTApfHxvLnBvcCgpKWlmKChoP20ubm9kZU5hbWUudG9Mb3dlckNhc2UoKT09PXI6MT09PW0ubm9kZVR5cGUpJiYrK3QmJihzJiYobD1tW3VdfHwobVt1XT17fSksaz1sW20udW5pcXVlSURdfHwobFttLnVuaXF1ZUlEXT17fSksa1thXT1bdyx0XSksbT09PWIpKWJyZWFrO3JldHVybiB0LT1lLHQ9PT1kfHx0JWQ9PT0wJiZ0L2Q+PTB9fX0sUFNFVURPOmZ1bmN0aW9uKGEsYil7dmFyIGMsZT1kLnBzZXVkb3NbYV18fGQuc2V0RmlsdGVyc1thLnRvTG93ZXJDYXNlKCldfHxmYS5lcnJvcihcInVuc3VwcG9ydGVkIHBzZXVkbzogXCIrYSk7cmV0dXJuIGVbdV0/ZShiKTplLmxlbmd0aD4xPyhjPVthLGEsXCJcIixiXSxkLnNldEZpbHRlcnMuaGFzT3duUHJvcGVydHkoYS50b0xvd2VyQ2FzZSgpKT9oYShmdW5jdGlvbihhLGMpe3ZhciBkLGY9ZShhLGIpLGc9Zi5sZW5ndGg7d2hpbGUoZy0tKWQ9SihhLGZbZ10pLGFbZF09IShjW2RdPWZbZ10pfSk6ZnVuY3Rpb24oYSl7cmV0dXJuIGUoYSwwLGMpfSk6ZX19LHBzZXVkb3M6e25vdDpoYShmdW5jdGlvbihhKXt2YXIgYj1bXSxjPVtdLGQ9aChhLnJlcGxhY2UoUSxcIiQxXCIpKTtyZXR1cm4gZFt1XT9oYShmdW5jdGlvbihhLGIsYyxlKXt2YXIgZixnPWQoYSxudWxsLGUsW10pLGg9YS5sZW5ndGg7d2hpbGUoaC0tKShmPWdbaF0pJiYoYVtoXT0hKGJbaF09ZikpfSk6ZnVuY3Rpb24oYSxlLGYpe3JldHVybiBiWzBdPWEsZChiLG51bGwsZixjKSxiWzBdPW51bGwsIWMucG9wKCl9fSksaGFzOmhhKGZ1bmN0aW9uKGEpe3JldHVybiBmdW5jdGlvbihiKXtyZXR1cm4gZmEoYSxiKS5sZW5ndGg+MH19
7437KSxjb250YWluczpoYShmdW5jdGlvbihhKXtyZXR1cm4gYT1hLnJlcGxhY2UoYmEsY2EpLGZ1bmN0aW9uKGIpe3JldHVybihiLnRleHRDb250ZW50fHxiLmlubmVyVGV4dHx8ZShiKSkuaW5kZXhPZihhKT4tMX19KSxsYW5nOmhhKGZ1bmN0aW9uKGEpe3JldHVybiBWLnRlc3QoYXx8XCJcIil8fGZhLmVycm9yKFwidW5zdXBwb3J0ZWQgbGFuZzogXCIrYSksYT1hLnJlcGxhY2UoYmEsY2EpLnRvTG93ZXJDYXNlKCksZnVuY3Rpb24oYil7dmFyIGM7ZG8gaWYoYz1wP2IubGFuZzpiLmdldEF0dHJpYnV0ZShcInhtbDpsYW5nXCIpfHxiLmdldEF0dHJpYnV0ZShcImxhbmdcIikpcmV0dXJuIGM9Yy50b0xvd2VyQ2FzZSgpLGM9PT1hfHwwPT09Yy5pbmRleE9mKGErXCItXCIpO3doaWxlKChiPWIucGFyZW50Tm9kZSkmJjE9PT1iLm5vZGVUeXBlKTtyZXR1cm4hMX19KSx0YXJnZXQ6ZnVuY3Rpb24oYil7dmFyIGM9YS5sb2NhdGlvbiYmYS5sb2NhdGlvbi5oYXNoO3JldHVybiBjJiZjLnNsaWNlKDEpPT09Yi5pZH0scm9vdDpmdW5jdGlvbihhKXtyZXR1cm4gYT09PW99LGZvY3VzOmZ1bmN0aW9uKGEpe3JldHVybiBhPT09bi5hY3RpdmVFbGVtZW50JiYoIW4uaGFzRm9jdXN8fG4uaGFzRm9jdXMoKSkmJiEhKGEudHlwZXx8YS5ocmVmfHx+YS50YWJJbmRleCl9LGVuYWJsZWQ6ZnVuY3Rpb24oYSl7cmV0dXJuIGEuZGlzYWJsZWQ9PT0hMX0sZGlzYWJsZWQ6ZnVuY3Rpb24oYSl7cmV0dXJuIGEuZGlzYWJsZWQ9PT0hMH0sY2hlY2tlZDpmdW5jdGlvbihhKXt2YXIgYj1hLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7cmV0dXJuXCJpbnB1dFwiPT09YiYmISFhLmNoZWNrZWR8fFwib3B0aW9uXCI9PT1iJiYhIWEuc2VsZWN0ZWR9LHNlbGVjdGVkOmZ1bmN0aW9uKGEpe3JldHVybiBhLnBhcmVudE5vZGUmJmEucGFyZW50Tm9kZS5zZWxlY3RlZEluZGV4LGEuc2VsZWN0ZWQ9PT0hMH0sZW1wdHk6ZnVuY3Rpb24oYSl7Zm9yKGE9YS5maXJzdENoaWxkO2E7YT1hLm5leHRTaWJsaW5nKWlmKGEubm9kZVR5cGU8NilyZXR1cm4hMTtyZXR1cm4hMH0scGFyZW50OmZ1bmN0aW9uKGEpe3JldHVybiFkLnBzZXVkb3MuZW1wdHkoYSl9LGhlYWRlcjpmdW5jdGlvbihhKXtyZXR1cm4gWS50ZXN0KGEubm9kZU5hbWUpfSxpbnB1dDpmdW5jdGlvbihhKXtyZXR1cm4gWC50ZXN0KGEubm9kZU5hbWUpfSxidXR0b246ZnVuY3Rpb24oYSl7dmFyIGI9YS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO3JldHVyblwiaW5wdXRcIj09PWImJlwiYnV0dG9uXCI9PT1hLnR5cGV8fFwiYnV0dG9uXCI9PT1ifSx0ZXh0OmZ1bmN0aW9uKGEpe3ZhciBiO3JldHVyblwiaW5wdXRcIj09PWEubm9kZU5hbWUudG9Mb3dlckNhc2UoKSYmXCJ0ZXh0XCI9PT1hLnR5cGUmJihudWxsPT0oYj1hLmdldEF0dHJpYnV0ZShcInR5cGVcIikpfHxcInRleHRcIj09PWIudG9Mb3dlckNhc2UoKSl9LGZpcnN0Om5hKGZ1bmN0aW9uKCl7cmV0dXJuWzBdfSksbGFzdDpuYShmdW5jdGlvbihhLGIpe3JldHVybltiLTFdfSksZXE6bmEoZnVuY3Rpb24oYSxiLGMpe3JldHVyblswPmM/YytiOmNdfSksZXZlbjpuYShmdW5jdGlvbihhLGIpe2Zvcih2YXIgYz0wO2I+YztjKz0yKWEucHVzaChjKTtyZXR1cm4gYX0pLG9kZDpuYShmdW5jdGlvbihhLGIpe2Zvcih2YXIgYz0xO2I+YztjKz0yKWEucHVzaChjKTtyZXR1cm4gYX0pLGx0Om5hKGZ1bmN0aW9uKGEsYixjKXtmb3IodmFyIGQ9MD5jP2MrYjpjOy0tZD49MDspYS5wdXNoKGQpO3JldHVybiBhfSksZ3Q6bmEoZnVuY3Rpb24oYSxiLGMpe2Zvcih2YXIgZD0wPmM/YytiOmM7KytkPGI7KWEucHVzaChkKTtyZXR1cm4gYX0pfX0sZC5wc2V1ZG9zLm50aD1kLnBzZXVkb3MuZXE7Zm9yKGIgaW57cmFkaW86ITAsY2hlY2tib3g6ITAsZmlsZTohMCxwYXNzd29yZDohMCxpbWFnZTohMH0pZC5wc2V1ZG9zW2JdPWxhKGIpO2ZvcihiIGlue3N1Ym1pdDohMCxyZXNldDohMH0pZC5wc2V1ZG9zW2JdPW1hKGIpO2Z1bmN0aW9uIHBhKCl7fXBhLnByb3RvdHlwZT1kLmZpbHRlcnM9ZC5wc2V1ZG9zLGQuc2V0RmlsdGVycz1uZXcgcGEsZz1mYS50b2tlbml6ZT1mdW5jdGlvbihhLGIpe3ZhciBjLGUsZixnLGgsaSxqLGs9elthK1wiIFwiXTtpZihrKXJldHVybiBiPzA6ay5zbGljZSgwKTtoPWEsaT1bXSxqPWQucHJlRmlsdGVyO3doaWxlKGgpe2MmJiEoZT1SLmV4ZWMoaCkpfHwoZSYmKGg9aC5zbGljZShlWzBdLmxlbmd0aCl8fGgpLGkucHVzaChmPVtdKSksYz0hMSwoZT1TLmV4ZWMoaCkpJiYoYz1lLnNoaWZ0KCksZi5wdXNoKHt2YWx1ZTpjLHR5cGU6ZVswXS5yZXBsYWNlKFEsXCIgXCIpfSksaD1oLnNsaWNlKGMubGVuZ3RoKSk7Zm9yKGcgaW4gZC5maWx0ZXIpIShlPVdbZ10uZXhlYyhoKSl8fGpbZ10mJiEoZT1qW2ddKGUpKXx8KGM9ZS5zaGlmdCgpLGYucHVzaCh7dmFsdWU6Yyx0eXBlOmcsbWF0Y2hlczplfSksaD1oLnNsaWNlKGMubGVuZ3RoKSk7aWYoIWMpYnJlYWt9cmV0dXJuIGI/aC5sZW5ndGg6aD9mYS5lcnJvcihhKTp6KGEsaSkuc2xpY2UoMCl9O2Z1bmN0aW9uIHFhKGEpe2Zvcih2YXIgYj0wLGM9YS5sZW5ndGgsZD1cIlwiO2M+YjtiKyspZCs9YVtiXS52YWx1ZTtyZXR1cm4gZH1mdW5jdGlvbiByYShhLGIsYyl7dmFyIGQ9Yi5kaXIsZT1jJiZcInBhcmVudE5vZGVcIj09PWQsZj14Kys7cmV0dXJuIGIuZmlyc3Q/ZnVuY3Rpb24oYixjLGYpe3doaWxlKGI9YltkXSlpZigxPT09Yi5ub2RlVHlwZXx8ZSlyZXR1cm4gYShiLGMsZil9OmZ1bmN0aW9uKGIsYyxnKXt2YXIgaCxpLGosaz1bdyxmXTtpZihnKXt3aGlsZShiPWJbZF0paWYoKDE9PT1iLm5vZGVUeXBlfHxlKSYmYShiLGMsZykpcmV0dXJuITB9ZWxzZSB3aGlsZShiPWJbZF0paWYoMT09PWIubm9kZVR5cGV8fGUpe2lmKGo9Ylt1XXx8
7437KGJbdV09e30pLGk9altiLnVuaXF1ZUlEXXx8KGpbYi51bmlxdWVJRF09e30pLChoPWlbZF0pJiZoWzBdPT09dyYmaFsxXT09PWYpcmV0dXJuIGtbMl09aFsyXTtpZihpW2RdPWssa1syXT1hKGIsYyxnKSlyZXR1cm4hMH19fWZ1bmN0aW9uIHNhKGEpe3JldHVybiBhLmxlbmd0aD4xP2Z1bmN0aW9uKGIsYyxkKXt2YXIgZT1hLmxlbmd0aDt3aGlsZShlLS0paWYoIWFbZV0oYixjLGQpKXJldHVybiExO3JldHVybiEwfTphWzBdfWZ1bmN0aW9uIHRhKGEsYixjKXtmb3IodmFyIGQ9MCxlPWIubGVuZ3RoO2U+ZDtkKyspZmEoYSxiW2RdLGMpO3JldHVybiBjfWZ1bmN0aW9uIHVhKGEsYixjLGQsZSl7Zm9yKHZhciBmLGc9W10saD0wLGk9YS5sZW5ndGgsaj1udWxsIT1iO2k+aDtoKyspKGY9YVtoXSkmJihjJiYhYyhmLGQsZSl8fChnLnB1c2goZiksaiYmYi5wdXNoKGgpKSk7cmV0dXJuIGd9ZnVuY3Rpb24gdmEoYSxiLGMsZCxlLGYpe3JldHVybiBkJiYhZFt1XSYmKGQ9dmEoZCkpLGUmJiFlW3VdJiYoZT12YShlLGYpKSxoYShmdW5jdGlvbihmLGcsaCxpKXt2YXIgaixrLGwsbT1bXSxuPVtdLG89Zy5sZW5ndGgscD1mfHx0YShifHxcIipcIixoLm5vZGVUeXBlP1toXTpoLFtdKSxxPSFhfHwhZiYmYj9wOnVhKHAsbSxhLGgsaSkscj1jP2V8fChmP2E6b3x8ZCk/W106ZzpxO2lmKGMmJmMocSxyLGgsaSksZCl7aj11YShyLG4pLGQoaixbXSxoLGkpLGs9ai5sZW5ndGg7d2hpbGUoay0tKShsPWpba10pJiYocltuW2tdXT0hKHFbbltrXV09bCkpfWlmKGYpe2lmKGV8fGEpe2lmKGUpe2o9W10saz1yLmxlbmd0aDt3aGlsZShrLS0pKGw9cltrXSkmJmoucHVzaChxW2tdPWwpO2UobnVsbCxyPVtdLGosaSl9az1yLmxlbmd0aDt3aGlsZShrLS0pKGw9cltrXSkmJihqPWU/SihmLGwpOm1ba10pPi0xJiYoZltqXT0hKGdbal09bCkpfX1lbHNlIHI9dWEocj09PWc/ci5zcGxpY2UobyxyLmxlbmd0aCk6ciksZT9lKG51bGwsZyxyLGkpOkguYXBwbHkoZyxyKX0pfWZ1bmN0aW9uIHdhKGEpe2Zvcih2YXIgYixjLGUsZj1hLmxlbmd0aCxnPWQucmVsYXRpdmVbYVswXS50eXBlXSxoPWd8fGQucmVsYXRpdmVbXCIgXCJdLGk9Zz8xOjAsaz1yYShmdW5jdGlvbihhKXtyZXR1cm4gYT09PWJ9LGgsITApLGw9cmEoZnVuY3Rpb24oYSl7cmV0dXJuIEooYixhKT4tMX0saCwhMCksbT1bZnVuY3Rpb24oYSxjLGQpe3ZhciBlPSFnJiYoZHx8YyE9PWopfHwoKGI9Yykubm9kZVR5cGU/ayhhLGMsZCk6bChhLGMsZCkpO3JldHVybiBiPW51bGwsZX1dO2Y+aTtpKyspaWYoYz1kLnJlbGF0aXZlW2FbaV0udHlwZV0pbT1bcmEoc2EobSksYyldO2Vsc2V7aWYoYz1kLmZpbHRlclthW2ldLnR5cGVdLmFwcGx5KG51bGwsYVtpXS5tYXRjaGVzKSxjW3VdKXtmb3IoZT0rK2k7Zj5lO2UrKylpZihkLnJlbGF0aXZlW2FbZV0udHlwZV0pYnJlYWs7cmV0dXJuIHZhKGk+MSYmc2EobSksaT4xJiZxYShhLnNsaWNlKDAsaS0xKS5jb25jYXQoe3ZhbHVlOlwiIFwiPT09YVtpLTJdLnR5cGU/XCIqXCI6XCJcIn0pKS5yZXBsYWNlKFEsXCIkMVwiKSxjLGU+aSYmd2EoYS5zbGljZShpLGUpKSxmPmUmJndhKGE9YS5zbGljZShlKSksZj5lJiZxYShhKSl9bS5wdXNoKGMpfXJldHVybiBzYShtKX1mdW5jdGlvbiB4YShhLGIpe3ZhciBjPWIubGVuZ3RoPjAsZT1hLmxlbmd0aD4wLGY9ZnVuY3Rpb24oZixnLGgsaSxrKXt2YXIgbCxvLHEscj0wLHM9XCIwXCIsdD1mJiZbXSx1PVtdLHY9aix4PWZ8fGUmJmQuZmluZC5UQUcoXCIqXCIsaykseT13Kz1udWxsPT12PzE6TWF0aC5yYW5kb20oKXx8LjEsej14Lmxlbmd0aDtmb3IoayYmKGo9Zz09PW58fGd8fGspO3MhPT16JiZudWxsIT0obD14W3NdKTtzKyspe2lmKGUmJmwpe289MCxnfHxsLm93bmVyRG9jdW1lbnQ9PT1ufHwobShsKSxoPSFwKTt3aGlsZShxPWFbbysrXSlpZihxKGwsZ3x8bixoKSl7aS5wdXNoKGwpO2JyZWFrfWsmJih3PXkpfWMmJigobD0hcSYmbCkmJnItLSxmJiZ0LnB1c2gobCkpfWlmKHIrPXMsYyYmcyE9PXIpe289MDt3aGlsZShxPWJbbysrXSlxKHQsdSxnLGgpO2lmKGYpe2lmKHI+MCl3aGlsZShzLS0pdFtzXXx8dVtzXXx8KHVbc109Ri5jYWxsKGkpKTt1PXVhKHUpfUguYXBwbHkoaSx1KSxrJiYhZiYmdS5sZW5ndGg+MCYmcitiLmxlbmd0aD4xJiZmYS51bmlxdWVTb3J0KGkpfXJldHVybiBrJiYodz15LGo9diksdH07cmV0dXJuIGM/aGEoZik6Zn1yZXR1cm4gaD1mYS5jb21waWxlPWZ1bmN0aW9uKGEsYil7dmFyIGMsZD1bXSxlPVtdLGY9QVthK1wiIFwiXTtpZighZil7Ynx8KGI9ZyhhKSksYz1iLmxlbmd0aDt3aGlsZShjLS0pZj13YShiW2NdKSxmW3VdP2QucHVzaChmKTplLnB1c2goZik7Zj1BKGEseGEoZSxkKSksZi5zZWxlY3Rvcj1hfXJldHVybiBmfSxpPWZhLnNlbGVjdD1mdW5jdGlvbihhLGIsZSxmKXt2YXIgaSxqLGssbCxtLG49XCJmdW5jdGlvblwiPT10eXBlb2YgYSYmYSxvPSFmJiZnKGE9bi5zZWxlY3Rvcnx8YSk7aWYoZT1lfHxbXSwxPT09by5sZW5ndGgpe2lmKGo9b1swXT1vWzBdLnNsaWNlKDApLGoubGVuZ3RoPjImJlwiSURcIj09PShrPWpbMF0pLnR5cGUmJmMuZ2V0QnlJZCYmOT09PWIubm9kZVR5cGUmJnAmJmQucmVsYXRpdmVbalsxXS50eXBlXSl7aWYoYj0oZC5maW5kLklEKGsubWF0Y2hlc1swXS5yZXBsYWNlKGJhLGNhKSxiKXx8W10pWzBdLCFiKXJldHVybiBlO24mJihiPWIucGFyZW50Tm9kZSksYT1hLnNsaWNlKGouc2hpZnQoKS52YWx1ZS5sZW5ndGgpfWk9Vy5uZWVkc0NvbnRleHQudGVzdChhKT8wOmoubGVuZ3RoO3doaWxlKGktLSl7aWYoaz1qW2ldLGQucmVsYXRpdmVbbD1rLnR5cGVdKWJyZWFrO2lmKChtPWQuZmluZFtsXSkmJihmPW0oay5tYXRjaGVzWzBdLnJlcGxhY2UoYmEsY2EpLF8udGVzdChqWzBdLnR5cGUpJiZvYShiLnBhcmVudE5vZGUpfHxiKSkpe2lmKGouc3BsaWNlKGksMSksYT1mLmxlbmd0aCYmcWEoaiksIWEpcmV0dXJuIEguYXBwbHkoZSxmKSxlO2JyZWFrfX19cmV0dXJuKG58fGgoYSxvKSkoZixiLCFwLGUsIWJ8fF8udGVzdChhKSYmb2EoYi5wYXJlbnROb2RlKXx8YiksZX0sYy5zb3J0U3RhYmxlPXUuc3BsaXQoXCJcIikuc29ydChCKS5qb2luKFwiXCIpPT09dSxjLmRldGVjdER1cGxpY2F0ZXM9ISFsLG0oKSxjLnNvcnREZXRhY2hlZD1pYShmdW5jdGlvbihhKXtyZXR1cm4gMSZhLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKG4uY3JlYXRlRWxlbWVudChcImRpdlwiKSl9KSxpYShmdW5jdGlvbihhKXtyZXR1cm4gYS5pbm5lckhUTUw9XCI8YSBocmVmPScjJz48L2E+XCIsXCIjXCI9PT1hLmZpcnN0Q2hpbGQuZ2V0QXR0cmlidXRlKFwiaHJlZlwiKX0pfHxqYShcInR5cGV8aHJlZnxoZWlnaHR8d2lkdGhcIixmdW5jdGlvbihhLGIsYyl7cmV0dXJuIGM/dm9pZCAwOmEuZ2V0QXR0cmlidXRlKGIsXCJ0eXBlXCI9PT1iLnRvTG93ZXJDYXNlKCk/MToyKX0pLGMuYXR0cmlidXRlcyYmaWEoZnVuY3Rpb24oYSl7cmV0dXJuIGEuaW5uZXJIVE1MPVwiPGlucHV0Lz5cIixhLmZpcnN0Q2hpbGQuc2V0QXR0cmlidXRlKFwidmFsdWVcIixcIlwiKSxcIlwiPT09YS5maXJzdENoaWxkLmdldEF0dHJpYnV0ZShcInZhbHVlXCIpfSl8fGphKFwidmFsdWVcIixmdW5jdGlvbihhLGIsYyl7cmV0dXJuIGN8fFwiaW5wdXRcIiE9PWEubm9kZU5hbWUudG9Mb3dlckNhc2UoKT92b2lkIDA6YS5kZWZhdWx0VmFsdWV9KSxpYShmdW5jdGlvbihhKXtyZXR1cm4gbnVsbD09YS5nZXRBdHRyaWJ1dGUoXCJkaXNhYmxlZFwiKX0pfHxqYShLLGZ1bmN0aW9uKGEsYixjKXt2YXIgZDtyZXR1cm4gYz92b2lkIDA6YVtiXT09PSEwP2IudG9Mb3dlckNhc2UoKTooZD1hLmdldEF0dHJpYnV0ZU5vZGUoYikpJiZkLnNwZWNpZmllZD9kLnZhbHVlOm51bGx9KSxmYX0oYSk7bi5maW5kPXQsbi5leHByPXQuc2VsZWN0b3JzLG4uZXhwcltcIjpcIl09bi5leHByLnBzZXVkb3Msbi51bmlxdWVTb3J0PW4udW5pcXVlPXQudW5pcXVlU29ydCxuLnRleHQ9dC5nZXRUZXh0LG4uaXNYTUxEb2M9dC5pc1hNTCxuLmNvbnRhaW5zPXQuY29udGFpbnM7dmFyIHU9ZnVuY3Rpb24oYSxiLGMpe3ZhciBkPVtdLGU9dm9pZCAwIT09Yzt3aGlsZSgoYT1hW2JdKSYmOSE9PWEubm9kZVR5cGUpaWYoMT09PWEubm9kZVR5cGUpe2lmKGUmJm4oYSkuaXMoYykpYnJlYWs7ZC5wdXNoKGEpf
7437XJldHVybiBkfSx2PWZ1bmN0aW9uKGEsYil7Zm9yKHZhciBjPVtdO2E7YT1hLm5leHRTaWJsaW5nKTE9PT1hLm5vZGVUeXBlJiZhIT09YiYmYy5wdXNoKGEpO3JldHVybiBjfSx3PW4uZXhwci5tYXRjaC5uZWVkc0NvbnRleHQseD0vXjwoW1xcdy1dKylcXHMqXFwvPz4oPzo8XFwvXFwxPnwpJC8seT0vXi5bXjojXFxbXFwuLF0qJC87ZnVuY3Rpb24geihhLGIsYyl7aWYobi5pc0Z1bmN0aW9uKGIpKXJldHVybiBuLmdyZXAoYSxmdW5jdGlvbihhLGQpe3JldHVybiEhYi5jYWxsKGEsZCxhKSE9PWN9KTtpZihiLm5vZGVUeXBlKXJldHVybiBuLmdyZXAoYSxmdW5jdGlvbihhKXtyZXR1cm4gYT09PWIhPT1jfSk7aWYoXCJzdHJpbmdcIj09dHlwZW9mIGIpe2lmKHkudGVzdChiKSlyZXR1cm4gbi5maWx0ZXIoYixhLGMpO2I9bi5maWx0ZXIoYixhKX1yZXR1cm4gbi5ncmVwKGEsZnVuY3Rpb24oYSl7cmV0dXJuIGguY2FsbChiLGEpPi0xIT09Y30pfW4uZmlsdGVyPWZ1bmN0aW9uKGEsYixjKXt2YXIgZD1iWzBdO3JldHVybiBjJiYoYT1cIjpub3QoXCIrYStcIilcIiksMT09PWIubGVuZ3RoJiYxPT09ZC5ub2RlVHlwZT9uLmZpbmQubWF0Y2hlc1NlbGVjdG9yKGQsYSk/W2RdOltdOm4uZmluZC5tYXRjaGVzKGEsbi5ncmVwKGIsZnVuY3Rpb24oYSl7cmV0dXJuIDE9PT1hLm5vZGVUeXBlfSkpfSxuLmZuLmV4dGVuZCh7ZmluZDpmdW5jdGlvbihhKXt2YXIgYixjPXRoaXMubGVuZ3RoLGQ9W10sZT10aGlzO2lmKFwic3RyaW5nXCIhPXR5cGVvZiBhKXJldHVybiB0aGlzLnB1c2hTdGFjayhuKGEpLmZpbHRlcihmdW5jdGlvbigpe2ZvcihiPTA7Yz5iO2IrKylpZihuLmNvbnRhaW5zKGVbYl0sdGhpcykpcmV0dXJuITB9KSk7Zm9yKGI9MDtjPmI7YisrKW4uZmluZChhLGVbYl0sZCk7cmV0dXJuIGQ9dGhpcy5wdXNoU3RhY2soYz4xP24udW5pcXVlKGQpOmQpLGQuc2VsZWN0b3I9dGhpcy5zZWxlY3Rvcj90aGlzLnNlbGVjdG9yK1wiIFwiK2E6YSxkfSxmaWx0ZXI6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMucHVzaFN0YWNrKHoodGhpcyxhfHxbXSwhMSkpfSxub3Q6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMucHVzaFN0YWNrKHoodGhpcyxhfHxbXSwhMCkpfSxpczpmdW5jdGlvbihhKXtyZXR1cm4hIXoodGhpcyxcInN0cmluZ1wiPT10eXBlb2YgYSYmdy50ZXN0KGEpP24oYSk6YXx8W10sITEpLmxlbmd0aH19KTt2YXIgQSxCPS9eKD86XFxzKig8W1xcd1xcV10rPilbXj5dKnwjKFtcXHctXSopKSQvLEM9bi5mbi5pbml0PWZ1bmN0aW9uKGEsYixjKXt2YXIgZSxmO2lmKCFhKXJldHVybiB0aGlzO2lmKGM9Y3x8QSxcInN0cmluZ1wiPT10eXBlb2YgYSl7aWYoZT1cIjxcIj09PWFbMF0mJlwiPlwiPT09YVthLmxlbmd0aC0xXSYmYS5sZW5ndGg+PTM/W251bGwsYSxudWxsXTpCLmV4ZWMoYSksIWV8fCFlWzFdJiZiKXJldHVybiFifHxiLmpxdWVyeT8oYnx8YykuZmluZChhKTp0aGlzLmNvbnN0cnVjdG9yKGIpLmZpbmQoYSk7aWYoZVsxXSl7aWYoYj1iIGluc3RhbmNlb2Ygbj9iWzBdOmIsbi5tZXJnZSh0aGlzLG4ucGFyc2VIVE1MKGVbMV0sYiYmYi5ub2RlVHlwZT9iLm93bmVyRG9jdW1lbnR8fGI6ZCwhMCkpLHgudGVzdChlWzFdKSYmbi5pc1BsYWluT2JqZWN0KGIpKWZvcihlIGluIGIpbi5pc0Z1bmN0aW9uKHRoaXNbZV0pP3RoaXNbZV0oYltlXSk6dGhpcy5hdHRyKGUsYltlXSk7cmV0dXJuIHRoaXN9cmV0dXJuIGY9ZC5nZXRFbGVtZW50QnlJZChlWzJdKSxmJiZmLnBhcmVudE5vZGUmJih0aGlzLmxlbmd0aD0xLHRoaXNbMF09ZiksdGhpcy5jb250ZXh0PWQsdGhpcy5zZWxlY3Rvcj1hLHRoaXN9cmV0dXJuIGEubm9kZVR5cGU/KHRoaXMuY29udGV4dD10aGlzWzBdPWEsdGhpcy5sZW5ndGg9MSx0aGlzKTpuLmlzRnVuY3Rpb24oYSk/dm9pZCAwIT09Yy5yZWFkeT9jLnJlYWR5KGEpOmEobik6KHZvaWQgMCE9PWEuc2VsZWN0b3ImJih0aGlzLnNlbGVjdG9yPWEuc2VsZWN0b3IsdGhpcy5jb250ZXh0PWEuY29udGV4dCksbi5tYWtlQXJyYXkoYSx0aGlzKSl9O0MucHJvdG90eXBlPW4uZm4sQT1uKGQpO3ZhciBEPS9eKD86cGFyZW50c3xwcmV2KD86VW50aWx8QWxsKSkvLEU9e2NoaWxkcmVuOiEwLGNvbnRlbnRzOiEwLG5leHQ6ITAscHJldjohMH07bi5mbi5leHRlbmQoe2hhczpmdW5jdGlvbihhKXt2YXIgYj1uKGEsdGhpcyksYz1iLmxlbmd0aDtyZXR1cm4gdGhpcy5maWx0ZXIoZnVuY3Rpb24oKXtmb3IodmFyIGE9MDtjPmE7YSsrKWlmKG4uY29udGFpbnModGhpcyxiW2FdKSlyZXR1cm4hMH0pfSxjbG9zZXN0OmZ1bmN0aW9uKGEsYil7Zm9yKHZhciBjLGQ9MCxlPXRoaXMubGVuZ3RoLGY9W10sZz13LnRlc3QoYSl8fFwic3RyaW5nXCIhPXR5cGVvZiBhP24oYSxifHx0aGlzLmNvbnRleHQpOjA7ZT5kO2QrKylmb3IoYz10aGlzW2RdO2MmJmMhPT1iO2M9Yy5wYXJlbnROb2RlKWlmKGMubm9kZVR5cGU8MTEmJihnP2cuaW5kZXgoYyk+LTE6MT09PWMubm9kZVR5cGUmJm4uZmluZC5tYXRjaGVzU2VsZWN0b3IoYyxhKSkpe2YucHVzaChjKTticmVha31yZXR1cm4gdGhpcy5wdXNoU3RhY2soZi5sZW5ndGg+MT9uLnVuaXF1ZVNvcnQoZik6Zil9LGluZGV4OmZ1bmN0aW9uKGEpe3JldHVybiBhP1wic3RyaW5nXCI9PXR5cGVvZiBhP2guY2FsbChuKGEpLHRoaXNbMF0pOmguY2FsbCh0aGlzLGEuanF1ZXJ5P2FbMF06YSk6dGhpc1swXSYmdGhpc1swXS5wYXJlbnROb2RlP3RoaXMuZmlyc3QoKS5wcmV2QWxsKCkubGVuZ3RoOi0xfSxhZGQ6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5wdXNoU3RhY2sobi51bmlxdWVTb3J0KG4ubWVyZ2UodGhpcy5nZXQoKSxuKGEsYikpKSl9LGFkZEJhY2s6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYWRkKG51bGw9PWE/dGhpcy5wcmV2T2JqZWN0OnRoaXMucHJldk9iamVjdC5maWx0ZXIoYSkpfX0pO2Z1bmN0aW9uIEYoYSxiKXt3aGlsZSgoYT1hW2JdKSYmMSE9PWEubm9kZVR5cGUpO3JldHVybiBhfW4uZWFjaCh7cGFyZW50OmZ1bmN0aW9uKGEpe3ZhciBiPWEucGFyZW50Tm9kZTtyZXR1cm4gYiYmMTEhPT1iLm5vZGVUeXBlP2I6bnVsbH0scGFyZW50czpmdW5jdGlvbihhKXtyZXR1cm4gdShhLFwicGFyZW50Tm9kZVwiKX0scGFyZW50c1VudGlsOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gdShhLFwicGFyZW50Tm9kZVwiLGMpfSxuZXh0OmZ1bmN0aW9uKGEpe3JldHVybiBGKGEsXCJuZXh0U2libGluZ1wiKX0scHJldjpmdW5jdGlvbihhKXtyZXR1cm4gRihhLFwicHJldmlvdXNTaWJsaW5nXCIpfSxuZXh0QWxsOmZ1bmN0aW9uKGEpe3JldHVybiB1KGEsXCJuZXh0U2libGluZ1wiKX0scHJldkFsbDpmdW5jdGlvbihhKXtyZXR1cm4gdShhLFwicHJldmlvdXNTaWJsaW5nXCIpfSxuZXh0VW50aWw6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiB1KGEsXCJuZXh0U2libGluZ1wiLGMpfSxwcmV2VW50aWw6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiB1KGEsXCJwcmV2aW91c1NpYmxpbmdcIixjKX0sc2libGluZ3M6ZnVuY3Rpb24oYSl7cmV0dXJuIHYoKGEucGFyZW50Tm9kZXx8e30pLmZpcnN0Q2hpbGQsYSl9LGNoaWxkcmVuOmZ1bmN0aW9uKGEpe3JldHVybiB2KGEuZmlyc3RDaGlsZCl9LGNvbnRlbn
7437RzOmZ1bmN0aW9uKGEpe3JldHVybiBhLmNvbnRlbnREb2N1bWVudHx8bi5tZXJnZShbXSxhLmNoaWxkTm9kZXMpfX0sZnVuY3Rpb24oYSxiKXtuLmZuW2FdPWZ1bmN0aW9uKGMsZCl7dmFyIGU9bi5tYXAodGhpcyxiLGMpO3JldHVyblwiVW50aWxcIiE9PWEuc2xpY2UoLTUpJiYoZD1jKSxkJiZcInN0cmluZ1wiPT10eXBlb2YgZCYmKGU9bi5maWx0ZXIoZCxlKSksdGhpcy5sZW5ndGg+MSYmKEVbYV18fG4udW5pcXVlU29ydChlKSxELnRlc3QoYSkmJmUucmV2ZXJzZSgpKSx0aGlzLnB1c2hTdGFjayhlKX19KTt2YXIgRz0vXFxTKy9nO2Z1bmN0aW9uIEgoYSl7dmFyIGI9e307cmV0dXJuIG4uZWFjaChhLm1hdGNoKEcpfHxbXSxmdW5jdGlvbihhLGMpe2JbY109ITB9KSxifW4uQ2FsbGJhY2tzPWZ1bmN0aW9uKGEpe2E9XCJzdHJpbmdcIj09dHlwZW9mIGE/SChhKTpuLmV4dGVuZCh7fSxhKTt2YXIgYixjLGQsZSxmPVtdLGc9W10saD0tMSxpPWZ1bmN0aW9uKCl7Zm9yKGU9YS5vbmNlLGQ9Yj0hMDtnLmxlbmd0aDtoPS0xKXtjPWcuc2hpZnQoKTt3aGlsZSgrK2g8Zi5sZW5ndGgpZltoXS5hcHBseShjWzBdLGNbMV0pPT09ITEmJmEuc3RvcE9uRmFsc2UmJihoPWYubGVuZ3RoLGM9ITEpfWEubWVtb3J5fHwoYz0hMSksYj0hMSxlJiYoZj1jP1tdOlwiXCIpfSxqPXthZGQ6ZnVuY3Rpb24oKXtyZXR1cm4gZiYmKGMmJiFiJiYoaD1mLmxlbmd0aC0xLGcucHVzaChjKSksZnVuY3Rpb24gZChiKXtuLmVhY2goYixmdW5jdGlvbihiLGMpe24uaXNGdW5jdGlvbihjKT9hLnVuaXF1ZSYmai5oYXMoYyl8fGYucHVzaChjKTpjJiZjLmxlbmd0aCYmXCJzdHJpbmdcIiE9PW4udHlwZShjKSYmZChjKX0pfShhcmd1bWVudHMpLGMmJiFiJiZpKCkpLHRoaXN9LHJlbW92ZTpmdW5jdGlvbigpe3JldHVybiBuLmVhY2goYXJndW1lbnRzLGZ1bmN0aW9uKGEsYil7dmFyIGM7d2hpbGUoKGM9bi5pbkFycmF5KGIsZixjKSk+LTEpZi5zcGxpY2UoYywxKSxoPj1jJiZoLS19KSx0aGlzfSxoYXM6ZnVuY3Rpb24oYSl7cmV0dXJuIGE/bi5pbkFycmF5KGEsZik+LTE6Zi5sZW5ndGg+MH0sZW1wdHk6ZnVuY3Rpb24oKXtyZXR1cm4gZiYmKGY9W10pLHRoaXN9LGRpc2FibGU6ZnVuY3Rpb24oKXtyZXR1cm4gZT1nPVtdLGY9Yz1cIlwiLHRoaXN9LGRpc2FibGVkOmZ1bmN0aW9uKCl7cmV0dXJuIWZ9LGxvY2s6ZnVuY3Rpb24oKXtyZXR1cm4gZT1nPVtdLGN8fChmPWM9XCJcIiksdGhpc30sbG9ja2VkOmZ1bmN0aW9uKCl7cmV0dXJuISFlfSxmaXJlV2l0aDpmdW5jdGlvbihhLGMpe3JldHVybiBlfHwoYz1jfHxbXSxjPVthLGMuc2xpY2U/Yy5zbGljZSgpOmNdLGcucHVzaChjKSxifHxpKCkpLHRoaXN9LGZpcmU6ZnVuY3Rpb24oKXtyZXR1cm4gai5maXJlV2l0aCh0aGlzLGFyZ3VtZW50cyksdGhpc30sZmlyZWQ6ZnVuY3Rpb24oKXtyZXR1cm4hIWR9fTtyZXR1cm4gan0sbi5leHRlbmQoe0RlZmVycmVkOmZ1bmN0aW9uKGEpe3ZhciBiPVtbXCJyZXNvbHZlXCIsXCJkb25lXCIsbi5DYWxsYmFja3MoXCJvbmNlIG1lbW9yeVwiKSxcInJlc29sdmVkXCJdLFtcInJlamVjdFwiLFwiZmFpbFwiLG4uQ2FsbGJhY2tzKFwib25jZSBtZW1vcnlcIiksXCJyZWplY3RlZFwiXSxbXCJub3RpZnlcIixcInByb2dyZXNzXCIsbi5DYWxsYmFja3MoXCJtZW1vcnlcIildXSxjPVwicGVuZGluZ1wiLGQ9e3N0YXRlOmZ1bmN0aW9uKCl7cmV0dXJuIGN9LGFsd2F5czpmdW5jdGlvbigpe3JldHVybiBlLmRvbmUoYXJndW1lbnRzKS5mYWlsKGFyZ3VtZW50cyksdGhpc30sdGhlbjpmdW5jdGlvbigpe3ZhciBhPWFyZ3VtZW50cztyZXR1cm4gbi5EZWZlcnJlZChmdW5jdGlvbihjKXtuLmVhY2goYixmdW5jdGlvbihiLGYpe3ZhciBnPW4uaXNGdW5jdGlvbihhW2JdKSYmYVtiXTtlW2ZbMV1dKGZ1bmN0aW9uKCl7dmFyIGE9ZyYmZy5hcHBseSh0aGlzLGFyZ3VtZW50cyk7YSYmbi5pc0Z1bmN0aW9uKGEucHJvbWlzZSk/YS5wcm9taXNlKCkucHJvZ3Jlc3MoYy5ub3RpZnkpLmRvbmUoYy5yZXNvbHZlKS5mYWlsKGMucmVqZWN0KTpjW2ZbMF0rXCJXaXRoXCJdKHRoaXM9PT1kP2MucHJvbWlzZSgpOnRoaXMsZz9bYV06YXJndW1lbnRzKX0pfSksYT1udWxsfSkucHJvbWlzZSgpfSxwcm9taXNlOmZ1bmN0aW9uKGEpe3JldHVybiBudWxsIT1hP24uZXh0ZW5kKGEsZCk6ZH19LGU9e307cmV0dXJuIGQucGlwZT1kLnRoZW4sbi5lYWNoKGIsZnVuY3Rpb24oYSxmKXt2YXIgZz1mWzJdLGg9ZlszXTtkW2ZbMV1dPWcuYWRkLGgmJmcuYWRkKGZ1bmN0aW9uKCl7Yz1ofSxiWzFeYV1bMl0uZGlzYWJsZSxiWzJdWzJdLmxvY2spLGVbZlswXV09ZnVuY3Rpb24oKXtyZXR1cm4gZVtmWzBdK1wiV2l0aFwiXSh0aGlzPT09ZT9kOnRoaXMsYXJndW1lbnRzKSx0aGlzfSxlW2ZbMF0rXCJXaXRoXCJdPWcuZmlyZVdpdGh9KSxkLnByb21pc2UoZSksYSYmYS5jYWxsKGUsZSksZX0sd2hlbjpmdW5jdGlvbihhKXt2YXIgYj0wLGM9ZS5jYWxsKGFyZ3VtZW50cyksZD1jLmxlbmd0aCxmPTEhPT1kfHxhJiZuLmlzRnVuY3Rpb24oYS5wcm9taXNlKT9kOjAsZz0xPT09Zj9hOm4uRGVmZXJyZWQoKSxoPWZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gZnVuY3Rpb24oZCl7YlthXT10aGlzLGNbYV09YXJndW1lbnRzLmxlbmd0aD4xP2UuY2FsbChhcmd1bWVudHMpOmQsYz09PWk/Zy5ub3RpZnlXaXRoKGIsYyk6LS1mfHxnLnJlc29sdmVXaXRoKGIsYyl9fSxpLGosaztpZihkPjEpZm9yKGk9bmV3IEFycmF5KGQpLGo9bmV3IEFycmF5KGQpLGs9bmV3IEFycmF5KGQpO2Q+YjtiKyspY1tiXSYmbi5pc0Z1bmN0aW9uKGNbYl0ucHJvbWlzZSk/Y1tiXS5wcm9taXNlKCkucHJvZ3Jlc3MoaChiLGosaSkpLmRvbmUoaChiLGssYykpLmZhaWwoZy5yZWplY3QpOi0tZjtyZXR1cm4gZnx8Zy5yZXNvbHZlV2l0aChrLGMpLGcucHJvbWlzZSgpfX0pO3ZhciBJO24uZm4ucmVhZHk9ZnVuY3Rpb24oYSl7cmV0dXJuIG4ucmVhZHkucHJvbWlzZSgpLmRvbmUoYSksdGhpc30sbi5leHRlbmQoe2lz
7437UmVhZHk6ITEscmVhZHlXYWl0OjEsaG9sZFJlYWR5OmZ1bmN0aW9uKGEpe2E/bi5yZWFkeVdhaXQrKzpuLnJlYWR5KCEwKX0scmVhZHk6ZnVuY3Rpb24oYSl7KGE9PT0hMD8tLW4ucmVhZHlXYWl0Om4uaXNSZWFkeSl8fChuLmlzUmVhZHk9ITAsYSE9PSEwJiYtLW4ucmVhZHlXYWl0PjB8fChJLnJlc29sdmVXaXRoKGQsW25dKSxuLmZuLnRyaWdnZXJIYW5kbGVyJiYobihkKS50cmlnZ2VySGFuZGxlcihcInJlYWR5XCIpLG4oZCkub2ZmKFwicmVhZHlcIikpKSl9fSk7ZnVuY3Rpb24gSigpe2QucmVtb3ZlRXZlbnRMaXN0ZW5lcihcIkRPTUNvbnRlbnRMb2FkZWRcIixKKSxhLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJsb2FkXCIsSiksbi5yZWFkeSgpfW4ucmVhZHkucHJvbWlzZT1mdW5jdGlvbihiKXtyZXR1cm4gSXx8KEk9bi5EZWZlcnJlZCgpLFwiY29tcGxldGVcIj09PWQucmVhZHlTdGF0ZXx8XCJsb2FkaW5nXCIhPT1kLnJlYWR5U3RhdGUmJiFkLmRvY3VtZW50RWxlbWVudC5kb1Njcm9sbD9hLnNldFRpbWVvdXQobi5yZWFkeSk6KGQuYWRkRXZlbnRMaXN0ZW5lcihcIkRPTUNvbnRlbnRMb2FkZWRcIixKKSxhLmFkZEV2ZW50TGlzdGVuZXIoXCJsb2FkXCIsSikpKSxJLnByb21pc2UoYil9LG4ucmVhZHkucHJvbWlzZSgpO3ZhciBLPWZ1bmN0aW9uKGEsYixjLGQsZSxmLGcpe3ZhciBoPTAsaT1hLmxlbmd0aCxqPW51bGw9PWM7aWYoXCJvYmplY3RcIj09PW4udHlwZShjKSl7ZT0hMDtmb3IoaCBpbiBjKUsoYSxiLGgsY1toXSwhMCxmLGcpfWVsc2UgaWYodm9pZCAwIT09ZCYmKGU9ITAsbi5pc0Z1bmN0aW9uKGQpfHwoZz0hMCksaiYmKGc/KGIuY2FsbChhLGQpLGI9bnVsbCk6KGo9YixiPWZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gai5jYWxsKG4oYSksYyl9KSksYikpZm9yKDtpPmg7aCsrKWIoYVtoXSxjLGc/ZDpkLmNhbGwoYVtoXSxoLGIoYVtoXSxjKSkpO3JldHVybiBlP2E6aj9iLmNhbGwoYSk6aT9iKGFbMF0sYyk6Zn0sTD1mdW5jdGlvbihhKXtyZXR1cm4gMT09PWEubm9kZVR5cGV8fDk9PT1hLm5vZGVUeXBlfHwhK2Eubm9kZVR5cGV9O2Z1bmN0aW9uIE0oKXt0aGlzLmV4cGFuZG89bi5leHBhbmRvK00udWlkKyt9TS51aWQ9MSxNLnByb3RvdHlwZT17cmVnaXN0ZXI6ZnVuY3Rpb24oYSxiKXt2YXIgYz1ifHx7fTtyZXR1cm4gYS5ub2RlVHlwZT9hW3RoaXMuZXhwYW5kb109YzpPYmplY3QuZGVmaW5lUHJvcGVydHkoYSx0aGlzLmV4cGFuZG8se3ZhbHVlOmMsd3JpdGFibGU6ITAsY29uZmlndXJhYmxlOiEwfSksYVt0aGlzLmV4cGFuZG9dfSxjYWNoZTpmdW5jdGlvbihhKXtpZighTChhKSlyZXR1cm57fTt2YXIgYj1hW3RoaXMuZXhwYW5kb107cmV0dXJuIGJ8fChiPXt9LEwoYSkmJihhLm5vZGVUeXBlP2FbdGhpcy5leHBhbmRvXT1iOk9iamVjdC5kZWZpbmVQcm9wZXJ0eShhLHRoaXMuZXhwYW5kbyx7dmFsdWU6Yixjb25maWd1cmFibGU6ITB9KSkpLGJ9LHNldDpmdW5jdGlvbihhLGIsYyl7dmFyIGQsZT10aGlzLmNhY2hlKGEpO2lmKFwic3RyaW5nXCI9PXR5cGVvZiBiKWVbYl09YztlbHNlIGZvcihkIGluIGIpZVtkXT1iW2RdO3JldHVybiBlfSxnZXQ6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdm9pZCAwPT09Yj90aGlzLmNhY2hlKGEpOmFbdGhpcy5leHBhbmRvXSYmYVt0aGlzLmV4cGFuZG9dW2JdfSxhY2Nlc3M6ZnVuY3Rpb24oYSxiLGMpe3ZhciBkO3JldHVybiB2b2lkIDA9PT1ifHxiJiZcInN0cmluZ1wiPT10eXBlb2YgYiYmdm9pZCAwPT09Yz8oZD10aGlzLmdldChhLGIpLHZvaWQgMCE9PWQ/ZDp0aGlzLmdldChhLG4uY2FtZWxDYXNlKGIpKSk6KHRoaXMuc2V0KGEsYixjKSx2b2lkIDAhPT1jP2M6Yil9LHJlbW92ZTpmdW5jdGlvbihhLGIpe3ZhciBjLGQsZSxmPWFbdGhpcy5leHBhbmRvXTtpZih2b2lkIDAhPT1mKXtpZih2b2lkIDA9PT1iKXRoaXMucmVnaXN0ZXIoYSk7ZWxzZXtuLmlzQXJyYXkoYik/ZD1iLmNvbmNhdChiLm1hcChuLmNhbWVsQ2FzZSkpOihlPW4uY2FtZWxDYXNlKGIpLGIgaW4gZj9kPVtiLGVdOihkPWUsZD1kIGluIGY/W2RdOmQubWF0Y2goRyl8fFtdKSksYz1kLmxlbmd0aDt3aGlsZShjLS0pZGVsZXRlIGZbZFtjXV19KHZvaWQgMD09PWJ8fG4uaXNFbXB0eU9iamVjdChmKSkmJihhLm5vZGVUeXBlP2FbdGhpcy5leHBhbmRvXT12b2lkIDA6ZGVsZXRlIGFbdGhpcy5leHBhbmRvXSl9fSxoYXNEYXRhOmZ1bmN0aW9uKGEpe3ZhciBiPWFbdGhpcy5leHBhbmRvXTtyZXR1cm4gdm9pZCAwIT09YiYmIW4uaXNFbXB0eU9iamVjdChiKX19O3ZhciBOPW5ldyBNLE89bmV3IE0sUD0vXig/Olxce1tcXHdcXFddKlxcfXxcXFtbXFx3XFxXXSpcXF0pJC8sUT0vW0EtWl0vZztmdW5jdGlvbiBSKGEsYixjKXt2YXIgZDtpZih2b2lkIDA9PT1jJiYxPT09YS5ub2RlVHlwZSlpZihkPVwiZGF0YS1cIitiLnJlcGxhY2UoUSxcIi0kJlwiKS50b0xvd2VyQ2FzZSgpLGM9YS5nZXRBdHRyaWJ1dGUoZCksXCJzdHJpbmdcIj09dHlwZW9mIGMpe3RyeXtjPVwidHJ1ZVwiPT09Yz8hMDpcImZhbHNlXCI9PT1jPyExOlwibnVsbFwiPT09Yz9udWxsOitjK1wiXCI9PT1jPytjOlAudGVzdChjKT9uLnBhcnNlSlNPTihjKTpjO1xufWNhdGNoKGUpe31PLnNldChhLGIsYyl9ZWxzZSBjPXZvaWQgMDtyZXR1cm4gY31uLmV4dGVuZCh7aGFzRGF0YTpmdW5jdGlvbihhKXtyZXR1cm4gTy5oYXNEYXRhKGEpfHxOLmhhc0RhdGEoYSl9LGRhdGE6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBPLmFjY2VzcyhhLGIsYyl9LHJlbW92ZURhdGE6ZnVuY3Rpb24oYSxiKXtPLnJlbW92ZShhLGIpfSxfZGF0YTpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIE4uYWNjZXNzKGEsYixjKX0sX3JlbW92ZURhdGE6ZnVuY3Rpb24oYSxiKXtOLnJlbW92ZShhLGIpfX0pLG4uZm4uZXh0ZW5kKHtkYXRhOmZ1bmN0aW9uKGEsYil7dmFyIGMsZCxlLGY9dGhpc1swXSxnPWYmJmYuYXR0cmlidXRlcztpZih2b2lkIDA9PT1hKXtpZih0aGlzLmxlbmd0aCYmKGU9Ty5nZXQoZiksMT09PWYubm9kZVR5cGUmJiFOLmdldChmLFwiaGFzRGF0YUF0dHJzXCIpKSl7Yz1nLmxlbmd0aDt3aGlsZShjLS0pZ1tjXSYmKGQ9Z1tjXS5uYW1lLDA9PT1kLmluZGV4T2YoXCJkYXRhLVwiKSYmKGQ9bi5jYW1lbENhc2UoZC5zbGljZSg1KSksUihmLGQsZVtkXSkpKTtOLnNldChmLFwiaGFzRGF0YUF0dHJzXCIsITApfXJldHVybi
7437BlfXJldHVyblwib2JqZWN0XCI9PXR5cGVvZiBhP3RoaXMuZWFjaChmdW5jdGlvbigpe08uc2V0KHRoaXMsYSl9KTpLKHRoaXMsZnVuY3Rpb24oYil7dmFyIGMsZDtpZihmJiZ2b2lkIDA9PT1iKXtpZihjPU8uZ2V0KGYsYSl8fE8uZ2V0KGYsYS5yZXBsYWNlKFEsXCItJCZcIikudG9Mb3dlckNhc2UoKSksdm9pZCAwIT09YylyZXR1cm4gYztpZihkPW4uY2FtZWxDYXNlKGEpLGM9Ty5nZXQoZixkKSx2b2lkIDAhPT1jKXJldHVybiBjO2lmKGM9UihmLGQsdm9pZCAwKSx2b2lkIDAhPT1jKXJldHVybiBjfWVsc2UgZD1uLmNhbWVsQ2FzZShhKSx0aGlzLmVhY2goZnVuY3Rpb24oKXt2YXIgYz1PLmdldCh0aGlzLGQpO08uc2V0KHRoaXMsZCxiKSxhLmluZGV4T2YoXCItXCIpPi0xJiZ2b2lkIDAhPT1jJiZPLnNldCh0aGlzLGEsYil9KX0sbnVsbCxiLGFyZ3VtZW50cy5sZW5ndGg+MSxudWxsLCEwKX0scmVtb3ZlRGF0YTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCl7Ty5yZW1vdmUodGhpcyxhKX0pfX0pLG4uZXh0ZW5kKHtxdWV1ZTpmdW5jdGlvbihhLGIsYyl7dmFyIGQ7cmV0dXJuIGE/KGI9KGJ8fFwiZnhcIikrXCJxdWV1ZVwiLGQ9Ti5nZXQoYSxiKSxjJiYoIWR8fG4uaXNBcnJheShjKT9kPU4uYWNjZXNzKGEsYixuLm1ha2VBcnJheShjKSk6ZC5wdXNoKGMpKSxkfHxbXSk6dm9pZCAwfSxkZXF1ZXVlOmZ1bmN0aW9uKGEsYil7Yj1ifHxcImZ4XCI7dmFyIGM9bi5xdWV1ZShhLGIpLGQ9Yy5sZW5ndGgsZT1jLnNoaWZ0KCksZj1uLl9xdWV1ZUhvb2tzKGEsYiksZz1mdW5jdGlvbigpe24uZGVxdWV1ZShhLGIpfTtcImlucHJvZ3Jlc3NcIj09PWUmJihlPWMuc2hpZnQoKSxkLS0pLGUmJihcImZ4XCI9PT1iJiZjLnVuc2hpZnQoXCJpbnByb2dyZXNzXCIpLGRlbGV0ZSBmLnN0b3AsZS5jYWxsKGEsZyxmKSksIWQmJmYmJmYuZW1wdHkuZmlyZSgpfSxfcXVldWVIb29rczpmdW5jdGlvbihhLGIpe3ZhciBjPWIrXCJxdWV1ZUhvb2tzXCI7cmV0dXJuIE4uZ2V0KGEsYyl8fE4uYWNjZXNzKGEsYyx7ZW1wdHk6bi5DYWxsYmFja3MoXCJvbmNlIG1lbW9yeVwiKS5hZGQoZnVuY3Rpb24oKXtOLnJlbW92ZShhLFtiK1wicXVldWVcIixjXSl9KX0pfX0pLG4uZm4uZXh0ZW5kKHtxdWV1ZTpmdW5jdGlvbihhLGIpe3ZhciBjPTI7cmV0dXJuXCJzdHJpbmdcIiE9dHlwZW9mIGEmJihiPWEsYT1cImZ4XCIsYy0tKSxhcmd1bWVudHMubGVuZ3RoPGM/bi5xdWV1ZSh0aGlzWzBdLGEpOnZvaWQgMD09PWI/dGhpczp0aGlzLmVhY2goZnVuY3Rpb24oKXt2YXIgYz1uLnF1ZXVlKHRoaXMsYSxiKTtuLl9xdWV1ZUhvb2tzKHRoaXMsYSksXCJmeFwiPT09YSYmXCJpbnByb2dyZXNzXCIhPT1jWzBdJiZuLmRlcXVldWUodGhpcyxhKX0pfSxkZXF1ZXVlOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKXtuLmRlcXVldWUodGhpcyxhKX0pfSxjbGVhclF1ZXVlOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLnF1ZXVlKGF8fFwiZnhcIixbXSl9LHByb21pc2U6ZnVuY3Rpb24oYSxiKXt2YXIgYyxkPTEsZT1uLkRlZmVycmVkKCksZj10aGlzLGc9dGhpcy5sZW5ndGgsaD1mdW5jdGlvbigpey0tZHx8ZS5yZXNvbHZlV2l0aChmLFtmXSl9O1wic3RyaW5nXCIhPXR5cGVvZiBhJiYoYj1hLGE9dm9pZCAwKSxhPWF8fFwiZnhcIjt3aGlsZShnLS0pYz1OLmdldChmW2ddLGErXCJxdWV1ZUhvb2tzXCIpLGMmJmMuZW1wdHkmJihkKyssYy5lbXB0eS5hZGQoaCkpO3JldHVybiBoKCksZS5wcm9taXNlKGIpfX0pO3ZhciBTPS9bKy1dPyg/OlxcZCpcXC58KVxcZCsoPzpbZUVdWystXT9cXGQrfCkvLnNvdXJjZSxUPW5ldyBSZWdFeHAoXCJeKD86KFsrLV0pPXwpKFwiK1MrXCIpKFthLXolXSopJFwiLFwiaVwiKSxVPVtcIlRvcFwiLFwiUmlnaHRcIixcIkJvdHRvbVwiLFwiTGVmdFwiXSxWPWZ1bmN0aW9uKGEsYil7cmV0dXJuIGE9Ynx8YSxcIm5vbmVcIj09PW4uY3NzKGEsXCJkaXNwbGF5XCIpfHwhbi5jb250YWlucyhhLm93bmVyRG9jdW1lbnQsYSl9O2Z1bmN0aW9uIFcoYSxiLGMsZCl7dmFyIGUsZj0xLGc9MjAsaD1kP2Z1bmN0aW9uKCl7cmV0dXJuIGQuY3VyKCl9OmZ1bmN0aW9uKCl7cmV0dXJuIG4uY3NzKGEsYixcIlwiKX0saT1oKCksaj1jJiZjWzNdfHwobi5jc3NOdW1iZXJbYl0/XCJcIjpcInB4XCIpLGs9KG4uY3NzTnVtYmVyW2JdfHxcInB4XCIhPT1qJiYraSkmJlQuZXhlYyhuLmNzcyhhLGIpKTtpZihrJiZrWzNdIT09ail7aj1qfHxrWzNdLGM9Y3x8W10saz0raXx8MTtkbyBmPWZ8fFwiLjVcIixrLz1mLG4uc3R5bGUoYSxiLGsraik7d2hpbGUoZiE9PShmPWgoKS9pKSYmMSE9PWYmJi0tZyl9cmV0dXJuIGMmJihrPStrfHwraXx8MCxlPWNbMV0/aysoY1sxXSsxKSpjWzJdOitjWzJdLGQmJihkLnVuaXQ9aixkLnN0YXJ0PWssZC5lbmQ9ZSkpLGV9dmFyIFg9L14oPzpjaGVja2JveHxyYWRpbykkL2ksWT0vPChbXFx3Oi1dKykvLFo9L14kfFxcLyg/OmphdmF8ZWNtYSlzY3JpcHQvaSwkPXtvcHRpb246WzEsXCI8c2VsZWN0IG11bHRpcGxlPSdtdWx0aXBsZSc+XCIsXCI8L3NlbGVjdD5cIl0sdGhlYWQ6WzEsXCI8dGFibGU+XCIsXCI8L3RhYmxlPlwiXSxjb2w6WzIsXCI8dGFibGU+PGNvbGdyb3VwPlwiLFwiPC9jb2xncm91cD48L3RhYmxlPlwiXSx0cjpbMixcIjx0YWJsZT48dGJvZHk+XCIsXCI8L3Rib2R5PjwvdGFibGU+XCJdLHRkOlszLFwiPHRhYmxlPjx0Ym9keT48dHI+XCIsXCI8L3RyPjwvdGJvZHk+PC90YWJsZT5cIl0sX2RlZmF1bHQ6WzAsXCJcIixcIlwiXX07JC5vcHRncm91cD0kLm9wdGlvbiwkLnRib2R5PSQudGZvb3Q9JC5jb2xncm91cD0kLmNhcHRpb249JC50aGVhZCwkLnRoPSQudGQ7ZnVuY3Rpb24gXyhhLGIpe3ZhciBjPVwidW5kZWZpbmVkXCIhPXR5cGVvZiBhLmdldEVsZW1lbnRzQnlUYWdOYW1lP2EuZ2V0RWxlbWVudHNCeVRhZ05hbWUoYnx8XCIqXCIpOlwidW5kZWZpbmVkXCIhPXR5cGVvZiBhLnF1ZXJ5U2VsZWN0b3JBbGw/YS5xdWVyeVNlbGVjdG9yQWxsKGJ8fFwiKlwiKTpbXTtyZXR1cm4gdm9pZCAwPT09Ynx8YiYmbi5ub2RlTmFtZShhLGIpP24ubWVyZ2UoW2FdLGMpOmN9ZnVuY3Rpb24gYWEoYSxiKXtmb3IodmFyIGM9MCxkPWEubGVuZ3RoO2Q+YztjKyspTi5zZXQoYVtjXSxcImdsb2JhbEV2YWxcIiwhYnx8Ti5nZXQoYltjXSxcImdsb2JhbEV2YWxcIikpfXZhciBiYT0vPHwmIz9cXHcrOy87ZnVuY3Rpb24gY2EoYSxiLGMsZCxlKXtmb3IodmFyIGYsZyxoLGksaixrLGw9Yi5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCksbT1bXSxvPTAscD1hLmxlbmd0aDtwPm87bysrKWlmKGY9YVtvXSxmfHwwPT09ZilpZihcIm9iamVjdFwiPT09bi50eX
7437BlKGYpKW4ubWVyZ2UobSxmLm5vZGVUeXBlP1tmXTpmKTtlbHNlIGlmKGJhLnRlc3QoZikpe2c9Z3x8bC5hcHBlbmRDaGlsZChiLmNyZWF0ZUVsZW1lbnQoXCJkaXZcIikpLGg9KFkuZXhlYyhmKXx8W1wiXCIsXCJcIl0pWzFdLnRvTG93ZXJDYXNlKCksaT0kW2hdfHwkLl9kZWZhdWx0LGcuaW5uZXJIVE1MPWlbMV0rbi5odG1sUHJlZmlsdGVyKGYpK2lbMl0saz1pWzBdO3doaWxlKGstLSlnPWcubGFzdENoaWxkO24ubWVyZ2UobSxnLmNoaWxkTm9kZXMpLGc9bC5maXJzdENoaWxkLGcudGV4dENvbnRlbnQ9XCJcIn1lbHNlIG0ucHVzaChiLmNyZWF0ZVRleHROb2RlKGYpKTtsLnRleHRDb250ZW50PVwiXCIsbz0wO3doaWxlKGY9bVtvKytdKWlmKGQmJm4uaW5BcnJheShmLGQpPi0xKWUmJmUucHVzaChmKTtlbHNlIGlmKGo9bi5jb250YWlucyhmLm93bmVyRG9jdW1lbnQsZiksZz1fKGwuYXBwZW5kQ2hpbGQoZiksXCJzY3JpcHRcIiksaiYmYWEoZyksYyl7az0wO3doaWxlKGY9Z1trKytdKVoudGVzdChmLnR5cGV8fFwiXCIpJiZjLnB1c2goZil9cmV0dXJuIGx9IWZ1bmN0aW9uKCl7dmFyIGE9ZC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCksYj1hLmFwcGVuZENoaWxkKGQuY3JlYXRlRWxlbWVudChcImRpdlwiKSksYz1kLmNyZWF0ZUVsZW1lbnQoXCJpbnB1dFwiKTtjLnNldEF0dHJpYnV0ZShcInR5cGVcIixcInJhZGlvXCIpLGMuc2V0QXR0cmlidXRlKFwiY2hlY2tlZFwiLFwiY2hlY2tlZFwiKSxjLnNldEF0dHJpYnV0ZShcIm5hbWVcIixcInRcIiksYi5hcHBlbmRDaGlsZChjKSxsLmNoZWNrQ2xvbmU9Yi5jbG9uZU5vZGUoITApLmNsb25lTm9kZSghMCkubGFzdENoaWxkLmNoZWNrZWQsYi5pbm5lckhUTUw9XCI8dGV4dGFyZWE+eDwvdGV4dGFyZWE+XCIsbC5ub0Nsb25lQ2hlY2tlZD0hIWIuY2xvbmVOb2RlKCEwKS5sYXN0Q2hpbGQuZGVmYXVsdFZhbHVlfSgpO3ZhciBkYT0vXmtleS8sZWE9L14oPzptb3VzZXxwb2ludGVyfGNvbn
7437RleHRtZW51fGRyYWd8ZHJvcCl8Y2xpY2svLGZhPS9eKFteLl0qKSg/OlxcLiguKyl8KS87ZnVuY3Rpb24gZ2EoKXtyZXR1cm4hMH1mdW5jdGlvbiBoYSgpe3JldHVybiExfWZ1bmN0aW9uIGlhKCl7dHJ5e3JldHVybiBkLmFjdGl2ZUVsZW1lbnR9Y2F0Y2goYSl7fX1mdW5jdGlvbiBqYShhLGIsYyxkLGUsZil7dmFyIGcsaDtpZihcIm9iamVjdFwiPT10eXBlb2YgYil7XCJzdHJpbmdcIiE9dHlwZW9mIGMmJihkPWR8fGMsYz12b2lkIDApO2ZvcihoIGluIGIpamEoYSxoLGMsZCxiW2hdLGYpO3JldHVybiBhfWlmKG51bGw9PWQmJm51bGw9PWU/KGU9YyxkPWM9dm9pZCAwKTpudWxsPT1lJiYoXCJzdHJpbmdcIj09dHlwZW9mIGM/KGU9ZCxkPXZvaWQgMCk6KGU9ZCxkPWMsYz12b2lkIDApKSxlPT09ITEpZT1oYTtlbHNlIGlmKCFlKXJldHVybiBhO3JldHVybiAxPT09ZiYmKGc9ZSxlPWZ1bmN0aW9uKGEpe3JldHVybiBuKCkub2ZmKGEpLGcuYXBwbHkodGhpcyxhcmd1bWVudHMpfSxlLmd1aWQ9Zy5ndWlkfHwoZy5ndWlkPW4uZ3VpZCsrKSksYS5lYWNoKGZ1bmN0aW9uKCl7bi5ldmVudC5hZGQodGhpcyxiLGUsZCxjKX0pfW4uZXZlbnQ9e2dsb2JhbDp7fSxhZGQ6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgZixnLGgsaSxqLGssbCxtLG8scCxxLHI9Ti5nZXQoYSk7aWYocil7Yy5oYW5kbGVyJiYoZj1jLGM9Zi5oYW5kbGVyLGU9Zi5zZWxlY3RvciksYy5ndWlkfHwoYy5ndWlkPW4uZ3VpZCsrKSwoaT1yLmV2ZW50cyl8fChpPXIuZXZlbnRzPXt9KSwoZz1yLmhhbmRsZSl8fChnPXIuaGFuZGxlPWZ1bmN0aW9uKGIpe3JldHVyblwidW5kZWZpbmVkXCIhPXR5cGVvZiBuJiZuLmV2ZW50LnRyaWdnZXJlZCE9PWIudHlwZT9uLmV2ZW50LmRpc3BhdGNoLmFwcGx5KGEsYXJndW1lbnRzKTp2b2lkIDB9KSxiPShifHxcIlwiKS5tYXRjaChHKXx8W1wiXCJdLGo9Yi5sZW5ndGg7d2hpbGUoai0tKWg9ZmEuZXhlYyhiW2pdKXx8W10sbz1xPWhbMV0scD0oaFsyXXx8XCJcIikuc3BsaXQoXCIuXCIpLnNvcnQoKSxvJiYobD1uLmV2ZW50LnNwZWNpYWxbb118fHt9LG89KGU/bC5kZWxlZ2F0ZVR5cGU6bC5iaW5kVHlwZSl8fG8sbD1uLmV2ZW50LnNwZWNpYWxbb118fHt9LGs9bi5leHRlbmQoe3R5cGU6byxvcmlnVHlwZTpxLGRhdGE6ZCxoYW5kbGVyOmMsZ3VpZDpjLmd1aWQsc2VsZWN0b3I6ZSxuZWVkc0NvbnRleHQ6ZSYmbi5leHByLm1hdGNoLm5lZWRzQ29udGV4dC50ZXN0KGUpLG5hbWVzcGFjZTpwLmpvaW4oXCIuXCIpfSxmKSwobT1pW29dKXx8KG09aVtvXT1bXSxtLmRlbGVnYXRlQ291bnQ9MCxsLnNldHVwJiZsLnNldHVwLmNhbGwoYSxkLHAsZykhPT0hMXx8YS5hZGRFdmVudExpc3RlbmVyJiZhLmFkZEV2ZW50TGlzdGVuZXIobyxnKSksbC5hZGQmJihsLmFkZC5jYWxsKGEsayksay5oYW5kbGVyLmd1aWR8fChrLmhhbmRsZXIuZ3VpZD1jLmd1aWQpKSxlP20uc3BsaWNlKG0uZGVsZWdhdGVDb3VudCsrLDAsayk6bS5wdXNoKGspLG4uZXZlbnQuZ2xvYmFsW29dPSEwKX19LHJlbW92ZTpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciBmLGcsaCxpLGosayxsLG0sbyxwLHEscj1OLmhhc0RhdGEoYSkmJk4uZ2V0KGEpO2lmKHImJihpPXIuZXZlbnRzKSl7Yj0oYnx8XCJcIikubWF0Y2goRyl8fFtcIlwiXSxqPWIubGVuZ3RoO3doaWxlKGotLSlpZihoPWZhLmV4ZWMoYltqXSl8fFtdLG89cT1oWzFdLHA9KGhbMl18fFwiXCIpLnNwbGl0KFwiLlwiKS5zb3J0KCksbyl7bD1uLmV2ZW50LnNwZWNpYWxbb118fHt9LG89KGQ/bC5kZWxlZ2F0ZVR5cGU6bC5iaW5kVHlwZSl8fG8sbT1pW29dfHxbXSxoPWhbMl0mJm5ldyBSZWdFeHAoXCIoXnxcXFxcLilcIitwLmpvaW4oXCJcXFxcLig/Oi4qXFxcXC58KVwiKStcIihcXFxcLnwkKVwiKSxnPWY9bS5sZW5ndGg7d2hpbGUoZi0tKWs9bVtmXSwhZSYmcSE9PWsub3JpZ1R5cGV8fGMmJmMuZ3VpZCE9PWsuZ3VpZHx8aCYmIWgudGVzdChrLm5hbWVzcGFjZSl8fGQmJmQhPT1rLnNlbGVjdG9yJiYoXCIqKlwiIT09ZHx8IWsuc2VsZWN0b3IpfHwobS5zcGxpY2UoZiwxKSxrLnNlbGVjdG9yJiZtLmRlbGVnYXRlQ291bnQtLSxsLnJlbW92ZSYmbC5yZW1vdmUuY2FsbChhLGspKTtnJiYhbS5sZW5ndGgmJihsLnRlYXJkb3duJiZsLnRlYXJkb3duLmNhbGwoYSxwLHIuaGFuZGxlKSE9PSExfHxuLnJlbW92ZUV2ZW50KGEsbyxyLmhhbmRsZSksZGVsZXRlIGlbb10pfWVsc2UgZm9yKG8gaW4gaSluLmV2ZW50LnJlbW92ZShhLG8rYltqXSxjLGQsITApO24uaXNFbXB0eU9iamVjdChpKSYmTi5yZW1vdmUoYSxcImhhbmRsZSBldmVudHNcIil9fSxkaXNwYXRjaDpmdW5jdGlvbihhKXthPW4uZXZlbnQuZml4KGEpO3ZhciBiLGMsZCxmLGcsaD1bXSxpPWUuY2FsbChhcmd1bWVudHMpLGo9KE4uZ2V0KHRoaXMsXCJldmVudHNcIil8fHt9KVthLnR5cGVdfHxbXSxrPW4uZXZlbnQuc3BlY2lhbFthLnR5cGVdfHx7fTtpZihpWzBdPWEsYS5kZWxlZ2F0ZVRhcmdldD10aGlzLCFrLnByZURpc3BhdGNofHxrLnByZURpc3BhdGNoLmNhbGwodGhpcyxhKSE9PSExKXtoPW4uZXZlbnQuaGFuZGxlcnMuY2FsbCh0aGlzLGEsaiksYj0wO3doaWxlKChmPWhbYisrXSkmJiFhLmlzUHJvcGFnYXRpb25TdG9wcGVkKCkpe2EuY3VycmVudFRhcmdldD1mLmVsZW0sYz0wO3doaWxlKChnPWYuaGFuZGxlcnNbYysrXSkmJiFhLmlzSW1tZWRpYXRlUHJvcGFnYXRpb25TdG9wcGVkKCkpYS5ybmFtZXNwYWNlJiYhYS5ybmFtZXNwYWNlLnRlc3QoZy5uYW1lc3BhY2UpfHwoYS5oYW5kbGVPYmo9ZyxhLmRhdGE9Zy5kYXRhLGQ9KChuLmV2ZW50LnNwZWNpYWxbZy5vcmlnVHlwZV18fHt9KS5oYW5kbGV8fGcuaGFuZGxlcikuYXBwbHkoZi5lbGVtLGkpLHZvaWQgMCE9PWQmJihhLnJlc3VsdD1kKT09PSExJiYoYS5wcmV2ZW50RGVmYXVsdCgpLGEuc3RvcFByb3BhZ2F0aW9uKCkpKX1yZXR1cm4gay5wb3N0RGlzcGF0Y2gmJmsucG9zdERpc3BhdGNoLmNhbGwodGhpcyxhKSxhLnJlc3VsdH19LGhhbmRsZXJzOmZ1bmN0aW9uKGEsYil7dmFyIGMsZCxlLGYsZz1bXSxoPWIuZGVsZWdhdGVDb3VudCxpPWEudGFyZ2V0O2lmKGgmJmkubm9kZVR5cGUmJihcImNsaWNrXCIhPT1hLnR5cGV8fGlzTmFOKGEuYnV0dG9uKXx8YS5idXR0b248MSkpZm9yKDtpIT09dGhpcztpPWkucGFyZW50Tm9kZXx8dGhpcylpZigxPT09aS5ub2RlVHlwZSYmKGkuZGlzYWJsZWQhPT0hMHx8XCJjbGlja1wiIT09YS50eXBlKSl7Zm9yKGQ9W10sYz0wO2g+YztjKyspZj1iW2NdLGU9Zi5zZWxlY3RvcitcIiBcIix2b2lkIDA9PT1kW2VdJiYoZFtlXT1mLm5lZWRzQ29udGV4dD9uKGUsdGhpcykuaW5kZXgoaSk+LTE6bi5maW5kKGUsdGhpcyxudWxsLFtpXSkubGVuZ3RoKSxkW2VdJiZkLnB1c2goZik7ZC5sZW5ndGgmJmcucHVzaCh7ZWxlbTppLGhhbmRsZXJzOmR9KX1yZXR1cm4gaDxiLmxlbmd0aCYmZy5wdXNoKHtlbGVtOnRoaXMsaGFuZGxlcnM6Yi5zbGljZShoKX0pLGd9LHByb3BzOlwiYWx0S2V5IGJ1YmJsZXMgY2FuY2VsYWJsZSBjdHJsS2V5IGN1cnJlbnRUYXJnZXQgZGV0YWlsIGV2ZW50UGhhc2UgbWV0YUtleSByZWxhdGVkVGFyZ2V0IHNoaWZ0S2V5IHRhcmdldCB0aW1l
7437U3RhbXAgdmlldyB3aGljaFwiLnNwbGl0KFwiIFwiKSxmaXhIb29rczp7fSxrZXlIb29rczp7cHJvcHM6XCJjaGFyIGNoYXJDb2RlIGtleSBrZXlDb2RlXCIuc3BsaXQoXCIgXCIpLGZpbHRlcjpmdW5jdGlvbihhLGIpe3JldHVybiBudWxsPT1hLndoaWNoJiYoYS53aGljaD1udWxsIT1iLmNoYXJDb2RlP2IuY2hhckNvZGU6Yi5rZXlDb2RlKSxhfX0sbW91c2VIb29rczp7cHJvcHM6XCJidXR0b24gYnV0dG9ucyBjbGllbnRYIGNsaWVudFkgb2Zmc2V0WCBvZmZzZXRZIHBhZ2VYIHBhZ2VZIHNjcmVlblggc2NyZWVuWSB0b0VsZW1lbnRcIi5zcGxpdChcIiBcIiksZmlsdGVyOmZ1bmN0aW9uKGEsYil7dmFyIGMsZSxmLGc9Yi5idXR0b247cmV0dXJuIG51bGw9PWEucGFnZVgmJm51bGwhPWIuY2xpZW50WCYmKGM9YS50YXJnZXQub3duZXJEb2N1bWVudHx8ZCxlPWMuZG9jdW1lbnRFbGVtZW50LGY9Yy5ib2R5LGEucGFnZVg9Yi5jbGllbnRYKyhlJiZlLnNjcm9sbExlZnR8fGYmJmYuc2Nyb2xsTGVmdHx8MCktKGUmJmUuY2xpZW50TGVmdHx8ZiYmZi5jbGllbnRMZWZ0fHwwKSxhLnBhZ2VZPWIuY2xpZW50WSsoZSYmZS5zY3JvbGxUb3B8fGYmJmYuc2Nyb2xsVG9wfHwwKS0oZSYmZS5jbGllbnRUb3B8fGYmJmYuY2xpZW50VG9wfHwwKSksYS53aGljaHx8dm9pZCAwPT09Z3x8KGEud2hpY2g9MSZnPzE6MiZnPzM6NCZnPzI6MCksYX19LGZpeDpmdW5jdGlvbihhKXtpZihhW24uZXhwYW5kb10pcmV0dXJuIGE7dmFyIGIsYyxlLGY9YS50eXBlLGc9YSxoPXRoaXMuZml4SG9va3NbZl07aHx8KHRoaXMuZml4SG9va3NbZl09aD1lYS50ZXN0KGYpP3RoaXMubW91c2VIb29rczpkYS50ZXN0KGYpP3RoaXMua2V5SG9va3M6e30pLGU9aC5wcm9wcz90aGlzLnByb3BzLmNvbmNhdChoLnByb3BzKTp0aGlzLnByb3BzLGE9bmV3IG4uRXZlbnQoZyksYj1lLmxlbmd0aDt3aGlsZShiLS0pYz1lW2JdLGFbY109Z1tjXTtyZXR1cm4gYS50YXJnZXR8fChhLnRhcmdldD1kKSwzPT09YS50YXJnZXQubm9kZVR5cGUmJihhLnRhcmdldD1hLnRhcmdldC5wYXJlbnROb2RlKSxoLmZpbHRlcj9oLmZpbHRlcihhLGcpOmF9LHNwZWNpYWw6e2xvYWQ6e25vQnViYmxlOiEwfSxmb2N1czp7dHJpZ2dlcjpmdW5jdGlvbigpe3JldHVybiB0aGlzIT09aWEoKSYmdGhpcy5mb2N1cz8odGhpcy5mb2N1cygpLCExKTp2b2lkIDB9LGRlbGVnYXRlVHlwZTpcImZvY3VzaW5cIn0sYmx1cjp7dHJpZ2dlcjpmdW5jdGlvbigpe3JldHVybiB0aGlzPT09aWEoKSYmdGhpcy5ibHVyPyh0aGlzLmJsdXIoKSwhMSk6dm9pZCAwfSxkZWxlZ2F0ZVR5cGU6XCJmb2N1c291dFwifSxjbGljazp7dHJpZ2dlcjpmdW5jdGlvbigpe3JldHVyblwiY2hlY2tib3hcIj09PXRoaXMudHlwZSYmdGhpcy5jbGljayYmbi5ub2RlTmFtZSh0aGlzLFwiaW5wdXRcIik/KHRoaXMuY2xpY2soKSwhMSk6dm9pZCAwfSxfZGVmYXVsdDpmdW5jdGlvbihhKXtyZXR1cm4gbi5ub2RlTmFtZShhLnRhcmdldCxcImFcIil9fSxiZWZvcmV1bmxvYWQ6e3Bvc3REaXNwYXRjaDpmdW5jdGlvbihhKXt2b2lkIDAhPT1hLnJlc3VsdCYmYS5vcmlnaW5hbEV2ZW50JiYoYS5vcmlnaW5hbEV2ZW50LnJldHVyblZhbHVlPWEucmVzdWx0KX19fX0sbi5yZW1vdmVFdmVudD1mdW5jdGlvbihhLGIsYyl7YS5yZW1vdmVFdmVudExpc3RlbmVyJiZhLnJlbW92ZUV2ZW50TGlzdGVuZXIoYixjKX0sbi5FdmVudD1mdW5jdGlvbihhLGIpe3JldHVybiB0aGlzIGluc3RhbmNlb2Ygbi5FdmVudD8oYSYmYS50eXBlPyh0aGlzLm9yaWdpbmFsRXZlbnQ9YSx0aGlzLnR5cGU9YS50eXBlLHRoaXMuaXNEZWZhdWx0UHJldmVudGVkPWEuZGVmYXVsdFByZXZlbnRlZHx8dm9pZCAwPT09YS5kZWZhdWx0UHJldmVudGVkJiZhLnJldHVyblZhbHVlPT09ITE/Z2E6aGEpOnRoaXMudHlwZT1hLGImJm4uZXh0ZW5kKHRoaXMsYiksdGhpcy50aW1lU3RhbXA9YSYmYS50aW1lU3RhbXB8fG4ubm93KCksdm9pZCh0aGlzW24uZXhwYW5kb109ITApKTpuZXcgbi5FdmVudChhLGIpfSxuLkV2ZW50LnByb3RvdHlwZT17Y29uc3RydWN0b3I6bi5FdmVudCxpc0RlZmF1bHRQcmV2ZW50ZWQ6aGEsaXNQcm9wYWdhdGlvblN0b3BwZWQ6aGEsaXNJbW1lZGlhdGVQcm9wYWdhdGlvblN0b3BwZWQ6aGEsaXNTaW11bGF0ZWQ6ITEscHJldmVudERlZmF1bHQ6ZnVuY3Rpb24oKXt2YXIgYT10aGlzLm9yaWdpbmFsRXZlbnQ7dGhpcy5pc0RlZmF1bHRQcmV2ZW50ZWQ9Z2EsYSYmIXRoaXMuaXNTaW11bGF0ZWQmJmEucHJldmVudERlZmF1bHQoKX0sc3RvcFByb3BhZ2F0aW9uOmZ1bmN0aW9uKCl7dmFyIGE9dGhpcy5vcmlnaW5hbEV2ZW50O3RoaXMuaXNQcm9wYWdhdGlvblN0b3BwZWQ9Z2EsYSYmIXRoaXMuaXNTaW11bGF0ZWQmJmEuc3RvcFByb3BhZ2F0aW9uKCl9LHN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbjpmdW5jdGlvbigpe3ZhciBhPXRoaXMub3JpZ2luYWxFdmVudDt0aGlzLmlzSW1tZWRpYXRlUHJvcGFnYXRpb25TdG9wcGVkPWdhLGEmJiF0aGlzLmlzU2ltdWxhdGVkJiZhLnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpLHRoaXMuc3RvcFByb3BhZ2F0aW9uKCl9fSxuLmVhY2goe21vdXNlZW50ZXI6XCJtb3VzZW92ZXJcIixtb3VzZWxlYXZlOlwibW91c2VvdXRcIixwb2ludGVyZW50ZXI6XCJwb2ludGVyb3ZlclwiLHBvaW50ZXJsZWF2ZTpcInBvaW50ZXJvdXRcIn0sZnVuY3Rpb24oYSxiKXtuLmV2ZW50LnNwZWNpYWxbYV09e2RlbGVnYXRlVHlwZTpiLGJpbmRUeXBlOmIsaGFuZGxlOmZ1bmN0aW9uKGEpe3ZhciBjLGQ9dGhpcyxlPWEucmVsYXRlZFRhcmdldCxmPWEuaGFuZGxlT2JqO3JldHVybiBlJiYoZT09PWR8fG4uY29udGFpbnMoZCxlKSl8fChhLnR5cGU9Zi5vcmlnVHlwZSxjPWYuaGFuZGxlci5hcHBseSh0aGlzLGFyZ3VtZW50cyksYS50eXBlPWIpLGN9fX0pLG4uZm4uZXh0ZW5kKHtvbjpmdW5jdGlvbihhLGIsYyxkKXtyZXR1cm4gamEodGhpcyxhLGIsYyxkKX0sb25lOmZ1bmN0aW9uKGEsYixjLGQpe3JldHVybiBqYSh0aGlzLGEsYixjLGQsMSl9LG9mZjpmdW5jdGlvbihhLGIsYyl7dmFyIGQsZTtpZihhJiZhLnByZXZlbnREZWZhdWx0JiZhLmhhbmRsZU9iailyZXR1cm4gZD1hLmhhbmRsZU9iaixuKGEuZGVsZWdhdGVUYXJnZXQpLm9mZihkLm5hbWVzcGFjZT9kLm9yaWdUeXBlK1wiLlwiK2QubmFtZXNwYWNlOmQub3JpZ1R5cGUsZC5zZWxlY3RvcixkLmhhbmRsZXIpLHRoaXM7aWYoXCJvYmplY3RcIj09dHlwZW9mIGEpe2ZvcihlIGluIGEpdGhpcy5vZmYoZSxiLGFbZV0pO3JldHVybiB0aGlzfXJldHVybi
7437BiIT09ITEmJlwiZnVuY3Rpb25cIiE9dHlwZW9mIGJ8fChjPWIsYj12b2lkIDApLGM9PT0hMSYmKGM9aGEpLHRoaXMuZWFjaChmdW5jdGlvbigpe24uZXZlbnQucmVtb3ZlKHRoaXMsYSxjLGIpfSl9fSk7dmFyIGthPS88KD8hYXJlYXxicnxjb2x8ZW1iZWR8aHJ8aW1nfGlucHV0fGxpbmt8bWV0YXxwYXJhbSkoKFtcXHc6LV0rKVtePl0qKVxcLz4vZ2ksbGE9LzxzY3JpcHR8PHN0eWxlfDxsaW5rL2ksbWE9L2NoZWNrZWRcXHMqKD86W149XXw9XFxzKi5jaGVja2VkLikvaSxuYT0vXnRydWVcXC8oLiopLyxvYT0vXlxccyo8ISg/OlxcW0NEQVRBXFxbfC0tKXwoPzpcXF1cXF18LS0pPlxccyokL2c7ZnVuY3Rpb24gcGEoYSxiKXtyZXR1cm4gbi5ub2RlTmFtZShhLFwidGFibGVcIikmJm4ubm9kZU5hbWUoMTEhPT1iLm5vZGVUeXBlP2I6Yi5maXJzdENoaWxkLFwidHJcIik/YS5nZXRFbGVtZW50c0J5VGFnTmFtZShcInRib2R5XCIpWzBdfHxhLmFwcGVuZENoaWxkKGEub3duZXJEb2N1bWVudC5jcmVhdGVFbGVtZW50KFwidGJvZHlcIikpOmF9ZnVuY3Rpb24gcWEoYSl7cmV0dXJuIGEudHlwZT0obnVsbCE9PWEuZ2V0QXR0cmlidXRlKFwidHlwZVwiKSkrXCIvXCIrYS50eXBlLGF9ZnVuY3Rpb24gcmEoYSl7dmFyIGI9bmEuZXhlYyhhLnR5cGUpO3JldHVybiBiP2EudHlwZT1iWzFdOmEucmVtb3ZlQXR0cmlidXRlKFwidHlwZVwiKSxhfWZ1bmN0aW9uIHNhKGEsYil7dmFyIGMsZCxlLGYsZyxoLGksajtpZigxPT09Yi5ub2RlVHlwZSl7aWYoTi5oYXNEYXRhKGEpJiYoZj1OLmFjY2VzcyhhKSxnPU4uc2V0KGIsZiksaj1mLmV2ZW50cykpe2RlbGV0ZSBnLmhhbmRsZSxnLmV2ZW50cz17fTtmb3IoZSBpbiBqKWZvcihjPTAsZD1qW2VdLmxlbmd0aDtkPmM7YysrKW4uZXZlbnQuYWRkKGIsZSxqW2VdW2NdKX1PLmhhc0RhdGEoYSkmJihoPU8uYWNjZXNzKGEpLGk9bi5leHRlbmQoe30saCksTy5zZXQoYixpKSl9fWZ1bmN0aW9uIHRhKGEsYil7dmFyIGM9Yi5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1wiaW5wdXRcIj09PWMmJlgudGVzdChhLnR5cGUpP2IuY2hlY2tlZD1hLmNoZWNrZWQ6XCJpbnB1dFwiIT09YyYmXCJ0ZXh0YXJlYVwiIT09Y3x8KGIuZGVmYXVsdFZhbHVlPWEuZGVmYXVsdFZhbHVlKX1mdW5jdGlvbiB1YShhLGIsYyxkKXtiPWYuYXBwbHkoW10sYik7dmFyIGUsZyxoLGksaixrLG09MCxvPWEubGVuZ3RoLHA9by0xLHE9YlswXSxyPW4uaXNGdW5jdGlvbihxKTtpZihyfHxvPjEmJlwic3RyaW5nXCI9PXR5cGVvZiBxJiYhbC5jaGVja0Nsb25lJiZtYS50ZXN0KHEpKXJldHVybiBhLmVhY2goZnVuY3Rpb24oZSl7dmFyIGY9YS5lcShlKTtyJiYoYlswXT1xLmNhbGwodGhpcyxlLGYuaHRtbCgpKSksdWEoZixiLGMsZCl9KTtpZihvJiYoZT1jYShiLGFbMF0ub3duZXJEb2N1bWVudCwhMSxhLGQpLGc9ZS5maXJzdENoaWxkLDE9PT1lLmNoaWxkTm9kZXMubGVuZ3RoJiYoZT1nKSxnfHxkKSl7Zm9yKGg9bi5tYXAoXyhlLFwic2NyaXB0XCIpLHFhKSxpPWgubGVuZ3RoO28+bTttKyspaj1lLG0hPT1wJiYoaj1uLmNsb25lKGosITAsITApLGkmJm4ubWVyZ2UoaCxfKGosXCJzY3JpcHRcIikpKSxjLmNhbGwoYVttXSxqLG0pO2lmKGkpZm9yKGs9aFtoLmxlbmd0aC0xXS5vd25lckRvY3VtZW50LG4ubWFwKGgscmEpLG09MDtpPm07bSsrKWo9aFttXSxaLnRlc3Qoai50eXBlfHxcIlwiKSYmIU4uYWNjZXNzKGosXCJnbG9iYWxFdmFsXCIpJiZuLmNvbnRhaW5zKGssaikmJihqLnNyYz9uLl9ldmFsVXJsJiZuLl9ldmFsVXJsKGouc3JjKTpuLmdsb2JhbEV2YWwoai50ZXh0Q29udGVudC5yZXBsYWNlKG9hLFwiXCIpKSl9cmV0dXJuIGF9ZnVuY3Rpb24gdmEoYSxiLGMpe2Zvcih2YXIgZCxlPWI/bi5maWx0ZXIoYixhKTphLGY9MDtudWxsIT0oZD1lW2ZdKTtmKyspY3x8MSE9PWQubm9kZVR5cGV8fG4uY2xlYW5EYXRhKF8oZCkpLGQucGFyZW50Tm9kZSYmKGMmJm4uY29udGFpbnMoZC5vd25lckRvY3VtZW50LGQpJiZhYShfKGQsXCJzY3JpcHRcIikpLGQucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChkKSk7cmV0dXJuIGF9bi5leHRlbmQoe2h0bWxQcmVmaWx0ZXI6ZnVuY3Rpb24oYSl7cmV0dXJuIGEucmVwbGFjZShrYSxcIjwkMT48LyQyPlwiKX0sY2xvbmU6ZnVuY3Rpb24oYSxiLGMpe3ZhciBkLGUsZixnLGg9YS5jbG9uZU5vZGUoITApLGk9bi5jb250YWlucyhhLm93bmVyRG9jdW1lbnQsYSk7aWYoIShsLm5vQ2xvbmVDaGVja2VkfHwxIT09YS5ub2RlVHlwZSYmMTEhPT1hLm5vZGVUeXBlfHxuLmlzWE1MRG9jKGEpKSlmb3IoZz1fKGgpLGY9XyhhKSxkPTAsZT1mLmxlbmd0aDtlPmQ7ZCsrKXRhKGZbZF0sZ1tkXSk7aWYoYilpZihjKWZvcihmPWZ8fF8oYSksZz1nfHxfKGgpLGQ9MCxlPWYubGVuZ3RoO2U+ZDtkKyspc2EoZltkXSxnW2RdKTtlbHNlIHNhKGEsaCk7cmV0dXJuIGc9XyhoLFwic2NyaXB0XCIpLGcubGVuZ3RoPjAmJmFhKGcsIWkmJl8oYSxcInNjcmlwdFwiKSksaH0sY2xlYW5EYXRhOmZ1bmN0aW9uKGEpe2Zvcih2YXIgYixjLGQsZT1uLmV2ZW50LnNwZWNpYWwsZj0wO3ZvaWQgMCE9PShjPWFbZl0pO2YrKylpZihMKGMpKXtpZihiPWNbTi5leHBhbmRvXSl7aWYoYi5ldmVudHMpZm9yKGQgaW4gYi5ldmVudHMpZVtkXT9uLmV2ZW50LnJlbW92ZShjLGQpOm4ucmVtb3ZlRXZlbnQoYyxkLGIuaGFuZGxlKTtjW04uZXhwYW5kb109dm9pZCAwfWNbTy5leHBhbmRvXSYmKGNbTy5leHBhbmRvXT12b2lkIDApfX19KSxuLmZuLmV4dGVuZCh7ZG9tTWFuaXA6dWEsZGV0YWNoOmZ1bmN0aW9uKGEpe3JldHVybiB2YSh0aGlzLGEsITApfSxyZW1vdmU6ZnVuY3Rpb24oYSl7cmV0dXJuIHZhKHRoaXMsYSl9LHRleHQ6ZnVuY3Rpb24oYSl7cmV0dXJuIEsodGhpcyxmdW5jdGlvbihhKXtyZXR1cm4gdm9pZCAwPT09YT9uLnRleHQodGhpcyk6dGhpcy5lbXB0eSgpLmVhY2goZnVuY3Rpb24oKXsxIT09dGhpcy5ub2RlVHlwZSYmMTEhPT10aGlzLm5vZGVUeXBlJiY5IT09dGhpcy5ub2RlVHlwZXx8KHRoaXMudGV4dENvbnRlbnQ9YSl9KX0sbnVsbCxhLGFyZ3VtZW50cy5sZW5ndGgpfSxhcHBlbmQ6ZnVuY3Rpb24oKXtyZXR1cm4gdWEodGhpcyxhcmd1bWVudHMsZnVuY3Rpb24oYSl7aWYoMT09PXRoaXMubm9kZVR5cGV8fDExPT09dGhpcy5ub2RlVHlwZXx8OT09PXRoaXMubm9kZVR5cGUpe3ZhciBiPXBhKHRoaXMsYSk7Yi5hc
7437HBlbmRDaGlsZChhKX19KX0scHJlcGVuZDpmdW5jdGlvbigpe3JldHVybiB1YSh0aGlzLGFyZ3VtZW50cyxmdW5jdGlvbihhKXtpZigxPT09dGhpcy5ub2RlVHlwZXx8MTE9PT10aGlzLm5vZGVUeXBlfHw5PT09dGhpcy5ub2RlVHlwZSl7dmFyIGI9cGEodGhpcyxhKTtiLmluc2VydEJlZm9yZShhLGIuZmlyc3RDaGlsZCl9fSl9LGJlZm9yZTpmdW5jdGlvbigpe3JldHVybiB1YSh0aGlzLGFyZ3VtZW50cyxmdW5jdGlvbihhKXt0aGlzLnBhcmVudE5vZGUmJnRoaXMucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoYSx0aGlzKX0pfSxhZnRlcjpmdW5jdGlvbigpe3JldHVybiB1YSh0aGlzLGFyZ3VtZW50cyxmdW5jdGlvbihhKXt0aGlzLnBhcmVudE5vZGUmJnRoaXMucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoYSx0aGlzLm5leHRTaWJsaW5nKX0pfSxlbXB0eTpmdW5jdGlvbigpe2Zvcih2YXIgYSxiPTA7bnVsbCE9KGE9dGhpc1tiXSk7YisrKTE9PT1hLm5vZGVUeXBlJiYobi5jbGVhbkRhdGEoXyhhLCExKSksYS50ZXh0Q29udGVudD1cIlwiKTtyZXR1cm4gdGhpc30sY2xvbmU6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gYT1udWxsPT1hPyExOmEsYj1udWxsPT1iP2E6Yix0aGlzLm1hcChmdW5jdGlvbigpe3JldHVybiBuLmNsb25lKHRoaXMsYSxiKX0pfSxodG1sOmZ1bmN0aW9uKGEpe3JldHVybiBLKHRoaXMsZnVuY3Rpb24oYSl7dmFyIGI9dGhpc1swXXx8e30sYz0wLGQ9dGhpcy5sZW5ndGg7aWYodm9pZCAwPT09YSYmMT09PWIubm9kZVR5cGUpcmV0dXJuIGIuaW5uZXJIVE1MO2lmKFwic3RyaW5nXCI9PXR5cGVvZiBhJiYhbGEudGVzdChhKSYmISRbKFkuZXhlYyhhKXx8W1wiXCIsXCJcIl0pWzFdLnRvTG93ZXJDYXNlKCldKXthPW4uaHRtbFByZWZpbHRlcihhKTt0cnl7Zm9yKDtkPmM7YysrKWI9dGhpc1tjXXx8e30sMT09PWIubm9kZVR5cGUmJihuLmNsZWFuRGF0YShfKGIsITEpKSxiLmlubmVySFRNTD1hKTtiPTB9Y2F0Y2goZSl7fX1iJiZ0aGlzLmVtcHR5KCkuYXBwZW5kKGEpfSxudWxsLGEsYXJndW1lbnRzLmxlbmd0aCl9LHJlcGxhY2VXaXRoOmZ1bmN0aW9uKCl7dmFyIGE9W107cmV0dXJuIHVhKHRoaXMsYXJndW1lbnRzLGZ1bmN0aW9uKGIpe3ZhciBjPXRoaXMucGFyZW50Tm9kZTtuLmluQXJyYXkodGhpcyxhKTwwJiYobi5jbGVhbkRhdGEoXyh0aGlzKSksYyYmYy5yZXBsYWNlQ2hpbGQoYix0aGlzKSl9LGEpfX0pLG4uZWFjaCh7YXBwZW5kVG86XCJhcHBlbmRcIixwcmVwZW5kVG86XCJwcmVwZW5kXCIsaW5zZXJ0QmVmb3JlOlwiYmVmb3JlXCIsaW5zZXJ0QWZ0ZXI6XCJhZnRlclwiLHJlcGxhY2VBbGw6XCJyZXBsYWNlV2l0aFwifSxmdW5jdGlvbihhLGIpe24uZm5bYV09ZnVuY3Rpb24oYSl7Zm9yKHZhciBjLGQ9W10sZT1uKGEpLGY9ZS5sZW5ndGgtMSxoPTA7Zj49aDtoKyspYz1oPT09Zj90aGlzOnRoaXMuY2xvbmUoITApLG4oZVtoXSlbYl0oYyksZy5hcHBseShkLGMuZ2V0KCkpO3JldHVybiB0aGlzLnB1c2hTdGFjayhkKX19KTt2YXIgd2EseGE9e0hUTUw6XCJibG9ja1wiLEJPRFk6XCJibG9ja1wifTtmdW5jdGlvbiB5YShhLGIpe3ZhciBjPW4oYi5jcmVhdGVFbGVtZW50KGEpKS5hcHBlbmRUbyhiLmJvZHkpLGQ9bi5jc3MoY1swXSxcImRpc3BsYXlcIik7cmV0dXJuIGMuZGV0YWNoKCksZH1mdW5jdGlvbiB6YShhKXt2YXIgYj1kLGM9eGFbYV07cmV0dXJuIGN8fChjPXlhKGEsYiksXCJub25lXCIhPT1jJiZjfHwod2E9KHdhfHxuKFwiPGlmcmFtZSBmcmFtZWJvcmRlcj0nMCcgd2lkdGg9JzAnIGhlaWdodD0nMCcvPlwiKSkuYXBwZW5kVG8oYi5kb2N1bWVudEVsZW1lbnQpLGI9d2FbMF0uY29udGVudERvY3VtZW50LGIud3JpdGUoKSxiLmNsb3NlKCksYz15YShhLGIpLHdhLmRldGFjaCgpKSx4YVthXT1jKSxjfXZhciBBYT0vXm1hcmdpbi8sQmE9bmV3IFJlZ0V4cChcIl4oXCIrUytcIikoPyFweClbYS16JV0rJFwiLFwiaVwiKSxDYT1mdW5jdGlvbihiKXt2YXIgYz1iLm93bmVyRG9jdW1lbnQuZGVmYXVsdFZpZXc7cmV0dXJuIGMmJmMub3BlbmVyfHwoYz1hKSxjLmdldENvbXB1dGVkU3R5bGUoYil9LERhPWZ1bmN0aW9uKGEsYixjLGQpe3ZhciBlLGYsZz17fTtmb3IoZiBpbiBiKWdbZl09YS5zdHlsZVtmXSxhLnN0eWxlW2ZdPWJbZl07ZT1jLmFwcGx5KGEsZHx8W10pO2ZvcihmIGluIGIpYS5zdHlsZVtmXT1nW2ZdO3JldHVybiBlfSxFYT1kLmRvY3VtZW50RWxlbWVudDshZnVuY3Rpb24oKXt2YXIgYixjLGUsZixnPWQuY3JlYXRlRWxlbWVudChcImRpdlwiKSxoPWQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtpZihoLnN0eWxlKXtoLnN0eWxlLmJhY2tncm91bmRDbGlwPVwiY29udGVudC1ib3hcIixoLmNsb25lTm9kZSghMCkuc3R5bGUuYmFja2dyb3VuZENsaXA9XCJcIixsLmNsZWFyQ2xvbmVTdHlsZT1cImNvbnRlbnQtYm94XCI9PT1oLnN0eWxlLmJhY2tncm91bmRDbGlwLGcuc3R5bGUuY3NzVGV4dD1cImJvcmRlcjowO3dpZHRoOjhweDtoZWlnaHQ6MDt0b3A6MDtsZWZ0Oi05OTk5cHg7cGFkZGluZzowO21hcmdpbi10b3A6MXB4O3Bvc2l0aW9uOmFic29sdXRlXCIsZy5hcHBlbmRDaGlsZChoKTtmdW5jdGlvbiBpKCl7aC5zdHlsZS5jc3NUZXh0PVwiLXdlYmtpdC1ib3gtc2l6aW5nOmJvcmRlci1ib3g7LW1vei1ib3gtc2l6aW5nOmJvcmRlci1ib3g7Ym94LXNpemluZzpib3JkZXItYm94O3Bvc2l0aW9uOnJlbGF0aXZlO2Rpc3BsYXk6YmxvY2s7bWFyZ2luOmF1dG87Ym9yZGVyOjFweDtwYWRkaW5nOjFweDt0b3A6MSU7d2lkdGg6NTAlXCIsaC5pbm5lckhUTUw9XCJcIixFYS5hcHBlbmRDaGlsZChnKTt2YXIgZD1hLmdldENvbXB1dGVkU3R5bGUoaCk7Yj1cIjElXCIhPT1kLnRvcCxmPVwiMnB4XCI9PT1kLm1hcmdpbkxlZnQsYz1cIjRweFwiPT09ZC53aWR0aCxoLnN0eWxlLm1hcmdpblJpZ2h0PVwiNTAlXCIsZT1cIjRweFwiPT09ZC5tYXJnaW5SaWdodCxFYS5yZW1vdmVDaGlsZChnKX1uLmV4dGVuZChsLHtwaXhlbFBvc2l0aW9uOmZ1bmN0aW9uKCl7cmV0dXJuIGkoKSxifSxib3hTaXppbmdSZWxpYWJsZTpmdW5jdGlvbigpe3JldHVybiBudWxsPT1jJiZpKCksY30scGl4ZWxNYXJnaW5SaWdodDpmdW5jdGlvbigpe3JldHVybiBudWxsPT1jJiZpKCksZX0scmVsaWFibGVNYXJnaW5MZWZ0OmZ1bmN0aW9uKCl7cmV0dXJuIG51bGw9PWMmJmkoKSxmfSxyZWxpYWJsZU1hcmdpblJpZ2h0OmZ1bmN0aW9uKCl7dmFyIGIsYz1oLmFwcGVuZENoaWxkKGQuY3JlYXRlRWxlbWVudChcImRpdlwiKSk7cmV0dXJuIGMuc3R5bGUuY3NzVGV4dD1oLnN0eWxlLmNzc1RleHQ9XCItd2Via2l0LWJveC1zaXppbmc6Y29udGVudC1ib3g7Ym94LXNpemluZzpjb250ZW50LWJveDtkaXNwbGF5OmJsb2NrO21hcmdpbjowO2JvcmRlcjowO3BhZGRpbmc6MFwiLGMuc3R5bGUubWFyZ2luUmlnaHQ9Yy5zdHlsZS53aWR0aD1cIjBcIixoLnN0eWxlLndpZHRoPVwiMXB4XCIsRWEuYXBwZW5kQ2hpbGQoZyksYj0hcGFyc2VGbG9hdChhLmdldENvbXB1dGVkU3R5bGUoYykubWFyZ2luUmlnaHQpLEVhLnJlbW92ZUNoaWxkKGcpLGgucmVtb3ZlQ2hpbGQoYyksYn19KX19KCk7ZnVuY3Rpb24gRmEoYSxiLGMpe3ZhciBkLGUsZixnLGg9YS5zdHlsZTtyZXR1cm4gYz1jfHxDYShhKSxnPWM/Yy5nZXRQcm9wZXJ0eVZhbHVlKGIpfHxjW2JdOnZvaWQgMCxcIlwiIT09ZyYmdm9pZCAwIT09Z3x8bi5jb250YWlucyhhLm93bmVyRG9jdW1lbnQsYSl8fChnPW4uc3R5bGUoYSxiKSksYyYmIWwucGl4ZWxNYXJnaW5SaWdodCgpJiZCYS50ZXN0KGcpJiZBYS50ZXN0KGIpJiYoZD1oLndpZHRoLGU9aC5taW5XaWR0aCxmPWgubWF4V2lkdGgsaC5taW5XaWR0aD1oLm1heFdpZHRoPWgud2lkdGg9ZyxnPWMud2lkdGgsaC53aWR0aD1kLGgubWluV2lk
7437dGg9ZSxoLm1heFdpZHRoPWYpLHZvaWQgMCE9PWc/ZytcIlwiOmd9ZnVuY3Rpb24gR2EoYSxiKXtyZXR1cm57Z2V0OmZ1bmN0aW9uKCl7cmV0dXJuIGEoKT92b2lkIGRlbGV0ZSB0aGlzLmdldDoodGhpcy5nZXQ9YikuYXBwbHkodGhpcyxhcmd1bWVudHMpfX19dmFyIEhhPS9eKG5vbmV8dGFibGUoPyEtY1tlYV0pLispLyxJYT17cG9zaXRpb246XCJhYnNvbHV0ZVwiLHZpc2liaWxpdHk6XCJoaWRkZW5cIixkaXNwbGF5OlwiYmxvY2tcIn0sSmE9e2xldHRlclNwYWNpbmc6XCIwXCIsZm9udFdlaWdodDpcIjQwMFwifSxLYT1bXCJXZWJraXRcIixcIk9cIixcIk1velwiLFwibXNcIl0sTGE9ZC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpLnN0eWxlO2Z1bmN0aW9uIE1hKGEpe2lmKGEgaW4gTGEpcmV0dXJuIGE7dmFyIGI9YVswXS50b1VwcGVyQ2FzZSgpK2Euc2xpY2UoMSksYz1LYS5sZW5ndGg7d2hpbGUoYy0tKWlmKGE9S2FbY10rYixhIGluIExhKXJldHVybiBhfWZ1bmN0aW9uIE5hKGEsYixjKXt2YXIgZD1ULmV4ZWMoYik7cmV0dXJuIGQ/TWF0aC5tYXgoMCxkWzJdLShjfHwwKSkrKGRbM118fFwicHhcIik6Yn1mdW5jdGlvbiBPYShhLGIsYyxkLGUpe2Zvcih2YXIgZj1jPT09KGQ/XCJib3JkZXJcIjpcImNvbnRlbnRcIik/NDpcIndpZHRoXCI9PT1iPzE6MCxnPTA7ND5mO2YrPTIpXCJtYXJnaW5cIj09PWMmJihnKz1uLmNzcyhhLGMrVVtmXSwhMCxlKSksZD8oXCJjb250ZW50XCI9PT1jJiYoZy09bi5jc3MoYSxcInBhZGRpbmdcIitVW2ZdLCEwLGUpKSxcIm1hcmdpblwiIT09YyYmKGctPW4uY3NzKGEsXCJib3JkZXJcIitVW2ZdK1wiV2lkdGhcIiwhMCxlKSkpOihnKz1uLmNzcyhhLFwicGFkZGluZ1wiK1VbZl0sITAsZSksXCJwYWRkaW5nXCIhPT1jJiYoZys9bi5jc3MoYSxcImJvcmRlclwiK1VbZl0rXCJXaWR0aFwiLCEwLGUpKSk7cmV0dXJuIGd9ZnVuY3Rpb24gUGEoYSxiLGMpe3ZhciBkPSEwLGU9XCJ3aWR0aFwiPT09Yj9hLm9mZnNldFdpZHRoOmEub2Zmc2V0SGVpZ2h0LGY9Q2EoYSksZz1cImJvcmRlci1ib3hcIj09PW4uY3NzKGEsXCJib3hTaXppbmdcIiwhMSxmKTtpZigwPj1lfHxudWxsPT1lKXtpZihlPUZhKGEsYixmKSwoMD5lfHxudWxsPT1lKSYmKGU9YS5zdHlsZVtiXSksQmEudGVzdChlKSlyZXR1cm4gZTtkPWcmJihsLmJveFNpemluZ1JlbGlhYmxlKCl8fGU9PT1hLnN0eWxlW2JdKSxlPXBhcnNlRmxvYXQoZSl8fDB9cmV0dXJuIGUrT2EoYSxiLGN8fChnP1wiYm9yZGVyXCI6XCJjb250ZW50XCIpLGQsZikrXCJweFwifWZ1bmN0aW9uIFFhKGEsYil7Zm9yKHZhciBjLGQsZSxmPVtdLGc9MCxoPWEubGVuZ3RoO2g+ZztnKyspZD1hW2ddLGQuc3R5bGUmJihmW2ddPU4uZ2V0KGQsXCJvbGRkaXNwbGF5XCIpLGM9ZC5zdHlsZS5kaXNwbGF5LGI/KGZbZ118fFwibm9uZVwiIT09Y3x8KGQuc3R5bGUuZGlzcGxheT1cIlwiKSxcIlwiPT09ZC5zdHlsZS5kaXNwbGF5JiZWKGQpJiYoZltnXT1OLmFjY2VzcyhkLFwib2xkZGlzcGxheVwiLHphKGQubm9kZU5hbWUpKSkpOihlPVYoZCksXCJub25lXCI9PT1jJiZlfHxOLnNldChkLFwib2xkZGlzcGxheVwiLGU/YzpuLmNzcyhkLFwiZGlzcGxheVwiKSkpKTtmb3IoZz0wO2g+ZztnKyspZD1hW2ddLGQuc3R5bGUmJihiJiZcIm5vbmVcIiE9PWQuc3R5bGUuZGlzcGxheSYmXCJcIiE9PWQuc3R5bGUuZGlzcGxheXx8KGQuc3R5bGUuZGlzcGxheT1iP2ZbZ118fFwiXCI6XCJub25lXCIpKTtyZXR1cm4gYX1uLmV4dGVuZCh7Y3NzSG9va3M6e29wYWNpdHk6e2dldDpmdW5jdGlvbihhLGIpe2lmKGIpe3ZhciBjPUZhKGEsXCJvcGFjaXR5XCIpO3JldHVyblwiXCI9PT1jP1wiMVwiOmN9fX19LGNzc051bWJlcjp7YW5pbWF0aW9uSXRlcmF0aW9uQ291bnQ6ITAsY29sdW1uQ291bnQ6ITAsZmlsbE9wYWNpdHk6ITAsZmxleEdyb3c6ITAsZmxleFNocmluazohMCxmb250V2VpZ2h0OiEwLGxpbmVIZWlnaHQ6ITAsb3BhY2l0eTohMCxvcmRlcjohMCxvcnBoYW5zOiEwLHdpZG93czohMCx6SW5kZXg6ITAsem9vbTohMH0sY3NzUHJvcHM6e1wiZmxvYXRcIjpcImNzc0Zsb2F0XCJ9LHN0eWxlOmZ1bmN0aW9uKGEsYixjLGQpe2lmKGEmJjMhPT1hLm5vZGVUeXBlJiY4IT09YS5ub2RlVHlwZSYmYS5zdHlsZSl7dmFyIGUsZixnLGg9bi5jYW1lbENhc2UoYiksaT1hLnN0eWxlO3JldHVybiBiPW4uY3NzUHJvcHNbaF18fChuLmNzc1Byb3BzW2hdPU1hKGgpfHxoKSxnPW4uY3NzSG9va3NbYl18fG4uY3NzSG9va3NbaF0sdm9pZCAwPT09Yz9nJiZcImdldFwiaW4gZyYmdm9pZCAwIT09KGU9Zy5nZXQoYSwhMSxkKSk/ZTppW2JdOihmPXR5cGVvZiBjLFwic3RyaW5nXCI9PT1mJiYoZT1ULmV4ZWMoYykpJiZlWzFdJiYoYz1XKGEsYixlKSxmPVwibnVtYmVyXCIpLG51bGwhPWMmJmM9PT1jJiYoXCJudW1iZXJcIj09PWYmJihjKz1lJiZlWzNdfHwobi5jc3NOdW1iZXJbaF0/XCJcIjpcInB4XCIpKSxsLmNsZWFyQ2xvbmVTdHlsZXx8XCJcIiE9PWN8fDAhPT1iLmluZGV4T2YoXCJiYWNrZ3JvdW5kXCIpfHwoaVtiXT1cImluaGVyaXRcIiksZyYmXCJzZXRcImluIGcmJnZvaWQgMD09PShjPWcuc2V0KGEsYyxkKSl8fChpW2JdPWMpKSx2b2lkIDApfX0sY3NzOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBlLGYsZyxoPW4uY2FtZWxDYXNlKGIpO3JldHVybiBiPW4uY3NzUHJvcHNbaF18fChuLmNzc1Byb3BzW2hdPU1hKGgpfHxoKSxnPW4uY3NzSG9va3NbYl18fG4uY3NzSG9va3NbaF0sZyYmXCJnZXRcImluIGcmJihlPWcuZ2V0KGEsITAsYykpLHZvaWQgMD09PWUmJihlPUZhKGEsYixkKSksXCJub3JtYWxcIj09PWUmJmIgaW4gSmEmJihlPUphW2JdKSxcIlwiPT09Y3x8Yz8oZj1wYXJzZUZsb2F0KGUpLGM9PT0hMHx8aXNGaW5pdGUoZik/Znx8MDplKTplfX0pLG4uZWFjaChbXCJoZWlnaHRcIixcIndpZHRoXCJdLGZ1bmN0aW9uKGEsYil7bi5jc3NIb29rc1tiXT17Z2V0OmZ1bmN0aW9uKGEsYyxkKXtyZXR1cm4gYz9IYS50ZXN0KG4uY3NzKGEsXCJkaXNwbGF5XCIpKSYmMD09PWEub2Zmc2V0V2lkdGg/RGEoYSxJYSxmdW5jdGlvbigpe3JldHVybiBQYShhLGIsZCl9KTpQYShhLGIsZCk6dm9pZCAwfSxzZXQ6ZnVuY3Rpb24oYSxjLGQpe3ZhciBlLGY9ZCYmQ2EoYSksZz1kJiZPYShhLGIsZCxcImJvcmRlci1ib3hcIj09PW4uY3NzKGEsXCJib3hTaXppbmdcIiwhMSxmKSxmKTtyZXR1cm4gZyYmKGU9VC5leGVjKGMpKSYmXCJweFwiIT09KGVbM118fFwicHhcIikmJihhLnN0eWxlW2JdPWMsYz1uLmNzcyhhLGIpKSxOYShhLGMsZyl9fX0pLG4uY3NzSG9va3MubWFyZ2luTGVmdD1HYShsLnJlbGlhYmxlTWFyZ2luTGVmdCxmdW5jdGlvbihhLGIpe3JldHVybiBiPyhwYXJzZU
7437Zsb2F0KEZhKGEsXCJtYXJnaW5MZWZ0XCIpKXx8YS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5sZWZ0LURhKGEse21hcmdpbkxlZnQ6MH0sZnVuY3Rpb24oKXtyZXR1cm4gYS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5sZWZ0fSkpK1wicHhcIjp2b2lkIDB9KSxuLmNzc0hvb2tzLm1hcmdpblJpZ2h0PUdhKGwucmVsaWFibGVNYXJnaW5SaWdodCxmdW5jdGlvbihhLGIpe3JldHVybiBiP0RhKGEse2Rpc3BsYXk6XCJpbmxpbmUtYmxvY2tcIn0sRmEsW2EsXCJtYXJnaW5SaWdodFwiXSk6dm9pZCAwfSksbi5lYWNoKHttYXJnaW46XCJcIixwYWRkaW5nOlwiXCIsYm9yZGVyOlwiV2lkdGhcIn0sZnVuY3Rpb24oYSxiKXtuLmNzc0hvb2tzW2ErYl09e2V4cGFuZDpmdW5jdGlvbihjKXtmb3IodmFyIGQ9MCxlPXt9LGY9XCJzdHJpbmdcIj09dHlwZW9mIGM/Yy5zcGxpdChcIiBcIik6W2NdOzQ+ZDtkKyspZVthK1VbZF0rYl09ZltkXXx8ZltkLTJdfHxmWzBdO3JldHVybiBlfX0sQWEudGVzdChhKXx8KG4uY3NzSG9va3NbYStiXS5zZXQ9TmEpfSksbi5mbi5leHRlbmQoe2NzczpmdW5jdGlvbihhLGIpe3JldHVybiBLKHRoaXMsZnVuY3Rpb24oYSxiLGMpe3ZhciBkLGUsZj17fSxnPTA7aWYobi5pc0FycmF5KGIpKXtmb3IoZD1DYShhKSxlPWIubGVuZ3RoO2U+ZztnKyspZltiW2ddXT1uLmNzcyhhLGJbZ10sITEsZCk7cmV0dXJuIGZ9cmV0dXJuIHZvaWQgMCE9PWM/bi5zdHlsZShhLGIsYyk6bi5jc3MoYSxiKX0sYSxiLGFyZ3VtZW50cy5sZW5ndGg+MSl9LHNob3c6ZnVuY3Rpb24oKXtyZXR1cm4gUWEodGhpcywhMCl9LGhpZGU6ZnVuY3Rpb24oKXtyZXR1cm4gUWEodGhpcyl9LHRvZ2dsZTpmdW5jdGlvbihhKXtyZXR1cm5cImJvb2xlYW5cIj09dHlwZW9mIGE/YT90aGlzLnNob3coKTp0aGlzLmhpZGUoKTp0aGlzLmVhY2goZnVuY3Rpb24oKXtWKHRoaXMpP24odGhpcykuc2hvdygpOm4odGhpcykuaGlkZSgpfSl9fSk7ZnVuY3Rpb24gUmEoYSxiLGMsZCxlKXtyZXR1cm4gbmV3IFJhLnByb3RvdHlwZS5pbml0KGEsYixjLGQsZSl9bi5Ud2Vlbj1SYSxSYS5wcm90b3R5cGU9e2NvbnN0cnVjdG9yOlJhLGluaXQ6ZnVuY3Rpb24oYSxiLGMsZCxlLGYpe3RoaXMuZWxlbT1hLHRoaXMucHJvcD1jLHRoaXMuZWFzaW5nPWV8fG4uZWFzaW5nLl9kZWZhdWx0LHRoaXMub3B0aW9ucz1iLHRoaXMuc3RhcnQ9dGhpcy5ub3c9dGhpcy5jdXIoKSx0aGlzLmVuZD1kLHRoaXMudW5pdD1mfHwobi5jc3NOdW1iZXJbY10/XCJcIjpcInB4XCIpfSxjdXI6ZnVuY3Rpb24oKXt2YXIgYT1SYS5wcm9wSG9va3NbdGhpcy5wcm9wXTtyZXR1cm4gYSYmYS5nZXQ/YS5nZXQodGhpcyk6UmEucHJvcEhvb2tzLl9kZWZhdWx0LmdldCh0aGlzKX0scnVuOmZ1bmN0aW9uKGEpe3ZhciBiLGM9UmEucHJvcEhvb2tzW3RoaXMucHJvcF07cmV0dXJuIHRoaXMub3B0aW9ucy5kdXJhdGlvbj90aGlzLnBvcz1iPW4uZWFzaW5nW3RoaXMuZWFzaW5nXShhLHRoaXMub3B0aW9ucy5kdXJhdGlvbiphLDAsMSx0aGlzLm9wdGlvbnMuZHVyYXRpb24pOnRoaXMucG9zPWI9YSx0aGlzLm5vdz0odGhpcy5lbmQtdGhpcy5zdGFydCkqYit0aGlzLnN0YXJ0LHRoaXMub3B0aW9ucy5zdGVwJiZ0aGlzLm9wdGlvbnMuc3RlcC5jYWxsKHRoaXMuZWxlbSx0aGlzLm5vdyx0aGlzKSxjJiZjLnNldD9jLnNldCh0aGlzKTpSYS5wcm9wSG9va3MuX2RlZmF1bHQuc2V0KHRoaXMpLHRoaXN9fSxSYS5wcm90b3R5cGUuaW5pdC5wcm90b3R5cGU9UmEucHJvdG90eXBlLFJhLnByb3BIb29rcz17X2RlZmF1bHQ6e2dldDpmdW5jdGlvbihhKXt2YXIgYjtyZXR1cm4gMSE9PWEuZWxlbS5ub2RlVHlwZXx8bnVsbCE9YS5lbGVtW2EucHJvcF0mJm51bGw9PWEuZWxlbS5zdHlsZVthLnByb3BdP2EuZWxlbVthLnByb3BdOihiPW4uY3NzKGEuZWxlbSxhLnByb3AsXCJcIiksYiYmXCJhdXRvXCIhPT1iP2I6MCl9LHNldDpmdW5jdGlvbihhKXtuLmZ4LnN0ZXBbYS5wcm9wXT9uLmZ4LnN0ZXBbYS5wcm9wXShhKToxIT09YS5lbGVtLm5vZGVUeXBlfHxudWxsPT1hLmVsZW0uc3R5bGVbbi5jc3NQcm9wc1thLnByb3BdXSYmIW4uY3NzSG9va3NbYS5wcm9wXT9hLmVsZW1bYS5wcm9wXT1hLm5vdzpuLnN0eWxlKGEuZWxlbSxhLnByb3AsYS5ub3crYS51bml0KX19fSxSYS5wcm9wSG9va3Muc2Nyb2xsVG9wPVJhLnByb3BIb29rcy5zY3JvbGxMZWZ0PXtzZXQ6ZnVuY3Rpb24oYSl7YS5lbGVtLm5vZGVUeXBlJiZhLmVsZW0ucGFyZW50Tm9kZSYmKGEuZWxlbVthLnByb3BdPWEubm93KX19LG4uZWFzaW5nPXtsaW5lYXI6ZnVuY3Rpb24oYSl7cmV0dXJuIGF9LHN3aW5nOmZ1bmN0aW9uKGEpe3JldHVybi41LU1hdGguY29zKGEqTWF0aC5QSSkvMn0sX2RlZmF1bHQ6XCJzd2luZ1wifSxuLmZ4PVJhLnByb3RvdHlwZS5pbml0LG4uZnguc3RlcD17fTt2YXIgU2EsVGEsVWE9L14oPzp0b2dnbGV8c2hvd3xoaWRlKSQvLFZhPS9xdWV1ZUhvb2tzJC87ZnVuY3Rpb24gV2EoKXtyZXR1cm4gYS5zZXRUaW
74371lb3V0KGZ1bmN0aW9uKCl7U2E9dm9pZCAwfSksU2E9bi5ub3coKX1mdW5jdGlvbiBYYShhLGIpe3ZhciBjLGQ9MCxlPXtoZWlnaHQ6YX07Zm9yKGI9Yj8xOjA7ND5kO2QrPTItYiljPVVbZF0sZVtcIm1hcmdpblwiK2NdPWVbXCJwYWRkaW5nXCIrY109YTtyZXR1cm4gYiYmKGUub3BhY2l0eT1lLndpZHRoPWEpLGV9ZnVuY3Rpb24gWWEoYSxiLGMpe2Zvcih2YXIgZCxlPShfYS50d2VlbmVyc1tiXXx8W10pLmNvbmNhdChfYS50d2VlbmVyc1tcIipcIl0pLGY9MCxnPWUubGVuZ3RoO2c+ZjtmKyspaWYoZD1lW2ZdLmNhbGwoYyxiLGEpKXJldHVybiBkfWZ1bmN0aW9uIFphKGEsYixjKXt2YXIgZCxlLGYsZyxoLGksaixrLGw9dGhpcyxtPXt9LG89YS5zdHlsZSxwPWEubm9kZVR5cGUmJlYoYSkscT1OLmdldChhLFwiZnhzaG93XCIpO2MucXVldWV8fChoPW4uX3F1ZXVlSG9va3MoYSxcImZ4XCIpLG51bGw9PWgudW5xdWV1ZWQmJihoLnVucXVldWVkPTAsaT1oLmVtcHR5LmZpcmUsaC5lbXB0eS5maXJlPWZ1bmN0aW9uKCl7aC51bnF1ZXVlZHx8aSgpfSksaC51bnF1ZXVlZCsrLGwuYWx3YXlzKGZ1bmN0aW9uKCl7bC5hbHdheXMoZnVuY3Rpb24oKXtoLnVucXVldWVkLS0sbi5xdWV1ZShhLFwiZnhcIikubGVuZ3RofHxoLmVtcHR5LmZpcmUoKX0pfSkpLDE9PT1hLm5vZGVUeXBlJiYoXCJoZWlnaHRcImluIGJ8fFwid2lkdGhcImluIGIpJiYoYy5vdmVyZmxvdz1bby5vdmVyZmxvdyxvLm92ZXJmbG93WCxvLm92ZXJmbG93WV0saj1uLmNzcyhhLFwiZGlzcGxheVwiKSxrPVwibm9uZVwiPT09aj9OLmdldChhLFwib2xkZGlzcGxheVwiKXx8emEoYS5ub2RlTmFtZSk6aixcImlubGluZVwiPT09ayYmXCJub25lXCI9PT1uLmNzcyhhLFwiZmxvYXRcIikmJihvLmRpc3BsYXk9XCJpbmxpbmUtYmxvY2tcIikpLGMub3ZlcmZsb3cmJihvLm92ZXJmbG93PVwiaGlkZGVuXCIsbC5hbHdheXMoZnVuY3Rpb24oKXtvLm92ZXJmbG93PWMub3ZlcmZsb3dbMF0sby5vdmVyZmxvd1g9Yy5vdmVyZmxvd1sxXSxvLm92ZXJmbG93WT1jLm92ZXJmbG93WzJdfSkpO2ZvcihkIGluIGIpaWYoZT1iW2RdLFVhLmV4ZWMoZSkpe2lmKGRlbGV0ZSBiW2RdLGY9Znx8XCJ0b2dnbGVcIj09PWUsZT09PShwP1wiaGlkZVwiOlwic2hvd1wiKSl7aWYoXCJzaG93XCIhPT1lfHwhcXx8dm9pZCAwPT09cVtkXSljb250aW51ZTtwPSEwfW1bZF09cSYmcVtkXXx8bi5zdHlsZShhLGQpfWVsc2Ugaj12b2lkIDA7aWYobi5pc0VtcHR5T2JqZWN0KG0pKVwiaW5saW5lXCI9PT0oXCJub25lXCI9PT1qP3phKGEubm9kZU5hbWUpOmopJiYoby5kaXNwbGF5PWopO2Vsc2V7cT9cImhpZGRlblwiaW4gcSYmKHA9cS5oaWRkZW4pOnE9Ti5hY2Nlc3MoYSxcImZ4c2hvd1wiLHt9KSxmJiYocS5oaWRkZW49IXApLHA/bihhKS5zaG93KCk6bC5kb25lKGZ1bmN0aW9uKCl7bihhKS5oaWRlKCl9KSxsLmRvbmUoZnVuY3Rpb24oKXt2YXIgYjtOLnJlbW92ZShhLFwiZnhzaG93XCIpO2ZvcihiIGluIG0pbi5zdHlsZShhLGIsbVtiXSl9KTtmb3IoZCBpbiBtKWc9WWEocD9xW2RdOjAsZCxsKSxkIGluIHF8fChxW2RdPWcuc3RhcnQscCYmKGcuZW5kPWcuc3RhcnQsZy5zdGFydD1cIndpZHRoXCI9PT1kfHxcImhlaWdodFwiPT09ZD8xOjApKX19ZnVuY3Rpb24gJGEoYSxiKXt2YXIgYyxkLGUsZixnO2ZvcihjIGluIGEpaWYoZD1uLmNhbWVsQ2FzZShjKSxlPWJbZF0sZj1hW2NdLG4uaXNBcnJheShmKSYmKGU9ZlsxXSxmPWFbY109ZlswXSksYyE9PWQmJihhW2RdPWYsZGVsZXRlIGFbY10pLGc9bi5jc3NIb29rc1tkXSxnJiZcImV4cGFuZFwiaW4gZyl7Zj1nLmV4cGFuZChmKSxkZWxldGUgYVtkXTtmb3IoYyBpbiBmKWMgaW4gYXx8KGFbY109ZltjXSxiW2NdPWUpfWVsc2UgYltkXT1lfWZ1bmN0aW9uIF9hKGEsYixjKXt2YXIgZCxlLGY9MCxnPV9hLnByZWZpbHRlcnMubGVuZ3RoLGg9bi5EZWZlcnJlZCgpLmFsd2F5cyhmdW5jdGlvbigpe2RlbGV0ZSBpLmVsZW19KSxpPWZ1bmN0aW9uKCl7aWYoZSlyZXR1cm4hMTtmb3IodmFyIGI9U2F8fFdhKCksYz1NYXRoLm1heCgwLGouc3RhcnRUaW1lK2ouZHVyYXRpb24tYiksZD1jL2ouZHVyYXRpb258fDAsZj0xLWQsZz0wLGk9ai50d2VlbnMubGVuZ3RoO2k+ZztnKyspai50d2VlbnNbZ10ucnVuKGYpO3JldHVybiBoLm5vdGlmeVdpdGgoYSxbaixmLGNdKSwxPmYmJmk/YzooaC5yZXNvbHZlV2l0aChhLFtqXSksITEpfSxqPWgucHJvbWlzZSh7ZWxlbTphLHByb3BzOm4uZXh0ZW5kKHt9LGIpLG9wdHM6bi5leHRlbmQoITAse3NwZWNpYWxFYXNpbmc6e30sZWFzaW5nOm4uZWFzaW5nLl9kZWZhdWx0fSxjKSxvcmlnaW5hbFByb3BlcnRpZXM6YixvcmlnaW5hbE9wdGlvbnM6YyxzdGFydFRpbWU6U2F8fFdhKCksZHVyYXRpb246Yy5kdXJhdGlvbix0d2VlbnM6W10sY3JlYXRlVHdlZW46ZnVuY3Rpb24oYixjKXt2YXIgZD1uLlR3ZWVuKGEsai5vcHRzLGIsYyxqLm9wdHMuc3BlY2lhbEVhc2luZ1tiXXx8ai5vcHRzLmVhc2luZyk7cmV0dXJuIGoudHdlZW5zLnB1c2goZCksZH0sc3RvcDpmdW5jdGlvbihiKXt2YXIgYz0wLGQ9Yj9qLnR3ZWVucy5sZW5ndGg6MDtpZihlKXJldHVybi
7437B0aGlzO2ZvcihlPSEwO2Q+YztjKyspai50d2VlbnNbY10ucnVuKDEpO3JldHVybiBiPyhoLm5vdGlmeVdpdGgoYSxbaiwxLDBdKSxoLnJlc29sdmVXaXRoKGEsW2osYl0pKTpoLnJlamVjdFdpdGgoYSxbaixiXSksdGhpc319KSxrPWoucHJvcHM7Zm9yKCRhKGssai5vcHRzLnNwZWNpYWxFYXNpbmcpO2c+ZjtmKyspaWYoZD1fYS5wcmVmaWx0ZXJzW2ZdLmNhbGwoaixhLGssai5vcHRzKSlyZXR1cm4gbi5pc0Z1bmN0aW9uKGQuc3RvcCkmJihuLl9xdWV1ZUhvb2tzKGouZWxlbSxqLm9wdHMucXVldWUpLnN0b3A9bi5wcm94eShkLnN0b3AsZCkpLGQ7cmV0dXJuIG4ubWFwKGssWWEsaiksbi5pc0Z1bmN0aW9uKGoub3B0cy5zdGFydCkmJmoub3B0cy5zdGFydC5jYWxsKGEsaiksbi5meC50aW1lcihuLmV4dGVuZChpLHtlbGVtOmEsYW5pbTpqLHF1ZXVlOmoub3B0cy5xdWV1ZX0pKSxqLnByb2dyZXNzKGoub3B0cy5wcm9ncmVzcykuZG9uZShqLm9wdHMuZG9uZSxqLm9wdHMuY29tcGxldGUpLmZhaWwoai5vcHRzLmZhaWwpLmFsd2F5cyhqLm9wdHMuYWx3YXlzKX1uLkFuaW1hdGlvbj1uLmV4dGVuZChfYSx7dHdlZW5lcnM6e1wiKlwiOltmdW5jdGlvbihhLGIpe3ZhciBjPXRoaXMuY3JlYXRlVHdlZW4oYSxiKTtyZXR1cm4gVyhjLmVsZW0sYSxULmV4ZWMoYiksYyksY31dfSx0d2VlbmVyOmZ1bmN0aW9uKGEsYil7bi5pc0Z1bmN0aW9uKGEpPyhiPWEsYT1bXCIqXCJdKTphPWEubWF0Y2goRyk7Zm9yKHZhciBjLGQ9MCxlPWEubGVuZ3RoO2U+ZDtkKyspYz1hW2RdLF9hLnR3ZWVuZXJzW2NdPV9hLnR3ZWVuZXJzW2NdfHxbXSxfYS50d2VlbmVyc1tjXS51bnNoaWZ0KGIpfSxwcmVmaWx0ZXJzOltaYV0scHJlZmlsdGVyOmZ1bmN0aW9uKGEsYil7Yj9fYS5wcmVmaWx0ZXJzLnVuc2hpZnQoYSk6X2EucHJlZmlsdGVycy5wdXNoKGEpfX0pLG4uc3BlZWQ9ZnVuY3Rpb24oYSxiLGMpe3ZhciBkPWEmJlwib2JqZWN0XCI9PXR5cGVvZiBhP24uZXh0ZW5kKHt9LGEpOntjb21wbGV0ZTpjfHwhYyYmYnx8bi5pc0Z1bmN0aW9uKGEpJiZhLGR1cmF0aW9uOmEsZWFzaW5nOmMmJmJ8fGImJiFuLmlzRnVuY3Rpb24oYikmJmJ9O3JldHVybiBkLmR1cmF0aW9uPW4uZngub2ZmPzA6XCJudW1iZXJcIj09dHlwZW9mIGQuZHVyYXRpb24/ZC5kdXJhdGlvbjpkLmR1cmF0aW9uIGluIG4uZnguc3BlZWRzP24uZnguc3BlZWRzW2QuZHVyYXRpb25dOm4uZnguc3BlZWRzLl9kZWZhdWx0LG51bGwhPWQucXVldWUmJmQucXVldWUhPT0hMHx8KGQucXVldWU9XCJmeFwiKSxkLm9sZD1kLmNvbXBsZXRlLGQuY29tcGxldGU9ZnVuY3Rpb24oKXtuLmlzRnVuY3Rpb24oZC5vbGQpJiZkLm9sZC5jYWxsKHRoaXMpLGQucXVldWUmJm4uZGVxdWV1ZSh0aGlzLGQucXVldWUpfSxkfSxuLmZuLmV4dGVuZCh7ZmFkZVRvOmZ1bmN0aW9uKGEsYixjLGQpe3JldHVybiB0aGlzLmZpbHRlcihWKS5jc3MoXCJvcGFjaXR5XCIsMCkuc2hvdygpLmVuZCgpLmFuaW1hdGUoe29wYWNpdHk6Yn0sYSxjLGQpfSxhbmltYXRlOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBlPW4uaXNFbXB0eU9iamVjdChhKSxmPW4uc3BlZWQoYixjLGQpLGc9ZnVuY3Rpb24oKXt2YXIgYj1fYSh0aGlzLG4uZXh0ZW5kKHt9LGEpLGYpOyhlfHxOLmdldCh0aGlzLFwiZmluaXNoXCIpKSYmYi5zdG9wKCEwKX07cmV0dXJuIGcuZmluaXNoPWcsZXx8Zi5xdWV1ZT09PSExP3RoaXMuZWFjaChnKTp0aGlzLnF1ZXVlKGYucXVldWUsZyl9LHN0b3A6ZnVuY3Rpb24oYSxiLGMpe3ZhciBkPWZ1bmN0aW9uKGEpe3ZhciBiPWEuc3RvcDtkZWxldGUgYS5zdG9wLGIoYyl9O3JldHVyblwic3RyaW5nXCIhPXR5cGVvZiBhJiYoYz1iLGI9YSxhPXZvaWQgMCksYiYmYSE9PSExJiZ0aGlzLnF1ZXVlKGF8fFwiZnhcIixbXSksdGhpcy5lYWNoKGZ1bmN0aW9uKCl7dmFyIGI9ITAsZT1udWxsIT1hJiZhK1wicXVldWVIb29rc1wiLGY9bi50aW1lcnMsZz1OLmdldCh0aGlzKTtpZihlKWdbZV0mJmdbZV0uc3RvcCYmZChnW2VdKTtlbHNlIGZvcihlIGluIGcpZ1tlXSYmZ1tlXS5zdG9wJiZWYS50ZXN0KGUpJiZkKGdbZV0pO2ZvcihlPWYubGVuZ3RoO2UtLTspZltlXS5lbGVtIT09dGhpc3x8bnVsbCE9YSYmZltlXS5xdWV1ZSE9PWF8fChmW2VdLmFuaW0uc3RvcChjKSxiPSExLGYuc3BsaWNlKGUsMSkpOyFiJiZjfHxuLmRlcXVldWUodGhpcyxhKX0pfSxmaW5pc2g6ZnVuY3Rpb24oYSl7cmV0dXJuIGEhPT0hMSYmKGE9YXx8XCJmeFwiKSx0aGlzLmVhY2goZnVuY3Rpb24oKXt2YXIgYixjPU4uZ2V0KHRoaXMpLGQ9Y1thK1wicXVldWVcIl0sZT1jW2ErXCJxdWV1ZUhvb2tzXCJdLGY9bi50aW1lcnMsZz1kP2QubGVuZ3RoOjA7Zm9yKGMuZmluaXNoPSEwLG4ucXVldWUodGhpcyxhLFtdKSxlJiZlLnN0b3AmJmUuc3RvcC5jYWxsKHRoaXMsITApLGI9Zi5sZW5ndGg7Yi0tOylmW2JdLmVsZW09PT10aGlzJiZmW2JdLnF1ZXVlPT09YSYmKGZbYl0uYW5pbS5zdG9wKCEwKSxmLnNwbGljZShiLDEpKTtmb3IoYj0wO2c+YjtiKyspZFtiXSYmZFtiXS5maW5pc2gmJmRbYl0uZmluaXNoLmNhbGwodGhpcyk7ZGVsZXRlIGMuZmluaXNofSl9fSksbi5lYWNoKFtcInRvZ2dsZVwiLFwic2hvd1wiLFwiaGlkZVwiXSxmdW5jdGlvbihhLGIpe3ZhciBjPW4uZm5bYl07bi5mbltiXT1mdW5jdGlvbihhLGQsZSl7cmV0dXJuIG51bGw9PWF8fFwiYm9vbGVhblwiPT10eXBlb2YgYT9jLmFwcGx5KHRoaXMsYXJndW1lbnRzKTp0aGlzLmFuaW1hdGUoWGEoYiwhMCksYSxkLGUpfX0pLG4uZWFjaCh7c2xpZGVEb3duOlhhKFwic2hvd1wiKSxzbGlkZVVwOlhhKFwiaGlkZVwiKSxzbGlkZVRvZ2dsZTpYYShcInRvZ2dsZVwiKSxmYWRlSW46e29wYWNpdHk6XCJzaG93XCJ9LGZhZGVPdXQ6e29wYWNpdHk6XCJoaWRlXCJ9LGZhZGVUb2dnbGU6e29wYWNpdHk6XCJ0b2dnbGVcIn19LGZ1bmN0aW9uKGEsYil7bi5mblthXT1mdW5jdGlvbihhLGMsZCl7cmV0dXJuIHRoaXMuYW5pbWF0ZShiLGEsYyxkKX19KSxuLnRpbWVycz1bXSxuLmZ4LnRpY2s9ZnVuY3Rpb24oKXt2YXIgYSxiPTAsYz1uLnRpbWVycztmb3IoU2E9bi5ub3coKTtiPGMubGVuZ3RoO2IrKylhPWNbYl0sYSgpfHxjW2JdIT09YXx8Yy5zcGxpY2UoYi0tLDEpO2MubGVuZ3RofHxuLmZ4LnN0b3AoKSxTYT12b2lkIDB9LG4uZngudGltZXI9ZnVuY3Rpb24oYSl7bi50aW1lcnMucHVzaChhKSxhKCk/bi5meC5zdGFydCgpOm4udGltZXJzLnBvcCgpfSxuLmZ4LmludGVydmFsPTEzLG4uZnguc3RhcnQ9ZnVuY3Rpb24oKXtUYXx8KFRhPWEuc2
7437V0SW50ZXJ2YWwobi5meC50aWNrLG4uZnguaW50ZXJ2YWwpKX0sbi5meC5zdG9wPWZ1bmN0aW9uKCl7YS5jbGVhckludGVydmFsKFRhKSxUYT1udWxsfSxuLmZ4LnNwZWVkcz17c2xvdzo2MDAsZmFzdDoyMDAsX2RlZmF1bHQ6NDAwfSxuLmZuLmRlbGF5PWZ1bmN0aW9uKGIsYyl7cmV0dXJuIGI9bi5meD9uLmZ4LnNwZWVkc1tiXXx8YjpiLGM9Y3x8XCJmeFwiLHRoaXMucXVldWUoYyxmdW5jdGlvbihjLGQpe3ZhciBlPWEuc2V0VGltZW91dChjLGIpO2Quc3RvcD1mdW5jdGlvbigpe2EuY2xlYXJUaW1lb3V0KGUpfX0pfSxmdW5jdGlvbigpe3ZhciBhPWQuY3JlYXRlRWxlbWVudChcImlucHV0XCIpLGI9ZC5jcmVhdGVFbGVtZW50KFwic2VsZWN0XCIpLGM9Yi5hcHBlbmRDaGlsZChkLmNyZWF0ZUVsZW1lbnQoXCJvcHRpb25cIikpO2EudHlwZT1cImNoZWNrYm94XCIsbC5jaGVja09uPVwiXCIhPT1hLnZhbHVlLGwub3B0U2VsZWN0ZWQ9Yy5zZWxlY3RlZCxiLmRpc2FibGVkPSEwLGwub3B0RGlzYWJsZWQ9IWMuZGlzYWJsZWQsYT1kLmNyZWF0ZUVsZW1lbnQoXCJpbnB1dFwiKSxhLnZhbHVlPVwidFwiLGEudHlwZT1cInJhZGlvXCIsbC5yYWRpb1ZhbHVlPVwidFwiPT09YS52YWx1ZX0oKTt2YXIgYWIsYmI9bi5leHByLmF0dHJIYW5kbGU7bi5mbi5leHRlbmQoe2F0dHI6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSyh0aGlzLG4uYXR0cixhLGIsYXJndW1lbnRzLmxlbmd0aD4xKX0scmVtb3ZlQXR0cjpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCl7bi5yZW1vdmVBdHRyKHRoaXMsYSl9KX19KSxuLmV4dGVuZCh7YXR0cjpmdW5jdGlvbihhLGIsYyl7dmFyIGQsZSxmPWEubm9kZVR5cGU7aWYoMyE9PWYmJjghPT1mJiYyIT09ZilyZXR1cm5cInVuZGVmaW5lZFwiPT10eXBlb2YgYS5nZXRBdHRyaWJ1dGU/bi5wcm9wKGEsYixjKTooMT09PWYmJm4uaXNYTUxEb2MoYSl8fChiPWIudG9Mb3dlckNhc2UoKSxlPW4uYXR0ckhvb2tzW2JdfHwobi5leHByLm1hdGNoLmJvb2wudGVzdChiKT9hYjp2b2lkIDApKSx2b2lkIDAhPT1jP251bGw9PT1jP3ZvaWQgbi5yZW1vdmVBdHRyKGEsYik6ZSYmXCJzZXRcImluIGUmJnZvaWQgMCE9PShkPWUuc2V0KGEsYyxiKSk/ZDooYS5zZXRBdHRyaWJ1dGUoYixjK1wiXCIpLGMpOmUmJlwiZ2V0XCJpbiBlJiZudWxsIT09KGQ9ZS5nZXQoYSxiKSk/ZDooZD1uLmZpbmQuYXR0cihhLGIpLG51bGw9PWQ/dm9pZCAwOmQpKX0sYXR0ckhvb2tzOnt0eXBlOntzZXQ6ZnVuY3Rpb24oYSxiKXtpZighbC5yYWRpb1ZhbHVlJiZcInJhZGlvXCI9PT1iJiZuLm5vZGVOYW1lKGEsXCJpbnB1dFwiKSl7dmFyIGM9YS52YWx1ZTtyZXR1cm4gYS5zZXRBdHRyaWJ1dGUoXCJ0eXBlXCIsYiksYyYmKGEudmFsdWU9YyksYn19fX0scmVtb3ZlQXR0cjpmdW5jdGlvbihhLGIpe3ZhciBjLGQsZT0wLGY9YiYmYi5tYXRjaChHKTtpZihmJiYxPT09YS5ub2RlVHlwZSl3aGlsZShjPWZbZSsrXSlkPW4ucHJvcEZpeFtjXXx8YyxuLmV4cHIubWF0Y2guYm9vbC50ZXN0KGMpJiYoYVtkXT0hMSksYS5yZW1vdmVBdHRyaWJ1dGUoYyl9fSksYWI9e3NldDpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIGI9PT0hMT9uLnJlbW92ZUF0dHIoYSxjKTphLnNldEF0dHJpYnV0ZShjLGMpLGN9fSxuLmVhY2gobi5leHByLm1hdGNoLmJvb2wuc291cmNlLm1hdGNoKC9cXHcrL2cpLGZ1bmN0aW9uKGEsYil7dmFyIGM9YmJbYl18fG4uZmluZC5hdHRyO2JiW2JdPWZ1bmN0aW9uKGEsYixkKXt2YXIgZSxmO3JldHVybiBkfHwoZj1iYltiXSxiYltiXT1lLGU9bnVsbCE9YyhhLGIsZCk/Yi50b0xvd2VyQ2FzZSgpOm51bGwsYmJbYl09ZiksZX19KTt2YXIgY2I9L14oPzppbnB1dHxzZWxlY3R8dGV4dGFyZWF8YnV0dG9uKSQvaSxkYj0vXig/OmF8YXJlYSkkL2k7bi5mbi5leHRlbmQoe3Byb3A6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSyh0aGlzLG4ucHJvcCxhLGIsYXJndW1lbnRzLmxlbmd0aD4xKX0scmVtb3ZlUHJvcDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCl7ZGVsZXRlIHRoaXNbbi5wcm9wRml4W2FdfHxhXX0pfX0pLG4uZXh0ZW5kKHtwcm9wOmZ1bmN0aW9uKGEsYixjKXt2YXIgZCxlLGY9YS5ub2RlVHlwZTtpZigzIT09ZiYmOCE9PWYmJjIhPT1mKXJldHVybiAxPT09ZiYmbi5pc1hNTERvYyhhKXx8KGI9bi5wcm9wRml4W2JdfHxiLGU9bi5wcm9wSG9va3NbYl0pLFxudm9pZCAwIT09Yz9lJiZcInNldFwiaW4gZSYmdm9pZCAwIT09KGQ9ZS5zZXQoYSxjLGIpKT9kOmFbYl09YzplJiZcImdldFwiaW4gZSYmbnVsbCE9PShkPWUuZ2V0KGEsYikpP2Q6YVtiXX0scHJvcEhvb2tzOnt0YWJJbmRleDp7Z2V0OmZ1bmN0aW9uKGEpe3ZhciBiPW4uZmluZC5hdHRyKGEsXCJ0YWJpbmRleFwiKTtyZXR1cm4gYj9wYXJzZUludChiLDEwKTpjYi50ZXN0KGEubm9kZU5hbWUpfHxkYi50ZXN0KGEubm9kZU5hbWUpJiZhLmhyZWY/MDotMX19fSxwcm9wRml4OntcImZvclwiOlwiaHRtbEZvclwiLFwiY2xhc3NcIjpcImNsYXNzTmFtZVwifX0pLGwub3B0U2VsZWN0ZWR8fChuLnByb3BIb29rcy5zZWxlY3RlZD17Z2V0OmZ1bmN0aW9uKGEpe3ZhciBiPWEucGFyZW50Tm9kZTtyZXR1cm4gYiYmYi5wYXJlbnROb2RlJiZiLnBhcmVudE5vZGUuc2VsZWN0ZWRJbmRleCxudWxsfSxzZXQ6ZnVuY3Rpb24oYSl7dmFyIGI9YS5wYXJlbnROb2RlO2ImJihiLnNlbGVjdGVkSW5kZXgsYi5wYXJlbnROb2RlJiZiLnBhcmVudE5vZGUuc2VsZWN0ZWRJbmRleCl9fSksbi5lYWNoKFtcInRhYkluZGV4XCIsXCJyZWFkT25seVwiLFwibWF4TGVuZ3RoXCIsXCJjZWxsU3BhY2luZ1wiLFwiY2VsbFBhZGRpbmdcIixcInJvd1NwYW5cIixcImNvbFNwYW5cIixcInVzZU1hcFwiLFwiZnJhbWVCb3JkZXJcIixcImNvbnRlbnRFZGl0YWJsZVwiXSxmdW5jdGlvbigpe24ucHJvcEZpeFt0aGlzLnRvTG93ZXJDYXNlKCldPXRoaXN9KTt2YXIgZWI9L1tcXHRcXHJcXG5cXGZdL2c7ZnVuY3Rpb24gZmIoYSl7cmV0dXJuIGEuZ2V0QXR0cmlidXRlJiZhLmdldEF0dHJpYnV0ZShcImNsYXNzXCIpfHxcIlwifW4uZm4uZXh0ZW5kKHthZGRDbGFzczpmdW5jdGlvbihhKXt2YXIgYixjLGQsZSxmLGcsaCxpPTA7aWYobi5pc0Z1bmN0aW9uKGEpKXJldHVybi
7437B0aGlzLmVhY2goZnVuY3Rpb24oYil7bih0aGlzKS5hZGRDbGFzcyhhLmNhbGwodGhpcyxiLGZiKHRoaXMpKSl9KTtpZihcInN0cmluZ1wiPT10eXBlb2YgYSYmYSl7Yj1hLm1hdGNoKEcpfHxbXTt3aGlsZShjPXRoaXNbaSsrXSlpZihlPWZiKGMpLGQ9MT09PWMubm9kZVR5cGUmJihcIiBcIitlK1wiIFwiKS5yZXBsYWNlKGViLFwiIFwiKSl7Zz0wO3doaWxlKGY9YltnKytdKWQuaW5kZXhPZihcIiBcIitmK1wiIFwiKTwwJiYoZCs9ZitcIiBcIik7aD1uLnRyaW0oZCksZSE9PWgmJmMuc2V0QXR0cmlidXRlKFwiY2xhc3NcIixoKX19cmV0dXJuIHRoaXN9LHJlbW92ZUNsYXNzOmZ1bmN0aW9uKGEpe3ZhciBiLGMsZCxlLGYsZyxoLGk9MDtpZihuLmlzRnVuY3Rpb24oYSkpcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbihiKXtuKHRoaXMpLnJlbW92ZUNsYXNzKGEuY2FsbCh0aGlzLGIsZmIodGhpcykpKX0pO2lmKCFhcmd1bWVudHMubGVuZ3RoKXJldHVybiB0aGlzLmF0dHIoXCJjbGFzc1wiLFwiXCIpO2lmKFwic3RyaW5nXCI9PXR5cGVvZiBhJiZhKXtiPWEubWF0Y2goRyl8fFtdO3doaWxlKGM9dGhpc1tpKytdKWlmKGU9ZmIoYyksZD0xPT09Yy5ub2RlVHlwZSYmKFwiIFwiK2UrXCIgXCIpLnJlcGxhY2UoZWIsXCIgXCIpKXtnPTA7d2hpbGUoZj1iW2crK10pd2hpbGUoZC5pbmRleE9mKFwiIFwiK2YrXCIgXCIpPi0xKWQ9ZC5yZXBsYWNlKFwiIFwiK2YrXCIgXCIsXCIgXCIpO2g9bi50cmltKGQpLGUhPT1oJiZjLnNldEF0dHJpYnV0ZShcImNsYXNzXCIsaCl9fXJldHVybiB0aGlzfSx0b2dnbGVDbGFzczpmdW5jdGlvbihhLGIpe3ZhciBjPXR5cGVvZiBhO3JldHVyblwiYm9vbGVhblwiPT10eXBlb2YgYiYmXCJzdHJpbmdcIj09PWM/Yj90aGlzLmFkZENsYXNzKGEpOnRoaXMucmVtb3ZlQ2xhc3MoYSk6bi5pc0Z1bmN0aW9uKGEpP3RoaXMuZWFjaChmdW5jdGlvbihjKXtuKHRoaXMpLnRvZ2dsZUNsYXNzKGEuY2FsbCh0aGlzLGMsZmIodGhpcyksYiksYil9KTp0aGlzLmVhY2goZnVuY3Rpb24oKXt2YXIgYixkLGUsZjtpZihcInN0cmluZ1wiPT09Yyl7ZD0wLGU9bih0aGlzKSxmPWEubWF0Y2goRyl8fFtdO3doaWxlKGI9ZltkKytdKWUuaGFzQ2xhc3MoYik/ZS5yZW1vdmVDbGFzcyhiKTplLmFkZENsYXNzKGIpfWVsc2Ugdm9pZCAwIT09YSYmXCJib29sZWFuXCIhPT1jfHwoYj1mYih0aGlzKSxiJiZOLnNldCh0aGlzLFwiX19jbGFzc05hbWVfX1wiLGIpLHRoaXMuc2V0QXR0cmlidXRlJiZ0aGlzLnNldEF0dHJpYnV0ZShcImNsYXNzXCIsYnx8YT09PSExP1wiXCI6Ti5nZXQodGhpcyxcIl9fY2xhc3NOYW1lX19cIil8fFwiXCIpKX0pfSxoYXNDbGFzczpmdW5jdGlvbihhKXt2YXIgYixjLGQ9MDtiPVwiIFwiK2ErXCIgXCI7d2hpbGUoYz10aGlzW2QrK10paWYoMT09PWMubm9kZVR5cGUmJihcIiBcIitmYihjKStcIiBcIikucmVwbGFjZShlYixcIiBcIikuaW5kZXhPZihiKT4tMSlyZXR1cm4hMDtyZXR1cm4hMX19KTt2YXIgZ2I9L1xcci9nLGhiPS9bXFx4MjBcXHRcXHJcXG5cXGZdKy9nO24uZm4uZXh0ZW5kKHt2YWw6ZnVuY3Rpb24oYSl7dmFyIGIsYyxkLGU9dGhpc1swXTt7aWYoYXJndW1lbnRzLmxlbmd0aClyZXR1cm4gZD1uLmlzRnVuY3Rpb24oYSksdGhpcy5lYWNoKGZ1bmN0aW9uKGMpe3ZhciBlOzE9PT10aGlzLm5vZGVUeXBlJiYoZT1kP2EuY2FsbCh0aGlzLGMsbih0aGlzKS52YWwoKSk6YSxudWxsPT1lP2U9XCJcIjpcIm51bWJlclwiPT10eXBlb2YgZT9lKz1cIlwiOm4uaXNBcnJheShlKSYmKGU9bi5tYXAoZSxmdW5jdGlvbihhKXtyZXR1cm4gbnVsbD09YT9cIlwiOmErXCJcIn0pKSxiPW4udmFsSG9va3NbdGhpcy50eXBlXXx8bi52YWxIb29rc1t0aGlzLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCldLGImJlwic2V0XCJpbiBiJiZ2b2lkIDAhPT1iLnNldCh0aGlzLGUsXCJ2YWx1ZVwiKXx8KHRoaXMudmFsdWU9ZSkpfSk7aWYoZSlyZXR1cm4gYj1uLnZhbEhvb2tzW2UudHlwZV18fG4udmFsSG9va3NbZS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpXSxiJiZcImdldFwiaW4gYiYmdm9pZCAwIT09KGM9Yi5nZXQoZSxcInZhbHVlXCIpKT9jOihjPWUudmFsdWUsXCJzdHJpbmdcIj09dHlwZW9mIGM/Yy5yZXBsYWNlKGdiLFwiXCIpOm51bGw9PWM/XCJcIjpjKX19fSksbi5leHRlbmQoe3ZhbEhvb2tzOntvcHRpb246e2dldDpmdW5jdGlvbihhKXt2YXIgYj1uLmZpbmQuYXR0cihhLFwidmFsdWVcIik7cmV0dXJuIG51bGwhPWI/YjpuLnRyaW0obi50ZXh0KGEpKS5yZXBsYWNlKGhiLFwiIFwiKX19LHNlbGVjdDp7Z2V0OmZ1bmN0aW9uKGEpe2Zvcih2YXIgYixjLGQ9YS5vcHRpb25zLGU9YS5zZWxlY3RlZEluZGV4LGY9XCJzZWxlY3Qtb25lXCI9PT1hLnR5cGV8fDA+ZSxnPWY/bnVsbDpbXSxoPWY/ZSsxOmQubGVuZ3RoLGk9MD5lP2g6Zj9lOjA7aD5pO2krKylpZihjPWRbaV0sKGMuc2VsZWN0ZWR8fGk9PT1lKSYmKGwub3B0RGlzYWJsZWQ/IWMuZGlzYWJsZWQ6bnVsbD09PWMuZ2V0QXR0cmlidXRlKFwiZGlzYWJsZWRcIikpJiYoIWMucGFyZW50Tm9kZS5kaXNhYmxlZHx8IW4ubm9kZU5hbWUoYy5wYXJlbnROb2RlLFwib3B0Z3JvdXBcIikpKXtpZihiPW4oYykudmFsKCksZilyZXR1cm4gYjtnLnB1c2goYil9cmV0dXJuIGd9LHNldDpmdW5jdGlvbihhLGIpe3ZhciBjLGQsZT1hLm9wdGlvbnMsZj1uLm1ha2VBcnJheShiKSxnPWUubGVuZ3RoO3doaWxlKGctLSlkPWVbZ10sKGQuc2VsZWN0ZWQ9bi5pbkFycmF5KG4udmFsSG9va3Mub3B0aW9uLmdldChkKSxmKT4tMSkmJihjPSEwKTtyZXR1cm4gY3x8KGEuc2VsZWN0ZWRJbmRleD0tMSksZn19fX0pLG4uZWFjaChbXCJyYWRpb1wiLFwiY2hlY2tib3hcIl0sZnVuY3Rpb24oKXtuLnZhbEhvb2tzW3RoaXNdPXtzZXQ6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbi5pc0FycmF5KGIpP2EuY2hlY2tlZD1uLmluQXJyYXkobihhKS52YWwoKSxiKT4tMTp2b2lkIDB9fSxsLmNoZWNrT258fChuLnZhbEhvb2tzW3RoaXNdLmdldD1mdW5jdGlvbihhKXtyZXR1cm4gbnVsbD09PWEuZ2V0QXR0cmlidXRlKFwidmFsdWVcIik/XCJvblwiOmEudmFsdWV9KX0pO3ZhciBpYj0vXig/OmZvY3VzaW5mb2N1c3xmb2N1c291dGJsdXIpJC87bi5leHRlbmQobi5ldmVudCx7dHJpZ2dlcjpmdW5jdGlvbihiLGMsZSxmKXt2YXIgZyxoLGksaixsLG0sbyxwPVtlfHxkXSxxPWsuY2FsbChiLFwidHlwZVwiKT9iLnR5cGU6YixyPWsuY2FsbChiLFwibmFtZXNwYWNlXCIpP2IubmFtZXNwYWNlLnNwbGl0KFwiLlwiKTpbXTtpZihoPWk9ZT1lfHxkLDMhPT1lLm5vZGVUeXBlJiY4IT09ZS5ub2RlVHlwZSYmIWliLnRlc3QocStuLmV2ZW50LnRyaWdnZXJlZCkmJihxLmluZGV4T2YoXCIuXCIpPi0xJiYocj1xLnNwbGl0KFwiLlwiKSxxPXIuc2hpZnQoKSxyLnNvcnQoKSksbD1xLmluZGV4T2YoXCI6XCIpPDAmJlwib25cIitxLGI9YltuLmV4cGFuZG9dP2I6bmV3IG4uRXZlbnQocSxcIm9iamVjdFwiPT10eXBlb2YgYiYmYiksYi5pc1RyaWdnZXI9Zj8yOjMsYi5uYW1lc3BhY2U9ci5qb2luKFwiLlwiKSxiLnJuYW1lc3BhY2U9Yi5uYW1lc3BhY2U/bmV3IFJlZ0V4cChcIihefFxcXFwuKVwiK3Iuam9pbihcIlxcX
7437FwuKD86LipcXFxcLnwpXCIpK1wiKFxcXFwufCQpXCIpOm51bGwsYi5yZXN1bHQ9dm9pZCAwLGIudGFyZ2V0fHwoYi50YXJnZXQ9ZSksYz1udWxsPT1jP1tiXTpuLm1ha2VBcnJheShjLFtiXSksbz1uLmV2ZW50LnNwZWNpYWxbcV18fHt9LGZ8fCFvLnRyaWdnZXJ8fG8udHJpZ2dlci5hcHBseShlLGMpIT09ITEpKXtpZighZiYmIW8ubm9CdWJibGUmJiFuLmlzV2luZG93KGUpKXtmb3Ioaj1vLmRlbGVnYXRlVHlwZXx8cSxpYi50ZXN0KGorcSl8fChoPWgucGFyZW50Tm9kZSk7aDtoPWgucGFyZW50Tm9kZSlwLnB1c2goaCksaT1oO2k9PT0oZS5vd25lckRvY3VtZW50fHxkKSYmcC5wdXNoKGkuZGVmYXVsdFZpZXd8fGkucGFyZW50V2luZG93fHxhKX1nPTA7d2hpbGUoKGg9cFtnKytdKSYmIWIuaXNQcm9wYWdhdGlvblN0b3BwZWQoKSliLnR5cGU9Zz4xP2o6by5iaW5kVHlwZXx8cSxtPShOLmdldChoLFwiZXZlbnRzXCIpfHx7fSlbYi50eXBlXSYmTi5nZXQoaCxcImhhbmRsZVwiKSxtJiZtLmFwcGx5KGgsYyksbT1sJiZoW2xdLG0mJm0uYXBwbHkmJkwoaCkmJihiLnJlc3VsdD1tLmFwcGx5KGgsYyksYi5yZXN1bHQ9PT0hMSYmYi5wcmV2ZW50RGVmYXVsdCgpKTtyZXR1cm4gYi50eXBlPXEsZnx8Yi5pc0RlZmF1bHRQcmV2ZW50ZWQoKXx8by5fZGVmYXVsdCYmby5fZGVmYXVsdC5hcHBseShwLnBvcCgpLGMpIT09ITF8fCFMKGUpfHxsJiZuLmlzRnVuY3Rpb24oZVtxXSkmJiFuLmlzV2luZG93KGUpJiYoaT1lW2xdLGkmJihlW2xdPW51bGwpLG4uZXZlbnQudHJpZ2dlcmVkPXEsZVtxXSgpLG4uZXZlbnQudHJpZ2dlcmVkPXZvaWQgMCxpJiYoZVtsXT1pKSksYi5yZXN1bHR9fSxzaW11bGF0ZTpmdW5jdGlvbihhLGIsYyl7dmFyIGQ9bi5leHRlbmQobmV3IG4uRXZlbnQsYyx7dHlwZTphLGlzU2ltdWxhdGVkOiEwfSk7bi5ldmVudC50cmlnZ2VyKGQsbnVsbCxiKX19KSxuLmZuLmV4dGVuZCh7dHJpZ2dlcjpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKXtuLmV2ZW50LnRyaWdnZXIoYSxiLHRoaXMpfSl9LHRyaWdnZXJIYW5kbGVyOmZ1bmN0aW9uKGEsYil7dmFyIGM9dGhpc1swXTtyZXR1cm4gYz9uLmV2ZW50LnRyaWdnZXIoYSxiLGMsITApOnZvaWQgMH19KSxuLmVhY2goXCJibHVyIGZvY3VzIGZvY3VzaW4gZm9jdXNvdXQgbG9hZCByZXNpemUgc2Nyb2xsIHVubG9hZCBjbGljayBkYmxjbGljayBtb3VzZWRvd24gbW91c2V1cCBtb3VzZW1vdmUgbW91c2VvdmVyIG1vdXNlb3V0IG1vdXNlZW50ZXIgbW91c2VsZWF2ZSBjaGFuZ2Ugc2VsZWN0IHN1Ym1pdCBrZXlkb3duIGtleXByZXNzIGtleXVwIGVycm9yIGNvbnRleHRtZW51XCIuc3BsaXQoXCIgXCIpLGZ1bmN0aW9uKGEsYil7bi5mbltiXT1mdW5jdGlvbihhLGMpe3JldHVybiBhcmd1bWVudHMubGVuZ3RoPjA/dGhpcy5vbihiLG51bGwsYSxjKTp0aGlzLnRyaWdnZXIoYil9fSksbi5mbi5leHRlbmQoe2hvdmVyOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMubW91c2VlbnRlcihhKS5tb3VzZWxlYXZlKGJ8fGEpfX0pLGwuZm9jdXNpbj1cIm9uZm9jdXNpblwiaW4gYSxsLmZvY3VzaW58fG4uZWFjaCh7Zm9jdXM6XCJmb2N1c2luXCIsYmx1cjpcImZvY3Vzb3V0XCJ9LGZ1bmN0aW9uKGEsYil7dmFyIGM9ZnVuY3Rpb24oYSl7bi5ldmVudC5zaW11bGF0ZShiLGEudGFyZ2V0LG4uZXZlbnQuZml4KGEpKX07bi5ldmVudC5zcGVjaWFsW2JdPXtzZXR1cDpmdW5jdGlvbigpe3ZhciBkPXRoaXMub3duZXJEb2N1bWVudHx8dGhpcyxlPU4uYWNjZXNzKGQsYik7ZXx8ZC5hZGRFdmVudExpc3RlbmVyKGEsYywhMCksTi5hY2Nlc3MoZCxiLChlfHwwKSsxKX0sdGVhcmRvd246ZnVuY3Rpb24oKXt2YXIgZD10aGlzLm93bmVyRG9jdW1lbnR8fHRoaXMsZT1OLmFjY2VzcyhkLGIpLTE7ZT9OLmFjY2VzcyhkLGIsZSk6KGQucmVtb3ZlRXZlbnRMaXN0ZW5lcihhLGMsITApLE4ucmVtb3ZlKGQsYikpfX19KTt2YXIgamI9YS5sb2NhdGlvbixrYj1uLm5vdygpLGxiPS9cXD8vO24ucGFyc2VKU09OPWZ1bmN0aW9uKGEpe3JldHVybiBKU09OLnBhcnNlKGErXCJcIil9LG4ucGFyc2VYTUw9ZnVuY3Rpb24oYil7dmFyIGM7aWYoIWJ8fFwic3RyaW5nXCIhPXR5cGVvZiBiKXJldHVybiBudWxsO3RyeXtjPShuZXcgYS5ET01QYXJzZXIpLnBhcnNlRnJvbVN0cmluZyhiLFwidGV4dC94bWxcIil9Y2F0Y2goZCl7Yz12b2lkIDB9cmV0dXJuIGMmJiFjLmdldEVsZW1lbnRzQnlUYWdOYW1lKFwicGFyc2VyZXJyb3JcIikubGVuZ3RofHxuLmVycm9yKFwiSW52YWxpZCBYTUw6IFwiK2IpLGN9O3ZhciBtYj0vIy4qJC8sbmI9LyhbPyZdKV89W14mXSovLG9iPS9eKC4qPyk6WyBcXHRdKihbXlxcclxcbl0qKSQvZ20scGI9L14oPzphYm91dHxhcHB8YXBwLXN0b3JhZ2V8ListZXh0ZW5zaW9ufGZpbGV8cmVzfHdpZGdldCk6JC8scWI9L14oPzpHRVR8SEVBRCkkLyxyYj0vXlxcL1xcLy8sc2I9e30sdGI9e30sdWI9XCIqL1wiLmNvbmNhdChcIipcIiksdmI9ZC5jcmVhdGVFbGVtZW50KFwiYVwiKTt2Yi5ocmVmPWpiLmhyZWY7ZnVuY3Rpb24gd2IoYSl7cmV0dXJuIGZ1bmN0aW9uKGIsYyl7XCJzdHJpbmdcIiE9dHlwZW9mIGImJihjPWIsYj1cIipcIik7dmFyIGQsZT0wLGY9Yi50b0xvd2VyQ2FzZSgpLm1hdGNoKEcpfHxbXTtpZihuLmlzRnVuY3Rpb24oYykpd2hpbGUoZD1mW2UrK10pXCIrXCI9PT1kWzBdPyhkPWQuc2xpY2UoMSl8fFwiKlwiLChhW2RdPWFbZF18fFtdKS51bnNoaWZ0KGMpKTooYVtkXT1hW2RdfHxbXSkucHVzaChjKX19ZnVuY3Rpb24geGIoYSxiLGMsZCl7dmFyIGU9e30sZj1hPT09dGI7ZnVuY3Rpb24gZyhoKXt2YXIgaTtyZXR1cm4gZVtoXT0hMCxuLmVhY2goYVtoXXx8W10sZnVuY3Rpb24oYSxoKXt2YXIgaj1oKGIsYyxkKTtyZXR1cm5cInN0cmluZ1wiIT10eXBlb2Yganx8Znx8ZVtqXT9mPyEoaT1qKTp2b2lkIDA6KGIuZGF0YVR5cGVzLnVuc2hpZnQoaiksZyhqKSwhMSl9KSxpfXJldHVybiBnKGIuZGF0YVR5cGVzWzBdKXx8IWVbXCIqXCJdJiZnKFwiKlwiKX1mdW5jdGlvbiB5YihhLGIpe3ZhciBjLGQsZT1uLmFqYXhTZXR0aW5ncy5mbGF0T3B0aW9uc3x8e307Zm9yKGMgaW4gYil2b2lkIDAhPT1iW2NdJiYoKGVbY10/YTpkfHwoZD17fSkpW2NdPWJbY10pO3JldHVybiBkJiZuLmV4dGVuZCghMCxhLGQpLGF9ZnVuY3Rpb24gemIoYSxiLGMpe3ZhciBkLGUsZixnLGg9YS5jb250ZW50cyxpPWEuZGF0YVR5cGVzO3doaWxlKFwiKlwiPT09aVswXSlpLnNoaWZ0KCksdm9pZCAwPT09ZCYmKGQ9YS5taW1lVHlwZXx8Yi5nZXRSZXNwb25zZUhlYWRlcihcIkNvbnRlbnQtVHlwZVwiKSk7
7437aWYoZClmb3IoZSBpbiBoKWlmKGhbZV0mJmhbZV0udGVzdChkKSl7aS51bnNoaWZ0KGUpO2JyZWFrfWlmKGlbMF1pbiBjKWY9aVswXTtlbHNle2ZvcihlIGluIGMpe2lmKCFpWzBdfHxhLmNvbnZlcnRlcnNbZStcIiBcIitpWzBdXSl7Zj1lO2JyZWFrfWd8fChnPWUpfWY9Znx8Z31yZXR1cm4gZj8oZiE9PWlbMF0mJmkudW5zaGlmdChmKSxjW2ZdKTp2b2lkIDB9ZnVuY3Rpb24gQWIoYSxiLGMsZCl7dmFyIGUsZixnLGgsaSxqPXt9LGs9YS5kYXRhVHlwZXMuc2xpY2UoKTtpZihrWzFdKWZvcihnIGluIGEuY29udmVydGVycylqW2cudG9Mb3dlckNhc2UoKV09YS5jb252ZXJ0ZXJzW2ddO2Y9ay5zaGlmdCgpO3doaWxlKGYpaWYoYS5yZXNwb25zZUZpZWxkc1tmXSYmKGNbYS5yZXNwb25zZUZpZWxkc1tmXV09YiksIWkmJmQmJmEuZGF0YUZpbHRlciYmKGI9YS5kYXRhRmlsdGVyKGIsYS5kYXRhVHlwZSkpLGk9ZixmPWsuc2hpZnQoKSlpZihcIipcIj09PWYpZj1pO2Vsc2UgaWYoXCIqXCIhPT1pJiZpIT09Zil7aWYoZz1qW2krXCIgXCIrZl18fGpbXCIqIFwiK2ZdLCFnKWZvcihlIGluIGopaWYoaD1lLnNwbGl0KFwiIFwiKSxoWzFdPT09ZiYmKGc9altpK1wiIFwiK2hbMF1dfHxqW1wiKiBcIitoWzBdXSkpe2c9PT0hMD9nPWpbZV06altlXSE9PSEwJiYoZj1oWzBdLGsudW5zaGlmdChoWzFdKSk7YnJlYWt9aWYoZyE9PSEwKWlmKGcmJmFbXCJ0aHJvd3NcIl0pYj1nKGIpO2Vsc2UgdHJ5e2I9ZyhiKX1jYXRjaChsKXtyZXR1cm57c3RhdGU6XCJwYXJzZXJlcnJvclwiLGVycm9yOmc/bDpcIk5vIGNvbnZlcnNpb24gZnJvbSBcIitpK1wiIHRvIFwiK2Z9fX1yZXR1cm57c3RhdGU6XCJzdWNjZXNzXCIsZGF0YTpifX1uLmV4dGVuZCh7YWN0aXZlOjAsbGFzdE1vZGlmaWVkOnt9LGV0YWc6e30sYWpheFNldHRpbmdzOnt1cmw6amIuaHJlZix0eXBlOlwiR0VUXCIsaXNMb2NhbDpwYi50ZXN0KGpiLnByb3RvY29sKSxnbG9iYWw6ITAscHJvY2Vzc0RhdGE6ITAsYXN5bmM6ITAsY29udGVudFR5cGU6XCJhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQ7IGNoYXJzZXQ9VVRGLThcIixhY2NlcHRzOntcIipcIjp1Yix0ZXh0OlwidGV4dC9wbGFpblwiLGh0bWw6XCJ0ZXh0L2h0bWxcIix4bWw6XCJhcHBsaWNhdGlvbi94bWwsIHRleHQveG1sXCIsanNvbjpcImFwcGxpY2F0aW9uL2pzb24sIHRleHQvamF2YXNjcmlwdFwifSxjb250ZW50czp7eG1sOi9cXGJ4bWxcXGIvLGh0bWw6L1xcYmh0bWwvLGpzb246L1xcYmpzb25cXGIvfSxyZXNwb25zZUZpZWxkczp7eG1sOlwicmVzcG9uc2VYTUxcIix0ZXh0OlwicmVzcG9uc2VUZXh0XCIsanNvbjpcInJlc3BvbnNlSlNPTlwifSxjb252ZXJ0ZXJzOntcIiogdGV4dFwiOlN0cmluZyxcInRleHQgaHRtbFwiOiEwLFwidGV4dCBqc29uXCI6bi5wYXJzZUpTT04sXCJ0ZXh0IHhtbFwiOm4ucGFyc2VYTUx9LGZsYXRPcHRpb25zOnt1cmw6ITAsY29udGV4dDohMH19LGFqYXhTZXR1cDpmdW5jdGlvbihhLGIpe3JldHVybiBiP3liKHliKGEsbi5hamF4U2V0dGluZ3MpLGIpOnliKG4uYWpheFNldHRpbmdzLGEpfSxhamF4UHJlZmlsdGVyOndiKHNiKSxhamF4VHJhbnNwb3J0OndiKHRiKSxhamF4OmZ1bmN0aW9uKGIsYyl7XCJvYmplY3RcIj09dHlwZW9mIGImJihjPWIsYj12b2lkIDApLGM9Y3x8e307dmFyIGUsZixnLGgsaSxqLGssbCxtPW4uYWpheFNldHVwKHt9LGMpLG89bS5jb250ZXh0fHxtLHA9bS5jb250ZXh0JiYoby5ub2RlVHlwZXx8by5qcXVlcnkpP24obyk6bi5ldmVudCxxPW4uRGVmZXJyZWQoKSxyPW4uQ2FsbGJhY2tzKFwib25jZSBtZW1vcnlcIikscz1tLnN0YXR1c0NvZGV8fHt9LHQ9e30sdT17fSx2PTAsdz1cImNhbmNlbGVkXCIseD17cmVhZHlTdGF0ZTowLGdldFJlc3BvbnNlSGVhZGVyOmZ1bmN0aW9uKGEpe3ZhciBiO2lmKDI9PT12KXtpZighaCl7aD17fTt3aGlsZShiPW9iLmV4ZWMoZykpaFtiWzFdLnRvTG93ZXJDYXNlKCldPWJbMl19Yj1oW2EudG9Mb3dlckNhc2UoKV19cmV0dXJuIG51bGw9PWI/bnVsbDpifSxnZXRBbGxSZXNwb25zZUhlYWRlcnM6ZnVuY3Rpb24oKXtyZXR1cm4gMj09PXY/ZzpudWxsfSxzZXRSZXF1ZXN0SGVhZGVyOmZ1bmN0aW9uKGEsYil7dmFyIGM9YS50b0xvd2VyQ2FzZSgpO3JldHVybiB2fHwoYT
743711W2NdPXVbY118fGEsdFthXT1iKSx0aGlzfSxvdmVycmlkZU1pbWVUeXBlOmZ1bmN0aW9uKGEpe3JldHVybiB2fHwobS5taW1lVHlwZT1hKSx0aGlzfSxzdGF0dXNDb2RlOmZ1bmN0aW9uKGEpe3ZhciBiO2lmKGEpaWYoMj52KWZvcihiIGluIGEpc1tiXT1bc1tiXSxhW2JdXTtlbHNlIHguYWx3YXlzKGFbeC5zdGF0dXNdKTtyZXR1cm4gdGhpc30sYWJvcnQ6ZnVuY3Rpb24oYSl7dmFyIGI9YXx8dztyZXR1cm4gZSYmZS5hYm9ydChiKSx6KDAsYiksdGhpc319O2lmKHEucHJvbWlzZSh4KS5jb21wbGV0ZT1yLmFkZCx4LnN1Y2Nlc3M9eC5kb25lLHguZXJyb3I9eC5mYWlsLG0udXJsPSgoYnx8bS51cmx8fGpiLmhyZWYpK1wiXCIpLnJlcGxhY2UobWIsXCJcIikucmVwbGFjZShyYixqYi5wcm90b2NvbCtcIi8vXCIpLG0udHlwZT1jLm1ldGhvZHx8Yy50eXBlfHxtLm1ldGhvZHx8bS50eXBlLG0uZGF0YVR5cGVzPW4udHJpbShtLmRhdGFUeXBlfHxcIipcIikudG9Mb3dlckNhc2UoKS5tYXRjaChHKXx8W1wiXCJdLG51bGw9PW0uY3Jvc3NEb21haW4pe2o9ZC5jcmVhdGVFbGVtZW50KFwiYVwiKTt0cnl7ai5ocmVmPW0udXJsLGouaHJlZj1qLmhyZWYsbS5jcm9zc0RvbWFpbj12Yi5wcm90b2NvbCtcIi8vXCIrdmIuaG9zdCE9ai5wcm90b2NvbCtcIi8vXCIrai5ob3N0fWNhdGNoKHkpe20uY3Jvc3NEb21haW49ITB9fWlmKG0uZGF0YSYmbS5wcm9jZXNzRGF0YSYmXCJzdHJpbmdcIiE9dHlwZW9mIG0uZGF0YSYmKG0uZGF0YT1uLnBhcmFtKG0uZGF0YSxtLnRyYWRpdGlvbmFsKSkseGIoc2IsbSxjLHgpLDI9PT12KXJldHVybiB4O2s9bi5ldmVudCYmbS5nbG9iYWwsayYmMD09PW4uYWN0aXZlKysmJm4uZXZlbnQudHJpZ2dlcihcImFqYXhTdGFydFwiKSxtLnR5cGU9bS50eXBlLnRvVXBwZXJDYXNlKCksbS5oYXNDb250ZW50PSFxYi50ZXN0KG0udHlwZSksZj1tLnVybCxtLmhhc0NvbnRlbnR8fChtLmRhdGEmJihmPW0udXJsKz0obGIudGVzdChmKT9cIiZcIjpcIj9cIikrbS5kYXRhLGRlbGV0ZSBtLmRhdGEpLG0uY2FjaGU9PT
74370hMSYmKG0udXJsPW5iLnRlc3QoZik/Zi5yZXBsYWNlKG5iLFwiJDFfPVwiK2tiKyspOmYrKGxiLnRlc3QoZik/XCImXCI6XCI/XCIpK1wiXz1cIitrYisrKSksbS5pZk1vZGlmaWVkJiYobi5sYXN0TW9kaWZpZWRbZl0mJnguc2V0UmVxdWVzdEhlYWRlcihcIklmLU1vZGlmaWVkLVNpbmNlXCIsbi5sYXN0TW9kaWZpZWRbZl0pLG4uZXRhZ1tmXSYmeC5zZXRSZXF1ZXN0SGVhZGVyKFwiSWYtTm9uZS1NYXRjaFwiLG4uZXRhZ1tmXSkpLChtLmRhdGEmJm0uaGFzQ29udGVudCYmbS5jb250ZW50VHlwZSE9PSExfHxjLmNvbnRlbnRUeXBlKSYmeC5zZXRSZXF1ZXN0SGVhZGVyKFwiQ29udGVudC1UeXBlXCIsbS5jb250ZW50VHlwZSkseC5zZXRSZXF1ZXN0SGVhZGVyKFwiQWNjZXB0XCIsbS5kYXRhVHlwZXNbMF0mJm0uYWNjZXB0c1ttLmRhdGFUeXBlc1swXV0/bS5hY2NlcHRzW20uZGF0YVR5cGVzWzBdXSsoXCIqXCIhPT1tLmRhdGFUeXBlc1swXT9cIiwgXCIrdWIrXCI7IHE9MC4wMVwiOlwiXCIpOm0uYWNjZXB0c1tcIipcIl0pO2ZvcihsIGluIG0uaGVhZGVycyl4LnNldFJlcXVlc3RIZWFkZXIobCxtLmhlYWRlcnNbbF0pO2lmKG0uYmVmb3JlU2VuZCYmKG0uYmVmb3JlU2VuZC5jYWxsKG8seCxtKT09PSExfHwyPT09dikpcmV0dXJuIHguYWJvcnQoKTt3PVwiYWJvcnRcIjtmb3IobCBpbntzdWNjZXNzOjEsZXJyb3I6MSxjb21wbGV0ZToxfSl4W2xdKG1bbF0pO2lmKGU9eGIodGIsbSxjLHgpKXtpZih4LnJlYWR5U3RhdGU9MSxrJiZwLnRyaWdnZXIoXCJhamF4U2VuZFwiLFt4LG1dKSwyPT09dilyZXR1cm4geDttLmFzeW5jJiZtLnRpbWVvdXQ+MCYmKGk9YS5zZXRUaW
74371lb3V0KGZ1bmN0aW9uKCl7eC5hYm9ydChcInRpbWVvdXRcIil9LG0udGltZW91dCkpO3RyeXt2PTEsZS5zZW5kKHQseil9Y2F0Y2goeSl7aWYoISgyPnYpKXRocm93IHk7eigtMSx5KX19ZWxzZSB6KC0xLFwiTm8gVHJhbnNwb3J0XCIpO2Z1bmN0aW9uIHooYixjLGQsaCl7dmFyIGosbCx0LHUsdyx5PWM7MiE9PXYmJih2PTIsaSYmYS5jbGVhclRpbWVvdXQoaSksZT12b2lkIDAsZz1ofHxcIlwiLHgucmVhZHlTdGF0ZT1iPjA/NDowLGo9Yj49MjAwJiYzMDA+Ynx8MzA0PT09YixkJiYodT16YihtLHgsZCkpLHU9QWIobSx1LHgsaiksaj8obS5pZk1vZGlmaWVkJiYodz14LmdldFJlc3BvbnNlSGVhZGVyKFwiTGFzdC1Nb2RpZmllZFwiKSx3JiYobi5sYXN0TW9kaWZpZWRbZl09dyksdz14LmdldFJlc3BvbnNlSGVhZGVyKFwiZXRhZ1wiKSx3JiYobi5ldGFnW2ZdPXcpKSwyMDQ9PT1ifHxcIkhFQURcIj09PW0udHlwZT95PVwibm9jb250ZW50XCI6MzA0PT09Yj95PVwibm90bW9kaWZpZWRcIjooeT11LnN0YXRlLGw9dS5kYXRhLHQ9dS5lcnJvcixqPSF0KSk6KHQ9eSwhYiYmeXx8KHk9XCJlcnJvclwiLDA+YiYmKGI9MCkpKSx4LnN0YXR1cz1iLHguc3RhdHVzVGV4dD0oY3x8eSkrXCJcIixqP3EucmVzb2x2ZVdpdGgobyxbbCx5LHhdKTpxLnJlamVjdFdpdGgobyxbeCx5LHRdKSx4LnN0YXR1c0NvZGUocykscz12b2lkIDAsayYmcC50cmlnZ2VyKGo/XCJhamF4U3VjY2Vzc1wiOlwiYWpheEVycm9yXCIsW3gsbSxqP2w6dF0pLHIuZmlyZVdpdGgobyxbeCx5XSksayYmKHAudHJpZ2dlcihcImFqYXhDb21wbGV0ZVwiLFt4LG1dKSwtLW4uYWN0aXZlfHxuLmV2ZW50LnRyaWdnZXIoXCJhamF4U3RvcFwiKSkpfXJldHVybiB4fSxnZXRKU09OOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gbi5nZXQoYSxiLGMsXCJqc29uXCIpfSxnZXRTY3JpcHQ6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbi5nZXQoYSx2b2lkIDAsYixcInNjcmlwdFwiKX19KSxuLmVhY2goW1wiZ2V0XCIsXCJwb3N0XCJdLGZ1bmN0aW9uKGEsYil7bltiXT1mdW5jdGlvbihhLGMsZCxlKXtyZXR1cm4gbi5pc0Z1bmN0aW9uKGMpJiYoZT1lfHxkLGQ9YyxjPXZvaWQgMCksbi5hamF4KG4uZXh0ZW5kKHt1cmw6YSx0eXBlOmIsZGF0YVR5cGU6ZSxkYXRhOmMsc3VjY2VzczpkfSxuLmlzUGxhaW5PYmplY3QoYSkmJmEpKX19KSxuLl9ldmFsVXJsPWZ1bmN0aW9uKGEpe3JldHVybiBuLmFqYXgoe3VybDphLHR5cGU6XCJHRVRcIixkYXRhVHlwZTpcInNjcmlwdFwiLGFzeW5jOiExLGdsb2JhbDohMSxcInRocm93c1wiOiEwfSl9LG4uZm4uZXh0ZW5kKHt3cmFwQWxsOmZ1bmN0aW9uKGEpe3ZhciBiO3JldHVybiBuLmlzRnVuY3Rpb24oYSk/dGhpcy5lYWNoKGZ1bmN0aW9uKGIpe24odGhpcykud3JhcEFsbChhLmNhbGwodGhpcyxiKSl9KToodGhpc1swXSYmKGI9bihhLHRoaXNbMF0ub3duZXJEb2N1bWVudCkuZXEoMCkuY2xvbmUoITApLHRoaXNbMF0ucGFyZW50Tm9kZSYmYi5pbnNlcnRCZWZvcmUodGhpc1swXSksYi5tYXAoZnVuY3Rpb24oKXt2YXIgYT10aGlzO3doaWxlKGEuZmlyc3RFbGVtZW50Q2hpbGQpYT1hLmZpcnN0RWxlbWVudENoaWxkO3JldHVybiBhfSkuYXBwZW5kKHRoaXMpKSx0aGlzKX0sd3JhcElubmVyOmZ1bmN0aW9uKGEpe3JldHVybiBuLmlzRnVuY3Rpb24oYSk/dGhpcy5lYWNoKGZ1bmN0aW9uKGIpe24odGhpcykud3JhcElubmVyKGEuY2FsbCh0aGlzLGIpKX0pOnRoaXMuZWFjaChmdW5jdGlvbigpe3ZhciBiPW4odGhpcyksYz1iLmNvbnRlbn
7437RzKCk7Yy5sZW5ndGg/Yy53cmFwQWxsKGEpOmIuYXBwZW5kKGEpfSl9LHdyYXA6ZnVuY3Rpb24oYSl7dmFyIGI9bi5pc0Z1bmN0aW9uKGEpO3JldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oYyl7bih0aGlzKS53cmFwQWxsKGI/YS5jYWxsKHRoaXMsYyk6YSl9KX0sdW53cmFwOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMucGFyZW50KCkuZWFjaChmdW5jdGlvbigpe24ubm9kZU5hbWUodGhpcyxcImJvZHlcIil8fG4odGhpcykucmVwbGFjZVdpdGgodGhpcy5jaGlsZE5vZGVzKX0pLmVuZCgpfX0pLG4uZXhwci5maWx0ZXJzLmhpZGRlbj1mdW5jdGlvbihhKXtyZXR1cm4hbi5leHByLmZpbHRlcnMudmlzaWJsZShhKX0sbi5leHByLmZpbHRlcnMudmlzaWJsZT1mdW5jdGlvbihhKXtyZXR1cm4gYS5vZmZzZXRXaWR0aD4wfHxhLm9mZnNldEhlaWdodD4wfHxhLmdldENsaWVudFJlY3RzKCkubGVuZ3RoPjB9O3ZhciBCYj0vJTIwL2csQ2I9L1xcW1xcXSQvLERiPS9cXHI/XFxuL2csRWI9L14oPzpzdWJtaXR8YnV0dG9ufGltYWdlfHJlc2V0fGZpbGUpJC9pLEZiPS9eKD86aW5wdXR8c2VsZWN0fHRleHRhcmVhfGtleWdlbikvaTtmdW5jdGlvbiBHYihhLGIsYyxkKXt2YXIgZTtpZihuLmlzQXJyYXkoYikpbi5lYWNoKGIsZnVuY3Rpb24oYixlKXtjfHxDYi50ZXN0KGEpP2QoYSxlKTpHYihhK1wiW1wiKyhcIm9iamVjdFwiPT10eXBlb2YgZSYmbnVsbCE9ZT9iOlwiXCIpK1wiXVwiLGUsYyxkKX0pO2Vsc2UgaWYoY3x8XCJvYmplY3RcIiE9PW4udHlwZShiKSlkKGEsYik7ZWxzZSBmb3IoZSBpbiBiKUdiKGErXCJbXCIrZStcIl1cIixiW2VdLGMsZCl9bi5wYXJhbT1mdW5jdGlvbihhLGIpe3ZhciBjLGQ9W10sZT1mdW5jdGlvbihhLGIpe2I9bi5pc0Z1bmN0aW9uKGIpP2IoKTpudWxsPT1iP1wiXCI6YixkW2QubGVuZ3RoXT1lbmNvZGVVUklDb21wb25lbnQoYSkrXCI9XCIrZW5jb2RlVVJJQ29tcG9uZW50KGIpfTtpZih2b2lkIDA9PT1iJiYoYj1uLmFqYXhTZXR0aW5ncyYmbi5hamF4U2V0dGluZ3MudHJhZGl0aW9uYWwpLG4uaXNBcnJheShhKXx8YS5qcXVlcnkmJiFuLmlzUGxhaW5PYmplY3QoYSkpbi5lYWNoKGEsZnVuY3Rpb24oKXtlKHRoaXMubmFtZSx0aGlzLnZhbHVlKX0pO2Vsc2UgZm9yKGMgaW4gYSlHYihjLGFbY10sYixlKTtyZXR1cm4gZC5qb2luKFwiJlwiKS5yZXBsYWNlKEJiLFwiK1wiKX0sbi5mbi5leHRlbmQoe3NlcmlhbGl6ZTpmdW5jdGlvbigpe3JldHVybiBuLnBhcmFtKHRoaXMuc2VyaWFsaXplQXJyYXkoKSl9LHNlcmlhbGl6ZUFycmF5OmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMubWFwKGZ1bmN0aW9uKCl7dmFyIGE9bi5wcm9wKHRoaXMsXCJlbGVtZW50c1wiKTtyZXR1cm4gYT9uLm1ha2VBcnJheShhKTp0aGlzfSkuZmlsdGVyKGZ1bmN0aW9uKCl7dmFyIGE9dGhpcy50eXBlO3JldHVybiB0aGlzLm5hbWUmJiFuKHRoaXMpLmlzKFwiOmRpc2FibGVkXCIpJiZGYi50ZXN0KHRoaXMubm9kZU5hbWUpJiYhRWIudGVzdChhKSYmKHRoaXMuY2hlY2tlZHx8IVgudGVzdChhKSl9KS5tYXAoZnVuY3Rpb24oYSxiKXt2YXIgYz1uKHRoaXMpLnZhbCgpO3JldHVybiBudWxsPT1jP251bGw6bi5pc0FycmF5KGMpP24ubWFwKGMsZnVuY3Rpb24oYSl7cmV0dXJue25hbWU6Yi5uYW1lLHZhbHVlOmEucmVwbGFjZShEYixcIlxcclxcblwiKX19KTp7bmFtZTpiLm5hbWUsdmFsdWU6Yy5yZXBsYWNlKERiLFwiXFxyXFxuXCIpfX0pLmdldCgpfX0pLG4uYWpheFNldHRpbmdzLnhocj1mdW5jdGlvbigpe3RyeXtyZXR1cm4gbmV3IGEuWE1MSHR0cFJlcXVlc3R9Y2F0Y2goYil7fX07dmFyIEhiPXswOjIwMCwxMjIzOjIwNH0sSWI9bi5hamF4U2V0dGluZ3MueGhyKCk7bC5jb3JzPSEhSWImJlwid2l0aENyZWRlbnRpYWxzXCJpbiBJYixsLmFqYXg9SWI9ISFJYixuLmFqYXhUcmFuc3BvcnQoZnVuY3Rpb24oYil7dmFyIGMsZDtyZXR1cm4gbC5jb3JzfHxJYiYmIWIuY3Jvc3NEb21haW4/e3NlbmQ6ZnVuY3Rpb24oZSxmKXt2YXIgZyxoPWIueGhyKCk7aWYoaC5vcGVuKGIudHlwZSxiLnVybCxiLmFzeW5jLGIudXNlcm5hbWUsYi5wYXNzd29yZCksYi54aHJGaWVsZHMpZm9yKGcgaW4gYi54aHJGaWVsZHMpaFtnXT1iLnhockZpZWxkc1tnXTtiLm1pbWVUeXBlJiZoLm92ZXJyaWRlTWltZVR5cGUmJmgub3ZlcnJpZGVNaW1lVHlwZShiLm1pbWVUeXBlKSxiLmNyb3NzRG9tYWlufHxlW1wiWC1SZXF1ZXN0ZWQtV2l0aFwiXXx8KGVbXCJYLVJlcXVlc3RlZC1XaXRoXCJdPVwiWE1MSHR0cFJlcXVlc3RcIik7Zm9yKGcgaW4gZSloLnNldFJlcXVlc3RIZWFkZXIoZyxlW2ddKTtjPWZ1bmN0aW9uKGEpe3JldHVybiBmdW5jdGlvbigpe2MmJihjPWQ9aC5vbmxvYWQ9aC5vbmVycm9yPWgub25hYm9ydD1oLm9ucmVhZHlzdGF0ZWNoYW5nZT1udWxsLFwiYWJvcnRcIj09PWE/aC5hYm9ydCgpOlwiZXJyb3JcIj09PWE/XCJudW1iZXJcIiE9dHlwZW9mIGguc3RhdHVzP2YoMCxcImVycm9yXCIpOmYoaC5zdGF0dXMsaC5zdGF0dXNUZXh0KTpmKEhiW2guc3RhdHVzXXx8aC5zdGF0dXMsaC5zdGF0dXNUZXh0LFwidGV4dFwiIT09KGgucmVzcG9uc2VUeXBlfHxcInRleHRcIil8fFwic3RyaW5nXCIhPXR5cGVvZiBoLnJlc3BvbnNlVGV4dD97YmluYXJ5OmgucmVzcG9uc2V9Ont0ZXh0OmgucmVzcG9uc2VUZXh0fSxoLmdldEFsbFJlc3BvbnNlSGVhZGVycygpKSl9fSxoLm9ubG9hZD1jKCksZD1oLm9uZXJyb3I9YyhcImVycm9yXCIpLHZvaWQgMCE9PWgub25hYm9ydD9oLm9uYWJvcnQ9ZDpoLm9ucmVhZHlzdGF0ZWNoYW5nZT1mdW5jdGlvbigpezQ9PT1oLnJlYWR5U3RhdGUmJmEuc2V0VGltZW91dChmdW5jdGlvbigpe2MmJmQoKX0pfSxjPWMoXCJhYm9ydFwiKTt0cnl7aC5zZW5kKGIuaGFzQ29udGVudCYmYi5kYXRhfHxudWxsKX1jYXRjaChpKXtpZihjKXRocm93IGl9fSxhYm9ydDpmdW5jdGlvbigpe2MmJmMoKX19OnZvaWQgMH0pLG4uYWpheFNldHVwKHthY2NlcHRzOntzY3JpcHQ6XCJ0ZXh0L2phdmFzY3JpcHQsIGFwcGxpY2F0aW9uL2phdmFzY3JpcHQsIGFwcGxpY2F0aW9uL2VjbWFzY3JpcHQsIGFwcGxpY2F0aW9uL3gtZWNtYXNjcmlwdFwifSxjb250ZW50czp7c2NyaXB0Oi9cXGIoPzpqYXZhfGVjbWEpc2NyaXB0XFxiL30sY29udmVydGVyczp7XCJ0ZXh0IHNjcmlwdFwiOmZ1bmN0aW9uKGEpe3JldHVybiBuLmdsb2JhbEV2YWwoYSksYX19fSksbi5hamF4UHJlZmlsdGVyKFwic2NyaXB0XCIsZnVuY3Rpb24oYSl7dm9pZCAwPT09YS5jYWNoZSYmKGEuY2FjaGU9ITEpLGEuY3Jvc3
7437NEb21haW4mJihhLnR5cGU9XCJHRVRcIil9KSxuLmFqYXhUcmFuc3BvcnQoXCJzY3JpcHRcIixmdW5jdGlvbihhKXtpZihhLmNyb3NzRG9tYWluKXt2YXIgYixjO3JldHVybntzZW5kOmZ1bmN0aW9uKGUsZil7Yj1uKFwiPHNjcmlwdD5cIikucHJvcCh7Y2hhcnNldDphLnNjcmlwdENoYXJzZXQsc3JjOmEudXJsfSkub24oXCJsb2FkIGVycm9yXCIsYz1mdW5jdGlvbihhKXtiLnJlbW92ZSgpLGM9bnVsbCxhJiZmKFwiZXJyb3JcIj09PWEudHlwZT80MDQ6MjAwLGEudHlwZSl9KSxkLmhlYWQuYXBwZW5kQ2hpbGQoYlswXSl9LGFib3J0OmZ1bmN0aW9uKCl7YyYmYygpfX19fSk7dmFyIEpiPVtdLEtiPS8oPSlcXD8oPz0mfCQpfFxcP1xcPy87bi5hamF4U2V0dXAoe2pzb25wOlwiY2FsbGJhY2tcIixqc29ucENhbGxiYWNrOmZ1bmN0aW9uKCl7dmFyIGE9SmIucG9wKCl8fG4uZXhwYW5kbytcIl9cIitrYisrO3JldHVybiB0aGlzW2FdPSEwLGF9fSksbi5hamF4UHJlZmlsdGVyKFwianNvbiBqc29ucFwiLGZ1bmN0aW9uKGIsYyxkKXt2YXIgZSxmLGcsaD1iLmpzb25wIT09ITEmJihLYi50ZXN0KGIudXJsKT9cInVybFwiOlwic3RyaW5nXCI9PXR5cGVvZiBiLmRhdGEmJjA9PT0oYi5jb250ZW50VHlwZXx8XCJcIikuaW5kZXhPZihcImFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZFwiKSYmS2IudGVzdChiLmRhdGEpJiZcImRhdGFcIik7cmV0dXJuIGh8fFwianNvbnBcIj09PWIuZGF0YVR5cGVzWzBdPyhlPWIuanNvbnBDYWxsYmFjaz1uLmlzRnVuY3Rpb24oYi5qc29ucENhbGxiYWNrKT9iLmpzb25wQ2FsbGJhY2soKTpiLmpzb25wQ2FsbGJhY2ssaD9iW2hdPWJbaF0ucmVwbGFjZShLYixcIiQxXCIrZSk6Yi5qc29ucCE9PSExJiYoYi51cmwrPShsYi50ZXN0KGIudXJsKT9cIiZcIjpcIj9cIikrYi5qc29ucCtcIj1cIitlKSxiLmNvbnZlcnRlcnNbXCJzY3JpcHQganNvblwiXT1mdW5jdGlvbigpe3JldHVybiBnfHxuLmVycm9yKGUrXCIgd2FzIG5vdCBjYWxsZWRcIiksZ1swXX0sYi5kYXRhVHlwZXNbMF09XCJqc29uXCIsZj1hW2VdLGFbZV09ZnVuY3Rpb24oKXtnPWFyZ3VtZW50c30sZC5hbHdheXMoZnVuY3Rpb24oKXt2b2lkIDA9PT1mP24oYSkucmVtb3ZlUHJvcChlKTphW2VdPWYsYltlXSYmKGIuanNvbnBDYWxsYmFjaz1jLmpzb25wQ2FsbGJhY2ssSmIucHVzaChlKSksZyYmbi5pc0Z1bmN0aW9uKGYpJiZmKGdbMF0pLGc9Zj12b2lkIDB9KSxcInNjcmlwdFwiKTp2b2lkIDB9KSxuLnBhcnNlSFRNTD1mdW5jdGlvbihhLGIsYyl7aWYoIWF8fFwic3RyaW5nXCIhPXR5cGVvZiBhKXJldHVybiBudWxsO1wiYm9vbGVhblwiPT10eXBlb2YgYiYmKGM9YixiPSExKSxiPWJ8fGQ7dmFyIGU9eC5leGVjKGEpLGY9IWMmJltdO3JldHVybiBlP1tiLmNyZWF0ZUVsZW1lbnQoZVsxXSldOihlPWNhKFthXSxiLGYpLGYmJmYubGVuZ3RoJiZuKGYpLnJlbW92ZSgpLG4ubWVyZ2UoW10sZS5jaGlsZE5vZGVzKSl9O3ZhciBMYj1uLmZuLmxvYWQ7bi5mbi5sb2FkPWZ1bmN0aW9uKGEsYixjKXtpZihcInN0cmluZ1wiIT10eXBlb2YgYSYmTGIpcmV0dXJuIExiLmFwcGx5KHRoaXMsYXJndW1lbnRzKTt2YXIgZCxlLGYsZz10aGlzLGg9YS5pbmRleE9mKFwiIFwiKTtyZXR1cm4gaD4tMSYmKGQ9bi50cmltKGEuc2xpY2UoaCkpLGE9YS5zbGljZSgwLGgpKSxuLmlzRnVuY3Rpb24oYik/KGM9YixiPXZvaWQgMCk6YiYmXCJvYmplY3RcIj09dHlwZW9mIGImJihlPVwiUE9TVFwiKSxnLmxlbmd0aD4wJiZuLmFqYXgoe3VybDphLHR5cGU6ZXx8XCJHRVRcIixkYXRhVHlwZTpcImh0bWxcIixkYXRhOmJ9KS5kb25lKGZ1bmN0aW9uKGEpe2Y9YXJndW1lbnRzLGcuaHRtbChkP24oXCI8ZGl2PlwiKS5hcHBlbmQobi5wYXJzZUhUTUwoYSkpLmZpbmQoZCk6YSl9KS5hbHdheXMoYyYmZnVuY3Rpb24oYSxiKXtnLmVhY2goZnVuY3Rpb24oKXtjLmFwcGx5KHRoaXMsZnx8W2EucmVzcG9uc2VUZXh0LGIsYV0pfSl9KSx0aGlzfSxuLmVhY2goW1wiYWpheFN0YXJ0XCIsXCJhamF4U3RvcFwiLFwiYWpheENvbXBsZXRlXCIsXCJhamF4RXJyb3JcIixcImFqYXhTdWNjZXNzXCIsXCJhamF4U2VuZFwiXSxmdW5jdGlvbihhLGIpe24uZm5bYl09ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMub24oYixhKX19KSxuLmV4cHIuZmlsdGVycy5hbmltYXRlZD1mdW5jdGlvbihhKXtyZXR1cm4gbi5ncmVwKG4udGltZXJzLGZ1bmN0aW9uKGIpe3JldHVybiBhPT09Yi5lbGVtfSkubGVuZ3RofTtmdW5jdGlvbiBNYihhKXtyZXR1cm4gbi5pc1dpbmRvdyhhKT9hOjk9PT1hLm5vZGVUeXBlJiZhLmRlZmF1bHRWaWV3fW4ub2Zmc2V0PXtzZXRPZmZzZXQ6ZnVuY3Rpb24oYSxiLGMpe3ZhciBkLGUsZixnLGgsaSxqLGs9bi5jc3MoYSxcInBvc2l0aW9uXCIpLGw9bihhKSxtPXt9O1wic3RhdGljXCI9PT1rJiYoYS5zdHlsZS5wb3NpdGlvbj1cInJlbGF0aXZlXCIpLGg9bC5vZmZzZXQoKSxmPW4uY3NzKGEsXCJ0b3BcIiksaT1uLmNzcyhhLFwibGVmdFwiKSxqPShcImFic29sdXRlXCI9PT1rfHxcImZpeGVkXCI9PT1rKSYmKGYraSkuaW5kZXhPZihcImF1dG9cIik+LTEsaj8oZD1sLnBvc2l0aW9uKCksZz1kLnRvcCxlPWQubGVmdCk6KGc9cGFyc2VGbG9hdChmKXx8MCxlPXBhcnNlRmxvYXQoaSl8fDApLG4uaXNGdW5jdGlvbihiKSYmKGI9Yi5jYWxsKGEsYyxuLmV4dGVuZCh7fSxoKSkpLG51bGwhPWIudG9wJiYobS50b3A9Yi50b3AtaC50b3ArZyksbnVsbCE9Yi5sZWZ0JiYobS5sZWZ0PWIubGVmdC1oLmxlZnQrZSksXCJ1c2luZ1wiaW4gYj9iLnVzaW5nLmNhbGwoYSxtKTpsLmNzcyhtKX19LG4uZm4uZXh0ZW5kKHtvZmZzZXQ6ZnVuY3Rpb24oYSl7aWYoYXJndW1lbnRzLmxlbmd0aClyZXR1cm4gdm9pZCAwPT09YT90aGlzOnRoaXMuZWFjaChmdW5jdGlvbihiKXtuLm9mZnNldC5zZXRPZmZzZXQodGhpcyxhLGIpfSk7dmFyIGIsYyxkPXRoaXNbMF0sZT17dG9wOjAsbGVmdDowfSxmPWQmJmQub3duZXJEb2N1bWVudDtpZihmKXJldHVybi
7437BiPWYuZG9jdW1lbnRFbGVtZW50LG4uY29udGFpbnMoYixkKT8oZT1kLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLGM9TWIoZikse3RvcDplLnRvcCtjLnBhZ2VZT2Zmc2V0LWIuY2xpZW50VG9wLGxlZnQ6ZS5sZWZ0K2MucGFnZVhPZmZzZXQtYi5jbGllbnRMZWZ0fSk6ZX0scG9zaXRpb246ZnVuY3Rpb24oKXtpZih0aGlzWzBdKXt2YXIgYSxiLGM9dGhpc1swXSxkPXt0b3A6MCxsZWZ0OjB9O3JldHVyblwiZml4ZWRcIj09PW4uY3NzKGMsXCJwb3NpdGlvblwiKT9iPWMuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk6KGE9dGhpcy5vZmZzZXRQYXJlbnQoKSxiPXRoaXMub2Zmc2V0KCksbi5ub2RlTmFtZShhWzBdLFwiaHRtbFwiKXx8KGQ9YS5vZmZzZXQoKSksZC50b3ArPW4uY3NzKGFbMF0sXCJib3JkZXJUb3BXaWR0aFwiLCEwKSxkLmxlZnQrPW4uY3NzKGFbMF0sXCJib3JkZXJMZWZ0V2lkdGhcIiwhMCkpLHt0b3A6Yi50b3AtZC50b3Atbi5jc3MoYyxcIm1hcmdpblRvcFwiLCEwKSxsZWZ0OmIubGVmdC1kLmxlZnQtbi5jc3MoYyxcIm1hcmdpbkxlZnRcIiwhMCl9fX0sb2Zmc2V0UGFyZW50OmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMubWFwKGZ1bmN0aW9uKCl7dmFyIGE9dGhpcy5vZmZzZXRQYXJlbnQ7d2hpbGUoYSYmXCJzdGF0aWNcIj09PW4uY3NzKGEsXCJwb3NpdGlvblwiKSlhPWEub2Zmc2V0UGFyZW50O3JldHVybiBhfHxFYX0pfX0pLG4uZWFjaCh7c2Nyb2xsTGVmdDpcInBhZ2VYT2Zmc2V0XCIsc2Nyb2xsVG9wOlwicGFnZVlPZmZzZXRcIn0sZnVuY3Rpb24oYSxiKXt2YXIgYz1cInBhZ2VZT2Zmc2V0XCI9PT1iO24uZm5bYV09ZnVuY3Rpb24oZCl7cmV0dXJuIEsodGhpcyxmdW5jdGlvbihhLGQsZSl7dmFyIGY9TWIoYSk7cmV0dXJuIHZvaWQgMD09PWU/Zj9mW2JdOmFbZF06dm9pZChmP2Yuc2Nyb2xsVG8oYz9mLnBhZ2VYT2Zmc2V0OmUsYz9lOmYucGFnZVlPZmZzZXQpOmFbZF09ZSl9LGEsZCxhcmd1bWVudHMubGVuZ3RoKX19KSxuLmVhY2goW1widG9wXCIsXCJsZWZ0XCJdLGZ1bmN0aW9uKGEsYil7bi5jc3NIb29rc1tiXT1HYShsLnBpeGVsUG9zaXRpb24sZnVuY3Rpb24oYSxjKXtyZXR1cm4gYz8oYz1GYShhLGIpLEJhLnRlc3QoYyk/bihhKS5wb3NpdGlvbigpW2JdK1wicHhcIjpjKTp2b2lkIDB9KX0pLG4uZWFjaCh7SGVpZ2h0OlwiaGVpZ2h0XCIsV2lkdGg6XCJ3aWR0aFwifSxmdW5jdGlvbihhLGIpe24uZWFjaCh7cGFkZGluZzpcImlubmVyXCIrYSxjb250ZW50OmIsXCJcIjpcIm91dGVyXCIrYX0s
7437ZnVuY3Rpb24oYyxkKXtuLmZuW2RdPWZ1bmN0aW9uKGQsZSl7dmFyIGY9YXJndW1lbnRzLmxlbmd0aCYmKGN8fFwiYm9vbGVhblwiIT10eXBlb2YgZCksZz1jfHwoZD09PSEwfHxlPT09ITA/XCJtYXJnaW5cIjpcImJvcmRlclwiKTtyZXR1cm4gSyh0aGlzLGZ1bmN0aW9uKGIsYyxkKXt2YXIgZTtyZXR1cm4gbi5pc1dpbmRvdyhiKT9iLmRvY3VtZW50LmRvY3VtZW50RWxlbWVudFtcImNsaWVudFwiK2FdOjk9PT1iLm5vZGVUeXBlPyhlPWIuZG9jdW1lbnRFbGVtZW50LE1hdGgubWF4KGIuYm9keVtcInNjcm9sbFwiK2FdLGVbXCJzY3JvbGxcIithXSxiLmJvZHlbXCJvZmZzZXRcIithXSxlW1wib2Zmc2V0XCIrYV0sZVtcImNsaWVudFwiK2FdKSk6dm9pZCAwPT09ZD9uLmNzcyhiLGMsZyk6bi5zdHlsZShiLGMsZCxnKX0sYixmP2Q6dm9pZCAwLGYsbnVsbCl9fSl9KSxuLmZuLmV4dGVuZCh7YmluZDpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIHRoaXMub24oYSxudWxsLGIsYyl9LHVuYmluZDpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLm9mZihhLG51bGwsYil9LGRlbGVnYXRlOmZ1bmN0aW9uKGEsYixjLGQpe3JldHVybiB0aGlzLm9uKGIsYSxjLGQpfSx1bmRlbGVnYXRlOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gMT09PWFyZ3VtZW50cy5sZW5ndGg/dGhpcy5vZmYoYSxcIioqXCIpOnRoaXMub2ZmKGIsYXx8XCIqKlwiLGMpfSxzaXplOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMubGVuZ3RofX0pLG4uZm4uYW5kU2VsZj1uLmZuLmFkZEJhY2ssXCJmdW5jdGlvblwiPT10eXBlb2YgZGVmaW5lJiZkZWZpbmUuYW1kJiZkZWZpbmUoXCJqcXVlcnlcIixbXSxmdW5jdGlvbigpe3JldHVybiBufSk7dmFyIE5iPWEualF1ZXJ5LE9iPWEuJDtyZXR1cm4gbi5ub0NvbmZsaWN0PWZ1bmN0aW9uKGIpe3JldHVybiBhLiQ9PT1uJiYoYS4kPU9iKSxiJiZhLmpRdWVyeT09PW4mJihhLmpRdWVyeT1OYiksbn0sYnx8KGEualF1ZXJ5PWEuJD1uKSxufSk7IiwiLyohXG4gKiBCb290c3RyYXAgdjMuMy43IChodHRwOi8vZ2V0Ym9vdHN0cmFwLmNvbSlcbiAqIENvcHlyaWdodCAyMDExLTIwMTcgVHdpdHRlciwgSW5jLlxuICogTGljZW5zZWQgdW5kZXIgTUlUIChodHRwczovL2dpdGh1Yi5jb20vdHdicy9ib290c3RyYXAvYmxvYi9tYXN0ZXIvTElDRU5TRSlcbiAqL1xuXG4vKiFcbiAqIEdlbmVyYXRlZCB1c2luZyB0aGUgQm9vdHN0cmFwIEN1c3RvbWl6ZXIgKGh0dHA6Ly9nZXRib290c3RyYXAuY29tL2N1c3RvbWl6ZS8/aWQ9NmYzZjRjMmRlOTQ2MWZiYzc2YTA5MzViOGFlMWRhNDApXG4gKiBDb25maWcgc2F2ZWQgdG8gY29uZmlnLmpzb24gYW5kIGh0dHBzOi8vZ2lzdC5naXRodWIuY29tLzZmM2Y0YzJkZTk0NjFmYmM3NmEwOTM1YjhhZTFkYTQwXG4gKi9cbmlmICh0eXBlb2YgalF1ZXJ5ID09PSAndW5kZWZpbmVkJykge1xuICB0aHJvdyBuZXcgRXJyb3IoJ0Jvb3RzdHJhcFxcJ3MgSmF2YVNjcmlwdCByZXF1aXJlcyBqUXVlcnknKVxufVxuK2Z1bmN0aW9uICgkKSB7XG4gICd1c2Ugc3RyaWN0JztcbiAgdmFyIHZlcnNpb24gPSAkLmZuLmpxdWVyeS5zcGxpdCgnICcpWzBdLnNwbGl0KCcuJylcbiAgaWYgKCh2ZXJzaW9uWzBdIDwgMiAmJiB2ZXJzaW9uWzFdIDwgOSkgfHwgKHZlcnNpb25bMF0gPT0gMSAmJiB2ZXJzaW9uWzFdID09IDkgJiYgdmVyc2lvblsyXSA8IDEpIHx8ICh2ZXJzaW9uWzBdID4gMykpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0Jvb3RzdHJhcFxcJ3MgSmF2YVNjcmlwdCByZXF1aXJlcyBqUXVlcnkgdmVyc2lvbiAxLjkuMSBvciBoaWdoZXIsIGJ1dCBsb3dlciB0aGFuIHZlcnNpb24gNCcpXG4gIH1cbn0oalF1ZXJ5KTtcblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBCb290c3RyYXA6IGRyb3Bkb3duLmpzIHYzLjMuN1xuICogaHR0cDovL2dldGJvb3RzdHJhcC5jb20vamF2YXNjcmlwdC8jZHJvcGRvd25zXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIENvcHlyaWdodCAyMDExLTIwMTYgVHdpdHRlciwgSW5jLlxuICogTGljZW5zZWQgdW5kZXIgTUlUIChodHRwczovL2dpdGh1Yi5jb20vdHdicy9ib290c3RyYXAvYmxvYi9tYXN0ZXIvTElDRU5TRSlcbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqL1xuXG5cbitmdW5jdGlvbiAoJCkge1xuICAndXNlIHN0cmljdCc7XG5cbiAgLy8gRFJPUERPV04gQ0xBU1MgREVGSU5JVElPTlxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgdmFyIGJhY2tkcm9wID0gJy5kcm9wZG93bi1iYWNrZHJvcCdcbiAgdmFyIHRvZ2dsZSAgID0gJ1tkYXRhLXRvZ2dsZT1cImRyb3Bkb3duXCJdJ1xuICB2YXIgRHJvcGRvd24gPSBmdW5jdGlvbiAoZWxlbWVudCkge1xuICAgICQoZWxlbWVudCkub24oJ2NsaWNrLmJzLmRyb3Bkb3duJywgdGhpcy50b2dnbGUpXG4gIH1cblxuICBEcm9wZG93bi5WRVJTSU9OID0gJzMuMy43J1xuXG4gIGZ1bmN0aW9uIGdldFBhcmVudCgkdGhpcykge1xuICAgIHZhciBzZWxlY3RvciA9ICR0aGlzLmF0dHIoJ2RhdGEtdGFyZ2V0JylcblxuICAgIGlmICghc2VsZWN0b3IpIHtcbiAgICAgIHNlbGVjdG9yID0gJHRoaXMuYXR0cignaHJlZicpXG4gICAgICBzZWxlY3RvciA9IHNlbGVjdG9yICYmIC8jW0EtWmEtel0vLnRlc3Qoc2VsZWN0b3IpICYmIHNlbGVjdG9yLnJlcGxhY2UoLy4qKD89I1teXFxzXSokKS8sICcnKSAvLyBzdHJpcCBmb3IgaWU3XG4gICAgfVxuXG4gICAgdmFyICRwYXJlbnQgPSBzZWxlY3RvciAmJiAkKHNlbGVjdG9yKVxuXG4gICAgcmV0dXJuICRwYXJlbnQgJiYgJHBhcmVudC5sZW5ndGggPyAkcGFyZW50IDogJHRoaXMucGFyZW50KClcbiAgfVxuXG4gIGZ1bmN0aW9uIGNsZWFyTWVudXMoZSkge1xuICAgIGlmIChlICYmIGUud2hpY2ggPT09IDMpIHJldHVyblxuICAgICQoYmFja2Ryb3ApLnJlbW92ZSgpXG4gICAgJCh0b2dnbGUpLmVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgdmFyICR0aGlzICAgICAgICAgPSAkKHRoaXMpXG4gICAgICB2Y
7437XIgJHBhcmVudCAgICAgICA9IGdldFBhcmVudCgkdGhpcylcbiAgICAgIHZhciByZWxhdGVkVGFyZ2V0ID0geyByZWxhdGVkVGFyZ2V0OiB0aGlzIH1cblxuICAgICAgaWYgKCEkcGFyZW50Lmhhc0NsYXNzKCdvcGVuJykpIHJldHVyblxuXG4gICAgICBpZiAoZSAmJiBlLnR5cGUgPT0gJ2NsaWNrJyAmJiAvaW5wdXR8dGV4dGFyZWEvaS50ZXN0KGUudGFyZ2V0LnRhZ05hbWUpICYmICQuY29udGFpbnMoJHBhcmVudFswXSwgZS50YXJnZXQpKSByZXR1cm5cblxuICAgICAgJHBhcmVudC50cmlnZ2VyKGUgPSAkLkV2ZW50KCdoaWRlLmJzLmRyb3Bkb3duJywgcmVsYXRlZFRhcmdldCkpXG5cbiAgICAgIGlmIChlLmlzRGVmYXVsdFByZXZlbnRlZCgpKSByZXR1cm5cblxuICAgICAgJHRoaXMuYXR0cignYXJpYS1leHBhbmRlZCcsICdmYWxzZScpXG4gICAgICAkcGFyZW50LnJlbW92ZUNsYXNzKCdvcGVuJykudHJpZ2dlcigkLkV2ZW50KCdoaWRkZW4uYnMuZHJvcGRvd24nLCByZWxhdGVkVGFyZ2V0KSlcbiAgICB9KVxuICB9XG5cbiAgRHJvcGRvd24ucHJvdG90eXBlLnRvZ2dsZSA9IGZ1bmN0aW9uIChlKSB7XG4gICAgdmFyICR0aGlzID0gJCh0aGlzKVxuXG4gICAgaWYgKCR0aGlzLmlzKCcuZGlzYWJsZWQsIDpkaXNhYmxlZCcpKSByZXR1cm5cblxuICAgIHZhciAkcGFyZW50ICA9IGdldFBhcmVudCgkdGhpcylcbiAgICB2YXIgaXNBY3RpdmUgPSAkcGFyZW50Lmhhc0NsYXNzKCdvcGVuJylcblxuICAgIGNsZWFyTWVudXMoKVxuXG4gICAgaWYgKCFpc0FjdGl2ZSkge1xuICAgICAgaWYgKCdvbnRvdWNoc3RhcnQnIGluIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCAmJiAhJHBhcmVudC5jbG9zZXN0KCcubmF2YmFyLW5hdicpLmxlbmd0aCkge1xuICAgICAgICAvLyBpZiBtb2JpbGUgd2UgdXNlIGEgYmFja2Ryb3AgYmVjYXVzZSBjbGljayBldmVudHMgZG9uJ3QgZGVsZWdhdGVcbiAgICAgICAgJChkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKSlcbiAgICAgICAgICAuYWRkQ2xhc3MoJ2Ryb3Bkb3duLWJhY2tkcm9wJylcbiAgICAgICAgICAuaW5zZXJ0QWZ0ZXIoJCh0aGlzKSlcbiAgICAgICAgICAub24oJ2NsaWNrJywgY2xlYXJNZW51cylcbiAgICAgIH1cblxuICAgICAgdmFyIHJlbGF0ZWRUYXJnZXQgPSB7IHJlbGF0ZWRUYXJnZXQ6IHRoaXMgfVxuICAgICAgJHBhcmVudC50cmlnZ2VyKGUgPSAkLkV2ZW50KCdzaG93LmJzLmRyb3Bkb3duJywgcmVsYXRlZFRhcmdldCkpXG5cbiAgICAgIGlmIChlLmlzRGVmYXVsdFByZXZlbnRlZCgpKSByZXR1cm5cblxuICAgICAgJHRoaXNcbiAgICAgICAgLnRyaWdnZXIoJ2ZvY3VzJylcbiAgICAgICAgLmF0dHIoJ2FyaWEtZXhwYW5kZWQnLCAndHJ1ZScpXG5cbiAgICAgICRwYXJlbnRcbiAgICAgICAgLnRvZ2dsZUNsYXNzKCdvcGVuJylcbiAgICAgICAgLnRyaWdnZXIoJC5FdmVudCgnc2hvd24uYnMuZHJvcGRvd24nLCByZWxhdGVkVGFyZ2V0KSlcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIERyb3Bkb3duLnByb3RvdHlwZS5rZXlkb3duID0gZnVuY3Rpb24gKGUpIHtcbiAgICBpZiAoIS8oMzh8NDB8Mjd8MzIpLy50ZXN0KGUud2hpY2gpIHx8IC9pbnB1dHx0ZXh0YXJlYS9pLnRlc3QoZS50YXJnZXQudGFnTmFtZSkpIHJldHVyblxuXG4gICAgdmFyICR0aGlzID0gJCh0aGlzKVxuXG4gICAgZS5wcmV2ZW50RGVmYXVsdCgpXG4gICAgZS5zdG9wUHJvcGFnYXRpb24oKVxuXG4gICAgaWYgKCR0aGlzLmlzKCcuZGlzYWJsZWQsIDpkaXNhYmxlZCcpKSByZXR1cm5cblxuICAgIHZhciAkcGFyZW50ICA9IGdldFBhcmVudCgkdGhpcylcbiAgICB2YXIgaXNBY3RpdmUgPSAkcGFyZW50Lmhhc0NsYXNzKCdvcGVuJylcblxuICAgIGlmICghaXNBY3RpdmUgJiYgZS53aGljaCAhPSAyNyB8fCBpc0FjdGl2ZSAmJiBlLndoaWNoID09IDI3KSB7XG4gICAgICBpZiAoZS53aGljaCA9PSAyNykgJHBhcmVudC5maW5kKHRvZ2dsZSkudHJpZ2dlcignZm9jdXMnKVxuICAgICAgcmV0dXJuICR0aGlzLnRyaWdnZXIoJ2NsaWNrJylcbiAgICB9XG5cbiAgICB2YXIgZGVzYyA9ICcgbGk6bm90KC5kaXNhYmxlZCk6dmlzaWJsZSBhJ1xuICAgIHZhciAkaXRlbXMgPSAkcGFyZW50LmZpbmQoJy5kcm9wZG93bi1tZW51JyArIGRlc2MpXG5cbiAgICBpZiAoISRpdGVtcy5sZW5ndGgpIHJldHVyblxuXG4gICAgdmFyIGluZGV4ID0gJGl0ZW1zLmluZGV4KGUudGFyZ2V0KVxuXG4gICAgaWYgKGUud2hpY2ggPT0gMzggJiYgaW5kZXggPiAwKSAgICAgICAgICAgICAgICAgaW5kZXgtLSAgICAgICAgIC8vIHVwXG4gICAgaWYgKGUud2hpY2ggPT0gNDAgJiYgaW5kZXggPCAkaXRlbXMubGVuZ3RoIC0gMSkgaW5kZXgrKyAgICAgICAgIC8vIGRvd25cbiAgICBpZiAoIX5pbmRleCkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmRleCA9IDBcblxuICAgICRpdGVtcy5lcShpbmRleCkudHJpZ2dlcignZm9jdXMnKVxuICB9XG5cblxuICAvLyBEUk9QRE9XTiBQTFVHSU4gREVGSU5JVElPTlxuICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gIGZ1bmN0aW9uIFBsdWdpbihvcHRpb24pIHtcbiAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciAkdGhpcyA9ICQodGhpcylcbiAgICAgIHZhciBkYXRhICA9ICR0aGlzLmRhdGEoJ2JzLmRyb3Bkb3duJylcblxuICAgICAgaWYgKCFkYXRhKSAkdGhpcy5kYXRhKCdicy5kcm9wZG93bicsIChkYXRhID0gbmV3IERyb3Bkb3duKHRoaXMpKSlcbiAgICAgIGlmICh0eXBlb2Ygb3B0aW9uID09ICdzdHJpbmcnKSBkYXRhW29wdGlvbl0uY2FsbCgkdGhpcylcbiAgICB9KVxuICB9XG5cbiAgdmFyIG9sZCA9ICQuZm4uZHJvcGRvd25cblxuICAkLmZuLmRyb3Bkb3duICAgICAgICAgICAgID0gUGx1Z2luXG4gICQuZm4uZHJvcGRvd24uQ29uc3RydWN0b3IgPSBEcm9wZG93blxuXG5cbiAgLy8gRFJPUERPV04gTk8gQ09ORkxJQ1RcbiAgLy8gPT09PT09PT09PT09PT09PT09PT1cblxuICAkLmZuLmRyb3Bkb3duLm5vQ29uZmxpY3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgJC5mbi5kcm9wZG93biA9IG9sZFxuICAgIHJldHVybi
7437B0aGlzXG4gIH1cblxuXG4gIC8vIEFQUExZIFRPIFNUQU5EQVJEIERST1BET1dOIEVMRU1FTlRTXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgJChkb2N1bWVudClcbiAgICAub24oJ2NsaWNrLmJzLmRyb3Bkb3duLmRhdGEtYXBpJywgY2xlYXJNZW51cylcbiAgICAub24oJ2NsaWNrLmJzLmRyb3Bkb3duLmRhdGEtYXBpJywgJy5kcm9wZG93biBmb3JtJywgZnVuY3Rpb24gKGUpIHsgZS5zdG9wUHJvcGFnYXRpb24oKSB9KVxuICAgIC5vbignY2xpY2suYnMuZHJvcGRvd24uZGF0YS1hcGknLCB0b2dnbGUsIERyb3Bkb3duLnByb3RvdHlwZS50b2dnbGUpXG4gICAgLm9uKCdrZXlkb3duLmJzLmRyb3Bkb3duLmRhdGEtYXBpJywgdG9nZ2xlLCBEcm9wZG93bi5wcm90b3R5cGUua2V5ZG93bilcbiAgICAub24oJ2tleWRvd24uYnMuZHJvcGRvd24uZGF0YS1hcGknLCAnLmRyb3Bkb3duLW1lbnUnLCBEcm9wZG93bi5wcm90b3R5cGUua2V5ZG93bilcblxufShqUXVlcnkpO1xuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIEJvb3RzdHJhcDogdG9vbHRpcC5qcyB2My4zLjdcbiAqIGh0dHA6Ly9nZXRib290c3RyYXAuY29tL2phdmFzY3JpcHQvI3Rvb2x0aXBcbiAqIEluc3BpcmVkIGJ5IHRoZSBvcmlnaW5hbCBqUXVlcnkudGlwc3kgYnkgSmFzb24gRnJhbWVcbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogQ29weXJpZ2h0IDIwMTEtMjAxNiBUd2l0dGVyLCBJbmMuXG4gKiBMaWNlbnNlZCB1bmRlciBNSVQgKGh0dHBzOi8vZ2l0aHViLmNvbS90d2JzL2Jvb3RzdHJhcC9ibG9iL21hc3Rlci9MSUNFTlNFKVxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09ICovXG5cblxuK2Z1bmN0aW9uICgkKSB7XG4gICd1c2Ugc3RyaWN0JztcblxuICAvLyBUT09MVElQIFBVQkxJQyBDTEFTUyBERUZJTklUSU9OXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuICB2YXIgVG9vbHRpcCA9IGZ1bmN0aW9uIChlbGVtZW50LCBvcHRpb25zKSB7XG4gICAgdGhpcy50eXBlICAgICAgID0gbnVsbFxuICAgIHRoaXMub3B0aW9ucyAgICA9IG51bGxcbiAgICB0aGlzLmVuYWJsZWQgICAgPSBudWxsXG4gICAgdGhpcy50aW1lb3V0ICAgID0gbnVsbFxuICAgIHRoaXMuaG92ZXJTdGF0ZSA9IG51bGxcbiAgICB0aGlzLiRlbGVtZW50ICAgPSBudWxsXG4gICAgdGhpcy5pblN0YXRlICAgID0gbnVsbFxuXG4gICAgdGhpcy5pbml0KCd0b29sdGlwJywgZWxlbWVudCwgb3B0aW9ucylcbiAgfVxuXG4gIFRvb2x0aXAuVkVSU0lPTiAgPSAnMy4zLjcnXG5cbiAgVG9vbHRpcC5UUkFOU0lUSU9OX0RVUkFUSU9OID0gMTUwXG5cbiAgVG9vbHRpcC5ERUZBVUxUUyA9IHtcbiAgICBhbmltYXRpb246IHRydWUsXG4gICAgcGxhY2VtZW50OiAndG9wJyxcbiAgICBzZWxlY3RvcjogZmFsc2UsXG4gICAgdGVtcGxhdGU6ICc8ZGl2IGNsYXNzPVwidG9vbHRpcFwiIHJvbGU9XCJ0b29sdGlwXCI+PGRpdiBjbGFzcz1cInRvb2x0aXAtYXJyb3dcIj48L2Rpdj48ZGl2IGNsYXNzPVwidG9vbHRpcC1pbm5lclwiPjwvZGl2PjwvZGl2PicsXG4gICAgdHJpZ2dlcjogJ2hvdmVyIGZvY3VzJyxcbiAgICB0aXRsZTogJycsXG4gICAgZGVsYXk6IDAsXG4gICAgaHRtbDogZmFsc2UsXG4gICAgY29udGFpbmVyOiBmYWxzZSxcbiAgICB2aWV3cG9ydDoge1xuICAgICAgc2VsZWN0b3I6ICdib2R5JyxcbiAgICAgIHBhZGRpbmc6IDBcbiAgICB9XG4gIH1cblxuICBUb29sdGlwLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24gKHR5cGUsIGVsZW1lbnQsIG9wdGlvbnMpIHtcbiAgICB0aGlzLmVuYWJsZWQgICA9IHRydWVcbiAgICB0aGlzLnR5cGUgICAgICA9IHR5cGVcbiAgICB0aGlzLiRlbGVtZW50ICA9ICQoZWxlbWVudClcbiAgICB0aGlzLm9wdGlvbnMgICA9IHRoaXMuZ2V0T3B0aW9ucyhvcHRpb25zKVxuICAgIHRoaXMuJHZpZXdwb3J0ID0gdGhpcy5vcHRpb25zLnZpZXdwb3J0ICYmICQoJC5pc0Z1bmN0aW9uKHRoaXMub3B0aW9ucy52aWV3cG9ydCkgPyB0aGlzLm9wdGlvbnMudmlld3BvcnQuY2FsbCh0aGlzLCB0aGlzLiRlbGVtZW50KSA6ICh0aGlzLm9wdGlvbnMudmlld3BvcnQuc2VsZWN0b3IgfHwgdGhpcy5vcHRpb25zLnZpZXdwb3J0KSlcbiAgICB0aGlzLmluU3RhdGUgICA9IHsgY2xpY2s6IGZhbHNlLCBob3ZlcjogZmFsc2UsIGZvY3VzOiBmYWxzZSB9XG5cbiAgICBpZiAodGhpcy4kZWxlbWVudFswXSBpbnN0YW5jZW9mIGRvY3VtZW50LmNvbnN0cnVjdG9yICYmICF0aGlzLm9wdGlvbnMuc2VsZWN0b3IpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignYHNlbGVjdG9yYCBvcHRpb24gbXVzdCBiZSBzcGVjaWZpZWQgd2hlbiBpbml0aWFsaXppbmcgJyArIHRoaXMudHlwZSArICcgb24gdGhlIHdpbmRvdy5kb2N1bWVudCBvYmplY3QhJylcbiAgICB9XG5cbiAgICB2YXIgdHJpZ2dlcnMgPSB0aGlzLm9wdGlvbnMudHJpZ2dlci5zcGxpdCgnICcpXG5cbiAgICBmb3IgKHZhciBpID0gdHJpZ2dlcnMubGVuZ3RoOyBpLS07KSB7XG4gICAgICB2Y
7437XIgdHJpZ2dlciA9IHRyaWdnZXJzW2ldXG5cbiAgICAgIGlmICh0cmlnZ2VyID09ICdjbGljaycpIHtcbiAgICAgICAgdGhpcy4kZWxlbWVudC5vbignY2xpY2suJyArIHRoaXMudHlwZSwgdGhpcy5vcHRpb25zLnNlbGVjdG9yLCAkLnByb3h5KHRoaXMudG9nZ2xlLCB0aGlzKSlcbiAgICAgIH0gZWxzZSBpZiAodHJpZ2dlciAhPSAnbWFudWFsJykge1xuICAgICAgICB2YXIgZXZlbnRJbiAgPSB0cmlnZ2VyID09ICdob3ZlcicgPyAnbW91c2VlbnRlcicgOiAnZm9jdXNpbidcbiAgICAgICAgdmFyIGV2ZW50T3V0ID0gdHJpZ2dlciA9PSAnaG92ZXInID8gJ21vdXNlbGVhdmUnIDogJ2ZvY3Vzb3V0J1xuXG4gICAgICAgIHRoaXMuJGVsZW1lbnQub24oZXZlbnRJbiAgKyAnLicgKyB0aGlzLnR5cGUsIHRoaXMub3B0aW9ucy5zZWxlY3RvciwgJC5wcm94eSh0aGlzLmVudGVyLCB0aGlzKSlcbiAgICAgICAgdGhpcy4kZWxlbWVudC5vbihldmVudE91dCArICcuJyArIHRoaXMudHlwZSwgdGhpcy5vcHRpb25zLnNlbGVjdG9yLCAkLnByb3h5KHRoaXMubGVhdmUsIHRoaXMpKVxuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMub3B0aW9ucy5zZWxlY3RvciA/XG4gICAgICAodGhpcy5fb3B0aW9ucyA9ICQuZXh0ZW5kKHt9LCB0aGlzLm9wdGlvbnMsIHsgdHJpZ2dlcjogJ21hbnVhbCcsIHNlbGVjdG9yOiAnJyB9KSkgOlxuICAgICAgdGhpcy5maXhUaXRsZSgpXG4gIH1cblxuICBUb29sdGlwLnByb3RvdHlwZS5nZXREZWZhdWx0cyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gVG9vbHRpcC5ERUZBVUxUU1xuICB9XG5cbiAgVG9vbHRpcC5wcm90b3R5cGUuZ2V0T3B0aW9ucyA9IGZ1bmN0aW9uIChvcHRpb25zKSB7XG4gICAgb3B0aW9ucyA9ICQuZXh0ZW5kKHt9LCB0aGlzLmdldERlZmF1bHRzKCksIHRoaXMuJGVsZW1lbnQuZGF0YSgpLCBvcHRpb25zKVxuXG4gICAgaWYgKG9wdGlvbnMuZGVsYXkgJiYgdHlwZW9mIG9wdGlvbnMuZGVsYXkgPT0gJ251bWJlcicpIHtcbiAgICAgIG9wdGlvbnMuZGVsYXkgPSB7XG4gICAgICAgIHNob3c6IG9wdGlvbnMuZGVsYXksXG4gICAgICAgIGhpZGU6IG9wdGlvbnMuZGVsYXlcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gb3B0aW9uc1xuICB9XG5cbiAgVG9vbHRpcC5wcm90b3R5cGUuZ2V0RGVsZWdhdGVPcHRpb25zID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBvcHRpb25zICA9IHt9XG4gICAgdmFyIGRlZmF1bHRzID0gdGhpcy5nZXREZWZhdWx0cygpXG5cbiAgICB0aGlzLl9vcHRpb25zICYmICQuZWFjaCh0aGlzLl9vcHRpb25zLCBmdW5jdGlvbiAoa2V5LCB2YWx1ZSkge1xuICAgICAgaWYgKGRlZmF1bHRzW2tleV0gIT0gdmFsdWUpIG9wdGlvbnNba2V5XSA9IHZhbHVlXG4gICAgfSlcblxuICAgIHJldHVybiBvcHRpb25zXG4gIH1cblxuICBUb29sdGlwLnByb3RvdHlwZS5lbnRlciA9IGZ1bmN0aW9uIChvYmopIHtcbiAgICB2YXIgc2VsZiA9IG9iaiBpbnN0YW5jZW9mIHRoaXMuY29uc3RydWN0b3IgP1xuICAgICAgb2JqIDogJChvYmouY3VycmVudFRhcmdldCkuZGF0YSgnYnMuJyArIHRoaXMudHlwZSlcblxuICAgIGlmICghc2VsZikge1xuICAgICAgc2VsZiA9IG5ldyB0aGlzLmNvbnN0cnVjdG9yKG9iai5jdXJyZW50VGFyZ2V0LCB0aGlzLmdldERlbGVnYXRlT3B0aW9ucygpKVxuICAgICAgJChvYmouY3VycmVudFRhcmdldCkuZGF0YSgnYnMuJyArIHRoaXMudHlwZSwgc2VsZilcbiAgICB9XG5cbiAgICBpZiAob2JqIGluc3RhbmNlb2YgJC5FdmVudCkge1xuICAgICAgc2VsZi5pblN0YXRlW29iai50eXBlID09ICdmb2N1c2luJyA/ICdmb2N1cycgOiAnaG92ZXInXSA9IHRydWVcbiAgICB9XG5cbiAgICBpZiAoc2VsZi50aXAoKS5oYXNDbGFzcygnaW4nKSB8fCBzZWxmLmhvdmVyU3RhdGUgPT0gJ2luJykge1xuICAgICAgc2VsZi5ob3ZlclN0YXRlID0gJ2luJ1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgY2xlYXJUaW1lb3V0KHNlbGYudGltZW91dClcblxuICAgIHNlbGYuaG92ZXJTdGF0ZSA9ICdpbidcblxuICAgIGlmICghc2VsZi5vcHRpb25zLmRlbGF5IHx8ICFzZWxmLm9wdGlvbnMuZGVsYXkuc2hvdykgcmV0dXJuIHNlbGYuc2hvdygpXG5cbiAgICBzZWxmLnRpbWVvdXQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgIGlmIChzZWxmLmhvdmVyU3RhdGUgPT0gJ2luJykgc2VsZi5zaG93KClcbiAgICB9LCBzZWxmLm9wdGlvbnMuZGVsYXkuc2hvdylcbiAgfVxuXG4gIFRvb2x0aXAucHJvdG90eXBlLmlzSW5TdGF0ZVRydWUgPSBmdW5jdGlvbiAoKSB7XG4gICAgZm9yICh2YXIga2V5IGluIHRoaXMuaW5TdGF0ZSkge1xuICAgICAgaWYgKHRoaXMuaW5TdGF0ZVtrZXldKSByZXR1cm4gdHJ1ZVxuICAgIH1cblxuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgVG9vbHRpcC5wcm90b3R5cGUubGVhdmUgPSBmdW5jdGlvbiAob2JqKSB7XG4gICAgdmFyIHNlbGYgPSBvYmogaW5zdGFuY2VvZiB0aGlzLmNvbnN0cnVjdG9yID9cbiAgICAgIG9iaiA6ICQob2JqLmN1cnJlbnRUYXJnZXQpLmRhdGEoJ2JzLicgKyB0aGlzLnR5cGUpXG5cbiAgICBpZiAoIXNlbGYpIHtcbiAgICAgIHNlbGYgPSBuZXcgdGhpcy5jb25zdHJ1Y3RvcihvYmouY3VycmVudFRhcmdldCwgdGhpcy5nZXREZWxlZ2F0ZU9wdGlvbnMoKSlcbiAgICAgICQob2JqLmN1cnJlbnRUYXJnZXQpLmRhdGEoJ2JzLicgKyB0aGlzLnR5cGUsIHNlbGYpXG4gICAgfVxuXG4gICAgaWYgKG9iaiBpbnN0YW5jZW9mICQuRXZlbnQpIHtcbiAgICAgIHNlbGYuaW5TdGF0ZVtvYmoudHlwZSA9PSAnZm9jdXNvdXQnID8gJ2ZvY3VzJyA6ICdob3ZlciddID0gZmFsc2VcbiAgICB9XG5cbiAgICBpZiAoc2VsZi5pc0luU3RhdGVUcnVlKCkpIHJldHVyblxuXG4gICAgY2xlYXJUaW1lb3V0KHNlbGYudGltZW91dClcblxuICAgIHNlbGYuaG92ZXJTdGF0ZSA9ICdvdXQnXG5cbiAgICBpZiAoIXNlbGYub3B0aW9ucy5kZWxheSB8fCAhc2VsZi5vcHRpb25zLmRlbGF5LmhpZGUpIHJldHVybiBzZWxmLmhpZGUoKVxuXG4gICAgc2VsZi50aW1lb3V0ID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICBpZiAoc2VsZi5ob3ZlclN0YXRlID09ICdvdXQnKSBzZWxmLmhpZGUoKVxuICAgIH0sIHNlbGYub3B0aW9ucy5kZWxheS5oaWRlKVxuICB9XG5cbiAgVG9vbHRpcC5wcm90b3R5cGUuc2hvdyA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgZSA9ICQuRXZlbnQoJ3Nob3cuYnMuJyArIHRoaXMudHlwZSlcblxuICAgIGlmICh0aGlzLmhhc0NvbnRlbnQoKSAmJi
7437B0aGlzLmVuYWJsZWQpIHtcbiAgICAgIHRoaXMuJGVsZW1lbnQudHJpZ2dlcihlKVxuXG4gICAgICB2YXIgaW5Eb20gPSAkLmNvbnRhaW5zKHRoaXMuJGVsZW1lbnRbMF0ub3duZXJEb2N1bWVudC5kb2N1bWVudEVsZW1lbnQsIHRoaXMuJGVsZW1lbnRbMF0pXG4gICAgICBpZiAoZS5pc0RlZmF1bHRQcmV2ZW50ZWQoKSB8fCAhaW5Eb20pIHJldHVyblxuICAgICAgdmFyIHRoYXQgPSB0aGlzXG5cbiAgICAgIHZhciAkdGlwID0gdGhpcy50aXAoKVxuXG4gICAgICB2YXIgdGlwSWQgPSB0aGlzLmdldFVJRCh0aGlzLnR5cGUpXG5cbiAgICAgIHRoaXMuc2V0Q29udGVudCgpXG4gICAgICAkdGlwLmF0dHIoJ2lkJywgdGlwSWQpXG4gICAgICB0aGlzLiRlbGVtZW50LmF0dHIoJ2FyaWEtZGVzY3JpYmVkYnknLCB0aXBJZClcblxuICAgICAgaWYgKHRoaXMub3B0aW9ucy5hbmltYXRpb24pICR0aXAuYWRkQ2xhc3MoJ2ZhZGUnKVxuXG4gICAgICB2YXIgcGxhY2VtZW50ID0gdHlwZW9mIHRoaXMub3B0aW9ucy5wbGFjZW1lbnQgPT0gJ2Z1bmN0aW9uJyA/XG4gICAgICAgIHRoaXMub3B0aW9ucy5wbGFjZW1lbnQuY2FsbCh0aGlzLCAkdGlwWzBdLCB0aGlzLiRlbGVtZW50WzBdKSA6XG4gICAgICAgIHRoaXMub3B0aW9ucy5wbGFjZW1lbnRcblxuICAgICAgdmFyIGF1dG9Ub2tlbiA9IC9cXHM/YXV0bz9cXHM/L2lcbiAgICAgIHZhciBhdXRvUGxhY2UgPSBhdXRvVG9rZW4udGVzdChwbGFjZW1lbnQpXG4gICAgICBpZiAoYXV0b1BsYWNlKSBwbGFjZW1lbnQgPSBwbGFjZW1lbnQucmVwbGFjZShhdXRvVG9rZW4sICcnKSB8fCAndG9wJ1xuXG4gICAgICAkdGlwXG4gICAgICAgIC5kZXRhY2goKVxuICAgICAgICAuY3NzKHsgdG9wOiAwLCBsZWZ0OiAwLCBkaXNwbGF5OiAnYmxvY2snIH0pXG4gICAgICAgIC5hZGRDbGFzcyhwbGFjZW1lbnQpXG4gICAgICAgIC5kYXRhKCdicy4nICsgdGhpcy50eXBlLCB0aGlzKVxuXG4gICAgICB0aGlzLm9wdGlvbnMuY29udGFpbmVyID8gJHRpcC5hcHBlbmRUbyh0aGlzLm9wdGlvbnMuY29udGFpbmVyKSA6ICR0aXAuaW5zZXJ0QWZ0ZXIodGhpcy4kZWxlbWVudClcbiAgICAgIHRoaXMuJGVsZW1lbnQudHJpZ2dlcignaW5zZXJ0ZWQuYnMuJyArIHRoaXMudHlwZSlcblxuICAgICAgdmFyIHBvcyAgICAgICAgICA9IHRoaXMuZ2V0UG9zaXRpb24oKVxuICAgICAgdmFyIGFjdHVhbFdpZHRoICA9ICR0aXBbMF0ub2Zmc2V0V2lkdGhcbiAgICAgIHZhciBhY3R1YWxIZWlnaHQgPSAkdGlwWzBdLm9mZnNldEhlaWdodFxuXG4gICAgICBpZiAoYXV0b1BsYWNlKSB7XG4gICAgICAgIHZhciBvcmdQbGFjZW1lbnQgPSBwbGFjZW1lbnRcbiAgICAgICAgdmFyIHZpZXdwb3J0RGltID0gdGhpcy5nZXRQb3NpdGlvbih0aGlzLiR2aWV3cG9ydClcblxuICAgICAgICBwbGFjZW1lbnQgPSBwbGFjZW1lbnQgPT0gJ2JvdHRvbScgJiYgcG9zLmJvdHRvbSArIGFjdHVhbEhlaWdodCA+IHZpZXdwb3J0RGltLmJvdHRvbSA/ICd0b3AnICAgIDpcbiAgICAgICAgICAgICAgICAgICAgcGxhY2VtZW50ID09ICd0b3AnICAgICYmIHBvcy50b3AgICAgLSBhY3R1YWxIZWlnaHQgPCB2aWV3cG9ydERpbS50b3AgICAgPyAnYm90dG9tJyA6XG4gICAgICAgICAgICAgICAgICAgIHBsYWNlbWVudCA9PSAncmlnaHQnICAmJiBwb3MucmlnaHQgICsgYWN0dWFsV2lkdGggID4gdmlld3BvcnREaW0ud2lkdGggID8gJ2xlZnQnICAgOlxuICAgICAgICAgICAgICAgICAgICBwbGFjZW1lbnQgPT0gJ2xlZnQnICAgJiYgcG9zLmxlZnQgICAtIGFjdHVhbFdpZHRoICA8IHZpZXdwb3J0RGltLmxlZnQgICA/ICdyaWdodCcgIDpcbiAgICAgICAgICAgICAgICAgICAgcGxhY2VtZW50XG5cbiAgICAgICAgJHRpcFxuICAgICAgICAgIC5yZW1vdmVDbGFzcyhvcmdQbGFjZW1lbnQpXG4gICAgICAgICAgLmFkZENsYXNzKHBsYWNlbWVudClcbiAgICAgIH1cblxuICAgICAgdmFyIGNhbGN1bGF0ZWRPZmZzZXQgPSB0aGlzLmdldENhbGN1bGF0ZWRPZmZzZXQocGxhY2VtZW50LCBwb3MsIGFjdHVhbFdpZHRoLCBhY3R1YWxIZWlnaHQpXG5cbiAgICAgIHRoaXMuYXBwbHlQbGFjZW1lbnQoY2FsY3VsYXRlZE9mZnNldCwgcGxhY2VtZW50KVxuXG4gICAgICB2Y
7437XIgY29tcGxldGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBwcmV2SG92ZXJTdGF0ZSA9IHRoYXQuaG92ZXJTdGF0ZVxuICAgICAgICB0aGF0LiRlbGVtZW50LnRyaWdnZXIoJ3Nob3duLmJzLicgKyB0aGF0LnR5cGUpXG4gICAgICAgIHRoYXQuaG92ZXJTdGF0ZSA9IG51bGxcblxuICAgICAgICBpZiAocHJldkhvdmVyU3RhdGUgPT0gJ291dCcpIHRoYXQubGVhdmUodGhhdClcbiAgICAgIH1cblxuICAgICAgJC5zdXBwb3J0LnRyYW5zaXRpb24gJiYgdGhpcy4kdGlwLmhhc0NsYXNzKCdmYWRlJykgP1xuICAgICAgICAkdGlwXG4gICAgICAgICAgLm9uZSgnYnNUcmFuc2l0aW9uRW5kJywgY29tcGxldGUpXG4gICAgICAgICAgLmVtdWxhdGVUcmFuc2l0aW9uRW5kKFRvb2x0aXAuVFJBTlNJVElPTl9EVVJBVElPTikgOlxuICAgICAgICBjb21wbGV0ZSgpXG4gICAgfVxuICB9XG5cbiAgVG9vbHRpcC5wcm90b3R5cGUuYXBwbHlQbGFjZW1lbnQgPSBmdW5jdGlvbiAob2Zmc2V0LCBwbGFjZW1lbnQpIHtcbiAgICB2YXIgJHRpcCAgID0gdGhpcy50aXAoKVxuICAgIHZhciB3aWR0aCAgPSAkdGlwWzBdLm9mZnNldFdpZHRoXG4gICAgdmFyIGhlaWdodCA9ICR0aXBbMF0ub2Zmc2V0SGVpZ2h0XG5cbiAgICAvLyBtYW51YWxseSByZWFkIG1hcmdpbnMgYmVjYXVzZSBnZXRCb3VuZGluZ0NsaWVudFJlY3QgaW5jbHVkZXMgZGlmZmVyZW5jZVxuICAgIHZhciBtYXJnaW5Ub3AgPSBwYXJzZUludCgkdGlwLmNzcygnbWFyZ2luLXRvcCcpLCAxMClcbiAgICB2YXIgbWFyZ2luTGVmdCA9IHBhcnNlSW50KCR0aXAuY3NzKCdtYXJnaW4tbGVmdCcpLCAxMClcblxuICAgIC8vIHdlIG11c3QgY2hlY2sgZm9yIE5hTiBmb3IgaWUgOC85XG4gICAgaWYgKGlzTmFOKG1hcmdpblRvcCkpICBtYXJnaW5Ub3AgID0gMFxuICAgIGlmIChpc05hTihtYXJnaW5MZWZ0KSkgbWFyZ2luTGVmdCA9IDBcblxuICAgIG9mZnNldC50b3AgICs9IG1hcmdpblRvcFxuICAgIG9mZnNldC5sZWZ0ICs9IG1hcmdpbkxlZnRcblxuICAgIC8vICQuZm4ub2Zmc2V0IGRvZXNuJ3Qgcm91bmQgcGl4ZWwgdmFsdWVzXG4gICAgLy8gc28gd2UgdXNlIHNldE9mZnNldCBkaXJlY3RseSB3aXRoIG91ciBvd24gZnVuY3Rpb24gQi0wXG4gICAgJC5vZmZzZXQuc2V0T2Zmc2V0KCR0aXBbMF0sICQuZXh0ZW5kKHtcbiAgICAgIHVzaW5nOiBmdW5jdGlvbiAocHJvcHMpIHtcbiAgICAgICAgJHRpcC5jc3Moe1xuICAgICAgICAgIHRvcDogTWF0aC5yb3VuZChwcm9wcy50b3ApLFxuICAgICAgICAgIGxlZnQ6IE1hdGgucm91bmQocHJvcHMubGVmdClcbiAgICAgICAgfSlcbiAgICAgIH1cbiAgICB9LCBvZmZzZXQpLCAwKVxuXG4gICAgJHRpcC5hZGRDbGFzcygnaW4nKVxuXG4gICAgLy8gY2hlY2sgdG8gc2VlIGlmIHBsYWNpbmcgdGlwIGluIG5ldyBvZmZzZXQgY2F1c2VkIHRoZSB0aXAgdG8gcmVzaXplIGl0c2VsZlxuICAgIHZhciBhY3R1YWxXaWR0aCAgPSAkdGlwWzBdLm9mZnNldFdpZHRoXG4gICAgdmFyIGFjdHVhbEhlaWdodCA9ICR0aXBbMF0ub2Zmc2V0SGVpZ2h0XG5cbiAgICBpZiAocGxhY2VtZW50ID09ICd0b3AnICYmIGFjdHVhbEhlaWdodCAhPSBoZWlnaHQpIHtcbiAgICAgIG9mZnNldC50b3AgPSBvZmZzZXQudG9wICsgaGVpZ2h0IC0gYWN0dWFsSGVpZ2h0XG4gICAgfVxuXG4gICAgdmFyIGRlbHRhID0gdGhpcy5nZXRWaWV3cG9ydEFkanVzdGVkRGVsdGEocGxhY2VtZW50LCBvZmZzZXQsIGFjdHVhbFdpZHRoLCBhY3R1YWxIZWlnaHQpXG5cbiAgICBpZiAoZGVsdGEubGVmdCkgb2Zmc2V0LmxlZnQgKz0gZGVsdGEubGVmdFxuICAgIGVsc2Ugb2Zmc2V0LnRvcCArPSBkZWx0YS50b3BcblxuICAgIHZhciBpc1ZlcnRpY2FsICAgICAgICAgID0gL3RvcHxib3R0b20vLnRlc3QocGxhY2VtZW50KVxuICAgIHZhciBhcnJvd0RlbHRhICAgICAgICAgID0gaXNWZXJ0aWNhbCA/IGRlbHRhLmxlZnQgKiAyIC0gd2lkdGggKyBhY3R1YWxXaWR0aCA6IGRlbHRhLnRvcCAqIDIgLSBoZWlnaHQgKyBhY3R1YWxIZWlnaHRcbiAgICB2YXIgYXJyb3dPZmZzZXRQb3NpdGlvbiA9IGlzVmVydGljYWwgPyAnb2Zmc2V0V2lkdGgnIDogJ29mZnNldEhlaWdodCdcblxuICAgICR0aXAub2Zmc2V0KG9mZnNldClcbiAgICB0aGlzLnJlcGxhY2VBcnJvdyhhcnJvd0RlbHRhLCAkdGlwWzBdW2Fycm93T2Zmc2V0UG9zaXRpb25dLCBpc1ZlcnRpY2FsKVxuICB9XG5cbiAgVG9vbHRpcC5wcm90b3R5cGUucmVwbGFjZUFycm93ID0gZnVuY3Rpb24gKGRlbHRhLCBkaW1lbnNpb24sIGlzVmVydGljYWwpIHtcbiAgICB0aGlzLmFycm93KClcbiAgICAgIC5jc3MoaXNWZXJ0aWNhbCA/ICdsZWZ0JyA6ICd0b3AnLCA1MCAqICgxIC0gZGVsdGEgLyBkaW1lbnNpb24pICsgJyUnKVxuICAgICAgLmNzcyhpc1ZlcnRpY2FsID8gJ3RvcCcgOiAnbGVmdCcsICcnKVxuICB9XG5cbiAgVG9vbHRpcC5wcm90b3R5cGUuc2V0Q29udGVudCA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgJHRpcCAgPSB0aGlzLnRpcCgpXG4gICAgdmFyIHRpdGxlID0gdGhpcy5nZXRUaXRsZSgpXG5cbiAgICAkdGlwLmZpbmQoJy50b29sdGlwLWlubmVyJylbdGhpcy5vcHRpb25zLmh0bWwgPyAnaHRtbCcgOiAndGV4dCddKHRpdGxlKVxuICAgICR0aXAucmVtb3ZlQ2xhc3MoJ2ZhZGUgaW4gdG9wIGJvdHRvbSBsZWZ0IHJpZ2h0JylcbiAgfVxuXG4gIFRvb2x0aXAucHJvdG90eXBlLmhpZGUgPSBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICB2YXIgdGhhdCA9IHRoaXNcbiAgICB2YXIgJHRpcCA9ICQodGhpcy4kdGlwKVxuICAgIHZhciBlICAgID0gJC5FdmVudCgnaGlkZS5icy4nICsgdGhpcy50eXBlKVxuXG4gICAgZnVuY3Rpb24gY29tcGxldGUoKSB7XG4gICAgICBpZiAodGhhdC5ob3ZlclN0YXRlICE9ICdpbicpICR0aXAuZGV0YWNoKClcbiAgICAgIGlmICh0aGF0LiRlbGVtZW50KSB7IC8vIFRPRE86IENoZWNrIHdoZXRoZXIgZ3VhcmRpbmcgdGhpcyBjb2RlIHdpdGggdGhpcyBgaWZgIGlzIHJlYWxseSBuZWNlc3NhcnkuXG4gICAgICAgIHRoYXQuJGVsZW1lbnRcbiAgICAgICAgICAucmVtb3ZlQXR0cignYXJpYS1kZXNjcmliZWRieScpXG4gICAgICAgICAgLnRyaWdnZXIoJ2hpZGRlbi5icy4nICsgdGhhdC50eXBlKVxuICAgICAgfVxuICAgICAgY2FsbGJhY2sgJiYgY2FsbGJhY2soKVxuICAgIH1cblxuICAgI
7437HRoaXMuJGVsZW1lbnQudHJpZ2dlcihlKVxuXG4gICAgaWYgKGUuaXNEZWZhdWx0UHJldmVudGVkKCkpIHJldHVyblxuXG4gICAgJHRpcC5yZW1vdmVDbGFzcygnaW4nKVxuXG4gICAgJC5zdXBwb3J0LnRyYW5zaXRpb24gJiYgJHRpcC5oYXNDbGFzcygnZmFkZScpID9cbiAgICAgICR0aXBcbiAgICAgICAgLm9uZSgnYnNUcmFuc2l0aW9uRW5kJywgY29tcGxldGUpXG4gICAgICAgIC5lbXVsYXRlVHJhbnNpdGlvbkVuZChUb29sdGlwLlRSQU5TSVRJT05fRFVSQVRJT04pIDpcbiAgICAgIGNvbXBsZXRlKClcblxuICAgIHRoaXMuaG92ZXJTdGF0ZSA9IG51bGxcblxuICAgIHJldHVybiB0aGlzXG4gIH1cblxuICBUb29sdGlwLnByb3RvdHlwZS5maXhUaXRsZSA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgJGUgPSB0aGlzLiRlbGVtZW50XG4gICAgaWYgKCRlLmF0dHIoJ3RpdGxlJykgfHwgdHlwZW9mICRlLmF0dHIoJ2RhdGEtb3JpZ2luYWwtdGl0bGUnKSAhPSAnc3RyaW5nJykge1xuICAgICAgJGUuYXR0cignZGF0YS1vcmlnaW5hbC10aXRsZScsICRlLmF0dHIoJ3RpdGxlJykgfHwgJycpLmF0dHIoJ3RpdGxlJywgJycpXG4gICAgfVxuICB9XG5cbiAgVG9vbHRpcC5wcm90b3R5cGUuaGFzQ29udGVudCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5nZXRUaXRsZSgpXG4gIH1cblxuICBUb29sdGlwLnByb3RvdHlwZS5nZXRQb3NpdGlvbiA9IGZ1bmN0aW9uICgkZWxlbWVudCkge1xuICAgICRlbGVtZW50ICAgPSAkZWxlbWVudCB8fCB0aGlzLiRlbGVtZW50XG5cbiAgICB2YXIgZWwgICAgID0gJGVsZW1lbnRbMF1cbiAgICB2YXIgaXNCb2R5ID0gZWwudGFnTmFtZSA9PSAnQk9EWSdcblxuICAgIHZhciBlbFJlY3QgICAgPSBlbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKVxuICAgIGlmIChlbFJlY3Qud2lkdGggPT0gbnVsbCkge1xuICAgICAgLy8gd2lkdGggYW5kIGhlaWdodCBhcmUgbWlzc2luZyBpbiBJRTgsIHNvIGNvbXB1dGUgdGhlbSBtYW51YWxseTsgc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS90d2JzL2Jvb3RzdHJhcC9pc3N1ZXMvMTQwOTNcbiAgICAgIGVsUmVjdCA9ICQuZXh0ZW5kKHt9LCBlbFJlY3QsIHsgd2lkdGg6IGVsUmVjdC5yaWdodCAtIGVsUmVjdC5sZWZ0LCBoZWlnaHQ6IGVsUmVjdC5ib3R0b20gLSBlbFJlY3QudG9wIH0pXG4gICAgfVxuICAgIHZhciBpc1N2ZyA9IHdpbmRvdy5TVkdFbGVtZW50ICYmIGVsIGluc3RhbmNlb2Ygd2luZG93LlNWR0VsZW1lbnRcbiAgICAvLyBBdm9pZCB1c2luZyAkLm9mZnNldCgpIG9uIFNWR3Mgc2luY2UgaXQgZ2l2ZXMgaW5jb3JyZWN0IHJlc3VsdHMgaW4galF1ZXJ5IDMuXG4gICAgLy8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS90d2JzL2Jvb3RzdHJhcC9pc3N1ZXMvMjAyODBcbiAgICB2YXIgZWxPZmZzZXQgID0gaXNCb2R5ID8geyB0b3A6IDAsIGxlZnQ6IDAgfSA6IChpc1N2ZyA/IG51bGwgOiAkZWxlbWVudC5vZmZzZXQoKSlcbiAgICB2YXIgc2Nyb2xsICAgID0geyBzY3JvbGw6IGlzQm9keSA/IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxUb3AgfHwgZG9jdW1lbnQuYm9keS5zY3JvbGxUb3AgOiAkZWxlbWVudC5zY3JvbGxUb3AoKSB9XG4gICAgdmFyIG91dGVyRGltcyA9IGlzQm9keSA/IHsgd2lkdGg6ICQod2luZG93KS53aWR0aCgpLCBoZWlnaHQ6ICQod2luZG93KS5oZWlnaHQoKSB9IDogbnVsbFxuXG4gICAgcmV0dXJuICQuZXh0ZW5kKHt9LCBlbFJlY3QsIHNjcm9sbCwgb3V0ZXJEaW1zLCBlbE9mZnNldClcbiAgfVxuXG4gIFRvb2x0aXAucHJvdG90eXBlLmdldENhbGN1bGF0ZWRPZmZzZXQgPSBmdW5jdGlvbiAocGxhY2VtZW50LCBwb3MsIGFjdHVhbFdpZHRoLCBhY3R1YWxIZWlnaHQpIHtcbiAgICByZXR1cm4gcGxhY2VtZW50ID09ICdib3R0b20nID8geyB0b3A6IHBvcy50b3AgKyBwb3MuaGVpZ2h0LCAgIGxlZnQ6IHBvcy5sZWZ0ICsgcG9zLndpZHRoIC8gMiAtIGFjdHVhbFdpZHRoIC8gMiB9IDpcbiAgICAgICAgICAgcGxhY2VtZW50ID09ICd0b3AnICAgID8geyB0b3A6IHBvcy50b3AgLSBhY3R1YWxIZWlnaHQsIGxlZnQ6IHBvcy5sZWZ0ICsgcG9zLndpZHRoIC8gMiAtIGFjdHVhbFdpZHRoIC8gMiB9IDpcbiAgICAgICAgICAgcGxhY2VtZW50ID09ICdsZWZ0JyAgID8geyB0b3A6IHBvcy50b3AgKyBwb3MuaGVpZ2h0IC8gMiAtIGFjdHVhbEhlaWdodCAvIDIsIGxlZnQ6IHBvcy5sZWZ0IC0gYWN0dWFsV2lkdGggfSA6XG4gICAgICAgIC8qIHBsYWNlbWVudCA9PSAncmlnaHQnICovIHsgdG9wOiBwb3MudG9wICsgcG9zLmhlaWdodCAvIDIgLSBhY3R1YWxIZWlnaHQgLyAyLCBsZWZ0OiBwb3MubGVmdCArIHBvcy53aWR0aCB9XG5cbiAgfVxuXG4gIFRvb2x0aXAucHJvdG90eXBlLmdldFZpZXdwb3J0QWRqdXN0ZWREZWx0YSA9IGZ1bmN0aW9uIChwbGFjZW1lbnQsIHBvcywgYWN0dWFsV2lkdGgsIGFjdHVhbEhlaWdodCkge1xuICAgIHZhciBkZWx0YSA9IHsgdG9wOiAwLCBsZWZ0OiAwIH1cbiAgICBpZiAoIXRoaXMuJHZpZXdwb3J0KSByZXR1cm4gZGVsdGFcblxuICAgIHZhciB2aWV3cG9ydFBhZGRpbmcgPSB0aGlzLm9wdGlvbnMudmlld3BvcnQgJiYgdGhpcy5vcHRpb25zLnZpZXdwb3J0LnBhZGRpbmcgfHwgMFxuICAgIHZhciB2aWV3cG9ydERpbWVuc2lvbnMgPSB0aGlzLmdldFBvc2l0aW9uKHRoaXMuJHZpZXdwb3J0KVxuXG4gICAgaWYgKC9yaWdodHxsZWZ0Ly50ZXN0KHBsYWNlbWVudCkpIHtcbiAgICAgIHZhciB0b3BFZGdlT2Zmc2V0ICAgID0gcG9zLnRvcCAtIHZpZXdwb3J0UGFkZGluZyAtIHZpZXdwb3J0RGltZW5zaW9ucy5zY3JvbGxcbiAgICAgIHZhciBib3R0b21FZGdlT2Zmc2V0ID0gcG9zLnRvcCArIHZpZXdwb3J0UGFkZGluZyAtIHZpZXdwb3J0RGltZW5zaW9ucy5zY3JvbGwgKyBhY3R1YWxIZWlnaHRcbiAgICAgIGlmICh0b3BFZGdlT2Zmc2V0IDwgdmlld3BvcnREaW1lbnNpb25zLnRvcCkgeyAvLyB0b3Agb3ZlcmZsb3dcbiAgICAgICAgZGVsdGEudG9wID0gdmlld3BvcnREaW1lbnNpb25zLnRvcCAtIHRvcEVkZ2VPZmZzZXRcbiAgICAgIH0gZWxzZSBpZiAoYm90dG9tRWRnZU9mZnNldCA+IHZpZXdwb3J0RGltZW5zaW9ucy50b3AgKyB2aWV3cG9ydERpbWVuc2lvbnMuaGVpZ2h0KSB7IC8vIGJvdHRvbSBvdmVyZmxvd1xuICAgICAgICBkZWx0YS50b3AgPSB2aWV3cG9ydERpbWVuc2lvbnMudG9wICsgdmlld3BvcnREaW1lbnNpb25zLmhlaWdodCAtIGJvdHRvbUVkZ2VPZmZzZXRcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIGxlZnRFZGdlT2Zmc2V0ICA9IHBvcy5sZWZ0IC0gdmlld3BvcnRQYWRkaW5nXG4gICAgICB2Y
7437XIgcmlnaHRFZGdlT2Zmc2V0ID0gcG9zLmxlZnQgKyB2aWV3cG9ydFBhZGRpbmcgKyBhY3R1YWxXaWR0aFxuICAgICAgaWYgKGxlZnRFZGdlT2Zmc2V0IDwgdmlld3BvcnREaW1lbnNpb25zLmxlZnQpIHsgLy8gbGVmdCBvdmVyZmxvd1xuICAgICAgICBkZWx0YS5sZWZ0ID0gdmlld3BvcnREaW1lbnNpb25zLmxlZnQgLSBsZWZ0RWRnZU9mZnNldFxuICAgICAgfSBlbHNlIGlmIChyaWdodEVkZ2VPZmZzZXQgPiB2aWV3cG9ydERpbWVuc2lvbnMucmlnaHQpIHsgLy8gcmlnaHQgb3ZlcmZsb3dcbiAgICAgICAgZGVsdGEubGVmdCA9IHZpZXdwb3J0RGltZW5zaW9ucy5sZWZ0ICsgdmlld3BvcnREaW1lbnNpb25zLndpZHRoIC0gcmlnaHRFZGdlT2Zmc2V0XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGRlbHRhXG4gIH1cblxuICBUb29sdGlwLnByb3RvdHlwZS5nZXRUaXRsZSA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgdGl0bGVcbiAgICB2YXIgJGUgPSB0aGlzLiRlbGVtZW50XG4gICAgdmFyIG8gID0gdGhpcy5vcHRpb25zXG5cbiAgICB0aXRsZSA9ICRlLmF0dHIoJ2RhdGEtb3JpZ2luYWwtdGl0bGUnKVxuICAgICAgfHwgKHR5cGVvZiBvLnRpdGxlID09ICdmdW5jdGlvbicgPyBvLnRpdGxlLmNhbGwoJGVbMF0pIDogIG8udGl0bGUpXG5cbiAgICByZXR1cm4gdGl0bGVcbiAgfVxuXG4gIFRvb2x0aXAucHJvdG90eXBlLmdldFVJRCA9IGZ1bmN0aW9uIChwcmVmaXgpIHtcbiAgICBkbyBwcmVmaXggKz0gfn4oTWF0aC5yYW5kb20oKSAqIDEwMDAwMDApXG4gICAgd2hpbGUgKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHByZWZpeCkpXG4gICAgcmV0dXJuIHByZWZpeFxuICB9XG5cbiAgVG9vbHRpcC5wcm90b3R5cGUudGlwID0gZnVuY3Rpb24gKCkge1xuICAgIGlmICghdGhpcy4kdGlwKSB7XG4gICAgICB0aGlzLiR0aXAgPSAkKHRoaXMub3B0aW9ucy50ZW1wbGF0ZSlcbiAgICAgIGlmICh0aGlzLiR0aXAubGVuZ3RoICE9IDEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKHRoaXMudHlwZSArICcgYHRlbXBsYXRlYCBvcHRpb24gbXVzdCBjb25zaXN0IG9mIGV4YWN0bHkgMSB0b3AtbGV2ZWwgZWxlbWVudCEnKVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdGhpcy4kdGlwXG4gIH1cblxuICBUb29sdGlwLnByb3RvdHlwZS5hcnJvdyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gKHRoaXMuJGFycm93ID0gdGhpcy4kYXJyb3cgfHwgdGhpcy50aXAoKS5maW5kKCcudG9vbHRpcC1hcnJvdycpKVxuICB9XG5cbiAgVG9vbHRpcC5wcm90b3R5cGUuZW5hYmxlID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuZW5hYmxlZCA9IHRydWVcbiAgfVxuXG4gIFRvb2x0aXAucHJvdG90eXBlLmRpc2FibGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5lbmFibGVkID0gZmFsc2VcbiAgfVxuXG4gIFRvb2x0aXAucHJvdG90eXBlLnRvZ2dsZUVuYWJsZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5lbmFibGVkID0gIXRoaXMuZW5hYmxlZFxuICB9XG5cbiAgVG9vbHRpcC5wcm90b3R5cGUudG9nZ2xlID0gZnVuY3Rpb24gKGUpIHtcbiAgICB2YXIgc2VsZiA9IHRoaXNcbiAgICBpZiAoZSkge1xuICAgICAgc2VsZiA9ICQoZS5jdXJyZW50VGFyZ2V0KS5kYXRhKCdicy4nICsgdGhpcy50eXBlKVxuICAgICAgaWYgKCFzZWxmKSB7XG4gICAgICAgIHNlbGYgPSBuZXcgdGhpcy5jb25zdHJ1Y3RvcihlLmN1cnJlbnRUYXJnZXQsIHRoaXMuZ2V0RGVsZWdhdGVPcHRpb25zKCkpXG4gICAgICAgICQoZS5jdXJyZW50VGFyZ2V0KS5kYXRhKCdicy4nICsgdGhpcy50eXBlLCBzZWxmKVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChlKSB7XG4gICAgICBzZWxmLmluU3RhdGUuY2xpY2sgPSAhc2VsZi5pblN0YXRlLmNsaWNrXG4gICAgICBpZiAoc2VsZi5pc0luU3RhdGVUcnVlKCkpIHNlbGYuZW50ZXIoc2VsZilcbiAgICAgIGVsc2Ugc2VsZi5sZWF2ZShzZWxmKVxuICAgIH0gZWxzZSB7XG4gICAgICBzZWxmLnRpcCgpLmhhc0NsYXNzKCdpbicpID8gc2VsZi5sZWF2ZShzZWxmKSA6IHNlbGYuZW50ZXIoc2VsZilcbiAgICB9XG4gIH1cblxuICBUb29sdGlwLnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciB0aGF0ID0gdGhpc1xuICAgIGNsZWFyVGltZW91dCh0aGlzLnRpbWVvdXQpXG4gICAgdGhpcy5oaWRlKGZ1bmN0aW9uICgpIHtcbiAgICAgIHRoYXQuJGVsZW1lbnQub2ZmKCcuJyArIHRoYXQudHlwZSkucmVtb3ZlRGF0YSgnYnMuJyArIHRoYXQudHlwZSlcbiAgICAgIGlmICh0aGF0LiR0aXApIHtcbiAgICAgICAgdGhhdC4kdGlwLmRldGFjaCgpXG4gICAgICB9XG4gICAgICB0aGF0LiR0aXAgPSBudWxsXG4gICAgICB0aGF0LiRhcnJvdyA9IG51bGxcbiAgICAgIHRoYXQuJHZpZXdwb3J0ID0gbnVsbFxuICAgICAgdGhhdC4kZWxlbWVudCA9IG51bGxcbiAgICB9KVxuICB9XG5cblxuICAvLyBUT09MVElQIFBMVUdJTiBERUZJTklUSU9OXG4gIC8vID09PT09PT09PT09PT09PT09PT09PT09PT1cblxuICBmdW5jdGlvbiBQbHVnaW4ob3B0aW9uKSB7XG4gICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICB2Y
7437XIgJHRoaXMgICA9ICQodGhpcylcbiAgICAgIHZhciBkYXRhICAgID0gJHRoaXMuZGF0YSgnYnMudG9vbHRpcCcpXG4gICAgICB2YXIgb3B0aW9ucyA9IHR5cGVvZiBvcHRpb24gPT0gJ29iamVjdCcgJiYgb3B0aW9uXG5cbiAgICAgIGlmICghZGF0YSAmJiAvZGVzdHJveXxoaWRlLy50ZXN0KG9wdGlvbikpIHJldHVyblxuICAgICAgaWYgKCFkYXRhKSAkdGhpcy5kYXRhKCdicy50b29sdGlwJywgKGRhdGEgPSBuZXcgVG9vbHRpcCh0aGlzLCBvcHRpb25zKSkpXG4gICAgICBpZiAodHlwZW9mIG9wdGlvbiA9PSAnc3RyaW5nJykgZGF0YVtvcHRpb25dKClcbiAgICB9KVxuICB9XG5cbiAgdmFyIG9sZCA9ICQuZm4udG9vbHRpcFxuXG4gICQuZm4udG9vbHRpcCAgICAgICAgICAgICA9IFBsdWdpblxuICAkLmZuLnRvb2x0aXAuQ29uc3RydWN0b3IgPSBUb29sdGlwXG5cblxuICAvLyBUT09MVElQIE5PIENPTkZMSUNUXG4gIC8vID09PT09PT09PT09PT09PT09PT1cblxuICAkLmZuLnRvb2x0aXAubm9Db25mbGljdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAkLmZuLnRvb2x0aXAgPSBvbGRcbiAgICByZXR1cm4gdGhpc1xuICB9XG5cbn0oalF1ZXJ5KTtcbiIsIi8qKlxuICogRmVhdGhlcmxpZ2h0IC0gdWx0cmEgc2xpbSBqUXVlcnkgbGlnaHRib3hcbiAqIFZlcnNpb24gMS43LjEgLSBodHRwOi8vbm9lbGJvc3MuZ2l0aHViLmlvL2ZlYXRoZXJsaWdodC9cbiAqXG4gKiBDb3B5cmlnaHQgMjAxNywgTm/Dq2wgUmFvdWwgQm9zc2FydCAoaHR0cDovL3d3dy5ub2VsYm9zcy5jb20pXG4gKiBNSVQgTGljZW5zZWQuXG4qKi9cbihmdW5jdGlvbigkKSB7XG5cdFwidXNlIHN0cmljdFwiO1xuXG5cdGlmKCd1bmRlZmluZWQnID09PSB0eXBlb2YgJCkge1xuXHRcdGlmKCdjb25zb2xlJyBpbiB3aW5kb3cpeyB3aW5kb3cuY29uc29sZS5pbmZvKCdUb28gbXVjaCBsaWdodG5lc3MsIEZlYXRoZXJsaWdodCBuZWVkcyBqUXVlcnkuJyk7IH1cblx0XHRyZXR1cm47XG5cdH1cblxuXHQvKiBGZWF0aGVybGlnaHQgaXMgZXhwb3J0ZWQgYXMgJC5mZWF0aGVybGlnaHQuXG5cdCAgIEl0IGlzIGEgZnVuY3Rpb24gdXNlZCB0byBvcGVuIGEgZmVhdGhlcmxpZ2h0IGxpZ2h0Ym94LlxuXG5cdCAgIFt0ZWNoXVxuXHQgICBGZWF0aGVybGlnaHQgdXNlcyBwcm90b3R5cGUgaW5oZXJpdGFuY2UuXG5cdCAgIEVhY2ggb3BlbmVkIGxpZ2h0Ym94IHdpbGwgaGF2ZSBhIGNvcnJlc3BvbmRpbmcgb2JqZWN0LlxuXHQgICBUaGF0IG9iamVjdCBtYXkgaGF2ZSBzb21lIGF0dHJpYnV0ZXMgdGhhdCBvdmVycmlkZSB0aGVcblx0ICAgcHJvdG90eXBlJ3MuXG5cdCAgIEV4dGVuc2lvbnMgY3JlYXRlZCB3aXRoIEZlYXRoZXJsaWdodC5leHRlbmQgd2lsbCBoYXZlIHRoZWlyXG5cdCAgIG93biBwcm90b3R5cGUgdGhhdCBpbmhlcml0cyBmcm9tIEZlYXRoZXJsaWdodCdzIHByb3RvdHlwZSxcblx0ICAgdGh1cyBhdHRyaWJ1dGVzIGNhbiBiZSBvdmVycmlkZW4gZWl0aGVyIGF0IHRoZSBvYmplY3QgbGV2ZWwsXG5cdCAgIG9yIGF0IHRoZSBleHRlbnNpb24gbGV2ZWwuXG5cdCAgIFRvIGNyZWF0ZSBjYWxsYmFja3MgdGhhdCBjaGFpbiB0aGVtc2VsdmVzIGluc3RlYWQgb2Ygb3ZlcnJpZGluZyxcblx0ICAgdXNlIGNoYWluQ2FsbGJhY2tzLlxuXHQgICBGb3IgdGhvc2UgZmFtaWxpYXIgd2l0aCBDb2ZmZWVTY3JpcHQsIHRoaXMgY29ycmVzcG9uZCB0b1xuXHQgICBGZWF0aGVybGlnaHQgYmVpbmcgYSBjbGFzcyBhbmQgdGhlIEdhbGxlcnkgYmVpbmcgYSBjbGFzc1xuXHQgICBleHRlbmRpbmcgRmVhdGhlcmxpZ2h0LlxuXHQgICBUaGUgY2hhaW5DYWxsYmFja3MgaXMgdXNlZCBzaW5jZSB3ZSBkb24ndCBoYXZlIGFjY2VzcyB0b1xuXHQgICBDb2ZmZWVTY3JpcHQncyBgc3VwZXJgLlxuXHQqL1xuXG5cdGZ1bmN0aW9uIEZlYXRoZXJsaWdodCgkY29udGVudCwgY29uZmlnKSB7XG5cdFx0aWYodGhpcyBpbnN0YW5jZW9mIEZlYXRoZXJsaWdodCkgeyAgLyogY2FsbGVkIHdpdGggbmV3ICovXG5cdFx0XHR0aGlzLmlkID0gRmVhdGhlcmxpZ2h0LmlkKys7XG5cdFx0XHR0aGlzLnNldHVwKCRjb250ZW50LCBjb25maWcpO1xuXHRcdFx0dGhpcy5jaGFpbkNhbGxiYWNrcyhGZWF0aGVybGlnaHQuX2NhbGxiYWNrQ2hhaW4pO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR2YXIgZmwgPSBuZXcgRmVhdGhlcmxpZ2h0KCRjb250ZW50LCBjb25maWcpO1xuXHRcdFx0Zmwub3BlbigpO1xuXHRcdFx0cmV0dXJuIGZsO1xuXHRcdH1cblx0fVxuXG5cdHZhciBvcGVuZWQgPSBbXSxcblx0XHRwcnVuZU9wZW5lZCA9IGZ1bmN0aW9uKHJlbW92ZSkge1xuXHRcdFx0b3BlbmVkID0gJC5ncmVwKG9wZW5lZCwgZnVuY3Rpb24oZmwpIHtcblx0XHRcdFx0cmV0dXJuIGZsICE9PSByZW1vdmUgJiYgZmwuJGluc3RhbmNlLmNsb3Nlc3QoJ2JvZHknKS5sZW5ndGggPiAwO1xuXHRcdFx0fSApO1xuXHRcdFx0cmV0dXJuIG9wZW5lZDtcblx0XHR9O1xuXG5cdC8vIFJlbW92ZXMga2V5cyBvZiBgc2V0YCBmcm9tIGBvYmpgIGFuZCByZXR1cm5zIHRoZSByZW1vdmVkIGtleS92YWx1ZXMuXG5cdGZ1bmN0aW9uIHNsaWNlKG9iaiwgc2V0KSB7XG5cdFx0dmFyIHIgPSB7fTtcblx0XHRmb3IgKHZhciBrZXkgaW4gb2JqKSB7XG5cdFx0XHRpZiAoa2V5IGluIHNldCkge1xuXHRcdFx0XHRyW2tleV0gPSBvYmpba2V5XTtcblx0XHRcdFx0ZGVsZXRlIG9ialtrZXldO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gcjtcblx0fVxuXG5cdC8vIE5PVEU6IExpc3Qgb2YgYXZhaWxhYmxlIFtpZnJhbWUgYXR0cmlidXRlc10oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSFRNTC9FbGVtZW50L2lmcmFtZSkuXG5cdHZhciBpRnJhbWVBdHRyaWJ1dGVTZXQgPSB7XG5cdFx0YWxsb3dmdWxsc2NyZWVuOiAxLCBmcmFtZWJvcmRlcjogMSwgaGVpZ2h0OiAxLCBsb25nZGVzYzogMSwgbWFyZ2luaGVpZ2h0OiAxLCBtYXJnaW53aWR0aDogMSxcblx0XHRuYW1lOiAxLCByZWZlcnJlcnBvbGljeTogMSwgc2Nyb2xsaW5nOiAxLCBzYW5kYm94OiAxLCBzcmM6IDEsIHNyY2RvYzogMSwgd2lkdGg6IDFcblx0fTtcblxuXHQvLyBDb252ZXJ0cyBjYW1lbENhc2VkIGF0dHJpYnV0ZXMgdG8gZGFzaGVyaXplZCB2ZXJzaW9ucyBmb3IgZ2l2ZW4gcHJlZml4OlxuXHQvLyAgIHBhcnNlQXR0cnMoe2hlbGxvOiAxLCBoZWxsRnJvemVPdmVyOiAyfSwgJ2hlbGwnKSA9PiB7ZnJvemUtb3ZlcjogMn1cblx0ZnVuY3Rpb24gcGFyc2VBdHRycyhvYmosIHByZWZpeCkge1xuXHRcdHZhciBhdHRycyA9IHt9LFxuXHRcdFx0cmVnZXggPSBuZXcgUmVnRXhwKCdeJyArIHByZWZpeCArICcoW0EtWl0pKC4qKScpO1xuXHRcdGZvciAodmFyIGtleSBpbiBvYmopIHtcblx0XHRcdHZhciBtYXRjaCA9IGtleS5tYXRjaChyZWdleCk7XG5cdFx0XHRpZiAobWF0Y2gpIHtcblx0XHRcdFx0dmFyIGRhc2hlcml6ZWQgPSAobWF0Y2hbMV0gKyBtYXRjaFsyXS5yZXBsYWNlKC8oW0EtWl0pL2csICctJDEnKSkudG9Mb3dlckNhc2UoKTtcblx0XHRcdFx0YXR0cnNbZGFzaGVyaXplZF0gPSBvYmpba2V5XTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIGF0dHJzO1xuXHR9XG5cblx0LyogZG9jdW1lbnQgd2lkZSBrZXkgaGFuZGxlciAqL1xuXHR2YXIgZXZlbnRNYXAgPSB7IGtleXVwOiAnb25LZXlVcCcsIHJlc2l6ZTogJ29uUmVzaXplJyB9O1xuXG5cdHZhciBnbG9iYWxFdmVudEhhbmRsZXIgPSBmdW5jdGlvbihldmVudCkge1xuXHRcdCQuZWFjaChGZWF0aGVybGlnaHQub3BlbmVkKCkucmV2ZXJzZSgpLCBmdW5jdGlvbigpIHtcblx0XHRcdGlmICghZXZlbnQuaXNEZWZhdWx0UHJldmVudGVkKCkpIHtcblx0XHRcdFx0aWYgKGZhbHNlID09PSB0aGlzW2V2ZW50TWFwW2V2ZW50LnR5cGVdXShldmVudCkpIHtcblx0XHRcdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpOyBldmVudC5zdG9wUHJvcGFnYXRpb24oKTsgcmV0dXJuIGZhbHNlO1xuXHRcdFx0ICB9XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH07XG5cblx0dmFyIHRvZ2dsZUdsb2JhbEV2ZW50cyA9IGZ1bmN0aW9uKHNldCkge1xuXHRcdFx0aWYoc2V0ICE9PSBGZWF0aGVybGlnaHQuX2dsb2JhbEhhbmRsZXJJbnN0YWxsZWQpIHtcblx0XHRcdFx0RmVhdGhlcmxpZ2h0Ll9nbG9iYWxIYW5kbGVySW5zdGFsbGVkID0gc2V0O1xuXHRcdFx0XHR2YXIgZXZlbnRzID0gJC5tYXAoZXZlbnRNYXAsIGZ1bmN0aW9uKF8sIG5hbWUpIHsgcmV0dXJuIG5hbWUrJy4nK0ZlYXRoZXJsaWdodC5wcm90b3R5cGUubmFtZXNwYWNlOyB9ICkuam9pbignICcpO1xuXHRcdFx0XHQkKHdpbmRvdylbc2V0ID8gJ29uJyA6ICdvZmYnXShldmVudHMsIGdsb2JhbEV2ZW50SGFuZGxlcik7XG5cdFx0XHR9XG5cdFx0fTtcblxuXHRGZWF0aGVybGlnaHQucHJvdG90eXBlID0ge1xuXHRcdGNvbnN0cnVjdG9yOiBGZWF0aGVybGlnaHQsXG5cdFx0LyoqKiBkZWZhdWx0cyAqKiovXG5cdFx0LyogZXh0ZW5kIGZlYXRoZXJsaWdodCB3aXRoIGRlZmF1bHRzIGFuZCBtZXRob2RzICovXG5cdFx0bmFtZXNwYWNlOiAgICAgICdmZWF0aGVybGlnaHQnLCAgICAgICAgLyogTmFtZSBvZiB0aGUgZXZlbnRzIGFuZCBjc3MgY2xhc3MgcHJlZml4ICovXG5cdFx0dGFyZ2V0QXR0cjogICAgICdkYXRhLWZlYXRoZXJsaWdodCcsICAgLyogQXR0cmlidXRlIG9mIHRoZSB0cmlnZ2VyZWQgZWxlbWVudCB0aGF0IGNvbnRhaW5zIHRoZSBzZWxlY3RvciB0byB0aGUgbGlnaHRib3ggY29udGVudCAqL1xuXHRcdHZhcmlhbnQ6ICAgICAgICBudWxsLCAgICAgICAgICAgICAgICAgIC8qIENsYXNzIHRoYXQgd2lsbCBiZSBhZGRlZCB0byBjaGFuZ2UgbG9vayBvZiB0aGUgbGlnaHRib3ggKi9cblx0XHRyZXNldENzczogICAgICAgZmFsc2UsICAgICAgICAgICAgICAgICAvKiBSZXNldCBhbGwgY3NzICovXG5cdFx0YmFja2dyb3VuZDogICAgIG51bGwsICAgICAgICAgICAgICAgICAgLyogQ3VzdG9tIERPTSBmb3IgdGhlIGJhY2tncm91bmQsIHdyYXBwZXIgYW5kIHR
7437oZSBjbG9zZWJ1dHRvbiAqL1xuXHRcdG9wZW5UcmlnZ2VyOiAgICAnY2xpY2snLCAgICAgICAgICAgICAgIC8qIEV2ZW50IHRoYXQgdHJpZ2dlcnMgdGhlIGxpZ2h0Ym94ICovXG5cdFx0Y2xvc2VUcmlnZ2VyOiAgICdjbGljaycsICAgICAgICAgICAgICAgLyogRXZlbnQgdGhhdCB0cmlnZ2VycyB0aGUgY2xvc2luZyBvZiB0aGUgbGlnaHRib3ggKi9cblx0XHRmaWx0ZXI6ICAgICAgICAgbnVsbCwgICAgICAgICAgICAgICAgICAvKiBTZWxlY3RvciB0byBmaWx0ZXIgZXZlbnRzLiBUaGluayAkKC4uLikub24oJ2NsaWNrJywgZmlsdGVyLCBldmVudEhhbmRsZXIpICovXG5cdFx0cm9vdDogICAgICAgICAgICdib2R5JywgICAgICAgICAgICAgICAgLyogV2hlcmUgdG8gYXBwZW5kIGZlYXRoZXJsaWdodHMgKi9cblx0XHRvcGVuU3BlZWQ6ICAgICAgMjUwLCAgICAgICAgICAgICAgICAgICAvKiBEdXJhdGlvbiBvZiBvcGVuaW5nIGFuaW1hdGlvbiAqL1xuXHRcdGNsb3NlU3BlZWQ6ICAgICAyNTAsICAgICAgICAgICAgICAgICAgIC8qIER1cmF0aW9uIG9mIGNsb3NpbmcgYW5pbWF0aW9uICovXG5cdFx0Y2xvc2VPbkNsaWNrOiAgICdiYWNrZ3JvdW5kJywgICAgICAgICAgLyogQ2xvc2UgbGlnaHRib3ggb24gY2xpY2sgKCdiYWNrZ3JvdW5kJywgJ2FueXdoZXJlJyBvciBmYWxzZSkgKi9cblx0XHRjbG9zZU9uRXNjOiAgICAgdHJ1ZSwgICAgICAgICAgICAgICAgICAvKiBDbG9zZSBsaWdodGJveCB3aGVuIHByZXNzaW5nIGVzYyAqL1xuXHRcdGNsb3NlSWNvbjogICAgICAnJiMxMDAwNTsnLCAgICAgICAgICAgIC8qIENsb3NlIGljb24gKi9cblx0XHRsb2FkaW5nOiAgICAgICAgJycsICAgICAgICAgICAgICAgICAgICAvKiBDb250ZW50IHRvIHNob3cgd2hpbGUgaW5pdGlhbCBjb250ZW50IGlzIGxvYWRpbmcgKi9cblx0XHRwZXJzaXN0OiAgICAgICAgZmFsc2UsICAgICAgICAgICAgICAgICAvKiBJZiBzZXQsIHRoZSBjb250ZW50IHdpbGwgcGVyc2lzdCBhbmQgd2lsbCBiZSBzaG93biBhZ2FpbiB3aGVuIG9wZW5lZCBhZ2Fpbi4gJ3NoYXJlZCcgaXMgYSBzcGVjaWFsIHZhbHVlIHdoZW4gYmluZGluZyBtdWx0aXBsZSBlbGVtZW50cyBmb3IgdGhlbSB0byBzaGFyZSB0aGUgc2FtZSBjb250ZW50ICovXG5cdFx0b3RoZXJDbG9zZTogICAgIG51bGwsICAgICAgICAgICAgICAgICAgLyogU2VsZWN0b3IgZm9yIGFsdGVybmF0ZSBjbG9zZSBidXR0b25zIChlLmcuIFwiYS5jbG9zZVwiKSAqL1xuXHRcdGJlZm9yZU9wZW46ICAgICAkLm5vb3AsICAgICAgICAgICAgICAgIC8qIENhbGxlZCBiZWZvcmUgb3Blbi4gY2FuIHJldHVybiBmYWxzZSB0byBwcmV2ZW50IG9wZW5pbmcgb2YgbGlnaHRib3guIEdldHMgZXZlbnQgYXMgcGFyYW1ldGVyLCB0aGlzIGNvbnRhaW5zIGFsbCBkYXRhICovXG5cdFx0YmVmb3JlQ29udGVudDogICQubm9vcCwgICAgICAgICAgICAgICAgLyogQ2FsbGVkIHdoZW4gY29udGVudCBpcyBsb2FkZWQuIEdldHMgZXZlbnQgYXMgcGFyYW1ldGVyLCB0aGlzIGNvbnRhaW5zIGFsbCBkYXRhICovXG5cdFx0YmVmb3JlQ2xvc2U6ICAgICQubm9vcCwgICAgICAgICAgICAgICAgLyogQ2FsbGVkIGJlZm9yZSBjbG9zZS4gY2FuIHJldHVybiBmYWxzZSB0byBwcmV2ZW50IG9wZW5pbmcgb2YgbGlnaHRib3guIEdldHMgZXZlbnQgYXMgcGFyYW1ldGVyLCB0aGlzIGNvbnRhaW5zIGFsbCBkYXRhICovXG5cdFx0YWZ0ZXJPcGVuOiAgICAgICQubm9vcCwgICAgICAgICAgICAgICAgLyogQ2FsbGVkIGFmdGVyIG9wZW4uIEdldHMgZXZlbnQgYXMgcGFyYW1ldGVyLCB0aGlzIGNvbnRhaW5zIGFsbCBkYXRhICovXG5cdFx0YWZ0ZXJDb250ZW50OiAgICQubm9vcCwgICAgICAgICAgICAgICAgLyogQ2FsbGVkIGFmdGVyIGNvbnRlbnQgaXMgcmVhZHkgYW5kIGhhcyBiZWVuIHNldC4gR2V0cyBldmVudCBhcyBwYXJhbWV0ZXIsIHRoaXMgY29udGFpbnMgYWxsIGRhdGEgKi9cblx0XHRhZnRlckNsb3NlOiAgICAgJC5ub29wLCAgICAgICAgICAgICAgICAvKiBDYWxsZWQgYWZ0ZXIgY2xvc2UuIEdldHMgZXZlbnQgYXMgcGFyYW1ldGVyLCB0aGlzIGNvbnRhaW5zIGFsbCBkYXRhICovXG5cdFx0b25LZXlVcDogICAgICAgICQubm9vcCwgICAgICAgICAgICAgICAgLyogQ2FsbGVkIG9uIGtleSB1cCBmb3IgdGhlIGZyb250bW9zdCBmZWF0aGVybGlnaHQgKi9cblx0XHRvblJlc2l6ZTogICAgICAgJC5ub29wLCAgICAgICAgICAgICAgICAvKiBDYWxsZWQgYWZ0ZXIgbmV3IGNvbnRlbnQgYW5kIHdoZW4gYSB3aW5kb3cgaXMgcmVzaXplZCAqL1xuXHRcdHR5cGU6ICAgICAgICAgICBudWxsLCAgICAgICAgICAgICAgICAgIC8qIFNwZWNpZnkgdHlwZSBvZiBsaWdodGJveC4gSWYgdW5zZXQsIGl0IHdpbGwgY2hlY2sgZm9yIHRoZSB0YXJnZXRBdHRycyB2YWx1ZS4gKi9cblx0XHRjb250ZW50RmlsdGVyczogWydqcXVlcnknLCAnaW1hZ2UnLCAnaHRtbCcsICdhamF4JywgJ2lmcmFtZScsICd0ZXh0J10sIC8qIExpc3Qgb2YgY29udGVudCBmaWx0ZXJzIHRvIHVzZSB0byBkZXRlcm1pbmUgdGhlIGNvbnRlbnQgKi9cblxuXHRcdC8qKiogbWV0aG9kcyAqKiovXG5cdFx0Lyogc2V0dXAgaXRlcmF0ZXMgb3ZlciBhIHNpbmdsZSBpbnN0YW5jZSBvZiBmZWF0aGVybGlnaHQgYW5kIHByZXBhcmVzIHRoZSBiYWNrZ3JvdW5kIGFuZCBiaW5kcyB0aGUgZXZlbnRzICovXG5cdFx0c2V0dXA6IGZ1bmN0aW9uKHRhcmdldCwgY29uZmlnKXtcblx0XHRcdC8qIGFsbCBhcmd1bWVudHMgYXJlIG9wdGlvbmFsICovXG5cdFx0XHRpZiAodHlwZW9mIHRhcmdldCA9PT0gJ29iamVjdCcgJiYgdGFyZ2V0IGluc3RhbmNlb2YgJCA9PT0gZmFsc2UgJiYgIWNvbmZpZykge1xuXHRcdFx0XHRjb25maWcgPSB0YXJnZXQ7XG5cdFx0XHRcdHRhcmdldCA9IHVuZGVmaW5lZDtcblx0XHRcdH1cblxuXHRcdFx0dmFyIHNlbGYgPSAkLmV4dGVuZCh0aGlzLCBjb25maWcsIHt0YXJnZXQ6IHRhcmdldH0pLFxuXHRcdFx0XHRjc3MgPSAhc2VsZi5yZXNldENzcyA/IHNlbGYubmFtZXNwYWNlIDogc2VsZi5uYW1lc3BhY2UrJy1yZXNldCcsIC8qIGJ5IGFkZGluZyAtcmVzZXQgdG8gdGhlIGNsYXNzbmFtZSwgd2UgcmVzZXQgYWxsIHRoZSBkZWZhdWx0IGNzcyAqL1xuXHRcdFx0XHQkYmFja2dyb3VuZCA9ICQoc2VsZi5iYWNrZ3JvdW5kIHx8IFtcblx0XHRcdFx0XHQnPGRp
7437diBjbGFzcz1cIicrY3NzKyctbG9hZGluZyAnK2NzcysnXCI+Jyxcblx0XHRcdFx0XHRcdCc8ZGl2IGNsYXNzPVwiJytjc3MrJy1jb250ZW50XCI+Jyxcblx0XHRcdFx0XHRcdFx0JzxidXR0b24gY2xhc3M9XCInK2NzcysnLWNsb3NlLWljb24gJysgc2VsZi5uYW1lc3BhY2UgKyAnLWNsb3NlXCIgYXJpYS1sYWJlbD1cIkNsb3NlXCI+Jyxcblx0XHRcdFx0XHRcdFx0XHRzZWxmLmNsb3NlSWNvbixcblx0XHRcdFx0XHRcdFx0JzwvYnV0dG9uPicsXG5cdFx0XHRcdFx0XHRcdCc8ZGl2IGNsYXNzPVwiJytzZWxmLm5hbWVzcGFjZSsnLWlubmVyXCI+JyArIHNlbGYubG9hZGluZyArICc8L2Rpdj4nLFxuXHRcdFx0XHRcdFx0JzwvZGl2PicsXG5cdFx0XHRcdFx0JzwvZGl2PiddLmpvaW4oJycpKSxcblx0XHRcdFx0Y2xvc2VCdXR0b25TZWxlY3RvciA9ICcuJytzZWxmLm5hbWVzcGFjZSsnLWNsb3NlJyArIChzZWxmLm90aGVyQ2xvc2UgPyAnLCcgKyBzZWxmLm90aGVyQ2xvc2UgOiAnJyk7XG5cblx0XHRcdHNlbGYuJGluc3RhbmNlID0gJGJhY2tncm91bmQuY2xvbmUoKS5hZGRDbGFzcyhzZWxmLnZhcmlhbnQpOyAvKiBjbG9uZSBET00gZm9yIHRoZSBiYWNrZ3JvdW5kLCB3cmFwcGVyIGFuZCB0aGUgY2xvc2UgYnV0dG9uICovXG5cblx0XHRcdC8qIGNsb3NlIHdoZW4gY2xpY2sgb24gYmFja2dyb3VuZC9hbnl3aGVyZS9udWxsIG9yIGNsb3NlYm94ICovXG5cdFx0XHRzZWxmLiRpbnN0YW5jZS5vbihzZWxmLmNsb3NlVHJpZ2dlcisnLicrc2VsZi5uYW1lc3BhY2UsIGZ1bmN0aW9uKGV2ZW50KSB7XG5cdFx0XHRcdHZhciAkdGFyZ2V0ID0gJChldmVudC50YXJnZXQpO1xuXHRcdFx0XHRpZiggKCdiYWNrZ3JvdW5kJyA9PT0gc2VsZi5jbG9zZU9uQ2xpY2sgICYmICR0YXJnZXQuaXMoJy4nK3NlbGYubmFtZXNwYWNlKSlcblx0XHRcdFx0XHR8fCAnYW55d2hlcmUnID09PSBzZWxmLmNsb3NlT25DbGlja1xuXHRcdFx0XHRcdHx8ICR0YXJnZXQuY2xvc2VzdChjbG9zZUJ1dHRvblNlbGVjdG9yKS5sZW5ndGggKXtcblx0XHRcdFx0XHRzZWxmLmNsb3NlKGV2ZW50KTtcblx0XHRcdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblxuXHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0fSxcblxuXHRcdC8qIHRoaXMgbWV0aG9kIHByZXBhcmVzIHRoZSBjb250ZW50IGFuZCBjb252ZXJ0cyBpdCBpbnRvIGEgalF1ZXJ5IG9iamVjdCBvciBhIHByb21pc2UgKi9cblx0XHRnZXRDb250ZW50OiBmdW5jdGlvbigpe1xuXHRcdFx0aWYodGhpcy5wZXJzaXN0ICE9PSBmYWxzZSAmJiB0aGlzLiRjb250ZW50KSB7XG5cdFx0XHRcdHJldHVybiB0aGlzLiRjb250ZW50O1xuXHRcdFx0fVxuXHRcdFx0dmFyIHNlbGYgPSB0aGlzLFxuXHRcdFx0XHRmaWx0ZXJzID0gdGhpcy5jb25zdHJ1Y3Rvci5jb250ZW50RmlsdGVycyxcblx0XHRcdFx0cmVhZFRhcmdldEF0dHIgPSBmdW5jdGlvbihuYW1lKXsgcmV0dXJuIHNlbGYuJGN1cnJlbnRUYXJnZXQgJiYgc2VsZi4kY3VycmVudFRhcmdldC5hdHRyKG5hbWUpOyB9LFxuXHRcdFx0XHR0YXJnZXRWYWx1ZSA9IHJlYWRUYXJnZXRBdHRyKHNlbGYudGFyZ2V0QXR0ciksXG5cdFx0XHRcdGRhdGEgPSBzZWxmLnRhcmdldCB8fCB0YXJnZXRWYWx1ZSB8fCAnJztcblxuXHRcdFx0LyogRmluZCB3aGljaCBmaWx0ZXIgYXBwbGllcyAqL1xuXHRcdFx0dmFyIGZpbHRlciA9IGZpbHRlcnNbc2VsZi50eXBlXTsgLyogY2hlY2sgZXhwbGljaXQgdHlwZSBsaWtlIHt0eXBlOiAnaW1hZ2UnfSAqL1xuXG5cdFx0XHQvKiBjaGVjayBleHBsaWNpdCB0eXBlIGxpa2UgZGF0YS1mZWF0aGVybGlnaHQ9XCJpbWFnZVwiICovXG5cdFx0XHRpZighZmlsdGVyICYmIGRhdGEgaW4gZmlsdGVycykge1xuXHRcdFx0XHRmaWx0ZXIgPSBmaWx0ZXJzW2RhdGFdO1xuXHRcdFx0XHRkYXRhID0gc2VsZi50YXJnZXQgJiYgdGFyZ2V0VmFsdWU7XG5cdFx0XHR9XG5cdFx0XHRkYXRhID0gZGF0YSB8fCByZWFkVGFyZ2V0QXR0cignaHJlZicpIHx8ICcnO1xuXG5cdFx0XHQvKiBjaGVjayBleHBsaWNpdHkgdHlwZSAmIGNvbnRlbnQgbGlrZSB7aW1hZ2U6ICdwaG90by5qcGcnfSAqL1xuXHRcdFx0aWYoIWZpbHRlcikge1xuXHRcdFx0XHRmb3IodmFyIGZpbHRlck5hbWUgaW4gZmlsdGVycykge1xuXHRcdFx0XHRcdGlmKHNlbGZbZmlsdGVyTmFtZV0pIHtcblx0XHRcdFx0XHRcdGZpbHRlciA9IGZpbHRlcnNbZmlsdGVyTmFtZV07XG5cdFx0XHRcdFx0XHRkYXRhID0gc2VsZltmaWx0ZXJOYW1lXTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Lyogb3RoZXJ3aXNlIGl0J3MgaW1wbGljaXQsIHJ1biBjaGVja3MgKi9cblx0XHRcdGlmKCFmaWx0ZXIpIHtcblx0XHRcdFx0dmFyIHRhcmdldCA9IGRhdGE7XG5cdFx0XHRcdGRhdGEgPSBudWxsO1xuXHRcdFx0XHQkLmVhY2goc2VsZi5jb250ZW50RmlsdGVycywgZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0ZmlsdGVyID0gZmlsdGVyc1t0aGlzXTtcblx0XHRcdFx0XHRpZihmaWx0ZXIudGVzdCkgIHtcblx0XHRcdFx0XHRcdGRhdGEgPSBmaWx0ZXIudGVzdCh0YXJnZXQpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRpZighZGF0YSAmJiBmaWx0ZXIucmVnZXggJiYgdGFyZ2V0Lm1hdGNoICYmIHRhcmdldC5tYXRjaChmaWx0ZXIucmVnZXgpKSB7XG5cdFx0XHRcdFx0XHRkYXRhID0gdGFyZ2V0O1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRyZXR1cm4gIWRhdGE7XG5cdFx0XHRcdH0pO1xuXHRcdFx0XHRpZighZGF0YSkge1xuXHRcdFx0XHRcdGlmKCdjb25zb2xlJyBpbiB3aW5kb3cpeyB3aW5kb3cuY29uc29sZS5lcnJvcignRmVhdGhlcmxpZ2h0OiBubyBjb250ZW50IGZpbHRlciBmb3VuZCAnICsgKHRhcmdldCA/ICcgZm9yIFwiJyArIHRhcmdldCArICdcIicgOiAnIChubyB0YXJnZXQgc3BlY2lmaWVkKScpKTsgfVxuXHRcdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0LyogUHJvY2VzcyBpdCAqL1xuXHRcdFx0cmV0dXJuIGZpbHRlci5wcm9jZXNzLmNhbGwoc2VsZiwgZGF0YSk7XG5cdFx0fSxcblxuXHRcdC8qIHNldHMgdGhlIGNvbnRlbnQgb2YgJGluc3RhbmNlIHRvICRjb250ZW50ICovXG5cdFx0c2V0Q29udGVudDogZnVuY3Rpb24oJGNvbnRlbnQpe1xuXHRcdFx0dmFyIHNlbGYgPSB0aGlzO1xuXHRcdFx0Lyogd2UgbmVlZCBhIHNwZWNpYWwgY2xhc3MgZm9yIHRoZSBpZnJhbWUgKi9cblx0XHRcdGlmKCRjb250ZW50LmlzKCdpZnJhbWUnKSkge1xuXHRcdFx0XHRzZWxmLiRpbnN0YW5jZS5hZGRDbGFzcyhzZWxmLm5hbWVzcGFjZSsnLWlmcmFtZScpO1xuXHRcdFx0fVxuXG5cdFx0XHRzZWxmLiRpbnN0YW5jZS5yZW1vdmVDbGFzcyhzZWxmLm5hbWVzcGFjZSsnLWxvYWRpbmcnKTtcblxuXHRcdFx0LyogcmVwbGFjZSBjb250ZW50IGJ5IGFwcGVuZGluZyB0byBleGlzdGluZyBvbmUgYmVmb3JlIGl0IGlzIHJlbW92ZWRcblx0XHRcdCAgIHRoaXMgaW5zdXJlcyB0aGF0IGZlYXRoZXJsaWdodC1pbm5lciByZW1haW4gYXQgdGhlIHNhbWUgcmVsYXRpdmVcblx0XHRcdFx0IHBvc2l0aW9uIHRvIGFueSBvdGhlciBpdGVtcyBhZGRlZCB0byBmZWF0aGVybGlnaHQtY29udGVudCAqL1xuXHRcdFx0c2VsZi4kaW5zdGFuY2UuZmluZCgnLicrc2VsZi5uYW1lc3BhY2UrJy1pbm5lcicpXG5cdFx0XHRcdC5ub3QoJGNvbnRlbnQpICAgICAgICAgICAgICAgIC8qIGV4Y2x1ZGVkIG5ldyBjb250ZW50LCBpbXBvcnRhbnQgaWYgcGVyc2lzdGVkICovXG5cdFx0XHRcdC5zbGljZSgxKS5yZW1vdmUoKS5lbmQoKSAgICAgIC8qIEluIHRoZSB1bmV4cGVjdGVkIGV2ZW50IHdoZXJlIHRoZXJlIGFyZSBtYW55IGlubmVyIGVsZW1lbnRzLCByZW1vdmUgYWxsIGJ1dCB0aGUgZmlyc3Qgb25lICovXG5cdFx0XHRcdC5yZXBsYWNlV2l0aCgkLmNvbnRhaW5zKHNlbGYuJGluc3RhbmNlWzBdLCAkY29udGVudFswXSkgPyAnJyA6ICRjb250ZW50KTtcblxuXHRcdFx0c2VsZi4kY29udGVudCA9ICRjb250ZW50LmFkZENsYXNzKHNlbGYubmFtZXNwYWNlKyctaW5uZXInKTtcblxuXHRcdFx0cmV0dXJuIHNlbGY7XG5cdFx0fSxcblxuXHRcdC8qIG9wZW5zIHRoZSBsaWdodGJveC4gXCJ0aGlzXCIgY29udGFpbnMgJGluc3RhbmNlIHdpdGggdGhlIGxpZ2h0Ym94LCBhbmQgd2l0aCB0aGUgY29uZmlnLlxuXHRcdFx0UmV0dXJucyBhIHByb21pc2UgdGhhdCBpcyByZXNvbHZlZCBhZnRlciBpcyBzdWNjZXNzZnVsbHkgb3BlbmVkLiAqL1xuXHRcdG9wZW46IGZ1bmN0aW9uKGV2ZW50KXtcblx0XHRcdHZhciBzZWxmID0gdGhpcztcblx0XHRcdHNlbGYuJGluc3RhbmNlLmhpZGUoKS5hcHBlbmRUbyhzZWxmLnJvb3QpO1xuXHRcdFx0aWYoKCFldmVudCB8fCAhZXZlbnQuaXNEZWZhdWx0UHJldmVudGVkKCkpXG5cdFx0XHRcdCYmIHNlbGYuYmVmb3JlT3BlbihldmVudCkgIT09IGZhbHNlKSB7XG5cblx0XHRcdFx0aWYoZXZlbnQpe1xuXHRcdFx0XHRcdGV2ZW50LnByZXZlbn
7437REZWZhdWx0KCk7XG5cdFx0XHRcdH1cblx0XHRcdFx0dmFyICRjb250ZW50ID0gc2VsZi5nZXRDb250ZW50KCk7XG5cblx0XHRcdFx0aWYoJGNvbnRlbnQpIHtcblx0XHRcdFx0XHRvcGVuZWQucHVzaChzZWxmKTtcblxuXHRcdFx0XHRcdHRvZ2dsZUdsb2JhbEV2ZW50cyh0cnVlKTtcblxuXHRcdFx0XHRcdHNlbGYuJGluc3RhbmNlLmZhZGVJbihzZWxmLm9wZW5TcGVlZCk7XG5cdFx0XHRcdFx0c2VsZi5iZWZvcmVDb250ZW50KGV2ZW50KTtcblxuXHRcdFx0XHRcdC8qIFNldCBjb250ZW50IGFuZCBzaG93ICovXG5cdFx0XHRcdFx0cmV0dXJuICQud2hlbigkY29udGVudClcblx0XHRcdFx0XHRcdC5hbHdheXMoZnVuY3Rpb24oJGNvbnRlbnQpe1xuXHRcdFx0XHRcdFx0XHRzZWxmLnNldENvbnRlbnQoJGNvbnRlbnQpO1xuXHRcdFx0XHRcdFx0XHRzZWxmLmFmdGVyQ29udGVudChldmVudCk7XG5cdFx0XHRcdFx0XHR9KVxuXHRcdFx0XHRcdFx0LnRoZW4oc2VsZi4kaW5zdGFuY2UucHJvbWlzZSgpKVxuXHRcdFx0XHRcdFx0LyogQ2FsbCBhZnRlck9wZW4gYWZ0ZXIgZmFkZUluIGlzIGRvbmUgKi9cblx0XHRcdFx0XHRcdC5kb25lKGZ1bmN0aW9uKCl7IHNlbGYuYWZ0ZXJPcGVuKGV2ZW50KTsgfSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHNlbGYuJGluc3RhbmNlLmRldGFjaCgpO1xuXHRcdFx0cmV0dXJuICQuRGVmZXJyZWQoKS5yZWplY3QoKS5wcm9taXNlKCk7XG5cdFx0fSxcblxuXHRcdC8qIGNsb3NlcyB0aGUgbGlnaHRib3guIFwidGhpc1wiIGNvbnRhaW5zICRpbnN0YW5jZSB3aXRoIHRoZSBsaWdodGJveCwgYW5kIHdpdGggdGhlIGNvbmZpZ1xuXHRcdFx0cmV0dXJucyBhIHByb21pc2UsIHJlc29sdmVkIGFmdGVyIHRoZSBsaWdodGJveCBpcyBzdWNjZXNzZnVsbHkgY2xvc2VkLiAqL1xuXHRcdGNsb3NlOiBmdW5jdGlvbihldmVudCl7XG5cdFx0XHR2YXIgc2VsZiA9IHRoaXMsXG5cdFx0XHRcdGRlZmVycmVkID0gJC5EZWZlcnJlZCgpO1xuXG5cdFx0XHRpZihzZWxmLmJlZm9yZUNsb3NlKGV2ZW50KSA9PT0gZmFsc2UpIHtcblx0XHRcdFx0ZGVmZXJyZWQucmVqZWN0KCk7XG5cdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdGlmICgwID09PSBwcnVuZU9wZW5lZChzZWxmKS5sZW5ndGgpIHtcblx0XHRcdFx0XHR0b2dnbGVHbG9iYWxFdmVudHMoZmFsc2UpO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0c2VsZi4kaW5zdGFuY2UuZmFkZU91dChzZWxmLmNsb3NlU3BlZWQsZnVuY3Rpb24oKXtcblx0XHRcdFx0XHRzZWxmLiRpbnN0YW5jZS5kZXRhY2goKTtcblx0XHRcdFx0XHRzZWxmLmFmdGVyQ2xvc2UoZXZlbnQpO1xuXHRcdFx0XHRcdGRlZmVycmVkLnJlc29sdmUoKTtcblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gZGVmZXJyZWQucHJvbWlzZSgpO1xuXHRcdH0sXG5cblx0XHQvKiByZXNpemVzIHRoZSBjb250ZW50IHNvIGl0IGZpdHMgaW4gdmlzaWJsZSBhcmVhIGFuZCBrZWVwcyB0aGUgc2FtZSBhc3BlY3QgcmF0aW8uXG5cdFx0XHRcdERvZXMgbm90aGluZyBpZiBlaXRoZXIgdGhlIHdpZHRoIG9yIHRoZSBoZWlnaHQgaXMgbm90IHNwZWNpZmllZC5cblx0XHRcdFx0Q2FsbGVkIGF1dG9tYXRpY2FsbHkgb24gd2luZG93IHJlc2l6ZS5cblx0XHRcdFx0T3ZlcnJpZGUgaWYgeW91IHdhbnQgZGlmZmVyZW50IGJlaGF2aW9yLiAqL1xuXHRcdHJlc2l6ZTogZnVuY3Rpb24odywgaCkge1xuXHRcdFx0aWYgKHcgJiYgaCkge1xuXHRcdFx0XHQvKiBSZXNldCBhcHBhcmVudCBpbWFnZSBzaXplIGZpcnN0IHNvIGNvbnRhaW5lciBncm93cyAqL1xuXHRcdFx0XHR0aGlzLiRjb250ZW50LmNzcygnd2lkdGgnLCAnJykuY3NzKCdoZWlnaHQnLCAnJyk7XG5cdFx0XHRcdC8qIENhbGN1bGF0ZSB0aGUgd29yc3QgcmF0aW8gc28gdGhhdCBkaW1lbnNpb25zIGZpdCAqL1xuXHRcdFx0XHQgLyogTm90ZTogLTEgdG8gYXZvaWQgcm91bmRpbmcgZXJyb3JzICovXG5cdFx0XHRcdHZhciByYXRpbyA9IE1hdGgubWF4KFxuXHRcdFx0XHRcdHcgIC8gKHBhcnNlSW50KHRoaXMuJGNvbnRlbnQucGFyZW50KCkuY3NzKCd3aWR0aCcpLDEwKS0xKSxcblx0XHRcdFx0XHRoIC8gKHBhcnNlSW50KHRoaXMuJGNvbnRlbnQucGFyZW50KCkuY3NzKCdoZWlnaHQnKSwxMCktMSkpO1xuXHRcdFx0XHQvKiBSZXNpemUgY29udGVudCAqL1xuXHRcdFx0XHRpZiAocmF0aW8gPiAxKSB7XG5cdFx0XHRcdFx0cmF0aW8gPSBoIC8gTWF0aC5mbG9vcihoIC8gcmF0aW8pOyAvKiBSb3VuZCByYXRpbyBkb3duIHNvIGhlaWdodCBjYWxjIHdvcmtzICovXG5cdFx0XHRcdFx0dGhpcy4kY29udGVudC5jc3MoJ3dpZHRoJywgJycgKyB3IC8gcmF0aW8gKyAncHgnKS5jc3MoJ2hlaWdodCcsICcnICsgaCAvIHJhdGlvICsgJ3B4Jyk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9LFxuXG5cdFx0LyogVXRpbGl0eSBmdW5jdGlvbiB0byBjaGFpbiBjYWxsYmFja3Ncblx0XHQgICBbV2FybmluZzogZ3VydS1sZXZlbF1cblx0XHQgICBVc2VkIGJlIGV4dGVuc2lvbnMgdGhhdCB3YW50IHRvIGxldCB1c2VycyBzcGVjaWZ5IGNhbGxiYWNrcyBidXRcblx0XHQgICBhbHNvIG5lZWQgdGhlbXNlbHZlcyB0byB1c2UgdGhlIGNhbGxiYWNrcy5cblx0XHQgICBUaGUgYXJndW1lbnQgJ2NoYWluJyBoYXMgY2FsbGJhY2sgbmFtZXMgYXMga2V5cyBhbmQgZnVuY3Rpb24oc3VwZXIsIGV2ZW50KVxuXHRcdCAgIGFzIHZhbHVlcy4gVGhhdCBmdW5jdGlvbiBpcyBtZWFudCB0byBjYWxsIGBzdXBlcmAgYXQgc29tZSBwb2ludC5cblx0XHQqL1xuXHRcdGNoYWluQ2FsbGJhY2tzOiBmdW5jdGlvbihjaGFpbikge1xuXHRcdFx0Zm9yICh2YXIgbmFtZSBpbiBjaGFpbikge1xuXHRcdFx0XHR0aGlzW25hbWVdID0gJC5wcm94eShjaGFpbltuYW1lXSwgdGhpcywgJC5wcm94eSh0aGlzW25hbWVdLCB0aGlzKSk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9O1xuXG5cdCQuZXh0ZW5kKEZlYXRoZXJsaWdodCwge1xuXHRcdGlkOiAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIFVzZWQgdG8gaWQgc2luZ2xlIGZlYXRoZXJsaWdodCBpbnN0YW5jZXMgKi9cblx0XHRhdXRvQmluZDogICAgICAgJ1tkYXRhLWZlYXRoZXJsaWdodF0nLCAgICAvKiBXaWxsIGF1dG9tYXRpY2FsbHkgYmluZCBlbGVtZW50cyBtYXRjaGluZyB0aGlzIHNlbGVjdG9yLiBDbGVhciBvciBzZXQgYmVmb3JlIG9uUmVhZHkgKi9cblx0XHRkZWZhdWx0czogICAgICAgRmVhdGhlcmxpZ2h0LnByb3RvdHlwZSwgICAvKiBZb3UgY2FuIGFjY2VzcyBhbmQgb3ZlcnJpZGUgYWxsIGRlZmF1bHRzIHVzaW5nICQuZmVhdGhlcmxpZ2h0LmRlZmF1bHRzLCB3aGljaCBpcyBqdXN0IGEg
7437c3lub255bSBmb3IgJC5mZWF0aGVybGlnaHQucHJvdG90eXBlICovXG5cdFx0LyogQ29udGFpbnMgdGhlIGxvZ2ljIHRvIGRldGVybWluZSBjb250ZW50ICovXG5cdFx0Y29udGVudEZpbHRlcnM6IHtcblx0XHRcdGpxdWVyeToge1xuXHRcdFx0XHRyZWdleDogL15bIy5dXFx3LywgICAgICAgICAvKiBBbnl0aGluZyB0aGF0IHN0YXJ0cyB3aXRoIGEgY2xhc3MgbmFtZSBvciBpZGVudGlmaWVycyAqL1xuXHRcdFx0XHR0ZXN0OiBmdW5jdGlvbihlbGVtKSAgICB7IHJldHVybiBlbGVtIGluc3RhbmNlb2YgJCAmJiBlbGVtOyB9LFxuXHRcdFx0XHRwcm9jZXNzOiBmdW5jdGlvbihlbGVtKSB7IHJldHVybiB0aGlzLnBlcnNpc3QgIT09IGZhbHNlID8gJChlbGVtKSA6ICQoZWxlbSkuY2xvbmUodHJ1ZSk7IH1cblx0XHRcdH0sXG5cdFx0XHRpbWFnZToge1xuXHRcdFx0XHRyZWdleDogL1xcLihwbmd8anBnfGpwZWd8Z2lmfHRpZmZ8Ym1wfHN2ZykoXFw/XFxTKik/JC9pLFxuXHRcdFx0XHRwcm9jZXNzOiBmdW5jdGlvbih1cmwpICB7XG5cdFx0XHRcdFx0dmFyIHNlbGYgPSB0aGlzLFxuXHRcdFx0XHRcdFx0ZGVmZXJyZWQgPSAkLkRlZmVycmVkKCksXG5cdFx0XHRcdFx0XHRpbWcgPSBuZXcgSW1hZ2UoKSxcblx0XHRcdFx0XHRcdCRpbWcgPSAkKCc8aW1nIHNyYz1cIicrdXJsKydcIiBhbHQ9XCJcIiBjbGFzcz1cIicrc2VsZi5uYW1lc3BhY2UrJy1pbWFnZVwiIC8+Jyk7XG5cdFx0XHRcdFx0aW1nLm9ubG9hZCAgPSBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdC8qIFN0b3JlIG5hdHVyYWxXaWR0aCAmIGhlaWdodCBmb3IgSUU4ICovXG5cdFx0XHRcdFx0XHQkaW1nLm5hdHVyYWxXaWR0aCA9IGltZy53aWR0aDsgJGltZy5uYXR1cmFsSGVpZ2h0ID0gaW1nLmhlaWdodDtcblx0XHRcdFx0XHRcdGRlZmVycmVkLnJlc29sdmUoICRpbWcgKTtcblx0XHRcdFx0XHR9O1xuXHRcdFx0XHRcdGltZy5vbmVycm9yID0gZnVuY3Rpb24oKSB7IGRlZmVycmVkLnJlamVjdCgkaW1nKTsgfTtcblx0XHRcdFx0XHRpbWcuc3JjID0gdXJsO1xuXHRcdFx0XHRcdHJldHVybiBkZWZlcnJlZC5wcm9taXNlKCk7XG5cdFx0XHRcdH1cblx0XHRcdH0sXG5cdFx0XHRodG1sOiB7XG5cdFx0XHRcdHJlZ2V4OiAvXlxccyo8W1xcdyFdW148XSo+LywgLyogQW55dGhpbmcgdGhhdCBzdGFydHMgd2l0aCBzb21lIGtpbmQgb2YgdmFsaWQgdGFnICovXG5cdFx0XHRcdHByb2Nlc3M6IGZ1bmN0aW9uKGh0bWwpIHsgcmV0dXJuICQoaHRtbCk7IH1cblx0XHRcdH0sXG5cdFx0XHRhamF4OiB7XG5cdFx0XHRcdHJlZ2V4OiAvLi8sICAgICAgICAgICAgLyogQXQgdGhpcyBwb2ludCwgYW55IGNvbnRlbnQgaXMgYXNzdW1lZCB0byBiZSBhbiBVUkwgKi9cblx0XHRcdFx0cHJvY2VzczogZnVuY3Rpb24odXJsKSAge1xuXHRcdFx0XHRcdHZhciBzZWxmID0gdGhpcyxcblx0XHRcdFx0XHRcdGRlZmVycmVkID0gJC5EZWZlcnJlZCgpO1xuXHRcdFx0XHRcdC8qIHdlIGFyZSB1c2luZyBsb2FkIHNvIG9uZSBjYW4gc3BlY2lmeSBhIHRhcmdldCB3aXRoOiB1cmwuaHRtbCAjdGFyZ2V0ZWxlbWVudCAqL1xuXHRcdFx0XHRcdHZhciAkY29udGFpbmVyID0gJCgnPGRpdj48L2Rpdj4nKS5sb2FkKHVybCwgZnVuY3Rpb24ocmVzcG9uc2UsIHN0YXR1cyl7XG5cdFx0XHRcdFx0XHRpZiAoIHN0YXR1cyAhPT0gXCJlcnJvclwiICkge1xuXHRcdFx0XHRcdFx0XHRkZWZlcnJlZC5yZXNvbHZlKCRjb250YWluZXIuY29udGVudHMoKSk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRkZWZlcnJlZC5mYWlsKCk7XG5cdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0cmV0dXJuIGRlZmVycmVkLnByb21pc2UoKTtcblx0XHRcdFx0fVxuXHRcdFx0fSxcblx0XHRcdGlmcmFtZToge1xuXHRcdFx0XHRwcm9jZXNzOiBmdW5jdGlvbih1cmwpIHtcblx0XHRcdFx0XHR2YXIgZGVmZXJyZWQgPSBuZXcgJC5EZWZlcnJlZCgpO1xuXHRcdFx0XHRcdHZhciAkY29udGVudCA9ICQoJzxpZnJhbWUvPicpO1xuXHRcdFx0XHRcdHZhciBjc3MgPSBwYXJzZUF0dHJzKHRoaXMsICdpZnJhbWUnKTtcblx0XHRcdFx0XHR2YXIgYXR0cnMgPSBzbGljZShjc3MsIGlGcmFtZUF0dHJpYnV0ZVNldCk7XG5cdFx0XHRcdFx0JGNvbnRlbnQuaGlkZSgpXG5cdFx0XHRcdFx0XHQuYXR0cignc3JjJywgdXJsKVxuXHRcdFx0XHRcdFx0LmF0dHIoYXR0cnMpXG5cdFx0XHRcdFx0XHQuY3NzKGNzcylcblx0XHRcdFx0XHRcdC5vbignbG9hZCcsIGZ1bmN0aW9uKCkgeyBkZWZlcnJlZC5yZXNvbHZlKCRjb250ZW50LnNob3coKSk7IH0pXG5cdFx0XHRcdFx0XHQvLyBXZSBjYW4ndCBtb3ZlIGFuIDxpZnJhbWU+IGFuZCBhdm9pZCByZWxvYWRpbmcgaXQsXG5cdFx0XHRcdFx0XHQvLyBzbyBsZXQncyBwdXQgaXQgaW4gcGxhY2Ugb3Vyc2VsdmVzIHJpZ2h0IG5vdzpcblx0XHRcdFx0XHRcdC5hcHBlbmRUbyh0aGlzLiRpbnN0YW5jZS5maW5kKCcuJyArIHRoaXMubmFtZXNwYWNlICsgJy1jb250ZW50JykpO1xuXHRcdFx0XHRcdHJldHVybiBkZWZlcnJlZC5wcm9taXNlKCk7XG5cdFx0XHRcdH1cblx0XHRcdH0sXG5cdFx0XHR0ZXh0OiB7XG5cdFx0XHRcdHByb2Nlc3M6IGZ1bmN0aW9uKHRleHQpIHsgcmV0dXJuICQoJzxkaXY+Jywge3RleHQ6IHRleHR9KTsgfVxuXHRcdFx0fVxuXHRcdH0sXG5cblx0XHRmdW5jdGlvbkF0dHJpYnV0ZXM6IFsnYmVmb3JlT3BlbicsICdhZnRlck9wZW4nLCAnYmVmb3JlQ29udGVudCcsICdhZnRlckNvbnRlbnQnLCAnYmVmb3JlQ2xvc2UnLCAnYWZ0ZXJDbG9zZSddLFxuXG5cdFx0LyoqKiBjbGFzcyBtZXRob2RzICoqKi9cblx0XHQvKiByZWFkIGVsZW1lbnQncyBhdHRyaWJ1dGVzIHN0YXJ0aW5nIHdpdGggZGF0YS1mZWF0aGVybGlnaHQtICovXG5cdFx0cmVhZEVsZW1lbnRDb25maWc6IGZ1bmN0aW9uKGVsZW1lbnQsIG5hbWVzcGFjZSkge1xuXHRcdFx0dmFyIEtsYXNzID0gdGhpcyxcblx0XHRcdFx0cmVnZXhwID0gbmV3IFJlZ0V4cCgnXmRhdGEtJyArIG5hbWVzcGFjZSArICctKC4qKScpLFxuXHRcdFx0XHRjb25maWcgPSB7fTtcblx0XHRcdGlmIChlbGVtZW50ICYmIGVsZW1lbnQuYXR0cmlidXRlcykge1xuXHRcdFx0XHQkLmVhY2goZWxlbWVudC5hdHRyaWJ1dGVzLCBmdW5jdGlvbigpe1xuXHRcdFx0XHRcdHZhciBtYXRjaCA9IHRoaXMubmFtZS5tYXRjaChyZWdleHApO1xuXHRcdFx0XHRcdGlmIChtYXRjaCkge1xuXHRcdFx0XHRcdFx0dmFyIHZhbCA9IHRoaXMudmFsdWUsXG5cdFx0XHRcdFx0XHRcdG5hbW
7437UgPSAkLmNhbWVsQ2FzZShtYXRjaFsxXSk7XG5cdFx0XHRcdFx0XHRpZiAoJC5pbkFycmF5KG5hbWUsIEtsYXNzLmZ1bmN0aW9uQXR0cmlidXRlcykgPj0gMCkgeyAgLyoganNoaW50IC1XMDU0ICovXG5cdFx0XHRcdFx0XHRcdHZhbCA9IG5ldyBGdW5jdGlvbih2YWwpOyAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGpzaGludCArVzA1NCAqL1xuXHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0dHJ5IHsgdmFsID0gSlNPTi5wYXJzZSh2YWwpOyB9XG5cdFx0XHRcdFx0XHRcdGNhdGNoKGUpIHt9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRjb25maWdbbmFtZV0gPSB2YWw7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9KTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBjb25maWc7XG5cdFx0fSxcblxuXHRcdC8qIFVzZWQgdG8gY3JlYXRlIGEgRmVhdGhlcmxpZ2h0IGV4dGVuc2lvblxuXHRcdCAgIFtXYXJuaW5nOiBndXJ1LWxldmVsXVxuXHRcdCAgIENyZWF0ZXMgdGhlIGV4dGVuc2lvbidzIHByb3RvdHlwZSB0aGF0IGluIHR1cm5cblx0XHQgICBpbmhlcml0cyBGZWF0aGVybGlnaHQncyBwcm90b3R5cGUuXG5cdFx0ICAgQ291bGQgYmUgdXNlZCB0byBleHRlbmQgYW4gZXh0ZW5zaW9uIHRvby4uLlxuXHRcdCAgIFRoaXMgaXMgcHJldHR5IGhpZ2ggbGV2ZWwgd2l6YXJkeSwgaXQgY29tZXMgcHJldHR5IG11Y2ggc3RyYWlnaHRcblx0XHQgICBmcm9tIENvZmZlZVNjcmlwdCBhbmQgd29uJ3QgdGVhY2ggeW91IGFueXRoaW5nIGFib3V0IEZlYXRoZXJsaWdodFxuXHRcdCAgIGFzIGl0J3Mgbm90IHJlYWxseSBzcGVjaWZpYyB0byB0aGlzIGxpYnJhcnkuXG5cdFx0ICAgTXkgc3VnZ2VzdGlvbjogbW92ZSBhbG9uZyBhbmQga2VlcCB5b3VyIHNhbml0eS5cblx0XHQqL1xuXHRcdGV4dGVuZDogZnVuY3Rpb24oY2hpbGQsIGRlZmF1bHRzKSB7XG5cdFx0XHQvKiBTZXR1cCBjbGFzcyBoaWVyYXJjaHksIGFkYXB0ZWQgZnJvbSBDb2ZmZWVTY3JpcHQgKi9cblx0XHRcdHZhciBDdG9yID0gZnVuY3Rpb24oKXsgdGhpcy5jb25zdHJ1Y3RvciA9IGNoaWxkOyB9O1xuXHRcdFx0Q3Rvci5wcm90b3R5cGUgPSB0aGlzLnByb3RvdHlwZTtcblx0XHRcdGNoaWxkLnByb3RvdHlwZSA9IG5ldyBDdG9yKCk7XG5cdFx0XHRjaGlsZC5fX3N1cGVyX18gPSB0aGlzLnByb3RvdHlwZTtcblx0XHRcdC8qIENvcHkgY2xhc3MgbWV0aG9kcyAmIGF0dHJpYnV0ZXMgKi9cblx0XHRcdCQuZXh0ZW5kKGNoaWxkLCB0aGlzLCBkZWZhdWx0cyk7XG5cdFx0XHRjaGlsZC5kZWZhdWx0cyA9IGNoaWxkLnByb3RvdHlwZTtcblx0XHRcdHJldHVybiBjaGlsZDtcblx0XHR9LFxuXG5cdFx0YXR0YWNoOiBmdW5jdGlvbigkc291cmNlLCAkY29udGVudCwgY29uZmlnKSB7XG5cdFx0XHR2YXIgS2xhc3MgPSB0aGlzO1xuXHRcdFx0aWYgKHR5cGVvZiAkY29udGVudCA9PT0gJ29iamVjdCcgJiYgJGNvbnRlbnQgaW5zdGFuY2VvZiAkID09PSBmYWxzZSAmJiAhY29uZmlnKSB7XG5cdFx0XHRcdGNvbmZpZyA9ICRjb250ZW50O1xuXHRcdFx0XHQkY29udGVudCA9IHVuZGVmaW5lZDtcblx0XHRcdH1cblx0XHRcdC8qIG1ha2UgYSBjb3B5ICovXG5cdFx0XHRjb25maWcgPSAkLmV4dGVuZCh7fSwgY29uZmlnKTtcblxuXHRcdFx0LyogT25seSBmb3Igb3BlblRyaWdnZXIgYW5kIG5hbWVzcGFjZS4uLiAqL1xuXHRcdFx0dmFyIG5hbWVzcGFjZSA9IGNvbmZpZy5uYW1lc3BhY2UgfHwgS2xhc3MuZGVmYXVsdHMubmFtZXNwYWNlLFxuXHRcdFx0XHR0ZW1wQ29uZmlnID0gJC5leHRlbmQoe30sIEtsYXNzLmRlZmF1bHRzLCBLbGFzcy5yZWFkRWxlbWVudENvbmZpZygkc291cmNlWzBdLCBuYW1lc3BhY2UpLCBjb25maWcpLFxuXHRcdFx0XHRzaGFyZWRQZXJzaXN0O1xuXHRcdFx0dmFyIGhhbmRsZXIgPSBmdW5jdGlvbihldmVudCkge1xuXHRcdFx0XHQvKiAuLi4gc2luY2Ugd2UgbWlnaHQgYXMgd2VsbCBjb21wdXRlIHRoZSBjb25maWcgb24gdGhlIGFjdHVhbCB0YXJnZXQgKi9cblx0XHRcdFx0dmFyIGVsZW1Db25maWcgPSAkLmV4dGVuZChcblx0XHRcdFx0XHR7JHNvdXJjZTogJHNvdXJjZSwgJGN1cnJlbnRUYXJnZXQ6ICQodGhpcyl9LFxuXHRcdFx0XHRcdEtsYXNzLnJlYWRFbGVtZW50Q29uZmlnKCRzb3VyY2VbMF0sIHRlbXBDb25maWcubmFtZXNwYWNlKSxcblx0XHRcdFx0XHRLbGFzcy5yZWFkRWxlbWVudENvbmZpZyh0aGlzLCB0ZW1wQ29uZmlnLm5hbWVzcGFjZSksXG5cdFx0XHRcdFx0Y29uZmlnKTtcblx0XHRcdFx0dmFyIGZsID0gc2hhcmVkUGVyc2lzdCB8fCAkKHRoaXMpLmRhdGEoJ2ZlYXRoZXJsaWdodC1wZXJzaXN0ZWQnKSB8fCBuZXcgS2xhc3MoJGNvbnRlbnQsIGVsZW1Db25maWcpO1xuXHRcdFx0XHRpZihmbC5wZXJzaXN0ID09PSAnc2hhcmVkJykge1xuXHRcdFx0XHRcdHNoYXJlZFBlcnNpc3QgPSBmbDtcblx0XHRcdFx0fSBlbHNlIGlmKGZsLnBlcnNpc3QgIT09IGZhbHNlKSB7XG5cdFx0XHRcdFx0JCh0aGlzKS5kYXRhKCdmZWF0aGVybGlnaHQtcGVyc2lzdGVkJywgZmwpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGVsZW1Db25maWcuJGN1cnJlbnRUYXJnZXQuYmx1cigpOyAvLyBPdGhlcndpc2UgJ2VudGVyJyBrZXkgbWlnaHQgdHJpZ2dlciB0aGUgZGlhbG9nIGFnYWluXG5cdFx0XHRcdGZsLm9wZW4oZXZlbnQpO1xuXHRcdFx0fTtcblxuXHRcdFx0JHNvdXJjZS5vbih0ZW1wQ29uZmlnLm9wZW5UcmlnZ2VyKycuJyt0ZW1wQ29uZmlnLm5hbWVzcGFjZSwgdGVtcENvbmZpZy5maWx0ZXIsIGhhbmRsZXIpO1xuXG5cdFx0XHRyZXR1cm4gaGFuZGxlcjtcblx0XHR9LFxuXG5cdFx0Y3VycmVudDogZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgYWxsID0gdGhpcy5vcGVuZWQoKTtcblx0XHRcdHJldHVybiBhbGxbYWxsLmxlbmd0aCAtIDFdIHx8IG51bGw7XG5cdFx0fSxcblxuXHRcdG9wZW5lZDogZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIga2xhc3MgPSB0aGlzO1xuXHRcdFx0cHJ1bmVPcGVuZWQoKTtcblx0XHRcdHJldHVybiAkLmdyZXAob3BlbmVkLCBmdW5jdGlvbihmbCkgeyByZXR1cm4gZmwgaW5zdGFuY2VvZiBrbGFzczsgfSApO1xuXHRcdH0sXG5cblx0XHRjbG9zZTogZnVuY3Rpb24oZXZlbnQpIHtcblx0XHRcdHZhciBjdXIgPSB0aGlzLmN1cnJlbnQoKTtcblx0XHRcdGlmKGN1cikgeyByZXR1cm4gY3VyLmNsb3NlKGV2ZW50KTsgfVxuXHRcdH0sXG5cblx0XHQvKiBEb2VzIHRoZSBhdXRvIGJpbmRpbmcgb24gc3RhcnR1cC5cblx0XHQgICBNZWFudCBvbmx5IHRvIGJlIHVzZWQgYnkgRmVhdGhlcmxpZ2h0IGFuZCBpdHMgZXh0ZW5zaW9uc1xuXHRcdCovXG5cdFx0X29uUmVhZHk6IGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIEtsYXNzID0gdGhpcztcblx0XHRcdGlmKEtsYXNzLmF1dG9CaW5kKXtcblx0XHRcdFx0LyogQmluZCBleGlzdGluZyBlbGVtZW50cyAqL1xuXHRcdFx0XHQkKEtsYXNzLmF1dG9CaW5kKS5lYWNoKGZ1bmN0aW9uKCl7XG5cdFx0XHRcdFx0S2xhc3MuYXR0YWNoKCQodGhpcykpO1xuXHRcdFx0XHR9KTtcblx0XHRcdFx0LyogSWYgYSBjbGljayBwcm9wYWdhdGVzIHRvIHRoZSBkb2N1bWVudCBsZXZlbCwgdGhlbiB3ZSBoYXZlIGFuIGl0ZW0gdGhhdCB3YXMgYWRkZWQgbGF0ZXIgb24gKi9cblx0XHRcdFx0JChkb2N1bWVudCkub24oJ2NsaWNrJywgS2xhc3MuYXV0b0JpbmQsIGZ1bmN0aW9uKGV2dCkge1xuXHRcdFx0XHRcdGlmIChldnQuaXNEZWZhdWx0UHJldmVudGVkKCkpIHtcblx0XHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0LyogQmluZCBmZWF0aGVybGlnaHQgKi9cblx0XHRcdFx0XHR2YXIgaGFuZGxlciA9IEtsYXNzLmF0dGFjaCgkKGV2dC5jdXJyZW50VGFyZ2V0KSk7XG5cdFx0XHRcdFx0LyogRGlzcGF0Y2ggZXZlbnQgZGlyZWN0bHkgKi9cblx0XHRcdFx0XHRoYW5kbGVyKGV2dCk7XG5cdFx0XHRcdH0pO1xuXHRcdFx0fVxuXHRcdH0sXG5cblx0XHQvKiBGZWF0aGVybGlnaHQgdXNlcyB0aGUgb25LZXlVcCBjYWxsYmFjayB0byBpbnRlcmNlcHQgdGhlIGVzY2FwZSBrZXkuXG5cdFx0ICAgUHJpdmF0ZSB0byBGZWF0aGVybGlnaHQuXG5cdFx0Ki9cblx0XHRfY2FsbGJhY2tDaGFpbjoge1xuXHRcdFx0b25LZXlVcDogZnVuY3Rpb24oX3N1cGVyLCBldmVudCl7XG5cdFx0XHRcdGlmKDI3ID09PSBldmVudC5rZXlDb2RlKSB7XG5cdFx0XHRcdFx0aWYgKHRoaXMuY2xvc2VPbkVzYykge1xuXHRcdFx0XHRcdFx0JC5mZWF0aGVybGlnaHQuY2xvc2UoZXZlbnQpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0cmV0dXJuIF9zdXBlcihldmVudCk7XG5cdFx0XHRcdH1cblx0XHRcdH0sXG5cblx0XHRcdGJlZm9yZU9wZW46IGZ1bmN0aW9uKF9zdXBlciwgZXZlbnQpIHtcblx0XHRcdFx0Ly8gUmVtZW1iZXIgZm9jdXM6XG5cdFx0XHRcdHRoaXMuX3ByZXZpb3VzbHlBY3RpdmUgPSBkb2N1bWVudC5hY3RpdmVFbGVtZW50O1xuXG5cdFx0XHRcdC8vIERpc2FibGUgdGFiYmluZzpcblx0XHRcdFx0Ly8gU2VlIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMTU5OTY2MC93aGljaC1odG1sLWVsZW1lbnRzLWNhbi1yZWNlaXZlLWZvY3VzXG5cdFx0XHRcdHRoaXMuXyRwcmV2aW91c2x5VGFiYmFibGUgPSAkKFwiYSwgaW5wdXQsIHNlbGVjdCwgdGV4dGFyZWEsIGlmcmFtZSwgYnV0dG9uLCBpZnJhbWUsIFtjb250ZW50RWRpdGFibGU9dHJ1ZV1cIilcblx0XHRcdFx0XHQubm90KCdbdGFiaW5kZX
7437hdJylcblx0XHRcdFx0XHQubm90KHRoaXMuJGluc3RhbmNlLmZpbmQoJ2J1dHRvbicpKTtcblxuXHRcdFx0XHR0aGlzLl8kcHJldmlvdXNseVdpdGhUYWJJbmRleCA9ICQoJ1t0YWJpbmRleF0nKS5ub3QoJ1t0YWJpbmRleD1cIi0xXCJdJyk7XG5cdFx0XHRcdHRoaXMuX3ByZXZpb3VzV2l0aFRhYkluZGljZXMgPSB0aGlzLl8kcHJldmlvdXNseVdpdGhUYWJJbmRleC5tYXAoZnVuY3Rpb24oX2ksIGVsZW0pIHtcblx0XHRcdFx0XHRyZXR1cm4gJChlbGVtKS5hdHRyKCd0YWJpbmRleCcpO1xuXHRcdFx0XHR9KTtcblxuXHRcdFx0XHR0aGlzLl8kcHJldmlvdXNseVdpdGhUYWJJbmRleC5hZGQodGhpcy5fJHByZXZpb3VzbHlUYWJiYWJsZSkuYXR0cigndGFiaW5kZXgnLCAtMSk7XG5cblx0XHRcdFx0ZG9jdW1lbnQuYWN0aXZlRWxlbWVudC5ibHVyKCk7XG5cdFx0XHRcdHJldHVybiBfc3VwZXIoZXZlbnQpO1xuXHRcdFx0fSxcblxuXHRcdFx0YWZ0ZXJDbG9zZTogZnVuY3Rpb24oX3N1cGVyLCBldmVudCkge1xuXHRcdFx0XHR2YXIgciA9IF9zdXBlcihldmVudCk7XG5cdFx0XHRcdHZhciBzZWxmID0gdGhpcztcblx0XHRcdFx0dGhpcy5fJHByZXZpb3VzbHlUYWJiYWJsZS5yZW1vdmVBdHRyKCd0YWJpbmRleCcpO1xuXHRcdFx0XHR0aGlzLl8kcHJldmlvdXNseVdpdGhUYWJJbmRleC5lYWNoKGZ1bmN0aW9uKGksIGVsZW0pIHtcblx0XHRcdFx0XHQkKGVsZW0pLmF0dHIoJ3RhYmluZGV4Jywgc2VsZi5fcHJldmlvdXNXaXRoVGFiSW5kaWNlc1tpXSk7XG5cdFx0XHRcdH0pO1xuXHRcdFx0XHR0aGlzLl9wcmV2aW91c2x5QWN0aXZlLmZvY3VzKCk7XG5cdFx0XHRcdHJldHVybiByO1xuXHRcdFx0fSxcblxuXHRcdFx0b25SZXNpemU6IGZ1bmN0aW9uKF9zdXBlciwgZXZlbnQpe1xuXHRcdFx0XHR0aGlzLnJlc2l6ZSh0aGlzLiRjb250ZW50Lm5hdHVyYWxXaWR0aCwgdGhpcy4kY29udGVudC5uYXR1cmFsSGVpZ2h0KTtcblx0XHRcdFx0cmV0dXJuIF9zdXBlcihldmVudCk7XG5cdFx0XHR9LFxuXG5cdFx0XHRhZnRlckNvbnRlbnQ6IGZ1bmN0aW9uKF9zdXBlciwgZXZlbnQpe1xuXHRcdFx0XHR2YXIgciA9IF9zdXBlcihldmVudCk7XG5cdFx0XHRcdHRoaXMuJGluc3RhbmNlLmZpbmQoJ1thdXRvZm9jdXNdOm5vdChbZGlzYWJsZWRdKScpLmZvY3VzKCk7XG5cdFx0XHRcdHRoaXMub25SZXNpemUoZXZlbnQpO1xuXHRcdFx0XHRyZXR1cm4gcjtcblx0XHRcdH1cblx0XHR9XG5cdH0pO1xuXG5cdCQuZmVhdGhlcmxpZ2h0ID0gRmVhdGhlcmxpZ2h0O1xuXG5cdC8qIGJpbmQgalF1ZXJ5IGVsZW1lbnRzIHRvIHRyaWdnZXIgZmVhdGhlcmxpZ2h0ICovXG5cdCQuZm4uZmVhdGhlcmxpZ2h0ID0gZnVuY3Rpb24oJGNvbnRlbnQsIGNvbmZpZykge1xuXHRcdEZlYXRoZXJsaWdodC5hdHRhY2godGhpcywgJGNvbnRlbnQsIGNvbmZpZyk7XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH07XG5cblx0LyogYmluZCBmZWF0aGVybGlnaHQgb24gcmVhZHkgaWYgY29uZmlnIGF1dG9CaW5kIGlzIHNldCAqL1xuXHQkKGRvY3VtZW50KS5yZWFkeShmdW5jdGlvbigpeyBGZWF0aGVybGlnaHQuX29uUmVhZHkoKTsgfSk7XG59KGpRdWVyeSkpO1xuIiwiLyoqXG4gKiBGZWF0aGVybGlnaHQgR2FsbGVyeSDigJMgYW4gZXh0ZW5zaW9uIGZvciB0aGUgdWx0cmEgc2xpbSBqUXVlcnkgbGlnaHRib3hcbiAqIFZlcnNpb24gMS43LjEgLSBodHRwOi8vbm9lbGJvc3MuZ2l0aHViLmlvL2ZlYXRoZXJsaWdodC9cbiAqXG4gKiBDb3B5cmlnaHQgMjAxNywgTm/Dq2wgUmFvdWwgQm9zc2FydCAoaHR0cDovL3d3dy5ub2VsYm9zcy5jb20pXG4gKiBNSVQgTGljZW5zZWQuXG4qKi9cbihmdW5jdGlvbigkKSB7XG5cdFwidXNlIHN0cmljdFwiO1xuXG5cdHZhciB3YXJuID0gZnVuY3Rpb24obSkge1xuXHRcdGlmKHdpbmRvdy5jb25zb2xlICYmIHdpbmRvdy5jb25zb2xlLndhcm4pIHtcblx0XHRcdHdpbmRvdy5jb25zb2xlLndhcm4oJ0ZlYXRoZXJsaWdodEdhbGxlcnk6ICcgKyBtKTtcblx0XHR9XG5cdH07XG5cblx0aWYoJ3VuZGVmaW5lZCcgPT09IHR5cGVvZiAkKSB7XG5cdFx0cmV0dXJuIHdhcm4oJ1RvbyBtdWNoIGxpZ2h0bmVzcywgRmVhdGhlcmxpZ2h0IG5lZWRzIGpRdWVyeS4nKTtcblx0fSBlbHNlIGlmKCEkLmZlYXRoZXJsaWdodCkge1xuXHRcdHJldHVybiB3YXJuKCdMb2FkIHRoZSBmZWF0aGVybGlnaHQgcGx1Z2luIGJlZm9yZSB0aGUgZ2FsbGVyeSBwbHVnaW4nKTtcblx0fVxuXG5cdHZhciBpc1RvdWNoQXdhcmUgPSAoJ29udG91Y2hzdGFydCcgaW4gd2luZG93KSB8fCB3aW5kb3cuRG9jdW1lbnRUb3VjaCAmJiBkb2N1bWVudCBpbnN0YW5jZW9mIERvY3VtZW50VG91Y2gsXG5cdFx0alF1ZXJ5Q29uc3RydWN0b3IgPSAkLmV2ZW50ICYmICQuZXZlbnQuc3BlY2lhbC5zd2lwZWxlZnQgJiYgJCxcblx0XHRoYW1tZXJDb25zdHJ1Y3RvciA9IHdpbmRvdy5IYW1tZXIgJiYgZnVuY3Rpb24oJGVsKXtcblx0XHRcdHZhciBtYyA9IG5ldyB3aW5kb3cuSGFtbWVyLk1hbmFnZXIoJGVsWzBdKTtcblx0XHRcdG1jLmFkZChuZXcgd2luZG93LkhhbW1lci5Td2lwZSgpKTtcblx0XHRcdHJldHVybiBtYztcblx0XHR9LFxuXHRcdHN3aXBlQXdhcmVDb25zdHJ1Y3RvciA9IGlzVG91Y2hBd2FyZSAmJiAoalF1ZXJ5Q29uc3RydWN0b3IgfHwgaGFtbWVyQ29uc3RydWN0b3IpO1xuXHRpZihpc1RvdWNoQXdhcmUgJiYgIXN3aXBlQXdhcmVDb25zdHJ1Y3Rvcikge1xuXHRcdHdhcm4oJ05vIGNvbXBhdGlibGUgc3dpcGUgbGlicmFyeSBkZXRlY3RlZDsgb25lIG11c3QgYmUgaW5jbHVkZWQgYmVmb3JlIGZlYXRoZXJsaWdodEdhbGxlcnkgZm9yIHN3aXBlIG1vdGlvbnMgdG8gbmF2aWdhdGUgdGhlIGdhbGxlcmllcy4nKTtcblx0fVxuXG5cdHZhciBjYWxsYmFja0NoYWluID0ge1xuXHRcdFx0YWZ0ZXJDbG9zZTogZnVuY3Rpb24oX3N1cGVyLCBldmVudCkge1xuXHRcdFx0XHRcdHZhciBzZWxmID0gdGhpcztcblx0XHRcdFx0XHRzZWxmLiRpbnN0YW5jZS5vZmYoJ25leHQuJytzZWxmLm5hbWVzcGFjZSsnIHByZXZpb3VzLicrc2VsZi5uYW1lc3BhY2UpO1xuXHRcdFx0XHRcdGlmIChzZWxmLl9zd2lwZXIp
7437IHtcblx0XHRcdFx0XHRcdHNlbGYuX3N3aXBlclxuXHRcdFx0XHRcdFx0XHQub2ZmKCdzd2lwZWxlZnQnLCBzZWxmLl9zd2lwZWxlZnQpIC8qIFNlZSBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzE3MzY3MTk4L2hhbW1lci1qcy1jYW50LXJlbW92ZS1ldmVudC1saXN0ZW5lciAqL1xuXHRcdFx0XHRcdFx0XHQub2ZmKCdzd2lwZXJpZ2h0Jywgc2VsZi5fc3dpcGVyaWdodCk7XG5cdFx0XHRcdFx0XHRzZWxmLl9zd2lwZXIgPSBudWxsO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRyZXR1cm4gX3N1cGVyKGV2ZW50KTtcblx0XHRcdH0sXG5cdFx0XHRiZWZvcmVPcGVuOiBmdW5jdGlvbihfc3VwZXIsIGV2ZW50KXtcblx0XHRcdFx0XHR2YXIgc2VsZiA9IHRoaXM7XG5cblx0XHRcdFx0XHRzZWxmLiRpbnN0YW5jZS5vbignbmV4dC4nK3NlbGYubmFtZXNwYWNlKycgcHJldmlvdXMuJytzZWxmLm5hbWVzcGFjZSwgZnVuY3Rpb24oZXZlbnQpe1xuXHRcdFx0XHRcdFx0dmFyIG9mZnNldCA9IGV2ZW50LnR5cGUgPT09ICduZXh0JyA/ICsxIDogLTE7XG5cdFx0XHRcdFx0XHRzZWxmLm5hdmlnYXRlVG8oc2VsZi5jdXJyZW50TmF2aWdhdGlvbigpICsgb2Zmc2V0KTtcblx0XHRcdFx0XHR9KTtcblxuXHRcdFx0XHRcdGlmIChzd2lwZUF3YXJlQ29uc3RydWN0b3IpIHtcblx0XHRcdFx0XHRcdHNlbGYuX3N3aXBlciA9IHN3aXBlQXdhcmVDb25zdHJ1Y3RvcihzZWxmLiRpbnN0YW5jZSlcblx0XHRcdFx0XHRcdFx0Lm9uKCdzd2lwZWxlZnQnLCBzZWxmLl9zd2lwZWxlZnQgPSBmdW5jdGlvbigpICB7IHNlbGYuJGluc3RhbmNlLnRyaWdnZXIoJ25leHQnKTsgfSlcblx0XHRcdFx0XHRcdFx0Lm9uKCdzd2lwZXJpZ2h0Jywgc2VsZi5fc3dpcGVyaWdodCA9IGZ1bmN0aW9uKCkgeyBzZWxmLiRpbnN0YW5jZS50cmlnZ2VyKCdwcmV2aW91cycpOyB9KTtcblxuXHRcdFx0XHRcdFx0c2VsZi4kaW5zdGFuY2Vcblx0XHRcdFx0XHRcdFx0LmFkZENsYXNzKHRoaXMubmFtZXNwYWNlKyctc3dpcGUtYXdhcmUnLCBzd2lwZUF3YXJlQ29uc3RydWN0b3IpO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdHNlbGYuJGluc3RhbmNlLmZpbmQoJy4nK3NlbGYubmFtZXNwYWNlKyctY29udGVudCcpXG5cdFx0XHRcdFx0XHQuYXBwZW5kKHNlbGYuY3JlYXRlTmF2aWdhdGlvbigncHJldmlvdXMnKSlcblx0XHRcdFx0XHRcdC5hcHBlbmQoc2VsZi5jcmVhdGVOYXZpZ2F0aW9uKCduZXh0JykpO1xuXG5cdFx0XHRcdFx0cmV0dXJuIF9zdXBlcihldmVudCk7XG5cdFx0XHR9LFxuXHRcdFx0YmVmb3JlQ29udGVudDogZnVuY3Rpb24oX3N1cGVyLCBldmVudCkge1xuXHRcdFx0XHR2YXIgaW5kZXggPSB0aGlzLmN1cnJlbnROYXZpZ2F0aW9uKCk7XG5cdFx0XHRcdHZhciBsZW4gPSB0aGlzLnNsaWRlcygpLmxlbmd0aDtcblx0XHRcdFx0dGhpcy4kaW5zdGFuY2Vcblx0XHRcdFx0XHQudG9nZ2xlQ2xhc3ModGhpcy5uYW1lc3BhY2UrJy1maXJzdC1zbGlkZScsIGluZGV4ID09PSAwKVxuXHRcdFx0XHRcdC50b2dnbGVDbGFzcyh0aGlzLm5hbWVzcGFjZSsnLWxhc3Qtc2xpZGUnLCBpbmRleCA9PT0gbGVuIC0gMSk7XG5cdFx0XHRcdHJldHVybiBfc3VwZXIoZXZlbnQpO1xuXHRcdFx0fSxcblx0XHRcdG9uS2V5VXA6IGZ1bmN0aW9uKF9zdXBlciwgZXZlbnQpe1xuXHRcdFx0XHR2YXIgZGlyID0ge1xuXHRcdFx0XHRcdDM3OiAncHJldmlvdXMnLCAvKiBMZWZ0IGFycm93ICovXG5cdFx0XHRcdFx0Mzk6ICduZXh0J1x0XHRcdC8qIFJpZ3RoIGFycm93ICovXG5cdFx0XHRcdH1bZXZlbnQua2V5Q29kZV07XG5cdFx0XHRcdGlmKGRpcikge1xuXHRcdFx0XHRcdHRoaXMuJGluc3RhbmNlLnRyaWdnZXIoZGlyKTtcblx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0cmV0dXJuIF9zdXBlcihldmVudCk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9O1xuXG5cdGZ1bmN0aW9uIEZlYXRoZXJsaWdodEdhbGxlcnkoJHNvdXJjZSwgY29uZmlnKSB7XG5cdFx0aWYodGhpcyBpbnN0YW5jZW9mIEZlYXRoZXJsaWdodEdhbGxlcnkpIHsgIC8qIGNhbGxlZCB3aXRoIG5ldyAqL1xuXHRcdFx0JC5mZWF0aGVybGlnaHQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcblx0XHRcdHRoaXMuY2hhaW5DYWxsYmFja3MoY2FsbGJhY2tDaGFpbik7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHZhciBmbGcgPSBuZXcgRmVhdGhlcmxpZ2h0R2FsbGVyeSgkLmV4dGVuZCh7JHNvdXJjZTogJHNvdXJjZSwgJGN1cnJlbnRUYXJnZXQ6ICRzb3VyY2UuZmlyc3QoKX0sIGNvbmZpZykpO1xuXHRcdFx0ZmxnLm9wZW4oKTtcblx0XHRcdHJldHVybiBmbGc7XG5cdFx0fVxuXHR9XG5cblx0JC5mZWF0aGVybGlnaHQuZXh0ZW5kKEZlYXRoZXJsaWdodEdhbGxlcnksIHtcblx0XHRhdXRvQmluZDogJ1tkYXRhLWZlYXRoZXJsaWdodC1nYWxsZXJ5XSdcblx0fSk7XG5cblx0JC5leHRlbmQoRmVhdGhlcmxpZ2h0R2FsbGVyeS5wcm90b3R5cGUsIHtcblx0XHQvKiogQWRkaXRpb25hbCBzZXR0aW5ncyBmb3IgR2FsbGVyeSAqKi9cblx0XHRwcmV2aW91c0ljb246ICcmIzk2NjQ7JywgICAgIC8qIENvZGUgdGhhdCBpcyB1c2VkIGFzIHByZXZpb3VzIGljb24gKi9cblx0XHRuZXh0SWNvbjogJyYjOTY1NDsnLCAgICAgICAgIC8qIENvZGUgdGhhdCBpcyB1c2VkIGFzIG5leHQgaWNvbiAqL1xuXHRcdGdhbGxlcnlGYWRlSW46IDEwMCwgICAgICAgICAgLyogZmFkZUluIHNwZWVkIHdoZW4gaW1hZ2UgaXMgbG9hZGVkICovXG5cdFx0Z2FsbGVyeUZhZGVPdXQ6IDMwMCwgICAgICAgICAvKiBmYWRlT3V0IHNwZWVkIGJlZm9yZSBpbWFnZSBpcyBsb2FkZWQgKi9cblxuXHRcdHNsaWRlczogZnVuY3Rpb24oKSB7XG5cdFx0XHRpZiAodGhpcy5maWx0ZXIpIHtcblx0XHRcdFx0cmV0dXJuIHRoaXMuJHNvdXJjZS5maW5kKHRoaXMuZmlsdGVyKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiB0aGlzLiRzb3VyY2U7XG5cdFx0fSxcblxuXHRcdGltYWdlczogZnVuY3Rpb24oKSB7XG5cdFx0XHR3YXJuKCdpbWFnZXMgaXMgZGVwcmVjYXRlZCwgcGxlYXNlIHVzZSBzbGlkZXMgaW5zdGVhZCcpO1xuXHRcdFx0cmV0dXJuIHRoaXMuc2xpZGVzKCk7XG5cdFx0fSxcblxuXHRcdGN1cnJlbnROYXZpZ2F0aW9uOiBmdW5jdGlvbigpIHtcblx0XHRcdHJldHVybi
7437B0aGlzLnNsaWRlcygpLmluZGV4KHRoaXMuJGN1cnJlbnRUYXJnZXQpO1xuXHRcdH0sXG5cblx0XHRuYXZpZ2F0ZVRvOiBmdW5jdGlvbihpbmRleCkge1xuXHRcdFx0dmFyIHNlbGYgPSB0aGlzLFxuXHRcdFx0XHRzb3VyY2UgPSBzZWxmLnNsaWRlcygpLFxuXHRcdFx0XHRsZW4gPSBzb3VyY2UubGVuZ3RoLFxuXHRcdFx0XHQkaW5uZXIgPSBzZWxmLiRpbnN0YW5jZS5maW5kKCcuJyArIHNlbGYubmFtZXNwYWNlICsgJy1pbm5lcicpO1xuXHRcdFx0aW5kZXggPSAoKGluZGV4ICUgbGVuKSArIGxlbikgJSBsZW47IC8qIHBpbiBpbmRleCB0byBbMCwgbGVuWyAqL1xuXG5cdFx0XHRzZWxmLiRjdXJyZW50VGFyZ2V0ID0gc291cmNlLmVxKGluZGV4KTtcblx0XHRcdHNlbGYuYmVmb3JlQ29udGVudCgpO1xuXHRcdFx0cmV0dXJuICQud2hlbihcblx0XHRcdFx0c2VsZi5nZXRDb250ZW50KCksXG5cdFx0XHRcdCRpbm5lci5mYWRlVG8oc2VsZi5nYWxsZXJ5RmFkZU91dCwwLjIpXG5cdFx0XHQpLmFsd2F5cyhmdW5jdGlvbigkbmV3Q29udGVudCkge1xuXHRcdFx0XHRcdHNlbGYuc2V0Q29udGVudCgkbmV3Q29udGVudCk7XG5cdFx0XHRcdFx0c2VsZi5hZnRlckNvbnRlbnQoKTtcblx0XHRcdFx0XHQkbmV3Q29udGVudC5mYWRlVG8oc2VsZi5nYWxsZXJ5RmFkZUluLDEpO1xuXHRcdFx0fSk7XG5cdFx0fSxcblxuXHRcdGNyZWF0ZU5hdmlnYXRpb246IGZ1bmN0aW9uKHRhcmdldCkge1xuXHRcdFx0dmFyIHNlbGYgPSB0aGlzO1xuXHRcdFx0cmV0dXJuICQoJzxzcGFuIHRpdGxlPVwiJyt0YXJnZXQrJ1wiIGNsYXNzPVwiJyt0aGlzLm5hbWVzcGFjZSsnLScrdGFyZ2V0KydcIj48c3Bhbj4nK3RoaXNbdGFyZ2V0KydJY29uJ10rJzwvc3Bhbj48L3NwYW4+JykuY2xpY2soZnVuY3Rpb24oKXtcblx0XHRcdFx0JCh0aGlzKS50cmlnZ2VyKHRhcmdldCsnLicrc2VsZi5uYW1lc3BhY2UpO1xuXHRcdFx0fSk7XG5cdFx0fVxuXHR9KTtcblxuXHQkLmZlYXRoZXJsaWdodEdhbGxlcnkgPSBGZWF0aGVybGlnaHRHYWxsZXJ5O1xuXG5cdC8qIGV4dGVuZCBqUXVlcnkgd2l0aCBzZWxlY3RvciBmZWF0aGVybGlnaHQgbWV0aG9kICQoZWxtKS5mZWF0aGVybGlnaHQoY29uZmlnLCBlbG0pOyAqL1xuXHQkLmZuLmZlYXRoZXJsaWdodEdhbGxlcnkgPSBmdW5jdGlvbihjb25maWcpIHtcblx0XHRGZWF0aGVybGlnaHRHYWxsZXJ5LmF0dGFjaCh0aGlzLCBjb25maWcpO1xuXHRcdHJldHVybiB0aGlzO1xuXHR9O1xuXG5cdC8qIGJpbmQgZmVhdGhlcmxpZ2h0IG9uIHJlYWR5IGlmIGNvbmZpZyBhdXRvQmluZCBpcyBzZXQgKi9cblx0JChkb2N1bWVudCkucmVhZHkoZnVuY3Rpb24oKXsgRmVhdGhlcmxpZ2h0R2FsbGVyeS5fb25SZWFkeSgpOyB9KTtcblxufShqUXVlcnkpKTtcbiIsIi8qKlxuICogQGxpY2Vuc2UganF1ZXJ5LnBhbnpvb20uanMgdjMuMi4yXG4gKiBVcGRhdGVkOiBTdW4gQXVnIDI4IDIwMTZcbiAqIEFkZCBwYW4gYW5kIHpvb20gZnVuY3Rpb25hbGl0eSB0byBhbnkgZWxlbWVudFxuICogQ29weXJpZ2h0IChjKSB0aW1teSB3aWxsaXNvblx0XHRcdFx0XHRcdFx0XHRcbiAqIFJlbGVhc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZVxuICogaHR0cHM6Ly9naXRodWIuY29tL3RpbW15d2lsL2pxdWVyeS5wYW56b29tL2Jsb2IvbWFzdGVyL01JVC1MaWNlbnNlLnR4dFxuICovXG5cbihmdW5jdGlvbihnbG9iYWwsIGZhY3RvcnkpIHtcblx0Ly8gQU1EXG5cdGlmICh0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpIHtcblx0XHRkZWZpbmUoWyAnanF1ZXJ5JyBdLCBmdW5jdGlvbihqUXVlcnkpIHtcblx0XHRcdHJldHVybiBmYWN0b3J5KGdsb2JhbCwgalF1ZXJ5KTtcblx0XHR9KTtcblx0Ly8gQ29tbW9uSlMvQnJvd3NlcmlmeVxuXHR9IGVsc2UgaWYgKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0Jykge1xuXHRcdGZhY3RvcnkoZ2xvYmFsLCByZXF1aXJlKCdqcXVlcnknKSk7XG5cdC8vIEdsb2JhbFxuXHR9IGVsc2Uge1xuXHRcdGZhY3RvcnkoZ2xvYmFsLCBnbG9iYWwualF1ZXJ5KTtcblx0fVxufSh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyA/IHdpbmRvdyA6IHRoaXMsIGZ1bmN0aW9uKHdpbmRvdywgJCkge1xuXHQndXNlIHN0cmljdCc7XG5cblx0dmFyIGRvY3VtZW50ID0gd2luZG93LmRvY3VtZW50O1xuXHR2YXIgZGF0YWtleSA9ICdfX3B6X18nO1xuXHR2YXIgc2xpY2UgPSBBcnJheS5wcm90b3R5cGUuc2xpY2U7XG5cdHZhciBySUUxMSA9IC90cmlkZW50XFwvNy4vaTtcblx0dmFyIHN1cHBvcnRzSW5wdXRFdmVudCA9IChmdW5jdGlvbigpIHtcblx0XHQvLyBJRTExIHJldHVybnMgYSBmYWxzZSBwb3NpdGl2ZVxuXHRcdGlmIChySUUxMS50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXHRcdHZhciBpbnB1dCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2lucHV0Jyk7XG5cdFx0aW5wdXQuc2V0QXR0cmlidXRlKCdvbmlucHV0JywgJ3JldHVybicpO1xuXHRcdHJldHVybiB0eXBlb2YgaW5wdXQub25pbnB1dCA9PT0gJ2Z1bmN0aW9uJztcblx0fSkoKTtcblxuXHQvLyBSZWdleFxuXHR2YXIgcnVwcGVyID0gLyhbQS1aXSkvZztcblx0dmFyIHJzdmcgPSAvXmh0dHA6W1xcd1xcLlxcL10rc3ZnJC87XG5cblx0dmFyIGZsb2F0aW5nID0gJyhcXFxcLT9cXFxcZFtcXFxcZFxcXFwuZS1dKiknO1xuXHR2YXIgY29tbWFTcGFjZSA9ICdcXFxcLD9cXFxccyonO1xuXHR2YXIgcm1hdHJpeCA9IG5ldyBSZWdFeHAoXG5cdFx0J15tYXRyaXhcXFxcKCcgK1xuXHRcdGZsb2F0aW5nICsgY29tbWFTcGFjZSArXG5cdFx0ZmxvYXRpbmcgKyBjb21tYVNwYWNlICtcblx0XHRmbG9hdGluZyArIGNvbW1hU3BhY2UgK1xuXHRcdGZsb2F0aW5nICsgY29tbWFTcGFjZSArXG5cdFx0ZmxvYXRpbmcgKyBjb21tYVNwYWNlICtcblx0XHRmbG9hdGluZyArICdcXFxcKSQnXG5cdCk7XG5cblx0LyoqXG5cdCAqIFV0aWxpdHkgZm9yIGRldGVybWluaW5nIHRyYW5zZm9ybSBtYXRyaXggZXF1YWxpdHlcblx0ICogQ2hlY2tzIGJhY2t3YXJkcyB0byB0ZXN0IHRyYW5zbGF0aW9uIGZpcnN0XG5cdCAqIEBwYXJhbSB7QXJyYXl9IGZpcnN0XG5cdCAqIEBwYXJhbSB7QXJyYXl9IHNlY29uZFxuXHQgKi9cblx0ZnVuY3Rpb24gbWF0cml4RXF1YWxzKGZpcnN0LCBzZWNvbmQpIHtcblx0XHR2YXIgaSA9IGZpcnN0Lmxlbmd0aDtcblx0XHR3aGlsZSgtLWkpIHtcblx0XHRcdGlmIChNYXRoLnJvdW5kKCtmaXJzdFtpXSkgIT09IE1hdGgucm91bmQoK3NlY29uZFtpXSkpIHtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gdHJ1ZTtcblx0fVxuXG5cdC8qKlxuXHQgKiBDcmVhdGVzIHRoZSBvcHRpb25zIG9iamVjdCBmb3IgcmVzZXQgZnVuY3Rpb25zXG5cdCAqIEBwYXJhbSB7Qm9vbGVhbnxPYmplY3R9IG9wdHMgU2VlIHJlc2V0IG1ldGhvZHNcblx0ICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3bHktY3JlYXRlZCBvcHRpb25zIG9iamVjdFxuXHQgKi9cblx0ZnVuY3Rpb24gY3JlYXRlUmVzZXRPcHRpb25zKG9wdHMpIHtcblx0XHR2YXIgb3B0aW9ucyA9IHsgcmFuZ2U6IHRydWUsIGFuaW1hdGU6IHRydWUgfTtcblx0XHRpZiAodHlwZW9mIG9wdHMgPT09ICdib29sZWFuJykge1xuXHRcdFx0b3B0aW9ucy5hbmltYXRlID0gb3B0cztcblx0XHR9IGVsc2Uge1xuXHRcdFx0JC5leHRlbmQob3B0aW9ucywgb3B0cyk7XG5cdFx0fVxuXHRcdHJldHVybi
7437BvcHRpb25zO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlcHJlc2VudCBhIHRyYW5zZm9ybWF0aW9uIG1hdHJpeCB3aXRoIGEgM3gzIG1hdHJpeCBmb3IgY2FsY3VsYXRpb25zXG5cdCAqIE1hdHJpeCBmdW5jdGlvbnMgYWRhcHRlZCBmcm9tIExvdWlzIFJlbWkncyBqUXVlcnkudHJhbnNmb3JtIChodHRwczovL2dpdGh1Yi5jb20vbG91aXNyZW1pL2pxdWVyeS50cmFuc2Zvcm0uanMpXG5cdCAqIEBwYXJhbSB7QXJyYXl8TnVtYmVyfSBhIEFuIGFycmF5IG9mIHNpeCB2YWx1ZXMgcmVwcmVzZW50aW5nIGEgMmQgdHJhbnNmb3JtYXRpb24gbWF0cml4XG5cdCAqL1xuXHRmdW5jdGlvbiBNYXRyaXgoYSwgYiwgYywgZCwgZSwgZiwgZywgaCwgaSkge1xuXHRcdGlmICgkLnR5cGUoYSkgPT09ICdhcnJheScpIHtcblx0XHRcdHRoaXMuZWxlbWVudHMgPSBbXG5cdFx0XHRcdCthWzBdLCArYVsyXSwgK2FbNF0sXG5cdFx0XHRcdCthWzFdLCArYVszXSwgK2FbNV0sXG5cdFx0XHRcdCAgICAwLCAgICAgMCwgICAgIDFcblx0XHRcdF07XG5cdFx0fSBlbHNlIHtcblx0XHRcdHRoaXMuZWxlbWVudHMgPSBbXG5cdFx0XHRcdGEsIGIsIGMsXG5cdFx0XHRcdGQsIGUsIGYsXG5cdFx0XHRcdGcgfHwgMCwgaCB8fCAwLCBpIHx8IDFcblx0XHRcdF07XG5cdFx0fVxuXHR9XG5cblx0TWF0cml4LnByb3RvdHlwZSA9IHtcblx0XHQvKipcblx0XHQgKiBNdWx0aXBseSBhIDN4MyBtYXRyaXggYnkgYSBzaW1pbGFyIG1hdHJpeCBvciBhIHZlY3RvclxuXHRcdCAqIEBwYXJhbSB7TWF0cml4fFZlY3Rvcn0gbWF0cml4XG5cdFx0ICogQHJldHVybiB7TWF0cml4fFZlY3Rvcn0gUmV0dXJucyBhIHZlY3RvciBpZiBtdWx0aXBseWluZyBieSBhIHZlY3RvclxuXHRcdCAqL1xuXHRcdHg6IGZ1bmN0aW9uKG1hdHJpeCkge1xuXHRcdFx0dmFyIGlzVmVjdG9yID0gbWF0cml4IGluc3RhbmNlb2YgVmVjdG9yO1xuXG5cdFx0XHR2YXIgYSA9IHRoaXMuZWxlbWVudHMsXG5cdFx0XHRcdGIgPSBtYXRyaXguZWxlbWVudHM7XG5cblx0XHRcdGlmIChpc1ZlY3RvciAmJiBiLmxlbmd0aCA9PT0gMykge1xuXHRcdFx0XHQvLyBiIGlzIGFjdHVhbGx5IGEgdmVjdG9yXG5cdFx0XHRcdHJldHVybiBuZXcgVmVjdG9yKFxuXHRcdFx0XHRcdGFbMF0gKiBiWzBdICsgYVsxXSAqIGJbMV0gKyBhWzJdICogYlsyXSxcblx0XHRcdFx0XHRhWzNdICogYlswXSArIGFbNF0gKiBiWzFdICsgYVs1XSAqIGJbMl0sXG5cdFx0XHRcdFx0YVs2XSAqIGJbMF0gKyBhWzddICogYlsxXSArIGFbOF0gKiBiWzJdXG5cdFx0XHRcdCk7XG5cdFx0XHR9IGVsc2UgaWYgKGIubGVuZ3RoID09PSBhLmxlbmd0aCkge1xuXHRcdFx0XHQvLyBiIGlzIGEgM3gzIG1hdHJpeFxuXHRcdFx0XHRyZXR1cm4gbmV3IE1hdHJpeChcblx0XHRcdFx0XHRhWzBdICogYlswXSArIGFbMV0gKiBiWzNdICsgYVsyXSAqIGJbNl0sXG5cdFx0XHRcdFx0YVswXSAqIGJbMV0gKyBhWzFdICogYls0XSArIGFbMl0gKiBiWzddLFxuXHRcdFx0XHRcdGFbMF0gKiBiWzJdICsgYVsxXSAqIGJbNV0gKyBhWzJdICogYls4XSxcblxuXHRcdFx0XHRcdGFbM10gKiBiWzBdICsgYVs0XSAqIGJbM10gKyBhWzVdICogYls2XSxcblx0XHRcdFx0XHRhWzNdICogYlsxXSArIGFbNF0gKiBiWzRdICsgYVs1XSAqIGJbN10sXG5cdFx0XHRcdFx0YVszXSAqIGJbMl0gKyBhWzRdICogYls1XSArIGFbNV0gKiBiWzhdLFxuXG5cdFx0XHRcdFx0YVs2XSAqIGJbMF0gKyBhWzddICogYlszXSArIGFbOF0gKiBiWzZdLFxuXHRcdFx0XHRcdGFbNl0gKiBiWzFdICsgYVs3XSAqIGJbNF0gKyBhWzhdICogYls3XSxcblx0XHRcdFx0XHRhWzZdICogYlsyXSArIGFbN10gKiBiWzVdICsgYVs4XSAqIGJbOF1cblx0XHRcdFx0KTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBmYWxzZTsgLy8gZmFpbFxuXHRcdH0sXG5cdFx0LyoqXG5cdFx0ICogR2VuZXJhdGVzIGFuIGludmVyc2Ugb2YgdGhlIGN1cnJlbnQgbWF0cml4XG5cdFx0ICogQHJldHVybnMge01hdHJpeH1cblx0XHQgKi9cblx0XHRpbnZlcnNlOiBmdW5jdGlvbigpIHtcblx0XHRcdHZhciBkID0gMSAvIHRoaXMuZGV0ZXJtaW5hbnQoKSxcblx0XHRcdFx0YSA9IHRoaXMuZWxlbWVudHM7XG5cdFx0XHRyZXR1cm4gbmV3IE1hdHJpeChcblx0XHRcdFx0ZCAqICggYVs4XSAqIGFbNF0gLSBhWzddICogYVs1XSksXG5cdFx0XHRcdGQgKiAoLShhWzhdICogYVsxXSAtIGFbN10gKiBhWzJdKSksXG5cdFx0XHRcdGQgKiAoIGFbNV0gKiBhWzFdIC0gYVs0XSAqIGFbMl0pLFxuXG5cdFx0XHRcdGQgKiAoLShhWzhdICogYVszXSAtIGFbNl0gKiBhWzVdKSksXG5cdFx0XHRcdGQgKiAoIGFbOF0gKiBhWzBdIC0gYVs2XSAqIGFbMl0pLFxuXHRcdFx0XHRkICogKC0oYVs1XSAqIGFbMF0gLSBhWzNdICogYVsyXSkpLFxuXG5cdFx0XHRcdGQgKiAoIGFbN10gKiBhWzNdIC0gYVs2XSAqIGFbNF0pLFxuXHRcdFx0XHRkICogKC0oYVs3XSAqIGFbMF0gLSBhWzZdICogYVsxXSkpLFxuXHRcdFx0XHRkICogKCBhWzRdICogYVswXSAtIGFbM10gKiBhWzFdKVxuXHRcdFx0KTtcblx0XHR9LFxuXHRcdC8qKlxuXHRcdCAqIENhbGN1bGF0ZXMgdGhlIGRldGVybWluYW50IG9mIHRoZSBjdXJyZW50IG1hdHJpeFxuXHRcdCAqIEByZXR1cm5zIHtOdW1iZXJ9XG5cdFx0ICovXG5cdFx0ZGV0ZXJtaW5hbnQ6IGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIGEgPSB0aGlzLmVsZW1lbnRzO1xuXHRcdFx0cmV0dXJuIGFbMF0gKiAoYVs4XSAqIGFbNF0gLSBhWzddICogYVs1XSkgLSBhWzNdICogKGFbOF0gKiBhWzFdIC0gYVs3XSAqIGFbMl0pICsgYVs2XSAqIChhWzVdICogYVsxXSAtIGFbNF0gKiBhWzJdKTtcblx0XHR9XG5cdH07XG5cblx0LyoqXG5cdCAqIENyZWF0ZSBhIHZlY3RvciBjb250YWluaW5nIHRocmVlIHZhbHVlc1xuXHQgKi9cblx0ZnVuY3Rpb24gVmVjdG9yKHgsIHksIHopIHtcblx0XHR0aGlzLmVsZW1lbnRzID0gWyB4LCB5LCB6IF07XG5cdH1cblxuXHQvKipcblx0ICogR2V0IHRoZSBlbGVtZW50IGF0IHplcm8taW5kZXhlZCBpbmRleCBpXG5cdCAqIEBwYXJhbSB7TnVtYmVyfSBpXG5cdCAqL1xuXHRWZWN0b3IucHJvdG90eXBlLmUgPSBNYXRyaXgucHJvdG90eXBlLmUgPSBmdW5jdGlvbihpKSB7XG5cdFx0cmV0dXJuIHRoaXMuZWxlbWVudHNbIGkgXTtcblx0fTtcblxuXHQvKipcblx0ICogQ3JlYXRlIGEgUGFuem9vbSBvYmplY3QgZm9yIGEgZ2l2ZW4gZWxlbWVudFxuXHQgKiBAY29uc3RydWN0b3Jcblx0ICogQHBhcmFtIHtFbGVtZW50fSBlbGVtIC0gRWxlbWVudCB0byB1c2UgcGFuIGFuZCB6b29tXG5cdCAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc10gLSB
7437BbiBvYmplY3QgbGl0ZXJhbCBjb250YWluaW5nIG9wdGlvbnMgdG8gb3ZlcnJpZGUgZGVmYXVsdCBvcHRpb25zXG5cdCAqICAoU2VlIFBhbnpvb20uZGVmYXVsdHMgZm9yIG9uZXMgbm90IGxpc3RlZCBiZWxvdylcblx0ICogQHBhcmFtIHtqUXVlcnl9IFtvcHRpb25zLiR6b29tSW5dIC0gem9vbSBpbiBidXR0b25zL2xpbmtzIGNvbGxlY3Rpb24gKHlvdSBjYW4gYWxzbyBiaW5kIHRoZXNlIHlvdXJzZWxmXG5cdCAqICBlLmcuICRidXR0b24ub24oJ2NsaWNrJywgZnVuY3Rpb24oZSkgeyBlLnByZXZlbnREZWZhdWx0KCk7ICRlbGVtLnBhbnpvb20oJ3pvb21JbicpOyB9KTspXG5cdCAqIEBwYXJhbSB7alF1ZXJ5fSBbb3B0aW9ucy4kem9vbU91dF0gLSB6b29tIG91dCBidXR0b25zL2xpbmtzIGNvbGxlY3Rpb24gb24gd2hpY2ggdG8gYmluZCB6b29tT3V0XG5cdCAqIEBwYXJhbSB7alF1ZXJ5fSBbb3B0aW9ucy4kem9vbVJhbmdlXSAtIHpvb20gaW4vb3V0IHdpdGggdGhpcyByYW5nZSBjb250cm9sXG5cdCAqIEBwYXJhbSB7alF1ZXJ5fSBbb3B0aW9ucy4kcmVzZXRdIC0gUmVzZXQgYnV0dG9ucy9saW5rcyBjb2xsZWN0aW9uIG9uIHdoaWNoIHRvIGJpbmQgdGhlIHJlc2V0IG1ldGhvZFxuXHQgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbb3B0aW9ucy5vbltTdGFydHxDaGFuZ2V8Wm9vbXxQYW58RW5kfFJlc2V0XSAtIE9wdGlvbmFsIGNhbGxiYWNrcyBmb3IgcGFuem9vbSBldmVudHNcblx0ICovXG5cdGZ1bmN0aW9uIFBhbnpvb20oZWxlbSwgb3B0aW9ucykge1xuXG5cdFx0Ly8gQWxsb3cgaW5zdGFudGlhdGlvbiB3aXRob3V0IGBuZXdgIGtleXdvcmRcblx0XHRpZiAoISh0aGlzIGluc3RhbmNlb2YgUGFuem9vbSkpIHtcblx0XHRcdHJldHVybiBuZXcgUGFuem9vbShlbGVtLCBvcHRpb25zKTtcblx0XHR9XG5cblx0XHQvLyBTYW5pdHkgY2hlY2tzXG5cdFx0aWYgKGVsZW0ubm9kZVR5cGUgIT09IDEpIHtcblx0XHRcdCQuZXJyb3IoJ1Bhbnpvb20gY2FsbGVkIG9uIG5vbi1FbGVtZW50IG5vZGUnKTtcblx0XHR9XG5cdFx0aWYgKCEkLmNvbnRhaW5zKGRvY3VtZW50LCBlbGVtKSkge1xuXHRcdFx0JC5lcnJvcignUGFuem9vbSBlbGVtZW50IG11c3QgYmUgYXR0YWNoZWQgdG8gdGhlIGRvY3VtZW50Jyk7XG5cdFx0fVxuXG5cdFx0Ly8gRG9uJ3QgcmVtYWtlXG5cdFx0dmFyIGQgPSAkLmRhdGEoZWxlbSwgZGF0YWtleSk7XG5cdFx0aWYgKGQpIHtcblx0XHRcdHJldHVybiBkO1xuXHRcdH1cblxuXHRcdC8vIEV4dGVuZCBkZWZhdWx0IHdpdGggZ2l2ZW4gb2JqZWN0IGxpdGVyYWxcblx0XHQvLyBFYWNoIGluc3RhbmNlIGdldHMgaXRzIG93biBvcHRpb25zXG5cdFx0dGhpcy5vcHRpb25zID0gb3B0aW9ucyA9ICQuZXh0ZW5kKHt9LCBQYW56b29tLmRlZmF1bHRzLCBvcHRpb25zKTtcblx0XHR0aGlzLmVsZW0gPSBlbGVtO1xuXHRcdHZhciAkZWxlbSA9IHRoaXMuJGVsZW0gPSAkKGVsZW0pO1xuXHRcdHRoaXMuJHNldCA9IG9wdGlvbnMuJHNldCAmJiBvcHRpb25zLiRzZXQubGVuZ3RoID8gb3B0aW9ucy4kc2V0IDogJGVsZW07XG5cdFx0dGhpcy4kZG9jID0gJChlbGVtLm93bmVyRG9jdW1lbnQgfHwgZG9jdW1lbnQpO1xuXHRcdHRoaXMuJHBhcmVudCA9ICRlbGVtLnBhcmVudCgpO1xuXHRcdHRoaXMucGFyZW50ID0gdGhpcy4kcGFyZW50WzBdO1xuXG5cdFx0Ly8gVGhpcyBpcyBTVkcgaWYgdGhlIG5hbWVzcGFjZSBpcyBTVkdcblx0XHQvLyBIb3dldmVyLCB3aGlsZSA8c3ZnPiBlbGVtZW50cyBhcmUgU1ZHLCB3ZSB3YW50IHRvIHRyZWF0IHRob3NlIGxpa2Ugb3RoZXIgZWxlbWVudHNcblx0XHR0aGlzLmlzU1ZHID0gcnN2Zy50ZXN0KGVsZW0ubmFtZXNwYWNlVVJJKSAmJiBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgIT09ICdzdmcnO1xuXG5cdFx0dGhpcy5wYW5uaW5nID0gZmFsc2U7XG5cblx0XHQvLyBTYXZlIHRoZSBvcmlnaW5hbCB0cmFuc2Zvcm0gdmFsdWVcblx0XHQvLyBTYXZlIHRoZSBwcmVmaXhlZCB0cmFuc2Zvcm0gc3R5bGUga2V5XG5cdFx0Ly8gU2V0IHRoZSBzdGFydGluZyB0cmFuc2Zvcm1cblx0XHR0aGlzLl9idWlsZFRyYW5zZm9ybSgpO1xuXG5cdFx0Ly8gQnVpbGQgdGhlIGFwcHJvcHJpYXRlbHktcHJlZml4ZWQgdHJhbnNmb3JtIHN0eWxlIHByb3BlcnR5IG5hbWVcblx0XHQvLyBEZS1jYW1lbGNhc2Vcblx0XHR0aGlzLl90cmFuc2Zvcm0gPSAkLmNzc1Byb3BzLnRyYW5zZm9ybS5yZXBsYWNlKHJ1cHBlciwgJy0kMScpLnRvTG93ZXJDYXNlKCk7XG5cblx0XHQvLyBCdWlsZCB0aGUgdHJhbnNpdGlvbiB2YWx1ZVxuXHRcdHRoaXMuX2J1aWxkVHJhbnNpdGlvbigpO1xuXG5cdFx0Ly8gQnVpbGQgY29udGFpbm1lbnQgZGltZW5zaW9uc1xuXHRcdHRoaXMucmVzZXREaW1lbnNpb25zKCk7XG5cblx0XHQvLyBBZGQgem9vbSBhbmQgcmVzZXQgYnV0dG9ucyB0byBgdGhpc2Bcblx0XHR2YXIgJGVtcHR5ID0gJ
7437CgpO1xuXHRcdHZhciBzZWxmID0gdGhpcztcblx0XHQkLmVhY2goWyAnJHpvb21JbicsICckem9vbU91dCcsICckem9vbVJhbmdlJywgJyRyZXNldCcgXSwgZnVuY3Rpb24oaSwgbmFtZSkge1xuXHRcdFx0c2VsZlsgbmFtZSBdID0gb3B0aW9uc1sgbmFtZSBdIHx8ICRlbXB0eTtcblx0XHR9KTtcblxuXHRcdHRoaXMuZW5hYmxlKCk7XG5cblx0XHR0aGlzLnNjYWxlID0gdGhpcy5nZXRNYXRyaXgoKVswXTtcblx0XHR0aGlzLl9jaGVja1BhbldoZW5ab29tZWQoKTtcblxuXHRcdC8vIFNhdmUgdGhlIGluc3RhbmNlXG5cdFx0JC5kYXRhKGVsZW0sIGRhdGFrZXksIHRoaXMpO1xuXHR9XG5cblx0Ly8gQXR0YWNoIHJlZ2V4IGZvciBwb3NzaWJsZSB1c2UgKGltbXV0YWJsZSlcblx0UGFuem9vbS5ybWF0cml4ID0gcm1hdHJpeDtcblxuXHRQYW56b29tLmRlZmF1bHRzID0ge1xuXHRcdC8vIFNob3VsZCBhbHdheXMgYmUgbm9uLWVtcHR5XG5cdFx0Ly8gVXNlZCB0byBiaW5kIGpRdWVyeSBldmVudHMgd2l0aG91dCBjb2xsaXNpb25zXG5cdFx0Ly8gQSBndWlkIGlzIG5vdCBhZGRlZCBoZXJlIGFzIGRpZmZlcmVudCBpbnN0YW50aWF0aW9ucy92ZXJzaW9ucyBvZiBwYW56b29tXG5cdFx0Ly8gb24gdGhlIHNhbWUgZWxlbWVudCBpcyBub3Qgc3VwcG9ydGVkLCBzbyBkb24ndCBkbyBpdC5cblx0XHRldmVudE5hbWVzcGFjZTogJy5wYW56b29tJyxcblxuXHRcdC8vIFdoZXRoZXIgb3Igbm90IHRvIHRyYW5zaXRpb24gdGhlIHNjYWxlXG5cdFx0dHJhbnNpdGlvbjogdHJ1ZSxcblxuXHRcdC8vIERlZmF1bHQgY3Vyc29yIHN0eWxlIGZvciB0aGUgZWxlbWVudFxuXHRcdGN1cnNvcjogJ21vdmUnLFxuXG5cdFx0Ly8gVGhlcmUgbWF5IGJlIHNvbWUgdXNlIGNhc2VzIGZvciB6b29taW5nIHdpdGhvdXQgcGFubmluZyBvciB2aWNlIHZlcnNhXG5cdFx0ZGlzYWJsZVBhbjogZmFsc2UsXG5cdFx0ZGlzYWJsZVpvb206IGZhbHNlLFxuXG5cdFx0Ly8gUGFuIG9ubHkgb24gdGhlIFggb3IgWSBheGVzXG5cdFx0ZGlzYWJsZVhBeGlzOiBmYWxzZSxcblx0XHRkaXNhYmxlWUF4aXM6IGZhbHNlLFxuXG5cdFx0Ly8gU2V0IHdoZXRoZXIgeW91J2QgbGlrZSB0byBwYW4gb24gbGVmdCAoMSksIG1pZGRsZSAoMiksIG9yIHJpZ2h0IGNsaWNrICgzKVxuXHRcdHdoaWNoOiAxLFxuXG5cdFx0Ly8gVGhlIGluY3JlbWVudCBhdCB3aGljaCB0byB6b29tXG5cdFx0Ly8gU2hvdWxkIGJlIGEgbnVtYmVyIGdyZWF0ZXIgdGhhbiAwXG5cdFx0aW5jcmVtZW50OiAwLjMsXG5cblx0XHQvLyBXaGVuIG5vIHNjYWxlIGlzIHBhc3NlZCwgdGhpcyBvcHRpb24gdGVsbHNcblx0XHQvLyB0aGUgYHpvb21gIG1ldGhvZCB0byBpbmNyZW1lbnRcblx0XHQvLyB0aGUgc2NhbGUgKmxpbmVhcmx5KiBiYXNlZCBvbiB0aGUgaW5jcmVtZW50IG9wdGlvbi5cblx0XHQvLyBUaGlzIG9mdGVuIGVuZHMgdXAgbG9va2luZyBsaWtlIHZlcnkgbGl0dGxlIGhhcHBlbmVkIGF0IGxhcmdlciB6b29tIGxldmVscy5cblx0XHQvLyBUaGUgZGVmYXVsdCBpcyB0byBtdWx0aXBseS9kaXZpZGUgdGhlIHNjYWxlIGJhc2VkIG9uIHRoZSBpbmNyZW1lbnQuXG5cdFx0bGluZWFyWm9vbTogZmFsc2UsXG5cblx0XHQvLyBQYW4gb25seSB3aGVuIHRoZSBzY2FsZSBpcyBncmVhdGVyIHRoYW4gbWluU2NhbGVcblx0XHRwYW5Pbmx5V2hlblpvb21lZDogZmFsc2UsXG5cblx0XHQvLyBtaW4gYW5kIG1heCB6b29tIHNjYWxlc1xuXHRcdG1pblNjYWxlOiAwLjMsXG5cdFx0bWF4U2NhbGU6IDYsXG5cblx0XHQvLyBUaGUgZGVmYXVsdCBzdGVwIGZvciB0aGUgcmFuZ2UgaW5wdXRcblx0XHQvLyBQcmVjZW5kZW5jZTogZGVmYXVsdCA8IEhUTUwgYXR0cmlidXRlIDwgb3B0aW9uIHNldHRpbmdcblx0XHRyYW5nZVN0ZXA6IDAuMDUsXG5cblx0XHQvLyBBbmltYXRpb24gZHVyYXRpb24gKG1zKVxuXHRcdGR1cmF0aW9uOiAyMDAsXG5cdFx0Ly8gQ1NTIGVhc2luZyB1c2VkIGZvciBzY2FsZSB0cmFuc2l0aW9uXG5cdFx0ZWFzaW5nOiAnZWFzZS1pbi1vdXQnLFxuXG5cdFx0Ly8gSW5kaWNhdGUgdGhhdCB0aGUgZWxlbWVudCBzaG91bGQgYmUgY29udGFpbmVkIHdpdGhpbiBpdCdzIHBhcmVudCB3aGVuIHBhbm5pbmdcblx0XHQvLyBOb3RlOiB0aGlzIGRvZXMgbm90IGFmZmVjdCB6b29taW5nIG91dHNpZGUgb2YgdGhlIHBhcmVudFxuXHRcdC8vIFNldCB0aGlzIHZhbHVlIHRvICdpbnZlcnQnIHRvIG9ubHkgYWxsb3cgcGFubmluZyBvdXRzaWRlIG9mIHRoZSBwYXJlbnQgZWxlbWVudCAoYmFzaWNhbGx5IHRoZSBvcHBvc2l0ZSBvZiB0aGUgbm9ybWFsIHVzZSBvZiBjb250YWluKVxuXHRcdC8vICdpbnZlcnQnIGlzIHVzZWZ1bCBmb3IgYSBsYXJnZSBwYW56b29tIGVsZW1lbnQgd2hlcmUgeW91IGRvbid0IHdhbnQgdG8gc2hvdyBhbnl0aGluZyBiZWhpbmQgaXRcblx0XHRjb250YWluOiBmYWxzZVxuXHR9O1xuXG5cdFBhbnpvb20ucHJvdG90eXBlID0ge1xuXHRcdGNvbnN0cnVjdG9yOiBQYW56b29tLFxuXG5cdFx0LyoqXG5cdFx0ICogQHJldHVybnMge1Bhbnpvb219IFJldHVybnMgdGhlIGluc3RhbmNlXG5cdFx0ICovXG5cdFx0aW5zdGFuY2U6IGZ1bmN0aW9uKCkge1xuXHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0fSxcblxuXHRcdC8qKlxuXHRcdCAqIEVuYWJsZSBvciByZS1lbmFibGUgdGhlIHBhbnpvb20gaW5zdGFuY2Vcblx0XHQgKi9cblx0XHRlbmFibGU6IGZ1bmN0aW9uKCkge1xuXHRcdFx0Ly8gVW5iaW5kIGZpcnN0XG5cdFx0XHR0aGlzLl9pbml0U3R5bGUoKTtcblx0XHRcdHRoaXMuX2JpbmQoKTtcblx0XHRcdHRoaXMuZGlzYWJsZWQgPSBmYWxzZTtcblx0XHR9LFxuXG5cdFx0LyoqXG5cdFx0ICogRGlzYWJsZSBwYW56b29tXG5cdFx0ICovXG5cdFx0ZGlzYWJsZTogZnVuY3Rpb24oKSB7XG5cdFx0XHR0aGlzLmRpc2FibGVkID0gdHJ1ZTtcblx0XHRcdHRoaXMuX3Jlc2V0U3R5bGUoKTtcblx0XHRcdHRoaXMuX3VuYmluZCgpO1xuXHRcdH0sXG5cblx0XHQvKipcblx0XHQgKiBAcmV0dXJucyB7Qm9vbGVhbn0gUmV0dXJucyB3aGV0aGVyIHR
7437oZSBjdXJyZW50IHBhbnpvb20gaW5zdGFuY2UgaXMgZGlzYWJsZWRcblx0XHQgKi9cblx0XHRpc0Rpc2FibGVkOiBmdW5jdGlvbigpIHtcblx0XHRcdHJldHVybiB0aGlzLmRpc2FibGVkO1xuXHRcdH0sXG5cblx0XHQvKipcblx0XHQgKiBEZXN0cm95IHRoZSBwYW56b29tIGluc3RhbmNlXG5cdFx0ICovXG5cdFx0ZGVzdHJveTogZnVuY3Rpb24oKSB7XG5cdFx0XHR0aGlzLmRpc2FibGUoKTtcblx0XHRcdCQucmVtb3ZlRGF0YSh0aGlzLmVsZW0sIGRhdGFrZXkpO1xuXHRcdH0sXG5cblx0XHQvKipcblx0XHQgKiBCdWlsZHMgdGhlIHJlc3RyaWNpbmcgZGltZW5zaW9ucyBmcm9tIHRoZSBjb250YWlubWVudCBlbGVtZW50XG5cdFx0ICogQWxzbyB1c2VkIHdpdGggZm9jYWwgcG9pbnRzXG5cdFx0ICogQ2FsbCB0aGlzIG1ldGhvZCB3aGVuZXZlciB0aGUgZGltZW5zaW9ucyBvZiB0aGUgZWxlbWVudCBvciBwYXJlbnQgYXJlIGNoYW5nZWRcblx0XHQgKi9cblx0XHRyZXNldERpbWVuc2lvbnM6IGZ1bmN0aW9uKCkge1xuXHRcdFx0Ly8gUmVzZXQgY29udGFpbmVyIHByb3BlcnRpZXNcblx0XHRcdHRoaXMuY29udGFpbmVyID0gdGhpcy5wYXJlbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cblx0XHRcdC8vIFNldCBlbGVtZW50IHByb3BlcnRpZXNcblx0XHRcdHZhciBlbGVtID0gdGhpcy5lbGVtO1xuXHRcdFx0Ly8gZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkgd29ya3Mgd2l0aCBTVkcsIG9mZnNldFdpZHRoIGRvZXMgbm90XG5cdFx0XHR2YXIgZGltcyA9IGVsZW0uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cdFx0XHR2YXIgYWJzU2NhbGUgPSBNYXRoLmFicyh0aGlzLnNjYWxlKTtcblx0XHRcdHRoaXMuZGltZW5zaW9ucyA9IHtcblx0XHRcdFx0d2lkdGg6IGRpbXMud2lkdGgsXG5cdFx0XHRcdGhlaWdodDogZGltcy5oZWlnaHQsXG5cdFx0XHRcdGxlZnQ6ICQuY3NzKGVsZW0sICdsZWZ0JywgdHJ1ZSkgfHwgMCxcblx0XHRcdFx0dG9wOiAkLmNzcyhlbGVtLCAndG9wJywgdHJ1ZSkgfHwgMCxcblx0XHRcdFx0Ly8gQm9yZGVycyBhbmQgbWFyZ2lucyBhcmUgc2NhbGVkXG5cdFx0XHRcdGJvcmRlcjoge1xuXHRcdFx0XHRcdHRvcDogJC5jc3MoZWxlbSwgJ2JvcmRlclRvcFdpZHRoJywgdHJ1ZSkgKiBhYnNTY2FsZSB8fCAwLFxuXHRcdFx0XHRcdGJvdHRvbTogJC5jc3MoZWxlbSwgJ2JvcmRlckJvdHRvbVdpZHRoJywgdHJ1ZSkgKiBhYnNTY2FsZSB8fCAwLFxuXHRcdFx0XHRcdGxlZnQ6ICQuY3NzKGVsZW0sICdib3JkZXJMZWZ0V2lkdGgnLCB0cnVlKSAqIGFic1NjYWxlIHx8IDAsXG5cdFx0XHRcdFx0cmlnaHQ6ICQuY3NzKGVsZW0sICdib3JkZXJSaWdodFdpZHRoJywgdHJ1ZSkgKiBhYnNTY2FsZSB8fCAwXG5cdFx0XHRcdH0sXG5cdFx0XHRcdG1hcmdpbjoge1xuXHRcdFx0XHRcdHRvcDogJC5jc3MoZWxlbSwgJ21hcmdpblRvcCcsIHRydWUpICogYWJzU2NhbGUgfHwgMCxcblx0XHRcdFx0XHRsZWZ0OiAkLmNzcyhlbGVtLCAnbWFyZ2luTGVmdCcsIHRydWUpICogYWJzU2NhbGUgfHwgMFxuXHRcdFx0XHR9XG5cdFx0XHR9O1xuXHRcdH0sXG5cblx0XHQvKipcblx0XHQgKiBSZXR1cm4gdGhlIGVsZW1lbnQgdG8gaXQncyBvcmlnaW5hbCB0cmFuc2Zvcm0gbWF0cml4XG5cdFx0ICogQHBhcmFtIHtCb29sZWFufSBbb3B0aW9uc10gSWYgYSBib29sZWFuIGlzIHBhc3NlZCwgYW5pbWF0ZSB0aGUgcmVzZXQgKGRlZmF1bHQ6IHRydWUpLiBJZiBhbiBvcHRpb25zIG9iamVjdCBpcyBwYXNzZWQsIHNpbXBseSBwYXNzIHRoYXQgYWxvbmcgdG8gc2V0TWF0cml4LlxuXHRcdCAqIEBwYXJhbSB7Qm9vbGVhbn0gW29wdGlvbnMuc2lsZW50XSBTaWxlbmNlIHRoZSByZXNldCBldmVudFxuXHRcdCAqL1xuXHRcdHJlc2V0OiBmdW5jdGlvbihvcHRpb25zKSB7XG5cdFx0XHRvcHRpb25zID0gY3JlYXRlUmVzZXRPcHRpb25zKG9wdGlvbnMpO1xuXHRcdFx0Ly8gUmVzZXQgdGhlIHRyYW5zZm9ybSB0byBpdHMgb3JpZ2luYWwgdmFsdWVcblx0XHRcdHZhciBtYXRyaXggPSB0aGlzLnNldE1hdHJpeCh0aGlzLl9vcmlnVHJhbnNmb3JtLCBvcHRpb25zKTtcblx0XHRcdGlmICghb3B0aW9ucy5zaWxlbnQpIHtcblx0XHRcdFx0dGhpcy5fdHJpZ2dlcigncmVzZXQnLCBtYXRyaXgpO1xuXHRcdFx0fVxuXHRcdH0sXG5cblx0XHQvKipcblx0XHQgKiBPbmx5IHJlc2V0cyB6b29tIGxldmVsXG5cdFx0ICogQHBhcmFtIHtCb29sZWFufE9iamVjdH0gW29wdGlvbnNdIFdoZXRoZXIgdG8gYW5pbWF0ZSB0aGUgcmVzZXQgKGRlZmF1bHQ6IHRydWUpIG9yIGFuIG9iamVjdCBvZiBvcHRpb25zIHRvIHBhc3MgdG8gem9vbSgpXG5cdFx0ICovXG5cdFx0cmVzZXRab29tOiBmdW5jdGlvbihvcHRpb25zKSB7XG5cdFx0XHRvcHRpb25zID0gY3JlYXRlUmVzZXRPcHRpb25zKG9wdGlvbnMpO1xuXHRcdFx0dmFyIG9yaWdNYXRyaXggPSB0aGlzLmdldE1hdHJpeCh0aGlzLl9vcmlnVHJhbnNmb3JtKTtcblx0XHRcdG9wdGlvbnMuZFZhbHVlID0gb3JpZ01hdHJpeFsgMyBdO1xuXHRcdFx0dGhpcy56b29tKG9yaWdNYXRyaXhbMF0sIG9wdGlvbnMpO1xuXHRcdH0sXG5cblx0XHQvKipcblx0XHQgKiBPbmx5IHJlc2V0IHBhbm5pbmdcblx0XHQgKiBAcGFyYW0ge0Jvb2xlYW58T2JqZWN0fSBbb3B0aW9uc10gV2hldGhlciB0byBhbmltYXRlIHRoZSByZXNldCAoZGVmYXVsdDogdHJ1ZSkgb3IgYW4gb2JqZWN0IG9mIG9wdGlvbnMgdG8gcGFzcyB0byBwYW4oKVxuXHRcdCAqL1xuXHRcdHJlc2V0UGFuOiBmdW5jdGlvbihvcHRpb25zKSB7XG5cdFx0XHR2YXIgb3JpZ01hdHJpeCA9IHRoaXMuZ2V0TWF0cml4KHRoaXMuX29yaWdUcmFuc2Zvcm0pO1xuXHRcdFx0dGhpcy5wYW4ob3JpZ01hdHJpeFs0XSwgb3JpZ01hdHJpeFs1XSwgY3JlYXRlUmVzZXRPcHRpb25zKG9wdGlvbnMpKTtcblx0XHR9LFxuXG5cdFx0LyoqXG5cdFx0ICogU2V0cyBhIHRyYW5zZm9ybSBvbiB0aGUgJHNldFxuXHRcdCAqIEZvciBTVkcsIHRoZSBzdHlsZSBhdHRyaWJ1dGUgdGFrZXMgcHJlY2VkZW5jZVxuXHRcdCAqIGFuZCBhbGxvd3MgdXMgdG8gYW5pbWF0ZVxuXHRcdCAqIEBwYXJhbSB7U3RyaW5nfSB0cmFuc2Zvcm1cblx0XHQgKi9cblx0XHRzZXRUcmFuc2Zvcm06IGZ1bmN0aW9uKHRyYW5zZm9ybSkge1xuXHRcdFx0dmFyICRzZXQgP
7437SB0aGlzLiRzZXQ7XG5cdFx0XHR2YXIgaSA9ICRzZXQubGVuZ3RoO1xuXHRcdFx0d2hpbGUoaS0tKSB7XG5cdFx0XHRcdCQuc3R5bGUoJHNldFtpXSwgJ3RyYW5zZm9ybScsIHRyYW5zZm9ybSk7XG5cblx0XHRcdFx0Ly8gU3VwcG9ydCBJRTktMTEsIEVkZ2UgMTMtMTQrXG5cdFx0XHRcdC8vIFNldCBhdHRyaWJ1dGUgYWxvbmdzaWRlIHN0eWxlIGF0dHJpYnV0ZVxuXHRcdFx0XHQvLyBzaW5jZSBJRSBhbmQgRWRnZSBkbyBub3QgcmVzcGVjdCBzdHlsZSBzZXR0aW5ncyBvbiBTVkdcblx0XHRcdFx0Ly8gU2VlIGh0dHBzOi8vY3NzLXRyaWNrcy5jb20vdHJhbnNmb3Jtcy1vbi1zdmctZWxlbWVudHMvXG5cdFx0XHRcdGlmICh0aGlzLmlzU1ZHKSB7XG5cdFx0XHRcdFx0JHNldFtpXS5zZXRBdHRyaWJ1dGUoJ3RyYW5zZm9ybScsIHRyYW5zZm9ybSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9LFxuXG5cdFx0LyoqXG5cdFx0ICogUmV0cmlldmluZyB0aGUgdHJhbnNmb3JtIGlzIGRpZmZlcmVudCBmb3IgU1ZHXG5cdFx0ICogICh1bmxlc3MgYSBzdHlsZSB0cmFuc2Zvcm0gaXMgYWxyZWFkeSBwcmVzZW50KVxuXHRcdCAqIFVzZXMgdGhlICRzZXQgY29sbGVjdGlvbiBmb3IgcmV0cmlldmluZyB0aGUgdHJhbnNmb3JtXG5cdFx0ICogQHBhcmFtIHtTdHJpbmd9IFt0cmFuc2Zvcm1dIFBhc3MgaW4gYW4gdHJhbnNmb3JtIHZhbHVlIChsaWtlICdzY2FsZSgxLjEpJylcblx0XHQgKiAgdG8gaGF2ZSBpdCBmb3JtYXR0ZWQgaW50byBtYXRyaXggZm9ybWF0IGZvciB1c2UgYnkgUGFuem9vbVxuXHRcdCAqIEByZXR1cm5zIHtTdHJpbmd9IFJldHVybnMgdGhlIGN1cnJlbnQgdHJhbnNmb3JtIHZhbHVlIG9mIHRoZSBlbGVtZW50XG5cdFx0ICovXG5cdFx0Z2V0VHJhbnNmb3JtOiBmdW5jdGlvbih0cmFuc2Zvcm0pIHtcblx0XHRcdHZhciAkc2V0ID0gdGhpcy4kc2V0O1xuXHRcdFx0dmFyIHRyYW5zZm9ybUVsZW0gPSAkc2V0WzBdO1xuXHRcdFx0aWYgKHRyYW5zZm9ybSkge1xuXHRcdFx0XHR0aGlzLnNldFRyYW5zZm9ybSh0cmFuc2Zvcm0pO1xuXHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHQvLyBJRSBhbmQgRWRnZSBzdGlsbCBzZXQgdGhlIHRyYW5zZm9ybSBzdHlsZSBwcm9wZXJseVxuXHRcdFx0XHQvLyBUaGV5IGp1c3QgZG9uJ3QgcmVuZGVyIGl0IG9uIFNWR1xuXHRcdFx0XHQvLyBTbyB3ZSBnZXQgYSBjb3JyZWN0IHZhbHVlIGhlcmVcblx0XHRcdFx0dHJhbnNmb3JtID0gJC5zdHlsZSh0cmFuc2Zvcm1FbGVtLCAndHJhbnNmb3JtJyk7XG5cblx0XHRcdFx0aWYgKHRoaXMuaXNTVkcgJiYgKCF0cmFuc2Zvcm0gfHwgdHJhbnNmb3JtID09PSAnbm9uZScpKSB7XG5cdFx0XHRcdFx0dHJhbnNmb3JtID0gJC5hdHRyKHRyYW5zZm9ybUVsZW0sICd0cmFuc2Zvcm0nKSB8fCAnbm9uZSc7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Ly8gQ29udmVydCBhbnkgdHJhbnNmb3JtcyBzZXQgYnkgdGhlI
7437HVzZXIgdG8gbWF0cml4IGZvcm1hdFxuXHRcdFx0Ly8gYnkgc2V0dGluZyB0byBjb21wdXRlZFxuXHRcdFx0aWYgKHRyYW5zZm9ybSAhPT0gJ25vbmUnICYmICFybWF0cml4LnRlc3QodHJhbnNmb3JtKSkge1xuXG5cdFx0XHRcdC8vIEdldCBjb21wdXRlZCBhbmQgc2V0IGZvciBuZXh0IHRpbWVcblx0XHRcdFx0dGhpcy5zZXRUcmFuc2Zvcm0odHJhbnNmb3JtID0gJC5jc3ModHJhbnNmb3JtRWxlbSwgJ3RyYW5zZm9ybScpKTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIHRyYW5zZm9ybSB8fCAnbm9uZSc7XG5cdFx0fSxcblxuXHRcdC8qKlxuXHRcdCAqIFJldHJpZXZlIHRoZSBjdXJyZW50IHRyYW5zZm9ybSBtYXRyaXggZm9yICRlbGVtIChvciB0dXJuIGEgdHJhbnNmb3JtIGludG8gaXQncyBhcnJheSB2YWx1ZXMpXG5cdFx0ICogQHBhcmFtIHtTdHJpbmd9IFt0cmFuc2Zvcm1dIG1hdHJpeC1mb3JtYXR0ZWQgdHJhbnNmb3JtIHZhbHVlXG5cdFx0ICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBjdXJyZW50IHRyYW5zZm9ybSBtYXRyaXggc3BsaXQgdXAgaW50byBpdCdzIHBhcnRzLCBvciBhIGRlZmF1bHQgbWF0cml4XG5cdFx0ICovXG5cdFx0Z2V0TWF0cml4OiBmdW5jdGlvbih0cmFuc2Zvcm0pIHtcblx0XHRcdHZhciBtYXRyaXggPSBybWF0cml4LmV4ZWModHJhbnNmb3JtIHx8IHRoaXMuZ2V0VHJhbnNmb3JtKCkpO1xuXHRcdFx0aWYgKG1hdHJpeCkge1xuXHRcdFx0XHRtYXRyaXguc2hpZnQoKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBtYXRyaXggfHwgWyAxLCAwLCAwLCAxLCAwLCAwIF07XG5cdFx0fSxcblxuXHRcdC8qKlxuXHRcdCAqIEdpdmVuIGEgbWF0cml4IG9iamVjdCwgcXVpY2tseSBzZXQgdGhlIGN1cnJlbnQgbWF0cml4IG9mIHRoZSBlbGVtZW50XG5cdFx0ICogQHBhcmFtIHtBcnJheXxTdHJpbmd9IG1hdHJpeFxuXHRcdCAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc11cblx0XHQgKiBAcGFyYW0ge0Jvb2xlYW58U3RyaW5nfSBbb3B0aW9ucy5hbmltYXRlXSBXaGV0aGVyIHRvIGFuaW1hdGUgdGhlIHRyYW5zZm9ybSBjaGFuZ2UsIG9yICdza2lwJyBpbmRpY2F0aW5nIHRoYXQgaXQgaXMgdW5uZWNlc3NhcnkgdG8gc2V0XG5cdFx0ICogQHBhcmFtIHtCb29sZWFufSBbb3B0aW9ucy5jb250YWluXSBPdmVycmlkZSB0aGUgZ2xvYmFsIGNvbnRhaW4gb3B0aW9uXG5cdFx0ICogQHBhcmFtIHtCb29sZWFufSBbb3B0aW9ucy5yYW5nZV0gSWYgdHJ1ZSwgJHpvb21SYW5nZSdzIHZhbHVlIHdpbGwgYmUgdXBkYXRlZC5cblx0XHQgKiBAcGFyYW0ge0Jvb2xlYW59IFtvcHRpb25zLnNpbGVudF0gSWYgdHJ1ZSwgdGhlIGNoYW5nZSBldmVudCB3aWxsIG5vdCBiZSB0cmlnZ2VyZWRcblx0XHQgKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ld2x5LXNldCBtYXRyaXhcblx0XHQgKi9cblx0XHRzZXRNYXRyaXg6IGZ1bmN0aW9uKG1hdHJpeCwgb3B0aW9ucykge1xuXHRcdFx0aWYgKHRoaXMuZGlzYWJsZWQpIHsgcmV0dXJuOyB9XG5cdFx0XHRpZiAoIW9wdGlvbnMpIHsgb3B0aW9ucyA9IHt9OyB9XG5cdFx0XHQvLyBDb252ZXJ0IHRvIGFycmF5XG5cdFx0XHRpZiAodHlwZW9mIG1hdHJpeCA9PT0gJ3N0cmluZycpIHtcblx0XHRcdFx0bWF0cml4ID0gdGhpcy5nZXRNYXRyaXgobWF0cml4KTtcblx0XHRcdH1cblx0XHRcdHZhciBzY2FsZSA9ICttYXRyaXhbMF07XG5cdFx0XHR2YXIgY29udGFpbiA9IHR5cGVvZiBvcHRpb25zLmNvbnRhaW4gIT09ICd1bmRlZmluZWQnID8gb3B0aW9ucy5jb250YWluIDogdGhpcy5vcHRpb25zLmNvbnRhaW47XG5cblx0XHRcdC8vIEFwcGx5IGNvbnRhaW5tZW50XG5cdFx0XHRpZiAoY29udGFpbikge1xuXHRcdFx0XHR2YXIgZGltcyA9IG9wdGlvbnMuZGltcztcblx0XHRcdFx0aWYgKCFkaW1zKSB7XG5cdFx0XHRcdFx0dGhpcy5yZXNldERpbWVuc2lvbnMoKTtcblx0XHRcdFx0XHRkaW1zID0gdGhpcy5kaW1lbnNpb25zO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHZhciBzcGFjZVdMZWZ0LCBzcGFjZVdSaWdodCwgc2NhbGVEaWZmO1xuXHRcdFx0XHR2YXIgY29udGFpbmVyID0gdGhpcy5jb250YWluZXI7XG5cdFx0XHRcdHZhciB3aWR0aCA9IGRpbXMud2lkdGg7XG5cdFx0XHRcdHZhciBoZWlnaHQgPSBkaW1zLmhlaWdodDtcblx0XHRcdFx0dmFyIGNvbldpZHRoID0gY29udGFpbmVyLndpZHR
7437oO1xuXHRcdFx0XHR2YXIgY29uSGVpZ2h0ID0gY29udGFpbmVyLmhlaWdodDtcblx0XHRcdFx0dmFyIHpvb21Bc3BlY3RXID0gY29uV2lkdGggLyB3aWR0aDtcblx0XHRcdFx0dmFyIHpvb21Bc3BlY3RIID0gY29uSGVpZ2h0IC8gaGVpZ2h0O1xuXG5cdFx0XHRcdC8vIElmIHRoZSBlbGVtZW50IGlzIG5vdCBuYXR1cmFsbHkgY2VudGVyZWQsXG5cdFx0XHRcdC8vIGFzc3VtZSBmdWxsIHNwYWNlIHJpZ2h0XG5cdFx0XHRcdGlmICh0aGlzLiRwYXJlbnQuY3NzKCd0ZXh0QWxpZ24nKSAhPT0gJ2NlbnRlcicgfHwgJC5jc3ModGhpcy5lbGVtLCAnZGlzcGxheScpICE9PSAnaW5saW5lJykge1xuXHRcdFx0XHRcdC8vIG9mZnNldFdpZHRoIGdldHMgdXMgdGhlIHdpZHRoIHdpdGhvdXQgdGhlIHRyYW5zZm9ybVxuXHRcdFx0XHRcdHNjYWxlRGlmZiA9ICh3aWR0aCAtIHRoaXMuZWxlbS5vZmZzZXRXaWR0aCkgLyAyO1xuXHRcdFx0XHRcdHNwYWNlV0xlZnQgPSBzY2FsZURpZmYgLSBkaW1zLmJvcmRlci5sZWZ0O1xuXHRcdFx0XHRcdHNwYWNlV1JpZ2h0ID0gd2lkdGggLSBjb25XaWR0aCAtIHNjYWxlRGlmZiArIGRpbXMuYm9yZGVyLnJpZ2h0O1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHNwYWNlV0xlZnQgPSBzcGFjZVdSaWdodCA9ICgod2lkdGggLSBjb25XaWR0aCkgLyAyKTtcblx0XHRcdFx0fVxuXHRcdFx0XHR2YXIgc3BhY2VIVG9wID0gKChoZWlnaHQgLSBjb25IZWlnaHQpIC8gMikgKyBkaW1zLmJvcmRlci50b3A7XG5cdFx0XHRcdHZhciBzcGFjZUhCb3R0b20gPSAoKGhlaWdodCAtIGNvbkhlaWdodCkgLyAyKSAtIGRpbXMuYm9yZGVyLnRvcCAtIGRpbXMuYm9yZGVyLmJvdHRvbTtcblxuXHRcdFx0XHRpZiAoY29udGFpbiA9PT0gJ2ludmVydCcgfHwgY29udGFpbiA9PT0gJ2F1dG9tYXRpYycgJiYgem9vbUFzcGVjdFcgPCAxLjAxKSB7XG5cdFx0XHRcdFx0bWF0cml4WzRdID0gTWF0aC5tYXgoTWF0aC5taW4obWF0cml4WzRdLCBzcGFjZVdMZWZ0IC0gZGltcy5ib3JkZXIubGVmdCksIC1zcGFjZVdSaWdodCk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0bWF0cml4WzRdID0gTWF0aC5taW4oTWF0aC5tYXgobWF0cml4WzRdLCBzcGFjZVdMZWZ0KSwgLXNwYWNlV1JpZ2h0KTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGlmIChjb250YWluID09PSAnaW52ZXJ0JyB8fCAoY29udGFpbiA9PT0gJ2F1dG9tYXRpYycgJiYgem9vbUFzcGVjdEggPCAxLjAxKSkge1xuXHRcdFx0XHRcdG1hdHJpeFs1XSA9IE1hdGgubWF4KE1hdGgubWluKG1hdHJpeFs1XSwgc3BhY2VIVG9wIC0gZGltcy5ib3JkZXIudG9wKSwgLXNwYWNlSEJvdHRvbSk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0bWF0cml4WzVdID0gTWF0aC5taW4oTWF0aC5tYXgobWF0cml4WzVdLCBzcGFjZUhUb3ApLCAtc3BhY2VIQm90dG9tKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBBbmltYXRlXG5cdFx0XHRpZiAob3B0aW9ucy5hbmltYXRlICE9PSAnc2tpcCcpIHtcblx0XHRcdFx0Ly8gU2V0IHRyYW5zaXRpb25cblx0XHRcdFx0dGhpcy50cmFuc2l0aW9uKCFvcHRpb25zLmFuaW1hdGUpO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBVcGRhdGUgcmFuZ2UgZWxlbWVudFxuXHRcdFx0aWYgKG9wdGlvbnMucmFuZ2UpIHtcblx0XHRcdFx0dGhpcy4kem9vbVJhbmdlLnZhbChzY2FsZSk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFNldCB0aGUgbWF0cml4IG9uIHRoaXMuJHNldFxuXHRcdFx0aWYgKHRoaXMub3B0aW9ucy5kaXNhYmxlWEF4aXMgfHwgdGhpcy5vcHRpb25zLmRpc2FibGVZQXhpcykge1xuXHRcdFx0XHR2YXIgb3JpZ2luYWxNYXRyaXggPSB0aGlzLmdldE1hdHJpeCgpO1xuXHRcdFx0XHRpZiAodGhpcy5vcHRpb25zLmRpc2FibGVYQXhpcykge1xuXHRcdFx0XHRcdG1hdHJpeFs0XSA9IG9yaWdpbmFsTWF0cml4WzRdO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGlmICh0aGlzLm9wdGlvbnMuZGlzYWJsZVlBeGlzKSB7XG5cdFx0XHRcdFx0bWF0cml4WzVdID0gb3JpZ2luYWxNYXRyaXhbNV07XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHRoaXMuc2V0VHJhbnNmb3JtKCdtYXRyaXgoJyArIG1hdHJpeC5qb2luKCcsJykgKyAnKScpO1xuXG5cdFx0XHR0aGlzLnNjYWxlID0gc2NhbGU7XG5cblx0XHRcdC8vIERpc2FibGUvZW5hYmxlIHBhbm5pbmcgaWYgem9vbWluZyBpcyBhdCBtaW5pbXVtIGFuZCBwYW5Pbmx5V2hlblpvb21lZCBpcyB0cnVlXG5cdFx0XHR0aGlzLl9jaGVja1BhbldoZW5ab29tZWQoc2NhbGUpO1xuXG5cdFx0XHRpZiAoIW9wdGlvbnMuc2lsZW50KSB7XG5cdFx0XHRcdHRoaXMuX3RyaWdnZXIoJ2NoYW5nZScsIG1hdHJpeCk7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBtYXRyaXg7XG5cdFx0fSxcblxuXHRcdC8qKlxuXHRcdCAqIEByZXR1cm5zIHtCb29sZWFufSBSZXR1cm5zIHdoZXRoZXIgdGhlIHBhbnpvb20gZWxlbWVudCBpcyBjdXJyZW50bHkgYmVpbmcgZHJhZ2dlZFxuXHRcdCAqL1xuXHRcdGlzUGFubmluZzogZnVuY3Rpb24oKSB7XG5cdFx0XHRyZXR1cm4gdGhpcy5wYW5uaW5nO1xuXHRcdH0sXG5cblx0XHQvKipcblx0XHQgKiBBcHBseSB0aGUgY3VycmVudCB0cmFuc2l0aW9uIHRvIHRoZSBlbGVtZW50LCBpZiBhbGxvd2VkXG5cdFx0ICogQHBhcmFtIHtCb29sZWFufSBbb2ZmXSBJbmRpY2F0ZXMgdGhhdCB0aGUgdHJhbnNpdGlvbiBzaG91bGQgYmUgdHVybmVkIG9mZlxuXHRcdCAqL1xuXHRcdHRyYW5zaXRpb246IGZ1bmN0aW9uKG9mZikge1xuXHRcdFx0aWYgKCF0aGlzLl90cmFuc2l0aW9uKSB7IHJldHVybjsgfVxuXHRcdFx0dmFyIHRyYW5zaXRpb24gPSBvZmYgfHwgIXRoaXMub3B0aW9ucy50cmFuc2l0aW9uID8gJ25vbmUnIDogdGhpcy5fdHJhbnNpdGlvbjtcblx0XHRcdHZhciAkc2V0ID0gdGhpcy4kc2V0O1xuXHRcdFx0dmFyIGkgPSAkc2V0Lmxlbmd0aDtcblx0XHRcdHdoaWxlKGktLSkge1xuXHRcdFx0XHQvLyBBdm9pZCByZWZsb3dzIHdoZW4gem9vbWluZ1xuXHRcdFx0XHRpZiAoJC5zdHlsZSgkc2V0W2ldLCAndHJhbnNpdGlvbicpICE9PSB0cmFuc2l0aW9uKSB7XG5cdFx0XHRcdFx0JC5zdHlsZSgkc2V0W2ldLCAndHJhbnNpdGlvbicsIHRyYW5zaXRpb24pO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSxcblxuXHRcdC8qKlxuXHRcdCAqIFBhbiB0aGUgZWxlbWVudCB0byB0aGUgc3BlY2lmaWVkIHRyYW5zbGF0aW9uIFggYW5kIFlcblx0XHQgKiBOb3RlOiB0aGlzIGlzIG5vdCB0aGUgc2FtZSBhcyBzZXR0aW5nIGpRdWVyeSNvZmZzZXQoKSBvciBqUXVlcnkjcG9zaXRpb24oKVxuXHRcdCAqIEBwYXJhbSB7TnVtYmVyfSB4XG5cdFx0ICogQHBhcmFtIHtOdW1iZXJ9IHlcblx0XHQgKiBAcGFyYW0ge09
7437iamVjdH0gW29wdGlvbnNdIFRoZXNlIG9wdGlvbnMgYXJlIHBhc3NlZCBhbG9uZyB0byBzZXRNYXRyaXhcblx0XHQgKiBAcGFyYW0ge0FycmF5fSBbb3B0aW9ucy5tYXRyaXhdIFRoZSBtYXRyaXggYmVpbmcgbWFuaXB1bGF0ZWQgKGlmIGFscmVhZHkga25vd24gc28gaXQgZG9lc24ndCBoYXZlIHRvIGJlIHJldHJpZXZlZCBhZ2Fpbilcblx0XHQgKiBAcGFyYW0ge0Jvb2xlYW59IFtvcHRpb25zLnNpbGVudF0gU2lsZW5jZSB0aGUgcGFuIGV2ZW50LiBOb3RlIHRoYXQgdGhpcyB3aWxsIGFsc28gc2lsZW5jZSB0aGUgc2V0TWF0cml4IGNoYW5nZSBldmVudC5cblx0XHQgKiBAcGFyYW0ge0Jvb2xlYW59IFtvcHRpb25zLnJlbGF0aXZlXSBNYWtlIHRoZSB4IGFuZCB5IHZhbHVlcyByZWxhdGl2ZSB0byB0aGUgZXhpc3RpbmcgbWF0cml4XG5cdFx0ICovXG5cdFx0cGFuOiBmdW5jdGlvbih4LCB5LCBvcHRpb25zKSB7XG5cdFx0XHRpZiAodGhpcy5vcHRpb25zLmRpc2FibGVQYW4pIHsgcmV0dXJuOyB9XG5cdFx0XHRpZiAoIW9wdGlvbnMpIHsgb3B0aW9ucyA9IHt9OyB9XG5cdFx0XHR2YXIgbWF0cml4ID0gb3B0aW9ucy5tYXRyaXg7XG5cdFx0XHRpZiAoIW1hdHJpeCkge1xuXHRcdFx0XHRtYXRyaXggPSB0aGlzLmdldE1hdHJpeCgpO1xuXHRcdFx0fVxuXHRcdFx0Ly8gQ2FzdCBleGlzdGluZyBtYXRyaXggdmFsdWVzIHRvIG51bWJlcnNcblx0XHRcdGlmIChvcHRpb25zLnJlbGF0aXZlKSB7XG5cdFx0XHRcdHggKz0gK21hdHJpeFs0XTtcblx0XHRcdFx0eSArPSArbWF0cml4WzVdO1xuXHRcdFx0fVxuXHRcdFx0bWF0cml4WzRdID0geDtcblx0XHRcdG1hdHJpeFs1XSA9IHk7XG5cdFx0XHR0aGlzLnNldE1hdHJpeChtYXRyaXgsIG9wdGlvbnMpO1xuXHRcdFx0aWYgKCFvcHRpb25zLnNpbGVudCkge1xuXHRcdFx0XHR0aGlzLl90cmlnZ2VyKCdwYW4nLCBtYXRyaXhbNF0sIG1hdHJpeFs1XSk7XG5cdFx0XHR9XG5cdFx0fSxcblxuXHRcdC8qKlxuXHRcdCAqIFpvb20gaW4vb3V0IHRoZSBlbGVtZW50IHVzaW5nIHRoZSBzY2FsZSBwcm9wZXJ0aWVzIG9mIGEgdHJhbnNmb3JtIG1hdHJpeFxuXHRcdCAqIEBwYXJhbSB7TnVtYmVyfEJvb2xlYW59IFtzY2FsZV0gVGhlIHNjYWxlIHRvIHdoaWNoIHRvIHpvb20gb3IgYSBib29sZWFuIGluZGljYXRpbmcgdG8gdHJhbnNpdGlvbiBhIHpvb20gb3V0XG5cdFx0ICogQHBhcmFtIHtPYmplY3R9IFtvcHRzXSBBbGwgZ2xvYmFsIG9wdGlvbnMgY2FuIGJlIG92ZXJ3cml0dGVuIGJ5IHRoaXMgb3B0aW9ucyBvYmplY3QuIEZvciBleGFtcGxlLCBvdmVycmlkZSB0aGUgZGVmYXVsdCBpbmNyZW1lbnQuXG5cdFx0ICogQHBhcmFtIHtCb29sZWFufSBbb3B0cy5ub1NldFJhbmdlXSBTcGVjaWZ5IHRoYXQgdGhlIG1ldGhvZCBzaG91bGQgbm90IHNldCB0aGUgJHpvb21SYW5nZSB2YWx1ZSAoYXMgaXMgdGhlIGNhc2Ugd2hlbiAkem9vbVJhbmdlIGlzIGNhbGxpbmcgem9vbSBvbiBjaGFuZ2UpXG5cdFx0ICogQHBhcmFtIHtqUXVlcnkuRXZlbnR8T2JqZWN0fSBbb3B0cy5mb2NhbF0gQSBmb2NhbCBwb2ludCBvbiB0aGUgcGFuem9vbSBlbGVtZW50IG9uIHdoaWNoIHRvIHpvb20uXG5cdFx0ICogIElmIGFuIG9iamVjdCwgc2V0IHRoZSBjbGllbnRYIGFuZCBjbGllbnRZIHByb3BlcnRpZXMgdG8gdGhlIHBvc2l0aW9uIHJlbGF0aXZlIHRvIHRoZSBwYXJlbnRcblx0XHQgKiBAcGFyYW0ge0Jvb2xlYW59IFtvcHRzLmFuaW1hdGVdIFdoZXRoZXIgdG8gYW5pbWF0ZSB0aGUgem9vbSAoZGVmYXVsdHMgdG8gdHJ1ZSBpZiBzY2FsZSBpcyBub3QgYSBudW1iZXIsIGZhbHNlIG90aGVyd2lzZSlcblx0XHQgKiBAcGFyYW0ge0Jvb2xlYW59IFtvcHRzLnNpbGVudF0gU2lsZW5jZSB0aGUgem9vbSBldmVudFxuXHRcdCAqIEBwYXJhbSB7QXJyYXl9IFtvcHRzLm1hdHJpeF0gT3B0aW9uYWxseSBwYXNzIHRoZSBjdXJyZW50IG1hdHJpeCBzbyBpdCBkb2Vzbid0IG5lZWQgdG8gYmUgcmV0cmlldmVkXG5cdFx0ICogQHBhcmFtIHtOdW1iZXJ9IFtvcHRzLmRWYWx1ZV0gVGhpbmsgb2YgYSB0cmFuc2Zvcm0gbWF0cml4IGFzIGZvdXIgdmFsdWVzIGEsIGIsIGMsIGRcblx0XHQgKiAgd2hlcmUgYS9kIGFyZSB0aGUgaG9yaXpvbnRhbC92ZXJ0aWNhbCBzY2FsZSB2YWx1ZXMgYW5kIGIvYyBhcmUgdGhlIHNrZXcgdmFsdWVzXG5cdFx0ICogICg1IGFuZCA2IG9mIG1hdHJpeCBhcnJheSBhcmUgdGhlIHR4L3R5IHRyYW5zZm9ybSB2YWx1ZXMpLlxuXHRcdCAqICBOb3JtYWxseSwgdGhlIHNjYWxlIGlzIHNldCB0byBib3RoIHRoZSBhIGFuZCBkIHZhbHVlcyBvZiB0aGUgbWF0cml4LlxuXHRcdCAqICBUaGlzIG9wdGlvbiBhbGxvd3MgeW91IHRvIHNwZWNpZnkgYSBkaWZmZXJlbnQgZCB2YWx1ZSBmb3IgdGhlIHpvb20uXG5cdFx0ICogIEZvciBpbnN0YW5jZSwgdG8gZmxpcCB2ZXJ0aWNhbGx5LCB5b3UgY291bGQgc2V0IC0xIGFzIHRoZSBkVmFsdWUuXG5cdFx0ICovXG5cdFx0em9vbTogZnVuY3Rpb24oc2NhbGUsIG9wdHMpIHtcblx0XHRcdC8vIFNodWZmbGUgYXJndW1lbnRzXG5cdFx0XHRpZiAodHlwZW9mIHNjYWxlID09PSAnb2JqZWN0Jykge1xuXHRcdFx0XHRvcHRzID0gc2NhbGU7XG5cdFx0XHRcdHNjYWxlID0gbnVsbDtcblx0XHRcdH0gZWxzZSBpZiAoIW9wdHMpIHtcblx0XHRcdFx0b3B0cyA9IHt9O1xuXHRcdFx0fVxuXHRcdFx0dmFyIG9wdGlvbnMgPSAkLmV4dGVuZCh7fSwgdGhpcy5vcHRpb25zLCBvcHRzKTtcblx0XHRcdC8vIENoZWNrIGlmIGRpc2FibGVkXG5cdFx0XHRpZiAob3B0aW9ucy5kaXNhYmxlWm9vbSkgeyByZXR1cm47IH1cblx0XHRcdHZhciBhbmltYXRlID0gZmFsc2U7XG5cdFx0XHR2YXIgbWF0cml4ID0gb3B0aW9ucy5tYXRyaXggfHwgdGhpcy5nZXRNYXRyaXgoKTtcblx0XHRcdHZhciBzdGFydFNjYWxlID0gK21hdHJpeFswXTtcblxuXHRcdFx0Ly8gQ2FsY3VsYXRlIHpvb20gYmFzZWQgb24gaW5jcmVtZW50XG5cdFx0XHRpZiAodHlwZW9mIHNjYWxlICE9PSAnbnVtYmVyJykge1xuXHRcdFx0XHRpZiAob3B0aW9ucy5saW5lYXJab29tKSB7XG5cdFx0XHRcdFx0c2NhbGUgPSBzdGFydFNjYWxlICsgKG9wdGlvbnMuaW5jcmVtZW50ICogKHNjYWxlID8gLTEgOiAxKSk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0c2NhbGUgPSBzY2FsZSA/IChzdGFydFNjYWxlIC8gKDEgKyBvcHRpb25zLmluY3JlbWVudCkpIDogKHN0YXJ0U2NhbGUgKiAoMSArIG9wdGlvbnMuaW5jcmVtZW50KSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0YW5pbWF0ZSA9IHRydWU7XG5cdFx0XHR9XG5cblx0XHRcdC8vIENvbnN0cmFpbiBzY2FsZVxuXHRcdFx0c2NhbGUgPSBNYXRoLm1heChNYXRoLm1pbihzY2FsZSwgb3B0aW9ucy5tYXhTY2FsZSksIG9wdGlvbnMubWluU2NhbGUpO1xuXG5cdFx0XHQvLyBDYWxjdWxhdGUgZm9jYWwgcG9pbnQgYmFzZWQgb24gc2NhbGVcblx0XHRcdHZhciBmb2NhbCA9IG9wdGlvbnMuZm9jYWw7XG5cdFx0XHRpZiAoZm9jYWwgJiYgIW9wdGlvbnMuZGlzYWJsZVBhbikge1xuXHRcdFx0XHQvLyBBZGFwdGVkIGZyb20gY29kZSBieSBGbG9yaWFuIEfDvG50aGVyXG5cdFx0XHRcdC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9mbG9yaWFuZ3VlbnRoZXIvenVpNTNcblx0XHRcdFx0dGhpcy5yZXNldERpbWVuc2lvbnMoKTtcblx0XHRcdFx0dmFyIGRpbXMgPSBvcHRpb25zLmRpbXMgPSB0aGlzLmRpbWVuc2lvbnM7XG5cdFx0XHRcdHZhciBjbGllbnRYID0gZm9jYWwuY2xpZW50WDtcblx0XHRcdFx0dmFyIGNsaWVudFkgPSBmb2NhbC5jbGllbnRZO1xuXG5cdFx0XHRcdC8vIEFkanVzdCB0aGUgZm9jYWwgcG9pbnQgZm9yIHRyYW5zZm9ybS1vcmlnaW4gNTAlIDUwJVxuXHRcdFx0XHQvLyBTVkcgZWxlbWVudHMgaGF2ZSBhIHRyYW5zZm9ybSBvcmlnaW4gb2YgMCAwXG5cdFx0XHRcdGlmICghdGhpcy5pc1NWRykge1xuXHRcdFx0XHRcdGNsaWVudFggLT0gKGRpbXMud2lkdGggLyBzdGFydFNjYWxlKSAvIDI7XG5cdFx0XHRcdFx0Y2xpZW50WSAtPSAoZGltcy5oZWlnaHQgLyBzdGFydFNjYWxlKSAvIDI7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHR2YXIgY2xpZW50ViA9IG5ldyBWZWN0b3IoY2xpZW50WCwgY2x
7437pZW50WSwgMSk7XG5cdFx0XHRcdHZhciBzdXJmYWNlTSA9IG5ldyBNYXRyaXgobWF0cml4KTtcblx0XHRcdFx0Ly8gU3VwcGx5IGFuIG9mZnNldCBtYW51YWxseSBpZiBuZWNlc3Nhcnlcblx0XHRcdFx0dmFyIG8gPSB0aGlzLnBhcmVudE9mZnNldCB8fCB0aGlzLiRwYXJlbnQub2Zmc2V0KCk7XG5cdFx0XHRcdHZhciBvZmZzZXRNID0gbmV3IE1hdHJpeCgxLCAwLCBvLmxlZnQgLSB0aGlzLiRkb2Muc2Nyb2xsTGVmdCgpLCAwLCAxLCBvLnRvcCAtIHRoaXMuJGRvYy5zY3JvbGxUb3AoKSk7XG5cdFx0XHRcdHZhciBzdXJmYWNlViA9IHN1cmZhY2VNLmludmVyc2UoKS54KG9mZnNldE0uaW52ZXJzZSgpLngoY2xpZW50VikpO1xuXHRcdFx0XHR2YXIgc2NhbGVCeSA9IHNjYWxlIC8gbWF0cml4WzBdO1xuXHRcdFx0XHRzdXJmYWNlTSA9IHN1cmZhY2VNLngobmV3IE1hdHJpeChbc2NhbGVCeSwgMCwgMCwgc2NhbGVCeSwgMCwgMF0pKTtcblx0XHRcdFx0Y2xpZW50ViA9IG9mZnNldE0ueChzdXJmYWNlTS54KHN1cmZhY2VWKSk7XG5cdFx0XHRcdG1hdHJpeFs0XSA9ICttYXRyaXhbNF0gKyAoY2xpZW50WCAtIGNsaWVudFYuZSgwKSk7XG5cdFx0XHRcdG1hdHJpeFs1XSA9ICttYXRyaXhbNV0gKyAoY2xpZW50WSAtIGNsaWVudFYuZSgxKSk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFNldCB0aGUgc2NhbGVcblx0XHRcdG1hdHJpeFswXSA9IHNjYWxlO1xuXHRcdFx0bWF0cml4WzNdID0gdHlwZW9mIG9wdGlvbnMuZFZhbHVlID09PSAnbnVtYmVyJyA/IG9wdGlvbnMuZFZhbHVlIDogc2NhbGU7XG5cblx0XHRcdC8vIENhbGxpbmcgem9vbSBtYXkgc3RpbGwgcGFuIHRoZSBlbGVtZW50XG5cdFx0XHR0aGlzLnNldE1hdHJpeChtYXRyaXgsIHtcblx0XHRcdFx0YW5pbWF0ZTogdHlwZW9mIG9wdGlvbnMuYW5pbWF0ZSAhPT0gJ3VuZGVmaW5lZCcgPyBvcHRpb25zLmFuaW1hdGUgOiBhbmltYXRlLFxuXHRcdFx0XHQvLyBTZXQgdGhlIHpvb21SYW5nZSB2YWx1ZVxuXHRcdFx0XHRyYW5nZTogIW9wdGlvbnMubm9TZXRSYW5nZVxuXHRcdFx0fSk7XG5cblx0XHRcdC8vIFRyaWdnZXIgem9vbSBldmVudFxuXHRcdFx0aWYgKCFvcHRpb25zLnNpbGVudCkge1xuXHRcdFx0XHR0aGlzLl90cmlnZ2VyKCd6b29tJywgbWF0cml4WzBdLCBvcHRpb25zKTtcblx0XHRcdH1cblx0XHR9LFxuXG5cdFx0LyoqXG5cdFx0ICogR2V0L3NldCBvcHRpb24gb24gYW4gZXhpc3RpbmcgaW5zdGFuY2Vcblx0XHQgKiBAcmV0dXJucyB7QXJyYXl8dW5kZWZpbmVkfSBJZiBnZXR0aW5nLCByZXR1cm5zIGFuIGFycmF5IG9mIGFsbCB2YWx1ZXNcblx0XHQgKiAgIG9uIGVhY2ggaW5zdGFuY2UgZm9yIGEgZ2l2ZW4ga2V5LiBJZiBzZXR0aW5nLCBjb250aW51ZSBjaGFpbmluZyBieSByZXR1cm5pbmcgdW5kZWZpbmVkLlxuXHRcdCAqL1xuXHRcdG9wdGlvbjogZnVuY3Rpb24oa2V5LCB2YWx1ZSkge1xuXHRcdFx0dmFyIG9wdGlvbnM7XG5cdFx0XHRpZiAoIWtleSkge1xuXHRcdFx0XHQvLyBBdm9pZHMgcmV0dXJuaW5nIGRpcmVjdCByZWZlcmVuY2Vcblx0XHRcdFx0cmV0dXJuICQuZXh0ZW5kKHt9LCB0aGlzLm9wdGlvbnMpO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAodHlwZW9mIGtleSA9PT0gJ3N0cmluZycpIHtcblx0XHRcdFx0aWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDEpIHtcblx0XHRcdFx0XHRyZXR1cm4gdGhpcy5vcHRpb25zWyBrZXkgXSAhPT0gdW5kZWZpbmVkID9cblx0XHRcdFx0XHRcdHRoaXMub3B0aW9uc1sga2V5IF0gOlxuXHRcdFx0XHRcdFx0bnVsbDtcblx0XHRcdFx0fVxuXHRcdFx0XHRvcHRpb25zID0ge307XG5cdFx0XHRcdG9wdGlvbnNbIGtleSBdID0gdmFsdWU7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRvcHRpb25zID0ga2V5O1xuXHRcdFx0fVxuXG5cdFx0XHR0aGlzLl9zZXRPcHRpb25zKG9wdGlvbnMpO1xuXHRcdH0sXG5cblx0XHQvKipcblx0XHQgKiBJbnRlcm5hbGx5IHNldHMgb3B0aW9uc1xuXHRcdCAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC0gQW4gb2JqZWN0IGxpdGVyYWwgb2Ygb3B0aW9ucyB0byBzZXRcblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqL1xuXHRcdF9zZXRPcHRpb25zOiBmdW5jdGlvbihvcHRpb25zKSB7XG5cdFx0XHQkLmVhY2gob3B0aW9ucywgJC5wcm94eShmdW5jdGlvbihrZXksIHZhbHVlKSB7XG5cdFx0XHRcdHN3aXRjaChrZXkpIHtcblx0XHRcdFx0XHRjYXNlICdkaXNhYmxlUGFuJzpcblx0XHRcdFx0XHRcdHRoaXMuX3Jlc2V0U3R5bGUoKTtcblx0XHRcdFx0XHRcdC8qIGZhbGxzIHRocm91Z2ggKi9cblx0XHRcdFx0XHRjYXNlICckem9vbUluJzpcblx0XHRcdFx0XHRjYXNlICckem9vbU91dCc6XG5cdFx0XHRcdFx0Y2FzZSAnJHpvb21SYW5nZSc6XG5cdFx0XHRcdFx0Y2FzZSAnJHJlc2V0Jzpcblx0XHRcdFx0XHRjYXNlICdkaXNhYmxlWm9vbSc6XG5cdFx0XHRcdFx0Y2FzZSAnb25TdGFydCc6XG5cdFx0XHRcdFx0Y2FzZSAnb25DaGFuZ2UnOlxuXHRcdFx0XHRcdGNhc2UgJ29uWm9vbSc6XG5cdFx0XHRcdFx0Y2FzZSAnb25QYW4nOlxuXHRcdFx0XHRcdGNhc2UgJ29uRW5kJzpcblx0XHRcdFx0XHRjYXNlICdvblJlc2V0Jzpcblx0XHRcdFx0XHRjYXNlICdldmVudE5hbWVzcGFjZSc6XG5cdFx0XHRcdFx0XHR0aGlzLl91bmJpbmQoKTtcblx0XHRcdFx0fVxuXHRcdFx0XHR0aGlzLm9wdGlvbnNbIGtleSBdID0gdmFsdWU7XG5cdFx0XHRcdHN3aXRjaChrZXkpIHtcblx0XHRcdFx0XHRjYXNlICdkaXNhYmxlUGFuJzpcblx0XHRcdFx0XHRcdHRoaXMuX2luaXRTdHlsZSgpO1xuXHRcdFx0XHRcdFx0LyogZmFsbHMgdGhyb3VnaCAqL1xuXHRcdFx0XHRcdGNhc2UgJyR6b29tSW4nOlxuXHRcdFx0XHRcdGNhc2UgJyR6b29tT3V0Jzpcblx0XHRcdFx0XHRjYXNlICckem9vbVJhbmdlJzpcblx0XHRcdFx0XHRjYXNlICckcmVzZXQnOlxuXHRcdFx0XHRcdFx0Ly8gU2V0IHRoZXNlIG9uIHRoZSBpbnN0YW5jZVxuXHRcdFx0XHRcdFx0dGhpc1sga2V5IF0gPSB2YWx1ZTtcblx0XHRcdFx0XHRcdC8qIGZhbGxzIHRocm91Z2ggKi9cblx0XHRcdFx0XHRjYXNlICdkaXNhYmxlWm9vbSc6XG5cdFx0XHRcdFx0Y2FzZSAnb25TdGFydCc6XG5cdFx0XHRcdFx0Y2FzZSAnb25DaGFuZ2UnOlxuXHRcdFx0XHRcdGNhc2UgJ29uWm9vbSc6XG5cdFx0XHRcdFx0Y2FzZSAnb25QYW4nOlxuXHRcdFx0XHRcdGNhc2UgJ29uRW5kJzpcblx0XHRcdFx0XHRjYXNlICdvblJlc2V0Jzpcblx0XHRcdFx0XHRjYXNlICdldmVudE5hbWVzcGFjZSc6XG5cdFx0XHRcdFx0XHR0aGlzLl9iaW5kKCk7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRjYXNlICdjdXJzb3InOlxuXHRcdFx0XHRcdFx0JC5zdHlsZSh0aGlzLmVsZW0sICdjdXJzb3InLCB2YWx1ZSk7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRjYXNlICdtaW5TY2FsZSc6XG5cdFx0XHRcdFx0XHR0aGlzLiR6b29tUmFuZ2UuYXR0cignbWluJywgdmFsdWUpO1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0Y2FzZSAnbWF4U2NhbGUnOlxuXHRcdFx0XHRcdFx0dGhpcy4kem9vbVJhbmdlLmF0dHIoJ21heCcsIHZhbHVlKTtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdGNhc2UgJ3JhbmdlU3RlcCc6XG5cdFx0XHRcdFx0XHR0aGlzLiR6b29tUmFuZ2UuYXR0cignc3RlcCcsIHZhbHVlKTtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdGNhc2UgJ3N0YXJ0VHJhbnNmb3JtJzpcblx0XHRcdFx0XHRcdHRoaXMuX2J1
7437aWxkVHJhbnNmb3JtKCk7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRjYXNlICdkdXJhdGlvbic6XG5cdFx0XHRcdFx0Y2FzZSAnZWFzaW5nJzpcblx0XHRcdFx0XHRcdHRoaXMuX2J1aWxkVHJhbnNpdGlvbigpO1xuXHRcdFx0XHRcdFx0LyogZmFsbHMgdGhyb3VnaCAqL1xuXHRcdFx0XHRcdGNhc2UgJ3RyYW5zaXRpb24nOlxuXHRcdFx0XHRcdFx0dGhpcy50cmFuc2l0aW9uKCk7XG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRjYXNlICdwYW5Pbmx5V2hlblpvb21lZCc6XG5cdFx0XHRcdFx0XHR0aGlzLl9jaGVja1BhbldoZW5ab29tZWQoKTtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdGNhc2UgJyRzZXQnOlxuXHRcdFx0XHRcdFx0aWYgKHZhbHVlIGluc3RhbmNlb2YgJCAmJiB2YWx1ZS5sZW5ndGgpIHtcblx0XHRcdFx0XHRcdFx0dGhpcy4kc2V0ID0gdmFsdWU7XG5cdFx0XHRcdFx0XHRcdC8vIFJlc2V0IHN0eWxlc1xuXHRcdFx0XHRcdFx0XHR0aGlzLl9pbml0U3R5bGUoKTtcblx0XHRcdFx0XHRcdFx0dGhpcy5fYnVpbGRUcmFuc2Zvcm0oKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fSwgdGhpcykpO1xuXHRcdH0sXG5cblx0XHQvKipcblx0XHQgKiBEaXNhYmxlL2VuYWJsZSBwYW5uaW5nIGRlcGVuZGluZyBvbiB3aGV0aGVyIHRoZSBjdXJyZW50IHNjYWxlXG5cdFx0ICogbWF0Y2hlcyB0aGUgbWluaW11bVxuXHRcdCAqIEBwYXJhbSB7TnVtYmVyfSBbc2NhbGVdXG5cdFx0ICogQHByaXZhdGVcblx0XHQgKi9cblx0XHRfY2hlY2tQYW5XaGVuWm9vbWVkOiBmdW5jdGlvbihzY2FsZSkge1xuXHRcdFx0dmFyIG9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XG5cdFx0XHRpZiAob3B0aW9ucy5wYW5Pbmx5V2hlblpvb21lZCkge1xuXHRcdFx0XHRpZiAoIXNjYWxlKSB7XG5cdFx0XHRcdFx0c2NhbGUgPSB0aGlzLmdldE1hdHJpeCgpWzBdO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHZhciB0b0Rpc2FibGUgPSBzY2FsZSA8PSBvcHRpb25zLm1pblNjYWxlO1xuXHRcdFx0XHRpZiAob3B0aW9ucy5kaXNhYmxlUGFuICE9PSB0b0Rpc2FibGUpIHtcblx0XHRcdFx0XHR0aGlzLm9wdGlvbignZGlzYWJsZVBhbicsIHRvRGlzYWJsZSk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9LFxuXG5cdFx0LyoqXG5cdFx0ICogSW5pdGlhbGl6ZSBiYXNlIHN0eWxlcyBmb3IgdGhlIGVsZW1lbnQgYW5kIGl0cyBwYXJlbnRcblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqL1xuXHRcdF9pbml0U3R5bGU6IGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIHN0eWxlcyA9IHtcblx0XHRcdFx0Ly8gU2V0IHRoZSBzYW1lIGRlZmF1bHQgd2hldGhlciBTVkcgb3IgSFRNTFxuXHRcdFx0XHQvLyB0cmFuc2Zvcm0tb3JpZ2luIGNhbm5vdCBiZSBjaGFuZ2VkIHRvIDUwJSA1MCUgaW4gSUU5LTExIG9yIEVkZ2UgMTMtMTQrXG5cdFx0XHRcdCd0cmFuc2Zvcm0tb3JpZ2luJzogdGhpcy5pc1NWRyA/ICcwIDAnIDogJzUwJSA1MCUnXG5cdFx0XHR9O1xuXHRcdFx0Ly8gU2V0IGVsZW0gc3R5bGVzXG5cdFx0XHRpZiAoIXRoaXMub3B0aW9ucy5kaXNhYmxlUGFuKSB7XG5cdFx0XHRcdHN0eWxlcy5jdXJzb3IgPSB0aGlzLm9wdGlvbnMuY3Vyc29yO1xuXHRcdFx0fVxuXHRcdFx0dGhpcy4kc2V0LmNzcyhzdHlsZXMpO1xuXG5cdFx0XHQvLyBTZXQgcGFyZW50IHRvIHJlbGF0aXZlIGlmIHNldCB0byBzdGF0aWNcblx0XHRcdHZhciAkcGFyZW50ID0gdGhpcy4kcGFyZW50O1xuXHRcdFx0Ly8gTm8gbmVlZCB0byBhZGQgc3R5bGVzIHRvIHRoZSBib2R5XG5cdFx0XHRpZiAoJHBhcmVudC5sZW5ndGggJiYgISQubm9kZU5hbWUodGhpcy5wYXJlbnQsICdib2R5JykpIHtcblx0XHRcdFx0c3R5bGVzID0ge1xuXHRcdFx0XHRcdG92ZXJmbG93OiAnaGlkZGVuJ1xuXHRcdFx0XHR9O1xuXHRcdFx0XHRpZiAoJHBhcmVudC5jc3MoJ3Bvc2l0aW9uJykgPT09ICdzdGF0aWMnKSB7XG5cdFx0XHRcdFx0c3R5bGVzLnBvc2l0aW9uID0gJ3JlbGF0aXZlJztcblx0XHRcdFx0fVxuXHRcdFx0XHQkcGFyZW50LmNzcyhzdHlsZXMpO1xuXHRcdFx0fVxuXHRcdH0sXG5cblx0XHQvKipcblx0XHQgKiBVbmRvIGFueSBzdHlsZXMgYXR0YWNoZWQgaW4gdGhpcyBwbHVnaW5cblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqL1xuXHRcdF9yZXNldFN0eWxlOiBmdW5jdGlvbigpIHtcblx0XHRcdHRoaXMuJGVsZW0uY3NzKHtcblx0XHRcdFx0J2N1cnNvcic6ICcnLFxuXHRcdFx0XHQndHJhbnNpdGlvbic6ICcnXG5cdFx0XHR9KTtcblx0XHRcdHRoaXMuJHBhcmVudC5jc3Moe1xuXHRcdFx0XHQnb3ZlcmZsb3cnOiAnJyxcblx0XHRcdFx0J3Bvc2l0aW9uJzogJydcblx0XHRcdH0pO1xuXHRcdH0sXG5cblx0XHQvKipcblx0XHQgKiBCaW5kcyBhbGwgbmVjZXNzYXJ5IGV2ZW50c1xuXHRcdCAqIEBwcml2YXRlXG5cdFx0ICovXG5cdFx0X2JpbmQ6IGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIHNlbGYgPSB0aGlzO1xuXHRcdFx0dmFyIG9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XG5cdFx0XHR2YXIgbnMgPSBvcHRpb25zLmV2ZW50TmFtZXNwYWNlO1xuXHRcdFx0dmFyIHN0cl9kb3duID0gJ21vdXNlZG93bicgKyBucyArICcgcG9pbnRlcmRvd24nICsgbnMgKyAnIE1TUG9pbnRlckRvd24nICsgbnM7XG5cdFx0XHR2YXIgc3RyX3N0YXJ0ID0gJ3RvdWNoc3RhcnQnICsgbnMgKyAnICcgKyBzdHJfZG93bjtcblx0XHRcdHZhciBzdHJfY2xpY2sgPSAndG91Y2hlbmQnICsgbnMgKyAnIGNsaWNrJyArIG5zICsgJyBwb2ludGVydXAnICsgbnMgKyAnIE1TUG9pbnRlclVwJyArIG5zO1xuXHRcdFx0dmFyIGV2ZW50cyA9IHt9O1xuXHRcdFx0dmFyICRyZXNldCA9IHRoaXMuJHJlc2V0O1xuXHRcdFx0dmFyICR6b29tUmFuZ2UgPSB0aGlzLiR6b29tUmFuZ2U7XG5cblx0XHRcdC8vIEJpbmQgcGFuem9vbSBldmVudHMgZnJvbSBvcHRpb25zXG5cdFx0XHQkLmVhY2goWyAnU3RhcnQnLCAnQ2hhbmdlJywgJ1pvb20nLCAnUGFuJywgJ0VuZCcsICdSZXNldCcgXSwgZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHZhciBtID0gb3B0aW9uc1sgJ29uJyArIHRoaXMgXTtcblx0XHRcdFx0aWYgKCQuaXNGdW5jdGlvbihtKSkge1xuXHRcdFx0XHRcdGV2ZW50c1sgJ3Bhbnpvb20nICsgdGh
7437pcy50b0xvd2VyQ2FzZSgpICsgbnMgXSA9IG07XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXG5cdFx0XHQvLyBCaW5kICRlbGVtIGRyYWcgYW5kIGNsaWNrL3RvdWNoZG93biBldmVudHNcblx0XHRcdC8vIEJpbmQgdG91Y2hzdGFydCBpZiBlaXRoZXIgcGFubmluZyBvciB6b29taW5nIGlzIGVuYWJsZWRcblx0XHRcdGlmICghb3B0aW9ucy5kaXNhYmxlUGFuIHx8ICFvcHRpb25zLmRpc2FibGVab29tKSB7XG5cdFx0XHRcdGV2ZW50c1sgc3RyX3N0YXJ0IF0gPSBmdW5jdGlvbihlKSB7XG5cdFx0XHRcdFx0dmFyIHRvdWNoZXM7XG5cdFx0XHRcdFx0aWYgKGUudHlwZSA9PT0gJ3RvdWNoc3RhcnQnID9cblx0XHRcdFx0XHRcdC8vIFRvdWNoXG5cdFx0XHRcdFx0XHQodG91Y2hlcyA9IGUudG91Y2hlcyB8fCBlLm9yaWdpbmFsRXZlbnQudG91Y2hlcykgJiZcblx0XHRcdFx0XHRcdFx0KCh0b3VjaGVzLmxlbmd0aCA9PT0gMSAmJiAhb3B0aW9ucy5kaXNhYmxlUGFuKSB8fCB0b3VjaGVzLmxlbmd0aCA9PT0gMikgOlxuXHRcdFx0XHRcdFx0Ly8gTW91c2UvUG9pbnRlcjogSWdub3JlIHVuZXhwZWN0ZWQgY2xpY2sgdHlwZXNcblx0XHRcdFx0XHRcdC8vIFN1cHBvcnQ6IElFMTAgb25seVxuXHRcdFx0XHRcdFx0Ly8gSUUxMCBkb2VzIG5vdCBzdXBwb3J0IGUuYnV0dG9uIGZvciBNU1BvaW50ZXJEb3duLCBidXQgZG9lcyBoYXZlIGUud2hpY2hcblx0XHRcdFx0XHRcdCFvcHRpb25zLmRpc2FibGVQYW4gJiYgKGUud2hpY2ggfHwgZS5vcmlnaW5hbEV2ZW50LndoaWNoKSA9PT0gb3B0aW9ucy53aGljaCkge1xuXG5cdFx0XHRcdFx0XHRlLnByZXZlbnREZWZhdWx0KCk7XG5cdFx0XHRcdFx0XHRlLnN0b3BQcm9wYWdhdGlvbigpO1xuXHRcdFx0XHRcdFx0c2VsZi5fc3RhcnRNb3ZlKGUsIHRvdWNoZXMpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fTtcblx0XHRcdFx0Ly8gUHJldmVudCB0aGUgY29udGV4dG1lbnUgZXZlbnRcblx0XHRcdFx0Ly8gaWYgd2UncmUgYmluZGluZyB0byByaWdodC1jbGlja1xuXHRcdFx0XHRpZiAob3B0aW9ucy53aGljaCA9PT0gMykge1xuXHRcdFx0XHRcdGV2ZW50cy5jb250ZXh0bWVudSA9IGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHR0aGlzLiRlbGVtLm9uKGV2ZW50cyk7XG5cblx0XHRcdC8vIEJpbmQgcmVzZXRcblx0XHRcdGlmICgkcmVzZXQubGVuZ3RoKSB7XG5cdFx0XHRcdCRyZXNldC5vbihzdHJfY2xpY2ssIGZ1bmN0aW9uKGUpIHtcblx0XHRcdFx0XHRlLnByZXZlbnREZWZhdWx0KCk7XG5cdFx0XHRcdFx0c2VsZi5yZXNldCgpO1xuXHRcdFx0XHR9KTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gU2V0IGRlZmF1bHQgYXR0cmlidXRlcyBmb3IgdGhlIHJhbmdlIGlucHV0XG5cdFx0XHRpZiAoJHpvb21SYW5nZS5sZW5ndGgpIHtcblx0XHRcdFx0JHpvb21SYW5nZS5hdHRyKHtcblx0XHRcdFx0XHQvLyBPbmx5IHNldCB0aGUgcmFuZ2Ugc3RlcCBpZiBleHBsaWNpdCBvclxuXHRcdFx0XHRcdC8vIHNldCB0aGUgZGVmYXVsdCBpZiB0aGVyZSBpcyBubyBhdHRyaWJ1dGUgcHJlc2VudFxuXHRcdFx0XHRcdHN0ZXA6IG9wdGlvbnMucmFuZ2VTdGVwID09PSBQYW56b29tLmRlZmF1bHRzLnJhbmdlU3RlcCAmJlxuXHRcdFx0XHRcdFx0JHpvb21SYW5nZS5hdHRyKCdzdGVwJykgfHxcblx0XHRcdFx0XHRcdG9wdGlvbnMucmFuZ2VTdGVwLFxuXHRcdFx0XHRcdG1pbjogb3B0aW9ucy5taW5TY2FsZSxcblx0XHRcdFx0XHRtYXg6IG9wdGlvbnMubWF4U2NhbGVcblx0XHRcdFx0fSkucHJvcCh7XG5cdFx0XHRcdFx0dmFsdWU6IHRoaXMuZ2V0TWF0cml4KClbMF1cblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIE5vIGJpbmRpbmdzIGlmIHpvb21pbmcgaXMgZGlzYWJsZWRcblx0XHRcdGlmIChvcHRpb25zLmRpc2FibGVab29tKSB7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblxuXHRcdFx0dmFyICR6b29tSW4gPSB0aGlzLiR6b29tSW47XG5cdFx0XHR2YXIgJHpvb21PdXQgPSB0aGlzLiR6b29tT3V0O1xuXG5cdFx0XHQvLyBCaW5kIHpvb20gaW4vb3V0XG5cdFx0XHQvLyBEb24ndCBiaW5kIG9uZSB3aXRob3V0IHRoZSBvdGhlclxuXHRcdFx0aWYgKCR6b29tSW4ubGVuZ3RoICYmICR6b29tT3V0Lmxlbmd0aCkge1xuXHRcdFx0XHQvLyBwcmV2ZW50RGVmYXVsdCBjYW5jZWxzIGZ1dHVyZSBtb3VzZSBldmVudHMgb24gdG91Y2ggZXZlbnRzXG5cdFx0XHRcdCR6b29tSW4ub24oc3RyX2NsaWNrLCBmdW5jdGlvbihlKSB7XG5cdFx0XHRcdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0XHRcdHNlbGYuem9vbSgpO1xuXHRcdFx0XHR9KTtcblx0XHRcdFx0JHpvb21PdXQub24oc3RyX2NsaWNrLCBmdW5jdGlvbihlKSB7XG5cdFx0XHRcdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0XHRcdHNlbGYuem9vbSh0cnVlKTtcblx0XHRcdFx0fSk7XG5cdFx0XHR9XG5cblx0XHRcdGlmICgkem9vbVJhbmdlLmxlbmd0aCkge1xuXHRcdFx0XHRldmVudHMgPSB7fTtcblx0XHRcdFx0Ly8gQ2Fubm90IHByZXZlbnQgZGVmYXVsdCBhY3Rpb24gaGVyZVxuXHRcdFx0XHRldmVudHNbIHN0cl9kb3duIF0gPSBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRzZWxmLnRyYW5zaXRpb24odHJ1ZSk7XG5cdFx0XHRcdH07XG5cdFx0XHRcdC8vIFpvb20gb24gaW5wdXQgZXZlbnRzIGlmIGF2YWlsYWJsZSBhbmQgY2hhbmdlIGV2ZW50c1xuXHRcdFx0XHQvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL3RpbW15d2lsL2pxdWVyeS5wYW56b29tL2lzc3Vlcy85MFxuXHRcdFx0XHRldmVudHNbIChzdXBwb3J0c0lucHV0RXZlbnQgPyAnaW5wdXQnIDogJ2NoYW5nZScpICsgbnMgXSA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdHNlbGYuem9vbSgrdGhpcy52YWx1ZSwgeyBub1NldFJhbmdlOiB0cnVlIH0pO1xuXHRcdFx0XHR9O1xuXHRcdFx0XHQkem9vbVJhbmdlLm9uKGV2ZW50cyk7XG5cdFx0XHR9XG5cdFx0fSxcblxuXHRcdC8qKlxuXHRcdCAqIFVuYmluZCBhbGwgZXZlbnRzXG5cdFx0ICogQHByaXZhdGVcblx0XHQgKi9cblx0XHRfdW5iaW5kOiBmdW5jdGlvbigpIHtcblx0XHRcdHRoaXMuJGVsZW1cblx0XHRcdFx0LmFkZCh0aGlzLiR6b29tSW4pXG5cdFx0XHRcdC5hZGQodGhpcy4kem9vbU91dClcblx0XHRcdFx0LmFkZCh0aGlzLiRyZXNldClcblx0XHRcdFx0Lm9mZih0aGlzLm9wdGlvbnMuZXZlbnROYW1lc3BhY2UpO1xuXHRcdH0sXG5cblx0XHQvKipcblx0XHQgKiBCdWlsZHMgdGhlIG9yaWdpbmFsIHRyYW5zZm9ybSB2YWx1ZVxuXHRcdCAqIEBwcml2YXRlXG5cdFx0ICovXG5cdFx0X2J1aWxkVHJhbnNmb3JtOiBmdW5jdGlvbigpIHtcblx0XHRcdC8vIFNhdmUgdGhlIG9yaWdpbmFsIHRyYW5zZm9ybVxuXHRcdFx0Ly8gUmV0cmlldmluZyB0aGlzIGFsc28gYWRkcyB0aGUgY29ycmVjdCBwcmVmaXhlZCBzdHlsZSBuYW1lXG5cdFx0XHQvLyB0byBqUXVlcnkncyBpbnRlcm5hbCAkLmNzc1Byb3BzXG5cdFx0XHRyZXR1cm4gdGhpcy5fb3JpZ1RyYW5zZm9ybSA9IHRoaXMuZ2V0VHJhbnNmb3JtKHRoaXMub3B0aW9ucy5zdGFydFRyYW5zZm9ybSk7XG5cdFx0fSxcblxuXHRcdC8qKlxuXHRcdCAqIFNldCB0cmFuc2l0aW9uIHByb3BlcnR5IGZvciBsYXRlciB1c2Ugd2hlbiB6b29taW5nXG5cdFx0ICogQHByaXZhdGVcblx0XHQgKi9cblx0XHRfYnVpbGRUcmFuc2l0aW9uOiBmdW5jdGlvbigpIHtcblx0XHRcdGlmICh0aGlzLl90cmFuc2Zvcm0pIHtcblx0XHRcdFx0dmFyIG9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XG5cdFx0XHRcdHRoaXMuX3RyYW5zaXRpb24gPSB0aGlzLl90cmFuc2Zvcm0gKyAnICcgKyBvcHRpb25zLmR1cmF0aW9uICsgJ21zICcgKyBvcHRpb25zLmVhc2luZztcblx0XHRcdH1cblx0XHR9LFxuXG5cdFx0LyoqXG5cdFx0ICogQ2FsY3VsYXRlcyB0aGUgZGlzdGFuY2UgYmV0d2VlbiB0d28gdG91Y2ggcG9pbnRzXG5cdFx0ICogUmVtZW1iZXIgcHl0aGFnb3JlYW4/XG5cdFx0ICogQHBhcmFtIHtBcnJheX0gdG91Y2hlc1xuXHRcdCAqIEByZXR1cm5zIHtOdW1iZXJ9IFJldHVybnMgdGhlIGRpc3RhbmNlXG5cdFx0ICogQHByaXZhdGVcblx0XHQgKi9cblx0XHRfZ2V0RGlzdGFuY2U6IGZ1bmN0aW9uKHRvdWNoZXMpIHtcblx0XHRcdHZhciB0b3VjaDEgPSB0b3VjaGVzWzBdO1xuXHRcdFx0dmFyIHRvdWNoMiA9IHRvdWNoZXNbMV07XG5cdFx0XHRyZXR1cm4gTWF0aC5zcXJ0KE1hdGgucG93KE1hdGguYWJzKHRvdWNoMi5jbGllbnRYIC0gdG91Y2gxLmNsaWVudFgpLCAyKSArIE1hdGgucG93KE1hdGguYWJzKHRvdWNoMi5jbGllbnRZIC0gdG91Y2gxLmNsaWVudFkpLCAyKSk7XG5cdFx0fSxcblxuXHRcdC8qKlxuXHRcdCAqIENvbnN0cnVjdH
7437MgYW4gYXBwcm94aW1hdGVkIHBvaW50IGluIHRoZSBtaWRkbGUgb2YgdHdvIHRvdWNoIHBvaW50c1xuXHRcdCAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYW4gb2JqZWN0IGNvbnRhaW5pbmcgcGFnZVggYW5kIHBhZ2VZXG5cdFx0ICogQHByaXZhdGVcblx0XHQgKi9cblx0XHRfZ2V0TWlkZGxlOiBmdW5jdGlvbih0b3VjaGVzKSB7XG5cdFx0XHR2YXIgdG91Y2gxID0gdG91Y2hlc1swXTtcblx0XHRcdHZhciB0b3VjaDIgPSB0b3VjaGVzWzFdO1xuXHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0Y2xpZW50WDogKCh0b3VjaDIuY2xpZW50WCAtIHRvdWNoMS5jbGllbnRYKSAvIDIpICsgdG91Y2gxLmNsaWVudFgsXG5cdFx0XHRcdGNsaWVudFk6ICgodG91Y2gyLmNsaWVudFkgLSB0b3VjaDEuY2xpZW50WSkgLyAyKSArIHRvdWNoMS5jbGllbnRZXG5cdFx0XHR9O1xuXHRcdH0sXG5cblx0XHQvKipcblx0XHQgKiBUcmlnZ2VyIGEgcGFuem9vbSBldmVudCBvbiBvdXIgZWxlbWVudFxuXHRcdCAqIFRoZSBldmVudCBpcyBwYXNzZWQgdGhlIFBhbnpvb20gaW5zdGFuY2Vcblx0XHQgKiBAcGFyYW0ge1N0cmluZ3xqUXVlcnkuRXZlbnR9IGV2ZW50XG5cdFx0ICogQHBhcmFtIHtNaXhlZH0gYXJnMVssIGFyZzIsIGFyZzMsIC4uLl0gQXJndW1lbnRzIHRvIGFwcGVuZCB0byB0aGUgdHJpZ2dlclxuXHRcdCAqIEBwcml2YXRlXG5cdFx0ICovXG5cdFx0X3RyaWdnZXI6IGZ1bmN0aW9uIChldmVudCkge1xuXHRcdFx0aWYgKHR5cGVvZiBldmVudCA9PT0gJ3N0cmluZycpIHtcblx0XHRcdFx0ZXZlbnQgPSAncGFuem9vbScgKyBldmVudDtcblx0XHRcdH1cblx0XHRcdHRoaXMuJGVsZW0udHJpZ2dlckhhbmRsZXIoZXZlbnQsIFt0aGlzXS5jb25jYXQoc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpKSk7XG5cdFx0fSxcblxuXHRcdC8qKlxuXHRcdCAqIFN0YXJ0cyB0aGUgcGFuXG5cdFx0ICogVGhpcyBpcyBib3VuZCB0byBtb3VzZS90b3VjaG1vdmUgb24gdGhlIGVsZW1lbnRcblx0XHQgKiBAcGFyYW0ge2pRdWVyeS5FdmVudH0gZXZlbnQgQW4gZXZlbnQgd2l0aCBwYWdlWCwgcGFnZVksIGFuZCBwb3NzaWJseSB0aGUgdG91Y2hlcyBsaXN0XG5cdFx0ICogQHBhcmFtIHtUb3VjaExpc3R9IFt0b3VjaGVzXSBUaGUgdG91Y2hlcyBsaXN0IGlmIHByZXNlbnRcblx0XHQgKiBAcHJpdmF0ZVxuXHRcdCAqL1xuXHRcdF9zdGFydE1vdmU6IGZ1bmN0aW9uKGV2ZW50LCB0b3VjaGVzKSB7XG5cdFx0XHRpZiAodGhpcy5wYW5uaW5nKSB7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblx0XHRcdHZhciBtb3ZlRXZlbnQsIGVuZEV2ZW50LFxuXHRcdFx0XHRzdGFydERpc3RhbmNlLCBzdGFydFNjYWxlLCBzdGFydE1pZGRsZSxcblx0XHRcdFx0c3RhcnRQYWdlWCwgc3RhcnRQYWdlWSwgdG91Y2g7XG5cdFx0XHR2YXIgc2VsZiA9IHRoaXM7XG5cdFx0XHR2YXIgb3B0aW9ucyA9IHRoaXMub3B0aW9ucztcblx0XHRcdHZhciBucyA9IG9wdGlvbnMuZXZlbnROYW1lc3BhY2U7XG5cdFx0XHR2YXIgbWF0cml4ID0gdGhpcy5nZXRNYXRyaXgoKTtcblx0XHRcdHZhciBvcmlnaW5hbCA9IG1hdHJpeC5zbGljZSgwKTtcblx0XHRcdHZhciBvcmlnUGFnZVggPSArb3JpZ2luYWxbNF07XG5cdFx0XHR2YXIgb3JpZ1BhZ2VZID0gK29yaWdpbmFsWzVdO1xuXHRcdFx0dmFyIHBhbk9wdGlvbnMgPSB7IG1hdHJpeDogbWF0cml4LCBhbmltYXRlOiAnc2tpcCcgfTtcblx0XHRcdHZhciB0eXBlID0gZXZlbnQudHlwZTtcblxuXHRcdFx0Ly8gVXNlIHByb3BlciBldmVudHNcblx0XHRcdGlmICh0eXBlID09PSAncG9pbnRlcmRvd24nKSB7XG5cdFx0XHRcdG1vdmVFdmVudCA9ICdwb2ludGVybW92ZSc7XG5cdFx0XHRcdGVuZEV2ZW50ID0gJ3BvaW50ZXJ1cCc7XG5cdFx0XHR9IGVsc2UgaWYgKHR5cGUgPT09ICd0b3VjaHN0YXJ0Jykge1xuXHRcdFx0XHRtb3ZlRXZlbnQgPSAndG91Y2htb3ZlJztcblx0XHRcdFx0ZW5kRXZlbnQgPSAndG91Y2hlbmQnO1xuXHRcdFx0fSBlbHNlIGlmICh0eXBlID09PSAnTVNQb2ludGVyRG93bicpIHtcblx0XHRcdFx0bW92ZUV2ZW50ID0gJ01TUG9pbnRlck1vdmUnO1xuXHRcdFx0XHRlbmRFdmVudCA9ICdNU1BvaW50ZXJVcCc7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRtb3ZlRXZlbnQgPSAnbW91c2Vtb3ZlJztcblx0XHRcdFx0ZW5kRXZlbnQgPSAnbW91c2V1cCc7XG5cdFx0XHR9XG5cblx0XHRcdC8vIEFkZCBuYW1lc3BhY2Vcblx0XHRcdG1vdmVFdmVudCArPSBucztcblx0XHRcdGVuZEV2ZW50ICs9IG5zO1xuXG5cdFx0XHQvLyBSZW1vdmUgYW55IHRyYW5zaXRpb25zIGhhcHBlbmluZ1xuXHRcdFx0dGhpcy50cmFuc2l0aW9uKHRydWUpO1xuXG5cdFx0XHQvLyBJbmRpY2F0ZSB0aGF0IHdlIGFyZSBjdXJyZW50bHkgcGFubmluZ1xuXHRcdFx0dGhpcy5wYW5uaW5nID0gdHJ1ZTtcblxuXHRcdFx0Ly8gVHJpZ2dlciBzdGFydCBldmVudFxuXHRcdFx0dGhpcy5fdHJpZ2dlcignc3RhcnQnLCBldmVudCwgdG91Y2hlcyk7XG5cblx0XHRcdHZhciBzZXRTdGFydCA9IGZ1bmN0aW9uKGV2ZW50LCB0b3VjaGVzKSB7XG5cdFx0XHRcdGlmICh0b3VjaGVzKSB7XG5cdFx0XHRcdFx0aWYgKHRvdWNoZXMubGVuZ3RoID09PSAyKSB7XG5cdFx0XHRcdFx0XHRpZiAoc3RhcnREaXN0YW5jZSAhPSBudWxsKSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdHN0YXJ0RGlzdGFuY2UgPSBzZWxmLl9nZXREaXN0YW5jZSh0b3VjaGVzKTtcblx0XHRcdFx0XHRcdHN0YXJ0U2NhbGUgPSArbWF0cml4WzBdO1xuXHRcdFx0XHRcdFx0c3RhcnRNaWRkbGUgPSBzZWxmLl9nZXRNaWRkbGUodG91Y2hlcyk7XG5cdFx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGlmIChzdGFydFBhZ2VYICE9IG51bGwpIHtcblx0XHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0aWYgKCh0b3VjaCA9IHRvdWNoZXNbMF0pKSB7XG5cdFx0XHRcdFx0XHRzdGFydFBhZ2VYID0gdG91Y2gucGFnZVg7XG5cdFx0XHRcdFx0XHRzdGFydFBhZ2VZID0gdG91Y2gucGFnZVk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHRcdGlmIChzdGFydFBhZ2VYICE9IG51bGwpIHtcblx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdH1cblx0XHRcdFx0c3RhcnRQYWdlWCA9IGV2ZW50LnBhZ2VYO1xuXHRcdFx0XHRzdGFydFBhZ2VZID0gZXZlbnQucGFnZVk7XG5cdFx0XHR9O1xuXG5cdFx0XHRzZXRTdGFydChldmVudCwgdG91Y2hlcyk7XG5cblx0XHRcdHZhciBtb3ZlID0gZnVuY3Rpb24oZSkge1xuXHRcdFx0XHR2YXIgY29vcmRzO1xuXHRcdFx0XHRlLnByZXZlbn
7437REZWZhdWx0KCk7XG5cdFx0XHRcdHRvdWNoZXMgPSBlLnRvdWNoZXMgfHwgZS5vcmlnaW5hbEV2ZW50LnRvdWNoZXM7XG5cdFx0XHRcdHNldFN0YXJ0KGUsIHRvdWNoZXMpO1xuXG5cdFx0XHRcdGlmICh0b3VjaGVzKSB7XG5cdFx0XHRcdFx0aWYgKHRvdWNoZXMubGVuZ3RoID09PSAyKSB7XG5cblx0XHRcdFx0XHRcdC8vIENhbGN1bGF0ZSBtb3ZlIG9uIG1pZGRsZSBwb2ludFxuXHRcdFx0XHRcdFx0dmFyIG1pZGRsZSA9IHNlbGYuX2dldE1pZGRsZSh0b3VjaGVzKTtcblx0XHRcdFx0XHRcdHZhciBkaWZmID0gc2VsZi5fZ2V0RGlzdGFuY2UodG91Y2hlcykgLSBzdGFydERpc3RhbmNlO1xuXG5cdFx0XHRcdFx0XHQvLyBTZXQgem9vbVxuXHRcdFx0XHRcdFx0c2VsZi56b29tKGRpZmYgKiAob3B0aW9ucy5pbmNyZW1lbnQgLyAxMDApICsgc3RhcnRTY2FsZSwge1xuXHRcdFx0XHRcdFx0XHRmb2NhbDogbWlkZGxlLFxuXHRcdFx0XHRcdFx0XHRtYXRyaXg6IG1hdHJpeCxcblx0XHRcdFx0XHRcdFx0YW5pbWF0ZTogJ3NraXAnXG5cdFx0XHRcdFx0XHR9KTtcblxuXHRcdFx0XHRcdFx0Ly8gU2V0IHBhblxuXHRcdFx0XHRcdFx0c2VsZi5wYW4oXG5cdFx0XHRcdFx0XHRcdCttYXRyaXhbNF0gKyBtaWRkbGUuY2xpZW50WCAtIHN0YXJ0TWlkZGxlLmNsaWVudFgsXG5cdFx0XHRcdFx0XHRcdCttYXRyaXhbNV0gKyBtaWRkbGUuY2xpZW50WSAtIHN0YXJ0TWlkZGxlLmNsaWVudFksXG5cdFx0XHRcdFx0XHRcdHBhbk9wdGlvbnNcblx0XHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0XHRzdGFydE1pZGRsZSA9IG1pZGRsZTtcblx0XHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0Y29vcmRzID0gdG91Y2hlc1swXSB8fCB7IHBhZ2VYOiAwLCBwYWdlWTogMCB9O1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0aWYgKCFjb29yZHMpIHtcblx0XHRcdFx0XHRjb29yZHMgPSBlO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0c2VsZi5wYW4oXG5cdFx0XHRcdFx0b3JpZ1BhZ2VYICsgY29vcmRzLnBhZ2VYIC0gc3RhcnRQYWdlWCxcblx0XHRcdFx0XHRvcmlnUGFnZVkgKyBjb29yZHMucGFnZVkgLSBzdGFydFBhZ2VZLFxuXHRcdFx0XHRcdHBhbk9wdGlvbnNcblx0XHRcdFx0KTtcblx0XHRcdH07XG5cblx0XHRcdC8vIEJpbmQgdGhlIGhhbmRsZXJzXG5cdFx0XHQkKGRvY3VtZW50KVxuXHRcdFx0XHQub2ZmKG5zKVxuXHRcdFx0XHQub24obW92ZUV2ZW50LCBtb3ZlKVxuXHRcdFx0XHQub24oZW5kRXZlbnQsIGZ1bmN0aW9uKGUpIHtcblx0XHRcdFx0XHRlLnByZXZlbnREZWZhdWx0KCk7XG5cdFx0XHRcdFx0Ly8gVW5iaW5kIGFsbCBkb2N1bWVudCBldmVudHNcblx0XHRcdFx0XHQkKHRoaXMpLm9mZihucyk7XG5cdFx0XHRcdFx0c2VsZi5wYW5uaW5nID0gZmFsc2U7XG5cdFx0XHRcdFx0Ly8gVHJpZ2dlciBvdXIgZW5kIGV2ZW50XG5cdFx0XHRcdFx0Ly8gU2ltcGx5IHNldCB0aGUgdHlwZSB0byBcInBhbnpvb21lbmRcIiB0byBwYXNzIHRocm91Z2ggYWxsIGVuZCBwcm9wZXJ0aWVzXG5cdFx0XHRcdFx0Ly8galF1ZXJ5J3MgYG5vdGAgaXMgdXNlZCBoZXJlIHRvIGNvbXBhcmUgQXJyYXkgZXF1YWxpdHlcblx0XHRcdFx0XHRlLnR5cGUgPSAncGFuem9vbWVuZCc7XG5cdFx0XHRcdFx0c2VsZi5fdHJpZ2dlcihlLCBtYXRyaXgsICFtYXRyaXhFcXVhbHMobWF0cml4LCBvcmlnaW5hbCkpO1xuXHRcdFx0XHR9KTtcblx0XHR9XG5cdH07XG5cblx0Ly8gQWRkIFBhbnpvb20gYXMgYSBzdGF0aWMgcHJvcGVydHlcblx0JC5QYW56b29tID0gUGFuem9vbTtcblxuXHQvKipcblx0ICogRXh0ZW5kIGpRdWVyeVxuXHQgKiBAcGFyYW0ge09iamVjdHxTdHJpbmd9IG9wdGlvbnMgLSBUaGUgbmFtZSBvZiBhIG1ldGhvZCB0byBjYWxsIG9uIHRoZSBwcm90b3R5cGVcblx0ICogIG9yIGFuIG9iamVjdCBsaXRlcmFsIG9mIG9wdGlvbnNcblx0ICogQHJldHVybnMge2pRdWVyeXxNaXhlZH0galF1ZXJ5IGluc3RhbmNlIGZvciByZWd1bGFyIGNoYWluaW5nIG9yIHRoZSByZXR1cm4gdmFsdWUocykgb2YgYSBwYW56b29tIG1ldGhvZCBjYWxsXG5cdCAqL1xuXHQkLmZuLnBhbnpvb20gPSBmdW5jdGlvbihvcHRpb25zKSB7XG5cdFx0dmFyIGluc3RhbmNlLCBhcmdzLCBtLCByZXQ7XG5cblx0XHQvLyBDYWxsIG1ldGhvZHMgd2lkZ2V0LXN0eWxlXG5cdFx0aWYgKHR5cGVvZiBvcHRpb25zID09PSAnc3RyaW5nJykge1xuXHRcdFx0cmV0ID0gW107XG5cdFx0XHRhcmdzID0gc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xuXHRcdFx0dGhpcy5lYWNoKGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRpbnN0YW5jZSA9ICQuZGF0YSh0aGlzLCBkYXRha2V5KTtcblxuXHRcdFx0XHRpZiAoIWluc3RhbmNlKSB7XG5cdFx0XHRcdFx0cmV0LnB1c2godW5kZWZpbmVkKTtcblxuXHRcdFx0XHQvLyBJZ25vcmUgbWV0aG9kcyBiZWdpbm5pbmcgd2l0aCBgX2Bcblx0XHRcdFx0fSBlbHNlIGlmIChvcHRpb25zLmNoYXJBdCgwKSAhPT0gJ18nICYmXG5cdFx0XHRcdFx0dHlwZW9mIChtID0gaW5zdGFuY2VbIG9wdGlvbnMgXSkgPT09ICdmdW5jdGlvbicgJiZcblx0XHRcdFx0XHQvLyBJZiBub3RoaW5nIGlzIHJldHVybmVkLCBkbyBub3QgYWRkIHRvIHJldHVybiB2YWx1ZXNcblx0XHRcdFx0XHQobSA9IG0uYXBwbHkoaW5zdGFuY2UsIGFyZ3MpKSAhPT0gdW5kZWZpbmVkKSB7XG5cblx0XHRcdFx0XHRyZXQucHVzaChtKTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cblx0XHRcdC8vIFJldHVybiBhbiBhcnJheSBvZiB2YWx1ZXMgZm9yIHRoZSBqUXVlcnkgaW5zdGFuY2VzXG5cdFx0XHQvLyBPciB0aGUgdmFsdWUgaXRzZWxmIGlmIHRoZXJlIGlzIG9ubHkgb25lXG5cdFx0XHQvLyBPciBrZWVwIGNoYWluaW5nXG5cdFx0XHRyZXR1cm4gcmV0Lmxlbmd0aCA/XG5cdFx0XHRcdChyZXQubGVuZ3RoID09PSAxID8gcmV0WzBdIDogcmV0KSA6XG5cdFx0XHRcdHRoaXM7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpIHsgbmV3IFBhbnpvb20odGhpcywgb3B0aW9ucyk7IH0pO1xuXHR9O1xuXG5cdHJldHVybiBQYW56b29tO1xufSkpOyIsIi8qXG4gICAgIF8gXyAgICAgIF8gICAgICAgX1xuIF9fX3wgKF8pIF9fX3wgfCBfXyAgKF8pX19fXG4vIF9ffCB8IHwvIF9ffCB8LyAvICB8IC8gX198XG5cXF9fIFxcIHwgfCAoX198ICAgPCBfIHwgXFxfXyBcXFxufF9fXy9ffF98XFxfX198X3xcXF8oXykvIHxfX18vXG4gICAgICAgICAgICAgICAgICAgfF9fL1xuXG4gVmVyc2lvbjogMS42LjBcbiAgQXV0aG9yOiBLZW4gV2hlZWxlclxuIFdlYnNpdGU6IGh0dHA6Ly9rZW53aGVlbGVyLmdpdGh1Yi5pb1xuICAgIERvY3M6IGh0dHA6Ly9rZW53aGVlbGVyLmdpdGh1Yi5pby9zbGlja1xuICAgIFJlcG86IGh0dHA6Ly9naXRodWIuY29tL2tlbndoZWVsZXIvc2xpY2tcbiAgSXNzdWVzOiBodHRwOi8vZ2l0aHViLmNvbS9rZW53aGVlbGVyL3NsaWNrL2lzc3Vlc1xuXG4gKi9cbiFmdW5jdGlvbihhKXtcInVzZSBzdHJpY3RcIjtcImZ1bmN0aW9uXCI9PXR5cGVvZiBkZWZpbmUmJmRlZmluZS5hbWQ/ZGVmaW5lKFtcImpxdWVyeVwiXSxhKTpcInVuZGVmaW5lZFwiIT10eXBlb2YgZXhwb3J0cz9tb2R1bGUuZXhwb3J0cz1hKHJlcXVpcmUoXCJqcXVlcnlcIikpOmEoalF1ZXJ5KX0oZnVuY3Rpb24oYSl7XCJ1c2Ugc3RyaWN0XCI7dmFyIGI9d2luZG93LlNsaWNrfHx7fTtiPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gYyhjLGQpe3ZhciBmLGU9dGhpcztlLmRlZmF1bHRzPXthY2Nlc3NpYmlsaXR5OiEwLGFkYXB0aXZlSGVpZ2h0OiExLGFwcGVuZEFycm93czphKGMpLGFwcGVuZERvdHM6YShjKSxhcnJvd3M6ITAsYXNOYXZGb3I6bnVsbCxwcmV2QXJyb3c6JzxidXR0b24gdHlwZT1cImJ1dHRvblwiIGRhdGEtcm9sZT1cIm5vbmVcIiBjbGFzcz1cInNsaWNrLXByZXZcIiBhcmlhLWxhYmVsPVwiU
7437HJldmlvdXNcIiB0YWJpbmRleD1cIjBcIiByb2xlPVwiYnV0dG9uXCI+UHJldmlvdXM8L2J1dHRvbj4nLG5leHRBcnJvdzonPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgZGF0YS1yb2xlPVwibm9uZVwiIGNsYXNzPVwic2xpY2stbmV4dFwiIGFyaWEtbGFiZWw9XCJOZXh0XCIgdGFiaW5kZXg9XCIwXCIgcm9sZT1cImJ1dHRvblwiPk5leHQ8L2J1dHRvbj4nLGF1dG9wbGF5OiExLGF1dG9wbGF5U3BlZWQ6M2UzLGNlbnRlck1vZGU6ITEsY2VudGVyUGFkZGluZzpcIjUwcHhcIixjc3NFYXNlOlwiZWFzZVwiLGN1c3RvbVBhZ2luZzpmdW5jdGlvbihiLGMpe3JldHVybiBhKCc8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBkYXRhLXJvbGU9XCJub25lXCIgcm9sZT1cImJ1dHRvblwiIHRhYmluZGV4PVwiMFwiIC8+JykudGV4dChjKzEpfSxkb3RzOiExLGRvdHNDbGFzczpcInNsaWNrLWRvdHNcIixkcmFnZ2FibGU6ITAsZWFzaW5nOlwibGluZWFyXCIsZWRnZUZyaWN0aW9uOi4zNSxmYWRlOiExLGZvY3VzT25TZWxlY3Q6ITEsaW5maW5pdGU6ITAsaW5pdGlhbFNsaWRlOjAsbGF6eUxvYWQ6XCJvbmRlbWFuZFwiLG1vYmlsZUZpcnN0OiExLHBhdXNlT25Ib3ZlcjohMCxwYXVzZU9uRm9jdXM6ITAscGF1c2VPbkRvdHNIb3ZlcjohMSxyZXNwb25kVG86XCJ3aW5kb3dcIixyZXNwb25zaXZlOm51bGwscm93czoxLHJ0bDohMSxzbGlkZTpcIlwiLHNsaWRlc1BlclJvdzoxLHNsaWRlc1RvU2hvdzoxLHNsaWRlc1RvU2Nyb2xsOjEsc3BlZWQ6NTAwLHN3aXBlOiEwLHN3aXBlVG9TbGlkZTohMSx0b3VjaE1vdmU6ITAsdG91Y2hUaHJlc2hvbGQ6NSx1c2VDU1M6ITAsdXNlVHJhbnNmb3JtOiEwLHZhcmlhYmxlV2lkdGg6ITEsdmVydGljYWw6ITEsdmVydGljYWxTd2lwaW5nOiExLHdhaXRGb3JBbmltYXRlOiEwLHpJbmRleDoxZTN9LGUuaW5pdGlhbHM9e2FuaW1hdGluZzohMSxkcmFnZ2luZzohMSxhdXRvUGxheVRpbWVyOm51bGwsY3VycmVudERpcmVjdGlvbjowLGN1cnJlbnRMZWZ0Om51bGwsY3VycmVudFNsaWRlOjAsZGlyZWN0aW9uOjEsJGRvdHM6bnVsbCxsaXN0V2lkdGg6bnVsbCxsaXN0SGVpZ2h0Om51bGwsbG9hZEluZGV4OjAsJG5leHRBcnJvdzpudWxsLCRwcmV2QXJyb3c6bnVsbCxzbGlkZUNvdW50Om51bGwsc2xpZGVXaWR0aDpudWxsLCRzbGlkZVRyYWNrOm51bGwsJHNsaWRlczpudWxsLHNsaWRpbmc6ITEsc2xpZGVPZmZzZXQ6MCxzd2lwZUxlZnQ6bnVsbCwkbGlzdDpudWxsLHRvdWNoT2JqZWN0Ont9LHRyYW5zZm9ybXNFbmFibGVkOiExLHVuc2xpY2tlZDohMX0sYS5leHRlbmQoZSxlLmluaXRpYWxzKSxlLmFjdGl2ZUJyZWFrcG9pbnQ9bnVsbCxlLmFuaW1UeXBlPW51bGwsZS5hbmltUHJvcD1udWxsLGUuYnJlYWtwb2ludHM9W10sZS5icmVha3BvaW50U2V0dGluZ3M9W10sZS5jc3NUcmFuc2l0aW9ucz0hMSxlLmZvY3Vzc2VkPSExLGUuaW50ZXJydXB0ZWQ9ITEsZS5oaWRkZW49XCJoaWRkZW5cIixlLnBhdXNlZD0hMCxlLnBvc2l0aW9uUHJvcD1udWxsLGUucmVzcG9uZFRvPW51bGwsZS5yb3dDb3VudD0xLGUuc2hvdWxkQ2xpY2s9ITAsZS4kc2xpZGVyPWEoYyksZS4kc2xpZGVzQ2FjaGU9bnVsbCxlLnRyYW5zZm9ybVR5cGU9bnVsbCxlLnRyYW5zaXRpb25UeXBlPW51bGwsZS52aXNpYmlsaXR5Q2hhbmdlPVwidmlzaWJpbGl0eWNoYW5nZVwiLGUud2luZG93V2lkdGg9MCxlLndpbmRvd1RpbWVyPW51bGwsZj1hKGMpLmRhdGEoXCJzbGlja1wiKXx8e30sZS5vcHRpb25zPWEuZXh0ZW5kKHt9LGUuZGVmYXVsdHMsZCxmKSxlLmN1cnJlbnRTbGlkZT1lLm9wdGlvbnMuaW5pdGlhbFNsaWRlLGUub3JpZ2luYWxTZXR0aW5ncz1lLm9wdGlvbnMsXCJ1bmRlZmluZWRcIiE9dHlwZW9mIGRvY3VtZW50Lm1vekhpZGRlbj8oZS5oaWRkZW49XCJtb3pIaWRkZW5cIixlLnZpc2liaWxpdHlDaGFuZ2U9XCJtb3p2aXNpYmlsaXR5Y2hhbmdlXCIpOlwidW5kZWZpbmVkXCIhPXR5cGVvZiBkb2N1bWVudC53ZWJraXRIaWRkZW4mJihlLmhpZGRlbj1cIndlYmtpdEhpZGRlblwiLGUudmlzaWJpbGl0eUNoYW5nZT1cIndlYmtpdHZpc2liaWxpdHljaGFuZ2VcIiksZS5hdXRvUGxheT1hLnByb3h5KGUuYXV0b1BsYXksZSksZS5hdXRvUGxheUNsZWFyPWEucHJveHkoZS5hdXRvUGxheUNsZWFyLGUpLGUuYXV0b1BsYXlJdGVyYXRvcj1hLnByb3h5KGUuYXV0b1BsYXlJdGVyYXRvcixlKSxlLmNoYW5nZVNsaWRlPWEucHJveHkoZS5jaGFuZ2VTbGlkZSxlKSxlLmNsaWNrSGFuZGxlcj1hLnByb3h5KGUuY2xpY2tIYW5kbGVyLGUpLGUuc2VsZWN0SGFuZGxlcj1hLnByb3h5KGUuc2VsZWN0SGFuZGxlcixlKSxlLnNldFBvc2l0aW9uPWEucHJveHkoZS5zZXRQb3NpdGlvbixlKSxlLnN3aXBlSGFuZGxlcj1hLnByb3h5KGUuc3dpcGVIYW5kbGVyLGUpLGUuZHJhZ0hhbmRsZXI9YS5wcm94eShlLmRyYWdIYW5kbGVyLGUpLGUua2V5SGFuZGxlcj1hLnByb3h5KGUua2V5SGFuZGxlcixlKSxlLmluc3RhbmNlVWlkPWIrKyxlLmh0bWxFeHByPS9eKD86XFxzKig8W1xcd1xcV10rPilbXj5dKikkLyxlLnJlZ2lzdGVyQnJlYWtwb2ludHMoKSxlLmluaXQoITApfXZhciBiPTA7cmV0dXJuIGN9KCksYi5wcm90b3R5cGUuYWN0aXZhdGVBREE9ZnVuY3Rpb24oKXt2YXIgYT10aGlzO2EuJHNsaWRlVHJhY2suZmluZChcIi5zbGljay1hY3RpdmVcIikuYXR0cih7XCJhcmlhLWhpZGRlblwiOlwiZmFsc2VcIn0pLmZpbmQoXCJhLCBpbnB1dCwgYnV0dG9uLCBzZWxlY3RcIikuYXR0cih7dGFiaW5kZXg6XCIwXCJ9KX0sYi5wcm90b3R5cGUuYWRkU2xpZGU9Yi5wcm90b3R5cGUuc2xpY2tBZGQ9ZnVuY3Rpb24oYixjLGQpe3ZhciBlPXRoaXM7aWYoXCJib29sZWFuXCI9PXR5cGVvZiBjKWQ9YyxjPW51bGw7ZWxzZSBpZigwPmN8fGM+PWUuc2xpZGVDb3VudClyZXR1cm4hMTtlLnVubG9hZCgpLFwibnVtYmVyXCI9PXR5cGVvZiBjPzA9PT1jJiYwPT09ZS4kc2xpZGVzLmxlbmd0aD9hKGIpLmFwcGVuZFRvKGUuJHNsaWRlVHJhY2spOmQ/YShiKS5pbnNlcnRCZWZvcmUoZS4kc2xpZGVzLmVxKGMpKTphKGIpLmluc2VydEFmdGVyKGUuJHNsaWRlcy5lcShjKSk6ZD09PSEwP2EoYikucHJlcGVuZFRvKGUuJHNsaWRlVHJhY2spOmEoYikuYXBwZW5kVG8oZS4kc2xpZGVUcmFjayksZS4kc2xpZGVzPWUuJHNsaWRlVHJhY2suY2hpbGRyZW4odGhpcy5vcHRpb25zLnNsaWRlKSxlLiRzbGlkZVRyYWNrLmNoaWxkcmVuKHRoaXMub3B0aW9ucy5zbGlkZSkuZGV0YWNoKCksZS4kc2xpZGVUcmFjay5hcHBlbmQoZS4kc2xpZGVzKSxlLiRzbGlkZXMuZWFjaChmdW5jdGlvbihiLGMpe2EoYykuYXR0cihcImRhdGEtc2xpY2staW5kZXhcIixiKX0pLGUuJHNsaWRlc0NhY2hlPWUuJHNsaWRlcyxlLnJlaW5pdCgpfSxiLnByb3RvdHlwZS5hbmltYXRlSGVpZ2h0PWZ1bmN0aW9uKCl7dmFyIGE9dGhpcztpZigxPT09YS5vcHRpb25zLnNsaWRlc1RvU2hvdyYmYS5vcHRpb25zLmFkYXB0aXZlSGVpZ2h0PT09ITAmJmEub3B0aW9ucy52ZXJ0aWNhbD09PSExKXt2YXIgYj1hLiRzbGlkZXMuZXEoYS5jdXJyZW50U2xpZGUpLm91dGVySGVpZ2h0KCEwKTthLiRsaXN0LmFuaW1hdGUoe2hlaWdodDpifSxhLm9wdGlvbnMuc3BlZWQpfX0sYi5wcm90b3R5cGUuYW5pbWF0ZVNsaWRlPWZ1bmN0aW9uKGIsYyl7dmFyIGQ9e30sZT10aGlzO2UuYW5pbWF0ZUhlaWdodCgpLGUub3B0aW9ucy5ydGw9PT0hMCYmZS5vcHRpb25zLnZlcnRpY2FsPT09ITEmJihiPS1iKSxlLnRyYW5zZm9ybXNFbmFibGVkPT09ITE/ZS5vcHRpb25zLnZlcnRpY2FsPT09ITE/ZS4kc2xpZGVUcmFjay5hbmltYXRlKHtsZWZ0OmJ9LGUub3B0aW9ucy5zcGVlZCxlLm9wdGlvbnMuZWFzaW5nLGMpOmUuJHNsaWRlVHJhY2suYW5pbWF0ZSh7dG9wOmJ9LGUub3B0aW9ucy5zcGVlZCxlLm9wdGlvbnMuZWFzaW5nLGMpOmUuY3NzVHJhbnNpdGlvbnM9PT0hMT8oZS5vcHRpb25zLnJ0bD09PSEwJiYoZS5jdXJyZW50TGVmdD0tZS5jdXJyZW50TGVmdCksYSh7YW5pbVN0YXJ0OmUuY3VycmVudExlZnR9KS
74375hbmltYXRlKHthbmltU3RhcnQ6Yn0se2R1cmF0aW9uOmUub3B0aW9ucy5zcGVlZCxlYXNpbmc6ZS5vcHRpb25zLmVhc2luZyxzdGVwOmZ1bmN0aW9uKGEpe2E9TWF0aC5jZWlsKGEpLGUub3B0aW9ucy52ZXJ0aWNhbD09PSExPyhkW2UuYW5pbVR5cGVdPVwidHJhbnNsYXRlKFwiK2ErXCJweCwgMHB4KVwiLGUuJHNsaWRlVHJhY2suY3NzKGQpKTooZFtlLmFuaW1UeXBlXT1cInRyYW5zbGF0ZSgwcHgsXCIrYStcInB4KVwiLGUuJHNsaWRlVHJhY2suY3NzKGQpKX0sY29tcGxldGU6ZnVuY3Rpb24oKXtjJiZjLmNhbGwoKX19KSk6KGUuYXBwbHlUcmFuc2l0aW9uKCksYj1NYXRoLmNlaWwoYiksZS5vcHRpb25zLnZlcnRpY2FsPT09ITE/ZFtlLmFuaW1UeXBlXT1cInRyYW5zbGF0ZTNkKFwiK2IrXCJweCwgMHB4LCAwcHgpXCI6ZFtlLmFuaW1UeXBlXT1cInRyYW5zbGF0ZTNkKDBweCxcIitiK1wicHgsIDBweClcIixlLiRzbGlkZVRyYWNrLmNzcyhkKSxjJiZzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7ZS5kaXNhYmxlVHJhbnNpdGlvbigpLGMuY2FsbCgpfSxlLm9wdGlvbnMuc3BlZWQpKX0sYi5wcm90b3R5cGUuZ2V0TmF2VGFyZ2V0PWZ1bmN0aW9uKCl7dmFyIGI9dGhpcyxjPWIub3B0aW9ucy5hc05hdkZvcjtyZXR1cm4gYyYmbnVsbCE9PWMmJihjPWEoYykubm90KGIuJHNsaWRlcikpLGN9LGIucHJvdG90eXBlLmFzTmF2Rm9yPWZ1bmN0aW9uKGIpe3ZhciBjPXRoaXMsZD1jLmdldE5hdlRhcmdldCgpO251bGwhPT1kJiZcIm9iamVjdFwiPT10eXBlb2YgZCYmZC5lYWNoKGZ1bmN0aW9uKCl7dmFyIGM9YSh0aGlzKS5zbGljayhcImdldFNsaWNrXCIpO2MudW5zbGlja2VkfHxjLnNsaWRlSGFuZGxlcihiLCEwKX0pfSxiLnByb3RvdHlwZS5hcHBseVRyYW5zaXRpb249ZnVuY3Rpb24oYSl7dmFyIGI9dGhpcyxjPXt9O2Iub3B0aW9ucy5mYWRlPT09ITE/Y1tiLnRyYW5zaXRpb25UeXBlXT1iLnRyYW5zZm9ybVR5cGUrXCIgXCIrYi5vcHRpb25zLnNwZWVkK1wibXMgXCIrYi5vcHRpb25zLmNzc0Vhc2U6Y1tiLnRyYW5zaXRpb25UeXBlXT1cIm9wYWNpdHkgXCIrYi5vcHRpb25zLnNwZWVkK1wibXMgXCIrYi5vcHRpb25zLmNzc0Vhc2UsYi5vcHRpb25zLmZhZGU9PT0hMT9iLiRzbGlkZVRyYWNrLmNzcyhjKTpiLiRzbGlkZXMuZXEoYSkuY3NzKGMpfSxiLnByb3RvdHlwZS5hdXRvUGxheT1mdW5jdGlvbigpe3ZhciBhPXRoaXM7YS5hdXRvUGxheUNsZWFyKCksYS5zbGlkZUNvdW50PmEub3B0aW9ucy5zbGlkZXNUb1Nob3cmJihhLmF1dG9QbGF5VGltZXI9c2V0SW50ZXJ2YWwoYS5hdXRvUGxheUl0ZXJhdG9yLGEub3B0aW9ucy5hdXRvcGxheVNwZWVkKSl9LGIucHJvdG90eXBlLmF1dG9QbGF5Q2xlYXI9ZnVuY3Rpb24oKXt2YXIgYT10aGlzO2EuYXV0b1BsYXlUaW1lciYmY2xlYXJJbnRlcnZhbChhLmF1dG9QbGF5VGltZXIpfSxiLnByb3RvdHlwZS5hdXRvUGxheUl0ZXJhdG9yPWZ1bmN0aW9uKCl7dmFyIGE9dGhpcyxiPWEuY3VycmVudFNsaWRlK2Eub3B0aW9ucy5zbGlkZXNUb1Njcm9sbDthLnBhdXNlZHx8YS5pbnRlcnJ1cHRlZHx8YS5mb2N1c3NlZHx8KGEub3B0aW9ucy5pbmZpbml0ZT09PSExJiYoMT09PWEuZGlyZWN0aW9uJiZhLmN1cnJlbnRTbGlkZSsxPT09YS5zbGlkZUNvdW50LTE/YS5kaXJlY3Rpb249MDowPT09YS5kaXJlY3Rpb24mJihiPWEuY3VycmVudFNsaWRlLWEub3B0aW9ucy5zbGlkZXNUb1Njcm9sbCxhLmN1cnJlbnRTbGlkZS0xPT09MCYmKGEuZGlyZWN0aW9uPTEpKSksYS5zbGlkZUhhbmRsZXIoYikpfSxiLnByb3RvdHlwZS5idWlsZEFycm93cz1mdW5jdGlvbigpe3ZhciBiPXRoaXM7Yi5vcHRpb25zLmFycm93cz09PSEwJiYoYi4kcHJldkFycm93PWEoYi5vcHRpb25zLnByZXZBcnJvdykuYWRkQ2xhc3MoXCJzbGljay1hcnJvd1wiKSxiLiRuZXh0QXJyb3c9YShiLm9wdGlvbnMubmV4dEFycm93KS5hZGRDbGFzcyhcInNsaWNrLWFycm93XCIpLGIuc2xpZGVDb3VudD5iLm9wdGlvbnMuc2xpZGVzVG9TaG93PyhiLiRwcmV2QXJyb3cucmVtb3ZlQ2xhc3MoXCJzbGljay1oaWRkZW5cIikucmVtb3ZlQXR0cihcImFyaWEtaGlkZGVuIHRhYmluZGV4XCIpLGIuJG5leHRBcnJvdy5yZW1vdmVDbGFzcyhcInNsaWNrLWhpZGRlblwiKS5yZW1vdmVBdHRyKFwiYXJpYS1oaWRkZW4gdGFiaW5kZXhcIiksYi5odG1sRXhwci50ZXN0KGIub3B0aW9ucy5wcmV2QXJyb3cpJiZiLiRwcmV2QXJyb3cucHJlcGVuZFRvKGIub3B0aW9ucy5hcHBlbmRBcnJvd3MpLGIuaHRtbEV4cHIudGVzdChiLm9wdGlvbnMubmV4dEFycm93KSYmYi4kbmV4dEFycm93LmFwcGVuZFRvKGIub3B0aW9ucy5hcHBlbmRBcnJvd3MpLGIub3B0aW9ucy5pbmZpbml0ZSE9PSEwJiZiLiRwcmV2QXJyb3cuYWRkQ2xhc3MoXCJzbGljay1kaXNhYmxlZFwiKS5hdHRyKFwiYXJpYS1kaXNhYmxlZFwiLFwidHJ1ZVwiKSk6Yi4kcHJldkFycm93LmFkZChiLiRuZXh0QXJyb3cpLmFkZENsYXNzKFwic2xpY2staGlkZGVuXCIpLmF0dHIoe1wiYXJpYS1kaXNhYmxlZFwiOlwidHJ1ZVwiLHRhYmluZGV4OlwiLTFcIn0pKX0sYi5wcm90b3R5cGUuYnVpbGREb3RzPWZ1bmN0aW9uKCl7dmFyIGMsZCxiPXRoaXM7aWYoYi5vcHRpb25zLmRvdHM9PT0hMCYmYi5zbGlkZUNvdW50PmIub3B0aW9ucy5zbGlkZXNUb1Nob3cpe2ZvcihiLiRzbGlkZXIuYWRkQ2xhc3MoXCJzbGljay1kb3R0ZWRcIiksZD1hKFwiPHVsIC8+XCIpLmFkZENsYXNzKGIub3B0aW9ucy5kb3RzQ2xhc3MpLGM9MDtjPD1iLmdldERvdENvdW50KCk7Yys9MSlkLmFwcGVuZChhKFwiPGxpIC8+XCIpLmFwcGVuZChiLm9wdGlvbnMuY3VzdG9tUGFnaW5nLmNhbGwodGhpcyxiLGMpKSk7Yi4kZG90cz1kLmFwcGVuZFRvKGIub3B0aW9ucy5hcHBlbmREb3RzKSxiLiRkb3RzLmZpbmQoXCJsaVwiKS5maXJzdCgpLmFkZENsYXNzKFwic2xpY2stYWN0aXZlXCIpLmF0dHIoXCJhcmlhLWhpZGRlblwiLFwiZmFsc2VcIil9fSxiLnByb3RvdHlwZS5idWlsZE91dD1mdW5jdGlvbigpe3ZhciBiPXRoaXM7Yi4kc2xpZGVzPWIuJHNsaWRlci5jaGlsZHJlbihiLm9wdGlvbnMuc2xpZGUrXCI6bm90KC5zbGljay1jbG9uZWQpXCIpLmFkZENsYXNzKFwic2xpY2stc2xpZGVcIiksYi5zbGlkZUNvdW50PWIuJHNsaWRlcy5sZW5ndGgsYi4kc2xpZGVzLmVhY2goZnVuY3Rpb24oYixjKXthKGMpLmF0dHIoXCJkYXRhLXNsaWNrLWluZGV4XCIsYikuZGF0YShcIm9yaWdpbmFsU3R5bGluZ1wiLGEoYykuYXR0cihcInN0eWxlXCIpfHxcIlwiKX0pLGIuJHNsaWRlci5hZGRDbGFzcyhcInNsaWNrLXNsaWRlclwiKSxiLiRzbGlkZVRyYWNrPTA9PT1iLnNsaWRlQ291bnQ/YSgnPGRpdiBjbGFzcz1cInNsaWNrLXRyYWNrXCIvPicpLmFwcGVuZFRvKGIuJHNsaWRlcik6Yi4kc2xpZGVzLndyYXBBbGwoJzxkaXYgY2xhc3M9XCJzbGljay10cmFja1wiLz4nKS5wYXJlbnQoKSxiLiRsaXN0PWIuJHNsaWRlVHJhY2sud3JhcCgnPGRpdiBhcmlhLWxpdmU9XCJwb2xpdGVcIiBjbGFzcz1cInNsaWNrLWxpc3RcIi8+JykucGFyZW50KCksYi4kc2xpZGVUcmFjay5jc3MoXCJvcGFjaXR5XCIsMCksKGIub3B0aW9ucy5jZW50ZXJNb2RlPT09ITB8fGIub3B0aW9ucy5zd2lwZVRvU2xpZGU9PT0hMCkmJihiLm9wdGlvbnMuc2xpZGVzVG9TY3JvbGw9MSksYShcImltZ1tkYXRhLWxhenldXCIsYi4kc2xpZGVyKS5ub3QoXCJbc3JjXVwiKS5hZGRDbGFzcyhcInNsaWNrLWxvYWRpbmdcIiksYi5zZXR1cEluZmluaXRlKCksYi5idWlsZEFycm93cygpLGIuYnVpbGREb3RzKCksYi51cGRhdGVEb3RzKCksYi5zZXRTbGlkZUNsYXNzZXMoXCJudW1iZXJcIj09dHlwZW9mIGIuY3VycmVudFNsaWRlP2IuY3VycmVudFNsaWRlOjApLGIub3B0aW9ucy5kcmFnZ2FibGU9PT0hMCYmYi4kbGlzdC5hZGRDbGFzcyhcImRyYWdnYWJsZVwiKX0sYi5wcm90b3R5cGUuYnVpbGRSb3dzPWZ1bmN0aW9uKCl7dmFyIGIsYyxkLGUsZixnLGgsYT10aGlzO2lmKGU9ZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpLGc9YS4kc2xpZGVyLmNoaWxkcmVuKCksYS5vcHRpb25zLnJvd3M+MSl7Zm9yKGg9YS5vcHRpb25zLnNsaWRlc1BlclJvdyphLm9wdGlvbnMucm93cyxmPU1hdGguY2VpbChnLmxlbmd0aC9oKSxiPTA7Zj5iO2IrKyl7dmFyIGk9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtmb3IoYz0wO2M8YS5vcHRpb25zLnJvd3M7YysrKXt2YXIgaj1kb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO2ZvcihkPTA7ZDxhLm9wdGlvbnMuc2xpZGVzUGVyUm93O2QrKyl7dmFyIGs9YipoKy
7437hjKmEub3B0aW9ucy5zbGlkZXNQZXJSb3crZCk7Zy5nZXQoaykmJmouYXBwZW5kQ2hpbGQoZy5nZXQoaykpfWkuYXBwZW5kQ2hpbGQoail9ZS5hcHBlbmRDaGlsZChpKX1hLiRzbGlkZXIuZW1wdHkoKS5hcHBlbmQoZSksYS4kc2xpZGVyLmNoaWxkcmVuKCkuY2hpbGRyZW4oKS5jaGlsZHJlbigpLmNzcyh7d2lkdGg6MTAwL2Eub3B0aW9ucy5zbGlkZXNQZXJSb3crXCIlXCIsZGlzcGxheTpcImlubGluZS1ibG9ja1wifSl9fSxiLnByb3RvdHlwZS5jaGVja1Jlc3BvbnNpdmU9ZnVuY3Rpb24oYixjKXt2YXIgZSxmLGcsZD10aGlzLGg9ITEsaT1kLiRzbGlkZXIud2lkdGgoKSxqPXdpbmRvdy5pbm5lcldpZHRofHxhKHdpbmRvdykud2lkdGgoKTtpZihcIndpbmRvd1wiPT09ZC5yZXNwb25kVG8/Zz1qOlwic2xpZGVyXCI9PT1kLnJlc3BvbmRUbz9nPWk6XCJtaW5cIj09PWQucmVzcG9uZFRvJiYoZz1NYXRoLm1pbihqLGkpKSxkLm9wdGlvbnMucmVzcG9uc2l2ZSYmZC5vcHRpb25zLnJlc3BvbnNpdmUubGVuZ3RoJiZudWxsIT09ZC5vcHRpb25zLnJlc3BvbnNpdmUpe2Y9bnVsbDtmb3IoZSBpbiBkLmJyZWFrcG9pbnRzKWQuYnJlYWtwb2ludHMuaGFzT3duUHJvcGVydHkoZSkmJihkLm9yaWdpbmFsU2V0dGluZ3MubW9iaWxlRmlyc3Q9PT0hMT9nPGQuYnJlYWtwb2ludHNbZV0mJihmPWQuYnJlYWtwb2ludHNbZV0pOmc+ZC5icmVha3BvaW50c1tlXSYmKGY9ZC5icmVha3BvaW50c1tlXSkpO251bGwhPT1mP251bGwhPT1kLmFjdGl2ZUJyZWFrcG9pbnQ/KGYhPT1kLmFjdGl2ZUJyZWFrcG9pbnR8fGMpJiYoZC5hY3RpdmVCcmVha3BvaW50PWYsXCJ1bnNsaWNrXCI9PT1kLmJyZWFrcG9pbnRTZXR0aW5nc1tmXT9kLnVuc2xpY2soZik6KGQub3B0aW9ucz1hLmV4dGVuZCh7fSxkLm9yaWdpbmFsU2V0dGluZ3MsZC5icmVha3BvaW50U2V0dGluZ3NbZl0pLGI9PT0hMCYmKGQuY3VycmVudFNsaWRlPWQub3B0aW9ucy5pbml0aWFsU2xpZGUpLGQucmVmcmVzaChiKSksaD1mKTooZC5hY3RpdmVCcmVha3BvaW50PWYsXCJ1bnNsaWNrXCI9PT1kLmJyZWFrcG9pbnRTZXR0aW5nc1tmXT9kLnVuc2xpY2soZik6KGQub3B0aW9ucz1hLmV4dGVuZCh7fSxkLm9yaWdpbmFsU2V0dGluZ3MsZC5icmVha3BvaW50U2V0dGluZ3NbZl0pLGI9PT0hMCYmKGQuY3VycmVudFNsaWRlPWQub3B0aW9ucy5pbml0aWFsU2xpZGUpLGQucmVmcmVzaChiKSksaD1mKTpudWxsIT09ZC5hY3RpdmVCcmVha3BvaW50JiYoZC5hY3RpdmVCcmVha3BvaW50PW51bGwsZC5vcHRpb25zPWQub3JpZ2luYWxTZXR0aW5ncyxiPT09ITAmJihkLmN1cnJlbnRTbGlkZT1kLm9wdGlvbnMuaW5pdGlhbFNsaWRlKSxkLnJlZnJlc2goYiksaD1mKSxifHxoPT09ITF8fGQuJHNsaWRlci50cmlnZ2VyKFwiYnJlYWtwb2ludFwiLFtkLGhdKX19LGIucHJvdG90eXBlLmNoYW5nZVNsaWRlPWZ1bmN0aW9uKGIsYyl7dmFyIGYsZyxoLGQ9dGhpcyxlPWEoYi5jdXJyZW50VGFyZ2V0KTtzd2l0Y2goZS5pcyhcImFcIikmJmIucHJldmVudERlZmF1bHQoKSxlLmlzKFwibGlcIil8fChlPWUuY2xvc2VzdChcImxpXCIpKSxoPWQuc2xpZGVDb3VudCVkLm9wdGlvbnMuc2xpZGVzVG9TY3JvbGwhPT0wLGY9aD8wOihkLnNsaWRlQ291bnQtZC5jdXJyZW50U2xpZGUpJWQub3B0aW9ucy5zbGlkZXNUb1Njcm9sbCxiLmRhdGEubWVzc2FnZSl7Y2FzZVwicHJldmlvdXNcIjpnPTA9PT1mP2Qub3B0aW9ucy5zbGlkZXNUb1Njcm9sbDpkLm9wdGlvbnMuc2xpZGVzVG9TaG93LWYsZC5zbGlkZUNvdW50PmQub3B0aW9ucy5zbGlkZXNUb1Nob3cmJmQuc2xpZGVIYW5kbGVyKGQuY3VycmVudFNsaWRlLWcsITEsYyk7YnJlYWs7Y2FzZVwibmV4dFwiOmc9MD09PWY/ZC5vcHRpb25zLnNsaWRlc1RvU2Nyb2xsOmYsZC5zbGlkZUNvdW50PmQub3B0aW9ucy5zbGlkZXNUb1Nob3cmJmQuc2xpZGVIYW5kbGVyKGQuY3VycmVudFNsaWRlK2csITEsYyk7YnJlYWs7Y2FzZVwiaW5kZXhcIjp2YXIgaT0wPT09Yi5kYXRhLmluZGV4PzA6Yi5kYXRhLmluZGV4fHxlLmluZGV4KCkqZC5vcHRpb25zLnNsaWRlc1RvU2Nyb2xsO2Quc2xpZGVIYW5kbGVyKGQuY2hlY2tOYXZpZ2FibGUoaSksITEsYyksZS5jaGlsZHJlbigpLnRyaWdnZXIoXCJmb2N1c1wiKTticmVhaztkZWZhdWx0OnJldHVybn19LGIucHJvdG90eXBlLmNoZWNrTmF2aWdhYmxlPWZ1bmN0aW9uKGEpe3ZhciBjLGQsYj10aGlzO2lmKGM9Yi5nZXROYXZpZ2FibGVJbmRleGVzKCksZD0wLGE+Y1tjLmxlbmd0aC0xXSlhPWNbYy5sZW5ndGgtMV07ZWxzZSBmb3IodmFyIGUgaW4gYyl7aWYoYTxjW2VdKXthPWQ7YnJlYWt9ZD1jW2VdfXJldHVybiBhfSxiLnByb3RvdHlwZS5jbGVhblVwRXZlbnRzPWZ1bmN0aW9uKCl7dmFyIGI9dGhpcztiLm9wdGlvbnMuZG90cyYmbnVsbCE9PWIuJGRvdHMmJmEoXCJsaVwiLGIuJGRvdHMpLm9mZihcImNsaWNrLnNsaWNrXCIsYi5jaGFuZ2VTbGlkZSkub2ZmKFwibW91c2VlbnRlci5zbGlja1wiLGEucHJveHkoYi5pbnRlcnJ1cHQsYiwhMCkpLm9mZihcIm1vdXNlbGVhdmUuc2xpY2tcIixhLnByb3h5KGIuaW50ZXJydXB0LGIsITEpKSxiLiRzbGlkZXIub2ZmKFwiZm9jdXMuc2xpY2sgYmx1ci5zbGlja1wiKSxiLm9wdGlvbnMuYXJyb3dzPT09ITAmJmIuc2xpZGVDb3VudD5iLm9wdGlvbnMuc2xpZGVzVG9TaG93JiYoYi4kcHJldkFycm93JiZiLiRwcmV2QXJyb3cub2ZmKFwiY2xpY2suc2xpY2tcIixiLmNoYW5nZVNsaWRlKSxiLiRuZXh0QXJyb3cmJmIuJG5leHRBcnJvdy5vZmYoXCJjbGljay5zbGlja1wiLGIuY2hhbmdlU2xpZGUpKSxiLiRsaXN0Lm9mZihcInRvdWNoc3RhcnQuc2xpY2sgbW91c2Vkb3duLnNsaWNrXCIsYi5zd2lwZUhhbmRsZXIpLGIuJGxpc3Qub2ZmKFwidG91Y2htb3ZlLnNsaWNrIG1vdXNlbW92ZS5zbGlja1wiLGIuc3dpcGVIYW5kbGVyKSxiLiRsaXN0Lm9mZihcInRvdWNoZW5kLnNsaWNrIG1vdXNldXAuc2xpY2tcIixiLnN3aXBlSGFuZGxlciksYi4kbGlzdC5vZmYoXCJ0b3VjaGNhbmNlbC5zbGljayBtb3VzZWxlYXZlLnNsaWNrXCIsYi5zd2lwZUhhbmRsZXIpLGIuJGxpc3Qub2ZmKFwiY2xpY2suc2xpY2tcIixiLmNsaWNrSGFuZGxlciksYShkb2N1bWVudCkub2ZmKGIudmlzaWJpbGl0eUNoYW5nZSxiLnZpc2liaWxpdHkpLGIuY2xlYW5VcFNsaWRlRXZlbnRzKCksYi5vcHRpb25zLmFjY2Vzc2liaWxpdHk9PT0hMCYmYi4kbGlzdC5vZmYoXCJrZXlkb3duLnNsaWNrXCIsYi5rZXlIYW5kbGVyKSxiLm9wdGlvbnMuZm9jdXNPblNlbGVjdD09PSEwJiZhKGIuJHNsaWRlVHJhY2spLmN
7437oaWxkcmVuKCkub2ZmKFwiY2xpY2suc2xpY2tcIixiLnNlbGVjdEhhbmRsZXIpLGEod2luZG93KS5vZmYoXCJvcmllbnRhdGlvbmNoYW5nZS5zbGljay5zbGljay1cIitiLmluc3RhbmNlVWlkLGIub3JpZW50YXRpb25DaGFuZ2UpLGEod2luZG93KS5vZmYoXCJyZXNpemUuc2xpY2suc2xpY2stXCIrYi5pbnN0YW5jZVVpZCxiLnJlc2l6ZSksYShcIltkcmFnZ2FibGUhPXRydWVdXCIsYi4kc2xpZGVUcmFjaykub2ZmKFwiZHJhZ3N0YXJ0XCIsYi5wcmV2ZW50RGVmYXVsdCksYSh3aW5kb3cpLm9mZihcImxvYWQuc2xpY2suc2xpY2stXCIrYi5pbnN0YW5jZVVpZCxiLnNldFBvc2l0aW9uKSxhKGRvY3VtZW50KS5vZmYoXCJyZWFkeS5zbGljay5zbGljay1cIitiLmluc3RhbmNlVWlkLGIuc2V0UG9zaXRpb24pfSxiLnByb3RvdHlwZS5jbGVhblVwU2xpZGVFdmVudHM9ZnVuY3Rpb24oKXt2YXIgYj10aGlzO2IuJGxpc3Qub2ZmKFwibW91c2VlbnRlci5zbGlja1wiLGEucHJveHkoYi5pbnRlcnJ1cHQsYiwhMCkpLGIuJGxpc3Qub2ZmKFwibW91c2VsZWF2ZS5zbGlja1wiLGEucHJveHkoYi5pbnRlcnJ1cHQsYiwhMSkpfSxiLnByb3RvdHlwZS5jbGVhblVwUm93cz1mdW5jdGlvbigpe3ZhciBiLGE9dGhpczthLm9wdGlvbnMucm93cz4xJiYoYj1hLiRzbGlkZXMuY2hpbGRyZW4oKS5jaGlsZHJlbigpLGIucmVtb3ZlQXR0cihcInN0eWxlXCIpLGEuJHNsaWRlci5lbXB0eSgpLmFwcGVuZChiKSl9LGIucHJvdG90eXBlLmNsaWNrSGFuZGxlcj1mdW5jdGlvbihhKXt2YXIgYj10aGlzO2Iuc2hvdWxkQ2xpY2s9PT0hMSYmKGEuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCksYS5zdG9wUHJvcGFnYXRpb24oKSxhLnByZXZlbnREZWZhdWx0KCkpfSxiLnByb3RvdHlwZS5kZXN0cm95PWZ1bmN0aW9uKGIpe3ZhciBjPXRoaXM7Yy5hdXRvUGxheUNsZWFyKCksYy50b3VjaE9iamVjdD17fSxjLmNsZWFuVXBFdmVudHMoKSxhKFwiLnNsaWNrLWNsb25lZFwiLGMuJHNsaWRlcikuZGV0YWNoKCksYy4kZG90cyYmYy4kZG90cy5yZW1vdmUoKSxjLiRwcmV2QXJyb3cmJmMuJHByZXZBcnJvdy5sZW5ndGgmJihjLiRwcmV2QXJyb3cucmVtb3ZlQ2xhc3MoXCJzbGljay1kaXNhYmxlZCBzbGljay1hcnJvdyBzbGljay1oaWRkZW5cIikucmVtb3ZlQXR0cihcImFyaWEtaGlkZGVuIGFyaWEtZGlzYWJsZWQgdGFiaW5kZXhcIikuY3NzKFwiZGlzcGxheVwiLFwiXCIpLGMuaHRtbEV4cHIudGVzdChjLm9wdGlvbnMucHJldkFycm93KSYmYy4kcHJldkFycm93LnJlbW92ZSgpKSxjLiRuZXh0QXJyb3cmJmMuJG5leHRBcnJvdy5sZW5ndGgmJihjLiRuZXh0QXJyb3cucmVtb3ZlQ2xhc3MoXCJzbGljay1kaXNhYmxlZCBzbGljay1hcnJvdyBzbGljay1oaWRkZW5cIikucmVtb3ZlQXR0cihcImFyaWEtaGlkZGVuIGFyaWEtZGlzYWJsZWQgdGFiaW5kZXhcIikuY3NzKFwiZGlzcGxheVwiLFwiXCIpLGMuaHRtbEV4cHIudGVzdChjLm9wdGlvbnMubmV4dEFycm93KSYmYy4kbmV4dEFycm93LnJlbW92ZSgpKSxjLiRzbGlkZXMmJihjLiRzbGlkZXMucmVtb3ZlQ2xhc3MoXCJzbGljay1zbGlkZSBzbGljay1hY3RpdmUgc2xpY2stY2VudGVyIHNsaWNrLXZpc2libGUgc2xpY2stY3VycmVudFwiKS5yZW1vdmVBdHRyKFwiYXJpYS1oaWRkZW5cIikucmVtb3ZlQXR0cihcImRhdGEtc2xpY2staW5kZXhcIikuZWFjaChmdW5jdGlvbigpe2EodGhpcykuYXR0cihcInN0eWxlXCIsYSh0aGlzKS5kYXRhKFwib3JpZ2luYWxTdHlsaW5nXCIpKX0pLGMuJHNsaWRlVHJhY2suY2hpbGRyZW4odGhpcy5vcHRpb25zLnNsaWRlKS5kZXRhY2goKSxjLiRzbGlkZVRyYWNrLmRldGFjaCgpLGMuJGxpc3QuZGV0YWNoKCksYy4kc2xpZGVyLmFwcGVuZChjLiRzbGlkZXMpKSxjLmNsZWFuVXBSb3dzKCksYy4kc2xpZGVyLnJlbW92ZUNsYXNzKFwic2xpY2stc2xpZGVyXCIpLGMuJHNsaWRlci5yZW1vdmVDbGFzcyhcInNsaWNrLWluaXRpYWxpemVkXCIpLGMuJHNsaWRlci5yZW1vdmVDbGFzcyhcInNsaWNrLWRvdHRlZFwiKSxjLnVuc2xpY2tlZD0hMCxifHxjLiRzbGlkZXIudHJpZ2dlcihcImRlc3Ryb3lcIixbY10pfSxiLnByb3RvdHlwZS5kaXNhYmxlVHJhbnNpdGlvbj1mdW5jdGlvbihhKXt2YXIgYj10aGlzLGM9e307Y1tiLnRyYW5zaXRpb25UeXBlXT1cIlwiLGIub3B0aW9ucy5mYWRlPT09ITE/Yi4kc2xpZGVUcmFjay5jc3MoYyk6Yi4kc2xpZGVzLmVxKGEpLmNzcyhjKX0sYi5wcm90b3R5cGUuZmFkZVNsaWRlPWZ1bmN0aW9uKGEsYil7dmFyIGM9dGhpcztjLmNzc1RyYW5zaXRpb25zPT09ITE/KGMuJHNsaWRlcy5lcShhKS5jc3Moe3pJbmRleDpjLm9wdGlvbnMuekluZGV4fSksYy4kc2xpZGVzLmVxKGEpLmFuaW1hdGUoe29wYWNpdHk6MX0sYy5vcHRpb25zLnNwZWVkLGMub3B0aW9ucy5lYXNpbmcsYikpOihjLmFwcGx5VHJhbnNpdGlvbihhKSxjLiRzbGlkZXMuZXEoYSkuY3NzKHtvcGFjaXR5OjEsekluZGV4OmMub3B0aW9ucy56SW5kZXh9KSxiJiZzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7Yy5kaXNhYmxlVHJhbnNpdGlvbihhKSxiLmNhbGwoKX0sYy5vcHRpb25zLnNwZWVkKSl9LGIucHJvdG90eXBlLmZhZGVTbGlkZU91dD1mdW5jdGlvbihhKXt2YXIgYj10aGlzO2IuY3NzVHJhbnNpdGlvbnM9PT0hMT9iLiRzbGlkZXMuZXEoYSkuYW5pbWF0ZSh7b3BhY2l0eTowLHpJbmRleDpiLm9wdGlvbnMuekluZGV4LTJ9LGIub3B0aW9ucy5zcGVlZCxiLm9wdGlvbnMuZWFzaW5nKTooYi5hcHBseVRyYW5zaXRpb24oYSksYi4kc2xpZGVzLmVxKGEpLmNzcyh7b3BhY2l0eTowLHpJbmRleDpiLm9wdGlvbnMuekluZGV4LTJ9KSl9LGIucHJvdG90eXBlLmZpbHRlclNsaWRlcz1iLnByb3RvdHlwZS5zbGlja0ZpbHRlcj1mdW5jdGlvbihhKXt2YXIgYj10aGlzO251bGwhPT1hJiYoYi4kc2xpZGVzQ2FjaGU9Yi4kc2xpZGVzLGIudW5sb2FkKCksYi4kc2xpZGVUcmFjay5jaGlsZHJlbih0aGlzLm9wdGlvbnMuc2xpZGUpLmRldGFjaCgpLGIuJHNsaWRlc0NhY2hlLmZpbHRlcihhKS5hcHBlbmRUbyhiLiRzbGlkZVRyYWNrKSxiLnJlaW5pdCgpKX0sYi5wcm90b3R5cGUuZm9jdXNIYW5kbGVyPWZ1bmN0aW9uKCl7dmFyIGI9dGhpcztiLiRzbGlkZXIub2ZmKFwiZm9jdXMuc2xpY2sgYmx1ci5zbGlja1wiKS5vbihcImZvY3VzLnNsaWNrIGJsdXIuc2xpY2tcIixcIio6bm90KC5zbGljay1hcnJvdylcIixmdW5jdGlvbihjKXtjLnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO3ZhciBkPWEodGhpcyk7c2V0VGltZW91dChmdW5jdGlvbigpe2Iub3B0aW9ucy5wYXVzZU9uRm9jdXMmJihiLmZvY3Vzc2VkPWQuaXMoXCI6Zm9jdXNcIiksYi5hdXRvUGxheSgpKX0sMCl9KX0sYi5wcm90b3R5cGUuZ2V0Q3VycmVudD1iLnByb3RvdHlwZS5zbGlja0N1cnJlbnRTbGlkZT1mdW5jdGlvbigpe3ZhciBhPXRoaXM7cmV0dXJuIGEuY3VycmVudFNsaWRlfSxiLnByb3RvdHlwZS5nZXREb3RDb3VudD1mdW5jdGlvbigpe3ZhciBhPXRoaXMsYj0wLGM9MCxkPTA7aWYoYS5vcHRpb25zLmluZmluaXRlPT09ITApZm9yKDtiPGEuc2xpZGVDb3VudDspKytkLGI9YythLm9wdGlvbnMuc2xpZGVzVG9TY3JvbGwsYys9YS5vcHRpb25zLnNsaWRlc1RvU2Nyb2xsPD1hLm9wdGlvbnMuc2xpZGVzVG9TaG93P2Eub3B0aW9ucy5zbGlkZXNUb1Njcm9sbDphLm9wdGlvbnMuc2xpZGVzVG9TaG93O2Vsc2UgaWYoYS5vcHRpb25zLmNlbn
7437Rlck1vZGU9PT0hMClkPWEuc2xpZGVDb3VudDtlbHNlIGlmKGEub3B0aW9ucy5hc05hdkZvcilmb3IoO2I8YS5zbGlkZUNvdW50OykrK2QsYj1jK2Eub3B0aW9ucy5zbGlkZXNUb1Njcm9sbCxjKz1hLm9wdGlvbnMuc2xpZGVzVG9TY3JvbGw8PWEub3B0aW9ucy5zbGlkZXNUb1Nob3c/YS5vcHRpb25zLnNsaWRlc1RvU2Nyb2xsOmEub3B0aW9ucy5zbGlkZXNUb1Nob3c7ZWxzZSBkPTErTWF0aC5jZWlsKChhLnNsaWRlQ291bnQtYS5vcHRpb25zLnNsaWRlc1RvU2hvdykvYS5vcHRpb25zLnNsaWRlc1RvU2Nyb2xsKTtyZXR1cm4gZC0xfSxiLnByb3RvdHlwZS5nZXRMZWZ0PWZ1bmN0aW9uKGEpe3ZhciBjLGQsZixiPXRoaXMsZT0wO3JldHVybiBiLnNsaWRlT2Zmc2V0PTAsZD1iLiRzbGlkZXMuZmlyc3QoKS5vdXRlckhlaWdodCghMCksYi5vcHRpb25zLmluZmluaXRlPT09ITA/KGIuc2xpZGVDb3VudD5iLm9wdGlvbnMuc2xpZGVzVG9TaG93JiYoYi5zbGlkZU9mZnNldD1iLnNsaWRlV2lkdGgqYi5vcHRpb25zLnNsaWRlc1RvU2hvdyotMSxlPWQqYi5vcHRpb25zLnNsaWRlc1RvU2hvdyotMSksYi5zbGlkZUNvdW50JWIub3B0aW9ucy5zbGlkZXNUb1Njcm9sbCE9PTAmJmErYi5vcHRpb25zLnNsaWRlc1RvU2Nyb2xsPmIuc2xpZGVDb3VudCYmYi5zbGlkZUNvdW50PmIub3B0aW9ucy5zbGlkZXNUb1Nob3cmJihhPmIuc2xpZGVDb3VudD8oYi5zbGlkZU9mZnNldD0oYi5vcHRpb25zLnNsaWRlc1RvU2hvdy0oYS1iLnNsaWRlQ291bnQpKSpiLnNsaWRlV2lkdGgqLTEsZT0oYi5vcHRpb25zLnNsaWRlc1RvU2hvdy0oYS1iLnNsaWRlQ291bnQpKSpkKi0xKTooYi5zbGlkZU9mZnNldD1iLnNsaWRlQ291bnQlYi5vcHRpb25zLnNsaWRlc1RvU2Nyb2xsKmIuc2xpZGVXaWR0aCotMSxlPWIuc2xpZGVDb3VudCViLm9wdGlvbnMuc2xpZGVzVG9TY3JvbGwqZCotMSkpKTphK2Iub3B0aW9ucy5zbGlkZXNUb1Nob3c+Yi5zbGlkZUNvdW50JiYoYi5zbGlkZU9mZnNldD0oYStiLm9wdGlvbnMuc2xpZGVzVG9TaG93LWIuc2xpZGVDb3VudCkqYi5zbGlkZVdpZHRoLGU9KGErYi5vcHRpb25zLnNsaWRlc1RvU2hvdy1iLnNsaWRlQ291bnQpKmQpLGIuc2xpZGVDb3VudDw9Yi5vcHRpb25zLnNsaWRlc1RvU2hvdyYmKGIuc2xpZGVPZmZzZXQ9MCxlPTApLGIub3B0aW9ucy5jZW50ZXJNb2RlPT09ITAmJmIub3B0aW9ucy5pbmZpbml0ZT09PSEwP2Iuc2xpZGVPZmZzZXQrPWIuc2xpZGVXaWR0aCpNYXRoLmZsb29yKGIub3B0aW9ucy5zbGlkZXNUb1Nob3cvMiktYi5zbGlkZVdpZHRoOmIub3B0aW9ucy5jZW50ZXJNb2RlPT09ITAmJihiLnNsaWRlT2Zmc2V0PTAsYi5zbGlkZU9mZnNldCs9Yi5zbGlkZVdpZHRoKk1hdGguZmxvb3IoYi5vcHRpb25zLnNsaWRlc1RvU2hvdy8yKSksYz1iLm9wdGlvbnMudmVydGljYWw9PT0hMT9hKmIuc2xpZGVXaWR0aCotMStiLnNsaWRlT2Zmc2V0OmEqZCotMStlLGIub3B0aW9ucy52YXJpYWJsZVdpZHRoPT09ITAmJihmPWIuc2xpZGVDb3VudDw9Yi5vcHRpb25zLnNsaWRlc1RvU2hvd3x8Yi5vcHRpb25zLmluZmluaXRlPT09ITE/Yi4kc2xpZGVUcmFjay5jaGlsZHJlbihcIi5zbGljay1zbGlkZVwiKS5lcShhKTpiLiRzbGlkZVRyYWNrLmNoaWxkcmVuKFwiLnNsaWNrLXNsaWRlXCIpLmVxKGErYi5vcHRpb25zLnNsaWRlc1RvU2hvdyksYz1iLm9wdGlvbnMucnRsPT09ITA/ZlswXT8tMSooYi4kc2xpZGVUcmFjay53aWR0aCgpLWZbMF0ub2Zmc2V0TGVmdC1mLndpZHRoKCkpOjA6ZlswXT8tMSpmWzBdLm9mZnNldExlZnQ6MCxiLm9wdGlvbnMuY2VudGVyTW9kZT09PSEwJiYoZj1iLnNsaWRlQ291bnQ8PWIub3B0aW9ucy5zbGlkZXNUb1Nob3d8fGIub3B0aW9ucy5pbmZpbml0ZT09PSExP2IuJHNsaWRlVHJhY2suY2hpbGRyZW4oXCIuc2xpY2stc2xpZGVcIikuZXEoYSk6Yi4kc2xpZGVUcmFjay5jaGlsZHJlbihcIi5zbGljay1zbGlkZVwiKS5lcShhK2Iub3B0aW9ucy5zbGlkZXNUb1Nob3crMSksYz1iLm9wdGlvbnMucnRsPT09ITA/ZlswXT8tMSooYi4kc2xpZGVUcmFjay53aWR0aCgpLWZbMF0ub2Zmc2V0TGVmdC1mLndpZHRoKCkpOjA6ZlswXT8tMSpmWzBdLm9mZnNldExlZnQ6MCxjKz0oYi4kbGlzdC53aWR0aCgpLWYub3V0ZXJXaWR0aCgpKS8yKSksY30sYi5wcm90b3R5cGUuZ2V0T3B0aW9uPWIucHJvdG90eXBlLnNsaWNrR2V0T3B0aW9uPWZ1bmN0aW9uKGEpe3ZhciBiPXRoaXM7cmV0dXJuIGIub3B0aW9uc1thXX0sYi5wcm90b3R5cGUuZ2V0TmF2aWdhYmxlSW5kZXhlcz1mdW5jdGlvbigpe3ZhciBlLGE9dGhpcyxiPTAsYz0wLGQ9W107Zm9yKGEub3B0aW9ucy5pbmZpbml0ZT09PSExP2U9YS5zbGlkZUNvdW50OihiPS0xKmEub3B0aW9ucy5zbGlkZXNUb1Njcm9sbCxjPS0xKmEub3B0aW9ucy5zbGlkZXNUb1Njcm9sbCxlPTIqYS5zbGlkZUNvdW50KTtlPmI7KWQucHVzaChiKSxiPWMrYS5vcHRpb25zLnNsaWRlc1RvU2Nyb2xsLGMrPWEub3B0aW9ucy5zbGlkZXNUb1Njcm9sbDw9YS5vcHRpb25zLnNsaWRlc1RvU2hvdz9hLm9wdGlvbnMuc2xpZGVzVG9TY3JvbGw6YS5vcHRpb25zLnNsaWRlc1RvU2hvdztyZXR1cm4gZH0sYi5wcm90b3R5cGUuZ2V0U2xpY2s9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpc30sYi5wcm90b3R5cGUuZ2V0U2xpZGVDb3VudD1mdW5jdGlvbigpe3ZhciBjLGQsZSxiPXRoaXM7cmV0dXJuIGU9Yi5vcHRpb25zLmNlbnRlck1vZGU9PT0hMD9iLnNsaWRlV2lkdGgqTWF0aC5mbG9vcihiLm9wdGlvbnMuc2xpZGVzVG9TaG93LzIpOjAsYi5vcHRpb25zLnN3aXBlVG9TbGlkZT09PSEwPyhiLiRzbGlkZVRyYWNrLmZpbmQoXCIuc2xpY2stc2xpZGVcIikuZWFjaChmdW5jdGlvbihjLGYpe3JldHVybiBmLm9mZnNldExlZnQtZSthKGYpLm91dGVyV2lkdGgoKS8yPi0xKmIuc3dpcGVMZWZ0PyhkPWYsITEpOnZvaWQgMH0pLGM9TWF0aC5hYnMoYShkKS5hdHRyKFwiZGF0YS1zbGljay1pbmRleFwiKS1iLmN1cnJlbnRTbGlkZSl8fDEpOmIub3B0aW9ucy5zbGlkZXNUb1Njcm9sbH0sYi5wcm90b3R5cGUuZ29Ubz1iLnByb3RvdHlwZS5zbGlja0dvVG89ZnVuY3Rpb24oYSxiKXt2YXIgYz10aGlzO2MuY2hhbmdlU2xpZGUoe2R
7437hdGE6e21lc3NhZ2U6XCJpbmRleFwiLGluZGV4OnBhcnNlSW50KGEpfX0sYil9LGIucHJvdG90eXBlLmluaXQ9ZnVuY3Rpb24oYil7dmFyIGM9dGhpczthKGMuJHNsaWRlcikuaGFzQ2xhc3MoXCJzbGljay1pbml0aWFsaXplZFwiKXx8KGEoYy4kc2xpZGVyKS5hZGRDbGFzcyhcInNsaWNrLWluaXRpYWxpemVkXCIpLGMuYnVpbGRSb3dzKCksYy5idWlsZE91dCgpLGMuc2V0UHJvcHMoKSxjLnN0YXJ0TG9hZCgpLGMubG9hZFNsaWRlcigpLGMuaW5pdGlhbGl6ZUV2ZW50cygpLGMudXBkYXRlQXJyb3dzKCksYy51cGRhdGVEb3RzKCksYy5jaGVja1Jlc3BvbnNpdmUoITApLGMuZm9jdXNIYW5kbGVyKCkpLGImJmMuJHNsaWRlci50cmlnZ2VyKFwiaW5pdFwiLFtjXSksYy5vcHRpb25zLmFjY2Vzc2liaWxpdHk9PT0hMCYmYy5pbml0QURBKCksYy5vcHRpb25zLmF1dG9wbGF5JiYoYy5wYXVzZWQ9ITEsYy5hdXRvUGxheSgpKX0sYi5wcm90b3R5cGUuaW5pdEFEQT1mdW5jdGlvbigpe3ZhciBiPXRoaXM7Yi4kc2xpZGVzLmFkZChiLiRzbGlkZVRyYWNrLmZpbmQoXCIuc2xpY2stY2xvbmVkXCIpKS5hdHRyKHtcImFyaWEtaGlkZGVuXCI6XCJ0cnVlXCIsdGFiaW5kZXg6XCItMVwifSkuZmluZChcImEsIGlucHV0LCBidXR0b24sIHNlbGVjdFwiKS5hdHRyKHt0YWJpbmRleDpcIi0xXCJ9KSxiLiRzbGlkZVRyYWNrLmF0dHIoXCJyb2xlXCIsXCJsaXN0Ym94XCIpLGIuJHNsaWRlcy5ub3QoYi4kc2xpZGVUcmFjay5maW5kKFwiLnNsaWNrLWNsb25lZFwiKSkuZWFjaChmdW5jdGlvbihjKXthKHRoaXMpLmF0dHIoe3JvbGU6XCJvcHRpb25cIixcImFyaWEtZGVzY3JpYmVkYnlcIjpcInNsaWNrLXNsaWRlXCIrYi5pbnN0YW5jZVVpZCtjfSl9KSxudWxsIT09Yi4kZG90cyYmYi4kZG90cy5hdHRyKFwicm9sZVwiLFwidGFibGlzdFwiKS5maW5kKFwibGlcIikuZWFjaChmdW5jdGlvbihjKXthKHRoaXMpLmF0dHIoe3JvbGU6XCJwcmVzZW50YXRpb25cIixcImFyaWEtc2VsZWN0ZWRcIjpcImZhbHNlXCIsXCJhcmlhLWNvbnRyb2xzXCI6XCJuYXZpZ2F0aW9uXCIrYi5pbnN0YW5jZVVpZCtjLGlkOlwic2xpY2stc2xpZGVcIitiLmluc3RhbmNlVWlkK2N9KX0pLmZpcnN0KCkuYXR0cihcImFyaWEtc2VsZWN0ZWRcIixcInRydWVcIikuZW5kKCkuZmluZChcImJ1dHRvblwiKS5hdHRyKFwicm9sZVwiLFwiYnV0dG9uXCIpLmVuZCgpLmNsb3Nlc3QoXCJkaXZcIikuYXR0cihcInJvbGVcIixcInRvb2xiYXJcIiksYi5hY3RpdmF0ZUFEQSgpfSxiLnByb3RvdHlwZS5pbml0QXJyb3dFdmVudHM9ZnVuY3Rpb24oKXt2YXIgYT10aGlzO2Eub3B0aW9ucy5hcnJvd3M9PT0hMCYmYS5zbGlkZUNvdW50PmEub3B0aW9ucy5zbGlkZXNUb1Nob3cmJihhLiRwcmV2QXJyb3cub2ZmKFwiY2xpY2suc2xpY2tcIikub24oXCJjbGljay5zbGlja1wiLHttZXNzYWdlOlwicHJldmlvdXNcIn0sYS5jaGFuZ2VTbGlkZSksYS4kbmV4dEFycm93Lm9mZihcImNsaWNrLnNsaWNrXCIpLm9uKFwiY2xpY2suc2xpY2tcIix7bWVzc2FnZTpcIm5leHRcIn0sYS5jaGFuZ2VTbGlkZSkpfSxiLnByb3RvdHlwZS5pbml0RG90RXZlbnRzPWZ1bmN0aW9uKCl7dmFyIGI9dGhpcztiLm9wdGlvbnMuZG90cz09PSEwJiZiLnNsaWRlQ291bnQ+Yi5vcHRpb25zLnNsaWRlc1RvU2hvdyYmYShcImxpXCIsYi4kZG90cykub24oXCJjbGljay5zbGlja1wiLHttZXNzYWdlOlwiaW5kZXhcIn0sYi5jaGFuZ2VTbGlkZSksYi5vcHRpb25zLmRvdHM9PT0hMCYmYi5vcHRpb25zLnBhdXNlT25Eb3RzSG92ZXI9PT0hMCYmYShcImxpXCIsYi4kZG90cykub24oXCJtb3VzZWVudGVyLnNsaWNrXCIsYS5wcm94eShiLmludGVycnVwdCxiLCEwKSkub24oXCJtb3VzZWxlYXZlLnNsaWNrXCIsYS5wcm94eShiLmludGVycnVwdCxiLCExKSl9LGIucHJvdG90eXBlLmluaXRTbGlkZUV2ZW50cz1mdW5jdGlvbigpe3ZhciBiPXRoaXM7Yi5vcHRpb25zLnBhdXNlT25Ib3ZlciYmKGIuJGxpc3Qub24oXCJtb3VzZWVudGVyLnNsaWNrXCIsYS5wcm94eShiLmludGVycnVwdCxiLCEwKSksYi4kbGlzdC5vbihcIm1vdXNlbGVhdmUuc2xpY2tcIixhLnByb3h5KGIuaW50ZXJydXB0LGIsITEpKSl9LGIucHJvdG90eXBlLmluaXRpYWxpemVFdmVudHM9ZnVuY3Rpb24oKXt2YXIgYj10aGlzO2IuaW5pdEFycm93RXZlbnRzKCksYi5pbml0RG90RXZlbnRzKCksYi5pbml0U2xpZGVFdmVudHMoKSxiLiRsaXN0Lm9uKFwidG91Y2hzdGFydC5zbGljayBtb3VzZWRvd24uc2xpY2tcIix7YWN0aW9uOlwic3RhcnRcIn0sYi5zd2lwZUhhbmRsZXIpLGIuJGxpc3Qub24oXCJ0b3VjaG1vdmUuc2xpY2sgbW91c2Vtb3ZlLnNsaWNrXCIse2FjdGlvbjpcIm1vdmVcIn0sYi5zd2lwZUhhbmRsZXIpLGIuJGxpc3Qub24oXCJ0b3VjaGVuZC5zbGljayBtb3VzZXVwLnNsaWNrXCIse2FjdGlvbjpcImVuZFwifSxiLnN3aXBlSGFuZGxlciksYi4kbGlzdC5vbihcInRvdWNoY2FuY2VsLnNsaWNrIG1vdXNlbGVhdmUuc2xpY2tcIix7YWN0aW9uOlwiZW5kXCJ9LGIuc3dpcGVIYW5kbGVyKSxiLiRsaXN0Lm9uKFwiY2xpY2suc2xpY2tcIixiLmNsaWNrSGFuZGxlciksYShkb2N1bWVudCkub24oYi52aXNpYmlsaXR5Q2hhbmdlLGEucHJveHkoYi52aXNpYmlsaXR5LGIpKSxiLm9wdGlvbnMuYWNjZXNzaWJpbGl0eT09PSEwJiZiLiRsaXN0Lm9uKFwia2V5ZG93bi5zbGlja1wiLGIua2V5SGFuZGxlciksYi5vcHRpb25zLmZvY3VzT25TZWxlY3Q9PT0hMCYmYShiLiRzbGlkZVRyYWNrKS5jaGlsZHJlbigpLm9uKFwiY2xpY2suc2xpY2tcIixiLnNlbGVjdEhhbmRsZXIpLGEod2luZG93KS5vbihcIm9yaWVudGF0aW9uY2hhbmdlLnNsaWNrLnNsaWNrLVwiK2IuaW5zdGFuY2VVaWQsYS5wcm94eShiLm9yaWVudGF0aW9uQ2hhbmdlLGIpKSxhKHdpbmRvdykub24oXCJyZXNpemUuc2xpY2suc2xpY2stXCIrYi5pbnN0YW5jZVVpZCxhLnByb3h5KGIucmVzaXplLGIpKSxhKFwiW2RyYWdnYWJsZSE9dHJ1ZV1cIixiLiRzbGlkZVRyYWNrKS5vbihcImRyYWdzdGFydFwiLGIucHJldmVudERlZmF1bHQpLGEod2luZG93KS5vbihcImxvYWQuc2xpY2suc2xpY2stXCIrYi5pbnN0YW5jZVVpZCxiLnNldFBvc2l0aW9uKSxhKGRvY3VtZW50KS5vbihcInJlYWR5LnNsaWNrLnNsaWNrLVwiK2IuaW5zdGFuY2VVaWQsYi5zZXRQb3NpdGlvbil9LGIucHJvdG90eXBlLmluaXRVST1mdW5jdGlvbigpe3ZhciBhPXRoaXM7YS5vcHRpb25zLmFycm93cz09PSEwJiZhLnNsaWRlQ291bnQ+YS5vcHRpb25zLnNsaWRlc1RvU2hvdyYmKGEuJHByZXZBcnJvdy5zaG93KCksYS4kbmV4dEFycm93LnNob3coKSksYS5vcHRpb25zLmRvdHM9PT0hMCYmYS5zbGlkZUNvdW50PmEub3B0aW9ucy5zbGlkZXNUb1Nob3cmJmEuJGRvdHMuc2hvdygpfSxiLnByb3RvdHlwZS5rZXlIYW5kbGVyPWZ1bmN0aW9uKGEpe3ZhciBiPXRoaXM7YS50YXJnZXQudGFnTmFtZS5tYXRjaChcIlRFWFRBUkVBfElOUFVUfFNFTEVDVFwiKXx8KDM3PT09YS5rZXlDb2RlJiZiLm9wdGlvbnMuYWNjZXNzaWJpbGl0eT09PSEwP2IuY2hhbmdlU2xpZGUoe2R
7437hdGE6e21lc3NhZ2U6Yi5vcHRpb25zLnJ0bD09PSEwP1wibmV4dFwiOlwicHJldmlvdXNcIn19KTozOT09PWEua2V5Q29kZSYmYi5vcHRpb25zLmFjY2Vzc2liaWxpdHk9PT0hMCYmYi5jaGFuZ2VTbGlkZSh7ZGF0YTp7bWVzc2FnZTpiLm9wdGlvbnMucnRsPT09ITA/XCJwcmV2aW91c1wiOlwibmV4dFwifX0pKX0sYi5wcm90b3R5cGUubGF6eUxvYWQ9ZnVuY3Rpb24oKXtmdW5jdGlvbiBnKGMpe2EoXCJpbWdbZGF0YS1sYXp5XVwiLGMpLmVhY2goZnVuY3Rpb24oKXt2YXIgYz1hKHRoaXMpLGQ9YSh0aGlzKS5hdHRyKFwiZGF0YS1sYXp5XCIpLGU9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImltZ1wiKTtlLm9ubG9hZD1mdW5jdGlvbigpe2MuYW5pbWF0ZSh7b3BhY2l0eTowfSwxMDAsZnVuY3Rpb24oKXtjLmF0dHIoXCJzcmNcIixkKS5hbmltYXRlKHtvcGFjaXR5OjF9LDIwMCxmdW5jdGlvbigpe2MucmVtb3ZlQXR0cihcImRhdGEtbGF6eVwiKS5yZW1vdmVDbGFzcyhcInNsaWNrLWxvYWRpbmdcIil9KSxiLiRzbGlkZXIudHJpZ2dlcihcImxhenlMb2FkZWRcIixbYixjLGRdKX0pfSxlLm9uZXJyb3I9ZnVuY3Rpb24oKXtjLnJlbW92ZUF0dHIoXCJkYXRhLWxhenlcIikucmVtb3ZlQ2xhc3MoXCJzbGljay1sb2FkaW5nXCIpLmFkZENsYXNzKFwic2xpY2stbGF6eWxvYWQtZXJyb3JcIiksYi4kc2xpZGVyLnRyaWdnZXIoXCJsYXp5TG9hZEVycm9yXCIsW2IsYyxkXSl9LGUuc3JjPWR9KX12YXIgYyxkLGUsZixiPXRoaXM7Yi5vcHRpb25zLmNlbnRlck1vZGU9PT0hMD9iLm9wdGlvbnMuaW5maW5pdGU9PT0hMD8oZT1iLmN1cnJlbnRTbGlkZSsoYi5vcHRpb25zLnNsaWRlc1RvU2hvdy8yKzEpLGY9ZStiLm9wdGlvbnMuc2xpZGVzVG9TaG93KzIpOihlPU1hdGgubWF4KDAsYi5jdXJyZW50U2xpZGUtKGIub3B0aW9ucy5zbGlkZXNUb1Nob3cvMisxKSksZj0yKyhiLm9wdGlvbnMuc2xpZGVzVG9TaG93LzIrMSkrYi5jdXJyZW50U2xpZGUpOihlPWIub3B0aW9ucy5pbmZpbml0ZT9iLm9wdGlvbnMuc2xpZGVzVG9TaG93K2IuY3VycmVudFNsaWRlOmIuY3VycmVudFNsaWRlLGY9TWF0aC5jZWlsKGUrYi5vcHRpb25zLnNsaWRlc1RvU2hvdyksYi5vcHRpb25zLmZhZGU9PT0hMCYmKGU+MCYmZS0tLGY8PWIuc2xpZGVDb3VudCYmZisrKSksYz1iLiRzbGlkZXIuZmluZChcIi5zbGljay1zbGlkZVwiKS5zbGljZShlLGYpLGcoYyksYi5zbGlkZUNvdW50PD1iLm9wdGlvbnMuc2xpZGVzVG9TaG93PyhkPWIuJHNsaWRlci5maW5kKFwiLnNsaWNrLXNsaWRlXCIpLGcoZCkpOmIuY3VycmVudFNsaWRlPj1iLnNsaWRlQ291bnQtYi5vcHRpb25zLnNsaWRlc1RvU2hvdz8oZD1iLiRzbGlkZXIuZmluZChcIi5zbGljay1jbG9uZWRcIikuc2xpY2UoMCxiLm9wdGlvbnMuc2xpZGVzVG9TaG93KSxnKGQpKTowPT09Yi5jdXJyZW50U2xpZGUmJihkPWIuJHNsaWRlci5maW5kKFwiLnNsaWNrLWNsb25lZFwiKS5zbGljZSgtMSpiLm9wdGlvbnMuc2xpZGVzVG9TaG93KSxnKGQpKX0sYi5wcm90b3R5cGUubG9hZFNsaWRlcj1mdW5jdGlvbigpe3ZhciBhPXRoaXM7YS5zZXRQb3NpdGlvbigpLGEuJHNsaWRlVHJhY2suY3NzKHtvcGFjaXR5OjF9KSxhLiRzbGlkZXIucmVtb3ZlQ2xhc3MoXCJzbGljay1sb2FkaW5nXCIpLGEuaW5pdFVJKCksXCJwcm9ncmVzc2l2ZVwiPT09YS5vcHRpb25zLmxhenlMb2FkJiZhLnByb2dyZXNzaXZlTGF6eUxvYWQoKX0sYi5wcm90b3R5cGUubmV4dD1iLnByb3RvdHlwZS5zbGlja05leHQ9ZnVuY3Rpb24oKXt2YXIgYT10aGlzO2EuY2hhbmdlU2xpZGUoe2R
7437hdGE6e21lc3NhZ2U6XCJuZXh0XCJ9fSl9LGIucHJvdG90eXBlLm9yaWVudGF0aW9uQ2hhbmdlPWZ1bmN0aW9uKCl7dmFyIGE9dGhpczthLmNoZWNrUmVzcG9uc2l2ZSgpLGEuc2V0UG9zaXRpb24oKX0sYi5wcm90b3R5cGUucGF1c2U9Yi5wcm90b3R5cGUuc2xpY2tQYXVzZT1mdW5jdGlvbigpe3ZhciBhPXRoaXM7YS5hdXRvUGxheUNsZWFyKCksYS5wYXVzZWQ9ITB9LGIucHJvdG90eXBlLnBsYXk9Yi5wcm90b3R5cGUuc2xpY2tQbGF5PWZ1bmN0aW9uKCl7dmFyIGE9dGhpczthLmF1dG9QbGF5KCksYS5vcHRpb25zLmF1dG9wbGF5PSEwLGEucGF1c2VkPSExLGEuZm9jdXNzZWQ9ITEsYS5pbnRlcnJ1cHRlZD0hMX0sYi5wcm90b3R5cGUucG9zdFNsaWRlPWZ1bmN0aW9uKGEpe3ZhciBiPXRoaXM7Yi51bnNsaWNrZWR8fChiLiRzbGlkZXIudHJpZ2dlcihcImFmdGVyQ2hhbmdlXCIsW2IsYV0pLGIuYW5pbWF0aW5nPSExLGIuc2V0UG9zaXRpb24oKSxiLnN3aXBlTGVmdD1udWxsLGIub3B0aW9ucy5hdXRvcGxheSYmYi5hdXRvUGxheSgpLGIub3B0aW9ucy5hY2Nlc3NpYmlsaXR5PT09ITAmJmIuaW5pdEFEQSgpKX0sYi5wcm90b3R5cGUucHJldj1iLnByb3RvdHlwZS5zbGlja1ByZXY9ZnVuY3Rpb24oKXt2YXIgYT10aGlzO2EuY2hhbmdlU2xpZGUoe2RhdGE6e21lc3NhZ2U6XCJwcmV2aW91c1wifX0pfSxiLnByb3RvdHlwZS5wcmV2ZW50RGVmYXVsdD1mdW5jdGlvbihhKXthLnByZXZlbnREZWZhdWx0KCl9LGIucHJvdG90eXBlLnByb2dyZXNzaXZlTGF6eUxvYWQ9ZnVuY3Rpb24oYil7Yj1ifHwxO3ZhciBlLGYsZyxjPXRoaXMsZD1hKFwiaW1nW2RhdGEtbGF6eV1cIixjLiRzbGlkZXIpO2QubGVuZ3RoPyhlPWQuZmlyc3QoKSxmPWUuYXR0cihcImRhdGEtbGF6eVwiKSxnPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJpbWdcIiksZy5vbmxvYWQ9ZnVuY3Rpb24oKXtlLmF0dHIoXCJzcmNcIixmKS5yZW1vdmVBdHRyKFwiZGF0YS1sYXp5XCIpLnJlbW92ZUNsYXNzKFwic2xpY2stbG9hZGluZ1wiKSxjLm9wdGlvbnMuYWRhcHRpdmVIZWlnaHQ9PT0hMCYmYy5zZXRQb3NpdGlvbigpLGMuJHNsaWRlci50cmlnZ2VyKFwibGF6eUxvYWRlZFwiLFtjLGUsZl0pLGMucHJvZ3Jlc3NpdmVMYXp5TG9hZCgpfSxnLm9uZXJyb3I9ZnVuY3Rpb24oKXszPmI/c2V0VGltZW91dChmdW5jdGlvbigpe2MucHJvZ3Jlc3NpdmVMYXp5TG9hZChiKzEpfSw1MDApOihlLnJlbW92ZUF0dHIoXCJkYXRhLWxhenlcIikucmVtb3ZlQ2xhc3MoXCJzbGljay1sb2FkaW5nXCIpLmFkZENsYXNzKFwic2xpY2stbGF6eWxvYWQtZXJyb3JcIiksYy4kc2xpZGVyLnRyaWdnZXIoXCJsYXp5TG9hZEVycm9yXCIsW2MsZSxmXSksYy5wcm9ncmVzc2l2ZUxhenlMb2FkKCkpfSxnLnNyYz1mKTpjLiRzbGlkZXIudHJpZ2dlcihcImFsbEltYWdlc0xvYWRlZFwiLFtjXSl9LGIucHJvdG90eXBlLnJlZnJlc2g9ZnVuY3Rpb24oYil7dmFyIGQsZSxjPXRoaXM7ZT1jLnNsaWRlQ291bnQtYy5vcHRpb25zLnNsaWRlc1RvU2hvdywhYy5vcHRpb25zLmluZmluaXRlJiZjLmN1cnJlbnRTbGlkZT5lJiYoYy5jdXJyZW50U2xpZGU9ZSksYy5zbGlkZUNvdW50PD1jLm9wdGlvbnMuc2xpZGVzVG9TaG93JiYoYy5jdXJyZW50U2xpZGU9MCksZD1jLmN1cnJlbnRTbGlkZSxjLmRlc3Ryb3koITApLGEuZXh0ZW5kKGMsYy5pbml0aWFscyx7Y3VycmVudFNsaWRlOmR9KSxjLmluaXQoKSxifHxjLmNoYW5nZVNsaWRlKHtkYXRhOnttZXNzYWdlOlwiaW5kZXhcIixpbmRleDpkfX0sITEpfSxiLnByb3RvdHlwZS5yZWdpc3RlckJyZWFrcG9pbnRzPWZ1bmN0aW9uKCl7dmFyIGMsZCxlLGI9dGhpcyxmPWIub3B0aW9ucy5yZXNwb25zaXZlfHxudWxsO2lmKFwiYXJyYXlcIj09PWEudHlwZShmKSYmZi5sZW5ndGgpe2IucmVzcG9uZFRvPWIub3B0aW9ucy5yZXNwb25kVG98fFwid2luZG93XCI7Zm9yKGMgaW4gZilpZihlPWIuYnJlYWtwb2ludHMubGVuZ3RoLTEsZD1mW2NdLmJyZWFrcG9pbnQsZi5oYXNPd25Qcm9wZXJ0eShjKSl7Zm9yKDtlPj0wOyliLmJyZWFrcG9pbnRzW2VdJiZiLmJyZWFrcG9pbnRzW2VdPT09ZCYmYi5icmVha3BvaW50cy5zcGxpY2UoZSwxKSxlLS07Yi5icmVha3BvaW50cy5wdXNoKGQpLGIuYnJlYWtwb2ludFNldHRpbmdzW2RdPWZbY10uc2V0dGluZ3N9Yi5icmVha3BvaW50cy5zb3J0KGZ1bmN0aW9uKGEsYyl7cmV0dXJuIGIub3B0aW9ucy5tb2JpbGVGaXJzdD9hLWM6Yy1hfSl9fSxiLnByb3RvdHlwZS5yZWluaXQ9ZnVuY3Rpb24oKXt2YXIgYj10aGlzO2IuJHNsaWRlcz1iLiRzbGlkZVRyYWNrLmNoaWxkcmVuKGIub3B0aW9ucy5zbGlkZSkuYWRkQ2xhc3MoXCJzbGljay1zbGlkZVwiKSxiLnNsaWRlQ291bnQ9Yi4kc2xpZGVzLmxlbmd0aCxiLmN1cnJlbnRTbGlkZT49Yi5zbGlkZUNvdW50JiYwIT09Yi5jdXJyZW50U2xpZGUmJihiLmN1cnJlbnRTbGlkZT1iLmN1cnJlbnRTbGlkZS1iLm9wdGlvbnMuc2xpZGVzVG9TY3JvbGwpLGIuc2xpZGVDb3VudDw9Yi5vcHRpb25zLnNsaWRlc1RvU2hvdyYmKGIuY3VycmVudFNsaWRlPTApLGIucmVnaXN0ZXJCcmVha3BvaW50cygpLGIuc2V0UHJvcHMoKSxiLnNldHVwSW5maW5pdGUoKSxiLmJ1aWxkQXJyb3dzKCksYi51cGRhdGVBcnJvd3MoKSxiLmluaXRBcnJvd0V2ZW50cygpLGIuYnVpbGREb3RzKCksYi51cGRhdGVEb3RzKCksYi5pbml0RG90RXZlbnRzKCksYi5jbGVhblVwU2xpZGVFdmVudHMoKSxiLmluaXRTbGlkZUV2ZW50cygpLGIuY2hlY2tSZXNwb25zaXZlKCExLCEwKSxiLm9wdGlvbnMuZm9jdXNPblNlbGVjdD09PSEwJiZhKGIuJHNsaWRlVHJhY2spLmNoaWxkcmVuKCkub24oXCJjbGljay5zbGlja1wiLGIuc2VsZWN0SGFuZGxlciksYi5zZXRTbGlkZUNsYXNzZXMoXCJudW1iZXJcIj09dHlwZW9mIGIuY3VycmVudFNsaWRlP2IuY3VycmVudFNsaWRlOjApLGIuc2V0UG9zaXRpb24oKSxiLmZvY3VzSGFuZGxlcigpLGIucGF1c2VkPSFiLm9wdGlvbnMuYXV0b3BsYXksYi5hdXRvUGxheSgpLGIuJHNsaWRlci50cmlnZ2VyKFwicmVJbml0XCIsW2JdKX0sYi5wcm90b3R5cGUucmVzaXplPWZ1bmN0aW9uKCl7dmFyIGI9dGhpczthKHdpbmRvdykud2lkdGgoKSE9PWIud2luZG93V2lkdGgmJihjbGVhclRpbWVvdXQoYi53aW5kb3dEZWxheSksYi53aW5kb3dEZWxheT13aW5kb3cuc2V0VGltZW91dChmdW5jdGlvbigpe2Iud2luZG93V2lkdGg9YSh3aW5kb3cpLndpZHRoKCksYi5jaGVja1Jlc3BvbnNpdmUoKSxiLnVuc2xpY2tlZHx8Yi5zZXRQb3NpdGlvbigpfSw1MCkpfSxiLnByb3RvdHlwZS5yZW1vdmVTbGlkZT1iLnByb3RvdHlwZS5zbGlja1JlbW92ZT1mdW5jdGlvbihhLGIsYyl7dmFyIGQ9dGhpcztyZXR1cm5cImJvb2xlYW5cIj09dHlwZW9mIGE/KGI9YSxhPWI9PT0hMD8wOmQuc2xpZGVDb3VudC0xKTphPWI9PT0hMD8tLWE6YSxkLnNsaWRlQ291bnQ8MXx8MD5hfHxhPmQuc2xpZGVDb3VudC0xPyExOihkLnVubG9hZCgpLGM9PT0hMD9kLiRzbGlkZVRyYWNrLmNoaWxkcmVuKCkucmVtb3ZlKCk6ZC4kc2xpZGVUcmFjay5jaGlsZHJlbih0aGlzLm9wdGlvbnMuc2xpZGUpLmVxKGEpLnJlbW92ZSgpLGQuJHNsaWRlcz1kLiRzbGlkZVRyYWNrLmNoaWxkcmVuKHRoaXMub3B0aW9ucy5zbGlkZSksZC4kc2xpZGVUcmFjay5jaGlsZHJlbih0aGlzLm9wdGlvbnMuc2xpZGUpLmRldGFjaCgpLGQuJHNsaWRlVHJhY2suYXBwZW5kKGQuJHNsaWRlcyksZC4kc2xpZGVzQ2FjaGU9ZC4kc2xpZGVzLHZvaWQgZC5yZWluaXQoKSl9LGIucHJvdG90eXBlLnNldENTUz1mdW5jdGlvbihhKXt2YXIgZCxlLGI9dGhpcyxjPXt9O2Iub3B0aW9ucy5ydGw9PT0hMCYmKGE9LWEpLGQ9XCJsZWZ0XCI9PWIucG9zaXRpb25Qcm9wP01hdGguY2VpbChhKStcInB4XCI6XCIwcHhcIixlPVwidG9wXCI9PWIucG9zaXRpb25Qcm9wP01hdGguY2VpbChhKStcInB4XCI6XCIwcHhcIixjW2IucG9zaXRpb25Qcm9wXT1hLGIudHJhbnNmb3Jtc0VuYWJsZWQ9PT0hMT9iLiRzbGlkZVRyYWNrLmNzcyhjKTooYz17fSxiLmNzc1RyYW5zaXRpb25zPT09ITE/KGNbYi5hbmltVHlwZV09XCJ0cmFuc2xhdGUoXCIrZCtcIiwgXCIrZStcIilcIixiLiRzbGlkZVRyYWNrLmNzcyhjKSk6KGNbYi5hbmltVHlwZV09XCJ0cmFuc2xhdGUzZChcIitkK1wiLCBcIitlK1wiLCAwcHgpXCIsYi4kc2xpZGVUcmFjay5jc3MoYykpKX0sYi5wcm90b3R5cGUuc2V0RGltZW5zaW9ucz1mdW5jdGlvbigpe3ZhciBhPXRoaXM7YS5vcHRpb25zLnZlcnRpY2FsPT09ITE/YS5vcHRpb25zLmNlbn
7437Rlck1vZGU9PT0hMCYmYS4kbGlzdC5jc3Moe3BhZGRpbmc6XCIwcHggXCIrYS5vcHRpb25zLmNlbnRlclBhZGRpbmd9KTooYS4kbGlzdC5oZWlnaHQoYS4kc2xpZGVzLmZpcnN0KCkub3V0ZXJIZWlnaHQoITApKmEub3B0aW9ucy5zbGlkZXNUb1Nob3cpLGEub3B0aW9ucy5jZW50ZXJNb2RlPT09ITAmJmEuJGxpc3QuY3NzKHtwYWRkaW5nOmEub3B0aW9ucy5jZW50ZXJQYWRkaW5nK1wiIDBweFwifSkpLGEubGlzdFdpZHRoPWEuJGxpc3Qud2lkdGgoKSxhLmxpc3RIZWlnaHQ9YS4kbGlzdC5oZWlnaHQoKSxhLm9wdGlvbnMudmVydGljYWw9PT0hMSYmYS5vcHRpb25zLnZhcmlhYmxlV2lkdGg9PT0hMT8oYS5zbGlkZVdpZHRoPU1hdGguY2VpbChhLmxpc3RXaWR0aC9hLm9wdGlvbnMuc2xpZGVzVG9TaG93KSxhLiRzbGlkZVRyYWNrLndpZHRoKE1hdGguY2VpbChhLnNsaWRlV2lkdGgqYS4kc2xpZGVUcmFjay5jaGlsZHJlbihcIi5zbGljay1zbGlkZVwiKS5sZW5ndGgpKSk6YS5vcHRpb25zLnZhcmlhYmxlV2lkdGg9PT0hMD9hLiRzbGlkZVRyYWNrLndpZHRoKDVlMyphLnNsaWRlQ291bnQpOihhLnNsaWRlV2lkdGg9TWF0aC5jZWlsKGEubGlzdFdpZHRoKSxhLiRzbGlkZVRyYWNrLmhlaWdodChNYXRoLmNlaWwoYS4kc2xpZGVzLmZpcnN0KCkub3V0ZXJIZWlnaHQoITApKmEuJHNsaWRlVHJhY2suY2hpbGRyZW4oXCIuc2xpY2stc2xpZGVcIikubGVuZ3RoKSkpO3ZhciBiPWEuJHNsaWRlcy5maXJzdCgpLm91dGVyV2lkdGgoITApLWEuJHNsaWRlcy5maXJzdCgpLndpZHRoKCk7YS5vcHRpb25zLnZhcmlhYmxlV2lkdGg9PT0hMSYmYS4kc2xpZGVUcmFjay5jaGlsZHJlbihcIi5zbGljay1zbGlkZVwiKS53aWR0aChhLnNsaWRlV2lkdGgtYil9LGIucHJvdG90eXBlLnNldEZhZGU9ZnVuY3Rpb24oKXt2YXIgYyxiPXRoaXM7Yi4kc2xpZGVzLmVhY2goZnVuY3Rpb24oZCxlKXtjPWIuc2xpZGVXaWR0aCpkKi0xLGIub3B0aW9ucy5ydGw9PT0hMD9hKGUpLmNzcyh7cG9zaXRpb246XCJyZWxhdGl2ZVwiLHJpZ2h0OmMsdG9wOjAsekluZGV4OmIub3B0aW9ucy56SW5kZXgtMixvcGFjaXR5OjB9KTphKGUpLmNzcyh7cG9zaXRpb246XCJyZWxhdGl2ZVwiLGxlZnQ6Yyx0b3A6MCx6SW5kZXg6Yi5vcHRpb25zLnpJbmRleC0yLG9wYWNpdHk6MH0pfSksYi4kc2xpZGVzLmVxKGIuY3VycmVudFNsaWRlKS5jc3Moe3pJbmRleDpiLm9wdGlvbnMuekluZGV4LTEsb3BhY2l0eToxfSl9LGIucHJvdG90eXBlLnNldEhlaWdodD1mdW5jdGlvbigpe3ZhciBhPXRoaXM7aWYoMT09PWEub3B0aW9ucy5zbGlkZXNUb1Nob3cmJmEub3B0aW9ucy5hZGFwdGl2ZUhlaWdodD09PSEwJiZhLm9wdGlvbnMudmVydGljYWw9PT0hMSl7dmFyIGI9YS4kc2xpZGVzLmVxKGEuY3VycmVudFNsaWRlKS5vdXRlckhlaWdodCghMCk7YS4kbGlzdC5jc3MoXCJoZWlnaHRcIixiKX19LGIucHJvdG90eXBlLnNldE9wdGlvbj1iLnByb3RvdHlwZS5zbGlja1NldE9wdGlvbj1mdW5jdGlvbigpe3ZhciBjLGQsZSxmLGgsYj10aGlzLGc9ITE7aWYoXCJvYmplY3RcIj09PWEudHlwZShhcmd1bWVudHNbMF0pPyhlPWFyZ3VtZW50c1swXSxnPWFyZ3VtZW50c1sxXSxoPVwibXVsdGlwbGVcIik6XCJzdHJpbmdcIj09PWEudHlwZShhcmd1bWVudHNbMF0pJiYoZT1hcmd1bWVudHNbMF0sZj1hcmd1bWVudHNbMV0sZz1hcmd1bWVudHNbMl0sXCJyZXNwb25zaXZlXCI9PT1hcmd1bWVudHNbMF0mJlwiYXJyYXlcIj09PWEudHlwZShhcmd1bWVudHNbMV0pP2g9XCJyZXNwb25zaXZlXCI6XCJ1bmRlZmluZWRcIiE9dHlwZW9mIGFyZ3VtZW50c1sxXSYmKGg9XCJzaW5nbGVcIikpLFwic2luZ2xlXCI9PT1oKWIub3B0aW9uc1tlXT1mO2Vsc2UgaWYoXCJtdWx0aXBsZVwiPT09aClhLmVhY2goZSxmdW5jdGlvbihhLGMpe2Iub3B0aW9uc1thXT1jfSk7ZWxzZSBpZihcInJlc3BvbnNpdmVcIj09PWgpZm9yKGQgaW4gZilpZihcImFycmF5XCIhPT1hLnR5cGUoYi5vcHRpb25zLnJlc3BvbnNpdmUpKWIub3B0aW9ucy5yZXNwb25zaXZlPVtmW2RdXTtlbHNle2ZvcihjPWIub3B0aW9ucy5yZXNwb25zaXZlLmxlbmd0aC0xO2M+PTA7KWIub3B0aW9ucy5yZXNwb25zaXZlW2NdLmJyZWFrcG9pbnQ9PT1mW2RdLmJyZWFrcG9pbnQmJmIub3B0aW9ucy5yZXNwb25zaXZlLnNwbGljZShjLDEpLGMtLTtiLm9wdGlvbnMucmVzcG9uc2l2ZS5wdXNoKGZbZF0pfWcmJihiLnVubG9hZCgpLGIucmVpbml0KCkpfSxiLnByb3RvdHlwZS5zZXRQb3NpdGlvbj1mdW5jdGlvbigpe3ZhciBhPXRoaXM7YS5zZXREaW1lbnNpb25zKCksYS5zZXRIZWlnaHQoKSxhLm9wdGlvbnMuZmFkZT09PSExP2Euc2V0Q1NTKGEuZ2V0TGVmdChhLmN1cnJlbnRTbGlkZSkpOmEuc2V0RmFkZSgpLGEuJHNsaWRlci50cmlnZ2VyKFwic2V0UG9zaXRpb25cIixbYV0pfSxiLnByb3RvdHlwZS5zZXRQcm9wcz1mdW5jdGlvbigpe3ZhciBhPXRoaXMsYj1kb2N1bWVudC5ib2R5LnN0eWxlO2EucG9zaXRpb25Qcm9wPWEub3B0aW9ucy52ZXJ0aWNhbD09PSEwP1widG9wXCI6XCJsZWZ0XCIsXCJ0b3BcIj09PWEucG9zaXRpb25Qcm9wP2EuJHNsaWRlci5hZGRDbGFzcyhcInNsaWNrLXZlcnRpY2FsXCIpOmEuJHNsaWRlci5yZW1vdmVDbGFzcyhcInNsaWNrLXZlcnRpY2FsXCIpLCh2b2lkIDAhPT1iLldlYmtpdFRyYW5zaXRpb258fHZvaWQgMCE9PWIuTW96VHJhbnNpdGlvbnx8dm9pZCAwIT09Yi5tc1RyYW5zaXRpb24pJiZhLm9wdGlvbnMudXNlQ1NTPT09ITAmJihhLmNzc1RyYW5zaXRpb25zPSEwKSxhLm9wdGlvbnMuZmFkZSYmKFwibnVtYmVyXCI9PXR5cGVvZiBhLm9wdGlvbnMuekluZGV4P2Eub3B0aW9ucy56SW5kZXg8MyYmKGEub3B0aW9ucy56SW5kZXg9Myk6YS5vcHRpb25zLnpJbmRleD1hLmRlZmF1bHRzLnpJbmRleCksdm9pZCAwIT09Yi5PVHJhbnNmb3JtJiYoYS5hbmltVHlwZT1cIk9UcmFuc2Zvcm1cIixhLnRyYW5zZm9ybVR5cGU9XCItby10cmFuc2Zvcm1cIixhLnRyYW5zaXRpb25UeXBlPVwiT1RyYW5zaXRpb25cIix2b2lkIDA9PT1iLnBlcnNwZWN0aXZlUHJvcGVydHkmJnZvaWQgMD09PWIud2Via2l0UGVyc3BlY3RpdmUmJihhLmFuaW1UeXBlPSExKSksdm9pZCAwIT09Yi5Nb3pUcmFuc2Zvcm0mJihhLmFuaW1UeXBlPVwiTW96VHJhbnNmb3JtXCIsYS50cmFuc2Zvcm1UeXBlPVwiLW1vei10cmFuc2Zvcm1cIixhLnRyYW5zaXRpb25UeXBlPVwiTW96VHJhbnNpdGlvblwiLHZvaWQgMD09PWIucGVyc3BlY3RpdmVQcm9wZXJ0eSYmdm9pZCAwPT09Yi5Nb3pQZXJzcGVjdGl2ZSYmKGEuYW5pbVR5cGU9ITEpKSx2b2lkIDAhPT1iLndlYmtpdFRyYW5zZm9ybSYmKGEuYW5pbVR5cGU9XCJ3ZWJraXRUcmFuc2Zvcm1cIixhLnRyYW5zZm9ybVR5cGU9XCItd2Via2l0LXRyYW5zZm9ybVwiLGEudHJhbnNpdGlvblR5cGU9XCJ3ZWJraXRUcmFuc2l0aW9uXCIsdm9pZCAwPT09Yi5wZXJzcGVjdGl2ZVByb3BlcnR5JiZ2b2lkIDA9PT1iLndlYmtpdFBlcnNwZWN0aXZlJiYoYS5hbmltVHlwZT0hMSkpLHZvaWQgMCE9PWIubXNUcmFuc2Zvcm0mJihhLmFuaW1UeXBlPVwibXNUcmFuc2Zvcm1cIixhLnRyYW5zZm9ybVR5cGU9XCItbXMtdHJhbnNmb3JtXCIsYS50cmFuc2l0aW9uVHlwZT1cIm1zVHJhbnNpdGlvblwiLHZvaWQgMD09PWIubXNUcmFuc2Zvcm0mJihhLmFuaW1UeXBlPSExKSksdm9pZCAwIT09Yi50cmFuc2Zvcm0mJmEuYW5pbVR5cGUhPT0hMSYmKGEuYW5pbVR5cGU9XCJ0cmFuc2Zvcm1cIixhLnRyYW5zZm9ybVR5cGU9XCJ0cmFuc2Zvcm1cIixhLnRyYW5zaXRpb25UeXBlPVwidHJhbnNpdGlvblwiKSxhLnRyYW5zZm9ybXNFbmFibGVkPWEub3B0aW9ucy51c2VUcmFuc2Zvcm0mJm51bGwhPT1hLmFuaW1UeXBlJiZhLmFuaW1UeXBlIT09ITF9LGIucHJvdG90eXBlLnNldFNsaWRlQ2xhc3Nlcz1mdW5jdGlvbihhKXt2YXIgYyxkLGUsZixiPXRoaXM7ZD1iLiRzbGlkZXIuZmluZChcIi5zbGljay1zbGlkZVwiKS5yZW1vdmVDbGFzcyhcInNsaWNrLWFjdGl2ZSBzbGljay1jZW50ZXIgc2xpY2stY3VycmVudFwiKS5hdHRyKFwiYXJpYS1oaWRkZW5cIixcInRydWVcIiksYi4kc2xpZGVzLmVxKGEpLmFkZENsYXNzKFwic2xpY2stY3VycmVudFwiKSxiLm9wdGlvbnMuY2VudGVyTW9kZT09PSEwPyhjPU1hdGguZmxvb3IoYi5vcHRpb25zLnNsaWRlc1RvU2hvdy8yKSxiLm9wdGlvbnMuaW5maW5pdGU9PT0hMCYmKGE+PWMmJmE8PWIuc2xpZGVDb3VudC0xLWM/Yi4kc2xpZGVzLnNsaWNlKGEtYyxhK2MrMSkuYWRk
7437Q2xhc3MoXCJzbGljay1hY3RpdmVcIikuYXR0cihcImFyaWEtaGlkZGVuXCIsXCJmYWxzZVwiKTooZT1iLm9wdGlvbnMuc2xpZGVzVG9TaG93K2EsXG5kLnNsaWNlKGUtYysxLGUrYysyKS5hZGRDbGFzcyhcInNsaWNrLWFjdGl2ZVwiKS5hdHRyKFwiYXJpYS1oaWRkZW5cIixcImZhbHNlXCIpKSwwPT09YT9kLmVxKGQubGVuZ3RoLTEtYi5vcHRpb25zLnNsaWRlc1RvU2hvdykuYWRkQ2xhc3MoXCJzbGljay1jZW50ZXJcIik6YT09PWIuc2xpZGVDb3VudC0xJiZkLmVxKGIub3B0aW9ucy5zbGlkZXNUb1Nob3cpLmFkZENsYXNzKFwic2xpY2stY2VudGVyXCIpKSxiLiRzbGlkZXMuZXEoYSkuYWRkQ2xhc3MoXCJzbGljay1jZW50ZXJcIikpOmE+PTAmJmE8PWIuc2xpZGVDb3VudC1iLm9wdGlvbnMuc2xpZGVzVG9TaG93P2IuJHNsaWRlcy5zbGljZShhLGErYi5vcHRpb25zLnNsaWRlc1RvU2hvdykuYWRkQ2xhc3MoXCJzbGljay1hY3RpdmVcIikuYXR0cihcImFyaWEtaGlkZGVuXCIsXCJmYWxzZVwiKTpkLmxlbmd0aDw9Yi5vcHRpb25zLnNsaWRlc1RvU2hvdz9kLmFkZENsYXNzKFwic2xpY2stYWN0aXZlXCIpLmF0dHIoXCJhcmlhLWhpZGRlblwiLFwiZmFsc2VcIik6KGY9Yi5zbGlkZUNvdW50JWIub3B0aW9ucy5zbGlkZXNUb1Nob3csZT1iLm9wdGlvbnMuaW5maW5pdGU9PT0hMD9iLm9wdGlvbnMuc2xpZGVzVG9TaG93K2E6YSxiLm9wdGlvbnMuc2xpZGVzVG9TaG93PT1iLm9wdGlvbnMuc2xpZGVzVG9TY3JvbGwmJmIuc2xpZGVDb3VudC1hPGIub3B0aW9ucy5zbGlkZXNUb1Nob3c/ZC5zbGljZShlLShiLm9wdGlvbnMuc2xpZGVzVG9TaG93LWYpLGUrZikuYWRkQ2xhc3MoXCJzbGljay1hY3RpdmVcIikuYXR0cihcImFyaWEtaGlkZGVuXCIsXCJmYWxzZVwiKTpkLnNsaWNlKGUsZStiLm9wdGlvbnMuc2xpZGVzVG9TaG93KS5hZGRDbGFzcyhcInNsaWNrLWFjdGl2ZVwiKS5hdHRyKFwiYXJpYS1oaWRkZW5cIixcImZhbHNlXCIpKSxcIm9uZGVtYW5kXCI9PT1iLm9wdGlvbnMubGF6eUxvYWQmJmIubGF6eUxvYWQoKX0sYi5wcm90b3R5cGUuc2V0dXBJbmZpbml0ZT1mdW5jdGlvbigpe3ZhciBjLGQsZSxiPXRoaXM7aWYoYi5vcHRpb25zLmZhZGU9PT0hMCYmKGIub3B0aW9ucy5jZW50ZXJNb2RlPSExKSxiLm9wdGlvbnMuaW5maW5pdGU9PT0hMCYmYi5vcHRpb25zLmZhZGU9PT0hMSYmKGQ9bnVsbCxiLnNsaWRlQ291bnQ+Yi5vcHRpb25zLnNsaWRlc1RvU2hvdykpe2ZvcihlPWIub3B0aW9ucy5jZW50ZXJNb2RlPT09ITA/Yi5vcHRpb25zLnNsaWRlc1RvU2hvdysxOmIub3B0aW9ucy5zbGlkZXNUb1Nob3csYz1iLnNsaWRlQ291bnQ7Yz5iLnNsaWRlQ291bnQtZTtjLT0xKWQ9Yy0xLGEoYi4kc2xpZGVzW2RdKS5jbG9uZSghMCkuYXR0cihcImlkXCIsXCJcIikuYXR0cihcImRhdGEtc2xpY2staW5kZXhcIixkLWIuc2xpZGVDb3VudCkucHJlcGVuZFRvKGIuJHNsaWRlVHJhY2spLmFkZENsYXNzKFwic2xpY2stY2xvbmVkXCIpO2ZvcihjPTA7ZT5jO2MrPTEpZD1jLGEoYi4kc2xpZGVzW2RdKS5jbG9uZSghMCkuYXR0cihcImlkXCIsXCJcIikuYXR0cihcImRhdGEtc2xpY2staW5kZXhcIixkK2Iuc2xpZGVDb3VudCkuYXBwZW5kVG8oYi4kc2xpZGVUcmFjaykuYWRkQ2xhc3MoXCJzbGljay1jbG9uZWRcIik7Yi4kc2xpZGVUcmFjay5maW5kKFwiLnNsaWNrLWNsb25lZFwiKS5maW5kKFwiW2lkXVwiKS5lYWNoKGZ1bmN0aW9uKCl7YSh0aGlzKS5hdHRyKFwiaWRcIixcIlwiKX0pfX0sYi5wcm90b3R5cGUuaW50ZXJydXB0PWZ1bmN0aW9uKGEpe3ZhciBiPXRoaXM7YXx8Yi5hdXRvUGxheSgpLGIuaW50ZXJydXB0ZWQ9YX0sYi5wcm90b3R5cGUuc2VsZWN0SGFuZGxlcj1mdW5jdGlvbihiKXt2YXIgYz10aGlzLGQ9YShiLnRhcmdldCkuaXMoXCIuc2xpY2stc2xpZGVcIik/YShiLnRhcmdldCk6YShiLnRhcmdldCkucGFyZW50cyhcIi5zbGljay1zbGlkZVwiKSxlPXBhcnNlSW50KGQuYXR0cihcImRhdGEtc2xpY2staW5kZXhcIikpO3JldHVybiBlfHwoZT0wKSxjLnNsaWRlQ291bnQ8PWMub3B0aW9ucy5zbGlkZXNUb1Nob3c/KGMuc2V0U2xpZGVDbGFzc2VzKGUpLHZvaWQgYy5hc05hdkZvcihlKSk6dm9pZCBjLnNsaWRlSGFuZGxlcihlKX0sYi5wcm90b3R5cGUuc2xpZGVIYW5kbGVyPWZ1bmN0aW9uKGEsYixjKXt2YXIgZCxlLGYsZyxqLGg9bnVsbCxpPXRoaXM7cmV0dXJuIGI9Ynx8ITEsaS5hbmltYXRpbmc9PT0hMCYmaS5vcHRpb25zLndhaXRGb3JBbmltYXRlPT09ITB8fGkub3B0aW9ucy5mYWRlPT09ITAmJmkuY3VycmVudFNsaWRlPT09YXx8aS5zbGlkZUNvdW50PD1pLm9wdGlvbnMuc2xpZGVzVG9TaG93P3ZvaWQgMDooYj09PSExJiZpLmFzTmF2Rm9yKGEpLGQ9YSxoPWkuZ2V0TGVmdChkKSxnPWkuZ2V0TGVmdChpLmN1cnJlbnRTbGlkZSksaS5jdXJyZW50TGVmdD1udWxsPT09aS5zd2lwZUxlZnQ/ZzppLnN3aXBlTGVmdCxpLm9wdGlvbnMuaW5maW5pdGU9PT0hMSYmaS5vcHRpb25zLmNlbnRlck1vZGU9PT0hMSYmKDA+YXx8YT5pLmdldERvdENvdW50KCkqaS5vcHRpb25zLnNsaWRlc1RvU2Nyb2xsKT92b2lkKGkub3B0aW9ucy5mYWRlPT09ITEmJihkPWkuY3VycmVudFNsaWRlLGMhPT0hMD9pLmFuaW1hdGVTbGlkZShnLGZ1bmN0aW9uKCl7aS5wb3N0U2xpZGUoZCl9KTppLnBvc3RTbGlkZShkKSkpOmkub3B0aW9ucy5pbmZpbml0ZT09PSExJiZpLm9wdGlvbnMuY2VudGVyTW9kZT09PSEwJiYoMD5hfHxhPmkuc2xpZGVDb3VudC1pLm9wdGlvbnMuc2xpZGVzVG9TY3JvbGwpP3ZvaWQoaS5vcHRpb25zLmZhZGU9PT0hMSYmKGQ9aS5jdXJyZW50U2xpZGUsYyE9PSEwP2kuYW5pbWF0ZVNsaWRlKGcsZnVuY3Rpb24oKXtpLnBvc3RTbGlkZShkKX0pOmkucG9zdFNsaWRlKGQpKSk6KGkub3B0aW9ucy5hdXRvcGxheSYmY2xlYXJJbnRlcnZhbChpLmF1dG9QbGF5VGltZXIpLGU9MD5kP2kuc2xpZGVDb3VudCVpLm9wdGlvbnMuc2xpZGVzVG9TY3JvbGwhPT0wP2kuc2xpZGVDb3VudC1pLnNsaWRlQ291bnQlaS5vcHRpb25zLnNsaWRlc1RvU2Nyb2xsOmkuc2xpZGVDb3VudCtkOmQ+PWkuc2xpZGVDb3VudD9pLnNsaWRlQ291bnQlaS5vcHRpb25zLnNsaWRlc1RvU2Nyb2xsIT09MD8wOmQtaS5zbGlkZUNvdW50OmQsaS5hbmltYXRpbmc9ITAsaS4kc2xpZGVyLnRyaWdnZXIoXCJiZWZvcmVDaGFuZ2VcIixbaSxpLmN1cnJlbnRTbGlkZSxlXSksZj1pLmN1cnJlbnRTbGlkZSxpLmN1cnJlbnRTbGlkZT1lLGkuc2V0U2xpZGVDbGFzc2VzKGkuY3VycmVudFNsaWRlKSxpLm9wdGlvbnMuYXNOYXZGb3ImJihqPWkuZ2V0TmF2VGFyZ2V0KCksaj1qLnNsaWNrKFwiZ2V0U2xpY2tcIiksai5zbGlkZUNvdW50PD1qLm9wdGlvbnMuc2xpZGVzVG9TaG93JiZqLnNldFNsaWRlQ2xhc3NlcyhpLmN1cnJlbnRTbGlkZSkpLGkudXBkYXRlRG90cygpLGkudXBkYXRlQXJyb3dzKCksaS5vcHRpb25zLmZhZGU9PT0hMD8oYyE9PSEwPyhpLmZhZGVTbGlkZU91dChmKSxpLmZhZGVTbGlkZShlLGZ1bmN0aW9uKCl7aS5wb3N0U2xpZGUoZSl9KSk6aS5wb3N0U2xpZGUoZSksdm9pZCBpLmFuaW1hdGVIZWlnaHQoKSk6dm9pZChjIT09ITA/aS5hbmltYXRlU2xpZGUoaCxmdW5jdGlvbigpe2kucG9zdFNsaWRlKGUpfSk6aS5wb3N0U2xpZGUoZSkpKSl9LGIucHJvdG90eXBlLnN0YXJ0TG9hZD1mdW5jdGlvbigpe3ZhciBhPXRoaXM7YS5vcHRpb25zLmFycm93cz09PSEwJiZhLnNsaWRlQ291bnQ+YS5vcHRpb25zLnNsaWRlc1RvU2hvdyYmKGEuJHByZXZBcnJvdy5oaWRlKCksYS4kbmV4dEFycm93LmhpZGUoKSksYS5vcHRpb25zLmRvdHM9PT0hMCYmYS5zbGlkZUNvdW50PmEub3B0aW9ucy5zbGlkZXNUb1Nob3cmJmEuJGRvdHMuaGlkZSgpLGEuJHNsaWRlci5hZGRDbGFzcyhcInNsaWNrLWxvYWRpbmdcIil9LGIucHJvdG90eXBlLnN3aXBlRGlyZWN0aW9uPWZ1bmN0aW9uKCl7dmFyIGEsYixjLGQsZT10aGlzO3JldHVybiBhPWUudG91Y2hPYmplY3Quc3RhcnRYLWUudG91Y2hPYmplY3QuY3VyWCxiPWUudG91Y2hPYmplY3Quc3RhcnRZLWUudG91Y2hPYmplY3QuY3VyWSxjPU1hdGguYXRhbjIoYixhKSxkPU1hdGgucm91bmQoMTgwKmMvTWF0aC5QSSksMD5kJiYoZD0zNjAtTWF0aC5hYnMoZCkpLDQ1Pj1kJiZkPj0wP2Uub3B0aW9ucy5ydGw9PT0hMT9cImxlZnRcIjpcInJpZ2h0XCI6MzYwPj1kJiZkPj0zMTU/ZS5vcHRpb25zLnJ0bD09PSExP1wibGVmdFwiOlwicmlnaHRcIjpkPj0xMzUmJjIyNT49ZD9lLm9wdGlvbnMucnRsPT09ITE/XCJyaWdodFwiOlwibGVmdFwiOmUub3B0aW9ucy52ZXJ0aWNhbFN3aXBpbmc9PT0hMD9kPj0zNSYmMTM1Pj1kP1wiZG93blwiOlwidXBcIjpcInZlcnRpY2FsXCJ9LGIucHJvdG90eXBlLnN3aXBlRW5kPWZ1bmN0aW9uKGEpe3ZhciBjLGQsYj10aGlzO2lmKGIuZHJhZ2dpbmc9ITEsYi5pbnRlcnJ1cHRlZD0hMSxiLnNob3VsZENsaWNrPWIudG91Y2hPYmplY3Quc3dpcGVMZW5ndGg+MTA/ITE6ITAsdm9pZCAwPT09Yi50b3VjaE9iamVjdC5jdXJYKXJldHVybiExO2lmKGIudG91Y2hPYmplY3QuZWRnZUhpdD09PSEwJiZiLiRzbGlkZXIudHJpZ2dlcihcImVkZ2VcIixbYixiLnN3aXBlRGlyZWN0aW9uKCldKSxiLnRvdWNoT2JqZWN0LnN3aXBlTGVuZ3RoPj1iLnRvdWNoT2JqZWN0Lm1pblN3aXBlKXtzd2l0Y2goZD1iLnN3aXBlRGlyZWN0aW9uKCkpe2Nhc2VcImxlZnRcIjpjYXNlXCJkb3duXCI6Yz1iLm9wdGlvbnMuc3dpcGVUb1NsaWRlP2IuY2hlY2tOYXZpZ2FibGUoYi5jdXJyZW50U2xpZGUrYi5nZXRTbGlkZUNvdW50KCkpOmIuY3VycmVudFNsaWRlK2IuZ2V0U2xpZGVDb3VudCgpLGIuY3VycmVudERpcmVjdGlvbj0wO2JyZWFrO2Nhc2VcInJpZ2h0XCI6Y2FzZVwidXBcIjpjPWIub3B0aW9ucy5zd2lwZVRvU2xpZGU/Yi5jaGVja05hdmlnYWJsZShiLmN1cnJlbnRTbGlkZS1iLmdldFNsaWRlQ291bnQoKSk6Yi5jdXJyZW50U2xpZGUtYi5nZXRTbGlkZUNvdW50KCksYi5jdXJyZW50RGlyZWN0aW9uPTF9XCJ2ZXJ0aWNhbFwiIT1kJiYoYi5zbGlkZUhhbmRsZXIoYyksYi50b3VjaE9iamVjdD17fSxiLiRzbGlkZXIudHJpZ2dlcihcInN3aXBlXCIsW2IsZF0pKX1lbHNlIGIudG91Y2hPYmplY3Quc3RhcnRYIT09Yi50b3VjaE9iamVjdC5jdXJYJiYoYi5zbGlkZUhhbmRsZXIoYi5jdXJyZW50U2xpZGUpLGIudG91Y2hPYmplY3Q9e30pfSxiLnByb3RvdHlwZS5zd2lwZUhhbmRsZXI9ZnVuY3Rpb24oYSl7dmFyIGI9dGhpcztpZighKGIub3B0aW9ucy5zd2lwZT09PSExfHxcIm9udG91Y2hlbmRcImluIGRvY3VtZW50JiZiLm9wdGlvbnMuc3dpcGU9PT0hMXx8Yi5vcHRpb25zLmRyYWdnYWJsZT09PSExJiYtMSE9PWEudHlwZS5pbmRleE9mKFwibW91c2VcIikpKXN3aXRjaChiLnRvdWNoT2JqZWN0LmZpbmdlckNvdW50PWEub3JpZ2luYWxFdmVudCYmdm9pZCAwIT09YS5vcmlnaW5hbEV2ZW50LnRvdWNoZXM/YS5vcmlnaW5hbEV2ZW50LnRvdWNoZXMubGVuZ3RoOjEsYi50b3VjaE9iamVjdC5taW5Td2lwZT1iLmxpc3RXaWR0aC9iLm9wdGlvbnMudG91Y2hUaHJlc2hvbGQsYi5vcHRpb25zLnZlcnRpY2FsU3dpcGluZz09PSEwJiYoYi50b3VjaE9iamVjdC5taW5Td2lwZT1iLmxpc3RIZWlnaHQvYi5vcHRpb25zLnRvdWNoVGhyZXNob2xkKSxhLmRhdGEuYWN0aW9uKXtjYXNlXCJzdGFydFwiOmIuc3dpcGVTdGFydChhKTticmVhaztjYXNlXCJtb3ZlXCI6Yi5zd2lwZU1vdmUoYSk7YnJlYWs7Y2FzZVwiZW5kXCI6Yi5zd2lwZUVuZChhKX19LGIucHJvdG90eXBlLnN3aXBlTW92ZT1mdW5jdGlvbihhKXt2YXIgZCxlLGYsZyxoLGI9dGhpcztyZXR1cm4gaD12b2lkIDAhPT1hLm9yaWdpbmFsRXZlbnQ/YS5vcmlnaW5hbEV2ZW50LnRvdWNoZXM6bnVsbCwhYi5kcmFnZ2luZ3x8aCYmMSE9PWgubGVuZ3RoPyExOihkPWIuZ2V0TGVmdChiLmN1cnJlbnRTbGlkZSksYi50b3VjaE9iamVjdC5jdXJYPXZvaWQgMCE9PWg/aFswXS5wYWdlWDphLmNsaWVudFgsYi50b3VjaE9iamVjdC5jdXJZPXZvaWQgMCE9PWg/aFswXS5wYWdlWTphLmNsaWVudFksYi50b3VjaE9iamVjdC5zd2lwZUxlbmd0aD1NYXRoLnJvdW5kKE1hdGguc3FydChNYXRoLnBvdyhiLnRvdWNoT2JqZWN0LmN1clgtYi50b3VjaE9iamVjdC5zdGFydFgsMikpKSxiLm9wdGlvbnMudmVydGljYWxTd2lwaW5nPT09ITAmJihiLnRvdWNoT2JqZWN0LnN3aXBlTGVuZ3RoPU1hdGgucm91bmQoTWF0aC5zcXJ0KE1hdGgucG93KGIudG91Y2hPYmplY3QuY3VyWS1iLnRvdWNoT2JqZWN0LnN0YXJ0WSwyKSkpKSxlPWIuc3dpcGVEaXJlY3Rpb24oKSxcInZlcnRpY2FsXCIhPT1lPyh2b2lkIDAhPT1hLm9yaWdpbmFsRXZlbnQmJmIudG91Y2hPYmplY3Quc3dpcGVMZW5ndGg+NCYmYS5wcmV2ZW50RGVmYXVsdCgpLGc9KGIub3B0aW9ucy5ydGw9PT0hMT8xOi0xKSooYi50b3VjaE9iamVjdC5jdXJYPmIudG91Y2hPYmplY3Quc3RhcnRYPzE6LTEpLGIub3B0aW9ucy52ZXJ0aWNhbFN3aXBpbmc9PT0hMCYmKGc9Yi50b3VjaE9iamVjdC5jdXJZPmIudG91Y2hPYmplY3Quc3RhcnRZPzE6LTEpLGY9Yi50b3VjaE9iamVjdC5zd2lwZUxlbmd0aCxiLnRvdWNoT2JqZWN0LmVkZ2VIaXQ9ITEsYi5vcHRpb25zLmluZmluaXRlPT09ITEmJigwPT09Yi5jdXJyZW50U2xpZGUmJlwicmlnaHRcIj09PWV8fGIuY3VycmVudFNsaWRlPj1iLmdldERvdENvdW50KCkmJlwibGVmdFwiPT09ZSkmJihmPWIudG91Y2hPYmplY3Quc3dpcGVMZW5ndGgqYi5vcHRpb25zLmVkZ2VGcmljdGlvbixiLnRvdWNoT2JqZWN0LmVkZ2VIaXQ9ITApLGIub3B0aW9ucy52ZXJ0aWNhbD09PSExP2Iuc3dpcGVMZWZ0PWQrZipnOmIuc3dpcGVMZWZ0PWQrZiooYi4kbGlzdC5oZWlnaHQoKS9iLmxpc3RXaWR0aCkqZyxiLm9wdGlvbnMudmVydGljYWxTd2lwaW5nPT09ITAmJihiLnN3aXBlTGVmdD1kK2YqZyksYi5vcHRpb25zLmZhZGU9PT0hMHx8Yi5vcHRpb25zLnRvdWNoTW92ZT09PSExPyExOmIuYW5pbWF0aW5nPT09ITA/KGIuc3dpcGVMZWZ0PW51bGwsITEpOnZvaWQgYi5zZXRDU1MoYi5zd2lwZUxlZnQpKTp2b2lkIDApfSxiLnByb3RvdHlwZS5zd2lwZVN0YXJ0PWZ1bmN0aW9uKGEpe3ZhciBjLGI9dGhpcztyZXR1cm4gYi5pbnRlcnJ1cHRlZD0hMCwxIT09Yi50b3VjaE9iamVjdC5maW5nZXJDb3VudHx8Yi5zbGlkZUNvdW50PD1iLm9wdGlvbnMuc2xpZGVzVG9TaG93PyhiLnRvdWNoT2JqZWN0PXt9LCExKToodm9pZCAwIT09YS5vcmlnaW5hbEV2ZW50JiZ2b2lkIDAhPT1hLm9yaWdpbmFsRXZlbnQudG91Y2hlcyYmKGM9YS5vcmlnaW5hbEV2ZW50LnRvdWNoZXNbMF0pLGIudG91Y2hPYmplY3Quc3RhcnRYPWIudG91Y2hPYmplY3QuY3VyWD12b2lkIDAhPT1jP2MucGFnZVg6YS5jbGllbnRYLGIudG91Y2hPYmplY3Quc3RhcnRZPWIudG91Y2hPYmplY3QuY3VyWT12b2lkIDAhPT1jP2MucGFnZVk6YS5jbGllbnRZLHZvaWQoYi5kcmFnZ2luZz0hMCkpfSxiLnByb3RvdHlwZS51bmZpbHRlclNsaWRlcz1iLnByb3RvdHlwZS5zbGlja1VuZmlsdGVyPWZ1bmN0aW9uKCl7dmFyIGE9dGhpcztudWxsIT09YS4kc2xpZGVzQ2FjaGUmJihhLnVubG9hZCgpLGEuJHNsaWRlVHJhY2suY2hpbGRyZW4odGhpcy5vcHRpb25zLnNsaWRlKS5kZXRhY2goKSxhLiRzbGlkZXNDYWNoZS5hcHBlbmRUbyhhLiRzbGlkZVRyYWNrKSxhLnJlaW5pdCgpKX0sYi5wcm90b3R5cGUudW5sb2FkPWZ1bmN0aW9uKCl7dmFyIGI9dGhpczthKFwiLnNsaWNrLWNsb25lZFwiLGIuJHNsaWRlcikucmVtb3ZlKCksYi4kZG90cyYmYi4kZG90cy5yZW1vdmUoKSxiLiRwcmV2QXJyb3cmJmIuaHRtbEV4cHIudGVzdChiLm9wdGlvbnMucHJldkFycm93KSYmYi4kcHJldkFycm93LnJlbW92ZSgpLGIuJG5leHRBcnJvdyYmYi5odG1sRXhwci50ZXN0KGIub3B0aW9ucy5uZXh0QXJyb3cpJiZiLiRuZXh0QXJyb3cucmVtb3ZlKCksYi4kc2xpZGVzLnJlbW92ZUNsYXNzKFwic2xpY2stc2xpZGUgc2xpY2stYWN0aXZlIHNsaWNrLXZpc2libGUgc2xpY2stY3VycmVudFwiKS5hdHRyKFwiYXJpYS1oaWRkZW5cIixcInRydWVcIikuY3NzKFwid2lkdGhcIixcIlwiKX0sYi5wcm90b3R5cGUudW5zbGljaz1mdW5jdGlvbihhKXt2YXIgYj10aGlzO2IuJHNsaWRlci50cmlnZ2VyKFwidW5zbGlja1wiLFtiLGFdKSxiLmRlc3Ryb3koKX0sYi5wcm90b3R5cGUudXBkYXRlQXJyb3dzPWZ1bmN0aW9uKCl7dmFyIGIsYT10aGlzO2I9TWF0aC5mbG9vcihhLm9wdGlvbnMuc2xpZGVzVG9TaG93LzIpLGEub3B0aW9ucy5hcnJvd3M9PT0hMCYmYS5zbGlkZUNvdW50PmEub3B0aW9ucy5zbGlkZXNUb1Nob3cmJiFhLm9wdGlvbnMuaW5maW5pdGUmJihhLiRwcmV2QXJyb3cucmVtb3ZlQ2xhc3MoXCJzbGljay1kaXNhYmxlZFwiKS5hdHRyKFwiYXJpYS1kaXNhYmxlZFwiLFwiZmFsc2VcIiksYS4kbmV4dEFycm93LnJlbW92ZUNsYXNzKFwic2xpY2stZGlzYWJsZWRcIikuYXR0cihcImFyaWEtZGlzYWJsZWRcIixcImZhbHNlXCIpLDA9PT1hLmN1cnJlbnRTbGlkZT8oYS4kcHJldkFycm93LmFkZENsYXNzKFwic2xpY2stZGlzYWJsZWRcIikuYXR0cihcImFyaWEtZGlzYWJsZWRcIixcInRydWVcIiksYS4kbmV4dEFycm93LnJlbW92ZUNsYXNzKFwic2xpY2stZGlzYWJsZWRcIikuYXR0cihcImFyaWEtZGlzYWJsZWRcIixcImZhbHNlXCIpKTphLmN1cnJlbnRTbGlkZT49YS5zbGlkZUNvdW50LWEub3B0aW9ucy5zbGlkZXNUb1Nob3cmJmEub3B0aW9ucy5jZW50ZXJNb2RlPT09ITE/KGEuJG5leHRBcnJvdy5hZGRDbGFzcyhcInNsaWNrLWRpc2FibGVkXCIpLmF0dHIoXCJhcmlhLWRpc2FibGVkXCIsXCJ0cnVlXCIpLGEuJHByZXZBcnJvdy5yZW1vdmVDbGFzcyhcInNsaWNrLWRpc2FibGVkXCIpLmF0dHIoXCJhcmlhLWRpc2FibGVkXCIsXCJmYWxzZVwiKSk6YS5jdXJyZW50U2xpZGU+PWEuc2xpZGVDb3VudC0xJiZhLm9wdGlvbnMuY2VudGVyTW9kZT09PSEwJiYoYS4kbmV4dEFycm93LmFkZENsYXNzKFwic2xpY2stZGlzYWJsZWRcIikuYXR0cihcImFyaWEtZGlzYWJsZWRcIixcInRydWVcIiksYS4kcHJldkFycm93LnJlbW92ZUNsYXNzKFwic2xpY2stZGlzYWJsZWRcIikuYXR0cihcImFyaWEtZGlzYWJsZWRcIixcImZhbHNlXCIpKSl9LGIucHJvdG90eXBlLnVwZGF0ZURvdHM9ZnVuY3Rpb24oKXt2YXIgYT10aGlzO251bGwhPT1hLiRkb3RzJiYoYS4kZG90cy5maW5kKFwibGlcIikucmVtb3ZlQ2xhc3MoXCJzbGljay1hY3RpdmVcIikuYXR0cihcImFyaWEtaGlkZGVuXCIsXCJ0cnVlXCIpLGEuJGRvdHMuZmluZChcImxpXCIpLmVxKE1hdGguZmxvb3IoYS5jdXJyZW50U2xpZGUvYS5vcHRpb25zLnNsaWRlc1RvU2Nyb2xsKSkuYWRk
7437Q2xhc3MoXCJzbGljay1hY3RpdmVcIikuYXR0cihcImFyaWEtaGlkZGVuXCIsXCJmYWxzZVwiKSl9LGIucHJvdG90eXBlLnZpc2liaWxpdHk9ZnVuY3Rpb24oKXt2YXIgYT10aGlzO2Eub3B0aW9ucy5hdXRvcGxheSYmKGRvY3VtZW50W2EuaGlkZGVuXT9hLmludGVycnVwdGVkPSEwOmEuaW50ZXJydXB0ZWQ9ITEpfSxhLmZuLnNsaWNrPWZ1bmN0aW9uKCl7dmFyIGYsZyxhPXRoaXMsYz1hcmd1bWVudHNbMF0sZD1BcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsMSksZT1hLmxlbmd0aDtmb3IoZj0wO2U+ZjtmKyspaWYoXCJvYmplY3RcIj09dHlwZW9mIGN8fFwidW5kZWZpbmVkXCI9PXR5cGVvZiBjP2FbZl0uc2xpY2s9bmV3IGIoYVtmXSxjKTpnPWFbZl0uc2xpY2tbY10uYXBwbHkoYVtmXS5zbGljayxkKSxcInVuZGVmaW5lZFwiIT10eXBlb2YgZylyZXR1cm4gZztyZXR1cm4gYX19KTsiLCIvKiFcbiAqIGltYWdlc0xvYWRlZCBQQUNLQUdFRCB2NC4xLjNcbiAqIEphdmFTY3JpcHQgaXMgYWxsIGxpa2UgXCJZb3UgaW1hZ2VzIGFyZSBkb25lIHlldCBvciB3aGF0P1wiXG4gKiBNSVQgTGljZW5zZVxuICovXG5cbiFmdW5jdGlvbihlLHQpe1wiZnVuY3Rpb25cIj09dHlwZW9mIGRlZmluZSYmZGVmaW5lLmFtZD9kZWZpbmUoXCJldi1lbWl0dGVyL2V2LWVtaXR0ZXJcIix0KTpcIm9iamVjdFwiPT10eXBlb2YgbW9kdWxlJiZtb2R1bGUuZXhwb3J0cz9tb2R1bGUuZXhwb3J0cz10KCk6ZS5FdkVtaXR0ZXI9dCgpfShcInVuZGVmaW5lZFwiIT10eXBlb2Ygd2luZG93P3dpbmRvdzp0aGlzLGZ1bmN0aW9uKCl7ZnVuY3Rpb24gZSgpe312YXIgdD1lLnByb3RvdHlwZTtyZXR1cm4gdC5vbj1mdW5jdGlvbihlLHQpe2lmKGUmJnQpe3ZhciBpPXRoaXMuX2V2ZW50cz10aGlzLl9ldmVudHN8fHt9LG49aVtlXT1pW2VdfHxbXTtyZXR1cm4tMT09bi5pbmRleE9mKHQpJiZuLnB1c2godCksdGhpc319LHQub25jZT1mdW5jdGlvbihlLHQpe2lmKGUmJnQpe3RoaXMub24oZSx0KTt2YXIgaT10aGlzLl9vbmNlRXZlbnRzPXRoaXMuX29uY2VFdmVudHN8fHt9LG49aVtlXT1pW2VdfHx7fTtyZXR1cm4gblt0XT0hMCx0aGlzfX0sdC5vZmY9ZnVuY3Rpb24oZSx0KXt2YXIgaT10aGlzLl9ldmVudHMmJnRoaXMuX2V2ZW50c1tlXTtpZihpJiZpLmxlbmd0aCl7dmFyIG49aS5pbmRleE9mKHQpO3JldHVybi0xIT1uJiZpLnNwbGljZShuLDEpLHRoaXN9fSx0LmVtaXRFdmVudD1mdW5jdGlvbihlLHQpe3ZhciBpPXRoaXMuX2V2ZW50cyYmdGhpcy5fZXZlbnRzW2VdO2lmKGkmJmkubGVuZ3RoKXt2YXIgbj0wLG89aVtuXTt0PXR8fFtdO2Zvcih2YXIgcj10aGlzLl9vbmNlRXZlbnRzJiZ0aGlzLl9vbmNlRXZlbnRzW2VdO287KXt2YXIgcz1yJiZyW29dO3MmJih0aGlzLm9mZihlLG8pLGRlbGV0ZSByW29dKSxvLmFwcGx5KHRoaXMsdCksbis9cz8wOjEsbz1pW25dfXJldHVybiB0aGlzfX0sdC5hbGxPZmY9dC5yZW1vdmVBbGxMaXN0ZW5lcnM9ZnVuY3Rpb24oKXtkZWxldGUgdGhpcy5fZXZlbnRzLGRlbGV0ZSB0aGlzLl9vbmNlRXZlbnRzfSxlfSksZnVuY3Rpb24oZSx0KXtcInVzZSBzdHJpY3RcIjtcImZ1bmN0aW9uXCI9PXR5cGVvZiBkZWZpbmUmJmRlZmluZS5hbWQ/ZGVmaW5lKFtcImV2LWVtaXR0ZXIvZXYtZW1pdHRlclwiXSxmdW5jdGlvbihpKXtyZXR1cm4gdChlLGkpfSk6XCJvYmplY3RcIj09dHlwZW9mIG1vZHVsZSYmbW9kdWxlLmV4cG9ydHM/bW9kdWxlLmV4cG9ydHM9dChlLHJlcXVpcmUoXCJldi1lbWl0dGVyXCIpKTplLmltYWdlc0xvYWRlZD10KGUsZS5FdkVtaXR0ZXIpfShcInVuZGVmaW5lZFwiIT10eXBlb2Ygd2luZG93P3dpbmRvdzp0aGlzLGZ1bmN0aW9uKGUsdCl7ZnVuY3Rpb24gaShlLHQpe2Zvcih2YXIgaSBpbiB0KWVbaV09dFtpXTtyZXR1cm4gZX1mdW5jdGlvbiBuKGUpe3ZhciB0PVtdO2lmKEFycmF
74375LmlzQXJyYXkoZSkpdD1lO2Vsc2UgaWYoXCJudW1iZXJcIj09dHlwZW9mIGUubGVuZ3RoKWZvcih2YXIgaT0wO2k8ZS5sZW5ndGg7aSsrKXQucHVzaChlW2ldKTtlbHNlIHQucHVzaChlKTtyZXR1cm4gdH1mdW5jdGlvbiBvKGUsdCxyKXtyZXR1cm4gdGhpcyBpbnN0YW5jZW9mIG8/KFwic3RyaW5nXCI9PXR5cGVvZiBlJiYoZT1kb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKGUpKSx0aGlzLmVsZW1lbnRzPW4oZSksdGhpcy5vcHRpb25zPWkoe30sdGhpcy5vcHRpb25zKSxcImZ1bmN0aW9uXCI9PXR5cGVvZiB0P3I9dDppKHRoaXMub3B0aW9ucyx0KSxyJiZ0aGlzLm9uKFwiYWx3YXlzXCIsciksdGhpcy5nZXRJbWFnZXMoKSxoJiYodGhpcy5qcURlZmVycmVkPW5ldyBoLkRlZmVycmVkKSx2b2lkIHNldFRpbWVvdXQoZnVuY3Rpb24oKXt0aGlzLmNoZWNrKCl9LmJpbmQodGhpcykpKTpuZXcgbyhlLHQscil9ZnVuY3Rpb24gcihlKXt0aGlzLmltZz1lfWZ1bmN0aW9uIHMoZSx0KXt0aGlzLnVybD1lLHRoaXMuZWxlbWVudD10LHRoaXMuaW1nPW5ldyBJbWFnZX12YXIgaD1lLmpRdWVyeSxhPWUuY29uc29sZTtvLnByb3RvdHlwZT1PYmplY3QuY3JlYXRlKHQucHJvdG90eXBlKSxvLnByb3RvdHlwZS5vcHRpb25zPXt9LG8ucHJvdG90eXBlLmdldEltYWdlcz1mdW5jdGlvbigpe3RoaXMuaW1hZ2VzPVtdLHRoaXMuZWxlbWVudHMuZm9yRWFjaCh0aGlzLmFkZEVsZW1lbnRJbWFnZXMsdGhpcyl9LG8ucHJvdG90eXBlLmFkZEVsZW1lbnRJbWFnZXM9ZnVuY3Rpb24oZSl7XCJJTUdcIj09ZS5ub2RlTmFtZSYmdGhpcy5hZGRJbWFnZShlKSx0aGlzLm9wdGlvbnMuYmFja2dyb3VuZD09PSEwJiZ0aGlzLmFkZEVsZW1lbnRCYWNrZ3JvdW5kSW1hZ2VzKGUpO3ZhciB0PWUubm9kZVR5cGU7aWYodCYmZFt0XSl7Zm9yKHZhciBpPWUucXVlcnlTZWxlY3RvckFsbChcImltZ1wiKSxuPTA7bjxpLmxlbmd0aDtuKyspe3ZhciBvPWlbbl07dGhpcy5hZGRJbWFnZShvKX1pZihcInN0cmluZ1wiPT10eXBlb2YgdGhpcy5vcHRpb25zLmJhY2tncm91bmQpe3ZhciByPWUucXVlcnlTZWxlY3RvckFsbCh0aGlzLm9wdGlvbnMuYmFja2dyb3VuZCk7Zm9yKG49MDtuPHIubGVuZ3RoO24rKyl7dmFyIHM9cltuXTt0aGlzLmFkZEVsZW1lbnRCYWNrZ3JvdW5kSW1hZ2VzKHMpfX19fTt2YXIgZD17MTohMCw5OiEwLDExOiEwfTtyZXR1cm4gby5wcm90b3R5cGUuYWRkRWxlbWVudEJhY2tncm91bmRJbWFnZXM9ZnVuY3Rpb24oZSl7dmFyIHQ9Z2V0Q29tcHV0ZWRTdHlsZShlKTtpZih0KWZvcih2YXIgaT0vdXJsXFwoKFsnXCJdKT8oLio/KVxcMVxcKS9naSxuPWkuZXhlYyh0LmJhY2tncm91bmRJbWFnZSk7bnVsbCE9PW47KXt2YXIgbz1uJiZuWzJdO28mJnRoaXMuYWRkQmFja2dyb3VuZChvLGUpLG49aS5leGVjKHQuYmFja2dyb3VuZEltYWdlKX19LG8ucHJvdG90eXBlLmFkZEltYWdlPWZ1bmN0aW9uKGUpe3ZhciB0PW5ldyByKGUpO3RoaXMuaW1hZ2VzLnB1c2godCl9LG8ucHJvdG90eXBlLmFkZEJhY2tncm91bmQ9ZnVuY3Rpb24oZSx0KXt2YXIgaT1uZXcgcyhlLHQpO3RoaXMuaW1hZ2VzLnB1c2goaSl9LG8ucHJvdG90eXBlLmNoZWNrPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gZShlLGksbil7c2V0VGltZW91dChmdW5jdGlvbigpe3QucHJvZ3Jlc3MoZSxpLG4pfSl9dmFyIHQ9dGhpcztyZXR1cm4gdGhpcy5wcm9ncmVzc2VkQ291bnQ9MCx0aGlzLmhhc0FueUJyb2tlbj0hMSx0aGlzLmltYWdlcy5sZW5ndGg/dm9pZCB0aGlzLmltYWdlcy5mb3JFYWNoKGZ1bmN0aW9uKHQpe3Qub25jZShcInByb2dyZXNzXCIsZSksdC5jaGVjaygpfSk6dm9pZCB0aGlzLmNvbXBsZXRlKCl9LG8ucHJvdG90eXBlLnByb2dyZXNzPWZ1bmN0aW9uKGUsdCxpKXt0aGlzLnByb2dyZXNzZWRDb3VudCsrLHRoaXMuaGFzQW55QnJva2VuPXRoaXMuaGFzQW55QnJva2VufHwhZS5pc0xvYWRlZCx0aGlzLmVtaXRFdmVudChcInByb2dyZXNzXCIsW3RoaXMsZSx0XSksdGhpcy5qcURlZmVycmVkJiZ0aGlzLmpxRGVmZXJyZWQubm90aWZ5JiZ0aGlzLmpxRGVmZXJyZWQubm90aWZ5KHRoaXMsZSksdGhpcy5wcm9ncmVzc2VkQ291bnQ9PXRoaXMuaW1hZ2VzLmxlbmd0aCYmdGhpcy5jb21wbGV0ZSgpLHRoaXMub3B0aW9ucy5kZWJ1ZyYmYSYmYS5sb2coXCJwcm9ncmVzczogXCIraSxlLHQpfSxvLnByb3RvdHlwZS5jb21wbGV0ZT1mdW5jdGlvbigpe3ZhciBlPXRoaXMuaGFzQW55QnJva2VuP1wiZmFpbFwiOlwiZG9uZVwiO2lmKHRoaXMuaXNDb21wbGV0ZT0hMCx0aGlzLmVtaXRFdmVudChlLFt0aGlzXSksdGhpcy5lbWl0RXZlbnQoXCJhbHdheXNcIixbdGhpc10pLHRoaXMuanFEZWZlcnJlZCl7dmFyIHQ9dGhpcy5oYXNBbnlCcm9rZW4/XCJyZWplY3RcIjpcInJlc29sdmVcIjt0aGlzLmpxRGVmZXJyZWRbdF0odGhpcyl9fSxyLnByb3RvdHlwZT1PYmplY3QuY3JlYXRlKHQucHJvdG90eXBlKSxyLnByb3RvdHlwZS5jaGVjaz1mdW5jdGlvbigpe3ZhciBlPXRoaXMuZ2V0SXNJbWFnZUNvbXBsZXRlKCk7cmV0dXJuIGU/dm9pZCB0aGlzLmNvbmZpcm0oMCE9PXRoaXMuaW1nLm5hdHVyYWxXaWR0aCxcIm5hdHVyYWxXaWR0aFwiKToodGhpcy5wcm94eUltYWdlPW5ldyBJbWFnZSx0aGlzLnByb3h5SW1hZ2UuYWRkRXZlbnRMaXN0ZW5lcihcImxvYWRcIix0aGlzKSx0aGlzLnByb3h5SW1hZ2UuYWRkRXZlbnRMaXN0ZW5lcihcImVycm9yXCIsdGhpcyksdGhpcy5pbWcuYWRkRXZlbnRMaXN0ZW5lcihcImxvYWRcIix0aGlzKSx0aGlzLmltZy5hZGRFdmVudExpc3RlbmVyKFwiZXJyb3JcIix0aGlzKSx2b2lkKHRoaXMucHJveHlJbWFnZS5zcmM9dGhpcy5pbWcuc3JjKSl9LHIucHJvdG90eXBlLmdldElzSW1hZ2VDb21wbGV0ZT1mdW5jdGlvbigpe3JldHVybiB0aGlzLmltZy5jb21wbGV0ZSYmdm9pZCAwIT09dGhpcy5pbWcubmF0dXJhbFdpZHRofSxyLnByb3RvdHlwZS5jb25maXJtPWZ1bmN0aW9uKGUsdCl7dGhpcy5pc0xvYWRlZD1lLHRoaXMuZW1pdEV2ZW50KFwicHJvZ3Jlc3NcIixbdGhpcyx0aGlzLmltZyx0XSl9LHIucHJvdG90eXBlLmhhbmRsZUV2ZW50PWZ1bmN0aW9uKGUpe3ZhciB0PVwib25cIitlLnR5cGU7dGhpc1t0XSYmdGhpc1t0XShlKX0sci5wcm90b3R5cGUub25sb2FkPWZ1bmN0aW9uKCl7dGhpcy5jb25maXJtKCEwLFwib25sb2FkXCIpLHRoaXMudW5iaW5kRXZlbnRzKCl9LHIucHJvdG90eXBlLm9uZXJyb3I9ZnVuY3Rpb24oKXt0aGlzLmNvbmZpcm0oITEsXCJvbmVycm9yXCIpLHRoaXMudW5iaW5kRXZlbnRzKCl9LHIucHJvdG90eXBlLnVuYmluZEV2ZW50cz1mdW5jdGlvbigpe3RoaXMucHJveHlJbWFnZS5yZW1vdmVFdmVudExpc3RlbmVyKFwibG9hZFwiLHRoaXMpLHRoaXMucHJveHlJbWFnZS5yZW1vdmVFdmVudExpc3RlbmVyKFwiZXJyb3JcIix0aGlzKSx0aGlzLmltZy5yZW1vdmVFdmVudExpc3RlbmVyKFwibG9hZFwiLHRoaXMpLHRoaXMuaW1nLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJlcnJvclwiLHRoaXMpfSxzLnByb3RvdHlwZT1PYmplY3QuY3JlYXRlKHIucHJvdG90eXBlKSxzLnByb3RvdHlwZS5jaGVjaz1mdW5jdGlvbigpe3RoaXMuaW1nLmFkZEV2ZW50TGlzdGVuZXIoXCJsb2FkXCIsdGhpcyksdGhpcy5pbWcuYWRkRXZlbnRMaXN0ZW5lcihcImVycm9yXCIsdGhpcyksdGhpcy5pbWcuc3JjPXRoaXMudXJsO3ZhciBlPXR
7437oaXMuZ2V0SXNJbWFnZUNvbXBsZXRlKCk7ZSYmKHRoaXMuY29uZmlybSgwIT09dGhpcy5pbWcubmF0dXJhbFdpZHRoLFwibmF0dXJhbFdpZHRoXCIpLHRoaXMudW5iaW5kRXZlbnRzKCkpfSxzLnByb3RvdHlwZS51bmJpbmRFdmVudHM9ZnVuY3Rpb24oKXt0aGlzLmltZy5yZW1vdmVFdmVudExpc3RlbmVyKFwibG9hZFwiLHRoaXMpLHRoaXMuaW1nLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJlcnJvclwiLHRoaXMpfSxzLnByb3RvdHlwZS5jb25maXJtPWZ1bmN0aW9uKGUsdCl7dGhpcy5pc0xvYWRlZD1lLHRoaXMuZW1pdEV2ZW50KFwicHJvZ3Jlc3NcIixbdGhpcyx0aGlzLmVsZW1lbnQsdF0pfSxvLm1ha2VKUXVlcnlQbHVnaW49ZnVuY3Rpb24odCl7dD10fHxlLmpRdWVyeSx0JiYoaD10LGguZm4uaW1hZ2VzTG9hZGVkPWZ1bmN0aW9uKGUsdCl7dmFyIGk9bmV3IG8odGhpcyxlLHQpO3JldHVybiBpLmpxRGVmZXJyZWQucHJvbWlzZShoKHRoaXMpKX0pfSxvLm1ha2VKUXVlcnlQbHVnaW4oKSxvfSk7IiwiS1QuTWFzb25yeSA9IHtcblx0aW5pdDogZnVuY3Rpb24oKSB7XG5cdFxuXHRcdGlmICggJCgnW2RhdGEtbWFzb25yeS1ncmlkXScpLmxlbmd0aCApIHsgXG5cdFx0XHQgIFxuXHRcdFx0dmFyICRncmlkID0gJCgnW2RhdGEtbWFzb25yeS1ncmlkXScpO1xuXG5cdFx0XHRjb25zb2xlLmxvZygkZ3JpZCk7XG5cblx0XHRcdCQuZWFjaCgkZ3JpZCwgZnVuY3Rpb24oaSxncmlkKSB7XG5cblx0XHRcdFx0dmFyIGdyaWRfb3B0aW9ucyA9ICQoZ3JpZCkuZGF0YSgnbWFzb25yeS1ncmlkJyk7XG5cblx0XHRcdFx0dmFyIG9wdGlvbnMgPSB7IFxuXHRcdFx0XHRcdHRyYW5zaXRpb25EdXJhdGlvbjogMCBcdFxuXHRcdFx0XHR9O1xuXG5cdFx0XHRcdGlmIChncmlkX29wdGlvbnMuaXRlbVNlbGVjdG9yKXsgb3B0aW9ucy5pdGVtU2VsZWN0b3IgPSBncmlkX29wdGlvbnMuaXRlbVNlbGVjdG9yOyB9XG5cdFx0XHRcdGlmIChncmlkX29wdGlvbnMuY29sdW1uV2lkdGgpeyBvcHRpb25zLmNvbHVtbldpZHRoID0gZ3JpZF9vcHRpb25zLmNvbHVtbldpZHRoOyB9XG5cdFx0XHRcdGlmIChncmlkX29wdGlvbnMucHJlc2VydmVPcmRlcil7IG9wdGlvbnMucHJlc2VydmVPcmRlciA9IGdyaWRfb3B0aW9ucy5wcmVzZXJ2ZU9yZGVyOyB9XG5cblx0XHRcdFx0dmFyICRpdGVtcyA9ICQoJ1tkYXRhLW1hc29ucnktZ3JpZF0gPiBkaXYnKTsgICAgICBcblxuXHRcdFx0XHQkZ3JpZC5vbignbGF5b3V0Q29tcGxldGUnLCBmdW5jdGlvbigpIHsgLy8gY29uc29sZS5sb2coJ2xheW91dCBsYXlvdXRDb21wbGV0ZSAnKSBcblx0XHRcdCAgXHRcdCRncmlkLmZpbmQoJy5jYXJkJykubm90KCcudmlzaWJsZScpLmFkZENsYXNzKCd2aXNpYmxlJyk7IFxuXHRcdFx0ICBcdFx0JCgnLmxvYWRlci50b3AnKS5yZW1vdmVDbGFzcygndmlzaWJsZScpOyAgICBcblx0XHRcdCAgXHR9KTsgIFxuXG5cdFx0XHRcdCQoZ3JpZCkuaW1hZ2VzTG9hZGVkKGZ1bmN0aW9uKCkgeyBcblx0XHRcdFx0IFx0Y29uc29sZS5sb2coJ2ltYWdlc0xvYWRlZCcpOyAgXG5cdFx0XHRcdCBcdCAgXG5cdFx0XHRcdCBcdHZhciBmaXJzdF9jYXJkX2ggPSAkKCRpdGVtc1swXSkuaGVpZ2h0KCk7ICAgICAgICAgIFxuXG5cdFx0XHRcdCBcdCQoZ3JpZCkuY3NzKCdtaW4taGVpZ2h0JywgZmlyc3RfY2FyZF9oKTsgXG5cblx0XHRcdFx0IFx0JChncmlkKS5tYXNvbnJ5KG9wdGlvbnMpOyAgICBcblxuXHRcdFx0XHQgIFx0Ly8gU2Nyb2xsIGRvd24gdG8gbGFzdCB2aWV3ZWQgaXRlbSAodGhpcyByZXF1aXJlcyBhbmQgaWQgb24gdGhlIGNhcmQgdXNlZCBmb3IgcG9zaXRpb24gdHJhY2tpbmcgaW4gbG9uZyBwYWdpbmF0ZWQgbGlzdHMpXG5cdFx0ICBcdFx0XHRpZiAod2luZG93LmxvY2F0aW9uLmhhc2gubGVuZ3RoID4gMiApe1xuXHRcdCAgICAgICAgICAgICAgICAkKCdodG1sLGJvZHknKS5hbmltYXRlKHsgc2Nyb2xsVG9wOiAkKHdpbmRvdy5sb2NhdGlvbi5oYXNoKS5vZmZzZXQoKS50b3AgfSwgMTAwKTtcblx0XHQgICAgICAgICAgICB9XG5cdFx0ICBcdFxuXHRcdFx0XHQgIFx0aWYgKCQoJy5sb2FkLW1vcmUnKS5sZW5ndGgpXG5cdFx0XHRcdCAgXHRcdCQoJy5sb2FkLW1vcmUnKS5hbmltYXRlKHtcIm9wYWNpdHlcIjogMX0sIDIwMCk7XG5cdFx0XHRcdCAgXHR9KTtcblx0XHRcdFx0fSk7XG5cdFx0fSBcblx0fVxufSIsIi8vIGh0dHBzOi8vZ2l0aHViLmNvbS93ZWJzYW5vdmEvbW91c2VzdG9wa1xuKGZ1bmN0aW9uKCQpIHtcbiAgICAkLmV2ZW50LnNwZWNpYWwubW91c2VzdG9wID0ge1xuICAgICAgICBzZXR1cDogZnVuY3Rpb24oZGF0YSkge1xuICAgICAgICAgICAgJCh0aGlzKS5kYXRhKCdtb3VzZXN0b3AnLCBfZGF0YShkYXRhKSlcbiAgICAgICAgICAgICAgICAgICAuYmluZCgnbW91c2VlbnRlci5tb3VzZXN0b3AnLCBfbW91c2VlbnRlcilcbiAgICAgICAgICAgICAgICAgICAuYmluZCgnbW91c2VsZWF2ZS5tb3VzZXN0b3AnLCBfbW91c2VsZWF2ZSlcbiAgICAgICAgICAgICAgICAgICAuYmluZCgnbW91c2Vtb3ZlLm1vdXNlc3RvcCcsIF9tb3VzZW1vdmUpO1xuICAgICAgICB9LFxuICAgICAgICB0ZWFyZG93bjogZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAkKHRoaXMpLnJlbW92ZURhdGEoJ21vdXNlc3RvcCcpXG4gICAgICAgICAgICAgICAgICAgLnVuYmluZCgnLm1vdXNlc3RvcCcpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIF9tb3VzZWVudGVyKCkge1xuICAgICAgICB2Y
7437XIgX3NlbGYgPSB0aGlzLFxuICAgICAgICAgICAgZGF0YSA9ICQodGhpcykuZGF0YSgnbW91c2VzdG9wJyk7XG5cbiAgICAgICAgdGhpcy5tb3ZlbWVudCA9IHRydWU7XG5cbiAgICAgICAgaWYoZGF0YS50aW1lVG9TdG9wKSB7XG4gICAgICAgICAgICB0aGlzLnRpbWVUb1N0b3BUaW1lciA9IHdpbmRvdy5zZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgIF9zZWxmLm1vdmVtZW50ID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgd2luZG93LmNsZWFyVGltZW91dChfc2VsZi50aW1lcik7XG4gICAgICAgICAgICB9LCBkYXRhLnRpbWVUb1N0b3ApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gX21vdXNlbGVhdmUoKSB7XG4gICAgICAgIHdpbmRvdy5jbGVhclRpbWVvdXQodGhpcy50aW1lcik7XG4gICAgICAgIHdpbmRvdy5jbGVhclRpbWVvdXQodGhpcy50aW1lVG9TdG9wVGltZXIpO1xuICAgIH1cbiAgICBcbiAgICBmdW5jdGlvbiBfbW91c2Vtb3ZlKCkge1xuICAgICAgICB2YXIgJGVsID0gJCh0aGlzKSxcbiAgICAgICAgICAgIGRhdGEgPSAkZWwuZGF0YSgnbW91c2VzdG9wJyk7XG5cbiAgICAgICAgaWYodGhpcy5tb3ZlbWVudCkge1xuICAgICAgICAgICAgd2luZG93LmNsZWFyVGltZW91dCh0aGlzLnRpbWVyKTtcbiAgICAgICAgICAgIHRoaXMudGltZXIgPSB3aW5kb3cuc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICAkZWwudHJpZ2dlcignbW91c2VzdG9wJyk7XG4gICAgICAgICAgICB9LCBkYXRhLmRlbGF5KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIF9kYXRhKGRhdGEpIHtcbiAgICAgICAgaWYoJC5pc051bWVyaWMoZGF0YSkpIHtcbiAgICAgICAgICAgIGRhdGEgPSB7ZGVsYXk6IGRhdGF9O1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYodHlwZW9mIGRhdGEgIT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICBkYXRhID0ge307XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gJC5leHRlbmQoe30sICQuZm4ubW91c2VzdG9wLmRlZmF1bHRzLCBkYXRhKTtcbiAgICB9XG5cbiAgICAkLmZuLm1vdXNlc3RvcCA9IGZ1bmN0aW9uKGRhdGEsIGZuKSB7XG4gICAgICAgIGlmICh0eXBlb2YgZGF0YSA9PT0gJ2Z1bmN0aW9uJykgeyBmbiA9IGRhdGE7IH1cbiAgICAgICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPiAwID8gdGhpcy5iaW5kKCdtb3VzZXN0b3AnLCBkYXRhLCBmbikgOiB0aGlzLnRyaWdnZXIoJ21vdXNlc3RvcCcpO1xuICAgIH07XG5cbiAgICAkLmZuLm1vdXNlc3RvcC5kZWZhdWx0cyA9IHtcbiAgICAgICAgZGVsYXk6IDMwMCxcbiAgICAgICAgdGltZVRvU3RvcDogbnVsbFxuICAgIH07XG59KShqUXVlcnkpO1xuIiwiLyohIG5hbm9TY3JvbGxlckpTIC0gdjAuOC43IC0gMjAxNVxuKiBodHRwOi8vamFtZXNmbG9yZW50aW5vLmdpdGh1Yi5jb20vbmFub1Njcm9sbGVySlMvXG4qIENvcHlyaWdodCAoYykgMjAxNSBKYW1lcyBGbG9yZW50aW5vOyBMaWNlbnNlZCBNSVQgKi9cbihmdW5jdGlvbihmYWN0b3J5KSB7XG4gIGlmICh0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpIHtcbiAgICByZXR1cm4gZGVmaW5lKFsnanF1ZXJ5J10sIGZ1bmN0aW9uKCQpIHtcbiAgICAgIHJldHVybiBmYWN0b3J5KCQsIHdpbmRvdywgZG9jdW1lbnQpO1xuICAgIH0pO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0Jykge1xuICAgIHJldHVybiBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZSgnanF1ZXJ5JyksIHdpbmRvdywgZG9jdW1lbnQpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBmYWN0b3J5KGpRdWVyeSwgd2luZG93LCBkb2N1bWVudCk7XG4gIH1cbn0pKGZ1bmN0aW9uKCQsIHdpbmRvdywgZG9jdW1lbnQpIHtcbiAgXCJ1c2Ugc3RyaWN0XCI7XG4gIHZhciBCUk9XU0VSX0lTX0lFNywgQlJPV1NFUl9TQ1JPTExCQVJfV0lEVEgsIERPTVNDUk9MTCwgRE9XTiwgRFJBRywgRU5URVIsIEtFWURPV04sIEtFWVVQLCBNT1VTRURPV04sIE1PVVNFRU5URVIsIE1PVVNFTU9WRSwgTU9VU0VVUCwgTU9VU0VXSEVFTCwgTmFub1Njcm9sbCwgUEFORURPV04sIFJFU0laRSwgU0NST0xMLCBTQ1JPTExCQVIsIFRPVUNITU9WRSwgVVAsIFdIRUVMLCBjQUYsIGRlZmF1bHRzLCBnZXRCcm93c2VyU2Nyb2xsYmFyV2lkdGgsIGhhc1RyYW5zZm9ybSwgaXNGRldpdGhCdWdneVNjcm9sbGJhciwgckFGLCB0cmFuc2Zvcm0sIF9lbGVtZW50U3R5bGUsIF9wcmVmaXhTdHlsZSwgX3ZlbmRvcjtcbiAgZGVmYXVsdHMgPSB7XG5cbiAgICAvKipcbiAgICAgIGEgY2xhc3NuYW1lIGZvciB0aGUgcGFuZSBlbGVtZW50LlxuICAgICAgQHByb3BlcnR5IHBhbmVDbGFzc1xuICAgICAgQHR5cGUgU3RyaW5nXG4gICAgICBAZGVmYXVsdCAnbmFuby1wYW5lJ1xuICAgICAqL1xuICAgIHBhbmVDbGFzczogJ25hbm8tcGFuZScsXG5cbiAgICAvKipcbiAgICAgIGEgY2xhc3NuYW1lIGZvciB0aGUgc2xpZGVyIGVsZW1lbnQuXG4gICAgICBAcHJvcGVydHkgc2xpZGVyQ2xhc3NcbiAgICAgIEB0eXBlIFN0cmluZ1xuICAgICAgQGRlZmF1bHQgJ25hbm8tc2xpZGVyJ1xuICAgICAqL1xuICAgIHNsaWRlckNsYXNzOiAnbmFuby1zbGlkZXInLFxuXG4gICAgLyoqXG4gICAgICBhIGNsYXNzbmFtZSBmb3IgdGhlIGNvbnRlbnQgZWxlbWVudC5cbiAgICAgIEBwcm9wZXJ0eSBjb250ZW50Q2xhc3NcbiAgICAgIEB0eXBlIFN0cmluZ1xuICAgICAgQGRlZmF1bHQgJ25hbm8tY29udGVudCdcbiAgICAgKi9cbiAgICBjb250ZW50Q2xhc3M6ICduYW5vLWNvbnRlbnQnLFxuXG4gICAgLyoqXG4gICAgICBhIGNsYXNzbmFtZSBmb3IgZW5hYmxlZCBtb2RlXG4gICAgICBAcHJvcGVydHkgZW5hYmxlZENsYXNzXG4gICAgICBAdHlwZSBTdHJpbmdcbiAgICAgIEBkZWZhdWx0ICdoYXMtc2Nyb2xsYmFyJ1xuICAgICAqL1xuICAgIGVuYWJsZWRDbGFzczogJ2hhcy1zY3JvbGxiYXInLFxuXG4gICAgLyoqXG4gICAgICBhIGNsYXNzbmFtZSBmb3IgZmxhc2hlZCBtb2RlXG4gICAgICBAcHJvcGVydHkgZmxhc2hlZENsYXNzXG4gICAgICBAd
7437HlwZSBTdHJpbmdcbiAgICAgIEBkZWZhdWx0ICdmbGFzaGVkJ1xuICAgICAqL1xuICAgIGZsYXNoZWRDbGFzczogJ2ZsYXNoZWQnLFxuXG4gICAgLyoqXG4gICAgICBhIGNsYXNzbmFtZSBmb3IgYWN0aXZlIG1vZGVcbiAgICAgIEBwcm9wZXJ0eSBhY3RpdmVDbGFzc1xuICAgICAgQHR5cGUgU3RyaW5nXG4gICAgICBAZGVmYXVsdCAnYWN0aXZlJ1xuICAgICAqL1xuICAgIGFjdGl2ZUNsYXNzOiAnYWN0aXZlJyxcblxuICAgIC8qKlxuICAgICAgYSBzZXR0aW5nIHRvIGVuYWJsZSBuYXRpdmUgc2Nyb2xsaW5nIGluIGlPUyBkZXZpY2VzLlxuICAgICAgQHByb3BlcnR5IGlPU05hdGl2ZVNjcm9sbGluZ1xuICAgICAgQHR5cGUgQm9vbGVhblxuICAgICAgQGRlZmF1bHQgZmFsc2VcbiAgICAgKi9cbiAgICBpT1NOYXRpdmVTY3JvbGxpbmc6IGZhbHNlLFxuXG4gICAgLyoqXG4gICAgICBhIHNldHRpbmcgdG8gcHJldmVudCB0aGUgcmVzdCBvZiB0aGUgcGFnZSBiZWluZ1xuICAgICAgc2Nyb2xsZWQgd2hlbiB1c2VyIHNjcm9sbHMgdGhlIGAuY29udGVudGAgZWxlbWVudC5cbiAgICAgIEBwcm9wZXJ0eSBwcmV2ZW50UGFnZVNjcm9sbGluZ1xuICAgICAgQHR5cGUgQm9vbGVhblxuICAgICAgQGRlZmF1bHQgZmFsc2VcbiAgICAgKi9cbiAgICBwcmV2ZW50UGFnZVNjcm9sbGluZzogZmFsc2UsXG5cbiAgICAvKipcbiAgICAgIGEgc2V0dGluZyB0byBkaXNhYmxlIGJpbmRpbmcgdG8gdGhlIHJlc2l6ZSBldmVudC5cbiAgICAgIEBwcm9wZXJ0eSBkaXNhYmxlUmVzaXplXG4gICAgICBAdHlwZSBCb29sZWFuXG4gICAgICBAZGVmYXVsdCBmYWxzZVxuICAgICAqL1xuICAgIGRpc2FibGVSZXNpemU6IGZhbHNlLFxuXG4gICAgLyoqXG4gICAgICBhIHNldHRpbmcgdG8gbWFrZSB0aGUgc2Nyb2xsYmFyIGFsd2F5cyB2aXNpYmxlLlxuICAgICAgQHByb3BlcnR5IGFsd2F5c1Zpc2libGVcbiAgICAgIEB0eXBlIEJvb2xlYW5cbiAgICAgIEBkZWZhdWx0IGZhbHNlXG4gICAgICovXG4gICAgYWx3YXlzVmlzaWJsZTogZmFsc2UsXG5cbiAgICAvKipcbiAgICAgIGEgZGVmYXVsdCB0aW1lb3V0IGZvciB0aGUgYGZsYXNoKClgIG1ldGhvZC5cbiAgICAgIEBwcm9wZXJ0eSBmbGFzaERlbGF5XG4gICAgICBAdHlwZSBOdW1iZXJcbiAgICAgIEBkZWZhdWx0IDE1MDBcbiAgICAgKi9cbiAgICBmbGFzaERlbGF5OiAxNTAwLFxuXG4gICAgLyoqXG4gICAgICBhIG1pbmltdW0gaGVpZ2h0IGZvciB0aGUgYC5zbGlkZXJgIGVsZW1lbnQuXG4gICAgICBAcHJvcGVydHkgc2xpZGVyTWluSGVpZ2h0XG4gICAgICBAdHlwZSBOdW1iZXJcbiAgICAgIEBkZWZhdWx0IDIwXG4gICAgICovXG4gICAgc2xpZGVyTWluSGVpZ2h0OiAyMCxcblxuICAgIC8qKlxuICAgICAgYSBtYXhpbXVtIGhlaWdodCBmb3IgdGhlIGAuc2xpZGVyYCBlbGVtZW50LlxuICAgICAgQHByb3BlcnR5IHNsaWRlck1heEhlaWdodFxuICAgICAgQHR5cGUgTnVtYmVyXG4gICAgICBAZGVmYXVsdCBudWxsXG4gICAgICovXG4gICAgc2xpZGVyTWF4SGVpZ2h0OiBudWxsLFxuXG4gICAgLyoqXG4gICAgICBhbiBhbHRlcm5hdGUgZG9jdW1lbnQgY29udGV4dC5cbiAgICAgIEBwcm9wZXJ0eSBkb2N1bWVudENvbnRleHRcbiAgICAgIEB0eXBlIERvY3VtZW50XG4gICAgICBAZGVmYXVsdCBudWxsXG4gICAgICovXG4gICAgZG9jdW1lbnRDb250ZXh0OiBudWxsLFxuXG4gICAgLyoqXG4gICAgICBhbiBhbHRlcm5hdGUgd2luZG93IGNvbnRleHQuXG4gICAgICBAcHJvcGVydHkgd2luZG93Q29udGV4dFxuICAgICAgQHR5cGUgV2luZG93XG4gICAgICBAZGVmYXVsdCBudWxsXG4gICAgICovXG4gICAgd2luZG93Q29udGV4dDogbnVsbFxuICB9O1xuXG4gIC8qKlxuICAgIEBwcm9wZXJ0eSBTQ1JPTExCQVJcbiAgICBAdHlwZSBTdHJpbmdcbiAgICBAc3RhdGljXG4gICAgQGZpbmFsXG4gICAgQHByaXZhdGVcbiAgICovXG4gIFNDUk9MTEJBUiA9ICdzY3JvbGxiYXInO1xuXG4gIC8qKlxuICAgIEBwcm9wZXJ0eSBTQ1JPTExcbiAgICBAdHlwZSBTdHJpbmdcbiAgICBAc3RhdGljXG4gICAgQGZpbmFsXG4gICAgQHByaXZhdGVcbiAgICovXG4gIFNDUk9MTCA9ICdzY3JvbGwnO1xuXG4gIC8qKlxuICAgIEBwcm9wZXJ0eSBNT1VTRURPV05cbiAgICBAdHlwZSBTdHJpbmdcbiAgICBAZmluYWxcbiAgICBAcHJpdmF0ZVxuICAgKi9cbiAgTU9VU0VET1dOID0gJ21vdXNlZG93bic7XG5cbiAgLyoqXG4gICAgQHByb3BlcnR5IE1PVVNFRU5URVJcbiAgICBAdHlwZSBTdHJpbmdcbiAgICBAZmluYWxcbiAgICBAcHJpdmF0ZVxuICAgKi9cbiAgTU9VU0VFTlRFUiA9ICdtb3VzZWVudGVyJztcblxuICAvKipcbiAgICBAcHJvcGVydHkgTU9VU0VNT1ZFXG4gICAgQHR5cGUgU3RyaW5nXG4gICAgQHN0YXRpY1xuICAgIEBmaW5hbFxuICAgIEBwcml2YXRlXG4gICAqL1xuICBNT1VTRU1PVkUgPSAnbW91c2Vtb3ZlJztcblxuICAvKipcbiAgICBAcHJvcGVydHkgTU9VU0VXSEVFTFxuICAgIEB0eXBlIFN0cmluZ1xuICAgIEBmaW5hbFxuICAgIEBwcml2YXRlXG4gICAqL1xuICBNT1VTRVdIRUVMID0gJ21vdXNld2hlZWwnO1xuXG4gIC8qKlxuICAgIEBwcm9wZXJ0eSBNT1VTRVVQXG4gICAgQHR5cGUgU3RyaW5nXG4gICAgQHN0YXRpY1xuICAgIEBmaW5hbFxuICAgIEBwcml2YXRlXG4gICAqL1xuICBNT1VTRVVQID0gJ21vdXNldXAnO1xuXG4gIC8qKlxuICAgIEBwcm9wZXJ0eSBSRVNJWkVcbiAgICBAdHlwZSBTdHJpbmdcbiAgICBAZmluYWxcbiAgICBAcHJpdmF0ZVxuICAgKi9cbiAgUkVTSVpFID0gJ3Jlc2l6ZSc7XG5cbiAgLyoqXG4gICAgQHByb3BlcnR5IERSQUdcbiAgICBAdHlwZSBTdHJpbmdcbiAgICBAc3RhdGljXG4gICAgQGZpbmFsXG4gICAgQHByaXZhdGVcbiAgICovXG4gIERSQUcgPSAnZHJhZyc7XG5cbiAgLyoqXG4gICAgQHByb3BlcnR5IEVOVEVSXG4gICAgQHR5cGUgU3RyaW5nXG4gICAgQHN0YXRpY1xuICAgIEBmaW5hbFxuICAgIEBwcml2YXRlXG4gICAqL1xuICBFTlRFUiA9ICdlbnRlcic7XG5cbiAgLyoqXG4gICAgQHByb3BlcnR5IFVQXG4gICAgQHR5cGUgU3RyaW5nXG4gICAgQHN0YXRpY1xuICAgIEBmaW5hbFxuICAgIEBwcml2YXRlXG4gICAqL1xuICBVUCA9ICd1cCc7XG5cbiAgLyoqXG4gICAgQHByb3BlcnR5IFBBTkVET1dOXG4gICAgQHR5cGUgU3RyaW5nXG4gICAgQHN0YXRpY1xuICAgIEBmaW5hbFxuICAgIEBwcml2YXRlXG4gICAqL1xuICBQQU5FRE9XTiA9ICdwYW5lZG93bic7XG5cbiAgLyoqXG4gICAgQHByb3BlcnR5IERPTVNDUk9MTFxuICAgIEB0eXBlIFN0cmluZ1xuICAgIEBzdGF0aWNcbiAgICBAZmluYWxcbiAgICBAcHJpdmF0ZVxuICAgKi9cbiAgRE9NU0NST0xMID0gJ0RPTU1vdXNlU2Nyb2xsJztcblxuICAvKipcbiAgICBAcHJvcGVydHkgRE9XTlxuICAgIEB0eXBlIFN0cmluZ1xuICAgIEBzdGF0aWNcbiAgICBAZmluYWxcbiAgICBAcHJpdmF0ZVxuICAgKi9cbiAgRE9XTiA9ICdkb3duJztcblxuICAvKipcbiAgICBAcHJvcGVydHkgV0hFRUxcbiAgICBAdHlwZSBTdHJpbmdcbiAgICBAc3RhdGljXG4gICAgQGZ
7437pbmFsXG4gICAgQHByaXZhdGVcbiAgICovXG4gIFdIRUVMID0gJ3doZWVsJztcblxuICAvKipcbiAgICBAcHJvcGVydHkgS0VZRE9XTlxuICAgIEB0eXBlIFN0cmluZ1xuICAgIEBzdGF0aWNcbiAgICBAZmluYWxcbiAgICBAcHJpdmF0ZVxuICAgKi9cbiAgS0VZRE9XTiA9ICdrZXlkb3duJztcblxuICAvKipcbiAgICBAcHJvcGVydHkgS0VZVVBcbiAgICBAdHlwZSBTdHJpbmdcbiAgICBAc3RhdGljXG4gICAgQGZpbmFsXG4gICAgQHByaXZhdGVcbiAgICovXG4gIEtFWVVQID0gJ2tleXVwJztcblxuICAvKipcbiAgICBAcHJvcGVydHkgVE9VQ0hNT1ZFXG4gICAgQHR5cGUgU3RyaW5nXG4gICAgQHN0YXRpY1xuICAgIEBmaW5hbFxuICAgIEBwcml2YXRlXG4gICAqL1xuICBUT1VDSE1PVkUgPSAndG91Y2htb3ZlJztcblxuICAvKipcbiAgICBAcHJvcGVydHkgQlJPV1NFUl9JU19JRTdcbiAgICBAdHlwZSBCb29sZWFuXG4gICAgQHN0YXRpY1xuICAgIEBmaW5hbFxuICAgIEBwcml2YXRlXG4gICAqL1xuICBCUk9XU0VSX0lTX0lFNyA9IHdpbmRvdy5uYXZpZ2F0b3IuYXBwTmFtZSA9PT0gJ01pY3Jvc29mdCBJbnRlcm5ldCBFeHBsb3JlcicgJiYgL21zaWUgNy4vaS50ZXN0KHdpbmRvdy5uYXZpZ2F0b3IuYXBwVmVyc2lvbikgJiYgd2luZG93LkFjdGl2ZVhPYmplY3Q7XG5cbiAgLyoqXG4gICAgQHByb3BlcnR5IEJST1dTRVJfU0NST0xMQkFSX1dJRFRIXG4gICAgQHR5cGUgTnVtYmVyXG4gICAgQHN0YXRpY1xuICAgIEBkZWZhdWx0IG51bGxcbiAgICBAcHJpdmF0ZVxuICAgKi9cbiAgQlJPV1NFUl9TQ1JPTExCQVJfV0lEVEggPSBudWxsO1xuICByQUYgPSB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lO1xuICBjQUYgPSB3aW5kb3cuY2FuY2VsQW5pbWF0aW9uRnJhbWU7XG4gIF9lbGVtZW50U3R5bGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKS5zdHlsZTtcbiAgX3ZlbmRvciA9IChmdW5jdGlvbigpIHtcbiAgICB2YXIgaSwgdHJhbnNmb3JtLCB2ZW5kb3IsIHZlbmRvcnMsIF9pLCBfbGVuO1xuICAgIHZlbmRvcnMgPSBbJ3QnLCAnd2Via2l0VCcsICdNb3pUJywgJ21zVCcsICdPVCddO1xuICAgIGZvciAoaSA9IF9pID0gMCwgX2xlbiA9IHZlbmRvcnMubGVuZ3RoOyBfaSA8IF9sZW47IGkgPSArK19pKSB7XG4gICAgICB2ZW5kb3IgPSB2ZW5kb3JzW2ldO1xuICAgICAgdHJhbnNmb3JtID0gdmVuZG9yc1tpXSArICdyYW5zZm9ybSc7XG4gICAgICBpZiAodHJhbnNmb3JtIGluIF9lbGVtZW50U3R5bGUpIHtcbiAgICAgICAgcmV0dXJuIHZlbmRvcnNbaV0uc3Vic3RyKDAsIHZlbmRvcnNbaV0ubGVuZ3RoIC0gMSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfSkoKTtcbiAgX3ByZWZpeFN0eWxlID0gZnVuY3Rpb24oc3R5bGUpIHtcbiAgICBpZiAoX3ZlbmRvciA9PT0gZmFsc2UpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKF92ZW5kb3IgPT09ICcnKSB7XG4gICAgICByZXR1cm4gc3R5bGU7XG4gICAgfVxuICAgIHJldHVybiBfdmVuZG9yICsgc3R5bGUuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBzdHlsZS5zdWJzdHIoMSk7XG4gIH07XG4gIHRyYW5zZm9ybSA9IF9wcmVmaXhTdHlsZSgndHJhbnNmb3JtJyk7XG4gIGhhc1RyYW5zZm9ybSA9IHRyYW5zZm9ybSAhPT0gZmFsc2U7XG5cbiAgLyoqXG4gICAgUmV0dXJucyBicm93c2VyJ3MgbmF0aXZlIHNjcm9sbGJhciB3aWR0aFxuICAgIEBtZXRob2QgZ2V0QnJvd3NlclNjcm9sbGJhcldpZHRoXG4gICAgQHJldHVybiB7TnVtYmVyfSB0aGUgc2Nyb2xsYmFyIHdpZHRoIGluIHBpeGVsc1xuICAgIEBzdGF0aWNcbiAgICBAcHJpdmF0ZVxuICAgKi9cbiAgZ2V0QnJvd3NlclNjcm9sbGJhcldpZHRoID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIG91dGVyLCBvdXRlclN0eWxlLCBzY3JvbGxiYXJXaWR0aDtcbiAgICBvdXRlciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICAgIG91dGVyU3R5bGUgPSBvdXRlci5zdHlsZTtcbiAgICBvdXRlclN0eWxlLnBvc2l0aW9uID0gJ2Fic29sdXRlJztcbiAgICBvdXRlclN0eWxlLndpZHRoID0gJzEwMHB4JztcbiAgICBvdXRlclN0eWxlLmhlaWdodCA9ICcxMDBweCc7XG4gICAgb3V0ZXJTdHlsZS5vdmVyZmxvdyA9IFNDUk9MTDtcbiAgICBvdXRlclN0eWxlLnRvcCA9ICctOTk5OXB4JztcbiAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKG91dGVyKTtcbiAgICBzY3JvbGxiYXJXaWR0aCA9IG91dGVyLm9mZnNldFdpZHRoIC0gb3V0ZXIuY2xpZW50V2lkdGg7XG4gICAgZG9jdW1lbnQuYm9keS5yZW1vdmVDaGlsZChvdXRlcik7XG4gICAgcmV0dXJuIHNjcm9sbGJhcldpZHRoO1xuICB9O1xuICBpc0ZGV2l0aEJ1Z2d5U2Nyb2xsYmFyID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGlzT1NYRkYsIHVhLCB2ZXJzaW9uO1xuICAgIHVhID0gd2luZG93Lm5hdmlnYXRvci51c2VyQWdlbnQ7XG4gICAgaXNPU1hGRiA9IC8oPz0uK01hYyBPUyBYKSg/PS4rRmlyZWZveCkvLnRlc3QodWEpO1xuICAgIGlmICghaXNPU1hGRikge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB2ZXJzaW9uID0gL0ZpcmVmb3hcXC9cXGR7Mn1cXC4vLmV4ZWModWEpO1xuICAgIGlmICh2ZXJzaW9uKSB7XG4gICAgICB2ZXJzaW9uID0gdmVyc2lvblswXS5yZXBsYWNlKC9cXEQrL2csICcnKTtcbiAgICB9XG4gICAgcmV0dXJuIGlzT1NYRkYgJiYgK3ZlcnNpb24gPiAyMztcbiAgfTtcblxuICAvKipcbiAgICBAY2xhc3MgTmFub1Njcm9sbFxuICAgIEBwYXJhbSBlbGVtZW50IHtIVE1MRWxlbWVudHxOb2RlfSB0aGUgbWFpbiBlbGVtZW50XG4gICAgQHBhcmFtIG9wdGlvbnMge09iamVjdH0gbmFub1Njcm9sbGVyJ3Mgb3B0aW9uc1xuICAgIEBjb25zdHJ1Y3RvclxuICAgKi9cbiAgTmFub1Njcm9sbCA9IChmdW5jdGlvbigpIHtcbiAgICBmdW5jdGlvbiBOYW5vU2Nyb2xsKGVsLCBvcHRpb25zKSB7XG4gICAgICB0aGlzLmVsID0gZWw7XG4gICAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuICAgICAgQlJPV1NFUl9TQ1JPTExCQVJfV0lEVEggfHwgKEJST1dTRVJfU0NST0xMQkFSX1dJRFRIID0gZ2V0QnJvd3NlclNjcm9sbGJhcldpZHRoKCkpO1xuICAgICAgdGhpcy4kZWwgPSAkKHRoaXMuZWwpO1xuICAgICAgdGhpcy5kb2MgPSAkKHRoaXMub3B0aW9ucy5kb2N1bWVudENvbnRleHQgfHwgZG9jdW1lbnQpO1xuICAgICAgdGhpcy53aW4gPSAkKHRoaXMub3B0aW9ucy53aW5kb3dDb250ZXh0IHx8IHdpbmRvdyk7XG4gICAgICB0aGlzLmJvZHkgPSB0aGlzLmRvYy5maW5kKCdib2R5Jyk7XG4gICAgICB0aGlzLiRjb250ZW50ID0gdGhpcy4kZWwuY2hpbGRyZW4oXCIuXCIgKyB0aGlzLm9wdGlvbnMuY29udGVudENsYXNzKTtcbiAgICAgIHRoaXMuJGNvbnRlbnQuYXR0cigndGFiaW5kZXgnLCB0aGlzLm9wdGlvbnMudGFiSW5kZXggfHwgMCk7XG4gICAgICB0aGlzLmNvbnRlbnQgPSB0aGlzLiRjb250ZW50WzBdO1xuICAgICAgdGhpcy5wcmV2aW91c1Bvc2l0aW9uID0gMDtcbiAgICAgIGlmICh0aGlzLm9wdGlvbnMuaU9TTmF0aXZlU2Nyb2xsaW5nICYmICh0aGlzLmVsLnN0eWxlLldlYmtpdE92ZXJmbG93U2Nyb2xsaW5nICE9IG51bGwpKSB7XG4gICAgICAgI
7437HRoaXMubmF0aXZlU2Nyb2xsaW5nKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmdlbmVyYXRlKCk7XG4gICAgICB9XG4gICAgICB0aGlzLmNyZWF0ZUV2ZW50cygpO1xuICAgICAgdGhpcy5hZGRFdmVudHMoKTtcbiAgICAgIHRoaXMucmVzZXQoKTtcbiAgICB9XG5cblxuICAgIC8qKlxuICAgICAgUHJldmVudHMgdGhlIHJlc3Qgb2YgdGhlIHBhZ2UgYmVpbmcgc2Nyb2xsZWRcbiAgICAgIHdoZW4gdXNlciBzY3JvbGxzIHRoZSBgLm5hbm8tY29udGVudGAgZWxlbWVudC5cbiAgICAgIEBtZXRob2QgcHJldmVudFNjcm9sbGluZ1xuICAgICAgQHBhcmFtIGV2ZW50IHtFdmVudH1cbiAgICAgIEBwYXJhbSBkaXJlY3Rpb24ge1N0cmluZ30gU2Nyb2xsIGRpcmVjdGlvbiAodXAgb3IgZG93bilcbiAgICAgIEBwcml2YXRlXG4gICAgICovXG5cbiAgICBOYW5vU2Nyb2xsLnByb3RvdHlwZS5wcmV2ZW50U2Nyb2xsaW5nID0gZnVuY3Rpb24oZSwgZGlyZWN0aW9uKSB7XG4gICAgICBpZiAoIXRoaXMuaXNBY3RpdmUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKGUudHlwZSA9PT0gRE9NU0NST0xMKSB7XG4gICAgICAgIGlmIChkaXJlY3Rpb24gPT09IERPV04gJiYgZS5vcmlnaW5hbEV2ZW50LmRldGFpbCA+IDAgfHwgZGlyZWN0aW9uID09PSBVUCAmJiBlLm9yaWdpbmFsRXZlbnQuZGV0YWlsIDwgMCkge1xuICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChlLnR5cGUgPT09IE1PVVNFV0hFRUwpIHtcbiAgICAgICAgaWYgKCFlLm9yaWdpbmFsRXZlbnQgfHwgIWUub3JpZ2luYWxFdmVudC53aGVlbERlbHRhKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChkaXJlY3Rpb24gPT09IERPV04gJiYgZS5vcmlnaW5hbEV2ZW50LndoZWVsRGVsdGEgPCAwIHx8IGRpcmVjdGlvbiA9PT0gVVAgJiYgZS5vcmlnaW5hbEV2ZW50LndoZWVsRGVsdGEgPiAwKSB7XG4gICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcblxuXG4gICAgLyoqXG4gICAgICBFbmFibGUgaU9TIG5hdGl2ZSBzY3JvbGxpbmdcbiAgICAgIEBtZXRob2QgbmF0aXZlU2Nyb2xsaW5nXG4gICAgICBAcHJpdmF0ZVxuICAgICAqL1xuXG4gICAgTmFub1Njcm9sbC5wcm90b3R5cGUubmF0aXZlU2Nyb2xsaW5nID0gZnVuY3Rpb24oKSB7XG4gICAgICB0aGlzLiRjb250ZW50LmNzcyh7XG4gICAgICAgIFdlYmtpdE92ZXJmbG93U2Nyb2xsaW5nOiAndG91Y2gnXG4gICAgICB9KTtcbiAgICAgIHRoaXMuaU9TTmF0aXZlU2Nyb2xsaW5nID0gdHJ1ZTtcbiAgICAgIHRoaXMuaXNBY3RpdmUgPSB0cnVlO1xuICAgIH07XG5cblxuICAgIC8qKlxuICAgICAgVXBkYXRlcyB0aG9zZSBuYW5vU2Nyb2xsZXIgcHJvcGVydGllcyB0aGF0XG4gICAgICBhcmUgcmVsYXRlZCB0byBjdXJyZW50IHNjcm9sbGJhciBwb3NpdGlvbi5cbiAgICAgIEBtZXRob2QgdXBkYXRlU2Nyb2xsVmFsdWVzXG4gICAgICBAcHJpdmF0ZVxuICAgICAqL1xuXG4gICAgTmFub1Njcm9sbC5wcm90b3R5cGUudXBkYXRlU2Nyb2xsVmFsdWVzID0gZnVuY3Rpb24oKSB7XG4gICAgICB2Y
7437XIgY29udGVudCwgZGlyZWN0aW9uO1xuICAgICAgY29udGVudCA9IHRoaXMuY29udGVudDtcbiAgICAgIHRoaXMubWF4U2Nyb2xsVG9wID0gY29udGVudC5zY3JvbGxIZWlnaHQgLSBjb250ZW50LmNsaWVudEhlaWdodDtcbiAgICAgIHRoaXMucHJldlNjcm9sbFRvcCA9IHRoaXMuY29udGVudFNjcm9sbFRvcCB8fCAwO1xuICAgICAgdGhpcy5jb250ZW50U2Nyb2xsVG9wID0gY29udGVudC5zY3JvbGxUb3A7XG4gICAgICBkaXJlY3Rpb24gPSB0aGlzLmNvbnRlbnRTY3JvbGxUb3AgPiB0aGlzLnByZXZpb3VzUG9zaXRpb24gPyBcImRvd25cIiA6IHRoaXMuY29udGVudFNjcm9sbFRvcCA8IHRoaXMucHJldmlvdXNQb3NpdGlvbiA/IFwidXBcIiA6IFwic2FtZVwiO1xuICAgICAgdGhpcy5wcmV2aW91c1Bvc2l0aW9uID0gdGhpcy5jb250ZW50U2Nyb2xsVG9wO1xuICAgICAgaWYgKGRpcmVjdGlvbiAhPT0gXCJzYW1lXCIpIHtcbiAgICAgICAgdGhpcy4kZWwudHJpZ2dlcigndXBkYXRlJywge1xuICAgICAgICAgIHBvc2l0aW9uOiB0aGlzLmNvbnRlbnRTY3JvbGxUb3AsXG4gICAgICAgICAgbWF4aW11bTogdGhpcy5tYXhTY3JvbGxUb3AsXG4gICAgICAgICAgZGlyZWN0aW9uOiBkaXJlY3Rpb25cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBpZiAoIXRoaXMuaU9TTmF0aXZlU2Nyb2xsaW5nKSB7XG4gICAgICAgIHRoaXMubWF4U2xpZGVyVG9wID0gdGhpcy5wYW5lSGVpZ2h0IC0gdGhpcy5zbGlkZXJIZWlnaHQ7XG4gICAgICAgIHRoaXMuc2xpZGVyVG9wID0gdGhpcy5tYXhTY3JvbGxUb3AgPT09IDAgPyAwIDogdGhpcy5jb250ZW50U2Nyb2xsVG9wICogdGhpcy5tYXhTbGlkZXJUb3AgLyB0aGlzLm1heFNjcm9sbFRvcDtcbiAgICAgIH1cbiAgICB9O1xuXG5cbiAgICAvKipcbiAgICAgIFVwZGF0ZXMgQ1NTIHN0eWxlcyBmb3IgY3VycmVudCBzY3JvbGwgcG9zaXRpb24uXG4gICAgICBVc2VzIENTUyAyZCB0cmFuc2Zyb21zIGFuZCBgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZWAgaWYgYXZhaWxhYmxlLlxuICAgICAgQG1ldGhvZCBzZXRPblNjcm9sbFN0eWxlc1xuICAgICAgQHByaXZhdGVcbiAgICAgKi9cblxuICAgIE5hbm9TY3JvbGwucHJvdG90eXBlLnNldE9uU2Nyb2xsU3R5bGVzID0gZnVuY3Rpb24oKSB7XG4gICAgICB2Y
7437XIgY3NzVmFsdWU7XG4gICAgICBpZiAoaGFzVHJhbnNmb3JtKSB7XG4gICAgICAgIGNzc1ZhbHVlID0ge307XG4gICAgICAgIGNzc1ZhbHVlW3RyYW5zZm9ybV0gPSBcInRyYW5zbGF0ZSgwLCBcIiArIHRoaXMuc2xpZGVyVG9wICsgXCJweClcIjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNzc1ZhbHVlID0ge1xuICAgICAgICAgIHRvcDogdGhpcy5zbGlkZXJUb3BcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIGlmIChyQUYpIHtcbiAgICAgICAgaWYgKGNBRiAmJiB0aGlzLnNjcm9sbFJBRikge1xuICAgICAgICAgIGNBRih0aGlzLnNjcm9sbFJBRik7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zY3JvbGxSQUYgPSByQUYoKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgX3RoaXMuc2Nyb2xsUkFGID0gbnVsbDtcbiAgICAgICAgICAgIHJldHVybiBfdGhpcy5zbGlkZXIuY3NzKGNzc1ZhbHVlKTtcbiAgICAgICAgICB9O1xuICAgICAgICB9KSh0aGlzKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnNsaWRlci5jc3MoY3NzVmFsdWUpO1xuICAgICAgfVxuICAgIH07XG5cblxuICAgIC8qKlxuICAgICAgQ3JlYXRlcyBldmVudCByZWxhdGVkIG1ldGhvZHNcbiAgICAgIEBtZXRob2QgY3JlYXRlRXZlbnRzXG4gICAgICBAcHJpdmF0ZVxuICAgICAqL1xuXG4gICAgTmFub1Njcm9sbC5wcm90b3R5cGUuY3JlYXRlRXZlbnRzID0gZnVuY3Rpb24oKSB7XG4gICAgICB0aGlzLmV2ZW50cyA9IHtcbiAgICAgICAgZG93bjogKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGUpIHtcbiAgICAgICAgICAgIF90aGlzLmlzQmVpbmdEcmFnZ2VkID0gdHJ1ZTtcbiAgICAgICAgICAgIF90aGlzLm9mZnNldFkgPSBlLnBhZ2VZIC0gX3RoaXMuc2xpZGVyLm9mZnNldCgpLnRvcDtcbiAgICAgICAgICAgIGlmICghX3RoaXMuc2xpZGVyLmlzKGUudGFyZ2V0KSkge1xuICAgICAgICAgICAgICBfdGhpcy5vZmZzZXRZID0gMDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIF90aGlzLnBhbmUuYWRkQ2xhc3MoX3RoaXMub3B0aW9ucy5hY3RpdmVDbGFzcyk7XG4gICAgICAgICAgICBfdGhpcy5kb2MuYmluZChNT1VTRU1PVkUsIF90aGlzLmV2ZW50c1tEUkFHXSkuYmluZChNT1VTRVVQLCBfdGhpcy5ldmVudHNbVVBdKTtcbiAgICAgICAgICAgIF90aGlzLmJvZHkuYmluZChNT1VTRUVOVEVSLCBfdGhpcy5ldmVudHNbRU5URVJdKTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9O1xuICAgICAgICB9KSh0aGlzKSxcbiAgICAgICAgZHJhZzogKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGUpIHtcbiAgICAgICAgICAgIF90aGlzLnNsaWRlclkgPSBlLnBhZ2VZIC0gX3RoaXMuJGVsLm9mZnNldCgpLnRvcCAtIF90aGlzLnBhbmVUb3AgLSAoX3RoaXMub2Zmc2V0WSB8fCBfdGhpcy5zbGlkZXJIZWlnaHQgKiAwLjUpO1xuICAgICAgICAgICAgX3RoaXMuc2Nyb2xsKCk7XG4gICAgICAgICAgICBpZiAoX3RoaXMuY29udGVudFNjcm9sbFRvcCA+PSBfdGhpcy5tYXhTY3JvbGxUb3AgJiYgX3RoaXMucHJldlNjcm9sbFRvcCAhPT0gX3RoaXMubWF4U2Nyb2xsVG9wKSB7XG4gICAgICAgICAgICAgIF90aGlzLiRlbC50cmlnZ2VyKCdzY3JvbGxlbmQnKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoX3RoaXMuY29udGVudFNjcm9sbFRvcCA9PT0gMCAmJiBfdGhpcy5wcmV2U2Nyb2xsVG9wICE9PSAwKSB7XG4gICAgICAgICAgICAgIF90aGlzLiRlbC50cmlnZ2VyKCdzY3JvbGx0b3AnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9O1xuICAgICAgICB9KSh0aGlzKSxcbiAgICAgICAgdXA6IChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICAgIHJldHVybiBmdW5jdGlvbihlKSB7XG4gICAgICAgICAgICBfdGhpcy5pc0JlaW5nRHJhZ2dlZCA9IGZhbHNlO1xuICAgICAgICAgICAgX3RoaXMucGFuZS5yZW1vdmVDbGFzcyhfdGhpcy5vcHRpb25zLmFjdGl2ZUNsYXNzKTtcbiAgICAgICAgICAgIF90aGlzLmRvYy51bmJpbmQoTU9VU0VNT1ZFLCBfdGhpcy5ldmVudHNbRFJBR10pLnVuYmluZChNT1VTRVVQLCBfdGhpcy5ldmVudHNbVVBdKTtcbiAgICAgICAgICAgIF90aGlzLmJvZHkudW5iaW5kKE1PVVNFRU5URVIsIF90aGlzLmV2ZW50c1tFTlRFUl0pO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH07XG4gICAgICAgIH0pKHRoaXMpLFxuICAgICAgICByZXNpemU6IChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICAgIHJldHVybiBmdW5jdGlvbihlKSB7XG4gICAgICAgICAgICBfdGhpcy5yZXNldCgpO1xuICAgICAgICAgIH07XG4gICAgICAgIH0pKHRoaXMpLFxuICAgICAgICBwYW5lZG93bjogKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKGUpIHtcbiAgICAgICAgICAgIF90aGlzLnNsaWRlclkgPSAoZS5vZmZzZXRZIHx8IGUub3JpZ2luYWxFdmVudC5sYXllclkpIC0gKF90aGlzLnNsaWRlckhlaWdodCAqIDAuNSk7XG4gICAgICAgICAgICBfdGhpcy5zY3JvbGwoKTtcbiAgICAgICAgICAgIF90aGlzLmV2ZW50cy5kb3duKGUpO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH07XG4gICAgICAgIH0pKHRoaXMpLFxuICAgICAgICBzY3JvbGw6IChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICAgIHJldHVybiBmdW5jdGlvbihlKSB7XG4gICAgICAgICAgICBfdGhpcy51cGRhdGVTY3JvbGxWYWx1ZXMoKTtcbiAgICAgICAgICAgIGlmIChfdGhpcy5pc0JlaW5nRHJhZ2dlZCkge1xuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIV90aGlzLmlPU05hdGl2ZVNjcm9sbGluZykge1xuICAgICAgICAgICAgICBfdGhpcy5zbGlkZXJZID0gX3RoaXMuc2xpZGVyVG9wO1xuICAgICAgICAgICAgICBfdGhpcy5zZXRPblNjcm9sbFN0eWxlcygpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGUgPT0gbnVsbCkge1xuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoX3RoaXMuY29udGVudFNjcm9sbFRvcCA+PSBfdGhpcy5tYXhTY3JvbGxUb3ApIHtcbiAgICAgICAgICAgICAgaWYgKF90aGlzLm9wdGlvbnMucHJldmVudFBhZ2VTY3JvbGxpbmcpIHtcbiAgICAgICAgICAgICAgICBfdGhpcy5wcmV2ZW50U2Nyb2xsaW5nKGUsIERPV04pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGlmIChfdGhpcy5wcmV2U2Nyb2xsVG9wICE9PSBfdGhpcy5tYXhTY3JvbGxUb3ApIHtcbiAgICAgICAgICAgICAgICBfdGhpcy4kZWwudHJpZ2dlcignc2Nyb2xsZW5kJyk7XG4gICAgICAgICAgICAgI
7437H1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoX3RoaXMuY29udGVudFNjcm9sbFRvcCA9PT0gMCkge1xuICAgICAgICAgICAgICBpZiAoX3RoaXMub3B0aW9ucy5wcmV2ZW50UGFnZVNjcm9sbGluZykge1xuICAgICAgICAgICAgICAgIF90aGlzLnByZXZlbnRTY3JvbGxpbmcoZSwgVVApO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGlmIChfdGhpcy5wcmV2U2Nyb2xsVG9wICE9PSAwKSB7XG4gICAgICAgICAgICAgICAgX3RoaXMuJGVsLnRyaWdnZXIoJ3Njcm9sbHRvcCcpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfTtcbiAgICAgICAgfSkodGhpcyksXG4gICAgICAgIHdoZWVsOiAoZnVuY3Rpb24oX3RoaXMpIHtcbiAgICAgICAgICByZXR1cm4gZnVuY3Rpb24oZSkge1xuICAgICAgICAgICAgdmFyIGRlbHRhO1xuICAgICAgICAgICAgaWYgKGUgPT0gbnVsbCkge1xuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkZWx0YSA9IGUuZGVsdGEgfHwgZS53aGVlbERlbHRhIHx8IChlLm9yaWdpbmFsRXZlbnQgJiYgZS5vcmlnaW5hbEV2ZW50LndoZWVsRGVsdGEpIHx8IC1lLmRldGFpbCB8fCAoZS5vcmlnaW5hbEV2ZW50ICYmIC1lLm9yaWdpbmFsRXZlbnQuZGV0YWlsKTtcbiAgICAgICAgICAgIGlmIChkZWx0YSkge1xuICAgICAgICAgICAgICBfdGhpcy5zbGlkZXJZICs9IC1kZWx0YSAvIDM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBfdGhpcy5zY3JvbGwoKTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9O1xuICAgICAgICB9KSh0aGlzKSxcbiAgICAgICAgZW50ZXI6IChmdW5jdGlvbihfdGhpcykge1xuICAgICAgICAgIHJldHVybiBmdW5jdGlvbihlKSB7XG4gICAgICAgICAgICB2Y
7437XIgX3JlZjtcbiAgICAgICAgICAgIGlmICghX3RoaXMuaXNCZWluZ0RyYWdnZWQpIHtcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKChlLmJ1dHRvbnMgfHwgZS53aGljaCkgIT09IDEpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIChfcmVmID0gX3RoaXMuZXZlbnRzKVtVUF0uYXBwbHkoX3JlZiwgYXJndW1lbnRzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9O1xuICAgICAgICB9KSh0aGlzKVxuICAgICAgfTtcbiAgICB9O1xuXG5cbiAgICAvKipcbiAgICAgIEFkZHMgZXZlbnQgbGlzdGVuZXJzIHdpdGggalF1ZXJ5LlxuICAgICAgQG1ldGhvZCBhZGRFdmVudHNcbiAgICAgIEBwcml2YXRlXG4gICAgICovXG5cbiAgICBOYW5vU2Nyb2xsLnByb3RvdHlwZS5hZGRFdmVudHMgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBldmVudHM7XG4gICAgICB0aGlzLnJlbW92ZUV2ZW50cygpO1xuICAgICAgZXZlbnRzID0gdGhpcy5ldmVudHM7XG4gICAgICBpZiAoIXRoaXMub3B0aW9ucy5kaXNhYmxlUmVzaXplKSB7XG4gICAgICAgIHRoaXMud2luLmJpbmQoUkVTSVpFLCBldmVudHNbUkVTSVpFXSk7XG4gICAgICB9XG4gICAgICBpZiAoIXRoaXMuaU9TTmF0aXZlU2Nyb2xsaW5nKSB7XG4gICAgICAgIHRoaXMuc2xpZGVyLmJpbmQoTU9VU0VET1dOLCBldmVudHNbRE9XTl0pO1xuICAgICAgICB0aGlzLnBhbmUuYmluZChNT1VTRURPV04sIGV2ZW50c1tQQU5FRE9XTl0pLmJpbmQoXCJcIiArIE1PVVNFV0hFRUwgKyBcIiBcIiArIERPTVNDUk9MTCwgZXZlbnRzW1dIRUVMXSk7XG4gICAgICB9XG4gICAgICB0aGlzLiRjb250ZW50LmJpbmQoXCJcIiArIFNDUk9MTCArIFwiIFwiICsgTU9VU0VXSEVFTCArIFwiIFwiICsgRE9NU0NST0xMICsgXCIgXCIgKyBUT1VDSE1PVkUsIGV2ZW50c1tTQ1JPTExdKTtcbiAgICB9O1xuXG5cbiAgICAvKipcbiAgICAgIFJlbW92ZXMgZXZlbnQgbGlzdGVuZXJzIHdpdGggalF1ZXJ5LlxuICAgICAgQG1ldGhvZCByZW1vdmVFdmVudHNcbiAgICAgIEBwcml2YXRlXG4gICAgICovXG5cbiAgICBOYW5vU2Nyb2xsLnByb3RvdHlwZS5yZW1vdmVFdmVudHMgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBldmVudHM7XG4gICAgICBldmVudHMgPSB0aGlzLmV2ZW50cztcbiAgICAgIHRoaXMud2luLnVuYmluZChSRVNJWkUsIGV2ZW50c1tSRVNJWkVdKTtcbiAgICAgIGlmICghdGhpcy5pT1NOYXRpdmVTY3JvbGxpbmcpIHtcbiAgICAgICAgdGhpcy5zbGlkZXIudW5iaW5kKCk7XG4gICAgICAgIHRoaXMucGFuZS51bmJpbmQoKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuJGNvbnRlbnQudW5iaW5kKFwiXCIgKyBTQ1JPTEwgKyBcIiBcIiArIE1PVVNFV0hFRUwgKyBcIiBcIiArIERPTVNDUk9MTCArIFwiIFwiICsgVE9VQ0hNT1ZFLCBldmVudHNbU0NST0xMXSk7XG4gICAgfTtcblxuXG4gICAgLyoqXG4gICAgICBHZW5lcmF0ZXMgbmFub1Njcm9sbGVyJ3Mgc2Nyb2xsYmFyIGFuZCBlbGVtZW50cyBmb3IgaXQuXG4gICAgICBAbWV0aG9kIGdlbmVyYXRlXG4gICAgICBAY2hhaW5hYmxlXG4gICAgICBAcHJpdmF0ZVxuICAgICAqL1xuXG4gICAgTmFub1Njcm9sbC5wcm90b3R5cGUuZ2VuZXJhdGUgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBjb250ZW50Q2xhc3MsIGNzc1J1bGUsIGN1cnJlbnRQYWRkaW5nLCBvcHRpb25zLCBwYW5lLCBwYW5lQ2xhc3MsIHNsaWRlckNsYXNzO1xuICAgICAgb3B0aW9ucyA9IHRoaXMub3B0aW9ucztcbiAgICAgIHBhbmVDbGFzcyA9IG9wdGlvbnMucGFuZUNsYXNzLCBzbGlkZXJDbGFzcyA9IG9wdGlvbnMuc2xpZGVyQ2xhc3MsIGNvbnRlbnRDbGFzcyA9IG9wdGlvbnMuY29udGVudENsYXNzO1xuICAgICAgaWYgKCEocGFuZSA9IHRoaXMuJGVsLmNoaWxkcmVuKFwiLlwiICsgcGFuZUNsYXNzKSkubGVuZ3RoICYmICFwYW5lLmNoaWxkcmVuKFwiLlwiICsgc2xpZGVyQ2xhc3MpLmxlbmd0aCkge1xuICAgICAgICB0aGlzLiRlbC5hcHBlbmQoXCI8ZGl2IGNsYXNzPVxcXCJcIiArIHBhbmVDbGFzcyArIFwiXFxcIj48ZGl2IGNsYXNzPVxcXCJcIiArIHNsaWRlckNsYXNzICsgXCJcXFwiIC8+PC9kaXY+XCIpO1xuICAgICAgfVxuICAgICAgdGhpcy5wYW5lID0gdGhpcy4kZWwuY2hpbGRyZW4oXCIuXCIgKyBwYW5lQ2xhc3MpO1xuICAgICAgdGhpcy5zbGlkZXIgPSB0aGlzLnBhbmUuZmluZChcIi5cIiArIHNsaWRlckNsYXNzKTtcbiAgICAgIGlmIChCUk9XU0VSX1NDUk9MTEJBUl9XSURUSCA9PT0gMCAmJiBpc0ZGV2l0aEJ1Z2d5U2Nyb2xsYmFyKCkpIHtcbiAgICAgICAgY3VycmVudFBhZGRpbmcgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZSh0aGlzLmNvbnRlbnQsIG51bGwpLmdldFByb3BlcnR5VmFsdWUoJ3BhZGRpbmctcmlnaHQnKS5yZXBsYWNlKC9bXjAtOS5dKy9nLCAnJyk7XG4gICAgICAgIGNzc1J1bGUgPSB7XG4gICAgICAgICAgcmlnaHQ6IC0xNCxcbiAgICAgICAgICBwYWRkaW5nUmlnaHQ6ICtjdXJyZW50UGFkZGluZyArIDE0XG4gICAgICAgIH07XG4gICAgICB9IGVsc2UgaWYgKEJST1dTRVJfU0NST0xMQkFSX1dJRFRIKSB7XG4gICAgICAgIGNzc1J1bGUgPSB7XG4gICAgICAgICAgcmlnaHQ6IC1CUk9XU0VSX1NDUk9MTEJBUl9XSURUSFxuICAgICAgICB9O1xuICAgICAgICB0aGlzLiRlbC5hZGRDbGFzcyhvcHRpb25zLmVuYWJsZWRDbGFzcyk7XG4gICAgICB9XG4gICAgICBpZiAoY3NzUnVsZSAhPSBudWxsKSB7XG4gICAgICAgIHRoaXMuJGNvbnRlbnQuY3NzKGNzc1J1bGUpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuXG4gICAgLyoqXG4gICAgICBAbWV0aG9kIHJlc3RvcmVcbiAgICAgIEBwcml2YXRlXG4gICAgICovXG5cbiAgICBOYW5vU2Nyb2xsLnByb3RvdHlwZS5yZXN0b3JlID0gZnVuY3Rpb24oKSB7XG4gICAgICB0aGlzLnN0b3BwZWQgPSBmYWxzZTtcbiAgICAgIGlmICghdGhpcy5pT1NOYXRpdmVTY3JvbGxpbmcpIHtcbiAgICAgICAgdGhpcy5wYW5lLnNob3coKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuYWRkRXZlbnRzKCk7XG4gICAgfTtcblxuXG4gICAgLyoqXG4gICAgICBSZXNldHMgbmFub1Njcm9sbGVyJ3Mgc2Nyb2xsYmFyLlxuICAgICAgQG1ldGhvZCByZXNldFxuICAgICAgQGNoYWluYWJsZVxuICAgICAgQGV4YW1wbGVcbiAgICAgICAgICAkKFwiLm5hbm9cIikubmFub1Njcm9sbGVyKCk7XG4gICAgICovXG5cbiAgICBOYW5vU2Nyb2xsLnByb3RvdHlwZS5yZXNldCA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGNvbnRlbnQsIGNvbnRlbn
7437RIZWlnaHQsIGNvbnRlbnRQb3NpdGlvbiwgY29udGVudFN0eWxlLCBjb250ZW50U3R5bGVPdmVyZmxvd1ksIHBhbmVCb3R0b20sIHBhbmVIZWlnaHQsIHBhbmVPdXRlckhlaWdodCwgcGFuZVRvcCwgcGFyZW50TWF4SGVpZ2h0LCByaWdodCwgc2xpZGVySGVpZ2h0O1xuICAgICAgaWYgKHRoaXMuaU9TTmF0aXZlU2Nyb2xsaW5nKSB7XG4gICAgICAgIHRoaXMuY29udGVudEhlaWdodCA9IHRoaXMuY29udGVudC5zY3JvbGxIZWlnaHQ7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmICghdGhpcy4kZWwuZmluZChcIi5cIiArIHRoaXMub3B0aW9ucy5wYW5lQ2xhc3MpLmxlbmd0aCkge1xuICAgICAgICB0aGlzLmdlbmVyYXRlKCkuc3RvcCgpO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMuc3RvcHBlZCkge1xuICAgICAgICB0aGlzLnJlc3RvcmUoKTtcbiAgICAgIH1cbiAgICAgIGNvbnRlbnQgPSB0aGlzLmNvbnRlbnQ7XG4gICAgICBjb250ZW50U3R5bGUgPSBjb250ZW50LnN0eWxlO1xuICAgICAgY29udGVudFN0eWxlT3ZlcmZsb3dZID0gY29udGVudFN0eWxlLm92ZXJmbG93WTtcbiAgICAgIGlmIChCUk9XU0VSX0lTX0lFNykge1xuICAgICAgICB0aGlzLiRjb250ZW50LmNzcyh7XG4gICAgICAgICAgaGVpZ2h0OiB0aGlzLiRjb250ZW50LmhlaWdodCgpXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgY29udGVudEhlaWdodCA9IGNvbnRlbnQuc2Nyb2xsSGVpZ2h0ICsgQlJPV1NFUl9TQ1JPTExCQVJfV0lEVEg7XG4gICAgICBwYXJlbnRNYXhIZWlnaHQgPSBwYXJzZUludCh0aGlzLiRlbC5jc3MoXCJtYXgtaGVpZ2h0XCIpLCAxMCk7XG4gICAgICBpZiAocGFyZW50TWF4SGVpZ2h0ID4gMCkge1xuICAgICAgICB0aGlzLiRlbC5oZWlnaHQoXCJcIik7XG4gICAgICAgIHRoaXMuJGVsLmhlaWdodChjb250ZW50LnNjcm9sbEhlaWdodCA+IHBhcmVudE1heEhlaWdodCA/IHBhcmVudE1heEhlaWdodCA6IGNvbnRlbnQuc2Nyb2xsSGVpZ2h0KTtcbiAgICAgIH1cbiAgICAgIHBhbmVIZWlnaHQgPSB0aGlzLnBhbmUub3V0ZXJIZWlnaHQoZmFsc2UpO1xuICAgICAgcGFuZVRvcCA9IHBhcnNlSW50KHRoaXMucGFuZS5jc3MoJ3RvcCcpLCAxMCk7XG4gICAgICBwYW5lQm90dG9tID0gcGFyc2VJbnQodGhpcy5wYW5lLmNzcygnYm90dG9tJyksIDEwKTtcbiAgICAgIHBhbmVPdXRlckhlaWdodCA9IHBhbmVIZWlnaHQgKyBwYW5lVG9wICsgcGFuZUJvdHRvbTtcbiAgICAgIHNsaWRlckhlaWdodCA9IE1hdGgucm91bmQocGFuZU91dGVySGVpZ2h0IC8gY29udGVudEhlaWdodCAqIHBhbmVIZWlnaHQpO1xuICAgICAgaWYgKHNsaWRlckhlaWdodCA8IHRoaXMub3B0aW9ucy5zbGlkZXJNaW5IZWlnaHQpIHtcbiAgICAgICAgc2xpZGVySGVpZ2h0ID0gdGhpcy5vcHRpb25zLnNsaWRlck1pbkhlaWdodDtcbiAgICAgIH0gZWxzZSBpZiAoKHRoaXMub3B0aW9ucy5zbGlkZXJNYXhIZWlnaHQgIT0gbnVsbCkgJiYgc2xpZGVySGVpZ2h0ID4gdGhpcy5vcHRpb25zLnNsaWRlck1heEhlaWdodCkge1xuICAgICAgICBzbGlkZXJIZWlnaHQgPSB0aGlzLm9wdGlvbnMuc2xpZGVyTWF4SGVpZ2h0O1xuICAgICAgfVxuICAgICAgaWYgKGNvbnRlbnRTdHlsZU92ZXJmbG93WSA9PT0gU0NST0xMICYmIGNvbnRlbnRTdHlsZS5vdmVyZmxvd1ggIT09IFNDUk9MTCkge1xuICAgICAgICBzbGlkZXJIZWlnaHQgKz0gQlJPV1NFUl9TQ1JPTExCQVJfV0lEVEg7XG4gICAgICB9XG4gICAgICB0aGlzLm1heFNsaWRlclRvcCA9IHBhbmVPdXRlckhlaWdodCAtIHNsaWRlckhlaWdodDtcbiAgICAgIHRoaXMuY29udGVudEhlaWdodCA9IGNvbnRlbnRIZWlnaHQ7XG4gICAgICB0aGlzLnBhbmVIZWlnaHQgPSBwYW5lSGVpZ2h0O1xuICAgICAgdGhpcy5wYW5lT3V0ZXJIZWlnaHQgPSBwYW5lT3V0ZXJIZWlnaHQ7XG4gICAgICB0aGlzLnNsaWRlckhlaWdodCA9IHNsaWRlckhlaWdodDtcbiAgICAgIHRoaXMucGFuZVRvcCA9IHBhbmVUb3A7XG4gICAgICB0aGlzLnNsaWRlci5oZWlnaHQoc2xpZGVySGVpZ2h0KTtcbiAgICAgIHRoaXMuZXZlbnRzLnNjcm9sbCgpO1xuICAgICAgdGhpcy5wYW5lLnNob3coKTtcbiAgICAgIHRoaXMuaXNBY3RpdmUgPSB0cnVlO1xuICAgICAgaWYgKChjb250ZW50LnNjcm9sbEhlaWdodCA9PT0gY29udGVudC5jbGllbnRIZWlnaHQpIHx8ICh0aGlzLnBhbmUub3V0ZXJIZWlnaHQodHJ1ZSkgPj0gY29udGVudC5zY3JvbGxIZWlnaHQgJiYgY29udGVudFN0eWxlT3ZlcmZsb3dZICE9PSBTQ1JPTEwpKSB7XG4gICAgICAgIHRoaXMucGFuZS5oaWRlKCk7XG4gICAgICAgIHRoaXMuaXNBY3RpdmUgPSBmYWxzZTtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5lbC5jbGllbnRIZWlnaHQgPT09IGNvbnRlbnQuc2Nyb2xsSGVpZ2h0ICYmIGNvbnRlbnRTdHlsZU92ZXJmbG93WSA9PT0gU0NST0xMKSB7XG4gICAgICAgIHRoaXMuc2xpZGVyLmhpZGUoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuc2xpZGVyLnNob3coKTtcbiAgICAgIH1cbiAgICAgIHRoaXMucGFuZS5jc3Moe1xuICAgICAgICBvcGFjaXR5OiAodGhpcy5vcHRpb25zLmFsd2F5c1Zpc2libGUgPyAxIDogJycpLFxuICAgICAgICB2aXNpYmlsaXR5OiAodGhpcy5vcHRpb25zLmFsd2F5c1Zpc2libGUgPyAndmlzaWJsZScgOiAnJylcbiAgICAgIH0pO1xuICAgICAgY29udGVudFBvc2l0aW9uID0gdGhpcy4kY29udGVudC5jc3MoJ3Bvc2l0aW9uJyk7XG4gICAgICBpZiAoY29udGVudFBvc2l0aW9uID09PSAnc3RhdGljJyB8fCBjb250ZW50UG9zaXRpb24gPT09ICdyZWxhdGl2ZScpIHtcbiAgICAgICAgcmlnaHQgPSBwYXJzZUludCh0aGlzLiRjb250ZW50LmNzcygncmlnaHQnKSwgMTApO1xuICAgICAgICBpZiAocmlnaHQpIHtcbiAgICAgICAgICB0aGlzLiRjb250ZW50LmNzcyh7XG4gICAgICAgICAgICByaWdodDogJycsXG4gICAgICAgICAgICBtYXJnaW5SaWdodDogcmlnaHRcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuXG4gICAgLyoqXG4gICAgICBAbWV0aG9kIHNjcm9sbFxuICAgICAgQHByaXZhdGVcbiAgICAgIEBleGFtcGxlXG4gICAgICAgICAgJChcIi5uYW5vXCIpLm5hbm9TY3JvbGxlcih7IHNjcm9sbDogJ3RvcCcgfSk7XG4gICAgICovXG5cbiAgICBOYW5vU2Nyb2xsLnByb3RvdHlwZS5zY3JvbGwgP
7437SBmdW5jdGlvbigpIHtcbiAgICAgIGlmICghdGhpcy5pc0FjdGl2ZSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aGlzLnNsaWRlclkgPSBNYXRoLm1heCgwLCB0aGlzLnNsaWRlclkpO1xuICAgICAgdGhpcy5zbGlkZXJZID0gTWF0aC5taW4odGhpcy5tYXhTbGlkZXJUb3AsIHRoaXMuc2xpZGVyWSk7XG4gICAgICB0aGlzLiRjb250ZW50LnNjcm9sbFRvcCh0aGlzLm1heFNjcm9sbFRvcCAqIHRoaXMuc2xpZGVyWSAvIHRoaXMubWF4U2xpZGVyVG9wKTtcbiAgICAgIGlmICghdGhpcy5pT1NOYXRpdmVTY3JvbGxpbmcpIHtcbiAgICAgICAgdGhpcy51cGRhdGVTY3JvbGxWYWx1ZXMoKTtcbiAgICAgICAgdGhpcy5zZXRPblNjcm9sbFN0eWxlcygpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuXG4gICAgLyoqXG4gICAgICBTY3JvbGwgYXQgdGhlIGJvdHRvbSB3aXRoIGFuIG9mZnNldCB2YWx1ZVxuICAgICAgQG1ldGhvZCBzY3JvbGxCb3R0b21cbiAgICAgIEBwYXJhbSBvZmZzZXRZIHtOdW1iZXJ9XG4gICAgICBAY2hhaW5hYmxlXG4gICAgICBAZXhhbXBsZVxuICAgICAgICAgICQoXCIubmFub1wiKS5uYW5vU2Nyb2xsZXIoeyBzY3JvbGxCb3R0b206IHZhbHVlIH0pO1xuICAgICAqL1xuXG4gICAgTmFub1Njcm9sbC5wcm90b3R5cGUuc2Nyb2xsQm90dG9tID0gZnVuY3Rpb24ob2Zmc2V0WSkge1xuICAgICAgaWYgKCF0aGlzLmlzQWN0aXZlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMuJGNvbnRlbnQuc2Nyb2xsVG9wKHRoaXMuY29udGVudEhlaWdodCAtIHRoaXMuJGNvbnRlbnQuaGVpZ2h0KCkgLSBvZmZzZXRZKS50cmlnZ2VyKE1PVVNFV0hFRUwpO1xuICAgICAgdGhpcy5zdG9wKCkucmVzdG9yZSgpO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuXG4gICAgLyoqXG4gICAgICBTY3JvbGwgYXQgdGhlIHRvcCB3aXRoIGFuIG9mZnNldCB2YWx1ZVxuICAgICAgQG1ldGhvZCBzY3JvbGxUb3BcbiAgICAgIEBwYXJhbSBvZmZzZXRZIHtOdW1iZXJ9XG4gICAgICBAY2hhaW5hYmxlXG4gICAgICBAZXhhbXBsZVxuICAgICAgICAgICQoXCIubmFub1wiKS5uYW5vU2Nyb2xsZXIoeyBzY3JvbGxUb3A6IHZhbHVlIH0pO1xuICAgICAqL1xuXG4gICAgTmFub1Njcm9sbC5wcm90b3R5cGUuc2Nyb2xsVG9wID0gZnVuY3Rpb24ob2Zmc2V0WSkge1xuICAgICAgaWYgKCF0aGlzLmlzQWN0aXZlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMuJGNvbnRlbnQuc2Nyb2xsVG9wKCtvZmZzZXRZKS50cmlnZ2VyKE1PVVNFV0hFRUwpO1xuICAgICAgdGhpcy5zdG9wKCkucmVzdG9yZSgpO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuXG4gICAgLyoqXG4gICAgICBTY3JvbGwgdG8gYW4gZWxlbWVudFxuICAgICAgQG1ldGhvZCBzY3JvbGxUb1xuICAgICAgQHBhcmFtIG5vZGUge05vZGV9IEEgbm9kZSB0byBzY3JvbGwgdG8uXG4gICAgICBAY2hhaW5hYmxlXG4gICAgICBAZXhhbXBsZVxuICAgICAgICAgICQoXCIubmFub1wiKS5uYW5vU2Nyb2xsZXIoeyBzY3JvbGxUbzogJCgnI2Ffbm9kZScpIH0pO1xuICAgICAqL1xuXG4gICAgTmFub1Njcm9sbC5wcm90b3R5cGUuc2Nyb2xsVG8gPSBmdW5jdGlvbihub2RlKSB7XG4gICAgICBpZiAoIXRoaXMuaXNBY3RpdmUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhpcy5zY3JvbGxUb3AodGhpcy4kZWwuZmluZChub2RlKS5nZXQoMCkub2Zmc2V0VG9wKTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cblxuICAgIC8qKlxuICAgICAgVG8gc3RvcCB0aGUgb3BlcmF0aW9uLlxuICAgICAgVGhpcyBvcHRpb24gd2lsbCB0ZWxsIHRoZSBwbHVnaW4gdG8gZGlzYWJsZSBhbGwgZXZlbnQgYmluZGluZ3MgYW5kIGhpZGUgdGhlIGdhZGdldCBzY3JvbGxiYXIgZnJvbSB0aGUgVUkuXG4gICAgICBAbWV0aG9kIHN0b3BcbiAgICAgIEBjaGFpbmFibGVcbiAgICAgIEBleGFtcGxlXG4gICAgICAgICAgJChcIi5uYW5vXCIpLm5hbm9TY3JvbGxlcih7IHN0b3A6IHRydWUgfSk7XG4gICAgICovXG5cbiAgICBOYW5vU2Nyb2xsLnByb3RvdHlwZS5zdG9wID0gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAoY0FGICYmIHRoaXMuc2Nyb2xsUkFGKSB7XG4gICAgICAgIGNBRih0aGlzLnNjcm9sbFJBRik7XG4gICAgICAgIHRoaXMuc2Nyb2xsUkFGID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIHRoaXMuc3RvcHBlZCA9IHRydWU7XG4gICAgICB0aGlzLnJlbW92ZUV2ZW50cygpO1xuICAgICAgaWYgKCF0aGlzLmlPU05hdGl2ZVNjcm9sbGluZykge1xuICAgICAgICB0aGlzLnBhbmUuaGlkZSgpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfTtcblxuXG4gICAgLyoqXG4gICAgICBEZXN0cm95cyBuYW5vU2Nyb2xsZXIgYW5kIHJlc3RvcmVzIGJyb3dzZXIncyBuYXRpdmUgc2Nyb2xsYmFyLlxuICAgICAgQG1ldGhvZCBkZXN0cm95XG4gICAgICBAY2hhaW5hYmxlXG4gICAgICBAZXhhbXBsZVxuICAgICAgICAgICQoXCIubmFub1wiKS5uYW5vU2Nyb2xsZXIoeyBkZXN0cm95OiB0cnVlIH0pO1xuICAgICAqL1xuXG4gICAgTmFub1Njcm9sbC5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKCF0aGlzLnN0b3BwZWQpIHtcbiAgICAgICAgdGhpcy5zdG9wKCk7XG4gICAgICB9XG4gICAgICBpZiAoIXRoaXMuaU9TTmF0aXZlU2Nyb2xsaW5nICYmIHRoaXMucGFuZS5sZW5ndGgpIHtcbiAgICAgICAgdGhpcy5wYW5lLnJlbW92ZSgpO1xuICAgICAgfVxuICAgICAgaWYgKEJST1dTRVJfSVNfSUU3KSB7XG4gICAgICAgIHRoaXMuJGNvbnRlbnQuaGVpZ2h0KCcnKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuJGNvbnRlbnQucmVtb3ZlQXR0cigndGFiaW5kZXgnKTtcbiAgICAgIGlmICh0aGlzLiRlbC5oYXNDbGFzcyh0aGlzLm9wdGlvbnMuZW5hYmxlZENsYXNzKSkge1xuICAgICAgICB0aGlzLiRlbC5yZW1vdmVDbGFzcyh0aGlzLm9wdGlvbnMuZW5hYmxlZENsYXNzKTtcbiAgICAgICAgdGhpcy4kY29udGVudC5jc3Moe1xuICAgICAgICAgI
7437HJpZ2h0OiAnJ1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH07XG5cblxuICAgIC8qKlxuICAgICAgVG8gZmxhc2ggdGhlIHNjcm9sbGJhciBnYWRnZXQgZm9yIGFuIGFtb3VudCBvZiB0aW1lIGRlZmluZWQgaW4gcGx1Z2luIHNldHRpbmdzIChkZWZhdWx0cyB0byAxLDVzKS5cbiAgICAgIFVzZWZ1bCBpZiB5b3Ugd2FudCB0byBzaG93IHRoZSB1c2VyIChlLmcuIG9uIHBhZ2Vsb2FkKSB0aGF0IHRoZXJlIGlzIG1vcmUgY29udGVudCB3YWl0aW5nIGZvciBoaW0uXG4gICAgICBAbWV0aG9kIGZsYXNoXG4gICAgICBAY2hhaW5hYmxlXG4gICAgICBAZXhhbXBsZVxuICAgICAgICAgICQoXCIubmFub1wiKS5uYW5vU2Nyb2xsZXIoeyBmbGFzaDogdHJ1ZSB9KTtcbiAgICAgKi9cblxuICAgIE5hbm9TY3JvbGwucHJvdG90eXBlLmZsYXNoID0gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAodGhpcy5pT1NOYXRpdmVTY3JvbGxpbmcpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKCF0aGlzLmlzQWN0aXZlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMucmVzZXQoKTtcbiAgICAgIHRoaXMucGFuZS5hZGRDbGFzcyh0aGlzLm9wdGlvbnMuZmxhc2hlZENsYXNzKTtcbiAgICAgIHNldFRpbWVvdXQoKGZ1bmN0aW9uKF90aGlzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgICAgICBfdGhpcy5wYW5lLnJlbW92ZUNsYXNzKF90aGlzLm9wdGlvbnMuZmxhc2hlZENsYXNzKTtcbiAgICAgICAgfTtcbiAgICAgIH0pKHRoaXMpLCB0aGlzLm9wdGlvbnMuZmxhc2hEZWxheSk7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuXG4gICAgcmV0dXJuIE5hbm9TY3JvbGw7XG5cbiAgfSkoKTtcbiAgJC5mbi5uYW5vU2Nyb2xsZXIgPSBmdW5jdGlvbihzZXR0aW5ncykge1xuICAgIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKSB7XG4gICAgICB2Y
7437XIgb3B0aW9ucywgc2Nyb2xsYmFyO1xuICAgICAgaWYgKCEoc2Nyb2xsYmFyID0gdGhpcy5uYW5vc2Nyb2xsZXIpKSB7XG4gICAgICAgIG9wdGlvbnMgPSAkLmV4dGVuZCh7fSwgZGVmYXVsdHMsIHNldHRpbmdzKTtcbiAgICAgICAgdGhpcy5uYW5vc2Nyb2xsZXIgPSBzY3JvbGxiYXIgPSBuZXcgTmFub1Njcm9sbCh0aGlzLCBvcHRpb25zKTtcbiAgICAgIH1cbiAgICAgIGlmIChzZXR0aW5ncyAmJiB0eXBlb2Ygc2V0dGluZ3MgPT09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgJC5leHRlbmQoc2Nyb2xsYmFyLm9wdGlvbnMsIHNldHRpbmdzKTtcbiAgICAgICAgaWYgKHNldHRpbmdzLnNjcm9sbEJvdHRvbSAhPSBudWxsKSB7XG4gICAgICAgICAgcmV0dXJuIHNjcm9sbGJhci5zY3JvbGxCb3R0b20oc2V0dGluZ3Muc2Nyb2xsQm90dG9tKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc2V0dGluZ3Muc2Nyb2xsVG9wICE9IG51bGwpIHtcbiAgICAgICAgICByZXR1cm4gc2Nyb2xsYmFyLnNjcm9sbFRvcChzZXR0aW5ncy5zY3JvbGxUb3ApO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzZXR0aW5ncy5zY3JvbGxUbykge1xuICAgICAgICAgIHJldHVybiBzY3JvbGxiYXIuc2Nyb2xsVG8oc2V0dGluZ3Muc2Nyb2xsVG8pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzZXR0aW5ncy5zY3JvbGwgPT09ICdib3R0b20nKSB7XG4gICAgICAgICAgcmV0dXJuIHNjcm9sbGJhci5zY3JvbGxCb3R0b20oMCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHNldHRpbmdzLnNjcm9sbCA9PT0gJ3RvcCcpIHtcbiAgICAgICAgICByZXR1cm4gc2Nyb2xsYmFyLnNjcm9sbFRvcCgwKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc2V0dGluZ3Muc2Nyb2xsICYmIHNldHRpbmdzLnNjcm9sbCBpbnN0YW5jZW9mICQpIHtcbiAgICAgICAgICByZXR1cm4gc2Nyb2xsYmFyLnNjcm9sbFRvKHNldHRpbmdzLnNjcm9sbCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHNldHRpbmdzLnN0b3ApIHtcbiAgICAgICAgICByZXR1cm4gc2Nyb2xsYmFyLnN0b3AoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc2V0dGluZ3MuZGVzdHJveSkge1xuICAgICAgICAgIHJldHVybiBzY3JvbGxiYXIuZGVzdHJveSgpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzZXR0aW5ncy5mbGFzaCkge1xuICAgICAgICAgIHJldHVybiBzY3JvbGxiYXIuZmxhc2goKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHNjcm9sbGJhci5yZXNldCgpO1xuICAgIH0pO1xuICB9O1xuICAkLmZuLm5hbm9TY3JvbGxlci5Db25zdHJ1Y3RvciA9IE5hbm9TY3JvbGw7XG59KTtcblxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9anF1ZXJ5Lm5hbm9zY3JvbGxlci5qcy5tYXBcbiIsIi8vIENyZWF0ZSBjb29raWUgZnVuY3Rpb25cbmZ1bmN0aW9uIGNyZWF0ZUNvb2tpZShuYW1lLHZhbHVlLGRheXMpIHtcbiAgICBpZiAoZGF5cykge1xuICAgICAgICB2Y
7437XIgZGF0ZSA9IG5ldyBEYXRlKCk7XG4gICAgICAgIGRhdGUuc2V0VGltZShkYXRlLmdldFRpbWUoKSsoZGF5cyoyNCo2MCo2MCoxMDAwKSk7XG4gICAgICAgIHZhciBleHBpcmVzID0gXCI7IGV4cGlyZXM9XCIrZGF0ZS50b0dNVFN0cmluZygpO1xuICAgIH1cbiAgICBlbHNlIHZhciBleHBpcmVzID0gXCJcIjtcbiAgICBkb2N1bWVudC5jb29raWUgPSBuYW1lK1wiPVwiK3ZhbHVlK2V4cGlyZXMrXCI7IHBhdGg9L1wiO1xufVxuXG4vLyBEZWxldGUgY29va2llICAgIFxuZnVuY3Rpb24gZGVsZXRlQ29va2llKG5hbWUpIHsgICBcbiAgICBjcmVhdGVDb29raWUobmFtZSxcIlwiLC0xKTsgICAgIFxufVxuXG4vLyBUbyBkZXRlcm1pbmUgaWYgYSBlbGVtZW50IGlzIHZpc2JsZSB3aXRoaW4gdGhlIHZpZXdwb3J0IC0gaW50ZW5kZWQgdG8gYmUgdXNlZCBpbiBjb25qdW5jdGlvIHdpdGggc2Nyb2xsaW5nXG5mdW5jdGlvbiBzY3JvbGxlZEludG9WaWV3KGVsZW0pIHtcbiAgICB2YXIgJGVsZW0gPSAkKGVsZW0pO1xuICAgIHZhciAkd2luZG93ID0gJCh3aW5kb3cpO1xuICAgIHZhciBkb2NWaWV3VG9wID0gJHdpbmRvdy5zY3JvbGxUb3AoKTtcbiAgICB2YXIgZG9jVmlld0JvdHRvbSA9IGRvY1ZpZXdUb3AgKyAkd2luZG93Lm91dGVySGVpZ2h0KCk7XG4gICAgdmFyIGVsZW1Ub3AgPSAkZWxlbS5vZmZzZXQoKS50b3A7XG4gICAgdmFyIGVsZW1Cb3R0b20gPSBlbGVtVG9wICsgJGVsZW0uaGVpZ2h0KCk7XG4gICAgcmV0dXJuICgoZWxlbUJvdHRvbSA8PSBkb2NWaWV3Qm90dG9tKSAmJiAoZWxlbVRvcCA+PSBkb2NWaWV3VG9wKSk7XG59XG5cbmZ1bmN0aW9uIGpzX3NlcmlhbGl6ZShvYmopIHtcbiAgdmFyIHN0ciA9IFtdO1xuICBmb3IodmFyIHAgaW4gb2JqKVxuICAgIGlmIChvYmouaGFzT3duUHJvcGVydHkocCkpIHtcbiAgICAgIHN0ci5wdXNoKGVuY29kZVVSSUNvbXBvbmVudChwKSArIFwiPVwiICsgZW5jb2RlVVJJQ29tcG9uZW50KG9ialtwXSkpO1xuICAgIH1cbiAgcmV0dXJuIHN0ci5qb2luKFwiJlwiKTtcbn1cblxuIGZ1bmN0aW9uIGFkZFNjcmlwdCggdXJsLCBjYWxsYmFjayApIHtcbiAgICB2YXIgc2NyaXB0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggJ3NjcmlwdCcgKTtcbiAgICBpZiggY2FsbGJhY2sgKSBzY3JpcHQub25sb2FkID0gY2FsbGJhY2s7XG4gICAgc2NyaXB0LnR5cGUgPSAndGV4dC9qYXZhc2NyaXB0JztcbiAgICBzY3JpcHQuc3JjID0gdXJsO1xuICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoIHNjcmlwdCApOyAgXG59XG5cbmZ1bmN0aW9uIGlzVG91Y2hEZXZpY2UoKXtcbiAgICByZXR1cm4gdHJ1ZSA9PSAoXCJvbnRvdWNoc3RhcnRcIiBpbiB3aW5kb3cgfHwgd2luZG93LkRvY3VtZW50VG91Y2ggJiYgZG9jdW1lbnQgaW5zdGFuY2VvZiBEb2N1bWVudFRvdWNoKTtcbn0iLCIvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIEhvbWUgLSBcbi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuS1QuSG9tZSA9IHtcbiAgICBpbml0OiBmdW5jdGlvbigpIHtcblxuICAgICAgICBpZiAoJCgnYm9keS5ob21lJykubGVuZ3RoKSB7XG5cbiAgICAgICAgICAgIC8vIE9wZW4gc2VhcmNoIGJhciBvbiBob3ZlclxuICAgICAgICAgICAgJCgnI2hvbWUtc2VhcmNoLXRvZ2dsZScpLmhvdmVyKGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgICQoJy5ob21lLWZlYXR1cmVfX3NlYXJjaCcpLmFkZENsYXNzKCdob21lLWZlYXR1cmVfX3NlYXJjaC0tb3BlbicpO1xuICAgICAgICAgICAgICAgICQoJy5ob21lLWZlYXR1cmVfX2ltYWdlJykuYWRkQ2xhc3MoJ2hvbWUtZmVhdHVyZV9faW1hZ2UtLXNlYXJjaCcpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICQoXCIjaGFzX2RvY3VtZW50XCIpLm9uKCdjaGFuZ2UnLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICBpZiAoJCh0aGlzKS5pcyhcIjpjaGVja2VkXCIpKSB7XG4gICAgICAgICAgICAgICAgICAgICAkKFwiI2hhc19pbWFnZVwiKS5wcm9wKCdjaGVja2VkJywgZmFsc2UpO1xuICAgICAgICAgICAgICAgIH0gXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICQoXCIjaGFzX2ltYWdlXCIpLm9uKCdjbGljaycsIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgIGlmICgkKHRoaXMpLmlzKFwiOmNoZWNrZWRcIikpIHsgICBcbiAgICAgICAgICAgICAgICAgICAgJChcIiNoYXNfZG9jdW1lbnRcIikucHJvcCgnY2hlY2tlZCcsIGZhbHNlKTsgIFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAvLyBDaGFuZ2UgYmFja2dyb3VuZCBjb2xvdXIgYW5kIGZvbnQgb2YgbmF2IGJhc2VkIG9uIHNjcm9sbCBoZWlnaHRcblxuICAgICAgICAgICAgdmFyIHRhcmdldE9mZnNldCA9ICQoXCIjYW5jaG9yLXBvaW50XCIpLm9mZnNldCgpLnRvcDtcblxuICAgICAgICAgICAgdmFyICR3ID0gJCh3aW5kb3cpLnNjcm9sbChmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICBpZiAoKCR3LnNjcm9sbFRvcCgpICsgNTAwKSA+IHRhcmdldE9mZnNldCkge1xuICAgICAgICAgICAgICAgICAgICAkKCcubmF2aWdhdGlvbicpLmFkZENsYXNzKCduYXZpZ2F0aW9uLS1zY3JvbGwnKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAkKCcubmF2aWdhdGlvbicpLnJlbW92ZUNsYXNzKCduYXZpZ2F0aW9uLS1zY3JvbGwnKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgJCgnLmhvbWUtZmVhdHVyZV9fc2Nyb2xsJykub24oJ2NsaWNrJywgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgICAgJCgnaHRtbCxib2R5JykuYW5pbWF0ZSh7XG4gICAgICAgICAgICAgICAgICAgIHNjcm9sbFRvcDogJCgnLnN1bW1hcnktZmVhdHVyZScpLnBvc2l0aW9uKCkudG9wIC0gNTVcbiAgICAgICAgICAgICAgICB9LCAxMDAwKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIH1cbiAgICB9XG59XG4iLCIvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIExpZ2h0Ym94IC0gdXNpbmcgZmVhdGhlcmxpZ2h0IHBsdWdpbiwgdXNlZCBmb3IgbG9naW4gYW5kIGltYWdlc1xuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5LVC5MaWdodGJveCA9IHtcbiAgICBpbml0OiBmdW5jdGlvbigpIHtcblxuICAgIFx0dmFyIGNvbmZpZ3VyYXRpb24gPSB7IFxuXG4gICAgXHR9ICAgXG5cbiAgICBcdCQoJ1tkYXRhLWltZy1saWdodGJveF0nKS5lYWNoKGZ1bmN0aW9uKCl7IFxuICAgIFx0XHR2YXIgJGVsID0gJCh0aGlzKTsgXG4gICAgXHRcdCRlbC5mZWF0aGVybGlnaHQoJGVsLmF0dHIoJ2hyZWYnKSk7IFxuICAgIFx0fSk7XG4gICBcbiAgICBcdCQoJ1tkYXRhLWltZy1pZ2h0Ym94LWdhbGxlcnldJykuZmVhdGhlcmxpZ2h0R2FsbGVyeSh7IFxuICAgICAgICAgICAgYWZ0ZXJDb250ZW50OiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICB0aGlzLiRsZWdlbmQgPSB0aGlzLiRsZWdlbmQgfHwgJCgnPGRpdiBjbGFzcz1cImxlZ2VuZFwiLz4nKS5pbnNlcnRBZnRlcih0aGlzLiRjb250ZW50KTtcbiAgICAgICAgICAgICAgICB0aGlzLiRsZWdlbmQuaHRtbCh0aGlzLiRjdXJyZW50VGFyZ2V0LmRhdGEoJ2NvbnRlbnQnKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgI
7437H0pOyAgICAgXG4gICAgXHQgXG4gICAgfVxufSAgICAgICAgICIsIlxuS1QuTmF2aWdhdGlvbiA9IHtcbiAgICBpbml0OiBmdW5jdGlvbigpIHtcblxuICAgIFx0JCgnI21lbnUtdG9nZ2xlJykub24oJ2NsaWNrJywgZnVuY3Rpb24oKXsgXG5cdFx0XHQkKCcjbmF2aWdhdGlvbicpLmFkZENsYXNzKCduYXZpZ2F0aW9uLS1vcGVuJyk7XG5cdFx0XHQkKCcubmF2aWdhdGlvbicpLmFkZENsYXNzKCduYXZpZ2F0aW9uLS1vcGVuJyk7XG5cdFx0XHQkKCcjY2xvc2UtbWVudScpLmFkZENsYXNzKCduYXZpZ2F0aW9uLS1vcGVuJyk7XG5cdFx0XHQkKCcjbWVudS10b2dnbGUnKS5hZGRDbGFzcygnbmF2aWdhdGlvbi0tb3BlbicpO1xuXHRcdFx0JCgnI2xvZ2luLXRvZ2dsZScpLmFkZENsYXNzKCduYXZpZ2F0aW9uLS1vcGVuJyk7XG5cdFx0XHQkKCcubmF2aWdhdGlvbl9fYWN0aW9ucycpLmFkZENsYXNzKCduYXZpZ2F0aW9uLS1vcGVuJyk7XG5cdFx0XHQkKCcubmF2aWdhdGlvbl9fb3ZlcmxheScpLmFkZENsYXNzKCduYXZpZ2F0aW9uX19vdmVybGF5LS12aXNpYmxlJyk7XG5cdFx0XHQkKCdib2R5JykuYWRkQ2xhc3MoJ25vLXNjcm9sbCcpO1xuXHRcdH0pXG5cblx0XHQkKCcjY2xvc2UtbWVudScpLm9uKCdjbGljaycsIGZ1bmN0aW9uKCl7XG5cdFx0XHQkKCcjbmF2aWdhdGlvbicpLnJlbW92ZUNsYXNzKCduYXZpZ2F0aW9uLS1vcGVuJyk7XG5cdFx0XHQkKCcubmF2aWdhdGlvbicpLnJlbW92ZUNsYXNzKCduYXZpZ2F0aW9uLS1vcGVuJyk7XG5cdFx0XHQkKCcjY2xvc2UtbWVudScpLnJlbW92ZUNsYXNzKCduYXZpZ2F0aW9uLS1vcGVuJyk7XG5cdFx0XHQkKCcjbWVudS10b2dnbGUnKS5yZW1vdmVDbGFzcygnbmF2aWdhdGlvbi0tb3BlbicpO1xuXHRcdFx0JCgnI2xvZ2luLXRvZ2dsZScpLnJlbW92ZUNsYXNzKCduYXZpZ2F0aW9uLS1vcGVuJyk7XG5cdFx0XHQkKCcubmF2aWdhdGlvbl9fYWN0aW9ucycpLnJlbW92ZUNsYXNzKCduYXZpZ2F0aW9uLS1vcGVuJyk7XG5cdFx0XHQkKCcubmF2aWdhdGlvbl9fb3ZlcmxheScpLnJlbW92ZUNsYXNzKCduYXZpZ2F0aW9uX19vdmVybGF5LS12aXNpYmxlJyk7XG5cdFx0XHQkKCdib2R5JykucmVtb3ZlQ2xhc3MoJ25vLXNjcm9sbCcpO1xuXHRcdH0pXG5cblx0XHQkKCdbZGF0YS1sb2dpbi10cmlnZ2VyXScpLm9uKCdjbGljaycsIGZ1bmN0aW9uKCl7XG5cdFx0XHQkLmZlYXRoZXJsaWdodCgnI2xvZ2luLWZvcm0nLCB7XG5cdFx0XHRcdG5hbWVzcGFjZTogJ2ZlYXRoZXJsaWdodCcsXG5cdFx0XHRcdGNsb3NlSWNvbjogJycsXG5cdFx0XHRcdG90aGVyQ2xvc2U6ICcjY2xvc2UtbGlnaHRib3gnLFxuXHRcdFx0fSk7XG5cdFx0fSk7XG5cblx0XHQkKCdbZGF0YS1mb3Jnb3R0ZW5dJykub24oJ2NsaWNrJywgZnVuY3Rpb24oKXsgXG5cdFx0XHQkKCcubGlnaHRib3hfbG9naW5fX2Zvcm0nKS5oaWRlKCk7XG5cdFx0XHQkKCcubGlnaHRib3hfbG9naW5fX2Zvcm0tLXBhc3N3b3JkJykuc2hvdygpO1xuXHRcdH0pO1xuXG5cdFx0JCgnW2RhdGEtZm9yZ290dGVuLWJhY2tdJykub24oJ2NsaWNrJywgZnVuY3Rpb24oKXsgXG5cdFx0XHQkKCcubGlnaHRib3hfbG9naW5fX2Zvcm0nKS5zaG93KCk7XG5cdFx0XHQkKCcubGlnaHRib3hfbG9naW5fX2Zvcm0tLXBhc3N3b3JkJykuaGlkZSgpO1xuXHRcdH0pO1x0XG5cdFx0XG4gICAgfSBcbn0iLCIvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIEN1c3RvbSA8c2VsZWN0PiBlbGVtZW50IC0gdXNlZCBmb3Igc3R5bGluZyBwdXJwb3Nlc1xuLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5LVC5TZWxlY3QgPSB7XG4gIC8vIFNFTEVDVCBNRU5VIElURU0gT04gRklSU1QgTEVUVEVSIEtFWVBSRVNTXG4gIC8vIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbiAgc3RvcmFnZTp7XG4gICAgbGV0dGVyOiAnJyxcbiAgICBpbmRleDogMCxcbiAgICBsZXR0ZXJBcnI6IFtdXG4gIH0sXG5cbiAgZ2V0TWVudUl0ZW1zOiBmdW5jdGlvbih0aGF0KXtcbiAgICBcInVzZSBzdHJpY3RcIlxuICAgIHRoaXMuY2xlYXJMZXR0ZXJTdGF0ZSgpXG5cbiAgICB2YXIgJGl0ZW1zID0gICQodGhhdCkucGFyZW50KCkuZmluZCgnLm5hbm8gbGk6bnRoLW9mLXR5cGUobisyKScpXG4gICAgdmFyIGl0ZW1zQXJyID0gQXJyYXkuZnJvbSgkaXRlbXMpXG5cbiAgICB2YXIgaXRlbXNPYmogPSBpdGVtc0Fyci5yZWR1Y2UoZnVuY3Rpb24ob2JqLCBpdGVtKXtcbiAgICAgIHZhciBmaXJzdExldHRlciA9IGl0ZW0uaW5uZXJUZXh0LnRvTG93ZXJDYXNlKCkuc2xpY2UoMCwxKVxuICAgICAgaWYob2JqW2ZpcnN0TGV0dGVyXSA9PT0gdW5kZWZpbmVkKXtcbiAgICAgICAgb2JqW2ZpcnN0TGV0dGVyXSA9IFtdXG4gICAgICB9XG4gICAgICBvYmpbZmlyc3RMZXR0ZXJdLnB1c2goaXRlbS5pZClcbiAgICAgIHJldHVybiBvYmpcbiAgICB9LCB7fSlcbiAgICAvLyBjb25zb2xlLnRhYmxlKGl0ZW1zT2JqKVxuICAgIHJldHVybiBpdGVtc09ialxuICB9LFxuXG4gIG9uS2V5VXBIb3ZlcjogZnVuY3Rpb24ob2JqKXtcbiAgICBcInVzZSBzdHJpY3RcIlxuICAgIHZhciB0aGF0ID0gdGhpc1xuICAgICQod2luZG93KS5vZmYoXCJrZXl1cFwiKVxuICAgICQod2luZG93KS5iaW5kKFwia2V5dXBcIixmdW5jdGlvbihlKXtcbiAgICAgIHZhciBrZXlQcmVzcyA9IFN0cmluZy5mcm9tQ2hhckNvZGUoZS5rZXlDb2RlKS50b0xvd2VyQ2FzZSgpO1xuICAgICAgdGhhdC5zdG9yYWdlLmxldHRlckFyciA9IG9ialtrZXlQcmVzc11cbiAgICAgIHZhciBpZHhBcnIgPSB0aGF0LnN0b3JhZ2UubGV0dGVyQXJyXG5cbiAgICAgIGlmKGlkeEFycil7XG4gICAgICAgIHZhciBpZHhJZCA9IHRoYXQubGV0dGVyU3RhdGUoa2V5UHJlc3MpXG4gICAgICAgIHRoYXQuZm9jdXNCeUVsZW1lbnQoaWR4QXJyLCBpZHhJZClcbiAgICAgIH1cbiAgICB9KVxuICB9LFxuXG4gIGxldHRlclN0YXRlOiBmdW5jdGlvbihsZXR0ZXIpe1xuICAgIFwidXNlIHN0cmljdFwiXG4gICAgLy8gcmVzc2V0IGluZGV4IGlmIGRpZmZlcmVudCBsZXR0ZXIgd2FzIHByZXNzZWRcbiAgICBpZihsZXR0ZXIgIT09IHRoaXMuc3RvcmFnZS5sZXR0ZXIpe1xuICAgICAgdGhpcy5zdG9yYWdlLmluZGV4ID0gMFxuICAgIH1cbiAgICB0aGlzLnN0b3JhZ2UubGV0dGVyID0gbGV0dGVyXG5cbiAgICAvLyBhcnJheS9pbmRleCBpbmNyZXNzaW5nIG9yIHJlc3NldGluZ1xuICAgIHZhciBhcnJMZW5ndGggPSB0aGlzLnN0b3JhZ2UubGV0dGVyQXJyLmxlbmd0aCAtMVxuICAgIHZhciBsYXN0SW5kZXggPSB0aGlzLnN0b3JhZ2UuaW5kZXhcbiAgICBpZih0aGlzLnN0b3JhZ2UuaW5kZXggPCBhcnJMZW5ndGgpe1xuICAgICAgdGhpcy5zdG9yYWdlLmluZGV4ICsrXG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc3RvcmFnZS5pbmRleCA9IDBcbiAgICB9XG4gICAgcmV0dXJuIGxhc3RJbmRleFxuICB9LFxuXG4gIGZvY3VzQnlFbGVtZW50OiBmdW5jdGlvbihsZXR0ZXJJZHNBcnIsIGluZGV4KXtcbiAgICBcInVzZSBzdHJpY3RcIlxuICAgIHZhciBlbGVtZW50ID0gbGV0dGVySWRzQXJyW2luZGV4XVxuICAgIGlmKGVsZW1lbnQpe1xuICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoZWxlbWVudCkuZm9jdXMoKVxuICAgIH1cbiAgfSxcblxuICBjbGVhckxldHRlclN0YXRlOiBmdW5jdGlvbigpe1xuICAgIFwidXNlIHN0cmljdFwiXG4gICAgdGhpcy5zdG9yYWdlLmxldHRlciA9ICcnXG4gICAgdGhpcy5zdG9yYWdlLmluZGV4ID0gMFxuICB9LFxuXG4gIGluaXRGb2N1c0J5TGV0dGVyOiBmdW5jdGlvbihldmVudCl7XG4gICAgXCJ1c2Ugc3RyaWN0XCJcbiAgICB2YXIgZ2V0TGV0dGVyc0luZGV4ID0gdGhpcy5nZXRNZW51SXRlbXMoZXZlbnQpXG4gICAgdGhpcy5vbktleVVwSG92ZXIoZ2V0TGV0dGVyc0luZGV4KVxuICB9LFxuXG4gIC8vIElOSVQnaXNoIGFuZCBldmVyeXRoaW5nIGVsc2UuLi5cbiAgLy8gLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXHRpbml0OiBmdW5jdGlvbigpIHtcbiAgICBcInVzZSBzdHJpY3RcIlxuICAgIHZhciB0aGF0ID0gdGhpc1xuXHRcdGlmICggJCgnW2RhdGEtc2VsZWN0XScpLmxlbmd0aCAmJiAhJCgnYm9keScpLmhhc0NsYXNzKCdpc01vYmlsZScpICl7ICBcbiAgICAgIHZhciBmaWx0ZXJJZCA9IDBcblx0XHRcdCQoJ1tkYXRhLXNlbGVjdF0nKS5lYWNoKGZ1bmN0aW9uKCl7ICAgXG4gICAgICAgIGZpbHRlcklkICsrXG5cdFx0XHRcdHZhciAkZWwgPSAkKHRoaXMpOyAgIFxuXHRcdFx0XHR2YXIgJHNlbGVjdCA9ICRlbC5maW5kKCdzZWxlY3QnKTsgIFxuXHRcdFx0XHR2YXIgbGFiZWwgPSAoJGVsLmRhdGEoJ2xhYmVsJykgJiYgJGVsLmRhdGEoJ2xhYmVsJykubGVuZ3RoID4gMCA/ICRlbC5kYXRhKCdsYWJlbCcpIDogJycpO1xuXG5cdFx0XHRcdGlmICgkZWwuZmluZCgnZHJvcGRvd24nKS5sZW5ndGggPiAwKXsgcmV0dXJuOyB9IFxuXG5cdFx0XHRcdCRlbC5hcHBlbmQoJzxkaXYgY2xhc3M9XCJkcm9wZG93blwiPjxkaXYgY2xhc3M9XCJzZWxlY3RlZFwiPicrbGFiZWwrJHNlbGVjdC5maW5kKCdvcHRpb246c2VsZWN0ZWQnKS50ZXh0KCkrJzwvZGl2PjxkaXYgY2xhc3M9XCJuYW5vXCI+PGRpdiBjbGFzcz1cIm5hbm8tY29udGVudFwiPjx1bD48L3VsPjwvZGl2PjwvZGl2PjwvZGl2PicpXG5cdFx0XHRcdHZhciAkZHJvcGRvd24gPSAkZWwuZmluZCgnLmRyb3Bkb3duJyk7XG5cdFx0XHRcdHZhciAkc2VsZWN0ZWQgPSAkZHJvcGRvd24uZmluZCgnLnNlbGVjdGVkJyk7IFxuXHRcdFx0XHR2YXIgJGxpc3QgPSAkZHJvcGRvd24uZmluZCgnLm5hbm8nKTtcblx0XHRcdCAgXG5cdFx0XHRcdCRzZWxlY3QuZmluZCgnb3B0aW9uJykuZWFjaChmdW5jdGlvbihpbmRleCl7XHRcblx0XHRcdFx0XHR2YXIgc2VsZWN0ZWQgPSAnJztcblx0XHRcdFx0XHRpZiAoICQodGhpcykuaXMoJzpzZWxlY3RlZCcpKXsgc2VsZWN0ZWQgPSBcInN0eWxlPSdkaXNwbGF5Om5vbmU7J1wiOyB9XG5cdFx0XHRcdFx0XHR2YXIgbGkgPSAnPGxpICcr
7437c2VsZWN0ZWQrJyBkYXRhLXZhbD1cIicrJCh0aGlzKS52YWwoKSsnXCIgaWQ9XCJpZHgnK2ZpbHRlcklkK2luZGV4KydcIiB0YWJpbmRleD1cIi0xXCI+JyskKHRoaXMpLnRleHQoKSsnPC9saT4nO1xuXHRcdFx0XHRcdFx0JGRyb3Bkb3duLmZpbmQoJ3VsJykuYXBwZW5kKGxpKTsgIFxuXHRcdFx0XHR9KTsgICBcbiAgICAgICAgLy8gb3BlbiBtZW51XG5cdFx0XHRcdCRzZWxlY3RlZC5jbGljayhmdW5jdGlvbigpeyBcbiAgICAgICAgICAvLyBzZWxlY3QgaXRlbSBieSBwcmVzc2luZyBsZXR0ZXJcbiAgICAgICAgICB0aGF0LmluaXRGb2N1c0J5TGV0dGVyKHRoaXMpXG5cblx0XHRcdFx0XHRpZiAoICRsaXN0Lmhhc0NsYXNzKCdvcGVuJykgKSB7IFxuXHRcdFx0XHRcdFx0JGxpc3QucmVtb3ZlQ2xhc3MoJ29wZW4nKTtcblx0XHRcdFx0XHRcdCRkcm9wZG93bi5yZW1vdmVDbGFzcygnb3BlbicpO1xuICAgICAgICAgICAgJChcIi5uYW5vXCIpLm5hbm9TY3JvbGxlcih7IGRlc3Ryb3k6IHRydWUgfSk7XG5cdFx0XHRcdFx0fSBlbHNlIHsgXG5cdFx0XHRcdFx0XHQkKCcuZHJvcGRvd24ub3BlbicpLnJlbW92ZUNsYXNzKCdvcGVuJyk7IFxuXHRcdFx0XHRcdFx0JCgnLmRyb3Bkb3duIC5uYW5vLm9wZW4nKS5yZW1vdmVDbGFzcygnb3BlbicpO1xuXHRcdFx0XHRcdFx0JGxpc3QuYWRkQ2xhc3MoJ29wZW4nKTtcblx0XHRcdFx0XHRcdCRkcm9wZG93bi5hZGRDbGFzcygnb3BlbicpOyBcblxuICAgICAgICAgICAgJChcIi5uYW5vXCIpLm5hbm9TY3JvbGxlcih7IHNsaWRlck1pbkhlaWdodDogODAsIHNsaWRlck1heEhlaWdodDogODAgfSk7XG4gICAgICAgICAgICAkKCcubmFuby1zbGlkZXInKS5odG1sKCc8c3B
7437hbiBjbGFzcz1cInNUb3BcIj48L3NwYW4+PHNwYW4gY2xhc3M9XCJzTWlkZGxlXCI+PC9zcGFuPjxzcGFuIGNsYXNzPVwic0JvdHRvbVwiPjwvc3Bhbj4nKVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSk7XG4gICAgICAgIC8vIGNsaWNrIG1lbnUgaXRlbVxuXHRcdFx0XHQkZHJvcGRvd24uZmluZCgndWwgbGknKS5vbignY2xpY2sga2V5dXAnLCBmdW5jdGlvbihlKXsgXG4gICAgICAgICAgaWYgKGUud2hpY2ggPT09IDEzIHx8IGUudHlwZSA9PT0gJ2NsaWNrJykge1xuICAgICAgICAgICAgJHNlbGVjdC5maW5kKCdvcHRpb246c2VsZWN0ZWQnKS5yZW1vdmVBdHRyKCdzZWxlY3RlZCcpOyBcbiAgICAgICAgICAgICRzZWxlY3QuZmluZCgnb3B0aW9uW3ZhbHVlPVwiJyskKHRoaXMpLmRhdGEoJ3ZhbCcpKydcIl0nKS5hdHRyKCdzZWxlY3RlZCcsJ3NlbGVjdGVkJyk7XG5cbiAgICAgICAgICAgICRkcm9wZG93bi5maW5kKCd1bCBsaScpLnNob3coKTsgIFxuICAgICAgICAgICAgJCh0aGlzKS5oaWRlKCk7IFxuICAgICAgICAgICAgJGxpc3QudG9nZ2xlQ2xhc3MoJ29wZW4nKTtcbiAgICAgICAgICAgICRkcm9wZG93bi50b2dnbGVDbGFzcygnb3BlbicpOyBcblxuICAgICAgICAgICAgLy8gQXNzaWduIG5ldyB2YWx1ZSBhbmQgdHJpZ2dlciBjaGFuZ2VcbiAgICAgICAgICAgICRzZWxlY3QudmFsKCQodGhpcykuZGF0YSgndmFsJykpLnRyaWdnZXIoJ2NoYW5nZScpO1xuXG4gICAgICAgICAgICAvLyBUcmlnZ2VyIGV2ZW50XG4gICAgICAgICAgICB2YXIgZWwgPSAkc2VsZWN0LmdldCgwKTtcbiAgICAgICAgICAgIHZhciBldmVudCA9IGRvY3VtZW50LmNyZWF0ZUV2ZW50KCdFdmVudHMnKTtcbiAgICAgICAgICAgIGV2ZW50LmluaXRFdmVudCgnY2hhbmdlJywgdHJ1ZSwgZmFsc2UpO1xuICAgICAgICAgICAgZWwuZGlzcGF0Y2hFdmVudChldmVudCk7IC8vIGdvdG8gY29sbGVjdGlvbi5qc1xuICAgICAgICAgIH1cblx0XHRcdFx0fSk7XG5cdFx0XHRcdCRzZWxlY3QuaGlkZSgpO1xuXG5cdFx0XHRcdGlmICggJGVsLmlzKCdbZGF0YS1zZWxlY3QtbGF5b3V0XScpICl7XG5cdFx0XHRcdFx0dmFyIHdpZHRoID0gMDsgXG5cdFx0XHRcdFx0JGVsLmZpbmQoJ2xpJykuZWFjaChmdW5jdGlvbigpeyAgXG5cdFx0XHRcdFx0XHRpZiAoJCh0aGlzKS5vdXRlcldpZHRoKCkgPiB3aWR0aCl7ICBcblx0XHRcdFx0XHRcdFx0d2lkdGggPSAkKHRoaXMpLm91dGVyV2lkdGgoKTsgXG5cdFx0XHRcdFx0XHR9ICAgIFxuXHRcdFx0XHRcdH0pOyBcblx0XHRcdFx0XHQkbGlzdC5jc3MoJ3dpZHRoJyx3aWR0aCk7XG5cdFx0XHRcdFx0JGVsLmFkZENsYXNzKCdyZW5kZXJlZCcpOyAgXG5cdFx0XHRcdFx0aWYgKCAkZWwud2lkdGgoKSA+ICRsaXN0LndpZHRoKCkgKXsgXG5cdFx0XHRcdFx0XHQkbGlzdC5jc3MoJ3dpZHRoJywkZWwub3V0ZXJXaWR0aCgpKTsgXG5cdFx0XHRcdFx0fSAgIFxuXHRcdFx0XHR9XG5cdFx0XHR9KTsgXG5cblx0XHRcdGlmICggJCgnW2RhdGEtc2VsZWN0XScpLmxlbmd0aCApeyBcblx0XHRcdFx0JChkb2N1bWVudCkub24oJ2NsaWNrJywgZnVuY3Rpb24oZSl7XG4gICAgICAgICAgLy8gZGVidWdnZXIgLy8gb3BlbiBtZW51IGNsaWNrOyBsaSBpdGVtIGNsaWNrO1xuXHRcdFx0XHRcdHZhciAkZWwgPSAkKGUudGFyZ2V0KTtcblx0XHRcdFx0XHRpZiAoICRlbC5wYXJlbnRzKCdbZGF0YS1zZWxlY3RdJykubGVuZ3RoID09PSAwICl7IFxuXHRcdFx0XHRcdFx0JCgnLmRyb3Bkb3duLm9wZW4nKS5yZW1vdmVDbGFzcygnb3BlbicpO1xuXHRcdFx0XHRcdFx0JCgnLmRyb3Bkb3duIC5uYW5vLm9wZW4nKS5yZW1vdmVDbGFzcygnb3BlbicpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSk7IFxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGlmICggJCgnW2RhdGEtbW9iaWxlXScpLmxlbmd0aCApeyAgXG5cdFx0XHQkKCdbZGF0YS1tb2JpbGVdJykuZWFjaChmdW5jdGlvbigpeyAgXG5cdFx0XHRcdHZhciAkZWwgPSAkKHRoaXMpOyAgICBcblx0XHRcdFx0dmFyICRzZWxlY3QgPSAkZWwuZmluZCgnc2VsZWN0Jyk7ICBcblx0XHRcdFx0JHNlbGVjdC5jaGFuZ2UoZnVuY3Rpb24oKXsgXG5cdFx0XHRcdFx0Ly8gY29uc29sZS5sb2coJHNlbGVjdC52YWwoKSk7XG5cdFx0XHRcdFx0d2luZG93LmxvY2F0aW9uID0gJHNlbGVjdC52YWwoKTtcblx0XHRcdFx0fSk7XG5cdFx0XHR9KTtcblx0XHR9XG5cblx0fSBcbn1cbiIsIktULk9iamVjdCA9IHtcblx0aW5pdDogZnVuY3Rpb24oKSB7XG5cblx0XHR2YXIgd2lkbm93X3cgPSAkKHdpbmRvdykud2lkdGgoKTtcblx0XHRcblx0XHQvLyBpbWFnZSBzbGlkZXIgXG5cdFx0dmFyIHNsaWRlciA9ICQoJy5zbGlkZXInKS5zbGljayh7XG5cdFx0XHRzbGlkZXNUb1Nob3c6IDEsXG5cdFx0XHRhZGFwdGl2ZUhlaWdodDogdHJ1ZSxcblx0XHRcdGNlbnRlck1vZGU6IGZhbHNlLFxuICBcdFx0XHRpbmZpbml0ZTogZmFsc2UsXG4gIFx0XHRcdHNsaWRlOiAnLnNsaWRlcl9fc2xpZGUnLCBcbiAgXHRcdFx0YXJyb3dzOiB0cnVlLFxuICBcdFx0XHRkcmFnZ2FibGU6IGZhbHNlLFx0XG4gIFx0XHRcdHByZXZBcnJvdzogJzxidXR0b24gY2xhc3M9XCJidG4tLWljb24gaWNvbi1hcnJvdy1sZWZ0IHByZXZcIj5wcmV2aW91cyBpbWFnZTwvYnV0dG9uPicsXG5cdFx0XHRuZXh0QXJyb3c6ICc8YnV0dG9uIGNsYXNzPVwiYnRuLS1pY29uIGljb24tYXJyb3ctcmlnaHQgbmV4dFwiPm5leHQgaW1hZ2U8L2J1dHRvbj4nLFxuXHRcdFx0YXBwZW5kQXJyb3dzOiAnLnNsaWRlcl9fbmF2JyAgICAgICBcblx0XHR9KTsgICBcblxuXHRcdHNsaWRlci5vbignYmVmb3JlQ2hhbmdlJywgZnVuY3Rpb24oZXZlbnQsIHNsaWNrLCBjdXJyZW50U2xpZGUsIG5leHRTbGlkZSl7XG5cdFx0XHRpZiAoICQoJ1tkYXRhLXNsaWRlci1jcmVkaXRzXScpLmxlbmd0aCA+IDApeyBcblx0XHRcdFx0JCgnW2RhdGEtc2xpZGVyLWNyZWRpdHNdJykuZmluZCgncCcpLmhpZGUoKTtcblx0XHRcdFx0JCgnW2RhdGEtc2xpZGVyLWNyZWRpdHNdJykuZmluZCgncDpudGgtY2hpbGQoJytuZXh0U2xpZGUrMSsnKScpLnNob3coKTtcblx0XHRcdH1cblx0XHR9KTtcdFx0XG5cdFx0c2xpZGVyLm9uKCdhZnRlckNoYW5nZScsIGZ1bmN0aW9uKGV2ZW50LCBzbGljaywgY3VycmVudFNsaWRlLCBuZXh0U2xpZGUpe1x0XG5cdFx0XHQkKCdbZGF0YS1jb3VudF0nKS5maW5kKCdzcGFuJykuaHRtbChjdXJyZW50U2xpZGUrMSk7XHRcdFx0XHRcblx0XHR9KTtcblxuXHRcdC8vIGNhcm91c2VsIGZvciBjYXJkcyBvbiBtb2JpbGVcblx0XHR2YXIgc2xpZGVzX3RvX3Nob3cgPSAxLjI7XG5cdFx0aWYod2lkbm93X3cgPiA2MDApeyBzbGlkZXNfdG9fc2hvdyA9IDM7IH1cdFxuXHRcdGlmKHdpZG5vd193ID4gODAwKXsgc2xpZGVzX3RvX3Nob3cgPSA0OyB9XG5cdFx0JCgnLmNhcm91c2VsJykuZWFjaChmdW5jdGlvbigpe1xuXHRcdFx0JCh0aGlzKS5zbGljayh7XG5cdFx0XHRcdHNsaWRlc1RvU2hvdzogc2xpZGVzX3RvX3Nob3csXG5cdFx0XHRcdGFkYXB0aXZlSGVpZ2h0OiB0cnVlLFxuXHRcdFx0XHRjZW50ZXJNb2RlOiBmYWxzZSxcblx0ICBcdFx0XHRpbmZpbml0ZTogZmFsc2UsXG5cdCAgXHRcdFx0c2xpZGU6ICcuY2Fyb3VzZWxfX2l0ZW0nLCBcblx0ICBcdFx0XHRhcnJvd3M6IHRydWUsXG5cdCAgXHRcdFx0cHJldkFycm93OiBmYWxzZSxcblx0XHRcdFx0bmV4dEFycm93OiAnPGJ1dHRvbiBjbGFzcz1cImJ0bi0tY2Fyb3VzZWwgaWNvbi1hcnJvdy1yaWdodCBuZXh0XCI+PC9idXR0b24+Jyxcblx0XHRcdFx0cHJldkFycm93OiAnPGJ1dHRvbiBjbGFzcz1cImJ0bi0tY2Fyb3VzZWwgaWNvbi1hcnJvdy1sZWZ0IHByZXZcIj48L2J1dHRvbj4nLFxuXHRcdFx0XHRhcHBlbmRBcnJvd3M6ICQodGhpcykuZmluZCgnLmNhcm91c2VsX19uYXYnKSAgICAgICBcblx0XHRcdH0pOyBcblx0XHR9KTtcblxuXHR9XG59IiwiS1QuUGFuem9vbSA9IHtcbiAgc2V0dXA6IGZ1bmN0aW9uKCl7XG4gICAgXCJ1c2Ugc3RyaWN0XCJcbiAgICB0aGlzLiRQWl9QYWdlICAgICAgICAgID0gJCgnW2RhdGEtcGFuLXpvb20tcGFnZV0nKVxuICAgIHRoaXMuJFBaX1BhZ2VfU3RhZ2UgICAgPSB0aGlzLiRQWl9QYWdlLmZpbmQoJ1tkYXRhLXBhbi16b29tLXN0YWdlXScpXG4gICAgdGhpcy4kUFpfUGFnZV9JbWFnZXMgICA9IHRoaXMuJFBaX1BhZ2VfU3RhZ2UuZmluZCgnaW1nJylcbiAgICB0aGlzLiRQWl9QYWdlX0luc3RhbmNlID0gdGhpcy4kUFpfUGFnZV9TdGFnZS5wYW56b29tKHtcdC8vIFBsdWdpbiBzZXR1cFxuICAgICAgbWluU2NhbGU6IDEsXG4gICAgICBpbmNyZW1lbnQ6IDAuMyxcbiAgICAgIGR1cmF0aW9uOiA0MDAsIC8vIEFuaW1hdGlvbiBkdXJhdGlvbiAobXMpXG4gICAgICAkem9vbUluOiAgdGhpcy4kUFpfUGFnZS5maW5kKCdbZGF0YS16b29tLWluXScpLFxuICAgICAgJHpvb21PdXQ6IHRoaXMuJFBaX1BhZ2UuZmluZCgnW2RhdGEtem9vbS1vdXRdJylcbiAgICB9KVxuXG4gICAgdGhpcy4kUFpfTGlnaHRib3ggICAgICAgICAgPSAkKCdbZGF0YS1wYW4tem9vbS1saWdodGJveF0nKVxuICAgIHRoaXMuJFBaX0xpZ2h0Ym94X1N0YWdlICAgID0gdGhpcy4kUFpfTGlnaHRib3guZmluZCgnW2RhdGEtcGFuLXpvb20tc3RhZ2VdJylcbiAgICB0aGlzLiRQWl9MaWdodGJveF9JbWFnZXMgICA9IHRoaXMuJFBaX0xpZ2h0Ym94X1N0YWdlLmZpbmQoJ2ltZycpXG4gICAgdGhpcy4kUFpfTGlnaHRib3hfSW5zdGFuY2UgPSB0aGlzLiRQWl9MaWdodGJveF9TdGFnZS5wYW56b29tKHtcdC8vIFBsdWdpbiBzZXR1cFxuICAgICAgbWluU2NhbGU6IDAuNSxcbiAgICAgIGluY3JlbWVudDogMC4zLFxuICAgICAgZHVyYXRpb246IDQwMCwgLy8gQW5pbWF0aW9uIGR1cmF0aW9uIChtcylcbiAgICAgICR6b29tSW46ICB0aGlzLiRQWl9MaWdodGJveC5maW5kKCdbZGF0YS16b29tLWluXScpLFxuICAgICAgJHpvb21PdXQ6IHRoaXMuJFBaX0xpZ2h0Ym94LmZpbmQoJ1tkYXRhLXpvb20tb3V0XScpXG4gICAgfSlcblxuICAgI
7437HRoaXMuY3VycmVudEltZyA9IDFcbiAgfSxcblxuXG4gIHNob3dDdXJyZW50SW1hZ2U6IGZ1bmN0aW9uKCl7XG4gICAgXCJ1c2Ugc3RyaWN0XCJcbiAgICAkKCdbZGF0YS1vYmplY3QtbGlnaHRib3hdJykuYWRkQ2xhc3MoJ3Zpc2libGUnKVxuICAgICQoJ2JvZHknKS5hZGRDbGFzcygnbm8tc2Nyb2xsJylcdFxuXG4gICAgdGhpcy4kUFpfUGFnZV9TdGFnZS5maW5kKCcuc2xpZGVyX19pbWFnZScpLmhpZGUoKVx0XG4gICAgdmFyICRuZXh0X2ltZ19wYWdlID0gdGhpcy4kUFpfUGFnZV9TdGFnZS5maW5kKCcuc2xpZGVyX19pbWFnZTpudGgtY2hpbGQoJysodGhpcy5jdXJyZW50SW1nKSsnKScpXG4gICAgJG5leHRfaW1nX3BhZ2UuYXR0cignc3JjJywgJG5leHRfaW1nX3BhZ2UuZGF0YSgnc3JjJykgKVxuICAgICRuZXh0X2ltZ19wYWdlLnNob3coKVxuICAgIFxuICAgIHRoaXMuJFBaX0xpZ2h0Ym94X1N0YWdlLmZpbmQoJy5zbGlkZXJfX2ltYWdlJykuaGlkZSgpXG4gICAgdmFyICRuZXh0X2ltZ19saWdodGJveCA9IHRoaXMuJFBaX0xpZ2h0Ym94X1N0YWdlLmZpbmQoJy5zbGlkZXJfX2ltYWdlOm50aC1jaGlsZCgnKyh0aGlzLmN1cnJlbnRJbWcpKycpJylcbiAgICAkbmV4dF9pbWdfbGlnaHRib3guYXR0cignc3JjJywgJG5leHRfaW1nX2xpZ2h0Ym94LmRhdGEoJ3NyYycpIClcbiAgICAkbmV4dF9pbWdfbGlnaHRib3guc2hvdygpXG5cbiAgICAkKCdbZGF0YS1nYWxsZXJ5XScpLnJlbW92ZUNsYXNzKCd2aXNpYmxlJylcbiAgICB0aGlzLiRQWl9MaWdodGJveC5hZGRDbGFzcygndmlzaWJsZScpXG4gIH0sXG5cblxuICB1cGRhdGVJbmRleDogZnVuY3Rpb24oJGltZ0NvbnRhaW5lcil7XG4gICAgXCJ1c2Ugc3RyaWN0XCJcbiAgICB2YXIgJGltZyA9ICRpbWdDb250YWluZXIuZmluZCgnaW1nJylcbiAgICB0aGlzLmN1cnJlbnRJbWcgPSAkaW1nLmRhdGEoJ2luZGV4JykrMSAvLyBjbGVhbmluZzogZGF0YS1rZXkgbm8gbG9uZ2VyIG5lZWRlZCBpbiBtYXJrZG93blxuICAgICQoJ1tkYXRhLWNvdW50XSBzcGFuJykuaHRtbCh0aGlzLmN1cnJlbnRJbWcpIFxuICB9LFxuXG5cbiAgY29weXJpZ2h0OiBmdW5jdGlvbigpe1xuICAgIFwidXNlIHN0cmljdFwiXG4gICAgJCgnW2RhdGEtY29weXJpZ2h0XScpLmhpZGUoKVxuICAgICQoJ1tkYXRhLWNvcHlyaWdodF06bnRoLWNoaWxkKCcrdGhpcy5jdXJyZW50SW1nKycpJykuc2hvdygpXG4gIH0sXG5cblxuICBwcmV2TmV4dEltZzogZnVuY3Rpb24odmFyaWFudCwgZGlyZWN0aW9uKXtcbiAgICBcInVzZSBzdHJpY3RcIlxuICAgIHZhciAkUFosICRQWl9JbnN0YW5jZSwgJFBaX1N0YWdlLCAkUFpfSW1hZ2VzXG4gICAgdmFyIHRoYXQgPSB0aGlzXG5cbiAgICBzd2l0Y2godmFyaWFudCl7XG4gICAgICBjYXNlICdwYWdlJzpcbiAgICAgICAgJFBaID0gdGhpcy4kUFpfUGFnZVxuICAgICAgICAkUFpfSW5zdGFuY2UgPSB0aGlzLiRQWl9QYWdlX0luc3RhbmNlXG4gICAgICAgICRQWl9TdGFnZSA9IHRoaXMuJFBaX1BhZ2VfU3RhZ2VcbiAgICAgICAgJFBaX0ltYWdlcyA9IHRoaXMuJFBaX1BhZ2VfSW1hZ2VzXG4gICAgICAgIGJyZWFrXG4gICAgICBjYXNlICdsaWdodGJveCc6XG4gICAgICAgICRQWiA9IHRoaXMuJFBaX0xpZ2h0Ym94IFxuICAgICAgICAkUFpfSW5zdGFuY2UgPSB0aGlzLiRQWl9MaWdodGJveF9JbnN0YW5jZVxuICAgICAgICAkUFpfU3RhZ2UgPSB0aGlzLiRQWl9MaWdodGJveF9TdGFnZVxuICAgICAgICAkUFpfSW1hZ2VzID0gdGhpcy4kUFpfTGlnaHRib3hfSW1hZ2VzXG4gICAgICAgIGJyZWFrXG4gICAgfVxuICAgIFxuICAgIHZhciBlbGVtZW50LCBjaGlsZE51bWJlclxuICAgIHN3aXRjaChkaXJlY3Rpb24pe1xuICAgICAgY2FzZSAncHJldic6XG4gICAgICAgIGVsZW1lbnQgPSAnW2RhdGEtcHJldl0nXG4gICAgICAgIGNoaWxkTnVtYmVyID0gLTFcbiAgICAgICAgYnJlYWtcbiAgICAgIGNhc2UgJ25leHQnOlxuICAgICAgICBlbGVtZW50ID0gJ1tkYXRhLW5leHRdJ1xuICAgICAgICBjaGlsZE51bWJlciA9ICsxXG4gICAgICAgIGJyZWFrXG4gICAgfVxuXG4gICAgJFBaLmZpbmQoZWxlbWVudCkub24oJ2NsaWNrJywgZnVuY3Rpb24oKXsgXG4gICAgICBpZiggIGRpcmVjdGlvbiA9PT0gJ3ByZXYnICYmIHRoaXMuY3VycmVudEltZyA9PT0gMSApeyByZXR1cm4gZmFsc2UgfVxuICAgICAgaWYoIChkaXJlY3Rpb24gPT09ICduZXh0JyAmJiB0aGlzLmN1cnJlbnRJbWcgPT09ICRQWl9JbWFnZXMubGVuZ3RoKSB8fCB0aGlzLmN1cnJlbnRJbWcgPiAkUFpfSW1hZ2VzLmxlbmd0aCl7IHJldHVybiBmYWxzZSB9XG4gICAgICAkKCRQWikuZmluZCgnLnNsaWRlcl9faW1hZ2U6bnRoLWNoaWxkKCcrdGhhdC5jdXJyZW50SW1nKycpJylcbiAgICAgICAgLmhpZGUoKVxuICAgICAgJFBaX0luc3RhbmNlLnBhbnpvb20oXCJyZXNldFwiKSAvLyByZXNldCB6b29tXG4gICAgICB2Y
7437XIgJG5leHRfaW1nID0gJCgkUFpfU3RhZ2UpLmZpbmQoJy5zbGlkZXJfX2ltYWdlOm50aC1jaGlsZCgnKyh0aGlzLmN1cnJlbnRJbWcgKyBjaGlsZE51bWJlcikrJyknKVxuICAgICAgJG5leHRfaW1nLmF0dHIoJ3NyYycsICRuZXh0X2ltZy5kYXRhKCdzcmMnKSApXG4gICAgICAgIC5zaG93KCkgXG5cbiAgICAgIHRoaXMudXBkYXRlSW5kZXgoJG5leHRfaW1nKVxuICAgICAgdGhpcy5jb3B5cmlnaHQoKVxuICAgIH0uYmluZCh0aGlzKSlcbiAgfSxcblxuXG5cdGluaXQ6IGZ1bmN0aW9uKCkge1xuICAgIFwidXNlIHN0cmljdFwiXG4gICAgdGhpcy5zZXR1cCgpXG5cblx0XHQvLyBQYW4gem9vbSBQQUdFXG4gICAgLy8gLy8vLy8vLy8vLy8vLy8vL1xuICAgIHRoaXMucHJldk5leHRJbWcoJ3BhZ2UnLCAncHJldicpXG4gICAgdGhpcy5wcmV2TmV4dEltZygncGFnZScsICduZXh0JylcblxuXHRcdC8vIFBhbiB6b29tIExJR0hUIEJPWFxuICAgIC8vIC8vLy8vLy8vLy8vLy8vLy8vXG4gICAgdGhpcy5wcmV2TmV4dEltZygnbGlnaHRib3gnLCAncHJldicpXG4gICAgdGhpcy5wcmV2TmV4dEltZygnbGlnaHRib3gnLCAnbmV4dCcpXG5cblx0XHQkKCdbZGF0YS1mdWxsc2NyZWVuXScpLm9uKCdjbGljaycsIGZ1bmN0aW9uKCl7IFxuICAgICAgdGhpcy5zaG93Q3VycmVudEltYWdlKClcblx0XHR9LmJpbmQodGhpcykpXHRcdFxuXG5cdFx0JCgnW2RhdGEtZnVsbHNjcmVlbi1jbG9zZV0nKS5vbignY2xpY2snLCBmdW5jdGlvbigpeyBcbiAgICAgIHRoaXMuc2hvd0N1cnJlbnRJbWFnZSgpXG5cdFx0XHQkKCdbZGF0YS1vYmplY3QtbGlnaHRib3hdJykucmVtb3ZlQ2xhc3MoJ3Zpc2libGUnKVxuXHRcdFx0JCgnYm9keScpLnJlbW92ZUNsYXNzKCduby1zY3JvbGwnKVxuXHRcdH0uYmluZCh0aGlzKSlcdFxuXG5cdFx0JCgnW2RhdGEtYm90dG9tLWNsb3NlXScpLm9uKCdjbGljaycsIGZ1bmN0aW9uKCl7IFx0XG5cdFx0XHRpZiAoJCh0aGlzKS5oYXNDbGFzcygnY29sbGFwc2VkJykpIHsgXHRcdFx0XHRcblx0XHRcdFx0JCgnW2RhdGEtb2JqZWN0LWxpZ2h0Ym94XScpLnJlbW92ZUNsYXNzKCdib3R0b20taGlkZGVuJylcblx0XHRcdFx0JCh0aGlzKS5yZW1vdmVDbGFzcygnY29sbGFwc2VkJylcdFx0XG5cdFx0XHR9IGVsc2UgeyBcblx0XHRcdFx0JCgnW2RhdGEtb2JqZWN0LWxpZ2h0Ym94XScpLmFkZENsYXNzKCdib3R0b20taGlkZGVuJylcblx0XHRcdFx0JCh0aGlzKS5hZGRDbGFzcygnY29sbGFwc2VkJylcdFx0XG5cdFx0XHR9XG5cdFx0fS5iaW5kKHRoaXMpKVx0XG5cblx0XHQvLyBHYWxsZXJ5IHZpZXcgLSBhbGwgaW1hZ2VzIGluIHBhbnpvb20gbW9kZVxuICAgIC8vIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXHRcdCQoJ1tkYXRhLWdhbGxlcnktdG9nZ2xlXScpLm9uKCdjbGljaycsIGZ1bmN0aW9uKCl7IC8vIG9wZW4gZ2FsbGVyeVxuXHRcdFx0dGhpcy4kUFpfTGlnaHRib3gucmVtb3ZlQ2xhc3MoJ3Zpc2libGUnKVxuXHRcdFx0JCgnW2RhdGEtZ2FsbGVyeV0nKS5hZGRDbGFzcygndmlzaWJsZScpXG5cdFx0fS5iaW5kKHRoaXMpKVxuXG5cdFx0JCgnW2RhdGEtZ2FsbGVyeV0gLmltZycpLm9uKCdjbGljaycsIGZ1bmN0aW9uKGV2ZW50KXsgLy8gY2xvc2UgZ2FsbGVyeVxuICAgICAgdmFyICRpbWdDb250YWluZXIgPSAkKGV2ZW50LnRhcmdldC5jbG9zZXN0KCcuaW1nJykpIFxuICAgICAgdGhpcy51cGRhdGVJbmRleCgkaW1nQ29udGFpbmVyKVxuICAgICAgdGhpcy5zaG93Q3VycmVudEltYWdlKClcbiAgICAgIHRoaXMuY29weXJpZ2h0KClcblxuXHRcdFx0dGhpcy4kUFpfUGFnZV9JbnN0YW5jZS5wYW56b29tKFwicmVzZXRcIikgLy8gcmVzZXQgem9vbVxuXHRcdFx0dGhpcy4kUFpfTGlnaHRib3hfSW5zdGFuY2UucGFuem9vbShcInJlc2V0XCIpIC8vIHJlc2V0IHpvb21cblx0XHR9LmJpbmQodGhpcykpXG5cblx0fVxufVxuIiwiXG5cbiQoJ1tkYXRhLXNlYXJjaC1jb250ZW50LXRvZ2dsZV0nKS5vbignY2xpY2snLCBmdW5jdGlvbigpeyBcblx0dmFyIHRleHQgPSAkKHRoaXMpLnRleHQoKTtcblx0JCh0aGlzKS50b2dnbGVDbGFzcygnYWN0aXZlJyk7XG5cdCQodGhpcykuaHRtbCgkKHRoaXMpLmF0dHIoJ3JlbCcpKS5hdHRyKCdyZWwnLCB0ZXh0KTtcdFxuXHQkKHRoaXMpLnBhcmVudHMoJy5zZWFyY2gtYmFyJykudG9nZ2xlQ2xhc3MoJ3NlYXJjaC1iYXItLW9wZW4nKTtcbn0pO1x0XHRcdFx0XHQiLCIvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIENvbGxlY3Rpb24gXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbktULkNvbGxlY3Rpb24gPSB7XG4gIG1vcmVUYWdzOiBmdW5jdGlvbigpe1xuICAgICQoJ1tkYXRhLW1vcmUtdGFnc10nKS5vbignY2xpY2snLCBmdW5jdGlvbigpeyBcdFxuICAgICAgdmFyICRjb250YWluZXIgPSAkKCcudGFncycpXG4gICAgICB2Y
7437XIgJHRhZyA9ICAkY29udGFpbmVyLmZpbmQoJy50YWcnKVxuICAgICAgdmFyICRoaWRlblRhZ3MgPSAkY29udGFpbmVyLmZpbmQoJy5oaWRkZW4nKVxuXG4gICAgICB2YXIgYm94SGVpZ2h0ID0gJGNvbnRhaW5lci5oZWlnaHQoKVxuICAgICAgdmFyIGxpbmVIZWlnaHQgPSAkdGFnLm91dGVySGVpZ2h0KHRydWUpXG4gICAgICAgIC8vIGNvbnNvbGUubG9nKFwiaXQgc2hvdWxkIGJ5IDA6IFwiICsgYm94SGVpZ2h0ICUgbGluZUhlaWdodClcblxuICAgICAgaWYoJGhpZGVuVGFncy5sZW5ndGggPT0gMCl7XG4gICAgICAgICRjb250YWluZXIuZmluZCgnW2RhdGEtaGlkZGVuXScpLnRvZ2dsZUNsYXNzKCdoaWRkZW4nKVxuICAgICAgICB2YXIgdGV4dCA9ICQodGhpcykudGV4dCgpIC8vIHRvb2dsZSBhdHRyPC0+dGV4dFxuICAgICAgICAkKHRoaXMpLmh0bWwoJCh0aGlzKS5hdHRyKCdyZWwnKSkuYXR0cigncmVsJywgdGV4dClcdFxuICAgICAgfVxuXG4gICAgICBmb3IodmFyIGk9MDsgaSA8ICRoaWRlblRhZ3MubGVuZ3RoOyBpKyspe1xuICAgICAgICB2YXIgYm94SGVpZ2h0RXhwYW5kID0gJGNvbnRhaW5lci5oZWlnaHQoKVxuICAgICAgICB2YXIgaGVpZ2h0QWRkZWQgPSBib3hIZWlnaHRFeHBhbmQgLSBib3hIZWlnaHRcblxuICAgICAgICBpZigoaGVpZ2h0QWRkZWQgLyBsaW5lSGVpZ2h0KSA8IDQpe1xuICAgICAgICAgICRoaWRlblRhZ3MuZXEoaSkudG9nZ2xlQ2xhc3MoJ2hpZGRlbicpXG4gICAgICAgIH0gXG4gICAgICB9XG5cbiAgICAgIC8vIHVwZGF0ZSBET00gdmFyaWFibGVzXG4gICAgICAvLyB2YXIgYm94SGVpZ2h0ID0gJGNvbnRhaW5lci5oZWlnaHQoKVxuICAgICAgdmFyICRoaWRlblRhZ3MgPSAkY29udGFpbmVyLmZpbmQoJy5oaWRkZW4nKVxuXG4gICAgICBpZigkaGlkZW5UYWdzLmxlbmd0aCA9PSAwKXtcbiAgICAgICAgdmFyIHRleHQgPSAkKHRoaXMpLnRleHQoKSAvLyB0b29nbGUgYXR0cjwtPnRleHRcbiAgICAgICAgJCh0aGlzKS5odG1sKCQodGhpcykuYXR0cigncmVsJykpLmF0dHIoJ3JlbCcsIHRleHQpXHRcbiAgICAgIH1cblxuICAgIH0pXG4gIH0sXG5cbiAgcmVkdWNlVGFnczogZnVuY3Rpb24oKXtcbiAgICB2YXIgaXNNb2JpbGUgPSAkKCdib2R5JykuaGFzQ2xhc3MoJ21vYmlsZScpXG4gICAgaWYoaXNNb2JpbGUpe1xuICAgICAgdmFyICRjb250YWluZXIgPSAkKCcudGFncycpXG4gICAgICB2Y
7437XIgJHRhZyA9ICAkY29udGFpbmVyLmZpbmQoJy50YWcnKVxuICAgICAgdmFyICR2aXNpYmxlVGFncyA9ICRjb250YWluZXIuZmluZCgnYTpub3QoLmhpZGRlbiknKVxuICAgICAgICAvLyBjb25zb2xlLmxvZygkdmlzaWJsZVRhZ3MpXG4gICAgICAgIC8vIGNvbnNvbGUubG9nKCR2aXNpYmxlVGFncy5sZW5ndGgpXG4gICAgICBcbiAgICAgIHZhciAkdmlzaWJsZVRhZ3MgPSAkY29udGFpbmVyLmZpbmQoJ2E6bm90KC5oaWRkZW4pJylcbiAgICAgIHZhciBib3hIZWlnaHQgPSAkY29udGFpbmVyLmhlaWdodCgpXG4gICAgICB2YXIgbGluZUhlaWdodCA9ICR0YWcub3V0ZXJIZWlnaHQodHJ1ZSlcbiAgICAgICAgLy8gY29uc29sZS5sb2coXCJpdCBzaG91bGQgYnkgMDogXCIgKyBib3hIZWlnaHQgJSBsaW5lSGVpZ2h0KVxuXG4gICAgICBmb3IodmFyIGk9JHZpc2libGVUYWdzLmxlbmd0aDsgaT4wOyBpLS0pe1xuICAgICAgdmFyICR2aXNpYmxlVGFncyA9ICRjb250YWluZXIuZmluZCgnYTpub3QoLmhpZGRlbiknKVxuICAgICAgICB2YXIgYm94SGVpZ2h0UmVkdWNlZCA9ICRjb250YWluZXIuaGVpZ2h0KClcbiAgICAgICAgLy8gY29uc29sZS5sb2coYm94SGVpZ2h0UmVkdWNlZCwgJ2JveEhlaWdodFJlZHVjZWQnKVxuICAgICAgICAvLyBjb25zb2xlLmxvZyhsaW5lSGVpZ2h0LCAnYm94SGVpZ2h0JylcbiAgICAgICAgLy8gY29uc29sZS5sb2coYm94SGVpZ2h0UmVkdWNlZCAvIGxpbmVIZWlnaHQpXG5cbiAgICAgICAgaWYoKGJveEhlaWdodFJlZHVjZWQgLyBsaW5lSGVpZ2h0KSA+IDQpe1xuICAgICAgICAgICR2aXNpYmxlVGFncy5lcShpKS50b2dnbGVDbGFzcygnaGlkZGVuJylcbiAgICAgICAgfSBcbiAgICAgIH1cbiAgICB9XG4gIH0sXG5cbiAgaW1hZ2VUb2dnbGU6IGZ1bmN0aW9uKCRmb3JtKXtcbiAgICAkKCcjaGFzX2ltYWdlX3RvZ2dsZScpLm9uKCdjbGljaycsIGZ1bmN0aW9uKCl7IFx0XG4gICAgICAkKCcjaGFzX2ltYWdlJykuYXR0cignY2hlY2tlZCcsIHRydWUpXG4gICAgICAkKCcjaGFzX2RvY3VtZW50JykuYXR0cignY2hlY2tlZCcsIGZhbHNlKVxuICAgICAgJGZvcm0uc3VibWl0KCkgXG4gICAgfSlcdFx0XG4gIH0sXG5cbiAgZG9jdW1lbnRUb2dnbGU6IGZ1bmN0aW9uKCRmb3JtKXtcbiAgICAkKCcjaGFzX2RvY3VtZW50X3RvZ2dsZScpLm9uKCdjbGljaycsIGZ1bmN0aW9uKCl7XHRcbiAgICAgICQoJyNoYXNfaW1hZ2UnKS5hdHRyKCdjaGVja2VkJywgZmFsc2UpXG4gICAgICAkKCcjaGFzX2RvY3VtZW50JykuYXR0cignY2hlY2tlZCcsIHRydWUpXG4gICAgICAkZm9ybS5zdWJtaXQoKVx0XHRcbiAgICB9KVxuICB9LFxuXG4gIGluaXQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMubW9yZVRhZ3MoKVxuICAgIHRoaXMucmVkdWNlVGFncygpXG5cbiAgICAvLyBkb2N1bWVudCBvciBpbWFnZSB0b29nbGUuIFNvbWUgZGF5IG1ha2UgaXQgRFJZKG9uZSBmdW5jdGlvbikuXG4gICAgdmFyICRkYXRhQ29sbGVjdGlvblNlYXJjaCA9ICQoJ1tkYXRhLWNvbGxlY3Rpb24tc2VhcmNoXScpXG4gICAgaWYgKCAkZGF0YUNvbGxlY3Rpb25TZWFyY2gubGVuZ3RoICl7XG4gICAgICB2Y
7437XIgJGZvcm0gPSAkZGF0YUNvbGxlY3Rpb25TZWFyY2guZmluZCgnZm9ybScpXG5cbiAgICAgICRkYXRhQ29sbGVjdGlvblNlYXJjaC5maW5kKCdzZWxlY3QnKVxuICAgICAgICAub24oJ2NoYW5nZScsIGZ1bmN0aW9uKCl7IFxuICAgICAgICAgICRmb3JtLnN1Ym1pdCgpXG4gICAgICAgIH0pXG4gICAgICAgXG4gICAgICB0aGlzLmRvY3VtZW50VG9nZ2xlKCRmb3JtKVxuICAgICAgdGhpcy5pbWFnZVRvZ2dsZSgkZm9ybSlcbiAgICB9XG5cbiAgfVxufVxuIFxuIiwiLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBBamF4IHBhZ2luYXRpb24gXG4vLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbktULkFqYXhQYWdpbmF0aW9uID0geyBcbiAgICBpbml0OiBmdW5jdGlvbigpIHtcbiBcbiAgICAgICAgLy8gQ29sbGVjdGlvbiBPYmplY3RzXG4gICAgICAgIGlmKCAkKCdbZGF0YS1hamF4LXBhZ2luYXRlXScpLmxlbmd0aCA+IDAgKXsgXG4gICAgICAgICAgIEtULkFqYXhQYWdpbmF0aW9uLmFqYXhfY29sbGVjdGlvbigpOyAgICAgXG4gICAgICAgIH1cblxuICAgIH0sICAgICAgXG4gICAgYWpheF9jb2xsZWN0aW9uOiBmdW5jdGlvbigpeyBcbiAgICAgXG4gICAgICAgIHZhciAkZWwgPSAkKCdbZGF0YS1hamF4LXBhZ2luYXRlXScpLmZpbmQoJ2EnKTsgICBcbiAgICAgICAgdmFyICRjb250YWluZXIgPSAkKCdbZGF0YS1hamF4LWdyaWRdJyk7ICAgICBcbiAgICAgICAgdmFyICRsb2FkZXIgPSAkZWwubmV4dCgnLmxvYWRlcicpO1xuICAgICAgICB2Y
7437XIgdXJsID0gJGVsLmF0dHIoJ2hyZWYnKTtcblxuICAgICAgICB2YXIgJGZvcm0gPSAkKCdbZGF0YS1jb2xsZWN0aW9uLXNlYXJjaF0nKTtcbiAgICAgICBcbiAgICAgICAgdmFyIHBhcmFtcyA9IHsgXG4gICAgICAgICAgICBwYWdlOiAkKCdbZGF0YS1wYWdlXScpLmRhdGEoJ3BhZ2UnKSxcbiAgICAgICAgICAgIHZpZXdfYXM6ICQoJ1tkYXRhLXZpZXddJykuZGF0YSgndmlldycpICAgICAgXG4gICAgICAgIH07XG4gICAgICAgIFxuICAgICAgICAkZWwub24oJ2NsaWNrJywgZnVuY3Rpb24oZXZlbnQpe1xuICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsgICAgICAgICBcbiAgICAgICAgICAgICRlbC5oaWRlKCk7ICAgIFxuICAgICAgICAgICAgJGxvYWRlci5hZGRDbGFzcygndmlzaWJsZScpOyAgICBcbiAgICAgICAgICAgIHBhcmFtcy5wYWdlID0gcGFyYW1zLnBhZ2UrMTsgICBcbiBcbiAgICAgICAgICAgICQuYWpheCh7XG4gICAgICAgICAgICAgICAgdXJsOiB1cmwsIFxuICAgICAgICAgICAgICAgIENvbnRlbnRUeXBlOiBcImFwcGxpY2F0aW9uL2pzb247IGNoYXJzZXQ9dXRmLThcIixcbiAgICAgICAgICAgICAgICBkYXRhIDogcGFyYW1zLCAgICAgICAgIFxuICAgICAgICAgICAgICAgIHR5cGU6ICdQT1NUJ1xuICAgICAgICAgICAgfSkuZG9uZShmdW5jdGlvbihkYXRhKXsgICBcbiAgICAgICAgICAgICAgICBkYXRhID0gSlNPTi5wYXJzZShkYXRhKTtcblxuICAgICAgICAgICAgICAgIHZhciAkaHRtbCA9ICQoZGF0YS5odG1sKTtcbiAgICAgICAgICAgICAgICAkY29udGFpbmVyLmFwcGVuZCgkaHRtbCk7XG4gICAgICAgICAgICAgICAgJGxvYWRlci5yZW1vdmVDbGFzcygndmlzaWJsZScpOyBcbiAgICAgICAgICAgICAgICAvLyAkaHRtbC5pbWFnZXNMb2FkZWQoZnVuY3Rpb24oKSB7IFxuICAgICAgICAgICAgICAgIC8vICAgICAkaHRtbC5hZGRDbGFzcygndmlzaWJsZScpOyBcbiAgICAgICAgICAgICAgICAvLyB9KTsgXG4gICAgICAgICAgICAgICAgaWYoZGF0YS5sb2FkX21vcmUpeyAgXG4gICAgICAgICAgICAgICAgICAgICRlbC5zaG93KCk7ICAgXG4gICAgICAgICAgICAgICAgfSBlbHNlIHsgIFxuICAgICAgICAgICAgICAgICAgICAkZWwuaGlkZSgpOyAgIFxuICAgICAgICAgICAgICAgIH0gICAgICAgICAgIFxuXG4gICAgICAgICAgICAgICAgS1QuQWpheFBhZ2luYXRpb24udXBkYXRlX3VybChwYXJhbXMucGFnZSk7XG4gICAgICAgICAgICB9KTsgXG4gICAgICAgIH0pO1xuXG4gICAgICAgIEtULkFqYXhQYWdpbmF0aW9uLnNjcm9sbF90b190b3AoKTsgICAgICBcbiAgICB9LFxuICAgIHNjcm9sbF90b190b3A6IGZ1bmN0aW9uKCl7IFxuXG4gICAgICAgIHZhciAkYmFja1RvcCA9ICQoJy5iYWNrLXRvcCcpO1xuICBcbiAgICAgICAgJCh3aW5kb3cpLnNjcm9sbChmdW5jdGlvbigpIHsgICAgICAgICAgIFxuICAgICAgICAgICAgXG4gICAgICAgICAgICB2Y
7437XIgc3QgPSAkKHRoaXMpLnNjcm9sbFRvcCgpOyAgIFxuXG4gICAgICAgICAgICAvL3Nob3cgLyBoaWRlIGJhY2sgdG8gdG9wXG4gICAgICAgICAgICBpZiAoc3QgPiAxMDAwKSB7XG4gICAgICAgICAgICAgICAgJGJhY2tUb3Auc2hvdygpXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICRiYWNrVG9wLmhpZGUoKSAgXG4gICAgICAgICAgICB9ICAgXG4gICAgICAgIH0pO1xuICBcbiAgICAgICAgJGJhY2tUb3Aub24oJ2NsaWNrJywgZnVuY3Rpb24oZSkgeyAgXG4gICAgICAgICAgICAkKCdodG1sLGJvZHknKS5hbmltYXRlKHsgc2Nyb2xsVG9wOiAwIH0sIDEwMDApOyBcbiAgICAgICAgfSk7IFxuICAgIFxuICAgIH0sXG4gICAgdXBkYXRlX3VybDogZnVuY3Rpb24ocGFnZV9ubyl7IFxuICAgICAgICBpZiAoaGlzdG9yeS5wdXNoU3RhdGUpIHtcbiAgICAgICAgICAgIHZhciBuZXdwYXRobmFtZSA9IHdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZTtcbiAgICAgICAgICAgIHZhciBwYXRoQXJyYXkgPSB3aW5kb3cubG9jYXRpb24ucGF0aG5hbWUuc3BsaXQoJy8nKTtcbiAgICAgICAgICAgIGlmICh3aW5kb3cubG9jYXRpb24ucGF0aG5hbWUuaW5kZXhPZigncGFnZS8nKSA8IDApIHtcbiAgICAgICAgICAgICAgICBwYXRoQXJyYXkucHVzaCgncGFnZScpO1xuICAgICAgICAgICAgICAgIHBhdGhBcnJheS5wdXNoKHBhZ2Vfbm8pOyBcbiAgICAgICAgICAgICAgICBuZXdwYXRobmFtZSA9IHBhdGhBcnJheS5qb2luKCcvJyk7XG4gXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHZhciBpbmRleF9wYWdlID0gcGF0aEFycmF5LmluZGV4T2YoJ3BhZ2UnKTtcbiAgICAgICAgICAgICAgICB2Y
7437XIgaW5kZXhfcGFnZV9ubyA9IGluZGV4X3BhZ2UgKyAxO1xuICAgICAgICAgICAgICAgIGlmIChpbmRleF9wYWdlID4gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgcGF0aEFycmF5W2luZGV4X3BhZ2Vfbm9dID0gcGFnZV9ubztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbmV3cGF0aG5hbWUgPSBwYXRoQXJyYXkuam9pbignLycpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIG5ld3VybCA9IHdpbmRvdy5sb2NhdGlvbi5wcm90b2NvbCArIFwiLy9cIiArIHdpbmRvdy5sb2NhdGlvbi5ob3N0ICsgbmV3cGF0aG5hbWU7XG4gICAgICAgICAgICB3aW5kb3cuaGlzdG9yeS5wdXNoU3RhdGUoe30sICcnLCBuZXd1cmwpO1xuICAgICAgICAgICAgd2luZG93LmxvY2F0aW9uLnBhdGhuYW1lLnNwbGl0KCcvJykuaW5kZXhPZigncGFnZScpICsgMTtcbiAgICAgICAgfVxuICAgIH1cbn0iLCJLVC5BamF4Rm9ybSA9IHtcblx0aW5pdDogZnVuY3Rpb24oKSB7XG5cdFx0dmFyICRhamF4Rm9ybSA9ICQoJy5hamF4LWZvcm0nKTtcblxuXHRcdCRhamF4Rm9ybS5vbignc3VibWl0JywgZnVuY3Rpb24oZSkgeyBjb25zb2xlLmxvZyhlKTsgXG5cdFx0XHRlLnByZXZlbnREZWZhdWx0KCk7XG5cdFx0XHR2YXIgJGZvcm0gPSAkKHRoaXMpO1xuXHRcdFx0dmFyIHVybCA9ICRmb3JtLnByb3AoJ2FjdGlvbicpO1xuXHRcdFx0dmFyIGZvcm1EYXRhID0gJGZvcm0uc2VyaWFsaXplKCk7XG5cdFx0XHR2YXIgJHN1Ym1pdCA9ICRmb3JtLmZpbmQoJ2lucHV0W3R5cGU9XCJzdWJtaXRcIl0nKTtcblx0XHRcdHZhciBzZW5kaW5nID0gJHN1Ym1pdC5kYXRhKCdmZWVkYmFjaycpO1xuXHRcdFx0dmFyIHJlc2V0ID0gJHN1Ym1pdC5kYXRhKCdyZXNldCcpO1xuXHRcdFx0dmFyIGNvbXBsZXRlID0gJHN1Ym1pdC5kYXRhKCdjb21wbGV0ZScpO1xuXHRcdFx0dmFyICRtZXNzYWdlID0gJCh0aGlzKS5maW5kKCcubWVzc2FnZScpOyBcdFx0XG5cdFx0XHQkc3VibWl0LnZhbChzZW5kaW5nKTtcbiBcblx0XHRcdHZhciBoZWFkZXJzID0ge307XG5cblx0XHRcdGlmKCAkKHRoaXMpLmRhdGEoJ3R5cGUnKSA9PSAnbG9naW4nICl7IFxuXHRcdFx0XHRoZWFkZXJzID0geyBcIkFjY2Vzcy1Db250cm9sLUFsbG93LU9yaWdpblwiOiBcIipcIiB9OyAgXG5cdFx0XHR9XG4gIFxuXHRcdFx0JC5hamF4KHtcblx0XHRcdFx0dHlwZTogJ1BPU1QnLFxuXHRcdFx0XHR1cmw6IHVybCxcblx0XHRcdFx0ZGF0YTogZm9ybURhdGEsXG5cdFx0XHRcdGRhdGFUeXBlOiAnanNvbicsIFxuXHRcdFx0XHRoZWFkZXJzOiBoZWFkZXJzLFxuXHRcdFx0XHRzdWNjZXNzOiBmdW5jdGlvbihyZXNwb25zZSkge1xuXHRcdFx0XHRcdFxuXHRcdFx0XHRcdCRmb3JtLmZpbmQoXCJpbnB1dFwiKS5yZW1vdmVDbGFzcyhcImVycm9yXCIpLmZpbmQoXCJzcGFuLmVycm9yXCIpLmZhZGVPdXQoKTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XG5cdFx0XHRcdFx0aWYgKHJlc3BvbnNlLnN0YXR1cyA9PSAxKSB7XG5cblx0XHRcdFx0XHRcdGlmKCAkZm9ybS5kYXRhKCd0eXBlJykgPT0gJ2xvZ2luJyApeyBcblx0XHRcdFx0XHRcdFx0d2luZG93LmxvY2F0aW9uID0gcmVzcG9uc2UucmVkaXJlY3Q7XG5cdFx0XHRcdFx0XHRcdHJldHVybjtcdFxuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdFx0XG5cdFx0XHRcdFx0XHRpZiggJGZvcm0uZGF0YSgndHlwZScpID09ICdmb3Jnb3R0ZW4nICl7IFxuXHRcdFx0XHRcdFx0XHRcdFxuXHRcdFx0XHRcdFx0fVx0XHRcdFxuICBcdFxuXHRcdFx0XHRcdCAgICAvLyBSZXNldCBmb3JtXG5cdFx0XHRcdFx0XHQkYWpheEZvcm1bMF0ucmVzZXQoKTtcblx0XHRcdFx0XHRcdCBcblx0XHRcdFx0XHRcdCQoJy5mb3JtX19maWVsZCBpbnB1dCwgLmZvcm1fX2ZpZWxkIHRleHRhcmVhJykudmFsKCcnKTsgICBcblx0XHRcdFx0XHRcdGlmICgkKCcuc2VsZWN0aXplLWlucHV0JykubGVuZ3RoID4gMCl7IFxuXHRcdFx0XHRcdFx0XHR2YXIgJHNlbGVjdCA9ICQoJ3NlbGVjdCcpLnNlbGVjdGl6ZSgpO1xuXHRcdFx0XHRcdFx0XHR2YXIgY29udHJvbCA9ICRzZWxlY3RbMF0uc2VsZWN0aXplO1xuXHRcdFx0XHRcdFx0XHRjb250cm9sLmNsZWFyKCk7IFxuXHRcdFx0XHRcdFx0fSBcblx0XHRcdFx0XHRcdCRzdWJtaXQudmFsKHJlc2V0KTsgIFxuXHRcdFx0XHRcdFx0Ly8gRGlzcGxheSBtZXNzYWdlXG5cdFx0XHRcdFx0XHQkbWVzc2FnZS5odG1sKHJlc3BvbnNlLm1lc3NhZ2UpOyAgIFxuXHRcdFx0XHRcdFx0XG5cdFx0XHRcdFx0XHQgICAgICAgICAgICAgICBcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XG5cdFx0XHRcdFx0XHRjb25zb2xlLmxvZygkbWVzc2FnZSk7XHRcblxuXHRcdFx0XHRcdFx0JG1lc3NhZ2UuaHRtbChyZXNwb25zZS5tZXNzYWdlKTtcblxuXHRcdFx0XHRcdFx0Ly8gJCgnbGFiZWwnKS5yZW1vdmVDbGFzcygnZmFpbHVyZScpLmZpbmQoXCJzcGFuXCIpLmZhZGVPdXQoXCJmYXN0XCIpOyBcblx0XHRcdFx0XHRcdC8vICQoJ2lucHV0LCB0ZXh0YXJlYSwgLnNlbGVjdGl6ZS1pbnB1dCcpLnJlbW92ZUNsYXNzKCdlcnJvcicpOyAgXG5cblx0XHRcdFx0XHRcdC8vIHNldFRpbWVvdXQoZnVuY3Rpb24oKXtcblx0XHRcdFx0XHRcdC8vICAgICBpZiAocmVzZXQpIHtcblx0XHRcdFx0XHRcdC8vICAgICBcdCRzdWJtaXQudmFsKHJlc2V0KTtcblx0XHRcdFx0XHRcdC8vICAgICB9XG5cdFx0XHRcdFx0XHQvLyBcdGlmIChyZXNwb25zZS5maWVsZHMpIHsgY29uc29sZS5sb2cocmVzcG9uc2UuZmllbGRzKTsgXG5cdFx0XHRcdFx0XHQvLyBcdFx0JC5lYWNoKHJlc3BvbnNlLmZpZWxkcywgZnVuY3Rpb24oaWQsIHZhbHVlKSB7XG5cdFx0XHRcdFx0XHQvLyBcdFx0XHR2YXIgZWwgPSAkKFwiI1wiICsgaWQpO1xuXHRcdFx0XHRcdFx0Ly8gXHRcdFx0aWYgKHJlc3BvbnNlLm1lc3NhZ2VzICYmIHJlc3BvbnNlLm1lc3NhZ2VzW2lkXS5sZW5ndGggPiAwKSB7IGNvbnNvbGUubG9nKHJlc3BvbnNlLm1lc3NhZ2VzW2lkXSkgIFxuXHRcdFx0XHRcdFx0Ly8gXHRcdFx0XHR2YXIgbWVzc2FnZSA9IHJlc3BvbnNlLm1lc3NhZ2VzW2lkXTtcblx0XHRcdFx0XHRcdC8vIFx0XHRcdFx0aWYgKGVsLmxlbmd0aCA+IDApIHsgIGNvbnNvbGUubG9nKGVsKSBcblx0XHRcdFx0XHRcdC8vIFx0XHRcdFx0XHR2YXIgZmVpbGQgPSAkKGVsKS5wYXJlbnRzKCcuZm9ybV9fZmllbGQnKTtcblx0XHRcdFx0XHRcdC8vIFx0XHRcdFx0XHRmZWlsZC5maW5kKFwibGFiZWxcIikuYWRkQ2xhc3MoXCJmYWlsdXJlXCIpLmZpbmQoJ3NwYW4nKS5odG1sKG1lc3NhZ2UpLmZhZGVJbihcImZhc3RcIik7IFxuXHRcdFx0XHRcdFx0Ly8gXHRcdFx0XHRcdGVsLmFkZENsYXNzKCdlcnJvcicpOyBcblx0XHRcdFx0XHRcdC8vIFx0XHRcdFx0fSBcblx0XHRcdFx0XHRcdC8vIFx0XHRcdH0gIFxuXHRcdFx0XHRcdFx0Ly8gXHRcdFx0ZWxzZSB7ICBcblx0XHRcdFx0XHRcdC8vIFx0XHRcdFx0aWYgKGVsLmxlbmd0aCA+IDAgJiYgdmFsdWUgPT0gdHJ1ZSkgeyBjb25zb2xlLmxvZyhlbCk7IGNvbnNvbGUubG9nKGlkKTsgY29uc29sZS5sb2codmFsdWUpOyBcblx0XHRcdFx0XHRcdC8vIFx0XHRcdFx0XHR2YXIgZmVpbGQgPSAkKGVsKS5wYXJlbnRzKCcuZm9ybV9fZmllbGQnKTtcblx0XHRcdFx0XHRcdC8vIFx0XHRcdFx0XHRmZWlsZC5jbG9zZXN0KFwibGFiZWxcIikuYWRkQ2xhc3MoXCJmYWlsdXJlXCIpLmZpbmQoXCJtYXJrXCIpLmh0bWwodmFsdWUpLmZhZGVJbihcImZhc3RcIik7XG5cdFx0XHRcdFx0XHQvLyBcdFx0XHRcdFx0ZmVpbGQuZmluZCgnaW5wdXQsIHRleHRhcmVhLCAu
7437c2VsZWN0aXplLWlucHV0JykuYWRkQ2xhc3MoJ2Vycm9yJyk7XG5cdFx0XHRcdFx0XHQvLyBcdFx0XHRcdFx0ZmVpbGQuZmluZCgnbGFiZWwgc3BhbicpLmZhZGVJbigpO1xuXHRcdFx0XHRcdFx0Ly8gXHRcdFx0XHR9XG5cdFx0XHRcdFx0XHQvLyBcdFx0XHR9XG5cdFx0XHRcdFx0XHQvLyBcdFx0XHRlbC5vbihcImZvY3VzXCIsIGZ1bmN0aW9uKGUpIHtcblx0XHRcdFx0XHRcdC8vIFx0XHRcdFx0JCh0aGlzKS5jbG9zZXN0KFwibGFiZWxcIikucmVtb3ZlQ2xhc3MoXCJmYWlsdXJlXCIpLmZpbmQoXCJzcGFuXCIpLmZhZGVPdXQoXCJmYXN0XCIpO1xuXHRcdFx0XHRcdFx0Ly8gXHRcdFx0fSk7IFxuXHRcdFx0XHRcdFx0Ly8gXHRcdFx0JCgnaW5wdXRbbmFtZT1cIicraWQrJ1wiXScpLm9uKCdjaGFuZ2UnLCBmdW5jdGlvbigpe1xuXHRcdFx0XHRcdFx0Ly8gXHRcdFx0XHQkKCdsYWJlbCMnK2lkKycnKS5yZW1vdmVDbGFzcygnZmFpbHVyZScpLmZpbmQoXCJzcGFuXCIpLmZhZGVPdXQoXCJmYXN0XCIpO1xuXHRcdFx0XHRcdFx0Ly8gXHRcdFx0fSk7IFxuXHRcdFx0XHRcdFx0Ly8gXHRcdH0pO1xuXHRcdFx0XHRcdFx0Ly8gXHR9ICBcblx0XHRcdFx0XHRcdC8vIH0sIDUwMCk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9LFxuXHRcdFx0XHRlcnJvcjogZnVuY3Rpb24oeGhyLCBhamF4T3B0aW9ucywgdGhyb3duRXJyb3IpIHtcblx0ICAgICAgICBcdFx0Y29uc29sZS5sb2coXCJVbmNhdWdodCBFcnJvci5cXG5cIiArIHRocm93bkVycm9yKTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0fSk7XG5cdH1cbn0iLCJLVC5TdW1tYXJ5TW9yZSA9IHtcbiAgICBpbml0OiBmdW5jdGlvbigpIHtcbiAgICAgIGlmKCQoXCIuZGV0YWlsc19fc3VtbWFyeVwiKS5sZW5ndGggPiAwKVxuICAgICAge1xuXG4gICAgICAgIHZhciBpc09wZW4gPSBmYWxzZVxuICAgICAgICB2Y
7437XIgJG1vcmVCdG4gPSAkKCAnPHNwYW4gY2xhc3M9XCJyZWFkLW1vcmUtc3VtbWFyeVwiPm1vcmUuLi48L3NwYW4+JyApXG4gICAgICAgIHZhciAkZGV0YWlsc19fc3VtbWFyeSA9ICQoXCIuZGV0YWlsc19fc3VtbWFyeVwiKVxuICAgICAgICB2YXIgJGRldGFpbHNfX2NvbnRlbnQgPSAkKCcuZGV0YWlsc19fc3VtbWFyeTpudGgtb2YtdHlwZSgxKScpXG5cbiAgICAgICAgLy8gYm94IGhpZ2h0IENMT1NFRFxuICAgICAgICB2YXIgJGNzc0hlaWdodCA9ICRkZXRhaWxzX19zdW1tYXJ5W1wiMFwiXS5jbGllbnRIZWlnaHRcblxuICAgICAgICAvLyBib3ggaGlnaHQgT1BFTkVEIChtaW51cyBwYWRkaW5ncylcbiAgICAgICAgdmFyICRwYWRkaW5nVG9wID0gcGFyc2VJbnQoJCgnLmRldGFpbHNfX3N1bW1hcnknKS5jc3MoJ3BhZGRpbmctdG9wJykpXG4gICAgICAgIHZhciAkcGFkZGluZ0JvdHRvbSA9IHBhcnNlSW50KCQoJy5kZXRhaWxzX19zdW1tYXJ5JykuY3NzKCdwYWRkaW5nLWJvdHRvbScpKVxuICAgICAgICB2YXIgJHJlYWxIZWlnaHQgPSAkZGV0YWlsc19fc3VtbWFyeVtcIjBcIl0uc2Nyb2xsSGVpZ2h0IC0gJHBhZGRpbmdUb3AgLSAkcGFkZGluZ0JvdHRvbVxuXG4gICAgICAgIGZ1bmN0aW9uIGhhbmRsZXIoKXtcbiAgICAgICAgICBpZihpc09wZW4gPT0gZmFsc2Upe1xuICAgICAgICAgICAgJGRldGFpbHNfX3N1bW1hcnlcbiAgICAgICAgICAgICAgLmFuaW1hdGUoe1wibWF4LWhlaWdodFwiOiAkcmVhbEhlaWdodH0sIFwic2xvd1wiKVxuXG4gICAgICAgICAgICBpc09wZW4gPSB0cnVlXG4gICAgICAgICAgICAkKFwiLnJlYWQtbW9yZS1zdW1tYXJ5XCIpLnRleHQoXCJoaWRlLi4uXCIpXG4gICAgICAgICAgfSBlbHNlIGlmKGlzT3BlbiA9PSB0cnVlKXtcbiAgICAgICAgICAgICRkZXRhaWxzX19zdW1tYXJ5XG4gICAgICAgICAgICAgIC5hbmltYXRlKHtcIm1heC1oZWlnaHRcIjogJGNzc0hlaWdodH0sIFwic2xvd1wiKVxuXG4gICAgICAgICAgICBpc09wZW4gPSBmYWxzZVxuICAgICAgICAgICAgJChcIi5yZWFkLW1vcmUtc3VtbWFyeVwiKS50ZXh0KFwibW9yZS4uLlwiKVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmKCRyZWFsSGVpZ2h0ID4gJGNzc0hlaWdodCl7XG4gICAgICAgICAgJGRldGFpbHNfX2NvbnRlbnRcbiAgICAgICAgICAuYWZ0ZXIoJG1vcmVCdG4pXG5cbiAgICAgICAgICAkKFwiLnJlYWQtbW9yZS1zdW1tYXJ5XCIpLmNsaWNrKGhhbmRsZXIpXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG59XG5cbiIsIktULm1vdXNlU3RvcCA9IHtcbiAgaW5pdDogZnVuY3Rpb24oKSB7XG4gICAgdmFyICRjb250YWluZXIgPSAkKCcub2JqZWN0LWltYWdlLWxpZ2h0Ym94JylcblxuICAgIGZ1bmN0aW9uIGljb25zVG9nZ2xlKGFyZyl7XG4gICAgICAkY29udGFpbmVyLmZpbmQoJy56b29tJykudG9nZ2xlKGFyZylcbiAgICAgICRjb250YWluZXIuZmluZCgnW2RhdGEtZnVsbHNjcmVlbi1jbG9zZV0nKS50b2dnbGUoYXJnKVxuICAgICAgJGNvbnRhaW5lci5maW5kKCcubmF2JykudG9nZ2xlKGFyZylcbiAgICAgICRjb250YWluZXIuZmluZCgnW2RhdGEtYm90dG9tLWNsb3NlXScpLnRvZ2dsZShhcmcpXG4gICAgICAkY29udGFpbmVyLmZpbmQoJ1tkYXRhLWdhbGxlcnktdG9nZ2xlXScpLnRvZ2dsZShhcmcpXG4gICAgICAkY29udGFpbmVyLmZpbmQoJy5pbWcgc3BhbicpLnRvZ2dsZShhcmcpXG4gICAgfVxuXG4gICAgJGNvbnRhaW5lci5tb3VzZXN0b3Aoe2RlbGF5OiAyMDAwfSwgZnVuY3Rpb24oKSB7IGljb25zVG9nZ2xlKGZhbHNlKSB9KVxuICAgICRjb250YWluZXIubW91c2Vtb3ZlKGZ1bmN0aW9uKCkgeyBpY29uc1RvZ2dsZSh0cnVlKSB9KVxuXG4gIH1cbn1cbiIsIktULm5hbm9TY3JvbGxlciA9IHtcblx0aW5pdDogZnVuY3Rpb24oKSB7XG4gICAgLy8gbmFub1Njcm9vbGVyIGlzIGluaXRpYWxpemVkIGluIHNlbGVjdC5qcyBcbiAgfVxufVxuIiwiJChmdW5jdGlvbigpe1xuXG5cdEtULkhvbWUuaW5pdCgpO1xuXHRLVC5NYXNvbnJ5LmluaXQoKTtcblx0S1QuTmF2aWdhdGlvbi5pbml0KCk7XG5cdEtULlNlbGVjdC5pbml0KCk7XG5cdEtULk9iamVjdC5pbml0KCk7XG5cdEtULkNvbGxlY3Rpb24uaW5pdCgpO1xuXHRLVC5QYW56b29tLmluaXQoKTtcblx0S1QuQWpheFBhZ2luYXRpb24uaW5pdCgpO1xuXHRLVC5BamF4Rm9ybS5pbml0KCk7XG4gIEtULlN1bW1hcnlNb3JlLmluaXQoKTtcbiAgS1QubW91c2VTdG9wLmluaXQoKTtcbiAgS1QubmFub1Njcm9sbGVyLmluaXQoKTtcblxuXHRpZihpc1RvdWNoRGV2aWNlKCk9PT1mYWxzZSl7XG5cdCAgICAkKCdbZGF0YS10b2dnbGU9XCJ0b29sdGlwXCJdJykudG9vbHRpcCgpO1xuXHR9XG5cblx0JCgnW2RhdGEtdG9vbHRpcC1oaWRlXScpLm9uKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcblx0ICAgICQodGhpcykudG9vbHRpcCgnaGlkZScpXG5cdH0pO1xuXG59KTtcbiJdfQ==
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.