(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.PydioBootstrap = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o -1 } } function normalizeName(name) { if (typeof name !== 'string') { name = String(name) } if (/[^a-z0-9\-#$%&'*+.\^_`|~]/i.test(name)) { throw new TypeError('Invalid character in header field name') } return name.toLowerCase() } function normalizeValue(value) { if (typeof value !== 'string') { value = String(value) } return value } // Build a destructive iterator for the value list function iteratorFor(items) { var iterator = { next: function() { var value = items.shift() return {done: value === undefined, value: value} } } if (support.iterable) { iterator[Symbol.iterator] = function() { return iterator } } return iterator } function Headers(headers) { this.map = {} if (headers instanceof Headers) { headers.forEach(function(value, name) { this.append(name, value) }, this) } else if (Array.isArray(headers)) { headers.forEach(function(header) { this.append(header[0], header[1]) }, this) } else if (headers) { Object.getOwnPropertyNames(headers).forEach(function(name) { this.append(name, headers[name]) }, this) } } Headers.prototype.append = function(name, value) { name = normalizeName(name) value = normalizeValue(value) var oldValue = this.map[name] this.map[name] = oldValue ? oldValue+','+value : value } Headers.prototype['delete'] = function(name) { delete this.map[normalizeName(name)] } Headers.prototype.get = function(name) { name = normalizeName(name) return this.has(name) ? this.map[name] : null } Headers.prototype.has = function(name) { return this.map.hasOwnProperty(normalizeName(name)) } Headers.prototype.set = function(name, value) { this.map[normalizeName(name)] = normalizeValue(value) } Headers.prototype.forEach = function(callback, thisArg) { for (var name in this.map) { if (this.map.hasOwnProperty(name)) { callback.call(thisArg, this.map[name], name, this) } } } Headers.prototype.keys = function() { var items = [] this.forEach(function(value, name) { items.push(name) }) return iteratorFor(items) } Headers.prototype.values = function() { var items = [] this.forEach(function(value) { items.push(value) }) return iteratorFor(items) } Headers.prototype.entries = function() { var items = [] this.forEach(function(value, name) { items.push([name, value]) }) return iteratorFor(items) } if (support.iterable) { Headers.prototype[Symbol.iterator] = Headers.prototype.entries } function consumed(body) { if (body.bodyUsed) { return Promise.reject(new TypeError('Already read')) } body.bodyUsed = true } function fileReaderReady(reader) { return new Promise(function(resolve, reject) { reader.onload = function() { resolve(reader.result) } reader.onerror = function() { reject(reader.error) } }) } function readBlobAsArrayBuffer(blob) { var reader = new FileReader() var promise = fileReaderReady(reader) reader.readAsArrayBuffer(blob) return promise } function readBlobAsText(blob) { var reader = new FileReader() var promise = fileReaderReady(reader) reader.readAsText(blob) return promise } function readArrayBufferAsText(buf) { var view = new Uint8Array(buf) var chars = new Array(view.length) for (var i = 0; i < view.length; i++) { chars[i] = String.fromCharCode(view[i]) } return chars.join('') } function bufferClone(buf) { if (buf.slice) { return buf.slice(0) } else { var view = new Uint8Array(buf.byteLength) view.set(new Uint8Array(buf)) return view.buffer } } function Body() { this.bodyUsed = false this._initBody = function(body) { this._bodyInit = body if (!body) { this._bodyText = '' } else if (typeof body === 'string') { this._bodyText = body } else if (support.blob && Blob.prototype.isPrototypeOf(body)) { this._bodyBlob = body } else if (support.formData && FormData.prototype.isPrototypeOf(body)) { this._bodyFormData = body } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) { this._bodyText = body.toString() } else if (support.arrayBuffer && support.blob && isDataView(body)) { this._bodyArrayBuffer = bufferClone(body.buffer) // IE 10-11 can't handle a DataView body. this._bodyInit = new Blob([this._bodyArrayBuffer]) } else if (support.arrayBuffer && (ArrayBuffer.prototype.isPrototypeOf(body) || isArrayBufferView(body))) { this._bodyArrayBuffer = bufferClone(body) } else { throw new Error('unsupported BodyInit type') } if (!this.headers.get('content-type')) { if (typeof body === 'string') { this.headers.set('content-type', 'text/plain;charset=UTF-8') } else if (this._bodyBlob && this._bodyBlob.type) { this.headers.set('content-type', this._bodyBlob.type) } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) { this.headers.set('content-type', 'application/x-www-form-urlencoded;charset=UTF-8') } } } if (support.blob) { this.blob = function() { var rejected = consumed(this) if (rejected) { return rejected } if (this._bodyBlob) { return Promise.resolve(this._bodyBlob) } else if (this._bodyArrayBuffer) { return Promise.resolve(new Blob([this._bodyArrayBuffer])) } else if (this._bodyFormData) { throw new Error('could not read FormData body as blob') } else { return Promise.resolve(new Blob([this._bodyText])) } } this.arrayBuffer = function() { if (this._bodyArrayBuffer) { return consumed(this) || Promise.resolve(this._bodyArrayBuffer) } else { return this.blob().then(readBlobAsArrayBuffer) } } } this.text = function() { var rejected = consumed(this) if (rejected) { return rejected } if (this._bodyBlob) { return readBlobAsText(this._bodyBlob) } else if (this._bodyArrayBuffer) { return Promise.resolve(readArrayBufferAsText(this._bodyArrayBuffer)) } else if (this._bodyFormData) { throw new Error('could not read FormData body as text') } else { return Promise.resolve(this._bodyText) } } if (support.formData) { this.formData = function() { return this.text().then(decode) } } this.json = function() { return this.text().then(JSON.parse) } return this } // HTTP methods whose capitalization should be normalized var methods = ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT'] function normalizeMethod(method) { var upcased = method.toUpperCase() return (methods.indexOf(upcased) > -1) ? upcased : method } function Request(input, options) { options = options || {} var body = options.body if (input instanceof Request) { if (input.bodyUsed) { throw new TypeError('Already read') } this.url = input.url this.credentials = input.credentials if (!options.headers) { this.headers = new Headers(input.headers) } this.method = input.method this.mode = input.mode if (!body && input._bodyInit != null) { body = input._bodyInit input.bodyUsed = true } } else { this.url = String(input) } this.credentials = options.credentials || this.credentials || 'omit' if (options.headers || !this.headers) { this.headers = new Headers(options.headers) } this.method = normalizeMethod(options.method || this.method || 'GET') this.mode = options.mode || this.mode || null this.referrer = null if ((this.method === 'GET' || this.method === 'HEAD') && body) { throw new TypeError('Body not allowed for GET or HEAD requests') } this._initBody(body) } Request.prototype.clone = function() { return new Request(this, { body: this._bodyInit }) } function decode(body) { var form = new FormData() body.trim().split('&').forEach(function(bytes) { if (bytes) { var split = bytes.split('=') var name = split.shift().replace(/\+/g, ' ') var value = split.join('=').replace(/\+/g, ' ') form.append(decodeURIComponent(name), decodeURIComponent(value)) } }) return form } function parseHeaders(rawHeaders) { var headers = new Headers() rawHeaders.split(/\r?\n/).forEach(function(line) { var parts = line.split(':') var key = parts.shift().trim() if (key) { var value = parts.join(':').trim() headers.append(key, value) } }) return headers } Body.call(Request.prototype) function Response(bodyInit, options) { if (!options) { options = {} } this.type = 'default' this.status = 'status' in options ? options.status : 200 this.ok = this.status >= 200 && this.status < 300 this.statusText = 'statusText' in options ? options.statusText : 'OK' this.headers = new Headers(options.headers) this.url = options.url || '' this._initBody(bodyInit) } Body.call(Response.prototype) Response.prototype.clone = function() { return new Response(this._bodyInit, { status: this.status, statusText: this.statusText, headers: new Headers(this.headers), url: this.url }) } Response.error = function() { var response = new Response(null, {status: 0, statusText: ''}) response.type = 'error' return response } var redirectStatuses = [301, 302, 303, 307, 308] Response.redirect = function(url, status) { if (redirectStatuses.indexOf(status) === -1) { throw new RangeError('Invalid status code') } return new Response(null, {status: status, headers: {location: url}}) } self.Headers = Headers self.Request = Request self.Response = Response self.fetch = function(input, init) { return new Promise(function(resolve, reject) { var request = new Request(input, init) var xhr = new XMLHttpRequest() xhr.onload = function() { var options = { status: xhr.status, statusText: xhr.statusText, headers: parseHeaders(xhr.getAllResponseHeaders() || '') } options.url = 'responseURL' in xhr ? xhr.responseURL : options.headers.get('X-Request-URL') var body = 'response' in xhr ? xhr.response : xhr.responseText resolve(new Response(body, options)) } xhr.onerror = function() { reject(new TypeError('Network request failed')) } xhr.ontimeout = function() { reject(new TypeError('Network request failed')) } xhr.open(request.method, request.url, true) if (request.credentials === 'include') { xhr.withCredentials = true } if ('responseType' in xhr && support.blob) { xhr.responseType = 'blob' } request.headers.forEach(function(value, name) { xhr.setRequestHeader(name, value) }) xhr.send(typeof request._bodyInit === 'undefined' ? null : request._bodyInit) }) } self.fetch.polyfill = true })(typeof self !== 'undefined' ? self : this); },{}],4:[function(require,module,exports){ (function (global){ (function(){'use strict';var k=this; function aa(a){var b=typeof a;if("object"==b)if(a){if(a instanceof Array)return"array";if(a instanceof Object)return b;var c=Object.prototype.toString.call(a);if("[object Window]"==c)return"object";if("[object Array]"==c||"number"==typeof a.length&&"undefined"!=typeof a.splice&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("splice"))return"array";if("[object Function]"==c||"undefined"!=typeof a.call&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("call"))return"function"}else return"null";else if("function"== b&&"undefined"==typeof a.call)return"object";return b}function l(a){return"string"==typeof a}function ba(a,b,c){return a.call.apply(a.bind,arguments)}function ca(a,b,c){if(!a)throw Error();if(2b?1:0};var ha=Array.prototype.indexOf?function(a,b,c){return Array.prototype.indexOf.call(a,b,c)}:function(a,b,c){c=null==c?0:0>c?Math.max(0,a.length+c):c;if(l(a))return l(b)&&1==b.length?a.indexOf(b,c):-1;for(;cc?null:l(a)?a.charAt(c):a[c]}function la(a){return Array.prototype.concat.apply(Array.prototype,arguments)}function ma(a,b,c){return 2>=arguments.length?Array.prototype.slice.call(a,b):Array.prototype.slice.call(a,b,c)};var u;a:{var na=k.navigator;if(na){var oa=na.userAgent;if(oa){u=oa;break a}}u=""};var pa=q(u,"Opera")||q(u,"OPR"),v=q(u,"Trident")||q(u,"MSIE"),qa=q(u,"Edge"),ra=q(u,"Gecko")&&!(q(u.toLowerCase(),"webkit")&&!q(u,"Edge"))&&!(q(u,"Trident")||q(u,"MSIE"))&&!q(u,"Edge"),sa=q(u.toLowerCase(),"webkit")&&!q(u,"Edge");function ta(){var a=k.document;return a?a.documentMode:void 0}var ua; a:{var va="",wa=function(){var a=u;if(ra)return/rv\:([^\);]+)(\)|;)/.exec(a);if(qa)return/Edge\/([\d\.]+)/.exec(a);if(v)return/\b(?:MSIE|rv)[: ]([^\);]+)(\)|;)/.exec(a);if(sa)return/WebKit\/(\S+)/.exec(a);if(pa)return/(?:Version)[ \/]?(\S+)/.exec(a)}();wa&&(va=wa?wa[1]:"");if(v){var xa=ta();if(null!=xa&&xa>parseFloat(va)){ua=String(xa);break a}}ua=va}var ya={}; function za(a){if(!ya[a]){for(var b=0,c=fa(String(ua)).split("."),d=fa(String(a)).split("."),e=Math.max(c.length,d.length),f=0;0==b&&f",4,2,function(a,b,c){return O(function(a,b){return a>b},a,b,c)});P("<=",4,2,function(a,b,c){return O(function(a,b){return a<=b},a,b,c)});P(">=",4,2,function(a,b,c){return O(function(a,b){return a>=b},a,b,c)});var Wa=P("=",3,2,function(a,b,c){return O(function(a,b){return a==b},a,b,c,!0)});P("!=",3,2,function(a,b,c){return O(function(a,b){return a!=b},a,b,c,!0)});P("and",2,2,function(a,b,c){return M(a,c)&&M(b,c)});P("or",1,2,function(a,b,c){return M(a,c)||M(b,c)});function Q(a,b,c){this.a=a;this.b=b||1;this.f=c||1};function Za(a,b){if(b.a.length&&4!=a.i)throw Error("Primary expression must evaluate to nodeset if filter has predicate(s).");n.call(this,a.i);this.c=a;this.h=b;this.g=a.g;this.b=a.b}m(Za);Za.prototype.a=function(a){a=this.c.a(a);return $a(this.h,a)};Za.prototype.toString=function(){var a;a="Filter:"+J(this.c);return a+=J(this.h)};function ab(a,b){if(b.lengtha.v)throw Error("Function "+a.j+" expects at most "+a.v+" arguments, "+b.length+" given");a.B&&r(b,function(b,d){if(4!=b.i)throw Error("Argument "+d+" to function "+a.j+" is not of type Nodeset: "+b);});n.call(this,a.i);this.h=a;this.c=b;Ua(this,a.g||ja(b,function(a){return a.g}));Va(this,a.D&&!b.length||a.C&&!!b.length||ja(b,function(a){return a.b}))}m(ab); ab.prototype.a=function(a){return this.h.m.apply(null,la(a,this.c))};ab.prototype.toString=function(){var a="Function: "+this.h;if(this.c.length)var b=t(this.c,function(a,b){return a+J(b)},"Arguments:"),a=a+J(b);return a};function bb(a,b,c,d,e,f,g,h,p){this.j=a;this.i=b;this.g=c;this.D=d;this.C=e;this.m=f;this.A=g;this.v=void 0!==h?h:g;this.B=!!p}bb.prototype.toString=function(){return this.j};var cb={}; function R(a,b,c,d,e,f,g,h){if(cb.hasOwnProperty(a))throw Error("Function already created: "+a+".");cb[a]=new bb(a,b,c,d,!1,e,f,g,h)}R("boolean",2,!1,!1,function(a,b){return M(b,a)},1);R("ceiling",1,!1,!1,function(a,b){return Math.ceil(K(b,a))},1);R("concat",3,!1,!1,function(a,b){return t(ma(arguments,1),function(b,d){return b+L(d,a)},"")},2,null);R("contains",2,!1,!1,function(a,b,c){return q(L(b,a),L(c,a))},2);R("count",1,!1,!1,function(a,b){return b.a(a).l},1,1,!0); R("false",2,!1,!1,function(){return!1},0);R("floor",1,!1,!1,function(a,b){return Math.floor(K(b,a))},1);R("id",4,!1,!1,function(a,b){function c(a){if(w){var b=e.all[a];if(b){if(b.nodeType&&a==b.id)return b;if(b.length)return ka(b,function(b){return a==b.id})}return null}return e.getElementById(a)}var d=a.a,e=9==d.nodeType?d:d.ownerDocument,d=L(b,a).split(/\s+/),f=[];r(d,function(a){a=c(a);!a||0<=ha(f,a)||f.push(a)});f.sort(La);var g=new C;r(f,function(a){F(g,a)});return g},1); R("lang",2,!1,!1,function(){return!1},1);R("last",1,!0,!1,function(a){if(1!=arguments.length)throw Error("Function last expects ()");return a.f},0);R("local-name",3,!1,!0,function(a,b){var c=b?Ra(b.a(a)):a.a;return c?c.localName||c.nodeName.toLowerCase():""},0,1,!0);R("name",3,!1,!0,function(a,b){var c=b?Ra(b.a(a)):a.a;return c?c.nodeName.toLowerCase():""},0,1,!0);R("namespace-uri",3,!0,!1,function(){return""},0,1,!0); R("normalize-space",3,!1,!0,function(a,b){return(b?L(b,a):z(a.a)).replace(/[\s\xa0]+/g," ").replace(/^\s+|\s+$/g,"")},0,1);R("not",2,!1,!1,function(a,b){return!M(b,a)},1);R("number",1,!1,!0,function(a,b){return b?K(b,a):+z(a.a)},0,1);R("position",1,!0,!1,function(a){return a.b},0);R("round",1,!1,!1,function(a,b){return Math.round(K(b,a))},1);R("starts-with",2,!1,!1,function(a,b,c){b=L(b,a);a=L(c,a);return 0==b.lastIndexOf(a,0)},2);R("string",3,!1,!0,function(a,b){return b?L(b,a):z(a.a)},0,1); R("string-length",1,!1,!0,function(a,b){return(b?L(b,a):z(a.a)).length},0,1);R("substring",3,!1,!1,function(a,b,c,d){c=K(c,a);if(isNaN(c)||Infinity==c||-Infinity==c)return"";d=d?K(d,a):Infinity;if(isNaN(d)||-Infinity===d)return"";c=Math.round(c)-1;var e=Math.max(c,0);a=L(b,a);return Infinity==d?a.substring(e):a.substring(e,c+Math.round(d))},2,3);R("substring-after",3,!1,!1,function(a,b,c){b=L(b,a);a=L(c,a);c=b.indexOf(a);return-1==c?"":b.substring(c+a.length)},2); R("substring-before",3,!1,!1,function(a,b,c){b=L(b,a);a=L(c,a);a=b.indexOf(a);return-1==a?"":b.substring(0,a)},2);R("sum",1,!1,!1,function(a,b){for(var c=H(b.a(a)),d=0,e=I(c);e;e=I(c))d+=+z(e);return d},1,1,!0);R("translate",3,!1,!1,function(a,b,c,d){b=L(b,a);c=L(c,a);var e=L(d,a);a={};for(d=0;d]=|\s+|./g,hb=/^\s/;function S(a,b){return a.b[a.a+(b||0)]}function T(a){return a.b[a.a++]}function ib(a){return a.b.length<=a.a};function jb(a){n.call(this,3);this.c=a.substring(1,a.length-1)}m(jb);jb.prototype.a=function(){return this.c};jb.prototype.toString=function(){return"Literal: "+this.c};function E(a,b){this.j=a.toLowerCase();var c;c="*"==this.j?"*":"http://www.w3.org/1999/xhtml";this.c=b?b.toLowerCase():c}E.prototype.a=function(a){var b=a.nodeType;if(1!=b&&2!=b)return!1;b=void 0!==a.localName?a.localName:a.nodeName;return"*"!=this.j&&this.j!=b.toLowerCase()?!1:"*"==this.c?!0:this.c==(a.namespaceURI?a.namespaceURI.toLowerCase():"http://www.w3.org/1999/xhtml")};E.prototype.f=function(){return this.j}; E.prototype.toString=function(){return"Name Test: "+("http://www.w3.org/1999/xhtml"==this.c?"":this.c+":")+this.j};function kb(a,b){n.call(this,a.i);this.h=a;this.c=b;this.g=a.g;this.b=a.b;if(1==this.c.length){var c=this.c[0];c.u||c.c!=lb||(c=c.o,"*"!=c.f()&&(this.f={name:c.f(),s:null}))}}m(kb);function mb(){n.call(this,4)}m(mb);mb.prototype.a=function(a){var b=new C;a=a.a;9==a.nodeType?F(b,a):F(b,a.ownerDocument);return b};mb.prototype.toString=function(){return"Root Helper Expression"};function nb(){n.call(this,4)}m(nb);nb.prototype.a=function(a){var b=new C;F(b,a.a);return b};nb.prototype.toString=function(){return"Context Helper Expression"}; function ob(a){return"/"==a||"//"==a}kb.prototype.a=function(a){var b=this.h.a(a);if(!(b instanceof C))throw Error("Filter expression must evaluate to nodeset.");a=this.c;for(var c=0,d=a.length;ca.length)throw Error("Unclosed literal string");return new jb(a)} function Hb(a){var b,c=[],d;if(ob(S(a.a))){b=T(a.a);d=S(a.a);if("/"==b&&(ib(a.a)||"."!=d&&".."!=d&&"@"!=d&&"*"!=d&&!/(?![0-9])[\w]/.test(d)))return new mb;d=new mb;W(a,"Missing next location step.");b=Ib(a,b);c.push(b)}else{a:{b=S(a.a);d=b.charAt(0);switch(d){case "$":throw Error("Variable reference not allowed in HTML XPath");case "(":T(a.a);b=Cb(a);W(a,'unclosed "("');Eb(a,")");break;case '"':case "'":b=Gb(a);break;default:if(isNaN(+b))if(!db(b)&&/(?![0-9])[\w]/.test(d)&&"("==S(a.a,1)){b=T(a.a); b=cb[b]||null;T(a.a);for(d=[];")"!=S(a.a);){W(a,"Missing function argument list.");d.push(Cb(a));if(","!=S(a.a))break;T(a.a)}W(a,"Unclosed function argument list.");Fb(a);b=new ab(b,d)}else{b=null;break a}else b=new Ab(+T(a.a))}"["==S(a.a)&&(d=new sb(Jb(a)),b=new Za(b,d))}if(b)if(ob(S(a.a)))d=b;else return b;else b=Ib(a,"/"),d=new nb,c.push(b)}for(;ob(S(a.a));)b=T(a.a),W(a,"Missing next location step."),b=Ib(a,b),c.push(b);return new kb(d,c)} function Ib(a,b){var c,d,e;if("/"!=b&&"//"!=b)throw Error('Step op should be "/" or "//"');if("."==S(a.a))return d=new U(yb,new G("node")),T(a.a),d;if(".."==S(a.a))return d=new U(xb,new G("node")),T(a.a),d;var f;if("@"==S(a.a))f=lb,T(a.a),W(a,"Missing attribute name");else if("::"==S(a.a,1)){if(!/(?![0-9])[\w]/.test(S(a.a).charAt(0)))throw Error("Bad token: "+T(a.a));c=T(a.a);f=wb[c]||null;if(!f)throw Error("No axis with name: "+c);T(a.a);W(a,"Missing node name")}else f=tb;c=S(a.a);if(/(?![0-9])[\w\*]/.test(c.charAt(0)))if("("== S(a.a,1)){if(!db(c))throw Error("Invalid node type: "+c);c=T(a.a);if(!db(c))throw Error("Invalid type name: "+c);Eb(a,"(");W(a,"Bad nodetype");e=S(a.a).charAt(0);var g=null;if('"'==e||"'"==e)g=Gb(a);W(a,"Bad nodetype");Fb(a);c=new G(c,g)}else if(c=T(a.a),e=c.indexOf(":"),-1==e)c=new E(c);else{var g=c.substring(0,e),h;if("*"==g)h="*";else if(h=a.b(g),!h)throw Error("Namespace prefix not declared: "+g);c=c.substr(e+1);c=new E(c,h)}else throw Error("Bad token: "+T(a.a));e=new sb(Jb(a),f.a);return d|| new U(f,c,e,"//"==b)}function Jb(a){for(var b=[];"["==S(a.a);){T(a.a);W(a,"Missing predicate expression.");var c=Cb(a);b.push(c);W(a,"Unclosed predicate expression.");Eb(a,"]")}return b}function Db(a){if("-"==S(a.a))return T(a.a),new zb(Db(a));var b=Hb(a);if("|"!=S(a.a))a=b;else{for(b=[b];"|"==T(a.a);)W(a,"Missing next union location path."),b.push(Hb(a));a.a.a--;a=new rb(b)}return a};function Kb(a){switch(a.nodeType){case 1:return ea(Lb,a);case 9:return Kb(a.documentElement);case 11:case 10:case 6:case 12:return Mb;default:return a.parentNode?Kb(a.parentNode):Mb}}function Mb(){return null}function Lb(a,b){if(a.prefix==b)return a.namespaceURI||"http://www.w3.org/1999/xhtml";var c=a.getAttributeNode("xmlns:"+b);return c&&c.specified?c.value||null:a.parentNode&&9!=a.parentNode.nodeType?Lb(a.parentNode,b):null};function Nb(a,b){if(!a.length)throw Error("Empty XPath expression.");var c=fb(a);if(ib(c))throw Error("Invalid XPath expression.");b?"function"==aa(b)||(b=da(b.lookupNamespaceURI,b)):b=function(){return null};var d=Cb(new Bb(c,b));if(!ib(c))throw Error("Bad token: "+T(c));this.evaluate=function(a,b){var c=d.a(new Q(a));return new Y(c,b)}} function Y(a,b){if(0==b)if(a instanceof C)b=4;else if("string"==typeof a)b=2;else if("number"==typeof a)b=1;else if("boolean"==typeof a)b=3;else throw Error("Unexpected evaluation result.");if(2!=b&&1!=b&&3!=b&&!(a instanceof C))throw Error("value could not be converted to the specified type");this.resultType=b;var c;switch(b){case 2:this.stringValue=a instanceof C?Sa(a):""+a;break;case 1:this.numberValue=a instanceof C?+Sa(a):+a;break;case 3:this.booleanValue=a instanceof C?0=c.length?null:c[f++]};this.snapshotItem=function(a){if(6!=b&&7!=b)throw Error("snapshotItem called with wrong result type");return a>=c.length|| 0>a?null:c[a]}}Y.ANY_TYPE=0;Y.NUMBER_TYPE=1;Y.STRING_TYPE=2;Y.BOOLEAN_TYPE=3;Y.UNORDERED_NODE_ITERATOR_TYPE=4;Y.ORDERED_NODE_ITERATOR_TYPE=5;Y.UNORDERED_NODE_SNAPSHOT_TYPE=6;Y.ORDERED_NODE_SNAPSHOT_TYPE=7;Y.ANY_UNORDERED_NODE_TYPE=8;Y.FIRST_ORDERED_NODE_TYPE=9;function Ob(a){this.lookupNamespaceURI=Kb(a)} function Pb(a,b){var c=a||k,d=c.Document&&c.Document.prototype||c.document;if(!d.evaluate||b)c.XPathResult=Y,d.evaluate=function(a,b,c,d){return(new Nb(a,c)).evaluate(b,d)},d.createExpression=function(a,b){return new Nb(a,b)},d.createNSResolver=function(a){return new Ob(a)}}var Qb=["wgxpath","install"],Z=k;Qb[0]in Z||!Z.execScript||Z.execScript("var "+Qb[0]);for(var Rb;Qb.length&&(Rb=Qb.shift());)Qb.length||void 0===Pb?Z[Rb]?Z=Z[Rb]:Z=Z[Rb]={}:Z[Rb]=Pb;module.exports.install=Pb;module.exports.XPathResultType={ANY_TYPE:0,NUMBER_TYPE:1,STRING_TYPE:2,BOOLEAN_TYPE:3,UNORDERED_NODE_ITERATOR_TYPE:4,ORDERED_NODE_ITERATOR_TYPE:5,UNORDERED_NODE_SNAPSHOT_TYPE:6,ORDERED_NODE_SNAPSHOT_TYPE:7,ANY_UNORDERED_NODE_TYPE:8,FIRST_ORDERED_NODE_TYPE:9};}).call(global) }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{}],5:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } var docReady = require('doc-ready'); var Connexion = require('./http/Connexion'); /** * Main BootLoader. * Defaults params for constructor should be {} and content.php?get_action=get_boot_conf */ var PydioBootstrap = (function () { /** * Constructor * @param startParameters Object The options */ function PydioBootstrap(startParameters) { var _this = this; _classCallCheck(this, PydioBootstrap); this.parameters = new Map(); for (var i in startParameters) { if (startParameters.hasOwnProperty(i)) { this.parameters.set(i, startParameters[i]); } } this.detectBaseParameters(); if (this.parameters.get("ALERT")) { window.setTimeout(function () { window.alert(_this.parameters.get("ALERT")); }, 0); } docReady((function () { var startedFromOpener = false; try { if (window.opener && window.opener.pydioBootstrap && this.parameters.get('serverAccessPath') === window.opener.pydioBootstrap.parameters.get('serverAccessPath')) { this.parameters = window.opener.pydioBootstrap.parameters; // Handle queryString case, as it's not passed via get_boot_conf var qParams = document.location.href.toQueryParams(); if (qParams['external_selector_type']) { this.parameters.set('SELECTOR_DATA', { type: qParams['external_selector_type'], data: qParams }); } else { if (this.parameters.get('SELECTOR_DATA')) { this.parameters.unset('SELECTOR_DATA'); } } this.refreshContextVariablesAndInit(new Connexion()); startedFromOpener = true; } } catch (e) { if (window.console && console.log) console.log(e); } if (!startedFromOpener) { this.loadBootConfig(); } }).bind(this)); window.Connexion = Connexion; window.pydioBootstrap = this; } /** * Real loading action */ PydioBootstrap.prototype.loadBootConfig = function loadBootConfig() { if (this.parameters.get('PRELOADED_BOOT_CONF')) { var preloaded = this.parameters.get('PRELOADED_BOOT_CONF'); for (var k in preloaded) { if (preloaded.hasOwnProperty(k)) { this.parameters.set(k, preloaded[k]); } } this.refreshContextVariablesAndInit(new Connexion()); return; } var url = this.parameters.get('BOOTER_URL') + (this.parameters.get("debugMode") ? '&debug=true' : ''); if (this.parameters.get('SERVER_PREFIX_URI')) { url += '&server_prefix_uri=' + this.parameters.get('SERVER_PREFIX_URI').replace(/\.\.\//g, "_UP_/"); } var connexion = new Connexion(url); connexion.onComplete = (function (transport) { if (transport.responseXML && transport.responseXML.documentElement && transport.responseXML.documentElement.nodeName == "tree") { var alert = XMLUtils.XPathSelectSingleNode(transport.responseXML.documentElement, "message"); window.alert('Exception caught by application : ' + alert.firstChild.nodeValue); return; } var phpError; var data = undefined; if (transport.responseJSON) { data = transport.responseJSON; } if (! typeof data === "object") { phpError = 'Exception uncaught by application : ' + transport.responseText; } if (phpError) { document.write(phpError); if (phpError.indexOf('Notice') > -1 || phpError.indexOf('Strict Standards') > -1) { window.alert('Php errors detected, it seems that Notice or Strict are detected, you may consider changing the PHP Error Reporting level!'); } return; } for (var key in data) { if (data.hasOwnProperty(key)) this.parameters.set(key, data[key]); } this.refreshContextVariablesAndInit(connexion); }).bind(this); connexion.sendAsync(); }; PydioBootstrap.prototype.refreshContextVariablesAndInit = function refreshContextVariablesAndInit(connexion) { Connexion.updateServerAccess(this.parameters); var cssRes = this.parameters.get("cssResources"); if (cssRes) cssRes.map(this.loadCSSResource.bind(this)); if (this.parameters.get('ajxpResourcesFolder')) { connexion._libUrl = this.parameters.get('ajxpResourcesFolder') + "/build"; window.ajxpResourcesFolder = this.parameters.get('ajxpResourcesFolder') + "/themes/" + this.parameters.get("theme"); } if (this.parameters.get('additional_js_resource')) { connexion.loadLibrary(this.parameters.get('additional_js_resource?v=' + this.parameters.get("ajxpVersion")), null, true); } //this.insertLoaderProgress(); window.MessageHash = this.parameters.get("i18nMessages"); if (!Object.keys(MessageHash).length) { alert('Ooups, this should not happen, your message file is empty!'); } for (var key in MessageHash) { MessageHash[key] = MessageHash[key].replace("\\n", "\n"); } window.zipEnabled = this.parameters.get("zipEnabled"); window.multipleFilesDownloadEnabled = this.parameters.get("multipleFilesDownloadEnabled"); var masterClassLoaded = (function () { var pydio = new Pydio(this.parameters); window.pydio = window.ajaxplorer = pydio; pydio.observe("actions_loaded", (function () { if (!this.parameters.get("SELECTOR_DATA") && pydio.getController().actions.get("ext_select")) { if (pydio.getController().actions._object) { pydio.getController().actions.unset("ext_select"); } else { pydio.getController().actions['delete']("ext_select"); } pydio.getController().fireContextChange(); pydio.getController().fireSelectionChange(); } else if (this.parameters.get("SELECTOR_DATA")) { pydio.getController().defaultActions.set("file", "ext_select"); } }).bind(this)); pydio.observe("loaded", (function (e) { if (this.parameters.get("SELECTOR_DATA")) { pydio.getController().defaultActions.set("file", "ext_select"); pydio.getController().selectorData = this.parameters.get("SELECTOR_DATA"); } }).bind(this)); if (this.parameters.get("currentLanguage")) { pydio.currentLanguage = this.parameters.get("currentLanguage"); } pydio.init(); }).bind(this); if (!this.parameters.get("debugMode")) { connexion.loadLibrary("pydio.min.js?v=" + this.parameters.get("ajxpVersion"), masterClassLoaded, true); } else { masterClassLoaded(); } var div = document.createElement('div'); div.setAttribute('style', 'position:absolute; bottom: 0; right: 0; z-index: 2000; color:rgba(0,0,0,0.6); font-size: 12px; padding: 0 10px;'); div.innerHTML = 'Pydio Community Edition - Copyright Abstrium 2017 - Learn more on pydio.com'; document.body.appendChild(div); }; /** * Detect the base path of the javascripts based on the script tags */ PydioBootstrap.prototype.detectBaseParameters = function detectBaseParameters() { var scripts = document.getElementsByTagName('script'); for (var i = 0; i < scripts.length; i++) { var scriptTag = scripts[i]; if (scriptTag.src.match("/build/pydio.boot.min.js") || scriptTag.src.match("/build/boot.prod.js")) { if (scriptTag.src.match("/build/pydio.boot.min.js")) { this.parameters.set("debugMode", false); } else { this.parameters.set("debugMode", true); } var src = scriptTag.src.replace('/build/boot.prod.js', '').replace('/build/pydio.boot.min.js', ''); if (src.indexOf("?") != -1) src = src.split("?")[0]; this.parameters.set("ajxpResourcesFolder", src); } } if (this.parameters.get("ajxpResourcesFolder")) { window.ajxpResourcesFolder = this.parameters.get("ajxpResourcesFolder"); } else { alert("Cannot find resource folder"); } var booterUrl = this.parameters.get("BOOTER_URL"); if (booterUrl.indexOf("?") > -1) { booterUrl = booterUrl.substring(0, booterUrl.indexOf("?")); } this.parameters.set('ajxpServerAccessPath', booterUrl); this.parameters.set('serverAccessPath', booterUrl); window.ajxpServerAccessPath = booterUrl; }; /** * Loads a CSS file * @param fileName String */ PydioBootstrap.prototype.loadCSSResource = function loadCSSResource(fileName) { var head = document.getElementsByTagName('head')[0]; var cssNode = document.createElement('link'); cssNode.type = 'text/css'; cssNode.rel = 'stylesheet'; cssNode.href = this.parameters.get("ajxpResourcesFolder") + '/' + fileName; cssNode.media = 'screen'; head.appendChild(cssNode); }; /** * Try to load something under data/cache/ * @param onError Function */ PydioBootstrap.testDataFolderAccess = function testDataFolderAccess(onError) { var c = new Connexion('data/cache/index.html'); c.setMethod('get'); c.onComplete = function (response) { if (200 === response.status) { onError(); } }; c.sendAsync(); }; return PydioBootstrap; })(); exports['default'] = PydioBootstrap; module.exports = exports['default']; },{"./http/Connexion":6,"doc-ready":1}],6:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . */ 'use strict'; exports.__esModule = true; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } var _utilXMLUtils = require('../util/XMLUtils'); var _utilXMLUtils2 = _interopRequireDefault(_utilXMLUtils); /** * Pydio encapsulation of XHR / Fetch */ require('whatwg-fetch'); var Connexion = (function () { /** * Constructor * @param baseUrl String The base url for services */ function Connexion(baseUrl) { _classCallCheck(this, Connexion); this._pydio = window.pydio; this._baseUrl = baseUrl || window.ajxpServerAccessPath; this._libUrl = window.ajxpResourcesFolder + '/build'; this._parameters = new Map(); this._method = 'post'; this.discrete = false; } Connexion.updateServerAccess = function updateServerAccess(parameters) { if (parameters.get('SECURE_TOKEN')) { Connexion.SECURE_TOKEN = parameters.get('SECURE_TOKEN'); } var serverAccessPath = parameters.get('ajxpServerAccess').split('?').shift(); if (parameters.get('SERVER_PREFIX_URI')) { parameters.set('ajxpResourcesFolder', parameters.get('SERVER_PREFIX_URI') + parameters.get('ajxpResourcesFolder')); serverAccessPath = parameters.get('SERVER_PREFIX_URI') + serverAccessPath + '?' + (Connexion.SECURE_TOKEN ? 'secure_token=' + Connexion.SECURE_TOKEN : ''); } else { serverAccessPath = serverAccessPath + '?' + (Connexion.SECURE_TOKEN ? 'secure_token=' + Connexion.SECURE_TOKEN : ''); } if (parameters.get('SERVER_PERMANENT_PARAMS')) { var permParams = parameters.get('SERVER_PERMANENT_PARAMS'); var permStrings = []; for (var permanent in permParams) { if (permParams.hasOwnProperty(permanent)) { permStrings.push(permanent + '=' + permParams[permanent]); } } permStrings = permStrings.join('&'); if (permStrings) { serverAccessPath += '&' + permStrings; } } parameters.set('ajxpServerAccess', serverAccessPath); // BACKWARD COMPAT window.ajxpServerAccessPath = serverAccessPath; if (window.pydioBootstrap && window.pydioBootstrap.parameters) { pydioBootstrap.parameters.set("ajxpServerAccess", serverAccessPath); pydioBootstrap.parameters.set("SECURE_TOKEN", Connexion.SECURE_TOKEN); } }; Connexion.log = function log(action, syncStatus) { if (!Connexion.PydioLogs) { Connexion.PydioLogs = []; } Connexion.PydioLogs.push({ action: action, sync: syncStatus }); }; /** * Add a parameter to the query * @param paramName String * @param paramValue String */ Connexion.prototype.addParameter = function addParameter(paramName, paramValue) { if (this._parameters.get(paramName) && paramName.endsWith('[]')) { var existing = this._parameters.get(paramName); if (!existing instanceof Array) { existing = [existing]; } existing.push(paramValue); this._parameters.set(paramName, existing); } else { this._parameters.set(paramName, paramValue); } }; /** * Sets the whole parameter as a bunch * @param hParameters Map */ Connexion.prototype.setParameters = function setParameters(hParameters) { if (hParameters instanceof Map) { this._parameters = hParameters; } else { if (hParameters._object) { console.error('Passed a legacy Hash object to Connexion.setParameters'); hParameters = hParameters._object; } for (var key in hParameters) { if (hParameters.hasOwnProperty(key)) { this._parameters.set(key, hParameters[key]); } } } }; /** * Set the query method (get post) * @param method String */ Connexion.prototype.setMethod = function setMethod(method) { this._method = method; }; /** * Add the secure token parameter */ Connexion.prototype.addSecureToken = function addSecureToken() { if (Connexion.SECURE_TOKEN && this._baseUrl.indexOf('secure_token') == -1 && !this._parameters.get('secure_token')) { this.addParameter('secure_token', Connexion.SECURE_TOKEN); } else if (this._baseUrl.indexOf('secure_token=') !== -1) { // Remove from baseUrl and set inside params var parts = this._baseUrl.split('secure_token='); var toks = parts[1].split('&'); var token = toks.shift(); var rest = toks.join('&'); this._baseUrl = parts[0] + (rest ? '&' + rest : ''); this._parameters.set('secure_token', token); } }; Connexion.prototype.addServerPermanentParams = function addServerPermanentParams() { if (!this._pydio || !this._pydio.Parameters.has('SERVER_PERMANENT_PARAMS')) { return; } var permParams = this._pydio.Parameters.get('SERVER_PERMANENT_PARAMS'); for (var permanent in permParams) { if (permParams.hasOwnProperty(permanent)) { this.addParameter(permanent, permParams[permanent]); } } }; /** * Show a small loader */ Connexion.prototype.showLoader = function showLoader() { if (this.discrete || !this._pydio) return; this._pydio.notify("connection-start"); }; /** * Hide a small loader */ Connexion.prototype.hideLoader = function hideLoader() { if (this.discrete || !this._pydio) return; this._pydio.notify("connection-end"); }; Connexion.prototype._send = function _send() { var _this = this; var aSync = arguments.length <= 0 || arguments[0] === undefined ? true : arguments[0]; Connexion.log(this._parameters.get("get_action"), aSync ? 'async' : 'sync'); this.addSecureToken(); this.addServerPermanentParams(); this.showLoader(); var oThis = this; var options = { method: this._method, credentials: 'same-origin' }; var url = this._baseUrl; if (!aSync) { options.synchronous = true; } var bodyParts = []; this._parameters.forEach(function (value, key) { if (value instanceof Array) { value.map(function (oneV) { bodyParts.push(key + '=' + encodeURIComponent(oneV)); }); } else { bodyParts.push(key + '=' + encodeURIComponent(value)); } }); var queryString = bodyParts.join('&'); if (this._method === 'post') { options.headers = { "Content-type": "application/x-www-form-urlencoded; charset=UTF-8" }; options.body = queryString; } else { url += (url.indexOf('?') > -1 ? '&' : '?') + queryString; } window.fetch(url, options).then(function (response) { var h = response.headers.get('Content-type'); if (h.indexOf('/json') !== -1) { response.json().then(function (json) { oThis.applyComplete({ responseJSON: json }, response); }); } else if (h.indexOf('/xml') !== -1) { response.text().then(function (text) { oThis.applyComplete({ responseXML: _utilXMLUtils2['default'].parseXml(text) }, response); }); } else { response.text().then(function (text) { oThis.applyComplete({ responseText: text }, response); }); } return response; })['catch'](function (error) { if (_this._pydio) { _this._pydio.displayMessage('ERROR', 'Network error ' + error.message); } }); }; /** * Send Asynchronously */ Connexion.prototype.sendAsync = function sendAsync() { this._send(true); }; /** * Send synchronously */ Connexion.prototype.sendSync = function sendSync() { this._send(false); }; /** * Apply the complete callback, try to grab maximum of errors * @param parsedBody Transpot */ Connexion.prototype.applyComplete = function applyComplete(parsedBody, response) { this.hideLoader(); var pydio = this._pydio; var message = undefined, tokenMessage = undefined; var tok1 = "Ooops, it seems that your security token has expired! Please %s by hitting refresh or F5 in your browser!"; var tok2 = "reload the page"; if (window.MessageHash && window.MessageHash[437]) { tok1 = window.MessageHash[437]; tok2 = window.MessageHash[438]; } tokenMessage = tok1.replace("%s", "" + tok2 + ""); var ctype = response.headers.get('Content-type'); if (parsedBody.responseXML && parsedBody.responseXML.documentElement && parsedBody.responseXML.documentElement.nodeName == "parsererror") { message = "Parsing error : \n" + parsedBody.responseXML.documentElement.firstChild.textContent; } else if (parsedBody.responseXML && parsedBody.responseXML.parseError && parsedBody.responseXML.parseError.errorCode != 0) { message = "Parsing Error : \n" + parsedBody.responseXML.parseError.reason; } else if (ctype.indexOf("text/xml") > -1 && parsedBody.responseXML == null) { message = "Expected XML but got empty response!"; } else if (ctype.indexOf("text/xml") == -1 && ctype.indexOf("application/json") == -1 && parsedBody.responseText.indexOf("Fatal error") > -1) { message = parsedBody.responseText.replace("
", ""); } else if (response.status == 500) { message = "Internal Server Error: you should check your web server logs to find what's going wrong!"; } if (message) { if (message.startsWith("You are not allowed to access this resource.")) { message = tokenMessage; } if (pydio) { pydio.displayMessage("ERROR", message); } else { alert(message); } } if (parsedBody.responseXML && parsedBody.responseXML.documentElement) { var authNode = _utilXMLUtils2['default'].XPathSelectSingleNode(parsedBody.responseXML.documentElement, "require_auth"); if (authNode && pydio) { var root = pydio.getContextHolder().getRootNode(); if (root) { pydio.getContextHolder().setContextNode(root); root.clear(); } pydio.getController().fireAction('logout'); setTimeout(function () { pydio.getController().fireAction('login'); }, 350); } var messageNode = _utilXMLUtils2['default'].XPathSelectSingleNode(parsedBody.responseXML.documentElement, "message"); if (messageNode) { var messageType = messageNode.getAttribute("type").toUpperCase(); var messageContent = _utilXMLUtils2['default'].getDomNodeText(messageNode); if (messageContent.startsWith("You are not allowed to access this resource.")) { messageContent = tokenMessage; } if (pydio) { pydio.displayMessage(messageType, messageContent); } else { if (messageType == "ERROR") { alert(messageType + ":" + messageContent); } } if (messageType == "SUCCESS") messageNode.parentNode.removeChild(messageNode); } } if (this.onComplete) { parsedBody.status = response.status; parsedBody.responseObject = response; this.onComplete(parsedBody); } if (pydio) { pydio.fire("server_answer", this); } }; Connexion.prototype.uploadFile = function uploadFile(file, fileParameterName, uploadUrl, onComplete, onError, onProgress, xhrSettings) { if (xhrSettings === undefined) xhrSettings = {}; if (!onComplete) onComplete = function () {}; if (!onError) onError = function () {}; if (!onProgress) onProgress = function () {}; var xhr = this.initializeXHRForUpload(uploadUrl, onComplete, onError, onProgress, xhrSettings); if (window.FormData) { this.sendFileUsingFormData(xhr, file, fileParameterName); } else if (window.FileReader) { var fileReader = new FileReader(); fileReader.onload = (function (e) { this.xhrSendAsBinary(xhr, file.name, e.target.result, fileParameterName); }).bind(this); fileReader.readAsBinaryString(file); } else if (file.getAsBinary) { this.xhrSendAsBinary(xhr, file.name, file.getAsBinary(), fileParameterName); } return xhr; }; Connexion.prototype.initializeXHRForUpload = function initializeXHRForUpload(url, onComplete, onError, onProgress, xhrSettings) { if (xhrSettings === undefined) xhrSettings = {}; var xhr = new XMLHttpRequest(); var upload = xhr.upload; if (xhrSettings.withCredentials) { xhr.withCredentials = true; } upload.addEventListener("progress", function (e) { if (!e.lengthComputable) return; onProgress(e); }, false); xhr.onreadystatechange = (function () { if (xhr.readyState == 4) { if (xhr.status === 200) { onComplete(xhr); } else { onError(xhr); } } }).bind(this); upload.onerror = function () { onError(xhr); }; xhr.open("POST", url, true); return xhr; }; Connexion.prototype.sendFileUsingFormData = function sendFileUsingFormData(xhr, file, fileParameterName) { var formData = new FormData(); formData.append(fileParameterName, file); xhr.send(formData); }; Connexion.prototype.xhrSendAsBinary = function xhrSendAsBinary(xhr, fileName, fileData, fileParameterName) { var boundary = '----MultiPartFormBoundary' + new Date().getTime(); xhr.setRequestHeader("Content-Type", "multipart/form-data, boundary=" + boundary); var body = "--" + boundary + "\r\n"; body += "Content-Disposition: form-data; name='" + fileParameterName + "'; filename='" + unescape(encodeURIComponent(fileName)) + "'\r\n"; body += "Content-Type: application/octet-stream\r\n\r\n"; body += fileData + "\r\n"; body += "--" + boundary + "--\r\n"; xhr.sendAsBinary(body); }; /** * Load a javascript library * @param fileName String * @param onLoadedCode Function Callback * @param aSync Boolean load library asynchroneously */ Connexion.prototype.loadLibrary = function loadLibrary(fileName, onLoadedCode, aSync) { var _this2 = this; if (window.pydioBootstrap && window.pydioBootstrap.parameters.get("ajxpVersion") && fileName.indexOf("?") == -1) { fileName += "?v=" + window.pydioBootstrap.parameters.get("ajxpVersion"); } var url = this._libUrl ? this._libUrl + '/' + fileName : fileName; var pydio = this._pydio; var scriptLoaded = function scriptLoaded(script) { try { if (window.execScript) { window.execScript(script); } else { window.my_code = script; var head = document.getElementsByTagName('head')[0]; var script_tag = document.createElement('script'); script_tag.type = 'text/javascript'; script_tag.innerHTML = 'eval(window.my_code)'; head.appendChild(script_tag); delete window.my_code; head.removeChild(script_tag); } if (onLoadedCode != null) onLoadedCode(); } catch (e) { alert('error loading ' + fileName + ':' + e.message); if (console) console.error(e); } if (pydio) pydio.fire("server_answer"); }; if (aSync) { window.fetch(url, { method: 'GET', credentials: 'same-origin' }).then(function (response) { return response.text(); }).then(function (script) { scriptLoaded(script); }); } else { (function () { // SHOULD BE REMOVED!! var xhr = new XMLHttpRequest(); xhr.onreadystatechange = (function () { if (xhr.readyState == 4) { if (xhr.status === 200) { scriptLoaded(xhr.responseText); } else { alert('error loading ' + fileName + ': Status code was ' + xhr.status); } } }).bind(_this2); xhr.open("GET", url, false); xhr.send(); })(); } }; return Connexion; })(); exports['default'] = Connexion; module.exports = exports['default']; },{"../util/XMLUtils":7,"whatwg-fetch":3}],7:[function(require,module,exports){ /* * Copyright 2007-2017 Charles du Jeu - Abstrium SAS * This file is part of Pydio. * * Pydio is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Pydio is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Pydio. If not, see . * * The latest code can be found at . * */ 'use strict'; exports.__esModule = true; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } var _wickedGoodXpath = require('wicked-good-xpath'); var _wickedGoodXpath2 = _interopRequireDefault(_wickedGoodXpath); _wickedGoodXpath2['default'].install(); /** * Utilitary class for manipulating XML */ var XMLUtils = (function () { function XMLUtils() { _classCallCheck(this, XMLUtils); } /** * Selects the first XmlNode that matches the XPath expression. * * @param element {Element | Document} root element for the search * @param query {String} XPath query * @return {Element} first matching element * @signature function(element, query) */ XMLUtils.XPathSelectSingleNode = function XPathSelectSingleNode(element, query) { try { if (element['selectSingleNode'] && typeof element.selectSingleNode === "function") { var res = element.selectSingleNode(query); if (res) return res; } } catch (e) {} if (!XMLUtils.__xpe && window.XPathEvaluator) { try { XMLUtils.__xpe = new XPathEvaluator(); } catch (e) {} } if (!XMLUtils.__xpe) { query = document.createExpression(query, null); var result = query.evaluate(element, 7, null); return result.snapshotLength ? result.snapshotItem(0) : null; } var xpe = XMLUtils.__xpe; try { return xpe.evaluate(query, element, xpe.createNSResolver(element), XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; } catch (err) { throw new Error("selectSingleNode: query: " + query + ", element: " + element + ", error: " + err); } }; /** * Selects a list of nodes matching the XPath expression. * * @param element {Element | Document} root element for the search * @param query {String} XPath query * @return {Element[]} List of matching elements * @signature function(element, query) */ XMLUtils.XPathSelectNodes = function XPathSelectNodes(element, query) { try { if (typeof element.selectNodes === "function") { try { if (element.ownerDocument && element.ownerDocument.setProperty) { element.ownerDocument.setProperty("SelectionLanguage", "XPath"); } else if (element.setProperty) { element.setProperty("SelectionLanguage", "XPath"); } } catch (e) {} var res = Array.from(element.selectNodes(query)); if (res) return res; } } catch (e) {} var xpe = XMLUtils.__xpe; if (!xpe && window.XPathEvaluator) { try { XMLUtils.__xpe = xpe = new XPathEvaluator(); } catch (e) {} } var result, nodes = [], i; if (!XMLUtils.__xpe) { query = document.createExpression(query, null); result = query.evaluate(element, 7, null); nodes = []; for (i = 0; i < result.snapshotLength; i++) { if (Element.extend) { nodes[i] = Element.extend(result.snapshotItem(i)); } else { nodes[i] = result.snapshotItem(i); } } return nodes; } try { result = xpe.evaluate(query, element, xpe.createNSResolver(element), XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); } catch (err) { throw new Error("selectNodes: query: " + query + ", element: " + element + ", error: " + err); } for (i = 0; i < result.snapshotLength; i++) { nodes[i] = result.snapshotItem(i); } return nodes; }; /** * Selects the first XmlNode that matches the XPath expression and returns the text content of the element * * @param element {Element|Document} root element for the search * @param query {String} XPath query * @return {String} the joined text content of the found element or null if not appropriate. * @signature function(element, query) */ XMLUtils.XPathGetSingleNodeText = function XPathGetSingleNodeText(element, query) { var node = XMLUtils.XPathSelectSingleNode(element, query); return XMLUtils.getDomNodeText(node); }; XMLUtils.getDomNodeText = function getDomNodeText(node) { var includeCData = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1]; if (!node || !node.nodeType) { return null; } switch (node.nodeType) { case 1: // NODE_ELEMENT var i, a = [], nodes = node.childNodes, length = nodes.length; for (i = 0; i < length; i++) { a[i] = XMLUtils.getDomNodeText(nodes[i], includeCData); } return a.join(""); case 2: // NODE_ATTRIBUTE return node.value; case 3: // NODE_TEXT return node.nodeValue; case 4: // CDATA if (includeCData) return node.nodeValue; break; } return null; }; /** * @param xmlStr * @returns {*} */ XMLUtils.parseXml = function parseXml(xmlStr) { if (typeof window.DOMParser != "undefined") { return new window.DOMParser().parseFromString(xmlStr, "text/xml"); } if (typeof window.ActiveXObject != "undefined" && new window.ActiveXObject("MSXML2.DOMDocument.6.0")) { var xmlDoc = new window.ActiveXObject("MSXML2.DOMDocument.6.0"); xmlDoc.validateOnParse = false; xmlDoc.async = false; xmlDoc.loadXML(xmlStr); xmlDoc.setProperty('SelectionLanguage', 'XPath'); return xmlDoc; } throw new Error('Cannot parse XML string'); }; return XMLUtils; })(); exports['default'] = XMLUtils; module.exports = exports['default']; },{"wicked-good-xpath":4}]},{},[5])(5) }); //# sourceMappingURL=data:application/json;charset:utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJub2RlX21vZHVsZXMvZG9jLXJlYWR5L2RvYy1yZWFkeS5qcyIsIm5vZGVfbW9kdWxlcy9ldmVudGllL2V2ZW50aWUuanMiLCJub2RlX21vZHVsZXMvd2hhdHdnLWZldGNoL2ZldGNoLmpzIiwibm9kZV9tb2R1bGVzL3dpY2tlZC1nb29kLXhwYXRoL2Rpc3Qvd2d4cGF0aC5pbnN0YWxsLW5vZGUuanMiLCJyZXMvYnVpbGQvY29yZS9QeWRpb0Jvb3RzdHJhcC5qcyIsInJlcy9idWlsZC9jb3JlL2h0dHAvQ29ubmV4aW9uLmpzIiwicmVzL2J1aWxkL2NvcmUvdXRpbC9YTUxVdGlscy5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUM3Y0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDN0VBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyBmLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pIiwiLyohXG4gKiBkb2NSZWFkeSB2MS4wLjRcbiAqIENyb3NzIGJyb3dzZXIgRE9NQ29udGVudExvYWRlZCBldmVudCBlbWl0dGVyXG4gKiBNSVQgbGljZW5zZVxuICovXG5cbi8qanNoaW50IGJyb3dzZXI6IHRydWUsIHN0cmljdDogdHJ1ZSwgdW5kZWY6IHRydWUsIHVudXNlZDogdHJ1ZSovXG4vKmdsb2JhbCBkZWZpbmU6IGZhbHNlLCByZXF1aXJlOiBmYWxzZSwgbW9kdWxlOiBmYWxzZSAqL1xuXG4oIGZ1bmN0aW9uKCB3aW5kb3cgKSB7XG5cbid1c2Ugc3RyaWN0JztcblxudmFyIGRvY3VtZW50ID0gd2luZG93LmRvY3VtZW50O1xuLy8gY29sbGVjdGlvbiBvZiBmdW5jdGlvbnMgdG8gYmUgdHJpZ2dlcmVkIG9uIHJlYWR5XG52YXIgcXVldWUgPSBbXTtcblxuZnVuY3Rpb24gZG9jUmVhZHkoIGZuICkge1xuICAvLyB0aHJvdyBvdXQgbm9uLWZ1bmN0aW9uc1xuICBpZiAoIHR5cGVvZiBmbiAhPT0gJ2Z1bmN0aW9uJyApIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAoIGRvY1JlYWR5LmlzUmVhZHkgKSB7XG4gICAgLy8gcmVhZHkgbm93LCBoaXQgaXRcbiAgICBmbigpO1xuICB9IGVsc2Uge1xuICAgIC8vIHF1ZXVlIGZ1bmN0aW9uIHdoZW4gcmVhZHlcbiAgICBxdWV1ZS5wdXNoKCBmbiApO1xuICB9XG59XG5cbmRvY1JlYWR5LmlzUmVhZHkgPSBmYWxzZTtcblxuLy8gdHJpZ2dlcmVkIG9uIHZhcmlvdXMgZG9jIHJlYWR5IGV2ZW50c1xuZnVuY3Rpb24gb25SZWFkeSggZXZlbnQgKSB7XG4gIC8vIGJhaWwgaWYgYWxyZWFkeSB0cmlnZ2VyZWQgb3IgSUU4IGRvY3VtZW50IGlzIG5vdCByZWFkeSBqdXN0IHlldFxuICB2YXIgaXNJRThOb3RSZWFkeSA9IGV2ZW50LnR5cGUgPT09ICdyZWFkeXN0YXRlY2hhbmdlJyAmJiBkb2N1bWVudC5yZWFkeVN0YXRlICE9PSAnY29tcGxldGUnO1xuICBpZiAoIGRvY1JlYWR5LmlzUmVhZHkgfHwgaXNJRThOb3RSZWFkeSApIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB0cmlnZ2VyKCk7XG59XG5cbmZ1bmN0aW9uIHRyaWdnZXIoKSB7XG4gIGRvY1JlYWR5LmlzUmVhZHkgPSB0cnVlO1xuICAvLyBwcm9jZXNzIHF1ZXVlXG4gIGZvciAoIHZhciBpPTAsIGxlbiA9IHF1ZXVlLmxlbmd0aDsgaSA8IGxlbjsgaSsrICkge1xuICAgIHZhciBmbiA9IHF1ZXVlW2ldO1xuICAgIGZuKCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZGVmaW5lRG9jUmVhZHkoIGV2ZW50aWUgKSB7XG4gIC8vIHRyaWdnZXIgcmVhZHkgaWYgcGFnZSBpcyByZWFkeVxuICBpZiAoIGRvY3VtZW50LnJlYWR5U3RhdGUgPT09ICdjb21wbGV0ZScgKSB7XG4gICAgdHJpZ2dlcigpO1xuICB9IGVsc2Uge1xuICAgIC8vIGxpc3RlbiBmb3IgZXZlbnRzXG4gICAgZXZlbnRpZS5iaW5kKCBkb2N1bWVudCwgJ0RPTUNvbnRlbnRMb2FkZWQnLCBvblJlYWR5ICk7XG4gICAgZXZlbnRpZS5iaW5kKCBkb2N1bWVudCwgJ3JlYWR5c3RhdGVjaGFuZ2UnLCBvblJlYWR5ICk7XG4gICAgZXZlbnRpZS5iaW5kKCB3aW5kb3csICdsb2FkJywgb25SZWFkeSApO1xuICB9XG5cbiAgcmV0dXJuIGRvY1JlYWR5O1xufVxuXG4vLyB0cmFuc3BvcnRcbmlmICggdHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kICkge1xuICAvLyBBTURcbiAgZGVmaW5lKCBbICdldmVudGllL2V2ZW50aWUnIF0sIGRlZmluZURvY1JlYWR5ICk7XG59IGVsc2UgaWYgKCB0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcgKSB7XG4gIG1vZHVsZS5leHBvcnRzID0gZGVmaW5lRG9jUmVhZHkoIHJlcXVpcmUoJ2V2ZW50aWUnKSApO1xufSBlbHNlIHtcbiAgLy8gYnJvd3NlciBnbG9iYWxcbiAgd2luZG93LmRvY1JlYWR5ID0gZGVmaW5lRG9jUmVhZHkoIHdpbmRvdy5ldmVudGllICk7XG59XG5cbn0pKCB3aW5kb3cgKTtcbiIsIi8qIVxuICogZXZlbnRpZSB2MS4wLjZcbiAqIGV2ZW50IGJpbmRpbmcgaGVscGVyXG4gKiAgIGV2ZW50aWUuYmluZCggZWxlbSwgJ2NsaWNrJywgbXlGbiApXG4gKiAgIGV2ZW50aWUudW5iaW5kKCBlbGVtLCAnY2xpY2snLCBteUZuIClcbiAqIE1JVCBsaWNlbnNlXG4gKi9cblxuLypqc2hpbnQgYnJvd3NlcjogdHJ1ZSwgdW5kZWY6IHRydWUsIHVudXNlZDogdHJ1ZSAqL1xuLypnbG9iYWwgZGVmaW5lOiBmYWxzZSwgbW9kdWxlOiBmYWxzZSAqL1xuXG4oIGZ1bmN0aW9uKCB3aW5kb3cgKSB7XG5cbid1c2Ugc3RyaWN0JztcblxudmFyIGRvY0VsZW0gPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7XG5cbnZhciBiaW5kID0gZnVuY3Rpb24oKSB7fTtcblxuZnVuY3Rpb24gZ2V0SUVFdmVudCggb2JqICkge1xuICB2YXIgZXZlbnQgPSB3aW5kb3cuZXZlbnQ7XG4gIC8vIGFkZCBldmVudC50YXJnZXRcbiAgZXZlbnQudGFyZ2V0ID0gZXZlbnQudGFyZ2V0IHx8IGV2ZW50LnNyY0VsZW1lbnQgfHwgb2JqO1xuICByZXR1cm4gZXZlbnQ7XG59XG5cbmlmICggZG9jRWxlbS5hZGRFdmVudExpc3RlbmVyICkge1xuICBiaW5kID0gZnVuY3Rpb24oIG9iaiwgdHlwZSwgZm4gKSB7XG4gICAgb2JqLmFkZEV2ZW50TGlzdGVuZXIoIHR5cGUsIGZuLCBmYWxzZSApO1xuICB9O1xufSBlbHNlIGlmICggZG9jRWxlbS5hdHRhY2hFdmVudCApIHtcbiAgYmluZCA9IGZ1bmN0aW9uKCBvYmosIHR5cGUsIGZuICkge1xuICAgIG9ialsgdHlwZSArIGZuIF0gPSBmbi5oYW5kbGVFdmVudCA/XG4gICAgICBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIGV2ZW50ID0gZ2V0SUVFdmVudCggb2JqICk7XG4gICAgICAgIGZuLmhhbmRsZUV2ZW50LmNhbGwoIGZuLCBldmVudCApO1xuICAgICAgfSA6XG4gICAgICBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIGV2ZW50ID0gZ2V0SUVFdmVudCggb2JqICk7XG4gICAgICAgIGZuLmNhbGwoIG9iaiwgZXZlbnQgKTtcbiAgICAgIH07XG4gICAgb2JqLmF0dGFjaEV2ZW50KCBcIm9uXCIgKyB0eXBlLCBvYmpbIHR5cGUgKyBmbiBdICk7XG4gIH07XG59XG5cbnZhciB1bmJpbmQgPSBmdW5jdGlvbigpIHt9O1xuXG5pZiAoIGRvY0VsZW0ucmVtb3ZlRXZlbnRMaXN0ZW5lciApIHtcbiAgdW5iaW5kID0gZnVuY3Rpb24oIG9iaiwgdHlwZSwgZm4gKSB7XG4gICAgb2JqLnJlbW92ZUV2ZW50TGlzdGVuZXIoIHR5cGUsIGZuLCBmYWxzZSApO1xuICB9O1xufSBlbHNlIGlmICggZG9jRWxlbS5kZXRhY2hFdmVudCApIHtcbiAgdW5iaW5kID0gZnVuY3Rpb24oIG9iaiwgdHlwZSwgZm4gKSB7XG4gICAgb2JqLmRldGFjaEV2ZW50KCBcIm9uXCIgKyB0eXBlLCBvYmpbIHR5cGUgKyBmbiBdICk7XG4gICAgdHJ5IHtcbiAgICAgIGRlbGV0ZSBvYmpbIHR5cGUgKyBmbiBdO1xuICAgIH0gY2F0Y2ggKCBlcnIgKSB7XG4gICAgICAvLyBjYW4ndCBkZWxldGUgd2luZG93IG9iamVjdCBwcm9wZXJ0aWVzXG4gICAgICBvYmpbIHR5cGUgKyBmbiBdID0gdW5kZWZpbmVkO1xuICAgIH1cbiAgfTtcbn1cblxudmFyIGV2ZW50aWUgPSB7XG4gIGJpbmQ6IGJpbmQsXG4gIHVuYmluZDogdW5iaW5kXG59O1xuXG4vLyAtLS0tLSBtb2R1bGUgZGVmaW5pdGlvbiAtLS0tLSAvL1xuXG5pZiAoIHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCApIHtcbiAgLy8gQU1EXG4gIGRlZmluZSggZXZlbnRpZSApO1xufSBlbHNlIGlmICggdHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnICkge1xuICAvLyBDb21tb25KU1xuICBtb2R1bGUuZXhwb3J0cyA9IGV2ZW50aWU7XG59IGVsc2Uge1xuICAvLyBicm93c2VyIGdsb2JhbFxuICB3aW5kb3cuZXZlbnRpZSA9IGV2ZW50aWU7XG59XG5cbn0pKCB3aW5kb3cgKTtcbiIsIihmdW5jdGlvbihzZWxmKSB7XG4gICd1c2Ugc3RyaWN0JztcblxuICBpZiAoc2VsZi5mZXRjaCkge1xuICAgIHJldHVyblxuICB9XG5cbiAgdmFyIHN1cHBvcnQgPSB7XG4gICAgc2VhcmNoUGFyYW1zOiAnVVJMU2VhcmNoUGFyYW1zJyBpbiBzZWxmLFxuICAgIGl0ZXJhYmxlOiAnU3ltYm9sJyBpbiBzZWxmICYmICdpdGVyYXRvcicgaW4gU3ltYm9sLFxuICAgIGJsb2I6ICdGaWxlUmVhZGVyJyBpbiBzZWxmICYmICdCbG9iJyBpbiBzZWxmICYmIChmdW5jdGlvbigpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIG5ldyBCbG9iKClcbiAgICAgICAgcmV0dXJuIHRydWVcbiAgICAgIH0gY2F0Y2goZSkge1xuICAgICAgICByZXR1cm4gZmFsc2VcbiAgICAgIH1cbiAgICB9KSgpLFxuICAgIGZvcm1EYXRhOiAnRm9ybURhdGEnIGluIHNlbGYsXG4gICAgYXJyYXlCdWZmZXI6ICdBcnJheUJ1ZmZlcicgaW4gc2VsZlxuICB9XG5cbiAgaWYgKHN1cHBvcnQuYXJyYXlCdWZmZXIpIHtcbiAgICB2YXIgdmlld0NsYXNzZXMgPSBbXG4gICAgICAnW29iamVjdCBJbnQ4QXJyYXldJyxcbiAgICAgICdbb2JqZWN0IFVpbnQ4QXJyYXldJyxcbiAgICAgICdbb2JqZWN0IFVpbnQ4Q2xhbXBlZEFycmF5XScsXG4gICAgICAnW29iamVjdCBJbnQxNkFycmF5XScsXG4gICAgICAnW29iamVjdCBVaW50MTZBcnJheV0nLFxuICAgICAgJ1tvYmplY3QgSW50MzJBcnJheV0nLFxuICAgICAgJ1tvYmplY3QgVWludDMyQXJyYXldJyxcbiAgICAgICdbb2JqZWN0IEZsb2F0MzJBcnJheV0nLFxuICAgICAgJ1tvYmplY3QgRmxvYXQ2NEFycmF5XSdcbiAgICBdXG5cbiAgICB2YXIgaXNEYXRhVmlldyA9IGZ1bmN0aW9uKG9iaikge1xuICAgICAgcmV0dXJuIG9iaiAmJiBEYXRhVmlldy5wcm90b3R5cGUuaXNQcm90b3R5cGVPZihvYmopXG4gICAgfVxuXG4gICAgdmFyIGlzQXJyYXlCdWZmZXJWaWV3ID0gQXJyYXlCdWZmZXIuaXNWaWV3IHx8IGZ1bmN0aW9uKG9iaikge1xuICAgICAgcmV0dXJuIG9iaiAmJiB2aWV3Q2xhc3Nlcy5pbmRleE9mKE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvYmopKSA+IC0xXG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gbm9ybWFsaXplTmFtZShuYW1lKSB7XG4gICAgaWYgKHR5cGVvZiBuYW1lICE9PSAnc3RyaW5nJykge1xuICAgICAgbmFtZSA9IFN0cmluZyhuYW1lKVxuICAgIH1cbiAgICBpZiAoL1teYS16MC05XFwtIyQlJicqKy5cXF5fYHx+XS9pLnRlc3QobmFtZSkpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0ludmFsaWQgY2hhcmFjdGVyIGluIGhlYWRlciBmaWVsZCBuYW1lJylcbiAgICB9XG4gICAgcmV0dXJuIG5hbWUudG9Mb3dlckNhc2UoKVxuICB9XG5cbiAgZnVuY3Rpb24gbm9ybWFsaXplVmFsdWUodmFsdWUpIHtcbiAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnc3RyaW5nJykge1xuICAgICAgdmFsdWUgPSBTdHJpbmcodmFsdWUpXG4gICAgfVxuICAgIHJldHVybiB2YWx1ZVxuICB9XG5cbiAgLy8gQnVpbGQgYSBkZXN0cnVjdGl2ZSBpdGVyYXRvciBmb3IgdGhlIHZhbHVlIGxpc3RcbiAgZnVuY3Rpb24gaXRlcmF0b3JGb3IoaXRlbXMpIHtcbiAgICB2YXIgaXRlcmF0b3IgPSB7XG4gICAgICBuZXh0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIHZhbHVlID0gaXRlbXMuc2hpZnQoKVxuICAgICAgICByZXR1cm4ge2RvbmU6IHZhbHVlID09PSB1bmRlZmluZWQsIHZhbHVlOiB2YWx1ZX1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoc3VwcG9ydC5pdGVyYWJsZSkge1xuICAgICAgaXRlcmF0b3JbU3ltYm9sLml0ZXJhdG9yXSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gaXRlcmF0b3JcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gaXRlcmF0b3JcbiAgfVxuXG4gIGZ1bmN0aW9uIEhlYWRlcnMoaGVhZGVycykge1xuICAgIHRoaXMubWFwID0ge31cblxuICAgIGlmIChoZWFkZXJzIGluc3RhbmNlb2YgSGVhZGVycykge1xuICAgICAgaGVhZGVycy5mb3JFYWNoKGZ1bmN0aW9uKHZhbHVlLCBuYW1lKSB7XG4gICAgICAgIHRoaXMuYXBwZW5kKG5hbWUsIHZhbHVlKVxuICAgICAgfSwgdGhpcylcbiAgICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkoaGVhZGVycykpIHtcbiAgICAgIGhlYWRlcnMuZm9yRWFjaChmdW5jdGlvbihoZWFkZXIpIHtcbiAgICAgICAgdGhpcy5hcHBlbmQoaGVhZGVyWzBdLCBoZWFkZXJbMV0pXG4gICAgICB9LCB0aGlzKVxuICAgIH0gZWxzZSBpZiAoaGVhZGVycykge1xuICAgICAgT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMoaGVhZGVycykuZm9yRWFjaChmdW5jdGlvbihuYW1lKSB7XG4gICAgICAgIHRoaXMuYXBwZW5kKG5hbWUsIGhlYWRlcnNbbmFtZV0pXG4gICAgICB9LCB0aGlzKVxuICAgIH1cbiAgfVxuXG4gIEhlYWRlcnMucHJvdG90eXBlLmFwcGVuZCA9IGZ1bmN0aW9uKG5hbWUsIHZhbHVlKSB7XG4gICAgbmFtZSA9IG5vcm1hbGl6ZU5hbWUobmFtZSlcbiAgICB2YWx1ZSA9IG5vcm1hbGl6ZVZhbHVlKHZhbHVlKVxuICAgIHZhciBvbGRWYWx1ZSA9IHRoaXMubWFwW25hbWVdXG4gICAgdGhpcy5tYXBbbmFtZV0gPSBvbGRWYWx1ZSA/IG9sZFZhbHVlKycsJyt2YWx1ZSA6IHZhbHVlXG4gIH1cblxuICBIZWFkZXJzLnByb3RvdHlwZVsnZGVsZXRlJ10gPSBmdW5jdGlvbihuYW1lKSB7XG4gICAgZGVsZXRlIHRoaXMubWFwW25vcm1hbGl6ZU5hbWUobmFtZSldXG4gIH1cblxuICBIZWFkZXJzLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbihuYW1lKSB7XG4gICAgbmFtZSA9IG5vcm1hbGl6ZU5hbWUobmFtZSlcbiAgICByZXR1cm4gdGhpcy5oYXMobmFtZSkgPyB0aGlzLm1hcFtuYW1lXSA6IG51bGxcbiAgfVxuXG4gIEhlYWRlcnMucHJvdG90eXBlLmhhcyA9IGZ1bmN0aW9uKG5hbWUpIHtcbiAgICByZXR1cm4gdGhpcy5tYXAuaGFzT3duUHJvcGVydHkobm9ybWFsaXplTmFtZShuYW1lKSlcbiAgfVxuXG4gIEhlYWRlcnMucHJvdG90eXBlLnNldCA9IGZ1bmN0aW9uKG5hbWUsIHZhbHVlKSB7XG4gICAgdGhpcy5tYXBbbm9ybWFsaXplTmFtZShuYW1lKV0gPSBub3JtYWxpemVWYWx1ZSh2YWx1ZSlcbiAgfVxuXG4gIEhlYWRlcnMucHJvdG90eXBlLmZvckVhY2ggPSBmdW5jdGlvbihjYWxsYmFjaywgdGhpc0FyZykge1xuICAgIGZvciAodmFyIG5hbWUgaW4gdGhpcy5tYXApIHtcbiAgICAgIGlmICh0aGlzLm1hcC5oYXNPd25Qcm9wZXJ0eShuYW1lKSkge1xuICAgICAgICBjYWxsYmFjay5jYWxsKHRoaXNBcmcsIHRoaXMubWFwW25hbWVdLCBuYW1lLCB0aGlzKVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIEhlYWRlcnMucHJvdG90eXBlLmtleXMgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgaXRlbXMgPSBbXVxuICAgIHRoaXMuZm9yRWFjaChmdW5jdGlvbih2YWx1ZSwgbmFtZSkgeyBpdGVtcy5wdXNoKG5hbWUpIH0pXG4gICAgcmV0dXJuIGl0ZXJhdG9yRm9yKGl0ZW1zKVxuICB9XG5cbiAgSGVhZGVycy5wcm90b3R5cGUudmFsdWVzID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGl0ZW1zID0gW11cbiAgICB0aGlzLmZvckVhY2goZnVuY3Rpb24odmFsdWUpIHsgaXRlbXMucHVzaCh2YWx1ZSkgfSlcbiAgICByZXR1cm4gaXRlcmF0b3JGb3IoaXRlbXMpXG4gIH1cblxuICBIZWFkZXJzLnByb3RvdHlwZS5lbnRyaWVzID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGl0ZW1zID0gW11cbiAgICB0aGlzLmZvckVhY2goZnVuY3Rpb24odmFsdWUsIG5hbWUpIHsgaXRlbXMucHVzaChbbmFtZSwgdmFsdWVdKSB9KVxuICAgIHJldHVybiBpdGVyYXRvckZvcihpdGVtcylcbiAgfVxuXG4gIGlmIChzdXBwb3J0Lml0ZXJhYmxlKSB7XG4gICAgSGVhZGVycy5wcm90b3R5cGVbU3ltYm9sLml0ZXJhdG9yXSA9IEhlYWRlcnMucHJvdG90eXBlLmVudHJpZXNcbiAgfVxuXG4gIGZ1bmN0aW9uIGNvbnN1bWVkKGJvZHkpIHtcbiAgICBpZiAoYm9keS5ib2R5VXNlZCkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBUeXBlRXJyb3IoJ0FscmVhZHkgcmVhZCcpKVxuICAgIH1cbiAgICBib2R5LmJvZHlVc2VkID0gdHJ1ZVxuICB9XG5cbiAgZnVuY3Rpb24gZmlsZVJlYWRlclJlYWR5KHJlYWRlcikge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgIHJlYWRlci5vbmxvYWQgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgcmVzb2x2ZShyZWFkZXIucmVzdWx0KVxuICAgICAgfVxuICAgICAgcmVhZGVyLm9uZXJyb3IgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgcmVqZWN0KHJlYWRlci5lcnJvcilcbiAgICAgIH1cbiAgICB9KVxuICB9XG5cbiAgZnVuY3Rpb24gcmVhZEJsb2JBc0FycmF5QnVmZmVyKGJsb2IpIHtcbiAgICB2YXIgcmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKVxuICAgIHZhciBwcm9taXNlID0gZmlsZVJlYWRlclJlYWR5KHJlYWRlcilcbiAgICByZWFkZXIucmVhZEFzQXJyYXlCdWZmZXIoYmxvYilcbiAgICByZXR1cm4gcHJvbWlzZVxuICB9XG5cbiAgZnVuY3Rpb24gcmVhZEJsb2JBc1RleHQoYmxvYikge1xuICAgIHZhciByZWFkZXIgPSBuZXcgRmlsZVJlYWRlcigpXG4gICAgdmFyIHByb21pc2UgPSBmaWxlUmVhZGVyUmVhZHkocmVhZGVyKVxuICAgIHJlYWRlci5yZWFkQXNUZXh0KGJsb2IpXG4gICAgcmV0dXJuIHByb21pc2VcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlYWRBcnJheUJ1ZmZlckFzVGV4dChidWYpIHtcbiAgICB2YXIgdmlldyA9IG5ldyBVaW50OEFycmF5KGJ1ZilcbiAgICB2YXIgY2hhcnMgPSBuZXcgQXJyYXkodmlldy5sZW5ndGgpXG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHZpZXcubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNoYXJzW2ldID0gU3RyaW5nLmZyb21DaGFyQ29kZSh2aWV3W2ldKVxuICAgIH1cbiAgICByZXR1cm4gY2hhcnMuam9pbignJylcbiAgfVxuXG4gIGZ1bmN0aW9uIGJ1ZmZlckNsb25lKGJ1Zikge1xuICAgIGlmIChidWYuc2xpY2UpIHtcbiAgICAgIHJldHVybiBidWYuc2xpY2UoMClcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIHZpZXcgPSBuZXcgVWludDhBcnJheShidWYuYnl0ZUxlbmd0aClcbiAgICAgIHZpZXcuc2V0KG5ldyBVaW50OEFycmF5KGJ1ZikpXG4gICAgICByZXR1cm4gdmlldy5idWZmZXJcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBCb2R5KCkge1xuICAgIHRoaXMuYm9keVVzZWQgPSBmYWxzZVxuXG4gICAgdGhpcy5faW5pdEJvZHkgPSBmdW5jdGlvbihib2R5KSB7XG4gICAgICB0aGlzLl9ib2R5SW5pdCA9IGJvZHlcbiAgICAgIGlmICghYm9keSkge1xuICAgICAgICB0aGlzLl9ib2R5VGV4dCA9ICcnXG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBib2R5ID09PSAnc3RyaW5nJykge1xuICAgICAgICB0aGlzLl9ib2R5VGV4dCA9IGJvZHlcbiAgICAgIH0gZWxzZSBpZiAoc3VwcG9ydC5ibG9iICYmIEJsb2IucHJvdG90eXBlLmlzUHJvdG90eXBlT2YoYm9keSkpIHtcbiAgICAgICAgdGhpcy5fYm9keUJsb2IgPSBib2R5XG4gICAgICB9IGVsc2UgaWYgKHN1cHBvcnQuZm9ybURhdGEgJiYgRm9ybURhdGEucHJvdG90eXBlLmlzUHJvdG90eXBlT2YoYm9keSkpIHtcbiAgICAgICAgdGhpcy5fYm9keUZvcm1EYXRhID0gYm9keVxuICAgICAgfSBlbHNlIGlmIChzdXBwb3J0LnNlYXJjaFBhcmFtcyAmJiBVUkxTZWFyY2hQYXJhbXMucHJvdG90eXBlLmlzUHJvdG90eXBlT2YoYm9keSkpIHtcbiAgICAgICAgdGhpcy5fYm9keVRleHQgPSBib2R5LnRvU3RyaW5nKClcbiAgICAgIH0gZWxzZSBpZiAoc3VwcG9ydC5hcnJheUJ1ZmZlciAmJiBzdXBwb3J0LmJsb2IgJiYgaXNEYXRhVmlldyhib2R5KSkge1xuICAgICAgICB0aGlzLl9ib2R5QXJyYXlCdWZmZXIgPSBidWZmZXJDbG9uZShib2R5LmJ1ZmZlcilcbiAgICAgICAgLy8gSUUgMTAtMTEgY2FuJ3QgaGFuZGxlIGEgRGF0YVZpZXcgYm9keS5cbiAgICAgICAgdGhpcy5fYm9keUluaXQgPSBuZXcgQmxvYihbdGhpcy5fYm9keUFycmF5QnVmZmVyXSlcbiAgICAgIH0gZWxzZSBpZiAoc3VwcG9ydC5hcnJheUJ1ZmZlciAmJiAoQXJyYXlCdWZmZXIucHJvdG90eXBlLmlzUHJvdG90eXBlT2YoYm9keSkgfHwgaXNBcnJheUJ1ZmZlclZpZXcoYm9keSkpKSB7XG4gICAgICAgIHRoaXMuX2JvZHlBcnJheUJ1ZmZlciA9IGJ1ZmZlckNsb25lKGJvZHkpXG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3Vuc3VwcG9ydGVkIEJvZHlJbml0IHR5cGUnKVxuICAgICAgfVxuXG4gICAgICBpZiAoIXRoaXMuaGVhZGVycy5nZXQoJ2NvbnRlbnQtdHlwZScpKSB7XG4gICAgICAgIGlmICh0eXBlb2YgYm9keSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICB0aGlzLmhlYWRlcnMuc2V0KCdjb250ZW50LXR5cGUnLCAndGV4dC9wbGFpbjtjaGFyc2V0PVVURi04JylcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLl9ib2R5QmxvYiAmJiB0aGlzLl9ib2R5QmxvYi50eXBlKSB7XG4gICAgICAgICAgdGhpcy5oZWFkZXJzLnNldCgnY29udGVudC10eXBlJywgdGhpcy5fYm9keUJsb2IudHlwZSlcbiAgICAgICAgfSBlbHNlIGlmIChzdXBwb3J0LnNlYXJjaFBhcmFtcyAmJiBVUkxTZWFyY2hQYXJhbXMucHJvdG90eXBlLmlzUHJvdG90eXBlT2YoYm9keSkpIHtcbiAgICAgICAgICB0aGlzLmhlYWRlcnMuc2V0KCdjb250ZW50LXR5cGUnLCAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkO2NoYXJzZXQ9VVRGLTgnKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHN1cHBvcnQuYmxvYikge1xuICAgICAgdGhpcy5ibG9iID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciByZWplY3RlZCA9IGNvbnN1bWVkKHRoaXMpXG4gICAgICAgIGlmIChyZWplY3RlZCkge1xuICAgICAgICAgIHJldHVybiByZWplY3RlZFxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuX2JvZHlCbG9iKSB7XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh0aGlzLl9ib2R5QmxvYilcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLl9ib2R5QXJyYXlCdWZmZXIpIHtcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKG5ldyBCbG9iKFt0aGlzLl9ib2R5QXJyYXlCdWZmZXJdKSlcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLl9ib2R5Rm9ybURhdGEpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2NvdWxkIG5vdCByZWFkIEZvcm1EYXRhIGJvZHkgYXMgYmxvYicpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShuZXcgQmxvYihbdGhpcy5fYm9keVRleHRdKSlcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB0aGlzLmFycmF5QnVmZmVyID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIGlmICh0aGlzLl9ib2R5QXJyYXlCdWZmZXIpIHtcbiAgICAgICAgICByZXR1cm4gY29uc3VtZWQodGhpcykgfHwgUHJvbWlzZS5yZXNvbHZlKHRoaXMuX2JvZHlBcnJheUJ1ZmZlcilcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5ibG9iKCkudGhlbihyZWFkQmxvYkFzQXJyYXlCdWZmZXIpXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLnRleHQgPSBmdW5jdGlvbigpIHtcbiAgICAgIHZhciByZWplY3RlZCA9IGNvbnN1bWVkKHRoaXMpXG4gICAgICBpZiAocmVqZWN0ZWQpIHtcbiAgICAgICAgcmV0dXJuIHJlamVjdGVkXG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLl9ib2R5QmxvYikge1xuICAgICAgICByZXR1cm4gcmVhZEJsb2JBc1RleHQodGhpcy5fYm9keUJsb2IpXG4gICAgICB9IGVsc2UgaWYgKHRoaXMuX2JvZHlBcnJheUJ1ZmZlcikge1xuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJlYWRBcnJheUJ1ZmZlckFzVGV4dCh0aGlzLl9ib2R5QXJyYXlCdWZmZXIpKVxuICAgICAgfSBlbHNlIGlmICh0aGlzLl9ib2R5Rm9ybURhdGEpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdjb3VsZCBub3QgcmVhZCBGb3JtRGF0YSBib2R5IGFzIHRleHQnKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh0aGlzLl9ib2R5VGV4dClcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoc3VwcG9ydC5mb3JtRGF0YSkge1xuICAgICAgdGhpcy5mb3JtRGF0YSA9IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gdGhpcy50ZXh0KCkudGhlbihkZWNvZGUpXG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5qc29uID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy50ZXh0KCkudGhlbihKU09OLnBhcnNlKVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzXG4gIH1cblxuICAvLyBIVFRQIG1ldGhvZHMgd2hvc2UgY2FwaXRhbGl6YXRpb24gc2hvdWxkIGJlIG5vcm1hbGl6ZWRcbiAgdmFyIG1ldGhvZHMgPSBbJ0RFTEVURScsICdHRVQnLCAnSEVBRCcsICdPUFRJT05TJywgJ1BPU1QnLCAnUFVUJ11cblxuICBmdW5jdGlvbiBub3JtYWxpemVNZXRob2QobWV0aG9kKSB7XG4gICAgdmFyIHVwY2FzZWQgPSBtZXRob2QudG9VcHBlckNhc2UoKVxuICAgIHJldHVybiAobWV0aG9kcy5pbmRleE9mKHVwY2FzZWQpID4gLTEpID8gdXBjYXNlZCA6IG1ldGhvZFxuICB9XG5cbiAgZnVuY3Rpb24gUmVxdWVzdChpbnB1dCwgb3B0aW9ucykge1xuICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9XG4gICAgdmFyIGJvZHkgPSBvcHRpb25zLmJvZHlcblxuICAgIGlmIChpbnB1dCBpbnN0YW5jZW9mIFJlcXVlc3QpIHtcbiAgICAgIGlmIChpbnB1dC5ib2R5VXNlZCkge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdBbHJlYWR5IHJlYWQnKVxuICAgICAgfVxuICAgICAgdGhpcy51cmwgPSBpbnB1dC51cmxcbiAgICAgIHRoaXMuY3JlZGVudGlhbHMgPSBpbnB1dC5jcmVkZW50aWFsc1xuICAgICAgaWYgKCFvcHRpb25zLmhlYWRlcnMpIHtcbiAgICAgICAgdGhpcy5oZWFkZXJzID0gbmV3IEhlYWRlcnMoaW5wdXQuaGVhZGVycylcbiAgICAgIH1cbiAgICAgIHRoaXMubWV0aG9kID0gaW5wdXQubWV0aG9kXG4gICAgICB0aGlzLm1vZGUgPSBpbnB1dC5tb2RlXG4gICAgICBpZiAoIWJvZHkgJiYgaW5wdXQuX2JvZHlJbml0ICE9IG51bGwpIHtcbiAgICAgICAgYm9keSA9IGlucHV0Ll9ib2R5SW5pdFxuICAgICAgICBpbnB1dC5ib2R5VXNlZCA9IHRydWVcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy51cmwgPSBTdHJpbmcoaW5wdXQpXG4gICAgfVxuXG4gICAgdGhpcy5jcmVkZW50aWFscyA9IG9wdGlvbnMuY3JlZGVudGlhbHMgfHwgdGhpcy5jcmVkZW50aWFscyB8fCAnb21pdCdcbiAgICBpZiAob3B0aW9ucy5oZWFkZXJzIHx8ICF0aGlzLmhlYWRlcnMpIHtcbiAgICAgIHRoaXMuaGVhZGVycyA9IG5ldyBIZWFkZXJzKG9wdGlvbnMuaGVhZGVycylcbiAgICB9XG4gICAgdGhpcy5tZXRob2QgPSBub3JtYWxpemVNZXRob2Qob3B0aW9ucy5tZXRob2QgfHwgdGhpcy5tZXRob2QgfHwgJ0dFVCcpXG4gICAgdGhpcy5tb2RlID0gb3B0aW9ucy5tb2RlIHx8IHRoaXMubW9kZSB8fCBudWxsXG4gICAgdGhpcy5yZWZlcnJlciA9IG51bGxcblxuICAgIGlmICgodGhpcy5tZXRob2QgPT09ICdHRVQnIHx8IHRoaXMubWV0aG9kID09PSAnSEVBRCcpICYmIGJvZHkpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0JvZHkgbm90IGFsbG93ZWQgZm9yIEdFVCBvciBIRUFEIHJlcXVlc3RzJylcbiAgICB9XG4gICAgdGhpcy5faW5pdEJvZHkoYm9keSlcbiAgfVxuXG4gIFJlcXVlc3QucHJvdG90eXBlLmNsb25lID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIG5ldyBSZXF1ZXN0KHRoaXMsIHsgYm9keTogdGhpcy5fYm9keUluaXQgfSlcbiAgfVxuXG4gIGZ1bmN0aW9uIGRlY29kZShib2R5KSB7XG4gICAgdmFyIGZvcm0gPSBuZXcgRm9ybURhdGEoKVxuICAgIGJvZHkudHJpbSgpLnNwbGl0KCcmJykuZm9yRWFjaChmdW5jdGlvbihieXRlcykge1xuICAgICAgaWYgKGJ5dGVzKSB7XG4gICAgICAgIHZhciBzcGxpdCA9IGJ5dGVzLnNwbGl0KCc9JylcbiAgICAgICAgdmFyIG5hbWUgPSBzcGxpdC5zaGlmdCgpLnJlcGxhY2UoL1xcKy9nLCAnICcpXG4gICAgICAgIHZhciB2YWx1ZSA9IHNwbGl0LmpvaW4oJz0nKS5yZXBsYWNlKC9cXCsvZywgJyAnKVxuICAgICAgICBmb3JtLmFwcGVuZChkZWNvZGVVUklDb21wb25lbnQobmFtZSksIGRlY29kZVVSSUNvbXBvbmVudCh2YWx1ZSkpXG4gICAgICB9XG4gICAgfSlcbiAgICByZXR1cm4gZm9ybVxuICB9XG5cbiAgZnVuY3Rpb24gcGFyc2VIZWFkZXJzKHJhd0hlYWRlcnMpIHtcbiAgICB2YXIgaGVhZGVycyA9IG5ldyBIZWFkZXJzKClcbiAgICByYXdIZWFkZXJzLnNwbGl0KC9cXHI/XFxuLykuZm9yRWFjaChmdW5jdGlvbihsaW5lKSB7XG4gICAgICB2YXIgcGFydHMgPSBsaW5lLnNwbGl0KCc6JylcbiAgICAgIHZhciBrZXkgPSBwYXJ0cy5zaGlmdCgpLnRyaW0oKVxuICAgICAgaWYgKGtleSkge1xuICAgICAgICB2YXIgdmFsdWUgPSBwYXJ0cy5qb2luKCc6JykudHJpbSgpXG4gICAgICAgIGhlYWRlcnMuYXBwZW5kKGtleSwgdmFsdWUpXG4gICAgICB9XG4gICAgfSlcbiAgICByZXR1cm4gaGVhZGVyc1xuICB9XG5cbiAgQm9keS5jYWxsKFJlcXVlc3QucHJvdG90eXBlKVxuXG4gIGZ1bmN0aW9uIFJlc3BvbnNlKGJvZHlJbml0LCBvcHRpb25zKSB7XG4gICAgaWYgKCFvcHRpb25zKSB7XG4gICAgICBvcHRpb25zID0ge31cbiAgICB9XG5cbiAgICB0aGlzLnR5cGUgPSAnZGVmYXVsdCdcbiAgICB0aGlzLnN0YXR1cyA9ICdzdGF0dXMnIGluIG9wdGlvbnMgPyBvcHRpb25zLnN0YXR1cyA6IDIwMFxuICAgIHRoaXMub2sgPSB0aGlzLnN0YXR1cyA+PSAyMDAgJiYgdGhpcy5zdGF0dXMgPCAzMDBcbiAgICB0aGlzLnN0YXR1c1RleHQgPSAnc3RhdHVzVGV4dCcgaW4gb3B0aW9ucyA/IG9wdGlvbnMuc3RhdHVzVGV4dCA6ICdPSydcbiAgICB0aGlzLmhlYWRlcnMgPSBuZXcgSGVhZGVycyhvcHRpb25zLmhlYWRlcnMpXG4gICAgdGhpcy51cmwgPSBvcHRpb25zLnVybCB8fCAnJ1xuICAgIHRoaXMuX2luaXRCb2R5KGJvZHlJbml0KVxuICB9XG5cbiAgQm9keS5jYWxsKFJlc3BvbnNlLnByb3RvdHlwZSlcblxuICBSZXNwb25zZS5wcm90b3R5cGUuY2xvbmUgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gbmV3IFJlc3BvbnNlKHRoaXMuX2JvZHlJbml0LCB7XG4gICAgICBzdGF0dXM6IHRoaXMuc3RhdHVzLFxuICAgICAgc3RhdHVzVGV4dDogdGhpcy5zdGF0dXNUZXh0LFxuICAgICAgaGVhZGVyczogbmV3IEhlYWRlcnModGhpcy5oZWFkZXJzKSxcbiAgICAgIHVybDogdGhpcy51cmxcbiAgICB9KVxuICB9XG5cbiAgUmVzcG9uc2UuZXJyb3IgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgcmVzcG9uc2UgPSBuZXcgUmVzcG9uc2UobnVsbCwge3N0YXR1czogMCwgc3RhdHVzVGV4dDogJyd9KVxuICAgIHJlc3BvbnNlLnR5cGUgPSAnZXJyb3InXG4gICAgcmV0dXJuIHJlc3BvbnNlXG4gIH1cblxuICB2YXIgcmVkaXJlY3RTdGF0dXNlcyA9IFszMDEsIDMwMiwgMzAzLCAzMDcsIDMwOF1cblxuICBSZXNwb25zZS5yZWRpcmVjdCA9IGZ1bmN0aW9uKHVybCwgc3RhdHVzKSB7XG4gICAgaWYgKHJlZGlyZWN0U3RhdHVzZXMuaW5kZXhPZihzdGF0dXMpID09PSAtMSkge1xuICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoJ0ludmFsaWQgc3RhdHVzIGNvZGUnKVxuICAgIH1cblxuICAgIHJldHVybiBuZXcgUmVzcG9uc2UobnVsbCwge3N0YXR1czogc3RhdHVzLCBoZWFkZXJzOiB7bG9jYXRpb246IHVybH19KVxuICB9XG5cbiAgc2VsZi5IZWFkZXJzID0gSGVhZGVyc1xuICBzZWxmLlJlcXVlc3QgPSBSZXF1ZXN0XG4gIHNlbGYuUmVzcG9uc2UgPSBSZXNwb25zZVxuXG4gIHNlbGYuZmV0Y2ggPSBmdW5jdGlvbihpbnB1dCwgaW5pdCkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICAgIHZhciByZXF1ZXN0ID0gbmV3IFJlcXVlc3QoaW5wdXQsIGluaXQpXG4gICAgICB2YXIgeGhyID0gbmV3IFhNTEh0dHBSZXF1ZXN0KClcblxuICAgICAgeGhyLm9ubG9hZCA9IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgb3B0aW9ucyA9IHtcbiAgICAgICAgICBzdGF0dXM6IHhoci5zdGF0dXMsXG4gICAgICAgICAgc3RhdHVzVGV4dDogeGhyLnN0YXR1c1RleHQsXG4gICAgICAgICAgaGVhZGVyczogcGFyc2VIZWFkZXJzKHhoci5nZXRBbGxSZXNwb25zZUhlYWRlcnMoKSB8fCAnJylcbiAgICAgICAgfVxuICAgICAgICBvcHRpb25zLnVybCA9ICdyZXNwb25zZVVSTCcgaW4geGhyID8geGhyLnJlc3BvbnNlVVJMIDogb3B0aW9ucy5oZWFkZXJzLmdldCgnWC1SZXF1ZXN0LVVSTCcpXG4gICAgICAgIHZhciBib2R5ID0gJ3Jlc3BvbnNlJyBpbiB4aHIgPyB4aHIucmVzcG9uc2UgOiB4aHIucmVzcG9uc2VUZXh0XG4gICAgICAgIHJlc29sdmUobmV3IFJlc3BvbnNlKGJvZHksIG9wdGlvbnMpKVxuICAgICAgfVxuXG4gICAgICB4aHIub25lcnJvciA9IGZ1bmN0aW9uKCkge1xuICAgICAgICByZWplY3QobmV3IFR5cGVFcnJvcignTmV0d29yayByZXF1ZXN0IGZhaWxlZCcpKVxuICAgICAgfVxuXG4gICAgICB4aHIub250aW1lb3V0ID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIHJlamVjdChuZXcgVHlwZUVycm9yKCdOZXR3b3JrIHJlcXVlc3QgZmFpbGVkJykpXG4gICAgICB9XG5cbiAgICAgIHhoci5vcGVuKHJlcXVlc3QubWV0aG9kLCByZXF1ZXN0LnVybCwgdHJ1ZSlcblxuICAgICAgaWYgKHJlcXVlc3QuY3JlZGVudGlhbHMgPT09ICdpbmNsdWRlJykge1xuICAgICAgICB4aHIud2l0aENyZWRlbnRpYWxzID0gdHJ1ZVxuICAgICAgfVxuXG4gICAgICBpZiAoJ3Jlc3BvbnNlVHlwZScgaW4geGhyICYmIHN1cHBvcnQuYmxvYikge1xuICAgICAgICB4aHIucmVzcG9uc2VUeXBlID0gJ2Jsb2InXG4gICAgICB9XG5cbiAgICAgIHJlcXVlc3QuaGVhZGVycy5mb3JFYWNoKGZ1bmN0aW9uKHZhbHVlLCBuYW1lKSB7XG4gICAgICAgIHhoci5zZXRSZXF1ZXN0SGVhZGVyKG5hbWUsIHZhbHVlKVxuICAgICAgfSlcblxuICAgICAgeGhyLnNlbmQodHlwZW9mIHJlcXVlc3QuX2JvZHlJbml0ID09PSAndW5kZWZpbmVkJyA/IG51bGwgOiByZXF1ZXN0Ll9ib2R5SW5pdClcbiAgICB9KVxuICB9XG4gIHNlbGYuZmV0Y2gucG9seWZpbGwgPSB0cnVlXG59KSh0eXBlb2Ygc2VsZiAhPT0gJ3VuZGVmaW5lZCcgPyBzZWxmIDogdGhpcyk7XG4iLCIoZnVuY3Rpb24oKXsndXNlIHN0cmljdCc7dmFyIGs9dGhpcztcbmZ1bmN0aW9uIGFhKGEpe3ZhciBiPXR5cGVvZiBhO2lmKFwib2JqZWN0XCI9PWIpaWYoYSl7aWYoYSBpbnN0YW5jZW9mIEFycmF5KXJldHVyblwiYXJyYXlcIjtpZihhIGluc3RhbmNlb2YgT2JqZWN0KXJldHVybiBiO3ZhciBjPU9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChhKTtpZihcIltvYmplY3QgV2luZG93XVwiPT1jKXJldHVyblwib2JqZWN0XCI7aWYoXCJbb2JqZWN0IEFycmF5XVwiPT1jfHxcIm51bWJlclwiPT10eXBlb2YgYS5sZW5ndGgmJlwidW5kZWZpbmVkXCIhPXR5cGVvZiBhLnNwbGljZSYmXCJ1bmRlZmluZWRcIiE9dHlwZW9mIGEucHJvcGVydHlJc0VudW1lcmFibGUmJiFhLnByb3BlcnR5SXNFbnVtZXJhYmxlKFwic3BsaWNlXCIpKXJldHVyblwiYXJyYXlcIjtpZihcIltvYmplY3QgRnVuY3Rpb25dXCI9PWN8fFwidW5kZWZpbmVkXCIhPXR5cGVvZiBhLmNhbGwmJlwidW5kZWZpbmVkXCIhPXR5cGVvZiBhLnByb3BlcnR5SXNFbnVtZXJhYmxlJiYhYS5wcm9wZXJ0eUlzRW51bWVyYWJsZShcImNhbGxcIikpcmV0dXJuXCJmdW5jdGlvblwifWVsc2UgcmV0dXJuXCJudWxsXCI7ZWxzZSBpZihcImZ1bmN0aW9uXCI9PVxuYiYmXCJ1bmRlZmluZWRcIj09dHlwZW9mIGEuY2FsbClyZXR1cm5cIm9iamVjdFwiO3JldHVybiBifWZ1bmN0aW9uIGwoYSl7cmV0dXJuXCJzdHJpbmdcIj09dHlwZW9mIGF9ZnVuY3Rpb24gYmEoYSxiLGMpe3JldHVybiBhLmNhbGwuYXBwbHkoYS5iaW5kLGFyZ3VtZW50cyl9ZnVuY3Rpb24gY2EoYSxiLGMpe2lmKCFhKXRocm93IEVycm9yKCk7aWYoMjxhcmd1bWVudHMubGVuZ3RoKXt2YXIgZD1BcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsMik7cmV0dXJuIGZ1bmN0aW9uKCl7dmFyIGM9QXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKTtBcnJheS5wcm90b3R5cGUudW5zaGlmdC5hcHBseShjLGQpO3JldHVybiBhLmFwcGx5KGIsYyl9fXJldHVybiBmdW5jdGlvbigpe3JldHVybiBhLmFwcGx5KGIsYXJndW1lbnRzKX19XG5mdW5jdGlvbiBkYShhLGIsYyl7ZGE9RnVuY3Rpb24ucHJvdG90eXBlLmJpbmQmJi0xIT1GdW5jdGlvbi5wcm90b3R5cGUuYmluZC50b1N0cmluZygpLmluZGV4T2YoXCJuYXRpdmUgY29kZVwiKT9iYTpjYTtyZXR1cm4gZGEuYXBwbHkobnVsbCxhcmd1bWVudHMpfWZ1bmN0aW9uIGVhKGEsYil7dmFyIGM9QXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLDEpO3JldHVybiBmdW5jdGlvbigpe3ZhciBiPWMuc2xpY2UoKTtiLnB1c2guYXBwbHkoYixhcmd1bWVudHMpO3JldHVybiBhLmFwcGx5KHRoaXMsYil9fVxuZnVuY3Rpb24gbShhKXt2YXIgYj1uO2Z1bmN0aW9uIGMoKXt9Yy5wcm90b3R5cGU9Yi5wcm90b3R5cGU7YS5HPWIucHJvdG90eXBlO2EucHJvdG90eXBlPW5ldyBjO2EucHJvdG90eXBlLmNvbnN0cnVjdG9yPWE7YS5GPWZ1bmN0aW9uKGEsYyxmKXtmb3IodmFyIGc9QXJyYXkoYXJndW1lbnRzLmxlbmd0aC0yKSxoPTI7aDxhcmd1bWVudHMubGVuZ3RoO2grKylnW2gtMl09YXJndW1lbnRzW2hdO3JldHVybiBiLnByb3RvdHlwZVtjXS5hcHBseShhLGcpfX07LypcblxuIFRoZSBNSVQgTGljZW5zZVxuXG4gQ29weXJpZ2h0IChjKSAyMDA3IEN5Ym96dSBMYWJzLCBJbmMuXG4gQ29weXJpZ2h0IChjKSAyMDEyIEdvb2dsZSBJbmMuXG5cbiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG4gb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG9cbiBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZVxuIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vclxuIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXG4gZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcblxuIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG5cbiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4gSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4gRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4gQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HXG4gRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HU1xuIElOIFRIRSBTT0ZUV0FSRS5cbiovXG52YXIgZmE9U3RyaW5nLnByb3RvdHlwZS50cmltP2Z1bmN0aW9uKGEpe3JldHVybiBhLnRyaW0oKX06ZnVuY3Rpb24oYSl7cmV0dXJuIGEucmVwbGFjZSgvXltcXHNcXHhhMF0rfFtcXHNcXHhhMF0rJC9nLFwiXCIpfTtmdW5jdGlvbiBxKGEsYil7cmV0dXJuLTEhPWEuaW5kZXhPZihiKX1mdW5jdGlvbiBnYShhLGIpe3JldHVybiBhPGI/LTE6YT5iPzE6MH07dmFyIGhhPUFycmF5LnByb3RvdHlwZS5pbmRleE9mP2Z1bmN0aW9uKGEsYixjKXtyZXR1cm4gQXJyYXkucHJvdG90eXBlLmluZGV4T2YuY2FsbChhLGIsYyl9OmZ1bmN0aW9uKGEsYixjKXtjPW51bGw9PWM/MDowPmM/TWF0aC5tYXgoMCxhLmxlbmd0aCtjKTpjO2lmKGwoYSkpcmV0dXJuIGwoYikmJjE9PWIubGVuZ3RoP2EuaW5kZXhPZihiLGMpOi0xO2Zvcig7YzxhLmxlbmd0aDtjKyspaWYoYyBpbiBhJiZhW2NdPT09YilyZXR1cm4gYztyZXR1cm4tMX0scj1BcnJheS5wcm90b3R5cGUuZm9yRWFjaD9mdW5jdGlvbihhLGIsYyl7QXJyYXkucHJvdG90eXBlLmZvckVhY2guY2FsbChhLGIsYyl9OmZ1bmN0aW9uKGEsYixjKXtmb3IodmFyIGQ9YS5sZW5ndGgsZT1sKGEpP2Euc3BsaXQoXCJcIik6YSxmPTA7ZjxkO2YrKylmIGluIGUmJmIuY2FsbChjLGVbZl0sZixhKX0saWE9QXJyYXkucHJvdG90eXBlLmZpbHRlcj9mdW5jdGlvbihhLGIsYyl7cmV0dXJuIEFycmF5LnByb3RvdHlwZS5maWx0ZXIuY2FsbChhLFxuYixjKX06ZnVuY3Rpb24oYSxiLGMpe2Zvcih2YXIgZD1hLmxlbmd0aCxlPVtdLGY9MCxnPWwoYSk/YS5zcGxpdChcIlwiKTphLGg9MDtoPGQ7aCsrKWlmKGggaW4gZyl7dmFyIHA9Z1toXTtiLmNhbGwoYyxwLGgsYSkmJihlW2YrK109cCl9cmV0dXJuIGV9LHQ9QXJyYXkucHJvdG90eXBlLnJlZHVjZT9mdW5jdGlvbihhLGIsYyxkKXtkJiYoYj1kYShiLGQpKTtyZXR1cm4gQXJyYXkucHJvdG90eXBlLnJlZHVjZS5jYWxsKGEsYixjKX06ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIGU9YztyKGEsZnVuY3Rpb24oYyxnKXtlPWIuY2FsbChkLGUsYyxnLGEpfSk7cmV0dXJuIGV9LGphPUFycmF5LnByb3RvdHlwZS5zb21lP2Z1bmN0aW9uKGEsYixjKXtyZXR1cm4gQXJyYXkucHJvdG90eXBlLnNvbWUuY2FsbChhLGIsYyl9OmZ1bmN0aW9uKGEsYixjKXtmb3IodmFyIGQ9YS5sZW5ndGgsZT1sKGEpP2Euc3BsaXQoXCJcIik6YSxmPTA7ZjxkO2YrKylpZihmIGluIGUmJmIuY2FsbChjLGVbZl0sZixhKSlyZXR1cm4hMDtcbnJldHVybiExfTtmdW5jdGlvbiBrYShhLGIpe3ZhciBjO2E6e2M9YS5sZW5ndGg7Zm9yKHZhciBkPWwoYSk/YS5zcGxpdChcIlwiKTphLGU9MDtlPGM7ZSsrKWlmKGUgaW4gZCYmYi5jYWxsKHZvaWQgMCxkW2VdLGUsYSkpe2M9ZTticmVhayBhfWM9LTF9cmV0dXJuIDA+Yz9udWxsOmwoYSk/YS5jaGFyQXQoYyk6YVtjXX1mdW5jdGlvbiBsYShhKXtyZXR1cm4gQXJyYXkucHJvdG90eXBlLmNvbmNhdC5hcHBseShBcnJheS5wcm90b3R5cGUsYXJndW1lbnRzKX1mdW5jdGlvbiBtYShhLGIsYyl7cmV0dXJuIDI+PWFyZ3VtZW50cy5sZW5ndGg/QXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYSxiKTpBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhLGIsYyl9O3ZhciB1O2E6e3ZhciBuYT1rLm5hdmlnYXRvcjtpZihuYSl7dmFyIG9hPW5hLnVzZXJBZ2VudDtpZihvYSl7dT1vYTticmVhayBhfX11PVwiXCJ9O3ZhciBwYT1xKHUsXCJPcGVyYVwiKXx8cSh1LFwiT1BSXCIpLHY9cSh1LFwiVHJpZGVudFwiKXx8cSh1LFwiTVNJRVwiKSxxYT1xKHUsXCJFZGdlXCIpLHJhPXEodSxcIkdlY2tvXCIpJiYhKHEodS50b0xvd2VyQ2FzZSgpLFwid2Via2l0XCIpJiYhcSh1LFwiRWRnZVwiKSkmJiEocSh1LFwiVHJpZGVudFwiKXx8cSh1LFwiTVNJRVwiKSkmJiFxKHUsXCJFZGdlXCIpLHNhPXEodS50b0xvd2VyQ2FzZSgpLFwid2Via2l0XCIpJiYhcSh1LFwiRWRnZVwiKTtmdW5jdGlvbiB0YSgpe3ZhciBhPWsuZG9jdW1lbnQ7cmV0dXJuIGE/YS5kb2N1bWVudE1vZGU6dm9pZCAwfXZhciB1YTtcbmE6e3ZhciB2YT1cIlwiLHdhPWZ1bmN0aW9uKCl7dmFyIGE9dTtpZihyYSlyZXR1cm4vcnZcXDooW15cXCk7XSspKFxcKXw7KS8uZXhlYyhhKTtpZihxYSlyZXR1cm4vRWRnZVxcLyhbXFxkXFwuXSspLy5leGVjKGEpO2lmKHYpcmV0dXJuL1xcYig/Ok1TSUV8cnYpWzogXShbXlxcKTtdKykoXFwpfDspLy5leGVjKGEpO2lmKHNhKXJldHVybi9XZWJLaXRcXC8oXFxTKykvLmV4ZWMoYSk7aWYocGEpcmV0dXJuLyg/OlZlcnNpb24pWyBcXC9dPyhcXFMrKS8uZXhlYyhhKX0oKTt3YSYmKHZhPXdhP3dhWzFdOlwiXCIpO2lmKHYpe3ZhciB4YT10YSgpO2lmKG51bGwhPXhhJiZ4YT5wYXJzZUZsb2F0KHZhKSl7dWE9U3RyaW5nKHhhKTticmVhayBhfX11YT12YX12YXIgeWE9e307XG5mdW5jdGlvbiB6YShhKXtpZigheWFbYV0pe2Zvcih2YXIgYj0wLGM9ZmEoU3RyaW5nKHVhKSkuc3BsaXQoXCIuXCIpLGQ9ZmEoU3RyaW5nKGEpKS5zcGxpdChcIi5cIiksZT1NYXRoLm1heChjLmxlbmd0aCxkLmxlbmd0aCksZj0wOzA9PWImJmY8ZTtmKyspe3ZhciBnPWNbZl18fFwiXCIsaD1kW2ZdfHxcIlwiLHA9LyhcXGQqKShcXEQqKS9nLHk9LyhcXGQqKShcXEQqKS9nO2Rve3ZhciBEPXAuZXhlYyhnKXx8W1wiXCIsXCJcIixcIlwiXSxYPXkuZXhlYyhoKXx8W1wiXCIsXCJcIixcIlwiXTtpZigwPT1EWzBdLmxlbmd0aCYmMD09WFswXS5sZW5ndGgpYnJlYWs7Yj1nYSgwPT1EWzFdLmxlbmd0aD8wOnBhcnNlSW50KERbMV0sMTApLDA9PVhbMV0ubGVuZ3RoPzA6cGFyc2VJbnQoWFsxXSwxMCkpfHxnYSgwPT1EWzJdLmxlbmd0aCwwPT1YWzJdLmxlbmd0aCl8fGdhKERbMl0sWFsyXSl9d2hpbGUoMD09Yil9eWFbYV09MDw9Yn19XG52YXIgQWE9ay5kb2N1bWVudCxCYT1BYSYmdj90YSgpfHwoXCJDU1MxQ29tcGF0XCI9PUFhLmNvbXBhdE1vZGU/cGFyc2VJbnQodWEsMTApOjUpOnZvaWQgMDt2YXIgdz12JiYhKDk8PU51bWJlcihCYSkpLENhPXYmJiEoODw9TnVtYmVyKEJhKSk7ZnVuY3Rpb24geChhLGIsYyxkKXt0aGlzLmE9YTt0aGlzLm5vZGVOYW1lPWM7dGhpcy5ub2RlVmFsdWU9ZDt0aGlzLm5vZGVUeXBlPTI7dGhpcy5wYXJlbnROb2RlPXRoaXMub3duZXJFbGVtZW50PWJ9ZnVuY3Rpb24gRGEoYSxiKXt2YXIgYz1DYSYmXCJocmVmXCI9PWIubm9kZU5hbWU/YS5nZXRBdHRyaWJ1dGUoYi5ub2RlTmFtZSwyKTpiLm5vZGVWYWx1ZTtyZXR1cm4gbmV3IHgoYixhLGIubm9kZU5hbWUsYyl9O2Z1bmN0aW9uIHooYSl7dmFyIGI9bnVsbCxjPWEubm9kZVR5cGU7MT09YyYmKGI9YS50ZXh0Q29udGVudCxiPXZvaWQgMD09Ynx8bnVsbD09Yj9hLmlubmVyVGV4dDpiLGI9dm9pZCAwPT1ifHxudWxsPT1iP1wiXCI6Yik7aWYoXCJzdHJpbmdcIiE9dHlwZW9mIGIpaWYodyYmXCJ0aXRsZVwiPT1hLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkmJjE9PWMpYj1hLnRleHQ7ZWxzZSBpZig5PT1jfHwxPT1jKXthPTk9PWM/YS5kb2N1bWVudEVsZW1lbnQ6YS5maXJzdENoaWxkO2Zvcih2YXIgYz0wLGQ9W10sYj1cIlwiO2E7KXtkbyAxIT1hLm5vZGVUeXBlJiYoYis9YS5ub2RlVmFsdWUpLHcmJlwidGl0bGVcIj09YS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpJiYoYis9YS50ZXh0KSxkW2MrK109YTt3aGlsZShhPWEuZmlyc3RDaGlsZCk7Zm9yKDtjJiYhKGE9ZFstLWNdLm5leHRTaWJsaW5nKTspO319ZWxzZSBiPWEubm9kZVZhbHVlO3JldHVyblwiXCIrYn1cbmZ1bmN0aW9uIEEoYSxiLGMpe2lmKG51bGw9PT1iKXJldHVybiEwO3RyeXtpZighYS5nZXRBdHRyaWJ1dGUpcmV0dXJuITF9Y2F0Y2goZCl7cmV0dXJuITF9Q2EmJlwiY2xhc3NcIj09YiYmKGI9XCJjbGFzc05hbWVcIik7cmV0dXJuIG51bGw9PWM/ISFhLmdldEF0dHJpYnV0ZShiKTphLmdldEF0dHJpYnV0ZShiLDIpPT1jfWZ1bmN0aW9uIEIoYSxiLGMsZCxlKXtyZXR1cm4odz9FYTpGYSkuY2FsbChudWxsLGEsYixsKGMpP2M6bnVsbCxsKGQpP2Q6bnVsbCxlfHxuZXcgQyl9XG5mdW5jdGlvbiBFYShhLGIsYyxkLGUpe2lmKGEgaW5zdGFuY2VvZiBFfHw4PT1hLmJ8fGMmJm51bGw9PT1hLmIpe3ZhciBmPWIuYWxsO2lmKCFmKXJldHVybiBlO2E9R2EoYSk7aWYoXCIqXCIhPWEmJihmPWIuZ2V0RWxlbWVudHNCeVRhZ05hbWUoYSksIWYpKXJldHVybiBlO2lmKGMpe2Zvcih2YXIgZz1bXSxoPTA7Yj1mW2grK107KUEoYixjLGQpJiZnLnB1c2goYik7Zj1nfWZvcihoPTA7Yj1mW2grK107KVwiKlwiPT1hJiZcIiFcIj09Yi50YWdOYW1lfHxGKGUsYik7cmV0dXJuIGV9SGEoYSxiLGMsZCxlKTtyZXR1cm4gZX1cbmZ1bmN0aW9uIEZhKGEsYixjLGQsZSl7Yi5nZXRFbGVtZW50c0J5TmFtZSYmZCYmXCJuYW1lXCI9PWMmJiF2PyhiPWIuZ2V0RWxlbWVudHNCeU5hbWUoZCkscihiLGZ1bmN0aW9uKGIpe2EuYShiKSYmRihlLGIpfSkpOmIuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSYmZCYmXCJjbGFzc1wiPT1jPyhiPWIuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZShkKSxyKGIsZnVuY3Rpb24oYil7Yi5jbGFzc05hbWU9PWQmJmEuYShiKSYmRihlLGIpfSkpOmEgaW5zdGFuY2VvZiBHP0hhKGEsYixjLGQsZSk6Yi5nZXRFbGVtZW50c0J5VGFnTmFtZSYmKGI9Yi5nZXRFbGVtZW50c0J5VGFnTmFtZShhLmYoKSkscihiLGZ1bmN0aW9uKGEpe0EoYSxjLGQpJiZGKGUsYSl9KSk7cmV0dXJuIGV9XG5mdW5jdGlvbiBJYShhLGIsYyxkLGUpe3ZhciBmO2lmKChhIGluc3RhbmNlb2YgRXx8OD09YS5ifHxjJiZudWxsPT09YS5iKSYmKGY9Yi5jaGlsZE5vZGVzKSl7dmFyIGc9R2EoYSk7aWYoXCIqXCIhPWcmJihmPWlhKGYsZnVuY3Rpb24oYSl7cmV0dXJuIGEudGFnTmFtZSYmYS50YWdOYW1lLnRvTG93ZXJDYXNlKCk9PWd9KSwhZikpcmV0dXJuIGU7YyYmKGY9aWEoZixmdW5jdGlvbihhKXtyZXR1cm4gQShhLGMsZCl9KSk7cihmLGZ1bmN0aW9uKGEpe1wiKlwiPT1nJiYoXCIhXCI9PWEudGFnTmFtZXx8XCIqXCI9PWcmJjEhPWEubm9kZVR5cGUpfHxGKGUsYSl9KTtyZXR1cm4gZX1yZXR1cm4gSmEoYSxiLGMsZCxlKX1mdW5jdGlvbiBKYShhLGIsYyxkLGUpe2ZvcihiPWIuZmlyc3RDaGlsZDtiO2I9Yi5uZXh0U2libGluZylBKGIsYyxkKSYmYS5hKGIpJiZGKGUsYik7cmV0dXJuIGV9XG5mdW5jdGlvbiBIYShhLGIsYyxkLGUpe2ZvcihiPWIuZmlyc3RDaGlsZDtiO2I9Yi5uZXh0U2libGluZylBKGIsYyxkKSYmYS5hKGIpJiZGKGUsYiksSGEoYSxiLGMsZCxlKX1mdW5jdGlvbiBHYShhKXtpZihhIGluc3RhbmNlb2YgRyl7aWYoOD09YS5iKXJldHVyblwiIVwiO2lmKG51bGw9PT1hLmIpcmV0dXJuXCIqXCJ9cmV0dXJuIGEuZigpfTshcmEmJiF2fHx2JiY5PD1OdW1iZXIoQmEpfHxyYSYmemEoXCIxLjkuMVwiKTt2JiZ6YShcIjlcIik7ZnVuY3Rpb24gS2EoYSxiKXtpZighYXx8IWIpcmV0dXJuITE7aWYoYS5jb250YWlucyYmMT09Yi5ub2RlVHlwZSlyZXR1cm4gYT09Ynx8YS5jb250YWlucyhiKTtpZihcInVuZGVmaW5lZFwiIT10eXBlb2YgYS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbilyZXR1cm4gYT09Ynx8ISEoYS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbihiKSYxNik7Zm9yKDtiJiZhIT1iOyliPWIucGFyZW50Tm9kZTtyZXR1cm4gYj09YX1cbmZ1bmN0aW9uIExhKGEsYil7aWYoYT09YilyZXR1cm4gMDtpZihhLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKXJldHVybiBhLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKGIpJjI/MTotMTtpZih2JiYhKDk8PU51bWJlcihCYSkpKXtpZig5PT1hLm5vZGVUeXBlKXJldHVybi0xO2lmKDk9PWIubm9kZVR5cGUpcmV0dXJuIDF9aWYoXCJzb3VyY2VJbmRleFwiaW4gYXx8YS5wYXJlbnROb2RlJiZcInNvdXJjZUluZGV4XCJpbiBhLnBhcmVudE5vZGUpe3ZhciBjPTE9PWEubm9kZVR5cGUsZD0xPT1iLm5vZGVUeXBlO2lmKGMmJmQpcmV0dXJuIGEuc291cmNlSW5kZXgtYi5zb3VyY2VJbmRleDt2YXIgZT1hLnBhcmVudE5vZGUsZj1iLnBhcmVudE5vZGU7cmV0dXJuIGU9PWY/TWEoYSxiKTohYyYmS2EoZSxiKT8tMSpOYShhLGIpOiFkJiZLYShmLGEpP05hKGIsYSk6KGM/YS5zb3VyY2VJbmRleDplLnNvdXJjZUluZGV4KS0oZD9iLnNvdXJjZUluZGV4OmYuc291cmNlSW5kZXgpfWQ9OT09YS5ub2RlVHlwZT9cbmE6YS5vd25lckRvY3VtZW50fHxhLmRvY3VtZW50O2M9ZC5jcmVhdGVSYW5nZSgpO2Muc2VsZWN0Tm9kZShhKTtjLmNvbGxhcHNlKCEwKTtkPWQuY3JlYXRlUmFuZ2UoKTtkLnNlbGVjdE5vZGUoYik7ZC5jb2xsYXBzZSghMCk7cmV0dXJuIGMuY29tcGFyZUJvdW5kYXJ5UG9pbnRzKGsuUmFuZ2UuU1RBUlRfVE9fRU5ELGQpfWZ1bmN0aW9uIE5hKGEsYil7dmFyIGM9YS5wYXJlbnROb2RlO2lmKGM9PWIpcmV0dXJuLTE7Zm9yKHZhciBkPWI7ZC5wYXJlbnROb2RlIT1jOylkPWQucGFyZW50Tm9kZTtyZXR1cm4gTWEoZCxhKX1mdW5jdGlvbiBNYShhLGIpe2Zvcih2YXIgYz1iO2M9Yy5wcmV2aW91c1NpYmxpbmc7KWlmKGM9PWEpcmV0dXJuLTE7cmV0dXJuIDF9O2Z1bmN0aW9uIEMoKXt0aGlzLmI9dGhpcy5hPW51bGw7dGhpcy5sPTB9ZnVuY3Rpb24gT2EoYSl7dGhpcy5ub2RlPWE7dGhpcy5hPXRoaXMuYj1udWxsfWZ1bmN0aW9uIFBhKGEsYil7aWYoIWEuYSlyZXR1cm4gYjtpZighYi5hKXJldHVybiBhO2Zvcih2YXIgYz1hLmEsZD1iLmEsZT1udWxsLGY9bnVsbCxnPTA7YyYmZDspe3ZhciBmPWMubm9kZSxoPWQubm9kZTtmPT1ofHxmIGluc3RhbmNlb2YgeCYmaCBpbnN0YW5jZW9mIHgmJmYuYT09aC5hPyhmPWMsYz1jLmEsZD1kLmEpOjA8TGEoYy5ub2RlLGQubm9kZSk/KGY9ZCxkPWQuYSk6KGY9YyxjPWMuYSk7KGYuYj1lKT9lLmE9ZjphLmE9ZjtlPWY7ZysrfWZvcihmPWN8fGQ7ZjspZi5iPWUsZT1lLmE9ZixnKyssZj1mLmE7YS5iPWU7YS5sPWc7cmV0dXJuIGF9ZnVuY3Rpb24gUWEoYSxiKXt2YXIgYz1uZXcgT2EoYik7Yy5hPWEuYTthLmI/YS5hLmI9YzphLmE9YS5iPWM7YS5hPWM7YS5sKyt9XG5mdW5jdGlvbiBGKGEsYil7dmFyIGM9bmV3IE9hKGIpO2MuYj1hLmI7YS5hP2EuYi5hPWM6YS5hPWEuYj1jO2EuYj1jO2EubCsrfWZ1bmN0aW9uIFJhKGEpe3JldHVybihhPWEuYSk/YS5ub2RlOm51bGx9ZnVuY3Rpb24gU2EoYSl7cmV0dXJuKGE9UmEoYSkpP3ooYSk6XCJcIn1mdW5jdGlvbiBIKGEsYil7cmV0dXJuIG5ldyBUYShhLCEhYil9ZnVuY3Rpb24gVGEoYSxiKXt0aGlzLmY9YTt0aGlzLmI9KHRoaXMuYz1iKT9hLmI6YS5hO3RoaXMuYT1udWxsfWZ1bmN0aW9uIEkoYSl7dmFyIGI9YS5iO2lmKG51bGw9PWIpcmV0dXJuIG51bGw7dmFyIGM9YS5hPWI7YS5iPWEuYz9iLmI6Yi5hO3JldHVybiBjLm5vZGV9O2Z1bmN0aW9uIG4oYSl7dGhpcy5pPWE7dGhpcy5iPXRoaXMuZz0hMTt0aGlzLmY9bnVsbH1mdW5jdGlvbiBKKGEpe3JldHVyblwiXFxuICBcIithLnRvU3RyaW5nKCkuc3BsaXQoXCJcXG5cIikuam9pbihcIlxcbiAgXCIpfWZ1bmN0aW9uIFVhKGEsYil7YS5nPWJ9ZnVuY3Rpb24gVmEoYSxiKXthLmI9Yn1mdW5jdGlvbiBLKGEsYil7dmFyIGM9YS5hKGIpO3JldHVybiBjIGluc3RhbmNlb2YgQz8rU2EoYyk6K2N9ZnVuY3Rpb24gTChhLGIpe3ZhciBjPWEuYShiKTtyZXR1cm4gYyBpbnN0YW5jZW9mIEM/U2EoYyk6XCJcIitjfWZ1bmN0aW9uIE0oYSxiKXt2YXIgYz1hLmEoYik7cmV0dXJuIGMgaW5zdGFuY2VvZiBDPyEhYy5sOiEhY307ZnVuY3Rpb24gTihhLGIsYyl7bi5jYWxsKHRoaXMsYS5pKTt0aGlzLmM9YTt0aGlzLmg9Yjt0aGlzLm89Yzt0aGlzLmc9Yi5nfHxjLmc7dGhpcy5iPWIuYnx8Yy5iO3RoaXMuYz09V2EmJihjLmJ8fGMuZ3x8ND09Yy5pfHwwPT1jLml8fCFiLmY/Yi5ifHxiLmd8fDQ9PWIuaXx8MD09Yi5pfHwhYy5mfHwodGhpcy5mPXtuYW1lOmMuZi5uYW1lLHM6Yn0pOnRoaXMuZj17bmFtZTpiLmYubmFtZSxzOmN9KX1tKE4pO1xuZnVuY3Rpb24gTyhhLGIsYyxkLGUpe2I9Yi5hKGQpO2M9Yy5hKGQpO3ZhciBmO2lmKGIgaW5zdGFuY2VvZiBDJiZjIGluc3RhbmNlb2YgQyl7Yj1IKGIpO2ZvcihkPUkoYik7ZDtkPUkoYikpZm9yKGU9SChjKSxmPUkoZSk7ZjtmPUkoZSkpaWYoYSh6KGQpLHooZikpKXJldHVybiEwO3JldHVybiExfWlmKGIgaW5zdGFuY2VvZiBDfHxjIGluc3RhbmNlb2YgQyl7YiBpbnN0YW5jZW9mIEM/KGU9YixkPWMpOihlPWMsZD1iKTtmPUgoZSk7Zm9yKHZhciBnPXR5cGVvZiBkLGg9SShmKTtoO2g9SShmKSl7c3dpdGNoKGcpe2Nhc2UgXCJudW1iZXJcIjpoPSt6KGgpO2JyZWFrO2Nhc2UgXCJib29sZWFuXCI6aD0hIXooaCk7YnJlYWs7Y2FzZSBcInN0cmluZ1wiOmg9eihoKTticmVhaztkZWZhdWx0OnRocm93IEVycm9yKFwiSWxsZWdhbCBwcmltaXRpdmUgdHlwZSBmb3IgY29tcGFyaXNvbi5cIik7fWlmKGU9PWImJmEoaCxkKXx8ZT09YyYmYShkLGgpKXJldHVybiEwfXJldHVybiExfXJldHVybiBlP1wiYm9vbGVhblwiPT1cbnR5cGVvZiBifHxcImJvb2xlYW5cIj09dHlwZW9mIGM/YSghIWIsISFjKTpcIm51bWJlclwiPT10eXBlb2YgYnx8XCJudW1iZXJcIj09dHlwZW9mIGM/YSgrYiwrYyk6YShiLGMpOmEoK2IsK2MpfU4ucHJvdG90eXBlLmE9ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYy5tKHRoaXMuaCx0aGlzLm8sYSl9O04ucHJvdG90eXBlLnRvU3RyaW5nPWZ1bmN0aW9uKCl7dmFyIGE9XCJCaW5hcnkgRXhwcmVzc2lvbjogXCIrdGhpcy5jLGE9YStKKHRoaXMuaCk7cmV0dXJuIGErPUoodGhpcy5vKX07ZnVuY3Rpb24gWGEoYSxiLGMsZCl7dGhpcy5hPWE7dGhpcy53PWI7dGhpcy5pPWM7dGhpcy5tPWR9WGEucHJvdG90eXBlLnRvU3RyaW5nPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYX07dmFyIFlhPXt9O1xuZnVuY3Rpb24gUChhLGIsYyxkKXtpZihZYS5oYXNPd25Qcm9wZXJ0eShhKSl0aHJvdyBFcnJvcihcIkJpbmFyeSBvcGVyYXRvciBhbHJlYWR5IGNyZWF0ZWQ6IFwiK2EpO2E9bmV3IFhhKGEsYixjLGQpO3JldHVybiBZYVthLnRvU3RyaW5nKCldPWF9UChcImRpdlwiLDYsMSxmdW5jdGlvbihhLGIsYyl7cmV0dXJuIEsoYSxjKS9LKGIsYyl9KTtQKFwibW9kXCIsNiwxLGZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gSyhhLGMpJUsoYixjKX0pO1AoXCIqXCIsNiwxLGZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gSyhhLGMpKksoYixjKX0pO1AoXCIrXCIsNSwxLGZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gSyhhLGMpK0soYixjKX0pO1AoXCItXCIsNSwxLGZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gSyhhLGMpLUsoYixjKX0pO1AoXCI8XCIsNCwyLGZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gTyhmdW5jdGlvbihhLGIpe3JldHVybiBhPGJ9LGEsYixjKX0pO1xuUChcIj5cIiw0LDIsZnVuY3Rpb24oYSxiLGMpe3JldHVybiBPKGZ1bmN0aW9uKGEsYil7cmV0dXJuIGE+Yn0sYSxiLGMpfSk7UChcIjw9XCIsNCwyLGZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gTyhmdW5jdGlvbihhLGIpe3JldHVybiBhPD1ifSxhLGIsYyl9KTtQKFwiPj1cIiw0LDIsZnVuY3Rpb24oYSxiLGMpe3JldHVybiBPKGZ1bmN0aW9uKGEsYil7cmV0dXJuIGE+PWJ9LGEsYixjKX0pO3ZhciBXYT1QKFwiPVwiLDMsMixmdW5jdGlvbihhLGIsYyl7cmV0dXJuIE8oZnVuY3Rpb24oYSxiKXtyZXR1cm4gYT09Yn0sYSxiLGMsITApfSk7UChcIiE9XCIsMywyLGZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gTyhmdW5jdGlvbihhLGIpe3JldHVybiBhIT1ifSxhLGIsYywhMCl9KTtQKFwiYW5kXCIsMiwyLGZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gTShhLGMpJiZNKGIsYyl9KTtQKFwib3JcIiwxLDIsZnVuY3Rpb24oYSxiLGMpe3JldHVybiBNKGEsYyl8fE0oYixjKX0pO2Z1bmN0aW9uIFEoYSxiLGMpe3RoaXMuYT1hO3RoaXMuYj1ifHwxO3RoaXMuZj1jfHwxfTtmdW5jdGlvbiBaYShhLGIpe2lmKGIuYS5sZW5ndGgmJjQhPWEuaSl0aHJvdyBFcnJvcihcIlByaW1hcnkgZXhwcmVzc2lvbiBtdXN0IGV2YWx1YXRlIHRvIG5vZGVzZXQgaWYgZmlsdGVyIGhhcyBwcmVkaWNhdGUocykuXCIpO24uY2FsbCh0aGlzLGEuaSk7dGhpcy5jPWE7dGhpcy5oPWI7dGhpcy5nPWEuZzt0aGlzLmI9YS5ifW0oWmEpO1phLnByb3RvdHlwZS5hPWZ1bmN0aW9uKGEpe2E9dGhpcy5jLmEoYSk7cmV0dXJuICRhKHRoaXMuaCxhKX07WmEucHJvdG90eXBlLnRvU3RyaW5nPWZ1bmN0aW9uKCl7dmFyIGE7YT1cIkZpbHRlcjpcIitKKHRoaXMuYyk7cmV0dXJuIGErPUoodGhpcy5oKX07ZnVuY3Rpb24gYWIoYSxiKXtpZihiLmxlbmd0aDxhLkEpdGhyb3cgRXJyb3IoXCJGdW5jdGlvbiBcIithLmorXCIgZXhwZWN0cyBhdCBsZWFzdFwiK2EuQStcIiBhcmd1bWVudHMsIFwiK2IubGVuZ3RoK1wiIGdpdmVuXCIpO2lmKG51bGwhPT1hLnYmJmIubGVuZ3RoPmEudil0aHJvdyBFcnJvcihcIkZ1bmN0aW9uIFwiK2EuaitcIiBleHBlY3RzIGF0IG1vc3QgXCIrYS52K1wiIGFyZ3VtZW50cywgXCIrYi5sZW5ndGgrXCIgZ2l2ZW5cIik7YS5CJiZyKGIsZnVuY3Rpb24oYixkKXtpZig0IT1iLmkpdGhyb3cgRXJyb3IoXCJBcmd1bWVudCBcIitkK1wiIHRvIGZ1bmN0aW9uIFwiK2EuaitcIiBpcyBub3Qgb2YgdHlwZSBOb2Rlc2V0OiBcIitiKTt9KTtuLmNhbGwodGhpcyxhLmkpO3RoaXMuaD1hO3RoaXMuYz1iO1VhKHRoaXMsYS5nfHxqYShiLGZ1bmN0aW9uKGEpe3JldHVybiBhLmd9KSk7VmEodGhpcyxhLkQmJiFiLmxlbmd0aHx8YS5DJiYhIWIubGVuZ3RofHxqYShiLGZ1bmN0aW9uKGEpe3JldHVybiBhLmJ9KSl9bShhYik7XG5hYi5wcm90b3R5cGUuYT1mdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5oLm0uYXBwbHkobnVsbCxsYShhLHRoaXMuYykpfTthYi5wcm90b3R5cGUudG9TdHJpbmc9ZnVuY3Rpb24oKXt2YXIgYT1cIkZ1bmN0aW9uOiBcIit0aGlzLmg7aWYodGhpcy5jLmxlbmd0aCl2YXIgYj10KHRoaXMuYyxmdW5jdGlvbihhLGIpe3JldHVybiBhK0ooYil9LFwiQXJndW1lbnRzOlwiKSxhPWErSihiKTtyZXR1cm4gYX07ZnVuY3Rpb24gYmIoYSxiLGMsZCxlLGYsZyxoLHApe3RoaXMuaj1hO3RoaXMuaT1iO3RoaXMuZz1jO3RoaXMuRD1kO3RoaXMuQz1lO3RoaXMubT1mO3RoaXMuQT1nO3RoaXMudj12b2lkIDAhPT1oP2g6Zzt0aGlzLkI9ISFwfWJiLnByb3RvdHlwZS50b1N0cmluZz1mdW5jdGlvbigpe3JldHVybiB0aGlzLmp9O3ZhciBjYj17fTtcbmZ1bmN0aW9uIFIoYSxiLGMsZCxlLGYsZyxoKXtpZihjYi5oYXNPd25Qcm9wZXJ0eShhKSl0aHJvdyBFcnJvcihcIkZ1bmN0aW9uIGFscmVhZHkgY3JlYXRlZDogXCIrYStcIi5cIik7Y2JbYV09bmV3IGJiKGEsYixjLGQsITEsZSxmLGcsaCl9UihcImJvb2xlYW5cIiwyLCExLCExLGZ1bmN0aW9uKGEsYil7cmV0dXJuIE0oYixhKX0sMSk7UihcImNlaWxpbmdcIiwxLCExLCExLGZ1bmN0aW9uKGEsYil7cmV0dXJuIE1hdGguY2VpbChLKGIsYSkpfSwxKTtSKFwiY29uY2F0XCIsMywhMSwhMSxmdW5jdGlvbihhLGIpe3JldHVybiB0KG1hKGFyZ3VtZW50cywxKSxmdW5jdGlvbihiLGQpe3JldHVybiBiK0woZCxhKX0sXCJcIil9LDIsbnVsbCk7UihcImNvbnRhaW5zXCIsMiwhMSwhMSxmdW5jdGlvbihhLGIsYyl7cmV0dXJuIHEoTChiLGEpLEwoYyxhKSl9LDIpO1IoXCJjb3VudFwiLDEsITEsITEsZnVuY3Rpb24oYSxiKXtyZXR1cm4gYi5hKGEpLmx9LDEsMSwhMCk7XG5SKFwiZmFsc2VcIiwyLCExLCExLGZ1bmN0aW9uKCl7cmV0dXJuITF9LDApO1IoXCJmbG9vclwiLDEsITEsITEsZnVuY3Rpb24oYSxiKXtyZXR1cm4gTWF0aC5mbG9vcihLKGIsYSkpfSwxKTtSKFwiaWRcIiw0LCExLCExLGZ1bmN0aW9uKGEsYil7ZnVuY3Rpb24gYyhhKXtpZih3KXt2YXIgYj1lLmFsbFthXTtpZihiKXtpZihiLm5vZGVUeXBlJiZhPT1iLmlkKXJldHVybiBiO2lmKGIubGVuZ3RoKXJldHVybiBrYShiLGZ1bmN0aW9uKGIpe3JldHVybiBhPT1iLmlkfSl9cmV0dXJuIG51bGx9cmV0dXJuIGUuZ2V0RWxlbWVudEJ5SWQoYSl9dmFyIGQ9YS5hLGU9OT09ZC5ub2RlVHlwZT9kOmQub3duZXJEb2N1bWVudCxkPUwoYixhKS5zcGxpdCgvXFxzKy8pLGY9W107cihkLGZ1bmN0aW9uKGEpe2E9YyhhKTshYXx8MDw9aGEoZixhKXx8Zi5wdXNoKGEpfSk7Zi5zb3J0KExhKTt2YXIgZz1uZXcgQztyKGYsZnVuY3Rpb24oYSl7RihnLGEpfSk7cmV0dXJuIGd9LDEpO1xuUihcImxhbmdcIiwyLCExLCExLGZ1bmN0aW9uKCl7cmV0dXJuITF9LDEpO1IoXCJsYXN0XCIsMSwhMCwhMSxmdW5jdGlvbihhKXtpZigxIT1hcmd1bWVudHMubGVuZ3RoKXRocm93IEVycm9yKFwiRnVuY3Rpb24gbGFzdCBleHBlY3RzICgpXCIpO3JldHVybiBhLmZ9LDApO1IoXCJsb2NhbC1uYW1lXCIsMywhMSwhMCxmdW5jdGlvbihhLGIpe3ZhciBjPWI/UmEoYi5hKGEpKTphLmE7cmV0dXJuIGM/Yy5sb2NhbE5hbWV8fGMubm9kZU5hbWUudG9Mb3dlckNhc2UoKTpcIlwifSwwLDEsITApO1IoXCJuYW1lXCIsMywhMSwhMCxmdW5jdGlvbihhLGIpe3ZhciBjPWI/UmEoYi5hKGEpKTphLmE7cmV0dXJuIGM/Yy5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpOlwiXCJ9LDAsMSwhMCk7UihcIm5hbWVzcGFjZS11cmlcIiwzLCEwLCExLGZ1bmN0aW9uKCl7cmV0dXJuXCJcIn0sMCwxLCEwKTtcblIoXCJub3JtYWxpemUtc3BhY2VcIiwzLCExLCEwLGZ1bmN0aW9uKGEsYil7cmV0dXJuKGI/TChiLGEpOnooYS5hKSkucmVwbGFjZSgvW1xcc1xceGEwXSsvZyxcIiBcIikucmVwbGFjZSgvXlxccyt8XFxzKyQvZyxcIlwiKX0sMCwxKTtSKFwibm90XCIsMiwhMSwhMSxmdW5jdGlvbihhLGIpe3JldHVybiFNKGIsYSl9LDEpO1IoXCJudW1iZXJcIiwxLCExLCEwLGZ1bmN0aW9uKGEsYil7cmV0dXJuIGI/SyhiLGEpOit6KGEuYSl9LDAsMSk7UihcInBvc2l0aW9uXCIsMSwhMCwhMSxmdW5jdGlvbihhKXtyZXR1cm4gYS5ifSwwKTtSKFwicm91bmRcIiwxLCExLCExLGZ1bmN0aW9uKGEsYil7cmV0dXJuIE1hdGgucm91bmQoSyhiLGEpKX0sMSk7UihcInN0YXJ0cy13aXRoXCIsMiwhMSwhMSxmdW5jdGlvbihhLGIsYyl7Yj1MKGIsYSk7YT1MKGMsYSk7cmV0dXJuIDA9PWIubGFzdEluZGV4T2YoYSwwKX0sMik7UihcInN0cmluZ1wiLDMsITEsITAsZnVuY3Rpb24oYSxiKXtyZXR1cm4gYj9MKGIsYSk6eihhLmEpfSwwLDEpO1xuUihcInN0cmluZy1sZW5ndGhcIiwxLCExLCEwLGZ1bmN0aW9uKGEsYil7cmV0dXJuKGI/TChiLGEpOnooYS5hKSkubGVuZ3RofSwwLDEpO1IoXCJzdWJzdHJpbmdcIiwzLCExLCExLGZ1bmN0aW9uKGEsYixjLGQpe2M9SyhjLGEpO2lmKGlzTmFOKGMpfHxJbmZpbml0eT09Y3x8LUluZmluaXR5PT1jKXJldHVyblwiXCI7ZD1kP0soZCxhKTpJbmZpbml0eTtpZihpc05hTihkKXx8LUluZmluaXR5PT09ZClyZXR1cm5cIlwiO2M9TWF0aC5yb3VuZChjKS0xO3ZhciBlPU1hdGgubWF4KGMsMCk7YT1MKGIsYSk7cmV0dXJuIEluZmluaXR5PT1kP2Euc3Vic3RyaW5nKGUpOmEuc3Vic3RyaW5nKGUsYytNYXRoLnJvdW5kKGQpKX0sMiwzKTtSKFwic3Vic3RyaW5nLWFmdGVyXCIsMywhMSwhMSxmdW5jdGlvbihhLGIsYyl7Yj1MKGIsYSk7YT1MKGMsYSk7Yz1iLmluZGV4T2YoYSk7cmV0dXJuLTE9PWM/XCJcIjpiLnN1YnN0cmluZyhjK2EubGVuZ3RoKX0sMik7XG5SKFwic3Vic3RyaW5nLWJlZm9yZVwiLDMsITEsITEsZnVuY3Rpb24oYSxiLGMpe2I9TChiLGEpO2E9TChjLGEpO2E9Yi5pbmRleE9mKGEpO3JldHVybi0xPT1hP1wiXCI6Yi5zdWJzdHJpbmcoMCxhKX0sMik7UihcInN1bVwiLDEsITEsITEsZnVuY3Rpb24oYSxiKXtmb3IodmFyIGM9SChiLmEoYSkpLGQ9MCxlPUkoYyk7ZTtlPUkoYykpZCs9K3ooZSk7cmV0dXJuIGR9LDEsMSwhMCk7UihcInRyYW5zbGF0ZVwiLDMsITEsITEsZnVuY3Rpb24oYSxiLGMsZCl7Yj1MKGIsYSk7Yz1MKGMsYSk7dmFyIGU9TChkLGEpO2E9e307Zm9yKGQ9MDtkPGMubGVuZ3RoO2QrKyl7dmFyIGY9Yy5jaGFyQXQoZCk7ZiBpbiBhfHwoYVtmXT1lLmNoYXJBdChkKSl9Yz1cIlwiO2ZvcihkPTA7ZDxiLmxlbmd0aDtkKyspZj1iLmNoYXJBdChkKSxjKz1mIGluIGE/YVtmXTpmO3JldHVybiBjfSwzKTtSKFwidHJ1ZVwiLDIsITEsITEsZnVuY3Rpb24oKXtyZXR1cm4hMH0sMCk7ZnVuY3Rpb24gRyhhLGIpe3RoaXMuaD1hO3RoaXMuYz12b2lkIDAhPT1iP2I6bnVsbDt0aGlzLmI9bnVsbDtzd2l0Y2goYSl7Y2FzZSBcImNvbW1lbnRcIjp0aGlzLmI9ODticmVhaztjYXNlIFwidGV4dFwiOnRoaXMuYj0zO2JyZWFrO2Nhc2UgXCJwcm9jZXNzaW5nLWluc3RydWN0aW9uXCI6dGhpcy5iPTc7YnJlYWs7Y2FzZSBcIm5vZGVcIjpicmVhaztkZWZhdWx0OnRocm93IEVycm9yKFwiVW5leHBlY3RlZCBhcmd1bWVudFwiKTt9fWZ1bmN0aW9uIGRiKGEpe3JldHVyblwiY29tbWVudFwiPT1hfHxcInRleHRcIj09YXx8XCJwcm9jZXNzaW5nLWluc3RydWN0aW9uXCI9PWF8fFwibm9kZVwiPT1hfUcucHJvdG90eXBlLmE9ZnVuY3Rpb24oYSl7cmV0dXJuIG51bGw9PT10aGlzLmJ8fHRoaXMuYj09YS5ub2RlVHlwZX07Ry5wcm90b3R5cGUuZj1mdW5jdGlvbigpe3JldHVybiB0aGlzLmh9O1xuRy5wcm90b3R5cGUudG9TdHJpbmc9ZnVuY3Rpb24oKXt2YXIgYT1cIktpbmQgVGVzdDogXCIrdGhpcy5oO251bGw9PT10aGlzLmN8fChhKz1KKHRoaXMuYykpO3JldHVybiBhfTtmdW5jdGlvbiBlYihhKXt0aGlzLmI9YTt0aGlzLmE9MH1mdW5jdGlvbiBmYihhKXthPWEubWF0Y2goZ2IpO2Zvcih2YXIgYj0wO2I8YS5sZW5ndGg7YisrKWhiLnRlc3QoYVtiXSkmJmEuc3BsaWNlKGIsMSk7cmV0dXJuIG5ldyBlYihhKX12YXIgZ2I9L1xcJD8oPzooPyFbMC05LVxcLl0pKD86XFwqfFtcXHctXFwuXSspOik/KD8hWzAtOS1cXC5dKSg/OlxcKnxbXFx3LVxcLl0rKXxcXC9cXC98XFwuXFwufDo6fFxcZCsoPzpcXC5cXGQqKT98XFwuXFxkK3xcIlteXCJdKlwifCdbXiddKid8WyE8Pl09fFxccyt8Li9nLGhiPS9eXFxzLztmdW5jdGlvbiBTKGEsYil7cmV0dXJuIGEuYlthLmErKGJ8fDApXX1mdW5jdGlvbiBUKGEpe3JldHVybiBhLmJbYS5hKytdfWZ1bmN0aW9uIGliKGEpe3JldHVybiBhLmIubGVuZ3RoPD1hLmF9O2Z1bmN0aW9uIGpiKGEpe24uY2FsbCh0aGlzLDMpO3RoaXMuYz1hLnN1YnN0cmluZygxLGEubGVuZ3RoLTEpfW0oamIpO2piLnByb3RvdHlwZS5hPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuY307amIucHJvdG90eXBlLnRvU3RyaW5nPWZ1bmN0aW9uKCl7cmV0dXJuXCJMaXRlcmFsOiBcIit0aGlzLmN9O2Z1bmN0aW9uIEUoYSxiKXt0aGlzLmo9YS50b0xvd2VyQ2FzZSgpO3ZhciBjO2M9XCIqXCI9PXRoaXMuaj9cIipcIjpcImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWxcIjt0aGlzLmM9Yj9iLnRvTG93ZXJDYXNlKCk6Y31FLnByb3RvdHlwZS5hPWZ1bmN0aW9uKGEpe3ZhciBiPWEubm9kZVR5cGU7aWYoMSE9YiYmMiE9YilyZXR1cm4hMTtiPXZvaWQgMCE9PWEubG9jYWxOYW1lP2EubG9jYWxOYW1lOmEubm9kZU5hbWU7cmV0dXJuXCIqXCIhPXRoaXMuaiYmdGhpcy5qIT1iLnRvTG93ZXJDYXNlKCk/ITE6XCIqXCI9PXRoaXMuYz8hMDp0aGlzLmM9PShhLm5hbWVzcGFjZVVSST9hLm5hbWVzcGFjZVVSSS50b0xvd2VyQ2FzZSgpOlwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbFwiKX07RS5wcm90b3R5cGUuZj1mdW5jdGlvbigpe3JldHVybiB0aGlzLmp9O1xuRS5wcm90b3R5cGUudG9TdHJpbmc9ZnVuY3Rpb24oKXtyZXR1cm5cIk5hbWUgVGVzdDogXCIrKFwiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbFwiPT10aGlzLmM/XCJcIjp0aGlzLmMrXCI6XCIpK3RoaXMuan07ZnVuY3Rpb24ga2IoYSxiKXtuLmNhbGwodGhpcyxhLmkpO3RoaXMuaD1hO3RoaXMuYz1iO3RoaXMuZz1hLmc7dGhpcy5iPWEuYjtpZigxPT10aGlzLmMubGVuZ3RoKXt2YXIgYz10aGlzLmNbMF07Yy51fHxjLmMhPWxifHwoYz1jLm8sXCIqXCIhPWMuZigpJiYodGhpcy5mPXtuYW1lOmMuZigpLHM6bnVsbH0pKX19bShrYik7ZnVuY3Rpb24gbWIoKXtuLmNhbGwodGhpcyw0KX1tKG1iKTttYi5wcm90b3R5cGUuYT1mdW5jdGlvbihhKXt2YXIgYj1uZXcgQzthPWEuYTs5PT1hLm5vZGVUeXBlP0YoYixhKTpGKGIsYS5vd25lckRvY3VtZW50KTtyZXR1cm4gYn07bWIucHJvdG90eXBlLnRvU3RyaW5nPWZ1bmN0aW9uKCl7cmV0dXJuXCJSb290IEhlbHBlciBFeHByZXNzaW9uXCJ9O2Z1bmN0aW9uIG5iKCl7bi5jYWxsKHRoaXMsNCl9bShuYik7bmIucHJvdG90eXBlLmE9ZnVuY3Rpb24oYSl7dmFyIGI9bmV3IEM7RihiLGEuYSk7cmV0dXJuIGJ9O25iLnByb3RvdHlwZS50b1N0cmluZz1mdW5jdGlvbigpe3JldHVyblwiQ29udGV4dCBIZWxwZXIgRXhwcmVzc2lvblwifTtcbmZ1bmN0aW9uIG9iKGEpe3JldHVyblwiL1wiPT1hfHxcIi8vXCI9PWF9a2IucHJvdG90eXBlLmE9ZnVuY3Rpb24oYSl7dmFyIGI9dGhpcy5oLmEoYSk7aWYoIShiIGluc3RhbmNlb2YgQykpdGhyb3cgRXJyb3IoXCJGaWx0ZXIgZXhwcmVzc2lvbiBtdXN0IGV2YWx1YXRlIHRvIG5vZGVzZXQuXCIpO2E9dGhpcy5jO2Zvcih2YXIgYz0wLGQ9YS5sZW5ndGg7YzxkJiZiLmw7YysrKXt2YXIgZT1hW2NdLGY9SChiLGUuYy5hKSxnO2lmKGUuZ3x8ZS5jIT1wYilpZihlLmd8fGUuYyE9cWIpZm9yKGc9SShmKSxiPWUuYShuZXcgUShnKSk7bnVsbCE9KGc9SShmKSk7KWc9ZS5hKG5ldyBRKGcpKSxiPVBhKGIsZyk7ZWxzZSBnPUkoZiksYj1lLmEobmV3IFEoZykpO2Vsc2V7Zm9yKGc9SShmKTsoYj1JKGYpKSYmKCFnLmNvbnRhaW5zfHxnLmNvbnRhaW5zKGIpKSYmYi5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbihnKSY4O2c9Yik7Yj1lLmEobmV3IFEoZykpfX1yZXR1cm4gYn07XG5rYi5wcm90b3R5cGUudG9TdHJpbmc9ZnVuY3Rpb24oKXt2YXIgYTthPVwiUGF0aCBFeHByZXNzaW9uOlwiK0oodGhpcy5oKTtpZih0aGlzLmMubGVuZ3RoKXt2YXIgYj10KHRoaXMuYyxmdW5jdGlvbihhLGIpe3JldHVybiBhK0ooYil9LFwiU3RlcHM6XCIpO2ErPUooYil9cmV0dXJuIGF9O2Z1bmN0aW9uIHJiKGEpe24uY2FsbCh0aGlzLDQpO3RoaXMuYz1hO1VhKHRoaXMsamEodGhpcy5jLGZ1bmN0aW9uKGEpe3JldHVybiBhLmd9KSk7VmEodGhpcyxqYSh0aGlzLmMsZnVuY3Rpb24oYSl7cmV0dXJuIGEuYn0pKX1tKHJiKTtyYi5wcm90b3R5cGUuYT1mdW5jdGlvbihhKXt2YXIgYj1uZXcgQztyKHRoaXMuYyxmdW5jdGlvbihjKXtjPWMuYShhKTtpZighKGMgaW5zdGFuY2VvZiBDKSl0aHJvdyBFcnJvcihcIlBhdGggZXhwcmVzc2lvbiBtdXN0IGV2YWx1YXRlIHRvIE5vZGVTZXQuXCIpO2I9UGEoYixjKX0pO3JldHVybiBifTtyYi5wcm90b3R5cGUudG9TdHJpbmc9ZnVuY3Rpb24oKXtyZXR1cm4gdCh0aGlzLmMsZnVuY3Rpb24oYSxiKXtyZXR1cm4gYStKKGIpfSxcIlVuaW9uIEV4cHJlc3Npb246XCIpfTtmdW5jdGlvbiBzYihhLGIpe3RoaXMuYT1hO3RoaXMuYj0hIWJ9XG5mdW5jdGlvbiAkYShhLGIsYyl7Zm9yKGM9Y3x8MDtjPGEuYS5sZW5ndGg7YysrKWZvcih2YXIgZD1hLmFbY10sZT1IKGIpLGY9Yi5sLGcsaD0wO2c9SShlKTtoKyspe3ZhciBwPWEuYj9mLWg6aCsxO2c9ZC5hKG5ldyBRKGcscCxmKSk7aWYoXCJudW1iZXJcIj09dHlwZW9mIGcpcD1wPT1nO2Vsc2UgaWYoXCJzdHJpbmdcIj09dHlwZW9mIGd8fFwiYm9vbGVhblwiPT10eXBlb2YgZylwPSEhZztlbHNlIGlmKGcgaW5zdGFuY2VvZiBDKXA9MDxnLmw7ZWxzZSB0aHJvdyBFcnJvcihcIlByZWRpY2F0ZS5ldmFsdWF0ZSByZXR1cm5lZCBhbiB1bmV4cGVjdGVkIHR5cGUuXCIpO2lmKCFwKXtwPWU7Zz1wLmY7dmFyIHk9cC5hO2lmKCF5KXRocm93IEVycm9yKFwiTmV4dCBtdXN0IGJlIGNhbGxlZCBhdCBsZWFzdCBvbmNlIGJlZm9yZSByZW1vdmUuXCIpO3ZhciBEPXkuYix5PXkuYTtEP0QuYT15OmcuYT15O3k/eS5iPUQ6Zy5iPUQ7Zy5sLS07cC5hPW51bGx9fXJldHVybiBifVxuc2IucHJvdG90eXBlLnRvU3RyaW5nPWZ1bmN0aW9uKCl7cmV0dXJuIHQodGhpcy5hLGZ1bmN0aW9uKGEsYil7cmV0dXJuIGErSihiKX0sXCJQcmVkaWNhdGVzOlwiKX07ZnVuY3Rpb24gVShhLGIsYyxkKXtuLmNhbGwodGhpcyw0KTt0aGlzLmM9YTt0aGlzLm89Yjt0aGlzLmg9Y3x8bmV3IHNiKFtdKTt0aGlzLnU9ISFkO2I9dGhpcy5oO2I9MDxiLmEubGVuZ3RoP2IuYVswXS5mOm51bGw7YS5iJiZiJiYoYT1iLm5hbWUsYT13P2EudG9Mb3dlckNhc2UoKTphLHRoaXMuZj17bmFtZTphLHM6Yi5zfSk7YTp7YT10aGlzLmg7Zm9yKGI9MDtiPGEuYS5sZW5ndGg7YisrKWlmKGM9YS5hW2JdLGMuZ3x8MT09Yy5pfHwwPT1jLmkpe2E9ITA7YnJlYWsgYX1hPSExfXRoaXMuZz1hfW0oVSk7XG5VLnByb3RvdHlwZS5hPWZ1bmN0aW9uKGEpe3ZhciBiPWEuYSxjPW51bGwsYz10aGlzLmYsZD1udWxsLGU9bnVsbCxmPTA7YyYmKGQ9Yy5uYW1lLGU9Yy5zP0woYy5zLGEpOm51bGwsZj0xKTtpZih0aGlzLnUpaWYodGhpcy5nfHx0aGlzLmMhPXRiKWlmKGE9SCgobmV3IFUodWIsbmV3IEcoXCJub2RlXCIpKSkuYShhKSksYj1JKGEpKWZvcihjPXRoaXMubShiLGQsZSxmKTtudWxsIT0oYj1JKGEpKTspYz1QYShjLHRoaXMubShiLGQsZSxmKSk7ZWxzZSBjPW5ldyBDO2Vsc2UgYz1CKHRoaXMubyxiLGQsZSksYz0kYSh0aGlzLmgsYyxmKTtlbHNlIGM9dGhpcy5tKGEuYSxkLGUsZik7cmV0dXJuIGN9O1UucHJvdG90eXBlLm09ZnVuY3Rpb24oYSxiLGMsZCl7YT10aGlzLmMuZih0aGlzLm8sYSxiLGMpO3JldHVybiBhPSRhKHRoaXMuaCxhLGQpfTtcblUucHJvdG90eXBlLnRvU3RyaW5nPWZ1bmN0aW9uKCl7dmFyIGE7YT1cIlN0ZXA6XCIrSihcIk9wZXJhdG9yOiBcIisodGhpcy51P1wiLy9cIjpcIi9cIikpO3RoaXMuYy5qJiYoYSs9SihcIkF4aXM6IFwiK3RoaXMuYykpO2ErPUoodGhpcy5vKTtpZih0aGlzLmguYS5sZW5ndGgpe3ZhciBiPXQodGhpcy5oLmEsZnVuY3Rpb24oYSxiKXtyZXR1cm4gYStKKGIpfSxcIlByZWRpY2F0ZXM6XCIpO2ErPUooYil9cmV0dXJuIGF9O2Z1bmN0aW9uIHZiKGEsYixjLGQpe3RoaXMuaj1hO3RoaXMuZj1iO3RoaXMuYT1jO3RoaXMuYj1kfXZiLnByb3RvdHlwZS50b1N0cmluZz1mdW5jdGlvbigpe3JldHVybiB0aGlzLmp9O3ZhciB3Yj17fTtmdW5jdGlvbiBWKGEsYixjLGQpe2lmKHdiLmhhc093blByb3BlcnR5KGEpKXRocm93IEVycm9yKFwiQXhpcyBhbHJlYWR5IGNyZWF0ZWQ6IFwiK2EpO2I9bmV3IHZiKGEsYixjLCEhZCk7cmV0dXJuIHdiW2FdPWJ9XG5WKFwiYW5jZXN0b3JcIixmdW5jdGlvbihhLGIpe2Zvcih2YXIgYz1uZXcgQyxkPWI7ZD1kLnBhcmVudE5vZGU7KWEuYShkKSYmUWEoYyxkKTtyZXR1cm4gY30sITApO1YoXCJhbmNlc3Rvci1vci1zZWxmXCIsZnVuY3Rpb24oYSxiKXt2YXIgYz1uZXcgQyxkPWI7ZG8gYS5hKGQpJiZRYShjLGQpO3doaWxlKGQ9ZC5wYXJlbnROb2RlKTtyZXR1cm4gY30sITApO1xudmFyIGxiPVYoXCJhdHRyaWJ1dGVcIixmdW5jdGlvbihhLGIpe3ZhciBjPW5ldyBDLGQ9YS5mKCk7aWYoXCJzdHlsZVwiPT1kJiZ3JiZiLnN0eWxlKXJldHVybiBGKGMsbmV3IHgoYi5zdHlsZSxiLFwic3R5bGVcIixiLnN0eWxlLmNzc1RleHQpKSxjO3ZhciBlPWIuYXR0cmlidXRlcztpZihlKWlmKGEgaW5zdGFuY2VvZiBHJiZudWxsPT09YS5ifHxcIipcIj09ZClmb3IodmFyIGQ9MCxmO2Y9ZVtkXTtkKyspdz9mLm5vZGVWYWx1ZSYmRihjLERhKGIsZikpOkYoYyxmKTtlbHNlKGY9ZS5nZXROYW1lZEl0ZW0oZCkpJiYodz9mLm5vZGVWYWx1ZSYmRihjLERhKGIsZikpOkYoYyxmKSk7cmV0dXJuIGN9LCExKSx0Yj1WKFwiY2hpbGRcIixmdW5jdGlvbihhLGIsYyxkLGUpe3JldHVybih3P0lhOkphKS5jYWxsKG51bGwsYSxiLGwoYyk/YzpudWxsLGwoZCk/ZDpudWxsLGV8fG5ldyBDKX0sITEsITApO1YoXCJkZXNjZW5kYW50XCIsQiwhMSwhMCk7XG52YXIgdWI9VihcImRlc2NlbmRhbnQtb3Itc2VsZlwiLGZ1bmN0aW9uKGEsYixjLGQpe3ZhciBlPW5ldyBDO0EoYixjLGQpJiZhLmEoYikmJkYoZSxiKTtyZXR1cm4gQihhLGIsYyxkLGUpfSwhMSwhMCkscGI9VihcImZvbGxvd2luZ1wiLGZ1bmN0aW9uKGEsYixjLGQpe3ZhciBlPW5ldyBDO2RvIGZvcih2YXIgZj1iO2Y9Zi5uZXh0U2libGluZzspQShmLGMsZCkmJmEuYShmKSYmRihlLGYpLGU9QihhLGYsYyxkLGUpO3doaWxlKGI9Yi5wYXJlbnROb2RlKTtyZXR1cm4gZX0sITEsITApO1YoXCJmb2xsb3dpbmctc2libGluZ1wiLGZ1bmN0aW9uKGEsYil7Zm9yKHZhciBjPW5ldyBDLGQ9YjtkPWQubmV4dFNpYmxpbmc7KWEuYShkKSYmRihjLGQpO3JldHVybiBjfSwhMSk7VihcIm5hbWVzcGFjZVwiLGZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBDfSwhMSk7XG52YXIgeGI9VihcInBhcmVudFwiLGZ1bmN0aW9uKGEsYil7dmFyIGM9bmV3IEM7aWYoOT09Yi5ub2RlVHlwZSlyZXR1cm4gYztpZigyPT1iLm5vZGVUeXBlKXJldHVybiBGKGMsYi5vd25lckVsZW1lbnQpLGM7dmFyIGQ9Yi5wYXJlbnROb2RlO2EuYShkKSYmRihjLGQpO3JldHVybiBjfSwhMSkscWI9VihcInByZWNlZGluZ1wiLGZ1bmN0aW9uKGEsYixjLGQpe3ZhciBlPW5ldyBDLGY9W107ZG8gZi51bnNoaWZ0KGIpO3doaWxlKGI9Yi5wYXJlbnROb2RlKTtmb3IodmFyIGc9MSxoPWYubGVuZ3RoO2c8aDtnKyspe3ZhciBwPVtdO2ZvcihiPWZbZ107Yj1iLnByZXZpb3VzU2libGluZzspcC51bnNoaWZ0KGIpO2Zvcih2YXIgeT0wLEQ9cC5sZW5ndGg7eTxEO3krKyliPXBbeV0sQShiLGMsZCkmJmEuYShiKSYmRihlLGIpLGU9QihhLGIsYyxkLGUpfXJldHVybiBlfSwhMCwhMCk7XG5WKFwicHJlY2VkaW5nLXNpYmxpbmdcIixmdW5jdGlvbihhLGIpe2Zvcih2YXIgYz1uZXcgQyxkPWI7ZD1kLnByZXZpb3VzU2libGluZzspYS5hKGQpJiZRYShjLGQpO3JldHVybiBjfSwhMCk7dmFyIHliPVYoXCJzZWxmXCIsZnVuY3Rpb24oYSxiKXt2YXIgYz1uZXcgQzthLmEoYikmJkYoYyxiKTtyZXR1cm4gY30sITEpO2Z1bmN0aW9uIHpiKGEpe24uY2FsbCh0aGlzLDEpO3RoaXMuYz1hO3RoaXMuZz1hLmc7dGhpcy5iPWEuYn1tKHpiKTt6Yi5wcm90b3R5cGUuYT1mdW5jdGlvbihhKXtyZXR1cm4tSyh0aGlzLmMsYSl9O3piLnByb3RvdHlwZS50b1N0cmluZz1mdW5jdGlvbigpe3JldHVyblwiVW5hcnkgRXhwcmVzc2lvbjogLVwiK0oodGhpcy5jKX07ZnVuY3Rpb24gQWIoYSl7bi5jYWxsKHRoaXMsMSk7dGhpcy5jPWF9bShBYik7QWIucHJvdG90eXBlLmE9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5jfTtBYi5wcm90b3R5cGUudG9TdHJpbmc9ZnVuY3Rpb24oKXtyZXR1cm5cIk51bWJlcjogXCIrdGhpcy5jfTtmdW5jdGlvbiBCYihhLGIpe3RoaXMuYT1hO3RoaXMuYj1ifWZ1bmN0aW9uIENiKGEpe2Zvcih2YXIgYixjPVtdOzspe1coYSxcIk1pc3NpbmcgcmlnaHQgaGFuZCBzaWRlIG9mIGJpbmFyeSBleHByZXNzaW9uLlwiKTtiPURiKGEpO3ZhciBkPVQoYS5hKTtpZighZClicmVhazt2YXIgZT0oZD1ZYVtkXXx8bnVsbCkmJmQudztpZighZSl7YS5hLmEtLTticmVha31mb3IoO2MubGVuZ3RoJiZlPD1jW2MubGVuZ3RoLTFdLnc7KWI9bmV3IE4oYy5wb3AoKSxjLnBvcCgpLGIpO2MucHVzaChiLGQpfWZvcig7Yy5sZW5ndGg7KWI9bmV3IE4oYy5wb3AoKSxjLnBvcCgpLGIpO3JldHVybiBifWZ1bmN0aW9uIFcoYSxiKXtpZihpYihhLmEpKXRocm93IEVycm9yKGIpO31mdW5jdGlvbiBFYihhLGIpe3ZhciBjPVQoYS5hKTtpZihjIT1iKXRocm93IEVycm9yKFwiQmFkIHRva2VuLCBleHBlY3RlZDogXCIrYitcIiBnb3Q6IFwiK2MpO31cbmZ1bmN0aW9uIEZiKGEpe2E9VChhLmEpO2lmKFwiKVwiIT1hKXRocm93IEVycm9yKFwiQmFkIHRva2VuOiBcIithKTt9ZnVuY3Rpb24gR2IoYSl7YT1UKGEuYSk7aWYoMj5hLmxlbmd0aCl0aHJvdyBFcnJvcihcIlVuY2xvc2VkIGxpdGVyYWwgc3RyaW5nXCIpO3JldHVybiBuZXcgamIoYSl9XG5mdW5jdGlvbiBIYihhKXt2YXIgYixjPVtdLGQ7aWYob2IoUyhhLmEpKSl7Yj1UKGEuYSk7ZD1TKGEuYSk7aWYoXCIvXCI9PWImJihpYihhLmEpfHxcIi5cIiE9ZCYmXCIuLlwiIT1kJiZcIkBcIiE9ZCYmXCIqXCIhPWQmJiEvKD8hWzAtOV0pW1xcd10vLnRlc3QoZCkpKXJldHVybiBuZXcgbWI7ZD1uZXcgbWI7VyhhLFwiTWlzc2luZyBuZXh0IGxvY2F0aW9uIHN0ZXAuXCIpO2I9SWIoYSxiKTtjLnB1c2goYil9ZWxzZXthOntiPVMoYS5hKTtkPWIuY2hhckF0KDApO3N3aXRjaChkKXtjYXNlIFwiJFwiOnRocm93IEVycm9yKFwiVmFyaWFibGUgcmVmZXJlbmNlIG5vdCBhbGxvd2VkIGluIEhUTUwgWFBhdGhcIik7Y2FzZSBcIihcIjpUKGEuYSk7Yj1DYihhKTtXKGEsJ3VuY2xvc2VkIFwiKFwiJyk7RWIoYSxcIilcIik7YnJlYWs7Y2FzZSAnXCInOmNhc2UgXCInXCI6Yj1HYihhKTticmVhaztkZWZhdWx0OmlmKGlzTmFOKCtiKSlpZighZGIoYikmJi8oPyFbMC05XSlbXFx3XS8udGVzdChkKSYmXCIoXCI9PVMoYS5hLDEpKXtiPVQoYS5hKTtcbmI9Y2JbYl18fG51bGw7VChhLmEpO2ZvcihkPVtdO1wiKVwiIT1TKGEuYSk7KXtXKGEsXCJNaXNzaW5nIGZ1bmN0aW9uIGFyZ3VtZW50IGxpc3QuXCIpO2QucHVzaChDYihhKSk7aWYoXCIsXCIhPVMoYS5hKSlicmVhaztUKGEuYSl9VyhhLFwiVW5jbG9zZWQgZnVuY3Rpb24gYXJndW1lbnQgbGlzdC5cIik7RmIoYSk7Yj1uZXcgYWIoYixkKX1lbHNle2I9bnVsbDticmVhayBhfWVsc2UgYj1uZXcgQWIoK1QoYS5hKSl9XCJbXCI9PVMoYS5hKSYmKGQ9bmV3IHNiKEpiKGEpKSxiPW5ldyBaYShiLGQpKX1pZihiKWlmKG9iKFMoYS5hKSkpZD1iO2Vsc2UgcmV0dXJuIGI7ZWxzZSBiPUliKGEsXCIvXCIpLGQ9bmV3IG5iLGMucHVzaChiKX1mb3IoO29iKFMoYS5hKSk7KWI9VChhLmEpLFcoYSxcIk1pc3NpbmcgbmV4dCBsb2NhdGlvbiBzdGVwLlwiKSxiPUliKGEsYiksYy5wdXNoKGIpO3JldHVybiBuZXcga2IoZCxjKX1cbmZ1bmN0aW9uIEliKGEsYil7dmFyIGMsZCxlO2lmKFwiL1wiIT1iJiZcIi8vXCIhPWIpdGhyb3cgRXJyb3IoJ1N0ZXAgb3Agc2hvdWxkIGJlIFwiL1wiIG9yIFwiLy9cIicpO2lmKFwiLlwiPT1TKGEuYSkpcmV0dXJuIGQ9bmV3IFUoeWIsbmV3IEcoXCJub2RlXCIpKSxUKGEuYSksZDtpZihcIi4uXCI9PVMoYS5hKSlyZXR1cm4gZD1uZXcgVSh4YixuZXcgRyhcIm5vZGVcIikpLFQoYS5hKSxkO3ZhciBmO2lmKFwiQFwiPT1TKGEuYSkpZj1sYixUKGEuYSksVyhhLFwiTWlzc2luZyBhdHRyaWJ1dGUgbmFtZVwiKTtlbHNlIGlmKFwiOjpcIj09UyhhLmEsMSkpe2lmKCEvKD8hWzAtOV0pW1xcd10vLnRlc3QoUyhhLmEpLmNoYXJBdCgwKSkpdGhyb3cgRXJyb3IoXCJCYWQgdG9rZW46IFwiK1QoYS5hKSk7Yz1UKGEuYSk7Zj13YltjXXx8bnVsbDtpZighZil0aHJvdyBFcnJvcihcIk5vIGF4aXMgd2l0aCBuYW1lOiBcIitjKTtUKGEuYSk7VyhhLFwiTWlzc2luZyBub2RlIG5hbWVcIil9ZWxzZSBmPXRiO2M9UyhhLmEpO2lmKC8oPyFbMC05XSlbXFx3XFwqXS8udGVzdChjLmNoYXJBdCgwKSkpaWYoXCIoXCI9PVxuUyhhLmEsMSkpe2lmKCFkYihjKSl0aHJvdyBFcnJvcihcIkludmFsaWQgbm9kZSB0eXBlOiBcIitjKTtjPVQoYS5hKTtpZighZGIoYykpdGhyb3cgRXJyb3IoXCJJbnZhbGlkIHR5cGUgbmFtZTogXCIrYyk7RWIoYSxcIihcIik7VyhhLFwiQmFkIG5vZGV0eXBlXCIpO2U9UyhhLmEpLmNoYXJBdCgwKTt2YXIgZz1udWxsO2lmKCdcIic9PWV8fFwiJ1wiPT1lKWc9R2IoYSk7VyhhLFwiQmFkIG5vZGV0eXBlXCIpO0ZiKGEpO2M9bmV3IEcoYyxnKX1lbHNlIGlmKGM9VChhLmEpLGU9Yy5pbmRleE9mKFwiOlwiKSwtMT09ZSljPW5ldyBFKGMpO2Vsc2V7dmFyIGc9Yy5zdWJzdHJpbmcoMCxlKSxoO2lmKFwiKlwiPT1nKWg9XCIqXCI7ZWxzZSBpZihoPWEuYihnKSwhaCl0aHJvdyBFcnJvcihcIk5hbWVzcGFjZSBwcmVmaXggbm90IGRlY2xhcmVkOiBcIitnKTtjPWMuc3Vic3RyKGUrMSk7Yz1uZXcgRShjLGgpfWVsc2UgdGhyb3cgRXJyb3IoXCJCYWQgdG9rZW46IFwiK1QoYS5hKSk7ZT1uZXcgc2IoSmIoYSksZi5hKTtyZXR1cm4gZHx8XG5uZXcgVShmLGMsZSxcIi8vXCI9PWIpfWZ1bmN0aW9uIEpiKGEpe2Zvcih2YXIgYj1bXTtcIltcIj09UyhhLmEpOyl7VChhLmEpO1coYSxcIk1pc3NpbmcgcHJlZGljYXRlIGV4cHJlc3Npb24uXCIpO3ZhciBjPUNiKGEpO2IucHVzaChjKTtXKGEsXCJVbmNsb3NlZCBwcmVkaWNhdGUgZXhwcmVzc2lvbi5cIik7RWIoYSxcIl1cIil9cmV0dXJuIGJ9ZnVuY3Rpb24gRGIoYSl7aWYoXCItXCI9PVMoYS5hKSlyZXR1cm4gVChhLmEpLG5ldyB6YihEYihhKSk7dmFyIGI9SGIoYSk7aWYoXCJ8XCIhPVMoYS5hKSlhPWI7ZWxzZXtmb3IoYj1bYl07XCJ8XCI9PVQoYS5hKTspVyhhLFwiTWlzc2luZyBuZXh0IHVuaW9uIGxvY2F0aW9uIHBhdGguXCIpLGIucHVzaChIYihhKSk7YS5hLmEtLTthPW5ldyByYihiKX1yZXR1cm4gYX07ZnVuY3Rpb24gS2IoYSl7c3dpdGNoKGEubm9kZVR5cGUpe2Nhc2UgMTpyZXR1cm4gZWEoTGIsYSk7Y2FzZSA5OnJldHVybiBLYihhLmRvY3VtZW50RWxlbWVudCk7Y2FzZSAxMTpjYXNlIDEwOmNhc2UgNjpjYXNlIDEyOnJldHVybiBNYjtkZWZhdWx0OnJldHVybiBhLnBhcmVudE5vZGU/S2IoYS5wYXJlbnROb2RlKTpNYn19ZnVuY3Rpb24gTWIoKXtyZXR1cm4gbnVsbH1mdW5jdGlvbiBMYihhLGIpe2lmKGEucHJlZml4PT1iKXJldHVybiBhLm5hbWVzcGFjZVVSSXx8XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sXCI7dmFyIGM9YS5nZXRBdHRyaWJ1dGVOb2RlKFwieG1sbnM6XCIrYik7cmV0dXJuIGMmJmMuc3BlY2lmaWVkP2MudmFsdWV8fG51bGw6YS5wYXJlbnROb2RlJiY5IT1hLnBhcmVudE5vZGUubm9kZVR5cGU/TGIoYS5wYXJlbnROb2RlLGIpOm51bGx9O2Z1bmN0aW9uIE5iKGEsYil7aWYoIWEubGVuZ3RoKXRocm93IEVycm9yKFwiRW1wdHkgWFBhdGggZXhwcmVzc2lvbi5cIik7dmFyIGM9ZmIoYSk7aWYoaWIoYykpdGhyb3cgRXJyb3IoXCJJbnZhbGlkIFhQYXRoIGV4cHJlc3Npb24uXCIpO2I/XCJmdW5jdGlvblwiPT1hYShiKXx8KGI9ZGEoYi5sb29rdXBOYW1lc3BhY2VVUkksYikpOmI9ZnVuY3Rpb24oKXtyZXR1cm4gbnVsbH07dmFyIGQ9Q2IobmV3IEJiKGMsYikpO2lmKCFpYihjKSl0aHJvdyBFcnJvcihcIkJhZCB0b2tlbjogXCIrVChjKSk7dGhpcy5ldmFsdWF0ZT1mdW5jdGlvbihhLGIpe3ZhciBjPWQuYShuZXcgUShhKSk7cmV0dXJuIG5ldyBZKGMsYil9fVxuZnVuY3Rpb24gWShhLGIpe2lmKDA9PWIpaWYoYSBpbnN0YW5jZW9mIEMpYj00O2Vsc2UgaWYoXCJzdHJpbmdcIj09dHlwZW9mIGEpYj0yO2Vsc2UgaWYoXCJudW1iZXJcIj09dHlwZW9mIGEpYj0xO2Vsc2UgaWYoXCJib29sZWFuXCI9PXR5cGVvZiBhKWI9MztlbHNlIHRocm93IEVycm9yKFwiVW5leHBlY3RlZCBldmFsdWF0aW9uIHJlc3VsdC5cIik7aWYoMiE9YiYmMSE9YiYmMyE9YiYmIShhIGluc3RhbmNlb2YgQykpdGhyb3cgRXJyb3IoXCJ2YWx1ZSBjb3VsZCBub3QgYmUgY29udmVydGVkIHRvIHRoZSBzcGVjaWZpZWQgdHlwZVwiKTt0aGlzLnJlc3VsdFR5cGU9Yjt2YXIgYztzd2l0Y2goYil7Y2FzZSAyOnRoaXMuc3RyaW5nVmFsdWU9YSBpbnN0YW5jZW9mIEM/U2EoYSk6XCJcIithO2JyZWFrO2Nhc2UgMTp0aGlzLm51bWJlclZhbHVlPWEgaW5zdGFuY2VvZiBDPytTYShhKTorYTticmVhaztjYXNlIDM6dGhpcy5ib29sZWFuVmFsdWU9YSBpbnN0YW5jZW9mIEM/MDxhLmw6ISFhO2JyZWFrO2Nhc2UgNDpjYXNlIDU6Y2FzZSA2OmNhc2UgNzp2YXIgZD1cbkgoYSk7Yz1bXTtmb3IodmFyIGU9SShkKTtlO2U9SShkKSljLnB1c2goZSBpbnN0YW5jZW9mIHg/ZS5hOmUpO3RoaXMuc25hcHNob3RMZW5ndGg9YS5sO3RoaXMuaW52YWxpZEl0ZXJhdG9yU3RhdGU9ITE7YnJlYWs7Y2FzZSA4OmNhc2UgOTpkPVJhKGEpO3RoaXMuc2luZ2xlTm9kZVZhbHVlPWQgaW5zdGFuY2VvZiB4P2QuYTpkO2JyZWFrO2RlZmF1bHQ6dGhyb3cgRXJyb3IoXCJVbmtub3duIFhQYXRoUmVzdWx0IHR5cGUuXCIpO312YXIgZj0wO3RoaXMuaXRlcmF0ZU5leHQ9ZnVuY3Rpb24oKXtpZig0IT1iJiY1IT1iKXRocm93IEVycm9yKFwiaXRlcmF0ZU5leHQgY2FsbGVkIHdpdGggd3JvbmcgcmVzdWx0IHR5cGVcIik7cmV0dXJuIGY+PWMubGVuZ3RoP251bGw6Y1tmKytdfTt0aGlzLnNuYXBzaG90SXRlbT1mdW5jdGlvbihhKXtpZig2IT1iJiY3IT1iKXRocm93IEVycm9yKFwic25hcHNob3RJdGVtIGNhbGxlZCB3aXRoIHdyb25nIHJlc3VsdCB0eXBlXCIpO3JldHVybiBhPj1jLmxlbmd0aHx8XG4wPmE/bnVsbDpjW2FdfX1ZLkFOWV9UWVBFPTA7WS5OVU1CRVJfVFlQRT0xO1kuU1RSSU5HX1RZUEU9MjtZLkJPT0xFQU5fVFlQRT0zO1kuVU5PUkRFUkVEX05PREVfSVRFUkFUT1JfVFlQRT00O1kuT1JERVJFRF9OT0RFX0lURVJBVE9SX1RZUEU9NTtZLlVOT1JERVJFRF9OT0RFX1NOQVBTSE9UX1RZUEU9NjtZLk9SREVSRURfTk9ERV9TTkFQU0hPVF9UWVBFPTc7WS5BTllfVU5PUkRFUkVEX05PREVfVFlQRT04O1kuRklSU1RfT1JERVJFRF9OT0RFX1RZUEU9OTtmdW5jdGlvbiBPYihhKXt0aGlzLmxvb2t1cE5hbWVzcGFjZVVSST1LYihhKX1cbmZ1bmN0aW9uIFBiKGEsYil7dmFyIGM9YXx8ayxkPWMuRG9jdW1lbnQmJmMuRG9jdW1lbnQucHJvdG90eXBlfHxjLmRvY3VtZW50O2lmKCFkLmV2YWx1YXRlfHxiKWMuWFBhdGhSZXN1bHQ9WSxkLmV2YWx1YXRlPWZ1bmN0aW9uKGEsYixjLGQpe3JldHVybihuZXcgTmIoYSxjKSkuZXZhbHVhdGUoYixkKX0sZC5jcmVhdGVFeHByZXNzaW9uPWZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBOYihhLGIpfSxkLmNyZWF0ZU5TUmVzb2x2ZXI9ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBPYihhKX19dmFyIFFiPVtcIndneHBhdGhcIixcImluc3RhbGxcIl0sWj1rO1FiWzBdaW4gWnx8IVouZXhlY1NjcmlwdHx8Wi5leGVjU2NyaXB0KFwidmFyIFwiK1FiWzBdKTtmb3IodmFyIFJiO1FiLmxlbmd0aCYmKFJiPVFiLnNoaWZ0KCkpOylRYi5sZW5ndGh8fHZvaWQgMD09PVBiP1pbUmJdP1o9WltSYl06Wj1aW1JiXT17fTpaW1JiXT1QYjttb2R1bGUuZXhwb3J0cy5pbnN0YWxsPVBiO21vZHVsZS5leHBvcnRzLlhQYXRoUmVzdWx0VHlwZT17QU5ZX1RZUEU6MCxOVU1CRVJfVFlQRToxLFNUUklOR19UWVBFOjIsQk9PTEVBTl9UWVBFOjMsVU5PUkRFUkVEX05PREVfSVRFUkFUT1JfVFlQRTo0LE9SREVSRURfTk9ERV9JVEVSQVRPUl9UWVBFOjUsVU5PUkRFUkVEX05PREVfU05BUFNIT1RfVFlQRTo2LE9SREVSRURfTk9ERV9TTkFQU0hPVF9UWVBFOjcsQU5ZX1VOT1JERVJFRF9OT0RFX1RZUEU6OCxGSVJTVF9PUkRFUkVEX05PREVfVFlQRTo5fTt9KS5jYWxsKGdsb2JhbClcbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDE3IENoYXJsZXMgZHUgSmV1IC0gQWJzdHJpdW0gU0FTIDx0ZWFtIChhdCkgcHlkLmlvPlxuICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgUHlkaW8uXG4gKlxuICogUHlkaW8gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBQeWRpbyBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCBQeWRpby4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAqXG4gKiBUaGUgbGF0ZXN0IGNvZGUgY2FuIGJlIGZvdW5kIGF0IDxodHRwczovL3B5ZGlvLmNvbT4uXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbicpOyB9IH1cblxudmFyIGRvY1JlYWR5ID0gcmVxdWlyZSgnZG9jLXJlYWR5Jyk7XG52YXIgQ29ubmV4aW9uID0gcmVxdWlyZSgnLi9odHRwL0Nvbm5leGlvbicpO1xuLyoqXG4gKiBNYWluIEJvb3RMb2FkZXIuXG4gKiBEZWZhdWx0cyBwYXJhbXMgZm9yIGNvbnN0cnVjdG9yIHNob3VsZCBiZSB7fSBhbmQgY29udGVudC5waHA/Z2V0X2FjdGlvbj1nZXRfYm9vdF9jb25mXG4gKi9cblxudmFyIFB5ZGlvQm9vdHN0cmFwID0gKGZ1bmN0aW9uICgpIHtcblxuICAgIC8qKlxuICAgICAqIENvbnN0cnVjdG9yXG4gICAgICogQHBhcmFtIHN0YXJ0UGFyYW1ldGVycyBPYmplY3QgVGhlIG9wdGlvbnNcbiAgICAgKi9cblxuICAgIGZ1bmN0aW9uIFB5ZGlvQm9vdHN0cmFwKHN0YXJ0UGFyYW1ldGVycykge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuXG4gICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBQeWRpb0Jvb3RzdHJhcCk7XG5cbiAgICAgICAgdGhpcy5wYXJhbWV0ZXJzID0gbmV3IE1hcCgpO1xuICAgICAgICBmb3IgKHZhciBpIGluIHN0YXJ0UGFyYW1ldGVycykge1xuICAgICAgICAgICAgaWYgKHN0YXJ0UGFyYW1ldGVycy5oYXNPd25Qcm9wZXJ0eShpKSkge1xuICAgICAgICAgICAgICAgIHRoaXMucGFyYW1ldGVycy5zZXQoaSwgc3RhcnRQYXJhbWV0ZXJzW2ldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLmRldGVjdEJhc2VQYXJhbWV0ZXJzKCk7XG5cbiAgICAgICAgaWYgKHRoaXMucGFyYW1ldGVycy5nZXQoXCJBTEVSVFwiKSkge1xuICAgICAgICAgICAgd2luZG93LnNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHdpbmRvdy5hbGVydChfdGhpcy5wYXJhbWV0ZXJzLmdldChcIkFMRVJUXCIpKTtcbiAgICAgICAgICAgIH0sIDApO1xuICAgICAgICB9XG5cbiAgICAgICAgZG9jUmVhZHkoKGZ1bmN0aW9uICgpIHtcblxuICAgICAgICAgICAgdmFyIHN0YXJ0ZWRGcm9tT3BlbmVyID0gZmFsc2U7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmICh3aW5kb3cub3BlbmVyICYmIHdpbmRvdy5vcGVuZXIucHlkaW9Cb290c3RyYXAgJiYgdGhpcy5wYXJhbWV0ZXJzLmdldCgnc2VydmVyQWNjZXNzUGF0aCcpID09PSB3aW5kb3cub3BlbmVyLnB5ZGlvQm9vdHN0cmFwLnBhcmFtZXRlcnMuZ2V0KCdzZXJ2ZXJBY2Nlc3NQYXRoJykpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wYXJhbWV0ZXJzID0gd2luZG93Lm9wZW5lci5weWRpb0Jvb3RzdHJhcC5wYXJhbWV0ZXJzO1xuICAgICAgICAgICAgICAgICAgICAvLyBIYW5kbGUgcXVlcnlTdHJpbmcgY2FzZSwgYXMgaXQncyBub3QgcGFzc2VkIHZpYSBnZXRfYm9vdF9jb25mXG4gICAgICAgICAgICAgICAgICAgIHZhciBxUGFyYW1zID0gZG9jdW1lbnQubG9jYXRpb24uaHJlZi50b1F1ZXJ5UGFyYW1zKCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChxUGFyYW1zWydleHRlcm5hbF9zZWxlY3Rvcl90eXBlJ10pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGFyYW1ldGVycy5zZXQoJ1NFTEVDVE9SX0RBVEEnLCB7IHR5cGU6IHFQYXJhbXNbJ2V4dGVybmFsX3NlbGVjdG9yX3R5cGUnXSwgZGF0YTogcVBhcmFtcyB9KTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnBhcmFtZXRlcnMuZ2V0KCdTRUxFQ1RPUl9EQVRBJykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnBhcmFtZXRlcnMudW5zZXQoJ1NFTEVDVE9SX0RBVEEnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB0aGlzLnJlZnJlc2hDb250ZXh0VmFyaWFibGVzQW5kSW5pdChuZXcgQ29ubmV4aW9uKCkpO1xuICAgICAgICAgICAgICAgICAgICBzdGFydGVkRnJvbU9wZW5lciA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIGlmICh3aW5kb3cuY29uc29sZSAmJiBjb25zb2xlLmxvZykgY29uc29sZS5sb2coZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIXN0YXJ0ZWRGcm9tT3BlbmVyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5sb2FkQm9vdENvbmZpZygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KS5iaW5kKHRoaXMpKTtcblxuICAgICAgICB3aW5kb3cuQ29ubmV4aW9uID0gQ29ubmV4aW9uO1xuICAgICAgICB3aW5kb3cucHlkaW9Cb290c3RyYXAgPSB0aGlzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlYWwgbG9hZGluZyBhY3Rpb25cbiAgICAgKi9cblxuICAgIFB5ZGlvQm9vdHN0cmFwLnByb3RvdHlwZS5sb2FkQm9vdENvbmZpZyA9IGZ1bmN0aW9uIGxvYWRCb290Q29uZmlnKCkge1xuICAgICAgICBpZiAodGhpcy5wYXJhbWV0ZXJzLmdldCgnUFJFTE9BREVEX0JPT1RfQ09ORicpKSB7XG4gICAgICAgICAgICB2YXIgcHJlbG9hZGVkID0gdGhpcy5wYXJhbWV0ZXJzLmdldCgnUFJFTE9BREVEX0JPT1RfQ09ORicpO1xuICAgICAgICAgICAgZm9yICh2YXIgayBpbiBwcmVsb2FkZWQpIHtcbiAgICAgICAgICAgICAgICBpZiAocHJlbG9hZGVkLmhhc093blByb3BlcnR5KGspKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGFyYW1ldGVycy5zZXQoaywgcHJlbG9hZGVkW2tdKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnJlZnJlc2hDb250ZXh0VmFyaWFibGVzQW5kSW5pdChuZXcgQ29ubmV4aW9uKCkpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHVybCA9IHRoaXMucGFyYW1ldGVycy5nZXQoJ0JPT1RFUl9VUkwnKSArICh0aGlzLnBhcmFtZXRlcnMuZ2V0KFwiZGVidWdNb2RlXCIpID8gJyZkZWJ1Zz10cnVlJyA6ICcnKTtcbiAgICAgICAgaWYgKHRoaXMucGFyYW1ldGVycy5nZXQoJ1NFUlZFUl9QUkVGSVhfVVJJJykpIHtcbiAgICAgICAgICAgIHVybCArPSAnJnNlcnZlcl9wcmVmaXhfdXJpPScgKyB0aGlzLnBhcmFtZXRlcnMuZ2V0KCdTRVJWRVJfUFJFRklYX1VSSScpLnJlcGxhY2UoL1xcLlxcLlxcLy9nLCBcIl9VUF8vXCIpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBjb25uZXhpb24gPSBuZXcgQ29ubmV4aW9uKHVybCk7XG4gICAgICAgIGNvbm5leGlvbi5vbkNvbXBsZXRlID0gKGZ1bmN0aW9uICh0cmFuc3BvcnQpIHtcbiAgICAgICAgICAgIGlmICh0cmFuc3BvcnQucmVzcG9uc2VYTUwgJiYgdHJhbnNwb3J0LnJlc3BvbnNlWE1MLmRvY3VtZW50RWxlbWVudCAmJiB0cmFuc3BvcnQucmVzcG9uc2VYTUwuZG9jdW1lbnRFbGVtZW50Lm5vZGVOYW1lID09IFwidHJlZVwiKSB7XG4gICAgICAgICAgICAgICAgdmFyIGFsZXJ0ID0gWE1MVXRpbHMuWFBhdGhTZWxlY3RTaW5nbGVOb2RlKHRyYW5zcG9ydC5yZXNwb25zZVhNTC5kb2N1bWVudEVsZW1lbnQsIFwibWVzc2FnZVwiKTtcbiAgICAgICAgICAgICAgICB3aW5kb3cuYWxlcnQoJ0V4Y2VwdGlvbiBjYXVnaHQgYnkgYXBwbGljYXRpb24gOiAnICsgYWxlcnQuZmlyc3RDaGlsZC5ub2RlVmFsdWUpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBwaHBFcnJvcjtcbiAgICAgICAgICAgIHZhciBkYXRhID0gdW5kZWZpbmVkO1xuICAgICAgICAgICAgaWYgKHRyYW5zcG9ydC5yZXNwb25zZUpTT04pIHtcbiAgICAgICAgICAgICAgICBkYXRhID0gdHJhbnNwb3J0LnJlc3BvbnNlSlNPTjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghIHR5cGVvZiBkYXRhID09PSBcIm9iamVjdFwiKSB7XG4gICAgICAgICAgICAgICAgcGhwRXJyb3IgPSAnRXhjZXB0aW9uIHVuY2F1Z2h0IGJ5IGFwcGxpY2F0aW9uIDogJyArIHRyYW5zcG9ydC5yZXNwb25zZVRleHQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAocGhwRXJyb3IpIHtcbiAgICAgICAgICAgICAgICBkb2N1bWVudC53cml0ZShwaHBFcnJvcik7XG4gICAgICAgICAgICAgICAgaWYgKHBocEVycm9yLmluZGV4T2YoJzxiPk5vdGljZTwvYj4nKSA+IC0xIHx8IHBocEVycm9yLmluZGV4T2YoJzxiPlN0cmljdCBTdGFuZGFyZHM8L2I+JykgPiAtMSkge1xuICAgICAgICAgICAgICAgICAgICB3aW5kb3cuYWxlcnQoJ1BocCBlcnJvcnMgZGV0ZWN0ZWQsIGl0IHNlZW1zIHRoYXQgTm90aWNlIG9yIFN0cmljdCBhcmUgZGV0ZWN0ZWQsIHlvdSBtYXkgY29uc2lkZXIgY2hhbmdpbmcgdGhlIFBIUCBFcnJvciBSZXBvcnRpbmcgbGV2ZWwhJyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvciAodmFyIGtleSBpbiBkYXRhKSB7XG4gICAgICAgICAgICAgICAgaWYgKGRhdGEuaGFzT3duUHJvcGVydHkoa2V5KSkgdGhpcy5wYXJhbWV0ZXJzLnNldChrZXksIGRhdGFba2V5XSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMucmVmcmVzaENvbnRleHRWYXJpYWJsZXNBbmRJbml0KGNvbm5leGlvbik7XG4gICAgICAgIH0pLmJpbmQodGhpcyk7XG4gICAgICAgIGNvbm5leGlvbi5zZW5kQXN5bmMoKTtcbiAgICB9O1xuXG4gICAgUHlkaW9Cb290c3RyYXAucHJvdG90eXBlLnJlZnJlc2hDb250ZXh0VmFyaWFibGVzQW5kSW5pdCA9IGZ1bmN0aW9uIHJlZnJlc2hDb250ZXh0VmFyaWFibGVzQW5kSW5pdChjb25uZXhpb24pIHtcblxuICAgICAgICBDb25uZXhpb24udXBkYXRlU2VydmVyQWNjZXNzKHRoaXMucGFyYW1ldGVycyk7XG5cbiAgICAgICAgdmFyIGNzc1JlcyA9IHRoaXMucGFyYW1ldGVycy5nZXQoXCJjc3NSZXNvdXJjZXNcIik7XG4gICAgICAgIGlmIChjc3NSZXMpIGNzc1Jlcy5tYXAodGhpcy5sb2FkQ1NTUmVzb3VyY2UuYmluZCh0aGlzKSk7XG5cbiAgICAgICAgaWYgKHRoaXMucGFyYW1ldGVycy5nZXQoJ2FqeHBSZXNvdXJjZXNGb2xkZXInKSkge1xuICAgICAgICAgICAgY29ubmV4aW9uLl9saWJVcmwgPSB0aGlzLnBhcmFtZXRlcnMuZ2V0KCdhanhwUmVzb3VyY2VzRm9sZGVyJykgKyBcIi9idWlsZFwiO1xuICAgICAgICAgICAgd2luZG93LmFqeHBSZXNvdXJjZXNGb2xkZXIgPSB0aGlzLnBhcmFtZXRlcnMuZ2V0KCdhanhwUmVzb3VyY2VzRm9sZGVyJykgKyBcIi90aGVtZXMvXCIgKyB0aGlzLnBhcmFtZXRlcnMuZ2V0KFwidGhlbWVcIik7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5wYXJhbWV0ZXJzLmdldCgnYWRkaXRpb25hbF9qc19yZXNvdXJjZScpKSB7XG4gICAgICAgICAgICBjb25uZXhpb24ubG9hZExpYnJhcnkodGhpcy5wYXJhbWV0ZXJzLmdldCgnYWRkaXRpb25hbF9qc19yZXNvdXJjZT92PScgKyB0aGlzLnBhcmFtZXRlcnMuZ2V0KFwiYWp4cFZlcnNpb25cIikpLCBudWxsLCB0cnVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vdGhpcy5pbnNlcnRMb2FkZXJQcm9ncmVzcygpO1xuICAgICAgICB3aW5kb3cuTWVzc2FnZUhhc2ggPSB0aGlzLnBhcmFtZXRlcnMuZ2V0KFwiaTE4bk1lc3NhZ2VzXCIpO1xuICAgICAgICBpZiAoIU9iamVjdC5rZXlzKE1lc3NhZ2VIYXNoKS5sZW5ndGgpIHtcbiAgICAgICAgICAgIGFsZXJ0KCdPb3VwcywgdGhpcyBzaG91bGQgbm90IGhhcHBlbiwgeW91ciBtZXNzYWdlIGZpbGUgaXMgZW1wdHkhJyk7XG4gICAgICAgIH1cbiAgICAgICAgZm9yICh2YXIga2V5IGluIE1lc3NhZ2VIYXNoKSB7XG4gICAgICAgICAgICBNZXNzYWdlSGFzaFtrZXldID0gTWVzc2FnZUhhc2hba2V5XS5yZXBsYWNlKFwiXFxcXG5cIiwgXCJcXG5cIik7XG4gICAgICAgIH1cbiAgICAgICAgd2luZG93LnppcEVuYWJsZWQgPSB0aGlzLnBhcmFtZXRlcnMuZ2V0KFwiemlwRW5hYmxlZFwiKTtcbiAgICAgICAgd2luZG93Lm11bHRpcGxlRmlsZXNEb3dubG9hZEVuYWJsZWQgPSB0aGlzLnBhcmFtZXRlcnMuZ2V0KFwibXVsdGlwbGVGaWxlc0Rvd25sb2FkRW5hYmxlZFwiKTtcblxuICAgICAgICB2YXIgbWFzdGVyQ2xhc3NMb2FkZWQgPSAoZnVuY3Rpb24gKCkge1xuXG4gICAgICAgICAgICB2YXIgcHlkaW8gPSBuZXcgUHlkaW8odGhpcy5wYXJhbWV0ZXJzKTtcbiAgICAgICAgICAgIHdpbmRvdy5weWRpbyA9IHdpbmRvdy5hamF4cGxvcmVyID0gcHlkaW87XG5cbiAgICAgICAgICAgIHB5ZGlvLm9ic2VydmUoXCJhY3Rpb25zX2xvYWRlZFwiLCAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGlmICghdGhpcy5wYXJhbWV0ZXJzLmdldChcIlNFTEVDVE9SX0RBVEFcIikgJiYgcHlkaW8uZ2V0Q29udHJvbGxlcigpLmFjdGlvbnMuZ2V0KFwiZXh0X3NlbGVjdFwiKSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAocHlkaW8uZ2V0Q29udHJvbGxlcigpLmFjdGlvbnMuX29iamVjdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcHlkaW8uZ2V0Q29udHJvbGxlcigpLmFjdGlvbnMudW5zZXQoXCJleHRfc2VsZWN0XCIpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcHlkaW8uZ2V0Q29udHJvbGxlcigpLmFjdGlvbnNbJ2RlbGV0ZSddKFwiZXh0X3NlbGVjdFwiKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBweWRpby5nZXRDb250cm9sbGVyKCkuZmlyZUNvbnRleHRDaGFuZ2UoKTtcbiAgICAgICAgICAgICAgICAgICAgcHlkaW8uZ2V0Q29udHJvbGxlcigpLmZpcmVTZWxlY3Rpb25DaGFuZ2UoKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMucGFyYW1ldGVycy5nZXQoXCJTRUxFQ1RPUl9EQVRBXCIpKSB7XG4gICAgICAgICAgICAgICAgICAgIHB5ZGlvLmdldENvbnRyb2xsZXIoKS5kZWZhdWx0QWN0aW9ucy5zZXQoXCJmaWxlXCIsIFwiZXh0X3NlbGVjdFwiKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KS5iaW5kKHRoaXMpKTtcblxuICAgICAgICAgICAgcHlkaW8ub2JzZXJ2ZShcImxvYWRlZFwiLCAoZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5wYXJhbWV0ZXJzLmdldChcIlNFTEVDVE9SX0RBVEFcIikpIHtcbiAgICAgICAgICAgICAgICAgICAgcHlkaW8uZ2V0Q29udHJvbGxlcigpLmRlZmF1bHRBY3Rpb25zLnNldChcImZpbGVcIiwgXCJleHRfc2VsZWN0XCIpO1xuICAgICAgICAgICAgICAgICAgICBweWRpby5nZXRDb250cm9sbGVyKCkuc2VsZWN0b3JEYXRhID0gdGhpcy5wYXJhbWV0ZXJzLmdldChcIlNFTEVDVE9SX0RBVEFcIik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSkuYmluZCh0aGlzKSk7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLnBhcmFtZXRlcnMuZ2V0KFwiY3VycmVudExhbmd1YWdlXCIpKSB7XG4gICAgICAgICAgICAgICAgcHlkaW8uY3VycmVudExhbmd1YWdlID0gdGhpcy5wYXJhbWV0ZXJzLmdldChcImN1cnJlbnRMYW5ndWFnZVwiKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcHlkaW8uaW5pdCgpO1xuICAgICAgICB9KS5iaW5kKHRoaXMpO1xuXG4gICAgICAgIGlmICghdGhpcy5wYXJhbWV0ZXJzLmdldChcImRlYnVnTW9kZVwiKSkge1xuICAgICAgICAgICAgY29ubmV4aW9uLmxvYWRMaWJyYXJ5KFwicHlkaW8ubWluLmpzP3Y9XCIgKyB0aGlzLnBhcmFtZXRlcnMuZ2V0KFwiYWp4cFZlcnNpb25cIiksIG1hc3RlckNsYXNzTG9hZGVkLCB0cnVlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG1hc3RlckNsYXNzTG9hZGVkKCk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgICAgIGRpdi5zZXRBdHRyaWJ1dGUoJ3N0eWxlJywgJ3Bvc2l0aW9uOmFic29sdXRlOyBib3R0b206IDA7IHJpZ2h0OiAwOyB6LWluZGV4OiAyMDAwOyBjb2xvcjpyZ2JhKDAsMCwwLDAuNik7IGZvbnQtc2l6ZTogMTJweDsgcGFkZGluZzogMCAxMHB4OycpO1xuICAgICAgICBkaXYuaW5uZXJIVE1MID0gJ1B5ZGlvIENvbW11bml0eSBFZGl0aW9uIC0gQ29weXJpZ2h0IEFic3RyaXVtIDIwMTcgLSBMZWFybiBtb3JlIG9uIDxhIGhyZWY9XCJodHRwczovL3B5ZGlvLmNvbVwiIHRhcmdldD1cIl9ibGFua1wiPnB5ZGlvLmNvbTwvYT4nO1xuICAgICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGRpdik7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIERldGVjdCB0aGUgYmFzZSBwYXRoIG9mIHRoZSBqYXZhc2NyaXB0cyBiYXNlZCBvbiB0aGUgc2NyaXB0IHRhZ3NcbiAgICAgKi9cblxuICAgIFB5ZGlvQm9vdHN0cmFwLnByb3RvdHlwZS5kZXRlY3RCYXNlUGFyYW1ldGVycyA9IGZ1bmN0aW9uIGRldGVjdEJhc2VQYXJhbWV0ZXJzKCkge1xuXG4gICAgICAgIHZhciBzY3JpcHRzID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ3NjcmlwdCcpO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNjcmlwdHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBzY3JpcHRUYWcgPSBzY3JpcHRzW2ldO1xuICAgICAgICAgICAgaWYgKHNjcmlwdFRhZy5zcmMubWF0Y2goXCIvYnVpbGQvcHlkaW8uYm9vdC5taW4uanNcIikgfHwgc2NyaXB0VGFnLnNyYy5tYXRjaChcIi9idWlsZC9ib290LnByb2QuanNcIikpIHtcbiAgICAgICAgICAgICAgICBpZiAoc2NyaXB0VGFnLnNyYy5tYXRjaChcIi9idWlsZC9weWRpby5ib290Lm1pbi5qc1wiKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnBhcmFtZXRlcnMuc2V0KFwiZGVidWdNb2RlXCIsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnBhcmFtZXRlcnMuc2V0KFwiZGVidWdNb2RlXCIsIHRydWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB2YXIgc3JjID0gc2NyaXB0VGFnLnNyYy5yZXBsYWNlKCcvYnVpbGQvYm9vdC5wcm9kLmpzJywgJycpLnJlcGxhY2UoJy9idWlsZC9weWRpby5ib290Lm1pbi5qcycsICcnKTtcbiAgICAgICAgICAgICAgICBpZiAoc3JjLmluZGV4T2YoXCI/XCIpICE9IC0xKSBzcmMgPSBzcmMuc3BsaXQoXCI/XCIpWzBdO1xuICAgICAgICAgICAgICAgIHRoaXMucGFyYW1ldGVycy5zZXQoXCJhanhwUmVzb3VyY2VzRm9sZGVyXCIsIHNyYyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMucGFyYW1ldGVycy5nZXQoXCJhanhwUmVzb3VyY2VzRm9sZGVyXCIpKSB7XG4gICAgICAgICAgICB3aW5kb3cuYWp4cFJlc291cmNlc0ZvbGRlciA9IHRoaXMucGFyYW1ldGVycy5nZXQoXCJhanhwUmVzb3VyY2VzRm9sZGVyXCIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYWxlcnQoXCJDYW5ub3QgZmluZCByZXNvdXJjZSBmb2xkZXJcIik7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGJvb3RlclVybCA9IHRoaXMucGFyYW1ldGVycy5nZXQoXCJCT09URVJfVVJMXCIpO1xuICAgICAgICBpZiAoYm9vdGVyVXJsLmluZGV4T2YoXCI/XCIpID4gLTEpIHtcbiAgICAgICAgICAgIGJvb3RlclVybCA9IGJvb3RlclVybC5zdWJzdHJpbmcoMCwgYm9vdGVyVXJsLmluZGV4T2YoXCI/XCIpKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnBhcmFtZXRlcnMuc2V0KCdhanhwU2VydmVyQWNjZXNzUGF0aCcsIGJvb3RlclVybCk7XG4gICAgICAgIHRoaXMucGFyYW1ldGVycy5zZXQoJ3NlcnZlckFjY2Vzc1BhdGgnLCBib290ZXJVcmwpO1xuICAgICAgICB3aW5kb3cuYWp4cFNlcnZlckFjY2Vzc1BhdGggPSBib290ZXJVcmw7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIExvYWRzIGEgQ1NTIGZpbGVcbiAgICAgKiBAcGFyYW0gZmlsZU5hbWUgU3RyaW5nXG4gICAgICovXG5cbiAgICBQeWRpb0Jvb3RzdHJhcC5wcm90b3R5cGUubG9hZENTU1Jlc291cmNlID0gZnVuY3Rpb24gbG9hZENTU1Jlc291cmNlKGZpbGVOYW1lKSB7XG4gICAgICAgIHZhciBoZWFkID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2hlYWQnKVswXTtcbiAgICAgICAgdmFyIGNzc05vZGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdsaW5rJyk7XG4gICAgICAgIGNzc05vZGUudHlwZSA9ICd0ZXh0L2Nzcyc7XG4gICAgICAgIGNzc05vZGUucmVsID0gJ3N0eWxlc2hlZXQnO1xuICAgICAgICBjc3NOb2RlLmhyZWYgPSB0aGlzLnBhcmFtZXRlcnMuZ2V0KFwiYWp4cFJlc291cmNlc0ZvbGRlclwiKSArICcvJyArIGZpbGVOYW1lO1xuICAgICAgICBjc3NOb2RlLm1lZGlhID0gJ3NjcmVlbic7XG4gICAgICAgIGhlYWQuYXBwZW5kQ2hpbGQoY3NzTm9kZSk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFRyeSB0byBsb2FkIHNvbWV0aGluZyB1bmRlciBkYXRhL2NhY2hlL1xuICAgICAqIEBwYXJhbSBvbkVycm9yIEZ1bmN0aW9uXG4gICAgICovXG5cbiAgICBQeWRpb0Jvb3RzdHJhcC50ZXN0RGF0YUZvbGRlckFjY2VzcyA9IGZ1bmN0aW9uIHRlc3REYXRhRm9sZGVyQWNjZXNzKG9uRXJyb3IpIHtcbiAgICAgICAgdmFyIGMgPSBuZXcgQ29ubmV4aW9uKCdkYXRhL2NhY2hlL2luZGV4Lmh0bWwnKTtcbiAgICAgICAgYy5zZXRNZXRob2QoJ2dldCcpO1xuICAgICAgICBjLm9uQ29tcGxldGUgPSBmdW5jdGlvbiAocmVzcG9uc2UpIHtcbiAgICAgICAgICAgIGlmICgyMDAgPT09IHJlc3BvbnNlLnN0YXR1cykge1xuICAgICAgICAgICAgICAgIG9uRXJyb3IoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgYy5zZW5kQXN5bmMoKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIFB5ZGlvQm9vdHN0cmFwO1xufSkoKTtcblxuZXhwb3J0c1snZGVmYXVsdCddID0gUHlkaW9Cb290c3RyYXA7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTtcbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDE3IENoYXJsZXMgZHUgSmV1IC0gQWJzdHJpdW0gU0FTIDx0ZWFtIChhdCkgcHlkLmlvPlxuICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgUHlkaW8uXG4gKlxuICogUHlkaW8gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBQeWRpbyBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBBZmZlcm8gR2VuZXJhbCBQdWJsaWMgTGljZW5zZVxuICogYWxvbmcgd2l0aCBQeWRpby4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAqXG4gKiBUaGUgbGF0ZXN0IGNvZGUgY2FuIGJlIGZvdW5kIGF0IDxodHRwczovL3B5ZGlvLmNvbT4uXG4gKi9cblxuJ3VzZSBzdHJpY3QnO1xuXG5leHBvcnRzLl9fZXNNb2R1bGUgPSB0cnVlO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyAnZGVmYXVsdCc6IG9iaiB9OyB9XG5cbmZ1bmN0aW9uIF9jbGFzc0NhbGxDaGVjayhpbnN0YW5jZSwgQ29uc3RydWN0b3IpIHsgaWYgKCEoaW5zdGFuY2UgaW5zdGFuY2VvZiBDb25zdHJ1Y3RvcikpIHsgdGhyb3cgbmV3IFR5cGVFcnJvcignQ2Fubm90IGNhbGwgYSBjbGFzcyBhcyBhIGZ1bmN0aW9uJyk7IH0gfVxuXG52YXIgX3V0aWxYTUxVdGlscyA9IHJlcXVpcmUoJy4uL3V0aWwvWE1MVXRpbHMnKTtcblxudmFyIF91dGlsWE1MVXRpbHMyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfdXRpbFhNTFV0aWxzKTtcblxuLyoqXG4gKiBQeWRpbyBlbmNhcHN1bGF0aW9uIG9mIFhIUiAvIEZldGNoXG4gKi9cbnJlcXVpcmUoJ3doYXR3Zy1mZXRjaCcpO1xuXG52YXIgQ29ubmV4aW9uID0gKGZ1bmN0aW9uICgpIHtcblxuICAgIC8qKlxuICAgICAqIENvbnN0cnVjdG9yXG4gICAgICogQHBhcmFtIGJhc2VVcmwgU3RyaW5nIFRoZSBiYXNlIHVybCBmb3Igc2VydmljZXNcbiAgICAgKi9cblxuICAgIGZ1bmN0aW9uIENvbm5leGlvbihiYXNlVXJsKSB7XG4gICAgICAgIF9jbGFzc0NhbGxDaGVjayh0aGlzLCBDb25uZXhpb24pO1xuXG4gICAgICAgIHRoaXMuX3B5ZGlvID0gd2luZG93LnB5ZGlvO1xuICAgICAgICB0aGlzLl9iYXNlVXJsID0gYmFzZVVybCB8fCB3aW5kb3cuYWp4cFNlcnZlckFjY2Vzc1BhdGg7XG4gICAgICAgIHRoaXMuX2xpYlVybCA9IHdpbmRvdy5hanhwUmVzb3VyY2VzRm9sZGVyICsgJy9idWlsZCc7XG4gICAgICAgIHRoaXMuX3BhcmFtZXRlcnMgPSBuZXcgTWFwKCk7XG4gICAgICAgIHRoaXMuX21ldGhvZCA9ICdwb3N0JztcbiAgICAgICAgdGhpcy5kaXNjcmV0ZSA9IGZhbHNlO1xuICAgIH1cblxuICAgIENvbm5leGlvbi51cGRhdGVTZXJ2ZXJBY2Nlc3MgPSBmdW5jdGlvbiB1cGRhdGVTZXJ2ZXJBY2Nlc3MocGFyYW1ldGVycykge1xuXG4gICAgICAgIGlmIChwYXJhbWV0ZXJzLmdldCgnU0VDVVJFX1RPS0VOJykpIHtcbiAgICAgICAgICAgIENvbm5leGlvbi5TRUNVUkVfVE9LRU4gPSBwYXJhbWV0ZXJzLmdldCgnU0VDVVJFX1RPS0VOJyk7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHNlcnZlckFjY2Vzc1BhdGggPSBwYXJhbWV0ZXJzLmdldCgnYWp4cFNlcnZlckFjY2VzcycpLnNwbGl0KCc/Jykuc2hpZnQoKTtcbiAgICAgICAgaWYgKHBhcmFtZXRlcnMuZ2V0KCdTRVJWRVJfUFJFRklYX1VSSScpKSB7XG4gICAgICAgICAgICBwYXJhbWV0ZXJzLnNldCgnYWp4cFJlc291cmNlc0ZvbGRlcicsIHBhcmFtZXRlcnMuZ2V0KCdTRVJWRVJfUFJFRklYX1VSSScpICsgcGFyYW1ldGVycy5nZXQoJ2FqeHBSZXNvdXJjZXNGb2xkZXInKSk7XG4gICAgICAgICAgICBzZXJ2ZXJBY2Nlc3NQYXRoID0gcGFyYW1ldGVycy5nZXQoJ1NFUlZFUl9QUkVGSVhfVVJJJykgKyBzZXJ2ZXJBY2Nlc3NQYXRoICsgJz8nICsgKENvbm5leGlvbi5TRUNVUkVfVE9LRU4gPyAnc2VjdXJlX3Rva2VuPScgKyBDb25uZXhpb24uU0VDVVJFX1RPS0VOIDogJycpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc2VydmVyQWNjZXNzUGF0aCA9IHNlcnZlckFjY2Vzc1BhdGggKyAnPycgKyAoQ29ubmV4aW9uLlNFQ1VSRV9UT0tFTiA/ICdzZWN1cmVfdG9rZW49JyArIENvbm5leGlvbi5TRUNVUkVfVE9LRU4gOiAnJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHBhcmFtZXRlcnMuZ2V0KCdTRVJWRVJfUEVSTUFORU5UX1BBUkFNUycpKSB7XG4gICAgICAgICAgICB2YXIgcGVybVBhcmFtcyA9IHBhcmFtZXRlcnMuZ2V0KCdTRVJWRVJfUEVSTUFORU5UX1BBUkFNUycpO1xuICAgICAgICAgICAgdmFyIHBlcm1TdHJpbmdzID0gW107XG4gICAgICAgICAgICBmb3IgKHZhciBwZXJtYW5lbnQgaW4gcGVybVBhcmFtcykge1xuICAgICAgICAgICAgICAgIGlmIChwZXJtUGFyYW1zLmhhc093blByb3BlcnR5KHBlcm1hbmVudCkpIHtcbiAgICAgICAgICAgICAgICAgICAgcGVybVN0cmluZ3MucHVzaChwZXJtYW5lbnQgKyAnPScgKyBwZXJtUGFyYW1zW3Blcm1hbmVudF0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHBlcm1TdHJpbmdzID0gcGVybVN0cmluZ3Muam9pbignJicpO1xuICAgICAgICAgICAgaWYgKHBlcm1TdHJpbmdzKSB7XG4gICAgICAgICAgICAgICAgc2VydmVyQWNjZXNzUGF0aCArPSAnJicgKyBwZXJtU3RyaW5ncztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHBhcmFtZXRlcnMuc2V0KCdhanhwU2VydmVyQWNjZXNzJywgc2VydmVyQWNjZXNzUGF0aCk7XG4gICAgICAgIC8vIEJBQ0tXQVJEIENPTVBBVFxuICAgICAgICB3aW5kb3cuYWp4cFNlcnZlckFjY2Vzc1BhdGggPSBzZXJ2ZXJBY2Nlc3NQYXRoO1xuICAgICAgICBpZiAod2luZG93LnB5ZGlvQm9vdHN0cmFwICYmIHdpbmRvdy5weWRpb0Jvb3RzdHJhcC5wYXJhbWV0ZXJzKSB7XG4gICAgICAgICAgICBweWRpb0Jvb3RzdHJhcC5wYXJhbWV0ZXJzLnNldChcImFqeHBTZXJ2ZXJBY2Nlc3NcIiwgc2VydmVyQWNjZXNzUGF0aCk7XG4gICAgICAgICAgICBweWRpb0Jvb3RzdHJhcC5wYXJhbWV0ZXJzLnNldChcIlNFQ1VSRV9UT0tFTlwiLCBDb25uZXhpb24uU0VDVVJFX1RPS0VOKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBDb25uZXhpb24ubG9nID0gZnVuY3Rpb24gbG9nKGFjdGlvbiwgc3luY1N0YXR1cykge1xuICAgICAgICBpZiAoIUNvbm5leGlvbi5QeWRpb0xvZ3MpIHtcbiAgICAgICAgICAgIENvbm5leGlvbi5QeWRpb0xvZ3MgPSBbXTtcbiAgICAgICAgfVxuICAgICAgICBDb25uZXhpb24uUHlkaW9Mb2dzLnB1c2goeyBhY3Rpb246IGFjdGlvbiwgc3luYzogc3luY1N0YXR1cyB9KTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQWRkIGEgcGFyYW1ldGVyIHRvIHRoZSBxdWVyeVxuICAgICAqIEBwYXJhbSBwYXJhbU5hbWUgU3RyaW5nXG4gICAgICogQHBhcmFtIHBhcmFtVmFsdWUgU3RyaW5nXG4gICAgICovXG5cbiAgICBDb25uZXhpb24ucHJvdG90eXBlLmFkZFBhcmFtZXRlciA9IGZ1bmN0aW9uIGFkZFBhcmFtZXRlcihwYXJhbU5hbWUsIHBhcmFtVmFsdWUpIHtcbiAgICAgICAgaWYgKHRoaXMuX3BhcmFtZXRlcnMuZ2V0KHBhcmFtTmFtZSkgJiYgcGFyYW1OYW1lLmVuZHNXaXRoKCdbXScpKSB7XG4gICAgICAgICAgICB2YXIgZXhpc3RpbmcgPSB0aGlzLl9wYXJhbWV0ZXJzLmdldChwYXJhbU5hbWUpO1xuICAgICAgICAgICAgaWYgKCFleGlzdGluZyBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICAgICAgICAgICAgZXhpc3RpbmcgPSBbZXhpc3RpbmddO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZXhpc3RpbmcucHVzaChwYXJhbVZhbHVlKTtcbiAgICAgICAgICAgIHRoaXMuX3BhcmFtZXRlcnMuc2V0KHBhcmFtTmFtZSwgZXhpc3RpbmcpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fcGFyYW1ldGVycy5zZXQocGFyYW1OYW1lLCBwYXJhbVZhbHVlKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSB3aG9sZSBwYXJhbWV0ZXIgYXMgYSBidW5jaFxuICAgICAqIEBwYXJhbSBoUGFyYW1ldGVycyBNYXBcbiAgICAgKi9cblxuICAgIENvbm5leGlvbi5wcm90b3R5cGUuc2V0UGFyYW1ldGVycyA9IGZ1bmN0aW9uIHNldFBhcmFtZXRlcnMoaFBhcmFtZXRlcnMpIHtcbiAgICAgICAgaWYgKGhQYXJhbWV0ZXJzIGluc3RhbmNlb2YgTWFwKSB7XG4gICAgICAgICAgICB0aGlzLl9wYXJhbWV0ZXJzID0gaFBhcmFtZXRlcnM7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoaFBhcmFtZXRlcnMuX29iamVjdCkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1Bhc3NlZCBhIGxlZ2FjeSBIYXNoIG9iamVjdCB0byBDb25uZXhpb24uc2V0UGFyYW1ldGVycycpO1xuICAgICAgICAgICAgICAgIGhQYXJhbWV0ZXJzID0gaFBhcmFtZXRlcnMuX29iamVjdDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZvciAodmFyIGtleSBpbiBoUGFyYW1ldGVycykge1xuICAgICAgICAgICAgICAgIGlmIChoUGFyYW1ldGVycy5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3BhcmFtZXRlcnMuc2V0KGtleSwgaFBhcmFtZXRlcnNba2V5XSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFNldCB0aGUgcXVlcnkgbWV0aG9kIChnZXQgcG9zdClcbiAgICAgKiBAcGFyYW0gbWV0aG9kIFN0cmluZ1xuICAgICAqL1xuXG4gICAgQ29ubmV4aW9uLnByb3RvdHlwZS5zZXRNZXRob2QgPSBmdW5jdGlvbiBzZXRNZXRob2QobWV0aG9kKSB7XG4gICAgICAgIHRoaXMuX21ldGhvZCA9IG1ldGhvZDtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQWRkIHRoZSBzZWN1cmUgdG9rZW4gcGFyYW1ldGVyXG4gICAgICovXG5cbiAgICBDb25uZXhpb24ucHJvdG90eXBlLmFkZFNlY3VyZVRva2VuID0gZnVuY3Rpb24gYWRkU2VjdXJlVG9rZW4oKSB7XG5cbiAgICAgICAgaWYgKENvbm5leGlvbi5TRUNVUkVfVE9LRU4gJiYgdGhpcy5fYmFzZVVybC5pbmRleE9mKCdzZWN1cmVfdG9rZW4nKSA9PSAtMSAmJiAhdGhpcy5fcGFyYW1ldGVycy5nZXQoJ3NlY3VyZV90b2tlbicpKSB7XG5cbiAgICAgICAgICAgIHRoaXMuYWRkUGFyYW1ldGVyKCdzZWN1cmVfdG9rZW4nLCBDb25uZXhpb24uU0VDVVJFX1RPS0VOKTtcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLl9iYXNlVXJsLmluZGV4T2YoJ3NlY3VyZV90b2tlbj0nKSAhPT0gLTEpIHtcblxuICAgICAgICAgICAgLy8gUmVtb3ZlIGZyb20gYmFzZVVybCBhbmQgc2V0IGluc2lkZSBwYXJhbXNcbiAgICAgICAgICAgIHZhciBwYXJ0cyA9IHRoaXMuX2Jhc2VVcmwuc3BsaXQoJ3NlY3VyZV90b2tlbj0nKTtcbiAgICAgICAgICAgIHZhciB0b2tzID0gcGFydHNbMV0uc3BsaXQoJyYnKTtcbiAgICAgICAgICAgIHZhciB0b2tlbiA9IHRva3Muc2hpZnQoKTtcbiAgICAgICAgICAgIHZhciByZXN0ID0gdG9rcy5qb2luKCcmJyk7XG4gICAgICAgICAgICB0aGlzLl9iYXNlVXJsID0gcGFydHNbMF0gKyAocmVzdCA/ICcmJyArIHJlc3QgOiAnJyk7XG4gICAgICAgICAgICB0aGlzLl9wYXJhbWV0ZXJzLnNldCgnc2VjdXJlX3Rva2VuJywgdG9rZW4pO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIENvbm5leGlvbi5wcm90b3R5cGUuYWRkU2VydmVyUGVybWFuZW50UGFyYW1zID0gZnVuY3Rpb24gYWRkU2VydmVyUGVybWFuZW50UGFyYW1zKCkge1xuICAgICAgICBpZiAoIXRoaXMuX3B5ZGlvIHx8ICF0aGlzLl9weWRpby5QYXJhbWV0ZXJzLmhhcygnU0VSVkVSX1BFUk1BTkVOVF9QQVJBTVMnKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHZhciBwZXJtUGFyYW1zID0gdGhpcy5fcHlkaW8uUGFyYW1ldGVycy5nZXQoJ1NFUlZFUl9QRVJNQU5FTlRfUEFSQU1TJyk7XG4gICAgICAgIGZvciAodmFyIHBlcm1hbmVudCBpbiBwZXJtUGFyYW1zKSB7XG4gICAgICAgICAgICBpZiAocGVybVBhcmFtcy5oYXNPd25Qcm9wZXJ0eShwZXJtYW5lbnQpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hZGRQYXJhbWV0ZXIocGVybWFuZW50LCBwZXJtUGFyYW1zW3Blcm1hbmVudF0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIFNob3cgYSBzbWFsbCBsb2FkZXJcbiAgICAgKi9cblxuICAgIENvbm5leGlvbi5wcm90b3R5cGUuc2hvd0xvYWRlciA9IGZ1bmN0aW9uIHNob3dMb2FkZXIoKSB7XG4gICAgICAgIGlmICh0aGlzLmRpc2NyZXRlIHx8ICF0aGlzLl9weWRpbykgcmV0dXJuO1xuICAgICAgICB0aGlzLl9weWRpby5ub3RpZnkoXCJjb25uZWN0aW9uLXN0YXJ0XCIpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBIaWRlIGEgc21hbGwgbG9hZGVyXG4gICAgICovXG5cbiAgICBDb25uZXhpb24ucHJvdG90eXBlLmhpZGVMb2FkZXIgPSBmdW5jdGlvbiBoaWRlTG9hZGVyKCkge1xuICAgICAgICBpZiAodGhpcy5kaXNjcmV0ZSB8fCAhdGhpcy5fcHlkaW8pIHJldHVybjtcbiAgICAgICAgdGhpcy5fcHlkaW8ubm90aWZ5KFwiY29ubmVjdGlvbi1lbmRcIik7XG4gICAgfTtcblxuICAgIENvbm5leGlvbi5wcm90b3R5cGUuX3NlbmQgPSBmdW5jdGlvbiBfc2VuZCgpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcblxuICAgICAgICB2YXIgYVN5bmMgPSBhcmd1bWVudHMubGVuZ3RoIDw9IDAgfHwgYXJndW1lbnRzWzBdID09PSB1bmRlZmluZWQgPyB0cnVlIDogYXJndW1lbnRzWzBdO1xuXG4gICAgICAgIENvbm5leGlvbi5sb2codGhpcy5fcGFyYW1ldGVycy5nZXQoXCJnZXRfYWN0aW9uXCIpLCBhU3luYyA/ICdhc3luYycgOiAnc3luYycpO1xuICAgICAgICB0aGlzLmFkZFNlY3VyZVRva2VuKCk7XG4gICAgICAgIHRoaXMuYWRkU2VydmVyUGVybWFuZW50UGFyYW1zKCk7XG4gICAgICAgIHRoaXMuc2hvd0xvYWRlcigpO1xuICAgICAgICB2YXIgb1RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgb3B0aW9ucyA9IHtcbiAgICAgICAgICAgIG1ldGhvZDogdGhpcy5fbWV0aG9kLFxuICAgICAgICAgICAgY3JlZGVudGlhbHM6ICdzYW1lLW9yaWdpbidcbiAgICAgICAgfTtcbiAgICAgICAgdmFyIHVybCA9IHRoaXMuX2Jhc2VVcmw7XG4gICAgICAgIGlmICghYVN5bmMpIHtcbiAgICAgICAgICAgIG9wdGlvbnMuc3luY2hyb25vdXMgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHZhciBib2R5UGFydHMgPSBbXTtcbiAgICAgICAgdGhpcy5fcGFyYW1ldGVycy5mb3JFYWNoKGZ1bmN0aW9uICh2YWx1ZSwga2V5KSB7XG4gICAgICAgICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBBcnJheSkge1xuICAgICAgICAgICAgICAgIHZhbHVlLm1hcChmdW5jdGlvbiAob25lVikge1xuICAgICAgICAgICAgICAgICAgICBib2R5UGFydHMucHVzaChrZXkgKyAnPScgKyBlbmNvZGVVUklDb21wb25lbnQob25lVikpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBib2R5UGFydHMucHVzaChrZXkgKyAnPScgKyBlbmNvZGVVUklDb21wb25lbnQodmFsdWUpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHZhciBxdWVyeVN0cmluZyA9IGJvZHlQYXJ0cy5qb2luKCcmJyk7XG4gICAgICAgIGlmICh0aGlzLl9tZXRob2QgPT09ICdwb3N0Jykge1xuICAgICAgICAgICAgb3B0aW9ucy5oZWFkZXJzID0geyBcIkNvbnRlbnQtdHlwZVwiOiBcImFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZDsgY2hhcnNldD1VVEYtOFwiIH07XG4gICAgICAgICAgICBvcHRpb25zLmJvZHkgPSBxdWVyeVN0cmluZztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHVybCArPSAodXJsLmluZGV4T2YoJz8nKSA+IC0xID8gJyYnIDogJz8nKSArIHF1ZXJ5U3RyaW5nO1xuICAgICAgICB9XG4gICAgICAgIHdpbmRvdy5mZXRjaCh1cmwsIG9wdGlvbnMpLnRoZW4oZnVuY3Rpb24gKHJlc3BvbnNlKSB7XG5cbiAgICAgICAgICAgIHZhciBoID0gcmVzcG9uc2UuaGVhZGVycy5nZXQoJ0NvbnRlbnQtdHlwZScpO1xuICAgICAgICAgICAgaWYgKGguaW5kZXhPZignL2pzb24nKSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICByZXNwb25zZS5qc29uKCkudGhlbihmdW5jdGlvbiAoanNvbikge1xuICAgICAgICAgICAgICAgICAgICBvVGhpcy5hcHBseUNvbXBsZXRlKHsgcmVzcG9uc2VKU09OOiBqc29uIH0sIHJlc3BvbnNlKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaC5pbmRleE9mKCcveG1sJykgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgcmVzcG9uc2UudGV4dCgpLnRoZW4oZnVuY3Rpb24gKHRleHQpIHtcbiAgICAgICAgICAgICAgICAgICAgb1RoaXMuYXBwbHlDb21wbGV0ZSh7IHJlc3BvbnNlWE1MOiBfdXRpbFhNTFV0aWxzMlsnZGVmYXVsdCddLnBhcnNlWG1sKHRleHQpIH0sIHJlc3BvbnNlKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVzcG9uc2UudGV4dCgpLnRoZW4oZnVuY3Rpb24gKHRleHQpIHtcbiAgICAgICAgICAgICAgICAgICAgb1RoaXMuYXBwbHlDb21wbGV0ZSh7IHJlc3BvbnNlVGV4dDogdGV4dCB9LCByZXNwb25zZSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcmVzcG9uc2U7XG4gICAgICAgIH0pWydjYXRjaCddKGZ1bmN0aW9uIChlcnJvcikge1xuICAgICAgICAgICAgaWYgKF90aGlzLl9weWRpbykge1xuICAgICAgICAgICAgICAgIF90aGlzLl9weWRpby5kaXNwbGF5TWVzc2FnZSgnRVJST1InLCAnTmV0d29yayBlcnJvciAnICsgZXJyb3IubWVzc2FnZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBTZW5kIEFzeW5jaHJvbm91c2x5XG4gICAgICovXG5cbiAgICBDb25uZXhpb24ucHJvdG90eXBlLnNlbmRBc3luYyA9IGZ1bmN0aW9uIHNlbmRBc3luYygpIHtcbiAgICAgICAgdGhpcy5fc2VuZCh0cnVlKTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogU2VuZCBzeW5jaHJvbm91c2x5XG4gICAgICovXG5cbiAgICBDb25uZXhpb24ucHJvdG90eXBlLnNlbmRTeW5jID0gZnVuY3Rpb24gc2VuZFN5bmMoKSB7XG4gICAgICAgIHRoaXMuX3NlbmQoZmFsc2UpO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBBcHBseSB0aGUgY29tcGxldGUgY2FsbGJhY2ssIHRyeSB0byBncmFiIG1heGltdW0gb2YgZXJyb3JzXG4gICAgICogQHBhcmFtIHBhcnNlZEJvZHkgVHJhbnNwb3RcbiAgICAgKi9cblxuICAgIENvbm5leGlvbi5wcm90b3R5cGUuYXBwbHlDb21wbGV0ZSA9IGZ1bmN0aW9uIGFwcGx5Q29tcGxldGUocGFyc2VkQm9keSwgcmVzcG9uc2UpIHtcbiAgICAgICAgdGhpcy5oaWRlTG9hZGVyKCk7XG4gICAgICAgIHZhciBweWRpbyA9IHRoaXMuX3B5ZGlvO1xuICAgICAgICB2YXIgbWVzc2FnZSA9IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIHRva2VuTWVzc2FnZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgdmFyIHRvazEgPSBcIk9vb3BzLCBpdCBzZWVtcyB0aGF0IHlvdXIgc2VjdXJpdHkgdG9rZW4gaGFzIGV4cGlyZWQhIFBsZWFzZSAlcyBieSBoaXR0aW5nIHJlZnJlc2ggb3IgRjUgaW4geW91ciBicm93c2VyIVwiO1xuICAgICAgICB2YXIgdG9rMiA9IFwicmVsb2FkIHRoZSBwYWdlXCI7XG4gICAgICAgIGlmICh3aW5kb3cuTWVzc2FnZUhhc2ggJiYgd2luZG93Lk1lc3NhZ2VIYXNoWzQzN10pIHtcbiAgICAgICAgICAgIHRvazEgPSB3aW5kb3cuTWVzc2FnZUhhc2hbNDM3XTtcbiAgICAgICAgICAgIHRvazIgPSB3aW5kb3cuTWVzc2FnZUhhc2hbNDM4XTtcbiAgICAgICAgfVxuICAgICAgICB0b2tlbk1lc3NhZ2UgPSB0b2sxLnJlcGxhY2UoXCIlc1wiLCBcIjxhIGhyZWY9J2phdmFzY3JpcHQ6ZG9jdW1lbnQubG9jYXRpb24ucmVsb2FkKCknIHN0eWxlPSd0ZXh0LWRlY29yYXRpb246IHVuZGVybGluZTsnPlwiICsgdG9rMiArIFwiPC9hPlwiKTtcblxuICAgICAgICB2YXIgY3R5cGUgPSByZXNwb25zZS5oZWFkZXJzLmdldCgnQ29udGVudC10eXBlJyk7XG4gICAgICAgIGlmIChwYXJzZWRCb2R5LnJlc3BvbnNlWE1MICYmIHBhcnNlZEJvZHkucmVzcG9uc2VYTUwuZG9jdW1lbnRFbGVtZW50ICYmIHBhcnNlZEJvZHkucmVzcG9uc2VYTUwuZG9jdW1lbnRFbGVtZW50Lm5vZGVOYW1lID09IFwicGFyc2VyZXJyb3JcIikge1xuXG4gICAgICAgICAgICBtZXNzYWdlID0gXCJQYXJzaW5nIGVycm9yIDogXFxuXCIgKyBwYXJzZWRCb2R5LnJlc3BvbnNlWE1MLmRvY3VtZW50RWxlbWVudC5maXJzdENoaWxkLnRleHRDb250ZW50O1xuICAgICAgICB9IGVsc2UgaWYgKHBhcnNlZEJvZHkucmVzcG9uc2VYTUwgJiYgcGFyc2VkQm9keS5yZXNwb25zZVhNTC5wYXJzZUVycm9yICYmIHBhcnNlZEJvZHkucmVzcG9uc2VYTUwucGFyc2VFcnJvci5lcnJvckNvZGUgIT0gMCkge1xuXG4gICAgICAgICAgICBtZXNzYWdlID0gXCJQYXJzaW5nIEVycm9yIDogXFxuXCIgKyBwYXJzZWRCb2R5LnJlc3BvbnNlWE1MLnBhcnNlRXJyb3IucmVhc29uO1xuICAgICAgICB9IGVsc2UgaWYgKGN0eXBlLmluZGV4T2YoXCJ0ZXh0L3htbFwiKSA+IC0xICYmIHBhcnNlZEJvZHkucmVzcG9uc2VYTUwgPT0gbnVsbCkge1xuXG4gICAgICAgICAgICBtZXNzYWdlID0gXCJFeHBlY3RlZCBYTUwgYnV0IGdvdCBlbXB0eSByZXNwb25zZSFcIjtcbiAgICAgICAgfSBlbHNlIGlmIChjdHlwZS5pbmRleE9mKFwidGV4dC94bWxcIikgPT0gLTEgJiYgY3R5cGUuaW5kZXhPZihcImFwcGxpY2F0aW9uL2pzb25cIikgPT0gLTEgJiYgcGFyc2VkQm9keS5yZXNwb25zZVRleHQuaW5kZXhPZihcIjxiPkZhdGFsIGVycm9yPC9iPlwiKSA+IC0xKSB7XG5cbiAgICAgICAgICAgIG1lc3NhZ2UgPSBwYXJzZWRCb2R5LnJlc3BvbnNlVGV4dC5yZXBsYWNlKFwiPGJyIC8+XCIsIFwiXCIpO1xuICAgICAgICB9IGVsc2UgaWYgKHJlc3BvbnNlLnN0YXR1cyA9PSA1MDApIHtcblxuICAgICAgICAgICAgbWVzc2FnZSA9IFwiSW50ZXJuYWwgU2VydmVyIEVycm9yOiB5b3Ugc2hvdWxkIGNoZWNrIHlvdXIgd2ViIHNlcnZlciBsb2dzIHRvIGZpbmQgd2hhdCdzIGdvaW5nIHdyb25nIVwiO1xuICAgICAgICB9XG4gICAgICAgIGlmIChtZXNzYWdlKSB7XG5cbiAgICAgICAgICAgIGlmIChtZXNzYWdlLnN0YXJ0c1dpdGgoXCJZb3UgYXJlIG5vdCBhbGxvd2VkIHRvIGFjY2VzcyB0aGlzIHJlc291cmNlLlwiKSkge1xuICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSB0b2tlbk1lc3NhZ2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAocHlkaW8pIHtcbiAgICAgICAgICAgICAgICBweWRpby5kaXNwbGF5TWVzc2FnZShcIkVSUk9SXCIsIG1lc3NhZ2UpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBhbGVydChtZXNzYWdlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAocGFyc2VkQm9keS5yZXNwb25zZVhNTCAmJiBwYXJzZWRCb2R5LnJlc3BvbnNlWE1MLmRvY3VtZW50RWxlbWVudCkge1xuXG4gICAgICAgICAgICB2YXIgYXV0aE5vZGUgPSBfdXRpbFhNTFV0aWxzMlsnZGVmYXVsdCddLlhQYXRoU2VsZWN0U2luZ2xlTm9kZShwYXJzZWRCb2R5LnJlc3BvbnNlWE1MLmRvY3VtZW50RWxlbWVudCwgXCJyZXF1aXJlX2F1dGhcIik7XG4gICAgICAgICAgICBpZiAoYXV0aE5vZGUgJiYgcHlkaW8pIHtcbiAgICAgICAgICAgICAgICB2YXIgcm9vdCA9IHB5ZGlvLmdldENvbnRleHRIb2xkZXIoKS5nZXRSb290Tm9kZSgpO1xuICAgICAgICAgICAgICAgIGlmIChyb290KSB7XG4gICAgICAgICAgICAgICAgICAgIHB5ZGlvLmdldENvbnRleHRIb2xkZXIoKS5zZXRDb250ZXh0Tm9kZShyb290KTtcbiAgICAgICAgICAgICAgICAgICAgcm9vdC5jbGVhcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBweWRpby5nZXRDb250cm9sbGVyKCkuZmlyZUFjdGlvbignbG9nb3V0Jyk7XG4gICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIHB5ZGlvLmdldENvbnRyb2xsZXIoKS5maXJlQWN0aW9uKCdsb2dpbicpO1xuICAgICAgICAgICAgICAgIH0sIDM1MCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciBtZXNzYWdlTm9kZSA9IF91dGlsWE1MVXRpbHMyWydkZWZhdWx0J10uWFBhdGhTZWxlY3RTaW5nbGVOb2RlKHBhcnNlZEJvZHkucmVzcG9uc2VYTUwuZG9jdW1lbnRFbGVtZW50LCBcIm1lc3NhZ2VcIik7XG4gICAgICAgICAgICBpZiAobWVzc2FnZU5vZGUpIHtcbiAgICAgICAgICAgICAgICB2YXIgbWVzc2FnZVR5cGUgPSBtZXNzYWdlTm9kZS5nZXRBdHRyaWJ1dGUoXCJ0eXBlXCIpLnRvVXBwZXJDYXNlKCk7XG4gICAgICAgICAgICAgICAgdmFyIG1lc3NhZ2VDb250ZW50ID0gX3V0aWxYTUxVdGlsczJbJ2RlZmF1bHQnXS5nZXREb21Ob2RlVGV4dChtZXNzYWdlTm9kZSk7XG4gICAgICAgICAgICAgICAgaWYgKG1lc3NhZ2VDb250ZW50LnN0YXJ0c1dpdGgoXCJZb3UgYXJlIG5vdCBhbGxvd2VkIHRvIGFjY2VzcyB0aGlzIHJlc291cmNlLlwiKSkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlQ29udGVudCA9IHRva2VuTWVzc2FnZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHB5ZGlvKSB7XG4gICAgICAgICAgICAgICAgICAgIHB5ZGlvLmRpc3BsYXlNZXNzYWdlKG1lc3NhZ2VUeXBlLCBtZXNzYWdlQ29udGVudCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG1lc3NhZ2VUeXBlID09IFwiRVJST1JcIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgYWxlcnQobWVzc2FnZVR5cGUgKyBcIjpcIiArIG1lc3NhZ2VDb250ZW50KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAobWVzc2FnZVR5cGUgPT0gXCJTVUNDRVNTXCIpIG1lc3NhZ2VOb2RlLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQobWVzc2FnZU5vZGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLm9uQ29tcGxldGUpIHtcblxuICAgICAgICAgICAgcGFyc2VkQm9keS5zdGF0dXMgPSByZXNwb25zZS5zdGF0dXM7XG4gICAgICAgICAgICBwYXJzZWRCb2R5LnJlc3BvbnNlT2JqZWN0ID0gcmVzcG9uc2U7XG4gICAgICAgICAgICB0aGlzLm9uQ29tcGxldGUocGFyc2VkQm9keSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHB5ZGlvKSB7XG4gICAgICAgICAgICBweWRpby5maXJlKFwic2VydmVyX2Fuc3dlclwiLCB0aGlzKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBDb25uZXhpb24ucHJvdG90eXBlLnVwbG9hZEZpbGUgPSBmdW5jdGlvbiB1cGxvYWRGaWxlKGZpbGUsIGZpbGVQYXJhbWV0ZXJOYW1lLCB1cGxvYWRVcmwsIG9uQ29tcGxldGUsIG9uRXJyb3IsIG9uUHJvZ3Jlc3MsIHhoclNldHRpbmdzKSB7XG5cbiAgICAgICAgaWYgKHhoclNldHRpbmdzID09PSB1bmRlZmluZWQpIHhoclNldHRpbmdzID0ge307XG5cbiAgICAgICAgaWYgKCFvbkNvbXBsZXRlKSBvbkNvbXBsZXRlID0gZnVuY3Rpb24gKCkge307XG4gICAgICAgIGlmICghb25FcnJvcikgb25FcnJvciA9IGZ1bmN0aW9uICgpIHt9O1xuICAgICAgICBpZiAoIW9uUHJvZ3Jlc3MpIG9uUHJvZ3Jlc3MgPSBmdW5jdGlvbiAoKSB7fTtcbiAgICAgICAgdmFyIHhociA9IHRoaXMuaW5pdGlhbGl6ZVhIUkZvclVwbG9hZCh1cGxvYWRVcmwsIG9uQ29tcGxldGUsIG9uRXJyb3IsIG9uUHJvZ3Jlc3MsIHhoclNldHRpbmdzKTtcbiAgICAgICAgaWYgKHdpbmRvdy5Gb3JtRGF0YSkge1xuICAgICAgICAgICAgdGhpcy5zZW5kRmlsZVVzaW5nRm9ybURhdGEoeGhyLCBmaWxlLCBmaWxlUGFyYW1ldGVyTmFtZSk7XG4gICAgICAgIH0gZWxzZSBpZiAod2luZG93LkZpbGVSZWFkZXIpIHtcbiAgICAgICAgICAgIHZhciBmaWxlUmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTtcbiAgICAgICAgICAgIGZpbGVSZWFkZXIub25sb2FkID0gKGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy54aHJTZW5kQXNCaW5hcnkoeGhyLCBmaWxlLm5hbWUsIGUudGFyZ2V0LnJlc3VsdCwgZmlsZVBhcmFtZXRlck5hbWUpO1xuICAgICAgICAgICAgfSkuYmluZCh0aGlzKTtcbiAgICAgICAgICAgIGZpbGVSZWFkZXIucmVhZEFzQmluYXJ5U3RyaW5nKGZpbGUpO1xuICAgICAgICB9IGVsc2UgaWYgKGZpbGUuZ2V0QXNCaW5hcnkpIHtcbiAgICAgICAgICAgIHRoaXMueGhyU2VuZEFzQmluYXJ5KHhociwgZmlsZS5uYW1lLCBmaWxlLmdldEFzQmluYXJ5KCksIGZpbGVQYXJhbWV0ZXJOYW1lKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geGhyO1xuICAgIH07XG5cbiAgICBDb25uZXhpb24ucHJvdG90eXBlLmluaXRpYWxpemVYSFJGb3JVcGxvYWQgPSBmdW5jdGlvbiBpbml0aWFsaXplWEhSRm9yVXBsb2FkKHVybCwgb25Db21wbGV0ZSwgb25FcnJvciwgb25Qcm9ncmVzcywgeGhyU2V0dGluZ3MpIHtcblxuICAgICAgICBpZiAoeGhyU2V0dGluZ3MgPT09IHVuZGVmaW5lZCkgeGhyU2V0dGluZ3MgPSB7fTtcblxuICAgICAgICB2YXIgeGhyID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG4gICAgICAgIHZhciB1cGxvYWQgPSB4aHIudXBsb2FkO1xuICAgICAgICBpZiAoeGhyU2V0dGluZ3Mud2l0aENyZWRlbnRpYWxzKSB7XG4gICAgICAgICAgICB4aHIud2l0aENyZWRlbnRpYWxzID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICB1cGxvYWQuYWRkRXZlbnRMaXN0ZW5lcihcInByb2dyZXNzXCIsIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICBpZiAoIWUubGVuZ3RoQ29tcHV0YWJsZSkgcmV0dXJuO1xuICAgICAgICAgICAgb25Qcm9ncmVzcyhlKTtcbiAgICAgICAgfSwgZmFsc2UpO1xuICAgICAgICB4aHIub25yZWFkeXN0YXRlY2hhbmdlID0gKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmICh4aHIucmVhZHlTdGF0ZSA9PSA0KSB7XG4gICAgICAgICAgICAgICAgaWYgKHhoci5zdGF0dXMgPT09IDIwMCkge1xuICAgICAgICAgICAgICAgICAgICBvbkNvbXBsZXRlKHhocik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgb25FcnJvcih4aHIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSkuYmluZCh0aGlzKTtcbiAgICAgICAgdXBsb2FkLm9uZXJyb3IgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBvbkVycm9yKHhocik7XG4gICAgICAgIH07XG4gICAgICAgIHhoci5vcGVuKFwiUE9TVFwiLCB1cmwsIHRydWUpO1xuICAgICAgICByZXR1cm4geGhyO1xuICAgIH07XG5cbiAgICBDb25uZXhpb24ucHJvdG90eXBlLnNlbmRGaWxlVXNpbmdGb3JtRGF0YSA9IGZ1bmN0aW9uIHNlbmRGaWxlVXNpbmdGb3JtRGF0YSh4aHIsIGZpbGUsIGZpbGVQYXJhbWV0ZXJOYW1lKSB7XG4gICAgICAgIHZhciBmb3JtRGF0YSA9IG5ldyBGb3JtRGF0YSgpO1xuICAgICAgICBmb3JtRGF0YS5hcHBlbmQoZmlsZVBhcmFtZXRlck5hbWUsIGZpbGUpO1xuICAgICAgICB4aHIuc2VuZChmb3JtRGF0YSk7XG4gICAgfTtcblxuICAgIENvbm5leGlvbi5wcm90b3R5cGUueGhyU2VuZEFzQmluYXJ5ID0gZnVuY3Rpb24geGhyU2VuZEFzQmluYXJ5KHhociwgZmlsZU5hbWUsIGZpbGVEYXRhLCBmaWxlUGFyYW1ldGVyTmFtZSkge1xuICAgICAgICB2YXIgYm91bmRhcnkgPSAnLS0tLU11bHRpUGFydEZvcm1Cb3VuZGFyeScgKyBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoXCJDb250ZW50LVR5cGVcIiwgXCJtdWx0aXBhcnQvZm9ybS1kYXRhLCBib3VuZGFyeT1cIiArIGJvdW5kYXJ5KTtcblxuICAgICAgICB2YXIgYm9keSA9IFwiLS1cIiArIGJvdW5kYXJ5ICsgXCJcXHJcXG5cIjtcbiAgICAgICAgYm9keSArPSBcIkNvbnRlbnQtRGlzcG9zaXRpb246IGZvcm0tZGF0YTsgbmFtZT0nXCIgKyBmaWxlUGFyYW1ldGVyTmFtZSArIFwiJzsgZmlsZW5hbWU9J1wiICsgdW5lc2NhcGUoZW5jb2RlVVJJQ29tcG9uZW50KGZpbGVOYW1lKSkgKyBcIidcXHJcXG5cIjtcbiAgICAgICAgYm9keSArPSBcIkNvbnRlbnQtVHlwZTogYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtXFxyXFxuXFxyXFxuXCI7XG4gICAgICAgIGJvZHkgKz0gZmlsZURhdGEgKyBcIlxcclxcblwiO1xuICAgICAgICBib2R5ICs9IFwiLS1cIiArIGJvdW5kYXJ5ICsgXCItLVxcclxcblwiO1xuXG4gICAgICAgIHhoci5zZW5kQXNCaW5hcnkoYm9keSk7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIExvYWQgYSBqYXZhc2NyaXB0IGxpYnJhcnlcbiAgICAgKiBAcGFyYW0gZmlsZU5hbWUgU3RyaW5nXG4gICAgICogQHBhcmFtIG9uTG9hZGVkQ29kZSBGdW5jdGlvbiBDYWxsYmFja1xuICAgICAgICAqIEBwYXJhbSBhU3luYyBCb29sZWFuIGxvYWQgbGlicmFyeSBhc3luY2hyb25lb3VzbHlcbiAgICAgKi9cblxuICAgIENvbm5leGlvbi5wcm90b3R5cGUubG9hZExpYnJhcnkgPSBmdW5jdGlvbiBsb2FkTGlicmFyeShmaWxlTmFtZSwgb25Mb2FkZWRDb2RlLCBhU3luYykge1xuICAgICAgICB2YXIgX3RoaXMyID0gdGhpcztcblxuICAgICAgICBpZiAod2luZG93LnB5ZGlvQm9vdHN0cmFwICYmIHdpbmRvdy5weWRpb0Jvb3RzdHJhcC5wYXJhbWV0ZXJzLmdldChcImFqeHBWZXJzaW9uXCIpICYmIGZpbGVOYW1lLmluZGV4T2YoXCI/XCIpID09IC0xKSB7XG4gICAgICAgICAgICBmaWxlTmFtZSArPSBcIj92PVwiICsgd2luZG93LnB5ZGlvQm9vdHN0cmFwLnBhcmFtZXRlcnMuZ2V0KFwiYWp4cFZlcnNpb25cIik7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHVybCA9IHRoaXMuX2xpYlVybCA/IHRoaXMuX2xpYlVybCArICcvJyArIGZpbGVOYW1lIDogZmlsZU5hbWU7XG4gICAgICAgIHZhciBweWRpbyA9IHRoaXMuX3B5ZGlvO1xuXG4gICAgICAgIHZhciBzY3JpcHRMb2FkZWQgPSBmdW5jdGlvbiBzY3JpcHRMb2FkZWQoc2NyaXB0KSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmICh3aW5kb3cuZXhlY1NjcmlwdCkge1xuICAgICAgICAgICAgICAgICAgICB3aW5kb3cuZXhlY1NjcmlwdChzY3JpcHQpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHdpbmRvdy5teV9jb2RlID0gc2NyaXB0O1xuICAgICAgICAgICAgICAgICAgICB2YXIgaGVhZCA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdoZWFkJylbMF07XG4gICAgICAgICAgICAgICAgICAgIHZhciBzY3JpcHRfdGFnID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc2NyaXB0Jyk7XG4gICAgICAgICAgICAgICAgICAgIHNjcmlwdF90YWcudHlwZSA9ICd0ZXh0L2phdmFzY3JpcHQnO1xuICAgICAgICAgICAgICAgICAgICBzY3JpcHRfdGFnLmlubmVySFRNTCA9ICdldmFsKHdpbmRvdy5teV9jb2RlKSc7XG4gICAgICAgICAgICAgICAgICAgIGhlYWQuYXBwZW5kQ2hpbGQoc2NyaXB0X3RhZyk7XG4gICAgICAgICAgICAgICAgICAgIGRlbGV0ZSB3aW5kb3cubXlfY29kZTtcbiAgICAgICAgICAgICAgICAgICAgaGVhZC5yZW1vdmVDaGlsZChzY3JpcHRfdGFnKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKG9uTG9hZGVkQ29kZSAhPSBudWxsKSBvbkxvYWRlZENvZGUoKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICBhbGVydCgnZXJyb3IgbG9hZGluZyAnICsgZmlsZU5hbWUgKyAnOicgKyBlLm1lc3NhZ2UpO1xuICAgICAgICAgICAgICAgIGlmIChjb25zb2xlKSBjb25zb2xlLmVycm9yKGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHB5ZGlvKSBweWRpby5maXJlKFwic2VydmVyX2Fuc3dlclwiKTtcbiAgICAgICAgfTtcblxuICAgICAgICBpZiAoYVN5bmMpIHtcbiAgICAgICAgICAgIHdpbmRvdy5mZXRjaCh1cmwsIHtcbiAgICAgICAgICAgICAgICBtZXRob2Q6ICdHRVQnLFxuICAgICAgICAgICAgICAgIGNyZWRlbnRpYWxzOiAnc2FtZS1vcmlnaW4nXG4gICAgICAgICAgICB9KS50aGVuKGZ1bmN0aW9uIChyZXNwb25zZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiByZXNwb25zZS50ZXh0KCk7XG4gICAgICAgICAgICB9KS50aGVuKGZ1bmN0aW9uIChzY3JpcHQpIHtcbiAgICAgICAgICAgICAgICBzY3JpcHRMb2FkZWQoc2NyaXB0KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAvLyBTSE9VTEQgQkUgUkVNT1ZFRCEhXG4gICAgICAgICAgICAgICAgdmFyIHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICAgICAgICAgICAgICAgIHhoci5vbnJlYWR5c3RhdGVjaGFuZ2UgPSAoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoeGhyLnJlYWR5U3RhdGUgPT0gNCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHhoci5zdGF0dXMgPT09IDIwMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjcmlwdExvYWRlZCh4aHIucmVzcG9uc2VUZXh0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxlcnQoJ2Vycm9yIGxvYWRpbmcgJyArIGZpbGVOYW1lICsgJzogU3RhdHVzIGNvZGUgd2FzICcgKyB4aHIuc3RhdHVzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pLmJpbmQoX3RoaXMyKTtcbiAgICAgICAgICAgICAgICB4aHIub3BlbihcIkdFVFwiLCB1cmwsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICB4aHIuc2VuZCgpO1xuICAgICAgICAgICAgfSkoKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICByZXR1cm4gQ29ubmV4aW9uO1xufSkoKTtcblxuZXhwb3J0c1snZGVmYXVsdCddID0gQ29ubmV4aW9uO1xubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzWydkZWZhdWx0J107XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMDctMjAxNyBDaGFybGVzIGR1IEpldSAtIEFic3RyaXVtIFNBUyA8dGVhbSAoYXQpIHB5ZC5pbz5cbiAqIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIFB5ZGlvLlxuICpcbiAqIFB5ZGlvIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEFmZmVybyBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieVxuICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3JcbiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uXG4gKlxuICogUHlkaW8gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgQWZmZXJvIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggUHlkaW8uICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uXG4gKlxuICogVGhlIGxhdGVzdCBjb2RlIGNhbiBiZSBmb3VuZCBhdCA8aHR0cHM6Ly9weWRpby5jb20vPi5cbiAqXG4gKi9cbid1c2Ugc3RyaWN0JztcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgJ2RlZmF1bHQnOiBvYmogfTsgfVxuXG5mdW5jdGlvbiBfY2xhc3NDYWxsQ2hlY2soaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCBjYWxsIGEgY2xhc3MgYXMgYSBmdW5jdGlvbicpOyB9IH1cblxudmFyIF93aWNrZWRHb29kWHBhdGggPSByZXF1aXJlKCd3aWNrZWQtZ29vZC14cGF0aCcpO1xuXG52YXIgX3dpY2tlZEdvb2RYcGF0aDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF93aWNrZWRHb29kWHBhdGgpO1xuXG5fd2lja2VkR29vZFhwYXRoMlsnZGVmYXVsdCddLmluc3RhbGwoKTtcbi8qKlxuICogVXRpbGl0YXJ5IGNsYXNzIGZvciBtYW5pcHVsYXRpbmcgWE1MXG4gKi9cblxudmFyIFhNTFV0aWxzID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBYTUxVdGlscygpIHtcbiAgICAgICAgX2NsYXNzQ2FsbENoZWNrKHRoaXMsIFhNTFV0aWxzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZWxlY3RzIHRoZSBmaXJzdCBYbWxOb2RlIHRoYXQgbWF0Y2hlcyB0aGUgWFBhdGggZXhwcmVzc2lvbi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBlbGVtZW50IHtFbGVtZW50IHwgRG9jdW1lbnR9IHJvb3QgZWxlbWVudCBmb3IgdGhlIHNlYXJjaFxuICAgICAqIEBwYXJhbSBxdWVyeSB7U3RyaW5nfSBYUGF0aCBxdWVyeVxuICAgICAqIEByZXR1cm4ge0VsZW1lbnR9IGZpcnN0IG1hdGNoaW5nIGVsZW1lbnRcbiAgICAgKiBAc2lnbmF0dXJlIGZ1bmN0aW9uKGVsZW1lbnQsIHF1ZXJ5KVxuICAgICAqL1xuXG4gICAgWE1MVXRpbHMuWFBhdGhTZWxlY3RTaW5nbGVOb2RlID0gZnVuY3Rpb24gWFBhdGhTZWxlY3RTaW5nbGVOb2RlKGVsZW1lbnQsIHF1ZXJ5KSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpZiAoZWxlbWVudFsnc2VsZWN0U2luZ2xlTm9kZSddICYmIHR5cGVvZiBlbGVtZW50LnNlbGVjdFNpbmdsZU5vZGUgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgICAgIHZhciByZXMgPSBlbGVtZW50LnNlbGVjdFNpbmdsZU5vZGUocXVlcnkpO1xuICAgICAgICAgICAgICAgIGlmIChyZXMpIHJldHVybiByZXM7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGUpIHt9XG5cbiAgICAgICAgaWYgKCFYTUxVdGlscy5fX3hwZSAmJiB3aW5kb3cuWFBhdGhFdmFsdWF0b3IpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgWE1MVXRpbHMuX194cGUgPSBuZXcgWFBhdGhFdmFsdWF0b3IoKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHt9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIVhNTFV0aWxzLl9feHBlKSB7XG4gICAgICAgICAgICBxdWVyeSA9IGRvY3VtZW50LmNyZWF0ZUV4cHJlc3Npb24ocXVlcnksIG51bGwpO1xuICAgICAgICAgICAgdmFyIHJlc3VsdCA9IHF1ZXJ5LmV2YWx1YXRlKGVsZW1lbnQsIDcsIG51bGwpO1xuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC5zbmFwc2hvdExlbmd0aCA/IHJlc3VsdC5zbmFwc2hvdEl0ZW0oMCkgOiBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHhwZSA9IFhNTFV0aWxzLl9feHBlO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4geHBlLmV2YWx1YXRlKHF1ZXJ5LCBlbGVtZW50LCB4cGUuY3JlYXRlTlNSZXNvbHZlcihlbGVtZW50KSwgWFBhdGhSZXN1bHQuRklSU1RfT1JERVJFRF9OT0RFX1RZUEUsIG51bGwpLnNpbmdsZU5vZGVWYWx1ZTtcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJzZWxlY3RTaW5nbGVOb2RlOiBxdWVyeTogXCIgKyBxdWVyeSArIFwiLCBlbGVtZW50OiBcIiArIGVsZW1lbnQgKyBcIiwgZXJyb3I6IFwiICsgZXJyKTtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBTZWxlY3RzIGEgbGlzdCBvZiBub2RlcyBtYXRjaGluZyB0aGUgWFBhdGggZXhwcmVzc2lvbi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBlbGVtZW50IHtFbGVtZW50IHwgRG9jdW1lbnR9IHJvb3QgZWxlbWVudCBmb3IgdGhlIHNlYXJjaFxuICAgICAqIEBwYXJhbSBxdWVyeSB7U3RyaW5nfSBYUGF0aCBxdWVyeVxuICAgICAqIEByZXR1cm4ge0VsZW1lbnRbXX0gTGlzdCBvZiBtYXRjaGluZyBlbGVtZW50c1xuICAgICAqIEBzaWduYXR1cmUgZnVuY3Rpb24oZWxlbWVudCwgcXVlcnkpXG4gICAgICovXG5cbiAgICBYTUxVdGlscy5YUGF0aFNlbGVjdE5vZGVzID0gZnVuY3Rpb24gWFBhdGhTZWxlY3ROb2RlcyhlbGVtZW50LCBxdWVyeSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBlbGVtZW50LnNlbGVjdE5vZGVzID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZWxlbWVudC5vd25lckRvY3VtZW50ICYmIGVsZW1lbnQub3duZXJEb2N1bWVudC5zZXRQcm9wZXJ0eSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5vd25lckRvY3VtZW50LnNldFByb3BlcnR5KFwiU2VsZWN0aW9uTGFuZ3VhZ2VcIiwgXCJYUGF0aFwiKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChlbGVtZW50LnNldFByb3BlcnR5KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50LnNldFByb3BlcnR5KFwiU2VsZWN0aW9uTGFuZ3VhZ2VcIiwgXCJYUGF0aFwiKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHt9XG4gICAgICAgICAgICAgICAgdmFyIHJlcyA9IEFycmF5LmZyb20oZWxlbWVudC5zZWxlY3ROb2RlcyhxdWVyeSkpO1xuICAgICAgICAgICAgICAgIGlmIChyZXMpIHJldHVybiByZXM7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGUpIHt9XG5cbiAgICAgICAgdmFyIHhwZSA9IFhNTFV0aWxzLl9feHBlO1xuXG4gICAgICAgIGlmICgheHBlICYmIHdpbmRvdy5YUGF0aEV2YWx1YXRvcikge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBYTUxVdGlscy5fX3hwZSA9IHhwZSA9IG5ldyBYUGF0aEV2YWx1YXRvcigpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge31cbiAgICAgICAgfVxuICAgICAgICB2YXIgcmVzdWx0LFxuICAgICAgICAgICAgbm9kZXMgPSBbXSxcbiAgICAgICAgICAgIGk7XG4gICAgICAgIGlmICghWE1MVXRpbHMuX194cGUpIHtcbiAgICAgICAgICAgIHF1ZXJ5ID0gZG9jdW1lbnQuY3JlYXRlRXhwcmVzc2lvbihxdWVyeSwgbnVsbCk7XG4gICAgICAgICAgICByZXN1bHQgPSBxdWVyeS5ldmFsdWF0ZShlbGVtZW50LCA3LCBudWxsKTtcbiAgICAgICAgICAgIG5vZGVzID0gW107XG4gICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgcmVzdWx0LnNuYXBzaG90TGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBpZiAoRWxlbWVudC5leHRlbmQpIHtcbiAgICAgICAgICAgICAgICAgICAgbm9kZXNbaV0gPSBFbGVtZW50LmV4dGVuZChyZXN1bHQuc25hcHNob3RJdGVtKGkpKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBub2Rlc1tpXSA9IHJlc3VsdC5zbmFwc2hvdEl0ZW0oaSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG5vZGVzO1xuICAgICAgICB9XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJlc3VsdCA9IHhwZS5ldmFsdWF0ZShxdWVyeSwgZWxlbWVudCwgeHBlLmNyZWF0ZU5TUmVzb2x2ZXIoZWxlbWVudCksIFhQYXRoUmVzdWx0Lk9SREVSRURfTk9ERV9TTkFQU0hPVF9UWVBFLCBudWxsKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJzZWxlY3ROb2RlczogcXVlcnk6IFwiICsgcXVlcnkgKyBcIiwgZWxlbWVudDogXCIgKyBlbGVtZW50ICsgXCIsIGVycm9yOiBcIiArIGVycik7XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgcmVzdWx0LnNuYXBzaG90TGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIG5vZGVzW2ldID0gcmVzdWx0LnNuYXBzaG90SXRlbShpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBub2RlcztcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogU2VsZWN0cyB0aGUgZmlyc3QgWG1sTm9kZSB0aGF0IG1hdGNoZXMgdGhlIFhQYXRoIGV4cHJlc3Npb24gYW5kIHJldHVybnMgdGhlIHRleHQgY29udGVudCBvZiB0aGUgZWxlbWVudFxuICAgICAqXG4gICAgICogQHBhcmFtIGVsZW1lbnQge0VsZW1lbnR8RG9jdW1lbnR9IHJvb3QgZWxlbWVudCBmb3IgdGhlIHNlYXJjaFxuICAgICAqIEBwYXJhbSBxdWVyeSB7U3RyaW5nfSAgWFBhdGggcXVlcnlcbiAgICAgKiBAcmV0dXJuIHtTdHJpbmd9IHRoZSBqb2luZWQgdGV4dCBjb250ZW50IG9mIHRoZSBmb3VuZCBlbGVtZW50IG9yIG51bGwgaWYgbm90IGFwcHJvcHJpYXRlLlxuICAgICAqIEBzaWduYXR1cmUgZnVuY3Rpb24oZWxlbWVudCwgcXVlcnkpXG4gICAgICovXG5cbiAgICBYTUxVdGlscy5YUGF0aEdldFNpbmdsZU5vZGVUZXh0ID0gZnVuY3Rpb24gWFBhdGhHZXRTaW5nbGVOb2RlVGV4dChlbGVtZW50LCBxdWVyeSkge1xuICAgICAgICB2YXIgbm9kZSA9IFhNTFV0aWxzLlhQYXRoU2VsZWN0U2luZ2xlTm9kZShlbGVtZW50LCBxdWVyeSk7XG4gICAgICAgIHJldHVybiBYTUxVdGlscy5nZXREb21Ob2RlVGV4dChub2RlKTtcbiAgICB9O1xuXG4gICAgWE1MVXRpbHMuZ2V0RG9tTm9kZVRleHQgPSBmdW5jdGlvbiBnZXREb21Ob2RlVGV4dChub2RlKSB7XG4gICAgICAgIHZhciBpbmNsdWRlQ0RhdGEgPSBhcmd1bWVudHMubGVuZ3RoIDw9IDEgfHwgYXJndW1lbnRzWzFdID09PSB1bmRlZmluZWQgPyBmYWxzZSA6IGFyZ3VtZW50c1sxXTtcblxuICAgICAgICBpZiAoIW5vZGUgfHwgIW5vZGUubm9kZVR5cGUpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgc3dpdGNoIChub2RlLm5vZGVUeXBlKSB7XG4gICAgICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgICAgICAgLy8gTk9ERV9FTEVNRU5UXG4gICAgICAgICAgICAgICAgdmFyIGksXG4gICAgICAgICAgICAgICAgICAgIGEgPSBbXSxcbiAgICAgICAgICAgICAgICAgICAgbm9kZXMgPSBub2RlLmNoaWxkTm9kZXMsXG4gICAgICAgICAgICAgICAgICAgIGxlbmd0aCA9IG5vZGVzLmxlbmd0aDtcbiAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgYVtpXSA9IFhNTFV0aWxzLmdldERvbU5vZGVUZXh0KG5vZGVzW2ldLCBpbmNsdWRlQ0RhdGEpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJldHVybiBhLmpvaW4oXCJcIik7XG5cbiAgICAgICAgICAgIGNhc2UgMjpcbiAgICAgICAgICAgICAgICAvLyBOT0RFX0FUVFJJQlVURVxuICAgICAgICAgICAgICAgIHJldHVybiBub2RlLnZhbHVlO1xuXG4gICAgICAgICAgICBjYXNlIDM6XG4gICAgICAgICAgICAgICAgLy8gTk9ERV9URVhUXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5vZGUubm9kZVZhbHVlO1xuXG4gICAgICAgICAgICBjYXNlIDQ6XG4gICAgICAgICAgICAgICAgLy8gQ0RBVEFcbiAgICAgICAgICAgICAgICBpZiAoaW5jbHVkZUNEYXRhKSByZXR1cm4gbm9kZS5ub2RlVmFsdWU7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQHBhcmFtIHhtbFN0clxuICAgICAqIEByZXR1cm5zIHsqfVxuICAgICAqL1xuXG4gICAgWE1MVXRpbHMucGFyc2VYbWwgPSBmdW5jdGlvbiBwYXJzZVhtbCh4bWxTdHIpIHtcblxuICAgICAgICBpZiAodHlwZW9mIHdpbmRvdy5ET01QYXJzZXIgIT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyB3aW5kb3cuRE9NUGFyc2VyKCkucGFyc2VGcm9tU3RyaW5nKHhtbFN0ciwgXCJ0ZXh0L3htbFwiKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodHlwZW9mIHdpbmRvdy5BY3RpdmVYT2JqZWN0ICE9IFwidW5kZWZpbmVkXCIgJiYgbmV3IHdpbmRvdy5BY3RpdmVYT2JqZWN0KFwiTVNYTUwyLkRPTURvY3VtZW50LjYuMFwiKSkge1xuICAgICAgICAgICAgdmFyIHhtbERvYyA9IG5ldyB3aW5kb3cuQWN0aXZlWE9iamVjdChcIk1TWE1MMi5ET01Eb2N1bWVudC42LjBcIik7XG4gICAgICAgICAgICB4bWxEb2MudmFsaWRhdGVPblBhcnNlID0gZmFsc2U7XG4gICAgICAgICAgICB4bWxEb2MuYXN5bmMgPSBmYWxzZTtcbiAgICAgICAgICAgIHhtbERvYy5sb2FkWE1MKHhtbFN0cik7XG4gICAgICAgICAgICB4bWxEb2Muc2V0UHJvcGVydHkoJ1NlbGVjdGlvbkxhbmd1YWdlJywgJ1hQYXRoJyk7XG4gICAgICAgICAgICByZXR1cm4geG1sRG9jO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IHBhcnNlIFhNTCBzdHJpbmcnKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIFhNTFV0aWxzO1xufSkoKTtcblxuZXhwb3J0c1snZGVmYXVsdCddID0gWE1MVXRpbHM7XG5tb2R1bGUuZXhwb3J0cyA9IGV4cG9ydHNbJ2RlZmF1bHQnXTtcbiJdfQ==