(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 postsJSON values[1] // => commentsJSON return values; }); ``` @class Promise @param {function} resolver Useful for tooling. @constructor */ function Promise(resolver) { this[PROMISE_ID] = nextId(); this._result = this._state = undefined; this._subscribers = []; if (noop !== resolver) { typeof resolver !== 'function' && needsResolver(); this instanceof Promise ? initializePromise(this, resolver) : needsNew(); } } Promise.all = all; Promise.race = race; Promise.resolve = resolve; Promise.reject = reject; Promise._setScheduler = setScheduler; Promise._setAsap = setAsap; Promise._asap = asap; Promise.prototype = { constructor: Promise, /** The primary way of interacting with a promise is through its `then` method, which registers callbacks to receive either a promise's eventual value or the reason why the promise cannot be fulfilled. ```js findUser().then(function(user){ // user is available }, function(reason){ // user is unavailable, and you are given the reason why }); ``` Chaining -------- The return value of `then` is itself a promise. This second, 'downstream' promise is resolved with the return value of the first promise's fulfillment or rejection handler, or rejected if the handler throws an exception. ```js findUser().then(function (user) { return user.name; }, function (reason) { return 'default name'; }).then(function (userName) { // If `findUser` fulfilled, `userName` will be the user's name, otherwise it // will be `'default name'` }); findUser().then(function (user) { throw new Error('Found user, but still unhappy'); }, function (reason) { throw new Error('`findUser` rejected and we're unhappy'); }).then(function (value) { // never reached }, function (reason) { // if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'. // If `findUser` rejected, `reason` will be '`findUser` rejected and we're unhappy'. }); ``` If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream. ```js findUser().then(function (user) { throw new PedagogicalException('Upstream error'); }).then(function (value) { // never reached }).then(function (value) { // never reached }, function (reason) { // The `PedgagocialException` is propagated all the way down to here }); ``` Assimilation ------------ Sometimes the value you want to propagate to a downstream promise can only be retrieved asynchronously. This can be achieved by returning a promise in the fulfillment or rejection handler. The downstream promise will then be pending until the returned promise is settled. This is called *assimilation*. ```js findUser().then(function (user) { return findCommentsByAuthor(user); }).then(function (comments) { // The user's comments are now available }); ``` If the assimliated promise rejects, then the downstream promise will also reject. ```js findUser().then(function (user) { return findCommentsByAuthor(user); }).then(function (comments) { // If `findCommentsByAuthor` fulfills, we'll have the value here }, function (reason) { // If `findCommentsByAuthor` rejects, we'll have the reason here }); ``` Simple Example -------------- Synchronous Example ```javascript let result; try { result = findResult(); // success } catch(reason) { // failure } ``` Errback Example ```js findResult(function(result, err){ if (err) { // failure } else { // success } }); ``` Promise Example; ```javascript findResult().then(function(result){ // success }, function(reason){ // failure }); ``` Advanced Example -------------- Synchronous Example ```javascript let author, books; try { author = findAuthor(); books = findBooksByAuthor(author); // success } catch(reason) { // failure } ``` Errback Example ```js function foundBooks(books) { } function failure(reason) { } findAuthor(function(author, err){ if (err) { failure(err); // failure } else { try { findBoooksByAuthor(author, function(books, err) { if (err) { failure(err); } else { try { foundBooks(books); } catch(reason) { failure(reason); } } }); } catch(error) { failure(err); } // success } }); ``` Promise Example; ```javascript findAuthor(). then(findBooksByAuthor). then(function(books){ // found books }).catch(function(reason){ // something went wrong }); ``` @method then @param {Function} onFulfilled @param {Function} onRejected Useful for tooling. @return {Promise} */ then: then, /** `catch` is simply sugar for `then(undefined, onRejection)` which makes it the same as the catch block of a try/catch statement. ```js function findAuthor(){ throw new Error('couldn't find that author'); } // synchronous try { findAuthor(); } catch(reason) { // something went wrong } // async with promises findAuthor().catch(function(reason){ // something went wrong }); ``` @method catch @param {Function} onRejection Useful for tooling. @return {Promise} */ 'catch': function _catch(onRejection) { return this.then(null, onRejection); } }; function polyfill() { var local = undefined; if (typeof global !== 'undefined') { local = global; } else if (typeof self !== 'undefined') { local = self; } else { try { local = Function('return this')(); } catch (e) { throw new Error('polyfill failed because global object is unavailable in this environment'); } } var P = local.Promise; if (P) { var promiseToString = null; try { promiseToString = Object.prototype.toString.call(P.resolve()); } catch (e) { // silently ignored } if (promiseToString === '[object Promise]' && !P.cast) { return; } } local.Promise = Promise; } polyfill(); // Strange compat.. Promise.polyfill = polyfill; Promise.Promise = Promise; return Promise; }))); }).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"_process":21}],2:[function(require,module,exports){ 'use strict'; var has = Object.prototype.hasOwnProperty; // // We store our EE objects in a plain object whose properties are event names. // If `Object.create(null)` is not supported we prefix the event names with a // `~` to make sure that the built-in object properties are not overridden or // used as an attack vector. // We also assume that `Object.create(null)` is available when the event name // is an ES6 Symbol. // var prefix = typeof Object.create !== 'function' ? '~' : false; /** * Representation of a single EventEmitter function. * * @param {Function} fn Event handler to be called. * @param {Mixed} context Context for function execution. * @param {Boolean} [once=false] Only emit once * @api private */ function EE(fn, context, once) { this.fn = fn; this.context = context; this.once = once || false; } /** * Minimal EventEmitter interface that is molded against the Node.js * EventEmitter interface. * * @constructor * @api public */ function EventEmitter() { /* Nothing to set */ } /** * Hold the assigned EventEmitters by name. * * @type {Object} * @private */ EventEmitter.prototype._events = undefined; /** * Return an array listing the events for which the emitter has registered * listeners. * * @returns {Array} * @api public */ EventEmitter.prototype.eventNames = function eventNames() { var events = this._events , names = [] , name; if (!events) return names; for (name in events) { if (has.call(events, name)) names.push(prefix ? name.slice(1) : name); } if (Object.getOwnPropertySymbols) { return names.concat(Object.getOwnPropertySymbols(events)); } return names; }; /** * Return a list of assigned event listeners. * * @param {String} event The events that should be listed. * @param {Boolean} exists We only need to know if there are listeners. * @returns {Array|Boolean} * @api public */ EventEmitter.prototype.listeners = function listeners(event, exists) { var evt = prefix ? prefix + event : event , available = this._events && this._events[evt]; if (exists) return !!available; if (!available) return []; if (available.fn) return [available.fn]; for (var i = 0, l = available.length, ee = new Array(l); i < l; i++) { ee[i] = available[i].fn; } return ee; }; /** * Emit an event to all registered event listeners. * * @param {String} event The name of the event. * @returns {Boolean} Indication if we've emitted an event. * @api public */ EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) { var evt = prefix ? prefix + event : event; if (!this._events || !this._events[evt]) return false; var listeners = this._events[evt] , len = arguments.length , args , i; if ('function' === typeof listeners.fn) { if (listeners.once) this.removeListener(event, listeners.fn, undefined, true); switch (len) { case 1: return listeners.fn.call(listeners.context), true; case 2: return listeners.fn.call(listeners.context, a1), true; case 3: return listeners.fn.call(listeners.context, a1, a2), true; case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true; case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true; case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true; } for (i = 1, args = new Array(len -1); i < len; i++) { args[i - 1] = arguments[i]; } listeners.fn.apply(listeners.context, args); } else { var length = listeners.length , j; for (i = 0; i < length; i++) { if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true); switch (len) { case 1: listeners[i].fn.call(listeners[i].context); break; case 2: listeners[i].fn.call(listeners[i].context, a1); break; case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break; default: if (!args) for (j = 1, args = new Array(len -1); j < len; j++) { args[j - 1] = arguments[j]; } listeners[i].fn.apply(listeners[i].context, args); } } } return true; }; /** * Register a new EventListener for the given event. * * @param {String} event Name of the event. * @param {Function} fn Callback function. * @param {Mixed} [context=this] The context of the function. * @api public */ EventEmitter.prototype.on = function on(event, fn, context) { var listener = new EE(fn, context || this) , evt = prefix ? prefix + event : event; if (!this._events) this._events = prefix ? {} : Object.create(null); if (!this._events[evt]) this._events[evt] = listener; else { if (!this._events[evt].fn) this._events[evt].push(listener); else this._events[evt] = [ this._events[evt], listener ]; } return this; }; /** * Add an EventListener that's only called once. * * @param {String} event Name of the event. * @param {Function} fn Callback function. * @param {Mixed} [context=this] The context of the function. * @api public */ EventEmitter.prototype.once = function once(event, fn, context) { var listener = new EE(fn, context || this, true) , evt = prefix ? prefix + event : event; if (!this._events) this._events = prefix ? {} : Object.create(null); if (!this._events[evt]) this._events[evt] = listener; else { if (!this._events[evt].fn) this._events[evt].push(listener); else this._events[evt] = [ this._events[evt], listener ]; } return this; }; /** * Remove event listeners. * * @param {String} event The event we want to remove. * @param {Function} fn The listener that we need to find. * @param {Mixed} context Only remove listeners matching this context. * @param {Boolean} once Only remove once listeners. * @api public */ EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) { var evt = prefix ? prefix + event : event; if (!this._events || !this._events[evt]) return this; var listeners = this._events[evt] , events = []; if (fn) { if (listeners.fn) { if ( listeners.fn !== fn || (once && !listeners.once) || (context && listeners.context !== context) ) { events.push(listeners); } } else { for (var i = 0, length = listeners.length; i < length; i++) { if ( listeners[i].fn !== fn || (once && !listeners[i].once) || (context && listeners[i].context !== context) ) { events.push(listeners[i]); } } } } // // Reset the array, or remove it completely if we have no more listeners. // if (events.length) { this._events[evt] = events.length === 1 ? events[0] : events; } else { delete this._events[evt]; } return this; }; /** * Remove all listeners or only the listeners for the specified event. * * @param {String} event The event want to remove all listeners for. * @api public */ EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) { if (!this._events) return this; if (event) delete this._events[prefix ? prefix + event : event]; else this._events = prefix ? {} : Object.create(null); return this; }; // // Alias methods names because people roll like that. // EventEmitter.prototype.off = EventEmitter.prototype.removeListener; EventEmitter.prototype.addListener = EventEmitter.prototype.on; // // This function doesn't apply anymore. // EventEmitter.prototype.setMaxListeners = function setMaxListeners() { return this; }; // // Expose the prefix. // EventEmitter.prefixed = prefix; // // Expose the module. // if ('undefined' !== typeof module) { module.exports = EventEmitter; } },{}],3:[function(require,module,exports){ (function(){var g={}; (function(window){var k,aa=this;aa.cd=!0;function m(a,b){var c=a.split("."),d=aa;c[0]in d||!d.execScript||d.execScript("var "+c[0]);for(var e;c.length&&(e=c.shift());)c.length||void 0===b?d[e]?d=d[e]:d=d[e]={}:d[e]=b}function ba(a){var b=p;function c(){}c.prototype=b.prototype;a.kd=b.prototype;a.prototype=new c;a.prototype.constructor=a;a.dd=function(a,c,f){return b.prototype[c].apply(a,Array.prototype.slice.call(arguments,2))}};/* Copyright 2016 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ function ca(a){this.c=Math.exp(Math.log(.5)/a);this.b=this.a=0}function da(a,b,c){var d=Math.pow(a.c,b);a.a=c*(1-d)+d*a.a;a.b+=b}function ea(a){return a.a/(1-Math.pow(a.c,a.b))};function fa(){this.c=new ca(2);this.f=new ca(5);this.a=0;this.b=5E5}function ga(a){return 128E3>a.a?a.b:Math.min(ea(a.c),ea(a.f))};function ha(){}function ia(){};function ja(){this.h=null;this.f=!1;this.b=new fa;this.g={};this.a={};this.i=!1;this.c=null}m("shaka.abr.SimpleAbrManager",ja);k=ja.prototype;k.stop=function(){this.h=null;this.f=!1;this.g={};this.a={};this.c=null};k.init=function(a){this.h=a}; k.chooseStreams=function(a){for(var b in a)this.g[b]=a[b];b={};if("audio"in a){var c=ka(this);c?(b.audio=c,this.a.audio=c):delete this.a.audio}"video"in a&&((c=la(this))?(b.video=c,this.a.video=c):delete this.a.video);"text"in a&&(b.text=a.text.streams[0]);this.c=Date.now();return b};k.enable=function(){this.f=!0};k.disable=function(){this.f=!1}; k.segmentDownloaded=function(a,b,c){var d=this.b;b-=a;16E3>c||(a=8E3*c/b,b/=1E3,d.a+=c,da(d.c,b,a),da(d.f,b,a));if(null!=this.c&&this.f)a:{if(!this.i){if(!(128E3<=this.b.a))break a;this.i=!0}else if(8E3>Date.now()-this.c)break a;c={};if(d=ka(this))c.audio=d,this.a.audio=d;if(d=la(this))c.video=d,this.a.video=d;this.c=Date.now();this.h(c)}};k.getBandwidthEstimate=function(){return ga(this.b)};k.setDefaultEstimate=function(a){this.b.b=a}; function ka(a){a=a.g.audio;if(!a)return null;a=ma(a);return a[Math.floor(a.length/2)]}function la(a){var b=a.g.video;if(!b)return null;var b=ma(b),c=a.a.audio,c=c&&c.bandwidth||0;a=ga(a.b);for(var d=b[0],e=0;e=(f.bandwidth+c)/.95&&a<=g&&(d=f))}return d} function ma(a){return a.streams.slice(0).filter(function(a){return a.allowedByApplication&&a.allowedByKeySystem}).sort(function(a,c){return a.bandwidth-c.bandwidth})};var na=/^(?:([^:/?#.]+):)?(?:\/\/(?:([^/?#]*)@)?([^/#?]*?)(?::([0-9]+))?(?=[/#?]|$))?([^?#]+)?(?:\?([^#]*))?(?:#(.*))?$/;function oa(a){var b;a instanceof oa?(pa(this,a.R),this.ka=a.ka,this.T=a.T,qa(this,a.wa),this.O=a.O,ra(this,sa(a.a)),this.ca=a.ca):a&&(b=String(a).match(na))?(pa(this,b[1]||"",!0),this.ka=ta(b[2]||""),this.T=ta(b[3]||"",!0),qa(this,b[4]),this.O=ta(b[5]||"",!0),ra(this,b[6]||"",!0),this.ca=ta(b[7]||"")):this.a=new ua(null)}k=oa.prototype;k.R="";k.ka="";k.T="";k.wa=null;k.O="";k.ca=""; k.toString=function(){var a=[],b=this.R;b&&a.push(va(b,wa,!0),":");if(b=this.T){a.push("//");var c=this.ka;c&&a.push(va(c,wa,!0),"@");a.push(encodeURIComponent(b).replace(/%25([0-9a-fA-F]{2})/g,"%$1"));b=this.wa;null!=b&&a.push(":",String(b))}if(b=this.O)this.T&&"/"!=b.charAt(0)&&a.push("/"),a.push(va(b,"/"==b.charAt(0)?xa:ya,!0));(b=this.a.toString())&&a.push("?",b);(b=this.ca)&&a.push("#",va(b,za));return a.join("")}; k.resolve=function(a){var b=new oa(this);"data"===b.R&&(b=new oa);var c=!!a.R;c?pa(b,a.R):c=!!a.ka;c?b.ka=a.ka:c=!!a.T;c?b.T=a.T:c=null!=a.wa;var d=a.O;if(c)qa(b,a.wa);else if(c=!!a.O){if("/"!=d.charAt(0))if(this.T&&!this.O)d="/"+d;else{var e=b.O.lastIndexOf("/");-1!=e&&(d=b.O.substr(0,e+1)+d)}if(".."==d||"."==d)d="";else if(-1!=d.indexOf("./")||-1!=d.indexOf("/.")){for(var e=!d.lastIndexOf("/",0),d=d.split("/"),f=[],g=0;gb)throw Error("Bad port number "+b);a.wa=b}else a.wa=null}function ra(a,b,c){b instanceof ua?a.a=b:(c||(b=va(b,Aa)),a.a=new ua(b))}function ta(a,b){return a?b?decodeURI(a):decodeURIComponent(a):""} function va(a,b,c){return"string"==typeof a?(a=encodeURI(a).replace(b,Ba),c&&(a=a.replace(/%25([0-9a-fA-F]{2})/g,"%$1")),a):null}function Ba(a){a=a.charCodeAt(0);return"%"+(a>>4&15).toString(16)+(a&15).toString(16)}var wa=/[#\/\?@]/g,ya=/[\#\?:]/g,xa=/[\#\?]/g,Aa=/[\#\?@]/g,za=/#/g;function ua(a){this.b=a||null}ua.prototype.a=null;ua.prototype.c=null; ua.prototype.toString=function(){if(this.b)return this.b;if(!this.a)return"";var a=[],b;for(b in this.a)for(var c=encodeURIComponent(b),d=this.a[b],e=0;e=a[b]}.bind(null,b);if(b[0]||b[2]){if(!b[1]&&!b[3])return Qa(a,!0);if(c(0)&&c(1)&&c(2)&&c(3))return D(a)}else return Qa(a,!1);throw new q(2,2003);} function Sa(a){a=unescape(encodeURIComponent(a));for(var b=new Uint8Array(a.length),c=0;cc||d&&1E3>c)this.a.splice(b,1),a.close();Va(this.v)}};k.vc=function(){Oa(this.w,function(a,b){return"expired"==b})&&this.g(new q(6,6014));this.J(this.w)}; function qb(){var a=[],b=[{contentType:'video/mp4; codecs="avc1.42E01E"'},{contentType:'video/webm; codecs="vp8"'}],c=[{videoCapabilities:b,persistentState:"required",sessionTypes:["persistent-license"]},{videoCapabilities:b}],d={};"org.w3.clearkey com.widevine.alpha com.microsoft.playready com.apple.fps.2_0 com.apple.fps.1_0 com.apple.fps com.adobe.primetime".split(" ").forEach(function(b){var f=navigator.requestMediaKeySystemAccess(b,c).then(function(a){return a.createMediaKeys()}).then(function(a){var c= !1;try{a.createSession("persistent-license"),c=!0}catch(f){}d[b]={persistentState:c}},function(){d[b]=null});a.push(f)});return Promise.all(a).then(function(){return d})};var rb={},sb={};m("shaka.media.ManifestParser.registerParserByExtension",function(a,b){sb[a]=b});m("shaka.media.ManifestParser.registerParserByMime",function(a,b){rb[a]=b});function tb(){var a={},b;for(b in rb)a[b]=!0;for(b in sb)a[b]=!0;["application/dash+xml","application/x-mpegurl","application/vnd.apple.mpegurl","application/vnd.ms-sstr+xml"].forEach(function(b){a[b]=!!rb[b]});["mpd","m3u8","ism"].forEach(function(b){a[b]=!!sb[b]});return a} function ub(a,b,c,d){var e=d;e||(d=(new oa(a)).O.split("/").pop().split("."),1=b?null:new xb(a,b,c)}m("shaka.media.TextEngine.makeCue",wb);var xb=window.VTTCue||window.TextTrackCue;vb.prototype.o=function(){this.c&&yb(this,function(){return!0});this.c=this.g=null;return Promise.resolve()}; function zb(a,b,c,d){var e=a.h;return Promise.resolve().then(function(){if(this.c){var a=this.g(b,e,c,d,this.i);if(null!=c&&null!=d){for(var g=0;g=this.f);++g)this.c.addCue(a[g]);null==this.b&&(this.b=c);this.a=Math.min(d,this.f)}}}.bind(a))} vb.prototype.remove=function(a,b){return Promise.resolve().then(function(){this.c&&(yb(this,function(c){return c.startTime>=b||c.endTime<=a?!1:!0}),null==this.b||b<=this.b||a>=this.a||(a<=this.b&&b>=this.a?this.b=this.a=null:a<=this.b&&bthis.b&&b>=this.a&&(this.a=a)))}.bind(this))};function Ab(a,b){return null==a.a||a.aa.end(0)-a.start(0)?null:a.length?a.end(a.length-1):null}function Cb(a,b){var c=0;if(!a||1==a.length&&1E-6>a.end(0)-a.start(0))return c;for(var d=!1,e=0;e=a.start(e)&&b=a.start(e)-a.end(e-1))c+=a.end(e)-a.start(e),c+=a.start(e)-a.end(e-1);else if(0=a.end(e-1))if(.04>=a.start(e)-b)c+=a.end(e)-b,d=!0;else break;else d=!1;return c};function Db(a,b,c){this.g=a;this.f=b;this.j=c;this.c={};this.b=null;this.a={};this.h=new z;this.i=!1} function Eb(){var a={};'video/mp4; codecs="avc1.42E01E",audio/mp4; codecs="mp4a.40.2",video/webm; codecs="vp8",video/webm; codecs="vp9",audio/webm; codecs="vorbis",audio/webm; codecs="opus",video/mp2t; codecs="avc1.42E01E",video/mp2t; codecs="mp4a.40.2",text/vtt,application/mp4; codecs="wvtt",application/ttml+xml,application/mp4; codecs="stpp"'.split(",").forEach(function(b){a[b]=!!E[b]||MediaSource.isTypeSupported(b);var c=b.split(";")[0];a[c]=a[c]||a[b]});return a}k=Db.prototype; k.o=function(){this.i=!0;var a=[],b;for(b in this.a){var c=this.a[b],d=c[0];this.a[b]=c.slice(0,1);d&&a.push(d.p["catch"](v));for(d=1;dc.end(0)-c.start(0)?null:1==c.length&&0>c.start(0)?0:c.length?c.start(0):null);return c} function Hb(a,b,c){"text"==b?(b=Ab(a.b,c),b||(b=Ab(a.b,c+.1))&&(b+=.1)):(a=Gb(a,b),b=Cb(a,c),b||(b=Cb(a,c+.1))&&(b+=.1));return b}function Gb(a,b){try{return a.c[b].buffered}catch(c){return null}}function Ib(a,b,c,d,e){return"text"==b?zb(a.b,c,d,e):Jb(a,b,a.Rc.bind(a,b,c))}k.remove=function(a,b,c){return"text"==a?this.b.remove(b,c):Jb(this,a,this.xb.bind(this,a,b,c))}; function Kb(a,b){return"text"==b?a.b.remove(0,Infinity):Promise.all([Jb(a,b,a.xb.bind(a,b,0,a.f.duration)),Jb(a,b,a.Rb.bind(a,b))])}function Lb(a,b,c){return"text"==b?(a.b.h=c,Promise.resolve()):Jb(a,b,a.Hc.bind(a,b,c))}function Mb(a,b,c){return"text"==b?(a.b.f=c,Promise.resolve()):Promise.all([Jb(a,b,a.Ib.bind(a,b)),Jb(a,b,a.Fc.bind(a,b,c))])}k.endOfStream=function(a){return Nb(this,function(){a?this.f.endOfStream(a):this.f.endOfStream()}.bind(this))}; k.za=function(a){return Nb(this,function(){this.f.duration=a}.bind(this))};k.da=function(){return this.f.duration};k.Rc=function(a,b){this.c[a].appendBuffer(b)};k.xb=function(a,b,c){c<=b?this.va(a):this.c[a].remove(b,c)};k.Ib=function(a){var b=this.c[a].appendWindowEnd;this.c[a].abort();this.c[a].appendWindowEnd=b;this.va(a)};k.Rb=function(a){this.g.currentTime-=.001;this.va(a)};k.Hc=function(a,b){this.c[a].timestampOffset=b;this.va(a)};k.Fc=function(a,b){this.c[a].appendWindowEnd=b+.04;this.va(a)}; k.Sc=function(a){this.a[a][0].p.reject(new q(3,3014,this.g.error?this.g.error.code:0))};k.va=function(a){var b=this.a[a][0];b&&(b.p.resolve(),Ob(this,a))};function Jb(a,b,c){if(a.i)return Promise.reject();c={start:c,p:new w};a.a[b].push(c);if(1==a.a[b].length)try{c.start()}catch(d){"QuotaExceededError"==d.name?c.p.reject(new q(3,3017,b)):c.p.reject(new q(3,3015,d)),Ob(a,b)}return c.p} function Nb(a,b){if(a.i)return Promise.reject();var c=[],d;for(d in a.c){var e=new w,f={start:function(a){a.resolve()}.bind(null,e),p:e};a.a[d].push(f);c.push(e);1==a.a[d].length&&f.start()}return Promise.all(c).then(function(){var a,c;try{b()}catch(d){c=Promise.reject(new q(3,3015,d))}for(a in this.c)Ob(this,a);return c}.bind(a),function(){return Promise.reject()}.bind(a))}function Ob(a,b){a.a[b].shift();var c=a.a[b][0];if(c)try{c.start()}catch(d){c.p.reject(new q(3,3015,d)),Ob(a,b)}};function Pb(a,b,c){this.a=a;this.L=b;this.D=c}m("shaka.media.InitSegmentReference",Pb);function F(a,b,c,d,e,f){this.position=a;this.startTime=b;this.endTime=c;this.a=d;this.L=e;this.D=f}m("shaka.media.SegmentReference",F);function G(a,b){this.j=a;this.i=b;this.c=this.a=Infinity;this.b=1;this.h=this.f=0;this.g=!0}m("shaka.media.PresentationTimeline",G);G.prototype.da=function(){return this.a};G.prototype.getDuration=G.prototype.da;G.prototype.za=function(a){this.a=a};G.prototype.setDuration=G.prototype.za;G.prototype.Bb=function(a){this.h=a};G.prototype.setClockOffset=G.prototype.Bb;G.prototype.Eb=function(a){this.g=a};G.prototype.setStatic=G.prototype.Eb;G.prototype.Ub=function(){return this.c}; G.prototype.getSegmentAvailabilityDuration=G.prototype.Ub;G.prototype.Db=function(a){this.c=a};G.prototype.setSegmentAvailabilityDuration=G.prototype.Db;G.prototype.Ea=function(a,b){b.length&&(this.b=b.reduce(function(a,b){return Math.max(a,b.endTime-b.startTime)},this.b),a||(this.f=Math.max(this.f,b[0].startTime)))};G.prototype.notifySegments=G.prototype.Ea;G.prototype.Va=function(a){this.b=Math.max(this.b,a)};G.prototype.notifyMaxSegmentDuration=G.prototype.Va; G.prototype.U=function(){return Infinity==this.a&&!this.g};G.prototype.isLive=G.prototype.U;G.prototype.fa=function(){return Infinity!=this.a&&!this.g};G.prototype.isInProgress=G.prototype.fa;G.prototype.ra=function(){return Math.max(Math.min(this.f,this.ea()),this.sa())};G.prototype.getEarliestStart=G.prototype.ra;G.prototype.sa=function(){return Infinity==this.c?0:Math.max(0,this.ea()-this.c-this.i)};G.prototype.getSegmentAvailabilityStart=G.prototype.sa; G.prototype.ea=function(){return this.U()||this.fa()?Math.min(Math.max(0,(Date.now()+this.h)/1E3-this.b-this.j),this.a):this.a};G.prototype.getSegmentAvailabilityEnd=G.prototype.ea;G.prototype.Ra=function(){return Math.max(0,this.ea()-(this.U()||this.fa()?this.i:0))};G.prototype.getSeekRangeEnd=G.prototype.Ra;function Qb(a,b,c,d,e,f){this.a=a;this.c=b;this.j=c;this.s=d;this.l=e;this.m=f;this.b=new z;this.g=!1;this.h=1;this.i=this.f=null;0a.c.da()?a.c.ra():Math.max(a.c.Ra(),a.c.ra())}function Wb(a,b){b!=a.g&&(a.g=b,Xb(a,a.h),a.l(b))}function Rb(a){Sb(a);a.i=window.setTimeout(a.mc.bind(a),250)}function Sb(a){a.i&&(window.clearTimeout(a.i),a.i=null)}k.mc=function(){this.i=null;Rb(this);var a=Cb(this.a.buffered,this.a.currentTime),b=Bb(this.a.buffered)>=this.a.duration-.05||this.a.ended;this.g?(b||a>this.j)&&Wb(this,!1):!b&&.5>a&&Wb(this,!0)};k.Qa=function(){return this.h}; function Xb(a,b){null!=a.f&&(window.clearInterval(a.f),a.f=null);a.h=b;a.a.playbackRate=a.g||0>b?0:b;!a.g&&0>b&&(a.f=window.setInterval(function(){this.a.currentTime+=b/4}.bind(a),250))}k.ic=function(){this.a.playbackRate!=(this.g||0>this.h?0:this.h)&&Xb(this,this.a.playbackRate)}; k.ob=function(){this.b.ja(this.a,"loadedmetadata");var a=Vb(this);.001>Math.abs(this.a.currentTime-a)?(B(this.b,this.a,"seeking",this.qb.bind(this)),B(this.b,this.a,"playing",this.pb.bind(this))):(B(this.b,this.a,"seeking",this.kc.bind(this)),this.a.currentTime=a)};k.kc=function(){this.b.ja(this.a,"seeking");B(this.b,this.a,"seeking",this.qb.bind(this));B(this.b,this.a,"playing",this.pb.bind(this))};k.qb=function(){var a=this.a.currentTime,b=Yb(this,a);.001e?e:b;c=d+1;d=c+a.j;return b>=d&&b<=e||Cb(a.a.buffered,b)&&b>=c&&b<=e?b:b>e?e:e=c&&b<=e?b:Math.min(d+2,e)}function Zb(a,b,c){a.a.currentTime=c;var d=0,e=function(){!this.a||10<=d++||this.a.currentTime!=b||(this.a.currentTime=c,setTimeout(e,100))}.bind(a);setTimeout(e,100)} function Ub(a,b){var c=a.c.ra();if(bc?c:b};function $b(a,b,c,d,e,f,g,h,l){this.m=a;this.f=b;this.S=c;this.a=d;this.G=e;this.v=f;this.j=g;this.w=h||null;this.A=l||null;this.g=null;this.i=1;this.C=Promise.resolve();this.h=[];this.l={};this.b={};this.c=this.s=this.J=!1}$b.prototype.o=function(){for(var a in this.b)ac(this.b[a]);this.g=this.b=this.l=this.h=this.A=this.w=this.j=this.v=this.G=this.C=this.a=this.S=this.f=this.m=null;this.c=!0;return Promise.resolve()}; $b.prototype.configure=function(a){this.g=a;this.m.j=this.i*Math.max(this.a.minBufferTime||0,this.g.rebufferingGoal)};$b.prototype.init=function(){var a=this.G(this.a.periods[bc(this,Tb(this.m))]);return Ma(a)?Promise.reject(new q(5,5005)):cc(this,a).then(function(){this.w&&this.w()}.bind(this))};function dc(a){return a.a.periods[bc(a,Tb(a.m))]}function ec(a){return Na(a.b,function(a){return a.stream})}function fc(a,b){var c={};c.text=b;return cc(a,c)} function gc(a,b,c,d){var e=a.b[b];!e&&"text"==b&&a.g.ignoreTextStreamFailures?fc(a,c):e&&(b=a.h[hc(a,c)])&&b.xa&&(b=a.l[c.id])&&b.xa&&e.stream!=c&&(e.stream=c,e.Ja=!0,d&&!e.ba&&(e.ga?e.la=!0:(ac(e),ic(a,e))))} function cc(a,b){var c=bc(a,Tb(a.m)),d=Na(b,function(a){return a.mimeType+(a.codecs?'; codecs="'+a.codecs+'"':"")});a.f.init(d,a.g.useRelativeCueTimestamps);jc(a);d=C(b);return kc(a,d).then(function(){if(!this.c)for(var a in b){var d=b[a];this.b[a]||(this.b[a]={stream:d,type:a,ta:null,V:null,Ja:!0,Ka:c,endOfStream:!1,ga:!1,aa:null,la:!1,ba:!1,Za:!1},lc(this,this.b[a],0))}}.bind(a))} function mc(a,b){var c=a.h[b];if(c)return c.I;c={I:new w,xa:!1};a.h[b]=c;var d=a.a.periods[b].streamSets.map(function(a){return a.streams}).reduce(u,[]);a.C=a.C.then(function(){if(!this.c)return kc(this,d)}.bind(a)).then(function(){this.c||(this.h[b].I.resolve(),this.h[b].xa=!0)}.bind(a))["catch"](function(a){this.c||(this.h[b].I.reject(),delete this.h[b],this.j(a))}.bind(a));return c.I} function kc(a,b){for(var c=[],d=0;db?a.f.za(b):a.f.za(Math.pow(2,32))} $b.prototype.X=function(a){if(!this.c&&!a.ga&&null!=a.aa&&!a.ba)if(a.aa=null,a.la)ic(this,a);else{try{var b=nc(this,a);null!=b&&lc(this,a,b)}catch(c){this.j(c);return}b=C(this.b);oc(this,a);b.every(function(a){return a.endOfStream})&&this.f.endOfStream()}}; function nc(a,b){var c=Tb(a.m),d,e;e=a.f;var f=b.type;e="text"==f?e.b.a:Bb(Gb(e,f));var f=b.ta&&b.V?a.a.periods[hc(a,b.ta)].startTime+b.V.endTime:c,g=hc(a,b.stream),h=bc(a,f),l=a.a.periods[h];g!=h?d=null:d=pc(a,b,c,e,h);if((d?l.startTime+d.startTime-c:Hb(a.f,b.type,c))>=Math.max(a.i*Math.max(a.a.minBufferTime||0,a.g.rebufferingGoal),a.i*a.g.bufferingGoal))return.5;if(f>=a.a.presentationTimeline.da())return b.endOfStream=!0,null;b.endOfStream=!1;if(h!=g)return b.Ka=h,null;d=pc(a,b,c,e,g);if(!d)return 1; qc(a,b,c,g,d);return null}function pc(a,b,c,d,e){if(b.V&&b.stream==b.ta)return c=b.V.position+1,rc(a,b,e,c);c=b.V?b.stream.findSegmentPosition(Math.max(0,a.a.periods[hc(a,b.ta)].startTime+b.V.endTime-a.a.periods[e].startTime)):b.stream.findSegmentPosition(Math.max(0,(d||c)-a.a.periods[e].startTime));if(null==c)return null;var f=null;null==d&&(f=rc(a,b,e,Math.max(0,c-1)));return f||rc(a,b,e,c)} function rc(a,b,c,d){c=a.a.periods[c];b=b.stream.getSegmentReference(d);if(!b)return null;a=a.a.presentationTimeline;d=a.ea();return c.startTime+b.endTimed?null:b} function qc(a,b,c,d,e){var f=a.a.periods[d],g=b.stream,h=a.a.periods[d+1],l=null,l=h?h.startTime:a.a.presentationTimeline.da();d=sc(a,b,d,l);b.ga=!0;b.Ja=!1;h=tc(a,e);Promise.all([d,h]).then(function(a){if(!this.c&&!this.s)return uc(this,b,c,f,g,e,a[1])}.bind(a)).then(function(){this.c||this.s||(b.ga=!1,b.Za=!1,lc(this,b,0),vc(this,g))}.bind(a))["catch"](function(a){this.c||this.s||(b.ga=!1,1001==a.code||1002==a.code||1003==a.code?"text"==b.type&&this.g.ignoreTextStreamFailures&&1001==a.code?delete this.b.text: (this.j(a),lc(this,b,4)):3017==a.code?wc(this,b,a):this.j(a))}.bind(a))}function wc(a,b,c){if(!C(a.b).some(function(a){return a!=b&&a.Za})){var d=Math.round(100*a.i);if(20=c?Promise.resolve():a.f.remove(b.type,d,d+c).then(function(){}.bind(a))} function vc(a,b){if(!a.J&&(a.J=C(a.b).every(function(a){return!a.la&&!a.ba&&a.V}),a.J)){var c=hc(a,b);a.h[c]||mc(a,c).then(function(){this.v()}.bind(a))["catch"](v);for(c=0;c=a.a.periods[c].startTime)return c;return 0}function hc(a,b){for(var c=0;c=Ec&&c==b.split("-")[0]||a>=Fc&&c.split("-")[0]==b.split("-")[0]?!0:!1}var Ec=1,Fc=2;function Gc(a){a=a.toLowerCase().split("-");var b=Hc[a[0]];b&&(a[0]=b);return a.join("-")} var Hc={aar:"aa",abk:"ab",afr:"af",aka:"ak",alb:"sq",amh:"am",ara:"ar",arg:"an",arm:"hy",asm:"as",ava:"av",ave:"ae",aym:"ay",aze:"az",bak:"ba",bam:"bm",baq:"eu",bel:"be",ben:"bn",bih:"bh",bis:"bi",bod:"bo",bos:"bs",bre:"br",bul:"bg",bur:"my",cat:"ca",ces:"cs",cha:"ch",che:"ce",chi:"zh",chu:"cu",chv:"cv",cor:"kw",cos:"co",cre:"cr",cym:"cy",cze:"cs",dan:"da",deu:"de",div:"dv",dut:"nl",dzo:"dz",ell:"el",eng:"en",epo:"eo",est:"et",eus:"eu",ewe:"ee",fao:"fo",fas:"fa",fij:"fj",fin:"fi",fra:"fr",fre:"fr", fry:"fy",ful:"ff",geo:"ka",ger:"de",gla:"gd",gle:"ga",glg:"gl",glv:"gv",gre:"el",grn:"gn",guj:"gu",hat:"ht",hau:"ha",heb:"he",her:"hz",hin:"hi",hmo:"ho",hrv:"hr",hun:"hu",hye:"hy",ibo:"ig",ice:"is",ido:"io",iii:"ii",iku:"iu",ile:"ie",ina:"ia",ind:"id",ipk:"ik",isl:"is",ita:"it",jav:"jv",jpn:"ja",kal:"kl",kan:"kn",kas:"ks",kat:"ka",kau:"kr",kaz:"kk",khm:"km",kik:"ki",kin:"rw",kir:"ky",kom:"kv",kon:"kg",kor:"ko",kua:"kj",kur:"ku",lao:"lo",lat:"la",lav:"lv",lim:"li",lin:"ln",lit:"lt",ltz:"lb",lub:"lu", lug:"lg",mac:"mk",mah:"mh",mal:"ml",mao:"mi",mar:"mr",may:"ms",mkd:"mk",mlg:"mg",mlt:"mt",mon:"mn",mri:"mi",msa:"ms",mya:"my",nau:"na",nav:"nv",nbl:"nr",nde:"nd",ndo:"ng",nep:"ne",nld:"nl",nno:"nn",nob:"nb",nor:"no",nya:"ny",oci:"oc",oji:"oj",ori:"or",orm:"om",oss:"os",pan:"pa",per:"fa",pli:"pi",pol:"pl",por:"pt",pus:"ps",que:"qu",roh:"rm",ron:"ro",rum:"ro",run:"rn",rus:"ru",sag:"sg",san:"sa",sin:"si",slk:"sk",slo:"sk",slv:"sl",sme:"se",smo:"sm",sna:"sn",snd:"sd",som:"so",sot:"st",spa:"es",sqi:"sq", srd:"sc",srp:"sr",ssw:"ss",sun:"su",swa:"sw",swe:"sv",tah:"ty",tam:"ta",tat:"tt",tel:"te",tgk:"tg",tgl:"tl",tha:"th",tib:"bo",tir:"ti",ton:"to",tsn:"tn",tso:"ts",tuk:"tk",tur:"tr",twi:"tw",uig:"ug",ukr:"uk",urd:"ur",uzb:"uz",ven:"ve",vie:"vi",vol:"vo",wel:"cy",wln:"wa",wol:"wo",xho:"xh",yid:"yi",yor:"yo",zha:"za",zho:"zh",zul:"zu"};function Ic(a,b,c){var d=!1;a.streamSets.forEach(function(a){a.streams.forEach(function(f){var g=f.allowedByApplication;f.allowedByApplication=!0;if("video"==a.type){if(f.widthb.maxWidth||f.width>c.width||f.heightb.maxHeight||f.height>c.height||f.width*f.heightb.maxPixels||f.bandwidthb.maxVideoBandwidth)f.allowedByApplication=!1}else"audio"==a.type&&(f.bandwidth b.maxAudioBandwidth)&&(f.allowedByApplication=!1);g!=f.allowedByApplication&&(d=!0)})});return d} function Jc(a,b,c){var d="",e=null;a&&a.A&&(d=a.keySystem(),e=a.m);for(a=0;ae.indexOf(n)?(f.streams.splice(h,1),--h):!g||l.mimeType==g.mimeType&&l.codecs.split(".")[0]== g.codecs.split(".")[0]||(f.streams.splice(h,1),--h):(f.streams.splice(h,1),--h)}f.streams.length||(c.streamSets.splice(a,1),--a)}}} function Kc(a,b){return a.streamSets.map(function(a){var d=b?b[a.type]:null;return a.streams.filter(function(a){return a.allowedByApplication&&a.allowedByKeySystem}).map(function(b){return{id:b.id,active:d==b,type:a.type,bandwidth:b.bandwidth,language:a.language,kind:b.kind||null,width:b.width||null,height:b.height||null,frameRate:b.frameRate||void 0,codecs:b.codecs||null}})}).reduce(u,[])} function Lc(a,b){for(var c=0;ce?(e=b,d.video=a):b==e&&Pc(a)a.streams.length)return b;a.streams.forEach(function(a){b+=a.bandwidth});return b/a.streams.length}function Oc(a){var b=0;if(!a)return b;a.streams.forEach(function(a){a.height>b&&(b=a.height)});return b};function I(a,b){p.call(this);this.w=!1;this.f=a;this.m=null;this.v=new z;this.fb=new ja;this.na=this.c=this.l=this.b=this.i=this.oa=this.G=this.A=this.g=this.h=null;this.Hb=1E9;this.ma=[];this.Na=!1;this.qa=!0;this.j=null;this.s={};this.a=Qc(this);this.Ba={width:Infinity,height:Infinity};this.C=[];this.X=this.J=this.pa=0;b&&b(this);this.h=new y(this.Mc.bind(this));this.oa=Rc(this);for(var c=0;cthis.ma.indexOf(a.id)}.bind(this))};I.prototype.getTracks=I.prototype.getTracks; I.prototype.Ec=function(a,b){if(this.b){var c=Lc(dc(this.b),a);if(c){var d=c.stream;d.allowedByApplication&&d.allowedByKeySystem&&(this.C.push({timestamp:Date.now()/1E3,id:d.id,type:a.type,fromAdaptation:!1}),c={},c[a.type]=d,"text"!=a.type&&(d=ec(this.b).text,this.configure({abr:{enabled:!1}}),c.text=d),Zc(this,c,b))}}};I.prototype.selectTrack=I.prototype.Ec;I.prototype.Zb=function(){return"showing"==this.m.mode};I.prototype.isTextTrackVisible=I.prototype.Zb; I.prototype.Gc=function(a){this.m.mode=a?"showing":"hidden";$c(this)};I.prototype.setTextTrackVisibility=I.prototype.Gc; I.prototype.getStats=function(){ad(this);var a={},b={},c=this.f&&this.f.getVideoPlaybackQuality?this.f.getVideoPlaybackQuality():{};this.b&&(b=ec(this.b),a=b.video||{},b=b.audio||{});return{width:a.width||0,height:a.height||0,streamBandwidth:a.bandwidth+b.bandwidth||0,decodedFrames:Number(c.totalVideoFrames),droppedFrames:Number(c.droppedVideoFrames),estimatedBandwidth:this.a.abr.manager.getBandwidthEstimate(),playTime:this.pa,bufferingTime:this.J,switchHistory:this.C.slice(0)}}; I.prototype.getStats=I.prototype.getStats; I.prototype.addTextTrack=function(a,b,c,d,e){if(!this.b)return Promise.reject();for(var f=dc(this.b),g,h=0;hb&&(b+=Math.pow(2,32)),b=b.toString(16));this.$(new q(3,3016,a,b))}}}; k.Kc=function(a){var b=["output-restricted","internal-error"],c=dc(this.b),d=!1;c.streamSets.forEach(function(c){c.streams.forEach(function(c){var e=c.allowedByKeySystem;c.keyId&&c.keyId in a&&(c.allowedByKeySystem=0>b.indexOf(a[c.keyId]));e!=c.allowedByKeySystem&&(d=!0)})});Yc(this,c);d&&Uc(this)};var dd="ended play playing pause pausing ratechange seeked seeking timeupdate volumechange".split(" "),ed="buffered currentTime duration ended loop muted paused playbackRate seeking videoHeight videoWidth volume".split(" "),fd=["loop","playbackRate"],gd=["pause","play"],hd=["adaptation","buffering","error","texttrackvisibility","trackschanged"],id="getConfiguration getManifestUri getPlaybackRate getTracks getStats isBuffering isLive isTextTrackVisible seekRange".split(" "),jd=[["getConfiguration", "configure"]],kd=[["isTextTrackVisible","setTextTrackVisibility"]],ld="configure resetConfiguration trickPlay cancelTrickPlay selectTrack setTextTrackVisibility addTextTrack".split(" "),md=["load","unload"]; function nd(a){return JSON.stringify(a,function(a,c){if("manager"!=a&&"function"!=typeof c){if(c instanceof Event||c instanceof H){var d={},e;for(e in c){var f=c[e];f&&"object"==typeof f||e in Event||(d[e]=f)}return d}if(c instanceof TimeRanges)for(d={__type__:"TimeRanges",length:c.length,start:[],end:[]},e=0;ec?"-Infinity":"Infinity":c;return d}})} function od(a){return JSON.parse(a,function(a,c){return"NaN"==c?NaN:"-Infinity"==c?-Infinity:"Infinity"==c?Infinity:c&&"object"==typeof c&&"TimeRanges"==c.__type__?pd(c):c})}function pd(a){return{length:a.length,start:function(b){return a.start[b]},end:function(b){return a.end[b]}}};function qd(a,b,c,d,e){this.C=a;this.l=b;this.w=c;this.A=d;this.s=e;this.f=this.j=this.h=!1;this.v="";this.a=this.i=null;this.b={video:{},player:{}};this.m=0;this.c={};this.g=null}k=qd.prototype;k.o=function(){rd(this);this.a&&(this.a.stop(function(){},function(){}),this.a=null);this.A=this.w=this.l=null;this.f=this.j=this.h=!1;this.g=this.c=this.b=this.a=this.i=null;return Promise.resolve()};k.N=function(){return this.f};k.Ya=function(){return this.v}; k.init=function(){if(window.chrome&&chrome.cast&&chrome.cast.isAvailable){delete window.__onGCastApiAvailable;this.h=!0;this.l();var a=new chrome.cast.SessionRequest(this.C),a=new chrome.cast.ApiConfig(a,this.cc.bind(this),this.jc.bind(this),"origin_scoped");chrome.cast.initialize(a,function(){},function(){})}else window.__onGCastApiAvailable=function(a){a&&this.init()}.bind(this)};k.$a=function(a){this.i=a;this.f&&sd(this,{type:"appData",appData:this.i})}; k.cast=function(a){if(!this.h)return Promise.reject(new q(8,8E3));if(!this.j)return Promise.reject(new q(8,8001));if(this.f)return Promise.reject(new q(8,8002));this.g=new w;chrome.cast.requestSession(this.Wa.bind(this,a),this.lb.bind(this));return this.g}; k.get=function(a,b){if("video"==a){if(0<=gd.indexOf(b))return this.wb.bind(this,a,b)}else if("player"==a){if(0<=ld.indexOf(b))return this.wb.bind(this,a,b);if(0<=md.indexOf(b))return this.yc.bind(this,a,b);if(0<=id.indexOf(b))return this.tb.bind(this,a,b)}return this.tb(a,b)};k.set=function(a,b,c){this.b[a][b]=c;sd(this,{type:"set",targetName:a,property:b,value:c})}; k.Wa=function(a,b){this.a=b;this.a.addUpdateListener(this.mb.bind(this));this.a.addMessageListener("urn:x-cast:com.google.shaka.v2",this.dc.bind(this));this.mb();sd(this,{type:"init",initState:a,appData:this.i});this.g.resolve()};k.lb=function(a){var b=8003;switch(a.code){case "cancel":b=8004;break;case "timeout":b=8005;break;case "receiver_unavailable":b=8006}this.g.reject(new q(8,b,a))};k.tb=function(a,b){return this.b[a][b]}; k.wb=function(a,b){sd(this,{type:"call",targetName:a,methodName:b,args:Array.prototype.slice.call(arguments,2)})};k.yc=function(a,b){var c=Array.prototype.slice.call(arguments,2),d=new w,e=this.m.toString();this.m++;this.c[e]=d;sd(this,{type:"asyncCall",targetName:a,methodName:b,args:c,id:e});return d};k.cc=function(a){var b=this.s();this.g=new w;this.Wa(b,a)};k.jc=function(a){this.j="available"==a;this.l()}; k.mb=function(){var a=this.a?"connected"==this.a.status:!1;if(this.f&&!a){this.A();for(var b in this.b)this.b[b]={};rd(this)}this.v=(this.f=a)?this.a.receiver.friendlyName:"";this.l()};function rd(a){for(var b in a.c){var c=a.c[b];delete a.c[b];c.reject(new q(7,7E3))}} k.dc=function(a,b){var c=od(b);switch(c.type){case "event":var d=c.targetName,e=c.event;this.w(d,new H(e.type,e));break;case "update":e=c.update;for(d in e){var c=this.b[d]||{},f;for(f in e[d])c[f]=e[d][f]}break;case "asyncComplete":if(d=c.id,f=c.error,c=this.c[d],delete this.c[d],c)if(f){d=new q(f.category,f.code);for(e in f)d[e]=f[e];c.reject(d)}else c.resolve()}};function sd(a,b){var c=nd(b);a.a.sendMessage("urn:x-cast:com.google.shaka.v2",c,function(){},ha)};function K(a,b,c){p.call(this);this.c=a;this.b=b;this.h=this.f=this.g=this.i=this.j=null;this.a=new qd(c,this.Nc.bind(this),this.Oc.bind(this),this.Pc.bind(this),this.jb.bind(this));td(this)}ba(K);m("shaka.cast.CastProxy",K);K.prototype.o=function(){var a=[this.h?this.h.o():null,this.b?this.b.o():null,this.a?this.a.o():null];this.a=this.h=this.i=this.j=this.b=this.c=null;return Promise.all(a)};K.prototype.destroy=K.prototype.o;K.prototype.Vb=function(){return this.j};K.prototype.getVideo=K.prototype.Vb; K.prototype.Tb=function(){return this.i};K.prototype.getPlayer=K.prototype.Tb;K.prototype.Jb=function(){return this.a?this.a.h&&this.a.j:!1};K.prototype.canCast=K.prototype.Jb;K.prototype.N=function(){return this.a?this.a.N():!1};K.prototype.isCasting=K.prototype.N;K.prototype.Ya=function(){return this.a?this.a.Ya():""};K.prototype.receiverName=K.prototype.Ya;K.prototype.cast=function(){var a=this.jb();return this.a.cast(a).then(function(){return this.b.eb()}.bind(this))};K.prototype.cast=K.prototype.cast; K.prototype.$a=function(a){this.a.$a(a)};K.prototype.setAppData=K.prototype.$a;K.prototype.Vc=function(){var a=this.a;if(a.f){var b=a.s();chrome.cast.requestSession(a.Wa.bind(a,b),a.lb.bind(a))}};K.prototype.suggestDisconnect=K.prototype.Vc; function td(a){a.a.init();a.h=new z;dd.forEach(function(a){B(this.h,this.c,a,this.ad.bind(this))}.bind(a));hd.forEach(function(a){B(this.h,this.b,a,this.uc.bind(this))}.bind(a));a.j={};for(var b in a.c)Object.defineProperty(a.j,b,{configurable:!1,enumerable:!0,get:a.$c.bind(a,b),set:a.bd.bind(a,b)});a.i={};for(b in a.b)Object.defineProperty(a.i,b,{configurable:!1,enumerable:!0,get:a.tc.bind(a,b)});a.g=new p;a.g.S=a.j;a.f=new p;a.f.S=a.i}k=K.prototype; k.jb=function(){var a={video:{},player:{},playerAfterLoad:{},manifest:this.b.na,startTime:null};this.c.pause();fd.forEach(function(b){a.video[b]=this.c[b]}.bind(this));this.c.ended||(a.startTime=this.c.currentTime);jd.forEach(function(b){var c=b[1];b=this.b[b[0]]();a.player[c]=b}.bind(this));kd.forEach(function(b){var c=b[1];b=this.b[b[0]]();a.playerAfterLoad[c]=b}.bind(this));return a};k.Nc=function(){this.dispatchEvent(new H("caststatuschanged"))}; k.Pc=function(){jd.forEach(function(a){var b=a[1];a=this.a.get("player",a[0])();this.b[b](a)}.bind(this));var a=this.a.get("player","getManifestUri")(),b=this.a.get("video","ended"),c=Promise.resolve(),d=this.c.autoplay,e=null;b||(e=this.a.get("video","currentTime"));a&&(this.c.autoplay=!1,c=this.b.load(a,e),c["catch"](function(a){this.b.dispatchEvent(new H("error",{detail:a}))}.bind(this)));var f={};fd.forEach(function(a){f[a]=this.a.get("video",a)}.bind(this));c.then(function(){fd.forEach(function(a){this.c[a]= f[a]}.bind(this));kd.forEach(function(a){var b=a[1];a=this.a.get("player",a[0])();this.b[b](a)}.bind(this));this.c.autoplay=d;a&&this.c.play()}.bind(this))}; k.$c=function(a){if("addEventListener"==a)return this.g.addEventListener.bind(this.g);if("removeEventListener"==a)return this.g.removeEventListener.bind(this.g);if(this.a.N()&&!Object.keys(this.a.b.video).length){var b=this.c[a];if("function"!=typeof b)return b}return this.a.N()?this.a.get("video",a):(b=this.c[a],"function"==typeof b&&(b=b.bind(this.c)),b)};k.bd=function(a,b){this.a.N()?this.a.set("video",a,b):this.c[a]=b};k.ad=function(a){this.a.N()||this.g.dispatchEvent(new H(a.type,a))}; k.tc=function(a){return"addEventListener"==a?this.f.addEventListener.bind(this.f):"removeEventListener"==a?this.f.removeEventListener.bind(this.f):"getNetworkingEngine"==a?this.b.kb.bind(this.b):this.a.N()&&!Object.keys(this.a.b.video).length&&0<=id.indexOf(a)||!this.a.N()?(a=this.b[a],a.bind(this.b)):this.a.get("player",a)};k.uc=function(a){this.a.N()||this.f.dispatchEvent(a)};k.Oc=function(a,b){this.a.N()&&("video"==a?this.g.dispatchEvent(b):"player"==a&&this.f.dispatchEvent(b))};function L(a,b,c){p.call(this);this.b=a;this.a=b;this.i={video:a,player:b};this.j=c||function(){};this.h=!1;this.c=!0;this.f=this.g=null;ud(this)}ba(L);m("shaka.cast.CastReceiver",L);L.prototype.Xb=function(){return this.h};L.prototype.isConnected=L.prototype.Xb;L.prototype.Yb=function(){return this.c};L.prototype.isIdle=L.prototype.Yb; L.prototype.o=function(){var a=this.a?this.a.o():Promise.resolve();null!=this.f&&window.clearTimeout(this.f);this.j=this.i=this.a=this.b=null;this.h=!1;this.c=!0;this.f=this.g=null;return a.then(function(){cast.receiver.CastReceiverManager.getInstance().stop()})};L.prototype.destroy=L.prototype.o; function ud(a){var b=cast.receiver.CastReceiverManager.getInstance();b.onSenderConnected=a.rb.bind(a);b.onSenderDisconnected=a.rb.bind(a);b.onSystemVolumeChanged=a.Qb.bind(a);a.g=b.getCastMessageBus("urn:x-cast:com.google.shaka.v2");a.g.onMessage=a.ec.bind(a);b.start();dd.forEach(function(a){this.b.addEventListener(a,this.ub.bind(this,"video"))}.bind(a));hd.forEach(function(a){this.a.addEventListener(a,this.ub.bind(this,"player"))}.bind(a));a.a.Cb(1920,1080);a.a.addEventListener("loading",function(){this.c= !1;vd(this)}.bind(a));a.b.addEventListener("playing",function(){this.c=!1;vd(this)}.bind(a));a.a.addEventListener("unloading",function(){this.c=!0;vd(this)}.bind(a));a.b.addEventListener("ended",function(){window.setTimeout(function(){this.b&&this.b.ended&&(this.c=!0,vd(this))}.bind(this),5E3)}.bind(a))}k=L.prototype;k.rb=function(){this.h=!!cast.receiver.CastReceiverManager.getInstance().getSenders().length;vd(this)}; function vd(a){Promise.resolve().then(function(){this.dispatchEvent(new H("caststatuschanged"))}.bind(a))} function wd(a,b,c){for(var d in b.player)a.a[d](b.player[d]);a.j(c);c=Promise.resolve();var e=a.b.autoplay;b.manifest&&(a.b.autoplay=!1,c=a.a.load(b.manifest,b.startTime),c["catch"](function(a){this.a.dispatchEvent(new H("error",{detail:a}))}.bind(a)));c.then(function(){for(var a in b.video){var c=b.video[a];this.b[a]=c}for(a in b.playerAfterLoad)c=b.playerAfterLoad[a],this.a[a](c);this.b.autoplay=e;b.manifest&&this.b.play()}.bind(a))} k.ub=function(a,b){this.Xa();xd(this,{type:"event",targetName:a,event:b})};k.Xa=function(){null!=this.f&&window.clearTimeout(this.f);this.f=window.setTimeout(this.Xa.bind(this),500);var a={video:{},player:{}};ed.forEach(function(b){a.video[b]=this.b[b]}.bind(this));id.forEach(function(b){a.player[b]=this.a[b]()}.bind(this));var b=cast.receiver.CastReceiverManager.getInstance().getSystemVolume();b&&(a.video.volume=b.level,a.video.muted=b.muted);xd(this,{type:"update",update:a})}; k.Qb=function(){var a=cast.receiver.CastReceiverManager.getInstance().getSystemVolume();a&&xd(this,{type:"update",update:{video:{volume:a.level,muted:a.muted}}});xd(this,{type:"event",targetName:"video",event:{type:"volumechange"}})}; k.ec=function(a){var b=od(a.data);switch(b.type){case "init":wd(this,b.initState,b.appData);this.Xa();break;case "appData":this.j(b.appData);break;case "set":var c=b.targetName,d=b.property,e=b.value;if("video"==c)if(b=cast.receiver.CastReceiverManager.getInstance(),"volume"==d){b.setSystemVolumeLevel(e);break}else if("muted"==d){b.setSystemVolumeMuted(e);break}this.i[c][d]=e;break;case "call":c=b.targetName;d=b.methodName;e=b.args;c=this.i[c];c[d].apply(c,e);break;case "asyncCall":c=b.targetName, d=b.methodName,e=b.args,b=b.id,a=a.senderId,c=this.i[c],c[d].apply(c,e).then(this.Ab.bind(this,a,b,null),this.Ab.bind(this,a,b))}};k.Ab=function(a,b,c){xd(this,{type:"asyncComplete",id:b,error:c},a)};function xd(a,b,c){a.h&&(b=nd(b),c?a.g.getCastChannel(c).send(b):a.g.broadcast(b))};function yd(a,b){var c=M(a,b);return 1!=c.length?null:c[0]}function M(a,b){return Array.prototype.filter.call(a.childNodes,function(a){return a.tagName==b})}function zd(a){return(a=a.firstChild)&&a.nodeType==Node.TEXT_NODE?a.nodeValue.trim():null}function N(a,b,c,d){var e=null;a=a.getAttribute(b);null!=a&&(e=c(a));return null==e?void 0!==d?d:null:e}function Ad(a){if(!a)return null;a=Date.parse(a);return isNaN(a)?null:Math.floor(a/1E3)} function O(a){if(!a)return null;a=/^P(?:([0-9]*)Y)?(?:([0-9]*)M)?(?:([0-9]*)D)?(?:T(?:([0-9]*)H)?(?:([0-9]*)M)?(?:([0-9.]*)S)?)?$/.exec(a);if(!a)return null;a=31536E3*Number(a[1]||null)+2592E3*Number(a[2]||null)+86400*Number(a[3]||null)+3600*Number(a[4]||null)+60*Number(a[5]||null)+Number(a[6]||null);return isFinite(a)?a:null}function Bd(a){var b=/([0-9]+)-([0-9]+)/.exec(a);if(!b)return null;a=Number(b[1]);if(!isFinite(a))return null;b=Number(b[2]);return isFinite(b)?{start:a,end:b}:null} function Cd(a){a=Number(a);return a%1?null:a}function Dd(a){a=Number(a);return!(a%1)&&0b||(c[c.length-1]=new F(a.position,a.startTime,b,a.a,a.L,a.D)))}}function P(a,b){if(!b.length)return a;var c=b.map(function(a){return new oa(a)});return a.map(function(a){return new oa(a)}).map(function(a){return c.map(a.resolve.bind(a))}).reduce(u,[]).map(function(a){return a.toString()})} function Qd(a,b){var c=Q(a,b,"timescale"),d=1;c&&(d=Dd(c)||1);c=Q(a,b,"duration");(c=Dd(c||""))&&(c/=d);var e=Q(a,b,"startNumber"),f=Q(a,b,"presentationTimeOffset"),g=Ed(e||"");if(null==e||null==g)g=1;var h=Rd(a,b,"SegmentTimeline"),e=null;if(h){for(var e=d,l=Number(f),n=a.H.duration||Infinity,h=M(h,"S"),r=[],t=0,A=0;Ax)if(A+1= x)break;x=Math.ceil((x-J)/kb)-1}else{if(Infinity==n)break;else if(J/e>=n)break;x=Math.ceil((n*e-J)/kb)-1}0a.b.byteLength&&Wd();var c=a.b.buffer.slice(a.a,a.a+b);a.a+=b;return new Uint8Array(c)}function S(a,b){a.a+b>a.b.byteLength&&Wd();a.a+=b} function $d(a){var b=a.a;try{for(;Ud(a)&&a.b.getUint8(a.a);)a.a+=1}catch(c){Wd()}b=a.b.buffer.slice(b,a.a);a.a+=1;return D(b)}function Wd(){throw new q(3,3E3);};function ae(a,b){for(;Ud(b);){var c=b.a,d=R(b),e=R(b);1==d?d=Yd(b):d||(d=b.b.byteLength-c);if(e==a)return d;S(b,d-(b.a-c))}return-1}function be(a,b){for(var c=new Sd(new DataView(a)),d=[[1836019574,0],[1953653099,0],[1835297121,0],[1835626086,0],[1937007212,0],[1937011556,8],[b,0]],e=-1,f=0;f>>31;l&=2147483647;var r=R(a);S(a,4);if(1==n)throw new q(3,3006);e.push(new F(e.length,d/h,(d+r)/h,function(){return c},b,b+l-1));d+=r;b+=l}return e};function T(a){this.a=a}m("shaka.media.SegmentIndex",T);T.prototype.o=function(){this.a=null;return Promise.resolve()};T.prototype.destroy=T.prototype.o;T.prototype.find=function(a){for(var b=this.a.length-1;0<=b;--b){var c=this.a[b];if(a>=c.startTime&&aa||a>=this.a.length?null:this.a[a]};T.prototype.get=T.prototype.get; T.prototype.Ua=function(a){for(var b=[],c=0,d=0;cf.startTime||(.1a);++b);this.a.splice(0,b)};T.prototype.evict=T.prototype.Pa;function de(a){this.b=a;this.a=new Sd(a);ee||(ee=[new Uint8Array([255]),new Uint8Array([127,255]),new Uint8Array([63,255,255]),new Uint8Array([31,255,255,255]),new Uint8Array([15,255,255,255,255]),new Uint8Array([7,255,255,255,255,255]),new Uint8Array([3,255,255,255,255,255,255]),new Uint8Array([1,255,255,255,255,255,255,255])])}var ee; function fe(a){var b;b=ge(a);if(7=c&&!(b&1<<8-c);c++);if(8a||c&&a>=c?null:Math.floor(a/d)},getSegmentReference:function(a){var b=a*d;return new F(a,b,b+d,function(){var c=Od(g,l,a+e,h,b*f);return P(n,[c])},0,null)}}} function xe(a,b){for(var c=[],d=0;da.s||(a.f=window.setTimeout(a.Qc.bind(a),1E3*Math.max(Math.max(3,a.s)-b,0)))} function Ee(a,b,c){b=b||{contentType:"",mimeType:"",codecs:"",frameRate:void 0};c=c||b.M;var d=M(a,"BaseURL").map(zd),e=a.getAttribute("contentType")||b.contentType,f=a.getAttribute("mimeType")||b.mimeType,g=N(a,"frameRate",Fd)||b.frameRate;e||(e=f.split("/")[0]);return{M:P(c,d),Fa:yd(a,"SegmentBase")||b.Fa,Z:yd(a,"SegmentList")||b.Z,Ga:yd(a,"SegmentTemplate")||b.Ga,width:N(a,"width",Ed)||b.width,height:N(a,"height",Ed)||b.height,contentType:e,mimeType:f,codecs:a.getAttribute("codecs")||b.codecs, frameRate:g,id:a.getAttribute("id")}} function Fe(a){var b={};a.forEach(function(a){b[a.id]=[a]});a.forEach(function(a){var c=b[a.id];a.Wc.forEach(function(a){(a=b[a])&&a!=c&&(c.push.apply(c,a),a.forEach(function(a){b[a.id]=c}))})});var c=[],d=[];C(b).forEach(function(a){if(!(0<=d.indexOf(a))){d.push(a);var b=new Ja;a.forEach(function(a){b.push(a.contentType||"",a)});b.keys().forEach(function(a){var d=new Ja;b.get(a).forEach(function(a){d.push(a.language,a)});d.keys().forEach(function(b){var e=d.get(b);b={language:b,type:a,primary:e.some(function(a){return a.$b}), drmInfos:e.map(function(a){return a.drmInfos}).reduce(u,[]),streams:e.map(function(a){return a.streams}).reduce(u,[])};c.push(b)})})}});return c}function Ge(a){var b;b=0+(a.Fa?1:0);b+=a.Z?1:0;b+=a.Ga?1:0;if(!b)return"text"==a.contentType||"application"==a.contentType?!0:!1;1!=b&&(a.Fa&&(a.Z=null),a.Ga=null);return!0} function He(a,b,c,d){b=P(b,[c]);b=Ha(b,a.c.retryParameters);b.method=d;return a.a.request(0,b).then(function(a){if("HEAD"==d){if(!a.headers||!a.headers.date)return 0;a=a.headers.date}else a=D(a.data);a=Date.parse(a);return isNaN(a)?0:a-Date.now()})} function De(a,b,c,d){c=c.map(function(a){return{scheme:a.getAttribute("schemeIdUri"),value:a.getAttribute("value")}});var e=a.c.dash.clockSyncUri;d&&!c.length&&e&&c.push({scheme:"urn:mpeg:dash:utc:http-head:2014",value:e});return Ca(c,function(a){var c=a.value;switch(a.scheme){case "urn:mpeg:dash:utc:http-head:2014":case "urn:mpeg:dash:utc:http-head:2012":return He(this,b,c,"HEAD");case "urn:mpeg:dash:utc:http-xsdate:2014":case "urn:mpeg:dash:utc:http-iso:2014":case "urn:mpeg:dash:utc:http-xsdate:2012":case "urn:mpeg:dash:utc:http-iso:2012":return He(this, b,c,"GET");case "urn:mpeg:dash:utc:direct:2014":case "urn:mpeg:dash:utc:direct:2012":return a=Date.parse(c),isNaN(a)?0:a-Date.now();case "urn:mpeg:dash:utc:http-ntp:2014":case "urn:mpeg:dash:utc:ntp:2014":case "urn:mpeg:dash:utc:sntp:2014":return Promise.reject();default:return Promise.reject()}}.bind(a))["catch"](function(){return 0})}k.zc=function(a,b,c){a=Ha(a,this.c.retryParameters);null!=b&&(a.headers.Range="bytes="+b+"-"+(null!=c?c:""));return this.a.request(1,a).then(function(a){return a.data})}; k.Ia=function(a,b){if(1==a){var c=new Sd(new DataView(b.data)),d=ae(1701671783,c);if(-1!=d){var e=c.a-8+d;S(c,4);d=$d(c);if("urn:mpeg:dash:event:2012"==d)ze(this);else{var f=$d(c),g=R(c),h=R(c),l=R(c),n=R(c),c=Zd(c,e-c.a);this.m(new H("emsg",{detail:{jd:d,value:f,Ha:g,hd:h,fd:l,id:n,gd:c}}))}}}};sb.mpd=ye;rb["application/dash+xml"]=ye;function U(a,b){var c=D(a),d=[],e=new DOMParser,f=null;try{f=e.parseFromString(c,"text/xml")}catch(n){throw new q(2,2005);}if(f){var g,h;if(c=f.getElementsByTagName("tt")[0])e=c.getAttribute("ttp:frameRate"),f=c.getAttribute("ttp:subFrameRate"),g=c.getAttribute("ttp:frameRateMultiplier"),h=c.getAttribute("ttp:tickRate");else throw new q(2,2006);e=new Ie(e,f,g,h);f=U.b(c.getElementsByTagName("styling")[0]);g=U.b(c.getElementsByTagName("layout")[0]);c=U.b(c.getElementsByTagName("body")[0]);for(h=0;h< c.length;h++){var l=U.c(c[h],b,e,f,g);l&&d.push(l)}}return d}U.l=/^(\d{2,}):(\d{2}):(\d{2}):(\d{2})\.?(\d+)?$/;U.s=/^(?:(\d{2,}):)?(\d{2}):(\d{2})$/;U.m=/^(?:(\d{2,}):)?(\d{2}):(\d{2}\.\d{2,})$/;U.v=/^(\d*\.?\d*)f$/;U.A=/^(\d*\.?\d*)t$/;U.w=/^(?:(\d*\.?\d*)h)?(?:(\d*\.?\d*)m)?(?:(\d*\.?\d*)s)?(?:(\d*\.?\d*)ms)?$/;U.j=/^(\d{1,2}|100)% (\d{1,2}|100)%$/; U.b=function(a){var b=[];if(!a)return b;for(var c=a.childNodes,d=0;dc.length)return null;var d=null;if(a=U.oa(a,b))for(b=0;ba[0].indexOf("--\x3e")&&(e=a[0],a.splice(0,1));var f=new Ke(a[0]),g=V.a(f),h=Le(f,/[ \t]+--\x3e[ \t]+/g),l=V.a(f);if(null==g||!h||null==l)throw new q(2,2001);g+=b;l+=b;d&&(g+=c,l+=c);a=wb(g,l,a.slice(1).join("\n").trim());if(!a)return null;Le(f,/[ \t]+/gm);for(b=Me(f);b;)V.i(a,b),Le(f,/[ \t]+/gm),b=Me(f);null!=e&&(a.id=e);return a}; V.i=function(a,b){var c;if(c=/^align:(start|middle|end|left|right)$/.exec(b))a.align=c[1];else if(c=/^vertical:(lr|rl)$/.exec(b))a.c=c[1];else if(c=/^size:(\d{1,2}|100)%$/.exec(b))a.size=Number(c[1]);else if(c=/^position:(\d{1,2}|100)%(?:,(line-left|line-right|center|start|end))?$/.exec(b))a.position=Number(c[1]),c[2]&&(a.g=c[2]);else if(c=/^line:(\d{1,2}|100)%(?:,(start|end|center))?$/.exec(b))a.f=!1,a.a=Number(c[1]),c[2]&&(a.b=c[2]);else if(c=/^line:(-?\d+)(?:,(start|end|center))?$/.exec(b))a.f= !0,a.a=Number(c[1]),c[2]&&(a.b=c[2])};V.a=function(a){a=Le(a,/(?:(\d{1,}):)?(\d{2}):(\d{2})\.(\d{3})/g);if(!a)return null;var b=Number(a[2]),c=Number(a[3]);return 59c.length||"data"!=c[0])throw new q(1,1004,a);c=c.slice(1).join(":").split(",");if(2>c.length)throw new q(1,1004,a);var d=c[0],c=window.decodeURIComponent(c.slice(1).join(",")),d=d.split(";"),e=null;1=b.status){var e=b.getAllResponseHeaders().split("\r\n").reduce(function(a,b){var c=b.split(": ");a[c[0].toLowerCase()]=c.slice(1).join(": ");return a},{});b.Bc&&(a=b.Bc);c({uri:a,data:b.response,headers:e})}else{e=null;try{e=Ra(b.response)}catch(f){}d(new q(1, 1001,a,b.status,e))}};e.onerror=function(){d(new q(1,1002,a))};e.ontimeout=function(){d(new q(1,1003,a))};for(var f in b.headers)e.setRequestHeader(f,b.headers[f]);e.send(b.body)})}Fa.http=Ne;Fa.https=Ne;function Oe(){this.a=null;this.c=[];this.b={}}k=Oe.prototype; k.init=function(a){if(!window.indexedDB)return Promise.reject(new q(9,9E3));var b=window.indexedDB.open("shaka_offline_db",1),c=new w;b.onupgradeneeded=function(b){b=b.target.result;for(var c in a)b.createObjectStore(c,{keyPath:a[c]})};b.onsuccess=function(a){this.a=a.target.result;c.resolve()}.bind(this);b.onerror=Pe.bind(null,b,c);return c.then(function(){var b=Object.keys(a);return Promise.all(b.map(function(a){return Qe(this,a).then(function(b){this.b[a]=b}.bind(this))}.bind(this)))}.bind(this))}; k.o=function(){return Promise.all(this.c.map(function(a){try{a.transaction.abort()}catch(b){}return a.I["catch"](v)})).then(function(){this.a&&(this.a.close(),this.a=null)}.bind(this))};k.get=function(a,b){return Re(this,a,"readonly",function(a){return a.get(b)})};k.forEach=function(a,b){return Re(this,a,"readonly",function(a){return a.openCursor()},function(a){a&&(b(a.value),a["continue"]())})};function Se(a,b,c){return Re(a,b,"readwrite",function(a){return a.put(c)})} k.remove=function(a,b){return Re(this,a,"readwrite",function(a){return a["delete"](b)})};function Te(a,b){var c=[];return Re(a,"segment","readwrite",function(a){return a.openCursor()},function(a){if(a){if(b(a.value)){var e=a["delete"](),f=new w;e.onsuccess=f.resolve;e.onerror=Pe.bind(null,e,f);c.push(f)}a["continue"]()}}).then(function(){return Promise.all(c)}).then(function(){return c.length})} function Qe(a,b){var c=0;return Re(a,b,"readonly",function(a){return a.openCursor(null,"prev")},function(a){a&&(c=a.key+1)}).then(function(){return c})} function Re(a,b,c,d,e){c=a.a.transaction([b],c);var f=d(c.objectStore(b)),g=new w;e&&(f.onsuccess=function(a){e(a.target.result)});f.onerror=Pe.bind(null,f,g);var h={transaction:c,I:g};a.c.push(h);var l=function(){this.c.splice(this.c.indexOf(h),1)}.bind(a);c.oncomplete=function(){l();g.resolve(f.result)};c.onerror=function(a){l();Pe(f,g,a)};return g}function Pe(a,b,c){"AbortError"==a.error.name?b.reject(new q(9,9002)):b.reject(new q(9,9001,a.error));c.preventDefault()};var Ue={manifest:"key",segment:"key"};function Ve(a){return{offlineUri:"offline:"+a.key,originalManifestUri:a.originalManifestUri,duration:a.duration,size:a.size,tracks:a.periods[0].streams.map(function(a){return{id:a.id,active:!1,type:a.contentType,bandwidth:0,language:a.language,kind:a.kind||null,width:a.width,height:a.height,frameRate:a.frameRate,codecs:a.codecs}}),appMetadata:a.appMetadata}};function We(){}We.prototype.configure=function(){};We.prototype.start=function(a){var b=/^offline:([0-9]+)$/.exec(a);if(!b)return Promise.reject(new q(1,9004,a));var c=Number(b[1]),d=new Oe;return d.init(Ue).then(function(){return d.get("manifest",c)}).then(function(a){if(!a)throw new q(9,9003,c);return Xe(a)}).then(function(a){return d.o().then(function(){return a})},function(a){return d.o().then(function(){throw a;})})};We.prototype.stop=function(){return Promise.resolve()}; function Xe(a){var b=new G(null,0);b.za(a.duration);var c=a.drmInfo?[a.drmInfo]:[];return{presentationTimeline:b,minBufferTime:10,offlineSessionIds:a.sessionIds,periods:a.periods.map(function(a){return{startTime:a.startTime,streamSets:a.streams.map(function(e){var f=e.segments.map(function(a,b){return new F(b,a.startTime,a.endTime,function(){return[a.uri]},0,null)});b.Ea(a.startTime,f);f=new T(f);return{language:e.language,type:e.contentType,primary:e.primary,drmInfos:c,streams:[{id:e.id,createSegmentIndex:Promise.resolve.bind(Promise), findSegmentPosition:f.find.bind(f),getSegmentReference:f.get.bind(f),initSegmentReference:e.initSegmentUri?new Pb(function(){return[e.initSegmentUri]},0,null):null,presentationTimeOffset:e.presentationTimeOffset,mimeType:e.mimeType,codecs:e.codecs,bandwidth:0,width:e.width||void 0,height:e.height||void 0,kind:e.kind,encrypted:e.encrypted,keyId:e.keyId,allowedByApplication:!0,allowedByKeySystem:!0}]}})}})}}rb["application/x-offline-manifest"]=We;Fa.offline=function(a){if(/^offline:([0-9]+)$/.exec(a)){var b={uri:a,data:new ArrayBuffer(0),headers:{"content-type":"application/x-offline-manifest"}};return Promise.resolve(b)}if(b=/^offline:[0-9]+\/[0-9]+\/([0-9]+)$/.exec(a)){var c=Number(b[1]),d=new Oe;return d.init(Ue).then(function(){return d.get("segment",c)}).then(function(b){return d.o().then(function(){if(!b)throw new q(9,9003,c);return{uri:a,data:b.data,headers:{}}})})}return Promise.reject(new q(1,9004,a))};function Ye(a,b,c){this.b={};this.i=c;this.m=a;this.l=b;this.j=this.a=null;this.f=this.g=this.h=this.c=0}Ye.prototype.o=function(){var a=this.j||Promise.resolve();this.b={};this.j=this.a=this.l=this.m=this.i=null;return a};function Ze(a,b,c,d,e){a.b[b]=a.b[b]||[];a.b[b].push({uris:c.a(),L:c.L,D:c.D,gb:d,Ca:e})} function $e(a,b){a.c=0;a.h=0;a.g=0;a.f=0;C(a.b).forEach(function(a){a.forEach(function(a){null!=a.D?this.c+=a.D-a.L+1:this.g+=a.gb}.bind(this))}.bind(a));a.a=b;a.a.size=a.c;var c=C(a.b).map(function(a){var b=0,c=function(){if(!this.i)return Promise.reject(new q(9,9002));if(b>=a.length)return Promise.resolve();var g=a[b++];return af(this,g).then(c)}.bind(this);return c()}.bind(a));a.b={};return a.j=Promise.all(c)} function af(a,b){var c=Ha(b.uris,a.l);if(b.L||null!=b.D)c.headers.Range="bytes="+b.L+"-"+(null==b.D?"":b.D);var d;return a.m.request(1,c).then(function(a){if(!this.a)return Promise.reject(new q(9,9002));d=a.data.byteLength;return b.Ca(a.data)}.bind(a)).then(function(){if(!this.a)return Promise.reject(new q(9,9002));null==b.D?(this.a.size+=d,this.f+=b.gb):this.h+=d;var a=(this.h+this.f)/(this.c+this.g),c=Ve(this.a);this.i.progressCallback(c,a)}.bind(a))};function X(a){this.a=new Oe;this.c=a;this.j=bf(this);this.g=null;this.v=!1;this.i=null;this.l=[];this.f=-1;this.m=0;this.b=null;this.h=new Ye(a.h,a.getConfiguration().streaming.retryParameters,this.j)}m("shaka.offline.Storage",X);function cf(){return!!window.indexedDB}X.support=cf; X.prototype.o=function(){var a=this.l,b=this.a,c=this.h?this.h.o()["catch"](function(){}).then(function(){return Promise.all(a.map(function(a){return b.remove("segment",a)}))}).then(function(){return b.o()}):Promise.resolve();this.j=this.c=this.h=this.a=null;return c};X.prototype.destroy=X.prototype.o;X.prototype.configure=function(a){Cc(this.j,a,bf(this),{},"")};X.prototype.configure=X.prototype.configure; X.prototype.Tc=function(a,b,c){function d(a){f=a}if(this.v)return Promise.reject(new q(9,9006));this.v=!0;var e,f=null;return df(this).then(function(){Y(this);return ef(this,a,d,c)}.bind(this)).then(function(c){Y(this);this.b=c.manifest;this.g=c.Pb;if(this.b.presentationTimeline.U()||this.b.presentationTimeline.fa())throw new q(9,9005,a);this.b.periods.forEach(this.s.bind(this));this.f=this.a.b.manifest++;this.m=0;c=this.b.periods.map(this.w.bind(this));var d=this.g.b,f=ib(this.g);if(d){if(!f.length)throw new q(9, 9007,a);d.initData=[]}e={key:this.f,originalManifestUri:a,duration:this.m,size:0,periods:c,sessionIds:f,drmInfo:d,appMetadata:b};return $e(this.h,e)}.bind(this)).then(function(){Y(this);if(f)throw f;return Se(this.a,"manifest",e)}.bind(this)).then(function(){return ff(this)}.bind(this)).then(function(){return Ve(e)}.bind(this))["catch"](function(a){return ff(this)["catch"](v).then(function(){throw a;})}.bind(this))};X.prototype.store=X.prototype.Tc; X.prototype.remove=function(a){function b(a){6013!=a.code&&(e=a)}var c=a.offlineUri,d=/^offline:([0-9]+)$/.exec(c);if(!d)return Promise.reject(new q(9,9004,c));var e=null,f,g,h=Number(d[1]);return df(this).then(function(){Y(this);return this.a.get("manifest",h)}.bind(this)).then(function(a){Y(this);if(!a)throw new q(9,9003,c);f=a;a=Xe(f);g=new ab(this.c.h,b,function(){});g.configure(this.c.getConfiguration().drm);return g.init(a,!0)}.bind(this)).then(function(){return fb(g,f.sessionIds)}.bind(this)).then(function(){return g.o()}.bind(this)).then(function(){Y(this); if(e)throw e;var b=f.periods.map(function(a){return a.streams.map(function(a){var b=a.segments.map(function(a){return Number(/^offline:[0-9]+\/[0-9]+\/([0-9]+)$/.exec(a.uri)[1])});a.initSegmentUri&&b.push(Number(/^offline:[0-9]+\/[0-9]+\/([0-9]+)$/.exec(a.initSegmentUri)[1]));return b}).reduce(u,[])}).reduce(u,[]),c=0,d=b.length,g=this.j.progressCallback;return Te(this.a,function(e){e=b.indexOf(e.key);0<=e&&(g(a,c/d),c++);return 0<=e}.bind(this))}.bind(this)).then(function(){Y(this);this.j.progressCallback(a, 1);return this.a.remove("manifest",h)}.bind(this))};X.prototype.remove=X.prototype.remove;X.prototype.list=function(){var a=[];return df(this).then(function(){Y(this);return this.a.forEach("manifest",function(b){a.push(Ve(b))})}.bind(this)).then(function(){return a})};X.prototype.list=X.prototype.list; function ef(a,b,c,d){function e(){}var f=a.c.h,g=a.c.getConfiguration(),h,l,n;return ub(b,f,g.manifest.retryParameters,d).then(function(a){Y(this);n=new a;n.configure(g.manifest);return n.start(b,f,this.s.bind(this),c)}.bind(a)).then(function(a){Y(this);h=a;l=new ab(f,c,e);l.configure(g.drm);return l.init(h,!0)}.bind(a)).then(function(){Y(this);return gf(h)}.bind(a)).then(function(){Y(this);return eb(l)}.bind(a)).then(function(){Y(this);return n.stop()}.bind(a)).then(function(){Y(this);return{manifest:h, Pb:l}}.bind(a))["catch"](function(a){if(n)return n.stop().then(function(){throw a;});throw a;})} X.prototype.A=function(a){var b=[],c=a.filter(function(a){return"video"==a.type&&480>=a.height});c.sort(function(a,b){return b.bandwidth-a.bandwidth});c.length&&b.push(c[0]);for(var d=Gc(this.c.getConfiguration().preferredAudioLanguage),c=[0,Ec,Fc],e=a.filter(function(a){return"audio"==a.type}),c=c.map(function(a){return e.filter(function(b){b=Gc(b.language);return Dc(a,d,b)})}),f=e,g=0;g=c.a.length)){for(var d=[],e=0;ea.indexOf("Apple")))if(0<=b.indexOf("Version/8"))window.MediaSource=null;else{var c=MediaSource.prototype.addSourceBuffer;MediaSource.prototype.addSourceBuffer=function(){var a=c.apply(this,arguments);a.abort=function(){};return a}}}});function Z(a){this.c=[];this.b=[];this.ia=Nf;if(a)try{a(this.W.bind(this),this.a.bind(this))}catch(b){this.a(b)}}var Nf=0;function Of(a){var b=new Z;b.W(a);return b}function Pf(a){var b=new Z;b.a(a);return b}function Qf(a){function b(a,b,c){a.ia==Nf&&(e[b]=c,d++,d==e.length&&a.W(e))}var c=new Z;if(!a.length)return c.W([]),c;for(var d=0,e=Array(a.length),f=c.a.bind(c),g=0;gc.children.length;){var j=document.createElement("span");j.style.cssText="width:1px;height:30px;float:left;background-color:#113";c.appendChild(j)}var d=document.createElement("div");d.id="ms";d.style.cssText="padding:0 0 3px 3px;text-align:left;background-color:#020;display:none";f.appendChild(d);var k=document.createElement("div"); k.id="msText";k.style.cssText="color:#0f0;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px";k.innerHTML="MS";d.appendChild(k);var e=document.createElement("div");e.id="msGraph";e.style.cssText="position:relative;width:74px;height:30px;background-color:#0f0";for(d.appendChild(e);74>e.children.length;)j=document.createElement("span"),j.style.cssText="width:1px;height:30px;float:left;background-color:#131",e.appendChild(j);var t=function(b){s=b;switch(s){case 0:a.style.display= "block";d.style.display="none";break;case 1:a.style.display="none",d.style.display="block"}};return{REVISION:12,domElement:f,setMode:t,begin:function(){l=Date.now()},end:function(){var b=Date.now();g=b-l;n=Math.min(n,g);o=Math.max(o,g);k.textContent=g+" MS ("+n+"-"+o+")";var a=Math.min(30,30-30*(g/200));e.appendChild(e.firstChild).style.height=a+"px";r++;b>m+1E3&&(h=Math.round(1E3*r/(b-m)),p=Math.min(p,h),q=Math.max(q,h),i.textContent=h+" FPS ("+p+"-"+q+")",a=Math.min(30,30-30*(h/100)),c.appendChild(c.firstChild).style.height= a+"px",m=b,r=0);return b},update:function(){l=this.end()}}};"object"===typeof module&&(module.exports=Stats); },{}],5:[function(require,module,exports){ (function (process){ /** * Tween.js - Licensed under the MIT license * https://github.com/tweenjs/tween.js * ---------------------------------------------- * * See https://github.com/tweenjs/tween.js/graphs/contributors for the full list of contributors. * Thank you all, you're awesome! */ var TWEEN = TWEEN || (function () { var _tweens = []; return { getAll: function () { return _tweens; }, removeAll: function () { _tweens = []; }, add: function (tween) { _tweens.push(tween); }, remove: function (tween) { var i = _tweens.indexOf(tween); if (i !== -1) { _tweens.splice(i, 1); } }, update: function (time, preserve) { if (_tweens.length === 0) { return false; } var i = 0; time = time !== undefined ? time : TWEEN.now(); while (i < _tweens.length) { if (_tweens[i].update(time) || preserve) { i++; } else { _tweens.splice(i, 1); } } return true; } }; })(); // Include a performance.now polyfill (function () { // In node.js, use process.hrtime. if (this.window === undefined && this.process !== undefined) { TWEEN.now = function () { var time = process.hrtime(); // Convert [seconds, microseconds] to milliseconds. return time[0] * 1000 + time[1] / 1000; }; } // In a browser, use window.performance.now if it is available. else if (this.window !== undefined && window.performance !== undefined && window.performance.now !== undefined) { // This must be bound, because directly assigning this function // leads to an invocation exception in Chrome. TWEEN.now = window.performance.now.bind(window.performance); } // Use Date.now if it is available. else if (Date.now !== undefined) { TWEEN.now = Date.now; } // Otherwise, use 'new Date().getTime()'. else { TWEEN.now = function () { return new Date().getTime(); }; } })(); TWEEN.Tween = function (object) { var _object = object; var _valuesStart = {}; var _valuesEnd = {}; var _valuesStartRepeat = {}; var _duration = 1000; var _repeat = 0; var _yoyo = false; var _isPlaying = false; var _reversed = false; var _delayTime = 0; var _startTime = null; var _easingFunction = TWEEN.Easing.Linear.None; var _interpolationFunction = TWEEN.Interpolation.Linear; var _chainedTweens = []; var _onStartCallback = null; var _onStartCallbackFired = false; var _onUpdateCallback = null; var _onCompleteCallback = null; var _onStopCallback = null; // Set all starting values present on the target object for (var field in object) { _valuesStart[field] = parseFloat(object[field], 10); } this.to = function (properties, duration) { if (duration !== undefined) { _duration = duration; } _valuesEnd = properties; return this; }; this.start = function (time) { TWEEN.add(this); _isPlaying = true; _onStartCallbackFired = false; _startTime = time !== undefined ? time : TWEEN.now(); _startTime += _delayTime; for (var property in _valuesEnd) { // Check if an Array was provided as property value if (_valuesEnd[property] instanceof Array) { if (_valuesEnd[property].length === 0) { continue; } // Create a local copy of the Array with the start value at the front _valuesEnd[property] = [_object[property]].concat(_valuesEnd[property]); } // If `to()` specifies a property that doesn't exist in the source object, // we should not set that property in the object if (_valuesStart[property] === undefined) { continue; } _valuesStart[property] = _object[property]; if ((_valuesStart[property] instanceof Array) === false) { _valuesStart[property] *= 1.0; // Ensures we're using numbers, not strings } _valuesStartRepeat[property] = _valuesStart[property] || 0; } return this; }; this.stop = function () { if (!_isPlaying) { return this; } TWEEN.remove(this); _isPlaying = false; if (_onStopCallback !== null) { _onStopCallback.call(_object); } this.stopChainedTweens(); return this; }; this.stopChainedTweens = function () { for (var i = 0, numChainedTweens = _chainedTweens.length; i < numChainedTweens; i++) { _chainedTweens[i].stop(); } }; this.delay = function (amount) { _delayTime = amount; return this; }; this.repeat = function (times) { _repeat = times; return this; }; this.yoyo = function (yoyo) { _yoyo = yoyo; return this; }; this.easing = function (easing) { _easingFunction = easing; return this; }; this.interpolation = function (interpolation) { _interpolationFunction = interpolation; return this; }; this.chain = function () { _chainedTweens = arguments; return this; }; this.onStart = function (callback) { _onStartCallback = callback; return this; }; this.onUpdate = function (callback) { _onUpdateCallback = callback; return this; }; this.onComplete = function (callback) { _onCompleteCallback = callback; return this; }; this.onStop = function (callback) { _onStopCallback = callback; return this; }; this.update = function (time) { var property; var elapsed; var value; if (time < _startTime) { return true; } if (_onStartCallbackFired === false) { if (_onStartCallback !== null) { _onStartCallback.call(_object); } _onStartCallbackFired = true; } elapsed = (time - _startTime) / _duration; elapsed = elapsed > 1 ? 1 : elapsed; value = _easingFunction(elapsed); for (property in _valuesEnd) { // Don't update properties that do not exist in the source object if (_valuesStart[property] === undefined) { continue; } var start = _valuesStart[property] || 0; var end = _valuesEnd[property]; if (end instanceof Array) { _object[property] = _interpolationFunction(end, value); } else { // Parses relative end values with start as base (e.g.: +10, -3) if (typeof (end) === 'string') { if (end.charAt(0) === '+' || end.charAt(0) === '-') { end = start + parseFloat(end, 10); } else { end = parseFloat(end, 10); } } // Protect against non numeric properties. if (typeof (end) === 'number') { _object[property] = start + (end - start) * value; } } } if (_onUpdateCallback !== null) { _onUpdateCallback.call(_object, value); } if (elapsed === 1) { if (_repeat > 0) { if (isFinite(_repeat)) { _repeat--; } // Reassign starting values, restart by making startTime = now for (property in _valuesStartRepeat) { if (typeof (_valuesEnd[property]) === 'string') { _valuesStartRepeat[property] = _valuesStartRepeat[property] + parseFloat(_valuesEnd[property], 10); } if (_yoyo) { var tmp = _valuesStartRepeat[property]; _valuesStartRepeat[property] = _valuesEnd[property]; _valuesEnd[property] = tmp; } _valuesStart[property] = _valuesStartRepeat[property]; } if (_yoyo) { _reversed = !_reversed; } _startTime = time + _delayTime; return true; } else { if (_onCompleteCallback !== null) { _onCompleteCallback.call(_object); } for (var i = 0, numChainedTweens = _chainedTweens.length; i < numChainedTweens; i++) { // Make the chained tweens start exactly at the time they should, // even if the `update()` method was called way past the duration of the tween _chainedTweens[i].start(_startTime + _duration); } return false; } } return true; }; }; TWEEN.Easing = { Linear: { None: function (k) { return k; } }, Quadratic: { In: function (k) { return k * k; }, Out: function (k) { return k * (2 - k); }, InOut: function (k) { if ((k *= 2) < 1) { return 0.5 * k * k; } return - 0.5 * (--k * (k - 2) - 1); } }, Cubic: { In: function (k) { return k * k * k; }, Out: function (k) { return --k * k * k + 1; }, InOut: function (k) { if ((k *= 2) < 1) { return 0.5 * k * k * k; } return 0.5 * ((k -= 2) * k * k + 2); } }, Quartic: { In: function (k) { return k * k * k * k; }, Out: function (k) { return 1 - (--k * k * k * k); }, InOut: function (k) { if ((k *= 2) < 1) { return 0.5 * k * k * k * k; } return - 0.5 * ((k -= 2) * k * k * k - 2); } }, Quintic: { In: function (k) { return k * k * k * k * k; }, Out: function (k) { return --k * k * k * k * k + 1; }, InOut: function (k) { if ((k *= 2) < 1) { return 0.5 * k * k * k * k * k; } return 0.5 * ((k -= 2) * k * k * k * k + 2); } }, Sinusoidal: { In: function (k) { return 1 - Math.cos(k * Math.PI / 2); }, Out: function (k) { return Math.sin(k * Math.PI / 2); }, InOut: function (k) { return 0.5 * (1 - Math.cos(Math.PI * k)); } }, Exponential: { In: function (k) { return k === 0 ? 0 : Math.pow(1024, k - 1); }, Out: function (k) { return k === 1 ? 1 : 1 - Math.pow(2, - 10 * k); }, InOut: function (k) { if (k === 0) { return 0; } if (k === 1) { return 1; } if ((k *= 2) < 1) { return 0.5 * Math.pow(1024, k - 1); } return 0.5 * (- Math.pow(2, - 10 * (k - 1)) + 2); } }, Circular: { In: function (k) { return 1 - Math.sqrt(1 - k * k); }, Out: function (k) { return Math.sqrt(1 - (--k * k)); }, InOut: function (k) { if ((k *= 2) < 1) { return - 0.5 * (Math.sqrt(1 - k * k) - 1); } return 0.5 * (Math.sqrt(1 - (k -= 2) * k) + 1); } }, Elastic: { In: function (k) { if (k === 0) { return 0; } if (k === 1) { return 1; } return -Math.pow(2, 10 * (k - 1)) * Math.sin((k - 1.1) * 5 * Math.PI); }, Out: function (k) { if (k === 0) { return 0; } if (k === 1) { return 1; } return Math.pow(2, -10 * k) * Math.sin((k - 0.1) * 5 * Math.PI) + 1; }, InOut: function (k) { if (k === 0) { return 0; } if (k === 1) { return 1; } k *= 2; if (k < 1) { return -0.5 * Math.pow(2, 10 * (k - 1)) * Math.sin((k - 1.1) * 5 * Math.PI); } return 0.5 * Math.pow(2, -10 * (k - 1)) * Math.sin((k - 1.1) * 5 * Math.PI) + 1; } }, Back: { In: function (k) { var s = 1.70158; return k * k * ((s + 1) * k - s); }, Out: function (k) { var s = 1.70158; return --k * k * ((s + 1) * k + s) + 1; }, InOut: function (k) { var s = 1.70158 * 1.525; if ((k *= 2) < 1) { return 0.5 * (k * k * ((s + 1) * k - s)); } return 0.5 * ((k -= 2) * k * ((s + 1) * k + s) + 2); } }, Bounce: { In: function (k) { return 1 - TWEEN.Easing.Bounce.Out(1 - k); }, Out: function (k) { if (k < (1 / 2.75)) { return 7.5625 * k * k; } else if (k < (2 / 2.75)) { return 7.5625 * (k -= (1.5 / 2.75)) * k + 0.75; } else if (k < (2.5 / 2.75)) { return 7.5625 * (k -= (2.25 / 2.75)) * k + 0.9375; } else { return 7.5625 * (k -= (2.625 / 2.75)) * k + 0.984375; } }, InOut: function (k) { if (k < 0.5) { return TWEEN.Easing.Bounce.In(k * 2) * 0.5; } return TWEEN.Easing.Bounce.Out(k * 2 - 1) * 0.5 + 0.5; } } }; TWEEN.Interpolation = { Linear: function (v, k) { var m = v.length - 1; var f = m * k; var i = Math.floor(f); var fn = TWEEN.Interpolation.Utils.Linear; if (k < 0) { return fn(v[0], v[1], f); } if (k > 1) { return fn(v[m], v[m - 1], m - f); } return fn(v[i], v[i + 1 > m ? m : i + 1], f - i); }, Bezier: function (v, k) { var b = 0; var n = v.length - 1; var pw = Math.pow; var bn = TWEEN.Interpolation.Utils.Bernstein; for (var i = 0; i <= n; i++) { b += pw(1 - k, n - i) * pw(k, i) * v[i] * bn(n, i); } return b; }, CatmullRom: function (v, k) { var m = v.length - 1; var f = m * k; var i = Math.floor(f); var fn = TWEEN.Interpolation.Utils.CatmullRom; if (v[0] === v[m]) { if (k < 0) { i = Math.floor(f = m * (1 + k)); } return fn(v[(i - 1 + m) % m], v[i], v[(i + 1) % m], v[(i + 2) % m], f - i); } else { if (k < 0) { return v[0] - (fn(v[0], v[0], v[1], v[1], -f) - v[0]); } if (k > 1) { return v[m] - (fn(v[m], v[m], v[m - 1], v[m - 1], f - m) - v[m]); } return fn(v[i ? i - 1 : 0], v[i], v[m < i + 1 ? m : i + 1], v[m < i + 2 ? m : i + 2], f - i); } }, Utils: { Linear: function (p0, p1, t) { return (p1 - p0) * t + p0; }, Bernstein: function (n, i) { var fc = TWEEN.Interpolation.Utils.Factorial; return fc(n) / fc(i) / fc(n - i); }, Factorial: (function () { var a = [1]; return function (n) { var s = 1; if (a[n]) { return a[n]; } for (var i = n; i > 1; i--) { s *= i; } a[n] = s; return s; }; })(), CatmullRom: function (p0, p1, p2, p3, t) { var v0 = (p2 - p0) * 0.5; var v1 = (p3 - p1) * 0.5; var t2 = t * t; var t3 = t * t2; return (2 * p1 - 2 * p2 + v0 + v1) * t3 + (- 3 * p1 + 3 * p2 - 2 * v0 - v1) * t2 + v0 * t + p1; } } }; // UMD (Universal Module Definition) (function (root) { if (typeof define === 'function' && define.amd) { // AMD define([], function () { return TWEEN; }); } else if (typeof module !== 'undefined' && typeof exports === 'object') { // Node.js module.exports = TWEEN; } else if (root !== undefined) { // Global variable root.TWEEN = TWEEN; } })(this); }).call(this,require('_process')) },{"_process":21}],6:[function(require,module,exports){ (function (global){ (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.WebVRManager = 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 %s', this.mode, mode); this.mode = mode; this.button.setMode(mode, this.isVRCompatible); // Emit an event indicating the mode changed. this.emit('modechange', mode, oldMode); }; /** * Main button was clicked. */ WebVRManager.prototype.onFSClick_ = function() { switch (this.mode) { case Modes.NORMAL: // TODO: Remove this hack if/when iOS gets real fullscreen mode. // If this is an iframe on iOS, break out and open in no_fullscreen mode. if (Util.isIOS() && Util.isIFrame()) { if (this.fullscreenCallback) { this.fullscreenCallback(); } else { var url = window.location.href; url = Util.appendQueryParameter(url, 'no_fullscreen', 'true'); url = Util.appendQueryParameter(url, 'start_mode', Modes.MAGIC_WINDOW); top.location.href = url; return; } } this.setMode_(Modes.MAGIC_WINDOW); this.requestFullscreen_(); break; case Modes.MAGIC_WINDOW: if (this.isFullscreenDisabled) { window.history.back(); return; } if (this.exitFullscreenCallback) { this.exitFullscreenCallback(); } this.setMode_(Modes.NORMAL); this.exitFullscreen_(); break; } }; /** * The VR button was clicked. */ WebVRManager.prototype.onVRClick_ = function() { // TODO: Remove this hack when iOS has fullscreen mode. // If this is an iframe on iOS, break out and open in no_fullscreen mode. if (this.mode == Modes.NORMAL && Util.isIOS() && Util.isIFrame()) { if (this.vrCallback) { this.vrCallback(); } else { var url = window.location.href; url = Util.appendQueryParameter(url, 'no_fullscreen', 'true'); url = Util.appendQueryParameter(url, 'start_mode', Modes.VR); top.location.href = url; return; } } this.enterVRMode_(); }; WebVRManager.prototype.requestFullscreen_ = function() { var canvas = document.body; //var canvas = this.renderer.domElement; if (canvas.requestFullscreen) { canvas.requestFullscreen(); } else if (canvas.mozRequestFullScreen) { canvas.mozRequestFullScreen(); } else if (canvas.webkitRequestFullscreen) { canvas.webkitRequestFullscreen(); } else if (canvas.msRequestFullscreen) { canvas.msRequestFullscreen(); } }; WebVRManager.prototype.exitFullscreen_ = function() { if (document.exitFullscreen) { document.exitFullscreen(); } else if (document.mozCancelFullScreen) { document.mozCancelFullScreen(); } else if (document.webkitExitFullscreen) { document.webkitExitFullscreen(); } else if (document.msExitFullscreen) { document.msExitFullscreen(); } }; WebVRManager.prototype.onVRDisplayPresentChange_ = function(e) { console.log('onVRDisplayPresentChange_', e); if (this.hmd.isPresenting) { this.setMode_(Modes.VR); } else { this.setMode_(Modes.NORMAL); } }; WebVRManager.prototype.onVRDisplayDeviceParamsChange_ = function(e) { console.log('onVRDisplayDeviceParamsChange_', e); }; WebVRManager.prototype.onFullscreenChange_ = function(e) { // If we leave full-screen, go back to normal mode. if (document.webkitFullscreenElement === null || document.mozFullScreenElement === null) { this.setMode_(Modes.NORMAL); } }; module.exports = WebVRManager; },{"./button-manager.js":1,"./emitter.js":2,"./modes.js":3,"./util.js":4}]},{},[5])(5) }); }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{}],7:[function(require,module,exports){ (function (global){ (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.WebVRPolyfill = 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 self.capabilities.maxLayers) { reject(new Error('Invalid number of layers.')); return; } var incomingLayer = layers[0]; if (!incomingLayer.source) { /* todo: figure out the correct behavior if the source is not provided. see https://github.com/w3c/webvr/issues/58 */ resolve(); return; } var leftBounds = incomingLayer.leftBounds || defaultLeftBounds; var rightBounds = incomingLayer.rightBounds || defaultRightBounds; if (wasPresenting) { // Already presenting, just changing configuration var layer = self.layer_; if (layer.source !== incomingLayer.source) { layer.source = incomingLayer.source; } for (var i = 0; i < 4; i++) { if (layer.leftBounds[i] !== leftBounds[i]) { layer.leftBounds[i] = leftBounds[i]; } if (layer.rightBounds[i] !== rightBounds[i]) { layer.rightBounds[i] = rightBounds[i]; } } resolve(); return; } // Was not already presenting. self.layer_ = { predistorted: incomingLayer.predistorted, source: incomingLayer.source, leftBounds: leftBounds.slice(0), rightBounds: rightBounds.slice(0) }; self.waitingForPresent_ = false; if (self.layer_ && self.layer_.source) { var fullscreenElement = self.wrapForFullscreen(self.layer_.source); function onFullscreenChange() { var actualFullscreenElement = Util.getFullscreenElement(); self.isPresenting = (fullscreenElement === actualFullscreenElement); if (self.isPresenting) { if (screen.orientation && screen.orientation.lock) { screen.orientation.lock('landscape-primary').catch(function(error){ console.error('screen.orientation.lock() failed due to', error.message) }); } self.waitingForPresent_ = false; self.beginPresent_(); resolve(); } else { if (screen.orientation && screen.orientation.unlock) { screen.orientation.unlock(); } self.removeFullscreenWrapper(); self.wakelock_.release(); self.endPresent_(); self.removeFullscreenListeners_(); } self.fireVRDisplayPresentChange_(); } function onFullscreenError() { if (!self.waitingForPresent_) { return; } self.removeFullscreenWrapper(); self.removeFullscreenListeners_(); self.wakelock_.release(); self.waitingForPresent_ = false; self.isPresenting = false; reject(new Error('Unable to present.')); } self.addFullscreenListeners_(fullscreenElement, onFullscreenChange, onFullscreenError); if (Util.requestFullscreen(fullscreenElement)) { self.wakelock_.request(); self.waitingForPresent_ = true; } else if (Util.isIOS()) { // *sigh* Just fake it. self.wakelock_.request(); self.isPresenting = true; self.beginPresent_(); self.fireVRDisplayPresentChange_(); resolve(); } } if (!self.waitingForPresent_ && !Util.isIOS()) { Util.exitFullscreen(); reject(new Error('Unable to present.')); } }); }; VRDisplay.prototype.exitPresent = function() { var wasPresenting = this.isPresenting; var self = this; this.isPresenting = false; this.layer_ = null; this.wakelock_.release(); return new Promise(function(resolve, reject) { if (wasPresenting) { if (!Util.exitFullscreen() && Util.isIOS()) { self.endPresent_(); self.fireVRDisplayPresentChange_(); } resolve(); } else { reject(new Error('Was not presenting to VRDisplay.')); } }); }; VRDisplay.prototype.getLayers = function() { if (this.layer_) { return [this.layer_]; } return []; }; VRDisplay.prototype.fireVRDisplayPresentChange_ = function() { var event = new CustomEvent('vrdisplaypresentchange', {detail: {display: this}}); window.dispatchEvent(event); }; VRDisplay.prototype.addFullscreenListeners_ = function(element, changeHandler, errorHandler) { this.removeFullscreenListeners_(); this.fullscreenEventTarget_ = element; this.fullscreenChangeHandler_ = changeHandler; this.fullscreenErrorHandler_ = errorHandler; if (changeHandler) { if (document.fullscreenEnabled) { element.addEventListener('fullscreenchange', changeHandler, false); } else if (document.webkitFullscreenEnabled) { element.addEventListener('webkitfullscreenchange', changeHandler, false); } else if (document.mozFullScreenEnabled) { document.addEventListener('mozfullscreenchange', changeHandler, false); } else if (document.msFullscreenEnabled) { element.addEventListener('msfullscreenchange', changeHandler, false); } } if (errorHandler) { if (document.fullscreenEnabled) { element.addEventListener('fullscreenerror', errorHandler, false); } else if (document.webkitFullscreenEnabled) { element.addEventListener('webkitfullscreenerror', errorHandler, false); } else if (document.mozFullScreenEnabled) { document.addEventListener('mozfullscreenerror', errorHandler, false); } else if (document.msFullscreenEnabled) { element.addEventListener('msfullscreenerror', errorHandler, false); } } }; VRDisplay.prototype.removeFullscreenListeners_ = function() { if (!this.fullscreenEventTarget_) return; var element = this.fullscreenEventTarget_; if (this.fullscreenChangeHandler_) { var changeHandler = this.fullscreenChangeHandler_; element.removeEventListener('fullscreenchange', changeHandler, false); element.removeEventListener('webkitfullscreenchange', changeHandler, false); document.removeEventListener('mozfullscreenchange', changeHandler, false); element.removeEventListener('msfullscreenchange', changeHandler, false); } if (this.fullscreenErrorHandler_) { var errorHandler = this.fullscreenErrorHandler_; element.removeEventListener('fullscreenerror', errorHandler, false); element.removeEventListener('webkitfullscreenerror', errorHandler, false); document.removeEventListener('mozfullscreenerror', errorHandler, false); element.removeEventListener('msfullscreenerror', errorHandler, false); } this.fullscreenEventTarget_ = null; this.fullscreenChangeHandler_ = null; this.fullscreenErrorHandler_ = null; }; VRDisplay.prototype.beginPresent_ = function() { // Override to add custom behavior when presentation begins. }; VRDisplay.prototype.endPresent_ = function() { // Override to add custom behavior when presentation ends. }; VRDisplay.prototype.submitFrame = function(pose) { // Override to add custom behavior for frame submission. }; VRDisplay.prototype.getEyeParameters = function(whichEye) { // Override to return accurate eye parameters if canPresent is true. return null; }; /* * Deprecated classes */ /** * The base class for all VR devices. (Deprecated) */ function VRDevice() { this.isPolyfilled = true; this.hardwareUnitId = 'webvr-polyfill hardwareUnitId'; this.deviceId = 'webvr-polyfill deviceId'; this.deviceName = 'webvr-polyfill deviceName'; } /** * The base class for all VR HMD devices. (Deprecated) */ function HMDVRDevice() { } HMDVRDevice.prototype = new VRDevice(); /** * The base class for all VR position sensor devices. (Deprecated) */ function PositionSensorVRDevice() { } PositionSensorVRDevice.prototype = new VRDevice(); module.exports.VRFrameData = VRFrameData; module.exports.VRDisplay = VRDisplay; module.exports.VRDevice = VRDevice; module.exports.HMDVRDevice = HMDVRDevice; module.exports.PositionSensorVRDevice = PositionSensorVRDevice; },{"./util.js":22,"./wakelock.js":24}],4:[function(_dereq_,module,exports){ /* * Copyright 2016 Google Inc. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var CardboardUI = _dereq_('./cardboard-ui.js'); var Util = _dereq_('./util.js'); var WGLUPreserveGLState = _dereq_('./deps/wglu-preserve-state.js'); var distortionVS = [ 'attribute vec2 position;', 'attribute vec3 texCoord;', 'varying vec2 vTexCoord;', 'uniform vec4 viewportOffsetScale[2];', 'void main() {', ' vec4 viewport = viewportOffsetScale[int(texCoord.z)];', ' vTexCoord = (texCoord.xy * viewport.zw) + viewport.xy;', ' gl_Position = vec4( position, 1.0, 1.0 );', '}', ].join('\n'); var distortionFS = [ 'precision mediump float;', 'uniform sampler2D diffuse;', 'varying vec2 vTexCoord;', 'void main() {', ' gl_FragColor = texture2D(diffuse, vTexCoord);', '}', ].join('\n'); /** * A mesh-based distorter. */ function CardboardDistorter(gl) { this.gl = gl; this.ctxAttribs = gl.getContextAttributes(); this.meshWidth = 20; this.meshHeight = 20; this.bufferScale = WebVRConfig.BUFFER_SCALE; this.bufferWidth = gl.drawingBufferWidth; this.bufferHeight = gl.drawingBufferHeight; // Patching support this.realBindFramebuffer = gl.bindFramebuffer; this.realEnable = gl.enable; this.realDisable = gl.disable; this.realColorMask = gl.colorMask; this.realClearColor = gl.clearColor; this.realViewport = gl.viewport; if (!Util.isIOS()) { this.realCanvasWidth = Object.getOwnPropertyDescriptor(gl.canvas.__proto__, 'width'); this.realCanvasHeight = Object.getOwnPropertyDescriptor(gl.canvas.__proto__, 'height'); } this.isPatched = false; // State tracking this.lastBoundFramebuffer = null; this.cullFace = false; this.depthTest = false; this.blend = false; this.scissorTest = false; this.stencilTest = false; this.viewport = [0, 0, 0, 0]; this.colorMask = [true, true, true, true]; this.clearColor = [0, 0, 0, 0]; this.attribs = { position: 0, texCoord: 1 }; this.program = Util.linkProgram(gl, distortionVS, distortionFS, this.attribs); this.uniforms = Util.getProgramUniforms(gl, this.program); this.viewportOffsetScale = new Float32Array(8); this.setTextureBounds(); this.vertexBuffer = gl.createBuffer(); this.indexBuffer = gl.createBuffer(); this.indexCount = 0; this.renderTarget = gl.createTexture(); this.framebuffer = gl.createFramebuffer(); this.depthStencilBuffer = null; this.depthBuffer = null; this.stencilBuffer = null; if (this.ctxAttribs.depth && this.ctxAttribs.stencil) { this.depthStencilBuffer = gl.createRenderbuffer(); } else if (this.ctxAttribs.depth) { this.depthBuffer = gl.createRenderbuffer(); } else if (this.ctxAttribs.stencil) { this.stencilBuffer = gl.createRenderbuffer(); } this.patch(); this.onResize(); if (!WebVRConfig.CARDBOARD_UI_DISABLED) { this.cardboardUI = new CardboardUI(gl); } }; /** * Tears down all the resources created by the distorter and removes any * patches. */ CardboardDistorter.prototype.destroy = function() { var gl = this.gl; this.unpatch(); gl.deleteProgram(this.program); gl.deleteBuffer(this.vertexBuffer); gl.deleteBuffer(this.indexBuffer); gl.deleteTexture(this.renderTarget); gl.deleteFramebuffer(this.framebuffer); if (this.depthStencilBuffer) { gl.deleteRenderbuffer(this.depthStencilBuffer); } if (this.depthBuffer) { gl.deleteRenderbuffer(this.depthBuffer); } if (this.stencilBuffer) { gl.deleteRenderbuffer(this.stencilBuffer); } if (this.cardboardUI) { this.cardboardUI.destroy(); } }; /** * Resizes the backbuffer to match the canvas width and height. */ CardboardDistorter.prototype.onResize = function() { var gl = this.gl; var self = this; var glState = [ gl.RENDERBUFFER_BINDING, gl.TEXTURE_BINDING_2D, gl.TEXTURE0 ]; WGLUPreserveGLState(gl, glState, function(gl) { // Bind real backbuffer and clear it once. We don't need to clear it again // after that because we're overwriting the same area every frame. self.realBindFramebuffer.call(gl, gl.FRAMEBUFFER, null); // Put things in a good state if (self.scissorTest) { self.realDisable.call(gl, gl.SCISSOR_TEST); } self.realColorMask.call(gl, true, true, true, true); self.realViewport.call(gl, 0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); self.realClearColor.call(gl, 0, 0, 0, 1); gl.clear(gl.COLOR_BUFFER_BIT); // Now bind and resize the fake backbuffer self.realBindFramebuffer.call(gl, gl.FRAMEBUFFER, self.framebuffer); gl.bindTexture(gl.TEXTURE_2D, self.renderTarget); gl.texImage2D(gl.TEXTURE_2D, 0, self.ctxAttribs.alpha ? gl.RGBA : gl.RGB, self.bufferWidth, self.bufferHeight, 0, self.ctxAttribs.alpha ? gl.RGBA : gl.RGB, gl.UNSIGNED_BYTE, null); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, self.renderTarget, 0); if (self.ctxAttribs.depth && self.ctxAttribs.stencil) { gl.bindRenderbuffer(gl.RENDERBUFFER, self.depthStencilBuffer); gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, self.bufferWidth, self.bufferHeight); gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, self.depthStencilBuffer); } else if (self.ctxAttribs.depth) { gl.bindRenderbuffer(gl.RENDERBUFFER, self.depthBuffer); gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, self.bufferWidth, self.bufferHeight); gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, self.depthBuffer); } else if (self.ctxAttribs.stencil) { gl.bindRenderbuffer(gl.RENDERBUFFER, self.stencilBuffer); gl.renderbufferStorage(gl.RENDERBUFFER, gl.STENCIL_INDEX8, self.bufferWidth, self.bufferHeight); gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT, gl.RENDERBUFFER, self.stencilBuffer); } if (!gl.checkFramebufferStatus(gl.FRAMEBUFFER) === gl.FRAMEBUFFER_COMPLETE) { console.error('Framebuffer incomplete!'); } self.realBindFramebuffer.call(gl, gl.FRAMEBUFFER, self.lastBoundFramebuffer); if (self.scissorTest) { self.realEnable.call(gl, gl.SCISSOR_TEST); } self.realColorMask.apply(gl, self.colorMask); self.realViewport.apply(gl, self.viewport); self.realClearColor.apply(gl, self.clearColor); }); if (this.cardboardUI) { this.cardboardUI.onResize(); } }; CardboardDistorter.prototype.patch = function() { if (this.isPatched) { return; } var self = this; var canvas = this.gl.canvas; var gl = this.gl; if (!Util.isIOS()) { canvas.width = Util.getScreenWidth() * this.bufferScale; canvas.height = Util.getScreenHeight() * this.bufferScale; Object.defineProperty(canvas, 'width', { configurable: true, enumerable: true, get: function() { return self.bufferWidth; }, set: function(value) { self.bufferWidth = value; self.realCanvasWidth.set.call(canvas, value); self.onResize(); } }); Object.defineProperty(canvas, 'height', { configurable: true, enumerable: true, get: function() { return self.bufferHeight; }, set: function(value) { self.bufferHeight = value; self.realCanvasHeight.set.call(canvas, value); self.onResize(); } }); } this.lastBoundFramebuffer = gl.getParameter(gl.FRAMEBUFFER_BINDING); if (this.lastBoundFramebuffer == null) { this.lastBoundFramebuffer = this.framebuffer; this.gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer); } this.gl.bindFramebuffer = function(target, framebuffer) { self.lastBoundFramebuffer = framebuffer ? framebuffer : self.framebuffer; // Silently make calls to bind the default framebuffer bind ours instead. self.realBindFramebuffer.call(gl, target, self.lastBoundFramebuffer); }; this.cullFace = gl.getParameter(gl.CULL_FACE); this.depthTest = gl.getParameter(gl.DEPTH_TEST); this.blend = gl.getParameter(gl.BLEND); this.scissorTest = gl.getParameter(gl.SCISSOR_TEST); this.stencilTest = gl.getParameter(gl.STENCIL_TEST); gl.enable = function(pname) { switch (pname) { case gl.CULL_FACE: self.cullFace = true; break; case gl.DEPTH_TEST: self.depthTest = true; break; case gl.BLEND: self.blend = true; break; case gl.SCISSOR_TEST: self.scissorTest = true; break; case gl.STENCIL_TEST: self.stencilTest = true; break; } self.realEnable.call(gl, pname); }; gl.disable = function(pname) { switch (pname) { case gl.CULL_FACE: self.cullFace = false; break; case gl.DEPTH_TEST: self.depthTest = false; break; case gl.BLEND: self.blend = false; break; case gl.SCISSOR_TEST: self.scissorTest = false; break; case gl.STENCIL_TEST: self.stencilTest = false; break; } self.realDisable.call(gl, pname); }; this.colorMask = gl.getParameter(gl.COLOR_WRITEMASK); gl.colorMask = function(r, g, b, a) { self.colorMask[0] = r; self.colorMask[1] = g; self.colorMask[2] = b; self.colorMask[3] = a; self.realColorMask.call(gl, r, g, b, a); }; this.clearColor = gl.getParameter(gl.COLOR_CLEAR_VALUE); gl.clearColor = function(r, g, b, a) { self.clearColor[0] = r; self.clearColor[1] = g; self.clearColor[2] = b; self.clearColor[3] = a; self.realClearColor.call(gl, r, g, b, a); }; this.viewport = gl.getParameter(gl.VIEWPORT); gl.viewport = function(x, y, w, h) { self.viewport[0] = x; self.viewport[1] = y; self.viewport[2] = w; self.viewport[3] = h; self.realViewport.call(gl, x, y, w, h); }; this.isPatched = true; Util.safariCssSizeWorkaround(canvas); }; CardboardDistorter.prototype.unpatch = function() { if (!this.isPatched) { return; } var gl = this.gl; var canvas = this.gl.canvas; if (!Util.isIOS()) { Object.defineProperty(canvas, 'width', this.realCanvasWidth); Object.defineProperty(canvas, 'height', this.realCanvasHeight); } canvas.width = this.bufferWidth; canvas.height = this.bufferHeight; gl.bindFramebuffer = this.realBindFramebuffer; gl.enable = this.realEnable; gl.disable = this.realDisable; gl.colorMask = this.realColorMask; gl.clearColor = this.realClearColor; gl.viewport = this.realViewport; // Check to see if our fake backbuffer is bound and bind the real backbuffer // if that's the case. if (this.lastBoundFramebuffer == this.framebuffer) { gl.bindFramebuffer(gl.FRAMEBUFFER, null); } this.isPatched = false; setTimeout(function() { Util.safariCssSizeWorkaround(canvas); }, 1); }; CardboardDistorter.prototype.setTextureBounds = function(leftBounds, rightBounds) { if (!leftBounds) { leftBounds = [0, 0, 0.5, 1]; } if (!rightBounds) { rightBounds = [0.5, 0, 0.5, 1]; } // Left eye this.viewportOffsetScale[0] = leftBounds[0]; // X this.viewportOffsetScale[1] = leftBounds[1]; // Y this.viewportOffsetScale[2] = leftBounds[2]; // Width this.viewportOffsetScale[3] = leftBounds[3]; // Height // Right eye this.viewportOffsetScale[4] = rightBounds[0]; // X this.viewportOffsetScale[5] = rightBounds[1]; // Y this.viewportOffsetScale[6] = rightBounds[2]; // Width this.viewportOffsetScale[7] = rightBounds[3]; // Height }; /** * Performs distortion pass on the injected backbuffer, rendering it to the real * backbuffer. */ CardboardDistorter.prototype.submitFrame = function() { var gl = this.gl; var self = this; var glState = []; if (!WebVRConfig.DIRTY_SUBMIT_FRAME_BINDINGS) { glState.push( gl.CURRENT_PROGRAM, gl.ARRAY_BUFFER_BINDING, gl.ELEMENT_ARRAY_BUFFER_BINDING, gl.TEXTURE_BINDING_2D, gl.TEXTURE0 ); } WGLUPreserveGLState(gl, glState, function(gl) { // Bind the real default framebuffer self.realBindFramebuffer.call(gl, gl.FRAMEBUFFER, null); // Make sure the GL state is in a good place if (self.cullFace) { self.realDisable.call(gl, gl.CULL_FACE); } if (self.depthTest) { self.realDisable.call(gl, gl.DEPTH_TEST); } if (self.blend) { self.realDisable.call(gl, gl.BLEND); } if (self.scissorTest) { self.realDisable.call(gl, gl.SCISSOR_TEST); } if (self.stencilTest) { self.realDisable.call(gl, gl.STENCIL_TEST); } self.realColorMask.call(gl, true, true, true, true); self.realViewport.call(gl, 0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); // If the backbuffer has an alpha channel clear every frame so the page // doesn't show through. if (self.ctxAttribs.alpha || Util.isIOS()) { self.realClearColor.call(gl, 0, 0, 0, 1); gl.clear(gl.COLOR_BUFFER_BIT); } // Bind distortion program and mesh gl.useProgram(self.program); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, self.indexBuffer); gl.bindBuffer(gl.ARRAY_BUFFER, self.vertexBuffer); gl.enableVertexAttribArray(self.attribs.position); gl.enableVertexAttribArray(self.attribs.texCoord); gl.vertexAttribPointer(self.attribs.position, 2, gl.FLOAT, false, 20, 0); gl.vertexAttribPointer(self.attribs.texCoord, 3, gl.FLOAT, false, 20, 8); gl.activeTexture(gl.TEXTURE0); gl.uniform1i(self.uniforms.diffuse, 0); gl.bindTexture(gl.TEXTURE_2D, self.renderTarget); gl.uniform4fv(self.uniforms.viewportOffsetScale, self.viewportOffsetScale); // Draws both eyes gl.drawElements(gl.TRIANGLES, self.indexCount, gl.UNSIGNED_SHORT, 0); if (self.cardboardUI) { self.cardboardUI.renderNoState(); } // Bind the fake default framebuffer again self.realBindFramebuffer.call(self.gl, gl.FRAMEBUFFER, self.framebuffer); // If preserveDrawingBuffer == false clear the framebuffer if (!self.ctxAttribs.preserveDrawingBuffer) { self.realClearColor.call(gl, 0, 0, 0, 0); gl.clear(gl.COLOR_BUFFER_BIT); } if (!WebVRConfig.DIRTY_SUBMIT_FRAME_BINDINGS) { self.realBindFramebuffer.call(gl, gl.FRAMEBUFFER, self.lastBoundFramebuffer); } // Restore state if (self.cullFace) { self.realEnable.call(gl, gl.CULL_FACE); } if (self.depthTest) { self.realEnable.call(gl, gl.DEPTH_TEST); } if (self.blend) { self.realEnable.call(gl, gl.BLEND); } if (self.scissorTest) { self.realEnable.call(gl, gl.SCISSOR_TEST); } if (self.stencilTest) { self.realEnable.call(gl, gl.STENCIL_TEST); } self.realColorMask.apply(gl, self.colorMask); self.realViewport.apply(gl, self.viewport); if (self.ctxAttribs.alpha || !self.ctxAttribs.preserveDrawingBuffer) { self.realClearColor.apply(gl, self.clearColor); } }); // Workaround for the fact that Safari doesn't allow us to patch the canvas // width and height correctly. After each submit frame check to see what the // real backbuffer size has been set to and resize the fake backbuffer size // to match. if (Util.isIOS()) { var canvas = gl.canvas; if (canvas.width != self.bufferWidth || canvas.height != self.bufferHeight) { self.bufferWidth = canvas.width; self.bufferHeight = canvas.height; self.onResize(); } } }; /** * Call when the deviceInfo has changed. At this point we need * to re-calculate the distortion mesh. */ CardboardDistorter.prototype.updateDeviceInfo = function(deviceInfo) { var gl = this.gl; var self = this; var glState = [gl.ARRAY_BUFFER_BINDING, gl.ELEMENT_ARRAY_BUFFER_BINDING]; WGLUPreserveGLState(gl, glState, function(gl) { var vertices = self.computeMeshVertices_(self.meshWidth, self.meshHeight, deviceInfo); gl.bindBuffer(gl.ARRAY_BUFFER, self.vertexBuffer); gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW); // Indices don't change based on device parameters, so only compute once. if (!self.indexCount) { var indices = self.computeMeshIndices_(self.meshWidth, self.meshHeight); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, self.indexBuffer); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW); self.indexCount = indices.length; } }); }; /** * Build the distortion mesh vertices. * Based on code from the Unity cardboard plugin. */ CardboardDistorter.prototype.computeMeshVertices_ = function(width, height, deviceInfo) { var vertices = new Float32Array(2 * width * height * 5); var lensFrustum = deviceInfo.getLeftEyeVisibleTanAngles(); var noLensFrustum = deviceInfo.getLeftEyeNoLensTanAngles(); var viewport = deviceInfo.getLeftEyeVisibleScreenRect(noLensFrustum); var vidx = 0; var iidx = 0; for (var e = 0; e < 2; e++) { for (var j = 0; j < height; j++) { for (var i = 0; i < width; i++, vidx++) { var u = i / (width - 1); var v = j / (height - 1); // Grid points regularly spaced in StreoScreen, and barrel distorted in // the mesh. var s = u; var t = v; var x = Util.lerp(lensFrustum[0], lensFrustum[2], u); var y = Util.lerp(lensFrustum[3], lensFrustum[1], v); var d = Math.sqrt(x * x + y * y); var r = deviceInfo.distortion.distortInverse(d); var p = x * r / d; var q = y * r / d; u = (p - noLensFrustum[0]) / (noLensFrustum[2] - noLensFrustum[0]); v = (q - noLensFrustum[3]) / (noLensFrustum[1] - noLensFrustum[3]); // Convert u,v to mesh screen coordinates. var aspect = deviceInfo.device.widthMeters / deviceInfo.device.heightMeters; // FIXME: The original Unity plugin multiplied U by the aspect ratio // and didn't multiply either value by 2, but that seems to get it // really close to correct looking for me. I hate this kind of "Don't // know why it works" code though, and wold love a more logical // explanation of what needs to happen here. u = (viewport.x + u * viewport.width - 0.5) * 2.0; //* aspect; v = (viewport.y + v * viewport.height - 0.5) * 2.0; vertices[(vidx * 5) + 0] = u; // position.x vertices[(vidx * 5) + 1] = v; // position.y vertices[(vidx * 5) + 2] = s; // texCoord.x vertices[(vidx * 5) + 3] = t; // texCoord.y vertices[(vidx * 5) + 4] = e; // texCoord.z (viewport index) } } var w = lensFrustum[2] - lensFrustum[0]; lensFrustum[0] = -(w + lensFrustum[0]); lensFrustum[2] = w - lensFrustum[2]; w = noLensFrustum[2] - noLensFrustum[0]; noLensFrustum[0] = -(w + noLensFrustum[0]); noLensFrustum[2] = w - noLensFrustum[2]; viewport.x = 1 - (viewport.x + viewport.width); } return vertices; } /** * Build the distortion mesh indices. * Based on code from the Unity cardboard plugin. */ CardboardDistorter.prototype.computeMeshIndices_ = function(width, height) { var indices = new Uint16Array(2 * (width - 1) * (height - 1) * 6); var halfwidth = width / 2; var halfheight = height / 2; var vidx = 0; var iidx = 0; for (var e = 0; e < 2; e++) { for (var j = 0; j < height; j++) { for (var i = 0; i < width; i++, vidx++) { if (i == 0 || j == 0) continue; // Build a quad. Lower right and upper left quadrants have quads with // the triangle diagonal flipped to get the vignette to interpolate // correctly. if ((i <= halfwidth) == (j <= halfheight)) { // Quad diagonal lower left to upper right. indices[iidx++] = vidx; indices[iidx++] = vidx - width - 1; indices[iidx++] = vidx - width; indices[iidx++] = vidx - width - 1; indices[iidx++] = vidx; indices[iidx++] = vidx - 1; } else { // Quad diagonal upper left to lower right. indices[iidx++] = vidx - 1; indices[iidx++] = vidx - width; indices[iidx++] = vidx; indices[iidx++] = vidx - width; indices[iidx++] = vidx - 1; indices[iidx++] = vidx - width - 1; } } } } return indices; }; CardboardDistorter.prototype.getOwnPropertyDescriptor_ = function(proto, attrName) { var descriptor = Object.getOwnPropertyDescriptor(proto, attrName); // In some cases (ahem... Safari), the descriptor returns undefined get and // set fields. In this case, we need to create a synthetic property // descriptor. This works around some of the issues in // https://github.com/borismus/webvr-polyfill/issues/46 if (descriptor.get === undefined || descriptor.set === undefined) { descriptor.configurable = true; descriptor.enumerable = true; descriptor.get = function() { return this.getAttribute(attrName); }; descriptor.set = function(val) { this.setAttribute(attrName, val); }; } return descriptor; }; module.exports = CardboardDistorter; },{"./cardboard-ui.js":5,"./deps/wglu-preserve-state.js":7,"./util.js":22}],5:[function(_dereq_,module,exports){ /* * Copyright 2016 Google Inc. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var Util = _dereq_('./util.js'); var WGLUPreserveGLState = _dereq_('./deps/wglu-preserve-state.js'); var uiVS = [ 'attribute vec2 position;', 'uniform mat4 projectionMat;', 'void main() {', ' gl_Position = projectionMat * vec4( position, -1.0, 1.0 );', '}', ].join('\n'); var uiFS = [ 'precision mediump float;', 'uniform vec4 color;', 'void main() {', ' gl_FragColor = color;', '}', ].join('\n'); var DEG2RAD = Math.PI/180.0; // The gear has 6 identical sections, each spanning 60 degrees. var kAnglePerGearSection = 60; // Half-angle of the span of the outer rim. var kOuterRimEndAngle = 12; // Angle between the middle of the outer rim and the start of the inner rim. var kInnerRimBeginAngle = 20; // Distance from center to outer rim, normalized so that the entire model // fits in a [-1, 1] x [-1, 1] square. var kOuterRadius = 1; // Distance from center to depressed rim, in model units. var kMiddleRadius = 0.75; // Radius of the inner hollow circle, in model units. var kInnerRadius = 0.3125; // Center line thickness in DP. var kCenterLineThicknessDp = 4; // Button width in DP. var kButtonWidthDp = 28; // Factor to scale the touch area that responds to the touch. var kTouchSlopFactor = 1.5; var Angles = [ 0, kOuterRimEndAngle, kInnerRimBeginAngle, kAnglePerGearSection - kInnerRimBeginAngle, kAnglePerGearSection - kOuterRimEndAngle ]; /** * Renders the alignment line and "options" gear. It is assumed that the canvas * this is rendered into covers the entire screen (or close to it.) */ function CardboardUI(gl) { this.gl = gl; this.attribs = { position: 0 }; this.program = Util.linkProgram(gl, uiVS, uiFS, this.attribs); this.uniforms = Util.getProgramUniforms(gl, this.program); this.vertexBuffer = gl.createBuffer(); this.gearOffset = 0; this.gearVertexCount = 0; this.arrowOffset = 0; this.arrowVertexCount = 0; this.projMat = new Float32Array(16); this.listener = null; this.onResize(); }; /** * Tears down all the resources created by the UI renderer. */ CardboardUI.prototype.destroy = function() { var gl = this.gl; if (this.listener) { gl.canvas.removeEventListener('click', this.listener, false); } gl.deleteProgram(this.program); gl.deleteBuffer(this.vertexBuffer); }; /** * Adds a listener to clicks on the gear and back icons */ CardboardUI.prototype.listen = function(optionsCallback, backCallback) { var canvas = this.gl.canvas; this.listener = function(event) { var midline = canvas.clientWidth / 2; var buttonSize = kButtonWidthDp * kTouchSlopFactor; // Check to see if the user clicked on (or around) the gear icon if (event.clientX > midline - buttonSize && event.clientX < midline + buttonSize && event.clientY > canvas.clientHeight - buttonSize) { optionsCallback(event); } // Check to see if the user clicked on (or around) the back icon else if (event.clientX < buttonSize && event.clientY < buttonSize) { backCallback(event); } }; canvas.addEventListener('click', this.listener, false); }; /** * Builds the UI mesh. */ CardboardUI.prototype.onResize = function() { var gl = this.gl; var self = this; var glState = [ gl.ARRAY_BUFFER_BINDING ]; WGLUPreserveGLState(gl, glState, function(gl) { var vertices = []; var midline = gl.drawingBufferWidth / 2; // Assumes your canvas width and height is scaled proportionately. // TODO(smus): The following causes buttons to become huge on iOS, but seems // like the right thing to do. For now, added a hack. But really, investigate why. var dps = (gl.drawingBufferWidth / (screen.width * window.devicePixelRatio)); if (!Util.isIOS()) { dps *= window.devicePixelRatio; } var lineWidth = kCenterLineThicknessDp * dps / 2; var buttonSize = kButtonWidthDp * kTouchSlopFactor * dps; var buttonScale = kButtonWidthDp * dps / 2; var buttonBorder = ((kButtonWidthDp * kTouchSlopFactor) - kButtonWidthDp) * dps; // Build centerline vertices.push(midline - lineWidth, buttonSize); vertices.push(midline - lineWidth, gl.drawingBufferHeight); vertices.push(midline + lineWidth, buttonSize); vertices.push(midline + lineWidth, gl.drawingBufferHeight); // Build gear self.gearOffset = (vertices.length / 2); function addGearSegment(theta, r) { var angle = (90 - theta) * DEG2RAD; var x = Math.cos(angle); var y = Math.sin(angle); vertices.push(kInnerRadius * x * buttonScale + midline, kInnerRadius * y * buttonScale + buttonScale); vertices.push(r * x * buttonScale + midline, r * y * buttonScale + buttonScale); } for (var i = 0; i <= 6; i++) { var segmentTheta = i * kAnglePerGearSection; addGearSegment(segmentTheta, kOuterRadius); addGearSegment(segmentTheta + kOuterRimEndAngle, kOuterRadius); addGearSegment(segmentTheta + kInnerRimBeginAngle, kMiddleRadius); addGearSegment(segmentTheta + (kAnglePerGearSection - kInnerRimBeginAngle), kMiddleRadius); addGearSegment(segmentTheta + (kAnglePerGearSection - kOuterRimEndAngle), kOuterRadius); } self.gearVertexCount = (vertices.length / 2) - self.gearOffset; // Build back arrow self.arrowOffset = (vertices.length / 2); function addArrowVertex(x, y) { vertices.push(buttonBorder + x, gl.drawingBufferHeight - buttonBorder - y); } var angledLineWidth = lineWidth / Math.sin(45 * DEG2RAD); addArrowVertex(0, buttonScale); addArrowVertex(buttonScale, 0); addArrowVertex(buttonScale + angledLineWidth, angledLineWidth); addArrowVertex(angledLineWidth, buttonScale + angledLineWidth); addArrowVertex(angledLineWidth, buttonScale - angledLineWidth); addArrowVertex(0, buttonScale); addArrowVertex(buttonScale, buttonScale * 2); addArrowVertex(buttonScale + angledLineWidth, (buttonScale * 2) - angledLineWidth); addArrowVertex(angledLineWidth, buttonScale - angledLineWidth); addArrowVertex(0, buttonScale); addArrowVertex(angledLineWidth, buttonScale - lineWidth); addArrowVertex(kButtonWidthDp * dps, buttonScale - lineWidth); addArrowVertex(angledLineWidth, buttonScale + lineWidth); addArrowVertex(kButtonWidthDp * dps, buttonScale + lineWidth); self.arrowVertexCount = (vertices.length / 2) - self.arrowOffset; // Buffer data gl.bindBuffer(gl.ARRAY_BUFFER, self.vertexBuffer); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); }); }; /** * Performs distortion pass on the injected backbuffer, rendering it to the real * backbuffer. */ CardboardUI.prototype.render = function() { var gl = this.gl; var self = this; var glState = [ gl.CULL_FACE, gl.DEPTH_TEST, gl.BLEND, gl.SCISSOR_TEST, gl.STENCIL_TEST, gl.COLOR_WRITEMASK, gl.VIEWPORT, gl.CURRENT_PROGRAM, gl.ARRAY_BUFFER_BINDING ]; WGLUPreserveGLState(gl, glState, function(gl) { // Make sure the GL state is in a good place gl.disable(gl.CULL_FACE); gl.disable(gl.DEPTH_TEST); gl.disable(gl.BLEND); gl.disable(gl.SCISSOR_TEST); gl.disable(gl.STENCIL_TEST); gl.colorMask(true, true, true, true); gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); self.renderNoState(); }); }; CardboardUI.prototype.renderNoState = function() { var gl = this.gl; // Bind distortion program and mesh gl.useProgram(this.program); gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); gl.enableVertexAttribArray(this.attribs.position); gl.vertexAttribPointer(this.attribs.position, 2, gl.FLOAT, false, 8, 0); gl.uniform4f(this.uniforms.color, 1.0, 1.0, 1.0, 1.0); Util.orthoMatrix(this.projMat, 0, gl.drawingBufferWidth, 0, gl.drawingBufferHeight, 0.1, 1024.0); gl.uniformMatrix4fv(this.uniforms.projectionMat, false, this.projMat); // Draws UI element gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); gl.drawArrays(gl.TRIANGLE_STRIP, this.gearOffset, this.gearVertexCount); gl.drawArrays(gl.TRIANGLE_STRIP, this.arrowOffset, this.arrowVertexCount); }; module.exports = CardboardUI; },{"./deps/wglu-preserve-state.js":7,"./util.js":22}],6:[function(_dereq_,module,exports){ /* * Copyright 2016 Google Inc. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var CardboardDistorter = _dereq_('./cardboard-distorter.js'); var CardboardUI = _dereq_('./cardboard-ui.js'); var DeviceInfo = _dereq_('./device-info.js'); var Dpdb = _dereq_('./dpdb/dpdb.js'); var FusionPoseSensor = _dereq_('./sensor-fusion/fusion-pose-sensor.js'); var RotateInstructions = _dereq_('./rotate-instructions.js'); var ViewerSelector = _dereq_('./viewer-selector.js'); var VRDisplay = _dereq_('./base.js').VRDisplay; var Util = _dereq_('./util.js'); var Eye = { LEFT: 'left', RIGHT: 'right' }; /** * VRDisplay based on mobile device parameters and DeviceMotion APIs. */ function CardboardVRDisplay() { this.displayName = 'Cardboard VRDisplay (webvr-polyfill)'; this.capabilities.hasOrientation = true; this.capabilities.canPresent = true; // "Private" members. this.bufferScale_ = WebVRConfig.BUFFER_SCALE; this.poseSensor_ = new FusionPoseSensor(); this.distorter_ = null; this.cardboardUI_ = null; this.dpdb_ = new Dpdb(true, this.onDeviceParamsUpdated_.bind(this)); this.deviceInfo_ = new DeviceInfo(this.dpdb_.getDeviceParams()); this.viewerSelector_ = new ViewerSelector(); this.viewerSelector_.on('change', this.onViewerChanged_.bind(this)); // Set the correct initial viewer. this.deviceInfo_.setViewer(this.viewerSelector_.getCurrentViewer()); if (!WebVRConfig.ROTATE_INSTRUCTIONS_DISABLED) { this.rotateInstructions_ = new RotateInstructions(); } if (Util.isIOS()) { // Listen for resize events to workaround this awful Safari bug. window.addEventListener('resize', this.onResize_.bind(this)); } } CardboardVRDisplay.prototype = new VRDisplay(); CardboardVRDisplay.prototype.getImmediatePose = function() { return { position: this.poseSensor_.getPosition(), orientation: this.poseSensor_.getOrientation(), linearVelocity: null, linearAcceleration: null, angularVelocity: null, angularAcceleration: null }; }; CardboardVRDisplay.prototype.resetPose = function() { this.poseSensor_.resetPose(); }; CardboardVRDisplay.prototype.getEyeParameters = function(whichEye) { var offset = [this.deviceInfo_.viewer.interLensDistance * 0.5, 0.0, 0.0]; var fieldOfView; // TODO: FoV can be a little expensive to compute. Cache when device params change. if (whichEye == Eye.LEFT) { offset[0] *= -1.0; fieldOfView = this.deviceInfo_.getFieldOfViewLeftEye(); } else if (whichEye == Eye.RIGHT) { fieldOfView = this.deviceInfo_.getFieldOfViewRightEye(); } else { console.error('Invalid eye provided: %s', whichEye); return null; } return { fieldOfView: fieldOfView, offset: offset, // TODO: Should be able to provide better values than these. renderWidth: this.deviceInfo_.device.width * 0.5 * this.bufferScale_, renderHeight: this.deviceInfo_.device.height * this.bufferScale_, }; }; CardboardVRDisplay.prototype.onDeviceParamsUpdated_ = function(newParams) { if (Util.isDebug()) { console.log('DPDB reported that device params were updated.'); } this.deviceInfo_.updateDeviceParams(newParams); if (this.distorter_) { this.distorter_.updateDeviceInfo(this.deviceInfo_); } }; CardboardVRDisplay.prototype.updateBounds_ = function () { if (this.layer_ && this.distorter_ && (this.layer_.leftBounds || this.layer_.rightBounds)) { this.distorter_.setTextureBounds(this.layer_.leftBounds, this.layer_.rightBounds); } }; CardboardVRDisplay.prototype.beginPresent_ = function() { var gl = this.layer_.source.getContext('webgl'); if (!gl) gl = this.layer_.source.getContext('experimental-webgl'); if (!gl) gl = this.layer_.source.getContext('webgl2'); if (!gl) return; // Can't do distortion without a WebGL context. // Provides a way to opt out of distortion if (this.layer_.predistorted) { if (!WebVRConfig.CARDBOARD_UI_DISABLED) { gl.canvas.width = Util.getScreenWidth() * this.bufferScale_; gl.canvas.height = Util.getScreenHeight() * this.bufferScale_; this.cardboardUI_ = new CardboardUI(gl); } } else { // Create a new distorter for the target context this.distorter_ = new CardboardDistorter(gl); this.distorter_.updateDeviceInfo(this.deviceInfo_); this.cardboardUI_ = this.distorter_.cardboardUI; } if (this.cardboardUI_) { this.cardboardUI_.listen(function(e) { // Options clicked. this.viewerSelector_.show(this.layer_.source.parentElement); e.stopPropagation(); e.preventDefault(); }.bind(this), function(e) { // Back clicked. this.exitPresent(); e.stopPropagation(); e.preventDefault(); }.bind(this)); } if (this.rotateInstructions_) { if (Util.isLandscapeMode() && Util.isMobile()) { // In landscape mode, temporarily show the "put into Cardboard" // interstitial. Otherwise, do the default thing. this.rotateInstructions_.showTemporarily(3000, this.layer_.source.parentElement); } else { this.rotateInstructions_.update(); } } // Listen for orientation change events in order to show interstitial. this.orientationHandler = this.onOrientationChange_.bind(this); window.addEventListener('orientationchange', this.orientationHandler); // Listen for present display change events in order to update distorter dimensions this.vrdisplaypresentchangeHandler = this.updateBounds_.bind(this); window.addEventListener('vrdisplaypresentchange', this.vrdisplaypresentchangeHandler); // Fire this event initially, to give geometry-distortion clients the chance // to do something custom. this.fireVRDisplayDeviceParamsChange_(); }; CardboardVRDisplay.prototype.endPresent_ = function() { if (this.distorter_) { this.distorter_.destroy(); this.distorter_ = null; } if (this.cardboardUI_) { this.cardboardUI_.destroy(); this.cardboardUI_ = null; } if (this.rotateInstructions_) { this.rotateInstructions_.hide(); } this.viewerSelector_.hide(); window.removeEventListener('orientationchange', this.orientationHandler); window.removeEventListener('vrdisplaypresentchange', this.vrdisplaypresentchangeHandler); }; CardboardVRDisplay.prototype.submitFrame = function(pose) { if (this.distorter_) { this.distorter_.submitFrame(); } else if (this.cardboardUI_ && this.layer_) { // Hack for predistorted: true. var canvas = this.layer_.source.getContext('webgl').canvas; if (canvas.width != this.lastWidth || canvas.height != this.lastHeight) { this.cardboardUI_.onResize(); } this.lastWidth = canvas.width; this.lastHeight = canvas.height; // Render the Cardboard UI. this.cardboardUI_.render(); } }; CardboardVRDisplay.prototype.onOrientationChange_ = function(e) { // Hide the viewer selector. this.viewerSelector_.hide(); // Update the rotate instructions. if (this.rotateInstructions_) { this.rotateInstructions_.update(); } this.onResize_(); }; CardboardVRDisplay.prototype.onResize_ = function(e) { if (this.layer_) { var gl = this.layer_.source.getContext('webgl'); // Size the CSS canvas. // Added padding on right and bottom because iPhone 5 will not // hide the URL bar unless content is bigger than the screen. // This will not be visible as long as the container element (e.g. body) // is set to 'overflow: hidden'. var cssProperties = [ 'position: absolute', 'top: 0', 'left: 0', 'width: ' + Math.max(screen.width, screen.height) + 'px', 'height: ' + Math.min(screen.height, screen.width) + 'px', 'border: 0', 'margin: 0', 'padding: 0 10px 10px 0', ]; gl.canvas.setAttribute('style', cssProperties.join('; ') + ';'); Util.safariCssSizeWorkaround(gl.canvas); } }; CardboardVRDisplay.prototype.onViewerChanged_ = function(viewer) { this.deviceInfo_.setViewer(viewer); if (this.distorter_) { // Update the distortion appropriately. this.distorter_.updateDeviceInfo(this.deviceInfo_); } // Fire a new event containing viewer and device parameters for clients that // want to implement their own geometry-based distortion. this.fireVRDisplayDeviceParamsChange_(); }; CardboardVRDisplay.prototype.fireVRDisplayDeviceParamsChange_ = function() { var event = new CustomEvent('vrdisplaydeviceparamschange', { detail: { vrdisplay: this, deviceInfo: this.deviceInfo_, } }); window.dispatchEvent(event); }; module.exports = CardboardVRDisplay; },{"./base.js":3,"./cardboard-distorter.js":4,"./cardboard-ui.js":5,"./device-info.js":8,"./dpdb/dpdb.js":12,"./rotate-instructions.js":16,"./sensor-fusion/fusion-pose-sensor.js":18,"./util.js":22,"./viewer-selector.js":23}],7:[function(_dereq_,module,exports){ /* Copyright (c) 2016, Brandon Jones. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* Caches specified GL state, runs a callback, and restores the cached state when done. Example usage: var savedState = [ gl.ARRAY_BUFFER_BINDING, // TEXTURE_BINDING_2D or _CUBE_MAP must always be followed by the texure unit. gl.TEXTURE_BINDING_2D, gl.TEXTURE0, gl.CLEAR_COLOR, ]; // After this call the array buffer, texture unit 0, active texture, and clear // color will be restored. The viewport will remain changed, however, because // gl.VIEWPORT was not included in the savedState list. WGLUPreserveGLState(gl, savedState, function(gl) { gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); gl.bindBuffer(gl.ARRAY_BUFFER, buffer); gl.bufferData(gl.ARRAY_BUFFER, ....); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, texture); gl.texImage2D(gl.TEXTURE_2D, ...); gl.clearColor(1, 0, 0, 1); gl.clear(gl.COLOR_BUFFER_BIT); }); Note that this is not intended to be fast. Managing state in your own code to avoid redundant state setting and querying will always be faster. This function is most useful for cases where you may not have full control over the WebGL calls being made, such as tooling or effect injectors. */ function WGLUPreserveGLState(gl, bindings, callback) { if (!bindings) { callback(gl); return; } var boundValues = []; var activeTexture = null; for (var i = 0; i < bindings.length; ++i) { var binding = bindings[i]; switch (binding) { case gl.TEXTURE_BINDING_2D: case gl.TEXTURE_BINDING_CUBE_MAP: var textureUnit = bindings[++i]; if (textureUnit < gl.TEXTURE0 || textureUnit > gl.TEXTURE31) { console.error("TEXTURE_BINDING_2D or TEXTURE_BINDING_CUBE_MAP must be followed by a valid texture unit"); boundValues.push(null, null); break; } if (!activeTexture) { activeTexture = gl.getParameter(gl.ACTIVE_TEXTURE); } gl.activeTexture(textureUnit); boundValues.push(gl.getParameter(binding), null); break; case gl.ACTIVE_TEXTURE: activeTexture = gl.getParameter(gl.ACTIVE_TEXTURE); boundValues.push(null); break; default: boundValues.push(gl.getParameter(binding)); break; } } callback(gl); for (var i = 0; i < bindings.length; ++i) { var binding = bindings[i]; var boundValue = boundValues[i]; switch (binding) { case gl.ACTIVE_TEXTURE: break; // Ignore this binding, since we special-case it to happen last. case gl.ARRAY_BUFFER_BINDING: gl.bindBuffer(gl.ARRAY_BUFFER, boundValue); break; case gl.COLOR_CLEAR_VALUE: gl.clearColor(boundValue[0], boundValue[1], boundValue[2], boundValue[3]); break; case gl.COLOR_WRITEMASK: gl.colorMask(boundValue[0], boundValue[1], boundValue[2], boundValue[3]); break; case gl.CURRENT_PROGRAM: gl.useProgram(boundValue); break; case gl.ELEMENT_ARRAY_BUFFER_BINDING: gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, boundValue); break; case gl.FRAMEBUFFER_BINDING: gl.bindFramebuffer(gl.FRAMEBUFFER, boundValue); break; case gl.RENDERBUFFER_BINDING: gl.bindRenderbuffer(gl.RENDERBUFFER, boundValue); break; case gl.TEXTURE_BINDING_2D: var textureUnit = bindings[++i]; if (textureUnit < gl.TEXTURE0 || textureUnit > gl.TEXTURE31) break; gl.activeTexture(textureUnit); gl.bindTexture(gl.TEXTURE_2D, boundValue); break; case gl.TEXTURE_BINDING_CUBE_MAP: var textureUnit = bindings[++i]; if (textureUnit < gl.TEXTURE0 || textureUnit > gl.TEXTURE31) break; gl.activeTexture(textureUnit); gl.bindTexture(gl.TEXTURE_CUBE_MAP, boundValue); break; case gl.VIEWPORT: gl.viewport(boundValue[0], boundValue[1], boundValue[2], boundValue[3]); break; case gl.BLEND: case gl.CULL_FACE: case gl.DEPTH_TEST: case gl.SCISSOR_TEST: case gl.STENCIL_TEST: if (boundValue) { gl.enable(binding); } else { gl.disable(binding); } break; default: console.log("No GL restore behavior for 0x" + binding.toString(16)); break; } if (activeTexture) { gl.activeTexture(activeTexture); } } } module.exports = WGLUPreserveGLState; },{}],8:[function(_dereq_,module,exports){ /* * Copyright 2015 Google Inc. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var Distortion = _dereq_('./distortion/distortion.js'); var MathUtil = _dereq_('./math-util.js'); var Util = _dereq_('./util.js'); function Device(params) { this.width = params.width || Util.getScreenWidth(); this.height = params.height || Util.getScreenHeight(); this.widthMeters = params.widthMeters; this.heightMeters = params.heightMeters; this.bevelMeters = params.bevelMeters; } // Fallback Android device (based on Nexus 5 measurements) for use when // we can't recognize an Android device. var DEFAULT_ANDROID = new Device({ widthMeters: 0.110, heightMeters: 0.062, bevelMeters: 0.004 }); // Fallback iOS device (based on iPhone6) for use when // we can't recognize an Android device. var DEFAULT_IOS = new Device({ widthMeters: 0.1038, heightMeters: 0.0584, bevelMeters: 0.004 }); var Viewers = { CardboardV1: new CardboardViewer({ id: 'CardboardV1', label: 'Cardboard I/O 2014', fov: 40, interLensDistance: 0.060, baselineLensDistance: 0.035, screenLensDistance: 0.042, distortionCoefficients: [0.441, 0.156], inverseCoefficients: [-0.4410035, 0.42756155, -0.4804439, 0.5460139, -0.58821183, 0.5733938, -0.48303202, 0.33299083, -0.17573841, 0.0651772, -0.01488963, 0.001559834] }), CardboardV2: new CardboardViewer({ id: 'CardboardV2', label: 'Cardboard I/O 2015', fov: 60, interLensDistance: 0.064, baselineLensDistance: 0.035, screenLensDistance: 0.039, distortionCoefficients: [0.34, 0.55], inverseCoefficients: [-0.33836704, -0.18162185, 0.862655, -1.2462051, 1.0560602, -0.58208317, 0.21609078, -0.05444823, 0.009177956, -9.904169E-4, 6.183535E-5, -1.6981803E-6] }) }; var DEFAULT_LEFT_CENTER = {x: 0.5, y: 0.5}; var DEFAULT_RIGHT_CENTER = {x: 0.5, y: 0.5}; /** * Manages information about the device and the viewer. * * deviceParams indicates the parameters of the device to use (generally * obtained from dpdb.getDeviceParams()). Can be null to mean no device * params were found. */ function DeviceInfo(deviceParams) { this.viewer = Viewers.CardboardV2; this.updateDeviceParams(deviceParams); this.distortion = new Distortion(this.viewer.distortionCoefficients); } DeviceInfo.prototype.updateDeviceParams = function(deviceParams) { this.device = this.determineDevice_(deviceParams) || this.device; }; DeviceInfo.prototype.getDevice = function() { return this.device; }; DeviceInfo.prototype.setViewer = function(viewer) { this.viewer = viewer; this.distortion = new Distortion(this.viewer.distortionCoefficients); }; DeviceInfo.prototype.determineDevice_ = function(deviceParams) { if (!deviceParams) { // No parameters, so use a default. if (Util.isIOS()) { console.warn('Using fallback iOS device measurements.'); return DEFAULT_IOS; } else { console.warn('Using fallback Android device measurements.'); return DEFAULT_ANDROID; } } // Compute device screen dimensions based on deviceParams. var METERS_PER_INCH = 0.0254; var metersPerPixelX = METERS_PER_INCH / deviceParams.xdpi; var metersPerPixelY = METERS_PER_INCH / deviceParams.ydpi; var width = Util.getScreenWidth(); var height = Util.getScreenHeight(); return new Device({ widthMeters: metersPerPixelX * width, heightMeters: metersPerPixelY * height, bevelMeters: deviceParams.bevelMm * 0.001, }); }; /** * Calculates field of view for the left eye. */ DeviceInfo.prototype.getDistortedFieldOfViewLeftEye = function() { var viewer = this.viewer; var device = this.device; var distortion = this.distortion; // Device.height and device.width for device in portrait mode, so transpose. var eyeToScreenDistance = viewer.screenLensDistance; var outerDist = (device.widthMeters - viewer.interLensDistance) / 2; var innerDist = viewer.interLensDistance / 2; var bottomDist = viewer.baselineLensDistance - device.bevelMeters; var topDist = device.heightMeters - bottomDist; var outerAngle = MathUtil.radToDeg * Math.atan( distortion.distort(outerDist / eyeToScreenDistance)); var innerAngle = MathUtil.radToDeg * Math.atan( distortion.distort(innerDist / eyeToScreenDistance)); var bottomAngle = MathUtil.radToDeg * Math.atan( distortion.distort(bottomDist / eyeToScreenDistance)); var topAngle = MathUtil.radToDeg * Math.atan( distortion.distort(topDist / eyeToScreenDistance)); return { leftDegrees: Math.min(outerAngle, viewer.fov), rightDegrees: Math.min(innerAngle, viewer.fov), downDegrees: Math.min(bottomAngle, viewer.fov), upDegrees: Math.min(topAngle, viewer.fov) }; }; /** * Calculates the tan-angles from the maximum FOV for the left eye for the * current device and screen parameters. */ DeviceInfo.prototype.getLeftEyeVisibleTanAngles = function() { var viewer = this.viewer; var device = this.device; var distortion = this.distortion; // Tan-angles from the max FOV. var fovLeft = Math.tan(-MathUtil.degToRad * viewer.fov); var fovTop = Math.tan(MathUtil.degToRad * viewer.fov); var fovRight = Math.tan(MathUtil.degToRad * viewer.fov); var fovBottom = Math.tan(-MathUtil.degToRad * viewer.fov); // Viewport size. var halfWidth = device.widthMeters / 4; var halfHeight = device.heightMeters / 2; // Viewport center, measured from left lens position. var verticalLensOffset = (viewer.baselineLensDistance - device.bevelMeters - halfHeight); var centerX = viewer.interLensDistance / 2 - halfWidth; var centerY = -verticalLensOffset; var centerZ = viewer.screenLensDistance; // Tan-angles of the viewport edges, as seen through the lens. var screenLeft = distortion.distort((centerX - halfWidth) / centerZ); var screenTop = distortion.distort((centerY + halfHeight) / centerZ); var screenRight = distortion.distort((centerX + halfWidth) / centerZ); var screenBottom = distortion.distort((centerY - halfHeight) / centerZ); // Compare the two sets of tan-angles and take the value closer to zero on each side. var result = new Float32Array(4); result[0] = Math.max(fovLeft, screenLeft); result[1] = Math.min(fovTop, screenTop); result[2] = Math.min(fovRight, screenRight); result[3] = Math.max(fovBottom, screenBottom); return result; }; /** * Calculates the tan-angles from the maximum FOV for the left eye for the * current device and screen parameters, assuming no lenses. */ DeviceInfo.prototype.getLeftEyeNoLensTanAngles = function() { var viewer = this.viewer; var device = this.device; var distortion = this.distortion; var result = new Float32Array(4); // Tan-angles from the max FOV. var fovLeft = distortion.distortInverse(Math.tan(-MathUtil.degToRad * viewer.fov)); var fovTop = distortion.distortInverse(Math.tan(MathUtil.degToRad * viewer.fov)); var fovRight = distortion.distortInverse(Math.tan(MathUtil.degToRad * viewer.fov)); var fovBottom = distortion.distortInverse(Math.tan(-MathUtil.degToRad * viewer.fov)); // Viewport size. var halfWidth = device.widthMeters / 4; var halfHeight = device.heightMeters / 2; // Viewport center, measured from left lens position. var verticalLensOffset = (viewer.baselineLensDistance - device.bevelMeters - halfHeight); var centerX = viewer.interLensDistance / 2 - halfWidth; var centerY = -verticalLensOffset; var centerZ = viewer.screenLensDistance; // Tan-angles of the viewport edges, as seen through the lens. var screenLeft = (centerX - halfWidth) / centerZ; var screenTop = (centerY + halfHeight) / centerZ; var screenRight = (centerX + halfWidth) / centerZ; var screenBottom = (centerY - halfHeight) / centerZ; // Compare the two sets of tan-angles and take the value closer to zero on each side. result[0] = Math.max(fovLeft, screenLeft); result[1] = Math.min(fovTop, screenTop); result[2] = Math.min(fovRight, screenRight); result[3] = Math.max(fovBottom, screenBottom); return result; }; /** * Calculates the screen rectangle visible from the left eye for the * current device and screen parameters. */ DeviceInfo.prototype.getLeftEyeVisibleScreenRect = function(undistortedFrustum) { var viewer = this.viewer; var device = this.device; var dist = viewer.screenLensDistance; var eyeX = (device.widthMeters - viewer.interLensDistance) / 2; var eyeY = viewer.baselineLensDistance - device.bevelMeters; var left = (undistortedFrustum[0] * dist + eyeX) / device.widthMeters; var top = (undistortedFrustum[1] * dist + eyeY) / device.heightMeters; var right = (undistortedFrustum[2] * dist + eyeX) / device.widthMeters; var bottom = (undistortedFrustum[3] * dist + eyeY) / device.heightMeters; return { x: left, y: bottom, width: right - left, height: top - bottom }; }; DeviceInfo.prototype.getFieldOfViewLeftEye = function(opt_isUndistorted) { return opt_isUndistorted ? this.getUndistortedFieldOfViewLeftEye() : this.getDistortedFieldOfViewLeftEye(); }; DeviceInfo.prototype.getFieldOfViewRightEye = function(opt_isUndistorted) { var fov = this.getFieldOfViewLeftEye(opt_isUndistorted); return { leftDegrees: fov.rightDegrees, rightDegrees: fov.leftDegrees, upDegrees: fov.upDegrees, downDegrees: fov.downDegrees }; }; /** * Calculates undistorted field of view for the left eye. */ DeviceInfo.prototype.getUndistortedFieldOfViewLeftEye = function() { var p = this.getUndistortedParams_(); return { leftDegrees: MathUtil.radToDeg * Math.atan(p.outerDist), rightDegrees: MathUtil.radToDeg * Math.atan(p.innerDist), downDegrees: MathUtil.radToDeg * Math.atan(p.bottomDist), upDegrees: MathUtil.radToDeg * Math.atan(p.topDist) }; }; DeviceInfo.prototype.getUndistortedViewportLeftEye = function() { var p = this.getUndistortedParams_(); var viewer = this.viewer; var device = this.device; // Distances stored in local variables are in tan-angle units unless otherwise // noted. var eyeToScreenDistance = viewer.screenLensDistance; var screenWidth = device.widthMeters / eyeToScreenDistance; var screenHeight = device.heightMeters / eyeToScreenDistance; var xPxPerTanAngle = device.width / screenWidth; var yPxPerTanAngle = device.height / screenHeight; var x = Math.round((p.eyePosX - p.outerDist) * xPxPerTanAngle); var y = Math.round((p.eyePosY - p.bottomDist) * yPxPerTanAngle); return { x: x, y: y, width: Math.round((p.eyePosX + p.innerDist) * xPxPerTanAngle) - x, height: Math.round((p.eyePosY + p.topDist) * yPxPerTanAngle) - y }; }; DeviceInfo.prototype.getUndistortedParams_ = function() { var viewer = this.viewer; var device = this.device; var distortion = this.distortion; // Most of these variables in tan-angle units. var eyeToScreenDistance = viewer.screenLensDistance; var halfLensDistance = viewer.interLensDistance / 2 / eyeToScreenDistance; var screenWidth = device.widthMeters / eyeToScreenDistance; var screenHeight = device.heightMeters / eyeToScreenDistance; var eyePosX = screenWidth / 2 - halfLensDistance; var eyePosY = (viewer.baselineLensDistance - device.bevelMeters) / eyeToScreenDistance; var maxFov = viewer.fov; var viewerMax = distortion.distortInverse(Math.tan(MathUtil.degToRad * maxFov)); var outerDist = Math.min(eyePosX, viewerMax); var innerDist = Math.min(halfLensDistance, viewerMax); var bottomDist = Math.min(eyePosY, viewerMax); var topDist = Math.min(screenHeight - eyePosY, viewerMax); return { outerDist: outerDist, innerDist: innerDist, topDist: topDist, bottomDist: bottomDist, eyePosX: eyePosX, eyePosY: eyePosY }; }; function CardboardViewer(params) { // A machine readable ID. this.id = params.id; // A human readable label. this.label = params.label; // Field of view in degrees (per side). this.fov = params.fov; // Distance between lens centers in meters. this.interLensDistance = params.interLensDistance; // Distance between viewer baseline and lens center in meters. this.baselineLensDistance = params.baselineLensDistance; // Screen-to-lens distance in meters. this.screenLensDistance = params.screenLensDistance; // Distortion coefficients. this.distortionCoefficients = params.distortionCoefficients; // Inverse distortion coefficients. // TODO: Calculate these from distortionCoefficients in the future. this.inverseCoefficients = params.inverseCoefficients; } // Export viewer information. DeviceInfo.Viewers = Viewers; module.exports = DeviceInfo; },{"./distortion/distortion.js":10,"./math-util.js":14,"./util.js":22}],9:[function(_dereq_,module,exports){ /* * Copyright 2016 Google Inc. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var VRDisplay = _dereq_('./base.js').VRDisplay; var HMDVRDevice = _dereq_('./base.js').HMDVRDevice; var PositionSensorVRDevice = _dereq_('./base.js').PositionSensorVRDevice; /** * Wraps a VRDisplay and exposes it as a HMDVRDevice */ function VRDisplayHMDDevice(display) { this.display = display; this.hardwareUnitId = display.displayId; this.deviceId = 'webvr-polyfill:HMD:' + display.displayId; this.deviceName = display.displayName + ' (HMD)'; } VRDisplayHMDDevice.prototype = new HMDVRDevice(); VRDisplayHMDDevice.prototype.getEyeParameters = function(whichEye) { var eyeParameters = this.display.getEyeParameters(whichEye); return { currentFieldOfView: eyeParameters.fieldOfView, maximumFieldOfView: eyeParameters.fieldOfView, minimumFieldOfView: eyeParameters.fieldOfView, recommendedFieldOfView: eyeParameters.fieldOfView, eyeTranslation: { x: eyeParameters.offset[0], y: eyeParameters.offset[1], z: eyeParameters.offset[2] }, renderRect: { x: (whichEye == 'right') ? eyeParameters.renderWidth : 0, y: 0, width: eyeParameters.renderWidth, height: eyeParameters.renderHeight } }; }; VRDisplayHMDDevice.prototype.setFieldOfView = function(opt_fovLeft, opt_fovRight, opt_zNear, opt_zFar) { // Not supported. getEyeParameters reports that the min, max, and recommended // FoV is all the same, so no adjustment can be made. }; // TODO: Need to hook requestFullscreen to see if a wrapped VRDisplay was passed // in as an option. If so we should prevent the default fullscreen behavior and // call VRDisplay.requestPresent instead. /** * Wraps a VRDisplay and exposes it as a PositionSensorVRDevice */ function VRDisplayPositionSensorDevice(display) { this.display = display; this.hardwareUnitId = display.displayId; this.deviceId = 'webvr-polyfill:PositionSensor: ' + display.displayId; this.deviceName = display.displayName + ' (PositionSensor)'; } VRDisplayPositionSensorDevice.prototype = new PositionSensorVRDevice(); VRDisplayPositionSensorDevice.prototype.getState = function() { var pose = this.display.getPose(); return { position: pose.position ? { x: pose.position[0], y: pose.position[1], z: pose.position[2] } : null, orientation: pose.orientation ? { x: pose.orientation[0], y: pose.orientation[1], z: pose.orientation[2], w: pose.orientation[3] } : null, linearVelocity: null, linearAcceleration: null, angularVelocity: null, angularAcceleration: null }; }; VRDisplayPositionSensorDevice.prototype.resetState = function() { return this.positionDevice.resetPose(); }; module.exports.VRDisplayHMDDevice = VRDisplayHMDDevice; module.exports.VRDisplayPositionSensorDevice = VRDisplayPositionSensorDevice; },{"./base.js":3}],10:[function(_dereq_,module,exports){ /** * TODO(smus): Implement coefficient inversion. */ function Distortion(coefficients) { this.coefficients = coefficients; } /** * Calculates the inverse distortion for a radius. *

* Allows to compute the original undistorted radius from a distorted one. * See also getApproximateInverseDistortion() for a faster but potentially * less accurate method. * * @param {Number} radius Distorted radius from the lens center in tan-angle units. * @return {Number} The undistorted radius in tan-angle units. */ Distortion.prototype.distortInverse = function(radius) { // Secant method. var r0 = 0; var r1 = 1; var dr0 = radius - this.distort(r0); while (Math.abs(r1 - r0) > 0.0001 /** 0.1mm */) { var dr1 = radius - this.distort(r1); var r2 = r1 - dr1 * ((r1 - r0) / (dr1 - dr0)); r0 = r1; r1 = r2; dr0 = dr1; } return r1; }; /** * Distorts a radius by its distortion factor from the center of the lenses. * * @param {Number} radius Radius from the lens center in tan-angle units. * @return {Number} The distorted radius in tan-angle units. */ Distortion.prototype.distort = function(radius) { var r2 = radius * radius; var ret = 0; for (var i = 0; i < this.coefficients.length; i++) { ret = r2 * (ret + this.coefficients[i]); } return (ret + 1) * radius; }; // Functions below roughly ported from // https://github.com/googlesamples/cardboard-unity/blob/master/Cardboard/Scripts/CardboardProfile.cs#L412 // Solves a small linear equation via destructive gaussian // elimination and back substitution. This isn't generic numeric // code, it's just a quick hack to work with the generally // well-behaved symmetric matrices for least-squares fitting. // Not intended for reuse. // // @param a Input positive definite symmetrical matrix. Destroyed // during calculation. // @param y Input right-hand-side values. Destroyed during calculation. // @return Resulting x value vector. // Distortion.prototype.solveLinear_ = function(a, y) { var n = a.length; // Gaussian elimination (no row exchange) to triangular matrix. // The input matrix is a A^T A product which should be a positive // definite symmetrical matrix, and if I remember my linear // algebra right this implies that the pivots will be nonzero and // calculations sufficiently accurate without needing row // exchange. for (var j = 0; j < n - 1; ++j) { for (var k = j + 1; k < n; ++k) { var p = a[j][k] / a[j][j]; for (var i = j + 1; i < n; ++i) { a[i][k] -= p * a[i][j]; } y[k] -= p * y[j]; } } // From this point on, only the matrix elements a[j][i] with i>=j are // valid. The elimination doesn't fill in eliminated 0 values. var x = new Array(n); // Back substitution. for (var j = n - 1; j >= 0; --j) { var v = y[j]; for (var i = j + 1; i < n; ++i) { v -= a[i][j] * x[i]; } x[j] = v / a[j][j]; } return x; }; // Solves a least-squares matrix equation. Given the equation A * x = y, calculate the // least-square fit x = inverse(A * transpose(A)) * transpose(A) * y. The way this works // is that, while A is typically not a square matrix (and hence not invertible), A * transpose(A) // is always square. That is: // A * x = y // transpose(A) * (A * x) = transpose(A) * y <- multiply both sides by transpose(A) // (transpose(A) * A) * x = transpose(A) * y <- associativity // x = inverse(transpose(A) * A) * transpose(A) * y <- solve for x // Matrix A's row count (first index) must match y's value count. A's column count (second index) // determines the length of the result vector x. Distortion.prototype.solveLeastSquares_ = function(matA, vecY) { var i, j, k, sum; var numSamples = matA.length; var numCoefficients = matA[0].length; if (numSamples != vecY.Length) { throw new Error("Matrix / vector dimension mismatch"); } // Calculate transpose(A) * A var matATA = new Array(numCoefficients); for (k = 0; k < numCoefficients; ++k) { matATA[k] = new Array(numCoefficients); for (j = 0; j < numCoefficients; ++j) { sum = 0; for (i = 0; i < numSamples; ++i) { sum += matA[j][i] * matA[k][i]; } matATA[k][j] = sum; } } // Calculate transpose(A) * y var vecATY = new Array(numCoefficients); for (j = 0; j < numCoefficients; ++j) { sum = 0; for (i = 0; i < numSamples; ++i) { sum += matA[j][i] * vecY[i]; } vecATY[j] = sum; } // Now solve (A * transpose(A)) * x = transpose(A) * y. return this.solveLinear_(matATA, vecATY); }; /// Calculates an approximate inverse to the given radial distortion parameters. Distortion.prototype.approximateInverse = function(maxRadius, numSamples) { maxRadius = maxRadius || 1; numSamples = numSamples || 100; var numCoefficients = 6; var i, j; // R + K1*R^3 + K2*R^5 = r, with R = rp = distort(r) // Repeating for numSamples: // [ R0^3, R0^5 ] * [ K1 ] = [ r0 - R0 ] // [ R1^3, R1^5 ] [ K2 ] [ r1 - R1 ] // [ R2^3, R2^5 ] [ r2 - R2 ] // [ etc... ] [ etc... ] // That is: // matA * [K1, K2] = y // Solve: // [K1, K2] = inverse(transpose(matA) * matA) * transpose(matA) * y var matA = new Array(numCoefficients); for (j = 0; j < numCoefficients; ++j) { matA[j] = new Array(numSamples); } var vecY = new Array(numSamples); for (i = 0; i < numSamples; ++i) { var r = maxRadius * (i + 1) / numSamples; var rp = this.distort(r); var v = rp; for (j = 0; j < numCoefficients; ++j) { v *= rp * rp; matA[j][i] = v; } vecY[i] = r - rp; } var inverseCoefficients = this.solveLeastSquares_(matA, vecY); return new Distortion(inverseCoefficients); }; module.exports = Distortion; },{}],11:[function(_dereq_,module,exports){ /* * Copyright 2015 Google Inc. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * DPDB cache. */ var DPDB_CACHE = { "format": 1, "last_updated": "2016-01-20T00:18:35Z", "devices": [ { "type": "android", "rules": [ { "mdmh": "asus/*/Nexus 7/*" }, { "ua": "Nexus 7" } ], "dpi": [ 320.8, 323.0 ], "bw": 3, "ac": 500 }, { "type": "android", "rules": [ { "mdmh": "asus/*/ASUS_Z00AD/*" }, { "ua": "ASUS_Z00AD" } ], "dpi": [ 403.0, 404.6 ], "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "HTC/*/HTC6435LVW/*" }, { "ua": "HTC6435LVW" } ], "dpi": [ 449.7, 443.3 ], "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "HTC/*/HTC One XL/*" }, { "ua": "HTC One XL" } ], "dpi": [ 315.3, 314.6 ], "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "htc/*/Nexus 9/*" }, { "ua": "Nexus 9" } ], "dpi": 289.0, "bw": 3, "ac": 500 }, { "type": "android", "rules": [ { "mdmh": "HTC/*/HTC One M9/*" }, { "ua": "HTC One M9" } ], "dpi": [ 442.5, 443.3 ], "bw": 3, "ac": 500 }, { "type": "android", "rules": [ { "mdmh": "HTC/*/HTC One_M8/*" }, { "ua": "HTC One_M8" } ], "dpi": [ 449.7, 447.4 ], "bw": 3, "ac": 500 }, { "type": "android", "rules": [ { "mdmh": "HTC/*/HTC One/*" }, { "ua": "HTC One" } ], "dpi": 472.8, "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "Huawei/*/Nexus 6P/*" }, { "ua": "Nexus 6P" } ], "dpi": [ 515.1, 518.0 ], "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "LGE/*/Nexus 5X/*" }, { "ua": "Nexus 5X" } ], "dpi": [ 422.0, 419.9 ], "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "LGE/*/LGMS345/*" }, { "ua": "LGMS345" } ], "dpi": [ 221.7, 219.1 ], "bw": 3, "ac": 500 }, { "type": "android", "rules": [ { "mdmh": "LGE/*/LG-D800/*" }, { "ua": "LG-D800" } ], "dpi": [ 422.0, 424.1 ], "bw": 3, "ac": 500 }, { "type": "android", "rules": [ { "mdmh": "LGE/*/LG-D850/*" }, { "ua": "LG-D850" } ], "dpi": [ 537.9, 541.9 ], "bw": 3, "ac": 500 }, { "type": "android", "rules": [ { "mdmh": "LGE/*/VS985 4G/*" }, { "ua": "VS985 4G" } ], "dpi": [ 537.9, 535.6 ], "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "LGE/*/Nexus 5/*" }, { "ua": "Nexus 5 " } ], "dpi": [ 442.4, 444.8 ], "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "LGE/*/Nexus 4/*" }, { "ua": "Nexus 4" } ], "dpi": [ 319.8, 318.4 ], "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "LGE/*/LG-P769/*" }, { "ua": "LG-P769" } ], "dpi": [ 240.6, 247.5 ], "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "LGE/*/LGMS323/*" }, { "ua": "LGMS323" } ], "dpi": [ 206.6, 204.6 ], "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "LGE/*/LGLS996/*" }, { "ua": "LGLS996" } ], "dpi": [ 403.4, 401.5 ], "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "Micromax/*/4560MMX/*" }, { "ua": "4560MMX" } ], "dpi": [ 240.0, 219.4 ], "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "Micromax/*/A250/*" }, { "ua": "Micromax A250" } ], "dpi": [ 480.0, 446.4 ], "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "Micromax/*/Micromax AQ4501/*" }, { "ua": "Micromax AQ4501" } ], "dpi": 240.0, "bw": 3, "ac": 500 }, { "type": "android", "rules": [ { "mdmh": "motorola/*/DROID RAZR/*" }, { "ua": "DROID RAZR" } ], "dpi": [ 368.1, 256.7 ], "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "motorola/*/XT830C/*" }, { "ua": "XT830C" } ], "dpi": [ 254.0, 255.9 ], "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "motorola/*/XT1021/*" }, { "ua": "XT1021" } ], "dpi": [ 254.0, 256.7 ], "bw": 3, "ac": 500 }, { "type": "android", "rules": [ { "mdmh": "motorola/*/XT1023/*" }, { "ua": "XT1023" } ], "dpi": [ 254.0, 256.7 ], "bw": 3, "ac": 500 }, { "type": "android", "rules": [ { "mdmh": "motorola/*/XT1028/*" }, { "ua": "XT1028" } ], "dpi": [ 326.6, 327.6 ], "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "motorola/*/XT1034/*" }, { "ua": "XT1034" } ], "dpi": [ 326.6, 328.4 ], "bw": 3, "ac": 500 }, { "type": "android", "rules": [ { "mdmh": "motorola/*/XT1053/*" }, { "ua": "XT1053" } ], "dpi": [ 315.3, 316.1 ], "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "motorola/*/XT1562/*" }, { "ua": "XT1562" } ], "dpi": [ 403.4, 402.7 ], "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "motorola/*/Nexus 6/*" }, { "ua": "Nexus 6 " } ], "dpi": [ 494.3, 489.7 ], "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "motorola/*/XT1063/*" }, { "ua": "XT1063" } ], "dpi": [ 295.0, 296.6 ], "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "motorola/*/XT1064/*" }, { "ua": "XT1064" } ], "dpi": [ 295.0, 295.6 ], "bw": 3, "ac": 500 }, { "type": "android", "rules": [ { "mdmh": "motorola/*/XT1092/*" }, { "ua": "XT1092" } ], "dpi": [ 422.0, 424.1 ], "bw": 3, "ac": 500 }, { "type": "android", "rules": [ { "mdmh": "motorola/*/XT1095/*" }, { "ua": "XT1095" } ], "dpi": [ 422.0, 423.4 ], "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "OnePlus/*/A0001/*" }, { "ua": "A0001" } ], "dpi": [ 403.4, 401.0 ], "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "OnePlus/*/ONE E1005/*" }, { "ua": "ONE E1005" } ], "dpi": [ 442.4, 441.4 ], "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "OnePlus/*/ONE A2005/*" }, { "ua": "ONE A2005" } ], "dpi": [ 391.9, 405.4 ], "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "OPPO/*/X909/*" }, { "ua": "X909" } ], "dpi": [ 442.4, 444.1 ], "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "samsung/*/GT-I9082/*" }, { "ua": "GT-I9082" } ], "dpi": [ 184.7, 185.4 ], "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "samsung/*/SM-G360P/*" }, { "ua": "SM-G360P" } ], "dpi": [ 196.7, 205.4 ], "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "samsung/*/Nexus S/*" }, { "ua": "Nexus S" } ], "dpi": [ 234.5, 229.8 ], "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "samsung/*/GT-I9300/*" }, { "ua": "GT-I9300" } ], "dpi": [ 304.8, 303.9 ], "bw": 5, "ac": 500 }, { "type": "android", "rules": [ { "mdmh": "samsung/*/SM-T230NU/*" }, { "ua": "SM-T230NU" } ], "dpi": 216.0, "bw": 3, "ac": 500 }, { "type": "android", "rules": [ { "mdmh": "samsung/*/SGH-T399/*" }, { "ua": "SGH-T399" } ], "dpi": [ 217.7, 231.4 ], "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "samsung/*/SM-N9005/*" }, { "ua": "SM-N9005" } ], "dpi": [ 386.4, 387.0 ], "bw": 3, "ac": 500 }, { "type": "android", "rules": [ { "mdmh": "samsung/*/SAMSUNG-SM-N900A/*" }, { "ua": "SAMSUNG-SM-N900A" } ], "dpi": [ 386.4, 387.7 ], "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "samsung/*/GT-I9500/*" }, { "ua": "GT-I9500" } ], "dpi": [ 442.5, 443.3 ], "bw": 3, "ac": 500 }, { "type": "android", "rules": [ { "mdmh": "samsung/*/GT-I9505/*" }, { "ua": "GT-I9505" } ], "dpi": 439.4, "bw": 4, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "samsung/*/SM-G900F/*" }, { "ua": "SM-G900F" } ], "dpi": [ 415.6, 431.6 ], "bw": 5, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "samsung/*/SM-G900M/*" }, { "ua": "SM-G900M" } ], "dpi": [ 415.6, 431.6 ], "bw": 5, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "samsung/*/SM-G800F/*" }, { "ua": "SM-G800F" } ], "dpi": 326.8, "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "samsung/*/SM-G906S/*" }, { "ua": "SM-G906S" } ], "dpi": [ 562.7, 572.4 ], "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "samsung/*/GT-I9300/*" }, { "ua": "GT-I9300" } ], "dpi": [ 306.7, 304.8 ], "bw": 5, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "samsung/*/SM-T535/*" }, { "ua": "SM-T535" } ], "dpi": [ 142.6, 136.4 ], "bw": 3, "ac": 500 }, { "type": "android", "rules": [ { "mdmh": "samsung/*/SM-N920C/*" }, { "ua": "SM-N920C" } ], "dpi": [ 515.1, 518.4 ], "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "samsung/*/GT-I9300I/*" }, { "ua": "GT-I9300I" } ], "dpi": [ 304.8, 305.8 ], "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "samsung/*/GT-I9195/*" }, { "ua": "GT-I9195" } ], "dpi": [ 249.4, 256.7 ], "bw": 3, "ac": 500 }, { "type": "android", "rules": [ { "mdmh": "samsung/*/SPH-L520/*" }, { "ua": "SPH-L520" } ], "dpi": [ 249.4, 255.9 ], "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "samsung/*/SAMSUNG-SGH-I717/*" }, { "ua": "SAMSUNG-SGH-I717" } ], "dpi": 285.8, "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "samsung/*/SPH-D710/*" }, { "ua": "SPH-D710" } ], "dpi": [ 217.7, 204.2 ], "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "samsung/*/GT-N7100/*" }, { "ua": "GT-N7100" } ], "dpi": 265.1, "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "samsung/*/SCH-I605/*" }, { "ua": "SCH-I605" } ], "dpi": 265.1, "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "samsung/*/Galaxy Nexus/*" }, { "ua": "Galaxy Nexus" } ], "dpi": [ 315.3, 314.2 ], "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "samsung/*/SM-N910H/*" }, { "ua": "SM-N910H" } ], "dpi": [ 515.1, 518.0 ], "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "samsung/*/SM-N910C/*" }, { "ua": "SM-N910C" } ], "dpi": [ 515.2, 520.2 ], "bw": 3, "ac": 500 }, { "type": "android", "rules": [ { "mdmh": "samsung/*/SM-G130M/*" }, { "ua": "SM-G130M" } ], "dpi": [ 165.9, 164.8 ], "bw": 3, "ac": 500 }, { "type": "android", "rules": [ { "mdmh": "samsung/*/SM-G928I/*" }, { "ua": "SM-G928I" } ], "dpi": [ 515.1, 518.4 ], "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "samsung/*/SM-G920F/*" }, { "ua": "SM-G920F" } ], "dpi": 580.6, "bw": 3, "ac": 500 }, { "type": "android", "rules": [ { "mdmh": "samsung/*/SM-G920P/*" }, { "ua": "SM-G920P" } ], "dpi": [ 522.5, 577.0 ], "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "samsung/*/SM-G925F/*" }, { "ua": "SM-G925F" } ], "dpi": 580.6, "bw": 3, "ac": 500 }, { "type": "android", "rules": [ { "mdmh": "samsung/*/SM-G925V/*" }, { "ua": "SM-G925V" } ], "dpi": [ 522.5, 576.6 ], "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "Sony/*/C6903/*" }, { "ua": "C6903" } ], "dpi": [ 442.5, 443.3 ], "bw": 3, "ac": 500 }, { "type": "android", "rules": [ { "mdmh": "Sony/*/D6653/*" }, { "ua": "D6653" } ], "dpi": [ 428.6, 427.6 ], "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "Sony/*/E6653/*" }, { "ua": "E6653" } ], "dpi": [ 428.6, 425.7 ], "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "Sony/*/E6853/*" }, { "ua": "E6853" } ], "dpi": [ 403.4, 401.9 ], "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "Sony/*/SGP321/*" }, { "ua": "SGP321" } ], "dpi": [ 224.7, 224.1 ], "bw": 3, "ac": 500 }, { "type": "android", "rules": [ { "mdmh": "TCT/*/ALCATEL ONE TOUCH Fierce/*" }, { "ua": "ALCATEL ONE TOUCH Fierce" } ], "dpi": [ 240.0, 247.5 ], "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "THL/*/thl 5000/*" }, { "ua": "thl 5000" } ], "dpi": [ 480.0, 443.3 ], "bw": 3, "ac": 1000 }, { "type": "android", "rules": [ { "mdmh": "ZTE/*/ZTE Blade L2/*" }, { "ua": "ZTE Blade L2" } ], "dpi": 240.0, "bw": 3, "ac": 500 }, { "type": "ios", "rules": [ { "res": [ 640, 960 ] } ], "dpi": [ 325.1, 328.4 ], "bw": 4, "ac": 1000 }, { "type": "ios", "rules": [ { "res": [ 640, 960 ] } ], "dpi": [ 325.1, 328.4 ], "bw": 4, "ac": 1000 }, { "type": "ios", "rules": [ { "res": [ 640, 1136 ] } ], "dpi": [ 317.1, 320.2 ], "bw": 3, "ac": 1000 }, { "type": "ios", "rules": [ { "res": [ 640, 1136 ] } ], "dpi": [ 317.1, 320.2 ], "bw": 3, "ac": 1000 }, { "type": "ios", "rules": [ { "res": [ 750, 1334 ] } ], "dpi": 326.4, "bw": 4, "ac": 1000 }, { "type": "ios", "rules": [ { "res": [ 750, 1334 ] } ], "dpi": 326.4, "bw": 4, "ac": 1000 }, { "type": "ios", "rules": [ { "res": [ 1242, 2208 ] } ], "dpi": [ 453.6, 458.4 ], "bw": 4, "ac": 1000 }, { "type": "ios", "rules": [ { "res": [ 1242, 2208 ] } ], "dpi": [ 453.6, 458.4 ], "bw": 4, "ac": 1000 } ]}; module.exports = DPDB_CACHE; },{}],12:[function(_dereq_,module,exports){ /* * Copyright 2015 Google Inc. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // Offline cache of the DPDB, to be used until we load the online one (and // as a fallback in case we can't load the online one). var DPDB_CACHE = _dereq_('./dpdb-cache.js'); var Util = _dereq_('../util.js'); // Online DPDB URL. var ONLINE_DPDB_URL = 'https://storage.googleapis.com/cardboard-dpdb/dpdb.json'; /** * Calculates device parameters based on the DPDB (Device Parameter Database). * Initially, uses the cached DPDB values. * * If fetchOnline == true, then this object tries to fetch the online version * of the DPDB and updates the device info if a better match is found. * Calls the onDeviceParamsUpdated callback when there is an update to the * device information. */ function Dpdb(fetchOnline, onDeviceParamsUpdated) { // Start with the offline DPDB cache while we are loading the real one. this.dpdb = DPDB_CACHE; // Calculate device params based on the offline version of the DPDB. this.recalculateDeviceParams_(); // XHR to fetch online DPDB file, if requested. if (fetchOnline) { // Set the callback. this.onDeviceParamsUpdated = onDeviceParamsUpdated; var xhr = new XMLHttpRequest(); var obj = this; xhr.open('GET', ONLINE_DPDB_URL, true); xhr.addEventListener('load', function() { obj.loading = false; if (xhr.status >= 200 && xhr.status <= 299) { // Success. obj.dpdb = JSON.parse(xhr.response); obj.recalculateDeviceParams_(); } else { // Error loading the DPDB. console.error('Error loading online DPDB!'); } }); xhr.send(); } } // Returns the current device parameters. Dpdb.prototype.getDeviceParams = function() { return this.deviceParams; }; // Recalculates this device's parameters based on the DPDB. Dpdb.prototype.recalculateDeviceParams_ = function() { var newDeviceParams = this.calcDeviceParams_(); if (newDeviceParams) { this.deviceParams = newDeviceParams; // Invoke callback, if it is set. if (this.onDeviceParamsUpdated) { this.onDeviceParamsUpdated(this.deviceParams); } } else { console.error('Failed to recalculate device parameters.'); } }; // Returns a DeviceParams object that represents the best guess as to this // device's parameters. Can return null if the device does not match any // known devices. Dpdb.prototype.calcDeviceParams_ = function() { var db = this.dpdb; // shorthand if (!db) { console.error('DPDB not available.'); return null; } if (db.format != 1) { console.error('DPDB has unexpected format version.'); return null; } if (!db.devices || !db.devices.length) { console.error('DPDB does not have a devices section.'); return null; } // Get the actual user agent and screen dimensions in pixels. var userAgent = navigator.userAgent || navigator.vendor || window.opera; var width = Util.getScreenWidth(); var height = Util.getScreenHeight(); if (!db.devices) { console.error('DPDB has no devices section.'); return null; } for (var i = 0; i < db.devices.length; i++) { var device = db.devices[i]; if (!device.rules) { console.warn('Device[' + i + '] has no rules section.'); continue; } if (device.type != 'ios' && device.type != 'android') { console.warn('Device[' + i + '] has invalid type.'); continue; } // See if this device is of the appropriate type. if (Util.isIOS() != (device.type == 'ios')) continue; // See if this device matches any of the rules: var matched = false; for (var j = 0; j < device.rules.length; j++) { var rule = device.rules[j]; if (this.matchRule_(rule, userAgent, width, height)) { matched = true; break; } } if (!matched) continue; // device.dpi might be an array of [ xdpi, ydpi] or just a scalar. var xdpi = device.dpi[0] || device.dpi; var ydpi = device.dpi[1] || device.dpi; return new DeviceParams({ xdpi: xdpi, ydpi: ydpi, bevelMm: device.bw }); } console.warn('No DPDB device match.'); return null; }; Dpdb.prototype.matchRule_ = function(rule, ua, screenWidth, screenHeight) { // We can only match 'ua' and 'res' rules, not other types like 'mdmh' // (which are meant for native platforms). if (!rule.ua && !rule.res) return false; // If our user agent string doesn't contain the indicated user agent string, // the match fails. if (rule.ua && ua.indexOf(rule.ua) < 0) return false; // If the rule specifies screen dimensions that don't correspond to ours, // the match fails. if (rule.res) { if (!rule.res[0] || !rule.res[1]) return false; var resX = rule.res[0]; var resY = rule.res[1]; // Compare min and max so as to make the order not matter, i.e., it should // be true that 640x480 == 480x640. if (Math.min(screenWidth, screenHeight) != Math.min(resX, resY) || (Math.max(screenWidth, screenHeight) != Math.max(resX, resY))) { return false; } } return true; } function DeviceParams(params) { this.xdpi = params.xdpi; this.ydpi = params.ydpi; this.bevelMm = params.bevelMm; } module.exports = Dpdb; },{"../util.js":22,"./dpdb-cache.js":11}],13:[function(_dereq_,module,exports){ /* * Copyright 2015 Google Inc. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var Util = _dereq_('./util.js'); var WebVRPolyfill = _dereq_('./webvr-polyfill.js').WebVRPolyfill; // Initialize a WebVRConfig just in case. window.WebVRConfig = Util.extend({ // Forces availability of VR mode, even for non-mobile devices. FORCE_ENABLE_VR: false, // Complementary filter coefficient. 0 for accelerometer, 1 for gyro. K_FILTER: 0.98, // How far into the future to predict during fast motion (in seconds). PREDICTION_TIME_S: 0.040, // Flag to enable touch panner. In case you have your own touch controls. TOUCH_PANNER_DISABLED: true, // Flag to disabled the UI in VR Mode. CARDBOARD_UI_DISABLED: false, // Default: false // Flag to disable the instructions to rotate your device. ROTATE_INSTRUCTIONS_DISABLED: false, // Default: false. // Enable yaw panning only, disabling roll and pitch. This can be useful // for panoramas with nothing interesting above or below. YAW_ONLY: false, // To disable keyboard and mouse controls, if you want to use your own // implementation. MOUSE_KEYBOARD_CONTROLS_DISABLED: false, // Prevent the polyfill from initializing immediately. Requires the app // to call InitializeWebVRPolyfill() before it can be used. DEFER_INITIALIZATION: false, // Enable the deprecated version of the API (navigator.getVRDevices). ENABLE_DEPRECATED_API: false, // Scales the recommended buffer size reported by WebVR, which can improve // performance. // UPDATE(2016-05-03): Setting this to 0.5 by default since 1.0 does not // perform well on many mobile devices. BUFFER_SCALE: 0.5, // Allow VRDisplay.submitFrame to change gl bindings, which is more // efficient if the application code will re-bind its resources on the // next frame anyway. This has been seen to cause rendering glitches with // THREE.js. // Dirty bindings include: gl.FRAMEBUFFER_BINDING, gl.CURRENT_PROGRAM, // gl.ARRAY_BUFFER_BINDING, gl.ELEMENT_ARRAY_BUFFER_BINDING, // and gl.TEXTURE_BINDING_2D for texture unit 0. DIRTY_SUBMIT_FRAME_BINDINGS: false, // When set to true, this will cause a polyfilled VRDisplay to always be // appended to the list returned by navigator.getVRDisplays(), even if that // list includes a native VRDisplay. ALWAYS_APPEND_POLYFILL_DISPLAY: false }, window.WebVRConfig); if (!window.WebVRConfig.DEFER_INITIALIZATION) { new WebVRPolyfill(); } else { window.InitializeWebVRPolyfill = function() { new WebVRPolyfill(); } } },{"./util.js":22,"./webvr-polyfill.js":25}],14:[function(_dereq_,module,exports){ /* * Copyright 2016 Google Inc. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var MathUtil = window.MathUtil || {}; MathUtil.degToRad = Math.PI / 180; MathUtil.radToDeg = 180 / Math.PI; // Some minimal math functionality borrowed from THREE.Math and stripped down // for the purposes of this library. MathUtil.Vector2 = function ( x, y ) { this.x = x || 0; this.y = y || 0; }; MathUtil.Vector2.prototype = { constructor: MathUtil.Vector2, set: function ( x, y ) { this.x = x; this.y = y; return this; }, copy: function ( v ) { this.x = v.x; this.y = v.y; return this; }, subVectors: function ( a, b ) { this.x = a.x - b.x; this.y = a.y - b.y; return this; }, }; MathUtil.Vector3 = function ( x, y, z ) { this.x = x || 0; this.y = y || 0; this.z = z || 0; }; MathUtil.Vector3.prototype = { constructor: MathUtil.Vector3, set: function ( x, y, z ) { this.x = x; this.y = y; this.z = z; return this; }, copy: function ( v ) { this.x = v.x; this.y = v.y; this.z = v.z; return this; }, length: function () { return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z ); }, normalize: function () { var scalar = this.length(); if ( scalar !== 0 ) { var invScalar = 1 / scalar; this.multiplyScalar(invScalar); } else { this.x = 0; this.y = 0; this.z = 0; } return this; }, multiplyScalar: function ( scalar ) { this.x *= scalar; this.y *= scalar; this.z *= scalar; }, applyQuaternion: function ( q ) { var x = this.x; var y = this.y; var z = this.z; var qx = q.x; var qy = q.y; var qz = q.z; var qw = q.w; // calculate quat * vector var ix = qw * x + qy * z - qz * y; var iy = qw * y + qz * x - qx * z; var iz = qw * z + qx * y - qy * x; var iw = - qx * x - qy * y - qz * z; // calculate result * inverse quat this.x = ix * qw + iw * - qx + iy * - qz - iz * - qy; this.y = iy * qw + iw * - qy + iz * - qx - ix * - qz; this.z = iz * qw + iw * - qz + ix * - qy - iy * - qx; return this; }, dot: function ( v ) { return this.x * v.x + this.y * v.y + this.z * v.z; }, crossVectors: function ( a, b ) { var ax = a.x, ay = a.y, az = a.z; var bx = b.x, by = b.y, bz = b.z; this.x = ay * bz - az * by; this.y = az * bx - ax * bz; this.z = ax * by - ay * bx; return this; }, }; MathUtil.Quaternion = function ( x, y, z, w ) { this.x = x || 0; this.y = y || 0; this.z = z || 0; this.w = ( w !== undefined ) ? w : 1; }; MathUtil.Quaternion.prototype = { constructor: MathUtil.Quaternion, set: function ( x, y, z, w ) { this.x = x; this.y = y; this.z = z; this.w = w; return this; }, copy: function ( quaternion ) { this.x = quaternion.x; this.y = quaternion.y; this.z = quaternion.z; this.w = quaternion.w; return this; }, setFromEulerXYZ: function( x, y, z ) { var c1 = Math.cos( x / 2 ); var c2 = Math.cos( y / 2 ); var c3 = Math.cos( z / 2 ); var s1 = Math.sin( x / 2 ); var s2 = Math.sin( y / 2 ); var s3 = Math.sin( z / 2 ); this.x = s1 * c2 * c3 + c1 * s2 * s3; this.y = c1 * s2 * c3 - s1 * c2 * s3; this.z = c1 * c2 * s3 + s1 * s2 * c3; this.w = c1 * c2 * c3 - s1 * s2 * s3; return this; }, setFromEulerYXZ: function( x, y, z ) { var c1 = Math.cos( x / 2 ); var c2 = Math.cos( y / 2 ); var c3 = Math.cos( z / 2 ); var s1 = Math.sin( x / 2 ); var s2 = Math.sin( y / 2 ); var s3 = Math.sin( z / 2 ); this.x = s1 * c2 * c3 + c1 * s2 * s3; this.y = c1 * s2 * c3 - s1 * c2 * s3; this.z = c1 * c2 * s3 - s1 * s2 * c3; this.w = c1 * c2 * c3 + s1 * s2 * s3; return this; }, setFromAxisAngle: function ( axis, angle ) { // http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm // assumes axis is normalized var halfAngle = angle / 2, s = Math.sin( halfAngle ); this.x = axis.x * s; this.y = axis.y * s; this.z = axis.z * s; this.w = Math.cos( halfAngle ); return this; }, multiply: function ( q ) { return this.multiplyQuaternions( this, q ); }, multiplyQuaternions: function ( a, b ) { // from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm var qax = a.x, qay = a.y, qaz = a.z, qaw = a.w; var qbx = b.x, qby = b.y, qbz = b.z, qbw = b.w; this.x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby; this.y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz; this.z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx; this.w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz; return this; }, inverse: function () { this.x *= -1; this.y *= -1; this.z *= -1; this.normalize(); return this; }, normalize: function () { var l = Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w ); if ( l === 0 ) { this.x = 0; this.y = 0; this.z = 0; this.w = 1; } else { l = 1 / l; this.x = this.x * l; this.y = this.y * l; this.z = this.z * l; this.w = this.w * l; } return this; }, slerp: function ( qb, t ) { if ( t === 0 ) return this; if ( t === 1 ) return this.copy( qb ); var x = this.x, y = this.y, z = this.z, w = this.w; // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/ var cosHalfTheta = w * qb.w + x * qb.x + y * qb.y + z * qb.z; if ( cosHalfTheta < 0 ) { this.w = - qb.w; this.x = - qb.x; this.y = - qb.y; this.z = - qb.z; cosHalfTheta = - cosHalfTheta; } else { this.copy( qb ); } if ( cosHalfTheta >= 1.0 ) { this.w = w; this.x = x; this.y = y; this.z = z; return this; } var halfTheta = Math.acos( cosHalfTheta ); var sinHalfTheta = Math.sqrt( 1.0 - cosHalfTheta * cosHalfTheta ); if ( Math.abs( sinHalfTheta ) < 0.001 ) { this.w = 0.5 * ( w + this.w ); this.x = 0.5 * ( x + this.x ); this.y = 0.5 * ( y + this.y ); this.z = 0.5 * ( z + this.z ); return this; } var ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta, ratioB = Math.sin( t * halfTheta ) / sinHalfTheta; this.w = ( w * ratioA + this.w * ratioB ); this.x = ( x * ratioA + this.x * ratioB ); this.y = ( y * ratioA + this.y * ratioB ); this.z = ( z * ratioA + this.z * ratioB ); return this; }, setFromUnitVectors: function () { // http://lolengine.net/blog/2014/02/24/quaternion-from-two-vectors-final // assumes direction vectors vFrom and vTo are normalized var v1, r; var EPS = 0.000001; return function ( vFrom, vTo ) { if ( v1 === undefined ) v1 = new MathUtil.Vector3(); r = vFrom.dot( vTo ) + 1; if ( r < EPS ) { r = 0; if ( Math.abs( vFrom.x ) > Math.abs( vFrom.z ) ) { v1.set( - vFrom.y, vFrom.x, 0 ); } else { v1.set( 0, - vFrom.z, vFrom.y ); } } else { v1.crossVectors( vFrom, vTo ); } this.x = v1.x; this.y = v1.y; this.z = v1.z; this.w = r; this.normalize(); return this; } }(), }; module.exports = MathUtil; },{}],15:[function(_dereq_,module,exports){ /* * Copyright 2016 Google Inc. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var VRDisplay = _dereq_('./base.js').VRDisplay; var MathUtil = _dereq_('./math-util.js'); var Util = _dereq_('./util.js'); // How much to rotate per key stroke. var KEY_SPEED = 0.15; var KEY_ANIMATION_DURATION = 80; // How much to rotate for mouse events. var MOUSE_SPEED_X = 0.5; var MOUSE_SPEED_Y = 0.3; /** * VRDisplay based on mouse and keyboard input. Designed for desktops/laptops * where orientation events aren't supported. Cannot present. */ function MouseKeyboardVRDisplay() { this.displayName = 'Mouse and Keyboard VRDisplay (webvr-polyfill)'; this.capabilities.hasOrientation = true; // Attach to mouse and keyboard events. window.addEventListener('keydown', this.onKeyDown_.bind(this)); window.addEventListener('mousemove', this.onMouseMove_.bind(this)); window.addEventListener('mousedown', this.onMouseDown_.bind(this)); window.addEventListener('mouseup', this.onMouseUp_.bind(this)); // "Private" members. this.phi_ = 0; this.theta_ = 0; // Variables for keyboard-based rotation animation. this.targetAngle_ = null; this.angleAnimation_ = null; // State variables for calculations. this.orientation_ = new MathUtil.Quaternion(); // Variables for mouse-based rotation. this.rotateStart_ = new MathUtil.Vector2(); this.rotateEnd_ = new MathUtil.Vector2(); this.rotateDelta_ = new MathUtil.Vector2(); this.isDragging_ = false; this.orientationOut_ = new Float32Array(4); } MouseKeyboardVRDisplay.prototype = new VRDisplay(); MouseKeyboardVRDisplay.prototype.getImmediatePose = function() { this.orientation_.setFromEulerYXZ(this.phi_, this.theta_, 0); this.orientationOut_[0] = this.orientation_.x; this.orientationOut_[1] = this.orientation_.y; this.orientationOut_[2] = this.orientation_.z; this.orientationOut_[3] = this.orientation_.w; return { position: null, orientation: this.orientationOut_, linearVelocity: null, linearAcceleration: null, angularVelocity: null, angularAcceleration: null }; }; MouseKeyboardVRDisplay.prototype.onKeyDown_ = function(e) { // Track WASD and arrow keys. if (e.keyCode == 38) { // Up key. this.animatePhi_(this.phi_ + KEY_SPEED); } else if (e.keyCode == 39) { // Right key. this.animateTheta_(this.theta_ - KEY_SPEED); } else if (e.keyCode == 40) { // Down key. this.animatePhi_(this.phi_ - KEY_SPEED); } else if (e.keyCode == 37) { // Left key. this.animateTheta_(this.theta_ + KEY_SPEED); } }; MouseKeyboardVRDisplay.prototype.animateTheta_ = function(targetAngle) { this.animateKeyTransitions_('theta_', targetAngle); }; MouseKeyboardVRDisplay.prototype.animatePhi_ = function(targetAngle) { // Prevent looking too far up or down. targetAngle = Util.clamp(targetAngle, -Math.PI/2, Math.PI/2); this.animateKeyTransitions_('phi_', targetAngle); }; /** * Start an animation to transition an angle from one value to another. */ MouseKeyboardVRDisplay.prototype.animateKeyTransitions_ = function(angleName, targetAngle) { // If an animation is currently running, cancel it. if (this.angleAnimation_) { cancelAnimationFrame(this.angleAnimation_); } var startAngle = this[angleName]; var startTime = new Date(); // Set up an interval timer to perform the animation. this.angleAnimation_ = requestAnimationFrame(function animate() { // Once we're finished the animation, we're done. var elapsed = new Date() - startTime; if (elapsed >= KEY_ANIMATION_DURATION) { this[angleName] = targetAngle; cancelAnimationFrame(this.angleAnimation_); return; } // loop with requestAnimationFrame this.angleAnimation_ = requestAnimationFrame(animate.bind(this)) // Linearly interpolate the angle some amount. var percent = elapsed / KEY_ANIMATION_DURATION; this[angleName] = startAngle + (targetAngle - startAngle) * percent; }.bind(this)); }; MouseKeyboardVRDisplay.prototype.onMouseDown_ = function(e) { this.rotateStart_.set(e.clientX, e.clientY); this.isDragging_ = true; }; // Very similar to https://gist.github.com/mrflix/8351020 MouseKeyboardVRDisplay.prototype.onMouseMove_ = function(e) { if (!this.isDragging_ && !this.isPointerLocked_()) { return; } // Support pointer lock API. if (this.isPointerLocked_()) { var movementX = e.movementX || e.mozMovementX || 0; var movementY = e.movementY || e.mozMovementY || 0; this.rotateEnd_.set(this.rotateStart_.x - movementX, this.rotateStart_.y - movementY); } else { this.rotateEnd_.set(e.clientX, e.clientY); } // Calculate how much we moved in mouse space. this.rotateDelta_.subVectors(this.rotateEnd_, this.rotateStart_); this.rotateStart_.copy(this.rotateEnd_); // Keep track of the cumulative euler angles. this.phi_ += 2 * Math.PI * this.rotateDelta_.y / screen.height * MOUSE_SPEED_Y; this.theta_ += 2 * Math.PI * this.rotateDelta_.x / screen.width * MOUSE_SPEED_X; // Prevent looking too far up or down. this.phi_ = Util.clamp(this.phi_, -Math.PI/2, Math.PI/2); }; MouseKeyboardVRDisplay.prototype.onMouseUp_ = function(e) { this.isDragging_ = false; }; MouseKeyboardVRDisplay.prototype.isPointerLocked_ = function() { var el = document.pointerLockElement || document.mozPointerLockElement || document.webkitPointerLockElement; return el !== undefined; }; MouseKeyboardVRDisplay.prototype.resetPose = function() { this.phi_ = 0; this.theta_ = 0; }; module.exports = MouseKeyboardVRDisplay; },{"./base.js":3,"./math-util.js":14,"./util.js":22}],16:[function(_dereq_,module,exports){ /* * Copyright 2015 Google Inc. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var Util = _dereq_('./util.js'); function RotateInstructions() { this.loadIcon_(); var overlay = document.createElement('div'); var s = overlay.style; s.position = 'fixed'; s.top = 0; s.right = 0; s.bottom = 0; s.left = 0; s.backgroundColor = 'gray'; s.fontFamily = 'sans-serif'; // Force this to be above the fullscreen canvas, which is at zIndex: 999999. s.zIndex = 1000000; var img = document.createElement('img'); img.src = this.icon; var s = img.style; s.marginLeft = '25%'; s.marginTop = '25%'; s.width = '50%'; overlay.appendChild(img); var text = document.createElement('div'); var s = text.style; s.textAlign = 'center'; s.fontSize = '16px'; s.lineHeight = '24px'; s.margin = '24px 25%'; s.width = '50%'; text.innerHTML = 'Place your phone into your Cardboard viewer.'; overlay.appendChild(text); var snackbar = document.createElement('div'); var s = snackbar.style; s.backgroundColor = '#CFD8DC'; s.position = 'fixed'; s.bottom = 0; s.width = '100%'; s.height = '48px'; s.padding = '14px 24px'; s.boxSizing = 'border-box'; s.color = '#656A6B'; overlay.appendChild(snackbar); var snackbarText = document.createElement('div'); snackbarText.style.float = 'left'; snackbarText.innerHTML = 'No Cardboard viewer?'; var snackbarButton = document.createElement('a'); snackbarButton.href = 'https://www.google.com/get/cardboard/get-cardboard/'; snackbarButton.innerHTML = 'get one'; snackbarButton.target = '_blank'; var s = snackbarButton.style; s.float = 'right'; s.fontWeight = 600; s.textTransform = 'uppercase'; s.borderLeft = '1px solid gray'; s.paddingLeft = '24px'; s.textDecoration = 'none'; s.color = '#656A6B'; snackbar.appendChild(snackbarText); snackbar.appendChild(snackbarButton); this.overlay = overlay; this.text = text; this.hide(); } RotateInstructions.prototype.show = function(parent) { if (!parent && !this.overlay.parentElement) { document.body.appendChild(this.overlay); } else if (parent) { if (this.overlay.parentElement && this.overlay.parentElement != parent) this.overlay.parentElement.removeChild(this.overlay); parent.appendChild(this.overlay); } this.overlay.style.display = 'block'; var img = this.overlay.querySelector('img'); var s = img.style; if (Util.isLandscapeMode()) { s.width = '20%'; s.marginLeft = '40%'; s.marginTop = '3%'; } else { s.width = '50%'; s.marginLeft = '25%'; s.marginTop = '25%'; } }; RotateInstructions.prototype.hide = function() { this.overlay.style.display = 'none'; }; RotateInstructions.prototype.showTemporarily = function(ms, parent) { this.show(parent); this.timer = setTimeout(this.hide.bind(this), ms); }; RotateInstructions.prototype.disableShowTemporarily = function() { clearTimeout(this.timer); }; RotateInstructions.prototype.update = function() { this.disableShowTemporarily(); // In portrait VR mode, tell the user to rotate to landscape. Otherwise, hide // the instructions. if (!Util.isLandscapeMode() && Util.isMobile()) { this.show(); } else { this.hide(); } }; RotateInstructions.prototype.loadIcon_ = function() { // Encoded asset_src/rotate-instructions.svg this.icon = Util.base64('image/svg+xml', 'PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+Cjxzdmcgd2lkdGg9IjE5OHB4IiBoZWlnaHQ9IjI0MHB4IiB2aWV3Qm94PSIwIDAgMTk4IDI0MCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWxuczpza2V0Y2g9Imh0dHA6Ly93d3cuYm9oZW1pYW5jb2RpbmcuY29tL3NrZXRjaC9ucyI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDMuMy4zICgxMjA4MSkgLSBodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2ggLS0+CiAgICA8dGl0bGU+dHJhbnNpdGlvbjwvdGl0bGU+CiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4KICAgIDxkZWZzPjwvZGVmcz4KICAgIDxnIGlkPSJQYWdlLTEiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHNrZXRjaDp0eXBlPSJNU1BhZ2UiPgogICAgICAgIDxnIGlkPSJ0cmFuc2l0aW9uIiBza2V0Y2g6dHlwZT0iTVNBcnRib2FyZEdyb3VwIj4KICAgICAgICAgICAgPGcgaWQ9IkltcG9ydGVkLUxheWVycy1Db3B5LTQtKy1JbXBvcnRlZC1MYXllcnMtQ29weS0rLUltcG9ydGVkLUxheWVycy1Db3B5LTItQ29weSIgc2tldGNoOnR5cGU9Ik1TTGF5ZXJHcm91cCI+CiAgICAgICAgICAgICAgICA8ZyBpZD0iSW1wb3J0ZWQtTGF5ZXJzLUNvcHktNCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMC4wMDAwMDAsIDEwNy4wMDAwMDApIiBza2V0Y2g6dHlwZT0iTVNTaGFwZUdyb3VwIj4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTQ5LjYyNSwyLjUyNyBDMTQ5LjYyNSwyLjUyNyAxNTUuODA1LDYuMDk2IDE1Ni4zNjIsNi40MTggTDE1Ni4zNjIsNy4zMDQgQzE1Ni4zNjIsNy40ODEgMTU2LjM3NSw3LjY2NCAxNTYuNCw3Ljg1MyBDMTU2LjQxLDcuOTM0IDE1Ni40Miw4LjAxNSAxNTYuNDI3LDguMDk1IEMxNTYuNTY3LDkuNTEgMTU3LjQwMSwxMS4wOTMgMTU4LjUzMiwxMi4wOTQgTDE2NC4yNTIsMTcuMTU2IEwxNjQuMzMzLDE3LjA2NiBDMTY0LjMzMywxNy4wNjYgMTY4LjcxNSwxNC41MzYgMTY5LjU2OCwxNC4wNDIgQzE3MS4wMjUsMTQuODgzIDE5NS41MzgsMjkuMDM1IDE5NS41MzgsMjkuMDM1IEwxOTUuNTM4LDgzLjAzNiBDMTk1LjUzOCw4My44MDcgMTk1LjE1Miw4NC4yNTMgMTk0LjU5LDg0LjI1MyBDMTk0LjM1Nyw4NC4yNTMgMTk0LjA5NSw4NC4xNzcgMTkzLjgxOCw4NC4wMTcgTDE2OS44NTEsNzAuMTc5IEwxNjkuODM3LDcwLjIwMyBMMTQyLjUxNSw4NS45NzggTDE0MS42NjUsODQuNjU1IEMxMzYuOTM0LDgzLjEyNiAxMzEuOTE3LDgxLjkxNSAxMjYuNzE0LDgxLjA0NSBDMTI2LjcwOSw4MS4wNiAxMjYuNzA3LDgxLjA2OSAxMjYuNzA3LDgxLjA2OSBMMTIxLjY0LDk4LjAzIEwxMTMuNzQ5LDEwMi41ODYgTDExMy43MTIsMTAyLjUyMyBMMTEzLjcxMiwxMzAuMTEzIEMxMTMuNzEyLDEzMC44ODUgMTEzLjMyNiwxMzEuMzMgMTEyLjc2NCwxMzEuMzMgQzExMi41MzIsMTMxLjMzIDExMi4yNjksMTMxLjI1NCAxMTEuOTkyLDEzMS4wOTQgTDY5LjUxOSwxMDYuNTcyIEM2OC41NjksMTA2LjAyMyA2Ny43OTksMTA0LjY5NSA2Ny43OTksMTAzLjYwNSBMNjcuNzk5LDEwMi41NyBMNjcuNzc4LDEwMi42MTcgQzY3LjI3LDEwMi4zOTMgNjYuNjQ4LDEwMi4yNDkgNjUuOTYyLDEwMi4yMTggQzY1Ljg3NSwxMDIuMjE0IDY1Ljc4OCwxMDIuMjEyIDY1LjcwMSwxMDIuMjEyIEM2NS42MDYsMTAyLjIxMiA2NS41MTEsMTAyLjIxNSA2NS40MTYsMTAyLjIxOSBDNjUuMTk1LDEwMi4yMjkgNjQuOTc0LDEwMi4yMzUgNjQuNzU0LDEwMi4yMzUgQzY0LjMzMSwxMDIuMjM1IDYzLjkxMSwxMDIuMjE2IDYzLjQ5OCwxMDIuMTc4IEM2MS44NDMsMTAyLjAyNSA2MC4yOTgsMTAxLjU3OCA1OS4wOTQsMTAwLjg4MiBMMTIuNTE4LDczLjk5MiBMMTIuNTIzLDc0LjAwNCBMMi4yNDUsNTUuMjU0IEMxLjI0NCw1My40MjcgMi4wMDQsNTEuMDM4IDMuOTQzLDQ5LjkxOCBMNTkuOTU0LDE3LjU3MyBDNjAuNjI2LDE3LjE4NSA2MS4zNSwxNy4wMDEgNjIuMDUzLDE3LjAwMSBDNjMuMzc5LDE3LjAwMSA2NC42MjUsMTcuNjYgNjUuMjgsMTguODU0IEw2NS4yODUsMTguODUxIEw2NS41MTIsMTkuMjY0IEw2NS41MDYsMTkuMjY4IEM2NS45MDksMjAuMDAzIDY2LjQwNSwyMC42OCA2Ni45ODMsMjEuMjg2IEw2Ny4yNiwyMS41NTYgQzY5LjE3NCwyMy40MDYgNzEuNzI4LDI0LjM1NyA3NC4zNzMsMjQuMzU3IEM3Ni4zMjIsMjQuMzU3IDc4LjMyMSwyMy44NCA4MC4xNDgsMjIuNzg1IEM4MC4xNjEsMjIuNzg1IDg3LjQ2NywxOC41NjYgODcuNDY3LDE4LjU2NiBDODguMTM5LDE4LjE3OCA4OC44NjMsMTcuOTk0IDg5LjU2NiwxNy45OTQgQzkwLjg5MiwxNy45OTQgOTIuMTM4LDE4LjY1MiA5Mi43OTIsMTkuODQ3IEw5Ni4wNDIsMjUuNzc1IEw5Ni4wNjQsMjUuNzU3IEwxMDIuODQ5LDI5LjY3NCBMMTAyLjc0NCwyOS40OTIgTDE0OS42MjUsMi41MjcgTTE0OS42MjUsMC44OTIgQzE0OS4zNDMsMC44OTIgMTQ5LjA2MiwwLjk2NSAxNDguODEsMS4xMSBMMTAyLjY0MSwyNy42NjYgTDk3LjIzMSwyNC41NDIgTDk0LjIyNiwxOS4wNjEgQzkzLjMxMywxNy4zOTQgOTEuNTI3LDE2LjM1OSA4OS41NjYsMTYuMzU4IEM4OC41NTUsMTYuMzU4IDg3LjU0NiwxNi42MzIgODYuNjQ5LDE3LjE1IEM4My44NzgsMTguNzUgNzkuNjg3LDIxLjE2OSA3OS4zNzQsMjEuMzQ1IEM3OS4zNTksMjEuMzUzIDc5LjM0NSwyMS4zNjEgNzkuMzMsMjEuMzY5IEM3Ny43OTgsMjIuMjU0IDc2LjA4NCwyMi43MjIgNzQuMzczLDIyLjcyMiBDNzIuMDgxLDIyLjcyMiA2OS45NTksMjEuODkgNjguMzk3LDIwLjM4IEw2OC4xNDUsMjAuMTM1IEM2Ny43MDYsMTkuNjcyIDY3LjMyMywxOS4xNTYgNjcuMDA2LDE4LjYwMSBDNjYuOTg4LDE4LjU1OSA2Ni45NjgsMTguNTE5IDY2Ljk0NiwxOC40NzkgTDY2LjcxOSwxOC4wNjUgQzY2LjY5LDE4LjAxMiA2Ni42NTgsMTcuOTYgNjYuNjI0LDE3LjkxMSBDNjUuNjg2LDE2LjMzNyA2My45NTEsMTUuMzY2IDYyLjA1MywxNS4zNjYgQzYxLjA0MiwxNS4zNjYgNjAuMDMzLDE1LjY0IDU5LjEzNiwxNi4xNTggTDMuMTI1LDQ4LjUwMiBDMC40MjYsNTAuMDYxIC0wLjYxMyw1My40NDIgMC44MTEsNTYuMDQgTDExLjA4OSw3NC43OSBDMTEuMjY2LDc1LjExMyAxMS41MzcsNzUuMzUzIDExLjg1LDc1LjQ5NCBMNTguMjc2LDEwMi4yOTggQzU5LjY3OSwxMDMuMTA4IDYxLjQzMywxMDMuNjMgNjMuMzQ4LDEwMy44MDYgQzYzLjgxMiwxMDMuODQ4IDY0LjI4NSwxMDMuODcgNjQuNzU0LDEwMy44NyBDNjUsMTAzLjg3IDY1LjI0OSwxMDMuODY0IDY1LjQ5NCwxMDMuODUyIEM2NS41NjMsMTAzLjg0OSA2NS42MzIsMTAzLjg0NyA2NS43MDEsMTAzLjg0NyBDNjUuNzY0LDEwMy44NDcgNjUuODI4LDEwMy44NDkgNjUuODksMTAzLjg1MiBDNjUuOTg2LDEwMy44NTYgNjYuMDgsMTAzLjg2MyA2Ni4xNzMsMTAzLjg3NCBDNjYuMjgyLDEwNS40NjcgNjcuMzMyLDEwNy4xOTcgNjguNzAyLDEwNy45ODggTDExMS4xNzQsMTMyLjUxIEMxMTEuNjk4LDEzMi44MTIgMTEyLjIzMiwxMzIuOTY1IDExMi43NjQsMTMyLjk2NSBDMTE0LjI2MSwxMzIuOTY1IDExNS4zNDcsMTMxLjc2NSAxMTUuMzQ3LDEzMC4xMTMgTDExNS4zNDcsMTAzLjU1MSBMMTIyLjQ1OCw5OS40NDYgQzEyMi44MTksOTkuMjM3IDEyMy4wODcsOTguODk4IDEyMy4yMDcsOTguNDk4IEwxMjcuODY1LDgyLjkwNSBDMTMyLjI3OSw4My43MDIgMTM2LjU1Nyw4NC43NTMgMTQwLjYwNyw4Ni4wMzMgTDE0MS4xNCw4Ni44NjIgQzE0MS40NTEsODcuMzQ2IDE0MS45NzcsODcuNjEzIDE0Mi41MTYsODcuNjEzIEMxNDIuNzk0LDg3LjYxMyAxNDMuMDc2LDg3LjU0MiAxNDMuMzMzLDg3LjM5MyBMMTY5Ljg2NSw3Mi4wNzYgTDE5Myw4NS40MzMgQzE5My41MjMsODUuNzM1IDE5NC4wNTgsODUuODg4IDE5NC41OSw4NS44ODggQzE5Ni4wODcsODUuODg4IDE5Ny4xNzMsODQuNjg5IDE5Ny4xNzMsODMuMDM2IEwxOTcuMTczLDI5LjAzNSBDMTk3LjE3MywyOC40NTEgMTk2Ljg2MSwyNy45MTEgMTk2LjM1NSwyNy42MTkgQzE5Ni4zNTUsMjcuNjE5IDE3MS44NDMsMTMuNDY3IDE3MC4zODUsMTIuNjI2IEMxNzAuMTMyLDEyLjQ4IDE2OS44NSwxMi40MDcgMTY5LjU2OCwxMi40MDcgQzE2OS4yODUsMTIuNDA3IDE2OS4wMDIsMTIuNDgxIDE2OC43NDksMTIuNjI3IEMxNjguMTQzLDEyLjk3OCAxNjUuNzU2LDE0LjM1NyAxNjQuNDI0LDE1LjEyNSBMMTU5LjYxNSwxMC44NyBDMTU4Ljc5NiwxMC4xNDUgMTU4LjE1NCw4LjkzNyAxNTguMDU0LDcuOTM0IEMxNTguMDQ1LDcuODM3IDE1OC4wMzQsNy43MzkgMTU4LjAyMSw3LjY0IEMxNTguMDA1LDcuNTIzIDE1Ny45OTgsNy40MSAxNTcuOTk4LDcuMzA0IEwxNTcuOTk4LDYuNDE4IEMxNTcuOTk4LDUuODM0IDE1Ny42ODYsNS4yOTUgMTU3LjE4MSw1LjAwMiBDMTU2LjYyNCw0LjY4IDE1MC40NDIsMS4xMTEgMTUwLjQ0MiwxLjExMSBDMTUwLjE4OSwwLjk2NSAxNDkuOTA3LDAuODkyIDE0OS42MjUsMC44OTIiIGlkPSJGaWxsLTEiIGZpbGw9IiM0NTVBNjQiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNOTYuMDI3LDI1LjYzNiBMMTQyLjYwMyw1Mi41MjcgQzE0My44MDcsNTMuMjIyIDE0NC41ODIsNTQuMTE0IDE0NC44NDUsNTUuMDY4IEwxNDQuODM1LDU1LjA3NSBMNjMuNDYxLDEwMi4wNTcgTDYzLjQ2LDEwMi4wNTcgQzYxLjgwNiwxMDEuOTA1IDYwLjI2MSwxMDEuNDU3IDU5LjA1NywxMDAuNzYyIEwxMi40ODEsNzMuODcxIEw5Ni4wMjcsMjUuNjM2IiBpZD0iRmlsbC0yIiBmaWxsPSIjRkFGQUZBIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTYzLjQ2MSwxMDIuMTc0IEM2My40NTMsMTAyLjE3NCA2My40NDYsMTAyLjE3NCA2My40MzksMTAyLjE3MiBDNjEuNzQ2LDEwMi4wMTYgNjAuMjExLDEwMS41NjMgNTguOTk4LDEwMC44NjMgTDEyLjQyMiw3My45NzMgQzEyLjM4Niw3My45NTIgMTIuMzY0LDczLjkxNCAxMi4zNjQsNzMuODcxIEMxMi4zNjQsNzMuODMgMTIuMzg2LDczLjc5MSAxMi40MjIsNzMuNzcgTDk1Ljk2OCwyNS41MzUgQzk2LjAwNCwyNS41MTQgOTYuMDQ5LDI1LjUxNCA5Ni4wODUsMjUuNTM1IEwxNDIuNjYxLDUyLjQyNiBDMTQzLjg4OCw1My4xMzQgMTQ0LjY4Miw1NC4wMzggMTQ0Ljk1Nyw1NS4wMzcgQzE0NC45Nyw1NS4wODMgMTQ0Ljk1Myw1NS4xMzMgMTQ0LjkxNSw1NS4xNjEgQzE0NC45MTEsNTUuMTY1IDE0NC44OTgsNTUuMTc0IDE0NC44OTQsNTUuMTc3IEw2My41MTksMTAyLjE1OCBDNjMuNTAxLDEwMi4xNjkgNjMuNDgxLDEwMi4xNzQgNjMuNDYxLDEwMi4xNzQgTDYzLjQ2MSwxMDIuMTc0IFogTTEyLjcxNCw3My44NzEgTDU5LjExNSwxMDAuNjYxIEM2MC4yOTMsMTAxLjM0MSA2MS43ODYsMTAxLjc4MiA2My40MzUsMTAxLjkzNyBMMTQ0LjcwNyw1NS4wMTUgQzE0NC40MjgsNTQuMTA4IDE0My42ODIsNTMuMjg1IDE0Mi41NDQsNTIuNjI4IEw5Ni4wMjcsMjUuNzcxIEwxMi43MTQsNzMuODcxIEwxMi43MTQsNzMuODcxIFoiIGlkPSJGaWxsLTMiIGZpbGw9IiM2MDdEOEIiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTQ4LjMyNyw1OC40NzEgQzE0OC4xNDUsNTguNDggMTQ3Ljk2Miw1OC40OCAxNDcuNzgxLDU4LjQ3MiBDMTQ1Ljg4Nyw1OC4zODkgMTQ0LjQ3OSw1Ny40MzQgMTQ0LjYzNiw1Ni4zNCBDMTQ0LjY4OSw1NS45NjcgMTQ0LjY2NCw1NS41OTcgMTQ0LjU2NCw1NS4yMzUgTDYzLjQ2MSwxMDIuMDU3IEM2NC4wODksMTAyLjExNSA2NC43MzMsMTAyLjEzIDY1LjM3OSwxMDIuMDk5IEM2NS41NjEsMTAyLjA5IDY1Ljc0MywxMDIuMDkgNjUuOTI1LDEwMi4wOTggQzY3LjgxOSwxMDIuMTgxIDY5LjIyNywxMDMuMTM2IDY5LjA3LDEwNC4yMyBMMTQ4LjMyNyw1OC40NzEiIGlkPSJGaWxsLTQiIGZpbGw9IiNGRkZGRkYiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNNjkuMDcsMTA0LjM0NyBDNjkuMDQ4LDEwNC4zNDcgNjkuMDI1LDEwNC4zNCA2OS4wMDUsMTA0LjMyNyBDNjguOTY4LDEwNC4zMDEgNjguOTQ4LDEwNC4yNTcgNjguOTU1LDEwNC4yMTMgQzY5LDEwMy44OTYgNjguODk4LDEwMy41NzYgNjguNjU4LDEwMy4yODggQzY4LjE1MywxMDIuNjc4IDY3LjEwMywxMDIuMjY2IDY1LjkyLDEwMi4yMTQgQzY1Ljc0MiwxMDIuMjA2IDY1LjU2MywxMDIuMjA3IDY1LjM4NSwxMDIuMjE1IEM2NC43NDIsMTAyLjI0NiA2NC4wODcsMTAyLjIzMiA2My40NSwxMDIuMTc0IEM2My4zOTksMTAyLjE2OSA2My4zNTgsMTAyLjEzMiA2My4zNDcsMTAyLjA4MiBDNjMuMzM2LDEwMi4wMzMgNjMuMzU4LDEwMS45ODEgNjMuNDAyLDEwMS45NTYgTDE0NC41MDYsNTUuMTM0IEMxNDQuNTM3LDU1LjExNiAxNDQuNTc1LDU1LjExMyAxNDQuNjA5LDU1LjEyNyBDMTQ0LjY0Miw1NS4xNDEgMTQ0LjY2OCw1NS4xNyAxNDQuNjc3LDU1LjIwNCBDMTQ0Ljc4MSw1NS41ODUgMTQ0LjgwNiw1NS45NzIgMTQ0Ljc1MSw1Ni4zNTcgQzE0NC43MDYsNTYuNjczIDE0NC44MDgsNTYuOTk0IDE0NS4wNDcsNTcuMjgyIEMxNDUuNTUzLDU3Ljg5MiAxNDYuNjAyLDU4LjMwMyAxNDcuNzg2LDU4LjM1NSBDMTQ3Ljk2NCw1OC4zNjMgMTQ4LjE0Myw1OC4zNjMgMTQ4LjMyMSw1OC4zNTQgQzE0OC4zNzcsNTguMzUyIDE0OC40MjQsNTguMzg3IDE0OC40MzksNTguNDM4IEMxNDguNDU0LDU4LjQ5IDE0OC40MzIsNTguNTQ1IDE0OC4zODUsNTguNTcyIEw2OS4xMjksMTA0LjMzMSBDNjkuMTExLDEwNC4zNDIgNjkuMDksMTA0LjM0NyA2OS4wNywxMDQuMzQ3IEw2OS4wNywxMDQuMzQ3IFogTTY1LjY2NSwxMDEuOTc1IEM2NS43NTQsMTAxLjk3NSA2NS44NDIsMTAxLjk3NyA2NS45MywxMDEuOTgxIEM2Ny4xOTYsMTAyLjAzNyA2OC4yODMsMTAyLjQ2OSA2OC44MzgsMTAzLjEzOSBDNjkuMDY1LDEwMy40MTMgNjkuMTg4LDEwMy43MTQgNjkuMTk4LDEwNC4wMjEgTDE0Ny44ODMsNTguNTkyIEMxNDcuODQ3LDU4LjU5MiAxNDcuODExLDU4LjU5MSAxNDcuNzc2LDU4LjU4OSBDMTQ2LjUwOSw1OC41MzMgMTQ1LjQyMiw1OC4xIDE0NC44NjcsNTcuNDMxIEMxNDQuNTg1LDU3LjA5MSAxNDQuNDY1LDU2LjcwNyAxNDQuNTIsNTYuMzI0IEMxNDQuNTYzLDU2LjAyMSAxNDQuNTUyLDU1LjcxNiAxNDQuNDg4LDU1LjQxNCBMNjMuODQ2LDEwMS45NyBDNjQuMzUzLDEwMi4wMDIgNjQuODY3LDEwMi4wMDYgNjUuMzc0LDEwMS45ODIgQzY1LjQ3MSwxMDEuOTc3IDY1LjU2OCwxMDEuOTc1IDY1LjY2NSwxMDEuOTc1IEw2NS42NjUsMTAxLjk3NSBaIiBpZD0iRmlsbC01IiBmaWxsPSIjNjA3RDhCIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTIuMjA4LDU1LjEzNCBDMS4yMDcsNTMuMzA3IDEuOTY3LDUwLjkxNyAzLjkwNiw0OS43OTcgTDU5LjkxNywxNy40NTMgQzYxLjg1NiwxNi4zMzMgNjQuMjQxLDE2LjkwNyA2NS4yNDMsMTguNzM0IEw2NS40NzUsMTkuMTQ0IEM2NS44NzIsMTkuODgyIDY2LjM2OCwyMC41NiA2Ni45NDUsMjEuMTY1IEw2Ny4yMjMsMjEuNDM1IEM3MC41NDgsMjQuNjQ5IDc1LjgwNiwyNS4xNTEgODAuMTExLDIyLjY2NSBMODcuNDMsMTguNDQ1IEM4OS4zNywxNy4zMjYgOTEuNzU0LDE3Ljg5OSA5Mi43NTUsMTkuNzI3IEw5Ni4wMDUsMjUuNjU1IEwxMi40ODYsNzMuODg0IEwyLjIwOCw1NS4xMzQgWiIgaWQ9IkZpbGwtNiIgZmlsbD0iI0ZBRkFGQSI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0xMi40ODYsNzQuMDAxIEMxMi40NzYsNzQuMDAxIDEyLjQ2NSw3My45OTkgMTIuNDU1LDczLjk5NiBDMTIuNDI0LDczLjk4OCAxMi4zOTksNzMuOTY3IDEyLjM4NCw3My45NCBMMi4xMDYsNTUuMTkgQzEuMDc1LDUzLjMxIDEuODU3LDUwLjg0NSAzLjg0OCw0OS42OTYgTDU5Ljg1OCwxNy4zNTIgQzYwLjUyNSwxNi45NjcgNjEuMjcxLDE2Ljc2NCA2Mi4wMTYsMTYuNzY0IEM2My40MzEsMTYuNzY0IDY0LjY2NiwxNy40NjYgNjUuMzI3LDE4LjY0NiBDNjUuMzM3LDE4LjY1NCA2NS4zNDUsMTguNjYzIDY1LjM1MSwxOC42NzQgTDY1LjU3OCwxOS4wODggQzY1LjU4NCwxOS4xIDY1LjU4OSwxOS4xMTIgNjUuNTkxLDE5LjEyNiBDNjUuOTg1LDE5LjgzOCA2Ni40NjksMjAuNDk3IDY3LjAzLDIxLjA4NSBMNjcuMzA1LDIxLjM1MSBDNjkuMTUxLDIzLjEzNyA3MS42NDksMjQuMTIgNzQuMzM2LDI0LjEyIEM3Ni4zMTMsMjQuMTIgNzguMjksMjMuNTgyIDgwLjA1MywyMi41NjMgQzgwLjA2NCwyMi41NTcgODAuMDc2LDIyLjU1MyA4MC4wODgsMjIuNTUgTDg3LjM3MiwxOC4zNDQgQzg4LjAzOCwxNy45NTkgODguNzg0LDE3Ljc1NiA4OS41MjksMTcuNzU2IEM5MC45NTYsMTcuNzU2IDkyLjIwMSwxOC40NzIgOTIuODU4LDE5LjY3IEw5Ni4xMDcsMjUuNTk5IEM5Ni4xMzgsMjUuNjU0IDk2LjExOCwyNS43MjQgOTYuMDYzLDI1Ljc1NiBMMTIuNTQ1LDczLjk4NSBDMTIuNTI2LDczLjk5NiAxMi41MDYsNzQuMDAxIDEyLjQ4Niw3NC4wMDEgTDEyLjQ4Niw3NC4wMDEgWiBNNjIuMDE2LDE2Ljk5NyBDNjEuMzEyLDE2Ljk5NyA2MC42MDYsMTcuMTkgNTkuOTc1LDE3LjU1NCBMMy45NjUsNDkuODk5IEMyLjA4Myw1MC45ODUgMS4zNDEsNTMuMzA4IDIuMzEsNTUuMDc4IEwxMi41MzEsNzMuNzIzIEw5NS44NDgsMjUuNjExIEw5Mi42NTMsMTkuNzgyIEM5Mi4wMzgsMTguNjYgOTAuODcsMTcuOTkgODkuNTI5LDE3Ljk5IEM4OC44MjUsMTcuOTkgODguMTE5LDE4LjE4MiA4Ny40ODksMTguNTQ3IEw4MC4xNzIsMjIuNzcyIEM4MC4xNjEsMjIuNzc4IDgwLjE0OSwyMi43ODIgODAuMTM3LDIyLjc4NSBDNzguMzQ2LDIzLjgxMSA3Ni4zNDEsMjQuMzU0IDc0LjMzNiwyNC4zNTQgQzcxLjU4OCwyNC4zNTQgNjkuMDMzLDIzLjM0NyA2Ny4xNDIsMjEuNTE5IEw2Ni44NjQsMjEuMjQ5IEM2Ni4yNzcsMjAuNjM0IDY1Ljc3NCwxOS45NDcgNjUuMzY3LDE5LjIwMyBDNjUuMzYsMTkuMTkyIDY1LjM1NiwxOS4xNzkgNjUuMzU0LDE5LjE2NiBMNjUuMTYzLDE4LjgxOSBDNjUuMTU0LDE4LjgxMSA2NS4xNDYsMTguODAxIDY1LjE0LDE4Ljc5IEM2NC41MjUsMTcuNjY3IDYzLjM1NywxNi45OTcgNjIuMDE2LDE2Ljk5NyBMNjIuMDE2LDE2Ljk5NyBaIiBpZD0iRmlsbC03IiBmaWxsPSIjNjA3RDhCIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTQyLjQzNCw0OC44MDggTDQyLjQzNCw0OC44MDggQzM5LjkyNCw0OC44MDcgMzcuNzM3LDQ3LjU1IDM2LjU4Miw0NS40NDMgQzM0Ljc3MSw0Mi4xMzkgMzYuMTQ0LDM3LjgwOSAzOS42NDEsMzUuNzg5IEw1MS45MzIsMjguNjkxIEM1My4xMDMsMjguMDE1IDU0LjQxMywyNy42NTggNTUuNzIxLDI3LjY1OCBDNTguMjMxLDI3LjY1OCA2MC40MTgsMjguOTE2IDYxLjU3MywzMS4wMjMgQzYzLjM4NCwzNC4zMjcgNjIuMDEyLDM4LjY1NyA1OC41MTQsNDAuNjc3IEw0Ni4yMjMsNDcuNzc1IEM0NS4wNTMsNDguNDUgNDMuNzQyLDQ4LjgwOCA0Mi40MzQsNDguODA4IEw0Mi40MzQsNDguODA4IFogTTU1LjcyMSwyOC4xMjUgQzU0LjQ5NSwyOC4xMjUgNTMuMjY1LDI4LjQ2MSA1Mi4xNjYsMjkuMDk2IEwzOS44NzUsMzYuMTk0IEMzNi41OTYsMzguMDg3IDM1LjMwMiw0Mi4xMzYgMzYuOTkyLDQ1LjIxOCBDMzguMDYzLDQ3LjE3MyA0MC4wOTgsNDguMzQgNDIuNDM0LDQ4LjM0IEM0My42NjEsNDguMzQgNDQuODksNDguMDA1IDQ1Ljk5LDQ3LjM3IEw1OC4yODEsNDAuMjcyIEM2MS41NiwzOC4zNzkgNjIuODUzLDM0LjMzIDYxLjE2NCwzMS4yNDggQzYwLjA5MiwyOS4yOTMgNTguMDU4LDI4LjEyNSA1NS43MjEsMjguMTI1IEw1NS43MjEsMjguMTI1IFoiIGlkPSJGaWxsLTgiIGZpbGw9IiM2MDdEOEIiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTQ5LjU4OCwyLjQwNyBDMTQ5LjU4OCwyLjQwNyAxNTUuNzY4LDUuOTc1IDE1Ni4zMjUsNi4yOTcgTDE1Ni4zMjUsNy4xODQgQzE1Ni4zMjUsNy4zNiAxNTYuMzM4LDcuNTQ0IDE1Ni4zNjIsNy43MzMgQzE1Ni4zNzMsNy44MTQgMTU2LjM4Miw3Ljg5NCAxNTYuMzksNy45NzUgQzE1Ni41Myw5LjM5IDE1Ny4zNjMsMTAuOTczIDE1OC40OTUsMTEuOTc0IEwxNjUuODkxLDE4LjUxOSBDMTY2LjA2OCwxOC42NzUgMTY2LjI0OSwxOC44MTQgMTY2LjQzMiwxOC45MzQgQzE2OC4wMTEsMTkuOTc0IDE2OS4zODIsMTkuNCAxNjkuNDk0LDE3LjY1MiBDMTY5LjU0MywxNi44NjggMTY5LjU1MSwxNi4wNTcgMTY5LjUxNywxNS4yMjMgTDE2OS41MTQsMTUuMDYzIEwxNjkuNTE0LDEzLjkxMiBDMTcwLjc4LDE0LjY0MiAxOTUuNTAxLDI4LjkxNSAxOTUuNTAxLDI4LjkxNSBMMTk1LjUwMSw4Mi45MTUgQzE5NS41MDEsODQuMDA1IDE5NC43MzEsODQuNDQ1IDE5My43ODEsODMuODk3IEwxNTEuMzA4LDU5LjM3NCBDMTUwLjM1OCw1OC44MjYgMTQ5LjU4OCw1Ny40OTcgMTQ5LjU4OCw1Ni40MDggTDE0OS41ODgsMjIuMzc1IiBpZD0iRmlsbC05IiBmaWxsPSIjRkFGQUZBIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTE5NC41NTMsODQuMjUgQzE5NC4yOTYsODQuMjUgMTk0LjAxMyw4NC4xNjUgMTkzLjcyMiw4My45OTcgTDE1MS4yNSw1OS40NzYgQzE1MC4yNjksNTguOTA5IDE0OS40NzEsNTcuNTMzIDE0OS40NzEsNTYuNDA4IEwxNDkuNDcxLDIyLjM3NSBMMTQ5LjcwNSwyMi4zNzUgTDE0OS43MDUsNTYuNDA4IEMxNDkuNzA1LDU3LjQ1OSAxNTAuNDUsNTguNzQ0IDE1MS4zNjYsNTkuMjc0IEwxOTMuODM5LDgzLjc5NSBDMTk0LjI2Myw4NC4wNCAxOTQuNjU1LDg0LjA4MyAxOTQuOTQyLDgzLjkxNyBDMTk1LjIyNyw4My43NTMgMTk1LjM4NCw4My4zOTcgMTk1LjM4NCw4Mi45MTUgTDE5NS4zODQsMjguOTgyIEMxOTQuMTAyLDI4LjI0MiAxNzIuMTA0LDE1LjU0MiAxNjkuNjMxLDE0LjExNCBMMTY5LjYzNCwxNS4yMiBDMTY5LjY2OCwxNi4wNTIgMTY5LjY2LDE2Ljg3NCAxNjkuNjEsMTcuNjU5IEMxNjkuNTU2LDE4LjUwMyAxNjkuMjE0LDE5LjEyMyAxNjguNjQ3LDE5LjQwNSBDMTY4LjAyOCwxOS43MTQgMTY3LjE5NywxOS41NzggMTY2LjM2NywxOS4wMzIgQzE2Ni4xODEsMTguOTA5IDE2NS45OTUsMTguNzY2IDE2NS44MTQsMTguNjA2IEwxNTguNDE3LDEyLjA2MiBDMTU3LjI1OSwxMS4wMzYgMTU2LjQxOCw5LjQzNyAxNTYuMjc0LDcuOTg2IEMxNTYuMjY2LDcuOTA3IDE1Ni4yNTcsNy44MjcgMTU2LjI0Nyw3Ljc0OCBDMTU2LjIyMSw3LjU1NSAxNTYuMjA5LDcuMzY1IDE1Ni4yMDksNy4xODQgTDE1Ni4yMDksNi4zNjQgQzE1NS4zNzUsNS44ODMgMTQ5LjUyOSwyLjUwOCAxNDkuNTI5LDIuNTA4IEwxNDkuNjQ2LDIuMzA2IEMxNDkuNjQ2LDIuMzA2IDE1NS44MjcsNS44NzQgMTU2LjM4NCw2LjE5NiBMMTU2LjQ0Miw2LjIzIEwxNTYuNDQyLDcuMTg0IEMxNTYuNDQyLDcuMzU1IDE1Ni40NTQsNy41MzUgMTU2LjQ3OCw3LjcxNyBDMTU2LjQ4OSw3LjggMTU2LjQ5OSw3Ljg4MiAxNTYuNTA3LDcuOTYzIEMxNTYuNjQ1LDkuMzU4IDE1Ny40NTUsMTAuODk4IDE1OC41NzIsMTEuODg2IEwxNjUuOTY5LDE4LjQzMSBDMTY2LjE0MiwxOC41ODQgMTY2LjMxOSwxOC43MiAxNjYuNDk2LDE4LjgzNyBDMTY3LjI1NCwxOS4zMzYgMTY4LDE5LjQ2NyAxNjguNTQzLDE5LjE5NiBDMTY5LjAzMywxOC45NTMgMTY5LjMyOSwxOC40MDEgMTY5LjM3NywxNy42NDUgQzE2OS40MjcsMTYuODY3IDE2OS40MzQsMTYuMDU0IDE2OS40MDEsMTUuMjI4IEwxNjkuMzk3LDE1LjA2NSBMMTY5LjM5NywxMy43MSBMMTY5LjU3MiwxMy44MSBDMTcwLjgzOSwxNC41NDEgMTk1LjU1OSwyOC44MTQgMTk1LjU1OSwyOC44MTQgTDE5NS42MTgsMjguODQ3IEwxOTUuNjE4LDgyLjkxNSBDMTk1LjYxOCw4My40ODQgMTk1LjQyLDgzLjkxMSAxOTUuMDU5LDg0LjExOSBDMTk0LjkwOCw4NC4yMDYgMTk0LjczNyw4NC4yNSAxOTQuNTUzLDg0LjI1IiBpZD0iRmlsbC0xMCIgZmlsbD0iIzYwN0Q4QiI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0xNDUuNjg1LDU2LjE2MSBMMTY5LjgsNzAuMDgzIEwxNDMuODIyLDg1LjA4MSBMMTQyLjM2LDg0Ljc3NCBDMTM1LjgyNiw4Mi42MDQgMTI4LjczMiw4MS4wNDYgMTIxLjM0MSw4MC4xNTggQzExNi45NzYsNzkuNjM0IDExMi42NzgsODEuMjU0IDExMS43NDMsODMuNzc4IEMxMTEuNTA2LDg0LjQxNCAxMTEuNTAzLDg1LjA3MSAxMTEuNzMyLDg1LjcwNiBDMTEzLjI3LDg5Ljk3MyAxMTUuOTY4LDk0LjA2OSAxMTkuNzI3LDk3Ljg0MSBMMTIwLjI1OSw5OC42ODYgQzEyMC4yNiw5OC42ODUgOTQuMjgyLDExMy42ODMgOTQuMjgyLDExMy42ODMgTDcwLjE2Nyw5OS43NjEgTDE0NS42ODUsNTYuMTYxIiBpZD0iRmlsbC0xMSIgZmlsbD0iI0ZGRkZGRiI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik05NC4yODIsMTEzLjgxOCBMOTQuMjIzLDExMy43ODUgTDY5LjkzMyw5OS43NjEgTDcwLjEwOCw5OS42NiBMMTQ1LjY4NSw1Ni4wMjYgTDE0NS43NDMsNTYuMDU5IEwxNzAuMDMzLDcwLjA4MyBMMTQzLjg0Miw4NS4yMDUgTDE0My43OTcsODUuMTk1IEMxNDMuNzcyLDg1LjE5IDE0Mi4zMzYsODQuODg4IDE0Mi4zMzYsODQuODg4IEMxMzUuNzg3LDgyLjcxNCAxMjguNzIzLDgxLjE2MyAxMjEuMzI3LDgwLjI3NCBDMTIwLjc4OCw4MC4yMDkgMTIwLjIzNiw4MC4xNzcgMTE5LjY4OSw4MC4xNzcgQzExNS45MzEsODAuMTc3IDExMi42MzUsODEuNzA4IDExMS44NTIsODMuODE5IEMxMTEuNjI0LDg0LjQzMiAxMTEuNjIxLDg1LjA1MyAxMTEuODQyLDg1LjY2NyBDMTEzLjM3Nyw4OS45MjUgMTE2LjA1OCw5My45OTMgMTE5LjgxLDk3Ljc1OCBMMTE5LjgyNiw5Ny43NzkgTDEyMC4zNTIsOTguNjE0IEMxMjAuMzU0LDk4LjYxNyAxMjAuMzU2LDk4LjYyIDEyMC4zNTgsOTguNjI0IEwxMjAuNDIyLDk4LjcyNiBMMTIwLjMxNyw5OC43ODcgQzEyMC4yNjQsOTguODE4IDk0LjU5OSwxMTMuNjM1IDk0LjM0LDExMy43ODUgTDk0LjI4MiwxMTMuODE4IEw5NC4yODIsMTEzLjgxOCBaIE03MC40MDEsOTkuNzYxIEw5NC4yODIsMTEzLjU0OSBMMTE5LjA4NCw5OS4yMjkgQzExOS42Myw5OC45MTQgMTE5LjkzLDk4Ljc0IDEyMC4xMDEsOTguNjU0IEwxMTkuNjM1LDk3LjkxNCBDMTE1Ljg2NCw5NC4xMjcgMTEzLjE2OCw5MC4wMzMgMTExLjYyMiw4NS43NDYgQzExMS4zODIsODUuMDc5IDExMS4zODYsODQuNDA0IDExMS42MzMsODMuNzM4IEMxMTIuNDQ4LDgxLjUzOSAxMTUuODM2LDc5Ljk0MyAxMTkuNjg5LDc5Ljk0MyBDMTIwLjI0Niw3OS45NDMgMTIwLjgwNiw3OS45NzYgMTIxLjM1NSw4MC4wNDIgQzEyOC43NjcsODAuOTMzIDEzNS44NDYsODIuNDg3IDE0Mi4zOTYsODQuNjYzIEMxNDMuMjMyLDg0LjgzOCAxNDMuNjExLDg0LjkxNyAxNDMuNzg2LDg0Ljk2NyBMMTY5LjU2Niw3MC4wODMgTDE0NS42ODUsNTYuMjk1IEw3MC40MDEsOTkuNzYxIEw3MC40MDEsOTkuNzYxIFoiIGlkPSJGaWxsLTEyIiBmaWxsPSIjNjA3RDhCIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTE2Ny4yMywxOC45NzkgTDE2Ny4yMyw2OS44NSBMMTM5LjkwOSw4NS42MjMgTDEzMy40NDgsNzEuNDU2IEMxMzIuNTM4LDY5LjQ2IDEzMC4wMiw2OS43MTggMTI3LjgyNCw3Mi4wMyBDMTI2Ljc2OSw3My4xNCAxMjUuOTMxLDc0LjU4NSAxMjUuNDk0LDc2LjA0OCBMMTE5LjAzNCw5Ny42NzYgTDkxLjcxMiwxMTMuNDUgTDkxLjcxMiw2Mi41NzkgTDE2Ny4yMywxOC45NzkiIGlkPSJGaWxsLTEzIiBmaWxsPSIjRkZGRkZGIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTkxLjcxMiwxMTMuNTY3IEM5MS42OTIsMTEzLjU2NyA5MS42NzIsMTEzLjU2MSA5MS42NTMsMTEzLjU1MSBDOTEuNjE4LDExMy41MyA5MS41OTUsMTEzLjQ5MiA5MS41OTUsMTEzLjQ1IEw5MS41OTUsNjIuNTc5IEM5MS41OTUsNjIuNTM3IDkxLjYxOCw2Mi40OTkgOTEuNjUzLDYyLjQ3OCBMMTY3LjE3MiwxOC44NzggQzE2Ny4yMDgsMTguODU3IDE2Ny4yNTIsMTguODU3IDE2Ny4yODgsMTguODc4IEMxNjcuMzI0LDE4Ljg5OSAxNjcuMzQ3LDE4LjkzNyAxNjcuMzQ3LDE4Ljk3OSBMMTY3LjM0Nyw2OS44NSBDMTY3LjM0Nyw2OS44OTEgMTY3LjMyNCw2OS45MyAxNjcuMjg4LDY5Ljk1IEwxMzkuOTY3LDg1LjcyNSBDMTM5LjkzOSw4NS43NDEgMTM5LjkwNSw4NS43NDUgMTM5Ljg3Myw4NS43MzUgQzEzOS44NDIsODUuNzI1IDEzOS44MTYsODUuNzAyIDEzOS44MDIsODUuNjcyIEwxMzMuMzQyLDcxLjUwNCBDMTMyLjk2Nyw3MC42ODIgMTMyLjI4LDcwLjIyOSAxMzEuNDA4LDcwLjIyOSBDMTMwLjMxOSw3MC4yMjkgMTI5LjA0NCw3MC45MTUgMTI3LjkwOCw3Mi4xMSBDMTI2Ljg3NCw3My4yIDEyNi4wMzQsNzQuNjQ3IDEyNS42MDYsNzYuMDgyIEwxMTkuMTQ2LDk3LjcwOSBDMTE5LjEzNyw5Ny43MzggMTE5LjExOCw5Ny43NjIgMTE5LjA5Miw5Ny43NzcgTDkxLjc3LDExMy41NTEgQzkxLjc1MiwxMTMuNTYxIDkxLjczMiwxMTMuNTY3IDkxLjcxMiwxMTMuNTY3IEw5MS43MTIsMTEzLjU2NyBaIE05MS44MjksNjIuNjQ3IEw5MS44MjksMTEzLjI0OCBMMTE4LjkzNSw5Ny41OTggTDEyNS4zODIsNzYuMDE1IEMxMjUuODI3LDc0LjUyNSAxMjYuNjY0LDczLjA4MSAxMjcuNzM5LDcxLjk1IEMxMjguOTE5LDcwLjcwOCAxMzAuMjU2LDY5Ljk5NiAxMzEuNDA4LDY5Ljk5NiBDMTMyLjM3Nyw2OS45OTYgMTMzLjEzOSw3MC40OTcgMTMzLjU1NCw3MS40MDcgTDEzOS45NjEsODUuNDU4IEwxNjcuMTEzLDY5Ljc4MiBMMTY3LjExMywxOS4xODEgTDkxLjgyOSw2Mi42NDcgTDkxLjgyOSw2Mi42NDcgWiIgaWQ9IkZpbGwtMTQiIGZpbGw9IiM2MDdEOEIiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTY4LjU0MywxOS4yMTMgTDE2OC41NDMsNzAuMDgzIEwxNDEuMjIxLDg1Ljg1NyBMMTM0Ljc2MSw3MS42ODkgQzEzMy44NTEsNjkuNjk0IDEzMS4zMzMsNjkuOTUxIDEyOS4xMzcsNzIuMjYzIEMxMjguMDgyLDczLjM3NCAxMjcuMjQ0LDc0LjgxOSAxMjYuODA3LDc2LjI4MiBMMTIwLjM0Niw5Ny45MDkgTDkzLjAyNSwxMTMuNjgzIEw5My4wMjUsNjIuODEzIEwxNjguNTQzLDE5LjIxMyIgaWQ9IkZpbGwtMTUiIGZpbGw9IiNGRkZGRkYiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNOTMuMDI1LDExMy44IEM5My4wMDUsMTEzLjggOTIuOTg0LDExMy43OTUgOTIuOTY2LDExMy43ODUgQzkyLjkzMSwxMTMuNzY0IDkyLjkwOCwxMTMuNzI1IDkyLjkwOCwxMTMuNjg0IEw5Mi45MDgsNjIuODEzIEM5Mi45MDgsNjIuNzcxIDkyLjkzMSw2Mi43MzMgOTIuOTY2LDYyLjcxMiBMMTY4LjQ4NCwxOS4xMTIgQzE2OC41MiwxOS4wOSAxNjguNTY1LDE5LjA5IDE2OC42MDEsMTkuMTEyIEMxNjguNjM3LDE5LjEzMiAxNjguNjYsMTkuMTcxIDE2OC42NiwxOS4yMTIgTDE2OC42Niw3MC4wODMgQzE2OC42Niw3MC4xMjUgMTY4LjYzNyw3MC4xNjQgMTY4LjYwMSw3MC4xODQgTDE0MS4yOCw4NS45NTggQzE0MS4yNTEsODUuOTc1IDE0MS4yMTcsODUuOTc5IDE0MS4xODYsODUuOTY4IEMxNDEuMTU0LDg1Ljk1OCAxNDEuMTI5LDg1LjkzNiAxNDEuMTE1LDg1LjkwNiBMMTM0LjY1NSw3MS43MzggQzEzNC4yOCw3MC45MTUgMTMzLjU5Myw3MC40NjMgMTMyLjcyLDcwLjQ2MyBDMTMxLjYzMiw3MC40NjMgMTMwLjM1Nyw3MS4xNDggMTI5LjIyMSw3Mi4zNDQgQzEyOC4xODYsNzMuNDMzIDEyNy4zNDcsNzQuODgxIDEyNi45MTksNzYuMzE1IEwxMjAuNDU4LDk3Ljk0MyBDMTIwLjQ1LDk3Ljk3MiAxMjAuNDMxLDk3Ljk5NiAxMjAuNDA1LDk4LjAxIEw5My4wODMsMTEzLjc4NSBDOTMuMDY1LDExMy43OTUgOTMuMDQ1LDExMy44IDkzLjAyNSwxMTMuOCBMOTMuMDI1LDExMy44IFogTTkzLjE0Miw2Mi44ODEgTDkzLjE0MiwxMTMuNDgxIEwxMjAuMjQ4LDk3LjgzMiBMMTI2LjY5NSw3Ni4yNDggQzEyNy4xNCw3NC43NTggMTI3Ljk3Nyw3My4zMTUgMTI5LjA1Miw3Mi4xODMgQzEzMC4yMzEsNzAuOTQyIDEzMS41NjgsNzAuMjI5IDEzMi43Miw3MC4yMjkgQzEzMy42ODksNzAuMjI5IDEzNC40NTIsNzAuNzMxIDEzNC44NjcsNzEuNjQxIEwxNDEuMjc0LDg1LjY5MiBMMTY4LjQyNiw3MC4wMTYgTDE2OC40MjYsMTkuNDE1IEw5My4xNDIsNjIuODgxIEw5My4xNDIsNjIuODgxIFoiIGlkPSJGaWxsLTE2IiBmaWxsPSIjNjA3RDhCIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTE2OS44LDcwLjA4MyBMMTQyLjQ3OCw4NS44NTcgTDEzNi4wMTgsNzEuNjg5IEMxMzUuMTA4LDY5LjY5NCAxMzIuNTksNjkuOTUxIDEzMC4zOTMsNzIuMjYzIEMxMjkuMzM5LDczLjM3NCAxMjguNSw3NC44MTkgMTI4LjA2NCw3Ni4yODIgTDEyMS42MDMsOTcuOTA5IEw5NC4yODIsMTEzLjY4MyBMOTQuMjgyLDYyLjgxMyBMMTY5LjgsMTkuMjEzIEwxNjkuOCw3MC4wODMgWiIgaWQ9IkZpbGwtMTciIGZpbGw9IiNGQUZBRkEiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNOTQuMjgyLDExMy45MTcgQzk0LjI0MSwxMTMuOTE3IDk0LjIwMSwxMTMuOTA3IDk0LjE2NSwxMTMuODg2IEM5NC4wOTMsMTEzLjg0NSA5NC4wNDgsMTEzLjc2NyA5NC4wNDgsMTEzLjY4NCBMOTQuMDQ4LDYyLjgxMyBDOTQuMDQ4LDYyLjczIDk0LjA5Myw2Mi42NTIgOTQuMTY1LDYyLjYxMSBMMTY5LjY4MywxOS4wMSBDMTY5Ljc1NSwxOC45NjkgMTY5Ljg0NCwxOC45NjkgMTY5LjkxNywxOS4wMSBDMTY5Ljk4OSwxOS4wNTIgMTcwLjAzMywxOS4xMjkgMTcwLjAzMywxOS4yMTIgTDE3MC4wMzMsNzAuMDgzIEMxNzAuMDMzLDcwLjE2NiAxNjkuOTg5LDcwLjI0NCAxNjkuOTE3LDcwLjI4NSBMMTQyLjU5NSw4Ni4wNiBDMTQyLjUzOCw4Ni4wOTIgMTQyLjQ2OSw4Ni4xIDE0Mi40MDcsODYuMDggQzE0Mi4zNDQsODYuMDYgMTQyLjI5Myw4Ni4wMTQgMTQyLjI2Niw4NS45NTQgTDEzNS44MDUsNzEuNzg2IEMxMzUuNDQ1LDcwLjk5NyAxMzQuODEzLDcwLjU4IDEzMy45NzcsNzAuNTggQzEzMi45MjEsNzAuNTggMTMxLjY3Niw3MS4yNTIgMTMwLjU2Miw3Mi40MjQgQzEyOS41NCw3My41MDEgMTI4LjcxMSw3NC45MzEgMTI4LjI4Nyw3Ni4zNDggTDEyMS44MjcsOTcuOTc2IEMxMjEuODEsOTguMDM0IDEyMS43NzEsOTguMDgyIDEyMS43Miw5OC4xMTIgTDk0LjM5OCwxMTMuODg2IEM5NC4zNjIsMTEzLjkwNyA5NC4zMjIsMTEzLjkxNyA5NC4yODIsMTEzLjkxNyBMOTQuMjgyLDExMy45MTcgWiBNOTQuNTE1LDYyLjk0OCBMOTQuNTE1LDExMy4yNzkgTDEyMS40MDYsOTcuNzU0IEwxMjcuODQsNzYuMjE1IEMxMjguMjksNzQuNzA4IDEyOS4xMzcsNzMuMjQ3IDEzMC4yMjQsNzIuMTAzIEMxMzEuNDI1LDcwLjgzOCAxMzIuNzkzLDcwLjExMiAxMzMuOTc3LDcwLjExMiBDMTM0Ljk5NSw3MC4xMTIgMTM1Ljc5NSw3MC42MzggMTM2LjIzLDcxLjU5MiBMMTQyLjU4NCw4NS41MjYgTDE2OS41NjYsNjkuOTQ4IEwxNjkuNTY2LDE5LjYxNyBMOTQuNTE1LDYyLjk0OCBMOTQuNTE1LDYyLjk0OCBaIiBpZD0iRmlsbC0xOCIgZmlsbD0iIzYwN0Q4QiI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0xMDkuODk0LDkyLjk0MyBMMTA5Ljg5NCw5Mi45NDMgQzEwOC4xMiw5Mi45NDMgMTA2LjY1Myw5Mi4yMTggMTA1LjY1LDkwLjgyMyBDMTA1LjU4Myw5MC43MzEgMTA1LjU5Myw5MC42MSAxMDUuNjczLDkwLjUyOSBDMTA1Ljc1Myw5MC40NDggMTA1Ljg4LDkwLjQ0IDEwNS45NzQsOTAuNTA2IEMxMDYuNzU0LDkxLjA1MyAxMDcuNjc5LDkxLjMzMyAxMDguNzI0LDkxLjMzMyBDMTEwLjA0Nyw5MS4zMzMgMTExLjQ3OCw5MC44OTQgMTEyLjk4LDkwLjAyNyBDMTE4LjI5MSw4Ni45NiAxMjIuNjExLDc5LjUwOSAxMjIuNjExLDczLjQxNiBDMTIyLjYxMSw3MS40ODkgMTIyLjE2OSw2OS44NTYgMTIxLjMzMyw2OC42OTIgQzEyMS4yNjYsNjguNiAxMjEuMjc2LDY4LjQ3MyAxMjEuMzU2LDY4LjM5MiBDMTIxLjQzNiw2OC4zMTEgMTIxLjU2Myw2OC4yOTkgMTIxLjY1Niw2OC4zNjUgQzEyMy4zMjcsNjkuNTM3IDEyNC4yNDcsNzEuNzQ2IDEyNC4yNDcsNzQuNTg0IEMxMjQuMjQ3LDgwLjgyNiAxMTkuODIxLDg4LjQ0NyAxMTQuMzgyLDkxLjU4NyBDMTEyLjgwOCw5Mi40OTUgMTExLjI5OCw5Mi45NDMgMTA5Ljg5NCw5Mi45NDMgTDEwOS44OTQsOTIuOTQzIFogTTEwNi45MjUsOTEuNDAxIEMxMDcuNzM4LDkyLjA1MiAxMDguNzQ1LDkyLjI3OCAxMDkuODkzLDkyLjI3OCBMMTA5Ljg5NCw5Mi4yNzggQzExMS4yMTUsOTIuMjc4IDExMi42NDcsOTEuOTUxIDExNC4xNDgsOTEuMDg0IEMxMTkuNDU5LDg4LjAxNyAxMjMuNzgsODAuNjIxIDEyMy43OCw3NC41MjggQzEyMy43OCw3Mi41NDkgMTIzLjMxNyw3MC45MjkgMTIyLjQ1NCw2OS43NjcgQzEyMi44NjUsNzAuODAyIDEyMy4wNzksNzIuMDQyIDEyMy4wNzksNzMuNDAyIEMxMjMuMDc5LDc5LjY0NSAxMTguNjUzLDg3LjI4NSAxMTMuMjE0LDkwLjQyNSBDMTExLjY0LDkxLjMzNCAxMTAuMTMsOTEuNzQyIDEwOC43MjQsOTEuNzQyIEMxMDguMDgzLDkxLjc0MiAxMDcuNDgxLDkxLjU5MyAxMDYuOTI1LDkxLjQwMSBMMTA2LjkyNSw5MS40MDEgWiIgaWQ9IkZpbGwtMTkiIGZpbGw9IiM2MDdEOEIiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTEzLjA5Nyw5MC4yMyBDMTE4LjQ4MSw4Ny4xMjIgMTIyLjg0NSw3OS41OTQgMTIyLjg0NSw3My40MTYgQzEyMi44NDUsNzEuMzY1IDEyMi4zNjIsNjkuNzI0IDEyMS41MjIsNjguNTU2IEMxMTkuNzM4LDY3LjMwNCAxMTcuMTQ4LDY3LjM2MiAxMTQuMjY1LDY5LjAyNiBDMTA4Ljg4MSw3Mi4xMzQgMTA0LjUxNyw3OS42NjIgMTA0LjUxNyw4NS44NCBDMTA0LjUxNyw4Ny44OTEgMTA1LDg5LjUzMiAxMDUuODQsOTAuNyBDMTA3LjYyNCw5MS45NTIgMTEwLjIxNCw5MS44OTQgMTEzLjA5Nyw5MC4yMyIgaWQ9IkZpbGwtMjAiIGZpbGw9IiNGQUZBRkEiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTA4LjcyNCw5MS42MTQgTDEwOC43MjQsOTEuNjE0IEMxMDcuNTgyLDkxLjYxNCAxMDYuNTY2LDkxLjQwMSAxMDUuNzA1LDkwLjc5NyBDMTA1LjY4NCw5MC43ODMgMTA1LjY2NSw5MC44MTEgMTA1LjY1LDkwLjc5IEMxMDQuNzU2LDg5LjU0NiAxMDQuMjgzLDg3Ljg0MiAxMDQuMjgzLDg1LjgxNyBDMTA0LjI4Myw3OS41NzUgMTA4LjcwOSw3MS45NTMgMTE0LjE0OCw2OC44MTIgQzExNS43MjIsNjcuOTA0IDExNy4yMzIsNjcuNDQ5IDExOC42MzgsNjcuNDQ5IEMxMTkuNzgsNjcuNDQ5IDEyMC43OTYsNjcuNzU4IDEyMS42NTYsNjguMzYyIEMxMjEuNjc4LDY4LjM3NyAxMjEuNjk3LDY4LjM5NyAxMjEuNzEyLDY4LjQxOCBDMTIyLjYwNiw2OS42NjIgMTIzLjA3OSw3MS4zOSAxMjMuMDc5LDczLjQxNSBDMTIzLjA3OSw3OS42NTggMTE4LjY1Myw4Ny4xOTggMTEzLjIxNCw5MC4zMzggQzExMS42NCw5MS4yNDcgMTEwLjEzLDkxLjYxNCAxMDguNzI0LDkxLjYxNCBMMTA4LjcyNCw5MS42MTQgWiBNMTA2LjAwNiw5MC41MDUgQzEwNi43OCw5MS4wMzcgMTA3LjY5NCw5MS4yODEgMTA4LjcyNCw5MS4yODEgQzExMC4wNDcsOTEuMjgxIDExMS40NzgsOTAuODY4IDExMi45OCw5MC4wMDEgQzExOC4yOTEsODYuOTM1IDEyMi42MTEsNzkuNDk2IDEyMi42MTEsNzMuNDAzIEMxMjIuNjExLDcxLjQ5NCAxMjIuMTc3LDY5Ljg4IDEyMS4zNTYsNjguNzE4IEMxMjAuNTgyLDY4LjE4NSAxMTkuNjY4LDY3LjkxOSAxMTguNjM4LDY3LjkxOSBDMTE3LjMxNSw2Ny45MTkgMTE1Ljg4Myw2OC4zNiAxMTQuMzgyLDY5LjIyNyBDMTA5LjA3MSw3Mi4yOTMgMTA0Ljc1MSw3OS43MzMgMTA0Ljc1MSw4NS44MjYgQzEwNC43NTEsODcuNzM1IDEwNS4xODUsODkuMzQzIDEwNi4wMDYsOTAuNTA1IEwxMDYuMDA2LDkwLjUwNSBaIiBpZD0iRmlsbC0yMSIgZmlsbD0iIzYwN0Q4QiI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0xNDkuMzE4LDcuMjYyIEwxMzkuMzM0LDE2LjE0IEwxNTUuMjI3LDI3LjE3MSBMMTYwLjgxNiwyMS4wNTkgTDE0OS4zMTgsNy4yNjIiIGlkPSJGaWxsLTIyIiBmaWxsPSIjRkFGQUZBIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTE2OS42NzYsMTMuODQgTDE1OS45MjgsMTkuNDY3IEMxNTYuMjg2LDIxLjU3IDE1MC40LDIxLjU4IDE0Ni43ODEsMTkuNDkxIEMxNDMuMTYxLDE3LjQwMiAxNDMuMTgsMTQuMDAzIDE0Ni44MjIsMTEuOSBMMTU2LjMxNyw2LjI5MiBMMTQ5LjU4OCwyLjQwNyBMNjcuNzUyLDQ5LjQ3OCBMMTEzLjY3NSw3NS45OTIgTDExNi43NTYsNzQuMjEzIEMxMTcuMzg3LDczLjg0OCAxMTcuNjI1LDczLjMxNSAxMTcuMzc0LDcyLjgyMyBDMTE1LjAxNyw2OC4xOTEgMTE0Ljc4MSw2My4yNzcgMTE2LjY5MSw1OC41NjEgQzEyMi4zMjksNDQuNjQxIDE0MS4yLDMzLjc0NiAxNjUuMzA5LDMwLjQ5MSBDMTczLjQ3OCwyOS4zODggMTgxLjk4OSwyOS41MjQgMTkwLjAxMywzMC44ODUgQzE5MC44NjUsMzEuMDMgMTkxLjc4OSwzMC44OTMgMTkyLjQyLDMwLjUyOCBMMTk1LjUwMSwyOC43NSBMMTY5LjY3NiwxMy44NCIgaWQ9IkZpbGwtMjMiIGZpbGw9IiNGQUZBRkEiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTEzLjY3NSw3Ni40NTkgQzExMy41OTQsNzYuNDU5IDExMy41MTQsNzYuNDM4IDExMy40NDIsNzYuMzk3IEw2Ny41MTgsNDkuODgyIEM2Ny4zNzQsNDkuNzk5IDY3LjI4NCw0OS42NDUgNjcuMjg1LDQ5LjQ3OCBDNjcuMjg1LDQ5LjMxMSA2Ny4zNzQsNDkuMTU3IDY3LjUxOSw0OS4wNzMgTDE0OS4zNTUsMi4wMDIgQzE0OS40OTksMS45MTkgMTQ5LjY3NywxLjkxOSAxNDkuODIxLDIuMDAyIEwxNTYuNTUsNS44ODcgQzE1Ni43NzQsNi4wMTcgMTU2Ljg1LDYuMzAyIDE1Ni43MjIsNi41MjYgQzE1Ni41OTIsNi43NDkgMTU2LjMwNyw2LjgyNiAxNTYuMDgzLDYuNjk2IEwxNDkuNTg3LDIuOTQ2IEw2OC42ODcsNDkuNDc5IEwxMTMuNjc1LDc1LjQ1MiBMMTE2LjUyMyw3My44MDggQzExNi43MTUsNzMuNjk3IDExNy4xNDMsNzMuMzk5IDExNi45NTgsNzMuMDM1IEMxMTQuNTQyLDY4LjI4NyAxMTQuMyw2My4yMjEgMTE2LjI1OCw1OC4zODUgQzExOS4wNjQsNTEuNDU4IDEyNS4xNDMsNDUuMTQzIDEzMy44NCw0MC4xMjIgQzE0Mi40OTcsMzUuMTI0IDE1My4zNTgsMzEuNjMzIDE2NS4yNDcsMzAuMDI4IEMxNzMuNDQ1LDI4LjkyMSAxODIuMDM3LDI5LjA1OCAxOTAuMDkxLDMwLjQyNSBDMTkwLjgzLDMwLjU1IDE5MS42NTIsMzAuNDMyIDE5Mi4xODYsMzAuMTI0IEwxOTQuNTY3LDI4Ljc1IEwxNjkuNDQyLDE0LjI0NCBDMTY5LjIxOSwxNC4xMTUgMTY5LjE0MiwxMy44MjkgMTY5LjI3MSwxMy42MDYgQzE2OS40LDEzLjM4MiAxNjkuNjg1LDEzLjMwNiAxNjkuOTA5LDEzLjQzNSBMMTk1LjczNCwyOC4zNDUgQzE5NS44NzksMjguNDI4IDE5NS45NjgsMjguNTgzIDE5NS45NjgsMjguNzUgQzE5NS45NjgsMjguOTE2IDE5NS44NzksMjkuMDcxIDE5NS43MzQsMjkuMTU0IEwxOTIuNjUzLDMwLjkzMyBDMTkxLjkzMiwzMS4zNSAxOTAuODksMzEuNTA4IDE4OS45MzUsMzEuMzQ2IEMxODEuOTcyLDI5Ljk5NSAxNzMuNDc4LDI5Ljg2IDE2NS4zNzIsMzAuOTU0IEMxNTMuNjAyLDMyLjU0MyAxNDIuODYsMzUuOTkzIDEzNC4zMDcsNDAuOTMxIEMxMjUuNzkzLDQ1Ljg0NyAxMTkuODUxLDUyLjAwNCAxMTcuMTI0LDU4LjczNiBDMTE1LjI3LDYzLjMxNCAxMTUuNTAxLDY4LjExMiAxMTcuNzksNzIuNjExIEMxMTguMTYsNzMuMzM2IDExNy44NDUsNzQuMTI0IDExNi45OSw3NC42MTcgTDExMy45MDksNzYuMzk3IEMxMTMuODM2LDc2LjQzOCAxMTMuNzU2LDc2LjQ1OSAxMTMuNjc1LDc2LjQ1OSIgaWQ9IkZpbGwtMjQiIGZpbGw9IiM0NTVBNjQiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTUzLjMxNiwyMS4yNzkgQzE1MC45MDMsMjEuMjc5IDE0OC40OTUsMjAuNzUxIDE0Ni42NjQsMTkuNjkzIEMxNDQuODQ2LDE4LjY0NCAxNDMuODQ0LDE3LjIzMiAxNDMuODQ0LDE1LjcxOCBDMTQzLjg0NCwxNC4xOTEgMTQ0Ljg2LDEyLjc2MyAxNDYuNzA1LDExLjY5OCBMMTU2LjE5OCw2LjA5MSBDMTU2LjMwOSw2LjAyNSAxNTYuNDUyLDYuMDYyIDE1Ni41MTgsNi4xNzMgQzE1Ni41ODMsNi4yODQgMTU2LjU0Nyw2LjQyNyAxNTYuNDM2LDYuNDkzIEwxNDYuOTQsMTIuMTAyIEMxNDUuMjQ0LDEzLjA4MSAxNDQuMzEyLDE0LjM2NSAxNDQuMzEyLDE1LjcxOCBDMTQ0LjMxMiwxNy4wNTggMTQ1LjIzLDE4LjMyNiAxNDYuODk3LDE5LjI4OSBDMTUwLjQ0NiwyMS4zMzggMTU2LjI0LDIxLjMyNyAxNTkuODExLDE5LjI2NSBMMTY5LjU1OSwxMy42MzcgQzE2OS42NywxMy41NzMgMTY5LjgxMywxMy42MTEgMTY5Ljg3OCwxMy43MjMgQzE2OS45NDMsMTMuODM0IDE2OS45MDQsMTMuOTc3IDE2OS43OTMsMTQuMDQyIEwxNjAuMDQ1LDE5LjY3IEMxNTguMTg3LDIwLjc0MiAxNTUuNzQ5LDIxLjI3OSAxNTMuMzE2LDIxLjI3OSIgaWQ9IkZpbGwtMjUiIGZpbGw9IiM2MDdEOEIiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTEzLjY3NSw3NS45OTIgTDY3Ljc2Miw0OS40ODQiIGlkPSJGaWxsLTI2IiBmaWxsPSIjNDU1QTY0Ij48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTExMy42NzUsNzYuMzQyIEMxMTMuNjE1LDc2LjM0MiAxMTMuNTU1LDc2LjMyNyAxMTMuNSw3Ni4yOTUgTDY3LjU4Nyw0OS43ODcgQzY3LjQxOSw0OS42OSA2Ny4zNjIsNDkuNDc2IDY3LjQ1OSw0OS4zMDkgQzY3LjU1Niw0OS4xNDEgNjcuNzcsNDkuMDgzIDY3LjkzNyw0OS4xOCBMMTEzLjg1LDc1LjY4OCBDMTE0LjAxOCw3NS43ODUgMTE0LjA3NSw3NiAxMTMuOTc4LDc2LjE2NyBDMTEzLjkxNCw3Ni4yNzkgMTEzLjc5Niw3Ni4zNDIgMTEzLjY3NSw3Ni4zNDIiIGlkPSJGaWxsLTI3IiBmaWxsPSIjNDU1QTY0Ij48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTY3Ljc2Miw0OS40ODQgTDY3Ljc2MiwxMDMuNDg1IEM2Ny43NjIsMTA0LjU3NSA2OC41MzIsMTA1LjkwMyA2OS40ODIsMTA2LjQ1MiBMMTExLjk1NSwxMzAuOTczIEMxMTIuOTA1LDEzMS41MjIgMTEzLjY3NSwxMzEuMDgzIDExMy42NzUsMTI5Ljk5MyBMMTEzLjY3NSw3NS45OTIiIGlkPSJGaWxsLTI4IiBmaWxsPSIjRkFGQUZBIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTExMi43MjcsMTMxLjU2MSBDMTEyLjQzLDEzMS41NjEgMTEyLjEwNywxMzEuNDY2IDExMS43OCwxMzEuMjc2IEw2OS4zMDcsMTA2Ljc1NSBDNjguMjQ0LDEwNi4xNDIgNjcuNDEyLDEwNC43MDUgNjcuNDEyLDEwMy40ODUgTDY3LjQxMiw0OS40ODQgQzY3LjQxMiw0OS4yOSA2Ny41NjksNDkuMTM0IDY3Ljc2Miw0OS4xMzQgQzY3Ljk1Niw0OS4xMzQgNjguMTEzLDQ5LjI5IDY4LjExMyw0OS40ODQgTDY4LjExMywxMDMuNDg1IEM2OC4xMTMsMTA0LjQ0NSA2OC44MiwxMDUuNjY1IDY5LjY1NywxMDYuMTQ4IEwxMTIuMTMsMTMwLjY3IEMxMTIuNDc0LDEzMC44NjggMTEyLjc5MSwxMzAuOTEzIDExMywxMzAuNzkyIEMxMTMuMjA2LDEzMC42NzMgMTEzLjMyNSwxMzAuMzgxIDExMy4zMjUsMTI5Ljk5MyBMMTEzLjMyNSw3NS45OTIgQzExMy4zMjUsNzUuNzk4IDExMy40ODIsNzUuNjQxIDExMy42NzUsNzUuNjQxIEMxMTMuODY5LDc1LjY0MSAxMTQuMDI1LDc1Ljc5OCAxMTQuMDI1LDc1Ljk5MiBMMTE0LjAyNSwxMjkuOTkzIEMxMTQuMDI1LDEzMC42NDggMTEzLjc4NiwxMzEuMTQ3IDExMy4zNSwxMzEuMzk5IEMxMTMuMTYyLDEzMS41MDcgMTEyLjk1MiwxMzEuNTYxIDExMi43MjcsMTMxLjU2MSIgaWQ9IkZpbGwtMjkiIGZpbGw9IiM0NTVBNjQiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTEyLjg2LDQwLjUxMiBDMTEyLjg2LDQwLjUxMiAxMTIuODYsNDAuNTEyIDExMi44NTksNDAuNTEyIEMxMTAuNTQxLDQwLjUxMiAxMDguMzYsMzkuOTkgMTA2LjcxNywzOS4wNDEgQzEwNS4wMTIsMzguMDU3IDEwNC4wNzQsMzYuNzI2IDEwNC4wNzQsMzUuMjkyIEMxMDQuMDc0LDMzLjg0NyAxMDUuMDI2LDMyLjUwMSAxMDYuNzU0LDMxLjUwNCBMMTE4Ljc5NSwyNC41NTEgQzEyMC40NjMsMjMuNTg5IDEyMi42NjksMjMuMDU4IDEyNS4wMDcsMjMuMDU4IEMxMjcuMzI1LDIzLjA1OCAxMjkuNTA2LDIzLjU4MSAxMzEuMTUsMjQuNTMgQzEzMi44NTQsMjUuNTE0IDEzMy43OTMsMjYuODQ1IDEzMy43OTMsMjguMjc4IEMxMzMuNzkzLDI5LjcyNCAxMzIuODQxLDMxLjA2OSAxMzEuMTEzLDMyLjA2NyBMMTE5LjA3MSwzOS4wMTkgQzExNy40MDMsMzkuOTgyIDExNS4xOTcsNDAuNTEyIDExMi44Niw0MC41MTIgTDExMi44Niw0MC41MTIgWiBNMTI1LjAwNywyMy43NTkgQzEyMi43OSwyMy43NTkgMTIwLjcwOSwyNC4yNTYgMTE5LjE0NiwyNS4xNTggTDEwNy4xMDQsMzIuMTEgQzEwNS42MDIsMzIuOTc4IDEwNC43NzQsMzQuMTA4IDEwNC43NzQsMzUuMjkyIEMxMDQuNzc0LDM2LjQ2NSAxMDUuNTg5LDM3LjU4MSAxMDcuMDY3LDM4LjQzNCBDMTA4LjYwNSwzOS4zMjMgMTEwLjY2MywzOS44MTIgMTEyLjg1OSwzOS44MTIgTDExMi44NiwzOS44MTIgQzExNS4wNzYsMzkuODEyIDExNy4xNTgsMzkuMzE1IDExOC43MjEsMzguNDEzIEwxMzAuNzYyLDMxLjQ2IEMxMzIuMjY0LDMwLjU5MyAxMzMuMDkyLDI5LjQ2MyAxMzMuMDkyLDI4LjI3OCBDMTMzLjA5MiwyNy4xMDYgMTMyLjI3OCwyNS45OSAxMzAuOCwyNS4xMzYgQzEyOS4yNjEsMjQuMjQ4IDEyNy4yMDQsMjMuNzU5IDEyNS4wMDcsMjMuNzU5IEwxMjUuMDA3LDIzLjc1OSBaIiBpZD0iRmlsbC0zMCIgZmlsbD0iIzYwN0Q4QiI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0xNjUuNjMsMTYuMjE5IEwxNTkuODk2LDE5LjUzIEMxNTYuNzI5LDIxLjM1OCAxNTEuNjEsMjEuMzY3IDE0OC40NjMsMTkuNTUgQzE0NS4zMTYsMTcuNzMzIDE0NS4zMzIsMTQuNzc4IDE0OC40OTksMTIuOTQ5IEwxNTQuMjMzLDkuNjM5IEwxNjUuNjMsMTYuMjE5IiBpZD0iRmlsbC0zMSIgZmlsbD0iI0ZBRkFGQSI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0xNTQuMjMzLDEwLjQ0OCBMMTY0LjIyOCwxNi4yMTkgTDE1OS41NDYsMTguOTIzIEMxNTguMTEyLDE5Ljc1IDE1Ni4xOTQsMjAuMjA2IDE1NC4xNDcsMjAuMjA2IEMxNTIuMTE4LDIwLjIwNiAxNTAuMjI0LDE5Ljc1NyAxNDguODE0LDE4Ljk0MyBDMTQ3LjUyNCwxOC4xOTkgMTQ2LjgxNCwxNy4yNDkgMTQ2LjgxNCwxNi4yNjkgQzE0Ni44MTQsMTUuMjc4IDE0Ny41MzcsMTQuMzE0IDE0OC44NSwxMy41NTYgTDE1NC4yMzMsMTAuNDQ4IE0xNTQuMjMzLDkuNjM5IEwxNDguNDk5LDEyLjk0OSBDMTQ1LjMzMiwxNC43NzggMTQ1LjMxNiwxNy43MzMgMTQ4LjQ2MywxOS41NSBDMTUwLjAzMSwyMC40NTUgMTUyLjA4NiwyMC45MDcgMTU0LjE0NywyMC45MDcgQzE1Ni4yMjQsMjAuOTA3IDE1OC4zMDYsMjAuNDQ3IDE1OS44OTYsMTkuNTMgTDE2NS42MywxNi4yMTkgTDE1NC4yMzMsOS42MzkiIGlkPSJGaWxsLTMyIiBmaWxsPSIjNjA3RDhCIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTE0NS40NDUsNzIuNjY3IEwxNDUuNDQ1LDcyLjY2NyBDMTQzLjY3Miw3Mi42NjcgMTQyLjIwNCw3MS44MTcgMTQxLjIwMiw3MC40MjIgQzE0MS4xMzUsNzAuMzMgMTQxLjE0NSw3MC4xNDcgMTQxLjIyNSw3MC4wNjYgQzE0MS4zMDUsNjkuOTg1IDE0MS40MzIsNjkuOTQ2IDE0MS41MjUsNzAuMDExIEMxNDIuMzA2LDcwLjU1OSAxNDMuMjMxLDcwLjgyMyAxNDQuMjc2LDcwLjgyMiBDMTQ1LjU5OCw3MC44MjIgMTQ3LjAzLDcwLjM3NiAxNDguNTMyLDY5LjUwOSBDMTUzLjg0Miw2Ni40NDMgMTU4LjE2Myw1OC45ODcgMTU4LjE2Myw1Mi44OTQgQzE1OC4xNjMsNTAuOTY3IDE1Ny43MjEsNDkuMzMyIDE1Ni44ODQsNDguMTY4IEMxNTYuODE4LDQ4LjA3NiAxNTYuODI4LDQ3Ljk0OCAxNTYuOTA4LDQ3Ljg2NyBDMTU2Ljk4OCw0Ny43ODYgMTU3LjExNCw0Ny43NzQgMTU3LjIwOCw0Ny44NCBDMTU4Ljg3OCw0OS4wMTIgMTU5Ljc5OCw1MS4yMiAxNTkuNzk4LDU0LjA1OSBDMTU5Ljc5OCw2MC4zMDEgMTU1LjM3Myw2OC4wNDYgMTQ5LjkzMyw3MS4xODYgQzE0OC4zNiw3Mi4wOTQgMTQ2Ljg1LDcyLjY2NyAxNDUuNDQ1LDcyLjY2NyBMMTQ1LjQ0NSw3Mi42NjcgWiBNMTQyLjQ3Niw3MSBDMTQzLjI5LDcxLjY1MSAxNDQuMjk2LDcyLjAwMiAxNDUuNDQ1LDcyLjAwMiBDMTQ2Ljc2Nyw3Mi4wMDIgMTQ4LjE5OCw3MS41NSAxNDkuNyw3MC42ODIgQzE1NS4wMSw2Ny42MTcgMTU5LjMzMSw2MC4xNTkgMTU5LjMzMSw1NC4wNjUgQzE1OS4zMzEsNTIuMDg1IDE1OC44NjgsNTAuNDM1IDE1OC4wMDYsNDkuMjcyIEMxNTguNDE3LDUwLjMwNyAxNTguNjMsNTEuNTMyIDE1OC42Myw1Mi44OTIgQzE1OC42Myw1OS4xMzQgMTU0LjIwNSw2Ni43NjcgMTQ4Ljc2NSw2OS45MDcgQzE0Ny4xOTIsNzAuODE2IDE0NS42ODEsNzEuMjgzIDE0NC4yNzYsNzEuMjgzIEMxNDMuNjM0LDcxLjI4MyAxNDMuMDMzLDcxLjE5MiAxNDIuNDc2LDcxIEwxNDIuNDc2LDcxIFoiIGlkPSJGaWxsLTMzIiBmaWxsPSIjNjA3RDhCIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTE0OC42NDgsNjkuNzA0IEMxNTQuMDMyLDY2LjU5NiAxNTguMzk2LDU5LjA2OCAxNTguMzk2LDUyLjg5MSBDMTU4LjM5Niw1MC44MzkgMTU3LjkxMyw0OS4xOTggMTU3LjA3NCw0OC4wMyBDMTU1LjI4OSw0Ni43NzggMTUyLjY5OSw0Ni44MzYgMTQ5LjgxNiw0OC41MDEgQzE0NC40MzMsNTEuNjA5IDE0MC4wNjgsNTkuMTM3IDE0MC4wNjgsNjUuMzE0IEMxNDAuMDY4LDY3LjM2NSAxNDAuNTUyLDY5LjAwNiAxNDEuMzkxLDcwLjE3NCBDMTQzLjE3Niw3MS40MjcgMTQ1Ljc2NSw3MS4zNjkgMTQ4LjY0OCw2OS43MDQiIGlkPSJGaWxsLTM0IiBmaWxsPSIjRkFGQUZBIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTE0NC4yNzYsNzEuMjc2IEwxNDQuMjc2LDcxLjI3NiBDMTQzLjEzMyw3MS4yNzYgMTQyLjExOCw3MC45NjkgMTQxLjI1Nyw3MC4zNjUgQzE0MS4yMzYsNzAuMzUxIDE0MS4yMTcsNzAuMzMyIDE0MS4yMDIsNzAuMzExIEMxNDAuMzA3LDY5LjA2NyAxMzkuODM1LDY3LjMzOSAxMzkuODM1LDY1LjMxNCBDMTM5LjgzNSw1OS4wNzMgMTQ0LjI2LDUxLjQzOSAxNDkuNyw0OC4yOTggQzE1MS4yNzMsNDcuMzkgMTUyLjc4NCw0Ni45MjkgMTU0LjE4OSw0Ni45MjkgQzE1NS4zMzIsNDYuOTI5IDE1Ni4zNDcsNDcuMjM2IDE1Ny4yMDgsNDcuODM5IEMxNTcuMjI5LDQ3Ljg1NCAxNTcuMjQ4LDQ3Ljg3MyAxNTcuMjYzLDQ3Ljg5NCBDMTU4LjE1Nyw0OS4xMzggMTU4LjYzLDUwLjg2NSAxNTguNjMsNTIuODkxIEMxNTguNjMsNTkuMTMyIDE1NC4yMDUsNjYuNzY2IDE0OC43NjUsNjkuOTA3IEMxNDcuMTkyLDcwLjgxNSAxNDUuNjgxLDcxLjI3NiAxNDQuMjc2LDcxLjI3NiBMMTQ0LjI3Niw3MS4yNzYgWiBNMTQxLjU1OCw3MC4xMDQgQzE0Mi4zMzEsNzAuNjM3IDE0My4yNDUsNzEuMDA1IDE0NC4yNzYsNzEuMDA1IEMxNDUuNTk4LDcxLjAwNSAxNDcuMDMsNzAuNDY3IDE0OC41MzIsNjkuNiBDMTUzLjg0Miw2Ni41MzQgMTU4LjE2Myw1OS4wMzMgMTU4LjE2Myw1Mi45MzkgQzE1OC4xNjMsNTEuMDMxIDE1Ny43MjksNDkuMzg1IDE1Ni45MDcsNDguMjIzIEMxNTYuMTMzLDQ3LjY5MSAxNTUuMjE5LDQ3LjQwOSAxNTQuMTg5LDQ3LjQwOSBDMTUyLjg2Nyw0Ny40MDkgMTUxLjQzNSw0Ny44NDIgMTQ5LjkzMyw0OC43MDkgQzE0NC42MjMsNTEuNzc1IDE0MC4zMDIsNTkuMjczIDE0MC4zMDIsNjUuMzY2IEMxNDAuMzAyLDY3LjI3NiAxNDAuNzM2LDY4Ljk0MiAxNDEuNTU4LDcwLjEwNCBMMTQxLjU1OCw3MC4xMDQgWiIgaWQ9IkZpbGwtMzUiIGZpbGw9IiM2MDdEOEIiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTUwLjcyLDY1LjM2MSBMMTUwLjM1Nyw2NS4wNjYgQzE1MS4xNDcsNjQuMDkyIDE1MS44NjksNjMuMDQgMTUyLjUwNSw2MS45MzggQzE1My4zMTMsNjAuNTM5IDE1My45NzgsNTkuMDY3IDE1NC40ODIsNTcuNTYzIEwxNTQuOTI1LDU3LjcxMiBDMTU0LjQxMiw1OS4yNDUgMTUzLjczMyw2MC43NDUgMTUyLjkxLDYyLjE3MiBDMTUyLjI2Miw2My4yOTUgMTUxLjUyNSw2NC4zNjggMTUwLjcyLDY1LjM2MSIgaWQ9IkZpbGwtMzYiIGZpbGw9IiM2MDdEOEIiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTE1LjkxNyw4NC41MTQgTDExNS41NTQsODQuMjIgQzExNi4zNDQsODMuMjQ1IDExNy4wNjYsODIuMTk0IDExNy43MDIsODEuMDkyIEMxMTguNTEsNzkuNjkyIDExOS4xNzUsNzguMjIgMTE5LjY3OCw3Ni43MTcgTDEyMC4xMjEsNzYuODY1IEMxMTkuNjA4LDc4LjM5OCAxMTguOTMsNzkuODk5IDExOC4xMDYsODEuMzI2IEMxMTcuNDU4LDgyLjQ0OCAxMTYuNzIyLDgzLjUyMSAxMTUuOTE3LDg0LjUxNCIgaWQ9IkZpbGwtMzciIGZpbGw9IiM2MDdEOEIiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTE0LDEzMC40NzYgTDExNCwxMzAuMDA4IEwxMTQsNzYuMDUyIEwxMTQsNzUuNTg0IEwxMTQsNzYuMDUyIEwxMTQsMTMwLjAwOCBMMTE0LDEzMC40NzYiIGlkPSJGaWxsLTM4IiBmaWxsPSIjNjA3RDhCIj48L3BhdGg+CiAgICAgICAgICAgICAgICA8L2c+CiAgICAgICAgICAgICAgICA8ZyBpZD0iSW1wb3J0ZWQtTGF5ZXJzLUNvcHkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDYyLjAwMDAwMCwgMC4wMDAwMDApIiBza2V0Y2g6dHlwZT0iTVNTaGFwZUdyb3VwIj4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTkuODIyLDM3LjQ3NCBDMTkuODM5LDM3LjMzOSAxOS43NDcsMzcuMTk0IDE5LjU1NSwzNy4wODIgQzE5LjIyOCwzNi44OTQgMTguNzI5LDM2Ljg3MiAxOC40NDYsMzcuMDM3IEwxMi40MzQsNDAuNTA4IEMxMi4zMDMsNDAuNTg0IDEyLjI0LDQwLjY4NiAxMi4yNDMsNDAuNzkzIEMxMi4yNDUsNDAuOTI1IDEyLjI0NSw0MS4yNTQgMTIuMjQ1LDQxLjM3MSBMMTIuMjQ1LDQxLjQxNCBMMTIuMjM4LDQxLjU0MiBDOC4xNDgsNDMuODg3IDUuNjQ3LDQ1LjMyMSA1LjY0Nyw0NS4zMjEgQzUuNjQ2LDQ1LjMyMSAzLjU3LDQ2LjM2NyAyLjg2LDUwLjUxMyBDMi44Niw1MC41MTMgMS45NDgsNTcuNDc0IDEuOTYyLDcwLjI1OCBDMS45NzcsODIuODI4IDIuNTY4LDg3LjMyOCAzLjEyOSw5MS42MDkgQzMuMzQ5LDkzLjI5MyA2LjEzLDkzLjczNCA2LjEzLDkzLjczNCBDNi40NjEsOTMuNzc0IDYuODI4LDkzLjcwNyA3LjIxLDkzLjQ4NiBMODIuNDgzLDQ5LjkzNSBDODQuMjkxLDQ4Ljg2NiA4NS4xNSw0Ni4yMTYgODUuNTM5LDQzLjY1MSBDODYuNzUyLDM1LjY2MSA4Ny4yMTQsMTAuNjczIDg1LjI2NCwzLjc3MyBDODUuMDY4LDMuMDggODQuNzU0LDIuNjkgODQuMzk2LDIuNDkxIEw4Mi4zMSwxLjcwMSBDODEuNTgzLDEuNzI5IDgwLjg5NCwyLjE2OCA4MC43NzYsMi4yMzYgQzgwLjYzNiwyLjMxNyA0MS44MDcsMjQuNTg1IDIwLjAzMiwzNy4wNzIgTDE5LjgyMiwzNy40NzQiIGlkPSJGaWxsLTEiIGZpbGw9IiNGRkZGRkYiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNODIuMzExLDEuNzAxIEw4NC4zOTYsMi40OTEgQzg0Ljc1NCwyLjY5IDg1LjA2OCwzLjA4IDg1LjI2NCwzLjc3MyBDODcuMjEzLDEwLjY3MyA4Ni43NTEsMzUuNjYgODUuNTM5LDQzLjY1MSBDODUuMTQ5LDQ2LjIxNiA4NC4yOSw0OC44NjYgODIuNDgzLDQ5LjkzNSBMNy4yMSw5My40ODYgQzYuODk3LDkzLjY2NyA2LjU5NSw5My43NDQgNi4zMTQsOTMuNzQ0IEw2LjEzMSw5My43MzMgQzYuMTMxLDkzLjczNCAzLjM0OSw5My4yOTMgMy4xMjgsOTEuNjA5IEMyLjU2OCw4Ny4zMjcgMS45NzcsODIuODI4IDEuOTYzLDcwLjI1OCBDMS45NDgsNTcuNDc0IDIuODYsNTAuNTEzIDIuODYsNTAuNTEzIEMzLjU3LDQ2LjM2NyA1LjY0Nyw0NS4zMjEgNS42NDcsNDUuMzIxIEM1LjY0Nyw0NS4zMjEgOC4xNDgsNDMuODg3IDEyLjIzOCw0MS41NDIgTDEyLjI0NSw0MS40MTQgTDEyLjI0NSw0MS4zNzEgQzEyLjI0NSw0MS4yNTQgMTIuMjQ1LDQwLjkyNSAxMi4yNDMsNDAuNzkzIEMxMi4yNCw0MC42ODYgMTIuMzAyLDQwLjU4MyAxMi40MzQsNDAuNTA4IEwxOC40NDYsMzcuMDM2IEMxOC41NzQsMzYuOTYyIDE4Ljc0NiwzNi45MjYgMTguOTI3LDM2LjkyNiBDMTkuMTQ1LDM2LjkyNiAxOS4zNzYsMzYuOTc5IDE5LjU1NCwzNy4wODIgQzE5Ljc0NywzNy4xOTQgMTkuODM5LDM3LjM0IDE5LjgyMiwzNy40NzQgTDIwLjAzMywzNy4wNzIgQzQxLjgwNiwyNC41ODUgODAuNjM2LDIuMzE4IDgwLjc3NywyLjIzNiBDODAuODk0LDIuMTY4IDgxLjU4MywxLjcyOSA4Mi4zMTEsMS43MDEgTTgyLjMxMSwwLjcwNCBMODIuMjcyLDAuNzA1IEM4MS42NTQsMC43MjggODAuOTg5LDAuOTQ5IDgwLjI5OCwxLjM2MSBMODAuMjc3LDEuMzczIEM4MC4xMjksMS40NTggNTkuNzY4LDEzLjEzNSAxOS43NTgsMzYuMDc5IEMxOS41LDM1Ljk4MSAxOS4yMTQsMzUuOTI5IDE4LjkyNywzNS45MjkgQzE4LjU2MiwzNS45MjkgMTguMjIzLDM2LjAxMyAxNy45NDcsMzYuMTczIEwxMS45MzUsMzkuNjQ0IEMxMS40OTMsMzkuODk5IDExLjIzNiw0MC4zMzQgMTEuMjQ2LDQwLjgxIEwxMS4yNDcsNDAuOTYgTDUuMTY3LDQ0LjQ0NyBDNC43OTQsNDQuNjQ2IDIuNjI1LDQ1Ljk3OCAxLjg3Nyw1MC4zNDUgTDEuODcxLDUwLjM4NCBDMS44NjIsNTAuNDU0IDAuOTUxLDU3LjU1NyAwLjk2NSw3MC4yNTkgQzAuOTc5LDgyLjg3OSAxLjU2OCw4Ny4zNzUgMi4xMzcsOTEuNzI0IEwyLjEzOSw5MS43MzkgQzIuNDQ3LDk0LjA5NCA1LjYxNCw5NC42NjIgNS45NzUsOTQuNzE5IEw2LjAwOSw5NC43MjMgQzYuMTEsOTQuNzM2IDYuMjEzLDk0Ljc0MiA2LjMxNCw5NC43NDIgQzYuNzksOTQuNzQyIDcuMjYsOTQuNjEgNy43MSw5NC4zNSBMODIuOTgzLDUwLjc5OCBDODQuNzk0LDQ5LjcyNyA4NS45ODIsNDcuMzc1IDg2LjUyNSw0My44MDEgQzg3LjcxMSwzNS45ODcgODguMjU5LDEwLjcwNSA4Ni4yMjQsMy41MDIgQzg1Ljk3MSwyLjYwOSA4NS41MiwxLjk3NSA4NC44ODEsMS42MiBMODQuNzQ5LDEuNTU4IEw4Mi42NjQsMC43NjkgQzgyLjU1MSwwLjcyNSA4Mi40MzEsMC43MDQgODIuMzExLDAuNzA0IiBpZD0iRmlsbC0yIiBmaWxsPSIjNDU1QTY0Ij48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTY2LjI2NywxMS41NjUgTDY3Ljc2MiwxMS45OTkgTDExLjQyMyw0NC4zMjUiIGlkPSJGaWxsLTMiIGZpbGw9IiNGRkZGRkYiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTIuMjAyLDkwLjU0NSBDMTIuMDI5LDkwLjU0NSAxMS44NjIsOTAuNDU1IDExLjc2OSw5MC4yOTUgQzExLjYzMiw5MC4wNTcgMTEuNzEzLDg5Ljc1MiAxMS45NTIsODkuNjE0IEwzMC4zODksNzguOTY5IEMzMC42MjgsNzguODMxIDMwLjkzMyw3OC45MTMgMzEuMDcxLDc5LjE1MiBDMzEuMjA4LDc5LjM5IDMxLjEyNyw3OS42OTYgMzAuODg4LDc5LjgzMyBMMTIuNDUxLDkwLjQ3OCBMMTIuMjAyLDkwLjU0NSIgaWQ9IkZpbGwtNCIgZmlsbD0iIzYwN0Q4QiI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0xMy43NjQsNDIuNjU0IEwxMy42NTYsNDIuNTkyIEwxMy43MDIsNDIuNDIxIEwxOC44MzcsMzkuNDU3IEwxOS4wMDcsMzkuNTAyIEwxOC45NjIsMzkuNjczIEwxMy44MjcsNDIuNjM3IEwxMy43NjQsNDIuNjU0IiBpZD0iRmlsbC01IiBmaWxsPSIjNjA3RDhCIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTguNTIsOTAuMzc1IEw4LjUyLDQ2LjQyMSBMOC41ODMsNDYuMzg1IEw3NS44NCw3LjU1NCBMNzUuODQsNTEuNTA4IEw3NS43NzgsNTEuNTQ0IEw4LjUyLDkwLjM3NSBMOC41Miw5MC4zNzUgWiBNOC43Nyw0Ni41NjQgTDguNzcsODkuOTQ0IEw3NS41OTEsNTEuMzY1IEw3NS41OTEsNy45ODUgTDguNzcsNDYuNTY0IEw4Ljc3LDQ2LjU2NCBaIiBpZD0iRmlsbC02IiBmaWxsPSIjNjA3RDhCIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTI0Ljk4Niw4My4xODIgQzI0Ljc1Niw4My4zMzEgMjQuMzc0LDgzLjU2NiAyNC4xMzcsODMuNzA1IEwxMi42MzIsOTAuNDA2IEMxMi4zOTUsOTAuNTQ1IDEyLjQyNiw5MC42NTggMTIuNyw5MC42NTggTDEzLjI2NSw5MC42NTggQzEzLjU0LDkwLjY1OCAxMy45NTgsOTAuNTQ1IDE0LjE5NSw5MC40MDYgTDI1LjcsODMuNzA1IEMyNS45MzcsODMuNTY2IDI2LjEyOCw4My40NTIgMjYuMTI1LDgzLjQ0OSBDMjYuMTIyLDgzLjQ0NyAyNi4xMTksODMuMjIgMjYuMTE5LDgyLjk0NiBDMjYuMTE5LDgyLjY3MiAyNS45MzEsODIuNTY5IDI1LjcwMSw4Mi43MTkgTDI0Ljk4Niw4My4xODIiIGlkPSJGaWxsLTciIGZpbGw9IiM2MDdEOEIiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTMuMjY2LDkwLjc4MiBMMTIuNyw5MC43ODIgQzEyLjUsOTAuNzgyIDEyLjM4NCw5MC43MjYgMTIuMzU0LDkwLjYxNiBDMTIuMzI0LDkwLjUwNiAxMi4zOTcsOTAuMzk5IDEyLjU2OSw5MC4yOTkgTDI0LjA3NCw4My41OTcgQzI0LjMxLDgzLjQ1OSAyNC42ODksODMuMjI2IDI0LjkxOCw4My4wNzggTDI1LjYzMyw4Mi42MTQgQzI1LjcyMyw4Mi41NTUgMjUuODEzLDgyLjUyNSAyNS44OTksODIuNTI1IEMyNi4wNzEsODIuNTI1IDI2LjI0NCw4Mi42NTUgMjYuMjQ0LDgyLjk0NiBDMjYuMjQ0LDgzLjE2IDI2LjI0NSw4My4zMDkgMjYuMjQ3LDgzLjM4MyBMMjYuMjUzLDgzLjM4NyBMMjYuMjQ5LDgzLjQ1NiBDMjYuMjQ2LDgzLjUzMSAyNi4yNDYsODMuNTMxIDI1Ljc2Myw4My44MTIgTDE0LjI1OCw5MC41MTQgQzE0LDkwLjY2NSAxMy41NjQsOTAuNzgyIDEzLjI2Niw5MC43ODIgTDEzLjI2Niw5MC43ODIgWiBNMTIuNjY2LDkwLjUzMiBMMTIuNyw5MC41MzMgTDEzLjI2Niw5MC41MzMgQzEzLjUxOCw5MC41MzMgMTMuOTE1LDkwLjQyNSAxNC4xMzIsOTAuMjk5IEwyNS42MzcsODMuNTk3IEMyNS44MDUsODMuNDk5IDI1LjkzMSw4My40MjQgMjUuOTk4LDgzLjM4MyBDMjUuOTk0LDgzLjI5OSAyNS45OTQsODMuMTY1IDI1Ljk5NCw4Mi45NDYgTDI1Ljg5OSw4Mi43NzUgTDI1Ljc2OCw4Mi44MjQgTDI1LjA1NCw4My4yODcgQzI0LjgyMiw4My40MzcgMjQuNDM4LDgzLjY3MyAyNC4yLDgzLjgxMiBMMTIuNjk1LDkwLjUxNCBMMTIuNjY2LDkwLjUzMiBMMTIuNjY2LDkwLjUzMiBaIiBpZD0iRmlsbC04IiBmaWxsPSIjNjA3RDhCIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTEzLjI2Niw4OS44NzEgTDEyLjcsODkuODcxIEMxMi41LDg5Ljg3MSAxMi4zODQsODkuODE1IDEyLjM1NCw4OS43MDUgQzEyLjMyNCw4OS41OTUgMTIuMzk3LDg5LjQ4OCAxMi41NjksODkuMzg4IEwyNC4wNzQsODIuNjg2IEMyNC4zMzIsODIuNTM1IDI0Ljc2OCw4Mi40MTggMjUuMDY3LDgyLjQxOCBMMjUuNjMyLDgyLjQxOCBDMjUuODMyLDgyLjQxOCAyNS45NDgsODIuNDc0IDI1Ljk3OCw4Mi41ODQgQzI2LjAwOCw4Mi42OTQgMjUuOTM1LDgyLjgwMSAyNS43NjMsODIuOTAxIEwxNC4yNTgsODkuNjAzIEMxNCw4OS43NTQgMTMuNTY0LDg5Ljg3MSAxMy4yNjYsODkuODcxIEwxMy4yNjYsODkuODcxIFogTTEyLjY2Niw4OS42MjEgTDEyLjcsODkuNjIyIEwxMy4yNjYsODkuNjIyIEMxMy41MTgsODkuNjIyIDEzLjkxNSw4OS41MTUgMTQuMTMyLDg5LjM4OCBMMjUuNjM3LDgyLjY4NiBMMjUuNjY3LDgyLjY2OCBMMjUuNjMyLDgyLjY2NyBMMjUuMDY3LDgyLjY2NyBDMjQuODE1LDgyLjY2NyAyNC40MTgsODIuNzc1IDI0LjIsODIuOTAxIEwxMi42OTUsODkuNjAzIEwxMi42NjYsODkuNjIxIEwxMi42NjYsODkuNjIxIFoiIGlkPSJGaWxsLTkiIGZpbGw9IiM2MDdEOEIiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTIuMzcsOTAuODAxIEwxMi4zNyw4OS41NTQgTDEyLjM3LDkwLjgwMSIgaWQ9IkZpbGwtMTAiIGZpbGw9IiM2MDdEOEIiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNNi4xMyw5My45MDEgQzUuMzc5LDkzLjgwOCA0LjgxNiw5My4xNjQgNC42OTEsOTIuNTI1IEMzLjg2LDg4LjI4NyAzLjU0LDgzLjc0MyAzLjUyNiw3MS4xNzMgQzMuNTExLDU4LjM4OSA0LjQyMyw1MS40MjggNC40MjMsNTEuNDI4IEM1LjEzNCw0Ny4yODIgNy4yMSw0Ni4yMzYgNy4yMSw0Ni4yMzYgQzcuMjEsNDYuMjM2IDgxLjY2NywzLjI1IDgyLjA2OSwzLjAxNyBDODIuMjkyLDIuODg4IDg0LjU1NiwxLjQzMyA4NS4yNjQsMy45NCBDODcuMjE0LDEwLjg0IDg2Ljc1MiwzNS44MjcgODUuNTM5LDQzLjgxOCBDODUuMTUsNDYuMzgzIDg0LjI5MSw0OS4wMzMgODIuNDgzLDUwLjEwMSBMNy4yMSw5My42NTMgQzYuODI4LDkzLjg3NCA2LjQ2MSw5My45NDEgNi4xMyw5My45MDEgQzYuMTMsOTMuOTAxIDMuMzQ5LDkzLjQ2IDMuMTI5LDkxLjc3NiBDMi41NjgsODcuNDk1IDEuOTc3LDgyLjk5NSAxLjk2Miw3MC40MjUgQzEuOTQ4LDU3LjY0MSAyLjg2LDUwLjY4IDIuODYsNTAuNjggQzMuNTcsNDYuNTM0IDUuNjQ3LDQ1LjQ4OSA1LjY0Nyw0NS40ODkgQzUuNjQ2LDQ1LjQ4OSA4LjA2NSw0NC4wOTIgMTIuMjQ1LDQxLjY3OSBMMTMuMTE2LDQxLjU2IEwxOS43MTUsMzcuNzMgTDE5Ljc2MSwzNy4yNjkgTDYuMTMsOTMuOTAxIiBpZD0iRmlsbC0xMSIgZmlsbD0iI0ZBRkFGQSI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik02LjMxNyw5NC4xNjEgTDYuMTAyLDk0LjE0OCBMNi4xMDEsOTQuMTQ4IEw1Ljg1Nyw5NC4xMDEgQzUuMTM4LDkzLjk0NSAzLjA4NSw5My4zNjUgMi44ODEsOTEuODA5IEMyLjMxMyw4Ny40NjkgMS43MjcsODIuOTk2IDEuNzEzLDcwLjQyNSBDMS42OTksNTcuNzcxIDIuNjA0LDUwLjcxOCAyLjYxMyw1MC42NDggQzMuMzM4LDQ2LjQxNyA1LjQ0NSw0NS4zMSA1LjUzNSw0NS4yNjYgTDEyLjE2Myw0MS40MzkgTDEzLjAzMyw0MS4zMiBMMTkuNDc5LDM3LjU3OCBMMTkuNTEzLDM3LjI0NCBDMTkuNTI2LDM3LjEwNyAxOS42NDcsMzcuMDA4IDE5Ljc4NiwzNy4wMjEgQzE5LjkyMiwzNy4wMzQgMjAuMDIzLDM3LjE1NiAyMC4wMDksMzcuMjkzIEwxOS45NSwzNy44ODIgTDEzLjE5OCw0MS44MDEgTDEyLjMyOCw0MS45MTkgTDUuNzcyLDQ1LjcwNCBDNS43NDEsNDUuNzIgMy43ODIsNDYuNzcyIDMuMTA2LDUwLjcyMiBDMy4wOTksNTAuNzgyIDIuMTk4LDU3LjgwOCAyLjIxMiw3MC40MjQgQzIuMjI2LDgyLjk2MyAyLjgwOSw4Ny40MiAzLjM3Myw5MS43MjkgQzMuNDY0LDkyLjQyIDQuMDYyLDkyLjg4MyA0LjY4Miw5My4xODEgQzQuNTY2LDkyLjk4NCA0LjQ4Niw5Mi43NzYgNC40NDYsOTIuNTcyIEMzLjY2NSw4OC41ODggMy4yOTEsODQuMzcgMy4yNzYsNzEuMTczIEMzLjI2Miw1OC41MiA0LjE2Nyw1MS40NjYgNC4xNzYsNTEuMzk2IEM0LjkwMSw0Ny4xNjUgNy4wMDgsNDYuMDU5IDcuMDk4LDQ2LjAxNCBDNy4wOTQsNDYuMDE1IDgxLjU0MiwzLjAzNCA4MS45NDQsMi44MDIgTDgxLjk3MiwyLjc4NSBDODIuODc2LDIuMjQ3IDgzLjY5MiwyLjA5NyA4NC4zMzIsMi4zNTIgQzg0Ljg4NywyLjU3MyA4NS4yODEsMy4wODUgODUuNTA0LDMuODcyIEM4Ny41MTgsMTEgODYuOTY0LDM2LjA5MSA4NS43ODUsNDMuODU1IEM4NS4yNzgsNDcuMTk2IDg0LjIxLDQ5LjM3IDgyLjYxLDUwLjMxNyBMNy4zMzUsOTMuODY5IEM2Ljk5OSw5NC4wNjMgNi42NTgsOTQuMTYxIDYuMzE3LDk0LjE2MSBMNi4zMTcsOTQuMTYxIFogTTYuMTcsOTMuNjU0IEM2LjQ2Myw5My42OSA2Ljc3NCw5My42MTcgNy4wODUsOTMuNDM3IEw4Mi4zNTgsNDkuODg2IEM4NC4xODEsNDguODA4IDg0Ljk2LDQ1Ljk3MSA4NS4yOTIsNDMuNzggQzg2LjQ2NiwzNi4wNDkgODcuMDIzLDExLjA4NSA4NS4wMjQsNC4wMDggQzg0Ljg0NiwzLjM3NyA4NC41NTEsMi45NzYgODQuMTQ4LDIuODE2IEM4My42NjQsMi42MjMgODIuOTgyLDIuNzY0IDgyLjIyNywzLjIxMyBMODIuMTkzLDMuMjM0IEM4MS43OTEsMy40NjYgNy4zMzUsNDYuNDUyIDcuMzM1LDQ2LjQ1MiBDNy4zMDQsNDYuNDY5IDUuMzQ2LDQ3LjUyMSA0LjY2OSw1MS40NzEgQzQuNjYyLDUxLjUzIDMuNzYxLDU4LjU1NiAzLjc3NSw3MS4xNzMgQzMuNzksODQuMzI4IDQuMTYxLDg4LjUyNCA0LjkzNiw5Mi40NzYgQzUuMDI2LDkyLjkzNyA1LjQxMiw5My40NTkgNS45NzMsOTMuNjE1IEM2LjA4Nyw5My42NCA2LjE1OCw5My42NTIgNi4xNjksOTMuNjU0IEw2LjE3LDkzLjY1NCBMNi4xNyw5My42NTQgWiIgaWQ9IkZpbGwtMTIiIGZpbGw9IiM0NTVBNjQiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNNy4zMTcsNjguOTgyIEM3LjgwNiw2OC43MDEgOC4yMDIsNjguOTI2IDguMjAyLDY5LjQ4NyBDOC4yMDIsNzAuMDQ3IDcuODA2LDcwLjczIDcuMzE3LDcxLjAxMiBDNi44MjksNzEuMjk0IDYuNDMzLDcxLjA2OSA2LjQzMyw3MC41MDggQzYuNDMzLDY5Ljk0OCA2LjgyOSw2OS4yNjUgNy4zMTcsNjguOTgyIiBpZD0iRmlsbC0xMyIgZmlsbD0iI0ZGRkZGRiI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik02LjkyLDcxLjEzMyBDNi42MzEsNzEuMTMzIDYuNDMzLDcwLjkwNSA2LjQzMyw3MC41MDggQzYuNDMzLDY5Ljk0OCA2LjgyOSw2OS4yNjUgNy4zMTcsNjguOTgyIEM3LjQ2LDY4LjkgNy41OTUsNjguODYxIDcuNzE0LDY4Ljg2MSBDOC4wMDMsNjguODYxIDguMjAyLDY5LjA5IDguMjAyLDY5LjQ4NyBDOC4yMDIsNzAuMDQ3IDcuODA2LDcwLjczIDcuMzE3LDcxLjAxMiBDNy4xNzQsNzEuMDk0IDcuMDM5LDcxLjEzMyA2LjkyLDcxLjEzMyBNNy43MTQsNjguNjc0IEM3LjU1Nyw2OC42NzQgNy4zOTIsNjguNzIzIDcuMjI0LDY4LjgyMSBDNi42NzYsNjkuMTM4IDYuMjQ2LDY5Ljg3OSA2LjI0Niw3MC41MDggQzYuMjQ2LDcwLjk5NCA2LjUxNyw3MS4zMiA2LjkyLDcxLjMyIEM3LjA3OCw3MS4zMiA3LjI0Myw3MS4yNzEgNy40MTEsNzEuMTc0IEM3Ljk1OSw3MC44NTcgOC4zODksNzAuMTE3IDguMzg5LDY5LjQ4NyBDOC4zODksNjkuMDAxIDguMTE3LDY4LjY3NCA3LjcxNCw2OC42NzQiIGlkPSJGaWxsLTE0IiBmaWxsPSIjODA5N0EyIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTYuOTIsNzAuOTQ3IEM2LjY0OSw3MC45NDcgNi42MjEsNzAuNjQgNi42MjEsNzAuNTA4IEM2LjYyMSw3MC4wMTcgNi45ODIsNjkuMzkyIDcuNDExLDY5LjE0NSBDNy41MjEsNjkuMDgyIDcuNjI1LDY5LjA0OSA3LjcxNCw2OS4wNDkgQzcuOTg2LDY5LjA0OSA4LjAxNSw2OS4zNTUgOC4wMTUsNjkuNDg3IEM4LjAxNSw2OS45NzggNy42NTIsNzAuNjAzIDcuMjI0LDcwLjg1MSBDNy4xMTUsNzAuOTE0IDcuMDEsNzAuOTQ3IDYuOTIsNzAuOTQ3IE03LjcxNCw2OC44NjEgQzcuNTk1LDY4Ljg2MSA3LjQ2LDY4LjkgNy4zMTcsNjguOTgyIEM2LjgyOSw2OS4yNjUgNi40MzMsNjkuOTQ4IDYuNDMzLDcwLjUwOCBDNi40MzMsNzAuOTA1IDYuNjMxLDcxLjEzMyA2LjkyLDcxLjEzMyBDNy4wMzksNzEuMTMzIDcuMTc0LDcxLjA5NCA3LjMxNyw3MS4wMTIgQzcuODA2LDcwLjczIDguMjAyLDcwLjA0NyA4LjIwMiw2OS40ODcgQzguMjAyLDY5LjA5IDguMDAzLDY4Ljg2MSA3LjcxNCw2OC44NjEiIGlkPSJGaWxsLTE1IiBmaWxsPSIjODA5N0EyIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTcuNDQ0LDg1LjM1IEM3LjcwOCw4NS4xOTggNy45MjEsODUuMzE5IDcuOTIxLDg1LjYyMiBDNy45MjEsODUuOTI1IDcuNzA4LDg2LjI5MiA3LjQ0NCw4Ni40NDQgQzcuMTgxLDg2LjU5NyA2Ljk2Nyw4Ni40NzUgNi45NjcsODYuMTczIEM2Ljk2Nyw4NS44NzEgNy4xODEsODUuNTAyIDcuNDQ0LDg1LjM1IiBpZD0iRmlsbC0xNiIgZmlsbD0iI0ZGRkZGRiI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik03LjIzLDg2LjUxIEM3LjA3NCw4Ni41MSA2Ljk2Nyw4Ni4zODcgNi45NjcsODYuMTczIEM2Ljk2Nyw4NS44NzEgNy4xODEsODUuNTAyIDcuNDQ0LDg1LjM1IEM3LjUyMSw4NS4zMDUgNy41OTQsODUuMjg0IDcuNjU4LDg1LjI4NCBDNy44MTQsODUuMjg0IDcuOTIxLDg1LjQwOCA3LjkyMSw4NS42MjIgQzcuOTIxLDg1LjkyNSA3LjcwOCw4Ni4yOTIgNy40NDQsODYuNDQ0IEM3LjM2Nyw4Ni40ODkgNy4yOTQsODYuNTEgNy4yMyw4Ni41MSBNNy42NTgsODUuMDk4IEM3LjU1OCw4NS4wOTggNy40NTUsODUuMTI3IDcuMzUxLDg1LjE4OCBDNy4wMzEsODUuMzczIDYuNzgxLDg1LjgwNiA2Ljc4MSw4Ni4xNzMgQzYuNzgxLDg2LjQ4MiA2Ljk2Niw4Ni42OTcgNy4yMyw4Ni42OTcgQzcuMzMsODYuNjk3IDcuNDMzLDg2LjY2NiA3LjUzOCw4Ni42MDcgQzcuODU4LDg2LjQyMiA4LjEwOCw4NS45ODkgOC4xMDgsODUuNjIyIEM4LjEwOCw4NS4zMTMgNy45MjMsODUuMDk4IDcuNjU4LDg1LjA5OCIgaWQ9IkZpbGwtMTciIGZpbGw9IiM4MDk3QTIiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNNy4yMyw4Ni4zMjIgTDcuMTU0LDg2LjE3MyBDNy4xNTQsODUuOTM4IDcuMzMzLDg1LjYyOSA3LjUzOCw4NS41MTIgTDcuNjU4LDg1LjQ3MSBMNy43MzQsODUuNjIyIEM3LjczNCw4NS44NTYgNy41NTUsODYuMTY0IDcuMzUxLDg2LjI4MiBMNy4yMyw4Ni4zMjIgTTcuNjU4LDg1LjI4NCBDNy41OTQsODUuMjg0IDcuNTIxLDg1LjMwNSA3LjQ0NCw4NS4zNSBDNy4xODEsODUuNTAyIDYuOTY3LDg1Ljg3MSA2Ljk2Nyw4Ni4xNzMgQzYuOTY3LDg2LjM4NyA3LjA3NCw4Ni41MSA3LjIzLDg2LjUxIEM3LjI5NCw4Ni41MSA3LjM2Nyw4Ni40ODkgNy40NDQsODYuNDQ0IEM3LjcwOCw4Ni4yOTIgNy45MjEsODUuOTI1IDcuOTIxLDg1LjYyMiBDNy45MjEsODUuNDA4IDcuODE0LDg1LjI4NCA3LjY1OCw4NS4yODQiIGlkPSJGaWxsLTE4IiBmaWxsPSIjODA5N0EyIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTc3LjI3OCw3Ljc2OSBMNzcuMjc4LDUxLjQzNiBMMTAuMjA4LDkwLjE2IEwxMC4yMDgsNDYuNDkzIEw3Ny4yNzgsNy43NjkiIGlkPSJGaWxsLTE5IiBmaWxsPSIjNDU1QTY0Ij48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTEwLjA4Myw5MC4zNzUgTDEwLjA4Myw0Ni40MjEgTDEwLjE0Niw0Ni4zODUgTDc3LjQwMyw3LjU1NCBMNzcuNDAzLDUxLjUwOCBMNzcuMzQxLDUxLjU0NCBMMTAuMDgzLDkwLjM3NSBMMTAuMDgzLDkwLjM3NSBaIE0xMC4zMzMsNDYuNTY0IEwxMC4zMzMsODkuOTQ0IEw3Ny4xNTQsNTEuMzY1IEw3Ny4xNTQsNy45ODUgTDEwLjMzMyw0Ni41NjQgTDEwLjMzMyw0Ni41NjQgWiIgaWQ9IkZpbGwtMjAiIGZpbGw9IiM2MDdEOEIiPjwvcGF0aD4KICAgICAgICAgICAgICAgIDwvZz4KICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0xMjUuNzM3LDg4LjY0NyBMMTE4LjA5OCw5MS45ODEgTDExOC4wOTgsODQgTDEwNi42MzksODguNzEzIEwxMDYuNjM5LDk2Ljk4MiBMOTksMTAwLjMxNSBMMTEyLjM2OSwxMDMuOTYxIEwxMjUuNzM3LDg4LjY0NyIgaWQ9IkltcG9ydGVkLUxheWVycy1Db3B5LTIiIGZpbGw9IiM0NTVBNjQiIHNrZXRjaDp0eXBlPSJNU1NoYXBlR3JvdXAiPjwvcGF0aD4KICAgICAgICAgICAgPC9nPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+'); }; module.exports = RotateInstructions; },{"./util.js":22}],17:[function(_dereq_,module,exports){ /* * Copyright 2015 Google Inc. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var SensorSample = _dereq_('./sensor-sample.js'); var MathUtil = _dereq_('../math-util.js'); var Util = _dereq_('../util.js'); /** * An implementation of a simple complementary filter, which fuses gyroscope and * accelerometer data from the 'devicemotion' event. * * Accelerometer data is very noisy, but stable over the long term. * Gyroscope data is smooth, but tends to drift over the long term. * * This fusion is relatively simple: * 1. Get orientation estimates from accelerometer by applying a low-pass filter * on that data. * 2. Get orientation estimates from gyroscope by integrating over time. * 3. Combine the two estimates, weighing (1) in the long term, but (2) for the * short term. */ function ComplementaryFilter(kFilter) { this.kFilter = kFilter; // Raw sensor measurements. this.currentAccelMeasurement = new SensorSample(); this.currentGyroMeasurement = new SensorSample(); this.previousGyroMeasurement = new SensorSample(); // Set default look direction to be in the correct direction. if (Util.isIOS()) { this.filterQ = new MathUtil.Quaternion(-1, 0, 0, 1); } else { this.filterQ = new MathUtil.Quaternion(1, 0, 0, 1); } this.previousFilterQ = new MathUtil.Quaternion(); this.previousFilterQ.copy(this.filterQ); // Orientation based on the accelerometer. this.accelQ = new MathUtil.Quaternion(); // Whether or not the orientation has been initialized. this.isOrientationInitialized = false; // Running estimate of gravity based on the current orientation. this.estimatedGravity = new MathUtil.Vector3(); // Measured gravity based on accelerometer. this.measuredGravity = new MathUtil.Vector3(); // Debug only quaternion of gyro-based orientation. this.gyroIntegralQ = new MathUtil.Quaternion(); } ComplementaryFilter.prototype.addAccelMeasurement = function(vector, timestampS) { this.currentAccelMeasurement.set(vector, timestampS); }; ComplementaryFilter.prototype.addGyroMeasurement = function(vector, timestampS) { this.currentGyroMeasurement.set(vector, timestampS); var deltaT = timestampS - this.previousGyroMeasurement.timestampS; if (Util.isTimestampDeltaValid(deltaT)) { this.run_(); } this.previousGyroMeasurement.copy(this.currentGyroMeasurement); }; ComplementaryFilter.prototype.run_ = function() { if (!this.isOrientationInitialized) { this.accelQ = this.accelToQuaternion_(this.currentAccelMeasurement.sample); this.previousFilterQ.copy(this.accelQ); this.isOrientationInitialized = true; return; } var deltaT = this.currentGyroMeasurement.timestampS - this.previousGyroMeasurement.timestampS; // Convert gyro rotation vector to a quaternion delta. var gyroDeltaQ = this.gyroToQuaternionDelta_(this.currentGyroMeasurement.sample, deltaT); this.gyroIntegralQ.multiply(gyroDeltaQ); // filter_1 = K * (filter_0 + gyro * dT) + (1 - K) * accel. this.filterQ.copy(this.previousFilterQ); this.filterQ.multiply(gyroDeltaQ); // Calculate the delta between the current estimated gravity and the real // gravity vector from accelerometer. var invFilterQ = new MathUtil.Quaternion(); invFilterQ.copy(this.filterQ); invFilterQ.inverse(); this.estimatedGravity.set(0, 0, -1); this.estimatedGravity.applyQuaternion(invFilterQ); this.estimatedGravity.normalize(); this.measuredGravity.copy(this.currentAccelMeasurement.sample); this.measuredGravity.normalize(); // Compare estimated gravity with measured gravity, get the delta quaternion // between the two. var deltaQ = new MathUtil.Quaternion(); deltaQ.setFromUnitVectors(this.estimatedGravity, this.measuredGravity); deltaQ.inverse(); if (Util.isDebug()) { console.log('Delta: %d deg, G_est: (%s, %s, %s), G_meas: (%s, %s, %s)', MathUtil.radToDeg * Util.getQuaternionAngle(deltaQ), (this.estimatedGravity.x).toFixed(1), (this.estimatedGravity.y).toFixed(1), (this.estimatedGravity.z).toFixed(1), (this.measuredGravity.x).toFixed(1), (this.measuredGravity.y).toFixed(1), (this.measuredGravity.z).toFixed(1)); } // Calculate the SLERP target: current orientation plus the measured-estimated // quaternion delta. var targetQ = new MathUtil.Quaternion(); targetQ.copy(this.filterQ); targetQ.multiply(deltaQ); // SLERP factor: 0 is pure gyro, 1 is pure accel. this.filterQ.slerp(targetQ, 1 - this.kFilter); this.previousFilterQ.copy(this.filterQ); }; ComplementaryFilter.prototype.getOrientation = function() { return this.filterQ; }; ComplementaryFilter.prototype.accelToQuaternion_ = function(accel) { var normAccel = new MathUtil.Vector3(); normAccel.copy(accel); normAccel.normalize(); var quat = new MathUtil.Quaternion(); quat.setFromUnitVectors(new MathUtil.Vector3(0, 0, -1), normAccel); quat.inverse(); return quat; }; ComplementaryFilter.prototype.gyroToQuaternionDelta_ = function(gyro, dt) { // Extract axis and angle from the gyroscope data. var quat = new MathUtil.Quaternion(); var axis = new MathUtil.Vector3(); axis.copy(gyro); axis.normalize(); quat.setFromAxisAngle(axis, gyro.length() * dt); return quat; }; module.exports = ComplementaryFilter; },{"../math-util.js":14,"../util.js":22,"./sensor-sample.js":20}],18:[function(_dereq_,module,exports){ /* * Copyright 2015 Google Inc. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var ComplementaryFilter = _dereq_('./complementary-filter.js'); var PosePredictor = _dereq_('./pose-predictor.js'); var TouchPanner = _dereq_('../touch-panner.js'); var MathUtil = _dereq_('../math-util.js'); var Util = _dereq_('../util.js'); /** * The pose sensor, implemented using DeviceMotion APIs. */ function FusionPoseSensor() { this.deviceId = 'webvr-polyfill:fused'; this.deviceName = 'VR Position Device (webvr-polyfill:fused)'; this.accelerometer = new MathUtil.Vector3(); this.gyroscope = new MathUtil.Vector3(); this.start(); this.filter = new ComplementaryFilter(WebVRConfig.K_FILTER); this.posePredictor = new PosePredictor(WebVRConfig.PREDICTION_TIME_S); this.touchPanner = new TouchPanner(); this.filterToWorldQ = new MathUtil.Quaternion(); // Set the filter to world transform, depending on OS. if (Util.isIOS()) { this.filterToWorldQ.setFromAxisAngle(new MathUtil.Vector3(1, 0, 0), Math.PI / 2); } else { this.filterToWorldQ.setFromAxisAngle(new MathUtil.Vector3(1, 0, 0), -Math.PI / 2); } this.inverseWorldToScreenQ = new MathUtil.Quaternion(); this.worldToScreenQ = new MathUtil.Quaternion(); this.originalPoseAdjustQ = new MathUtil.Quaternion(); this.originalPoseAdjustQ.setFromAxisAngle(new MathUtil.Vector3(0, 0, 1), -window.orientation * Math.PI / 180); this.setScreenTransform_(); // Adjust this filter for being in landscape mode. if (Util.isLandscapeMode()) { this.filterToWorldQ.multiply(this.inverseWorldToScreenQ); } // Keep track of a reset transform for resetSensor. this.resetQ = new MathUtil.Quaternion(); this.isFirefoxAndroid = Util.isFirefoxAndroid(); this.isIOS = Util.isIOS(); this.orientationOut_ = new Float32Array(4); } FusionPoseSensor.prototype.getPosition = function() { // This PoseSensor doesn't support position return null; }; FusionPoseSensor.prototype.getOrientation = function() { // Convert from filter space to the the same system used by the // deviceorientation event. var orientation = this.filter.getOrientation(); // Predict orientation. this.predictedQ = this.posePredictor.getPrediction(orientation, this.gyroscope, this.previousTimestampS); // Convert to THREE coordinate system: -Z forward, Y up, X right. var out = new MathUtil.Quaternion(); out.copy(this.filterToWorldQ); out.multiply(this.resetQ); if (!WebVRConfig.TOUCH_PANNER_DISABLED) { out.multiply(this.touchPanner.getOrientation()); } out.multiply(this.predictedQ); out.multiply(this.worldToScreenQ); // Handle the yaw-only case. if (WebVRConfig.YAW_ONLY) { // Make a quaternion that only turns around the Y-axis. out.x = 0; out.z = 0; out.normalize(); } this.orientationOut_[0] = out.x; this.orientationOut_[1] = out.y; this.orientationOut_[2] = out.z; this.orientationOut_[3] = out.w; return this.orientationOut_; }; FusionPoseSensor.prototype.resetPose = function() { // Reduce to inverted yaw-only. this.resetQ.copy(this.filter.getOrientation()); this.resetQ.x = 0; this.resetQ.y = 0; this.resetQ.z *= -1; this.resetQ.normalize(); // Take into account extra transformations in landscape mode. if (Util.isLandscapeMode()) { this.resetQ.multiply(this.inverseWorldToScreenQ); } // Take into account original pose. this.resetQ.multiply(this.originalPoseAdjustQ); if (!WebVRConfig.TOUCH_PANNER_DISABLED) { this.touchPanner.resetSensor(); } }; FusionPoseSensor.prototype.onDeviceMotion_ = function(deviceMotion) { this.updateDeviceMotion_(deviceMotion); }; FusionPoseSensor.prototype.updateDeviceMotion_ = function(deviceMotion) { var accGravity = deviceMotion.accelerationIncludingGravity; var rotRate = deviceMotion.rotationRate; var timestampS = deviceMotion.timeStamp / 1000; // Firefox Android timeStamp returns one thousandth of a millisecond. if (this.isFirefoxAndroid) { timestampS /= 1000; } var deltaS = timestampS - this.previousTimestampS; if (deltaS <= Util.MIN_TIMESTEP || deltaS > Util.MAX_TIMESTEP) { console.warn('Invalid timestamps detected. Time step between successive ' + 'gyroscope sensor samples is very small or not monotonic'); this.previousTimestampS = timestampS; return; } this.accelerometer.set(-accGravity.x, -accGravity.y, -accGravity.z); this.gyroscope.set(rotRate.alpha, rotRate.beta, rotRate.gamma); // With iOS and Firefox Android, rotationRate is reported in degrees, // so we first convert to radians. if (this.isIOS || this.isFirefoxAndroid) { this.gyroscope.multiplyScalar(Math.PI / 180); } this.filter.addAccelMeasurement(this.accelerometer, timestampS); this.filter.addGyroMeasurement(this.gyroscope, timestampS); this.previousTimestampS = timestampS; }; FusionPoseSensor.prototype.onOrientationChange_ = function(screenOrientation) { this.setScreenTransform_(); }; /** * This is only needed if we are in an cross origin iframe on iOS to work around * this issue: https://bugs.webkit.org/show_bug.cgi?id=152299. */ FusionPoseSensor.prototype.onMessage_ = function(event) { var message = event.data; // If there's no message type, ignore it. if (!message || !message.type) { return; } // Ignore all messages that aren't devicemotion. var type = message.type.toLowerCase(); if (type !== 'devicemotion') { return; } // Update device motion. this.updateDeviceMotion_(message.deviceMotionEvent); }; FusionPoseSensor.prototype.setScreenTransform_ = function() { this.worldToScreenQ.set(0, 0, 0, 1); switch (window.orientation) { case 0: break; case 90: this.worldToScreenQ.setFromAxisAngle(new MathUtil.Vector3(0, 0, 1), -Math.PI / 2); break; case -90: this.worldToScreenQ.setFromAxisAngle(new MathUtil.Vector3(0, 0, 1), Math.PI / 2); break; case 180: // TODO. break; } this.inverseWorldToScreenQ.copy(this.worldToScreenQ); this.inverseWorldToScreenQ.inverse(); }; FusionPoseSensor.prototype.start = function() { this.onDeviceMotionCallback_ = this.onDeviceMotion_.bind(this); this.onOrientationChangeCallback_ = this.onOrientationChange_.bind(this); this.onMessageCallback_ = this.onMessage_.bind(this); // Only listen for postMessages if we're in an iOS. Note: there's no reliable // way to know if we're in a cross-domain iframe: https://goo.gl/K6hlE. if (Util.isIOS() && Util.isInsideCrossDomainIFrame()) { window.addEventListener('message', this.onMessageCallback_); } window.addEventListener('orientationchange', this.onOrientationChangeCallback_); window.addEventListener('devicemotion', this.onDeviceMotionCallback_); }; FusionPoseSensor.prototype.stop = function() { window.removeEventListener('devicemotion', this.onDeviceMotionCallback_); window.removeEventListener('orientationchange', this.onOrientationChangeCallback_); window.removeEventListener('message', this.onMessageCallback_); }; module.exports = FusionPoseSensor; },{"../math-util.js":14,"../touch-panner.js":21,"../util.js":22,"./complementary-filter.js":17,"./pose-predictor.js":19}],19:[function(_dereq_,module,exports){ /* * Copyright 2015 Google Inc. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var MathUtil = _dereq_('../math-util'); var Util = _dereq_('../util'); /** * Given an orientation and the gyroscope data, predicts the future orientation * of the head. This makes rendering appear faster. * * Also see: http://msl.cs.uiuc.edu/~lavalle/papers/LavYerKatAnt14.pdf * * @param {Number} predictionTimeS time from head movement to the appearance of * the corresponding image. */ function PosePredictor(predictionTimeS) { this.predictionTimeS = predictionTimeS; // The quaternion corresponding to the previous state. this.previousQ = new MathUtil.Quaternion(); // Previous time a prediction occurred. this.previousTimestampS = null; // The delta quaternion that adjusts the current pose. this.deltaQ = new MathUtil.Quaternion(); // The output quaternion. this.outQ = new MathUtil.Quaternion(); } PosePredictor.prototype.getPrediction = function(currentQ, gyro, timestampS) { if (!this.previousTimestampS) { this.previousQ.copy(currentQ); this.previousTimestampS = timestampS; return currentQ; } // Calculate axis and angle based on gyroscope rotation rate data. var axis = new MathUtil.Vector3(); axis.copy(gyro); axis.normalize(); var angularSpeed = gyro.length(); // If we're rotating slowly, don't do prediction. if (angularSpeed < MathUtil.degToRad * 20) { if (Util.isDebug()) { console.log('Moving slowly, at %s deg/s: no prediction', (MathUtil.radToDeg * angularSpeed).toFixed(1)); } this.outQ.copy(currentQ); this.previousQ.copy(currentQ); return this.outQ; } // Get the predicted angle based on the time delta and latency. var deltaT = timestampS - this.previousTimestampS; var predictAngle = angularSpeed * this.predictionTimeS; this.deltaQ.setFromAxisAngle(axis, predictAngle); this.outQ.copy(this.previousQ); this.outQ.multiply(this.deltaQ); this.previousQ.copy(currentQ); this.previousTimestampS = timestampS; return this.outQ; }; module.exports = PosePredictor; },{"../math-util":14,"../util":22}],20:[function(_dereq_,module,exports){ function SensorSample(sample, timestampS) { this.set(sample, timestampS); }; SensorSample.prototype.set = function(sample, timestampS) { this.sample = sample; this.timestampS = timestampS; }; SensorSample.prototype.copy = function(sensorSample) { this.set(sensorSample.sample, sensorSample.timestampS); }; module.exports = SensorSample; },{}],21:[function(_dereq_,module,exports){ /* * Copyright 2015 Google Inc. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var MathUtil = _dereq_('./math-util.js'); var Util = _dereq_('./util.js'); var ROTATE_SPEED = 0.5; /** * Provides a quaternion responsible for pre-panning the scene before further * transformations due to device sensors. */ function TouchPanner() { window.addEventListener('touchstart', this.onTouchStart_.bind(this)); window.addEventListener('touchmove', this.onTouchMove_.bind(this)); window.addEventListener('touchend', this.onTouchEnd_.bind(this)); this.isTouching = false; this.rotateStart = new MathUtil.Vector2(); this.rotateEnd = new MathUtil.Vector2(); this.rotateDelta = new MathUtil.Vector2(); this.theta = 0; this.orientation = new MathUtil.Quaternion(); } TouchPanner.prototype.getOrientation = function() { this.orientation.setFromEulerXYZ(0, 0, this.theta); return this.orientation; }; TouchPanner.prototype.resetSensor = function() { this.theta = 0; }; TouchPanner.prototype.onTouchStart_ = function(e) { // Only respond if there is exactly one touch. if (e.touches.length != 1) { return; } this.rotateStart.set(e.touches[0].pageX, e.touches[0].pageY); this.isTouching = true; }; TouchPanner.prototype.onTouchMove_ = function(e) { if (!this.isTouching) { return; } this.rotateEnd.set(e.touches[0].pageX, e.touches[0].pageY); this.rotateDelta.subVectors(this.rotateEnd, this.rotateStart); this.rotateStart.copy(this.rotateEnd); // On iOS, direction is inverted. if (Util.isIOS()) { this.rotateDelta.x *= -1; } var element = document.body; this.theta += 2 * Math.PI * this.rotateDelta.x / element.clientWidth * ROTATE_SPEED; }; TouchPanner.prototype.onTouchEnd_ = function(e) { this.isTouching = false; }; module.exports = TouchPanner; },{"./math-util.js":14,"./util.js":22}],22:[function(_dereq_,module,exports){ /* * Copyright 2015 Google Inc. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var objectAssign = _dereq_('object-assign'); var Util = window.Util || {}; Util.MIN_TIMESTEP = 0.001; Util.MAX_TIMESTEP = 1; Util.base64 = function(mimeType, base64) { return 'data:' + mimeType + ';base64,' + base64; }; Util.clamp = function(value, min, max) { return Math.min(Math.max(min, value), max); }; Util.lerp = function(a, b, t) { return a + ((b - a) * t); }; Util.isIOS = (function() { var isIOS = /iPad|iPhone|iPod/.test(navigator.platform); return function() { return isIOS; }; })(); Util.isSafari = (function() { var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent); return function() { return isSafari; }; })(); Util.isFirefoxAndroid = (function() { var isFirefoxAndroid = navigator.userAgent.indexOf('Firefox') !== -1 && navigator.userAgent.indexOf('Android') !== -1; return function() { return isFirefoxAndroid; }; })(); Util.isLandscapeMode = function() { return (window.orientation == 90 || window.orientation == -90); }; // Helper method to validate the time steps of sensor timestamps. Util.isTimestampDeltaValid = function(timestampDeltaS) { if (isNaN(timestampDeltaS)) { return false; } if (timestampDeltaS <= Util.MIN_TIMESTEP) { return false; } if (timestampDeltaS > Util.MAX_TIMESTEP) { return false; } return true; }; Util.getScreenWidth = function() { return Math.max(window.screen.width, window.screen.height) * window.devicePixelRatio; }; Util.getScreenHeight = function() { return Math.min(window.screen.width, window.screen.height) * window.devicePixelRatio; }; Util.requestFullscreen = function(element) { if (element.requestFullscreen) { element.requestFullscreen(); } else if (element.webkitRequestFullscreen) { element.webkitRequestFullscreen(); } else if (element.mozRequestFullScreen) { element.mozRequestFullScreen(); } else if (element.msRequestFullscreen) { element.msRequestFullscreen(); } else { return false; } return true; }; Util.exitFullscreen = function() { if (document.exitFullscreen) { document.exitFullscreen(); } else if (document.webkitExitFullscreen) { document.webkitExitFullscreen(); } else if (document.mozCancelFullScreen) { document.mozCancelFullScreen(); } else if (document.msExitFullscreen) { document.msExitFullscreen(); } else { return false; } return true; }; Util.getFullscreenElement = function() { return document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement; }; Util.linkProgram = function(gl, vertexSource, fragmentSource, attribLocationMap) { // No error checking for brevity. var vertexShader = gl.createShader(gl.VERTEX_SHADER); gl.shaderSource(vertexShader, vertexSource); gl.compileShader(vertexShader); var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); gl.shaderSource(fragmentShader, fragmentSource); gl.compileShader(fragmentShader); var program = gl.createProgram(); gl.attachShader(program, vertexShader); gl.attachShader(program, fragmentShader); for (var attribName in attribLocationMap) gl.bindAttribLocation(program, attribLocationMap[attribName], attribName); gl.linkProgram(program); gl.deleteShader(vertexShader); gl.deleteShader(fragmentShader); return program; }; Util.getProgramUniforms = function(gl, program) { var uniforms = {}; var uniformCount = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); var uniformName = ''; for (var i = 0; i < uniformCount; i++) { var uniformInfo = gl.getActiveUniform(program, i); uniformName = uniformInfo.name.replace('[0]', ''); uniforms[uniformName] = gl.getUniformLocation(program, uniformName); } return uniforms; }; Util.orthoMatrix = function (out, left, right, bottom, top, near, far) { var lr = 1 / (left - right), bt = 1 / (bottom - top), nf = 1 / (near - far); out[0] = -2 * lr; out[1] = 0; out[2] = 0; out[3] = 0; out[4] = 0; out[5] = -2 * bt; out[6] = 0; out[7] = 0; out[8] = 0; out[9] = 0; out[10] = 2 * nf; out[11] = 0; out[12] = (left + right) * lr; out[13] = (top + bottom) * bt; out[14] = (far + near) * nf; out[15] = 1; return out; }; Util.isMobile = function() { var check = false; (function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4)))check = true})(navigator.userAgent||navigator.vendor||window.opera); return check; }; Util.extend = objectAssign; Util.safariCssSizeWorkaround = function(canvas) { // TODO(smus): Remove this workaround when Safari for iOS is fixed. // iOS only workaround (for https://bugs.webkit.org/show_bug.cgi?id=152556). // // "To the last I grapple with thee; // from hell's heart I stab at thee; // for hate's sake I spit my last breath at thee." // -- Moby Dick, by Herman Melville if (Util.isIOS()) { var width = canvas.style.width; var height = canvas.style.height; canvas.style.width = (parseInt(width) + 1) + 'px'; canvas.style.height = (parseInt(height)) + 'px'; setTimeout(function() { canvas.style.width = width; canvas.style.height = height; }, 100); } // Debug only. window.Util = Util; window.canvas = canvas; }; Util.isDebug = function() { return Util.getQueryParameter('debug'); }; Util.getQueryParameter = function(name) { var name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]"); var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"), results = regex.exec(location.search); return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " ")); }; Util.frameDataFromPose = (function() { var piOver180 = Math.PI / 180.0; var rad45 = Math.PI * 0.25; // Borrowed from glMatrix. function mat4_perspectiveFromFieldOfView(out, fov, near, far) { var upTan = Math.tan(fov ? (fov.upDegrees * piOver180) : rad45), downTan = Math.tan(fov ? (fov.downDegrees * piOver180) : rad45), leftTan = Math.tan(fov ? (fov.leftDegrees * piOver180) : rad45), rightTan = Math.tan(fov ? (fov.rightDegrees * piOver180) : rad45), xScale = 2.0 / (leftTan + rightTan), yScale = 2.0 / (upTan + downTan); out[0] = xScale; out[1] = 0.0; out[2] = 0.0; out[3] = 0.0; out[4] = 0.0; out[5] = yScale; out[6] = 0.0; out[7] = 0.0; out[8] = -((leftTan - rightTan) * xScale * 0.5); out[9] = ((upTan - downTan) * yScale * 0.5); out[10] = far / (near - far); out[11] = -1.0; out[12] = 0.0; out[13] = 0.0; out[14] = (far * near) / (near - far); out[15] = 0.0; return out; } function mat4_fromRotationTranslation(out, q, v) { // Quaternion math var x = q[0], y = q[1], z = q[2], w = q[3], x2 = x + x, y2 = y + y, z2 = z + z, xx = x * x2, xy = x * y2, xz = x * z2, yy = y * y2, yz = y * z2, zz = z * z2, wx = w * x2, wy = w * y2, wz = w * z2; out[0] = 1 - (yy + zz); out[1] = xy + wz; out[2] = xz - wy; out[3] = 0; out[4] = xy - wz; out[5] = 1 - (xx + zz); out[6] = yz + wx; out[7] = 0; out[8] = xz + wy; out[9] = yz - wx; out[10] = 1 - (xx + yy); out[11] = 0; out[12] = v[0]; out[13] = v[1]; out[14] = v[2]; out[15] = 1; return out; }; function mat4_translate(out, a, v) { var x = v[0], y = v[1], z = v[2], a00, a01, a02, a03, a10, a11, a12, a13, a20, a21, a22, a23; if (a === out) { out[12] = a[0] * x + a[4] * y + a[8] * z + a[12]; out[13] = a[1] * x + a[5] * y + a[9] * z + a[13]; out[14] = a[2] * x + a[6] * y + a[10] * z + a[14]; out[15] = a[3] * x + a[7] * y + a[11] * z + a[15]; } else { a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3]; a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7]; a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11]; out[0] = a00; out[1] = a01; out[2] = a02; out[3] = a03; out[4] = a10; out[5] = a11; out[6] = a12; out[7] = a13; out[8] = a20; out[9] = a21; out[10] = a22; out[11] = a23; out[12] = a00 * x + a10 * y + a20 * z + a[12]; out[13] = a01 * x + a11 * y + a21 * z + a[13]; out[14] = a02 * x + a12 * y + a22 * z + a[14]; out[15] = a03 * x + a13 * y + a23 * z + a[15]; } return out; }; function mat4_invert(out, a) { var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3], a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7], a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11], a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15], b00 = a00 * a11 - a01 * a10, b01 = a00 * a12 - a02 * a10, b02 = a00 * a13 - a03 * a10, b03 = a01 * a12 - a02 * a11, b04 = a01 * a13 - a03 * a11, b05 = a02 * a13 - a03 * a12, b06 = a20 * a31 - a21 * a30, b07 = a20 * a32 - a22 * a30, b08 = a20 * a33 - a23 * a30, b09 = a21 * a32 - a22 * a31, b10 = a21 * a33 - a23 * a31, b11 = a22 * a33 - a23 * a32, // Calculate the determinant det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06; if (!det) { return null; } det = 1.0 / det; out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det; out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det; out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det; out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det; out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det; out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det; out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det; out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det; out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det; out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det; out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det; out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det; out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det; out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det; out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det; out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det; return out; }; var defaultOrientation = new Float32Array([0, 0, 0, 1]); var defaultPosition = new Float32Array([0, 0, 0]); function updateEyeMatrices(projection, view, pose, parameters, vrDisplay) { mat4_perspectiveFromFieldOfView(projection, parameters ? parameters.fieldOfView : null, vrDisplay.depthNear, vrDisplay.depthFar); var orientation = pose.orientation || defaultOrientation; var position = pose.position || defaultPosition; mat4_fromRotationTranslation(view, orientation, position); if (parameters) mat4_translate(view, view, parameters.offset); mat4_invert(view, view); } return function(frameData, pose, vrDisplay) { if (!frameData || !pose) return false; frameData.pose = pose; frameData.timestamp = pose.timestamp; updateEyeMatrices( frameData.leftProjectionMatrix, frameData.leftViewMatrix, pose, vrDisplay.getEyeParameters("left"), vrDisplay); updateEyeMatrices( frameData.rightProjectionMatrix, frameData.rightViewMatrix, pose, vrDisplay.getEyeParameters("right"), vrDisplay); return true; }; })(); Util.isInsideCrossDomainIFrame = function() { var isFramed = (window.self !== window.top); var refDomain = Util.getDomainFromUrl(document.referrer); var thisDomain = Util.getDomainFromUrl(window.location.href); return isFramed && (refDomain !== thisDomain); }; // From http://stackoverflow.com/a/23945027. Util.getDomainFromUrl = function(url) { var domain; // Find & remove protocol (http, ftp, etc.) and get domain. if (url.indexOf("://") > -1) { domain = url.split('/')[2]; } else { domain = url.split('/')[0]; } //find & remove port number domain = domain.split(':')[0]; return domain; } module.exports = Util; },{"object-assign":2}],23:[function(_dereq_,module,exports){ /* * Copyright 2015 Google Inc. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var DeviceInfo = _dereq_('./device-info.js'); var EventEmitter3 = _dereq_('eventemitter3'); var Util = _dereq_('./util.js'); var DEFAULT_VIEWER = 'CardboardV1'; var VIEWER_KEY = 'WEBVR_CARDBOARD_VIEWER'; var CLASS_NAME = 'webvr-polyfill-viewer-selector'; /** * Creates a viewer selector with the options specified. Supports being shown * and hidden. Generates events when viewer parameters change. Also supports * saving the currently selected index in localStorage. */ function ViewerSelector() { // Try to load the selected key from local storage. If none exists, use the // default key. try { this.selectedKey = localStorage.getItem(VIEWER_KEY) || DEFAULT_VIEWER; } catch (error) { console.error('Failed to load viewer profile: %s', error); } this.dialog = this.createDialog_(DeviceInfo.Viewers); this.root = null; } ViewerSelector.prototype = new EventEmitter3(); ViewerSelector.prototype.show = function(root) { this.root = root; root.appendChild(this.dialog); // Ensure the currently selected item is checked. var selected = this.dialog.querySelector('#' + this.selectedKey); selected.checked = true; // Show the UI. this.dialog.style.display = 'block'; }; ViewerSelector.prototype.hide = function() { if (this.root && this.root.contains(this.dialog)) { this.root.removeChild(this.dialog); } this.dialog.style.display = 'none'; }; ViewerSelector.prototype.getCurrentViewer = function() { return DeviceInfo.Viewers[this.selectedKey]; }; ViewerSelector.prototype.getSelectedKey_ = function() { var input = this.dialog.querySelector('input[name=field]:checked'); if (input) { return input.id; } return null; }; ViewerSelector.prototype.onSave_ = function() { this.selectedKey = this.getSelectedKey_(); if (!this.selectedKey || !DeviceInfo.Viewers[this.selectedKey]) { console.error('ViewerSelector.onSave_: this should never happen!'); return; } this.emit('change', DeviceInfo.Viewers[this.selectedKey]); // Attempt to save the viewer profile, but fails in private mode. try { localStorage.setItem(VIEWER_KEY, this.selectedKey); } catch(error) { console.error('Failed to save viewer profile: %s', error); } this.hide(); }; /** * Creates the dialog. */ ViewerSelector.prototype.createDialog_ = function(options) { var container = document.createElement('div'); container.classList.add(CLASS_NAME); container.style.display = 'none'; // Create an overlay that dims the background, and which goes away when you // tap it. var overlay = document.createElement('div'); var s = overlay.style; s.position = 'fixed'; s.left = 0; s.top = 0; s.width = '100%'; s.height = '100%'; s.background = 'rgba(0, 0, 0, 0.3)'; overlay.addEventListener('click', this.hide.bind(this)); var width = 280; var dialog = document.createElement('div'); var s = dialog.style; s.boxSizing = 'border-box'; s.position = 'fixed'; s.top = '24px'; s.left = '50%'; s.marginLeft = (-width/2) + 'px'; s.width = width + 'px'; s.padding = '24px'; s.overflow = 'hidden'; s.background = '#fafafa'; s.fontFamily = "'Roboto', sans-serif"; s.boxShadow = '0px 5px 20px #666'; dialog.appendChild(this.createH1_('Select your viewer')); for (var id in options) { dialog.appendChild(this.createChoice_(id, options[id].label)); } dialog.appendChild(this.createButton_('Save', this.onSave_.bind(this))); container.appendChild(overlay); container.appendChild(dialog); return container; }; ViewerSelector.prototype.createH1_ = function(name) { var h1 = document.createElement('h1'); var s = h1.style; s.color = 'black'; s.fontSize = '20px'; s.fontWeight = 'bold'; s.marginTop = 0; s.marginBottom = '24px'; h1.innerHTML = name; return h1; }; ViewerSelector.prototype.createChoice_ = function(id, name) { /*

*/ var div = document.createElement('div'); div.style.marginTop = '8px'; div.style.color = 'black'; var input = document.createElement('input'); input.style.fontSize = '30px'; input.setAttribute('id', id); input.setAttribute('type', 'radio'); input.setAttribute('value', id); input.setAttribute('name', 'field'); var label = document.createElement('label'); label.style.marginLeft = '4px'; label.setAttribute('for', id); label.innerHTML = name; div.appendChild(input); div.appendChild(label); return div; }; ViewerSelector.prototype.createButton_ = function(label, onclick) { var button = document.createElement('button'); button.innerHTML = label; var s = button.style; s.float = 'right'; s.textTransform = 'uppercase'; s.color = '#1094f7'; s.fontSize = '14px'; s.letterSpacing = 0; s.border = 0; s.background = 'none'; s.marginTop = '16px'; button.addEventListener('click', onclick); return button; }; module.exports = ViewerSelector; },{"./device-info.js":8,"./util.js":22,"eventemitter3":1}],24:[function(_dereq_,module,exports){ /* * Copyright 2015 Google Inc. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var Util = _dereq_('./util.js'); /** * Android and iOS compatible wakelock implementation. * * Refactored thanks to dkovalev@. */ function AndroidWakeLock() { var video = document.createElement('video'); video.addEventListener('ended', function() { video.play(); }); this.request = function() { if (video.paused) { // Base64 version of videos_src/no-sleep-120s.mp4. video.src = Util.base64('video/mp4', 'AAAAGGZ0eXBpc29tAAAAAG1wNDFhdmMxAAAIA21vb3YAAABsbXZoZAAAAADSa9v60mvb+gABX5AAlw/gAAEAAAEAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAdkdHJhawAAAFx0a2hkAAAAAdJr2/rSa9v6AAAAAQAAAAAAlw/gAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAQAAAAAAQAAAAHAAAAAAAJGVkdHMAAAAcZWxzdAAAAAAAAAABAJcP4AAAAAAAAQAAAAAG3G1kaWEAAAAgbWRoZAAAAADSa9v60mvb+gAPQkAGjneAFccAAAAAAC1oZGxyAAAAAAAAAAB2aWRlAAAAAAAAAAAAAAAAVmlkZW9IYW5kbGVyAAAABodtaW5mAAAAFHZtaGQAAAABAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAAZHc3RibAAAAJdzdHNkAAAAAAAAAAEAAACHYXZjMQAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAMABwASAAAAEgAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABj//wAAADFhdmNDAWQAC//hABlnZAALrNlfllw4QAAAAwBAAAADAKPFCmWAAQAFaOvssiwAAAAYc3R0cwAAAAAAAAABAAAAbgAPQkAAAAAUc3RzcwAAAAAAAAABAAAAAQAAA4BjdHRzAAAAAAAAAG4AAAABAD0JAAAAAAEAehIAAAAAAQA9CQAAAAABAAAAAAAAAAEAD0JAAAAAAQBMS0AAAAABAB6EgAAAAAEAAAAAAAAAAQAPQkAAAAABAExLQAAAAAEAHoSAAAAAAQAAAAAAAAABAA9CQAAAAAEATEtAAAAAAQAehIAAAAABAAAAAAAAAAEAD0JAAAAAAQBMS0AAAAABAB6EgAAAAAEAAAAAAAAAAQAPQkAAAAABAExLQAAAAAEAHoSAAAAAAQAAAAAAAAABAA9CQAAAAAEATEtAAAAAAQAehIAAAAABAAAAAAAAAAEAD0JAAAAAAQBMS0AAAAABAB6EgAAAAAEAAAAAAAAAAQAPQkAAAAABAExLQAAAAAEAHoSAAAAAAQAAAAAAAAABAA9CQAAAAAEATEtAAAAAAQAehIAAAAABAAAAAAAAAAEAD0JAAAAAAQBMS0AAAAABAB6EgAAAAAEAAAAAAAAAAQAPQkAAAAABAExLQAAAAAEAHoSAAAAAAQAAAAAAAAABAA9CQAAAAAEATEtAAAAAAQAehIAAAAABAAAAAAAAAAEAD0JAAAAAAQBMS0AAAAABAB6EgAAAAAEAAAAAAAAAAQAPQkAAAAABAExLQAAAAAEAHoSAAAAAAQAAAAAAAAABAA9CQAAAAAEATEtAAAAAAQAehIAAAAABAAAAAAAAAAEAD0JAAAAAAQBMS0AAAAABAB6EgAAAAAEAAAAAAAAAAQAPQkAAAAABAExLQAAAAAEAHoSAAAAAAQAAAAAAAAABAA9CQAAAAAEATEtAAAAAAQAehIAAAAABAAAAAAAAAAEAD0JAAAAAAQBMS0AAAAABAB6EgAAAAAEAAAAAAAAAAQAPQkAAAAABAExLQAAAAAEAHoSAAAAAAQAAAAAAAAABAA9CQAAAAAEATEtAAAAAAQAehIAAAAABAAAAAAAAAAEAD0JAAAAAAQBMS0AAAAABAB6EgAAAAAEAAAAAAAAAAQAPQkAAAAABAExLQAAAAAEAHoSAAAAAAQAAAAAAAAABAA9CQAAAAAEATEtAAAAAAQAehIAAAAABAAAAAAAAAAEAD0JAAAAAAQBMS0AAAAABAB6EgAAAAAEAAAAAAAAAAQAPQkAAAAABAExLQAAAAAEAHoSAAAAAAQAAAAAAAAABAA9CQAAAAAEALcbAAAAAHHN0c2MAAAAAAAAAAQAAAAEAAABuAAAAAQAAAcxzdHN6AAAAAAAAAAAAAABuAAADCQAAABgAAAAOAAAADgAAAAwAAAASAAAADgAAAAwAAAAMAAAAEgAAAA4AAAAMAAAADAAAABIAAAAOAAAADAAAAAwAAAASAAAADgAAAAwAAAAMAAAAEgAAAA4AAAAMAAAADAAAABIAAAAOAAAADAAAAAwAAAASAAAADgAAAAwAAAAMAAAAEgAAAA4AAAAMAAAADAAAABIAAAAOAAAADAAAAAwAAAASAAAADgAAAAwAAAAMAAAAEgAAAA4AAAAMAAAADAAAABIAAAAOAAAADAAAAAwAAAASAAAADgAAAAwAAAAMAAAAEgAAAA4AAAAMAAAADAAAABIAAAAOAAAADAAAAAwAAAASAAAADgAAAAwAAAAMAAAAEgAAAA4AAAAMAAAADAAAABIAAAAOAAAADAAAAAwAAAASAAAADgAAAAwAAAAMAAAAEgAAAA4AAAAMAAAADAAAABIAAAAOAAAADAAAAAwAAAASAAAADgAAAAwAAAAMAAAAEgAAAA4AAAAMAAAADAAAABIAAAAOAAAADAAAAAwAAAASAAAADgAAAAwAAAAMAAAAEgAAAA4AAAAMAAAADAAAABMAAAAUc3RjbwAAAAAAAAABAAAIKwAAACt1ZHRhAAAAI6llbmMAFwAAdmxjIDIuMi4xIHN0cmVhbSBvdXRwdXQAAAAId2lkZQAACRRtZGF0AAACrgX//6vcRem95tlIt5Ys2CDZI+7veDI2NCAtIGNvcmUgMTQyIC0gSC4yNjQvTVBFRy00IEFWQyBjb2RlYyAtIENvcHlsZWZ0IDIwMDMtMjAxNCAtIGh0dHA6Ly93d3cudmlkZW9sYW4ub3JnL3gyNjQuaHRtbCAtIG9wdGlvbnM6IGNhYmFjPTEgcmVmPTMgZGVibG9jaz0xOjA6MCBhbmFseXNlPTB4MzoweDEzIG1lPWhleCBzdWJtZT03IHBzeT0xIHBzeV9yZD0xLjAwOjAuMDAgbWl4ZWRfcmVmPTEgbWVfcmFuZ2U9MTYgY2hyb21hX21lPTEgdHJlbGxpcz0xIDh4OGRjdD0xIGNxbT0wIGRlYWR6b25lPTIxLDExIGZhc3RfcHNraXA9MSBjaHJvbWFfcXBfb2Zmc2V0PS0yIHRocmVhZHM9MTIgbG9va2FoZWFkX3RocmVhZHM9MSBzbGljZWRfdGhyZWFkcz0wIG5yPTAgZGVjaW1hdGU9MSBpbnRlcmxhY2VkPTAgYmx1cmF5X2NvbXBhdD0wIGNvbnN0cmFpbmVkX2ludHJhPTAgYmZyYW1lcz0zIGJfcHlyYW1pZD0yIGJfYWRhcHQ9MSBiX2JpYXM9MCBkaXJlY3Q9MSB3ZWlnaHRiPTEgb3Blbl9nb3A9MCB3ZWlnaHRwPTIga2V5aW50PTI1MCBrZXlpbnRfbWluPTEgc2NlbmVjdXQ9NDAgaW50cmFfcmVmcmVzaD0wIHJjX2xvb2thaGVhZD00MCByYz1hYnIgbWJ0cmVlPTEgYml0cmF0ZT0xMDAgcmF0ZXRvbD0xLjAgcWNvbXA9MC42MCBxcG1pbj0xMCBxcG1heD01MSBxcHN0ZXA9NCBpcF9yYXRpbz0xLjQwIGFxPTE6MS4wMACAAAAAU2WIhAAQ/8ltlOe+cTZuGkKg+aRtuivcDZ0pBsfsEi9p/i1yU9DxS2lq4dXTinViF1URBKXgnzKBd/Uh1bkhHtMrwrRcOJslD01UB+fyaL6ef+DBAAAAFEGaJGxBD5B+v+a+4QqF3MgBXz9MAAAACkGeQniH/+94r6EAAAAKAZ5hdEN/8QytwAAAAAgBnmNqQ3/EgQAAAA5BmmhJqEFomUwIIf/+4QAAAApBnoZFESw//76BAAAACAGepXRDf8SBAAAACAGep2pDf8SAAAAADkGarEmoQWyZTAgh//7gAAAACkGeykUVLD//voEAAAAIAZ7pdEN/xIAAAAAIAZ7rakN/xIAAAAAOQZrwSahBbJlMCCH//uEAAAAKQZ8ORRUsP/++gQAAAAgBny10Q3/EgQAAAAgBny9qQ3/EgAAAAA5BmzRJqEFsmUwIIf/+4AAAAApBn1JFFSw//76BAAAACAGfcXRDf8SAAAAACAGfc2pDf8SAAAAADkGbeEmoQWyZTAgh//7hAAAACkGflkUVLD//voAAAAAIAZ+1dEN/xIEAAAAIAZ+3akN/xIEAAAAOQZu8SahBbJlMCCH//uAAAAAKQZ/aRRUsP/++gQAAAAgBn/l0Q3/EgAAAAAgBn/tqQ3/EgQAAAA5Bm+BJqEFsmUwIIf/+4QAAAApBnh5FFSw//76AAAAACAGePXRDf8SAAAAACAGeP2pDf8SBAAAADkGaJEmoQWyZTAgh//7gAAAACkGeQkUVLD//voEAAAAIAZ5hdEN/xIAAAAAIAZ5jakN/xIEAAAAOQZpoSahBbJlMCCH//uEAAAAKQZ6GRRUsP/++gQAAAAgBnqV0Q3/EgQAAAAgBnqdqQ3/EgAAAAA5BmqxJqEFsmUwIIf/+4AAAAApBnspFFSw//76BAAAACAGe6XRDf8SAAAAACAGe62pDf8SAAAAADkGa8EmoQWyZTAgh//7hAAAACkGfDkUVLD//voEAAAAIAZ8tdEN/xIEAAAAIAZ8vakN/xIAAAAAOQZs0SahBbJlMCCH//uAAAAAKQZ9SRRUsP/++gQAAAAgBn3F0Q3/EgAAAAAgBn3NqQ3/EgAAAAA5Bm3hJqEFsmUwIIf/+4QAAAApBn5ZFFSw//76AAAAACAGftXRDf8SBAAAACAGft2pDf8SBAAAADkGbvEmoQWyZTAgh//7gAAAACkGf2kUVLD//voEAAAAIAZ/5dEN/xIAAAAAIAZ/7akN/xIEAAAAOQZvgSahBbJlMCCH//uEAAAAKQZ4eRRUsP/++gAAAAAgBnj10Q3/EgAAAAAgBnj9qQ3/EgQAAAA5BmiRJqEFsmUwIIf/+4AAAAApBnkJFFSw//76BAAAACAGeYXRDf8SAAAAACAGeY2pDf8SBAAAADkGaaEmoQWyZTAgh//7hAAAACkGehkUVLD//voEAAAAIAZ6ldEN/xIEAAAAIAZ6nakN/xIAAAAAOQZqsSahBbJlMCCH//uAAAAAKQZ7KRRUsP/++gQAAAAgBnul0Q3/EgAAAAAgBnutqQ3/EgAAAAA5BmvBJqEFsmUwIIf/+4QAAAApBnw5FFSw//76BAAAACAGfLXRDf8SBAAAACAGfL2pDf8SAAAAADkGbNEmoQWyZTAgh//7gAAAACkGfUkUVLD//voEAAAAIAZ9xdEN/xIAAAAAIAZ9zakN/xIAAAAAOQZt4SahBbJlMCCH//uEAAAAKQZ+WRRUsP/++gAAAAAgBn7V0Q3/EgQAAAAgBn7dqQ3/EgQAAAA5Bm7xJqEFsmUwIIf/+4AAAAApBn9pFFSw//76BAAAACAGf+XRDf8SAAAAACAGf+2pDf8SBAAAADkGb4EmoQWyZTAgh//7hAAAACkGeHkUVLD//voAAAAAIAZ49dEN/xIAAAAAIAZ4/akN/xIEAAAAOQZokSahBbJlMCCH//uAAAAAKQZ5CRRUsP/++gQAAAAgBnmF0Q3/EgAAAAAgBnmNqQ3/EgQAAAA5BmmhJqEFsmUwIIf/+4QAAAApBnoZFFSw//76BAAAACAGepXRDf8SBAAAACAGep2pDf8SAAAAADkGarEmoQWyZTAgh//7gAAAACkGeykUVLD//voEAAAAIAZ7pdEN/xIAAAAAIAZ7rakN/xIAAAAAPQZruSahBbJlMFEw3//7B'); video.play(); } }; this.release = function() { video.pause(); video.src = ''; }; } function iOSWakeLock() { var timer = null; this.request = function() { if (!timer) { timer = setInterval(function() { window.location = window.location; setTimeout(window.stop, 0); }, 30000); } } this.release = function() { if (timer) { clearInterval(timer); timer = null; } } } function getWakeLock() { var userAgent = navigator.userAgent || navigator.vendor || window.opera; if (userAgent.match(/iPhone/i) || userAgent.match(/iPod/i)) { return iOSWakeLock; } else { return AndroidWakeLock; } } module.exports = getWakeLock(); },{"./util.js":22}],25:[function(_dereq_,module,exports){ /* * Copyright 2015 Google Inc. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var Util = _dereq_('./util.js'); var CardboardVRDisplay = _dereq_('./cardboard-vr-display.js'); var MouseKeyboardVRDisplay = _dereq_('./mouse-keyboard-vr-display.js'); // Uncomment to add positional tracking via webcam. //var WebcamPositionSensorVRDevice = require('./webcam-position-sensor-vr-device.js'); var VRDisplay = _dereq_('./base.js').VRDisplay; var VRFrameData = _dereq_('./base.js').VRFrameData; var HMDVRDevice = _dereq_('./base.js').HMDVRDevice; var PositionSensorVRDevice = _dereq_('./base.js').PositionSensorVRDevice; var VRDisplayHMDDevice = _dereq_('./display-wrappers.js').VRDisplayHMDDevice; var VRDisplayPositionSensorDevice = _dereq_('./display-wrappers.js').VRDisplayPositionSensorDevice; function WebVRPolyfill() { this.displays = []; this.devices = []; // For deprecated objects this.devicesPopulated = false; this.nativeWebVRAvailable = this.isWebVRAvailable(); this.nativeLegacyWebVRAvailable = this.isDeprecatedWebVRAvailable(); this.nativeGetVRDisplaysFunc = this.nativeWebVRAvailable ? navigator.getVRDisplays : null; if (!this.nativeLegacyWebVRAvailable) { this.enablePolyfill(); if (WebVRConfig.ENABLE_DEPRECATED_API) { this.enableDeprecatedPolyfill(); } } // Put a shim in place to update the API to 1.1 if needed. InstallWebVRSpecShim(); } WebVRPolyfill.prototype.isWebVRAvailable = function() { return ('getVRDisplays' in navigator); }; WebVRPolyfill.prototype.isDeprecatedWebVRAvailable = function() { return ('getVRDevices' in navigator) || ('mozGetVRDevices' in navigator); }; WebVRPolyfill.prototype.populateDevices = function() { if (this.devicesPopulated) { return; } // Initialize our virtual VR devices. var vrDisplay = null; // Add a Cardboard VRDisplay on compatible mobile devices if (this.isCardboardCompatible()) { vrDisplay = new CardboardVRDisplay(); this.displays.push(vrDisplay); // For backwards compatibility if (WebVRConfig.ENABLE_DEPRECATED_API) { this.devices.push(new VRDisplayHMDDevice(vrDisplay)); this.devices.push(new VRDisplayPositionSensorDevice(vrDisplay)); } } // Add a Mouse and Keyboard driven VRDisplay for desktops/laptops if (!this.isMobile() && !WebVRConfig.MOUSE_KEYBOARD_CONTROLS_DISABLED) { vrDisplay = new MouseKeyboardVRDisplay(); this.displays.push(vrDisplay); // For backwards compatibility if (WebVRConfig.ENABLE_DEPRECATED_API) { this.devices.push(new VRDisplayHMDDevice(vrDisplay)); this.devices.push(new VRDisplayPositionSensorDevice(vrDisplay)); } } // Uncomment to add positional tracking via webcam. //if (!this.isMobile() && WebVRConfig.ENABLE_DEPRECATED_API) { // positionDevice = new WebcamPositionSensorVRDevice(); // this.devices.push(positionDevice); //} this.devicesPopulated = true; }; WebVRPolyfill.prototype.enablePolyfill = function() { // Provide navigator.getVRDisplays. navigator.getVRDisplays = this.getVRDisplays.bind(this); // Provide the VRDisplay object. window.VRDisplay = VRDisplay; // Provide navigator.vrEnabled. var self = this; Object.defineProperty(navigator, 'vrEnabled', { get: function () { return self.isCardboardCompatible() && (self.isFullScreenAvailable() || Util.isIOS()); } }); if (!'VRFrameData' in window) { // Provide the VRFrameData object. window.VRFrameData = VRFrameData; } }; WebVRPolyfill.prototype.enableDeprecatedPolyfill = function() { // Provide navigator.getVRDevices. navigator.getVRDevices = this.getVRDevices.bind(this); // Provide the CardboardHMDVRDevice and PositionSensorVRDevice objects. window.HMDVRDevice = HMDVRDevice; window.PositionSensorVRDevice = PositionSensorVRDevice; }; WebVRPolyfill.prototype.getVRDisplays = function() { this.populateDevices(); var polyfillDisplays = this.displays; if (this.nativeWebVRAvailable) { return this.nativeGetVRDisplaysFunc.call(navigator).then(function(nativeDisplays) { if (WebVRConfig.ALWAYS_APPEND_POLYFILL_DISPLAY) { return nativeDisplays.concat(polyfillDisplays); } else { return nativeDisplays.length > 0 ? nativeDisplays : polyfillDisplays; } }); } else { return new Promise(function(resolve, reject) { try { resolve(polyfillDisplays); } catch (e) { reject(e); } }); } }; WebVRPolyfill.prototype.getVRDevices = function() { console.warn('getVRDevices is deprecated. Please update your code to use getVRDisplays instead.'); var self = this; return new Promise(function(resolve, reject) { try { if (!self.devicesPopulated) { if (self.nativeWebVRAvailable) { return navigator.getVRDisplays(function(displays) { for (var i = 0; i < displays.length; ++i) { self.devices.push(new VRDisplayHMDDevice(displays[i])); self.devices.push(new VRDisplayPositionSensorDevice(displays[i])); } self.devicesPopulated = true; resolve(self.devices); }, reject); } if (self.nativeLegacyWebVRAvailable) { return (navigator.getVRDDevices || navigator.mozGetVRDevices)(function(devices) { for (var i = 0; i < devices.length; ++i) { if (devices[i] instanceof HMDVRDevice) { self.devices.push(devices[i]); } if (devices[i] instanceof PositionSensorVRDevice) { self.devices.push(devices[i]); } } self.devicesPopulated = true; resolve(self.devices); }, reject); } } self.populateDevices(); resolve(self.devices); } catch (e) { reject(e); } }); }; /** * Determine if a device is mobile. */ WebVRPolyfill.prototype.isMobile = function() { return /Android/i.test(navigator.userAgent) || /iPhone|iPad|iPod/i.test(navigator.userAgent); }; WebVRPolyfill.prototype.isCardboardCompatible = function() { // For now, support all iOS and Android devices. // Also enable the WebVRConfig.FORCE_VR flag for debugging. return this.isMobile() || WebVRConfig.FORCE_ENABLE_VR; }; WebVRPolyfill.prototype.isFullScreenAvailable = function() { return (document.fullscreenEnabled || document.mozFullScreenEnabled || document.webkitFullscreenEnabled || false); }; // Installs a shim that updates a WebVR 1.0 spec implementation to WebVR 1.1 function InstallWebVRSpecShim() { if ('VRDisplay' in window && !('VRFrameData' in window)) { // Provide the VRFrameData object. window.VRFrameData = VRFrameData; // A lot of Chrome builds don't have depthNear and depthFar, even // though they're in the WebVR 1.0 spec. Patch them in if they're not present. if(!('depthNear' in window.VRDisplay.prototype)) { window.VRDisplay.prototype.depthNear = 0.01; } if(!('depthFar' in window.VRDisplay.prototype)) { window.VRDisplay.prototype.depthFar = 10000.0; } window.VRDisplay.prototype.getFrameData = function(frameData) { return Util.frameDataFromPose(frameData, this.getPose(), this); } } }; module.exports.WebVRPolyfill = WebVRPolyfill; },{"./base.js":3,"./cardboard-vr-display.js":6,"./display-wrappers.js":9,"./mouse-keyboard-vr-display.js":15,"./util.js":22}]},{},[13])(13) }); }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{}],8:[function(require,module,exports){ /* * Copyright 2016 Google Inc. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var EventEmitter = require('eventemitter3'); var shaka = require('shaka-player'); var Types = { HLS: 1, DASH: 2, VIDEO: 3 }; var DEFAULT_BITS_PER_SECOND = 1000000; /** * Supports regular video URLs (eg. mp4), as well as adaptive manifests like * DASH (.mpd) and soon HLS (.m3u8). * * Events: * load(video): When the video is loaded. * error(message): If an error occurs. * * To play/pause/seek/etc, please use the underlying video element. */ function AdaptivePlayer() { this.video = document.createElement('video'); // Loop by default. //this.video.setAttribute('loop', true); // ★ // For FF, make sure we enable preload. this.video.setAttribute('preload', 'auto'); // Enable inline video playback in iOS 10+. this.video.setAttribute('playsinline', true); this.video.setAttribute('crossOrigin', 'anonymous'); this.video.style.position = 'absolute'; this.video.style.top = '-100000px'; uiControlAttachToPlayer(this.video); // ★ document.body.appendChild(this.video); } AdaptivePlayer.prototype = new EventEmitter(); AdaptivePlayer.prototype.load = function(url) { var self = this; // TODO(smus): Investigate whether or not differentiation is best done by // mimeType after all. Cursory research suggests that adaptive streaming // manifest mime types aren't properly supported. // // For now, make determination based on extension. var extension = Util.getExtension(url); switch (extension) { case 'm3u8': // HLS this.type = Types.HLS; if (Util.isSafari()) { this.loadVideo_(url).then(function() { self.emit('load', self.video); }).catch(this.onError_.bind(this)); } else { self.onError_('HLS is only supported on Safari.'); } break; case 'mpd': // MPEG-DASH this.type = Types.DASH; this.loadShakaVideo_(url).then(function() { console.log('The video has now been loaded!'); self.emit('load', self.video); }).catch(this.onError_.bind(this)); break; default: // A regular video, not an adaptive manifest. this.type = Types.VIDEO; this.loadVideo_(url).then(function() { self.emit('load', self.video); }).catch(this.onError_.bind(this)); break; } }; AdaptivePlayer.prototype.destroy = function() { this.video.pause(); this.video.src = ''; this.video = null; }; /*** PRIVATE API ***/ AdaptivePlayer.prototype.onError_ = function(e) { console.error(e); this.emit('error', e); }; AdaptivePlayer.prototype.loadVideo_ = function(url) { var video = this.video; return new Promise(function(resolve, reject) { video.src = url; video.addEventListener('canplaythrough', resolve); video.addEventListener('error', reject); video.load(); }); }; AdaptivePlayer.prototype.initShaka_ = function() { this.player = new shaka.Player(this.video); this.player.configure({ abr: { defaultBandwidthEstimate: DEFAULT_BITS_PER_SECOND } }); // Listen for error events. this.player.addEventListener('error', this.onError_); }; AdaptivePlayer.prototype.loadShakaVideo_ = function(url) { // Install built-in polyfills to patch browser incompatibilities. shaka.polyfill.installAll(); if (!shaka.Player.isBrowserSupported()) { console.error('Shaka is not supported on this browser.'); return; } this.initShaka_(); return this.player.load(url); }; module.exports = AdaptivePlayer; },{"eventemitter3":2,"shaka-player":3}],9:[function(require,module,exports){ /* * Copyright 2016 Google Inc. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var Eyes = { LEFT: 1, RIGHT: 2 }; module.exports = Eyes; },{}],10:[function(require,module,exports){ /* * Copyright 2016 Google Inc. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var EventEmitter = require('eventemitter3'); var TWEEN = require('tween.js'); // Constants for the focus/blur animation. var NORMAL_SCALE = new THREE.Vector3(1, 1, 1); var FOCUS_SCALE = new THREE.Vector3(1.2, 1.2, 1.2); var FOCUS_DURATION = 200; // Constants for the active/inactive animation. var INACTIVE_COLOR = new THREE.Color(1, 1, 1); var ACTIVE_COLOR = new THREE.Color(0.8, 0, 0); var ACTIVE_DURATION = 100; // Constants for opacity. var MAX_INNER_OPACITY = 0.8; var MAX_OUTER_OPACITY = 0.5; var FADE_START_ANGLE_DEG = 35; var FADE_END_ANGLE_DEG = 60; /** * Responsible for rectangular hot spots that the user can interact with. * * Specific duties: * Adding and removing hotspots. * Rendering the hotspots (debug mode only). * Notifying when hotspots are interacted with. * * Emits the following events: * click (id): a hotspot is clicked. * focus (id): a hotspot is focused. * blur (id): a hotspot is no longer hovered over. */ function HotspotRenderer(worldRenderer) { this.worldRenderer = worldRenderer; this.scene = worldRenderer.scene; // Note: this event must be added to document.body and not to window for it to // work inside iOS iframes. var body = document.body; // Bind events for hotspot interaction. if (!Util.isMobile()) { // Only enable mouse events on desktop. body.addEventListener('mousedown', this.onMouseDown_.bind(this), false); body.addEventListener('mousemove', this.onMouseMove_.bind(this), false); body.addEventListener('mouseup', this.onMouseUp_.bind(this), false); } body.addEventListener('touchstart', this.onTouchStart_.bind(this), false); body.addEventListener('touchend', this.onTouchEnd_.bind(this), false); // Add a placeholder for hotspots. this.hotspotRoot = new THREE.Object3D(); // Align the center with the center of the camera too. this.hotspotRoot.rotation.y = Math.PI / 2; this.scene.add(this.hotspotRoot); // All hotspot IDs. this.hotspots = {}; // Currently selected hotspots. this.selectedHotspots = {}; // Hotspots that the last touchstart / mousedown event happened for. this.downHotspots = {}; // For raycasting. Initialize mouse to be off screen initially. this.pointer = new THREE.Vector2(1, 1); this.raycaster = new THREE.Raycaster(); } HotspotRenderer.prototype = new EventEmitter(); /** * @param pitch {Number} The latitude of center, specified in degrees, between * -90 and 90, with 0 at the horizon. * @param yaw {Number} The longitude of center, specified in degrees, between * -180 and 180, with 0 at the image center. * @param radius {Number} The radius of the hotspot, specified in meters. * @param distance {Number} The distance of the hotspot from camera, specified * in meters. * @param hotspotId {String} The ID of the hotspot. */ HotspotRenderer.prototype.add = function(pitch, yaw, radius, distance, id) { // If a hotspot already exists with this ID, stop. if (this.hotspots[id]) { // TODO: Proper error reporting. console.error('Attempt to add hotspot with existing id %s.', id); return; } var hotspot = this.createHotspot_(radius, distance); hotspot.name = id; // Position the hotspot based on the pitch and yaw specified. var quat = new THREE.Quaternion(); quat.setFromEuler(new THREE.Euler(THREE.Math.degToRad(pitch), THREE.Math.degToRad(yaw), 0)); hotspot.position.applyQuaternion(quat); hotspot.lookAt(new THREE.Vector3()); this.hotspotRoot.add(hotspot); this.hotspots[id] = hotspot; } /** * Removes a hotspot based on the ID. * * @param ID {String} Identifier of the hotspot to be removed. */ HotspotRenderer.prototype.remove = function(id) { // If there's no hotspot with this ID, fail. if (!this.hotspots[id]) { // TODO: Proper error reporting. console.error('Attempt to remove non-existing hotspot with id %s.', id); return; } // Remove the mesh from the scene. this.hotspotRoot.remove(this.hotspots[id]); // If this hotspot was selected, make sure it gets unselected. delete this.selectedHotspots[id]; delete this.downHotspots[id]; delete this.hotspots[id]; this.emit('blur', id); }; /** * Clears all hotspots from the pano. Often called when changing panos. */ HotspotRenderer.prototype.clearAll = function() { for (var id in this.hotspots) { this.remove(id); } }; HotspotRenderer.prototype.getCount = function() { var count = 0; for (var id in this.hotspots) { count += 1; } return count; }; HotspotRenderer.prototype.update = function(camera) { if (this.worldRenderer.isVRMode()) { this.pointer.set(0, 0); } // Update the picking ray with the camera and mouse position. this.raycaster.setFromCamera(this.pointer, camera); // Fade hotspots out if they are really far from center to avoid overly // distorted visuals. this.fadeOffCenterHotspots_(camera); var hotspots = this.hotspotRoot.children; // Go through all hotspots to see if they are currently selected. for (var i = 0; i < hotspots.length; i++) { var hotspot = hotspots[i]; //hotspot.lookAt(camera.position); var id = hotspot.name; // Check if hotspot is intersected with the picking ray. var intersects = this.raycaster.intersectObjects(hotspot.children); var isIntersected = (intersects.length > 0); // If newly selected, emit a focus event. if (isIntersected && !this.selectedHotspots[id]) { this.emit('focus', id); this.focus_(id); } // If no longer selected, emit a blur event. if (!isIntersected && this.selectedHotspots[id]) { this.emit('blur', id); this.blur_(id); } // Update the set of selected hotspots. if (isIntersected) { this.selectedHotspots[id] = true; } else { delete this.selectedHotspots[id]; } } }; /** * Toggle whether or not hotspots are visible. */ HotspotRenderer.prototype.setVisibility = function(isVisible) { this.hotspotRoot.visible = isVisible; }; HotspotRenderer.prototype.onTouchStart_ = function(e) { // In VR mode, don't touch the pointer position. if (!this.worldRenderer.isVRMode()) { this.updateTouch_(e); } // Force a camera update to see if any hotspots were selected. this.update(this.worldRenderer.camera); this.downHotspots = {}; for (var id in this.selectedHotspots) { this.downHotspots[id] = true; this.down_(id); } return false; }; HotspotRenderer.prototype.onTouchEnd_ = function(e) { // If no hotspots are pressed, emit an empty click event. if (Util.isEmptyObject(this.downHotspots)) { this.emit('click'); return; } // Only emit a click if the finger was down on the same hotspot before. for (var id in this.downHotspots) { this.emit('click', id); this.up_(id); e.preventDefault(); } }; HotspotRenderer.prototype.updateTouch_ = function(e) { var size = this.getSize_(); var touch = e.touches[0]; this.pointer.x = (touch.clientX / size.width) * 2 - 1; this.pointer.y = - (touch.clientY / size.height) * 2 + 1; }; HotspotRenderer.prototype.onMouseDown_ = function(e) { this.updateMouse_(e); this.downHotspots = {}; for (var id in this.selectedHotspots) { this.downHotspots[id] = true; this.down_(id); } }; HotspotRenderer.prototype.onMouseMove_ = function(e) { this.updateMouse_(e); }; HotspotRenderer.prototype.onMouseUp_ = function(e) { this.updateMouse_(e); // If no hotspots are pressed, emit an empty click event. if (Util.isEmptyObject(this.downHotspots)) { this.emit('click'); return; } // Only emit a click if the mouse was down on the same hotspot before. for (var id in this.selectedHotspots) { if (id in this.downHotspots) { this.emit('click', id); this.up_(id); } } }; HotspotRenderer.prototype.updateMouse_ = function(e) { var size = this.getSize_(); this.pointer.x = (e.clientX / size.width) * 2 - 1; this.pointer.y = - (e.clientY / size.height) * 2 + 1; }; HotspotRenderer.prototype.getSize_ = function() { var canvas = this.worldRenderer.renderer.domElement; return this.worldRenderer.renderer.getSize(); }; HotspotRenderer.prototype.createHotspot_ = function(radius, distance) { var innerGeometry = new THREE.CircleGeometry(radius, 32); var innerMaterial = new THREE.MeshBasicMaterial({ color: 0xffffff, side: THREE.DoubleSide, transparent: true, opacity: MAX_INNER_OPACITY, depthTest: false }); var inner = new THREE.Mesh(innerGeometry, innerMaterial); inner.name = 'inner'; var outerMaterial = new THREE.MeshBasicMaterial({ color: 0xffffff, side: THREE.DoubleSide, transparent: true, opacity: MAX_OUTER_OPACITY, depthTest: false }); var outerGeometry = new THREE.RingGeometry(radius * 0.85, radius, 32); var outer = new THREE.Mesh(outerGeometry, outerMaterial); outer.name = 'outer'; // Position at the extreme end of the sphere. var hotspot = new THREE.Object3D(); hotspot.position.z = -distance; hotspot.scale.set(NORMAL_SCALE); hotspot.add(inner); hotspot.add(outer); return hotspot; }; /** * Large aspect ratios tend to cause visually jarring distortions on the sides. * Here we fade hotspots out to avoid them. */ HotspotRenderer.prototype.fadeOffCenterHotspots_ = function(camera) { var lookAt = new THREE.Vector3(1, 0, 0); lookAt.applyQuaternion(camera.quaternion); // Take into account the camera parent too. lookAt.applyQuaternion(camera.parent.quaternion); // Go through each hotspot. Calculate how far off center it is. for (var id in this.hotspots) { var hotspot = this.hotspots[id]; var angle = hotspot.position.angleTo(lookAt); var angleDeg = THREE.Math.radToDeg(angle); var isVisible = angleDeg < 45; var opacity; if (angleDeg < FADE_START_ANGLE_DEG) { opacity = 1; } else if (angleDeg > FADE_END_ANGLE_DEG) { opacity = 0; } else { // We are in the case START < angle < END. Linearly interpolate. var range = FADE_END_ANGLE_DEG - FADE_START_ANGLE_DEG; var value = FADE_END_ANGLE_DEG - angleDeg; opacity = value / range; } // Opacity a function of angle. If angle is large, opacity is zero. At some // point, ramp opacity down. this.setOpacity_(id, opacity); } }; HotspotRenderer.prototype.focus_ = function(id) { var hotspot = this.hotspots[id]; // Tween scale of hotspot. this.tween = new TWEEN.Tween(hotspot.scale).to(FOCUS_SCALE, FOCUS_DURATION) .easing(TWEEN.Easing.Quadratic.InOut) .start(); }; HotspotRenderer.prototype.blur_ = function(id) { var hotspot = this.hotspots[id]; this.tween = new TWEEN.Tween(hotspot.scale).to(NORMAL_SCALE, FOCUS_DURATION) .easing(TWEEN.Easing.Quadratic.InOut) .start(); }; HotspotRenderer.prototype.down_ = function(id) { // Become active. var hotspot = this.hotspots[id]; var outer = hotspot.getObjectByName('inner'); this.tween = new TWEEN.Tween(outer.material.color).to(ACTIVE_COLOR, ACTIVE_DURATION) .start(); }; HotspotRenderer.prototype.up_ = function(id) { // Become inactive. var hotspot = this.hotspots[id]; var outer = hotspot.getObjectByName('inner'); this.tween = new TWEEN.Tween(outer.material.color).to(INACTIVE_COLOR, ACTIVE_DURATION) .start(); }; HotspotRenderer.prototype.setOpacity_ = function(id, opacity) { var hotspot = this.hotspots[id]; var outer = hotspot.getObjectByName('outer'); var inner = hotspot.getObjectByName('inner'); outer.material.opacity = opacity * MAX_OUTER_OPACITY; inner.material.opacity = opacity * MAX_INNER_OPACITY; }; module.exports = HotspotRenderer; },{"eventemitter3":2,"tween.js":5}],11:[function(require,module,exports){ /* * Copyright 2016 Google Inc. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var EventEmitter = require('eventemitter3'); var Message = require('../message'); var Util = require('../util'); /** * Sits in an embedded iframe, receiving messages from a containing * iFrame. This facilitates an API which provides the following features: * * Playing and pausing content. * Adding hotspots. * Sending messages back to the containing iframe when hotspot is clicked * Sending analytics events to containing iframe. * Receiving DeviceMotion events and resynthesizing them in this iframe * (workaround for https://bugs.webkit.org/show_bug.cgi?id=150072). */ function IFrameMessageReceiver() { window.addEventListener('message', this.onMessage_.bind(this), false); } IFrameMessageReceiver.prototype = new EventEmitter(); IFrameMessageReceiver.prototype.onMessage_ = function(event) { if (Util.isDebug()) { console.log('onMessage_', event); } var message = event.data; var type = message.type.toLowerCase(); var data = message.data; switch (type) { case Message.DEVICE_MOTION: // Synthesize a DeviceMotion event. this.synthesizeDeviceMotionEvent_(message.deviceMotionEvent); break; case Message.SET_CONTENT: case Message.SET_VOLUME: case Message.ADD_HOTSPOT: case Message.PLAY: case Message.PAUSE: // TODO(smus): Emit the event this.emit(type, data); break; default: if (Util.isDebug()) { console.warn('Got unknown message of type %s from %s', message.type, message.origin); } } }; IFrameMessageReceiver.prototype.synthesizeDeviceMotionEvent_ = function(eventData) { var type = 'devicemotion-iframe'; var canBubble = false; var cancelable = false; var dme = document.createEvent('DeviceMotionEvent'); dme.initDeviceMotionEvent(type, canBubble, cancelable, eventData.acceleration, eventData.accelerationIncludingGravity, eventData.rotationRate, eventData.interval); window.dispatchEvent(dme); }; module.exports = IFrameMessageReceiver; },{"../message":19,"../util":20,"eventemitter3":2}],12:[function(require,module,exports){ /* * Copyright 2016 Google Inc. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Shows a 2D loading indicator while various pieces of EmbedVR load. */ function LoadingIndicator() { this.el = this.build_(); document.body.appendChild(this.el); this.show(); } LoadingIndicator.prototype.build_ = function() { var overlay = document.createElement('div'); var s = overlay.style; s.position = 'fixed'; s.top = 0; s.left = 0; s.width = '100%'; s.height = '100%'; s.background = '#eee'; var img = document.createElement('img'); img.src = 'images/loading.gif'; var s = img.style; s.position = 'absolute'; s.top = '50%'; s.left = '50%'; s.transform = 'translate(-50%, -50%)'; overlay.appendChild(img); return overlay; }; LoadingIndicator.prototype.hide = function() { this.el.style.display = 'none'; }; LoadingIndicator.prototype.show = function() { this.el.style.display = 'block'; }; module.exports = LoadingIndicator; },{}],13:[function(require,module,exports){ /* * Copyright 2016 Google Inc. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // Initialize the loading indicator as quickly as possible to give the user // immediate feedback. var LoadingIndicator = require('./loading-indicator'); var loadIndicator = new LoadingIndicator(); var ES6Promise = require('es6-promise'); // Polyfill ES6 promises for IE. ES6Promise.polyfill(); var IFrameMessageReceiver = require('./iframe-message-receiver'); var Message = require('../message'); var SceneInfo = require('./scene-info'); var Stats = require('../../node_modules/stats-js/build/stats.min'); var Util = require('../util'); var WebVRPolyfill = require('webvr-polyfill'); var WorldRenderer = require('./world-renderer'); var receiver = new IFrameMessageReceiver(); receiver.on(Message.PLAY, onPlayRequest); receiver.on(Message.PAUSE, onPauseRequest); receiver.on(Message.ADD_HOTSPOT, onAddHotspot); receiver.on(Message.SET_CONTENT, onSetContent); receiver.on(Message.SET_VOLUME, onSetVolume); window.addEventListener('load', onLoad); var stats = new Stats(); var worldRenderer = new WorldRenderer(); worldRenderer.on('error', onRenderError); worldRenderer.on('load', onRenderLoad); worldRenderer.on('modechange', onModeChange); worldRenderer.hotspotRenderer.on('click', onHotspotClick); window.worldRenderer = worldRenderer; var isReadySent = false; function onLoad() { if (!Util.isWebGLEnabled()) { showError('WebGL not supported.'); return; } // Load the scene. var scene = SceneInfo.loadFromGetParams(); worldRenderer.setScene(scene); if (scene.isDebug) { // Show stats. showStats(); } if (scene.isYawOnly) { WebVRConfig = window.WebVRConfig || {}; WebVRConfig.YAW_ONLY = true; } requestAnimationFrame(loop); } function onVideoTap() { worldRenderer.videoProxy.play(); hidePlayButton(); // Prevent multiple play() calls on the video element. document.body.removeEventListener('touchend', onVideoTap); } function onRenderLoad(event) { if (event.videoElement) { // On mobile, tell the user they need to tap to start. Otherwise, autoplay. if (Util.isMobile()) { // Tell user to tap to start. showPlayButton(); document.body.addEventListener('touchend', onVideoTap); } else { //event.videoElement.play(); // ★ } // Attach to pause and play events, to notify the API. event.videoElement.addEventListener('pause', onPause); event.videoElement.addEventListener('play', onPlay); } // Hide loading indicator. loadIndicator.hide(); // Autopan only on desktop, for photos only, and only if autopan is enabled. if (!Util.isMobile() && !worldRenderer.sceneInfo.video && !worldRenderer.sceneInfo.isAutopanOff) { worldRenderer.autopan(); } // Notify the API that we are ready, but only do this once. if (!isReadySent) { Util.sendParentMessage({ type: 'ready' }); isReadySent = true; } } function onPlayRequest() { if (!worldRenderer.videoProxy) { onApiError('Attempt to pause, but no video found.'); return; } worldRenderer.videoProxy.play(); } function onPauseRequest() { if (!worldRenderer.videoProxy) { onApiError('Attempt to pause, but no video found.'); return; } worldRenderer.videoProxy.pause(); } function onAddHotspot(e) { if (Util.isDebug()) { console.log('onAddHotspot', e); } // TODO: Implement some validation? var pitch = parseFloat(e.pitch); var yaw = parseFloat(e.yaw); var radius = parseFloat(e.radius); var distance = parseFloat(e.distance); var id = e.id; worldRenderer.hotspotRenderer.add(pitch, yaw, radius, distance, id); } function onSetContent(e) { if (Util.isDebug()) { console.log('onSetContent', e); } // Remove all of the hotspots. worldRenderer.hotspotRenderer.clearAll(); // Fade to black. worldRenderer.sphereRenderer.setOpacity(0, 500).then(function() { // Then load the new scene. var scene = SceneInfo.loadFromAPIParams(e.contentInfo); worldRenderer.destroy(); // Update the URL to reflect the new scene. This is important particularily // on iOS where we use a fake fullscreen mode. var url = scene.getCurrentUrl(); //console.log('Updating url to be %s', url); window.history.pushState(null, 'VR View', url); // And set the new scene. return worldRenderer.setScene(scene); }).then(function() { // Then fade the scene back in. worldRenderer.sphereRenderer.setOpacity(1, 500); }); } function onSetVolume(e) { // Only work for video. If there's no video, send back an error. if (!worldRenderer.videoProxy) { onApiError('Attempt to set volume, but no video found.'); return; } worldRenderer.videoProxy.setVolume(e.volumeLevel); } function onApiError(message) { console.error(message); Util.sendParentMessage({ type: 'error', data: {message: message} }); } function onModeChange(mode) { Util.sendParentMessage({ type: 'modechange', data: {mode: mode} }); } function onHotspotClick(id) { Util.sendParentMessage({ type: 'click', data: {id: id} }); } function onPlay() { Util.sendParentMessage({ type: 'paused', data: false }); } function onPause() { Util.sendParentMessage({ type: 'paused', data: true }); } function onSceneError(message) { showError('Loader: ' + message); } function onRenderError(message) { showError('Render: ' + message); } function showError(message, opt_title) { // Hide loading indicator. loadIndicator.hide(); var error = document.querySelector('#error'); error.classList.add('visible'); error.querySelector('.message').innerHTML = message; var title = (opt_title !== undefined ? opt_title : 'Error'); error.querySelector('.title').innerHTML = title; } function hideError() { var error = document.querySelector('#error'); error.classList.remove('visible'); } function showPlayButton() { var playButton = document.querySelector('#play-overlay'); playButton.classList.add('visible'); } function hidePlayButton() { var playButton = document.querySelector('#play-overlay'); playButton.classList.remove('visible'); } function showStats() { stats.setMode(0); // 0: fps, 1: ms // Align bottom-left. stats.domElement.style.position = 'absolute'; stats.domElement.style.left = '0px'; stats.domElement.style.bottom = '0px'; document.body.appendChild(stats.domElement); } function loop(time) { // Use the VRDisplay RAF if it is present. if (worldRenderer.vrDisplay) { worldRenderer.vrDisplay.requestAnimationFrame(loop); } else { requestAnimationFrame(loop); } stats.begin(); // Update the video if needed. if (worldRenderer.videoProxy) { worldRenderer.videoProxy.update(time); } worldRenderer.render(time); worldRenderer.submitFrame(); stats.end(); } },{"../../node_modules/stats-js/build/stats.min":4,"../message":19,"../util":20,"./iframe-message-receiver":11,"./loading-indicator":12,"./scene-info":15,"./world-renderer":18,"es6-promise":1,"webvr-polyfill":7}],14:[function(require,module,exports){ /* * Copyright 2016 Google Inc. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ function ReticleRenderer(camera) { this.camera = camera; this.reticle = this.createReticle_(); // In front of the hotspot itself, which is at r=0.99. this.reticle.position.z = -0.97; camera.add(this.reticle); this.setVisibility(false); } ReticleRenderer.prototype.setVisibility = function(isVisible) { // TODO: Tween the transition. this.reticle.visible = isVisible; }; ReticleRenderer.prototype.createReticle_ = function() { // Make a torus. var geometry = new THREE.TorusGeometry(0.02, 0.005, 10, 20); var material = new THREE.MeshBasicMaterial({color: 0x000000}); var torus = new THREE.Mesh(geometry, material); return torus; }; module.exports = ReticleRenderer; },{}],15:[function(require,module,exports){ /* * Copyright 2016 Google Inc. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var CAMEL_TO_UNDERSCORE = { video: 'video', image: 'image', preview: 'preview', isStereo: 'is_stereo', defaultYaw: 'default_yaw', isYawOnly: 'is_yaw_only', isDebug: 'is_debug', isVROff: 'is_vr_off', isAutopanOff: 'is_autopan_off', }; /** * Contains all information about a given scene. */ function SceneInfo(opt_params) { var params = opt_params || {}; this.image = params.image; this.preview = params.preview; this.video = params.video; this.defaultYaw = THREE.Math.degToRad(params.defaultYaw || 0); this.isStereo = Util.parseBoolean(params.isStereo); this.isYawOnly = Util.parseBoolean(params.isYawOnly); this.isDebug = Util.parseBoolean(params.isDebug); this.isVROff = Util.parseBoolean(params.isVROff); this.isAutopanOff = Util.parseBoolean(params.isAutopanOff); } SceneInfo.loadFromGetParams = function() { var params = {}; for (var camelCase in CAMEL_TO_UNDERSCORE) { var underscore = CAMEL_TO_UNDERSCORE[camelCase]; params[camelCase] = Util.getQueryParameter(underscore); } var scene = new SceneInfo(params); if (!scene.isValid()) { console.warn('Invalid scene: %s', scene.errorMessage); } return scene; }; SceneInfo.loadFromAPIParams = function(underscoreParams) { var params = {}; for (var camelCase in CAMEL_TO_UNDERSCORE) { var underscore = CAMEL_TO_UNDERSCORE[camelCase]; if (underscoreParams[underscore]) { params[camelCase] = underscoreParams[underscore]; } } var scene = new SceneInfo(params); if (!scene.isValid()) { console.warn('Invalid scene: %s', scene.errorMessage); } return scene; }; SceneInfo.prototype.isValid = function() { // Either it's an image or a video. if (!this.image && !this.video) { this.errorMessage = 'Either image or video URL must be specified.'; return false; } if (this.image && this.video) { this.errorMessage = 'Both image and video URL can\'t be specified.'; return false; } if (this.image && !this.isValidImage_(this.image)) { this.errorMessage = 'Invalid image URL: ' + this.image; return false; } this.errorMessage = null; return true; }; /** * Generates a URL to reflect this scene. */ SceneInfo.prototype.getCurrentUrl = function() { var url = location.protocol + '//' + location.host + location.pathname + '?'; for (var camelCase in CAMEL_TO_UNDERSCORE) { var underscore = CAMEL_TO_UNDERSCORE[camelCase]; var value = this[camelCase]; if (value !== undefined) { url += underscore + '=' + value + '&'; } } // Chop off the trailing ampersand. return url.substring(0, url.length - 1); }; SceneInfo.prototype.isValidImage_ = function(imageUrl) { return true; }; module.exports = SceneInfo; },{}],16:[function(require,module,exports){ /* * Copyright 2016 Google Inc. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var Eyes = require('./eyes'); var TWEEN = require('tween.js'); var Util = require('../util'); function SphereRenderer(scene) { this.scene = scene; // Create a transparent mask. this.createOpacityMask_(); } /** * Sets the photosphere based on the image in the source. Supports stereo and * mono photospheres. * * @return {Promise} */ SphereRenderer.prototype.setPhotosphere = function(src, opt_params) { return new Promise(function(resolve, reject) { this.resolve = resolve; this.reject = reject; var params = opt_params || {}; this.isStereo = !!params.isStereo; this.src = src; // Load texture. var loader = new THREE.TextureLoader(); loader.crossOrigin = 'anonymous'; loader.load(src, this.onTextureLoaded_.bind(this), undefined, this.onTextureError_.bind(this)); }.bind(this)); }; /** * @return {Promise} Yeah. */ SphereRenderer.prototype.set360Video = function(videoElement, opt_params) { return new Promise(function(resolve, reject) { this.resolve = resolve; this.reject = reject; var params = opt_params || {}; this.isStereo = !!params.isStereo; // Load the video texture. var videoTexture = new THREE.VideoTexture(videoElement); videoTexture.minFilter = THREE.LinearFilter; videoTexture.magFilter = THREE.LinearFilter; videoTexture.format = THREE.RGBFormat; videoTexture.generateMipmaps = false; videoTexture.needsUpdate = true; this.onTextureLoaded_(videoTexture); }.bind(this)); }; /** * Set the opacity of the panorama. * * @param {Number} opacity How opaque we want the panorama to be. 0 means black, * 1 means full color. * @param {Number} duration Number of milliseconds the transition should take. * * @return {Promise} When the opacity change is complete. */ SphereRenderer.prototype.setOpacity = function(opacity, duration) { var scene = this.scene; // If we want the opacity var overlayOpacity = 1 - opacity; return new Promise(function(resolve, reject) { var mask = scene.getObjectByName('opacityMask'); var tween = new TWEEN.Tween({opacity: mask.material.opacity}) .to({opacity: overlayOpacity}, duration) .easing(TWEEN.Easing.Quadratic.InOut); tween.onUpdate(function(e) { mask.material.opacity = this.opacity; }); tween.onComplete(resolve).start(); }); }; SphereRenderer.prototype.onTextureLoaded_ = function(texture) { var sphereLeft; var sphereRight; if (this.isStereo) { sphereLeft = this.createPhotosphere_(texture, {offsetY: 0.5, scaleY: 0.5}); sphereRight = this.createPhotosphere_(texture, {offsetY: 0, scaleY: 0.5}); } else { sphereLeft = this.createPhotosphere_(texture); sphereRight = this.createPhotosphere_(texture); } // Display in left and right eye respectively. sphereLeft.layers.set(Eyes.LEFT); sphereLeft.eye = Eyes.LEFT; sphereRight.layers.set(Eyes.RIGHT); sphereRight.eye = Eyes.RIGHT; this.scene.getObjectByName('photo').children = [sphereLeft, sphereRight]; this.resolve(); }; SphereRenderer.prototype.onTextureError_ = function(error) { this.reject('Unable to load texture from "' + this.src + '"'); }; SphereRenderer.prototype.createPhotosphere_ = function(texture, opt_params) { var p = opt_params || {}; p.scaleX = p.scaleX || 1; p.scaleY = p.scaleY || 1; p.offsetX = p.offsetX || 0; p.offsetY = p.offsetY || 0; p.phiStart = p.phiStart || 0; p.phiLength = p.phiLength || Math.PI * 2; p.thetaStart = p.thetaStart || 0; p.thetaLength = p.thetaLength || Math.PI; var geometry = new THREE.SphereGeometry(1, 48, 48, p.phiStart, p.phiLength, p.thetaStart, p.thetaLength); geometry.applyMatrix(new THREE.Matrix4().makeScale(-1, 1, 1)); var uvs = geometry.faceVertexUvs[0]; for (var i = 0; i < uvs.length; i ++) { for (var j = 0; j < 3; j ++) { uvs[i][j].x *= p.scaleX; uvs[i][j].x += p.offsetX; uvs[i][j].y *= p.scaleY; uvs[i][j].y += p.offsetY; } } var material = new THREE.MeshBasicMaterial({ map: texture }); var out = new THREE.Mesh(geometry, material); //out.visible = false; out.renderOrder = -1; return out; }; SphereRenderer.prototype.createOpacityMask_ = function() { var geometry = new THREE.SphereGeometry(0.49, 48, 48); var material = new THREE.MeshBasicMaterial({ color: 0x000000, side: THREE.DoubleSide, opacity: 0, transparent: true}); var opacityMask = new THREE.Mesh(geometry, material); opacityMask.name = 'opacityMask'; opacityMask.renderOrder = 1; this.scene.add(opacityMask); return opacityMask; }; module.exports = SphereRenderer; },{"../util":20,"./eyes":9,"tween.js":5}],17:[function(require,module,exports){ /* * Copyright 2016 Google Inc. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var Util = require('../util'); /** * A proxy class for working around the fact that as soon as a video is play()ed * on iOS, Safari auto-fullscreens the video. * * TODO(smus): The entire raison d'etre for this class is to work around this * issue. Once Safari implements some way to suppress this fullscreen player, we * can remove this code. */ function VideoProxy(videoElement) { this.videoElement = videoElement; // True if we're currently manually advancing the playhead (only on iOS). this.isFakePlayback = false; // When the video started playing. this.startTime = null; } VideoProxy.prototype.play = function() { if (Util.isIOS9OrLess()) { this.startTime = performance.now(); this.isFakePlayback = true; // Make an audio element to playback just the audio part. this.audioElement = new Audio(); this.audioElement.src = this.videoElement.src; this.audioElement.play(); } else { this.videoElement.play().then(function(e) { console.log('Playing video.', e); }); } }; VideoProxy.prototype.pause = function() { if (Util.isIOS9OrLess() && this.isFakePlayback) { this.isFakePlayback = true; this.audioElement.pause(); } else { this.videoElement.pause(); } }; VideoProxy.prototype.setVolume = function(volumeLevel) { if (this.videoElement) { // On iOS 10, the VideoElement.volume property is read-only. So we special // case muting and unmuting. if (Util.isIOS()) { this.videoElement.muted = (volumeLevel === 0); } else { this.videoElement.volume = volumeLevel; } } if (this.audioElement) { this.audioElement.volume = volumeLevel; } }; /** * Called on RAF to progress playback. */ VideoProxy.prototype.update = function() { // Fakes playback for iOS only. if (!this.isFakePlayback) { return; } var duration = this.videoElement.duration; var now = performance.now(); var delta = now - this.startTime; var deltaS = delta / 1000; this.videoElement.currentTime = deltaS; // Loop through the video // if (deltaS > duration) { // ★ // this.startTime = now; // this.videoElement.currentTime = 0; // // Also restart the audio. // this.audioElement.currentTime = 0; // } }; module.exports = VideoProxy; },{"../util":20}],18:[function(require,module,exports){ /* * Copyright 2016 Google Inc. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var AdaptivePlayer = require('./adaptive-player'); var EventEmitter = require('eventemitter3'); var Eyes = require('./eyes'); var HotspotRenderer = require('./hotspot-renderer'); var ReticleRenderer = require('./reticle-renderer'); var SphereRenderer = require('./sphere-renderer'); var TWEEN = require('tween.js'); var Util = require('../util'); var VideoProxy = require('./video-proxy'); var WebVRManager = require('webvr-boilerplate'); var AUTOPAN_DURATION = 3000; var AUTOPAN_ANGLE = 0.4; /** * The main WebGL rendering entry point. Manages the scene, camera, VR-related * rendering updates. Interacts with the WebVRManager. * * Coordinates the other renderers: SphereRenderer, HotspotRenderer, * ReticleRenderer. * * Also manages the AdaptivePlayer and VideoProxy. * * Emits the following events: * load: when the scene is loaded. * error: if there is an error loading the scene. * modechange(Boolean isVR): if the mode (eg. VR, fullscreen, etc) changes. */ function WorldRenderer() { this.init_(); this.sphereRenderer = new SphereRenderer(this.scene); this.hotspotRenderer = new HotspotRenderer(this); this.hotspotRenderer.on('focus', this.onHotspotFocus_.bind(this)); this.hotspotRenderer.on('blur', this.onHotspotBlur_.bind(this)); this.reticleRenderer = new ReticleRenderer(this.camera); // Get the VR Display as soon as we initialize. navigator.getVRDisplays().then(function(displays) { if (displays.length > 0) { this.vrDisplay = displays[0]; } }.bind(this)); } WorldRenderer.prototype = new EventEmitter(); WorldRenderer.prototype.render = function(time) { this.controls.update(); this.hotspotRenderer.update(this.camera); TWEEN.update(time); this.effect.render(this.scene, this.camera); }; /** * @return {Promise} When the scene is fully loaded. */ WorldRenderer.prototype.setScene = function(scene) { var self = this; var promise = new Promise(function(resolve, reject) { self.sceneResolve = resolve; self.sceneReject = reject; }); if (!scene || !scene.isValid()) { this.didLoadFail_(scene.errorMessage); return; } var params = { isStereo: scene.isStereo, }; this.setDefaultYaw_(scene.defaultYaw || 0); // Disable VR mode if explicitly disabled, or if we're loading a video on iOS // 9 or earlier. if (scene.isVROff || (scene.video && Util.isIOS9OrLess())) { this.manager.setVRCompatibleOverride(false); } // Set various callback overrides in iOS. if (Util.isIOS()) { this.manager.setFullscreenCallback(function() { Util.sendParentMessage({type: 'enter-fullscreen'}); }); this.manager.setExitFullscreenCallback(function() { Util.sendParentMessage({type: 'exit-fullscreen'}); }); this.manager.setVRCallback(function() { Util.sendParentMessage({type: 'enter-vr'}); }); } // If we're dealing with an image, and not a video. if (scene.image && !scene.video) { if (scene.preview) { // First load the preview. this.sphereRenderer.setPhotosphere(scene.preview, params).then(function() { // As soon as something is loaded, emit the load event to hide the // loading progress bar. self.didLoad_(); // Then load the full resolution image. self.sphereRenderer.setPhotosphere(scene.image, params); }).catch(self.didLoadFail_.bind(self)); } else { // No preview -- go straight to rendering the full image. this.sphereRenderer.setPhotosphere(scene.image, params).then(function() { self.didLoad_(); }).catch(self.didLoadFail_.bind(self)); } } else if (scene.video) { if (Util.isIE11()) { // On IE 11, if an 'image' param is provided, load it instead of showing // an error. // // TODO(smus): Once video textures are supported, remove this fallback. if (scene.image) { this.sphereRenderer.setPhotosphere(scene.image, params).then(function() { self.didLoad_(); }).catch(self.didLoadFail_.bind(self)); } else { this.didLoadFail_('Video is not supported on IE11.'); } } else { this.player = new AdaptivePlayer(); this.player.on('load', function (videoElement) { self.sphereRenderer.set360Video(videoElement, params).then(function() { self.didLoad_({videoElement: videoElement}); }).catch(self.didLoadFail_.bind(self)); }); this.player.on('error', function(error) { self.didLoadFail_('Video load error: ' + error); }); this.player.load(scene.video); this.videoProxy = new VideoProxy(this.player.video); } } this.sceneInfo = scene; if (Util.isDebug()) { console.log('Loaded scene', scene); } return promise; }; WorldRenderer.prototype.isVRMode = function() { return !!this.vrDisplay && this.vrDisplay.isPresenting; }; WorldRenderer.prototype.submitFrame = function() { if (this.isVRMode()) { this.vrDisplay.submitFrame(); } }; WorldRenderer.prototype.destroy = function() { if (this.player) { this.player.removeAllListeners(); this.player.destroy(); this.player = null; } } WorldRenderer.prototype.didLoad_ = function(opt_event) { var event = opt_event || {}; this.emit('load', event); if (this.sceneResolve) { this.sceneResolve(); } }; WorldRenderer.prototype.didLoadFail_ = function(message) { this.emit('error', message); if (this.sceneReject) { this.sceneReject(message); } }; /** * Sets the default yaw. * @param {Number} angleRad The yaw in radians. */ WorldRenderer.prototype.setDefaultYaw_ = function(angleRad) { // Rotate the camera parent to take into account the scene's rotation. // By default, it should be at the center of the image. this.camera.parent.rotation.y = (Math.PI / 2.0) + angleRad; }; /** * Do the initial camera tween to rotate the camera, giving an indication that * there is live content there (on desktop only). */ WorldRenderer.prototype.autopan = function(duration) { var targetY = this.camera.parent.rotation.y - AUTOPAN_ANGLE; var tween = new TWEEN.Tween(this.camera.parent.rotation) .to({y: targetY}, AUTOPAN_DURATION) .easing(TWEEN.Easing.Quadratic.Out) .start(); }; WorldRenderer.prototype.init_ = function() { var container = document.querySelector('body'); var aspect = window.innerWidth / window.innerHeight; var camera = new THREE.PerspectiveCamera(75, aspect, 0.1, 100); camera.layers.enable(1); var cameraDummy = new THREE.Object3D(); cameraDummy.add(camera); // Antialiasing disabled to improve performance. var renderer = new THREE.WebGLRenderer({antialias: false}); renderer.setClearColor(0x000000, 0); renderer.setSize(window.innerWidth, window.innerHeight); renderer.setPixelRatio(window.devicePixelRatio); renderer.domElement.setAttribute('crossOrigin', 'anonymous'); container.appendChild(renderer.domElement); var controls = new THREE.VRControls(camera); var effect = new THREE.VREffect(renderer); // Disable eye separation. effect.scale = 0; effect.setSize(window.innerWidth, window.innerHeight); // Present submission of frames automatically. This is done manually in // submitFrame(). effect.autoSubmitFrame = false; this.camera = camera; this.renderer = renderer; this.effect = effect; this.controls = controls; this.manager = new WebVRManager(renderer, effect, {predistorted: false}); this.scene = this.createScene_(); this.scene.add(this.camera.parent); // Watch the resize event. window.addEventListener('resize', this.onResize_.bind(this)); // Prevent context menu. window.addEventListener('contextmenu', this.onContextMenu_.bind(this)); window.addEventListener('vrdisplaypresentchange', this.onVRDisplayPresentChange_.bind(this)); }; WorldRenderer.prototype.onResize_ = function() { this.effect.setSize(window.innerWidth, window.innerHeight); this.camera.aspect = window.innerWidth / window.innerHeight; this.camera.updateProjectionMatrix(); }; WorldRenderer.prototype.onVRDisplayPresentChange_ = function(e) { if (Util.isDebug()) { console.log('onVRDisplayPresentChange_'); } var isVR = this.isVRMode(); // If the mode changed to VR and there is at least one hotspot, show reticle. var isReticleVisible = isVR && this.hotspotRenderer.getCount() > 0; //this.reticleRenderer.setVisibility(isReticleVisible); // Resize the renderer for good measure. this.onResize_(); // Analytics. if (window.analytics) { analytics.logModeChanged(isVR); } // When exiting VR mode from iOS, make sure we emit back an exit-fullscreen event. if (!isVR && Util.isIOS()) { Util.sendParentMessage({type: 'exit-fullscreen'}); } // Emit a mode change event back to any listeners. this.emit('modechange', isVR); }; WorldRenderer.prototype.createScene_ = function(opt_params) { var scene = new THREE.Scene(); // Add a group for the photosphere. var photoGroup = new THREE.Object3D(); photoGroup.name = 'photo'; scene.add(photoGroup); return scene; }; WorldRenderer.prototype.onHotspotFocus_ = function(id) { // Set the default cursor to be a pointer. this.setCursor_('pointer'); }; WorldRenderer.prototype.onHotspotBlur_ = function(id) { // Reset the default cursor to be the default one. this.setCursor_(''); }; WorldRenderer.prototype.setCursor_ = function(cursor) { this.renderer.domElement.style.cursor = cursor; }; WorldRenderer.prototype.onContextMenu_ = function(e) { e.preventDefault(); e.stopPropagation(); return false; }; module.exports = WorldRenderer; },{"../util":20,"./adaptive-player":8,"./eyes":9,"./hotspot-renderer":10,"./reticle-renderer":14,"./sphere-renderer":16,"./video-proxy":17,"eventemitter3":2,"tween.js":5,"webvr-boilerplate":6}],19:[function(require,module,exports){ /* * Copyright 2016 Google Inc. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Messages from the API to the embed. */ var Message = { PLAY: 'play', PAUSE: 'pause', ADD_HOTSPOT: 'addhotspot', SET_CONTENT: 'setimage', SET_VOLUME: 'setvolume', DEVICE_MOTION: 'devicemotion', }; module.exports = Message; },{}],20:[function(require,module,exports){ /* * Copyright 2016 Google Inc. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ Util = window.Util || {}; Util.isDataURI = function(src) { return src && src.indexOf('data:') == 0; }; Util.generateUUID = function() { function s4() { return Math.floor((1 + Math.random()) * 0x10000) .toString(16) .substring(1); } return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4(); }; Util.isMobile = function() { var check = false; (function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4)))check = true})(navigator.userAgent||navigator.vendor||window.opera); return check; }; Util.isIOS = function() { return /(iPad|iPhone|iPod)/g.test(navigator.userAgent); }; Util.isSafari = function() { return /^((?!chrome|android).)*safari/i.test(navigator.userAgent); }; Util.cloneObject = function(obj) { var out = {}; for (key in obj) { out[key] = obj[key]; } return out; }; Util.hashCode = function(s) { return s.split("").reduce(function(a,b){a=((a<<5)-a)+b.charCodeAt(0);return a&a},0); }; Util.loadTrackSrc = function(context, src, callback, opt_progressCallback) { var request = new XMLHttpRequest(); request.open('GET', src, true); request.responseType = 'arraybuffer'; // Decode asynchronously. request.onload = function() { context.decodeAudioData(request.response, function(buffer) { callback(buffer); }, function(e) { console.error(e); }); }; if (opt_progressCallback) { request.onprogress = function(e) { var percent = e.loaded / e.total; opt_progressCallback(percent); }; } request.send(); }; Util.isPow2 = function(n) { return (n & (n - 1)) == 0; }; Util.capitalize = function(s) { return s.charAt(0).toUpperCase() + s.slice(1); }; Util.isIFrame = function() { try { return window.self !== window.top; } catch (e) { return true; } }; // From http://goo.gl/4WX3tg Util.getQueryParameter = function(name) { name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]"); var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"), results = regex.exec(location.search); return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " ")); }; // From http://stackoverflow.com/questions/11871077/proper-way-to-detect-webgl-support. Util.isWebGLEnabled = function() { var canvas = document.createElement('canvas'); try { gl = canvas.getContext("webgl"); } catch (x) { gl = null; } if (gl == null) { try { gl = canvas.getContext("experimental-webgl"); experimental = true; } catch (x) { gl = null; } } tapHandler(canvas); return !!gl; }; Util.clone = function(obj) { return JSON.parse(JSON.stringify(obj)); }; // From http://stackoverflow.com/questions/10140604/fastest-hypotenuse-in-javascript Util.hypot = Math.hypot || function(x, y) { return Math.sqrt(x*x + y*y); }; // From http://stackoverflow.com/a/17447718/693934 Util.isIE11 = function() { return navigator.userAgent.match(/Trident/); }; Util.getRectCenter = function(rect) { return new THREE.Vector2(rect.x + rect.width/2, rect.y + rect.height/2); }; Util.getScreenWidth = function() { return Math.max(window.screen.width, window.screen.height) * window.devicePixelRatio; }; Util.getScreenHeight = function() { return Math.min(window.screen.width, window.screen.height) * window.devicePixelRatio; }; Util.isIOS9OrLess = function() { if (!Util.isIOS()) { return false; } var re = /(iPhone|iPad|iPod) OS ([\d_]+)/; var iOSVersion = navigator.userAgent.match(re); if (!iOSVersion) { return false; } // Get the last group. var versionString = iOSVersion[iOSVersion.length - 1]; var majorVersion = parseFloat(versionString); return majorVersion <= 9; }; Util.getExtension = function(url) { return url.split('.').pop(); }; Util.createGetParams = function(params) { var out = '?'; for (var k in params) { var paramString = k + '=' + params[k] + '&'; out += paramString; } // Remove the trailing ampersand. out.substring(0, params.length - 2); return out; }; Util.sendParentMessage = function(message) { if (window.parent) { parent.postMessage(message, '*'); } }; Util.parseBoolean = function(value) { if (value == 'false' || value == 0) { return false; } else if (value == 'true' || value == 1) { return true; } else { return !!value; } }; /** * @param base {String} An absolute directory root. * @param relative {String} A relative path. * * @returns {String} An absolute path corresponding to the rootPath. * * From http://stackoverflow.com/a/14780463/693934. */ Util.relativeToAbsolutePath = function(base, relative) { var stack = base.split('/'); var parts = relative.split('/'); for (var i = 0; i < parts.length; i++) { if (parts[i] == '.') { continue; } if (parts[i] == '..') { stack.pop(); } else { stack.push(parts[i]); } } return stack.join('/'); }; /** * @return {Boolean} True iff the specified path is an absolute path. */ Util.isPathAbsolute = function(path) { return ! /^(?:\/|[a-z]+:\/\/)/.test(path); } Util.isEmptyObject = function(obj) { return Object.getOwnPropertyNames(obj).length == 0; }; Util.isDebug = function() { return Util.parseBoolean(Util.getQueryParameter('debug')); }; Util.getCurrentScript = function() { // Note: in IE11, document.currentScript doesn't work, so we fall back to this // hack, taken from https://goo.gl/TpExuH. if (!document.currentScript) { console.warn('This browser does not support document.currentScript. Trying fallback.'); } return document.currentScript || document.scripts[document.scripts.length - 1]; } module.exports = Util; },{}],21:[function(require,module,exports){ // shim for using process in browser var process = module.exports = {}; var queue = []; var draining = false; var currentQueue; var queueIndex = -1; function cleanUpNextTick() { draining = false; if (currentQueue.length) { queue = currentQueue.concat(queue); } else { queueIndex = -1; } if (queue.length) { drainQueue(); } } function drainQueue() { if (draining) { return; } var timeout = setTimeout(cleanUpNextTick); draining = true; var len = queue.length; while(len) { currentQueue = queue; queue = []; while (++queueIndex < len) { if (currentQueue) { currentQueue[queueIndex].run(); } } queueIndex = -1; len = queue.length; } currentQueue = null; draining = false; clearTimeout(timeout); } process.nextTick = function (fun) { var args = new Array(arguments.length - 1); if (arguments.length > 1) { for (var i = 1; i < arguments.length; i++) { args[i - 1] = arguments[i]; } } queue.push(new Item(fun, args)); if (queue.length === 1 && !draining) { setTimeout(drainQueue, 0); } }; // v8 likes predictible objects function Item(fun, array) { this.fun = fun; this.array = array; } Item.prototype.run = function () { this.fun.apply(null, this.array); }; process.title = 'browser'; process.browser = true; process.env = {}; process.argv = []; process.version = ''; // empty string to avoid regexp issues process.versions = {}; function noop() {} process.on = noop; process.addListener = noop; process.once = noop; process.off = noop; process.removeListener = noop; process.removeAllListeners = noop; process.emit = noop; process.binding = function (name) { throw new Error('process.binding is not supported'); }; process.cwd = function () { return '/' }; process.chdir = function (dir) { throw new Error('process.chdir is not supported'); }; process.umask = function() { return 0; }; },{}]},{},[13]) //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL2hvbWVicmV3L2xpYi9ub2RlX21vZHVsZXMvd2F0Y2hpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItcGFjay9fcHJlbHVkZS5qcyIsIm5vZGVfbW9kdWxlcy9lczYtcHJvbWlzZS9kaXN0L2VzNi1wcm9taXNlLmpzIiwibm9kZV9tb2R1bGVzL2V2ZW50ZW1pdHRlcjMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvc2hha2EtcGxheWVyL2Rpc3Qvc2hha2EtcGxheWVyLmNvbXBpbGVkLmpzIiwibm9kZV9tb2R1bGVzL3N0YXRzLWpzL2J1aWxkL3N0YXRzLm1pbi5qcyIsIm5vZGVfbW9kdWxlcy90d2Vlbi5qcy9zcmMvVHdlZW4uanMiLCJub2RlX21vZHVsZXMvd2VidnItYm9pbGVycGxhdGUvYnVpbGQvd2VidnItbWFuYWdlci5qcyIsIm5vZGVfbW9kdWxlcy93ZWJ2ci1wb2x5ZmlsbC9idWlsZC93ZWJ2ci1wb2x5ZmlsbC5qcyIsInNyYy9lbWJlZC9hZGFwdGl2ZS1wbGF5ZXIuanMiLCJzcmMvZW1iZWQvZXllcy5qcyIsInNyYy9lbWJlZC9ob3RzcG90LXJlbmRlcmVyLmpzIiwic3JjL2VtYmVkL2lmcmFtZS1tZXNzYWdlLXJlY2VpdmVyLmpzIiwic3JjL2VtYmVkL2xvYWRpbmctaW5kaWNhdG9yLmpzIiwic3JjL2VtYmVkL21haW4uanMiLCJzcmMvZW1iZWQvcmV0aWNsZS1yZW5kZXJlci5qcyIsInNyYy9lbWJlZC9zY2VuZS1pbmZvLmpzIiwic3JjL2VtYmVkL3NwaGVyZS1yZW5kZXJlci5qcyIsInNyYy9lbWJlZC92aWRlby1wcm94eS5qcyIsInNyYy9lbWJlZC93b3JsZC1yZW5kZXJlci5qcyIsInNyYy9tZXNzYWdlLmpzIiwic3JjL3V0aWwuanMiLCIuLi8uLi9ob21lYnJldy9saWIvbm9kZV9tb2R1bGVzL3dhdGNoaWZ5L25vZGVfbW9kdWxlcy9wcm9jZXNzL2Jyb3dzZXIuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ2pvQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqU0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaFNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUNOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUN0MkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDOWpCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ3JxTUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25JQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdllBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6UkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25HQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxVUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIGUodCxuLHIpe2Z1bmN0aW9uIHMobyx1KXtpZighbltvXSl7aWYoIXRbb10pe3ZhciBhPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7aWYoIXUmJmEpcmV0dXJuIGEobywhMCk7aWYoaSlyZXR1cm4gaShvLCEwKTt2YXIgZj1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK28rXCInXCIpO3Rocm93IGYuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixmfXZhciBsPW5bb109e2V4cG9ydHM6e319O3Rbb11bMF0uY2FsbChsLmV4cG9ydHMsZnVuY3Rpb24oZSl7dmFyIG49dFtvXVsxXVtlXTtyZXR1cm4gcyhuP246ZSl9LGwsbC5leHBvcnRzLGUsdCxuLHIpfXJldHVybiBuW29dLmV4cG9ydHN9dmFyIGk9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtmb3IodmFyIG89MDtvPHIubGVuZ3RoO28rKylzKHJbb10pO3JldHVybiBzfSkiLCIvKiFcbiAqIEBvdmVydmlldyBlczYtcHJvbWlzZSAtIGEgdGlueSBpbXBsZW1lbnRhdGlvbiBvZiBQcm9taXNlcy9BKy5cbiAqIEBjb3B5cmlnaHQgQ29weXJpZ2h0IChjKSAyMDE0IFllaHVkYSBLYXR6LCBUb20gRGFsZSwgU3RlZmFuIFBlbm5lciBhbmQgY29udHJpYnV0b3JzIChDb252ZXJzaW9uIHRvIEVTNiBBUEkgYnkgSmFrZSBBcmNoaWJhbGQpXG4gKiBAbGljZW5zZSAgIExpY2Vuc2VkIHVuZGVyIE1JVCBsaWNlbnNlXG4gKiAgICAgICAgICAgIFNlZSBodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vc3RlZmFucGVubmVyL2VzNi1wcm9taXNlL21hc3Rlci9MSUNFTlNFXG4gKiBAdmVyc2lvbiAgIDMuMy4xXG4gKi9cblxuKGZ1bmN0aW9uIChnbG9iYWwsIGZhY3RvcnkpIHtcbiAgICB0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIG1vZHVsZSAhPT0gJ3VuZGVmaW5lZCcgPyBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkoKSA6XG4gICAgdHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kID8gZGVmaW5lKGZhY3RvcnkpIDpcbiAgICAoZ2xvYmFsLkVTNlByb21pc2UgPSBmYWN0b3J5KCkpO1xufSh0aGlzLCAoZnVuY3Rpb24gKCkgeyAndXNlIHN0cmljdCc7XG5cbmZ1bmN0aW9uIG9iamVjdE9yRnVuY3Rpb24oeCkge1xuICByZXR1cm4gdHlwZW9mIHggPT09ICdmdW5jdGlvbicgfHwgdHlwZW9mIHggPT09ICdvYmplY3QnICYmIHggIT09IG51bGw7XG59XG5cbmZ1bmN0aW9uIGlzRnVuY3Rpb24oeCkge1xuICByZXR1cm4gdHlwZW9mIHggPT09ICdmdW5jdGlvbic7XG59XG5cbnZhciBfaXNBcnJheSA9IHVuZGVmaW5lZDtcbmlmICghQXJyYXkuaXNBcnJheSkge1xuICBfaXNBcnJheSA9IGZ1bmN0aW9uICh4KSB7XG4gICAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh4KSA9PT0gJ1tvYmplY3QgQXJyYXldJztcbiAgfTtcbn0gZWxzZSB7XG4gIF9pc0FycmF5ID0gQXJyYXkuaXNBcnJheTtcbn1cblxudmFyIGlzQXJyYXkgPSBfaXNBcnJheTtcblxudmFyIGxlbiA9IDA7XG52YXIgdmVydHhOZXh0ID0gdW5kZWZpbmVkO1xudmFyIGN1c3RvbVNjaGVkdWxlckZuID0gdW5kZWZpbmVkO1xuXG52YXIgYXNhcCA9IGZ1bmN0aW9uIGFzYXAoY2FsbGJhY2ssIGFyZykge1xuICBxdWV1ZVtsZW5dID0gY2FsbGJhY2s7XG4gIHF1ZXVlW2xlbiArIDFdID0gYXJnO1xuICBsZW4gKz0gMjtcbiAgaWYgKGxlbiA9PT0gMikge1xuICAgIC8vIElmIGxlbiBpcyAyLCB0aGF0IG1lYW5zIHRoYXQgd2UgbmVlZCB0byBzY2hlZHVsZSBhbiBhc3luYyBmbHVzaC5cbiAgICAvLyBJZiBhZGRpdGlvbmFsIGNhbGxiYWNrcyBhcmUgcXVldWVkIGJlZm9yZSB0aGUgcXVldWUgaXMgZmx1c2hlZCwgdGhleVxuICAgIC8vIHdpbGwgYmUgcHJvY2Vzc2VkIGJ5IHRoaXMgZmx1c2ggdGhhdCB3ZSBhcmUgc2NoZWR1bGluZy5cbiAgICBpZiAoY3VzdG9tU2NoZWR1bGVyRm4pIHtcbiAgICAgIGN1c3RvbVNjaGVkdWxlckZuKGZsdXNoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc2NoZWR1bGVGbHVzaCgpO1xuICAgIH1cbiAgfVxufTtcblxuZnVuY3Rpb24gc2V0U2NoZWR1bGVyKHNjaGVkdWxlRm4pIHtcbiAgY3VzdG9tU2NoZWR1bGVyRm4gPSBzY2hlZHVsZUZuO1xufVxuXG5mdW5jdGlvbiBzZXRBc2FwKGFzYXBGbikge1xuICBhc2FwID0gYXNhcEZuO1xufVxuXG52YXIgYnJvd3NlcldpbmRvdyA9IHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnID8gd2luZG93IDogdW5kZWZpbmVkO1xudmFyIGJyb3dzZXJHbG9iYWwgPSBicm93c2VyV2luZG93IHx8IHt9O1xudmFyIEJyb3dzZXJNdXRhdGlvbk9ic2VydmVyID0gYnJvd3Nlckdsb2JhbC5NdXRhdGlvbk9ic2VydmVyIHx8IGJyb3dzZXJHbG9iYWwuV2ViS2l0TXV0YXRpb25PYnNlcnZlcjtcbnZhciBpc05vZGUgPSB0eXBlb2Ygc2VsZiA9PT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIHByb2Nlc3MgIT09ICd1bmRlZmluZWQnICYmICh7fSkudG9TdHJpbmcuY2FsbChwcm9jZXNzKSA9PT0gJ1tvYmplY3QgcHJvY2Vzc10nO1xuXG4vLyB0ZXN0IGZvciB3ZWIgd29ya2VyIGJ1dCBub3QgaW4gSUUxMFxudmFyIGlzV29ya2VyID0gdHlwZW9mIFVpbnQ4Q2xhbXBlZEFycmF5ICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgaW1wb3J0U2NyaXB0cyAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIE1lc3NhZ2VDaGFubmVsICE9PSAndW5kZWZpbmVkJztcblxuLy8gbm9kZVxuZnVuY3Rpb24gdXNlTmV4dFRpY2soKSB7XG4gIC8vIG5vZGUgdmVyc2lvbiAwLjEwLnggZGlzcGxheXMgYSBkZXByZWNhdGlvbiB3YXJuaW5nIHdoZW4gbmV4dFRpY2sgaXMgdXNlZCByZWN1cnNpdmVseVxuICAvLyBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2N1am9qcy93aGVuL2lzc3Vlcy80MTAgZm9yIGRldGFpbHNcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gcHJvY2Vzcy5uZXh0VGljayhmbHVzaCk7XG4gIH07XG59XG5cbi8vIHZlcnR4XG5mdW5jdGlvbiB1c2VWZXJ0eFRpbWVyKCkge1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIHZlcnR4TmV4dChmbHVzaCk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIHVzZU11dGF0aW9uT2JzZXJ2ZXIoKSB7XG4gIHZhciBpdGVyYXRpb25zID0gMDtcbiAgdmFyIG9ic2VydmVyID0gbmV3IEJyb3dzZXJNdXRhdGlvbk9ic2VydmVyKGZsdXNoKTtcbiAgdmFyIG5vZGUgPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSgnJyk7XG4gIG9ic2VydmVyLm9ic2VydmUobm9kZSwgeyBjaGFyYWN0ZXJEYXRhOiB0cnVlIH0pO1xuXG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgbm9kZS5kYXRhID0gaXRlcmF0aW9ucyA9ICsraXRlcmF0aW9ucyAlIDI7XG4gIH07XG59XG5cbi8vIHdlYiB3b3JrZXJcbmZ1bmN0aW9uIHVzZU1lc3NhZ2VDaGFubmVsKCkge1xuICB2YXIgY2hhbm5lbCA9IG5ldyBNZXNzYWdlQ2hhbm5lbCgpO1xuICBjaGFubmVsLnBvcnQxLm9ubWVzc2FnZSA9IGZsdXNoO1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBjaGFubmVsLnBvcnQyLnBvc3RNZXNzYWdlKDApO1xuICB9O1xufVxuXG5mdW5jdGlvbiB1c2VTZXRUaW1lb3V0KCkge1xuICAvLyBTdG9yZSBzZXRUaW1lb3V0IHJlZmVyZW5jZSBzbyBlczYtcHJvbWlzZSB3aWxsIGJlIHVuYWZmZWN0ZWQgYnlcbiAgLy8gb3RoZXIgY29kZSBtb2RpZnlpbmcgc2V0VGltZW91dCAobGlrZSBzaW5vbi51c2VGYWtlVGltZXJzKCkpXG4gIHZhciBnbG9iYWxTZXRUaW1lb3V0ID0gc2V0VGltZW91dDtcbiAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gZ2xvYmFsU2V0VGltZW91dChmbHVzaCwgMSk7XG4gIH07XG59XG5cbnZhciBxdWV1ZSA9IG5ldyBBcnJheSgxMDAwKTtcbmZ1bmN0aW9uIGZsdXNoKCkge1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSArPSAyKSB7XG4gICAgdmFyIGNhbGxiYWNrID0gcXVldWVbaV07XG4gICAgdmFyIGFyZyA9IHF1ZXVlW2kgKyAxXTtcblxuICAgIGNhbGxiYWNrKGFyZyk7XG5cbiAgICBxdWV1ZVtpXSA9IHVuZGVmaW5lZDtcbiAgICBxdWV1ZVtpICsgMV0gPSB1bmRlZmluZWQ7XG4gIH1cblxuICBsZW4gPSAwO1xufVxuXG5mdW5jdGlvbiBhdHRlbXB0VmVydHgoKSB7XG4gIHRyeSB7XG4gICAgdmFyIHIgPSByZXF1aXJlO1xuICAgIHZhciB2ZXJ0eCA9IHIoJ3ZlcnR4Jyk7XG4gICAgdmVydHhOZXh0ID0gdmVydHgucnVuT25Mb29wIHx8IHZlcnR4LnJ1bk9uQ29udGV4dDtcbiAgICByZXR1cm4gdXNlVmVydHhUaW1lcigpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIHVzZVNldFRpbWVvdXQoKTtcbiAgfVxufVxuXG52YXIgc2NoZWR1bGVGbHVzaCA9IHVuZGVmaW5lZDtcbi8vIERlY2lkZSB3aGF0IGFzeW5jIG1ldGhvZCB0byB1c2UgdG8gdHJpZ2dlcmluZyBwcm9jZXNzaW5nIG9mIHF1ZXVlZCBjYWxsYmFja3M6XG5pZiAoaXNOb2RlKSB7XG4gIHNjaGVkdWxlRmx1c2ggPSB1c2VOZXh0VGljaygpO1xufSBlbHNlIGlmIChCcm93c2VyTXV0YXRpb25PYnNlcnZlcikge1xuICBzY2hlZHVsZUZsdXNoID0gdXNlTXV0YXRpb25PYnNlcnZlcigpO1xufSBlbHNlIGlmIChpc1dvcmtlcikge1xuICBzY2hlZHVsZUZsdXNoID0gdXNlTWVzc2FnZUNoYW5uZWwoKTtcbn0gZWxzZSBpZiAoYnJvd3NlcldpbmRvdyA9PT0gdW5kZWZpbmVkICYmIHR5cGVvZiByZXF1aXJlID09PSAnZnVuY3Rpb24nKSB7XG4gIHNjaGVkdWxlRmx1c2ggPSBhdHRlbXB0VmVydHgoKTtcbn0gZWxzZSB7XG4gIHNjaGVkdWxlRmx1c2ggPSB1c2VTZXRUaW1lb3V0KCk7XG59XG5cbmZ1bmN0aW9uIHRoZW4ob25GdWxmaWxsbWVudCwgb25SZWplY3Rpb24pIHtcbiAgdmFyIF9hcmd1bWVudHMgPSBhcmd1bWVudHM7XG5cbiAgdmFyIHBhcmVudCA9IHRoaXM7XG5cbiAgdmFyIGNoaWxkID0gbmV3IHRoaXMuY29uc3RydWN0b3Iobm9vcCk7XG5cbiAgaWYgKGNoaWxkW1BST01JU0VfSURdID09PSB1bmRlZmluZWQpIHtcbiAgICBtYWtlUHJvbWlzZShjaGlsZCk7XG4gIH1cblxuICB2YXIgX3N0YXRlID0gcGFyZW50Ll9zdGF0ZTtcblxuICBpZiAoX3N0YXRlKSB7XG4gICAgKGZ1bmN0aW9uICgpIHtcbiAgICAgIHZhciBjYWxsYmFjayA9IF9hcmd1bWVudHNbX3N0YXRlIC0gMV07XG4gICAgICBhc2FwKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIGludm9rZUNhbGxiYWNrKF9zdGF0ZSwgY2hpbGQsIGNhbGxiYWNrLCBwYXJlbnQuX3Jlc3VsdCk7XG4gICAgICB9KTtcbiAgICB9KSgpO1xuICB9IGVsc2Uge1xuICAgIHN1YnNjcmliZShwYXJlbnQsIGNoaWxkLCBvbkZ1bGZpbGxtZW50LCBvblJlamVjdGlvbik7XG4gIH1cblxuICByZXR1cm4gY2hpbGQ7XG59XG5cbi8qKlxuICBgUHJvbWlzZS5yZXNvbHZlYCByZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHdpbGwgYmVjb21lIHJlc29sdmVkIHdpdGggdGhlXG4gIHBhc3NlZCBgdmFsdWVgLiBJdCBpcyBzaG9ydGhhbmQgZm9yIHRoZSBmb2xsb3dpbmc6XG5cbiAgYGBgamF2YXNjcmlwdFxuICBsZXQgcHJvbWlzZSA9IG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCl7XG4gICAgcmVzb2x2ZSgxKTtcbiAgfSk7XG5cbiAgcHJvbWlzZS50aGVuKGZ1bmN0aW9uKHZhbHVlKXtcbiAgICAvLyB2YWx1ZSA9PT0gMVxuICB9KTtcbiAgYGBgXG5cbiAgSW5zdGVhZCBvZiB3cml0aW5nIHRoZSBhYm92ZSwgeW91ciBjb2RlIG5vdyBzaW1wbHkgYmVjb21lcyB0aGUgZm9sbG93aW5nOlxuXG4gIGBgYGphdmFzY3JpcHRcbiAgbGV0IHByb21pc2UgPSBQcm9taXNlLnJlc29sdmUoMSk7XG5cbiAgcHJvbWlzZS50aGVuKGZ1bmN0aW9uKHZhbHVlKXtcbiAgICAvLyB2YWx1ZSA9PT0gMVxuICB9KTtcbiAgYGBgXG5cbiAgQG1ldGhvZCByZXNvbHZlXG4gIEBzdGF0aWNcbiAgQHBhcmFtIHtBbnl9IHZhbHVlIHZhbHVlIHRoYXQgdGhlIHJldHVybmVkIHByb21pc2Ugd2lsbCBiZSByZXNvbHZlZCB3aXRoXG4gIFVzZWZ1bCBmb3IgdG9vbGluZy5cbiAgQHJldHVybiB7UHJvbWlzZX0gYSBwcm9taXNlIHRoYXQgd2lsbCBiZWNvbWUgZnVsZmlsbGVkIHdpdGggdGhlIGdpdmVuXG4gIGB2YWx1ZWBcbiovXG5mdW5jdGlvbiByZXNvbHZlKG9iamVjdCkge1xuICAvKmpzaGludCB2YWxpZHRoaXM6dHJ1ZSAqL1xuICB2YXIgQ29uc3RydWN0b3IgPSB0aGlzO1xuXG4gIGlmIChvYmplY3QgJiYgdHlwZW9mIG9iamVjdCA9PT0gJ29iamVjdCcgJiYgb2JqZWN0LmNvbnN0cnVjdG9yID09PSBDb25zdHJ1Y3Rvcikge1xuICAgIHJldHVybiBvYmplY3Q7XG4gIH1cblxuICB2YXIgcHJvbWlzZSA9IG5ldyBDb25zdHJ1Y3Rvcihub29wKTtcbiAgX3Jlc29sdmUocHJvbWlzZSwgb2JqZWN0KTtcbiAgcmV0dXJuIHByb21pc2U7XG59XG5cbnZhciBQUk9NSVNFX0lEID0gTWF0aC5yYW5kb20oKS50b1N0cmluZygzNikuc3Vic3RyaW5nKDE2KTtcblxuZnVuY3Rpb24gbm9vcCgpIHt9XG5cbnZhciBQRU5ESU5HID0gdm9pZCAwO1xudmFyIEZVTEZJTExFRCA9IDE7XG52YXIgUkVKRUNURUQgPSAyO1xuXG52YXIgR0VUX1RIRU5fRVJST1IgPSBuZXcgRXJyb3JPYmplY3QoKTtcblxuZnVuY3Rpb24gc2VsZkZ1bGZpbGxtZW50KCkge1xuICByZXR1cm4gbmV3IFR5cGVFcnJvcihcIllvdSBjYW5ub3QgcmVzb2x2ZSBhIHByb21pc2Ugd2l0aCBpdHNlbGZcIik7XG59XG5cbmZ1bmN0aW9uIGNhbm5vdFJldHVybk93bigpIHtcbiAgcmV0dXJuIG5ldyBUeXBlRXJyb3IoJ0EgcHJvbWlzZXMgY2FsbGJhY2sgY2Fubm90IHJldHVybiB0aGF0IHNhbWUgcHJvbWlzZS4nKTtcbn1cblxuZnVuY3Rpb24gZ2V0VGhlbihwcm9taXNlKSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIHByb21pc2UudGhlbjtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBHRVRfVEhFTl9FUlJPUi5lcnJvciA9IGVycm9yO1xuICAgIHJldHVybiBHRVRfVEhFTl9FUlJPUjtcbiAgfVxufVxuXG5mdW5jdGlvbiB0cnlUaGVuKHRoZW4sIHZhbHVlLCBmdWxmaWxsbWVudEhhbmRsZXIsIHJlamVjdGlvbkhhbmRsZXIpIHtcbiAgdHJ5IHtcbiAgICB0aGVuLmNhbGwodmFsdWUsIGZ1bGZpbGxtZW50SGFuZGxlciwgcmVqZWN0aW9uSGFuZGxlcik7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gZTtcbiAgfVxufVxuXG5mdW5jdGlvbiBoYW5kbGVGb3JlaWduVGhlbmFibGUocHJvbWlzZSwgdGhlbmFibGUsIHRoZW4pIHtcbiAgYXNhcChmdW5jdGlvbiAocHJvbWlzZSkge1xuICAgIHZhciBzZWFsZWQgPSBmYWxzZTtcbiAgICB2YXIgZXJyb3IgPSB0cnlUaGVuKHRoZW4sIHRoZW5hYmxlLCBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgIGlmIChzZWFsZWQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgc2VhbGVkID0gdHJ1ZTtcbiAgICAgIGlmICh0aGVuYWJsZSAhPT0gdmFsdWUpIHtcbiAgICAgICAgX3Jlc29sdmUocHJvbWlzZSwgdmFsdWUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZnVsZmlsbChwcm9taXNlLCB2YWx1ZSk7XG4gICAgICB9XG4gICAgfSwgZnVuY3Rpb24gKHJlYXNvbikge1xuICAgICAgaWYgKHNlYWxlZCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBzZWFsZWQgPSB0cnVlO1xuXG4gICAgICBfcmVqZWN0KHByb21pc2UsIHJlYXNvbik7XG4gICAgfSwgJ1NldHRsZTogJyArIChwcm9taXNlLl9sYWJlbCB8fCAnIHVua25vd24gcHJvbWlzZScpKTtcblxuICAgIGlmICghc2VhbGVkICYmIGVycm9yKSB7XG4gICAgICBzZWFsZWQgPSB0cnVlO1xuICAgICAgX3JlamVjdChwcm9taXNlLCBlcnJvcik7XG4gICAgfVxuICB9LCBwcm9taXNlKTtcbn1cblxuZnVuY3Rpb24gaGFuZGxlT3duVGhlbmFibGUocHJvbWlzZSwgdGhlbmFibGUpIHtcbiAgaWYgKHRoZW5hYmxlLl9zdGF0ZSA9PT0gRlVMRklMTEVEKSB7XG4gICAgZnVsZmlsbChwcm9taXNlLCB0aGVuYWJsZS5fcmVzdWx0KTtcbiAgfSBlbHNlIGlmICh0aGVuYWJsZS5fc3RhdGUgPT09IFJFSkVDVEVEKSB7XG4gICAgX3JlamVjdChwcm9taXNlLCB0aGVuYWJsZS5fcmVzdWx0KTtcbiAgfSBlbHNlIHtcbiAgICBzdWJzY3JpYmUodGhlbmFibGUsIHVuZGVmaW5lZCwgZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICByZXR1cm4gX3Jlc29sdmUocHJvbWlzZSwgdmFsdWUpO1xuICAgIH0sIGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICAgIHJldHVybiBfcmVqZWN0KHByb21pc2UsIHJlYXNvbik7XG4gICAgfSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gaGFuZGxlTWF5YmVUaGVuYWJsZShwcm9taXNlLCBtYXliZVRoZW5hYmxlLCB0aGVuJCQpIHtcbiAgaWYgKG1heWJlVGhlbmFibGUuY29uc3RydWN0b3IgPT09IHByb21pc2UuY29uc3RydWN0b3IgJiYgdGhlbiQkID09PSB0aGVuICYmIG1heWJlVGhlbmFibGUuY29uc3RydWN0b3IucmVzb2x2ZSA9PT0gcmVzb2x2ZSkge1xuICAgIGhhbmRsZU93blRoZW5hYmxlKHByb21pc2UsIG1heWJlVGhlbmFibGUpO1xuICB9IGVsc2Uge1xuICAgIGlmICh0aGVuJCQgPT09IEdFVF9USEVOX0VSUk9SKSB7XG4gICAgICBfcmVqZWN0KHByb21pc2UsIEdFVF9USEVOX0VSUk9SLmVycm9yKTtcbiAgICB9IGVsc2UgaWYgKHRoZW4kJCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBmdWxmaWxsKHByb21pc2UsIG1heWJlVGhlbmFibGUpO1xuICAgIH0gZWxzZSBpZiAoaXNGdW5jdGlvbih0aGVuJCQpKSB7XG4gICAgICBoYW5kbGVGb3JlaWduVGhlbmFibGUocHJvbWlzZSwgbWF5YmVUaGVuYWJsZSwgdGhlbiQkKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZnVsZmlsbChwcm9taXNlLCBtYXliZVRoZW5hYmxlKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gX3Jlc29sdmUocHJvbWlzZSwgdmFsdWUpIHtcbiAgaWYgKHByb21pc2UgPT09IHZhbHVlKSB7XG4gICAgX3JlamVjdChwcm9taXNlLCBzZWxmRnVsZmlsbG1lbnQoKSk7XG4gIH0gZWxzZSBpZiAob2JqZWN0T3JGdW5jdGlvbih2YWx1ZSkpIHtcbiAgICBoYW5kbGVNYXliZVRoZW5hYmxlKHByb21pc2UsIHZhbHVlLCBnZXRUaGVuKHZhbHVlKSk7XG4gIH0gZWxzZSB7XG4gICAgZnVsZmlsbChwcm9taXNlLCB2YWx1ZSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcHVibGlzaFJlamVjdGlvbihwcm9taXNlKSB7XG4gIGlmIChwcm9taXNlLl9vbmVycm9yKSB7XG4gICAgcHJvbWlzZS5fb25lcnJvcihwcm9taXNlLl9yZXN1bHQpO1xuICB9XG5cbiAgcHVibGlzaChwcm9taXNlKTtcbn1cblxuZnVuY3Rpb24gZnVsZmlsbChwcm9taXNlLCB2YWx1ZSkge1xuICBpZiAocHJvbWlzZS5fc3RhdGUgIT09IFBFTkRJTkcpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBwcm9taXNlLl9yZXN1bHQgPSB2YWx1ZTtcbiAgcHJvbWlzZS5fc3RhdGUgPSBGVUxGSUxMRUQ7XG5cbiAgaWYgKHByb21pc2UuX3N1YnNjcmliZXJzLmxlbmd0aCAhPT0gMCkge1xuICAgIGFzYXAocHVibGlzaCwgcHJvbWlzZSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gX3JlamVjdChwcm9taXNlLCByZWFzb24pIHtcbiAgaWYgKHByb21pc2UuX3N0YXRlICE9PSBQRU5ESU5HKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIHByb21pc2UuX3N0YXRlID0gUkVKRUNURUQ7XG4gIHByb21pc2UuX3Jlc3VsdCA9IHJlYXNvbjtcblxuICBhc2FwKHB1Ymxpc2hSZWplY3Rpb24sIHByb21pc2UpO1xufVxuXG5mdW5jdGlvbiBzdWJzY3JpYmUocGFyZW50LCBjaGlsZCwgb25GdWxmaWxsbWVudCwgb25SZWplY3Rpb24pIHtcbiAgdmFyIF9zdWJzY3JpYmVycyA9IHBhcmVudC5fc3Vic2NyaWJlcnM7XG4gIHZhciBsZW5ndGggPSBfc3Vic2NyaWJlcnMubGVuZ3RoO1xuXG4gIHBhcmVudC5fb25lcnJvciA9IG51bGw7XG5cbiAgX3N1YnNjcmliZXJzW2xlbmd0aF0gPSBjaGlsZDtcbiAgX3N1YnNjcmliZXJzW2xlbmd0aCArIEZVTEZJTExFRF0gPSBvbkZ1bGZpbGxtZW50O1xuICBfc3Vic2NyaWJlcnNbbGVuZ3RoICsgUkVKRUNURURdID0gb25SZWplY3Rpb247XG5cbiAgaWYgKGxlbmd0aCA9PT0gMCAmJiBwYXJlbnQuX3N0YXRlKSB7XG4gICAgYXNhcChwdWJsaXNoLCBwYXJlbnQpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHB1Ymxpc2gocHJvbWlzZSkge1xuICB2YXIgc3Vic2NyaWJlcnMgPSBwcm9taXNlLl9zdWJzY3JpYmVycztcbiAgdmFyIHNldHRsZWQgPSBwcm9taXNlLl9zdGF0ZTtcblxuICBpZiAoc3Vic2NyaWJlcnMubGVuZ3RoID09PSAwKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIGNoaWxkID0gdW5kZWZpbmVkLFxuICAgICAgY2FsbGJhY2sgPSB1bmRlZmluZWQsXG4gICAgICBkZXRhaWwgPSBwcm9taXNlLl9yZXN1bHQ7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdWJzY3JpYmVycy5sZW5ndGg7IGkgKz0gMykge1xuICAgIGNoaWxkID0gc3Vic2NyaWJlcnNbaV07XG4gICAgY2FsbGJhY2sgPSBzdWJzY3JpYmVyc1tpICsgc2V0dGxlZF07XG5cbiAgICBpZiAoY2hpbGQpIHtcbiAgICAgIGludm9rZUNhbGxiYWNrKHNldHRsZWQsIGNoaWxkLCBjYWxsYmFjaywgZGV0YWlsKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY2FsbGJhY2soZGV0YWlsKTtcbiAgICB9XG4gIH1cblxuICBwcm9taXNlLl9zdWJzY3JpYmVycy5sZW5ndGggPSAwO1xufVxuXG5mdW5jdGlvbiBFcnJvck9iamVjdCgpIHtcbiAgdGhpcy5lcnJvciA9IG51bGw7XG59XG5cbnZhciBUUllfQ0FUQ0hfRVJST1IgPSBuZXcgRXJyb3JPYmplY3QoKTtcblxuZnVuY3Rpb24gdHJ5Q2F0Y2goY2FsbGJhY2ssIGRldGFpbCkge1xuICB0cnkge1xuICAgIHJldHVybiBjYWxsYmFjayhkZXRhaWwpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgVFJZX0NBVENIX0VSUk9SLmVycm9yID0gZTtcbiAgICByZXR1cm4gVFJZX0NBVENIX0VSUk9SO1xuICB9XG59XG5cbmZ1bmN0aW9uIGludm9rZUNhbGxiYWNrKHNldHRsZWQsIHByb21pc2UsIGNhbGxiYWNrLCBkZXRhaWwpIHtcbiAgdmFyIGhhc0NhbGxiYWNrID0gaXNGdW5jdGlvbihjYWxsYmFjayksXG4gICAgICB2YWx1ZSA9IHVuZGVmaW5lZCxcbiAgICAgIGVycm9yID0gdW5kZWZpbmVkLFxuICAgICAgc3VjY2VlZGVkID0gdW5kZWZpbmVkLFxuICAgICAgZmFpbGVkID0gdW5kZWZpbmVkO1xuXG4gIGlmIChoYXNDYWxsYmFjaykge1xuICAgIHZhbHVlID0gdHJ5Q2F0Y2goY2FsbGJhY2ssIGRldGFpbCk7XG5cbiAgICBpZiAodmFsdWUgPT09IFRSWV9DQVRDSF9FUlJPUikge1xuICAgICAgZmFpbGVkID0gdHJ1ZTtcbiAgICAgIGVycm9yID0gdmFsdWUuZXJyb3I7XG4gICAgICB2YWx1ZSA9IG51bGw7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN1Y2NlZWRlZCA9IHRydWU7XG4gICAgfVxuXG4gICAgaWYgKHByb21pc2UgPT09IHZhbHVlKSB7XG4gICAgICBfcmVqZWN0KHByb21pc2UsIGNhbm5vdFJldHVybk93bigpKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdmFsdWUgPSBkZXRhaWw7XG4gICAgc3VjY2VlZGVkID0gdHJ1ZTtcbiAgfVxuXG4gIGlmIChwcm9taXNlLl9zdGF0ZSAhPT0gUEVORElORykge1xuICAgIC8vIG5vb3BcbiAgfSBlbHNlIGlmIChoYXNDYWxsYmFjayAmJiBzdWNjZWVkZWQpIHtcbiAgICAgIF9yZXNvbHZlKHByb21pc2UsIHZhbHVlKTtcbiAgICB9IGVsc2UgaWYgKGZhaWxlZCkge1xuICAgICAgX3JlamVjdChwcm9taXNlLCBlcnJvcik7XG4gICAgfSBlbHNlIGlmIChzZXR0bGVkID09PSBGVUxGSUxMRUQpIHtcbiAgICAgIGZ1bGZpbGwocHJvbWlzZSwgdmFsdWUpO1xuICAgIH0gZWxzZSBpZiAoc2V0dGxlZCA9PT0gUkVKRUNURUQpIHtcbiAgICAgIF9yZWplY3QocHJvbWlzZSwgdmFsdWUpO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gaW5pdGlhbGl6ZVByb21pc2UocHJvbWlzZSwgcmVzb2x2ZXIpIHtcbiAgdHJ5IHtcbiAgICByZXNvbHZlcihmdW5jdGlvbiByZXNvbHZlUHJvbWlzZSh2YWx1ZSkge1xuICAgICAgX3Jlc29sdmUocHJvbWlzZSwgdmFsdWUpO1xuICAgIH0sIGZ1bmN0aW9uIHJlamVjdFByb21pc2UocmVhc29uKSB7XG4gICAgICBfcmVqZWN0KHByb21pc2UsIHJlYXNvbik7XG4gICAgfSk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBfcmVqZWN0KHByb21pc2UsIGUpO1xuICB9XG59XG5cbnZhciBpZCA9IDA7XG5mdW5jdGlvbiBuZXh0SWQoKSB7XG4gIHJldHVybiBpZCsrO1xufVxuXG5mdW5jdGlvbiBtYWtlUHJvbWlzZShwcm9taXNlKSB7XG4gIHByb21pc2VbUFJPTUlTRV9JRF0gPSBpZCsrO1xuICBwcm9taXNlLl9zdGF0ZSA9IHVuZGVmaW5lZDtcbiAgcHJvbWlzZS5fcmVzdWx0ID0gdW5kZWZpbmVkO1xuICBwcm9taXNlLl9zdWJzY3JpYmVycyA9IFtdO1xufVxuXG5mdW5jdGlvbiBFbnVtZXJhdG9yKENvbnN0cnVjdG9yLCBpbnB1dCkge1xuICB0aGlzLl9pbnN0YW5jZUNvbnN0cnVjdG9yID0gQ29uc3RydWN0b3I7XG4gIHRoaXMucHJvbWlzZSA9IG5ldyBDb25zdHJ1Y3Rvcihub29wKTtcblxuICBpZiAoIXRoaXMucHJvbWlzZVtQUk9NSVNFX0lEXSkge1xuICAgIG1ha2VQcm9taXNlKHRoaXMucHJvbWlzZSk7XG4gIH1cblxuICBpZiAoaXNBcnJheShpbnB1dCkpIHtcbiAgICB0aGlzLl9pbnB1dCA9IGlucHV0O1xuICAgIHRoaXMubGVuZ3RoID0gaW5wdXQubGVuZ3RoO1xuICAgIHRoaXMuX3JlbWFpbmluZyA9IGlucHV0Lmxlbmd0aDtcblxuICAgIHRoaXMuX3Jlc3VsdCA9IG5ldyBBcnJheSh0aGlzLmxlbmd0aCk7XG5cbiAgICBpZiAodGhpcy5sZW5ndGggPT09IDApIHtcbiAgICAgIGZ1bGZpbGwodGhpcy5wcm9taXNlLCB0aGlzLl9yZXN1bHQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmxlbmd0aCA9IHRoaXMubGVuZ3RoIHx8IDA7XG4gICAgICB0aGlzLl9lbnVtZXJhdGUoKTtcbiAgICAgIGlmICh0aGlzLl9yZW1haW5pbmcgPT09IDApIHtcbiAgICAgICAgZnVsZmlsbCh0aGlzLnByb21pc2UsIHRoaXMuX3Jlc3VsdCk7XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIF9yZWplY3QodGhpcy5wcm9taXNlLCB2YWxpZGF0aW9uRXJyb3IoKSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gdmFsaWRhdGlvbkVycm9yKCkge1xuICByZXR1cm4gbmV3IEVycm9yKCdBcnJheSBNZXRob2RzIG11c3QgYmUgcHJvdmlkZWQgYW4gQXJyYXknKTtcbn07XG5cbkVudW1lcmF0b3IucHJvdG90eXBlLl9lbnVtZXJhdGUgPSBmdW5jdGlvbiAoKSB7XG4gIHZhciBsZW5ndGggPSB0aGlzLmxlbmd0aDtcbiAgdmFyIF9pbnB1dCA9IHRoaXMuX2lucHV0O1xuXG4gIGZvciAodmFyIGkgPSAwOyB0aGlzLl9zdGF0ZSA9PT0gUEVORElORyAmJiBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICB0aGlzLl9lYWNoRW50cnkoX2lucHV0W2ldLCBpKTtcbiAgfVxufTtcblxuRW51bWVyYXRvci5wcm90b3R5cGUuX2VhY2hFbnRyeSA9IGZ1bmN0aW9uIChlbnRyeSwgaSkge1xuICB2YXIgYyA9IHRoaXMuX2luc3RhbmNlQ29uc3RydWN0b3I7XG4gIHZhciByZXNvbHZlJCQgPSBjLnJlc29sdmU7XG5cbiAgaWYgKHJlc29sdmUkJCA9PT0gcmVzb2x2ZSkge1xuICAgIHZhciBfdGhlbiA9IGdldFRoZW4oZW50cnkpO1xuXG4gICAgaWYgKF90aGVuID09PSB0aGVuICYmIGVudHJ5Ll9zdGF0ZSAhPT0gUEVORElORykge1xuICAgICAgdGhpcy5fc2V0dGxlZEF0KGVudHJ5Ll9zdGF0ZSwgaSwgZW50cnkuX3Jlc3VsdCk7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgX3RoZW4gIT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHRoaXMuX3JlbWFpbmluZy0tO1xuICAgICAgdGhpcy5fcmVzdWx0W2ldID0gZW50cnk7XG4gICAgfSBlbHNlIGlmIChjID09PSBQcm9taXNlKSB7XG4gICAgICB2YXIgcHJvbWlzZSA9IG5ldyBjKG5vb3ApO1xuICAgICAgaGFuZGxlTWF5YmVUaGVuYWJsZShwcm9taXNlLCBlbnRyeSwgX3RoZW4pO1xuICAgICAgdGhpcy5fd2lsbFNldHRsZUF0KHByb21pc2UsIGkpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl93aWxsU2V0dGxlQXQobmV3IGMoZnVuY3Rpb24gKHJlc29sdmUkJCkge1xuICAgICAgICByZXR1cm4gcmVzb2x2ZSQkKGVudHJ5KTtcbiAgICAgIH0pLCBpKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5fd2lsbFNldHRsZUF0KHJlc29sdmUkJChlbnRyeSksIGkpO1xuICB9XG59O1xuXG5FbnVtZXJhdG9yLnByb3RvdHlwZS5fc2V0dGxlZEF0ID0gZnVuY3Rpb24gKHN0YXRlLCBpLCB2YWx1ZSkge1xuICB2YXIgcHJvbWlzZSA9IHRoaXMucHJvbWlzZTtcblxuICBpZiAocHJvbWlzZS5fc3RhdGUgPT09IFBFTkRJTkcpIHtcbiAgICB0aGlzLl9yZW1haW5pbmctLTtcblxuICAgIGlmIChzdGF0ZSA9PT0gUkVKRUNURUQpIHtcbiAgICAgIF9yZWplY3QocHJvbWlzZSwgdmFsdWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9yZXN1bHRbaV0gPSB2YWx1ZTtcbiAgICB9XG4gIH1cblxuICBpZiAodGhpcy5fcmVtYWluaW5nID09PSAwKSB7XG4gICAgZnVsZmlsbChwcm9taXNlLCB0aGlzLl9yZXN1bHQpO1xuICB9XG59O1xuXG5FbnVtZXJhdG9yLnByb3RvdHlwZS5fd2lsbFNldHRsZUF0ID0gZnVuY3Rpb24gKHByb21pc2UsIGkpIHtcbiAgdmFyIGVudW1lcmF0b3IgPSB0aGlzO1xuXG4gIHN1YnNjcmliZShwcm9taXNlLCB1bmRlZmluZWQsIGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgIHJldHVybiBlbnVtZXJhdG9yLl9zZXR0bGVkQXQoRlVMRklMTEVELCBpLCB2YWx1ZSk7XG4gIH0sIGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICByZXR1cm4gZW51bWVyYXRvci5fc2V0dGxlZEF0KFJFSkVDVEVELCBpLCByZWFzb24pO1xuICB9KTtcbn07XG5cbi8qKlxuICBgUHJvbWlzZS5hbGxgIGFjY2VwdHMgYW4gYXJyYXkgb2YgcHJvbWlzZXMsIGFuZCByZXR1cm5zIGEgbmV3IHByb21pc2Ugd2hpY2hcbiAgaXMgZnVsZmlsbGVkIHdpdGggYW4gYXJyYXkgb2YgZnVsZmlsbG1lbnQgdmFsdWVzIGZvciB0aGUgcGFzc2VkIHByb21pc2VzLCBvclxuICByZWplY3RlZCB3aXRoIHRoZSByZWFzb24gb2YgdGhlIGZpcnN0IHBhc3NlZCBwcm9taXNlIHRvIGJlIHJlamVjdGVkLiBJdCBjYXN0cyBhbGxcbiAgZWxlbWVudHMgb2YgdGhlIHBhc3NlZCBpdGVyYWJsZSB0byBwcm9taXNlcyBhcyBpdCBydW5zIHRoaXMgYWxnb3JpdGhtLlxuXG4gIEV4YW1wbGU6XG5cbiAgYGBgamF2YXNjcmlwdFxuICBsZXQgcHJvbWlzZTEgPSByZXNvbHZlKDEpO1xuICBsZXQgcHJvbWlzZTIgPSByZXNvbHZlKDIpO1xuICBsZXQgcHJvbWlzZTMgPSByZXNvbHZlKDMpO1xuICBsZXQgcHJvbWlzZXMgPSBbIHByb21pc2UxLCBwcm9taXNlMiwgcHJvbWlzZTMgXTtcblxuICBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbihmdW5jdGlvbihhcnJheSl7XG4gICAgLy8gVGhlIGFycmF5IGhlcmUgd291bGQgYmUgWyAxLCAyLCAzIF07XG4gIH0pO1xuICBgYGBcblxuICBJZiBhbnkgb2YgdGhlIGBwcm9taXNlc2AgZ2l2ZW4gdG8gYGFsbGAgYXJlIHJlamVjdGVkLCB0aGUgZmlyc3QgcHJvbWlzZVxuICB0aGF0IGlzIHJlamVjdGVkIHdpbGwgYmUgZ2l2ZW4gYXMgYW4gYXJndW1lbnQgdG8gdGhlIHJldHVybmVkIHByb21pc2VzJ3NcbiAgcmVqZWN0aW9uIGhhbmRsZXIuIEZvciBleGFtcGxlOlxuXG4gIEV4YW1wbGU6XG5cbiAgYGBgamF2YXNjcmlwdFxuICBsZXQgcHJvbWlzZTEgPSByZXNvbHZlKDEpO1xuICBsZXQgcHJvbWlzZTIgPSByZWplY3QobmV3IEVycm9yKFwiMlwiKSk7XG4gIGxldCBwcm9taXNlMyA9IHJlamVjdChuZXcgRXJyb3IoXCIzXCIpKTtcbiAgbGV0IHByb21pc2VzID0gWyBwcm9taXNlMSwgcHJvbWlzZTIsIHByb21pc2UzIF07XG5cbiAgUHJvbWlzZS5hbGwocHJvbWlzZXMpLnRoZW4oZnVuY3Rpb24oYXJyYXkpe1xuICAgIC8vIENvZGUgaGVyZSBuZXZlciBydW5zIGJlY2F1c2UgdGhlcmUgYXJlIHJlamVjdGVkIHByb21pc2VzIVxuICB9LCBmdW5jdGlvbihlcnJvcikge1xuICAgIC8vIGVycm9yLm1lc3NhZ2UgPT09IFwiMlwiXG4gIH0pO1xuICBgYGBcblxuICBAbWV0aG9kIGFsbFxuICBAc3RhdGljXG4gIEBwYXJhbSB7QXJyYXl9IGVudHJpZXMgYXJyYXkgb2YgcHJvbWlzZXNcbiAgQHBhcmFtIHtTdHJpbmd9IGxhYmVsIG9wdGlvbmFsIHN0cmluZyBmb3IgbGFiZWxpbmcgdGhlIHByb21pc2UuXG4gIFVzZWZ1bCBmb3IgdG9vbGluZy5cbiAgQHJldHVybiB7UHJvbWlzZX0gcHJvbWlzZSB0aGF0IGlzIGZ1bGZpbGxlZCB3aGVuIGFsbCBgcHJvbWlzZXNgIGhhdmUgYmVlblxuICBmdWxmaWxsZWQsIG9yIHJlamVjdGVkIGlmIGFueSBvZiB0aGVtIGJlY29tZSByZWplY3RlZC5cbiAgQHN0YXRpY1xuKi9cbmZ1bmN0aW9uIGFsbChlbnRyaWVzKSB7XG4gIHJldHVybiBuZXcgRW51bWVyYXRvcih0aGlzLCBlbnRyaWVzKS5wcm9taXNlO1xufVxuXG4vKipcbiAgYFByb21pc2UucmFjZWAgcmV0dXJucyBhIG5ldyBwcm9taXNlIHdoaWNoIGlzIHNldHRsZWQgaW4gdGhlIHNhbWUgd2F5IGFzIHRoZVxuICBmaXJzdCBwYXNzZWQgcHJvbWlzZSB0byBzZXR0bGUuXG5cbiAgRXhhbXBsZTpcblxuICBgYGBqYXZhc2NyaXB0XG4gIGxldCBwcm9taXNlMSA9IG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCl7XG4gICAgc2V0VGltZW91dChmdW5jdGlvbigpe1xuICAgICAgcmVzb2x2ZSgncHJvbWlzZSAxJyk7XG4gICAgfSwgMjAwKTtcbiAgfSk7XG5cbiAgbGV0IHByb21pc2UyID0gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KXtcbiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7XG4gICAgICByZXNvbHZlKCdwcm9taXNlIDInKTtcbiAgICB9LCAxMDApO1xuICB9KTtcblxuICBQcm9taXNlLnJhY2UoW3Byb21pc2UxLCBwcm9taXNlMl0pLnRoZW4oZnVuY3Rpb24ocmVzdWx0KXtcbiAgICAvLyByZXN1bHQgPT09ICdwcm9taXNlIDInIGJlY2F1c2UgaXQgd2FzIHJlc29sdmVkIGJlZm9yZSBwcm9taXNlMVxuICAgIC8vIHdhcyByZXNvbHZlZC5cbiAgfSk7XG4gIGBgYFxuXG4gIGBQcm9taXNlLnJhY2VgIGlzIGRldGVybWluaXN0aWMgaW4gdGhhdCBvbmx5IHRoZSBzdGF0ZSBvZiB0aGUgZmlyc3RcbiAgc2V0dGxlZCBwcm9taXNlIG1hdHRlcnMuIEZvciBleGFtcGxlLCBldmVuIGlmIG90aGVyIHByb21pc2VzIGdpdmVuIHRvIHRoZVxuICBgcHJvbWlzZXNgIGFycmF5IGFyZ3VtZW50IGFyZSByZXNvbHZlZCwgYnV0IHRoZSBmaXJzdCBzZXR0bGVkIHByb21pc2UgaGFzXG4gIGJlY29tZSByZWplY3RlZCBiZWZvcmUgdGhlIG90aGVyIHByb21pc2VzIGJlY2FtZSBmdWxmaWxsZWQsIHRoZSByZXR1cm5lZFxuICBwcm9taXNlIHdpbGwgYmVjb21lIHJlamVjdGVkOlxuXG4gIGBgYGphdmFzY3JpcHRcbiAgbGV0IHByb21pc2UxID0gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KXtcbiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7XG4gICAgICByZXNvbHZlKCdwcm9taXNlIDEnKTtcbiAgICB9LCAyMDApO1xuICB9KTtcblxuICBsZXQgcHJvbWlzZTIgPSBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3Qpe1xuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKXtcbiAgICAgIHJlamVjdChuZXcgRXJyb3IoJ3Byb21pc2UgMicpKTtcbiAgICB9LCAxMDApO1xuICB9KTtcblxuICBQcm9taXNlLnJhY2UoW3Byb21pc2UxLCBwcm9taXNlMl0pLnRoZW4oZnVuY3Rpb24ocmVzdWx0KXtcbiAgICAvLyBDb2RlIGhlcmUgbmV2ZXIgcnVuc1xuICB9LCBmdW5jdGlvbihyZWFzb24pe1xuICAgIC8vIHJlYXNvbi5tZXNzYWdlID09PSAncHJvbWlzZSAyJyBiZWNhdXNlIHByb21pc2UgMiBiZWNhbWUgcmVqZWN0ZWQgYmVmb3JlXG4gICAgLy8gcHJvbWlzZSAxIGJlY2FtZSBmdWxmaWxsZWRcbiAgfSk7XG4gIGBgYFxuXG4gIEFuIGV4YW1wbGUgcmVhbC13b3JsZCB1c2UgY2FzZSBpcyBpbXBsZW1lbnRpbmcgdGltZW91dHM6XG5cbiAgYGBgamF2YXNjcmlwdFxuICBQcm9taXNlLnJhY2UoW2FqYXgoJ2Zvby5qc29uJyksIHRpbWVvdXQoNTAwMCldKVxuICBgYGBcblxuICBAbWV0aG9kIHJhY2VcbiAgQHN0YXRpY1xuICBAcGFyYW0ge0FycmF5fSBwcm9taXNlcyBhcnJheSBvZiBwcm9taXNlcyB0byBvYnNlcnZlXG4gIFVzZWZ1bCBmb3IgdG9vbGluZy5cbiAgQHJldHVybiB7UHJvbWlzZX0gYSBwcm9taXNlIHdoaWNoIHNldHRsZXMgaW4gdGhlIHNhbWUgd2F5IGFzIHRoZSBmaXJzdCBwYXNzZWRcbiAgcHJvbWlzZSB0byBzZXR0bGUuXG4qL1xuZnVuY3Rpb24gcmFjZShlbnRyaWVzKSB7XG4gIC8qanNoaW50IHZhbGlkdGhpczp0cnVlICovXG4gIHZhciBDb25zdHJ1Y3RvciA9IHRoaXM7XG5cbiAgaWYgKCFpc0FycmF5KGVudHJpZXMpKSB7XG4gICAgcmV0dXJuIG5ldyBDb25zdHJ1Y3RvcihmdW5jdGlvbiAoXywgcmVqZWN0KSB7XG4gICAgICByZXR1cm4gcmVqZWN0KG5ldyBUeXBlRXJyb3IoJ1lvdSBtdXN0IHBhc3MgYW4gYXJyYXkgdG8gcmFjZS4nKSk7XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG5ldyBDb25zdHJ1Y3RvcihmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICB2YXIgbGVuZ3RoID0gZW50cmllcy5sZW5ndGg7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICAgIENvbnN0cnVjdG9yLnJlc29sdmUoZW50cmllc1tpXSkudGhlbihyZXNvbHZlLCByZWplY3QpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG59XG5cbi8qKlxuICBgUHJvbWlzZS5yZWplY3RgIHJldHVybnMgYSBwcm9taXNlIHJlamVjdGVkIHdpdGggdGhlIHBhc3NlZCBgcmVhc29uYC5cbiAgSXQgaXMgc2hvcnRoYW5kIGZvciB0aGUgZm9sbG93aW5nOlxuXG4gIGBgYGphdmFzY3JpcHRcbiAgbGV0IHByb21pc2UgPSBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3Qpe1xuICAgIHJlamVjdChuZXcgRXJyb3IoJ1dIT09QUycpKTtcbiAgfSk7XG5cbiAgcHJvbWlzZS50aGVuKGZ1bmN0aW9uKHZhbHVlKXtcbiAgICAvLyBDb2RlIGhlcmUgZG9lc24ndCBydW4gYmVjYXVzZSB0aGUgcHJvbWlzZSBpcyByZWplY3RlZCFcbiAgfSwgZnVuY3Rpb24ocmVhc29uKXtcbiAgICAvLyByZWFzb24ubWVzc2FnZSA9PT0gJ1dIT09QUydcbiAgfSk7XG4gIGBgYFxuXG4gIEluc3RlYWQgb2Ygd3JpdGluZyB0aGUgYWJvdmUsIHlvdXIgY29kZSBub3cgc2ltcGx5IGJlY29tZXMgdGhlIGZvbGxvd2luZzpcblxuICBgYGBqYXZhc2NyaXB0XG4gIGxldCBwcm9taXNlID0gUHJvbWlzZS5yZWplY3QobmV3IEVycm9yKCdXSE9PUFMnKSk7XG5cbiAgcHJvbWlzZS50aGVuKGZ1bmN0aW9uKHZhbHVlKXtcbiAgICAvLyBDb2RlIGhlcmUgZG9lc24ndCBydW4gYmVjYXVzZSB0aGUgcHJvbWlzZSBpcyByZWplY3RlZCFcbiAgfSwgZnVuY3Rpb24ocmVhc29uKXtcbiAgICAvLyByZWFzb24ubWVzc2FnZSA9PT0gJ1dIT09QUydcbiAgfSk7XG4gIGBgYFxuXG4gIEBtZXRob2QgcmVqZWN0XG4gIEBzdGF0aWNcbiAgQHBhcmFtIHtBbnl9IHJlYXNvbiB2YWx1ZSB0aGF0IHRoZSByZXR1cm5lZCBwcm9taXNlIHdpbGwgYmUgcmVqZWN0ZWQgd2l0aC5cbiAgVXNlZnVsIGZvciB0b29saW5nLlxuICBAcmV0dXJuIHtQcm9taXNlfSBhIHByb21pc2UgcmVqZWN0ZWQgd2l0aCB0aGUgZ2l2ZW4gYHJlYXNvbmAuXG4qL1xuZnVuY3Rpb24gcmVqZWN0KHJlYXNvbikge1xuICAvKmpzaGludCB2YWxpZHRoaXM6dHJ1ZSAqL1xuICB2YXIgQ29uc3RydWN0b3IgPSB0aGlzO1xuICB2YXIgcHJvbWlzZSA9IG5ldyBDb25zdHJ1Y3Rvcihub29wKTtcbiAgX3JlamVjdChwcm9taXNlLCByZWFzb24pO1xuICByZXR1cm4gcHJvbWlzZTtcbn1cblxuZnVuY3Rpb24gbmVlZHNSZXNvbHZlcigpIHtcbiAgdGhyb3cgbmV3IFR5cGVFcnJvcignWW91IG11c3QgcGFzcyBhIHJlc29sdmVyIGZ1bmN0aW9uIGFzIHRoZSBmaXJzdCBhcmd1bWVudCB0byB0aGUgcHJvbWlzZSBjb25zdHJ1Y3RvcicpO1xufVxuXG5mdW5jdGlvbiBuZWVkc05ldygpIHtcbiAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkZhaWxlZCB0byBjb25zdHJ1Y3QgJ1Byb21pc2UnOiBQbGVhc2UgdXNlIHRoZSAnbmV3JyBvcGVyYXRvciwgdGhpcyBvYmplY3QgY29uc3RydWN0b3IgY2Fubm90IGJlIGNhbGxlZCBhcyBhIGZ1bmN0aW9uLlwiKTtcbn1cblxuLyoqXG4gIFByb21pc2Ugb2JqZWN0cyByZXByZXNlbnQgdGhlIGV2ZW50dWFsIHJlc3VsdCBvZiBhbiBhc3luY2hyb25vdXMgb3BlcmF0aW9uLiBUaGVcbiAgcHJpbWFyeSB3YXkgb2YgaW50ZXJhY3Rpbmcgd2l0aCBhIHByb21pc2UgaXMgdGhyb3VnaCBpdHMgYHRoZW5gIG1ldGhvZCwgd2hpY2hcbiAgcmVnaXN0ZXJzIGNhbGxiYWNrcyB0byByZWNlaXZlIGVpdGhlciBhIHByb21pc2UncyBldmVudHVhbCB2YWx1ZSBvciB0aGUgcmVhc29uXG4gIHdoeSB0aGUgcHJvbWlzZSBjYW5ub3QgYmUgZnVsZmlsbGVkLlxuXG4gIFRlcm1pbm9sb2d5XG4gIC0tLS0tLS0tLS0tXG5cbiAgLSBgcHJvbWlzZWAgaXMgYW4gb2JqZWN0IG9yIGZ1bmN0aW9uIHdpdGggYSBgdGhlbmAgbWV0aG9kIHdob3NlIGJlaGF2aW9yIGNvbmZvcm1zIHRvIHRoaXMgc3BlY2lmaWNhdGlvbi5cbiAgLSBgdGhlbmFibGVgIGlzIGFuIG9iamVjdCBvciBmdW5jdGlvbiB0aGF0IGRlZmluZXMgYSBgdGhlbmAgbWV0aG9kLlxuICAtIGB2YWx1ZWAgaXMgYW55IGxlZ2FsIEphdmFTY3JpcHQgdmFsdWUgKGluY2x1ZGluZyB1bmRlZmluZWQsIGEgdGhlbmFibGUsIG9yIGEgcHJvbWlzZSkuXG4gIC0gYGV4Y2VwdGlvbmAgaXMgYSB2YWx1ZSB0aGF0IGlzIHRocm93biB1c2luZyB0aGUgdGhyb3cgc3RhdGVtZW50LlxuICAtIGByZWFzb25gIGlzIGEgdmFsdWUgdGhhdCBpbmRpY2F0ZXMgd2h5IGEgcHJvbWlzZSB3YXMgcmVqZWN0ZWQuXG4gIC0gYHNldHRsZWRgIHRoZSBmaW5hbCByZXN0aW5nIHN0YXRlIG9mIGEgcHJvbWlzZSwgZnVsZmlsbGVkIG9yIHJlamVjdGVkLlxuXG4gIEEgcHJvbWlzZSBjYW4gYmUgaW4gb25lIG9mIHRocmVlIHN0YXRlczogcGVuZGluZywgZnVsZmlsbGVkLCBvciByZWplY3RlZC5cblxuICBQcm9taXNlcyB0aGF0IGFyZSBmdWxmaWxsZWQgaGF2ZSBhIGZ1bGZpbGxtZW50IHZhbHVlIGFuZCBhcmUgaW4gdGhlIGZ1bGZpbGxlZFxuICBzdGF0ZS4gIFByb21pc2VzIHRoYXQgYXJlIHJlamVjdGVkIGhhdmUgYSByZWplY3Rpb24gcmVhc29uIGFuZCBhcmUgaW4gdGhlXG4gIHJlamVjdGVkIHN0YXRlLiAgQSBmdWxmaWxsbWVudCB2YWx1ZSBpcyBuZXZlciBhIHRoZW5hYmxlLlxuXG4gIFByb21pc2VzIGNhbiBhbHNvIGJlIHNhaWQgdG8gKnJlc29sdmUqIGEgdmFsdWUuICBJZiB0aGlzIHZhbHVlIGlzIGFsc28gYVxuICBwcm9taXNlLCB0aGVuIHRoZSBvcmlnaW5hbCBwcm9taXNlJ3Mgc2V0dGxlZCBzdGF0ZSB3aWxsIG1hdGNoIHRoZSB2YWx1ZSdzXG4gIHNldHRsZWQgc3RhdGUuICBTbyBhIHByb21pc2UgdGhhdCAqcmVzb2x2ZXMqIGEgcHJvbWlzZSB0aGF0IHJlamVjdHMgd2lsbFxuICBpdHNlbGYgcmVqZWN0LCBhbmQgYSBwcm9taXNlIHRoYXQgKnJlc29sdmVzKiBhIHByb21pc2UgdGhhdCBmdWxmaWxscyB3aWxsXG4gIGl0c2VsZiBmdWxmaWxsLlxuXG5cbiAgQmFzaWMgVXNhZ2U6XG4gIC0tLS0tLS0tLS0tLVxuXG4gIGBgYGpzXG4gIGxldCBwcm9taXNlID0gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgLy8gb24gc3VjY2Vzc1xuICAgIHJlc29sdmUodmFsdWUpO1xuXG4gICAgLy8gb24gZmFpbHVyZVxuICAgIHJlamVjdChyZWFzb24pO1xuICB9KTtcblxuICBwcm9taXNlLnRoZW4oZnVuY3Rpb24odmFsdWUpIHtcbiAgICAvLyBvbiBmdWxmaWxsbWVudFxuICB9LCBmdW5jdGlvbihyZWFzb24pIHtcbiAgICAvLyBvbiByZWplY3Rpb25cbiAgfSk7XG4gIGBgYFxuXG4gIEFkdmFuY2VkIFVzYWdlOlxuICAtLS0tLS0tLS0tLS0tLS1cblxuICBQcm9taXNlcyBzaGluZSB3aGVuIGFic3RyYWN0aW5nIGF3YXkgYXN5bmNocm9ub3VzIGludGVyYWN0aW9ucyBzdWNoIGFzXG4gIGBYTUxIdHRwUmVxdWVzdGBzLlxuXG4gIGBgYGpzXG4gIGZ1bmN0aW9uIGdldEpTT04odXJsKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCl7XG4gICAgICBsZXQgeGhyID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG5cbiAgICAgIHhoci5vcGVuKCdHRVQnLCB1cmwpO1xuICAgICAgeGhyLm9ucmVhZHlzdGF0ZWNoYW5nZSA9IGhhbmRsZXI7XG4gICAgICB4aHIucmVzcG9uc2VUeXBlID0gJ2pzb24nO1xuICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoJ0FjY2VwdCcsICdhcHBsaWNhdGlvbi9qc29uJyk7XG4gICAgICB4aHIuc2VuZCgpO1xuXG4gICAgICBmdW5jdGlvbiBoYW5kbGVyKCkge1xuICAgICAgICBpZiAodGhpcy5yZWFkeVN0YXRlID09PSB0aGlzLkRPTkUpIHtcbiAgICAgICAgICBpZiAodGhpcy5zdGF0dXMgPT09IDIwMCkge1xuICAgICAgICAgICAgcmVzb2x2ZSh0aGlzLnJlc3BvbnNlKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcignZ2V0SlNPTjogYCcgKyB1cmwgKyAnYCBmYWlsZWQgd2l0aCBzdGF0dXM6IFsnICsgdGhpcy5zdGF0dXMgKyAnXScpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgfSk7XG4gIH1cblxuICBnZXRKU09OKCcvcG9zdHMuanNvbicpLnRoZW4oZnVuY3Rpb24oanNvbikge1xuICAgIC8vIG9uIGZ1bGZpbGxtZW50XG4gIH0sIGZ1bmN0aW9uKHJlYXNvbikge1xuICAgIC8vIG9uIHJlamVjdGlvblxuICB9KTtcbiAgYGBgXG5cbiAgVW5saWtlIGNhbGxiYWNrcywgcHJvbWlzZXMgYXJlIGdyZWF0IGNvbXBvc2FibGUgcHJpbWl0aXZlcy5cblxuICBgYGBqc1xuICBQcm9taXNlLmFsbChbXG4gICAgZ2V0SlNPTignL3Bvc3RzJyksXG4gICAgZ2V0SlNPTignL2NvbW1lbnRzJylcbiAgXSkudGhlbihmdW5jdGlvbih2YWx1ZXMpe1xuICAgIHZhbHVlc1swXSAvLyA9PiBwb3N0c0pTT05cbiAgICB2YWx1ZXNbMV0gLy8gPT4gY29tbWVudHNKU09OXG5cbiAgICByZXR1cm4gdmFsdWVzO1xuICB9KTtcbiAgYGBgXG5cbiAgQGNsYXNzIFByb21pc2VcbiAgQHBhcmFtIHtmdW5jdGlvbn0gcmVzb2x2ZXJcbiAgVXNlZnVsIGZvciB0b29saW5nLlxuICBAY29uc3RydWN0b3JcbiovXG5mdW5jdGlvbiBQcm9taXNlKHJlc29sdmVyKSB7XG4gIHRoaXNbUFJPTUlTRV9JRF0gPSBuZXh0SWQoKTtcbiAgdGhpcy5fcmVzdWx0ID0gdGhpcy5fc3RhdGUgPSB1bmRlZmluZWQ7XG4gIHRoaXMuX3N1YnNjcmliZXJzID0gW107XG5cbiAgaWYgKG5vb3AgIT09IHJlc29sdmVyKSB7XG4gICAgdHlwZW9mIHJlc29sdmVyICE9PSAnZnVuY3Rpb24nICYmIG5lZWRzUmVzb2x2ZXIoKTtcbiAgICB0aGlzIGluc3RhbmNlb2YgUHJvbWlzZSA/IGluaXRpYWxpemVQcm9taXNlKHRoaXMsIHJlc29sdmVyKSA6IG5lZWRzTmV3KCk7XG4gIH1cbn1cblxuUHJvbWlzZS5hbGwgPSBhbGw7XG5Qcm9taXNlLnJhY2UgPSByYWNlO1xuUHJvbWlzZS5yZXNvbHZlID0gcmVzb2x2ZTtcblByb21pc2UucmVqZWN0ID0gcmVqZWN0O1xuUHJvbWlzZS5fc2V0U2NoZWR1bGVyID0gc2V0U2NoZWR1bGVyO1xuUHJvbWlzZS5fc2V0QXNhcCA9IHNldEFzYXA7XG5Qcm9taXNlLl9hc2FwID0gYXNhcDtcblxuUHJvbWlzZS5wcm90b3R5cGUgPSB7XG4gIGNvbnN0cnVjdG9yOiBQcm9taXNlLFxuXG4gIC8qKlxuICAgIFRoZSBwcmltYXJ5IHdheSBvZiBpbnRlcmFjdGluZyB3aXRoIGEgcHJvbWlzZSBpcyB0aHJvdWdoIGl0cyBgdGhlbmAgbWV0aG9kLFxuICAgIHdoaWNoIHJlZ2lzdGVycyBjYWxsYmFja3MgdG8gcmVjZWl2ZSBlaXRoZXIgYSBwcm9taXNlJ3MgZXZlbnR1YWwgdmFsdWUgb3IgdGhlXG4gICAgcmVhc29uIHdoeSB0aGUgcHJvbWlzZSBjYW5ub3QgYmUgZnVsZmlsbGVkLlxuICBcbiAgICBgYGBqc1xuICAgIGZpbmRVc2VyKCkudGhlbihmdW5jdGlvbih1c2VyKXtcbiAgICAgIC8vIHVzZXIgaXMgYXZhaWxhYmxlXG4gICAgfSwgZnVuY3Rpb24ocmVhc29uKXtcbiAgICAgIC8vIHVzZXIgaXMgdW5hdmFpbGFibGUsIGFuZCB5b3UgYXJlIGdpdmVuIHRoZSByZWFzb24gd2h5XG4gICAgfSk7XG4gICAgYGBgXG4gIFxuICAgIENoYWluaW5nXG4gICAgLS0tLS0tLS1cbiAgXG4gICAgVGhlIHJldHVybiB2YWx1ZSBvZiBgdGhlbmAgaXMgaXRzZWxmIGEgcHJvbWlzZS4gIFRoaXMgc2Vjb25kLCAnZG93bnN0cmVhbSdcbiAgICBwcm9taXNlIGlzIHJlc29sdmVkIHdpdGggdGhlIHJldHVybiB2YWx1ZSBvZiB0aGUgZmlyc3QgcHJvbWlzZSdzIGZ1bGZpbGxtZW50XG4gICAgb3IgcmVqZWN0aW9uIGhhbmRsZXIsIG9yIHJlamVjdGVkIGlmIHRoZSBoYW5kbGVyIHRocm93cyBhbiBleGNlcHRpb24uXG4gIFxuICAgIGBgYGpzXG4gICAgZmluZFVzZXIoKS50aGVuKGZ1bmN0aW9uICh1c2VyKSB7XG4gICAgICByZXR1cm4gdXNlci5uYW1lO1xuICAgIH0sIGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICAgIHJldHVybiAnZGVmYXVsdCBuYW1lJztcbiAgICB9KS50aGVuKGZ1bmN0aW9uICh1c2VyTmFtZSkge1xuICAgICAgLy8gSWYgYGZpbmRVc2VyYCBmdWxmaWxsZWQsIGB1c2VyTmFtZWAgd2lsbCBiZSB0aGUgdXNlcidzIG5hbWUsIG90aGVyd2lzZSBpdFxuICAgICAgLy8gd2lsbCBiZSBgJ2RlZmF1bHQgbmFtZSdgXG4gICAgfSk7XG4gIFxuICAgIGZpbmRVc2VyKCkudGhlbihmdW5jdGlvbiAodXNlcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdGb3VuZCB1c2VyLCBidXQgc3RpbGwgdW5oYXBweScpO1xuICAgIH0sIGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignYGZpbmRVc2VyYCByZWplY3RlZCBhbmQgd2UncmUgdW5oYXBweScpO1xuICAgIH0pLnRoZW4oZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAvLyBuZXZlciByZWFjaGVkXG4gICAgfSwgZnVuY3Rpb24gKHJlYXNvbikge1xuICAgICAgLy8gaWYgYGZpbmRVc2VyYCBmdWxmaWxsZWQsIGByZWFzb25gIHdpbGwgYmUgJ0ZvdW5kIHVzZXIsIGJ1dCBzdGlsbCB1bmhhcHB5Jy5cbiAgICAgIC8vIElmIGBmaW5kVXNlcmAgcmVqZWN0ZWQsIGByZWFzb25gIHdpbGwgYmUgJ2BmaW5kVXNlcmAgcmVqZWN0ZWQgYW5kIHdlJ3JlIHVuaGFwcHknLlxuICAgIH0pO1xuICAgIGBgYFxuICAgIElmIHRoZSBkb3duc3RyZWFtIHByb21pc2UgZG9lcyBub3Qgc3BlY2lmeSBhIHJlamVjdGlvbiBoYW5kbGVyLCByZWplY3Rpb24gcmVhc29ucyB3aWxsIGJlIHByb3BhZ2F0ZWQgZnVydGhlciBkb3duc3RyZWFtLlxuICBcbiAgICBgYGBqc1xuICAgIGZpbmRVc2VyKCkudGhlbihmdW5jdGlvbiAodXNlcikge1xuICAgICAgdGhyb3cgbmV3IFBlZGFnb2dpY2FsRXhjZXB0aW9uKCdVcHN0cmVhbSBlcnJvcicpO1xuICAgIH0pLnRoZW4oZnVuY3Rpb24gKHZhbHVlKSB7XG4gICAgICAvLyBuZXZlciByZWFjaGVkXG4gICAgfSkudGhlbihmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgIC8vIG5ldmVyIHJlYWNoZWRcbiAgICB9LCBmdW5jdGlvbiAocmVhc29uKSB7XG4gICAgICAvLyBUaGUgYFBlZGdhZ29jaWFsRXhjZXB0aW9uYCBpcyBwcm9wYWdhdGVkIGFsbCB0aGUgd2F5IGRvd24gdG8gaGVyZVxuICAgIH0pO1xuICAgIGBgYFxuICBcbiAgICBBc3NpbWlsYXRpb25cbiAgICAtLS0tLS0tLS0tLS1cbiAgXG4gICAgU29tZXRpbWVzIHRoZSB2YWx1ZSB5b3Ugd2FudCB0byBwcm9wYWdhdGUgdG8gYSBkb3duc3RyZWFtIHByb21pc2UgY2FuIG9ubHkgYmVcbiAgICByZXRyaWV2ZWQgYXN5bmNocm9ub3VzbHkuIFRoaXMgY2FuIGJlIGFjaGlldmVkIGJ5IHJldHVybmluZyBhIHByb21pc2UgaW4gdGhlXG4gICAgZnVsZmlsbG1lbnQgb3IgcmVqZWN0aW9uIGhhbmRsZXIuIFRoZSBkb3duc3RyZWFtIHByb21pc2Ugd2lsbCB0aGVuIGJlIHBlbmRpbmdcbiAgICB1bnRpbCB0aGUgcmV0dXJuZWQgcHJvbWlzZSBpcyBzZXR0bGVkLiBUaGlzIGlzIGNhbGxlZCAqYXNzaW1pbGF0aW9uKi5cbiAgXG4gICAgYGBganNcbiAgICBmaW5kVXNlcigpLnRoZW4oZnVuY3Rpb24gKHVzZXIpIHtcbiAgICAgIHJldHVybiBmaW5kQ29tbWVudHNCeUF1dGhvcih1c2VyKTtcbiAgICB9KS50aGVuKGZ1bmN0aW9uIChjb21tZW50cykge1xuICAgICAgLy8gVGhlIHVzZXIncyBjb21tZW50cyBhcmUgbm93IGF2YWlsYWJsZVxuICAgIH0pO1xuICAgIGBgYFxuICBcbiAgICBJZiB0aGUgYXNzaW1saWF0ZWQgcHJvbWlzZSByZWplY3RzLCB0aGVuIHRoZSBkb3duc3RyZWFtIHByb21pc2Ugd2lsbCBhbHNvIHJlamVjdC5cbiAgXG4gICAgYGBganNcbiAgICBmaW5kVXNlcigpLnRoZW4oZnVuY3Rpb24gKHVzZXIpIHtcbiAgICAgIHJldHVybiBmaW5kQ29tbWVudHNCeUF1dGhvcih1c2VyKTtcbiAgICB9KS50aGVuKGZ1bmN0aW9uIChjb21tZW50cykge1xuICAgICAgLy8gSWYgYGZpbmRDb21tZW50c0J5QXV0aG9yYCBmdWxmaWxscywgd2UnbGwgaGF2ZSB0aGUgdmFsdWUgaGVyZVxuICAgIH0sIGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICAgIC8vIElmIGBmaW5kQ29tbWVudHNCeUF1dGhvcmAgcmVqZWN0cywgd2UnbGwgaGF2ZSB0aGUgcmVhc29uIGhlcmVcbiAgICB9KTtcbiAgICBgYGBcbiAgXG4gICAgU2ltcGxlIEV4YW1wbGVcbiAgICAtLS0tLS0tLS0tLS0tLVxuICBcbiAgICBTeW5jaHJvbm91cyBFeGFtcGxlXG4gIFxuICAgIGBgYGphdmFzY3JpcHRcbiAgICBsZXQgcmVzdWx0O1xuICBcbiAgICB0cnkge1xuICAgICAgcmVzdWx0ID0gZmluZFJlc3VsdCgpO1xuICAgICAgLy8gc3VjY2Vzc1xuICAgIH0gY2F0Y2gocmVhc29uKSB7XG4gICAgICAvLyBmYWlsdXJlXG4gICAgfVxuICAgIGBgYFxuICBcbiAgICBFcnJiYWNrIEV4YW1wbGVcbiAgXG4gICAgYGBganNcbiAgICBmaW5kUmVzdWx0KGZ1bmN0aW9uKHJlc3VsdCwgZXJyKXtcbiAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgLy8gZmFpbHVyZVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gc3VjY2Vzc1xuICAgICAgfVxuICAgIH0pO1xuICAgIGBgYFxuICBcbiAgICBQcm9taXNlIEV4YW1wbGU7XG4gIFxuICAgIGBgYGphdmFzY3JpcHRcbiAgICBmaW5kUmVzdWx0KCkudGhlbihmdW5jdGlvbihyZXN1bHQpe1xuICAgICAgLy8gc3VjY2Vzc1xuICAgIH0sIGZ1bmN0aW9uKHJlYXNvbil7XG4gICAgICAvLyBmYWlsdXJlXG4gICAgfSk7XG4gICAgYGBgXG4gIFxuICAgIEFkdmFuY2VkIEV4YW1wbGVcbiAgICAtLS0tLS0tLS0tLS0tLVxuICBcbiAgICBTeW5jaHJvbm91cyBFeGFtcGxlXG4gIFxuICAgIGBgYGphdmFzY3JpcHRcbiAgICBsZXQgYXV0aG9yLCBib29rcztcbiAgXG4gICAgdHJ5IHtcbiAgICAgIGF1dGhvciA9IGZpbmRBdXRob3IoKTtcbiAgICAgIGJvb2tzICA9IGZpbmRCb29rc0J5QXV0aG9yKGF1dGhvcik7XG4gICAgICAvLyBzdWNjZXNzXG4gICAgfSBjYXRjaChyZWFzb24pIHtcbiAgICAgIC8vIGZhaWx1cmVcbiAgICB9XG4gICAgYGBgXG4gIFxuICAgIEVycmJhY2sgRXhhbXBsZVxuICBcbiAgICBgYGBqc1xuICBcbiAgICBmdW5jdGlvbiBmb3VuZEJvb2tzKGJvb2tzKSB7XG4gIFxuICAgIH1cbiAgXG4gICAgZnVuY3Rpb24gZmFpbHVyZShyZWFzb24pIHtcbiAgXG4gICAgfVxuICBcbiAgICBmaW5kQXV0aG9yKGZ1bmN0aW9uKGF1dGhvciwgZXJyKXtcbiAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgZmFpbHVyZShlcnIpO1xuICAgICAgICAvLyBmYWlsdXJlXG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGZpbmRCb29va3NCeUF1dGhvcihhdXRob3IsIGZ1bmN0aW9uKGJvb2tzLCBlcnIpIHtcbiAgICAgICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgICAgZmFpbHVyZShlcnIpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBmb3VuZEJvb2tzKGJvb2tzKTtcbiAgICAgICAgICAgICAgfSBjYXRjaChyZWFzb24pIHtcbiAgICAgICAgICAgICAgICBmYWlsdXJlKHJlYXNvbik7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBjYXRjaChlcnJvcikge1xuICAgICAgICAgIGZhaWx1cmUoZXJyKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBzdWNjZXNzXG4gICAgICB9XG4gICAgfSk7XG4gICAgYGBgXG4gIFxuICAgIFByb21pc2UgRXhhbXBsZTtcbiAgXG4gICAgYGBgamF2YXNjcmlwdFxuICAgIGZpbmRBdXRob3IoKS5cbiAgICAgIHRoZW4oZmluZEJvb2tzQnlBdXRob3IpLlxuICAgICAgdGhlbihmdW5jdGlvbihib29rcyl7XG4gICAgICAgIC8vIGZvdW5kIGJvb2tzXG4gICAgfSkuY2F0Y2goZnVuY3Rpb24ocmVhc29uKXtcbiAgICAgIC8vIHNvbWV0aGluZyB3ZW50IHdyb25nXG4gICAgfSk7XG4gICAgYGBgXG4gIFxuICAgIEBtZXRob2QgdGhlblxuICAgIEBwYXJhbSB7RnVuY3Rpb259IG9uRnVsZmlsbGVkXG4gICAgQHBhcmFtIHtGdW5jdGlvbn0gb25SZWplY3RlZFxuICAgIFVzZWZ1bCBmb3IgdG9vbGluZy5cbiAgICBAcmV0dXJuIHtQcm9taXNlfVxuICAqL1xuICB0aGVuOiB0aGVuLFxuXG4gIC8qKlxuICAgIGBjYXRjaGAgaXMgc2ltcGx5IHN1Z2FyIGZvciBgdGhlbih1bmRlZmluZWQsIG9uUmVqZWN0aW9uKWAgd2hpY2ggbWFrZXMgaXQgdGhlIHNhbWVcbiAgICBhcyB0aGUgY2F0Y2ggYmxvY2sgb2YgYSB0cnkvY2F0Y2ggc3RhdGVtZW50LlxuICBcbiAgICBgYGBqc1xuICAgIGZ1bmN0aW9uIGZpbmRBdXRob3IoKXtcbiAgICAgIHRocm93IG5ldyBFcnJvcignY291bGRuJ3QgZmluZCB0aGF0IGF1dGhvcicpO1xuICAgIH1cbiAgXG4gICAgLy8gc3luY2hyb25vdXNcbiAgICB0cnkge1xuICAgICAgZmluZEF1dGhvcigpO1xuICAgIH0gY2F0Y2gocmVhc29uKSB7XG4gICAgICAvLyBzb21ldGhpbmcgd2VudCB3cm9uZ1xuICAgIH1cbiAgXG4gICAgLy8gYXN5bmMgd2l0aCBwcm9taXNlc1xuICAgIGZpbmRBdXRob3IoKS5jYXRjaChmdW5jdGlvbihyZWFzb24pe1xuICAgICAgLy8gc29tZXRoaW5nIHdlbnQgd3JvbmdcbiAgICB9KTtcbiAgICBgYGBcbiAgXG4gICAgQG1ldGhvZCBjYXRjaFxuICAgIEBwYXJhbSB7RnVuY3Rpb259IG9uUmVqZWN0aW9uXG4gICAgVXNlZnVsIGZvciB0b29saW5nLlxuICAgIEByZXR1cm4ge1Byb21pc2V9XG4gICovXG4gICdjYXRjaCc6IGZ1bmN0aW9uIF9jYXRjaChvblJlamVjdGlvbikge1xuICAgIHJldHVybiB0aGlzLnRoZW4obnVsbCwgb25SZWplY3Rpb24pO1xuICB9XG59O1xuXG5mdW5jdGlvbiBwb2x5ZmlsbCgpIHtcbiAgICB2YXIgbG9jYWwgPSB1bmRlZmluZWQ7XG5cbiAgICBpZiAodHlwZW9mIGdsb2JhbCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgbG9jYWwgPSBnbG9iYWw7XG4gICAgfSBlbHNlIGlmICh0eXBlb2Ygc2VsZiAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgbG9jYWwgPSBzZWxmO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBsb2NhbCA9IEZ1bmN0aW9uKCdyZXR1cm4gdGhpcycpKCk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigncG9seWZpbGwgZmFpbGVkIGJlY2F1c2UgZ2xvYmFsIG9iamVjdCBpcyB1bmF2YWlsYWJsZSBpbiB0aGlzIGVudmlyb25tZW50Jyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgUCA9IGxvY2FsLlByb21pc2U7XG5cbiAgICBpZiAoUCkge1xuICAgICAgICB2YXIgcHJvbWlzZVRvU3RyaW5nID0gbnVsbDtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHByb21pc2VUb1N0cmluZyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChQLnJlc29sdmUoKSk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIC8vIHNpbGVudGx5IGlnbm9yZWRcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwcm9taXNlVG9TdHJpbmcgPT09ICdbb2JqZWN0IFByb21pc2VdJyAmJiAhUC5jYXN0KSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBsb2NhbC5Qcm9taXNlID0gUHJvbWlzZTtcbn1cblxucG9seWZpbGwoKTtcbi8vIFN0cmFuZ2UgY29tcGF0Li5cblByb21pc2UucG9seWZpbGwgPSBwb2x5ZmlsbDtcblByb21pc2UuUHJvbWlzZSA9IFByb21pc2U7XG5cbnJldHVybiBQcm9taXNlO1xuXG59KSkpO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZXM2LXByb21pc2UubWFwIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgaGFzID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcblxuLy9cbi8vIFdlIHN0b3JlIG91ciBFRSBvYmplY3RzIGluIGEgcGxhaW4gb2JqZWN0IHdob3NlIHByb3BlcnRpZXMgYXJlIGV2ZW50IG5hbWVzLlxuLy8gSWYgYE9iamVjdC5jcmVhdGUobnVsbClgIGlzIG5vdCBzdXBwb3J0ZWQgd2UgcHJlZml4IHRoZSBldmVudCBuYW1lcyB3aXRoIGFcbi8vIGB+YCB0byBtYWtlIHN1cmUgdGhhdCB0aGUgYnVpbHQtaW4gb2JqZWN0IHByb3BlcnRpZXMgYXJlIG5vdCBvdmVycmlkZGVuIG9yXG4vLyB1c2VkIGFzIGFuIGF0dGFjayB2ZWN0b3IuXG4vLyBXZSBhbHNvIGFzc3VtZSB0aGF0IGBPYmplY3QuY3JlYXRlKG51bGwpYCBpcyBhdmFpbGFibGUgd2hlbiB0aGUgZXZlbnQgbmFtZVxuLy8gaXMgYW4gRVM2IFN5bWJvbC5cbi8vXG52YXIgcHJlZml4ID0gdHlwZW9mIE9iamVjdC5jcmVhdGUgIT09ICdmdW5jdGlvbicgPyAnficgOiBmYWxzZTtcblxuLyoqXG4gKiBSZXByZXNlbnRhdGlvbiBvZiBhIHNpbmdsZSBFdmVudEVtaXR0ZXIgZnVuY3Rpb24uXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gRXZlbnQgaGFuZGxlciB0byBiZSBjYWxsZWQuXG4gKiBAcGFyYW0ge01peGVkfSBjb250ZXh0IENvbnRleHQgZm9yIGZ1bmN0aW9uIGV4ZWN1dGlvbi5cbiAqIEBwYXJhbSB7Qm9vbGVhbn0gW29uY2U9ZmFsc2VdIE9ubHkgZW1pdCBvbmNlXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gRUUoZm4sIGNvbnRleHQsIG9uY2UpIHtcbiAgdGhpcy5mbiA9IGZuO1xuICB0aGlzLmNvbnRleHQgPSBjb250ZXh0O1xuICB0aGlzLm9uY2UgPSBvbmNlIHx8IGZhbHNlO1xufVxuXG4vKipcbiAqIE1pbmltYWwgRXZlbnRFbWl0dGVyIGludGVyZmFjZSB0aGF0IGlzIG1vbGRlZCBhZ2FpbnN0IHRoZSBOb2RlLmpzXG4gKiBFdmVudEVtaXR0ZXIgaW50ZXJmYWNlLlxuICpcbiAqIEBjb25zdHJ1Y3RvclxuICogQGFwaSBwdWJsaWNcbiAqL1xuZnVuY3Rpb24gRXZlbnRFbWl0dGVyKCkgeyAvKiBOb3RoaW5nIHRvIHNldCAqLyB9XG5cbi8qKlxuICogSG9sZCB0aGUgYXNzaWduZWQgRXZlbnRFbWl0dGVycyBieSBuYW1lLlxuICpcbiAqIEB0eXBlIHtPYmplY3R9XG4gKiBAcHJpdmF0ZVxuICovXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLl9ldmVudHMgPSB1bmRlZmluZWQ7XG5cbi8qKlxuICogUmV0dXJuIGFuIGFycmF5IGxpc3RpbmcgdGhlIGV2ZW50cyBmb3Igd2hpY2ggdGhlIGVtaXR0ZXIgaGFzIHJlZ2lzdGVyZWRcbiAqIGxpc3RlbmVycy5cbiAqXG4gKiBAcmV0dXJucyB7QXJyYXl9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmV2ZW50TmFtZXMgPSBmdW5jdGlvbiBldmVudE5hbWVzKCkge1xuICB2YXIgZXZlbnRzID0gdGhpcy5fZXZlbnRzXG4gICAgLCBuYW1lcyA9IFtdXG4gICAgLCBuYW1lO1xuXG4gIGlmICghZXZlbnRzKSByZXR1cm4gbmFtZXM7XG5cbiAgZm9yIChuYW1lIGluIGV2ZW50cykge1xuICAgIGlmIChoYXMuY2FsbChldmVudHMsIG5hbWUpKSBuYW1lcy5wdXNoKHByZWZpeCA/IG5hbWUuc2xpY2UoMSkgOiBuYW1lKTtcbiAgfVxuXG4gIGlmIChPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKSB7XG4gICAgcmV0dXJuIG5hbWVzLmNvbmNhdChPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKGV2ZW50cykpO1xuICB9XG5cbiAgcmV0dXJuIG5hbWVzO1xufTtcblxuLyoqXG4gKiBSZXR1cm4gYSBsaXN0IG9mIGFzc2lnbmVkIGV2ZW50IGxpc3RlbmVycy5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnQgVGhlIGV2ZW50cyB0aGF0IHNob3VsZCBiZSBsaXN0ZWQuXG4gKiBAcGFyYW0ge0Jvb2xlYW59IGV4aXN0cyBXZSBvbmx5IG5lZWQgdG8ga25vdyBpZiB0aGVyZSBhcmUgbGlzdGVuZXJzLlxuICogQHJldHVybnMge0FycmF5fEJvb2xlYW59XG4gKiBAYXBpIHB1YmxpY1xuICovXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmxpc3RlbmVycyA9IGZ1bmN0aW9uIGxpc3RlbmVycyhldmVudCwgZXhpc3RzKSB7XG4gIHZhciBldnQgPSBwcmVmaXggPyBwcmVmaXggKyBldmVudCA6IGV2ZW50XG4gICAgLCBhdmFpbGFibGUgPSB0aGlzLl9ldmVudHMgJiYgdGhpcy5fZXZlbnRzW2V2dF07XG5cbiAgaWYgKGV4aXN0cykgcmV0dXJuICEhYXZhaWxhYmxlO1xuICBpZiAoIWF2YWlsYWJsZSkgcmV0dXJuIFtdO1xuICBpZiAoYXZhaWxhYmxlLmZuKSByZXR1cm4gW2F2YWlsYWJsZS5mbl07XG5cbiAgZm9yICh2YXIgaSA9IDAsIGwgPSBhdmFpbGFibGUubGVuZ3RoLCBlZSA9IG5ldyBBcnJheShsKTsgaSA8IGw7IGkrKykge1xuICAgIGVlW2ldID0gYXZhaWxhYmxlW2ldLmZuO1xuICB9XG5cbiAgcmV0dXJuIGVlO1xufTtcblxuLyoqXG4gKiBFbWl0IGFuIGV2ZW50IHRvIGFsbCByZWdpc3RlcmVkIGV2ZW50IGxpc3RlbmVycy5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnQgVGhlIG5hbWUgb2YgdGhlIGV2ZW50LlxuICogQHJldHVybnMge0Jvb2xlYW59IEluZGljYXRpb24gaWYgd2UndmUgZW1pdHRlZCBhbiBldmVudC5cbiAqIEBhcGkgcHVibGljXG4gKi9cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uIGVtaXQoZXZlbnQsIGExLCBhMiwgYTMsIGE0LCBhNSkge1xuICB2YXIgZXZ0ID0gcHJlZml4ID8gcHJlZml4ICsgZXZlbnQgOiBldmVudDtcblxuICBpZiAoIXRoaXMuX2V2ZW50cyB8fCAhdGhpcy5fZXZlbnRzW2V2dF0pIHJldHVybiBmYWxzZTtcblxuICB2YXIgbGlzdGVuZXJzID0gdGhpcy5fZXZlbnRzW2V2dF1cbiAgICAsIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGhcbiAgICAsIGFyZ3NcbiAgICAsIGk7XG5cbiAgaWYgKCdmdW5jdGlvbicgPT09IHR5cGVvZiBsaXN0ZW5lcnMuZm4pIHtcbiAgICBpZiAobGlzdGVuZXJzLm9uY2UpIHRoaXMucmVtb3ZlTGlzdGVuZXIoZXZlbnQsIGxpc3RlbmVycy5mbiwgdW5kZWZpbmVkLCB0cnVlKTtcblxuICAgIHN3aXRjaCAobGVuKSB7XG4gICAgICBjYXNlIDE6IHJldHVybiBsaXN0ZW5lcnMuZm4uY2FsbChsaXN0ZW5lcnMuY29udGV4dCksIHRydWU7XG4gICAgICBjYXNlIDI6IHJldHVybiBsaXN0ZW5lcnMuZm4uY2FsbChsaXN0ZW5lcnMuY29udGV4dCwgYTEpLCB0cnVlO1xuICAgICAgY2FzZSAzOiByZXR1cm4gbGlzdGVuZXJzLmZuLmNhbGwobGlzdGVuZXJzLmNvbnRleHQsIGExLCBhMiksIHRydWU7XG4gICAgICBjYXNlIDQ6IHJldHVybiBsaXN0ZW5lcnMuZm4uY2FsbChsaXN0ZW5lcnMuY29udGV4dCwgYTEsIGEyLCBhMyksIHRydWU7XG4gICAgICBjYXNlIDU6IHJldHVybiBsaXN0ZW5lcnMuZm4uY2FsbChsaXN0ZW5lcnMuY29udGV4dCwgYTEsIGEyLCBhMywgYTQpLCB0cnVlO1xuICAgICAgY2FzZSA2OiByZXR1cm4gbGlzdGVuZXJzLmZuLmNhbGwobGlzdGVuZXJzLmNvbnRleHQsIGExLCBhMiwgYTMsIGE0LCBhNSksIHRydWU7XG4gICAgfVxuXG4gICAgZm9yIChpID0gMSwgYXJncyA9IG5ldyBBcnJheShsZW4gLTEpOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgIGFyZ3NbaSAtIDFdID0gYXJndW1lbnRzW2ldO1xuICAgIH1cblxuICAgIGxpc3RlbmVycy5mbi5hcHBseShsaXN0ZW5lcnMuY29udGV4dCwgYXJncyk7XG4gIH0gZWxzZSB7XG4gICAgdmFyIGxlbmd0aCA9IGxpc3RlbmVycy5sZW5ndGhcbiAgICAgICwgajtcblxuICAgIGZvciAoaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgaWYgKGxpc3RlbmVyc1tpXS5vbmNlKSB0aGlzLnJlbW92ZUxpc3RlbmVyKGV2ZW50LCBsaXN0ZW5lcnNbaV0uZm4sIHVuZGVmaW5lZCwgdHJ1ZSk7XG5cbiAgICAgIHN3aXRjaCAobGVuKSB7XG4gICAgICAgIGNhc2UgMTogbGlzdGVuZXJzW2ldLmZuLmNhbGwobGlzdGVuZXJzW2ldLmNvbnRleHQpOyBicmVhaztcbiAgICAgICAgY2FzZSAyOiBsaXN0ZW5lcnNbaV0uZm4uY2FsbChsaXN0ZW5lcnNbaV0uY29udGV4dCwgYTEpOyBicmVhaztcbiAgICAgICAgY2FzZSAzOiBsaXN0ZW5lcnNbaV0uZm4uY2FsbChsaXN0ZW5lcnNbaV0uY29udGV4dCwgYTEsIGEyKTsgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgaWYgKCFhcmdzKSBmb3IgKGogPSAxLCBhcmdzID0gbmV3IEFycmF5KGxlbiAtMSk7IGogPCBsZW47IGorKykge1xuICAgICAgICAgICAgYXJnc1tqIC0gMV0gPSBhcmd1bWVudHNbal07XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgbGlzdGVuZXJzW2ldLmZuLmFwcGx5KGxpc3RlbmVyc1tpXS5jb250ZXh0LCBhcmdzKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbi8qKlxuICogUmVnaXN0ZXIgYSBuZXcgRXZlbnRMaXN0ZW5lciBmb3IgdGhlIGdpdmVuIGV2ZW50LlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudCBOYW1lIG9mIHRoZSBldmVudC5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIENhbGxiYWNrIGZ1bmN0aW9uLlxuICogQHBhcmFtIHtNaXhlZH0gW2NvbnRleHQ9dGhpc10gVGhlIGNvbnRleHQgb2YgdGhlIGZ1bmN0aW9uLlxuICogQGFwaSBwdWJsaWNcbiAqL1xuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbiA9IGZ1bmN0aW9uIG9uKGV2ZW50LCBmbiwgY29udGV4dCkge1xuICB2YXIgbGlzdGVuZXIgPSBuZXcgRUUoZm4sIGNvbnRleHQgfHwgdGhpcylcbiAgICAsIGV2dCA9IHByZWZpeCA/IHByZWZpeCArIGV2ZW50IDogZXZlbnQ7XG5cbiAgaWYgKCF0aGlzLl9ldmVudHMpIHRoaXMuX2V2ZW50cyA9IHByZWZpeCA/IHt9IDogT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgaWYgKCF0aGlzLl9ldmVudHNbZXZ0XSkgdGhpcy5fZXZlbnRzW2V2dF0gPSBsaXN0ZW5lcjtcbiAgZWxzZSB7XG4gICAgaWYgKCF0aGlzLl9ldmVudHNbZXZ0XS5mbikgdGhpcy5fZXZlbnRzW2V2dF0ucHVzaChsaXN0ZW5lcik7XG4gICAgZWxzZSB0aGlzLl9ldmVudHNbZXZ0XSA9IFtcbiAgICAgIHRoaXMuX2V2ZW50c1tldnRdLCBsaXN0ZW5lclxuICAgIF07XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogQWRkIGFuIEV2ZW50TGlzdGVuZXIgdGhhdCdzIG9ubHkgY2FsbGVkIG9uY2UuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50IE5hbWUgb2YgdGhlIGV2ZW50LlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gQ2FsbGJhY2sgZnVuY3Rpb24uXG4gKiBAcGFyYW0ge01peGVkfSBbY29udGV4dD10aGlzXSBUaGUgY29udGV4dCBvZiB0aGUgZnVuY3Rpb24uXG4gKiBAYXBpIHB1YmxpY1xuICovXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbiBvbmNlKGV2ZW50LCBmbiwgY29udGV4dCkge1xuICB2YXIgbGlzdGVuZXIgPSBuZXcgRUUoZm4sIGNvbnRleHQgfHwgdGhpcywgdHJ1ZSlcbiAgICAsIGV2dCA9IHByZWZpeCA/IHByZWZpeCArIGV2ZW50IDogZXZlbnQ7XG5cbiAgaWYgKCF0aGlzLl9ldmVudHMpIHRoaXMuX2V2ZW50cyA9IHByZWZpeCA/IHt9IDogT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgaWYgKCF0aGlzLl9ldmVudHNbZXZ0XSkgdGhpcy5fZXZlbnRzW2V2dF0gPSBsaXN0ZW5lcjtcbiAgZWxzZSB7XG4gICAgaWYgKCF0aGlzLl9ldmVudHNbZXZ0XS5mbikgdGhpcy5fZXZlbnRzW2V2dF0ucHVzaChsaXN0ZW5lcik7XG4gICAgZWxzZSB0aGlzLl9ldmVudHNbZXZ0XSA9IFtcbiAgICAgIHRoaXMuX2V2ZW50c1tldnRdLCBsaXN0ZW5lclxuICAgIF07XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogUmVtb3ZlIGV2ZW50IGxpc3RlbmVycy5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnQgVGhlIGV2ZW50IHdlIHdhbnQgdG8gcmVtb3ZlLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gVGhlIGxpc3RlbmVyIHRoYXQgd2UgbmVlZCB0byBmaW5kLlxuICogQHBhcmFtIHtNaXhlZH0gY29udGV4dCBPbmx5IHJlbW92ZSBsaXN0ZW5lcnMgbWF0Y2hpbmcgdGhpcyBjb250ZXh0LlxuICogQHBhcmFtIHtCb29sZWFufSBvbmNlIE9ubHkgcmVtb3ZlIG9uY2UgbGlzdGVuZXJzLlxuICogQGFwaSBwdWJsaWNcbiAqL1xuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVMaXN0ZW5lciA9IGZ1bmN0aW9uIHJlbW92ZUxpc3RlbmVyKGV2ZW50LCBmbiwgY29udGV4dCwgb25jZSkge1xuICB2YXIgZXZ0ID0gcHJlZml4ID8gcHJlZml4ICsgZXZlbnQgOiBldmVudDtcblxuICBpZiAoIXRoaXMuX2V2ZW50cyB8fCAhdGhpcy5fZXZlbnRzW2V2dF0pIHJldHVybiB0aGlzO1xuXG4gIHZhciBsaXN0ZW5lcnMgPSB0aGlzLl9ldmVudHNbZXZ0XVxuICAgICwgZXZlbnRzID0gW107XG5cbiAgaWYgKGZuKSB7XG4gICAgaWYgKGxpc3RlbmVycy5mbikge1xuICAgICAgaWYgKFxuICAgICAgICAgICBsaXN0ZW5lcnMuZm4gIT09IGZuXG4gICAgICAgIHx8IChvbmNlICYmICFsaXN0ZW5lcnMub25jZSlcbiAgICAgICAgfHwgKGNvbnRleHQgJiYgbGlzdGVuZXJzLmNvbnRleHQgIT09IGNvbnRleHQpXG4gICAgICApIHtcbiAgICAgICAgZXZlbnRzLnB1c2gobGlzdGVuZXJzKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbmd0aCA9IGxpc3RlbmVycy5sZW5ndGg7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgICAgbGlzdGVuZXJzW2ldLmZuICE9PSBmblxuICAgICAgICAgIHx8IChvbmNlICYmICFsaXN0ZW5lcnNbaV0ub25jZSlcbiAgICAgICAgICB8fCAoY29udGV4dCAmJiBsaXN0ZW5lcnNbaV0uY29udGV4dCAhPT0gY29udGV4dClcbiAgICAgICAgKSB7XG4gICAgICAgICAgZXZlbnRzLnB1c2gobGlzdGVuZXJzW2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vXG4gIC8vIFJlc2V0IHRoZSBhcnJheSwgb3IgcmVtb3ZlIGl0IGNvbXBsZXRlbHkgaWYgd2UgaGF2ZSBubyBtb3JlIGxpc3RlbmVycy5cbiAgLy9cbiAgaWYgKGV2ZW50cy5sZW5ndGgpIHtcbiAgICB0aGlzLl9ldmVudHNbZXZ0XSA9IGV2ZW50cy5sZW5ndGggPT09IDEgPyBldmVudHNbMF0gOiBldmVudHM7XG4gIH0gZWxzZSB7XG4gICAgZGVsZXRlIHRoaXMuX2V2ZW50c1tldnRdO1xuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFJlbW92ZSBhbGwgbGlzdGVuZXJzIG9yIG9ubHkgdGhlIGxpc3RlbmVycyBmb3IgdGhlIHNwZWNpZmllZCBldmVudC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZXZlbnQgVGhlIGV2ZW50IHdhbnQgdG8gcmVtb3ZlIGFsbCBsaXN0ZW5lcnMgZm9yLlxuICogQGFwaSBwdWJsaWNcbiAqL1xuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVBbGxMaXN0ZW5lcnMgPSBmdW5jdGlvbiByZW1vdmVBbGxMaXN0ZW5lcnMoZXZlbnQpIHtcbiAgaWYgKCF0aGlzLl9ldmVudHMpIHJldHVybiB0aGlzO1xuXG4gIGlmIChldmVudCkgZGVsZXRlIHRoaXMuX2V2ZW50c1twcmVmaXggPyBwcmVmaXggKyBldmVudCA6IGV2ZW50XTtcbiAgZWxzZSB0aGlzLl9ldmVudHMgPSBwcmVmaXggPyB7fSA6IE9iamVjdC5jcmVhdGUobnVsbCk7XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vL1xuLy8gQWxpYXMgbWV0aG9kcyBuYW1lcyBiZWNhdXNlIHBlb3BsZSByb2xsIGxpa2UgdGhhdC5cbi8vXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLm9mZiA9IEV2ZW50RW1pdHRlci5wcm90b3R5cGUucmVtb3ZlTGlzdGVuZXI7XG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyID0gRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbjtcblxuLy9cbi8vIFRoaXMgZnVuY3Rpb24gZG9lc24ndCBhcHBseSBhbnltb3JlLlxuLy9cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuc2V0TWF4TGlzdGVuZXJzID0gZnVuY3Rpb24gc2V0TWF4TGlzdGVuZXJzKCkge1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8vXG4vLyBFeHBvc2UgdGhlIHByZWZpeC5cbi8vXG5FdmVudEVtaXR0ZXIucHJlZml4ZWQgPSBwcmVmaXg7XG5cbi8vXG4vLyBFeHBvc2UgdGhlIG1vZHVsZS5cbi8vXG5pZiAoJ3VuZGVmaW5lZCcgIT09IHR5cGVvZiBtb2R1bGUpIHtcbiAgbW9kdWxlLmV4cG9ydHMgPSBFdmVudEVtaXR0ZXI7XG59XG4iLCIoZnVuY3Rpb24oKXt2YXIgZz17fTtcbihmdW5jdGlvbih3aW5kb3cpe3ZhciBrLGFhPXRoaXM7YWEuY2Q9ITA7ZnVuY3Rpb24gbShhLGIpe3ZhciBjPWEuc3BsaXQoXCIuXCIpLGQ9YWE7Y1swXWluIGR8fCFkLmV4ZWNTY3JpcHR8fGQuZXhlY1NjcmlwdChcInZhciBcIitjWzBdKTtmb3IodmFyIGU7Yy5sZW5ndGgmJihlPWMuc2hpZnQoKSk7KWMubGVuZ3RofHx2b2lkIDA9PT1iP2RbZV0/ZD1kW2VdOmQ9ZFtlXT17fTpkW2VdPWJ9ZnVuY3Rpb24gYmEoYSl7dmFyIGI9cDtmdW5jdGlvbiBjKCl7fWMucHJvdG90eXBlPWIucHJvdG90eXBlO2Eua2Q9Yi5wcm90b3R5cGU7YS5wcm90b3R5cGU9bmV3IGM7YS5wcm90b3R5cGUuY29uc3RydWN0b3I9YTthLmRkPWZ1bmN0aW9uKGEsYyxmKXtyZXR1cm4gYi5wcm90b3R5cGVbY10uYXBwbHkoYSxBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsMikpfX07LypcblxuIENvcHlyaWdodCAyMDE2IEdvb2dsZSBJbmMuXG5cbiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuKi9cbmZ1bmN0aW9uIGNhKGEpe3RoaXMuYz1NYXRoLmV4cChNYXRoLmxvZyguNSkvYSk7dGhpcy5iPXRoaXMuYT0wfWZ1bmN0aW9uIGRhKGEsYixjKXt2YXIgZD1NYXRoLnBvdyhhLmMsYik7YS5hPWMqKDEtZCkrZCphLmE7YS5iKz1ifWZ1bmN0aW9uIGVhKGEpe3JldHVybiBhLmEvKDEtTWF0aC5wb3coYS5jLGEuYikpfTtmdW5jdGlvbiBmYSgpe3RoaXMuYz1uZXcgY2EoMik7dGhpcy5mPW5ldyBjYSg1KTt0aGlzLmE9MDt0aGlzLmI9NUU1fWZ1bmN0aW9uIGdhKGEpe3JldHVybiAxMjhFMz5hLmE/YS5iOk1hdGgubWluKGVhKGEuYyksZWEoYS5mKSl9O2Z1bmN0aW9uIGhhKCl7fWZ1bmN0aW9uIGlhKCl7fTtmdW5jdGlvbiBqYSgpe3RoaXMuaD1udWxsO3RoaXMuZj0hMTt0aGlzLmI9bmV3IGZhO3RoaXMuZz17fTt0aGlzLmE9e307dGhpcy5pPSExO3RoaXMuYz1udWxsfW0oXCJzaGFrYS5hYnIuU2ltcGxlQWJyTWFuYWdlclwiLGphKTtrPWphLnByb3RvdHlwZTtrLnN0b3A9ZnVuY3Rpb24oKXt0aGlzLmg9bnVsbDt0aGlzLmY9ITE7dGhpcy5nPXt9O3RoaXMuYT17fTt0aGlzLmM9bnVsbH07ay5pbml0PWZ1bmN0aW9uKGEpe3RoaXMuaD1hfTtcbmsuY2hvb3NlU3RyZWFtcz1mdW5jdGlvbihhKXtmb3IodmFyIGIgaW4gYSl0aGlzLmdbYl09YVtiXTtiPXt9O2lmKFwiYXVkaW9cImluIGEpe3ZhciBjPWthKHRoaXMpO2M/KGIuYXVkaW89Yyx0aGlzLmEuYXVkaW89Yyk6ZGVsZXRlIHRoaXMuYS5hdWRpb31cInZpZGVvXCJpbiBhJiYoKGM9bGEodGhpcykpPyhiLnZpZGVvPWMsdGhpcy5hLnZpZGVvPWMpOmRlbGV0ZSB0aGlzLmEudmlkZW8pO1widGV4dFwiaW4gYSYmKGIudGV4dD1hLnRleHQuc3RyZWFtc1swXSk7dGhpcy5jPURhdGUubm93KCk7cmV0dXJuIGJ9O2suZW5hYmxlPWZ1bmN0aW9uKCl7dGhpcy5mPSEwfTtrLmRpc2FibGU9ZnVuY3Rpb24oKXt0aGlzLmY9ITF9O1xuay5zZWdtZW50RG93bmxvYWRlZD1mdW5jdGlvbihhLGIsYyl7dmFyIGQ9dGhpcy5iO2ItPWE7MTZFMz5jfHwoYT04RTMqYy9iLGIvPTFFMyxkLmErPWMsZGEoZC5jLGIsYSksZGEoZC5mLGIsYSkpO2lmKG51bGwhPXRoaXMuYyYmdGhpcy5mKWE6e2lmKCF0aGlzLmkpe2lmKCEoMTI4RTM8PXRoaXMuYi5hKSlicmVhayBhO3RoaXMuaT0hMH1lbHNlIGlmKDhFMz5EYXRlLm5vdygpLXRoaXMuYylicmVhayBhO2M9e307aWYoZD1rYSh0aGlzKSljLmF1ZGlvPWQsdGhpcy5hLmF1ZGlvPWQ7aWYoZD1sYSh0aGlzKSljLnZpZGVvPWQsdGhpcy5hLnZpZGVvPWQ7dGhpcy5jPURhdGUubm93KCk7dGhpcy5oKGMpfX07ay5nZXRCYW5kd2lkdGhFc3RpbWF0ZT1mdW5jdGlvbigpe3JldHVybiBnYSh0aGlzLmIpfTtrLnNldERlZmF1bHRFc3RpbWF0ZT1mdW5jdGlvbihhKXt0aGlzLmIuYj1hfTtcbmZ1bmN0aW9uIGthKGEpe2E9YS5nLmF1ZGlvO2lmKCFhKXJldHVybiBudWxsO2E9bWEoYSk7cmV0dXJuIGFbTWF0aC5mbG9vcihhLmxlbmd0aC8yKV19ZnVuY3Rpb24gbGEoYSl7dmFyIGI9YS5nLnZpZGVvO2lmKCFiKXJldHVybiBudWxsO3ZhciBiPW1hKGIpLGM9YS5hLmF1ZGlvLGM9YyYmYy5iYW5kd2lkdGh8fDA7YT1nYShhLmIpO2Zvcih2YXIgZD1iWzBdLGU9MDtlPGIubGVuZ3RoOysrZSl7dmFyIGY9YltlXSxnPWUrMTxiLmxlbmd0aD9iW2UrMV06e2JhbmR3aWR0aDpJbmZpbml0eX07Zi5iYW5kd2lkdGgmJihnPShnLmJhbmR3aWR0aCtjKS8uODUsYT49KGYuYmFuZHdpZHRoK2MpLy45NSYmYTw9ZyYmKGQ9ZikpfXJldHVybiBkfVxuZnVuY3Rpb24gbWEoYSl7cmV0dXJuIGEuc3RyZWFtcy5zbGljZSgwKS5maWx0ZXIoZnVuY3Rpb24oYSl7cmV0dXJuIGEuYWxsb3dlZEJ5QXBwbGljYXRpb24mJmEuYWxsb3dlZEJ5S2V5U3lzdGVtfSkuc29ydChmdW5jdGlvbihhLGMpe3JldHVybiBhLmJhbmR3aWR0aC1jLmJhbmR3aWR0aH0pfTt2YXIgbmE9L14oPzooW146Lz8jLl0rKTopPyg/OlxcL1xcLyg/OihbXi8/I10qKUApPyhbXi8jP10qPykoPzo6KFswLTldKykpPyg/PVsvIz9dfCQpKT8oW14/I10rKT8oPzpcXD8oW14jXSopKT8oPzojKC4qKSk/JC87ZnVuY3Rpb24gb2EoYSl7dmFyIGI7YSBpbnN0YW5jZW9mIG9hPyhwYSh0aGlzLGEuUiksdGhpcy5rYT1hLmthLHRoaXMuVD1hLlQscWEodGhpcyxhLndhKSx0aGlzLk89YS5PLHJhKHRoaXMsc2EoYS5hKSksdGhpcy5jYT1hLmNhKTphJiYoYj1TdHJpbmcoYSkubWF0Y2gobmEpKT8ocGEodGhpcyxiWzFdfHxcIlwiLCEwKSx0aGlzLmthPXRhKGJbMl18fFwiXCIpLHRoaXMuVD10YShiWzNdfHxcIlwiLCEwKSxxYSh0aGlzLGJbNF0pLHRoaXMuTz10YShiWzVdfHxcIlwiLCEwKSxyYSh0aGlzLGJbNl18fFwiXCIsITApLHRoaXMuY2E9dGEoYls3XXx8XCJcIikpOnRoaXMuYT1uZXcgdWEobnVsbCl9az1vYS5wcm90b3R5cGU7ay5SPVwiXCI7ay5rYT1cIlwiO2suVD1cIlwiO2sud2E9bnVsbDtrLk89XCJcIjtrLmNhPVwiXCI7XG5rLnRvU3RyaW5nPWZ1bmN0aW9uKCl7dmFyIGE9W10sYj10aGlzLlI7YiYmYS5wdXNoKHZhKGIsd2EsITApLFwiOlwiKTtpZihiPXRoaXMuVCl7YS5wdXNoKFwiLy9cIik7dmFyIGM9dGhpcy5rYTtjJiZhLnB1c2godmEoYyx3YSwhMCksXCJAXCIpO2EucHVzaChlbmNvZGVVUklDb21wb25lbnQoYikucmVwbGFjZSgvJTI1KFswLTlhLWZBLUZdezJ9KS9nLFwiJSQxXCIpKTtiPXRoaXMud2E7bnVsbCE9YiYmYS5wdXNoKFwiOlwiLFN0cmluZyhiKSl9aWYoYj10aGlzLk8pdGhpcy5UJiZcIi9cIiE9Yi5jaGFyQXQoMCkmJmEucHVzaChcIi9cIiksYS5wdXNoKHZhKGIsXCIvXCI9PWIuY2hhckF0KDApP3hhOnlhLCEwKSk7KGI9dGhpcy5hLnRvU3RyaW5nKCkpJiZhLnB1c2goXCI/XCIsYik7KGI9dGhpcy5jYSkmJmEucHVzaChcIiNcIix2YShiLHphKSk7cmV0dXJuIGEuam9pbihcIlwiKX07XG5rLnJlc29sdmU9ZnVuY3Rpb24oYSl7dmFyIGI9bmV3IG9hKHRoaXMpO1wiZGF0YVwiPT09Yi5SJiYoYj1uZXcgb2EpO3ZhciBjPSEhYS5SO2M/cGEoYixhLlIpOmM9ISFhLmthO2M/Yi5rYT1hLmthOmM9ISFhLlQ7Yz9iLlQ9YS5UOmM9bnVsbCE9YS53YTt2YXIgZD1hLk87aWYoYylxYShiLGEud2EpO2Vsc2UgaWYoYz0hIWEuTyl7aWYoXCIvXCIhPWQuY2hhckF0KDApKWlmKHRoaXMuVCYmIXRoaXMuTylkPVwiL1wiK2Q7ZWxzZXt2YXIgZT1iLk8ubGFzdEluZGV4T2YoXCIvXCIpOy0xIT1lJiYoZD1iLk8uc3Vic3RyKDAsZSsxKStkKX1pZihcIi4uXCI9PWR8fFwiLlwiPT1kKWQ9XCJcIjtlbHNlIGlmKC0xIT1kLmluZGV4T2YoXCIuL1wiKXx8LTEhPWQuaW5kZXhPZihcIi8uXCIpKXtmb3IodmFyIGU9IWQubGFzdEluZGV4T2YoXCIvXCIsMCksZD1kLnNwbGl0KFwiL1wiKSxmPVtdLGc9MDtnPGQubGVuZ3RoOyl7dmFyIGg9ZFtnKytdO1wiLlwiPT1oP2UmJmc9PWQubGVuZ3RoJiZmLnB1c2goXCJcIik6XCIuLlwiPT1oPygoMTxmLmxlbmd0aHx8XG4xPT1mLmxlbmd0aCYmXCJcIiE9ZlswXSkmJmYucG9wKCksZSYmZz09ZC5sZW5ndGgmJmYucHVzaChcIlwiKSk6KGYucHVzaChoKSxlPSEwKX1kPWYuam9pbihcIi9cIil9fWM/Yi5PPWQ6Yz1cIlwiIT09YS5hLnRvU3RyaW5nKCk7Yz9yYShiLHNhKGEuYSkpOmM9ISFhLmNhO2MmJihiLmNhPWEuY2EpO3JldHVybiBifTtmdW5jdGlvbiBwYShhLGIsYyl7YS5SPWM/dGEoYiwhMCk6YjthLlImJihhLlI9YS5SLnJlcGxhY2UoLzokLyxcIlwiKSl9ZnVuY3Rpb24gcWEoYSxiKXtpZihiKXtiPU51bWJlcihiKTtpZihpc05hTihiKXx8MD5iKXRocm93IEVycm9yKFwiQmFkIHBvcnQgbnVtYmVyIFwiK2IpO2Eud2E9Yn1lbHNlIGEud2E9bnVsbH1mdW5jdGlvbiByYShhLGIsYyl7YiBpbnN0YW5jZW9mIHVhP2EuYT1iOihjfHwoYj12YShiLEFhKSksYS5hPW5ldyB1YShiKSl9ZnVuY3Rpb24gdGEoYSxiKXtyZXR1cm4gYT9iP2RlY29kZVVSSShhKTpkZWNvZGVVUklDb21wb25lbnQoYSk6XCJcIn1cbmZ1bmN0aW9uIHZhKGEsYixjKXtyZXR1cm5cInN0cmluZ1wiPT10eXBlb2YgYT8oYT1lbmNvZGVVUkkoYSkucmVwbGFjZShiLEJhKSxjJiYoYT1hLnJlcGxhY2UoLyUyNShbMC05YS1mQS1GXXsyfSkvZyxcIiUkMVwiKSksYSk6bnVsbH1mdW5jdGlvbiBCYShhKXthPWEuY2hhckNvZGVBdCgwKTtyZXR1cm5cIiVcIisoYT4+NCYxNSkudG9TdHJpbmcoMTYpKyhhJjE1KS50b1N0cmluZygxNil9dmFyIHdhPS9bI1xcL1xcP0BdL2cseWE9L1tcXCNcXD86XS9nLHhhPS9bXFwjXFw/XS9nLEFhPS9bXFwjXFw/QF0vZyx6YT0vIy9nO2Z1bmN0aW9uIHVhKGEpe3RoaXMuYj1hfHxudWxsfXVhLnByb3RvdHlwZS5hPW51bGw7dWEucHJvdG90eXBlLmM9bnVsbDtcbnVhLnByb3RvdHlwZS50b1N0cmluZz1mdW5jdGlvbigpe2lmKHRoaXMuYilyZXR1cm4gdGhpcy5iO2lmKCF0aGlzLmEpcmV0dXJuXCJcIjt2YXIgYT1bXSxiO2ZvcihiIGluIHRoaXMuYSlmb3IodmFyIGM9ZW5jb2RlVVJJQ29tcG9uZW50KGIpLGQ9dGhpcy5hW2JdLGU9MDtlPGQubGVuZ3RoO2UrKyl7dmFyIGY9YztcIlwiIT09ZFtlXSYmKGYrPVwiPVwiK2VuY29kZVVSSUNvbXBvbmVudChkW2VdKSk7YS5wdXNoKGYpfXJldHVybiB0aGlzLmI9YS5qb2luKFwiJlwiKX07ZnVuY3Rpb24gc2EoYSl7dmFyIGI9bmV3IHVhO2IuYj1hLmI7aWYoYS5hKXt2YXIgYz17fSxkO2ZvcihkIGluIGEuYSljW2RdPWEuYVtkXS5jb25jYXQoKTtiLmE9YztiLmM9YS5jfXJldHVybiBifTtmdW5jdGlvbiBxKGEsYixjKXt0aGlzLmNhdGVnb3J5PWE7dGhpcy5jb2RlPWI7dGhpcy5kYXRhPUFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywyKX1tKFwic2hha2EudXRpbC5FcnJvclwiLHEpO3EucHJvdG90eXBlLnRvU3RyaW5nPWZ1bmN0aW9uKCl7cmV0dXJuXCJzaGFrYS51dGlsLkVycm9yIFwiK0pTT04uc3RyaW5naWZ5KHRoaXMsbnVsbCxcIiAgXCIpfTtxLkNhdGVnb3J5PXtORVRXT1JLOjEsVEVYVDoyLE1FRElBOjMsTUFOSUZFU1Q6NCxTVFJFQU1JTkc6NSxEUk06NixQTEFZRVI6NyxDQVNUOjgsU1RPUkFHRTo5fTtcbnEuQ29kZT17VU5TVVBQT1JURURfU0NIRU1FOjFFMyxCQURfSFRUUF9TVEFUVVM6MTAwMSxIVFRQX0VSUk9SOjEwMDIsVElNRU9VVDoxMDAzLE1BTEZPUk1FRF9EQVRBX1VSSToxMDA0LFVOS05PV05fREFUQV9VUklfRU5DT0RJTkc6MTAwNSxJTlZBTElEX1RFWFRfSEVBREVSOjJFMyxJTlZBTElEX1RFWFRfQ1VFOjIwMDEsVU5BQkxFX1RPX0RFVEVDVF9FTkNPRElORzoyMDAzLEJBRF9FTkNPRElORzoyMDA0LElOVkFMSURfWE1MOjIwMDUsSU5WQUxJRF9UVE1MOjIwMDYsSU5WQUxJRF9NUDRfVFRNTDoyMDA3LElOVkFMSURfTVA0X1ZUVDoyMDA4LEJVRkZFUl9SRUFEX09VVF9PRl9CT1VORFM6M0UzLEpTX0lOVEVHRVJfT1ZFUkZMT1c6MzAwMSxFQk1MX09WRVJGTE9XOjMwMDIsRUJNTF9CQURfRkxPQVRJTkdfUE9JTlRfU0laRTozMDAzLE1QNF9TSURYX1dST05HX0JPWF9UWVBFOjMwMDQsTVA0X1NJRFhfSU5WQUxJRF9USU1FU0NBTEU6MzAwNSxNUDRfU0lEWF9UWVBFX05PVF9TVVBQT1JURUQ6MzAwNixcbldFQk1fQ1VFU19FTEVNRU5UX01JU1NJTkc6MzAwNyxXRUJNX0VCTUxfSEVBREVSX0VMRU1FTlRfTUlTU0lORzozMDA4LFdFQk1fU0VHTUVOVF9FTEVNRU5UX01JU1NJTkc6MzAwOSxXRUJNX0lORk9fRUxFTUVOVF9NSVNTSU5HOjMwMTAsV0VCTV9EVVJBVElPTl9FTEVNRU5UX01JU1NJTkc6MzAxMSxXRUJNX0NVRV9UUkFDS19QT1NJVElPTlNfRUxFTUVOVF9NSVNTSU5HOjMwMTIsV0VCTV9DVUVfVElNRV9FTEVNRU5UX01JU1NJTkc6MzAxMyxNRURJQV9TT1VSQ0VfT1BFUkFUSU9OX0ZBSUxFRDozMDE0LE1FRElBX1NPVVJDRV9PUEVSQVRJT05fVEhSRVc6MzAxNSxWSURFT19FUlJPUjozMDE2LFFVT1RBX0VYQ0VFREVEX0VSUk9SOjMwMTcsVU5BQkxFX1RPX0dVRVNTX01BTklGRVNUX1RZUEU6NEUzLERBU0hfSU5WQUxJRF9YTUw6NDAwMSxEQVNIX05PX1NFR01FTlRfSU5GTzo0MDAyLERBU0hfRU1QVFlfQURBUFRBVElPTl9TRVQ6NDAwMyxEQVNIX0VNUFRZX1BFUklPRDo0MDA0LERBU0hfV0VCTV9NSVNTSU5HX0lOSVQ6NDAwNSxcbkRBU0hfVU5TVVBQT1JURURfQ09OVEFJTkVSOjQwMDYsREFTSF9QU1NIX0JBRF9FTkNPRElORzo0MDA3LERBU0hfTk9fQ09NTU9OX0tFWV9TWVNURU06NDAwOCxEQVNIX01VTFRJUExFX0tFWV9JRFNfTk9UX1NVUFBPUlRFRDo0MDA5LERBU0hfQ09ORkxJQ1RJTkdfS0VZX0lEUzo0MDEwLFVOUExBWUFCTEVfUEVSSU9EOjQwMTEsUkVTVFJJQ1RJT05TX0NBTk5PVF9CRV9NRVQ6NDAxMixJTlZBTElEX1NUUkVBTVNfQ0hPU0VOOjUwMDUsTk9fUkVDT0dOSVpFRF9LRVlfU1lTVEVNUzo2RTMsUkVRVUVTVEVEX0tFWV9TWVNURU1fQ09ORklHX1VOQVZBSUxBQkxFOjYwMDEsRkFJTEVEX1RPX0NSRUFURV9DRE06NjAwMixGQUlMRURfVE9fQVRUQUNIX1RPX1ZJREVPOjYwMDMsSU5WQUxJRF9TRVJWRVJfQ0VSVElGSUNBVEU6NjAwNCxGQUlMRURfVE9fQ1JFQVRFX1NFU1NJT046NjAwNSxGQUlMRURfVE9fR0VORVJBVEVfTElDRU5TRV9SRVFVRVNUOjYwMDYsTElDRU5TRV9SRVFVRVNUX0ZBSUxFRDo2MDA3LFxuTElDRU5TRV9SRVNQT05TRV9SRUpFQ1RFRDo2MDA4LEVOQ1JZUFRFRF9DT05URU5UX1dJVEhPVVRfRFJNX0lORk86NjAxMCxOT19MSUNFTlNFX1NFUlZFUl9HSVZFTjo2MDEyLE9GRkxJTkVfU0VTU0lPTl9SRU1PVkVEOjYwMTMsRVhQSVJFRDo2MDE0LExPQURfSU5URVJSVVBURUQ6N0UzLENBU1RfQVBJX1VOQVZBSUxBQkxFOjhFMyxOT19DQVNUX1JFQ0VJVkVSUzo4MDAxLEFMUkVBRFlfQ0FTVElORzo4MDAyLFVORVhQRUNURURfQ0FTVF9FUlJPUjo4MDAzLENBU1RfQ0FOQ0VMRURfQllfVVNFUjo4MDA0LENBU1RfQ09OTkVDVElPTl9USU1FRF9PVVQ6ODAwNSxDQVNUX1JFQ0VJVkVSX0FQUF9VTkFWQUlMQUJMRTo4MDA2LElOREVYRURfREJfTk9UX1NVUFBPUlRFRDo5RTMsSU5ERVhFRF9EQl9FUlJPUjo5MDAxLE9QRVJBVElPTl9BQk9SVEVEOjkwMDIsUkVRVUVTVEVEX0lURU1fTk9UX0ZPVU5EOjkwMDMsTUFMRk9STUVEX09GRkxJTkVfVVJJOjkwMDQsQ0FOTk9UX1NUT1JFX0xJVkVfT0ZGTElORTo5MDA1LFxuU1RPUkVfQUxSRUFEWV9JTl9QUk9HUkVTUzo5MDA2LE5PX0lOSVRfREFUQV9GT1JfT0ZGTElORTo5MDA3fTtmdW5jdGlvbiBDYShhLGIpe3JldHVybiBhLnJlZHVjZShmdW5jdGlvbihhLGIsZSl7cmV0dXJuIGJbXCJjYXRjaFwiXShhLmJpbmQobnVsbCxlKSl9LmJpbmQobnVsbCxiKSxQcm9taXNlLnJlamVjdCgpKX1mdW5jdGlvbiB1KGEsYil7cmV0dXJuIGEuY29uY2F0KGIpfWZ1bmN0aW9uIHYoKXt9ZnVuY3Rpb24gRGEoYSl7cmV0dXJuIG51bGwhPWF9ZnVuY3Rpb24gRWEoYSl7cmV0dXJuIGZ1bmN0aW9uKGIpe3JldHVybiBiIT1hfX07ZnVuY3Rpb24gdygpe3ZhciBhLGIsYz1uZXcgUHJvbWlzZShmdW5jdGlvbihjLGUpe2E9YztiPWV9KTtjLnJlc29sdmU9YTtjLnJlamVjdD1iO3JldHVybiBjfTtmdW5jdGlvbiB5KGEpe3RoaXMuZj0hMTt0aGlzLmE9W107dGhpcy5iPVtdO3RoaXMuYz1bXTt0aGlzLmg9YXx8bnVsbH1tKFwic2hha2EubmV0Lk5ldHdvcmtpbmdFbmdpbmUuUmVxdWVzdFR5cGVcIix7TUFOSUZFU1Q6MCxTRUdNRU5UOjEsTElDRU5TRToyfSk7dmFyIEZhPXt9O20oXCJzaGFrYS5uZXQuTmV0d29ya2luZ0VuZ2luZS5yZWdpc3RlclNjaGVtZVwiLGZ1bmN0aW9uKGEsYil7RmFbYV09Yn0pO20oXCJzaGFrYS5uZXQuTmV0d29ya2luZ0VuZ2luZS51bnJlZ2lzdGVyU2NoZW1lXCIsZnVuY3Rpb24oYSl7ZGVsZXRlIEZhW2FdfSk7eS5wcm90b3R5cGUud2M9ZnVuY3Rpb24oYSl7dGhpcy5iLnB1c2goYSl9O3kucHJvdG90eXBlLnJlZ2lzdGVyUmVxdWVzdEZpbHRlcj15LnByb3RvdHlwZS53Yzt5LnByb3RvdHlwZS5ZYz1mdW5jdGlvbihhKXt2YXIgYj10aGlzLmI7YT1iLmluZGV4T2YoYSk7MDw9YSYmYi5zcGxpY2UoYSwxKX07XG55LnByb3RvdHlwZS51bnJlZ2lzdGVyUmVxdWVzdEZpbHRlcj15LnByb3RvdHlwZS5ZYzt5LnByb3RvdHlwZS5NYj1mdW5jdGlvbigpe3RoaXMuYj1bXX07eS5wcm90b3R5cGUuY2xlYXJBbGxSZXF1ZXN0RmlsdGVycz15LnByb3RvdHlwZS5NYjt5LnByb3RvdHlwZS52Yj1mdW5jdGlvbihhKXt0aGlzLmMucHVzaChhKX07eS5wcm90b3R5cGUucmVnaXN0ZXJSZXNwb25zZUZpbHRlcj15LnByb3RvdHlwZS52Yjt5LnByb3RvdHlwZS5HYj1mdW5jdGlvbihhKXt2YXIgYj10aGlzLmM7YT1iLmluZGV4T2YoYSk7MDw9YSYmYi5zcGxpY2UoYSwxKX07eS5wcm90b3R5cGUudW5yZWdpc3RlclJlc3BvbnNlRmlsdGVyPXkucHJvdG90eXBlLkdiO3kucHJvdG90eXBlLk5iPWZ1bmN0aW9uKCl7dGhpcy5jPVtdfTt5LnByb3RvdHlwZS5jbGVhckFsbFJlc3BvbnNlRmlsdGVycz15LnByb3RvdHlwZS5OYjtcbmZ1bmN0aW9uIEdhKCl7cmV0dXJue21heEF0dGVtcHRzOjIsYmFzZURlbGF5OjFFMyxiYWNrb2ZmRmFjdG9yOjIsZnV6ekZhY3RvcjouNSx0aW1lb3V0OjB9fWZ1bmN0aW9uIEhhKGEsYil7cmV0dXJue3VyaXM6YSxtZXRob2Q6XCJHRVRcIixib2R5Om51bGwsaGVhZGVyczp7fSxhbGxvd0Nyb3NzU2l0ZUNyZWRlbnRpYWxzOiExLHJldHJ5UGFyYW1ldGVyczpifX15LnByb3RvdHlwZS5vPWZ1bmN0aW9uKCl7dGhpcy5mPSEwO3RoaXMuYj1bXTt0aGlzLmM9W107Zm9yKHZhciBhPVtdLGI9MDtiPHRoaXMuYS5sZW5ndGg7KytiKWEucHVzaCh0aGlzLmFbYl1bXCJjYXRjaFwiXSh2KSk7cmV0dXJuIFByb21pc2UuYWxsKGEpfTtcbnkucHJvdG90eXBlLnJlcXVlc3Q9ZnVuY3Rpb24oYSxiKXtpZih0aGlzLmYpcmV0dXJuIFByb21pc2UucmVqZWN0KCk7Zm9yKHZhciBjPURhdGUubm93KCksZD10aGlzLmIsZT0wO2U8ZC5sZW5ndGg7ZSsrKXRyeXtkW2VdKGEsYil9Y2F0Y2gobCl7cmV0dXJuIFByb21pc2UucmVqZWN0KGwpfWZvcih2YXIgZT1iLnJldHJ5UGFyYW1ldGVyc3x8e30sZD1lLm1heEF0dGVtcHRzfHwxLGY9ZS5iYWNrb2ZmRmFjdG9yfHwyLGc9bnVsbD09ZS5iYXNlRGVsYXk/MUUzOmUuYmFzZURlbGF5LGg9dGhpcy5nKGEsYiwwKSxlPTE7ZTxkO2UrKyloPWhbXCJjYXRjaFwiXSh0aGlzLmkuYmluZCh0aGlzLGEsYixnLGUlYi51cmlzLmxlbmd0aCkpLGcqPWY7dGhpcy5hLnB1c2goaCk7cmV0dXJuIGgudGhlbihmdW5jdGlvbihiKXt0aGlzLmEuc3BsaWNlKHRoaXMuYS5pbmRleE9mKGgpLDEpO3ZhciBkPURhdGUubm93KCk7dGhpcy5oJiYxPT1hJiZ0aGlzLmgoYyxkLGIuZGF0YS5ieXRlTGVuZ3RoKTtyZXR1cm4gYn0uYmluZCh0aGlzKSlbXCJjYXRjaFwiXShmdW5jdGlvbihhKXt0aGlzLmEuc3BsaWNlKHRoaXMuYS5pbmRleE9mKGgpLFxuMSk7cmV0dXJuIFByb21pc2UucmVqZWN0KGEpfS5iaW5kKHRoaXMpKX07eS5wcm90b3R5cGUucmVxdWVzdD15LnByb3RvdHlwZS5yZXF1ZXN0O3kucHJvdG90eXBlLmc9ZnVuY3Rpb24oYSxiLGMpe2lmKHRoaXMuZilyZXR1cm4gUHJvbWlzZS5yZWplY3QoKTt2YXIgZD1uZXcgb2EoYi51cmlzW2NdKSxlPWQuUjtlfHwoZT1sb2NhdGlvbi5wcm90b2NvbCxlPWUuc2xpY2UoMCwtMSkscGEoZCxlKSxiLnVyaXNbY109ZC50b1N0cmluZygpKTtyZXR1cm4oZT1GYVtlXSk/ZShiLnVyaXNbY10sYikudGhlbihmdW5jdGlvbihiKXtmb3IodmFyIGM9dGhpcy5jLGQ9MDtkPGMubGVuZ3RoO2QrKyljW2RdKGEsYik7cmV0dXJuIGJ9LmJpbmQodGhpcykpOlByb21pc2UucmVqZWN0KG5ldyBxKDEsMUUzLGQpKX07XG55LnByb3RvdHlwZS5pPWZ1bmN0aW9uKGEsYixjLGQpe3ZhciBlPW5ldyB3LGY9Yi5yZXRyeVBhcmFtZXRlcnN8fHt9O3dpbmRvdy5zZXRUaW1lb3V0KGUucmVzb2x2ZSxjKigxKygyKk1hdGgucmFuZG9tKCktMSkqKG51bGw9PWYuZnV6ekZhY3Rvcj8uNTpmLmZ1enpGYWN0b3IpKSk7cmV0dXJuIGUudGhlbih0aGlzLmcuYmluZCh0aGlzLGEsYixkKSl9O2Z1bmN0aW9uIElhKGEsYixjKXtmb3IodmFyIGQ9MDtkPGEubGVuZ3RoOysrZClpZihjKGFbZF0sYikpcmV0dXJuIGQ7cmV0dXJuLTF9O2Z1bmN0aW9uIEphKCl7dGhpcy5hPXt9fWs9SmEucHJvdG90eXBlO2sucHVzaD1mdW5jdGlvbihhLGIpe3RoaXMuYS5oYXNPd25Qcm9wZXJ0eShhKT90aGlzLmFbYV0ucHVzaChiKTp0aGlzLmFbYV09W2JdfTtrLnNldD1mdW5jdGlvbihhLGIpe3RoaXMuYVthXT1ifTtrLmhhcz1mdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLmhhc093blByb3BlcnR5KGEpfTtrLmdldD1mdW5jdGlvbihhKXtyZXR1cm4oYT10aGlzLmFbYV0pP2Euc2xpY2UoKTpudWxsfTtrLnJlbW92ZT1mdW5jdGlvbihhLGIpe3ZhciBjPXRoaXMuYVthXTtpZihjKWZvcih2YXIgZD0wO2Q8Yy5sZW5ndGg7KytkKWNbZF09PWImJihjLnNwbGljZShkLDEpLC0tZCl9O2sua2V5cz1mdW5jdGlvbigpe3ZhciBhPVtdLGI7Zm9yKGIgaW4gdGhpcy5hKWEucHVzaChiKTtyZXR1cm4gYX07ZnVuY3Rpb24geigpe3RoaXMuYT1uZXcgSmF9ei5wcm90b3R5cGUubz1mdW5jdGlvbigpe0thKHRoaXMpO3RoaXMuYT1udWxsO3JldHVybiBQcm9taXNlLnJlc29sdmUoKX07ZnVuY3Rpb24gQihhLGIsYyxkKXtiPW5ldyBMYShiLGMsZCk7YS5hLnB1c2goYyxiKX16LnByb3RvdHlwZS5qYT1mdW5jdGlvbihhLGIpe2Zvcih2YXIgYz10aGlzLmEuZ2V0KGIpfHxbXSxkPTA7ZDxjLmxlbmd0aDsrK2Qpe3ZhciBlPWNbZF07ZS50YXJnZXQ9PWEmJihlLmphKCksdGhpcy5hLnJlbW92ZShiLGUpKX19O2Z1bmN0aW9uIEthKGEpe3ZhciBiPWEuYSxjPVtdLGQ7Zm9yKGQgaW4gYi5hKWMucHVzaC5hcHBseShjLGIuYVtkXSk7Zm9yKGI9MDtiPGMubGVuZ3RoOysrYiljW2JdLmphKCk7YS5hLmE9e319ZnVuY3Rpb24gTGEoYSxiLGMpe3RoaXMudGFyZ2V0PWE7dGhpcy50eXBlPWI7dGhpcy5hPWM7dGhpcy50YXJnZXQuYWRkRXZlbnRMaXN0ZW5lcihiLGMsITEpfVxuTGEucHJvdG90eXBlLmphPWZ1bmN0aW9uKCl7dGhpcy50YXJnZXQmJih0aGlzLnRhcmdldC5yZW1vdmVFdmVudExpc3RlbmVyKHRoaXMudHlwZSx0aGlzLmEsITEpLHRoaXMuYT10aGlzLnRhcmdldD1udWxsKX07ZnVuY3Rpb24gTWEoYSl7cmV0dXJuIWF8fCFPYmplY3Qua2V5cyhhKS5sZW5ndGh9ZnVuY3Rpb24gQyhhKXtyZXR1cm4gT2JqZWN0LmtleXMoYSkubWFwKGZ1bmN0aW9uKGIpe3JldHVybiBhW2JdfSl9ZnVuY3Rpb24gTmEoYSxiKXtyZXR1cm4gT2JqZWN0LmtleXMoYSkucmVkdWNlKGZ1bmN0aW9uKGMsZCl7Y1tkXT1iKGFbZF0sZCk7cmV0dXJuIGN9LHt9KX1mdW5jdGlvbiBPYShhLGIpe3JldHVybiBPYmplY3Qua2V5cyhhKS5ldmVyeShmdW5jdGlvbihjKXtyZXR1cm4gYihjLGFbY10pfSl9O2Z1bmN0aW9uIEQoYSl7aWYoIWEpcmV0dXJuXCJcIjthPW5ldyBVaW50OEFycmF5KGEpOzIzOT09YVswXSYmMTg3PT1hWzFdJiYxOTE9PWFbMl0mJihhPWEuc3ViYXJyYXkoMykpO2E9ZXNjYXBlKFBhKGEpKTt0cnl7cmV0dXJuIGRlY29kZVVSSUNvbXBvbmVudChhKX1jYXRjaChiKXt0aHJvdyBuZXcgcSgyLDIwMDQpO319ZnVuY3Rpb24gUWEoYSxiKXtpZighYSlyZXR1cm5cIlwiO2lmKGEuYnl0ZUxlbmd0aCUyKXRocm93IG5ldyBxKDIsMjAwNCk7dmFyIGM7aWYoYSBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKWM9YTtlbHNle3ZhciBkPW5ldyBVaW50OEFycmF5KGEuYnl0ZUxlbmd0aCk7ZC5zZXQobmV3IFVpbnQ4QXJyYXkoYSkpO2M9ZC5idWZmZXJ9dmFyIGQ9YS5ieXRlTGVuZ3RoLzIsZT1uZXcgVWludDE2QXJyYXkoZCk7Yz1uZXcgRGF0YVZpZXcoYyk7Zm9yKHZhciBmPTA7ZjxkO2YrKyllW2ZdPWMuZ2V0VWludDE2KDIqZixiKTtyZXR1cm4gUGEoZSl9XG5mdW5jdGlvbiBSYShhKXt2YXIgYj1uZXcgVWludDhBcnJheShhKTtpZigyMzk9PWJbMF0mJjE4Nz09YlsxXSYmMTkxPT1iWzJdKXJldHVybiBEKGIpO2lmKDI1ND09YlswXSYmMjU1PT1iWzFdKXJldHVybiBRYShiLnN1YmFycmF5KDIpLCExKTtpZigyNTU9PWJbMF0mJjI1ND09YlsxXSlyZXR1cm4gUWEoYi5zdWJhcnJheSgyKSwhMCk7dmFyIGM9ZnVuY3Rpb24oYSxiKXtyZXR1cm4gYS5ieXRlTGVuZ3RoPD1ifHwzMjw9YVtiXSYmMTI2Pj1hW2JdfS5iaW5kKG51bGwsYik7aWYoYlswXXx8YlsyXSl7aWYoIWJbMV0mJiFiWzNdKXJldHVybiBRYShhLCEwKTtpZihjKDApJiZjKDEpJiZjKDIpJiZjKDMpKXJldHVybiBEKGEpfWVsc2UgcmV0dXJuIFFhKGEsITEpO3Rocm93IG5ldyBxKDIsMjAwMyk7fVxuZnVuY3Rpb24gU2EoYSl7YT11bmVzY2FwZShlbmNvZGVVUklDb21wb25lbnQoYSkpO2Zvcih2YXIgYj1uZXcgVWludDhBcnJheShhLmxlbmd0aCksYz0wO2M8YS5sZW5ndGg7KytjKWJbY109YS5jaGFyQ29kZUF0KGMpO3JldHVybiBiLmJ1ZmZlcn1mdW5jdGlvbiBQYShhKXtmb3IodmFyIGI9XCJcIixjPTA7YzxhLmxlbmd0aDtjKz0xNkUzKWIrPVN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCxhLnN1YmFycmF5KGMsYysxNkUzKSk7cmV0dXJuIGJ9O2Z1bmN0aW9uIFRhKGEpe3RoaXMuYT1udWxsO3RoaXMuYj1mdW5jdGlvbigpe3RoaXMuYT1udWxsO2EoKX0uYmluZCh0aGlzKX1mdW5jdGlvbiBVYShhKXtudWxsIT1hLmEmJihjbGVhclRpbWVvdXQoYS5hKSxhLmE9bnVsbCl9ZnVuY3Rpb24gVmEoYSl7VWEoYSk7YS5hPXNldFRpbWVvdXQoYS5iLDEwMCl9O2Z1bmN0aW9uIFdhKGEpe3JldHVybiB3aW5kb3cuYnRvYShTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsYSkpLnJlcGxhY2UoL1xcKy9nLFwiLVwiKS5yZXBsYWNlKC9cXC8vZyxcIl9cIikucmVwbGFjZSgvPSokLyxcIlwiKX1mdW5jdGlvbiBYYShhKXthPXdpbmRvdy5hdG9iKGEucmVwbGFjZSgvLS9nLFwiK1wiKS5yZXBsYWNlKC9fL2csXCIvXCIpKTtmb3IodmFyIGI9bmV3IFVpbnQ4QXJyYXkoYS5sZW5ndGgpLGM9MDtjPGEubGVuZ3RoOysrYyliW2NdPWEuY2hhckNvZGVBdChjKTtyZXR1cm4gYn1mdW5jdGlvbiBZYShhKXtmb3IodmFyIGI9bmV3IFVpbnQ4QXJyYXkoYS5sZW5ndGgvMiksYz0wO2M8YS5sZW5ndGg7Yys9MiliW2MvMl09d2luZG93LnBhcnNlSW50KGEuc3Vic3RyKGMsMiksMTYpO3JldHVybiBifVxuZnVuY3Rpb24gWmEoYSl7Zm9yKHZhciBiPVwiXCIsYz0wO2M8YS5sZW5ndGg7KytjKXt2YXIgZD1hW2NdLnRvU3RyaW5nKDE2KTsxPT1kLmxlbmd0aCYmKGQ9XCIwXCIrZCk7Yis9ZH1yZXR1cm4gYn1mdW5jdGlvbiAkYShhLGIpe2lmKCFhJiYhYilyZXR1cm4hMDtpZighYXx8IWJ8fGEubGVuZ3RoIT1iLmxlbmd0aClyZXR1cm4hMTtmb3IodmFyIGM9MDtjPGEubGVuZ3RoOysrYylpZihhW2NdIT1iW2NdKXJldHVybiExO3JldHVybiEwfTtmdW5jdGlvbiBhYihhLGIsYyl7dGhpcy5sPXRoaXMuaD10aGlzLm09bnVsbDt0aGlzLkE9ITE7dGhpcy5iPW51bGw7dGhpcy5mPW5ldyB6O3RoaXMuYT1bXTt0aGlzLnM9W107dGhpcy5qPW5ldyB3O3RoaXMuRz1hO3RoaXMuaT1udWxsO3RoaXMuZz1mdW5jdGlvbihhKXt0aGlzLmoucmVqZWN0KGEpO2IoYSl9LmJpbmQodGhpcyk7dGhpcy53PXt9O3RoaXMuSj1jO3RoaXMudj1uZXcgVGEodGhpcy52Yy5iaW5kKHRoaXMpKTt0aGlzLkM9dGhpcy5jPSExO3RoaXMualtcImNhdGNoXCJdKGZ1bmN0aW9uKCl7fSl9az1hYi5wcm90b3R5cGU7XG5rLm89ZnVuY3Rpb24oKXt0aGlzLmM9ITA7dmFyIGE9dGhpcy5hLm1hcChmdW5jdGlvbihhKXthLnlhLmNsb3NlKClbXCJjYXRjaFwiXSh2KTtyZXR1cm4gYS55YS5jbG9zZWR9KTt0aGlzLmoucmVqZWN0KCk7dGhpcy5mJiZhLnB1c2godGhpcy5mLm8oKSk7dGhpcy5sJiZhLnB1c2godGhpcy5sLnNldE1lZGlhS2V5cyhudWxsKVtcImNhdGNoXCJdKHYpKTt0aGlzLnYmJlVhKHRoaXMudik7dGhpcy5mPXRoaXMubD10aGlzLmg9dGhpcy5tPXRoaXMuYj10aGlzLnY9bnVsbDt0aGlzLmE9W107dGhpcy5zPVtdO3RoaXMuZz10aGlzLmk9dGhpcy5HPW51bGw7cmV0dXJuIFByb21pc2UuYWxsKGEpfTtrLmNvbmZpZ3VyZT1mdW5jdGlvbihhKXt0aGlzLmk9YX07XG5rLmluaXQ9ZnVuY3Rpb24oYSxiKXt2YXIgYz17fSxkPVtdO3RoaXMuQz1iO3RoaXMucz1hLm9mZmxpbmVTZXNzaW9uSWRzO2JiKHRoaXMsYSxifHwwPGEub2ZmbGluZVNlc3Npb25JZHMubGVuZ3RoLGMsZCk7cmV0dXJuIGQubGVuZ3RoP2NiKHRoaXMsYyxkKToodGhpcy5BPSEwLFByb21pc2UucmVzb2x2ZSgpKX07XG5mdW5jdGlvbiBkYihhLGIpe2lmKCFhLmgpcmV0dXJuIEIoYS5mLGIsXCJlbmNyeXB0ZWRcIixmdW5jdGlvbigpe3RoaXMuZi5qYShiLFwiZW5jcnlwdGVkXCIpO3RoaXMuZyhuZXcgcSg2LDYwMTApKX0uYmluZChhKSksUHJvbWlzZS5yZXNvbHZlKCk7YS5sPWI7dmFyIGM9YS5sLnNldE1lZGlhS2V5cyhhLmgpLGM9Y1tcImNhdGNoXCJdKGZ1bmN0aW9uKGEpe3JldHVybiBQcm9taXNlLnJlamVjdChuZXcgcSg2LDYwMDMsYS5tZXNzYWdlKSl9KSxkPW51bGw7YS5iLnNlcnZlckNlcnRpZmljYXRlJiYoZD1hLmguc2V0U2VydmVyQ2VydGlmaWNhdGUoYS5iLnNlcnZlckNlcnRpZmljYXRlKSxkPWRbXCJjYXRjaFwiXShmdW5jdGlvbihhKXtyZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IHEoNiw2MDA0LGEubWVzc2FnZSkpfSkpO3JldHVybiBQcm9taXNlLmFsbChbYyxkXSkudGhlbihmdW5jdGlvbigpe2lmKHRoaXMuYylyZXR1cm4gUHJvbWlzZS5yZWplY3QoKTtlYih0aGlzKTt0aGlzLmIuaW5pdERhdGEubGVuZ3RofHxcbnRoaXMucy5sZW5ndGh8fEIodGhpcy5mLHRoaXMubCxcImVuY3J5cHRlZFwiLHRoaXMuYmMuYmluZCh0aGlzKSl9LmJpbmQoYSkpW1wiY2F0Y2hcIl0oZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYz9Qcm9taXNlLnJlc29sdmUoKTpQcm9taXNlLnJlamVjdChhKX0uYmluZChhKSl9ZnVuY3Rpb24gZmIoYSxiKXtyZXR1cm4gUHJvbWlzZS5hbGwoYi5tYXAoZnVuY3Rpb24oYSl7cmV0dXJuIGdiKHRoaXMsYSkudGhlbihmdW5jdGlvbihhKXtpZihhKXJldHVybiBhLnJlbW92ZSgpfSl9LmJpbmQoYSkpKX1mdW5jdGlvbiBlYihhKXt2YXIgYj1hLmI/YS5iLmluaXREYXRhOltdO2IuZm9yRWFjaChmdW5jdGlvbihhKXtoYih0aGlzLGEuaW5pdERhdGFUeXBlLGEuaW5pdERhdGEpfS5iaW5kKGEpKTthLnMuZm9yRWFjaChmdW5jdGlvbihhKXtnYih0aGlzLGEpfS5iaW5kKGEpKTtiLmxlbmd0aHx8YS5zLmxlbmd0aHx8YS5qLnJlc29sdmUoKTtyZXR1cm4gYS5qfVxuay5rZXlTeXN0ZW09ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5iP3RoaXMuYi5rZXlTeXN0ZW06XCJcIn07ZnVuY3Rpb24gaWIoYSl7cmV0dXJuIGEuYS5tYXAoZnVuY3Rpb24oYSl7cmV0dXJuIGEueWEuc2Vzc2lvbklkfSl9XG5mdW5jdGlvbiBiYihhLGIsYyxkLGUpe3ZhciBmPWpiKGEpLGc9MDw9bmF2aWdhdG9yLnVzZXJBZ2VudC5pbmRleE9mKFwiRWRnZS9cIik7Yi5wZXJpb2RzLmZvckVhY2goZnVuY3Rpb24oYSl7YS5zdHJlYW1TZXRzLmZvckVhY2goZnVuY3Rpb24oYSl7XCJ0ZXh0XCIhPWEudHlwZSYmKGYmJihhLmRybUluZm9zPVtmXSksYS5kcm1JbmZvcy5mb3JFYWNoKGZ1bmN0aW9uKGIpe2xiKHRoaXMsYik7dmFyIGY9ZFtiLmtleVN5c3RlbV07Znx8KGY9e2F1ZGlvQ2FwYWJpbGl0aWVzOltdLHZpZGVvQ2FwYWJpbGl0aWVzOltdLGRpc3RpbmN0aXZlSWRlbnRpZmllcjpcIm9wdGlvbmFsXCIscGVyc2lzdGVudFN0YXRlOmM/XCJyZXF1aXJlZFwiOlwib3B0aW9uYWxcIixzZXNzaW9uVHlwZXM6W2M/XCJwZXJzaXN0ZW50LWxpY2Vuc2VcIjpcInRlbXBvcmFyeVwiXSxsYWJlbDpiLmtleVN5c3RlbSxkcm1JbmZvczpbXX0sZFtiLmtleVN5c3RlbV09ZixlLnB1c2goYi5rZXlTeXN0ZW0pKTtmLmRybUluZm9zLnB1c2goYik7Yi5kaXN0aW5jdGl2ZUlkZW50aWZpZXJSZXF1aXJlZCYmXG4oZi5kaXN0aW5jdGl2ZUlkZW50aWZpZXI9XCJyZXF1aXJlZFwiKTtiLnBlcnNpc3RlbnRTdGF0ZVJlcXVpcmVkJiYoZi5wZXJzaXN0ZW50U3RhdGU9XCJyZXF1aXJlZFwiKTt2YXIgaD1cInZpZGVvXCI9PWEudHlwZT9mLnZpZGVvQ2FwYWJpbGl0aWVzOmYuYXVkaW9DYXBhYmlsaXRpZXMsQT0oXCJ2aWRlb1wiPT1hLnR5cGU/Yi52aWRlb1JvYnVzdG5lc3M6Yi5hdWRpb1JvYnVzdG5lc3MpfHxcIlwiO2Euc3RyZWFtcy5mb3JFYWNoKGZ1bmN0aW9uKGEpe3ZhciBjPWEubWltZVR5cGU7YS5jb2RlY3MmJihjKz0nOyBjb2RlY3M9XCInK2EuY29kZWNzKydcIicpO2Eua2V5SWQmJmIua2V5SWRzLnB1c2goYS5rZXlJZCk7ZyYmXCJjb20ubWljcm9zb2Z0LnBsYXlyZWFkeVwiPT1iLmtleVN5c3RlbSYmaC5sZW5ndGh8fGgucHVzaCh7cm9idXN0bmVzczpBLGNvbnRlbnRUeXBlOmN9KX0uYmluZCh0aGlzKSl9LmJpbmQodGhpcykpKX0uYmluZCh0aGlzKSl9LmJpbmQoYSkpfVxuZnVuY3Rpb24gY2IoYSxiLGMpe2lmKDE9PWMubGVuZ3RoJiZcIlwiPT1jWzBdKXJldHVybiBQcm9taXNlLnJlamVjdChuZXcgcSg2LDZFMykpO3ZhciBkPW5ldyB3LGU9ZDtbITAsITFdLmZvckVhY2goZnVuY3Rpb24oYSl7Yy5mb3JFYWNoKGZ1bmN0aW9uKGMpe3ZhciBkPWJbY107ZC5kcm1JbmZvcy5zb21lKGZ1bmN0aW9uKGEpe3JldHVybiEhYS5saWNlbnNlU2VydmVyVXJpfSk9PWEmJihkLmF1ZGlvQ2FwYWJpbGl0aWVzLmxlbmd0aHx8ZGVsZXRlIGQuYXVkaW9DYXBhYmlsaXRpZXMsZC52aWRlb0NhcGFiaWxpdGllcy5sZW5ndGh8fGRlbGV0ZSBkLnZpZGVvQ2FwYWJpbGl0aWVzLGU9ZVtcImNhdGNoXCJdKGZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYz9Qcm9taXNlLnJlamVjdCgpOm5hdmlnYXRvci5yZXF1ZXN0TWVkaWFLZXlTeXN0ZW1BY2Nlc3MoYyxbZF0pfS5iaW5kKHRoaXMpKSl9LmJpbmQodGhpcykpfS5iaW5kKGEpKTtlPWVbXCJjYXRjaFwiXShmdW5jdGlvbigpe3JldHVybiBQcm9taXNlLnJlamVjdChuZXcgcSg2LFxuNjAwMSkpfSk7ZT1lLnRoZW4oZnVuY3Rpb24oYSl7aWYodGhpcy5jKXJldHVybiBQcm9taXNlLnJlamVjdCgpO3ZhciBjPWEuZ2V0Q29uZmlndXJhdGlvbigpO3RoaXMubT0oYy5hdWRpb0NhcGFiaWxpdGllc3x8W10pLmNvbmNhdChjLnZpZGVvQ2FwYWJpbGl0aWVzfHxbXSkubWFwKGZ1bmN0aW9uKGEpe3JldHVybiBhLmNvbnRlbnRUeXBlfSk7dGhpcy5tLmxlbmd0aHx8KHRoaXMubT1udWxsKTtjPWJbYS5rZXlTeXN0ZW1dO21iKHRoaXMsYS5rZXlTeXN0ZW0sYyxjLmRybUluZm9zKTtyZXR1cm4gdGhpcy5iLmxpY2Vuc2VTZXJ2ZXJVcmk/YS5jcmVhdGVNZWRpYUtleXMoKTpQcm9taXNlLnJlamVjdChuZXcgcSg2LDYwMTIpKX0uYmluZChhKSkudGhlbihmdW5jdGlvbihhKXtpZih0aGlzLmMpcmV0dXJuIFByb21pc2UucmVqZWN0KCk7dGhpcy5oPWE7dGhpcy5BPSEwfS5iaW5kKGEpKVtcImNhdGNoXCJdKGZ1bmN0aW9uKGEpe2lmKHRoaXMuYylyZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG50aGlzLm09dGhpcy5iPW51bGw7cmV0dXJuIGEgaW5zdGFuY2VvZiBxP1Byb21pc2UucmVqZWN0KGEpOlByb21pc2UucmVqZWN0KG5ldyBxKDYsNjAwMixhLm1lc3NhZ2UpKX0uYmluZChhKSk7ZC5yZWplY3QoKTtyZXR1cm4gZX1cbmZ1bmN0aW9uIGxiKGEsYil7dmFyIGM9Yi5rZXlTeXN0ZW07aWYoYyl7aWYoIWIubGljZW5zZVNlcnZlclVyaSl7dmFyIGQ9YS5pLnNlcnZlcnNbY107ZCYmKGIubGljZW5zZVNlcnZlclVyaT1kKX1iLmtleUlkc3x8KGIua2V5SWRzPVtdKTtpZihjPWEuaS5hZHZhbmNlZFtjXSliLmRpc3RpbmN0aXZlSWRlbnRpZmllclJlcXVpcmVkfHwoYi5kaXN0aW5jdGl2ZUlkZW50aWZpZXJSZXF1aXJlZD1jLmRpc3RpbmN0aXZlSWRlbnRpZmllclJlcXVpcmVkKSxiLnBlcnNpc3RlbnRTdGF0ZVJlcXVpcmVkfHwoYi5wZXJzaXN0ZW50U3RhdGVSZXF1aXJlZD1jLnBlcnNpc3RlbnRTdGF0ZVJlcXVpcmVkKSxiLnZpZGVvUm9idXN0bmVzc3x8KGIudmlkZW9Sb2J1c3RuZXNzPWMudmlkZW9Sb2J1c3RuZXNzKSxiLmF1ZGlvUm9idXN0bmVzc3x8KGIuYXVkaW9Sb2J1c3RuZXNzPWMuYXVkaW9Sb2J1c3RuZXNzKSxiLnNlcnZlckNlcnRpZmljYXRlfHwoYi5zZXJ2ZXJDZXJ0aWZpY2F0ZT1jLnNlcnZlckNlcnRpZmljYXRlKX19XG5mdW5jdGlvbiBqYihhKXtpZihNYShhLmkuY2xlYXJLZXlzKSlyZXR1cm4gbnVsbDt2YXIgYj1bXSxjPVtdLGQ7Zm9yKGQgaW4gYS5pLmNsZWFyS2V5cyl7dmFyIGU9YS5pLmNsZWFyS2V5c1tkXSxmPVlhKGQpLGU9WWEoZSksZj17a3R5Olwib2N0XCIsa2lkOldhKGYpLGs6V2EoZSl9O2IucHVzaChmKTtjLnB1c2goZi5raWQpfWE9SlNPTi5zdHJpbmdpZnkoe2tleXM6Yn0pO2M9SlNPTi5zdHJpbmdpZnkoe2tpZHM6Y30pO2M9W3tpbml0RGF0YTpuZXcgVWludDhBcnJheShTYShjKSksaW5pdERhdGFUeXBlOlwia2V5aWRzXCJ9XTtyZXR1cm57a2V5U3lzdGVtOlwib3JnLnczLmNsZWFya2V5XCIsbGljZW5zZVNlcnZlclVyaTpcImRhdGE6YXBwbGljYXRpb24vanNvbjtiYXNlNjQsXCIrd2luZG93LmJ0b2EoYSksZGlzdGluY3RpdmVJZGVudGlmaWVyUmVxdWlyZWQ6ITEscGVyc2lzdGVudFN0YXRlUmVxdWlyZWQ6ITEsYXVkaW9Sb2J1c3RuZXNzOlwiXCIsdmlkZW9Sb2J1c3RuZXNzOlwiXCIsc2VydmVyQ2VydGlmaWNhdGU6bnVsbCxcbmluaXREYXRhOmMsa2V5SWRzOltdfX1mdW5jdGlvbiBtYihhLGIsYyxkKXt2YXIgZT1bXSxmPVtdLGc9W10saD1bXTtuYihkLGUsZixnLGgpO2EuYj17a2V5U3lzdGVtOmIsbGljZW5zZVNlcnZlclVyaTplWzBdLGRpc3RpbmN0aXZlSWRlbnRpZmllclJlcXVpcmVkOlwicmVxdWlyZWRcIj09Yy5kaXN0aW5jdGl2ZUlkZW50aWZpZXIscGVyc2lzdGVudFN0YXRlUmVxdWlyZWQ6XCJyZXF1aXJlZFwiPT1jLnBlcnNpc3RlbnRTdGF0ZSxhdWRpb1JvYnVzdG5lc3M6Yy5hdWRpb0NhcGFiaWxpdGllcz9jLmF1ZGlvQ2FwYWJpbGl0aWVzWzBdLnJvYnVzdG5lc3M6XCJcIix2aWRlb1JvYnVzdG5lc3M6Yy52aWRlb0NhcGFiaWxpdGllcz9jLnZpZGVvQ2FwYWJpbGl0aWVzWzBdLnJvYnVzdG5lc3M6XCJcIixzZXJ2ZXJDZXJ0aWZpY2F0ZTpmWzBdLGluaXREYXRhOmcsa2V5SWRzOmh9fVxuZnVuY3Rpb24gbmIoYSxiLGMsZCxlKXtmdW5jdGlvbiBmKGEsYil7cmV0dXJuIGEuaW5pdERhdGFUeXBlPT1iLmluaXREYXRhVHlwZSYmJGEoYS5pbml0RGF0YSxiLmluaXREYXRhKX1hLmZvckVhY2goZnVuY3Rpb24oYSl7LTE9PWIuaW5kZXhPZihhLmxpY2Vuc2VTZXJ2ZXJVcmkpJiZiLnB1c2goYS5saWNlbnNlU2VydmVyVXJpKTthLnNlcnZlckNlcnRpZmljYXRlJiYtMT09SWEoYyxhLnNlcnZlckNlcnRpZmljYXRlLCRhKSYmYy5wdXNoKGEuc2VydmVyQ2VydGlmaWNhdGUpO2EuaW5pdERhdGEmJmEuaW5pdERhdGEuZm9yRWFjaChmdW5jdGlvbihhKXstMT09SWEoZCxhLGYpJiZkLnB1c2goYSl9KTtpZihhLmtleUlkcylmb3IodmFyIGg9MDtoPGEua2V5SWRzLmxlbmd0aDsrK2gpLTE9PWUuaW5kZXhPZihhLmtleUlkc1toXSkmJmUucHVzaChhLmtleUlkc1toXSl9KX1cbmsuYmM9ZnVuY3Rpb24oYSl7Zm9yKHZhciBiPW5ldyBVaW50OEFycmF5KGEuaW5pdERhdGEpLGM9MDtjPHRoaXMuYS5sZW5ndGg7KytjKWlmKCRhKGIsdGhpcy5hW2NdLmluaXREYXRhKSlyZXR1cm47aGIodGhpcyxhLmluaXREYXRhVHlwZSxiKX07XG5mdW5jdGlvbiBnYihhLGIpe3ZhciBjO3RyeXtjPWEuaC5jcmVhdGVTZXNzaW9uKFwicGVyc2lzdGVudC1saWNlbnNlXCIpfWNhdGNoKGYpe3ZhciBkPW5ldyBxKDYsNjAwNSxmLm1lc3NhZ2UpO2EuZyhkKTtyZXR1cm4gUHJvbWlzZS5yZWplY3QoZCl9QihhLmYsYyxcIm1lc3NhZ2VcIixhLnNiLmJpbmQoYSkpO0IoYS5mLGMsXCJrZXlzdGF0dXNlc2NoYW5nZVwiLGEubmIuYmluZChhKSk7dmFyIGU9e2luaXREYXRhOm51bGwseWE6Yyxsb2FkZWQ6ITF9O2EuYS5wdXNoKGUpO3JldHVybiBjLmxvYWQoYikudGhlbihmdW5jdGlvbihhKXtpZighdGhpcy5jKXtpZihhKXJldHVybiBlLmxvYWRlZD0hMCx0aGlzLmEuZXZlcnkoZnVuY3Rpb24oYSl7cmV0dXJuIGEubG9hZGVkfSkmJnRoaXMuai5yZXNvbHZlKCksYzt0aGlzLmEuc3BsaWNlKHRoaXMuYS5pbmRleE9mKGUpLDEpO3RoaXMuZyhuZXcgcSg2LDYwMTMpKX19LmJpbmQoYSksZnVuY3Rpb24oYSl7dGhpcy5jfHwodGhpcy5hLnNwbGljZSh0aGlzLmEuaW5kZXhPZihlKSxcbjEpLHRoaXMuZyhuZXcgcSg2LDYwMDUsYS5tZXNzYWdlKSkpfS5iaW5kKGEpKX1mdW5jdGlvbiBoYihhLGIsYyl7dmFyIGQ7dHJ5e2Q9YS5DP2EuaC5jcmVhdGVTZXNzaW9uKFwicGVyc2lzdGVudC1saWNlbnNlXCIpOmEuaC5jcmVhdGVTZXNzaW9uKCl9Y2F0Y2goZSl7YS5nKG5ldyBxKDYsNjAwNSxlLm1lc3NhZ2UpKTtyZXR1cm59QihhLmYsZCxcIm1lc3NhZ2VcIixhLnNiLmJpbmQoYSkpO0IoYS5mLGQsXCJrZXlzdGF0dXNlc2NoYW5nZVwiLGEubmIuYmluZChhKSk7YS5hLnB1c2goe2luaXREYXRhOmMseWE6ZCxsb2FkZWQ6ITF9KTtkLmdlbmVyYXRlUmVxdWVzdChiLGMuYnVmZmVyKVtcImNhdGNoXCJdKGZ1bmN0aW9uKGEpe2lmKCF0aGlzLmMpe2Zvcih2YXIgYj0wO2I8dGhpcy5hLmxlbmd0aDsrK2IpaWYodGhpcy5hW2JdLnlhPT1kKXt0aGlzLmEuc3BsaWNlKGIsMSk7YnJlYWt9dGhpcy5nKG5ldyBxKDYsNjAwNixhLm1lc3NhZ2UpKX19LmJpbmQoYSkpfVxuay5zYj1mdW5jdGlvbihhKXt2YXIgYj1hLnRhcmdldCxjPUhhKFt0aGlzLmIubGljZW5zZVNlcnZlclVyaV0sdGhpcy5pLnJldHJ5UGFyYW1ldGVycyk7Yy5ib2R5PWEubWVzc2FnZTtjLm1ldGhvZD1cIlBPU1RcIjtcImNvbS5taWNyb3NvZnQucGxheXJlYWR5XCI9PXRoaXMuYi5rZXlTeXN0ZW0mJm9iKGMpO3RoaXMuRy5yZXF1ZXN0KDIsYykudGhlbihmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5jP1Byb21pc2UucmVqZWN0KCk6Yi51cGRhdGUoYS5kYXRhKX0uYmluZCh0aGlzKSxmdW5jdGlvbihhKXtpZih0aGlzLmMpcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO3RoaXMuZyhuZXcgcSg2LDYwMDcsYSkpfS5iaW5kKHRoaXMpKVtcImNhdGNoXCJdKGZ1bmN0aW9uKGEpe2lmKHRoaXMuYylyZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7dGhpcy5nKG5ldyBxKDYsNjAwOCxhLm1lc3NhZ2UpKX0uYmluZCh0aGlzKSl9O1xuZnVuY3Rpb24gb2IoYSl7Zm9yKHZhciBiPVFhKGEuYm9keSwhMCksYj0obmV3IERPTVBhcnNlcikucGFyc2VGcm9tU3RyaW5nKGIsXCJhcHBsaWNhdGlvbi94bWxcIiksYz1iLmdldEVsZW1lbnRzQnlUYWdOYW1lKFwiSHR0cEhlYWRlclwiKSxkPTA7ZDxjLmxlbmd0aDsrK2QpYS5oZWFkZXJzW2NbZF0ucXVlcnlTZWxlY3RvcihcIm5hbWVcIikudGV4dENvbnRlbnRdPWNbZF0ucXVlcnlTZWxlY3RvcihcInZhbHVlXCIpLnRleHRDb250ZW50O2EuYm9keT1YYShiLnF1ZXJ5U2VsZWN0b3IoXCJDaGFsbGVuZ2VcIikudGV4dENvbnRlbnQpLmJ1ZmZlcn1cbmsubmI9ZnVuY3Rpb24oYSl7YT1hLnRhcmdldDt2YXIgYjtmb3IoYj0wO2I8dGhpcy5hLmxlbmd0aCYmdGhpcy5hW2JdLnlhIT1hOysrYik7aWYoYiE9dGhpcy5hLmxlbmd0aCl7dmFyIGM9YS5rZXlTdGF0dXNlcyxkPSExO2MuZm9yRWFjaHx8KGM9W10pO2MuZm9yRWFjaChmdW5jdGlvbihhLGMpe2lmKFwic3RyaW5nXCI9PXR5cGVvZiBjKXt2YXIgZz1jO2M9YTthPWd9aWYoXCJjb20ubWljcm9zb2Z0LnBsYXlyZWFkeVwiPT10aGlzLmIua2V5U3lzdGVtJiYxNj09Yy5ieXRlTGVuZ3RoKXt2YXIgZz1uZXcgRGF0YVZpZXcoYyksaD1nLmdldFVpbnQzMigwLCEwKSxsPWcuZ2V0VWludDE2KDQsITApLG49Zy5nZXRVaW50MTYoNiwhMCk7Zy5zZXRVaW50MzIoMCxoLCExKTtnLnNldFVpbnQxNig0LGwsITEpO2cuc2V0VWludDE2KDYsbiwhMSl9XCJjb20ubWljcm9zb2Z0LnBsYXlyZWFkeVwiPT10aGlzLmIua2V5U3lzdGVtJiZcInN0YXR1cy1wZW5kaW5nXCI9PWEmJihhPVwidXNhYmxlXCIpO1wic3RhdHVzLXBlbmRpbmdcIiE9XG5hJiYodGhpcy5hW2JdLmxvYWRlZD0hMCx0aGlzLmEuZXZlcnkoZnVuY3Rpb24oYSl7cmV0dXJuIGEubG9hZGVkfSkmJnRoaXMuai5yZXNvbHZlKCkpO1wiZXhwaXJlZFwiPT1hJiYoZD0hMCk7Zz1aYShuZXcgVWludDhBcnJheShjKSk7dGhpcy53W2ddPWF9LmJpbmQodGhpcykpO2M9YS5leHBpcmF0aW9uLURhdGUubm93KCk7aWYoMD5jfHxkJiYxRTM+Yyl0aGlzLmEuc3BsaWNlKGIsMSksYS5jbG9zZSgpO1ZhKHRoaXMudil9fTtrLnZjPWZ1bmN0aW9uKCl7T2EodGhpcy53LGZ1bmN0aW9uKGEsYil7cmV0dXJuXCJleHBpcmVkXCI9PWJ9KSYmdGhpcy5nKG5ldyBxKDYsNjAxNCkpO3RoaXMuSih0aGlzLncpfTtcbmZ1bmN0aW9uIHFiKCl7dmFyIGE9W10sYj1be2NvbnRlbnRUeXBlOid2aWRlby9tcDQ7IGNvZGVjcz1cImF2YzEuNDJFMDFFXCInfSx7Y29udGVudFR5cGU6J3ZpZGVvL3dlYm07IGNvZGVjcz1cInZwOFwiJ31dLGM9W3t2aWRlb0NhcGFiaWxpdGllczpiLHBlcnNpc3RlbnRTdGF0ZTpcInJlcXVpcmVkXCIsc2Vzc2lvblR5cGVzOltcInBlcnNpc3RlbnQtbGljZW5zZVwiXX0se3ZpZGVvQ2FwYWJpbGl0aWVzOmJ9XSxkPXt9O1wib3JnLnczLmNsZWFya2V5IGNvbS53aWRldmluZS5hbHBoYSBjb20ubWljcm9zb2Z0LnBsYXlyZWFkeSBjb20uYXBwbGUuZnBzLjJfMCBjb20uYXBwbGUuZnBzLjFfMCBjb20uYXBwbGUuZnBzIGNvbS5hZG9iZS5wcmltZXRpbWVcIi5zcGxpdChcIiBcIikuZm9yRWFjaChmdW5jdGlvbihiKXt2YXIgZj1uYXZpZ2F0b3IucmVxdWVzdE1lZGlhS2V5U3lzdGVtQWNjZXNzKGIsYykudGhlbihmdW5jdGlvbihhKXtyZXR1cm4gYS5jcmVhdGVNZWRpYUtleXMoKX0pLnRoZW4oZnVuY3Rpb24oYSl7dmFyIGM9XG4hMTt0cnl7YS5jcmVhdGVTZXNzaW9uKFwicGVyc2lzdGVudC1saWNlbnNlXCIpLGM9ITB9Y2F0Y2goZil7fWRbYl09e3BlcnNpc3RlbnRTdGF0ZTpjfX0sZnVuY3Rpb24oKXtkW2JdPW51bGx9KTthLnB1c2goZil9KTtyZXR1cm4gUHJvbWlzZS5hbGwoYSkudGhlbihmdW5jdGlvbigpe3JldHVybiBkfSl9O3ZhciByYj17fSxzYj17fTttKFwic2hha2EubWVkaWEuTWFuaWZlc3RQYXJzZXIucmVnaXN0ZXJQYXJzZXJCeUV4dGVuc2lvblwiLGZ1bmN0aW9uKGEsYil7c2JbYV09Yn0pO20oXCJzaGFrYS5tZWRpYS5NYW5pZmVzdFBhcnNlci5yZWdpc3RlclBhcnNlckJ5TWltZVwiLGZ1bmN0aW9uKGEsYil7cmJbYV09Yn0pO2Z1bmN0aW9uIHRiKCl7dmFyIGE9e30sYjtmb3IoYiBpbiByYilhW2JdPSEwO2ZvcihiIGluIHNiKWFbYl09ITA7W1wiYXBwbGljYXRpb24vZGFzaCt4bWxcIixcImFwcGxpY2F0aW9uL3gtbXBlZ3VybFwiLFwiYXBwbGljYXRpb24vdm5kLmFwcGxlLm1wZWd1cmxcIixcImFwcGxpY2F0aW9uL3ZuZC5tcy1zc3RyK3htbFwiXS5mb3JFYWNoKGZ1bmN0aW9uKGIpe2FbYl09ISFyYltiXX0pO1tcIm1wZFwiLFwibTN1OFwiLFwiaXNtXCJdLmZvckVhY2goZnVuY3Rpb24oYil7YVtiXT0hIXNiW2JdfSk7cmV0dXJuIGF9XG5mdW5jdGlvbiB1YihhLGIsYyxkKXt2YXIgZT1kO2V8fChkPShuZXcgb2EoYSkpLk8uc3BsaXQoXCIvXCIpLnBvcCgpLnNwbGl0KFwiLlwiKSwxPGQubGVuZ3RoJiYoZD1kLnBvcCgpLnRvTG93ZXJDYXNlKCksZT1zYltkXSkpO2lmKGUpcmV0dXJuIFByb21pc2UucmVzb2x2ZShlKTtjPUhhKFthXSxjKTtjLm1ldGhvZD1cIkhFQURcIjtyZXR1cm4gYi5yZXF1ZXN0KDAsYykudGhlbihmdW5jdGlvbihiKXsoYj1iLmhlYWRlcnNbXCJjb250ZW50LXR5cGVcIl0pJiYoYj1iLnRvTG93ZXJDYXNlKCkpO3JldHVybihlPXJiW2JdKT9lOlByb21pc2UucmVqZWN0KG5ldyBxKDQsNEUzLGEpKX0sZnVuY3Rpb24oYSl7cmV0dXJuIFByb21pc2UucmVqZWN0KGEpfSl9O2Z1bmN0aW9uIHZiKGEsYixjKXt0aGlzLmc9RVtiXTt0aGlzLmM9YTt0aGlzLmg9MDt0aGlzLmY9SW5maW5pdHk7dGhpcy5hPXRoaXMuYj1udWxsO3RoaXMuaT1jfXZhciBFPXt9O20oXCJzaGFrYS5tZWRpYS5UZXh0RW5naW5lLnJlZ2lzdGVyUGFyc2VyXCIsZnVuY3Rpb24oYSxiKXtFW2FdPWJ9KTttKFwic2hha2EubWVkaWEuVGV4dEVuZ2luZS51bnJlZ2lzdGVyUGFyc2VyXCIsZnVuY3Rpb24oYSl7ZGVsZXRlIEVbYV19KTtmdW5jdGlvbiB3YihhLGIsYyl7cmV0dXJuIGE+PWI/bnVsbDpuZXcgeGIoYSxiLGMpfW0oXCJzaGFrYS5tZWRpYS5UZXh0RW5naW5lLm1ha2VDdWVcIix3Yik7dmFyIHhiPXdpbmRvdy5WVFRDdWV8fHdpbmRvdy5UZXh0VHJhY2tDdWU7dmIucHJvdG90eXBlLm89ZnVuY3Rpb24oKXt0aGlzLmMmJnliKHRoaXMsZnVuY3Rpb24oKXtyZXR1cm4hMH0pO3RoaXMuYz10aGlzLmc9bnVsbDtyZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCl9O1xuZnVuY3Rpb24gemIoYSxiLGMsZCl7dmFyIGU9YS5oO3JldHVybiBQcm9taXNlLnJlc29sdmUoKS50aGVuKGZ1bmN0aW9uKCl7aWYodGhpcy5jKXt2YXIgYT10aGlzLmcoYixlLGMsZCx0aGlzLmkpO2lmKG51bGwhPWMmJm51bGwhPWQpe2Zvcih2YXIgZz0wO2c8YS5sZW5ndGgmJiEoYVtnXS5zdGFydFRpbWU+PXRoaXMuZik7KytnKXRoaXMuYy5hZGRDdWUoYVtnXSk7bnVsbD09dGhpcy5iJiYodGhpcy5iPWMpO3RoaXMuYT1NYXRoLm1pbihkLHRoaXMuZil9fX0uYmluZChhKSl9XG52Yi5wcm90b3R5cGUucmVtb3ZlPWZ1bmN0aW9uKGEsYil7cmV0dXJuIFByb21pc2UucmVzb2x2ZSgpLnRoZW4oZnVuY3Rpb24oKXt0aGlzLmMmJih5Yih0aGlzLGZ1bmN0aW9uKGMpe3JldHVybiBjLnN0YXJ0VGltZT49Ynx8Yy5lbmRUaW1lPD1hPyExOiEwfSksbnVsbD09dGhpcy5ifHxiPD10aGlzLmJ8fGE+PXRoaXMuYXx8KGE8PXRoaXMuYiYmYj49dGhpcy5hP3RoaXMuYj10aGlzLmE9bnVsbDphPD10aGlzLmImJmI8dGhpcy5hP3RoaXMuYj1iOmE+dGhpcy5iJiZiPj10aGlzLmEmJih0aGlzLmE9YSkpKX0uYmluZCh0aGlzKSl9O2Z1bmN0aW9uIEFiKGEsYil7cmV0dXJuIG51bGw9PWEuYXx8YS5hPGJ8fGI8YS5iPzA6YS5hLWJ9ZnVuY3Rpb24geWIoYSxiKXtmb3IodmFyIGM9YS5jLmN1ZXMsZD1bXSxlPTA7ZTxjLmxlbmd0aDsrK2UpYihjW2VdKSYmZC5wdXNoKGNbZV0pO2ZvcihlPTA7ZTxkLmxlbmd0aDsrK2UpYS5jLnJlbW92ZUN1ZShkW2VdKX07ZnVuY3Rpb24gQmIoYSl7cmV0dXJuIWF8fDE9PWEubGVuZ3RoJiYxRS02PmEuZW5kKDApLWEuc3RhcnQoMCk/bnVsbDphLmxlbmd0aD9hLmVuZChhLmxlbmd0aC0xKTpudWxsfWZ1bmN0aW9uIENiKGEsYil7dmFyIGM9MDtpZighYXx8MT09YS5sZW5ndGgmJjFFLTY+YS5lbmQoMCktYS5zdGFydCgwKSlyZXR1cm4gYztmb3IodmFyIGQ9ITEsZT0wO2U8YS5sZW5ndGg7KytlKWlmKGIrMUUtND49YS5zdGFydChlKSYmYjxhLmVuZChlKSljKz1hLmVuZChlKS1iLGQ9ITA7ZWxzZSBpZihkJiYuMDQ+PWEuc3RhcnQoZSktYS5lbmQoZS0xKSljKz1hLmVuZChlKS1hLnN0YXJ0KGUpLGMrPWEuc3RhcnQoZSktYS5lbmQoZS0xKTtlbHNlIGlmKDA8ZSYmYisxRS00PGEuc3RhcnQoZSkmJmIrMUUtND49YS5lbmQoZS0xKSlpZiguMDQ+PWEuc3RhcnQoZSktYiljKz1hLmVuZChlKS1iLGQ9ITA7ZWxzZSBicmVhaztlbHNlIGQ9ITE7cmV0dXJuIGN9O2Z1bmN0aW9uIERiKGEsYixjKXt0aGlzLmc9YTt0aGlzLmY9Yjt0aGlzLmo9Yzt0aGlzLmM9e307dGhpcy5iPW51bGw7dGhpcy5hPXt9O3RoaXMuaD1uZXcgejt0aGlzLmk9ITF9XG5mdW5jdGlvbiBFYigpe3ZhciBhPXt9Oyd2aWRlby9tcDQ7IGNvZGVjcz1cImF2YzEuNDJFMDFFXCIsYXVkaW8vbXA0OyBjb2RlY3M9XCJtcDRhLjQwLjJcIix2aWRlby93ZWJtOyBjb2RlY3M9XCJ2cDhcIix2aWRlby93ZWJtOyBjb2RlY3M9XCJ2cDlcIixhdWRpby93ZWJtOyBjb2RlY3M9XCJ2b3JiaXNcIixhdWRpby93ZWJtOyBjb2RlY3M9XCJvcHVzXCIsdmlkZW8vbXAydDsgY29kZWNzPVwiYXZjMS40MkUwMUVcIix2aWRlby9tcDJ0OyBjb2RlY3M9XCJtcDRhLjQwLjJcIix0ZXh0L3Z0dCxhcHBsaWNhdGlvbi9tcDQ7IGNvZGVjcz1cInd2dHRcIixhcHBsaWNhdGlvbi90dG1sK3htbCxhcHBsaWNhdGlvbi9tcDQ7IGNvZGVjcz1cInN0cHBcIicuc3BsaXQoXCIsXCIpLmZvckVhY2goZnVuY3Rpb24oYil7YVtiXT0hIUVbYl18fE1lZGlhU291cmNlLmlzVHlwZVN1cHBvcnRlZChiKTt2YXIgYz1iLnNwbGl0KFwiO1wiKVswXTthW2NdPWFbY118fGFbYl19KTtyZXR1cm4gYX1rPURiLnByb3RvdHlwZTtcbmsubz1mdW5jdGlvbigpe3RoaXMuaT0hMDt2YXIgYT1bXSxiO2ZvcihiIGluIHRoaXMuYSl7dmFyIGM9dGhpcy5hW2JdLGQ9Y1swXTt0aGlzLmFbYl09Yy5zbGljZSgwLDEpO2QmJmEucHVzaChkLnBbXCJjYXRjaFwiXSh2KSk7Zm9yKGQ9MTtkPGMubGVuZ3RoOysrZCljW2RdLnBbXCJjYXRjaFwiXSh2KSxjW2RdLnAucmVqZWN0KCl9dGhpcy5iJiZhLnB1c2godGhpcy5iLm8oKSk7cmV0dXJuIFByb21pc2UuYWxsKGEpLnRoZW4oZnVuY3Rpb24oKXt0aGlzLmgubygpO3RoaXMuYj10aGlzLmo9dGhpcy5mPXRoaXMuZz10aGlzLmg9bnVsbDt0aGlzLmM9e307dGhpcy5hPXt9fS5iaW5kKHRoaXMpKX07XG5rLmluaXQ9ZnVuY3Rpb24oYSxiKXtmb3IodmFyIGMgaW4gYSl7dmFyIGQ9YVtjXTtcInRleHRcIj09Yz90aGlzLmI9bmV3IHZiKHRoaXMuaixkLGIpOihkPXRoaXMuZi5hZGRTb3VyY2VCdWZmZXIoZCksQih0aGlzLmgsZCxcImVycm9yXCIsdGhpcy5TYy5iaW5kKHRoaXMsYykpLEIodGhpcy5oLGQsXCJ1cGRhdGVlbmRcIix0aGlzLnZhLmJpbmQodGhpcyxjKSksdGhpcy5jW2NdPWQsdGhpcy5hW2NdPVtdKX19O2Z1bmN0aW9uIEZiKGEsYil7dmFyIGM7XCJ0ZXh0XCI9PWI/Yz1hLmIuYjooYz1HYihhLGIpLGM9IWN8fDE9PWMubGVuZ3RoJiYxRS02PmMuZW5kKDApLWMuc3RhcnQoMCk/bnVsbDoxPT1jLmxlbmd0aCYmMD5jLnN0YXJ0KDApPzA6Yy5sZW5ndGg/Yy5zdGFydCgwKTpudWxsKTtyZXR1cm4gY31cbmZ1bmN0aW9uIEhiKGEsYixjKXtcInRleHRcIj09Yj8oYj1BYihhLmIsYyksYnx8KGI9QWIoYS5iLGMrLjEpKSYmKGIrPS4xKSk6KGE9R2IoYSxiKSxiPUNiKGEsYyksYnx8KGI9Q2IoYSxjKy4xKSkmJihiKz0uMSkpO3JldHVybiBifWZ1bmN0aW9uIEdiKGEsYil7dHJ5e3JldHVybiBhLmNbYl0uYnVmZmVyZWR9Y2F0Y2goYyl7cmV0dXJuIG51bGx9fWZ1bmN0aW9uIEliKGEsYixjLGQsZSl7cmV0dXJuXCJ0ZXh0XCI9PWI/emIoYS5iLGMsZCxlKTpKYihhLGIsYS5SYy5iaW5kKGEsYixjKSl9ay5yZW1vdmU9ZnVuY3Rpb24oYSxiLGMpe3JldHVyblwidGV4dFwiPT1hP3RoaXMuYi5yZW1vdmUoYixjKTpKYih0aGlzLGEsdGhpcy54Yi5iaW5kKHRoaXMsYSxiLGMpKX07XG5mdW5jdGlvbiBLYihhLGIpe3JldHVyblwidGV4dFwiPT1iP2EuYi5yZW1vdmUoMCxJbmZpbml0eSk6UHJvbWlzZS5hbGwoW0piKGEsYixhLnhiLmJpbmQoYSxiLDAsYS5mLmR1cmF0aW9uKSksSmIoYSxiLGEuUmIuYmluZChhLGIpKV0pfWZ1bmN0aW9uIExiKGEsYixjKXtyZXR1cm5cInRleHRcIj09Yj8oYS5iLmg9YyxQcm9taXNlLnJlc29sdmUoKSk6SmIoYSxiLGEuSGMuYmluZChhLGIsYykpfWZ1bmN0aW9uIE1iKGEsYixjKXtyZXR1cm5cInRleHRcIj09Yj8oYS5iLmY9YyxQcm9taXNlLnJlc29sdmUoKSk6UHJvbWlzZS5hbGwoW0piKGEsYixhLkliLmJpbmQoYSxiKSksSmIoYSxiLGEuRmMuYmluZChhLGIsYykpXSl9ay5lbmRPZlN0cmVhbT1mdW5jdGlvbihhKXtyZXR1cm4gTmIodGhpcyxmdW5jdGlvbigpe2E/dGhpcy5mLmVuZE9mU3RyZWFtKGEpOnRoaXMuZi5lbmRPZlN0cmVhbSgpfS5iaW5kKHRoaXMpKX07XG5rLnphPWZ1bmN0aW9uKGEpe3JldHVybiBOYih0aGlzLGZ1bmN0aW9uKCl7dGhpcy5mLmR1cmF0aW9uPWF9LmJpbmQodGhpcykpfTtrLmRhPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZi5kdXJhdGlvbn07ay5SYz1mdW5jdGlvbihhLGIpe3RoaXMuY1thXS5hcHBlbmRCdWZmZXIoYil9O2sueGI9ZnVuY3Rpb24oYSxiLGMpe2M8PWI/dGhpcy52YShhKTp0aGlzLmNbYV0ucmVtb3ZlKGIsYyl9O2suSWI9ZnVuY3Rpb24oYSl7dmFyIGI9dGhpcy5jW2FdLmFwcGVuZFdpbmRvd0VuZDt0aGlzLmNbYV0uYWJvcnQoKTt0aGlzLmNbYV0uYXBwZW5kV2luZG93RW5kPWI7dGhpcy52YShhKX07ay5SYj1mdW5jdGlvbihhKXt0aGlzLmcuY3VycmVudFRpbWUtPS4wMDE7dGhpcy52YShhKX07ay5IYz1mdW5jdGlvbihhLGIpe3RoaXMuY1thXS50aW1lc3RhbXBPZmZzZXQ9Yjt0aGlzLnZhKGEpfTtrLkZjPWZ1bmN0aW9uKGEsYil7dGhpcy5jW2FdLmFwcGVuZFdpbmRvd0VuZD1iKy4wNDt0aGlzLnZhKGEpfTtcbmsuU2M9ZnVuY3Rpb24oYSl7dGhpcy5hW2FdWzBdLnAucmVqZWN0KG5ldyBxKDMsMzAxNCx0aGlzLmcuZXJyb3I/dGhpcy5nLmVycm9yLmNvZGU6MCkpfTtrLnZhPWZ1bmN0aW9uKGEpe3ZhciBiPXRoaXMuYVthXVswXTtiJiYoYi5wLnJlc29sdmUoKSxPYih0aGlzLGEpKX07ZnVuY3Rpb24gSmIoYSxiLGMpe2lmKGEuaSlyZXR1cm4gUHJvbWlzZS5yZWplY3QoKTtjPXtzdGFydDpjLHA6bmV3IHd9O2EuYVtiXS5wdXNoKGMpO2lmKDE9PWEuYVtiXS5sZW5ndGgpdHJ5e2Muc3RhcnQoKX1jYXRjaChkKXtcIlF1b3RhRXhjZWVkZWRFcnJvclwiPT1kLm5hbWU/Yy5wLnJlamVjdChuZXcgcSgzLDMwMTcsYikpOmMucC5yZWplY3QobmV3IHEoMywzMDE1LGQpKSxPYihhLGIpfXJldHVybiBjLnB9XG5mdW5jdGlvbiBOYihhLGIpe2lmKGEuaSlyZXR1cm4gUHJvbWlzZS5yZWplY3QoKTt2YXIgYz1bXSxkO2ZvcihkIGluIGEuYyl7dmFyIGU9bmV3IHcsZj17c3RhcnQ6ZnVuY3Rpb24oYSl7YS5yZXNvbHZlKCl9LmJpbmQobnVsbCxlKSxwOmV9O2EuYVtkXS5wdXNoKGYpO2MucHVzaChlKTsxPT1hLmFbZF0ubGVuZ3RoJiZmLnN0YXJ0KCl9cmV0dXJuIFByb21pc2UuYWxsKGMpLnRoZW4oZnVuY3Rpb24oKXt2YXIgYSxjO3RyeXtiKCl9Y2F0Y2goZCl7Yz1Qcm9taXNlLnJlamVjdChuZXcgcSgzLDMwMTUsZCkpfWZvcihhIGluIHRoaXMuYylPYih0aGlzLGEpO3JldHVybiBjfS5iaW5kKGEpLGZ1bmN0aW9uKCl7cmV0dXJuIFByb21pc2UucmVqZWN0KCl9LmJpbmQoYSkpfWZ1bmN0aW9uIE9iKGEsYil7YS5hW2JdLnNoaWZ0KCk7dmFyIGM9YS5hW2JdWzBdO2lmKGMpdHJ5e2Muc3RhcnQoKX1jYXRjaChkKXtjLnAucmVqZWN0KG5ldyBxKDMsMzAxNSxkKSksT2IoYSxiKX19O2Z1bmN0aW9uIFBiKGEsYixjKXt0aGlzLmE9YTt0aGlzLkw9Yjt0aGlzLkQ9Y31tKFwic2hha2EubWVkaWEuSW5pdFNlZ21lbnRSZWZlcmVuY2VcIixQYik7ZnVuY3Rpb24gRihhLGIsYyxkLGUsZil7dGhpcy5wb3NpdGlvbj1hO3RoaXMuc3RhcnRUaW1lPWI7dGhpcy5lbmRUaW1lPWM7dGhpcy5hPWQ7dGhpcy5MPWU7dGhpcy5EPWZ9bShcInNoYWthLm1lZGlhLlNlZ21lbnRSZWZlcmVuY2VcIixGKTtmdW5jdGlvbiBHKGEsYil7dGhpcy5qPWE7dGhpcy5pPWI7dGhpcy5jPXRoaXMuYT1JbmZpbml0eTt0aGlzLmI9MTt0aGlzLmg9dGhpcy5mPTA7dGhpcy5nPSEwfW0oXCJzaGFrYS5tZWRpYS5QcmVzZW50YXRpb25UaW1lbGluZVwiLEcpO0cucHJvdG90eXBlLmRhPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYX07Ry5wcm90b3R5cGUuZ2V0RHVyYXRpb249Ry5wcm90b3R5cGUuZGE7Ry5wcm90b3R5cGUuemE9ZnVuY3Rpb24oYSl7dGhpcy5hPWF9O0cucHJvdG90eXBlLnNldER1cmF0aW9uPUcucHJvdG90eXBlLnphO0cucHJvdG90eXBlLkJiPWZ1bmN0aW9uKGEpe3RoaXMuaD1hfTtHLnByb3RvdHlwZS5zZXRDbG9ja09mZnNldD1HLnByb3RvdHlwZS5CYjtHLnByb3RvdHlwZS5FYj1mdW5jdGlvbihhKXt0aGlzLmc9YX07Ry5wcm90b3R5cGUuc2V0U3RhdGljPUcucHJvdG90eXBlLkViO0cucHJvdG90eXBlLlViPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuY307XG5HLnByb3RvdHlwZS5nZXRTZWdtZW50QXZhaWxhYmlsaXR5RHVyYXRpb249Ry5wcm90b3R5cGUuVWI7Ry5wcm90b3R5cGUuRGI9ZnVuY3Rpb24oYSl7dGhpcy5jPWF9O0cucHJvdG90eXBlLnNldFNlZ21lbnRBdmFpbGFiaWxpdHlEdXJhdGlvbj1HLnByb3RvdHlwZS5EYjtHLnByb3RvdHlwZS5FYT1mdW5jdGlvbihhLGIpe2IubGVuZ3RoJiYodGhpcy5iPWIucmVkdWNlKGZ1bmN0aW9uKGEsYil7cmV0dXJuIE1hdGgubWF4KGEsYi5lbmRUaW1lLWIuc3RhcnRUaW1lKX0sdGhpcy5iKSxhfHwodGhpcy5mPU1hdGgubWF4KHRoaXMuZixiWzBdLnN0YXJ0VGltZSkpKX07Ry5wcm90b3R5cGUubm90aWZ5U2VnbWVudHM9Ry5wcm90b3R5cGUuRWE7Ry5wcm90b3R5cGUuVmE9ZnVuY3Rpb24oYSl7dGhpcy5iPU1hdGgubWF4KHRoaXMuYixhKX07Ry5wcm90b3R5cGUubm90aWZ5TWF4U2VnbWVudER1cmF0aW9uPUcucHJvdG90eXBlLlZhO1xuRy5wcm90b3R5cGUuVT1mdW5jdGlvbigpe3JldHVybiBJbmZpbml0eT09dGhpcy5hJiYhdGhpcy5nfTtHLnByb3RvdHlwZS5pc0xpdmU9Ry5wcm90b3R5cGUuVTtHLnByb3RvdHlwZS5mYT1mdW5jdGlvbigpe3JldHVybiBJbmZpbml0eSE9dGhpcy5hJiYhdGhpcy5nfTtHLnByb3RvdHlwZS5pc0luUHJvZ3Jlc3M9Ry5wcm90b3R5cGUuZmE7Ry5wcm90b3R5cGUucmE9ZnVuY3Rpb24oKXtyZXR1cm4gTWF0aC5tYXgoTWF0aC5taW4odGhpcy5mLHRoaXMuZWEoKSksdGhpcy5zYSgpKX07Ry5wcm90b3R5cGUuZ2V0RWFybGllc3RTdGFydD1HLnByb3RvdHlwZS5yYTtHLnByb3RvdHlwZS5zYT1mdW5jdGlvbigpe3JldHVybiBJbmZpbml0eT09dGhpcy5jPzA6TWF0aC5tYXgoMCx0aGlzLmVhKCktdGhpcy5jLXRoaXMuaSl9O0cucHJvdG90eXBlLmdldFNlZ21lbnRBdmFpbGFiaWxpdHlTdGFydD1HLnByb3RvdHlwZS5zYTtcbkcucHJvdG90eXBlLmVhPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuVSgpfHx0aGlzLmZhKCk/TWF0aC5taW4oTWF0aC5tYXgoMCwoRGF0ZS5ub3coKSt0aGlzLmgpLzFFMy10aGlzLmItdGhpcy5qKSx0aGlzLmEpOnRoaXMuYX07Ry5wcm90b3R5cGUuZ2V0U2VnbWVudEF2YWlsYWJpbGl0eUVuZD1HLnByb3RvdHlwZS5lYTtHLnByb3RvdHlwZS5SYT1mdW5jdGlvbigpe3JldHVybiBNYXRoLm1heCgwLHRoaXMuZWEoKS0odGhpcy5VKCl8fHRoaXMuZmEoKT90aGlzLmk6MCkpfTtHLnByb3RvdHlwZS5nZXRTZWVrUmFuZ2VFbmQ9Ry5wcm90b3R5cGUuUmE7ZnVuY3Rpb24gUWIoYSxiLGMsZCxlLGYpe3RoaXMuYT1hO3RoaXMuYz1iO3RoaXMuaj1jO3RoaXMucz1kO3RoaXMubD1lO3RoaXMubT1mO3RoaXMuYj1uZXcgejt0aGlzLmc9ITE7dGhpcy5oPTE7dGhpcy5pPXRoaXMuZj1udWxsOzA8YS5yZWFkeVN0YXRlP3RoaXMub2IoKTpCKHRoaXMuYixhLFwibG9hZGVkbWV0YWRhdGFcIix0aGlzLm9iLmJpbmQodGhpcykpO0IodGhpcy5iLGEsXCJyYXRlY2hhbmdlXCIsdGhpcy5pYy5iaW5kKHRoaXMpKTtSYih0aGlzKX1rPVFiLnByb3RvdHlwZTtrLm89ZnVuY3Rpb24oKXt2YXIgYT10aGlzLmIubygpO3RoaXMuYj1udWxsO1NiKHRoaXMpO251bGwhPXRoaXMuZiYmKHdpbmRvdy5jbGVhckludGVydmFsKHRoaXMuZiksdGhpcy5mPW51bGwpO3RoaXMubT10aGlzLmw9dGhpcy5jPXRoaXMuYT1udWxsO3JldHVybiBhfTtmdW5jdGlvbiBUYihhKXtyZXR1cm4gMDxhLmEucmVhZHlTdGF0ZT9VYihhLGEuYS5jdXJyZW50VGltZSk6VmIoYSl9XG5mdW5jdGlvbiBWYihhKXtyZXR1cm4gYS5zP1ViKGEsYS5zKTpJbmZpbml0eT5hLmMuZGEoKT9hLmMucmEoKTpNYXRoLm1heChhLmMuUmEoKSxhLmMucmEoKSl9ZnVuY3Rpb24gV2IoYSxiKXtiIT1hLmcmJihhLmc9YixYYihhLGEuaCksYS5sKGIpKX1mdW5jdGlvbiBSYihhKXtTYihhKTthLmk9d2luZG93LnNldFRpbWVvdXQoYS5tYy5iaW5kKGEpLDI1MCl9ZnVuY3Rpb24gU2IoYSl7YS5pJiYod2luZG93LmNsZWFyVGltZW91dChhLmkpLGEuaT1udWxsKX1rLm1jPWZ1bmN0aW9uKCl7dGhpcy5pPW51bGw7UmIodGhpcyk7dmFyIGE9Q2IodGhpcy5hLmJ1ZmZlcmVkLHRoaXMuYS5jdXJyZW50VGltZSksYj1CYih0aGlzLmEuYnVmZmVyZWQpPj10aGlzLmEuZHVyYXRpb24tLjA1fHx0aGlzLmEuZW5kZWQ7dGhpcy5nPyhifHxhPnRoaXMuaikmJldiKHRoaXMsITEpOiFiJiYuNT5hJiZXYih0aGlzLCEwKX07ay5RYT1mdW5jdGlvbigpe3JldHVybiB0aGlzLmh9O1xuZnVuY3Rpb24gWGIoYSxiKXtudWxsIT1hLmYmJih3aW5kb3cuY2xlYXJJbnRlcnZhbChhLmYpLGEuZj1udWxsKTthLmg9YjthLmEucGxheWJhY2tSYXRlPWEuZ3x8MD5iPzA6YjshYS5nJiYwPmImJihhLmY9d2luZG93LnNldEludGVydmFsKGZ1bmN0aW9uKCl7dGhpcy5hLmN1cnJlbnRUaW1lKz1iLzR9LmJpbmQoYSksMjUwKSl9ay5pYz1mdW5jdGlvbigpe3RoaXMuYS5wbGF5YmFja1JhdGUhPSh0aGlzLmd8fDA+dGhpcy5oPzA6dGhpcy5oKSYmWGIodGhpcyx0aGlzLmEucGxheWJhY2tSYXRlKX07XG5rLm9iPWZ1bmN0aW9uKCl7dGhpcy5iLmphKHRoaXMuYSxcImxvYWRlZG1ldGFkYXRhXCIpO3ZhciBhPVZiKHRoaXMpOy4wMDE+TWF0aC5hYnModGhpcy5hLmN1cnJlbnRUaW1lLWEpPyhCKHRoaXMuYix0aGlzLmEsXCJzZWVraW5nXCIsdGhpcy5xYi5iaW5kKHRoaXMpKSxCKHRoaXMuYix0aGlzLmEsXCJwbGF5aW5nXCIsdGhpcy5wYi5iaW5kKHRoaXMpKSk6KEIodGhpcy5iLHRoaXMuYSxcInNlZWtpbmdcIix0aGlzLmtjLmJpbmQodGhpcykpLHRoaXMuYS5jdXJyZW50VGltZT1hKX07ay5rYz1mdW5jdGlvbigpe3RoaXMuYi5qYSh0aGlzLmEsXCJzZWVraW5nXCIpO0IodGhpcy5iLHRoaXMuYSxcInNlZWtpbmdcIix0aGlzLnFiLmJpbmQodGhpcykpO0IodGhpcy5iLHRoaXMuYSxcInBsYXlpbmdcIix0aGlzLnBiLmJpbmQodGhpcykpfTtrLnFiPWZ1bmN0aW9uKCl7dmFyIGE9dGhpcy5hLmN1cnJlbnRUaW1lLGI9WWIodGhpcyxhKTsuMDAxPE1hdGguYWJzKGItYSk/WmIodGhpcyxhLGIpOnRoaXMubSgpfTtcbmsucGI9ZnVuY3Rpb24oKXt2YXIgYT10aGlzLmEuY3VycmVudFRpbWUsYj1ZYih0aGlzLGEpOy4wMDE8TWF0aC5hYnMoYi1hKSYmWmIodGhpcyxhLGIpfTtmdW5jdGlvbiBZYihhLGIpe3ZhciBjPWEuYyxkPWMucmEoKSxlPWMuZWEoKTtpZighYy5VKCl8fEluZmluaXR5PT1jLmMpcmV0dXJuIGI8ZD9kOmI+ZT9lOmI7Yz1kKzE7ZD1jK2EuajtyZXR1cm4gYj49ZCYmYjw9ZXx8Q2IoYS5hLmJ1ZmZlcmVkLGIpJiZiPj1jJiZiPD1lP2I6Yj5lP2U6ZTxkJiZiPj1jJiZiPD1lP2I6TWF0aC5taW4oZCsyLGUpfWZ1bmN0aW9uIFpiKGEsYixjKXthLmEuY3VycmVudFRpbWU9Yzt2YXIgZD0wLGU9ZnVuY3Rpb24oKXshdGhpcy5hfHwxMDw9ZCsrfHx0aGlzLmEuY3VycmVudFRpbWUhPWJ8fCh0aGlzLmEuY3VycmVudFRpbWU9YyxzZXRUaW1lb3V0KGUsMTAwKSl9LmJpbmQoYSk7c2V0VGltZW91dChlLDEwMCl9XG5mdW5jdGlvbiBVYihhLGIpe3ZhciBjPWEuYy5yYSgpO2lmKGI8YylyZXR1cm4gYztjPWEuYy5lYSgpO3JldHVybiBiPmM/YzpifTtmdW5jdGlvbiAkYihhLGIsYyxkLGUsZixnLGgsbCl7dGhpcy5tPWE7dGhpcy5mPWI7dGhpcy5TPWM7dGhpcy5hPWQ7dGhpcy5HPWU7dGhpcy52PWY7dGhpcy5qPWc7dGhpcy53PWh8fG51bGw7dGhpcy5BPWx8fG51bGw7dGhpcy5nPW51bGw7dGhpcy5pPTE7dGhpcy5DPVByb21pc2UucmVzb2x2ZSgpO3RoaXMuaD1bXTt0aGlzLmw9e307dGhpcy5iPXt9O3RoaXMuYz10aGlzLnM9dGhpcy5KPSExfSRiLnByb3RvdHlwZS5vPWZ1bmN0aW9uKCl7Zm9yKHZhciBhIGluIHRoaXMuYilhYyh0aGlzLmJbYV0pO3RoaXMuZz10aGlzLmI9dGhpcy5sPXRoaXMuaD10aGlzLkE9dGhpcy53PXRoaXMuaj10aGlzLnY9dGhpcy5HPXRoaXMuQz10aGlzLmE9dGhpcy5TPXRoaXMuZj10aGlzLm09bnVsbDt0aGlzLmM9ITA7cmV0dXJuIFByb21pc2UucmVzb2x2ZSgpfTtcbiRiLnByb3RvdHlwZS5jb25maWd1cmU9ZnVuY3Rpb24oYSl7dGhpcy5nPWE7dGhpcy5tLmo9dGhpcy5pKk1hdGgubWF4KHRoaXMuYS5taW5CdWZmZXJUaW1lfHwwLHRoaXMuZy5yZWJ1ZmZlcmluZ0dvYWwpfTskYi5wcm90b3R5cGUuaW5pdD1mdW5jdGlvbigpe3ZhciBhPXRoaXMuRyh0aGlzLmEucGVyaW9kc1tiYyh0aGlzLFRiKHRoaXMubSkpXSk7cmV0dXJuIE1hKGEpP1Byb21pc2UucmVqZWN0KG5ldyBxKDUsNTAwNSkpOmNjKHRoaXMsYSkudGhlbihmdW5jdGlvbigpe3RoaXMudyYmdGhpcy53KCl9LmJpbmQodGhpcykpfTtmdW5jdGlvbiBkYyhhKXtyZXR1cm4gYS5hLnBlcmlvZHNbYmMoYSxUYihhLm0pKV19ZnVuY3Rpb24gZWMoYSl7cmV0dXJuIE5hKGEuYixmdW5jdGlvbihhKXtyZXR1cm4gYS5zdHJlYW19KX1mdW5jdGlvbiBmYyhhLGIpe3ZhciBjPXt9O2MudGV4dD1iO3JldHVybiBjYyhhLGMpfVxuZnVuY3Rpb24gZ2MoYSxiLGMsZCl7dmFyIGU9YS5iW2JdOyFlJiZcInRleHRcIj09YiYmYS5nLmlnbm9yZVRleHRTdHJlYW1GYWlsdXJlcz9mYyhhLGMpOmUmJihiPWEuaFtoYyhhLGMpXSkmJmIueGEmJihiPWEubFtjLmlkXSkmJmIueGEmJmUuc3RyZWFtIT1jJiYoZS5zdHJlYW09YyxlLkphPSEwLGQmJiFlLmJhJiYoZS5nYT9lLmxhPSEwOihhYyhlKSxpYyhhLGUpKSkpfVxuZnVuY3Rpb24gY2MoYSxiKXt2YXIgYz1iYyhhLFRiKGEubSkpLGQ9TmEoYixmdW5jdGlvbihhKXtyZXR1cm4gYS5taW1lVHlwZSsoYS5jb2RlY3M/JzsgY29kZWNzPVwiJythLmNvZGVjcysnXCInOlwiXCIpfSk7YS5mLmluaXQoZCxhLmcudXNlUmVsYXRpdmVDdWVUaW1lc3RhbXBzKTtqYyhhKTtkPUMoYik7cmV0dXJuIGtjKGEsZCkudGhlbihmdW5jdGlvbigpe2lmKCF0aGlzLmMpZm9yKHZhciBhIGluIGIpe3ZhciBkPWJbYV07dGhpcy5iW2FdfHwodGhpcy5iW2FdPXtzdHJlYW06ZCx0eXBlOmEsdGE6bnVsbCxWOm51bGwsSmE6ITAsS2E6YyxlbmRPZlN0cmVhbTohMSxnYTohMSxhYTpudWxsLGxhOiExLGJhOiExLFphOiExfSxsYyh0aGlzLHRoaXMuYlthXSwwKSl9fS5iaW5kKGEpKX1cbmZ1bmN0aW9uIG1jKGEsYil7dmFyIGM9YS5oW2JdO2lmKGMpcmV0dXJuIGMuSTtjPXtJOm5ldyB3LHhhOiExfTthLmhbYl09Yzt2YXIgZD1hLmEucGVyaW9kc1tiXS5zdHJlYW1TZXRzLm1hcChmdW5jdGlvbihhKXtyZXR1cm4gYS5zdHJlYW1zfSkucmVkdWNlKHUsW10pO2EuQz1hLkMudGhlbihmdW5jdGlvbigpe2lmKCF0aGlzLmMpcmV0dXJuIGtjKHRoaXMsZCl9LmJpbmQoYSkpLnRoZW4oZnVuY3Rpb24oKXt0aGlzLmN8fCh0aGlzLmhbYl0uSS5yZXNvbHZlKCksdGhpcy5oW2JdLnhhPSEwKX0uYmluZChhKSlbXCJjYXRjaFwiXShmdW5jdGlvbihhKXt0aGlzLmN8fCh0aGlzLmhbYl0uSS5yZWplY3QoKSxkZWxldGUgdGhpcy5oW2JdLHRoaXMuaihhKSl9LmJpbmQoYSkpO3JldHVybiBjLkl9XG5mdW5jdGlvbiBrYyhhLGIpe2Zvcih2YXIgYz1bXSxkPTA7ZDxiLmxlbmd0aDsrK2Qpe3ZhciBlPWJbZF0sZj1hLmxbZS5pZF07Zj9jLnB1c2goZi5JKTooYS5sW2UuaWRdPXtJOm5ldyB3LHhhOiExfSxjLnB1c2goZS5jcmVhdGVTZWdtZW50SW5kZXgoKSkpfXJldHVybiBQcm9taXNlLmFsbChjKS50aGVuKGZ1bmN0aW9uKCl7aWYoIXRoaXMuYylmb3IodmFyIGE9MDthPGIubGVuZ3RoOysrYSl7dmFyIGM9dGhpcy5sW2JbYV0uaWRdO2MueGF8fChjLkkucmVzb2x2ZSgpLGMueGE9ITApfX0uYmluZChhKSlbXCJjYXRjaFwiXShmdW5jdGlvbihhKXtpZighdGhpcy5jKXJldHVybiB0aGlzLmxbZS5pZF0uSS5yZWplY3QoKSxkZWxldGUgdGhpcy5sW2UuaWRdLFByb21pc2UucmVqZWN0KGEpfS5iaW5kKGEpKX1mdW5jdGlvbiBqYyhhKXt2YXIgYj1hLmEucHJlc2VudGF0aW9uVGltZWxpbmUuZGEoKTtJbmZpbml0eT5iP2EuZi56YShiKTphLmYuemEoTWF0aC5wb3coMiwzMikpfVxuJGIucHJvdG90eXBlLlg9ZnVuY3Rpb24oYSl7aWYoIXRoaXMuYyYmIWEuZ2EmJm51bGwhPWEuYWEmJiFhLmJhKWlmKGEuYWE9bnVsbCxhLmxhKWljKHRoaXMsYSk7ZWxzZXt0cnl7dmFyIGI9bmModGhpcyxhKTtudWxsIT1iJiZsYyh0aGlzLGEsYil9Y2F0Y2goYyl7dGhpcy5qKGMpO3JldHVybn1iPUModGhpcy5iKTtvYyh0aGlzLGEpO2IuZXZlcnkoZnVuY3Rpb24oYSl7cmV0dXJuIGEuZW5kT2ZTdHJlYW19KSYmdGhpcy5mLmVuZE9mU3RyZWFtKCl9fTtcbmZ1bmN0aW9uIG5jKGEsYil7dmFyIGM9VGIoYS5tKSxkLGU7ZT1hLmY7dmFyIGY9Yi50eXBlO2U9XCJ0ZXh0XCI9PWY/ZS5iLmE6QmIoR2IoZSxmKSk7dmFyIGY9Yi50YSYmYi5WP2EuYS5wZXJpb2RzW2hjKGEsYi50YSldLnN0YXJ0VGltZStiLlYuZW5kVGltZTpjLGc9aGMoYSxiLnN0cmVhbSksaD1iYyhhLGYpLGw9YS5hLnBlcmlvZHNbaF07ZyE9aD9kPW51bGw6ZD1wYyhhLGIsYyxlLGgpO2lmKChkP2wuc3RhcnRUaW1lK2Quc3RhcnRUaW1lLWM6SGIoYS5mLGIudHlwZSxjKSk+PU1hdGgubWF4KGEuaSpNYXRoLm1heChhLmEubWluQnVmZmVyVGltZXx8MCxhLmcucmVidWZmZXJpbmdHb2FsKSxhLmkqYS5nLmJ1ZmZlcmluZ0dvYWwpKXJldHVybi41O2lmKGY+PWEuYS5wcmVzZW50YXRpb25UaW1lbGluZS5kYSgpKXJldHVybiBiLmVuZE9mU3RyZWFtPSEwLG51bGw7Yi5lbmRPZlN0cmVhbT0hMTtpZihoIT1nKXJldHVybiBiLkthPWgsbnVsbDtkPXBjKGEsYixjLGUsZyk7aWYoIWQpcmV0dXJuIDE7XG5xYyhhLGIsYyxnLGQpO3JldHVybiBudWxsfWZ1bmN0aW9uIHBjKGEsYixjLGQsZSl7aWYoYi5WJiZiLnN0cmVhbT09Yi50YSlyZXR1cm4gYz1iLlYucG9zaXRpb24rMSxyYyhhLGIsZSxjKTtjPWIuVj9iLnN0cmVhbS5maW5kU2VnbWVudFBvc2l0aW9uKE1hdGgubWF4KDAsYS5hLnBlcmlvZHNbaGMoYSxiLnRhKV0uc3RhcnRUaW1lK2IuVi5lbmRUaW1lLWEuYS5wZXJpb2RzW2VdLnN0YXJ0VGltZSkpOmIuc3RyZWFtLmZpbmRTZWdtZW50UG9zaXRpb24oTWF0aC5tYXgoMCwoZHx8YyktYS5hLnBlcmlvZHNbZV0uc3RhcnRUaW1lKSk7aWYobnVsbD09YylyZXR1cm4gbnVsbDt2YXIgZj1udWxsO251bGw9PWQmJihmPXJjKGEsYixlLE1hdGgubWF4KDAsYy0xKSkpO3JldHVybiBmfHxyYyhhLGIsZSxjKX1cbmZ1bmN0aW9uIHJjKGEsYixjLGQpe2M9YS5hLnBlcmlvZHNbY107Yj1iLnN0cmVhbS5nZXRTZWdtZW50UmVmZXJlbmNlKGQpO2lmKCFiKXJldHVybiBudWxsO2E9YS5hLnByZXNlbnRhdGlvblRpbWVsaW5lO2Q9YS5lYSgpO3JldHVybiBjLnN0YXJ0VGltZStiLmVuZFRpbWU8YS5zYSgpfHxjLnN0YXJ0VGltZStiLnN0YXJ0VGltZT5kP251bGw6Yn1cbmZ1bmN0aW9uIHFjKGEsYixjLGQsZSl7dmFyIGY9YS5hLnBlcmlvZHNbZF0sZz1iLnN0cmVhbSxoPWEuYS5wZXJpb2RzW2QrMV0sbD1udWxsLGw9aD9oLnN0YXJ0VGltZTphLmEucHJlc2VudGF0aW9uVGltZWxpbmUuZGEoKTtkPXNjKGEsYixkLGwpO2IuZ2E9ITA7Yi5KYT0hMTtoPXRjKGEsZSk7UHJvbWlzZS5hbGwoW2QsaF0pLnRoZW4oZnVuY3Rpb24oYSl7aWYoIXRoaXMuYyYmIXRoaXMucylyZXR1cm4gdWModGhpcyxiLGMsZixnLGUsYVsxXSl9LmJpbmQoYSkpLnRoZW4oZnVuY3Rpb24oKXt0aGlzLmN8fHRoaXMuc3x8KGIuZ2E9ITEsYi5aYT0hMSxsYyh0aGlzLGIsMCksdmModGhpcyxnKSl9LmJpbmQoYSkpW1wiY2F0Y2hcIl0oZnVuY3Rpb24oYSl7dGhpcy5jfHx0aGlzLnN8fChiLmdhPSExLDEwMDE9PWEuY29kZXx8MTAwMj09YS5jb2RlfHwxMDAzPT1hLmNvZGU/XCJ0ZXh0XCI9PWIudHlwZSYmdGhpcy5nLmlnbm9yZVRleHRTdHJlYW1GYWlsdXJlcyYmMTAwMT09YS5jb2RlP2RlbGV0ZSB0aGlzLmIudGV4dDpcbih0aGlzLmooYSksbGModGhpcyxiLDQpKTozMDE3PT1hLmNvZGU/d2ModGhpcyxiLGEpOnRoaXMuaihhKSl9LmJpbmQoYSkpfWZ1bmN0aW9uIHdjKGEsYixjKXtpZighQyhhLmIpLnNvbWUoZnVuY3Rpb24oYSl7cmV0dXJuIGEhPWImJmEuWmF9KSl7dmFyIGQ9TWF0aC5yb3VuZCgxMDAqYS5pKTtpZigyMDxkKWEuaS09LjI7ZWxzZSBpZig0PGQpYS5pLT0uMDQ7ZWxzZXthLnM9ITA7YS5qKGMpO3JldHVybn1iLlphPSEwfWxjKGEsYiw0KX1cbmZ1bmN0aW9uIHNjKGEsYixjLGQpe2lmKCFiLkphKXJldHVybiBQcm9taXNlLnJlc29sdmUoKTtjPUxiKGEuZixiLnR5cGUsYS5hLnBlcmlvZHNbY10uc3RhcnRUaW1lLWIuc3RyZWFtLnByZXNlbnRhdGlvblRpbWVPZmZzZXQpO2Q9bnVsbCE9ZD9NYihhLmYsYi50eXBlLGQpOlByb21pc2UucmVzb2x2ZSgpO2lmKCFiLnN0cmVhbS5pbml0U2VnbWVudFJlZmVyZW5jZSlyZXR1cm4gUHJvbWlzZS5hbGwoW2MsZF0pO2E9dGMoYSxiLnN0cmVhbS5pbml0U2VnbWVudFJlZmVyZW5jZSkudGhlbihmdW5jdGlvbihhKXtpZighdGhpcy5jKXJldHVybiBJYih0aGlzLmYsYi50eXBlLGEsbnVsbCxudWxsKX0uYmluZChhKSlbXCJjYXRjaFwiXShmdW5jdGlvbihhKXtiLkphPSEwO3JldHVybiBQcm9taXNlLnJlamVjdChhKX0pO3JldHVybiBQcm9taXNlLmFsbChbYyxkLGFdKX1cbmZ1bmN0aW9uIHVjKGEsYixjLGQsZSxmLGcpe3JldHVybiB4YyhhLGIsYykudGhlbihmdW5jdGlvbigpe2lmKCF0aGlzLmMpcmV0dXJuIEliKHRoaXMuZixiLnR5cGUsZyxmLnN0YXJ0VGltZStkLnN0YXJ0VGltZSxmLmVuZFRpbWUrZC5zdGFydFRpbWUpfS5iaW5kKGEpKS50aGVuKGZ1bmN0aW9uKCl7aWYoIXRoaXMuYylyZXR1cm4gYi50YT1lLGIuVj1mLFByb21pc2UucmVzb2x2ZSgpfS5iaW5kKGEpKX1mdW5jdGlvbiB4YyhhLGIsYyl7dmFyIGQ9RmIoYS5mLGIudHlwZSk7aWYobnVsbD09ZClyZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7Yz1jLWQtYS5nLmJ1ZmZlckJlaGluZDtyZXR1cm4gMD49Yz9Qcm9taXNlLnJlc29sdmUoKTphLmYucmVtb3ZlKGIudHlwZSxkLGQrYykudGhlbihmdW5jdGlvbigpe30uYmluZChhKSl9XG5mdW5jdGlvbiB2YyhhLGIpe2lmKCFhLkomJihhLko9QyhhLmIpLmV2ZXJ5KGZ1bmN0aW9uKGEpe3JldHVybiFhLmxhJiYhYS5iYSYmYS5WfSksYS5KKSl7dmFyIGM9aGMoYSxiKTthLmhbY118fG1jKGEsYykudGhlbihmdW5jdGlvbigpe3RoaXMudigpfS5iaW5kKGEpKVtcImNhdGNoXCJdKHYpO2ZvcihjPTA7YzxhLmEucGVyaW9kcy5sZW5ndGg7KytjKW1jKGEsYylbXCJjYXRjaFwiXSh2KTthLkEmJmEuQSgpfX1cbmZ1bmN0aW9uIG9jKGEsYil7aWYoYi5LYSE9aGMoYSxiLnN0cmVhbSkpe3ZhciBjPWIuS2EsZD1DKGEuYik7ZC5ldmVyeShmdW5jdGlvbihhKXtyZXR1cm4gYS5LYT09Y30pJiZkLmV2ZXJ5KHljKSYmbWMoYSxjKS50aGVuKGZ1bmN0aW9uKCl7aWYoIXRoaXMuYyl7dmFyIGE9dGhpcy5HKHRoaXMuYS5wZXJpb2RzW2NdKSxiO2ZvcihiIGluIHRoaXMuYilpZighYVtiXSl7dGhpcy5qKG5ldyBxKDUsNTAwNSkpO3JldHVybn1mb3IoYiBpbiBhKWlmKCEodGhpcy5iW2JdfHxcInRleHRcIj09YiYmdGhpcy5nLmlnbm9yZVRleHRTdHJlYW1GYWlsdXJlcykpe3RoaXMuaihuZXcgcSg1LDUwMDUpKTtyZXR1cm59Zm9yKGIgaW4gdGhpcy5iKXtnYyh0aGlzLGIsYVtiXSwhMSk7dmFyIGQ9dGhpcy5iW2JdO3ljKGQpJiZsYyh0aGlzLGQsMCl9dGhpcy52KCl9fS5iaW5kKGEpKVtcImNhdGNoXCJdKHYpfX1mdW5jdGlvbiB5YyhhKXtyZXR1cm4hYS5nYSYmbnVsbD09YS5hYSYmIWEubGEmJiFhLmJhfVxuZnVuY3Rpb24gYmMoYSxiKXtmb3IodmFyIGM9YS5hLnBlcmlvZHMubGVuZ3RoLTE7MDxjOy0tYylpZihiPj1hLmEucGVyaW9kc1tjXS5zdGFydFRpbWUpcmV0dXJuIGM7cmV0dXJuIDB9ZnVuY3Rpb24gaGMoYSxiKXtmb3IodmFyIGM9MDtjPGEuYS5wZXJpb2RzLmxlbmd0aDsrK2MpZm9yKHZhciBkPWEuYS5wZXJpb2RzW2NdLGU9MDtlPGQuc3RyZWFtU2V0cy5sZW5ndGg7KytlKWlmKDA8PWQuc3RyZWFtU2V0c1tlXS5zdHJlYW1zLmluZGV4T2YoYikpcmV0dXJuIGM7cmV0dXJuLTF9ZnVuY3Rpb24gdGMoYSxiKXt2YXIgYz1IYShiLmEoKSxhLmcucmV0cnlQYXJhbWV0ZXJzKTtpZihiLkx8fG51bGwhPWIuRCl7dmFyIGQ9XCJieXRlcz1cIitiLkwrXCItXCI7bnVsbCE9Yi5EJiYoZCs9Yi5EKTtjLmhlYWRlcnMuUmFuZ2U9ZH1yZXR1cm4gYS5TLnJlcXVlc3QoMSxjKS50aGVuKGZ1bmN0aW9uKGEpe3JldHVybiBhLmRhdGF9KX1cbmZ1bmN0aW9uIGljKGEsYil7Yi5sYT0hMTtiLmJhPSEwO0tiKGEuZixiLnR5cGUpLnRoZW4oZnVuY3Rpb24oKXt0aGlzLmN8fChiLnRhPW51bGwsYi5WPW51bGwsYi5iYT0hMSxsYyh0aGlzLGIsMCkpfS5iaW5kKGEpKX1mdW5jdGlvbiBsYyhhLGIsYyl7Yi5hYT13aW5kb3cuc2V0VGltZW91dChhLlguYmluZChhLGIpLDFFMypjKX1mdW5jdGlvbiBhYyhhKXtudWxsIT1hLmFhJiYod2luZG93LmNsZWFyVGltZW91dChhLmFhKSxhLmFhPW51bGwpfTtmdW5jdGlvbiB6Yygpe3RoaXMuYT1Qcm9taXNlLnJlc29sdmUoKTt0aGlzLmM9dGhpcy5iPXRoaXMuZj0hMTt0aGlzLmc9bmV3IFByb21pc2UoZnVuY3Rpb24oYSl7dGhpcy5oPWF9LmJpbmQodGhpcykpfXpjLnByb3RvdHlwZS50aGVuPWZ1bmN0aW9uKGEpe3RoaXMuYT10aGlzLmEudGhlbihhKS50aGVuKGZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmM/KHRoaXMuaCgpLFByb21pc2UucmVqZWN0KHRoaXMuaSkpOlByb21pc2UucmVzb2x2ZShhKX0uYmluZCh0aGlzKSk7cmV0dXJuIHRoaXN9O2Z1bmN0aW9uIEFjKGEpe2EuZnx8KGEuYT1hLmEudGhlbihmdW5jdGlvbihhKXt0aGlzLmI9ITA7cmV0dXJuIFByb21pc2UucmVzb2x2ZShhKX0uYmluZChhKSxmdW5jdGlvbihhKXt0aGlzLmI9ITA7cmV0dXJuIFByb21pc2UucmVqZWN0KGEpfS5iaW5kKGEpKSk7YS5mPSEwO3JldHVybiBhLmF9XG5mdW5jdGlvbiBCYyhhLGIpe2lmKGEuYilyZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7YS5jPSEwO2EuaT1iO3JldHVybiBhLmd9O2Z1bmN0aW9uIENjKGEsYixjLGQsZSl7dmFyIGY9ZSBpbiBkLGc7Zm9yKGcgaW4gYil7dmFyIGg9ZStcIi5cIitnLGw9Zj9kW2VdOmNbZ10sbj0hIXtcIi5hYnIubWFuYWdlclwiOiEwfVtoXTtpZihmfHxnIGluIGEpdm9pZCAwPT09YltnXT92b2lkIDA9PT1sfHxmP2RlbGV0ZSBhW2ddOmFbZ109bDpuP2FbZ109YltnXTpcIm9iamVjdFwiPT10eXBlb2YgYVtnXSYmXCJvYmplY3RcIj09dHlwZW9mIGJbZ10/Q2MoYVtnXSxiW2ddLGwsZCxoKTp0eXBlb2YgYltnXT09dHlwZW9mIGwmJihhW2ddPWJbZ10pfX07ZnVuY3Rpb24gSChhLGIpe3ZhciBjPWJ8fHt9LGQ7Zm9yKGQgaW4gYyl0aGlzW2RdPWNbZF07dGhpcy5kZWZhdWx0UHJldmVudGVkPXRoaXMuY2FuY2VsYWJsZT10aGlzLmJ1YmJsZXM9ITE7dGhpcy50aW1lU3RhbXA9d2luZG93LnBlcmZvcm1hbmNlP3dpbmRvdy5wZXJmb3JtYW5jZS5ub3coKTpEYXRlLm5vdygpO3RoaXMudHlwZT1hO3RoaXMuaXNUcnVzdGVkPSExO3RoaXMudGFyZ2V0PXRoaXMuY3VycmVudFRhcmdldD1udWxsO3RoaXMuYT0hMX1ILnByb3RvdHlwZS5wcmV2ZW50RGVmYXVsdD1mdW5jdGlvbigpe307SC5wcm90b3R5cGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uPWZ1bmN0aW9uKCl7dGhpcy5hPSEwfTtILnByb3RvdHlwZS5zdG9wUHJvcGFnYXRpb249ZnVuY3Rpb24oKXt9O2Z1bmN0aW9uIHAoKXt0aGlzLkFhPW5ldyBKYTt0aGlzLlM9dGhpc31wLnByb3RvdHlwZS5hZGRFdmVudExpc3RlbmVyPWZ1bmN0aW9uKGEsYil7dGhpcy5BYS5wdXNoKGEsYil9O3AucHJvdG90eXBlLnJlbW92ZUV2ZW50TGlzdGVuZXI9ZnVuY3Rpb24oYSxiKXt0aGlzLkFhLnJlbW92ZShhLGIpfTtwLnByb3RvdHlwZS5kaXNwYXRjaEV2ZW50PWZ1bmN0aW9uKGEpe2Zvcih2YXIgYj10aGlzLkFhLmdldChhLnR5cGUpfHxbXSxjPTA7YzxiLmxlbmd0aDsrK2Mpe2EudGFyZ2V0PXRoaXMuUzthLmN1cnJlbnRUYXJnZXQ9dGhpcy5TO3ZhciBkPWJbY107dHJ5e2QuaGFuZGxlRXZlbnQ/ZC5oYW5kbGVFdmVudChhKTpkLmNhbGwodGhpcyxhKX1jYXRjaChlKXt9aWYoYS5hKWJyZWFrfXJldHVybiBhLmRlZmF1bHRQcmV2ZW50ZWR9O2Z1bmN0aW9uIERjKGEsYixjKXtyZXR1cm4gYz09Ynx8YT49RWMmJmM9PWIuc3BsaXQoXCItXCIpWzBdfHxhPj1GYyYmYy5zcGxpdChcIi1cIilbMF09PWIuc3BsaXQoXCItXCIpWzBdPyEwOiExfXZhciBFYz0xLEZjPTI7ZnVuY3Rpb24gR2MoYSl7YT1hLnRvTG93ZXJDYXNlKCkuc3BsaXQoXCItXCIpO3ZhciBiPUhjW2FbMF1dO2ImJihhWzBdPWIpO3JldHVybiBhLmpvaW4oXCItXCIpfVxudmFyIEhjPXthYXI6XCJhYVwiLGFiazpcImFiXCIsYWZyOlwiYWZcIixha2E6XCJha1wiLGFsYjpcInNxXCIsYW1oOlwiYW1cIixhcmE6XCJhclwiLGFyZzpcImFuXCIsYXJtOlwiaHlcIixhc206XCJhc1wiLGF2YTpcImF2XCIsYXZlOlwiYWVcIixheW06XCJheVwiLGF6ZTpcImF6XCIsYmFrOlwiYmFcIixiYW06XCJibVwiLGJhcTpcImV1XCIsYmVsOlwiYmVcIixiZW46XCJiblwiLGJpaDpcImJoXCIsYmlzOlwiYmlcIixib2Q6XCJib1wiLGJvczpcImJzXCIsYnJlOlwiYnJcIixidWw6XCJiZ1wiLGJ1cjpcIm15XCIsY2F0OlwiY2FcIixjZXM6XCJjc1wiLGNoYTpcImNoXCIsY2hlOlwiY2VcIixjaGk6XCJ6aFwiLGNodTpcImN1XCIsY2h2OlwiY3ZcIixjb3I6XCJrd1wiLGNvczpcImNvXCIsY3JlOlwiY3JcIixjeW06XCJjeVwiLGN6ZTpcImNzXCIsZGFuOlwiZGFcIixkZXU6XCJkZVwiLGRpdjpcImR2XCIsZHV0OlwibmxcIixkem86XCJkelwiLGVsbDpcImVsXCIsZW5nOlwiZW5cIixlcG86XCJlb1wiLGVzdDpcImV0XCIsZXVzOlwiZXVcIixld2U6XCJlZVwiLGZhbzpcImZvXCIsZmFzOlwiZmFcIixmaWo6XCJmalwiLGZpbjpcImZpXCIsZnJhOlwiZnJcIixmcmU6XCJmclwiLFxuZnJ5OlwiZnlcIixmdWw6XCJmZlwiLGdlbzpcImthXCIsZ2VyOlwiZGVcIixnbGE6XCJnZFwiLGdsZTpcImdhXCIsZ2xnOlwiZ2xcIixnbHY6XCJndlwiLGdyZTpcImVsXCIsZ3JuOlwiZ25cIixndWo6XCJndVwiLGhhdDpcImh0XCIsaGF1OlwiaGFcIixoZWI6XCJoZVwiLGhlcjpcImh6XCIsaGluOlwiaGlcIixobW86XCJob1wiLGhydjpcImhyXCIsaHVuOlwiaHVcIixoeWU6XCJoeVwiLGlibzpcImlnXCIsaWNlOlwiaXNcIixpZG86XCJpb1wiLGlpaTpcImlpXCIsaWt1OlwiaXVcIixpbGU6XCJpZVwiLGluYTpcImlhXCIsaW5kOlwiaWRcIixpcGs6XCJpa1wiLGlzbDpcImlzXCIsaXRhOlwiaXRcIixqYXY6XCJqdlwiLGpwbjpcImphXCIsa2FsOlwia2xcIixrYW46XCJrblwiLGthczpcImtzXCIsa2F0Olwia2FcIixrYXU6XCJrclwiLGthejpcImtrXCIsa2htOlwia21cIixraWs6XCJraVwiLGtpbjpcInJ3XCIsa2lyOlwia3lcIixrb206XCJrdlwiLGtvbjpcImtnXCIsa29yOlwia29cIixrdWE6XCJralwiLGt1cjpcImt1XCIsbGFvOlwibG9cIixsYXQ6XCJsYVwiLGxhdjpcImx2XCIsbGltOlwibGlcIixsaW46XCJsblwiLGxpdDpcImx0XCIsbHR6OlwibGJcIixsdWI6XCJsdVwiLFxubHVnOlwibGdcIixtYWM6XCJta1wiLG1haDpcIm1oXCIsbWFsOlwibWxcIixtYW86XCJtaVwiLG1hcjpcIm1yXCIsbWF5OlwibXNcIixta2Q6XCJta1wiLG1sZzpcIm1nXCIsbWx0OlwibXRcIixtb246XCJtblwiLG1yaTpcIm1pXCIsbXNhOlwibXNcIixteWE6XCJteVwiLG5hdTpcIm5hXCIsbmF2OlwibnZcIixuYmw6XCJuclwiLG5kZTpcIm5kXCIsbmRvOlwibmdcIixuZXA6XCJuZVwiLG5sZDpcIm5sXCIsbm5vOlwibm5cIixub2I6XCJuYlwiLG5vcjpcIm5vXCIsbnlhOlwibnlcIixvY2k6XCJvY1wiLG9qaTpcIm9qXCIsb3JpOlwib3JcIixvcm06XCJvbVwiLG9zczpcIm9zXCIscGFuOlwicGFcIixwZXI6XCJmYVwiLHBsaTpcInBpXCIscG9sOlwicGxcIixwb3I6XCJwdFwiLHB1czpcInBzXCIscXVlOlwicXVcIixyb2g6XCJybVwiLHJvbjpcInJvXCIscnVtOlwicm9cIixydW46XCJyblwiLHJ1czpcInJ1XCIsc2FnOlwic2dcIixzYW46XCJzYVwiLHNpbjpcInNpXCIsc2xrOlwic2tcIixzbG86XCJza1wiLHNsdjpcInNsXCIsc21lOlwic2VcIixzbW86XCJzbVwiLHNuYTpcInNuXCIsc25kOlwic2RcIixzb206XCJzb1wiLHNvdDpcInN0XCIsc3BhOlwiZXNcIixzcWk6XCJzcVwiLFxuc3JkOlwic2NcIixzcnA6XCJzclwiLHNzdzpcInNzXCIsc3VuOlwic3VcIixzd2E6XCJzd1wiLHN3ZTpcInN2XCIsdGFoOlwidHlcIix0YW06XCJ0YVwiLHRhdDpcInR0XCIsdGVsOlwidGVcIix0Z2s6XCJ0Z1wiLHRnbDpcInRsXCIsdGhhOlwidGhcIix0aWI6XCJib1wiLHRpcjpcInRpXCIsdG9uOlwidG9cIix0c246XCJ0blwiLHRzbzpcInRzXCIsdHVrOlwidGtcIix0dXI6XCJ0clwiLHR3aTpcInR3XCIsdWlnOlwidWdcIix1a3I6XCJ1a1wiLHVyZDpcInVyXCIsdXpiOlwidXpcIix2ZW46XCJ2ZVwiLHZpZTpcInZpXCIsdm9sOlwidm9cIix3ZWw6XCJjeVwiLHdsbjpcIndhXCIsd29sOlwid29cIix4aG86XCJ4aFwiLHlpZDpcInlpXCIseW9yOlwieW9cIix6aGE6XCJ6YVwiLHpobzpcInpoXCIsenVsOlwienVcIn07ZnVuY3Rpb24gSWMoYSxiLGMpe3ZhciBkPSExO2Euc3RyZWFtU2V0cy5mb3JFYWNoKGZ1bmN0aW9uKGEpe2Euc3RyZWFtcy5mb3JFYWNoKGZ1bmN0aW9uKGYpe3ZhciBnPWYuYWxsb3dlZEJ5QXBwbGljYXRpb247Zi5hbGxvd2VkQnlBcHBsaWNhdGlvbj0hMDtpZihcInZpZGVvXCI9PWEudHlwZSl7aWYoZi53aWR0aDxiLm1pbldpZHRofHxmLndpZHRoPmIubWF4V2lkdGh8fGYud2lkdGg+Yy53aWR0aHx8Zi5oZWlnaHQ8Yi5taW5IZWlnaHR8fGYuaGVpZ2h0PmIubWF4SGVpZ2h0fHxmLmhlaWdodD5jLmhlaWdodHx8Zi53aWR0aCpmLmhlaWdodDxiLm1pblBpeGVsc3x8Zi53aWR0aCpmLmhlaWdodD5iLm1heFBpeGVsc3x8Zi5iYW5kd2lkdGg8Yi5taW5WaWRlb0JhbmR3aWR0aHx8Zi5iYW5kd2lkdGg+Yi5tYXhWaWRlb0JhbmR3aWR0aClmLmFsbG93ZWRCeUFwcGxpY2F0aW9uPSExfWVsc2VcImF1ZGlvXCI9PWEudHlwZSYmKGYuYmFuZHdpZHRoPGIubWluQXVkaW9CYW5kd2lkdGh8fGYuYmFuZHdpZHRoPlxuYi5tYXhBdWRpb0JhbmR3aWR0aCkmJihmLmFsbG93ZWRCeUFwcGxpY2F0aW9uPSExKTtnIT1mLmFsbG93ZWRCeUFwcGxpY2F0aW9uJiYoZD0hMCl9KX0pO3JldHVybiBkfVxuZnVuY3Rpb24gSmMoYSxiLGMpe3ZhciBkPVwiXCIsZT1udWxsO2EmJmEuQSYmKGQ9YS5rZXlTeXN0ZW0oKSxlPWEubSk7Zm9yKGE9MDthPGMuc3RyZWFtU2V0cy5sZW5ndGg7KythKXt2YXIgZj1jLnN0cmVhbVNldHNbYV07aWYoZCYmZi5kcm1JbmZvcy5sZW5ndGgmJiFmLmRybUluZm9zLnNvbWUoZnVuY3Rpb24oYSl7cmV0dXJuIGEua2V5U3lzdGVtPT1kfSkpYy5zdHJlYW1TZXRzLnNwbGljZShhLDEpLC0tYTtlbHNle2Zvcih2YXIgZz1iW2YudHlwZV0saD0wO2g8Zi5zdHJlYW1zLmxlbmd0aDsrK2gpe3ZhciBsPWYuc3RyZWFtc1toXSxuPWwubWltZVR5cGU7bC5jb2RlY3MmJihuKz0nOyBjb2RlY3M9XCInK2wuY29kZWNzKydcIicpO0Vbbl18fE1lZGlhU291cmNlLmlzVHlwZVN1cHBvcnRlZChuKT9lJiZsLmVuY3J5cHRlZCYmMD5lLmluZGV4T2Yobik/KGYuc3RyZWFtcy5zcGxpY2UoaCwxKSwtLWgpOiFnfHxsLm1pbWVUeXBlPT1nLm1pbWVUeXBlJiZsLmNvZGVjcy5zcGxpdChcIi5cIilbMF09PVxuZy5jb2RlY3Muc3BsaXQoXCIuXCIpWzBdfHwoZi5zdHJlYW1zLnNwbGljZShoLDEpLC0taCk6KGYuc3RyZWFtcy5zcGxpY2UoaCwxKSwtLWgpfWYuc3RyZWFtcy5sZW5ndGh8fChjLnN0cmVhbVNldHMuc3BsaWNlKGEsMSksLS1hKX19fVxuZnVuY3Rpb24gS2MoYSxiKXtyZXR1cm4gYS5zdHJlYW1TZXRzLm1hcChmdW5jdGlvbihhKXt2YXIgZD1iP2JbYS50eXBlXTpudWxsO3JldHVybiBhLnN0cmVhbXMuZmlsdGVyKGZ1bmN0aW9uKGEpe3JldHVybiBhLmFsbG93ZWRCeUFwcGxpY2F0aW9uJiZhLmFsbG93ZWRCeUtleVN5c3RlbX0pLm1hcChmdW5jdGlvbihiKXtyZXR1cm57aWQ6Yi5pZCxhY3RpdmU6ZD09Yix0eXBlOmEudHlwZSxiYW5kd2lkdGg6Yi5iYW5kd2lkdGgsbGFuZ3VhZ2U6YS5sYW5ndWFnZSxraW5kOmIua2luZHx8bnVsbCx3aWR0aDpiLndpZHRofHxudWxsLGhlaWdodDpiLmhlaWdodHx8bnVsbCxmcmFtZVJhdGU6Yi5mcmFtZVJhdGV8fHZvaWQgMCxjb2RlY3M6Yi5jb2RlY3N8fG51bGx9fSl9KS5yZWR1Y2UodSxbXSl9XG5mdW5jdGlvbiBMYyhhLGIpe2Zvcih2YXIgYz0wO2M8YS5zdHJlYW1TZXRzLmxlbmd0aDtjKyspZm9yKHZhciBkPWEuc3RyZWFtU2V0c1tjXSxlPTA7ZTxkLnN0cmVhbXMubGVuZ3RoO2UrKyl7dmFyIGY9ZC5zdHJlYW1zW2VdO2lmKGYuaWQ9PWIuaWQpcmV0dXJue3N0cmVhbTpmLFVjOmR9fXJldHVybiBudWxsfWZ1bmN0aW9uIE1jKGEpe3JldHVybiBhLnN0cmVhbXMuc29tZShmdW5jdGlvbihhKXtyZXR1cm4gYS5hbGxvd2VkQnlBcHBsaWNhdGlvbiYmYS5hbGxvd2VkQnlLZXlTeXN0ZW19KX1cbmZ1bmN0aW9uIE5jKGEsYixjKXt2YXIgZD17fTthLnN0cmVhbVNldHMuZm9yRWFjaChmdW5jdGlvbihhKXshTWMoYSl8fGEudHlwZSBpbiBkfHwoZFthLnR5cGVdPWEpfSk7dmFyIGU9MDthLnN0cmVhbVNldHMuZm9yRWFjaChmdW5jdGlvbihhKXtpZihNYyhhKSYmXCJ2aWRlb1wiPT1hLnR5cGUpe3ZhciBiPU9jKGEpO2I+ZT8oZT1iLGQudmlkZW89YSk6Yj09ZSYmUGMoYSk8UGMoZC52aWRlbykmJihkLnZpZGVvPWEpfX0pO2Euc3RyZWFtU2V0cy5mb3JFYWNoKGZ1bmN0aW9uKGEpe01jKGEpJiZhLnByaW1hcnkmJihkW2EudHlwZV0ucHJpbWFyeT9QYyhhKTxQYyhkW2EudHlwZV0pJiYoZFthLnR5cGVdPWEpOmRbYS50eXBlXT1hKX0pO1tGYyxFYywwXS5mb3JFYWNoKGZ1bmN0aW9uKGUpe2Euc3RyZWFtU2V0cy5mb3JFYWNoKGZ1bmN0aW9uKGEpe2lmKE1jKGEpKXt2YXIgaDtcImF1ZGlvXCI9PWEudHlwZT9oPWIucHJlZmVycmVkQXVkaW9MYW5ndWFnZTpcInRleHRcIj09YS50eXBlJiYoaD1iLnByZWZlcnJlZFRleHRMYW5ndWFnZSk7XG5pZihoKXtoPUdjKGgpO3ZhciBsPUdjKGEubGFuZ3VhZ2UpO0RjKGUsaCxsKSYmKGEubGFuZ3VhZ2U9PWRbYS50eXBlXS5sYW5ndWFnZT9QYyhhKTxQYyhkW2EudHlwZV0pJiYoZFthLnR5cGVdPWEpOmRbYS50eXBlXT1hLGMmJihjW2EudHlwZV09ITApKX19fSl9KTtyZXR1cm4gZH1mdW5jdGlvbiBQYyhhKXt2YXIgYj0wO2lmKCFhfHwxPmEuc3RyZWFtcy5sZW5ndGgpcmV0dXJuIGI7YS5zdHJlYW1zLmZvckVhY2goZnVuY3Rpb24oYSl7Yis9YS5iYW5kd2lkdGh9KTtyZXR1cm4gYi9hLnN0cmVhbXMubGVuZ3RofWZ1bmN0aW9uIE9jKGEpe3ZhciBiPTA7aWYoIWEpcmV0dXJuIGI7YS5zdHJlYW1zLmZvckVhY2goZnVuY3Rpb24oYSl7YS5oZWlnaHQ+YiYmKGI9YS5oZWlnaHQpfSk7cmV0dXJuIGJ9O2Z1bmN0aW9uIEkoYSxiKXtwLmNhbGwodGhpcyk7dGhpcy53PSExO3RoaXMuZj1hO3RoaXMubT1udWxsO3RoaXMudj1uZXcgejt0aGlzLmZiPW5ldyBqYTt0aGlzLm5hPXRoaXMuYz10aGlzLmw9dGhpcy5iPXRoaXMuaT10aGlzLm9hPXRoaXMuRz10aGlzLkE9dGhpcy5nPXRoaXMuaD1udWxsO3RoaXMuSGI9MUU5O3RoaXMubWE9W107dGhpcy5OYT0hMTt0aGlzLnFhPSEwO3RoaXMuaj1udWxsO3RoaXMucz17fTt0aGlzLmE9UWModGhpcyk7dGhpcy5CYT17d2lkdGg6SW5maW5pdHksaGVpZ2h0OkluZmluaXR5fTt0aGlzLkM9W107dGhpcy5YPXRoaXMuSj10aGlzLnBhPTA7YiYmYih0aGlzKTt0aGlzLmg9bmV3IHkodGhpcy5NYy5iaW5kKHRoaXMpKTt0aGlzLm9hPVJjKHRoaXMpO2Zvcih2YXIgYz0wO2M8dGhpcy5mLnRleHRUcmFja3MubGVuZ3RoOysrYyl7dmFyIGQ9dGhpcy5mLnRleHRUcmFja3NbY107ZC5tb2RlPVwiZGlzYWJsZWRcIjtcIlNoYWthIFBsYXllciBUZXh0VHJhY2tcIj09ZC5sYWJlbCYmXG4odGhpcy5tPWQpfXRoaXMubXx8KHRoaXMubT10aGlzLmYuYWRkVGV4dFRyYWNrKFwic3VidGl0bGVzXCIsXCJTaGFrYSBQbGF5ZXIgVGV4dFRyYWNrXCIpKTt0aGlzLm0ubW9kZT1cImhpZGRlblwiO0IodGhpcy52LHRoaXMuZixcImVycm9yXCIsdGhpcy5sYy5iaW5kKHRoaXMpKX1iYShJKTttKFwic2hha2EuUGxheWVyXCIsSSk7SS5wcm90b3R5cGUubz1mdW5jdGlvbigpe3RoaXMudz0hMDt2YXIgYT1Qcm9taXNlLnJlc29sdmUoKTt0aGlzLmomJihhPUJjKHRoaXMuaixuZXcgcSg3LDdFMykpKTtyZXR1cm4gYS50aGVuKGZ1bmN0aW9uKCl7dmFyIGE9UHJvbWlzZS5hbGwoW1NjKHRoaXMpLHRoaXMudj90aGlzLnYubygpOm51bGwsdGhpcy5oP3RoaXMuaC5vKCk6bnVsbF0pO3RoaXMuYT10aGlzLmg9dGhpcy5mYj10aGlzLnY9dGhpcy5tPXRoaXMuZj1udWxsO3JldHVybiBhfS5iaW5kKHRoaXMpKX07SS5wcm90b3R5cGUuZGVzdHJveT1JLnByb3RvdHlwZS5vO0kudmVyc2lvbj1cInYyLjAuMVwiO1xudmFyIFRjPXt9O0kucmVnaXN0ZXJTdXBwb3J0UGx1Z2luPWZ1bmN0aW9uKGEsYil7VGNbYV09Yn07SS5pc0Jyb3dzZXJTdXBwb3J0ZWQ9ZnVuY3Rpb24oKXtyZXR1cm4hIXdpbmRvdy5Qcm9taXNlJiYhIXdpbmRvdy5VaW50OEFycmF5JiYhIUFycmF5LnByb3RvdHlwZS5mb3JFYWNoJiYhIXdpbmRvdy5NZWRpYVNvdXJjZSYmISF3aW5kb3cuTWVkaWFLZXlzJiYhIXdpbmRvdy5uYXZpZ2F0b3ImJiEhd2luZG93Lm5hdmlnYXRvci5yZXF1ZXN0TWVkaWFLZXlTeXN0ZW1BY2Nlc3MmJiEhd2luZG93Lk1lZGlhS2V5U3lzdGVtQWNjZXNzJiYhIXdpbmRvdy5NZWRpYUtleVN5c3RlbUFjY2Vzcy5wcm90b3R5cGUuZ2V0Q29uZmlndXJhdGlvbn07SS5wcm9iZVN1cHBvcnQ9ZnVuY3Rpb24oKXtyZXR1cm4gcWIoKS50aGVuKGZ1bmN0aW9uKGEpe3ZhciBiPXRiKCksYz1FYigpO2E9e21hbmlmZXN0OmIsbWVkaWE6Yyxkcm06YX07Zm9yKHZhciBkIGluIFRjKWFbZF09VGNbZF0oKTtyZXR1cm4gYX0pfTtcbkkucHJvdG90eXBlLmxvYWQ9ZnVuY3Rpb24oYSxiLGMpe3ZhciBkPXRoaXMuZWIoKSxlPW5ldyB6Yzt0aGlzLmo9ZTt0aGlzLmRpc3BhdGNoRXZlbnQobmV3IEgoXCJsb2FkaW5nXCIpKTtyZXR1cm4gQWMoZS50aGVuKGZ1bmN0aW9uKCl7cmV0dXJuIGR9KS50aGVuKGZ1bmN0aW9uKCl7cmV0dXJuIHViKGEsdGhpcy5oLHRoaXMuYS5tYW5pZmVzdC5yZXRyeVBhcmFtZXRlcnMsYyl9LmJpbmQodGhpcykpLnRoZW4oZnVuY3Rpb24oYil7dGhpcy5sPW5ldyBiO3RoaXMubC5jb25maWd1cmUodGhpcy5hLm1hbmlmZXN0KTtyZXR1cm4gdGhpcy5sLnN0YXJ0KGEsdGhpcy5oLHRoaXMuTGEuYmluZCh0aGlzKSx0aGlzLiQuYmluZCh0aGlzKSx0aGlzLkpjLmJpbmQodGhpcykpfS5iaW5kKHRoaXMpKS50aGVuKGZ1bmN0aW9uKGIpe3RoaXMuYz1iO3RoaXMubmE9YTt0aGlzLmc9bmV3IGFiKHRoaXMuaCx0aGlzLiQuYmluZCh0aGlzKSx0aGlzLktjLmJpbmQodGhpcykpO3RoaXMuZy5jb25maWd1cmUodGhpcy5hLmRybSk7XG5yZXR1cm4gdGhpcy5nLmluaXQoYiwhMSl9LmJpbmQodGhpcykpLnRoZW4oZnVuY3Rpb24oKXt0aGlzLmMucGVyaW9kcy5mb3JFYWNoKHRoaXMuTGEuYmluZCh0aGlzKSk7dGhpcy5YPURhdGUubm93KCkvMUUzO3JldHVybiBQcm9taXNlLmFsbChbZGIodGhpcy5nLHRoaXMuZiksdGhpcy5vYV0pfS5iaW5kKHRoaXMpKS50aGVuKGZ1bmN0aW9uKCl7dGhpcy5pPW5ldyBRYih0aGlzLmYsdGhpcy5jLnByZXNlbnRhdGlvblRpbWVsaW5lLDEqTWF0aC5tYXgodGhpcy5jLm1pbkJ1ZmZlclRpbWV8fDAsdGhpcy5hLnN0cmVhbWluZy5yZWJ1ZmZlcmluZ0dvYWwpLGJ8fG51bGwsdGhpcy5GYi5iaW5kKHRoaXMpLHRoaXMuTGMuYmluZCh0aGlzKSk7dGhpcy5HPW5ldyBEYih0aGlzLmYsdGhpcy5BLHRoaXMubSk7dGhpcy5iPW5ldyAkYih0aGlzLmksdGhpcy5HLHRoaXMuaCx0aGlzLmMsdGhpcy5JYy5iaW5kKHRoaXMpLHRoaXMuS2IuYmluZCh0aGlzKSx0aGlzLiQuYmluZCh0aGlzKSk7dGhpcy5iLmNvbmZpZ3VyZSh0aGlzLmEuc3RyZWFtaW5nKTtcbnJldHVybiB0aGlzLmIuaW5pdCgpfS5iaW5kKHRoaXMpKS50aGVuKGZ1bmN0aW9uKCl7dGhpcy5jLnBlcmlvZHMuZm9yRWFjaCh0aGlzLkxhLmJpbmQodGhpcykpO1VjKHRoaXMpO1ZjKHRoaXMpO3RoaXMuYS5hYnIubWFuYWdlci5pbml0KHRoaXMuYmIuYmluZCh0aGlzKSk7dGhpcy5qPW51bGx9LmJpbmQodGhpcykpKVtcImNhdGNoXCJdKGZ1bmN0aW9uKGEpe3RoaXMuaj09ZSYmKHRoaXMuaj1udWxsLHRoaXMuZGlzcGF0Y2hFdmVudChuZXcgSChcInVubG9hZGluZ1wiKSkpO3JldHVybiBQcm9taXNlLnJlamVjdChhKX0uYmluZCh0aGlzKSl9O0kucHJvdG90eXBlLmxvYWQ9SS5wcm90b3R5cGUubG9hZDtmdW5jdGlvbiBSYyhhKXthLkE9bmV3IE1lZGlhU291cmNlO3ZhciBiPW5ldyB3O0IoYS52LGEuQSxcInNvdXJjZW9wZW5cIixiLnJlc29sdmUpO2EuZi5zcmM9d2luZG93LlVSTC5jcmVhdGVPYmplY3RVUkwoYS5BKTtyZXR1cm4gYn1cbkkucHJvdG90eXBlLmNvbmZpZ3VyZT1mdW5jdGlvbihhKXthLmFiciYmYS5hYnIubWFuYWdlciYmYS5hYnIubWFuYWdlciE9dGhpcy5hLmFici5tYW5hZ2VyJiYodGhpcy5hLmFici5tYW5hZ2VyLnN0b3AoKSxhLmFici5tYW5hZ2VyLmluaXQodGhpcy5iYi5iaW5kKHRoaXMpKSk7Q2ModGhpcy5hLGEsUWModGhpcyksV2MoKSxcIlwiKTtYYyh0aGlzKX07SS5wcm90b3R5cGUuY29uZmlndXJlPUkucHJvdG90eXBlLmNvbmZpZ3VyZTtcbmZ1bmN0aW9uIFhjKGEpe2EubCYmYS5sLmNvbmZpZ3VyZShhLmEubWFuaWZlc3QpO2EuZyYmYS5nLmNvbmZpZ3VyZShhLmEuZHJtKTthLmImJihhLmIuY29uZmlndXJlKGEuYS5zdHJlYW1pbmcpLGEuYy5wZXJpb2RzLmZvckVhY2goYS5MYS5iaW5kKGEpKSxZYyhhLGRjKGEuYikpKTthLmEuYWJyLmVuYWJsZWQmJiFhLnFhP2EuYS5hYnIubWFuYWdlci5lbmFibGUoKTphLmEuYWJyLm1hbmFnZXIuZGlzYWJsZSgpO2EuYS5hYnIubWFuYWdlci5zZXREZWZhdWx0RXN0aW1hdGUoYS5hLmFici5kZWZhdWx0QmFuZHdpZHRoRXN0aW1hdGUpfUkucHJvdG90eXBlLmdldENvbmZpZ3VyYXRpb249ZnVuY3Rpb24oKXt2YXIgYT1RYyh0aGlzKTtDYyhhLHRoaXMuYSxRYyh0aGlzKSxXYygpLFwiXCIpO3JldHVybiBhfTtJLnByb3RvdHlwZS5nZXRDb25maWd1cmF0aW9uPUkucHJvdG90eXBlLmdldENvbmZpZ3VyYXRpb247XG5JLnByb3RvdHlwZS5BYz1mdW5jdGlvbigpe3ZhciBhPVFjKHRoaXMpO2EuYWJyJiZhLmFici5tYW5hZ2VyJiZhLmFici5tYW5hZ2VyIT10aGlzLmEuYWJyLm1hbmFnZXImJih0aGlzLmEuYWJyLm1hbmFnZXIuc3RvcCgpLGEuYWJyLm1hbmFnZXIuaW5pdCh0aGlzLmJiLmJpbmQodGhpcykpKTt0aGlzLmE9UWModGhpcyk7WGModGhpcyl9O0kucHJvdG90eXBlLnJlc2V0Q29uZmlndXJhdGlvbj1JLnByb3RvdHlwZS5BYztJLnByb3RvdHlwZS5rYj1mdW5jdGlvbigpe3JldHVybiB0aGlzLmh9O0kucHJvdG90eXBlLmdldE5ldHdvcmtpbmdFbmdpbmU9SS5wcm90b3R5cGUua2I7SS5wcm90b3R5cGUuU2I9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5uYX07SS5wcm90b3R5cGUuZ2V0TWFuaWZlc3RVcmk9SS5wcm90b3R5cGUuU2I7SS5wcm90b3R5cGUuVT1mdW5jdGlvbigpe3JldHVybiB0aGlzLmM/dGhpcy5jLnByZXNlbnRhdGlvblRpbWVsaW5lLlUoKTohMX07XG5JLnByb3RvdHlwZS5pc0xpdmU9SS5wcm90b3R5cGUuVTtJLnByb3RvdHlwZS5mYT1mdW5jdGlvbigpe3JldHVybiB0aGlzLmM/dGhpcy5jLnByZXNlbnRhdGlvblRpbWVsaW5lLmZhKCk6ITF9O0kucHJvdG90eXBlLmlzSW5Qcm9ncmVzcz1JLnByb3RvdHlwZS5mYTtJLnByb3RvdHlwZS5EYz1mdW5jdGlvbigpe3ZhciBhPTAsYj0wO3RoaXMuYyYmKGI9dGhpcy5jLnByZXNlbnRhdGlvblRpbWVsaW5lLGE9Yi5zYSgpLGI9Yi5SYSgpKTtyZXR1cm57c3RhcnQ6YSxlbmQ6Yn19O0kucHJvdG90eXBlLnNlZWtSYW5nZT1JLnByb3RvdHlwZS5EYztJLnByb3RvdHlwZS5rZXlTeXN0ZW09ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5nP3RoaXMuZy5rZXlTeXN0ZW0oKTpcIlwifTtJLnByb3RvdHlwZS5rZXlTeXN0ZW09SS5wcm90b3R5cGUua2V5U3lzdGVtO0kucHJvdG90eXBlLmRybUluZm89ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5nP3RoaXMuZy5iOm51bGx9O0kucHJvdG90eXBlLmRybUluZm89SS5wcm90b3R5cGUuZHJtSW5mbztcbkkucHJvdG90eXBlLldiPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuTmF9O0kucHJvdG90eXBlLmlzQnVmZmVyaW5nPUkucHJvdG90eXBlLldiO0kucHJvdG90eXBlLmViPWZ1bmN0aW9uKCl7aWYodGhpcy53KXJldHVybiBQcm9taXNlLnJlc29sdmUoKTt0aGlzLmRpc3BhdGNoRXZlbnQobmV3IEgoXCJ1bmxvYWRpbmdcIikpO2lmKHRoaXMuail7dmFyIGE9bmV3IHEoNyw3RTMpO3JldHVybiBCYyh0aGlzLmosYSkudGhlbih0aGlzLnliLmJpbmQodGhpcykpfXJldHVybiB0aGlzLnliKCl9O0kucHJvdG90eXBlLnVubG9hZD1JLnByb3RvdHlwZS5lYjtJLnByb3RvdHlwZS5RYT1mdW5jdGlvbigpe3JldHVybiB0aGlzLmk/dGhpcy5pLlFhKCk6MH07SS5wcm90b3R5cGUuZ2V0UGxheWJhY2tSYXRlPUkucHJvdG90eXBlLlFhO0kucHJvdG90eXBlLlhjPWZ1bmN0aW9uKGEpe3RoaXMuaSYmWGIodGhpcy5pLGEpfTtJLnByb3RvdHlwZS50cmlja1BsYXk9SS5wcm90b3R5cGUuWGM7XG5JLnByb3RvdHlwZS5MYj1mdW5jdGlvbigpe3RoaXMuaSYmWGIodGhpcy5pLDEpfTtJLnByb3RvdHlwZS5jYW5jZWxUcmlja1BsYXk9SS5wcm90b3R5cGUuTGI7SS5wcm90b3R5cGUuZ2V0VHJhY2tzPWZ1bmN0aW9uKCl7aWYoIXRoaXMuYilyZXR1cm5bXTt2YXIgYT1lYyh0aGlzLmIpO3JldHVybiBLYyhkYyh0aGlzLmIpLGEpLmZpbHRlcihmdW5jdGlvbihhKXtyZXR1cm4gMD50aGlzLm1hLmluZGV4T2YoYS5pZCl9LmJpbmQodGhpcykpfTtJLnByb3RvdHlwZS5nZXRUcmFja3M9SS5wcm90b3R5cGUuZ2V0VHJhY2tzO1xuSS5wcm90b3R5cGUuRWM9ZnVuY3Rpb24oYSxiKXtpZih0aGlzLmIpe3ZhciBjPUxjKGRjKHRoaXMuYiksYSk7aWYoYyl7dmFyIGQ9Yy5zdHJlYW07ZC5hbGxvd2VkQnlBcHBsaWNhdGlvbiYmZC5hbGxvd2VkQnlLZXlTeXN0ZW0mJih0aGlzLkMucHVzaCh7dGltZXN0YW1wOkRhdGUubm93KCkvMUUzLGlkOmQuaWQsdHlwZTphLnR5cGUsZnJvbUFkYXB0YXRpb246ITF9KSxjPXt9LGNbYS50eXBlXT1kLFwidGV4dFwiIT1hLnR5cGUmJihkPWVjKHRoaXMuYikudGV4dCx0aGlzLmNvbmZpZ3VyZSh7YWJyOntlbmFibGVkOiExfX0pLGMudGV4dD1kKSxaYyh0aGlzLGMsYikpfX19O0kucHJvdG90eXBlLnNlbGVjdFRyYWNrPUkucHJvdG90eXBlLkVjO0kucHJvdG90eXBlLlpiPWZ1bmN0aW9uKCl7cmV0dXJuXCJzaG93aW5nXCI9PXRoaXMubS5tb2RlfTtJLnByb3RvdHlwZS5pc1RleHRUcmFja1Zpc2libGU9SS5wcm90b3R5cGUuWmI7XG5JLnByb3RvdHlwZS5HYz1mdW5jdGlvbihhKXt0aGlzLm0ubW9kZT1hP1wic2hvd2luZ1wiOlwiaGlkZGVuXCI7JGModGhpcyl9O0kucHJvdG90eXBlLnNldFRleHRUcmFja1Zpc2liaWxpdHk9SS5wcm90b3R5cGUuR2M7XG5JLnByb3RvdHlwZS5nZXRTdGF0cz1mdW5jdGlvbigpe2FkKHRoaXMpO3ZhciBhPXt9LGI9e30sYz10aGlzLmYmJnRoaXMuZi5nZXRWaWRlb1BsYXliYWNrUXVhbGl0eT90aGlzLmYuZ2V0VmlkZW9QbGF5YmFja1F1YWxpdHkoKTp7fTt0aGlzLmImJihiPWVjKHRoaXMuYiksYT1iLnZpZGVvfHx7fSxiPWIuYXVkaW98fHt9KTtyZXR1cm57d2lkdGg6YS53aWR0aHx8MCxoZWlnaHQ6YS5oZWlnaHR8fDAsc3RyZWFtQmFuZHdpZHRoOmEuYmFuZHdpZHRoK2IuYmFuZHdpZHRofHwwLGRlY29kZWRGcmFtZXM6TnVtYmVyKGMudG90YWxWaWRlb0ZyYW1lcyksZHJvcHBlZEZyYW1lczpOdW1iZXIoYy5kcm9wcGVkVmlkZW9GcmFtZXMpLGVzdGltYXRlZEJhbmR3aWR0aDp0aGlzLmEuYWJyLm1hbmFnZXIuZ2V0QmFuZHdpZHRoRXN0aW1hdGUoKSxwbGF5VGltZTp0aGlzLnBhLGJ1ZmZlcmluZ1RpbWU6dGhpcy5KLHN3aXRjaEhpc3Rvcnk6dGhpcy5DLnNsaWNlKDApfX07XG5JLnByb3RvdHlwZS5nZXRTdGF0cz1JLnByb3RvdHlwZS5nZXRTdGF0cztcbkkucHJvdG90eXBlLmFkZFRleHRUcmFjaz1mdW5jdGlvbihhLGIsYyxkLGUpe2lmKCF0aGlzLmIpcmV0dXJuIFByb21pc2UucmVqZWN0KCk7Zm9yKHZhciBmPWRjKHRoaXMuYiksZyxoPTA7aDx0aGlzLmMucGVyaW9kcy5sZW5ndGg7aCsrKWlmKHRoaXMuYy5wZXJpb2RzW2hdPT1mKXtpZihoPT10aGlzLmMucGVyaW9kcy5sZW5ndGgtMSl7aWYoZz10aGlzLmMucHJlc2VudGF0aW9uVGltZWxpbmUuZGEoKS1mLnN0YXJ0VGltZSxJbmZpbml0eT09ZylyZXR1cm4gUHJvbWlzZS5yZWplY3QoKX1lbHNlIGc9dGhpcy5jLnBlcmlvZHNbaCsxXS5zdGFydFRpbWUtZi5zdGFydFRpbWU7YnJlYWt9dmFyIGw9e2lkOnRoaXMuSGIrKyxjcmVhdGVTZWdtZW50SW5kZXg6UHJvbWlzZS5yZXNvbHZlLmJpbmQoUHJvbWlzZSksZmluZFNlZ21lbnRQb3NpdGlvbjpmdW5jdGlvbigpe3JldHVybiAxfSxnZXRTZWdtZW50UmVmZXJlbmNlOmZ1bmN0aW9uKGIpe3JldHVybiAxIT1iP251bGw6bmV3IEYoMSwwLFxuZyxmdW5jdGlvbigpe3JldHVyblthXX0sMCxudWxsKX0saW5pdFNlZ21lbnRSZWZlcmVuY2U6bnVsbCxwcmVzZW50YXRpb25UaW1lT2Zmc2V0OjAsbWltZVR5cGU6ZCxjb2RlY3M6ZXx8XCJcIixiYW5kd2lkdGg6MCxraW5kOmMsZW5jcnlwdGVkOiExLGtleUlkOm51bGwsbGFuZ3VhZ2U6YixhbGxvd2VkQnlBcHBsaWNhdGlvbjohMCxhbGxvd2VkQnlLZXlTeXN0ZW06ITB9O2Q9e2xhbmd1YWdlOmIsdHlwZTpcInRleHRcIixwcmltYXJ5OiExLGRybUluZm9zOltdLHN0cmVhbXM6W2xdfTt0aGlzLm1hLnB1c2gobC5pZCk7Zi5zdHJlYW1TZXRzLnB1c2goZCk7cmV0dXJuIGZjKHRoaXMuYixsKS50aGVuKGZ1bmN0aW9uKCl7aWYoIXRoaXMudylyZXR1cm4gdGhpcy5tYS5zcGxpY2UodGhpcy5tYS5pbmRleE9mKGwuaWQpLDEpLFljKHRoaXMsZiksVWModGhpcykse2lkOmwuaWQsYWN0aXZlOiExLHR5cGU6XCJ0ZXh0XCIsYmFuZHdpZHRoOjAsbGFuZ3VhZ2U6YixraW5kOmMsd2lkdGg6bnVsbCxoZWlnaHQ6bnVsbH19LmJpbmQodGhpcykpfTtcbkkucHJvdG90eXBlLmFkZFRleHRUcmFjaz1JLnByb3RvdHlwZS5hZGRUZXh0VHJhY2s7SS5wcm90b3R5cGUuQ2I9ZnVuY3Rpb24oYSxiKXt0aGlzLkJhLndpZHRoPWE7dGhpcy5CYS5oZWlnaHQ9Yn07SS5wcm90b3R5cGUuc2V0TWF4SGFyZHdhcmVSZXNvbHV0aW9uPUkucHJvdG90eXBlLkNiO1xuZnVuY3Rpb24gU2MoYSl7YS52JiZhLnYuamEoYS5BLFwic291cmNlb3BlblwiKTthLmYmJihhLmYucmVtb3ZlQXR0cmlidXRlKFwic3JjXCIpLGEuZi5sb2FkKCkpO3ZhciBiPVByb21pc2UuYWxsKFthLmE/YS5hLmFici5tYW5hZ2VyLnN0b3AoKTpudWxsLGEuZz9hLmcubygpOm51bGwsYS5HP2EuRy5vKCk6bnVsbCxhLmk/YS5pLm8oKTpudWxsLGEuYj9hLmIubygpOm51bGwsYS5sP2EubC5zdG9wKCk6bnVsbF0pO2EuZz1udWxsO2EuRz1udWxsO2EuaT1udWxsO2EuYj1udWxsO2EubD1udWxsO2EuYz1udWxsO2EubmE9bnVsbDthLm9hPW51bGw7YS5BPW51bGw7YS5zPXt9O2EuQz1bXTthLnBhPTA7YS5KPTA7cmV0dXJuIGJ9az1JLnByb3RvdHlwZTtrLnliPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMubD9TYyh0aGlzKS50aGVuKGZ1bmN0aW9uKCl7dGhpcy53fHwodGhpcy5GYighMSksdGhpcy5vYT1SYyh0aGlzKSl9LmJpbmQodGhpcykpOlByb21pc2UucmVzb2x2ZSgpfTtcbmZ1bmN0aW9uIFdjKCl7cmV0dXJue1wiLmRybS5zZXJ2ZXJzXCI6XCJcIixcIi5kcm0uY2xlYXJLZXlzXCI6XCJcIixcIi5kcm0uYWR2YW5jZWRcIjp7ZGlzdGluY3RpdmVJZGVudGlmaWVyUmVxdWlyZWQ6ITEscGVyc2lzdGVudFN0YXRlUmVxdWlyZWQ6ITEsdmlkZW9Sb2J1c3RuZXNzOlwiXCIsYXVkaW9Sb2J1c3RuZXNzOlwiXCIsc2VydmVyQ2VydGlmaWNhdGU6bnVsbH19fVxuZnVuY3Rpb24gUWMoYSl7cmV0dXJue2RybTp7cmV0cnlQYXJhbWV0ZXJzOkdhKCksc2VydmVyczp7fSxjbGVhcktleXM6e30sYWR2YW5jZWQ6e319LG1hbmlmZXN0OntyZXRyeVBhcmFtZXRlcnM6R2EoKSxkYXNoOntjdXN0b21TY2hlbWU6ZnVuY3Rpb24oYSl7aWYoYSlyZXR1cm4gbnVsbH0sY2xvY2tTeW5jVXJpOlwiXCJ9fSxzdHJlYW1pbmc6e3JldHJ5UGFyYW1ldGVyczpHYSgpLHJlYnVmZmVyaW5nR29hbDoyLGJ1ZmZlcmluZ0dvYWw6MTAsYnVmZmVyQmVoaW5kOjMwLGlnbm9yZVRleHRTdHJlYW1GYWlsdXJlczohMSx1c2VSZWxhdGl2ZUN1ZVRpbWVzdGFtcHM6ITF9LGFicjp7bWFuYWdlcjphLmZiLGVuYWJsZWQ6ITAsZGVmYXVsdEJhbmR3aWR0aEVzdGltYXRlOjVFNX0scHJlZmVycmVkQXVkaW9MYW5ndWFnZTpcIlwiLHByZWZlcnJlZFRleHRMYW5ndWFnZTpcIlwiLHJlc3RyaWN0aW9uczp7bWluV2lkdGg6MCxtYXhXaWR0aDpJbmZpbml0eSxtaW5IZWlnaHQ6MCxtYXhIZWlnaHQ6SW5maW5pdHksXG5taW5QaXhlbHM6MCxtYXhQaXhlbHM6SW5maW5pdHksbWluQXVkaW9CYW5kd2lkdGg6MCxtYXhBdWRpb0JhbmR3aWR0aDpJbmZpbml0eSxtaW5WaWRlb0JhbmR3aWR0aDowLG1heFZpZGVvQmFuZHdpZHRoOkluZmluaXR5fX19ay5MYT1mdW5jdGlvbihhKXt2YXIgYj10aGlzLmI/ZWModGhpcy5iKTp7fTtKYyh0aGlzLmcsYixhKTtiPWEuc3RyZWFtU2V0cy5zb21lKE1jKTtJYyhhLHRoaXMuYS5yZXN0cmljdGlvbnMsdGhpcy5CYSkmJiF0aGlzLmomJlVjKHRoaXMpO2E9IWEuc3RyZWFtU2V0cy5zb21lKE1jKTtiP2EmJnRoaXMuJChuZXcgcSg0LDQwMTIpKTp0aGlzLiQobmV3IHEoNCw0MDExKSl9O2Z1bmN0aW9uIFpjKGEsYixjKXtmb3IodmFyIGQgaW4gYil7dmFyIGU9YltkXSxmPWN8fCExO1widGV4dFwiPT1kJiYoZj0hMCk7YS5xYT9hLnNbZF09e3N0cmVhbTplLE9iOmZ9OmdjKGEuYixkLGUsZil9fVxuZnVuY3Rpb24gYWQoYSl7aWYoYS5jKXt2YXIgYj1EYXRlLm5vdygpLzFFMzthLk5hP2EuSis9Yi1hLlg6YS5wYSs9Yi1hLlg7YS5YPWJ9fWsuTWM9ZnVuY3Rpb24oYSxiLGMpe3RoaXMuYS5hYnIubWFuYWdlci5zZWdtZW50RG93bmxvYWRlZChhLGIsYyl9O2suRmI9ZnVuY3Rpb24oYSl7YWQodGhpcyk7dGhpcy5OYT1hO3RoaXMuZGlzcGF0Y2hFdmVudChuZXcgSChcImJ1ZmZlcmluZ1wiLHtidWZmZXJpbmc6YX0pKX07ay5MYz1mdW5jdGlvbigpe2lmKHRoaXMuYil7dmFyIGE9dGhpcy5iLGI7Zm9yKGIgaW4gYS5iKXt2YXIgYz1hLmJbYl07Yy5iYXx8MDxIYihhLmYsYixUYihhLm0pKXx8Yy5sYXx8KGMuZ2E/Yy5sYT0hMDpudWxsPT1GYihhLmYsYik/bnVsbD09Yy5hYSYmbGMoYSxjLDApOihhYyhjKSxpYyhhLGMpKSl9fX07XG5mdW5jdGlvbiBiZChhLGIsYyl7aWYoIUMoYikuc29tZShNYykpcmV0dXJuIGEuJChuZXcgcSg0LDQwMTIpKSx7fTt2YXIgZD17fTtpZihjKWQ9YjtlbHNle2M9ZWMoYS5iKTtmb3IodmFyIGUgaW4gYyl7dmFyIGY9Y1tlXTtmLmFsbG93ZWRCeUFwcGxpY2F0aW9uJiZmLmFsbG93ZWRCeUtleVN5c3RlbSYmYltlXS5sYW5ndWFnZT09Zi5sYW5ndWFnZXx8KGRbZV09YltlXSl9fWlmKE1hKGQpKXJldHVybnt9O2lhKE9iamVjdC5rZXlzKGQpKTt2YXIgZz1hLmEuYWJyLm1hbmFnZXIuY2hvb3NlU3RyZWFtcyhkKTtyZXR1cm4gT2EoZCxmdW5jdGlvbihhKXtyZXR1cm4hIWdbYV19KT9nOihhLiQobmV3IHEoNCw0MDEyKSkse30pfVxuZnVuY3Rpb24gWWMoYSxiKXt2YXIgYz17YXVkaW86ITEsdGV4dDohMX0sZD1OYyhiLGEuYSxjKSxlPWJkKGEsZCksZjtmb3IoZiBpbiBlKWEuQy5wdXNoKHt0aW1lc3RhbXA6RGF0ZS5ub3coKS8xRTMsaWQ6ZVtmXS5pZCx0eXBlOmYsZnJvbUFkYXB0YXRpb246ITB9KTtaYyhhLGUsITApO1ZjKGEpO2QudGV4dCYmZC5hdWRpbyYmYy50ZXh0JiZkLnRleHQubGFuZ3VhZ2UhPWQuYXVkaW8ubGFuZ3VhZ2UmJihhLm0ubW9kZT1cInNob3dpbmdcIiwkYyhhKSl9ay5JYz1mdW5jdGlvbihhKXt0aGlzLnFhPSEwO3RoaXMuYS5hYnIubWFuYWdlci5kaXNhYmxlKCk7YT1OYyhhLHRoaXMuYSk7YT1iZCh0aGlzLGEsITApO2Zvcih2YXIgYiBpbiB0aGlzLnMpYVtiXT10aGlzLnNbYl0uc3RyZWFtO3RoaXMucz17fTtmb3IoYiBpbiBhKXRoaXMuQy5wdXNoKHt0aW1lc3RhbXA6RGF0ZS5ub3coKS8xRTMsaWQ6YVtiXS5pZCx0eXBlOmIsZnJvbUFkYXB0YXRpb246ITB9KTt0aGlzLmp8fFVjKHRoaXMpO3JldHVybiBhfTtcbmsuS2I9ZnVuY3Rpb24oKXt0aGlzLnFhPSExO3RoaXMuYS5hYnIuZW5hYmxlZCYmdGhpcy5hLmFici5tYW5hZ2VyLmVuYWJsZSgpO2Zvcih2YXIgYSBpbiB0aGlzLnMpe3ZhciBiPXRoaXMuc1thXTtnYyh0aGlzLmIsYSxiLnN0cmVhbSxiLk9iKX10aGlzLnM9e319O2suYmI9ZnVuY3Rpb24oYSxiKXt2YXIgYz1lYyh0aGlzLmIpLGQ7Zm9yKGQgaW4gYSl7dmFyIGU9YVtkXTtjW2RdIT1lP3RoaXMuQy5wdXNoKHt0aW1lc3RhbXA6RGF0ZS5ub3coKS8xRTMsaWQ6ZS5pZCx0eXBlOmQsZnJvbUFkYXB0YXRpb246ITB9KTpkZWxldGUgYVtkXX1pZighTWEoYSkmJnRoaXMuYil7Zm9yKGQgaW4gYSlnYyh0aGlzLmIsZCxhW2RdLGJ8fCExKTtWYyh0aGlzKX19O2Z1bmN0aW9uIFZjKGEpe1Byb21pc2UucmVzb2x2ZSgpLnRoZW4oZnVuY3Rpb24oKXt0aGlzLnd8fHRoaXMuZGlzcGF0Y2hFdmVudChuZXcgSChcImFkYXB0YXRpb25cIikpfS5iaW5kKGEpKX1cbmZ1bmN0aW9uIFVjKGEpe1Byb21pc2UucmVzb2x2ZSgpLnRoZW4oZnVuY3Rpb24oKXt0aGlzLnd8fHRoaXMuZGlzcGF0Y2hFdmVudChuZXcgSChcInRyYWNrc2NoYW5nZWRcIikpfS5iaW5kKGEpKX1mdW5jdGlvbiAkYyhhKXthLmRpc3BhdGNoRXZlbnQobmV3IEgoXCJ0ZXh0dHJhY2t2aXNpYmlsaXR5XCIpKX1rLiQ9ZnVuY3Rpb24oYSl7dGhpcy5kaXNwYXRjaEV2ZW50KG5ldyBIKFwiZXJyb3JcIix7ZGV0YWlsOmF9KSl9O2suSmM9ZnVuY3Rpb24oYSl7dGhpcy5kaXNwYXRjaEV2ZW50KGEpfTtrLmxjPWZ1bmN0aW9uKCl7aWYodGhpcy5mLmVycm9yKXt2YXIgYT10aGlzLmYuZXJyb3IuY29kZTtpZigxIT1hKXt2YXIgYj10aGlzLmYuZXJyb3IubXNFeHRlbmRlZENvZGU7YiYmKDA+YiYmKGIrPU1hdGgucG93KDIsMzIpKSxiPWIudG9TdHJpbmcoMTYpKTt0aGlzLiQobmV3IHEoMywzMDE2LGEsYikpfX19O1xuay5LYz1mdW5jdGlvbihhKXt2YXIgYj1bXCJvdXRwdXQtcmVzdHJpY3RlZFwiLFwiaW50ZXJuYWwtZXJyb3JcIl0sYz1kYyh0aGlzLmIpLGQ9ITE7Yy5zdHJlYW1TZXRzLmZvckVhY2goZnVuY3Rpb24oYyl7Yy5zdHJlYW1zLmZvckVhY2goZnVuY3Rpb24oYyl7dmFyIGU9Yy5hbGxvd2VkQnlLZXlTeXN0ZW07Yy5rZXlJZCYmYy5rZXlJZCBpbiBhJiYoYy5hbGxvd2VkQnlLZXlTeXN0ZW09MD5iLmluZGV4T2YoYVtjLmtleUlkXSkpO2UhPWMuYWxsb3dlZEJ5S2V5U3lzdGVtJiYoZD0hMCl9KX0pO1ljKHRoaXMsYyk7ZCYmVWModGhpcyl9O3ZhciBkZD1cImVuZGVkIHBsYXkgcGxheWluZyBwYXVzZSBwYXVzaW5nIHJhdGVjaGFuZ2Ugc2Vla2VkIHNlZWtpbmcgdGltZXVwZGF0ZSB2b2x1bWVjaGFuZ2VcIi5zcGxpdChcIiBcIiksZWQ9XCJidWZmZXJlZCBjdXJyZW50VGltZSBkdXJhdGlvbiBlbmRlZCBsb29wIG11dGVkIHBhdXNlZCBwbGF5YmFja1JhdGUgc2Vla2luZyB2aWRlb0hlaWdodCB2aWRlb1dpZHRoIHZvbHVtZVwiLnNwbGl0KFwiIFwiKSxmZD1bXCJsb29wXCIsXCJwbGF5YmFja1JhdGVcIl0sZ2Q9W1wicGF1c2VcIixcInBsYXlcIl0saGQ9W1wiYWRhcHRhdGlvblwiLFwiYnVmZmVyaW5nXCIsXCJlcnJvclwiLFwidGV4dHRyYWNrdmlzaWJpbGl0eVwiLFwidHJhY2tzY2hhbmdlZFwiXSxpZD1cImdldENvbmZpZ3VyYXRpb24gZ2V0TWFuaWZlc3RVcmkgZ2V0UGxheWJhY2tSYXRlIGdldFRyYWNrcyBnZXRTdGF0cyBpc0J1ZmZlcmluZyBpc0xpdmUgaXNUZXh0VHJhY2tWaXNpYmxlIHNlZWtSYW5nZVwiLnNwbGl0KFwiIFwiKSxqZD1bW1wiZ2V0Q29uZmlndXJhdGlvblwiLFxuXCJjb25maWd1cmVcIl1dLGtkPVtbXCJpc1RleHRUcmFja1Zpc2libGVcIixcInNldFRleHRUcmFja1Zpc2liaWxpdHlcIl1dLGxkPVwiY29uZmlndXJlIHJlc2V0Q29uZmlndXJhdGlvbiB0cmlja1BsYXkgY2FuY2VsVHJpY2tQbGF5IHNlbGVjdFRyYWNrIHNldFRleHRUcmFja1Zpc2liaWxpdHkgYWRkVGV4dFRyYWNrXCIuc3BsaXQoXCIgXCIpLG1kPVtcImxvYWRcIixcInVubG9hZFwiXTtcbmZ1bmN0aW9uIG5kKGEpe3JldHVybiBKU09OLnN0cmluZ2lmeShhLGZ1bmN0aW9uKGEsYyl7aWYoXCJtYW5hZ2VyXCIhPWEmJlwiZnVuY3Rpb25cIiE9dHlwZW9mIGMpe2lmKGMgaW5zdGFuY2VvZiBFdmVudHx8YyBpbnN0YW5jZW9mIEgpe3ZhciBkPXt9LGU7Zm9yKGUgaW4gYyl7dmFyIGY9Y1tlXTtmJiZcIm9iamVjdFwiPT10eXBlb2YgZnx8ZSBpbiBFdmVudHx8KGRbZV09Zil9cmV0dXJuIGR9aWYoYyBpbnN0YW5jZW9mIFRpbWVSYW5nZXMpZm9yKGQ9e19fdHlwZV9fOlwiVGltZVJhbmdlc1wiLGxlbmd0aDpjLmxlbmd0aCxzdGFydDpbXSxlbmQ6W119LGU9MDtlPGMubGVuZ3RoOysrZSlkLnN0YXJ0LnB1c2goYy5zdGFydChlKSksZC5lbmQucHVzaChjLmVuZChlKSk7ZWxzZSBkPVwibnVtYmVyXCI9PXR5cGVvZiBjP2lzTmFOKGMpP1wiTmFOXCI6aXNGaW5pdGUoYyk/YzowPmM/XCItSW5maW5pdHlcIjpcIkluZmluaXR5XCI6YztyZXR1cm4gZH19KX1cbmZ1bmN0aW9uIG9kKGEpe3JldHVybiBKU09OLnBhcnNlKGEsZnVuY3Rpb24oYSxjKXtyZXR1cm5cIk5hTlwiPT1jP05hTjpcIi1JbmZpbml0eVwiPT1jPy1JbmZpbml0eTpcIkluZmluaXR5XCI9PWM/SW5maW5pdHk6YyYmXCJvYmplY3RcIj09dHlwZW9mIGMmJlwiVGltZVJhbmdlc1wiPT1jLl9fdHlwZV9fP3BkKGMpOmN9KX1mdW5jdGlvbiBwZChhKXtyZXR1cm57bGVuZ3RoOmEubGVuZ3RoLHN0YXJ0OmZ1bmN0aW9uKGIpe3JldHVybiBhLnN0YXJ0W2JdfSxlbmQ6ZnVuY3Rpb24oYil7cmV0dXJuIGEuZW5kW2JdfX19O2Z1bmN0aW9uIHFkKGEsYixjLGQsZSl7dGhpcy5DPWE7dGhpcy5sPWI7dGhpcy53PWM7dGhpcy5BPWQ7dGhpcy5zPWU7dGhpcy5mPXRoaXMuaj10aGlzLmg9ITE7dGhpcy52PVwiXCI7dGhpcy5hPXRoaXMuaT1udWxsO3RoaXMuYj17dmlkZW86e30scGxheWVyOnt9fTt0aGlzLm09MDt0aGlzLmM9e307dGhpcy5nPW51bGx9az1xZC5wcm90b3R5cGU7ay5vPWZ1bmN0aW9uKCl7cmQodGhpcyk7dGhpcy5hJiYodGhpcy5hLnN0b3AoZnVuY3Rpb24oKXt9LGZ1bmN0aW9uKCl7fSksdGhpcy5hPW51bGwpO3RoaXMuQT10aGlzLnc9dGhpcy5sPW51bGw7dGhpcy5mPXRoaXMuaj10aGlzLmg9ITE7dGhpcy5nPXRoaXMuYz10aGlzLmI9dGhpcy5hPXRoaXMuaT1udWxsO3JldHVybiBQcm9taXNlLnJlc29sdmUoKX07ay5OPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZn07ay5ZYT1mdW5jdGlvbigpe3JldHVybiB0aGlzLnZ9O1xuay5pbml0PWZ1bmN0aW9uKCl7aWYod2luZG93LmNocm9tZSYmY2hyb21lLmNhc3QmJmNocm9tZS5jYXN0LmlzQXZhaWxhYmxlKXtkZWxldGUgd2luZG93Ll9fb25HQ2FzdEFwaUF2YWlsYWJsZTt0aGlzLmg9ITA7dGhpcy5sKCk7dmFyIGE9bmV3IGNocm9tZS5jYXN0LlNlc3Npb25SZXF1ZXN0KHRoaXMuQyksYT1uZXcgY2hyb21lLmNhc3QuQXBpQ29uZmlnKGEsdGhpcy5jYy5iaW5kKHRoaXMpLHRoaXMuamMuYmluZCh0aGlzKSxcIm9yaWdpbl9zY29wZWRcIik7Y2hyb21lLmNhc3QuaW5pdGlhbGl6ZShhLGZ1bmN0aW9uKCl7fSxmdW5jdGlvbigpe30pfWVsc2Ugd2luZG93Ll9fb25HQ2FzdEFwaUF2YWlsYWJsZT1mdW5jdGlvbihhKXthJiZ0aGlzLmluaXQoKX0uYmluZCh0aGlzKX07ay4kYT1mdW5jdGlvbihhKXt0aGlzLmk9YTt0aGlzLmYmJnNkKHRoaXMse3R5cGU6XCJhcHBEYXRhXCIsYXBwRGF0YTp0aGlzLml9KX07XG5rLmNhc3Q9ZnVuY3Rpb24oYSl7aWYoIXRoaXMuaClyZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IHEoOCw4RTMpKTtpZighdGhpcy5qKXJldHVybiBQcm9taXNlLnJlamVjdChuZXcgcSg4LDgwMDEpKTtpZih0aGlzLmYpcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBxKDgsODAwMikpO3RoaXMuZz1uZXcgdztjaHJvbWUuY2FzdC5yZXF1ZXN0U2Vzc2lvbih0aGlzLldhLmJpbmQodGhpcyxhKSx0aGlzLmxiLmJpbmQodGhpcykpO3JldHVybiB0aGlzLmd9O1xuay5nZXQ9ZnVuY3Rpb24oYSxiKXtpZihcInZpZGVvXCI9PWEpe2lmKDA8PWdkLmluZGV4T2YoYikpcmV0dXJuIHRoaXMud2IuYmluZCh0aGlzLGEsYil9ZWxzZSBpZihcInBsYXllclwiPT1hKXtpZigwPD1sZC5pbmRleE9mKGIpKXJldHVybiB0aGlzLndiLmJpbmQodGhpcyxhLGIpO2lmKDA8PW1kLmluZGV4T2YoYikpcmV0dXJuIHRoaXMueWMuYmluZCh0aGlzLGEsYik7aWYoMDw9aWQuaW5kZXhPZihiKSlyZXR1cm4gdGhpcy50Yi5iaW5kKHRoaXMsYSxiKX1yZXR1cm4gdGhpcy50YihhLGIpfTtrLnNldD1mdW5jdGlvbihhLGIsYyl7dGhpcy5iW2FdW2JdPWM7c2QodGhpcyx7dHlwZTpcInNldFwiLHRhcmdldE5hbWU6YSxwcm9wZXJ0eTpiLHZhbHVlOmN9KX07XG5rLldhPWZ1bmN0aW9uKGEsYil7dGhpcy5hPWI7dGhpcy5hLmFkZFVwZGF0ZUxpc3RlbmVyKHRoaXMubWIuYmluZCh0aGlzKSk7dGhpcy5hLmFkZE1lc3NhZ2VMaXN0ZW5lcihcInVybjp4LWNhc3Q6Y29tLmdvb2dsZS5zaGFrYS52MlwiLHRoaXMuZGMuYmluZCh0aGlzKSk7dGhpcy5tYigpO3NkKHRoaXMse3R5cGU6XCJpbml0XCIsaW5pdFN0YXRlOmEsYXBwRGF0YTp0aGlzLml9KTt0aGlzLmcucmVzb2x2ZSgpfTtrLmxiPWZ1bmN0aW9uKGEpe3ZhciBiPTgwMDM7c3dpdGNoKGEuY29kZSl7Y2FzZSBcImNhbmNlbFwiOmI9ODAwNDticmVhaztjYXNlIFwidGltZW91dFwiOmI9ODAwNTticmVhaztjYXNlIFwicmVjZWl2ZXJfdW5hdmFpbGFibGVcIjpiPTgwMDZ9dGhpcy5nLnJlamVjdChuZXcgcSg4LGIsYSkpfTtrLnRiPWZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuYlthXVtiXX07XG5rLndiPWZ1bmN0aW9uKGEsYil7c2QodGhpcyx7dHlwZTpcImNhbGxcIix0YXJnZXROYW1lOmEsbWV0aG9kTmFtZTpiLGFyZ3M6QXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLDIpfSl9O2sueWM9ZnVuY3Rpb24oYSxiKXt2YXIgYz1BcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsMiksZD1uZXcgdyxlPXRoaXMubS50b1N0cmluZygpO3RoaXMubSsrO3RoaXMuY1tlXT1kO3NkKHRoaXMse3R5cGU6XCJhc3luY0NhbGxcIix0YXJnZXROYW1lOmEsbWV0aG9kTmFtZTpiLGFyZ3M6YyxpZDplfSk7cmV0dXJuIGR9O2suY2M9ZnVuY3Rpb24oYSl7dmFyIGI9dGhpcy5zKCk7dGhpcy5nPW5ldyB3O3RoaXMuV2EoYixhKX07ay5qYz1mdW5jdGlvbihhKXt0aGlzLmo9XCJhdmFpbGFibGVcIj09YTt0aGlzLmwoKX07XG5rLm1iPWZ1bmN0aW9uKCl7dmFyIGE9dGhpcy5hP1wiY29ubmVjdGVkXCI9PXRoaXMuYS5zdGF0dXM6ITE7aWYodGhpcy5mJiYhYSl7dGhpcy5BKCk7Zm9yKHZhciBiIGluIHRoaXMuYil0aGlzLmJbYl09e307cmQodGhpcyl9dGhpcy52PSh0aGlzLmY9YSk/dGhpcy5hLnJlY2VpdmVyLmZyaWVuZGx5TmFtZTpcIlwiO3RoaXMubCgpfTtmdW5jdGlvbiByZChhKXtmb3IodmFyIGIgaW4gYS5jKXt2YXIgYz1hLmNbYl07ZGVsZXRlIGEuY1tiXTtjLnJlamVjdChuZXcgcSg3LDdFMykpfX1cbmsuZGM9ZnVuY3Rpb24oYSxiKXt2YXIgYz1vZChiKTtzd2l0Y2goYy50eXBlKXtjYXNlIFwiZXZlbnRcIjp2YXIgZD1jLnRhcmdldE5hbWUsZT1jLmV2ZW50O3RoaXMudyhkLG5ldyBIKGUudHlwZSxlKSk7YnJlYWs7Y2FzZSBcInVwZGF0ZVwiOmU9Yy51cGRhdGU7Zm9yKGQgaW4gZSl7dmFyIGM9dGhpcy5iW2RdfHx7fSxmO2ZvcihmIGluIGVbZF0pY1tmXT1lW2RdW2ZdfWJyZWFrO2Nhc2UgXCJhc3luY0NvbXBsZXRlXCI6aWYoZD1jLmlkLGY9Yy5lcnJvcixjPXRoaXMuY1tkXSxkZWxldGUgdGhpcy5jW2RdLGMpaWYoZil7ZD1uZXcgcShmLmNhdGVnb3J5LGYuY29kZSk7Zm9yKGUgaW4gZilkW2VdPWZbZV07Yy5yZWplY3QoZCl9ZWxzZSBjLnJlc29sdmUoKX19O2Z1bmN0aW9uIHNkKGEsYil7dmFyIGM9bmQoYik7YS5hLnNlbmRNZXNzYWdlKFwidXJuOngtY2FzdDpjb20uZ29vZ2xlLnNoYWthLnYyXCIsYyxmdW5jdGlvbigpe30saGEpfTtmdW5jdGlvbiBLKGEsYixjKXtwLmNhbGwodGhpcyk7dGhpcy5jPWE7dGhpcy5iPWI7dGhpcy5oPXRoaXMuZj10aGlzLmc9dGhpcy5pPXRoaXMuaj1udWxsO3RoaXMuYT1uZXcgcWQoYyx0aGlzLk5jLmJpbmQodGhpcyksdGhpcy5PYy5iaW5kKHRoaXMpLHRoaXMuUGMuYmluZCh0aGlzKSx0aGlzLmpiLmJpbmQodGhpcykpO3RkKHRoaXMpfWJhKEspO20oXCJzaGFrYS5jYXN0LkNhc3RQcm94eVwiLEspO0sucHJvdG90eXBlLm89ZnVuY3Rpb24oKXt2YXIgYT1bdGhpcy5oP3RoaXMuaC5vKCk6bnVsbCx0aGlzLmI/dGhpcy5iLm8oKTpudWxsLHRoaXMuYT90aGlzLmEubygpOm51bGxdO3RoaXMuYT10aGlzLmg9dGhpcy5pPXRoaXMuaj10aGlzLmI9dGhpcy5jPW51bGw7cmV0dXJuIFByb21pc2UuYWxsKGEpfTtLLnByb3RvdHlwZS5kZXN0cm95PUsucHJvdG90eXBlLm87Sy5wcm90b3R5cGUuVmI9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5qfTtLLnByb3RvdHlwZS5nZXRWaWRlbz1LLnByb3RvdHlwZS5WYjtcbksucHJvdG90eXBlLlRiPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuaX07Sy5wcm90b3R5cGUuZ2V0UGxheWVyPUsucHJvdG90eXBlLlRiO0sucHJvdG90eXBlLkpiPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYT90aGlzLmEuaCYmdGhpcy5hLmo6ITF9O0sucHJvdG90eXBlLmNhbkNhc3Q9Sy5wcm90b3R5cGUuSmI7Sy5wcm90b3R5cGUuTj1mdW5jdGlvbigpe3JldHVybiB0aGlzLmE/dGhpcy5hLk4oKTohMX07Sy5wcm90b3R5cGUuaXNDYXN0aW5nPUsucHJvdG90eXBlLk47Sy5wcm90b3R5cGUuWWE9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5hP3RoaXMuYS5ZYSgpOlwiXCJ9O0sucHJvdG90eXBlLnJlY2VpdmVyTmFtZT1LLnByb3RvdHlwZS5ZYTtLLnByb3RvdHlwZS5jYXN0PWZ1bmN0aW9uKCl7dmFyIGE9dGhpcy5qYigpO3JldHVybiB0aGlzLmEuY2FzdChhKS50aGVuKGZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYi5lYigpfS5iaW5kKHRoaXMpKX07Sy5wcm90b3R5cGUuY2FzdD1LLnByb3RvdHlwZS5jYXN0O1xuSy5wcm90b3R5cGUuJGE9ZnVuY3Rpb24oYSl7dGhpcy5hLiRhKGEpfTtLLnByb3RvdHlwZS5zZXRBcHBEYXRhPUsucHJvdG90eXBlLiRhO0sucHJvdG90eXBlLlZjPWZ1bmN0aW9uKCl7dmFyIGE9dGhpcy5hO2lmKGEuZil7dmFyIGI9YS5zKCk7Y2hyb21lLmNhc3QucmVxdWVzdFNlc3Npb24oYS5XYS5iaW5kKGEsYiksYS5sYi5iaW5kKGEpKX19O0sucHJvdG90eXBlLnN1Z2dlc3REaXNjb25uZWN0PUsucHJvdG90eXBlLlZjO1xuZnVuY3Rpb24gdGQoYSl7YS5hLmluaXQoKTthLmg9bmV3IHo7ZGQuZm9yRWFjaChmdW5jdGlvbihhKXtCKHRoaXMuaCx0aGlzLmMsYSx0aGlzLmFkLmJpbmQodGhpcykpfS5iaW5kKGEpKTtoZC5mb3JFYWNoKGZ1bmN0aW9uKGEpe0IodGhpcy5oLHRoaXMuYixhLHRoaXMudWMuYmluZCh0aGlzKSl9LmJpbmQoYSkpO2Euaj17fTtmb3IodmFyIGIgaW4gYS5jKU9iamVjdC5kZWZpbmVQcm9wZXJ0eShhLmosYix7Y29uZmlndXJhYmxlOiExLGVudW1lcmFibGU6ITAsZ2V0OmEuJGMuYmluZChhLGIpLHNldDphLmJkLmJpbmQoYSxiKX0pO2EuaT17fTtmb3IoYiBpbiBhLmIpT2JqZWN0LmRlZmluZVByb3BlcnR5KGEuaSxiLHtjb25maWd1cmFibGU6ITEsZW51bWVyYWJsZTohMCxnZXQ6YS50Yy5iaW5kKGEsYil9KTthLmc9bmV3IHA7YS5nLlM9YS5qO2EuZj1uZXcgcDthLmYuUz1hLml9az1LLnByb3RvdHlwZTtcbmsuamI9ZnVuY3Rpb24oKXt2YXIgYT17dmlkZW86e30scGxheWVyOnt9LHBsYXllckFmdGVyTG9hZDp7fSxtYW5pZmVzdDp0aGlzLmIubmEsc3RhcnRUaW1lOm51bGx9O3RoaXMuYy5wYXVzZSgpO2ZkLmZvckVhY2goZnVuY3Rpb24oYil7YS52aWRlb1tiXT10aGlzLmNbYl19LmJpbmQodGhpcykpO3RoaXMuYy5lbmRlZHx8KGEuc3RhcnRUaW1lPXRoaXMuYy5jdXJyZW50VGltZSk7amQuZm9yRWFjaChmdW5jdGlvbihiKXt2YXIgYz1iWzFdO2I9dGhpcy5iW2JbMF1dKCk7YS5wbGF5ZXJbY109Yn0uYmluZCh0aGlzKSk7a2QuZm9yRWFjaChmdW5jdGlvbihiKXt2YXIgYz1iWzFdO2I9dGhpcy5iW2JbMF1dKCk7YS5wbGF5ZXJBZnRlckxvYWRbY109Yn0uYmluZCh0aGlzKSk7cmV0dXJuIGF9O2suTmM9ZnVuY3Rpb24oKXt0aGlzLmRpc3BhdGNoRXZlbnQobmV3IEgoXCJjYXN0c3RhdHVzY2hhbmdlZFwiKSl9O1xuay5QYz1mdW5jdGlvbigpe2pkLmZvckVhY2goZnVuY3Rpb24oYSl7dmFyIGI9YVsxXTthPXRoaXMuYS5nZXQoXCJwbGF5ZXJcIixhWzBdKSgpO3RoaXMuYltiXShhKX0uYmluZCh0aGlzKSk7dmFyIGE9dGhpcy5hLmdldChcInBsYXllclwiLFwiZ2V0TWFuaWZlc3RVcmlcIikoKSxiPXRoaXMuYS5nZXQoXCJ2aWRlb1wiLFwiZW5kZWRcIiksYz1Qcm9taXNlLnJlc29sdmUoKSxkPXRoaXMuYy5hdXRvcGxheSxlPW51bGw7Ynx8KGU9dGhpcy5hLmdldChcInZpZGVvXCIsXCJjdXJyZW50VGltZVwiKSk7YSYmKHRoaXMuYy5hdXRvcGxheT0hMSxjPXRoaXMuYi5sb2FkKGEsZSksY1tcImNhdGNoXCJdKGZ1bmN0aW9uKGEpe3RoaXMuYi5kaXNwYXRjaEV2ZW50KG5ldyBIKFwiZXJyb3JcIix7ZGV0YWlsOmF9KSl9LmJpbmQodGhpcykpKTt2YXIgZj17fTtmZC5mb3JFYWNoKGZ1bmN0aW9uKGEpe2ZbYV09dGhpcy5hLmdldChcInZpZGVvXCIsYSl9LmJpbmQodGhpcykpO2MudGhlbihmdW5jdGlvbigpe2ZkLmZvckVhY2goZnVuY3Rpb24oYSl7dGhpcy5jW2FdPVxuZlthXX0uYmluZCh0aGlzKSk7a2QuZm9yRWFjaChmdW5jdGlvbihhKXt2YXIgYj1hWzFdO2E9dGhpcy5hLmdldChcInBsYXllclwiLGFbMF0pKCk7dGhpcy5iW2JdKGEpfS5iaW5kKHRoaXMpKTt0aGlzLmMuYXV0b3BsYXk9ZDthJiZ0aGlzLmMucGxheSgpfS5iaW5kKHRoaXMpKX07XG5rLiRjPWZ1bmN0aW9uKGEpe2lmKFwiYWRkRXZlbnRMaXN0ZW5lclwiPT1hKXJldHVybiB0aGlzLmcuYWRkRXZlbnRMaXN0ZW5lci5iaW5kKHRoaXMuZyk7aWYoXCJyZW1vdmVFdmVudExpc3RlbmVyXCI9PWEpcmV0dXJuIHRoaXMuZy5yZW1vdmVFdmVudExpc3RlbmVyLmJpbmQodGhpcy5nKTtpZih0aGlzLmEuTigpJiYhT2JqZWN0LmtleXModGhpcy5hLmIudmlkZW8pLmxlbmd0aCl7dmFyIGI9dGhpcy5jW2FdO2lmKFwiZnVuY3Rpb25cIiE9dHlwZW9mIGIpcmV0dXJuIGJ9cmV0dXJuIHRoaXMuYS5OKCk/dGhpcy5hLmdldChcInZpZGVvXCIsYSk6KGI9dGhpcy5jW2FdLFwiZnVuY3Rpb25cIj09dHlwZW9mIGImJihiPWIuYmluZCh0aGlzLmMpKSxiKX07ay5iZD1mdW5jdGlvbihhLGIpe3RoaXMuYS5OKCk/dGhpcy5hLnNldChcInZpZGVvXCIsYSxiKTp0aGlzLmNbYV09Yn07ay5hZD1mdW5jdGlvbihhKXt0aGlzLmEuTigpfHx0aGlzLmcuZGlzcGF0Y2hFdmVudChuZXcgSChhLnR5cGUsYSkpfTtcbmsudGM9ZnVuY3Rpb24oYSl7cmV0dXJuXCJhZGRFdmVudExpc3RlbmVyXCI9PWE/dGhpcy5mLmFkZEV2ZW50TGlzdGVuZXIuYmluZCh0aGlzLmYpOlwicmVtb3ZlRXZlbnRMaXN0ZW5lclwiPT1hP3RoaXMuZi5yZW1vdmVFdmVudExpc3RlbmVyLmJpbmQodGhpcy5mKTpcImdldE5ldHdvcmtpbmdFbmdpbmVcIj09YT90aGlzLmIua2IuYmluZCh0aGlzLmIpOnRoaXMuYS5OKCkmJiFPYmplY3Qua2V5cyh0aGlzLmEuYi52aWRlbykubGVuZ3RoJiYwPD1pZC5pbmRleE9mKGEpfHwhdGhpcy5hLk4oKT8oYT10aGlzLmJbYV0sYS5iaW5kKHRoaXMuYikpOnRoaXMuYS5nZXQoXCJwbGF5ZXJcIixhKX07ay51Yz1mdW5jdGlvbihhKXt0aGlzLmEuTigpfHx0aGlzLmYuZGlzcGF0Y2hFdmVudChhKX07ay5PYz1mdW5jdGlvbihhLGIpe3RoaXMuYS5OKCkmJihcInZpZGVvXCI9PWE/dGhpcy5nLmRpc3BhdGNoRXZlbnQoYik6XCJwbGF5ZXJcIj09YSYmdGhpcy5mLmRpc3BhdGNoRXZlbnQoYikpfTtmdW5jdGlvbiBMKGEsYixjKXtwLmNhbGwodGhpcyk7dGhpcy5iPWE7dGhpcy5hPWI7dGhpcy5pPXt2aWRlbzphLHBsYXllcjpifTt0aGlzLmo9Y3x8ZnVuY3Rpb24oKXt9O3RoaXMuaD0hMTt0aGlzLmM9ITA7dGhpcy5mPXRoaXMuZz1udWxsO3VkKHRoaXMpfWJhKEwpO20oXCJzaGFrYS5jYXN0LkNhc3RSZWNlaXZlclwiLEwpO0wucHJvdG90eXBlLlhiPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuaH07TC5wcm90b3R5cGUuaXNDb25uZWN0ZWQ9TC5wcm90b3R5cGUuWGI7TC5wcm90b3R5cGUuWWI9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5jfTtMLnByb3RvdHlwZS5pc0lkbGU9TC5wcm90b3R5cGUuWWI7XG5MLnByb3RvdHlwZS5vPWZ1bmN0aW9uKCl7dmFyIGE9dGhpcy5hP3RoaXMuYS5vKCk6UHJvbWlzZS5yZXNvbHZlKCk7bnVsbCE9dGhpcy5mJiZ3aW5kb3cuY2xlYXJUaW1lb3V0KHRoaXMuZik7dGhpcy5qPXRoaXMuaT10aGlzLmE9dGhpcy5iPW51bGw7dGhpcy5oPSExO3RoaXMuYz0hMDt0aGlzLmY9dGhpcy5nPW51bGw7cmV0dXJuIGEudGhlbihmdW5jdGlvbigpe2Nhc3QucmVjZWl2ZXIuQ2FzdFJlY2VpdmVyTWFuYWdlci5nZXRJbnN0YW5jZSgpLnN0b3AoKX0pfTtMLnByb3RvdHlwZS5kZXN0cm95PUwucHJvdG90eXBlLm87XG5mdW5jdGlvbiB1ZChhKXt2YXIgYj1jYXN0LnJlY2VpdmVyLkNhc3RSZWNlaXZlck1hbmFnZXIuZ2V0SW5zdGFuY2UoKTtiLm9uU2VuZGVyQ29ubmVjdGVkPWEucmIuYmluZChhKTtiLm9uU2VuZGVyRGlzY29ubmVjdGVkPWEucmIuYmluZChhKTtiLm9uU3lzdGVtVm9sdW1lQ2hhbmdlZD1hLlFiLmJpbmQoYSk7YS5nPWIuZ2V0Q2FzdE1lc3NhZ2VCdXMoXCJ1cm46eC1jYXN0OmNvbS5nb29nbGUuc2hha2EudjJcIik7YS5nLm9uTWVzc2FnZT1hLmVjLmJpbmQoYSk7Yi5zdGFydCgpO2RkLmZvckVhY2goZnVuY3Rpb24oYSl7dGhpcy5iLmFkZEV2ZW50TGlzdGVuZXIoYSx0aGlzLnViLmJpbmQodGhpcyxcInZpZGVvXCIpKX0uYmluZChhKSk7aGQuZm9yRWFjaChmdW5jdGlvbihhKXt0aGlzLmEuYWRkRXZlbnRMaXN0ZW5lcihhLHRoaXMudWIuYmluZCh0aGlzLFwicGxheWVyXCIpKX0uYmluZChhKSk7YS5hLkNiKDE5MjAsMTA4MCk7YS5hLmFkZEV2ZW50TGlzdGVuZXIoXCJsb2FkaW5nXCIsZnVuY3Rpb24oKXt0aGlzLmM9XG4hMTt2ZCh0aGlzKX0uYmluZChhKSk7YS5iLmFkZEV2ZW50TGlzdGVuZXIoXCJwbGF5aW5nXCIsZnVuY3Rpb24oKXt0aGlzLmM9ITE7dmQodGhpcyl9LmJpbmQoYSkpO2EuYS5hZGRFdmVudExpc3RlbmVyKFwidW5sb2FkaW5nXCIsZnVuY3Rpb24oKXt0aGlzLmM9ITA7dmQodGhpcyl9LmJpbmQoYSkpO2EuYi5hZGRFdmVudExpc3RlbmVyKFwiZW5kZWRcIixmdW5jdGlvbigpe3dpbmRvdy5zZXRUaW1lb3V0KGZ1bmN0aW9uKCl7dGhpcy5iJiZ0aGlzLmIuZW5kZWQmJih0aGlzLmM9ITAsdmQodGhpcykpfS5iaW5kKHRoaXMpLDVFMyl9LmJpbmQoYSkpfWs9TC5wcm90b3R5cGU7ay5yYj1mdW5jdGlvbigpe3RoaXMuaD0hIWNhc3QucmVjZWl2ZXIuQ2FzdFJlY2VpdmVyTWFuYWdlci5nZXRJbnN0YW5jZSgpLmdldFNlbmRlcnMoKS5sZW5ndGg7dmQodGhpcyl9O1xuZnVuY3Rpb24gdmQoYSl7UHJvbWlzZS5yZXNvbHZlKCkudGhlbihmdW5jdGlvbigpe3RoaXMuZGlzcGF0Y2hFdmVudChuZXcgSChcImNhc3RzdGF0dXNjaGFuZ2VkXCIpKX0uYmluZChhKSl9XG5mdW5jdGlvbiB3ZChhLGIsYyl7Zm9yKHZhciBkIGluIGIucGxheWVyKWEuYVtkXShiLnBsYXllcltkXSk7YS5qKGMpO2M9UHJvbWlzZS5yZXNvbHZlKCk7dmFyIGU9YS5iLmF1dG9wbGF5O2IubWFuaWZlc3QmJihhLmIuYXV0b3BsYXk9ITEsYz1hLmEubG9hZChiLm1hbmlmZXN0LGIuc3RhcnRUaW1lKSxjW1wiY2F0Y2hcIl0oZnVuY3Rpb24oYSl7dGhpcy5hLmRpc3BhdGNoRXZlbnQobmV3IEgoXCJlcnJvclwiLHtkZXRhaWw6YX0pKX0uYmluZChhKSkpO2MudGhlbihmdW5jdGlvbigpe2Zvcih2YXIgYSBpbiBiLnZpZGVvKXt2YXIgYz1iLnZpZGVvW2FdO3RoaXMuYlthXT1jfWZvcihhIGluIGIucGxheWVyQWZ0ZXJMb2FkKWM9Yi5wbGF5ZXJBZnRlckxvYWRbYV0sdGhpcy5hW2FdKGMpO3RoaXMuYi5hdXRvcGxheT1lO2IubWFuaWZlc3QmJnRoaXMuYi5wbGF5KCl9LmJpbmQoYSkpfVxuay51Yj1mdW5jdGlvbihhLGIpe3RoaXMuWGEoKTt4ZCh0aGlzLHt0eXBlOlwiZXZlbnRcIix0YXJnZXROYW1lOmEsZXZlbnQ6Yn0pfTtrLlhhPWZ1bmN0aW9uKCl7bnVsbCE9dGhpcy5mJiZ3aW5kb3cuY2xlYXJUaW1lb3V0KHRoaXMuZik7dGhpcy5mPXdpbmRvdy5zZXRUaW1lb3V0KHRoaXMuWGEuYmluZCh0aGlzKSw1MDApO3ZhciBhPXt2aWRlbzp7fSxwbGF5ZXI6e319O2VkLmZvckVhY2goZnVuY3Rpb24oYil7YS52aWRlb1tiXT10aGlzLmJbYl19LmJpbmQodGhpcykpO2lkLmZvckVhY2goZnVuY3Rpb24oYil7YS5wbGF5ZXJbYl09dGhpcy5hW2JdKCl9LmJpbmQodGhpcykpO3ZhciBiPWNhc3QucmVjZWl2ZXIuQ2FzdFJlY2VpdmVyTWFuYWdlci5nZXRJbnN0YW5jZSgpLmdldFN5c3RlbVZvbHVtZSgpO2ImJihhLnZpZGVvLnZvbHVtZT1iLmxldmVsLGEudmlkZW8ubXV0ZWQ9Yi5tdXRlZCk7eGQodGhpcyx7dHlwZTpcInVwZGF0ZVwiLHVwZGF0ZTphfSl9O1xuay5RYj1mdW5jdGlvbigpe3ZhciBhPWNhc3QucmVjZWl2ZXIuQ2FzdFJlY2VpdmVyTWFuYWdlci5nZXRJbnN0YW5jZSgpLmdldFN5c3RlbVZvbHVtZSgpO2EmJnhkKHRoaXMse3R5cGU6XCJ1cGRhdGVcIix1cGRhdGU6e3ZpZGVvOnt2b2x1bWU6YS5sZXZlbCxtdXRlZDphLm11dGVkfX19KTt4ZCh0aGlzLHt0eXBlOlwiZXZlbnRcIix0YXJnZXROYW1lOlwidmlkZW9cIixldmVudDp7dHlwZTpcInZvbHVtZWNoYW5nZVwifX0pfTtcbmsuZWM9ZnVuY3Rpb24oYSl7dmFyIGI9b2QoYS5kYXRhKTtzd2l0Y2goYi50eXBlKXtjYXNlIFwiaW5pdFwiOndkKHRoaXMsYi5pbml0U3RhdGUsYi5hcHBEYXRhKTt0aGlzLlhhKCk7YnJlYWs7Y2FzZSBcImFwcERhdGFcIjp0aGlzLmooYi5hcHBEYXRhKTticmVhaztjYXNlIFwic2V0XCI6dmFyIGM9Yi50YXJnZXROYW1lLGQ9Yi5wcm9wZXJ0eSxlPWIudmFsdWU7aWYoXCJ2aWRlb1wiPT1jKWlmKGI9Y2FzdC5yZWNlaXZlci5DYXN0UmVjZWl2ZXJNYW5hZ2VyLmdldEluc3RhbmNlKCksXCJ2b2x1bWVcIj09ZCl7Yi5zZXRTeXN0ZW1Wb2x1bWVMZXZlbChlKTticmVha31lbHNlIGlmKFwibXV0ZWRcIj09ZCl7Yi5zZXRTeXN0ZW1Wb2x1bWVNdXRlZChlKTticmVha310aGlzLmlbY11bZF09ZTticmVhaztjYXNlIFwiY2FsbFwiOmM9Yi50YXJnZXROYW1lO2Q9Yi5tZXRob2ROYW1lO2U9Yi5hcmdzO2M9dGhpcy5pW2NdO2NbZF0uYXBwbHkoYyxlKTticmVhaztjYXNlIFwiYXN5bmNDYWxsXCI6Yz1iLnRhcmdldE5hbWUsXG5kPWIubWV0aG9kTmFtZSxlPWIuYXJncyxiPWIuaWQsYT1hLnNlbmRlcklkLGM9dGhpcy5pW2NdLGNbZF0uYXBwbHkoYyxlKS50aGVuKHRoaXMuQWIuYmluZCh0aGlzLGEsYixudWxsKSx0aGlzLkFiLmJpbmQodGhpcyxhLGIpKX19O2suQWI9ZnVuY3Rpb24oYSxiLGMpe3hkKHRoaXMse3R5cGU6XCJhc3luY0NvbXBsZXRlXCIsaWQ6YixlcnJvcjpjfSxhKX07ZnVuY3Rpb24geGQoYSxiLGMpe2EuaCYmKGI9bmQoYiksYz9hLmcuZ2V0Q2FzdENoYW5uZWwoYykuc2VuZChiKTphLmcuYnJvYWRjYXN0KGIpKX07ZnVuY3Rpb24geWQoYSxiKXt2YXIgYz1NKGEsYik7cmV0dXJuIDEhPWMubGVuZ3RoP251bGw6Y1swXX1mdW5jdGlvbiBNKGEsYil7cmV0dXJuIEFycmF5LnByb3RvdHlwZS5maWx0ZXIuY2FsbChhLmNoaWxkTm9kZXMsZnVuY3Rpb24oYSl7cmV0dXJuIGEudGFnTmFtZT09Yn0pfWZ1bmN0aW9uIHpkKGEpe3JldHVybihhPWEuZmlyc3RDaGlsZCkmJmEubm9kZVR5cGU9PU5vZGUuVEVYVF9OT0RFP2Eubm9kZVZhbHVlLnRyaW0oKTpudWxsfWZ1bmN0aW9uIE4oYSxiLGMsZCl7dmFyIGU9bnVsbDthPWEuZ2V0QXR0cmlidXRlKGIpO251bGwhPWEmJihlPWMoYSkpO3JldHVybiBudWxsPT1lP3ZvaWQgMCE9PWQ/ZDpudWxsOmV9ZnVuY3Rpb24gQWQoYSl7aWYoIWEpcmV0dXJuIG51bGw7YT1EYXRlLnBhcnNlKGEpO3JldHVybiBpc05hTihhKT9udWxsOk1hdGguZmxvb3IoYS8xRTMpfVxuZnVuY3Rpb24gTyhhKXtpZighYSlyZXR1cm4gbnVsbDthPS9eUCg/OihbMC05XSopWSk/KD86KFswLTldKilNKT8oPzooWzAtOV0qKUQpPyg/OlQoPzooWzAtOV0qKUgpPyg/OihbMC05XSopTSk/KD86KFswLTkuXSopUyk/KT8kLy5leGVjKGEpO2lmKCFhKXJldHVybiBudWxsO2E9MzE1MzZFMypOdW1iZXIoYVsxXXx8bnVsbCkrMjU5MkUzKk51bWJlcihhWzJdfHxudWxsKSs4NjQwMCpOdW1iZXIoYVszXXx8bnVsbCkrMzYwMCpOdW1iZXIoYVs0XXx8bnVsbCkrNjAqTnVtYmVyKGFbNV18fG51bGwpK051bWJlcihhWzZdfHxudWxsKTtyZXR1cm4gaXNGaW5pdGUoYSk/YTpudWxsfWZ1bmN0aW9uIEJkKGEpe3ZhciBiPS8oWzAtOV0rKS0oWzAtOV0rKS8uZXhlYyhhKTtpZighYilyZXR1cm4gbnVsbDthPU51bWJlcihiWzFdKTtpZighaXNGaW5pdGUoYSkpcmV0dXJuIG51bGw7Yj1OdW1iZXIoYlsyXSk7cmV0dXJuIGlzRmluaXRlKGIpP3tzdGFydDphLGVuZDpifTpudWxsfVxuZnVuY3Rpb24gQ2QoYSl7YT1OdW1iZXIoYSk7cmV0dXJuIGElMT9udWxsOmF9ZnVuY3Rpb24gRGQoYSl7YT1OdW1iZXIoYSk7cmV0dXJuIShhJTEpJiYwPGE/YTpudWxsfWZ1bmN0aW9uIEVkKGEpe2E9TnVtYmVyKGEpO3JldHVybiEoYSUxKSYmMDw9YT9hOm51bGx9ZnVuY3Rpb24gRmQoYSl7dmFyIGI7YT0oYj1hLm1hdGNoKC9eKFxcZCspXFwvKFxcZCspJC8pKT9OdW1iZXIoYlsxXS9iWzJdKTpOdW1iZXIoYSk7cmV0dXJuIGlzTmFOKGEpP251bGw6YX07dmFyIEdkPXtcInVybjp1dWlkOjEwNzdlZmVjLWMwYjItNGQwMi1hY2UzLTNjMWU1MmUyZmI0YlwiOlwib3JnLnczLmNsZWFya2V5XCIsXCJ1cm46dXVpZDplZGVmOGJhOS03OWQ2LTRhY2UtYTNjOC0yN2RjZDUxZDIxZWRcIjpcImNvbS53aWRldmluZS5hbHBoYVwiLFwidXJuOnV1aWQ6OWEwNGYwNzktOTg0MC00Mjg2LWFiOTItZTY1YmUwODg1Zjk1XCI6XCJjb20ubWljcm9zb2Z0LnBsYXlyZWFkeVwiLFwidXJuOnV1aWQ6ZjIzOWU3NjktZWZhMy00ODUwLTljMTYtYTkwM2M2OTMyZWZiXCI6XCJjb20uYWRvYmUucHJpbWV0aW1lXCJ9O1xuZnVuY3Rpb24gSGQoYSxiKXt2YXIgYz1JZChhKSxkPW51bGwsZT1jLmZpbHRlcihmdW5jdGlvbihhKXtyZXR1cm5cInVybjptcGVnOmRhc2g6bXA0cHJvdGVjdGlvbjoyMDExXCI9PWEuemI/KGQ9YS5pbml0fHxkLCExKTohMH0pLGY9Yy5tYXAoZnVuY3Rpb24oYSl7cmV0dXJuIGEua2V5SWR9KS5maWx0ZXIoRGEpLGc9bnVsbDtpZigwPGYubGVuZ3RoJiYoZz1mWzBdLGYuc29tZShFYShnKSkpKXRocm93IG5ldyBxKDQsNDAxMCk7Zj1bXTswPGUubGVuZ3RoPyhmPUtkKGQsYixlKSxmLmxlbmd0aHx8KGY9W0xkKFwiXCIsZCldKSk6MDxjLmxlbmd0aCYmKGY9QyhHZCkubWFwKGZ1bmN0aW9uKGEpe3JldHVybiBMZChhLGQpfSkpO3JldHVybntoYjpnLGVkOmQsZHJtSW5mb3M6ZixpYjohMH19XG5mdW5jdGlvbiBNZChhLGIsYyl7dmFyIGQ9SGQoYSxiKTtpZihjLmliKXthPTE9PWMuZHJtSW5mb3MubGVuZ3RoJiYhYy5kcm1JbmZvc1swXS5rZXlTeXN0ZW07Yj0hZC5kcm1JbmZvcy5sZW5ndGg7aWYoIWMuZHJtSW5mb3MubGVuZ3RofHxhJiYhYiljLmRybUluZm9zPWQuZHJtSW5mb3M7Yy5pYj0hMX1lbHNlIGlmKDA8ZC5kcm1JbmZvcy5sZW5ndGgmJihjLmRybUluZm9zPWMuZHJtSW5mb3MuZmlsdGVyKGZ1bmN0aW9uKGEpe3JldHVybiBkLmRybUluZm9zLnNvbWUoZnVuY3Rpb24oYil7cmV0dXJuIGIua2V5U3lzdGVtPT1hLmtleVN5c3RlbX0pfSksIWMuZHJtSW5mb3MubGVuZ3RoKSl0aHJvdyBuZXcgcSg0LDQwMDgpO3JldHVybiBkLmhifHxjLmhifVxuZnVuY3Rpb24gTGQoYSxiKXtyZXR1cm57a2V5U3lzdGVtOmEsbGljZW5zZVNlcnZlclVyaTpcIlwiLGRpc3RpbmN0aXZlSWRlbnRpZmllclJlcXVpcmVkOiExLHBlcnNpc3RlbnRTdGF0ZVJlcXVpcmVkOiExLGF1ZGlvUm9idXN0bmVzczpcIlwiLHZpZGVvUm9idXN0bmVzczpcIlwiLHNlcnZlckNlcnRpZmljYXRlOm51bGwsaW5pdERhdGE6Ynx8W10sa2V5SWRzOltdfX1mdW5jdGlvbiBLZChhLGIsYyl7cmV0dXJuIGMubWFwKGZ1bmN0aW9uKGMpe3ZhciBlPUdkW2MuemJdO3JldHVybiBlP1tMZChlLGMuaW5pdHx8YSldOmIoYy5ub2RlKXx8W119KS5yZWR1Y2UodSxbXSl9XG5mdW5jdGlvbiBJZChhKXtyZXR1cm4gYS5tYXAoZnVuY3Rpb24oYSl7dmFyIGM9YS5nZXRBdHRyaWJ1dGUoXCJzY2hlbWVJZFVyaVwiKSxkPWEuZ2V0QXR0cmlidXRlKFwiY2VuYzpkZWZhdWx0X0tJRFwiKSxlPU0oYSxcImNlbmM6cHNzaFwiKS5tYXAoemQpO2lmKCFjKXJldHVybiBudWxsO2M9Yy50b0xvd2VyQ2FzZSgpO2lmKGQmJihkPWQucmVwbGFjZSgvLS9nLFwiXCIpLnRvTG93ZXJDYXNlKCksMDw9ZC5pbmRleE9mKFwiIFwiKSkpdGhyb3cgbmV3IHEoNCw0MDA5KTt2YXIgZj1bXTt0cnl7Zj1lLm1hcChmdW5jdGlvbihhKXtyZXR1cm57aW5pdERhdGFUeXBlOlwiY2VuY1wiLGluaXREYXRhOlhhKGEpfX0pfWNhdGNoKGcpe3Rocm93IG5ldyBxKDQsNDAwNyk7fXJldHVybntub2RlOmEsemI6YyxrZXlJZDpkLGluaXQ6MDxmLmxlbmd0aD9mOm51bGx9fSkuZmlsdGVyKERhKX07dmFyIE5kPTEvMTU7ZnVuY3Rpb24gT2QoYSxiLGMsZCxlKXtudWxsIT09ZSYmKGU9TWF0aC5yb3VuZChlKSk7dmFyIGY9e1JlcHJlc2VudGF0aW9uSUQ6YixOdW1iZXI6YyxCYW5kd2lkdGg6ZCxUaW1lOmV9O3JldHVybiBhLnJlcGxhY2UoL1xcJChSZXByZXNlbnRhdGlvbklEfE51bWJlcnxCYW5kd2lkdGh8VGltZSk/KD86JTAoWzAtOV0rKWQpP1xcJC9nLGZ1bmN0aW9uKGEsYixjKXtpZihcIiQkXCI9PWEpcmV0dXJuXCIkXCI7dmFyIGQ9ZltiXTtpZihudWxsPT1kKXJldHVybiBhO1wiUmVwcmVzZW50YXRpb25JRFwiPT1iJiZjJiYoYz12b2lkIDApO2E9ZC50b1N0cmluZygpO2M9d2luZG93LnBhcnNlSW50KGMsMTApfHwxO3JldHVybiBBcnJheShNYXRoLm1heCgwLGMtYS5sZW5ndGgpKzEpLmpvaW4oXCIwXCIpK2F9KX1cbmZ1bmN0aW9uIFBkKGEsYixjKXtpZihjLmxlbmd0aCl7dmFyIGQ9Y1swXTtkLnN0YXJ0VGltZTw9TmQmJihjWzBdPW5ldyBGKGQucG9zaXRpb24sMCxkLmVuZFRpbWUsZC5hLGQuTCxkLkQpKTthfHwoYT1jW2MubGVuZ3RoLTFdLGEuc3RhcnRUaW1lPmJ8fChjW2MubGVuZ3RoLTFdPW5ldyBGKGEucG9zaXRpb24sYS5zdGFydFRpbWUsYixhLmEsYS5MLGEuRCkpKX19ZnVuY3Rpb24gUChhLGIpe2lmKCFiLmxlbmd0aClyZXR1cm4gYTt2YXIgYz1iLm1hcChmdW5jdGlvbihhKXtyZXR1cm4gbmV3IG9hKGEpfSk7cmV0dXJuIGEubWFwKGZ1bmN0aW9uKGEpe3JldHVybiBuZXcgb2EoYSl9KS5tYXAoZnVuY3Rpb24oYSl7cmV0dXJuIGMubWFwKGEucmVzb2x2ZS5iaW5kKGEpKX0pLnJlZHVjZSh1LFtdKS5tYXAoZnVuY3Rpb24oYSl7cmV0dXJuIGEudG9TdHJpbmcoKX0pfVxuZnVuY3Rpb24gUWQoYSxiKXt2YXIgYz1RKGEsYixcInRpbWVzY2FsZVwiKSxkPTE7YyYmKGQ9RGQoYyl8fDEpO2M9UShhLGIsXCJkdXJhdGlvblwiKTsoYz1EZChjfHxcIlwiKSkmJihjLz1kKTt2YXIgZT1RKGEsYixcInN0YXJ0TnVtYmVyXCIpLGY9UShhLGIsXCJwcmVzZW50YXRpb25UaW1lT2Zmc2V0XCIpLGc9RWQoZXx8XCJcIik7aWYobnVsbD09ZXx8bnVsbD09ZylnPTE7dmFyIGg9UmQoYSxiLFwiU2VnbWVudFRpbWVsaW5lXCIpLGU9bnVsbDtpZihoKXtmb3IodmFyIGU9ZCxsPU51bWJlcihmKSxuPWEuSC5kdXJhdGlvbnx8SW5maW5pdHksaD1NKGgsXCJTXCIpLHI9W10sdD0wLEE9MDtBPGgubGVuZ3RoOysrQSl7dmFyIHg9aFtBXSxKPU4oeCxcInRcIixFZCksa2I9Tih4LFwiZFwiLEVkKSx4PU4oeCxcInJcIixDZCk7bnVsbCE9SiYmKEotPWwpO2lmKCFrYilicmVhaztKPW51bGwhPUo/Sjp0O3g9eHx8MDtpZigwPngpaWYoQSsxPGgubGVuZ3RoKXt4PU4oaFtBKzFdLFwidFwiLEVkKTtpZihudWxsPT14KWJyZWFrO2Vsc2UgaWYoSj49XG54KWJyZWFrO3g9TWF0aC5jZWlsKCh4LUopL2tiKS0xfWVsc2V7aWYoSW5maW5pdHk9PW4pYnJlYWs7ZWxzZSBpZihKL2U+PW4pYnJlYWs7eD1NYXRoLmNlaWwoKG4qZS1KKS9rYiktMX0wPHIubGVuZ3RoJiZKIT10JiYocltyLmxlbmd0aC0xXS5lbmQ9Si9lKTtmb3IodmFyIEpkPTA7SmQ8PXg7KytKZCl0PUora2Isci5wdXNoKHtzdGFydDpKL2UsZW5kOnQvZX0pLEo9dH1lPXJ9cmV0dXJue0hhOmQsRjpjLGhhOmcscHJlc2VudGF0aW9uVGltZU9mZnNldDpOdW1iZXIoZikvZHx8MCxCOmV9fWZ1bmN0aW9uIFEoYSxiLGMpe3JldHVybltiKGEudSksYihhLlApLGIoYS5LKV0uZmlsdGVyKERhKS5tYXAoZnVuY3Rpb24oYSl7cmV0dXJuIGEuZ2V0QXR0cmlidXRlKGMpfSkucmVkdWNlKGZ1bmN0aW9uKGEsYil7cmV0dXJuIGF8fGJ9KX1cbmZ1bmN0aW9uIFJkKGEsYixjKXtyZXR1cm5bYihhLnUpLGIoYS5QKSxiKGEuSyldLmZpbHRlcihEYSkubWFwKGZ1bmN0aW9uKGEpe3JldHVybiB5ZChhLGMpfSkucmVkdWNlKGZ1bmN0aW9uKGEsYil7cmV0dXJuIGF8fGJ9KX07ZnVuY3Rpb24gU2QoYSl7dGhpcy5iPWE7dGhpcy5jPTA9PVRkO3RoaXMuYT0wfXZhciBUZD0xO2Z1bmN0aW9uIFVkKGEpe3JldHVybiBhLmE8YS5iLmJ5dGVMZW5ndGh9ZnVuY3Rpb24gVmQoYSl7dHJ5e3ZhciBiPWEuYi5nZXRVaW50OChhLmEpfWNhdGNoKGMpe1dkKCl9YS5hKz0xO3JldHVybiBifWZ1bmN0aW9uIFhkKGEpe3RyeXt2YXIgYj1hLmIuZ2V0VWludDE2KGEuYSxhLmMpfWNhdGNoKGMpe1dkKCl9YS5hKz0yO3JldHVybiBifWZ1bmN0aW9uIFIoYSl7dHJ5e3ZhciBiPWEuYi5nZXRVaW50MzIoYS5hLGEuYyl9Y2F0Y2goYyl7V2QoKX1hLmErPTQ7cmV0dXJuIGJ9XG5mdW5jdGlvbiBZZChhKXt2YXIgYixjO3RyeXthLmM/KGI9YS5iLmdldFVpbnQzMihhLmEsITApLGM9YS5iLmdldFVpbnQzMihhLmErNCwhMCkpOihjPWEuYi5nZXRVaW50MzIoYS5hLCExKSxiPWEuYi5nZXRVaW50MzIoYS5hKzQsITEpKX1jYXRjaChkKXtXZCgpfWlmKDIwOTcxNTE8Yyl0aHJvdyBuZXcgcSgzLDMwMDEpO2EuYSs9ODtyZXR1cm4gYypNYXRoLnBvdygyLDMyKStifWZ1bmN0aW9uIFpkKGEsYil7YS5hK2I+YS5iLmJ5dGVMZW5ndGgmJldkKCk7dmFyIGM9YS5iLmJ1ZmZlci5zbGljZShhLmEsYS5hK2IpO2EuYSs9YjtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkoYyl9ZnVuY3Rpb24gUyhhLGIpe2EuYStiPmEuYi5ieXRlTGVuZ3RoJiZXZCgpO2EuYSs9Yn1cbmZ1bmN0aW9uICRkKGEpe3ZhciBiPWEuYTt0cnl7Zm9yKDtVZChhKSYmYS5iLmdldFVpbnQ4KGEuYSk7KWEuYSs9MX1jYXRjaChjKXtXZCgpfWI9YS5iLmJ1ZmZlci5zbGljZShiLGEuYSk7YS5hKz0xO3JldHVybiBEKGIpfWZ1bmN0aW9uIFdkKCl7dGhyb3cgbmV3IHEoMywzRTMpO307ZnVuY3Rpb24gYWUoYSxiKXtmb3IoO1VkKGIpOyl7dmFyIGM9Yi5hLGQ9UihiKSxlPVIoYik7MT09ZD9kPVlkKGIpOmR8fChkPWIuYi5ieXRlTGVuZ3RoLWMpO2lmKGU9PWEpcmV0dXJuIGQ7UyhiLGQtKGIuYS1jKSl9cmV0dXJuLTF9ZnVuY3Rpb24gYmUoYSxiKXtmb3IodmFyIGM9bmV3IFNkKG5ldyBEYXRhVmlldyhhKSksZD1bWzE4MzYwMTk1NzQsMF0sWzE5NTM2NTMwOTksMF0sWzE4MzUyOTcxMjEsMF0sWzE4MzU2MjYwODYsMF0sWzE5MzcwMDcyMTIsMF0sWzE5MzcwMTE1NTYsOF0sW2IsMF1dLGU9LTEsZj0wO2Y8ZC5sZW5ndGg7ZisrKXt2YXIgZz1kW2ZdWzFdLGU9YWUoZFtmXVswXSxjKTtpZigtMT09ZSlyZXR1cm4tMTtTKGMsZyl9cmV0dXJuIGV9O2Z1bmN0aW9uIGNlKGEsYixjLGQpe3ZhciBlPVtdO2E9bmV3IFNkKG5ldyBEYXRhVmlldyhhKSk7dmFyIGY9YWUoMTkzNjI4Njg0MCxhKTtpZigtMT09Zil0aHJvdyBuZXcgcSgzLDMwMDQpO3ZhciBnPVZkKGEpO1MoYSwzKTtTKGEsNCk7dmFyIGg9UihhKTtpZighaCl0aHJvdyBuZXcgcSgzLDMwMDUpO3ZhciBsLG47Zz8obD1ZZChhKSxuPVlkKGEpKToobD1SKGEpLG49UihhKSk7UyhhLDIpO2c9WGQoYSk7ZD1sLWQ7Yj1iK2Yrbjtmb3IoZj0wO2Y8ZztmKyspe2w9UihhKTtuPShsJjIxNDc0ODM2NDgpPj4+MzE7bCY9MjE0NzQ4MzY0Nzt2YXIgcj1SKGEpO1MoYSw0KTtpZigxPT1uKXRocm93IG5ldyBxKDMsMzAwNik7ZS5wdXNoKG5ldyBGKGUubGVuZ3RoLGQvaCwoZCtyKS9oLGZ1bmN0aW9uKCl7cmV0dXJuIGN9LGIsYitsLTEpKTtkKz1yO2IrPWx9cmV0dXJuIGV9O2Z1bmN0aW9uIFQoYSl7dGhpcy5hPWF9bShcInNoYWthLm1lZGlhLlNlZ21lbnRJbmRleFwiLFQpO1QucHJvdG90eXBlLm89ZnVuY3Rpb24oKXt0aGlzLmE9bnVsbDtyZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCl9O1QucHJvdG90eXBlLmRlc3Ryb3k9VC5wcm90b3R5cGUubztULnByb3RvdHlwZS5maW5kPWZ1bmN0aW9uKGEpe2Zvcih2YXIgYj10aGlzLmEubGVuZ3RoLTE7MDw9YjstLWIpe3ZhciBjPXRoaXMuYVtiXTtpZihhPj1jLnN0YXJ0VGltZSYmYTxjLmVuZFRpbWUpcmV0dXJuIGMucG9zaXRpb259cmV0dXJuIG51bGx9O1QucHJvdG90eXBlLmZpbmQ9VC5wcm90b3R5cGUuZmluZDtULnByb3RvdHlwZS5nZXQ9ZnVuY3Rpb24oYSl7aWYoIXRoaXMuYS5sZW5ndGgpcmV0dXJuIG51bGw7YS09dGhpcy5hWzBdLnBvc2l0aW9uO3JldHVybiAwPmF8fGE+PXRoaXMuYS5sZW5ndGg/bnVsbDp0aGlzLmFbYV19O1QucHJvdG90eXBlLmdldD1ULnByb3RvdHlwZS5nZXQ7XG5ULnByb3RvdHlwZS5VYT1mdW5jdGlvbihhKXtmb3IodmFyIGI9W10sYz0wLGQ9MDtjPHRoaXMuYS5sZW5ndGgmJmQ8YS5sZW5ndGg7KXt2YXIgZT10aGlzLmFbY10sZj1hW2RdO2Uuc3RhcnRUaW1lPGYuc3RhcnRUaW1lPyhiLnB1c2goZSksYysrKTooZS5zdGFydFRpbWU+Zi5zdGFydFRpbWV8fCguMTxNYXRoLmFicyhlLmVuZFRpbWUtZi5lbmRUaW1lKT9iLnB1c2goZik6Yi5wdXNoKGUpLGMrKyksZCsrKX1mb3IoO2M8dGhpcy5hLmxlbmd0aDspYi5wdXNoKHRoaXMuYVtjKytdKTtpZihiLmxlbmd0aClmb3IoYz1iW2IubGVuZ3RoLTFdLnBvc2l0aW9uKzE7ZDxhLmxlbmd0aDspZj1hW2QrK10sZj1uZXcgRihjKyssZi5zdGFydFRpbWUsZi5lbmRUaW1lLGYuYSxmLkwsZi5EKSxiLnB1c2goZik7ZWxzZSBiPWE7dGhpcy5hPWJ9O1QucHJvdG90eXBlLm1lcmdlPVQucHJvdG90eXBlLlVhO1xuVC5wcm90b3R5cGUuUGE9ZnVuY3Rpb24oYSl7Zm9yKHZhciBiPTA7Yjx0aGlzLmEubGVuZ3RoJiYhKHRoaXMuYVtiXS5lbmRUaW1lPmEpOysrYik7dGhpcy5hLnNwbGljZSgwLGIpfTtULnByb3RvdHlwZS5ldmljdD1ULnByb3RvdHlwZS5QYTtmdW5jdGlvbiBkZShhKXt0aGlzLmI9YTt0aGlzLmE9bmV3IFNkKGEpO2VlfHwoZWU9W25ldyBVaW50OEFycmF5KFsyNTVdKSxuZXcgVWludDhBcnJheShbMTI3LDI1NV0pLG5ldyBVaW50OEFycmF5KFs2MywyNTUsMjU1XSksbmV3IFVpbnQ4QXJyYXkoWzMxLDI1NSwyNTUsMjU1XSksbmV3IFVpbnQ4QXJyYXkoWzE1LDI1NSwyNTUsMjU1LDI1NV0pLG5ldyBVaW50OEFycmF5KFs3LDI1NSwyNTUsMjU1LDI1NSwyNTVdKSxuZXcgVWludDhBcnJheShbMywyNTUsMjU1LDI1NSwyNTUsMjU1LDI1NV0pLG5ldyBVaW50OEFycmF5KFsxLDI1NSwyNTUsMjU1LDI1NSwyNTUsMjU1LDI1NV0pXSl9dmFyIGVlO1xuZnVuY3Rpb24gZmUoYSl7dmFyIGI7Yj1nZShhKTtpZig3PGIubGVuZ3RoKXRocm93IG5ldyBxKDMsMzAwMik7Zm9yKHZhciBjPTAsZD0wO2Q8Yi5sZW5ndGg7ZCsrKWM9MjU2KmMrYltkXTtiPWM7Yz1nZShhKTthOntmb3IoZD0wO2Q8ZWUubGVuZ3RoO2QrKylpZigkYShjLGVlW2RdKSl7ZD0hMDticmVhayBhfWQ9ITF9aWYoZCljPWEuYi5ieXRlTGVuZ3RoLWEuYS5hO2Vsc2V7aWYoOD09Yy5sZW5ndGgmJmNbMV0mMjI0KXRocm93IG5ldyBxKDMsMzAwMSk7Zm9yKHZhciBkPWNbMF0mKDE8PDgtYy5sZW5ndGgpLTEsZT0xO2U8Yy5sZW5ndGg7ZSsrKWQ9MjU2KmQrY1tlXTtjPWR9Yz1hLmEuYStjPD1hLmIuYnl0ZUxlbmd0aD9jOmEuYi5ieXRlTGVuZ3RoLWEuYS5hO2Q9bmV3IERhdGFWaWV3KGEuYi5idWZmZXIsYS5iLmJ5dGVPZmZzZXQrYS5hLmEsYyk7UyhhLmEsYyk7cmV0dXJuIG5ldyBoZShiLGQpfVxuZnVuY3Rpb24gZ2UoYSl7dmFyIGI9VmQoYS5hKSxjO2ZvcihjPTE7OD49YyYmIShiJjE8PDgtYyk7YysrKTtpZig4PGMpdGhyb3cgbmV3IHEoMywzMDAyKTt2YXIgZD1uZXcgVWludDhBcnJheShjKTtkWzBdPWI7Zm9yKGI9MTtiPGM7YisrKWRbYl09VmQoYS5hKTtyZXR1cm4gZH1mdW5jdGlvbiBoZShhLGIpe3RoaXMuaWQ9YTt0aGlzLmE9Yn1mdW5jdGlvbiBpZShhKXtpZig4PGEuYS5ieXRlTGVuZ3RoKXRocm93IG5ldyBxKDMsMzAwMik7aWYoOD09YS5hLmJ5dGVMZW5ndGgmJmEuYS5nZXRVaW50OCgwKSYyMjQpdGhyb3cgbmV3IHEoMywzMDAxKTtmb3IodmFyIGI9MCxjPTA7YzxhLmEuYnl0ZUxlbmd0aDtjKyspdmFyIGQ9YS5hLmdldFVpbnQ4KGMpLGI9MjU2KmIrZDtyZXR1cm4gYn07ZnVuY3Rpb24gamUoYSxiLGMsZCxlLGYpe2Z1bmN0aW9uIGcoKXtyZXR1cm4gZX12YXIgaD1bXTthPW5ldyBkZShhLmEpO2Zvcih2YXIgbD0tMSxuPS0xO1VkKGEuYSk7KXt2YXIgcj1mZShhKTtpZigxODc9PXIuaWQpe3ZhciB0PWtlKHIpO3QmJihyPWMqKHQuWmMtZiksdD1iK3QueGMsMDw9bCYmaC5wdXNoKG5ldyBGKGgubGVuZ3RoLGwscixnLG4sdC0xKSksbD1yLG49dCl9fTA8PWwmJmgucHVzaChuZXcgRihoLmxlbmd0aCxsLGQsZyxuLG51bGwpKTtyZXR1cm4gaH1mdW5jdGlvbiBrZShhKXt2YXIgYj1uZXcgZGUoYS5hKTthPWZlKGIpO2lmKDE3OSE9YS5pZCl0aHJvdyBuZXcgcSgzLDMwMTMpO2E9aWUoYSk7Yj1mZShiKTtpZigxODMhPWIuaWQpdGhyb3cgbmV3IHEoMywzMDEyKTtmb3IodmFyIGI9bmV3IGRlKGIuYSksYz0wO1VkKGIuYSk7KXt2YXIgZD1mZShiKTtpZigyNDE9PWQuaWQpe2M9aWUoZCk7YnJlYWt9fXJldHVybntaYzphLHhjOmN9fTtmdW5jdGlvbiBsZShhLGIpe3ZhciBjPVJkKGEsYixcIkluaXRpYWxpemF0aW9uXCIpO2lmKCFjKXJldHVybiBudWxsO3ZhciBkPWEudS5NLGU9Yy5nZXRBdHRyaWJ1dGUoXCJzb3VyY2VVUkxcIik7ZSYmKGQ9UChhLnUuTSxbZV0pKTt2YXIgZT0wLGY9bnVsbDtpZihjPU4oYyxcInJhbmdlXCIsQmQpKWU9Yy5zdGFydCxmPWMuZW5kO3JldHVybiBuZXcgUGIoZnVuY3Rpb24oKXtyZXR1cm4gZH0sZSxmKX1cbmZ1bmN0aW9uIG1lKGEsYil7dmFyIGM9UShhLG5lLFwicHJlc2VudGF0aW9uVGltZU9mZnNldFwiKSxkPWxlKGEsbmUpLGU7ZT1OdW1iZXIoYyk7dmFyIGY9YS51Lm1pbWVUeXBlLnNwbGl0KFwiL1wiKVsxXTtpZihcInRleHRcIiE9YS51LmNvbnRlbnRUeXBlJiZcIm1wNFwiIT1mJiZcIndlYm1cIiE9Zil0aHJvdyBuZXcgcSg0LDQwMDYpO2lmKFwid2VibVwiPT1mJiYhZCl0aHJvdyBuZXcgcSg0LDQwMDUpO3ZhciBnPVJkKGEsbmUsXCJSZXByZXNlbnRhdGlvbkluZGV4XCIpLGg9UShhLG5lLFwiaW5kZXhSYW5nZVwiKSxsPWEudS5NLGg9QmQoaHx8XCJcIik7aWYoZyl7dmFyIG49Zy5nZXRBdHRyaWJ1dGUoXCJzb3VyY2VVUkxcIik7biYmKGw9UChhLnUuTSxbbl0pKTtoPU4oZyxcInJhbmdlXCIsQmQsaCl9aWYoIWgpdGhyb3cgbmV3IHEoNCw0MDAyKTtlPW9lKGEsYixkLGwsaC5zdGFydCxoLmVuZCxmLGUpO3JldHVybntjcmVhdGVTZWdtZW50SW5kZXg6ZS5jcmVhdGVTZWdtZW50SW5kZXgsZmluZFNlZ21lbnRQb3NpdGlvbjplLmZpbmRTZWdtZW50UG9zaXRpb24sXG5nZXRTZWdtZW50UmVmZXJlbmNlOmUuZ2V0U2VnbWVudFJlZmVyZW5jZSxpbml0U2VnbWVudFJlZmVyZW5jZTpkLHByZXNlbnRhdGlvblRpbWVPZmZzZXQ6TnVtYmVyKGMpfHwwfX1cbmZ1bmN0aW9uIG9lKGEsYixjLGQsZSxmLGcsaCl7dmFyIGw9YS5wcmVzZW50YXRpb25UaW1lbGluZSxuPWEuSC5zdGFydCxyPWEuSC5kdXJhdGlvbix0PWIsQT1udWxsO3JldHVybntjcmVhdGVTZWdtZW50SW5kZXg6ZnVuY3Rpb24oKXt2YXIgYj1bdChkLGUsZiksXCJ3ZWJtXCI9PWc/dChjLmEoKSxjLkwsYy5EKTpudWxsXTt0PW51bGw7cmV0dXJuIFByb21pc2UuYWxsKGIpLnRoZW4oZnVuY3Rpb24oYil7dmFyIGMsZj1iWzBdO2I9YlsxXXx8bnVsbDtpZihcIm1wNFwiPT1nKWY9Y2UoZixlLGQsaCk7ZWxzZXtiPW5ldyBkZShuZXcgRGF0YVZpZXcoYikpO2lmKDQ0MDc4Njg1MSE9ZmUoYikuaWQpdGhyb3cgbmV3IHEoMywzMDA4KTt2YXIgdD1mZShiKTtpZig0MDgxMjU1NDMhPXQuaWQpdGhyb3cgbmV3IHEoMywzMDA5KTtiPXQuYS5ieXRlT2Zmc2V0O3Q9bmV3IGRlKHQuYSk7Zm9yKGM9bnVsbDtVZCh0LmEpOyl7dmFyIHg9ZmUodCk7aWYoMzU3MTQ5MDMwPT14LmlkKXtjPXg7YnJlYWt9fWlmKCFjKXRocm93IG5ldyBxKDMsXG4zMDEwKTt0PW5ldyBkZShjLmEpO2M9MUU2O2Zvcih4PW51bGw7VWQodC5hKTspe3ZhciBwYj1mZSh0KTtpZigyODA3NzI5PT1wYi5pZCljPWllKHBiKTtlbHNlIGlmKDE3NTQ1PT1wYi5pZClpZih4PXBiLDQ9PXguYS5ieXRlTGVuZ3RoKXg9eC5hLmdldEZsb2F0MzIoMCk7ZWxzZSBpZig4PT14LmEuYnl0ZUxlbmd0aCl4PXguYS5nZXRGbG9hdDY0KDApO2Vsc2UgdGhyb3cgbmV3IHEoMywzMDAzKTt9aWYobnVsbD09eCl0aHJvdyBuZXcgcSgzLDMwMTEpO3Q9Yy8xRTk7Yz14KnQ7Zj1mZShuZXcgZGUobmV3IERhdGFWaWV3KGYpKSk7aWYoNDc1MjQ5NTE1IT1mLmlkKXRocm93IG5ldyBxKDMsMzAwNyk7Zj1qZShmLGIsdCxjLGQsaCl9UGQoYS5PYSxyLGYpO2wuRWEobixmKTtBPW5ldyBUKGYpfSl9LGZpbmRTZWdtZW50UG9zaXRpb246ZnVuY3Rpb24oYSl7cmV0dXJuIEEuZmluZChhKX0sZ2V0U2VnbWVudFJlZmVyZW5jZTpmdW5jdGlvbihhKXtyZXR1cm4gQS5nZXQoYSl9fX1cbmZ1bmN0aW9uIG5lKGEpe3JldHVybiBhLkZhfTtmdW5jdGlvbiBwZShhLGIpe3ZhciBjPWxlKGEscWUpLGQ7ZD1yZShhKTt2YXIgZT1RZChhLHFlKSxmPWUuaGE7Znx8KGY9MSk7dmFyIGc9MDtlLkY/Zz1lLkYqKGYtMSktZS5wcmVzZW50YXRpb25UaW1lT2Zmc2V0OmUuQiYmMDxlLkIubGVuZ3RoJiYoZz1lLkJbMF0uc3RhcnQpO2Q9e0Y6ZS5GLHN0YXJ0VGltZTpnLGhhOmYscHJlc2VudGF0aW9uVGltZU9mZnNldDplLnByZXNlbnRhdGlvblRpbWVPZmZzZXQsQjplLkIsdWE6ZH07aWYoIWQuRiYmIWQuQiYmMTxkLnVhLmxlbmd0aCl0aHJvdyBuZXcgcSg0LDQwMDIpO2lmKCFkLkYmJiFhLkguZHVyYXRpb24mJiFkLkImJjE9PWQudWEubGVuZ3RoKXRocm93IG5ldyBxKDQsNDAwMik7aWYoZC5CJiYhZC5CLmxlbmd0aCl0aHJvdyBuZXcgcSg0LDQwMDIpO2Y9ZT1udWxsO2EuSy5pZCYmYS51LmlkJiYoZj1hLksuaWQrXCIsXCIrYS51LmlkLGU9YltmXSk7Zz1zZShhLkguZHVyYXRpb24sZC5oYSxhLnUuTSxkKTtQZChhLk9hLGEuSC5kdXJhdGlvbixcbmcpO2U/KGUuVWEoZyksZS5QYShhLnByZXNlbnRhdGlvblRpbWVsaW5lLnNhKCktYS5ILnN0YXJ0KSk6KGEucHJlc2VudGF0aW9uVGltZWxpbmUuRWEoYS5ILnN0YXJ0LGcpLGU9bmV3IFQoZyksZiYmKGJbZl09ZSkpO3JldHVybntjcmVhdGVTZWdtZW50SW5kZXg6UHJvbWlzZS5yZXNvbHZlLmJpbmQoUHJvbWlzZSksZmluZFNlZ21lbnRQb3NpdGlvbjplLmZpbmQuYmluZChlKSxnZXRTZWdtZW50UmVmZXJlbmNlOmUuZ2V0LmJpbmQoZSksaW5pdFNlZ21lbnRSZWZlcmVuY2U6YyxwcmVzZW50YXRpb25UaW1lT2Zmc2V0OmQucHJlc2VudGF0aW9uVGltZU9mZnNldH19ZnVuY3Rpb24gcWUoYSl7cmV0dXJuIGEuWn1cbmZ1bmN0aW9uIHNlKGEsYixjLGQpe3ZhciBlPWQudWEubGVuZ3RoO2QuQiYmZC5CLmxlbmd0aCE9ZC51YS5sZW5ndGgmJihlPU1hdGgubWluKGQuQi5sZW5ndGgsZC51YS5sZW5ndGgpKTtmb3IodmFyIGY9W10sZz1kLnN0YXJ0VGltZSxoPTA7aDxlO2grKyl7dmFyIGw9ZC51YVtoXSxuPVAoYyxbbC5hY10pLHI7cj1udWxsIT1kLkY/ZytkLkY6ZC5CP2QuQltoXS5lbmQ6ZythO2YucHVzaChuZXcgRihoK2IsZyxyLGZ1bmN0aW9uKGEpe3JldHVybiBhfS5iaW5kKG51bGwsbiksbC5zdGFydCxsLmVuZCkpO2c9cn1yZXR1cm4gZn1cbmZ1bmN0aW9uIHJlKGEpe3JldHVyblthLnUuWixhLlAuWixhLksuWl0uZmlsdGVyKERhKS5tYXAoZnVuY3Rpb24oYSl7cmV0dXJuIE0oYSxcIlNlZ21lbnRVUkxcIil9KS5yZWR1Y2UoZnVuY3Rpb24oYSxjKXtyZXR1cm4gMDxhLmxlbmd0aD9hOmN9KS5tYXAoZnVuY3Rpb24oYSl7dmFyIGM9YS5nZXRBdHRyaWJ1dGUoXCJtZWRpYVwiKTthPU4oYSxcIm1lZGlhUmFuZ2VcIixCZCx7c3RhcnQ6MCxlbmQ6bnVsbH0pO3JldHVybnthYzpjLHN0YXJ0OmEuc3RhcnQsZW5kOmEuZW5kfX0pfTtmdW5jdGlvbiB0ZShhLGIsYyxkKXt2YXIgZT11ZShhKSxmO2Y9UWQoYSx2ZSk7dmFyIGc9UShhLHZlLFwibWVkaWFcIiksaD1RKGEsdmUsXCJpbmRleFwiKTtmPXtGOmYuRixIYTpmLkhhLGhhOmYuaGEscHJlc2VudGF0aW9uVGltZU9mZnNldDpmLnByZXNlbnRhdGlvblRpbWVPZmZzZXQsQjpmLkIsVGE6ZyxEYTpofTtnPTArKGYuRGE/MTowKTtnKz1mLkI/MTowO2crPWYuRj8xOjA7aWYoIWcpdGhyb3cgbmV3IHEoNCw0MDAyKTsxIT1nJiYoZi5EYSYmKGYuQj1udWxsKSxmLkY9bnVsbCk7aWYoIWYuRGEmJiFmLlRhKXRocm93IG5ldyBxKDQsNDAwMik7aWYoZi5EYSl7Yz1hLnUubWltZVR5cGUuc3BsaXQoXCIvXCIpWzFdO2lmKFwibXA0XCIhPWMmJlwid2VibVwiIT1jKXRocm93IG5ldyBxKDQsNDAwNik7aWYoXCJ3ZWJtXCI9PWMmJiFlKXRocm93IG5ldyBxKDQsNDAwNSk7ZD1PZChmLkRhLGEudS5pZCxudWxsLGEuYmFuZHdpZHRofHxudWxsLG51bGwpO2Q9UChhLnUuTSxbZF0pO2E9b2UoYSxiLGUsZCxcbjAsbnVsbCxjLGYucHJlc2VudGF0aW9uVGltZU9mZnNldCl9ZWxzZSBmLkY/KGR8fGEucHJlc2VudGF0aW9uVGltZWxpbmUuVmEoZi5GKSxhPXdlKGEsZikpOihkPWI9bnVsbCxhLksuaWQmJmEudS5pZCYmKGQ9YS5LLmlkK1wiLFwiK2EudS5pZCxiPWNbZF0pLGc9eGUoYSxmKSxQZChhLk9hLGEuSC5kdXJhdGlvbixnKSxiPyhiLlVhKGcpLGIuUGEoYS5wcmVzZW50YXRpb25UaW1lbGluZS5zYSgpLWEuSC5zdGFydCkpOihhLnByZXNlbnRhdGlvblRpbWVsaW5lLkVhKGEuSC5zdGFydCxnKSxiPW5ldyBUKGcpLGQmJihjW2RdPWIpKSxhPXtjcmVhdGVTZWdtZW50SW5kZXg6UHJvbWlzZS5yZXNvbHZlLmJpbmQoUHJvbWlzZSksZmluZFNlZ21lbnRQb3NpdGlvbjpiLmZpbmQuYmluZChiKSxnZXRTZWdtZW50UmVmZXJlbmNlOmIuZ2V0LmJpbmQoYil9KTtyZXR1cm57Y3JlYXRlU2VnbWVudEluZGV4OmEuY3JlYXRlU2VnbWVudEluZGV4LGZpbmRTZWdtZW50UG9zaXRpb246YS5maW5kU2VnbWVudFBvc2l0aW9uLFxuZ2V0U2VnbWVudFJlZmVyZW5jZTphLmdldFNlZ21lbnRSZWZlcmVuY2UsaW5pdFNlZ21lbnRSZWZlcmVuY2U6ZSxwcmVzZW50YXRpb25UaW1lT2Zmc2V0OmYucHJlc2VudGF0aW9uVGltZU9mZnNldH19ZnVuY3Rpb24gdmUoYSl7cmV0dXJuIGEuR2F9ZnVuY3Rpb24gd2UoYSxiKXt2YXIgYz1hLkguZHVyYXRpb24sZD1iLkYsZT1iLmhhLGY9Yi5IYSxnPWIuVGEsaD1hLmJhbmR3aWR0aHx8bnVsbCxsPWEudS5pZCxuPWEudS5NO3JldHVybntjcmVhdGVTZWdtZW50SW5kZXg6UHJvbWlzZS5yZXNvbHZlLmJpbmQoUHJvbWlzZSksZmluZFNlZ21lbnRQb3NpdGlvbjpmdW5jdGlvbihhKXtyZXR1cm4gMD5hfHxjJiZhPj1jP251bGw6TWF0aC5mbG9vcihhL2QpfSxnZXRTZWdtZW50UmVmZXJlbmNlOmZ1bmN0aW9uKGEpe3ZhciBiPWEqZDtyZXR1cm4gbmV3IEYoYSxiLGIrZCxmdW5jdGlvbigpe3ZhciBjPU9kKGcsbCxhK2UsaCxiKmYpO3JldHVybiBQKG4sW2NdKX0sMCxudWxsKX19fVxuZnVuY3Rpb24geGUoYSxiKXtmb3IodmFyIGM9W10sZD0wO2Q8Yi5CLmxlbmd0aDtkKyspe3ZhciBlPWIuQltkXS5zdGFydCxmPWQrYi5oYTtjLnB1c2gobmV3IEYoZixlLGIuQltkXS5lbmQsZnVuY3Rpb24oYSxiLGMsZCxlLGYpe2E9T2QoYSxiLGUsYyxmKTtyZXR1cm4gUChkLFthXSkubWFwKGZ1bmN0aW9uKGEpe3JldHVybiBhLnRvU3RyaW5nKCl9KX0uYmluZChudWxsLGIuVGEsYS51LmlkLGEuYmFuZHdpZHRofHxudWxsLGEudS5NLGYsKGUrYi5wcmVzZW50YXRpb25UaW1lT2Zmc2V0KSpiLkhhKSwwLG51bGwpKX1yZXR1cm4gY31mdW5jdGlvbiB1ZShhKXt2YXIgYj1RKGEsdmUsXCJpbml0aWFsaXphdGlvblwiKTtpZighYilyZXR1cm4gbnVsbDt2YXIgYz1hLnUuaWQsZD1hLmJhbmR3aWR0aHx8bnVsbCxlPWEudS5NO3JldHVybiBuZXcgUGIoZnVuY3Rpb24oKXt2YXIgYT1PZChiLGMsbnVsbCxkLG51bGwpO3JldHVybiBQKGUsW2FdKX0sMCxudWxsKX07ZnVuY3Rpb24geWUoKXt0aGlzLm09dGhpcy5sPXRoaXMuaj10aGlzLmM9dGhpcy5hPW51bGw7dGhpcy5nPVtdO3RoaXMuYj1udWxsO3RoaXMuaD1bXTt0aGlzLnY9MTt0aGlzLmk9e307dGhpcy5zPTA7dGhpcy5mPW51bGw7dGhpcy5JYT10aGlzLklhLmJpbmQodGhpcyl9az15ZS5wcm90b3R5cGU7ay5jb25maWd1cmU9ZnVuY3Rpb24oYSl7dGhpcy5jPWF9O2suc3RhcnQ9ZnVuY3Rpb24oYSxiLGMsZCxlKXt0aGlzLmc9W2FdO3RoaXMuYT1iO3RoaXMuaj1jO3RoaXMubD1kO3RoaXMubT1lO3JldHVybiB6ZSh0aGlzKS50aGVuKGZ1bmN0aW9uKCl7dGhpcy5hJiZBZSh0aGlzLDApO3JldHVybiB0aGlzLmJ9LmJpbmQodGhpcykpfTtcbmsuc3RvcD1mdW5jdGlvbigpe3RoaXMuYSYmdGhpcy5hLkdiKHRoaXMuSWEpO3RoaXMuYz10aGlzLm09dGhpcy5sPXRoaXMuaj10aGlzLmE9bnVsbDt0aGlzLmc9W107dGhpcy5iPW51bGw7dGhpcy5oPVtdO3RoaXMuaT17fTtudWxsIT10aGlzLmYmJih3aW5kb3cuY2xlYXJUaW1lb3V0KHRoaXMuZiksdGhpcy5mPW51bGwpO3JldHVybiBQcm9taXNlLnJlc29sdmUoKX07ZnVuY3Rpb24gemUoYSl7cmV0dXJuIGEuYS5yZXF1ZXN0KDAsSGEoYS5nLGEuYy5yZXRyeVBhcmFtZXRlcnMpKS50aGVuKGZ1bmN0aW9uKGEpe2lmKHRoaXMuYSlyZXR1cm4gQmUodGhpcyxhLmRhdGEsYS51cmkpfS5iaW5kKGEpKX1cbmZ1bmN0aW9uIEJlKGEsYixjKXt2YXIgZD1EKGIpLGU9bmV3IERPTVBhcnNlcixmPW51bGw7Yj1udWxsO3RyeXtmPWUucGFyc2VGcm9tU3RyaW5nKGQsXCJ0ZXh0L3htbFwiKX1jYXRjaChBKXt9ZiYmXCJNUERcIj09Zi5kb2N1bWVudEVsZW1lbnQudGFnTmFtZSYmKGI9Zi5kb2N1bWVudEVsZW1lbnQpO2lmKCFiKXRocm93IG5ldyBxKDQsNDAwMSk7Yz1bY107ZD1NKGIsXCJMb2NhdGlvblwiKS5tYXAoemQpLmZpbHRlcihEYSk7MDxkLmxlbmd0aCYmKGM9YS5nPWQpO2Q9TShiLFwiQmFzZVVSTFwiKS5tYXAoemQpO2M9UChjLGQpO3ZhciBnPU4oYixcIm1pbkJ1ZmZlclRpbWVcIixPKTthLnM9TihiLFwibWluaW11bVVwZGF0ZVBlcmlvZFwiLE8sLTEpO3ZhciBoPU4oYixcImF2YWlsYWJpbGl0eVN0YXJ0VGltZVwiLEFkKSxkPU4oYixcInRpbWVTaGlmdEJ1ZmZlckRlcHRoXCIsTyksbD1OKGIsXCJzdWdnZXN0ZWRQcmVzZW50YXRpb25EZWxheVwiLE8pLGU9TihiLFwibWF4U2VnbWVudER1cmF0aW9uXCIsTyksZj1iLmdldEF0dHJpYnV0ZShcInR5cGVcIil8fFxuXCJzdGF0aWNcIixuO2lmKGEuYiluPWEuYi5wcmVzZW50YXRpb25UaW1lbGluZTtlbHNle3ZhciByPU1hdGgubWF4KDEwLDEuNSpnKTtuPW5ldyBHKGgsbnVsbCE9bD9sOnIpfXZhciBoPUNlKGEse09hOlwic3RhdGljXCIhPWYscHJlc2VudGF0aW9uVGltZWxpbmU6bixLOm51bGwsSDpudWxsLFA6bnVsbCx1Om51bGwsYmFuZHdpZHRoOnZvaWQgMH0sYyxiKSxsPWguZHVyYXRpb24sdD1oLnBlcmlvZHM7bi5FYihcInN0YXRpY1wiPT1mKTtuLnphKGx8fEluZmluaXR5KTtuLkRiKG51bGwhPWQ/ZDpJbmZpbml0eSk7bi5WYShlfHwxKTtpZihhLmIpcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO2I9TShiLFwiVVRDVGltaW5nXCIpO2Q9bi5VKCk7aC5ZJiZhLmEudmIoYS5JYSk7cmV0dXJuIERlKGEsYyxiLGQpLnRoZW4oZnVuY3Rpb24oYSl7dGhpcy5hJiYobi5CYihhKSx0aGlzLmI9e3ByZXNlbnRhdGlvblRpbWVsaW5lOm4scGVyaW9kczp0LG9mZmxpbmVTZXNzaW9uSWRzOltdLG1pbkJ1ZmZlclRpbWU6Z3x8XG4wfSl9LmJpbmQoYSkpfVxuZnVuY3Rpb24gQ2UoYSxiLGMsZCl7dmFyIGU9TihkLFwibWVkaWFQcmVzZW50YXRpb25EdXJhdGlvblwiLE8pLGY9W10sZz0wO2Q9TShkLFwiUGVyaW9kXCIpO2Zvcih2YXIgaD0wO2g8ZC5sZW5ndGg7aCsrKXt2YXIgbD1kW2hdLGc9TihsLFwic3RhcnRcIixPLGcpLG49TihsLFwiZHVyYXRpb25cIixPKTtpZihudWxsPT1uKWlmKGgrMSE9ZC5sZW5ndGgpe3ZhciByPU4oZFtoKzFdLFwic3RhcnRcIixPKTtudWxsIT1yJiYobj1yLWcpfWVsc2UgbnVsbCE9ZSYmKG49ZS1nKTt2YXIgbD17c3RhcnQ6ZyxkdXJhdGlvbjpuLG5vZGU6bCxZOiExfSx0PWEsQT1iLHI9bDtBLks9RWUoci5ub2RlLG51bGwsYyk7QS5IPXI7QS5LLmlkfHwoQS5LLmlkPVwiX19zaGFrYV9wZXJpb2RfXCIrci5zdGFydCk7dD1NKHIubm9kZSxcIkFkYXB0YXRpb25TZXRcIikubWFwKHQucmMuYmluZCh0LEEpKS5maWx0ZXIoRGEpO2lmKCF0Lmxlbmd0aCl0aHJvdyBuZXcgcSg0LDQwMDQpO2ZvcihBPTA7QTx0Lmxlbmd0aDtBKyspdFtBXS5ZJiYoci5ZPVxuITApO3Q9RmUodCk7cj17c3RhcnRUaW1lOnIuc3RhcnQsc3RyZWFtU2V0czp0fTtmLnB1c2gocik7dD1iLksuaWQ7YS5oLmV2ZXJ5KEVhKHQpKSYmKGEuaihyKSxhLmgucHVzaCh0KSxhLmImJmEuYi5wZXJpb2RzLnB1c2gocikpO2lmKG51bGw9PW4pe2c9bnVsbDticmVha31nKz1ufXJldHVybiBudWxsIT1lP3twZXJpb2RzOmYsZHVyYXRpb246ZSxZOmwuWX06e3BlcmlvZHM6ZixkdXJhdGlvbjpnLFk6bC5ZfX1cbmsucmM9ZnVuY3Rpb24oYSxiKXthLlA9RWUoYixhLkssbnVsbCk7dmFyIGM9ITEsZD1NKGIsXCJSb2xlXCIpLGU9dm9pZCAwO1widGV4dFwiPT1hLlAuY29udGVudFR5cGUmJihlPVwic3VidGl0bGVcIik7Zm9yKHZhciBmPTA7ZjxkLmxlbmd0aDtmKyspe3ZhciBnPWRbZl0uZ2V0QXR0cmlidXRlKFwic2NoZW1lSWRVcmlcIik7aWYobnVsbD09Z3x8XCJ1cm46bXBlZzpkYXNoOnJvbGU6MjAxMVwiPT1nKXN3aXRjaChnPWRbZl0uZ2V0QXR0cmlidXRlKFwidmFsdWVcIiksZyl7Y2FzZSBcIm1haW5cIjpjPSEwO2JyZWFrO2Nhc2UgXCJjYXB0aW9uXCI6Y2FzZSBcInN1YnRpdGxlXCI6ZT1nfX12YXIgZD0hIXlkKGIsXCJJbmJhbmRFdmVudFN0cmVhbVwiKSxoPVtdO00oYixcIlN1cHBsZW1lbnRhbFByb3BlcnR5XCIpLmZvckVhY2goZnVuY3Rpb24oYSl7dmFyIGI9YS5nZXRBdHRyaWJ1dGUoXCJzY2hlbWVJZFVyaVwiKTsoXCJ1cm46bXBlZzpkYXNoOmFkYXB0YXRpb24tc2V0LXN3aXRjaGluZzoyMDE2XCI9PWJ8fFwiaHR0cDovL2Rhc2hpZi5vcmcvZ3VpZGVsaW5lcy9BZGFwdGF0aW9uU2V0U3dpdGNoaW5nXCI9PVxuYnx8XCJodHRwOi8vZGFzaGlmLm9yZy9kZXNjcmlwdG9yL0FkYXB0YXRpb25TZXRTd2l0Y2hpbmdcIj09YikmJihhPWEuZ2V0QXR0cmlidXRlKFwidmFsdWVcIikpJiZoLnB1c2guYXBwbHkoaCxhLnNwbGl0KFwiLFwiKSl9KTt2YXIgbD1udWxsO00oYixcIkVzc2VudGlhbFByb3BlcnR5XCIpLmZvckVhY2goZnVuY3Rpb24oYSl7XCJodHRwOi8vZGFzaGlmLm9yZy9ndWlkZWxpbmVzL3RyaWNrbW9kZVwiPT1hLmdldEF0dHJpYnV0ZShcInNjaGVtZUlkVXJpXCIpJiYobD1hLmdldEF0dHJpYnV0ZShcInZhbHVlXCIpKX0pO2lmKG51bGwhPWwpcmV0dXJuIG51bGw7Zj1NKGIsXCJDb250ZW50UHJvdGVjdGlvblwiKTtmPUhkKGYsdGhpcy5jLmRhc2guY3VzdG9tU2NoZW1lKTtnPUdjKGIuZ2V0QXR0cmlidXRlKFwibGFuZ1wiKXx8XCJ1bmRcIik7ZT1NKGIsXCJSZXByZXNlbnRhdGlvblwiKS5tYXAodGhpcy5zYy5iaW5kKHRoaXMsYSxmLGUsZykpLmZpbHRlcihmdW5jdGlvbihhKXtyZXR1cm4hIWF9KTtpZighZS5sZW5ndGgpdGhyb3cgbmV3IHEoNCxcbjQwMDMpO2lmKCFhLlAuY29udGVudFR5cGUpe3ZhciBuPWVbMF0ubWltZVR5cGUscj1lWzBdLmNvZGVjcyx0PW47ciYmKHQrPSc7IGNvZGVjcz1cIicrcisnXCInKTthLlAuY29udGVudFR5cGU9RVt0XT9cInRleHRcIjpuLnNwbGl0KFwiL1wiKVswXX1yZXR1cm57aWQ6YS5QLmlkfHxcIl9fZmFrZV9fXCIrdGhpcy52KyssY29udGVudFR5cGU6YS5QLmNvbnRlbnRUeXBlLGxhbmd1YWdlOmcsJGI6YyxzdHJlYW1zOmUsZHJtSW5mb3M6Zi5kcm1JbmZvcyxXYzpoLFk6ZH19O1xuay5zYz1mdW5jdGlvbihhLGIsYyxkLGUpe2EudT1FZShlLGEuUCxudWxsKTtpZighR2UoYS51KSlyZXR1cm4gbnVsbDthLmJhbmR3aWR0aD1OKGUsXCJiYW5kd2lkdGhcIixEZCl8fHZvaWQgMDt2YXIgZjtmPXRoaXMuemMuYmluZCh0aGlzKTtpZihhLnUuRmEpZj1tZShhLGYpO2Vsc2UgaWYoYS51LlopZj1wZShhLHRoaXMuaSk7ZWxzZSBpZihhLnUuR2EpZj10ZShhLGYsdGhpcy5pLCEhdGhpcy5iKTtlbHNle3ZhciBnPWEudS5NLGg9YS5ILmR1cmF0aW9ufHwwO2Y9e2NyZWF0ZVNlZ21lbnRJbmRleDpQcm9taXNlLnJlc29sdmUuYmluZChQcm9taXNlKSxmaW5kU2VnbWVudFBvc2l0aW9uOmZ1bmN0aW9uKGEpe3JldHVybiAwPD1hJiZhPGg/MTpudWxsfSxnZXRTZWdtZW50UmVmZXJlbmNlOmZ1bmN0aW9uKGEpe3JldHVybiAxIT1hP251bGw6bmV3IEYoMSwwLGgsZnVuY3Rpb24oKXtyZXR1cm4gZ30sMCxudWxsKX0saW5pdFNlZ21lbnRSZWZlcmVuY2U6bnVsbCxwcmVzZW50YXRpb25UaW1lT2Zmc2V0OjB9fWU9XG5NKGUsXCJDb250ZW50UHJvdGVjdGlvblwiKTtlPU1kKGUsdGhpcy5jLmRhc2guY3VzdG9tU2NoZW1lLGIpO3JldHVybntpZDp0aGlzLnYrKyxjcmVhdGVTZWdtZW50SW5kZXg6Zi5jcmVhdGVTZWdtZW50SW5kZXgsZmluZFNlZ21lbnRQb3NpdGlvbjpmLmZpbmRTZWdtZW50UG9zaXRpb24sZ2V0U2VnbWVudFJlZmVyZW5jZTpmLmdldFNlZ21lbnRSZWZlcmVuY2UsaW5pdFNlZ21lbnRSZWZlcmVuY2U6Zi5pbml0U2VnbWVudFJlZmVyZW5jZSxwcmVzZW50YXRpb25UaW1lT2Zmc2V0OmYucHJlc2VudGF0aW9uVGltZU9mZnNldCxtaW1lVHlwZTphLnUubWltZVR5cGUsY29kZWNzOmEudS5jb2RlY3MsZnJhbWVSYXRlOmEudS5mcmFtZVJhdGUsYmFuZHdpZHRoOmEuYmFuZHdpZHRoLHdpZHRoOmEudS53aWR0aCxoZWlnaHQ6YS51LmhlaWdodCxraW5kOmMsZW5jcnlwdGVkOjA8Yi5kcm1JbmZvcy5sZW5ndGgsa2V5SWQ6ZSxsYW5ndWFnZTpkLGFsbG93ZWRCeUFwcGxpY2F0aW9uOiEwLGFsbG93ZWRCeUtleVN5c3RlbTohMH19O1xuay5RYz1mdW5jdGlvbigpe3RoaXMuZj1udWxsO3ZhciBhPURhdGUubm93KCk7emUodGhpcykudGhlbihmdW5jdGlvbigpe3RoaXMuYSYmQWUodGhpcywoRGF0ZS5ub3coKS1hKS8xRTMpfS5iaW5kKHRoaXMpKVtcImNhdGNoXCJdKGZ1bmN0aW9uKGEpe3RoaXMubChhKTt0aGlzLmEmJkFlKHRoaXMsMCl9LmJpbmQodGhpcykpfTtmdW5jdGlvbiBBZShhLGIpezA+YS5zfHwoYS5mPXdpbmRvdy5zZXRUaW1lb3V0KGEuUWMuYmluZChhKSwxRTMqTWF0aC5tYXgoTWF0aC5tYXgoMyxhLnMpLWIsMCkpKX1cbmZ1bmN0aW9uIEVlKGEsYixjKXtiPWJ8fHtjb250ZW50VHlwZTpcIlwiLG1pbWVUeXBlOlwiXCIsY29kZWNzOlwiXCIsZnJhbWVSYXRlOnZvaWQgMH07Yz1jfHxiLk07dmFyIGQ9TShhLFwiQmFzZVVSTFwiKS5tYXAoemQpLGU9YS5nZXRBdHRyaWJ1dGUoXCJjb250ZW50VHlwZVwiKXx8Yi5jb250ZW50VHlwZSxmPWEuZ2V0QXR0cmlidXRlKFwibWltZVR5cGVcIil8fGIubWltZVR5cGUsZz1OKGEsXCJmcmFtZVJhdGVcIixGZCl8fGIuZnJhbWVSYXRlO2V8fChlPWYuc3BsaXQoXCIvXCIpWzBdKTtyZXR1cm57TTpQKGMsZCksRmE6eWQoYSxcIlNlZ21lbnRCYXNlXCIpfHxiLkZhLFo6eWQoYSxcIlNlZ21lbnRMaXN0XCIpfHxiLlosR2E6eWQoYSxcIlNlZ21lbnRUZW1wbGF0ZVwiKXx8Yi5HYSx3aWR0aDpOKGEsXCJ3aWR0aFwiLEVkKXx8Yi53aWR0aCxoZWlnaHQ6TihhLFwiaGVpZ2h0XCIsRWQpfHxiLmhlaWdodCxjb250ZW50VHlwZTplLG1pbWVUeXBlOmYsY29kZWNzOmEuZ2V0QXR0cmlidXRlKFwiY29kZWNzXCIpfHxiLmNvZGVjcyxcbmZyYW1lUmF0ZTpnLGlkOmEuZ2V0QXR0cmlidXRlKFwiaWRcIil9fVxuZnVuY3Rpb24gRmUoYSl7dmFyIGI9e307YS5mb3JFYWNoKGZ1bmN0aW9uKGEpe2JbYS5pZF09W2FdfSk7YS5mb3JFYWNoKGZ1bmN0aW9uKGEpe3ZhciBjPWJbYS5pZF07YS5XYy5mb3JFYWNoKGZ1bmN0aW9uKGEpeyhhPWJbYV0pJiZhIT1jJiYoYy5wdXNoLmFwcGx5KGMsYSksYS5mb3JFYWNoKGZ1bmN0aW9uKGEpe2JbYS5pZF09Y30pKX0pfSk7dmFyIGM9W10sZD1bXTtDKGIpLmZvckVhY2goZnVuY3Rpb24oYSl7aWYoISgwPD1kLmluZGV4T2YoYSkpKXtkLnB1c2goYSk7dmFyIGI9bmV3IEphO2EuZm9yRWFjaChmdW5jdGlvbihhKXtiLnB1c2goYS5jb250ZW50VHlwZXx8XCJcIixhKX0pO2Iua2V5cygpLmZvckVhY2goZnVuY3Rpb24oYSl7dmFyIGQ9bmV3IEphO2IuZ2V0KGEpLmZvckVhY2goZnVuY3Rpb24oYSl7ZC5wdXNoKGEubGFuZ3VhZ2UsYSl9KTtkLmtleXMoKS5mb3JFYWNoKGZ1bmN0aW9uKGIpe3ZhciBlPWQuZ2V0KGIpO2I9e2xhbmd1YWdlOmIsdHlwZTphLHByaW1hcnk6ZS5zb21lKGZ1bmN0aW9uKGEpe3JldHVybiBhLiRifSksXG5kcm1JbmZvczplLm1hcChmdW5jdGlvbihhKXtyZXR1cm4gYS5kcm1JbmZvc30pLnJlZHVjZSh1LFtdKSxzdHJlYW1zOmUubWFwKGZ1bmN0aW9uKGEpe3JldHVybiBhLnN0cmVhbXN9KS5yZWR1Y2UodSxbXSl9O2MucHVzaChiKX0pfSl9fSk7cmV0dXJuIGN9ZnVuY3Rpb24gR2UoYSl7dmFyIGI7Yj0wKyhhLkZhPzE6MCk7Yis9YS5aPzE6MDtiKz1hLkdhPzE6MDtpZighYilyZXR1cm5cInRleHRcIj09YS5jb250ZW50VHlwZXx8XCJhcHBsaWNhdGlvblwiPT1hLmNvbnRlbnRUeXBlPyEwOiExOzEhPWImJihhLkZhJiYoYS5aPW51bGwpLGEuR2E9bnVsbCk7cmV0dXJuITB9XG5mdW5jdGlvbiBIZShhLGIsYyxkKXtiPVAoYixbY10pO2I9SGEoYixhLmMucmV0cnlQYXJhbWV0ZXJzKTtiLm1ldGhvZD1kO3JldHVybiBhLmEucmVxdWVzdCgwLGIpLnRoZW4oZnVuY3Rpb24oYSl7aWYoXCJIRUFEXCI9PWQpe2lmKCFhLmhlYWRlcnN8fCFhLmhlYWRlcnMuZGF0ZSlyZXR1cm4gMDthPWEuaGVhZGVycy5kYXRlfWVsc2UgYT1EKGEuZGF0YSk7YT1EYXRlLnBhcnNlKGEpO3JldHVybiBpc05hTihhKT8wOmEtRGF0ZS5ub3coKX0pfVxuZnVuY3Rpb24gRGUoYSxiLGMsZCl7Yz1jLm1hcChmdW5jdGlvbihhKXtyZXR1cm57c2NoZW1lOmEuZ2V0QXR0cmlidXRlKFwic2NoZW1lSWRVcmlcIiksdmFsdWU6YS5nZXRBdHRyaWJ1dGUoXCJ2YWx1ZVwiKX19KTt2YXIgZT1hLmMuZGFzaC5jbG9ja1N5bmNVcmk7ZCYmIWMubGVuZ3RoJiZlJiZjLnB1c2goe3NjaGVtZTpcInVybjptcGVnOmRhc2g6dXRjOmh0dHAtaGVhZDoyMDE0XCIsdmFsdWU6ZX0pO3JldHVybiBDYShjLGZ1bmN0aW9uKGEpe3ZhciBjPWEudmFsdWU7c3dpdGNoKGEuc2NoZW1lKXtjYXNlIFwidXJuOm1wZWc6ZGFzaDp1dGM6aHR0cC1oZWFkOjIwMTRcIjpjYXNlIFwidXJuOm1wZWc6ZGFzaDp1dGM6aHR0cC1oZWFkOjIwMTJcIjpyZXR1cm4gSGUodGhpcyxiLGMsXCJIRUFEXCIpO2Nhc2UgXCJ1cm46bXBlZzpkYXNoOnV0YzpodHRwLXhzZGF0ZToyMDE0XCI6Y2FzZSBcInVybjptcGVnOmRhc2g6dXRjOmh0dHAtaXNvOjIwMTRcIjpjYXNlIFwidXJuOm1wZWc6ZGFzaDp1dGM6aHR0cC14c2RhdGU6MjAxMlwiOmNhc2UgXCJ1cm46bXBlZzpkYXNoOnV0YzpodHRwLWlzbzoyMDEyXCI6cmV0dXJuIEhlKHRoaXMsXG5iLGMsXCJHRVRcIik7Y2FzZSBcInVybjptcGVnOmRhc2g6dXRjOmRpcmVjdDoyMDE0XCI6Y2FzZSBcInVybjptcGVnOmRhc2g6dXRjOmRpcmVjdDoyMDEyXCI6cmV0dXJuIGE9RGF0ZS5wYXJzZShjKSxpc05hTihhKT8wOmEtRGF0ZS5ub3coKTtjYXNlIFwidXJuOm1wZWc6ZGFzaDp1dGM6aHR0cC1udHA6MjAxNFwiOmNhc2UgXCJ1cm46bXBlZzpkYXNoOnV0YzpudHA6MjAxNFwiOmNhc2UgXCJ1cm46bXBlZzpkYXNoOnV0YzpzbnRwOjIwMTRcIjpyZXR1cm4gUHJvbWlzZS5yZWplY3QoKTtkZWZhdWx0OnJldHVybiBQcm9taXNlLnJlamVjdCgpfX0uYmluZChhKSlbXCJjYXRjaFwiXShmdW5jdGlvbigpe3JldHVybiAwfSl9ay56Yz1mdW5jdGlvbihhLGIsYyl7YT1IYShhLHRoaXMuYy5yZXRyeVBhcmFtZXRlcnMpO251bGwhPWImJihhLmhlYWRlcnMuUmFuZ2U9XCJieXRlcz1cIitiK1wiLVwiKyhudWxsIT1jP2M6XCJcIikpO3JldHVybiB0aGlzLmEucmVxdWVzdCgxLGEpLnRoZW4oZnVuY3Rpb24oYSl7cmV0dXJuIGEuZGF0YX0pfTtcbmsuSWE9ZnVuY3Rpb24oYSxiKXtpZigxPT1hKXt2YXIgYz1uZXcgU2QobmV3IERhdGFWaWV3KGIuZGF0YSkpLGQ9YWUoMTcwMTY3MTc4MyxjKTtpZigtMSE9ZCl7dmFyIGU9Yy5hLTgrZDtTKGMsNCk7ZD0kZChjKTtpZihcInVybjptcGVnOmRhc2g6ZXZlbnQ6MjAxMlwiPT1kKXplKHRoaXMpO2Vsc2V7dmFyIGY9JGQoYyksZz1SKGMpLGg9UihjKSxsPVIoYyksbj1SKGMpLGM9WmQoYyxlLWMuYSk7dGhpcy5tKG5ldyBIKFwiZW1zZ1wiLHtkZXRhaWw6e2pkOmQsdmFsdWU6ZixIYTpnLGhkOmgsZmQ6bCxpZDpuLGdkOmN9fSkpfX19fTtzYi5tcGQ9eWU7cmJbXCJhcHBsaWNhdGlvbi9kYXNoK3htbFwiXT15ZTtmdW5jdGlvbiBVKGEsYil7dmFyIGM9RChhKSxkPVtdLGU9bmV3IERPTVBhcnNlcixmPW51bGw7dHJ5e2Y9ZS5wYXJzZUZyb21TdHJpbmcoYyxcInRleHQveG1sXCIpfWNhdGNoKG4pe3Rocm93IG5ldyBxKDIsMjAwNSk7fWlmKGYpe3ZhciBnLGg7aWYoYz1mLmdldEVsZW1lbnRzQnlUYWdOYW1lKFwidHRcIilbMF0pZT1jLmdldEF0dHJpYnV0ZShcInR0cDpmcmFtZVJhdGVcIiksZj1jLmdldEF0dHJpYnV0ZShcInR0cDpzdWJGcmFtZVJhdGVcIiksZz1jLmdldEF0dHJpYnV0ZShcInR0cDpmcmFtZVJhdGVNdWx0aXBsaWVyXCIpLGg9Yy5nZXRBdHRyaWJ1dGUoXCJ0dHA6dGlja1JhdGVcIik7ZWxzZSB0aHJvdyBuZXcgcSgyLDIwMDYpO2U9bmV3IEllKGUsZixnLGgpO2Y9VS5iKGMuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJzdHlsaW5nXCIpWzBdKTtnPVUuYihjLmdldEVsZW1lbnRzQnlUYWdOYW1lKFwibGF5b3V0XCIpWzBdKTtjPVUuYihjLmdldEVsZW1lbnRzQnlUYWdOYW1lKFwiYm9keVwiKVswXSk7Zm9yKGg9MDtoPFxuYy5sZW5ndGg7aCsrKXt2YXIgbD1VLmMoY1toXSxiLGUsZixnKTtsJiZkLnB1c2gobCl9fXJldHVybiBkfVUubD0vXihcXGR7Mix9KTooXFxkezJ9KTooXFxkezJ9KTooXFxkezJ9KVxcLj8oXFxkKyk/JC87VS5zPS9eKD86KFxcZHsyLH0pOik/KFxcZHsyfSk6KFxcZHsyfSkkLztVLm09L14oPzooXFxkezIsfSk6KT8oXFxkezJ9KTooXFxkezJ9XFwuXFxkezIsfSkkLztVLnY9L14oXFxkKlxcLj9cXGQqKWYkLztVLkE9L14oXFxkKlxcLj9cXGQqKXQkLztVLnc9L14oPzooXFxkKlxcLj9cXGQqKWgpPyg/OihcXGQqXFwuP1xcZCopbSk/KD86KFxcZCpcXC4/XFxkKilzKT8oPzooXFxkKlxcLj9cXGQqKW1zKT8kLztVLmo9L14oXFxkezEsMn18MTAwKSUgKFxcZHsxLDJ9fDEwMCklJC87XG5VLmI9ZnVuY3Rpb24oYSl7dmFyIGI9W107aWYoIWEpcmV0dXJuIGI7Zm9yKHZhciBjPWEuY2hpbGROb2RlcyxkPTA7ZDxjLmxlbmd0aDtkKyspe3ZhciBlPVwic3BhblwiPT1jW2RdLm5vZGVOYW1lJiZcInBcIj09YS5ub2RlTmFtZTtjW2RdLm5vZGVUeXBlIT1Ob2RlLkVMRU1FTlRfTk9ERXx8XCJiclwiPT1jW2RdLm5vZGVOYW1lfHxlfHwoZT1VLmIoY1tkXSksYj1iLmNvbmNhdChlKSl9Yi5sZW5ndGh8fGIucHVzaChhKTtyZXR1cm4gYn07XG5VLmM9ZnVuY3Rpb24oYSxiLGMsZCxlKXtpZighYS5oYXNBdHRyaWJ1dGUoXCJiZWdpblwiKSYmIWEuaGFzQXR0cmlidXRlKFwiZW5kXCIpJiZcIlwiPT1hLnRleHRDb250ZW50KXJldHVybiBudWxsO3ZhciBmPVUuYShhLmdldEF0dHJpYnV0ZShcImJlZ2luXCIpLGMpLGc9VS5hKGEuZ2V0QXR0cmlidXRlKFwiZW5kXCIpLGMpO2M9VS5hKGEuZ2V0QXR0cmlidXRlKFwiZHVyXCIpLGMpO3ZhciBoPWEudGV4dENvbnRlbnQ7bnVsbD09ZyYmbnVsbCE9YyYmKGc9ZitjKTtpZihudWxsPT1mfHxudWxsPT1nKXRocm93IG5ldyBxKDIsMjAwMSk7Yj13YihmK2IsZytiLGgpO2lmKCFiKXJldHVybiBudWxsO2U9VS5oKGEsXCJyZWdpb25cIixlKTtVLm5hKGIsYSxlLGQpO3JldHVybiBifTtcblUubmE9ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIGUsZj1VLmYoYixjLGQsXCJ0dHM6dGV4dEFsaWduXCIpO2YmJihhLmI9Zik7aWYoZj1VLmYoYixjLGQsXCJ0dHM6ZXh0ZW50XCIpKWlmKGU9VS5qLmV4ZWMoZikpYS5zaXplPU51bWJlcihlWzFdKTtlPVUuZihiLGMsZCxcInR0czp3cml0aW5nTW9kZVwiKTtmPSEwO1widGJcIj09ZXx8XCJ0YmxyXCI9PWU/YS5jPVwibHJcIjpcInRicmxcIj09ZT9hLmM9XCJybFwiOmY9ITE7aWYoYj1VLmYoYixjLGQsXCJ0dHM6b3JpZ2luXCIpKWlmKGU9VS5qLmV4ZWMoYikpZj8oYS5wb3NpdGlvbj1OdW1iZXIoZVsyXSksYS5hPU51bWJlcihlWzFdKSk6KGEucG9zaXRpb249TnVtYmVyKGVbMV0pLGEuYT1OdW1iZXIoZVsyXSkpfTtcblUuZj1mdW5jdGlvbihhLGIsYyxkKXtmb3IodmFyIGU9VS5iKGIpLGY9MDtmPGUubGVuZ3RoO2YrKyl7dmFyIGc9ZVtmXS5nZXRBdHRyaWJ1dGUoZCk7aWYoZylyZXR1cm4gZ31lPVUuaDtyZXR1cm4oYT1lKGIsXCJzdHlsZVwiLGMpfHxlKGEsXCJzdHlsZVwiLGMpKT9hLmdldEF0dHJpYnV0ZShkKTpudWxsfTtVLmg9ZnVuY3Rpb24oYSxiLGMpe2lmKCFhfHwxPmMubGVuZ3RoKXJldHVybiBudWxsO3ZhciBkPW51bGw7aWYoYT1VLm9hKGEsYikpZm9yKGI9MDtiPGMubGVuZ3RoO2IrKylpZihjW2JdLmdldEF0dHJpYnV0ZShcInhtbDppZFwiKT09YSl7ZD1jW2JdO2JyZWFrfXJldHVybiBkfTtVLm9hPWZ1bmN0aW9uKGEsYil7Zm9yKHZhciBjPW51bGw7YSYmIShjPWEuZ2V0QXR0cmlidXRlKGIpKTspe3ZhciBkPWEucGFyZW50Tm9kZTtpZihkIGluc3RhbmNlb2YgRWxlbWVudClhPWQ7ZWxzZSBicmVha31yZXR1cm4gY307XG5VLmE9ZnVuY3Rpb24oYSxiKXt2YXIgYz1udWxsO1UubC50ZXN0KGEpP2M9VS5wYShiLGEpOlUucy50ZXN0KGEpP2M9VS5nKFUucyxhKTpVLm0udGVzdChhKT9jPVUuZyhVLm0sYSk6VS52LnRlc3QoYSk/Yz1VLkFhKGIsYSk6VS5BLnRlc3QoYSk/Yz1VLkJhKGIsYSk6VS53LnRlc3QoYSkmJihjPVUuZyhVLncsYSkpO3JldHVybiBjfTtVLkFhPWZ1bmN0aW9uKGEsYil7dmFyIGM9VS52LmV4ZWMoYik7cmV0dXJuIE51bWJlcihjWzFdKS9hLmZyYW1lUmF0ZX07VS5CYT1mdW5jdGlvbihhLGIpe3ZhciBjPVUuQS5leGVjKGIpO3JldHVybiBOdW1iZXIoY1sxXSkvYS5hfTtVLnBhPWZ1bmN0aW9uKGEsYil7dmFyIGM9VS5sLmV4ZWMoYiksZD1OdW1iZXIoY1sxXSksZT1OdW1iZXIoY1syXSksZj1OdW1iZXIoY1szXSksZz1OdW1iZXIoY1s0XSksZz1nKyhOdW1iZXIoY1s1XSl8fDApL2EuYixmPWYrZy9hLmZyYW1lUmF0ZTtyZXR1cm4gZis2MCplKzM2MDAqZH07XG5VLmc9ZnVuY3Rpb24oYSxiKXt2YXIgYz1hLmV4ZWMoYik7cmV0dXJuIGMmJlwiXCIhPWNbMF0/KE51bWJlcihjWzRdKXx8MCkvMUUzKyhOdW1iZXIoY1szXSl8fDApKzYwKihOdW1iZXIoY1syXSl8fDApKzM2MDAqKE51bWJlcihjWzFdKXx8MCk6bnVsbH07ZnVuY3Rpb24gSWUoYSxiLGMsZCl7dGhpcy5mcmFtZVJhdGU9TnVtYmVyKGEpfHwzMDt0aGlzLmI9TnVtYmVyKGIpfHwxO3RoaXMuYT1OdW1iZXIoZCk7dGhpcy5hfHwodGhpcy5hPWE/dGhpcy5mcmFtZVJhdGUqdGhpcy5iOjEpO2MmJihhPS9eKFxcZCspIChcXGQrKSQvZy5leGVjKGMpKSYmKHRoaXMuZnJhbWVSYXRlKj1hWzFdL2FbMl0pfUVbXCJhcHBsaWNhdGlvbi90dG1sK3htbFwiXT1VO2Z1bmN0aW9uIEplKGEsYil7dmFyIGM9bmV3IFNkKG5ldyBEYXRhVmlldyhhKSksZD1hZSgxODM1Mjk1MDkyLGMpO2lmKC0xIT1kKXJldHVybiBVKFpkKGMsZC04KS5idWZmZXIsYik7aWYoLTEhPWJlKGEsSmUuSikpcmV0dXJuW107dGhyb3cgbmV3IHEoMiwyMDA3KTt9SmUuSj0xOTM3MDEwODAwO0VbJ2FwcGxpY2F0aW9uL21wNDsgY29kZWNzPVwic3RwcFwiJ109SmU7ZnVuY3Rpb24gS2UoYSl7dGhpcy5iPWE7dGhpcy5hPTB9ZnVuY3Rpb24gTGUoYSxiKXt2YXIgYztiLmxhc3RJbmRleD1hLmE7Yz0oYz1iLmV4ZWMoYS5iKSk/e3Bvc2l0aW9uOmMuaW5kZXgsbGVuZ3RoOmNbMF0ubGVuZ3RoLENjOmN9Om51bGw7aWYoYS5hPT1hLmIubGVuZ3RofHwhY3x8Yy5wb3NpdGlvbiE9YS5hKXJldHVybiBudWxsO2EuYSs9Yy5sZW5ndGg7cmV0dXJuIGMuQ2N9ZnVuY3Rpb24gTWUoYSl7cmV0dXJuIGEuYT09YS5iLmxlbmd0aD9udWxsOihhPUxlKGEsL1teIFxcdFxcbl0qL2dtKSk/YVswXTpudWxsfTtmdW5jdGlvbiBWKGEsYixjLGQsZSl7YT1EKGEpO2E9YS5yZXBsYWNlKC9cXHJcXG58XFxyKD89W15cXG5dfCQpL2dtLFwiXFxuXCIpO2E9YS5zcGxpdCgvXFxuezIsfS9tKTtpZighL15XRUJWVFQoJHxbIFxcdFxcbl0pL20udGVzdChhWzBdKSl0aHJvdyBuZXcgcSgyLDJFMyk7ZD1bXTtmb3IodmFyIGY9MTtmPGEubGVuZ3RoO2YrKyl7dmFyIGc9Vi5jKGFbZl0uc3BsaXQoXCJcXG5cIiksYixjLGUpO2cmJmQucHVzaChnKX1yZXR1cm4gZH1cblYuYz1mdW5jdGlvbihhLGIsYyxkKXtpZigxPT1hLmxlbmd0aCYmIWFbMF18fC9eTk9URSgkfFsgXFx0XSkvLnRlc3QoYVswXSkpcmV0dXJuIG51bGw7dmFyIGU9bnVsbDswPmFbMF0uaW5kZXhPZihcIi0tXFx4M2VcIikmJihlPWFbMF0sYS5zcGxpY2UoMCwxKSk7dmFyIGY9bmV3IEtlKGFbMF0pLGc9Vi5hKGYpLGg9TGUoZiwvWyBcXHRdKy0tXFx4M2VbIFxcdF0rL2cpLGw9Vi5hKGYpO2lmKG51bGw9PWd8fCFofHxudWxsPT1sKXRocm93IG5ldyBxKDIsMjAwMSk7Zys9YjtsKz1iO2QmJihnKz1jLGwrPWMpO2E9d2IoZyxsLGEuc2xpY2UoMSkuam9pbihcIlxcblwiKS50cmltKCkpO2lmKCFhKXJldHVybiBudWxsO0xlKGYsL1sgXFx0XSsvZ20pO2ZvcihiPU1lKGYpO2I7KVYuaShhLGIpLExlKGYsL1sgXFx0XSsvZ20pLGI9TWUoZik7bnVsbCE9ZSYmKGEuaWQ9ZSk7cmV0dXJuIGF9O1xuVi5pPWZ1bmN0aW9uKGEsYil7dmFyIGM7aWYoYz0vXmFsaWduOihzdGFydHxtaWRkbGV8ZW5kfGxlZnR8cmlnaHQpJC8uZXhlYyhiKSlhLmFsaWduPWNbMV07ZWxzZSBpZihjPS9edmVydGljYWw6KGxyfHJsKSQvLmV4ZWMoYikpYS5jPWNbMV07ZWxzZSBpZihjPS9ec2l6ZTooXFxkezEsMn18MTAwKSUkLy5leGVjKGIpKWEuc2l6ZT1OdW1iZXIoY1sxXSk7ZWxzZSBpZihjPS9ecG9zaXRpb246KFxcZHsxLDJ9fDEwMCklKD86LChsaW5lLWxlZnR8bGluZS1yaWdodHxjZW50ZXJ8c3RhcnR8ZW5kKSk/JC8uZXhlYyhiKSlhLnBvc2l0aW9uPU51bWJlcihjWzFdKSxjWzJdJiYoYS5nPWNbMl0pO2Vsc2UgaWYoYz0vXmxpbmU6KFxcZHsxLDJ9fDEwMCklKD86LChzdGFydHxlbmR8Y2VudGVyKSk/JC8uZXhlYyhiKSlhLmY9ITEsYS5hPU51bWJlcihjWzFdKSxjWzJdJiYoYS5iPWNbMl0pO2Vsc2UgaWYoYz0vXmxpbmU6KC0/XFxkKykoPzosKHN0YXJ0fGVuZHxjZW50ZXIpKT8kLy5leGVjKGIpKWEuZj1cbiEwLGEuYT1OdW1iZXIoY1sxXSksY1syXSYmKGEuYj1jWzJdKX07Vi5hPWZ1bmN0aW9uKGEpe2E9TGUoYSwvKD86KFxcZHsxLH0pOik/KFxcZHsyfSk6KFxcZHsyfSlcXC4oXFxkezN9KS9nKTtpZighYSlyZXR1cm4gbnVsbDt2YXIgYj1OdW1iZXIoYVsyXSksYz1OdW1iZXIoYVszXSk7cmV0dXJuIDU5PGJ8fDU5PGM/bnVsbDpOdW1iZXIoYVs0XSkvMUUzK2MrNjAqYiszNjAwKihOdW1iZXIoYVsxXSl8fDApfTtFW1widGV4dC92dHRcIl09VjtFWyd0ZXh0L3Z0dDsgY29kZWNzPVwidnR0XCInXT1WO2Z1bmN0aW9uIFcoYSxiLGMsZCl7dmFyIGU9bmV3IFNkKG5ldyBEYXRhVmlldyhhKSksZj1hZSgxODM1Mjk1MDkyLGUpO2lmKC0xIT1mKXJldHVybiBXLnFhKFpkKGUsZi04KS5idWZmZXIsYixjLGQpO2lmKC0xIT1iZShhLFcubWEpKXJldHVybltdO3Rocm93IG5ldyBxKDIsMjAwOCk7fVcucWE9ZnVuY3Rpb24oYSxiLGMsZCl7YT1uZXcgU2QobmV3IERhdGFWaWV3KGEpKTtjKz1iO2QrPWI7Zm9yKGI9W107VWQoYSk7KXt2YXIgZT1hZShXLlgsYSk7aWYoLTE9PWUpYnJlYWs7KGU9Vy5jKFpkKGEsZS04KS5idWZmZXIsYyxkKSkmJmIucHVzaChlKX1yZXR1cm4gYn07XG5XLmM9ZnVuY3Rpb24oYSxiLGMpe2E9bmV3IFNkKG5ldyBEYXRhVmlldyhhKSk7Zm9yKHZhciBkLGUsZjtVZChhKTspe3ZhciBnPVIoYSksaD1SKGEpLGw9RChaZChhLGctOCkuYnVmZmVyKTsxPT1nJiZZZChhKTtzd2l0Y2goaCl7Y2FzZSBXLkc6ZD1sO2JyZWFrO2Nhc2UgVy5DOmY9bDticmVhaztjYXNlIFcuUzplPWx9fWlmKCFkKXRocm93IG5ldyBxKDIsMjAwOCk7Yj13YihiLGMsZCk7aWYoIWIpcmV0dXJuIG51bGw7ZiYmKGIuaWQ9Zik7aWYoZSlmb3IoZT1uZXcgS2UoZSksZj1NZShlKTtmOylWLmkoYixmKSxMZShlLC9bIFxcdF0rL2dtKSxmPU1lKGUpO3JldHVybiBifTtXLm1hPTIwMDQyNTE3NjQ7Vy5YPTE5ODczNDM0NTk7Vy5HPTE4ODU0MzYyNjg7Vy5DPTE3NjgxODcyNDc7Vy5TPTE5MzcwMTE4MTU7RVsnYXBwbGljYXRpb24vbXA0OyBjb2RlY3M9XCJ3dnR0XCInXT1XO0ZhLmRhdGE9ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKGIpe3ZhciBjPWEuc3BsaXQoXCI6XCIpO2lmKDI+Yy5sZW5ndGh8fFwiZGF0YVwiIT1jWzBdKXRocm93IG5ldyBxKDEsMTAwNCxhKTtjPWMuc2xpY2UoMSkuam9pbihcIjpcIikuc3BsaXQoXCIsXCIpO2lmKDI+Yy5sZW5ndGgpdGhyb3cgbmV3IHEoMSwxMDA0LGEpO3ZhciBkPWNbMF0sYz13aW5kb3cuZGVjb2RlVVJJQ29tcG9uZW50KGMuc2xpY2UoMSkuam9pbihcIixcIikpLGQ9ZC5zcGxpdChcIjtcIiksZT1udWxsOzE8ZC5sZW5ndGgmJihlPWRbMV0pO2lmKFwiYmFzZTY0XCI9PWUpYz1YYShjKS5idWZmZXI7ZWxzZXtpZihlKXRocm93IG5ldyBxKDEsMTAwNSxhKTtjPVNhKGMpfWIoe3VyaTphLGRhdGE6YyxoZWFkZXJzOntcImNvbnRlbnQtdHlwZVwiOmRbMF19fSl9KX07ZnVuY3Rpb24gTmUoYSxiKXtyZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24oYyxkKXt2YXIgZT1uZXcgWE1MSHR0cFJlcXVlc3Q7ZS5vcGVuKGIubWV0aG9kLGEsITApO2UucmVzcG9uc2VUeXBlPVwiYXJyYXlidWZmZXJcIjtlLnRpbWVvdXQ9Yi5yZXRyeVBhcmFtZXRlcnMudGltZW91dDtlLndpdGhDcmVkZW50aWFscz1iLmFsbG93Q3Jvc3NTaXRlQ3JlZGVudGlhbHM7ZS5vbmxvYWQ9ZnVuY3Rpb24oYil7Yj1iLnRhcmdldDtpZigyMDA8PWIuc3RhdHVzJiYyOTk+PWIuc3RhdHVzKXt2YXIgZT1iLmdldEFsbFJlc3BvbnNlSGVhZGVycygpLnNwbGl0KFwiXFxyXFxuXCIpLnJlZHVjZShmdW5jdGlvbihhLGIpe3ZhciBjPWIuc3BsaXQoXCI6IFwiKTthW2NbMF0udG9Mb3dlckNhc2UoKV09Yy5zbGljZSgxKS5qb2luKFwiOiBcIik7cmV0dXJuIGF9LHt9KTtiLkJjJiYoYT1iLkJjKTtjKHt1cmk6YSxkYXRhOmIucmVzcG9uc2UsaGVhZGVyczplfSl9ZWxzZXtlPW51bGw7dHJ5e2U9UmEoYi5yZXNwb25zZSl9Y2F0Y2goZil7fWQobmV3IHEoMSxcbjEwMDEsYSxiLnN0YXR1cyxlKSl9fTtlLm9uZXJyb3I9ZnVuY3Rpb24oKXtkKG5ldyBxKDEsMTAwMixhKSl9O2Uub250aW1lb3V0PWZ1bmN0aW9uKCl7ZChuZXcgcSgxLDEwMDMsYSkpfTtmb3IodmFyIGYgaW4gYi5oZWFkZXJzKWUuc2V0UmVxdWVzdEhlYWRlcihmLGIuaGVhZGVyc1tmXSk7ZS5zZW5kKGIuYm9keSl9KX1GYS5odHRwPU5lO0ZhLmh0dHBzPU5lO2Z1bmN0aW9uIE9lKCl7dGhpcy5hPW51bGw7dGhpcy5jPVtdO3RoaXMuYj17fX1rPU9lLnByb3RvdHlwZTtcbmsuaW5pdD1mdW5jdGlvbihhKXtpZighd2luZG93LmluZGV4ZWREQilyZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IHEoOSw5RTMpKTt2YXIgYj13aW5kb3cuaW5kZXhlZERCLm9wZW4oXCJzaGFrYV9vZmZsaW5lX2RiXCIsMSksYz1uZXcgdztiLm9udXBncmFkZW5lZWRlZD1mdW5jdGlvbihiKXtiPWIudGFyZ2V0LnJlc3VsdDtmb3IodmFyIGMgaW4gYSliLmNyZWF0ZU9iamVjdFN0b3JlKGMse2tleVBhdGg6YVtjXX0pfTtiLm9uc3VjY2Vzcz1mdW5jdGlvbihhKXt0aGlzLmE9YS50YXJnZXQucmVzdWx0O2MucmVzb2x2ZSgpfS5iaW5kKHRoaXMpO2Iub25lcnJvcj1QZS5iaW5kKG51bGwsYixjKTtyZXR1cm4gYy50aGVuKGZ1bmN0aW9uKCl7dmFyIGI9T2JqZWN0LmtleXMoYSk7cmV0dXJuIFByb21pc2UuYWxsKGIubWFwKGZ1bmN0aW9uKGEpe3JldHVybiBRZSh0aGlzLGEpLnRoZW4oZnVuY3Rpb24oYil7dGhpcy5iW2FdPWJ9LmJpbmQodGhpcykpfS5iaW5kKHRoaXMpKSl9LmJpbmQodGhpcykpfTtcbmsubz1mdW5jdGlvbigpe3JldHVybiBQcm9taXNlLmFsbCh0aGlzLmMubWFwKGZ1bmN0aW9uKGEpe3RyeXthLnRyYW5zYWN0aW9uLmFib3J0KCl9Y2F0Y2goYil7fXJldHVybiBhLklbXCJjYXRjaFwiXSh2KX0pKS50aGVuKGZ1bmN0aW9uKCl7dGhpcy5hJiYodGhpcy5hLmNsb3NlKCksdGhpcy5hPW51bGwpfS5iaW5kKHRoaXMpKX07ay5nZXQ9ZnVuY3Rpb24oYSxiKXtyZXR1cm4gUmUodGhpcyxhLFwicmVhZG9ubHlcIixmdW5jdGlvbihhKXtyZXR1cm4gYS5nZXQoYil9KX07ay5mb3JFYWNoPWZ1bmN0aW9uKGEsYil7cmV0dXJuIFJlKHRoaXMsYSxcInJlYWRvbmx5XCIsZnVuY3Rpb24oYSl7cmV0dXJuIGEub3BlbkN1cnNvcigpfSxmdW5jdGlvbihhKXthJiYoYihhLnZhbHVlKSxhW1wiY29udGludWVcIl0oKSl9KX07ZnVuY3Rpb24gU2UoYSxiLGMpe3JldHVybiBSZShhLGIsXCJyZWFkd3JpdGVcIixmdW5jdGlvbihhKXtyZXR1cm4gYS5wdXQoYyl9KX1cbmsucmVtb3ZlPWZ1bmN0aW9uKGEsYil7cmV0dXJuIFJlKHRoaXMsYSxcInJlYWR3cml0ZVwiLGZ1bmN0aW9uKGEpe3JldHVybiBhW1wiZGVsZXRlXCJdKGIpfSl9O2Z1bmN0aW9uIFRlKGEsYil7dmFyIGM9W107cmV0dXJuIFJlKGEsXCJzZWdtZW50XCIsXCJyZWFkd3JpdGVcIixmdW5jdGlvbihhKXtyZXR1cm4gYS5vcGVuQ3Vyc29yKCl9LGZ1bmN0aW9uKGEpe2lmKGEpe2lmKGIoYS52YWx1ZSkpe3ZhciBlPWFbXCJkZWxldGVcIl0oKSxmPW5ldyB3O2Uub25zdWNjZXNzPWYucmVzb2x2ZTtlLm9uZXJyb3I9UGUuYmluZChudWxsLGUsZik7Yy5wdXNoKGYpfWFbXCJjb250aW51ZVwiXSgpfX0pLnRoZW4oZnVuY3Rpb24oKXtyZXR1cm4gUHJvbWlzZS5hbGwoYyl9KS50aGVuKGZ1bmN0aW9uKCl7cmV0dXJuIGMubGVuZ3RofSl9XG5mdW5jdGlvbiBRZShhLGIpe3ZhciBjPTA7cmV0dXJuIFJlKGEsYixcInJlYWRvbmx5XCIsZnVuY3Rpb24oYSl7cmV0dXJuIGEub3BlbkN1cnNvcihudWxsLFwicHJldlwiKX0sZnVuY3Rpb24oYSl7YSYmKGM9YS5rZXkrMSl9KS50aGVuKGZ1bmN0aW9uKCl7cmV0dXJuIGN9KX1cbmZ1bmN0aW9uIFJlKGEsYixjLGQsZSl7Yz1hLmEudHJhbnNhY3Rpb24oW2JdLGMpO3ZhciBmPWQoYy5vYmplY3RTdG9yZShiKSksZz1uZXcgdztlJiYoZi5vbnN1Y2Nlc3M9ZnVuY3Rpb24oYSl7ZShhLnRhcmdldC5yZXN1bHQpfSk7Zi5vbmVycm9yPVBlLmJpbmQobnVsbCxmLGcpO3ZhciBoPXt0cmFuc2FjdGlvbjpjLEk6Z307YS5jLnB1c2goaCk7dmFyIGw9ZnVuY3Rpb24oKXt0aGlzLmMuc3BsaWNlKHRoaXMuYy5pbmRleE9mKGgpLDEpfS5iaW5kKGEpO2Mub25jb21wbGV0ZT1mdW5jdGlvbigpe2woKTtnLnJlc29sdmUoZi5yZXN1bHQpfTtjLm9uZXJyb3I9ZnVuY3Rpb24oYSl7bCgpO1BlKGYsZyxhKX07cmV0dXJuIGd9ZnVuY3Rpb24gUGUoYSxiLGMpe1wiQWJvcnRFcnJvclwiPT1hLmVycm9yLm5hbWU/Yi5yZWplY3QobmV3IHEoOSw5MDAyKSk6Yi5yZWplY3QobmV3IHEoOSw5MDAxLGEuZXJyb3IpKTtjLnByZXZlbnREZWZhdWx0KCl9O3ZhciBVZT17bWFuaWZlc3Q6XCJrZXlcIixzZWdtZW50Olwia2V5XCJ9O2Z1bmN0aW9uIFZlKGEpe3JldHVybntvZmZsaW5lVXJpOlwib2ZmbGluZTpcIithLmtleSxvcmlnaW5hbE1hbmlmZXN0VXJpOmEub3JpZ2luYWxNYW5pZmVzdFVyaSxkdXJhdGlvbjphLmR1cmF0aW9uLHNpemU6YS5zaXplLHRyYWNrczphLnBlcmlvZHNbMF0uc3RyZWFtcy5tYXAoZnVuY3Rpb24oYSl7cmV0dXJue2lkOmEuaWQsYWN0aXZlOiExLHR5cGU6YS5jb250ZW50VHlwZSxiYW5kd2lkdGg6MCxsYW5ndWFnZTphLmxhbmd1YWdlLGtpbmQ6YS5raW5kfHxudWxsLHdpZHRoOmEud2lkdGgsaGVpZ2h0OmEuaGVpZ2h0LGZyYW1lUmF0ZTphLmZyYW1lUmF0ZSxjb2RlY3M6YS5jb2RlY3N9fSksYXBwTWV0YWRhdGE6YS5hcHBNZXRhZGF0YX19O2Z1bmN0aW9uIFdlKCl7fVdlLnByb3RvdHlwZS5jb25maWd1cmU9ZnVuY3Rpb24oKXt9O1dlLnByb3RvdHlwZS5zdGFydD1mdW5jdGlvbihhKXt2YXIgYj0vXm9mZmxpbmU6KFswLTldKykkLy5leGVjKGEpO2lmKCFiKXJldHVybiBQcm9taXNlLnJlamVjdChuZXcgcSgxLDkwMDQsYSkpO3ZhciBjPU51bWJlcihiWzFdKSxkPW5ldyBPZTtyZXR1cm4gZC5pbml0KFVlKS50aGVuKGZ1bmN0aW9uKCl7cmV0dXJuIGQuZ2V0KFwibWFuaWZlc3RcIixjKX0pLnRoZW4oZnVuY3Rpb24oYSl7aWYoIWEpdGhyb3cgbmV3IHEoOSw5MDAzLGMpO3JldHVybiBYZShhKX0pLnRoZW4oZnVuY3Rpb24oYSl7cmV0dXJuIGQubygpLnRoZW4oZnVuY3Rpb24oKXtyZXR1cm4gYX0pfSxmdW5jdGlvbihhKXtyZXR1cm4gZC5vKCkudGhlbihmdW5jdGlvbigpe3Rocm93IGE7fSl9KX07V2UucHJvdG90eXBlLnN0b3A9ZnVuY3Rpb24oKXtyZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCl9O1xuZnVuY3Rpb24gWGUoYSl7dmFyIGI9bmV3IEcobnVsbCwwKTtiLnphKGEuZHVyYXRpb24pO3ZhciBjPWEuZHJtSW5mbz9bYS5kcm1JbmZvXTpbXTtyZXR1cm57cHJlc2VudGF0aW9uVGltZWxpbmU6YixtaW5CdWZmZXJUaW1lOjEwLG9mZmxpbmVTZXNzaW9uSWRzOmEuc2Vzc2lvbklkcyxwZXJpb2RzOmEucGVyaW9kcy5tYXAoZnVuY3Rpb24oYSl7cmV0dXJue3N0YXJ0VGltZTphLnN0YXJ0VGltZSxzdHJlYW1TZXRzOmEuc3RyZWFtcy5tYXAoZnVuY3Rpb24oZSl7dmFyIGY9ZS5zZWdtZW50cy5tYXAoZnVuY3Rpb24oYSxiKXtyZXR1cm4gbmV3IEYoYixhLnN0YXJ0VGltZSxhLmVuZFRpbWUsZnVuY3Rpb24oKXtyZXR1cm5bYS51cmldfSwwLG51bGwpfSk7Yi5FYShhLnN0YXJ0VGltZSxmKTtmPW5ldyBUKGYpO3JldHVybntsYW5ndWFnZTplLmxhbmd1YWdlLHR5cGU6ZS5jb250ZW50VHlwZSxwcmltYXJ5OmUucHJpbWFyeSxkcm1JbmZvczpjLHN0cmVhbXM6W3tpZDplLmlkLGNyZWF0ZVNlZ21lbnRJbmRleDpQcm9taXNlLnJlc29sdmUuYmluZChQcm9taXNlKSxcbmZpbmRTZWdtZW50UG9zaXRpb246Zi5maW5kLmJpbmQoZiksZ2V0U2VnbWVudFJlZmVyZW5jZTpmLmdldC5iaW5kKGYpLGluaXRTZWdtZW50UmVmZXJlbmNlOmUuaW5pdFNlZ21lbnRVcmk/bmV3IFBiKGZ1bmN0aW9uKCl7cmV0dXJuW2UuaW5pdFNlZ21lbnRVcmldfSwwLG51bGwpOm51bGwscHJlc2VudGF0aW9uVGltZU9mZnNldDplLnByZXNlbnRhdGlvblRpbWVPZmZzZXQsbWltZVR5cGU6ZS5taW1lVHlwZSxjb2RlY3M6ZS5jb2RlY3MsYmFuZHdpZHRoOjAsd2lkdGg6ZS53aWR0aHx8dm9pZCAwLGhlaWdodDplLmhlaWdodHx8dm9pZCAwLGtpbmQ6ZS5raW5kLGVuY3J5cHRlZDplLmVuY3J5cHRlZCxrZXlJZDplLmtleUlkLGFsbG93ZWRCeUFwcGxpY2F0aW9uOiEwLGFsbG93ZWRCeUtleVN5c3RlbTohMH1dfX0pfX0pfX1yYltcImFwcGxpY2F0aW9uL3gtb2ZmbGluZS1tYW5pZmVzdFwiXT1XZTtGYS5vZmZsaW5lPWZ1bmN0aW9uKGEpe2lmKC9eb2ZmbGluZTooWzAtOV0rKSQvLmV4ZWMoYSkpe3ZhciBiPXt1cmk6YSxkYXRhOm5ldyBBcnJheUJ1ZmZlcigwKSxoZWFkZXJzOntcImNvbnRlbnQtdHlwZVwiOlwiYXBwbGljYXRpb24veC1vZmZsaW5lLW1hbmlmZXN0XCJ9fTtyZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGIpfWlmKGI9L15vZmZsaW5lOlswLTldK1xcL1swLTldK1xcLyhbMC05XSspJC8uZXhlYyhhKSl7dmFyIGM9TnVtYmVyKGJbMV0pLGQ9bmV3IE9lO3JldHVybiBkLmluaXQoVWUpLnRoZW4oZnVuY3Rpb24oKXtyZXR1cm4gZC5nZXQoXCJzZWdtZW50XCIsYyl9KS50aGVuKGZ1bmN0aW9uKGIpe3JldHVybiBkLm8oKS50aGVuKGZ1bmN0aW9uKCl7aWYoIWIpdGhyb3cgbmV3IHEoOSw5MDAzLGMpO3JldHVybnt1cmk6YSxkYXRhOmIuZGF0YSxoZWFkZXJzOnt9fX0pfSl9cmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBxKDEsOTAwNCxhKSl9O2Z1bmN0aW9uIFllKGEsYixjKXt0aGlzLmI9e307dGhpcy5pPWM7dGhpcy5tPWE7dGhpcy5sPWI7dGhpcy5qPXRoaXMuYT1udWxsO3RoaXMuZj10aGlzLmc9dGhpcy5oPXRoaXMuYz0wfVllLnByb3RvdHlwZS5vPWZ1bmN0aW9uKCl7dmFyIGE9dGhpcy5qfHxQcm9taXNlLnJlc29sdmUoKTt0aGlzLmI9e307dGhpcy5qPXRoaXMuYT10aGlzLmw9dGhpcy5tPXRoaXMuaT1udWxsO3JldHVybiBhfTtmdW5jdGlvbiBaZShhLGIsYyxkLGUpe2EuYltiXT1hLmJbYl18fFtdO2EuYltiXS5wdXNoKHt1cmlzOmMuYSgpLEw6Yy5MLEQ6Yy5ELGdiOmQsQ2E6ZX0pfVxuZnVuY3Rpb24gJGUoYSxiKXthLmM9MDthLmg9MDthLmc9MDthLmY9MDtDKGEuYikuZm9yRWFjaChmdW5jdGlvbihhKXthLmZvckVhY2goZnVuY3Rpb24oYSl7bnVsbCE9YS5EP3RoaXMuYys9YS5ELWEuTCsxOnRoaXMuZys9YS5nYn0uYmluZCh0aGlzKSl9LmJpbmQoYSkpO2EuYT1iO2EuYS5zaXplPWEuYzt2YXIgYz1DKGEuYikubWFwKGZ1bmN0aW9uKGEpe3ZhciBiPTAsYz1mdW5jdGlvbigpe2lmKCF0aGlzLmkpcmV0dXJuIFByb21pc2UucmVqZWN0KG5ldyBxKDksOTAwMikpO2lmKGI+PWEubGVuZ3RoKXJldHVybiBQcm9taXNlLnJlc29sdmUoKTt2YXIgZz1hW2IrK107cmV0dXJuIGFmKHRoaXMsZykudGhlbihjKX0uYmluZCh0aGlzKTtyZXR1cm4gYygpfS5iaW5kKGEpKTthLmI9e307cmV0dXJuIGEuaj1Qcm9taXNlLmFsbChjKX1cbmZ1bmN0aW9uIGFmKGEsYil7dmFyIGM9SGEoYi51cmlzLGEubCk7aWYoYi5MfHxudWxsIT1iLkQpYy5oZWFkZXJzLlJhbmdlPVwiYnl0ZXM9XCIrYi5MK1wiLVwiKyhudWxsPT1iLkQ/XCJcIjpiLkQpO3ZhciBkO3JldHVybiBhLm0ucmVxdWVzdCgxLGMpLnRoZW4oZnVuY3Rpb24oYSl7aWYoIXRoaXMuYSlyZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IHEoOSw5MDAyKSk7ZD1hLmRhdGEuYnl0ZUxlbmd0aDtyZXR1cm4gYi5DYShhLmRhdGEpfS5iaW5kKGEpKS50aGVuKGZ1bmN0aW9uKCl7aWYoIXRoaXMuYSlyZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IHEoOSw5MDAyKSk7bnVsbD09Yi5EPyh0aGlzLmEuc2l6ZSs9ZCx0aGlzLmYrPWIuZ2IpOnRoaXMuaCs9ZDt2YXIgYT0odGhpcy5oK3RoaXMuZikvKHRoaXMuYyt0aGlzLmcpLGM9VmUodGhpcy5hKTt0aGlzLmkucHJvZ3Jlc3NDYWxsYmFjayhjLGEpfS5iaW5kKGEpKX07ZnVuY3Rpb24gWChhKXt0aGlzLmE9bmV3IE9lO3RoaXMuYz1hO3RoaXMuaj1iZih0aGlzKTt0aGlzLmc9bnVsbDt0aGlzLnY9ITE7dGhpcy5pPW51bGw7dGhpcy5sPVtdO3RoaXMuZj0tMTt0aGlzLm09MDt0aGlzLmI9bnVsbDt0aGlzLmg9bmV3IFllKGEuaCxhLmdldENvbmZpZ3VyYXRpb24oKS5zdHJlYW1pbmcucmV0cnlQYXJhbWV0ZXJzLHRoaXMuail9bShcInNoYWthLm9mZmxpbmUuU3RvcmFnZVwiLFgpO2Z1bmN0aW9uIGNmKCl7cmV0dXJuISF3aW5kb3cuaW5kZXhlZERCfVguc3VwcG9ydD1jZjtcblgucHJvdG90eXBlLm89ZnVuY3Rpb24oKXt2YXIgYT10aGlzLmwsYj10aGlzLmEsYz10aGlzLmg/dGhpcy5oLm8oKVtcImNhdGNoXCJdKGZ1bmN0aW9uKCl7fSkudGhlbihmdW5jdGlvbigpe3JldHVybiBQcm9taXNlLmFsbChhLm1hcChmdW5jdGlvbihhKXtyZXR1cm4gYi5yZW1vdmUoXCJzZWdtZW50XCIsYSl9KSl9KS50aGVuKGZ1bmN0aW9uKCl7cmV0dXJuIGIubygpfSk6UHJvbWlzZS5yZXNvbHZlKCk7dGhpcy5qPXRoaXMuYz10aGlzLmg9dGhpcy5hPW51bGw7cmV0dXJuIGN9O1gucHJvdG90eXBlLmRlc3Ryb3k9WC5wcm90b3R5cGUubztYLnByb3RvdHlwZS5jb25maWd1cmU9ZnVuY3Rpb24oYSl7Q2ModGhpcy5qLGEsYmYodGhpcykse30sXCJcIil9O1gucHJvdG90eXBlLmNvbmZpZ3VyZT1YLnByb3RvdHlwZS5jb25maWd1cmU7XG5YLnByb3RvdHlwZS5UYz1mdW5jdGlvbihhLGIsYyl7ZnVuY3Rpb24gZChhKXtmPWF9aWYodGhpcy52KXJldHVybiBQcm9taXNlLnJlamVjdChuZXcgcSg5LDkwMDYpKTt0aGlzLnY9ITA7dmFyIGUsZj1udWxsO3JldHVybiBkZih0aGlzKS50aGVuKGZ1bmN0aW9uKCl7WSh0aGlzKTtyZXR1cm4gZWYodGhpcyxhLGQsYyl9LmJpbmQodGhpcykpLnRoZW4oZnVuY3Rpb24oYyl7WSh0aGlzKTt0aGlzLmI9Yy5tYW5pZmVzdDt0aGlzLmc9Yy5QYjtpZih0aGlzLmIucHJlc2VudGF0aW9uVGltZWxpbmUuVSgpfHx0aGlzLmIucHJlc2VudGF0aW9uVGltZWxpbmUuZmEoKSl0aHJvdyBuZXcgcSg5LDkwMDUsYSk7dGhpcy5iLnBlcmlvZHMuZm9yRWFjaCh0aGlzLnMuYmluZCh0aGlzKSk7dGhpcy5mPXRoaXMuYS5iLm1hbmlmZXN0Kys7dGhpcy5tPTA7Yz10aGlzLmIucGVyaW9kcy5tYXAodGhpcy53LmJpbmQodGhpcykpO3ZhciBkPXRoaXMuZy5iLGY9aWIodGhpcy5nKTtpZihkKXtpZighZi5sZW5ndGgpdGhyb3cgbmV3IHEoOSxcbjkwMDcsYSk7ZC5pbml0RGF0YT1bXX1lPXtrZXk6dGhpcy5mLG9yaWdpbmFsTWFuaWZlc3RVcmk6YSxkdXJhdGlvbjp0aGlzLm0sc2l6ZTowLHBlcmlvZHM6YyxzZXNzaW9uSWRzOmYsZHJtSW5mbzpkLGFwcE1ldGFkYXRhOmJ9O3JldHVybiAkZSh0aGlzLmgsZSl9LmJpbmQodGhpcykpLnRoZW4oZnVuY3Rpb24oKXtZKHRoaXMpO2lmKGYpdGhyb3cgZjtyZXR1cm4gU2UodGhpcy5hLFwibWFuaWZlc3RcIixlKX0uYmluZCh0aGlzKSkudGhlbihmdW5jdGlvbigpe3JldHVybiBmZih0aGlzKX0uYmluZCh0aGlzKSkudGhlbihmdW5jdGlvbigpe3JldHVybiBWZShlKX0uYmluZCh0aGlzKSlbXCJjYXRjaFwiXShmdW5jdGlvbihhKXtyZXR1cm4gZmYodGhpcylbXCJjYXRjaFwiXSh2KS50aGVuKGZ1bmN0aW9uKCl7dGhyb3cgYTt9KX0uYmluZCh0aGlzKSl9O1gucHJvdG90eXBlLnN0b3JlPVgucHJvdG90eXBlLlRjO1xuWC5wcm90b3R5cGUucmVtb3ZlPWZ1bmN0aW9uKGEpe2Z1bmN0aW9uIGIoYSl7NjAxMyE9YS5jb2RlJiYoZT1hKX12YXIgYz1hLm9mZmxpbmVVcmksZD0vXm9mZmxpbmU6KFswLTldKykkLy5leGVjKGMpO2lmKCFkKXJldHVybiBQcm9taXNlLnJlamVjdChuZXcgcSg5LDkwMDQsYykpO3ZhciBlPW51bGwsZixnLGg9TnVtYmVyKGRbMV0pO3JldHVybiBkZih0aGlzKS50aGVuKGZ1bmN0aW9uKCl7WSh0aGlzKTtyZXR1cm4gdGhpcy5hLmdldChcIm1hbmlmZXN0XCIsaCl9LmJpbmQodGhpcykpLnRoZW4oZnVuY3Rpb24oYSl7WSh0aGlzKTtpZighYSl0aHJvdyBuZXcgcSg5LDkwMDMsYyk7Zj1hO2E9WGUoZik7Zz1uZXcgYWIodGhpcy5jLmgsYixmdW5jdGlvbigpe30pO2cuY29uZmlndXJlKHRoaXMuYy5nZXRDb25maWd1cmF0aW9uKCkuZHJtKTtyZXR1cm4gZy5pbml0KGEsITApfS5iaW5kKHRoaXMpKS50aGVuKGZ1bmN0aW9uKCl7cmV0dXJuIGZiKGcsZi5zZXNzaW9uSWRzKX0uYmluZCh0aGlzKSkudGhlbihmdW5jdGlvbigpe3JldHVybiBnLm8oKX0uYmluZCh0aGlzKSkudGhlbihmdW5jdGlvbigpe1kodGhpcyk7XG5pZihlKXRocm93IGU7dmFyIGI9Zi5wZXJpb2RzLm1hcChmdW5jdGlvbihhKXtyZXR1cm4gYS5zdHJlYW1zLm1hcChmdW5jdGlvbihhKXt2YXIgYj1hLnNlZ21lbnRzLm1hcChmdW5jdGlvbihhKXtyZXR1cm4gTnVtYmVyKC9eb2ZmbGluZTpbMC05XStcXC9bMC05XStcXC8oWzAtOV0rKSQvLmV4ZWMoYS51cmkpWzFdKX0pO2EuaW5pdFNlZ21lbnRVcmkmJmIucHVzaChOdW1iZXIoL15vZmZsaW5lOlswLTldK1xcL1swLTldK1xcLyhbMC05XSspJC8uZXhlYyhhLmluaXRTZWdtZW50VXJpKVsxXSkpO3JldHVybiBifSkucmVkdWNlKHUsW10pfSkucmVkdWNlKHUsW10pLGM9MCxkPWIubGVuZ3RoLGc9dGhpcy5qLnByb2dyZXNzQ2FsbGJhY2s7cmV0dXJuIFRlKHRoaXMuYSxmdW5jdGlvbihlKXtlPWIuaW5kZXhPZihlLmtleSk7MDw9ZSYmKGcoYSxjL2QpLGMrKyk7cmV0dXJuIDA8PWV9LmJpbmQodGhpcykpfS5iaW5kKHRoaXMpKS50aGVuKGZ1bmN0aW9uKCl7WSh0aGlzKTt0aGlzLmoucHJvZ3Jlc3NDYWxsYmFjayhhLFxuMSk7cmV0dXJuIHRoaXMuYS5yZW1vdmUoXCJtYW5pZmVzdFwiLGgpfS5iaW5kKHRoaXMpKX07WC5wcm90b3R5cGUucmVtb3ZlPVgucHJvdG90eXBlLnJlbW92ZTtYLnByb3RvdHlwZS5saXN0PWZ1bmN0aW9uKCl7dmFyIGE9W107cmV0dXJuIGRmKHRoaXMpLnRoZW4oZnVuY3Rpb24oKXtZKHRoaXMpO3JldHVybiB0aGlzLmEuZm9yRWFjaChcIm1hbmlmZXN0XCIsZnVuY3Rpb24oYil7YS5wdXNoKFZlKGIpKX0pfS5iaW5kKHRoaXMpKS50aGVuKGZ1bmN0aW9uKCl7cmV0dXJuIGF9KX07WC5wcm90b3R5cGUubGlzdD1YLnByb3RvdHlwZS5saXN0O1xuZnVuY3Rpb24gZWYoYSxiLGMsZCl7ZnVuY3Rpb24gZSgpe312YXIgZj1hLmMuaCxnPWEuYy5nZXRDb25maWd1cmF0aW9uKCksaCxsLG47cmV0dXJuIHViKGIsZixnLm1hbmlmZXN0LnJldHJ5UGFyYW1ldGVycyxkKS50aGVuKGZ1bmN0aW9uKGEpe1kodGhpcyk7bj1uZXcgYTtuLmNvbmZpZ3VyZShnLm1hbmlmZXN0KTtyZXR1cm4gbi5zdGFydChiLGYsdGhpcy5zLmJpbmQodGhpcyksYyl9LmJpbmQoYSkpLnRoZW4oZnVuY3Rpb24oYSl7WSh0aGlzKTtoPWE7bD1uZXcgYWIoZixjLGUpO2wuY29uZmlndXJlKGcuZHJtKTtyZXR1cm4gbC5pbml0KGgsITApfS5iaW5kKGEpKS50aGVuKGZ1bmN0aW9uKCl7WSh0aGlzKTtyZXR1cm4gZ2YoaCl9LmJpbmQoYSkpLnRoZW4oZnVuY3Rpb24oKXtZKHRoaXMpO3JldHVybiBlYihsKX0uYmluZChhKSkudGhlbihmdW5jdGlvbigpe1kodGhpcyk7cmV0dXJuIG4uc3RvcCgpfS5iaW5kKGEpKS50aGVuKGZ1bmN0aW9uKCl7WSh0aGlzKTtyZXR1cm57bWFuaWZlc3Q6aCxcblBiOmx9fS5iaW5kKGEpKVtcImNhdGNoXCJdKGZ1bmN0aW9uKGEpe2lmKG4pcmV0dXJuIG4uc3RvcCgpLnRoZW4oZnVuY3Rpb24oKXt0aHJvdyBhO30pO3Rocm93IGE7fSl9XG5YLnByb3RvdHlwZS5BPWZ1bmN0aW9uKGEpe3ZhciBiPVtdLGM9YS5maWx0ZXIoZnVuY3Rpb24oYSl7cmV0dXJuXCJ2aWRlb1wiPT1hLnR5cGUmJjQ4MD49YS5oZWlnaHR9KTtjLnNvcnQoZnVuY3Rpb24oYSxiKXtyZXR1cm4gYi5iYW5kd2lkdGgtYS5iYW5kd2lkdGh9KTtjLmxlbmd0aCYmYi5wdXNoKGNbMF0pO2Zvcih2YXIgZD1HYyh0aGlzLmMuZ2V0Q29uZmlndXJhdGlvbigpLnByZWZlcnJlZEF1ZGlvTGFuZ3VhZ2UpLGM9WzAsRWMsRmNdLGU9YS5maWx0ZXIoZnVuY3Rpb24oYSl7cmV0dXJuXCJhdWRpb1wiPT1hLnR5cGV9KSxjPWMubWFwKGZ1bmN0aW9uKGEpe3JldHVybiBlLmZpbHRlcihmdW5jdGlvbihiKXtiPUdjKGIubGFuZ3VhZ2UpO3JldHVybiBEYyhhLGQsYil9KX0pLGY9ZSxnPTA7ZzxjLmxlbmd0aDtnKyspY1tnXS5sZW5ndGgmJihmPWNbZ10pO2Yuc29ydChmdW5jdGlvbihhLGIpe3JldHVybiBhLmJhbmR3aWR0aC1iLmJhbmR3aWR0aH0pO2YubGVuZ3RoJiZiLnB1c2goZltNYXRoLmZsb29yKGYubGVuZ3RoL1xuMildKTt2YXIgYz1HYyh0aGlzLmMuZ2V0Q29uZmlndXJhdGlvbigpLnByZWZlcnJlZFRleHRMYW5ndWFnZSksaD1EYy5iaW5kKG51bGwsRmMsYyk7Yi5wdXNoLmFwcGx5KGIsYS5maWx0ZXIoZnVuY3Rpb24oYSl7dmFyIGI9R2MoYS5sYW5ndWFnZSk7cmV0dXJuXCJ0ZXh0XCI9PWEudHlwZSYmaChiKX0pKTtyZXR1cm4gYn07ZnVuY3Rpb24gYmYoYSl7cmV0dXJue3RyYWNrU2VsZWN0aW9uQ2FsbGJhY2s6YS5BLmJpbmQoYSkscHJvZ3Jlc3NDYWxsYmFjazpmdW5jdGlvbihhLGMpe2lmKGF8fGMpcmV0dXJuIG51bGx9fX1mdW5jdGlvbiBkZihhKXtyZXR1cm4gYS5hLmE/UHJvbWlzZS5yZXNvbHZlKCk6YS5hLmluaXQoVWUpfVxuWC5wcm90b3R5cGUucz1mdW5jdGlvbihhKXtmdW5jdGlvbiBiKGEsYixjKXtiPWIuZmlsdGVyKGZ1bmN0aW9uKGEpe3JldHVybiBhLnR5cGU9PWN9KTtyZXR1cm4gMD09Yi5sZW5ndGg/bnVsbDpMYyhhLGJbMF0pLnN0cmVhbX12YXIgYz17fTt0aGlzLmkmJihjPXt2aWRlbzpiKHRoaXMuYi5wZXJpb2RzWzBdLHRoaXMuaSxcInZpZGVvXCIpLGF1ZGlvOmIodGhpcy5iLnBlcmlvZHNbMF0sdGhpcy5pLFwiYXVkaW9cIil9KTtKYyh0aGlzLmcsYyxhKTtJYyhhLHRoaXMuYy5nZXRDb25maWd1cmF0aW9uKCkucmVzdHJpY3Rpb25zLHt3aWR0aDpJbmZpbml0eSxoZWlnaHQ6SW5maW5pdHl9KX07ZnVuY3Rpb24gZmYoYSl7dmFyIGI9YS5nP2EuZy5vKCk6UHJvbWlzZS5yZXNvbHZlKCk7YS5nPW51bGw7YS5iPW51bGw7YS52PSExO2EuaT1udWxsO2EubD1bXTthLmY9LTE7cmV0dXJuIGJ9XG5mdW5jdGlvbiBnZihhKXthPWEucGVyaW9kcy5tYXAoZnVuY3Rpb24oYSl7cmV0dXJuIGEuc3RyZWFtU2V0c30pLnJlZHVjZSh1LFtdKS5tYXAoZnVuY3Rpb24oYSl7cmV0dXJuIGEuc3RyZWFtc30pLnJlZHVjZSh1LFtdKTtyZXR1cm4gUHJvbWlzZS5hbGwoYS5tYXAoZnVuY3Rpb24oYSl7cmV0dXJuIGEuY3JlYXRlU2VnbWVudEluZGV4KCl9KSl9XG5YLnByb3RvdHlwZS53PWZ1bmN0aW9uKGEpe3ZhciBiPUtjKGEsbnVsbCksYj10aGlzLmoudHJhY2tTZWxlY3Rpb25DYWxsYmFjayhiKTt0aGlzLml8fCh0aGlzLmk9Yix0aGlzLmIucGVyaW9kcy5mb3JFYWNoKHRoaXMucy5iaW5kKHRoaXMpKSk7Zm9yKHZhciBjPWIubGVuZ3RoLTE7MDxjOy0tYyl7Zm9yKHZhciBkPSExLGU9Yy0xOzA8PWU7LS1lKWlmKGJbY10udHlwZT09YltlXS50eXBlJiZiW2NdLmtpbmQ9PWJbZV0ua2luZCYmYltjXS5sYW5ndWFnZT09YltlXS5sYW5ndWFnZSl7ZD0hMDticmVha31pZihkKWJyZWFrfWI9Yi5tYXAoZnVuY3Rpb24oYil7Yj1MYyhhLGIpO3JldHVybiBoZih0aGlzLGEsYi5VYyxiLnN0cmVhbSl9LmJpbmQodGhpcykpO3JldHVybntzdGFydFRpbWU6YS5zdGFydFRpbWUsc3RyZWFtczpifX07XG5mdW5jdGlvbiBoZihhLGIsYyxkKXtmb3IodmFyIGU9W10sZj1hLmIucHJlc2VudGF0aW9uVGltZWxpbmUucmEoKSxnPWYsaD1kLmZpbmRTZWdtZW50UG9zaXRpb24oZiksbD1udWxsIT1oP2QuZ2V0U2VnbWVudFJlZmVyZW5jZShoKTpudWxsO2w7KXt2YXIgbj1hLmEuYi5zZWdtZW50Kys7WmUoYS5oLGMudHlwZSxsLChsLmVuZFRpbWUtbC5zdGFydFRpbWUpKmQuYmFuZHdpZHRoLzgsZnVuY3Rpb24oYSxiLGMsZCl7Yj17a2V5OmEsZGF0YTpkLG1hbmlmZXN0S2V5OnRoaXMuZixzdHJlYW1OdW1iZXI6YyxzZWdtZW50TnVtYmVyOmJ9O3RoaXMubC5wdXNoKGEpO3JldHVybiBTZSh0aGlzLmEsXCJzZWdtZW50XCIsYil9LmJpbmQoYSxuLGwucG9zaXRpb24sZC5pZCkpO2UucHVzaCh7c3RhcnRUaW1lOmwuc3RhcnRUaW1lLGVuZFRpbWU6bC5lbmRUaW1lLHVyaTpcIm9mZmxpbmU6XCIrYS5mK1wiL1wiK2QuaWQrXCIvXCIrbn0pO2c9bC5lbmRUaW1lK2Iuc3RhcnRUaW1lO2w9ZC5nZXRTZWdtZW50UmVmZXJlbmNlKCsraCl9YS5tPVxuTWF0aC5tYXgoYS5tLGctZik7Yj1udWxsO2QuaW5pdFNlZ21lbnRSZWZlcmVuY2UmJihuPWEuYS5iLnNlZ21lbnQrKyxiPVwib2ZmbGluZTpcIithLmYrXCIvXCIrZC5pZCtcIi9cIituLFplKGEuaCxjLnR5cGUsZC5pbml0U2VnbWVudFJlZmVyZW5jZSwwLGZ1bmN0aW9uKGEsYil7dmFyIGM9e2tleTpuLGRhdGE6YixtYW5pZmVzdEtleTp0aGlzLmYsc3RyZWFtTnVtYmVyOmEsc2VnbWVudE51bWJlcjotMX07dGhpcy5sLnB1c2gobik7cmV0dXJuIFNlKHRoaXMuYSxcInNlZ21lbnRcIixjKX0uYmluZChhLGQuaWQpKSk7cmV0dXJue2lkOmQuaWQscHJpbWFyeTpjLnByaW1hcnkscHJlc2VudGF0aW9uVGltZU9mZnNldDpkLnByZXNlbnRhdGlvblRpbWVPZmZzZXR8fDAsY29udGVudFR5cGU6Yy50eXBlLG1pbWVUeXBlOmQubWltZVR5cGUsY29kZWNzOmQuY29kZWNzLGZyYW1lUmF0ZTpkLmZyYW1lUmF0ZSxraW5kOmQua2luZCxsYW5ndWFnZTpjLmxhbmd1YWdlLHdpZHRoOmQud2lkdGh8fG51bGwsaGVpZ2h0OmQuaGVpZ2h0fHxcbm51bGwsaW5pdFNlZ21lbnRVcmk6YixlbmNyeXB0ZWQ6ZC5lbmNyeXB0ZWQsa2V5SWQ6ZC5rZXlJZCxzZWdtZW50czplfX1mdW5jdGlvbiBZKGEpe2lmKCFhLmMpdGhyb3cgbmV3IHEoOSw5MDAyKTt9VGMub2ZmbGluZT1jZjttKFwic2hha2EucG9seWZpbGwuaW5zdGFsbEFsbFwiLGZ1bmN0aW9uKCl7Zm9yKHZhciBhPTA7YTxqZi5sZW5ndGg7KythKWpmW2FdKCl9KTt2YXIgamY9W107ZnVuY3Rpb24ga2YoYSl7amYucHVzaChhKX1tKFwic2hha2EucG9seWZpbGwucmVnaXN0ZXJcIixrZik7ZnVuY3Rpb24gbGYoYSl7dmFyIGI9YS50eXBlLnJlcGxhY2UoL14od2Via2l0fG1venxNUykvLFwiXCIpLnRvTG93ZXJDYXNlKCksYj1uZXcgRXZlbnQoYixhKTthLnRhcmdldC5kaXNwYXRjaEV2ZW50KGIpfVxua2YoZnVuY3Rpb24oKXtpZih3aW5kb3cuRG9jdW1lbnQpe3ZhciBhPUVsZW1lbnQucHJvdG90eXBlO2EucmVxdWVzdEZ1bGxzY3JlZW49YS5yZXF1ZXN0RnVsbHNjcmVlbnx8YS5tb3pSZXF1ZXN0RnVsbFNjcmVlbnx8YS5tc1JlcXVlc3RGdWxsc2NyZWVufHxhLndlYmtpdFJlcXVlc3RGdWxsc2NyZWVuO2E9RG9jdW1lbnQucHJvdG90eXBlO2EuZXhpdEZ1bGxzY3JlZW49YS5leGl0RnVsbHNjcmVlbnx8YS5tb3pDYW5jZWxGdWxsU2NyZWVufHxhLm1zRXhpdEZ1bGxzY3JlZW58fGEud2Via2l0RXhpdEZ1bGxzY3JlZW47XCJmdWxsc2NyZWVuRWxlbWVudFwiaW4gZG9jdW1lbnR8fE9iamVjdC5kZWZpbmVQcm9wZXJ0eShkb2N1bWVudCxcImZ1bGxzY3JlZW5FbGVtZW50XCIse2dldDpmdW5jdGlvbigpe3JldHVybiBkb2N1bWVudC5tb3pGdWxsU2NyZWVuRWxlbWVudHx8ZG9jdW1lbnQubXNGdWxsc2NyZWVuRWxlbWVudHx8ZG9jdW1lbnQud2Via2l0RnVsbHNjcmVlbkVsZW1lbnR9fSk7ZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcIndlYmtpdGZ1bGxzY3JlZW5jaGFuZ2VcIixcbmxmKTtkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwid2Via2l0ZnVsbHNjcmVlbmVycm9yXCIsbGYpO2RvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJtb3pmdWxsc2NyZWVuY2hhbmdlXCIsbGYpO2RvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJtb3pmdWxsc2NyZWVuZXJyb3JcIixsZik7ZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcIk1TRnVsbHNjcmVlbkNoYW5nZVwiLGxmKTtkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwiTVNGdWxsc2NyZWVuRXJyb3JcIixsZil9fSk7ZnVuY3Rpb24gbWYoYSl7dGhpcy5jPVtdO3RoaXMuYj1bXTt0aGlzLmE9W107Zm9yKGE9bmV3IFNkKG5ldyBEYXRhVmlldyhhLmJ1ZmZlcikpO1VkKGEpOyl7dmFyIGI9YWUoMTg4NjYxNDM3NixhKTtpZigtMT09YilicmVhazt2YXIgYz1hLmEtOCxkPVZkKGEpO2lmKDE8ZClTKGEsYi0oYS5hLWMpKTtlbHNle1MoYSwzKTt2YXIgZT1aYShaZChhLDE2KSksZj1bXTtpZigwPGQpZm9yKHZhciBkPVIoYSksZz0wO2c8ZDsrK2cpe3ZhciBoPVphKFpkKGEsMTYpKTtmLnB1c2goaCl9ZD1SKGEpO1MoYSxkKTt0aGlzLmIucHVzaC5hcHBseSh0aGlzLmIsZik7dGhpcy5jLnB1c2goZSk7dGhpcy5hLnB1c2goe3N0YXJ0OmMsZW5kOmEuYS0xfSk7YS5hIT1jK2ImJlMoYSxiLShhLmEtYykpfX19O2Z1bmN0aW9uIG5mKGEsYil7dHJ5e3ZhciBjPW5ldyBvZihhLGIpO3JldHVybiBQcm9taXNlLnJlc29sdmUoYyl9Y2F0Y2goZCl7cmV0dXJuIFByb21pc2UucmVqZWN0KGQpfX1cbmZ1bmN0aW9uIG9mKGEsYil7dGhpcy5rZXlTeXN0ZW09YTtmb3IodmFyIGM9ITEsZD0wO2Q8Yi5sZW5ndGg7KytkKXt2YXIgZT1iW2RdLGY9e2F1ZGlvQ2FwYWJpbGl0aWVzOltdLHZpZGVvQ2FwYWJpbGl0aWVzOltdLHBlcnNpc3RlbnRTdGF0ZTpcIm9wdGlvbmFsXCIsZGlzdGluY3RpdmVJZGVudGlmaWVyOlwib3B0aW9uYWxcIixpbml0RGF0YVR5cGVzOmUuaW5pdERhdGFUeXBlcyxzZXNzaW9uVHlwZXM6W1widGVtcG9yYXJ5XCJdLGxhYmVsOmUubGFiZWx9LGc9ITE7aWYoZS5hdWRpb0NhcGFiaWxpdGllcylmb3IodmFyIGg9MDtoPGUuYXVkaW9DYXBhYmlsaXRpZXMubGVuZ3RoOysraCl7dmFyIGw9ZS5hdWRpb0NhcGFiaWxpdGllc1toXTtpZihsLmNvbnRlbnRUeXBlKXt2YXIgZz0hMCxuPWwuY29udGVudFR5cGUuc3BsaXQoXCI7XCIpWzBdO01TTWVkaWFLZXlzLmlzVHlwZVN1cHBvcnRlZCh0aGlzLmtleVN5c3RlbSxuKSYmKGYuYXVkaW9DYXBhYmlsaXRpZXMucHVzaChsKSxjPSEwKX19aWYoZS52aWRlb0NhcGFiaWxpdGllcylmb3IoaD1cbjA7aDxlLnZpZGVvQ2FwYWJpbGl0aWVzLmxlbmd0aDsrK2gpbD1lLnZpZGVvQ2FwYWJpbGl0aWVzW2hdLGwuY29udGVudFR5cGUmJihnPSEwLG49bC5jb250ZW50VHlwZS5zcGxpdChcIjtcIilbMF0sTVNNZWRpYUtleXMuaXNUeXBlU3VwcG9ydGVkKHRoaXMua2V5U3lzdGVtLG4pJiYoZi52aWRlb0NhcGFiaWxpdGllcy5wdXNoKGwpLGM9ITApKTtnfHwoYz1NU01lZGlhS2V5cy5pc1R5cGVTdXBwb3J0ZWQodGhpcy5rZXlTeXN0ZW0sXCJ2aWRlby9tcDRcIikpO1wicmVxdWlyZWRcIj09ZS5wZXJzaXN0ZW50U3RhdGUmJihmLnBlcnNpc3RlbnRTdGF0ZT1cInJlcXVpcmVkXCIsZi5zZXNzaW9uVHlwZXM9W1wicGVyc2lzdGVudC1saWNlbnNlXCJdKTtpZihjKXt0aGlzLmE9ZjtyZXR1cm59fWM9RXJyb3IoXCJVbnN1cHBvcnRlZCBrZXlTeXN0ZW1cIik7Yy5uYW1lPVwiTm90U3VwcG9ydGVkRXJyb3JcIjtjLmNvZGU9RE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSO3Rocm93IGM7fVxub2YucHJvdG90eXBlLmNyZWF0ZU1lZGlhS2V5cz1mdW5jdGlvbigpe3ZhciBhPW5ldyBwZih0aGlzLmtleVN5c3RlbSk7cmV0dXJuIFByb21pc2UucmVzb2x2ZShhKX07b2YucHJvdG90eXBlLmdldENvbmZpZ3VyYXRpb249ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5hfTtmdW5jdGlvbiBxZihhKXt2YXIgYj10aGlzLm1lZGlhS2V5cztiJiZiIT1hJiZyZihiLG51bGwpO2RlbGV0ZSB0aGlzLm1lZGlhS2V5cztyZXR1cm4odGhpcy5tZWRpYUtleXM9YSk/cmYoYSx0aGlzKTpQcm9taXNlLnJlc29sdmUoKX1mdW5jdGlvbiBwZihhKXt0aGlzLmE9bmV3IE1TTWVkaWFLZXlzKGEpO3RoaXMuYj1uZXcgen1wZi5wcm90b3R5cGUuY3JlYXRlU2Vzc2lvbj1mdW5jdGlvbihhKXtpZihcInRlbXBvcmFyeVwiIT0oYXx8XCJ0ZW1wb3JhcnlcIikpdGhyb3cgbmV3IFR5cGVFcnJvcihcIlNlc3Npb24gdHlwZSBcIithK1wiIGlzIHVuc3VwcG9ydGVkIG9uIHRoaXMgcGxhdGZvcm0uXCIpO3JldHVybiBuZXcgc2YodGhpcy5hKX07XG5wZi5wcm90b3R5cGUuc2V0U2VydmVyQ2VydGlmaWNhdGU9ZnVuY3Rpb24oKXtyZXR1cm4gUHJvbWlzZS5yZWplY3QoRXJyb3IoXCJzZXRTZXJ2ZXJDZXJ0aWZpY2F0ZSBub3Qgc3VwcG9ydGVkIG9uIHRoaXMgcGxhdGZvcm0uXCIpKX07ZnVuY3Rpb24gcmYoYSxiKXtmdW5jdGlvbiBjKCl7Yi5tc1NldE1lZGlhS2V5cyhkLmEpO2IucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImxvYWRlZG1ldGFkYXRhXCIsYyl9S2EoYS5iKTtpZighYilyZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7QihhLmIsYixcIm1zbmVlZGtleVwiLHRmKTt2YXIgZD1hO3RyeXtyZXR1cm4gMTw9Yi5yZWFkeVN0YXRlP2IubXNTZXRNZWRpYUtleXMoYS5hKTpiLmFkZEV2ZW50TGlzdGVuZXIoXCJsb2FkZWRtZXRhZGF0YVwiLGMpLFByb21pc2UucmVzb2x2ZSgpfWNhdGNoKGUpe3JldHVybiBQcm9taXNlLnJlamVjdChlKX19XG5mdW5jdGlvbiBzZihhKXtwLmNhbGwodGhpcyk7dGhpcy5jPW51bGw7dGhpcy5nPWE7dGhpcy5iPXRoaXMuYT1udWxsO3RoaXMuZj1uZXcgejt0aGlzLnNlc3Npb25JZD1cIlwiO3RoaXMuZXhwaXJhdGlvbj1OYU47dGhpcy5jbG9zZWQ9bmV3IHc7dGhpcy5rZXlTdGF0dXNlcz1uZXcgdWZ9YmEoc2YpO2s9c2YucHJvdG90eXBlO2suZ2VuZXJhdGVSZXF1ZXN0PWZ1bmN0aW9uKGEsYil7dGhpcy5hPW5ldyB3O3RyeXt0aGlzLmM9dGhpcy5nLmNyZWF0ZVNlc3Npb24oXCJ2aWRlby9tcDRcIixuZXcgVWludDhBcnJheShiKSxudWxsKSxCKHRoaXMuZix0aGlzLmMsXCJtc2tleW1lc3NhZ2VcIix0aGlzLmhjLmJpbmQodGhpcykpLEIodGhpcy5mLHRoaXMuYyxcIm1za2V5YWRkZWRcIix0aGlzLmZjLmJpbmQodGhpcykpLEIodGhpcy5mLHRoaXMuYyxcIm1za2V5ZXJyb3JcIix0aGlzLmdjLmJpbmQodGhpcykpLHZmKHRoaXMsXCJzdGF0dXMtcGVuZGluZ1wiKX1jYXRjaChjKXt0aGlzLmEucmVqZWN0KGMpfXJldHVybiB0aGlzLmF9O1xuay5sb2FkPWZ1bmN0aW9uKCl7cmV0dXJuIFByb21pc2UucmVqZWN0KEVycm9yKFwiTWVkaWFLZXlTZXNzaW9uLmxvYWQgbm90IHlldCBzdXBwb3J0ZWRcIikpfTtrLnVwZGF0ZT1mdW5jdGlvbihhKXt0aGlzLmI9bmV3IHc7dHJ5e3RoaXMuYy51cGRhdGUobmV3IFVpbnQ4QXJyYXkoYSkpfWNhdGNoKGIpe3RoaXMuYi5yZWplY3QoYil9cmV0dXJuIHRoaXMuYn07ay5jbG9zZT1mdW5jdGlvbigpe3RyeXt0aGlzLmMuY2xvc2UoKSx0aGlzLmNsb3NlZC5yZXNvbHZlKCksS2EodGhpcy5mKX1jYXRjaChhKXt0aGlzLmNsb3NlZC5yZWplY3QoYSl9cmV0dXJuIHRoaXMuY2xvc2VkfTtrLnJlbW92ZT1mdW5jdGlvbigpe3JldHVybiBQcm9taXNlLnJlamVjdChFcnJvcihcIk1lZGlhS2V5U2Vzc2lvbi5yZW1vdmUgaXMgb25seSBhcHBsaWNhYmxlIGZvciBwZXJzaXN0ZW50IGxpY2Vuc2VzLCB3aGljaCBhcmUgbm90IHN1cHBvcnRlZCBvbiB0aGlzIHBsYXRmb3JtXCIpKX07XG5mdW5jdGlvbiB0ZihhKXt2YXIgYj1kb2N1bWVudC5jcmVhdGVFdmVudChcIkN1c3RvbUV2ZW50XCIpO2IuaW5pdEN1c3RvbUV2ZW50KFwiZW5jcnlwdGVkXCIsITEsITEsbnVsbCk7Yi5pbml0RGF0YVR5cGU9XCJjZW5jXCI7aWYoYT1hLmluaXREYXRhKXt2YXIgYz1uZXcgbWYoYSk7aWYoISgxPj1jLmEubGVuZ3RoKSl7Zm9yKHZhciBkPVtdLGU9MDtlPGMuYS5sZW5ndGg7ZSsrKWQucHVzaChhLnN1YmFycmF5KGMuYVtlXS5zdGFydCxjLmFbZV0uZW5kKzEpKTtlPXdmO2E9W107Zm9yKGM9MDtjPGQubGVuZ3RoOysrYyl7Zm9yKHZhciBmPSExLGc9MDtnPGEubGVuZ3RoJiYhKGY9ZT9lKGRbY10sYVtnXSk6ZFtjXT09PWFbZ10pOysrZyk7Znx8YS5wdXNoKGRbY10pfWZvcihlPWQ9MDtlPGEubGVuZ3RoO2UrKylkKz1hW2VdLmxlbmd0aDtkPW5ldyBVaW50OEFycmF5KGQpO2ZvcihlPWM9MDtlPGEubGVuZ3RoO2UrKylkLnNldChhW2VdLGMpLGMrPWFbZV0ubGVuZ3RoO2E9ZH19Yi5pbml0RGF0YT1cbmE7dGhpcy5kaXNwYXRjaEV2ZW50KGIpfWZ1bmN0aW9uIHdmKGEsYil7cmV0dXJuICRhKGEsYil9ay5oYz1mdW5jdGlvbihhKXt0aGlzLmEmJih0aGlzLmEucmVzb2x2ZSgpLHRoaXMuYT1udWxsKTt0aGlzLmRpc3BhdGNoRXZlbnQobmV3IEgoXCJtZXNzYWdlXCIse21lc3NhZ2VUeXBlOnZvaWQgMD09dGhpcy5rZXlTdGF0dXNlcy5TYSgpP1wibGljZW5zZXJlcXVlc3RcIjpcImxpY2Vuc2VyZW5ld2FsXCIsbWVzc2FnZTphLm1lc3NhZ2UuYnVmZmVyfSkpfTtrLmZjPWZ1bmN0aW9uKCl7dGhpcy5hPyh2Zih0aGlzLFwidXNhYmxlXCIpLHRoaXMuYS5yZXNvbHZlKCksdGhpcy5hPW51bGwpOnRoaXMuYiYmKHZmKHRoaXMsXCJ1c2FibGVcIiksdGhpcy5iLnJlc29sdmUoKSx0aGlzLmI9bnVsbCl9O1xuay5nYz1mdW5jdGlvbigpe3ZhciBhPUVycm9yKFwiRU1FIFBhdGNoZWRNZWRpYUtleXNNcyBrZXkgZXJyb3JcIik7YS5lcnJvckNvZGU9dGhpcy5jLmVycm9yO2lmKHRoaXMuYSl0aGlzLmEucmVqZWN0KGEpLHRoaXMuYT1udWxsO2Vsc2UgaWYodGhpcy5iKXRoaXMuYi5yZWplY3QoYSksdGhpcy5iPW51bGw7ZWxzZSBzd2l0Y2godGhpcy5jLmVycm9yLmNvZGUpe2Nhc2UgTVNNZWRpYUtleUVycm9yLk1TX01FRElBX0tFWUVSUl9PVVRQVVQ6Y2FzZSBNU01lZGlhS2V5RXJyb3IuTVNfTUVESUFfS0VZRVJSX0hBUkRXQVJFQ0hBTkdFOnZmKHRoaXMsXCJvdXRwdXQtbm90LWFsbG93ZWRcIik7ZGVmYXVsdDp2Zih0aGlzLFwiaW50ZXJuYWwtZXJyb3JcIil9fTtmdW5jdGlvbiB2ZihhLGIpe2Eua2V5U3RhdHVzZXMuYWIoYik7YS5kaXNwYXRjaEV2ZW50KG5ldyBIKFwia2V5c3RhdHVzZXNjaGFuZ2VcIikpfWZ1bmN0aW9uIHVmKCl7dGhpcy5zaXplPTA7dGhpcy5hPXZvaWQgMH12YXIgeGY7az11Zi5wcm90b3R5cGU7XG5rLmFiPWZ1bmN0aW9uKGEpe3RoaXMuc2l6ZT12b2lkIDA9PWE/MDoxO3RoaXMuYT1hfTtrLlNhPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYX07ay5mb3JFYWNoPWZ1bmN0aW9uKGEpe3RoaXMuYSYmYSh0aGlzLmEseGYpfTtrLmdldD1mdW5jdGlvbihhKXtpZih0aGlzLmhhcyhhKSlyZXR1cm4gdGhpcy5hfTtrLmhhcz1mdW5jdGlvbihhKXt2YXIgYj14ZjtyZXR1cm4gdGhpcy5hJiYkYShuZXcgVWludDhBcnJheShhKSxuZXcgVWludDhBcnJheShiKSk/ITA6ITF9O2sua2V5cz1mdW5jdGlvbigpe307ZnVuY3Rpb24geWYoKXtyZXR1cm4gUHJvbWlzZS5yZWplY3QoRXJyb3IoXCJUaGUga2V5IHN5c3RlbSBzcGVjaWZpZWQgaXMgbm90IHN1cHBvcnRlZC5cIikpfWZ1bmN0aW9uIHpmKGEpe3JldHVybiBhP1Byb21pc2UucmVqZWN0KEVycm9yKFwiTWVkaWFLZXlzIG5vdCBzdXBwb3J0ZWQuXCIpKTpQcm9taXNlLnJlc29sdmUoKX1mdW5jdGlvbiBBZigpe3Rocm93IG5ldyBUeXBlRXJyb3IoXCJJbGxlZ2FsIGNvbnN0cnVjdG9yLlwiKTt9QWYucHJvdG90eXBlLmNyZWF0ZVNlc3Npb249ZnVuY3Rpb24oKXt9O0FmLnByb3RvdHlwZS5zZXRTZXJ2ZXJDZXJ0aWZpY2F0ZT1mdW5jdGlvbigpe307ZnVuY3Rpb24gQmYoKXt0aHJvdyBuZXcgVHlwZUVycm9yKFwiSWxsZWdhbCBjb25zdHJ1Y3Rvci5cIik7fUJmLnByb3RvdHlwZS5nZXRDb25maWd1cmF0aW9uPWZ1bmN0aW9uKCl7fTtCZi5wcm90b3R5cGUuY3JlYXRlTWVkaWFLZXlzPWZ1bmN0aW9uKCl7fTtmdW5jdGlvbiBDZihhLGIpe3RyeXt2YXIgYz1uZXcgRGYoYSxiKTtyZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGMpfWNhdGNoKGQpe3JldHVybiBQcm9taXNlLnJlamVjdChkKX19ZnVuY3Rpb24gRWYoYSl7dmFyIGI9dGhpcy5tZWRpYUtleXM7YiYmYiE9YSYmRmYoYixudWxsKTtkZWxldGUgdGhpcy5tZWRpYUtleXM7KHRoaXMubWVkaWFLZXlzPWEpJiZGZihhLHRoaXMpO3JldHVybiBQcm9taXNlLnJlc29sdmUoKX1cbmZ1bmN0aW9uIERmKGEsYil7dGhpcy5hPXRoaXMua2V5U3lzdGVtPWE7dmFyIGM9ITA7XCJvcmcudzMuY2xlYXJrZXlcIj09YSYmKHRoaXMuYT1cIndlYmtpdC1vcmcudzMuY2xlYXJrZXlcIixjPSExKTt2YXIgZD0hMSxlO2U9ZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJ2aWRlb1wiKTtlPWUubGVuZ3RoP2VbMF06ZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInZpZGVvXCIpO2Zvcih2YXIgZj0wO2Y8Yi5sZW5ndGg7KytmKXt2YXIgZz1iW2ZdLGg9e2F1ZGlvQ2FwYWJpbGl0aWVzOltdLHZpZGVvQ2FwYWJpbGl0aWVzOltdLHBlcnNpc3RlbnRTdGF0ZTpcIm9wdGlvbmFsXCIsZGlzdGluY3RpdmVJZGVudGlmaWVyOlwib3B0aW9uYWxcIixpbml0RGF0YVR5cGVzOmcuaW5pdERhdGFUeXBlcyxzZXNzaW9uVHlwZXM6W1widGVtcG9yYXJ5XCJdLGxhYmVsOmcubGFiZWx9LGw9ITE7aWYoZy5hdWRpb0NhcGFiaWxpdGllcylmb3IodmFyIG49MDtuPGcuYXVkaW9DYXBhYmlsaXRpZXMubGVuZ3RoOysrbil7dmFyIHI9XG5nLmF1ZGlvQ2FwYWJpbGl0aWVzW25dO3IuY29udGVudFR5cGUmJihsPSEwLGUuY2FuUGxheVR5cGUoci5jb250ZW50VHlwZS5zcGxpdChcIjtcIilbMF0sdGhpcy5hKSYmKGguYXVkaW9DYXBhYmlsaXRpZXMucHVzaChyKSxkPSEwKSl9aWYoZy52aWRlb0NhcGFiaWxpdGllcylmb3Iobj0wO248Zy52aWRlb0NhcGFiaWxpdGllcy5sZW5ndGg7KytuKXI9Zy52aWRlb0NhcGFiaWxpdGllc1tuXSxyLmNvbnRlbnRUeXBlJiYobD0hMCxlLmNhblBsYXlUeXBlKHIuY29udGVudFR5cGUsdGhpcy5hKSYmKGgudmlkZW9DYXBhYmlsaXRpZXMucHVzaChyKSxkPSEwKSk7bHx8KGQ9ZS5jYW5QbGF5VHlwZShcInZpZGVvL21wNFwiLHRoaXMuYSl8fGUuY2FuUGxheVR5cGUoXCJ2aWRlby93ZWJtXCIsdGhpcy5hKSk7XCJyZXF1aXJlZFwiPT1nLnBlcnNpc3RlbnRTdGF0ZSYmKGM/KGgucGVyc2lzdGVudFN0YXRlPVwicmVxdWlyZWRcIixoLnNlc3Npb25UeXBlcz1bXCJwZXJzaXN0ZW50LWxpY2Vuc2VcIl0pOmQ9ITEpO2lmKGQpe3RoaXMuYj1cbmg7cmV0dXJufX1jPVwiVW5zdXBwb3J0ZWQga2V5U3lzdGVtXCI7aWYoXCJvcmcudzMuY2xlYXJrZXlcIj09YXx8XCJjb20ud2lkZXZpbmUuYWxwaGFcIj09YSljPVwiTm9uZSBvZiB0aGUgcmVxdWVzdGVkIGNvbmZpZ3VyYXRpb25zIHdlcmUgc3VwcG9ydGVkLlwiO2M9RXJyb3IoYyk7Yy5uYW1lPVwiTm90U3VwcG9ydGVkRXJyb3JcIjtjLmNvZGU9RE9NRXhjZXB0aW9uLk5PVF9TVVBQT1JURURfRVJSO3Rocm93IGM7fURmLnByb3RvdHlwZS5jcmVhdGVNZWRpYUtleXM9ZnVuY3Rpb24oKXt2YXIgYT1uZXcgR2YodGhpcy5hKTtyZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGEpfTtEZi5wcm90b3R5cGUuZ2V0Q29uZmlndXJhdGlvbj1mdW5jdGlvbigpe3JldHVybiB0aGlzLmJ9O2Z1bmN0aW9uIEdmKGEpe3RoaXMuZz1hO3RoaXMuYj1udWxsO3RoaXMuYT1uZXcgejt0aGlzLmM9W107dGhpcy5mPXt9fVxuZnVuY3Rpb24gRmYoYSxiKXthLmI9YjtLYShhLmEpO2ImJihCKGEuYSxiLFwid2Via2l0bmVlZGtleVwiLGEucWMuYmluZChhKSksQihhLmEsYixcIndlYmtpdGtleW1lc3NhZ2VcIixhLnBjLmJpbmQoYSkpLEIoYS5hLGIsXCJ3ZWJraXRrZXlhZGRlZFwiLGEubmMuYmluZChhKSksQihhLmEsYixcIndlYmtpdGtleWVycm9yXCIsYS5vYy5iaW5kKGEpKSl9az1HZi5wcm90b3R5cGU7ay5jcmVhdGVTZXNzaW9uPWZ1bmN0aW9uKGEpe3ZhciBiPWF8fFwidGVtcG9yYXJ5XCI7aWYoXCJ0ZW1wb3JhcnlcIiE9YiYmXCJwZXJzaXN0ZW50LWxpY2Vuc2VcIiE9Yil0aHJvdyBuZXcgVHlwZUVycm9yKFwiU2Vzc2lvbiB0eXBlIFwiK2ErXCIgaXMgdW5zdXBwb3J0ZWQgb24gdGhpcyBwbGF0Zm9ybS5cIik7YT10aGlzLmJ8fGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJ2aWRlb1wiKTthLnNyY3x8KGEuc3JjPVwiYWJvdXQ6YmxhbmtcIik7Yj1uZXcgSGYoYSx0aGlzLmcsYik7dGhpcy5jLnB1c2goYik7cmV0dXJuIGJ9O1xuay5zZXRTZXJ2ZXJDZXJ0aWZpY2F0ZT1mdW5jdGlvbigpe3JldHVybiBQcm9taXNlLnJlamVjdChFcnJvcihcInNldFNlcnZlckNlcnRpZmljYXRlIG5vdCBzdXBwb3J0ZWQgb24gdGhpcyBwbGF0Zm9ybS5cIikpfTtrLnFjPWZ1bmN0aW9uKGEpe3RoaXMuYi5kaXNwYXRjaEV2ZW50KG5ldyBIKFwiZW5jcnlwdGVkXCIse2luaXREYXRhVHlwZTpcIndlYm1cIixpbml0RGF0YTphLmluaXREYXRhfSkpfTtrLnBjPWZ1bmN0aW9uKGEpe3ZhciBiPUlmKHRoaXMsYS5zZXNzaW9uSWQpO2ImJihhPW5ldyBIKFwibWVzc2FnZVwiLHttZXNzYWdlVHlwZTp2b2lkIDA9PWIua2V5U3RhdHVzZXMuU2EoKT9cImxpY2Vuc2VyZXF1ZXN0XCI6XCJsaWNlbnNlcmVuZXdhbFwiLG1lc3NhZ2U6YS5tZXNzYWdlfSksYi5iJiYoYi5iLnJlc29sdmUoKSxiLmI9bnVsbCksYi5kaXNwYXRjaEV2ZW50KGEpKX07XG5rLm5jPWZ1bmN0aW9uKGEpe2lmKGE9SWYodGhpcyxhLnNlc3Npb25JZCkpSmYoYSxcInVzYWJsZVwiKSxhLmEmJmEuYS5yZXNvbHZlKCksYS5hPW51bGx9O1xuay5vYz1mdW5jdGlvbihhKXt2YXIgYj1JZih0aGlzLGEuc2Vzc2lvbklkKTtpZihiKXt2YXIgYz1FcnJvcihcIkVNRSB2MC4xYiBrZXkgZXJyb3JcIik7Yy5lcnJvckNvZGU9YS5lcnJvckNvZGU7Yy5lcnJvckNvZGUuc3lzdGVtQ29kZT1hLnN5c3RlbUNvZGU7IWEuc2Vzc2lvbklkJiZiLmI/KGMubWV0aG9kPVwiZ2VuZXJhdGVSZXF1ZXN0XCIsNDU9PWEuc3lzdGVtQ29kZSYmKGMubWVzc2FnZT1cIlVuc3VwcG9ydGVkIHNlc3Npb24gdHlwZS5cIiksYi5iLnJlamVjdChjKSxiLmI9bnVsbCk6YS5zZXNzaW9uSWQmJmIuYT8oYy5tZXRob2Q9XCJ1cGRhdGVcIixiLmEucmVqZWN0KGMpLGIuYT1udWxsKTooYz1hLnN5c3RlbUNvZGUsYS5lcnJvckNvZGUuY29kZT09TWVkaWFLZXlFcnJvci5NRURJQV9LRVlFUlJfT1VUUFVUP0pmKGIsXCJvdXRwdXQtcmVzdHJpY3RlZFwiKToxPT1jP0pmKGIsXCJleHBpcmVkXCIpOkpmKGIsXCJpbnRlcm5hbC1lcnJvclwiKSl9fTtcbmZ1bmN0aW9uIElmKGEsYil7dmFyIGM9YS5mW2JdO3JldHVybiBjP2M6KGM9YS5jLnNoaWZ0KCkpPyhjLnNlc3Npb25JZD1iLGEuZltiXT1jKTpudWxsfWZ1bmN0aW9uIEhmKGEsYixjKXtwLmNhbGwodGhpcyk7dGhpcy5mPWE7dGhpcy5oPSExO3RoaXMuYT10aGlzLmI9bnVsbDt0aGlzLmM9Yjt0aGlzLmc9Yzt0aGlzLnNlc3Npb25JZD1cIlwiO3RoaXMuZXhwaXJhdGlvbj1OYU47dGhpcy5jbG9zZWQ9bmV3IHc7dGhpcy5rZXlTdGF0dXNlcz1uZXcgS2Z9YmEoSGYpO1xuZnVuY3Rpb24gTGYoYSxiLGMpe2lmKGEuaClyZXR1cm4gUHJvbWlzZS5yZWplY3QoRXJyb3IoXCJUaGUgc2Vzc2lvbiBpcyBhbHJlYWR5IGluaXRpYWxpemVkLlwiKSk7YS5oPSEwO3ZhciBkO3RyeXtpZihcInBlcnNpc3RlbnQtbGljZW5zZVwiPT1hLmcpaWYoYylkPW5ldyBVaW50OEFycmF5KFNhKFwiTE9BRF9TRVNTSU9OfFwiK2MpKTtlbHNle3ZhciBlPVNhKFwiUEVSU0lTVEVOVHxcIiksZj1uZXcgVWludDhBcnJheShlLmJ5dGVMZW5ndGgrYi5ieXRlTGVuZ3RoKTtmLnNldChuZXcgVWludDhBcnJheShlKSwwKTtmLnNldChuZXcgVWludDhBcnJheShiKSxlLmJ5dGVMZW5ndGgpO2Q9Zn1lbHNlIGQ9bmV3IFVpbnQ4QXJyYXkoYil9Y2F0Y2goZyl7cmV0dXJuIFByb21pc2UucmVqZWN0KGcpfWEuYj1uZXcgdzt0cnl7YS5mLndlYmtpdEdlbmVyYXRlS2V5UmVxdWVzdChhLmMsZCl9Y2F0Y2goZyl7aWYoXCJJbnZhbGlkU3RhdGVFcnJvclwiIT1nLm5hbWUpcmV0dXJuIGEuYj1udWxsLFByb21pc2UucmVqZWN0KGcpO1xuc2V0VGltZW91dChmdW5jdGlvbigpe3RyeXt0aGlzLmYud2Via2l0R2VuZXJhdGVLZXlSZXF1ZXN0KHRoaXMuYyxkKX1jYXRjaChhKXt0aGlzLmIucmVqZWN0KGEpLHRoaXMuYj1udWxsfX0uYmluZChhKSwxMCl9cmV0dXJuIGEuYn1rPUhmLnByb3RvdHlwZTtcbmsuY2I9ZnVuY3Rpb24oYSxiKXtpZih0aGlzLmEpdGhpcy5hLnRoZW4odGhpcy5jYi5iaW5kKHRoaXMsYSxiKSlbXCJjYXRjaFwiXSh0aGlzLmNiLmJpbmQodGhpcyxhLGIpKTtlbHNle3RoaXMuYT1hO3ZhciBjLGQ7XCJ3ZWJraXQtb3JnLnczLmNsZWFya2V5XCI9PXRoaXMuYz8oYz1EKGIpLGQ9SlNPTi5wYXJzZShjKSxcIm9jdFwiIT1kLmtleXNbMF0ua3R5JiYodGhpcy5hLnJlamVjdChFcnJvcihcIlJlc3BvbnNlIGlzIG5vdCBhIHZhbGlkIEpTT04gV2ViIEtleSBTZXQuXCIpKSx0aGlzLmE9bnVsbCksYz1YYShkLmtleXNbMF0uayksZD1YYShkLmtleXNbMF0ua2lkKSk6KGM9bmV3IFVpbnQ4QXJyYXkoYiksZD1udWxsKTt0cnl7dGhpcy5mLndlYmtpdEFkZEtleSh0aGlzLmMsYyxkLHRoaXMuc2Vzc2lvbklkKX1jYXRjaChlKXt0aGlzLmEucmVqZWN0KGUpLHRoaXMuYT1udWxsfX19O1xuZnVuY3Rpb24gSmYoYSxiKXthLmtleVN0YXR1c2VzLmFiKGIpO2EuZGlzcGF0Y2hFdmVudChuZXcgSChcImtleXN0YXR1c2VzY2hhbmdlXCIpKX1rLmdlbmVyYXRlUmVxdWVzdD1mdW5jdGlvbihhLGIpe3JldHVybiBMZih0aGlzLGIsbnVsbCl9O2subG9hZD1mdW5jdGlvbihhKXtyZXR1cm5cInBlcnNpc3RlbnQtbGljZW5zZVwiPT10aGlzLmc/TGYodGhpcyxudWxsLGEpOlByb21pc2UucmVqZWN0KEVycm9yKFwiTm90IGEgcGVyc2lzdGVudCBzZXNzaW9uLlwiKSl9O2sudXBkYXRlPWZ1bmN0aW9uKGEpe3ZhciBiPW5ldyB3O3RoaXMuY2IoYixhKTtyZXR1cm4gYn07XG5rLmNsb3NlPWZ1bmN0aW9uKCl7aWYoXCJwZXJzaXN0ZW50LWxpY2Vuc2VcIiE9dGhpcy5nKXtpZighdGhpcy5zZXNzaW9uSWQpcmV0dXJuIHRoaXMuY2xvc2VkLnJlamVjdChFcnJvcihcIlRoZSBzZXNzaW9uIGlzIG5vdCBjYWxsYWJsZS5cIikpLHRoaXMuY2xvc2VkO3RyeXt0aGlzLmYud2Via2l0Q2FuY2VsS2V5UmVxdWVzdCh0aGlzLmMsdGhpcy5zZXNzaW9uSWQpfWNhdGNoKGEpe319dGhpcy5jbG9zZWQucmVzb2x2ZSgpO3JldHVybiB0aGlzLmNsb3NlZH07ay5yZW1vdmU9ZnVuY3Rpb24oKXtyZXR1cm5cInBlcnNpc3RlbnQtbGljZW5zZVwiIT10aGlzLmc/UHJvbWlzZS5yZWplY3QoRXJyb3IoXCJOb3QgYSBwZXJzaXN0ZW50IHNlc3Npb24uXCIpKTp0aGlzLmNsb3NlKCl9O2Z1bmN0aW9uIEtmKCl7dGhpcy5zaXplPTA7dGhpcy5hPXZvaWQgMH12YXIgTWY7az1LZi5wcm90b3R5cGU7ay5hYj1mdW5jdGlvbihhKXt0aGlzLnNpemU9dm9pZCAwPT1hPzA6MTt0aGlzLmE9YX07ay5TYT1mdW5jdGlvbigpe3JldHVybiB0aGlzLmF9O1xuay5mb3JFYWNoPWZ1bmN0aW9uKGEpe3RoaXMuYSYmYSh0aGlzLmEsTWYpfTtrLmdldD1mdW5jdGlvbihhKXtpZih0aGlzLmhhcyhhKSlyZXR1cm4gdGhpcy5hfTtrLmhhcz1mdW5jdGlvbihhKXt2YXIgYj1NZjtyZXR1cm4gdGhpcy5hJiYkYShuZXcgVWludDhBcnJheShhKSxuZXcgVWludDhBcnJheShiKSk/ITA6ITF9O2sua2V5cz1mdW5jdGlvbigpe307a2YoZnVuY3Rpb24oKXshd2luZG93LkhUTUxWaWRlb0VsZW1lbnR8fG5hdmlnYXRvci5yZXF1ZXN0TWVkaWFLZXlTeXN0ZW1BY2Nlc3MmJk1lZGlhS2V5U3lzdGVtQWNjZXNzLnByb3RvdHlwZS5nZXRDb25maWd1cmF0aW9ufHwoSFRNTE1lZGlhRWxlbWVudC5wcm90b3R5cGUud2Via2l0R2VuZXJhdGVLZXlSZXF1ZXN0PyhNZj0obmV3IFVpbnQ4QXJyYXkoWzBdKSkuYnVmZmVyLG5hdmlnYXRvci5yZXF1ZXN0TWVkaWFLZXlTeXN0ZW1BY2Nlc3M9Q2YsZGVsZXRlIEhUTUxNZWRpYUVsZW1lbnQucHJvdG90eXBlLm1lZGlhS2V5cyxIVE1MTWVkaWFFbGVtZW50LnByb3RvdHlwZS5tZWRpYUtleXM9bnVsbCxIVE1MTWVkaWFFbGVtZW50LnByb3RvdHlwZS5zZXRNZWRpYUtleXM9RWYsd2luZG93Lk1lZGlhS2V5cz1HZix3aW5kb3cuTWVkaWFLZXlTeXN0ZW1BY2Nlc3M9RGYpOndpbmRvdy5NU01lZGlhS2V5cz8oeGY9KG5ldyBVaW50OEFycmF5KFswXSkpLmJ1ZmZlcixkZWxldGUgSFRNTE1lZGlhRWxlbWVudC5wcm90b3R5cGUubWVkaWFLZXlzLFxuSFRNTE1lZGlhRWxlbWVudC5wcm90b3R5cGUubWVkaWFLZXlzPW51bGwsSFRNTE1lZGlhRWxlbWVudC5wcm90b3R5cGUuc2V0TWVkaWFLZXlzPXFmLHdpbmRvdy5NZWRpYUtleXM9cGYsd2luZG93Lk1lZGlhS2V5U3lzdGVtQWNjZXNzPW9mLG5hdmlnYXRvci5yZXF1ZXN0TWVkaWFLZXlTeXN0ZW1BY2Nlc3M9bmYpOihuYXZpZ2F0b3IucmVxdWVzdE1lZGlhS2V5U3lzdGVtQWNjZXNzPXlmLGRlbGV0ZSBIVE1MTWVkaWFFbGVtZW50LnByb3RvdHlwZS5tZWRpYUtleXMsSFRNTE1lZGlhRWxlbWVudC5wcm90b3R5cGUubWVkaWFLZXlzPW51bGwsSFRNTE1lZGlhRWxlbWVudC5wcm90b3R5cGUuc2V0TWVkaWFLZXlzPXpmLHdpbmRvdy5NZWRpYUtleXM9QWYsd2luZG93Lk1lZGlhS2V5U3lzdGVtQWNjZXNzPUJmKSl9KTtrZihmdW5jdGlvbigpe2lmKHdpbmRvdy5NZWRpYVNvdXJjZSl7dmFyIGE9bmF2aWdhdG9yLnZlbmRvcixiPW5hdmlnYXRvci5hcHBWZXJzaW9uO2lmKGEmJmImJiEoMD5hLmluZGV4T2YoXCJBcHBsZVwiKSkpaWYoMDw9Yi5pbmRleE9mKFwiVmVyc2lvbi84XCIpKXdpbmRvdy5NZWRpYVNvdXJjZT1udWxsO2Vsc2V7dmFyIGM9TWVkaWFTb3VyY2UucHJvdG90eXBlLmFkZFNvdXJjZUJ1ZmZlcjtNZWRpYVNvdXJjZS5wcm90b3R5cGUuYWRkU291cmNlQnVmZmVyPWZ1bmN0aW9uKCl7dmFyIGE9Yy5hcHBseSh0aGlzLGFyZ3VtZW50cyk7YS5hYm9ydD1mdW5jdGlvbigpe307cmV0dXJuIGF9fX19KTtmdW5jdGlvbiBaKGEpe3RoaXMuYz1bXTt0aGlzLmI9W107dGhpcy5pYT1OZjtpZihhKXRyeXthKHRoaXMuVy5iaW5kKHRoaXMpLHRoaXMuYS5iaW5kKHRoaXMpKX1jYXRjaChiKXt0aGlzLmEoYil9fXZhciBOZj0wO2Z1bmN0aW9uIE9mKGEpe3ZhciBiPW5ldyBaO2IuVyhhKTtyZXR1cm4gYn1mdW5jdGlvbiBQZihhKXt2YXIgYj1uZXcgWjtiLmEoYSk7cmV0dXJuIGJ9ZnVuY3Rpb24gUWYoYSl7ZnVuY3Rpb24gYihhLGIsYyl7YS5pYT09TmYmJihlW2JdPWMsZCsrLGQ9PWUubGVuZ3RoJiZhLlcoZSkpfXZhciBjPW5ldyBaO2lmKCFhLmxlbmd0aClyZXR1cm4gYy5XKFtdKSxjO2Zvcih2YXIgZD0wLGU9QXJyYXkoYS5sZW5ndGgpLGY9Yy5hLmJpbmQoYyksZz0wO2c8YS5sZW5ndGg7KytnKWFbZ10mJmFbZ10udGhlbj9hW2ddLnRoZW4oYi5iaW5kKG51bGwsYyxnKSxmKTpiKGMsZyxhW2ddKTtyZXR1cm4gY31cbmZ1bmN0aW9uIFJmKGEpe2Zvcih2YXIgYj1uZXcgWixjPWIuVy5iaW5kKGIpLGQ9Yi5hLmJpbmQoYiksZT0wO2U8YS5sZW5ndGg7KytlKWFbZV0mJmFbZV0udGhlbj9hW2VdLnRoZW4oYyxkKTpjKGFbZV0pO3JldHVybiBifVoucHJvdG90eXBlLnRoZW49ZnVuY3Rpb24oYSxiKXt2YXIgYz1uZXcgWjtzd2l0Y2godGhpcy5pYSl7Y2FzZSAxOlNmKHRoaXMsYyxhKTticmVhaztjYXNlIDI6U2YodGhpcyxjLGIpO2JyZWFrO2Nhc2UgTmY6dGhpcy5jLnB1c2goe0k6YyxDYTphfSksdGhpcy5iLnB1c2goe0k6YyxDYTpifSl9cmV0dXJuIGN9O1oucHJvdG90eXBlW1wiY2F0Y2hcIl09ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMudGhlbih2b2lkIDAsYSl9O1xuWi5wcm90b3R5cGUuVz1mdW5jdGlvbihhKXtpZih0aGlzLmlhPT1OZil7dGhpcy5NYT1hO3RoaXMuaWE9MTtmb3IoYT0wO2E8dGhpcy5jLmxlbmd0aDsrK2EpU2YodGhpcyx0aGlzLmNbYV0uSSx0aGlzLmNbYV0uQ2EpO3RoaXMuYz1bXTt0aGlzLmI9W119fTtaLnByb3RvdHlwZS5hPWZ1bmN0aW9uKGEpe2lmKHRoaXMuaWE9PU5mKXt0aGlzLk1hPWE7dGhpcy5pYT0yO2ZvcihhPTA7YTx0aGlzLmIubGVuZ3RoOysrYSlTZih0aGlzLHRoaXMuYlthXS5JLHRoaXMuYlthXS5DYSk7dGhpcy5jPVtdO3RoaXMuYj1bXX19O1xuZnVuY3Rpb24gU2YoYSxiLGMpe1RmLnB1c2goZnVuY3Rpb24oKXtpZihjJiZcImZ1bmN0aW9uXCI9PXR5cGVvZiBjKXt0cnl7dmFyIGE9Yyh0aGlzLk1hKX1jYXRjaChmKXtiLmEoZik7cmV0dXJufXZhciBlO3RyeXtlPWEmJmEudGhlbn1jYXRjaChmKXtiLmEoZik7cmV0dXJufWEgaW5zdGFuY2VvZiBaP2E9PWI/Yi5hKG5ldyBUeXBlRXJyb3IoXCJDaGFpbmluZyBjeWNsZSBkZXRlY3RlZFwiKSk6YS50aGVuKGIuVy5iaW5kKGIpLGIuYS5iaW5kKGIpKTplP1VmKGEsZSxiKTpiLlcoYSl9ZWxzZSAxPT10aGlzLmlhP2IuVyh0aGlzLk1hKTpiLmEodGhpcy5NYSl9LmJpbmQoYSkpO251bGw9PVZmJiYoVmY9V2YoWGYpKX1cbmZ1bmN0aW9uIFVmKGEsYixjKXt0cnl7dmFyIGQ9ITE7Yi5jYWxsKGEsZnVuY3Rpb24oYSl7aWYoIWQpe2Q9ITA7dmFyIGI7dHJ5e2I9YSYmYS50aGVufWNhdGNoKGcpe2MuYShnKTtyZXR1cm59Yj9VZihhLGIsYyk6Yy5XKGEpfX0sYy5hLmJpbmQoYykpfWNhdGNoKGUpe2MuYShlKX19ZnVuY3Rpb24gWGYoKXtmb3IoO1RmLmxlbmd0aDspe251bGwhPVZmJiYoWWYoVmYpLFZmPW51bGwpO3ZhciBhPVRmO1RmPVtdO2Zvcih2YXIgYj0wO2I8YS5sZW5ndGg7KytiKWFbYl0oKX19ZnVuY3Rpb24gV2YoKXtyZXR1cm4gMH1mdW5jdGlvbiBZZigpe312YXIgVmY9bnVsbCxUZj1bXTtcbmtmKGZ1bmN0aW9uKGEpe3dpbmRvdy5zZXRJbW1lZGlhdGU/KFdmPWZ1bmN0aW9uKGEpe3JldHVybiB3aW5kb3cuc2V0SW1tZWRpYXRlKGEpfSxZZj1mdW5jdGlvbihhKXtyZXR1cm4gd2luZG93LmNsZWFySW1tZWRpYXRlKGEpfSk6KFdmPWZ1bmN0aW9uKGEpe3JldHVybiB3aW5kb3cuc2V0VGltZW91dChhLDApfSxZZj1mdW5jdGlvbihhKXtyZXR1cm4gd2luZG93LmNsZWFyVGltZW91dChhKX0pO2lmKCF3aW5kb3cuUHJvbWlzZXx8YSl3aW5kb3cuUHJvbWlzZT1aLHdpbmRvdy5Qcm9taXNlLnJlc29sdmU9T2Ysd2luZG93LlByb21pc2UucmVqZWN0PVBmLHdpbmRvdy5Qcm9taXNlLmFsbD1RZix3aW5kb3cuUHJvbWlzZS5yYWNlPVJmLHdpbmRvdy5Qcm9taXNlLnByb3RvdHlwZS50aGVuPVoucHJvdG90eXBlLnRoZW4sd2luZG93LlByb21pc2UucHJvdG90eXBlW1wiY2F0Y2hcIl09Wi5wcm90b3R5cGVbXCJjYXRjaFwiXX0pO2Z1bmN0aW9uIFpmKCl7cmV0dXJue2Ryb3BwZWRWaWRlb0ZyYW1lczp0aGlzLndlYmtpdERyb3BwZWRGcmFtZUNvdW50LHRvdGFsVmlkZW9GcmFtZXM6dGhpcy53ZWJraXREZWNvZGVkRnJhbWVDb3VudCxjb3JydXB0ZWRWaWRlb0ZyYW1lczowLGNyZWF0aW9uVGltZTpOYU4sdG90YWxGcmFtZURlbGF5OjB9fWtmKGZ1bmN0aW9uKCl7aWYod2luZG93LkhUTUxWaWRlb0VsZW1lbnQpe3ZhciBhPUhUTUxWaWRlb0VsZW1lbnQucHJvdG90eXBlOyFhLmdldFZpZGVvUGxheWJhY2tRdWFsaXR5JiZcIndlYmtpdERyb3BwZWRGcmFtZUNvdW50XCJpbiBhJiYoYS5nZXRWaWRlb1BsYXliYWNrUXVhbGl0eT1aZil9fSk7fS5jYWxsKGcsdGhpcykpO1xuaWYgKHR5cGVvZihtb2R1bGUpIT1cInVuZGVmaW5lZFwiJiZtb2R1bGUuZXhwb3J0cyltb2R1bGUuZXhwb3J0cz1nLnNoYWthO1xuZWxzZSBpZiAodHlwZW9mKGRlZmluZSkhPVwidW5kZWZpbmVkXCIgJiYgZGVmaW5lLmFtZClkZWZpbmUoZnVuY3Rpb24oKXtyZXR1cm4gZy5zaGFrYX0pO1xuZWxzZSB0aGlzLnNoYWthPWcuc2hha2E7XG59KSgpO1xuXG4iLCIvLyBzdGF0cy5qcyAtIGh0dHA6Ly9naXRodWIuY29tL21yZG9vYi9zdGF0cy5qc1xudmFyIFN0YXRzPWZ1bmN0aW9uKCl7dmFyIGw9RGF0ZS5ub3coKSxtPWwsZz0wLG49SW5maW5pdHksbz0wLGg9MCxwPUluZmluaXR5LHE9MCxyPTAscz0wLGY9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtmLmlkPVwic3RhdHNcIjtmLmFkZEV2ZW50TGlzdGVuZXIoXCJtb3VzZWRvd25cIixmdW5jdGlvbihiKXtiLnByZXZlbnREZWZhdWx0KCk7dCgrK3MlMil9LCExKTtmLnN0eWxlLmNzc1RleHQ9XCJ3aWR0aDo4MHB4O29wYWNpdHk6MC45O2N1cnNvcjpwb2ludGVyXCI7dmFyIGE9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTthLmlkPVwiZnBzXCI7YS5zdHlsZS5jc3NUZXh0PVwicGFkZGluZzowIDAgM3B4IDNweDt0ZXh0LWFsaWduOmxlZnQ7YmFja2dyb3VuZC1jb2xvcjojMDAyXCI7Zi5hcHBlbmRDaGlsZChhKTt2YXIgaT1kb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO2kuaWQ9XCJmcHNUZXh0XCI7aS5zdHlsZS5jc3NUZXh0PVwiY29sb3I6IzBmZjtmb250LWZhbWlseTpIZWx2ZXRpY2EsQXJpYWwsc2Fucy1zZXJpZjtmb250LXNpemU6OXB4O2ZvbnQtd2VpZ2h0OmJvbGQ7bGluZS1oZWlnaHQ6MTVweFwiO1xuaS5pbm5lckhUTUw9XCJGUFNcIjthLmFwcGVuZENoaWxkKGkpO3ZhciBjPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7Yy5pZD1cImZwc0dyYXBoXCI7Yy5zdHlsZS5jc3NUZXh0PVwicG9zaXRpb246cmVsYXRpdmU7d2lkdGg6NzRweDtoZWlnaHQ6MzBweDtiYWNrZ3JvdW5kLWNvbG9yOiMwZmZcIjtmb3IoYS5hcHBlbmRDaGlsZChjKTs3ND5jLmNoaWxkcmVuLmxlbmd0aDspe3ZhciBqPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJzcGFuXCIpO2ouc3R5bGUuY3NzVGV4dD1cIndpZHRoOjFweDtoZWlnaHQ6MzBweDtmbG9hdDpsZWZ0O2JhY2tncm91bmQtY29sb3I6IzExM1wiO2MuYXBwZW5kQ2hpbGQoail9dmFyIGQ9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtkLmlkPVwibXNcIjtkLnN0eWxlLmNzc1RleHQ9XCJwYWRkaW5nOjAgMCAzcHggM3B4O3RleHQtYWxpZ246bGVmdDtiYWNrZ3JvdW5kLWNvbG9yOiMwMjA7ZGlzcGxheTpub25lXCI7Zi5hcHBlbmRDaGlsZChkKTt2YXIgaz1kb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuay5pZD1cIm1zVGV4dFwiO2suc3R5bGUuY3NzVGV4dD1cImNvbG9yOiMwZjA7Zm9udC1mYW1pbHk6SGVsdmV0aWNhLEFyaWFsLHNhbnMtc2VyaWY7Zm9udC1zaXplOjlweDtmb250LXdlaWdodDpib2xkO2xpbmUtaGVpZ2h0OjE1cHhcIjtrLmlubmVySFRNTD1cIk1TXCI7ZC5hcHBlbmRDaGlsZChrKTt2YXIgZT1kb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO2UuaWQ9XCJtc0dyYXBoXCI7ZS5zdHlsZS5jc3NUZXh0PVwicG9zaXRpb246cmVsYXRpdmU7d2lkdGg6NzRweDtoZWlnaHQ6MzBweDtiYWNrZ3JvdW5kLWNvbG9yOiMwZjBcIjtmb3IoZC5hcHBlbmRDaGlsZChlKTs3ND5lLmNoaWxkcmVuLmxlbmd0aDspaj1kb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic3BhblwiKSxqLnN0eWxlLmNzc1RleHQ9XCJ3aWR0aDoxcHg7aGVpZ2h0OjMwcHg7ZmxvYXQ6bGVmdDtiYWNrZ3JvdW5kLWNvbG9yOiMxMzFcIixlLmFwcGVuZENoaWxkKGopO3ZhciB0PWZ1bmN0aW9uKGIpe3M9Yjtzd2l0Y2gocyl7Y2FzZSAwOmEuc3R5bGUuZGlzcGxheT1cblwiYmxvY2tcIjtkLnN0eWxlLmRpc3BsYXk9XCJub25lXCI7YnJlYWs7Y2FzZSAxOmEuc3R5bGUuZGlzcGxheT1cIm5vbmVcIixkLnN0eWxlLmRpc3BsYXk9XCJibG9ja1wifX07cmV0dXJue1JFVklTSU9OOjEyLGRvbUVsZW1lbnQ6ZixzZXRNb2RlOnQsYmVnaW46ZnVuY3Rpb24oKXtsPURhdGUubm93KCl9LGVuZDpmdW5jdGlvbigpe3ZhciBiPURhdGUubm93KCk7Zz1iLWw7bj1NYXRoLm1pbihuLGcpO289TWF0aC5tYXgobyxnKTtrLnRleHRDb250ZW50PWcrXCIgTVMgKFwiK24rXCItXCIrbytcIilcIjt2YXIgYT1NYXRoLm1pbigzMCwzMC0zMCooZy8yMDApKTtlLmFwcGVuZENoaWxkKGUuZmlyc3RDaGlsZCkuc3R5bGUuaGVpZ2h0PWErXCJweFwiO3IrKztiPm0rMUUzJiYoaD1NYXRoLnJvdW5kKDFFMypyLyhiLW0pKSxwPU1hdGgubWluKHAsaCkscT1NYXRoLm1heChxLGgpLGkudGV4dENvbnRlbnQ9aCtcIiBGUFMgKFwiK3ArXCItXCIrcStcIilcIixhPU1hdGgubWluKDMwLDMwLTMwKihoLzEwMCkpLGMuYXBwZW5kQ2hpbGQoYy5maXJzdENoaWxkKS5zdHlsZS5oZWlnaHQ9XG5hK1wicHhcIixtPWIscj0wKTtyZXR1cm4gYn0sdXBkYXRlOmZ1bmN0aW9uKCl7bD10aGlzLmVuZCgpfX19O1wib2JqZWN0XCI9PT10eXBlb2YgbW9kdWxlJiYobW9kdWxlLmV4cG9ydHM9U3RhdHMpO1xuIiwiLyoqXG4gKiBUd2Vlbi5qcyAtIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZVxuICogaHR0cHM6Ly9naXRodWIuY29tL3R3ZWVuanMvdHdlZW4uanNcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqXG4gKiBTZWUgaHR0cHM6Ly9naXRodWIuY29tL3R3ZWVuanMvdHdlZW4uanMvZ3JhcGhzL2NvbnRyaWJ1dG9ycyBmb3IgdGhlIGZ1bGwgbGlzdCBvZiBjb250cmlidXRvcnMuXG4gKiBUaGFuayB5b3UgYWxsLCB5b3UncmUgYXdlc29tZSFcbiAqL1xuXG52YXIgVFdFRU4gPSBUV0VFTiB8fCAoZnVuY3Rpb24gKCkge1xuXG5cdHZhciBfdHdlZW5zID0gW107XG5cblx0cmV0dXJuIHtcblxuXHRcdGdldEFsbDogZnVuY3Rpb24gKCkge1xuXG5cdFx0XHRyZXR1cm4gX3R3ZWVucztcblxuXHRcdH0sXG5cblx0XHRyZW1vdmVBbGw6IGZ1bmN0aW9uICgpIHtcblxuXHRcdFx0X3R3ZWVucyA9IFtdO1xuXG5cdFx0fSxcblxuXHRcdGFkZDogZnVuY3Rpb24gKHR3ZWVuKSB7XG5cblx0XHRcdF90d2VlbnMucHVzaCh0d2Vlbik7XG5cblx0XHR9LFxuXG5cdFx0cmVtb3ZlOiBmdW5jdGlvbiAodHdlZW4pIHtcblxuXHRcdFx0dmFyIGkgPSBfdHdlZW5zLmluZGV4T2YodHdlZW4pO1xuXG5cdFx0XHRpZiAoaSAhPT0gLTEpIHtcblx0XHRcdFx0X3R3ZWVucy5zcGxpY2UoaSwgMSk7XG5cdFx0XHR9XG5cblx0XHR9LFxuXG5cdFx0dXBkYXRlOiBmdW5jdGlvbiAodGltZSwgcHJlc2VydmUpIHtcblxuXHRcdFx0aWYgKF90d2VlbnMubGVuZ3RoID09PSAwKSB7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH1cblxuXHRcdFx0dmFyIGkgPSAwO1xuXG5cdFx0XHR0aW1lID0gdGltZSAhPT0gdW5kZWZpbmVkID8gdGltZSA6IFRXRUVOLm5vdygpO1xuXG5cdFx0XHR3aGlsZSAoaSA8IF90d2VlbnMubGVuZ3RoKSB7XG5cblx0XHRcdFx0aWYgKF90d2VlbnNbaV0udXBkYXRlKHRpbWUpIHx8IHByZXNlcnZlKSB7XG5cdFx0XHRcdFx0aSsrO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdF90d2VlbnMuc3BsaWNlKGksIDEpO1xuXHRcdFx0XHR9XG5cblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIHRydWU7XG5cblx0XHR9XG5cdH07XG5cbn0pKCk7XG5cblxuLy8gSW5jbHVkZSBhIHBlcmZvcm1hbmNlLm5vdyBwb2x5ZmlsbFxuKGZ1bmN0aW9uICgpIHtcblx0Ly8gSW4gbm9kZS5qcywgdXNlIHByb2Nlc3MuaHJ0aW1lLlxuXHRpZiAodGhpcy53aW5kb3cgPT09IHVuZGVmaW5lZCAmJiB0aGlzLnByb2Nlc3MgIT09IHVuZGVmaW5lZCkge1xuXHRcdFRXRUVOLm5vdyA9IGZ1bmN0aW9uICgpIHtcblx0XHRcdHZhciB0aW1lID0gcHJvY2Vzcy5ocnRpbWUoKTtcblxuXHRcdFx0Ly8gQ29udmVydCBbc2Vjb25kcywgbWljcm9zZWNvbmRzXSB0byBtaWxsaXNlY29uZHMuXG5cdFx0XHRyZXR1cm4gdGltZVswXSAqIDEwMDAgKyB0aW1lWzFdIC8gMTAwMDtcblx0XHR9O1xuXHR9XG5cdC8vIEluIGEgYnJvd3NlciwgdXNlIHdpbmRvdy5wZXJmb3JtYW5jZS5ub3cgaWYgaXQgaXMgYXZhaWxhYmxlLlxuXHRlbHNlIGlmICh0aGlzLndpbmRvdyAhPT0gdW5kZWZpbmVkICYmXG5cdCAgICAgICAgIHdpbmRvdy5wZXJmb3JtYW5jZSAhPT0gdW5kZWZpbmVkICYmXG5cdFx0IHdpbmRvdy5wZXJmb3JtYW5jZS5ub3cgIT09IHVuZGVmaW5lZCkge1xuXG5cdFx0Ly8gVGhpcyBtdXN0IGJlIGJvdW5kLCBiZWNhdXNlIGRpcmVjdGx5IGFzc2lnbmluZyB0aGlzIGZ1bmN0aW9uXG5cdFx0Ly8gbGVhZHMgdG8gYW4gaW52b2NhdGlvbiBleGNlcHRpb24gaW4gQ2hyb21lLlxuXHRcdFRXRUVOLm5vdyA9IHdpbmRvdy5wZXJmb3JtYW5jZS5ub3cuYmluZCh3aW5kb3cucGVyZm9ybWFuY2UpO1xuXHR9XG5cdC8vIFVzZSBEYXRlLm5vdyBpZiBpdCBpcyBhdmFpbGFibGUuXG5cdGVsc2UgaWYgKERhdGUubm93ICE9PSB1bmRlZmluZWQpIHtcblx0XHRUV0VFTi5ub3cgPSBEYXRlLm5vdztcblx0fVxuXHQvLyBPdGhlcndpc2UsIHVzZSAnbmV3IERhdGUoKS5nZXRUaW1lKCknLlxuXHRlbHNlIHtcblx0XHRUV0VFTi5ub3cgPSBmdW5jdGlvbiAoKSB7XG5cdFx0XHRyZXR1cm4gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG5cdFx0fTtcblx0fVxufSkoKTtcblxuXG5UV0VFTi5Ud2VlbiA9IGZ1bmN0aW9uIChvYmplY3QpIHtcblxuXHR2YXIgX29iamVjdCA9IG9iamVjdDtcblx0dmFyIF92YWx1ZXNTdGFydCA9IHt9O1xuXHR2YXIgX3ZhbHVlc0VuZCA9IHt9O1xuXHR2YXIgX3ZhbHVlc1N0YXJ0UmVwZWF0ID0ge307XG5cdHZhciBfZHVyYXRpb24gPSAxMDAwO1xuXHR2YXIgX3JlcGVhdCA9IDA7XG5cdHZhciBfeW95byA9IGZhbHNlO1xuXHR2YXIgX2lzUGxheWluZyA9IGZhbHNlO1xuXHR2YXIgX3JldmVyc2VkID0gZmFsc2U7XG5cdHZhciBfZGVsYXlUaW1lID0gMDtcblx0dmFyIF9zdGFydFRpbWUgPSBudWxsO1xuXHR2YXIgX2Vhc2luZ0Z1bmN0aW9uID0gVFdFRU4uRWFzaW5nLkxpbmVhci5Ob25lO1xuXHR2YXIgX2ludGVycG9sYXRpb25GdW5jdGlvbiA9IFRXRUVOLkludGVycG9sYXRpb24uTGluZWFyO1xuXHR2YXIgX2NoYWluZWRUd2VlbnMgPSBbXTtcblx0dmFyIF9vblN0YXJ0Q2FsbGJhY2sgPSBudWxsO1xuXHR2YXIgX29uU3RhcnRDYWxsYmFja0ZpcmVkID0gZmFsc2U7XG5cdHZhciBfb25VcGRhdGVDYWxsYmFjayA9IG51bGw7XG5cdHZhciBfb25Db21wbGV0ZUNhbGxiYWNrID0gbnVsbDtcblx0dmFyIF9vblN0b3BDYWxsYmFjayA9IG51bGw7XG5cblx0Ly8gU2V0IGFsbCBzdGFydGluZyB2YWx1ZXMgcHJlc2VudCBvbiB0aGUgdGFyZ2V0IG9iamVjdFxuXHRmb3IgKHZhciBmaWVsZCBpbiBvYmplY3QpIHtcblx0XHRfdmFsdWVzU3RhcnRbZmllbGRdID0gcGFyc2VGbG9hdChvYmplY3RbZmllbGRdLCAxMCk7XG5cdH1cblxuXHR0aGlzLnRvID0gZnVuY3Rpb24gKHByb3BlcnRpZXMsIGR1cmF0aW9uKSB7XG5cblx0XHRpZiAoZHVyYXRpb24gIT09IHVuZGVmaW5lZCkge1xuXHRcdFx0X2R1cmF0aW9uID0gZHVyYXRpb247XG5cdFx0fVxuXG5cdFx0X3ZhbHVlc0VuZCA9IHByb3BlcnRpZXM7XG5cblx0XHRyZXR1cm4gdGhpcztcblxuXHR9O1xuXG5cdHRoaXMuc3RhcnQgPSBmdW5jdGlvbiAodGltZSkge1xuXG5cdFx0VFdFRU4uYWRkKHRoaXMpO1xuXG5cdFx0X2lzUGxheWluZyA9IHRydWU7XG5cblx0XHRfb25TdGFydENhbGxiYWNrRmlyZWQgPSBmYWxzZTtcblxuXHRcdF9zdGFydFRpbWUgPSB0aW1lICE9PSB1bmRlZmluZWQgPyB0aW1lIDogVFdFRU4ubm93KCk7XG5cdFx0X3N0YXJ0VGltZSArPSBfZGVsYXlUaW1lO1xuXG5cdFx0Zm9yICh2YXIgcHJvcGVydHkgaW4gX3ZhbHVlc0VuZCkge1xuXG5cdFx0XHQvLyBDaGVjayBpZiBhbiBBcnJheSB3YXMgcHJvdmlkZWQgYXMgcHJvcGVydHkgdmFsdWVcblx0XHRcdGlmIChfdmFsdWVzRW5kW3Byb3BlcnR5XSBpbnN0YW5jZW9mIEFycmF5KSB7XG5cblx0XHRcdFx0aWYgKF92YWx1ZXNFbmRbcHJvcGVydHldLmxlbmd0aCA9PT0gMCkge1xuXHRcdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gQ3JlYXRlIGEgbG9jYWwgY29weSBvZiB0aGUgQXJyYXkgd2l0aCB0aGUgc3RhcnQgdmFsdWUgYXQgdGhlIGZyb250XG5cdFx0XHRcdF92YWx1ZXNFbmRbcHJvcGVydHldID0gW19vYmplY3RbcHJvcGVydHldXS5jb25jYXQoX3ZhbHVlc0VuZFtwcm9wZXJ0eV0pO1xuXG5cdFx0XHR9XG5cblx0XHRcdC8vIElmIGB0bygpYCBzcGVjaWZpZXMgYSBwcm9wZXJ0eSB0aGF0IGRvZXNuJ3QgZXhpc3QgaW4gdGhlIHNvdXJjZSBvYmplY3QsXG5cdFx0XHQvLyB3ZSBzaG91bGQgbm90IHNldCB0aGF0IHByb3BlcnR5IGluIHRoZSBvYmplY3Rcblx0XHRcdGlmIChfdmFsdWVzU3RhcnRbcHJvcGVydHldID09PSB1bmRlZmluZWQpIHtcblx0XHRcdFx0Y29udGludWU7XG5cdFx0XHR9XG5cblx0XHRcdF92YWx1ZXNTdGFydFtwcm9wZXJ0eV0gPSBfb2JqZWN0W3Byb3BlcnR5XTtcblxuXHRcdFx0aWYgKChfdmFsdWVzU3RhcnRbcHJvcGVydHldIGluc3RhbmNlb2YgQXJyYXkpID09PSBmYWxzZSkge1xuXHRcdFx0XHRfdmFsdWVzU3RhcnRbcHJvcGVydHldICo9IDEuMDsgLy8gRW5zdXJlcyB3ZSdyZSB1c2luZyBudW1iZXJzLCBub3Qgc3RyaW5nc1xuXHRcdFx0fVxuXG5cdFx0XHRfdmFsdWVzU3RhcnRSZXBlYXRbcHJvcGVydHldID0gX3ZhbHVlc1N0YXJ0W3Byb3BlcnR5XSB8fCAwO1xuXG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fTtcblxuXHR0aGlzLnN0b3AgPSBmdW5jdGlvbiAoKSB7XG5cblx0XHRpZiAoIV9pc1BsYXlpbmcpIHtcblx0XHRcdHJldHVybiB0aGlzO1xuXHRcdH1cblxuXHRcdFRXRUVOLnJlbW92ZSh0aGlzKTtcblx0XHRfaXNQbGF5aW5nID0gZmFsc2U7XG5cblx0XHRpZiAoX29uU3RvcENhbGxiYWNrICE9PSBudWxsKSB7XG5cdFx0XHRfb25TdG9wQ2FsbGJhY2suY2FsbChfb2JqZWN0KTtcblx0XHR9XG5cblx0XHR0aGlzLnN0b3BDaGFpbmVkVHdlZW5zKCk7XG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fTtcblxuXHR0aGlzLnN0b3BDaGFpbmVkVHdlZW5zID0gZnVuY3Rpb24gKCkge1xuXG5cdFx0Zm9yICh2YXIgaSA9IDAsIG51bUNoYWluZWRUd2VlbnMgPSBfY2hhaW5lZFR3ZWVucy5sZW5ndGg7IGkgPCBudW1DaGFpbmVkVHdlZW5zOyBpKyspIHtcblx0XHRcdF9jaGFpbmVkVHdlZW5zW2ldLnN0b3AoKTtcblx0XHR9XG5cblx0fTtcblxuXHR0aGlzLmRlbGF5ID0gZnVuY3Rpb24gKGFtb3VudCkge1xuXG5cdFx0X2RlbGF5VGltZSA9IGFtb3VudDtcblx0XHRyZXR1cm4gdGhpcztcblxuXHR9O1xuXG5cdHRoaXMucmVwZWF0ID0gZnVuY3Rpb24gKHRpbWVzKSB7XG5cblx0XHRfcmVwZWF0ID0gdGltZXM7XG5cdFx0cmV0dXJuIHRoaXM7XG5cblx0fTtcblxuXHR0aGlzLnlveW8gPSBmdW5jdGlvbiAoeW95bykge1xuXG5cdFx0X3lveW8gPSB5b3lvO1xuXHRcdHJldHVybiB0aGlzO1xuXG5cdH07XG5cblxuXHR0aGlzLmVhc2luZyA9IGZ1bmN0aW9uIChlYXNpbmcpIHtcblxuXHRcdF9lYXNpbmdGdW5jdGlvbiA9IGVhc2luZztcblx0XHRyZXR1cm4gdGhpcztcblxuXHR9O1xuXG5cdHRoaXMuaW50ZXJwb2xhdGlvbiA9IGZ1bmN0aW9uIChpbnRlcnBvbGF0aW9uKSB7XG5cblx0XHRfaW50ZXJwb2xhdGlvbkZ1bmN0aW9uID0gaW50ZXJwb2xhdGlvbjtcblx0XHRyZXR1cm4gdGhpcztcblxuXHR9O1xuXG5cdHRoaXMuY2hhaW4gPSBmdW5jdGlvbiAoKSB7XG5cblx0XHRfY2hhaW5lZFR3ZWVucyA9IGFyZ3VtZW50cztcblx0XHRyZXR1cm4gdGhpcztcblxuXHR9O1xuXG5cdHRoaXMub25TdGFydCA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuXG5cdFx0X29uU3RhcnRDYWxsYmFjayA9IGNhbGxiYWNrO1xuXHRcdHJldHVybiB0aGlzO1xuXG5cdH07XG5cblx0dGhpcy5vblVwZGF0ZSA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuXG5cdFx0X29uVXBkYXRlQ2FsbGJhY2sgPSBjYWxsYmFjaztcblx0XHRyZXR1cm4gdGhpcztcblxuXHR9O1xuXG5cdHRoaXMub25Db21wbGV0ZSA9IGZ1bmN0aW9uIChjYWxsYmFjaykge1xuXG5cdFx0X29uQ29tcGxldGVDYWxsYmFjayA9IGNhbGxiYWNrO1xuXHRcdHJldHVybiB0aGlzO1xuXG5cdH07XG5cblx0dGhpcy5vblN0b3AgPSBmdW5jdGlvbiAoY2FsbGJhY2spIHtcblxuXHRcdF9vblN0b3BDYWxsYmFjayA9IGNhbGxiYWNrO1xuXHRcdHJldHVybiB0aGlzO1xuXG5cdH07XG5cblx0dGhpcy51cGRhdGUgPSBmdW5jdGlvbiAodGltZSkge1xuXG5cdFx0dmFyIHByb3BlcnR5O1xuXHRcdHZhciBlbGFwc2VkO1xuXHRcdHZhciB2YWx1ZTtcblxuXHRcdGlmICh0aW1lIDwgX3N0YXJ0VGltZSkge1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXG5cdFx0aWYgKF9vblN0YXJ0Q2FsbGJhY2tGaXJlZCA9PT0gZmFsc2UpIHtcblxuXHRcdFx0aWYgKF9vblN0YXJ0Q2FsbGJhY2sgIT09IG51bGwpIHtcblx0XHRcdFx0X29uU3RhcnRDYWxsYmFjay5jYWxsKF9vYmplY3QpO1xuXHRcdFx0fVxuXG5cdFx0XHRfb25TdGFydENhbGxiYWNrRmlyZWQgPSB0cnVlO1xuXG5cdFx0fVxuXG5cdFx0ZWxhcHNlZCA9ICh0aW1lIC0gX3N0YXJ0VGltZSkgLyBfZHVyYXRpb247XG5cdFx0ZWxhcHNlZCA9IGVsYXBzZWQgPiAxID8gMSA6IGVsYXBzZWQ7XG5cblx0XHR2YWx1ZSA9IF9lYXNpbmdGdW5jdGlvbihlbGFwc2VkKTtcblxuXHRcdGZvciAocHJvcGVydHkgaW4gX3ZhbHVlc0VuZCkge1xuXG5cdFx0XHQvLyBEb24ndCB1cGRhdGUgcHJvcGVydGllcyB0aGF0IGRvIG5vdCBleGlzdCBpbiB0aGUgc291cmNlIG9iamVjdFxuXHRcdFx0aWYgKF92YWx1ZXNTdGFydFtwcm9wZXJ0eV0gPT09IHVuZGVmaW5lZCkge1xuXHRcdFx0XHRjb250aW51ZTtcblx0XHRcdH1cblxuXHRcdFx0dmFyIHN0YXJ0ID0gX3ZhbHVlc1N0YXJ0W3Byb3BlcnR5XSB8fCAwO1xuXHRcdFx0dmFyIGVuZCA9IF92YWx1ZXNFbmRbcHJvcGVydHldO1xuXG5cdFx0XHRpZiAoZW5kIGluc3RhbmNlb2YgQXJyYXkpIHtcblxuXHRcdFx0XHRfb2JqZWN0W3Byb3BlcnR5XSA9IF9pbnRlcnBvbGF0aW9uRnVuY3Rpb24oZW5kLCB2YWx1ZSk7XG5cblx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0Ly8gUGFyc2VzIHJlbGF0aXZlIGVuZCB2YWx1ZXMgd2l0aCBzdGFydCBhcyBiYXNlIChlLmcuOiArMTAsIC0zKVxuXHRcdFx0XHRpZiAodHlwZW9mIChlbmQpID09PSAnc3RyaW5nJykge1xuXG5cdFx0XHRcdFx0aWYgKGVuZC5jaGFyQXQoMCkgPT09ICcrJyB8fCBlbmQuY2hhckF0KDApID09PSAnLScpIHtcblx0XHRcdFx0XHRcdGVuZCA9IHN0YXJ0ICsgcGFyc2VGbG9hdChlbmQsIDEwKTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0ZW5kID0gcGFyc2VGbG9hdChlbmQsIDEwKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBQcm90ZWN0IGFnYWluc3Qgbm9uIG51bWVyaWMgcHJvcGVydGllcy5cblx0XHRcdFx0aWYgKHR5cGVvZiAoZW5kKSA9PT0gJ251bWJlcicpIHtcblx0XHRcdFx0XHRfb2JqZWN0W3Byb3BlcnR5XSA9IHN0YXJ0ICsgKGVuZCAtIHN0YXJ0KSAqIHZhbHVlO1xuXHRcdFx0XHR9XG5cblx0XHRcdH1cblxuXHRcdH1cblxuXHRcdGlmIChfb25VcGRhdGVDYWxsYmFjayAhPT0gbnVsbCkge1xuXHRcdFx0X29uVXBkYXRlQ2FsbGJhY2suY2FsbChfb2JqZWN0LCB2YWx1ZSk7XG5cdFx0fVxuXG5cdFx0aWYgKGVsYXBzZWQgPT09IDEpIHtcblxuXHRcdFx0aWYgKF9yZXBlYXQgPiAwKSB7XG5cblx0XHRcdFx0aWYgKGlzRmluaXRlKF9yZXBlYXQpKSB7XG5cdFx0XHRcdFx0X3JlcGVhdC0tO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gUmVhc3NpZ24gc3RhcnRpbmcgdmFsdWVzLCByZXN0YXJ0IGJ5IG1ha2luZyBzdGFydFRpbWUgPSBub3dcblx0XHRcdFx0Zm9yIChwcm9wZXJ0eSBpbiBfdmFsdWVzU3RhcnRSZXBlYXQpIHtcblxuXHRcdFx0XHRcdGlmICh0eXBlb2YgKF92YWx1ZXNFbmRbcHJvcGVydHldKSA9PT0gJ3N0cmluZycpIHtcblx0XHRcdFx0XHRcdF92YWx1ZXNTdGFydFJlcGVhdFtwcm9wZXJ0eV0gPSBfdmFsdWVzU3RhcnRSZXBlYXRbcHJvcGVydHldICsgcGFyc2VGbG9hdChfdmFsdWVzRW5kW3Byb3BlcnR5XSwgMTApO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdGlmIChfeW95bykge1xuXHRcdFx0XHRcdFx0dmFyIHRtcCA9IF92YWx1ZXNTdGFydFJlcGVhdFtwcm9wZXJ0eV07XG5cblx0XHRcdFx0XHRcdF92YWx1ZXNTdGFydFJlcGVhdFtwcm9wZXJ0eV0gPSBfdmFsdWVzRW5kW3Byb3BlcnR5XTtcblx0XHRcdFx0XHRcdF92YWx1ZXNFbmRbcHJvcGVydHldID0gdG1wO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdF92YWx1ZXNTdGFydFtwcm9wZXJ0eV0gPSBfdmFsdWVzU3RhcnRSZXBlYXRbcHJvcGVydHldO1xuXG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZiAoX3lveW8pIHtcblx0XHRcdFx0XHRfcmV2ZXJzZWQgPSAhX3JldmVyc2VkO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0X3N0YXJ0VGltZSA9IHRpbWUgKyBfZGVsYXlUaW1lO1xuXG5cdFx0XHRcdHJldHVybiB0cnVlO1xuXG5cdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdGlmIChfb25Db21wbGV0ZUNhbGxiYWNrICE9PSBudWxsKSB7XG5cdFx0XHRcdFx0X29uQ29tcGxldGVDYWxsYmFjay5jYWxsKF9vYmplY3QpO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Zm9yICh2YXIgaSA9IDAsIG51bUNoYWluZWRUd2VlbnMgPSBfY2hhaW5lZFR3ZWVucy5sZW5ndGg7IGkgPCBudW1DaGFpbmVkVHdlZW5zOyBpKyspIHtcblx0XHRcdFx0XHQvLyBNYWtlIHRoZSBjaGFpbmVkIHR3ZWVucyBzdGFydCBleGFjdGx5IGF0IHRoZSB0aW1lIHRoZXkgc2hvdWxkLFxuXHRcdFx0XHRcdC8vIGV2ZW4gaWYgdGhlIGB1cGRhdGUoKWAgbWV0aG9kIHdhcyBjYWxsZWQgd2F5IHBhc3QgdGhlIGR1cmF0aW9uIG9mIHRoZSB0d2VlblxuXHRcdFx0XHRcdF9jaGFpbmVkVHdlZW5zW2ldLnN0YXJ0KF9zdGFydFRpbWUgKyBfZHVyYXRpb24pO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXG5cdFx0XHR9XG5cblx0XHR9XG5cblx0XHRyZXR1cm4gdHJ1ZTtcblxuXHR9O1xuXG59O1xuXG5cblRXRUVOLkVhc2luZyA9IHtcblxuXHRMaW5lYXI6IHtcblxuXHRcdE5vbmU6IGZ1bmN0aW9uIChrKSB7XG5cblx0XHRcdHJldHVybiBrO1xuXG5cdFx0fVxuXG5cdH0sXG5cblx0UXVhZHJhdGljOiB7XG5cblx0XHRJbjogZnVuY3Rpb24gKGspIHtcblxuXHRcdFx0cmV0dXJuIGsgKiBrO1xuXG5cdFx0fSxcblxuXHRcdE91dDogZnVuY3Rpb24gKGspIHtcblxuXHRcdFx0cmV0dXJuIGsgKiAoMiAtIGspO1xuXG5cdFx0fSxcblxuXHRcdEluT3V0OiBmdW5jdGlvbiAoaykge1xuXG5cdFx0XHRpZiAoKGsgKj0gMikgPCAxKSB7XG5cdFx0XHRcdHJldHVybiAwLjUgKiBrICogaztcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIC0gMC41ICogKC0tayAqIChrIC0gMikgLSAxKTtcblxuXHRcdH1cblxuXHR9LFxuXG5cdEN1YmljOiB7XG5cblx0XHRJbjogZnVuY3Rpb24gKGspIHtcblxuXHRcdFx0cmV0dXJuIGsgKiBrICogaztcblxuXHRcdH0sXG5cblx0XHRPdXQ6IGZ1bmN0aW9uIChrKSB7XG5cblx0XHRcdHJldHVybiAtLWsgKiBrICogayArIDE7XG5cblx0XHR9LFxuXG5cdFx0SW5PdXQ6IGZ1bmN0aW9uIChrKSB7XG5cblx0XHRcdGlmICgoayAqPSAyKSA8IDEpIHtcblx0XHRcdFx0cmV0dXJuIDAuNSAqIGsgKiBrICogaztcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIDAuNSAqICgoayAtPSAyKSAqIGsgKiBrICsgMik7XG5cblx0XHR9XG5cblx0fSxcblxuXHRRdWFydGljOiB7XG5cblx0XHRJbjogZnVuY3Rpb24gKGspIHtcblxuXHRcdFx0cmV0dXJuIGsgKiBrICogayAqIGs7XG5cblx0XHR9LFxuXG5cdFx0T3V0OiBmdW5jdGlvbiAoaykge1xuXG5cdFx0XHRyZXR1cm4gMSAtICgtLWsgKiBrICogayAqIGspO1xuXG5cdFx0fSxcblxuXHRcdEluT3V0OiBmdW5jdGlvbiAoaykge1xuXG5cdFx0XHRpZiAoKGsgKj0gMikgPCAxKSB7XG5cdFx0XHRcdHJldHVybiAwLjUgKiBrICogayAqIGsgKiBrO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gLSAwLjUgKiAoKGsgLT0gMikgKiBrICogayAqIGsgLSAyKTtcblxuXHRcdH1cblxuXHR9LFxuXG5cdFF1aW50aWM6IHtcblxuXHRcdEluOiBmdW5jdGlvbiAoaykge1xuXG5cdFx0XHRyZXR1cm4gayAqIGsgKiBrICogayAqIGs7XG5cblx0XHR9LFxuXG5cdFx0T3V0OiBmdW5jdGlvbiAoaykge1xuXG5cdFx0XHRyZXR1cm4gLS1rICogayAqIGsgKiBrICogayArIDE7XG5cblx0XHR9LFxuXG5cdFx0SW5PdXQ6IGZ1bmN0aW9uIChrKSB7XG5cblx0XHRcdGlmICgoayAqPSAyKSA8IDEpIHtcblx0XHRcdFx0cmV0dXJuIDAuNSAqIGsgKiBrICogayAqIGsgKiBrO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gMC41ICogKChrIC09IDIpICogayAqIGsgKiBrICogayArIDIpO1xuXG5cdFx0fVxuXG5cdH0sXG5cblx0U2ludXNvaWRhbDoge1xuXG5cdFx0SW46IGZ1bmN0aW9uIChrKSB7XG5cblx0XHRcdHJldHVybiAxIC0gTWF0aC5jb3MoayAqIE1hdGguUEkgLyAyKTtcblxuXHRcdH0sXG5cblx0XHRPdXQ6IGZ1bmN0aW9uIChrKSB7XG5cblx0XHRcdHJldHVybiBNYXRoLnNpbihrICogTWF0aC5QSSAvIDIpO1xuXG5cdFx0fSxcblxuXHRcdEluT3V0OiBmdW5jdGlvbiAoaykge1xuXG5cdFx0XHRyZXR1cm4gMC41ICogKDEgLSBNYXRoLmNvcyhNYXRoLlBJICogaykpO1xuXG5cdFx0fVxuXG5cdH0sXG5cblx0RXhwb25lbnRpYWw6IHtcblxuXHRcdEluOiBmdW5jdGlvbiAoaykge1xuXG5cdFx0XHRyZXR1cm4gayA9PT0gMCA/IDAgOiBNYXRoLnBvdygxMDI0LCBrIC0gMSk7XG5cblx0XHR9LFxuXG5cdFx0T3V0OiBmdW5jdGlvbiAoaykge1xuXG5cdFx0XHRyZXR1cm4gayA9PT0gMSA/IDEgOiAxIC0gTWF0aC5wb3coMiwgLSAxMCAqIGspO1xuXG5cdFx0fSxcblxuXHRcdEluT3V0OiBmdW5jdGlvbiAoaykge1xuXG5cdFx0XHRpZiAoayA9PT0gMCkge1xuXHRcdFx0XHRyZXR1cm4gMDtcblx0XHRcdH1cblxuXHRcdFx0aWYgKGsgPT09IDEpIHtcblx0XHRcdFx0cmV0dXJuIDE7XG5cdFx0XHR9XG5cblx0XHRcdGlmICgoayAqPSAyKSA8IDEpIHtcblx0XHRcdFx0cmV0dXJuIDAuNSAqIE1hdGgucG93KDEwMjQsIGsgLSAxKTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIDAuNSAqICgtIE1hdGgucG93KDIsIC0gMTAgKiAoayAtIDEpKSArIDIpO1xuXG5cdFx0fVxuXG5cdH0sXG5cblx0Q2lyY3VsYXI6IHtcblxuXHRcdEluOiBmdW5jdGlvbiAoaykge1xuXG5cdFx0XHRyZXR1cm4gMSAtIE1hdGguc3FydCgxIC0gayAqIGspO1xuXG5cdFx0fSxcblxuXHRcdE91dDogZnVuY3Rpb24gKGspIHtcblxuXHRcdFx0cmV0dXJuIE1hdGguc3FydCgxIC0gKC0tayAqIGspKTtcblxuXHRcdH0sXG5cblx0XHRJbk91dDogZnVuY3Rpb24gKGspIHtcblxuXHRcdFx0aWYgKChrICo9IDIpIDwgMSkge1xuXHRcdFx0XHRyZXR1cm4gLSAwLjUgKiAoTWF0aC5zcXJ0KDEgLSBrICogaykgLSAxKTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIDAuNSAqIChNYXRoLnNxcnQoMSAtIChrIC09IDIpICogaykgKyAxKTtcblxuXHRcdH1cblxuXHR9LFxuXG5cdEVsYXN0aWM6IHtcblxuXHRcdEluOiBmdW5jdGlvbiAoaykge1xuXG5cdFx0XHRpZiAoayA9PT0gMCkge1xuXHRcdFx0XHRyZXR1cm4gMDtcblx0XHRcdH1cblxuXHRcdFx0aWYgKGsgPT09IDEpIHtcblx0XHRcdFx0cmV0dXJuIDE7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiAtTWF0aC5wb3coMiwgMTAgKiAoayAtIDEpKSAqIE1hdGguc2luKChrIC0gMS4xKSAqIDUgKiBNYXRoLlBJKTtcblxuXHRcdH0sXG5cblx0XHRPdXQ6IGZ1bmN0aW9uIChrKSB7XG5cblx0XHRcdGlmIChrID09PSAwKSB7XG5cdFx0XHRcdHJldHVybiAwO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoayA9PT0gMSkge1xuXHRcdFx0XHRyZXR1cm4gMTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIE1hdGgucG93KDIsIC0xMCAqIGspICogTWF0aC5zaW4oKGsgLSAwLjEpICogNSAqIE1hdGguUEkpICsgMTtcblxuXHRcdH0sXG5cblx0XHRJbk91dDogZnVuY3Rpb24gKGspIHtcblxuXHRcdFx0aWYgKGsgPT09IDApIHtcblx0XHRcdFx0cmV0dXJuIDA7XG5cdFx0XHR9XG5cblx0XHRcdGlmIChrID09PSAxKSB7XG5cdFx0XHRcdHJldHVybiAxO1xuXHRcdFx0fVxuXG5cdFx0XHRrICo9IDI7XG5cblx0XHRcdGlmIChrIDwgMSkge1xuXHRcdFx0XHRyZXR1cm4gLTAuNSAqIE1hdGgucG93KDIsIDEwICogKGsgLSAxKSkgKiBNYXRoLnNpbigoayAtIDEuMSkgKiA1ICogTWF0aC5QSSk7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiAwLjUgKiBNYXRoLnBvdygyLCAtMTAgKiAoayAtIDEpKSAqIE1hdGguc2luKChrIC0gMS4xKSAqIDUgKiBNYXRoLlBJKSArIDE7XG5cblx0XHR9XG5cblx0fSxcblxuXHRCYWNrOiB7XG5cblx0XHRJbjogZnVuY3Rpb24gKGspIHtcblxuXHRcdFx0dmFyIHMgPSAxLjcwMTU4O1xuXG5cdFx0XHRyZXR1cm4gayAqIGsgKiAoKHMgKyAxKSAqIGsgLSBzKTtcblxuXHRcdH0sXG5cblx0XHRPdXQ6IGZ1bmN0aW9uIChrKSB7XG5cblx0XHRcdHZhciBzID0gMS43MDE1ODtcblxuXHRcdFx0cmV0dXJuIC0tayAqIGsgKiAoKHMgKyAxKSAqIGsgKyBzKSArIDE7XG5cblx0XHR9LFxuXG5cdFx0SW5PdXQ6IGZ1bmN0aW9uIChrKSB7XG5cblx0XHRcdHZhciBzID0gMS43MDE1OCAqIDEuNTI1O1xuXG5cdFx0XHRpZiAoKGsgKj0gMikgPCAxKSB7XG5cdFx0XHRcdHJldHVybiAwLjUgKiAoayAqIGsgKiAoKHMgKyAxKSAqIGsgLSBzKSk7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiAwLjUgKiAoKGsgLT0gMikgKiBrICogKChzICsgMSkgKiBrICsgcykgKyAyKTtcblxuXHRcdH1cblxuXHR9LFxuXG5cdEJvdW5jZToge1xuXG5cdFx0SW46IGZ1bmN0aW9uIChrKSB7XG5cblx0XHRcdHJldHVybiAxIC0gVFdFRU4uRWFzaW5nLkJvdW5jZS5PdXQoMSAtIGspO1xuXG5cdFx0fSxcblxuXHRcdE91dDogZnVuY3Rpb24gKGspIHtcblxuXHRcdFx0aWYgKGsgPCAoMSAvIDIuNzUpKSB7XG5cdFx0XHRcdHJldHVybiA3LjU2MjUgKiBrICogaztcblx0XHRcdH0gZWxzZSBpZiAoayA8ICgyIC8gMi43NSkpIHtcblx0XHRcdFx0cmV0dXJuIDcuNTYyNSAqIChrIC09ICgxLjUgLyAyLjc1KSkgKiBrICsgMC43NTtcblx0XHRcdH0gZWxzZSBpZiAoayA8ICgyLjUgLyAyLjc1KSkge1xuXHRcdFx0XHRyZXR1cm4gNy41NjI1ICogKGsgLT0gKDIuMjUgLyAyLjc1KSkgKiBrICsgMC45Mzc1O1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0cmV0dXJuIDcuNTYyNSAqIChrIC09ICgyLjYyNSAvIDIuNzUpKSAqIGsgKyAwLjk4NDM3NTtcblx0XHRcdH1cblxuXHRcdH0sXG5cblx0XHRJbk91dDogZnVuY3Rpb24gKGspIHtcblxuXHRcdFx0aWYgKGsgPCAwLjUpIHtcblx0XHRcdFx0cmV0dXJuIFRXRUVOLkVhc2luZy5Cb3VuY2UuSW4oayAqIDIpICogMC41O1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gVFdFRU4uRWFzaW5nLkJvdW5jZS5PdXQoayAqIDIgLSAxKSAqIDAuNSArIDAuNTtcblxuXHRcdH1cblxuXHR9XG5cbn07XG5cblRXRUVOLkludGVycG9sYXRpb24gPSB7XG5cblx0TGluZWFyOiBmdW5jdGlvbiAodiwgaykge1xuXG5cdFx0dmFyIG0gPSB2Lmxlbmd0aCAtIDE7XG5cdFx0dmFyIGYgPSBtICogaztcblx0XHR2YXIgaSA9IE1hdGguZmxvb3IoZik7XG5cdFx0dmFyIGZuID0gVFdFRU4uSW50ZXJwb2xhdGlvbi5VdGlscy5MaW5lYXI7XG5cblx0XHRpZiAoayA8IDApIHtcblx0XHRcdHJldHVybiBmbih2WzBdLCB2WzFdLCBmKTtcblx0XHR9XG5cblx0XHRpZiAoayA+IDEpIHtcblx0XHRcdHJldHVybiBmbih2W21dLCB2W20gLSAxXSwgbSAtIGYpO1xuXHRcdH1cblxuXHRcdHJldHVybiBmbih2W2ldLCB2W2kgKyAxID4gbSA/IG0gOiBpICsgMV0sIGYgLSBpKTtcblxuXHR9LFxuXG5cdEJlemllcjogZnVuY3Rpb24gKHYsIGspIHtcblxuXHRcdHZhciBiID0gMDtcblx0XHR2YXIgbiA9IHYubGVuZ3RoIC0gMTtcblx0XHR2YXIgcHcgPSBNYXRoLnBvdztcblx0XHR2YXIgYm4gPSBUV0VFTi5JbnRlcnBvbGF0aW9uLlV0aWxzLkJlcm5zdGVpbjtcblxuXHRcdGZvciAodmFyIGkgPSAwOyBpIDw9IG47IGkrKykge1xuXHRcdFx0YiArPSBwdygxIC0gaywgbiAtIGkpICogcHcoaywgaSkgKiB2W2ldICogYm4obiwgaSk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGI7XG5cblx0fSxcblxuXHRDYXRtdWxsUm9tOiBmdW5jdGlvbiAodiwgaykge1xuXG5cdFx0dmFyIG0gPSB2Lmxlbmd0aCAtIDE7XG5cdFx0dmFyIGYgPSBtICogaztcblx0XHR2YXIgaSA9IE1hdGguZmxvb3IoZik7XG5cdFx0dmFyIGZuID0gVFdFRU4uSW50ZXJwb2xhdGlvbi5VdGlscy5DYXRtdWxsUm9tO1xuXG5cdFx0aWYgKHZbMF0gPT09IHZbbV0pIHtcblxuXHRcdFx0aWYgKGsgPCAwKSB7XG5cdFx0XHRcdGkgPSBNYXRoLmZsb29yKGYgPSBtICogKDEgKyBrKSk7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBmbih2WyhpIC0gMSArIG0pICUgbV0sIHZbaV0sIHZbKGkgKyAxKSAlIG1dLCB2WyhpICsgMikgJSBtXSwgZiAtIGkpO1xuXG5cdFx0fSBlbHNlIHtcblxuXHRcdFx0aWYgKGsgPCAwKSB7XG5cdFx0XHRcdHJldHVybiB2WzBdIC0gKGZuKHZbMF0sIHZbMF0sIHZbMV0sIHZbMV0sIC1mKSAtIHZbMF0pO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoayA+IDEpIHtcblx0XHRcdFx0cmV0dXJuIHZbbV0gLSAoZm4odlttXSwgdlttXSwgdlttIC0gMV0sIHZbbSAtIDFdLCBmIC0gbSkgLSB2W21dKTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIGZuKHZbaSA/IGkgLSAxIDogMF0sIHZbaV0sIHZbbSA8IGkgKyAxID8gbSA6IGkgKyAxXSwgdlttIDwgaSArIDIgPyBtIDogaSArIDJdLCBmIC0gaSk7XG5cblx0XHR9XG5cblx0fSxcblxuXHRVdGlsczoge1xuXG5cdFx0TGluZWFyOiBmdW5jdGlvbiAocDAsIHAxLCB0KSB7XG5cblx0XHRcdHJldHVybiAocDEgLSBwMCkgKiB0ICsgcDA7XG5cblx0XHR9LFxuXG5cdFx0QmVybnN0ZWluOiBmdW5jdGlvbiAobiwgaSkge1xuXG5cdFx0XHR2YXIgZmMgPSBUV0VFTi5JbnRlcnBvbGF0aW9uLlV0aWxzLkZhY3RvcmlhbDtcblxuXHRcdFx0cmV0dXJuIGZjKG4pIC8gZmMoaSkgLyBmYyhuIC0gaSk7XG5cblx0XHR9LFxuXG5cdFx0RmFjdG9yaWFsOiAoZnVuY3Rpb24gKCkge1xuXG5cdFx0XHR2YXIgYSA9IFsxXTtcblxuXHRcdFx0cmV0dXJuIGZ1bmN0aW9uIChuKSB7XG5cblx0XHRcdFx0dmFyIHMgPSAxO1xuXG5cdFx0XHRcdGlmIChhW25dKSB7XG5cdFx0XHRcdFx0cmV0dXJuIGFbbl07XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRmb3IgKHZhciBpID0gbjsgaSA+IDE7IGktLSkge1xuXHRcdFx0XHRcdHMgKj0gaTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGFbbl0gPSBzO1xuXHRcdFx0XHRyZXR1cm4gcztcblxuXHRcdFx0fTtcblxuXHRcdH0pKCksXG5cblx0XHRDYXRtdWxsUm9tOiBmdW5jdGlvbiAocDAsIHAxLCBwMiwgcDMsIHQpIHtcblxuXHRcdFx0dmFyIHYwID0gKHAyIC0gcDApICogMC41O1xuXHRcdFx0dmFyIHYxID0gKHAzIC0gcDEpICogMC41O1xuXHRcdFx0dmFyIHQyID0gdCAqIHQ7XG5cdFx0XHR2YXIgdDMgPSB0ICogdDI7XG5cblx0XHRcdHJldHVybiAoMiAqIHAxIC0gMiAqIHAyICsgdjAgKyB2MSkgKiB0MyArICgtIDMgKiBwMSArIDMgKiBwMiAtIDIgKiB2MCAtIHYxKSAqIHQyICsgdjAgKiB0ICsgcDE7XG5cblx0XHR9XG5cblx0fVxuXG59O1xuXG4vLyBVTUQgKFVuaXZlcnNhbCBNb2R1bGUgRGVmaW5pdGlvbilcbihmdW5jdGlvbiAocm9vdCkge1xuXG5cdGlmICh0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpIHtcblxuXHRcdC8vIEFNRFxuXHRcdGRlZmluZShbXSwgZnVuY3Rpb24gKCkge1xuXHRcdFx0cmV0dXJuIFRXRUVOO1xuXHRcdH0pO1xuXG5cdH0gZWxzZSBpZiAodHlwZW9mIG1vZHVsZSAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnKSB7XG5cblx0XHQvLyBOb2RlLmpzXG5cdFx0bW9kdWxlLmV4cG9ydHMgPSBUV0VFTjtcblxuXHR9IGVsc2UgaWYgKHJvb3QgIT09IHVuZGVmaW5lZCkge1xuXG5cdFx0Ly8gR2xvYmFsIHZhcmlhYmxlXG5cdFx0cm9vdC5UV0VFTiA9IFRXRUVOO1xuXG5cdH1cblxufSkodGhpcyk7XG4iLCIoZnVuY3Rpb24oZil7aWYodHlwZW9mIGV4cG9ydHM9PT1cIm9iamVjdFwiJiZ0eXBlb2YgbW9kdWxlIT09XCJ1bmRlZmluZWRcIil7bW9kdWxlLmV4cG9ydHM9ZigpfWVsc2UgaWYodHlwZW9mIGRlZmluZT09PVwiZnVuY3Rpb25cIiYmZGVmaW5lLmFtZCl7ZGVmaW5lKFtdLGYpfWVsc2V7dmFyIGc7aWYodHlwZW9mIHdpbmRvdyE9PVwidW5kZWZpbmVkXCIpe2c9d2luZG93fWVsc2UgaWYodHlwZW9mIGdsb2JhbCE9PVwidW5kZWZpbmVkXCIpe2c9Z2xvYmFsfWVsc2UgaWYodHlwZW9mIHNlbGYhPT1cInVuZGVmaW5lZFwiKXtnPXNlbGZ9ZWxzZXtnPXRoaXN9Zy5XZWJWUk1hbmFnZXIgPSBmKCl9fSkoZnVuY3Rpb24oKXt2YXIgZGVmaW5lLG1vZHVsZSxleHBvcnRzO3JldHVybiAoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSh7MTpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4vKlxuICogQ29weXJpZ2h0IDIwMTUgR29vZ2xlIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG52YXIgRW1pdHRlciA9IF9kZXJlcV8oJy4vZW1pdHRlci5qcycpO1xudmFyIE1vZGVzID0gX2RlcmVxXygnLi9tb2Rlcy5qcycpO1xudmFyIFV0aWwgPSBfZGVyZXFfKCcuL3V0aWwuanMnKTtcblxuLyoqXG4gKiBFdmVyeXRoaW5nIGhhdmluZyB0byBkbyB3aXRoIHRoZSBXZWJWUiBidXR0b24uXG4gKiBFbWl0cyBhICdjbGljaycgZXZlbnQgd2hlbiBpdCdzIGNsaWNrZWQuXG4gKi9cbmZ1bmN0aW9uIEJ1dHRvbk1hbmFnZXIob3B0X3Jvb3QpIHtcbiAgdmFyIHJvb3QgPSBvcHRfcm9vdCB8fCBkb2N1bWVudC5ib2R5O1xuICB0aGlzLmxvYWRJY29uc18oKTtcblxuICAvLyBNYWtlIHRoZSBmdWxsc2NyZWVuIGJ1dHRvbi5cbiAgdmFyIGZzQnV0dG9uID0gdGhpcy5jcmVhdGVCdXR0b24oKTtcbiAgZnNCdXR0b24uc3JjID0gdGhpcy5JQ09OUy5mdWxsc2NyZWVuO1xuICBmc0J1dHRvbi50aXRsZSA9ICdGdWxsc2NyZWVuIG1vZGUnO1xuICB2YXIgcyA9IGZzQnV0dG9uLnN0eWxlO1xuICBzLmJvdHRvbSA9IDA7XG4gIHMucmlnaHQgPSAwO1xuICBmc0J1dHRvbi5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIHRoaXMuY3JlYXRlQ2xpY2tIYW5kbGVyXygnZnMnKSk7XG4gIHJvb3QuYXBwZW5kQ2hpbGQoZnNCdXR0b24pO1xuICB0aGlzLmZzQnV0dG9uID0gZnNCdXR0b247XG5cbiAgLy8gTWFrZSB0aGUgVlIgYnV0dG9uLlxuICB2YXIgdnJCdXR0b24gPSB0aGlzLmNyZWF0ZUJ1dHRvbigpO1xuICB2ckJ1dHRvbi5zcmMgPSB0aGlzLklDT05TLmNhcmRib2FyZDtcbiAgdnJCdXR0b24udGl0bGUgPSAnVmlydHVhbCByZWFsaXR5IG1vZGUnO1xuICB2YXIgcyA9IHZyQnV0dG9uLnN0eWxlO1xuICBzLmJvdHRvbSA9IDA7XG4gIHMucmlnaHQgPSAnNDhweCc7XG4gIHZyQnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5jcmVhdGVDbGlja0hhbmRsZXJfKCd2cicpKTtcbiAgcm9vdC5hcHBlbmRDaGlsZCh2ckJ1dHRvbik7XG4gIHRoaXMudnJCdXR0b24gPSB2ckJ1dHRvbjtcblxuICB0aGlzLmlzVmlzaWJsZSA9IHRydWU7XG5cbn1cbkJ1dHRvbk1hbmFnZXIucHJvdG90eXBlID0gbmV3IEVtaXR0ZXIoKTtcblxuQnV0dG9uTWFuYWdlci5wcm90b3R5cGUuY3JlYXRlQnV0dG9uID0gZnVuY3Rpb24oKSB7XG4gIHZhciBidXR0b24gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbWcnKTtcbiAgYnV0dG9uLmNsYXNzTmFtZSA9ICd3ZWJ2ci1idXR0b24nO1xuICB2YXIgcyA9IGJ1dHRvbi5zdHlsZTtcbiAgcy5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7XG4gIHMud2lkdGggPSAnMjRweCdcbiAgcy5oZWlnaHQgPSAnMjRweCc7XG4gIHMuYmFja2dyb3VuZFNpemUgPSAnY292ZXInO1xuICBzLmJhY2tncm91bmRDb2xvciA9ICd0cmFuc3BhcmVudCc7XG4gIHMuYm9yZGVyID0gMDtcbiAgcy51c2VyU2VsZWN0ID0gJ25vbmUnO1xuICBzLndlYmtpdFVzZXJTZWxlY3QgPSAnbm9uZSc7XG4gIHMuTW96VXNlclNlbGVjdCA9ICdub25lJztcbiAgcy5jdXJzb3IgPSAncG9pbnRlcic7XG4gIHMucGFkZGluZyA9ICcxMnB4JztcbiAgcy56SW5kZXggPSAxO1xuICBzLmRpc3BsYXkgPSAnbm9uZSc7XG4gIHMuYm94U2l6aW5nID0gJ2NvbnRlbnQtYm94JztcblxuICAvLyBQcmV2ZW50IGJ1dHRvbiBmcm9tIGJlaW5nIHNlbGVjdGVkIGFuZCBkcmFnZ2VkLlxuICBidXR0b24uZHJhZ2dhYmxlID0gZmFsc2U7XG4gIGJ1dHRvbi5hZGRFdmVudExpc3RlbmVyKCdkcmFnc3RhcnQnLCBmdW5jdGlvbihlKSB7XG4gICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICB9KTtcblxuICAvLyBTdHlsZSBpdCBvbiBob3Zlci5cbiAgYnV0dG9uLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZW50ZXInLCBmdW5jdGlvbihlKSB7XG4gICAgcy5maWx0ZXIgPSBzLndlYmtpdEZpbHRlciA9ICdkcm9wLXNoYWRvdygwIDAgNXB4IHJnYmEoMjU1LDI1NSwyNTUsMSkpJztcbiAgfSk7XG4gIGJ1dHRvbi5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWxlYXZlJywgZnVuY3Rpb24oZSkge1xuICAgIHMuZmlsdGVyID0gcy53ZWJraXRGaWx0ZXIgPSAnJztcbiAgfSk7XG4gIHJldHVybiBidXR0b247XG59O1xuXG5CdXR0b25NYW5hZ2VyLnByb3RvdHlwZS5zZXRNb2RlID0gZnVuY3Rpb24obW9kZSwgaXNWUkNvbXBhdGlibGUpIHtcbiAgaXNWUkNvbXBhdGlibGUgPSBpc1ZSQ29tcGF0aWJsZSB8fCBXZWJWUkNvbmZpZy5GT1JDRV9FTkFCTEVfVlI7XG4gIGlmICghdGhpcy5pc1Zpc2libGUpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgc3dpdGNoIChtb2RlKSB7XG4gICAgY2FzZSBNb2Rlcy5OT1JNQUw6XG4gICAgICB0aGlzLmZzQnV0dG9uLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xuICAgICAgdGhpcy5mc0J1dHRvbi5zcmMgPSB0aGlzLklDT05TLmZ1bGxzY3JlZW47XG4gICAgICB0aGlzLnZyQnV0dG9uLnN0eWxlLmRpc3BsYXkgPSAoaXNWUkNvbXBhdGlibGUgPyAnYmxvY2snIDogJ25vbmUnKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgTW9kZXMuTUFHSUNfV0lORE9XOlxuICAgICAgdGhpcy5mc0J1dHRvbi5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcbiAgICAgIHRoaXMuZnNCdXR0b24uc3JjID0gdGhpcy5JQ09OUy5leGl0RnVsbHNjcmVlbjtcbiAgICAgIHRoaXMudnJCdXR0b24uc3R5bGUuZGlzcGxheSA9ICdub25lJztcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgTW9kZXMuVlI6XG4gICAgICB0aGlzLmZzQnV0dG9uLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICB0aGlzLnZyQnV0dG9uLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICBicmVhaztcbiAgfVxuXG4gIC8vIEhhY2sgZm9yIFNhZmFyaSBNYWMvaU9TIHRvIGZvcmNlIHJlbGF5b3V0IChzdmctc3BlY2lmaWMgaXNzdWUpXG4gIC8vIGh0dHA6Ly9nb28uZ2wvaGpnUjZyXG4gIHZhciBvbGRWYWx1ZSA9IHRoaXMuZnNCdXR0b24uc3R5bGUuZGlzcGxheTtcbiAgdGhpcy5mc0J1dHRvbi5zdHlsZS5kaXNwbGF5ID0gJ2lubGluZS1ibG9jayc7XG4gIHRoaXMuZnNCdXR0b24ub2Zmc2V0SGVpZ2h0O1xuICB0aGlzLmZzQnV0dG9uLnN0eWxlLmRpc3BsYXkgPSBvbGRWYWx1ZTtcbn07XG5cbkJ1dHRvbk1hbmFnZXIucHJvdG90eXBlLnNldFZpc2liaWxpdHkgPSBmdW5jdGlvbihpc1Zpc2libGUpIHtcbiAgdGhpcy5pc1Zpc2libGUgPSBpc1Zpc2libGU7XG4gIHRoaXMuZnNCdXR0b24uc3R5bGUuZGlzcGxheSA9IGlzVmlzaWJsZSA/ICdibG9jaycgOiAnbm9uZSc7XG4gIHRoaXMudnJCdXR0b24uc3R5bGUuZGlzcGxheSA9IGlzVmlzaWJsZSA/ICdibG9jaycgOiAnbm9uZSc7XG59O1xuXG5CdXR0b25NYW5hZ2VyLnByb3RvdHlwZS5jcmVhdGVDbGlja0hhbmRsZXJfID0gZnVuY3Rpb24oZXZlbnROYW1lKSB7XG4gIHJldHVybiBmdW5jdGlvbihlKSB7XG4gICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgdGhpcy5lbWl0KGV2ZW50TmFtZSk7XG4gIH0uYmluZCh0aGlzKTtcbn07XG5cbkJ1dHRvbk1hbmFnZXIucHJvdG90eXBlLmxvYWRJY29uc18gPSBmdW5jdGlvbigpIHtcbiAgLy8gUHJlbG9hZCBzb21lIGhhcmQtY29kZWQgU1ZHLlxuICB0aGlzLklDT05TID0ge307XG4gIHRoaXMuSUNPTlMuY2FyZGJvYXJkID0gVXRpbC5iYXNlNjQoJ2ltYWdlL3N2Zyt4bWwnLCAnUEhOMlp5QjRiV3h1Y3owaWFIUjBjRG92TDNkM2R5NTNNeTV2Y21jdk1qQXdNQzl6ZG1jaUlIZHBaSFJvUFNJeU5IQjRJaUJvWldsbmFIUTlJakkwY0hnaUlIWnBaWGRDYjNnOUlqQWdNQ0F5TkNBeU5DSWdabWxzYkQwaUkwWkdSa1pHUmlJK0NpQWdJQ0E4Y0dGMGFDQmtQU0pOTWpBdU56UWdOa2d6TGpJeFF6SXVOVFVnTmlBeUlEWXVOVGNnTWlBM0xqSTRkakV3TGpRMFl6QWdMamN1TlRVZ01TNHlPQ0F4TGpJeklERXVNamhvTkM0M09XTXVOVElnTUNBdU9UWXRMak16SURFdU1UUXRMamM1YkRFdU5DMHpMalE0WXk0eU15MHVOVGt1TnprdE1TNHdNU0F4TGpRMExURXVNREZ6TVM0eU1TNDBNaUF4TGpRMUlERXVNREZzTVM0ek9TQXpMalE0WXk0eE9TNDBOaTQyTXk0M09TQXhMakV4TGpjNWFEUXVOemxqTGpjeElEQWdNUzR5TmkwdU5UY2dNUzR5TmkweExqSTRWamN1TWpoak1DMHVOeTB1TlRVdE1TNHlPQzB4TGpJMkxURXVNamg2VFRjdU5TQXhOQzQyTW1NdE1TNHhOeUF3TFRJdU1UTXRMamsxTFRJdU1UTXRNaTR4TWlBd0xURXVNVGN1T1RZdE1pNHhNeUF5TGpFekxUSXVNVE1nTVM0eE9DQXdJREl1TVRJdU9UWWdNaTR4TWlBeUxqRXpjeTB1T1RVZ01pNHhNaTB5TGpFeUlESXVNVEo2YlRrZ01HTXRNUzR4TnlBd0xUSXVNVE10TGprMUxUSXVNVE10TWk0eE1pQXdMVEV1TVRjdU9UWXRNaTR4TXlBeUxqRXpMVEl1TVROek1pNHhNaTQ1TmlBeUxqRXlJREl1TVRNdExqazFJREl1TVRJdE1pNHhNaUF5TGpFeWVpSXZQZ29nSUNBZ1BIQmhkR2dnWm1sc2JEMGlibTl1WlNJZ1pEMGlUVEFnTUdneU5IWXlORWd3VmpCNklpOCtDand2YzNablBnbz0nKTtcbiAgdGhpcy5JQ09OUy5mdWxsc2NyZWVuID0gVXRpbC5iYXNlNjQoJ2ltYWdlL3N2Zyt4bWwnLCAnUEhOMlp5QjRiV3h1Y3owaWFIUjBjRG92TDNkM2R5NTNNeTV2Y21jdk1qQXdNQzl6ZG1jaUlIZHBaSFJvUFNJeU5IQjRJaUJvWldsbmFIUTlJakkwY0hnaUlIWnBaWGRDYjNnOUlqQWdNQ0F5TkNBeU5DSWdabWxzYkQwaUkwWkdSa1pHUmlJK0NpQWdJQ0E4Y0dGMGFDQmtQU0pOTUNBd2FESTBkakkwU0RCNklpQm1hV3hzUFNKdWIyNWxJaTgrQ2lBZ0lDQThjR0YwYUNCa1BTSk5OeUF4TkVnMWRqVm9OWFl0TWtnM2RpMHplbTB0TWkwMGFESldOMmd6VmpWSU5YWTFlbTB4TWlBM2FDMHpkakpvTlhZdE5XZ3RNbll6ZWsweE5DQTFkakpvTTNZemFESldOV2d0TlhvaUx6NEtQQzl6ZG1jK0NnPT0nKTtcbiAgdGhpcy5JQ09OUy5leGl0RnVsbHNjcmVlbiA9IFV0aWwuYmFzZTY0KCdpbWFnZS9zdmcreG1sJywgJ1BITjJaeUI0Yld4dWN6MGlhSFIwY0RvdkwzZDNkeTUzTXk1dmNtY3ZNakF3TUM5emRtY2lJSGRwWkhSb1BTSXlOSEI0SWlCb1pXbG5hSFE5SWpJMGNIZ2lJSFpwWlhkQ2IzZzlJakFnTUNBeU5DQXlOQ0lnWm1sc2JEMGlJMFpHUmtaR1JpSStDaUFnSUNBOGNHRjBhQ0JrUFNKTk1DQXdhREkwZGpJMFNEQjZJaUJtYVd4c1BTSnViMjVsSWk4K0NpQWdJQ0E4Y0dGMGFDQmtQU0pOTlNBeE5tZ3pkak5vTW5ZdE5VZzFkako2YlRNdE9FZzFkakpvTlZZMVNEaDJNM3B0TmlBeE1XZ3lkaTB6YUROMkxUSm9MVFYyTlhwdE1pMHhNVlkxYUMweWRqVm9OVlk0YUMwemVpSXZQZ284TDNOMlp6NEsnKTtcbiAgdGhpcy5JQ09OUy5zZXR0aW5ncyA9IFV0aWwuYmFzZTY0KCdpbWFnZS9zdmcreG1sJywgJ1BITjJaeUI0Yld4dWN6MGlhSFIwY0RvdkwzZDNkeTUzTXk1dmNtY3ZNakF3TUM5emRtY2lJSGRwWkhSb1BTSXlOSEI0SWlCb1pXbG5hSFE5SWpJMGNIZ2lJSFpwWlhkQ2IzZzlJakFnTUNBeU5DQXlOQ0lnWm1sc2JEMGlJMFpHUmtaR1JpSStDaUFnSUNBOGNHRjBhQ0JrUFNKTk1DQXdhREkwZGpJMFNEQjZJaUJtYVd4c1BTSnViMjVsSWk4K0NpQWdJQ0E4Y0dGMGFDQmtQU0pOTVRrdU5ETWdNVEl1T1RoakxqQTBMUzR6TWk0d055MHVOalF1TURjdExqazRjeTB1TURNdExqWTJMUzR3TnkwdU9UaHNNaTR4TVMweExqWTFZeTR4T1MwdU1UVXVNalF0TGpReUxqRXlMUzQyTkd3dE1pMHpMalEyWXkwdU1USXRMakl5TFM0ek9TMHVNeTB1TmpFdExqSXliQzB5TGpRNUlERmpMUzQxTWkwdU5DMHhMakE0TFM0M015MHhMalk1TFM0NU9Hd3RMak00TFRJdU5qVkRNVFF1TkRZZ01pNHhPQ0F4TkM0eU5TQXlJREUwSURKb0xUUmpMUzR5TlNBd0xTNDBOaTR4T0MwdU5Ea3VOREpzTFM0ek9DQXlMalkxWXkwdU5qRXVNalV0TVM0eE55NDFPUzB4TGpZNUxqazRiQzB5TGpRNUxURmpMUzR5TXkwdU1Ea3RMalE1SURBdExqWXhMakl5YkMweUlETXVORFpqTFM0eE15NHlNaTB1TURjdU5Ea3VNVEl1TmpSc01pNHhNU0F4TGpZMVl5MHVNRFF1TXpJdExqQTNMalkxTFM0d055NDVPSE11TURNdU5qWXVNRGN1T1Roc0xUSXVNVEVnTVM0Mk5XTXRMakU1TGpFMUxTNHlOQzQwTWkwdU1USXVOalJzTWlBekxqUTJZeTR4TWk0eU1pNHpPUzR6TGpZeExqSXliREl1TkRrdE1XTXVOVEl1TkNBeExqQTRMamN6SURFdU5qa3VPVGhzTGpNNElESXVOalZqTGpBekxqSTBMakkwTGpReUxqUTVMalF5YURSakxqSTFJREFnTGpRMkxTNHhPQzQwT1MwdU5ESnNMak00TFRJdU5qVmpMall4TFM0eU5TQXhMakUzTFM0MU9TQXhMalk1TFM0NU9Hd3lMalE1SURGakxqSXpMakE1TGpRNUlEQWdMall4TFM0eU1td3lMVE11TkRaakxqRXlMUzR5TWk0d055MHVORGt0TGpFeUxTNDJOR3d0TWk0eE1TMHhMalkxZWsweE1pQXhOUzQxWXkweExqa3pJREF0TXk0MUxURXVOVGN0TXk0MUxUTXVOWE14TGpVM0xUTXVOU0F6TGpVdE15NDFJRE11TlNBeExqVTNJRE11TlNBekxqVXRNUzQxTnlBekxqVXRNeTQxSURNdU5Yb2lMejRLUEM5emRtYytDZz09Jyk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IEJ1dHRvbk1hbmFnZXI7XG5cbn0se1wiLi9lbWl0dGVyLmpzXCI6MixcIi4vbW9kZXMuanNcIjozLFwiLi91dGlsLmpzXCI6NH1dLDI6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuLypcbiAqIENvcHlyaWdodCAyMDE1IEdvb2dsZSBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuZnVuY3Rpb24gRW1pdHRlcigpIHtcbiAgdGhpcy5jYWxsYmFja3MgPSB7fTtcbn1cblxuRW1pdHRlci5wcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uKGV2ZW50TmFtZSkge1xuICB2YXIgY2FsbGJhY2tzID0gdGhpcy5jYWxsYmFja3NbZXZlbnROYW1lXTtcbiAgaWYgKCFjYWxsYmFja3MpIHtcbiAgICAvL2NvbnNvbGUubG9nKCdObyB2YWxpZCBjYWxsYmFjayBzcGVjaWZpZWQuJyk7XG4gICAgcmV0dXJuO1xuICB9XG4gIHZhciBhcmdzID0gW10uc2xpY2UuY2FsbChhcmd1bWVudHMpO1xuICAvLyBFbGltaW5hdGUgdGhlIGZpcnN0IHBhcmFtICh0aGUgY2FsbGJhY2spLlxuICBhcmdzLnNoaWZ0KCk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgY2FsbGJhY2tzLmxlbmd0aDsgaSsrKSB7XG4gICAgY2FsbGJhY2tzW2ldLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICB9XG59O1xuXG5FbWl0dGVyLnByb3RvdHlwZS5vbiA9IGZ1bmN0aW9uKGV2ZW50TmFtZSwgY2FsbGJhY2spIHtcbiAgaWYgKGV2ZW50TmFtZSBpbiB0aGlzLmNhbGxiYWNrcykge1xuICAgIHRoaXMuY2FsbGJhY2tzW2V2ZW50TmFtZV0ucHVzaChjYWxsYmFjayk7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5jYWxsYmFja3NbZXZlbnROYW1lXSA9IFtjYWxsYmFja107XG4gIH1cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gRW1pdHRlcjtcblxufSx7fV0sMzpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4vKlxuICogQ29weXJpZ2h0IDIwMTUgR29vZ2xlIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG52YXIgTW9kZXMgPSB7XG4gIFVOS05PV046IDAsXG4gIC8vIE5vdCBmdWxsc2NyZWVuLCBqdXN0IHRyYWNraW5nLlxuICBOT1JNQUw6IDEsXG4gIC8vIE1hZ2ljIHdpbmRvdyBpbW1lcnNpdmUgbW9kZS5cbiAgTUFHSUNfV0lORE9XOiAyLFxuICAvLyBGdWxsIHNjcmVlbiBzcGxpdCBzY3JlZW4gVlIgbW9kZS5cbiAgVlI6IDMsXG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IE1vZGVzO1xuXG59LHt9XSw0OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcbi8qXG4gKiBDb3B5cmlnaHQgMjAxNSBHb29nbGUgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbnZhciBVdGlsID0ge307XG5cblV0aWwuYmFzZTY0ID0gZnVuY3Rpb24obWltZVR5cGUsIGJhc2U2NCkge1xuICByZXR1cm4gJ2RhdGE6JyArIG1pbWVUeXBlICsgJztiYXNlNjQsJyArIGJhc2U2NDtcbn07XG5cblV0aWwuaXNNb2JpbGUgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGNoZWNrID0gZmFsc2U7XG4gIChmdW5jdGlvbihhKXtpZigvKGFuZHJvaWR8YmJcXGQrfG1lZWdvKS4rbW9iaWxlfGF2YW50Z298YmFkYVxcL3xibGFja2JlcnJ5fGJsYXplcnxjb21wYWx8ZWxhaW5lfGZlbm5lY3xoaXB0b3B8aWVtb2JpbGV8aXAoaG9uZXxvZCl8aXJpc3xraW5kbGV8bGdlIHxtYWVtb3xtaWRwfG1tcHxtb2JpbGUuK2ZpcmVmb3h8bmV0ZnJvbnR8b3BlcmEgbShvYnxpbilpfHBhbG0oIG9zKT98cGhvbmV8cChpeGl8cmUpXFwvfHBsdWNrZXJ8cG9ja2V0fHBzcHxzZXJpZXMoNHw2KTB8c3ltYmlhbnx0cmVvfHVwXFwuKGJyb3dzZXJ8bGluayl8dm9kYWZvbmV8d2FwfHdpbmRvd3MgY2V8eGRhfHhpaW5vL2kudGVzdChhKXx8LzEyMDd8NjMxMHw2NTkwfDNnc298NHRocHw1MFsxLTZdaXw3NzBzfDgwMnN8YSB3YXxhYmFjfGFjKGVyfG9vfHNcXC0pfGFpKGtvfHJuKXxhbChhdnxjYXxjbyl8YW1vaXxhbihleHxueXx5dyl8YXB0dXxhcihjaHxnbyl8YXModGV8dXMpfGF0dHd8YXUoZGl8XFwtbXxyIHxzICl8YXZhbnxiZShja3xsbHxucSl8YmkobGJ8cmQpfGJsKGFjfGF6KXxicihlfHYpd3xidW1ifGJ3XFwtKG58dSl8YzU1XFwvfGNhcGl8Y2N3YXxjZG1cXC18Y2VsbHxjaHRtfGNsZGN8Y21kXFwtfGNvKG1wfG5kKXxjcmF3fGRhKGl0fGxsfG5nKXxkYnRlfGRjXFwtc3xkZXZpfGRpY2F8ZG1vYnxkbyhjfHApb3xkcygxMnxcXC1kKXxlbCg0OXxhaSl8ZW0obDJ8dWwpfGVyKGljfGswKXxlc2w4fGV6KFs0LTddMHxvc3x3YXx6ZSl8ZmV0Y3xmbHkoXFwtfF8pfGcxIHV8ZzU2MHxnZW5lfGdmXFwtNXxnXFwtbW98Z28oXFwud3xvZCl8Z3IoYWR8dW4pfGhhaWV8aGNpdHxoZFxcLShtfHB8dCl8aGVpXFwtfGhpKHB0fHRhKXxocCggaXxpcCl8aHNcXC1jfGh0KGMoXFwtfCB8X3xhfGd8cHxzfHQpfHRwKXxodShhd3x0Yyl8aVxcLSgyMHxnb3xtYSl8aTIzMHxpYWMoIHxcXC18XFwvKXxpYnJvfGlkZWF8aWcwMXxpa29tfGltMWt8aW5ub3xpcGFxfGlyaXN8amEodHx2KWF8amJyb3xqZW11fGppZ3N8a2RkaXxrZWppfGtndCggfFxcLyl8a2xvbnxrcHQgfGt3Y1xcLXxreW8oY3xrKXxsZShub3x4aSl8bGcoIGd8XFwvKGt8bHx1KXw1MHw1NHxcXC1bYS13XSl8bGlid3xseW54fG0xXFwtd3xtM2dhfG01MFxcL3xtYSh0ZXx1aXx4byl8bWMoMDF8MjF8Y2EpfG1cXC1jcnxtZShyY3xyaSl8bWkobzh8b2F8dHMpfG1tZWZ8bW8oMDF8MDJ8Yml8ZGV8ZG98dChcXC18IHxvfHYpfHp6KXxtdCg1MHxwMXx2ICl8bXdicHxteXdhfG4xMFswLTJdfG4yMFsyLTNdfG4zMCgwfDIpfG41MCgwfDJ8NSl8bjcoMCgwfDEpfDEwKXxuZSgoY3xtKVxcLXxvbnx0Znx3Znx3Z3x3dCl8bm9rKDZ8aSl8bnpwaHxvMmltfG9wKHRpfHd2KXxvcmFufG93ZzF8cDgwMHxwYW4oYXxkfHQpfHBkeGd8cGcoMTN8XFwtKFsxLThdfGMpKXxwaGlsfHBpcmV8cGwoYXl8dWMpfHBuXFwtMnxwbyhja3xydHxzZSl8cHJveHxwc2lvfHB0XFwtZ3xxYVxcLWF8cWMoMDd8MTJ8MjF8MzJ8NjB8XFwtWzItN118aVxcLSl8cXRla3xyMzgwfHI2MDB8cmFrc3xyaW05fHJvKHZlfHpvKXxzNTVcXC98c2EoZ2V8bWF8bW18bXN8bnl8dmEpfHNjKDAxfGhcXC18b298cFxcLSl8c2RrXFwvfHNlKGMoXFwtfDB8MSl8NDd8bWN8bmR8cmkpfHNnaFxcLXxzaGFyfHNpZShcXC18bSl8c2tcXC0wfHNsKDQ1fGlkKXxzbShhbHxhcnxiM3xpdHx0NSl8c28oZnR8bnkpfHNwKDAxfGhcXC18dlxcLXx2ICl8c3koMDF8bWIpfHQyKDE4fDUwKXx0NigwMHwxMHwxOCl8dGEoZ3R8bGspfHRjbFxcLXx0ZGdcXC18dGVsKGl8bSl8dGltXFwtfHRcXC1tb3x0byhwbHxzaCl8dHMoNzB8bVxcLXxtM3xtNSl8dHhcXC05fHVwKFxcLmJ8ZzF8c2kpfHV0c3R8djQwMHx2NzUwfHZlcml8dmkocmd8dGUpfHZrKDQwfDVbMC0zXXxcXC12KXx2bTQwfHZvZGF8dnVsY3x2eCg1Mnw1M3w2MHw2MXw3MHw4MHw4MXw4M3w4NXw5OCl8dzNjKFxcLXwgKXx3ZWJjfHdoaXR8d2koZyB8bmN8bncpfHdtbGJ8d29udXx4NzAwfHlhc1xcLXx5b3VyfHpldG98enRlXFwtL2kudGVzdChhLnN1YnN0cigwLDQpKSljaGVjayA9IHRydWV9KShuYXZpZ2F0b3IudXNlckFnZW50fHxuYXZpZ2F0b3IudmVuZG9yfHx3aW5kb3cub3BlcmEpO1xuICByZXR1cm4gY2hlY2s7XG59O1xuXG5VdGlsLmlzRmlyZWZveCA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gL2ZpcmVmb3gvaS50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpO1xufTtcblxuVXRpbC5pc0lPUyA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gLyhpUGFkfGlQaG9uZXxpUG9kKS9nLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCk7XG59O1xuXG5VdGlsLmlzSUZyYW1lID0gZnVuY3Rpb24oKSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIHdpbmRvdy5zZWxmICE9PSB3aW5kb3cudG9wO1xuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbn07XG5cblV0aWwuYXBwZW5kUXVlcnlQYXJhbWV0ZXIgPSBmdW5jdGlvbih1cmwsIGtleSwgdmFsdWUpIHtcbiAgLy8gRGV0ZXJtaW5lIGRlbGltaXRlciBiYXNlZCBvbiBpZiB0aGUgVVJMIGFscmVhZHkgR0VUIHBhcmFtZXRlcnMgaW4gaXQuXG4gIHZhciBkZWxpbWl0ZXIgPSAodXJsLmluZGV4T2YoJz8nKSA8IDAgPyAnPycgOiAnJicpO1xuICB1cmwgKz0gZGVsaW1pdGVyICsga2V5ICsgJz0nICsgdmFsdWU7XG4gIHJldHVybiB1cmw7XG59O1xuXG4vLyBGcm9tIGh0dHA6Ly9nb28uZ2wvNFdYM3RnXG5VdGlsLmdldFF1ZXJ5UGFyYW1ldGVyID0gZnVuY3Rpb24obmFtZSkge1xuICB2YXIgbmFtZSA9IG5hbWUucmVwbGFjZSgvW1xcW10vLCBcIlxcXFxbXCIpLnJlcGxhY2UoL1tcXF1dLywgXCJcXFxcXVwiKTtcbiAgdmFyIHJlZ2V4ID0gbmV3IFJlZ0V4cChcIltcXFxcPyZdXCIgKyBuYW1lICsgXCI9KFteJiNdKilcIiksXG4gICAgICByZXN1bHRzID0gcmVnZXguZXhlYyhsb2NhdGlvbi5zZWFyY2gpO1xuICByZXR1cm4gcmVzdWx0cyA9PT0gbnVsbCA/IFwiXCIgOiBkZWNvZGVVUklDb21wb25lbnQocmVzdWx0c1sxXS5yZXBsYWNlKC9cXCsvZywgXCIgXCIpKTtcbn07XG5cblV0aWwuaXNMYW5kc2NhcGVNb2RlID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiAod2luZG93Lm9yaWVudGF0aW9uID09IDkwIHx8IHdpbmRvdy5vcmllbnRhdGlvbiA9PSAtOTApO1xufTtcblxuVXRpbC5nZXRTY3JlZW5XaWR0aCA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gTWF0aC5tYXgod2luZG93LnNjcmVlbi53aWR0aCwgd2luZG93LnNjcmVlbi5oZWlnaHQpICpcbiAgICAgIHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvO1xufTtcblxuVXRpbC5nZXRTY3JlZW5IZWlnaHQgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIE1hdGgubWluKHdpbmRvdy5zY3JlZW4ud2lkdGgsIHdpbmRvdy5zY3JlZW4uaGVpZ2h0KSAqXG4gICAgICB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbztcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gVXRpbDtcblxufSx7fV0sNTpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4vKlxuICogQ29weXJpZ2h0IDIwMTUgR29vZ2xlIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG52YXIgQnV0dG9uTWFuYWdlciA9IF9kZXJlcV8oJy4vYnV0dG9uLW1hbmFnZXIuanMnKTtcbnZhciBFbWl0dGVyID0gX2RlcmVxXygnLi9lbWl0dGVyLmpzJyk7XG52YXIgTW9kZXMgPSBfZGVyZXFfKCcuL21vZGVzLmpzJyk7XG52YXIgVXRpbCA9IF9kZXJlcV8oJy4vdXRpbC5qcycpO1xuXG4vKipcbiAqIEhlbHBlciBmb3IgZ2V0dGluZyBpbiBhbmQgb3V0IG9mIFZSIG1vZGUuXG4gKi9cbmZ1bmN0aW9uIFdlYlZSTWFuYWdlcihyZW5kZXJlciwgZWZmZWN0LCBwYXJhbXMpIHtcbiAgdGhpcy5wYXJhbXMgPSBwYXJhbXMgfHwge307XG5cbiAgdGhpcy5tb2RlID0gTW9kZXMuVU5LTk9XTjtcblxuICAvLyBTZXQgb3B0aW9uIHRvIGhpZGUgdGhlIGJ1dHRvbi5cbiAgdGhpcy5oaWRlQnV0dG9uID0gdGhpcy5wYXJhbXMuaGlkZUJ1dHRvbiB8fCBmYWxzZTtcbiAgLy8gV2hldGhlciBvciBub3QgdGhlIEZPViBzaG91bGQgYmUgZGlzdG9ydGVkIG9yIHVuLWRpc3RvcnRlZC4gQnkgZGVmYXVsdCwgaXRcbiAgLy8gc2hvdWxkIGJlIGRpc3RvcnRlZCwgYnV0IGluIHRoZSBjYXNlIG9mIHZlcnRleCBzaGFkZXIgYmFzZWQgZGlzdG9ydGlvbixcbiAgLy8gZW5zdXJlIHRoYXQgd2UgdXNlIHVuZGlzdG9ydGVkIHBhcmFtZXRlcnMuXG4gIHRoaXMucHJlZGlzdG9ydGVkID0gISF0aGlzLnBhcmFtcy5wcmVkaXN0b3J0ZWQ7XG5cbiAgLy8gU2F2ZSB0aGUgVEhSRUUuanMgcmVuZGVyZXIgYW5kIGVmZmVjdCBmb3IgbGF0ZXIuXG4gIHRoaXMucmVuZGVyZXIgPSByZW5kZXJlcjtcbiAgdGhpcy5lZmZlY3QgPSBlZmZlY3Q7XG4gIHZhciBwb2x5ZmlsbFdyYXBwZXIgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcud2VidnItcG9seWZpbGwtZnVsbHNjcmVlbi13cmFwcGVyJyk7XG4gIHRoaXMuYnV0dG9uID0gbmV3IEJ1dHRvbk1hbmFnZXIocG9seWZpbGxXcmFwcGVyKTtcblxuICB0aGlzLmlzRnVsbHNjcmVlbkRpc2FibGVkID0gISFVdGlsLmdldFF1ZXJ5UGFyYW1ldGVyKCdub19mdWxsc2NyZWVuJyk7XG4gIHRoaXMuc3RhcnRNb2RlID0gTW9kZXMuTk9STUFMO1xuICB2YXIgc3RhcnRNb2RlUGFyYW0gPSBwYXJzZUludChVdGlsLmdldFF1ZXJ5UGFyYW1ldGVyKCdzdGFydF9tb2RlJykpO1xuICBpZiAoIWlzTmFOKHN0YXJ0TW9kZVBhcmFtKSkge1xuICAgIHRoaXMuc3RhcnRNb2RlID0gc3RhcnRNb2RlUGFyYW07XG4gIH1cblxuICBpZiAodGhpcy5oaWRlQnV0dG9uKSB7XG4gICAgdGhpcy5idXR0b24uc2V0VmlzaWJpbGl0eShmYWxzZSk7XG4gIH1cblxuICAvLyBDaGVjayBpZiB0aGUgYnJvd3NlciBpcyBjb21wYXRpYmxlIHdpdGggV2ViVlIuXG4gIHRoaXMuZ2V0RGV2aWNlQnlUeXBlXyhWUkRpc3BsYXkpLnRoZW4oZnVuY3Rpb24oaG1kKSB7XG4gICAgdGhpcy5obWQgPSBobWQ7XG5cbiAgICAvLyBPbmx5IGVuYWJsZSBWUiBtb2RlIGlmIHRoZXJlJ3MgYSBWUiBkZXZpY2UgYXR0YWNoZWQgb3Igd2UgYXJlIHJ1bm5pbmcgdGhlXG4gICAgLy8gcG9seWZpbGwgb24gbW9iaWxlLlxuICAgIGlmICghdGhpcy5pc1ZSQ29tcGF0aWJsZU92ZXJyaWRlKSB7XG4gICAgICB0aGlzLmlzVlJDb21wYXRpYmxlID0gICFobWQuaXNQb2x5ZmlsbGVkIHx8IFV0aWwuaXNNb2JpbGUoKTtcbiAgICB9XG5cbiAgICBzd2l0Y2ggKHRoaXMuc3RhcnRNb2RlKSB7XG4gICAgICBjYXNlIE1vZGVzLk1BR0lDX1dJTkRPVzpcbiAgICAgICAgdGhpcy5zZXRNb2RlXyhNb2Rlcy5NQUdJQ19XSU5ET1cpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgTW9kZXMuVlI6XG4gICAgICAgIHRoaXMuZW50ZXJWUk1vZGVfKCk7XG4gICAgICAgIHRoaXMuc2V0TW9kZV8oTW9kZXMuVlIpO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRoaXMuc2V0TW9kZV8oTW9kZXMuTk9STUFMKTtcbiAgICB9XG5cbiAgICB0aGlzLmVtaXQoJ2luaXRpYWxpemVkJyk7XG4gIH0uYmluZCh0aGlzKSk7XG5cbiAgLy8gSG9vayB1cCBidXR0b24gbGlzdGVuZXJzLlxuICB0aGlzLmJ1dHRvbi5vbignZnMnLCB0aGlzLm9uRlNDbGlja18uYmluZCh0aGlzKSk7XG4gIHRoaXMuYnV0dG9uLm9uKCd2cicsIHRoaXMub25WUkNsaWNrXy5iaW5kKHRoaXMpKTtcblxuICAvLyBCaW5kIHRvIGZ1bGxzY3JlZW4gZXZlbnRzLlxuICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCd3ZWJraXRmdWxsc2NyZWVuY2hhbmdlJyxcbiAgICAgIHRoaXMub25GdWxsc2NyZWVuQ2hhbmdlXy5iaW5kKHRoaXMpKTtcbiAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignbW96ZnVsbHNjcmVlbmNoYW5nZScsXG4gICAgICB0aGlzLm9uRnVsbHNjcmVlbkNoYW5nZV8uYmluZCh0aGlzKSk7XG4gIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ21zZnVsbHNjcmVlbmNoYW5nZScsXG4gICAgICB0aGlzLm9uRnVsbHNjcmVlbkNoYW5nZV8uYmluZCh0aGlzKSk7XG5cbiAgLy8gQmluZCB0byBWUiogc3BlY2lmaWMgZXZlbnRzLlxuICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigndnJkaXNwbGF5cHJlc2VudGNoYW5nZScsXG4gICAgICB0aGlzLm9uVlJEaXNwbGF5UHJlc2VudENoYW5nZV8uYmluZCh0aGlzKSk7XG4gIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCd2cmRpc3BsYXlkZXZpY2VwYXJhbXNjaGFuZ2UnLFxuICAgICAgdGhpcy5vblZSRGlzcGxheURldmljZVBhcmFtc0NoYW5nZV8uYmluZCh0aGlzKSk7XG59XG5cbldlYlZSTWFuYWdlci5wcm90b3R5cGUgPSBuZXcgRW1pdHRlcigpO1xuXG4vLyBFeHBvc2UgdGhlc2UgdmFsdWVzIGV4dGVybmFsbHkuXG5XZWJWUk1hbmFnZXIuTW9kZXMgPSBNb2RlcztcblxuV2ViVlJNYW5hZ2VyLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbihzY2VuZSwgY2FtZXJhLCB0aW1lc3RhbXApIHtcbiAgLy8gU2NlbmUgbWF5IGJlIGFuIGFycmF5IG9mIHR3byBzY2VuZXMsIG9uZSBmb3IgZWFjaCBleWUuXG4gIGlmIChzY2VuZSBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgdGhpcy5lZmZlY3QucmVuZGVyKHNjZW5lWzBdLCBjYW1lcmEpO1xuICB9IGVsc2Uge1xuICAgIHRoaXMuZWZmZWN0LnJlbmRlcihzY2VuZSwgY2FtZXJhKTtcbiAgfVxufTtcblxuV2ViVlJNYW5hZ2VyLnByb3RvdHlwZS5zZXRWUkNvbXBhdGlibGVPdmVycmlkZSA9IGZ1bmN0aW9uKGlzVlJDb21wYXRpYmxlKSB7XG4gIHRoaXMuaXNWUkNvbXBhdGlibGUgPSBpc1ZSQ29tcGF0aWJsZTtcbiAgdGhpcy5pc1ZSQ29tcGF0aWJsZU92ZXJyaWRlID0gdHJ1ZTtcblxuICAvLyBEb24ndCBhY3R1YWxseSBjaGFuZ2UgbW9kZXMsIGp1c3QgdXBkYXRlIHRoZSBidXR0b25zLlxuICB0aGlzLmJ1dHRvbi5zZXRNb2RlKHRoaXMubW9kZSwgdGhpcy5pc1ZSQ29tcGF0aWJsZSk7XG59O1xuXG5XZWJWUk1hbmFnZXIucHJvdG90eXBlLnNldEZ1bGxzY3JlZW5DYWxsYmFjayA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gIHRoaXMuZnVsbHNjcmVlbkNhbGxiYWNrID0gY2FsbGJhY2s7XG59O1xuXG5XZWJWUk1hbmFnZXIucHJvdG90eXBlLnNldFZSQ2FsbGJhY2sgPSBmdW5jdGlvbihjYWxsYmFjaykge1xuICB0aGlzLnZyQ2FsbGJhY2sgPSBjYWxsYmFjaztcbn07XG5cbldlYlZSTWFuYWdlci5wcm90b3R5cGUuc2V0RXhpdEZ1bGxzY3JlZW5DYWxsYmFjayA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gIHRoaXMuZXhpdEZ1bGxzY3JlZW5DYWxsYmFjayA9IGNhbGxiYWNrO1xufVxuXG4vKipcbiAqIFByb21pc2UgcmV0dXJucyB0cnVlIGlmIHRoZXJlIGlzIGF0IGxlYXN0IG9uZSBITUQgZGV2aWNlIGF2YWlsYWJsZS5cbiAqL1xuV2ViVlJNYW5hZ2VyLnByb3RvdHlwZS5nZXREZXZpY2VCeVR5cGVfID0gZnVuY3Rpb24odHlwZSkge1xuICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgbmF2aWdhdG9yLmdldFZSRGlzcGxheXMoKS50aGVuKGZ1bmN0aW9uKGRpc3BsYXlzKSB7XG4gICAgICAvLyBQcm9taXNlIHN1Y2NlZWRzLCBidXQgY2hlY2sgaWYgdGhlcmUgYXJlIGFueSBkaXNwbGF5cyBhY3R1YWxseS5cbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZGlzcGxheXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaWYgKGRpc3BsYXlzW2ldIGluc3RhbmNlb2YgdHlwZSkge1xuICAgICAgICAgIHJlc29sdmUoZGlzcGxheXNbaV0pO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXNvbHZlKG51bGwpO1xuICAgIH0sIGZ1bmN0aW9uKCkge1xuICAgICAgLy8gTm8gZGlzcGxheXMgYXJlIGZvdW5kLlxuICAgICAgcmVzb2x2ZShudWxsKTtcbiAgICB9KTtcbiAgfSk7XG59O1xuXG4vKipcbiAqIEhlbHBlciBmb3IgZW50ZXJpbmcgVlIgbW9kZS5cbiAqL1xuV2ViVlJNYW5hZ2VyLnByb3RvdHlwZS5lbnRlclZSTW9kZV8gPSBmdW5jdGlvbigpIHtcbiAgdGhpcy5obWQucmVxdWVzdFByZXNlbnQoW3tcbiAgICBzb3VyY2U6IHRoaXMucmVuZGVyZXIuZG9tRWxlbWVudCxcbiAgICBwcmVkaXN0b3J0ZWQ6IHRoaXMucHJlZGlzdG9ydGVkXG4gIH1dKTtcbn07XG5cbldlYlZSTWFuYWdlci5wcm90b3R5cGUuc2V0TW9kZV8gPSBmdW5jdGlvbihtb2RlKSB7XG4gIHZhciBvbGRNb2RlID0gdGhpcy5tb2RlO1xuICBpZiAobW9kZSA9PSB0aGlzLm1vZGUpIHtcbiAgICBjb25zb2xlLndhcm4oJ05vdCBjaGFuZ2luZyBtb2RlcywgYWxyZWFkeSBpbiAlcycsIG1vZGUpO1xuICAgIHJldHVybjtcbiAgfVxuICAvLyBjb25zb2xlLmxvZygnTW9kZSBjaGFuZ2U6ICVzID0+ICVzJywgdGhpcy5tb2RlLCBtb2RlKTtcbiAgdGhpcy5tb2RlID0gbW9kZTtcbiAgdGhpcy5idXR0b24uc2V0TW9kZShtb2RlLCB0aGlzLmlzVlJDb21wYXRpYmxlKTtcblxuICAvLyBFbWl0IGFuIGV2ZW50IGluZGljYXRpbmcgdGhlIG1vZGUgY2hhbmdlZC5cbiAgdGhpcy5lbWl0KCdtb2RlY2hhbmdlJywgbW9kZSwgb2xkTW9kZSk7XG59O1xuXG4vKipcbiAqIE1haW4gYnV0dG9uIHdhcyBjbGlja2VkLlxuICovXG5XZWJWUk1hbmFnZXIucHJvdG90eXBlLm9uRlNDbGlja18gPSBmdW5jdGlvbigpIHtcbiAgc3dpdGNoICh0aGlzLm1vZGUpIHtcbiAgICBjYXNlIE1vZGVzLk5PUk1BTDpcbiAgICAgIC8vIFRPRE86IFJlbW92ZSB0aGlzIGhhY2sgaWYvd2hlbiBpT1MgZ2V0cyByZWFsIGZ1bGxzY3JlZW4gbW9kZS5cbiAgICAgIC8vIElmIHRoaXMgaXMgYW4gaWZyYW1lIG9uIGlPUywgYnJlYWsgb3V0IGFuZCBvcGVuIGluIG5vX2Z1bGxzY3JlZW4gbW9kZS5cbiAgICAgIGlmIChVdGlsLmlzSU9TKCkgJiYgVXRpbC5pc0lGcmFtZSgpKSB7XG4gICAgICAgIGlmICh0aGlzLmZ1bGxzY3JlZW5DYWxsYmFjaykge1xuICAgICAgICAgIHRoaXMuZnVsbHNjcmVlbkNhbGxiYWNrKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmFyIHVybCA9IHdpbmRvdy5sb2NhdGlvbi5ocmVmO1xuICAgICAgICAgIHVybCA9IFV0aWwuYXBwZW5kUXVlcnlQYXJhbWV0ZXIodXJsLCAnbm9fZnVsbHNjcmVlbicsICd0cnVlJyk7XG4gICAgICAgICAgdXJsID0gVXRpbC5hcHBlbmRRdWVyeVBhcmFtZXRlcih1cmwsICdzdGFydF9tb2RlJywgTW9kZXMuTUFHSUNfV0lORE9XKTtcbiAgICAgICAgICB0b3AubG9jYXRpb24uaHJlZiA9IHVybDtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHRoaXMuc2V0TW9kZV8oTW9kZXMuTUFHSUNfV0lORE9XKTtcbiAgICAgIHRoaXMucmVxdWVzdEZ1bGxzY3JlZW5fKCk7XG4gICAgICBicmVhaztcbiAgICBjYXNlIE1vZGVzLk1BR0lDX1dJTkRPVzpcbiAgICAgIGlmICh0aGlzLmlzRnVsbHNjcmVlbkRpc2FibGVkKSB7XG4gICAgICAgIHdpbmRvdy5oaXN0b3J5LmJhY2soKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMuZXhpdEZ1bGxzY3JlZW5DYWxsYmFjaykge1xuICAgICAgICB0aGlzLmV4aXRGdWxsc2NyZWVuQ2FsbGJhY2soKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuc2V0TW9kZV8oTW9kZXMuTk9STUFMKTtcbiAgICAgIHRoaXMuZXhpdEZ1bGxzY3JlZW5fKCk7XG4gICAgICBicmVhaztcbiAgfVxufTtcblxuLyoqXG4gKiBUaGUgVlIgYnV0dG9uIHdhcyBjbGlja2VkLlxuICovXG5XZWJWUk1hbmFnZXIucHJvdG90eXBlLm9uVlJDbGlja18gPSBmdW5jdGlvbigpIHtcbiAgLy8gVE9ETzogUmVtb3ZlIHRoaXMgaGFjayB3aGVuIGlPUyBoYXMgZnVsbHNjcmVlbiBtb2RlLlxuICAvLyBJZiB0aGlzIGlzIGFuIGlmcmFtZSBvbiBpT1MsIGJyZWFrIG91dCBhbmQgb3BlbiBpbiBub19mdWxsc2NyZWVuIG1vZGUuXG4gIGlmICh0aGlzLm1vZGUgPT0gTW9kZXMuTk9STUFMICYmIFV0aWwuaXNJT1MoKSAmJiBVdGlsLmlzSUZyYW1lKCkpIHtcbiAgICBpZiAodGhpcy52ckNhbGxiYWNrKSB7XG4gICAgICB0aGlzLnZyQ2FsbGJhY2soKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIHVybCA9IHdpbmRvdy5sb2NhdGlvbi5ocmVmO1xuICAgICAgdXJsID0gVXRpbC5hcHBlbmRRdWVyeVBhcmFtZXRlcih1cmwsICdub19mdWxsc2NyZWVuJywgJ3RydWUnKTtcbiAgICAgIHVybCA9IFV0aWwuYXBwZW5kUXVlcnlQYXJhbWV0ZXIodXJsLCAnc3RhcnRfbW9kZScsIE1vZGVzLlZSKTtcbiAgICAgIHRvcC5sb2NhdGlvbi5ocmVmID0gdXJsO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgfVxuICB0aGlzLmVudGVyVlJNb2RlXygpO1xufTtcblxuV2ViVlJNYW5hZ2VyLnByb3RvdHlwZS5yZXF1ZXN0RnVsbHNjcmVlbl8gPSBmdW5jdGlvbigpIHtcbiAgdmFyIGNhbnZhcyA9IGRvY3VtZW50LmJvZHk7XG4gIC8vdmFyIGNhbnZhcyA9IHRoaXMucmVuZGVyZXIuZG9tRWxlbWVudDtcbiAgaWYgKGNhbnZhcy5yZXF1ZXN0RnVsbHNjcmVlbikge1xuICAgIGNhbnZhcy5yZXF1ZXN0RnVsbHNjcmVlbigpO1xuICB9IGVsc2UgaWYgKGNhbnZhcy5tb3pSZXF1ZXN0RnVsbFNjcmVlbikge1xuICAgIGNhbnZhcy5tb3pSZXF1ZXN0RnVsbFNjcmVlbigpO1xuICB9IGVsc2UgaWYgKGNhbnZhcy53ZWJraXRSZXF1ZXN0RnVsbHNjcmVlbikge1xuICAgIGNhbnZhcy53ZWJraXRSZXF1ZXN0RnVsbHNjcmVlbigpO1xuICB9IGVsc2UgaWYgKGNhbnZhcy5tc1JlcXVlc3RGdWxsc2NyZWVuKSB7XG4gICAgY2FudmFzLm1zUmVxdWVzdEZ1bGxzY3JlZW4oKTtcbiAgfVxufTtcblxuV2ViVlJNYW5hZ2VyLnByb3RvdHlwZS5leGl0RnVsbHNjcmVlbl8gPSBmdW5jdGlvbigpIHtcbiAgaWYgKGRvY3VtZW50LmV4aXRGdWxsc2NyZWVuKSB7XG4gICAgZG9jdW1lbnQuZXhpdEZ1bGxzY3JlZW4oKTtcbiAgfSBlbHNlIGlmIChkb2N1bWVudC5tb3pDYW5jZWxGdWxsU2NyZWVuKSB7XG4gICAgZG9jdW1lbnQubW96Q2FuY2VsRnVsbFNjcmVlbigpO1xuICB9IGVsc2UgaWYgKGRvY3VtZW50LndlYmtpdEV4aXRGdWxsc2NyZWVuKSB7XG4gICAgZG9jdW1lbnQud2Via2l0RXhpdEZ1bGxzY3JlZW4oKTtcbiAgfSBlbHNlIGlmIChkb2N1bWVudC5tc0V4aXRGdWxsc2NyZWVuKSB7XG4gICAgZG9jdW1lbnQubXNFeGl0RnVsbHNjcmVlbigpO1xuICB9XG59O1xuXG5XZWJWUk1hbmFnZXIucHJvdG90eXBlLm9uVlJEaXNwbGF5UHJlc2VudENoYW5nZV8gPSBmdW5jdGlvbihlKSB7XG4gIGNvbnNvbGUubG9nKCdvblZSRGlzcGxheVByZXNlbnRDaGFuZ2VfJywgZSk7XG4gIGlmICh0aGlzLmhtZC5pc1ByZXNlbnRpbmcpIHtcbiAgICB0aGlzLnNldE1vZGVfKE1vZGVzLlZSKTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLnNldE1vZGVfKE1vZGVzLk5PUk1BTCk7XG4gIH1cbn07XG5cbldlYlZSTWFuYWdlci5wcm90b3R5cGUub25WUkRpc3BsYXlEZXZpY2VQYXJhbXNDaGFuZ2VfID0gZnVuY3Rpb24oZSkge1xuICBjb25zb2xlLmxvZygnb25WUkRpc3BsYXlEZXZpY2VQYXJhbXNDaGFuZ2VfJywgZSk7XG59O1xuXG5XZWJWUk1hbmFnZXIucHJvdG90eXBlLm9uRnVsbHNjcmVlbkNoYW5nZV8gPSBmdW5jdGlvbihlKSB7XG4gIC8vIElmIHdlIGxlYXZlIGZ1bGwtc2NyZWVuLCBnbyBiYWNrIHRvIG5vcm1hbCBtb2RlLlxuICBpZiAoZG9jdW1lbnQud2Via2l0RnVsbHNjcmVlbkVsZW1lbnQgPT09IG51bGwgfHxcbiAgICAgIGRvY3VtZW50Lm1vekZ1bGxTY3JlZW5FbGVtZW50ID09PSBudWxsKSB7XG4gICAgdGhpcy5zZXRNb2RlXyhNb2Rlcy5OT1JNQUwpO1xuICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFdlYlZSTWFuYWdlcjtcblxufSx7XCIuL2J1dHRvbi1tYW5hZ2VyLmpzXCI6MSxcIi4vZW1pdHRlci5qc1wiOjIsXCIuL21vZGVzLmpzXCI6MyxcIi4vdXRpbC5qc1wiOjR9XX0se30sWzVdKSg1KVxufSk7IiwiKGZ1bmN0aW9uKGYpe2lmKHR5cGVvZiBleHBvcnRzPT09XCJvYmplY3RcIiYmdHlwZW9mIG1vZHVsZSE9PVwidW5kZWZpbmVkXCIpe21vZHVsZS5leHBvcnRzPWYoKX1lbHNlIGlmKHR5cGVvZiBkZWZpbmU9PT1cImZ1bmN0aW9uXCImJmRlZmluZS5hbWQpe2RlZmluZShbXSxmKX1lbHNle3ZhciBnO2lmKHR5cGVvZiB3aW5kb3chPT1cInVuZGVmaW5lZFwiKXtnPXdpbmRvd31lbHNlIGlmKHR5cGVvZiBnbG9iYWwhPT1cInVuZGVmaW5lZFwiKXtnPWdsb2JhbH1lbHNlIGlmKHR5cGVvZiBzZWxmIT09XCJ1bmRlZmluZWRcIil7Zz1zZWxmfWVsc2V7Zz10aGlzfWcuV2ViVlJQb2x5ZmlsbCA9IGYoKX19KShmdW5jdGlvbigpe3ZhciBkZWZpbmUsbW9kdWxlLGV4cG9ydHM7cmV0dXJuIChmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyBmLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pKHsxOltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcbid1c2Ugc3RyaWN0JztcblxudmFyIGhhcyA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHlcbiAgLCBwcmVmaXggPSAnfic7XG5cbi8qKlxuICogQ29uc3RydWN0b3IgdG8gY3JlYXRlIGEgc3RvcmFnZSBmb3Igb3VyIGBFRWAgb2JqZWN0cy5cbiAqIEFuIGBFdmVudHNgIGluc3RhbmNlIGlzIGEgcGxhaW4gb2JqZWN0IHdob3NlIHByb3BlcnRpZXMgYXJlIGV2ZW50IG5hbWVzLlxuICpcbiAqIEBjb25zdHJ1Y3RvclxuICogQGFwaSBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIEV2ZW50cygpIHt9XG5cbi8vXG4vLyBXZSB0cnkgdG8gbm90IGluaGVyaXQgZnJvbSBgT2JqZWN0LnByb3RvdHlwZWAuIEluIHNvbWUgZW5naW5lcyBjcmVhdGluZyBhblxuLy8gaW5zdGFuY2UgaW4gdGhpcyB3YXkgaXMgZmFzdGVyIHRoYW4gY2FsbGluZyBgT2JqZWN0LmNyZWF0ZShudWxsKWAgZGlyZWN0bHkuXG4vLyBJZiBgT2JqZWN0LmNyZWF0ZShudWxsKWAgaXMgbm90IHN1cHBvcnRlZCB3ZSBwcmVmaXggdGhlIGV2ZW50IG5hbWVzIHdpdGggYVxuLy8gY2hhcmFjdGVyIHRvIG1ha2Ugc3VyZSB0aGF0IHRoZSBidWlsdC1pbiBvYmplY3QgcHJvcGVydGllcyBhcmUgbm90XG4vLyBvdmVycmlkZGVuIG9yIHVzZWQgYXMgYW4gYXR0YWNrIHZlY3Rvci5cbi8vXG5pZiAoT2JqZWN0LmNyZWF0ZSkge1xuICBFdmVudHMucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcblxuICAvL1xuICAvLyBUaGlzIGhhY2sgaXMgbmVlZGVkIGJlY2F1c2UgdGhlIGBfX3Byb3RvX19gIHByb3BlcnR5IGlzIHN0aWxsIGluaGVyaXRlZCBpblxuICAvLyBzb21lIG9sZCBicm93c2VycyBsaWtlIEFuZHJvaWQgNCwgaVBob25lIDUuMSwgT3BlcmEgMTEgYW5kIFNhZmFyaSA1LlxuICAvL1xuICBpZiAoIW5ldyBFdmVudHMoKS5fX3Byb3RvX18pIHByZWZpeCA9IGZhbHNlO1xufVxuXG4vKipcbiAqIFJlcHJlc2VudGF0aW9uIG9mIGEgc2luZ2xlIGV2ZW50IGxpc3RlbmVyLlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIFRoZSBsaXN0ZW5lciBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7TWl4ZWR9IGNvbnRleHQgVGhlIGNvbnRleHQgdG8gaW52b2tlIHRoZSBsaXN0ZW5lciB3aXRoLlxuICogQHBhcmFtIHtCb29sZWFufSBbb25jZT1mYWxzZV0gU3BlY2lmeSBpZiB0aGUgbGlzdGVuZXIgaXMgYSBvbmUtdGltZSBsaXN0ZW5lci5cbiAqIEBjb25zdHJ1Y3RvclxuICogQGFwaSBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIEVFKGZuLCBjb250ZXh0LCBvbmNlKSB7XG4gIHRoaXMuZm4gPSBmbjtcbiAgdGhpcy5jb250ZXh0ID0gY29udGV4dDtcbiAgdGhpcy5vbmNlID0gb25jZSB8fCBmYWxzZTtcbn1cblxuLyoqXG4gKiBNaW5pbWFsIGBFdmVudEVtaXR0ZXJgIGludGVyZmFjZSB0aGF0IGlzIG1vbGRlZCBhZ2FpbnN0IHRoZSBOb2RlLmpzXG4gKiBgRXZlbnRFbWl0dGVyYCBpbnRlcmZhY2UuXG4gKlxuICogQGNvbnN0cnVjdG9yXG4gKiBAYXBpIHB1YmxpY1xuICovXG5mdW5jdGlvbiBFdmVudEVtaXR0ZXIoKSB7XG4gIHRoaXMuX2V2ZW50cyA9IG5ldyBFdmVudHMoKTtcbiAgdGhpcy5fZXZlbnRzQ291bnQgPSAwO1xufVxuXG4vKipcbiAqIFJldHVybiBhbiBhcnJheSBsaXN0aW5nIHRoZSBldmVudHMgZm9yIHdoaWNoIHRoZSBlbWl0dGVyIGhhcyByZWdpc3RlcmVkXG4gKiBsaXN0ZW5lcnMuXG4gKlxuICogQHJldHVybnMge0FycmF5fVxuICogQGFwaSBwdWJsaWNcbiAqL1xuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5ldmVudE5hbWVzID0gZnVuY3Rpb24gZXZlbnROYW1lcygpIHtcbiAgdmFyIG5hbWVzID0gW11cbiAgICAsIGV2ZW50c1xuICAgICwgbmFtZTtcblxuICBpZiAodGhpcy5fZXZlbnRzQ291bnQgPT09IDApIHJldHVybiBuYW1lcztcblxuICBmb3IgKG5hbWUgaW4gKGV2ZW50cyA9IHRoaXMuX2V2ZW50cykpIHtcbiAgICBpZiAoaGFzLmNhbGwoZXZlbnRzLCBuYW1lKSkgbmFtZXMucHVzaChwcmVmaXggPyBuYW1lLnNsaWNlKDEpIDogbmFtZSk7XG4gIH1cblxuICBpZiAoT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scykge1xuICAgIHJldHVybiBuYW1lcy5jb25jYXQoT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scyhldmVudHMpKTtcbiAgfVxuXG4gIHJldHVybiBuYW1lcztcbn07XG5cbi8qKlxuICogUmV0dXJuIHRoZSBsaXN0ZW5lcnMgcmVnaXN0ZXJlZCBmb3IgYSBnaXZlbiBldmVudC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ3xTeW1ib2x9IGV2ZW50IFRoZSBldmVudCBuYW1lLlxuICogQHBhcmFtIHtCb29sZWFufSBleGlzdHMgT25seSBjaGVjayBpZiB0aGVyZSBhcmUgbGlzdGVuZXJzLlxuICogQHJldHVybnMge0FycmF5fEJvb2xlYW59XG4gKiBAYXBpIHB1YmxpY1xuICovXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmxpc3RlbmVycyA9IGZ1bmN0aW9uIGxpc3RlbmVycyhldmVudCwgZXhpc3RzKSB7XG4gIHZhciBldnQgPSBwcmVmaXggPyBwcmVmaXggKyBldmVudCA6IGV2ZW50XG4gICAgLCBhdmFpbGFibGUgPSB0aGlzLl9ldmVudHNbZXZ0XTtcblxuICBpZiAoZXhpc3RzKSByZXR1cm4gISFhdmFpbGFibGU7XG4gIGlmICghYXZhaWxhYmxlKSByZXR1cm4gW107XG4gIGlmIChhdmFpbGFibGUuZm4pIHJldHVybiBbYXZhaWxhYmxlLmZuXTtcblxuICBmb3IgKHZhciBpID0gMCwgbCA9IGF2YWlsYWJsZS5sZW5ndGgsIGVlID0gbmV3IEFycmF5KGwpOyBpIDwgbDsgaSsrKSB7XG4gICAgZWVbaV0gPSBhdmFpbGFibGVbaV0uZm47XG4gIH1cblxuICByZXR1cm4gZWU7XG59O1xuXG4vKipcbiAqIENhbGxzIGVhY2ggb2YgdGhlIGxpc3RlbmVycyByZWdpc3RlcmVkIGZvciBhIGdpdmVuIGV2ZW50LlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfFN5bWJvbH0gZXZlbnQgVGhlIGV2ZW50IG5hbWUuXG4gKiBAcmV0dXJucyB7Qm9vbGVhbn0gYHRydWVgIGlmIHRoZSBldmVudCBoYWQgbGlzdGVuZXJzLCBlbHNlIGBmYWxzZWAuXG4gKiBAYXBpIHB1YmxpY1xuICovXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmVtaXQgPSBmdW5jdGlvbiBlbWl0KGV2ZW50LCBhMSwgYTIsIGEzLCBhNCwgYTUpIHtcbiAgdmFyIGV2dCA9IHByZWZpeCA/IHByZWZpeCArIGV2ZW50IDogZXZlbnQ7XG5cbiAgaWYgKCF0aGlzLl9ldmVudHNbZXZ0XSkgcmV0dXJuIGZhbHNlO1xuXG4gIHZhciBsaXN0ZW5lcnMgPSB0aGlzLl9ldmVudHNbZXZ0XVxuICAgICwgbGVuID0gYXJndW1lbnRzLmxlbmd0aFxuICAgICwgYXJnc1xuICAgICwgaTtcblxuICBpZiAobGlzdGVuZXJzLmZuKSB7XG4gICAgaWYgKGxpc3RlbmVycy5vbmNlKSB0aGlzLnJlbW92ZUxpc3RlbmVyKGV2ZW50LCBsaXN0ZW5lcnMuZm4sIHVuZGVmaW5lZCwgdHJ1ZSk7XG5cbiAgICBzd2l0Y2ggKGxlbikge1xuICAgICAgY2FzZSAxOiByZXR1cm4gbGlzdGVuZXJzLmZuLmNhbGwobGlzdGVuZXJzLmNvbnRleHQpLCB0cnVlO1xuICAgICAgY2FzZSAyOiByZXR1cm4gbGlzdGVuZXJzLmZuLmNhbGwobGlzdGVuZXJzLmNvbnRleHQsIGExKSwgdHJ1ZTtcbiAgICAgIGNhc2UgMzogcmV0dXJuIGxpc3RlbmVycy5mbi5jYWxsKGxpc3RlbmVycy5jb250ZXh0LCBhMSwgYTIpLCB0cnVlO1xuICAgICAgY2FzZSA0OiByZXR1cm4gbGlzdGVuZXJzLmZuLmNhbGwobGlzdGVuZXJzLmNvbnRleHQsIGExLCBhMiwgYTMpLCB0cnVlO1xuICAgICAgY2FzZSA1OiByZXR1cm4gbGlzdGVuZXJzLmZuLmNhbGwobGlzdGVuZXJzLmNvbnRleHQsIGExLCBhMiwgYTMsIGE0KSwgdHJ1ZTtcbiAgICAgIGNhc2UgNjogcmV0dXJuIGxpc3RlbmVycy5mbi5jYWxsKGxpc3RlbmVycy5jb250ZXh0LCBhMSwgYTIsIGEzLCBhNCwgYTUpLCB0cnVlO1xuICAgIH1cblxuICAgIGZvciAoaSA9IDEsIGFyZ3MgPSBuZXcgQXJyYXkobGVuIC0xKTsgaSA8IGxlbjsgaSsrKSB7XG4gICAgICBhcmdzW2kgLSAxXSA9IGFyZ3VtZW50c1tpXTtcbiAgICB9XG5cbiAgICBsaXN0ZW5lcnMuZm4uYXBwbHkobGlzdGVuZXJzLmNvbnRleHQsIGFyZ3MpO1xuICB9IGVsc2Uge1xuICAgIHZhciBsZW5ndGggPSBsaXN0ZW5lcnMubGVuZ3RoXG4gICAgICAsIGo7XG5cbiAgICBmb3IgKGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChsaXN0ZW5lcnNbaV0ub25jZSkgdGhpcy5yZW1vdmVMaXN0ZW5lcihldmVudCwgbGlzdGVuZXJzW2ldLmZuLCB1bmRlZmluZWQsIHRydWUpO1xuXG4gICAgICBzd2l0Y2ggKGxlbikge1xuICAgICAgICBjYXNlIDE6IGxpc3RlbmVyc1tpXS5mbi5jYWxsKGxpc3RlbmVyc1tpXS5jb250ZXh0KTsgYnJlYWs7XG4gICAgICAgIGNhc2UgMjogbGlzdGVuZXJzW2ldLmZuLmNhbGwobGlzdGVuZXJzW2ldLmNvbnRleHQsIGExKTsgYnJlYWs7XG4gICAgICAgIGNhc2UgMzogbGlzdGVuZXJzW2ldLmZuLmNhbGwobGlzdGVuZXJzW2ldLmNvbnRleHQsIGExLCBhMik7IGJyZWFrO1xuICAgICAgICBjYXNlIDQ6IGxpc3RlbmVyc1tpXS5mbi5jYWxsKGxpc3RlbmVyc1tpXS5jb250ZXh0LCBhMSwgYTIsIGEzKTsgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgaWYgKCFhcmdzKSBmb3IgKGogPSAxLCBhcmdzID0gbmV3IEFycmF5KGxlbiAtMSk7IGogPCBsZW47IGorKykge1xuICAgICAgICAgICAgYXJnc1tqIC0gMV0gPSBhcmd1bWVudHNbal07XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgbGlzdGVuZXJzW2ldLmZuLmFwcGx5KGxpc3RlbmVyc1tpXS5jb250ZXh0LCBhcmdzKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbi8qKlxuICogQWRkIGEgbGlzdGVuZXIgZm9yIGEgZ2l2ZW4gZXZlbnQuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd8U3ltYm9sfSBldmVudCBUaGUgZXZlbnQgbmFtZS5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIFRoZSBsaXN0ZW5lciBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7TWl4ZWR9IFtjb250ZXh0PXRoaXNdIFRoZSBjb250ZXh0IHRvIGludm9rZSB0aGUgbGlzdGVuZXIgd2l0aC5cbiAqIEByZXR1cm5zIHtFdmVudEVtaXR0ZXJ9IGB0aGlzYC5cbiAqIEBhcGkgcHVibGljXG4gKi9cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub24gPSBmdW5jdGlvbiBvbihldmVudCwgZm4sIGNvbnRleHQpIHtcbiAgdmFyIGxpc3RlbmVyID0gbmV3IEVFKGZuLCBjb250ZXh0IHx8IHRoaXMpXG4gICAgLCBldnQgPSBwcmVmaXggPyBwcmVmaXggKyBldmVudCA6IGV2ZW50O1xuXG4gIGlmICghdGhpcy5fZXZlbnRzW2V2dF0pIHRoaXMuX2V2ZW50c1tldnRdID0gbGlzdGVuZXIsIHRoaXMuX2V2ZW50c0NvdW50Kys7XG4gIGVsc2UgaWYgKCF0aGlzLl9ldmVudHNbZXZ0XS5mbikgdGhpcy5fZXZlbnRzW2V2dF0ucHVzaChsaXN0ZW5lcik7XG4gIGVsc2UgdGhpcy5fZXZlbnRzW2V2dF0gPSBbdGhpcy5fZXZlbnRzW2V2dF0sIGxpc3RlbmVyXTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogQWRkIGEgb25lLXRpbWUgbGlzdGVuZXIgZm9yIGEgZ2l2ZW4gZXZlbnQuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd8U3ltYm9sfSBldmVudCBUaGUgZXZlbnQgbmFtZS5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIFRoZSBsaXN0ZW5lciBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7TWl4ZWR9IFtjb250ZXh0PXRoaXNdIFRoZSBjb250ZXh0IHRvIGludm9rZSB0aGUgbGlzdGVuZXIgd2l0aC5cbiAqIEByZXR1cm5zIHtFdmVudEVtaXR0ZXJ9IGB0aGlzYC5cbiAqIEBhcGkgcHVibGljXG4gKi9cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub25jZSA9IGZ1bmN0aW9uIG9uY2UoZXZlbnQsIGZuLCBjb250ZXh0KSB7XG4gIHZhciBsaXN0ZW5lciA9IG5ldyBFRShmbiwgY29udGV4dCB8fCB0aGlzLCB0cnVlKVxuICAgICwgZXZ0ID0gcHJlZml4ID8gcHJlZml4ICsgZXZlbnQgOiBldmVudDtcblxuICBpZiAoIXRoaXMuX2V2ZW50c1tldnRdKSB0aGlzLl9ldmVudHNbZXZ0XSA9IGxpc3RlbmVyLCB0aGlzLl9ldmVudHNDb3VudCsrO1xuICBlbHNlIGlmICghdGhpcy5fZXZlbnRzW2V2dF0uZm4pIHRoaXMuX2V2ZW50c1tldnRdLnB1c2gobGlzdGVuZXIpO1xuICBlbHNlIHRoaXMuX2V2ZW50c1tldnRdID0gW3RoaXMuX2V2ZW50c1tldnRdLCBsaXN0ZW5lcl07XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFJlbW92ZSB0aGUgbGlzdGVuZXJzIG9mIGEgZ2l2ZW4gZXZlbnQuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd8U3ltYm9sfSBldmVudCBUaGUgZXZlbnQgbmFtZS5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIE9ubHkgcmVtb3ZlIHRoZSBsaXN0ZW5lcnMgdGhhdCBtYXRjaCB0aGlzIGZ1bmN0aW9uLlxuICogQHBhcmFtIHtNaXhlZH0gY29udGV4dCBPbmx5IHJlbW92ZSB0aGUgbGlzdGVuZXJzIHRoYXQgaGF2ZSB0aGlzIGNvbnRleHQuXG4gKiBAcGFyYW0ge0Jvb2xlYW59IG9uY2UgT25seSByZW1vdmUgb25lLXRpbWUgbGlzdGVuZXJzLlxuICogQHJldHVybnMge0V2ZW50RW1pdHRlcn0gYHRoaXNgLlxuICogQGFwaSBwdWJsaWNcbiAqL1xuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVMaXN0ZW5lciA9IGZ1bmN0aW9uIHJlbW92ZUxpc3RlbmVyKGV2ZW50LCBmbiwgY29udGV4dCwgb25jZSkge1xuICB2YXIgZXZ0ID0gcHJlZml4ID8gcHJlZml4ICsgZXZlbnQgOiBldmVudDtcblxuICBpZiAoIXRoaXMuX2V2ZW50c1tldnRdKSByZXR1cm4gdGhpcztcbiAgaWYgKCFmbikge1xuICAgIGlmICgtLXRoaXMuX2V2ZW50c0NvdW50ID09PSAwKSB0aGlzLl9ldmVudHMgPSBuZXcgRXZlbnRzKCk7XG4gICAgZWxzZSBkZWxldGUgdGhpcy5fZXZlbnRzW2V2dF07XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICB2YXIgbGlzdGVuZXJzID0gdGhpcy5fZXZlbnRzW2V2dF07XG5cbiAgaWYgKGxpc3RlbmVycy5mbikge1xuICAgIGlmIChcbiAgICAgICAgIGxpc3RlbmVycy5mbiA9PT0gZm5cbiAgICAgICYmICghb25jZSB8fCBsaXN0ZW5lcnMub25jZSlcbiAgICAgICYmICghY29udGV4dCB8fCBsaXN0ZW5lcnMuY29udGV4dCA9PT0gY29udGV4dClcbiAgICApIHtcbiAgICAgIGlmICgtLXRoaXMuX2V2ZW50c0NvdW50ID09PSAwKSB0aGlzLl9ldmVudHMgPSBuZXcgRXZlbnRzKCk7XG4gICAgICBlbHNlIGRlbGV0ZSB0aGlzLl9ldmVudHNbZXZ0XTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgZm9yICh2YXIgaSA9IDAsIGV2ZW50cyA9IFtdLCBsZW5ndGggPSBsaXN0ZW5lcnMubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChcbiAgICAgICAgICAgbGlzdGVuZXJzW2ldLmZuICE9PSBmblxuICAgICAgICB8fCAob25jZSAmJiAhbGlzdGVuZXJzW2ldLm9uY2UpXG4gICAgICAgIHx8IChjb250ZXh0ICYmIGxpc3RlbmVyc1tpXS5jb250ZXh0ICE9PSBjb250ZXh0KVxuICAgICAgKSB7XG4gICAgICAgIGV2ZW50cy5wdXNoKGxpc3RlbmVyc1tpXSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy9cbiAgICAvLyBSZXNldCB0aGUgYXJyYXksIG9yIHJlbW92ZSBpdCBjb21wbGV0ZWx5IGlmIHdlIGhhdmUgbm8gbW9yZSBsaXN0ZW5lcnMuXG4gICAgLy9cbiAgICBpZiAoZXZlbnRzLmxlbmd0aCkgdGhpcy5fZXZlbnRzW2V2dF0gPSBldmVudHMubGVuZ3RoID09PSAxID8gZXZlbnRzWzBdIDogZXZlbnRzO1xuICAgIGVsc2UgaWYgKC0tdGhpcy5fZXZlbnRzQ291bnQgPT09IDApIHRoaXMuX2V2ZW50cyA9IG5ldyBFdmVudHMoKTtcbiAgICBlbHNlIGRlbGV0ZSB0aGlzLl9ldmVudHNbZXZ0XTtcbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBSZW1vdmUgYWxsIGxpc3RlbmVycywgb3IgdGhvc2Ugb2YgdGhlIHNwZWNpZmllZCBldmVudC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ3xTeW1ib2x9IFtldmVudF0gVGhlIGV2ZW50IG5hbWUuXG4gKiBAcmV0dXJucyB7RXZlbnRFbWl0dGVyfSBgdGhpc2AuXG4gKiBAYXBpIHB1YmxpY1xuICovXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUFsbExpc3RlbmVycyA9IGZ1bmN0aW9uIHJlbW92ZUFsbExpc3RlbmVycyhldmVudCkge1xuICB2YXIgZXZ0O1xuXG4gIGlmIChldmVudCkge1xuICAgIGV2dCA9IHByZWZpeCA/IHByZWZpeCArIGV2ZW50IDogZXZlbnQ7XG4gICAgaWYgKHRoaXMuX2V2ZW50c1tldnRdKSB7XG4gICAgICBpZiAoLS10aGlzLl9ldmVudHNDb3VudCA9PT0gMCkgdGhpcy5fZXZlbnRzID0gbmV3IEV2ZW50cygpO1xuICAgICAgZWxzZSBkZWxldGUgdGhpcy5fZXZlbnRzW2V2dF07XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHRoaXMuX2V2ZW50cyA9IG5ldyBFdmVudHMoKTtcbiAgICB0aGlzLl9ldmVudHNDb3VudCA9IDA7XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8vXG4vLyBBbGlhcyBtZXRob2RzIG5hbWVzIGJlY2F1c2UgcGVvcGxlIHJvbGwgbGlrZSB0aGF0LlxuLy9cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUub2ZmID0gRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVMaXN0ZW5lcjtcbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuYWRkTGlzdGVuZXIgPSBFdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uO1xuXG4vL1xuLy8gVGhpcyBmdW5jdGlvbiBkb2Vzbid0IGFwcGx5IGFueW1vcmUuXG4vL1xuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5zZXRNYXhMaXN0ZW5lcnMgPSBmdW5jdGlvbiBzZXRNYXhMaXN0ZW5lcnMoKSB7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLy9cbi8vIEV4cG9zZSB0aGUgcHJlZml4LlxuLy9cbkV2ZW50RW1pdHRlci5wcmVmaXhlZCA9IHByZWZpeDtcblxuLy9cbi8vIEFsbG93IGBFdmVudEVtaXR0ZXJgIHRvIGJlIGltcG9ydGVkIGFzIG1vZHVsZSBuYW1lc3BhY2UuXG4vL1xuRXZlbnRFbWl0dGVyLkV2ZW50RW1pdHRlciA9IEV2ZW50RW1pdHRlcjtcblxuLy9cbi8vIEV4cG9zZSB0aGUgbW9kdWxlLlxuLy9cbmlmICgndW5kZWZpbmVkJyAhPT0gdHlwZW9mIG1vZHVsZSkge1xuICBtb2R1bGUuZXhwb3J0cyA9IEV2ZW50RW1pdHRlcjtcbn1cblxufSx7fV0sMjpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4ndXNlIHN0cmljdCc7XG4vKiBlc2xpbnQtZGlzYWJsZSBuby11bnVzZWQtdmFycyAqL1xudmFyIGhhc093blByb3BlcnR5ID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcbnZhciBwcm9wSXNFbnVtZXJhYmxlID0gT2JqZWN0LnByb3RvdHlwZS5wcm9wZXJ0eUlzRW51bWVyYWJsZTtcblxuZnVuY3Rpb24gdG9PYmplY3QodmFsKSB7XG5cdGlmICh2YWwgPT09IG51bGwgfHwgdmFsID09PSB1bmRlZmluZWQpIHtcblx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCdPYmplY3QuYXNzaWduIGNhbm5vdCBiZSBjYWxsZWQgd2l0aCBudWxsIG9yIHVuZGVmaW5lZCcpO1xuXHR9XG5cblx0cmV0dXJuIE9iamVjdCh2YWwpO1xufVxuXG5mdW5jdGlvbiBzaG91bGRVc2VOYXRpdmUoKSB7XG5cdHRyeSB7XG5cdFx0aWYgKCFPYmplY3QuYXNzaWduKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0Ly8gRGV0ZWN0IGJ1Z2d5IHByb3BlcnR5IGVudW1lcmF0aW9uIG9yZGVyIGluIG9sZGVyIFY4IHZlcnNpb25zLlxuXG5cdFx0Ly8gaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9NDExOFxuXHRcdHZhciB0ZXN0MSA9IG5ldyBTdHJpbmcoJ2FiYycpOyAgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXHRcdHRlc3QxWzVdID0gJ2RlJztcblx0XHRpZiAoT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXModGVzdDEpWzBdID09PSAnNScpIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cblx0XHQvLyBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvdjgvaXNzdWVzL2RldGFpbD9pZD0zMDU2XG5cdFx0dmFyIHRlc3QyID0ge307XG5cdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCAxMDsgaSsrKSB7XG5cdFx0XHR0ZXN0MlsnXycgKyBTdHJpbmcuZnJvbUNoYXJDb2RlKGkpXSA9IGk7XG5cdFx0fVxuXHRcdHZhciBvcmRlcjIgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh0ZXN0MikubWFwKGZ1bmN0aW9uIChuKSB7XG5cdFx0XHRyZXR1cm4gdGVzdDJbbl07XG5cdFx0fSk7XG5cdFx0aWYgKG9yZGVyMi5qb2luKCcnKSAhPT0gJzAxMjM0NTY3ODknKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0Ly8gaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9MzA1NlxuXHRcdHZhciB0ZXN0MyA9IHt9O1xuXHRcdCdhYmNkZWZnaGlqa2xtbm9wcXJzdCcuc3BsaXQoJycpLmZvckVhY2goZnVuY3Rpb24gKGxldHRlcikge1xuXHRcdFx0dGVzdDNbbGV0dGVyXSA9IGxldHRlcjtcblx0XHR9KTtcblx0XHRpZiAoT2JqZWN0LmtleXMoT2JqZWN0LmFzc2lnbih7fSwgdGVzdDMpKS5qb2luKCcnKSAhPT1cblx0XHRcdFx0J2FiY2RlZmdoaWprbG1ub3BxcnN0Jykge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblxuXHRcdHJldHVybiB0cnVlO1xuXHR9IGNhdGNoIChlKSB7XG5cdFx0Ly8gV2UgZG9uJ3QgZXhwZWN0IGFueSBvZiB0aGUgYWJvdmUgdG8gdGhyb3csIGJ1dCBiZXR0ZXIgdG8gYmUgc2FmZS5cblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzaG91bGRVc2VOYXRpdmUoKSA/IE9iamVjdC5hc3NpZ24gOiBmdW5jdGlvbiAodGFyZ2V0LCBzb3VyY2UpIHtcblx0dmFyIGZyb207XG5cdHZhciB0byA9IHRvT2JqZWN0KHRhcmdldCk7XG5cdHZhciBzeW1ib2xzO1xuXG5cdGZvciAodmFyIHMgPSAxOyBzIDwgYXJndW1lbnRzLmxlbmd0aDsgcysrKSB7XG5cdFx0ZnJvbSA9IE9iamVjdChhcmd1bWVudHNbc10pO1xuXG5cdFx0Zm9yICh2YXIga2V5IGluIGZyb20pIHtcblx0XHRcdGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKGZyb20sIGtleSkpIHtcblx0XHRcdFx0dG9ba2V5XSA9IGZyb21ba2V5XTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scykge1xuXHRcdFx0c3ltYm9scyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMoZnJvbSk7XG5cdFx0XHRmb3IgKHZhciBpID0gMDsgaSA8IHN5bWJvbHMubGVuZ3RoOyBpKyspIHtcblx0XHRcdFx0aWYgKHByb3BJc0VudW1lcmFibGUuY2FsbChmcm9tLCBzeW1ib2xzW2ldKSkge1xuXHRcdFx0XHRcdHRvW3N5bWJvbHNbaV1dID0gZnJvbVtzeW1ib2xzW2ldXTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHJldHVybiB0bztcbn07XG5cbn0se31dLDM6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuLypcbiAqIENvcHlyaWdodCAyMDE1IEdvb2dsZSBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxudmFyIFV0aWwgPSBfZGVyZXFfKCcuL3V0aWwuanMnKTtcbnZhciBXYWtlTG9jayA9IF9kZXJlcV8oJy4vd2FrZWxvY2suanMnKTtcblxuLy8gU3RhcnQgYXQgYSBoaWdoZXIgbnVtYmVyIHRvIHJlZHVjZSBjaGFuY2Ugb2YgY29uZmxpY3QuXG52YXIgbmV4dERpc3BsYXlJZCA9IDEwMDA7XG52YXIgaGFzU2hvd0RlcHJlY2F0aW9uV2FybmluZyA9IGZhbHNlO1xuXG52YXIgZGVmYXVsdExlZnRCb3VuZHMgPSBbMCwgMCwgMC41LCAxXTtcbnZhciBkZWZhdWx0UmlnaHRCb3VuZHMgPSBbMC41LCAwLCAwLjUsIDFdO1xuXG4vKipcbiAqIFRoZSBiYXNlIGNsYXNzIGZvciBhbGwgVlIgZnJhbWUgZGF0YS5cbiAqL1xuXG5mdW5jdGlvbiBWUkZyYW1lRGF0YSgpIHtcbiAgdGhpcy5sZWZ0UHJvamVjdGlvbk1hdHJpeCA9IG5ldyBGbG9hdDMyQXJyYXkoMTYpO1xuICB0aGlzLmxlZnRWaWV3TWF0cml4ID0gbmV3IEZsb2F0MzJBcnJheSgxNik7XG4gIHRoaXMucmlnaHRQcm9qZWN0aW9uTWF0cml4ID0gbmV3IEZsb2F0MzJBcnJheSgxNik7XG4gIHRoaXMucmlnaHRWaWV3TWF0cml4ID0gbmV3IEZsb2F0MzJBcnJheSgxNik7XG4gIHRoaXMucG9zZSA9IG51bGw7XG59O1xuXG4vKipcbiAqIFRoZSBiYXNlIGNsYXNzIGZvciBhbGwgVlIgZGlzcGxheXMuXG4gKi9cbmZ1bmN0aW9uIFZSRGlzcGxheSgpIHtcbiAgdGhpcy5pc1BvbHlmaWxsZWQgPSB0cnVlO1xuICB0aGlzLmRpc3BsYXlJZCA9IG5leHREaXNwbGF5SWQrKztcbiAgdGhpcy5kaXNwbGF5TmFtZSA9ICd3ZWJ2ci1wb2x5ZmlsbCBkaXNwbGF5TmFtZSc7XG5cbiAgdGhpcy5kZXB0aE5lYXIgPSAwLjAxO1xuICB0aGlzLmRlcHRoRmFyID0gMTAwMDAuMDtcblxuICB0aGlzLmlzQ29ubmVjdGVkID0gdHJ1ZTtcbiAgdGhpcy5pc1ByZXNlbnRpbmcgPSBmYWxzZTtcbiAgdGhpcy5jYXBhYmlsaXRpZXMgPSB7XG4gICAgaGFzUG9zaXRpb246IGZhbHNlLFxuICAgIGhhc09yaWVudGF0aW9uOiBmYWxzZSxcbiAgICBoYXNFeHRlcm5hbERpc3BsYXk6IGZhbHNlLFxuICAgIGNhblByZXNlbnQ6IGZhbHNlLFxuICAgIG1heExheWVyczogMVxuICB9O1xuICB0aGlzLnN0YWdlUGFyYW1ldGVycyA9IG51bGw7XG5cbiAgLy8gXCJQcml2YXRlXCIgbWVtYmVycy5cbiAgdGhpcy53YWl0aW5nRm9yUHJlc2VudF8gPSBmYWxzZTtcbiAgdGhpcy5sYXllcl8gPSBudWxsO1xuXG4gIHRoaXMuZnVsbHNjcmVlbkVsZW1lbnRfID0gbnVsbDtcbiAgdGhpcy5mdWxsc2NyZWVuV3JhcHBlcl8gPSBudWxsO1xuICB0aGlzLmZ1bGxzY3JlZW5FbGVtZW50Q2FjaGVkU3R5bGVfID0gbnVsbDtcblxuICB0aGlzLmZ1bGxzY3JlZW5FdmVudFRhcmdldF8gPSBudWxsO1xuICB0aGlzLmZ1bGxzY3JlZW5DaGFuZ2VIYW5kbGVyXyA9IG51bGw7XG4gIHRoaXMuZnVsbHNjcmVlbkVycm9ySGFuZGxlcl8gPSBudWxsO1xuXG4gIHRoaXMud2FrZWxvY2tfID0gbmV3IFdha2VMb2NrKCk7XG59XG5cblZSRGlzcGxheS5wcm90b3R5cGUuZ2V0RnJhbWVEYXRhID0gZnVuY3Rpb24oZnJhbWVEYXRhKSB7XG4gIC8vIFRPRE86IFRlY2huaWNhbGx5IHRoaXMgc2hvdWxkIHJldGFpbiBpdCdzIHZhbHVlIGZvciB0aGUgZHVyYXRpb24gb2YgYSBmcmFtZVxuICAvLyBidXQgSSBkb3VidCB0aGF0J3MgcHJhY3RpY2FsIHRvIGRvIGluIGphdmFzY3JpcHQuXG4gIHJldHVybiBVdGlsLmZyYW1lRGF0YUZyb21Qb3NlKGZyYW1lRGF0YSwgdGhpcy5nZXRQb3NlKCksIHRoaXMpO1xufTtcblxuVlJEaXNwbGF5LnByb3RvdHlwZS5nZXRQb3NlID0gZnVuY3Rpb24oKSB7XG4gIC8vIFRPRE86IFRlY2huaWNhbGx5IHRoaXMgc2hvdWxkIHJldGFpbiBpdCdzIHZhbHVlIGZvciB0aGUgZHVyYXRpb24gb2YgYSBmcmFtZVxuICAvLyBidXQgSSBkb3VidCB0aGF0J3MgcHJhY3RpY2FsIHRvIGRvIGluIGphdmFzY3JpcHQuXG4gIHJldHVybiB0aGlzLmdldEltbWVkaWF0ZVBvc2UoKTtcbn07XG5cblZSRGlzcGxheS5wcm90b3R5cGUucmVxdWVzdEFuaW1hdGlvbkZyYW1lID0gZnVuY3Rpb24oY2FsbGJhY2spIHtcbiAgcmV0dXJuIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoY2FsbGJhY2spO1xufTtcblxuVlJEaXNwbGF5LnByb3RvdHlwZS5jYW5jZWxBbmltYXRpb25GcmFtZSA9IGZ1bmN0aW9uKGlkKSB7XG4gIHJldHVybiB3aW5kb3cuY2FuY2VsQW5pbWF0aW9uRnJhbWUoaWQpO1xufTtcblxuVlJEaXNwbGF5LnByb3RvdHlwZS53cmFwRm9yRnVsbHNjcmVlbiA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgLy8gRG9uJ3Qgd3JhcCBpbiBpT1MuXG4gIGlmIChVdGlsLmlzSU9TKCkpIHtcbiAgICByZXR1cm4gZWxlbWVudDtcbiAgfVxuICBpZiAoIXRoaXMuZnVsbHNjcmVlbldyYXBwZXJfKSB7XG4gICAgdGhpcy5mdWxsc2NyZWVuV3JhcHBlcl8gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICB2YXIgY3NzUHJvcGVydGllcyA9IFtcbiAgICAgICdoZWlnaHQ6ICcgKyBNYXRoLm1pbihzY3JlZW4uaGVpZ2h0LCBzY3JlZW4ud2lkdGgpICsgJ3B4ICFpbXBvcnRhbnQnLFxuICAgICAgJ3RvcDogMCAhaW1wb3J0YW50JyxcbiAgICAgICdsZWZ0OiAwICFpbXBvcnRhbnQnLFxuICAgICAgJ3JpZ2h0OiAwICFpbXBvcnRhbnQnLFxuICAgICAgJ2JvcmRlcjogMCcsXG4gICAgICAnbWFyZ2luOiAwJyxcbiAgICAgICdwYWRkaW5nOiAwJyxcbiAgICAgICd6LWluZGV4OiA5OTk5OTkgIWltcG9ydGFudCcsXG4gICAgICAncG9zaXRpb246IGZpeGVkJyxcbiAgICBdO1xuICAgIHRoaXMuZnVsbHNjcmVlbldyYXBwZXJfLnNldEF0dHJpYnV0ZSgnc3R5bGUnLCBjc3NQcm9wZXJ0aWVzLmpvaW4oJzsgJykgKyAnOycpO1xuICAgIHRoaXMuZnVsbHNjcmVlbldyYXBwZXJfLmNsYXNzTGlzdC5hZGQoJ3dlYnZyLXBvbHlmaWxsLWZ1bGxzY3JlZW4td3JhcHBlcicpO1xuICB9XG5cbiAgaWYgKHRoaXMuZnVsbHNjcmVlbkVsZW1lbnRfID09IGVsZW1lbnQpIHtcbiAgICByZXR1cm4gdGhpcy5mdWxsc2NyZWVuV3JhcHBlcl87XG4gIH1cblxuICAvLyBSZW1vdmUgYW55IHByZXZpb3VzbHkgYXBwbGllZCB3cmFwcGVyc1xuICB0aGlzLnJlbW92ZUZ1bGxzY3JlZW5XcmFwcGVyKCk7XG5cbiAgdGhpcy5mdWxsc2NyZWVuRWxlbWVudF8gPSBlbGVtZW50O1xuICB2YXIgcGFyZW50ID0gdGhpcy5mdWxsc2NyZWVuRWxlbWVudF8ucGFyZW50RWxlbWVudDtcbiAgcGFyZW50Lmluc2VydEJlZm9yZSh0aGlzLmZ1bGxzY3JlZW5XcmFwcGVyXywgdGhpcy5mdWxsc2NyZWVuRWxlbWVudF8pO1xuICBwYXJlbnQucmVtb3ZlQ2hpbGQodGhpcy5mdWxsc2NyZWVuRWxlbWVudF8pO1xuICB0aGlzLmZ1bGxzY3JlZW5XcmFwcGVyXy5pbnNlcnRCZWZvcmUodGhpcy5mdWxsc2NyZWVuRWxlbWVudF8sIHRoaXMuZnVsbHNjcmVlbldyYXBwZXJfLmZpcnN0Q2hpbGQpO1xuICB0aGlzLmZ1bGxzY3JlZW5FbGVtZW50Q2FjaGVkU3R5bGVfID0gdGhpcy5mdWxsc2NyZWVuRWxlbWVudF8uZ2V0QXR0cmlidXRlKCdzdHlsZScpO1xuXG4gIHZhciBzZWxmID0gdGhpcztcbiAgZnVuY3Rpb24gYXBwbHlGdWxsc2NyZWVuRWxlbWVudFN0eWxlKCkge1xuICAgIGlmICghc2VsZi5mdWxsc2NyZWVuRWxlbWVudF8pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgY3NzUHJvcGVydGllcyA9IFtcbiAgICAgICdwb3NpdGlvbjogYWJzb2x1dGUnLFxuICAgICAgJ3RvcDogMCcsXG4gICAgICAnbGVmdDogMCcsXG4gICAgICAnd2lkdGg6ICcgKyBNYXRoLm1heChzY3JlZW4ud2lkdGgsIHNjcmVlbi5oZWlnaHQpICsgJ3B4JyxcbiAgICAgICdoZWlnaHQ6ICcgKyBNYXRoLm1pbihzY3JlZW4uaGVpZ2h0LCBzY3JlZW4ud2lkdGgpICsgJ3B4JyxcbiAgICAgICdib3JkZXI6IDAnLFxuICAgICAgJ21hcmdpbjogMCcsXG4gICAgICAncGFkZGluZzogMCcsXG4gICAgXTtcbiAgICBzZWxmLmZ1bGxzY3JlZW5FbGVtZW50Xy5zZXRBdHRyaWJ1dGUoJ3N0eWxlJywgY3NzUHJvcGVydGllcy5qb2luKCc7ICcpICsgJzsnKTtcbiAgfVxuXG4gIGFwcGx5RnVsbHNjcmVlbkVsZW1lbnRTdHlsZSgpO1xuXG4gIHJldHVybiB0aGlzLmZ1bGxzY3JlZW5XcmFwcGVyXztcbn07XG5cblZSRGlzcGxheS5wcm90b3R5cGUucmVtb3ZlRnVsbHNjcmVlbldyYXBwZXIgPSBmdW5jdGlvbigpIHtcbiAgaWYgKCF0aGlzLmZ1bGxzY3JlZW5FbGVtZW50Xykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBlbGVtZW50ID0gdGhpcy5mdWxsc2NyZWVuRWxlbWVudF87XG4gIGlmICh0aGlzLmZ1bGxzY3JlZW5FbGVtZW50Q2FjaGVkU3R5bGVfKSB7XG4gICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ3N0eWxlJywgdGhpcy5mdWxsc2NyZWVuRWxlbWVudENhY2hlZFN0eWxlXyk7XG4gIH0gZWxzZSB7XG4gICAgZWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUoJ3N0eWxlJyk7XG4gIH1cbiAgdGhpcy5mdWxsc2NyZWVuRWxlbWVudF8gPSBudWxsO1xuICB0aGlzLmZ1bGxzY3JlZW5FbGVtZW50Q2FjaGVkU3R5bGVfID0gbnVsbDtcblxuICB2YXIgcGFyZW50ID0gdGhpcy5mdWxsc2NyZWVuV3JhcHBlcl8ucGFyZW50RWxlbWVudDtcbiAgdGhpcy5mdWxsc2NyZWVuV3JhcHBlcl8ucmVtb3ZlQ2hpbGQoZWxlbWVudCk7XG4gIHBhcmVudC5pbnNlcnRCZWZvcmUoZWxlbWVudCwgdGhpcy5mdWxsc2NyZWVuV3JhcHBlcl8pO1xuICBwYXJlbnQucmVtb3ZlQ2hpbGQodGhpcy5mdWxsc2NyZWVuV3JhcHBlcl8pO1xuXG4gIHJldHVybiBlbGVtZW50O1xufTtcblxuVlJEaXNwbGF5LnByb3RvdHlwZS5yZXF1ZXN0UHJlc2VudCA9IGZ1bmN0aW9uKGxheWVycykge1xuICB2YXIgd2FzUHJlc2VudGluZyA9IHRoaXMuaXNQcmVzZW50aW5nO1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgaWYgKCEobGF5ZXJzIGluc3RhbmNlb2YgQXJyYXkpKSB7XG4gICAgaWYgKCFoYXNTaG93RGVwcmVjYXRpb25XYXJuaW5nKSB7XG4gICAgICBjb25zb2xlLndhcm4oXCJVc2luZyBhIGRlcHJlY2F0ZWQgZm9ybSBvZiByZXF1ZXN0UHJlc2VudC4gU2hvdWxkIHBhc3MgaW4gYW4gYXJyYXkgb2YgVlJMYXllcnMuXCIpO1xuICAgICAgaGFzU2hvd0RlcHJlY2F0aW9uV2FybmluZyA9IHRydWU7XG4gICAgfVxuICAgIGxheWVycyA9IFtsYXllcnNdO1xuICB9XG5cbiAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuICAgIGlmICghc2VsZi5jYXBhYmlsaXRpZXMuY2FuUHJlc2VudCkge1xuICAgICAgcmVqZWN0KG5ldyBFcnJvcignVlJEaXNwbGF5IGlzIG5vdCBjYXBhYmxlIG9mIHByZXNlbnRpbmcuJykpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChsYXllcnMubGVuZ3RoID09IDAgfHwgbGF5ZXJzLmxlbmd0aCA+IHNlbGYuY2FwYWJpbGl0aWVzLm1heExheWVycykge1xuICAgICAgcmVqZWN0KG5ldyBFcnJvcignSW52YWxpZCBudW1iZXIgb2YgbGF5ZXJzLicpKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgaW5jb21pbmdMYXllciA9IGxheWVyc1swXTtcbiAgICBpZiAoIWluY29taW5nTGF5ZXIuc291cmNlKSB7XG4gICAgICAvKlxuICAgICAgdG9kbzogZmlndXJlIG91dCB0aGUgY29ycmVjdCBiZWhhdmlvciBpZiB0aGUgc291cmNlIGlzIG5vdCBwcm92aWRlZC5cbiAgICAgIHNlZSBodHRwczovL2dpdGh1Yi5jb20vdzNjL3dlYnZyL2lzc3Vlcy81OFxuICAgICAgKi9cbiAgICAgIHJlc29sdmUoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgbGVmdEJvdW5kcyA9IGluY29taW5nTGF5ZXIubGVmdEJvdW5kcyB8fCBkZWZhdWx0TGVmdEJvdW5kcztcbiAgICB2YXIgcmlnaHRCb3VuZHMgPSBpbmNvbWluZ0xheWVyLnJpZ2h0Qm91bmRzIHx8IGRlZmF1bHRSaWdodEJvdW5kcztcbiAgICBpZiAod2FzUHJlc2VudGluZykge1xuICAgICAgLy8gQWxyZWFkeSBwcmVzZW50aW5nLCBqdXN0IGNoYW5naW5nIGNvbmZpZ3VyYXRpb25cbiAgICAgIHZhciBsYXllciA9IHNlbGYubGF5ZXJfO1xuICAgICAgaWYgKGxheWVyLnNvdXJjZSAhPT0gaW5jb21pbmdMYXllci5zb3VyY2UpIHtcbiAgICAgICAgbGF5ZXIuc291cmNlID0gaW5jb21pbmdMYXllci5zb3VyY2U7XG4gICAgICB9XG5cbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgNDsgaSsrKSB7XG4gICAgICAgIGlmIChsYXllci5sZWZ0Qm91bmRzW2ldICE9PSBsZWZ0Qm91bmRzW2ldKSB7XG4gICAgICAgICAgbGF5ZXIubGVmdEJvdW5kc1tpXSA9IGxlZnRCb3VuZHNbaV07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGxheWVyLnJpZ2h0Qm91bmRzW2ldICE9PSByaWdodEJvdW5kc1tpXSkge1xuICAgICAgICAgIGxheWVyLnJpZ2h0Qm91bmRzW2ldID0gcmlnaHRCb3VuZHNbaV07XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmVzb2x2ZSgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIFdhcyBub3QgYWxyZWFkeSBwcmVzZW50aW5nLlxuICAgIHNlbGYubGF5ZXJfID0ge1xuICAgICAgcHJlZGlzdG9ydGVkOiBpbmNvbWluZ0xheWVyLnByZWRpc3RvcnRlZCxcbiAgICAgIHNvdXJjZTogaW5jb21pbmdMYXllci5zb3VyY2UsXG4gICAgICBsZWZ0Qm91bmRzOiBsZWZ0Qm91bmRzLnNsaWNlKDApLFxuICAgICAgcmlnaHRCb3VuZHM6IHJpZ2h0Qm91bmRzLnNsaWNlKDApXG4gICAgfTtcblxuICAgIHNlbGYud2FpdGluZ0ZvclByZXNlbnRfID0gZmFsc2U7XG4gICAgaWYgKHNlbGYubGF5ZXJfICYmIHNlbGYubGF5ZXJfLnNvdXJjZSkge1xuICAgICAgdmFyIGZ1bGxzY3JlZW5FbGVtZW50ID0gc2VsZi53cmFwRm9yRnVsbHNjcmVlbihzZWxmLmxheWVyXy5zb3VyY2UpO1xuXG4gICAgICBmdW5jdGlvbiBvbkZ1bGxzY3JlZW5DaGFuZ2UoKSB7XG4gICAgICAgIHZhciBhY3R1YWxGdWxsc2NyZWVuRWxlbWVudCA9IFV0aWwuZ2V0RnVsbHNjcmVlbkVsZW1lbnQoKTtcblxuICAgICAgICBzZWxmLmlzUHJlc2VudGluZyA9IChmdWxsc2NyZWVuRWxlbWVudCA9PT0gYWN0dWFsRnVsbHNjcmVlbkVsZW1lbnQpO1xuICAgICAgICBpZiAoc2VsZi5pc1ByZXNlbnRpbmcpIHtcbiAgICAgICAgICBpZiAoc2NyZWVuLm9yaWVudGF0aW9uICYmIHNjcmVlbi5vcmllbnRhdGlvbi5sb2NrKSB7XG4gICAgICAgICAgICBzY3JlZW4ub3JpZW50YXRpb24ubG9jaygnbGFuZHNjYXBlLXByaW1hcnknKS5jYXRjaChmdW5jdGlvbihlcnJvcil7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ3NjcmVlbi5vcmllbnRhdGlvbi5sb2NrKCkgZmFpbGVkIGR1ZSB0bycsIGVycm9yLm1lc3NhZ2UpXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgc2VsZi53YWl0aW5nRm9yUHJlc2VudF8gPSBmYWxzZTtcbiAgICAgICAgICBzZWxmLmJlZ2luUHJlc2VudF8oKTtcbiAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKHNjcmVlbi5vcmllbnRhdGlvbiAmJiBzY3JlZW4ub3JpZW50YXRpb24udW5sb2NrKSB7XG4gICAgICAgICAgICBzY3JlZW4ub3JpZW50YXRpb24udW5sb2NrKCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHNlbGYucmVtb3ZlRnVsbHNjcmVlbldyYXBwZXIoKTtcbiAgICAgICAgICBzZWxmLndha2Vsb2NrXy5yZWxlYXNlKCk7XG4gICAgICAgICAgc2VsZi5lbmRQcmVzZW50XygpO1xuICAgICAgICAgIHNlbGYucmVtb3ZlRnVsbHNjcmVlbkxpc3RlbmVyc18oKTtcbiAgICAgICAgfVxuICAgICAgICBzZWxmLmZpcmVWUkRpc3BsYXlQcmVzZW50Q2hhbmdlXygpO1xuICAgICAgfVxuICAgICAgZnVuY3Rpb24gb25GdWxsc2NyZWVuRXJyb3IoKSB7XG4gICAgICAgIGlmICghc2VsZi53YWl0aW5nRm9yUHJlc2VudF8pIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBzZWxmLnJlbW92ZUZ1bGxzY3JlZW5XcmFwcGVyKCk7XG4gICAgICAgIHNlbGYucmVtb3ZlRnVsbHNjcmVlbkxpc3RlbmVyc18oKTtcblxuICAgICAgICBzZWxmLndha2Vsb2NrXy5yZWxlYXNlKCk7XG4gICAgICAgIHNlbGYud2FpdGluZ0ZvclByZXNlbnRfID0gZmFsc2U7XG4gICAgICAgIHNlbGYuaXNQcmVzZW50aW5nID0gZmFsc2U7XG5cbiAgICAgICAgcmVqZWN0KG5ldyBFcnJvcignVW5hYmxlIHRvIHByZXNlbnQuJykpO1xuICAgICAgfVxuXG4gICAgICBzZWxmLmFkZEZ1bGxzY3JlZW5MaXN0ZW5lcnNfKGZ1bGxzY3JlZW5FbGVtZW50LFxuICAgICAgICAgIG9uRnVsbHNjcmVlbkNoYW5nZSwgb25GdWxsc2NyZWVuRXJyb3IpO1xuXG4gICAgICBpZiAoVXRpbC5yZXF1ZXN0RnVsbHNjcmVlbihmdWxsc2NyZWVuRWxlbWVudCkpIHtcbiAgICAgICAgc2VsZi53YWtlbG9ja18ucmVxdWVzdCgpO1xuICAgICAgICBzZWxmLndhaXRpbmdGb3JQcmVzZW50XyA9IHRydWU7XG4gICAgICB9IGVsc2UgaWYgKFV0aWwuaXNJT1MoKSkge1xuICAgICAgICAvLyAqc2lnaCogSnVzdCBmYWtlIGl0LlxuICAgICAgICBzZWxmLndha2Vsb2NrXy5yZXF1ZXN0KCk7XG4gICAgICAgIHNlbGYuaXNQcmVzZW50aW5nID0gdHJ1ZTtcbiAgICAgICAgc2VsZi5iZWdpblByZXNlbnRfKCk7XG4gICAgICAgIHNlbGYuZmlyZVZSRGlzcGxheVByZXNlbnRDaGFuZ2VfKCk7XG4gICAgICAgIHJlc29sdmUoKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIXNlbGYud2FpdGluZ0ZvclByZXNlbnRfICYmICFVdGlsLmlzSU9TKCkpIHtcbiAgICAgIFV0aWwuZXhpdEZ1bGxzY3JlZW4oKTtcbiAgICAgIHJlamVjdChuZXcgRXJyb3IoJ1VuYWJsZSB0byBwcmVzZW50LicpKTtcbiAgICB9XG4gIH0pO1xufTtcblxuVlJEaXNwbGF5LnByb3RvdHlwZS5leGl0UHJlc2VudCA9IGZ1bmN0aW9uKCkge1xuICB2YXIgd2FzUHJlc2VudGluZyA9IHRoaXMuaXNQcmVzZW50aW5nO1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHRoaXMuaXNQcmVzZW50aW5nID0gZmFsc2U7XG4gIHRoaXMubGF5ZXJfID0gbnVsbDtcbiAgdGhpcy53YWtlbG9ja18ucmVsZWFzZSgpO1xuXG4gIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICBpZiAod2FzUHJlc2VudGluZykge1xuICAgICAgaWYgKCFVdGlsLmV4aXRGdWxsc2NyZWVuKCkgJiYgVXRpbC5pc0lPUygpKSB7XG4gICAgICAgIHNlbGYuZW5kUHJlc2VudF8oKTtcbiAgICAgICAgc2VsZi5maXJlVlJEaXNwbGF5UHJlc2VudENoYW5nZV8oKTtcbiAgICAgIH1cblxuICAgICAgcmVzb2x2ZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZWplY3QobmV3IEVycm9yKCdXYXMgbm90IHByZXNlbnRpbmcgdG8gVlJEaXNwbGF5LicpKTtcbiAgICB9XG4gIH0pO1xufTtcblxuVlJEaXNwbGF5LnByb3RvdHlwZS5nZXRMYXllcnMgPSBmdW5jdGlvbigpIHtcbiAgaWYgKHRoaXMubGF5ZXJfKSB7XG4gICAgcmV0dXJuIFt0aGlzLmxheWVyX107XG4gIH1cbiAgcmV0dXJuIFtdO1xufTtcblxuVlJEaXNwbGF5LnByb3RvdHlwZS5maXJlVlJEaXNwbGF5UHJlc2VudENoYW5nZV8gPSBmdW5jdGlvbigpIHtcbiAgdmFyIGV2ZW50ID0gbmV3IEN1c3RvbUV2ZW50KCd2cmRpc3BsYXlwcmVzZW50Y2hhbmdlJywge2RldGFpbDoge2Rpc3BsYXk6IHRoaXN9fSk7XG4gIHdpbmRvdy5kaXNwYXRjaEV2ZW50KGV2ZW50KTtcbn07XG5cblZSRGlzcGxheS5wcm90b3R5cGUuYWRkRnVsbHNjcmVlbkxpc3RlbmVyc18gPSBmdW5jdGlvbihlbGVtZW50LCBjaGFuZ2VIYW5kbGVyLCBlcnJvckhhbmRsZXIpIHtcbiAgdGhpcy5yZW1vdmVGdWxsc2NyZWVuTGlzdGVuZXJzXygpO1xuXG4gIHRoaXMuZnVsbHNjcmVlbkV2ZW50VGFyZ2V0XyA9IGVsZW1lbnQ7XG4gIHRoaXMuZnVsbHNjcmVlbkNoYW5nZUhhbmRsZXJfID0gY2hhbmdlSGFuZGxlcjtcbiAgdGhpcy5mdWxsc2NyZWVuRXJyb3JIYW5kbGVyXyA9IGVycm9ySGFuZGxlcjtcblxuICBpZiAoY2hhbmdlSGFuZGxlcikge1xuICAgIGlmIChkb2N1bWVudC5mdWxsc2NyZWVuRW5hYmxlZCkge1xuICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCdmdWxsc2NyZWVuY2hhbmdlJywgY2hhbmdlSGFuZGxlciwgZmFsc2UpO1xuICAgIH0gZWxzZSBpZiAoZG9jdW1lbnQud2Via2l0RnVsbHNjcmVlbkVuYWJsZWQpIHtcbiAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignd2Via2l0ZnVsbHNjcmVlbmNoYW5nZScsIGNoYW5nZUhhbmRsZXIsIGZhbHNlKTtcbiAgICB9IGVsc2UgaWYgKGRvY3VtZW50Lm1vekZ1bGxTY3JlZW5FbmFibGVkKSB7XG4gICAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdtb3pmdWxsc2NyZWVuY2hhbmdlJywgY2hhbmdlSGFuZGxlciwgZmFsc2UpO1xuICAgIH0gZWxzZSBpZiAoZG9jdW1lbnQubXNGdWxsc2NyZWVuRW5hYmxlZCkge1xuICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCdtc2Z1bGxzY3JlZW5jaGFuZ2UnLCBjaGFuZ2VIYW5kbGVyLCBmYWxzZSk7XG4gICAgfVxuICB9XG5cbiAgaWYgKGVycm9ySGFuZGxlcikge1xuICAgIGlmIChkb2N1bWVudC5mdWxsc2NyZWVuRW5hYmxlZCkge1xuICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCdmdWxsc2NyZWVuZXJyb3InLCBlcnJvckhhbmRsZXIsIGZhbHNlKTtcbiAgICB9IGVsc2UgaWYgKGRvY3VtZW50LndlYmtpdEZ1bGxzY3JlZW5FbmFibGVkKSB7XG4gICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3dlYmtpdGZ1bGxzY3JlZW5lcnJvcicsIGVycm9ySGFuZGxlciwgZmFsc2UpO1xuICAgIH0gZWxzZSBpZiAoZG9jdW1lbnQubW96RnVsbFNjcmVlbkVuYWJsZWQpIHtcbiAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ21vemZ1bGxzY3JlZW5lcnJvcicsIGVycm9ySGFuZGxlciwgZmFsc2UpO1xuICAgIH0gZWxzZSBpZiAoZG9jdW1lbnQubXNGdWxsc2NyZWVuRW5hYmxlZCkge1xuICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCdtc2Z1bGxzY3JlZW5lcnJvcicsIGVycm9ySGFuZGxlciwgZmFsc2UpO1xuICAgIH1cbiAgfVxufTtcblxuVlJEaXNwbGF5LnByb3RvdHlwZS5yZW1vdmVGdWxsc2NyZWVuTGlzdGVuZXJzXyA9IGZ1bmN0aW9uKCkge1xuICBpZiAoIXRoaXMuZnVsbHNjcmVlbkV2ZW50VGFyZ2V0XylcbiAgICByZXR1cm47XG5cbiAgdmFyIGVsZW1lbnQgPSB0aGlzLmZ1bGxzY3JlZW5FdmVudFRhcmdldF87XG5cbiAgaWYgKHRoaXMuZnVsbHNjcmVlbkNoYW5nZUhhbmRsZXJfKSB7XG4gICAgdmFyIGNoYW5nZUhhbmRsZXIgPSB0aGlzLmZ1bGxzY3JlZW5DaGFuZ2VIYW5kbGVyXztcbiAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2Z1bGxzY3JlZW5jaGFuZ2UnLCBjaGFuZ2VIYW5kbGVyLCBmYWxzZSk7XG4gICAgZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCd3ZWJraXRmdWxsc2NyZWVuY2hhbmdlJywgY2hhbmdlSGFuZGxlciwgZmFsc2UpO1xuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vemZ1bGxzY3JlZW5jaGFuZ2UnLCBjaGFuZ2VIYW5kbGVyLCBmYWxzZSk7XG4gICAgZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdtc2Z1bGxzY3JlZW5jaGFuZ2UnLCBjaGFuZ2VIYW5kbGVyLCBmYWxzZSk7XG4gIH1cblxuICBpZiAodGhpcy5mdWxsc2NyZWVuRXJyb3JIYW5kbGVyXykge1xuICAgIHZhciBlcnJvckhhbmRsZXIgPSB0aGlzLmZ1bGxzY3JlZW5FcnJvckhhbmRsZXJfO1xuICAgIGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignZnVsbHNjcmVlbmVycm9yJywgZXJyb3JIYW5kbGVyLCBmYWxzZSk7XG4gICAgZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCd3ZWJraXRmdWxsc2NyZWVuZXJyb3InLCBlcnJvckhhbmRsZXIsIGZhbHNlKTtcbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3pmdWxsc2NyZWVuZXJyb3InLCBlcnJvckhhbmRsZXIsIGZhbHNlKTtcbiAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21zZnVsbHNjcmVlbmVycm9yJywgZXJyb3JIYW5kbGVyLCBmYWxzZSk7XG4gIH1cblxuICB0aGlzLmZ1bGxzY3JlZW5FdmVudFRhcmdldF8gPSBudWxsO1xuICB0aGlzLmZ1bGxzY3JlZW5DaGFuZ2VIYW5kbGVyXyA9IG51bGw7XG4gIHRoaXMuZnVsbHNjcmVlbkVycm9ySGFuZGxlcl8gPSBudWxsO1xufTtcblxuVlJEaXNwbGF5LnByb3RvdHlwZS5iZWdpblByZXNlbnRfID0gZnVuY3Rpb24oKSB7XG4gIC8vIE92ZXJyaWRlIHRvIGFkZCBjdXN0b20gYmVoYXZpb3Igd2hlbiBwcmVzZW50YXRpb24gYmVnaW5zLlxufTtcblxuVlJEaXNwbGF5LnByb3RvdHlwZS5lbmRQcmVzZW50XyA9IGZ1bmN0aW9uKCkge1xuICAvLyBPdmVycmlkZSB0byBhZGQgY3VzdG9tIGJlaGF2aW9yIHdoZW4gcHJlc2VudGF0aW9uIGVuZHMuXG59O1xuXG5WUkRpc3BsYXkucHJvdG90eXBlLnN1Ym1pdEZyYW1lID0gZnVuY3Rpb24ocG9zZSkge1xuICAvLyBPdmVycmlkZSB0byBhZGQgY3VzdG9tIGJlaGF2aW9yIGZvciBmcmFtZSBzdWJtaXNzaW9uLlxufTtcblxuVlJEaXNwbGF5LnByb3RvdHlwZS5nZXRFeWVQYXJhbWV0ZXJzID0gZnVuY3Rpb24od2hpY2hFeWUpIHtcbiAgLy8gT3ZlcnJpZGUgdG8gcmV0dXJuIGFjY3VyYXRlIGV5ZSBwYXJhbWV0ZXJzIGlmIGNhblByZXNlbnQgaXMgdHJ1ZS5cbiAgcmV0dXJuIG51bGw7XG59O1xuXG4vKlxuICogRGVwcmVjYXRlZCBjbGFzc2VzXG4gKi9cblxuLyoqXG4gKiBUaGUgYmFzZSBjbGFzcyBmb3IgYWxsIFZSIGRldmljZXMuIChEZXByZWNhdGVkKVxuICovXG5mdW5jdGlvbiBWUkRldmljZSgpIHtcbiAgdGhpcy5pc1BvbHlmaWxsZWQgPSB0cnVlO1xuICB0aGlzLmhhcmR3YXJlVW5pdElkID0gJ3dlYnZyLXBvbHlmaWxsIGhhcmR3YXJlVW5pdElkJztcbiAgdGhpcy5kZXZpY2VJZCA9ICd3ZWJ2ci1wb2x5ZmlsbCBkZXZpY2VJZCc7XG4gIHRoaXMuZGV2aWNlTmFtZSA9ICd3ZWJ2ci1wb2x5ZmlsbCBkZXZpY2VOYW1lJztcbn1cblxuLyoqXG4gKiBUaGUgYmFzZSBjbGFzcyBmb3IgYWxsIFZSIEhNRCBkZXZpY2VzLiAoRGVwcmVjYXRlZClcbiAqL1xuZnVuY3Rpb24gSE1EVlJEZXZpY2UoKSB7XG59XG5ITURWUkRldmljZS5wcm90b3R5cGUgPSBuZXcgVlJEZXZpY2UoKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBjbGFzcyBmb3IgYWxsIFZSIHBvc2l0aW9uIHNlbnNvciBkZXZpY2VzLiAoRGVwcmVjYXRlZClcbiAqL1xuZnVuY3Rpb24gUG9zaXRpb25TZW5zb3JWUkRldmljZSgpIHtcbn1cblBvc2l0aW9uU2Vuc29yVlJEZXZpY2UucHJvdG90eXBlID0gbmV3IFZSRGV2aWNlKCk7XG5cbm1vZHVsZS5leHBvcnRzLlZSRnJhbWVEYXRhID0gVlJGcmFtZURhdGE7XG5tb2R1bGUuZXhwb3J0cy5WUkRpc3BsYXkgPSBWUkRpc3BsYXk7XG5tb2R1bGUuZXhwb3J0cy5WUkRldmljZSA9IFZSRGV2aWNlO1xubW9kdWxlLmV4cG9ydHMuSE1EVlJEZXZpY2UgPSBITURWUkRldmljZTtcbm1vZHVsZS5leHBvcnRzLlBvc2l0aW9uU2Vuc29yVlJEZXZpY2UgPSBQb3NpdGlvblNlbnNvclZSRGV2aWNlO1xuXG59LHtcIi4vdXRpbC5qc1wiOjIyLFwiLi93YWtlbG9jay5qc1wiOjI0fV0sNDpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4vKlxuICogQ29weXJpZ2h0IDIwMTYgR29vZ2xlIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG52YXIgQ2FyZGJvYXJkVUkgPSBfZGVyZXFfKCcuL2NhcmRib2FyZC11aS5qcycpO1xudmFyIFV0aWwgPSBfZGVyZXFfKCcuL3V0aWwuanMnKTtcbnZhciBXR0xVUHJlc2VydmVHTFN0YXRlID0gX2RlcmVxXygnLi9kZXBzL3dnbHUtcHJlc2VydmUtc3RhdGUuanMnKTtcblxudmFyIGRpc3RvcnRpb25WUyA9IFtcbiAgJ2F0dHJpYnV0ZSB2ZWMyIHBvc2l0aW9uOycsXG4gICdhdHRyaWJ1dGUgdmVjMyB0ZXhDb29yZDsnLFxuXG4gICd2YXJ5aW5nIHZlYzIgdlRleENvb3JkOycsXG5cbiAgJ3VuaWZvcm0gdmVjNCB2aWV3cG9ydE9mZnNldFNjYWxlWzJdOycsXG5cbiAgJ3ZvaWQgbWFpbigpIHsnLFxuICAnICB2ZWM0IHZpZXdwb3J0ID0gdmlld3BvcnRPZmZzZXRTY2FsZVtpbnQodGV4Q29vcmQueildOycsXG4gICcgIHZUZXhDb29yZCA9ICh0ZXhDb29yZC54eSAqIHZpZXdwb3J0Lnp3KSArIHZpZXdwb3J0Lnh5OycsXG4gICcgIGdsX1Bvc2l0aW9uID0gdmVjNCggcG9zaXRpb24sIDEuMCwgMS4wICk7JyxcbiAgJ30nLFxuXS5qb2luKCdcXG4nKTtcblxudmFyIGRpc3RvcnRpb25GUyA9IFtcbiAgJ3ByZWNpc2lvbiBtZWRpdW1wIGZsb2F0OycsXG4gICd1bmlmb3JtIHNhbXBsZXIyRCBkaWZmdXNlOycsXG5cbiAgJ3ZhcnlpbmcgdmVjMiB2VGV4Q29vcmQ7JyxcblxuICAndm9pZCBtYWluKCkgeycsXG4gICcgIGdsX0ZyYWdDb2xvciA9IHRleHR1cmUyRChkaWZmdXNlLCB2VGV4Q29vcmQpOycsXG4gICd9Jyxcbl0uam9pbignXFxuJyk7XG5cbi8qKlxuICogQSBtZXNoLWJhc2VkIGRpc3RvcnRlci5cbiAqL1xuZnVuY3Rpb24gQ2FyZGJvYXJkRGlzdG9ydGVyKGdsKSB7XG4gIHRoaXMuZ2wgPSBnbDtcbiAgdGhpcy5jdHhBdHRyaWJzID0gZ2wuZ2V0Q29udGV4dEF0dHJpYnV0ZXMoKTtcblxuICB0aGlzLm1lc2hXaWR0aCA9IDIwO1xuICB0aGlzLm1lc2hIZWlnaHQgPSAyMDtcblxuICB0aGlzLmJ1ZmZlclNjYWxlID0gV2ViVlJDb25maWcuQlVGRkVSX1NDQUxFO1xuXG4gIHRoaXMuYnVmZmVyV2lkdGggPSBnbC5kcmF3aW5nQnVmZmVyV2lkdGg7XG4gIHRoaXMuYnVmZmVySGVpZ2h0ID0gZ2wuZHJhd2luZ0J1ZmZlckhlaWdodDtcblxuICAvLyBQYXRjaGluZyBzdXBwb3J0XG4gIHRoaXMucmVhbEJpbmRGcmFtZWJ1ZmZlciA9IGdsLmJpbmRGcmFtZWJ1ZmZlcjtcbiAgdGhpcy5yZWFsRW5hYmxlID0gZ2wuZW5hYmxlO1xuICB0aGlzLnJlYWxEaXNhYmxlID0gZ2wuZGlzYWJsZTtcbiAgdGhpcy5yZWFsQ29sb3JNYXNrID0gZ2wuY29sb3JNYXNrO1xuICB0aGlzLnJlYWxDbGVhckNvbG9yID0gZ2wuY2xlYXJDb2xvcjtcbiAgdGhpcy5yZWFsVmlld3BvcnQgPSBnbC52aWV3cG9ydDtcblxuICBpZiAoIVV0aWwuaXNJT1MoKSkge1xuICAgIHRoaXMucmVhbENhbnZhc1dpZHRoID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihnbC5jYW52YXMuX19wcm90b19fLCAnd2lkdGgnKTtcbiAgICB0aGlzLnJlYWxDYW52YXNIZWlnaHQgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGdsLmNhbnZhcy5fX3Byb3RvX18sICdoZWlnaHQnKTtcbiAgfVxuXG4gIHRoaXMuaXNQYXRjaGVkID0gZmFsc2U7XG5cbiAgLy8gU3RhdGUgdHJhY2tpbmdcbiAgdGhpcy5sYXN0Qm91bmRGcmFtZWJ1ZmZlciA9IG51bGw7XG4gIHRoaXMuY3VsbEZhY2UgPSBmYWxzZTtcbiAgdGhpcy5kZXB0aFRlc3QgPSBmYWxzZTtcbiAgdGhpcy5ibGVuZCA9IGZhbHNlO1xuICB0aGlzLnNjaXNzb3JUZXN0ID0gZmFsc2U7XG4gIHRoaXMuc3RlbmNpbFRlc3QgPSBmYWxzZTtcbiAgdGhpcy52aWV3cG9ydCA9IFswLCAwLCAwLCAwXTtcbiAgdGhpcy5jb2xvck1hc2sgPSBbdHJ1ZSwgdHJ1ZSwgdHJ1ZSwgdHJ1ZV07XG4gIHRoaXMuY2xlYXJDb2xvciA9IFswLCAwLCAwLCAwXTtcblxuICB0aGlzLmF0dHJpYnMgPSB7XG4gICAgcG9zaXRpb246IDAsXG4gICAgdGV4Q29vcmQ6IDFcbiAgfTtcbiAgdGhpcy5wcm9ncmFtID0gVXRpbC5saW5rUHJvZ3JhbShnbCwgZGlzdG9ydGlvblZTLCBkaXN0b3J0aW9uRlMsIHRoaXMuYXR0cmlicyk7XG4gIHRoaXMudW5pZm9ybXMgPSBVdGlsLmdldFByb2dyYW1Vbmlmb3JtcyhnbCwgdGhpcy5wcm9ncmFtKTtcblxuICB0aGlzLnZpZXdwb3J0T2Zmc2V0U2NhbGUgPSBuZXcgRmxvYXQzMkFycmF5KDgpO1xuICB0aGlzLnNldFRleHR1cmVCb3VuZHMoKTtcblxuICB0aGlzLnZlcnRleEJ1ZmZlciA9IGdsLmNyZWF0ZUJ1ZmZlcigpO1xuICB0aGlzLmluZGV4QnVmZmVyID0gZ2wuY3JlYXRlQnVmZmVyKCk7XG4gIHRoaXMuaW5kZXhDb3VudCA9IDA7XG5cbiAgdGhpcy5yZW5kZXJUYXJnZXQgPSBnbC5jcmVhdGVUZXh0dXJlKCk7XG4gIHRoaXMuZnJhbWVidWZmZXIgPSBnbC5jcmVhdGVGcmFtZWJ1ZmZlcigpO1xuXG4gIHRoaXMuZGVwdGhTdGVuY2lsQnVmZmVyID0gbnVsbDtcbiAgdGhpcy5kZXB0aEJ1ZmZlciA9IG51bGw7XG4gIHRoaXMuc3RlbmNpbEJ1ZmZlciA9IG51bGw7XG5cbiAgaWYgKHRoaXMuY3R4QXR0cmlicy5kZXB0aCAmJiB0aGlzLmN0eEF0dHJpYnMuc3RlbmNpbCkge1xuICAgIHRoaXMuZGVwdGhTdGVuY2lsQnVmZmVyID0gZ2wuY3JlYXRlUmVuZGVyYnVmZmVyKCk7XG4gIH0gZWxzZSBpZiAodGhpcy5jdHhBdHRyaWJzLmRlcHRoKSB7XG4gICAgdGhpcy5kZXB0aEJ1ZmZlciA9IGdsLmNyZWF0ZVJlbmRlcmJ1ZmZlcigpO1xuICB9IGVsc2UgaWYgKHRoaXMuY3R4QXR0cmlicy5zdGVuY2lsKSB7XG4gICAgdGhpcy5zdGVuY2lsQnVmZmVyID0gZ2wuY3JlYXRlUmVuZGVyYnVmZmVyKCk7XG4gIH1cblxuICB0aGlzLnBhdGNoKCk7XG5cbiAgdGhpcy5vblJlc2l6ZSgpO1xuXG4gIGlmICghV2ViVlJDb25maWcuQ0FSREJPQVJEX1VJX0RJU0FCTEVEKSB7XG4gICAgdGhpcy5jYXJkYm9hcmRVSSA9IG5ldyBDYXJkYm9hcmRVSShnbCk7XG4gIH1cbn07XG5cbi8qKlxuICogVGVhcnMgZG93biBhbGwgdGhlIHJlc291cmNlcyBjcmVhdGVkIGJ5IHRoZSBkaXN0b3J0ZXIgYW5kIHJlbW92ZXMgYW55XG4gKiBwYXRjaGVzLlxuICovXG5DYXJkYm9hcmREaXN0b3J0ZXIucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGdsID0gdGhpcy5nbDtcblxuICB0aGlzLnVucGF0Y2goKTtcblxuICBnbC5kZWxldGVQcm9ncmFtKHRoaXMucHJvZ3JhbSk7XG4gIGdsLmRlbGV0ZUJ1ZmZlcih0aGlzLnZlcnRleEJ1ZmZlcik7XG4gIGdsLmRlbGV0ZUJ1ZmZlcih0aGlzLmluZGV4QnVmZmVyKTtcbiAgZ2wuZGVsZXRlVGV4dHVyZSh0aGlzLnJlbmRlclRhcmdldCk7XG4gIGdsLmRlbGV0ZUZyYW1lYnVmZmVyKHRoaXMuZnJhbWVidWZmZXIpO1xuICBpZiAodGhpcy5kZXB0aFN0ZW5jaWxCdWZmZXIpIHtcbiAgICBnbC5kZWxldGVSZW5kZXJidWZmZXIodGhpcy5kZXB0aFN0ZW5jaWxCdWZmZXIpO1xuICB9XG4gIGlmICh0aGlzLmRlcHRoQnVmZmVyKSB7XG4gICAgZ2wuZGVsZXRlUmVuZGVyYnVmZmVyKHRoaXMuZGVwdGhCdWZmZXIpO1xuICB9XG4gIGlmICh0aGlzLnN0ZW5jaWxCdWZmZXIpIHtcbiAgICBnbC5kZWxldGVSZW5kZXJidWZmZXIodGhpcy5zdGVuY2lsQnVmZmVyKTtcbiAgfVxuXG4gIGlmICh0aGlzLmNhcmRib2FyZFVJKSB7XG4gICAgdGhpcy5jYXJkYm9hcmRVSS5kZXN0cm95KCk7XG4gIH1cbn07XG5cblxuLyoqXG4gKiBSZXNpemVzIHRoZSBiYWNrYnVmZmVyIHRvIG1hdGNoIHRoZSBjYW52YXMgd2lkdGggYW5kIGhlaWdodC5cbiAqL1xuQ2FyZGJvYXJkRGlzdG9ydGVyLnByb3RvdHlwZS5vblJlc2l6ZSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgZ2wgPSB0aGlzLmdsO1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdmFyIGdsU3RhdGUgPSBbXG4gICAgZ2wuUkVOREVSQlVGRkVSX0JJTkRJTkcsXG4gICAgZ2wuVEVYVFVSRV9CSU5ESU5HXzJELCBnbC5URVhUVVJFMFxuICBdO1xuXG4gIFdHTFVQcmVzZXJ2ZUdMU3RhdGUoZ2wsIGdsU3RhdGUsIGZ1bmN0aW9uKGdsKSB7XG4gICAgLy8gQmluZCByZWFsIGJhY2tidWZmZXIgYW5kIGNsZWFyIGl0IG9uY2UuIFdlIGRvbid0IG5lZWQgdG8gY2xlYXIgaXQgYWdhaW5cbiAgICAvLyBhZnRlciB0aGF0IGJlY2F1c2Ugd2UncmUgb3ZlcndyaXRpbmcgdGhlIHNhbWUgYXJlYSBldmVyeSBmcmFtZS5cbiAgICBzZWxmLnJlYWxCaW5kRnJhbWVidWZmZXIuY2FsbChnbCwgZ2wuRlJBTUVCVUZGRVIsIG51bGwpO1xuXG4gICAgLy8gUHV0IHRoaW5ncyBpbiBhIGdvb2Qgc3RhdGVcbiAgICBpZiAoc2VsZi5zY2lzc29yVGVzdCkgeyBzZWxmLnJlYWxEaXNhYmxlLmNhbGwoZ2wsIGdsLlNDSVNTT1JfVEVTVCk7IH1cbiAgICBzZWxmLnJlYWxDb2xvck1hc2suY2FsbChnbCwgdHJ1ZSwgdHJ1ZSwgdHJ1ZSwgdHJ1ZSk7XG4gICAgc2VsZi5yZWFsVmlld3BvcnQuY2FsbChnbCwgMCwgMCwgZ2wuZHJhd2luZ0J1ZmZlcldpZHRoLCBnbC5kcmF3aW5nQnVmZmVySGVpZ2h0KTtcbiAgICBzZWxmLnJlYWxDbGVhckNvbG9yLmNhbGwoZ2wsIDAsIDAsIDAsIDEpO1xuXG4gICAgZ2wuY2xlYXIoZ2wuQ09MT1JfQlVGRkVSX0JJVCk7XG5cbiAgICAvLyBOb3cgYmluZCBhbmQgcmVzaXplIHRoZSBmYWtlIGJhY2tidWZmZXJcbiAgICBzZWxmLnJlYWxCaW5kRnJhbWVidWZmZXIuY2FsbChnbCwgZ2wuRlJBTUVCVUZGRVIsIHNlbGYuZnJhbWVidWZmZXIpO1xuXG4gICAgZ2wuYmluZFRleHR1cmUoZ2wuVEVYVFVSRV8yRCwgc2VsZi5yZW5kZXJUYXJnZXQpO1xuICAgIGdsLnRleEltYWdlMkQoZ2wuVEVYVFVSRV8yRCwgMCwgc2VsZi5jdHhBdHRyaWJzLmFscGhhID8gZ2wuUkdCQSA6IGdsLlJHQixcbiAgICAgICAgc2VsZi5idWZmZXJXaWR0aCwgc2VsZi5idWZmZXJIZWlnaHQsIDAsXG4gICAgICAgIHNlbGYuY3R4QXR0cmlicy5hbHBoYSA/IGdsLlJHQkEgOiBnbC5SR0IsIGdsLlVOU0lHTkVEX0JZVEUsIG51bGwpO1xuICAgIGdsLnRleFBhcmFtZXRlcmkoZ2wuVEVYVFVSRV8yRCwgZ2wuVEVYVFVSRV9NQUdfRklMVEVSLCBnbC5MSU5FQVIpO1xuICAgIGdsLnRleFBhcmFtZXRlcmkoZ2wuVEVYVFVSRV8yRCwgZ2wuVEVYVFVSRV9NSU5fRklMVEVSLCBnbC5MSU5FQVIpO1xuICAgIGdsLnRleFBhcmFtZXRlcmkoZ2wuVEVYVFVSRV8yRCwgZ2wuVEVYVFVSRV9XUkFQX1MsIGdsLkNMQU1QX1RPX0VER0UpO1xuICAgIGdsLnRleFBhcmFtZXRlcmkoZ2wuVEVYVFVSRV8yRCwgZ2wuVEVYVFVSRV9XUkFQX1QsIGdsLkNMQU1QX1RPX0VER0UpO1xuICAgIGdsLmZyYW1lYnVmZmVyVGV4dHVyZTJEKGdsLkZSQU1FQlVGRkVSLCBnbC5DT0xPUl9BVFRBQ0hNRU5UMCwgZ2wuVEVYVFVSRV8yRCwgc2VsZi5yZW5kZXJUYXJnZXQsIDApO1xuXG4gICAgaWYgKHNlbGYuY3R4QXR0cmlicy5kZXB0aCAmJiBzZWxmLmN0eEF0dHJpYnMuc3RlbmNpbCkge1xuICAgICAgZ2wuYmluZFJlbmRlcmJ1ZmZlcihnbC5SRU5ERVJCVUZGRVIsIHNlbGYuZGVwdGhTdGVuY2lsQnVmZmVyKTtcbiAgICAgIGdsLnJlbmRlcmJ1ZmZlclN0b3JhZ2UoZ2wuUkVOREVSQlVGRkVSLCBnbC5ERVBUSF9TVEVOQ0lMLFxuICAgICAgICAgIHNlbGYuYnVmZmVyV2lkdGgsIHNlbGYuYnVmZmVySGVpZ2h0KTtcbiAgICAgIGdsLmZyYW1lYnVmZmVyUmVuZGVyYnVmZmVyKGdsLkZSQU1FQlVGRkVSLCBnbC5ERVBUSF9TVEVOQ0lMX0FUVEFDSE1FTlQsXG4gICAgICAgICAgZ2wuUkVOREVSQlVGRkVSLCBzZWxmLmRlcHRoU3RlbmNpbEJ1ZmZlcik7XG4gICAgfSBlbHNlIGlmIChzZWxmLmN0eEF0dHJpYnMuZGVwdGgpIHtcbiAgICAgIGdsLmJpbmRSZW5kZXJidWZmZXIoZ2wuUkVOREVSQlVGRkVSLCBzZWxmLmRlcHRoQnVmZmVyKTtcbiAgICAgIGdsLnJlbmRlcmJ1ZmZlclN0b3JhZ2UoZ2wuUkVOREVSQlVGRkVSLCBnbC5ERVBUSF9DT01QT05FTlQxNixcbiAgICAgICAgICBzZWxmLmJ1ZmZlcldpZHRoLCBzZWxmLmJ1ZmZlckhlaWdodCk7XG4gICAgICBnbC5mcmFtZWJ1ZmZlclJlbmRlcmJ1ZmZlcihnbC5GUkFNRUJVRkZFUiwgZ2wuREVQVEhfQVRUQUNITUVOVCxcbiAgICAgICAgICBnbC5SRU5ERVJCVUZGRVIsIHNlbGYuZGVwdGhCdWZmZXIpO1xuICAgIH0gZWxzZSBpZiAoc2VsZi5jdHhBdHRyaWJzLnN0ZW5jaWwpIHtcbiAgICAgIGdsLmJpbmRSZW5kZXJidWZmZXIoZ2wuUkVOREVSQlVGRkVSLCBzZWxmLnN0ZW5jaWxCdWZmZXIpO1xuICAgICAgZ2wucmVuZGVyYnVmZmVyU3RvcmFnZShnbC5SRU5ERVJCVUZGRVIsIGdsLlNURU5DSUxfSU5ERVg4LFxuICAgICAgICAgIHNlbGYuYnVmZmVyV2lkdGgsIHNlbGYuYnVmZmVySGVpZ2h0KTtcbiAgICAgIGdsLmZyYW1lYnVmZmVyUmVuZGVyYnVmZmVyKGdsLkZSQU1FQlVGRkVSLCBnbC5TVEVOQ0lMX0FUVEFDSE1FTlQsXG4gICAgICAgICAgZ2wuUkVOREVSQlVGRkVSLCBzZWxmLnN0ZW5jaWxCdWZmZXIpO1xuICAgIH1cblxuICAgIGlmICghZ2wuY2hlY2tGcmFtZWJ1ZmZlclN0YXR1cyhnbC5GUkFNRUJVRkZFUikgPT09IGdsLkZSQU1FQlVGRkVSX0NPTVBMRVRFKSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdGcmFtZWJ1ZmZlciBpbmNvbXBsZXRlIScpO1xuICAgIH1cblxuICAgIHNlbGYucmVhbEJpbmRGcmFtZWJ1ZmZlci5jYWxsKGdsLCBnbC5GUkFNRUJVRkZFUiwgc2VsZi5sYXN0Qm91bmRGcmFtZWJ1ZmZlcik7XG5cbiAgICBpZiAoc2VsZi5zY2lzc29yVGVzdCkgeyBzZWxmLnJlYWxFbmFibGUuY2FsbChnbCwgZ2wuU0NJU1NPUl9URVNUKTsgfVxuXG4gICAgc2VsZi5yZWFsQ29sb3JNYXNrLmFwcGx5KGdsLCBzZWxmLmNvbG9yTWFzayk7XG4gICAgc2VsZi5yZWFsVmlld3BvcnQuYXBwbHkoZ2wsIHNlbGYudmlld3BvcnQpO1xuICAgIHNlbGYucmVhbENsZWFyQ29sb3IuYXBwbHkoZ2wsIHNlbGYuY2xlYXJDb2xvcik7XG4gIH0pO1xuXG4gIGlmICh0aGlzLmNhcmRib2FyZFVJKSB7XG4gICAgdGhpcy5jYXJkYm9hcmRVSS5vblJlc2l6ZSgpO1xuICB9XG59O1xuXG5DYXJkYm9hcmREaXN0b3J0ZXIucHJvdG90eXBlLnBhdGNoID0gZnVuY3Rpb24oKSB7XG4gIGlmICh0aGlzLmlzUGF0Y2hlZCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBzZWxmID0gdGhpcztcbiAgdmFyIGNhbnZhcyA9IHRoaXMuZ2wuY2FudmFzO1xuICB2YXIgZ2wgPSB0aGlzLmdsO1xuXG4gIGlmICghVXRpbC5pc0lPUygpKSB7XG4gICAgY2FudmFzLndpZHRoID0gVXRpbC5nZXRTY3JlZW5XaWR0aCgpICogdGhpcy5idWZmZXJTY2FsZTtcbiAgICBjYW52YXMuaGVpZ2h0ID0gVXRpbC5nZXRTY3JlZW5IZWlnaHQoKSAqIHRoaXMuYnVmZmVyU2NhbGU7XG5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY2FudmFzLCAnd2lkdGgnLCB7XG4gICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgZ2V0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIHNlbGYuYnVmZmVyV2lkdGg7XG4gICAgICB9LFxuICAgICAgc2V0OiBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICBzZWxmLmJ1ZmZlcldpZHRoID0gdmFsdWU7XG4gICAgICAgIHNlbGYucmVhbENhbnZhc1dpZHRoLnNldC5jYWxsKGNhbnZhcywgdmFsdWUpO1xuICAgICAgICBzZWxmLm9uUmVzaXplKCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY2FudmFzLCAnaGVpZ2h0Jywge1xuICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiBzZWxmLmJ1ZmZlckhlaWdodDtcbiAgICAgIH0sXG4gICAgICBzZXQ6IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICAgIHNlbGYuYnVmZmVySGVpZ2h0ID0gdmFsdWU7XG4gICAgICAgIHNlbGYucmVhbENhbnZhc0hlaWdodC5zZXQuY2FsbChjYW52YXMsIHZhbHVlKTtcbiAgICAgICAgc2VsZi5vblJlc2l6ZSgpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgdGhpcy5sYXN0Qm91bmRGcmFtZWJ1ZmZlciA9IGdsLmdldFBhcmFtZXRlcihnbC5GUkFNRUJVRkZFUl9CSU5ESU5HKTtcblxuICBpZiAodGhpcy5sYXN0Qm91bmRGcmFtZWJ1ZmZlciA9PSBudWxsKSB7XG4gICAgdGhpcy5sYXN0Qm91bmRGcmFtZWJ1ZmZlciA9IHRoaXMuZnJhbWVidWZmZXI7XG4gICAgdGhpcy5nbC5iaW5kRnJhbWVidWZmZXIoZ2wuRlJBTUVCVUZGRVIsIHRoaXMuZnJhbWVidWZmZXIpO1xuICB9XG5cbiAgdGhpcy5nbC5iaW5kRnJhbWVidWZmZXIgPSBmdW5jdGlvbih0YXJnZXQsIGZyYW1lYnVmZmVyKSB7XG4gICAgc2VsZi5sYXN0Qm91bmRGcmFtZWJ1ZmZlciA9IGZyYW1lYnVmZmVyID8gZnJhbWVidWZmZXIgOiBzZWxmLmZyYW1lYnVmZmVyO1xuICAgIC8vIFNpbGVudGx5IG1ha2UgY2FsbHMgdG8gYmluZCB0aGUgZGVmYXVsdCBmcmFtZWJ1ZmZlciBiaW5kIG91cnMgaW5zdGVhZC5cbiAgICBzZWxmLnJlYWxCaW5kRnJhbWVidWZmZXIuY2FsbChnbCwgdGFyZ2V0LCBzZWxmLmxhc3RCb3VuZEZyYW1lYnVmZmVyKTtcbiAgfTtcblxuICB0aGlzLmN1bGxGYWNlID0gZ2wuZ2V0UGFyYW1ldGVyKGdsLkNVTExfRkFDRSk7XG4gIHRoaXMuZGVwdGhUZXN0ID0gZ2wuZ2V0UGFyYW1ldGVyKGdsLkRFUFRIX1RFU1QpO1xuICB0aGlzLmJsZW5kID0gZ2wuZ2V0UGFyYW1ldGVyKGdsLkJMRU5EKTtcbiAgdGhpcy5zY2lzc29yVGVzdCA9IGdsLmdldFBhcmFtZXRlcihnbC5TQ0lTU09SX1RFU1QpO1xuICB0aGlzLnN0ZW5jaWxUZXN0ID0gZ2wuZ2V0UGFyYW1ldGVyKGdsLlNURU5DSUxfVEVTVCk7XG5cbiAgZ2wuZW5hYmxlID0gZnVuY3Rpb24ocG5hbWUpIHtcbiAgICBzd2l0Y2ggKHBuYW1lKSB7XG4gICAgICBjYXNlIGdsLkNVTExfRkFDRTogc2VsZi5jdWxsRmFjZSA9IHRydWU7IGJyZWFrO1xuICAgICAgY2FzZSBnbC5ERVBUSF9URVNUOiBzZWxmLmRlcHRoVGVzdCA9IHRydWU7IGJyZWFrO1xuICAgICAgY2FzZSBnbC5CTEVORDogc2VsZi5ibGVuZCA9IHRydWU7IGJyZWFrO1xuICAgICAgY2FzZSBnbC5TQ0lTU09SX1RFU1Q6IHNlbGYuc2Npc3NvclRlc3QgPSB0cnVlOyBicmVhaztcbiAgICAgIGNhc2UgZ2wuU1RFTkNJTF9URVNUOiBzZWxmLnN0ZW5jaWxUZXN0ID0gdHJ1ZTsgYnJlYWs7XG4gICAgfVxuICAgIHNlbGYucmVhbEVuYWJsZS5jYWxsKGdsLCBwbmFtZSk7XG4gIH07XG5cbiAgZ2wuZGlzYWJsZSA9IGZ1bmN0aW9uKHBuYW1lKSB7XG4gICAgc3dpdGNoIChwbmFtZSkge1xuICAgICAgY2FzZSBnbC5DVUxMX0ZBQ0U6IHNlbGYuY3VsbEZhY2UgPSBmYWxzZTsgYnJlYWs7XG4gICAgICBjYXNlIGdsLkRFUFRIX1RFU1Q6IHNlbGYuZGVwdGhUZXN0ID0gZmFsc2U7IGJyZWFrO1xuICAgICAgY2FzZSBnbC5CTEVORDogc2VsZi5ibGVuZCA9IGZhbHNlOyBicmVhaztcbiAgICAgIGNhc2UgZ2wuU0NJU1NPUl9URVNUOiBzZWxmLnNjaXNzb3JUZXN0ID0gZmFsc2U7IGJyZWFrO1xuICAgICAgY2FzZSBnbC5TVEVOQ0lMX1RFU1Q6IHNlbGYuc3RlbmNpbFRlc3QgPSBmYWxzZTsgYnJlYWs7XG4gICAgfVxuICAgIHNlbGYucmVhbERpc2FibGUuY2FsbChnbCwgcG5hbWUpO1xuICB9O1xuXG4gIHRoaXMuY29sb3JNYXNrID0gZ2wuZ2V0UGFyYW1ldGVyKGdsLkNPTE9SX1dSSVRFTUFTSyk7XG4gIGdsLmNvbG9yTWFzayA9IGZ1bmN0aW9uKHIsIGcsIGIsIGEpIHtcbiAgICBzZWxmLmNvbG9yTWFza1swXSA9IHI7XG4gICAgc2VsZi5jb2xvck1hc2tbMV0gPSBnO1xuICAgIHNlbGYuY29sb3JNYXNrWzJdID0gYjtcbiAgICBzZWxmLmNvbG9yTWFza1szXSA9IGE7XG4gICAgc2VsZi5yZWFsQ29sb3JNYXNrLmNhbGwoZ2wsIHIsIGcsIGIsIGEpO1xuICB9O1xuXG4gIHRoaXMuY2xlYXJDb2xvciA9IGdsLmdldFBhcmFtZXRlcihnbC5DT0xPUl9DTEVBUl9WQUxVRSk7XG4gIGdsLmNsZWFyQ29sb3IgPSBmdW5jdGlvbihyLCBnLCBiLCBhKSB7XG4gICAgc2VsZi5jbGVhckNvbG9yWzBdID0gcjtcbiAgICBzZWxmLmNsZWFyQ29sb3JbMV0gPSBnO1xuICAgIHNlbGYuY2xlYXJDb2xvclsyXSA9IGI7XG4gICAgc2VsZi5jbGVhckNvbG9yWzNdID0gYTtcbiAgICBzZWxmLnJlYWxDbGVhckNvbG9yLmNhbGwoZ2wsIHIsIGcsIGIsIGEpO1xuICB9O1xuXG4gIHRoaXMudmlld3BvcnQgPSBnbC5nZXRQYXJhbWV0ZXIoZ2wuVklFV1BPUlQpO1xuICBnbC52aWV3cG9ydCA9IGZ1bmN0aW9uKHgsIHksIHcsIGgpIHtcbiAgICBzZWxmLnZpZXdwb3J0WzBdID0geDtcbiAgICBzZWxmLnZpZXdwb3J0WzFdID0geTtcbiAgICBzZWxmLnZpZXdwb3J0WzJdID0gdztcbiAgICBzZWxmLnZpZXdwb3J0WzNdID0gaDtcbiAgICBzZWxmLnJlYWxWaWV3cG9ydC5jYWxsKGdsLCB4LCB5LCB3LCBoKTtcbiAgfTtcblxuICB0aGlzLmlzUGF0Y2hlZCA9IHRydWU7XG4gIFV0aWwuc2FmYXJpQ3NzU2l6ZVdvcmthcm91bmQoY2FudmFzKTtcbn07XG5cbkNhcmRib2FyZERpc3RvcnRlci5wcm90b3R5cGUudW5wYXRjaCA9IGZ1bmN0aW9uKCkge1xuICBpZiAoIXRoaXMuaXNQYXRjaGVkKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIGdsID0gdGhpcy5nbDtcbiAgdmFyIGNhbnZhcyA9IHRoaXMuZ2wuY2FudmFzO1xuXG4gIGlmICghVXRpbC5pc0lPUygpKSB7XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGNhbnZhcywgJ3dpZHRoJywgdGhpcy5yZWFsQ2FudmFzV2lkdGgpO1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjYW52YXMsICdoZWlnaHQnLCB0aGlzLnJlYWxDYW52YXNIZWlnaHQpO1xuICB9XG4gIGNhbnZhcy53aWR0aCA9IHRoaXMuYnVmZmVyV2lkdGg7XG4gIGNhbnZhcy5oZWlnaHQgPSB0aGlzLmJ1ZmZlckhlaWdodDtcblxuICBnbC5iaW5kRnJhbWVidWZmZXIgPSB0aGlzLnJlYWxCaW5kRnJhbWVidWZmZXI7XG4gIGdsLmVuYWJsZSA9IHRoaXMucmVhbEVuYWJsZTtcbiAgZ2wuZGlzYWJsZSA9IHRoaXMucmVhbERpc2FibGU7XG4gIGdsLmNvbG9yTWFzayA9IHRoaXMucmVhbENvbG9yTWFzaztcbiAgZ2wuY2xlYXJDb2xvciA9IHRoaXMucmVhbENsZWFyQ29sb3I7XG4gIGdsLnZpZXdwb3J0ID0gdGhpcy5yZWFsVmlld3BvcnQ7XG5cbiAgLy8gQ2hlY2sgdG8gc2VlIGlmIG91ciBmYWtlIGJhY2tidWZmZXIgaXMgYm91bmQgYW5kIGJpbmQgdGhlIHJlYWwgYmFja2J1ZmZlclxuICAvLyBpZiB0aGF0J3MgdGhlIGNhc2UuXG4gIGlmICh0aGlzLmxhc3RCb3VuZEZyYW1lYnVmZmVyID09IHRoaXMuZnJhbWVidWZmZXIpIHtcbiAgICBnbC5iaW5kRnJhbWVidWZmZXIoZ2wuRlJBTUVCVUZGRVIsIG51bGwpO1xuICB9XG5cbiAgdGhpcy5pc1BhdGNoZWQgPSBmYWxzZTtcblxuICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAgIFV0aWwuc2FmYXJpQ3NzU2l6ZVdvcmthcm91bmQoY2FudmFzKTtcbiAgfSwgMSk7XG59O1xuXG5DYXJkYm9hcmREaXN0b3J0ZXIucHJvdG90eXBlLnNldFRleHR1cmVCb3VuZHMgPSBmdW5jdGlvbihsZWZ0Qm91bmRzLCByaWdodEJvdW5kcykge1xuICBpZiAoIWxlZnRCb3VuZHMpIHtcbiAgICBsZWZ0Qm91bmRzID0gWzAsIDAsIDAuNSwgMV07XG4gIH1cblxuICBpZiAoIXJpZ2h0Qm91bmRzKSB7XG4gICAgcmlnaHRCb3VuZHMgPSBbMC41LCAwLCAwLjUsIDFdO1xuICB9XG5cbiAgLy8gTGVmdCBleWVcbiAgdGhpcy52aWV3cG9ydE9mZnNldFNjYWxlWzBdID0gbGVmdEJvdW5kc1swXTsgLy8gWFxuICB0aGlzLnZpZXdwb3J0T2Zmc2V0U2NhbGVbMV0gPSBsZWZ0Qm91bmRzWzFdOyAvLyBZXG4gIHRoaXMudmlld3BvcnRPZmZzZXRTY2FsZVsyXSA9IGxlZnRCb3VuZHNbMl07IC8vIFdpZHRoXG4gIHRoaXMudmlld3BvcnRPZmZzZXRTY2FsZVszXSA9IGxlZnRCb3VuZHNbM107IC8vIEhlaWdodFxuXG4gIC8vIFJpZ2h0IGV5ZVxuICB0aGlzLnZpZXdwb3J0T2Zmc2V0U2NhbGVbNF0gPSByaWdodEJvdW5kc1swXTsgLy8gWFxuICB0aGlzLnZpZXdwb3J0T2Zmc2V0U2NhbGVbNV0gPSByaWdodEJvdW5kc1sxXTsgLy8gWVxuICB0aGlzLnZpZXdwb3J0T2Zmc2V0U2NhbGVbNl0gPSByaWdodEJvdW5kc1syXTsgLy8gV2lkdGhcbiAgdGhpcy52aWV3cG9ydE9mZnNldFNjYWxlWzddID0gcmlnaHRCb3VuZHNbM107IC8vIEhlaWdodFxufTtcblxuLyoqXG4gKiBQZXJmb3JtcyBkaXN0b3J0aW9uIHBhc3Mgb24gdGhlIGluamVjdGVkIGJhY2tidWZmZXIsIHJlbmRlcmluZyBpdCB0byB0aGUgcmVhbFxuICogYmFja2J1ZmZlci5cbiAqL1xuQ2FyZGJvYXJkRGlzdG9ydGVyLnByb3RvdHlwZS5zdWJtaXRGcmFtZSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgZ2wgPSB0aGlzLmdsO1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdmFyIGdsU3RhdGUgPSBbXTtcblxuICBpZiAoIVdlYlZSQ29uZmlnLkRJUlRZX1NVQk1JVF9GUkFNRV9CSU5ESU5HUykge1xuICAgIGdsU3RhdGUucHVzaChcbiAgICAgIGdsLkNVUlJFTlRfUFJPR1JBTSxcbiAgICAgIGdsLkFSUkFZX0JVRkZFUl9CSU5ESU5HLFxuICAgICAgZ2wuRUxFTUVOVF9BUlJBWV9CVUZGRVJfQklORElORyxcbiAgICAgIGdsLlRFWFRVUkVfQklORElOR18yRCwgZ2wuVEVYVFVSRTBcbiAgICApO1xuICB9XG5cbiAgV0dMVVByZXNlcnZlR0xTdGF0ZShnbCwgZ2xTdGF0ZSwgZnVuY3Rpb24oZ2wpIHtcbiAgICAvLyBCaW5kIHRoZSByZWFsIGRlZmF1bHQgZnJhbWVidWZmZXJcbiAgICBzZWxmLnJlYWxCaW5kRnJhbWVidWZmZXIuY2FsbChnbCwgZ2wuRlJBTUVCVUZGRVIsIG51bGwpO1xuXG4gICAgLy8gTWFrZSBzdXJlIHRoZSBHTCBzdGF0ZSBpcyBpbiBhIGdvb2QgcGxhY2VcbiAgICBpZiAoc2VsZi5jdWxsRmFjZSkgeyBzZWxmLnJlYWxEaXNhYmxlLmNhbGwoZ2wsIGdsLkNVTExfRkFDRSk7IH1cbiAgICBpZiAoc2VsZi5kZXB0aFRlc3QpIHsgc2VsZi5yZWFsRGlzYWJsZS5jYWxsKGdsLCBnbC5ERVBUSF9URVNUKTsgfVxuICAgIGlmIChzZWxmLmJsZW5kKSB7IHNlbGYucmVhbERpc2FibGUuY2FsbChnbCwgZ2wuQkxFTkQpOyB9XG4gICAgaWYgKHNlbGYuc2Npc3NvclRlc3QpIHsgc2VsZi5yZWFsRGlzYWJsZS5jYWxsKGdsLCBnbC5TQ0lTU09SX1RFU1QpOyB9XG4gICAgaWYgKHNlbGYuc3RlbmNpbFRlc3QpIHsgc2VsZi5yZWFsRGlzYWJsZS5jYWxsKGdsLCBnbC5TVEVOQ0lMX1RFU1QpOyB9XG4gICAgc2VsZi5yZWFsQ29sb3JNYXNrLmNhbGwoZ2wsIHRydWUsIHRydWUsIHRydWUsIHRydWUpO1xuICAgIHNlbGYucmVhbFZpZXdwb3J0LmNhbGwoZ2wsIDAsIDAsIGdsLmRyYXdpbmdCdWZmZXJXaWR0aCwgZ2wuZHJhd2luZ0J1ZmZlckhlaWdodCk7XG5cbiAgICAvLyBJZiB0aGUgYmFja2J1ZmZlciBoYXMgYW4gYWxwaGEgY2hhbm5lbCBjbGVhciBldmVyeSBmcmFtZSBzbyB0aGUgcGFnZVxuICAgIC8vIGRvZXNuJ3Qgc2hvdyB0aHJvdWdoLlxuICAgIGlmIChzZWxmLmN0eEF0dHJpYnMuYWxwaGEgfHwgVXRpbC5pc0lPUygpKSB7XG4gICAgICBzZWxmLnJlYWxDbGVhckNvbG9yLmNhbGwoZ2wsIDAsIDAsIDAsIDEpO1xuICAgICAgZ2wuY2xlYXIoZ2wuQ09MT1JfQlVGRkVSX0JJVCk7XG4gICAgfVxuXG4gICAgLy8gQmluZCBkaXN0b3J0aW9uIHByb2dyYW0gYW5kIG1lc2hcbiAgICBnbC51c2VQcm9ncmFtKHNlbGYucHJvZ3JhbSk7XG5cbiAgICBnbC5iaW5kQnVmZmVyKGdsLkVMRU1FTlRfQVJSQVlfQlVGRkVSLCBzZWxmLmluZGV4QnVmZmVyKTtcblxuICAgIGdsLmJpbmRCdWZmZXIoZ2wuQVJSQVlfQlVGRkVSLCBzZWxmLnZlcnRleEJ1ZmZlcik7XG4gICAgZ2wuZW5hYmxlVmVydGV4QXR0cmliQXJyYXkoc2VsZi5hdHRyaWJzLnBvc2l0aW9uKTtcbiAgICBnbC5lbmFibGVWZXJ0ZXhBdHRyaWJBcnJheShzZWxmLmF0dHJpYnMudGV4Q29vcmQpO1xuICAgIGdsLnZlcnRleEF0dHJpYlBvaW50ZXIoc2VsZi5hdHRyaWJzLnBvc2l0aW9uLCAyLCBnbC5GTE9BVCwgZmFsc2UsIDIwLCAwKTtcbiAgICBnbC52ZXJ0ZXhBdHRyaWJQb2ludGVyKHNlbGYuYXR0cmlicy50ZXhDb29yZCwgMywgZ2wuRkxPQVQsIGZhbHNlLCAyMCwgOCk7XG5cbiAgICBnbC5hY3RpdmVUZXh0dXJlKGdsLlRFWFRVUkUwKTtcbiAgICBnbC51bmlmb3JtMWkoc2VsZi51bmlmb3Jtcy5kaWZmdXNlLCAwKTtcbiAgICBnbC5iaW5kVGV4dHVyZShnbC5URVhUVVJFXzJELCBzZWxmLnJlbmRlclRhcmdldCk7XG5cbiAgICBnbC51bmlmb3JtNGZ2KHNlbGYudW5pZm9ybXMudmlld3BvcnRPZmZzZXRTY2FsZSwgc2VsZi52aWV3cG9ydE9mZnNldFNjYWxlKTtcblxuICAgIC8vIERyYXdzIGJvdGggZXllc1xuICAgIGdsLmRyYXdFbGVtZW50cyhnbC5UUklBTkdMRVMsIHNlbGYuaW5kZXhDb3VudCwgZ2wuVU5TSUdORURfU0hPUlQsIDApO1xuXG4gICAgaWYgKHNlbGYuY2FyZGJvYXJkVUkpIHtcbiAgICAgIHNlbGYuY2FyZGJvYXJkVUkucmVuZGVyTm9TdGF0ZSgpO1xuICAgIH1cblxuICAgIC8vIEJpbmQgdGhlIGZha2UgZGVmYXVsdCBmcmFtZWJ1ZmZlciBhZ2FpblxuICAgIHNlbGYucmVhbEJpbmRGcmFtZWJ1ZmZlci5jYWxsKHNlbGYuZ2wsIGdsLkZSQU1FQlVGRkVSLCBzZWxmLmZyYW1lYnVmZmVyKTtcblxuICAgIC8vIElmIHByZXNlcnZlRHJhd2luZ0J1ZmZlciA9PSBmYWxzZSBjbGVhciB0aGUgZnJhbWVidWZmZXJcbiAgICBpZiAoIXNlbGYuY3R4QXR0cmlicy5wcmVzZXJ2ZURyYXdpbmdCdWZmZXIpIHtcbiAgICAgIHNlbGYucmVhbENsZWFyQ29sb3IuY2FsbChnbCwgMCwgMCwgMCwgMCk7XG4gICAgICBnbC5jbGVhcihnbC5DT0xPUl9CVUZGRVJfQklUKTtcbiAgICB9XG5cbiAgICBpZiAoIVdlYlZSQ29uZmlnLkRJUlRZX1NVQk1JVF9GUkFNRV9CSU5ESU5HUykge1xuICAgICAgc2VsZi5yZWFsQmluZEZyYW1lYnVmZmVyLmNhbGwoZ2wsIGdsLkZSQU1FQlVGRkVSLCBzZWxmLmxhc3RCb3VuZEZyYW1lYnVmZmVyKTtcbiAgICB9XG5cbiAgICAvLyBSZXN0b3JlIHN0YXRlXG4gICAgaWYgKHNlbGYuY3VsbEZhY2UpIHsgc2VsZi5yZWFsRW5hYmxlLmNhbGwoZ2wsIGdsLkNVTExfRkFDRSk7IH1cbiAgICBpZiAoc2VsZi5kZXB0aFRlc3QpIHsgc2VsZi5yZWFsRW5hYmxlLmNhbGwoZ2wsIGdsLkRFUFRIX1RFU1QpOyB9XG4gICAgaWYgKHNlbGYuYmxlbmQpIHsgc2VsZi5yZWFsRW5hYmxlLmNhbGwoZ2wsIGdsLkJMRU5EKTsgfVxuICAgIGlmIChzZWxmLnNjaXNzb3JUZXN0KSB7IHNlbGYucmVhbEVuYWJsZS5jYWxsKGdsLCBnbC5TQ0lTU09SX1RFU1QpOyB9XG4gICAgaWYgKHNlbGYuc3RlbmNpbFRlc3QpIHsgc2VsZi5yZWFsRW5hYmxlLmNhbGwoZ2wsIGdsLlNURU5DSUxfVEVTVCk7IH1cblxuICAgIHNlbGYucmVhbENvbG9yTWFzay5hcHBseShnbCwgc2VsZi5jb2xvck1hc2spO1xuICAgIHNlbGYucmVhbFZpZXdwb3J0LmFwcGx5KGdsLCBzZWxmLnZpZXdwb3J0KTtcbiAgICBpZiAoc2VsZi5jdHhBdHRyaWJzLmFscGhhIHx8ICFzZWxmLmN0eEF0dHJpYnMucHJlc2VydmVEcmF3aW5nQnVmZmVyKSB7XG4gICAgICBzZWxmLnJlYWxDbGVhckNvbG9yLmFwcGx5KGdsLCBzZWxmLmNsZWFyQ29sb3IpO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gV29ya2Fyb3VuZCBmb3IgdGhlIGZhY3QgdGhhdCBTYWZhcmkgZG9lc24ndCBhbGxvdyB1cyB0byBwYXRjaCB0aGUgY2FudmFzXG4gIC8vIHdpZHRoIGFuZCBoZWlnaHQgY29ycmVjdGx5LiBBZnRlciBlYWNoIHN1Ym1pdCBmcmFtZSBjaGVjayB0byBzZWUgd2hhdCB0aGVcbiAgLy8gcmVhbCBiYWNrYnVmZmVyIHNpemUgaGFzIGJlZW4gc2V0IHRvIGFuZCByZXNpemUgdGhlIGZha2UgYmFja2J1ZmZlciBzaXplXG4gIC8vIHRvIG1hdGNoLlxuICBpZiAoVXRpbC5pc0lPUygpKSB7XG4gICAgdmFyIGNhbnZhcyA9IGdsLmNhbnZhcztcbiAgICBpZiAoY2FudmFzLndpZHRoICE9IHNlbGYuYnVmZmVyV2lkdGggfHwgY2FudmFzLmhlaWdodCAhPSBzZWxmLmJ1ZmZlckhlaWdodCkge1xuICAgICAgc2VsZi5idWZmZXJXaWR0aCA9IGNhbnZhcy53aWR0aDtcbiAgICAgIHNlbGYuYnVmZmVySGVpZ2h0ID0gY2FudmFzLmhlaWdodDtcbiAgICAgIHNlbGYub25SZXNpemUoKTtcbiAgICB9XG4gIH1cbn07XG5cbi8qKlxuICogQ2FsbCB3aGVuIHRoZSBkZXZpY2VJbmZvIGhhcyBjaGFuZ2VkLiBBdCB0aGlzIHBvaW50IHdlIG5lZWRcbiAqIHRvIHJlLWNhbGN1bGF0ZSB0aGUgZGlzdG9ydGlvbiBtZXNoLlxuICovXG5DYXJkYm9hcmREaXN0b3J0ZXIucHJvdG90eXBlLnVwZGF0ZURldmljZUluZm8gPSBmdW5jdGlvbihkZXZpY2VJbmZvKSB7XG4gIHZhciBnbCA9IHRoaXMuZ2w7XG4gIHZhciBzZWxmID0gdGhpcztcblxuICB2YXIgZ2xTdGF0ZSA9IFtnbC5BUlJBWV9CVUZGRVJfQklORElORywgZ2wuRUxFTUVOVF9BUlJBWV9CVUZGRVJfQklORElOR107XG4gIFdHTFVQcmVzZXJ2ZUdMU3RhdGUoZ2wsIGdsU3RhdGUsIGZ1bmN0aW9uKGdsKSB7XG4gICAgdmFyIHZlcnRpY2VzID0gc2VsZi5jb21wdXRlTWVzaFZlcnRpY2VzXyhzZWxmLm1lc2hXaWR0aCwgc2VsZi5tZXNoSGVpZ2h0LCBkZXZpY2VJbmZvKTtcbiAgICBnbC5iaW5kQnVmZmVyKGdsLkFSUkFZX0JVRkZFUiwgc2VsZi52ZXJ0ZXhCdWZmZXIpO1xuICAgIGdsLmJ1ZmZlckRhdGEoZ2wuQVJSQVlfQlVGRkVSLCB2ZXJ0aWNlcywgZ2wuU1RBVElDX0RSQVcpO1xuXG4gICAgLy8gSW5kaWNlcyBkb24ndCBjaGFuZ2UgYmFzZWQgb24gZGV2aWNlIHBhcmFtZXRlcnMsIHNvIG9ubHkgY29tcHV0ZSBvbmNlLlxuICAgIGlmICghc2VsZi5pbmRleENvdW50KSB7XG4gICAgICB2YXIgaW5kaWNlcyA9IHNlbGYuY29tcHV0ZU1lc2hJbmRpY2VzXyhzZWxmLm1lc2hXaWR0aCwgc2VsZi5tZXNoSGVpZ2h0KTtcbiAgICAgIGdsLmJpbmRCdWZmZXIoZ2wuRUxFTUVOVF9BUlJBWV9CVUZGRVIsIHNlbGYuaW5kZXhCdWZmZXIpO1xuICAgICAgZ2wuYnVmZmVyRGF0YShnbC5FTEVNRU5UX0FSUkFZX0JVRkZFUiwgaW5kaWNlcywgZ2wuU1RBVElDX0RSQVcpO1xuICAgICAgc2VsZi5pbmRleENvdW50ID0gaW5kaWNlcy5sZW5ndGg7XG4gICAgfVxuICB9KTtcbn07XG5cbi8qKlxuICogQnVpbGQgdGhlIGRpc3RvcnRpb24gbWVzaCB2ZXJ0aWNlcy5cbiAqIEJhc2VkIG9uIGNvZGUgZnJvbSB0aGUgVW5pdHkgY2FyZGJvYXJkIHBsdWdpbi5cbiAqL1xuQ2FyZGJvYXJkRGlzdG9ydGVyLnByb3RvdHlwZS5jb21wdXRlTWVzaFZlcnRpY2VzXyA9IGZ1bmN0aW9uKHdpZHRoLCBoZWlnaHQsIGRldmljZUluZm8pIHtcbiAgdmFyIHZlcnRpY2VzID0gbmV3IEZsb2F0MzJBcnJheSgyICogd2lkdGggKiBoZWlnaHQgKiA1KTtcblxuICB2YXIgbGVuc0ZydXN0dW0gPSBkZXZpY2VJbmZvLmdldExlZnRFeWVWaXNpYmxlVGFuQW5nbGVzKCk7XG4gIHZhciBub0xlbnNGcnVzdHVtID0gZGV2aWNlSW5mby5nZXRMZWZ0RXllTm9MZW5zVGFuQW5nbGVzKCk7XG4gIHZhciB2aWV3cG9ydCA9IGRldmljZUluZm8uZ2V0TGVmdEV5ZVZpc2libGVTY3JlZW5SZWN0KG5vTGVuc0ZydXN0dW0pO1xuICB2YXIgdmlkeCA9IDA7XG4gIHZhciBpaWR4ID0gMDtcbiAgZm9yICh2YXIgZSA9IDA7IGUgPCAyOyBlKyspIHtcbiAgICBmb3IgKHZhciBqID0gMDsgaiA8IGhlaWdodDsgaisrKSB7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHdpZHRoOyBpKyssIHZpZHgrKykge1xuICAgICAgICB2YXIgdSA9IGkgLyAod2lkdGggLSAxKTtcbiAgICAgICAgdmFyIHYgPSBqIC8gKGhlaWdodCAtIDEpO1xuXG4gICAgICAgIC8vIEdyaWQgcG9pbnRzIHJlZ3VsYXJseSBzcGFjZWQgaW4gU3RyZW9TY3JlZW4sIGFuZCBiYXJyZWwgZGlzdG9ydGVkIGluXG4gICAgICAgIC8vIHRoZSBtZXNoLlxuICAgICAgICB2YXIgcyA9IHU7XG4gICAgICAgIHZhciB0ID0gdjtcbiAgICAgICAgdmFyIHggPSBVdGlsLmxlcnAobGVuc0ZydXN0dW1bMF0sIGxlbnNGcnVzdHVtWzJdLCB1KTtcbiAgICAgICAgdmFyIHkgPSBVdGlsLmxlcnAobGVuc0ZydXN0dW1bM10sIGxlbnNGcnVzdHVtWzFdLCB2KTtcbiAgICAgICAgdmFyIGQgPSBNYXRoLnNxcnQoeCAqIHggKyB5ICogeSk7XG4gICAgICAgIHZhciByID0gZGV2aWNlSW5mby5kaXN0b3J0aW9uLmRpc3RvcnRJbnZlcnNlKGQpO1xuICAgICAgICB2YXIgcCA9IHggKiByIC8gZDtcbiAgICAgICAgdmFyIHEgPSB5ICogciAvIGQ7XG4gICAgICAgIHUgPSAocCAtIG5vTGVuc0ZydXN0dW1bMF0pIC8gKG5vTGVuc0ZydXN0dW1bMl0gLSBub0xlbnNGcnVzdHVtWzBdKTtcbiAgICAgICAgdiA9IChxIC0gbm9MZW5zRnJ1c3R1bVszXSkgLyAobm9MZW5zRnJ1c3R1bVsxXSAtIG5vTGVuc0ZydXN0dW1bM10pO1xuXG4gICAgICAgIC8vIENvbnZlcnQgdSx2IHRvIG1lc2ggc2NyZWVuIGNvb3JkaW5hdGVzLlxuICAgICAgICB2YXIgYXNwZWN0ID0gZGV2aWNlSW5mby5kZXZpY2Uud2lkdGhNZXRlcnMgLyBkZXZpY2VJbmZvLmRldmljZS5oZWlnaHRNZXRlcnM7XG5cbiAgICAgICAgLy8gRklYTUU6IFRoZSBvcmlnaW5hbCBVbml0eSBwbHVnaW4gbXVsdGlwbGllZCBVIGJ5IHRoZSBhc3BlY3QgcmF0aW9cbiAgICAgICAgLy8gYW5kIGRpZG4ndCBtdWx0aXBseSBlaXRoZXIgdmFsdWUgYnkgMiwgYnV0IHRoYXQgc2VlbXMgdG8gZ2V0IGl0XG4gICAgICAgIC8vIHJlYWxseSBjbG9zZSB0byBjb3JyZWN0IGxvb2tpbmcgZm9yIG1lLiBJIGhhdGUgdGhpcyBraW5kIG9mIFwiRG9uJ3RcbiAgICAgICAgLy8ga25vdyB3aHkgaXQgd29ya3NcIiBjb2RlIHRob3VnaCwgYW5kIHdvbGQgbG92ZSBhIG1vcmUgbG9naWNhbFxuICAgICAgICAvLyBleHBsYW5hdGlvbiBvZiB3aGF0IG5lZWRzIHRvIGhhcHBlbiBoZXJlLlxuICAgICAgICB1ID0gKHZpZXdwb3J0LnggKyB1ICogdmlld3BvcnQud2lkdGggLSAwLjUpICogMi4wOyAvLyogYXNwZWN0O1xuICAgICAgICB2ID0gKHZpZXdwb3J0LnkgKyB2ICogdmlld3BvcnQuaGVpZ2h0IC0gMC41KSAqIDIuMDtcblxuICAgICAgICB2ZXJ0aWNlc1sodmlkeCAqIDUpICsgMF0gPSB1OyAvLyBwb3NpdGlvbi54XG4gICAgICAgIHZlcnRpY2VzWyh2aWR4ICogNSkgKyAxXSA9IHY7IC8vIHBvc2l0aW9uLnlcbiAgICAgICAgdmVydGljZXNbKHZpZHggKiA1KSArIDJdID0gczsgLy8gdGV4Q29vcmQueFxuICAgICAgICB2ZXJ0aWNlc1sodmlkeCAqIDUpICsgM10gPSB0OyAvLyB0ZXhDb29yZC55XG4gICAgICAgIHZlcnRpY2VzWyh2aWR4ICogNSkgKyA0XSA9IGU7IC8vIHRleENvb3JkLnogKHZpZXdwb3J0IGluZGV4KVxuICAgICAgfVxuICAgIH1cbiAgICB2YXIgdyA9IGxlbnNGcnVzdHVtWzJdIC0gbGVuc0ZydXN0dW1bMF07XG4gICAgbGVuc0ZydXN0dW1bMF0gPSAtKHcgKyBsZW5zRnJ1c3R1bVswXSk7XG4gICAgbGVuc0ZydXN0dW1bMl0gPSB3IC0gbGVuc0ZydXN0dW1bMl07XG4gICAgdyA9IG5vTGVuc0ZydXN0dW1bMl0gLSBub0xlbnNGcnVzdHVtWzBdO1xuICAgIG5vTGVuc0ZydXN0dW1bMF0gPSAtKHcgKyBub0xlbnNGcnVzdHVtWzBdKTtcbiAgICBub0xlbnNGcnVzdHVtWzJdID0gdyAtIG5vTGVuc0ZydXN0dW1bMl07XG4gICAgdmlld3BvcnQueCA9IDEgLSAodmlld3BvcnQueCArIHZpZXdwb3J0LndpZHRoKTtcbiAgfVxuICByZXR1cm4gdmVydGljZXM7XG59XG5cbi8qKlxuICogQnVpbGQgdGhlIGRpc3RvcnRpb24gbWVzaCBpbmRpY2VzLlxuICogQmFzZWQgb24gY29kZSBmcm9tIHRoZSBVbml0eSBjYXJkYm9hcmQgcGx1Z2luLlxuICovXG5DYXJkYm9hcmREaXN0b3J0ZXIucHJvdG90eXBlLmNvbXB1dGVNZXNoSW5kaWNlc18gPSBmdW5jdGlvbih3aWR0aCwgaGVpZ2h0KSB7XG4gIHZhciBpbmRpY2VzID0gbmV3IFVpbnQxNkFycmF5KDIgKiAod2lkdGggLSAxKSAqIChoZWlnaHQgLSAxKSAqIDYpO1xuICB2YXIgaGFsZndpZHRoID0gd2lkdGggLyAyO1xuICB2YXIgaGFsZmhlaWdodCA9IGhlaWdodCAvIDI7XG4gIHZhciB2aWR4ID0gMDtcbiAgdmFyIGlpZHggPSAwO1xuICBmb3IgKHZhciBlID0gMDsgZSA8IDI7IGUrKykge1xuICAgIGZvciAodmFyIGogPSAwOyBqIDwgaGVpZ2h0OyBqKyspIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgd2lkdGg7IGkrKywgdmlkeCsrKSB7XG4gICAgICAgIGlmIChpID09IDAgfHwgaiA9PSAwKVxuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAvLyBCdWlsZCBhIHF1YWQuICBMb3dlciByaWdodCBhbmQgdXBwZXIgbGVmdCBxdWFkcmFudHMgaGF2ZSBxdWFkcyB3aXRoXG4gICAgICAgIC8vIHRoZSB0cmlhbmdsZSBkaWFnb25hbCBmbGlwcGVkIHRvIGdldCB0aGUgdmlnbmV0dGUgdG8gaW50ZXJwb2xhdGVcbiAgICAgICAgLy8gY29ycmVjdGx5LlxuICAgICAgICBpZiAoKGkgPD0gaGFsZndpZHRoKSA9PSAoaiA8PSBoYWxmaGVpZ2h0KSkge1xuICAgICAgICAgIC8vIFF1YWQgZGlhZ29uYWwgbG93ZXIgbGVmdCB0byB1cHBlciByaWdodC5cbiAgICAgICAgICBpbmRpY2VzW2lpZHgrK10gPSB2aWR4O1xuICAgICAgICAgIGluZGljZXNbaWlkeCsrXSA9IHZpZHggLSB3aWR0aCAtIDE7XG4gICAgICAgICAgaW5kaWNlc1tpaWR4KytdID0gdmlkeCAtIHdpZHRoO1xuICAgICAgICAgIGluZGljZXNbaWlkeCsrXSA9IHZpZHggLSB3aWR0aCAtIDE7XG4gICAgICAgICAgaW5kaWNlc1tpaWR4KytdID0gdmlkeDtcbiAgICAgICAgICBpbmRpY2VzW2lpZHgrK10gPSB2aWR4IC0gMTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBRdWFkIGRpYWdvbmFsIHVwcGVyIGxlZnQgdG8gbG93ZXIgcmlnaHQuXG4gICAgICAgICAgaW5kaWNlc1tpaWR4KytdID0gdmlkeCAtIDE7XG4gICAgICAgICAgaW5kaWNlc1tpaWR4KytdID0gdmlkeCAtIHdpZHRoO1xuICAgICAgICAgIGluZGljZXNbaWlkeCsrXSA9IHZpZHg7XG4gICAgICAgICAgaW5kaWNlc1tpaWR4KytdID0gdmlkeCAtIHdpZHRoO1xuICAgICAgICAgIGluZGljZXNbaWlkeCsrXSA9IHZpZHggLSAxO1xuICAgICAgICAgIGluZGljZXNbaWlkeCsrXSA9IHZpZHggLSB3aWR0aCAtIDE7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIGluZGljZXM7XG59O1xuXG5DYXJkYm9hcmREaXN0b3J0ZXIucHJvdG90eXBlLmdldE93blByb3BlcnR5RGVzY3JpcHRvcl8gPSBmdW5jdGlvbihwcm90bywgYXR0ck5hbWUpIHtcbiAgdmFyIGRlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHByb3RvLCBhdHRyTmFtZSk7XG4gIC8vIEluIHNvbWUgY2FzZXMgKGFoZW0uLi4gU2FmYXJpKSwgdGhlIGRlc2NyaXB0b3IgcmV0dXJucyB1bmRlZmluZWQgZ2V0IGFuZFxuICAvLyBzZXQgZmllbGRzLiBJbiB0aGlzIGNhc2UsIHdlIG5lZWQgdG8gY3JlYXRlIGEgc3ludGhldGljIHByb3BlcnR5XG4gIC8vIGRlc2NyaXB0b3IuIFRoaXMgd29ya3MgYXJvdW5kIHNvbWUgb2YgdGhlIGlzc3VlcyBpblxuICAvLyBodHRwczovL2dpdGh1Yi5jb20vYm9yaXNtdXMvd2VidnItcG9seWZpbGwvaXNzdWVzLzQ2XG4gIGlmIChkZXNjcmlwdG9yLmdldCA9PT0gdW5kZWZpbmVkIHx8IGRlc2NyaXB0b3Iuc2V0ID09PSB1bmRlZmluZWQpIHtcbiAgICBkZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSA9IHRydWU7XG4gICAgZGVzY3JpcHRvci5lbnVtZXJhYmxlID0gdHJ1ZTtcbiAgICBkZXNjcmlwdG9yLmdldCA9IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cmlidXRlKGF0dHJOYW1lKTtcbiAgICB9O1xuICAgIGRlc2NyaXB0b3Iuc2V0ID0gZnVuY3Rpb24odmFsKSB7XG4gICAgICB0aGlzLnNldEF0dHJpYnV0ZShhdHRyTmFtZSwgdmFsKTtcbiAgICB9O1xuICB9XG4gIHJldHVybiBkZXNjcmlwdG9yO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBDYXJkYm9hcmREaXN0b3J0ZXI7XG5cbn0se1wiLi9jYXJkYm9hcmQtdWkuanNcIjo1LFwiLi9kZXBzL3dnbHUtcHJlc2VydmUtc3RhdGUuanNcIjo3LFwiLi91dGlsLmpzXCI6MjJ9XSw1OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcbi8qXG4gKiBDb3B5cmlnaHQgMjAxNiBHb29nbGUgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbnZhciBVdGlsID0gX2RlcmVxXygnLi91dGlsLmpzJyk7XG52YXIgV0dMVVByZXNlcnZlR0xTdGF0ZSA9IF9kZXJlcV8oJy4vZGVwcy93Z2x1LXByZXNlcnZlLXN0YXRlLmpzJyk7XG5cbnZhciB1aVZTID0gW1xuICAnYXR0cmlidXRlIHZlYzIgcG9zaXRpb247JyxcblxuICAndW5pZm9ybSBtYXQ0IHByb2plY3Rpb25NYXQ7JyxcblxuICAndm9pZCBtYWluKCkgeycsXG4gICcgIGdsX1Bvc2l0aW9uID0gcHJvamVjdGlvbk1hdCAqIHZlYzQoIHBvc2l0aW9uLCAtMS4wLCAxLjAgKTsnLFxuICAnfScsXG5dLmpvaW4oJ1xcbicpO1xuXG52YXIgdWlGUyA9IFtcbiAgJ3ByZWNpc2lvbiBtZWRpdW1wIGZsb2F0OycsXG5cbiAgJ3VuaWZvcm0gdmVjNCBjb2xvcjsnLFxuXG4gICd2b2lkIG1haW4oKSB7JyxcbiAgJyAgZ2xfRnJhZ0NvbG9yID0gY29sb3I7JyxcbiAgJ30nLFxuXS5qb2luKCdcXG4nKTtcblxudmFyIERFRzJSQUQgPSBNYXRoLlBJLzE4MC4wO1xuXG4vLyBUaGUgZ2VhciBoYXMgNiBpZGVudGljYWwgc2VjdGlvbnMsIGVhY2ggc3Bhbm5pbmcgNjAgZGVncmVlcy5cbnZhciBrQW5nbGVQZXJHZWFyU2VjdGlvbiA9IDYwO1xuXG4vLyBIYWxmLWFuZ2xlIG9mIHRoZSBzcGFuIG9mIHRoZSBvdXRlciByaW0uXG52YXIga091dGVyUmltRW5kQW5nbGUgPSAxMjtcblxuLy8gQW5nbGUgYmV0d2VlbiB0aGUgbWlkZGxlIG9mIHRoZSBvdXRlciByaW0gYW5kIHRoZSBzdGFydCBvZiB0aGUgaW5uZXIgcmltLlxudmFyIGtJbm5lclJpbUJlZ2luQW5nbGUgPSAyMDtcblxuLy8gRGlzdGFuY2UgZnJvbSBjZW50ZXIgdG8gb3V0ZXIgcmltLCBub3JtYWxpemVkIHNvIHRoYXQgdGhlIGVudGlyZSBtb2RlbFxuLy8gZml0cyBpbiBhIFstMSwgMV0geCBbLTEsIDFdIHNxdWFyZS5cbnZhciBrT3V0ZXJSYWRpdXMgPSAxO1xuXG4vLyBEaXN0YW5jZSBmcm9tIGNlbnRlciB0byBkZXByZXNzZWQgcmltLCBpbiBtb2RlbCB1bml0cy5cbnZhciBrTWlkZGxlUmFkaXVzID0gMC43NTtcblxuLy8gUmFkaXVzIG9mIHRoZSBpbm5lciBob2xsb3cgY2lyY2xlLCBpbiBtb2RlbCB1bml0cy5cbnZhciBrSW5uZXJSYWRpdXMgPSAwLjMxMjU7XG5cbi8vIENlbnRlciBsaW5lIHRoaWNrbmVzcyBpbiBEUC5cbnZhciBrQ2VudGVyTGluZVRoaWNrbmVzc0RwID0gNDtcblxuLy8gQnV0dG9uIHdpZHRoIGluIERQLlxudmFyIGtCdXR0b25XaWR0aERwID0gMjg7XG5cbi8vIEZhY3RvciB0byBzY2FsZSB0aGUgdG91Y2ggYXJlYSB0aGF0IHJlc3BvbmRzIHRvIHRoZSB0b3VjaC5cbnZhciBrVG91Y2hTbG9wRmFjdG9yID0gMS41O1xuXG52YXIgQW5nbGVzID0gW1xuICAwLCBrT3V0ZXJSaW1FbmRBbmdsZSwga0lubmVyUmltQmVnaW5BbmdsZSxcbiAga0FuZ2xlUGVyR2VhclNlY3Rpb24gLSBrSW5uZXJSaW1CZWdpbkFuZ2xlLFxuICBrQW5nbGVQZXJHZWFyU2VjdGlvbiAtIGtPdXRlclJpbUVuZEFuZ2xlXG5dO1xuXG4vKipcbiAqIFJlbmRlcnMgdGhlIGFsaWdubWVudCBsaW5lIGFuZCBcIm9wdGlvbnNcIiBnZWFyLiBJdCBpcyBhc3N1bWVkIHRoYXQgdGhlIGNhbnZhc1xuICogdGhpcyBpcyByZW5kZXJlZCBpbnRvIGNvdmVycyB0aGUgZW50aXJlIHNjcmVlbiAob3IgY2xvc2UgdG8gaXQuKVxuICovXG5mdW5jdGlvbiBDYXJkYm9hcmRVSShnbCkge1xuICB0aGlzLmdsID0gZ2w7XG5cbiAgdGhpcy5hdHRyaWJzID0ge1xuICAgIHBvc2l0aW9uOiAwXG4gIH07XG4gIHRoaXMucHJvZ3JhbSA9IFV0aWwubGlua1Byb2dyYW0oZ2wsIHVpVlMsIHVpRlMsIHRoaXMuYXR0cmlicyk7XG4gIHRoaXMudW5pZm9ybXMgPSBVdGlsLmdldFByb2dyYW1Vbmlmb3JtcyhnbCwgdGhpcy5wcm9ncmFtKTtcblxuICB0aGlzLnZlcnRleEJ1ZmZlciA9IGdsLmNyZWF0ZUJ1ZmZlcigpO1xuICB0aGlzLmdlYXJPZmZzZXQgPSAwO1xuICB0aGlzLmdlYXJWZXJ0ZXhDb3VudCA9IDA7XG4gIHRoaXMuYXJyb3dPZmZzZXQgPSAwO1xuICB0aGlzLmFycm93VmVydGV4Q291bnQgPSAwO1xuXG4gIHRoaXMucHJvak1hdCA9IG5ldyBGbG9hdDMyQXJyYXkoMTYpO1xuXG4gIHRoaXMubGlzdGVuZXIgPSBudWxsO1xuXG4gIHRoaXMub25SZXNpemUoKTtcbn07XG5cbi8qKlxuICogVGVhcnMgZG93biBhbGwgdGhlIHJlc291cmNlcyBjcmVhdGVkIGJ5IHRoZSBVSSByZW5kZXJlci5cbiAqL1xuQ2FyZGJvYXJkVUkucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGdsID0gdGhpcy5nbDtcblxuICBpZiAodGhpcy5saXN0ZW5lcikge1xuICAgIGdsLmNhbnZhcy5yZW1vdmVFdmVudExpc3RlbmVyKCdjbGljaycsIHRoaXMubGlzdGVuZXIsIGZhbHNlKTtcbiAgfVxuXG4gIGdsLmRlbGV0ZVByb2dyYW0odGhpcy5wcm9ncmFtKTtcbiAgZ2wuZGVsZXRlQnVmZmVyKHRoaXMudmVydGV4QnVmZmVyKTtcbn07XG5cbi8qKlxuICogQWRkcyBhIGxpc3RlbmVyIHRvIGNsaWNrcyBvbiB0aGUgZ2VhciBhbmQgYmFjayBpY29uc1xuICovXG5DYXJkYm9hcmRVSS5wcm90b3R5cGUubGlzdGVuID0gZnVuY3Rpb24ob3B0aW9uc0NhbGxiYWNrLCBiYWNrQ2FsbGJhY2spIHtcbiAgdmFyIGNhbnZhcyA9IHRoaXMuZ2wuY2FudmFzO1xuICB0aGlzLmxpc3RlbmVyID0gZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgbWlkbGluZSA9IGNhbnZhcy5jbGllbnRXaWR0aCAvIDI7XG4gICAgdmFyIGJ1dHRvblNpemUgPSBrQnV0dG9uV2lkdGhEcCAqIGtUb3VjaFNsb3BGYWN0b3I7XG4gICAgLy8gQ2hlY2sgdG8gc2VlIGlmIHRoZSB1c2VyIGNsaWNrZWQgb24gKG9yIGFyb3VuZCkgdGhlIGdlYXIgaWNvblxuICAgIGlmIChldmVudC5jbGllbnRYID4gbWlkbGluZSAtIGJ1dHRvblNpemUgJiZcbiAgICAgICAgZXZlbnQuY2xpZW50WCA8IG1pZGxpbmUgKyBidXR0b25TaXplICYmXG4gICAgICAgIGV2ZW50LmNsaWVudFkgPiBjYW52YXMuY2xpZW50SGVpZ2h0IC0gYnV0dG9uU2l6ZSkge1xuICAgICAgb3B0aW9uc0NhbGxiYWNrKGV2ZW50KTtcbiAgICB9XG4gICAgLy8gQ2hlY2sgdG8gc2VlIGlmIHRoZSB1c2VyIGNsaWNrZWQgb24gKG9yIGFyb3VuZCkgdGhlIGJhY2sgaWNvblxuICAgIGVsc2UgaWYgKGV2ZW50LmNsaWVudFggPCBidXR0b25TaXplICYmIGV2ZW50LmNsaWVudFkgPCBidXR0b25TaXplKSB7XG4gICAgICBiYWNrQ2FsbGJhY2soZXZlbnQpO1xuICAgIH1cbiAgfTtcbiAgY2FudmFzLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5saXN0ZW5lciwgZmFsc2UpO1xufTtcblxuLyoqXG4gKiBCdWlsZHMgdGhlIFVJIG1lc2guXG4gKi9cbkNhcmRib2FyZFVJLnByb3RvdHlwZS5vblJlc2l6ZSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgZ2wgPSB0aGlzLmdsO1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdmFyIGdsU3RhdGUgPSBbXG4gICAgZ2wuQVJSQVlfQlVGRkVSX0JJTkRJTkdcbiAgXTtcblxuICBXR0xVUHJlc2VydmVHTFN0YXRlKGdsLCBnbFN0YXRlLCBmdW5jdGlvbihnbCkge1xuICAgIHZhciB2ZXJ0aWNlcyA9IFtdO1xuXG4gICAgdmFyIG1pZGxpbmUgPSBnbC5kcmF3aW5nQnVmZmVyV2lkdGggLyAyO1xuXG4gICAgLy8gQXNzdW1lcyB5b3VyIGNhbnZhcyB3aWR0aCBhbmQgaGVpZ2h0IGlzIHNjYWxlZCBwcm9wb3J0aW9uYXRlbHkuXG4gICAgLy8gVE9ETyhzbXVzKTogVGhlIGZvbGxvd2luZyBjYXVzZXMgYnV0dG9ucyB0byBiZWNvbWUgaHVnZSBvbiBpT1MsIGJ1dCBzZWVtc1xuICAgIC8vIGxpa2UgdGhlIHJpZ2h0IHRoaW5nIHRvIGRvLiBGb3Igbm93LCBhZGRlZCBhIGhhY2suIEJ1dCByZWFsbHksIGludmVzdGlnYXRlIHdoeS5cbiAgICB2YXIgZHBzID0gKGdsLmRyYXdpbmdCdWZmZXJXaWR0aCAvIChzY3JlZW4ud2lkdGggKiB3aW5kb3cuZGV2aWNlUGl4ZWxSYXRpbykpO1xuICAgIGlmICghVXRpbC5pc0lPUygpKSB7XG4gICAgICBkcHMgKj0gd2luZG93LmRldmljZVBpeGVsUmF0aW87XG4gICAgfVxuXG4gICAgdmFyIGxpbmVXaWR0aCA9IGtDZW50ZXJMaW5lVGhpY2tuZXNzRHAgKiBkcHMgLyAyO1xuICAgIHZhciBidXR0b25TaXplID0ga0J1dHRvbldpZHRoRHAgKiBrVG91Y2hTbG9wRmFjdG9yICogZHBzO1xuICAgIHZhciBidXR0b25TY2FsZSA9IGtCdXR0b25XaWR0aERwICogZHBzIC8gMjtcbiAgICB2YXIgYnV0dG9uQm9yZGVyID0gKChrQnV0dG9uV2lkdGhEcCAqIGtUb3VjaFNsb3BGYWN0b3IpIC0ga0J1dHRvbldpZHRoRHApICogZHBzO1xuXG4gICAgLy8gQnVpbGQgY2VudGVybGluZVxuICAgIHZlcnRpY2VzLnB1c2gobWlkbGluZSAtIGxpbmVXaWR0aCwgYnV0dG9uU2l6ZSk7XG4gICAgdmVydGljZXMucHVzaChtaWRsaW5lIC0gbGluZVdpZHRoLCBnbC5kcmF3aW5nQnVmZmVySGVpZ2h0KTtcbiAgICB2ZXJ0aWNlcy5wdXNoKG1pZGxpbmUgKyBsaW5lV2lkdGgsIGJ1dHRvblNpemUpO1xuICAgIHZlcnRpY2VzLnB1c2gobWlkbGluZSArIGxpbmVXaWR0aCwgZ2wuZHJhd2luZ0J1ZmZlckhlaWdodCk7XG5cbiAgICAvLyBCdWlsZCBnZWFyXG4gICAgc2VsZi5nZWFyT2Zmc2V0ID0gKHZlcnRpY2VzLmxlbmd0aCAvIDIpO1xuXG4gICAgZnVuY3Rpb24gYWRkR2VhclNlZ21lbnQodGhldGEsIHIpIHtcbiAgICAgIHZhciBhbmdsZSA9ICg5MCAtIHRoZXRhKSAqIERFRzJSQUQ7XG4gICAgICB2YXIgeCA9IE1hdGguY29zKGFuZ2xlKTtcbiAgICAgIHZhciB5ID0gTWF0aC5zaW4oYW5nbGUpO1xuICAgICAgdmVydGljZXMucHVzaChrSW5uZXJSYWRpdXMgKiB4ICogYnV0dG9uU2NhbGUgKyBtaWRsaW5lLCBrSW5uZXJSYWRpdXMgKiB5ICogYnV0dG9uU2NhbGUgKyBidXR0b25TY2FsZSk7XG4gICAgICB2ZXJ0aWNlcy5wdXNoKHIgKiB4ICogYnV0dG9uU2NhbGUgKyBtaWRsaW5lLCByICogeSAqIGJ1dHRvblNjYWxlICsgYnV0dG9uU2NhbGUpO1xuICAgIH1cblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDw9IDY7IGkrKykge1xuICAgICAgdmFyIHNlZ21lbnRUaGV0YSA9IGkgKiBrQW5nbGVQZXJHZWFyU2VjdGlvbjtcblxuICAgICAgYWRkR2VhclNlZ21lbnQoc2VnbWVudFRoZXRhLCBrT3V0ZXJSYWRpdXMpO1xuICAgICAgYWRkR2VhclNlZ21lbnQoc2VnbWVudFRoZXRhICsga091dGVyUmltRW5kQW5nbGUsIGtPdXRlclJhZGl1cyk7XG4gICAgICBhZGRHZWFyU2VnbWVudChzZWdtZW50VGhldGEgKyBrSW5uZXJSaW1CZWdpbkFuZ2xlLCBrTWlkZGxlUmFkaXVzKTtcbiAgICAgIGFkZEdlYXJTZWdtZW50KHNlZ21lbnRUaGV0YSArIChrQW5nbGVQZXJHZWFyU2VjdGlvbiAtIGtJbm5lclJpbUJlZ2luQW5nbGUpLCBrTWlkZGxlUmFkaXVzKTtcbiAgICAgIGFkZEdlYXJTZWdtZW50KHNlZ21lbnRUaGV0YSArIChrQW5nbGVQZXJHZWFyU2VjdGlvbiAtIGtPdXRlclJpbUVuZEFuZ2xlKSwga091dGVyUmFkaXVzKTtcbiAgICB9XG5cbiAgICBzZWxmLmdlYXJWZXJ0ZXhDb3VudCA9ICh2ZXJ0aWNlcy5sZW5ndGggLyAyKSAtIHNlbGYuZ2Vhck9mZnNldDtcblxuICAgIC8vIEJ1aWxkIGJhY2sgYXJyb3dcbiAgICBzZWxmLmFycm93T2Zmc2V0ID0gKHZlcnRpY2VzLmxlbmd0aCAvIDIpO1xuXG4gICAgZnVuY3Rpb24gYWRkQXJyb3dWZXJ0ZXgoeCwgeSkge1xuICAgICAgdmVydGljZXMucHVzaChidXR0b25Cb3JkZXIgKyB4LCBnbC5kcmF3aW5nQnVmZmVySGVpZ2h0IC0gYnV0dG9uQm9yZGVyIC0geSk7XG4gICAgfVxuXG4gICAgdmFyIGFuZ2xlZExpbmVXaWR0aCA9IGxpbmVXaWR0aCAvIE1hdGguc2luKDQ1ICogREVHMlJBRCk7XG5cbiAgICBhZGRBcnJvd1ZlcnRleCgwLCBidXR0b25TY2FsZSk7XG4gICAgYWRkQXJyb3dWZXJ0ZXgoYnV0dG9uU2NhbGUsIDApO1xuICAgIGFkZEFycm93VmVydGV4KGJ1dHRvblNjYWxlICsgYW5nbGVkTGluZVdpZHRoLCBhbmdsZWRMaW5lV2lkdGgpO1xuICAgIGFkZEFycm93VmVydGV4KGFuZ2xlZExpbmVXaWR0aCwgYnV0dG9uU2NhbGUgKyBhbmdsZWRMaW5lV2lkdGgpO1xuXG4gICAgYWRkQXJyb3dWZXJ0ZXgoYW5nbGVkTGluZVdpZHRoLCBidXR0b25TY2FsZSAtIGFuZ2xlZExpbmVXaWR0aCk7XG4gICAgYWRkQXJyb3dWZXJ0ZXgoMCwgYnV0dG9uU2NhbGUpO1xuICAgIGFkZEFycm93VmVydGV4KGJ1dHRvblNjYWxlLCBidXR0b25TY2FsZSAqIDIpO1xuICAgIGFkZEFycm93VmVydGV4KGJ1dHRvblNjYWxlICsgYW5nbGVkTGluZVdpZHRoLCAoYnV0dG9uU2NhbGUgKiAyKSAtIGFuZ2xlZExpbmVXaWR0aCk7XG5cbiAgICBhZGRBcnJvd1ZlcnRleChhbmdsZWRMaW5lV2lkdGgsIGJ1dHRvblNjYWxlIC0gYW5nbGVkTGluZVdpZHRoKTtcbiAgICBhZGRBcnJvd1ZlcnRleCgwLCBidXR0b25TY2FsZSk7XG5cbiAgICBhZGRBcnJvd1ZlcnRleChhbmdsZWRMaW5lV2lkdGgsIGJ1dHRvblNjYWxlIC0gbGluZVdpZHRoKTtcbiAgICBhZGRBcnJvd1ZlcnRleChrQnV0dG9uV2lkdGhEcCAqIGRwcywgYnV0dG9uU2NhbGUgLSBsaW5lV2lkdGgpO1xuICAgIGFkZEFycm93VmVydGV4KGFuZ2xlZExpbmVXaWR0aCwgYnV0dG9uU2NhbGUgKyBsaW5lV2lkdGgpO1xuICAgIGFkZEFycm93VmVydGV4KGtCdXR0b25XaWR0aERwICogZHBzLCBidXR0b25TY2FsZSArIGxpbmVXaWR0aCk7XG5cbiAgICBzZWxmLmFycm93VmVydGV4Q291bnQgPSAodmVydGljZXMubGVuZ3RoIC8gMikgLSBzZWxmLmFycm93T2Zmc2V0O1xuXG4gICAgLy8gQnVmZmVyIGRhdGFcbiAgICBnbC5iaW5kQnVmZmVyKGdsLkFSUkFZX0JVRkZFUiwgc2VsZi52ZXJ0ZXhCdWZmZXIpO1xuICAgIGdsLmJ1ZmZlckRhdGEoZ2wuQVJSQVlfQlVGRkVSLCBuZXcgRmxvYXQzMkFycmF5KHZlcnRpY2VzKSwgZ2wuU1RBVElDX0RSQVcpO1xuICB9KTtcbn07XG5cbi8qKlxuICogUGVyZm9ybXMgZGlzdG9ydGlvbiBwYXNzIG9uIHRoZSBpbmplY3RlZCBiYWNrYnVmZmVyLCByZW5kZXJpbmcgaXQgdG8gdGhlIHJlYWxcbiAqIGJhY2tidWZmZXIuXG4gKi9cbkNhcmRib2FyZFVJLnByb3RvdHlwZS5yZW5kZXIgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGdsID0gdGhpcy5nbDtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIHZhciBnbFN0YXRlID0gW1xuICAgIGdsLkNVTExfRkFDRSxcbiAgICBnbC5ERVBUSF9URVNULFxuICAgIGdsLkJMRU5ELFxuICAgIGdsLlNDSVNTT1JfVEVTVCxcbiAgICBnbC5TVEVOQ0lMX1RFU1QsXG4gICAgZ2wuQ09MT1JfV1JJVEVNQVNLLFxuICAgIGdsLlZJRVdQT1JULFxuXG4gICAgZ2wuQ1VSUkVOVF9QUk9HUkFNLFxuICAgIGdsLkFSUkFZX0JVRkZFUl9CSU5ESU5HXG4gIF07XG5cbiAgV0dMVVByZXNlcnZlR0xTdGF0ZShnbCwgZ2xTdGF0ZSwgZnVuY3Rpb24oZ2wpIHtcbiAgICAvLyBNYWtlIHN1cmUgdGhlIEdMIHN0YXRlIGlzIGluIGEgZ29vZCBwbGFjZVxuICAgIGdsLmRpc2FibGUoZ2wuQ1VMTF9GQUNFKTtcbiAgICBnbC5kaXNhYmxlKGdsLkRFUFRIX1RFU1QpO1xuICAgIGdsLmRpc2FibGUoZ2wuQkxFTkQpO1xuICAgIGdsLmRpc2FibGUoZ2wuU0NJU1NPUl9URVNUKTtcbiAgICBnbC5kaXNhYmxlKGdsLlNURU5DSUxfVEVTVCk7XG4gICAgZ2wuY29sb3JNYXNrKHRydWUsIHRydWUsIHRydWUsIHRydWUpO1xuICAgIGdsLnZpZXdwb3J0KDAsIDAsIGdsLmRyYXdpbmdCdWZmZXJXaWR0aCwgZ2wuZHJhd2luZ0J1ZmZlckhlaWdodCk7XG5cbiAgICBzZWxmLnJlbmRlck5vU3RhdGUoKTtcbiAgfSk7XG59O1xuXG5DYXJkYm9hcmRVSS5wcm90b3R5cGUucmVuZGVyTm9TdGF0ZSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgZ2wgPSB0aGlzLmdsO1xuXG4gIC8vIEJpbmQgZGlzdG9ydGlvbiBwcm9ncmFtIGFuZCBtZXNoXG4gIGdsLnVzZVByb2dyYW0odGhpcy5wcm9ncmFtKTtcblxuICBnbC5iaW5kQnVmZmVyKGdsLkFSUkFZX0JVRkZFUiwgdGhpcy52ZXJ0ZXhCdWZmZXIpO1xuICBnbC5lbmFibGVWZXJ0ZXhBdHRyaWJBcnJheSh0aGlzLmF0dHJpYnMucG9zaXRpb24pO1xuICBnbC52ZXJ0ZXhBdHRyaWJQb2ludGVyKHRoaXMuYXR0cmlicy5wb3NpdGlvbiwgMiwgZ2wuRkxPQVQsIGZhbHNlLCA4LCAwKTtcblxuICBnbC51bmlmb3JtNGYodGhpcy51bmlmb3Jtcy5jb2xvciwgMS4wLCAxLjAsIDEuMCwgMS4wKTtcblxuICBVdGlsLm9ydGhvTWF0cml4KHRoaXMucHJvak1hdCwgMCwgZ2wuZHJhd2luZ0J1ZmZlcldpZHRoLCAwLCBnbC5kcmF3aW5nQnVmZmVySGVpZ2h0LCAwLjEsIDEwMjQuMCk7XG4gIGdsLnVuaWZvcm1NYXRyaXg0ZnYodGhpcy51bmlmb3Jtcy5wcm9qZWN0aW9uTWF0LCBmYWxzZSwgdGhpcy5wcm9qTWF0KTtcblxuICAvLyBEcmF3cyBVSSBlbGVtZW50XG4gIGdsLmRyYXdBcnJheXMoZ2wuVFJJQU5HTEVfU1RSSVAsIDAsIDQpO1xuICBnbC5kcmF3QXJyYXlzKGdsLlRSSUFOR0xFX1NUUklQLCB0aGlzLmdlYXJPZmZzZXQsIHRoaXMuZ2VhclZlcnRleENvdW50KTtcbiAgZ2wuZHJhd0FycmF5cyhnbC5UUklBTkdMRV9TVFJJUCwgdGhpcy5hcnJvd09mZnNldCwgdGhpcy5hcnJvd1ZlcnRleENvdW50KTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gQ2FyZGJvYXJkVUk7XG5cbn0se1wiLi9kZXBzL3dnbHUtcHJlc2VydmUtc3RhdGUuanNcIjo3LFwiLi91dGlsLmpzXCI6MjJ9XSw2OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcbi8qXG4gKiBDb3B5cmlnaHQgMjAxNiBHb29nbGUgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbnZhciBDYXJkYm9hcmREaXN0b3J0ZXIgPSBfZGVyZXFfKCcuL2NhcmRib2FyZC1kaXN0b3J0ZXIuanMnKTtcbnZhciBDYXJkYm9hcmRVSSA9IF9kZXJlcV8oJy4vY2FyZGJvYXJkLXVpLmpzJyk7XG52YXIgRGV2aWNlSW5mbyA9IF9kZXJlcV8oJy4vZGV2aWNlLWluZm8uanMnKTtcbnZhciBEcGRiID0gX2RlcmVxXygnLi9kcGRiL2RwZGIuanMnKTtcbnZhciBGdXNpb25Qb3NlU2Vuc29yID0gX2RlcmVxXygnLi9zZW5zb3ItZnVzaW9uL2Z1c2lvbi1wb3NlLXNlbnNvci5qcycpO1xudmFyIFJvdGF0ZUluc3RydWN0aW9ucyA9IF9kZXJlcV8oJy4vcm90YXRlLWluc3RydWN0aW9ucy5qcycpO1xudmFyIFZpZXdlclNlbGVjdG9yID0gX2RlcmVxXygnLi92aWV3ZXItc2VsZWN0b3IuanMnKTtcbnZhciBWUkRpc3BsYXkgPSBfZGVyZXFfKCcuL2Jhc2UuanMnKS5WUkRpc3BsYXk7XG52YXIgVXRpbCA9IF9kZXJlcV8oJy4vdXRpbC5qcycpO1xuXG52YXIgRXllID0ge1xuICBMRUZUOiAnbGVmdCcsXG4gIFJJR0hUOiAncmlnaHQnXG59O1xuXG4vKipcbiAqIFZSRGlzcGxheSBiYXNlZCBvbiBtb2JpbGUgZGV2aWNlIHBhcmFtZXRlcnMgYW5kIERldmljZU1vdGlvbiBBUElzLlxuICovXG5mdW5jdGlvbiBDYXJkYm9hcmRWUkRpc3BsYXkoKSB7XG4gIHRoaXMuZGlzcGxheU5hbWUgPSAnQ2FyZGJvYXJkIFZSRGlzcGxheSAod2VidnItcG9seWZpbGwpJztcblxuICB0aGlzLmNhcGFiaWxpdGllcy5oYXNPcmllbnRhdGlvbiA9IHRydWU7XG4gIHRoaXMuY2FwYWJpbGl0aWVzLmNhblByZXNlbnQgPSB0cnVlO1xuXG4gIC8vIFwiUHJpdmF0ZVwiIG1lbWJlcnMuXG4gIHRoaXMuYnVmZmVyU2NhbGVfID0gV2ViVlJDb25maWcuQlVGRkVSX1NDQUxFO1xuICB0aGlzLnBvc2VTZW5zb3JfID0gbmV3IEZ1c2lvblBvc2VTZW5zb3IoKTtcbiAgdGhpcy5kaXN0b3J0ZXJfID0gbnVsbDtcbiAgdGhpcy5jYXJkYm9hcmRVSV8gPSBudWxsO1xuXG4gIHRoaXMuZHBkYl8gPSBuZXcgRHBkYih0cnVlLCB0aGlzLm9uRGV2aWNlUGFyYW1zVXBkYXRlZF8uYmluZCh0aGlzKSk7XG4gIHRoaXMuZGV2aWNlSW5mb18gPSBuZXcgRGV2aWNlSW5mbyh0aGlzLmRwZGJfLmdldERldmljZVBhcmFtcygpKTtcblxuICB0aGlzLnZpZXdlclNlbGVjdG9yXyA9IG5ldyBWaWV3ZXJTZWxlY3RvcigpO1xuICB0aGlzLnZpZXdlclNlbGVjdG9yXy5vbignY2hhbmdlJywgdGhpcy5vblZpZXdlckNoYW5nZWRfLmJpbmQodGhpcykpO1xuXG4gIC8vIFNldCB0aGUgY29ycmVjdCBpbml0aWFsIHZpZXdlci5cbiAgdGhpcy5kZXZpY2VJbmZvXy5zZXRWaWV3ZXIodGhpcy52aWV3ZXJTZWxlY3Rvcl8uZ2V0Q3VycmVudFZpZXdlcigpKTtcblxuICBpZiAoIVdlYlZSQ29uZmlnLlJPVEFURV9JTlNUUlVDVElPTlNfRElTQUJMRUQpIHtcbiAgICB0aGlzLnJvdGF0ZUluc3RydWN0aW9uc18gPSBuZXcgUm90YXRlSW5zdHJ1Y3Rpb25zKCk7XG4gIH1cblxuICBpZiAoVXRpbC5pc0lPUygpKSB7XG4gICAgLy8gTGlzdGVuIGZvciByZXNpemUgZXZlbnRzIHRvIHdvcmthcm91bmQgdGhpcyBhd2Z1bCBTYWZhcmkgYnVnLlxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdyZXNpemUnLCB0aGlzLm9uUmVzaXplXy5iaW5kKHRoaXMpKTtcbiAgfVxufVxuQ2FyZGJvYXJkVlJEaXNwbGF5LnByb3RvdHlwZSA9IG5ldyBWUkRpc3BsYXkoKTtcblxuQ2FyZGJvYXJkVlJEaXNwbGF5LnByb3RvdHlwZS5nZXRJbW1lZGlhdGVQb3NlID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB7XG4gICAgcG9zaXRpb246IHRoaXMucG9zZVNlbnNvcl8uZ2V0UG9zaXRpb24oKSxcbiAgICBvcmllbnRhdGlvbjogdGhpcy5wb3NlU2Vuc29yXy5nZXRPcmllbnRhdGlvbigpLFxuICAgIGxpbmVhclZlbG9jaXR5OiBudWxsLFxuICAgIGxpbmVhckFjY2VsZXJhdGlvbjogbnVsbCxcbiAgICBhbmd1bGFyVmVsb2NpdHk6IG51bGwsXG4gICAgYW5ndWxhckFjY2VsZXJhdGlvbjogbnVsbFxuICB9O1xufTtcblxuQ2FyZGJvYXJkVlJEaXNwbGF5LnByb3RvdHlwZS5yZXNldFBvc2UgPSBmdW5jdGlvbigpIHtcbiAgdGhpcy5wb3NlU2Vuc29yXy5yZXNldFBvc2UoKTtcbn07XG5cbkNhcmRib2FyZFZSRGlzcGxheS5wcm90b3R5cGUuZ2V0RXllUGFyYW1ldGVycyA9IGZ1bmN0aW9uKHdoaWNoRXllKSB7XG4gIHZhciBvZmZzZXQgPSBbdGhpcy5kZXZpY2VJbmZvXy52aWV3ZXIuaW50ZXJMZW5zRGlzdGFuY2UgKiAwLjUsIDAuMCwgMC4wXTtcbiAgdmFyIGZpZWxkT2ZWaWV3O1xuXG4gIC8vIFRPRE86IEZvViBjYW4gYmUgYSBsaXR0bGUgZXhwZW5zaXZlIHRvIGNvbXB1dGUuIENhY2hlIHdoZW4gZGV2aWNlIHBhcmFtcyBjaGFuZ2UuXG4gIGlmICh3aGljaEV5ZSA9PSBFeWUuTEVGVCkge1xuICAgIG9mZnNldFswXSAqPSAtMS4wO1xuICAgIGZpZWxkT2ZWaWV3ID0gdGhpcy5kZXZpY2VJbmZvXy5nZXRGaWVsZE9mVmlld0xlZnRFeWUoKTtcbiAgfSBlbHNlIGlmICh3aGljaEV5ZSA9PSBFeWUuUklHSFQpIHtcbiAgICBmaWVsZE9mVmlldyA9IHRoaXMuZGV2aWNlSW5mb18uZ2V0RmllbGRPZlZpZXdSaWdodEV5ZSgpO1xuICB9IGVsc2Uge1xuICAgIGNvbnNvbGUuZXJyb3IoJ0ludmFsaWQgZXllIHByb3ZpZGVkOiAlcycsIHdoaWNoRXllKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgZmllbGRPZlZpZXc6IGZpZWxkT2ZWaWV3LFxuICAgIG9mZnNldDogb2Zmc2V0LFxuICAgIC8vIFRPRE86IFNob3VsZCBiZSBhYmxlIHRvIHByb3ZpZGUgYmV0dGVyIHZhbHVlcyB0aGFuIHRoZXNlLlxuICAgIHJlbmRlcldpZHRoOiB0aGlzLmRldmljZUluZm9fLmRldmljZS53aWR0aCAqIDAuNSAqIHRoaXMuYnVmZmVyU2NhbGVfLFxuICAgIHJlbmRlckhlaWdodDogdGhpcy5kZXZpY2VJbmZvXy5kZXZpY2UuaGVpZ2h0ICogdGhpcy5idWZmZXJTY2FsZV8sXG4gIH07XG59O1xuXG5DYXJkYm9hcmRWUkRpc3BsYXkucHJvdG90eXBlLm9uRGV2aWNlUGFyYW1zVXBkYXRlZF8gPSBmdW5jdGlvbihuZXdQYXJhbXMpIHtcbiAgaWYgKFV0aWwuaXNEZWJ1ZygpKSB7XG4gICAgY29uc29sZS5sb2coJ0RQREIgcmVwb3J0ZWQgdGhhdCBkZXZpY2UgcGFyYW1zIHdlcmUgdXBkYXRlZC4nKTtcbiAgfVxuICB0aGlzLmRldmljZUluZm9fLnVwZGF0ZURldmljZVBhcmFtcyhuZXdQYXJhbXMpO1xuXG4gIGlmICh0aGlzLmRpc3RvcnRlcl8pIHtcbiAgICB0aGlzLmRpc3RvcnRlcl8udXBkYXRlRGV2aWNlSW5mbyh0aGlzLmRldmljZUluZm9fKTtcbiAgfVxufTtcblxuQ2FyZGJvYXJkVlJEaXNwbGF5LnByb3RvdHlwZS51cGRhdGVCb3VuZHNfID0gZnVuY3Rpb24gKCkge1xuICBpZiAodGhpcy5sYXllcl8gJiYgdGhpcy5kaXN0b3J0ZXJfICYmICh0aGlzLmxheWVyXy5sZWZ0Qm91bmRzIHx8IHRoaXMubGF5ZXJfLnJpZ2h0Qm91bmRzKSkge1xuICAgIHRoaXMuZGlzdG9ydGVyXy5zZXRUZXh0dXJlQm91bmRzKHRoaXMubGF5ZXJfLmxlZnRCb3VuZHMsIHRoaXMubGF5ZXJfLnJpZ2h0Qm91bmRzKTtcbiAgfVxufTtcblxuQ2FyZGJvYXJkVlJEaXNwbGF5LnByb3RvdHlwZS5iZWdpblByZXNlbnRfID0gZnVuY3Rpb24oKSB7XG4gIHZhciBnbCA9IHRoaXMubGF5ZXJfLnNvdXJjZS5nZXRDb250ZXh0KCd3ZWJnbCcpO1xuICBpZiAoIWdsKVxuICAgIGdsID0gdGhpcy5sYXllcl8uc291cmNlLmdldENvbnRleHQoJ2V4cGVyaW1lbnRhbC13ZWJnbCcpO1xuICBpZiAoIWdsKVxuICAgIGdsID0gdGhpcy5sYXllcl8uc291cmNlLmdldENvbnRleHQoJ3dlYmdsMicpO1xuXG4gIGlmICghZ2wpXG4gICAgcmV0dXJuOyAvLyBDYW4ndCBkbyBkaXN0b3J0aW9uIHdpdGhvdXQgYSBXZWJHTCBjb250ZXh0LlxuXG4gIC8vIFByb3ZpZGVzIGEgd2F5IHRvIG9wdCBvdXQgb2YgZGlzdG9ydGlvblxuICBpZiAodGhpcy5sYXllcl8ucHJlZGlzdG9ydGVkKSB7XG4gICAgaWYgKCFXZWJWUkNvbmZpZy5DQVJEQk9BUkRfVUlfRElTQUJMRUQpIHtcbiAgICAgIGdsLmNhbnZhcy53aWR0aCA9IFV0aWwuZ2V0U2NyZWVuV2lkdGgoKSAqIHRoaXMuYnVmZmVyU2NhbGVfO1xuICAgICAgZ2wuY2FudmFzLmhlaWdodCA9IFV0aWwuZ2V0U2NyZWVuSGVpZ2h0KCkgKiB0aGlzLmJ1ZmZlclNjYWxlXztcbiAgICAgIHRoaXMuY2FyZGJvYXJkVUlfID0gbmV3IENhcmRib2FyZFVJKGdsKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgLy8gQ3JlYXRlIGEgbmV3IGRpc3RvcnRlciBmb3IgdGhlIHRhcmdldCBjb250ZXh0XG4gICAgdGhpcy5kaXN0b3J0ZXJfID0gbmV3IENhcmRib2FyZERpc3RvcnRlcihnbCk7XG4gICAgdGhpcy5kaXN0b3J0ZXJfLnVwZGF0ZURldmljZUluZm8odGhpcy5kZXZpY2VJbmZvXyk7XG4gICAgdGhpcy5jYXJkYm9hcmRVSV8gPSB0aGlzLmRpc3RvcnRlcl8uY2FyZGJvYXJkVUk7XG4gIH1cblxuICBpZiAodGhpcy5jYXJkYm9hcmRVSV8pIHtcbiAgICB0aGlzLmNhcmRib2FyZFVJXy5saXN0ZW4oZnVuY3Rpb24oZSkge1xuICAgICAgLy8gT3B0aW9ucyBjbGlja2VkLlxuICAgICAgdGhpcy52aWV3ZXJTZWxlY3Rvcl8uc2hvdyh0aGlzLmxheWVyXy5zb3VyY2UucGFyZW50RWxlbWVudCk7XG4gICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH0uYmluZCh0aGlzKSwgZnVuY3Rpb24oZSkge1xuICAgICAgLy8gQmFjayBjbGlja2VkLlxuICAgICAgdGhpcy5leGl0UHJlc2VudCgpO1xuICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICB9LmJpbmQodGhpcykpO1xuICB9XG5cbiAgaWYgKHRoaXMucm90YXRlSW5zdHJ1Y3Rpb25zXykge1xuICAgIGlmIChVdGlsLmlzTGFuZHNjYXBlTW9kZSgpICYmIFV0aWwuaXNNb2JpbGUoKSkge1xuICAgICAgLy8gSW4gbGFuZHNjYXBlIG1vZGUsIHRlbXBvcmFyaWx5IHNob3cgdGhlIFwicHV0IGludG8gQ2FyZGJvYXJkXCJcbiAgICAgIC8vIGludGVyc3RpdGlhbC4gT3RoZXJ3aXNlLCBkbyB0aGUgZGVmYXVsdCB0aGluZy5cbiAgICAgIHRoaXMucm90YXRlSW5zdHJ1Y3Rpb25zXy5zaG93VGVtcG9yYXJpbHkoMzAwMCwgdGhpcy5sYXllcl8uc291cmNlLnBhcmVudEVsZW1lbnQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnJvdGF0ZUluc3RydWN0aW9uc18udXBkYXRlKCk7XG4gICAgfVxuICB9XG5cbiAgLy8gTGlzdGVuIGZvciBvcmllbnRhdGlvbiBjaGFuZ2UgZXZlbnRzIGluIG9yZGVyIHRvIHNob3cgaW50ZXJzdGl0aWFsLlxuICB0aGlzLm9yaWVudGF0aW9uSGFuZGxlciA9IHRoaXMub25PcmllbnRhdGlvbkNoYW5nZV8uYmluZCh0aGlzKTtcbiAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ29yaWVudGF0aW9uY2hhbmdlJywgdGhpcy5vcmllbnRhdGlvbkhhbmRsZXIpO1xuXG4gIC8vIExpc3RlbiBmb3IgcHJlc2VudCBkaXNwbGF5IGNoYW5nZSBldmVudHMgaW4gb3JkZXIgdG8gdXBkYXRlIGRpc3RvcnRlciBkaW1lbnNpb25zXG4gIHRoaXMudnJkaXNwbGF5cHJlc2VudGNoYW5nZUhhbmRsZXIgPSB0aGlzLnVwZGF0ZUJvdW5kc18uYmluZCh0aGlzKTtcbiAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3ZyZGlzcGxheXByZXNlbnRjaGFuZ2UnLCB0aGlzLnZyZGlzcGxheXByZXNlbnRjaGFuZ2VIYW5kbGVyKTtcblxuICAvLyBGaXJlIHRoaXMgZXZlbnQgaW5pdGlhbGx5LCB0byBnaXZlIGdlb21ldHJ5LWRpc3RvcnRpb24gY2xpZW50cyB0aGUgY2hhbmNlXG4gIC8vIHRvIGRvIHNvbWV0aGluZyBjdXN0b20uXG4gIHRoaXMuZmlyZVZSRGlzcGxheURldmljZVBhcmFtc0NoYW5nZV8oKTtcbn07XG5cbkNhcmRib2FyZFZSRGlzcGxheS5wcm90b3R5cGUuZW5kUHJlc2VudF8gPSBmdW5jdGlvbigpIHtcbiAgaWYgKHRoaXMuZGlzdG9ydGVyXykge1xuICAgIHRoaXMuZGlzdG9ydGVyXy5kZXN0cm95KCk7XG4gICAgdGhpcy5kaXN0b3J0ZXJfID0gbnVsbDtcbiAgfVxuICBpZiAodGhpcy5jYXJkYm9hcmRVSV8pIHtcbiAgICB0aGlzLmNhcmRib2FyZFVJXy5kZXN0cm95KCk7XG4gICAgdGhpcy5jYXJkYm9hcmRVSV8gPSBudWxsO1xuICB9XG5cbiAgaWYgKHRoaXMucm90YXRlSW5zdHJ1Y3Rpb25zXykge1xuICAgIHRoaXMucm90YXRlSW5zdHJ1Y3Rpb25zXy5oaWRlKCk7XG4gIH1cbiAgdGhpcy52aWV3ZXJTZWxlY3Rvcl8uaGlkZSgpO1xuXG4gIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdvcmllbnRhdGlvbmNoYW5nZScsIHRoaXMub3JpZW50YXRpb25IYW5kbGVyKTtcbiAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3ZyZGlzcGxheXByZXNlbnRjaGFuZ2UnLCB0aGlzLnZyZGlzcGxheXByZXNlbnRjaGFuZ2VIYW5kbGVyKTtcbn07XG5cbkNhcmRib2FyZFZSRGlzcGxheS5wcm90b3R5cGUuc3VibWl0RnJhbWUgPSBmdW5jdGlvbihwb3NlKSB7XG4gIGlmICh0aGlzLmRpc3RvcnRlcl8pIHtcbiAgICB0aGlzLmRpc3RvcnRlcl8uc3VibWl0RnJhbWUoKTtcbiAgfSBlbHNlIGlmICh0aGlzLmNhcmRib2FyZFVJXyAmJiB0aGlzLmxheWVyXykge1xuICAgIC8vIEhhY2sgZm9yIHByZWRpc3RvcnRlZDogdHJ1ZS5cbiAgICB2YXIgY2FudmFzID0gdGhpcy5sYXllcl8uc291cmNlLmdldENvbnRleHQoJ3dlYmdsJykuY2FudmFzO1xuICAgIGlmIChjYW52YXMud2lkdGggIT0gdGhpcy5sYXN0V2lkdGggfHwgY2FudmFzLmhlaWdodCAhPSB0aGlzLmxhc3RIZWlnaHQpIHtcbiAgICAgIHRoaXMuY2FyZGJvYXJkVUlfLm9uUmVzaXplKCk7XG4gICAgfVxuICAgIHRoaXMubGFzdFdpZHRoID0gY2FudmFzLndpZHRoO1xuICAgIHRoaXMubGFzdEhlaWdodCA9IGNhbnZhcy5oZWlnaHQ7XG5cbiAgICAvLyBSZW5kZXIgdGhlIENhcmRib2FyZCBVSS5cbiAgICB0aGlzLmNhcmRib2FyZFVJXy5yZW5kZXIoKTtcbiAgfVxufTtcblxuQ2FyZGJvYXJkVlJEaXNwbGF5LnByb3RvdHlwZS5vbk9yaWVudGF0aW9uQ2hhbmdlXyA9IGZ1bmN0aW9uKGUpIHtcbiAgLy8gSGlkZSB0aGUgdmlld2VyIHNlbGVjdG9yLlxuICB0aGlzLnZpZXdlclNlbGVjdG9yXy5oaWRlKCk7XG5cbiAgLy8gVXBkYXRlIHRoZSByb3RhdGUgaW5zdHJ1Y3Rpb25zLlxuICBpZiAodGhpcy5yb3RhdGVJbnN0cnVjdGlvbnNfKSB7XG4gICAgdGhpcy5yb3RhdGVJbnN0cnVjdGlvbnNfLnVwZGF0ZSgpO1xuICB9XG5cbiAgdGhpcy5vblJlc2l6ZV8oKTtcbn07XG5cbkNhcmRib2FyZFZSRGlzcGxheS5wcm90b3R5cGUub25SZXNpemVfID0gZnVuY3Rpb24oZSkge1xuICBpZiAodGhpcy5sYXllcl8pIHtcbiAgICB2YXIgZ2wgPSB0aGlzLmxheWVyXy5zb3VyY2UuZ2V0Q29udGV4dCgnd2ViZ2wnKTtcbiAgICAvLyBTaXplIHRoZSBDU1MgY2FudmFzLlxuICAgIC8vIEFkZGVkIHBhZGRpbmcgb24gcmlnaHQgYW5kIGJvdHRvbSBiZWNhdXNlIGlQaG9uZSA1IHdpbGwgbm90XG4gICAgLy8gaGlkZSB0aGUgVVJMIGJhciB1bmxlc3MgY29udGVudCBpcyBiaWdnZXIgdGhhbiB0aGUgc2NyZWVuLlxuICAgIC8vIFRoaXMgd2lsbCBub3QgYmUgdmlzaWJsZSBhcyBsb25nIGFzIHRoZSBjb250YWluZXIgZWxlbWVudCAoZS5nLiBib2R5KVxuICAgIC8vIGlzIHNldCB0byAnb3ZlcmZsb3c6IGhpZGRlbicuXG4gICAgdmFyIGNzc1Byb3BlcnRpZXMgPSBbXG4gICAgICAncG9zaXRpb246IGFic29sdXRlJyxcbiAgICAgICd0b3A6IDAnLFxuICAgICAgJ2xlZnQ6IDAnLFxuICAgICAgJ3dpZHRoOiAnICsgTWF0aC5tYXgoc2NyZWVuLndpZHRoLCBzY3JlZW4uaGVpZ2h0KSArICdweCcsXG4gICAgICAnaGVpZ2h0OiAnICsgTWF0aC5taW4oc2NyZWVuLmhlaWdodCwgc2NyZWVuLndpZHRoKSArICdweCcsXG4gICAgICAnYm9yZGVyOiAwJyxcbiAgICAgICdtYXJnaW46IDAnLFxuICAgICAgJ3BhZGRpbmc6IDAgMTBweCAxMHB4IDAnLFxuICAgIF07XG4gICAgZ2wuY2FudmFzLnNldEF0dHJpYnV0ZSgnc3R5bGUnLCBjc3NQcm9wZXJ0aWVzLmpvaW4oJzsgJykgKyAnOycpO1xuXG4gICAgVXRpbC5zYWZhcmlDc3NTaXplV29ya2Fyb3VuZChnbC5jYW52YXMpO1xuICB9XG59O1xuXG5DYXJkYm9hcmRWUkRpc3BsYXkucHJvdG90eXBlLm9uVmlld2VyQ2hhbmdlZF8gPSBmdW5jdGlvbih2aWV3ZXIpIHtcbiAgdGhpcy5kZXZpY2VJbmZvXy5zZXRWaWV3ZXIodmlld2VyKTtcblxuICBpZiAodGhpcy5kaXN0b3J0ZXJfKSB7XG4gICAgLy8gVXBkYXRlIHRoZSBkaXN0b3J0aW9uIGFwcHJvcHJpYXRlbHkuXG4gICAgdGhpcy5kaXN0b3J0ZXJfLnVwZGF0ZURldmljZUluZm8odGhpcy5kZXZpY2VJbmZvXyk7XG4gIH1cblxuICAvLyBGaXJlIGEgbmV3IGV2ZW50IGNvbnRhaW5pbmcgdmlld2VyIGFuZCBkZXZpY2UgcGFyYW1ldGVycyBmb3IgY2xpZW50cyB0aGF0XG4gIC8vIHdhbnQgdG8gaW1wbGVtZW50IHRoZWlyIG93biBnZW9tZXRyeS1iYXNlZCBkaXN0b3J0aW9uLlxuICB0aGlzLmZpcmVWUkRpc3BsYXlEZXZpY2VQYXJhbXNDaGFuZ2VfKCk7XG59O1xuXG5DYXJkYm9hcmRWUkRpc3BsYXkucHJvdG90eXBlLmZpcmVWUkRpc3BsYXlEZXZpY2VQYXJhbXNDaGFuZ2VfID0gZnVuY3Rpb24oKSB7XG4gIHZhciBldmVudCA9IG5ldyBDdXN0b21FdmVudCgndnJkaXNwbGF5ZGV2aWNlcGFyYW1zY2hhbmdlJywge1xuICAgIGRldGFpbDoge1xuICAgICAgdnJkaXNwbGF5OiB0aGlzLFxuICAgICAgZGV2aWNlSW5mbzogdGhpcy5kZXZpY2VJbmZvXyxcbiAgICB9XG4gIH0pO1xuICB3aW5kb3cuZGlzcGF0Y2hFdmVudChldmVudCk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IENhcmRib2FyZFZSRGlzcGxheTtcblxufSx7XCIuL2Jhc2UuanNcIjozLFwiLi9jYXJkYm9hcmQtZGlzdG9ydGVyLmpzXCI6NCxcIi4vY2FyZGJvYXJkLXVpLmpzXCI6NSxcIi4vZGV2aWNlLWluZm8uanNcIjo4LFwiLi9kcGRiL2RwZGIuanNcIjoxMixcIi4vcm90YXRlLWluc3RydWN0aW9ucy5qc1wiOjE2LFwiLi9zZW5zb3ItZnVzaW9uL2Z1c2lvbi1wb3NlLXNlbnNvci5qc1wiOjE4LFwiLi91dGlsLmpzXCI6MjIsXCIuL3ZpZXdlci1zZWxlY3Rvci5qc1wiOjIzfV0sNzpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4vKlxuQ29weXJpZ2h0IChjKSAyMDE2LCBCcmFuZG9uIEpvbmVzLlxuXG5QZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG5vZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0byBkZWFsXG5pbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzXG50byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsXG5jb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbmZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG5cblRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluXG5hbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cblxuVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG5GSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbkFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbkxJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sXG5PVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOXG5USEUgU09GVFdBUkUuXG4qL1xuXG4vKlxuQ2FjaGVzIHNwZWNpZmllZCBHTCBzdGF0ZSwgcnVucyBhIGNhbGxiYWNrLCBhbmQgcmVzdG9yZXMgdGhlIGNhY2hlZCBzdGF0ZSB3aGVuXG5kb25lLlxuXG5FeGFtcGxlIHVzYWdlOlxuXG52YXIgc2F2ZWRTdGF0ZSA9IFtcbiAgZ2wuQVJSQVlfQlVGRkVSX0JJTkRJTkcsXG5cbiAgLy8gVEVYVFVSRV9CSU5ESU5HXzJEIG9yIF9DVUJFX01BUCBtdXN0IGFsd2F5cyBiZSBmb2xsb3dlZCBieSB0aGUgdGV4dXJlIHVuaXQuXG4gIGdsLlRFWFRVUkVfQklORElOR18yRCwgZ2wuVEVYVFVSRTAsXG5cbiAgZ2wuQ0xFQVJfQ09MT1IsXG5dO1xuLy8gQWZ0ZXIgdGhpcyBjYWxsIHRoZSBhcnJheSBidWZmZXIsIHRleHR1cmUgdW5pdCAwLCBhY3RpdmUgdGV4dHVyZSwgYW5kIGNsZWFyXG4vLyBjb2xvciB3aWxsIGJlIHJlc3RvcmVkLiBUaGUgdmlld3BvcnQgd2lsbCByZW1haW4gY2hhbmdlZCwgaG93ZXZlciwgYmVjYXVzZVxuLy8gZ2wuVklFV1BPUlQgd2FzIG5vdCBpbmNsdWRlZCBpbiB0aGUgc2F2ZWRTdGF0ZSBsaXN0LlxuV0dMVVByZXNlcnZlR0xTdGF0ZShnbCwgc2F2ZWRTdGF0ZSwgZnVuY3Rpb24oZ2wpIHtcbiAgZ2wudmlld3BvcnQoMCwgMCwgZ2wuZHJhd2luZ0J1ZmZlcldpZHRoLCBnbC5kcmF3aW5nQnVmZmVySGVpZ2h0KTtcblxuICBnbC5iaW5kQnVmZmVyKGdsLkFSUkFZX0JVRkZFUiwgYnVmZmVyKTtcbiAgZ2wuYnVmZmVyRGF0YShnbC5BUlJBWV9CVUZGRVIsIC4uLi4pO1xuXG4gIGdsLmFjdGl2ZVRleHR1cmUoZ2wuVEVYVFVSRTApO1xuICBnbC5iaW5kVGV4dHVyZShnbC5URVhUVVJFXzJELCB0ZXh0dXJlKTtcbiAgZ2wudGV4SW1hZ2UyRChnbC5URVhUVVJFXzJELCAuLi4pO1xuXG4gIGdsLmNsZWFyQ29sb3IoMSwgMCwgMCwgMSk7XG4gIGdsLmNsZWFyKGdsLkNPTE9SX0JVRkZFUl9CSVQpO1xufSk7XG5cbk5vdGUgdGhhdCB0aGlzIGlzIG5vdCBpbnRlbmRlZCB0byBiZSBmYXN0LiBNYW5hZ2luZyBzdGF0ZSBpbiB5b3VyIG93biBjb2RlIHRvXG5hdm9pZCByZWR1bmRhbnQgc3RhdGUgc2V0dGluZyBhbmQgcXVlcnlpbmcgd2lsbCBhbHdheXMgYmUgZmFzdGVyLiBUaGlzIGZ1bmN0aW9uXG5pcyBtb3N0IHVzZWZ1bCBmb3IgY2FzZXMgd2hlcmUgeW91IG1heSBub3QgaGF2ZSBmdWxsIGNvbnRyb2wgb3ZlciB0aGUgV2ViR0xcbmNhbGxzIGJlaW5nIG1hZGUsIHN1Y2ggYXMgdG9vbGluZyBvciBlZmZlY3QgaW5qZWN0b3JzLlxuKi9cblxuZnVuY3Rpb24gV0dMVVByZXNlcnZlR0xTdGF0ZShnbCwgYmluZGluZ3MsIGNhbGxiYWNrKSB7XG4gIGlmICghYmluZGluZ3MpIHtcbiAgICBjYWxsYmFjayhnbCk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIGJvdW5kVmFsdWVzID0gW107XG5cbiAgdmFyIGFjdGl2ZVRleHR1cmUgPSBudWxsO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGJpbmRpbmdzLmxlbmd0aDsgKytpKSB7XG4gICAgdmFyIGJpbmRpbmcgPSBiaW5kaW5nc1tpXTtcbiAgICBzd2l0Y2ggKGJpbmRpbmcpIHtcbiAgICAgIGNhc2UgZ2wuVEVYVFVSRV9CSU5ESU5HXzJEOlxuICAgICAgY2FzZSBnbC5URVhUVVJFX0JJTkRJTkdfQ1VCRV9NQVA6XG4gICAgICAgIHZhciB0ZXh0dXJlVW5pdCA9IGJpbmRpbmdzWysraV07XG4gICAgICAgIGlmICh0ZXh0dXJlVW5pdCA8IGdsLlRFWFRVUkUwIHx8IHRleHR1cmVVbml0ID4gZ2wuVEVYVFVSRTMxKSB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcihcIlRFWFRVUkVfQklORElOR18yRCBvciBURVhUVVJFX0JJTkRJTkdfQ1VCRV9NQVAgbXVzdCBiZSBmb2xsb3dlZCBieSBhIHZhbGlkIHRleHR1cmUgdW5pdFwiKTtcbiAgICAgICAgICBib3VuZFZhbHVlcy5wdXNoKG51bGwsIG51bGwpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGlmICghYWN0aXZlVGV4dHVyZSkge1xuICAgICAgICAgIGFjdGl2ZVRleHR1cmUgPSBnbC5nZXRQYXJhbWV0ZXIoZ2wuQUNUSVZFX1RFWFRVUkUpO1xuICAgICAgICB9XG4gICAgICAgIGdsLmFjdGl2ZVRleHR1cmUodGV4dHVyZVVuaXQpO1xuICAgICAgICBib3VuZFZhbHVlcy5wdXNoKGdsLmdldFBhcmFtZXRlcihiaW5kaW5nKSwgbnVsbCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBnbC5BQ1RJVkVfVEVYVFVSRTpcbiAgICAgICAgYWN0aXZlVGV4dHVyZSA9IGdsLmdldFBhcmFtZXRlcihnbC5BQ1RJVkVfVEVYVFVSRSk7XG4gICAgICAgIGJvdW5kVmFsdWVzLnB1c2gobnVsbCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgYm91bmRWYWx1ZXMucHVzaChnbC5nZXRQYXJhbWV0ZXIoYmluZGluZykpO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICBjYWxsYmFjayhnbCk7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBiaW5kaW5ncy5sZW5ndGg7ICsraSkge1xuICAgIHZhciBiaW5kaW5nID0gYmluZGluZ3NbaV07XG4gICAgdmFyIGJvdW5kVmFsdWUgPSBib3VuZFZhbHVlc1tpXTtcbiAgICBzd2l0Y2ggKGJpbmRpbmcpIHtcbiAgICAgIGNhc2UgZ2wuQUNUSVZFX1RFWFRVUkU6XG4gICAgICAgIGJyZWFrOyAvLyBJZ25vcmUgdGhpcyBiaW5kaW5nLCBzaW5jZSB3ZSBzcGVjaWFsLWNhc2UgaXQgdG8gaGFwcGVuIGxhc3QuXG4gICAgICBjYXNlIGdsLkFSUkFZX0JVRkZFUl9CSU5ESU5HOlxuICAgICAgICBnbC5iaW5kQnVmZmVyKGdsLkFSUkFZX0JVRkZFUiwgYm91bmRWYWx1ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBnbC5DT0xPUl9DTEVBUl9WQUxVRTpcbiAgICAgICAgZ2wuY2xlYXJDb2xvcihib3VuZFZhbHVlWzBdLCBib3VuZFZhbHVlWzFdLCBib3VuZFZhbHVlWzJdLCBib3VuZFZhbHVlWzNdKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIGdsLkNPTE9SX1dSSVRFTUFTSzpcbiAgICAgICAgZ2wuY29sb3JNYXNrKGJvdW5kVmFsdWVbMF0sIGJvdW5kVmFsdWVbMV0sIGJvdW5kVmFsdWVbMl0sIGJvdW5kVmFsdWVbM10pO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgZ2wuQ1VSUkVOVF9QUk9HUkFNOlxuICAgICAgICBnbC51c2VQcm9ncmFtKGJvdW5kVmFsdWUpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgZ2wuRUxFTUVOVF9BUlJBWV9CVUZGRVJfQklORElORzpcbiAgICAgICAgZ2wuYmluZEJ1ZmZlcihnbC5FTEVNRU5UX0FSUkFZX0JVRkZFUiwgYm91bmRWYWx1ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBnbC5GUkFNRUJVRkZFUl9CSU5ESU5HOlxuICAgICAgICBnbC5iaW5kRnJhbWVidWZmZXIoZ2wuRlJBTUVCVUZGRVIsIGJvdW5kVmFsdWUpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgZ2wuUkVOREVSQlVGRkVSX0JJTkRJTkc6XG4gICAgICAgIGdsLmJpbmRSZW5kZXJidWZmZXIoZ2wuUkVOREVSQlVGRkVSLCBib3VuZFZhbHVlKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIGdsLlRFWFRVUkVfQklORElOR18yRDpcbiAgICAgICAgdmFyIHRleHR1cmVVbml0ID0gYmluZGluZ3NbKytpXTtcbiAgICAgICAgaWYgKHRleHR1cmVVbml0IDwgZ2wuVEVYVFVSRTAgfHwgdGV4dHVyZVVuaXQgPiBnbC5URVhUVVJFMzEpXG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGdsLmFjdGl2ZVRleHR1cmUodGV4dHVyZVVuaXQpO1xuICAgICAgICBnbC5iaW5kVGV4dHVyZShnbC5URVhUVVJFXzJELCBib3VuZFZhbHVlKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIGdsLlRFWFRVUkVfQklORElOR19DVUJFX01BUDpcbiAgICAgICAgdmFyIHRleHR1cmVVbml0ID0gYmluZGluZ3NbKytpXTtcbiAgICAgICAgaWYgKHRleHR1cmVVbml0IDwgZ2wuVEVYVFVSRTAgfHwgdGV4dHVyZVVuaXQgPiBnbC5URVhUVVJFMzEpXG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGdsLmFjdGl2ZVRleHR1cmUodGV4dHVyZVVuaXQpO1xuICAgICAgICBnbC5iaW5kVGV4dHVyZShnbC5URVhUVVJFX0NVQkVfTUFQLCBib3VuZFZhbHVlKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIGdsLlZJRVdQT1JUOlxuICAgICAgICBnbC52aWV3cG9ydChib3VuZFZhbHVlWzBdLCBib3VuZFZhbHVlWzFdLCBib3VuZFZhbHVlWzJdLCBib3VuZFZhbHVlWzNdKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIGdsLkJMRU5EOlxuICAgICAgY2FzZSBnbC5DVUxMX0ZBQ0U6XG4gICAgICBjYXNlIGdsLkRFUFRIX1RFU1Q6XG4gICAgICBjYXNlIGdsLlNDSVNTT1JfVEVTVDpcbiAgICAgIGNhc2UgZ2wuU1RFTkNJTF9URVNUOlxuICAgICAgICBpZiAoYm91bmRWYWx1ZSkge1xuICAgICAgICAgIGdsLmVuYWJsZShiaW5kaW5nKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBnbC5kaXNhYmxlKGJpbmRpbmcpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgY29uc29sZS5sb2coXCJObyBHTCByZXN0b3JlIGJlaGF2aW9yIGZvciAweFwiICsgYmluZGluZy50b1N0cmluZygxNikpO1xuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICBpZiAoYWN0aXZlVGV4dHVyZSkge1xuICAgICAgZ2wuYWN0aXZlVGV4dHVyZShhY3RpdmVUZXh0dXJlKTtcbiAgICB9XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBXR0xVUHJlc2VydmVHTFN0YXRlO1xufSx7fV0sODpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4vKlxuICogQ29weXJpZ2h0IDIwMTUgR29vZ2xlIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG52YXIgRGlzdG9ydGlvbiA9IF9kZXJlcV8oJy4vZGlzdG9ydGlvbi9kaXN0b3J0aW9uLmpzJyk7XG52YXIgTWF0aFV0aWwgPSBfZGVyZXFfKCcuL21hdGgtdXRpbC5qcycpO1xudmFyIFV0aWwgPSBfZGVyZXFfKCcuL3V0aWwuanMnKTtcblxuZnVuY3Rpb24gRGV2aWNlKHBhcmFtcykge1xuICB0aGlzLndpZHRoID0gcGFyYW1zLndpZHRoIHx8IFV0aWwuZ2V0U2NyZWVuV2lkdGgoKTtcbiAgdGhpcy5oZWlnaHQgPSBwYXJhbXMuaGVpZ2h0IHx8IFV0aWwuZ2V0U2NyZWVuSGVpZ2h0KCk7XG4gIHRoaXMud2lkdGhNZXRlcnMgPSBwYXJhbXMud2lkdGhNZXRlcnM7XG4gIHRoaXMuaGVpZ2h0TWV0ZXJzID0gcGFyYW1zLmhlaWdodE1ldGVycztcbiAgdGhpcy5iZXZlbE1ldGVycyA9IHBhcmFtcy5iZXZlbE1ldGVycztcbn1cblxuXG4vLyBGYWxsYmFjayBBbmRyb2lkIGRldmljZSAoYmFzZWQgb24gTmV4dXMgNSBtZWFzdXJlbWVudHMpIGZvciB1c2Ugd2hlblxuLy8gd2UgY2FuJ3QgcmVjb2duaXplIGFuIEFuZHJvaWQgZGV2aWNlLlxudmFyIERFRkFVTFRfQU5EUk9JRCA9IG5ldyBEZXZpY2Uoe1xuICB3aWR0aE1ldGVyczogMC4xMTAsXG4gIGhlaWdodE1ldGVyczogMC4wNjIsXG4gIGJldmVsTWV0ZXJzOiAwLjAwNFxufSk7XG5cbi8vIEZhbGxiYWNrIGlPUyBkZXZpY2UgKGJhc2VkIG9uIGlQaG9uZTYpIGZvciB1c2Ugd2hlblxuLy8gd2UgY2FuJ3QgcmVjb2duaXplIGFuIEFuZHJvaWQgZGV2aWNlLlxudmFyIERFRkFVTFRfSU9TID0gbmV3IERldmljZSh7XG4gIHdpZHRoTWV0ZXJzOiAwLjEwMzgsXG4gIGhlaWdodE1ldGVyczogMC4wNTg0LFxuICBiZXZlbE1ldGVyczogMC4wMDRcbn0pO1xuXG5cbnZhciBWaWV3ZXJzID0ge1xuICBDYXJkYm9hcmRWMTogbmV3IENhcmRib2FyZFZpZXdlcih7XG4gICAgaWQ6ICdDYXJkYm9hcmRWMScsXG4gICAgbGFiZWw6ICdDYXJkYm9hcmQgSS9PIDIwMTQnLFxuICAgIGZvdjogNDAsXG4gICAgaW50ZXJMZW5zRGlzdGFuY2U6IDAuMDYwLFxuICAgIGJhc2VsaW5lTGVuc0Rpc3RhbmNlOiAwLjAzNSxcbiAgICBzY3JlZW5MZW5zRGlzdGFuY2U6IDAuMDQyLFxuICAgIGRpc3RvcnRpb25Db2VmZmljaWVudHM6IFswLjQ0MSwgMC4xNTZdLFxuICAgIGludmVyc2VDb2VmZmljaWVudHM6IFstMC40NDEwMDM1LCAwLjQyNzU2MTU1LCAtMC40ODA0NDM5LCAwLjU0NjAxMzksXG4gICAgICAtMC41ODgyMTE4MywgMC41NzMzOTM4LCAtMC40ODMwMzIwMiwgMC4zMzI5OTA4MywgLTAuMTc1NzM4NDEsXG4gICAgICAwLjA2NTE3NzIsIC0wLjAxNDg4OTYzLCAwLjAwMTU1OTgzNF1cbiAgfSksXG4gIENhcmRib2FyZFYyOiBuZXcgQ2FyZGJvYXJkVmlld2VyKHtcbiAgICBpZDogJ0NhcmRib2FyZFYyJyxcbiAgICBsYWJlbDogJ0NhcmRib2FyZCBJL08gMjAxNScsXG4gICAgZm92OiA2MCxcbiAgICBpbnRlckxlbnNEaXN0YW5jZTogMC4wNjQsXG4gICAgYmFzZWxpbmVMZW5zRGlzdGFuY2U6IDAuMDM1LFxuICAgIHNjcmVlbkxlbnNEaXN0YW5jZTogMC4wMzksXG4gICAgZGlzdG9ydGlvbkNvZWZmaWNpZW50czogWzAuMzQsIDAuNTVdLFxuICAgIGludmVyc2VDb2VmZmljaWVudHM6IFstMC4zMzgzNjcwNCwgLTAuMTgxNjIxODUsIDAuODYyNjU1LCAtMS4yNDYyMDUxLFxuICAgICAgMS4wNTYwNjAyLCAtMC41ODIwODMxNywgMC4yMTYwOTA3OCwgLTAuMDU0NDQ4MjMsIDAuMDA5MTc3OTU2LFxuICAgICAgLTkuOTA0MTY5RS00LCA2LjE4MzUzNUUtNSwgLTEuNjk4MTgwM0UtNl1cbiAgfSlcbn07XG5cblxudmFyIERFRkFVTFRfTEVGVF9DRU5URVIgPSB7eDogMC41LCB5OiAwLjV9O1xudmFyIERFRkFVTFRfUklHSFRfQ0VOVEVSID0ge3g6IDAuNSwgeTogMC41fTtcblxuLyoqXG4gKiBNYW5hZ2VzIGluZm9ybWF0aW9uIGFib3V0IHRoZSBkZXZpY2UgYW5kIHRoZSB2aWV3ZXIuXG4gKlxuICogZGV2aWNlUGFyYW1zIGluZGljYXRlcyB0aGUgcGFyYW1ldGVycyBvZiB0aGUgZGV2aWNlIHRvIHVzZSAoZ2VuZXJhbGx5XG4gKiBvYnRhaW5lZCBmcm9tIGRwZGIuZ2V0RGV2aWNlUGFyYW1zKCkpLiBDYW4gYmUgbnVsbCB0byBtZWFuIG5vIGRldmljZVxuICogcGFyYW1zIHdlcmUgZm91bmQuXG4gKi9cbmZ1bmN0aW9uIERldmljZUluZm8oZGV2aWNlUGFyYW1zKSB7XG4gIHRoaXMudmlld2VyID0gVmlld2Vycy5DYXJkYm9hcmRWMjtcbiAgdGhpcy51cGRhdGVEZXZpY2VQYXJhbXMoZGV2aWNlUGFyYW1zKTtcbiAgdGhpcy5kaXN0b3J0aW9uID0gbmV3IERpc3RvcnRpb24odGhpcy52aWV3ZXIuZGlzdG9ydGlvbkNvZWZmaWNpZW50cyk7XG59XG5cbkRldmljZUluZm8ucHJvdG90eXBlLnVwZGF0ZURldmljZVBhcmFtcyA9IGZ1bmN0aW9uKGRldmljZVBhcmFtcykge1xuICB0aGlzLmRldmljZSA9IHRoaXMuZGV0ZXJtaW5lRGV2aWNlXyhkZXZpY2VQYXJhbXMpIHx8IHRoaXMuZGV2aWNlO1xufTtcblxuRGV2aWNlSW5mby5wcm90b3R5cGUuZ2V0RGV2aWNlID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLmRldmljZTtcbn07XG5cbkRldmljZUluZm8ucHJvdG90eXBlLnNldFZpZXdlciA9IGZ1bmN0aW9uKHZpZXdlcikge1xuICB0aGlzLnZpZXdlciA9IHZpZXdlcjtcbiAgdGhpcy5kaXN0b3J0aW9uID0gbmV3IERpc3RvcnRpb24odGhpcy52aWV3ZXIuZGlzdG9ydGlvbkNvZWZmaWNpZW50cyk7XG59O1xuXG5EZXZpY2VJbmZvLnByb3RvdHlwZS5kZXRlcm1pbmVEZXZpY2VfID0gZnVuY3Rpb24oZGV2aWNlUGFyYW1zKSB7XG4gIGlmICghZGV2aWNlUGFyYW1zKSB7XG4gICAgLy8gTm8gcGFyYW1ldGVycywgc28gdXNlIGEgZGVmYXVsdC5cbiAgICBpZiAoVXRpbC5pc0lPUygpKSB7XG4gICAgICBjb25zb2xlLndhcm4oJ1VzaW5nIGZhbGxiYWNrIGlPUyBkZXZpY2UgbWVhc3VyZW1lbnRzLicpO1xuICAgICAgcmV0dXJuIERFRkFVTFRfSU9TO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zb2xlLndhcm4oJ1VzaW5nIGZhbGxiYWNrIEFuZHJvaWQgZGV2aWNlIG1lYXN1cmVtZW50cy4nKTtcbiAgICAgIHJldHVybiBERUZBVUxUX0FORFJPSUQ7XG4gICAgfVxuICB9XG5cbiAgLy8gQ29tcHV0ZSBkZXZpY2Ugc2NyZWVuIGRpbWVuc2lvbnMgYmFzZWQgb24gZGV2aWNlUGFyYW1zLlxuICB2YXIgTUVURVJTX1BFUl9JTkNIID0gMC4wMjU0O1xuICB2YXIgbWV0ZXJzUGVyUGl4ZWxYID0gTUVURVJTX1BFUl9JTkNIIC8gZGV2aWNlUGFyYW1zLnhkcGk7XG4gIHZhciBtZXRlcnNQZXJQaXhlbFkgPSBNRVRFUlNfUEVSX0lOQ0ggLyBkZXZpY2VQYXJhbXMueWRwaTtcbiAgdmFyIHdpZHRoID0gVXRpbC5nZXRTY3JlZW5XaWR0aCgpO1xuICB2YXIgaGVpZ2h0ID0gVXRpbC5nZXRTY3JlZW5IZWlnaHQoKTtcbiAgcmV0dXJuIG5ldyBEZXZpY2Uoe1xuICAgIHdpZHRoTWV0ZXJzOiBtZXRlcnNQZXJQaXhlbFggKiB3aWR0aCxcbiAgICBoZWlnaHRNZXRlcnM6IG1ldGVyc1BlclBpeGVsWSAqIGhlaWdodCxcbiAgICBiZXZlbE1ldGVyczogZGV2aWNlUGFyYW1zLmJldmVsTW0gKiAwLjAwMSxcbiAgfSk7XG59O1xuXG4vKipcbiAqIENhbGN1bGF0ZXMgZmllbGQgb2YgdmlldyBmb3IgdGhlIGxlZnQgZXllLlxuICovXG5EZXZpY2VJbmZvLnByb3RvdHlwZS5nZXREaXN0b3J0ZWRGaWVsZE9mVmlld0xlZnRFeWUgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHZpZXdlciA9IHRoaXMudmlld2VyO1xuICB2YXIgZGV2aWNlID0gdGhpcy5kZXZpY2U7XG4gIHZhciBkaXN0b3J0aW9uID0gdGhpcy5kaXN0b3J0aW9uO1xuXG4gIC8vIERldmljZS5oZWlnaHQgYW5kIGRldmljZS53aWR0aCBmb3IgZGV2aWNlIGluIHBvcnRyYWl0IG1vZGUsIHNvIHRyYW5zcG9zZS5cbiAgdmFyIGV5ZVRvU2NyZWVuRGlzdGFuY2UgPSB2aWV3ZXIuc2NyZWVuTGVuc0Rpc3RhbmNlO1xuXG4gIHZhciBvdXRlckRpc3QgPSAoZGV2aWNlLndpZHRoTWV0ZXJzIC0gdmlld2VyLmludGVyTGVuc0Rpc3RhbmNlKSAvIDI7XG4gIHZhciBpbm5lckRpc3QgPSB2aWV3ZXIuaW50ZXJMZW5zRGlzdGFuY2UgLyAyO1xuICB2YXIgYm90dG9tRGlzdCA9IHZpZXdlci5iYXNlbGluZUxlbnNEaXN0YW5jZSAtIGRldmljZS5iZXZlbE1ldGVycztcbiAgdmFyIHRvcERpc3QgPSBkZXZpY2UuaGVpZ2h0TWV0ZXJzIC0gYm90dG9tRGlzdDtcblxuICB2YXIgb3V0ZXJBbmdsZSA9IE1hdGhVdGlsLnJhZFRvRGVnICogTWF0aC5hdGFuKFxuICAgICAgZGlzdG9ydGlvbi5kaXN0b3J0KG91dGVyRGlzdCAvIGV5ZVRvU2NyZWVuRGlzdGFuY2UpKTtcbiAgdmFyIGlubmVyQW5nbGUgPSBNYXRoVXRpbC5yYWRUb0RlZyAqIE1hdGguYXRhbihcbiAgICAgIGRpc3RvcnRpb24uZGlzdG9ydChpbm5lckRpc3QgLyBleWVUb1NjcmVlbkRpc3RhbmNlKSk7XG4gIHZhciBib3R0b21BbmdsZSA9IE1hdGhVdGlsLnJhZFRvRGVnICogTWF0aC5hdGFuKFxuICAgICAgZGlzdG9ydGlvbi5kaXN0b3J0KGJvdHRvbURpc3QgLyBleWVUb1NjcmVlbkRpc3RhbmNlKSk7XG4gIHZhciB0b3BBbmdsZSA9IE1hdGhVdGlsLnJhZFRvRGVnICogTWF0aC5hdGFuKFxuICAgICAgZGlzdG9ydGlvbi5kaXN0b3J0KHRvcERpc3QgLyBleWVUb1NjcmVlbkRpc3RhbmNlKSk7XG5cbiAgcmV0dXJuIHtcbiAgICBsZWZ0RGVncmVlczogTWF0aC5taW4ob3V0ZXJBbmdsZSwgdmlld2VyLmZvdiksXG4gICAgcmlnaHREZWdyZWVzOiBNYXRoLm1pbihpbm5lckFuZ2xlLCB2aWV3ZXIuZm92KSxcbiAgICBkb3duRGVncmVlczogTWF0aC5taW4oYm90dG9tQW5nbGUsIHZpZXdlci5mb3YpLFxuICAgIHVwRGVncmVlczogTWF0aC5taW4odG9wQW5nbGUsIHZpZXdlci5mb3YpXG4gIH07XG59O1xuXG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIHRhbi1hbmdsZXMgZnJvbSB0aGUgbWF4aW11bSBGT1YgZm9yIHRoZSBsZWZ0IGV5ZSBmb3IgdGhlXG4gKiBjdXJyZW50IGRldmljZSBhbmQgc2NyZWVuIHBhcmFtZXRlcnMuXG4gKi9cbkRldmljZUluZm8ucHJvdG90eXBlLmdldExlZnRFeWVWaXNpYmxlVGFuQW5nbGVzID0gZnVuY3Rpb24oKSB7XG4gIHZhciB2aWV3ZXIgPSB0aGlzLnZpZXdlcjtcbiAgdmFyIGRldmljZSA9IHRoaXMuZGV2aWNlO1xuICB2YXIgZGlzdG9ydGlvbiA9IHRoaXMuZGlzdG9ydGlvbjtcblxuICAvLyBUYW4tYW5nbGVzIGZyb20gdGhlIG1heCBGT1YuXG4gIHZhciBmb3ZMZWZ0ID0gTWF0aC50YW4oLU1hdGhVdGlsLmRlZ1RvUmFkICogdmlld2VyLmZvdik7XG4gIHZhciBmb3ZUb3AgPSBNYXRoLnRhbihNYXRoVXRpbC5kZWdUb1JhZCAqIHZpZXdlci5mb3YpO1xuICB2YXIgZm92UmlnaHQgPSBNYXRoLnRhbihNYXRoVXRpbC5kZWdUb1JhZCAqIHZpZXdlci5mb3YpO1xuICB2YXIgZm92Qm90dG9tID0gTWF0aC50YW4oLU1hdGhVdGlsLmRlZ1RvUmFkICogdmlld2VyLmZvdik7XG4gIC8vIFZpZXdwb3J0IHNpemUuXG4gIHZhciBoYWxmV2lkdGggPSBkZXZpY2Uud2lkdGhNZXRlcnMgLyA0O1xuICB2YXIgaGFsZkhlaWdodCA9IGRldmljZS5oZWlnaHRNZXRlcnMgLyAyO1xuICAvLyBWaWV3cG9ydCBjZW50ZXIsIG1lYXN1cmVkIGZyb20gbGVmdCBsZW5zIHBvc2l0aW9uLlxuICB2YXIgdmVydGljYWxMZW5zT2Zmc2V0ID0gKHZpZXdlci5iYXNlbGluZUxlbnNEaXN0YW5jZSAtIGRldmljZS5iZXZlbE1ldGVycyAtIGhhbGZIZWlnaHQpO1xuICB2YXIgY2VudGVyWCA9IHZpZXdlci5pbnRlckxlbnNEaXN0YW5jZSAvIDIgLSBoYWxmV2lkdGg7XG4gIHZhciBjZW50ZXJZID0gLXZlcnRpY2FsTGVuc09mZnNldDtcbiAgdmFyIGNlbnRlclogPSB2aWV3ZXIuc2NyZWVuTGVuc0Rpc3RhbmNlO1xuICAvLyBUYW4tYW5nbGVzIG9mIHRoZSB2aWV3cG9ydCBlZGdlcywgYXMgc2VlbiB0aHJvdWdoIHRoZSBsZW5zLlxuICB2YXIgc2NyZWVuTGVmdCA9IGRpc3RvcnRpb24uZGlzdG9ydCgoY2VudGVyWCAtIGhhbGZXaWR0aCkgLyBjZW50ZXJaKTtcbiAgdmFyIHNjcmVlblRvcCA9IGRpc3RvcnRpb24uZGlzdG9ydCgoY2VudGVyWSArIGhhbGZIZWlnaHQpIC8gY2VudGVyWik7XG4gIHZhciBzY3JlZW5SaWdodCA9IGRpc3RvcnRpb24uZGlzdG9ydCgoY2VudGVyWCArIGhhbGZXaWR0aCkgLyBjZW50ZXJaKTtcbiAgdmFyIHNjcmVlbkJvdHRvbSA9IGRpc3RvcnRpb24uZGlzdG9ydCgoY2VudGVyWSAtIGhhbGZIZWlnaHQpIC8gY2VudGVyWik7XG4gIC8vIENvbXBhcmUgdGhlIHR3byBzZXRzIG9mIHRhbi1hbmdsZXMgYW5kIHRha2UgdGhlIHZhbHVlIGNsb3NlciB0byB6ZXJvIG9uIGVhY2ggc2lkZS5cbiAgdmFyIHJlc3VsdCA9IG5ldyBGbG9hdDMyQXJyYXkoNCk7XG4gIHJlc3VsdFswXSA9IE1hdGgubWF4KGZvdkxlZnQsIHNjcmVlbkxlZnQpO1xuICByZXN1bHRbMV0gPSBNYXRoLm1pbihmb3ZUb3AsIHNjcmVlblRvcCk7XG4gIHJlc3VsdFsyXSA9IE1hdGgubWluKGZvdlJpZ2h0LCBzY3JlZW5SaWdodCk7XG4gIHJlc3VsdFszXSA9IE1hdGgubWF4KGZvdkJvdHRvbSwgc2NyZWVuQm90dG9tKTtcbiAgcmV0dXJuIHJlc3VsdDtcbn07XG5cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgdGFuLWFuZ2xlcyBmcm9tIHRoZSBtYXhpbXVtIEZPViBmb3IgdGhlIGxlZnQgZXllIGZvciB0aGVcbiAqIGN1cnJlbnQgZGV2aWNlIGFuZCBzY3JlZW4gcGFyYW1ldGVycywgYXNzdW1pbmcgbm8gbGVuc2VzLlxuICovXG5EZXZpY2VJbmZvLnByb3RvdHlwZS5nZXRMZWZ0RXllTm9MZW5zVGFuQW5nbGVzID0gZnVuY3Rpb24oKSB7XG4gIHZhciB2aWV3ZXIgPSB0aGlzLnZpZXdlcjtcbiAgdmFyIGRldmljZSA9IHRoaXMuZGV2aWNlO1xuICB2YXIgZGlzdG9ydGlvbiA9IHRoaXMuZGlzdG9ydGlvbjtcblxuICB2YXIgcmVzdWx0ID0gbmV3IEZsb2F0MzJBcnJheSg0KTtcbiAgLy8gVGFuLWFuZ2xlcyBmcm9tIHRoZSBtYXggRk9WLlxuICB2YXIgZm92TGVmdCA9IGRpc3RvcnRpb24uZGlzdG9ydEludmVyc2UoTWF0aC50YW4oLU1hdGhVdGlsLmRlZ1RvUmFkICogdmlld2VyLmZvdikpO1xuICB2YXIgZm92VG9wID0gZGlzdG9ydGlvbi5kaXN0b3J0SW52ZXJzZShNYXRoLnRhbihNYXRoVXRpbC5kZWdUb1JhZCAqIHZpZXdlci5mb3YpKTtcbiAgdmFyIGZvdlJpZ2h0ID0gZGlzdG9ydGlvbi5kaXN0b3J0SW52ZXJzZShNYXRoLnRhbihNYXRoVXRpbC5kZWdUb1JhZCAqIHZpZXdlci5mb3YpKTtcbiAgdmFyIGZvdkJvdHRvbSA9IGRpc3RvcnRpb24uZGlzdG9ydEludmVyc2UoTWF0aC50YW4oLU1hdGhVdGlsLmRlZ1RvUmFkICogdmlld2VyLmZvdikpO1xuICAvLyBWaWV3cG9ydCBzaXplLlxuICB2YXIgaGFsZldpZHRoID0gZGV2aWNlLndpZHRoTWV0ZXJzIC8gNDtcbiAgdmFyIGhhbGZIZWlnaHQgPSBkZXZpY2UuaGVpZ2h0TWV0ZXJzIC8gMjtcbiAgLy8gVmlld3BvcnQgY2VudGVyLCBtZWFzdXJlZCBmcm9tIGxlZnQgbGVucyBwb3NpdGlvbi5cbiAgdmFyIHZlcnRpY2FsTGVuc09mZnNldCA9ICh2aWV3ZXIuYmFzZWxpbmVMZW5zRGlzdGFuY2UgLSBkZXZpY2UuYmV2ZWxNZXRlcnMgLSBoYWxmSGVpZ2h0KTtcbiAgdmFyIGNlbnRlclggPSB2aWV3ZXIuaW50ZXJMZW5zRGlzdGFuY2UgLyAyIC0gaGFsZldpZHRoO1xuICB2YXIgY2VudGVyWSA9IC12ZXJ0aWNhbExlbnNPZmZzZXQ7XG4gIHZhciBjZW50ZXJaID0gdmlld2VyLnNjcmVlbkxlbnNEaXN0YW5jZTtcbiAgLy8gVGFuLWFuZ2xlcyBvZiB0aGUgdmlld3BvcnQgZWRnZXMsIGFzIHNlZW4gdGhyb3VnaCB0aGUgbGVucy5cbiAgdmFyIHNjcmVlbkxlZnQgPSAoY2VudGVyWCAtIGhhbGZXaWR0aCkgLyBjZW50ZXJaO1xuICB2YXIgc2NyZWVuVG9wID0gKGNlbnRlclkgKyBoYWxmSGVpZ2h0KSAvIGNlbnRlclo7XG4gIHZhciBzY3JlZW5SaWdodCA9IChjZW50ZXJYICsgaGFsZldpZHRoKSAvIGNlbnRlclo7XG4gIHZhciBzY3JlZW5Cb3R0b20gPSAoY2VudGVyWSAtIGhhbGZIZWlnaHQpIC8gY2VudGVyWjtcbiAgLy8gQ29tcGFyZSB0aGUgdHdvIHNldHMgb2YgdGFuLWFuZ2xlcyBhbmQgdGFrZSB0aGUgdmFsdWUgY2xvc2VyIHRvIHplcm8gb24gZWFjaCBzaWRlLlxuICByZXN1bHRbMF0gPSBNYXRoLm1heChmb3ZMZWZ0LCBzY3JlZW5MZWZ0KTtcbiAgcmVzdWx0WzFdID0gTWF0aC5taW4oZm92VG9wLCBzY3JlZW5Ub3ApO1xuICByZXN1bHRbMl0gPSBNYXRoLm1pbihmb3ZSaWdodCwgc2NyZWVuUmlnaHQpO1xuICByZXN1bHRbM10gPSBNYXRoLm1heChmb3ZCb3R0b20sIHNjcmVlbkJvdHRvbSk7XG4gIHJldHVybiByZXN1bHQ7XG59O1xuXG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIHNjcmVlbiByZWN0YW5nbGUgdmlzaWJsZSBmcm9tIHRoZSBsZWZ0IGV5ZSBmb3IgdGhlXG4gKiBjdXJyZW50IGRldmljZSBhbmQgc2NyZWVuIHBhcmFtZXRlcnMuXG4gKi9cbkRldmljZUluZm8ucHJvdG90eXBlLmdldExlZnRFeWVWaXNpYmxlU2NyZWVuUmVjdCA9IGZ1bmN0aW9uKHVuZGlzdG9ydGVkRnJ1c3R1bSkge1xuICB2YXIgdmlld2VyID0gdGhpcy52aWV3ZXI7XG4gIHZhciBkZXZpY2UgPSB0aGlzLmRldmljZTtcblxuICB2YXIgZGlzdCA9IHZpZXdlci5zY3JlZW5MZW5zRGlzdGFuY2U7XG4gIHZhciBleWVYID0gKGRldmljZS53aWR0aE1ldGVycyAtIHZpZXdlci5pbnRlckxlbnNEaXN0YW5jZSkgLyAyO1xuICB2YXIgZXllWSA9IHZpZXdlci5iYXNlbGluZUxlbnNEaXN0YW5jZSAtIGRldmljZS5iZXZlbE1ldGVycztcbiAgdmFyIGxlZnQgPSAodW5kaXN0b3J0ZWRGcnVzdHVtWzBdICogZGlzdCArIGV5ZVgpIC8gZGV2aWNlLndpZHRoTWV0ZXJzO1xuICB2YXIgdG9wID0gKHVuZGlzdG9ydGVkRnJ1c3R1bVsxXSAqIGRpc3QgKyBleWVZKSAvIGRldmljZS5oZWlnaHRNZXRlcnM7XG4gIHZhciByaWdodCA9ICh1bmRpc3RvcnRlZEZydXN0dW1bMl0gKiBkaXN0ICsgZXllWCkgLyBkZXZpY2Uud2lkdGhNZXRlcnM7XG4gIHZhciBib3R0b20gPSAodW5kaXN0b3J0ZWRGcnVzdHVtWzNdICogZGlzdCArIGV5ZVkpIC8gZGV2aWNlLmhlaWdodE1ldGVycztcbiAgcmV0dXJuIHtcbiAgICB4OiBsZWZ0LFxuICAgIHk6IGJvdHRvbSxcbiAgICB3aWR0aDogcmlnaHQgLSBsZWZ0LFxuICAgIGhlaWdodDogdG9wIC0gYm90dG9tXG4gIH07XG59O1xuXG5EZXZpY2VJbmZvLnByb3RvdHlwZS5nZXRGaWVsZE9mVmlld0xlZnRFeWUgPSBmdW5jdGlvbihvcHRfaXNVbmRpc3RvcnRlZCkge1xuICByZXR1cm4gb3B0X2lzVW5kaXN0b3J0ZWQgPyB0aGlzLmdldFVuZGlzdG9ydGVkRmllbGRPZlZpZXdMZWZ0RXllKCkgOlxuICAgICAgdGhpcy5nZXREaXN0b3J0ZWRGaWVsZE9mVmlld0xlZnRFeWUoKTtcbn07XG5cbkRldmljZUluZm8ucHJvdG90eXBlLmdldEZpZWxkT2ZWaWV3UmlnaHRFeWUgPSBmdW5jdGlvbihvcHRfaXNVbmRpc3RvcnRlZCkge1xuICB2YXIgZm92ID0gdGhpcy5nZXRGaWVsZE9mVmlld0xlZnRFeWUob3B0X2lzVW5kaXN0b3J0ZWQpO1xuICByZXR1cm4ge1xuICAgIGxlZnREZWdyZWVzOiBmb3YucmlnaHREZWdyZWVzLFxuICAgIHJpZ2h0RGVncmVlczogZm92LmxlZnREZWdyZWVzLFxuICAgIHVwRGVncmVlczogZm92LnVwRGVncmVlcyxcbiAgICBkb3duRGVncmVlczogZm92LmRvd25EZWdyZWVzXG4gIH07XG59O1xuXG4vKipcbiAqIENhbGN1bGF0ZXMgdW5kaXN0b3J0ZWQgZmllbGQgb2YgdmlldyBmb3IgdGhlIGxlZnQgZXllLlxuICovXG5EZXZpY2VJbmZvLnByb3RvdHlwZS5nZXRVbmRpc3RvcnRlZEZpZWxkT2ZWaWV3TGVmdEV5ZSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgcCA9IHRoaXMuZ2V0VW5kaXN0b3J0ZWRQYXJhbXNfKCk7XG5cbiAgcmV0dXJuIHtcbiAgICBsZWZ0RGVncmVlczogTWF0aFV0aWwucmFkVG9EZWcgKiBNYXRoLmF0YW4ocC5vdXRlckRpc3QpLFxuICAgIHJpZ2h0RGVncmVlczogTWF0aFV0aWwucmFkVG9EZWcgKiBNYXRoLmF0YW4ocC5pbm5lckRpc3QpLFxuICAgIGRvd25EZWdyZWVzOiBNYXRoVXRpbC5yYWRUb0RlZyAqIE1hdGguYXRhbihwLmJvdHRvbURpc3QpLFxuICAgIHVwRGVncmVlczogTWF0aFV0aWwucmFkVG9EZWcgKiBNYXRoLmF0YW4ocC50b3BEaXN0KVxuICB9O1xufTtcblxuRGV2aWNlSW5mby5wcm90b3R5cGUuZ2V0VW5kaXN0b3J0ZWRWaWV3cG9ydExlZnRFeWUgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHAgPSB0aGlzLmdldFVuZGlzdG9ydGVkUGFyYW1zXygpO1xuICB2YXIgdmlld2VyID0gdGhpcy52aWV3ZXI7XG4gIHZhciBkZXZpY2UgPSB0aGlzLmRldmljZTtcblxuICAvLyBEaXN0YW5jZXMgc3RvcmVkIGluIGxvY2FsIHZhcmlhYmxlcyBhcmUgaW4gdGFuLWFuZ2xlIHVuaXRzIHVubGVzcyBvdGhlcndpc2VcbiAgLy8gbm90ZWQuXG4gIHZhciBleWVUb1NjcmVlbkRpc3RhbmNlID0gdmlld2VyLnNjcmVlbkxlbnNEaXN0YW5jZTtcbiAgdmFyIHNjcmVlbldpZHRoID0gZGV2aWNlLndpZHRoTWV0ZXJzIC8gZXllVG9TY3JlZW5EaXN0YW5jZTtcbiAgdmFyIHNjcmVlbkhlaWdodCA9IGRldmljZS5oZWlnaHRNZXRlcnMgLyBleWVUb1NjcmVlbkRpc3RhbmNlO1xuICB2YXIgeFB4UGVyVGFuQW5nbGUgPSBkZXZpY2Uud2lkdGggLyBzY3JlZW5XaWR0aDtcbiAgdmFyIHlQeFBlclRhbkFuZ2xlID0gZGV2aWNlLmhlaWdodCAvIHNjcmVlbkhlaWdodDtcblxuICB2YXIgeCA9IE1hdGgucm91bmQoKHAuZXllUG9zWCAtIHAub3V0ZXJEaXN0KSAqIHhQeFBlclRhbkFuZ2xlKTtcbiAgdmFyIHkgPSBNYXRoLnJvdW5kKChwLmV5ZVBvc1kgLSBwLmJvdHRvbURpc3QpICogeVB4UGVyVGFuQW5nbGUpO1xuICByZXR1cm4ge1xuICAgIHg6IHgsXG4gICAgeTogeSxcbiAgICB3aWR0aDogTWF0aC5yb3VuZCgocC5leWVQb3NYICsgcC5pbm5lckRpc3QpICogeFB4UGVyVGFuQW5nbGUpIC0geCxcbiAgICBoZWlnaHQ6IE1hdGgucm91bmQoKHAuZXllUG9zWSArIHAudG9wRGlzdCkgKiB5UHhQZXJUYW5BbmdsZSkgLSB5XG4gIH07XG59O1xuXG5EZXZpY2VJbmZvLnByb3RvdHlwZS5nZXRVbmRpc3RvcnRlZFBhcmFtc18gPSBmdW5jdGlvbigpIHtcbiAgdmFyIHZpZXdlciA9IHRoaXMudmlld2VyO1xuICB2YXIgZGV2aWNlID0gdGhpcy5kZXZpY2U7XG4gIHZhciBkaXN0b3J0aW9uID0gdGhpcy5kaXN0b3J0aW9uO1xuXG4gIC8vIE1vc3Qgb2YgdGhlc2UgdmFyaWFibGVzIGluIHRhbi1hbmdsZSB1bml0cy5cbiAgdmFyIGV5ZVRvU2NyZWVuRGlzdGFuY2UgPSB2aWV3ZXIuc2NyZWVuTGVuc0Rpc3RhbmNlO1xuICB2YXIgaGFsZkxlbnNEaXN0YW5jZSA9IHZpZXdlci5pbnRlckxlbnNEaXN0YW5jZSAvIDIgLyBleWVUb1NjcmVlbkRpc3RhbmNlO1xuICB2YXIgc2NyZWVuV2lkdGggPSBkZXZpY2Uud2lkdGhNZXRlcnMgLyBleWVUb1NjcmVlbkRpc3RhbmNlO1xuICB2YXIgc2NyZWVuSGVpZ2h0ID0gZGV2aWNlLmhlaWdodE1ldGVycyAvIGV5ZVRvU2NyZWVuRGlzdGFuY2U7XG5cbiAgdmFyIGV5ZVBvc1ggPSBzY3JlZW5XaWR0aCAvIDIgLSBoYWxmTGVuc0Rpc3RhbmNlO1xuICB2YXIgZXllUG9zWSA9ICh2aWV3ZXIuYmFzZWxpbmVMZW5zRGlzdGFuY2UgLSBkZXZpY2UuYmV2ZWxNZXRlcnMpIC8gZXllVG9TY3JlZW5EaXN0YW5jZTtcblxuICB2YXIgbWF4Rm92ID0gdmlld2VyLmZvdjtcbiAgdmFyIHZpZXdlck1heCA9IGRpc3RvcnRpb24uZGlzdG9ydEludmVyc2UoTWF0aC50YW4oTWF0aFV0aWwuZGVnVG9SYWQgKiBtYXhGb3YpKTtcbiAgdmFyIG91dGVyRGlzdCA9IE1hdGgubWluKGV5ZVBvc1gsIHZpZXdlck1heCk7XG4gIHZhciBpbm5lckRpc3QgPSBNYXRoLm1pbihoYWxmTGVuc0Rpc3RhbmNlLCB2aWV3ZXJNYXgpO1xuICB2YXIgYm90dG9tRGlzdCA9IE1hdGgubWluKGV5ZVBvc1ksIHZpZXdlck1heCk7XG4gIHZhciB0b3BEaXN0ID0gTWF0aC5taW4oc2NyZWVuSGVpZ2h0IC0gZXllUG9zWSwgdmlld2VyTWF4KTtcblxuICByZXR1cm4ge1xuICAgIG91dGVyRGlzdDogb3V0ZXJEaXN0LFxuICAgIGlubmVyRGlzdDogaW5uZXJEaXN0LFxuICAgIHRvcERpc3Q6IHRvcERpc3QsXG4gICAgYm90dG9tRGlzdDogYm90dG9tRGlzdCxcbiAgICBleWVQb3NYOiBleWVQb3NYLFxuICAgIGV5ZVBvc1k6IGV5ZVBvc1lcbiAgfTtcbn07XG5cblxuZnVuY3Rpb24gQ2FyZGJvYXJkVmlld2VyKHBhcmFtcykge1xuICAvLyBBIG1hY2hpbmUgcmVhZGFibGUgSUQuXG4gIHRoaXMuaWQgPSBwYXJhbXMuaWQ7XG4gIC8vIEEgaHVtYW4gcmVhZGFibGUgbGFiZWwuXG4gIHRoaXMubGFiZWwgPSBwYXJhbXMubGFiZWw7XG5cbiAgLy8gRmllbGQgb2YgdmlldyBpbiBkZWdyZWVzIChwZXIgc2lkZSkuXG4gIHRoaXMuZm92ID0gcGFyYW1zLmZvdjtcblxuICAvLyBEaXN0YW5jZSBiZXR3ZWVuIGxlbnMgY2VudGVycyBpbiBtZXRlcnMuXG4gIHRoaXMuaW50ZXJMZW5zRGlzdGFuY2UgPSBwYXJhbXMuaW50ZXJMZW5zRGlzdGFuY2U7XG4gIC8vIERpc3RhbmNlIGJldHdlZW4gdmlld2VyIGJhc2VsaW5lIGFuZCBsZW5zIGNlbnRlciBpbiBtZXRlcnMuXG4gIHRoaXMuYmFzZWxpbmVMZW5zRGlzdGFuY2UgPSBwYXJhbXMuYmFzZWxpbmVMZW5zRGlzdGFuY2U7XG4gIC8vIFNjcmVlbi10by1sZW5zIGRpc3RhbmNlIGluIG1ldGVycy5cbiAgdGhpcy5zY3JlZW5MZW5zRGlzdGFuY2UgPSBwYXJhbXMuc2NyZWVuTGVuc0Rpc3RhbmNlO1xuXG4gIC8vIERpc3RvcnRpb24gY29lZmZpY2llbnRzLlxuICB0aGlzLmRpc3RvcnRpb25Db2VmZmljaWVudHMgPSBwYXJhbXMuZGlzdG9ydGlvbkNvZWZmaWNpZW50cztcbiAgLy8gSW52ZXJzZSBkaXN0b3J0aW9uIGNvZWZmaWNpZW50cy5cbiAgLy8gVE9ETzogQ2FsY3VsYXRlIHRoZXNlIGZyb20gZGlzdG9ydGlvbkNvZWZmaWNpZW50cyBpbiB0aGUgZnV0dXJlLlxuICB0aGlzLmludmVyc2VDb2VmZmljaWVudHMgPSBwYXJhbXMuaW52ZXJzZUNvZWZmaWNpZW50cztcbn1cblxuLy8gRXhwb3J0IHZpZXdlciBpbmZvcm1hdGlvbi5cbkRldmljZUluZm8uVmlld2VycyA9IFZpZXdlcnM7XG5tb2R1bGUuZXhwb3J0cyA9IERldmljZUluZm87XG5cbn0se1wiLi9kaXN0b3J0aW9uL2Rpc3RvcnRpb24uanNcIjoxMCxcIi4vbWF0aC11dGlsLmpzXCI6MTQsXCIuL3V0aWwuanNcIjoyMn1dLDk6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuLypcbiAqIENvcHlyaWdodCAyMDE2IEdvb2dsZSBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cbnZhciBWUkRpc3BsYXkgPSBfZGVyZXFfKCcuL2Jhc2UuanMnKS5WUkRpc3BsYXk7XG52YXIgSE1EVlJEZXZpY2UgPSBfZGVyZXFfKCcuL2Jhc2UuanMnKS5ITURWUkRldmljZTtcbnZhciBQb3NpdGlvblNlbnNvclZSRGV2aWNlID0gX2RlcmVxXygnLi9iYXNlLmpzJykuUG9zaXRpb25TZW5zb3JWUkRldmljZTtcblxuLyoqXG4gKiBXcmFwcyBhIFZSRGlzcGxheSBhbmQgZXhwb3NlcyBpdCBhcyBhIEhNRFZSRGV2aWNlXG4gKi9cbmZ1bmN0aW9uIFZSRGlzcGxheUhNRERldmljZShkaXNwbGF5KSB7XG4gIHRoaXMuZGlzcGxheSA9IGRpc3BsYXk7XG5cbiAgdGhpcy5oYXJkd2FyZVVuaXRJZCA9IGRpc3BsYXkuZGlzcGxheUlkO1xuICB0aGlzLmRldmljZUlkID0gJ3dlYnZyLXBvbHlmaWxsOkhNRDonICsgZGlzcGxheS5kaXNwbGF5SWQ7XG4gIHRoaXMuZGV2aWNlTmFtZSA9IGRpc3BsYXkuZGlzcGxheU5hbWUgKyAnIChITUQpJztcbn1cblZSRGlzcGxheUhNRERldmljZS5wcm90b3R5cGUgPSBuZXcgSE1EVlJEZXZpY2UoKTtcblxuVlJEaXNwbGF5SE1ERGV2aWNlLnByb3RvdHlwZS5nZXRFeWVQYXJhbWV0ZXJzID0gZnVuY3Rpb24od2hpY2hFeWUpIHtcbiAgdmFyIGV5ZVBhcmFtZXRlcnMgPSB0aGlzLmRpc3BsYXkuZ2V0RXllUGFyYW1ldGVycyh3aGljaEV5ZSk7XG5cbiAgcmV0dXJuIHtcbiAgICBjdXJyZW50RmllbGRPZlZpZXc6IGV5ZVBhcmFtZXRlcnMuZmllbGRPZlZpZXcsXG4gICAgbWF4aW11bUZpZWxkT2ZWaWV3OiBleWVQYXJhbWV0ZXJzLmZpZWxkT2ZWaWV3LFxuICAgIG1pbmltdW1GaWVsZE9mVmlldzogZXllUGFyYW1ldGVycy5maWVsZE9mVmlldyxcbiAgICByZWNvbW1lbmRlZEZpZWxkT2ZWaWV3OiBleWVQYXJhbWV0ZXJzLmZpZWxkT2ZWaWV3LFxuICAgIGV5ZVRyYW5zbGF0aW9uOiB7IHg6IGV5ZVBhcmFtZXRlcnMub2Zmc2V0WzBdLCB5OiBleWVQYXJhbWV0ZXJzLm9mZnNldFsxXSwgejogZXllUGFyYW1ldGVycy5vZmZzZXRbMl0gfSxcbiAgICByZW5kZXJSZWN0OiB7XG4gICAgICB4OiAod2hpY2hFeWUgPT0gJ3JpZ2h0JykgPyBleWVQYXJhbWV0ZXJzLnJlbmRlcldpZHRoIDogMCxcbiAgICAgIHk6IDAsXG4gICAgICB3aWR0aDogZXllUGFyYW1ldGVycy5yZW5kZXJXaWR0aCxcbiAgICAgIGhlaWdodDogZXllUGFyYW1ldGVycy5yZW5kZXJIZWlnaHRcbiAgICB9XG4gIH07XG59O1xuXG5WUkRpc3BsYXlITUREZXZpY2UucHJvdG90eXBlLnNldEZpZWxkT2ZWaWV3ID1cbiAgICBmdW5jdGlvbihvcHRfZm92TGVmdCwgb3B0X2ZvdlJpZ2h0LCBvcHRfek5lYXIsIG9wdF96RmFyKSB7XG4gIC8vIE5vdCBzdXBwb3J0ZWQuIGdldEV5ZVBhcmFtZXRlcnMgcmVwb3J0cyB0aGF0IHRoZSBtaW4sIG1heCwgYW5kIHJlY29tbWVuZGVkXG4gIC8vIEZvViBpcyBhbGwgdGhlIHNhbWUsIHNvIG5vIGFkanVzdG1lbnQgY2FuIGJlIG1hZGUuXG59O1xuXG4vLyBUT0RPOiBOZWVkIHRvIGhvb2sgcmVxdWVzdEZ1bGxzY3JlZW4gdG8gc2VlIGlmIGEgd3JhcHBlZCBWUkRpc3BsYXkgd2FzIHBhc3NlZFxuLy8gaW4gYXMgYW4gb3B0aW9uLiBJZiBzbyB3ZSBzaG91bGQgcHJldmVudCB0aGUgZGVmYXVsdCBmdWxsc2NyZWVuIGJlaGF2aW9yIGFuZFxuLy8gY2FsbCBWUkRpc3BsYXkucmVxdWVzdFByZXNlbnQgaW5zdGVhZC5cblxuLyoqXG4gKiBXcmFwcyBhIFZSRGlzcGxheSBhbmQgZXhwb3NlcyBpdCBhcyBhIFBvc2l0aW9uU2Vuc29yVlJEZXZpY2VcbiAqL1xuZnVuY3Rpb24gVlJEaXNwbGF5UG9zaXRpb25TZW5zb3JEZXZpY2UoZGlzcGxheSkge1xuICB0aGlzLmRpc3BsYXkgPSBkaXNwbGF5O1xuXG4gIHRoaXMuaGFyZHdhcmVVbml0SWQgPSBkaXNwbGF5LmRpc3BsYXlJZDtcbiAgdGhpcy5kZXZpY2VJZCA9ICd3ZWJ2ci1wb2x5ZmlsbDpQb3NpdGlvblNlbnNvcjogJyArIGRpc3BsYXkuZGlzcGxheUlkO1xuICB0aGlzLmRldmljZU5hbWUgPSBkaXNwbGF5LmRpc3BsYXlOYW1lICsgJyAoUG9zaXRpb25TZW5zb3IpJztcbn1cblZSRGlzcGxheVBvc2l0aW9uU2Vuc29yRGV2aWNlLnByb3RvdHlwZSA9IG5ldyBQb3NpdGlvblNlbnNvclZSRGV2aWNlKCk7XG5cblZSRGlzcGxheVBvc2l0aW9uU2Vuc29yRGV2aWNlLnByb3RvdHlwZS5nZXRTdGF0ZSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgcG9zZSA9IHRoaXMuZGlzcGxheS5nZXRQb3NlKCk7XG4gIHJldHVybiB7XG4gICAgcG9zaXRpb246IHBvc2UucG9zaXRpb24gPyB7IHg6IHBvc2UucG9zaXRpb25bMF0sIHk6IHBvc2UucG9zaXRpb25bMV0sIHo6IHBvc2UucG9zaXRpb25bMl0gfSA6IG51bGwsXG4gICAgb3JpZW50YXRpb246IHBvc2Uub3JpZW50YXRpb24gPyB7IHg6IHBvc2Uub3JpZW50YXRpb25bMF0sIHk6IHBvc2Uub3JpZW50YXRpb25bMV0sIHo6IHBvc2Uub3JpZW50YXRpb25bMl0sIHc6IHBvc2Uub3JpZW50YXRpb25bM10gfSA6IG51bGwsXG4gICAgbGluZWFyVmVsb2NpdHk6IG51bGwsXG4gICAgbGluZWFyQWNjZWxlcmF0aW9uOiBudWxsLFxuICAgIGFuZ3VsYXJWZWxvY2l0eTogbnVsbCxcbiAgICBhbmd1bGFyQWNjZWxlcmF0aW9uOiBudWxsXG4gIH07XG59O1xuXG5WUkRpc3BsYXlQb3NpdGlvblNlbnNvckRldmljZS5wcm90b3R5cGUucmVzZXRTdGF0ZSA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gdGhpcy5wb3NpdGlvbkRldmljZS5yZXNldFBvc2UoKTtcbn07XG5cblxubW9kdWxlLmV4cG9ydHMuVlJEaXNwbGF5SE1ERGV2aWNlID0gVlJEaXNwbGF5SE1ERGV2aWNlO1xubW9kdWxlLmV4cG9ydHMuVlJEaXNwbGF5UG9zaXRpb25TZW5zb3JEZXZpY2UgPSBWUkRpc3BsYXlQb3NpdGlvblNlbnNvckRldmljZTtcblxuXG59LHtcIi4vYmFzZS5qc1wiOjN9XSwxMDpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4vKipcbiAqIFRPRE8oc211cyk6IEltcGxlbWVudCBjb2VmZmljaWVudCBpbnZlcnNpb24uXG4gKi9cbmZ1bmN0aW9uIERpc3RvcnRpb24oY29lZmZpY2llbnRzKSB7XG4gIHRoaXMuY29lZmZpY2llbnRzID0gY29lZmZpY2llbnRzO1xufVxuXG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIGludmVyc2UgZGlzdG9ydGlvbiBmb3IgYSByYWRpdXMuXG4gKiA8L3A+PHA+XG4gKiBBbGxvd3MgdG8gY29tcHV0ZSB0aGUgb3JpZ2luYWwgdW5kaXN0b3J0ZWQgcmFkaXVzIGZyb20gYSBkaXN0b3J0ZWQgb25lLlxuICogU2VlIGFsc28gZ2V0QXBwcm94aW1hdGVJbnZlcnNlRGlzdG9ydGlvbigpIGZvciBhIGZhc3RlciBidXQgcG90ZW50aWFsbHlcbiAqIGxlc3MgYWNjdXJhdGUgbWV0aG9kLlxuICpcbiAqIEBwYXJhbSB7TnVtYmVyfSByYWRpdXMgRGlzdG9ydGVkIHJhZGl1cyBmcm9tIHRoZSBsZW5zIGNlbnRlciBpbiB0YW4tYW5nbGUgdW5pdHMuXG4gKiBAcmV0dXJuIHtOdW1iZXJ9IFRoZSB1bmRpc3RvcnRlZCByYWRpdXMgaW4gdGFuLWFuZ2xlIHVuaXRzLlxuICovXG5EaXN0b3J0aW9uLnByb3RvdHlwZS5kaXN0b3J0SW52ZXJzZSA9IGZ1bmN0aW9uKHJhZGl1cykge1xuICAvLyBTZWNhbnQgbWV0aG9kLlxuICB2YXIgcjAgPSAwO1xuICB2YXIgcjEgPSAxO1xuICB2YXIgZHIwID0gcmFkaXVzIC0gdGhpcy5kaXN0b3J0KHIwKTtcbiAgd2hpbGUgKE1hdGguYWJzKHIxIC0gcjApID4gMC4wMDAxIC8qKiAwLjFtbSAqLykge1xuICAgIHZhciBkcjEgPSByYWRpdXMgLSB0aGlzLmRpc3RvcnQocjEpO1xuICAgIHZhciByMiA9IHIxIC0gZHIxICogKChyMSAtIHIwKSAvIChkcjEgLSBkcjApKTtcbiAgICByMCA9IHIxO1xuICAgIHIxID0gcjI7XG4gICAgZHIwID0gZHIxO1xuICB9XG4gIHJldHVybiByMTtcbn07XG5cbi8qKlxuICogRGlzdG9ydHMgYSByYWRpdXMgYnkgaXRzIGRpc3RvcnRpb24gZmFjdG9yIGZyb20gdGhlIGNlbnRlciBvZiB0aGUgbGVuc2VzLlxuICpcbiAqIEBwYXJhbSB7TnVtYmVyfSByYWRpdXMgUmFkaXVzIGZyb20gdGhlIGxlbnMgY2VudGVyIGluIHRhbi1hbmdsZSB1bml0cy5cbiAqIEByZXR1cm4ge051bWJlcn0gVGhlIGRpc3RvcnRlZCByYWRpdXMgaW4gdGFuLWFuZ2xlIHVuaXRzLlxuICovXG5EaXN0b3J0aW9uLnByb3RvdHlwZS5kaXN0b3J0ID0gZnVuY3Rpb24ocmFkaXVzKSB7XG4gIHZhciByMiA9IHJhZGl1cyAqIHJhZGl1cztcbiAgdmFyIHJldCA9IDA7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5jb2VmZmljaWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICByZXQgPSByMiAqIChyZXQgKyB0aGlzLmNvZWZmaWNpZW50c1tpXSk7XG4gIH1cbiAgcmV0dXJuIChyZXQgKyAxKSAqIHJhZGl1cztcbn07XG5cbi8vIEZ1bmN0aW9ucyBiZWxvdyByb3VnaGx5IHBvcnRlZCBmcm9tXG4vLyBodHRwczovL2dpdGh1Yi5jb20vZ29vZ2xlc2FtcGxlcy9jYXJkYm9hcmQtdW5pdHkvYmxvYi9tYXN0ZXIvQ2FyZGJvYXJkL1NjcmlwdHMvQ2FyZGJvYXJkUHJvZmlsZS5jcyNMNDEyXG5cbi8vIFNvbHZlcyBhIHNtYWxsIGxpbmVhciBlcXVhdGlvbiB2aWEgZGVzdHJ1Y3RpdmUgZ2F1c3NpYW5cbi8vIGVsaW1pbmF0aW9uIGFuZCBiYWNrIHN1YnN0aXR1dGlvbi4gIFRoaXMgaXNuJ3QgZ2VuZXJpYyBudW1lcmljXG4vLyBjb2RlLCBpdCdzIGp1c3QgYSBxdWljayBoYWNrIHRvIHdvcmsgd2l0aCB0aGUgZ2VuZXJhbGx5XG4vLyB3ZWxsLWJlaGF2ZWQgc3ltbWV0cmljIG1hdHJpY2VzIGZvciBsZWFzdC1zcXVhcmVzIGZpdHRpbmcuXG4vLyBOb3QgaW50ZW5kZWQgZm9yIHJldXNlLlxuLy9cbi8vIEBwYXJhbSBhIElucHV0IHBvc2l0aXZlIGRlZmluaXRlIHN5bW1ldHJpY2FsIG1hdHJpeC4gRGVzdHJveWVkXG4vLyAgICAgZHVyaW5nIGNhbGN1bGF0aW9uLlxuLy8gQHBhcmFtIHkgSW5wdXQgcmlnaHQtaGFuZC1zaWRlIHZhbHVlcy4gRGVzdHJveWVkIGR1cmluZyBjYWxjdWxhdGlvbi5cbi8vIEByZXR1cm4gUmVzdWx0aW5nIHggdmFsdWUgdmVjdG9yLlxuLy9cbkRpc3RvcnRpb24ucHJvdG90eXBlLnNvbHZlTGluZWFyXyA9IGZ1bmN0aW9uKGEsIHkpIHtcbiAgdmFyIG4gPSBhLmxlbmd0aDtcblxuICAvLyBHYXVzc2lhbiBlbGltaW5hdGlvbiAobm8gcm93IGV4Y2hhbmdlKSB0byB0cmlhbmd1bGFyIG1hdHJpeC5cbiAgLy8gVGhlIGlucHV0IG1hdHJpeCBpcyBhIEFeVCBBIHByb2R1Y3Qgd2hpY2ggc2hvdWxkIGJlIGEgcG9zaXRpdmVcbiAgLy8gZGVmaW5pdGUgc3ltbWV0cmljYWwgbWF0cml4LCBhbmQgaWYgSSByZW1lbWJlciBteSBsaW5lYXJcbiAgLy8gYWxnZWJyYSByaWdodCB0aGlzIGltcGxpZXMgdGhhdCB0aGUgcGl2b3RzIHdpbGwgYmUgbm9uemVybyBhbmRcbiAgLy8gY2FsY3VsYXRpb25zIHN1ZmZpY2llbnRseSBhY2N1cmF0ZSB3aXRob3V0IG5lZWRpbmcgcm93XG4gIC8vIGV4Y2hhbmdlLlxuICBmb3IgKHZhciBqID0gMDsgaiA8IG4gLSAxOyArK2opIHtcbiAgICBmb3IgKHZhciBrID0gaiArIDE7IGsgPCBuOyArK2spIHtcbiAgICAgIHZhciBwID0gYVtqXVtrXSAvIGFbal1bal07XG4gICAgICBmb3IgKHZhciBpID0gaiArIDE7IGkgPCBuOyArK2kpIHtcbiAgICAgICAgYVtpXVtrXSAtPSBwICogYVtpXVtqXTtcbiAgICAgIH1cbiAgICAgIHlba10gLT0gcCAqIHlbal07XG4gICAgfVxuICB9XG4gIC8vIEZyb20gdGhpcyBwb2ludCBvbiwgb25seSB0aGUgbWF0cml4IGVsZW1lbnRzIGFbal1baV0gd2l0aCBpPj1qIGFyZVxuICAvLyB2YWxpZC4gVGhlIGVsaW1pbmF0aW9uIGRvZXNuJ3QgZmlsbCBpbiBlbGltaW5hdGVkIDAgdmFsdWVzLlxuXG4gIHZhciB4ID0gbmV3IEFycmF5KG4pO1xuXG4gIC8vIEJhY2sgc3Vic3RpdHV0aW9uLlxuICBmb3IgKHZhciBqID0gbiAtIDE7IGogPj0gMDsgLS1qKSB7XG4gICAgdmFyIHYgPSB5W2pdO1xuICAgIGZvciAodmFyIGkgPSBqICsgMTsgaSA8IG47ICsraSkge1xuICAgICAgdiAtPSBhW2ldW2pdICogeFtpXTtcbiAgICB9XG4gICAgeFtqXSA9IHYgLyBhW2pdW2pdO1xuICB9XG5cbiAgcmV0dXJuIHg7XG59O1xuXG4vLyBTb2x2ZXMgYSBsZWFzdC1zcXVhcmVzIG1hdHJpeCBlcXVhdGlvbi4gIEdpdmVuIHRoZSBlcXVhdGlvbiBBICogeCA9IHksIGNhbGN1bGF0ZSB0aGVcbi8vIGxlYXN0LXNxdWFyZSBmaXQgeCA9IGludmVyc2UoQSAqIHRyYW5zcG9zZShBKSkgKiB0cmFuc3Bvc2UoQSkgKiB5LiAgVGhlIHdheSB0aGlzIHdvcmtzXG4vLyBpcyB0aGF0LCB3aGlsZSBBIGlzIHR5cGljYWxseSBub3QgYSBzcXVhcmUgbWF0cml4IChhbmQgaGVuY2Ugbm90IGludmVydGlibGUpLCBBICogdHJhbnNwb3NlKEEpXG4vLyBpcyBhbHdheXMgc3F1YXJlLiAgVGhhdCBpczpcbi8vICAgQSAqIHggPSB5XG4vLyAgIHRyYW5zcG9zZShBKSAqIChBICogeCkgPSB0cmFuc3Bvc2UoQSkgKiB5ICAgPC0gbXVsdGlwbHkgYm90aCBzaWRlcyBieSB0cmFuc3Bvc2UoQSlcbi8vICAgKHRyYW5zcG9zZShBKSAqIEEpICogeCA9IHRyYW5zcG9zZShBKSAqIHkgICA8LSBhc3NvY2lhdGl2aXR5XG4vLyAgIHggPSBpbnZlcnNlKHRyYW5zcG9zZShBKSAqIEEpICogdHJhbnNwb3NlKEEpICogeSAgPC0gc29sdmUgZm9yIHhcbi8vIE1hdHJpeCBBJ3Mgcm93IGNvdW50IChmaXJzdCBpbmRleCkgbXVzdCBtYXRjaCB5J3MgdmFsdWUgY291bnQuICBBJ3MgY29sdW1uIGNvdW50IChzZWNvbmQgaW5kZXgpXG4vLyBkZXRlcm1pbmVzIHRoZSBsZW5ndGggb2YgdGhlIHJlc3VsdCB2ZWN0b3IgeC5cbkRpc3RvcnRpb24ucHJvdG90eXBlLnNvbHZlTGVhc3RTcXVhcmVzXyA9IGZ1bmN0aW9uKG1hdEEsIHZlY1kpIHtcbiAgdmFyIGksIGosIGssIHN1bTtcbiAgdmFyIG51bVNhbXBsZXMgPSBtYXRBLmxlbmd0aDtcbiAgdmFyIG51bUNvZWZmaWNpZW50cyA9IG1hdEFbMF0ubGVuZ3RoO1xuICBpZiAobnVtU2FtcGxlcyAhPSB2ZWNZLkxlbmd0aCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIk1hdHJpeCAvIHZlY3RvciBkaW1lbnNpb24gbWlzbWF0Y2hcIik7XG4gIH1cblxuICAvLyBDYWxjdWxhdGUgdHJhbnNwb3NlKEEpICogQVxuICB2YXIgbWF0QVRBID0gbmV3IEFycmF5KG51bUNvZWZmaWNpZW50cyk7XG4gIGZvciAoayA9IDA7IGsgPCBudW1Db2VmZmljaWVudHM7ICsraykge1xuICAgIG1hdEFUQVtrXSA9IG5ldyBBcnJheShudW1Db2VmZmljaWVudHMpO1xuICAgIGZvciAoaiA9IDA7IGogPCBudW1Db2VmZmljaWVudHM7ICsraikge1xuICAgICAgc3VtID0gMDtcbiAgICAgIGZvciAoaSA9IDA7IGkgPCBudW1TYW1wbGVzOyArK2kpIHtcbiAgICAgICAgc3VtICs9IG1hdEFbal1baV0gKiBtYXRBW2tdW2ldO1xuICAgICAgfVxuICAgICAgbWF0QVRBW2tdW2pdID0gc3VtO1xuICAgIH1cbiAgfVxuXG4gIC8vIENhbGN1bGF0ZSB0cmFuc3Bvc2UoQSkgKiB5XG4gIHZhciB2ZWNBVFkgPSBuZXcgQXJyYXkobnVtQ29lZmZpY2llbnRzKTtcbiAgZm9yIChqID0gMDsgaiA8IG51bUNvZWZmaWNpZW50czsgKytqKSB7XG4gICAgc3VtID0gMDtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbnVtU2FtcGxlczsgKytpKSB7XG4gICAgICBzdW0gKz0gbWF0QVtqXVtpXSAqIHZlY1lbaV07XG4gICAgfVxuICAgIHZlY0FUWVtqXSA9IHN1bTtcbiAgfVxuXG4gIC8vIE5vdyBzb2x2ZSAoQSAqIHRyYW5zcG9zZShBKSkgKiB4ID0gdHJhbnNwb3NlKEEpICogeS5cbiAgcmV0dXJuIHRoaXMuc29sdmVMaW5lYXJfKG1hdEFUQSwgdmVjQVRZKTtcbn07XG5cbi8vLyBDYWxjdWxhdGVzIGFuIGFwcHJveGltYXRlIGludmVyc2UgdG8gdGhlIGdpdmVuIHJhZGlhbCBkaXN0b3J0aW9uIHBhcmFtZXRlcnMuXG5EaXN0b3J0aW9uLnByb3RvdHlwZS5hcHByb3hpbWF0ZUludmVyc2UgPSBmdW5jdGlvbihtYXhSYWRpdXMsIG51bVNhbXBsZXMpIHtcbiAgbWF4UmFkaXVzID0gbWF4UmFkaXVzIHx8IDE7XG4gIG51bVNhbXBsZXMgPSBudW1TYW1wbGVzIHx8IDEwMDtcbiAgdmFyIG51bUNvZWZmaWNpZW50cyA9IDY7XG4gIHZhciBpLCBqO1xuXG4gIC8vIFIgKyBLMSpSXjMgKyBLMipSXjUgPSByLCB3aXRoIFIgPSBycCA9IGRpc3RvcnQocilcbiAgLy8gUmVwZWF0aW5nIGZvciBudW1TYW1wbGVzOlxuICAvLyAgIFsgUjBeMywgUjBeNSBdICogWyBLMSBdID0gWyByMCAtIFIwIF1cbiAgLy8gICBbIFIxXjMsIFIxXjUgXSAgIFsgSzIgXSAgIFsgcjEgLSBSMSBdXG4gIC8vICAgWyBSMl4zLCBSMl41IF0gICAgICAgICAgICBbIHIyIC0gUjIgXVxuICAvLyAgIFsgZXRjLi4uIF0gICAgICAgICAgICAgICAgWyBldGMuLi4gXVxuICAvLyBUaGF0IGlzOlxuICAvLyAgIG1hdEEgKiBbSzEsIEsyXSA9IHlcbiAgLy8gU29sdmU6XG4gIC8vICAgW0sxLCBLMl0gPSBpbnZlcnNlKHRyYW5zcG9zZShtYXRBKSAqIG1hdEEpICogdHJhbnNwb3NlKG1hdEEpICogeVxuICB2YXIgbWF0QSA9IG5ldyBBcnJheShudW1Db2VmZmljaWVudHMpO1xuICBmb3IgKGogPSAwOyBqIDwgbnVtQ29lZmZpY2llbnRzOyArK2opIHtcbiAgICBtYXRBW2pdID0gbmV3IEFycmF5KG51bVNhbXBsZXMpO1xuICB9XG4gIHZhciB2ZWNZID0gbmV3IEFycmF5KG51bVNhbXBsZXMpO1xuXG4gIGZvciAoaSA9IDA7IGkgPCBudW1TYW1wbGVzOyArK2kpIHtcbiAgICB2YXIgciA9IG1heFJhZGl1cyAqIChpICsgMSkgLyBudW1TYW1wbGVzO1xuICAgIHZhciBycCA9IHRoaXMuZGlzdG9ydChyKTtcbiAgICB2YXIgdiA9IHJwO1xuICAgIGZvciAoaiA9IDA7IGogPCBudW1Db2VmZmljaWVudHM7ICsraikge1xuICAgICAgdiAqPSBycCAqIHJwO1xuICAgICAgbWF0QVtqXVtpXSA9IHY7XG4gICAgfVxuICAgIHZlY1lbaV0gPSByIC0gcnA7XG4gIH1cblxuICB2YXIgaW52ZXJzZUNvZWZmaWNpZW50cyA9IHRoaXMuc29sdmVMZWFzdFNxdWFyZXNfKG1hdEEsIHZlY1kpO1xuXG4gIHJldHVybiBuZXcgRGlzdG9ydGlvbihpbnZlcnNlQ29lZmZpY2llbnRzKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gRGlzdG9ydGlvbjtcblxufSx7fV0sMTE6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuLypcbiAqIENvcHlyaWdodCAyMDE1IEdvb2dsZSBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuLyoqXG4gKiBEUERCIGNhY2hlLlxuICovXG52YXIgRFBEQl9DQUNIRSA9IHtcbiAgXCJmb3JtYXRcIjogMSxcbiAgXCJsYXN0X3VwZGF0ZWRcIjogXCIyMDE2LTAxLTIwVDAwOjE4OjM1WlwiLFxuICBcImRldmljZXNcIjogW1xuXG4gIHtcbiAgICBcInR5cGVcIjogXCJhbmRyb2lkXCIsXG4gICAgXCJydWxlc1wiOiBbXG4gICAgICB7IFwibWRtaFwiOiBcImFzdXMvKi9OZXh1cyA3LypcIiB9LFxuICAgICAgeyBcInVhXCI6IFwiTmV4dXMgN1wiIH1cbiAgICBdLFxuICAgIFwiZHBpXCI6IFsgMzIwLjgsIDMyMy4wIF0sXG4gICAgXCJid1wiOiAzLFxuICAgIFwiYWNcIjogNTAwXG4gIH0sXG5cbiAge1xuICAgIFwidHlwZVwiOiBcImFuZHJvaWRcIixcbiAgICBcInJ1bGVzXCI6IFtcbiAgICAgIHsgXCJtZG1oXCI6IFwiYXN1cy8qL0FTVVNfWjAwQUQvKlwiIH0sXG4gICAgICB7IFwidWFcIjogXCJBU1VTX1owMEFEXCIgfVxuICAgIF0sXG4gICAgXCJkcGlcIjogWyA0MDMuMCwgNDA0LjYgXSxcbiAgICBcImJ3XCI6IDMsXG4gICAgXCJhY1wiOiAxMDAwXG4gIH0sXG5cbiAge1xuICAgIFwidHlwZVwiOiBcImFuZHJvaWRcIixcbiAgICBcInJ1bGVzXCI6IFtcbiAgICAgIHsgXCJtZG1oXCI6IFwiSFRDLyovSFRDNjQzNUxWVy8qXCIgfSxcbiAgICAgIHsgXCJ1YVwiOiBcIkhUQzY0MzVMVldcIiB9XG4gICAgXSxcbiAgICBcImRwaVwiOiBbIDQ0OS43LCA0NDMuMyBdLFxuICAgIFwiYndcIjogMyxcbiAgICBcImFjXCI6IDEwMDBcbiAgfSxcblxuICB7XG4gICAgXCJ0eXBlXCI6IFwiYW5kcm9pZFwiLFxuICAgIFwicnVsZXNcIjogW1xuICAgICAgeyBcIm1kbWhcIjogXCJIVEMvKi9IVEMgT25lIFhMLypcIiB9LFxuICAgICAgeyBcInVhXCI6IFwiSFRDIE9uZSBYTFwiIH1cbiAgICBdLFxuICAgIFwiZHBpXCI6IFsgMzE1LjMsIDMxNC42IF0sXG4gICAgXCJid1wiOiAzLFxuICAgIFwiYWNcIjogMTAwMFxuICB9LFxuXG4gIHtcbiAgICBcInR5cGVcIjogXCJhbmRyb2lkXCIsXG4gICAgXCJydWxlc1wiOiBbXG4gICAgICB7IFwibWRtaFwiOiBcImh0Yy8qL05leHVzIDkvKlwiIH0sXG4gICAgICB7IFwidWFcIjogXCJOZXh1cyA5XCIgfVxuICAgIF0sXG4gICAgXCJkcGlcIjogMjg5LjAsXG4gICAgXCJid1wiOiAzLFxuICAgIFwiYWNcIjogNTAwXG4gIH0sXG5cbiAge1xuICAgIFwidHlwZVwiOiBcImFuZHJvaWRcIixcbiAgICBcInJ1bGVzXCI6IFtcbiAgICAgIHsgXCJtZG1oXCI6IFwiSFRDLyovSFRDIE9uZSBNOS8qXCIgfSxcbiAgICAgIHsgXCJ1YVwiOiBcIkhUQyBPbmUgTTlcIiB9XG4gICAgXSxcbiAgICBcImRwaVwiOiBbIDQ0Mi41LCA0NDMuMyBdLFxuICAgIFwiYndcIjogMyxcbiAgICBcImFjXCI6IDUwMFxuICB9LFxuXG4gIHtcbiAgICBcInR5cGVcIjogXCJhbmRyb2lkXCIsXG4gICAgXCJydWxlc1wiOiBbXG4gICAgICB7IFwibWRtaFwiOiBcIkhUQy8qL0hUQyBPbmVfTTgvKlwiIH0sXG4gICAgICB7IFwidWFcIjogXCJIVEMgT25lX004XCIgfVxuICAgIF0sXG4gICAgXCJkcGlcIjogWyA0NDkuNywgNDQ3LjQgXSxcbiAgICBcImJ3XCI6IDMsXG4gICAgXCJhY1wiOiA1MDBcbiAgfSxcblxuICB7XG4gICAgXCJ0eXBlXCI6IFwiYW5kcm9pZFwiLFxuICAgIFwicnVsZXNcIjogW1xuICAgICAgeyBcIm1kbWhcIjogXCJIVEMvKi9IVEMgT25lLypcIiB9LFxuICAgICAgeyBcInVhXCI6IFwiSFRDIE9uZVwiIH1cbiAgICBdLFxuICAgIFwiZHBpXCI6IDQ3Mi44LFxuICAgIFwiYndcIjogMyxcbiAgICBcImFjXCI6IDEwMDBcbiAgfSxcblxuICB7XG4gICAgXCJ0eXBlXCI6IFwiYW5kcm9pZFwiLFxuICAgIFwicnVsZXNcIjogW1xuICAgICAgeyBcIm1kbWhcIjogXCJIdWF3ZWkvKi9OZXh1cyA2UC8qXCIgfSxcbiAgICAgIHsgXCJ1YVwiOiBcIk5leHVzIDZQXCIgfVxuICAgIF0sXG4gICAgXCJkcGlcIjogWyA1MTUuMSwgNTE4LjAgXSxcbiAgICBcImJ3XCI6IDMsXG4gICAgXCJhY1wiOiAxMDAwXG4gIH0sXG5cbiAge1xuICAgIFwidHlwZVwiOiBcImFuZHJvaWRcIixcbiAgICBcInJ1bGVzXCI6IFtcbiAgICAgIHsgXCJtZG1oXCI6IFwiTEdFLyovTmV4dXMgNVgvKlwiIH0sXG4gICAgICB7IFwidWFcIjogXCJOZXh1cyA1WFwiIH1cbiAgICBdLFxuICAgIFwiZHBpXCI6IFsgNDIyLjAsIDQxOS45IF0sXG4gICAgXCJid1wiOiAzLFxuICAgIFwiYWNcIjogMTAwMFxuICB9LFxuXG4gIHtcbiAgICBcInR5cGVcIjogXCJhbmRyb2lkXCIsXG4gICAgXCJydWxlc1wiOiBbXG4gICAgICB7IFwibWRtaFwiOiBcIkxHRS8qL0xHTVMzNDUvKlwiIH0sXG4gICAgICB7IFwidWFcIjogXCJMR01TMzQ1XCIgfVxuICAgIF0sXG4gICAgXCJkcGlcIjogWyAyMjEuNywgMjE5LjEgXSxcbiAgICBcImJ3XCI6IDMsXG4gICAgXCJhY1wiOiA1MDBcbiAgfSxcblxuICB7XG4gICAgXCJ0eXBlXCI6IFwiYW5kcm9pZFwiLFxuICAgIFwicnVsZXNcIjogW1xuICAgICAgeyBcIm1kbWhcIjogXCJMR0UvKi9MRy1EODAwLypcIiB9LFxuICAgICAgeyBcInVhXCI6IFwiTEctRDgwMFwiIH1cbiAgICBdLFxuICAgIFwiZHBpXCI6IFsgNDIyLjAsIDQyNC4xIF0sXG4gICAgXCJid1wiOiAzLFxuICAgIFwiYWNcIjogNTAwXG4gIH0sXG5cbiAge1xuICAgIFwidHlwZVwiOiBcImFuZHJvaWRcIixcbiAgICBcInJ1bGVzXCI6IFtcbiAgICAgIHsgXCJtZG1oXCI6IFwiTEdFLyovTEctRDg1MC8qXCIgfSxcbiAgICAgIHsgXCJ1YVwiOiBcIkxHLUQ4NTBcIiB9XG4gICAgXSxcbiAgICBcImRwaVwiOiBbIDUzNy45LCA1NDEuOSBdLFxuICAgIFwiYndcIjogMyxcbiAgICBcImFjXCI6IDUwMFxuICB9LFxuXG4gIHtcbiAgICBcInR5cGVcIjogXCJhbmRyb2lkXCIsXG4gICAgXCJydWxlc1wiOiBbXG4gICAgICB7IFwibWRtaFwiOiBcIkxHRS8qL1ZTOTg1IDRHLypcIiB9LFxuICAgICAgeyBcInVhXCI6IFwiVlM5ODUgNEdcIiB9XG4gICAgXSxcbiAgICBcImRwaVwiOiBbIDUzNy45LCA1MzUuNiBdLFxuICAgIFwiYndcIjogMyxcbiAgICBcImFjXCI6IDEwMDBcbiAgfSxcblxuICB7XG4gICAgXCJ0eXBlXCI6IFwiYW5kcm9pZFwiLFxuICAgIFwicnVsZXNcIjogW1xuICAgICAgeyBcIm1kbWhcIjogXCJMR0UvKi9OZXh1cyA1LypcIiB9LFxuICAgICAgeyBcInVhXCI6IFwiTmV4dXMgNSBcIiB9XG4gICAgXSxcbiAgICBcImRwaVwiOiBbIDQ0Mi40LCA0NDQuOCBdLFxuICAgIFwiYndcIjogMyxcbiAgICBcImFjXCI6IDEwMDBcbiAgfSxcblxuICB7XG4gICAgXCJ0eXBlXCI6IFwiYW5kcm9pZFwiLFxuICAgIFwicnVsZXNcIjogW1xuICAgICAgeyBcIm1kbWhcIjogXCJMR0UvKi9OZXh1cyA0LypcIiB9LFxuICAgICAgeyBcInVhXCI6IFwiTmV4dXMgNFwiIH1cbiAgICBdLFxuICAgIFwiZHBpXCI6IFsgMzE5LjgsIDMxOC40IF0sXG4gICAgXCJid1wiOiAzLFxuICAgIFwiYWNcIjogMTAwMFxuICB9LFxuXG4gIHtcbiAgICBcInR5cGVcIjogXCJhbmRyb2lkXCIsXG4gICAgXCJydWxlc1wiOiBbXG4gICAgICB7IFwibWRtaFwiOiBcIkxHRS8qL0xHLVA3NjkvKlwiIH0sXG4gICAgICB7IFwidWFcIjogXCJMRy1QNzY5XCIgfVxuICAgIF0sXG4gICAgXCJkcGlcIjogWyAyNDAuNiwgMjQ3LjUgXSxcbiAgICBcImJ3XCI6IDMsXG4gICAgXCJhY1wiOiAxMDAwXG4gIH0sXG5cbiAge1xuICAgIFwidHlwZVwiOiBcImFuZHJvaWRcIixcbiAgICBcInJ1bGVzXCI6IFtcbiAgICAgIHsgXCJtZG1oXCI6IFwiTEdFLyovTEdNUzMyMy8qXCIgfSxcbiAgICAgIHsgXCJ1YVwiOiBcIkxHTVMzMjNcIiB9XG4gICAgXSxcbiAgICBcImRwaVwiOiBbIDIwNi42LCAyMDQuNiBdLFxuICAgIFwiYndcIjogMyxcbiAgICBcImFjXCI6IDEwMDBcbiAgfSxcblxuICB7XG4gICAgXCJ0eXBlXCI6IFwiYW5kcm9pZFwiLFxuICAgIFwicnVsZXNcIjogW1xuICAgICAgeyBcIm1kbWhcIjogXCJMR0UvKi9MR0xTOTk2LypcIiB9LFxuICAgICAgeyBcInVhXCI6IFwiTEdMUzk5NlwiIH1cbiAgICBdLFxuICAgIFwiZHBpXCI6IFsgNDAzLjQsIDQwMS41IF0sXG4gICAgXCJid1wiOiAzLFxuICAgIFwiYWNcIjogMTAwMFxuICB9LFxuXG4gIHtcbiAgICBcInR5cGVcIjogXCJhbmRyb2lkXCIsXG4gICAgXCJydWxlc1wiOiBbXG4gICAgICB7IFwibWRtaFwiOiBcIk1pY3JvbWF4LyovNDU2ME1NWC8qXCIgfSxcbiAgICAgIHsgXCJ1YVwiOiBcIjQ1NjBNTVhcIiB9XG4gICAgXSxcbiAgICBcImRwaVwiOiBbIDI0MC4wLCAyMTkuNCBdLFxuICAgIFwiYndcIjogMyxcbiAgICBcImFjXCI6IDEwMDBcbiAgfSxcblxuICB7XG4gICAgXCJ0eXBlXCI6IFwiYW5kcm9pZFwiLFxuICAgIFwicnVsZXNcIjogW1xuICAgICAgeyBcIm1kbWhcIjogXCJNaWNyb21heC8qL0EyNTAvKlwiIH0sXG4gICAgICB7IFwidWFcIjogXCJNaWNyb21heCBBMjUwXCIgfVxuICAgIF0sXG4gICAgXCJkcGlcIjogWyA0ODAuMCwgNDQ2LjQgXSxcbiAgICBcImJ3XCI6IDMsXG4gICAgXCJhY1wiOiAxMDAwXG4gIH0sXG5cbiAge1xuICAgIFwidHlwZVwiOiBcImFuZHJvaWRcIixcbiAgICBcInJ1bGVzXCI6IFtcbiAgICAgIHsgXCJtZG1oXCI6IFwiTWljcm9tYXgvKi9NaWNyb21heCBBUTQ1MDEvKlwiIH0sXG4gICAgICB7IFwidWFcIjogXCJNaWNyb21heCBBUTQ1MDFcIiB9XG4gICAgXSxcbiAgICBcImRwaVwiOiAyNDAuMCxcbiAgICBcImJ3XCI6IDMsXG4gICAgXCJhY1wiOiA1MDBcbiAgfSxcblxuICB7XG4gICAgXCJ0eXBlXCI6IFwiYW5kcm9pZFwiLFxuICAgIFwicnVsZXNcIjogW1xuICAgICAgeyBcIm1kbWhcIjogXCJtb3Rvcm9sYS8qL0RST0lEIFJBWlIvKlwiIH0sXG4gICAgICB7IFwidWFcIjogXCJEUk9JRCBSQVpSXCIgfVxuICAgIF0sXG4gICAgXCJkcGlcIjogWyAzNjguMSwgMjU2LjcgXSxcbiAgICBcImJ3XCI6IDMsXG4gICAgXCJhY1wiOiAxMDAwXG4gIH0sXG5cbiAge1xuICAgIFwidHlwZVwiOiBcImFuZHJvaWRcIixcbiAgICBcInJ1bGVzXCI6IFtcbiAgICAgIHsgXCJtZG1oXCI6IFwibW90b3JvbGEvKi9YVDgzMEMvKlwiIH0sXG4gICAgICB7IFwidWFcIjogXCJYVDgzMENcIiB9XG4gICAgXSxcbiAgICBcImRwaVwiOiBbIDI1NC4wLCAyNTUuOSBdLFxuICAgIFwiYndcIjogMyxcbiAgICBcImFjXCI6IDEwMDBcbiAgfSxcblxuICB7XG4gICAgXCJ0eXBlXCI6IFwiYW5kcm9pZFwiLFxuICAgIFwicnVsZXNcIjogW1xuICAgICAgeyBcIm1kbWhcIjogXCJtb3Rvcm9sYS8qL1hUMTAyMS8qXCIgfSxcbiAgICAgIHsgXCJ1YVwiOiBcIlhUMTAyMVwiIH1cbiAgICBdLFxuICAgIFwiZHBpXCI6IFsgMjU0LjAsIDI1Ni43IF0sXG4gICAgXCJid1wiOiAzLFxuICAgIFwiYWNcIjogNTAwXG4gIH0sXG5cbiAge1xuICAgIFwidHlwZVwiOiBcImFuZHJvaWRcIixcbiAgICBcInJ1bGVzXCI6IFtcbiAgICAgIHsgXCJtZG1oXCI6IFwibW90b3JvbGEvKi9YVDEwMjMvKlwiIH0sXG4gICAgICB7IFwidWFcIjogXCJYVDEwMjNcIiB9XG4gICAgXSxcbiAgICBcImRwaVwiOiBbIDI1NC4wLCAyNTYuNyBdLFxuICAgIFwiYndcIjogMyxcbiAgICBcImFjXCI6IDUwMFxuICB9LFxuXG4gIHtcbiAgICBcInR5cGVcIjogXCJhbmRyb2lkXCIsXG4gICAgXCJydWxlc1wiOiBbXG4gICAgICB7IFwibWRtaFwiOiBcIm1vdG9yb2xhLyovWFQxMDI4LypcIiB9LFxuICAgICAgeyBcInVhXCI6IFwiWFQxMDI4XCIgfVxuICAgIF0sXG4gICAgXCJkcGlcIjogWyAzMjYuNiwgMzI3LjYgXSxcbiAgICBcImJ3XCI6IDMsXG4gICAgXCJhY1wiOiAxMDAwXG4gIH0sXG5cbiAge1xuICAgIFwidHlwZVwiOiBcImFuZHJvaWRcIixcbiAgICBcInJ1bGVzXCI6IFtcbiAgICAgIHsgXCJtZG1oXCI6IFwibW90b3JvbGEvKi9YVDEwMzQvKlwiIH0sXG4gICAgICB7IFwidWFcIjogXCJYVDEwMzRcIiB9XG4gICAgXSxcbiAgICBcImRwaVwiOiBbIDMyNi42LCAzMjguNCBdLFxuICAgIFwiYndcIjogMyxcbiAgICBcImFjXCI6IDUwMFxuICB9LFxuXG4gIHtcbiAgICBcInR5cGVcIjogXCJhbmRyb2lkXCIsXG4gICAgXCJydWxlc1wiOiBbXG4gICAgICB7IFwibWRtaFwiOiBcIm1vdG9yb2xhLyovWFQxMDUzLypcIiB9LFxuICAgICAgeyBcInVhXCI6IFwiWFQxMDUzXCIgfVxuICAgIF0sXG4gICAgXCJkcGlcIjogWyAzMTUuMywgMzE2LjEgXSxcbiAgICBcImJ3XCI6IDMsXG4gICAgXCJhY1wiOiAxMDAwXG4gIH0sXG5cbiAge1xuICAgIFwidHlwZVwiOiBcImFuZHJvaWRcIixcbiAgICBcInJ1bGVzXCI6IFtcbiAgICAgIHsgXCJtZG1oXCI6IFwibW90b3JvbGEvKi9YVDE1NjIvKlwiIH0sXG4gICAgICB7IFwidWFcIjogXCJYVDE1NjJcIiB9XG4gICAgXSxcbiAgICBcImRwaVwiOiBbIDQwMy40LCA0MDIuNyBdLFxuICAgIFwiYndcIjogMyxcbiAgICBcImFjXCI6IDEwMDBcbiAgfSxcblxuICB7XG4gICAgXCJ0eXBlXCI6IFwiYW5kcm9pZFwiLFxuICAgIFwicnVsZXNcIjogW1xuICAgICAgeyBcIm1kbWhcIjogXCJtb3Rvcm9sYS8qL05leHVzIDYvKlwiIH0sXG4gICAgICB7IFwidWFcIjogXCJOZXh1cyA2IFwiIH1cbiAgICBdLFxuICAgIFwiZHBpXCI6IFsgNDk0LjMsIDQ4OS43IF0sXG4gICAgXCJid1wiOiAzLFxuICAgIFwiYWNcIjogMTAwMFxuICB9LFxuXG4gIHtcbiAgICBcInR5cGVcIjogXCJhbmRyb2lkXCIsXG4gICAgXCJydWxlc1wiOiBbXG4gICAgICB7IFwibWRtaFwiOiBcIm1vdG9yb2xhLyovWFQxMDYzLypcIiB9LFxuICAgICAgeyBcInVhXCI6IFwiWFQxMDYzXCIgfVxuICAgIF0sXG4gICAgXCJkcGlcIjogWyAyOTUuMCwgMjk2LjYgXSxcbiAgICBcImJ3XCI6IDMsXG4gICAgXCJhY1wiOiAxMDAwXG4gIH0sXG5cbiAge1xuICAgIFwidHlwZVwiOiBcImFuZHJvaWRcIixcbiAgICBcInJ1bGVzXCI6IFtcbiAgICAgIHsgXCJtZG1oXCI6IFwibW90b3JvbGEvKi9YVDEwNjQvKlwiIH0sXG4gICAgICB7IFwidWFcIjogXCJYVDEwNjRcIiB9XG4gICAgXSxcbiAgICBcImRwaVwiOiBbIDI5NS4wLCAyOTUuNiBdLFxuICAgIFwiYndcIjogMyxcbiAgICBcImFjXCI6IDUwMFxuICB9LFxuXG4gIHtcbiAgICBcInR5cGVcIjogXCJhbmRyb2lkXCIsXG4gICAgXCJydWxlc1wiOiBbXG4gICAgICB7IFwibWRtaFwiOiBcIm1vdG9yb2xhLyovWFQxMDkyLypcIiB9LFxuICAgICAgeyBcInVhXCI6IFwiWFQxMDkyXCIgfVxuICAgIF0sXG4gICAgXCJkcGlcIjogWyA0MjIuMCwgNDI0LjEgXSxcbiAgICBcImJ3XCI6IDMsXG4gICAgXCJhY1wiOiA1MDBcbiAgfSxcblxuICB7XG4gICAgXCJ0eXBlXCI6IFwiYW5kcm9pZFwiLFxuICAgIFwicnVsZXNcIjogW1xuICAgICAgeyBcIm1kbWhcIjogXCJtb3Rvcm9sYS8qL1hUMTA5NS8qXCIgfSxcbiAgICAgIHsgXCJ1YVwiOiBcIlhUMTA5NVwiIH1cbiAgICBdLFxuICAgIFwiZHBpXCI6IFsgNDIyLjAsIDQyMy40IF0sXG4gICAgXCJid1wiOiAzLFxuICAgIFwiYWNcIjogMTAwMFxuICB9LFxuXG4gIHtcbiAgICBcInR5cGVcIjogXCJhbmRyb2lkXCIsXG4gICAgXCJydWxlc1wiOiBbXG4gICAgICB7IFwibWRtaFwiOiBcIk9uZVBsdXMvKi9BMDAwMS8qXCIgfSxcbiAgICAgIHsgXCJ1YVwiOiBcIkEwMDAxXCIgfVxuICAgIF0sXG4gICAgXCJkcGlcIjogWyA0MDMuNCwgNDAxLjAgXSxcbiAgICBcImJ3XCI6IDMsXG4gICAgXCJhY1wiOiAxMDAwXG4gIH0sXG5cbiAge1xuICAgIFwidHlwZVwiOiBcImFuZHJvaWRcIixcbiAgICBcInJ1bGVzXCI6IFtcbiAgICAgIHsgXCJtZG1oXCI6IFwiT25lUGx1cy8qL09ORSBFMTAwNS8qXCIgfSxcbiAgICAgIHsgXCJ1YVwiOiBcIk9ORSBFMTAwNVwiIH1cbiAgICBdLFxuICAgIFwiZHBpXCI6IFsgNDQyLjQsIDQ0MS40IF0sXG4gICAgXCJid1wiOiAzLFxuICAgIFwiYWNcIjogMTAwMFxuICB9LFxuXG4gIHtcbiAgICBcInR5cGVcIjogXCJhbmRyb2lkXCIsXG4gICAgXCJydWxlc1wiOiBbXG4gICAgICB7IFwibWRtaFwiOiBcIk9uZVBsdXMvKi9PTkUgQTIwMDUvKlwiIH0sXG4gICAgICB7IFwidWFcIjogXCJPTkUgQTIwMDVcIiB9XG4gICAgXSxcbiAgICBcImRwaVwiOiBbIDM5MS45LCA0MDUuNCBdLFxuICAgIFwiYndcIjogMyxcbiAgICBcImFjXCI6IDEwMDBcbiAgfSxcblxuICB7XG4gICAgXCJ0eXBlXCI6IFwiYW5kcm9pZFwiLFxuICAgIFwicnVsZXNcIjogW1xuICAgICAgeyBcIm1kbWhcIjogXCJPUFBPLyovWDkwOS8qXCIgfSxcbiAgICAgIHsgXCJ1YVwiOiBcIlg5MDlcIiB9XG4gICAgXSxcbiAgICBcImRwaVwiOiBbIDQ0Mi40LCA0NDQuMSBdLFxuICAgIFwiYndcIjogMyxcbiAgICBcImFjXCI6IDEwMDBcbiAgfSxcblxuICB7XG4gICAgXCJ0eXBlXCI6IFwiYW5kcm9pZFwiLFxuICAgIFwicnVsZXNcIjogW1xuICAgICAgeyBcIm1kbWhcIjogXCJzYW1zdW5nLyovR1QtSTkwODIvKlwiIH0sXG4gICAgICB7IFwidWFcIjogXCJHVC1JOTA4MlwiIH1cbiAgICBdLFxuICAgIFwiZHBpXCI6IFsgMTg0LjcsIDE4NS40IF0sXG4gICAgXCJid1wiOiAzLFxuICAgIFwiYWNcIjogMTAwMFxuICB9LFxuXG4gIHtcbiAgICBcInR5cGVcIjogXCJhbmRyb2lkXCIsXG4gICAgXCJydWxlc1wiOiBbXG4gICAgICB7IFwibWRtaFwiOiBcInNhbXN1bmcvKi9TTS1HMzYwUC8qXCIgfSxcbiAgICAgIHsgXCJ1YVwiOiBcIlNNLUczNjBQXCIgfVxuICAgIF0sXG4gICAgXCJkcGlcIjogWyAxOTYuNywgMjA1LjQgXSxcbiAgICBcImJ3XCI6IDMsXG4gICAgXCJhY1wiOiAxMDAwXG4gIH0sXG5cbiAge1xuICAgIFwidHlwZVwiOiBcImFuZHJvaWRcIixcbiAgICBcInJ1bGVzXCI6IFtcbiAgICAgIHsgXCJtZG1oXCI6IFwic2Ftc3VuZy8qL05leHVzIFMvKlwiIH0sXG4gICAgICB7IFwidWFcIjogXCJOZXh1cyBTXCIgfVxuICAgIF0sXG4gICAgXCJkcGlcIjogWyAyMzQuNSwgMjI5LjggXSxcbiAgICBcImJ3XCI6IDMsXG4gICAgXCJhY1wiOiAxMDAwXG4gIH0sXG5cbiAge1xuICAgIFwidHlwZVwiOiBcImFuZHJvaWRcIixcbiAgICBcInJ1bGVzXCI6IFtcbiAgICAgIHsgXCJtZG1oXCI6IFwic2Ftc3VuZy8qL0dULUk5MzAwLypcIiB9LFxuICAgICAgeyBcInVhXCI6IFwiR1QtSTkzMDBcIiB9XG4gICAgXSxcbiAgICBcImRwaVwiOiBbIDMwNC44LCAzMDMuOSBdLFxuICAgIFwiYndcIjogNSxcbiAgICBcImFjXCI6IDUwMFxuICB9LFxuXG4gIHtcbiAgICBcInR5cGVcIjogXCJhbmRyb2lkXCIsXG4gICAgXCJydWxlc1wiOiBbXG4gICAgICB7IFwibWRtaFwiOiBcInNhbXN1bmcvKi9TTS1UMjMwTlUvKlwiIH0sXG4gICAgICB7IFwidWFcIjogXCJTTS1UMjMwTlVcIiB9XG4gICAgXSxcbiAgICBcImRwaVwiOiAyMTYuMCxcbiAgICBcImJ3XCI6IDMsXG4gICAgXCJhY1wiOiA1MDBcbiAgfSxcblxuICB7XG4gICAgXCJ0eXBlXCI6IFwiYW5kcm9pZFwiLFxuICAgIFwicnVsZXNcIjogW1xuICAgICAgeyBcIm1kbWhcIjogXCJzYW1zdW5nLyovU0dILVQzOTkvKlwiIH0sXG4gICAgICB7IFwidWFcIjogXCJTR0gtVDM5OVwiIH1cbiAgICBdLFxuICAgIFwiZHBpXCI6IFsgMjE3LjcsIDIzMS40IF0sXG4gICAgXCJid1wiOiAzLFxuICAgIFwiYWNcIjogMTAwMFxuICB9LFxuXG4gIHtcbiAgICBcInR5cGVcIjogXCJhbmRyb2lkXCIsXG4gICAgXCJydWxlc1wiOiBbXG4gICAgICB7IFwibWRtaFwiOiBcInNhbXN1bmcvKi9TTS1OOTAwNS8qXCIgfSxcbiAgICAgIHsgXCJ1YVwiOiBcIlNNLU45MDA1XCIgfVxuICAgIF0sXG4gICAgXCJkcGlcIjogWyAzODYuNCwgMzg3LjAgXSxcbiAgICBcImJ3XCI6IDMsXG4gICAgXCJhY1wiOiA1MDBcbiAgfSxcblxuICB7XG4gICAgXCJ0eXBlXCI6IFwiYW5kcm9pZFwiLFxuICAgIFwicnVsZXNcIjogW1xuICAgICAgeyBcIm1kbWhcIjogXCJzYW1zdW5nLyovU0FNU1VORy1TTS1OOTAwQS8qXCIgfSxcbiAgICAgIHsgXCJ1YVwiOiBcIlNBTVNVTkctU00tTjkwMEFcIiB9XG4gICAgXSxcbiAgICBcImRwaVwiOiBbIDM4Ni40LCAzODcuNyBdLFxuICAgIFwiYndcIjogMyxcbiAgICBcImFjXCI6IDEwMDBcbiAgfSxcblxuICB7XG4gICAgXCJ0eXBlXCI6IFwiYW5kcm9pZFwiLFxuICAgIFwicnVsZXNcIjogW1xuICAgICAgeyBcIm1kbWhcIjogXCJzYW1zdW5nLyovR1QtSTk1MDAvKlwiIH0sXG4gICAgICB7IFwidWFcIjogXCJHVC1JOTUwMFwiIH1cbiAgICBdLFxuICAgIFwiZHBpXCI6IFsgNDQyLjUsIDQ0My4zIF0sXG4gICAgXCJid1wiOiAzLFxuICAgIFwiYWNcIjogNTAwXG4gIH0sXG5cbiAge1xuICAgIFwidHlwZVwiOiBcImFuZHJvaWRcIixcbiAgICBcInJ1bGVzXCI6IFtcbiAgICAgIHsgXCJtZG1oXCI6IFwic2Ftc3VuZy8qL0dULUk5NTA1LypcIiB9LFxuICAgICAgeyBcInVhXCI6IFwiR1QtSTk1MDVcIiB9XG4gICAgXSxcbiAgICBcImRwaVwiOiA0MzkuNCxcbiAgICBcImJ3XCI6IDQsXG4gICAgXCJhY1wiOiAxMDAwXG4gIH0sXG5cbiAge1xuICAgIFwidHlwZVwiOiBcImFuZHJvaWRcIixcbiAgICBcInJ1bGVzXCI6IFtcbiAgICAgIHsgXCJtZG1oXCI6IFwic2Ftc3VuZy8qL1NNLUc5MDBGLypcIiB9LFxuICAgICAgeyBcInVhXCI6IFwiU00tRzkwMEZcIiB9XG4gICAgXSxcbiAgICBcImRwaVwiOiBbIDQxNS42LCA0MzEuNiBdLFxuICAgIFwiYndcIjogNSxcbiAgICBcImFjXCI6IDEwMDBcbiAgfSxcblxuICB7XG4gICAgXCJ0eXBlXCI6IFwiYW5kcm9pZFwiLFxuICAgIFwicnVsZXNcIjogW1xuICAgICAgeyBcIm1kbWhcIjogXCJzYW1zdW5nLyovU00tRzkwME0vKlwiIH0sXG4gICAgICB7IFwidWFcIjogXCJTTS1HOTAwTVwiIH1cbiAgICBdLFxuICAgIFwiZHBpXCI6IFsgNDE1LjYsIDQzMS42IF0sXG4gICAgXCJid1wiOiA1LFxuICAgIFwiYWNcIjogMTAwMFxuICB9LFxuXG4gIHtcbiAgICBcInR5cGVcIjogXCJhbmRyb2lkXCIsXG4gICAgXCJydWxlc1wiOiBbXG4gICAgICB7IFwibWRtaFwiOiBcInNhbXN1bmcvKi9TTS1HODAwRi8qXCIgfSxcbiAgICAgIHsgXCJ1YVwiOiBcIlNNLUc4MDBGXCIgfVxuICAgIF0sXG4gICAgXCJkcGlcIjogMzI2LjgsXG4gICAgXCJid1wiOiAzLFxuICAgIFwiYWNcIjogMTAwMFxuICB9LFxuXG4gIHtcbiAgICBcInR5cGVcIjogXCJhbmRyb2lkXCIsXG4gICAgXCJydWxlc1wiOiBbXG4gICAgICB7IFwibWRtaFwiOiBcInNhbXN1bmcvKi9TTS1HOTA2Uy8qXCIgfSxcbiAgICAgIHsgXCJ1YVwiOiBcIlNNLUc5MDZTXCIgfVxuICAgIF0sXG4gICAgXCJkcGlcIjogWyA1NjIuNywgNTcyLjQgXSxcbiAgICBcImJ3XCI6IDMsXG4gICAgXCJhY1wiOiAxMDAwXG4gIH0sXG5cbiAge1xuICAgIFwidHlwZVwiOiBcImFuZHJvaWRcIixcbiAgICBcInJ1bGVzXCI6IFtcbiAgICAgIHsgXCJtZG1oXCI6IFwic2Ftc3VuZy8qL0dULUk5MzAwLypcIiB9LFxuICAgICAgeyBcInVhXCI6IFwiR1QtSTkzMDBcIiB9XG4gICAgXSxcbiAgICBcImRwaVwiOiBbIDMwNi43LCAzMDQuOCBdLFxuICAgIFwiYndcIjogNSxcbiAgICBcImFjXCI6IDEwMDBcbiAgfSxcblxuICB7XG4gICAgXCJ0eXBlXCI6IFwiYW5kcm9pZFwiLFxuICAgIFwicnVsZXNcIjogW1xuICAgICAgeyBcIm1kbWhcIjogXCJzYW1zdW5nLyovU00tVDUzNS8qXCIgfSxcbiAgICAgIHsgXCJ1YVwiOiBcIlNNLVQ1MzVcIiB9XG4gICAgXSxcbiAgICBcImRwaVwiOiBbIDE0Mi42LCAxMzYuNCBdLFxuICAgIFwiYndcIjogMyxcbiAgICBcImFjXCI6IDUwMFxuICB9LFxuXG4gIHtcbiAgICBcInR5cGVcIjogXCJhbmRyb2lkXCIsXG4gICAgXCJydWxlc1wiOiBbXG4gICAgICB7IFwibWRtaFwiOiBcInNhbXN1bmcvKi9TTS1OOTIwQy8qXCIgfSxcbiAgICAgIHsgXCJ1YVwiOiBcIlNNLU45MjBDXCIgfVxuICAgIF0sXG4gICAgXCJkcGlcIjogWyA1MTUuMSwgNTE4LjQgXSxcbiAgICBcImJ3XCI6IDMsXG4gICAgXCJhY1wiOiAxMDAwXG4gIH0sXG5cbiAge1xuICAgIFwidHlwZVwiOiBcImFuZHJvaWRcIixcbiAgICBcInJ1bGVzXCI6IFtcbiAgICAgIHsgXCJtZG1oXCI6IFwic2Ftc3VuZy8qL0dULUk5MzAwSS8qXCIgfSxcbiAgICAgIHsgXCJ1YVwiOiBcIkdULUk5MzAwSVwiIH1cbiAgICBdLFxuICAgIFwiZHBpXCI6IFsgMzA0LjgsIDMwNS44IF0sXG4gICAgXCJid1wiOiAzLFxuICAgIFwiYWNcIjogMTAwMFxuICB9LFxuXG4gIHtcbiAgICBcInR5cGVcIjogXCJhbmRyb2lkXCIsXG4gICAgXCJydWxlc1wiOiBbXG4gICAgICB7IFwibWRtaFwiOiBcInNhbXN1bmcvKi9HVC1JOTE5NS8qXCIgfSxcbiAgICAgIHsgXCJ1YVwiOiBcIkdULUk5MTk1XCIgfVxuICAgIF0sXG4gICAgXCJkcGlcIjogWyAyNDkuNCwgMjU2LjcgXSxcbiAgICBcImJ3XCI6IDMsXG4gICAgXCJhY1wiOiA1MDBcbiAgfSxcblxuICB7XG4gICAgXCJ0eXBlXCI6IFwiYW5kcm9pZFwiLFxuICAgIFwicnVsZXNcIjogW1xuICAgICAgeyBcIm1kbWhcIjogXCJzYW1zdW5nLyovU1BILUw1MjAvKlwiIH0sXG4gICAgICB7IFwidWFcIjogXCJTUEgtTDUyMFwiIH1cbiAgICBdLFxuICAgIFwiZHBpXCI6IFsgMjQ5LjQsIDI1NS45IF0sXG4gICAgXCJid1wiOiAzLFxuICAgIFwiYWNcIjogMTAwMFxuICB9LFxuXG4gIHtcbiAgICBcInR5cGVcIjogXCJhbmRyb2lkXCIsXG4gICAgXCJydWxlc1wiOiBbXG4gICAgICB7IFwibWRtaFwiOiBcInNhbXN1bmcvKi9TQU1TVU5HLVNHSC1JNzE3LypcIiB9LFxuICAgICAgeyBcInVhXCI6IFwiU0FNU1VORy1TR0gtSTcxN1wiIH1cbiAgICBdLFxuICAgIFwiZHBpXCI6IDI4NS44LFxuICAgIFwiYndcIjogMyxcbiAgICBcImFjXCI6IDEwMDBcbiAgfSxcblxuICB7XG4gICAgXCJ0eXBlXCI6IFwiYW5kcm9pZFwiLFxuICAgIFwicnVsZXNcIjogW1xuICAgICAgeyBcIm1kbWhcIjogXCJzYW1zdW5nLyovU1BILUQ3MTAvKlwiIH0sXG4gICAgICB7IFwidWFcIjogXCJTUEgtRDcxMFwiIH1cbiAgICBdLFxuICAgIFwiZHBpXCI6IFsgMjE3LjcsIDIwNC4yIF0sXG4gICAgXCJid1wiOiAzLFxuICAgIFwiYWNcIjogMTAwMFxuICB9LFxuXG4gIHtcbiAgICBcInR5cGVcIjogXCJhbmRyb2lkXCIsXG4gICAgXCJydWxlc1wiOiBbXG4gICAgICB7IFwibWRtaFwiOiBcInNhbXN1bmcvKi9HVC1ONzEwMC8qXCIgfSxcbiAgICAgIHsgXCJ1YVwiOiBcIkdULU43MTAwXCIgfVxuICAgIF0sXG4gICAgXCJkcGlcIjogMjY1LjEsXG4gICAgXCJid1wiOiAzLFxuICAgIFwiYWNcIjogMTAwMFxuICB9LFxuXG4gIHtcbiAgICBcInR5cGVcIjogXCJhbmRyb2lkXCIsXG4gICAgXCJydWxlc1wiOiBbXG4gICAgICB7IFwibWRtaFwiOiBcInNhbXN1bmcvKi9TQ0gtSTYwNS8qXCIgfSxcbiAgICAgIHsgXCJ1YVwiOiBcIlNDSC1JNjA1XCIgfVxuICAgIF0sXG4gICAgXCJkcGlcIjogMjY1LjEsXG4gICAgXCJid1wiOiAzLFxuICAgIFwiYWNcIjogMTAwMFxuICB9LFxuXG4gIHtcbiAgICBcInR5cGVcIjogXCJhbmRyb2lkXCIsXG4gICAgXCJydWxlc1wiOiBbXG4gICAgICB7IFwibWRtaFwiOiBcInNhbXN1bmcvKi9HYWxheHkgTmV4dXMvKlwiIH0sXG4gICAgICB7IFwidWFcIjogXCJHYWxheHkgTmV4dXNcIiB9XG4gICAgXSxcbiAgICBcImRwaVwiOiBbIDMxNS4zLCAzMTQuMiBdLFxuICAgIFwiYndcIjogMyxcbiAgICBcImFjXCI6IDEwMDBcbiAgfSxcblxuICB7XG4gICAgXCJ0eXBlXCI6IFwiYW5kcm9pZFwiLFxuICAgIFwicnVsZXNcIjogW1xuICAgICAgeyBcIm1kbWhcIjogXCJzYW1zdW5nLyovU00tTjkxMEgvKlwiIH0sXG4gICAgICB7IFwidWFcIjogXCJTTS1OOTEwSFwiIH1cbiAgICBdLFxuICAgIFwiZHBpXCI6IFsgNTE1LjEsIDUxOC4wIF0sXG4gICAgXCJid1wiOiAzLFxuICAgIFwiYWNcIjogMTAwMFxuICB9LFxuXG4gIHtcbiAgICBcInR5cGVcIjogXCJhbmRyb2lkXCIsXG4gICAgXCJydWxlc1wiOiBbXG4gICAgICB7IFwibWRtaFwiOiBcInNhbXN1bmcvKi9TTS1OOTEwQy8qXCIgfSxcbiAgICAgIHsgXCJ1YVwiOiBcIlNNLU45MTBDXCIgfVxuICAgIF0sXG4gICAgXCJkcGlcIjogWyA1MTUuMiwgNTIwLjIgXSxcbiAgICBcImJ3XCI6IDMsXG4gICAgXCJhY1wiOiA1MDBcbiAgfSxcblxuICB7XG4gICAgXCJ0eXBlXCI6IFwiYW5kcm9pZFwiLFxuICAgIFwicnVsZXNcIjogW1xuICAgICAgeyBcIm1kbWhcIjogXCJzYW1zdW5nLyovU00tRzEzME0vKlwiIH0sXG4gICAgICB7IFwidWFcIjogXCJTTS1HMTMwTVwiIH1cbiAgICBdLFxuICAgIFwiZHBpXCI6IFsgMTY1LjksIDE2NC44IF0sXG4gICAgXCJid1wiOiAzLFxuICAgIFwiYWNcIjogNTAwXG4gIH0sXG5cbiAge1xuICAgIFwidHlwZVwiOiBcImFuZHJvaWRcIixcbiAgICBcInJ1bGVzXCI6IFtcbiAgICAgIHsgXCJtZG1oXCI6IFwic2Ftc3VuZy8qL1NNLUc5MjhJLypcIiB9LFxuICAgICAgeyBcInVhXCI6IFwiU00tRzkyOElcIiB9XG4gICAgXSxcbiAgICBcImRwaVwiOiBbIDUxNS4xLCA1MTguNCBdLFxuICAgIFwiYndcIjogMyxcbiAgICBcImFjXCI6IDEwMDBcbiAgfSxcblxuICB7XG4gICAgXCJ0eXBlXCI6IFwiYW5kcm9pZFwiLFxuICAgIFwicnVsZXNcIjogW1xuICAgICAgeyBcIm1kbWhcIjogXCJzYW1zdW5nLyovU00tRzkyMEYvKlwiIH0sXG4gICAgICB7IFwidWFcIjogXCJTTS1HOTIwRlwiIH1cbiAgICBdLFxuICAgIFwiZHBpXCI6IDU4MC42LFxuICAgIFwiYndcIjogMyxcbiAgICBcImFjXCI6IDUwMFxuICB9LFxuXG4gIHtcbiAgICBcInR5cGVcIjogXCJhbmRyb2lkXCIsXG4gICAgXCJydWxlc1wiOiBbXG4gICAgICB7IFwibWRtaFwiOiBcInNhbXN1bmcvKi9TTS1HOTIwUC8qXCIgfSxcbiAgICAgIHsgXCJ1YVwiOiBcIlNNLUc5MjBQXCIgfVxuICAgIF0sXG4gICAgXCJkcGlcIjogWyA1MjIuNSwgNTc3LjAgXSxcbiAgICBcImJ3XCI6IDMsXG4gICAgXCJhY1wiOiAxMDAwXG4gIH0sXG5cbiAge1xuICAgIFwidHlwZVwiOiBcImFuZHJvaWRcIixcbiAgICBcInJ1bGVzXCI6IFtcbiAgICAgIHsgXCJtZG1oXCI6IFwic2Ftc3VuZy8qL1NNLUc5MjVGLypcIiB9LFxuICAgICAgeyBcInVhXCI6IFwiU00tRzkyNUZcIiB9XG4gICAgXSxcbiAgICBcImRwaVwiOiA1ODAuNixcbiAgICBcImJ3XCI6IDMsXG4gICAgXCJhY1wiOiA1MDBcbiAgfSxcblxuICB7XG4gICAgXCJ0eXBlXCI6IFwiYW5kcm9pZFwiLFxuICAgIFwicnVsZXNcIjogW1xuICAgICAgeyBcIm1kbWhcIjogXCJzYW1zdW5nLyovU00tRzkyNVYvKlwiIH0sXG4gICAgICB7IFwidWFcIjogXCJTTS1HOTI1VlwiIH1cbiAgICBdLFxuICAgIFwiZHBpXCI6IFsgNTIyLjUsIDU3Ni42IF0sXG4gICAgXCJid1wiOiAzLFxuICAgIFwiYWNcIjogMTAwMFxuICB9LFxuXG4gIHtcbiAgICBcInR5cGVcIjogXCJhbmRyb2lkXCIsXG4gICAgXCJydWxlc1wiOiBbXG4gICAgICB7IFwibWRtaFwiOiBcIlNvbnkvKi9DNjkwMy8qXCIgfSxcbiAgICAgIHsgXCJ1YVwiOiBcIkM2OTAzXCIgfVxuICAgIF0sXG4gICAgXCJkcGlcIjogWyA0NDIuNSwgNDQzLjMgXSxcbiAgICBcImJ3XCI6IDMsXG4gICAgXCJhY1wiOiA1MDBcbiAgfSxcblxuICB7XG4gICAgXCJ0eXBlXCI6IFwiYW5kcm9pZFwiLFxuICAgIFwicnVsZXNcIjogW1xuICAgICAgeyBcIm1kbWhcIjogXCJTb255LyovRDY2NTMvKlwiIH0sXG4gICAgICB7IFwidWFcIjogXCJENjY1M1wiIH1cbiAgICBdLFxuICAgIFwiZHBpXCI6IFsgNDI4LjYsIDQyNy42IF0sXG4gICAgXCJid1wiOiAzLFxuICAgIFwiYWNcIjogMTAwMFxuICB9LFxuXG4gIHtcbiAgICBcInR5cGVcIjogXCJhbmRyb2lkXCIsXG4gICAgXCJydWxlc1wiOiBbXG4gICAgICB7IFwibWRtaFwiOiBcIlNvbnkvKi9FNjY1My8qXCIgfSxcbiAgICAgIHsgXCJ1YVwiOiBcIkU2NjUzXCIgfVxuICAgIF0sXG4gICAgXCJkcGlcIjogWyA0MjguNiwgNDI1LjcgXSxcbiAgICBcImJ3XCI6IDMsXG4gICAgXCJhY1wiOiAxMDAwXG4gIH0sXG5cbiAge1xuICAgIFwidHlwZVwiOiBcImFuZHJvaWRcIixcbiAgICBcInJ1bGVzXCI6IFtcbiAgICAgIHsgXCJtZG1oXCI6IFwiU29ueS8qL0U2ODUzLypcIiB9LFxuICAgICAgeyBcInVhXCI6IFwiRTY4NTNcIiB9XG4gICAgXSxcbiAgICBcImRwaVwiOiBbIDQwMy40LCA0MDEuOSBdLFxuICAgIFwiYndcIjogMyxcbiAgICBcImFjXCI6IDEwMDBcbiAgfSxcblxuICB7XG4gICAgXCJ0eXBlXCI6IFwiYW5kcm9pZFwiLFxuICAgIFwicnVsZXNcIjogW1xuICAgICAgeyBcIm1kbWhcIjogXCJTb255LyovU0dQMzIxLypcIiB9LFxuICAgICAgeyBcInVhXCI6IFwiU0dQMzIxXCIgfVxuICAgIF0sXG4gICAgXCJkcGlcIjogWyAyMjQuNywgMjI0LjEgXSxcbiAgICBcImJ3XCI6IDMsXG4gICAgXCJhY1wiOiA1MDBcbiAgfSxcblxuICB7XG4gICAgXCJ0eXBlXCI6IFwiYW5kcm9pZFwiLFxuICAgIFwicnVsZXNcIjogW1xuICAgICAgeyBcIm1kbWhcIjogXCJUQ1QvKi9BTENBVEVMIE9ORSBUT1VDSCBGaWVyY2UvKlwiIH0sXG4gICAgICB7IFwidWFcIjogXCJBTENBVEVMIE9ORSBUT1VDSCBGaWVyY2VcIiB9XG4gICAgXSxcbiAgICBcImRwaVwiOiBbIDI0MC4wLCAyNDcuNSBdLFxuICAgIFwiYndcIjogMyxcbiAgICBcImFjXCI6IDEwMDBcbiAgfSxcblxuICB7XG4gICAgXCJ0eXBlXCI6IFwiYW5kcm9pZFwiLFxuICAgIFwicnVsZXNcIjogW1xuICAgICAgeyBcIm1kbWhcIjogXCJUSEwvKi90aGwgNTAwMC8qXCIgfSxcbiAgICAgIHsgXCJ1YVwiOiBcInRobCA1MDAwXCIgfVxuICAgIF0sXG4gICAgXCJkcGlcIjogWyA0ODAuMCwgNDQzLjMgXSxcbiAgICBcImJ3XCI6IDMsXG4gICAgXCJhY1wiOiAxMDAwXG4gIH0sXG5cbiAge1xuICAgIFwidHlwZVwiOiBcImFuZHJvaWRcIixcbiAgICBcInJ1bGVzXCI6IFtcbiAgICAgIHsgXCJtZG1oXCI6IFwiWlRFLyovWlRFIEJsYWRlIEwyLypcIiB9LFxuICAgICAgeyBcInVhXCI6IFwiWlRFIEJsYWRlIEwyXCIgfVxuICAgIF0sXG4gICAgXCJkcGlcIjogMjQwLjAsXG4gICAgXCJid1wiOiAzLFxuICAgIFwiYWNcIjogNTAwXG4gIH0sXG5cbiAge1xuICAgIFwidHlwZVwiOiBcImlvc1wiLFxuICAgIFwicnVsZXNcIjogWyB7IFwicmVzXCI6IFsgNjQwLCA5NjAgXSB9IF0sXG4gICAgXCJkcGlcIjogWyAzMjUuMSwgMzI4LjQgXSxcbiAgICBcImJ3XCI6IDQsXG4gICAgXCJhY1wiOiAxMDAwXG4gIH0sXG5cbiAge1xuICAgIFwidHlwZVwiOiBcImlvc1wiLFxuICAgIFwicnVsZXNcIjogWyB7IFwicmVzXCI6IFsgNjQwLCA5NjAgXSB9IF0sXG4gICAgXCJkcGlcIjogWyAzMjUuMSwgMzI4LjQgXSxcbiAgICBcImJ3XCI6IDQsXG4gICAgXCJhY1wiOiAxMDAwXG4gIH0sXG5cbiAge1xuICAgIFwidHlwZVwiOiBcImlvc1wiLFxuICAgIFwicnVsZXNcIjogWyB7IFwicmVzXCI6IFsgNjQwLCAxMTM2IF0gfSBdLFxuICAgIFwiZHBpXCI6IFsgMzE3LjEsIDMyMC4yIF0sXG4gICAgXCJid1wiOiAzLFxuICAgIFwiYWNcIjogMTAwMFxuICB9LFxuXG4gIHtcbiAgICBcInR5cGVcIjogXCJpb3NcIixcbiAgICBcInJ1bGVzXCI6IFsgeyBcInJlc1wiOiBbIDY0MCwgMTEzNiBdIH0gXSxcbiAgICBcImRwaVwiOiBbIDMxNy4xLCAzMjAuMiBdLFxuICAgIFwiYndcIjogMyxcbiAgICBcImFjXCI6IDEwMDBcbiAgfSxcblxuICB7XG4gICAgXCJ0eXBlXCI6IFwiaW9zXCIsXG4gICAgXCJydWxlc1wiOiBbIHsgXCJyZXNcIjogWyA3NTAsIDEzMzQgXSB9IF0sXG4gICAgXCJkcGlcIjogMzI2LjQsXG4gICAgXCJid1wiOiA0LFxuICAgIFwiYWNcIjogMTAwMFxuICB9LFxuXG4gIHtcbiAgICBcInR5cGVcIjogXCJpb3NcIixcbiAgICBcInJ1bGVzXCI6IFsgeyBcInJlc1wiOiBbIDc1MCwgMTMzNCBdIH0gXSxcbiAgICBcImRwaVwiOiAzMjYuNCxcbiAgICBcImJ3XCI6IDQsXG4gICAgXCJhY1wiOiAxMDAwXG4gIH0sXG5cbiAge1xuICAgIFwidHlwZVwiOiBcImlvc1wiLFxuICAgIFwicnVsZXNcIjogWyB7IFwicmVzXCI6IFsgMTI0MiwgMjIwOCBdIH0gXSxcbiAgICBcImRwaVwiOiBbIDQ1My42LCA0NTguNCBdLFxuICAgIFwiYndcIjogNCxcbiAgICBcImFjXCI6IDEwMDBcbiAgfSxcblxuICB7XG4gICAgXCJ0eXBlXCI6IFwiaW9zXCIsXG4gICAgXCJydWxlc1wiOiBbIHsgXCJyZXNcIjogWyAxMjQyLCAyMjA4IF0gfSBdLFxuICAgIFwiZHBpXCI6IFsgNDUzLjYsIDQ1OC40IF0sXG4gICAgXCJid1wiOiA0LFxuICAgIFwiYWNcIjogMTAwMFxuICB9XG5dfTtcblxubW9kdWxlLmV4cG9ydHMgPSBEUERCX0NBQ0hFO1xuXG59LHt9XSwxMjpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4vKlxuICogQ29weXJpZ2h0IDIwMTUgR29vZ2xlIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG4vLyBPZmZsaW5lIGNhY2hlIG9mIHRoZSBEUERCLCB0byBiZSB1c2VkIHVudGlsIHdlIGxvYWQgdGhlIG9ubGluZSBvbmUgKGFuZFxuLy8gYXMgYSBmYWxsYmFjayBpbiBjYXNlIHdlIGNhbid0IGxvYWQgdGhlIG9ubGluZSBvbmUpLlxudmFyIERQREJfQ0FDSEUgPSBfZGVyZXFfKCcuL2RwZGItY2FjaGUuanMnKTtcbnZhciBVdGlsID0gX2RlcmVxXygnLi4vdXRpbC5qcycpO1xuXG4vLyBPbmxpbmUgRFBEQiBVUkwuXG52YXIgT05MSU5FX0RQREJfVVJMID0gJ2h0dHBzOi8vc3RvcmFnZS5nb29nbGVhcGlzLmNvbS9jYXJkYm9hcmQtZHBkYi9kcGRiLmpzb24nO1xuXG4vKipcbiAqIENhbGN1bGF0ZXMgZGV2aWNlIHBhcmFtZXRlcnMgYmFzZWQgb24gdGhlIERQREIgKERldmljZSBQYXJhbWV0ZXIgRGF0YWJhc2UpLlxuICogSW5pdGlhbGx5LCB1c2VzIHRoZSBjYWNoZWQgRFBEQiB2YWx1ZXMuXG4gKlxuICogSWYgZmV0Y2hPbmxpbmUgPT0gdHJ1ZSwgdGhlbiB0aGlzIG9iamVjdCB0cmllcyB0byBmZXRjaCB0aGUgb25saW5lIHZlcnNpb25cbiAqIG9mIHRoZSBEUERCIGFuZCB1cGRhdGVzIHRoZSBkZXZpY2UgaW5mbyBpZiBhIGJldHRlciBtYXRjaCBpcyBmb3VuZC5cbiAqIENhbGxzIHRoZSBvbkRldmljZVBhcmFtc1VwZGF0ZWQgY2FsbGJhY2sgd2hlbiB0aGVyZSBpcyBhbiB1cGRhdGUgdG8gdGhlXG4gKiBkZXZpY2UgaW5mb3JtYXRpb24uXG4gKi9cbmZ1bmN0aW9uIERwZGIoZmV0Y2hPbmxpbmUsIG9uRGV2aWNlUGFyYW1zVXBkYXRlZCkge1xuICAvLyBTdGFydCB3aXRoIHRoZSBvZmZsaW5lIERQREIgY2FjaGUgd2hpbGUgd2UgYXJlIGxvYWRpbmcgdGhlIHJlYWwgb25lLlxuICB0aGlzLmRwZGIgPSBEUERCX0NBQ0hFO1xuXG4gIC8vIENhbGN1bGF0ZSBkZXZpY2UgcGFyYW1zIGJhc2VkIG9uIHRoZSBvZmZsaW5lIHZlcnNpb24gb2YgdGhlIERQREIuXG4gIHRoaXMucmVjYWxjdWxhdGVEZXZpY2VQYXJhbXNfKCk7XG5cbiAgLy8gWEhSIHRvIGZldGNoIG9ubGluZSBEUERCIGZpbGUsIGlmIHJlcXVlc3RlZC5cbiAgaWYgKGZldGNoT25saW5lKSB7XG4gICAgLy8gU2V0IHRoZSBjYWxsYmFjay5cbiAgICB0aGlzLm9uRGV2aWNlUGFyYW1zVXBkYXRlZCA9IG9uRGV2aWNlUGFyYW1zVXBkYXRlZDtcblxuICAgIHZhciB4aHIgPSBuZXcgWE1MSHR0cFJlcXVlc3QoKTtcbiAgICB2YXIgb2JqID0gdGhpcztcbiAgICB4aHIub3BlbignR0VUJywgT05MSU5FX0RQREJfVVJMLCB0cnVlKTtcbiAgICB4aHIuYWRkRXZlbnRMaXN0ZW5lcignbG9hZCcsIGZ1bmN0aW9uKCkge1xuICAgICAgb2JqLmxvYWRpbmcgPSBmYWxzZTtcbiAgICAgIGlmICh4aHIuc3RhdHVzID49IDIwMCAmJiB4aHIuc3RhdHVzIDw9IDI5OSkge1xuICAgICAgICAvLyBTdWNjZXNzLlxuICAgICAgICBvYmouZHBkYiA9IEpTT04ucGFyc2UoeGhyLnJlc3BvbnNlKTtcbiAgICAgICAgb2JqLnJlY2FsY3VsYXRlRGV2aWNlUGFyYW1zXygpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gRXJyb3IgbG9hZGluZyB0aGUgRFBEQi5cbiAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgbG9hZGluZyBvbmxpbmUgRFBEQiEnKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICB4aHIuc2VuZCgpO1xuICB9XG59XG5cbi8vIFJldHVybnMgdGhlIGN1cnJlbnQgZGV2aWNlIHBhcmFtZXRlcnMuXG5EcGRiLnByb3RvdHlwZS5nZXREZXZpY2VQYXJhbXMgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHRoaXMuZGV2aWNlUGFyYW1zO1xufTtcblxuLy8gUmVjYWxjdWxhdGVzIHRoaXMgZGV2aWNlJ3MgcGFyYW1ldGVycyBiYXNlZCBvbiB0aGUgRFBEQi5cbkRwZGIucHJvdG90eXBlLnJlY2FsY3VsYXRlRGV2aWNlUGFyYW1zXyA9IGZ1bmN0aW9uKCkge1xuICB2YXIgbmV3RGV2aWNlUGFyYW1zID0gdGhpcy5jYWxjRGV2aWNlUGFyYW1zXygpO1xuICBpZiAobmV3RGV2aWNlUGFyYW1zKSB7XG4gICAgdGhpcy5kZXZpY2VQYXJhbXMgPSBuZXdEZXZpY2VQYXJhbXM7XG4gICAgLy8gSW52b2tlIGNhbGxiYWNrLCBpZiBpdCBpcyBzZXQuXG4gICAgaWYgKHRoaXMub25EZXZpY2VQYXJhbXNVcGRhdGVkKSB7XG4gICAgICB0aGlzLm9uRGV2aWNlUGFyYW1zVXBkYXRlZCh0aGlzLmRldmljZVBhcmFtcyk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGNvbnNvbGUuZXJyb3IoJ0ZhaWxlZCB0byByZWNhbGN1bGF0ZSBkZXZpY2UgcGFyYW1ldGVycy4nKTtcbiAgfVxufTtcblxuLy8gUmV0dXJucyBhIERldmljZVBhcmFtcyBvYmplY3QgdGhhdCByZXByZXNlbnRzIHRoZSBiZXN0IGd1ZXNzIGFzIHRvIHRoaXNcbi8vIGRldmljZSdzIHBhcmFtZXRlcnMuIENhbiByZXR1cm4gbnVsbCBpZiB0aGUgZGV2aWNlIGRvZXMgbm90IG1hdGNoIGFueVxuLy8ga25vd24gZGV2aWNlcy5cbkRwZGIucHJvdG90eXBlLmNhbGNEZXZpY2VQYXJhbXNfID0gZnVuY3Rpb24oKSB7XG4gIHZhciBkYiA9IHRoaXMuZHBkYjsgLy8gc2hvcnRoYW5kXG4gIGlmICghZGIpIHtcbiAgICBjb25zb2xlLmVycm9yKCdEUERCIG5vdCBhdmFpbGFibGUuJyk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgaWYgKGRiLmZvcm1hdCAhPSAxKSB7XG4gICAgY29uc29sZS5lcnJvcignRFBEQiBoYXMgdW5leHBlY3RlZCBmb3JtYXQgdmVyc2lvbi4nKTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICBpZiAoIWRiLmRldmljZXMgfHwgIWRiLmRldmljZXMubGVuZ3RoKSB7XG4gICAgY29uc29sZS5lcnJvcignRFBEQiBkb2VzIG5vdCBoYXZlIGEgZGV2aWNlcyBzZWN0aW9uLicpO1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLy8gR2V0IHRoZSBhY3R1YWwgdXNlciBhZ2VudCBhbmQgc2NyZWVuIGRpbWVuc2lvbnMgaW4gcGl4ZWxzLlxuICB2YXIgdXNlckFnZW50ID0gbmF2aWdhdG9yLnVzZXJBZ2VudCB8fCBuYXZpZ2F0b3IudmVuZG9yIHx8IHdpbmRvdy5vcGVyYTtcbiAgdmFyIHdpZHRoID0gVXRpbC5nZXRTY3JlZW5XaWR0aCgpO1xuICB2YXIgaGVpZ2h0ID0gVXRpbC5nZXRTY3JlZW5IZWlnaHQoKTtcblxuICBpZiAoIWRiLmRldmljZXMpIHtcbiAgICBjb25zb2xlLmVycm9yKCdEUERCIGhhcyBubyBkZXZpY2VzIHNlY3Rpb24uJyk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGRiLmRldmljZXMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgZGV2aWNlID0gZGIuZGV2aWNlc1tpXTtcbiAgICBpZiAoIWRldmljZS5ydWxlcykge1xuICAgICAgY29uc29sZS53YXJuKCdEZXZpY2VbJyArIGkgKyAnXSBoYXMgbm8gcnVsZXMgc2VjdGlvbi4nKTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGlmIChkZXZpY2UudHlwZSAhPSAnaW9zJyAmJiBkZXZpY2UudHlwZSAhPSAnYW5kcm9pZCcpIHtcbiAgICAgIGNvbnNvbGUud2FybignRGV2aWNlWycgKyBpICsgJ10gaGFzIGludmFsaWQgdHlwZS4nKTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIC8vIFNlZSBpZiB0aGlzIGRldmljZSBpcyBvZiB0aGUgYXBwcm9wcmlhdGUgdHlwZS5cbiAgICBpZiAoVXRpbC5pc0lPUygpICE9IChkZXZpY2UudHlwZSA9PSAnaW9zJykpIGNvbnRpbnVlO1xuXG4gICAgLy8gU2VlIGlmIHRoaXMgZGV2aWNlIG1hdGNoZXMgYW55IG9mIHRoZSBydWxlczpcbiAgICB2YXIgbWF0Y2hlZCA9IGZhbHNlO1xuICAgIGZvciAodmFyIGogPSAwOyBqIDwgZGV2aWNlLnJ1bGVzLmxlbmd0aDsgaisrKSB7XG4gICAgICB2YXIgcnVsZSA9IGRldmljZS5ydWxlc1tqXTtcbiAgICAgIGlmICh0aGlzLm1hdGNoUnVsZV8ocnVsZSwgdXNlckFnZW50LCB3aWR0aCwgaGVpZ2h0KSkge1xuICAgICAgICBtYXRjaGVkID0gdHJ1ZTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICAgIGlmICghbWF0Y2hlZCkgY29udGludWU7XG5cbiAgICAvLyBkZXZpY2UuZHBpIG1pZ2h0IGJlIGFuIGFycmF5IG9mIFsgeGRwaSwgeWRwaV0gb3IganVzdCBhIHNjYWxhci5cbiAgICB2YXIgeGRwaSA9IGRldmljZS5kcGlbMF0gfHwgZGV2aWNlLmRwaTtcbiAgICB2YXIgeWRwaSA9IGRldmljZS5kcGlbMV0gfHwgZGV2aWNlLmRwaTtcblxuICAgIHJldHVybiBuZXcgRGV2aWNlUGFyYW1zKHsgeGRwaTogeGRwaSwgeWRwaTogeWRwaSwgYmV2ZWxNbTogZGV2aWNlLmJ3IH0pO1xuICB9XG5cbiAgY29uc29sZS53YXJuKCdObyBEUERCIGRldmljZSBtYXRjaC4nKTtcbiAgcmV0dXJuIG51bGw7XG59O1xuXG5EcGRiLnByb3RvdHlwZS5tYXRjaFJ1bGVfID0gZnVuY3Rpb24ocnVsZSwgdWEsIHNjcmVlbldpZHRoLCBzY3JlZW5IZWlnaHQpIHtcbiAgLy8gV2UgY2FuIG9ubHkgbWF0Y2ggJ3VhJyBhbmQgJ3JlcycgcnVsZXMsIG5vdCBvdGhlciB0eXBlcyBsaWtlICdtZG1oJ1xuICAvLyAod2hpY2ggYXJlIG1lYW50IGZvciBuYXRpdmUgcGxhdGZvcm1zKS5cbiAgaWYgKCFydWxlLnVhICYmICFydWxlLnJlcykgcmV0dXJuIGZhbHNlO1xuXG4gIC8vIElmIG91ciB1c2VyIGFnZW50IHN0cmluZyBkb2Vzbid0IGNvbnRhaW4gdGhlIGluZGljYXRlZCB1c2VyIGFnZW50IHN0cmluZyxcbiAgLy8gdGhlIG1hdGNoIGZhaWxzLlxuICBpZiAocnVsZS51YSAmJiB1YS5pbmRleE9mKHJ1bGUudWEpIDwgMCkgcmV0dXJuIGZhbHNlO1xuXG4gIC8vIElmIHRoZSBydWxlIHNwZWNpZmllcyBzY3JlZW4gZGltZW5zaW9ucyB0aGF0IGRvbid0IGNvcnJlc3BvbmQgdG8gb3VycyxcbiAgLy8gdGhlIG1hdGNoIGZhaWxzLlxuICBpZiAocnVsZS5yZXMpIHtcbiAgICBpZiAoIXJ1bGUucmVzWzBdIHx8ICFydWxlLnJlc1sxXSkgcmV0dXJuIGZhbHNlO1xuICAgIHZhciByZXNYID0gcnVsZS5yZXNbMF07XG4gICAgdmFyIHJlc1kgPSBydWxlLnJlc1sxXTtcbiAgICAvLyBDb21wYXJlIG1pbiBhbmQgbWF4IHNvIGFzIHRvIG1ha2UgdGhlIG9yZGVyIG5vdCBtYXR0ZXIsIGkuZS4sIGl0IHNob3VsZFxuICAgIC8vIGJlIHRydWUgdGhhdCA2NDB4NDgwID09IDQ4MHg2NDAuXG4gICAgaWYgKE1hdGgubWluKHNjcmVlbldpZHRoLCBzY3JlZW5IZWlnaHQpICE9IE1hdGgubWluKHJlc1gsIHJlc1kpIHx8XG4gICAgICAgIChNYXRoLm1heChzY3JlZW5XaWR0aCwgc2NyZWVuSGVpZ2h0KSAhPSBNYXRoLm1heChyZXNYLCByZXNZKSkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gRGV2aWNlUGFyYW1zKHBhcmFtcykge1xuICB0aGlzLnhkcGkgPSBwYXJhbXMueGRwaTtcbiAgdGhpcy55ZHBpID0gcGFyYW1zLnlkcGk7XG4gIHRoaXMuYmV2ZWxNbSA9IHBhcmFtcy5iZXZlbE1tO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IERwZGI7XG5cbn0se1wiLi4vdXRpbC5qc1wiOjIyLFwiLi9kcGRiLWNhY2hlLmpzXCI6MTF9XSwxMzpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4vKlxuICogQ29weXJpZ2h0IDIwMTUgR29vZ2xlIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xudmFyIFV0aWwgPSBfZGVyZXFfKCcuL3V0aWwuanMnKTtcbnZhciBXZWJWUlBvbHlmaWxsID0gX2RlcmVxXygnLi93ZWJ2ci1wb2x5ZmlsbC5qcycpLldlYlZSUG9seWZpbGw7XG5cbi8vIEluaXRpYWxpemUgYSBXZWJWUkNvbmZpZyBqdXN0IGluIGNhc2UuXG53aW5kb3cuV2ViVlJDb25maWcgPSBVdGlsLmV4dGVuZCh7XG4gIC8vIEZvcmNlcyBhdmFpbGFiaWxpdHkgb2YgVlIgbW9kZSwgZXZlbiBmb3Igbm9uLW1vYmlsZSBkZXZpY2VzLlxuICBGT1JDRV9FTkFCTEVfVlI6IGZhbHNlLFxuXG4gIC8vIENvbXBsZW1lbnRhcnkgZmlsdGVyIGNvZWZmaWNpZW50LiAwIGZvciBhY2NlbGVyb21ldGVyLCAxIGZvciBneXJvLlxuICBLX0ZJTFRFUjogMC45OCxcblxuICAvLyBIb3cgZmFyIGludG8gdGhlIGZ1dHVyZSB0byBwcmVkaWN0IGR1cmluZyBmYXN0IG1vdGlvbiAoaW4gc2Vjb25kcykuXG4gIFBSRURJQ1RJT05fVElNRV9TOiAwLjA0MCxcblxuICAvLyBGbGFnIHRvIGVuYWJsZSB0b3VjaCBwYW5uZXIuIEluIGNhc2UgeW91IGhhdmUgeW91ciBvd24gdG91Y2ggY29udHJvbHMuXG4gIFRPVUNIX1BBTk5FUl9ESVNBQkxFRDogdHJ1ZSxcblxuICAvLyBGbGFnIHRvIGRpc2FibGVkIHRoZSBVSSBpbiBWUiBNb2RlLlxuICBDQVJEQk9BUkRfVUlfRElTQUJMRUQ6IGZhbHNlLCAvLyBEZWZhdWx0OiBmYWxzZVxuXG4gIC8vIEZsYWcgdG8gZGlzYWJsZSB0aGUgaW5zdHJ1Y3Rpb25zIHRvIHJvdGF0ZSB5b3VyIGRldmljZS5cbiAgUk9UQVRFX0lOU1RSVUNUSU9OU19ESVNBQkxFRDogZmFsc2UsIC8vIERlZmF1bHQ6IGZhbHNlLlxuXG4gIC8vIEVuYWJsZSB5YXcgcGFubmluZyBvbmx5LCBkaXNhYmxpbmcgcm9sbCBhbmQgcGl0Y2guIFRoaXMgY2FuIGJlIHVzZWZ1bFxuICAvLyBmb3IgcGFub3JhbWFzIHdpdGggbm90aGluZyBpbnRlcmVzdGluZyBhYm92ZSBvciBiZWxvdy5cbiAgWUFXX09OTFk6IGZhbHNlLFxuXG4gIC8vIFRvIGRpc2FibGUga2V5Ym9hcmQgYW5kIG1vdXNlIGNvbnRyb2xzLCBpZiB5b3Ugd2FudCB0byB1c2UgeW91ciBvd25cbiAgLy8gaW1wbGVtZW50YXRpb24uXG4gIE1PVVNFX0tFWUJPQVJEX0NPTlRST0xTX0RJU0FCTEVEOiBmYWxzZSxcblxuICAvLyBQcmV2ZW50IHRoZSBwb2x5ZmlsbCBmcm9tIGluaXRpYWxpemluZyBpbW1lZGlhdGVseS4gUmVxdWlyZXMgdGhlIGFwcFxuICAvLyB0byBjYWxsIEluaXRpYWxpemVXZWJWUlBvbHlmaWxsKCkgYmVmb3JlIGl0IGNhbiBiZSB1c2VkLlxuICBERUZFUl9JTklUSUFMSVpBVElPTjogZmFsc2UsXG5cbiAgLy8gRW5hYmxlIHRoZSBkZXByZWNhdGVkIHZlcnNpb24gb2YgdGhlIEFQSSAobmF2aWdhdG9yLmdldFZSRGV2aWNlcykuXG4gIEVOQUJMRV9ERVBSRUNBVEVEX0FQSTogZmFsc2UsXG5cbiAgLy8gU2NhbGVzIHRoZSByZWNvbW1lbmRlZCBidWZmZXIgc2l6ZSByZXBvcnRlZCBieSBXZWJWUiwgd2hpY2ggY2FuIGltcHJvdmVcbiAgLy8gcGVyZm9ybWFuY2UuXG4gIC8vIFVQREFURSgyMDE2LTA1LTAzKTogU2V0dGluZyB0aGlzIHRvIDAuNSBieSBkZWZhdWx0IHNpbmNlIDEuMCBkb2VzIG5vdFxuICAvLyBwZXJmb3JtIHdlbGwgb24gbWFueSBtb2JpbGUgZGV2aWNlcy5cbiAgQlVGRkVSX1NDQUxFOiAwLjUsXG5cbiAgLy8gQWxsb3cgVlJEaXNwbGF5LnN1Ym1pdEZyYW1lIHRvIGNoYW5nZSBnbCBiaW5kaW5ncywgd2hpY2ggaXMgbW9yZVxuICAvLyBlZmZpY2llbnQgaWYgdGhlIGFwcGxpY2F0aW9uIGNvZGUgd2lsbCByZS1iaW5kIGl0cyByZXNvdXJjZXMgb24gdGhlXG4gIC8vIG5leHQgZnJhbWUgYW55d2F5LiBUaGlzIGhhcyBiZWVuIHNlZW4gdG8gY2F1c2UgcmVuZGVyaW5nIGdsaXRjaGVzIHdpdGhcbiAgLy8gVEhSRUUuanMuXG4gIC8vIERpcnR5IGJpbmRpbmdzIGluY2x1ZGU6IGdsLkZSQU1FQlVGRkVSX0JJTkRJTkcsIGdsLkNVUlJFTlRfUFJPR1JBTSxcbiAgLy8gZ2wuQVJSQVlfQlVGRkVSX0JJTkRJTkcsIGdsLkVMRU1FTlRfQVJSQVlfQlVGRkVSX0JJTkRJTkcsXG4gIC8vIGFuZCBnbC5URVhUVVJFX0JJTkRJTkdfMkQgZm9yIHRleHR1cmUgdW5pdCAwLlxuICBESVJUWV9TVUJNSVRfRlJBTUVfQklORElOR1M6IGZhbHNlLFxuXG4gIC8vIFdoZW4gc2V0IHRvIHRydWUsIHRoaXMgd2lsbCBjYXVzZSBhIHBvbHlmaWxsZWQgVlJEaXNwbGF5IHRvIGFsd2F5cyBiZVxuICAvLyBhcHBlbmRlZCB0byB0aGUgbGlzdCByZXR1cm5lZCBieSBuYXZpZ2F0b3IuZ2V0VlJEaXNwbGF5cygpLCBldmVuIGlmIHRoYXRcbiAgLy8gbGlzdCBpbmNsdWRlcyBhIG5hdGl2ZSBWUkRpc3BsYXkuXG4gIEFMV0FZU19BUFBFTkRfUE9MWUZJTExfRElTUExBWTogZmFsc2Vcbn0sIHdpbmRvdy5XZWJWUkNvbmZpZyk7XG5cbmlmICghd2luZG93LldlYlZSQ29uZmlnLkRFRkVSX0lOSVRJQUxJWkFUSU9OKSB7XG4gIG5ldyBXZWJWUlBvbHlmaWxsKCk7XG59IGVsc2Uge1xuICB3aW5kb3cuSW5pdGlhbGl6ZVdlYlZSUG9seWZpbGwgPSBmdW5jdGlvbigpIHtcbiAgICBuZXcgV2ViVlJQb2x5ZmlsbCgpO1xuICB9XG59XG5cbn0se1wiLi91dGlsLmpzXCI6MjIsXCIuL3dlYnZyLXBvbHlmaWxsLmpzXCI6MjV9XSwxNDpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4vKlxuICogQ29weXJpZ2h0IDIwMTYgR29vZ2xlIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG52YXIgTWF0aFV0aWwgPSB3aW5kb3cuTWF0aFV0aWwgfHwge307XG5cbk1hdGhVdGlsLmRlZ1RvUmFkID0gTWF0aC5QSSAvIDE4MDtcbk1hdGhVdGlsLnJhZFRvRGVnID0gMTgwIC8gTWF0aC5QSTtcblxuLy8gU29tZSBtaW5pbWFsIG1hdGggZnVuY3Rpb25hbGl0eSBib3Jyb3dlZCBmcm9tIFRIUkVFLk1hdGggYW5kIHN0cmlwcGVkIGRvd25cbi8vIGZvciB0aGUgcHVycG9zZXMgb2YgdGhpcyBsaWJyYXJ5LlxuXG5cbk1hdGhVdGlsLlZlY3RvcjIgPSBmdW5jdGlvbiAoIHgsIHkgKSB7XG4gIHRoaXMueCA9IHggfHwgMDtcbiAgdGhpcy55ID0geSB8fCAwO1xufTtcblxuTWF0aFV0aWwuVmVjdG9yMi5wcm90b3R5cGUgPSB7XG4gIGNvbnN0cnVjdG9yOiBNYXRoVXRpbC5WZWN0b3IyLFxuXG4gIHNldDogZnVuY3Rpb24gKCB4LCB5ICkge1xuICAgIHRoaXMueCA9IHg7XG4gICAgdGhpcy55ID0geTtcblxuICAgIHJldHVybiB0aGlzO1xuICB9LFxuXG4gIGNvcHk6IGZ1bmN0aW9uICggdiApIHtcbiAgICB0aGlzLnggPSB2Lng7XG4gICAgdGhpcy55ID0gdi55O1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH0sXG5cbiAgc3ViVmVjdG9yczogZnVuY3Rpb24gKCBhLCBiICkge1xuICAgIHRoaXMueCA9IGEueCAtIGIueDtcbiAgICB0aGlzLnkgPSBhLnkgLSBiLnk7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfSxcbn07XG5cbk1hdGhVdGlsLlZlY3RvcjMgPSBmdW5jdGlvbiAoIHgsIHksIHogKSB7XG4gIHRoaXMueCA9IHggfHwgMDtcbiAgdGhpcy55ID0geSB8fCAwO1xuICB0aGlzLnogPSB6IHx8IDA7XG59O1xuXG5NYXRoVXRpbC5WZWN0b3IzLnByb3RvdHlwZSA9IHtcbiAgY29uc3RydWN0b3I6IE1hdGhVdGlsLlZlY3RvcjMsXG5cbiAgc2V0OiBmdW5jdGlvbiAoIHgsIHksIHogKSB7XG4gICAgdGhpcy54ID0geDtcbiAgICB0aGlzLnkgPSB5O1xuICAgIHRoaXMueiA9IHo7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfSxcblxuICBjb3B5OiBmdW5jdGlvbiAoIHYgKSB7XG4gICAgdGhpcy54ID0gdi54O1xuICAgIHRoaXMueSA9IHYueTtcbiAgICB0aGlzLnogPSB2Lno7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfSxcblxuICBsZW5ndGg6IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gTWF0aC5zcXJ0KCB0aGlzLnggKiB0aGlzLnggKyB0aGlzLnkgKiB0aGlzLnkgKyB0aGlzLnogKiB0aGlzLnogKTtcbiAgfSxcblxuICBub3JtYWxpemU6IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgc2NhbGFyID0gdGhpcy5sZW5ndGgoKTtcblxuICAgIGlmICggc2NhbGFyICE9PSAwICkge1xuICAgICAgdmFyIGludlNjYWxhciA9IDEgLyBzY2FsYXI7XG5cbiAgICAgIHRoaXMubXVsdGlwbHlTY2FsYXIoaW52U2NhbGFyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy54ID0gMDtcbiAgICAgIHRoaXMueSA9IDA7XG4gICAgICB0aGlzLnogPSAwO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xuICB9LFxuXG4gIG11bHRpcGx5U2NhbGFyOiBmdW5jdGlvbiAoIHNjYWxhciApIHtcbiAgICB0aGlzLnggKj0gc2NhbGFyO1xuICAgIHRoaXMueSAqPSBzY2FsYXI7XG4gICAgdGhpcy56ICo9IHNjYWxhcjtcbiAgfSxcblxuICBhcHBseVF1YXRlcm5pb246IGZ1bmN0aW9uICggcSApIHtcbiAgICB2YXIgeCA9IHRoaXMueDtcbiAgICB2YXIgeSA9IHRoaXMueTtcbiAgICB2YXIgeiA9IHRoaXMuejtcblxuICAgIHZhciBxeCA9IHEueDtcbiAgICB2YXIgcXkgPSBxLnk7XG4gICAgdmFyIHF6ID0gcS56O1xuICAgIHZhciBxdyA9IHEudztcblxuICAgIC8vIGNhbGN1bGF0ZSBxdWF0ICogdmVjdG9yXG4gICAgdmFyIGl4ID0gIHF3ICogeCArIHF5ICogeiAtIHF6ICogeTtcbiAgICB2YXIgaXkgPSAgcXcgKiB5ICsgcXogKiB4IC0gcXggKiB6O1xuICAgIHZhciBpeiA9ICBxdyAqIHogKyBxeCAqIHkgLSBxeSAqIHg7XG4gICAgdmFyIGl3ID0gLSBxeCAqIHggLSBxeSAqIHkgLSBxeiAqIHo7XG5cbiAgICAvLyBjYWxjdWxhdGUgcmVzdWx0ICogaW52ZXJzZSBxdWF0XG4gICAgdGhpcy54ID0gaXggKiBxdyArIGl3ICogLSBxeCArIGl5ICogLSBxeiAtIGl6ICogLSBxeTtcbiAgICB0aGlzLnkgPSBpeSAqIHF3ICsgaXcgKiAtIHF5ICsgaXogKiAtIHF4IC0gaXggKiAtIHF6O1xuICAgIHRoaXMueiA9IGl6ICogcXcgKyBpdyAqIC0gcXogKyBpeCAqIC0gcXkgLSBpeSAqIC0gcXg7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfSxcblxuICBkb3Q6IGZ1bmN0aW9uICggdiApIHtcbiAgICByZXR1cm4gdGhpcy54ICogdi54ICsgdGhpcy55ICogdi55ICsgdGhpcy56ICogdi56O1xuICB9LFxuXG4gIGNyb3NzVmVjdG9yczogZnVuY3Rpb24gKCBhLCBiICkge1xuICAgIHZhciBheCA9IGEueCwgYXkgPSBhLnksIGF6ID0gYS56O1xuICAgIHZhciBieCA9IGIueCwgYnkgPSBiLnksIGJ6ID0gYi56O1xuXG4gICAgdGhpcy54ID0gYXkgKiBieiAtIGF6ICogYnk7XG4gICAgdGhpcy55ID0gYXogKiBieCAtIGF4ICogYno7XG4gICAgdGhpcy56ID0gYXggKiBieSAtIGF5ICogYng7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfSxcbn07XG5cbk1hdGhVdGlsLlF1YXRlcm5pb24gPSBmdW5jdGlvbiAoIHgsIHksIHosIHcgKSB7XG4gIHRoaXMueCA9IHggfHwgMDtcbiAgdGhpcy55ID0geSB8fCAwO1xuICB0aGlzLnogPSB6IHx8IDA7XG4gIHRoaXMudyA9ICggdyAhPT0gdW5kZWZpbmVkICkgPyB3IDogMTtcbn07XG5cbk1hdGhVdGlsLlF1YXRlcm5pb24ucHJvdG90eXBlID0ge1xuICBjb25zdHJ1Y3RvcjogTWF0aFV0aWwuUXVhdGVybmlvbixcblxuICBzZXQ6IGZ1bmN0aW9uICggeCwgeSwgeiwgdyApIHtcbiAgICB0aGlzLnggPSB4O1xuICAgIHRoaXMueSA9IHk7XG4gICAgdGhpcy56ID0gejtcbiAgICB0aGlzLncgPSB3O1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH0sXG5cbiAgY29weTogZnVuY3Rpb24gKCBxdWF0ZXJuaW9uICkge1xuICAgIHRoaXMueCA9IHF1YXRlcm5pb24ueDtcbiAgICB0aGlzLnkgPSBxdWF0ZXJuaW9uLnk7XG4gICAgdGhpcy56ID0gcXVhdGVybmlvbi56O1xuICAgIHRoaXMudyA9IHF1YXRlcm5pb24udztcblxuICAgIHJldHVybiB0aGlzO1xuICB9LFxuXG4gIHNldEZyb21FdWxlclhZWjogZnVuY3Rpb24oIHgsIHksIHogKSB7XG4gICAgdmFyIGMxID0gTWF0aC5jb3MoIHggLyAyICk7XG4gICAgdmFyIGMyID0gTWF0aC5jb3MoIHkgLyAyICk7XG4gICAgdmFyIGMzID0gTWF0aC5jb3MoIHogLyAyICk7XG4gICAgdmFyIHMxID0gTWF0aC5zaW4oIHggLyAyICk7XG4gICAgdmFyIHMyID0gTWF0aC5zaW4oIHkgLyAyICk7XG4gICAgdmFyIHMzID0gTWF0aC5zaW4oIHogLyAyICk7XG5cbiAgICB0aGlzLnggPSBzMSAqIGMyICogYzMgKyBjMSAqIHMyICogczM7XG4gICAgdGhpcy55ID0gYzEgKiBzMiAqIGMzIC0gczEgKiBjMiAqIHMzO1xuICAgIHRoaXMueiA9IGMxICogYzIgKiBzMyArIHMxICogczIgKiBjMztcbiAgICB0aGlzLncgPSBjMSAqIGMyICogYzMgLSBzMSAqIHMyICogczM7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfSxcblxuICBzZXRGcm9tRXVsZXJZWFo6IGZ1bmN0aW9uKCB4LCB5LCB6ICkge1xuICAgIHZhciBjMSA9IE1hdGguY29zKCB4IC8gMiApO1xuICAgIHZhciBjMiA9IE1hdGguY29zKCB5IC8gMiApO1xuICAgIHZhciBjMyA9IE1hdGguY29zKCB6IC8gMiApO1xuICAgIHZhciBzMSA9IE1hdGguc2luKCB4IC8gMiApO1xuICAgIHZhciBzMiA9IE1hdGguc2luKCB5IC8gMiApO1xuICAgIHZhciBzMyA9IE1hdGguc2luKCB6IC8gMiApO1xuXG4gICAgdGhpcy54ID0gczEgKiBjMiAqIGMzICsgYzEgKiBzMiAqIHMzO1xuICAgIHRoaXMueSA9IGMxICogczIgKiBjMyAtIHMxICogYzIgKiBzMztcbiAgICB0aGlzLnogPSBjMSAqIGMyICogczMgLSBzMSAqIHMyICogYzM7XG4gICAgdGhpcy53ID0gYzEgKiBjMiAqIGMzICsgczEgKiBzMiAqIHMzO1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH0sXG5cbiAgc2V0RnJvbUF4aXNBbmdsZTogZnVuY3Rpb24gKCBheGlzLCBhbmdsZSApIHtcbiAgICAvLyBodHRwOi8vd3d3LmV1Y2xpZGVhbnNwYWNlLmNvbS9tYXRocy9nZW9tZXRyeS9yb3RhdGlvbnMvY29udmVyc2lvbnMvYW5nbGVUb1F1YXRlcm5pb24vaW5kZXguaHRtXG4gICAgLy8gYXNzdW1lcyBheGlzIGlzIG5vcm1hbGl6ZWRcblxuICAgIHZhciBoYWxmQW5nbGUgPSBhbmdsZSAvIDIsIHMgPSBNYXRoLnNpbiggaGFsZkFuZ2xlICk7XG5cbiAgICB0aGlzLnggPSBheGlzLnggKiBzO1xuICAgIHRoaXMueSA9IGF4aXMueSAqIHM7XG4gICAgdGhpcy56ID0gYXhpcy56ICogcztcbiAgICB0aGlzLncgPSBNYXRoLmNvcyggaGFsZkFuZ2xlICk7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfSxcblxuICBtdWx0aXBseTogZnVuY3Rpb24gKCBxICkge1xuICAgIHJldHVybiB0aGlzLm11bHRpcGx5UXVhdGVybmlvbnMoIHRoaXMsIHEgKTtcbiAgfSxcblxuICBtdWx0aXBseVF1YXRlcm5pb25zOiBmdW5jdGlvbiAoIGEsIGIgKSB7XG4gICAgLy8gZnJvbSBodHRwOi8vd3d3LmV1Y2xpZGVhbnNwYWNlLmNvbS9tYXRocy9hbGdlYnJhL3JlYWxOb3JtZWRBbGdlYnJhL3F1YXRlcm5pb25zL2NvZGUvaW5kZXguaHRtXG5cbiAgICB2YXIgcWF4ID0gYS54LCBxYXkgPSBhLnksIHFheiA9IGEueiwgcWF3ID0gYS53O1xuICAgIHZhciBxYnggPSBiLngsIHFieSA9IGIueSwgcWJ6ID0gYi56LCBxYncgPSBiLnc7XG5cbiAgICB0aGlzLnggPSBxYXggKiBxYncgKyBxYXcgKiBxYnggKyBxYXkgKiBxYnogLSBxYXogKiBxYnk7XG4gICAgdGhpcy55ID0gcWF5ICogcWJ3ICsgcWF3ICogcWJ5ICsgcWF6ICogcWJ4IC0gcWF4ICogcWJ6O1xuICAgIHRoaXMueiA9IHFheiAqIHFidyArIHFhdyAqIHFieiArIHFheCAqIHFieSAtIHFheSAqIHFieDtcbiAgICB0aGlzLncgPSBxYXcgKiBxYncgLSBxYXggKiBxYnggLSBxYXkgKiBxYnkgLSBxYXogKiBxYno7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfSxcblxuICBpbnZlcnNlOiBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy54ICo9IC0xO1xuICAgIHRoaXMueSAqPSAtMTtcbiAgICB0aGlzLnogKj0gLTE7XG5cbiAgICB0aGlzLm5vcm1hbGl6ZSgpO1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH0sXG5cbiAgbm9ybWFsaXplOiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGwgPSBNYXRoLnNxcnQoIHRoaXMueCAqIHRoaXMueCArIHRoaXMueSAqIHRoaXMueSArIHRoaXMueiAqIHRoaXMueiArIHRoaXMudyAqIHRoaXMudyApO1xuXG4gICAgaWYgKCBsID09PSAwICkge1xuICAgICAgdGhpcy54ID0gMDtcbiAgICAgIHRoaXMueSA9IDA7XG4gICAgICB0aGlzLnogPSAwO1xuICAgICAgdGhpcy53ID0gMTtcbiAgICB9IGVsc2Uge1xuICAgICAgbCA9IDEgLyBsO1xuXG4gICAgICB0aGlzLnggPSB0aGlzLnggKiBsO1xuICAgICAgdGhpcy55ID0gdGhpcy55ICogbDtcbiAgICAgIHRoaXMueiA9IHRoaXMueiAqIGw7XG4gICAgICB0aGlzLncgPSB0aGlzLncgKiBsO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xuICB9LFxuXG4gIHNsZXJwOiBmdW5jdGlvbiAoIHFiLCB0ICkge1xuICAgIGlmICggdCA9PT0gMCApIHJldHVybiB0aGlzO1xuICAgIGlmICggdCA9PT0gMSApIHJldHVybiB0aGlzLmNvcHkoIHFiICk7XG5cbiAgICB2YXIgeCA9IHRoaXMueCwgeSA9IHRoaXMueSwgeiA9IHRoaXMueiwgdyA9IHRoaXMudztcblxuICAgIC8vIGh0dHA6Ly93d3cuZXVjbGlkZWFuc3BhY2UuY29tL21hdGhzL2FsZ2VicmEvcmVhbE5vcm1lZEFsZ2VicmEvcXVhdGVybmlvbnMvc2xlcnAvXG5cbiAgICB2YXIgY29zSGFsZlRoZXRhID0gdyAqIHFiLncgKyB4ICogcWIueCArIHkgKiBxYi55ICsgeiAqIHFiLno7XG5cbiAgICBpZiAoIGNvc0hhbGZUaGV0YSA8IDAgKSB7XG4gICAgICB0aGlzLncgPSAtIHFiLnc7XG4gICAgICB0aGlzLnggPSAtIHFiLng7XG4gICAgICB0aGlzLnkgPSAtIHFiLnk7XG4gICAgICB0aGlzLnogPSAtIHFiLno7XG5cbiAgICAgIGNvc0hhbGZUaGV0YSA9IC0gY29zSGFsZlRoZXRhO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmNvcHkoIHFiICk7XG4gICAgfVxuXG4gICAgaWYgKCBjb3NIYWxmVGhldGEgPj0gMS4wICkge1xuICAgICAgdGhpcy53ID0gdztcbiAgICAgIHRoaXMueCA9IHg7XG4gICAgICB0aGlzLnkgPSB5O1xuICAgICAgdGhpcy56ID0gejtcblxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgdmFyIGhhbGZUaGV0YSA9IE1hdGguYWNvcyggY29zSGFsZlRoZXRhICk7XG4gICAgdmFyIHNpbkhhbGZUaGV0YSA9IE1hdGguc3FydCggMS4wIC0gY29zSGFsZlRoZXRhICogY29zSGFsZlRoZXRhICk7XG5cbiAgICBpZiAoIE1hdGguYWJzKCBzaW5IYWxmVGhldGEgKSA8IDAuMDAxICkge1xuICAgICAgdGhpcy53ID0gMC41ICogKCB3ICsgdGhpcy53ICk7XG4gICAgICB0aGlzLnggPSAwLjUgKiAoIHggKyB0aGlzLnggKTtcbiAgICAgIHRoaXMueSA9IDAuNSAqICggeSArIHRoaXMueSApO1xuICAgICAgdGhpcy56ID0gMC41ICogKCB6ICsgdGhpcy56ICk7XG5cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIHZhciByYXRpb0EgPSBNYXRoLnNpbiggKCAxIC0gdCApICogaGFsZlRoZXRhICkgLyBzaW5IYWxmVGhldGEsXG4gICAgcmF0aW9CID0gTWF0aC5zaW4oIHQgKiBoYWxmVGhldGEgKSAvIHNpbkhhbGZUaGV0YTtcblxuICAgIHRoaXMudyA9ICggdyAqIHJhdGlvQSArIHRoaXMudyAqIHJhdGlvQiApO1xuICAgIHRoaXMueCA9ICggeCAqIHJhdGlvQSArIHRoaXMueCAqIHJhdGlvQiApO1xuICAgIHRoaXMueSA9ICggeSAqIHJhdGlvQSArIHRoaXMueSAqIHJhdGlvQiApO1xuICAgIHRoaXMueiA9ICggeiAqIHJhdGlvQSArIHRoaXMueiAqIHJhdGlvQiApO1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH0sXG5cbiAgc2V0RnJvbVVuaXRWZWN0b3JzOiBmdW5jdGlvbiAoKSB7XG4gICAgLy8gaHR0cDovL2xvbGVuZ2luZS5uZXQvYmxvZy8yMDE0LzAyLzI0L3F1YXRlcm5pb24tZnJvbS10d28tdmVjdG9ycy1maW5hbFxuICAgIC8vIGFzc3VtZXMgZGlyZWN0aW9uIHZlY3RvcnMgdkZyb20gYW5kIHZUbyBhcmUgbm9ybWFsaXplZFxuXG4gICAgdmFyIHYxLCByO1xuICAgIHZhciBFUFMgPSAwLjAwMDAwMTtcblxuICAgIHJldHVybiBmdW5jdGlvbiAoIHZGcm9tLCB2VG8gKSB7XG4gICAgICBpZiAoIHYxID09PSB1bmRlZmluZWQgKSB2MSA9IG5ldyBNYXRoVXRpbC5WZWN0b3IzKCk7XG5cbiAgICAgIHIgPSB2RnJvbS5kb3QoIHZUbyApICsgMTtcblxuICAgICAgaWYgKCByIDwgRVBTICkge1xuICAgICAgICByID0gMDtcblxuICAgICAgICBpZiAoIE1hdGguYWJzKCB2RnJvbS54ICkgPiBNYXRoLmFicyggdkZyb20ueiApICkge1xuICAgICAgICAgIHYxLnNldCggLSB2RnJvbS55LCB2RnJvbS54LCAwICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdjEuc2V0KCAwLCAtIHZGcm9tLnosIHZGcm9tLnkgKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdjEuY3Jvc3NWZWN0b3JzKCB2RnJvbSwgdlRvICk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMueCA9IHYxLng7XG4gICAgICB0aGlzLnkgPSB2MS55O1xuICAgICAgdGhpcy56ID0gdjEuejtcbiAgICAgIHRoaXMudyA9IHI7XG5cbiAgICAgIHRoaXMubm9ybWFsaXplKCk7XG5cbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbiAgfSgpLFxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBNYXRoVXRpbDtcblxufSx7fV0sMTU6W2Z1bmN0aW9uKF9kZXJlcV8sbW9kdWxlLGV4cG9ydHMpe1xuLypcbiAqIENvcHlyaWdodCAyMDE2IEdvb2dsZSBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxudmFyIFZSRGlzcGxheSA9IF9kZXJlcV8oJy4vYmFzZS5qcycpLlZSRGlzcGxheTtcbnZhciBNYXRoVXRpbCA9IF9kZXJlcV8oJy4vbWF0aC11dGlsLmpzJyk7XG52YXIgVXRpbCA9IF9kZXJlcV8oJy4vdXRpbC5qcycpO1xuXG4vLyBIb3cgbXVjaCB0byByb3RhdGUgcGVyIGtleSBzdHJva2UuXG52YXIgS0VZX1NQRUVEID0gMC4xNTtcbnZhciBLRVlfQU5JTUFUSU9OX0RVUkFUSU9OID0gODA7XG5cbi8vIEhvdyBtdWNoIHRvIHJvdGF0ZSBmb3IgbW91c2UgZXZlbnRzLlxudmFyIE1PVVNFX1NQRUVEX1ggPSAwLjU7XG52YXIgTU9VU0VfU1BFRURfWSA9IDAuMztcblxuLyoqXG4gKiBWUkRpc3BsYXkgYmFzZWQgb24gbW91c2UgYW5kIGtleWJvYXJkIGlucHV0LiBEZXNpZ25lZCBmb3IgZGVza3RvcHMvbGFwdG9wc1xuICogd2hlcmUgb3JpZW50YXRpb24gZXZlbnRzIGFyZW4ndCBzdXBwb3J0ZWQuIENhbm5vdCBwcmVzZW50LlxuICovXG5mdW5jdGlvbiBNb3VzZUtleWJvYXJkVlJEaXNwbGF5KCkge1xuICB0aGlzLmRpc3BsYXlOYW1lID0gJ01vdXNlIGFuZCBLZXlib2FyZCBWUkRpc3BsYXkgKHdlYnZyLXBvbHlmaWxsKSc7XG5cbiAgdGhpcy5jYXBhYmlsaXRpZXMuaGFzT3JpZW50YXRpb24gPSB0cnVlO1xuXG4gIC8vIEF0dGFjaCB0byBtb3VzZSBhbmQga2V5Ym9hcmQgZXZlbnRzLlxuICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIHRoaXMub25LZXlEb3duXy5iaW5kKHRoaXMpKTtcbiAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIHRoaXMub25Nb3VzZU1vdmVfLmJpbmQodGhpcykpO1xuICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgdGhpcy5vbk1vdXNlRG93bl8uYmluZCh0aGlzKSk7XG4gIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdtb3VzZXVwJywgdGhpcy5vbk1vdXNlVXBfLmJpbmQodGhpcykpO1xuXG4gIC8vIFwiUHJpdmF0ZVwiIG1lbWJlcnMuXG4gIHRoaXMucGhpXyA9IDA7XG4gIHRoaXMudGhldGFfID0gMDtcblxuICAvLyBWYXJpYWJsZXMgZm9yIGtleWJvYXJkLWJhc2VkIHJvdGF0aW9uIGFuaW1hdGlvbi5cbiAgdGhpcy50YXJnZXRBbmdsZV8gPSBudWxsO1xuICB0aGlzLmFuZ2xlQW5pbWF0aW9uXyA9IG51bGw7XG5cbiAgLy8gU3RhdGUgdmFyaWFibGVzIGZvciBjYWxjdWxhdGlvbnMuXG4gIHRoaXMub3JpZW50YXRpb25fID0gbmV3IE1hdGhVdGlsLlF1YXRlcm5pb24oKTtcblxuICAvLyBWYXJpYWJsZXMgZm9yIG1vdXNlLWJhc2VkIHJvdGF0aW9uLlxuICB0aGlzLnJvdGF0ZVN0YXJ0XyA9IG5ldyBNYXRoVXRpbC5WZWN0b3IyKCk7XG4gIHRoaXMucm90YXRlRW5kXyA9IG5ldyBNYXRoVXRpbC5WZWN0b3IyKCk7XG4gIHRoaXMucm90YXRlRGVsdGFfID0gbmV3IE1hdGhVdGlsLlZlY3RvcjIoKTtcbiAgdGhpcy5pc0RyYWdnaW5nXyA9IGZhbHNlO1xuXG4gIHRoaXMub3JpZW50YXRpb25PdXRfID0gbmV3IEZsb2F0MzJBcnJheSg0KTtcbn1cbk1vdXNlS2V5Ym9hcmRWUkRpc3BsYXkucHJvdG90eXBlID0gbmV3IFZSRGlzcGxheSgpO1xuXG5Nb3VzZUtleWJvYXJkVlJEaXNwbGF5LnByb3RvdHlwZS5nZXRJbW1lZGlhdGVQb3NlID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMub3JpZW50YXRpb25fLnNldEZyb21FdWxlcllYWih0aGlzLnBoaV8sIHRoaXMudGhldGFfLCAwKTtcblxuICB0aGlzLm9yaWVudGF0aW9uT3V0X1swXSA9IHRoaXMub3JpZW50YXRpb25fLng7XG4gIHRoaXMub3JpZW50YXRpb25PdXRfWzFdID0gdGhpcy5vcmllbnRhdGlvbl8ueTtcbiAgdGhpcy5vcmllbnRhdGlvbk91dF9bMl0gPSB0aGlzLm9yaWVudGF0aW9uXy56O1xuICB0aGlzLm9yaWVudGF0aW9uT3V0X1szXSA9IHRoaXMub3JpZW50YXRpb25fLnc7XG5cbiAgcmV0dXJuIHtcbiAgICBwb3NpdGlvbjogbnVsbCxcbiAgICBvcmllbnRhdGlvbjogdGhpcy5vcmllbnRhdGlvbk91dF8sXG4gICAgbGluZWFyVmVsb2NpdHk6IG51bGwsXG4gICAgbGluZWFyQWNjZWxlcmF0aW9uOiBudWxsLFxuICAgIGFuZ3VsYXJWZWxvY2l0eTogbnVsbCxcbiAgICBhbmd1bGFyQWNjZWxlcmF0aW9uOiBudWxsXG4gIH07XG59O1xuXG5Nb3VzZUtleWJvYXJkVlJEaXNwbGF5LnByb3RvdHlwZS5vbktleURvd25fID0gZnVuY3Rpb24oZSkge1xuICAvLyBUcmFjayBXQVNEIGFuZCBhcnJvdyBrZXlzLlxuICBpZiAoZS5rZXlDb2RlID09IDM4KSB7IC8vIFVwIGtleS5cbiAgICB0aGlzLmFuaW1hdGVQaGlfKHRoaXMucGhpXyArIEtFWV9TUEVFRCk7XG4gIH0gZWxzZSBpZiAoZS5rZXlDb2RlID09IDM5KSB7IC8vIFJpZ2h0IGtleS5cbiAgICB0aGlzLmFuaW1hdGVUaGV0YV8odGhpcy50aGV0YV8gLSBLRVlfU1BFRUQpO1xuICB9IGVsc2UgaWYgKGUua2V5Q29kZSA9PSA0MCkgeyAvLyBEb3duIGtleS5cbiAgICB0aGlzLmFuaW1hdGVQaGlfKHRoaXMucGhpXyAtIEtFWV9TUEVFRCk7XG4gIH0gZWxzZSBpZiAoZS5rZXlDb2RlID09IDM3KSB7IC8vIExlZnQga2V5LlxuICAgIHRoaXMuYW5pbWF0ZVRoZXRhXyh0aGlzLnRoZXRhXyArIEtFWV9TUEVFRCk7XG4gIH1cbn07XG5cbk1vdXNlS2V5Ym9hcmRWUkRpc3BsYXkucHJvdG90eXBlLmFuaW1hdGVUaGV0YV8gPSBmdW5jdGlvbih0YXJnZXRBbmdsZSkge1xuICB0aGlzLmFuaW1hdGVLZXlUcmFuc2l0aW9uc18oJ3RoZXRhXycsIHRhcmdldEFuZ2xlKTtcbn07XG5cbk1vdXNlS2V5Ym9hcmRWUkRpc3BsYXkucHJvdG90eXBlLmFuaW1hdGVQaGlfID0gZnVuY3Rpb24odGFyZ2V0QW5nbGUpIHtcbiAgLy8gUHJldmVudCBsb29raW5nIHRvbyBmYXIgdXAgb3IgZG93bi5cbiAgdGFyZ2V0QW5nbGUgPSBVdGlsLmNsYW1wKHRhcmdldEFuZ2xlLCAtTWF0aC5QSS8yLCBNYXRoLlBJLzIpO1xuICB0aGlzLmFuaW1hdGVLZXlUcmFuc2l0aW9uc18oJ3BoaV8nLCB0YXJnZXRBbmdsZSk7XG59O1xuXG4vKipcbiAqIFN0YXJ0IGFuIGFuaW1hdGlvbiB0byB0cmFuc2l0aW9uIGFuIGFuZ2xlIGZyb20gb25lIHZhbHVlIHRvIGFub3RoZXIuXG4gKi9cbk1vdXNlS2V5Ym9hcmRWUkRpc3BsYXkucHJvdG90eXBlLmFuaW1hdGVLZXlUcmFuc2l0aW9uc18gPSBmdW5jdGlvbihhbmdsZU5hbWUsIHRhcmdldEFuZ2xlKSB7XG4gIC8vIElmIGFuIGFuaW1hdGlvbiBpcyBjdXJyZW50bHkgcnVubmluZywgY2FuY2VsIGl0LlxuICBpZiAodGhpcy5hbmdsZUFuaW1hdGlvbl8pIHtcbiAgICBjYW5jZWxBbmltYXRpb25GcmFtZSh0aGlzLmFuZ2xlQW5pbWF0aW9uXyk7XG4gIH1cbiAgdmFyIHN0YXJ0QW5nbGUgPSB0aGlzW2FuZ2xlTmFtZV07XG4gIHZhciBzdGFydFRpbWUgPSBuZXcgRGF0ZSgpO1xuICAvLyBTZXQgdXAgYW4gaW50ZXJ2YWwgdGltZXIgdG8gcGVyZm9ybSB0aGUgYW5pbWF0aW9uLlxuICB0aGlzLmFuZ2xlQW5pbWF0aW9uXyA9IHJlcXVlc3RBbmltYXRpb25GcmFtZShmdW5jdGlvbiBhbmltYXRlKCkge1xuICAgIC8vIE9uY2Ugd2UncmUgZmluaXNoZWQgdGhlIGFuaW1hdGlvbiwgd2UncmUgZG9uZS5cbiAgICB2YXIgZWxhcHNlZCA9IG5ldyBEYXRlKCkgLSBzdGFydFRpbWU7XG4gICAgaWYgKGVsYXBzZWQgPj0gS0VZX0FOSU1BVElPTl9EVVJBVElPTikge1xuICAgICAgdGhpc1thbmdsZU5hbWVdID0gdGFyZ2V0QW5nbGU7XG4gICAgICBjYW5jZWxBbmltYXRpb25GcmFtZSh0aGlzLmFuZ2xlQW5pbWF0aW9uXyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIGxvb3Agd2l0aCByZXF1ZXN0QW5pbWF0aW9uRnJhbWVcbiAgICB0aGlzLmFuZ2xlQW5pbWF0aW9uXyA9IHJlcXVlc3RBbmltYXRpb25GcmFtZShhbmltYXRlLmJpbmQodGhpcykpXG4gICAgLy8gTGluZWFybHkgaW50ZXJwb2xhdGUgdGhlIGFuZ2xlIHNvbWUgYW1vdW50LlxuICAgIHZhciBwZXJjZW50ID0gZWxhcHNlZCAvIEtFWV9BTklNQVRJT05fRFVSQVRJT047XG4gICAgdGhpc1thbmdsZU5hbWVdID0gc3RhcnRBbmdsZSArICh0YXJnZXRBbmdsZSAtIHN0YXJ0QW5nbGUpICogcGVyY2VudDtcbiAgfS5iaW5kKHRoaXMpKTtcbn07XG5cbk1vdXNlS2V5Ym9hcmRWUkRpc3BsYXkucHJvdG90eXBlLm9uTW91c2VEb3duXyA9IGZ1bmN0aW9uKGUpIHtcbiAgdGhpcy5yb3RhdGVTdGFydF8uc2V0KGUuY2xpZW50WCwgZS5jbGllbnRZKTtcbiAgdGhpcy5pc0RyYWdnaW5nXyA9IHRydWU7XG59O1xuXG4vLyBWZXJ5IHNpbWlsYXIgdG8gaHR0cHM6Ly9naXN0LmdpdGh1Yi5jb20vbXJmbGl4LzgzNTEwMjBcbk1vdXNlS2V5Ym9hcmRWUkRpc3BsYXkucHJvdG90eXBlLm9uTW91c2VNb3ZlXyA9IGZ1bmN0aW9uKGUpIHtcbiAgaWYgKCF0aGlzLmlzRHJhZ2dpbmdfICYmICF0aGlzLmlzUG9pbnRlckxvY2tlZF8oKSkge1xuICAgIHJldHVybjtcbiAgfVxuICAvLyBTdXBwb3J0IHBvaW50ZXIgbG9jayBBUEkuXG4gIGlmICh0aGlzLmlzUG9pbnRlckxvY2tlZF8oKSkge1xuICAgIHZhciBtb3ZlbWVudFggPSBlLm1vdmVtZW50WCB8fCBlLm1vek1vdmVtZW50WCB8fCAwO1xuICAgIHZhciBtb3ZlbWVudFkgPSBlLm1vdmVtZW50WSB8fCBlLm1vek1vdmVtZW50WSB8fCAwO1xuICAgIHRoaXMucm90YXRlRW5kXy5zZXQodGhpcy5yb3RhdGVTdGFydF8ueCAtIG1vdmVtZW50WCwgdGhpcy5yb3RhdGVTdGFydF8ueSAtIG1vdmVtZW50WSk7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5yb3RhdGVFbmRfLnNldChlLmNsaWVudFgsIGUuY2xpZW50WSk7XG4gIH1cbiAgLy8gQ2FsY3VsYXRlIGhvdyBtdWNoIHdlIG1vdmVkIGluIG1vdXNlIHNwYWNlLlxuICB0aGlzLnJvdGF0ZURlbHRhXy5zdWJWZWN0b3JzKHRoaXMucm90YXRlRW5kXywgdGhpcy5yb3RhdGVTdGFydF8pO1xuICB0aGlzLnJvdGF0ZVN0YXJ0Xy5jb3B5KHRoaXMucm90YXRlRW5kXyk7XG5cbiAgLy8gS2VlcCB0cmFjayBvZiB0aGUgY3VtdWxhdGl2ZSBldWxlciBhbmdsZXMuXG4gIHRoaXMucGhpXyArPSAyICogTWF0aC5QSSAqIHRoaXMucm90YXRlRGVsdGFfLnkgLyBzY3JlZW4uaGVpZ2h0ICogTU9VU0VfU1BFRURfWTtcbiAgdGhpcy50aGV0YV8gKz0gMiAqIE1hdGguUEkgKiB0aGlzLnJvdGF0ZURlbHRhXy54IC8gc2NyZWVuLndpZHRoICogTU9VU0VfU1BFRURfWDtcblxuICAvLyBQcmV2ZW50IGxvb2tpbmcgdG9vIGZhciB1cCBvciBkb3duLlxuICB0aGlzLnBoaV8gPSBVdGlsLmNsYW1wKHRoaXMucGhpXywgLU1hdGguUEkvMiwgTWF0aC5QSS8yKTtcbn07XG5cbk1vdXNlS2V5Ym9hcmRWUkRpc3BsYXkucHJvdG90eXBlLm9uTW91c2VVcF8gPSBmdW5jdGlvbihlKSB7XG4gIHRoaXMuaXNEcmFnZ2luZ18gPSBmYWxzZTtcbn07XG5cbk1vdXNlS2V5Ym9hcmRWUkRpc3BsYXkucHJvdG90eXBlLmlzUG9pbnRlckxvY2tlZF8gPSBmdW5jdGlvbigpIHtcbiAgdmFyIGVsID0gZG9jdW1lbnQucG9pbnRlckxvY2tFbGVtZW50IHx8IGRvY3VtZW50Lm1velBvaW50ZXJMb2NrRWxlbWVudCB8fFxuICAgICAgZG9jdW1lbnQud2Via2l0UG9pbnRlckxvY2tFbGVtZW50O1xuICByZXR1cm4gZWwgIT09IHVuZGVmaW5lZDtcbn07XG5cbk1vdXNlS2V5Ym9hcmRWUkRpc3BsYXkucHJvdG90eXBlLnJlc2V0UG9zZSA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLnBoaV8gPSAwO1xuICB0aGlzLnRoZXRhXyA9IDA7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IE1vdXNlS2V5Ym9hcmRWUkRpc3BsYXk7XG5cbn0se1wiLi9iYXNlLmpzXCI6MyxcIi4vbWF0aC11dGlsLmpzXCI6MTQsXCIuL3V0aWwuanNcIjoyMn1dLDE2OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcbi8qXG4gKiBDb3B5cmlnaHQgMjAxNSBHb29nbGUgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbnZhciBVdGlsID0gX2RlcmVxXygnLi91dGlsLmpzJyk7XG5cbmZ1bmN0aW9uIFJvdGF0ZUluc3RydWN0aW9ucygpIHtcbiAgdGhpcy5sb2FkSWNvbl8oKTtcblxuICB2YXIgb3ZlcmxheSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICB2YXIgcyA9IG92ZXJsYXkuc3R5bGU7XG4gIHMucG9zaXRpb24gPSAnZml4ZWQnO1xuICBzLnRvcCA9IDA7XG4gIHMucmlnaHQgPSAwO1xuICBzLmJvdHRvbSA9IDA7XG4gIHMubGVmdCA9IDA7XG4gIHMuYmFja2dyb3VuZENvbG9yID0gJ2dyYXknO1xuICBzLmZvbnRGYW1pbHkgPSAnc2Fucy1zZXJpZic7XG4gIC8vIEZvcmNlIHRoaXMgdG8gYmUgYWJvdmUgdGhlIGZ1bGxzY3JlZW4gY2FudmFzLCB3aGljaCBpcyBhdCB6SW5kZXg6IDk5OTk5OS5cbiAgcy56SW5kZXggPSAxMDAwMDAwO1xuXG4gIHZhciBpbWcgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpbWcnKTtcbiAgaW1nLnNyYyA9IHRoaXMuaWNvbjtcbiAgdmFyIHMgPSBpbWcuc3R5bGU7XG4gIHMubWFyZ2luTGVmdCA9ICcyNSUnO1xuICBzLm1hcmdpblRvcCA9ICcyNSUnO1xuICBzLndpZHRoID0gJzUwJSc7XG4gIG92ZXJsYXkuYXBwZW5kQ2hpbGQoaW1nKTtcblxuICB2YXIgdGV4dCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICB2YXIgcyA9IHRleHQuc3R5bGU7XG4gIHMudGV4dEFsaWduID0gJ2NlbnRlcic7XG4gIHMuZm9udFNpemUgPSAnMTZweCc7XG4gIHMubGluZUhlaWdodCA9ICcyNHB4JztcbiAgcy5tYXJnaW4gPSAnMjRweCAyNSUnO1xuICBzLndpZHRoID0gJzUwJSc7XG4gIHRleHQuaW5uZXJIVE1MID0gJ1BsYWNlIHlvdXIgcGhvbmUgaW50byB5b3VyIENhcmRib2FyZCB2aWV3ZXIuJztcbiAgb3ZlcmxheS5hcHBlbmRDaGlsZCh0ZXh0KTtcblxuICB2YXIgc25hY2tiYXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgdmFyIHMgPSBzbmFja2Jhci5zdHlsZTtcbiAgcy5iYWNrZ3JvdW5kQ29sb3IgPSAnI0NGRDhEQyc7XG4gIHMucG9zaXRpb24gPSAnZml4ZWQnO1xuICBzLmJvdHRvbSA9IDA7XG4gIHMud2lkdGggPSAnMTAwJSc7XG4gIHMuaGVpZ2h0ID0gJzQ4cHgnO1xuICBzLnBhZGRpbmcgPSAnMTRweCAyNHB4JztcbiAgcy5ib3hTaXppbmcgPSAnYm9yZGVyLWJveCc7XG4gIHMuY29sb3IgPSAnIzY1NkE2Qic7XG4gIG92ZXJsYXkuYXBwZW5kQ2hpbGQoc25hY2tiYXIpO1xuXG4gIHZhciBzbmFja2JhclRleHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgc25hY2tiYXJUZXh0LnN0eWxlLmZsb2F0ID0gJ2xlZnQnO1xuICBzbmFja2JhclRleHQuaW5uZXJIVE1MID0gJ05vIENhcmRib2FyZCB2aWV3ZXI/JztcblxuICB2YXIgc25hY2tiYXJCdXR0b24gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdhJyk7XG4gIHNuYWNrYmFyQnV0dG9uLmhyZWYgPSAnaHR0cHM6Ly93d3cuZ29vZ2xlLmNvbS9nZXQvY2FyZGJvYXJkL2dldC1jYXJkYm9hcmQvJztcbiAgc25hY2tiYXJCdXR0b24uaW5uZXJIVE1MID0gJ2dldCBvbmUnO1xuICBzbmFja2JhckJ1dHRvbi50YXJnZXQgPSAnX2JsYW5rJztcbiAgdmFyIHMgPSBzbmFja2JhckJ1dHRvbi5zdHlsZTtcbiAgcy5mbG9hdCA9ICdyaWdodCc7XG4gIHMuZm9udFdlaWdodCA9IDYwMDtcbiAgcy50ZXh0VHJhbnNmb3JtID0gJ3VwcGVyY2FzZSc7XG4gIHMuYm9yZGVyTGVmdCA9ICcxcHggc29saWQgZ3JheSc7XG4gIHMucGFkZGluZ0xlZnQgPSAnMjRweCc7XG4gIHMudGV4dERlY29yYXRpb24gPSAnbm9uZSc7XG4gIHMuY29sb3IgPSAnIzY1NkE2Qic7XG5cbiAgc25hY2tiYXIuYXBwZW5kQ2hpbGQoc25hY2tiYXJUZXh0KTtcbiAgc25hY2tiYXIuYXBwZW5kQ2hpbGQoc25hY2tiYXJCdXR0b24pO1xuXG4gIHRoaXMub3ZlcmxheSA9IG92ZXJsYXk7XG4gIHRoaXMudGV4dCA9IHRleHQ7XG5cbiAgdGhpcy5oaWRlKCk7XG59XG5cblJvdGF0ZUluc3RydWN0aW9ucy5wcm90b3R5cGUuc2hvdyA9IGZ1bmN0aW9uKHBhcmVudCkge1xuICBpZiAoIXBhcmVudCAmJiAhdGhpcy5vdmVybGF5LnBhcmVudEVsZW1lbnQpIHtcbiAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHRoaXMub3ZlcmxheSk7XG4gIH0gZWxzZSBpZiAocGFyZW50KSB7XG4gICAgaWYgKHRoaXMub3ZlcmxheS5wYXJlbnRFbGVtZW50ICYmIHRoaXMub3ZlcmxheS5wYXJlbnRFbGVtZW50ICE9IHBhcmVudClcbiAgICAgIHRoaXMub3ZlcmxheS5wYXJlbnRFbGVtZW50LnJlbW92ZUNoaWxkKHRoaXMub3ZlcmxheSk7XG5cbiAgICBwYXJlbnQuYXBwZW5kQ2hpbGQodGhpcy5vdmVybGF5KTtcbiAgfVxuXG4gIHRoaXMub3ZlcmxheS5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcblxuICB2YXIgaW1nID0gdGhpcy5vdmVybGF5LnF1ZXJ5U2VsZWN0b3IoJ2ltZycpO1xuICB2YXIgcyA9IGltZy5zdHlsZTtcblxuICBpZiAoVXRpbC5pc0xhbmRzY2FwZU1vZGUoKSkge1xuICAgIHMud2lkdGggPSAnMjAlJztcbiAgICBzLm1hcmdpbkxlZnQgPSAnNDAlJztcbiAgICBzLm1hcmdpblRvcCA9ICczJSc7XG4gIH0gZWxzZSB7XG4gICAgcy53aWR0aCA9ICc1MCUnO1xuICAgIHMubWFyZ2luTGVmdCA9ICcyNSUnO1xuICAgIHMubWFyZ2luVG9wID0gJzI1JSc7XG4gIH1cbn07XG5cblJvdGF0ZUluc3RydWN0aW9ucy5wcm90b3R5cGUuaGlkZSA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLm92ZXJsYXkuc3R5bGUuZGlzcGxheSA9ICdub25lJztcbn07XG5cblJvdGF0ZUluc3RydWN0aW9ucy5wcm90b3R5cGUuc2hvd1RlbXBvcmFyaWx5ID0gZnVuY3Rpb24obXMsIHBhcmVudCkge1xuICB0aGlzLnNob3cocGFyZW50KTtcbiAgdGhpcy50aW1lciA9IHNldFRpbWVvdXQodGhpcy5oaWRlLmJpbmQodGhpcyksIG1zKTtcbn07XG5cblJvdGF0ZUluc3RydWN0aW9ucy5wcm90b3R5cGUuZGlzYWJsZVNob3dUZW1wb3JhcmlseSA9IGZ1bmN0aW9uKCkge1xuICBjbGVhclRpbWVvdXQodGhpcy50aW1lcik7XG59O1xuXG5Sb3RhdGVJbnN0cnVjdGlvbnMucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLmRpc2FibGVTaG93VGVtcG9yYXJpbHkoKTtcbiAgLy8gSW4gcG9ydHJhaXQgVlIgbW9kZSwgdGVsbCB0aGUgdXNlciB0byByb3RhdGUgdG8gbGFuZHNjYXBlLiBPdGhlcndpc2UsIGhpZGVcbiAgLy8gdGhlIGluc3RydWN0aW9ucy5cbiAgaWYgKCFVdGlsLmlzTGFuZHNjYXBlTW9kZSgpICYmIFV0aWwuaXNNb2JpbGUoKSkge1xuICAgIHRoaXMuc2hvdygpO1xuICB9IGVsc2Uge1xuICAgIHRoaXMuaGlkZSgpO1xuICB9XG59O1xuXG5Sb3RhdGVJbnN0cnVjdGlvbnMucHJvdG90eXBlLmxvYWRJY29uXyA9IGZ1bmN0aW9uKCkge1xuICAvLyBFbmNvZGVkIGFzc2V0X3NyYy9yb3RhdGUtaW5zdHJ1Y3Rpb25zLnN2Z1xuICB0aGlzLmljb24gPSBVdGlsLmJhc2U2NCgnaW1hZ2Uvc3ZnK3htbCcsICdQRDk0Yld3Z2RtVnljMmx2YmowaU1TNHdJaUJsYm1OdlpHbHVaejBpVlZSR0xUZ2lJSE4wWVc1a1lXeHZibVU5SW01dklqOCtDanh6ZG1jZ2QybGtkR2c5SWpFNU9IQjRJaUJvWldsbmFIUTlJakkwTUhCNElpQjJhV1YzUW05NFBTSXdJREFnTVRrNElESTBNQ0lnZG1WeWMybHZiajBpTVM0eElpQjRiV3h1Y3owaWFIUjBjRG92TDNkM2R5NTNNeTV2Y21jdk1qQXdNQzl6ZG1jaUlIaHRiRzV6T25oc2FXNXJQU0pvZEhSd09pOHZkM2QzTG5jekxtOXlaeTh4T1RrNUwzaHNhVzVySWlCNGJXeHVjenB6YTJWMFkyZzlJbWgwZEhBNkx5OTNkM2N1WW05b1pXMXBZVzVqYjJScGJtY3VZMjl0TDNOclpYUmphQzl1Y3lJK0NpQWdJQ0E4SVMwdElFZGxibVZ5WVhSdmNqb2dVMnRsZEdOb0lETXVNeTR6SUNneE1qQTRNU2tnTFNCb2RIUndPaTh2ZDNkM0xtSnZhR1Z0YVdGdVkyOWthVzVuTG1OdmJTOXphMlYwWTJnZ0xTMCtDaUFnSUNBOGRHbDBiR1UrZEhKaGJuTnBkR2x2Ymp3dmRHbDBiR1UrQ2lBZ0lDQThaR1Z6WXo1RGNtVmhkR1ZrSUhkcGRHZ2dVMnRsZEdOb0xqd3ZaR1Z6WXo0S0lDQWdJRHhrWldaelBqd3ZaR1ZtY3o0S0lDQWdJRHhuSUdsa1BTSlFZV2RsTFRFaUlITjBjbTlyWlQwaWJtOXVaU0lnYzNSeWIydGxMWGRwWkhSb1BTSXhJaUJtYVd4c1BTSnViMjVsSWlCbWFXeHNMWEoxYkdVOUltVjJaVzV2WkdRaUlITnJaWFJqYURwMGVYQmxQU0pOVTFCaFoyVWlQZ29nSUNBZ0lDQWdJRHhuSUdsa1BTSjBjbUZ1YzJsMGFXOXVJaUJ6YTJWMFkyZzZkSGx3WlQwaVRWTkJjblJpYjJGeVpFZHliM1Z3SWo0S0lDQWdJQ0FnSUNBZ0lDQWdQR2NnYVdROUlrbHRjRzl5ZEdWa0xVeGhlV1Z5Y3kxRGIzQjVMVFF0S3kxSmJYQnZjblJsWkMxTVlYbGxjbk10UTI5d2VTMHJMVWx0Y0c5eWRHVmtMVXhoZVdWeWN5MURiM0I1TFRJdFEyOXdlU0lnYzJ0bGRHTm9PblI1Y0dVOUlrMVRUR0Y1WlhKSGNtOTFjQ0krQ2lBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0E4WnlCcFpEMGlTVzF3YjNKMFpXUXRUR0Y1WlhKekxVTnZjSGt0TkNJZ2RISmhibk5tYjNKdFBTSjBjbUZ1YzJ4aGRHVW9NQzR3TURBd01EQXNJREV3Tnk0d01EQXdNREFwSWlCemEyVjBZMmc2ZEhsd1pUMGlUVk5UYUdGd1pVZHliM1Z3SWo0S0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQThjR0YwYUNCa1BTSk5NVFE1TGpZeU5Td3lMalV5TnlCRE1UUTVMall5TlN3eUxqVXlOeUF4TlRVdU9EQTFMRFl1TURrMklERTFOaTR6TmpJc05pNDBNVGdnVERFMU5pNHpOaklzTnk0ek1EUWdRekUxTmk0ek5qSXNOeTQwT0RFZ01UVTJMak0zTlN3M0xqWTJOQ0F4TlRZdU5DdzNMamcxTXlCRE1UVTJMalF4TERjdU9UTTBJREUxTmk0ME1pdzRMakF4TlNBeE5UWXVOREkzTERndU1EazFJRU14TlRZdU5UWTNMRGt1TlRFZ01UVTNMalF3TVN3eE1TNHdPVE1nTVRVNExqVXpNaXd4TWk0d09UUWdUREUyTkM0eU5USXNNVGN1TVRVMklFd3hOalF1TXpNekxERTNMakEyTmlCRE1UWTBMak16TXl3eE55NHdOallnTVRZNExqY3hOU3d4TkM0MU16WWdNVFk1TGpVMk9Dd3hOQzR3TkRJZ1F6RTNNUzR3TWpVc01UUXVPRGd6SURFNU5TNDFNemdzTWprdU1ETTFJREU1TlM0MU16Z3NNamt1TURNMUlFd3hPVFV1TlRNNExEZ3pMakF6TmlCRE1UazFMalV6T0N3NE15NDRNRGNnTVRrMUxqRTFNaXc0TkM0eU5UTWdNVGswTGpVNUxEZzBMakkxTXlCRE1UazBMak0xTnl3NE5DNHlOVE1nTVRrMExqQTVOU3c0TkM0eE56Y2dNVGt6TGpneE9DdzROQzR3TVRjZ1RERTJPUzQ0TlRFc056QXVNVGM1SUV3eE5qa3VPRE0zTERjd0xqSXdNeUJNTVRReUxqVXhOU3c0TlM0NU56Z2dUREUwTVM0Mk5qVXNPRFF1TmpVMUlFTXhNell1T1RNMExEZ3pMakV5TmlBeE16RXVPVEUzTERneExqa3hOU0F4TWpZdU56RTBMRGd4TGpBME5TQkRNVEkyTGpjd09TdzRNUzR3TmlBeE1qWXVOekEzTERneExqQTJPU0F4TWpZdU56QTNMRGd4TGpBMk9TQk1NVEl4TGpZMExEazRMakF6SUV3eE1UTXVOelE1TERFd01pNDFPRFlnVERFeE15NDNNVElzTVRBeUxqVXlNeUJNTVRFekxqY3hNaXd4TXpBdU1URXpJRU14TVRNdU56RXlMREV6TUM0NE9EVWdNVEV6TGpNeU5pd3hNekV1TXpNZ01URXlMamMyTkN3eE16RXVNek1nUXpFeE1pNDFNeklzTVRNeExqTXpJREV4TWk0eU5qa3NNVE14TGpJMU5DQXhNVEV1T1RreUxERXpNUzR3T1RRZ1REWTVMalV4T1N3eE1EWXVOVGN5SUVNMk9DNDFOamtzTVRBMkxqQXlNeUEyTnk0M09Ua3NNVEEwTGpZNU5TQTJOeTQzT1Rrc01UQXpMall3TlNCTU5qY3VOems1TERFd01pNDFOeUJNTmpjdU56YzRMREV3TWk0Mk1UY2dRelkzTGpJM0xERXdNaTR6T1RNZ05qWXVOalE0TERFd01pNHlORGtnTmpVdU9UWXlMREV3TWk0eU1UZ2dRelkxTGpnM05Td3hNREl1TWpFMElEWTFMamM0T0N3eE1ESXVNakV5SURZMUxqY3dNU3d4TURJdU1qRXlJRU0yTlM0Mk1EWXNNVEF5TGpJeE1pQTJOUzQxTVRFc01UQXlMakl4TlNBMk5TNDBNVFlzTVRBeUxqSXhPU0JETmpVdU1UazFMREV3TWk0eU1qa2dOalF1T1RjMExERXdNaTR5TXpVZ05qUXVOelUwTERFd01pNHlNelVnUXpZMExqTXpNU3d4TURJdU1qTTFJRFl6TGpreE1Td3hNREl1TWpFMklEWXpMalE1T0N3eE1ESXVNVGM0SUVNMk1TNDRORE1zTVRBeUxqQXlOU0EyTUM0eU9UZ3NNVEF4TGpVM09DQTFPUzR3T1RRc01UQXdMamc0TWlCTU1USXVOVEU0TERjekxqazVNaUJNTVRJdU5USXpMRGMwTGpBd05DQk1NaTR5TkRVc05UVXVNalUwSUVNeExqSTBOQ3cxTXk0ME1qY2dNaTR3TURRc05URXVNRE00SURNdU9UUXpMRFE1TGpreE9DQk1OVGt1T1RVMExERTNMalUzTXlCRE5qQXVOakkyTERFM0xqRTROU0EyTVM0ek5Td3hOeTR3TURFZ05qSXVNRFV6TERFM0xqQXdNU0JETmpNdU16YzVMREUzTGpBd01TQTJOQzQyTWpVc01UY3VOallnTmpVdU1qZ3NNVGd1T0RVMElFdzJOUzR5T0RVc01UZ3VPRFV4SUV3Mk5TNDFNVElzTVRrdU1qWTBJRXcyTlM0MU1EWXNNVGt1TWpZNElFTTJOUzQ1TURrc01qQXVNREF6SURZMkxqUXdOU3d5TUM0Mk9DQTJOaTQ1T0RNc01qRXVNamcySUV3Mk55NHlOaXd5TVM0MU5UWWdRelk1TGpFM05Dd3lNeTQwTURZZ056RXVOekk0TERJMExqTTFOeUEzTkM0ek56TXNNalF1TXpVM0lFTTNOaTR6TWpJc01qUXVNelUzSURjNExqTXlNU3d5TXk0NE5DQTRNQzR4TkRnc01qSXVOemcxSUVNNE1DNHhOakVzTWpJdU56ZzFJRGczTGpRMk55d3hPQzQxTmpZZ09EY3VORFkzTERFNExqVTJOaUJET0RndU1UTTVMREU0TGpFM09DQTRPQzQ0TmpNc01UY3VPVGswSURnNUxqVTJOaXd4Tnk0NU9UUWdRemt3TGpnNU1pd3hOeTQ1T1RRZ09USXVNVE00TERFNExqWTFNaUE1TWk0M09USXNNVGt1T0RRM0lFdzVOaTR3TkRJc01qVXVOemMxSUV3NU5pNHdOalFzTWpVdU56VTNJRXd4TURJdU9EUTVMREk1TGpZM05DQk1NVEF5TGpjME5Dd3lPUzQwT1RJZ1RERTBPUzQyTWpVc01pNDFNamNnVFRFME9TNDJNalVzTUM0NE9USWdRekUwT1M0ek5ETXNNQzQ0T1RJZ01UUTVMakEyTWl3d0xqazJOU0F4TkRndU9ERXNNUzR4TVNCTU1UQXlMalkwTVN3eU55NDJOallnVERrM0xqSXpNU3d5TkM0MU5ESWdURGswTGpJeU5pd3hPUzR3TmpFZ1F6a3pMak14TXl3eE55NHpPVFFnT1RFdU5USTNMREUyTGpNMU9TQTRPUzQxTmpZc01UWXVNelU0SUVNNE9DNDFOVFVzTVRZdU16VTRJRGczTGpVME5pd3hOaTQyTXpJZ09EWXVOalE1TERFM0xqRTFJRU00TXk0NE56Z3NNVGd1TnpVZ056a3VOamczTERJeExqRTJPU0EzT1M0ek56UXNNakV1TXpRMUlFTTNPUzR6TlRrc01qRXVNelV6SURjNUxqTTBOU3d5TVM0ek5qRWdOemt1TXpNc01qRXVNelk1SUVNM055NDNPVGdzTWpJdU1qVTBJRGMyTGpBNE5Dd3lNaTQzTWpJZ056UXVNemN6TERJeUxqY3lNaUJETnpJdU1EZ3hMREl5TGpjeU1pQTJPUzQ1TlRrc01qRXVPRGtnTmpndU16azNMREl3TGpNNElFdzJPQzR4TkRVc01qQXVNVE0xSUVNMk55NDNNRFlzTVRrdU5qY3lJRFkzTGpNeU15d3hPUzR4TlRZZ05qY3VNREEyTERFNExqWXdNU0JETmpZdU9UZzRMREU0TGpVMU9TQTJOaTQ1Tmpnc01UZ3VOVEU1SURZMkxqazBOaXd4T0M0ME56a2dURFkyTGpjeE9Td3hPQzR3TmpVZ1F6WTJMalk1TERFNExqQXhNaUEyTmk0Mk5UZ3NNVGN1T1RZZ05qWXVOakkwTERFM0xqa3hNU0JETmpVdU5qZzJMREUyTGpNek55QTJNeTQ1TlRFc01UVXVNelkySURZeUxqQTFNeXd4TlM0ek5qWWdRell4TGpBME1pd3hOUzR6TmpZZ05qQXVNRE16TERFMUxqWTBJRFU1TGpFek5pd3hOaTR4TlRnZ1RETXVNVEkxTERRNExqVXdNaUJETUM0ME1qWXNOVEF1TURZeElDMHdMall4TXl3MU15NDBORElnTUM0NE1URXNOVFl1TURRZ1RERXhMakE0T1N3M05DNDNPU0JETVRFdU1qWTJMRGMxTGpFeE15QXhNUzQxTXpjc056VXVNelV6SURFeExqZzFMRGMxTGpRNU5DQk1OVGd1TWpjMkxERXdNaTR5T1RnZ1F6VTVMalkzT1N3eE1ETXVNVEE0SURZeExqUXpNeXd4TURNdU5qTWdOak11TXpRNExERXdNeTQ0TURZZ1F6WXpMamd4TWl3eE1ETXVPRFE0SURZMExqSTROU3d4TURNdU9EY2dOalF1TnpVMExERXdNeTQ0TnlCRE5qVXNNVEF6TGpnM0lEWTFMakkwT1N3eE1ETXVPRFkwSURZMUxqUTVOQ3d4TURNdU9EVXlJRU0yTlM0MU5qTXNNVEF6TGpnME9TQTJOUzQyTXpJc01UQXpMamcwTnlBMk5TNDNNREVzTVRBekxqZzBOeUJETmpVdU56WTBMREV3TXk0NE5EY2dOalV1T0RJNExERXdNeTQ0TkRrZ05qVXVPRGtzTVRBekxqZzFNaUJETmpVdU9UZzJMREV3TXk0NE5UWWdOall1TURnc01UQXpMamcyTXlBMk5pNHhOek1zTVRBekxqZzNOQ0JETmpZdU1qZ3lMREV3TlM0ME5qY2dOamN1TXpNeUxERXdOeTR4T1RjZ05qZ3VOekF5TERFd055NDVPRGdnVERFeE1TNHhOelFzTVRNeUxqVXhJRU14TVRFdU5qazRMREV6TWk0NE1USWdNVEV5TGpJek1pd3hNekl1T1RZMUlERXhNaTQzTmpRc01UTXlMamsyTlNCRE1URTBMakkyTVN3eE16SXVPVFkxSURFeE5TNHpORGNzTVRNeExqYzJOU0F4TVRVdU16UTNMREV6TUM0eE1UTWdUREV4TlM0ek5EY3NNVEF6TGpVMU1TQk1NVEl5TGpRMU9DdzVPUzQwTkRZZ1F6RXlNaTQ0TVRrc09Ua3VNak0zSURFeU15NHdPRGNzT1RndU9EazRJREV5TXk0eU1EY3NPVGd1TkRrNElFd3hNamN1T0RZMUxEZ3lMamt3TlNCRE1UTXlMakkzT1N3NE15NDNNRElnTVRNMkxqVTFOeXc0TkM0M05UTWdNVFF3TGpZd055dzROaTR3TXpNZ1RERTBNUzR4TkN3NE5pNDROaklnUXpFME1TNDBOVEVzT0RjdU16UTJJREUwTVM0NU56Y3NPRGN1TmpFeklERTBNaTQxTVRZc09EY3VOakV6SUVNeE5ESXVOemswTERnM0xqWXhNeUF4TkRNdU1EYzJMRGczTGpVME1pQXhORE11TXpNekxEZzNMak01TXlCTU1UWTVMamcyTlN3M01pNHdOellnVERFNU15dzROUzQwTXpNZ1F6RTVNeTQxTWpNc09EVXVOek0xSURFNU5DNHdOVGdzT0RVdU9EZzRJREU1TkM0MU9TdzROUzQ0T0RnZ1F6RTVOaTR3T0Rjc09EVXVPRGc0SURFNU55NHhOek1zT0RRdU5qZzVJREU1Tnk0eE56TXNPRE11TURNMklFd3hPVGN1TVRjekxESTVMakF6TlNCRE1UazNMakUzTXl3eU9DNDBOVEVnTVRrMkxqZzJNU3d5Tnk0NU1URWdNVGsyTGpNMU5Td3lOeTQyTVRrZ1F6RTVOaTR6TlRVc01qY3VOakU1SURFM01TNDRORE1zTVRNdU5EWTNJREUzTUM0ek9EVXNNVEl1TmpJMklFTXhOekF1TVRNeUxERXlMalE0SURFMk9TNDROU3d4TWk0ME1EY2dNVFk1TGpVMk9Dd3hNaTQwTURjZ1F6RTJPUzR5T0RVc01USXVOREEzSURFMk9TNHdNRElzTVRJdU5EZ3hJREUyT0M0M05Ea3NNVEl1TmpJM0lFTXhOamd1TVRRekxERXlMamszT0NBeE5qVXVOelUyTERFMExqTTFOeUF4TmpRdU5ESTBMREUxTGpFeU5TQk1NVFU1TGpZeE5Td3hNQzQ0TnlCRE1UVTRMamM1Tml3eE1DNHhORFVnTVRVNExqRTFOQ3c0TGprek55QXhOVGd1TURVMExEY3VPVE0wSUVNeE5UZ3VNRFExTERjdU9ETTNJREUxT0M0d016UXNOeTQzTXprZ01UVTRMakF5TVN3M0xqWTBJRU14TlRndU1EQTFMRGN1TlRJeklERTFOeTQ1T1Rnc055NDBNU0F4TlRjdU9UazRMRGN1TXpBMElFd3hOVGN1T1RrNExEWXVOREU0SUVNeE5UY3VPVGs0TERVdU9ETTBJREUxTnk0Mk9EWXNOUzR5T1RVZ01UVTNMakU0TVN3MUxqQXdNaUJETVRVMkxqWXlOQ3cwTGpZNElERTFNQzQwTkRJc01TNHhNVEVnTVRVd0xqUTBNaXd4TGpFeE1TQkRNVFV3TGpFNE9Td3dMamsyTlNBeE5Ea3VPVEEzTERBdU9Ea3lJREUwT1M0Mk1qVXNNQzQ0T1RJaUlHbGtQU0pHYVd4c0xURWlJR1pwYkd3OUlpTTBOVFZCTmpRaVBqd3ZjR0YwYUQ0S0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQThjR0YwYUNCa1BTSk5PVFl1TURJM0xESTFMall6TmlCTU1UUXlMall3TXl3MU1pNDFNamNnUXpFME15NDRNRGNzTlRNdU1qSXlJREUwTkM0MU9ESXNOVFF1TVRFMElERTBOQzQ0TkRVc05UVXVNRFk0SUV3eE5EUXVPRE0xTERVMUxqQTNOU0JNTmpNdU5EWXhMREV3TWk0d05UY2dURFl6TGpRMkxERXdNaTR3TlRjZ1F6WXhMamd3Tml3eE1ERXVPVEExSURZd0xqSTJNU3d4TURFdU5EVTNJRFU1TGpBMU55d3hNREF1TnpZeUlFd3hNaTQwT0RFc056TXVPRGN4SUV3NU5pNHdNamNzTWpVdU5qTTJJaUJwWkQwaVJtbHNiQzB5SWlCbWFXeHNQU0lqUmtGR1FVWkJJajQ4TDNCaGRHZytDaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnUEhCaGRHZ2daRDBpVFRZekxqUTJNU3d4TURJdU1UYzBJRU0yTXk0ME5UTXNNVEF5TGpFM05DQTJNeTQwTkRZc01UQXlMakUzTkNBMk15NDBNemtzTVRBeUxqRTNNaUJETmpFdU56UTJMREV3TWk0d01UWWdOakF1TWpFeExERXdNUzQxTmpNZ05UZ3VPVGs0TERFd01DNDROak1nVERFeUxqUXlNaXczTXk0NU56TWdRekV5TGpNNE5pdzNNeTQ1TlRJZ01USXVNelkwTERjekxqa3hOQ0F4TWk0ek5qUXNOek11T0RjeElFTXhNaTR6TmpRc056TXVPRE1nTVRJdU16ZzJMRGN6TGpjNU1TQXhNaTQwTWpJc056TXVOemNnVERrMUxqazJPQ3d5TlM0MU16VWdRemsyTGpBd05Dd3lOUzQxTVRRZ09UWXVNRFE1TERJMUxqVXhOQ0E1Tmk0d09EVXNNalV1TlRNMUlFd3hOREl1TmpZeExEVXlMalF5TmlCRE1UUXpMamc0T0N3MU15NHhNelFnTVRRMExqWTRNaXcxTkM0d016Z2dNVFEwTGprMU55dzFOUzR3TXpjZ1F6RTBOQzQ1Tnl3MU5TNHdPRE1nTVRRMExqazFNeXcxTlM0eE16TWdNVFEwTGpreE5TdzFOUzR4TmpFZ1F6RTBOQzQ1TVRFc05UVXVNVFkxSURFME5DNDRPVGdzTlRVdU1UYzBJREUwTkM0NE9UUXNOVFV1TVRjM0lFdzJNeTQxTVRrc01UQXlMakUxT0NCRE5qTXVOVEF4TERFd01pNHhOamtnTmpNdU5EZ3hMREV3TWk0eE56UWdOak11TkRZeExERXdNaTR4TnpRZ1REWXpMalEyTVN3eE1ESXVNVGMwSUZvZ1RURXlMamN4TkN3M015NDROekVnVERVNUxqRXhOU3d4TURBdU5qWXhJRU0yTUM0eU9UTXNNVEF4TGpNME1TQTJNUzQzT0RZc01UQXhMamM0TWlBMk15NDBNelVzTVRBeExqa3pOeUJNTVRRMExqY3dOeXcxTlM0d01UVWdRekUwTkM0ME1qZ3NOVFF1TVRBNElERTBNeTQyT0RJc05UTXVNamcxSURFME1pNDFORFFzTlRJdU5qSTRJRXc1Tmk0d01qY3NNalV1TnpjeElFd3hNaTQzTVRRc056TXVPRGN4SUV3eE1pNDNNVFFzTnpNdU9EY3hJRm9pSUdsa1BTSkdhV3hzTFRNaUlHWnBiR3c5SWlNMk1EZEVPRUlpUGp3dmNHRjBhRDRLSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBOGNHRjBhQ0JrUFNKTk1UUTRMak15Tnl3MU9DNDBOekVnUXpFME9DNHhORFVzTlRndU5EZ2dNVFEzTGprMk1pdzFPQzQwT0NBeE5EY3VOemd4TERVNExqUTNNaUJETVRRMUxqZzROeXcxT0M0ek9Ea2dNVFEwTGpRM09TdzFOeTQwTXpRZ01UUTBMall6Tml3MU5pNHpOQ0JETVRRMExqWTRPU3cxTlM0NU5qY2dNVFEwTGpZMk5DdzFOUzQxT1RjZ01UUTBMalUyTkN3MU5TNHlNelVnVERZekxqUTJNU3d4TURJdU1EVTNJRU0yTkM0d09Ea3NNVEF5TGpFeE5TQTJOQzQzTXpNc01UQXlMakV6SURZMUxqTTNPU3d4TURJdU1EazVJRU0yTlM0MU5qRXNNVEF5TGpBNUlEWTFMamMwTXl3eE1ESXVNRGtnTmpVdU9USTFMREV3TWk0d09UZ2dRelkzTGpneE9Td3hNREl1TVRneElEWTVMakl5Tnl3eE1ETXVNVE0ySURZNUxqQTNMREV3TkM0eU15Qk1NVFE0TGpNeU55dzFPQzQwTnpFaUlHbGtQU0pHYVd4c0xUUWlJR1pwYkd3OUlpTkdSa1pHUmtZaVBqd3ZjR0YwYUQ0S0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQThjR0YwYUNCa1BTSk5Oamt1TURjc01UQTBMak0wTnlCRE5qa3VNRFE0TERFd05DNHpORGNnTmprdU1ESTFMREV3TkM0ek5DQTJPUzR3TURVc01UQTBMak15TnlCRE5qZ3VPVFk0TERFd05DNHpNREVnTmpndU9UUTRMREV3TkM0eU5UY2dOamd1T1RVMUxERXdOQzR5TVRNZ1F6WTVMREV3TXk0NE9UWWdOamd1T0RrNExERXdNeTQxTnpZZ05qZ3VOalU0TERFd015NHlPRGdnUXpZNExqRTFNeXd4TURJdU5qYzRJRFkzTGpFd015d3hNREl1TWpZMklEWTFMamt5TERFd01pNHlNVFFnUXpZMUxqYzBNaXd4TURJdU1qQTJJRFkxTGpVMk15d3hNREl1TWpBM0lEWTFMak00TlN3eE1ESXVNakUxSUVNMk5DNDNORElzTVRBeUxqSTBOaUEyTkM0d09EY3NNVEF5TGpJek1pQTJNeTQwTlN3eE1ESXVNVGMwSUVNMk15NHpPVGtzTVRBeUxqRTJPU0EyTXk0ek5UZ3NNVEF5TGpFek1pQTJNeTR6TkRjc01UQXlMakE0TWlCRE5qTXVNek0yTERFd01pNHdNek1nTmpNdU16VTRMREV3TVM0NU9ERWdOak11TkRBeUxERXdNUzQ1TlRZZ1RERTBOQzQxTURZc05UVXVNVE0wSUVNeE5EUXVOVE0zTERVMUxqRXhOaUF4TkRRdU5UYzFMRFUxTGpFeE15QXhORFF1TmpBNUxEVTFMakV5TnlCRE1UUTBMalkwTWl3MU5TNHhOREVnTVRRMExqWTJPQ3cxTlM0eE55QXhORFF1TmpjM0xEVTFMakl3TkNCRE1UUTBMamM0TVN3MU5TNDFPRFVnTVRRMExqZ3dOaXcxTlM0NU56SWdNVFEwTGpjMU1TdzFOaTR6TlRjZ1F6RTBOQzQzTURZc05UWXVOamN6SURFME5DNDRNRGdzTlRZdU9UazBJREUwTlM0d05EY3NOVGN1TWpneUlFTXhORFV1TlRVekxEVTNMamc1TWlBeE5EWXVOakF5TERVNExqTXdNeUF4TkRjdU56ZzJMRFU0TGpNMU5TQkRNVFEzTGprMk5DdzFPQzR6TmpNZ01UUTRMakUwTXl3MU9DNHpOak1nTVRRNExqTXlNU3cxT0M0ek5UUWdRekUwT0M0ek56Y3NOVGd1TXpVeUlERTBPQzQwTWpRc05UZ3VNemczSURFME9DNDBNemtzTlRndU5ETTRJRU14TkRndU5EVTBMRFU0TGpRNUlERTBPQzQwTXpJc05UZ3VOVFExSURFME9DNHpPRFVzTlRndU5UY3lJRXcyT1M0eE1qa3NNVEEwTGpNek1TQkROamt1TVRFeExERXdOQzR6TkRJZ05qa3VNRGtzTVRBMExqTTBOeUEyT1M0d055d3hNRFF1TXpRM0lFdzJPUzR3Tnl3eE1EUXVNelEzSUZvZ1RUWTFMalkyTlN3eE1ERXVPVGMxSUVNMk5TNDNOVFFzTVRBeExqazNOU0EyTlM0NE5ESXNNVEF4TGprM055QTJOUzQ1TXl3eE1ERXVPVGd4SUVNMk55NHhPVFlzTVRBeUxqQXpOeUEyT0M0eU9ETXNNVEF5TGpRMk9TQTJPQzQ0TXpnc01UQXpMakV6T1NCRE5qa3VNRFkxTERFd015NDBNVE1nTmprdU1UZzRMREV3TXk0M01UUWdOamt1TVRrNExERXdOQzR3TWpFZ1RERTBOeTQ0T0RNc05UZ3VOVGt5SUVNeE5EY3VPRFEzTERVNExqVTVNaUF4TkRjdU9ERXhMRFU0TGpVNU1TQXhORGN1TnpjMkxEVTRMalU0T1NCRE1UUTJMalV3T1N3MU9DNDFNek1nTVRRMUxqUXlNaXcxT0M0eElERTBOQzQ0Tmpjc05UY3VORE14SUVNeE5EUXVOVGcxTERVM0xqQTVNU0F4TkRRdU5EWTFMRFUyTGpjd055QXhORFF1TlRJc05UWXVNekkwSUVNeE5EUXVOVFl6TERVMkxqQXlNU0F4TkRRdU5UVXlMRFUxTGpjeE5pQXhORFF1TkRnNExEVTFMalF4TkNCTU5qTXVPRFEyTERFd01TNDVOeUJETmpRdU16VXpMREV3TWk0d01ESWdOalF1T0RZM0xERXdNaTR3TURZZ05qVXVNemMwTERFd01TNDVPRElnUXpZMUxqUTNNU3d4TURFdU9UYzNJRFkxTGpVMk9Dd3hNREV1T1RjMUlEWTFMalkyTlN3eE1ERXVPVGMxSUV3Mk5TNDJOalVzTVRBeExqazNOU0JhSWlCcFpEMGlSbWxzYkMwMUlpQm1hV3hzUFNJak5qQTNSRGhDSWo0OEwzQmhkR2crQ2lBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ1BIQmhkR2dnWkQwaVRUSXVNakE0TERVMUxqRXpOQ0JETVM0eU1EY3NOVE11TXpBM0lERXVPVFkzTERVd0xqa3hOeUF6TGprd05pdzBPUzQzT1RjZ1REVTVMamt4Tnl3eE55NDBOVE1nUXpZeExqZzFOaXd4Tmk0ek16TWdOalF1TWpReExERTJMamt3TnlBMk5TNHlORE1zTVRndU56TTBJRXcyTlM0ME56VXNNVGt1TVRRMElFTTJOUzQ0TnpJc01Ua3VPRGd5SURZMkxqTTJPQ3d5TUM0MU5pQTJOaTQ1TkRVc01qRXVNVFkxSUV3Mk55NHlNak1zTWpFdU5ETTFJRU0zTUM0MU5EZ3NNalF1TmpRNUlEYzFMamd3Tml3eU5TNHhOVEVnT0RBdU1URXhMREl5TGpZMk5TQk1PRGN1TkRNc01UZ3VORFExSUVNNE9TNHpOeXd4Tnk0ek1qWWdPVEV1TnpVMExERTNMamc1T1NBNU1pNDNOVFVzTVRrdU56STNJRXc1Tmk0d01EVXNNalV1TmpVMUlFd3hNaTQwT0RZc056TXVPRGcwSUV3eUxqSXdPQ3cxTlM0eE16UWdXaUlnYVdROUlrWnBiR3d0TmlJZ1ptbHNiRDBpSTBaQlJrRkdRU0krUEM5d1lYUm9QZ29nSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUR4d1lYUm9JR1E5SWsweE1pNDBPRFlzTnpRdU1EQXhJRU14TWk0ME56WXNOelF1TURBeElERXlMalEyTlN3M015NDVPVGtnTVRJdU5EVTFMRGN6TGprNU5pQkRNVEl1TkRJMExEY3pMams0T0NBeE1pNHpPVGtzTnpNdU9UWTNJREV5TGpNNE5DdzNNeTQ1TkNCTU1pNHhNRFlzTlRVdU1Ua2dRekV1TURjMUxEVXpMak14SURFdU9EVTNMRFV3TGpnME5TQXpMamcwT0N3ME9TNDJPVFlnVERVNUxqZzFPQ3d4Tnk0ek5USWdRell3TGpVeU5Td3hOaTQ1TmpjZ05qRXVNamN4TERFMkxqYzJOQ0EyTWk0d01UWXNNVFl1TnpZMElFTTJNeTQwTXpFc01UWXVOelkwSURZMExqWTJOaXd4Tnk0ME5qWWdOalV1TXpJM0xERTRMalkwTmlCRE5qVXVNek0zTERFNExqWTFOQ0EyTlM0ek5EVXNNVGd1TmpZeklEWTFMak0xTVN3eE9DNDJOelFnVERZMUxqVTNPQ3d4T1M0d09EZ2dRelkxTGpVNE5Dd3hPUzR4SURZMUxqVTRPU3d4T1M0eE1USWdOalV1TlRreExERTVMakV5TmlCRE5qVXVPVGcxTERFNUxqZ3pPQ0EyTmk0ME5qa3NNakF1TkRrM0lEWTNMakF6TERJeExqQTROU0JNTmpjdU16QTFMREl4TGpNMU1TQkROamt1TVRVeExESXpMakV6TnlBM01TNDJORGtzTWpRdU1USWdOelF1TXpNMkxESTBMakV5SUVNM05pNHpNVE1zTWpRdU1USWdOemd1TWprc01qTXVOVGd5SURnd0xqQTFNeXd5TWk0MU5qTWdRemd3TGpBMk5Dd3lNaTQxTlRjZ09EQXVNRGMyTERJeUxqVTFNeUE0TUM0d09EZ3NNakl1TlRVZ1REZzNMak0zTWl3eE9DNHpORFFnUXpnNExqQXpPQ3d4Tnk0NU5Ua2dPRGd1TnpnMExERTNMamMxTmlBNE9TNDFNamtzTVRjdU56VTJJRU01TUM0NU5UWXNNVGN1TnpVMklEa3lMakl3TVN3eE9DNDBOeklnT1RJdU9EVTRMREU1TGpZM0lFdzVOaTR4TURjc01qVXVOVGs1SUVNNU5pNHhNemdzTWpVdU5qVTBJRGsyTGpFeE9Dd3lOUzQzTWpRZ09UWXVNRFl6TERJMUxqYzFOaUJNTVRJdU5UUTFMRGN6TGprNE5TQkRNVEl1TlRJMkxEY3pMams1TmlBeE1pNDFNRFlzTnpRdU1EQXhJREV5TGpRNE5pdzNOQzR3TURFZ1RERXlMalE0Tml3M05DNHdNREVnV2lCTk5qSXVNREUyTERFMkxqazVOeUJETmpFdU16RXlMREUyTGprNU55QTJNQzQyTURZc01UY3VNVGtnTlRrdU9UYzFMREUzTGpVMU5DQk1NeTQ1TmpVc05Ea3VPRGs1SUVNeUxqQTRNeXcxTUM0NU9EVWdNUzR6TkRFc05UTXVNekE0SURJdU16RXNOVFV1TURjNElFd3hNaTQxTXpFc056TXVOekl6SUV3NU5TNDRORGdzTWpVdU5qRXhJRXc1TWk0Mk5UTXNNVGt1TnpneUlFTTVNaTR3TXpnc01UZ3VOallnT1RBdU9EY3NNVGN1T1RrZ09Ea3VOVEk1TERFM0xqazVJRU00T0M0NE1qVXNNVGN1T1RrZ09EZ3VNVEU1TERFNExqRTRNaUE0Tnk0ME9Ea3NNVGd1TlRRM0lFdzRNQzR4TnpJc01qSXVOemN5SUVNNE1DNHhOakVzTWpJdU56YzRJRGd3TGpFME9Td3lNaTQzT0RJZ09EQXVNVE0zTERJeUxqYzROU0JETnpndU16UTJMREl6TGpneE1TQTNOaTR6TkRFc01qUXVNelUwSURjMExqTXpOaXd5TkM0ek5UUWdRemN4TGpVNE9Dd3lOQzR6TlRRZ05qa3VNRE16TERJekxqTTBOeUEyTnk0eE5ESXNNakV1TlRFNUlFdzJOaTQ0TmpRc01qRXVNalE1SUVNMk5pNHlOemNzTWpBdU5qTTBJRFkxTGpjM05Dd3hPUzQ1TkRjZ05qVXVNelkzTERFNUxqSXdNeUJETmpVdU16WXNNVGt1TVRreUlEWTFMak0xTml3eE9TNHhOemtnTmpVdU16VTBMREU1TGpFMk5pQk1OalV1TVRZekxERTRMamd4T1NCRE5qVXVNVFUwTERFNExqZ3hNU0EyTlM0eE5EWXNNVGd1T0RBeElEWTFMakUwTERFNExqYzVJRU0yTkM0MU1qVXNNVGN1TmpZM0lEWXpMak0xTnl3eE5pNDVPVGNnTmpJdU1ERTJMREUyTGprNU55Qk1Oakl1TURFMkxERTJMams1TnlCYUlpQnBaRDBpUm1sc2JDMDNJaUJtYVd4c1BTSWpOakEzUkRoQ0lqNDhMM0JoZEdnK0NpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdQSEJoZEdnZ1pEMGlUVFF5TGpRek5DdzBPQzQ0TURnZ1REUXlMalF6TkN3ME9DNDRNRGdnUXpNNUxqa3lOQ3cwT0M0NE1EY2dNemN1TnpNM0xEUTNMalUxSURNMkxqVTRNaXcwTlM0ME5ETWdRek0wTGpjM01TdzBNaTR4TXprZ016WXVNVFEwTERNM0xqZ3dPU0F6T1M0Mk5ERXNNelV1TnpnNUlFdzFNUzQ1TXpJc01qZ3VOamt4SUVNMU15NHhNRE1zTWpndU1ERTFJRFUwTGpReE15d3lOeTQyTlRnZ05UVXVOekl4TERJM0xqWTFPQ0JETlRndU1qTXhMREkzTGpZMU9DQTJNQzQwTVRnc01qZ3VPVEUySURZeExqVTNNeXd6TVM0d01qTWdRell6TGpNNE5Dd3pOQzR6TWpjZ05qSXVNREV5TERNNExqWTFOeUExT0M0MU1UUXNOREF1TmpjM0lFdzBOaTR5TWpNc05EY3VOemMxSUVNME5TNHdOVE1zTkRndU5EVWdORE11TnpReUxEUTRMamd3T0NBME1pNDBNelFzTkRndU9EQTRJRXcwTWk0ME16UXNORGd1T0RBNElGb2dUVFUxTGpjeU1Td3lPQzR4TWpVZ1F6VTBMalE1TlN3eU9DNHhNalVnTlRNdU1qWTFMREk0TGpRMk1TQTFNaTR4TmpZc01qa3VNRGsySUV3ek9TNDROelVzTXpZdU1UazBJRU16Tmk0MU9UWXNNemd1TURnM0lETTFMak13TWl3ME1pNHhNellnTXpZdU9Ua3lMRFExTGpJeE9DQkRNemd1TURZekxEUTNMakUzTXlBME1DNHdPVGdzTkRndU16UWdOREl1TkRNMExEUTRMak0wSUVNME15NDJOakVzTkRndU16UWdORFF1T0Rrc05EZ3VNREExSURRMUxqazVMRFEzTGpNM0lFdzFPQzR5T0RFc05EQXVNamN5SUVNMk1TNDFOaXd6T0M0ek56a2dOakl1T0RVekxETTBMak16SURZeExqRTJOQ3d6TVM0eU5EZ2dRell3TGpBNU1pd3lPUzR5T1RNZ05UZ3VNRFU0TERJNExqRXlOU0ExTlM0M01qRXNNamd1TVRJMUlFdzFOUzQzTWpFc01qZ3VNVEkxSUZvaUlHbGtQU0pHYVd4c0xUZ2lJR1pwYkd3OUlpTTJNRGRFT0VJaVBqd3ZjR0YwYUQ0S0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQThjR0YwYUNCa1BTSk5NVFE1TGpVNE9Dd3lMalF3TnlCRE1UUTVMalU0T0N3eUxqUXdOeUF4TlRVdU56WTRMRFV1T1RjMUlERTFOaTR6TWpVc05pNHlPVGNnVERFMU5pNHpNalVzTnk0eE9EUWdRekUxTmk0ek1qVXNOeTR6TmlBeE5UWXVNek00TERjdU5UUTBJREUxTmk0ek5qSXNOeTQzTXpNZ1F6RTFOaTR6TnpNc055NDRNVFFnTVRVMkxqTTRNaXczTGpnNU5DQXhOVFl1TXprc055NDVOelVnUXpFMU5pNDFNeXc1TGpNNUlERTFOeTR6TmpNc01UQXVPVGN6SURFMU9DNDBPVFVzTVRFdU9UYzBJRXd4TmpVdU9Ea3hMREU0TGpVeE9TQkRNVFkyTGpBMk9Dd3hPQzQyTnpVZ01UWTJMakkwT1N3eE9DNDRNVFFnTVRZMkxqUXpNaXd4T0M0NU16UWdRekUyT0M0d01URXNNVGt1T1RjMElERTJPUzR6T0RJc01Ua3VOQ0F4TmprdU5EazBMREUzTGpZMU1pQkRNVFk1TGpVME15d3hOaTQ0TmpnZ01UWTVMalUxTVN3eE5pNHdOVGNnTVRZNUxqVXhOeXd4TlM0eU1qTWdUREUyT1M0MU1UUXNNVFV1TURZeklFd3hOamt1TlRFMExERXpMamt4TWlCRE1UY3dMamM0TERFMExqWTBNaUF4T1RVdU5UQXhMREk0TGpreE5TQXhPVFV1TlRBeExESTRMamt4TlNCTU1UazFMalV3TVN3NE1pNDVNVFVnUXpFNU5TNDFNREVzT0RRdU1EQTFJREU1TkM0M016RXNPRFF1TkRRMUlERTVNeTQzT0RFc09ETXVPRGszSUV3eE5URXVNekE0TERVNUxqTTNOQ0JETVRVd0xqTTFPQ3cxT0M0NE1qWWdNVFE1TGpVNE9DdzFOeTQwT1RjZ01UUTVMalU0T0N3MU5pNDBNRGdnVERFME9TNDFPRGdzTWpJdU16YzFJaUJwWkQwaVJtbHNiQzA1SWlCbWFXeHNQU0lqUmtGR1FVWkJJajQ4TDNCaGRHZytDaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnUEhCaGRHZ2daRDBpVFRFNU5DNDFOVE1zT0RRdU1qVWdRekU1TkM0eU9UWXNPRFF1TWpVZ01UazBMakF4TXl3NE5DNHhOalVnTVRrekxqY3lNaXc0TXk0NU9UY2dUREUxTVM0eU5TdzFPUzQwTnpZZ1F6RTFNQzR5Tmprc05UZ3VPVEE1SURFME9TNDBOekVzTlRjdU5UTXpJREUwT1M0ME56RXNOVFl1TkRBNElFd3hORGt1TkRjeExESXlMak0zTlNCTU1UUTVMamN3TlN3eU1pNHpOelVnVERFME9TNDNNRFVzTlRZdU5EQTRJRU14TkRrdU56QTFMRFUzTGpRMU9TQXhOVEF1TkRVc05UZ3VOelEwSURFMU1TNHpOallzTlRrdU1qYzBJRXd4T1RNdU9ETTVMRGd6TGpjNU5TQkRNVGswTGpJMk15dzROQzR3TkNBeE9UUXVOalUxTERnMExqQTRNeUF4T1RRdU9UUXlMRGd6TGpreE55QkRNVGsxTGpJeU55dzRNeTQzTlRNZ01UazFMak00TkN3NE15NHpPVGNnTVRrMUxqTTROQ3c0TWk0NU1UVWdUREU1TlM0ek9EUXNNamd1T1RneUlFTXhPVFF1TVRBeUxESTRMakkwTWlBeE56SXVNVEEwTERFMUxqVTBNaUF4TmprdU5qTXhMREUwTGpFeE5DQk1NVFk1TGpZek5Dd3hOUzR5TWlCRE1UWTVMalkyT0N3eE5pNHdOVElnTVRZNUxqWTJMREUyTGpnM05DQXhOamt1TmpFc01UY3VOalU1SUVNeE5qa3VOVFUyTERFNExqVXdNeUF4TmprdU1qRTBMREU1TGpFeU15QXhOamd1TmpRM0xERTVMalF3TlNCRE1UWTRMakF5T0N3eE9TNDNNVFFnTVRZM0xqRTVOeXd4T1M0MU56Z2dNVFkyTGpNMk55d3hPUzR3TXpJZ1F6RTJOaTR4T0RFc01UZ3VPVEE1SURFMk5TNDVPVFVzTVRndU56WTJJREUyTlM0NE1UUXNNVGd1TmpBMklFd3hOVGd1TkRFM0xERXlMakEyTWlCRE1UVTNMakkxT1N3eE1TNHdNellnTVRVMkxqUXhPQ3c1TGpRek55QXhOVFl1TWpjMExEY3VPVGcySUVNeE5UWXVNalkyTERjdU9UQTNJREUxTmk0eU5UY3NOeTQ0TWpjZ01UVTJMakkwTnl3M0xqYzBPQ0JETVRVMkxqSXlNU3czTGpVMU5TQXhOVFl1TWpBNUxEY3VNelkxSURFMU5pNHlNRGtzTnk0eE9EUWdUREUxTmk0eU1Ea3NOaTR6TmpRZ1F6RTFOUzR6TnpVc05TNDRPRE1nTVRRNUxqVXlPU3d5TGpVd09DQXhORGt1TlRJNUxESXVOVEE0SUV3eE5Ea3VOalEyTERJdU16QTJJRU14TkRrdU5qUTJMREl1TXpBMklERTFOUzQ0TWpjc05TNDROelFnTVRVMkxqTTROQ3cyTGpFNU5pQk1NVFUyTGpRME1pdzJMakl6SUV3eE5UWXVORFF5TERjdU1UZzBJRU14TlRZdU5EUXlMRGN1TXpVMUlERTFOaTQwTlRRc055NDFNelVnTVRVMkxqUTNPQ3czTGpjeE55QkRNVFUyTGpRNE9TdzNMamdnTVRVMkxqUTVPU3czTGpnNE1pQXhOVFl1TlRBM0xEY3VPVFl6SUVNeE5UWXVOalExTERrdU16VTRJREUxTnk0ME5UVXNNVEF1T0RrNElERTFPQzQxTnpJc01URXVPRGcySUV3eE5qVXVPVFk1TERFNExqUXpNU0JETVRZMkxqRTBNaXd4T0M0MU9EUWdNVFkyTGpNeE9Td3hPQzQzTWlBeE5qWXVORGsyTERFNExqZ3pOeUJETVRZM0xqSTFOQ3d4T1M0ek16WWdNVFk0TERFNUxqUTJOeUF4TmpndU5UUXpMREU1TGpFNU5pQkRNVFk1TGpBek15d3hPQzQ1TlRNZ01UWTVMak15T1N3eE9DNDBNREVnTVRZNUxqTTNOeXd4Tnk0Mk5EVWdRekUyT1M0ME1qY3NNVFl1T0RZM0lERTJPUzQwTXpRc01UWXVNRFUwSURFMk9TNDBNREVzTVRVdU1qSTRJRXd4TmprdU16azNMREUxTGpBMk5TQk1NVFk1TGpNNU55d3hNeTQzTVNCTU1UWTVMalUzTWl3eE15NDRNU0JETVRjd0xqZ3pPU3d4TkM0MU5ERWdNVGsxTGpVMU9Td3lPQzQ0TVRRZ01UazFMalUxT1N3eU9DNDRNVFFnVERFNU5TNDJNVGdzTWpndU9EUTNJRXd4T1RVdU5qRTRMRGd5TGpreE5TQkRNVGsxTGpZeE9DdzRNeTQwT0RRZ01UazFMalF5TERnekxqa3hNU0F4T1RVdU1EVTVMRGcwTGpFeE9TQkRNVGswTGprd09DdzROQzR5TURZZ01UazBMamN6Tnl3NE5DNHlOU0F4T1RRdU5UVXpMRGcwTGpJMUlpQnBaRDBpUm1sc2JDMHhNQ0lnWm1sc2JEMGlJell3TjBRNFFpSStQQzl3WVhSb1Bnb2dJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJRHh3WVhSb0lHUTlJazB4TkRVdU5qZzFMRFUyTGpFMk1TQk1NVFk1TGpnc056QXVNRGd6SUV3eE5ETXVPREl5TERnMUxqQTRNU0JNTVRReUxqTTJMRGcwTGpjM05DQkRNVE0xTGpneU5pdzRNaTQyTURRZ01USTRMamN6TWl3NE1TNHdORFlnTVRJeExqTTBNU3c0TUM0eE5UZ2dRekV4Tmk0NU56WXNOemt1TmpNMElERXhNaTQyTnpnc09ERXVNalUwSURFeE1TNDNORE1zT0RNdU56YzRJRU14TVRFdU5UQTJMRGcwTGpReE5DQXhNVEV1TlRBekxEZzFMakEzTVNBeE1URXVOek15TERnMUxqY3dOaUJETVRFekxqSTNMRGc1TGprM015QXhNVFV1T1RZNExEazBMakEyT1NBeE1Ua3VOekkzTERrM0xqZzBNU0JNTVRJd0xqSTFPU3c1T0M0Mk9EWWdRekV5TUM0eU5pdzVPQzQyT0RVZ09UUXVNamd5TERFeE15NDJPRE1nT1RRdU1qZ3lMREV4TXk0Mk9ETWdURGN3TGpFMk55dzVPUzQzTmpFZ1RERTBOUzQyT0RVc05UWXVNVFl4SWlCcFpEMGlSbWxzYkMweE1TSWdabWxzYkQwaUkwWkdSa1pHUmlJK1BDOXdZWFJvUGdvZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lEeHdZWFJvSUdROUlrMDVOQzR5T0RJc01URXpMamd4T0NCTU9UUXVNakl6TERFeE15NDNPRFVnVERZNUxqa3pNeXc1T1M0M05qRWdURGN3TGpFd09DdzVPUzQyTmlCTU1UUTFMalk0TlN3MU5pNHdNallnVERFME5TNDNORE1zTlRZdU1EVTVJRXd4TnpBdU1ETXpMRGN3TGpBNE15Qk1NVFF6TGpnME1pdzROUzR5TURVZ1RERTBNeTQzT1Rjc09EVXVNVGsxSUVNeE5ETXVOemN5TERnMUxqRTVJREUwTWk0ek16WXNPRFF1T0RnNElERTBNaTR6TXpZc09EUXVPRGc0SUVNeE16VXVOemczTERneUxqY3hOQ0F4TWpndU56SXpMRGd4TGpFMk15QXhNakV1TXpJM0xEZ3dMakkzTkNCRE1USXdMamM0T0N3NE1DNHlNRGtnTVRJd0xqSXpOaXc0TUM0eE56Y2dNVEU1TGpZNE9TdzRNQzR4TnpjZ1F6RXhOUzQ1TXpFc09EQXVNVGMzSURFeE1pNDJNelVzT0RFdU56QTRJREV4TVM0NE5USXNPRE11T0RFNUlFTXhNVEV1TmpJMExEZzBMalF6TWlBeE1URXVOakl4TERnMUxqQTFNeUF4TVRFdU9EUXlMRGcxTGpZMk55QkRNVEV6TGpNM055dzRPUzQ1TWpVZ01URTJMakExT0N3NU15NDVPVE1nTVRFNUxqZ3hMRGszTGpjMU9DQk1NVEU1TGpneU5pdzVOeTQzTnprZ1RERXlNQzR6TlRJc09UZ3VOakUwSUVNeE1qQXVNelUwTERrNExqWXhOeUF4TWpBdU16VTJMRGs0TGpZeUlERXlNQzR6TlRnc09UZ3VOakkwSUV3eE1qQXVOREl5TERrNExqY3lOaUJNTVRJd0xqTXhOeXc1T0M0M09EY2dRekV5TUM0eU5qUXNPVGd1T0RFNElEazBMalU1T1N3eE1UTXVOak0xSURrMExqTTBMREV4TXk0M09EVWdURGswTGpJNE1pd3hNVE11T0RFNElFdzVOQzR5T0RJc01URXpMamd4T0NCYUlFMDNNQzQwTURFc09Ua3VOell4SUV3NU5DNHlPRElzTVRFekxqVTBPU0JNTVRFNUxqQTROQ3c1T1M0eU1qa2dRekV4T1M0Mk15dzVPQzQ1TVRRZ01URTVMamt6TERrNExqYzBJREV5TUM0eE1ERXNPVGd1TmpVMElFd3hNVGt1TmpNMUxEazNMamt4TkNCRE1URTFMamcyTkN3NU5DNHhNamNnTVRFekxqRTJPQ3c1TUM0d016TWdNVEV4TGpZeU1pdzROUzQzTkRZZ1F6RXhNUzR6T0RJc09EVXVNRGM1SURFeE1TNHpPRFlzT0RRdU5EQTBJREV4TVM0Mk16TXNPRE11TnpNNElFTXhNVEl1TkRRNExEZ3hMalV6T1NBeE1UVXVPRE0yTERjNUxqazBNeUF4TVRrdU5qZzVMRGM1TGprME15QkRNVEl3TGpJME5pdzNPUzQ1TkRNZ01USXdMamd3Tml3M09TNDVOellnTVRJeExqTTFOU3c0TUM0d05ESWdRekV5T0M0M05qY3NPREF1T1RNeklERXpOUzQ0TkRZc09ESXVORGczSURFME1pNHpPVFlzT0RRdU5qWXpJRU14TkRNdU1qTXlMRGcwTGpnek9DQXhORE11TmpFeExEZzBMamt4TnlBeE5ETXVOemcyTERnMExqazJOeUJNTVRZNUxqVTJOaXczTUM0d09ETWdUREUwTlM0Mk9EVXNOVFl1TWprMUlFdzNNQzQwTURFc09Ua3VOell4SUV3M01DNDBNREVzT1RrdU56WXhJRm9pSUdsa1BTSkdhV3hzTFRFeUlpQm1hV3hzUFNJak5qQTNSRGhDSWo0OEwzQmhkR2crQ2lBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ1BIQmhkR2dnWkQwaVRURTJOeTR5TXl3eE9DNDVOemtnVERFMk55NHlNeXcyT1M0NE5TQk1NVE01TGprd09TdzROUzQyTWpNZ1RERXpNeTQwTkRnc056RXVORFUySUVNeE16SXVOVE00TERZNUxqUTJJREV6TUM0d01pdzJPUzQzTVRnZ01USTNMamd5TkN3M01pNHdNeUJETVRJMkxqYzJPU3czTXk0eE5DQXhNalV1T1RNeExEYzBMalU0TlNBeE1qVXVORGswTERjMkxqQTBPQ0JNTVRFNUxqQXpOQ3c1Tnk0Mk56WWdURGt4TGpjeE1pd3hNVE11TkRVZ1REa3hMamN4TWl3Mk1pNDFOemtnVERFMk55NHlNeXd4T0M0NU56a2lJR2xrUFNKR2FXeHNMVEV6SWlCbWFXeHNQU0lqUmtaR1JrWkdJajQ4TDNCaGRHZytDaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnUEhCaGRHZ2daRDBpVFRreExqY3hNaXd4TVRNdU5UWTNJRU01TVM0Mk9USXNNVEV6TGpVMk55QTVNUzQyTnpJc01URXpMalUyTVNBNU1TNDJOVE1zTVRFekxqVTFNU0JET1RFdU5qRTRMREV4TXk0MU15QTVNUzQxT1RVc01URXpMalE1TWlBNU1TNDFPVFVzTVRFekxqUTFJRXc1TVM0MU9UVXNOakl1TlRjNUlFTTVNUzQxT1RVc05qSXVOVE0zSURreExqWXhPQ3cyTWk0ME9Ua2dPVEV1TmpVekxEWXlMalEzT0NCTU1UWTNMakUzTWl3eE9DNDROemdnUXpFMk55NHlNRGdzTVRndU9EVTNJREUyTnk0eU5USXNNVGd1T0RVM0lERTJOeTR5T0Rnc01UZ3VPRGM0SUVNeE5qY3VNekkwTERFNExqZzVPU0F4TmpjdU16UTNMREU0TGprek55QXhOamN1TXpRM0xERTRMamszT1NCTU1UWTNMak0wTnl3Mk9TNDROU0JETVRZM0xqTTBOeXcyT1M0NE9URWdNVFkzTGpNeU5DdzJPUzQ1TXlBeE5qY3VNamc0TERZNUxqazFJRXd4TXprdU9UWTNMRGcxTGpjeU5TQkRNVE01TGprek9TdzROUzQzTkRFZ01UTTVMamt3TlN3NE5TNDNORFVnTVRNNUxqZzNNeXc0TlM0M016VWdRekV6T1M0NE5ESXNPRFV1TnpJMUlERXpPUzQ0TVRZc09EVXVOekF5SURFek9TNDRNRElzT0RVdU5qY3lJRXd4TXpNdU16UXlMRGN4TGpVd05DQkRNVE15TGprMk55dzNNQzQyT0RJZ01UTXlMakk0TERjd0xqSXlPU0F4TXpFdU5EQTRMRGN3TGpJeU9TQkRNVE13TGpNeE9TdzNNQzR5TWprZ01USTVMakEwTkN3M01DNDVNVFVnTVRJM0xqa3dPQ3czTWk0eE1TQkRNVEkyTGpnM05DdzNNeTR5SURFeU5pNHdNelFzTnpRdU5qUTNJREV5TlM0Mk1EWXNOell1TURneUlFd3hNVGt1TVRRMkxEazNMamN3T1NCRE1URTVMakV6Tnl3NU55NDNNemdnTVRFNUxqRXhPQ3c1Tnk0M05qSWdNVEU1TGpBNU1pdzVOeTQzTnpjZ1REa3hMamMzTERFeE15NDFOVEVnUXpreExqYzFNaXd4TVRNdU5UWXhJRGt4TGpjek1pd3hNVE11TlRZM0lEa3hMamN4TWl3eE1UTXVOVFkzSUV3NU1TNDNNVElzTVRFekxqVTJOeUJhSUUwNU1TNDRNamtzTmpJdU5qUTNJRXc1TVM0NE1qa3NNVEV6TGpJME9DQk1NVEU0TGprek5TdzVOeTQxT1RnZ1RERXlOUzR6T0RJc056WXVNREUxSUVNeE1qVXVPREkzTERjMExqVXlOU0F4TWpZdU5qWTBMRGN6TGpBNE1TQXhNamN1TnpNNUxEY3hMamsxSUVNeE1qZ3VPVEU1TERjd0xqY3dPQ0F4TXpBdU1qVTJMRFk1TGprNU5pQXhNekV1TkRBNExEWTVMams1TmlCRE1UTXlMak0zTnl3Mk9TNDVPVFlnTVRNekxqRXpPU3czTUM0ME9UY2dNVE16TGpVMU5DdzNNUzQwTURjZ1RERXpPUzQ1TmpFc09EVXVORFU0SUV3eE5qY3VNVEV6TERZNUxqYzRNaUJNTVRZM0xqRXhNeXd4T1M0eE9ERWdURGt4TGpneU9TdzJNaTQyTkRjZ1REa3hMamd5T1N3Mk1pNDJORGNnV2lJZ2FXUTlJa1pwYkd3dE1UUWlJR1pwYkd3OUlpTTJNRGRFT0VJaVBqd3ZjR0YwYUQ0S0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQThjR0YwYUNCa1BTSk5NVFk0TGpVME15d3hPUzR5TVRNZ1RERTJPQzQxTkRNc056QXVNRGd6SUV3eE5ERXVNakl4TERnMUxqZzFOeUJNTVRNMExqYzJNU3czTVM0Mk9Ea2dRekV6TXk0NE5URXNOamt1TmprMElERXpNUzR6TXpNc05qa3VPVFV4SURFeU9TNHhNemNzTnpJdU1qWXpJRU14TWpndU1EZ3lMRGN6TGpNM05DQXhNamN1TWpRMExEYzBMamd4T1NBeE1qWXVPREEzTERjMkxqSTRNaUJNTVRJd0xqTTBOaXc1Tnk0NU1Ea2dURGt6TGpBeU5Td3hNVE11TmpneklFdzVNeTR3TWpVc05qSXVPREV6SUV3eE5qZ3VOVFF6TERFNUxqSXhNeUlnYVdROUlrWnBiR3d0TVRVaUlHWnBiR3c5SWlOR1JrWkdSa1lpUGp3dmNHRjBhRDRLSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBOGNHRjBhQ0JrUFNKTk9UTXVNREkxTERFeE15NDRJRU01TXk0d01EVXNNVEV6TGpnZ09USXVPVGcwTERFeE15NDNPVFVnT1RJdU9UWTJMREV4TXk0M09EVWdRemt5TGprek1Td3hNVE11TnpZMElEa3lMamt3T0N3eE1UTXVOekkxSURreUxqa3dPQ3d4TVRNdU5qZzBJRXc1TWk0NU1EZ3NOakl1T0RFeklFTTVNaTQ1TURnc05qSXVOemN4SURreUxqa3pNU3cyTWk0M016TWdPVEl1T1RZMkxEWXlMamN4TWlCTU1UWTRMalE0TkN3eE9TNHhNVElnUXpFMk9DNDFNaXd4T1M0d09TQXhOamd1TlRZMUxERTVMakE1SURFMk9DNDJNREVzTVRrdU1URXlJRU14TmpndU5qTTNMREU1TGpFek1pQXhOamd1TmpZc01Ua3VNVGN4SURFMk9DNDJOaXd4T1M0eU1USWdUREUyT0M0Mk5pdzNNQzR3T0RNZ1F6RTJPQzQyTml3M01DNHhNalVnTVRZNExqWXpOeXczTUM0eE5qUWdNVFk0TGpZd01TdzNNQzR4T0RRZ1RERTBNUzR5T0N3NE5TNDVOVGdnUXpFME1TNHlOVEVzT0RVdU9UYzFJREUwTVM0eU1UY3NPRFV1T1RjNUlERTBNUzR4T0RZc09EVXVPVFk0SUVNeE5ERXVNVFUwTERnMUxqazFPQ0F4TkRFdU1USTVMRGcxTGprek5pQXhOREV1TVRFMUxEZzFMamt3TmlCTU1UTTBMalkxTlN3M01TNDNNemdnUXpFek5DNHlPQ3czTUM0NU1UVWdNVE16TGpVNU15dzNNQzQwTmpNZ01UTXlMamN5TERjd0xqUTJNeUJETVRNeExqWXpNaXczTUM0ME5qTWdNVE13TGpNMU55dzNNUzR4TkRnZ01USTVMakl5TVN3M01pNHpORFFnUXpFeU9DNHhPRFlzTnpNdU5ETXpJREV5Tnk0ek5EY3NOelF1T0RneElERXlOaTQ1TVRrc056WXVNekUxSUV3eE1qQXVORFU0TERrM0xqazBNeUJETVRJd0xqUTFMRGszTGprM01pQXhNakF1TkRNeExEazNMams1TmlBeE1qQXVOREExTERrNExqQXhJRXc1TXk0d09ETXNNVEV6TGpjNE5TQkRPVE11TURZMUxERXhNeTQzT1RVZ09UTXVNRFExTERFeE15NDRJRGt6TGpBeU5Td3hNVE11T0NCTU9UTXVNREkxTERFeE15NDRJRm9nVFRrekxqRTBNaXcyTWk0NE9ERWdURGt6TGpFME1pd3hNVE11TkRneElFd3hNakF1TWpRNExEazNMamd6TWlCTU1USTJMalk1TlN3M05pNHlORGdnUXpFeU55NHhOQ3czTkM0M05UZ2dNVEkzTGprM055dzNNeTR6TVRVZ01USTVMakExTWl3M01pNHhPRE1nUXpFek1DNHlNekVzTnpBdU9UUXlJREV6TVM0MU5qZ3NOekF1TWpJNUlERXpNaTQzTWl3M01DNHlNamtnUXpFek15NDJPRGtzTnpBdU1qSTVJREV6TkM0ME5USXNOekF1TnpNeElERXpOQzQ0Tmpjc056RXVOalF4SUV3eE5ERXVNamMwTERnMUxqWTVNaUJNTVRZNExqUXlOaXczTUM0d01UWWdUREUyT0M0ME1qWXNNVGt1TkRFMUlFdzVNeTR4TkRJc05qSXVPRGd4SUV3NU15NHhORElzTmpJdU9EZ3hJRm9pSUdsa1BTSkdhV3hzTFRFMklpQm1hV3hzUFNJak5qQTNSRGhDSWo0OEwzQmhkR2crQ2lBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ1BIQmhkR2dnWkQwaVRURTJPUzQ0TERjd0xqQTRNeUJNTVRReUxqUTNPQ3c0TlM0NE5UY2dUREV6Tmk0d01UZ3NOekV1TmpnNUlFTXhNelV1TVRBNExEWTVMalk1TkNBeE16SXVOVGtzTmprdU9UVXhJREV6TUM0ek9UTXNOekl1TWpZeklFTXhNamt1TXpNNUxEY3pMak0zTkNBeE1qZ3VOU3czTkM0NE1Ua2dNVEk0TGpBMk5DdzNOaTR5T0RJZ1RERXlNUzQyTURNc09UY3VPVEE1SUV3NU5DNHlPRElzTVRFekxqWTRNeUJNT1RRdU1qZ3lMRFl5TGpneE15Qk1NVFk1TGpnc01Ua3VNakV6SUV3eE5qa3VPQ3czTUM0d09ETWdXaUlnYVdROUlrWnBiR3d0TVRjaUlHWnBiR3c5SWlOR1FVWkJSa0VpUGp3dmNHRjBhRDRLSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBOGNHRjBhQ0JrUFNKTk9UUXVNamd5TERFeE15NDVNVGNnUXprMExqSTBNU3d4TVRNdU9URTNJRGswTGpJd01Td3hNVE11T1RBM0lEazBMakUyTlN3eE1UTXVPRGcySUVNNU5DNHdPVE1zTVRFekxqZzBOU0E1TkM0d05EZ3NNVEV6TGpjMk55QTVOQzR3TkRnc01URXpMalk0TkNCTU9UUXVNRFE0TERZeUxqZ3hNeUJET1RRdU1EUTRMRFl5TGpjeklEazBMakE1TXl3Mk1pNDJOVElnT1RRdU1UWTFMRFl5TGpZeE1TQk1NVFk1TGpZNE15d3hPUzR3TVNCRE1UWTVMamMxTlN3eE9DNDVOamtnTVRZNUxqZzBOQ3d4T0M0NU5qa2dNVFk1TGpreE55d3hPUzR3TVNCRE1UWTVMams0T1N3eE9TNHdOVElnTVRjd0xqQXpNeXd4T1M0eE1qa2dNVGN3TGpBek15d3hPUzR5TVRJZ1RERTNNQzR3TXpNc056QXVNRGd6SUVNeE56QXVNRE16TERjd0xqRTJOaUF4TmprdU9UZzVMRGN3TGpJME5DQXhOamt1T1RFM0xEY3dMakk0TlNCTU1UUXlMalU1TlN3NE5pNHdOaUJETVRReUxqVXpPQ3c0Tmk0d09USWdNVFF5TGpRMk9TdzROaTR4SURFME1pNDBNRGNzT0RZdU1EZ2dRekUwTWk0ek5EUXNPRFl1TURZZ01UUXlMakk1TXl3NE5pNHdNVFFnTVRReUxqSTJOaXc0TlM0NU5UUWdUREV6TlM0NE1EVXNOekV1TnpnMklFTXhNelV1TkRRMUxEY3dMams1TnlBeE16UXVPREV6TERjd0xqVTRJREV6TXk0NU56Y3NOekF1TlRnZ1F6RXpNaTQ1TWpFc056QXVOVGdnTVRNeExqWTNOaXczTVM0eU5USWdNVE13TGpVMk1pdzNNaTQwTWpRZ1F6RXlPUzQxTkN3M015NDFNREVnTVRJNExqY3hNU3czTkM0NU16RWdNVEk0TGpJNE55dzNOaTR6TkRnZ1RERXlNUzQ0TWpjc09UY3VPVGMySUVNeE1qRXVPREVzT1RndU1ETTBJREV5TVM0M056RXNPVGd1TURneUlERXlNUzQzTWl3NU9DNHhNVElnVERrMExqTTVPQ3d4TVRNdU9EZzJJRU01TkM0ek5qSXNNVEV6TGprd055QTVOQzR6TWpJc01URXpMamt4TnlBNU5DNHlPRElzTVRFekxqa3hOeUJNT1RRdU1qZ3lMREV4TXk0NU1UY2dXaUJOT1RRdU5URTFMRFl5TGprME9DQk1PVFF1TlRFMUxERXhNeTR5TnprZ1RERXlNUzQwTURZc09UY3VOelUwSUV3eE1qY3VPRFFzTnpZdU1qRTFJRU14TWpndU1qa3NOelF1TnpBNElERXlPUzR4TXpjc056TXVNalEzSURFek1DNHlNalFzTnpJdU1UQXpJRU14TXpFdU5ESTFMRGN3TGpnek9DQXhNekl1TnprekxEY3dMakV4TWlBeE16TXVPVGMzTERjd0xqRXhNaUJETVRNMExqazVOU3czTUM0eE1USWdNVE0xTGpjNU5TdzNNQzQyTXpnZ01UTTJMakl6TERjeExqVTVNaUJNTVRReUxqVTROQ3c0TlM0MU1qWWdUREUyT1M0MU5qWXNOamt1T1RRNElFd3hOamt1TlRZMkxERTVMall4TnlCTU9UUXVOVEUxTERZeUxqazBPQ0JNT1RRdU5URTFMRFl5TGprME9DQmFJaUJwWkQwaVJtbHNiQzB4T0NJZ1ptbHNiRDBpSXpZd04wUTRRaUkrUEM5d1lYUm9QZ29nSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUR4d1lYUm9JR1E5SWsweE1Ea3VPRGswTERreUxqazBNeUJNTVRBNUxqZzVOQ3c1TWk0NU5ETWdRekV3T0M0eE1pdzVNaTQ1TkRNZ01UQTJMalkxTXl3NU1pNHlNVGdnTVRBMUxqWTFMRGt3TGpneU15QkRNVEExTGpVNE15dzVNQzQzTXpFZ01UQTFMalU1TXl3NU1DNDJNU0F4TURVdU5qY3pMRGt3TGpVeU9TQkRNVEExTGpjMU15dzVNQzQwTkRnZ01UQTFMamc0TERrd0xqUTBJREV3TlM0NU56UXNPVEF1TlRBMklFTXhNRFl1TnpVMExEa3hMakExTXlBeE1EY3VOamM1TERreExqTXpNeUF4TURndU56STBMRGt4TGpNek15QkRNVEV3TGpBME55dzVNUzR6TXpNZ01URXhMalEzT0N3NU1DNDRPVFFnTVRFeUxqazRMRGt3TGpBeU55QkRNVEU0TGpJNU1TdzROaTQ1TmlBeE1qSXVOakV4TERjNUxqVXdPU0F4TWpJdU5qRXhMRGN6TGpReE5pQkRNVEl5TGpZeE1TdzNNUzQwT0RrZ01USXlMakUyT1N3Mk9TNDROVFlnTVRJeExqTXpNeXcyT0M0Mk9USWdRekV5TVM0eU5qWXNOamd1TmlBeE1qRXVNamMyTERZNExqUTNNeUF4TWpFdU16VTJMRFk0TGpNNU1pQkRNVEl4TGpRek5pdzJPQzR6TVRFZ01USXhMalUyTXl3Mk9DNHlPVGtnTVRJeExqWTFOaXcyT0M0ek5qVWdRekV5TXk0ek1qY3NOamt1TlRNM0lERXlOQzR5TkRjc056RXVOelEySURFeU5DNHlORGNzTnpRdU5UZzBJRU14TWpRdU1qUTNMRGd3TGpneU5pQXhNVGt1T0RJeExEZzRMalEwTnlBeE1UUXVNemd5TERreExqVTROeUJETVRFeUxqZ3dPQ3c1TWk0ME9UVWdNVEV4TGpJNU9DdzVNaTQ1TkRNZ01UQTVMamc1TkN3NU1pNDVORE1nVERFd09TNDRPVFFzT1RJdU9UUXpJRm9nVFRFd05pNDVNalVzT1RFdU5EQXhJRU14TURjdU56TTRMRGt5TGpBMU1pQXhNRGd1TnpRMUxEa3lMakkzT0NBeE1Ea3VPRGt6TERreUxqSTNPQ0JNTVRBNUxqZzVOQ3c1TWk0eU56Z2dRekV4TVM0eU1UVXNPVEl1TWpjNElERXhNaTQyTkRjc09URXVPVFV4SURFeE5DNHhORGdzT1RFdU1EZzBJRU14TVRrdU5EVTVMRGc0TGpBeE55QXhNak11Tnpnc09EQXVOakl4SURFeU15NDNPQ3czTkM0MU1qZ2dRekV5TXk0M09DdzNNaTQxTkRrZ01USXpMak14Tnl3M01DNDVNamtnTVRJeUxqUTFOQ3cyT1M0M05qY2dRekV5TWk0NE5qVXNOekF1T0RBeUlERXlNeTR3Tnprc056SXVNRFF5SURFeU15NHdOemtzTnpNdU5EQXlJRU14TWpNdU1EYzVMRGM1TGpZME5TQXhNVGd1TmpVekxEZzNMakk0TlNBeE1UTXVNakUwTERrd0xqUXlOU0JETVRFeExqWTBMRGt4TGpNek5DQXhNVEF1TVRNc09URXVOelF5SURFd09DNDNNalFzT1RFdU56UXlJRU14TURndU1EZ3pMRGt4TGpjME1pQXhNRGN1TkRneExEa3hMalU1TXlBeE1EWXVPVEkxTERreExqUXdNU0JNTVRBMkxqa3lOU3c1TVM0ME1ERWdXaUlnYVdROUlrWnBiR3d0TVRraUlHWnBiR3c5SWlNMk1EZEVPRUlpUGp3dmNHRjBhRDRLSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBOGNHRjBhQ0JrUFNKTk1URXpMakE1Tnl3NU1DNHlNeUJETVRFNExqUTRNU3c0Tnk0eE1qSWdNVEl5TGpnME5TdzNPUzQxT1RRZ01USXlMamcwTlN3M015NDBNVFlnUXpFeU1pNDRORFVzTnpFdU16WTFJREV5TWk0ek5qSXNOamt1TnpJMElERXlNUzQxTWpJc05qZ3VOVFUySUVNeE1Ua3VOek00TERZM0xqTXdOQ0F4TVRjdU1UUTRMRFkzTGpNMk1pQXhNVFF1TWpZMUxEWTVMakF5TmlCRE1UQTRMamc0TVN3M01pNHhNelFnTVRBMExqVXhOeXczT1M0Mk5qSWdNVEEwTGpVeE55dzROUzQ0TkNCRE1UQTBMalV4Tnl3NE55NDRPVEVnTVRBMUxEZzVMalV6TWlBeE1EVXVPRFFzT1RBdU55QkRNVEEzTGpZeU5DdzVNUzQ1TlRJZ01URXdMakl4TkN3NU1TNDRPVFFnTVRFekxqQTVOeXc1TUM0eU15SWdhV1E5SWtacGJHd3RNakFpSUdacGJHdzlJaU5HUVVaQlJrRWlQand2Y0dGMGFENEtJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0E4Y0dGMGFDQmtQU0pOTVRBNExqY3lOQ3c1TVM0Mk1UUWdUREV3T0M0M01qUXNPVEV1TmpFMElFTXhNRGN1TlRneUxEa3hMall4TkNBeE1EWXVOVFkyTERreExqUXdNU0F4TURVdU56QTFMRGt3TGpjNU55QkRNVEExTGpZNE5DdzVNQzQzT0RNZ01UQTFMalkyTlN3NU1DNDRNVEVnTVRBMUxqWTFMRGt3TGpjNUlFTXhNRFF1TnpVMkxEZzVMalUwTmlBeE1EUXVNamd6TERnM0xqZzBNaUF4TURRdU1qZ3pMRGcxTGpneE55QkRNVEEwTGpJNE15dzNPUzQxTnpVZ01UQTRMamN3T1N3M01TNDVOVE1nTVRFMExqRTBPQ3cyT0M0NE1USWdRekV4TlM0M01qSXNOamN1T1RBMElERXhOeTR5TXpJc05qY3VORFE1SURFeE9DNDJNemdzTmpjdU5EUTVJRU14TVRrdU56Z3NOamN1TkRRNUlERXlNQzQzT1RZc05qY3VOelU0SURFeU1TNDJOVFlzTmpndU16WXlJRU14TWpFdU5qYzRMRFk0TGpNM055QXhNakV1TmprM0xEWTRMak01TnlBeE1qRXVOekV5TERZNExqUXhPQ0JETVRJeUxqWXdOaXcyT1M0Mk5qSWdNVEl6TGpBM09TdzNNUzR6T1NBeE1qTXVNRGM1TERjekxqUXhOU0JETVRJekxqQTNPU3czT1M0Mk5UZ2dNVEU0TGpZMU15dzROeTR4T1RnZ01URXpMakl4TkN3NU1DNHpNemdnUXpFeE1TNDJOQ3c1TVM0eU5EY2dNVEV3TGpFekxEa3hMall4TkNBeE1EZ3VOekkwTERreExqWXhOQ0JNTVRBNExqY3lOQ3c1TVM0Mk1UUWdXaUJOTVRBMkxqQXdOaXc1TUM0MU1EVWdRekV3Tmk0M09DdzVNUzR3TXpjZ01UQTNMalk1TkN3NU1TNHlPREVnTVRBNExqY3lOQ3c1TVM0eU9ERWdRekV4TUM0d05EY3NPVEV1TWpneElERXhNUzQwTnpnc09UQXVPRFk0SURFeE1pNDVPQ3c1TUM0d01ERWdRekV4T0M0eU9URXNPRFl1T1RNMUlERXlNaTQyTVRFc056a3VORGsySURFeU1pNDJNVEVzTnpNdU5EQXpJRU14TWpJdU5qRXhMRGN4TGpRNU5DQXhNakl1TVRjM0xEWTVMamc0SURFeU1TNHpOVFlzTmpndU56RTRJRU14TWpBdU5UZ3lMRFk0TGpFNE5TQXhNVGt1TmpZNExEWTNMamt4T1NBeE1UZ3VOak00TERZM0xqa3hPU0JETVRFM0xqTXhOU3cyTnk0NU1Ua2dNVEUxTGpnNE15dzJPQzR6TmlBeE1UUXVNemd5TERZNUxqSXlOeUJETVRBNUxqQTNNU3czTWk0eU9UTWdNVEEwTGpjMU1TdzNPUzQzTXpNZ01UQTBMamMxTVN3NE5TNDRNallnUXpFd05DNDNOVEVzT0RjdU56TTFJREV3TlM0eE9EVXNPRGt1TXpReklERXdOaTR3TURZc09UQXVOVEExSUV3eE1EWXVNREEyTERrd0xqVXdOU0JhSWlCcFpEMGlSbWxzYkMweU1TSWdabWxzYkQwaUl6WXdOMFE0UWlJK1BDOXdZWFJvUGdvZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lEeHdZWFJvSUdROUlrMHhORGt1TXpFNExEY3VNall5SUV3eE16a3VNek0wTERFMkxqRTBJRXd4TlRVdU1qSTNMREkzTGpFM01TQk1NVFl3TGpneE5pd3lNUzR3TlRrZ1RERTBPUzR6TVRnc055NHlOaklpSUdsa1BTSkdhV3hzTFRJeUlpQm1hV3hzUFNJalJrRkdRVVpCSWo0OEwzQmhkR2crQ2lBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ1BIQmhkR2dnWkQwaVRURTJPUzQyTnpZc01UTXVPRFFnVERFMU9TNDVNamdzTVRrdU5EWTNJRU14TlRZdU1qZzJMREl4TGpVM0lERTFNQzQwTERJeExqVTRJREUwTmk0M09ERXNNVGt1TkRreElFTXhORE11TVRZeExERTNMalF3TWlBeE5ETXVNVGdzTVRRdU1EQXpJREUwTmk0NE1qSXNNVEV1T1NCTU1UVTJMak14Tnl3MkxqSTVNaUJNTVRRNUxqVTRPQ3d5TGpRd055Qk1OamN1TnpVeUxEUTVMalEzT0NCTU1URXpMalkzTlN3M05TNDVPVElnVERFeE5pNDNOVFlzTnpRdU1qRXpJRU14TVRjdU16ZzNMRGN6TGpnME9DQXhNVGN1TmpJMUxEY3pMak14TlNBeE1UY3VNemMwTERjeUxqZ3lNeUJETVRFMUxqQXhOeXcyT0M0eE9URWdNVEUwTGpjNE1TdzJNeTR5TnpjZ01URTJMalk1TVN3MU9DNDFOakVnUXpFeU1pNHpNamtzTkRRdU5qUXhJREUwTVM0eUxETXpMamMwTmlBeE5qVXVNekE1TERNd0xqUTVNU0JETVRjekxqUTNPQ3d5T1M0ek9EZ2dNVGd4TGprNE9Td3lPUzQxTWpRZ01Ua3dMakF4TXl3ek1DNDRPRFVnUXpFNU1DNDROalVzTXpFdU1ETWdNVGt4TGpjNE9Td3pNQzQ0T1RNZ01Ua3lMalF5TERNd0xqVXlPQ0JNTVRrMUxqVXdNU3d5T0M0M05TQk1NVFk1TGpZM05pd3hNeTQ0TkNJZ2FXUTlJa1pwYkd3dE1qTWlJR1pwYkd3OUlpTkdRVVpCUmtFaVBqd3ZjR0YwYUQ0S0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQThjR0YwYUNCa1BTSk5NVEV6TGpZM05TdzNOaTQwTlRrZ1F6RXhNeTQxT1RRc056WXVORFU1SURFeE15NDFNVFFzTnpZdU5ETTRJREV4TXk0ME5ESXNOell1TXprM0lFdzJOeTQxTVRnc05Ea3VPRGd5SUVNMk55NHpOelFzTkRrdU56azVJRFkzTGpJNE5DdzBPUzQyTkRVZ05qY3VNamcxTERRNUxqUTNPQ0JETmpjdU1qZzFMRFE1TGpNeE1TQTJOeTR6TnpRc05Ea3VNVFUzSURZM0xqVXhPU3cwT1M0d056TWdUREUwT1M0ek5UVXNNaTR3TURJZ1F6RTBPUzQwT1Rrc01TNDVNVGtnTVRRNUxqWTNOeXd4TGpreE9TQXhORGt1T0RJeExESXVNREF5SUV3eE5UWXVOVFVzTlM0NE9EY2dRekUxTmk0M056UXNOaTR3TVRjZ01UVTJMamcxTERZdU16QXlJREUxTmk0M01qSXNOaTQxTWpZZ1F6RTFOaTQxT1RJc05pNDNORGtnTVRVMkxqTXdOeXcyTGpneU5pQXhOVFl1TURnekxEWXVOamsySUV3eE5Ea3VOVGczTERJdU9UUTJJRXcyT0M0Mk9EY3NORGt1TkRjNUlFd3hNVE11TmpjMUxEYzFMalExTWlCTU1URTJMalV5TXl3M015NDRNRGdnUXpFeE5pNDNNVFVzTnpNdU5qazNJREV4Tnk0eE5ETXNOek11TXprNUlERXhOaTQ1TlRnc056TXVNRE0xSUVNeE1UUXVOVFF5TERZNExqSTROeUF4TVRRdU15dzJNeTR5TWpFZ01URTJMakkxT0N3MU9DNHpPRFVnUXpFeE9TNHdOalFzTlRFdU5EVTRJREV5TlM0eE5ETXNORFV1TVRReklERXpNeTQ0TkN3ME1DNHhNaklnUXpFME1pNDBPVGNzTXpVdU1USTBJREUxTXk0ek5UZ3NNekV1TmpNeklERTJOUzR5TkRjc016QXVNREk0SUVNeE56TXVORFExTERJNExqa3lNU0F4T0RJdU1ETTNMREk1TGpBMU9DQXhPVEF1TURreExETXdMalF5TlNCRE1Ua3dMamd6TERNd0xqVTFJREU1TVM0Mk5USXNNekF1TkRNeUlERTVNaTR4T0RZc016QXVNVEkwSUV3eE9UUXVOVFkzTERJNExqYzFJRXd4TmprdU5EUXlMREUwTGpJME5DQkRNVFk1TGpJeE9Td3hOQzR4TVRVZ01UWTVMakUwTWl3eE15NDRNamtnTVRZNUxqSTNNU3d4TXk0Mk1EWWdRekUyT1M0MExERXpMak00TWlBeE5qa3VOamcxTERFekxqTXdOaUF4TmprdU9UQTVMREV6TGpRek5TQk1NVGsxTGpjek5Dd3lPQzR6TkRVZ1F6RTVOUzQ0Tnprc01qZ3VOREk0SURFNU5TNDVOamdzTWpndU5UZ3pJREU1TlM0NU5qZ3NNamd1TnpVZ1F6RTVOUzQ1Tmpnc01qZ3VPVEUySURFNU5TNDROemtzTWprdU1EY3hJREU1TlM0M016UXNNamt1TVRVMElFd3hPVEl1TmpVekxETXdMamt6TXlCRE1Ua3hMamt6TWl3ek1TNHpOU0F4T1RBdU9Ea3NNekV1TlRBNElERTRPUzQ1TXpVc016RXVNelEySUVNeE9ERXVPVGN5TERJNUxqazVOU0F4TnpNdU5EYzRMREk1TGpnMklERTJOUzR6TnpJc016QXVPVFUwSUVNeE5UTXVOakF5TERNeUxqVTBNeUF4TkRJdU9EWXNNelV1T1RreklERXpOQzR6TURjc05EQXVPVE14SUVNeE1qVXVOemt6TERRMUxqZzBOeUF4TVRrdU9EVXhMRFV5TGpBd05DQXhNVGN1TVRJMExEVTRMamN6TmlCRE1URTFMakkzTERZekxqTXhOQ0F4TVRVdU5UQXhMRFk0TGpFeE1pQXhNVGN1Tnprc056SXVOakV4SUVNeE1UZ3VNVFlzTnpNdU16TTJJREV4Tnk0NE5EVXNOelF1TVRJMElERXhOaTQ1T1N3M05DNDJNVGNnVERFeE15NDVNRGtzTnpZdU16azNJRU14TVRNdU9ETTJMRGMyTGpRek9DQXhNVE11TnpVMkxEYzJMalExT1NBeE1UTXVOamMxTERjMkxqUTFPU0lnYVdROUlrWnBiR3d0TWpRaUlHWnBiR3c5SWlNME5UVkJOalFpUGp3dmNHRjBhRDRLSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBOGNHRjBhQ0JrUFNKTk1UVXpMak14Tml3eU1TNHlOemtnUXpFMU1DNDVNRE1zTWpFdU1qYzVJREUwT0M0ME9UVXNNakF1TnpVeElERTBOaTQyTmpRc01Ua3VOamt6SUVNeE5EUXVPRFEyTERFNExqWTBOQ0F4TkRNdU9EUTBMREUzTGpJek1pQXhORE11T0RRMExERTFMamN4T0NCRE1UUXpMamcwTkN3eE5DNHhPVEVnTVRRMExqZzJMREV5TGpjMk15QXhORFl1TnpBMUxERXhMalk1T0NCTU1UVTJMakU1T0N3MkxqQTVNU0JETVRVMkxqTXdPU3cyTGpBeU5TQXhOVFl1TkRVeUxEWXVNRFl5SURFMU5pNDFNVGdzTmk0eE56TWdRekUxTmk0MU9ETXNOaTR5T0RRZ01UVTJMalUwTnl3MkxqUXlOeUF4TlRZdU5ETTJMRFl1TkRreklFd3hORFl1T1RRc01USXVNVEF5SUVNeE5EVXVNalEwTERFekxqQTRNU0F4TkRRdU16RXlMREUwTGpNMk5TQXhORFF1TXpFeUxERTFMamN4T0NCRE1UUTBMak14TWl3eE55NHdOVGdnTVRRMUxqSXpMREU0TGpNeU5pQXhORFl1T0RrM0xERTVMakk0T1NCRE1UVXdMalEwTml3eU1TNHpNemdnTVRVMkxqSTBMREl4TGpNeU55QXhOVGt1T0RFeExERTVMakkyTlNCTU1UWTVMalUxT1N3eE15NDJNemNnUXpFMk9TNDJOeXd4TXk0MU56TWdNVFk1TGpneE15d3hNeTQyTVRFZ01UWTVMamczT0N3eE15NDNNak1nUXpFMk9TNDVORE1zTVRNdU9ETTBJREUyT1M0NU1EUXNNVE11T1RjM0lERTJPUzQzT1RNc01UUXVNRFF5SUV3eE5qQXVNRFExTERFNUxqWTNJRU14TlRndU1UZzNMREl3TGpjME1pQXhOVFV1TnpRNUxESXhMakkzT1NBeE5UTXVNekUyTERJeExqSTNPU0lnYVdROUlrWnBiR3d0TWpVaUlHWnBiR3c5SWlNMk1EZEVPRUlpUGp3dmNHRjBhRDRLSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBOGNHRjBhQ0JrUFNKTk1URXpMalkzTlN3M05TNDVPVElnVERZM0xqYzJNaXcwT1M0ME9EUWlJR2xrUFNKR2FXeHNMVEkySWlCbWFXeHNQU0lqTkRVMVFUWTBJajQ4TDNCaGRHZytDaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnUEhCaGRHZ2daRDBpVFRFeE15NDJOelVzTnpZdU16UXlJRU14TVRNdU5qRTFMRGMyTGpNME1pQXhNVE11TlRVMUxEYzJMak15TnlBeE1UTXVOU3czTmk0eU9UVWdURFkzTGpVNE55dzBPUzQzT0RjZ1F6WTNMalF4T1N3ME9TNDJPU0EyTnk0ek5qSXNORGt1TkRjMklEWTNMalExT1N3ME9TNHpNRGtnUXpZM0xqVTFOaXcwT1M0eE5ERWdOamN1Tnpjc05Ea3VNRGd6SURZM0xqa3pOeXcwT1M0eE9DQk1NVEV6TGpnMUxEYzFMalk0T0NCRE1URTBMakF4T0N3M05TNDNPRFVnTVRFMExqQTNOU3czTmlBeE1UTXVPVGM0TERjMkxqRTJOeUJETVRFekxqa3hOQ3czTmk0eU56a2dNVEV6TGpjNU5pdzNOaTR6TkRJZ01URXpMalkzTlN3M05pNHpORElpSUdsa1BTSkdhV3hzTFRJM0lpQm1hV3hzUFNJak5EVTFRVFkwSWo0OEwzQmhkR2crQ2lBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ1BIQmhkR2dnWkQwaVRUWTNMamMyTWl3ME9TNDBPRFFnVERZM0xqYzJNaXd4TURNdU5EZzFJRU0yTnk0M05qSXNNVEEwTGpVM05TQTJPQzQxTXpJc01UQTFMamt3TXlBMk9TNDBPRElzTVRBMkxqUTFNaUJNTVRFeExqazFOU3d4TXpBdU9UY3pJRU14TVRJdU9UQTFMREV6TVM0MU1qSWdNVEV6TGpZM05Td3hNekV1TURneklERXhNeTQyTnpVc01USTVMams1TXlCTU1URXpMalkzTlN3M05TNDVPVElpSUdsa1BTSkdhV3hzTFRJNElpQm1hV3hzUFNJalJrRkdRVVpCSWo0OEwzQmhkR2crQ2lBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ1BIQmhkR2dnWkQwaVRURXhNaTQzTWpjc01UTXhMalUyTVNCRE1URXlMalF6TERFek1TNDFOakVnTVRFeUxqRXdOeXd4TXpFdU5EWTJJREV4TVM0M09Dd3hNekV1TWpjMklFdzJPUzR6TURjc01UQTJMamMxTlNCRE5qZ3VNalEwTERFd05pNHhORElnTmpjdU5ERXlMREV3TkM0M01EVWdOamN1TkRFeUxERXdNeTQwT0RVZ1REWTNMalF4TWl3ME9TNDBPRFFnUXpZM0xqUXhNaXcwT1M0eU9TQTJOeTQxTmprc05Ea3VNVE0wSURZM0xqYzJNaXcwT1M0eE16UWdRelkzTGprMU5pdzBPUzR4TXpRZ05qZ3VNVEV6TERRNUxqSTVJRFk0TGpFeE15dzBPUzQwT0RRZ1REWTRMakV4TXl3eE1ETXVORGcxSUVNMk9DNHhNVE1zTVRBMExqUTBOU0EyT0M0NE1pd3hNRFV1TmpZMUlEWTVMalkxTnl3eE1EWXVNVFE0SUV3eE1USXVNVE1zTVRNd0xqWTNJRU14TVRJdU5EYzBMREV6TUM0NE5qZ2dNVEV5TGpjNU1Td3hNekF1T1RFeklERXhNeXd4TXpBdU56a3lJRU14TVRNdU1qQTJMREV6TUM0Mk56TWdNVEV6TGpNeU5Td3hNekF1TXpneElERXhNeTR6TWpVc01USTVMams1TXlCTU1URXpMak15TlN3M05TNDVPVElnUXpFeE15NHpNalVzTnpVdU56azRJREV4TXk0ME9ESXNOelV1TmpReElERXhNeTQyTnpVc056VXVOalF4SUVNeE1UTXVPRFk1TERjMUxqWTBNU0F4TVRRdU1ESTFMRGMxTGpjNU9DQXhNVFF1TURJMUxEYzFMams1TWlCTU1URTBMakF5TlN3eE1qa3VPVGt6SUVNeE1UUXVNREkxTERFek1DNDJORGdnTVRFekxqYzROaXd4TXpFdU1UUTNJREV4TXk0ek5Td3hNekV1TXprNUlFTXhNVE11TVRZeUxERXpNUzQxTURjZ01URXlMamsxTWl3eE16RXVOVFl4SURFeE1pNDNNamNzTVRNeExqVTJNU0lnYVdROUlrWnBiR3d0TWpraUlHWnBiR3c5SWlNME5UVkJOalFpUGp3dmNHRjBhRDRLSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBOGNHRjBhQ0JrUFNKTk1URXlMamcyTERRd0xqVXhNaUJETVRFeUxqZzJMRFF3TGpVeE1pQXhNVEl1T0RZc05EQXVOVEV5SURFeE1pNDROVGtzTkRBdU5URXlJRU14TVRBdU5UUXhMRFF3TGpVeE1pQXhNRGd1TXpZc016a3VPVGtnTVRBMkxqY3hOeXd6T1M0d05ERWdRekV3TlM0d01USXNNemd1TURVM0lERXdOQzR3TnpRc016WXVOekkySURFd05DNHdOelFzTXpVdU1qa3lJRU14TURRdU1EYzBMRE16TGpnME55QXhNRFV1TURJMkxETXlMalV3TVNBeE1EWXVOelUwTERNeExqVXdOQ0JNTVRFNExqYzVOU3d5TkM0MU5URWdRekV5TUM0ME5qTXNNak11TlRnNUlERXlNaTQyTmprc01qTXVNRFU0SURFeU5TNHdNRGNzTWpNdU1EVTRJRU14TWpjdU16STFMREl6TGpBMU9DQXhNamt1TlRBMkxESXpMalU0TVNBeE16RXVNVFVzTWpRdU5UTWdRekV6TWk0NE5UUXNNalV1TlRFMElERXpNeTQzT1RNc01qWXVPRFExSURFek15NDNPVE1zTWpndU1qYzRJRU14TXpNdU56a3pMREk1TGpjeU5DQXhNekl1T0RReExETXhMakEyT1NBeE16RXVNVEV6TERNeUxqQTJOeUJNTVRFNUxqQTNNU3d6T1M0d01Ua2dRekV4Tnk0ME1ETXNNemt1T1RneUlERXhOUzR4T1Rjc05EQXVOVEV5SURFeE1pNDROaXcwTUM0MU1USWdUREV4TWk0NE5pdzBNQzQxTVRJZ1dpQk5NVEkxTGpBd055d3lNeTQzTlRrZ1F6RXlNaTQzT1N3eU15NDNOVGtnTVRJd0xqY3dPU3d5TkM0eU5UWWdNVEU1TGpFME5pd3lOUzR4TlRnZ1RERXdOeTR4TURRc016SXVNVEVnUXpFd05TNDJNRElzTXpJdU9UYzRJREV3TkM0M056UXNNelF1TVRBNElERXdOQzQzTnpRc016VXVNamt5SUVNeE1EUXVOemMwTERNMkxqUTJOU0F4TURVdU5UZzVMRE0zTGpVNE1TQXhNRGN1TURZM0xETTRMalF6TkNCRE1UQTRMall3TlN3ek9TNHpNak1nTVRFd0xqWTJNeXd6T1M0NE1USWdNVEV5TGpnMU9Td3pPUzQ0TVRJZ1RERXhNaTQ0Tml3ek9TNDRNVElnUXpFeE5TNHdOellzTXprdU9ERXlJREV4Tnk0eE5UZ3NNemt1TXpFMUlERXhPQzQzTWpFc016Z3VOREV6SUV3eE16QXVOell5TERNeExqUTJJRU14TXpJdU1qWTBMRE13TGpVNU15QXhNek11TURreUxESTVMalEyTXlBeE16TXVNRGt5TERJNExqSTNPQ0JETVRNekxqQTVNaXd5Tnk0eE1EWWdNVE15TGpJM09Dd3lOUzQ1T1NBeE16QXVPQ3d5TlM0eE16WWdRekV5T1M0eU5qRXNNalF1TWpRNElERXlOeTR5TURRc01qTXVOelU1SURFeU5TNHdNRGNzTWpNdU56VTVJRXd4TWpVdU1EQTNMREl6TGpjMU9TQmFJaUJwWkQwaVJtbHNiQzB6TUNJZ1ptbHNiRDBpSXpZd04wUTRRaUkrUEM5d1lYUm9QZ29nSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUR4d1lYUm9JR1E5SWsweE5qVXVOak1zTVRZdU1qRTVJRXd4TlRrdU9EazJMREU1TGpVeklFTXhOVFl1TnpJNUxESXhMak0xT0NBeE5URXVOakVzTWpFdU16WTNJREUwT0M0ME5qTXNNVGt1TlRVZ1F6RTBOUzR6TVRZc01UY3VOek16SURFME5TNHpNeklzTVRRdU56YzRJREUwT0M0ME9Ua3NNVEl1T1RRNUlFd3hOVFF1TWpNekxEa3VOak01SUV3eE5qVXVOak1zTVRZdU1qRTVJaUJwWkQwaVJtbHNiQzB6TVNJZ1ptbHNiRDBpSTBaQlJrRkdRU0krUEM5d1lYUm9QZ29nSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUR4d1lYUm9JR1E5SWsweE5UUXVNak16TERFd0xqUTBPQ0JNTVRZMExqSXlPQ3d4Tmk0eU1Ua2dUREUxT1M0MU5EWXNNVGd1T1RJeklFTXhOVGd1TVRFeUxERTVMamMxSURFMU5pNHhPVFFzTWpBdU1qQTJJREUxTkM0eE5EY3NNakF1TWpBMklFTXhOVEl1TVRFNExESXdMakl3TmlBeE5UQXVNakkwTERFNUxqYzFOeUF4TkRndU9ERTBMREU0TGprME15QkRNVFEzTGpVeU5Dd3hPQzR4T1RrZ01UUTJMamd4TkN3eE55NHlORGtnTVRRMkxqZ3hOQ3d4Tmk0eU5qa2dRekUwTmk0NE1UUXNNVFV1TWpjNElERTBOeTQxTXpjc01UUXVNekUwSURFME9DNDROU3d4TXk0MU5UWWdUREUxTkM0eU16TXNNVEF1TkRRNElFMHhOVFF1TWpNekxEa3VOak01SUV3eE5EZ3VORGs1TERFeUxqazBPU0JETVRRMUxqTXpNaXd4TkM0M056Z2dNVFExTGpNeE5pd3hOeTQzTXpNZ01UUTRMalEyTXl3eE9TNDFOU0JETVRVd0xqQXpNU3d5TUM0ME5UVWdNVFV5TGpBNE5pd3lNQzQ1TURjZ01UVTBMakUwTnl3eU1DNDVNRGNnUXpFMU5pNHlNalFzTWpBdU9UQTNJREUxT0M0ek1EWXNNakF1TkRRM0lERTFPUzQ0T1RZc01Ua3VOVE1nVERFMk5TNDJNeXd4Tmk0eU1Ua2dUREUxTkM0eU16TXNPUzQyTXpraUlHbGtQU0pHYVd4c0xUTXlJaUJtYVd4c1BTSWpOakEzUkRoQ0lqNDhMM0JoZEdnK0NpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdQSEJoZEdnZ1pEMGlUVEUwTlM0ME5EVXNOekl1TmpZM0lFd3hORFV1TkRRMUxEY3lMalkyTnlCRE1UUXpMalkzTWl3M01pNDJOamNnTVRReUxqSXdOQ3czTVM0NE1UY2dNVFF4TGpJd01pdzNNQzQwTWpJZ1F6RTBNUzR4TXpVc056QXVNek1nTVRReExqRTBOU3czTUM0eE5EY2dNVFF4TGpJeU5TdzNNQzR3TmpZZ1F6RTBNUzR6TURVc05qa3VPVGcxSURFME1TNDBNeklzTmprdU9UUTJJREUwTVM0MU1qVXNOekF1TURFeElFTXhOREl1TXpBMkxEY3dMalUxT1NBeE5ETXVNak14TERjd0xqZ3lNeUF4TkRRdU1qYzJMRGN3TGpneU1pQkRNVFExTGpVNU9DdzNNQzQ0TWpJZ01UUTNMakF6TERjd0xqTTNOaUF4TkRndU5UTXlMRFk1TGpVd09TQkRNVFV6TGpnME1pdzJOaTQwTkRNZ01UVTRMakUyTXl3MU9DNDVPRGNnTVRVNExqRTJNeXcxTWk0NE9UUWdRekUxT0M0eE5qTXNOVEF1T1RZM0lERTFOeTQzTWpFc05Ea3VNek15SURFMU5pNDRPRFFzTkRndU1UWTRJRU14TlRZdU9ERTRMRFE0TGpBM05pQXhOVFl1T0RJNExEUTNMamswT0NBeE5UWXVPVEE0TERRM0xqZzJOeUJETVRVMkxqazRPQ3cwTnk0M09EWWdNVFUzTGpFeE5DdzBOeTQzTnpRZ01UVTNMakl3T0N3ME55NDROQ0JETVRVNExqZzNPQ3cwT1M0d01USWdNVFU1TGpjNU9DdzFNUzR5TWlBeE5Ua3VOems0TERVMExqQTFPU0JETVRVNUxqYzVPQ3cyTUM0ek1ERWdNVFUxTGpNM015dzJPQzR3TkRZZ01UUTVMamt6TXl3M01TNHhPRFlnUXpFME9DNHpOaXczTWk0d09UUWdNVFEyTGpnMUxEY3lMalkyTnlBeE5EVXVORFExTERjeUxqWTJOeUJNTVRRMUxqUTBOU3czTWk0Mk5qY2dXaUJOTVRReUxqUTNOaXczTVNCRE1UUXpMakk1TERjeExqWTFNU0F4TkRRdU1qazJMRGN5TGpBd01pQXhORFV1TkRRMUxEY3lMakF3TWlCRE1UUTJMamMyTnl3M01pNHdNRElnTVRRNExqRTVPQ3czTVM0MU5TQXhORGt1Tnl3M01DNDJPRElnUXpFMU5TNHdNU3cyTnk0Mk1UY2dNVFU1TGpNek1TdzJNQzR4TlRrZ01UVTVMak16TVN3MU5DNHdOalVnUXpFMU9TNHpNekVzTlRJdU1EZzFJREUxT0M0NE5qZ3NOVEF1TkRNMUlERTFPQzR3TURZc05Ea3VNamN5SUVNeE5UZ3VOREUzTERVd0xqTXdOeUF4TlRndU5qTXNOVEV1TlRNeUlERTFPQzQyTXl3MU1pNDRPVElnUXpFMU9DNDJNeXcxT1M0eE16UWdNVFUwTGpJd05TdzJOaTQzTmpjZ01UUTRMamMyTlN3Mk9TNDVNRGNnUXpFME55NHhPVElzTnpBdU9ERTJJREUwTlM0Mk9ERXNOekV1TWpneklERTBOQzR5TnpZc056RXVNamd6SUVNeE5ETXVOak0wTERjeExqSTRNeUF4TkRNdU1ETXpMRGN4TGpFNU1pQXhOREl1TkRjMkxEY3hJRXd4TkRJdU5EYzJMRGN4SUZvaUlHbGtQU0pHYVd4c0xUTXpJaUJtYVd4c1BTSWpOakEzUkRoQ0lqNDhMM0JoZEdnK0NpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdQSEJoZEdnZ1pEMGlUVEUwT0M0Mk5EZ3NOamt1TnpBMElFTXhOVFF1TURNeUxEWTJMalU1TmlBeE5UZ3VNemsyTERVNUxqQTJPQ0F4TlRndU16azJMRFV5TGpnNU1TQkRNVFU0TGpNNU5pdzFNQzQ0TXprZ01UVTNMamt4TXl3ME9TNHhPVGdnTVRVM0xqQTNOQ3cwT0M0d015QkRNVFUxTGpJNE9TdzBOaTQzTnpnZ01UVXlMalk1T1N3ME5pNDRNellnTVRRNUxqZ3hOaXcwT0M0MU1ERWdRekUwTkM0ME16TXNOVEV1TmpBNUlERTBNQzR3Tmpnc05Ua3VNVE0zSURFME1DNHdOamdzTmpVdU16RTBJRU14TkRBdU1EWTRMRFkzTGpNMk5TQXhOREF1TlRVeUxEWTVMakF3TmlBeE5ERXVNemt4TERjd0xqRTNOQ0JETVRRekxqRTNOaXczTVM0ME1qY2dNVFExTGpjMk5TdzNNUzR6TmprZ01UUTRMalkwT0N3Mk9TNDNNRFFpSUdsa1BTSkdhV3hzTFRNMElpQm1hV3hzUFNJalJrRkdRVVpCSWo0OEwzQmhkR2crQ2lBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ1BIQmhkR2dnWkQwaVRURTBOQzR5TnpZc056RXVNamMySUV3eE5EUXVNamMyTERjeExqSTNOaUJETVRRekxqRXpNeXczTVM0eU56WWdNVFF5TGpFeE9DdzNNQzQ1TmprZ01UUXhMakkxTnl3M01DNHpOalVnUXpFME1TNHlNellzTnpBdU16VXhJREUwTVM0eU1UY3NOekF1TXpNeUlERTBNUzR5TURJc056QXVNekV4SUVNeE5EQXVNekEzTERZNUxqQTJOeUF4TXprdU9ETTFMRFkzTGpNek9TQXhNemt1T0RNMUxEWTFMak14TkNCRE1UTTVMamd6TlN3MU9TNHdOek1nTVRRMExqSTJMRFV4TGpRek9TQXhORGt1Tnl3ME9DNHlPVGdnUXpFMU1TNHlOek1zTkRjdU16a2dNVFV5TGpjNE5DdzBOaTQ1TWprZ01UVTBMakU0T1N3ME5pNDVNamtnUXpFMU5TNHpNeklzTkRZdU9USTVJREUxTmk0ek5EY3NORGN1TWpNMklERTFOeTR5TURnc05EY3VPRE01SUVNeE5UY3VNakk1TERRM0xqZzFOQ0F4TlRjdU1qUTRMRFEzTGpnM015QXhOVGN1TWpZekxEUTNMamc1TkNCRE1UVTRMakUxTnl3ME9TNHhNemdnTVRVNExqWXpMRFV3TGpnMk5TQXhOVGd1TmpNc05USXVPRGt4SUVNeE5UZ3VOak1zTlRrdU1UTXlJREUxTkM0eU1EVXNOall1TnpZMklERTBPQzQzTmpVc05qa3VPVEEzSUVNeE5EY3VNVGt5TERjd0xqZ3hOU0F4TkRVdU5qZ3hMRGN4TGpJM05pQXhORFF1TWpjMkxEY3hMakkzTmlCTU1UUTBMakkzTml3M01TNHlOellnV2lCTk1UUXhMalUxT0N3M01DNHhNRFFnUXpFME1pNHpNekVzTnpBdU5qTTNJREUwTXk0eU5EVXNOekV1TURBMUlERTBOQzR5TnpZc056RXVNREExSUVNeE5EVXVOVGs0TERjeExqQXdOU0F4TkRjdU1ETXNOekF1TkRZM0lERTBPQzQxTXpJc05qa3VOaUJETVRVekxqZzBNaXcyTmk0MU16UWdNVFU0TGpFMk15dzFPUzR3TXpNZ01UVTRMakUyTXl3MU1pNDVNemtnUXpFMU9DNHhOak1zTlRFdU1ETXhJREUxTnk0M01qa3NORGt1TXpnMUlERTFOaTQ1TURjc05EZ3VNakl6SUVNeE5UWXVNVE16TERRM0xqWTVNU0F4TlRVdU1qRTVMRFEzTGpRd09TQXhOVFF1TVRnNUxEUTNMalF3T1NCRE1UVXlMamcyTnl3ME55NDBNRGtnTVRVeExqUXpOU3cwTnk0NE5ESWdNVFE1TGprek15dzBPQzQzTURrZ1F6RTBOQzQyTWpNc05URXVOemMxSURFME1DNHpNRElzTlRrdU1qY3pJREUwTUM0ek1ESXNOalV1TXpZMklFTXhOREF1TXpBeUxEWTNMakkzTmlBeE5EQXVOek0yTERZNExqazBNaUF4TkRFdU5UVTRMRGN3TGpFd05DQk1NVFF4TGpVMU9DdzNNQzR4TURRZ1dpSWdhV1E5SWtacGJHd3RNelVpSUdacGJHdzlJaU0yTURkRU9FSWlQand2Y0dGMGFENEtJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0E4Y0dGMGFDQmtQU0pOTVRVd0xqY3lMRFkxTGpNMk1TQk1NVFV3TGpNMU55dzJOUzR3TmpZZ1F6RTFNUzR4TkRjc05qUXVNRGt5SURFMU1TNDROamtzTmpNdU1EUWdNVFV5TGpVd05TdzJNUzQ1TXpnZ1F6RTFNeTR6TVRNc05qQXVOVE01SURFMU15NDVOemdzTlRrdU1EWTNJREUxTkM0ME9ESXNOVGN1TlRZeklFd3hOVFF1T1RJMUxEVTNMamN4TWlCRE1UVTBMalF4TWl3MU9TNHlORFVnTVRVekxqY3pNeXcyTUM0M05EVWdNVFV5TGpreExEWXlMakUzTWlCRE1UVXlMakkyTWl3Mk15NHlPVFVnTVRVeExqVXlOU3cyTkM0ek5qZ2dNVFV3TGpjeUxEWTFMak0yTVNJZ2FXUTlJa1pwYkd3dE16WWlJR1pwYkd3OUlpTTJNRGRFT0VJaVBqd3ZjR0YwYUQ0S0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQThjR0YwYUNCa1BTSk5NVEUxTGpreE55dzROQzQxTVRRZ1RERXhOUzQxTlRRc09EUXVNaklnUXpFeE5pNHpORFFzT0RNdU1qUTFJREV4Tnk0d05qWXNPREl1TVRrMElERXhOeTQzTURJc09ERXVNRGt5SUVNeE1UZ3VOVEVzTnprdU5qa3lJREV4T1M0eE56VXNOemd1TWpJZ01URTVMalkzT0N3M05pNDNNVGNnVERFeU1DNHhNakVzTnpZdU9EWTFJRU14TVRrdU5qQTRMRGM0TGpNNU9DQXhNVGd1T1RNc056a3VPRGs1SURFeE9DNHhNRFlzT0RFdU16STJJRU14TVRjdU5EVTRMRGd5TGpRME9DQXhNVFl1TnpJeUxEZ3pMalV5TVNBeE1UVXVPVEUzTERnMExqVXhOQ0lnYVdROUlrWnBiR3d0TXpjaUlHWnBiR3c5SWlNMk1EZEVPRUlpUGp3dmNHRjBhRDRLSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBOGNHRjBhQ0JrUFNKTk1URTBMREV6TUM0ME56WWdUREV4TkN3eE16QXVNREE0SUV3eE1UUXNOell1TURVeUlFd3hNVFFzTnpVdU5UZzBJRXd4TVRRc056WXVNRFV5SUV3eE1UUXNNVE13TGpBd09DQk1NVEUwTERFek1DNDBOellpSUdsa1BTSkdhV3hzTFRNNElpQm1hV3hzUFNJak5qQTNSRGhDSWo0OEwzQmhkR2crQ2lBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0E4TDJjK0NpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBOFp5QnBaRDBpU1cxd2IzSjBaV1F0VEdGNVpYSnpMVU52Y0hraUlIUnlZVzV6Wm05eWJUMGlkSEpoYm5Oc1lYUmxLRFl5TGpBd01EQXdNQ3dnTUM0d01EQXdNREFwSWlCemEyVjBZMmc2ZEhsd1pUMGlUVk5UYUdGd1pVZHliM1Z3SWo0S0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQThjR0YwYUNCa1BTSk5NVGt1T0RJeUxETTNMalEzTkNCRE1Ua3VPRE01TERNM0xqTXpPU0F4T1M0M05EY3NNemN1TVRrMElERTVMalUxTlN3ek55NHdPRElnUXpFNUxqSXlPQ3d6Tmk0NE9UUWdNVGd1TnpJNUxETTJMamczTWlBeE9DNDBORFlzTXpjdU1ETTNJRXd4TWk0ME16UXNOREF1TlRBNElFTXhNaTR6TURNc05EQXVOVGcwSURFeUxqSTBMRFF3TGpZNE5pQXhNaTR5TkRNc05EQXVOemt6SUVNeE1pNHlORFVzTkRBdU9USTFJREV5TGpJME5TdzBNUzR5TlRRZ01USXVNalExTERReExqTTNNU0JNTVRJdU1qUTFMRFF4TGpReE5DQk1NVEl1TWpNNExEUXhMalUwTWlCRE9DNHhORGdzTkRNdU9EZzNJRFV1TmpRM0xEUTFMak15TVNBMUxqWTBOeXcwTlM0ek1qRWdRelV1TmpRMkxEUTFMak15TVNBekxqVTNMRFEyTGpNMk55QXlMamcyTERVd0xqVXhNeUJETWk0NE5pdzFNQzQxTVRNZ01TNDVORGdzTlRjdU5EYzBJREV1T1RZeUxEY3dMakkxT0NCRE1TNDVOemNzT0RJdU9ESTRJREl1TlRZNExEZzNMak15T0NBekxqRXlPU3c1TVM0Mk1Ea2dRek11TXpRNUxEa3pMakk1TXlBMkxqRXpMRGt6TGpjek5DQTJMakV6TERrekxqY3pOQ0JETmk0ME5qRXNPVE11TnpjMElEWXVPREk0TERrekxqY3dOeUEzTGpJeExEa3pMalE0TmlCTU9ESXVORGd6TERRNUxqa3pOU0JET0RRdU1qa3hMRFE0TGpnMk5pQTROUzR4TlN3ME5pNHlNVFlnT0RVdU5UTTVMRFF6TGpZMU1TQkRPRFl1TnpVeUxETTFMalkyTVNBNE55NHlNVFFzTVRBdU5qY3pJRGcxTGpJMk5Dd3pMamMzTXlCRE9EVXVNRFk0TERNdU1EZ2dPRFF1TnpVMExESXVOamtnT0RRdU16azJMREl1TkRreElFdzRNaTR6TVN3eExqY3dNU0JET0RFdU5UZ3pMREV1TnpJNUlEZ3dMamc1TkN3eUxqRTJPQ0E0TUM0M056WXNNaTR5TXpZZ1F6Z3dMall6Tml3eUxqTXhOeUEwTVM0NE1EY3NNalF1TlRnMUlESXdMakF6TWl3ek55NHdOeklnVERFNUxqZ3lNaXd6Tnk0ME56UWlJR2xrUFNKR2FXeHNMVEVpSUdacGJHdzlJaU5HUmtaR1JrWWlQand2Y0dGMGFENEtJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0E4Y0dGMGFDQmtQU0pOT0RJdU16RXhMREV1TnpBeElFdzROQzR6T1RZc01pNDBPVEVnUXpnMExqYzFOQ3d5TGpZNUlEZzFMakEyT0N3ekxqQTRJRGcxTGpJMk5Dd3pMamMzTXlCRE9EY3VNakV6TERFd0xqWTNNeUE0Tmk0M05URXNNelV1TmpZZ09EVXVOVE01TERRekxqWTFNU0JET0RVdU1UUTVMRFEyTGpJeE5pQTROQzR5T1N3ME9DNDROallnT0RJdU5EZ3pMRFE1TGprek5TQk1OeTR5TVN3NU15NDBPRFlnUXpZdU9EazNMRGt6TGpZMk55QTJMalU1TlN3NU15NDNORFFnTmk0ek1UUXNPVE11TnpRMElFdzJMakV6TVN3NU15NDNNek1nUXpZdU1UTXhMRGt6TGpjek5DQXpMak0wT1N3NU15NHlPVE1nTXk0eE1qZ3NPVEV1TmpBNUlFTXlMalUyT0N3NE55NHpNamNnTVM0NU56Y3NPREl1T0RJNElERXVPVFl6TERjd0xqSTFPQ0JETVM0NU5EZ3NOVGN1TkRjMElESXVPRFlzTlRBdU5URXpJREl1T0RZc05UQXVOVEV6SUVNekxqVTNMRFEyTGpNMk55QTFMalkwTnl3ME5TNHpNakVnTlM0Mk5EY3NORFV1TXpJeElFTTFMalkwTnl3ME5TNHpNakVnT0M0eE5EZ3NORE11T0RnM0lERXlMakl6T0N3ME1TNDFORElnVERFeUxqSTBOU3cwTVM0ME1UUWdUREV5TGpJME5TdzBNUzR6TnpFZ1F6RXlMakkwTlN3ME1TNHlOVFFnTVRJdU1qUTFMRFF3TGpreU5TQXhNaTR5TkRNc05EQXVOemt6SUVNeE1pNHlOQ3cwTUM0Mk9EWWdNVEl1TXpBeUxEUXdMalU0TXlBeE1pNDBNelFzTkRBdU5UQTRJRXd4T0M0ME5EWXNNemN1TURNMklFTXhPQzQxTnpRc016WXVPVFl5SURFNExqYzBOaXd6Tmk0NU1qWWdNVGd1T1RJM0xETTJMamt5TmlCRE1Ua3VNVFExTERNMkxqa3lOaUF4T1M0ek56WXNNell1T1RjNUlERTVMalUxTkN3ek55NHdPRElnUXpFNUxqYzBOeXd6Tnk0eE9UUWdNVGt1T0RNNUxETTNMak0wSURFNUxqZ3lNaXd6Tnk0ME56UWdUREl3TGpBek15d3pOeTR3TnpJZ1F6UXhMamd3Tml3eU5DNDFPRFVnT0RBdU5qTTJMREl1TXpFNElEZ3dMamMzTnl3eUxqSXpOaUJET0RBdU9EazBMREl1TVRZNElEZ3hMalU0TXl3eExqY3lPU0E0TWk0ek1URXNNUzQzTURFZ1RUZ3lMak14TVN3d0xqY3dOQ0JNT0RJdU1qY3lMREF1TnpBMUlFTTRNUzQyTlRRc01DNDNNamdnT0RBdU9UZzVMREF1T1RRNUlEZ3dMakk1T0N3eExqTTJNU0JNT0RBdU1qYzNMREV1TXpjeklFTTRNQzR4TWprc01TNDBOVGdnTlRrdU56WTRMREV6TGpFek5TQXhPUzQzTlRnc016WXVNRGM1SUVNeE9TNDFMRE0xTGprNE1TQXhPUzR5TVRRc016VXVPVEk1SURFNExqa3lOeXd6TlM0NU1qa2dRekU0TGpVMk1pd3pOUzQ1TWprZ01UZ3VNakl6TERNMkxqQXhNeUF4Tnk0NU5EY3NNell1TVRjeklFd3hNUzQ1TXpVc016a3VOalEwSUVNeE1TNDBPVE1zTXprdU9EazVJREV4TGpJek5pdzBNQzR6TXpRZ01URXVNalEyTERRd0xqZ3hJRXd4TVM0eU5EY3NOREF1T1RZZ1REVXVNVFkzTERRMExqUTBOeUJETkM0M09UUXNORFF1TmpRMklESXVOakkxTERRMUxqazNPQ0F4TGpnM055dzFNQzR6TkRVZ1RERXVPRGN4TERVd0xqTTROQ0JETVM0NE5qSXNOVEF1TkRVMElEQXVPVFV4TERVM0xqVTFOeUF3TGprMk5TdzNNQzR5TlRrZ1F6QXVPVGM1TERneUxqZzNPU0F4TGpVMk9DdzROeTR6TnpVZ01pNHhNemNzT1RFdU56STBJRXd5TGpFek9TdzVNUzQzTXprZ1F6SXVORFEzTERrMExqQTVOQ0ExTGpZeE5DdzVOQzQyTmpJZ05TNDVOelVzT1RRdU56RTVJRXcyTGpBd09TdzVOQzQzTWpNZ1F6WXVNVEVzT1RRdU56TTJJRFl1TWpFekxEazBMamMwTWlBMkxqTXhOQ3c1TkM0M05ESWdRell1Tnprc09UUXVOelF5SURjdU1qWXNPVFF1TmpFZ055NDNNU3c1TkM0ek5TQk1PREl1T1RnekxEVXdMamM1T0NCRE9EUXVOemswTERRNUxqY3lOeUE0TlM0NU9ESXNORGN1TXpjMUlEZzJMalV5TlN3ME15NDRNREVnUXpnM0xqY3hNU3d6TlM0NU9EY2dPRGd1TWpVNUxERXdMamN3TlNBNE5pNHlNalFzTXk0MU1ESWdRemcxTGprM01Td3lMall3T1NBNE5TNDFNaXd4TGprM05TQTROQzQ0T0RFc01TNDJNaUJNT0RRdU56UTVMREV1TlRVNElFdzRNaTQyTmpRc01DNDNOamtnUXpneUxqVTFNU3d3TGpjeU5TQTRNaTQwTXpFc01DNDNNRFFnT0RJdU16RXhMREF1TnpBMElpQnBaRDBpUm1sc2JDMHlJaUJtYVd4c1BTSWpORFUxUVRZMElqNDhMM0JoZEdnK0NpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdQSEJoZEdnZ1pEMGlUVFkyTGpJMk55d3hNUzQxTmpVZ1REWTNMamMyTWl3eE1TNDVPVGtnVERFeExqUXlNeXcwTkM0ek1qVWlJR2xrUFNKR2FXeHNMVE1pSUdacGJHdzlJaU5HUmtaR1JrWWlQand2Y0dGMGFENEtJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0E4Y0dGMGFDQmtQU0pOTVRJdU1qQXlMRGt3TGpVME5TQkRNVEl1TURJNUxEa3dMalUwTlNBeE1TNDROaklzT1RBdU5EVTFJREV4TGpjMk9TdzVNQzR5T1RVZ1F6RXhMall6TWl3NU1DNHdOVGNnTVRFdU56RXpMRGc1TGpjMU1pQXhNUzQ1TlRJc09Ea3VOakUwSUV3ek1DNHpPRGtzTnpndU9UWTVJRU16TUM0Mk1qZ3NOemd1T0RNeElETXdMamt6TXl3M09DNDVNVE1nTXpFdU1EY3hMRGM1TGpFMU1pQkRNekV1TWpBNExEYzVMak01SURNeExqRXlOeXczT1M0Mk9UWWdNekF1T0RnNExEYzVMamd6TXlCTU1USXVORFV4TERrd0xqUTNPQ0JNTVRJdU1qQXlMRGt3TGpVME5TSWdhV1E5SWtacGJHd3ROQ0lnWm1sc2JEMGlJell3TjBRNFFpSStQQzl3WVhSb1Bnb2dJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJRHh3WVhSb0lHUTlJazB4TXk0M05qUXNOREl1TmpVMElFd3hNeTQyTlRZc05ESXVOVGt5SUV3eE15NDNNRElzTkRJdU5ESXhJRXd4T0M0NE16Y3NNemt1TkRVM0lFd3hPUzR3TURjc016a3VOVEF5SUV3eE9DNDVOaklzTXprdU5qY3pJRXd4TXk0NE1qY3NOREl1TmpNM0lFd3hNeTQzTmpRc05ESXVOalUwSWlCcFpEMGlSbWxzYkMwMUlpQm1hV3hzUFNJak5qQTNSRGhDSWo0OEwzQmhkR2crQ2lBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ1BIQmhkR2dnWkQwaVRUZ3VOVElzT1RBdU16YzFJRXc0TGpVeUxEUTJMalF5TVNCTU9DNDFPRE1zTkRZdU16ZzFJRXczTlM0NE5DdzNMalUxTkNCTU56VXVPRFFzTlRFdU5UQTRJRXczTlM0M056Z3NOVEV1TlRRMElFdzRMalV5TERrd0xqTTNOU0JNT0M0MU1pdzVNQzR6TnpVZ1dpQk5PQzQzTnl3ME5pNDFOalFnVERndU56Y3NPRGt1T1RRMElFdzNOUzQxT1RFc05URXVNelkxSUV3M05TNDFPVEVzTnk0NU9EVWdURGd1Tnpjc05EWXVOVFkwSUV3NExqYzNMRFEyTGpVMk5DQmFJaUJwWkQwaVJtbHNiQzAySWlCbWFXeHNQU0lqTmpBM1JEaENJajQ4TDNCaGRHZytDaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnUEhCaGRHZ2daRDBpVFRJMExqazROaXc0TXk0eE9ESWdRekkwTGpjMU5pdzRNeTR6TXpFZ01qUXVNemMwTERnekxqVTJOaUF5TkM0eE16Y3NPRE11TnpBMUlFd3hNaTQyTXpJc09UQXVOREEySUVNeE1pNHpPVFVzT1RBdU5UUTFJREV5TGpReU5pdzVNQzQyTlRnZ01USXVOeXc1TUM0Mk5UZ2dUREV6TGpJMk5TdzVNQzQyTlRnZ1F6RXpMalUwTERrd0xqWTFPQ0F4TXk0NU5UZ3NPVEF1TlRRMUlERTBMakU1TlN3NU1DNDBNRFlnVERJMUxqY3NPRE11TnpBMUlFTXlOUzQ1TXpjc09ETXVOVFkySURJMkxqRXlPQ3c0TXk0ME5USWdNall1TVRJMUxEZ3pMalEwT1NCRE1qWXVNVEl5TERnekxqUTBOeUF5Tmk0eE1Ua3NPRE11TWpJZ01qWXVNVEU1TERneUxqazBOaUJETWpZdU1URTVMRGd5TGpZM01pQXlOUzQ1TXpFc09ESXVOVFk1SURJMUxqY3dNU3c0TWk0M01Ua2dUREkwTGprNE5pdzRNeTR4T0RJaUlHbGtQU0pHYVd4c0xUY2lJR1pwYkd3OUlpTTJNRGRFT0VJaVBqd3ZjR0YwYUQ0S0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQThjR0YwYUNCa1BTSk5NVE11TWpZMkxEa3dMamM0TWlCTU1USXVOeXc1TUM0M09ESWdRekV5TGpVc09UQXVOemd5SURFeUxqTTROQ3c1TUM0M01qWWdNVEl1TXpVMExEa3dMall4TmlCRE1USXVNekkwTERrd0xqVXdOaUF4TWk0ek9UY3NPVEF1TXprNUlERXlMalUyT1N3NU1DNHlPVGtnVERJMExqQTNOQ3c0TXk0MU9UY2dRekkwTGpNeExEZ3pMalExT1NBeU5DNDJPRGtzT0RNdU1qSTJJREkwTGpreE9DdzRNeTR3TnpnZ1RESTFMall6TXl3NE1pNDJNVFFnUXpJMUxqY3lNeXc0TWk0MU5UVWdNalV1T0RFekxEZ3lMalV5TlNBeU5TNDRPVGtzT0RJdU5USTFJRU15Tmk0d056RXNPREl1TlRJMUlESTJMakkwTkN3NE1pNDJOVFVnTWpZdU1qUTBMRGd5TGprME5pQkRNall1TWpRMExEZ3pMakUySURJMkxqSTBOU3c0TXk0ek1Ea2dNall1TWpRM0xEZ3pMak00TXlCTU1qWXVNalV6TERnekxqTTROeUJNTWpZdU1qUTVMRGd6TGpRMU5pQkRNall1TWpRMkxEZ3pMalV6TVNBeU5pNHlORFlzT0RNdU5UTXhJREkxTGpjMk15dzRNeTQ0TVRJZ1RERTBMakkxT0N3NU1DNDFNVFFnUXpFMExEa3dMalkyTlNBeE15NDFOalFzT1RBdU56Z3lJREV6TGpJMk5pdzVNQzQzT0RJZ1RERXpMakkyTml3NU1DNDNPRElnV2lCTk1USXVOalkyTERrd0xqVXpNaUJNTVRJdU55dzVNQzQxTXpNZ1RERXpMakkyTml3NU1DNDFNek1nUXpFekxqVXhPQ3c1TUM0MU16TWdNVE11T1RFMUxEa3dMalF5TlNBeE5DNHhNeklzT1RBdU1qazVJRXd5TlM0Mk16Y3NPRE11TlRrM0lFTXlOUzQ0TURVc09ETXVORGs1SURJMUxqa3pNU3c0TXk0ME1qUWdNalV1T1RrNExEZ3pMak00TXlCRE1qVXVPVGswTERnekxqSTVPU0F5TlM0NU9UUXNPRE11TVRZMUlESTFMams1TkN3NE1pNDVORFlnVERJMUxqZzVPU3c0TWk0M056VWdUREkxTGpjMk9DdzRNaTQ0TWpRZ1RESTFMakExTkN3NE15NHlPRGNnUXpJMExqZ3lNaXc0TXk0ME16Y2dNalF1TkRNNExEZ3pMalkzTXlBeU5DNHlMRGd6TGpneE1pQk1NVEl1TmprMUxEa3dMalV4TkNCTU1USXVOalkyTERrd0xqVXpNaUJNTVRJdU5qWTJMRGt3TGpVek1pQmFJaUJwWkQwaVJtbHNiQzA0SWlCbWFXeHNQU0lqTmpBM1JEaENJajQ4TDNCaGRHZytDaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnUEhCaGRHZ2daRDBpVFRFekxqSTJOaXc0T1M0NE56RWdUREV5TGpjc09Ea3VPRGN4SUVNeE1pNDFMRGc1TGpnM01TQXhNaTR6T0RRc09Ea3VPREUxSURFeUxqTTFOQ3c0T1M0M01EVWdRekV5TGpNeU5DdzRPUzQxT1RVZ01USXVNemszTERnNUxqUTRPQ0F4TWk0MU5qa3NPRGt1TXpnNElFd3lOQzR3TnpRc09ESXVOamcySUVNeU5DNHpNeklzT0RJdU5UTTFJREkwTGpjMk9DdzRNaTQwTVRnZ01qVXVNRFkzTERneUxqUXhPQ0JNTWpVdU5qTXlMRGd5TGpReE9DQkRNalV1T0RNeUxEZ3lMalF4T0NBeU5TNDVORGdzT0RJdU5EYzBJREkxTGprM09DdzRNaTQxT0RRZ1F6STJMakF3T0N3NE1pNDJPVFFnTWpVdU9UTTFMRGd5TGpnd01TQXlOUzQzTmpNc09ESXVPVEF4SUV3eE5DNHlOVGdzT0RrdU5qQXpJRU14TkN3NE9TNDNOVFFnTVRNdU5UWTBMRGc1TGpnM01TQXhNeTR5TmpZc09Ea3VPRGN4SUV3eE15NHlOallzT0RrdU9EY3hJRm9nVFRFeUxqWTJOaXc0T1M0Mk1qRWdUREV5TGpjc09Ea3VOakl5SUV3eE15NHlOallzT0RrdU5qSXlJRU14TXk0MU1UZ3NPRGt1TmpJeUlERXpMamt4TlN3NE9TNDFNVFVnTVRRdU1UTXlMRGc1TGpNNE9DQk1NalV1TmpNM0xEZ3lMalk0TmlCTU1qVXVOalkzTERneUxqWTJPQ0JNTWpVdU5qTXlMRGd5TGpZMk55Qk1NalV1TURZM0xEZ3lMalkyTnlCRE1qUXVPREUxTERneUxqWTJOeUF5TkM0ME1UZ3NPREl1TnpjMUlESTBMaklzT0RJdU9UQXhJRXd4TWk0Mk9UVXNPRGt1TmpBeklFd3hNaTQyTmpZc09Ea3VOakl4SUV3eE1pNDJOallzT0RrdU5qSXhJRm9pSUdsa1BTSkdhV3hzTFRraUlHWnBiR3c5SWlNMk1EZEVPRUlpUGp3dmNHRjBhRDRLSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBOGNHRjBhQ0JrUFNKTk1USXVNemNzT1RBdU9EQXhJRXd4TWk0ek55dzRPUzQxTlRRZ1RERXlMak0zTERrd0xqZ3dNU0lnYVdROUlrWnBiR3d0TVRBaUlHWnBiR3c5SWlNMk1EZEVPRUlpUGp3dmNHRjBhRDRLSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBOGNHRjBhQ0JrUFNKTk5pNHhNeXc1TXk0NU1ERWdRelV1TXpjNUxEa3pMamd3T0NBMExqZ3hOaXc1TXk0eE5qUWdOQzQyT1RFc09USXVOVEkxSUVNekxqZzJMRGc0TGpJNE55QXpMalUwTERnekxqYzBNeUF6TGpVeU5pdzNNUzR4TnpNZ1F6TXVOVEV4TERVNExqTTRPU0EwTGpReU15dzFNUzQwTWpnZ05DNDBNak1zTlRFdU5ESTRJRU0xTGpFek5DdzBOeTR5T0RJZ055NHlNU3cwTmk0eU16WWdOeTR5TVN3ME5pNHlNellnUXpjdU1qRXNORFl1TWpNMklEZ3hMalkyTnl3ekxqSTFJRGd5TGpBMk9Td3pMakF4TnlCRE9ESXVNamt5TERJdU9EZzRJRGcwTGpVMU5pd3hMalF6TXlBNE5TNHlOalFzTXk0NU5DQkRPRGN1TWpFMExERXdMamcwSURnMkxqYzFNaXd6TlM0NE1qY2dPRFV1TlRNNUxEUXpMamd4T0NCRE9EVXVNVFVzTkRZdU16Z3pJRGcwTGpJNU1TdzBPUzR3TXpNZ09ESXVORGd6TERVd0xqRXdNU0JNTnk0eU1TdzVNeTQyTlRNZ1F6WXVPREk0TERrekxqZzNOQ0EyTGpRMk1TdzVNeTQ1TkRFZ05pNHhNeXc1TXk0NU1ERWdRell1TVRNc09UTXVPVEF4SURNdU16UTVMRGt6TGpRMklETXVNVEk1TERreExqYzNOaUJETWk0MU5qZ3NPRGN1TkRrMUlERXVPVGMzTERneUxqazVOU0F4TGprMk1pdzNNQzQwTWpVZ1F6RXVPVFE0TERVM0xqWTBNU0F5TGpnMkxEVXdMalk0SURJdU9EWXNOVEF1TmpnZ1F6TXVOVGNzTkRZdU5UTTBJRFV1TmpRM0xEUTFMalE0T1NBMUxqWTBOeXcwTlM0ME9Ea2dRelV1TmpRMkxEUTFMalE0T1NBNExqQTJOU3cwTkM0d09USWdNVEl1TWpRMUxEUXhMalkzT1NCTU1UTXVNVEUyTERReExqVTJJRXd4T1M0M01UVXNNemN1TnpNZ1RERTVMamMyTVN3ek55NHlOamtnVERZdU1UTXNPVE11T1RBeElpQnBaRDBpUm1sc2JDMHhNU0lnWm1sc2JEMGlJMFpCUmtGR1FTSStQQzl3WVhSb1Bnb2dJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJRHh3WVhSb0lHUTlJazAyTGpNeE55dzVOQzR4TmpFZ1REWXVNVEF5TERrMExqRTBPQ0JNTmk0eE1ERXNPVFF1TVRRNElFdzFMamcxTnl3NU5DNHhNREVnUXpVdU1UTTRMRGt6TGprME5TQXpMakE0TlN3NU15NHpOalVnTWk0NE9ERXNPVEV1T0RBNUlFTXlMak14TXl3NE55NDBOamtnTVM0M01qY3NPREl1T1RrMklERXVOekV6TERjd0xqUXlOU0JETVM0Mk9Ua3NOVGN1TnpjeElESXVOakEwTERVd0xqY3hPQ0F5TGpZeE15dzFNQzQyTkRnZ1F6TXVNek00TERRMkxqUXhOeUExTGpRME5TdzBOUzR6TVNBMUxqVXpOU3cwTlM0eU5qWWdUREV5TGpFMk15dzBNUzQwTXprZ1RERXpMakF6TXl3ME1TNHpNaUJNTVRrdU5EYzVMRE0zTGpVM09DQk1NVGt1TlRFekxETTNMakkwTkNCRE1Ua3VOVEkyTERNM0xqRXdOeUF4T1M0Mk5EY3NNemN1TURBNElERTVMamM0Tml3ek55NHdNakVnUXpFNUxqa3lNaXd6Tnk0d016UWdNakF1TURJekxETTNMakUxTmlBeU1DNHdNRGtzTXpjdU1qa3pJRXd4T1M0NU5Td3pOeTQ0T0RJZ1RERXpMakU1T0N3ME1TNDRNREVnVERFeUxqTXlPQ3cwTVM0NU1Ua2dURFV1TnpjeUxEUTFMamN3TkNCRE5TNDNOREVzTkRVdU56SWdNeTQzT0RJc05EWXVOemN5SURNdU1UQTJMRFV3TGpjeU1pQkRNeTR3T1Rrc05UQXVOemd5SURJdU1UazRMRFUzTGpnd09DQXlMakl4TWl3M01DNDBNalFnUXpJdU1qSTJMRGd5TGprMk15QXlMamd3T1N3NE55NDBNaUF6TGpNM015dzVNUzQzTWprZ1F6TXVORFkwTERreUxqUXlJRFF1TURZeUxEa3lMamc0TXlBMExqWTRNaXc1TXk0eE9ERWdRelF1TlRZMkxEa3lMams0TkNBMExqUTROaXc1TWk0M056WWdOQzQwTkRZc09USXVOVGN5SUVNekxqWTJOU3c0T0M0MU9EZ2dNeTR5T1RFc09EUXVNemNnTXk0eU56WXNOekV1TVRjeklFTXpMakkyTWl3MU9DNDFNaUEwTGpFMk55dzFNUzQwTmpZZ05DNHhOellzTlRFdU16azJJRU0wTGprd01TdzBOeTR4TmpVZ055NHdNRGdzTkRZdU1EVTVJRGN1TURrNExEUTJMakF4TkNCRE55NHdPVFFzTkRZdU1ERTFJRGd4TGpVME1pd3pMakF6TkNBNE1TNDVORFFzTWk0NE1ESWdURGd4TGprM01pd3lMamM0TlNCRE9ESXVPRGMyTERJdU1qUTNJRGd6TGpZNU1pd3lMakE1TnlBNE5DNHpNeklzTWk0ek5USWdRemcwTGpnNE55d3lMalUzTXlBNE5TNHlPREVzTXk0d09EVWdPRFV1TlRBMExETXVPRGN5SUVNNE55NDFNVGdzTVRFZ09EWXVPVFkwTERNMkxqQTVNU0E0TlM0M09EVXNORE11T0RVMUlFTTROUzR5Tnpnc05EY3VNVGsySURnMExqSXhMRFE1TGpNM0lEZ3lMall4TERVd0xqTXhOeUJNTnk0ek16VXNPVE11T0RZNUlFTTJMams1T1N3NU5DNHdOak1nTmk0Mk5UZ3NPVFF1TVRZeElEWXVNekUzTERrMExqRTJNU0JNTmk0ek1UY3NPVFF1TVRZeElGb2dUVFl1TVRjc09UTXVOalUwSUVNMkxqUTJNeXc1TXk0Mk9TQTJMamMzTkN3NU15NDJNVGNnTnk0d09EVXNPVE11TkRNM0lFdzRNaTR6TlRnc05Ea3VPRGcySUVNNE5DNHhPREVzTkRndU9EQTRJRGcwTGprMkxEUTFMamszTVNBNE5TNHlPVElzTkRNdU56Z2dRemcyTGpRMk5pd3pOaTR3TkRrZ09EY3VNREl6TERFeExqQTROU0E0TlM0d01qUXNOQzR3TURnZ1F6ZzBMamcwTml3ekxqTTNOeUE0TkM0MU5URXNNaTQ1TnpZZ09EUXVNVFE0TERJdU9ERTJJRU00TXk0Mk5qUXNNaTQyTWpNZ09ESXVPVGd5TERJdU56WTBJRGd5TGpJeU55d3pMakl4TXlCTU9ESXVNVGt6TERNdU1qTTBJRU00TVM0M09URXNNeTQwTmpZZ055NHpNelVzTkRZdU5EVXlJRGN1TXpNMUxEUTJMalExTWlCRE55NHpNRFFzTkRZdU5EWTVJRFV1TXpRMkxEUTNMalV5TVNBMExqWTJPU3cxTVM0ME56RWdRelF1TmpZeUxEVXhMalV6SURNdU56WXhMRFU0TGpVMU5pQXpMamMzTlN3M01TNHhOek1nUXpNdU56a3NPRFF1TXpJNElEUXVNVFl4TERnNExqVXlOQ0EwTGprek5pdzVNaTQwTnpZZ1F6VXVNREkyTERreUxqa3pOeUExTGpReE1pdzVNeTQwTlRrZ05TNDVOek1zT1RNdU5qRTFJRU0yTGpBNE55dzVNeTQyTkNBMkxqRTFPQ3c1TXk0Mk5USWdOaTR4Tmprc09UTXVOalUwSUV3MkxqRTNMRGt6TGpZMU5DQk1OaTR4Tnl3NU15NDJOVFFnV2lJZ2FXUTlJa1pwYkd3dE1USWlJR1pwYkd3OUlpTTBOVFZCTmpRaVBqd3ZjR0YwYUQ0S0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQThjR0YwYUNCa1BTSk5OeTR6TVRjc05qZ3VPVGd5SUVNM0xqZ3dOaXcyT0M0M01ERWdPQzR5TURJc05qZ3VPVEkySURndU1qQXlMRFk1TGpRNE55QkRPQzR5TURJc056QXVNRFEzSURjdU9EQTJMRGN3TGpjeklEY3VNekUzTERjeExqQXhNaUJETmk0NE1qa3NOekV1TWprMElEWXVORE16TERjeExqQTJPU0EyTGpRek15dzNNQzQxTURnZ1F6WXVORE16TERZNUxqazBPQ0EyTGpneU9TdzJPUzR5TmpVZ055NHpNVGNzTmpndU9UZ3lJaUJwWkQwaVJtbHNiQzB4TXlJZ1ptbHNiRDBpSTBaR1JrWkdSaUkrUEM5d1lYUm9QZ29nSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUR4d1lYUm9JR1E5SWswMkxqa3lMRGN4TGpFek15QkROaTQyTXpFc056RXVNVE16SURZdU5ETXpMRGN3TGprd05TQTJMalF6TXl3M01DNDFNRGdnUXpZdU5ETXpMRFk1TGprME9DQTJMamd5T1N3Mk9TNHlOalVnTnk0ek1UY3NOamd1T1RneUlFTTNMalEyTERZNExqa2dOeTQxT1RVc05qZ3VPRFl4SURjdU56RTBMRFk0TGpnMk1TQkRPQzR3TURNc05qZ3VPRFl4SURndU1qQXlMRFk1TGpBNUlEZ3VNakF5TERZNUxqUTROeUJET0M0eU1ESXNOekF1TURRM0lEY3VPREEyTERjd0xqY3pJRGN1TXpFM0xEY3hMakF4TWlCRE55NHhOelFzTnpFdU1EazBJRGN1TURNNUxEY3hMakV6TXlBMkxqa3lMRGN4TGpFek15Qk5OeTQzTVRRc05qZ3VOamMwSUVNM0xqVTFOeXcyT0M0Mk56UWdOeTR6T1RJc05qZ3VOekl6SURjdU1qSTBMRFk0TGpneU1TQkROaTQyTnpZc05qa3VNVE00SURZdU1qUTJMRFk1TGpnM09TQTJMakkwTml3M01DNDFNRGdnUXpZdU1qUTJMRGN3TGprNU5DQTJMalV4Tnl3M01TNHpNaUEyTGpreUxEY3hMak15SUVNM0xqQTNPQ3czTVM0ek1pQTNMakkwTXl3M01TNHlOekVnTnk0ME1URXNOekV1TVRjMElFTTNMamsxT1N3M01DNDROVGNnT0M0ek9Ea3NOekF1TVRFM0lEZ3VNemc1TERZNUxqUTROeUJET0M0ek9Ea3NOamt1TURBeElEZ3VNVEUzTERZNExqWTNOQ0EzTGpjeE5DdzJPQzQyTnpRaUlHbGtQU0pHYVd4c0xURTBJaUJtYVd4c1BTSWpPREE1TjBFeUlqNDhMM0JoZEdnK0NpQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdQSEJoZEdnZ1pEMGlUVFl1T1RJc056QXVPVFEzSUVNMkxqWTBPU3czTUM0NU5EY2dOaTQyTWpFc056QXVOalFnTmk0Mk1qRXNOekF1TlRBNElFTTJMall5TVN3M01DNHdNVGNnTmk0NU9ESXNOamt1TXpreUlEY3VOREV4TERZNUxqRTBOU0JETnk0MU1qRXNOamt1TURneUlEY3VOakkxTERZNUxqQTBPU0EzTGpjeE5DdzJPUzR3TkRrZ1F6Y3VPVGcyTERZNUxqQTBPU0E0TGpBeE5TdzJPUzR6TlRVZ09DNHdNVFVzTmprdU5EZzNJRU00TGpBeE5TdzJPUzQ1TnpnZ055NDJOVElzTnpBdU5qQXpJRGN1TWpJMExEY3dMamcxTVNCRE55NHhNVFVzTnpBdU9URTBJRGN1TURFc056QXVPVFEzSURZdU9USXNOekF1T1RRM0lFMDNMamN4TkN3Mk9DNDROakVnUXpjdU5UazFMRFk0TGpnMk1TQTNMalEyTERZNExqa2dOeTR6TVRjc05qZ3VPVGd5SUVNMkxqZ3lPU3cyT1M0eU5qVWdOaTQwTXpNc05qa3VPVFE0SURZdU5ETXpMRGN3TGpVd09DQkROaTQwTXpNc056QXVPVEExSURZdU5qTXhMRGN4TGpFek15QTJMamt5TERjeExqRXpNeUJETnk0d016a3NOekV1TVRNeklEY3VNVGMwTERjeExqQTVOQ0EzTGpNeE55dzNNUzR3TVRJZ1F6Y3VPREEyTERjd0xqY3pJRGd1TWpBeUxEY3dMakEwTnlBNExqSXdNaXcyT1M0ME9EY2dRemd1TWpBeUxEWTVMakE1SURndU1EQXpMRFk0TGpnMk1TQTNMamN4TkN3Mk9DNDROakVpSUdsa1BTSkdhV3hzTFRFMUlpQm1hV3hzUFNJak9EQTVOMEV5SWo0OEwzQmhkR2crQ2lBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ1BIQmhkR2dnWkQwaVRUY3VORFEwTERnMUxqTTFJRU0zTGpjd09DdzROUzR4T1RnZ055NDVNakVzT0RVdU16RTVJRGN1T1RJeExEZzFMall5TWlCRE55NDVNakVzT0RVdU9USTFJRGN1TnpBNExEZzJMakk1TWlBM0xqUTBOQ3c0Tmk0ME5EUWdRemN1TVRneExEZzJMalU1TnlBMkxqazJOeXc0Tmk0ME56VWdOaTQ1Tmpjc09EWXVNVGN6SUVNMkxqazJOeXc0TlM0NE56RWdOeTR4T0RFc09EVXVOVEF5SURjdU5EUTBMRGcxTGpNMUlpQnBaRDBpUm1sc2JDMHhOaUlnWm1sc2JEMGlJMFpHUmtaR1JpSStQQzl3WVhSb1Bnb2dJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJRHh3WVhSb0lHUTlJazAzTGpJekxEZzJMalV4SUVNM0xqQTNOQ3c0Tmk0MU1TQTJMamsyTnl3NE5pNHpPRGNnTmk0NU5qY3NPRFl1TVRjeklFTTJMamsyTnl3NE5TNDROekVnTnk0eE9ERXNPRFV1TlRBeUlEY3VORFEwTERnMUxqTTFJRU0zTGpVeU1TdzROUzR6TURVZ055NDFPVFFzT0RVdU1qZzBJRGN1TmpVNExEZzFMakk0TkNCRE55NDRNVFFzT0RVdU1qZzBJRGN1T1RJeExEZzFMalF3T0NBM0xqa3lNU3c0TlM0Mk1qSWdRemN1T1RJeExEZzFMamt5TlNBM0xqY3dPQ3c0Tmk0eU9USWdOeTQwTkRRc09EWXVORFEwSUVNM0xqTTJOeXc0Tmk0ME9Ea2dOeTR5T1RRc09EWXVOVEVnTnk0eU15dzROaTQxTVNCTk55NDJOVGdzT0RVdU1EazRJRU0zTGpVMU9DdzROUzR3T1RnZ055NDBOVFVzT0RVdU1USTNJRGN1TXpVeExEZzFMakU0T0NCRE55NHdNekVzT0RVdU16Y3pJRFl1TnpneExEZzFMamd3TmlBMkxqYzRNU3c0Tmk0eE56TWdRell1TnpneExEZzJMalE0TWlBMkxqazJOaXc0Tmk0Mk9UY2dOeTR5TXl3NE5pNDJPVGNnUXpjdU16TXNPRFl1TmprM0lEY3VORE16TERnMkxqWTJOaUEzTGpVek9DdzROaTQyTURjZ1F6Y3VPRFU0TERnMkxqUXlNaUE0TGpFd09DdzROUzQ1T0RrZ09DNHhNRGdzT0RVdU5qSXlJRU00TGpFd09DdzROUzR6TVRNZ055NDVNak1zT0RVdU1EazRJRGN1TmpVNExEZzFMakE1T0NJZ2FXUTlJa1pwYkd3dE1UY2lJR1pwYkd3OUlpTTRNRGszUVRJaVBqd3ZjR0YwYUQ0S0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ0lDQThjR0YwYUNCa1BTSk5OeTR5TXl3NE5pNHpNaklnVERjdU1UVTBMRGcyTGpFM015QkROeTR4TlRRc09EVXVPVE00SURjdU16TXpMRGcxTGpZeU9TQTNMalV6T0N3NE5TNDFNVElnVERjdU5qVTRMRGcxTGpRM01TQk1OeTQzTXpRc09EVXVOakl5SUVNM0xqY3pOQ3c0TlM0NE5UWWdOeTQxTlRVc09EWXVNVFkwSURjdU16VXhMRGcyTGpJNE1pQk1OeTR5TXl3NE5pNHpNaklnVFRjdU5qVTRMRGcxTGpJNE5DQkROeTQxT1RRc09EVXVNamcwSURjdU5USXhMRGcxTGpNd05TQTNMalEwTkN3NE5TNHpOU0JETnk0eE9ERXNPRFV1TlRBeUlEWXVPVFkzTERnMUxqZzNNU0EyTGprMk55dzROaTR4TnpNZ1F6WXVPVFkzTERnMkxqTTROeUEzTGpBM05DdzROaTQxTVNBM0xqSXpMRGcyTGpVeElFTTNMakk1TkN3NE5pNDFNU0EzTGpNMk55dzROaTQwT0RrZ055NDBORFFzT0RZdU5EUTBJRU0zTGpjd09DdzROaTR5T1RJZ055NDVNakVzT0RVdU9USTFJRGN1T1RJeExEZzFMall5TWlCRE55NDVNakVzT0RVdU5EQTRJRGN1T0RFMExEZzFMakk0TkNBM0xqWTFPQ3c0TlM0eU9EUWlJR2xrUFNKR2FXeHNMVEU0SWlCbWFXeHNQU0lqT0RBNU4wRXlJajQ4TDNCaGRHZytDaUFnSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnUEhCaGRHZ2daRDBpVFRjM0xqSTNPQ3czTGpjMk9TQk1OemN1TWpjNExEVXhMalF6TmlCTU1UQXVNakE0TERrd0xqRTJJRXd4TUM0eU1EZ3NORFl1TkRreklFdzNOeTR5Tnpnc055NDNOamtpSUdsa1BTSkdhV3hzTFRFNUlpQm1hV3hzUFNJak5EVTFRVFkwSWo0OEwzQmhkR2crQ2lBZ0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUNBZ1BIQmhkR2dnWkQwaVRURXdMakE0TXl3NU1DNHpOelVnVERFd0xqQTRNeXcwTmk0ME1qRWdUREV3TGpFME5pdzBOaTR6T0RVZ1REYzNMalF3TXl3M0xqVTFOQ0JNTnpjdU5EQXpMRFV4TGpVd09DQk1OemN1TXpReExEVXhMalUwTkNCTU1UQXVNRGd6TERrd0xqTTNOU0JNTVRBdU1EZ3pMRGt3TGpNM05TQmFJRTB4TUM0ek16TXNORFl1TlRZMElFd3hNQzR6TXpNc09Ea3VPVFEwSUV3M055NHhOVFFzTlRFdU16WTFJRXczTnk0eE5UUXNOeTQ1T0RVZ1RERXdMak16TXl3ME5pNDFOalFnVERFd0xqTXpNeXcwTmk0MU5qUWdXaUlnYVdROUlrWnBiR3d0TWpBaUlHWnBiR3c5SWlNMk1EZEVPRUlpUGp3dmNHRjBhRDRLSUNBZ0lDQWdJQ0FnSUNBZ0lDQWdJRHd2Wno0S0lDQWdJQ0FnSUNBZ0lDQWdJQ0FnSUR4d1lYUm9JR1E5SWsweE1qVXVOek0zTERnNExqWTBOeUJNTVRFNExqQTVPQ3c1TVM0NU9ERWdUREV4T0M0d09UZ3NPRFFnVERFd05pNDJNemtzT0RndU56RXpJRXd4TURZdU5qTTVMRGsyTGprNE1pQk1PVGtzTVRBd0xqTXhOU0JNTVRFeUxqTTJPU3d4TURNdU9UWXhJRXd4TWpVdU56TTNMRGc0TGpZME55SWdhV1E5SWtsdGNHOXlkR1ZrTFV4aGVXVnljeTFEYjNCNUxUSWlJR1pwYkd3OUlpTTBOVFZCTmpRaUlITnJaWFJqYURwMGVYQmxQU0pOVTFOb1lYQmxSM0p2ZFhBaVBqd3ZjR0YwYUQ0S0lDQWdJQ0FnSUNBZ0lDQWdQQzluUGdvZ0lDQWdJQ0FnSUR3dlp6NEtJQ0FnSUR3dlp6NEtQQzl6ZG1jKycpO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBSb3RhdGVJbnN0cnVjdGlvbnM7XG5cbn0se1wiLi91dGlsLmpzXCI6MjJ9XSwxNzpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4vKlxuICogQ29weXJpZ2h0IDIwMTUgR29vZ2xlIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG52YXIgU2Vuc29yU2FtcGxlID0gX2RlcmVxXygnLi9zZW5zb3Itc2FtcGxlLmpzJyk7XG52YXIgTWF0aFV0aWwgPSBfZGVyZXFfKCcuLi9tYXRoLXV0aWwuanMnKTtcbnZhciBVdGlsID0gX2RlcmVxXygnLi4vdXRpbC5qcycpO1xuXG4vKipcbiAqIEFuIGltcGxlbWVudGF0aW9uIG9mIGEgc2ltcGxlIGNvbXBsZW1lbnRhcnkgZmlsdGVyLCB3aGljaCBmdXNlcyBneXJvc2NvcGUgYW5kXG4gKiBhY2NlbGVyb21ldGVyIGRhdGEgZnJvbSB0aGUgJ2RldmljZW1vdGlvbicgZXZlbnQuXG4gKlxuICogQWNjZWxlcm9tZXRlciBkYXRhIGlzIHZlcnkgbm9pc3ksIGJ1dCBzdGFibGUgb3ZlciB0aGUgbG9uZyB0ZXJtLlxuICogR3lyb3Njb3BlIGRhdGEgaXMgc21vb3RoLCBidXQgdGVuZHMgdG8gZHJpZnQgb3ZlciB0aGUgbG9uZyB0ZXJtLlxuICpcbiAqIFRoaXMgZnVzaW9uIGlzIHJlbGF0aXZlbHkgc2ltcGxlOlxuICogMS4gR2V0IG9yaWVudGF0aW9uIGVzdGltYXRlcyBmcm9tIGFjY2VsZXJvbWV0ZXIgYnkgYXBwbHlpbmcgYSBsb3ctcGFzcyBmaWx0ZXJcbiAqICAgIG9uIHRoYXQgZGF0YS5cbiAqIDIuIEdldCBvcmllbnRhdGlvbiBlc3RpbWF0ZXMgZnJvbSBneXJvc2NvcGUgYnkgaW50ZWdyYXRpbmcgb3ZlciB0aW1lLlxuICogMy4gQ29tYmluZSB0aGUgdHdvIGVzdGltYXRlcywgd2VpZ2hpbmcgKDEpIGluIHRoZSBsb25nIHRlcm0sIGJ1dCAoMikgZm9yIHRoZVxuICogICAgc2hvcnQgdGVybS5cbiAqL1xuZnVuY3Rpb24gQ29tcGxlbWVudGFyeUZpbHRlcihrRmlsdGVyKSB7XG4gIHRoaXMua0ZpbHRlciA9IGtGaWx0ZXI7XG5cbiAgLy8gUmF3IHNlbnNvciBtZWFzdXJlbWVudHMuXG4gIHRoaXMuY3VycmVudEFjY2VsTWVhc3VyZW1lbnQgPSBuZXcgU2Vuc29yU2FtcGxlKCk7XG4gIHRoaXMuY3VycmVudEd5cm9NZWFzdXJlbWVudCA9IG5ldyBTZW5zb3JTYW1wbGUoKTtcbiAgdGhpcy5wcmV2aW91c0d5cm9NZWFzdXJlbWVudCA9IG5ldyBTZW5zb3JTYW1wbGUoKTtcblxuICAvLyBTZXQgZGVmYXVsdCBsb29rIGRpcmVjdGlvbiB0byBiZSBpbiB0aGUgY29ycmVjdCBkaXJlY3Rpb24uXG4gIGlmIChVdGlsLmlzSU9TKCkpIHtcbiAgICB0aGlzLmZpbHRlclEgPSBuZXcgTWF0aFV0aWwuUXVhdGVybmlvbigtMSwgMCwgMCwgMSk7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5maWx0ZXJRID0gbmV3IE1hdGhVdGlsLlF1YXRlcm5pb24oMSwgMCwgMCwgMSk7XG4gIH1cbiAgdGhpcy5wcmV2aW91c0ZpbHRlclEgPSBuZXcgTWF0aFV0aWwuUXVhdGVybmlvbigpO1xuICB0aGlzLnByZXZpb3VzRmlsdGVyUS5jb3B5KHRoaXMuZmlsdGVyUSk7XG5cbiAgLy8gT3JpZW50YXRpb24gYmFzZWQgb24gdGhlIGFjY2VsZXJvbWV0ZXIuXG4gIHRoaXMuYWNjZWxRID0gbmV3IE1hdGhVdGlsLlF1YXRlcm5pb24oKTtcbiAgLy8gV2hldGhlciBvciBub3QgdGhlIG9yaWVudGF0aW9uIGhhcyBiZWVuIGluaXRpYWxpemVkLlxuICB0aGlzLmlzT3JpZW50YXRpb25Jbml0aWFsaXplZCA9IGZhbHNlO1xuICAvLyBSdW5uaW5nIGVzdGltYXRlIG9mIGdyYXZpdHkgYmFzZWQgb24gdGhlIGN1cnJlbnQgb3JpZW50YXRpb24uXG4gIHRoaXMuZXN0aW1hdGVkR3Jhdml0eSA9IG5ldyBNYXRoVXRpbC5WZWN0b3IzKCk7XG4gIC8vIE1lYXN1cmVkIGdyYXZpdHkgYmFzZWQgb24gYWNjZWxlcm9tZXRlci5cbiAgdGhpcy5tZWFzdXJlZEdyYXZpdHkgPSBuZXcgTWF0aFV0aWwuVmVjdG9yMygpO1xuXG4gIC8vIERlYnVnIG9ubHkgcXVhdGVybmlvbiBvZiBneXJvLWJhc2VkIG9yaWVudGF0aW9uLlxuICB0aGlzLmd5cm9JbnRlZ3JhbFEgPSBuZXcgTWF0aFV0aWwuUXVhdGVybmlvbigpO1xufVxuXG5Db21wbGVtZW50YXJ5RmlsdGVyLnByb3RvdHlwZS5hZGRBY2NlbE1lYXN1cmVtZW50ID0gZnVuY3Rpb24odmVjdG9yLCB0aW1lc3RhbXBTKSB7XG4gIHRoaXMuY3VycmVudEFjY2VsTWVhc3VyZW1lbnQuc2V0KHZlY3RvciwgdGltZXN0YW1wUyk7XG59O1xuXG5Db21wbGVtZW50YXJ5RmlsdGVyLnByb3RvdHlwZS5hZGRHeXJvTWVhc3VyZW1lbnQgPSBmdW5jdGlvbih2ZWN0b3IsIHRpbWVzdGFtcFMpIHtcbiAgdGhpcy5jdXJyZW50R3lyb01lYXN1cmVtZW50LnNldCh2ZWN0b3IsIHRpbWVzdGFtcFMpO1xuXG4gIHZhciBkZWx0YVQgPSB0aW1lc3RhbXBTIC0gdGhpcy5wcmV2aW91c0d5cm9NZWFzdXJlbWVudC50aW1lc3RhbXBTO1xuICBpZiAoVXRpbC5pc1RpbWVzdGFtcERlbHRhVmFsaWQoZGVsdGFUKSkge1xuICAgIHRoaXMucnVuXygpO1xuICB9XG5cbiAgdGhpcy5wcmV2aW91c0d5cm9NZWFzdXJlbWVudC5jb3B5KHRoaXMuY3VycmVudEd5cm9NZWFzdXJlbWVudCk7XG59O1xuXG5Db21wbGVtZW50YXJ5RmlsdGVyLnByb3RvdHlwZS5ydW5fID0gZnVuY3Rpb24oKSB7XG5cbiAgaWYgKCF0aGlzLmlzT3JpZW50YXRpb25Jbml0aWFsaXplZCkge1xuICAgIHRoaXMuYWNjZWxRID0gdGhpcy5hY2NlbFRvUXVhdGVybmlvbl8odGhpcy5jdXJyZW50QWNjZWxNZWFzdXJlbWVudC5zYW1wbGUpO1xuICAgIHRoaXMucHJldmlvdXNGaWx0ZXJRLmNvcHkodGhpcy5hY2NlbFEpO1xuICAgIHRoaXMuaXNPcmllbnRhdGlvbkluaXRpYWxpemVkID0gdHJ1ZTtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgZGVsdGFUID0gdGhpcy5jdXJyZW50R3lyb01lYXN1cmVtZW50LnRpbWVzdGFtcFMgLVxuICAgICAgdGhpcy5wcmV2aW91c0d5cm9NZWFzdXJlbWVudC50aW1lc3RhbXBTO1xuXG4gIC8vIENvbnZlcnQgZ3lybyByb3RhdGlvbiB2ZWN0b3IgdG8gYSBxdWF0ZXJuaW9uIGRlbHRhLlxuICB2YXIgZ3lyb0RlbHRhUSA9IHRoaXMuZ3lyb1RvUXVhdGVybmlvbkRlbHRhXyh0aGlzLmN1cnJlbnRHeXJvTWVhc3VyZW1lbnQuc2FtcGxlLCBkZWx0YVQpO1xuICB0aGlzLmd5cm9JbnRlZ3JhbFEubXVsdGlwbHkoZ3lyb0RlbHRhUSk7XG5cbiAgLy8gZmlsdGVyXzEgPSBLICogKGZpbHRlcl8wICsgZ3lybyAqIGRUKSArICgxIC0gSykgKiBhY2NlbC5cbiAgdGhpcy5maWx0ZXJRLmNvcHkodGhpcy5wcmV2aW91c0ZpbHRlclEpO1xuICB0aGlzLmZpbHRlclEubXVsdGlwbHkoZ3lyb0RlbHRhUSk7XG5cbiAgLy8gQ2FsY3VsYXRlIHRoZSBkZWx0YSBiZXR3ZWVuIHRoZSBjdXJyZW50IGVzdGltYXRlZCBncmF2aXR5IGFuZCB0aGUgcmVhbFxuICAvLyBncmF2aXR5IHZlY3RvciBmcm9tIGFjY2VsZXJvbWV0ZXIuXG4gIHZhciBpbnZGaWx0ZXJRID0gbmV3IE1hdGhVdGlsLlF1YXRlcm5pb24oKTtcbiAgaW52RmlsdGVyUS5jb3B5KHRoaXMuZmlsdGVyUSk7XG4gIGludkZpbHRlclEuaW52ZXJzZSgpO1xuXG4gIHRoaXMuZXN0aW1hdGVkR3Jhdml0eS5zZXQoMCwgMCwgLTEpO1xuICB0aGlzLmVzdGltYXRlZEdyYXZpdHkuYXBwbHlRdWF0ZXJuaW9uKGludkZpbHRlclEpO1xuICB0aGlzLmVzdGltYXRlZEdyYXZpdHkubm9ybWFsaXplKCk7XG5cbiAgdGhpcy5tZWFzdXJlZEdyYXZpdHkuY29weSh0aGlzLmN1cnJlbnRBY2NlbE1lYXN1cmVtZW50LnNhbXBsZSk7XG4gIHRoaXMubWVhc3VyZWRHcmF2aXR5Lm5vcm1hbGl6ZSgpO1xuXG4gIC8vIENvbXBhcmUgZXN0aW1hdGVkIGdyYXZpdHkgd2l0aCBtZWFzdXJlZCBncmF2aXR5LCBnZXQgdGhlIGRlbHRhIHF1YXRlcm5pb25cbiAgLy8gYmV0d2VlbiB0aGUgdHdvLlxuICB2YXIgZGVsdGFRID0gbmV3IE1hdGhVdGlsLlF1YXRlcm5pb24oKTtcbiAgZGVsdGFRLnNldEZyb21Vbml0VmVjdG9ycyh0aGlzLmVzdGltYXRlZEdyYXZpdHksIHRoaXMubWVhc3VyZWRHcmF2aXR5KTtcbiAgZGVsdGFRLmludmVyc2UoKTtcblxuICBpZiAoVXRpbC5pc0RlYnVnKCkpIHtcbiAgICBjb25zb2xlLmxvZygnRGVsdGE6ICVkIGRlZywgR19lc3Q6ICglcywgJXMsICVzKSwgR19tZWFzOiAoJXMsICVzLCAlcyknLFxuICAgICAgICAgICAgICAgIE1hdGhVdGlsLnJhZFRvRGVnICogVXRpbC5nZXRRdWF0ZXJuaW9uQW5nbGUoZGVsdGFRKSxcbiAgICAgICAgICAgICAgICAodGhpcy5lc3RpbWF0ZWRHcmF2aXR5LngpLnRvRml4ZWQoMSksXG4gICAgICAgICAgICAgICAgKHRoaXMuZXN0aW1hdGVkR3Jhdml0eS55KS50b0ZpeGVkKDEpLFxuICAgICAgICAgICAgICAgICh0aGlzLmVzdGltYXRlZEdyYXZpdHkueikudG9GaXhlZCgxKSxcbiAgICAgICAgICAgICAgICAodGhpcy5tZWFzdXJlZEdyYXZpdHkueCkudG9GaXhlZCgxKSxcbiAgICAgICAgICAgICAgICAodGhpcy5tZWFzdXJlZEdyYXZpdHkueSkudG9GaXhlZCgxKSxcbiAgICAgICAgICAgICAgICAodGhpcy5tZWFzdXJlZEdyYXZpdHkueikudG9GaXhlZCgxKSk7XG4gIH1cblxuICAvLyBDYWxjdWxhdGUgdGhlIFNMRVJQIHRhcmdldDogY3VycmVudCBvcmllbnRhdGlvbiBwbHVzIHRoZSBtZWFzdXJlZC1lc3RpbWF0ZWRcbiAgLy8gcXVhdGVybmlvbiBkZWx0YS5cbiAgdmFyIHRhcmdldFEgPSBuZXcgTWF0aFV0aWwuUXVhdGVybmlvbigpO1xuICB0YXJnZXRRLmNvcHkodGhpcy5maWx0ZXJRKTtcbiAgdGFyZ2V0US5tdWx0aXBseShkZWx0YVEpO1xuXG4gIC8vIFNMRVJQIGZhY3RvcjogMCBpcyBwdXJlIGd5cm8sIDEgaXMgcHVyZSBhY2NlbC5cbiAgdGhpcy5maWx0ZXJRLnNsZXJwKHRhcmdldFEsIDEgLSB0aGlzLmtGaWx0ZXIpO1xuXG4gIHRoaXMucHJldmlvdXNGaWx0ZXJRLmNvcHkodGhpcy5maWx0ZXJRKTtcbn07XG5cbkNvbXBsZW1lbnRhcnlGaWx0ZXIucHJvdG90eXBlLmdldE9yaWVudGF0aW9uID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLmZpbHRlclE7XG59O1xuXG5Db21wbGVtZW50YXJ5RmlsdGVyLnByb3RvdHlwZS5hY2NlbFRvUXVhdGVybmlvbl8gPSBmdW5jdGlvbihhY2NlbCkge1xuICB2YXIgbm9ybUFjY2VsID0gbmV3IE1hdGhVdGlsLlZlY3RvcjMoKTtcbiAgbm9ybUFjY2VsLmNvcHkoYWNjZWwpO1xuICBub3JtQWNjZWwubm9ybWFsaXplKCk7XG4gIHZhciBxdWF0ID0gbmV3IE1hdGhVdGlsLlF1YXRlcm5pb24oKTtcbiAgcXVhdC5zZXRGcm9tVW5pdFZlY3RvcnMobmV3IE1hdGhVdGlsLlZlY3RvcjMoMCwgMCwgLTEpLCBub3JtQWNjZWwpO1xuICBxdWF0LmludmVyc2UoKTtcbiAgcmV0dXJuIHF1YXQ7XG59O1xuXG5Db21wbGVtZW50YXJ5RmlsdGVyLnByb3RvdHlwZS5neXJvVG9RdWF0ZXJuaW9uRGVsdGFfID0gZnVuY3Rpb24oZ3lybywgZHQpIHtcbiAgLy8gRXh0cmFjdCBheGlzIGFuZCBhbmdsZSBmcm9tIHRoZSBneXJvc2NvcGUgZGF0YS5cbiAgdmFyIHF1YXQgPSBuZXcgTWF0aFV0aWwuUXVhdGVybmlvbigpO1xuICB2YXIgYXhpcyA9IG5ldyBNYXRoVXRpbC5WZWN0b3IzKCk7XG4gIGF4aXMuY29weShneXJvKTtcbiAgYXhpcy5ub3JtYWxpemUoKTtcbiAgcXVhdC5zZXRGcm9tQXhpc0FuZ2xlKGF4aXMsIGd5cm8ubGVuZ3RoKCkgKiBkdCk7XG4gIHJldHVybiBxdWF0O1xufTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IENvbXBsZW1lbnRhcnlGaWx0ZXI7XG5cbn0se1wiLi4vbWF0aC11dGlsLmpzXCI6MTQsXCIuLi91dGlsLmpzXCI6MjIsXCIuL3NlbnNvci1zYW1wbGUuanNcIjoyMH1dLDE4OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcbi8qXG4gKiBDb3B5cmlnaHQgMjAxNSBHb29nbGUgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG52YXIgQ29tcGxlbWVudGFyeUZpbHRlciA9IF9kZXJlcV8oJy4vY29tcGxlbWVudGFyeS1maWx0ZXIuanMnKTtcbnZhciBQb3NlUHJlZGljdG9yID0gX2RlcmVxXygnLi9wb3NlLXByZWRpY3Rvci5qcycpO1xudmFyIFRvdWNoUGFubmVyID0gX2RlcmVxXygnLi4vdG91Y2gtcGFubmVyLmpzJyk7XG52YXIgTWF0aFV0aWwgPSBfZGVyZXFfKCcuLi9tYXRoLXV0aWwuanMnKTtcbnZhciBVdGlsID0gX2RlcmVxXygnLi4vdXRpbC5qcycpO1xuXG4vKipcbiAqIFRoZSBwb3NlIHNlbnNvciwgaW1wbGVtZW50ZWQgdXNpbmcgRGV2aWNlTW90aW9uIEFQSXMuXG4gKi9cbmZ1bmN0aW9uIEZ1c2lvblBvc2VTZW5zb3IoKSB7XG4gIHRoaXMuZGV2aWNlSWQgPSAnd2VidnItcG9seWZpbGw6ZnVzZWQnO1xuICB0aGlzLmRldmljZU5hbWUgPSAnVlIgUG9zaXRpb24gRGV2aWNlICh3ZWJ2ci1wb2x5ZmlsbDpmdXNlZCknO1xuXG4gIHRoaXMuYWNjZWxlcm9tZXRlciA9IG5ldyBNYXRoVXRpbC5WZWN0b3IzKCk7XG4gIHRoaXMuZ3lyb3Njb3BlID0gbmV3IE1hdGhVdGlsLlZlY3RvcjMoKTtcblxuICB0aGlzLnN0YXJ0KCk7XG5cbiAgdGhpcy5maWx0ZXIgPSBuZXcgQ29tcGxlbWVudGFyeUZpbHRlcihXZWJWUkNvbmZpZy5LX0ZJTFRFUik7XG4gIHRoaXMucG9zZVByZWRpY3RvciA9IG5ldyBQb3NlUHJlZGljdG9yKFdlYlZSQ29uZmlnLlBSRURJQ1RJT05fVElNRV9TKTtcbiAgdGhpcy50b3VjaFBhbm5lciA9IG5ldyBUb3VjaFBhbm5lcigpO1xuXG4gIHRoaXMuZmlsdGVyVG9Xb3JsZFEgPSBuZXcgTWF0aFV0aWwuUXVhdGVybmlvbigpO1xuXG4gIC8vIFNldCB0aGUgZmlsdGVyIHRvIHdvcmxkIHRyYW5zZm9ybSwgZGVwZW5kaW5nIG9uIE9TLlxuICBpZiAoVXRpbC5pc0lPUygpKSB7XG4gICAgdGhpcy5maWx0ZXJUb1dvcmxkUS5zZXRGcm9tQXhpc0FuZ2xlKG5ldyBNYXRoVXRpbC5WZWN0b3IzKDEsIDAsIDApLCBNYXRoLlBJIC8gMik7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5maWx0ZXJUb1dvcmxkUS5zZXRGcm9tQXhpc0FuZ2xlKG5ldyBNYXRoVXRpbC5WZWN0b3IzKDEsIDAsIDApLCAtTWF0aC5QSSAvIDIpO1xuICB9XG5cbiAgdGhpcy5pbnZlcnNlV29ybGRUb1NjcmVlblEgPSBuZXcgTWF0aFV0aWwuUXVhdGVybmlvbigpO1xuICB0aGlzLndvcmxkVG9TY3JlZW5RID0gbmV3IE1hdGhVdGlsLlF1YXRlcm5pb24oKTtcbiAgdGhpcy5vcmlnaW5hbFBvc2VBZGp1c3RRID0gbmV3IE1hdGhVdGlsLlF1YXRlcm5pb24oKTtcbiAgdGhpcy5vcmlnaW5hbFBvc2VBZGp1c3RRLnNldEZyb21BeGlzQW5nbGUobmV3IE1hdGhVdGlsLlZlY3RvcjMoMCwgMCwgMSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLXdpbmRvdy5vcmllbnRhdGlvbiAqIE1hdGguUEkgLyAxODApO1xuXG4gIHRoaXMuc2V0U2NyZWVuVHJhbnNmb3JtXygpO1xuICAvLyBBZGp1c3QgdGhpcyBmaWx0ZXIgZm9yIGJlaW5nIGluIGxhbmRzY2FwZSBtb2RlLlxuICBpZiAoVXRpbC5pc0xhbmRzY2FwZU1vZGUoKSkge1xuICAgIHRoaXMuZmlsdGVyVG9Xb3JsZFEubXVsdGlwbHkodGhpcy5pbnZlcnNlV29ybGRUb1NjcmVlblEpO1xuICB9XG5cbiAgLy8gS2VlcCB0cmFjayBvZiBhIHJlc2V0IHRyYW5zZm9ybSBmb3IgcmVzZXRTZW5zb3IuXG4gIHRoaXMucmVzZXRRID0gbmV3IE1hdGhVdGlsLlF1YXRlcm5pb24oKTtcblxuICB0aGlzLmlzRmlyZWZveEFuZHJvaWQgPSBVdGlsLmlzRmlyZWZveEFuZHJvaWQoKTtcbiAgdGhpcy5pc0lPUyA9IFV0aWwuaXNJT1MoKTtcblxuICB0aGlzLm9yaWVudGF0aW9uT3V0XyA9IG5ldyBGbG9hdDMyQXJyYXkoNCk7XG59XG5cbkZ1c2lvblBvc2VTZW5zb3IucHJvdG90eXBlLmdldFBvc2l0aW9uID0gZnVuY3Rpb24oKSB7XG4gIC8vIFRoaXMgUG9zZVNlbnNvciBkb2Vzbid0IHN1cHBvcnQgcG9zaXRpb25cbiAgcmV0dXJuIG51bGw7XG59O1xuXG5GdXNpb25Qb3NlU2Vuc29yLnByb3RvdHlwZS5nZXRPcmllbnRhdGlvbiA9IGZ1bmN0aW9uKCkge1xuICAvLyBDb252ZXJ0IGZyb20gZmlsdGVyIHNwYWNlIHRvIHRoZSB0aGUgc2FtZSBzeXN0ZW0gdXNlZCBieSB0aGVcbiAgLy8gZGV2aWNlb3JpZW50YXRpb24gZXZlbnQuXG4gIHZhciBvcmllbnRhdGlvbiA9IHRoaXMuZmlsdGVyLmdldE9yaWVudGF0aW9uKCk7XG5cbiAgLy8gUHJlZGljdCBvcmllbnRhdGlvbi5cbiAgdGhpcy5wcmVkaWN0ZWRRID0gdGhpcy5wb3NlUHJlZGljdG9yLmdldFByZWRpY3Rpb24ob3JpZW50YXRpb24sIHRoaXMuZ3lyb3Njb3BlLCB0aGlzLnByZXZpb3VzVGltZXN0YW1wUyk7XG5cbiAgLy8gQ29udmVydCB0byBUSFJFRSBjb29yZGluYXRlIHN5c3RlbTogLVogZm9yd2FyZCwgWSB1cCwgWCByaWdodC5cbiAgdmFyIG91dCA9IG5ldyBNYXRoVXRpbC5RdWF0ZXJuaW9uKCk7XG4gIG91dC5jb3B5KHRoaXMuZmlsdGVyVG9Xb3JsZFEpO1xuICBvdXQubXVsdGlwbHkodGhpcy5yZXNldFEpO1xuICBpZiAoIVdlYlZSQ29uZmlnLlRPVUNIX1BBTk5FUl9ESVNBQkxFRCkge1xuICAgIG91dC5tdWx0aXBseSh0aGlzLnRvdWNoUGFubmVyLmdldE9yaWVudGF0aW9uKCkpO1xuICB9XG4gIG91dC5tdWx0aXBseSh0aGlzLnByZWRpY3RlZFEpO1xuICBvdXQubXVsdGlwbHkodGhpcy53b3JsZFRvU2NyZWVuUSk7XG5cbiAgLy8gSGFuZGxlIHRoZSB5YXctb25seSBjYXNlLlxuICBpZiAoV2ViVlJDb25maWcuWUFXX09OTFkpIHtcbiAgICAvLyBNYWtlIGEgcXVhdGVybmlvbiB0aGF0IG9ubHkgdHVybnMgYXJvdW5kIHRoZSBZLWF4aXMuXG4gICAgb3V0LnggPSAwO1xuICAgIG91dC56ID0gMDtcbiAgICBvdXQubm9ybWFsaXplKCk7XG4gIH1cblxuICB0aGlzLm9yaWVudGF0aW9uT3V0X1swXSA9IG91dC54O1xuICB0aGlzLm9yaWVudGF0aW9uT3V0X1sxXSA9IG91dC55O1xuICB0aGlzLm9yaWVudGF0aW9uT3V0X1syXSA9IG91dC56O1xuICB0aGlzLm9yaWVudGF0aW9uT3V0X1szXSA9IG91dC53O1xuICByZXR1cm4gdGhpcy5vcmllbnRhdGlvbk91dF87XG59O1xuXG5GdXNpb25Qb3NlU2Vuc29yLnByb3RvdHlwZS5yZXNldFBvc2UgPSBmdW5jdGlvbigpIHtcbiAgLy8gUmVkdWNlIHRvIGludmVydGVkIHlhdy1vbmx5LlxuICB0aGlzLnJlc2V0US5jb3B5KHRoaXMuZmlsdGVyLmdldE9yaWVudGF0aW9uKCkpO1xuICB0aGlzLnJlc2V0US54ID0gMDtcbiAgdGhpcy5yZXNldFEueSA9IDA7XG4gIHRoaXMucmVzZXRRLnogKj0gLTE7XG4gIHRoaXMucmVzZXRRLm5vcm1hbGl6ZSgpO1xuXG4gIC8vIFRha2UgaW50byBhY2NvdW50IGV4dHJhIHRyYW5zZm9ybWF0aW9ucyBpbiBsYW5kc2NhcGUgbW9kZS5cbiAgaWYgKFV0aWwuaXNMYW5kc2NhcGVNb2RlKCkpIHtcbiAgICB0aGlzLnJlc2V0US5tdWx0aXBseSh0aGlzLmludmVyc2VXb3JsZFRvU2NyZWVuUSk7XG4gIH1cblxuICAvLyBUYWtlIGludG8gYWNjb3VudCBvcmlnaW5hbCBwb3NlLlxuICB0aGlzLnJlc2V0US5tdWx0aXBseSh0aGlzLm9yaWdpbmFsUG9zZUFkanVzdFEpO1xuXG4gIGlmICghV2ViVlJDb25maWcuVE9VQ0hfUEFOTkVSX0RJU0FCTEVEKSB7XG4gICAgdGhpcy50b3VjaFBhbm5lci5yZXNldFNlbnNvcigpO1xuICB9XG59O1xuXG5GdXNpb25Qb3NlU2Vuc29yLnByb3RvdHlwZS5vbkRldmljZU1vdGlvbl8gPSBmdW5jdGlvbihkZXZpY2VNb3Rpb24pIHtcbiAgdGhpcy51cGRhdGVEZXZpY2VNb3Rpb25fKGRldmljZU1vdGlvbik7XG59O1xuXG5GdXNpb25Qb3NlU2Vuc29yLnByb3RvdHlwZS51cGRhdGVEZXZpY2VNb3Rpb25fID0gZnVuY3Rpb24oZGV2aWNlTW90aW9uKSB7XG4gIHZhciBhY2NHcmF2aXR5ID0gZGV2aWNlTW90aW9uLmFjY2VsZXJhdGlvbkluY2x1ZGluZ0dyYXZpdHk7XG4gIHZhciByb3RSYXRlID0gZGV2aWNlTW90aW9uLnJvdGF0aW9uUmF0ZTtcbiAgdmFyIHRpbWVzdGFtcFMgPSBkZXZpY2VNb3Rpb24udGltZVN0YW1wIC8gMTAwMDtcblxuICAvLyBGaXJlZm94IEFuZHJvaWQgdGltZVN0YW1wIHJldHVybnMgb25lIHRob3VzYW5kdGggb2YgYSBtaWxsaXNlY29uZC5cbiAgaWYgKHRoaXMuaXNGaXJlZm94QW5kcm9pZCkge1xuICAgIHRpbWVzdGFtcFMgLz0gMTAwMDtcbiAgfVxuXG4gIHZhciBkZWx0YVMgPSB0aW1lc3RhbXBTIC0gdGhpcy5wcmV2aW91c1RpbWVzdGFtcFM7XG4gIGlmIChkZWx0YVMgPD0gVXRpbC5NSU5fVElNRVNURVAgfHwgZGVsdGFTID4gVXRpbC5NQVhfVElNRVNURVApIHtcbiAgICBjb25zb2xlLndhcm4oJ0ludmFsaWQgdGltZXN0YW1wcyBkZXRlY3RlZC4gVGltZSBzdGVwIGJldHdlZW4gc3VjY2Vzc2l2ZSAnICtcbiAgICAgICAgICAgICAgICAgJ2d5cm9zY29wZSBzZW5zb3Igc2FtcGxlcyBpcyB2ZXJ5IHNtYWxsIG9yIG5vdCBtb25vdG9uaWMnKTtcbiAgICB0aGlzLnByZXZpb3VzVGltZXN0YW1wUyA9IHRpbWVzdGFtcFM7XG4gICAgcmV0dXJuO1xuICB9XG4gIHRoaXMuYWNjZWxlcm9tZXRlci5zZXQoLWFjY0dyYXZpdHkueCwgLWFjY0dyYXZpdHkueSwgLWFjY0dyYXZpdHkueik7XG4gIHRoaXMuZ3lyb3Njb3BlLnNldChyb3RSYXRlLmFscGhhLCByb3RSYXRlLmJldGEsIHJvdFJhdGUuZ2FtbWEpO1xuXG4gIC8vIFdpdGggaU9TIGFuZCBGaXJlZm94IEFuZHJvaWQsIHJvdGF0aW9uUmF0ZSBpcyByZXBvcnRlZCBpbiBkZWdyZWVzLFxuICAvLyBzbyB3ZSBmaXJzdCBjb252ZXJ0IHRvIHJhZGlhbnMuXG4gIGlmICh0aGlzLmlzSU9TIHx8IHRoaXMuaXNGaXJlZm94QW5kcm9pZCkge1xuICAgIHRoaXMuZ3lyb3Njb3BlLm11bHRpcGx5U2NhbGFyKE1hdGguUEkgLyAxODApO1xuICB9XG5cbiAgdGhpcy5maWx0ZXIuYWRkQWNjZWxNZWFzdXJlbWVudCh0aGlzLmFjY2VsZXJvbWV0ZXIsIHRpbWVzdGFtcFMpO1xuICB0aGlzLmZpbHRlci5hZGRHeXJvTWVhc3VyZW1lbnQodGhpcy5neXJvc2NvcGUsIHRpbWVzdGFtcFMpO1xuXG4gIHRoaXMucHJldmlvdXNUaW1lc3RhbXBTID0gdGltZXN0YW1wUztcbn07XG5cbkZ1c2lvblBvc2VTZW5zb3IucHJvdG90eXBlLm9uT3JpZW50YXRpb25DaGFuZ2VfID0gZnVuY3Rpb24oc2NyZWVuT3JpZW50YXRpb24pIHtcbiAgdGhpcy5zZXRTY3JlZW5UcmFuc2Zvcm1fKCk7XG59O1xuXG4vKipcbiAqIFRoaXMgaXMgb25seSBuZWVkZWQgaWYgd2UgYXJlIGluIGFuIGNyb3NzIG9yaWdpbiBpZnJhbWUgb24gaU9TIHRvIHdvcmsgYXJvdW5kXG4gKiB0aGlzIGlzc3VlOiBodHRwczovL2J1Z3Mud2Via2l0Lm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MTUyMjk5LlxuICovXG5GdXNpb25Qb3NlU2Vuc29yLnByb3RvdHlwZS5vbk1lc3NhZ2VfID0gZnVuY3Rpb24oZXZlbnQpIHtcbiAgdmFyIG1lc3NhZ2UgPSBldmVudC5kYXRhO1xuXG4gIC8vIElmIHRoZXJlJ3Mgbm8gbWVzc2FnZSB0eXBlLCBpZ25vcmUgaXQuXG4gIGlmICghbWVzc2FnZSB8fCAhbWVzc2FnZS50eXBlKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gSWdub3JlIGFsbCBtZXNzYWdlcyB0aGF0IGFyZW4ndCBkZXZpY2Vtb3Rpb24uXG4gIHZhciB0eXBlID0gbWVzc2FnZS50eXBlLnRvTG93ZXJDYXNlKCk7XG4gIGlmICh0eXBlICE9PSAnZGV2aWNlbW90aW9uJykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIFVwZGF0ZSBkZXZpY2UgbW90aW9uLlxuICB0aGlzLnVwZGF0ZURldmljZU1vdGlvbl8obWVzc2FnZS5kZXZpY2VNb3Rpb25FdmVudCk7XG59O1xuXG5GdXNpb25Qb3NlU2Vuc29yLnByb3RvdHlwZS5zZXRTY3JlZW5UcmFuc2Zvcm1fID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMud29ybGRUb1NjcmVlblEuc2V0KDAsIDAsIDAsIDEpO1xuICBzd2l0Y2ggKHdpbmRvdy5vcmllbnRhdGlvbikge1xuICAgIGNhc2UgMDpcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgOTA6XG4gICAgICB0aGlzLndvcmxkVG9TY3JlZW5RLnNldEZyb21BeGlzQW5nbGUobmV3IE1hdGhVdGlsLlZlY3RvcjMoMCwgMCwgMSksIC1NYXRoLlBJIC8gMik7XG4gICAgICBicmVhaztcbiAgICBjYXNlIC05MDpcbiAgICAgIHRoaXMud29ybGRUb1NjcmVlblEuc2V0RnJvbUF4aXNBbmdsZShuZXcgTWF0aFV0aWwuVmVjdG9yMygwLCAwLCAxKSwgTWF0aC5QSSAvIDIpO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAxODA6XG4gICAgICAvLyBUT0RPLlxuICAgICAgYnJlYWs7XG4gIH1cbiAgdGhpcy5pbnZlcnNlV29ybGRUb1NjcmVlblEuY29weSh0aGlzLndvcmxkVG9TY3JlZW5RKTtcbiAgdGhpcy5pbnZlcnNlV29ybGRUb1NjcmVlblEuaW52ZXJzZSgpO1xufTtcblxuRnVzaW9uUG9zZVNlbnNvci5wcm90b3R5cGUuc3RhcnQgPSBmdW5jdGlvbigpIHtcbiAgdGhpcy5vbkRldmljZU1vdGlvbkNhbGxiYWNrXyA9IHRoaXMub25EZXZpY2VNb3Rpb25fLmJpbmQodGhpcyk7XG4gIHRoaXMub25PcmllbnRhdGlvbkNoYW5nZUNhbGxiYWNrXyA9IHRoaXMub25PcmllbnRhdGlvbkNoYW5nZV8uYmluZCh0aGlzKTtcbiAgdGhpcy5vbk1lc3NhZ2VDYWxsYmFja18gPSB0aGlzLm9uTWVzc2FnZV8uYmluZCh0aGlzKTtcblxuICAvLyBPbmx5IGxpc3RlbiBmb3IgcG9zdE1lc3NhZ2VzIGlmIHdlJ3JlIGluIGFuIGlPUy4gTm90ZTogdGhlcmUncyBubyByZWxpYWJsZVxuICAvLyB3YXkgdG8ga25vdyBpZiB3ZSdyZSBpbiBhIGNyb3NzLWRvbWFpbiBpZnJhbWU6IGh0dHBzOi8vZ29vLmdsL0s2aGxFLlxuICBpZiAoVXRpbC5pc0lPUygpICYmIFV0aWwuaXNJbnNpZGVDcm9zc0RvbWFpbklGcmFtZSgpKSB7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCB0aGlzLm9uTWVzc2FnZUNhbGxiYWNrXyk7XG4gIH1cbiAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ29yaWVudGF0aW9uY2hhbmdlJywgdGhpcy5vbk9yaWVudGF0aW9uQ2hhbmdlQ2FsbGJhY2tfKTtcbiAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ2RldmljZW1vdGlvbicsIHRoaXMub25EZXZpY2VNb3Rpb25DYWxsYmFja18pO1xufTtcblxuRnVzaW9uUG9zZVNlbnNvci5wcm90b3R5cGUuc3RvcCA9IGZ1bmN0aW9uKCkge1xuICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignZGV2aWNlbW90aW9uJywgdGhpcy5vbkRldmljZU1vdGlvbkNhbGxiYWNrXyk7XG4gIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdvcmllbnRhdGlvbmNoYW5nZScsIHRoaXMub25PcmllbnRhdGlvbkNoYW5nZUNhbGxiYWNrXyk7XG4gIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgdGhpcy5vbk1lc3NhZ2VDYWxsYmFja18pO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBGdXNpb25Qb3NlU2Vuc29yO1xuXG59LHtcIi4uL21hdGgtdXRpbC5qc1wiOjE0LFwiLi4vdG91Y2gtcGFubmVyLmpzXCI6MjEsXCIuLi91dGlsLmpzXCI6MjIsXCIuL2NvbXBsZW1lbnRhcnktZmlsdGVyLmpzXCI6MTcsXCIuL3Bvc2UtcHJlZGljdG9yLmpzXCI6MTl9XSwxOTpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4vKlxuICogQ29weXJpZ2h0IDIwMTUgR29vZ2xlIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xudmFyIE1hdGhVdGlsID0gX2RlcmVxXygnLi4vbWF0aC11dGlsJyk7XG52YXIgVXRpbCA9IF9kZXJlcV8oJy4uL3V0aWwnKTtcblxuLyoqXG4gKiBHaXZlbiBhbiBvcmllbnRhdGlvbiBhbmQgdGhlIGd5cm9zY29wZSBkYXRhLCBwcmVkaWN0cyB0aGUgZnV0dXJlIG9yaWVudGF0aW9uXG4gKiBvZiB0aGUgaGVhZC4gVGhpcyBtYWtlcyByZW5kZXJpbmcgYXBwZWFyIGZhc3Rlci5cbiAqXG4gKiBBbHNvIHNlZTogaHR0cDovL21zbC5jcy51aXVjLmVkdS9+bGF2YWxsZS9wYXBlcnMvTGF2WWVyS2F0QW50MTQucGRmXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IHByZWRpY3Rpb25UaW1lUyB0aW1lIGZyb20gaGVhZCBtb3ZlbWVudCB0byB0aGUgYXBwZWFyYW5jZSBvZlxuICogdGhlIGNvcnJlc3BvbmRpbmcgaW1hZ2UuXG4gKi9cbmZ1bmN0aW9uIFBvc2VQcmVkaWN0b3IocHJlZGljdGlvblRpbWVTKSB7XG4gIHRoaXMucHJlZGljdGlvblRpbWVTID0gcHJlZGljdGlvblRpbWVTO1xuXG4gIC8vIFRoZSBxdWF0ZXJuaW9uIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHByZXZpb3VzIHN0YXRlLlxuICB0aGlzLnByZXZpb3VzUSA9IG5ldyBNYXRoVXRpbC5RdWF0ZXJuaW9uKCk7XG4gIC8vIFByZXZpb3VzIHRpbWUgYSBwcmVkaWN0aW9uIG9jY3VycmVkLlxuICB0aGlzLnByZXZpb3VzVGltZXN0YW1wUyA9IG51bGw7XG5cbiAgLy8gVGhlIGRlbHRhIHF1YXRlcm5pb24gdGhhdCBhZGp1c3RzIHRoZSBjdXJyZW50IHBvc2UuXG4gIHRoaXMuZGVsdGFRID0gbmV3IE1hdGhVdGlsLlF1YXRlcm5pb24oKTtcbiAgLy8gVGhlIG91dHB1dCBxdWF0ZXJuaW9uLlxuICB0aGlzLm91dFEgPSBuZXcgTWF0aFV0aWwuUXVhdGVybmlvbigpO1xufVxuXG5Qb3NlUHJlZGljdG9yLnByb3RvdHlwZS5nZXRQcmVkaWN0aW9uID0gZnVuY3Rpb24oY3VycmVudFEsIGd5cm8sIHRpbWVzdGFtcFMpIHtcbiAgaWYgKCF0aGlzLnByZXZpb3VzVGltZXN0YW1wUykge1xuICAgIHRoaXMucHJldmlvdXNRLmNvcHkoY3VycmVudFEpO1xuICAgIHRoaXMucHJldmlvdXNUaW1lc3RhbXBTID0gdGltZXN0YW1wUztcbiAgICByZXR1cm4gY3VycmVudFE7XG4gIH1cblxuICAvLyBDYWxjdWxhdGUgYXhpcyBhbmQgYW5nbGUgYmFzZWQgb24gZ3lyb3Njb3BlIHJvdGF0aW9uIHJhdGUgZGF0YS5cbiAgdmFyIGF4aXMgPSBuZXcgTWF0aFV0aWwuVmVjdG9yMygpO1xuICBheGlzLmNvcHkoZ3lybyk7XG4gIGF4aXMubm9ybWFsaXplKCk7XG5cbiAgdmFyIGFuZ3VsYXJTcGVlZCA9IGd5cm8ubGVuZ3RoKCk7XG5cbiAgLy8gSWYgd2UncmUgcm90YXRpbmcgc2xvd2x5LCBkb24ndCBkbyBwcmVkaWN0aW9uLlxuICBpZiAoYW5ndWxhclNwZWVkIDwgTWF0aFV0aWwuZGVnVG9SYWQgKiAyMCkge1xuICAgIGlmIChVdGlsLmlzRGVidWcoKSkge1xuICAgICAgY29uc29sZS5sb2coJ01vdmluZyBzbG93bHksIGF0ICVzIGRlZy9zOiBubyBwcmVkaWN0aW9uJyxcbiAgICAgICAgICAgICAgICAgIChNYXRoVXRpbC5yYWRUb0RlZyAqIGFuZ3VsYXJTcGVlZCkudG9GaXhlZCgxKSk7XG4gICAgfVxuICAgIHRoaXMub3V0US5jb3B5KGN1cnJlbnRRKTtcbiAgICB0aGlzLnByZXZpb3VzUS5jb3B5KGN1cnJlbnRRKTtcbiAgICByZXR1cm4gdGhpcy5vdXRRO1xuICB9XG5cbiAgLy8gR2V0IHRoZSBwcmVkaWN0ZWQgYW5nbGUgYmFzZWQgb24gdGhlIHRpbWUgZGVsdGEgYW5kIGxhdGVuY3kuXG4gIHZhciBkZWx0YVQgPSB0aW1lc3RhbXBTIC0gdGhpcy5wcmV2aW91c1RpbWVzdGFtcFM7XG4gIHZhciBwcmVkaWN0QW5nbGUgPSBhbmd1bGFyU3BlZWQgKiB0aGlzLnByZWRpY3Rpb25UaW1lUztcblxuICB0aGlzLmRlbHRhUS5zZXRGcm9tQXhpc0FuZ2xlKGF4aXMsIHByZWRpY3RBbmdsZSk7XG4gIHRoaXMub3V0US5jb3B5KHRoaXMucHJldmlvdXNRKTtcbiAgdGhpcy5vdXRRLm11bHRpcGx5KHRoaXMuZGVsdGFRKTtcblxuICB0aGlzLnByZXZpb3VzUS5jb3B5KGN1cnJlbnRRKTtcbiAgdGhpcy5wcmV2aW91c1RpbWVzdGFtcFMgPSB0aW1lc3RhbXBTO1xuXG4gIHJldHVybiB0aGlzLm91dFE7XG59O1xuXG5cbm1vZHVsZS5leHBvcnRzID0gUG9zZVByZWRpY3RvcjtcblxufSx7XCIuLi9tYXRoLXV0aWxcIjoxNCxcIi4uL3V0aWxcIjoyMn1dLDIwOltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcbmZ1bmN0aW9uIFNlbnNvclNhbXBsZShzYW1wbGUsIHRpbWVzdGFtcFMpIHtcbiAgdGhpcy5zZXQoc2FtcGxlLCB0aW1lc3RhbXBTKTtcbn07XG5cblNlbnNvclNhbXBsZS5wcm90b3R5cGUuc2V0ID0gZnVuY3Rpb24oc2FtcGxlLCB0aW1lc3RhbXBTKSB7XG4gIHRoaXMuc2FtcGxlID0gc2FtcGxlO1xuICB0aGlzLnRpbWVzdGFtcFMgPSB0aW1lc3RhbXBTO1xufTtcblxuU2Vuc29yU2FtcGxlLnByb3RvdHlwZS5jb3B5ID0gZnVuY3Rpb24oc2Vuc29yU2FtcGxlKSB7XG4gIHRoaXMuc2V0KHNlbnNvclNhbXBsZS5zYW1wbGUsIHNlbnNvclNhbXBsZS50aW1lc3RhbXBTKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gU2Vuc29yU2FtcGxlO1xuXG59LHt9XSwyMTpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4vKlxuICogQ29weXJpZ2h0IDIwMTUgR29vZ2xlIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xudmFyIE1hdGhVdGlsID0gX2RlcmVxXygnLi9tYXRoLXV0aWwuanMnKTtcbnZhciBVdGlsID0gX2RlcmVxXygnLi91dGlsLmpzJyk7XG5cbnZhciBST1RBVEVfU1BFRUQgPSAwLjU7XG4vKipcbiAqIFByb3ZpZGVzIGEgcXVhdGVybmlvbiByZXNwb25zaWJsZSBmb3IgcHJlLXBhbm5pbmcgdGhlIHNjZW5lIGJlZm9yZSBmdXJ0aGVyXG4gKiB0cmFuc2Zvcm1hdGlvbnMgZHVlIHRvIGRldmljZSBzZW5zb3JzLlxuICovXG5mdW5jdGlvbiBUb3VjaFBhbm5lcigpIHtcbiAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoc3RhcnQnLCB0aGlzLm9uVG91Y2hTdGFydF8uYmluZCh0aGlzKSk7XG4gIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCd0b3VjaG1vdmUnLCB0aGlzLm9uVG91Y2hNb3ZlXy5iaW5kKHRoaXMpKTtcbiAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoZW5kJywgdGhpcy5vblRvdWNoRW5kXy5iaW5kKHRoaXMpKTtcblxuICB0aGlzLmlzVG91Y2hpbmcgPSBmYWxzZTtcbiAgdGhpcy5yb3RhdGVTdGFydCA9IG5ldyBNYXRoVXRpbC5WZWN0b3IyKCk7XG4gIHRoaXMucm90YXRlRW5kID0gbmV3IE1hdGhVdGlsLlZlY3RvcjIoKTtcbiAgdGhpcy5yb3RhdGVEZWx0YSA9IG5ldyBNYXRoVXRpbC5WZWN0b3IyKCk7XG5cbiAgdGhpcy50aGV0YSA9IDA7XG4gIHRoaXMub3JpZW50YXRpb24gPSBuZXcgTWF0aFV0aWwuUXVhdGVybmlvbigpO1xufVxuXG5Ub3VjaFBhbm5lci5wcm90b3R5cGUuZ2V0T3JpZW50YXRpb24gPSBmdW5jdGlvbigpIHtcbiAgdGhpcy5vcmllbnRhdGlvbi5zZXRGcm9tRXVsZXJYWVooMCwgMCwgdGhpcy50aGV0YSk7XG4gIHJldHVybiB0aGlzLm9yaWVudGF0aW9uO1xufTtcblxuVG91Y2hQYW5uZXIucHJvdG90eXBlLnJlc2V0U2Vuc29yID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMudGhldGEgPSAwO1xufTtcblxuVG91Y2hQYW5uZXIucHJvdG90eXBlLm9uVG91Y2hTdGFydF8gPSBmdW5jdGlvbihlKSB7XG4gIC8vIE9ubHkgcmVzcG9uZCBpZiB0aGVyZSBpcyBleGFjdGx5IG9uZSB0b3VjaC5cbiAgaWYgKGUudG91Y2hlcy5sZW5ndGggIT0gMSkge1xuICAgIHJldHVybjtcbiAgfVxuICB0aGlzLnJvdGF0ZVN0YXJ0LnNldChlLnRvdWNoZXNbMF0ucGFnZVgsIGUudG91Y2hlc1swXS5wYWdlWSk7XG4gIHRoaXMuaXNUb3VjaGluZyA9IHRydWU7XG59O1xuXG5Ub3VjaFBhbm5lci5wcm90b3R5cGUub25Ub3VjaE1vdmVfID0gZnVuY3Rpb24oZSkge1xuICBpZiAoIXRoaXMuaXNUb3VjaGluZykge1xuICAgIHJldHVybjtcbiAgfVxuICB0aGlzLnJvdGF0ZUVuZC5zZXQoZS50b3VjaGVzWzBdLnBhZ2VYLCBlLnRvdWNoZXNbMF0ucGFnZVkpO1xuICB0aGlzLnJvdGF0ZURlbHRhLnN1YlZlY3RvcnModGhpcy5yb3RhdGVFbmQsIHRoaXMucm90YXRlU3RhcnQpO1xuICB0aGlzLnJvdGF0ZVN0YXJ0LmNvcHkodGhpcy5yb3RhdGVFbmQpO1xuXG4gIC8vIE9uIGlPUywgZGlyZWN0aW9uIGlzIGludmVydGVkLlxuICBpZiAoVXRpbC5pc0lPUygpKSB7XG4gICAgdGhpcy5yb3RhdGVEZWx0YS54ICo9IC0xO1xuICB9XG5cbiAgdmFyIGVsZW1lbnQgPSBkb2N1bWVudC5ib2R5O1xuICB0aGlzLnRoZXRhICs9IDIgKiBNYXRoLlBJICogdGhpcy5yb3RhdGVEZWx0YS54IC8gZWxlbWVudC5jbGllbnRXaWR0aCAqIFJPVEFURV9TUEVFRDtcbn07XG5cblRvdWNoUGFubmVyLnByb3RvdHlwZS5vblRvdWNoRW5kXyA9IGZ1bmN0aW9uKGUpIHtcbiAgdGhpcy5pc1RvdWNoaW5nID0gZmFsc2U7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFRvdWNoUGFubmVyO1xuXG59LHtcIi4vbWF0aC11dGlsLmpzXCI6MTQsXCIuL3V0aWwuanNcIjoyMn1dLDIyOltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcbi8qXG4gKiBDb3B5cmlnaHQgMjAxNSBHb29nbGUgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbnZhciBvYmplY3RBc3NpZ24gPSBfZGVyZXFfKCdvYmplY3QtYXNzaWduJyk7XG5cbnZhciBVdGlsID0gd2luZG93LlV0aWwgfHwge307XG5cblV0aWwuTUlOX1RJTUVTVEVQID0gMC4wMDE7XG5VdGlsLk1BWF9USU1FU1RFUCA9IDE7XG5cblV0aWwuYmFzZTY0ID0gZnVuY3Rpb24obWltZVR5cGUsIGJhc2U2NCkge1xuICByZXR1cm4gJ2RhdGE6JyArIG1pbWVUeXBlICsgJztiYXNlNjQsJyArIGJhc2U2NDtcbn07XG5cblV0aWwuY2xhbXAgPSBmdW5jdGlvbih2YWx1ZSwgbWluLCBtYXgpIHtcbiAgcmV0dXJuIE1hdGgubWluKE1hdGgubWF4KG1pbiwgdmFsdWUpLCBtYXgpO1xufTtcblxuVXRpbC5sZXJwID0gZnVuY3Rpb24oYSwgYiwgdCkge1xuICByZXR1cm4gYSArICgoYiAtIGEpICogdCk7XG59O1xuXG5VdGlsLmlzSU9TID0gKGZ1bmN0aW9uKCkge1xuICB2YXIgaXNJT1MgPSAvaVBhZHxpUGhvbmV8aVBvZC8udGVzdChuYXZpZ2F0b3IucGxhdGZvcm0pO1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGlzSU9TO1xuICB9O1xufSkoKTtcblxuVXRpbC5pc1NhZmFyaSA9IChmdW5jdGlvbigpIHtcbiAgdmFyIGlzU2FmYXJpID0gL14oKD8hY2hyb21lfGFuZHJvaWQpLikqc2FmYXJpL2kudGVzdChuYXZpZ2F0b3IudXNlckFnZW50KTtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBpc1NhZmFyaTtcbiAgfTtcbn0pKCk7XG5cblV0aWwuaXNGaXJlZm94QW5kcm9pZCA9IChmdW5jdGlvbigpIHtcbiAgdmFyIGlzRmlyZWZveEFuZHJvaWQgPSBuYXZpZ2F0b3IudXNlckFnZW50LmluZGV4T2YoJ0ZpcmVmb3gnKSAhPT0gLTEgJiZcbiAgICAgIG5hdmlnYXRvci51c2VyQWdlbnQuaW5kZXhPZignQW5kcm9pZCcpICE9PSAtMTtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBpc0ZpcmVmb3hBbmRyb2lkO1xuICB9O1xufSkoKTtcblxuVXRpbC5pc0xhbmRzY2FwZU1vZGUgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuICh3aW5kb3cub3JpZW50YXRpb24gPT0gOTAgfHwgd2luZG93Lm9yaWVudGF0aW9uID09IC05MCk7XG59O1xuXG4vLyBIZWxwZXIgbWV0aG9kIHRvIHZhbGlkYXRlIHRoZSB0aW1lIHN0ZXBzIG9mIHNlbnNvciB0aW1lc3RhbXBzLlxuVXRpbC5pc1RpbWVzdGFtcERlbHRhVmFsaWQgPSBmdW5jdGlvbih0aW1lc3RhbXBEZWx0YVMpIHtcbiAgaWYgKGlzTmFOKHRpbWVzdGFtcERlbHRhUykpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKHRpbWVzdGFtcERlbHRhUyA8PSBVdGlsLk1JTl9USU1FU1RFUCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAodGltZXN0YW1wRGVsdGFTID4gVXRpbC5NQVhfVElNRVNURVApIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59O1xuXG5VdGlsLmdldFNjcmVlbldpZHRoID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiBNYXRoLm1heCh3aW5kb3cuc2NyZWVuLndpZHRoLCB3aW5kb3cuc2NyZWVuLmhlaWdodCkgKlxuICAgICAgd2luZG93LmRldmljZVBpeGVsUmF0aW87XG59O1xuXG5VdGlsLmdldFNjcmVlbkhlaWdodCA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gTWF0aC5taW4od2luZG93LnNjcmVlbi53aWR0aCwgd2luZG93LnNjcmVlbi5oZWlnaHQpICpcbiAgICAgIHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvO1xufTtcblxuVXRpbC5yZXF1ZXN0RnVsbHNjcmVlbiA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgaWYgKGVsZW1lbnQucmVxdWVzdEZ1bGxzY3JlZW4pIHtcbiAgICBlbGVtZW50LnJlcXVlc3RGdWxsc2NyZWVuKCk7XG4gIH0gZWxzZSBpZiAoZWxlbWVudC53ZWJraXRSZXF1ZXN0RnVsbHNjcmVlbikge1xuICAgIGVsZW1lbnQud2Via2l0UmVxdWVzdEZ1bGxzY3JlZW4oKTtcbiAgfSBlbHNlIGlmIChlbGVtZW50Lm1velJlcXVlc3RGdWxsU2NyZWVuKSB7XG4gICAgZWxlbWVudC5tb3pSZXF1ZXN0RnVsbFNjcmVlbigpO1xuICB9IGVsc2UgaWYgKGVsZW1lbnQubXNSZXF1ZXN0RnVsbHNjcmVlbikge1xuICAgIGVsZW1lbnQubXNSZXF1ZXN0RnVsbHNjcmVlbigpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiB0cnVlO1xufTtcblxuVXRpbC5leGl0RnVsbHNjcmVlbiA9IGZ1bmN0aW9uKCkge1xuICBpZiAoZG9jdW1lbnQuZXhpdEZ1bGxzY3JlZW4pIHtcbiAgICBkb2N1bWVudC5leGl0RnVsbHNjcmVlbigpO1xuICB9IGVsc2UgaWYgKGRvY3VtZW50LndlYmtpdEV4aXRGdWxsc2NyZWVuKSB7XG4gICAgZG9jdW1lbnQud2Via2l0RXhpdEZ1bGxzY3JlZW4oKTtcbiAgfSBlbHNlIGlmIChkb2N1bWVudC5tb3pDYW5jZWxGdWxsU2NyZWVuKSB7XG4gICAgZG9jdW1lbnQubW96Q2FuY2VsRnVsbFNjcmVlbigpO1xuICB9IGVsc2UgaWYgKGRvY3VtZW50Lm1zRXhpdEZ1bGxzY3JlZW4pIHtcbiAgICBkb2N1bWVudC5tc0V4aXRGdWxsc2NyZWVuKCk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59O1xuXG5VdGlsLmdldEZ1bGxzY3JlZW5FbGVtZW50ID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiBkb2N1bWVudC5mdWxsc2NyZWVuRWxlbWVudCB8fFxuICAgICAgZG9jdW1lbnQud2Via2l0RnVsbHNjcmVlbkVsZW1lbnQgfHxcbiAgICAgIGRvY3VtZW50Lm1vekZ1bGxTY3JlZW5FbGVtZW50IHx8XG4gICAgICBkb2N1bWVudC5tc0Z1bGxzY3JlZW5FbGVtZW50O1xufTtcblxuVXRpbC5saW5rUHJvZ3JhbSA9IGZ1bmN0aW9uKGdsLCB2ZXJ0ZXhTb3VyY2UsIGZyYWdtZW50U291cmNlLCBhdHRyaWJMb2NhdGlvbk1hcCkge1xuICAvLyBObyBlcnJvciBjaGVja2luZyBmb3IgYnJldml0eS5cbiAgdmFyIHZlcnRleFNoYWRlciA9IGdsLmNyZWF0ZVNoYWRlcihnbC5WRVJURVhfU0hBREVSKTtcbiAgZ2wuc2hhZGVyU291cmNlKHZlcnRleFNoYWRlciwgdmVydGV4U291cmNlKTtcbiAgZ2wuY29tcGlsZVNoYWRlcih2ZXJ0ZXhTaGFkZXIpO1xuXG4gIHZhciBmcmFnbWVudFNoYWRlciA9IGdsLmNyZWF0ZVNoYWRlcihnbC5GUkFHTUVOVF9TSEFERVIpO1xuICBnbC5zaGFkZXJTb3VyY2UoZnJhZ21lbnRTaGFkZXIsIGZyYWdtZW50U291cmNlKTtcbiAgZ2wuY29tcGlsZVNoYWRlcihmcmFnbWVudFNoYWRlcik7XG5cbiAgdmFyIHByb2dyYW0gPSBnbC5jcmVhdGVQcm9ncmFtKCk7XG4gIGdsLmF0dGFjaFNoYWRlcihwcm9ncmFtLCB2ZXJ0ZXhTaGFkZXIpO1xuICBnbC5hdHRhY2hTaGFkZXIocHJvZ3JhbSwgZnJhZ21lbnRTaGFkZXIpO1xuXG4gIGZvciAodmFyIGF0dHJpYk5hbWUgaW4gYXR0cmliTG9jYXRpb25NYXApXG4gICAgZ2wuYmluZEF0dHJpYkxvY2F0aW9uKHByb2dyYW0sIGF0dHJpYkxvY2F0aW9uTWFwW2F0dHJpYk5hbWVdLCBhdHRyaWJOYW1lKTtcblxuICBnbC5saW5rUHJvZ3JhbShwcm9ncmFtKTtcblxuICBnbC5kZWxldGVTaGFkZXIodmVydGV4U2hhZGVyKTtcbiAgZ2wuZGVsZXRlU2hhZGVyKGZyYWdtZW50U2hhZGVyKTtcblxuICByZXR1cm4gcHJvZ3JhbTtcbn07XG5cblV0aWwuZ2V0UHJvZ3JhbVVuaWZvcm1zID0gZnVuY3Rpb24oZ2wsIHByb2dyYW0pIHtcbiAgdmFyIHVuaWZvcm1zID0ge307XG4gIHZhciB1bmlmb3JtQ291bnQgPSBnbC5nZXRQcm9ncmFtUGFyYW1ldGVyKHByb2dyYW0sIGdsLkFDVElWRV9VTklGT1JNUyk7XG4gIHZhciB1bmlmb3JtTmFtZSA9ICcnO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IHVuaWZvcm1Db3VudDsgaSsrKSB7XG4gICAgdmFyIHVuaWZvcm1JbmZvID0gZ2wuZ2V0QWN0aXZlVW5pZm9ybShwcm9ncmFtLCBpKTtcbiAgICB1bmlmb3JtTmFtZSA9IHVuaWZvcm1JbmZvLm5hbWUucmVwbGFjZSgnWzBdJywgJycpO1xuICAgIHVuaWZvcm1zW3VuaWZvcm1OYW1lXSA9IGdsLmdldFVuaWZvcm1Mb2NhdGlvbihwcm9ncmFtLCB1bmlmb3JtTmFtZSk7XG4gIH1cbiAgcmV0dXJuIHVuaWZvcm1zO1xufTtcblxuVXRpbC5vcnRob01hdHJpeCA9IGZ1bmN0aW9uIChvdXQsIGxlZnQsIHJpZ2h0LCBib3R0b20sIHRvcCwgbmVhciwgZmFyKSB7XG4gIHZhciBsciA9IDEgLyAobGVmdCAtIHJpZ2h0KSxcbiAgICAgIGJ0ID0gMSAvIChib3R0b20gLSB0b3ApLFxuICAgICAgbmYgPSAxIC8gKG5lYXIgLSBmYXIpO1xuICBvdXRbMF0gPSAtMiAqIGxyO1xuICBvdXRbMV0gPSAwO1xuICBvdXRbMl0gPSAwO1xuICBvdXRbM10gPSAwO1xuICBvdXRbNF0gPSAwO1xuICBvdXRbNV0gPSAtMiAqIGJ0O1xuICBvdXRbNl0gPSAwO1xuICBvdXRbN10gPSAwO1xuICBvdXRbOF0gPSAwO1xuICBvdXRbOV0gPSAwO1xuICBvdXRbMTBdID0gMiAqIG5mO1xuICBvdXRbMTFdID0gMDtcbiAgb3V0WzEyXSA9IChsZWZ0ICsgcmlnaHQpICogbHI7XG4gIG91dFsxM10gPSAodG9wICsgYm90dG9tKSAqIGJ0O1xuICBvdXRbMTRdID0gKGZhciArIG5lYXIpICogbmY7XG4gIG91dFsxNV0gPSAxO1xuICByZXR1cm4gb3V0O1xufTtcblxuVXRpbC5pc01vYmlsZSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgY2hlY2sgPSBmYWxzZTtcbiAgKGZ1bmN0aW9uKGEpe2lmKC8oYW5kcm9pZHxiYlxcZCt8bWVlZ28pLittb2JpbGV8YXZhbnRnb3xiYWRhXFwvfGJsYWNrYmVycnl8YmxhemVyfGNvbXBhbHxlbGFpbmV8ZmVubmVjfGhpcHRvcHxpZW1vYmlsZXxpcChob25lfG9kKXxpcmlzfGtpbmRsZXxsZ2UgfG1hZW1vfG1pZHB8bW1wfG1vYmlsZS4rZmlyZWZveHxuZXRmcm9udHxvcGVyYSBtKG9ifGluKWl8cGFsbSggb3MpP3xwaG9uZXxwKGl4aXxyZSlcXC98cGx1Y2tlcnxwb2NrZXR8cHNwfHNlcmllcyg0fDYpMHxzeW1iaWFufHRyZW98dXBcXC4oYnJvd3NlcnxsaW5rKXx2b2RhZm9uZXx3YXB8d2luZG93cyBjZXx4ZGF8eGlpbm8vaS50ZXN0KGEpfHwvMTIwN3w2MzEwfDY1OTB8M2dzb3w0dGhwfDUwWzEtNl1pfDc3MHN8ODAyc3xhIHdhfGFiYWN8YWMoZXJ8b298c1xcLSl8YWkoa298cm4pfGFsKGF2fGNhfGNvKXxhbW9pfGFuKGV4fG55fHl3KXxhcHR1fGFyKGNofGdvKXxhcyh0ZXx1cyl8YXR0d3xhdShkaXxcXC1tfHIgfHMgKXxhdmFufGJlKGNrfGxsfG5xKXxiaShsYnxyZCl8YmwoYWN8YXopfGJyKGV8dil3fGJ1bWJ8YndcXC0obnx1KXxjNTVcXC98Y2FwaXxjY3dhfGNkbVxcLXxjZWxsfGNodG18Y2xkY3xjbWRcXC18Y28obXB8bmQpfGNyYXd8ZGEoaXR8bGx8bmcpfGRidGV8ZGNcXC1zfGRldml8ZGljYXxkbW9ifGRvKGN8cClvfGRzKDEyfFxcLWQpfGVsKDQ5fGFpKXxlbShsMnx1bCl8ZXIoaWN8azApfGVzbDh8ZXooWzQtN10wfG9zfHdhfHplKXxmZXRjfGZseShcXC18Xyl8ZzEgdXxnNTYwfGdlbmV8Z2ZcXC01fGdcXC1tb3xnbyhcXC53fG9kKXxncihhZHx1bil8aGFpZXxoY2l0fGhkXFwtKG18cHx0KXxoZWlcXC18aGkocHR8dGEpfGhwKCBpfGlwKXxoc1xcLWN8aHQoYyhcXC18IHxffGF8Z3xwfHN8dCl8dHApfGh1KGF3fHRjKXxpXFwtKDIwfGdvfG1hKXxpMjMwfGlhYyggfFxcLXxcXC8pfGlicm98aWRlYXxpZzAxfGlrb218aW0xa3xpbm5vfGlwYXF8aXJpc3xqYSh0fHYpYXxqYnJvfGplbXV8amlnc3xrZGRpfGtlaml8a2d0KCB8XFwvKXxrbG9ufGtwdCB8a3djXFwtfGt5byhjfGspfGxlKG5vfHhpKXxsZyggZ3xcXC8oa3xsfHUpfDUwfDU0fFxcLVthLXddKXxsaWJ3fGx5bnh8bTFcXC13fG0zZ2F8bTUwXFwvfG1hKHRlfHVpfHhvKXxtYygwMXwyMXxjYSl8bVxcLWNyfG1lKHJjfHJpKXxtaShvOHxvYXx0cyl8bW1lZnxtbygwMXwwMnxiaXxkZXxkb3x0KFxcLXwgfG98dil8enopfG10KDUwfHAxfHYgKXxtd2JwfG15d2F8bjEwWzAtMl18bjIwWzItM118bjMwKDB8Mil8bjUwKDB8Mnw1KXxuNygwKDB8MSl8MTApfG5lKChjfG0pXFwtfG9ufHRmfHdmfHdnfHd0KXxub2soNnxpKXxuenBofG8yaW18b3AodGl8d3YpfG9yYW58b3dnMXxwODAwfHBhbihhfGR8dCl8cGR4Z3xwZygxM3xcXC0oWzEtOF18YykpfHBoaWx8cGlyZXxwbChheXx1Yyl8cG5cXC0yfHBvKGNrfHJ0fHNlKXxwcm94fHBzaW98cHRcXC1nfHFhXFwtYXxxYygwN3wxMnwyMXwzMnw2MHxcXC1bMi03XXxpXFwtKXxxdGVrfHIzODB8cjYwMHxyYWtzfHJpbTl8cm8odmV8em8pfHM1NVxcL3xzYShnZXxtYXxtbXxtc3xueXx2YSl8c2MoMDF8aFxcLXxvb3xwXFwtKXxzZGtcXC98c2UoYyhcXC18MHwxKXw0N3xtY3xuZHxyaSl8c2doXFwtfHNoYXJ8c2llKFxcLXxtKXxza1xcLTB8c2woNDV8aWQpfHNtKGFsfGFyfGIzfGl0fHQ1KXxzbyhmdHxueSl8c3AoMDF8aFxcLXx2XFwtfHYgKXxzeSgwMXxtYil8dDIoMTh8NTApfHQ2KDAwfDEwfDE4KXx0YShndHxsayl8dGNsXFwtfHRkZ1xcLXx0ZWwoaXxtKXx0aW1cXC18dFxcLW1vfHRvKHBsfHNoKXx0cyg3MHxtXFwtfG0zfG01KXx0eFxcLTl8dXAoXFwuYnxnMXxzaSl8dXRzdHx2NDAwfHY3NTB8dmVyaXx2aShyZ3x0ZSl8dmsoNDB8NVswLTNdfFxcLXYpfHZtNDB8dm9kYXx2dWxjfHZ4KDUyfDUzfDYwfDYxfDcwfDgwfDgxfDgzfDg1fDk4KXx3M2MoXFwtfCApfHdlYmN8d2hpdHx3aShnIHxuY3xudyl8d21sYnx3b251fHg3MDB8eWFzXFwtfHlvdXJ8emV0b3x6dGVcXC0vaS50ZXN0KGEuc3Vic3RyKDAsNCkpKWNoZWNrID0gdHJ1ZX0pKG5hdmlnYXRvci51c2VyQWdlbnR8fG5hdmlnYXRvci52ZW5kb3J8fHdpbmRvdy5vcGVyYSk7XG4gIHJldHVybiBjaGVjaztcbn07XG5cblV0aWwuZXh0ZW5kID0gb2JqZWN0QXNzaWduO1xuXG5VdGlsLnNhZmFyaUNzc1NpemVXb3JrYXJvdW5kID0gZnVuY3Rpb24oY2FudmFzKSB7XG4gIC8vIFRPRE8oc211cyk6IFJlbW92ZSB0aGlzIHdvcmthcm91bmQgd2hlbiBTYWZhcmkgZm9yIGlPUyBpcyBmaXhlZC5cbiAgLy8gaU9TIG9ubHkgd29ya2Fyb3VuZCAoZm9yIGh0dHBzOi8vYnVncy53ZWJraXQub3JnL3Nob3dfYnVnLmNnaT9pZD0xNTI1NTYpLlxuICAvL1xuICAvLyBcIlRvIHRoZSBsYXN0IEkgZ3JhcHBsZSB3aXRoIHRoZWU7XG4gIC8vICBmcm9tIGhlbGwncyBoZWFydCBJIHN0YWIgYXQgdGhlZTtcbiAgLy8gIGZvciBoYXRlJ3Mgc2FrZSBJIHNwaXQgbXkgbGFzdCBicmVhdGggYXQgdGhlZS5cIlxuICAvLyAtLSBNb2J5IERpY2ssIGJ5IEhlcm1hbiBNZWx2aWxsZVxuICBpZiAoVXRpbC5pc0lPUygpKSB7XG4gICAgdmFyIHdpZHRoID0gY2FudmFzLnN0eWxlLndpZHRoO1xuICAgIHZhciBoZWlnaHQgPSBjYW52YXMuc3R5bGUuaGVpZ2h0O1xuICAgIGNhbnZhcy5zdHlsZS53aWR0aCA9IChwYXJzZUludCh3aWR0aCkgKyAxKSArICdweCc7XG4gICAgY2FudmFzLnN0eWxlLmhlaWdodCA9IChwYXJzZUludChoZWlnaHQpKSArICdweCc7XG4gICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAgICAgIGNhbnZhcy5zdHlsZS53aWR0aCA9IHdpZHRoO1xuICAgICAgY2FudmFzLnN0eWxlLmhlaWdodCA9IGhlaWdodDtcbiAgICB9LCAxMDApO1xuICB9XG5cbiAgLy8gRGVidWcgb25seS5cbiAgd2luZG93LlV0aWwgPSBVdGlsO1xuICB3aW5kb3cuY2FudmFzID0gY2FudmFzO1xufTtcblxuVXRpbC5pc0RlYnVnID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiBVdGlsLmdldFF1ZXJ5UGFyYW1ldGVyKCdkZWJ1ZycpO1xufTtcblxuVXRpbC5nZXRRdWVyeVBhcmFtZXRlciA9IGZ1bmN0aW9uKG5hbWUpIHtcbiAgdmFyIG5hbWUgPSBuYW1lLnJlcGxhY2UoL1tcXFtdLywgXCJcXFxcW1wiKS5yZXBsYWNlKC9bXFxdXS8sIFwiXFxcXF1cIik7XG4gIHZhciByZWdleCA9IG5ldyBSZWdFeHAoXCJbXFxcXD8mXVwiICsgbmFtZSArIFwiPShbXiYjXSopXCIpLFxuICAgICAgcmVzdWx0cyA9IHJlZ2V4LmV4ZWMobG9jYXRpb24uc2VhcmNoKTtcbiAgcmV0dXJuIHJlc3VsdHMgPT09IG51bGwgPyBcIlwiIDogZGVjb2RlVVJJQ29tcG9uZW50KHJlc3VsdHNbMV0ucmVwbGFjZSgvXFwrL2csIFwiIFwiKSk7XG59O1xuXG5VdGlsLmZyYW1lRGF0YUZyb21Qb3NlID0gKGZ1bmN0aW9uKCkge1xuICB2YXIgcGlPdmVyMTgwID0gTWF0aC5QSSAvIDE4MC4wO1xuICB2YXIgcmFkNDUgPSBNYXRoLlBJICogMC4yNTtcblxuICAvLyBCb3Jyb3dlZCBmcm9tIGdsTWF0cml4LlxuICBmdW5jdGlvbiBtYXQ0X3BlcnNwZWN0aXZlRnJvbUZpZWxkT2ZWaWV3KG91dCwgZm92LCBuZWFyLCBmYXIpIHtcbiAgICB2YXIgdXBUYW4gPSBNYXRoLnRhbihmb3YgPyAoZm92LnVwRGVncmVlcyAqIHBpT3ZlcjE4MCkgOiByYWQ0NSksXG4gICAgZG93blRhbiA9IE1hdGgudGFuKGZvdiA/IChmb3YuZG93bkRlZ3JlZXMgKiBwaU92ZXIxODApIDogcmFkNDUpLFxuICAgIGxlZnRUYW4gPSBNYXRoLnRhbihmb3YgPyAoZm92LmxlZnREZWdyZWVzICogcGlPdmVyMTgwKSA6IHJhZDQ1KSxcbiAgICByaWdodFRhbiA9IE1hdGgudGFuKGZvdiA/IChmb3YucmlnaHREZWdyZWVzICogcGlPdmVyMTgwKSA6IHJhZDQ1KSxcbiAgICB4U2NhbGUgPSAyLjAgLyAobGVmdFRhbiArIHJpZ2h0VGFuKSxcbiAgICB5U2NhbGUgPSAyLjAgLyAodXBUYW4gKyBkb3duVGFuKTtcblxuICAgIG91dFswXSA9IHhTY2FsZTtcbiAgICBvdXRbMV0gPSAwLjA7XG4gICAgb3V0WzJdID0gMC4wO1xuICAgIG91dFszXSA9IDAuMDtcbiAgICBvdXRbNF0gPSAwLjA7XG4gICAgb3V0WzVdID0geVNjYWxlO1xuICAgIG91dFs2XSA9IDAuMDtcbiAgICBvdXRbN10gPSAwLjA7XG4gICAgb3V0WzhdID0gLSgobGVmdFRhbiAtIHJpZ2h0VGFuKSAqIHhTY2FsZSAqIDAuNSk7XG4gICAgb3V0WzldID0gKCh1cFRhbiAtIGRvd25UYW4pICogeVNjYWxlICogMC41KTtcbiAgICBvdXRbMTBdID0gZmFyIC8gKG5lYXIgLSBmYXIpO1xuICAgIG91dFsxMV0gPSAtMS4wO1xuICAgIG91dFsxMl0gPSAwLjA7XG4gICAgb3V0WzEzXSA9IDAuMDtcbiAgICBvdXRbMTRdID0gKGZhciAqIG5lYXIpIC8gKG5lYXIgLSBmYXIpO1xuICAgIG91dFsxNV0gPSAwLjA7XG4gICAgcmV0dXJuIG91dDtcbiAgfVxuXG4gIGZ1bmN0aW9uIG1hdDRfZnJvbVJvdGF0aW9uVHJhbnNsYXRpb24ob3V0LCBxLCB2KSB7XG4gICAgLy8gUXVhdGVybmlvbiBtYXRoXG4gICAgdmFyIHggPSBxWzBdLCB5ID0gcVsxXSwgeiA9IHFbMl0sIHcgPSBxWzNdLFxuICAgICAgICB4MiA9IHggKyB4LFxuICAgICAgICB5MiA9IHkgKyB5LFxuICAgICAgICB6MiA9IHogKyB6LFxuXG4gICAgICAgIHh4ID0geCAqIHgyLFxuICAgICAgICB4eSA9IHggKiB5MixcbiAgICAgICAgeHogPSB4ICogejIsXG4gICAgICAgIHl5ID0geSAqIHkyLFxuICAgICAgICB5eiA9IHkgKiB6MixcbiAgICAgICAgenogPSB6ICogejIsXG4gICAgICAgIHd4ID0gdyAqIHgyLFxuICAgICAgICB3eSA9IHcgKiB5MixcbiAgICAgICAgd3ogPSB3ICogejI7XG5cbiAgICBvdXRbMF0gPSAxIC0gKHl5ICsgenopO1xuICAgIG91dFsxXSA9IHh5ICsgd3o7XG4gICAgb3V0WzJdID0geHogLSB3eTtcbiAgICBvdXRbM10gPSAwO1xuICAgIG91dFs0XSA9IHh5IC0gd3o7XG4gICAgb3V0WzVdID0gMSAtICh4eCArIHp6KTtcbiAgICBvdXRbNl0gPSB5eiArIHd4O1xuICAgIG91dFs3XSA9IDA7XG4gICAgb3V0WzhdID0geHogKyB3eTtcbiAgICBvdXRbOV0gPSB5eiAtIHd4O1xuICAgIG91dFsxMF0gPSAxIC0gKHh4ICsgeXkpO1xuICAgIG91dFsxMV0gPSAwO1xuICAgIG91dFsxMl0gPSB2WzBdO1xuICAgIG91dFsxM10gPSB2WzFdO1xuICAgIG91dFsxNF0gPSB2WzJdO1xuICAgIG91dFsxNV0gPSAxO1xuXG4gICAgcmV0dXJuIG91dDtcbiAgfTtcblxuICBmdW5jdGlvbiBtYXQ0X3RyYW5zbGF0ZShvdXQsIGEsIHYpIHtcbiAgICB2YXIgeCA9IHZbMF0sIHkgPSB2WzFdLCB6ID0gdlsyXSxcbiAgICAgICAgYTAwLCBhMDEsIGEwMiwgYTAzLFxuICAgICAgICBhMTAsIGExMSwgYTEyLCBhMTMsXG4gICAgICAgIGEyMCwgYTIxLCBhMjIsIGEyMztcblxuICAgIGlmIChhID09PSBvdXQpIHtcbiAgICAgIG91dFsxMl0gPSBhWzBdICogeCArIGFbNF0gKiB5ICsgYVs4XSAqIHogKyBhWzEyXTtcbiAgICAgIG91dFsxM10gPSBhWzFdICogeCArIGFbNV0gKiB5ICsgYVs5XSAqIHogKyBhWzEzXTtcbiAgICAgIG91dFsxNF0gPSBhWzJdICogeCArIGFbNl0gKiB5ICsgYVsxMF0gKiB6ICsgYVsxNF07XG4gICAgICBvdXRbMTVdID0gYVszXSAqIHggKyBhWzddICogeSArIGFbMTFdICogeiArIGFbMTVdO1xuICAgIH0gZWxzZSB7XG4gICAgICBhMDAgPSBhWzBdOyBhMDEgPSBhWzFdOyBhMDIgPSBhWzJdOyBhMDMgPSBhWzNdO1xuICAgICAgYTEwID0gYVs0XTsgYTExID0gYVs1XTsgYTEyID0gYVs2XTsgYTEzID0gYVs3XTtcbiAgICAgIGEyMCA9IGFbOF07IGEyMSA9IGFbOV07IGEyMiA9IGFbMTBdOyBhMjMgPSBhWzExXTtcblxuICAgICAgb3V0WzBdID0gYTAwOyBvdXRbMV0gPSBhMDE7IG91dFsyXSA9IGEwMjsgb3V0WzNdID0gYTAzO1xuICAgICAgb3V0WzRdID0gYTEwOyBvdXRbNV0gPSBhMTE7IG91dFs2XSA9IGExMjsgb3V0WzddID0gYTEzO1xuICAgICAgb3V0WzhdID0gYTIwOyBvdXRbOV0gPSBhMjE7IG91dFsxMF0gPSBhMjI7IG91dFsxMV0gPSBhMjM7XG5cbiAgICAgIG91dFsxMl0gPSBhMDAgKiB4ICsgYTEwICogeSArIGEyMCAqIHogKyBhWzEyXTtcbiAgICAgIG91dFsxM10gPSBhMDEgKiB4ICsgYTExICogeSArIGEyMSAqIHogKyBhWzEzXTtcbiAgICAgIG91dFsxNF0gPSBhMDIgKiB4ICsgYTEyICogeSArIGEyMiAqIHogKyBhWzE0XTtcbiAgICAgIG91dFsxNV0gPSBhMDMgKiB4ICsgYTEzICogeSArIGEyMyAqIHogKyBhWzE1XTtcbiAgICB9XG5cbiAgICByZXR1cm4gb3V0O1xuICB9O1xuXG4gIGZ1bmN0aW9uIG1hdDRfaW52ZXJ0KG91dCwgYSkge1xuICAgIHZhciBhMDAgPSBhWzBdLCBhMDEgPSBhWzFdLCBhMDIgPSBhWzJdLCBhMDMgPSBhWzNdLFxuICAgICAgICBhMTAgPSBhWzRdLCBhMTEgPSBhWzVdLCBhMTIgPSBhWzZdLCBhMTMgPSBhWzddLFxuICAgICAgICBhMjAgPSBhWzhdLCBhMjEgPSBhWzldLCBhMjIgPSBhWzEwXSwgYTIzID0gYVsxMV0sXG4gICAgICAgIGEzMCA9IGFbMTJdLCBhMzEgPSBhWzEzXSwgYTMyID0gYVsxNF0sIGEzMyA9IGFbMTVdLFxuXG4gICAgICAgIGIwMCA9IGEwMCAqIGExMSAtIGEwMSAqIGExMCxcbiAgICAgICAgYjAxID0gYTAwICogYTEyIC0gYTAyICogYTEwLFxuICAgICAgICBiMDIgPSBhMDAgKiBhMTMgLSBhMDMgKiBhMTAsXG4gICAgICAgIGIwMyA9IGEwMSAqIGExMiAtIGEwMiAqIGExMSxcbiAgICAgICAgYjA0ID0gYTAxICogYTEzIC0gYTAzICogYTExLFxuICAgICAgICBiMDUgPSBhMDIgKiBhMTMgLSBhMDMgKiBhMTIsXG4gICAgICAgIGIwNiA9IGEyMCAqIGEzMSAtIGEyMSAqIGEzMCxcbiAgICAgICAgYjA3ID0gYTIwICogYTMyIC0gYTIyICogYTMwLFxuICAgICAgICBiMDggPSBhMjAgKiBhMzMgLSBhMjMgKiBhMzAsXG4gICAgICAgIGIwOSA9IGEyMSAqIGEzMiAtIGEyMiAqIGEzMSxcbiAgICAgICAgYjEwID0gYTIxICogYTMzIC0gYTIzICogYTMxLFxuICAgICAgICBiMTEgPSBhMjIgKiBhMzMgLSBhMjMgKiBhMzIsXG5cbiAgICAgICAgLy8gQ2FsY3VsYXRlIHRoZSBkZXRlcm1pbmFudFxuICAgICAgICBkZXQgPSBiMDAgKiBiMTEgLSBiMDEgKiBiMTAgKyBiMDIgKiBiMDkgKyBiMDMgKiBiMDggLSBiMDQgKiBiMDcgKyBiMDUgKiBiMDY7XG5cbiAgICBpZiAoIWRldCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGRldCA9IDEuMCAvIGRldDtcblxuICAgIG91dFswXSA9IChhMTEgKiBiMTEgLSBhMTIgKiBiMTAgKyBhMTMgKiBiMDkpICogZGV0O1xuICAgIG91dFsxXSA9IChhMDIgKiBiMTAgLSBhMDEgKiBiMTEgLSBhMDMgKiBiMDkpICogZGV0O1xuICAgIG91dFsyXSA9IChhMzEgKiBiMDUgLSBhMzIgKiBiMDQgKyBhMzMgKiBiMDMpICogZGV0O1xuICAgIG91dFszXSA9IChhMjIgKiBiMDQgLSBhMjEgKiBiMDUgLSBhMjMgKiBiMDMpICogZGV0O1xuICAgIG91dFs0XSA9IChhMTIgKiBiMDggLSBhMTAgKiBiMTEgLSBhMTMgKiBiMDcpICogZGV0O1xuICAgIG91dFs1XSA9IChhMDAgKiBiMTEgLSBhMDIgKiBiMDggKyBhMDMgKiBiMDcpICogZGV0O1xuICAgIG91dFs2XSA9IChhMzIgKiBiMDIgLSBhMzAgKiBiMDUgLSBhMzMgKiBiMDEpICogZGV0O1xuICAgIG91dFs3XSA9IChhMjAgKiBiMDUgLSBhMjIgKiBiMDIgKyBhMjMgKiBiMDEpICogZGV0O1xuICAgIG91dFs4XSA9IChhMTAgKiBiMTAgLSBhMTEgKiBiMDggKyBhMTMgKiBiMDYpICogZGV0O1xuICAgIG91dFs5XSA9IChhMDEgKiBiMDggLSBhMDAgKiBiMTAgLSBhMDMgKiBiMDYpICogZGV0O1xuICAgIG91dFsxMF0gPSAoYTMwICogYjA0IC0gYTMxICogYjAyICsgYTMzICogYjAwKSAqIGRldDtcbiAgICBvdXRbMTFdID0gKGEyMSAqIGIwMiAtIGEyMCAqIGIwNCAtIGEyMyAqIGIwMCkgKiBkZXQ7XG4gICAgb3V0WzEyXSA9IChhMTEgKiBiMDcgLSBhMTAgKiBiMDkgLSBhMTIgKiBiMDYpICogZGV0O1xuICAgIG91dFsxM10gPSAoYTAwICogYjA5IC0gYTAxICogYjA3ICsgYTAyICogYjA2KSAqIGRldDtcbiAgICBvdXRbMTRdID0gKGEzMSAqIGIwMSAtIGEzMCAqIGIwMyAtIGEzMiAqIGIwMCkgKiBkZXQ7XG4gICAgb3V0WzE1XSA9IChhMjAgKiBiMDMgLSBhMjEgKiBiMDEgKyBhMjIgKiBiMDApICogZGV0O1xuXG4gICAgcmV0dXJuIG91dDtcbiAgfTtcblxuICB2YXIgZGVmYXVsdE9yaWVudGF0aW9uID0gbmV3IEZsb2F0MzJBcnJheShbMCwgMCwgMCwgMV0pO1xuICB2YXIgZGVmYXVsdFBvc2l0aW9uID0gbmV3IEZsb2F0MzJBcnJheShbMCwgMCwgMF0pO1xuXG4gIGZ1bmN0aW9uIHVwZGF0ZUV5ZU1hdHJpY2VzKHByb2plY3Rpb24sIHZpZXcsIHBvc2UsIHBhcmFtZXRlcnMsIHZyRGlzcGxheSkge1xuICAgIG1hdDRfcGVyc3BlY3RpdmVGcm9tRmllbGRPZlZpZXcocHJvamVjdGlvbiwgcGFyYW1ldGVycyA/IHBhcmFtZXRlcnMuZmllbGRPZlZpZXcgOiBudWxsLCB2ckRpc3BsYXkuZGVwdGhOZWFyLCB2ckRpc3BsYXkuZGVwdGhGYXIpO1xuXG4gICAgdmFyIG9yaWVudGF0aW9uID0gcG9zZS5vcmllbnRhdGlvbiB8fCBkZWZhdWx0T3JpZW50YXRpb247XG4gICAgdmFyIHBvc2l0aW9uID0gcG9zZS5wb3NpdGlvbiB8fCBkZWZhdWx0UG9zaXRpb247XG5cbiAgICBtYXQ0X2Zyb21Sb3RhdGlvblRyYW5zbGF0aW9uKHZpZXcsIG9yaWVudGF0aW9uLCBwb3NpdGlvbik7XG4gICAgaWYgKHBhcmFtZXRlcnMpXG4gICAgICBtYXQ0X3RyYW5zbGF0ZSh2aWV3LCB2aWV3LCBwYXJhbWV0ZXJzLm9mZnNldCk7XG4gICAgbWF0NF9pbnZlcnQodmlldywgdmlldyk7XG4gIH1cblxuICByZXR1cm4gZnVuY3Rpb24oZnJhbWVEYXRhLCBwb3NlLCB2ckRpc3BsYXkpIHtcbiAgICBpZiAoIWZyYW1lRGF0YSB8fCAhcG9zZSlcbiAgICAgIHJldHVybiBmYWxzZTtcblxuICAgIGZyYW1lRGF0YS5wb3NlID0gcG9zZTtcbiAgICBmcmFtZURhdGEudGltZXN0YW1wID0gcG9zZS50aW1lc3RhbXA7XG5cbiAgICB1cGRhdGVFeWVNYXRyaWNlcyhcbiAgICAgICAgZnJhbWVEYXRhLmxlZnRQcm9qZWN0aW9uTWF0cml4LCBmcmFtZURhdGEubGVmdFZpZXdNYXRyaXgsXG4gICAgICAgIHBvc2UsIHZyRGlzcGxheS5nZXRFeWVQYXJhbWV0ZXJzKFwibGVmdFwiKSwgdnJEaXNwbGF5KTtcbiAgICB1cGRhdGVFeWVNYXRyaWNlcyhcbiAgICAgICAgZnJhbWVEYXRhLnJpZ2h0UHJvamVjdGlvbk1hdHJpeCwgZnJhbWVEYXRhLnJpZ2h0Vmlld01hdHJpeCxcbiAgICAgICAgcG9zZSwgdnJEaXNwbGF5LmdldEV5ZVBhcmFtZXRlcnMoXCJyaWdodFwiKSwgdnJEaXNwbGF5KTtcblxuICAgIHJldHVybiB0cnVlO1xuICB9O1xufSkoKTtcblxuVXRpbC5pc0luc2lkZUNyb3NzRG9tYWluSUZyYW1lID0gZnVuY3Rpb24oKSB7XG4gIHZhciBpc0ZyYW1lZCA9ICh3aW5kb3cuc2VsZiAhPT0gd2luZG93LnRvcCk7XG4gIHZhciByZWZEb21haW4gPSBVdGlsLmdldERvbWFpbkZyb21VcmwoZG9jdW1lbnQucmVmZXJyZXIpO1xuICB2YXIgdGhpc0RvbWFpbiA9IFV0aWwuZ2V0RG9tYWluRnJvbVVybCh3aW5kb3cubG9jYXRpb24uaHJlZik7XG5cbiAgcmV0dXJuIGlzRnJhbWVkICYmIChyZWZEb21haW4gIT09IHRoaXNEb21haW4pO1xufTtcblxuLy8gRnJvbSBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8yMzk0NTAyNy5cblV0aWwuZ2V0RG9tYWluRnJvbVVybCA9IGZ1bmN0aW9uKHVybCkge1xuICB2YXIgZG9tYWluO1xuICAvLyBGaW5kICYgcmVtb3ZlIHByb3RvY29sIChodHRwLCBmdHAsIGV0Yy4pIGFuZCBnZXQgZG9tYWluLlxuICBpZiAodXJsLmluZGV4T2YoXCI6Ly9cIikgPiAtMSkge1xuICAgIGRvbWFpbiA9IHVybC5zcGxpdCgnLycpWzJdO1xuICB9XG4gIGVsc2Uge1xuICAgIGRvbWFpbiA9IHVybC5zcGxpdCgnLycpWzBdO1xuICB9XG5cbiAgLy9maW5kICYgcmVtb3ZlIHBvcnQgbnVtYmVyXG4gIGRvbWFpbiA9IGRvbWFpbi5zcGxpdCgnOicpWzBdO1xuXG4gIHJldHVybiBkb21haW47XG59XG5cbm1vZHVsZS5leHBvcnRzID0gVXRpbDtcblxufSx7XCJvYmplY3QtYXNzaWduXCI6Mn1dLDIzOltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcbi8qXG4gKiBDb3B5cmlnaHQgMjAxNSBHb29nbGUgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbnZhciBEZXZpY2VJbmZvID0gX2RlcmVxXygnLi9kZXZpY2UtaW5mby5qcycpO1xudmFyIEV2ZW50RW1pdHRlcjMgPSBfZGVyZXFfKCdldmVudGVtaXR0ZXIzJyk7XG52YXIgVXRpbCA9IF9kZXJlcV8oJy4vdXRpbC5qcycpO1xuXG52YXIgREVGQVVMVF9WSUVXRVIgPSAnQ2FyZGJvYXJkVjEnO1xudmFyIFZJRVdFUl9LRVkgPSAnV0VCVlJfQ0FSREJPQVJEX1ZJRVdFUic7XG52YXIgQ0xBU1NfTkFNRSA9ICd3ZWJ2ci1wb2x5ZmlsbC12aWV3ZXItc2VsZWN0b3InO1xuXG4vKipcbiAqIENyZWF0ZXMgYSB2aWV3ZXIgc2VsZWN0b3Igd2l0aCB0aGUgb3B0aW9ucyBzcGVjaWZpZWQuIFN1cHBvcnRzIGJlaW5nIHNob3duXG4gKiBhbmQgaGlkZGVuLiBHZW5lcmF0ZXMgZXZlbnRzIHdoZW4gdmlld2VyIHBhcmFtZXRlcnMgY2hhbmdlLiBBbHNvIHN1cHBvcnRzXG4gKiBzYXZpbmcgdGhlIGN1cnJlbnRseSBzZWxlY3RlZCBpbmRleCBpbiBsb2NhbFN0b3JhZ2UuXG4gKi9cbmZ1bmN0aW9uIFZpZXdlclNlbGVjdG9yKCkge1xuICAvLyBUcnkgdG8gbG9hZCB0aGUgc2VsZWN0ZWQga2V5IGZyb20gbG9jYWwgc3RvcmFnZS4gSWYgbm9uZSBleGlzdHMsIHVzZSB0aGVcbiAgLy8gZGVmYXVsdCBrZXkuXG4gIHRyeSB7XG4gICAgdGhpcy5zZWxlY3RlZEtleSA9IGxvY2FsU3RvcmFnZS5nZXRJdGVtKFZJRVdFUl9LRVkpIHx8IERFRkFVTFRfVklFV0VSO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGNvbnNvbGUuZXJyb3IoJ0ZhaWxlZCB0byBsb2FkIHZpZXdlciBwcm9maWxlOiAlcycsIGVycm9yKTtcbiAgfVxuICB0aGlzLmRpYWxvZyA9IHRoaXMuY3JlYXRlRGlhbG9nXyhEZXZpY2VJbmZvLlZpZXdlcnMpO1xuICB0aGlzLnJvb3QgPSBudWxsO1xufVxuVmlld2VyU2VsZWN0b3IucHJvdG90eXBlID0gbmV3IEV2ZW50RW1pdHRlcjMoKTtcblxuVmlld2VyU2VsZWN0b3IucHJvdG90eXBlLnNob3cgPSBmdW5jdGlvbihyb290KSB7XG4gIHRoaXMucm9vdCA9IHJvb3Q7XG5cbiAgcm9vdC5hcHBlbmRDaGlsZCh0aGlzLmRpYWxvZyk7XG5cbiAgLy8gRW5zdXJlIHRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgaXRlbSBpcyBjaGVja2VkLlxuICB2YXIgc2VsZWN0ZWQgPSB0aGlzLmRpYWxvZy5xdWVyeVNlbGVjdG9yKCcjJyArIHRoaXMuc2VsZWN0ZWRLZXkpO1xuICBzZWxlY3RlZC5jaGVja2VkID0gdHJ1ZTtcblxuICAvLyBTaG93IHRoZSBVSS5cbiAgdGhpcy5kaWFsb2cuc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG59O1xuXG5WaWV3ZXJTZWxlY3Rvci5wcm90b3R5cGUuaGlkZSA9IGZ1bmN0aW9uKCkge1xuICBpZiAodGhpcy5yb290ICYmIHRoaXMucm9vdC5jb250YWlucyh0aGlzLmRpYWxvZykpIHtcbiAgICB0aGlzLnJvb3QucmVtb3ZlQ2hpbGQodGhpcy5kaWFsb2cpO1xuICB9XG4gIHRoaXMuZGlhbG9nLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG59O1xuXG5WaWV3ZXJTZWxlY3Rvci5wcm90b3R5cGUuZ2V0Q3VycmVudFZpZXdlciA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gRGV2aWNlSW5mby5WaWV3ZXJzW3RoaXMuc2VsZWN0ZWRLZXldO1xufTtcblxuVmlld2VyU2VsZWN0b3IucHJvdG90eXBlLmdldFNlbGVjdGVkS2V5XyA9IGZ1bmN0aW9uKCkge1xuICB2YXIgaW5wdXQgPSB0aGlzLmRpYWxvZy5xdWVyeVNlbGVjdG9yKCdpbnB1dFtuYW1lPWZpZWxkXTpjaGVja2VkJyk7XG4gIGlmIChpbnB1dCkge1xuICAgIHJldHVybiBpbnB1dC5pZDtcbiAgfVxuICByZXR1cm4gbnVsbDtcbn07XG5cblZpZXdlclNlbGVjdG9yLnByb3RvdHlwZS5vblNhdmVfID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMuc2VsZWN0ZWRLZXkgPSB0aGlzLmdldFNlbGVjdGVkS2V5XygpO1xuICBpZiAoIXRoaXMuc2VsZWN0ZWRLZXkgfHwgIURldmljZUluZm8uVmlld2Vyc1t0aGlzLnNlbGVjdGVkS2V5XSkge1xuICAgIGNvbnNvbGUuZXJyb3IoJ1ZpZXdlclNlbGVjdG9yLm9uU2F2ZV86IHRoaXMgc2hvdWxkIG5ldmVyIGhhcHBlbiEnKTtcbiAgICByZXR1cm47XG4gIH1cblxuICB0aGlzLmVtaXQoJ2NoYW5nZScsIERldmljZUluZm8uVmlld2Vyc1t0aGlzLnNlbGVjdGVkS2V5XSk7XG5cbiAgLy8gQXR0ZW1wdCB0byBzYXZlIHRoZSB2aWV3ZXIgcHJvZmlsZSwgYnV0IGZhaWxzIGluIHByaXZhdGUgbW9kZS5cbiAgdHJ5IHtcbiAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbShWSUVXRVJfS0VZLCB0aGlzLnNlbGVjdGVkS2V5KTtcbiAgfSBjYXRjaChlcnJvcikge1xuICAgIGNvbnNvbGUuZXJyb3IoJ0ZhaWxlZCB0byBzYXZlIHZpZXdlciBwcm9maWxlOiAlcycsIGVycm9yKTtcbiAgfVxuICB0aGlzLmhpZGUoKTtcbn07XG5cbi8qKlxuICogQ3JlYXRlcyB0aGUgZGlhbG9nLlxuICovXG5WaWV3ZXJTZWxlY3Rvci5wcm90b3R5cGUuY3JlYXRlRGlhbG9nXyA9IGZ1bmN0aW9uKG9wdGlvbnMpIHtcbiAgdmFyIGNvbnRhaW5lciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICBjb250YWluZXIuY2xhc3NMaXN0LmFkZChDTEFTU19OQU1FKTtcbiAgY29udGFpbmVyLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gIC8vIENyZWF0ZSBhbiBvdmVybGF5IHRoYXQgZGltcyB0aGUgYmFja2dyb3VuZCwgYW5kIHdoaWNoIGdvZXMgYXdheSB3aGVuIHlvdVxuICAvLyB0YXAgaXQuXG4gIHZhciBvdmVybGF5ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gIHZhciBzID0gb3ZlcmxheS5zdHlsZTtcbiAgcy5wb3NpdGlvbiA9ICdmaXhlZCc7XG4gIHMubGVmdCA9IDA7XG4gIHMudG9wID0gMDtcbiAgcy53aWR0aCA9ICcxMDAlJztcbiAgcy5oZWlnaHQgPSAnMTAwJSc7XG4gIHMuYmFja2dyb3VuZCA9ICdyZ2JhKDAsIDAsIDAsIDAuMyknO1xuICBvdmVybGF5LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5oaWRlLmJpbmQodGhpcykpO1xuXG4gIHZhciB3aWR0aCA9IDI4MDtcbiAgdmFyIGRpYWxvZyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICB2YXIgcyA9IGRpYWxvZy5zdHlsZTtcbiAgcy5ib3hTaXppbmcgPSAnYm9yZGVyLWJveCc7XG4gIHMucG9zaXRpb24gPSAnZml4ZWQnO1xuICBzLnRvcCA9ICcyNHB4JztcbiAgcy5sZWZ0ID0gJzUwJSc7XG4gIHMubWFyZ2luTGVmdCA9ICgtd2lkdGgvMikgKyAncHgnO1xuICBzLndpZHRoID0gd2lkdGggKyAncHgnO1xuICBzLnBhZGRpbmcgPSAnMjRweCc7XG4gIHMub3ZlcmZsb3cgPSAnaGlkZGVuJztcbiAgcy5iYWNrZ3JvdW5kID0gJyNmYWZhZmEnO1xuICBzLmZvbnRGYW1pbHkgPSBcIidSb2JvdG8nLCBzYW5zLXNlcmlmXCI7XG4gIHMuYm94U2hhZG93ID0gJzBweCA1cHggMjBweCAjNjY2JztcblxuICBkaWFsb2cuYXBwZW5kQ2hpbGQodGhpcy5jcmVhdGVIMV8oJ1NlbGVjdCB5b3VyIHZpZXdlcicpKTtcbiAgZm9yICh2YXIgaWQgaW4gb3B0aW9ucykge1xuICAgIGRpYWxvZy5hcHBlbmRDaGlsZCh0aGlzLmNyZWF0ZUNob2ljZV8oaWQsIG9wdGlvbnNbaWRdLmxhYmVsKSk7XG4gIH1cbiAgZGlhbG9nLmFwcGVuZENoaWxkKHRoaXMuY3JlYXRlQnV0dG9uXygnU2F2ZScsIHRoaXMub25TYXZlXy5iaW5kKHRoaXMpKSk7XG5cbiAgY29udGFpbmVyLmFwcGVuZENoaWxkKG92ZXJsYXkpO1xuICBjb250YWluZXIuYXBwZW5kQ2hpbGQoZGlhbG9nKTtcblxuICByZXR1cm4gY29udGFpbmVyO1xufTtcblxuVmlld2VyU2VsZWN0b3IucHJvdG90eXBlLmNyZWF0ZUgxXyA9IGZ1bmN0aW9uKG5hbWUpIHtcbiAgdmFyIGgxID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaDEnKTtcbiAgdmFyIHMgPSBoMS5zdHlsZTtcbiAgcy5jb2xvciA9ICdibGFjayc7XG4gIHMuZm9udFNpemUgPSAnMjBweCc7XG4gIHMuZm9udFdlaWdodCA9ICdib2xkJztcbiAgcy5tYXJnaW5Ub3AgPSAwO1xuICBzLm1hcmdpbkJvdHRvbSA9ICcyNHB4JztcbiAgaDEuaW5uZXJIVE1MID0gbmFtZTtcbiAgcmV0dXJuIGgxO1xufTtcblxuVmlld2VyU2VsZWN0b3IucHJvdG90eXBlLmNyZWF0ZUNob2ljZV8gPSBmdW5jdGlvbihpZCwgbmFtZSkge1xuICAvKlxuICA8ZGl2IGNsYXNzPVwiY2hvaWNlXCI+XG4gIDxpbnB1dCBpZD1cInYxXCIgdHlwZT1cInJhZGlvXCIgbmFtZT1cImZpZWxkXCIgdmFsdWU9XCJ2MVwiPlxuICA8bGFiZWwgZm9yPVwidjFcIj5DYXJkYm9hcmQgVjE8L2xhYmVsPlxuICA8L2Rpdj5cbiAgKi9cbiAgdmFyIGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuICBkaXYuc3R5bGUubWFyZ2luVG9wID0gJzhweCc7XG4gIGRpdi5zdHlsZS5jb2xvciA9ICdibGFjayc7XG5cbiAgdmFyIGlucHV0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaW5wdXQnKTtcbiAgaW5wdXQuc3R5bGUuZm9udFNpemUgPSAnMzBweCc7XG4gIGlucHV0LnNldEF0dHJpYnV0ZSgnaWQnLCBpZCk7XG4gIGlucHV0LnNldEF0dHJpYnV0ZSgndHlwZScsICdyYWRpbycpO1xuICBpbnB1dC5zZXRBdHRyaWJ1dGUoJ3ZhbHVlJywgaWQpO1xuICBpbnB1dC5zZXRBdHRyaWJ1dGUoJ25hbWUnLCAnZmllbGQnKTtcblxuICB2YXIgbGFiZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdsYWJlbCcpO1xuICBsYWJlbC5zdHlsZS5tYXJnaW5MZWZ0ID0gJzRweCc7XG4gIGxhYmVsLnNldEF0dHJpYnV0ZSgnZm9yJywgaWQpO1xuICBsYWJlbC5pbm5lckhUTUwgPSBuYW1lO1xuXG4gIGRpdi5hcHBlbmRDaGlsZChpbnB1dCk7XG4gIGRpdi5hcHBlbmRDaGlsZChsYWJlbCk7XG5cbiAgcmV0dXJuIGRpdjtcbn07XG5cblZpZXdlclNlbGVjdG9yLnByb3RvdHlwZS5jcmVhdGVCdXR0b25fID0gZnVuY3Rpb24obGFiZWwsIG9uY2xpY2spIHtcbiAgdmFyIGJ1dHRvbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2J1dHRvbicpO1xuICBidXR0b24uaW5uZXJIVE1MID0gbGFiZWw7XG4gIHZhciBzID0gYnV0dG9uLnN0eWxlO1xuICBzLmZsb2F0ID0gJ3JpZ2h0JztcbiAgcy50ZXh0VHJhbnNmb3JtID0gJ3VwcGVyY2FzZSc7XG4gIHMuY29sb3IgPSAnIzEwOTRmNyc7XG4gIHMuZm9udFNpemUgPSAnMTRweCc7XG4gIHMubGV0dGVyU3BhY2luZyA9IDA7XG4gIHMuYm9yZGVyID0gMDtcbiAgcy5iYWNrZ3JvdW5kID0gJ25vbmUnO1xuICBzLm1hcmdpblRvcCA9ICcxNnB4JztcblxuICBidXR0b24uYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBvbmNsaWNrKTtcblxuICByZXR1cm4gYnV0dG9uO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBWaWV3ZXJTZWxlY3RvcjtcblxufSx7XCIuL2RldmljZS1pbmZvLmpzXCI6OCxcIi4vdXRpbC5qc1wiOjIyLFwiZXZlbnRlbWl0dGVyM1wiOjF9XSwyNDpbZnVuY3Rpb24oX2RlcmVxXyxtb2R1bGUsZXhwb3J0cyl7XG4vKlxuICogQ29weXJpZ2h0IDIwMTUgR29vZ2xlIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG52YXIgVXRpbCA9IF9kZXJlcV8oJy4vdXRpbC5qcycpO1xuXG4vKipcbiAqIEFuZHJvaWQgYW5kIGlPUyBjb21wYXRpYmxlIHdha2Vsb2NrIGltcGxlbWVudGF0aW9uLlxuICpcbiAqIFJlZmFjdG9yZWQgdGhhbmtzIHRvIGRrb3ZhbGV2QC5cbiAqL1xuZnVuY3Rpb24gQW5kcm9pZFdha2VMb2NrKCkge1xuICB2YXIgdmlkZW8gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpO1xuXG4gIHZpZGVvLmFkZEV2ZW50TGlzdGVuZXIoJ2VuZGVkJywgZnVuY3Rpb24oKSB7XG4gICAgdmlkZW8ucGxheSgpO1xuICB9KTtcblxuICB0aGlzLnJlcXVlc3QgPSBmdW5jdGlvbigpIHtcbiAgICBpZiAodmlkZW8ucGF1c2VkKSB7XG4gICAgICAvLyBCYXNlNjQgdmVyc2lvbiBvZiB2aWRlb3Nfc3JjL25vLXNsZWVwLTEyMHMubXA0LlxuICAgICAgdmlkZW8uc3JjID0gVXRpbC5iYXNlNjQoJ3ZpZGVvL21wNCcsICdBQUFBR0daMGVYQnBjMjl0QUFBQUFHMXdOREZoZG1NeEFBQUlBMjF2YjNZQUFBQnNiWFpvWkFBQUFBRFNhOXY2MG12YitnQUJYNUFBbHcvZ0FBRUFBQUVBQUFBQUFBQUFBQUFBQUFBQkFBQUFBQUFBQUFBQUFBQUFBQUFBQVFBQUFBQUFBQUFBQUFBQUFBQUFRQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFJQUFBZGtkSEpoYXdBQUFGeDBhMmhrQUFBQUFkSnIyL3JTYTl2NkFBQUFBUUFBQUFBQWx3L2dBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUJBQUFBQUFBQUFBQUFBQUFBQUFBQUFRQUFBQUFBQUFBQUFBQUFBQUFBUUFBQUFBQVFBQUFBSEFBQUFBQUFKR1ZrZEhNQUFBQWNaV3h6ZEFBQUFBQUFBQUFCQUpjUDRBQUFBQUFBQVFBQUFBQUczRzFrYVdFQUFBQWdiV1JvWkFBQUFBRFNhOXY2MG12YitnQVBRa0FHam5lQUZjY0FBQUFBQUMxb1pHeHlBQUFBQUFBQUFBQjJhV1JsQUFBQUFBQUFBQUFBQUFBQVZtbGtaVzlJWVc1a2JHVnlBQUFBQm9kdGFXNW1BQUFBRkhadGFHUUFBQUFCQUFBQUFBQUFBQUFBQUFBa1pHbHVaZ0FBQUJ4a2NtVm1BQUFBQUFBQUFBRUFBQUFNZFhKc0lBQUFBQUVBQUFaSGMzUmliQUFBQUpkemRITmtBQUFBQUFBQUFBRUFBQUNIWVhaak1RQUFBQUFBQUFBQkFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBTUFCd0FTQUFBQUVnQUFBQUFBQUFBQVFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQmovL3dBQUFERmhkbU5EQVdRQUMvL2hBQmxuWkFBTHJObGZsbHc0UUFBQUF3QkFBQUFEQUtQRkNtV0FBUUFGYU92c3Npd0FBQUFZYzNSMGN3QUFBQUFBQUFBQkFBQUFiZ0FQUWtBQUFBQVVjM1J6Y3dBQUFBQUFBQUFCQUFBQUFRQUFBNEJqZEhSekFBQUFBQUFBQUc0QUFBQUJBRDBKQUFBQUFBRUFlaElBQUFBQUFRQTlDUUFBQUFBQkFBQUFBQUFBQUFFQUQwSkFBQUFBQVFCTVMwQUFBQUFCQUI2RWdBQUFBQUVBQUFBQUFBQUFBUUFQUWtBQUFBQUJBRXhMUUFBQUFBRUFIb1NBQUFBQUFRQUFBQUFBQUFBQkFBOUNRQUFBQUFFQVRFdEFBQUFBQVFBZWhJQUFBQUFCQUFBQUFBQUFBQUVBRDBKQUFBQUFBUUJNUzBBQUFBQUJBQjZFZ0FBQUFBRUFBQUFBQUFBQUFRQVBRa0FBQUFBQkFFeExRQUFBQUFFQUhvU0FBQUFBQVFBQUFBQUFBQUFCQUE5Q1FBQUFBQUVBVEV0QUFBQUFBUUFlaElBQUFBQUJBQUFBQUFBQUFBRUFEMEpBQUFBQUFRQk1TMEFBQUFBQkFCNkVnQUFBQUFFQUFBQUFBQUFBQVFBUFFrQUFBQUFCQUV4TFFBQUFBQUVBSG9TQUFBQUFBUUFBQUFBQUFBQUJBQTlDUUFBQUFBRUFURXRBQUFBQUFRQWVoSUFBQUFBQkFBQUFBQUFBQUFFQUQwSkFBQUFBQVFCTVMwQUFBQUFCQUI2RWdBQUFBQUVBQUFBQUFBQUFBUUFQUWtBQUFBQUJBRXhMUUFBQUFBRUFIb1NBQUFBQUFRQUFBQUFBQUFBQkFBOUNRQUFBQUFFQVRFdEFBQUFBQVFBZWhJQUFBQUFCQUFBQUFBQUFBQUVBRDBKQUFBQUFBUUJNUzBBQUFBQUJBQjZFZ0FBQUFBRUFBQUFBQUFBQUFRQVBRa0FBQUFBQkFFeExRQUFBQUFFQUhvU0FBQUFBQVFBQUFBQUFBQUFCQUE5Q1FBQUFBQUVBVEV0QUFBQUFBUUFlaElBQUFBQUJBQUFBQUFBQUFBRUFEMEpBQUFBQUFRQk1TMEFBQUFBQkFCNkVnQUFBQUFFQUFBQUFBQUFBQVFBUFFrQUFBQUFCQUV4TFFBQUFBQUVBSG9TQUFBQUFBUUFBQUFBQUFBQUJBQTlDUUFBQUFBRUFURXRBQUFBQUFRQWVoSUFBQUFBQkFBQUFBQUFBQUFFQUQwSkFBQUFBQVFCTVMwQUFBQUFCQUI2RWdBQUFBQUVBQUFBQUFBQUFBUUFQUWtBQUFBQUJBRXhMUUFBQUFBRUFIb1NBQUFBQUFRQUFBQUFBQUFBQkFBOUNRQUFBQUFFQVRFdEFBQUFBQVFBZWhJQUFBQUFCQUFBQUFBQUFBQUVBRDBKQUFBQUFBUUJNUzBBQUFBQUJBQjZFZ0FBQUFBRUFBQUFBQUFBQUFRQVBRa0FBQUFBQkFFeExRQUFBQUFFQUhvU0FBQUFBQVFBQUFBQUFBQUFCQUE5Q1FBQUFBQUVBVEV0QUFBQUFBUUFlaElBQUFBQUJBQUFBQUFBQUFBRUFEMEpBQUFBQUFRQk1TMEFBQUFBQkFCNkVnQUFBQUFFQUFBQUFBQUFBQVFBUFFrQUFBQUFCQUV4TFFBQUFBQUVBSG9TQUFBQUFBUUFBQUFBQUFBQUJBQTlDUUFBQUFBRUFMY2JBQUFBQUhITjBjMk1BQUFBQUFBQUFBUUFBQUFFQUFBQnVBQUFBQVFBQUFjeHpkSE42QUFBQUFBQUFBQUFBQUFCdUFBQURDUUFBQUJnQUFBQU9BQUFBRGdBQUFBd0FBQUFTQUFBQURnQUFBQXdBQUFBTUFBQUFFZ0FBQUE0QUFBQU1BQUFBREFBQUFCSUFBQUFPQUFBQURBQUFBQXdBQUFBU0FBQUFEZ0FBQUF3QUFBQU1BQUFBRWdBQUFBNEFBQUFNQUFBQURBQUFBQklBQUFBT0FBQUFEQUFBQUF3QUFBQVNBQUFBRGdBQUFBd0FBQUFNQUFBQUVnQUFBQTRBQUFBTUFBQUFEQUFBQUJJQUFBQU9BQUFBREFBQUFBd0FBQUFTQUFBQURnQUFBQXdBQUFBTUFBQUFFZ0FBQUE0QUFBQU1BQUFBREFBQUFCSUFBQUFPQUFBQURBQUFBQXdBQUFBU0FBQUFEZ0FBQUF3QUFBQU1BQUFBRWdBQUFBNEFBQUFNQUFBQURBQUFBQklBQUFBT0FBQUFEQUFBQUF3QUFBQVNBQUFBRGdBQUFBd0FBQUFNQUFBQUVnQUFBQTRBQUFBTUFBQUFEQUFBQUJJQUFBQU9BQUFBREFBQUFBd0FBQUFTQUFBQURnQUFBQXdBQUFBTUFBQUFFZ0FBQUE0QUFBQU1BQUFBREFBQUFCSUFBQUFPQUFBQURBQUFBQXdBQUFBU0FBQUFEZ0FBQUF3QUFBQU1BQUFBRWdBQUFBNEFBQUFNQUFBQURBQUFBQklBQUFBT0FBQUFEQUFBQUF3QUFBQVNBQUFBRGdBQUFBd0FBQUFNQUFBQUVnQUFBQTRBQUFBTUFBQUFEQUFBQUJNQUFBQVVjM1JqYndBQUFBQUFBQUFCQUFBSUt3QUFBQ3QxWkhSaEFBQUFJNmxsYm1NQUZ3QUFkbXhqSURJdU1pNHhJSE4wY21WaGJTQnZkWFJ3ZFhRQUFBQUlkMmxrWlFBQUNSUnRaR0YwQUFBQ3JnWC8vNnZjUmVtOTV0bEl0NVlzMkNEWkkrN3ZlREkyTkNBdElHTnZjbVVnTVRReUlDMGdTQzR5TmpRdlRWQkZSeTAwSUVGV1F5QmpiMlJsWXlBdElFTnZjSGxzWldaMElESXdNRE10TWpBeE5DQXRJR2gwZEhBNkx5OTNkM2N1ZG1sa1pXOXNZVzR1YjNKbkwzZ3lOalF1YUhSdGJDQXRJRzl3ZEdsdmJuTTZJR05oWW1GalBURWdjbVZtUFRNZ1pHVmliRzlqYXoweE9qQTZNQ0JoYm1Gc2VYTmxQVEI0TXpvd2VERXpJRzFsUFdobGVDQnpkV0p0WlQwM0lIQnplVDB4SUhCemVWOXlaRDB4TGpBd09qQXVNREFnYldsNFpXUmZjbVZtUFRFZ2JXVmZjbUZ1WjJVOU1UWWdZMmh5YjIxaFgyMWxQVEVnZEhKbGJHeHBjejB4SURoNE9HUmpkRDB4SUdOeGJUMHdJR1JsWVdSNmIyNWxQVEl4TERFeElHWmhjM1JmY0hOcmFYQTlNU0JqYUhKdmJXRmZjWEJmYjJabWMyVjBQUzB5SUhSb2NtVmhaSE05TVRJZ2JHOXZhMkZvWldGa1gzUm9jbVZoWkhNOU1TQnpiR2xqWldSZmRHaHlaV0ZrY3owd0lHNXlQVEFnWkdWamFXMWhkR1U5TVNCcGJuUmxjbXhoWTJWa1BUQWdZbXgxY21GNVgyTnZiWEJoZEQwd0lHTnZibk4wY21GcGJtVmtYMmx1ZEhKaFBUQWdZbVp5WVcxbGN6MHpJR0pmY0hseVlXMXBaRDB5SUdKZllXUmhjSFE5TVNCaVgySnBZWE05TUNCa2FYSmxZM1E5TVNCM1pXbG5hSFJpUFRFZ2IzQmxibDluYjNBOU1DQjNaV2xuYUhSd1BUSWdhMlY1YVc1MFBUSTFNQ0JyWlhscGJuUmZiV2x1UFRFZ2MyTmxibVZqZFhROU5EQWdhVzUwY21GZmNtVm1jbVZ6YUQwd0lISmpYMnh2YjJ0aGFHVmhaRDAwTUNCeVl6MWhZbklnYldKMGNtVmxQVEVnWW1sMGNtRjBaVDB4TURBZ2NtRjBaWFJ2YkQweExqQWdjV052YlhBOU1DNDJNQ0J4Y0cxcGJqMHhNQ0J4Y0cxaGVEMDFNU0J4Y0hOMFpYQTlOQ0JwY0Y5eVlYUnBiejB4TGpRd0lHRnhQVEU2TVM0d01BQ0FBQUFBVTJXSWhBQVEvOGx0bE9lK2NUWnVHa0tnK2FSdHVpdmNEWjBwQnNmc0VpOXAvaTF5VTlEeFMybHE0ZFhUaW5WaUYxVVJCS1hnbnpLQmQvVWgxYmtoSHRNcndyUmNPSnNsRDAxVUIrZnlhTDZlZitEQkFBQUFGRUdhSkd4QkQ1Qit2K2ErNFFxRjNNZ0JYejlNQUFBQUNrR2VRbmlILys5NHI2RUFBQUFLQVo1aGRFTi84UXl0d0FBQUFBZ0JubU5xUTMvRWdRQUFBQTVCbW1oSnFFRm9tVXdJSWYvKzRRQUFBQXBCbm9aRkVTdy8vNzZCQUFBQUNBR2VwWFJEZjhTQkFBQUFDQUdlcDJwRGY4U0FBQUFBRGtHYXJFbW9RV3laVEFnaC8vN2dBQUFBQ2tHZXlrVVZMRC8vdm9FQUFBQUlBWjdwZEVOL3hJQUFBQUFJQVo3cmFrTi94SUFBQUFBT1FacndTYWhCYkpsTUNDSC8vdUVBQUFBS1FaOE9SUlVzUC8rK2dRQUFBQWdCbnkxMFEzL0VnUUFBQUFnQm55OXFRMy9FZ0FBQUFBNUJtelJKcUVGc21Vd0lJZi8rNEFBQUFBcEJuMUpGRlN3Ly83NkJBQUFBQ0FHZmNYUkRmOFNBQUFBQUNBR2ZjMnBEZjhTQUFBQUFEa0diZUVtb1FXeVpUQWdoLy83aEFBQUFDa0dmbGtVVkxELy92b0FBQUFBSUFaKzFkRU4veElFQUFBQUlBWiszYWtOL3hJRUFBQUFPUVp1OFNhaEJiSmxNQ0NILy91QUFBQUFLUVovYVJSVXNQLysrZ1FBQUFBZ0JuL2wwUTMvRWdBQUFBQWdCbi90cVEzL0VnUUFBQUE1Qm0rQkpxRUZzbVV3SUlmLys0UUFBQUFwQm5oNUZGU3cvLzc2QUFBQUFDQUdlUFhSRGY4U0FBQUFBQ0FHZVAycERmOFNCQUFBQURrR2FKRW1vUVd5WlRBZ2gvLzdnQUFBQUNrR2VRa1VWTEQvL3ZvRUFBQUFJQVo1aGRFTi94SUFBQUFBSUFaNWpha04veElFQUFBQU9RWnBvU2FoQmJKbE1DQ0gvL3VFQUFBQUtRWjZHUlJVc1AvKytnUUFBQUFnQm5xVjBRMy9FZ1FBQUFBZ0JucWRxUTMvRWdBQUFBQTVCbXF4SnFFRnNtVXdJSWYvKzRBQUFBQXBCbnNwRkZTdy8vNzZCQUFBQUNBR2U2WFJEZjhTQUFBQUFDQUdlNjJwRGY4U0FBQUFBRGtHYThFbW9RV3laVEFnaC8vN2hBQUFBQ2tHZkRrVVZMRC8vdm9FQUFBQUlBWjh0ZEVOL3hJRUFBQUFJQVo4dmFrTi94SUFBQUFBT1FaczBTYWhCYkpsTUNDSC8vdUFBQUFBS1FaOVNSUlVzUC8rK2dRQUFBQWdCbjNGMFEzL0VnQUFBQUFnQm4zTnFRMy9FZ0FBQUFBNUJtM2hKcUVGc21Vd0lJZi8rNFFBQUFBcEJuNVpGRlN3Ly83NkFBQUFBQ0FHZnRYUkRmOFNCQUFBQUNBR2Z0MnBEZjhTQkFBQUFEa0didkVtb1FXeVpUQWdoLy83Z0FBQUFDa0dmMmtVVkxELy92b0VBQUFBSUFaLzVkRU4veElBQUFBQUlBWi83YWtOL3hJRUFBQUFPUVp2Z1NhaEJiSmxNQ0NILy91RUFBQUFLUVo0ZVJSVXNQLysrZ0FBQUFBZ0JuajEwUTMvRWdBQUFBQWdCbmo5cVEzL0VnUUFBQUE1Qm1pUkpxRUZzbVV3SUlmLys0QUFBQUFwQm5rSkZGU3cvLzc2QkFBQUFDQUdlWVhSRGY4U0FBQUFBQ0FHZVkycERmOFNCQUFBQURrR2FhRW1vUVd5WlRBZ2gvLzdoQUFBQUNrR2Voa1VWTEQvL3ZvRUFBQUFJQVo2bGRFTi94SUVBQUFBSUFaNm5ha04veElBQUFBQU9RWnFzU2FoQmJKbE1DQ0gvL3VBQUFBQUtRWjdLUlJVc1AvKytnUUFBQUFnQm51bDBRMy9FZ0FBQUFBZ0JudXRxUTMvRWdBQUFBQTVCbXZCSnFFRnNtVXdJSWYvKzRRQUFBQXBCbnc1RkZTdy8vNzZCQUFBQUNBR2ZMWFJEZjhTQkFBQUFDQUdmTDJwRGY4U0FBQUFBRGtHYk5FbW9RV3laVEFnaC8vN2dBQUFBQ2tHZlVrVVZMRC8vdm9FQUFBQUlBWjl4ZEVOL3hJQUFBQUFJQVo5emFrTi94SUFBQUFBT1FadDRTYWhCYkpsTUNDSC8vdUVBQUFBS1FaK1dSUlVzUC8rK2dBQUFBQWdCbjdWMFEzL0VnUUFBQUFnQm43ZHFRMy9FZ1FBQUFBNUJtN3hKcUVGc21Vd0lJZi8rNEFBQUFBcEJuOXBGRlN3Ly83NkJBQUFBQ0FHZitYUkRmOFNBQUFBQUNBR2YrMnBEZjhTQkFBQUFEa0diNEVtb1FXeVpUQWdoLy83aEFBQUFDa0dlSGtVVkxELy92b0FBQUFBSUFaNDlkRU4veElBQUFBQUlBWjQvYWtOL3hJRUFBQUFPUVpva1NhaEJiSmxNQ0NILy91QUFBQUFLUVo1Q1JSVXNQLysrZ1FBQUFBZ0JubUYwUTMvRWdBQUFBQWdCbm1OcVEzL0VnUUFBQUE1Qm1taEpxRUZzbVV3SUlmLys0UUFBQUFwQm5vWkZGU3cvLzc2QkFBQUFDQUdlcFhSRGY4U0JBQUFBQ0FHZXAycERmOFNBQUFBQURrR2FyRW1vUVd5WlRBZ2gvLzdnQUFBQUNrR2V5a1VWTEQvL3ZvRUFBQUFJQVo3cGRFTi94SUFBQUFBSUFaN3Jha04veElBQUFBQVBRWnJ1U2FoQmJKbE1GRXczLy83QicpO1xuICAgICAgdmlkZW8ucGxheSgpO1xuICAgIH1cbiAgfTtcblxuICB0aGlzLnJlbGVhc2UgPSBmdW5jdGlvbigpIHtcbiAgICB2aWRlby5wYXVzZSgpO1xuICAgIHZpZGVvLnNyYyA9ICcnO1xuICB9O1xufVxuXG5mdW5jdGlvbiBpT1NXYWtlTG9jaygpIHtcbiAgdmFyIHRpbWVyID0gbnVsbDtcblxuICB0aGlzLnJlcXVlc3QgPSBmdW5jdGlvbigpIHtcbiAgICBpZiAoIXRpbWVyKSB7XG4gICAgICB0aW1lciA9IHNldEludGVydmFsKGZ1bmN0aW9uKCkge1xuICAgICAgICB3aW5kb3cubG9jYXRpb24gPSB3aW5kb3cubG9jYXRpb247XG4gICAgICAgIHNldFRpbWVvdXQod2luZG93LnN0b3AsIDApO1xuICAgICAgfSwgMzAwMDApO1xuICAgIH1cbiAgfVxuXG4gIHRoaXMucmVsZWFzZSA9IGZ1bmN0aW9uKCkge1xuICAgIGlmICh0aW1lcikge1xuICAgICAgY2xlYXJJbnRlcnZhbCh0aW1lcik7XG4gICAgICB0aW1lciA9IG51bGw7XG4gICAgfVxuICB9XG59XG5cblxuZnVuY3Rpb24gZ2V0V2FrZUxvY2soKSB7XG4gIHZhciB1c2VyQWdlbnQgPSBuYXZpZ2F0b3IudXNlckFnZW50IHx8IG5hdmlnYXRvci52ZW5kb3IgfHwgd2luZG93Lm9wZXJhO1xuICBpZiAodXNlckFnZW50Lm1hdGNoKC9pUGhvbmUvaSkgfHwgdXNlckFnZW50Lm1hdGNoKC9pUG9kL2kpKSB7XG4gICAgcmV0dXJuIGlPU1dha2VMb2NrO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBBbmRyb2lkV2FrZUxvY2s7XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBnZXRXYWtlTG9jaygpO1xufSx7XCIuL3V0aWwuanNcIjoyMn1dLDI1OltmdW5jdGlvbihfZGVyZXFfLG1vZHVsZSxleHBvcnRzKXtcbi8qXG4gKiBDb3B5cmlnaHQgMjAxNSBHb29nbGUgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbnZhciBVdGlsID0gX2RlcmVxXygnLi91dGlsLmpzJyk7XG52YXIgQ2FyZGJvYXJkVlJEaXNwbGF5ID0gX2RlcmVxXygnLi9jYXJkYm9hcmQtdnItZGlzcGxheS5qcycpO1xudmFyIE1vdXNlS2V5Ym9hcmRWUkRpc3BsYXkgPSBfZGVyZXFfKCcuL21vdXNlLWtleWJvYXJkLXZyLWRpc3BsYXkuanMnKTtcbi8vIFVuY29tbWVudCB0byBhZGQgcG9zaXRpb25hbCB0cmFja2luZyB2aWEgd2ViY2FtLlxuLy92YXIgV2ViY2FtUG9zaXRpb25TZW5zb3JWUkRldmljZSA9IHJlcXVpcmUoJy4vd2ViY2FtLXBvc2l0aW9uLXNlbnNvci12ci1kZXZpY2UuanMnKTtcbnZhciBWUkRpc3BsYXkgPSBfZGVyZXFfKCcuL2Jhc2UuanMnKS5WUkRpc3BsYXk7XG52YXIgVlJGcmFtZURhdGEgPSBfZGVyZXFfKCcuL2Jhc2UuanMnKS5WUkZyYW1lRGF0YTtcbnZhciBITURWUkRldmljZSA9IF9kZXJlcV8oJy4vYmFzZS5qcycpLkhNRFZSRGV2aWNlO1xudmFyIFBvc2l0aW9uU2Vuc29yVlJEZXZpY2UgPSBfZGVyZXFfKCcuL2Jhc2UuanMnKS5Qb3NpdGlvblNlbnNvclZSRGV2aWNlO1xudmFyIFZSRGlzcGxheUhNRERldmljZSA9IF9kZXJlcV8oJy4vZGlzcGxheS13cmFwcGVycy5qcycpLlZSRGlzcGxheUhNRERldmljZTtcbnZhciBWUkRpc3BsYXlQb3NpdGlvblNlbnNvckRldmljZSA9IF9kZXJlcV8oJy4vZGlzcGxheS13cmFwcGVycy5qcycpLlZSRGlzcGxheVBvc2l0aW9uU2Vuc29yRGV2aWNlO1xuXG5mdW5jdGlvbiBXZWJWUlBvbHlmaWxsKCkge1xuICB0aGlzLmRpc3BsYXlzID0gW107XG4gIHRoaXMuZGV2aWNlcyA9IFtdOyAvLyBGb3IgZGVwcmVjYXRlZCBvYmplY3RzXG4gIHRoaXMuZGV2aWNlc1BvcHVsYXRlZCA9IGZhbHNlO1xuICB0aGlzLm5hdGl2ZVdlYlZSQXZhaWxhYmxlID0gdGhpcy5pc1dlYlZSQXZhaWxhYmxlKCk7XG4gIHRoaXMubmF0aXZlTGVnYWN5V2ViVlJBdmFpbGFibGUgPSB0aGlzLmlzRGVwcmVjYXRlZFdlYlZSQXZhaWxhYmxlKCk7XG4gIHRoaXMubmF0aXZlR2V0VlJEaXNwbGF5c0Z1bmMgPSB0aGlzLm5hdGl2ZVdlYlZSQXZhaWxhYmxlID9cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hdmlnYXRvci5nZXRWUkRpc3BsYXlzIDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG51bGw7XG5cbiAgaWYgKCF0aGlzLm5hdGl2ZUxlZ2FjeVdlYlZSQXZhaWxhYmxlKSB7XG4gICAgdGhpcy5lbmFibGVQb2x5ZmlsbCgpO1xuICAgIGlmIChXZWJWUkNvbmZpZy5FTkFCTEVfREVQUkVDQVRFRF9BUEkpIHtcbiAgICAgIHRoaXMuZW5hYmxlRGVwcmVjYXRlZFBvbHlmaWxsKCk7XG4gICAgfVxuICB9XG5cbiAgLy8gUHV0IGEgc2hpbSBpbiBwbGFjZSB0byB1cGRhdGUgdGhlIEFQSSB0byAxLjEgaWYgbmVlZGVkLlxuICBJbnN0YWxsV2ViVlJTcGVjU2hpbSgpO1xufVxuXG5XZWJWUlBvbHlmaWxsLnByb3RvdHlwZS5pc1dlYlZSQXZhaWxhYmxlID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiAoJ2dldFZSRGlzcGxheXMnIGluIG5hdmlnYXRvcik7XG59O1xuXG5XZWJWUlBvbHlmaWxsLnByb3RvdHlwZS5pc0RlcHJlY2F0ZWRXZWJWUkF2YWlsYWJsZSA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gKCdnZXRWUkRldmljZXMnIGluIG5hdmlnYXRvcikgfHwgKCdtb3pHZXRWUkRldmljZXMnIGluIG5hdmlnYXRvcik7XG59O1xuXG5XZWJWUlBvbHlmaWxsLnByb3RvdHlwZS5wb3B1bGF0ZURldmljZXMgPSBmdW5jdGlvbigpIHtcbiAgaWYgKHRoaXMuZGV2aWNlc1BvcHVsYXRlZCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIEluaXRpYWxpemUgb3VyIHZpcnR1YWwgVlIgZGV2aWNlcy5cbiAgdmFyIHZyRGlzcGxheSA9IG51bGw7XG5cbiAgLy8gQWRkIGEgQ2FyZGJvYXJkIFZSRGlzcGxheSBvbiBjb21wYXRpYmxlIG1vYmlsZSBkZXZpY2VzXG4gIGlmICh0aGlzLmlzQ2FyZGJvYXJkQ29tcGF0aWJsZSgpKSB7XG4gICAgdnJEaXNwbGF5ID0gbmV3IENhcmRib2FyZFZSRGlzcGxheSgpO1xuICAgIHRoaXMuZGlzcGxheXMucHVzaCh2ckRpc3BsYXkpO1xuXG4gICAgLy8gRm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5XG4gICAgaWYgKFdlYlZSQ29uZmlnLkVOQUJMRV9ERVBSRUNBVEVEX0FQSSkge1xuICAgICAgdGhpcy5kZXZpY2VzLnB1c2gobmV3IFZSRGlzcGxheUhNRERldmljZSh2ckRpc3BsYXkpKTtcbiAgICAgIHRoaXMuZGV2aWNlcy5wdXNoKG5ldyBWUkRpc3BsYXlQb3NpdGlvblNlbnNvckRldmljZSh2ckRpc3BsYXkpKTtcbiAgICB9XG4gIH1cblxuICAvLyBBZGQgYSBNb3VzZSBhbmQgS2V5Ym9hcmQgZHJpdmVuIFZSRGlzcGxheSBmb3IgZGVza3RvcHMvbGFwdG9wc1xuICBpZiAoIXRoaXMuaXNNb2JpbGUoKSAmJiAhV2ViVlJDb25maWcuTU9VU0VfS0VZQk9BUkRfQ09OVFJPTFNfRElTQUJMRUQpIHtcbiAgICB2ckRpc3BsYXkgPSBuZXcgTW91c2VLZXlib2FyZFZSRGlzcGxheSgpO1xuICAgIHRoaXMuZGlzcGxheXMucHVzaCh2ckRpc3BsYXkpO1xuXG4gICAgLy8gRm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5XG4gICAgaWYgKFdlYlZSQ29uZmlnLkVOQUJMRV9ERVBSRUNBVEVEX0FQSSkge1xuICAgICAgdGhpcy5kZXZpY2VzLnB1c2gobmV3IFZSRGlzcGxheUhNRERldmljZSh2ckRpc3BsYXkpKTtcbiAgICAgIHRoaXMuZGV2aWNlcy5wdXNoKG5ldyBWUkRpc3BsYXlQb3NpdGlvblNlbnNvckRldmljZSh2ckRpc3BsYXkpKTtcbiAgICB9XG4gIH1cblxuICAvLyBVbmNvbW1lbnQgdG8gYWRkIHBvc2l0aW9uYWwgdHJhY2tpbmcgdmlhIHdlYmNhbS5cbiAgLy9pZiAoIXRoaXMuaXNNb2JpbGUoKSAmJiBXZWJWUkNvbmZpZy5FTkFCTEVfREVQUkVDQVRFRF9BUEkpIHtcbiAgLy8gIHBvc2l0aW9uRGV2aWNlID0gbmV3IFdlYmNhbVBvc2l0aW9uU2Vuc29yVlJEZXZpY2UoKTtcbiAgLy8gIHRoaXMuZGV2aWNlcy5wdXNoKHBvc2l0aW9uRGV2aWNlKTtcbiAgLy99XG5cbiAgdGhpcy5kZXZpY2VzUG9wdWxhdGVkID0gdHJ1ZTtcbn07XG5cbldlYlZSUG9seWZpbGwucHJvdG90eXBlLmVuYWJsZVBvbHlmaWxsID0gZnVuY3Rpb24oKSB7XG4gIC8vIFByb3ZpZGUgbmF2aWdhdG9yLmdldFZSRGlzcGxheXMuXG4gIG5hdmlnYXRvci5nZXRWUkRpc3BsYXlzID0gdGhpcy5nZXRWUkRpc3BsYXlzLmJpbmQodGhpcyk7XG5cbiAgLy8gUHJvdmlkZSB0aGUgVlJEaXNwbGF5IG9iamVjdC5cbiAgd2luZG93LlZSRGlzcGxheSA9IFZSRGlzcGxheTtcblxuICAvLyBQcm92aWRlIG5hdmlnYXRvci52ckVuYWJsZWQuXG4gIHZhciBzZWxmID0gdGhpcztcbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG5hdmlnYXRvciwgJ3ZyRW5hYmxlZCcsIHtcbiAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgIHJldHVybiBzZWxmLmlzQ2FyZGJvYXJkQ29tcGF0aWJsZSgpICYmXG4gICAgICAgICAgKHNlbGYuaXNGdWxsU2NyZWVuQXZhaWxhYmxlKCkgfHwgVXRpbC5pc0lPUygpKTtcbiAgICB9XG4gIH0pO1xuXG4gIGlmICghJ1ZSRnJhbWVEYXRhJyBpbiB3aW5kb3cpIHtcbiAgICAvLyBQcm92aWRlIHRoZSBWUkZyYW1lRGF0YSBvYmplY3QuXG4gICAgd2luZG93LlZSRnJhbWVEYXRhID0gVlJGcmFtZURhdGE7XG4gIH1cbn07XG5cbldlYlZSUG9seWZpbGwucHJvdG90eXBlLmVuYWJsZURlcHJlY2F0ZWRQb2x5ZmlsbCA9IGZ1bmN0aW9uKCkge1xuICAvLyBQcm92aWRlIG5hdmlnYXRvci5nZXRWUkRldmljZXMuXG4gIG5hdmlnYXRvci5nZXRWUkRldmljZXMgPSB0aGlzLmdldFZSRGV2aWNlcy5iaW5kKHRoaXMpO1xuXG4gIC8vIFByb3ZpZGUgdGhlIENhcmRib2FyZEhNRFZSRGV2aWNlIGFuZCBQb3NpdGlvblNlbnNvclZSRGV2aWNlIG9iamVjdHMuXG4gIHdpbmRvdy5ITURWUkRldmljZSA9IEhNRFZSRGV2aWNlO1xuICB3aW5kb3cuUG9zaXRpb25TZW5zb3JWUkRldmljZSA9IFBvc2l0aW9uU2Vuc29yVlJEZXZpY2U7XG59O1xuXG5XZWJWUlBvbHlmaWxsLnByb3RvdHlwZS5nZXRWUkRpc3BsYXlzID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMucG9wdWxhdGVEZXZpY2VzKCk7XG4gIHZhciBwb2x5ZmlsbERpc3BsYXlzID0gdGhpcy5kaXNwbGF5cztcblxuICBpZiAodGhpcy5uYXRpdmVXZWJWUkF2YWlsYWJsZSkge1xuICAgIHJldHVybiB0aGlzLm5hdGl2ZUdldFZSRGlzcGxheXNGdW5jLmNhbGwobmF2aWdhdG9yKS50aGVuKGZ1bmN0aW9uKG5hdGl2ZURpc3BsYXlzKSB7XG4gICAgICBpZiAoV2ViVlJDb25maWcuQUxXQVlTX0FQUEVORF9QT0xZRklMTF9ESVNQTEFZKSB7XG4gICAgICAgIHJldHVybiBuYXRpdmVEaXNwbGF5cy5jb25jYXQocG9seWZpbGxEaXNwbGF5cyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gbmF0aXZlRGlzcGxheXMubGVuZ3RoID4gMCA/IG5hdGl2ZURpc3BsYXlzIDogcG9seWZpbGxEaXNwbGF5cztcbiAgICAgIH1cbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgICB0cnkge1xuICAgICAgICByZXNvbHZlKHBvbHlmaWxsRGlzcGxheXMpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICByZWplY3QoZSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn07XG5cbldlYlZSUG9seWZpbGwucHJvdG90eXBlLmdldFZSRGV2aWNlcyA9IGZ1bmN0aW9uKCkge1xuICBjb25zb2xlLndhcm4oJ2dldFZSRGV2aWNlcyBpcyBkZXByZWNhdGVkLiBQbGVhc2UgdXBkYXRlIHlvdXIgY29kZSB0byB1c2UgZ2V0VlJEaXNwbGF5cyBpbnN0ZWFkLicpO1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICB0cnkge1xuICAgICAgaWYgKCFzZWxmLmRldmljZXNQb3B1bGF0ZWQpIHtcbiAgICAgICAgaWYgKHNlbGYubmF0aXZlV2ViVlJBdmFpbGFibGUpIHtcbiAgICAgICAgICByZXR1cm4gbmF2aWdhdG9yLmdldFZSRGlzcGxheXMoZnVuY3Rpb24oZGlzcGxheXMpIHtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZGlzcGxheXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgICAgc2VsZi5kZXZpY2VzLnB1c2gobmV3IFZSRGlzcGxheUhNRERldmljZShkaXNwbGF5c1tpXSkpO1xuICAgICAgICAgICAgICBzZWxmLmRldmljZXMucHVzaChuZXcgVlJEaXNwbGF5UG9zaXRpb25TZW5zb3JEZXZpY2UoZGlzcGxheXNbaV0pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHNlbGYuZGV2aWNlc1BvcHVsYXRlZCA9IHRydWU7XG4gICAgICAgICAgICByZXNvbHZlKHNlbGYuZGV2aWNlcyk7XG4gICAgICAgICAgfSwgcmVqZWN0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzZWxmLm5hdGl2ZUxlZ2FjeVdlYlZSQXZhaWxhYmxlKSB7XG4gICAgICAgICAgcmV0dXJuIChuYXZpZ2F0b3IuZ2V0VlJERGV2aWNlcyB8fCBuYXZpZ2F0b3IubW96R2V0VlJEZXZpY2VzKShmdW5jdGlvbihkZXZpY2VzKSB7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGRldmljZXMubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgICAgaWYgKGRldmljZXNbaV0gaW5zdGFuY2VvZiBITURWUkRldmljZSkge1xuICAgICAgICAgICAgICAgIHNlbGYuZGV2aWNlcy5wdXNoKGRldmljZXNbaV0pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGlmIChkZXZpY2VzW2ldIGluc3RhbmNlb2YgUG9zaXRpb25TZW5zb3JWUkRldmljZSkge1xuICAgICAgICAgICAgICAgIHNlbGYuZGV2aWNlcy5wdXNoKGRldmljZXNbaV0pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzZWxmLmRldmljZXNQb3B1bGF0ZWQgPSB0cnVlO1xuICAgICAgICAgICAgcmVzb2x2ZShzZWxmLmRldmljZXMpO1xuICAgICAgICAgIH0sIHJlamVjdCk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgc2VsZi5wb3B1bGF0ZURldmljZXMoKTtcbiAgICAgIHJlc29sdmUoc2VsZi5kZXZpY2VzKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZWplY3QoZSk7XG4gICAgfVxuICB9KTtcbn07XG5cbi8qKlxuICogRGV0ZXJtaW5lIGlmIGEgZGV2aWNlIGlzIG1vYmlsZS5cbiAqL1xuV2ViVlJQb2x5ZmlsbC5wcm90b3R5cGUuaXNNb2JpbGUgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIC9BbmRyb2lkL2kudGVzdChuYXZpZ2F0b3IudXNlckFnZW50KSB8fFxuICAgICAgL2lQaG9uZXxpUGFkfGlQb2QvaS50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpO1xufTtcblxuV2ViVlJQb2x5ZmlsbC5wcm90b3R5cGUuaXNDYXJkYm9hcmRDb21wYXRpYmxlID0gZnVuY3Rpb24oKSB7XG4gIC8vIEZvciBub3csIHN1cHBvcnQgYWxsIGlPUyBhbmQgQW5kcm9pZCBkZXZpY2VzLlxuICAvLyBBbHNvIGVuYWJsZSB0aGUgV2ViVlJDb25maWcuRk9SQ0VfVlIgZmxhZyBmb3IgZGVidWdnaW5nLlxuICByZXR1cm4gdGhpcy5pc01vYmlsZSgpIHx8IFdlYlZSQ29uZmlnLkZPUkNFX0VOQUJMRV9WUjtcbn07XG5cbldlYlZSUG9seWZpbGwucHJvdG90eXBlLmlzRnVsbFNjcmVlbkF2YWlsYWJsZSA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gKGRvY3VtZW50LmZ1bGxzY3JlZW5FbmFibGVkIHx8XG4gICAgICAgICAgZG9jdW1lbnQubW96RnVsbFNjcmVlbkVuYWJsZWQgfHxcbiAgICAgICAgICBkb2N1bWVudC53ZWJraXRGdWxsc2NyZWVuRW5hYmxlZCB8fFxuICAgICAgICAgIGZhbHNlKTtcbn07XG5cbi8vIEluc3RhbGxzIGEgc2hpbSB0aGF0IHVwZGF0ZXMgYSBXZWJWUiAxLjAgc3BlYyBpbXBsZW1lbnRhdGlvbiB0byBXZWJWUiAxLjFcbmZ1bmN0aW9uIEluc3RhbGxXZWJWUlNwZWNTaGltKCkge1xuICBpZiAoJ1ZSRGlzcGxheScgaW4gd2luZG93ICYmICEoJ1ZSRnJhbWVEYXRhJyBpbiB3aW5kb3cpKSB7XG4gICAgLy8gUHJvdmlkZSB0aGUgVlJGcmFtZURhdGEgb2JqZWN0LlxuICAgIHdpbmRvdy5WUkZyYW1lRGF0YSA9IFZSRnJhbWVEYXRhO1xuXG4gICAgLy8gQSBsb3Qgb2YgQ2hyb21lIGJ1aWxkcyBkb24ndCBoYXZlIGRlcHRoTmVhciBhbmQgZGVwdGhGYXIsIGV2ZW5cbiAgICAvLyB0aG91Z2ggdGhleSdyZSBpbiB0aGUgV2ViVlIgMS4wIHNwZWMuIFBhdGNoIHRoZW0gaW4gaWYgdGhleSdyZSBub3QgcHJlc2VudC5cbiAgICBpZighKCdkZXB0aE5lYXInIGluIHdpbmRvdy5WUkRpc3BsYXkucHJvdG90eXBlKSkge1xuICAgICAgd2luZG93LlZSRGlzcGxheS5wcm90b3R5cGUuZGVwdGhOZWFyID0gMC4wMTtcbiAgICB9XG5cbiAgICBpZighKCdkZXB0aEZhcicgaW4gd2luZG93LlZSRGlzcGxheS5wcm90b3R5cGUpKSB7XG4gICAgICB3aW5kb3cuVlJEaXNwbGF5LnByb3RvdHlwZS5kZXB0aEZhciA9IDEwMDAwLjA7XG4gICAgfVxuXG4gICAgd2luZG93LlZSRGlzcGxheS5wcm90b3R5cGUuZ2V0RnJhbWVEYXRhID0gZnVuY3Rpb24oZnJhbWVEYXRhKSB7XG4gICAgICByZXR1cm4gVXRpbC5mcmFtZURhdGFGcm9tUG9zZShmcmFtZURhdGEsIHRoaXMuZ2V0UG9zZSgpLCB0aGlzKTtcbiAgICB9XG4gIH1cbn07XG5cbm1vZHVsZS5leHBvcnRzLldlYlZSUG9seWZpbGwgPSBXZWJWUlBvbHlmaWxsO1xuXG59LHtcIi4vYmFzZS5qc1wiOjMsXCIuL2NhcmRib2FyZC12ci1kaXNwbGF5LmpzXCI6NixcIi4vZGlzcGxheS13cmFwcGVycy5qc1wiOjksXCIuL21vdXNlLWtleWJvYXJkLXZyLWRpc3BsYXkuanNcIjoxNSxcIi4vdXRpbC5qc1wiOjIyfV19LHt9LFsxM10pKDEzKVxufSk7IiwiLypcbiAqIENvcHlyaWdodCAyMDE2IEdvb2dsZSBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxudmFyIEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJ2V2ZW50ZW1pdHRlcjMnKTtcbnZhciBzaGFrYSA9IHJlcXVpcmUoJ3NoYWthLXBsYXllcicpO1xuXG52YXIgVHlwZXMgPSB7XG4gIEhMUzogMSxcbiAgREFTSDogMixcbiAgVklERU86IDNcbn07XG5cbnZhciBERUZBVUxUX0JJVFNfUEVSX1NFQ09ORCA9IDEwMDAwMDA7XG5cbi8qKlxuICogU3VwcG9ydHMgcmVndWxhciB2aWRlbyBVUkxzIChlZy4gbXA0KSwgYXMgd2VsbCBhcyBhZGFwdGl2ZSBtYW5pZmVzdHMgbGlrZVxuICogREFTSCAoLm1wZCkgYW5kIHNvb24gSExTICgubTN1OCkuXG4gKlxuICogRXZlbnRzOlxuICogICBsb2FkKHZpZGVvKTogV2hlbiB0aGUgdmlkZW8gaXMgbG9hZGVkLlxuICogICBlcnJvcihtZXNzYWdlKTogSWYgYW4gZXJyb3Igb2NjdXJzLlxuICpcbiAqIFRvIHBsYXkvcGF1c2Uvc2Vlay9ldGMsIHBsZWFzZSB1c2UgdGhlIHVuZGVybHlpbmcgdmlkZW8gZWxlbWVudC5cbiAqL1xuZnVuY3Rpb24gQWRhcHRpdmVQbGF5ZXIoKSB7XG4gIHRoaXMudmlkZW8gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd2aWRlbycpO1xuICAvLyBMb29wIGJ5IGRlZmF1bHQuXG4gIHRoaXMudmlkZW8uc2V0QXR0cmlidXRlKCdsb29wJywgdHJ1ZSk7XG4gIC8vIEZvciBGRiwgbWFrZSBzdXJlIHdlIGVuYWJsZSBwcmVsb2FkLlxuICB0aGlzLnZpZGVvLnNldEF0dHJpYnV0ZSgncHJlbG9hZCcsICdhdXRvJyk7XG4gIC8vIEVuYWJsZSBpbmxpbmUgdmlkZW8gcGxheWJhY2sgaW4gaU9TIDEwKy5cbiAgdGhpcy52aWRlby5zZXRBdHRyaWJ1dGUoJ3BsYXlzaW5saW5lJywgdHJ1ZSk7XG4gIHRoaXMudmlkZW8uc2V0QXR0cmlidXRlKCdjcm9zc29yaWdpbicsICdhbm9ueW1vdXMnKTtcbn1cbkFkYXB0aXZlUGxheWVyLnByb3RvdHlwZSA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuQWRhcHRpdmVQbGF5ZXIucHJvdG90eXBlLmxvYWQgPSBmdW5jdGlvbih1cmwpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICAvLyBUT0RPKHNtdXMpOiBJbnZlc3RpZ2F0ZSB3aGV0aGVyIG9yIG5vdCBkaWZmZXJlbnRpYXRpb24gaXMgYmVzdCBkb25lIGJ5XG4gIC8vIG1pbWVUeXBlIGFmdGVyIGFsbC4gQ3Vyc29yeSByZXNlYXJjaCBzdWdnZXN0cyB0aGF0IGFkYXB0aXZlIHN0cmVhbWluZ1xuICAvLyBtYW5pZmVzdCBtaW1lIHR5cGVzIGFyZW4ndCBwcm9wZXJseSBzdXBwb3J0ZWQuXG4gIC8vXG4gIC8vIEZvciBub3csIG1ha2UgZGV0ZXJtaW5hdGlvbiBiYXNlZCBvbiBleHRlbnNpb24uXG4gIHZhciBleHRlbnNpb24gPSBVdGlsLmdldEV4dGVuc2lvbih1cmwpO1xuICBzd2l0Y2ggKGV4dGVuc2lvbikge1xuICAgIGNhc2UgJ20zdTgnOiAvLyBITFNcbiAgICAgIHRoaXMudHlwZSA9IFR5cGVzLkhMUztcbiAgICAgIGlmIChVdGlsLmlzU2FmYXJpKCkpIHtcbiAgICAgICAgdGhpcy5sb2FkVmlkZW9fKHVybCkudGhlbihmdW5jdGlvbigpIHtcbiAgICAgICAgICBzZWxmLmVtaXQoJ2xvYWQnLCBzZWxmLnZpZGVvKTtcbiAgICAgICAgfSkuY2F0Y2godGhpcy5vbkVycm9yXy5iaW5kKHRoaXMpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNlbGYub25FcnJvcl8oJ0hMUyBpcyBvbmx5IHN1cHBvcnRlZCBvbiBTYWZhcmkuJyk7XG4gICAgICB9XG4gICAgICBicmVhaztcbiAgICBjYXNlICdtcGQnOiAvLyBNUEVHLURBU0hcbiAgICAgIHRoaXMudHlwZSA9IFR5cGVzLkRBU0g7XG4gICAgICB0aGlzLmxvYWRTaGFrYVZpZGVvXyh1cmwpLnRoZW4oZnVuY3Rpb24oKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKCdUaGUgdmlkZW8gaGFzIG5vdyBiZWVuIGxvYWRlZCEnKTtcbiAgICAgICAgc2VsZi5lbWl0KCdsb2FkJywgc2VsZi52aWRlbyk7XG4gICAgICB9KS5jYXRjaCh0aGlzLm9uRXJyb3JfLmJpbmQodGhpcykpO1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDogLy8gQSByZWd1bGFyIHZpZGVvLCBub3QgYW4gYWRhcHRpdmUgbWFuaWZlc3QuXG4gICAgICB0aGlzLnR5cGUgPSBUeXBlcy5WSURFTztcbiAgICAgIHRoaXMubG9hZFZpZGVvXyh1cmwpLnRoZW4oZnVuY3Rpb24oKSB7XG4gICAgICAgIHNlbGYuZW1pdCgnbG9hZCcsIHNlbGYudmlkZW8pO1xuICAgICAgfSkuY2F0Y2godGhpcy5vbkVycm9yXy5iaW5kKHRoaXMpKTtcbiAgICAgIGJyZWFrO1xuICB9XG59O1xuXG5BZGFwdGl2ZVBsYXllci5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLnZpZGVvLnBhdXNlKCk7XG4gIHRoaXMudmlkZW8uc3JjID0gJyc7XG4gIHRoaXMudmlkZW8gPSBudWxsO1xufTtcblxuLyoqKiBQUklWQVRFIEFQSSAqKiovXG5cbkFkYXB0aXZlUGxheWVyLnByb3RvdHlwZS5vbkVycm9yXyA9IGZ1bmN0aW9uKGUpIHtcbiAgY29uc29sZS5lcnJvcihlKTtcbiAgdGhpcy5lbWl0KCdlcnJvcicsIGUpO1xufTtcblxuQWRhcHRpdmVQbGF5ZXIucHJvdG90eXBlLmxvYWRWaWRlb18gPSBmdW5jdGlvbih1cmwpIHtcbiAgdmFyIHZpZGVvID0gdGhpcy52aWRlbztcbiAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuICAgIHZpZGVvLnNyYyA9IHVybDtcbiAgICB2aWRlby5hZGRFdmVudExpc3RlbmVyKCdjYW5wbGF5dGhyb3VnaCcsIHJlc29sdmUpO1xuICAgIHZpZGVvLmFkZEV2ZW50TGlzdGVuZXIoJ2Vycm9yJywgcmVqZWN0KTtcbiAgICB2aWRlby5sb2FkKCk7XG4gIH0pO1xufTtcblxuQWRhcHRpdmVQbGF5ZXIucHJvdG90eXBlLmluaXRTaGFrYV8gPSBmdW5jdGlvbigpIHtcbiAgdGhpcy5wbGF5ZXIgPSBuZXcgc2hha2EuUGxheWVyKHRoaXMudmlkZW8pO1xuXG4gIHRoaXMucGxheWVyLmNvbmZpZ3VyZSh7XG4gICAgYWJyOiB7IGRlZmF1bHRCYW5kd2lkdGhFc3RpbWF0ZTogREVGQVVMVF9CSVRTX1BFUl9TRUNPTkQgfVxuICB9KTtcblxuICAvLyBMaXN0ZW4gZm9yIGVycm9yIGV2ZW50cy5cbiAgdGhpcy5wbGF5ZXIuYWRkRXZlbnRMaXN0ZW5lcignZXJyb3InLCB0aGlzLm9uRXJyb3JfKTtcbn07XG5cbkFkYXB0aXZlUGxheWVyLnByb3RvdHlwZS5sb2FkU2hha2FWaWRlb18gPSBmdW5jdGlvbih1cmwpIHtcbiAgLy8gSW5zdGFsbCBidWlsdC1pbiBwb2x5ZmlsbHMgdG8gcGF0Y2ggYnJvd3NlciBpbmNvbXBhdGliaWxpdGllcy5cbiAgc2hha2EucG9seWZpbGwuaW5zdGFsbEFsbCgpO1xuXG4gIGlmICghc2hha2EuUGxheWVyLmlzQnJvd3NlclN1cHBvcnRlZCgpKSB7XG4gICAgY29uc29sZS5lcnJvcignU2hha2EgaXMgbm90IHN1cHBvcnRlZCBvbiB0aGlzIGJyb3dzZXIuJyk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdGhpcy5pbml0U2hha2FfKCk7XG4gIHJldHVybiB0aGlzLnBsYXllci5sb2FkKHVybCk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IEFkYXB0aXZlUGxheWVyO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDE2IEdvb2dsZSBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cbnZhciBFeWVzID0ge1xuICBMRUZUOiAxLFxuICBSSUdIVDogMlxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBFeWVzO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDE2IEdvb2dsZSBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cbnZhciBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCdldmVudGVtaXR0ZXIzJyk7XG52YXIgVFdFRU4gPSByZXF1aXJlKCd0d2Vlbi5qcycpO1xuXG4vLyBDb25zdGFudHMgZm9yIHRoZSBmb2N1cy9ibHVyIGFuaW1hdGlvbi5cbnZhciBOT1JNQUxfU0NBTEUgPSBuZXcgVEhSRUUuVmVjdG9yMygxLCAxLCAxKTtcbnZhciBGT0NVU19TQ0FMRSA9IG5ldyBUSFJFRS5WZWN0b3IzKDEuMiwgMS4yLCAxLjIpO1xudmFyIEZPQ1VTX0RVUkFUSU9OID0gMjAwO1xuXG4vLyBDb25zdGFudHMgZm9yIHRoZSBhY3RpdmUvaW5hY3RpdmUgYW5pbWF0aW9uLlxudmFyIElOQUNUSVZFX0NPTE9SID0gbmV3IFRIUkVFLkNvbG9yKDEsIDEsIDEpO1xudmFyIEFDVElWRV9DT0xPUiA9IG5ldyBUSFJFRS5Db2xvcigwLjgsIDAsIDApO1xudmFyIEFDVElWRV9EVVJBVElPTiA9IDEwMDtcblxuLy8gQ29uc3RhbnRzIGZvciBvcGFjaXR5LlxudmFyIE1BWF9JTk5FUl9PUEFDSVRZID0gMC44O1xudmFyIE1BWF9PVVRFUl9PUEFDSVRZID0gMC41O1xudmFyIEZBREVfU1RBUlRfQU5HTEVfREVHID0gMzU7XG52YXIgRkFERV9FTkRfQU5HTEVfREVHID0gNjA7XG4vKipcbiAqIFJlc3BvbnNpYmxlIGZvciByZWN0YW5ndWxhciBob3Qgc3BvdHMgdGhhdCB0aGUgdXNlciBjYW4gaW50ZXJhY3Qgd2l0aC5cbiAqXG4gKiBTcGVjaWZpYyBkdXRpZXM6XG4gKiAgIEFkZGluZyBhbmQgcmVtb3ZpbmcgaG90c3BvdHMuXG4gKiAgIFJlbmRlcmluZyB0aGUgaG90c3BvdHMgKGRlYnVnIG1vZGUgb25seSkuXG4gKiAgIE5vdGlmeWluZyB3aGVuIGhvdHNwb3RzIGFyZSBpbnRlcmFjdGVkIHdpdGguXG4gKlxuICogRW1pdHMgdGhlIGZvbGxvd2luZyBldmVudHM6XG4gKiAgIGNsaWNrIChpZCk6IGEgaG90c3BvdCBpcyBjbGlja2VkLlxuICogICBmb2N1cyAoaWQpOiBhIGhvdHNwb3QgaXMgZm9jdXNlZC5cbiAqICAgYmx1ciAoaWQpOiBhIGhvdHNwb3QgaXMgbm8gbG9uZ2VyIGhvdmVyZWQgb3Zlci5cbiAqL1xuZnVuY3Rpb24gSG90c3BvdFJlbmRlcmVyKHdvcmxkUmVuZGVyZXIpIHtcbiAgdGhpcy53b3JsZFJlbmRlcmVyID0gd29ybGRSZW5kZXJlcjtcbiAgdGhpcy5zY2VuZSA9IHdvcmxkUmVuZGVyZXIuc2NlbmU7XG5cbiAgLy8gTm90ZTogdGhpcyBldmVudCBtdXN0IGJlIGFkZGVkIHRvIGRvY3VtZW50LmJvZHkgYW5kIG5vdCB0byB3aW5kb3cgZm9yIGl0IHRvXG4gIC8vIHdvcmsgaW5zaWRlIGlPUyBpZnJhbWVzLlxuICB2YXIgYm9keSA9IGRvY3VtZW50LmJvZHk7XG4gIC8vIEJpbmQgZXZlbnRzIGZvciBob3RzcG90IGludGVyYWN0aW9uLlxuICBpZiAoIVV0aWwuaXNNb2JpbGUoKSkge1xuICAgIC8vIE9ubHkgZW5hYmxlIG1vdXNlIGV2ZW50cyBvbiBkZXNrdG9wLlxuICAgIGJvZHkuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgdGhpcy5vbk1vdXNlRG93bl8uYmluZCh0aGlzKSwgZmFsc2UpO1xuICAgIGJvZHkuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgdGhpcy5vbk1vdXNlTW92ZV8uYmluZCh0aGlzKSwgZmFsc2UpO1xuICAgIGJvZHkuYWRkRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsIHRoaXMub25Nb3VzZVVwXy5iaW5kKHRoaXMpLCBmYWxzZSk7XG4gIH1cbiAgYm9keS5hZGRFdmVudExpc3RlbmVyKCd0b3VjaHN0YXJ0JywgdGhpcy5vblRvdWNoU3RhcnRfLmJpbmQodGhpcyksIGZhbHNlKTtcbiAgYm9keS5hZGRFdmVudExpc3RlbmVyKCd0b3VjaGVuZCcsIHRoaXMub25Ub3VjaEVuZF8uYmluZCh0aGlzKSwgZmFsc2UpO1xuXG4gIC8vIEFkZCBhIHBsYWNlaG9sZGVyIGZvciBob3RzcG90cy5cbiAgdGhpcy5ob3RzcG90Um9vdCA9IG5ldyBUSFJFRS5PYmplY3QzRCgpO1xuICAvLyBBbGlnbiB0aGUgY2VudGVyIHdpdGggdGhlIGNlbnRlciBvZiB0aGUgY2FtZXJhIHRvby5cbiAgdGhpcy5ob3RzcG90Um9vdC5yb3RhdGlvbi55ID0gTWF0aC5QSSAvIDI7XG4gIHRoaXMuc2NlbmUuYWRkKHRoaXMuaG90c3BvdFJvb3QpO1xuXG4gIC8vIEFsbCBob3RzcG90IElEcy5cbiAgdGhpcy5ob3RzcG90cyA9IHt9O1xuXG4gIC8vIEN1cnJlbnRseSBzZWxlY3RlZCBob3RzcG90cy5cbiAgdGhpcy5zZWxlY3RlZEhvdHNwb3RzID0ge307XG5cbiAgLy8gSG90c3BvdHMgdGhhdCB0aGUgbGFzdCB0b3VjaHN0YXJ0IC8gbW91c2Vkb3duIGV2ZW50IGhhcHBlbmVkIGZvci5cbiAgdGhpcy5kb3duSG90c3BvdHMgPSB7fTtcblxuICAvLyBGb3IgcmF5Y2FzdGluZy4gSW5pdGlhbGl6ZSBtb3VzZSB0byBiZSBvZmYgc2NyZWVuIGluaXRpYWxseS5cbiAgdGhpcy5wb2ludGVyID0gbmV3IFRIUkVFLlZlY3RvcjIoMSwgMSk7XG4gIHRoaXMucmF5Y2FzdGVyID0gbmV3IFRIUkVFLlJheWNhc3RlcigpO1xufVxuSG90c3BvdFJlbmRlcmVyLnByb3RvdHlwZSA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuLyoqXG4gKiBAcGFyYW0gcGl0Y2gge051bWJlcn0gVGhlIGxhdGl0dWRlIG9mIGNlbnRlciwgc3BlY2lmaWVkIGluIGRlZ3JlZXMsIGJldHdlZW5cbiAqIC05MCBhbmQgOTAsIHdpdGggMCBhdCB0aGUgaG9yaXpvbi5cbiAqIEBwYXJhbSB5YXcge051bWJlcn0gVGhlIGxvbmdpdHVkZSBvZiBjZW50ZXIsIHNwZWNpZmllZCBpbiBkZWdyZWVzLCBiZXR3ZWVuXG4gKiAtMTgwIGFuZCAxODAsIHdpdGggMCBhdCB0aGUgaW1hZ2UgY2VudGVyLlxuICogQHBhcmFtIHJhZGl1cyB7TnVtYmVyfSBUaGUgcmFkaXVzIG9mIHRoZSBob3RzcG90LCBzcGVjaWZpZWQgaW4gbWV0ZXJzLlxuICogQHBhcmFtIGRpc3RhbmNlIHtOdW1iZXJ9IFRoZSBkaXN0YW5jZSBvZiB0aGUgaG90c3BvdCBmcm9tIGNhbWVyYSwgc3BlY2lmaWVkXG4gKiBpbiBtZXRlcnMuXG4gKiBAcGFyYW0gaG90c3BvdElkIHtTdHJpbmd9IFRoZSBJRCBvZiB0aGUgaG90c3BvdC5cbiAqL1xuSG90c3BvdFJlbmRlcmVyLnByb3RvdHlwZS5hZGQgPSBmdW5jdGlvbihwaXRjaCwgeWF3LCByYWRpdXMsIGRpc3RhbmNlLCBpZCkge1xuICAvLyBJZiBhIGhvdHNwb3QgYWxyZWFkeSBleGlzdHMgd2l0aCB0aGlzIElELCBzdG9wLlxuICBpZiAodGhpcy5ob3RzcG90c1tpZF0pIHtcbiAgICAvLyBUT0RPOiBQcm9wZXIgZXJyb3IgcmVwb3J0aW5nLlxuICAgIGNvbnNvbGUuZXJyb3IoJ0F0dGVtcHQgdG8gYWRkIGhvdHNwb3Qgd2l0aCBleGlzdGluZyBpZCAlcy4nLCBpZCk7XG4gICAgcmV0dXJuO1xuICB9XG4gIHZhciBob3RzcG90ID0gdGhpcy5jcmVhdGVIb3RzcG90XyhyYWRpdXMsIGRpc3RhbmNlKTtcbiAgaG90c3BvdC5uYW1lID0gaWQ7XG5cbiAgLy8gUG9zaXRpb24gdGhlIGhvdHNwb3QgYmFzZWQgb24gdGhlIHBpdGNoIGFuZCB5YXcgc3BlY2lmaWVkLlxuICB2YXIgcXVhdCA9IG5ldyBUSFJFRS5RdWF0ZXJuaW9uKCk7XG4gIHF1YXQuc2V0RnJvbUV1bGVyKG5ldyBUSFJFRS5FdWxlcihUSFJFRS5NYXRoLmRlZ1RvUmFkKHBpdGNoKSwgVEhSRUUuTWF0aC5kZWdUb1JhZCh5YXcpLCAwKSk7XG4gIGhvdHNwb3QucG9zaXRpb24uYXBwbHlRdWF0ZXJuaW9uKHF1YXQpO1xuICBob3RzcG90Lmxvb2tBdChuZXcgVEhSRUUuVmVjdG9yMygpKTtcbiAgXG4gIHRoaXMuaG90c3BvdFJvb3QuYWRkKGhvdHNwb3QpO1xuICB0aGlzLmhvdHNwb3RzW2lkXSA9IGhvdHNwb3Q7XG59XG5cbi8qKlxuICogUmVtb3ZlcyBhIGhvdHNwb3QgYmFzZWQgb24gdGhlIElELlxuICpcbiAqIEBwYXJhbSBJRCB7U3RyaW5nfSBJZGVudGlmaWVyIG9mIHRoZSBob3RzcG90IHRvIGJlIHJlbW92ZWQuXG4gKi9cbkhvdHNwb3RSZW5kZXJlci5wcm90b3R5cGUucmVtb3ZlID0gZnVuY3Rpb24oaWQpIHtcbiAgLy8gSWYgdGhlcmUncyBubyBob3RzcG90IHdpdGggdGhpcyBJRCwgZmFpbC5cbiAgaWYgKCF0aGlzLmhvdHNwb3RzW2lkXSkgeyBcbiAgICAvLyBUT0RPOiBQcm9wZXIgZXJyb3IgcmVwb3J0aW5nLlxuICAgIGNvbnNvbGUuZXJyb3IoJ0F0dGVtcHQgdG8gcmVtb3ZlIG5vbi1leGlzdGluZyBob3RzcG90IHdpdGggaWQgJXMuJywgaWQpO1xuICAgIHJldHVybjtcbiAgfVxuICAvLyBSZW1vdmUgdGhlIG1lc2ggZnJvbSB0aGUgc2NlbmUuXG4gIHRoaXMuaG90c3BvdFJvb3QucmVtb3ZlKHRoaXMuaG90c3BvdHNbaWRdKTtcblxuICAvLyBJZiB0aGlzIGhvdHNwb3Qgd2FzIHNlbGVjdGVkLCBtYWtlIHN1cmUgaXQgZ2V0cyB1bnNlbGVjdGVkLlxuICBkZWxldGUgdGhpcy5zZWxlY3RlZEhvdHNwb3RzW2lkXTtcbiAgZGVsZXRlIHRoaXMuZG93bkhvdHNwb3RzW2lkXTtcbiAgZGVsZXRlIHRoaXMuaG90c3BvdHNbaWRdO1xuICB0aGlzLmVtaXQoJ2JsdXInLCBpZCk7XG59O1xuXG4vKipcbiAqIENsZWFycyBhbGwgaG90c3BvdHMgZnJvbSB0aGUgcGFuby4gT2Z0ZW4gY2FsbGVkIHdoZW4gY2hhbmdpbmcgcGFub3MuXG4gKi9cbkhvdHNwb3RSZW5kZXJlci5wcm90b3R5cGUuY2xlYXJBbGwgPSBmdW5jdGlvbigpIHtcbiAgZm9yICh2YXIgaWQgaW4gdGhpcy5ob3RzcG90cykge1xuICAgIHRoaXMucmVtb3ZlKGlkKTtcbiAgfVxufTtcblxuSG90c3BvdFJlbmRlcmVyLnByb3RvdHlwZS5nZXRDb3VudCA9IGZ1bmN0aW9uKCkge1xuICB2YXIgY291bnQgPSAwO1xuICBmb3IgKHZhciBpZCBpbiB0aGlzLmhvdHNwb3RzKSB7XG4gICAgY291bnQgKz0gMTtcbiAgfVxuICByZXR1cm4gY291bnQ7XG59O1xuXG5Ib3RzcG90UmVuZGVyZXIucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uKGNhbWVyYSkge1xuICBpZiAodGhpcy53b3JsZFJlbmRlcmVyLmlzVlJNb2RlKCkpIHtcbiAgICB0aGlzLnBvaW50ZXIuc2V0KDAsIDApO1xuICB9XG4gIC8vIFVwZGF0ZSB0aGUgcGlja2luZyByYXkgd2l0aCB0aGUgY2FtZXJhIGFuZCBtb3VzZSBwb3NpdGlvbi5cbiAgdGhpcy5yYXljYXN0ZXIuc2V0RnJvbUNhbWVyYSh0aGlzLnBvaW50ZXIsIGNhbWVyYSk7XHRcblxuICAvLyBGYWRlIGhvdHNwb3RzIG91dCBpZiB0aGV5IGFyZSByZWFsbHkgZmFyIGZyb20gY2VudGVyIHRvIGF2b2lkIG92ZXJseVxuICAvLyBkaXN0b3J0ZWQgdmlzdWFscy5cbiAgdGhpcy5mYWRlT2ZmQ2VudGVySG90c3BvdHNfKGNhbWVyYSk7XG5cbiAgdmFyIGhvdHNwb3RzID0gdGhpcy5ob3RzcG90Um9vdC5jaGlsZHJlbjtcblxuICAvLyBHbyB0aHJvdWdoIGFsbCBob3RzcG90cyB0byBzZWUgaWYgdGhleSBhcmUgY3VycmVudGx5IHNlbGVjdGVkLlxuICBmb3IgKHZhciBpID0gMDsgaSA8IGhvdHNwb3RzLmxlbmd0aDsgaSsrKSB7XG4gICAgdmFyIGhvdHNwb3QgPSBob3RzcG90c1tpXTtcbiAgICAvL2hvdHNwb3QubG9va0F0KGNhbWVyYS5wb3NpdGlvbik7XG4gICAgdmFyIGlkID0gaG90c3BvdC5uYW1lO1xuICAgIC8vIENoZWNrIGlmIGhvdHNwb3QgaXMgaW50ZXJzZWN0ZWQgd2l0aCB0aGUgcGlja2luZyByYXkuXG4gICAgdmFyIGludGVyc2VjdHMgPSB0aGlzLnJheWNhc3Rlci5pbnRlcnNlY3RPYmplY3RzKGhvdHNwb3QuY2hpbGRyZW4pO1xuICAgIHZhciBpc0ludGVyc2VjdGVkID0gKGludGVyc2VjdHMubGVuZ3RoID4gMCk7XG5cbiAgICAvLyBJZiBuZXdseSBzZWxlY3RlZCwgZW1pdCBhIGZvY3VzIGV2ZW50LlxuICAgIGlmIChpc0ludGVyc2VjdGVkICYmICF0aGlzLnNlbGVjdGVkSG90c3BvdHNbaWRdKSB7XG4gICAgICB0aGlzLmVtaXQoJ2ZvY3VzJywgaWQpO1xuICAgICAgdGhpcy5mb2N1c18oaWQpO1xuICAgIH1cbiAgICAvLyBJZiBubyBsb25nZXIgc2VsZWN0ZWQsIGVtaXQgYSBibHVyIGV2ZW50LlxuICAgIGlmICghaXNJbnRlcnNlY3RlZCAmJiB0aGlzLnNlbGVjdGVkSG90c3BvdHNbaWRdKSB7XG4gICAgICB0aGlzLmVtaXQoJ2JsdXInLCBpZCk7XG4gICAgICB0aGlzLmJsdXJfKGlkKTtcbiAgICB9XG4gICAgLy8gVXBkYXRlIHRoZSBzZXQgb2Ygc2VsZWN0ZWQgaG90c3BvdHMuXG4gICAgaWYgKGlzSW50ZXJzZWN0ZWQpIHtcbiAgICAgIHRoaXMuc2VsZWN0ZWRIb3RzcG90c1tpZF0gPSB0cnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICBkZWxldGUgdGhpcy5zZWxlY3RlZEhvdHNwb3RzW2lkXTtcbiAgICB9XG4gIH1cbn07XG5cbi8qKlxuICogVG9nZ2xlIHdoZXRoZXIgb3Igbm90IGhvdHNwb3RzIGFyZSB2aXNpYmxlLlxuICovXG5Ib3RzcG90UmVuZGVyZXIucHJvdG90eXBlLnNldFZpc2liaWxpdHkgPSBmdW5jdGlvbihpc1Zpc2libGUpIHtcbiAgdGhpcy5ob3RzcG90Um9vdC52aXNpYmxlID0gaXNWaXNpYmxlO1xufTtcblxuSG90c3BvdFJlbmRlcmVyLnByb3RvdHlwZS5vblRvdWNoU3RhcnRfID0gZnVuY3Rpb24oZSkge1xuICAvLyBJbiBWUiBtb2RlLCBkb24ndCB0b3VjaCB0aGUgcG9pbnRlciBwb3NpdGlvbi5cbiAgaWYgKCF0aGlzLndvcmxkUmVuZGVyZXIuaXNWUk1vZGUoKSkge1xuICAgIHRoaXMudXBkYXRlVG91Y2hfKGUpO1xuICB9XG5cbiAgLy8gRm9yY2UgYSBjYW1lcmEgdXBkYXRlIHRvIHNlZSBpZiBhbnkgaG90c3BvdHMgd2VyZSBzZWxlY3RlZC5cbiAgdGhpcy51cGRhdGUodGhpcy53b3JsZFJlbmRlcmVyLmNhbWVyYSk7XG5cbiAgdGhpcy5kb3duSG90c3BvdHMgPSB7fTtcbiAgZm9yICh2YXIgaWQgaW4gdGhpcy5zZWxlY3RlZEhvdHNwb3RzKSB7XG4gICAgdGhpcy5kb3duSG90c3BvdHNbaWRdID0gdHJ1ZTtcbiAgICB0aGlzLmRvd25fKGlkKTtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59O1xuXG5Ib3RzcG90UmVuZGVyZXIucHJvdG90eXBlLm9uVG91Y2hFbmRfID0gZnVuY3Rpb24oZSkge1xuICAvLyBJZiBubyBob3RzcG90cyBhcmUgcHJlc3NlZCwgZW1pdCBhbiBlbXB0eSBjbGljayBldmVudC5cbiAgaWYgKFV0aWwuaXNFbXB0eU9iamVjdCh0aGlzLmRvd25Ib3RzcG90cykpIHtcbiAgICB0aGlzLmVtaXQoJ2NsaWNrJyk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gT25seSBlbWl0IGEgY2xpY2sgaWYgdGhlIGZpbmdlciB3YXMgZG93biBvbiB0aGUgc2FtZSBob3RzcG90IGJlZm9yZS5cbiAgZm9yICh2YXIgaWQgaW4gdGhpcy5kb3duSG90c3BvdHMpIHtcbiAgICB0aGlzLmVtaXQoJ2NsaWNrJywgaWQpO1xuICAgIHRoaXMudXBfKGlkKTtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gIH1cbn07XG5cbkhvdHNwb3RSZW5kZXJlci5wcm90b3R5cGUudXBkYXRlVG91Y2hfID0gZnVuY3Rpb24oZSkge1xuICB2YXIgc2l6ZSA9IHRoaXMuZ2V0U2l6ZV8oKTtcbiAgdmFyIHRvdWNoID0gZS50b3VjaGVzWzBdO1xuXHR0aGlzLnBvaW50ZXIueCA9ICh0b3VjaC5jbGllbnRYIC8gc2l6ZS53aWR0aCkgKiAyIC0gMTtcblx0dGhpcy5wb2ludGVyLnkgPSAtICh0b3VjaC5jbGllbnRZIC8gc2l6ZS5oZWlnaHQpICogMiArIDE7XHRcbn07XG5cbkhvdHNwb3RSZW5kZXJlci5wcm90b3R5cGUub25Nb3VzZURvd25fID0gZnVuY3Rpb24oZSkge1xuICB0aGlzLnVwZGF0ZU1vdXNlXyhlKTtcblxuICB0aGlzLmRvd25Ib3RzcG90cyA9IHt9O1xuICBmb3IgKHZhciBpZCBpbiB0aGlzLnNlbGVjdGVkSG90c3BvdHMpIHtcbiAgICB0aGlzLmRvd25Ib3RzcG90c1tpZF0gPSB0cnVlO1xuICAgIHRoaXMuZG93bl8oaWQpO1xuICB9XG59O1xuXG5Ib3RzcG90UmVuZGVyZXIucHJvdG90eXBlLm9uTW91c2VNb3ZlXyA9IGZ1bmN0aW9uKGUpIHtcbiAgdGhpcy51cGRhdGVNb3VzZV8oZSk7XG59O1xuXG5Ib3RzcG90UmVuZGVyZXIucHJvdG90eXBlLm9uTW91c2VVcF8gPSBmdW5jdGlvbihlKSB7XG4gIHRoaXMudXBkYXRlTW91c2VfKGUpO1xuXG4gIC8vIElmIG5vIGhvdHNwb3RzIGFyZSBwcmVzc2VkLCBlbWl0IGFuIGVtcHR5IGNsaWNrIGV2ZW50LlxuICBpZiAoVXRpbC5pc0VtcHR5T2JqZWN0KHRoaXMuZG93bkhvdHNwb3RzKSkge1xuICAgIHRoaXMuZW1pdCgnY2xpY2snKTtcbiAgICByZXR1cm47XG4gIH1cblxuICAvLyBPbmx5IGVtaXQgYSBjbGljayBpZiB0aGUgbW91c2Ugd2FzIGRvd24gb24gdGhlIHNhbWUgaG90c3BvdCBiZWZvcmUuXG4gIGZvciAodmFyIGlkIGluIHRoaXMuc2VsZWN0ZWRIb3RzcG90cykge1xuICAgIGlmIChpZCBpbiB0aGlzLmRvd25Ib3RzcG90cykge1xuICAgICAgdGhpcy5lbWl0KCdjbGljaycsIGlkKTtcbiAgICAgIHRoaXMudXBfKGlkKTtcbiAgICB9XG4gIH1cbn07XG5cbkhvdHNwb3RSZW5kZXJlci5wcm90b3R5cGUudXBkYXRlTW91c2VfID0gZnVuY3Rpb24oZSkge1xuICB2YXIgc2l6ZSA9IHRoaXMuZ2V0U2l6ZV8oKTtcblx0dGhpcy5wb2ludGVyLnggPSAoZS5jbGllbnRYIC8gc2l6ZS53aWR0aCkgKiAyIC0gMTtcblx0dGhpcy5wb2ludGVyLnkgPSAtIChlLmNsaWVudFkgLyBzaXplLmhlaWdodCkgKiAyICsgMTtcdFxufTtcblxuSG90c3BvdFJlbmRlcmVyLnByb3RvdHlwZS5nZXRTaXplXyA9IGZ1bmN0aW9uKCkge1xuICB2YXIgY2FudmFzID0gdGhpcy53b3JsZFJlbmRlcmVyLnJlbmRlcmVyLmRvbUVsZW1lbnQ7XG4gIHJldHVybiB0aGlzLndvcmxkUmVuZGVyZXIucmVuZGVyZXIuZ2V0U2l6ZSgpO1xufTtcblxuSG90c3BvdFJlbmRlcmVyLnByb3RvdHlwZS5jcmVhdGVIb3RzcG90XyA9IGZ1bmN0aW9uKHJhZGl1cywgZGlzdGFuY2UpIHtcbiAgdmFyIGlubmVyR2VvbWV0cnkgPSBuZXcgVEhSRUUuQ2lyY2xlR2VvbWV0cnkocmFkaXVzLCAzMik7XG5cbiAgdmFyIGlubmVyTWF0ZXJpYWwgPSBuZXcgVEhSRUUuTWVzaEJhc2ljTWF0ZXJpYWwoe1xuICAgIGNvbG9yOiAweGZmZmZmZiwgc2lkZTogVEhSRUUuRG91YmxlU2lkZSwgdHJhbnNwYXJlbnQ6IHRydWUsXG4gICAgb3BhY2l0eTogTUFYX0lOTkVSX09QQUNJVFksIGRlcHRoVGVzdDogZmFsc2VcbiAgfSk7XG5cbiAgdmFyIGlubmVyID0gbmV3IFRIUkVFLk1lc2goaW5uZXJHZW9tZXRyeSwgaW5uZXJNYXRlcmlhbCk7XG4gIGlubmVyLm5hbWUgPSAnaW5uZXInO1xuXG4gIHZhciBvdXRlck1hdGVyaWFsID0gbmV3IFRIUkVFLk1lc2hCYXNpY01hdGVyaWFsKHtcbiAgICBjb2xvcjogMHhmZmZmZmYsIHNpZGU6IFRIUkVFLkRvdWJsZVNpZGUsIHRyYW5zcGFyZW50OiB0cnVlLFxuICAgIG9wYWNpdHk6IE1BWF9PVVRFUl9PUEFDSVRZLCBkZXB0aFRlc3Q6IGZhbHNlXG4gIH0pO1xuICB2YXIgb3V0ZXJHZW9tZXRyeSA9IG5ldyBUSFJFRS5SaW5nR2VvbWV0cnkocmFkaXVzICogMC44NSwgcmFkaXVzLCAzMik7XG4gIHZhciBvdXRlciA9IG5ldyBUSFJFRS5NZXNoKG91dGVyR2VvbWV0cnksIG91dGVyTWF0ZXJpYWwpO1xuICBvdXRlci5uYW1lID0gJ291dGVyJztcblxuICAvLyBQb3NpdGlvbiBhdCB0aGUgZXh0cmVtZSBlbmQgb2YgdGhlIHNwaGVyZS5cbiAgdmFyIGhvdHNwb3QgPSBuZXcgVEhSRUUuT2JqZWN0M0QoKTtcbiAgaG90c3BvdC5wb3NpdGlvbi56ID0gLWRpc3RhbmNlO1xuICBob3RzcG90LnNjYWxlLnNldChOT1JNQUxfU0NBTEUpO1xuXG4gIGhvdHNwb3QuYWRkKGlubmVyKTtcbiAgaG90c3BvdC5hZGQob3V0ZXIpO1xuXG4gIHJldHVybiBob3RzcG90O1xufTtcblxuLyoqXG4gKiBMYXJnZSBhc3BlY3QgcmF0aW9zIHRlbmQgdG8gY2F1c2UgdmlzdWFsbHkgamFycmluZyBkaXN0b3J0aW9ucyBvbiB0aGUgc2lkZXMuXG4gKiBIZXJlIHdlIGZhZGUgaG90c3BvdHMgb3V0IHRvIGF2b2lkIHRoZW0uXG4gKi9cbkhvdHNwb3RSZW5kZXJlci5wcm90b3R5cGUuZmFkZU9mZkNlbnRlckhvdHNwb3RzXyA9IGZ1bmN0aW9uKGNhbWVyYSkge1xuICB2YXIgbG9va0F0ID0gbmV3IFRIUkVFLlZlY3RvcjMoMSwgMCwgMCk7XG4gIGxvb2tBdC5hcHBseVF1YXRlcm5pb24oY2FtZXJhLnF1YXRlcm5pb24pO1xuICAvLyBUYWtlIGludG8gYWNjb3VudCB0aGUgY2FtZXJhIHBhcmVudCB0b28uXG4gIGxvb2tBdC5hcHBseVF1YXRlcm5pb24oY2FtZXJhLnBhcmVudC5xdWF0ZXJuaW9uKTtcblxuICAvLyBHbyB0aHJvdWdoIGVhY2ggaG90c3BvdC4gQ2FsY3VsYXRlIGhvdyBmYXIgb2ZmIGNlbnRlciBpdCBpcy5cbiAgZm9yICh2YXIgaWQgaW4gdGhpcy5ob3RzcG90cykge1xuICAgIHZhciBob3RzcG90ID0gdGhpcy5ob3RzcG90c1tpZF07XG4gICAgdmFyIGFuZ2xlID0gaG90c3BvdC5wb3NpdGlvbi5hbmdsZVRvKGxvb2tBdCk7XG4gICAgdmFyIGFuZ2xlRGVnID0gVEhSRUUuTWF0aC5yYWRUb0RlZyhhbmdsZSk7XG4gICAgdmFyIGlzVmlzaWJsZSA9IGFuZ2xlRGVnIDwgNDU7XG4gICAgdmFyIG9wYWNpdHk7XG4gICAgaWYgKGFuZ2xlRGVnIDwgRkFERV9TVEFSVF9BTkdMRV9ERUcpIHtcbiAgICAgIG9wYWNpdHkgPSAxO1xuICAgIH0gZWxzZSBpZiAoYW5nbGVEZWcgPiBGQURFX0VORF9BTkdMRV9ERUcpIHtcbiAgICAgIG9wYWNpdHkgPSAwO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBXZSBhcmUgaW4gdGhlIGNhc2UgU1RBUlQgPCBhbmdsZSA8IEVORC4gTGluZWFybHkgaW50ZXJwb2xhdGUuXG4gICAgICB2YXIgcmFuZ2UgPSBGQURFX0VORF9BTkdMRV9ERUcgLSBGQURFX1NUQVJUX0FOR0xFX0RFRztcbiAgICAgIHZhciB2YWx1ZSA9IEZBREVfRU5EX0FOR0xFX0RFRyAtIGFuZ2xlRGVnO1xuICAgICAgb3BhY2l0eSA9IHZhbHVlIC8gcmFuZ2U7XG4gICAgfVxuXG4gICAgLy8gT3BhY2l0eSBhIGZ1bmN0aW9uIG9mIGFuZ2xlLiBJZiBhbmdsZSBpcyBsYXJnZSwgb3BhY2l0eSBpcyB6ZXJvLiBBdCBzb21lXG4gICAgLy8gcG9pbnQsIHJhbXAgb3BhY2l0eSBkb3duLlxuICAgIHRoaXMuc2V0T3BhY2l0eV8oaWQsIG9wYWNpdHkpO1xuICB9XG59O1xuXG5Ib3RzcG90UmVuZGVyZXIucHJvdG90eXBlLmZvY3VzXyA9IGZ1bmN0aW9uKGlkKSB7XG4gIHZhciBob3RzcG90ID0gdGhpcy5ob3RzcG90c1tpZF07XG5cbiAgLy8gVHdlZW4gc2NhbGUgb2YgaG90c3BvdC5cbiAgdGhpcy50d2VlbiA9IG5ldyBUV0VFTi5Ud2Vlbihob3RzcG90LnNjYWxlKS50byhGT0NVU19TQ0FMRSwgRk9DVVNfRFVSQVRJT04pXG4gICAgICAuZWFzaW5nKFRXRUVOLkVhc2luZy5RdWFkcmF0aWMuSW5PdXQpXG4gICAgICAuc3RhcnQoKTtcbn07XG5cbkhvdHNwb3RSZW5kZXJlci5wcm90b3R5cGUuYmx1cl8gPSBmdW5jdGlvbihpZCkge1xuICB2YXIgaG90c3BvdCA9IHRoaXMuaG90c3BvdHNbaWRdO1xuXG4gIHRoaXMudHdlZW4gPSBuZXcgVFdFRU4uVHdlZW4oaG90c3BvdC5zY2FsZSkudG8oTk9STUFMX1NDQUxFLCBGT0NVU19EVVJBVElPTilcbiAgICAgIC5lYXNpbmcoVFdFRU4uRWFzaW5nLlF1YWRyYXRpYy5Jbk91dClcbiAgICAgIC5zdGFydCgpO1xufTtcblxuSG90c3BvdFJlbmRlcmVyLnByb3RvdHlwZS5kb3duXyA9IGZ1bmN0aW9uKGlkKSB7XG4gIC8vIEJlY29tZSBhY3RpdmUuXG4gIHZhciBob3RzcG90ID0gdGhpcy5ob3RzcG90c1tpZF07XG4gIHZhciBvdXRlciA9IGhvdHNwb3QuZ2V0T2JqZWN0QnlOYW1lKCdpbm5lcicpO1xuXG4gIHRoaXMudHdlZW4gPSBuZXcgVFdFRU4uVHdlZW4ob3V0ZXIubWF0ZXJpYWwuY29sb3IpLnRvKEFDVElWRV9DT0xPUiwgQUNUSVZFX0RVUkFUSU9OKVxuICAgICAgLnN0YXJ0KCk7XG59O1xuXG5Ib3RzcG90UmVuZGVyZXIucHJvdG90eXBlLnVwXyA9IGZ1bmN0aW9uKGlkKSB7XG4gIC8vIEJlY29tZSBpbmFjdGl2ZS5cbiAgdmFyIGhvdHNwb3QgPSB0aGlzLmhvdHNwb3RzW2lkXTtcbiAgdmFyIG91dGVyID0gaG90c3BvdC5nZXRPYmplY3RCeU5hbWUoJ2lubmVyJyk7XG5cbiAgdGhpcy50d2VlbiA9IG5ldyBUV0VFTi5Ud2VlbihvdXRlci5tYXRlcmlhbC5jb2xvcikudG8oSU5BQ1RJVkVfQ09MT1IsIEFDVElWRV9EVVJBVElPTilcbiAgICAgIC5zdGFydCgpO1xufTtcblxuSG90c3BvdFJlbmRlcmVyLnByb3RvdHlwZS5zZXRPcGFjaXR5XyA9IGZ1bmN0aW9uKGlkLCBvcGFjaXR5KSB7XG4gIHZhciBob3RzcG90ID0gdGhpcy5ob3RzcG90c1tpZF07XG4gIHZhciBvdXRlciA9IGhvdHNwb3QuZ2V0T2JqZWN0QnlOYW1lKCdvdXRlcicpO1xuICB2YXIgaW5uZXIgPSBob3RzcG90LmdldE9iamVjdEJ5TmFtZSgnaW5uZXInKTtcblxuICBvdXRlci5tYXRlcmlhbC5vcGFjaXR5ID0gb3BhY2l0eSAqIE1BWF9PVVRFUl9PUEFDSVRZO1xuICBpbm5lci5tYXRlcmlhbC5vcGFjaXR5ID0gb3BhY2l0eSAqIE1BWF9JTk5FUl9PUEFDSVRZO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBIb3RzcG90UmVuZGVyZXI7XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMTYgR29vZ2xlIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xudmFyIEV2ZW50RW1pdHRlciA9IHJlcXVpcmUoJ2V2ZW50ZW1pdHRlcjMnKTtcbnZhciBNZXNzYWdlID0gcmVxdWlyZSgnLi4vbWVzc2FnZScpO1xudmFyIFV0aWwgPSByZXF1aXJlKCcuLi91dGlsJyk7XG5cblxuLyoqXG4gKiBTaXRzIGluIGFuIGVtYmVkZGVkIGlmcmFtZSwgcmVjZWl2aW5nIG1lc3NhZ2VzIGZyb20gYSBjb250YWluaW5nXG4gKiBpRnJhbWUuIFRoaXMgZmFjaWxpdGF0ZXMgYW4gQVBJIHdoaWNoIHByb3ZpZGVzIHRoZSBmb2xsb3dpbmcgZmVhdHVyZXM6XG4gKlxuICogICAgUGxheWluZyBhbmQgcGF1c2luZyBjb250ZW50LlxuICogICAgQWRkaW5nIGhvdHNwb3RzLlxuICogICAgU2VuZGluZyBtZXNzYWdlcyBiYWNrIHRvIHRoZSBjb250YWluaW5nIGlmcmFtZSB3aGVuIGhvdHNwb3QgaXMgY2xpY2tlZFxuICogICAgU2VuZGluZyBhbmFseXRpY3MgZXZlbnRzIHRvIGNvbnRhaW5pbmcgaWZyYW1lLlxuICogICAgUmVjZWl2aW5nIERldmljZU1vdGlvbiBldmVudHMgYW5kIHJlc3ludGhlc2l6aW5nIHRoZW0gaW4gdGhpcyBpZnJhbWVcbiAqICAgICAgICAod29ya2Fyb3VuZCBmb3IgaHR0cHM6Ly9idWdzLndlYmtpdC5vcmcvc2hvd19idWcuY2dpP2lkPTE1MDA3MikuXG4gKi9cbmZ1bmN0aW9uIElGcmFtZU1lc3NhZ2VSZWNlaXZlcigpIHtcbiAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCB0aGlzLm9uTWVzc2FnZV8uYmluZCh0aGlzKSwgZmFsc2UpO1xufVxuSUZyYW1lTWVzc2FnZVJlY2VpdmVyLnByb3RvdHlwZSA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuSUZyYW1lTWVzc2FnZVJlY2VpdmVyLnByb3RvdHlwZS5vbk1lc3NhZ2VfID0gZnVuY3Rpb24oZXZlbnQpIHtcbiAgaWYgKFV0aWwuaXNEZWJ1ZygpKSB7XG4gICAgY29uc29sZS5sb2coJ29uTWVzc2FnZV8nLCBldmVudCk7XG4gIH1cblxuICB2YXIgbWVzc2FnZSA9IGV2ZW50LmRhdGE7XG4gIHZhciB0eXBlID0gbWVzc2FnZS50eXBlLnRvTG93ZXJDYXNlKCk7XG4gIHZhciBkYXRhID0gbWVzc2FnZS5kYXRhO1xuXG4gIHN3aXRjaCAodHlwZSkge1xuICAgIGNhc2UgTWVzc2FnZS5ERVZJQ0VfTU9USU9OOlxuICAgICAgLy8gU3ludGhlc2l6ZSBhIERldmljZU1vdGlvbiBldmVudC5cbiAgICAgIHRoaXMuc3ludGhlc2l6ZURldmljZU1vdGlvbkV2ZW50XyhtZXNzYWdlLmRldmljZU1vdGlvbkV2ZW50KTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgTWVzc2FnZS5TRVRfQ09OVEVOVDpcbiAgICBjYXNlIE1lc3NhZ2UuU0VUX1ZPTFVNRTpcbiAgICBjYXNlIE1lc3NhZ2UuQUREX0hPVFNQT1Q6XG4gICAgY2FzZSBNZXNzYWdlLlBMQVk6XG4gICAgY2FzZSBNZXNzYWdlLlBBVVNFOlxuICAgICAgLy8gVE9ETyhzbXVzKTogRW1pdCB0aGUgZXZlbnQgXG4gICAgICB0aGlzLmVtaXQodHlwZSwgZGF0YSk7XG4gICAgICBicmVhaztcbiAgICBkZWZhdWx0OlxuICAgICAgaWYgKFV0aWwuaXNEZWJ1ZygpKSB7XG4gICAgICAgIGNvbnNvbGUud2FybignR290IHVua25vd24gbWVzc2FnZSBvZiB0eXBlICVzIGZyb20gJXMnLCBtZXNzYWdlLnR5cGUsIG1lc3NhZ2Uub3JpZ2luKTtcbiAgICAgIH1cbiAgfVxufTtcblxuSUZyYW1lTWVzc2FnZVJlY2VpdmVyLnByb3RvdHlwZS5zeW50aGVzaXplRGV2aWNlTW90aW9uRXZlbnRfID0gZnVuY3Rpb24oZXZlbnREYXRhKSB7XG4gIHZhciB0eXBlID0gJ2RldmljZW1vdGlvbi1pZnJhbWUnO1xuICB2YXIgY2FuQnViYmxlID0gZmFsc2U7XG4gIHZhciBjYW5jZWxhYmxlID0gZmFsc2U7XG5cbiAgdmFyIGRtZSA9IGRvY3VtZW50LmNyZWF0ZUV2ZW50KCdEZXZpY2VNb3Rpb25FdmVudCcpO1xuICBkbWUuaW5pdERldmljZU1vdGlvbkV2ZW50KHR5cGUsIGNhbkJ1YmJsZSwgY2FuY2VsYWJsZSxcbiAgICAgIGV2ZW50RGF0YS5hY2NlbGVyYXRpb24sXG4gICAgICBldmVudERhdGEuYWNjZWxlcmF0aW9uSW5jbHVkaW5nR3Jhdml0eSxcbiAgICAgIGV2ZW50RGF0YS5yb3RhdGlvblJhdGUsXG4gICAgICBldmVudERhdGEuaW50ZXJ2YWwpO1xuXG4gIHdpbmRvdy5kaXNwYXRjaEV2ZW50KGRtZSk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IElGcmFtZU1lc3NhZ2VSZWNlaXZlcjtcbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAxNiBHb29nbGUgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbi8qKlxuICogU2hvd3MgYSAyRCBsb2FkaW5nIGluZGljYXRvciB3aGlsZSB2YXJpb3VzIHBpZWNlcyBvZiBFbWJlZFZSIGxvYWQuXG4gKi9cbmZ1bmN0aW9uIExvYWRpbmdJbmRpY2F0b3IoKSB7XG4gIHRoaXMuZWwgPSB0aGlzLmJ1aWxkXygpO1xuICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHRoaXMuZWwpO1xuICB0aGlzLnNob3coKTtcbn1cblxuTG9hZGluZ0luZGljYXRvci5wcm90b3R5cGUuYnVpbGRfID0gZnVuY3Rpb24oKSB7XG4gIHZhciBvdmVybGF5ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gIHZhciBzID0gb3ZlcmxheS5zdHlsZTtcbiAgcy5wb3NpdGlvbiA9ICdmaXhlZCc7XG4gIHMudG9wID0gMDtcbiAgcy5sZWZ0ID0gMDtcbiAgcy53aWR0aCA9ICcxMDAlJztcbiAgcy5oZWlnaHQgPSAnMTAwJSc7XG4gIHMuYmFja2dyb3VuZCA9ICcjZWVlJztcbiAgdmFyIGltZyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2ltZycpO1xuICBpbWcuc3JjID0gJ2ltYWdlcy9sb2FkaW5nLmdpZic7XG4gIHZhciBzID0gaW1nLnN0eWxlO1xuICBzLnBvc2l0aW9uID0gJ2Fic29sdXRlJztcbiAgcy50b3AgPSAnNTAlJztcbiAgcy5sZWZ0ID0gJzUwJSc7XG4gIHMudHJhbnNmb3JtID0gJ3RyYW5zbGF0ZSgtNTAlLCAtNTAlKSc7XG5cbiAgb3ZlcmxheS5hcHBlbmRDaGlsZChpbWcpO1xuICByZXR1cm4gb3ZlcmxheTtcbn07XG5cbkxvYWRpbmdJbmRpY2F0b3IucHJvdG90eXBlLmhpZGUgPSBmdW5jdGlvbigpIHtcbiAgdGhpcy5lbC5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xufTtcblxuTG9hZGluZ0luZGljYXRvci5wcm90b3R5cGUuc2hvdyA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLmVsLnN0eWxlLmRpc3BsYXkgPSAnYmxvY2snO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBMb2FkaW5nSW5kaWNhdG9yO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDE2IEdvb2dsZSBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuLy8gSW5pdGlhbGl6ZSB0aGUgbG9hZGluZyBpbmRpY2F0b3IgYXMgcXVpY2tseSBhcyBwb3NzaWJsZSB0byBnaXZlIHRoZSB1c2VyXG4vLyBpbW1lZGlhdGUgZmVlZGJhY2suXG52YXIgTG9hZGluZ0luZGljYXRvciA9IHJlcXVpcmUoJy4vbG9hZGluZy1pbmRpY2F0b3InKTtcbnZhciBsb2FkSW5kaWNhdG9yID0gbmV3IExvYWRpbmdJbmRpY2F0b3IoKTtcblxudmFyIEVTNlByb21pc2UgPSByZXF1aXJlKCdlczYtcHJvbWlzZScpO1xuLy8gUG9seWZpbGwgRVM2IHByb21pc2VzIGZvciBJRS5cbkVTNlByb21pc2UucG9seWZpbGwoKTtcblxudmFyIElGcmFtZU1lc3NhZ2VSZWNlaXZlciA9IHJlcXVpcmUoJy4vaWZyYW1lLW1lc3NhZ2UtcmVjZWl2ZXInKTtcbnZhciBNZXNzYWdlID0gcmVxdWlyZSgnLi4vbWVzc2FnZScpO1xudmFyIFNjZW5lSW5mbyA9IHJlcXVpcmUoJy4vc2NlbmUtaW5mbycpO1xudmFyIFN0YXRzID0gcmVxdWlyZSgnLi4vLi4vbm9kZV9tb2R1bGVzL3N0YXRzLWpzL2J1aWxkL3N0YXRzLm1pbicpO1xudmFyIFV0aWwgPSByZXF1aXJlKCcuLi91dGlsJyk7XG52YXIgV2ViVlJQb2x5ZmlsbCA9IHJlcXVpcmUoJ3dlYnZyLXBvbHlmaWxsJyk7XG52YXIgV29ybGRSZW5kZXJlciA9IHJlcXVpcmUoJy4vd29ybGQtcmVuZGVyZXInKTtcblxudmFyIHJlY2VpdmVyID0gbmV3IElGcmFtZU1lc3NhZ2VSZWNlaXZlcigpO1xucmVjZWl2ZXIub24oTWVzc2FnZS5QTEFZLCBvblBsYXlSZXF1ZXN0KTtcbnJlY2VpdmVyLm9uKE1lc3NhZ2UuUEFVU0UsIG9uUGF1c2VSZXF1ZXN0KTtcbnJlY2VpdmVyLm9uKE1lc3NhZ2UuQUREX0hPVFNQT1QsIG9uQWRkSG90c3BvdCk7XG5yZWNlaXZlci5vbihNZXNzYWdlLlNFVF9DT05URU5ULCBvblNldENvbnRlbnQpO1xucmVjZWl2ZXIub24oTWVzc2FnZS5TRVRfVk9MVU1FLCBvblNldFZvbHVtZSk7XG5cbndpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdsb2FkJywgb25Mb2FkKTtcblxudmFyIHN0YXRzID0gbmV3IFN0YXRzKCk7XG5cbnZhciB3b3JsZFJlbmRlcmVyID0gbmV3IFdvcmxkUmVuZGVyZXIoKTtcbndvcmxkUmVuZGVyZXIub24oJ2Vycm9yJywgb25SZW5kZXJFcnJvcik7XG53b3JsZFJlbmRlcmVyLm9uKCdsb2FkJywgb25SZW5kZXJMb2FkKTtcbndvcmxkUmVuZGVyZXIub24oJ21vZGVjaGFuZ2UnLCBvbk1vZGVDaGFuZ2UpO1xud29ybGRSZW5kZXJlci5ob3RzcG90UmVuZGVyZXIub24oJ2NsaWNrJywgb25Ib3RzcG90Q2xpY2spO1xuXG53aW5kb3cud29ybGRSZW5kZXJlciA9IHdvcmxkUmVuZGVyZXI7XG5cbnZhciBpc1JlYWR5U2VudCA9IGZhbHNlO1xuXG5mdW5jdGlvbiBvbkxvYWQoKSB7XG4gIGlmICghVXRpbC5pc1dlYkdMRW5hYmxlZCgpKSB7XG4gICAgc2hvd0Vycm9yKCdXZWJHTCBub3Qgc3VwcG9ydGVkLicpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIExvYWQgdGhlIHNjZW5lLlxuICB2YXIgc2NlbmUgPSBTY2VuZUluZm8ubG9hZEZyb21HZXRQYXJhbXMoKTtcbiAgd29ybGRSZW5kZXJlci5zZXRTY2VuZShzY2VuZSk7XG5cbiAgaWYgKHNjZW5lLmlzRGVidWcpIHtcbiAgICAvLyBTaG93IHN0YXRzLlxuICAgIHNob3dTdGF0cygpO1xuICB9XG5cbiAgaWYgKHNjZW5lLmlzWWF3T25seSkge1xuICAgIFdlYlZSQ29uZmlnID0gd2luZG93LldlYlZSQ29uZmlnIHx8IHt9O1xuICAgIFdlYlZSQ29uZmlnLllBV19PTkxZID0gdHJ1ZTtcbiAgfVxuXG4gIHJlcXVlc3RBbmltYXRpb25GcmFtZShsb29wKTtcbn1cblxuXG5mdW5jdGlvbiBvblZpZGVvVGFwKCkge1xuICB3b3JsZFJlbmRlcmVyLnZpZGVvUHJveHkucGxheSgpO1xuICBoaWRlUGxheUJ1dHRvbigpO1xuXG4gIC8vIFByZXZlbnQgbXVsdGlwbGUgcGxheSgpIGNhbGxzIG9uIHRoZSB2aWRlbyBlbGVtZW50LlxuICBkb2N1bWVudC5ib2R5LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3RvdWNoZW5kJywgb25WaWRlb1RhcCk7XG59XG5cbmZ1bmN0aW9uIG9uUmVuZGVyTG9hZChldmVudCkge1xuICBpZiAoZXZlbnQudmlkZW9FbGVtZW50KSB7XG4gICAgLy8gT24gbW9iaWxlLCB0ZWxsIHRoZSB1c2VyIHRoZXkgbmVlZCB0byB0YXAgdG8gc3RhcnQuIE90aGVyd2lzZSwgYXV0b3BsYXkuXG4gICAgaWYgKFV0aWwuaXNNb2JpbGUoKSkge1xuICAgICAgLy8gVGVsbCB1c2VyIHRvIHRhcCB0byBzdGFydC5cbiAgICAgIHNob3dQbGF5QnV0dG9uKCk7XG4gICAgICBkb2N1bWVudC5ib2R5LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNoZW5kJywgb25WaWRlb1RhcCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGV2ZW50LnZpZGVvRWxlbWVudC5wbGF5KCk7XG4gICAgfVxuXG4gICAgLy8gQXR0YWNoIHRvIHBhdXNlIGFuZCBwbGF5IGV2ZW50cywgdG8gbm90aWZ5IHRoZSBBUEkuXG4gICAgZXZlbnQudmlkZW9FbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3BhdXNlJywgb25QYXVzZSk7XG4gICAgZXZlbnQudmlkZW9FbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3BsYXknLCBvblBsYXkpO1xuICB9XG4gIC8vIEhpZGUgbG9hZGluZyBpbmRpY2F0b3IuXG4gIGxvYWRJbmRpY2F0b3IuaGlkZSgpO1xuXG4gIC8vIEF1dG9wYW4gb25seSBvbiBkZXNrdG9wLCBmb3IgcGhvdG9zIG9ubHksIGFuZCBvbmx5IGlmIGF1dG9wYW4gaXMgZW5hYmxlZC5cbiAgaWYgKCFVdGlsLmlzTW9iaWxlKCkgJiYgIXdvcmxkUmVuZGVyZXIuc2NlbmVJbmZvLnZpZGVvICYmXG4gICAgICAhd29ybGRSZW5kZXJlci5zY2VuZUluZm8uaXNBdXRvcGFuT2ZmKSB7XG4gICAgd29ybGRSZW5kZXJlci5hdXRvcGFuKCk7XG4gIH1cblxuICAvLyBOb3RpZnkgdGhlIEFQSSB0aGF0IHdlIGFyZSByZWFkeSwgYnV0IG9ubHkgZG8gdGhpcyBvbmNlLlxuICBpZiAoIWlzUmVhZHlTZW50KSB7XG4gICAgVXRpbC5zZW5kUGFyZW50TWVzc2FnZSh7XG4gICAgICB0eXBlOiAncmVhZHknXG4gICAgfSk7XG4gICAgaXNSZWFkeVNlbnQgPSB0cnVlO1xuICB9XG59XG5cbmZ1bmN0aW9uIG9uUGxheVJlcXVlc3QoKSB7XG4gIGlmICghd29ybGRSZW5kZXJlci52aWRlb1Byb3h5KSB7XG4gICAgb25BcGlFcnJvcignQXR0ZW1wdCB0byBwYXVzZSwgYnV0IG5vIHZpZGVvIGZvdW5kLicpO1xuICAgIHJldHVybjtcbiAgfVxuICB3b3JsZFJlbmRlcmVyLnZpZGVvUHJveHkucGxheSgpO1xufVxuXG5mdW5jdGlvbiBvblBhdXNlUmVxdWVzdCgpIHtcbiAgaWYgKCF3b3JsZFJlbmRlcmVyLnZpZGVvUHJveHkpIHtcbiAgICBvbkFwaUVycm9yKCdBdHRlbXB0IHRvIHBhdXNlLCBidXQgbm8gdmlkZW8gZm91bmQuJyk7XG4gICAgcmV0dXJuO1xuICB9XG4gIHdvcmxkUmVuZGVyZXIudmlkZW9Qcm94eS5wYXVzZSgpO1xufVxuXG5mdW5jdGlvbiBvbkFkZEhvdHNwb3QoZSkge1xuICBpZiAoVXRpbC5pc0RlYnVnKCkpIHtcbiAgICBjb25zb2xlLmxvZygnb25BZGRIb3RzcG90JywgZSk7XG4gIH1cbiAgLy8gVE9ETzogSW1wbGVtZW50IHNvbWUgdmFsaWRhdGlvbj9cblxuICB2YXIgcGl0Y2ggPSBwYXJzZUZsb2F0KGUucGl0Y2gpO1xuICB2YXIgeWF3ID0gcGFyc2VGbG9hdChlLnlhdyk7XG4gIHZhciByYWRpdXMgPSBwYXJzZUZsb2F0KGUucmFkaXVzKTtcbiAgdmFyIGRpc3RhbmNlID0gcGFyc2VGbG9hdChlLmRpc3RhbmNlKTtcbiAgdmFyIGlkID0gZS5pZDtcbiAgd29ybGRSZW5kZXJlci5ob3RzcG90UmVuZGVyZXIuYWRkKHBpdGNoLCB5YXcsIHJhZGl1cywgZGlzdGFuY2UsIGlkKTtcbn1cblxuZnVuY3Rpb24gb25TZXRDb250ZW50KGUpIHtcbiAgaWYgKFV0aWwuaXNEZWJ1ZygpKSB7XG4gICAgY29uc29sZS5sb2coJ29uU2V0Q29udGVudCcsIGUpO1xuICB9XG4gIC8vIFJlbW92ZSBhbGwgb2YgdGhlIGhvdHNwb3RzLlxuICB3b3JsZFJlbmRlcmVyLmhvdHNwb3RSZW5kZXJlci5jbGVhckFsbCgpO1xuICAvLyBGYWRlIHRvIGJsYWNrLlxuICB3b3JsZFJlbmRlcmVyLnNwaGVyZVJlbmRlcmVyLnNldE9wYWNpdHkoMCwgNTAwKS50aGVuKGZ1bmN0aW9uKCkge1xuICAgIC8vIFRoZW4gbG9hZCB0aGUgbmV3IHNjZW5lLlxuICAgIHZhciBzY2VuZSA9IFNjZW5lSW5mby5sb2FkRnJvbUFQSVBhcmFtcyhlLmNvbnRlbnRJbmZvKTtcbiAgICB3b3JsZFJlbmRlcmVyLmRlc3Ryb3koKTtcblxuICAgIC8vIFVwZGF0ZSB0aGUgVVJMIHRvIHJlZmxlY3QgdGhlIG5ldyBzY2VuZS4gVGhpcyBpcyBpbXBvcnRhbnQgcGFydGljdWxhcmlseVxuICAgIC8vIG9uIGlPUyB3aGVyZSB3ZSB1c2UgYSBmYWtlIGZ1bGxzY3JlZW4gbW9kZS5cbiAgICB2YXIgdXJsID0gc2NlbmUuZ2V0Q3VycmVudFVybCgpO1xuICAgIC8vY29uc29sZS5sb2coJ1VwZGF0aW5nIHVybCB0byBiZSAlcycsIHVybCk7XG4gICAgd2luZG93Lmhpc3RvcnkucHVzaFN0YXRlKG51bGwsICdWUiBWaWV3JywgdXJsKTtcblxuICAgIC8vIEFuZCBzZXQgdGhlIG5ldyBzY2VuZS5cbiAgICByZXR1cm4gd29ybGRSZW5kZXJlci5zZXRTY2VuZShzY2VuZSk7XG4gIH0pLnRoZW4oZnVuY3Rpb24oKSB7XG4gICAgLy8gVGhlbiBmYWRlIHRoZSBzY2VuZSBiYWNrIGluLlxuICAgIHdvcmxkUmVuZGVyZXIuc3BoZXJlUmVuZGVyZXIuc2V0T3BhY2l0eSgxLCA1MDApO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gb25TZXRWb2x1bWUoZSkge1xuICAvLyBPbmx5IHdvcmsgZm9yIHZpZGVvLiBJZiB0aGVyZSdzIG5vIHZpZGVvLCBzZW5kIGJhY2sgYW4gZXJyb3IuXG4gIGlmICghd29ybGRSZW5kZXJlci52aWRlb1Byb3h5KSB7XG4gICAgb25BcGlFcnJvcignQXR0ZW1wdCB0byBzZXQgdm9sdW1lLCBidXQgbm8gdmlkZW8gZm91bmQuJyk7XG4gICAgcmV0dXJuO1xuICB9XG4gIHdvcmxkUmVuZGVyZXIudmlkZW9Qcm94eS5zZXRWb2x1bWUoZS52b2x1bWVMZXZlbCk7XG59XG5cbmZ1bmN0aW9uIG9uQXBpRXJyb3IobWVzc2FnZSkge1xuICBjb25zb2xlLmVycm9yKG1lc3NhZ2UpO1xuICBVdGlsLnNlbmRQYXJlbnRNZXNzYWdlKHtcbiAgICB0eXBlOiAnZXJyb3InLFxuICAgIGRhdGE6IHttZXNzYWdlOiBtZXNzYWdlfVxuICB9KTtcbn1cblxuZnVuY3Rpb24gb25Nb2RlQ2hhbmdlKG1vZGUpIHtcbiAgVXRpbC5zZW5kUGFyZW50TWVzc2FnZSh7XG4gICAgdHlwZTogJ21vZGVjaGFuZ2UnLFxuICAgIGRhdGE6IHttb2RlOiBtb2RlfVxuICB9KTtcbn1cblxuZnVuY3Rpb24gb25Ib3RzcG90Q2xpY2soaWQpIHtcbiAgVXRpbC5zZW5kUGFyZW50TWVzc2FnZSh7XG4gICAgdHlwZTogJ2NsaWNrJyxcbiAgICBkYXRhOiB7aWQ6IGlkfVxuICB9KTtcbn1cblxuZnVuY3Rpb24gb25QbGF5KCkge1xuICBVdGlsLnNlbmRQYXJlbnRNZXNzYWdlKHtcbiAgICB0eXBlOiAncGF1c2VkJyxcbiAgICBkYXRhOiBmYWxzZVxuICB9KTtcbn1cblxuZnVuY3Rpb24gb25QYXVzZSgpIHtcbiAgVXRpbC5zZW5kUGFyZW50TWVzc2FnZSh7XG4gICAgdHlwZTogJ3BhdXNlZCcsXG4gICAgZGF0YTogdHJ1ZVxuICB9KTtcbn1cblxuZnVuY3Rpb24gb25TY2VuZUVycm9yKG1lc3NhZ2UpIHtcbiAgc2hvd0Vycm9yKCdMb2FkZXI6ICcgKyBtZXNzYWdlKTtcbn1cblxuZnVuY3Rpb24gb25SZW5kZXJFcnJvcihtZXNzYWdlKSB7XG4gIHNob3dFcnJvcignUmVuZGVyOiAnICsgbWVzc2FnZSk7XG59XG5cbmZ1bmN0aW9uIHNob3dFcnJvcihtZXNzYWdlLCBvcHRfdGl0bGUpIHtcbiAgLy8gSGlkZSBsb2FkaW5nIGluZGljYXRvci5cbiAgbG9hZEluZGljYXRvci5oaWRlKCk7XG5cbiAgdmFyIGVycm9yID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2Vycm9yJyk7XG4gIGVycm9yLmNsYXNzTGlzdC5hZGQoJ3Zpc2libGUnKTtcbiAgZXJyb3IucXVlcnlTZWxlY3RvcignLm1lc3NhZ2UnKS5pbm5lckhUTUwgPSBtZXNzYWdlO1xuXG4gIHZhciB0aXRsZSA9IChvcHRfdGl0bGUgIT09IHVuZGVmaW5lZCA/IG9wdF90aXRsZSA6ICdFcnJvcicpO1xuICBlcnJvci5xdWVyeVNlbGVjdG9yKCcudGl0bGUnKS5pbm5lckhUTUwgPSB0aXRsZTtcbn1cblxuZnVuY3Rpb24gaGlkZUVycm9yKCkge1xuICB2YXIgZXJyb3IgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjZXJyb3InKTtcbiAgZXJyb3IuY2xhc3NMaXN0LnJlbW92ZSgndmlzaWJsZScpO1xufVxuXG5mdW5jdGlvbiBzaG93UGxheUJ1dHRvbigpIHtcbiAgdmFyIHBsYXlCdXR0b24gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjcGxheS1vdmVybGF5Jyk7XG4gIHBsYXlCdXR0b24uY2xhc3NMaXN0LmFkZCgndmlzaWJsZScpO1xufVxuXG5mdW5jdGlvbiBoaWRlUGxheUJ1dHRvbigpIHtcbiAgdmFyIHBsYXlCdXR0b24gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjcGxheS1vdmVybGF5Jyk7XG4gIHBsYXlCdXR0b24uY2xhc3NMaXN0LnJlbW92ZSgndmlzaWJsZScpO1xufVxuXG5mdW5jdGlvbiBzaG93U3RhdHMoKSB7XG4gIHN0YXRzLnNldE1vZGUoMCk7IC8vIDA6IGZwcywgMTogbXNcblxuICAvLyBBbGlnbiBib3R0b20tbGVmdC5cbiAgc3RhdHMuZG9tRWxlbWVudC5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7XG4gIHN0YXRzLmRvbUVsZW1lbnQuc3R5bGUubGVmdCA9ICcwcHgnO1xuICBzdGF0cy5kb21FbGVtZW50LnN0eWxlLmJvdHRvbSA9ICcwcHgnO1xuICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHN0YXRzLmRvbUVsZW1lbnQpO1xufVxuXG5mdW5jdGlvbiBsb29wKHRpbWUpIHtcbiAgLy8gVXNlIHRoZSBWUkRpc3BsYXkgUkFGIGlmIGl0IGlzIHByZXNlbnQuXG4gIGlmICh3b3JsZFJlbmRlcmVyLnZyRGlzcGxheSkge1xuICAgIHdvcmxkUmVuZGVyZXIudnJEaXNwbGF5LnJlcXVlc3RBbmltYXRpb25GcmFtZShsb29wKTtcbiAgfSBlbHNlIHtcbiAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUobG9vcCk7XG4gIH1cblxuICBzdGF0cy5iZWdpbigpO1xuICAvLyBVcGRhdGUgdGhlIHZpZGVvIGlmIG5lZWRlZC5cbiAgaWYgKHdvcmxkUmVuZGVyZXIudmlkZW9Qcm94eSkge1xuICAgIHdvcmxkUmVuZGVyZXIudmlkZW9Qcm94eS51cGRhdGUodGltZSk7XG4gIH1cbiAgd29ybGRSZW5kZXJlci5yZW5kZXIodGltZSk7XG4gIHdvcmxkUmVuZGVyZXIuc3VibWl0RnJhbWUoKTtcbiAgc3RhdHMuZW5kKCk7XG59XG4iLCIvKlxuICogQ29weXJpZ2h0IDIwMTYgR29vZ2xlIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuXG5mdW5jdGlvbiBSZXRpY2xlUmVuZGVyZXIoY2FtZXJhKSB7XG4gIHRoaXMuY2FtZXJhID0gY2FtZXJhO1xuXG4gIHRoaXMucmV0aWNsZSA9IHRoaXMuY3JlYXRlUmV0aWNsZV8oKTtcbiAgLy8gSW4gZnJvbnQgb2YgdGhlIGhvdHNwb3QgaXRzZWxmLCB3aGljaCBpcyBhdCByPTAuOTkuXG4gIHRoaXMucmV0aWNsZS5wb3NpdGlvbi56ID0gLTAuOTc7XG4gIGNhbWVyYS5hZGQodGhpcy5yZXRpY2xlKTtcblxuICB0aGlzLnNldFZpc2liaWxpdHkoZmFsc2UpO1xufVxuXG5SZXRpY2xlUmVuZGVyZXIucHJvdG90eXBlLnNldFZpc2liaWxpdHkgPSBmdW5jdGlvbihpc1Zpc2libGUpIHtcbiAgLy8gVE9ETzogVHdlZW4gdGhlIHRyYW5zaXRpb24uXG4gIHRoaXMucmV0aWNsZS52aXNpYmxlID0gaXNWaXNpYmxlO1xufTtcblxuUmV0aWNsZVJlbmRlcmVyLnByb3RvdHlwZS5jcmVhdGVSZXRpY2xlXyA9IGZ1bmN0aW9uKCkge1xuICAvLyBNYWtlIGEgdG9ydXMuXG4gIHZhciBnZW9tZXRyeSA9IG5ldyBUSFJFRS5Ub3J1c0dlb21ldHJ5KDAuMDIsIDAuMDA1LCAxMCwgMjApO1xuICB2YXIgbWF0ZXJpYWwgPSBuZXcgVEhSRUUuTWVzaEJhc2ljTWF0ZXJpYWwoe2NvbG9yOiAweDAwMDAwMH0pO1xuICB2YXIgdG9ydXMgPSBuZXcgVEhSRUUuTWVzaChnZW9tZXRyeSwgbWF0ZXJpYWwpO1xuXG4gIHJldHVybiB0b3J1cztcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gUmV0aWNsZVJlbmRlcmVyO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDE2IEdvb2dsZSBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxudmFyIENBTUVMX1RPX1VOREVSU0NPUkUgPSB7XG4gIHZpZGVvOiAndmlkZW8nLFxuICBpbWFnZTogJ2ltYWdlJyxcbiAgcHJldmlldzogJ3ByZXZpZXcnLFxuICBpc1N0ZXJlbzogJ2lzX3N0ZXJlbycsXG4gIGRlZmF1bHRZYXc6ICdkZWZhdWx0X3lhdycsXG4gIGlzWWF3T25seTogJ2lzX3lhd19vbmx5JyxcbiAgaXNEZWJ1ZzogJ2lzX2RlYnVnJyxcbiAgaXNWUk9mZjogJ2lzX3ZyX29mZicsXG4gIGlzQXV0b3Bhbk9mZjogJ2lzX2F1dG9wYW5fb2ZmJyxcbn07XG5cbi8qKlxuICogQ29udGFpbnMgYWxsIGluZm9ybWF0aW9uIGFib3V0IGEgZ2l2ZW4gc2NlbmUuXG4gKi9cbmZ1bmN0aW9uIFNjZW5lSW5mbyhvcHRfcGFyYW1zKSB7XG4gIHZhciBwYXJhbXMgPSBvcHRfcGFyYW1zIHx8IHt9O1xuXG4gIHRoaXMuaW1hZ2UgPSBwYXJhbXMuaW1hZ2U7XG4gIHRoaXMucHJldmlldyA9IHBhcmFtcy5wcmV2aWV3O1xuICB0aGlzLnZpZGVvID0gcGFyYW1zLnZpZGVvO1xuICB0aGlzLmRlZmF1bHRZYXcgPSBUSFJFRS5NYXRoLmRlZ1RvUmFkKHBhcmFtcy5kZWZhdWx0WWF3IHx8IDApO1xuXG4gIHRoaXMuaXNTdGVyZW8gPSBVdGlsLnBhcnNlQm9vbGVhbihwYXJhbXMuaXNTdGVyZW8pO1xuICB0aGlzLmlzWWF3T25seSA9IFV0aWwucGFyc2VCb29sZWFuKHBhcmFtcy5pc1lhd09ubHkpO1xuICB0aGlzLmlzRGVidWcgPSBVdGlsLnBhcnNlQm9vbGVhbihwYXJhbXMuaXNEZWJ1Zyk7XG4gIHRoaXMuaXNWUk9mZiA9IFV0aWwucGFyc2VCb29sZWFuKHBhcmFtcy5pc1ZST2ZmKTtcbiAgdGhpcy5pc0F1dG9wYW5PZmYgPSBVdGlsLnBhcnNlQm9vbGVhbihwYXJhbXMuaXNBdXRvcGFuT2ZmKTtcbn1cblxuU2NlbmVJbmZvLmxvYWRGcm9tR2V0UGFyYW1zID0gZnVuY3Rpb24oKSB7XG4gIHZhciBwYXJhbXMgPSB7fTtcbiAgZm9yICh2YXIgY2FtZWxDYXNlIGluIENBTUVMX1RPX1VOREVSU0NPUkUpIHtcbiAgICB2YXIgdW5kZXJzY29yZSA9IENBTUVMX1RPX1VOREVSU0NPUkVbY2FtZWxDYXNlXTtcbiAgICBwYXJhbXNbY2FtZWxDYXNlXSA9IFV0aWwuZ2V0UXVlcnlQYXJhbWV0ZXIodW5kZXJzY29yZSk7XG4gIH1cbiAgdmFyIHNjZW5lID0gbmV3IFNjZW5lSW5mbyhwYXJhbXMpO1xuICBpZiAoIXNjZW5lLmlzVmFsaWQoKSkge1xuICAgIGNvbnNvbGUud2FybignSW52YWxpZCBzY2VuZTogJXMnLCBzY2VuZS5lcnJvck1lc3NhZ2UpO1xuICB9XG4gIHJldHVybiBzY2VuZTtcbn07XG5cblNjZW5lSW5mby5sb2FkRnJvbUFQSVBhcmFtcyA9IGZ1bmN0aW9uKHVuZGVyc2NvcmVQYXJhbXMpIHtcbiAgdmFyIHBhcmFtcyA9IHt9O1xuICBmb3IgKHZhciBjYW1lbENhc2UgaW4gQ0FNRUxfVE9fVU5ERVJTQ09SRSkge1xuICAgIHZhciB1bmRlcnNjb3JlID0gQ0FNRUxfVE9fVU5ERVJTQ09SRVtjYW1lbENhc2VdO1xuICAgIGlmICh1bmRlcnNjb3JlUGFyYW1zW3VuZGVyc2NvcmVdKSB7XG4gICAgICBwYXJhbXNbY2FtZWxDYXNlXSA9IHVuZGVyc2NvcmVQYXJhbXNbdW5kZXJzY29yZV07XG4gICAgfVxuICB9XG4gIHZhciBzY2VuZSA9IG5ldyBTY2VuZUluZm8ocGFyYW1zKTtcbiAgaWYgKCFzY2VuZS5pc1ZhbGlkKCkpIHtcbiAgICBjb25zb2xlLndhcm4oJ0ludmFsaWQgc2NlbmU6ICVzJywgc2NlbmUuZXJyb3JNZXNzYWdlKTtcbiAgfVxuICByZXR1cm4gc2NlbmU7XG59O1xuXG5TY2VuZUluZm8ucHJvdG90eXBlLmlzVmFsaWQgPSBmdW5jdGlvbigpIHtcbiAgLy8gRWl0aGVyIGl0J3MgYW4gaW1hZ2Ugb3IgYSB2aWRlby5cbiAgaWYgKCF0aGlzLmltYWdlICYmICF0aGlzLnZpZGVvKSB7XG4gICAgdGhpcy5lcnJvck1lc3NhZ2UgPSAnRWl0aGVyIGltYWdlIG9yIHZpZGVvIFVSTCBtdXN0IGJlIHNwZWNpZmllZC4nO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAodGhpcy5pbWFnZSAmJiB0aGlzLnZpZGVvKSB7XG4gICAgdGhpcy5lcnJvck1lc3NhZ2UgPSAnQm90aCBpbWFnZSBhbmQgdmlkZW8gVVJMIGNhblxcJ3QgYmUgc3BlY2lmaWVkLic7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmICh0aGlzLmltYWdlICYmICF0aGlzLmlzVmFsaWRJbWFnZV8odGhpcy5pbWFnZSkpIHtcbiAgICB0aGlzLmVycm9yTWVzc2FnZSA9ICdJbnZhbGlkIGltYWdlIFVSTDogJyArIHRoaXMuaW1hZ2U7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHRoaXMuZXJyb3JNZXNzYWdlID0gbnVsbDtcbiAgcmV0dXJuIHRydWU7XG59O1xuXG4vKipcbiAqIEdlbmVyYXRlcyBhIFVSTCB0byByZWZsZWN0IHRoaXMgc2NlbmUuXG4gKi9cblNjZW5lSW5mby5wcm90b3R5cGUuZ2V0Q3VycmVudFVybCA9IGZ1bmN0aW9uKCkge1xuICB2YXIgdXJsID0gbG9jYXRpb24ucHJvdG9jb2wgKyAnLy8nICsgbG9jYXRpb24uaG9zdCArIGxvY2F0aW9uLnBhdGhuYW1lICsgJz8nO1xuICBmb3IgKHZhciBjYW1lbENhc2UgaW4gQ0FNRUxfVE9fVU5ERVJTQ09SRSkge1xuICAgIHZhciB1bmRlcnNjb3JlID0gQ0FNRUxfVE9fVU5ERVJTQ09SRVtjYW1lbENhc2VdO1xuICAgIHZhciB2YWx1ZSA9IHRoaXNbY2FtZWxDYXNlXTtcbiAgICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdXJsICs9IHVuZGVyc2NvcmUgKyAnPScgKyB2YWx1ZSArICcmJztcbiAgICB9XG4gIH1cbiAgLy8gQ2hvcCBvZmYgdGhlIHRyYWlsaW5nIGFtcGVyc2FuZC5cbiAgcmV0dXJuIHVybC5zdWJzdHJpbmcoMCwgdXJsLmxlbmd0aCAtIDEpO1xufTtcblxuU2NlbmVJbmZvLnByb3RvdHlwZS5pc1ZhbGlkSW1hZ2VfID0gZnVuY3Rpb24oaW1hZ2VVcmwpIHtcbiAgcmV0dXJuIHRydWU7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFNjZW5lSW5mbztcbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAxNiBHb29nbGUgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cbnZhciBFeWVzID0gcmVxdWlyZSgnLi9leWVzJyk7XG52YXIgVFdFRU4gPSByZXF1aXJlKCd0d2Vlbi5qcycpO1xudmFyIFV0aWwgPSByZXF1aXJlKCcuLi91dGlsJyk7XG5cbmZ1bmN0aW9uIFNwaGVyZVJlbmRlcmVyKHNjZW5lKSB7XG4gIHRoaXMuc2NlbmUgPSBzY2VuZTtcblxuICAvLyBDcmVhdGUgYSB0cmFuc3BhcmVudCBtYXNrLlxuICB0aGlzLmNyZWF0ZU9wYWNpdHlNYXNrXygpO1xufVxuXG4vKipcbiAqIFNldHMgdGhlIHBob3Rvc3BoZXJlIGJhc2VkIG9uIHRoZSBpbWFnZSBpbiB0aGUgc291cmNlLiBTdXBwb3J0cyBzdGVyZW8gYW5kXG4gKiBtb25vIHBob3Rvc3BoZXJlcy5cbiAqXG4gKiBAcmV0dXJuIHtQcm9taXNlfVxuICovXG5TcGhlcmVSZW5kZXJlci5wcm90b3R5cGUuc2V0UGhvdG9zcGhlcmUgPSBmdW5jdGlvbihzcmMsIG9wdF9wYXJhbXMpIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuICAgIHRoaXMucmVzb2x2ZSA9IHJlc29sdmU7XG4gICAgdGhpcy5yZWplY3QgPSByZWplY3Q7XG5cbiAgICB2YXIgcGFyYW1zID0gb3B0X3BhcmFtcyB8fCB7fTtcblxuICAgIHRoaXMuaXNTdGVyZW8gPSAhIXBhcmFtcy5pc1N0ZXJlbztcbiAgICB0aGlzLnNyYyA9IHNyYztcblxuICAgIC8vIExvYWQgdGV4dHVyZS5cbiAgICB2YXIgbG9hZGVyID0gbmV3IFRIUkVFLlRleHR1cmVMb2FkZXIoKTtcbiAgICBsb2FkZXIuY3Jvc3NPcmlnaW4gPSAnYW5vbnltb3VzJztcbiAgICBsb2FkZXIubG9hZChzcmMsIHRoaXMub25UZXh0dXJlTG9hZGVkXy5iaW5kKHRoaXMpLCB1bmRlZmluZWQsXG4gICAgICAgICAgICAgICAgdGhpcy5vblRleHR1cmVFcnJvcl8uYmluZCh0aGlzKSk7XG4gIH0uYmluZCh0aGlzKSk7XG59O1xuXG4vKipcbiAqIEByZXR1cm4ge1Byb21pc2V9IFllYWguXG4gKi9cblNwaGVyZVJlbmRlcmVyLnByb3RvdHlwZS5zZXQzNjBWaWRlbyA9IGZ1bmN0aW9uKHZpZGVvRWxlbWVudCwgb3B0X3BhcmFtcykge1xuICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KSB7XG4gICAgdGhpcy5yZXNvbHZlID0gcmVzb2x2ZTtcbiAgICB0aGlzLnJlamVjdCA9IHJlamVjdDtcblxuICAgIHZhciBwYXJhbXMgPSBvcHRfcGFyYW1zIHx8IHt9O1xuXG4gICAgdGhpcy5pc1N0ZXJlbyA9ICEhcGFyYW1zLmlzU3RlcmVvO1xuXG4gICAgLy8gTG9hZCB0aGUgdmlkZW8gdGV4dHVyZS5cbiAgICB2YXIgdmlkZW9UZXh0dXJlID0gbmV3IFRIUkVFLlZpZGVvVGV4dHVyZSh2aWRlb0VsZW1lbnQpO1xuICAgIHZpZGVvVGV4dHVyZS5taW5GaWx0ZXIgPSBUSFJFRS5MaW5lYXJGaWx0ZXI7XG4gICAgdmlkZW9UZXh0dXJlLm1hZ0ZpbHRlciA9IFRIUkVFLkxpbmVhckZpbHRlcjtcbiAgICB2aWRlb1RleHR1cmUuZm9ybWF0ID0gVEhSRUUuUkdCRm9ybWF0O1xuICAgIHZpZGVvVGV4dHVyZS5nZW5lcmF0ZU1pcG1hcHMgPSBmYWxzZTtcbiAgICB2aWRlb1RleHR1cmUubmVlZHNVcGRhdGUgPSB0cnVlO1xuXG4gICAgdGhpcy5vblRleHR1cmVMb2FkZWRfKHZpZGVvVGV4dHVyZSk7XG4gIH0uYmluZCh0aGlzKSk7XG59O1xuXG4vKipcbiAqIFNldCB0aGUgb3BhY2l0eSBvZiB0aGUgcGFub3JhbWEuXG4gKlxuICogQHBhcmFtIHtOdW1iZXJ9IG9wYWNpdHkgSG93IG9wYXF1ZSB3ZSB3YW50IHRoZSBwYW5vcmFtYSB0byBiZS4gMCBtZWFucyBibGFjayxcbiAqIDEgbWVhbnMgZnVsbCBjb2xvci5cbiAqIEBwYXJhbSB7TnVtYmVyfSBkdXJhdGlvbiBOdW1iZXIgb2YgbWlsbGlzZWNvbmRzIHRoZSB0cmFuc2l0aW9uIHNob3VsZCB0YWtlLlxuICpcbiAqIEByZXR1cm4ge1Byb21pc2V9IFdoZW4gdGhlIG9wYWNpdHkgY2hhbmdlIGlzIGNvbXBsZXRlLlxuICovXG5TcGhlcmVSZW5kZXJlci5wcm90b3R5cGUuc2V0T3BhY2l0eSA9IGZ1bmN0aW9uKG9wYWNpdHksIGR1cmF0aW9uKSB7XG4gIHZhciBzY2VuZSA9IHRoaXMuc2NlbmU7XG4gIC8vIElmIHdlIHdhbnQgdGhlIG9wYWNpdHlcbiAgdmFyIG92ZXJsYXlPcGFjaXR5ID0gMSAtIG9wYWNpdHk7XG4gIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICB2YXIgbWFzayA9IHNjZW5lLmdldE9iamVjdEJ5TmFtZSgnb3BhY2l0eU1hc2snKTtcbiAgICB2YXIgdHdlZW4gPSBuZXcgVFdFRU4uVHdlZW4oe29wYWNpdHk6IG1hc2subWF0ZXJpYWwub3BhY2l0eX0pXG4gICAgICAgIC50byh7b3BhY2l0eTogb3ZlcmxheU9wYWNpdHl9LCBkdXJhdGlvbilcbiAgICAgICAgLmVhc2luZyhUV0VFTi5FYXNpbmcuUXVhZHJhdGljLkluT3V0KTtcbiAgICB0d2Vlbi5vblVwZGF0ZShmdW5jdGlvbihlKSB7XG4gICAgICBtYXNrLm1hdGVyaWFsLm9wYWNpdHkgPSB0aGlzLm9wYWNpdHk7XG4gICAgfSk7XG4gICAgdHdlZW4ub25Db21wbGV0ZShyZXNvbHZlKS5zdGFydCgpO1xuICB9KTtcbn07XG5cblNwaGVyZVJlbmRlcmVyLnByb3RvdHlwZS5vblRleHR1cmVMb2FkZWRfID0gZnVuY3Rpb24odGV4dHVyZSkge1xuICB2YXIgc3BoZXJlTGVmdDtcbiAgdmFyIHNwaGVyZVJpZ2h0O1xuICBpZiAodGhpcy5pc1N0ZXJlbykge1xuICAgIHNwaGVyZUxlZnQgPSB0aGlzLmNyZWF0ZVBob3Rvc3BoZXJlXyh0ZXh0dXJlLCB7b2Zmc2V0WTogMC41LCBzY2FsZVk6IDAuNX0pO1xuICAgIHNwaGVyZVJpZ2h0ID0gdGhpcy5jcmVhdGVQaG90b3NwaGVyZV8odGV4dHVyZSwge29mZnNldFk6IDAsIHNjYWxlWTogMC41fSk7XG4gIH0gZWxzZSB7XG4gICAgc3BoZXJlTGVmdCA9IHRoaXMuY3JlYXRlUGhvdG9zcGhlcmVfKHRleHR1cmUpO1xuICAgIHNwaGVyZVJpZ2h0ID0gdGhpcy5jcmVhdGVQaG90b3NwaGVyZV8odGV4dHVyZSk7XG4gIH1cblxuICAvLyBEaXNwbGF5IGluIGxlZnQgYW5kIHJpZ2h0IGV5ZSByZXNwZWN0aXZlbHkuXG4gIHNwaGVyZUxlZnQubGF5ZXJzLnNldChFeWVzLkxFRlQpO1xuICBzcGhlcmVMZWZ0LmV5ZSA9IEV5ZXMuTEVGVDtcbiAgc3BoZXJlUmlnaHQubGF5ZXJzLnNldChFeWVzLlJJR0hUKTtcbiAgc3BoZXJlUmlnaHQuZXllID0gRXllcy5SSUdIVDtcblxuICB0aGlzLnNjZW5lLmdldE9iamVjdEJ5TmFtZSgncGhvdG8nKS5jaGlsZHJlbiA9IFtzcGhlcmVMZWZ0LCBzcGhlcmVSaWdodF07XG5cbiAgdGhpcy5yZXNvbHZlKCk7XG59O1xuXG5TcGhlcmVSZW5kZXJlci5wcm90b3R5cGUub25UZXh0dXJlRXJyb3JfID0gZnVuY3Rpb24oZXJyb3IpIHtcbiAgdGhpcy5yZWplY3QoJ1VuYWJsZSB0byBsb2FkIHRleHR1cmUgZnJvbSBcIicgKyB0aGlzLnNyYyArICdcIicpO1xufTtcblxuXG5TcGhlcmVSZW5kZXJlci5wcm90b3R5cGUuY3JlYXRlUGhvdG9zcGhlcmVfID0gZnVuY3Rpb24odGV4dHVyZSwgb3B0X3BhcmFtcykge1xuICB2YXIgcCA9IG9wdF9wYXJhbXMgfHwge307XG4gIHAuc2NhbGVYID0gcC5zY2FsZVggfHwgMTtcbiAgcC5zY2FsZVkgPSBwLnNjYWxlWSB8fCAxO1xuICBwLm9mZnNldFggPSBwLm9mZnNldFggfHwgMDtcbiAgcC5vZmZzZXRZID0gcC5vZmZzZXRZIHx8IDA7XG4gIHAucGhpU3RhcnQgPSBwLnBoaVN0YXJ0IHx8IDA7XG4gIHAucGhpTGVuZ3RoID0gcC5waGlMZW5ndGggfHwgTWF0aC5QSSAqIDI7XG4gIHAudGhldGFTdGFydCA9IHAudGhldGFTdGFydCB8fCAwO1xuICBwLnRoZXRhTGVuZ3RoID0gcC50aGV0YUxlbmd0aCB8fCBNYXRoLlBJO1xuXG4gIHZhciBnZW9tZXRyeSA9IG5ldyBUSFJFRS5TcGhlcmVHZW9tZXRyeSgxLCA0OCwgNDgsXG4gICAgICBwLnBoaVN0YXJ0LCBwLnBoaUxlbmd0aCwgcC50aGV0YVN0YXJ0LCBwLnRoZXRhTGVuZ3RoKTtcbiAgZ2VvbWV0cnkuYXBwbHlNYXRyaXgobmV3IFRIUkVFLk1hdHJpeDQoKS5tYWtlU2NhbGUoLTEsIDEsIDEpKTtcbiAgdmFyIHV2cyA9IGdlb21ldHJ5LmZhY2VWZXJ0ZXhVdnNbMF07XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgdXZzLmxlbmd0aDsgaSArKykge1xuICAgIGZvciAodmFyIGogPSAwOyBqIDwgMzsgaiArKykge1xuICAgICAgdXZzW2ldW2pdLnggKj0gcC5zY2FsZVg7XG4gICAgICB1dnNbaV1bal0ueCArPSBwLm9mZnNldFg7XG4gICAgICB1dnNbaV1bal0ueSAqPSBwLnNjYWxlWTtcbiAgICAgIHV2c1tpXVtqXS55ICs9IHAub2Zmc2V0WTtcbiAgICB9XG4gIH1cblxuICB2YXIgbWF0ZXJpYWwgPSBuZXcgVEhSRUUuTWVzaEJhc2ljTWF0ZXJpYWwoeyBtYXA6IHRleHR1cmUgfSk7XG4gIHZhciBvdXQgPSBuZXcgVEhSRUUuTWVzaChnZW9tZXRyeSwgbWF0ZXJpYWwpO1xuICAvL291dC52aXNpYmxlID0gZmFsc2U7XG4gIG91dC5yZW5kZXJPcmRlciA9IC0xO1xuICByZXR1cm4gb3V0O1xufTtcblxuU3BoZXJlUmVuZGVyZXIucHJvdG90eXBlLmNyZWF0ZU9wYWNpdHlNYXNrXyA9IGZ1bmN0aW9uKCkge1xuICB2YXIgZ2VvbWV0cnkgPSBuZXcgVEhSRUUuU3BoZXJlR2VvbWV0cnkoMC40OSwgNDgsIDQ4KTtcbiAgdmFyIG1hdGVyaWFsID0gbmV3IFRIUkVFLk1lc2hCYXNpY01hdGVyaWFsKHtcbiAgICBjb2xvcjogMHgwMDAwMDAsIHNpZGU6IFRIUkVFLkRvdWJsZVNpZGUsIG9wYWNpdHk6IDAsIHRyYW5zcGFyZW50OiB0cnVlfSk7XG4gIHZhciBvcGFjaXR5TWFzayA9IG5ldyBUSFJFRS5NZXNoKGdlb21ldHJ5LCBtYXRlcmlhbCk7XG4gIG9wYWNpdHlNYXNrLm5hbWUgPSAnb3BhY2l0eU1hc2snO1xuICBvcGFjaXR5TWFzay5yZW5kZXJPcmRlciA9IDE7XG5cbiAgdGhpcy5zY2VuZS5hZGQob3BhY2l0eU1hc2spO1xuICByZXR1cm4gb3BhY2l0eU1hc2s7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFNwaGVyZVJlbmRlcmVyO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDE2IEdvb2dsZSBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxudmFyIFV0aWwgPSByZXF1aXJlKCcuLi91dGlsJyk7XG5cbi8qKlxuICogQSBwcm94eSBjbGFzcyBmb3Igd29ya2luZyBhcm91bmQgdGhlIGZhY3QgdGhhdCBhcyBzb29uIGFzIGEgdmlkZW8gaXMgcGxheSgpZWRcbiAqIG9uIGlPUywgU2FmYXJpIGF1dG8tZnVsbHNjcmVlbnMgdGhlIHZpZGVvLlxuICpcbiAqIFRPRE8oc211cyk6IFRoZSBlbnRpcmUgcmFpc29uIGQnZXRyZSBmb3IgdGhpcyBjbGFzcyBpcyB0byB3b3JrIGFyb3VuZCB0aGlzXG4gKiBpc3N1ZS4gT25jZSBTYWZhcmkgaW1wbGVtZW50cyBzb21lIHdheSB0byBzdXBwcmVzcyB0aGlzIGZ1bGxzY3JlZW4gcGxheWVyLCB3ZVxuICogY2FuIHJlbW92ZSB0aGlzIGNvZGUuXG4gKi9cbmZ1bmN0aW9uIFZpZGVvUHJveHkodmlkZW9FbGVtZW50KSB7XG4gIHRoaXMudmlkZW9FbGVtZW50ID0gdmlkZW9FbGVtZW50O1xuICAvLyBUcnVlIGlmIHdlJ3JlIGN1cnJlbnRseSBtYW51YWxseSBhZHZhbmNpbmcgdGhlIHBsYXloZWFkIChvbmx5IG9uIGlPUykuXG4gIHRoaXMuaXNGYWtlUGxheWJhY2sgPSBmYWxzZTtcblxuICAvLyBXaGVuIHRoZSB2aWRlbyBzdGFydGVkIHBsYXlpbmcuXG4gIHRoaXMuc3RhcnRUaW1lID0gbnVsbDtcbn1cblxuVmlkZW9Qcm94eS5wcm90b3R5cGUucGxheSA9IGZ1bmN0aW9uKCkge1xuICBpZiAoVXRpbC5pc0lPUzlPckxlc3MoKSkge1xuICAgIHRoaXMuc3RhcnRUaW1lID0gcGVyZm9ybWFuY2Uubm93KCk7XG4gICAgdGhpcy5pc0Zha2VQbGF5YmFjayA9IHRydWU7XG5cbiAgICAvLyBNYWtlIGFuIGF1ZGlvIGVsZW1lbnQgdG8gcGxheWJhY2sganVzdCB0aGUgYXVkaW8gcGFydC5cbiAgICB0aGlzLmF1ZGlvRWxlbWVudCA9IG5ldyBBdWRpbygpO1xuICAgIHRoaXMuYXVkaW9FbGVtZW50LnNyYyA9IHRoaXMudmlkZW9FbGVtZW50LnNyYztcbiAgICB0aGlzLmF1ZGlvRWxlbWVudC5wbGF5KCk7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy52aWRlb0VsZW1lbnQucGxheSgpLnRoZW4oZnVuY3Rpb24oZSkge1xuICAgICAgY29uc29sZS5sb2coJ1BsYXlpbmcgdmlkZW8uJywgZSk7XG4gICAgfSk7XG4gIH1cbn07XG5cblZpZGVvUHJveHkucHJvdG90eXBlLnBhdXNlID0gZnVuY3Rpb24oKSB7XG4gIGlmIChVdGlsLmlzSU9TOU9yTGVzcygpICYmIHRoaXMuaXNGYWtlUGxheWJhY2spIHtcbiAgICB0aGlzLmlzRmFrZVBsYXliYWNrID0gdHJ1ZTtcblxuICAgIHRoaXMuYXVkaW9FbGVtZW50LnBhdXNlKCk7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy52aWRlb0VsZW1lbnQucGF1c2UoKTtcbiAgfVxufTtcblxuVmlkZW9Qcm94eS5wcm90b3R5cGUuc2V0Vm9sdW1lID0gZnVuY3Rpb24odm9sdW1lTGV2ZWwpIHtcbiAgaWYgKHRoaXMudmlkZW9FbGVtZW50KSB7XG4gICAgLy8gT24gaU9TIDEwLCB0aGUgVmlkZW9FbGVtZW50LnZvbHVtZSBwcm9wZXJ0eSBpcyByZWFkLW9ubHkuIFNvIHdlIHNwZWNpYWxcbiAgICAvLyBjYXNlIG11dGluZyBhbmQgdW5tdXRpbmcuXG4gICAgaWYgKFV0aWwuaXNJT1MoKSkge1xuICAgICAgdGhpcy52aWRlb0VsZW1lbnQubXV0ZWQgPSAodm9sdW1lTGV2ZWwgPT09IDApO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnZpZGVvRWxlbWVudC52b2x1bWUgPSB2b2x1bWVMZXZlbDtcbiAgICB9XG4gIH1cbiAgaWYgKHRoaXMuYXVkaW9FbGVtZW50KSB7XG4gICAgdGhpcy5hdWRpb0VsZW1lbnQudm9sdW1lID0gdm9sdW1lTGV2ZWw7XG4gIH1cbn07XG5cbi8qKlxuICogQ2FsbGVkIG9uIFJBRiB0byBwcm9ncmVzcyBwbGF5YmFjay5cbiAqL1xuVmlkZW9Qcm94eS5wcm90b3R5cGUudXBkYXRlID0gZnVuY3Rpb24oKSB7XG4gIC8vIEZha2VzIHBsYXliYWNrIGZvciBpT1Mgb25seS5cbiAgaWYgKCF0aGlzLmlzRmFrZVBsYXliYWNrKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIHZhciBkdXJhdGlvbiA9IHRoaXMudmlkZW9FbGVtZW50LmR1cmF0aW9uO1xuICB2YXIgbm93ID0gcGVyZm9ybWFuY2Uubm93KCk7XG4gIHZhciBkZWx0YSA9IG5vdyAtIHRoaXMuc3RhcnRUaW1lO1xuICB2YXIgZGVsdGFTID0gZGVsdGEgLyAxMDAwO1xuICB0aGlzLnZpZGVvRWxlbWVudC5jdXJyZW50VGltZSA9IGRlbHRhUztcblxuICAvLyBMb29wIHRocm91Z2ggdGhlIHZpZGVvXG4gIGlmIChkZWx0YVMgPiBkdXJhdGlvbikge1xuICAgIHRoaXMuc3RhcnRUaW1lID0gbm93O1xuICAgIHRoaXMudmlkZW9FbGVtZW50LmN1cnJlbnRUaW1lID0gMDtcbiAgICAvLyBBbHNvIHJlc3RhcnQgdGhlIGF1ZGlvLlxuICAgIHRoaXMuYXVkaW9FbGVtZW50LmN1cnJlbnRUaW1lID0gMDtcbiAgfVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBWaWRlb1Byb3h5O1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDE2IEdvb2dsZSBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cbnZhciBBZGFwdGl2ZVBsYXllciA9IHJlcXVpcmUoJy4vYWRhcHRpdmUtcGxheWVyJyk7XG52YXIgRXZlbnRFbWl0dGVyID0gcmVxdWlyZSgnZXZlbnRlbWl0dGVyMycpO1xudmFyIEV5ZXMgPSByZXF1aXJlKCcuL2V5ZXMnKTtcbnZhciBIb3RzcG90UmVuZGVyZXIgPSByZXF1aXJlKCcuL2hvdHNwb3QtcmVuZGVyZXInKTtcbnZhciBSZXRpY2xlUmVuZGVyZXIgPSByZXF1aXJlKCcuL3JldGljbGUtcmVuZGVyZXInKTtcbnZhciBTcGhlcmVSZW5kZXJlciA9IHJlcXVpcmUoJy4vc3BoZXJlLXJlbmRlcmVyJyk7XG52YXIgVFdFRU4gPSByZXF1aXJlKCd0d2Vlbi5qcycpO1xudmFyIFV0aWwgPSByZXF1aXJlKCcuLi91dGlsJyk7XG52YXIgVmlkZW9Qcm94eSA9IHJlcXVpcmUoJy4vdmlkZW8tcHJveHknKTtcbnZhciBXZWJWUk1hbmFnZXIgPSByZXF1aXJlKCd3ZWJ2ci1ib2lsZXJwbGF0ZScpO1xuXG52YXIgQVVUT1BBTl9EVVJBVElPTiA9IDMwMDA7XG52YXIgQVVUT1BBTl9BTkdMRSA9IDAuNDtcblxuLyoqXG4gKiBUaGUgbWFpbiBXZWJHTCByZW5kZXJpbmcgZW50cnkgcG9pbnQuIE1hbmFnZXMgdGhlIHNjZW5lLCBjYW1lcmEsIFZSLXJlbGF0ZWRcbiAqIHJlbmRlcmluZyB1cGRhdGVzLiBJbnRlcmFjdHMgd2l0aCB0aGUgV2ViVlJNYW5hZ2VyLlxuICpcbiAqIENvb3JkaW5hdGVzIHRoZSBvdGhlciByZW5kZXJlcnM6IFNwaGVyZVJlbmRlcmVyLCBIb3RzcG90UmVuZGVyZXIsXG4gKiBSZXRpY2xlUmVuZGVyZXIuXG4gKlxuICogQWxzbyBtYW5hZ2VzIHRoZSBBZGFwdGl2ZVBsYXllciBhbmQgVmlkZW9Qcm94eS5cbiAqXG4gKiBFbWl0cyB0aGUgZm9sbG93aW5nIGV2ZW50czpcbiAqICAgbG9hZDogd2hlbiB0aGUgc2NlbmUgaXMgbG9hZGVkLlxuICogICBlcnJvcjogaWYgdGhlcmUgaXMgYW4gZXJyb3IgbG9hZGluZyB0aGUgc2NlbmUuXG4gKiAgIG1vZGVjaGFuZ2UoQm9vbGVhbiBpc1ZSKTogaWYgdGhlIG1vZGUgKGVnLiBWUiwgZnVsbHNjcmVlbiwgZXRjKSBjaGFuZ2VzLlxuICovXG5mdW5jdGlvbiBXb3JsZFJlbmRlcmVyKCkge1xuICB0aGlzLmluaXRfKCk7XG5cbiAgdGhpcy5zcGhlcmVSZW5kZXJlciA9IG5ldyBTcGhlcmVSZW5kZXJlcih0aGlzLnNjZW5lKTtcbiAgdGhpcy5ob3RzcG90UmVuZGVyZXIgPSBuZXcgSG90c3BvdFJlbmRlcmVyKHRoaXMpO1xuICB0aGlzLmhvdHNwb3RSZW5kZXJlci5vbignZm9jdXMnLCB0aGlzLm9uSG90c3BvdEZvY3VzXy5iaW5kKHRoaXMpKTtcbiAgdGhpcy5ob3RzcG90UmVuZGVyZXIub24oJ2JsdXInLCB0aGlzLm9uSG90c3BvdEJsdXJfLmJpbmQodGhpcykpO1xuICB0aGlzLnJldGljbGVSZW5kZXJlciA9IG5ldyBSZXRpY2xlUmVuZGVyZXIodGhpcy5jYW1lcmEpO1xuXG4gIC8vIEdldCB0aGUgVlIgRGlzcGxheSBhcyBzb29uIGFzIHdlIGluaXRpYWxpemUuXG4gIG5hdmlnYXRvci5nZXRWUkRpc3BsYXlzKCkudGhlbihmdW5jdGlvbihkaXNwbGF5cykge1xuICAgIGlmIChkaXNwbGF5cy5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLnZyRGlzcGxheSA9IGRpc3BsYXlzWzBdO1xuICAgIH1cbiAgfS5iaW5kKHRoaXMpKTtcblxufVxuV29ybGRSZW5kZXJlci5wcm90b3R5cGUgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbldvcmxkUmVuZGVyZXIucHJvdG90eXBlLnJlbmRlciA9IGZ1bmN0aW9uKHRpbWUpIHtcbiAgdGhpcy5jb250cm9scy51cGRhdGUoKTtcbiAgdGhpcy5ob3RzcG90UmVuZGVyZXIudXBkYXRlKHRoaXMuY2FtZXJhKTtcbiAgVFdFRU4udXBkYXRlKHRpbWUpO1xuICB0aGlzLmVmZmVjdC5yZW5kZXIodGhpcy5zY2VuZSwgdGhpcy5jYW1lcmEpO1xufTtcblxuLyoqXG4gKiBAcmV0dXJuIHtQcm9taXNlfSBXaGVuIHRoZSBzY2VuZSBpcyBmdWxseSBsb2FkZWQuXG4gKi9cbldvcmxkUmVuZGVyZXIucHJvdG90eXBlLnNldFNjZW5lID0gZnVuY3Rpb24oc2NlbmUpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB2YXIgcHJvbWlzZSA9IG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuICAgIHNlbGYuc2NlbmVSZXNvbHZlID0gcmVzb2x2ZTtcbiAgICBzZWxmLnNjZW5lUmVqZWN0ID0gcmVqZWN0O1xuICB9KTtcblxuICBpZiAoIXNjZW5lIHx8ICFzY2VuZS5pc1ZhbGlkKCkpIHtcbiAgICB0aGlzLmRpZExvYWRGYWlsXyhzY2VuZS5lcnJvck1lc3NhZ2UpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBwYXJhbXMgPSB7XG4gICAgaXNTdGVyZW86IHNjZW5lLmlzU3RlcmVvLFxuICB9O1xuICB0aGlzLnNldERlZmF1bHRZYXdfKHNjZW5lLmRlZmF1bHRZYXcgfHwgMCk7XG5cbiAgLy8gRGlzYWJsZSBWUiBtb2RlIGlmIGV4cGxpY2l0bHkgZGlzYWJsZWQsIG9yIGlmIHdlJ3JlIGxvYWRpbmcgYSB2aWRlbyBvbiBpT1NcbiAgLy8gOSBvciBlYXJsaWVyLlxuICBpZiAoc2NlbmUuaXNWUk9mZiB8fCAoc2NlbmUudmlkZW8gJiYgVXRpbC5pc0lPUzlPckxlc3MoKSkpIHtcbiAgICB0aGlzLm1hbmFnZXIuc2V0VlJDb21wYXRpYmxlT3ZlcnJpZGUoZmFsc2UpO1xuICB9XG5cbiAgLy8gU2V0IHZhcmlvdXMgY2FsbGJhY2sgb3ZlcnJpZGVzIGluIGlPUy5cbiAgaWYgKFV0aWwuaXNJT1MoKSkge1xuICAgIHRoaXMubWFuYWdlci5zZXRGdWxsc2NyZWVuQ2FsbGJhY2soZnVuY3Rpb24oKSB7XG4gICAgICBVdGlsLnNlbmRQYXJlbnRNZXNzYWdlKHt0eXBlOiAnZW50ZXItZnVsbHNjcmVlbid9KTtcbiAgICB9KTtcbiAgICB0aGlzLm1hbmFnZXIuc2V0RXhpdEZ1bGxzY3JlZW5DYWxsYmFjayhmdW5jdGlvbigpIHtcbiAgICAgIFV0aWwuc2VuZFBhcmVudE1lc3NhZ2Uoe3R5cGU6ICdleGl0LWZ1bGxzY3JlZW4nfSk7XG4gICAgfSk7XG4gICAgdGhpcy5tYW5hZ2VyLnNldFZSQ2FsbGJhY2soZnVuY3Rpb24oKSB7XG4gICAgICBVdGlsLnNlbmRQYXJlbnRNZXNzYWdlKHt0eXBlOiAnZW50ZXItdnInfSk7XG4gICAgfSk7XG4gIH1cblxuICAvLyBJZiB3ZSdyZSBkZWFsaW5nIHdpdGggYW4gaW1hZ2UsIGFuZCBub3QgYSB2aWRlby5cbiAgaWYgKHNjZW5lLmltYWdlICYmICFzY2VuZS52aWRlbykge1xuICAgIGlmIChzY2VuZS5wcmV2aWV3KSB7XG4gICAgICAvLyBGaXJzdCBsb2FkIHRoZSBwcmV2aWV3LlxuICAgICAgdGhpcy5zcGhlcmVSZW5kZXJlci5zZXRQaG90b3NwaGVyZShzY2VuZS5wcmV2aWV3LCBwYXJhbXMpLnRoZW4oZnVuY3Rpb24oKSB7XG4gICAgICAgIC8vIEFzIHNvb24gYXMgc29tZXRoaW5nIGlzIGxvYWRlZCwgZW1pdCB0aGUgbG9hZCBldmVudCB0byBoaWRlIHRoZVxuICAgICAgICAvLyBsb2FkaW5nIHByb2dyZXNzIGJhci5cbiAgICAgICAgc2VsZi5kaWRMb2FkXygpO1xuICAgICAgICAvLyBUaGVuIGxvYWQgdGhlIGZ1bGwgcmVzb2x1dGlvbiBpbWFnZS5cbiAgICAgICAgc2VsZi5zcGhlcmVSZW5kZXJlci5zZXRQaG90b3NwaGVyZShzY2VuZS5pbWFnZSwgcGFyYW1zKTtcbiAgICAgIH0pLmNhdGNoKHNlbGYuZGlkTG9hZEZhaWxfLmJpbmQoc2VsZikpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBObyBwcmV2aWV3IC0tIGdvIHN0cmFpZ2h0IHRvIHJlbmRlcmluZyB0aGUgZnVsbCBpbWFnZS5cbiAgICAgIHRoaXMuc3BoZXJlUmVuZGVyZXIuc2V0UGhvdG9zcGhlcmUoc2NlbmUuaW1hZ2UsIHBhcmFtcykudGhlbihmdW5jdGlvbigpIHtcbiAgICAgICAgc2VsZi5kaWRMb2FkXygpO1xuICAgICAgfSkuY2F0Y2goc2VsZi5kaWRMb2FkRmFpbF8uYmluZChzZWxmKSk7XG4gICAgfVxuICB9IGVsc2UgaWYgKHNjZW5lLnZpZGVvKSB7XG4gICAgaWYgKFV0aWwuaXNJRTExKCkpIHtcbiAgICAgIC8vIE9uIElFIDExLCBpZiBhbiAnaW1hZ2UnIHBhcmFtIGlzIHByb3ZpZGVkLCBsb2FkIGl0IGluc3RlYWQgb2Ygc2hvd2luZ1xuICAgICAgLy8gYW4gZXJyb3IuXG4gICAgICAvL1xuICAgICAgLy8gVE9ETyhzbXVzKTogT25jZSB2aWRlbyB0ZXh0dXJlcyBhcmUgc3VwcG9ydGVkLCByZW1vdmUgdGhpcyBmYWxsYmFjay5cbiAgICAgIGlmIChzY2VuZS5pbWFnZSkge1xuICAgICAgICB0aGlzLnNwaGVyZVJlbmRlcmVyLnNldFBob3Rvc3BoZXJlKHNjZW5lLmltYWdlLCBwYXJhbXMpLnRoZW4oZnVuY3Rpb24oKSB7XG4gICAgICAgICAgc2VsZi5kaWRMb2FkXygpO1xuICAgICAgICB9KS5jYXRjaChzZWxmLmRpZExvYWRGYWlsXy5iaW5kKHNlbGYpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuZGlkTG9hZEZhaWxfKCdWaWRlbyBpcyBub3Qgc3VwcG9ydGVkIG9uIElFMTEuJyk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucGxheWVyID0gbmV3IEFkYXB0aXZlUGxheWVyKCk7XG4gICAgICB0aGlzLnBsYXllci5vbignbG9hZCcsIGZ1bmN0aW9uKHZpZGVvRWxlbWVudCkge1xuICAgICAgICBzZWxmLnNwaGVyZVJlbmRlcmVyLnNldDM2MFZpZGVvKHZpZGVvRWxlbWVudCwgcGFyYW1zKS50aGVuKGZ1bmN0aW9uKCkge1xuICAgICAgICAgIHNlbGYuZGlkTG9hZF8oe3ZpZGVvRWxlbWVudDogdmlkZW9FbGVtZW50fSk7XG4gICAgICAgIH0pLmNhdGNoKHNlbGYuZGlkTG9hZEZhaWxfLmJpbmQoc2VsZikpO1xuICAgICAgfSk7XG4gICAgICB0aGlzLnBsYXllci5vbignZXJyb3InLCBmdW5jdGlvbihlcnJvcikge1xuICAgICAgICBzZWxmLmRpZExvYWRGYWlsXygnVmlkZW8gbG9hZCBlcnJvcjogJyArIGVycm9yKTtcbiAgICAgIH0pO1xuICAgICAgdGhpcy5wbGF5ZXIubG9hZChzY2VuZS52aWRlbyk7XG5cbiAgICAgIHRoaXMudmlkZW9Qcm94eSA9IG5ldyBWaWRlb1Byb3h5KHRoaXMucGxheWVyLnZpZGVvKTtcbiAgICB9XG4gIH1cblxuICB0aGlzLnNjZW5lSW5mbyA9IHNjZW5lO1xuICBpZiAoVXRpbC5pc0RlYnVnKCkpIHtcbiAgICBjb25zb2xlLmxvZygnTG9hZGVkIHNjZW5lJywgc2NlbmUpO1xuICB9XG5cbiAgcmV0dXJuIHByb21pc2U7XG59O1xuXG5Xb3JsZFJlbmRlcmVyLnByb3RvdHlwZS5pc1ZSTW9kZSA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gISF0aGlzLnZyRGlzcGxheSAmJiB0aGlzLnZyRGlzcGxheS5pc1ByZXNlbnRpbmc7XG59O1xuXG5Xb3JsZFJlbmRlcmVyLnByb3RvdHlwZS5zdWJtaXRGcmFtZSA9IGZ1bmN0aW9uKCkge1xuICBpZiAodGhpcy5pc1ZSTW9kZSgpKSB7XG4gICAgdGhpcy52ckRpc3BsYXkuc3VibWl0RnJhbWUoKTtcbiAgfVxufTtcblxuV29ybGRSZW5kZXJlci5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uKCkge1xuICBpZiAodGhpcy5wbGF5ZXIpIHtcbiAgICB0aGlzLnBsYXllci5yZW1vdmVBbGxMaXN0ZW5lcnMoKTtcbiAgICB0aGlzLnBsYXllci5kZXN0cm95KCk7XG4gICAgdGhpcy5wbGF5ZXIgPSBudWxsO1xuICB9XG59XG5cbldvcmxkUmVuZGVyZXIucHJvdG90eXBlLmRpZExvYWRfID0gZnVuY3Rpb24ob3B0X2V2ZW50KSB7XG4gIHZhciBldmVudCA9IG9wdF9ldmVudCB8fCB7fTtcbiAgdGhpcy5lbWl0KCdsb2FkJywgZXZlbnQpO1xuICBpZiAodGhpcy5zY2VuZVJlc29sdmUpIHtcbiAgICB0aGlzLnNjZW5lUmVzb2x2ZSgpO1xuICB9XG59O1xuXG5Xb3JsZFJlbmRlcmVyLnByb3RvdHlwZS5kaWRMb2FkRmFpbF8gPSBmdW5jdGlvbihtZXNzYWdlKSB7XG4gIHRoaXMuZW1pdCgnZXJyb3InLCBtZXNzYWdlKTtcbiAgaWYgKHRoaXMuc2NlbmVSZWplY3QpIHtcbiAgICB0aGlzLnNjZW5lUmVqZWN0KG1lc3NhZ2UpO1xuICB9XG59O1xuXG4vKipcbiAqIFNldHMgdGhlIGRlZmF1bHQgeWF3LlxuICogQHBhcmFtIHtOdW1iZXJ9IGFuZ2xlUmFkIFRoZSB5YXcgaW4gcmFkaWFucy5cbiAqL1xuV29ybGRSZW5kZXJlci5wcm90b3R5cGUuc2V0RGVmYXVsdFlhd18gPSBmdW5jdGlvbihhbmdsZVJhZCkge1xuICAvLyBSb3RhdGUgdGhlIGNhbWVyYSBwYXJlbnQgdG8gdGFrZSBpbnRvIGFjY291bnQgdGhlIHNjZW5lJ3Mgcm90YXRpb24uXG4gIC8vIEJ5IGRlZmF1bHQsIGl0IHNob3VsZCBiZSBhdCB0aGUgY2VudGVyIG9mIHRoZSBpbWFnZS5cbiAgdGhpcy5jYW1lcmEucGFyZW50LnJvdGF0aW9uLnkgPSAoTWF0aC5QSSAvIDIuMCkgKyBhbmdsZVJhZDtcbn07XG5cbi8qKlxuICogRG8gdGhlIGluaXRpYWwgY2FtZXJhIHR3ZWVuIHRvIHJvdGF0ZSB0aGUgY2FtZXJhLCBnaXZpbmcgYW4gaW5kaWNhdGlvbiB0aGF0XG4gKiB0aGVyZSBpcyBsaXZlIGNvbnRlbnQgdGhlcmUgKG9uIGRlc2t0b3Agb25seSkuXG4gKi9cbldvcmxkUmVuZGVyZXIucHJvdG90eXBlLmF1dG9wYW4gPSBmdW5jdGlvbihkdXJhdGlvbikge1xuICB2YXIgdGFyZ2V0WSA9IHRoaXMuY2FtZXJhLnBhcmVudC5yb3RhdGlvbi55IC0gQVVUT1BBTl9BTkdMRTtcbiAgdmFyIHR3ZWVuID0gbmV3IFRXRUVOLlR3ZWVuKHRoaXMuY2FtZXJhLnBhcmVudC5yb3RhdGlvbilcbiAgICAgIC50byh7eTogdGFyZ2V0WX0sIEFVVE9QQU5fRFVSQVRJT04pXG4gICAgICAuZWFzaW5nKFRXRUVOLkVhc2luZy5RdWFkcmF0aWMuT3V0KVxuICAgICAgLnN0YXJ0KCk7XG59O1xuXG5Xb3JsZFJlbmRlcmVyLnByb3RvdHlwZS5pbml0XyA9IGZ1bmN0aW9uKCkge1xuICB2YXIgY29udGFpbmVyID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignYm9keScpO1xuICB2YXIgYXNwZWN0ID0gd2luZG93LmlubmVyV2lkdGggLyB3aW5kb3cuaW5uZXJIZWlnaHQ7XG4gIHZhciBjYW1lcmEgPSBuZXcgVEhSRUUuUGVyc3BlY3RpdmVDYW1lcmEoNzUsIGFzcGVjdCwgMC4xLCAxMDApO1xuICBjYW1lcmEubGF5ZXJzLmVuYWJsZSgxKTtcblxuICB2YXIgY2FtZXJhRHVtbXkgPSBuZXcgVEhSRUUuT2JqZWN0M0QoKTtcbiAgY2FtZXJhRHVtbXkuYWRkKGNhbWVyYSk7XG5cbiAgLy8gQW50aWFsaWFzaW5nIGRpc2FibGVkIHRvIGltcHJvdmUgcGVyZm9ybWFuY2UuXG4gIHZhciByZW5kZXJlciA9IG5ldyBUSFJFRS5XZWJHTFJlbmRlcmVyKHthbnRpYWxpYXM6IGZhbHNlfSk7XG4gIHJlbmRlcmVyLnNldENsZWFyQ29sb3IoMHgwMDAwMDAsIDApO1xuICByZW5kZXJlci5zZXRTaXplKHdpbmRvdy5pbm5lcldpZHRoLCB3aW5kb3cuaW5uZXJIZWlnaHQpO1xuICByZW5kZXJlci5zZXRQaXhlbFJhdGlvKHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvKTtcblxuICBjb250YWluZXIuYXBwZW5kQ2hpbGQocmVuZGVyZXIuZG9tRWxlbWVudCk7XG5cbiAgdmFyIGNvbnRyb2xzID0gbmV3IFRIUkVFLlZSQ29udHJvbHMoY2FtZXJhKTtcbiAgdmFyIGVmZmVjdCA9IG5ldyBUSFJFRS5WUkVmZmVjdChyZW5kZXJlcik7XG5cbiAgLy8gRGlzYWJsZSBleWUgc2VwYXJhdGlvbi5cbiAgZWZmZWN0LnNjYWxlID0gMDtcbiAgZWZmZWN0LnNldFNpemUod2luZG93LmlubmVyV2lkdGgsIHdpbmRvdy5pbm5lckhlaWdodCk7XG5cbiAgLy8gUHJlc2VudCBzdWJtaXNzaW9uIG9mIGZyYW1lcyBhdXRvbWF0aWNhbGx5LiBUaGlzIGlzIGRvbmUgbWFudWFsbHkgaW5cbiAgLy8gc3VibWl0RnJhbWUoKS5cbiAgZWZmZWN0LmF1dG9TdWJtaXRGcmFtZSA9IGZhbHNlO1xuXG4gIHRoaXMuY2FtZXJhID0gY2FtZXJhO1xuICB0aGlzLnJlbmRlcmVyID0gcmVuZGVyZXI7XG4gIHRoaXMuZWZmZWN0ID0gZWZmZWN0O1xuICB0aGlzLmNvbnRyb2xzID0gY29udHJvbHM7XG4gIHRoaXMubWFuYWdlciA9IG5ldyBXZWJWUk1hbmFnZXIocmVuZGVyZXIsIGVmZmVjdCwge3ByZWRpc3RvcnRlZDogZmFsc2V9KTtcblxuICB0aGlzLnNjZW5lID0gdGhpcy5jcmVhdGVTY2VuZV8oKTtcbiAgdGhpcy5zY2VuZS5hZGQodGhpcy5jYW1lcmEucGFyZW50KTtcblxuXG4gIC8vIFdhdGNoIHRoZSByZXNpemUgZXZlbnQuXG4gIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdyZXNpemUnLCB0aGlzLm9uUmVzaXplXy5iaW5kKHRoaXMpKTtcblxuICAvLyBQcmV2ZW50IGNvbnRleHQgbWVudS5cbiAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ2NvbnRleHRtZW51JywgdGhpcy5vbkNvbnRleHRNZW51Xy5iaW5kKHRoaXMpKTtcblxuICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigndnJkaXNwbGF5cHJlc2VudGNoYW5nZScsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub25WUkRpc3BsYXlQcmVzZW50Q2hhbmdlXy5iaW5kKHRoaXMpKTtcbn07XG5cbldvcmxkUmVuZGVyZXIucHJvdG90eXBlLm9uUmVzaXplXyA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLmVmZmVjdC5zZXRTaXplKHdpbmRvdy5pbm5lcldpZHRoLCB3aW5kb3cuaW5uZXJIZWlnaHQpO1xuICB0aGlzLmNhbWVyYS5hc3BlY3QgPSB3aW5kb3cuaW5uZXJXaWR0aCAvIHdpbmRvdy5pbm5lckhlaWdodDtcbiAgdGhpcy5jYW1lcmEudXBkYXRlUHJvamVjdGlvbk1hdHJpeCgpO1xufTtcblxuV29ybGRSZW5kZXJlci5wcm90b3R5cGUub25WUkRpc3BsYXlQcmVzZW50Q2hhbmdlXyA9IGZ1bmN0aW9uKGUpIHtcbiAgaWYgKFV0aWwuaXNEZWJ1ZygpKSB7XG4gICAgY29uc29sZS5sb2coJ29uVlJEaXNwbGF5UHJlc2VudENoYW5nZV8nKTtcbiAgfVxuICB2YXIgaXNWUiA9IHRoaXMuaXNWUk1vZGUoKTtcblxuICAvLyBJZiB0aGUgbW9kZSBjaGFuZ2VkIHRvIFZSIGFuZCB0aGVyZSBpcyBhdCBsZWFzdCBvbmUgaG90c3BvdCwgc2hvdyByZXRpY2xlLlxuICB2YXIgaXNSZXRpY2xlVmlzaWJsZSA9IGlzVlIgJiYgdGhpcy5ob3RzcG90UmVuZGVyZXIuZ2V0Q291bnQoKSA+IDA7XG4gIC8vdGhpcy5yZXRpY2xlUmVuZGVyZXIuc2V0VmlzaWJpbGl0eShpc1JldGljbGVWaXNpYmxlKTtcblxuICAvLyBSZXNpemUgdGhlIHJlbmRlcmVyIGZvciBnb29kIG1lYXN1cmUuXG4gIHRoaXMub25SZXNpemVfKCk7XG5cbiAgLy8gQW5hbHl0aWNzLlxuICBpZiAod2luZG93LmFuYWx5dGljcykge1xuICAgIGFuYWx5dGljcy5sb2dNb2RlQ2hhbmdlZChpc1ZSKTtcbiAgfVxuXG4gIC8vIFdoZW4gZXhpdGluZyBWUiBtb2RlIGZyb20gaU9TLCBtYWtlIHN1cmUgd2UgZW1pdCBiYWNrIGFuIGV4aXQtZnVsbHNjcmVlbiBldmVudC5cbiAgaWYgKCFpc1ZSICYmIFV0aWwuaXNJT1MoKSkge1xuICAgIFV0aWwuc2VuZFBhcmVudE1lc3NhZ2Uoe3R5cGU6ICdleGl0LWZ1bGxzY3JlZW4nfSk7XG4gIH1cblxuICAvLyBFbWl0IGEgbW9kZSBjaGFuZ2UgZXZlbnQgYmFjayB0byBhbnkgbGlzdGVuZXJzLlxuICB0aGlzLmVtaXQoJ21vZGVjaGFuZ2UnLCBpc1ZSKTtcbn07XG5cbldvcmxkUmVuZGVyZXIucHJvdG90eXBlLmNyZWF0ZVNjZW5lXyA9IGZ1bmN0aW9uKG9wdF9wYXJhbXMpIHtcbiAgdmFyIHNjZW5lID0gbmV3IFRIUkVFLlNjZW5lKCk7XG5cbiAgLy8gQWRkIGEgZ3JvdXAgZm9yIHRoZSBwaG90b3NwaGVyZS5cbiAgdmFyIHBob3RvR3JvdXAgPSBuZXcgVEhSRUUuT2JqZWN0M0QoKTtcbiAgcGhvdG9Hcm91cC5uYW1lID0gJ3Bob3RvJztcbiAgc2NlbmUuYWRkKHBob3RvR3JvdXApO1xuXG4gIHJldHVybiBzY2VuZTtcbn07XG5cbldvcmxkUmVuZGVyZXIucHJvdG90eXBlLm9uSG90c3BvdEZvY3VzXyA9IGZ1bmN0aW9uKGlkKSB7XG4gIC8vIFNldCB0aGUgZGVmYXVsdCBjdXJzb3IgdG8gYmUgYSBwb2ludGVyLlxuICB0aGlzLnNldEN1cnNvcl8oJ3BvaW50ZXInKTtcbn07XG5cbldvcmxkUmVuZGVyZXIucHJvdG90eXBlLm9uSG90c3BvdEJsdXJfID0gZnVuY3Rpb24oaWQpIHtcbiAgLy8gUmVzZXQgdGhlIGRlZmF1bHQgY3Vyc29yIHRvIGJlIHRoZSBkZWZhdWx0IG9uZS5cbiAgdGhpcy5zZXRDdXJzb3JfKCcnKTtcbn07XG5cbldvcmxkUmVuZGVyZXIucHJvdG90eXBlLnNldEN1cnNvcl8gPSBmdW5jdGlvbihjdXJzb3IpIHtcbiAgdGhpcy5yZW5kZXJlci5kb21FbGVtZW50LnN0eWxlLmN1cnNvciA9IGN1cnNvcjtcbn07XG5cbldvcmxkUmVuZGVyZXIucHJvdG90eXBlLm9uQ29udGV4dE1lbnVfID0gZnVuY3Rpb24oZSkge1xuICBlLnByZXZlbnREZWZhdWx0KCk7XG4gIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gIHJldHVybiBmYWxzZTtcbn07XG5cblxubW9kdWxlLmV4cG9ydHMgPSBXb3JsZFJlbmRlcmVyO1xuIiwiLypcbiAqIENvcHlyaWdodCAyMDE2IEdvb2dsZSBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuLyoqXG4gKiBNZXNzYWdlcyBmcm9tIHRoZSBBUEkgdG8gdGhlIGVtYmVkLlxuICovXG52YXIgTWVzc2FnZSA9IHtcbiAgUExBWTogJ3BsYXknLFxuICBQQVVTRTogJ3BhdXNlJyxcbiAgQUREX0hPVFNQT1Q6ICdhZGRob3RzcG90JyxcbiAgU0VUX0NPTlRFTlQ6ICdzZXRpbWFnZScsXG4gIFNFVF9WT0xVTUU6ICdzZXR2b2x1bWUnLFxuICBERVZJQ0VfTU9USU9OOiAnZGV2aWNlbW90aW9uJyxcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gTWVzc2FnZTtcbiIsIi8qXG4gKiBDb3B5cmlnaHQgMjAxNiBHb29nbGUgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICovXG5cblV0aWwgPSB3aW5kb3cuVXRpbCB8fCB7fTtcblxuVXRpbC5pc0RhdGFVUkkgPSBmdW5jdGlvbihzcmMpIHtcbiAgcmV0dXJuIHNyYyAmJiBzcmMuaW5kZXhPZignZGF0YTonKSA9PSAwO1xufTtcblxuVXRpbC5nZW5lcmF0ZVVVSUQgPSBmdW5jdGlvbigpIHtcbiAgZnVuY3Rpb24gczQoKSB7XG4gICAgcmV0dXJuIE1hdGguZmxvb3IoKDEgKyBNYXRoLnJhbmRvbSgpKSAqIDB4MTAwMDApXG4gICAgLnRvU3RyaW5nKDE2KVxuICAgIC5zdWJzdHJpbmcoMSk7XG4gIH1cbiAgcmV0dXJuIHM0KCkgKyBzNCgpICsgJy0nICsgczQoKSArICctJyArIHM0KCkgKyAnLScgK1xuICAgIHM0KCkgKyAnLScgKyBzNCgpICsgczQoKSArIHM0KCk7XG59O1xuXG5VdGlsLmlzTW9iaWxlID0gZnVuY3Rpb24oKSB7XG4gIHZhciBjaGVjayA9IGZhbHNlO1xuICAoZnVuY3Rpb24oYSl7aWYoLyhhbmRyb2lkfGJiXFxkK3xtZWVnbykuK21vYmlsZXxhdmFudGdvfGJhZGFcXC98YmxhY2tiZXJyeXxibGF6ZXJ8Y29tcGFsfGVsYWluZXxmZW5uZWN8aGlwdG9wfGllbW9iaWxlfGlwKGhvbmV8b2QpfGlyaXN8a2luZGxlfGxnZSB8bWFlbW98bWlkcHxtbXB8bW9iaWxlLitmaXJlZm94fG5ldGZyb250fG9wZXJhIG0ob2J8aW4paXxwYWxtKCBvcyk/fHBob25lfHAoaXhpfHJlKVxcL3xwbHVja2VyfHBvY2tldHxwc3B8c2VyaWVzKDR8NikwfHN5bWJpYW58dHJlb3x1cFxcLihicm93c2VyfGxpbmspfHZvZGFmb25lfHdhcHx3aW5kb3dzIGNlfHhkYXx4aWluby9pLnRlc3QoYSl8fC8xMjA3fDYzMTB8NjU5MHwzZ3NvfDR0aHB8NTBbMS02XWl8Nzcwc3w4MDJzfGEgd2F8YWJhY3xhYyhlcnxvb3xzXFwtKXxhaShrb3xybil8YWwoYXZ8Y2F8Y28pfGFtb2l8YW4oZXh8bnl8eXcpfGFwdHV8YXIoY2h8Z28pfGFzKHRlfHVzKXxhdHR3fGF1KGRpfFxcLW18ciB8cyApfGF2YW58YmUoY2t8bGx8bnEpfGJpKGxifHJkKXxibChhY3xheil8YnIoZXx2KXd8YnVtYnxid1xcLShufHUpfGM1NVxcL3xjYXBpfGNjd2F8Y2RtXFwtfGNlbGx8Y2h0bXxjbGRjfGNtZFxcLXxjbyhtcHxuZCl8Y3Jhd3xkYShpdHxsbHxuZyl8ZGJ0ZXxkY1xcLXN8ZGV2aXxkaWNhfGRtb2J8ZG8oY3xwKW98ZHMoMTJ8XFwtZCl8ZWwoNDl8YWkpfGVtKGwyfHVsKXxlcihpY3xrMCl8ZXNsOHxleihbNC03XTB8b3N8d2F8emUpfGZldGN8Zmx5KFxcLXxfKXxnMSB1fGc1NjB8Z2VuZXxnZlxcLTV8Z1xcLW1vfGdvKFxcLnd8b2QpfGdyKGFkfHVuKXxoYWllfGhjaXR8aGRcXC0obXxwfHQpfGhlaVxcLXxoaShwdHx0YSl8aHAoIGl8aXApfGhzXFwtY3xodChjKFxcLXwgfF98YXxnfHB8c3x0KXx0cCl8aHUoYXd8dGMpfGlcXC0oMjB8Z298bWEpfGkyMzB8aWFjKCB8XFwtfFxcLyl8aWJyb3xpZGVhfGlnMDF8aWtvbXxpbTFrfGlubm98aXBhcXxpcmlzfGphKHR8dilhfGpicm98amVtdXxqaWdzfGtkZGl8a2VqaXxrZ3QoIHxcXC8pfGtsb258a3B0IHxrd2NcXC18a3lvKGN8ayl8bGUobm98eGkpfGxnKCBnfFxcLyhrfGx8dSl8NTB8NTR8XFwtW2Etd10pfGxpYnd8bHlueHxtMVxcLXd8bTNnYXxtNTBcXC98bWEodGV8dWl8eG8pfG1jKDAxfDIxfGNhKXxtXFwtY3J8bWUocmN8cmkpfG1pKG84fG9hfHRzKXxtbWVmfG1vKDAxfDAyfGJpfGRlfGRvfHQoXFwtfCB8b3x2KXx6eil8bXQoNTB8cDF8diApfG13YnB8bXl3YXxuMTBbMC0yXXxuMjBbMi0zXXxuMzAoMHwyKXxuNTAoMHwyfDUpfG43KDAoMHwxKXwxMCl8bmUoKGN8bSlcXC18b258dGZ8d2Z8d2d8d3QpfG5vayg2fGkpfG56cGh8bzJpbXxvcCh0aXx3dil8b3Jhbnxvd2cxfHA4MDB8cGFuKGF8ZHx0KXxwZHhnfHBnKDEzfFxcLShbMS04XXxjKSl8cGhpbHxwaXJlfHBsKGF5fHVjKXxwblxcLTJ8cG8oY2t8cnR8c2UpfHByb3h8cHNpb3xwdFxcLWd8cWFcXC1hfHFjKDA3fDEyfDIxfDMyfDYwfFxcLVsyLTddfGlcXC0pfHF0ZWt8cjM4MHxyNjAwfHJha3N8cmltOXxybyh2ZXx6byl8czU1XFwvfHNhKGdlfG1hfG1tfG1zfG55fHZhKXxzYygwMXxoXFwtfG9vfHBcXC0pfHNka1xcL3xzZShjKFxcLXwwfDEpfDQ3fG1jfG5kfHJpKXxzZ2hcXC18c2hhcnxzaWUoXFwtfG0pfHNrXFwtMHxzbCg0NXxpZCl8c20oYWx8YXJ8YjN8aXR8dDUpfHNvKGZ0fG55KXxzcCgwMXxoXFwtfHZcXC18diApfHN5KDAxfG1iKXx0MigxOHw1MCl8dDYoMDB8MTB8MTgpfHRhKGd0fGxrKXx0Y2xcXC18dGRnXFwtfHRlbChpfG0pfHRpbVxcLXx0XFwtbW98dG8ocGx8c2gpfHRzKDcwfG1cXC18bTN8bTUpfHR4XFwtOXx1cChcXC5ifGcxfHNpKXx1dHN0fHY0MDB8djc1MHx2ZXJpfHZpKHJnfHRlKXx2ayg0MHw1WzAtM118XFwtdil8dm00MHx2b2RhfHZ1bGN8dngoNTJ8NTN8NjB8NjF8NzB8ODB8ODF8ODN8ODV8OTgpfHczYyhcXC18ICl8d2ViY3x3aGl0fHdpKGcgfG5jfG53KXx3bWxifHdvbnV8eDcwMHx5YXNcXC18eW91cnx6ZXRvfHp0ZVxcLS9pLnRlc3QoYS5zdWJzdHIoMCw0KSkpY2hlY2sgPSB0cnVlfSkobmF2aWdhdG9yLnVzZXJBZ2VudHx8bmF2aWdhdG9yLnZlbmRvcnx8d2luZG93Lm9wZXJhKTtcbiAgcmV0dXJuIGNoZWNrO1xufTtcblxuVXRpbC5pc0lPUyA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gLyhpUGFkfGlQaG9uZXxpUG9kKS9nLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCk7XG59O1xuXG5VdGlsLmlzU2FmYXJpID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiAvXigoPyFjaHJvbWV8YW5kcm9pZCkuKSpzYWZhcmkvaS50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpO1xufTtcblxuVXRpbC5jbG9uZU9iamVjdCA9IGZ1bmN0aW9uKG9iaikge1xuICB2YXIgb3V0ID0ge307XG4gIGZvciAoa2V5IGluIG9iaikge1xuICAgIG91dFtrZXldID0gb2JqW2tleV07XG4gIH1cbiAgcmV0dXJuIG91dDtcbn07XG5cblV0aWwuaGFzaENvZGUgPSBmdW5jdGlvbihzKSB7XG4gIHJldHVybiBzLnNwbGl0KFwiXCIpLnJlZHVjZShmdW5jdGlvbihhLGIpe2E9KChhPDw1KS1hKStiLmNoYXJDb2RlQXQoMCk7cmV0dXJuIGEmYX0sMCk7XG59O1xuXG5VdGlsLmxvYWRUcmFja1NyYyA9IGZ1bmN0aW9uKGNvbnRleHQsIHNyYywgY2FsbGJhY2ssIG9wdF9wcm9ncmVzc0NhbGxiYWNrKSB7XG4gIHZhciByZXF1ZXN0ID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7XG4gIHJlcXVlc3Qub3BlbignR0VUJywgc3JjLCB0cnVlKTtcbiAgcmVxdWVzdC5yZXNwb25zZVR5cGUgPSAnYXJyYXlidWZmZXInO1xuXG4gIC8vIERlY29kZSBhc3luY2hyb25vdXNseS5cbiAgcmVxdWVzdC5vbmxvYWQgPSBmdW5jdGlvbigpIHtcbiAgICBjb250ZXh0LmRlY29kZUF1ZGlvRGF0YShyZXF1ZXN0LnJlc3BvbnNlLCBmdW5jdGlvbihidWZmZXIpIHtcbiAgICAgIGNhbGxiYWNrKGJ1ZmZlcik7XG4gICAgfSwgZnVuY3Rpb24oZSkge1xuICAgICAgY29uc29sZS5lcnJvcihlKTtcbiAgICB9KTtcbiAgfTtcbiAgaWYgKG9wdF9wcm9ncmVzc0NhbGxiYWNrKSB7XG4gICAgcmVxdWVzdC5vbnByb2dyZXNzID0gZnVuY3Rpb24oZSkge1xuICAgICAgdmFyIHBlcmNlbnQgPSBlLmxvYWRlZCAvIGUudG90YWw7XG4gICAgICBvcHRfcHJvZ3Jlc3NDYWxsYmFjayhwZXJjZW50KTtcbiAgICB9O1xuICB9XG4gIHJlcXVlc3Quc2VuZCgpO1xufTtcblxuVXRpbC5pc1BvdzIgPSBmdW5jdGlvbihuKSB7XG4gIHJldHVybiAobiAmIChuIC0gMSkpID09IDA7XG59O1xuXG5VdGlsLmNhcGl0YWxpemUgPSBmdW5jdGlvbihzKSB7XG4gIHJldHVybiBzLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgcy5zbGljZSgxKTtcbn07XG5cblV0aWwuaXNJRnJhbWUgPSBmdW5jdGlvbigpIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gd2luZG93LnNlbGYgIT09IHdpbmRvdy50b3A7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxufTtcblxuLy8gRnJvbSBodHRwOi8vZ29vLmdsLzRXWDN0Z1xuVXRpbC5nZXRRdWVyeVBhcmFtZXRlciA9IGZ1bmN0aW9uKG5hbWUpIHtcbiAgbmFtZSA9IG5hbWUucmVwbGFjZSgvW1xcW10vLCBcIlxcXFxbXCIpLnJlcGxhY2UoL1tcXF1dLywgXCJcXFxcXVwiKTtcbiAgdmFyIHJlZ2V4ID0gbmV3IFJlZ0V4cChcIltcXFxcPyZdXCIgKyBuYW1lICsgXCI9KFteJiNdKilcIiksXG4gICAgICByZXN1bHRzID0gcmVnZXguZXhlYyhsb2NhdGlvbi5zZWFyY2gpO1xuICByZXR1cm4gcmVzdWx0cyA9PT0gbnVsbCA/IFwiXCIgOiBkZWNvZGVVUklDb21wb25lbnQocmVzdWx0c1sxXS5yZXBsYWNlKC9cXCsvZywgXCIgXCIpKTtcbn07XG5cblxuLy8gRnJvbSBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzExODcxMDc3L3Byb3Blci13YXktdG8tZGV0ZWN0LXdlYmdsLXN1cHBvcnQuXG5VdGlsLmlzV2ViR0xFbmFibGVkID0gZnVuY3Rpb24oKSB7XG4gIHZhciBjYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTtcbiAgdHJ5IHsgZ2wgPSBjYW52YXMuZ2V0Q29udGV4dChcIndlYmdsXCIpOyB9XG4gIGNhdGNoICh4KSB7IGdsID0gbnVsbDsgfVxuXG4gIGlmIChnbCA9PSBudWxsKSB7XG4gICAgdHJ5IHsgZ2wgPSBjYW52YXMuZ2V0Q29udGV4dChcImV4cGVyaW1lbnRhbC13ZWJnbFwiKTsgZXhwZXJpbWVudGFsID0gdHJ1ZTsgfVxuICAgIGNhdGNoICh4KSB7IGdsID0gbnVsbDsgfVxuICB9XG4gIHJldHVybiAhIWdsO1xufTtcblxuVXRpbC5jbG9uZSA9IGZ1bmN0aW9uKG9iaikge1xuICByZXR1cm4gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShvYmopKTtcbn07XG5cbi8vIEZyb20gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8xMDE0MDYwNC9mYXN0ZXN0LWh5cG90ZW51c2UtaW4tamF2YXNjcmlwdFxuVXRpbC5oeXBvdCA9IE1hdGguaHlwb3QgfHwgZnVuY3Rpb24oeCwgeSkge1xuICByZXR1cm4gTWF0aC5zcXJ0KHgqeCArIHkqeSk7XG59O1xuXG4vLyBGcm9tIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9hLzE3NDQ3NzE4LzY5MzkzNFxuVXRpbC5pc0lFMTEgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL1RyaWRlbnQvKTtcbn07XG5cblV0aWwuZ2V0UmVjdENlbnRlciA9IGZ1bmN0aW9uKHJlY3QpIHtcbiAgcmV0dXJuIG5ldyBUSFJFRS5WZWN0b3IyKHJlY3QueCArIHJlY3Qud2lkdGgvMiwgcmVjdC55ICsgcmVjdC5oZWlnaHQvMik7XG59O1xuXG5VdGlsLmdldFNjcmVlbldpZHRoID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiBNYXRoLm1heCh3aW5kb3cuc2NyZWVuLndpZHRoLCB3aW5kb3cuc2NyZWVuLmhlaWdodCkgKlxuICAgICAgd2luZG93LmRldmljZVBpeGVsUmF0aW87XG59O1xuXG5VdGlsLmdldFNjcmVlbkhlaWdodCA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gTWF0aC5taW4od2luZG93LnNjcmVlbi53aWR0aCwgd2luZG93LnNjcmVlbi5oZWlnaHQpICpcbiAgICAgIHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvO1xufTtcblxuVXRpbC5pc0lPUzlPckxlc3MgPSBmdW5jdGlvbigpIHtcbiAgaWYgKCFVdGlsLmlzSU9TKCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgdmFyIHJlID0gLyhpUGhvbmV8aVBhZHxpUG9kKSBPUyAoW1xcZF9dKykvO1xuICB2YXIgaU9TVmVyc2lvbiA9IG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2gocmUpO1xuICBpZiAoIWlPU1ZlcnNpb24pIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgLy8gR2V0IHRoZSBsYXN0IGdyb3VwLlxuICB2YXIgdmVyc2lvblN0cmluZyA9IGlPU1ZlcnNpb25baU9TVmVyc2lvbi5sZW5ndGggLSAxXTtcbiAgdmFyIG1ham9yVmVyc2lvbiA9IHBhcnNlRmxvYXQodmVyc2lvblN0cmluZyk7XG4gIHJldHVybiBtYWpvclZlcnNpb24gPD0gOTtcbn07XG5cblV0aWwuZ2V0RXh0ZW5zaW9uID0gZnVuY3Rpb24odXJsKSB7XG4gIHJldHVybiB1cmwuc3BsaXQoJy4nKS5wb3AoKTtcbn07XG5cblV0aWwuY3JlYXRlR2V0UGFyYW1zID0gZnVuY3Rpb24ocGFyYW1zKSB7XG4gIHZhciBvdXQgPSAnPyc7XG4gIGZvciAodmFyIGsgaW4gcGFyYW1zKSB7XG4gICAgdmFyIHBhcmFtU3RyaW5nID0gayArICc9JyArIHBhcmFtc1trXSArICcmJztcbiAgICBvdXQgKz0gcGFyYW1TdHJpbmc7XG4gIH1cbiAgLy8gUmVtb3ZlIHRoZSB0cmFpbGluZyBhbXBlcnNhbmQuXG4gIG91dC5zdWJzdHJpbmcoMCwgcGFyYW1zLmxlbmd0aCAtIDIpO1xuICByZXR1cm4gb3V0O1xufTtcblxuVXRpbC5zZW5kUGFyZW50TWVzc2FnZSA9IGZ1bmN0aW9uKG1lc3NhZ2UpIHtcbiAgaWYgKHdpbmRvdy5wYXJlbnQpIHtcbiAgICBwYXJlbnQucG9zdE1lc3NhZ2UobWVzc2FnZSwgJyonKTtcbiAgfVxufTtcblxuVXRpbC5wYXJzZUJvb2xlYW4gPSBmdW5jdGlvbih2YWx1ZSkge1xuICBpZiAodmFsdWUgPT0gJ2ZhbHNlJyB8fCB2YWx1ZSA9PSAwKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9IGVsc2UgaWYgKHZhbHVlID09ICd0cnVlJyB8fCB2YWx1ZSA9PSAxKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuICEhdmFsdWU7XG4gIH1cbn07XG5cbi8qKlxuICogQHBhcmFtIGJhc2Uge1N0cmluZ30gQW4gYWJzb2x1dGUgZGlyZWN0b3J5IHJvb3QuXG4gKiBAcGFyYW0gcmVsYXRpdmUge1N0cmluZ30gQSByZWxhdGl2ZSBwYXRoLlxuICpcbiAqIEByZXR1cm5zIHtTdHJpbmd9IEFuIGFic29sdXRlIHBhdGggY29ycmVzcG9uZGluZyB0byB0aGUgcm9vdFBhdGguXG4gKlxuICogRnJvbSBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8xNDc4MDQ2My82OTM5MzQuXG4gKi9cblV0aWwucmVsYXRpdmVUb0Fic29sdXRlUGF0aCA9IGZ1bmN0aW9uKGJhc2UsIHJlbGF0aXZlKSB7XG4gIHZhciBzdGFjayA9IGJhc2Uuc3BsaXQoJy8nKTtcbiAgdmFyIHBhcnRzID0gcmVsYXRpdmUuc3BsaXQoJy8nKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBwYXJ0cy5sZW5ndGg7IGkrKykge1xuICAgIGlmIChwYXJ0c1tpXSA9PSAnLicpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBpZiAocGFydHNbaV0gPT0gJy4uJykge1xuICAgICAgc3RhY2sucG9wKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0YWNrLnB1c2gocGFydHNbaV0pO1xuICAgIH1cbiAgfVxuICByZXR1cm4gc3RhY2suam9pbignLycpO1xufTtcblxuLyoqXG4gKiBAcmV0dXJuIHtCb29sZWFufSBUcnVlIGlmZiB0aGUgc3BlY2lmaWVkIHBhdGggaXMgYW4gYWJzb2x1dGUgcGF0aC5cbiAqL1xuVXRpbC5pc1BhdGhBYnNvbHV0ZSA9IGZ1bmN0aW9uKHBhdGgpIHtcbiAgcmV0dXJuICEgL14oPzpcXC98W2Etel0rOlxcL1xcLykvLnRlc3QocGF0aCk7XG59XG5cblV0aWwuaXNFbXB0eU9iamVjdCA9IGZ1bmN0aW9uKG9iaikge1xuICByZXR1cm4gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMob2JqKS5sZW5ndGggPT0gMDtcbn07XG5cblV0aWwuaXNEZWJ1ZyA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gVXRpbC5wYXJzZUJvb2xlYW4oVXRpbC5nZXRRdWVyeVBhcmFtZXRlcignZGVidWcnKSk7XG59O1xuXG5VdGlsLmdldEN1cnJlbnRTY3JpcHQgPSBmdW5jdGlvbigpIHtcbiAgLy8gTm90ZTogaW4gSUUxMSwgZG9jdW1lbnQuY3VycmVudFNjcmlwdCBkb2Vzbid0IHdvcmssIHNvIHdlIGZhbGwgYmFjayB0byB0aGlzXG4gIC8vIGhhY2ssIHRha2VuIGZyb20gaHR0cHM6Ly9nb28uZ2wvVHBFeHVILlxuICBpZiAoIWRvY3VtZW50LmN1cnJlbnRTY3JpcHQpIHtcbiAgICBjb25zb2xlLndhcm4oJ1RoaXMgYnJvd3NlciBkb2VzIG5vdCBzdXBwb3J0IGRvY3VtZW50LmN1cnJlbnRTY3JpcHQuIFRyeWluZyBmYWxsYmFjay4nKTtcbiAgfVxuICByZXR1cm4gZG9jdW1lbnQuY3VycmVudFNjcmlwdCB8fCBkb2N1bWVudC5zY3JpcHRzW2RvY3VtZW50LnNjcmlwdHMubGVuZ3RoIC0gMV07XG59XG5cblxubW9kdWxlLmV4cG9ydHMgPSBVdGlsO1xuIiwiLy8gc2hpbSBmb3IgdXNpbmcgcHJvY2VzcyBpbiBicm93c2VyXG5cbnZhciBwcm9jZXNzID0gbW9kdWxlLmV4cG9ydHMgPSB7fTtcbnZhciBxdWV1ZSA9IFtdO1xudmFyIGRyYWluaW5nID0gZmFsc2U7XG52YXIgY3VycmVudFF1ZXVlO1xudmFyIHF1ZXVlSW5kZXggPSAtMTtcblxuZnVuY3Rpb24gY2xlYW5VcE5leHRUaWNrKCkge1xuICAgIGRyYWluaW5nID0gZmFsc2U7XG4gICAgaWYgKGN1cnJlbnRRdWV1ZS5sZW5ndGgpIHtcbiAgICAgICAgcXVldWUgPSBjdXJyZW50UXVldWUuY29uY2F0KHF1ZXVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBxdWV1ZUluZGV4ID0gLTE7XG4gICAgfVxuICAgIGlmIChxdWV1ZS5sZW5ndGgpIHtcbiAgICAgICAgZHJhaW5RdWV1ZSgpO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gZHJhaW5RdWV1ZSgpIHtcbiAgICBpZiAoZHJhaW5pbmcpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB2YXIgdGltZW91dCA9IHNldFRpbWVvdXQoY2xlYW5VcE5leHRUaWNrKTtcbiAgICBkcmFpbmluZyA9IHRydWU7XG5cbiAgICB2YXIgbGVuID0gcXVldWUubGVuZ3RoO1xuICAgIHdoaWxlKGxlbikge1xuICAgICAgICBjdXJyZW50UXVldWUgPSBxdWV1ZTtcbiAgICAgICAgcXVldWUgPSBbXTtcbiAgICAgICAgd2hpbGUgKCsrcXVldWVJbmRleCA8IGxlbikge1xuICAgICAgICAgICAgaWYgKGN1cnJlbnRRdWV1ZSkge1xuICAgICAgICAgICAgICAgIGN1cnJlbnRRdWV1ZVtxdWV1ZUluZGV4XS5ydW4oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBxdWV1ZUluZGV4ID0gLTE7XG4gICAgICAgIGxlbiA9IHF1ZXVlLmxlbmd0aDtcbiAgICB9XG4gICAgY3VycmVudFF1ZXVlID0gbnVsbDtcbiAgICBkcmFpbmluZyA9IGZhbHNlO1xuICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbn1cblxucHJvY2Vzcy5uZXh0VGljayA9IGZ1bmN0aW9uIChmdW4pIHtcbiAgICB2YXIgYXJncyA9IG5ldyBBcnJheShhcmd1bWVudHMubGVuZ3RoIC0gMSk7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBhcmdzW2kgLSAxXSA9IGFyZ3VtZW50c1tpXTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBxdWV1ZS5wdXNoKG5ldyBJdGVtKGZ1biwgYXJncykpO1xuICAgIGlmIChxdWV1ZS5sZW5ndGggPT09IDEgJiYgIWRyYWluaW5nKSB7XG4gICAgICAgIHNldFRpbWVvdXQoZHJhaW5RdWV1ZSwgMCk7XG4gICAgfVxufTtcblxuLy8gdjggbGlrZXMgcHJlZGljdGlibGUgb2JqZWN0c1xuZnVuY3Rpb24gSXRlbShmdW4sIGFycmF5KSB7XG4gICAgdGhpcy5mdW4gPSBmdW47XG4gICAgdGhpcy5hcnJheSA9IGFycmF5O1xufVxuSXRlbS5wcm90b3R5cGUucnVuID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuZnVuLmFwcGx5KG51bGwsIHRoaXMuYXJyYXkpO1xufTtcbnByb2Nlc3MudGl0bGUgPSAnYnJvd3Nlcic7XG5wcm9jZXNzLmJyb3dzZXIgPSB0cnVlO1xucHJvY2Vzcy5lbnYgPSB7fTtcbnByb2Nlc3MuYXJndiA9IFtdO1xucHJvY2Vzcy52ZXJzaW9uID0gJyc7IC8vIGVtcHR5IHN0cmluZyB0byBhdm9pZCByZWdleHAgaXNzdWVzXG5wcm9jZXNzLnZlcnNpb25zID0ge307XG5cbmZ1bmN0aW9uIG5vb3AoKSB7fVxuXG5wcm9jZXNzLm9uID0gbm9vcDtcbnByb2Nlc3MuYWRkTGlzdGVuZXIgPSBub29wO1xucHJvY2Vzcy5vbmNlID0gbm9vcDtcbnByb2Nlc3Mub2ZmID0gbm9vcDtcbnByb2Nlc3MucmVtb3ZlTGlzdGVuZXIgPSBub29wO1xucHJvY2Vzcy5yZW1vdmVBbGxMaXN0ZW5lcnMgPSBub29wO1xucHJvY2Vzcy5lbWl0ID0gbm9vcDtcblxucHJvY2Vzcy5iaW5kaW5nID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Byb2Nlc3MuYmluZGluZyBpcyBub3Qgc3VwcG9ydGVkJyk7XG59O1xuXG5wcm9jZXNzLmN3ZCA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuICcvJyB9O1xucHJvY2Vzcy5jaGRpciA9IGZ1bmN0aW9uIChkaXIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Byb2Nlc3MuY2hkaXIgaXMgbm90IHN1cHBvcnRlZCcpO1xufTtcbnByb2Nlc3MudW1hc2sgPSBmdW5jdGlvbigpIHsgcmV0dXJuIDA7IH07XG4iXX0=