var C;!function(C){C.LOAD="LOAD",C.EXEC="EXEC",C.WRITE_FILE="WRITE_FILE",C.READ_FILE="READ_FILE",C.DELETE_FILE="DELETE_FILE",C.RENAME="RENAME",C.CREATE_DIR="CREATE_DIR",C.LIST_DIR="LIST_DIR",C.DELETE_DIR="DELETE_DIR",C.ERROR="ERROR",C.DOWNLOAD="DOWNLOAD",C.PROGRESS="PROGRESS",C.LOG="LOG",C.MOUNT="MOUNT",C.UNMOUNT="UNMOUNT"}(C||(C={}));const l=(()=>{let C=0;return()=>C++})(),g=new Error("ffmpeg is not loaded, call `await ffmpeg.load()` first"),Z=new Error("called FFmpeg.terminate()");var J="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function c(C,l,g){return C(g={path:l,exports:{},require:function(C,l){return function(){throw new Error("Dynamic requires are not currently supported by @rollup/plugin-commonjs")}(null==l&&g.path)}},g.exports),g.exports}var I=c((function(C,l){Object.defineProperty(l,"__esModule",{value:!0}),l.ERROR_INCOMPLETED_DOWNLOAD=l.ERROR_RESPONSE_BODY_READER=void 0,l.ERROR_RESPONSE_BODY_READER=new Error("failed to get response body reader"),l.ERROR_INCOMPLETED_DOWNLOAD=new Error("failed to complete download")})),G=c((function(C,l){Object.defineProperty(l,"__esModule",{value:!0}),l.HeaderContentLength=void 0,l.HeaderContentLength="Content-Length"})),m=c((function(C,l){var g=J&&J.__awaiter||function(C,l,g,Z){return new(g||(g=Promise))((function(J,c){function I(C){try{m(Z.next(C))}catch(C){c(C)}}function G(C){try{m(Z.throw(C))}catch(C){c(C)}}function m(C){var l;C.done?J(C.value):(l=C.value,l instanceof g?l:new g((function(C){C(l)}))).then(I,G)}m((Z=Z.apply(C,l||[])).next())}))};Object.defineProperty(l,"__esModule",{value:!0}),l.toBlobURL=l.downloadWithProgress=l.importScript=l.fetchFile=void 0;l.fetchFile=C=>g(void 0,void 0,void 0,(function*(){let l;if("string"==typeof C)l=/data:_data\/([a-zA-Z]*);base64,([^"]*)/.test(C)?atob(C.split(",")[1]).split("").map((C=>C.charCodeAt(0))):yield(yield fetch(C)).arrayBuffer();else if(C instanceof URL)l=yield(yield fetch(C)).arrayBuffer();else{if(!(C instanceof File||C instanceof Blob))return new Uint8Array;l=yield(g=C,new Promise(((C,l)=>{const Z=new FileReader;Z.onload=()=>{const{result:l}=Z;l instanceof ArrayBuffer?C(new Uint8Array(l)):C(new Uint8Array)},Z.onerror=C=>{var g,Z;l(Error(`File could not be read! Code=${(null===(Z=null===(g=null==C?void 0:C.target)||void 0===g?void 0:g.error)||void 0===Z?void 0:Z.code)||-1}`))},Z.readAsArrayBuffer(g)})))}var g;return new Uint8Array(l)}));l.importScript=C=>g(void 0,void 0,void 0,(function*(){return new Promise((l=>{const g=document.createElement("script"),Z=()=>{g.removeEventListener("load",Z),l()};g.src=C,g.type="text/javascript",g.addEventListener("load",Z),document.getElementsByTagName("head")[0].appendChild(g)}))}));l.downloadWithProgress=(C,l)=>g(void 0,void 0,void 0,(function*(){var g;const Z=yield fetch(C);let J;try{const c=parseInt(Z.headers.get(G.HeaderContentLength)||"-1"),m=null===(g=Z.body)||void 0===g?void 0:g.getReader();if(!m)throw I.ERROR_RESPONSE_BODY_READER;const d=[];let b=0;for(;;){const{done:g,value:Z}=yield m.read(),J=Z?Z.length:0;if(g){if(-1!=c&&c!==b)throw I.ERROR_INCOMPLETED_DOWNLOAD;l&&l({url:C,total:c,received:b,delta:J,done:g});break}d.push(Z),b+=J,l&&l({url:C,total:c,received:b,delta:J,done:g})}const W=new Uint8Array(b);let X=0;for(const C of d)W.set(C,X),X+=C.length;J=W.buffer}catch(g){console.log("failed to send download progress event: ",g),J=yield Z.arrayBuffer(),l&&l({url:C,total:J.byteLength,received:J.byteLength,delta:0,done:!0})}return J}));l.toBlobURL=(C,Z,J=!1,c)=>g(void 0,void 0,void 0,(function*(){const g=J?yield(0,l.downloadWithProgress)(C,c):yield(yield fetch(C)).arrayBuffer(),I=new Blob([g],{type:Z});return URL.createObjectURL(I)}))}));const d=globalThis.showSaveFilePicker;globalThis.DataTransferItem&&!DataTransferItem.prototype.getAsFileSystemHandle&&(DataTransferItem.prototype.getAsFileSystemHandle=async function(){const C=this.webkitGetAsEntry(),[{FileHandle:l,FolderHandle:g},{FileSystemDirectoryHandle:Z},{FileSystemFileHandle:J}]=await Promise.all([import("./DOk8TlOo.js"),Promise.resolve().then((function(){return B})),Promise.resolve().then((function(){return n}))]);return C.isFile?new J(new l(C,!1)):new Z(new g(C,!1))});const b={ReadableStream:globalThis.ReadableStream,WritableStream:globalThis.WritableStream,TransformStream:globalThis.TransformStream,DOMException:globalThis.DOMException,Blob:globalThis.Blob,File:globalThis.File},{WritableStream:W}=b;class X extends W{#C;constructor(C){super(C),this.#C=C,Object.setPrototypeOf(this,X.prototype),this._closed=!1}async close(){this._closed=!0;const C=this.getWriter(),l=C.close();return C.releaseLock(),l}seek(C){return this.write({type:"seek",position:C})}truncate(C){return this.write({type:"truncate",size:C})}write(C){if(this._closed)return Promise.reject(new TypeError("Cannot write to a CLOSED writable stream"));const l=this.getWriter(),g=l.write(C);return l.releaseLock(),g}}Object.defineProperty(X.prototype,Symbol.toStringTag,{value:"FileSystemWritableFileStream",writable:!1,enumerable:!1,configurable:!0}),Object.defineProperties(X.prototype,{close:{enumerable:!0},seek:{enumerable:!0},truncate:{enumerable:!0},write:{enumerable:!0}}),!globalThis.FileSystemFileHandle||globalThis.FileSystemFileHandle.prototype.createWritable||globalThis.FileSystemWritableFileStream||(globalThis.FileSystemWritableFileStream=X);const V=Symbol("adapter");class y{[V];name;kind;constructor(C){this.kind=C.kind,this.name=C.name,this[V]=C}async queryPermission(C={}){const{mode:l="read"}=C,g=this[V];if(g.queryPermission)return g.queryPermission({mode:l});if("read"===l)return"granted";if("readwrite"===l)return g.writable?"granted":"denied";throw new TypeError(`Mode ${l} must be 'read' or 'readwrite'`)}async requestPermission({mode:C="read"}={}){const l=this[V];if(l.requestPermission)return l.requestPermission({mode:C});if("read"===C)return"granted";if("readwrite"===C)return l.writable?"granted":"denied";throw new TypeError(`Mode ${C} must be 'read' or 'readwrite'`)}async remove(C={}){await this[V].remove(C)}async isSameEntry(C){return this===C||!(!C||"object"!=typeof C||this.kind!==C.kind||!C[V])&&this[V].isSameEntry(C[V])}}Object.defineProperty(y.prototype,Symbol.toStringTag,{value:"FileSystemHandle",writable:!1,enumerable:!1,configurable:!0}),globalThis.FileSystemHandle&&(globalThis.FileSystemHandle.prototype.queryPermission??=function(C){return"granted"});const k={INVALID:["seeking position failed.","InvalidStateError"],GONE:["A requested file or directory could not be found at the time an operation was processed.","NotFoundError"],MISMATCH:["The path supplied exists, but was not an entry of requested type.","TypeMismatchError"],MOD_ERR:["The object can not be modified in this way.","InvalidModificationError"],SYNTAX:C=>[`Failed to execute 'write' on 'UnderlyingSinkBase': Invalid params passed. ${C}`,"SyntaxError"],SECURITY:["It was determined that certain files are unsafe for access within a Web application, or that too many calls are being made on file resources.","SecurityError"],DISALLOWED:["The request is not allowed by the user agent or the platform in the current context.","NotAllowedError"]},{GONE:R,MOD_ERR:a}=k,h=Symbol("adapter");let o=class C extends y{[h];constructor(C){super(C),this[h]=C}async getDirectoryHandle(l,g={}){if(""===l)throw new TypeError("Name can't be an empty string.");if("."===l||".."===l||l.includes("/"))throw new TypeError("Name contains invalid characters.");g.create=!!g.create;const Z=await this[h].getDirectoryHandle(l,g);return new C(Z)}async*entries(){const{FileSystemFileHandle:l}=await Promise.resolve().then((function(){return n}));for await(const[g,Z]of this[h].entries())yield[Z.name,"file"===Z.kind?new l(Z):new C(Z)]}async*getEntries(){const{FileSystemFileHandle:l}=await Promise.resolve().then((function(){return n}));console.warn("deprecated, use .entries() instead");for await(let g of this[h].entries())yield"file"===g.kind?new l(g):new C(g)}async getFileHandle(C,l={}){const{FileSystemFileHandle:g}=await Promise.resolve().then((function(){return n}));if(""===C)throw new TypeError("Name can't be an empty string.");if("."===C||".."===C||C.includes("/"))throw new TypeError("Name contains invalid characters.");l.create=!!l.create;return new g(await this[h].getFileHandle(C,l))}async removeEntry(C,l={}){if(""===C)throw new TypeError("Name can't be an empty string.");if("."===C||".."===C||C.includes("/"))throw new TypeError("Name contains invalid characters.");return l.recursive=!!l.recursive,this[h].removeEntry(C,l)}async resolve(C){if(await C.isSameEntry(this))return[];const l=[{handle:this,path:[]}];for(;l.length;){let{handle:g,path:Z}=l.pop();for await(const J of g.values()){if(await J.isSameEntry(C))return[...Z,J.name];"directory"===J.kind&&l.push({handle:J,path:[...Z,J.name]})}}return null}async*keys(){for await(const[C]of this[h].entries())yield C}async*values(){for await(const[C,l]of this)yield l}[Symbol.asyncIterator](){return this.entries()}};if(Object.defineProperty(o.prototype,Symbol.toStringTag,{value:"FileSystemDirectoryHandle",writable:!1,enumerable:!1,configurable:!0}),Object.defineProperties(o.prototype,{getDirectoryHandle:{enumerable:!0},entries:{enumerable:!0},getFileHandle:{enumerable:!0},removeEntry:{enumerable:!0}}),globalThis.FileSystemDirectoryHandle){const U=globalThis.FileSystemDirectoryHandle.prototype;async function v(C){const l=await navigator.storage.getDirectory();if(null===await l.resolve(C))throw new DOMException(...R)}U.resolve=async function(C){if(await C.isSameEntry(this))return[];const l=[{handle:this,path:[]}];for(;l.length;){let{handle:g,path:Z}=l.pop();for await(const J of g.values()){if(await J.isSameEntry(C))return[...Z,J.name];"directory"===J.kind&&l.push({handle:J,path:[...Z,J.name]})}}return null};const M=U.entries;U.entries=async function*(){await v(this),yield*M.call(this)},U[Symbol.asyncIterator]=async function*(){yield*this.entries()};const D=U.removeEntry;U.removeEntry=async function(C,l={}){return D.call(this,C,l).catch((async C=>{if(C instanceof DOMException&&"UnknownError"===C.name&&!l.recursive){if(!(await M.call(this).next()).done)throw new DOMException(...a)}throw C}))}}var B=Object.freeze({__proto__:null,FileSystemDirectoryHandle:o,default:o});const{INVALID:Y,SYNTAX:Q,GONE:K}=k,p=Symbol("adapter");class u extends y{[p];constructor(C){super(C),this[p]=C}async createWritable(C={}){return new X(await this[p].createWritable(C))}async getFile(){return this[p].getFile()}}if(Object.defineProperty(u.prototype,Symbol.toStringTag,{value:"FileSystemFileHandle",writable:!1,enumerable:!1,configurable:!0}),Object.defineProperties(u.prototype,{createWritable:{enumerable:!0},getFile:{enumerable:!0}}),globalThis.FileSystemFileHandle&&!globalThis.FileSystemFileHandle.prototype.createWritable){const T=new WeakMap;let x;const O=()=>{let C,l;onmessage=async g=>{const Z=g.ports[0],J=g.data;switch(J.type){case"open":const g=J.name;let Z=await navigator.storage.getDirectory();for(const C of J.path)Z=await Z.getDirectoryHandle(C);C=await Z.getFileHandle(g),l=await C.createSyncAccessHandle();break;case"write":l.write(J.data,{at:J.position}),l.flush();break;case"truncate":l.truncate(J.size);break;case"abort":case"close":l.close()}Z.postMessage(0)}};globalThis.FileSystemFileHandle.prototype.createWritable=async function(C){if(!x){const C=`(${O.toString()})()`,l=new Blob([C],{type:"text/javascript"});x=URL.createObjectURL(l)}const l=new Worker(x,{type:"module"});let g=0;const Z=new TextEncoder;let J=await this.getFile().then((C=>C.size));const c=C=>new Promise(((g,Z)=>{const J=new MessageChannel;J.port1.onmessage=C=>{C.data instanceof Error?Z(C.data):g(C.data),J.port1.close(),J.port2.close(),J.port1.onmessage=null},l.postMessage(C,[J.port2])})),I=await navigator.storage.getDirectory(),G=await T.get(this),m=await I.resolve(G);if(null===m)throw new DOMException(...K);await c({type:"open",path:m,name:this.name}),!1===C?.keepExistingData&&(await c({type:"truncate",size:0}),J=0);return new X({start:C=>{},async write(C){if("write"===(C=C?.constructor===Object?{...C}:{type:"write",data:C,position:g}).type){if(!("data"in C))throw await c({type:"close"}),new DOMException(...Q("write requires a data argument"));if(C.position??=g,"string"==typeof C.data)C.data=Z.encode(C.data);else if(C.data instanceof ArrayBuffer)C.data=new Uint8Array(C.data);else if(C.data instanceof Uint8Array||!ArrayBuffer.isView(C.data)){if(!(C.data instanceof Uint8Array)){const l=await new Response(C.data).arrayBuffer();C.data=new Uint8Array(l)}}else C.data=new Uint8Array(C.data.buffer,C.data.byteOffset,C.data.byteLength);Number.isInteger(C.position)&&C.position>=0&&(g=C.position),g+=C.data.byteLength,J+=C.data.byteLength}else{if("seek"===C.type){if(Number.isInteger(C.position)&&C.position>=0){if(J=0))throw await c({type:"close"}),new DOMException(...Q("truncate requires a size argument"));J=C.size,g>J&&(g=J)}}await c(C)},async close(){await c({type:"close"}),l.terminate()},async abort(C){await c({type:"abort",reason:C}),l.terminate()}})};const f=FileSystemDirectoryHandle.prototype.getFileHandle;FileSystemDirectoryHandle.prototype.getFileHandle=async function(...C){const l=await f.call(this,...C);return T.set(l,this),l}}var n=Object.freeze({__proto__:null,FileSystemFileHandle:u,default:u}),F=null;try{var S="undefined"!=typeof module&&"function"==typeof module.require&&module.require("worker_threads")||"function"==typeof __non_webpack_require__&&__non_webpack_require__("worker_threads")||"function"==typeof require&&require("worker_threads");F=S.Worker}catch(E){}function H(C,l,g){var Z=function(C){return Buffer.from(C,"base64").toString("utf8")}(C),J=Z.indexOf("\n",10)+1,c=Z.substring(J)+"";return function(C){return new F(c,Object.assign({},C,{eval:!0}))}}function i(C,l,g){var Z=function(C){return atob(C)}(C),J=Z.indexOf("\n",10)+1,c=Z.substring(J)+"",I=new Blob([c],{type:"application/javascript"});return URL.createObjectURL(I)}var s="[object process]"===Object.prototype.toString.call("undefined"!=typeof process?process:0);function N(C,l,g){return s?H(C):function(C){var l;return function(g){return l=l||i(C),new Worker(l,g)}}(C)}var A=N("Lyogcm9sbHVwLXBsdWdpbi13ZWItd29ya2VyLWxvYWRlciAqLwooZnVuY3Rpb24gKCkgewogICd1c2Ugc3RyaWN0JzsKCiAgY2xhc3MgQ2FudmFzMkRSZW5kZXJlciB7DQogICAgY2FudmFzID0gbnVsbDsNCiAgICBjdHggPSBudWxsOw0KICAgIGdldFNob3dEYXRhID0gbnVsbDsNCiAgICBzdG9yYWdlID0gW107DQoNCiAgICBjb25zdHJ1Y3RvcihjYW52YXMsIGdldFNob3dEYXRhLCBvdXRwdXRMYXllciwgY3JvcEZ1bGxJbmZvKSB7DQogICAgICB0aGlzLmNhbnZhcyA9IGNhbnZhczsNCiAgICAgIHRoaXMuY3R4ID0gY2FudmFzLmdldENvbnRleHQoIjJkIik7DQogICAgICB0aGlzLmdldFNob3dEYXRhID0gZ2V0U2hvd0RhdGE7DQogICAgICB0aGlzLm91dHB1dExheWVyID0gb3V0cHV0TGF5ZXI7DQogICAgICB0aGlzLmNyb3BGdWxsSW5mbyA9IEpTT04ucGFyc2UoY3JvcEZ1bGxJbmZvKTsNCiAgICB9DQogICAgI0FycmF5c0FyZUVxdWFsKGFycjEsIGFycjIpIHsNCiAgICAgIGlmIChhcnIxLmxlbmd0aCAhPT0gYXJyMi5sZW5ndGgpIHsNCiAgICAgICAgcmV0dXJuIGZhbHNlOw0KICAgICAgfQ0KICAgICAgcmV0dXJuIGFycjEuZXZlcnkoZnVuY3Rpb24gKHZhbCwgaW5kZXgpIHsNCiAgICAgICAgcmV0dXJuIHZhbCA9PT0gYXJyMltpbmRleF07DQogICAgICB9KTsNCiAgICB9DQoNCiAgICAjRHJhd0JveChhcnIpIHsNCiAgICAgIGlmIChhcnIubGVuZ3RoKSB7DQogICAgICAgIHRoaXMuY3R4LnNhdmUoKTsNCiAgICAgICAgdGhpcy5jdHguc2V0VHJhbnNmb3JtKDEsIDAsIDAsIDEsIDAsIDApOyAvLyBSZXNldCB0cmFuc2Zvcm0gdG8gYXZvaWQgYWZmZWN0aW5nIGJveCBkcmF3aW5nDQogICAgICAgIHRoaXMuY3R4LnN0cm9rZVN0eWxlID0gInJlZCI7DQogICAgICAgIHRoaXMuY3R4LmxpbmVXaWR0aCA9IDEwOw0KICAgICAgICBpZiAodGhpcy5vdXRwdXRMYXllcikgew0KICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7DQogICAgICAgICAgICBsZXQgW3gsIHksIHcsIGhdID0gWw0KICAgICAgICAgICAgICBhcnJbaV1bMF0gKiAodGhpcy5jYW52YXMud2lkdGggLyB0aGlzLm91dHB1dExheWVyLldpZHRoTWFpbiksDQogICAgICAgICAgICAgIGFycltpXVsxXSAqICh0aGlzLmNhbnZhcy5oZWlnaHQgLyB0aGlzLm91dHB1dExheWVyLkhlaWdodE1haW4pLA0KICAgICAgICAgICAgICAoYXJyW2ldWzJdIC0gYXJyW2ldWzBdKSAqDQogICAgICAgICAgICAgICAgKHRoaXMuY2FudmFzLndpZHRoIC8gdGhpcy5vdXRwdXRMYXllci5XaWR0aE1haW4pLA0KICAgICAgICAgICAgICAoYXJyW2ldWzNdIC0gYXJyW2ldWzFdKSAqDQogICAgICAgICAgICAgICAgKHRoaXMuY2FudmFzLmhlaWdodCAvIHRoaXMub3V0cHV0TGF5ZXIuSGVpZ2h0TWFpbiksDQogICAgICAgICAgICBdOw0KICAgICAgICAgICAgdGhpcy5jdHguc3Ryb2tlUmVjdCh4LCB5LCB3LCBoKTsNCiAgICAgICAgICAgIHRoaXMuc3RvcmFnZSA9IFt4LCB5LCB3LCBoXTsNCiAgICAgICAgICB9DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJvdXRwdXRMYXllciBpcyBudWxsIik7DQogICAgICAgIH0NCiAgICAgICAgdGhpcy5jdHgucmVzdG9yZSgpOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgbGV0IFt4LCB5LCB3LCBoXSA9IHRoaXMuc3RvcmFnZTsNCiAgICAgICAgdGhpcy5jdHguc2F2ZSgpOw0KICAgICAgICB0aGlzLmN0eC5zZXRUcmFuc2Zvcm0oMSwgMCwgMCwgMSwgMCwgMCk7DQogICAgICAgIHRoaXMuY3R4LnN0cm9rZVN0eWxlID0gInRyYW5zcGFyZW50IjsNCiAgICAgICAgdGhpcy5jdHgubGluZVdpZHRoID0gMTA7DQogICAgICAgIHRoaXMuY3R4LnN0cm9rZVJlY3QoeCwgeSwgdywgaCk7DQogICAgICAgIHRoaXMuY3R4LnJlc3RvcmUoKTsNCiAgICAgIH0NCiAgICB9DQogICAgdGVtcCA9IG51bGw7DQogICAgZHJhdyhmcmFtZSkgew0KICAgICAgaWYgKHRoaXMuY3JvcEZ1bGxJbmZvLlVzZUNyb3ApIHsNCiAgICAgICAgdGhpcy5jYW52YXMud2lkdGggPSB0aGlzLmNyb3BGdWxsSW5mby5XOw0KICAgICAgICB0aGlzLmNhbnZhcy5oZWlnaHQgPSB0aGlzLmNyb3BGdWxsSW5mby5IOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgdGhpcy5jYW52YXMud2lkdGggPSBmcmFtZS5kaXNwbGF5V2lkdGg7DQogICAgICAgIHRoaXMuY2FudmFzLmhlaWdodCA9IGZyYW1lLmRpc3BsYXlIZWlnaHQ7DQogICAgICB9DQogICAgICB0aGlzLmN0eC5zYXZlKCk7DQogICAgICB0aGlzLmN0eC50cmFuc2xhdGUodGhpcy5jYW52YXMud2lkdGggLyAyLCB0aGlzLmNhbnZhcy5oZWlnaHQgLyAyKTsNCiAgICAgIGlmICghdGhpcy5jcm9wRnVsbEluZm8uVXNlUm90YXRlKSB7DQogICAgICAgIHRoaXMuY3R4LnJvdGF0ZSgwKTsNCiAgICAgICAgdGhpcy5jcm9wRnVsbEluZm8uUm90YXRlID0gMDsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIHRoaXMuY3R4LnJvdGF0ZSgodGhpcy5jcm9wRnVsbEluZm8uUm90YXRlIC8gOTApICogMS41Nyk7DQogICAgICB9DQoNCiAgICAgIHN3aXRjaCAodGhpcy5jcm9wRnVsbEluZm8uUm90YXRlKSB7DQogICAgICAgIGNhc2UgMDoNCiAgICAgICAgY2FzZSAxODA6DQogICAgICAgICAgdGhpcy5jdHguZHJhd0ltYWdlKA0KICAgICAgICAgICAgZnJhbWUsDQogICAgICAgICAgICB0aGlzLmNyb3BGdWxsSW5mby5Vc2VDcm9wDQogICAgICAgICAgICAgID8gLXRoaXMuY2FudmFzLndpZHRoIC8gMiAtIHRoaXMuY3JvcEZ1bGxJbmZvLlgNCiAgICAgICAgICAgICAgOiAtdGhpcy5jYW52YXMud2lkdGggLyAyLA0KICAgICAgICAgICAgdGhpcy5jcm9wRnVsbEluZm8uVXNlQ3JvcA0KICAgICAgICAgICAgICA/IC10aGlzLmNhbnZhcy5oZWlnaHQgLyAyIC0gdGhpcy5jcm9wRnVsbEluZm8uWQ0KICAgICAgICAgICAgICA6IC10aGlzLmNhbnZhcy5oZWlnaHQgLyAyLA0KICAgICAgICAgICAgZnJhbWUuZGlzcGxheVdpZHRoLA0KICAgICAgICAgICAgZnJhbWUuZGlzcGxheUhlaWdodA0KICAgICAgICAgICk7DQogICAgICAgICAgYnJlYWs7DQogICAgICAgIGNhc2UgOTA6DQogICAgICAgIGNhc2UgMjcwOg0KICAgICAgICAgIHRoaXMuY3R4LmRyYXdJbWFnZSgNCiAgICAgICAgICAgIGZyYW1lLA0KICAgICAgICAgICAgdGhpcy5jcm9wRnVsbEluZm8uVXNlQ3JvcA0KICAgICAgICAgICAgICA/IC10aGlzLmNhbnZhcy5oZWlnaHQgLyAyIC0gdGhpcy5jcm9wRnVsbEluZm8uWQ0KICAgICAgICAgICAgICA6IC10aGlzLmNhbnZhcy5oZWlnaHQgLyAyLA0KICAgICAgICAgICAgdGhpcy5jcm9wRnVsbEluZm8uVXNlQ3JvcA0KICAgICAgICAgICAgICA/IC10aGlzLmNhbnZhcy53aWR0aCAvIDIgLSB0aGlzLmNyb3BGdWxsSW5mby5YDQogICAgICAgICAgICAgIDogLXRoaXMuY2FudmFzLndpZHRoIC8gMiwNCiAgICAgICAgICAgIGZyYW1lLmRpc3BsYXlXaWR0aCwNCiAgICAgICAgICAgIGZyYW1lLmRpc3BsYXlIZWlnaHQNCiAgICAgICAgICApOw0KICAgICAgICAgIGJyZWFrOw0KICAgICAgfQ0KICAgICAgdGhpcy5jdHgucmVzdG9yZSgpOw0KDQogICAgICBpZiAoc2VsZi5HZXRJbWcpIHsNCiAgICAgICAgdGhpcy5jdHguY2FudmFzLmNvbnZlcnRUb0Jsb2IoKS50aGVuKChibG9iKSA9PiB7DQogICAgICAgICAgc2VsZi5wb3N0TWVzc2FnZSh7IGltZzogYmxvYiwgdHlwZTogImltZyIgfSk7DQogICAgICAgIH0pOw0KICAgICAgICBzZWxmLkdldEltZyA9IGZhbHNlOw0KICAgICAgfQ0KICAgICAgY29uc3Qgc2hvd0RhdGEgPSB0aGlzLmdldFNob3dEYXRhKCk7DQogICAgICBpZiAoc2hvd0RhdGEpIHsNCiAgICAgICAgdGhpcy4jRHJhd0JveChzaG93RGF0YSk7DQogICAgICB9DQogICAgICBmcmFtZS5jbG9zZSgpOw0KICAgIH0NCiAgfQoKICBzZWxmLkdldEltZyA9IGZhbHNlOw0KDQogIC8vIOa4suafkyzmr4/kuKrliqjnlLvluKflj6rog73nu5jliLbkuIDmrKENCiAgbGV0IHJlbmRlcmVyID0gbnVsbDsNCiAgbGV0IHNob3dEYXRhID0gbnVsbDsNCiAgY2xhc3MgUXVldWUgew0KICAgIGNvbnN0cnVjdG9yKCkgew0KICAgICAgdGhpcy5faXRlbXMgPSBbXTsNCiAgICB9DQoNCiAgICBlbnF1ZXVlKGl0ZW0pIHsNCiAgICAgIHRoaXMuX2l0ZW1zLnB1c2goaXRlbSk7DQogICAgfQ0KDQogICAgZGVxdWV1ZSgpIHsNCiAgICAgIHJldHVybiB0aGlzLl9pdGVtcy5zaGlmdCgpOw0KICAgIH0NCg0KICAgIGhlYWQoKSB7DQogICAgICByZXR1cm4gdGhpcy5faXRlbXNbMF07DQogICAgfQ0KDQogICAgdGFpbCgpIHsNCiAgICAgIHJldHVybiB0aGlzLl9pdGVtc1t0aGlzLl9pdGVtcy5sZW5ndGggLSAxXTsNCiAgICB9DQoNCiAgICBpc0VtcHR5KCkgew0KICAgICAgcmV0dXJuICF0aGlzLl9pdGVtcy5sZW5ndGg7DQogICAgfQ0KDQogICAgc2l6ZSgpIHsNCiAgICAgIHJldHVybiB0aGlzLl9pdGVtcy5sZW5ndGg7DQogICAgfQ0KDQogICAgY2xlYXIoKSB7DQogICAgICB0aGlzLl9pdGVtcyA9IFtdOw0KICAgIH0NCiAgfQ0KDQogIHZhciBGcmFtZUJ1ZmZlciA9IG5ldyBRdWV1ZSgpOw0KDQogIGZ1bmN0aW9uIHJlbmRlckZyYW1lKGZyYW1lKSB7DQogICAgRnJhbWVCdWZmZXIuZW5xdWV1ZShmcmFtZSk7DQogIH0NCg0KICBjb25zdCBkZWNvZGVyID0gbmV3IFZpZGVvRGVjb2Rlcih7DQogICAgb3V0cHV0KGZyYW1lKSB7DQogICAgICByZW5kZXJGcmFtZShmcmFtZSk7DQogICAgfSwNCiAgICBlcnJvcihlKSB7DQogICAgICBjb25zb2xlLmVycm9yKGUpOw0KICAgIH0sDQogIH0pOw0KDQogIHNldEludGVydmFsKGZ1bmN0aW9uICgpIHsNCiAgICBpZiAoRnJhbWVCdWZmZXIuc2l6ZSgpID4gMCkgew0KICAgICAgcmVuZGVyZXIuZHJhdyhGcmFtZUJ1ZmZlci5kZXF1ZXVlKCkpOw0KICAgIH0NCiAgfSwgMzkpOw0KDQogIGZ1bmN0aW9uIGdldFNob3dEYXRhKCkgew0KICAgIHJldHVybiBzaG93RGF0YTsNCiAgfQ0KDQogIHZhciBmbGFnUG9zdCA9IDA7DQogIHZhciBjcm9wRnVsbEluZm8gPSAiIjsNCiAgLy8gTGlzdGVuIGZvciB0aGUgc3RhcnQgcmVxdWVzdC4NCiAgc2VsZi5hZGRFdmVudExpc3RlbmVyKCJtZXNzYWdlIiwgKG1lc3NhZ2UpID0+IHsNCiAgICBsZXQge2NhbnZhcywgdHlwZSwgYmFzZVdIIH0gPSBtZXNzYWdlLmRhdGE7DQogICAgaWYgKHR5cGUgPT09ICJqdCIpIHsNCiAgICAgIHNlbGYuR2V0SW1nID0gdHJ1ZTsNCiAgICB9DQogICAgaWYgKG1lc3NhZ2UuZGF0YS5EYXRhVHlwZSA9PT0gIk9wdCIpIHsNCiAgICAgIGNyb3BGdWxsSW5mbyA9IG1lc3NhZ2UuZGF0YS5kYXRhOw0KICAgIH0NCiAgICBpZiAobWVzc2FnZS5kYXRhLkRhdGFUeXBlID09PSAiU3RhcnQiKSB7DQogICAgICBjb25zdCBiYXNlSW5mbyA9IGJhc2VXSCA/IEpTT04ucGFyc2UoYmFzZVdIKSA6IG51bGw7DQoNCiAgICAgIHJlbmRlcmVyID0gbmV3IENhbnZhczJEUmVuZGVyZXIoY2FudmFzLCBnZXRTaG93RGF0YSwgYmFzZUluZm8sIGNyb3BGdWxsSW5mbyk7DQogICAgICBpZiAoIVZpZGVvRGVjb2RlcikNCiAgICAgICAgdGhyb3cgbmV3IEVycm9yKA0KICAgICAgICAgICJUaGUgY3VycmVudCBicm93c2VyIGRvZXMgbm90IHN1cHBvcnQgdGhlIFZpZGVvRGVjb2RlciBBUEkiDQogICAgICAgICk7DQogICAgfQ0KICAgIGlmIChtZXNzYWdlLmRhdGEuRGF0YVR5cGUgPT09ICJUcmFjayIpIHsNCiAgICAgIGRlY29kZXIuY29uZmlndXJlKHsNCiAgICAgICAgY29kZWM6IG1lc3NhZ2UuZGF0YS5jb2RlYywNCiAgICAgICAgY29kZWRIZWlnaHQ6IG1lc3NhZ2UuZGF0YS5jb2RlZEhlaWdodCwNCiAgICAgICAgY29kZWRXaWR0aDogbWVzc2FnZS5kYXRhLmNvZGVkV2lkdGgsDQogICAgICAgIGRlc2NyaXB0aW9uOiBtZXNzYWdlLmRhdGEuZGVzY3JpcHRpb24sDQogICAgICB9KTsNCiAgICAgIGNvbnNvbGUubG9nKG1lc3NhZ2UuZGF0YSk7DQogICAgfQ0KICAgIGlmIChtZXNzYWdlLmRhdGEuRGF0YVR5cGUgPT09ICJTYW1wbGVzIikgew0KICAgICAgc2hvd0RhdGEgPSBtZXNzYWdlLmRhdGEuc2hvd0RhdGEgfHwgbnVsbDsNCiAgICAgIGRlY29kZXIuZGVjb2RlKA0KICAgICAgICBuZXcgRW5jb2RlZFZpZGVvQ2h1bmsoew0KICAgICAgICAgIHR5cGU6IG1lc3NhZ2UuZGF0YS50eXBlLA0KICAgICAgICAgIHRpbWVzdGFtcDogbWVzc2FnZS5kYXRhLnRpbWVzdGFtcCwNCiAgICAgICAgICBkdXJhdGlvbjogbWVzc2FnZS5kYXRhLmR1cmF0aW9uLA0KICAgICAgICAgIGRhdGE6IG1lc3NhZ2UuZGF0YS5kYXRhLA0KICAgICAgICB9KQ0KICAgICAgKTsNCiAgICAgIGlmIChmbGFnUG9zdCA9PT0gMykgew0KICAgICAgICB2YXIgY29ubmVjdCA9IHRydWU7DQogICAgICAgIHNlbGYucG9zdE1lc3NhZ2UoY29ubmVjdCk7DQogICAgICAgIGZsYWdQb3N0ID0gNDsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIGlmIChmbGFnUG9zdCA9PT0gNCkgcmV0dXJuOw0KICAgICAgICBmbGFnUG9zdCsrOw0KICAgICAgfQ0KICAgIH0NCiAgfSk7Cgp9KSgpOwovLyMgc291cmNlTWFwcGluZ1VSTD13b3JrZXIuanMubWFwCgo="),z=N("Lyogcm9sbHVwLXBsdWdpbi13ZWItd29ya2VyLWxvYWRlciAqLwooZnVuY3Rpb24gKCkgewoJJ3VzZSBzdHJpY3QnOwoKCWZ1bmN0aW9uIGNyZWF0ZUNvbW1vbmpzTW9kdWxlKGZuLCBiYXNlZGlyLCBtb2R1bGUpIHsKCQlyZXR1cm4gbW9kdWxlID0gewoJCSAgcGF0aDogYmFzZWRpciwKCQkgIGV4cG9ydHM6IHt9LAoJCSAgcmVxdWlyZTogZnVuY3Rpb24gKHBhdGgsIGJhc2UpIHsKCSAgICAgIHJldHVybiBjb21tb25qc1JlcXVpcmUocGF0aCwgKGJhc2UgPT09IHVuZGVmaW5lZCB8fCBiYXNlID09PSBudWxsKSA/IG1vZHVsZS5wYXRoIDogYmFzZSk7CgkgICAgfQoJCX0sIGZuKG1vZHVsZSwgbW9kdWxlLmV4cG9ydHMpLCBtb2R1bGUuZXhwb3J0czsKCX0KCglmdW5jdGlvbiBjb21tb25qc1JlcXVpcmUgKCkgewoJCXRocm93IG5ldyBFcnJvcignRHluYW1pYyByZXF1aXJlcyBhcmUgbm90IGN1cnJlbnRseSBzdXBwb3J0ZWQgYnkgQHJvbGx1cC9wbHVnaW4tY29tbW9uanMnKTsKCX0KCgl2YXIgbXA0Ym94X2FsbCA9IGNyZWF0ZUNvbW1vbmpzTW9kdWxlKGZ1bmN0aW9uIChtb2R1bGUsIGV4cG9ydHMpIHsKCS8vIGZpbGU6c3JjL2xvZy5qcwoJLyogCgkgKiBDb3B5cmlnaHQgKGMpIDIwMTItMjAxMy4gVGVsZWNvbSBQYXJpc1RlY2gvVFNJL01NL0dQQUMgQ3lyaWwgQ29uY29sYXRvCgkgKiBMaWNlbnNlOiBCU0QtMy1DbGF1c2UgKHNlZSBMSUNFTlNFIGZpbGUpCgkgKi8KCXZhciBMb2cgPSAoZnVuY3Rpb24gKCl7CgkJCXZhciBzdGFydCA9IG5ldyBEYXRlKCk7CgkJCXZhciBMT0dfTEVWRUxfRVJST1IgCT0gNDsKCQkJdmFyIExPR19MRVZFTF9XQVJOSU5HIAk9IDM7CgkJCXZhciBMT0dfTEVWRUxfSU5GTyAJCT0gMjsKCQkJdmFyIExPR19MRVZFTF9ERUJVRwkJPSAxOwoJCQl2YXIgbG9nX2xldmVsID0gTE9HX0xFVkVMX0VSUk9SOwoJCQl2YXIgbG9nT2JqZWN0ID0gewoJCQkJc2V0TG9nTGV2ZWwgOiBmdW5jdGlvbihsZXZlbCkgewoJCQkJCWlmIChsZXZlbCA9PSB0aGlzLmRlYnVnKSBsb2dfbGV2ZWwgPSBMT0dfTEVWRUxfREVCVUc7CgkJCQkJZWxzZSBpZiAobGV2ZWwgPT0gdGhpcy5pbmZvKSBsb2dfbGV2ZWwgPSBMT0dfTEVWRUxfSU5GTzsKCQkJCQllbHNlIGlmIChsZXZlbCA9PSB0aGlzLndhcm4pIGxvZ19sZXZlbCA9IExPR19MRVZFTF9XQVJOSU5HOwoJCQkJCWVsc2UgaWYgKGxldmVsID09IHRoaXMuZXJyb3IpIGxvZ19sZXZlbCA9IExPR19MRVZFTF9FUlJPUjsKCQkJCQllbHNlIGxvZ19sZXZlbCA9IExPR19MRVZFTF9FUlJPUjsKCQkJCX0sCgkJCQlkZWJ1ZyA6IGZ1bmN0aW9uKG1vZHVsZSwgbXNnKSB7CgkJCQkJaWYgKGNvbnNvbGUuZGVidWcgPT09IHVuZGVmaW5lZCkgewoJCQkJCQljb25zb2xlLmRlYnVnID0gY29uc29sZS5sb2c7CgkJCQkJfQoJCQkJCWlmIChMT0dfTEVWRUxfREVCVUcgPj0gbG9nX2xldmVsKSB7CgkJCQkJCWNvbnNvbGUuZGVidWcoIlsiK0xvZy5nZXREdXJhdGlvblN0cmluZyhuZXcgRGF0ZSgpLXN0YXJ0LDEwMDApKyJdIiwiWyIrbW9kdWxlKyJdIixtc2cpOwoJCQkJCX0KCQkJCX0sCgkJCQlsb2cgOiBmdW5jdGlvbihtb2R1bGUsIG1zZykgewoJCQkJCXRoaXMuZGVidWcobW9kdWxlLm1zZyk7CgkJCQl9LAoJCQkJaW5mbyA6IGZ1bmN0aW9uKG1vZHVsZSwgbXNnKSB7CgkJCQkJaWYgKExPR19MRVZFTF9JTkZPID49IGxvZ19sZXZlbCkgewoJCQkJCQljb25zb2xlLmluZm8oIlsiK0xvZy5nZXREdXJhdGlvblN0cmluZyhuZXcgRGF0ZSgpLXN0YXJ0LDEwMDApKyJdIiwiWyIrbW9kdWxlKyJdIixtc2cpOwoJCQkJCX0KCQkJCX0sCgkJCQl3YXJuIDogZnVuY3Rpb24obW9kdWxlLCBtc2cpIHsKCQkJCQlpZiAoTE9HX0xFVkVMX1dBUk5JTkcgPj0gbG9nX2xldmVsKSB7CgkJCQkJCWNvbnNvbGUud2FybigiWyIrTG9nLmdldER1cmF0aW9uU3RyaW5nKG5ldyBEYXRlKCktc3RhcnQsMTAwMCkrIl0iLCJbIittb2R1bGUrIl0iLG1zZyk7CgkJCQkJfQoJCQkJfSwKCQkJCWVycm9yIDogZnVuY3Rpb24obW9kdWxlLCBtc2cpIHsKCQkJCQlpZiAoTE9HX0xFVkVMX0VSUk9SID49IGxvZ19sZXZlbCkgewoJCQkJCQljb25zb2xlLmVycm9yKCJbIitMb2cuZ2V0RHVyYXRpb25TdHJpbmcobmV3IERhdGUoKS1zdGFydCwxMDAwKSsiXSIsIlsiK21vZHVsZSsiXSIsbXNnKTsKCQkJCQl9CgkJCQl9CgkJCX07CgkJCXJldHVybiBsb2dPYmplY3Q7CgkJfSkoKTsKCQkKCS8qIEhlbHBlciBmdW5jdGlvbiB0byBwcmludCBhIGR1cmF0aW9uIHZhbHVlIGluIHRoZSBmb3JtIEg6TU06U1MuTVMgKi8KCUxvZy5nZXREdXJhdGlvblN0cmluZyA9IGZ1bmN0aW9uKGR1cmF0aW9uLCBfdGltZXNjYWxlKSB7CgkJdmFyIG5lZzsKCQkvKiBIZWxwZXIgZnVuY3Rpb24gdG8gcHJpbnQgYSBudW1iZXIgb24gYSBmaXhlZCBudW1iZXIgb2YgZGlnaXRzICovCgkJZnVuY3Rpb24gcGFkKG51bWJlciwgbGVuZ3RoKSB7CgkJCXZhciBzdHIgPSAnJyArIG51bWJlcjsKCQkJdmFyIGEgPSBzdHIuc3BsaXQoJy4nKTsJCQoJCQl3aGlsZSAoYVswXS5sZW5ndGggPCBsZW5ndGgpIHsKCQkJCWFbMF0gPSAnMCcgKyBhWzBdOwoJCQl9CgkJCXJldHVybiBhLmpvaW4oJy4nKTsKCQl9CgkJaWYgKGR1cmF0aW9uIDwgMCkgewoJCQluZWcgPSB0cnVlOwoJCQlkdXJhdGlvbiA9IC1kdXJhdGlvbjsKCQl9IGVsc2UgewoJCQluZWcgPSBmYWxzZTsJCgkJfQoJCXZhciB0aW1lc2NhbGUgPSBfdGltZXNjYWxlIHx8IDE7CgkJdmFyIGR1cmF0aW9uX3NlYyA9IGR1cmF0aW9uL3RpbWVzY2FsZTsKCQl2YXIgaG91cnMgPSBNYXRoLmZsb29yKGR1cmF0aW9uX3NlYy8zNjAwKTsKCQlkdXJhdGlvbl9zZWMgLT0gaG91cnMgKiAzNjAwOwoJCXZhciBtaW51dGVzID0gTWF0aC5mbG9vcihkdXJhdGlvbl9zZWMvNjApOwoJCWR1cmF0aW9uX3NlYyAtPSBtaW51dGVzICogNjA7CQkKCQl2YXIgbXNlYyA9IGR1cmF0aW9uX3NlYyoxMDAwOwoJCWR1cmF0aW9uX3NlYyA9IE1hdGguZmxvb3IoZHVyYXRpb25fc2VjKTsKCQltc2VjIC09IGR1cmF0aW9uX3NlYyoxMDAwOwoJCW1zZWMgPSBNYXRoLmZsb29yKG1zZWMpOwoJCXJldHVybiAobmVnID8gIi0iOiAiIikraG91cnMrIjoiK3BhZChtaW51dGVzLDIpKyI6IitwYWQoZHVyYXRpb25fc2VjLDIpKyIuIitwYWQobXNlYywzKTsKCX07CgkJCgkvKiBIZWxwZXIgZnVuY3Rpb24gdG8gc3RyaW5naWZ5IEhUTUw1IFRpbWVSYW5nZXMgb2JqZWN0cyAqLwkKCUxvZy5wcmludFJhbmdlcyA9IGZ1bmN0aW9uKHJhbmdlcykgewoJCXZhciBsZW5ndGggPSByYW5nZXMubGVuZ3RoOwoJCWlmIChsZW5ndGggPiAwKSB7CgkJCXZhciBzdHIgPSAiIjsKCQkJZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykgewoJCQkgIGlmIChpID4gMCkgc3RyICs9ICIsIjsKCQkJICBzdHIgKz0gIlsiK0xvZy5nZXREdXJhdGlvblN0cmluZyhyYW5nZXMuc3RhcnQoaSkpKyAiLCIrTG9nLmdldER1cmF0aW9uU3RyaW5nKHJhbmdlcy5lbmQoaSkpKyJdIjsKCQkJfQoJCQlyZXR1cm4gc3RyOwoJCX0gZWxzZSB7CgkJCXJldHVybiAiKGVtcHR5KSI7CgkJfQoJfTsKCgl7CgkJZXhwb3J0cy5Mb2cgPSBMb2c7Cgl9CgkvLyBmaWxlOnNyYy9zdHJlYW0uanMKCXZhciBNUDRCb3hTdHJlYW0gPSBmdW5jdGlvbihhcnJheUJ1ZmZlcikgewoJICBpZiAoYXJyYXlCdWZmZXIgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikgewoJICAgIHRoaXMuYnVmZmVyID0gYXJyYXlCdWZmZXI7CgkgICAgdGhpcy5kYXRhdmlldyA9IG5ldyBEYXRhVmlldyhhcnJheUJ1ZmZlcik7CgkgIH0gZWxzZSB7CgkgICAgdGhyb3cgKCJOZWVkcyBhbiBhcnJheSBidWZmZXIiKTsKCSAgfQoJICB0aGlzLnBvc2l0aW9uID0gMDsKCX07CgoJLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKCSAgQ29tbW9uIEFQSSBiZXR3ZWVuIE11bHRpQnVmZmVyU3RyZWFtIGFuZCBTaW1wbGVTdHJlYW0KCSAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoJTVA0Qm94U3RyZWFtLnByb3RvdHlwZS5nZXRQb3NpdGlvbiA9IGZ1bmN0aW9uKCkgewoJICByZXR1cm4gdGhpcy5wb3NpdGlvbjsKCX07CgoJTVA0Qm94U3RyZWFtLnByb3RvdHlwZS5nZXRFbmRQb3NpdGlvbiA9IGZ1bmN0aW9uKCkgewoJICByZXR1cm4gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aDsKCX07CgoJTVA0Qm94U3RyZWFtLnByb3RvdHlwZS5nZXRMZW5ndGggPSBmdW5jdGlvbigpIHsKCSAgcmV0dXJuIHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGg7Cgl9OwoKCU1QNEJveFN0cmVhbS5wcm90b3R5cGUuc2VlayA9IGZ1bmN0aW9uIChwb3MpIHsKCSAgdmFyIG5wb3MgPSBNYXRoLm1heCgwLCBNYXRoLm1pbih0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoLCBwb3MpKTsKCSAgdGhpcy5wb3NpdGlvbiA9IChpc05hTihucG9zKSB8fCAhaXNGaW5pdGUobnBvcykpID8gMCA6IG5wb3M7CgkgIHJldHVybiB0cnVlOwoJfTsKCglNUDRCb3hTdHJlYW0ucHJvdG90eXBlLmlzRW9zID0gZnVuY3Rpb24gKCkgewoJICByZXR1cm4gdGhpcy5nZXRQb3NpdGlvbigpID49IHRoaXMuZ2V0RW5kUG9zaXRpb24oKTsKCX07CgoJLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKCSAgUmVhZCBtZXRob2RzLCBzaW1pbWFyIHRvIERhdGFTdHJlYW0gYnV0IHNpbXBsZXIKCSAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoJTVA0Qm94U3RyZWFtLnByb3RvdHlwZS5yZWFkQW55SW50ID0gZnVuY3Rpb24oc2l6ZSwgc2lnbmVkKSB7CgkgIHZhciByZXMgPSAwOwoJICBpZiAodGhpcy5wb3NpdGlvbiArIHNpemUgPD0gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCkgewoJICAgIHN3aXRjaCAoc2l6ZSkgewoJICAgICAgY2FzZSAxOgoJICAgICAgICBpZiAoc2lnbmVkKSB7CgkgICAgICAgICAgcmVzID0gdGhpcy5kYXRhdmlldy5nZXRJbnQ4KHRoaXMucG9zaXRpb24pOwoJICAgICAgICB9IGVsc2UgewoJICAgICAgICAgIHJlcyA9IHRoaXMuZGF0YXZpZXcuZ2V0VWludDgodGhpcy5wb3NpdGlvbik7CgkgICAgICAgIH0KCSAgICAgICAgYnJlYWs7CgkgICAgICBjYXNlIDI6CgkgICAgICAgIGlmIChzaWduZWQpIHsKCSAgICAgICAgICByZXMgPSB0aGlzLmRhdGF2aWV3LmdldEludDE2KHRoaXMucG9zaXRpb24pOwoJICAgICAgICB9IGVsc2UgewoJICAgICAgICAgIHJlcyA9IHRoaXMuZGF0YXZpZXcuZ2V0VWludDE2KHRoaXMucG9zaXRpb24pOwoJICAgICAgICB9CgkgICAgICAgIGJyZWFrOwoJICAgICAgY2FzZSAzOgoJICAgICAgICBpZiAoc2lnbmVkKSB7CgkgICAgICAgICAgdGhyb3cgKCJObyBtZXRob2QgZm9yIHJlYWRpbmcgc2lnbmVkIDI0IGJpdHMgdmFsdWVzIik7CgkgICAgICAgIH0gZWxzZSB7CgkgICAgICAgICAgcmVzID0gdGhpcy5kYXRhdmlldy5nZXRVaW50OCh0aGlzLnBvc2l0aW9uKSA8PCAxNjsKCSAgICAgICAgICByZXMgfD0gdGhpcy5kYXRhdmlldy5nZXRVaW50OCh0aGlzLnBvc2l0aW9uKzEpIDw8IDg7CgkgICAgICAgICAgcmVzIHw9IHRoaXMuZGF0YXZpZXcuZ2V0VWludDgodGhpcy5wb3NpdGlvbisyKTsKCSAgICAgICAgfQoJICAgICAgICBicmVhazsKCSAgICAgIGNhc2UgNDoKCSAgICAgICAgaWYgKHNpZ25lZCkgewoJICAgICAgICAgIHJlcyA9IHRoaXMuZGF0YXZpZXcuZ2V0SW50MzIodGhpcy5wb3NpdGlvbik7CgkgICAgICAgIH0gZWxzZSB7CgkgICAgICAgICAgcmVzID0gdGhpcy5kYXRhdmlldy5nZXRVaW50MzIodGhpcy5wb3NpdGlvbik7CgkgICAgICAgIH0KCSAgICAgICAgYnJlYWs7CgkgICAgICBjYXNlIDg6CgkgICAgICAgIGlmIChzaWduZWQpIHsKCSAgICAgICAgICB0aHJvdyAoIk5vIG1ldGhvZCBmb3IgcmVhZGluZyBzaWduZWQgNjQgYml0cyB2YWx1ZXMiKTsKCSAgICAgICAgfSBlbHNlIHsKCSAgICAgICAgICByZXMgPSB0aGlzLmRhdGF2aWV3LmdldFVpbnQzMih0aGlzLnBvc2l0aW9uKSA8PCAzMjsKCSAgICAgICAgICByZXMgfD0gdGhpcy5kYXRhdmlldy5nZXRVaW50MzIodGhpcy5wb3NpdGlvbis0KTsKCSAgICAgICAgfQoJICAgICAgICBicmVhazsKCSAgICAgIGRlZmF1bHQ6CgkgICAgICAgIHRocm93ICgicmVhZEludCBtZXRob2Qgbm90IGltcGxlbWVudGVkIGZvciBzaXplOiAiK3NpemUpOwoJICAgIH0KCSAgICB0aGlzLnBvc2l0aW9uKz0gc2l6ZTsKCSAgICByZXR1cm4gcmVzOwoJICB9IGVsc2UgewoJICAgIHRocm93ICgiTm90IGVub3VnaCBieXRlcyBpbiBidWZmZXIiKTsKCSAgfQoJfTsKCglNUDRCb3hTdHJlYW0ucHJvdG90eXBlLnJlYWRVaW50OCA9IGZ1bmN0aW9uKCkgewoJICByZXR1cm4gdGhpcy5yZWFkQW55SW50KDEsIGZhbHNlKTsKCX07CgoJTVA0Qm94U3RyZWFtLnByb3RvdHlwZS5yZWFkVWludDE2ID0gZnVuY3Rpb24oKSB7CgkgIHJldHVybiB0aGlzLnJlYWRBbnlJbnQoMiwgZmFsc2UpOwoJfTsKCglNUDRCb3hTdHJlYW0ucHJvdG90eXBlLnJlYWRVaW50MjQgPSBmdW5jdGlvbigpIHsKCSAgcmV0dXJuIHRoaXMucmVhZEFueUludCgzLCBmYWxzZSk7Cgl9OwoKCU1QNEJveFN0cmVhbS5wcm90b3R5cGUucmVhZFVpbnQzMiA9IGZ1bmN0aW9uKCkgewoJICByZXR1cm4gdGhpcy5yZWFkQW55SW50KDQsIGZhbHNlKTsKCX07CgoJTVA0Qm94U3RyZWFtLnByb3RvdHlwZS5yZWFkVWludDY0ID0gZnVuY3Rpb24oKSB7CgkgIHJldHVybiB0aGlzLnJlYWRBbnlJbnQoOCwgZmFsc2UpOwoJfTsKCglNUDRCb3hTdHJlYW0ucHJvdG90eXBlLnJlYWRTdHJpbmcgPSBmdW5jdGlvbihsZW5ndGgpIHsKCSAgaWYgKHRoaXMucG9zaXRpb24gKyBsZW5ndGggPD0gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aCkgewoJICAgIHZhciBzID0gIiI7CgkgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykgewoJICAgICAgcyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHRoaXMucmVhZFVpbnQ4KCkpOwoJICAgIH0KCSAgICByZXR1cm4gczsKCSAgfSBlbHNlIHsKCSAgICB0aHJvdyAoIk5vdCBlbm91Z2ggYnl0ZXMgaW4gYnVmZmVyIik7CgkgIH0KCX07CgoJTVA0Qm94U3RyZWFtLnByb3RvdHlwZS5yZWFkQ1N0cmluZyA9IGZ1bmN0aW9uKCkgewoJICB2YXIgYXJyID0gW107CgkgIHdoaWxlKHRydWUpIHsKCSAgICB2YXIgYiA9IHRoaXMucmVhZFVpbnQ4KCk7CgkgICAgaWYgKGIgIT09IDApIHsKCSAgICAgIGFyci5wdXNoKGIpOwoJICAgIH0gZWxzZSB7CgkgICAgICBicmVhazsKCSAgICB9CgkgIH0KCSAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCwgYXJyKTsgCgl9OwoKCU1QNEJveFN0cmVhbS5wcm90b3R5cGUucmVhZEludDggPSBmdW5jdGlvbigpIHsKCSAgcmV0dXJuIHRoaXMucmVhZEFueUludCgxLCB0cnVlKTsKCX07CgoJTVA0Qm94U3RyZWFtLnByb3RvdHlwZS5yZWFkSW50MTYgPSBmdW5jdGlvbigpIHsKCSAgcmV0dXJuIHRoaXMucmVhZEFueUludCgyLCB0cnVlKTsKCX07CgoJTVA0Qm94U3RyZWFtLnByb3RvdHlwZS5yZWFkSW50MzIgPSBmdW5jdGlvbigpIHsKCSAgcmV0dXJuIHRoaXMucmVhZEFueUludCg0LCB0cnVlKTsKCX07CgoJTVA0Qm94U3RyZWFtLnByb3RvdHlwZS5yZWFkSW50NjQgPSBmdW5jdGlvbigpIHsKCSAgcmV0dXJuIHRoaXMucmVhZEFueUludCg4LCBmYWxzZSk7Cgl9OwoKCU1QNEJveFN0cmVhbS5wcm90b3R5cGUucmVhZFVpbnQ4QXJyYXkgPSBmdW5jdGlvbihsZW5ndGgpIHsKCSAgdmFyIGFyciA9IG5ldyBVaW50OEFycmF5KGxlbmd0aCk7CgkgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKCSAgICBhcnJbaV0gPSB0aGlzLnJlYWRVaW50OCgpOwoJICB9CgkgIHJldHVybiBhcnI7Cgl9OwoKCU1QNEJveFN0cmVhbS5wcm90b3R5cGUucmVhZEludDE2QXJyYXkgPSBmdW5jdGlvbihsZW5ndGgpIHsKCSAgdmFyIGFyciA9IG5ldyBJbnQxNkFycmF5KGxlbmd0aCk7CgkgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKCSAgICBhcnJbaV0gPSB0aGlzLnJlYWRJbnQxNigpOwoJICB9CgkgIHJldHVybiBhcnI7Cgl9OwoKCU1QNEJveFN0cmVhbS5wcm90b3R5cGUucmVhZFVpbnQxNkFycmF5ID0gZnVuY3Rpb24obGVuZ3RoKSB7CgkgIHZhciBhcnIgPSBuZXcgSW50MTZBcnJheShsZW5ndGgpOwoJICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7CgkgICAgYXJyW2ldID0gdGhpcy5yZWFkVWludDE2KCk7CgkgIH0KCSAgcmV0dXJuIGFycjsKCX07CgoJTVA0Qm94U3RyZWFtLnByb3RvdHlwZS5yZWFkVWludDMyQXJyYXkgPSBmdW5jdGlvbihsZW5ndGgpIHsKCSAgdmFyIGFyciA9IG5ldyBVaW50MzJBcnJheShsZW5ndGgpOwoJICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7CgkgICAgYXJyW2ldID0gdGhpcy5yZWFkVWludDMyKCk7CgkgIH0KCSAgcmV0dXJuIGFycjsKCX07CgoJTVA0Qm94U3RyZWFtLnByb3RvdHlwZS5yZWFkSW50MzJBcnJheSA9IGZ1bmN0aW9uKGxlbmd0aCkgewoJICB2YXIgYXJyID0gbmV3IEludDMyQXJyYXkobGVuZ3RoKTsKCSAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykgewoJICAgIGFycltpXSA9IHRoaXMucmVhZEludDMyKCk7CgkgIH0KCSAgcmV0dXJuIGFycjsKCX07CgoJewoJICBleHBvcnRzLk1QNEJveFN0cmVhbSA9IE1QNEJveFN0cmVhbTsKCX0vLyBmaWxlOnNyYy9EYXRhU3RyZWFtLmpzCgkvKioKCSAgRGF0YVN0cmVhbSByZWFkcyBzY2FsYXJzLCBhcnJheXMgYW5kIHN0cnVjdHMgb2YgZGF0YSBmcm9tIGFuIEFycmF5QnVmZmVyLgoJICBJdCdzIGxpa2UgYSBmaWxlLWxpa2UgRGF0YVZpZXcgb24gc3Rlcm9pZHMuCgoJICBAcGFyYW0ge0FycmF5QnVmZmVyfSBhcnJheUJ1ZmZlciBBcnJheUJ1ZmZlciB0byByZWFkIGZyb20uCgkgIEBwYXJhbSB7P051bWJlcn0gYnl0ZU9mZnNldCBPZmZzZXQgZnJvbSBhcnJheUJ1ZmZlciBiZWdpbm5pbmcgZm9yIHRoZSBEYXRhU3RyZWFtLgoJICBAcGFyYW0gez9Cb29sZWFufSBlbmRpYW5uZXNzIERhdGFTdHJlYW0uQklHX0VORElBTiBvciBEYXRhU3RyZWFtLkxJVFRMRV9FTkRJQU4gKHRoZSBkZWZhdWx0KS4KCSAgKi8KCXZhciBEYXRhU3RyZWFtID0gZnVuY3Rpb24oYXJyYXlCdWZmZXIsIGJ5dGVPZmZzZXQsIGVuZGlhbm5lc3MpIHsKCSAgdGhpcy5fYnl0ZU9mZnNldCA9IGJ5dGVPZmZzZXQgfHwgMDsKCSAgaWYgKGFycmF5QnVmZmVyIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHsKCSAgICB0aGlzLmJ1ZmZlciA9IGFycmF5QnVmZmVyOwoJICB9IGVsc2UgaWYgKHR5cGVvZiBhcnJheUJ1ZmZlciA9PSAib2JqZWN0IikgewoJICAgIHRoaXMuZGF0YVZpZXcgPSBhcnJheUJ1ZmZlcjsKCSAgICBpZiAoYnl0ZU9mZnNldCkgewoJICAgICAgdGhpcy5fYnl0ZU9mZnNldCArPSBieXRlT2Zmc2V0OwoJICAgIH0KCSAgfSBlbHNlIHsKCSAgICB0aGlzLmJ1ZmZlciA9IG5ldyBBcnJheUJ1ZmZlcihhcnJheUJ1ZmZlciB8fCAwKTsKCSAgfQoJICB0aGlzLnBvc2l0aW9uID0gMDsKCSAgdGhpcy5lbmRpYW5uZXNzID0gZW5kaWFubmVzcyA9PSBudWxsID8gRGF0YVN0cmVhbS5MSVRUTEVfRU5ESUFOIDogZW5kaWFubmVzczsKCX07CglEYXRhU3RyZWFtLnByb3RvdHlwZSA9IHt9OwoKCURhdGFTdHJlYW0ucHJvdG90eXBlLmdldFBvc2l0aW9uID0gZnVuY3Rpb24oKSB7CgkgIHJldHVybiB0aGlzLnBvc2l0aW9uOwoJfTsKCgkvKioKCSAgSW50ZXJuYWwgZnVuY3Rpb24gdG8gcmVzaXplIHRoZSBEYXRhU3RyZWFtIGJ1ZmZlciB3aGVuIHJlcXVpcmVkLgoJICBAcGFyYW0ge251bWJlcn0gZXh0cmEgTnVtYmVyIG9mIGJ5dGVzIHRvIGFkZCB0byB0aGUgYnVmZmVyIGFsbG9jYXRpb24uCgkgIEByZXR1cm4ge251bGx9CgkgICovCglEYXRhU3RyZWFtLnByb3RvdHlwZS5fcmVhbGxvYyA9IGZ1bmN0aW9uKGV4dHJhKSB7CgkgIGlmICghdGhpcy5fZHluYW1pY1NpemUpIHsKCSAgICByZXR1cm47CgkgIH0KCSAgdmFyIHJlcSA9IHRoaXMuX2J5dGVPZmZzZXQgKyB0aGlzLnBvc2l0aW9uICsgZXh0cmE7CgkgIHZhciBibGVuID0gdGhpcy5fYnVmZmVyLmJ5dGVMZW5ndGg7CgkgIGlmIChyZXEgPD0gYmxlbikgewoJICAgIGlmIChyZXEgPiB0aGlzLl9ieXRlTGVuZ3RoKSB7CgkgICAgICB0aGlzLl9ieXRlTGVuZ3RoID0gcmVxOwoJICAgIH0KCSAgICByZXR1cm47CgkgIH0KCSAgaWYgKGJsZW4gPCAxKSB7CgkgICAgYmxlbiA9IDE7CgkgIH0KCSAgd2hpbGUgKHJlcSA+IGJsZW4pIHsKCSAgICBibGVuICo9IDI7CgkgIH0KCSAgdmFyIGJ1ZiA9IG5ldyBBcnJheUJ1ZmZlcihibGVuKTsKCSAgdmFyIHNyYyA9IG5ldyBVaW50OEFycmF5KHRoaXMuX2J1ZmZlcik7CgkgIHZhciBkc3QgPSBuZXcgVWludDhBcnJheShidWYsIDAsIHNyYy5sZW5ndGgpOwoJICBkc3Quc2V0KHNyYyk7CgkgIHRoaXMuYnVmZmVyID0gYnVmOwoJICB0aGlzLl9ieXRlTGVuZ3RoID0gcmVxOwoJfTsKCgkvKioKCSAgSW50ZXJuYWwgZnVuY3Rpb24gdG8gdHJpbSB0aGUgRGF0YVN0cmVhbSBidWZmZXIgd2hlbiByZXF1aXJlZC4KCSAgVXNlZCBmb3Igc3RyaXBwaW5nIG91dCB0aGUgZXh0cmEgYnl0ZXMgZnJvbSB0aGUgYmFja2luZyBidWZmZXIgd2hlbgoJICB0aGUgdmlydHVhbCBieXRlTGVuZ3RoIGlzIHNtYWxsZXIgdGhhbiB0aGUgYnVmZmVyIGJ5dGVMZW5ndGggKGhhcHBlbnMgYWZ0ZXIKCSAgZ3Jvd2luZyB0aGUgYnVmZmVyIHdpdGggd3JpdGVzIGFuZCBub3QgZmlsbGluZyB0aGUgZXh0cmEgc3BhY2UgY29tcGxldGVseSkuCgoJICBAcmV0dXJuIHtudWxsfQoJICAqLwoJRGF0YVN0cmVhbS5wcm90b3R5cGUuX3RyaW1BbGxvYyA9IGZ1bmN0aW9uKCkgewoJICBpZiAodGhpcy5fYnl0ZUxlbmd0aCA9PSB0aGlzLl9idWZmZXIuYnl0ZUxlbmd0aCkgewoJICAgIHJldHVybjsKCSAgfQoJICB2YXIgYnVmID0gbmV3IEFycmF5QnVmZmVyKHRoaXMuX2J5dGVMZW5ndGgpOwoJICB2YXIgZHN0ID0gbmV3IFVpbnQ4QXJyYXkoYnVmKTsKCSAgdmFyIHNyYyA9IG5ldyBVaW50OEFycmF5KHRoaXMuX2J1ZmZlciwgMCwgZHN0Lmxlbmd0aCk7CgkgIGRzdC5zZXQoc3JjKTsKCSAgdGhpcy5idWZmZXIgPSBidWY7Cgl9OwoKCgkvKioKCSAgQmlnLWVuZGlhbiBjb25zdCB0byB1c2UgYXMgZGVmYXVsdCBlbmRpYW5uZXNzLgoJICBAdHlwZSB7Ym9vbGVhbn0KCSAgKi8KCURhdGFTdHJlYW0uQklHX0VORElBTiA9IGZhbHNlOwoKCS8qKgoJICBMaXR0bGUtZW5kaWFuIGNvbnN0IHRvIHVzZSBhcyBkZWZhdWx0IGVuZGlhbm5lc3MuCgkgIEB0eXBlIHtib29sZWFufQoJICAqLwoJRGF0YVN0cmVhbS5MSVRUTEVfRU5ESUFOID0gdHJ1ZTsKCgkvKioKCSAgVmlydHVhbCBieXRlIGxlbmd0aCBvZiB0aGUgRGF0YVN0cmVhbSBiYWNraW5nIGJ1ZmZlci4KCSAgVXBkYXRlZCB0byBiZSBtYXggb2Ygb3JpZ2luYWwgYnVmZmVyIHNpemUgYW5kIGxhc3Qgd3JpdHRlbiBzaXplLgoJICBJZiBkeW5hbWljU2l6ZSBpcyBmYWxzZSBpcyBzZXQgdG8gYnVmZmVyIHNpemUuCgkgIEB0eXBlIHtudW1iZXJ9CgkgICovCglEYXRhU3RyZWFtLnByb3RvdHlwZS5fYnl0ZUxlbmd0aCA9IDA7CgoJLyoqCgkgIFJldHVybnMgdGhlIGJ5dGUgbGVuZ3RoIG9mIHRoZSBEYXRhU3RyZWFtIG9iamVjdC4KCSAgQHR5cGUge251bWJlcn0KCSAgKi8KCU9iamVjdC5kZWZpbmVQcm9wZXJ0eShEYXRhU3RyZWFtLnByb3RvdHlwZSwgJ2J5dGVMZW5ndGgnLAoJICB7IGdldDogZnVuY3Rpb24oKSB7CgkgICAgcmV0dXJuIHRoaXMuX2J5dGVMZW5ndGggLSB0aGlzLl9ieXRlT2Zmc2V0OwoJICB9fSk7CgoJLyoqCgkgIFNldC9nZXQgdGhlIGJhY2tpbmcgQXJyYXlCdWZmZXIgb2YgdGhlIERhdGFTdHJlYW0gb2JqZWN0LgoJICBUaGUgc2V0dGVyIHVwZGF0ZXMgdGhlIERhdGFWaWV3IHRvIHBvaW50IHRvIHRoZSBuZXcgYnVmZmVyLgoJICBAdHlwZSB7T2JqZWN0fQoJICAqLwoJT2JqZWN0LmRlZmluZVByb3BlcnR5KERhdGFTdHJlYW0ucHJvdG90eXBlLCAnYnVmZmVyJywKCSAgeyBnZXQ6IGZ1bmN0aW9uKCkgewoJICAgICAgdGhpcy5fdHJpbUFsbG9jKCk7CgkgICAgICByZXR1cm4gdGhpcy5fYnVmZmVyOwoJICAgIH0sCgkgICAgc2V0OiBmdW5jdGlvbih2KSB7CgkgICAgICB0aGlzLl9idWZmZXIgPSB2OwoJICAgICAgdGhpcy5fZGF0YVZpZXcgPSBuZXcgRGF0YVZpZXcodGhpcy5fYnVmZmVyLCB0aGlzLl9ieXRlT2Zmc2V0KTsKCSAgICAgIHRoaXMuX2J5dGVMZW5ndGggPSB0aGlzLl9idWZmZXIuYnl0ZUxlbmd0aDsKCSAgICB9IH0pOwoKCS8qKgoJICBTZXQvZ2V0IHRoZSBieXRlT2Zmc2V0IG9mIHRoZSBEYXRhU3RyZWFtIG9iamVjdC4KCSAgVGhlIHNldHRlciB1cGRhdGVzIHRoZSBEYXRhVmlldyB0byBwb2ludCB0byB0aGUgbmV3IGJ5dGVPZmZzZXQuCgkgIEB0eXBlIHtudW1iZXJ9CgkgICovCglPYmplY3QuZGVmaW5lUHJvcGVydHkoRGF0YVN0cmVhbS5wcm90b3R5cGUsICdieXRlT2Zmc2V0JywKCSAgeyBnZXQ6IGZ1bmN0aW9uKCkgewoJICAgICAgcmV0dXJuIHRoaXMuX2J5dGVPZmZzZXQ7CgkgICAgfSwKCSAgICBzZXQ6IGZ1bmN0aW9uKHYpIHsKCSAgICAgIHRoaXMuX2J5dGVPZmZzZXQgPSB2OwoJICAgICAgdGhpcy5fZGF0YVZpZXcgPSBuZXcgRGF0YVZpZXcodGhpcy5fYnVmZmVyLCB0aGlzLl9ieXRlT2Zmc2V0KTsKCSAgICAgIHRoaXMuX2J5dGVMZW5ndGggPSB0aGlzLl9idWZmZXIuYnl0ZUxlbmd0aDsKCSAgICB9IH0pOwoKCS8qKgoJICBTZXQvZ2V0IHRoZSBiYWNraW5nIERhdGFWaWV3IG9mIHRoZSBEYXRhU3RyZWFtIG9iamVjdC4KCSAgVGhlIHNldHRlciB1cGRhdGVzIHRoZSBidWZmZXIgYW5kIGJ5dGVPZmZzZXQgdG8gcG9pbnQgdG8gdGhlIERhdGFWaWV3IHZhbHVlcy4KCSAgQHR5cGUge09iamVjdH0KCSAgKi8KCU9iamVjdC5kZWZpbmVQcm9wZXJ0eShEYXRhU3RyZWFtLnByb3RvdHlwZSwgJ2RhdGFWaWV3JywKCSAgeyBnZXQ6IGZ1bmN0aW9uKCkgewoJICAgICAgcmV0dXJuIHRoaXMuX2RhdGFWaWV3OwoJICAgIH0sCgkgICAgc2V0OiBmdW5jdGlvbih2KSB7CgkgICAgICB0aGlzLl9ieXRlT2Zmc2V0ID0gdi5ieXRlT2Zmc2V0OwoJICAgICAgdGhpcy5fYnVmZmVyID0gdi5idWZmZXI7CgkgICAgICB0aGlzLl9kYXRhVmlldyA9IG5ldyBEYXRhVmlldyh0aGlzLl9idWZmZXIsIHRoaXMuX2J5dGVPZmZzZXQpOwoJICAgICAgdGhpcy5fYnl0ZUxlbmd0aCA9IHRoaXMuX2J5dGVPZmZzZXQgKyB2LmJ5dGVMZW5ndGg7CgkgICAgfSB9KTsKCgkvKioKCSAgU2V0cyB0aGUgRGF0YVN0cmVhbSByZWFkL3dyaXRlIHBvc2l0aW9uIHRvIGdpdmVuIHBvc2l0aW9uLgoJICBDbGFtcHMgYmV0d2VlbiAwIGFuZCBEYXRhU3RyZWFtIGxlbmd0aC4KCgkgIEBwYXJhbSB7bnVtYmVyfSBwb3MgUG9zaXRpb24gdG8gc2VlayB0by4KCSAgQHJldHVybiB7bnVsbH0KCSAgKi8KCURhdGFTdHJlYW0ucHJvdG90eXBlLnNlZWsgPSBmdW5jdGlvbihwb3MpIHsKCSAgdmFyIG5wb3MgPSBNYXRoLm1heCgwLCBNYXRoLm1pbih0aGlzLmJ5dGVMZW5ndGgsIHBvcykpOwoJICB0aGlzLnBvc2l0aW9uID0gKGlzTmFOKG5wb3MpIHx8ICFpc0Zpbml0ZShucG9zKSkgPyAwIDogbnBvczsKCX07CgoJLyoqCgkgIFJldHVybnMgdHJ1ZSBpZiB0aGUgRGF0YVN0cmVhbSBzZWVrIHBvaW50ZXIgaXMgYXQgdGhlIGVuZCBvZiBidWZmZXIgYW5kCgkgIHRoZXJlJ3Mgbm8gbW9yZSBkYXRhIHRvIHJlYWQuCgoJICBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIHRoZSBzZWVrIHBvaW50ZXIgaXMgYXQgdGhlIGVuZCBvZiB0aGUgYnVmZmVyLgoJICAqLwoJRGF0YVN0cmVhbS5wcm90b3R5cGUuaXNFb2YgPSBmdW5jdGlvbigpIHsKCSAgcmV0dXJuICh0aGlzLnBvc2l0aW9uID49IHRoaXMuX2J5dGVMZW5ndGgpOwoJfTsKCgoJLyoqCgkgIE1hcHMgYSBVaW50OEFycmF5IGludG8gdGhlIERhdGFTdHJlYW0gYnVmZmVyLgoKCSAgTmljZSBmb3IgcXVpY2tseSByZWFkaW5nIGluIGRhdGEuCgoJICBAcGFyYW0ge251bWJlcn0gbGVuZ3RoIE51bWJlciBvZiBlbGVtZW50cyB0byBtYXAuCgkgIEBwYXJhbSB7P2Jvb2xlYW59IGUgRW5kaWFubmVzcyBvZiB0aGUgZGF0YSB0byByZWFkLgoJICBAcmV0dXJuIHtPYmplY3R9IFVpbnQ4QXJyYXkgdG8gdGhlIERhdGFTdHJlYW0gYmFja2luZyBidWZmZXIuCgkgICovCglEYXRhU3RyZWFtLnByb3RvdHlwZS5tYXBVaW50OEFycmF5ID0gZnVuY3Rpb24obGVuZ3RoKSB7CgkgIHRoaXMuX3JlYWxsb2MobGVuZ3RoICogMSk7CgkgIHZhciBhcnIgPSBuZXcgVWludDhBcnJheSh0aGlzLl9idWZmZXIsIHRoaXMuYnl0ZU9mZnNldCt0aGlzLnBvc2l0aW9uLCBsZW5ndGgpOwoJICB0aGlzLnBvc2l0aW9uICs9IGxlbmd0aCAqIDE7CgkgIHJldHVybiBhcnI7Cgl9OwoKCgkvKioKCSAgUmVhZHMgYW4gSW50MzJBcnJheSBvZiBkZXNpcmVkIGxlbmd0aCBhbmQgZW5kaWFubmVzcyBmcm9tIHRoZSBEYXRhU3RyZWFtLgoKCSAgQHBhcmFtIHtudW1iZXJ9IGxlbmd0aCBOdW1iZXIgb2YgZWxlbWVudHMgdG8gbWFwLgoJICBAcGFyYW0gez9ib29sZWFufSBlIEVuZGlhbm5lc3Mgb2YgdGhlIGRhdGEgdG8gcmVhZC4KCSAgQHJldHVybiB7T2JqZWN0fSBUaGUgcmVhZCBJbnQzMkFycmF5LgoJICovCglEYXRhU3RyZWFtLnByb3RvdHlwZS5yZWFkSW50MzJBcnJheSA9IGZ1bmN0aW9uKGxlbmd0aCwgZSkgewoJICBsZW5ndGggPSBsZW5ndGggPT0gbnVsbCA/ICh0aGlzLmJ5dGVMZW5ndGgtdGhpcy5wb3NpdGlvbiAvIDQpIDogbGVuZ3RoOwoJICB2YXIgYXJyID0gbmV3IEludDMyQXJyYXkobGVuZ3RoKTsKCSAgRGF0YVN0cmVhbS5tZW1jcHkoYXJyLmJ1ZmZlciwgMCwKCSAgICAgICAgICAgICAgICAgICAgdGhpcy5idWZmZXIsIHRoaXMuYnl0ZU9mZnNldCt0aGlzLnBvc2l0aW9uLAoJICAgICAgICAgICAgICAgICAgICBsZW5ndGgqYXJyLkJZVEVTX1BFUl9FTEVNRU5UKTsKCSAgRGF0YVN0cmVhbS5hcnJheVRvTmF0aXZlKGFyciwgZSA9PSBudWxsID8gdGhpcy5lbmRpYW5uZXNzIDogZSk7CgkgIHRoaXMucG9zaXRpb24gKz0gYXJyLmJ5dGVMZW5ndGg7CgkgIHJldHVybiBhcnI7Cgl9OwoKCS8qKgoJICBSZWFkcyBhbiBJbnQxNkFycmF5IG9mIGRlc2lyZWQgbGVuZ3RoIGFuZCBlbmRpYW5uZXNzIGZyb20gdGhlIERhdGFTdHJlYW0uCgoJICBAcGFyYW0ge251bWJlcn0gbGVuZ3RoIE51bWJlciBvZiBlbGVtZW50cyB0byBtYXAuCgkgIEBwYXJhbSB7P2Jvb2xlYW59IGUgRW5kaWFubmVzcyBvZiB0aGUgZGF0YSB0byByZWFkLgoJICBAcmV0dXJuIHtPYmplY3R9IFRoZSByZWFkIEludDE2QXJyYXkuCgkgKi8KCURhdGFTdHJlYW0ucHJvdG90eXBlLnJlYWRJbnQxNkFycmF5ID0gZnVuY3Rpb24obGVuZ3RoLCBlKSB7CgkgIGxlbmd0aCA9IGxlbmd0aCA9PSBudWxsID8gKHRoaXMuYnl0ZUxlbmd0aC10aGlzLnBvc2l0aW9uIC8gMikgOiBsZW5ndGg7CgkgIHZhciBhcnIgPSBuZXcgSW50MTZBcnJheShsZW5ndGgpOwoJICBEYXRhU3RyZWFtLm1lbWNweShhcnIuYnVmZmVyLCAwLAoJICAgICAgICAgICAgICAgICAgICB0aGlzLmJ1ZmZlciwgdGhpcy5ieXRlT2Zmc2V0K3RoaXMucG9zaXRpb24sCgkgICAgICAgICAgICAgICAgICAgIGxlbmd0aCphcnIuQllURVNfUEVSX0VMRU1FTlQpOwoJICBEYXRhU3RyZWFtLmFycmF5VG9OYXRpdmUoYXJyLCBlID09IG51bGwgPyB0aGlzLmVuZGlhbm5lc3MgOiBlKTsKCSAgdGhpcy5wb3NpdGlvbiArPSBhcnIuYnl0ZUxlbmd0aDsKCSAgcmV0dXJuIGFycjsKCX07CgoJLyoqCgkgIFJlYWRzIGFuIEludDhBcnJheSBvZiBkZXNpcmVkIGxlbmd0aCBmcm9tIHRoZSBEYXRhU3RyZWFtLgoKCSAgQHBhcmFtIHtudW1iZXJ9IGxlbmd0aCBOdW1iZXIgb2YgZWxlbWVudHMgdG8gbWFwLgoJICBAcGFyYW0gez9ib29sZWFufSBlIEVuZGlhbm5lc3Mgb2YgdGhlIGRhdGEgdG8gcmVhZC4KCSAgQHJldHVybiB7T2JqZWN0fSBUaGUgcmVhZCBJbnQ4QXJyYXkuCgkgKi8KCURhdGFTdHJlYW0ucHJvdG90eXBlLnJlYWRJbnQ4QXJyYXkgPSBmdW5jdGlvbihsZW5ndGgpIHsKCSAgbGVuZ3RoID0gbGVuZ3RoID09IG51bGwgPyAodGhpcy5ieXRlTGVuZ3RoLXRoaXMucG9zaXRpb24pIDogbGVuZ3RoOwoJICB2YXIgYXJyID0gbmV3IEludDhBcnJheShsZW5ndGgpOwoJICBEYXRhU3RyZWFtLm1lbWNweShhcnIuYnVmZmVyLCAwLAoJICAgICAgICAgICAgICAgICAgICB0aGlzLmJ1ZmZlciwgdGhpcy5ieXRlT2Zmc2V0K3RoaXMucG9zaXRpb24sCgkgICAgICAgICAgICAgICAgICAgIGxlbmd0aCphcnIuQllURVNfUEVSX0VMRU1FTlQpOwoJICB0aGlzLnBvc2l0aW9uICs9IGFyci5ieXRlTGVuZ3RoOwoJICByZXR1cm4gYXJyOwoJfTsKCgkvKioKCSAgUmVhZHMgYSBVaW50MzJBcnJheSBvZiBkZXNpcmVkIGxlbmd0aCBhbmQgZW5kaWFubmVzcyBmcm9tIHRoZSBEYXRhU3RyZWFtLgoKCSAgQHBhcmFtIHtudW1iZXJ9IGxlbmd0aCBOdW1iZXIgb2YgZWxlbWVudHMgdG8gbWFwLgoJICBAcGFyYW0gez9ib29sZWFufSBlIEVuZGlhbm5lc3Mgb2YgdGhlIGRhdGEgdG8gcmVhZC4KCSAgQHJldHVybiB7T2JqZWN0fSBUaGUgcmVhZCBVaW50MzJBcnJheS4KCSAqLwoJRGF0YVN0cmVhbS5wcm90b3R5cGUucmVhZFVpbnQzMkFycmF5ID0gZnVuY3Rpb24obGVuZ3RoLCBlKSB7CgkgIGxlbmd0aCA9IGxlbmd0aCA9PSBudWxsID8gKHRoaXMuYnl0ZUxlbmd0aC10aGlzLnBvc2l0aW9uIC8gNCkgOiBsZW5ndGg7CgkgIHZhciBhcnIgPSBuZXcgVWludDMyQXJyYXkobGVuZ3RoKTsKCSAgRGF0YVN0cmVhbS5tZW1jcHkoYXJyLmJ1ZmZlciwgMCwKCSAgICAgICAgICAgICAgICAgICAgdGhpcy5idWZmZXIsIHRoaXMuYnl0ZU9mZnNldCt0aGlzLnBvc2l0aW9uLAoJICAgICAgICAgICAgICAgICAgICBsZW5ndGgqYXJyLkJZVEVTX1BFUl9FTEVNRU5UKTsKCSAgRGF0YVN0cmVhbS5hcnJheVRvTmF0aXZlKGFyciwgZSA9PSBudWxsID8gdGhpcy5lbmRpYW5uZXNzIDogZSk7CgkgIHRoaXMucG9zaXRpb24gKz0gYXJyLmJ5dGVMZW5ndGg7CgkgIHJldHVybiBhcnI7Cgl9OwoKCS8qKgoJICBSZWFkcyBhIFVpbnQxNkFycmF5IG9mIGRlc2lyZWQgbGVuZ3RoIGFuZCBlbmRpYW5uZXNzIGZyb20gdGhlIERhdGFTdHJlYW0uCgoJICBAcGFyYW0ge251bWJlcn0gbGVuZ3RoIE51bWJlciBvZiBlbGVtZW50cyB0byBtYXAuCgkgIEBwYXJhbSB7P2Jvb2xlYW59IGUgRW5kaWFubmVzcyBvZiB0aGUgZGF0YSB0byByZWFkLgoJICBAcmV0dXJuIHtPYmplY3R9IFRoZSByZWFkIFVpbnQxNkFycmF5LgoJICovCglEYXRhU3RyZWFtLnByb3RvdHlwZS5yZWFkVWludDE2QXJyYXkgPSBmdW5jdGlvbihsZW5ndGgsIGUpIHsKCSAgbGVuZ3RoID0gbGVuZ3RoID09IG51bGwgPyAodGhpcy5ieXRlTGVuZ3RoLXRoaXMucG9zaXRpb24gLyAyKSA6IGxlbmd0aDsKCSAgdmFyIGFyciA9IG5ldyBVaW50MTZBcnJheShsZW5ndGgpOwoJICBEYXRhU3RyZWFtLm1lbWNweShhcnIuYnVmZmVyLCAwLAoJICAgICAgICAgICAgICAgICAgICB0aGlzLmJ1ZmZlciwgdGhpcy5ieXRlT2Zmc2V0K3RoaXMucG9zaXRpb24sCgkgICAgICAgICAgICAgICAgICAgIGxlbmd0aCphcnIuQllURVNfUEVSX0VMRU1FTlQpOwoJICBEYXRhU3RyZWFtLmFycmF5VG9OYXRpdmUoYXJyLCBlID09IG51bGwgPyB0aGlzLmVuZGlhbm5lc3MgOiBlKTsKCSAgdGhpcy5wb3NpdGlvbiArPSBhcnIuYnl0ZUxlbmd0aDsKCSAgcmV0dXJuIGFycjsKCX07CgoJLyoqCgkgIFJlYWRzIGEgVWludDhBcnJheSBvZiBkZXNpcmVkIGxlbmd0aCBmcm9tIHRoZSBEYXRhU3RyZWFtLgoKCSAgQHBhcmFtIHtudW1iZXJ9IGxlbmd0aCBOdW1iZXIgb2YgZWxlbWVudHMgdG8gbWFwLgoJICBAcGFyYW0gez9ib29sZWFufSBlIEVuZGlhbm5lc3Mgb2YgdGhlIGRhdGEgdG8gcmVhZC4KCSAgQHJldHVybiB7T2JqZWN0fSBUaGUgcmVhZCBVaW50OEFycmF5LgoJICovCglEYXRhU3RyZWFtLnByb3RvdHlwZS5yZWFkVWludDhBcnJheSA9IGZ1bmN0aW9uKGxlbmd0aCkgewoJICBsZW5ndGggPSBsZW5ndGggPT0gbnVsbCA/ICh0aGlzLmJ5dGVMZW5ndGgtdGhpcy5wb3NpdGlvbikgOiBsZW5ndGg7CgkgIHZhciBhcnIgPSBuZXcgVWludDhBcnJheShsZW5ndGgpOwoJICBEYXRhU3RyZWFtLm1lbWNweShhcnIuYnVmZmVyLCAwLAoJICAgICAgICAgICAgICAgICAgICB0aGlzLmJ1ZmZlciwgdGhpcy5ieXRlT2Zmc2V0K3RoaXMucG9zaXRpb24sCgkgICAgICAgICAgICAgICAgICAgIGxlbmd0aCphcnIuQllURVNfUEVSX0VMRU1FTlQpOwoJICB0aGlzLnBvc2l0aW9uICs9IGFyci5ieXRlTGVuZ3RoOwoJICByZXR1cm4gYXJyOwoJfTsKCgkvKioKCSAgUmVhZHMgYSBGbG9hdDY0QXJyYXkgb2YgZGVzaXJlZCBsZW5ndGggYW5kIGVuZGlhbm5lc3MgZnJvbSB0aGUgRGF0YVN0cmVhbS4KCgkgIEBwYXJhbSB7bnVtYmVyfSBsZW5ndGggTnVtYmVyIG9mIGVsZW1lbnRzIHRvIG1hcC4KCSAgQHBhcmFtIHs/Ym9vbGVhbn0gZSBFbmRpYW5uZXNzIG9mIHRoZSBkYXRhIHRvIHJlYWQuCgkgIEByZXR1cm4ge09iamVjdH0gVGhlIHJlYWQgRmxvYXQ2NEFycmF5LgoJICovCglEYXRhU3RyZWFtLnByb3RvdHlwZS5yZWFkRmxvYXQ2NEFycmF5ID0gZnVuY3Rpb24obGVuZ3RoLCBlKSB7CgkgIGxlbmd0aCA9IGxlbmd0aCA9PSBudWxsID8gKHRoaXMuYnl0ZUxlbmd0aC10aGlzLnBvc2l0aW9uIC8gOCkgOiBsZW5ndGg7CgkgIHZhciBhcnIgPSBuZXcgRmxvYXQ2NEFycmF5KGxlbmd0aCk7CgkgIERhdGFTdHJlYW0ubWVtY3B5KGFyci5idWZmZXIsIDAsCgkgICAgICAgICAgICAgICAgICAgIHRoaXMuYnVmZmVyLCB0aGlzLmJ5dGVPZmZzZXQrdGhpcy5wb3NpdGlvbiwKCSAgICAgICAgICAgICAgICAgICAgbGVuZ3RoKmFyci5CWVRFU19QRVJfRUxFTUVOVCk7CgkgIERhdGFTdHJlYW0uYXJyYXlUb05hdGl2ZShhcnIsIGUgPT0gbnVsbCA/IHRoaXMuZW5kaWFubmVzcyA6IGUpOwoJICB0aGlzLnBvc2l0aW9uICs9IGFyci5ieXRlTGVuZ3RoOwoJICByZXR1cm4gYXJyOwoJfTsKCgkvKioKCSAgUmVhZHMgYSBGbG9hdDMyQXJyYXkgb2YgZGVzaXJlZCBsZW5ndGggYW5kIGVuZGlhbm5lc3MgZnJvbSB0aGUgRGF0YVN0cmVhbS4KCgkgIEBwYXJhbSB7bnVtYmVyfSBsZW5ndGggTnVtYmVyIG9mIGVsZW1lbnRzIHRvIG1hcC4KCSAgQHBhcmFtIHs/Ym9vbGVhbn0gZSBFbmRpYW5uZXNzIG9mIHRoZSBkYXRhIHRvIHJlYWQuCgkgIEByZXR1cm4ge09iamVjdH0gVGhlIHJlYWQgRmxvYXQzMkFycmF5LgoJICovCglEYXRhU3RyZWFtLnByb3RvdHlwZS5yZWFkRmxvYXQzMkFycmF5ID0gZnVuY3Rpb24obGVuZ3RoLCBlKSB7CgkgIGxlbmd0aCA9IGxlbmd0aCA9PSBudWxsID8gKHRoaXMuYnl0ZUxlbmd0aC10aGlzLnBvc2l0aW9uIC8gNCkgOiBsZW5ndGg7CgkgIHZhciBhcnIgPSBuZXcgRmxvYXQzMkFycmF5KGxlbmd0aCk7CgkgIERhdGFTdHJlYW0ubWVtY3B5KGFyci5idWZmZXIsIDAsCgkgICAgICAgICAgICAgICAgICAgIHRoaXMuYnVmZmVyLCB0aGlzLmJ5dGVPZmZzZXQrdGhpcy5wb3NpdGlvbiwKCSAgICAgICAgICAgICAgICAgICAgbGVuZ3RoKmFyci5CWVRFU19QRVJfRUxFTUVOVCk7CgkgIERhdGFTdHJlYW0uYXJyYXlUb05hdGl2ZShhcnIsIGUgPT0gbnVsbCA/IHRoaXMuZW5kaWFubmVzcyA6IGUpOwoJICB0aGlzLnBvc2l0aW9uICs9IGFyci5ieXRlTGVuZ3RoOwoJICByZXR1cm4gYXJyOwoJfTsKCgoJLyoqCgkgIFJlYWRzIGEgMzItYml0IGludCBmcm9tIHRoZSBEYXRhU3RyZWFtIHdpdGggdGhlIGRlc2lyZWQgZW5kaWFubmVzcy4KCgkgIEBwYXJhbSB7P2Jvb2xlYW59IGUgRW5kaWFubmVzcyBvZiB0aGUgbnVtYmVyLgoJICBAcmV0dXJuIHtudW1iZXJ9IFRoZSByZWFkIG51bWJlci4KCSAqLwoJRGF0YVN0cmVhbS5wcm90b3R5cGUucmVhZEludDMyID0gZnVuY3Rpb24oZSkgewoJICB2YXIgdiA9IHRoaXMuX2RhdGFWaWV3LmdldEludDMyKHRoaXMucG9zaXRpb24sIGUgPT0gbnVsbCA/IHRoaXMuZW5kaWFubmVzcyA6IGUpOwoJICB0aGlzLnBvc2l0aW9uICs9IDQ7CgkgIHJldHVybiB2OwoJfTsKCgkvKioKCSAgUmVhZHMgYSAxNi1iaXQgaW50IGZyb20gdGhlIERhdGFTdHJlYW0gd2l0aCB0aGUgZGVzaXJlZCBlbmRpYW5uZXNzLgoKCSAgQHBhcmFtIHs/Ym9vbGVhbn0gZSBFbmRpYW5uZXNzIG9mIHRoZSBudW1iZXIuCgkgIEByZXR1cm4ge251bWJlcn0gVGhlIHJlYWQgbnVtYmVyLgoJICovCglEYXRhU3RyZWFtLnByb3RvdHlwZS5yZWFkSW50MTYgPSBmdW5jdGlvbihlKSB7CgkgIHZhciB2ID0gdGhpcy5fZGF0YVZpZXcuZ2V0SW50MTYodGhpcy5wb3NpdGlvbiwgZSA9PSBudWxsID8gdGhpcy5lbmRpYW5uZXNzIDogZSk7CgkgIHRoaXMucG9zaXRpb24gKz0gMjsKCSAgcmV0dXJuIHY7Cgl9OwoKCS8qKgoJICBSZWFkcyBhbiA4LWJpdCBpbnQgZnJvbSB0aGUgRGF0YVN0cmVhbS4KCgkgIEByZXR1cm4ge251bWJlcn0gVGhlIHJlYWQgbnVtYmVyLgoJICovCglEYXRhU3RyZWFtLnByb3RvdHlwZS5yZWFkSW50OCA9IGZ1bmN0aW9uKCkgewoJICB2YXIgdiA9IHRoaXMuX2RhdGFWaWV3LmdldEludDgodGhpcy5wb3NpdGlvbik7CgkgIHRoaXMucG9zaXRpb24gKz0gMTsKCSAgcmV0dXJuIHY7Cgl9OwoKCS8qKgoJICBSZWFkcyBhIDMyLWJpdCB1bnNpZ25lZCBpbnQgZnJvbSB0aGUgRGF0YVN0cmVhbSB3aXRoIHRoZSBkZXNpcmVkIGVuZGlhbm5lc3MuCgoJICBAcGFyYW0gez9ib29sZWFufSBlIEVuZGlhbm5lc3Mgb2YgdGhlIG51bWJlci4KCSAgQHJldHVybiB7bnVtYmVyfSBUaGUgcmVhZCBudW1iZXIuCgkgKi8KCURhdGFTdHJlYW0ucHJvdG90eXBlLnJlYWRVaW50MzIgPSBmdW5jdGlvbihlKSB7CgkgIHZhciB2ID0gdGhpcy5fZGF0YVZpZXcuZ2V0VWludDMyKHRoaXMucG9zaXRpb24sIGUgPT0gbnVsbCA/IHRoaXMuZW5kaWFubmVzcyA6IGUpOwoJICB0aGlzLnBvc2l0aW9uICs9IDQ7CgkgIHJldHVybiB2OwoJfTsKCgkvKioKCSAgUmVhZHMgYSAxNi1iaXQgdW5zaWduZWQgaW50IGZyb20gdGhlIERhdGFTdHJlYW0gd2l0aCB0aGUgZGVzaXJlZCBlbmRpYW5uZXNzLgoKCSAgQHBhcmFtIHs/Ym9vbGVhbn0gZSBFbmRpYW5uZXNzIG9mIHRoZSBudW1iZXIuCgkgIEByZXR1cm4ge251bWJlcn0gVGhlIHJlYWQgbnVtYmVyLgoJICovCglEYXRhU3RyZWFtLnByb3RvdHlwZS5yZWFkVWludDE2ID0gZnVuY3Rpb24oZSkgewoJICB2YXIgdiA9IHRoaXMuX2RhdGFWaWV3LmdldFVpbnQxNih0aGlzLnBvc2l0aW9uLCBlID09IG51bGwgPyB0aGlzLmVuZGlhbm5lc3MgOiBlKTsKCSAgdGhpcy5wb3NpdGlvbiArPSAyOwoJICByZXR1cm4gdjsKCX07CgoJLyoqCgkgIFJlYWRzIGFuIDgtYml0IHVuc2lnbmVkIGludCBmcm9tIHRoZSBEYXRhU3RyZWFtLgoKCSAgQHJldHVybiB7bnVtYmVyfSBUaGUgcmVhZCBudW1iZXIuCgkgKi8KCURhdGFTdHJlYW0ucHJvdG90eXBlLnJlYWRVaW50OCA9IGZ1bmN0aW9uKCkgewoJICB2YXIgdiA9IHRoaXMuX2RhdGFWaWV3LmdldFVpbnQ4KHRoaXMucG9zaXRpb24pOwoJICB0aGlzLnBvc2l0aW9uICs9IDE7CgkgIHJldHVybiB2OwoJfTsKCgkvKioKCSAgUmVhZHMgYSAzMi1iaXQgZmxvYXQgZnJvbSB0aGUgRGF0YVN0cmVhbSB3aXRoIHRoZSBkZXNpcmVkIGVuZGlhbm5lc3MuCgoJICBAcGFyYW0gez9ib29sZWFufSBlIEVuZGlhbm5lc3Mgb2YgdGhlIG51bWJlci4KCSAgQHJldHVybiB7bnVtYmVyfSBUaGUgcmVhZCBudW1iZXIuCgkgKi8KCURhdGFTdHJlYW0ucHJvdG90eXBlLnJlYWRGbG9hdDMyID0gZnVuY3Rpb24oZSkgewoJICB2YXIgdiA9IHRoaXMuX2RhdGFWaWV3LmdldEZsb2F0MzIodGhpcy5wb3NpdGlvbiwgZSA9PSBudWxsID8gdGhpcy5lbmRpYW5uZXNzIDogZSk7CgkgIHRoaXMucG9zaXRpb24gKz0gNDsKCSAgcmV0dXJuIHY7Cgl9OwoKCS8qKgoJICBSZWFkcyBhIDY0LWJpdCBmbG9hdCBmcm9tIHRoZSBEYXRhU3RyZWFtIHdpdGggdGhlIGRlc2lyZWQgZW5kaWFubmVzcy4KCgkgIEBwYXJhbSB7P2Jvb2xlYW59IGUgRW5kaWFubmVzcyBvZiB0aGUgbnVtYmVyLgoJICBAcmV0dXJuIHtudW1iZXJ9IFRoZSByZWFkIG51bWJlci4KCSAqLwoJRGF0YVN0cmVhbS5wcm90b3R5cGUucmVhZEZsb2F0NjQgPSBmdW5jdGlvbihlKSB7CgkgIHZhciB2ID0gdGhpcy5fZGF0YVZpZXcuZ2V0RmxvYXQ2NCh0aGlzLnBvc2l0aW9uLCBlID09IG51bGwgPyB0aGlzLmVuZGlhbm5lc3MgOiBlKTsKCSAgdGhpcy5wb3NpdGlvbiArPSA4OwoJICByZXR1cm4gdjsKCX07CgoJLyoqCgkgIE5hdGl2ZSBlbmRpYW5uZXNzLiBFaXRoZXIgRGF0YVN0cmVhbS5CSUdfRU5ESUFOIG9yIERhdGFTdHJlYW0uTElUVExFX0VORElBTgoJICBkZXBlbmRpbmcgb24gdGhlIHBsYXRmb3JtIGVuZGlhbm5lc3MuCgoJICBAdHlwZSB7Ym9vbGVhbn0KCSAqLwoJRGF0YVN0cmVhbS5lbmRpYW5uZXNzID0gbmV3IEludDhBcnJheShuZXcgSW50MTZBcnJheShbMV0pLmJ1ZmZlcilbMF0gPiAwOwoKCS8qKgoJICBDb3BpZXMgYnl0ZUxlbmd0aCBieXRlcyBmcm9tIHRoZSBzcmMgYnVmZmVyIGF0IHNyY09mZnNldCB0byB0aGUKCSAgZHN0IGJ1ZmZlciBhdCBkc3RPZmZzZXQuCgoJICBAcGFyYW0ge09iamVjdH0gZHN0IERlc3RpbmF0aW9uIEFycmF5QnVmZmVyIHRvIHdyaXRlIHRvLgoJICBAcGFyYW0ge251bWJlcn0gZHN0T2Zmc2V0IE9mZnNldCB0byB0aGUgZGVzdGluYXRpb24gQXJyYXlCdWZmZXIuCgkgIEBwYXJhbSB7T2JqZWN0fSBzcmMgU291cmNlIEFycmF5QnVmZmVyIHRvIHJlYWQgZnJvbS4KCSAgQHBhcmFtIHtudW1iZXJ9IHNyY09mZnNldCBPZmZzZXQgdG8gdGhlIHNvdXJjZSBBcnJheUJ1ZmZlci4KCSAgQHBhcmFtIHtudW1iZXJ9IGJ5dGVMZW5ndGggTnVtYmVyIG9mIGJ5dGVzIHRvIGNvcHkuCgkgKi8KCURhdGFTdHJlYW0ubWVtY3B5ID0gZnVuY3Rpb24oZHN0LCBkc3RPZmZzZXQsIHNyYywgc3JjT2Zmc2V0LCBieXRlTGVuZ3RoKSB7CgkgIHZhciBkc3RVOCA9IG5ldyBVaW50OEFycmF5KGRzdCwgZHN0T2Zmc2V0LCBieXRlTGVuZ3RoKTsKCSAgdmFyIHNyY1U4ID0gbmV3IFVpbnQ4QXJyYXkoc3JjLCBzcmNPZmZzZXQsIGJ5dGVMZW5ndGgpOwoJICBkc3RVOC5zZXQoc3JjVTgpOwoJfTsKCgkvKioKCSAgQ29udmVydHMgYXJyYXkgdG8gbmF0aXZlIGVuZGlhbm5lc3MgaW4tcGxhY2UuCgoJICBAcGFyYW0ge09iamVjdH0gYXJyYXkgVHlwZWQgYXJyYXkgdG8gY29udmVydC4KCSAgQHBhcmFtIHtib29sZWFufSBhcnJheUlzTGl0dGxlRW5kaWFuIFRydWUgaWYgdGhlIGRhdGEgaW4gdGhlIGFycmF5IGlzCgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaXR0bGUtZW5kaWFuLiBTZXQgZmFsc2UgZm9yIGJpZy1lbmRpYW4uCgkgIEByZXR1cm4ge09iamVjdH0gVGhlIGNvbnZlcnRlZCB0eXBlZCBhcnJheS4KCSAqLwoJRGF0YVN0cmVhbS5hcnJheVRvTmF0aXZlID0gZnVuY3Rpb24oYXJyYXksIGFycmF5SXNMaXR0bGVFbmRpYW4pIHsKCSAgaWYgKGFycmF5SXNMaXR0bGVFbmRpYW4gPT0gdGhpcy5lbmRpYW5uZXNzKSB7CgkgICAgcmV0dXJuIGFycmF5OwoJICB9IGVsc2UgewoJICAgIHJldHVybiB0aGlzLmZsaXBBcnJheUVuZGlhbm5lc3MoYXJyYXkpOwoJICB9Cgl9OwoKCS8qKgoJICBDb252ZXJ0cyBuYXRpdmUgZW5kaWFubmVzcyBhcnJheSB0byBkZXNpcmVkIGVuZGlhbm5lc3MgaW4tcGxhY2UuCgoJICBAcGFyYW0ge09iamVjdH0gYXJyYXkgVHlwZWQgYXJyYXkgdG8gY29udmVydC4KCSAgQHBhcmFtIHtib29sZWFufSBsaXR0bGVFbmRpYW4gVHJ1ZSBpZiB0aGUgY29udmVydGVkIGFycmF5IHNob3VsZCBiZQoJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaXR0bGUtZW5kaWFuLiBTZXQgZmFsc2UgZm9yIGJpZy1lbmRpYW4uCgkgIEByZXR1cm4ge09iamVjdH0gVGhlIGNvbnZlcnRlZCB0eXBlZCBhcnJheS4KCSAqLwoJRGF0YVN0cmVhbS5uYXRpdmVUb0VuZGlhbiA9IGZ1bmN0aW9uKGFycmF5LCBsaXR0bGVFbmRpYW4pIHsKCSAgaWYgKHRoaXMuZW5kaWFubmVzcyA9PSBsaXR0bGVFbmRpYW4pIHsKCSAgICByZXR1cm4gYXJyYXk7CgkgIH0gZWxzZSB7CgkgICAgcmV0dXJuIHRoaXMuZmxpcEFycmF5RW5kaWFubmVzcyhhcnJheSk7CgkgIH0KCX07CgoJLyoqCgkgIEZsaXBzIHR5cGVkIGFycmF5IGVuZGlhbm5lc3MgaW4tcGxhY2UuCgoJICBAcGFyYW0ge09iamVjdH0gYXJyYXkgVHlwZWQgYXJyYXkgdG8gZmxpcC4KCSAgQHJldHVybiB7T2JqZWN0fSBUaGUgY29udmVydGVkIHR5cGVkIGFycmF5LgoJICovCglEYXRhU3RyZWFtLmZsaXBBcnJheUVuZGlhbm5lc3MgPSBmdW5jdGlvbihhcnJheSkgewoJICB2YXIgdTggPSBuZXcgVWludDhBcnJheShhcnJheS5idWZmZXIsIGFycmF5LmJ5dGVPZmZzZXQsIGFycmF5LmJ5dGVMZW5ndGgpOwoJICBmb3IgKHZhciBpPTA7IGk8YXJyYXkuYnl0ZUxlbmd0aDsgaSs9YXJyYXkuQllURVNfUEVSX0VMRU1FTlQpIHsKCSAgICBmb3IgKHZhciBqPWkrYXJyYXkuQllURVNfUEVSX0VMRU1FTlQtMSwgaz1pOyBqPms7IGotLSwgaysrKSB7CgkgICAgICB2YXIgdG1wID0gdThba107CgkgICAgICB1OFtrXSA9IHU4W2pdOwoJICAgICAgdThbal0gPSB0bXA7CgkgICAgfQoJICB9CgkgIHJldHVybiBhcnJheTsKCX07CgoJLyoqCgkgIFNlZWsgcG9zaXRpb24gd2hlcmUgRGF0YVN0cmVhbSNyZWFkU3RydWN0IHJhbiBpbnRvIGEgcHJvYmxlbS4KCSAgVXNlZnVsIGZvciBkZWJ1Z2dpbmcgc3RydWN0IHBhcnNpbmcuCgoJICBAdHlwZSB7bnVtYmVyfQoJICovCglEYXRhU3RyZWFtLnByb3RvdHlwZS5mYWlsdXJlUG9zaXRpb24gPSAwOwoKCVN0cmluZy5mcm9tQ2hhckNvZGVVaW50OCA9IGZ1bmN0aW9uKHVpbnQ4YXJyKSB7CgkgICAgdmFyIGFyciA9IFtdOwoJICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdWludDhhcnIubGVuZ3RoOyBpKyspIHsKCSAgICAgIGFycltpXSA9IHVpbnQ4YXJyW2ldOwoJICAgIH0KCSAgICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShudWxsLCBhcnIpOwoJfTsKCS8qKgoJICBSZWFkIGEgc3RyaW5nIG9mIGRlc2lyZWQgbGVuZ3RoIGFuZCBlbmNvZGluZyBmcm9tIHRoZSBEYXRhU3RyZWFtLgoKCSAgQHBhcmFtIHtudW1iZXJ9IGxlbmd0aCBUaGUgbGVuZ3RoIG9mIHRoZSBzdHJpbmcgdG8gcmVhZCBpbiBieXRlcy4KCSAgQHBhcmFtIHs/c3RyaW5nfSBlbmNvZGluZyBUaGUgZW5jb2Rpbmcgb2YgdGhlIHN0cmluZyBkYXRhIGluIHRoZSBEYXRhU3RyZWFtLgoJICAgICAgICAgICAgICAgICAgICAgICAgICAgIERlZmF1bHRzIHRvIEFTQ0lJLgoJICBAcmV0dXJuIHtzdHJpbmd9IFRoZSByZWFkIHN0cmluZy4KCSAqLwoJRGF0YVN0cmVhbS5wcm90b3R5cGUucmVhZFN0cmluZyA9IGZ1bmN0aW9uKGxlbmd0aCwgZW5jb2RpbmcpIHsKCSAgaWYgKGVuY29kaW5nID09IG51bGwgfHwgZW5jb2RpbmcgPT0gIkFTQ0lJIikgewoJICAgIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlVWludDguYXBwbHkobnVsbCwgW3RoaXMubWFwVWludDhBcnJheShsZW5ndGggPT0gbnVsbCA/IHRoaXMuYnl0ZUxlbmd0aC10aGlzLnBvc2l0aW9uIDogbGVuZ3RoKV0pOwoJICB9IGVsc2UgewoJICAgIHJldHVybiAobmV3IFRleHREZWNvZGVyKGVuY29kaW5nKSkuZGVjb2RlKHRoaXMubWFwVWludDhBcnJheShsZW5ndGgpKTsKCSAgfQoJfTsKCgkvKioKCSAgUmVhZCBudWxsLXRlcm1pbmF0ZWQgc3RyaW5nIG9mIGRlc2lyZWQgbGVuZ3RoIGZyb20gdGhlIERhdGFTdHJlYW0uIFRydW5jYXRlcwoJICB0aGUgcmV0dXJuZWQgc3RyaW5nIHNvIHRoYXQgdGhlIG51bGwgYnl0ZSBpcyBub3QgYSBwYXJ0IG9mIGl0LgoKCSAgQHBhcmFtIHs/bnVtYmVyfSBsZW5ndGggVGhlIGxlbmd0aCBvZiB0aGUgc3RyaW5nIHRvIHJlYWQuCgkgIEByZXR1cm4ge3N0cmluZ30gVGhlIHJlYWQgc3RyaW5nLgoJICovCglEYXRhU3RyZWFtLnByb3RvdHlwZS5yZWFkQ1N0cmluZyA9IGZ1bmN0aW9uKGxlbmd0aCkgewoJICB2YXIgYmxlbiA9IHRoaXMuYnl0ZUxlbmd0aC10aGlzLnBvc2l0aW9uOwoJICB2YXIgdTggPSBuZXcgVWludDhBcnJheSh0aGlzLl9idWZmZXIsIHRoaXMuX2J5dGVPZmZzZXQgKyB0aGlzLnBvc2l0aW9uKTsKCSAgdmFyIGxlbiA9IGJsZW47CgkgIGlmIChsZW5ndGggIT0gbnVsbCkgewoJICAgIGxlbiA9IE1hdGgubWluKGxlbmd0aCwgYmxlbik7CgkgIH0KCSAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW4gJiYgdThbaV0gIT09IDA7IGkrKyk7IC8vIGZpbmQgZmlyc3QgemVybyBieXRlCgkgIHZhciBzID0gU3RyaW5nLmZyb21DaGFyQ29kZVVpbnQ4LmFwcGx5KG51bGwsIFt0aGlzLm1hcFVpbnQ4QXJyYXkoaSldKTsKCSAgaWYgKGxlbmd0aCAhPSBudWxsKSB7CgkgICAgdGhpcy5wb3NpdGlvbiArPSBsZW4taTsKCSAgfSBlbHNlIGlmIChpICE9IGJsZW4pIHsKCSAgICB0aGlzLnBvc2l0aW9uICs9IDE7IC8vIHRyYWlsaW5nIHplcm8gaWYgbm90IGF0IGVuZCBvZiBidWZmZXIKCSAgfQoJICByZXR1cm4gczsKCX07CgoJLyogCgkgICBUT0RPOiBmaXggZW5kaWFubmVzcyBmb3IgMjQvNjQtYml0IGZpZWxkcwoJICAgVE9ETzogY2hlY2sgcmFuZ2Uvc3VwcG9ydCBmb3IgNjQtYml0cyBudW1iZXJzIGluIEphdmFTY3JpcHQKCSovCgl2YXIgTUFYX1NJWkUgPSBNYXRoLnBvdygyLCAzMik7CgoJRGF0YVN0cmVhbS5wcm90b3R5cGUucmVhZEludDY0ID0gZnVuY3Rpb24gKCkgewoJICByZXR1cm4gKHRoaXMucmVhZEludDMyKCkqTUFYX1NJWkUpK3RoaXMucmVhZFVpbnQzMigpOwoJfTsKCURhdGFTdHJlYW0ucHJvdG90eXBlLnJlYWRVaW50NjQgPSBmdW5jdGlvbiAoKSB7CgkJcmV0dXJuICh0aGlzLnJlYWRVaW50MzIoKSpNQVhfU0laRSkrdGhpcy5yZWFkVWludDMyKCk7Cgl9OwoKCURhdGFTdHJlYW0ucHJvdG90eXBlLnJlYWRJbnQ2NCA9IGZ1bmN0aW9uICgpIHsKCSAgcmV0dXJuICh0aGlzLnJlYWRVaW50MzIoKSpNQVhfU0laRSkrdGhpcy5yZWFkVWludDMyKCk7Cgl9OwoKCURhdGFTdHJlYW0ucHJvdG90eXBlLnJlYWRVaW50MjQgPSBmdW5jdGlvbiAoKSB7CgkJcmV0dXJuICh0aGlzLnJlYWRVaW50OCgpPDwxNikrKHRoaXMucmVhZFVpbnQ4KCk8PDgpK3RoaXMucmVhZFVpbnQ4KCk7Cgl9OwoKCXsKCSAgZXhwb3J0cy5EYXRhU3RyZWFtID0gRGF0YVN0cmVhbTsgIAoJfQoJLy8gZmlsZTpzcmMvRGF0YVN0cmVhbS13cml0ZS5qcwoJLyoqCgkgIFNhdmVzIHRoZSBEYXRhU3RyZWFtIGNvbnRlbnRzIHRvIHRoZSBnaXZlbiBmaWxlbmFtZS4KCSAgVXNlcyBDaHJvbWUncyBhbmNob3IgZG93bmxvYWQgcHJvcGVydHkgdG8gaW5pdGlhdGUgZG93bmxvYWQuCgkgCgkgIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSBGaWxlbmFtZSB0byBzYXZlIGFzLgoJICBAcmV0dXJuIHtudWxsfQoJICAqLwoJRGF0YVN0cmVhbS5wcm90b3R5cGUuc2F2ZSA9IGZ1bmN0aW9uKGZpbGVuYW1lKSB7CgkgIHZhciBibG9iID0gbmV3IEJsb2IoW3RoaXMuYnVmZmVyXSk7CgkgIGlmICh3aW5kb3cuVVJMICYmIFVSTC5jcmVhdGVPYmplY3RVUkwpIHsKCSAgICAgIHZhciB1cmwgPSB3aW5kb3cuVVJMLmNyZWF0ZU9iamVjdFVSTChibG9iKTsKCSAgICAgIHZhciBhID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYScpOwoJICAgICAgLy8gUmVxdWlyZWQgaW4gRmlyZWZveDoKCSAgICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoYSk7CgkgICAgICBhLnNldEF0dHJpYnV0ZSgnaHJlZicsIHVybCk7CgkgICAgICBhLnNldEF0dHJpYnV0ZSgnZG93bmxvYWQnLCBmaWxlbmFtZSk7CgkgICAgICAvLyBSZXF1aXJlZCBpbiBGaXJlZm94OgoJICAgICAgYS5zZXRBdHRyaWJ1dGUoJ3RhcmdldCcsICdfc2VsZicpOwoJICAgICAgYS5jbGljaygpOwoJICAgICAgd2luZG93LlVSTC5yZXZva2VPYmplY3RVUkwodXJsKTsKCSAgfSBlbHNlIHsKCSAgICAgIHRocm93KCJEYXRhU3RyZWFtLnNhdmU6IENhbid0IGNyZWF0ZSBvYmplY3QgVVJMLiIpOwoJICB9Cgl9OwoKCS8qKgoJICBXaGV0aGVyIHRvIGV4dGVuZCBEYXRhU3RyZWFtIGJ1ZmZlciB3aGVuIHRyeWluZyB0byB3cml0ZSBiZXlvbmQgaXRzIHNpemUuCgkgIElmIHNldCwgdGhlIGJ1ZmZlciBpcyByZWFsbG9jYXRlZCB0byB0d2ljZSBpdHMgY3VycmVudCBzaXplIHVudGlsIHRoZQoJICByZXF1ZXN0ZWQgd3JpdGUgZml0cyB0aGUgYnVmZmVyLgoJICBAdHlwZSB7Ym9vbGVhbn0KCSAgKi8KCURhdGFTdHJlYW0ucHJvdG90eXBlLl9keW5hbWljU2l6ZSA9IHRydWU7CglPYmplY3QuZGVmaW5lUHJvcGVydHkoRGF0YVN0cmVhbS5wcm90b3R5cGUsICdkeW5hbWljU2l6ZScsCgkgIHsgZ2V0OiBmdW5jdGlvbigpIHsKCSAgICAgIHJldHVybiB0aGlzLl9keW5hbWljU2l6ZTsKCSAgICB9LAoJICAgIHNldDogZnVuY3Rpb24odikgewoJICAgICAgaWYgKCF2KSB7CgkgICAgICAgIHRoaXMuX3RyaW1BbGxvYygpOwoJICAgICAgfQoJICAgICAgdGhpcy5fZHluYW1pY1NpemUgPSB2OwoJICAgIH0gfSk7CgoJLyoqCgkgIEludGVybmFsIGZ1bmN0aW9uIHRvIHRyaW0gdGhlIERhdGFTdHJlYW0gYnVmZmVyIHdoZW4gcmVxdWlyZWQuCgkgIFVzZWQgZm9yIHN0cmlwcGluZyBvdXQgdGhlIGZpcnN0IGJ5dGVzIHdoZW4gbm90IG5lZWRlZCBhbnltb3JlLgoKCSAgQHJldHVybiB7bnVsbH0KCSAgKi8KCURhdGFTdHJlYW0ucHJvdG90eXBlLnNoaWZ0ID0gZnVuY3Rpb24ob2Zmc2V0KSB7CgkgIHZhciBidWYgPSBuZXcgQXJyYXlCdWZmZXIodGhpcy5fYnl0ZUxlbmd0aC1vZmZzZXQpOwoJICB2YXIgZHN0ID0gbmV3IFVpbnQ4QXJyYXkoYnVmKTsKCSAgdmFyIHNyYyA9IG5ldyBVaW50OEFycmF5KHRoaXMuX2J1ZmZlciwgb2Zmc2V0LCBkc3QubGVuZ3RoKTsKCSAgZHN0LnNldChzcmMpOwoJICB0aGlzLmJ1ZmZlciA9IGJ1ZjsKCSAgdGhpcy5wb3NpdGlvbiAtPSBvZmZzZXQ7Cgl9OwoKCS8qKgoJICBXcml0ZXMgYW4gSW50MzJBcnJheSBvZiBzcGVjaWZpZWQgZW5kaWFubmVzcyB0byB0aGUgRGF0YVN0cmVhbS4KCgkgIEBwYXJhbSB7T2JqZWN0fSBhcnIgVGhlIGFycmF5IHRvIHdyaXRlLgoJICBAcGFyYW0gez9ib29sZWFufSBlIEVuZGlhbm5lc3Mgb2YgdGhlIGRhdGEgdG8gd3JpdGUuCgkgKi8KCURhdGFTdHJlYW0ucHJvdG90eXBlLndyaXRlSW50MzJBcnJheSA9IGZ1bmN0aW9uKGFyciwgZSkgewoJICB0aGlzLl9yZWFsbG9jKGFyci5sZW5ndGggKiA0KTsKCSAgaWYgKGFyciBpbnN0YW5jZW9mIEludDMyQXJyYXkgJiYKCSAgICAgIHRoaXMuYnl0ZU9mZnNldCt0aGlzLnBvc2l0aW9uICUgYXJyLkJZVEVTX1BFUl9FTEVNRU5UID09PSAwKSB7CgkgICAgRGF0YVN0cmVhbS5tZW1jcHkodGhpcy5fYnVmZmVyLCB0aGlzLmJ5dGVPZmZzZXQrdGhpcy5wb3NpdGlvbiwKCSAgICAgICAgICAgICAgICAgICAgICBhcnIuYnVmZmVyLCAwLAoJICAgICAgICAgICAgICAgICAgICAgIGFyci5ieXRlTGVuZ3RoKTsKCSAgICB0aGlzLm1hcEludDMyQXJyYXkoYXJyLmxlbmd0aCwgZSk7CgkgIH0gZWxzZSB7CgkgICAgZm9yICh2YXIgaT0wOyBpPGFyci5sZW5ndGg7IGkrKykgewoJICAgICAgdGhpcy53cml0ZUludDMyKGFycltpXSwgZSk7CgkgICAgfQoJICB9Cgl9OwoKCS8qKgoJICBXcml0ZXMgYW4gSW50MTZBcnJheSBvZiBzcGVjaWZpZWQgZW5kaWFubmVzcyB0byB0aGUgRGF0YVN0cmVhbS4KCgkgIEBwYXJhbSB7T2JqZWN0fSBhcnIgVGhlIGFycmF5IHRvIHdyaXRlLgoJICBAcGFyYW0gez9ib29sZWFufSBlIEVuZGlhbm5lc3Mgb2YgdGhlIGRhdGEgdG8gd3JpdGUuCgkgKi8KCURhdGFTdHJlYW0ucHJvdG90eXBlLndyaXRlSW50MTZBcnJheSA9IGZ1bmN0aW9uKGFyciwgZSkgewoJICB0aGlzLl9yZWFsbG9jKGFyci5sZW5ndGggKiAyKTsKCSAgaWYgKGFyciBpbnN0YW5jZW9mIEludDE2QXJyYXkgJiYKCSAgICAgIHRoaXMuYnl0ZU9mZnNldCt0aGlzLnBvc2l0aW9uICUgYXJyLkJZVEVTX1BFUl9FTEVNRU5UID09PSAwKSB7CgkgICAgRGF0YVN0cmVhbS5tZW1jcHkodGhpcy5fYnVmZmVyLCB0aGlzLmJ5dGVPZmZzZXQrdGhpcy5wb3NpdGlvbiwKCSAgICAgICAgICAgICAgICAgICAgICBhcnIuYnVmZmVyLCAwLAoJICAgICAgICAgICAgICAgICAgICAgIGFyci5ieXRlTGVuZ3RoKTsKCSAgICB0aGlzLm1hcEludDE2QXJyYXkoYXJyLmxlbmd0aCwgZSk7CgkgIH0gZWxzZSB7CgkgICAgZm9yICh2YXIgaT0wOyBpPGFyci5sZW5ndGg7IGkrKykgewoJICAgICAgdGhpcy53cml0ZUludDE2KGFycltpXSwgZSk7CgkgICAgfQoJICB9Cgl9OwoKCS8qKgoJICBXcml0ZXMgYW4gSW50OEFycmF5IHRvIHRoZSBEYXRhU3RyZWFtLgoKCSAgQHBhcmFtIHtPYmplY3R9IGFyciBUaGUgYXJyYXkgdG8gd3JpdGUuCgkgKi8KCURhdGFTdHJlYW0ucHJvdG90eXBlLndyaXRlSW50OEFycmF5ID0gZnVuY3Rpb24oYXJyKSB7CgkgIHRoaXMuX3JlYWxsb2MoYXJyLmxlbmd0aCAqIDEpOwoJICBpZiAoYXJyIGluc3RhbmNlb2YgSW50OEFycmF5ICYmCgkgICAgICB0aGlzLmJ5dGVPZmZzZXQrdGhpcy5wb3NpdGlvbiAlIGFyci5CWVRFU19QRVJfRUxFTUVOVCA9PT0gMCkgewoJICAgIERhdGFTdHJlYW0ubWVtY3B5KHRoaXMuX2J1ZmZlciwgdGhpcy5ieXRlT2Zmc2V0K3RoaXMucG9zaXRpb24sCgkgICAgICAgICAgICAgICAgICAgICAgYXJyLmJ1ZmZlciwgMCwKCSAgICAgICAgICAgICAgICAgICAgICBhcnIuYnl0ZUxlbmd0aCk7CgkgICAgdGhpcy5tYXBJbnQ4QXJyYXkoYXJyLmxlbmd0aCk7CgkgIH0gZWxzZSB7CgkgICAgZm9yICh2YXIgaT0wOyBpPGFyci5sZW5ndGg7IGkrKykgewoJICAgICAgdGhpcy53cml0ZUludDgoYXJyW2ldKTsKCSAgICB9CgkgIH0KCX07CgoJLyoqCgkgIFdyaXRlcyBhIFVpbnQzMkFycmF5IG9mIHNwZWNpZmllZCBlbmRpYW5uZXNzIHRvIHRoZSBEYXRhU3RyZWFtLgoKCSAgQHBhcmFtIHtPYmplY3R9IGFyciBUaGUgYXJyYXkgdG8gd3JpdGUuCgkgIEBwYXJhbSB7P2Jvb2xlYW59IGUgRW5kaWFubmVzcyBvZiB0aGUgZGF0YSB0byB3cml0ZS4KCSAqLwoJRGF0YVN0cmVhbS5wcm90b3R5cGUud3JpdGVVaW50MzJBcnJheSA9IGZ1bmN0aW9uKGFyciwgZSkgewoJICB0aGlzLl9yZWFsbG9jKGFyci5sZW5ndGggKiA0KTsKCSAgaWYgKGFyciBpbnN0YW5jZW9mIFVpbnQzMkFycmF5ICYmCgkgICAgICB0aGlzLmJ5dGVPZmZzZXQrdGhpcy5wb3NpdGlvbiAlIGFyci5CWVRFU19QRVJfRUxFTUVOVCA9PT0gMCkgewoJICAgIERhdGFTdHJlYW0ubWVtY3B5KHRoaXMuX2J1ZmZlciwgdGhpcy5ieXRlT2Zmc2V0K3RoaXMucG9zaXRpb24sCgkgICAgICAgICAgICAgICAgICAgICAgYXJyLmJ1ZmZlciwgMCwKCSAgICAgICAgICAgICAgICAgICAgICBhcnIuYnl0ZUxlbmd0aCk7CgkgICAgdGhpcy5tYXBVaW50MzJBcnJheShhcnIubGVuZ3RoLCBlKTsKCSAgfSBlbHNlIHsKCSAgICBmb3IgKHZhciBpPTA7IGk8YXJyLmxlbmd0aDsgaSsrKSB7CgkgICAgICB0aGlzLndyaXRlVWludDMyKGFycltpXSwgZSk7CgkgICAgfQoJICB9Cgl9OwoKCS8qKgoJICBXcml0ZXMgYSBVaW50MTZBcnJheSBvZiBzcGVjaWZpZWQgZW5kaWFubmVzcyB0byB0aGUgRGF0YVN0cmVhbS4KCgkgIEBwYXJhbSB7T2JqZWN0fSBhcnIgVGhlIGFycmF5IHRvIHdyaXRlLgoJICBAcGFyYW0gez9ib29sZWFufSBlIEVuZGlhbm5lc3Mgb2YgdGhlIGRhdGEgdG8gd3JpdGUuCgkgKi8KCURhdGFTdHJlYW0ucHJvdG90eXBlLndyaXRlVWludDE2QXJyYXkgPSBmdW5jdGlvbihhcnIsIGUpIHsKCSAgdGhpcy5fcmVhbGxvYyhhcnIubGVuZ3RoICogMik7CgkgIGlmIChhcnIgaW5zdGFuY2VvZiBVaW50MTZBcnJheSAmJgoJICAgICAgdGhpcy5ieXRlT2Zmc2V0K3RoaXMucG9zaXRpb24gJSBhcnIuQllURVNfUEVSX0VMRU1FTlQgPT09IDApIHsKCSAgICBEYXRhU3RyZWFtLm1lbWNweSh0aGlzLl9idWZmZXIsIHRoaXMuYnl0ZU9mZnNldCt0aGlzLnBvc2l0aW9uLAoJICAgICAgICAgICAgICAgICAgICAgIGFyci5idWZmZXIsIDAsCgkgICAgICAgICAgICAgICAgICAgICAgYXJyLmJ5dGVMZW5ndGgpOwoJICAgIHRoaXMubWFwVWludDE2QXJyYXkoYXJyLmxlbmd0aCwgZSk7CgkgIH0gZWxzZSB7CgkgICAgZm9yICh2YXIgaT0wOyBpPGFyci5sZW5ndGg7IGkrKykgewoJICAgICAgdGhpcy53cml0ZVVpbnQxNihhcnJbaV0sIGUpOwoJICAgIH0KCSAgfQoJfTsKCgkvKioKCSAgV3JpdGVzIGEgVWludDhBcnJheSB0byB0aGUgRGF0YVN0cmVhbS4KCgkgIEBwYXJhbSB7T2JqZWN0fSBhcnIgVGhlIGFycmF5IHRvIHdyaXRlLgoJICovCglEYXRhU3RyZWFtLnByb3RvdHlwZS53cml0ZVVpbnQ4QXJyYXkgPSBmdW5jdGlvbihhcnIpIHsKCSAgdGhpcy5fcmVhbGxvYyhhcnIubGVuZ3RoICogMSk7CgkgIGlmIChhcnIgaW5zdGFuY2VvZiBVaW50OEFycmF5ICYmCgkgICAgICB0aGlzLmJ5dGVPZmZzZXQrdGhpcy5wb3NpdGlvbiAlIGFyci5CWVRFU19QRVJfRUxFTUVOVCA9PT0gMCkgewoJICAgIERhdGFTdHJlYW0ubWVtY3B5KHRoaXMuX2J1ZmZlciwgdGhpcy5ieXRlT2Zmc2V0K3RoaXMucG9zaXRpb24sCgkgICAgICAgICAgICAgICAgICAgICAgYXJyLmJ1ZmZlciwgMCwKCSAgICAgICAgICAgICAgICAgICAgICBhcnIuYnl0ZUxlbmd0aCk7CgkgICAgdGhpcy5tYXBVaW50OEFycmF5KGFyci5sZW5ndGgpOwoJICB9IGVsc2UgewoJICAgIGZvciAodmFyIGk9MDsgaTxhcnIubGVuZ3RoOyBpKyspIHsKCSAgICAgIHRoaXMud3JpdGVVaW50OChhcnJbaV0pOwoJICAgIH0KCSAgfQoJfTsKCgkvKioKCSAgV3JpdGVzIGEgRmxvYXQ2NEFycmF5IG9mIHNwZWNpZmllZCBlbmRpYW5uZXNzIHRvIHRoZSBEYXRhU3RyZWFtLgoKCSAgQHBhcmFtIHtPYmplY3R9IGFyciBUaGUgYXJyYXkgdG8gd3JpdGUuCgkgIEBwYXJhbSB7P2Jvb2xlYW59IGUgRW5kaWFubmVzcyBvZiB0aGUgZGF0YSB0byB3cml0ZS4KCSAqLwoJRGF0YVN0cmVhbS5wcm90b3R5cGUud3JpdGVGbG9hdDY0QXJyYXkgPSBmdW5jdGlvbihhcnIsIGUpIHsKCSAgdGhpcy5fcmVhbGxvYyhhcnIubGVuZ3RoICogOCk7CgkgIGlmIChhcnIgaW5zdGFuY2VvZiBGbG9hdDY0QXJyYXkgJiYKCSAgICAgIHRoaXMuYnl0ZU9mZnNldCt0aGlzLnBvc2l0aW9uICUgYXJyLkJZVEVTX1BFUl9FTEVNRU5UID09PSAwKSB7CgkgICAgRGF0YVN0cmVhbS5tZW1jcHkodGhpcy5fYnVmZmVyLCB0aGlzLmJ5dGVPZmZzZXQrdGhpcy5wb3NpdGlvbiwKCSAgICAgICAgICAgICAgICAgICAgICBhcnIuYnVmZmVyLCAwLAoJICAgICAgICAgICAgICAgICAgICAgIGFyci5ieXRlTGVuZ3RoKTsKCSAgICB0aGlzLm1hcEZsb2F0NjRBcnJheShhcnIubGVuZ3RoLCBlKTsKCSAgfSBlbHNlIHsKCSAgICBmb3IgKHZhciBpPTA7IGk8YXJyLmxlbmd0aDsgaSsrKSB7CgkgICAgICB0aGlzLndyaXRlRmxvYXQ2NChhcnJbaV0sIGUpOwoJICAgIH0KCSAgfQoJfTsKCgkvKioKCSAgV3JpdGVzIGEgRmxvYXQzMkFycmF5IG9mIHNwZWNpZmllZCBlbmRpYW5uZXNzIHRvIHRoZSBEYXRhU3RyZWFtLgoKCSAgQHBhcmFtIHtPYmplY3R9IGFyciBUaGUgYXJyYXkgdG8gd3JpdGUuCgkgIEBwYXJhbSB7P2Jvb2xlYW59IGUgRW5kaWFubmVzcyBvZiB0aGUgZGF0YSB0byB3cml0ZS4KCSAqLwoJRGF0YVN0cmVhbS5wcm90b3R5cGUud3JpdGVGbG9hdDMyQXJyYXkgPSBmdW5jdGlvbihhcnIsIGUpIHsKCSAgdGhpcy5fcmVhbGxvYyhhcnIubGVuZ3RoICogNCk7CgkgIGlmIChhcnIgaW5zdGFuY2VvZiBGbG9hdDMyQXJyYXkgJiYKCSAgICAgIHRoaXMuYnl0ZU9mZnNldCt0aGlzLnBvc2l0aW9uICUgYXJyLkJZVEVTX1BFUl9FTEVNRU5UID09PSAwKSB7CgkgICAgRGF0YVN0cmVhbS5tZW1jcHkodGhpcy5fYnVmZmVyLCB0aGlzLmJ5dGVPZmZzZXQrdGhpcy5wb3NpdGlvbiwKCSAgICAgICAgICAgICAgICAgICAgICBhcnIuYnVmZmVyLCAwLAoJICAgICAgICAgICAgICAgICAgICAgIGFyci5ieXRlTGVuZ3RoKTsKCSAgICB0aGlzLm1hcEZsb2F0MzJBcnJheShhcnIubGVuZ3RoLCBlKTsKCSAgfSBlbHNlIHsKCSAgICBmb3IgKHZhciBpPTA7IGk8YXJyLmxlbmd0aDsgaSsrKSB7CgkgICAgICB0aGlzLndyaXRlRmxvYXQzMihhcnJbaV0sIGUpOwoJICAgIH0KCSAgfQoJfTsKCgoJLyoqCgkgIFdyaXRlcyBhIDMyLWJpdCBpbnQgdG8gdGhlIERhdGFTdHJlYW0gd2l0aCB0aGUgZGVzaXJlZCBlbmRpYW5uZXNzLgoKCSAgQHBhcmFtIHtudW1iZXJ9IHYgTnVtYmVyIHRvIHdyaXRlLgoJICBAcGFyYW0gez9ib29sZWFufSBlIEVuZGlhbm5lc3Mgb2YgdGhlIG51bWJlci4KCSAqLwoJRGF0YVN0cmVhbS5wcm90b3R5cGUud3JpdGVJbnQzMiA9IGZ1bmN0aW9uKHYsIGUpIHsKCSAgdGhpcy5fcmVhbGxvYyg0KTsKCSAgdGhpcy5fZGF0YVZpZXcuc2V0SW50MzIodGhpcy5wb3NpdGlvbiwgdiwgZSA9PSBudWxsID8gdGhpcy5lbmRpYW5uZXNzIDogZSk7CgkgIHRoaXMucG9zaXRpb24gKz0gNDsKCX07CgoJLyoqCgkgIFdyaXRlcyBhIDE2LWJpdCBpbnQgdG8gdGhlIERhdGFTdHJlYW0gd2l0aCB0aGUgZGVzaXJlZCBlbmRpYW5uZXNzLgoKCSAgQHBhcmFtIHtudW1iZXJ9IHYgTnVtYmVyIHRvIHdyaXRlLgoJICBAcGFyYW0gez9ib29sZWFufSBlIEVuZGlhbm5lc3Mgb2YgdGhlIG51bWJlci4KCSAqLwoJRGF0YVN0cmVhbS5wcm90b3R5cGUud3JpdGVJbnQxNiA9IGZ1bmN0aW9uKHYsIGUpIHsKCSAgdGhpcy5fcmVhbGxvYygyKTsKCSAgdGhpcy5fZGF0YVZpZXcuc2V0SW50MTYodGhpcy5wb3NpdGlvbiwgdiwgZSA9PSBudWxsID8gdGhpcy5lbmRpYW5uZXNzIDogZSk7CgkgIHRoaXMucG9zaXRpb24gKz0gMjsKCX07CgoJLyoqCgkgIFdyaXRlcyBhbiA4LWJpdCBpbnQgdG8gdGhlIERhdGFTdHJlYW0uCgoJICBAcGFyYW0ge251bWJlcn0gdiBOdW1iZXIgdG8gd3JpdGUuCgkgKi8KCURhdGFTdHJlYW0ucHJvdG90eXBlLndyaXRlSW50OCA9IGZ1bmN0aW9uKHYpIHsKCSAgdGhpcy5fcmVhbGxvYygxKTsKCSAgdGhpcy5fZGF0YVZpZXcuc2V0SW50OCh0aGlzLnBvc2l0aW9uLCB2KTsKCSAgdGhpcy5wb3NpdGlvbiArPSAxOwoJfTsKCgkvKioKCSAgV3JpdGVzIGEgMzItYml0IHVuc2lnbmVkIGludCB0byB0aGUgRGF0YVN0cmVhbSB3aXRoIHRoZSBkZXNpcmVkIGVuZGlhbm5lc3MuCgoJICBAcGFyYW0ge251bWJlcn0gdiBOdW1iZXIgdG8gd3JpdGUuCgkgIEBwYXJhbSB7P2Jvb2xlYW59IGUgRW5kaWFubmVzcyBvZiB0aGUgbnVtYmVyLgoJICovCglEYXRhU3RyZWFtLnByb3RvdHlwZS53cml0ZVVpbnQzMiA9IGZ1bmN0aW9uKHYsIGUpIHsKCSAgdGhpcy5fcmVhbGxvYyg0KTsKCSAgdGhpcy5fZGF0YVZpZXcuc2V0VWludDMyKHRoaXMucG9zaXRpb24sIHYsIGUgPT0gbnVsbCA/IHRoaXMuZW5kaWFubmVzcyA6IGUpOwoJICB0aGlzLnBvc2l0aW9uICs9IDQ7Cgl9OwoKCS8qKgoJICBXcml0ZXMgYSAxNi1iaXQgdW5zaWduZWQgaW50IHRvIHRoZSBEYXRhU3RyZWFtIHdpdGggdGhlIGRlc2lyZWQgZW5kaWFubmVzcy4KCgkgIEBwYXJhbSB7bnVtYmVyfSB2IE51bWJlciB0byB3cml0ZS4KCSAgQHBhcmFtIHs/Ym9vbGVhbn0gZSBFbmRpYW5uZXNzIG9mIHRoZSBudW1iZXIuCgkgKi8KCURhdGFTdHJlYW0ucHJvdG90eXBlLndyaXRlVWludDE2ID0gZnVuY3Rpb24odiwgZSkgewoJICB0aGlzLl9yZWFsbG9jKDIpOwoJICB0aGlzLl9kYXRhVmlldy5zZXRVaW50MTYodGhpcy5wb3NpdGlvbiwgdiwgZSA9PSBudWxsID8gdGhpcy5lbmRpYW5uZXNzIDogZSk7CgkgIHRoaXMucG9zaXRpb24gKz0gMjsKCX07CgoJLyoqCgkgIFdyaXRlcyBhbiA4LWJpdCB1bnNpZ25lZCAgaW50IHRvIHRoZSBEYXRhU3RyZWFtLgoKCSAgQHBhcmFtIHtudW1iZXJ9IHYgTnVtYmVyIHRvIHdyaXRlLgoJICovCglEYXRhU3RyZWFtLnByb3RvdHlwZS53cml0ZVVpbnQ4ID0gZnVuY3Rpb24odikgewoJICB0aGlzLl9yZWFsbG9jKDEpOwoJICB0aGlzLl9kYXRhVmlldy5zZXRVaW50OCh0aGlzLnBvc2l0aW9uLCB2KTsKCSAgdGhpcy5wb3NpdGlvbiArPSAxOwoJfTsKCgkvKioKCSAgV3JpdGVzIGEgMzItYml0IGZsb2F0IHRvIHRoZSBEYXRhU3RyZWFtIHdpdGggdGhlIGRlc2lyZWQgZW5kaWFubmVzcy4KCgkgIEBwYXJhbSB7bnVtYmVyfSB2IE51bWJlciB0byB3cml0ZS4KCSAgQHBhcmFtIHs/Ym9vbGVhbn0gZSBFbmRpYW5uZXNzIG9mIHRoZSBudW1iZXIuCgkgKi8KCURhdGFTdHJlYW0ucHJvdG90eXBlLndyaXRlRmxvYXQzMiA9IGZ1bmN0aW9uKHYsIGUpIHsKCSAgdGhpcy5fcmVhbGxvYyg0KTsKCSAgdGhpcy5fZGF0YVZpZXcuc2V0RmxvYXQzMih0aGlzLnBvc2l0aW9uLCB2LCBlID09IG51bGwgPyB0aGlzLmVuZGlhbm5lc3MgOiBlKTsKCSAgdGhpcy5wb3NpdGlvbiArPSA0OwoJfTsKCgkvKioKCSAgV3JpdGVzIGEgNjQtYml0IGZsb2F0IHRvIHRoZSBEYXRhU3RyZWFtIHdpdGggdGhlIGRlc2lyZWQgZW5kaWFubmVzcy4KCgkgIEBwYXJhbSB7bnVtYmVyfSB2IE51bWJlciB0byB3cml0ZS4KCSAgQHBhcmFtIHs/Ym9vbGVhbn0gZSBFbmRpYW5uZXNzIG9mIHRoZSBudW1iZXIuCgkgKi8KCURhdGFTdHJlYW0ucHJvdG90eXBlLndyaXRlRmxvYXQ2NCA9IGZ1bmN0aW9uKHYsIGUpIHsKCSAgdGhpcy5fcmVhbGxvYyg4KTsKCSAgdGhpcy5fZGF0YVZpZXcuc2V0RmxvYXQ2NCh0aGlzLnBvc2l0aW9uLCB2LCBlID09IG51bGwgPyB0aGlzLmVuZGlhbm5lc3MgOiBlKTsKCSAgdGhpcy5wb3NpdGlvbiArPSA4OwoJfTsKCgkvKioKCSAgV3JpdGUgYSBVQ1MtMiBzdHJpbmcgb2YgZGVzaXJlZCBlbmRpYW5uZXNzIHRvIHRoZSBEYXRhU3RyZWFtLiBUaGUKCSAgbGVuZ3RoT3ZlcnJpZGUgYXJndW1lbnQgbGV0cyB5b3UgZGVmaW5lIHRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byB3cml0ZS4KCSAgSWYgdGhlIHN0cmluZyBpcyBzaG9ydGVyIHRoYW4gbGVuZ3RoT3ZlcnJpZGUsIHRoZSBleHRyYSBzcGFjZSBpcyBwYWRkZWQgd2l0aAoJICB6ZXJvZXMuCgoJICBAcGFyYW0ge3N0cmluZ30gc3RyIFRoZSBzdHJpbmcgdG8gd3JpdGUuCgkgIEBwYXJhbSB7P2Jvb2xlYW59IGVuZGlhbm5lc3MgVGhlIGVuZGlhbm5lc3MgdG8gdXNlIGZvciB0aGUgd3JpdHRlbiBzdHJpbmcgZGF0YS4KCSAgQHBhcmFtIHs/bnVtYmVyfSBsZW5ndGhPdmVycmlkZSBUaGUgbnVtYmVyIG9mIGNoYXJhY3RlcnMgdG8gd3JpdGUuCgkgKi8KCURhdGFTdHJlYW0ucHJvdG90eXBlLndyaXRlVUNTMlN0cmluZyA9IGZ1bmN0aW9uKHN0ciwgZW5kaWFubmVzcywgbGVuZ3RoT3ZlcnJpZGUpIHsKCSAgaWYgKGxlbmd0aE92ZXJyaWRlID09IG51bGwpIHsKCSAgICBsZW5ndGhPdmVycmlkZSA9IHN0ci5sZW5ndGg7CgkgIH0KCSAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoICYmIGkgPCBsZW5ndGhPdmVycmlkZTsgaSsrKSB7CgkgICAgdGhpcy53cml0ZVVpbnQxNihzdHIuY2hhckNvZGVBdChpKSwgZW5kaWFubmVzcyk7CgkgIH0KCSAgZm9yICg7IGk8bGVuZ3RoT3ZlcnJpZGU7IGkrKykgewoJICAgIHRoaXMud3JpdGVVaW50MTYoMCk7CgkgIH0KCX07CgoJLyoqCgkgIFdyaXRlcyBhIHN0cmluZyBvZiBkZXNpcmVkIGxlbmd0aCBhbmQgZW5jb2RpbmcgdG8gdGhlIERhdGFTdHJlYW0uCgoJICBAcGFyYW0ge3N0cmluZ30gcyBUaGUgc3RyaW5nIHRvIHdyaXRlLgoJICBAcGFyYW0gez9zdHJpbmd9IGVuY29kaW5nIFRoZSBlbmNvZGluZyBmb3IgdGhlIHdyaXR0ZW4gc3RyaW5nIGRhdGEuCgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGVmYXVsdHMgdG8gQVNDSUkuCgkgIEBwYXJhbSB7P251bWJlcn0gbGVuZ3RoIFRoZSBudW1iZXIgb2YgY2hhcmFjdGVycyB0byB3cml0ZS4KCSAqLwoJRGF0YVN0cmVhbS5wcm90b3R5cGUud3JpdGVTdHJpbmcgPSBmdW5jdGlvbihzLCBlbmNvZGluZywgbGVuZ3RoKSB7CgkgIHZhciBpID0gMDsKCSAgaWYgKGVuY29kaW5nID09IG51bGwgfHwgZW5jb2RpbmcgPT0gIkFTQ0lJIikgewoJICAgIGlmIChsZW5ndGggIT0gbnVsbCkgewoJICAgICAgdmFyIGxlbiA9IE1hdGgubWluKHMubGVuZ3RoLCBsZW5ndGgpOwoJICAgICAgZm9yIChpPTA7IGk8bGVuOyBpKyspIHsKCSAgICAgICAgdGhpcy53cml0ZVVpbnQ4KHMuY2hhckNvZGVBdChpKSk7CgkgICAgICB9CgkgICAgICBmb3IgKDsgaTxsZW5ndGg7IGkrKykgewoJICAgICAgICB0aGlzLndyaXRlVWludDgoMCk7CgkgICAgICB9CgkgICAgfSBlbHNlIHsKCSAgICAgIGZvciAoaT0wOyBpPHMubGVuZ3RoOyBpKyspIHsKCSAgICAgICAgdGhpcy53cml0ZVVpbnQ4KHMuY2hhckNvZGVBdChpKSk7CgkgICAgICB9CgkgICAgfQoJICB9IGVsc2UgewoJICAgIHRoaXMud3JpdGVVaW50OEFycmF5KChuZXcgVGV4dEVuY29kZXIoZW5jb2RpbmcpKS5lbmNvZGUocy5zdWJzdHJpbmcoMCwgbGVuZ3RoKSkpOwoJICB9Cgl9OwoKCS8qKgoJICBXcml0ZXMgYSBudWxsLXRlcm1pbmF0ZWQgc3RyaW5nIHRvIERhdGFTdHJlYW0gYW5kIHplcm8tcGFkcyBpdCB0byBsZW5ndGgKCSAgYnl0ZXMuIElmIGxlbmd0aCBpcyBub3QgZ2l2ZW4sIHdyaXRlcyB0aGUgc3RyaW5nIGZvbGxvd2VkIGJ5IGEgemVyby4KCSAgSWYgc3RyaW5nIGlzIGxvbmdlciB0aGFuIGxlbmd0aCwgdGhlIHdyaXR0ZW4gcGFydCBvZiB0aGUgc3RyaW5nIGRvZXMgbm90IGhhdmUKCSAgYSB0cmFpbGluZyB6ZXJvLgoKCSAgQHBhcmFtIHtzdHJpbmd9IHMgVGhlIHN0cmluZyB0byB3cml0ZS4KCSAgQHBhcmFtIHs/bnVtYmVyfSBsZW5ndGggVGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRvIHdyaXRlLgoJICovCglEYXRhU3RyZWFtLnByb3RvdHlwZS53cml0ZUNTdHJpbmcgPSBmdW5jdGlvbihzLCBsZW5ndGgpIHsKCSAgdmFyIGkgPSAwOwoJICBpZiAobGVuZ3RoICE9IG51bGwpIHsKCSAgICB2YXIgbGVuID0gTWF0aC5taW4ocy5sZW5ndGgsIGxlbmd0aCk7CgkgICAgZm9yIChpPTA7IGk8bGVuOyBpKyspIHsKCSAgICAgIHRoaXMud3JpdGVVaW50OChzLmNoYXJDb2RlQXQoaSkpOwoJICAgIH0KCSAgICBmb3IgKDsgaTxsZW5ndGg7IGkrKykgewoJICAgICAgdGhpcy53cml0ZVVpbnQ4KDApOwoJICAgIH0KCSAgfSBlbHNlIHsKCSAgICBmb3IgKGk9MDsgaTxzLmxlbmd0aDsgaSsrKSB7CgkgICAgICB0aGlzLndyaXRlVWludDgocy5jaGFyQ29kZUF0KGkpKTsKCSAgICB9CgkgICAgdGhpcy53cml0ZVVpbnQ4KDApOwoJICB9Cgl9OwoKCS8qKgoJICBXcml0ZXMgYSBzdHJ1Y3QgdG8gdGhlIERhdGFTdHJlYW0uIFRha2VzIGEgc3RydWN0RGVmaW5pdGlvbiB0aGF0IGdpdmVzIHRoZQoJICB0eXBlcyBhbmQgYSBzdHJ1Y3Qgb2JqZWN0IHRoYXQgZ2l2ZXMgdGhlIHZhbHVlcy4gUmVmZXIgdG8gcmVhZFN0cnVjdCBmb3IgdGhlCgkgIHN0cnVjdHVyZSBvZiBzdHJ1Y3REZWZpbml0aW9uLgoKCSAgQHBhcmFtIHtPYmplY3R9IHN0cnVjdERlZmluaXRpb24gVHlwZSBkZWZpbml0aW9uIG9mIHRoZSBzdHJ1Y3QuCgkgIEBwYXJhbSB7T2JqZWN0fSBzdHJ1Y3QgVGhlIHN0cnVjdCBkYXRhIG9iamVjdC4KCSAgKi8KCURhdGFTdHJlYW0ucHJvdG90eXBlLndyaXRlU3RydWN0ID0gZnVuY3Rpb24oc3RydWN0RGVmaW5pdGlvbiwgc3RydWN0KSB7CgkgIGZvciAodmFyIGkgPSAwOyBpIDwgc3RydWN0RGVmaW5pdGlvbi5sZW5ndGg7IGkrPTIpIHsKCSAgICB2YXIgdCA9IHN0cnVjdERlZmluaXRpb25baSsxXTsKCSAgICB0aGlzLndyaXRlVHlwZSh0LCBzdHJ1Y3Rbc3RydWN0RGVmaW5pdGlvbltpXV0sIHN0cnVjdCk7CgkgIH0KCX07CgoJLyoqCgkgIFdyaXRlcyBvYmplY3QgdiBvZiB0eXBlIHQgdG8gdGhlIERhdGFTdHJlYW0uCgoJICBAcGFyYW0ge09iamVjdH0gdCBUeXBlIG9mIGRhdGEgdG8gd3JpdGUuCgkgIEBwYXJhbSB7T2JqZWN0fSB2IFZhbHVlIG9mIGRhdGEgdG8gd3JpdGUuCgkgIEBwYXJhbSB7T2JqZWN0fSBzdHJ1Y3QgU3RydWN0IHRvIHBhc3MgdG8gd3JpdGUgY2FsbGJhY2sgZnVuY3Rpb25zLgoJICAqLwoJRGF0YVN0cmVhbS5wcm90b3R5cGUud3JpdGVUeXBlID0gZnVuY3Rpb24odCwgdiwgc3RydWN0KSB7CgkgIHZhciB0cDsKCSAgaWYgKHR5cGVvZiB0ID09ICJmdW5jdGlvbiIpIHsKCSAgICByZXR1cm4gdCh0aGlzLCB2KTsKCSAgfSBlbHNlIGlmICh0eXBlb2YgdCA9PSAib2JqZWN0IiAmJiAhKHQgaW5zdGFuY2VvZiBBcnJheSkpIHsKCSAgICByZXR1cm4gdC5zZXQodGhpcywgdiwgc3RydWN0KTsKCSAgfQoJICB2YXIgbGVuZ3RoT3ZlcnJpZGUgPSBudWxsOwoJICB2YXIgY2hhcnNldCA9ICJBU0NJSSI7CgkgIHZhciBwb3MgPSB0aGlzLnBvc2l0aW9uOwoJICBpZiAodHlwZW9mKHQpID09ICdzdHJpbmcnICYmIC86Ly50ZXN0KHQpKSB7CgkgICAgdHAgPSB0LnNwbGl0KCI6Iik7CgkgICAgdCA9IHRwWzBdOwoJICAgIGxlbmd0aE92ZXJyaWRlID0gcGFyc2VJbnQodHBbMV0pOwoJICB9CgkgIGlmICh0eXBlb2YgdCA9PSAnc3RyaW5nJyAmJiAvLC8udGVzdCh0KSkgewoJICAgIHRwID0gdC5zcGxpdCgiLCIpOwoJICAgIHQgPSB0cFswXTsKCSAgICBjaGFyc2V0ID0gcGFyc2VJbnQodHBbMV0pOwoJICB9CgoJICBzd2l0Y2godCkgewoJICAgIGNhc2UgJ3VpbnQ4JzoKCSAgICAgIHRoaXMud3JpdGVVaW50OCh2KTsKCSAgICAgIGJyZWFrOwoJICAgIGNhc2UgJ2ludDgnOgoJICAgICAgdGhpcy53cml0ZUludDgodik7CgkgICAgICBicmVhazsKCgkgICAgY2FzZSAndWludDE2JzoKCSAgICAgIHRoaXMud3JpdGVVaW50MTYodiwgdGhpcy5lbmRpYW5uZXNzKTsKCSAgICAgIGJyZWFrOwoJICAgIGNhc2UgJ2ludDE2JzoKCSAgICAgIHRoaXMud3JpdGVJbnQxNih2LCB0aGlzLmVuZGlhbm5lc3MpOwoJICAgICAgYnJlYWs7CgkgICAgY2FzZSAndWludDMyJzoKCSAgICAgIHRoaXMud3JpdGVVaW50MzIodiwgdGhpcy5lbmRpYW5uZXNzKTsKCSAgICAgIGJyZWFrOwoJICAgIGNhc2UgJ2ludDMyJzoKCSAgICAgIHRoaXMud3JpdGVJbnQzMih2LCB0aGlzLmVuZGlhbm5lc3MpOwoJICAgICAgYnJlYWs7CgkgICAgY2FzZSAnZmxvYXQzMic6CgkgICAgICB0aGlzLndyaXRlRmxvYXQzMih2LCB0aGlzLmVuZGlhbm5lc3MpOwoJICAgICAgYnJlYWs7CgkgICAgY2FzZSAnZmxvYXQ2NCc6CgkgICAgICB0aGlzLndyaXRlRmxvYXQ2NCh2LCB0aGlzLmVuZGlhbm5lc3MpOwoJICAgICAgYnJlYWs7CgoJICAgIGNhc2UgJ3VpbnQxNmJlJzoKCSAgICAgIHRoaXMud3JpdGVVaW50MTYodiwgRGF0YVN0cmVhbS5CSUdfRU5ESUFOKTsKCSAgICAgIGJyZWFrOwoJICAgIGNhc2UgJ2ludDE2YmUnOgoJICAgICAgdGhpcy53cml0ZUludDE2KHYsIERhdGFTdHJlYW0uQklHX0VORElBTik7CgkgICAgICBicmVhazsKCSAgICBjYXNlICd1aW50MzJiZSc6CgkgICAgICB0aGlzLndyaXRlVWludDMyKHYsIERhdGFTdHJlYW0uQklHX0VORElBTik7CgkgICAgICBicmVhazsKCSAgICBjYXNlICdpbnQzMmJlJzoKCSAgICAgIHRoaXMud3JpdGVJbnQzMih2LCBEYXRhU3RyZWFtLkJJR19FTkRJQU4pOwoJICAgICAgYnJlYWs7CgkgICAgY2FzZSAnZmxvYXQzMmJlJzoKCSAgICAgIHRoaXMud3JpdGVGbG9hdDMyKHYsIERhdGFTdHJlYW0uQklHX0VORElBTik7CgkgICAgICBicmVhazsKCSAgICBjYXNlICdmbG9hdDY0YmUnOgoJICAgICAgdGhpcy53cml0ZUZsb2F0NjQodiwgRGF0YVN0cmVhbS5CSUdfRU5ESUFOKTsKCSAgICAgIGJyZWFrOwoKCSAgICBjYXNlICd1aW50MTZsZSc6CgkgICAgICB0aGlzLndyaXRlVWludDE2KHYsIERhdGFTdHJlYW0uTElUVExFX0VORElBTik7CgkgICAgICBicmVhazsKCSAgICBjYXNlICdpbnQxNmxlJzoKCSAgICAgIHRoaXMud3JpdGVJbnQxNih2LCBEYXRhU3RyZWFtLkxJVFRMRV9FTkRJQU4pOwoJICAgICAgYnJlYWs7CgkgICAgY2FzZSAndWludDMybGUnOgoJICAgICAgdGhpcy53cml0ZVVpbnQzMih2LCBEYXRhU3RyZWFtLkxJVFRMRV9FTkRJQU4pOwoJICAgICAgYnJlYWs7CgkgICAgY2FzZSAnaW50MzJsZSc6CgkgICAgICB0aGlzLndyaXRlSW50MzIodiwgRGF0YVN0cmVhbS5MSVRUTEVfRU5ESUFOKTsKCSAgICAgIGJyZWFrOwoJICAgIGNhc2UgJ2Zsb2F0MzJsZSc6CgkgICAgICB0aGlzLndyaXRlRmxvYXQzMih2LCBEYXRhU3RyZWFtLkxJVFRMRV9FTkRJQU4pOwoJICAgICAgYnJlYWs7CgkgICAgY2FzZSAnZmxvYXQ2NGxlJzoKCSAgICAgIHRoaXMud3JpdGVGbG9hdDY0KHYsIERhdGFTdHJlYW0uTElUVExFX0VORElBTik7CgkgICAgICBicmVhazsKCgkgICAgY2FzZSAnY3N0cmluZyc6CgkgICAgICB0aGlzLndyaXRlQ1N0cmluZyh2LCBsZW5ndGhPdmVycmlkZSk7CgkgICAgICBicmVhazsKCgkgICAgY2FzZSAnc3RyaW5nJzoKCSAgICAgIHRoaXMud3JpdGVTdHJpbmcodiwgY2hhcnNldCwgbGVuZ3RoT3ZlcnJpZGUpOwoJICAgICAgYnJlYWs7CgoJICAgIGNhc2UgJ3UxNnN0cmluZyc6CgkgICAgICB0aGlzLndyaXRlVUNTMlN0cmluZyh2LCB0aGlzLmVuZGlhbm5lc3MsIGxlbmd0aE92ZXJyaWRlKTsKCSAgICAgIGJyZWFrOwoKCSAgICBjYXNlICd1MTZzdHJpbmdsZSc6CgkgICAgICB0aGlzLndyaXRlVUNTMlN0cmluZyh2LCBEYXRhU3RyZWFtLkxJVFRMRV9FTkRJQU4sIGxlbmd0aE92ZXJyaWRlKTsKCSAgICAgIGJyZWFrOwoKCSAgICBjYXNlICd1MTZzdHJpbmdiZSc6CgkgICAgICB0aGlzLndyaXRlVUNTMlN0cmluZyh2LCBEYXRhU3RyZWFtLkJJR19FTkRJQU4sIGxlbmd0aE92ZXJyaWRlKTsKCSAgICAgIGJyZWFrOwoKCSAgICBkZWZhdWx0OgoJICAgICAgaWYgKHQubGVuZ3RoID09IDMpIHsKCSAgICAgICAgdmFyIHRhID0gdFsxXTsKCSAgICAgICAgZm9yICh2YXIgaT0wOyBpPHYubGVuZ3RoOyBpKyspIHsKCSAgICAgICAgICB0aGlzLndyaXRlVHlwZSh0YSwgdltpXSk7CgkgICAgICAgIH0KCSAgICAgICAgYnJlYWs7CgkgICAgICB9IGVsc2UgewoJICAgICAgICB0aGlzLndyaXRlU3RydWN0KHQsIHYpOwoJICAgICAgICBicmVhazsKCSAgICAgIH0KCSAgfQoJICBpZiAobGVuZ3RoT3ZlcnJpZGUgIT0gbnVsbCkgewoJICAgIHRoaXMucG9zaXRpb24gPSBwb3M7CgkgICAgdGhpcy5fcmVhbGxvYyhsZW5ndGhPdmVycmlkZSk7CgkgICAgdGhpcy5wb3NpdGlvbiA9IHBvcyArIGxlbmd0aE92ZXJyaWRlOwoJICB9Cgl9OwoKCglEYXRhU3RyZWFtLnByb3RvdHlwZS53cml0ZVVpbnQ2NCA9IGZ1bmN0aW9uICh2KSB7CgkJdmFyIGggPSBNYXRoLmZsb29yKHYgLyBNQVhfU0laRSk7CgkJdGhpcy53cml0ZVVpbnQzMihoKTsKCQl0aGlzLndyaXRlVWludDMyKHYgJiAweEZGRkZGRkZGKTsKCX07CgoJRGF0YVN0cmVhbS5wcm90b3R5cGUud3JpdGVVaW50MjQgPSBmdW5jdGlvbiAodikgewoJCXRoaXMud3JpdGVVaW50OCgodiAmIDB4MDBGRjAwMDApPj4xNik7CgkJdGhpcy53cml0ZVVpbnQ4KCh2ICYgMHgwMDAwRkYwMCk+PjgpOwoJCXRoaXMud3JpdGVVaW50OCgodiAmIDB4MDAwMDAwRkYpKTsKCX07CgoJRGF0YVN0cmVhbS5wcm90b3R5cGUuYWRqdXN0VWludDMyID0gZnVuY3Rpb24ocG9zaXRpb24sIHZhbHVlKSB7CgkJdmFyIHBvcyA9IHRoaXMucG9zaXRpb247CgkJdGhpcy5zZWVrKHBvc2l0aW9uKTsKCQl0aGlzLndyaXRlVWludDMyKHZhbHVlKTsKCQl0aGlzLnNlZWsocG9zKTsKCX07CgkvLyBmaWxlOnNyYy9EYXRhU3RyZWFtLW1hcC5qcwoJLyoqCgkgIE1hcHMgYW4gSW50MzJBcnJheSBpbnRvIHRoZSBEYXRhU3RyZWFtIGJ1ZmZlciwgc3dpenpsaW5nIGl0IHRvIG5hdGl2ZQoJICBlbmRpYW5uZXNzIGluLXBsYWNlLiBUaGUgY3VycmVudCBvZmZzZXQgZnJvbSB0aGUgc3RhcnQgb2YgdGhlIGJ1ZmZlciBuZWVkcyB0bwoJICBiZSBhIG11bHRpcGxlIG9mIGVsZW1lbnQgc2l6ZSwganVzdCBsaWtlIHdpdGggdHlwZWQgYXJyYXkgdmlld3MuCgoJICBOaWNlIGZvciBxdWlja2x5IHJlYWRpbmcgaW4gZGF0YS4gV2FybmluZzogcG90ZW50aWFsbHkgbW9kaWZpZXMgdGhlIGJ1ZmZlcgoJICBjb250ZW50cy4KCgkgIEBwYXJhbSB7bnVtYmVyfSBsZW5ndGggTnVtYmVyIG9mIGVsZW1lbnRzIHRvIG1hcC4KCSAgQHBhcmFtIHs/Ym9vbGVhbn0gZSBFbmRpYW5uZXNzIG9mIHRoZSBkYXRhIHRvIHJlYWQuCgkgIEByZXR1cm4ge09iamVjdH0gSW50MzJBcnJheSB0byB0aGUgRGF0YVN0cmVhbSBiYWNraW5nIGJ1ZmZlci4KCSAgKi8KCURhdGFTdHJlYW0ucHJvdG90eXBlLm1hcEludDMyQXJyYXkgPSBmdW5jdGlvbihsZW5ndGgsIGUpIHsKCSAgdGhpcy5fcmVhbGxvYyhsZW5ndGggKiA0KTsKCSAgdmFyIGFyciA9IG5ldyBJbnQzMkFycmF5KHRoaXMuX2J1ZmZlciwgdGhpcy5ieXRlT2Zmc2V0K3RoaXMucG9zaXRpb24sIGxlbmd0aCk7CgkgIERhdGFTdHJlYW0uYXJyYXlUb05hdGl2ZShhcnIsIGUgPT0gbnVsbCA/IHRoaXMuZW5kaWFubmVzcyA6IGUpOwoJICB0aGlzLnBvc2l0aW9uICs9IGxlbmd0aCAqIDQ7CgkgIHJldHVybiBhcnI7Cgl9OwoKCS8qKgoJICBNYXBzIGFuIEludDE2QXJyYXkgaW50byB0aGUgRGF0YVN0cmVhbSBidWZmZXIsIHN3aXp6bGluZyBpdCB0byBuYXRpdmUKCSAgZW5kaWFubmVzcyBpbi1wbGFjZS4gVGhlIGN1cnJlbnQgb2Zmc2V0IGZyb20gdGhlIHN0YXJ0IG9mIHRoZSBidWZmZXIgbmVlZHMgdG8KCSAgYmUgYSBtdWx0aXBsZSBvZiBlbGVtZW50IHNpemUsIGp1c3QgbGlrZSB3aXRoIHR5cGVkIGFycmF5IHZpZXdzLgoKCSAgTmljZSBmb3IgcXVpY2tseSByZWFkaW5nIGluIGRhdGEuIFdhcm5pbmc6IHBvdGVudGlhbGx5IG1vZGlmaWVzIHRoZSBidWZmZXIKCSAgY29udGVudHMuCgoJICBAcGFyYW0ge251bWJlcn0gbGVuZ3RoIE51bWJlciBvZiBlbGVtZW50cyB0byBtYXAuCgkgIEBwYXJhbSB7P2Jvb2xlYW59IGUgRW5kaWFubmVzcyBvZiB0aGUgZGF0YSB0byByZWFkLgoJICBAcmV0dXJuIHtPYmplY3R9IEludDE2QXJyYXkgdG8gdGhlIERhdGFTdHJlYW0gYmFja2luZyBidWZmZXIuCgkgICovCglEYXRhU3RyZWFtLnByb3RvdHlwZS5tYXBJbnQxNkFycmF5ID0gZnVuY3Rpb24obGVuZ3RoLCBlKSB7CgkgIHRoaXMuX3JlYWxsb2MobGVuZ3RoICogMik7CgkgIHZhciBhcnIgPSBuZXcgSW50MTZBcnJheSh0aGlzLl9idWZmZXIsIHRoaXMuYnl0ZU9mZnNldCt0aGlzLnBvc2l0aW9uLCBsZW5ndGgpOwoJICBEYXRhU3RyZWFtLmFycmF5VG9OYXRpdmUoYXJyLCBlID09IG51bGwgPyB0aGlzLmVuZGlhbm5lc3MgOiBlKTsKCSAgdGhpcy5wb3NpdGlvbiArPSBsZW5ndGggKiAyOwoJICByZXR1cm4gYXJyOwoJfTsKCgkvKioKCSAgTWFwcyBhbiBJbnQ4QXJyYXkgaW50byB0aGUgRGF0YVN0cmVhbSBidWZmZXIuCgoJICBOaWNlIGZvciBxdWlja2x5IHJlYWRpbmcgaW4gZGF0YS4KCgkgIEBwYXJhbSB7bnVtYmVyfSBsZW5ndGggTnVtYmVyIG9mIGVsZW1lbnRzIHRvIG1hcC4KCSAgQHBhcmFtIHs/Ym9vbGVhbn0gZSBFbmRpYW5uZXNzIG9mIHRoZSBkYXRhIHRvIHJlYWQuCgkgIEByZXR1cm4ge09iamVjdH0gSW50OEFycmF5IHRvIHRoZSBEYXRhU3RyZWFtIGJhY2tpbmcgYnVmZmVyLgoJICAqLwoJRGF0YVN0cmVhbS5wcm90b3R5cGUubWFwSW50OEFycmF5ID0gZnVuY3Rpb24obGVuZ3RoKSB7CgkgIHRoaXMuX3JlYWxsb2MobGVuZ3RoICogMSk7CgkgIHZhciBhcnIgPSBuZXcgSW50OEFycmF5KHRoaXMuX2J1ZmZlciwgdGhpcy5ieXRlT2Zmc2V0K3RoaXMucG9zaXRpb24sIGxlbmd0aCk7CgkgIHRoaXMucG9zaXRpb24gKz0gbGVuZ3RoICogMTsKCSAgcmV0dXJuIGFycjsKCX07CgoJLyoqCgkgIE1hcHMgYSBVaW50MzJBcnJheSBpbnRvIHRoZSBEYXRhU3RyZWFtIGJ1ZmZlciwgc3dpenpsaW5nIGl0IHRvIG5hdGl2ZQoJICBlbmRpYW5uZXNzIGluLXBsYWNlLiBUaGUgY3VycmVudCBvZmZzZXQgZnJvbSB0aGUgc3RhcnQgb2YgdGhlIGJ1ZmZlciBuZWVkcyB0bwoJICBiZSBhIG11bHRpcGxlIG9mIGVsZW1lbnQgc2l6ZSwganVzdCBsaWtlIHdpdGggdHlwZWQgYXJyYXkgdmlld3MuCgoJICBOaWNlIGZvciBxdWlja2x5IHJlYWRpbmcgaW4gZGF0YS4gV2FybmluZzogcG90ZW50aWFsbHkgbW9kaWZpZXMgdGhlIGJ1ZmZlcgoJICBjb250ZW50cy4KCgkgIEBwYXJhbSB7bnVtYmVyfSBsZW5ndGggTnVtYmVyIG9mIGVsZW1lbnRzIHRvIG1hcC4KCSAgQHBhcmFtIHs/Ym9vbGVhbn0gZSBFbmRpYW5uZXNzIG9mIHRoZSBkYXRhIHRvIHJlYWQuCgkgIEByZXR1cm4ge09iamVjdH0gVWludDMyQXJyYXkgdG8gdGhlIERhdGFTdHJlYW0gYmFja2luZyBidWZmZXIuCgkgICovCglEYXRhU3RyZWFtLnByb3RvdHlwZS5tYXBVaW50MzJBcnJheSA9IGZ1bmN0aW9uKGxlbmd0aCwgZSkgewoJICB0aGlzLl9yZWFsbG9jKGxlbmd0aCAqIDQpOwoJICB2YXIgYXJyID0gbmV3IFVpbnQzMkFycmF5KHRoaXMuX2J1ZmZlciwgdGhpcy5ieXRlT2Zmc2V0K3RoaXMucG9zaXRpb24sIGxlbmd0aCk7CgkgIERhdGFTdHJlYW0uYXJyYXlUb05hdGl2ZShhcnIsIGUgPT0gbnVsbCA/IHRoaXMuZW5kaWFubmVzcyA6IGUpOwoJICB0aGlzLnBvc2l0aW9uICs9IGxlbmd0aCAqIDQ7CgkgIHJldHVybiBhcnI7Cgl9OwoKCS8qKgoJICBNYXBzIGEgVWludDE2QXJyYXkgaW50byB0aGUgRGF0YVN0cmVhbSBidWZmZXIsIHN3aXp6bGluZyBpdCB0byBuYXRpdmUKCSAgZW5kaWFubmVzcyBpbi1wbGFjZS4gVGhlIGN1cnJlbnQgb2Zmc2V0IGZyb20gdGhlIHN0YXJ0IG9mIHRoZSBidWZmZXIgbmVlZHMgdG8KCSAgYmUgYSBtdWx0aXBsZSBvZiBlbGVtZW50IHNpemUsIGp1c3QgbGlrZSB3aXRoIHR5cGVkIGFycmF5IHZpZXdzLgoKCSAgTmljZSBmb3IgcXVpY2tseSByZWFkaW5nIGluIGRhdGEuIFdhcm5pbmc6IHBvdGVudGlhbGx5IG1vZGlmaWVzIHRoZSBidWZmZXIKCSAgY29udGVudHMuCgoJICBAcGFyYW0ge251bWJlcn0gbGVuZ3RoIE51bWJlciBvZiBlbGVtZW50cyB0byBtYXAuCgkgIEBwYXJhbSB7P2Jvb2xlYW59IGUgRW5kaWFubmVzcyBvZiB0aGUgZGF0YSB0byByZWFkLgoJICBAcmV0dXJuIHtPYmplY3R9IFVpbnQxNkFycmF5IHRvIHRoZSBEYXRhU3RyZWFtIGJhY2tpbmcgYnVmZmVyLgoJICAqLwoJRGF0YVN0cmVhbS5wcm90b3R5cGUubWFwVWludDE2QXJyYXkgPSBmdW5jdGlvbihsZW5ndGgsIGUpIHsKCSAgdGhpcy5fcmVhbGxvYyhsZW5ndGggKiAyKTsKCSAgdmFyIGFyciA9IG5ldyBVaW50MTZBcnJheSh0aGlzLl9idWZmZXIsIHRoaXMuYnl0ZU9mZnNldCt0aGlzLnBvc2l0aW9uLCBsZW5ndGgpOwoJICBEYXRhU3RyZWFtLmFycmF5VG9OYXRpdmUoYXJyLCBlID09IG51bGwgPyB0aGlzLmVuZGlhbm5lc3MgOiBlKTsKCSAgdGhpcy5wb3NpdGlvbiArPSBsZW5ndGggKiAyOwoJICByZXR1cm4gYXJyOwoJfTsKCgkvKioKCSAgTWFwcyBhIEZsb2F0NjRBcnJheSBpbnRvIHRoZSBEYXRhU3RyZWFtIGJ1ZmZlciwgc3dpenpsaW5nIGl0IHRvIG5hdGl2ZQoJICBlbmRpYW5uZXNzIGluLXBsYWNlLiBUaGUgY3VycmVudCBvZmZzZXQgZnJvbSB0aGUgc3RhcnQgb2YgdGhlIGJ1ZmZlciBuZWVkcyB0bwoJICBiZSBhIG11bHRpcGxlIG9mIGVsZW1lbnQgc2l6ZSwganVzdCBsaWtlIHdpdGggdHlwZWQgYXJyYXkgdmlld3MuCgoJICBOaWNlIGZvciBxdWlja2x5IHJlYWRpbmcgaW4gZGF0YS4gV2FybmluZzogcG90ZW50aWFsbHkgbW9kaWZpZXMgdGhlIGJ1ZmZlcgoJICBjb250ZW50cy4KCgkgIEBwYXJhbSB7bnVtYmVyfSBsZW5ndGggTnVtYmVyIG9mIGVsZW1lbnRzIHRvIG1hcC4KCSAgQHBhcmFtIHs/Ym9vbGVhbn0gZSBFbmRpYW5uZXNzIG9mIHRoZSBkYXRhIHRvIHJlYWQuCgkgIEByZXR1cm4ge09iamVjdH0gRmxvYXQ2NEFycmF5IHRvIHRoZSBEYXRhU3RyZWFtIGJhY2tpbmcgYnVmZmVyLgoJICAqLwoJRGF0YVN0cmVhbS5wcm90b3R5cGUubWFwRmxvYXQ2NEFycmF5ID0gZnVuY3Rpb24obGVuZ3RoLCBlKSB7CgkgIHRoaXMuX3JlYWxsb2MobGVuZ3RoICogOCk7CgkgIHZhciBhcnIgPSBuZXcgRmxvYXQ2NEFycmF5KHRoaXMuX2J1ZmZlciwgdGhpcy5ieXRlT2Zmc2V0K3RoaXMucG9zaXRpb24sIGxlbmd0aCk7CgkgIERhdGFTdHJlYW0uYXJyYXlUb05hdGl2ZShhcnIsIGUgPT0gbnVsbCA/IHRoaXMuZW5kaWFubmVzcyA6IGUpOwoJICB0aGlzLnBvc2l0aW9uICs9IGxlbmd0aCAqIDg7CgkgIHJldHVybiBhcnI7Cgl9OwoKCS8qKgoJICBNYXBzIGEgRmxvYXQzMkFycmF5IGludG8gdGhlIERhdGFTdHJlYW0gYnVmZmVyLCBzd2l6emxpbmcgaXQgdG8gbmF0aXZlCgkgIGVuZGlhbm5lc3MgaW4tcGxhY2UuIFRoZSBjdXJyZW50IG9mZnNldCBmcm9tIHRoZSBzdGFydCBvZiB0aGUgYnVmZmVyIG5lZWRzIHRvCgkgIGJlIGEgbXVsdGlwbGUgb2YgZWxlbWVudCBzaXplLCBqdXN0IGxpa2Ugd2l0aCB0eXBlZCBhcnJheSB2aWV3cy4KCgkgIE5pY2UgZm9yIHF1aWNrbHkgcmVhZGluZyBpbiBkYXRhLiBXYXJuaW5nOiBwb3RlbnRpYWxseSBtb2RpZmllcyB0aGUgYnVmZmVyCgkgIGNvbnRlbnRzLgoKCSAgQHBhcmFtIHtudW1iZXJ9IGxlbmd0aCBOdW1iZXIgb2YgZWxlbWVudHMgdG8gbWFwLgoJICBAcGFyYW0gez9ib29sZWFufSBlIEVuZGlhbm5lc3Mgb2YgdGhlIGRhdGEgdG8gcmVhZC4KCSAgQHJldHVybiB7T2JqZWN0fSBGbG9hdDMyQXJyYXkgdG8gdGhlIERhdGFTdHJlYW0gYmFja2luZyBidWZmZXIuCgkgICovCglEYXRhU3RyZWFtLnByb3RvdHlwZS5tYXBGbG9hdDMyQXJyYXkgPSBmdW5jdGlvbihsZW5ndGgsIGUpIHsKCSAgdGhpcy5fcmVhbGxvYyhsZW5ndGggKiA0KTsKCSAgdmFyIGFyciA9IG5ldyBGbG9hdDMyQXJyYXkodGhpcy5fYnVmZmVyLCB0aGlzLmJ5dGVPZmZzZXQrdGhpcy5wb3NpdGlvbiwgbGVuZ3RoKTsKCSAgRGF0YVN0cmVhbS5hcnJheVRvTmF0aXZlKGFyciwgZSA9PSBudWxsID8gdGhpcy5lbmRpYW5uZXNzIDogZSk7CgkgIHRoaXMucG9zaXRpb24gKz0gbGVuZ3RoICogNDsKCSAgcmV0dXJuIGFycjsKCX07CgkvLyBmaWxlOnNyYy9idWZmZXIuanMKCS8qKgoJICogTXVsdGlCdWZmZXJTdHJlYW0gaXMgYSBjbGFzcyB0aGF0IGFjdHMgYXMgYSBTaW1wbGVTdHJlYW0gZm9yIHBhcnNpbmcgCgkgKiBJdCBob2xkcyBzZXZlcmFsLCBwb3NzaWJseSBub24tY29udGlndW91cyBBcnJheUJ1ZmZlciBvYmplY3RzLCBlYWNoIHdpdGggYSBmaWxlU3RhcnQgcHJvcGVydHkgCgkgKiBjb250YWluaW5nIHRoZSBvZmZzZXQgZm9yIHRoZSBidWZmZXIgZGF0YSBpbiBhbiBvcmlnaW5hbC92aXJ0dWFsIGZpbGUgCgkgKgoJICogSXQgaW5oZXJpdHMgYWxzbyBmcm9tIERhdGFTdHJlYW0gZm9yIGFsbCByZWFkL3dyaXRlL2FsbG9jIG9wZXJhdGlvbnMKCSAqLwoKCS8qKgoJICogQ29uc3RydWN0b3IKCSAqLwoJdmFyIE11bHRpQnVmZmVyU3RyZWFtID0gZnVuY3Rpb24oYnVmZmVyKSB7CgkJLyogTGlzdCBvZiBBcnJheUJ1ZmZlcnMsIHdpdGggYSBmaWxlU3RhcnQgcHJvcGVydHksIHNvcnRlZCBpbiBmaWxlU3RhcnQgb3JkZXIgYW5kIG5vbiBvdmVybGFwcGluZyAqLwoJCXRoaXMuYnVmZmVycyA9IFtdOwkKCQl0aGlzLmJ1ZmZlckluZGV4ID0gLTE7CgkJaWYgKGJ1ZmZlcikgewoJCQl0aGlzLmluc2VydEJ1ZmZlcihidWZmZXIpOwoJCQl0aGlzLmJ1ZmZlckluZGV4ID0gMDsKCQl9Cgl9OwoJTXVsdGlCdWZmZXJTdHJlYW0ucHJvdG90eXBlID0gbmV3IERhdGFTdHJlYW0obmV3IEFycmF5QnVmZmVyKCksIDAsIERhdGFTdHJlYW0uQklHX0VORElBTik7CgoJLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoJICBNZXRob2RzIGZvciB0aGUgbWFuYWduZW1lbnQgb2YgdGhlIGJ1ZmZlcnMgKGluc2VydGlvbiwgcmVtb3ZhbCwgY29uY2F0ZW5hdGlvbiwgLi4uKQoJICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKCU11bHRpQnVmZmVyU3RyZWFtLnByb3RvdHlwZS5pbml0aWFsaXplZCA9IGZ1bmN0aW9uKCkgewoJCXZhciBmaXJzdEJ1ZmZlcjsKCQlpZiAodGhpcy5idWZmZXJJbmRleCA+IC0xKSB7CgkJCXJldHVybiB0cnVlOwoJCX0gZWxzZSBpZiAodGhpcy5idWZmZXJzLmxlbmd0aCA+IDApIHsKCQkJZmlyc3RCdWZmZXIgPSB0aGlzLmJ1ZmZlcnNbMF07CgkJCWlmIChmaXJzdEJ1ZmZlci5maWxlU3RhcnQgPT09IDApIHsKCQkJCXRoaXMuYnVmZmVyID0gZmlyc3RCdWZmZXI7CgkJCQl0aGlzLmJ1ZmZlckluZGV4ID0gMDsKCQkJCUxvZy5kZWJ1ZygiTXVsdGlCdWZmZXJTdHJlYW0iLCAiU3RyZWFtIHJlYWR5IGZvciBwYXJzaW5nIik7CgkJCQlyZXR1cm4gdHJ1ZTsKCQkJfSBlbHNlIHsKCQkJCUxvZy53YXJuKCJNdWx0aUJ1ZmZlclN0cmVhbSIsICJUaGUgZmlyc3QgYnVmZmVyIHNob3VsZCBoYXZlIGEgZmlsZVN0YXJ0IG9mIDAiKTsKCQkJCXRoaXMubG9nQnVmZmVyTGV2ZWwoKTsKCQkJCXJldHVybiBmYWxzZTsKCQkJfQoJCX0gZWxzZSB7CgkJCUxvZy53YXJuKCJNdWx0aUJ1ZmZlclN0cmVhbSIsICJObyBidWZmZXIgdG8gc3RhcnQgcGFyc2luZyBmcm9tIik7CgkJCXRoaXMubG9nQnVmZmVyTGV2ZWwoKTsKCQkJcmV0dXJuIGZhbHNlOwoJCX0JCQkKCX07CgoJLyoqCgkgKiBoZWxwZXIgZnVuY3Rpb25zIHRvIGNvbmNhdGVuYXRlIHR3byBBcnJheUJ1ZmZlciBvYmplY3RzCgkgKiBAcGFyYW0gIHtBcnJheUJ1ZmZlcn0gYnVmZmVyMSAKCSAqIEBwYXJhbSAge0FycmF5QnVmZmVyfSBidWZmZXIyIAoJICogQHJldHVybiB7QXJyYXlCdWZmZXJ9IHRoZSBjb25jYXRlbmF0aW9uIG9mIGJ1ZmZlcjEgYW5kIGJ1ZmZlcjIgaW4gdGhhdCBvcmRlcgoJICovCglBcnJheUJ1ZmZlci5jb25jYXQgPSBmdW5jdGlvbihidWZmZXIxLCBidWZmZXIyKSB7CgkgIExvZy5kZWJ1ZygiQXJyYXlCdWZmZXIiLCAiVHJ5aW5nIHRvIGNyZWF0ZSBhIG5ldyBidWZmZXIgb2Ygc2l6ZTogIisoYnVmZmVyMS5ieXRlTGVuZ3RoICsgYnVmZmVyMi5ieXRlTGVuZ3RoKSk7CgkgIHZhciB0bXAgPSBuZXcgVWludDhBcnJheShidWZmZXIxLmJ5dGVMZW5ndGggKyBidWZmZXIyLmJ5dGVMZW5ndGgpOwoJICB0bXAuc2V0KG5ldyBVaW50OEFycmF5KGJ1ZmZlcjEpLCAwKTsKCSAgdG1wLnNldChuZXcgVWludDhBcnJheShidWZmZXIyKSwgYnVmZmVyMS5ieXRlTGVuZ3RoKTsKCSAgcmV0dXJuIHRtcC5idWZmZXI7Cgl9OwoKCS8qKgoJICogUmVkdWNlcyB0aGUgc2l6ZSBvZiBhIGdpdmVuIGJ1ZmZlciwgYnV0IHRha2luZyB0aGUgcGFydCBiZXR3ZWVuIG9mZnNldCBhbmQgb2Zmc2V0K25ld2xlbmd0aAoJICogQHBhcmFtICB7QXJyYXlCdWZmZXJ9IGJ1ZmZlciAgICAKCSAqIEBwYXJhbSAge051bWJlcn0gICAgICBvZmZzZXQgICAgdGhlIHN0YXJ0IG9mIG5ldyBidWZmZXIKCSAqIEBwYXJhbSAge051bWJlcn0gICAgICBuZXdMZW5ndGggdGhlIGxlbmd0aCBvZiB0aGUgbmV3IGJ1ZmZlcgoJICogQHJldHVybiB7QXJyYXlCdWZmZXJ9ICAgICAgICAgICB0aGUgbmV3IGJ1ZmZlcgoJICovCglNdWx0aUJ1ZmZlclN0cmVhbS5wcm90b3R5cGUucmVkdWNlQnVmZmVyID0gZnVuY3Rpb24oYnVmZmVyLCBvZmZzZXQsIG5ld0xlbmd0aCkgewoJCXZhciBzbWFsbEI7CgkJc21hbGxCID0gbmV3IFVpbnQ4QXJyYXkobmV3TGVuZ3RoKTsKCQlzbWFsbEIuc2V0KG5ldyBVaW50OEFycmF5KGJ1ZmZlciwgb2Zmc2V0LCBuZXdMZW5ndGgpKTsKCQlzbWFsbEIuYnVmZmVyLmZpbGVTdGFydCA9IGJ1ZmZlci5maWxlU3RhcnQrb2Zmc2V0OwoJCXNtYWxsQi5idWZmZXIudXNlZEJ5dGVzID0gMDsKCQlyZXR1cm4gc21hbGxCLmJ1ZmZlcjsJCgl9OwoKCS8qKgoJICogSW5zZXJ0cyB0aGUgbmV3IGJ1ZmZlciBpbiB0aGUgc29ydGVkIGxpc3Qgb2YgYnVmZmVycywKCSAqICBtYWtpbmcgc3VyZSwgaXQgaXMgbm90IG92ZXJsYXBwaW5nIHdpdGggZXhpc3Rpbmcgb25lcyAocG9zc2libHkgcmVkdWNpbmcgaXRzIHNpemUpLgoJICogIGlmIHRoZSBuZXcgYnVmZmVyIG92ZXJyaWRlcy9yZXBsYWNlcyB0aGUgMC10aCBidWZmZXIgKGZvciBpbnN0YW5jZSBiZWNhdXNlIGl0IGlzIGJpZ2dlciksIAoJICogIHVwZGF0ZXMgdGhlIERhdGFTdHJlYW0gYnVmZmVyIGZvciBwYXJzaW5nIAoJKi8KCU11bHRpQnVmZmVyU3RyZWFtLnByb3RvdHlwZS5pbnNlcnRCdWZmZXIgPSBmdW5jdGlvbihhYikgewkKCQl2YXIgdG9fYWRkID0gdHJ1ZTsKCQkvKiBUT0RPOiBpbXByb3ZlIGluc2VydGlvbiBpZiBtYW55IGJ1ZmZlcnMgKi8KCQlmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuYnVmZmVycy5sZW5ndGg7IGkrKykgewoJCQl2YXIgYiA9IHRoaXMuYnVmZmVyc1tpXTsKCQkJaWYgKGFiLmZpbGVTdGFydCA8PSBiLmZpbGVTdGFydCkgewoJCQkJLyogdGhlIGluc2VydGlvbiBwb3NpdGlvbiBpcyBmb3VuZCAqLwoJCQkJaWYgKGFiLmZpbGVTdGFydCA9PT0gYi5maWxlU3RhcnQpIHsKCQkJCQkvKiBUaGUgbmV3IGJ1ZmZlciBvdmVybGFwcyB3aXRoIGFuIGV4aXN0aW5nIGJ1ZmZlciAqLwoJCQkJCWlmIChhYi5ieXRlTGVuZ3RoID4gIGIuYnl0ZUxlbmd0aCkgewoJCQkJCQkvKiB0aGUgbmV3IGJ1ZmZlciBpcyBiaWdnZXIgdGhhbiB0aGUgZXhpc3Rpbmcgb25lCgkJCQkJCSAgIHJlbW92ZSB0aGUgZXhpc3RpbmcgYnVmZmVyIGFuZCB0cnkgYWdhaW4gdG8gaW5zZXJ0IAoJCQkJCQkgICB0aGUgbmV3IGJ1ZmZlciB0byBjaGVjayBvdmVybGFwIHdpdGggdGhlIG5leHQgb25lcyAqLwoJCQkJCQl0aGlzLmJ1ZmZlcnMuc3BsaWNlKGksIDEpOwoJCQkJCQlpLS07IAoJCQkJCQljb250aW51ZTsKCQkJCQl9IGVsc2UgewoJCQkJCQkvKiB0aGUgbmV3IGJ1ZmZlciBpcyBzbWFsbGVyIHRoYW4gdGhlIGV4aXN0aW5nIG9uZSwganVzdCBkcm9wIGl0ICovCgkJCQkJCUxvZy53YXJuKCJNdWx0aUJ1ZmZlclN0cmVhbSIsICJCdWZmZXIgKGZpbGVTdGFydDogIithYi5maWxlU3RhcnQrIiAtIExlbmd0aDogIithYi5ieXRlTGVuZ3RoKyIpIGFscmVhZHkgYXBwZW5kZWQsIGlnbm9yaW5nIik7CgkJCQkJfQoJCQkJfSBlbHNlIHsKCQkJCQkvKiBUaGUgYmVnaW5uaW5nIG9mIHRoZSBuZXcgYnVmZmVyIGlzIG5vdCBvdmVybGFwcGluZyB3aXRoIGFuIGV4aXN0aW5nIGJ1ZmZlcgoJCQkJCSAgIGxldCdzIGNoZWNrIHRoZSBlbmQgb2YgaXQgKi8KCQkJCQlpZiAoYWIuZmlsZVN0YXJ0ICsgYWIuYnl0ZUxlbmd0aCA8PSBiLmZpbGVTdGFydCkgOyBlbHNlIHsKCQkJCQkJLyogVGhlcmUgaXMgc29tZSBvdmVybGFwLCBjdXQgdGhlIG5ldyBidWZmZXIgc2hvcnQsIGFuZCBhZGQgaXQqLwoJCQkJCQlhYiA9IHRoaXMucmVkdWNlQnVmZmVyKGFiLCAwLCBiLmZpbGVTdGFydCAtIGFiLmZpbGVTdGFydCk7CgkJCQkJfQoJCQkJCUxvZy5kZWJ1ZygiTXVsdGlCdWZmZXJTdHJlYW0iLCAiQXBwZW5kaW5nIG5ldyBidWZmZXIgKGZpbGVTdGFydDogIithYi5maWxlU3RhcnQrIiAtIExlbmd0aDogIithYi5ieXRlTGVuZ3RoKyIpIik7CgkJCQkJdGhpcy5idWZmZXJzLnNwbGljZShpLCAwLCBhYik7CgkJCQkJLyogaWYgdGhpcyBuZXcgYnVmZmVyIGlzIGluc2VydGVkIGluIHRoZSBmaXJzdCBwbGFjZSBpbiB0aGUgbGlzdCBvZiB0aGUgYnVmZmVyLCAKCQkJCQkgICBhbmQgdGhlIERhdGFTdHJlYW0gaXMgaW5pdGlhbGl6ZWQsIG1ha2UgaXQgdGhlIGJ1ZmZlciB1c2VkIGZvciBwYXJzaW5nICovCgkJCQkJaWYgKGkgPT09IDApIHsKCQkJCQkJdGhpcy5idWZmZXIgPSBhYjsKCQkJCQl9CgkJCQl9CgkJCQl0b19hZGQgPSBmYWxzZTsKCQkJCWJyZWFrOwoJCQl9IGVsc2UgaWYgKGFiLmZpbGVTdGFydCA8IGIuZmlsZVN0YXJ0ICsgYi5ieXRlTGVuZ3RoKSB7CgkJCQkvKiB0aGUgbmV3IGJ1ZmZlciBvdmVybGFwcyBpdHMgYmVnaW5uaW5nIHdpdGggdGhlIGVuZCBvZiB0aGUgY3VycmVudCBidWZmZXIgKi8KCQkJCXZhciBvZmZzZXQgPSBiLmZpbGVTdGFydCArIGIuYnl0ZUxlbmd0aCAtIGFiLmZpbGVTdGFydDsKCQkJCXZhciBuZXdMZW5ndGggPSBhYi5ieXRlTGVuZ3RoIC0gb2Zmc2V0OwoJCQkJaWYgKG5ld0xlbmd0aCA+IDApIHsKCQkJCQkvKiB0aGUgbmV3IGJ1ZmZlciBpcyBiaWdnZXIgdGhhbiB0aGUgY3VycmVudCBvdmVybGFwLCBkcm9wIHRoZSBvdmVybGFwcGluZyBwYXJ0IGFuZCB0cnkgYWdhaW4gaW5zZXJ0aW5nIHRoZSByZW1haW5pbmcgYnVmZmVyICovCgkJCQkJYWIgPSB0aGlzLnJlZHVjZUJ1ZmZlcihhYiwgb2Zmc2V0LCBuZXdMZW5ndGgpOwoJCQkJfSBlbHNlIHsKCQkJCQkvKiB0aGUgY29udGVudCBvZiB0aGUgbmV3IGJ1ZmZlciBpcyBlbnRpcmVseSBjb250YWluZWQgaW4gdGhlIGV4aXN0aW5nIGJ1ZmZlciwgZHJvcCBpdCBlbnRpcmVseSAqLwoJCQkJCXRvX2FkZCA9IGZhbHNlOwoJCQkJCWJyZWFrOwoJCQkJfQoJCQl9CgkJfQoJCS8qIGlmIHRoZSBidWZmZXIgaGFzIG5vdCBiZWVuIGFkZGVkLCB3ZSBjYW4gYWRkIGl0IGF0IHRoZSBlbmQgKi8KCQlpZiAodG9fYWRkKSB7CgkJCUxvZy5kZWJ1ZygiTXVsdGlCdWZmZXJTdHJlYW0iLCAiQXBwZW5kaW5nIG5ldyBidWZmZXIgKGZpbGVTdGFydDogIithYi5maWxlU3RhcnQrIiAtIExlbmd0aDogIithYi5ieXRlTGVuZ3RoKyIpIik7CgkJCXRoaXMuYnVmZmVycy5wdXNoKGFiKTsKCQkJLyogaWYgdGhpcyBuZXcgYnVmZmVyIGlzIGluc2VydGVkIGluIHRoZSBmaXJzdCBwbGFjZSBpbiB0aGUgbGlzdCBvZiB0aGUgYnVmZmVyLCAKCQkJICAgYW5kIHRoZSBEYXRhU3RyZWFtIGlzIGluaXRpYWxpemVkLCBtYWtlIGl0IHRoZSBidWZmZXIgdXNlZCBmb3IgcGFyc2luZyAqLwoJCQlpZiAoaSA9PT0gMCkgewoJCQkJdGhpcy5idWZmZXIgPSBhYjsKCQkJfQoJCX0KCX07CgoJLyoqCgkgKiBEaXNwbGF5cyB0aGUgc3RhdHVzIG9mIHRoZSBidWZmZXJzIChudW1iZXIgYW5kIHVzZWQgYnl0ZXMpCgkgKiBAcGFyYW0gIHtPYmplY3R9IGluZm8gY2FsbGJhY2sgbWV0aG9kIGZvciBkaXNwbGF5CgkgKi8KCU11bHRpQnVmZmVyU3RyZWFtLnByb3RvdHlwZS5sb2dCdWZmZXJMZXZlbCA9IGZ1bmN0aW9uKGluZm8pIHsKCQl2YXIgaTsKCQl2YXIgYnVmZmVyOwoJCXZhciB1c2VkLCB0b3RhbDsKCQl2YXIgcmFuZ2VzID0gW107CgkJdmFyIHJhbmdlOwoJCXZhciBidWZmZXJlZFN0cmluZyA9ICIiOwoJCXVzZWQgPSAwOwoJCXRvdGFsID0gMDsKCQlmb3IgKGkgPSAwOyBpIDwgdGhpcy5idWZmZXJzLmxlbmd0aDsgaSsrKSB7CgkJCWJ1ZmZlciA9IHRoaXMuYnVmZmVyc1tpXTsKCQkJaWYgKGkgPT09IDApIHsKCQkJCXJhbmdlID0ge307CgkJCQlyYW5nZXMucHVzaChyYW5nZSk7CgkJCQlyYW5nZS5zdGFydCA9IGJ1ZmZlci5maWxlU3RhcnQ7CgkJCQlyYW5nZS5lbmQgPSBidWZmZXIuZmlsZVN0YXJ0K2J1ZmZlci5ieXRlTGVuZ3RoOwoJCQkJYnVmZmVyZWRTdHJpbmcgKz0gIlsiK3JhbmdlLnN0YXJ0KyItIjsKCQkJfSBlbHNlIGlmIChyYW5nZS5lbmQgPT09IGJ1ZmZlci5maWxlU3RhcnQpIHsKCQkJCXJhbmdlLmVuZCA9IGJ1ZmZlci5maWxlU3RhcnQrYnVmZmVyLmJ5dGVMZW5ndGg7CgkJCX0gZWxzZSB7CgkJCQlyYW5nZSA9IHt9OwoJCQkJcmFuZ2Uuc3RhcnQgPSBidWZmZXIuZmlsZVN0YXJ0OwoJCQkJYnVmZmVyZWRTdHJpbmcgKz0gKHJhbmdlc1tyYW5nZXMubGVuZ3RoLTFdLmVuZC0xKSsiXSwgWyIrcmFuZ2Uuc3RhcnQrIi0iOwoJCQkJcmFuZ2UuZW5kID0gYnVmZmVyLmZpbGVTdGFydCtidWZmZXIuYnl0ZUxlbmd0aDsKCQkJCXJhbmdlcy5wdXNoKHJhbmdlKTsKCQkJfQoJCQl1c2VkICs9IGJ1ZmZlci51c2VkQnl0ZXM7CgkJCXRvdGFsICs9IGJ1ZmZlci5ieXRlTGVuZ3RoOwoJCX0KCQlpZiAocmFuZ2VzLmxlbmd0aCA+IDApIHsKCQkJYnVmZmVyZWRTdHJpbmcgKz0gKHJhbmdlLmVuZC0xKSsiXSI7CgkJfQoJCXZhciBsb2cgPSAoaW5mbyA/IExvZy5pbmZvIDogTG9nLmRlYnVnKTsKCQlpZiAodGhpcy5idWZmZXJzLmxlbmd0aCA9PT0gMCkgewoJCQlsb2coIk11bHRpQnVmZmVyU3RyZWFtIiwgIk5vIG1vcmUgYnVmZmVyIGluIG1lbW9yeSIpOwoJCX0gZWxzZSB7CgkJCWxvZygiTXVsdGlCdWZmZXJTdHJlYW0iLCAiIit0aGlzLmJ1ZmZlcnMubGVuZ3RoKyIgc3RvcmVkIGJ1ZmZlcihzKSAoIit1c2VkKyIvIit0b3RhbCsiIGJ5dGVzKSwgY29udGludW91cyByYW5nZXM6ICIrYnVmZmVyZWRTdHJpbmcpOwoJCX0KCX07CgoJTXVsdGlCdWZmZXJTdHJlYW0ucHJvdG90eXBlLmNsZWFuQnVmZmVycyA9IGZ1bmN0aW9uICgpIHsKCQl2YXIgaTsKCQl2YXIgYnVmZmVyOwoJCWZvciAoaSA9IDA7IGkgPCB0aGlzLmJ1ZmZlcnMubGVuZ3RoOyBpKyspIHsKCQkJYnVmZmVyID0gdGhpcy5idWZmZXJzW2ldOwoJCQlpZiAoYnVmZmVyLnVzZWRCeXRlcyA9PT0gYnVmZmVyLmJ5dGVMZW5ndGgpIHsKCQkJCUxvZy5kZWJ1ZygiTXVsdGlCdWZmZXJTdHJlYW0iLCAiUmVtb3ZpbmcgYnVmZmVyICMiK2kpOwoJCQkJdGhpcy5idWZmZXJzLnNwbGljZShpLCAxKTsKCQkJCWktLTsKCQkJfQoJCX0KCX07CgoJTXVsdGlCdWZmZXJTdHJlYW0ucHJvdG90eXBlLm1lcmdlTmV4dEJ1ZmZlciA9IGZ1bmN0aW9uKCkgewoJCXZhciBuZXh0X2J1ZmZlcjsKCQlpZiAodGhpcy5idWZmZXJJbmRleCsxIDwgdGhpcy5idWZmZXJzLmxlbmd0aCkgewoJCQluZXh0X2J1ZmZlciA9IHRoaXMuYnVmZmVyc1t0aGlzLmJ1ZmZlckluZGV4KzFdOwoJCQlpZiAobmV4dF9idWZmZXIuZmlsZVN0YXJ0ID09PSB0aGlzLmJ1ZmZlci5maWxlU3RhcnQgKyB0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKSB7CgkJCQl2YXIgb2xkTGVuZ3RoID0gdGhpcy5idWZmZXIuYnl0ZUxlbmd0aDsKCQkJCXZhciBvbGRVc2VkQnl0ZXMgPSB0aGlzLmJ1ZmZlci51c2VkQnl0ZXM7CgkJCQl2YXIgb2xkRmlsZVN0YXJ0ID0gdGhpcy5idWZmZXIuZmlsZVN0YXJ0OwoJCQkJdGhpcy5idWZmZXJzW3RoaXMuYnVmZmVySW5kZXhdID0gQXJyYXlCdWZmZXIuY29uY2F0KHRoaXMuYnVmZmVyLCBuZXh0X2J1ZmZlcik7CgkJCQl0aGlzLmJ1ZmZlciA9IHRoaXMuYnVmZmVyc1t0aGlzLmJ1ZmZlckluZGV4XTsKCQkJCXRoaXMuYnVmZmVycy5zcGxpY2UodGhpcy5idWZmZXJJbmRleCsxLCAxKTsKCQkJCXRoaXMuYnVmZmVyLnVzZWRCeXRlcyA9IG9sZFVzZWRCeXRlczsgLyogVE9ETzogc2hvdWxkIGl0IGJlICs9ID8gKi8KCQkJCXRoaXMuYnVmZmVyLmZpbGVTdGFydCA9IG9sZEZpbGVTdGFydDsKCQkJCUxvZy5kZWJ1ZygiSVNPRmlsZSIsICJDb25jYXRlbmF0aW5nIGJ1ZmZlciBmb3IgYm94IHBhcnNpbmcgKGxlbmd0aDogIitvbGRMZW5ndGgrIi0+Iit0aGlzLmJ1ZmZlci5ieXRlTGVuZ3RoKyIpIik7CgkJCQlyZXR1cm4gdHJ1ZTsKCQkJfSBlbHNlIHsKCQkJCXJldHVybiBmYWxzZTsKCQkJfQoJCX0gZWxzZSB7CgkJCXJldHVybiBmYWxzZTsKCQl9Cgl9OwoKCgkvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoJICBTZWVrLXJlbGF0ZWQgZnVuY3Rpb25zCgkgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgkvKioKCSAqIEZpbmRzIHRoZSBidWZmZXIgdGhhdCBob2xkcyB0aGUgZ2l2ZW4gZmlsZSBwb3NpdGlvbgoJICogQHBhcmFtICB7Qm9vbGVhbn0gZnJvbVN0YXJ0ICAgIGluZGljYXRlcyBpZiB0aGUgc2VhcmNoIHNob3VsZCBzdGFydCBmcm9tIHRoZSBjdXJyZW50IGJ1ZmZlciAoZmFsc2UpIAoJICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yIGZyb20gdGhlIGZpcnN0IGJ1ZmZlciAodHJ1ZSkKCSAqIEBwYXJhbSAge051bWJlcn0gIGZpbGVQb3NpdGlvbiBwb3NpdGlvbiBpbiB0aGUgZmlsZSB0byBzZWVrIHRvCgkgKiBAcGFyYW0gIHtCb29sZWFufSBtYXJrQXNVc2VkICAgaW5kaWNhdGVzIGlmIHRoZSBieXRlcyBpbiBiZXR3ZWVuIHRoZSBjdXJyZW50IHBvc2l0aW9uIGFuZCB0aGUgc2VlayBwb3NpdGlvbiAKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaG91bGQgYmUgbWFya2VkIGFzIHVzZWQgZm9yIGdhcmJhZ2UgY29sbGVjdGlvbgoJICogQHJldHVybiB7TnVtYmVyfSAgICAgICAgICAgICAgIHRoZSBpbmRleCBvZiB0aGUgYnVmZmVyIGhvbGRpbmcgdGhlIHNlZWtlZCBmaWxlIHBvc2l0aW9uLCAtMSBpZiBub3QgZm91bmQuCgkgKi8KCU11bHRpQnVmZmVyU3RyZWFtLnByb3RvdHlwZS5maW5kUG9zaXRpb24gPSBmdW5jdGlvbihmcm9tU3RhcnQsIGZpbGVQb3NpdGlvbiwgbWFya0FzVXNlZCkgewoJCXZhciBpOwoJCXZhciBhYnVmZmVyID0gbnVsbDsKCQl2YXIgaW5kZXggPSAtMTsKCgkJLyogZmluZCB0aGUgYnVmZmVyIHdpdGggdGhlIGxhcmdlc3QgcG9zaXRpb24gc21hbGxlciB0aGFuIHRoZSBnaXZlbiBwb3NpdGlvbiAqLwoJCWlmIChmcm9tU3RhcnQgPT09IHRydWUpIHsKCQkgICAvKiB0aGUgcmVwb3NpdGlvbiBjYW4gYmUgaW4gdGhlIHBhc3QsIHdlIG5lZWQgdG8gY2hlY2sgZnJvbSB0aGUgYmVnaW5uaW5nIG9mIHRoZSBsaXN0IG9mIGJ1ZmZlcnMgKi8KCQkJaSA9IDA7CgkJfSBlbHNlIHsKCQkJaSA9IHRoaXMuYnVmZmVySW5kZXg7CgkJfQoKCQl3aGlsZSAoaSA8IHRoaXMuYnVmZmVycy5sZW5ndGgpIHsKCQkJYWJ1ZmZlciA9IHRoaXMuYnVmZmVyc1tpXTsKCQkJaWYgKGFidWZmZXIuZmlsZVN0YXJ0IDw9IGZpbGVQb3NpdGlvbikgewoJCQkJaW5kZXggPSBpOwoJCQkJaWYgKG1hcmtBc1VzZWQpIHsKCQkJCQlpZiAoYWJ1ZmZlci5maWxlU3RhcnQgKyBhYnVmZmVyLmJ5dGVMZW5ndGggPD0gZmlsZVBvc2l0aW9uKSB7CgkJCQkJCWFidWZmZXIudXNlZEJ5dGVzID0gYWJ1ZmZlci5ieXRlTGVuZ3RoOwkKCQkJCQl9IGVsc2UgewoJCQkJCQlhYnVmZmVyLnVzZWRCeXRlcyA9IGZpbGVQb3NpdGlvbiAtIGFidWZmZXIuZmlsZVN0YXJ0OwoJCQkJCX0JCQoJCQkJCXRoaXMubG9nQnVmZmVyTGV2ZWwoKTsJCgkJCQl9CgkJCX0gZWxzZSB7CgkJCQlicmVhazsKCQkJfQoJCQlpKys7CgkJfQoKCQlpZiAoaW5kZXggIT09IC0xKSB7CgkJCWFidWZmZXIgPSB0aGlzLmJ1ZmZlcnNbaW5kZXhdOwoJCQlpZiAoYWJ1ZmZlci5maWxlU3RhcnQgKyBhYnVmZmVyLmJ5dGVMZW5ndGggPj0gZmlsZVBvc2l0aW9uKSB7CQkJCgkJCQlMb2cuZGVidWcoIk11bHRpQnVmZmVyU3RyZWFtIiwgIkZvdW5kIHBvc2l0aW9uIGluIGV4aXN0aW5nIGJ1ZmZlciAjIitpbmRleCk7CgkJCQlyZXR1cm4gaW5kZXg7CgkJCX0gZWxzZSB7CgkJCQlyZXR1cm4gLTE7CgkJCX0KCQl9IGVsc2UgewoJCQlyZXR1cm4gLTE7CgkJfQoJfTsKCgkvKioKCSAqIEZpbmRzIHRoZSBsYXJnZXN0IGZpbGUgcG9zaXRpb24gY29udGFpbmVkIGluIGEgYnVmZmVyIG9yIGluIHRoZSBuZXh0IGJ1ZmZlcnMgaWYgdGhleSBhcmUgY29udGlndW91cyAobm8gZ2FwKQoJICogc3RhcnRpbmcgZnJvbSB0aGUgZ2l2ZW4gYnVmZmVyIGluZGV4IG9yIGZyb20gdGhlIGN1cnJlbnQgYnVmZmVyIGlmIHRoZSBpbmRleCBpcyBub3QgZ2l2ZW4KCSAqCgkgKiBAcGFyYW0gIHtOdW1iZXJ9IGlucHV0aW5kZXggSW5kZXggb2YgdGhlIGJ1ZmZlciB0byBzdGFydCBmcm9tCgkgKiBAcmV0dXJuIHtOdW1iZXJ9ICAgICAgICAgICAgVGhlIGxhcmdlc3QgZmlsZSBwb3NpdGlvbiBmb3VuZCBpbiB0aGUgYnVmZmVycwoJICovCglNdWx0aUJ1ZmZlclN0cmVhbS5wcm90b3R5cGUuZmluZEVuZENvbnRpZ3VvdXNCdWYgPSBmdW5jdGlvbihpbnB1dGluZGV4KSB7CgkJdmFyIGk7CgkJdmFyIGN1cnJlbnRCdWY7CgkJdmFyIG5leHRCdWY7CgkJdmFyIGluZGV4ID0gKGlucHV0aW5kZXggIT09IHVuZGVmaW5lZCA/IGlucHV0aW5kZXggOiB0aGlzLmJ1ZmZlckluZGV4KTsKCQljdXJyZW50QnVmID0gdGhpcy5idWZmZXJzW2luZGV4XTsKCQkvKiBmaW5kIHRoZSBlbmQgb2YgdGhlIGNvbnRpZ3VvdXMgcmFuZ2Ugb2YgZGF0YSAqLwoJCWlmICh0aGlzLmJ1ZmZlcnMubGVuZ3RoID4gaW5kZXgrMSkgewoJCQlmb3IgKGkgPSBpbmRleCsxOyBpIDwgdGhpcy5idWZmZXJzLmxlbmd0aDsgaSsrKSB7CgkJCQluZXh0QnVmID0gdGhpcy5idWZmZXJzW2ldOwoJCQkJaWYgKG5leHRCdWYuZmlsZVN0YXJ0ID09PSBjdXJyZW50QnVmLmZpbGVTdGFydCArIGN1cnJlbnRCdWYuYnl0ZUxlbmd0aCkgewoJCQkJCWN1cnJlbnRCdWYgPSBuZXh0QnVmOwoJCQkJfSBlbHNlIHsKCQkJCQlicmVhazsKCQkJCX0KCQkJfQoJCX0KCQkvKiByZXR1cm4gdGhlIHBvc2l0aW9uIG9mIGxhc3QgYnl0ZSBpbiB0aGUgZmlsZSB0aGF0IHdlIGhhdmUgKi8KCQlyZXR1cm4gY3VycmVudEJ1Zi5maWxlU3RhcnQgKyBjdXJyZW50QnVmLmJ5dGVMZW5ndGg7Cgl9OwoKCS8qKgoJICogUmV0dXJucyB0aGUgbGFyZ2VzdCBmaWxlIHBvc2l0aW9uIGNvbnRhaW5lZCBpbiB0aGUgYnVmZmVycywgbGFyZ2VyIHRoYW4gdGhlIGdpdmVuIHBvc2l0aW9uCgkgKiBAcGFyYW0gIHtOdW1iZXJ9IHBvcyB0aGUgZmlsZSBwb3NpdGlvbiB0byBzdGFydCBmcm9tCgkgKiBAcmV0dXJuIHtOdW1iZXJ9ICAgICB0aGUgbGFyZ2VzdCBwb3NpdGlvbiBpbiB0aGUgY3VycmVudCBidWZmZXIgb3IgaW4gdGhlIGJ1ZmZlciBhbmQgdGhlIG5leHQgY29udGlndW91cyAKCSAqICAgICAgICAgICAgICAgICAgICAgIGJ1ZmZlciB0aGF0IGhvbGRzIHRoZSBnaXZlbiBwb3NpdGlvbgoJICovCglNdWx0aUJ1ZmZlclN0cmVhbS5wcm90b3R5cGUuZ2V0RW5kRmlsZVBvc2l0aW9uQWZ0ZXIgPSBmdW5jdGlvbihwb3MpIHsKCQl2YXIgaW5kZXggPSB0aGlzLmZpbmRQb3NpdGlvbih0cnVlLCBwb3MsIGZhbHNlKTsKCQlpZiAoaW5kZXggIT09IC0xKSB7CgkJCXJldHVybiB0aGlzLmZpbmRFbmRDb250aWd1b3VzQnVmKGluZGV4KTsKCQl9IGVsc2UgewoJCQlyZXR1cm4gcG9zOwoJCX0KCX07CgoJLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKCSAgR2FyYmFnZSBjb2xsZWN0aW9uIHJlbGF0ZWQgZnVuY3Rpb25zCgkgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgkvKioKCSAqIE1hcmtzIGEgZ2l2ZW4gbnVtYmVyIG9mIGJ5dGVzIGFzIHVzZWQgaW4gdGhlIGN1cnJlbnQgYnVmZmVyIGZvciBnYXJiYWdlIGNvbGxlY3Rpb24KCSAqIEBwYXJhbSB7TnVtYmVyfSBuYkJ5dGVzIAoJICovCglNdWx0aUJ1ZmZlclN0cmVhbS5wcm90b3R5cGUuYWRkVXNlZEJ5dGVzID0gZnVuY3Rpb24obmJCeXRlcykgewoJCXRoaXMuYnVmZmVyLnVzZWRCeXRlcyArPSBuYkJ5dGVzOwoJCXRoaXMubG9nQnVmZmVyTGV2ZWwoKTsKCX07CgoJLyoqCgkgKiBNYXJrcyB0aGUgZW50aXJlIGN1cnJlbnQgYnVmZmVyIGFzIHVzZWQsIHJlYWR5IGZvciBnYXJiYWdlIGNvbGxlY3Rpb24KCSAqLwoJTXVsdGlCdWZmZXJTdHJlYW0ucHJvdG90eXBlLnNldEFsbFVzZWRCeXRlcyA9IGZ1bmN0aW9uKCkgewoJCXRoaXMuYnVmZmVyLnVzZWRCeXRlcyA9IHRoaXMuYnVmZmVyLmJ5dGVMZW5ndGg7CgkJdGhpcy5sb2dCdWZmZXJMZXZlbCgpOwoJfTsKCgkvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoJICBDb21tb24gQVBJIGJldHdlZW4gTXVsdGlCdWZmZXJTdHJlYW0gYW5kIFNpbXBsZVN0cmVhbQoJICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgoJLyoqCgkgKiBUcmllcyB0byBzZWVrIHRvIGEgZ2l2ZW4gZmlsZSBwb3NpdGlvbgoJICogaWYgcG9zc2libGUsIHJlcG9zaXRpb25zIHRoZSBwYXJzaW5nIGZyb20gdGhlcmUgYW5kIHJldHVybnMgdHJ1ZSAKCSAqIGlmIG5vdCBwb3NzaWJsZSwgZG9lcyBub3QgY2hhbmdlIGFueXRoaW5nIGFuZCByZXR1cm5zIGZhbHNlIAoJICogQHBhcmFtICB7TnVtYmVyfSAgZmlsZVBvc2l0aW9uIHBvc2l0aW9uIGluIHRoZSBmaWxlIHRvIHNlZWsgdG8KCSAqIEBwYXJhbSAge0Jvb2xlYW59IGZyb21TdGFydCAgICBpbmRpY2F0ZXMgaWYgdGhlIHNlYXJjaCBzaG91bGQgc3RhcnQgZnJvbSB0aGUgY3VycmVudCBidWZmZXIgKGZhbHNlKSAKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvciBmcm9tIHRoZSBmaXJzdCBidWZmZXIgKHRydWUpCgkgKiBAcGFyYW0gIHtCb29sZWFufSBtYXJrQXNVc2VkICAgaW5kaWNhdGVzIGlmIHRoZSBieXRlcyBpbiBiZXR3ZWVuIHRoZSBjdXJyZW50IHBvc2l0aW9uIGFuZCB0aGUgc2VlayBwb3NpdGlvbiAKCSAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaG91bGQgYmUgbWFya2VkIGFzIHVzZWQgZm9yIGdhcmJhZ2UgY29sbGVjdGlvbgoJICogQHJldHVybiB7Qm9vbGVhbn0gICAgICAgICAgICAgIHRydWUgaWYgdGhlIHNlZWsgc3VjY2VlZGVkLCBmYWxzZSBvdGhlcndpc2UKCSAqLwoJTXVsdGlCdWZmZXJTdHJlYW0ucHJvdG90eXBlLnNlZWsgPSBmdW5jdGlvbihmaWxlUG9zaXRpb24sIGZyb21TdGFydCwgbWFya0FzVXNlZCkgewoJCXZhciBpbmRleDsKCQlpbmRleCA9IHRoaXMuZmluZFBvc2l0aW9uKGZyb21TdGFydCwgZmlsZVBvc2l0aW9uLCBtYXJrQXNVc2VkKTsKCQlpZiAoaW5kZXggIT09IC0xKSB7CgkJCXRoaXMuYnVmZmVyID0gdGhpcy5idWZmZXJzW2luZGV4XTsKCQkJdGhpcy5idWZmZXJJbmRleCA9IGluZGV4OwoJCQl0aGlzLnBvc2l0aW9uID0gZmlsZVBvc2l0aW9uIC0gdGhpcy5idWZmZXIuZmlsZVN0YXJ0OwoJCQlMb2cuZGVidWcoIk11bHRpQnVmZmVyU3RyZWFtIiwgIlJlcG9zaXRpb25pbmcgcGFyc2VyIGF0IGJ1ZmZlciBwb3NpdGlvbjogIit0aGlzLnBvc2l0aW9uKTsKCQkJcmV0dXJuIHRydWU7CgkJfSBlbHNlIHsKCQkJTG9nLmRlYnVnKCJNdWx0aUJ1ZmZlclN0cmVhbSIsICJQb3NpdGlvbiAiK2ZpbGVQb3NpdGlvbisiIG5vdCBmb3VuZCBpbiBidWZmZXJlZCBkYXRhIik7CgkJCXJldHVybiBmYWxzZTsKCQl9Cgl9OwoKCS8qKgoJICogUmV0dXJucyB0aGUgY3VycmVudCBwb3NpdGlvbiBpbiB0aGUgZmlsZQoJICogQHJldHVybiB7TnVtYmVyfSB0aGUgcG9zaXRpb24gaW4gdGhlIGZpbGUKCSAqLwoJTXVsdGlCdWZmZXJTdHJlYW0ucHJvdG90eXBlLmdldFBvc2l0aW9uID0gZnVuY3Rpb24oKSB7CgkJaWYgKHRoaXMuYnVmZmVySW5kZXggPT09IC0xIHx8IHRoaXMuYnVmZmVyc1t0aGlzLmJ1ZmZlckluZGV4XSA9PT0gbnVsbCkgewoJCQl0aHJvdyAiRXJyb3IgYWNjZXNzaW5nIHBvc2l0aW9uIGluIHRoZSBNdWx0aUJ1ZmZlclN0cmVhbSI7CgkJfQoJCXJldHVybiB0aGlzLmJ1ZmZlcnNbdGhpcy5idWZmZXJJbmRleF0uZmlsZVN0YXJ0K3RoaXMucG9zaXRpb247Cgl9OwoKCS8qKgoJICogUmV0dXJucyB0aGUgbGVuZ3RoIG9mIHRoZSBjdXJyZW50IGJ1ZmZlcgoJICogQHJldHVybiB7TnVtYmVyfSB0aGUgbGVuZ3RoIG9mIHRoZSBjdXJyZW50IGJ1ZmZlcgoJICovCglNdWx0aUJ1ZmZlclN0cmVhbS5wcm90b3R5cGUuZ2V0TGVuZ3RoID0gZnVuY3Rpb24oKSB7CgkJcmV0dXJuIHRoaXMuYnl0ZUxlbmd0aDsKCX07CgoJTXVsdGlCdWZmZXJTdHJlYW0ucHJvdG90eXBlLmdldEVuZFBvc2l0aW9uID0gZnVuY3Rpb24oKSB7CgkJaWYgKHRoaXMuYnVmZmVySW5kZXggPT09IC0xIHx8IHRoaXMuYnVmZmVyc1t0aGlzLmJ1ZmZlckluZGV4XSA9PT0gbnVsbCkgewoJCQl0aHJvdyAiRXJyb3IgYWNjZXNzaW5nIHBvc2l0aW9uIGluIHRoZSBNdWx0aUJ1ZmZlclN0cmVhbSI7CgkJfQoJCXJldHVybiB0aGlzLmJ1ZmZlcnNbdGhpcy5idWZmZXJJbmRleF0uZmlsZVN0YXJ0K3RoaXMuYnl0ZUxlbmd0aDsKCX07CgoJewoJCWV4cG9ydHMuTXVsdGlCdWZmZXJTdHJlYW0gPSBNdWx0aUJ1ZmZlclN0cmVhbTsKCX0vLyBmaWxlOnNyYy9kZXNjcmlwdG9yLmpzCgkvKgoJICogQ29weXJpZ2h0IChjKSAyMDEyLTIwMTMuIFRlbGVjb20gUGFyaXNUZWNoL1RTSS9NTS9HUEFDIEN5cmlsIENvbmNvbGF0bwoJICogTGljZW5zZTogQlNELTMtQ2xhdXNlIChzZWUgTElDRU5TRSBmaWxlKQoJICovCgl2YXIgTVBFRzREZXNjcmlwdG9yUGFyc2VyID0gZnVuY3Rpb24gKCkgewoJCXZhciBFU19EZXNjclRhZyAJCQk9IDB4MDM7CgkJdmFyIERlY29kZXJDb25maWdEZXNjclRhZyAJPSAweDA0OwoJCXZhciBEZWNTcGVjaWZpY0luZm9UYWcgCQk9IDB4MDU7CgkJdmFyIFNMQ29uZmlnRGVzY3JUYWcgCQk9IDB4MDY7CgoJCXZhciBkZXNjVGFnVG9OYW1lID0gW107CgkJZGVzY1RhZ1RvTmFtZVtFU19EZXNjclRhZ10gCQkJCT0gIkVTX0Rlc2NyaXB0b3IiOwoJCWRlc2NUYWdUb05hbWVbRGVjb2RlckNvbmZpZ0Rlc2NyVGFnXSAJPSAiRGVjb2RlckNvbmZpZ0Rlc2NyaXB0b3IiOwoJCWRlc2NUYWdUb05hbWVbRGVjU3BlY2lmaWNJbmZvVGFnXSAJCT0gIkRlY29kZXJTcGVjaWZpY0luZm8iOwoJCWRlc2NUYWdUb05hbWVbU0xDb25maWdEZXNjclRhZ10gCQk9ICJTTENvbmZpZ0Rlc2NyaXB0b3IiOwoKCQl0aGlzLmdldERlc2NyaXB0b3JOYW1lID0gZnVuY3Rpb24odGFnKSB7CgkJCXJldHVybiBkZXNjVGFnVG9OYW1lW3RhZ107CgkJfTsKCgkJdmFyIHRoYXQgPSB0aGlzOwoJCXZhciBjbGFzc2VzID0ge307CgoJCXRoaXMucGFyc2VPbmVEZXNjcmlwdG9yID0gZnVuY3Rpb24gKHN0cmVhbSkgewoJCQl2YXIgc2l6ZSA9IDA7CgkJCXZhciB0YWc7CgkJCXZhciBkZXNjOwoJCQl2YXIgYnl0ZVJlYWQ7CgkJCXRhZyA9IHN0cmVhbS5yZWFkVWludDgoKTsKCQkJYnl0ZVJlYWQgPSBzdHJlYW0ucmVhZFVpbnQ4KCk7CgkJCXdoaWxlIChieXRlUmVhZCAmIDB4ODApIHsKCQkJCXNpemUgPSAoYnl0ZVJlYWQgJiAweDdGKTw8NzsKCQkJCWJ5dGVSZWFkID0gc3RyZWFtLnJlYWRVaW50OCgpOwoJCQl9CgkJCXNpemUgKz0gYnl0ZVJlYWQgJiAweDdGOwoJCQlMb2cuZGVidWcoIk1QRUc0RGVzY3JpcHRvclBhcnNlciIsICJGb3VuZCAiKyhkZXNjVGFnVG9OYW1lW3RhZ10gfHwgIkRlc2NyaXB0b3IgIit0YWcpKyIsIHNpemUgIitzaXplKyIgYXQgcG9zaXRpb24gIitzdHJlYW0uZ2V0UG9zaXRpb24oKSk7CgkJCWlmIChkZXNjVGFnVG9OYW1lW3RhZ10pIHsKCQkJCWRlc2MgPSBuZXcgY2xhc3Nlc1tkZXNjVGFnVG9OYW1lW3RhZ11dKHNpemUpOwoJCQl9IGVsc2UgewoJCQkJZGVzYyA9IG5ldyBjbGFzc2VzLkRlc2NyaXB0b3Ioc2l6ZSk7CgkJCX0KCQkJZGVzYy5wYXJzZShzdHJlYW0pOwoJCQlyZXR1cm4gZGVzYzsKCQl9OwoKCQljbGFzc2VzLkRlc2NyaXB0b3IgPSBmdW5jdGlvbihfdGFnLCBfc2l6ZSkgewoJCQl0aGlzLnRhZyA9IF90YWc7CgkJCXRoaXMuc2l6ZSA9IF9zaXplOwoJCQl0aGlzLmRlc2NzID0gW107CgkJfTsKCgkJY2xhc3Nlcy5EZXNjcmlwdG9yLnByb3RvdHlwZS5wYXJzZSA9IGZ1bmN0aW9uIChzdHJlYW0pIHsKCQkJdGhpcy5kYXRhID0gc3RyZWFtLnJlYWRVaW50OEFycmF5KHRoaXMuc2l6ZSk7CgkJfTsKCgkJY2xhc3Nlcy5EZXNjcmlwdG9yLnByb3RvdHlwZS5maW5kRGVzY3JpcHRvciA9IGZ1bmN0aW9uICh0YWcpIHsKCQkJZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmRlc2NzLmxlbmd0aDsgaSsrKSB7CgkJCQlpZiAodGhpcy5kZXNjc1tpXS50YWcgPT0gdGFnKSB7CgkJCQkJcmV0dXJuIHRoaXMuZGVzY3NbaV07CgkJCQl9CgkJCX0KCQkJcmV0dXJuIG51bGw7CgkJfTsKCgkJY2xhc3Nlcy5EZXNjcmlwdG9yLnByb3RvdHlwZS5wYXJzZVJlbWFpbmluZ0Rlc2NyaXB0b3JzID0gZnVuY3Rpb24gKHN0cmVhbSkgewoJCQl2YXIgc3RhcnQgPSBzdHJlYW0ucG9zaXRpb247CgkJCXdoaWxlIChzdHJlYW0ucG9zaXRpb24gPCBzdGFydCt0aGlzLnNpemUpIHsKCQkJCXZhciBkZXNjID0gdGhhdC5wYXJzZU9uZURlc2NyaXB0b3Ioc3RyZWFtKTsKCQkJCXRoaXMuZGVzY3MucHVzaChkZXNjKTsKCQkJfQoJCX07CgoJCWNsYXNzZXMuRVNfRGVzY3JpcHRvciA9IGZ1bmN0aW9uIChzaXplKSB7CgkJCWNsYXNzZXMuRGVzY3JpcHRvci5jYWxsKHRoaXMsIEVTX0Rlc2NyVGFnLCBzaXplKTsKCQl9OwoKCQljbGFzc2VzLkVTX0Rlc2NyaXB0b3IucHJvdG90eXBlID0gbmV3IGNsYXNzZXMuRGVzY3JpcHRvcigpOwoKCQljbGFzc2VzLkVTX0Rlc2NyaXB0b3IucHJvdG90eXBlLnBhcnNlID0gZnVuY3Rpb24oc3RyZWFtKSB7CgkJCXRoaXMuRVNfSUQgPSBzdHJlYW0ucmVhZFVpbnQxNigpOwoJCQl0aGlzLmZsYWdzID0gc3RyZWFtLnJlYWRVaW50OCgpOwoJCQl0aGlzLnNpemUgLT0gMzsKCQkJaWYgKHRoaXMuZmxhZ3MgJiAweDgwKSB7CgkJCQl0aGlzLmRlcGVuZHNPbl9FU19JRCA9IHN0cmVhbS5yZWFkVWludDE2KCk7CgkJCQl0aGlzLnNpemUgLT0gMjsKCQkJfSBlbHNlIHsKCQkJCXRoaXMuZGVwZW5kc09uX0VTX0lEID0gMDsKCQkJfQoJCQlpZiAodGhpcy5mbGFncyAmIDB4NDApIHsKCQkJCXZhciBsID0gc3RyZWFtLnJlYWRVaW50OCgpOwoJCQkJdGhpcy5VUkwgPSBzdHJlYW0ucmVhZFN0cmluZyhsKTsKCQkJCXRoaXMuc2l6ZSAtPSBsKzE7CgkJCX0gZWxzZSB7CgkJCQl0aGlzLlVSTCA9ICIiOwoJCQl9CgkJCWlmICh0aGlzLmZsYWdzICYgMHgyMCkgewoJCQkJdGhpcy5PQ1JfRVNfSUQgPSBzdHJlYW0ucmVhZFVpbnQxNigpOwoJCQkJdGhpcy5zaXplIC09IDI7CgkJCX0gZWxzZSB7CgkJCQl0aGlzLk9DUl9FU19JRCA9IDA7CgkJCX0KCQkJdGhpcy5wYXJzZVJlbWFpbmluZ0Rlc2NyaXB0b3JzKHN0cmVhbSk7CgkJfTsKCgkJY2xhc3Nlcy5FU19EZXNjcmlwdG9yLnByb3RvdHlwZS5nZXRPVEkgPSBmdW5jdGlvbihzdHJlYW0pIHsKCQkJdmFyIGRjZCA9IHRoaXMuZmluZERlc2NyaXB0b3IoRGVjb2RlckNvbmZpZ0Rlc2NyVGFnKTsKCQkJaWYgKGRjZCkgewoJCQkJcmV0dXJuIGRjZC5vdGk7CgkJCX0gZWxzZSB7CgkJCQlyZXR1cm4gMDsKCQkJfQoJCX07CgoJCWNsYXNzZXMuRVNfRGVzY3JpcHRvci5wcm90b3R5cGUuZ2V0QXVkaW9Db25maWcgPSBmdW5jdGlvbihzdHJlYW0pIHsKCQkJdmFyIGRjZCA9IHRoaXMuZmluZERlc2NyaXB0b3IoRGVjb2RlckNvbmZpZ0Rlc2NyVGFnKTsKCQkJaWYgKCFkY2QpIHJldHVybiBudWxsOwoJCQl2YXIgZHNpID0gZGNkLmZpbmREZXNjcmlwdG9yKERlY1NwZWNpZmljSW5mb1RhZyk7CgkJCWlmIChkc2kgJiYgZHNpLmRhdGEpIHsKCQkJCXZhciBhdWRpb09iamVjdFR5cGUgPSAoZHNpLmRhdGFbMF0mIDB4RjgpID4+IDM7CgkJCQlpZiAoYXVkaW9PYmplY3RUeXBlID09PSAzMSAmJiBkc2kuZGF0YS5sZW5ndGggPj0gMikgewoJCQkJCWF1ZGlvT2JqZWN0VHlwZSA9IDMyICsgKChkc2kuZGF0YVswXSAmIDB4NykgPDwgMykgKyAoKGRzaS5kYXRhWzFdICYgMHhFMCkgPj4gNSk7CgkJCQl9CgkJCQlyZXR1cm4gYXVkaW9PYmplY3RUeXBlOwoJCQl9IGVsc2UgewoJCQkJcmV0dXJuIG51bGw7CgkJCX0KCQl9OwoKCQljbGFzc2VzLkRlY29kZXJDb25maWdEZXNjcmlwdG9yID0gZnVuY3Rpb24gKHNpemUpIHsKCQkJY2xhc3Nlcy5EZXNjcmlwdG9yLmNhbGwodGhpcywgRGVjb2RlckNvbmZpZ0Rlc2NyVGFnLCBzaXplKTsKCQl9OwoJCWNsYXNzZXMuRGVjb2RlckNvbmZpZ0Rlc2NyaXB0b3IucHJvdG90eXBlID0gbmV3IGNsYXNzZXMuRGVzY3JpcHRvcigpOwoKCQljbGFzc2VzLkRlY29kZXJDb25maWdEZXNjcmlwdG9yLnByb3RvdHlwZS5wYXJzZSA9IGZ1bmN0aW9uKHN0cmVhbSkgewoJCQl0aGlzLm90aSA9IHN0cmVhbS5yZWFkVWludDgoKTsKCQkJdGhpcy5zdHJlYW1UeXBlID0gc3RyZWFtLnJlYWRVaW50OCgpOwoJCQl0aGlzLmJ1ZmZlclNpemUgPSBzdHJlYW0ucmVhZFVpbnQyNCgpOwoJCQl0aGlzLm1heEJpdHJhdGUgPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCQl0aGlzLmF2Z0JpdHJhdGUgPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCQl0aGlzLnNpemUgLT0gMTM7CgkJCXRoaXMucGFyc2VSZW1haW5pbmdEZXNjcmlwdG9ycyhzdHJlYW0pOwoJCX07CgoJCWNsYXNzZXMuRGVjb2RlclNwZWNpZmljSW5mbyA9IGZ1bmN0aW9uIChzaXplKSB7CgkJCWNsYXNzZXMuRGVzY3JpcHRvci5jYWxsKHRoaXMsIERlY1NwZWNpZmljSW5mb1RhZywgc2l6ZSk7CgkJfTsKCQljbGFzc2VzLkRlY29kZXJTcGVjaWZpY0luZm8ucHJvdG90eXBlID0gbmV3IGNsYXNzZXMuRGVzY3JpcHRvcigpOwoKCQljbGFzc2VzLlNMQ29uZmlnRGVzY3JpcHRvciA9IGZ1bmN0aW9uIChzaXplKSB7CgkJCWNsYXNzZXMuRGVzY3JpcHRvci5jYWxsKHRoaXMsIFNMQ29uZmlnRGVzY3JUYWcsIHNpemUpOwoJCX07CgkJY2xhc3Nlcy5TTENvbmZpZ0Rlc2NyaXB0b3IucHJvdG90eXBlID0gbmV3IGNsYXNzZXMuRGVzY3JpcHRvcigpOwoKCQlyZXR1cm4gdGhpczsKCX07CgoJewoJCWV4cG9ydHMuTVBFRzREZXNjcmlwdG9yUGFyc2VyID0gTVBFRzREZXNjcmlwdG9yUGFyc2VyOwoJfS8vIGZpbGU6c3JjL2JveC5qcwoJLyoKCSAqIENvcHlyaWdodCAoYykgMjAxMi0yMDEzLiBUZWxlY29tIFBhcmlzVGVjaC9UU0kvTU0vR1BBQyBDeXJpbCBDb25jb2xhdG8KCSAqIExpY2Vuc2U6IEJTRC0zLUNsYXVzZSAoc2VlIExJQ0VOU0UgZmlsZSkKCSAqLwoJdmFyIEJveFBhcnNlciA9IHsKCQlFUlJfSU5WQUxJRF9EQVRBIDogLTEsCgkJRVJSX05PVF9FTk9VR0hfREFUQSA6IDAsCgkJT0sgOiAxLAoKCQkvLyBCb3hlcyB0byBiZSBjcmVhdGVkIHdpdGggZGVmYXVsdCBwYXJzaW5nCgkJQkFTSUNfQk9YRVM6IFsgIm1kYXQiLCAiaWRhdCIsICJmcmVlIiwgInNraXAiLCAibWVjbyIsICJzdHJrIiBdLAoJCUZVTExfQk9YRVM6IFsgImhtaGQiLCAibm1oZCIsICJpb2RzIiwgInhtbCAiLCAiYnhtbCIsICJpcHJvIiwgIm1lcmUiIF0sCgkJQ09OVEFJTkVSX0JPWEVTOiBbCgkJCVsgIm1vb3YiLCBbICJ0cmFrIiwgInBzc2giIF0gXSwKCQkJWyAidHJhayIgXSwKCQkJWyAiZWR0cyIgXSwKCQkJWyAibWRpYSIgXSwKCQkJWyAibWluZiIgXSwKCQkJWyAiZGluZiIgXSwKCQkJWyAic3RibCIsIFsgInNncGQiLCAic2JncCIgXSBdLAoJCQlbICJtdmV4IiwgWyAidHJleCIgXSBdLAoJCQlbICJtb29mIiwgWyAidHJhZiIgXSBdLAoJCQlbICJ0cmFmIiwgWyAidHJ1biIsICJzZ3BkIiwgInNiZ3AiIF0gXSwKCQkJWyAidnR0YyIgXSwKCQkJWyAidHJlZiIgXSwKCQkJWyAiaXJlZiIgXSwKCQkJWyAibWZyYSIsIFsgInRmcmEiIF0gXSwKCQkJWyAibWVjbyIgXSwKCQkJWyAiaG50aSIgXSwKCQkJWyAiaGluZiIgXSwKCQkJWyAic3RyayIgXSwKCQkJWyAic3RyZCIgXSwKCQkJWyAic2luZiIgXSwKCQkJWyAicmluZiIgXSwKCQkJWyAic2NoaSIgXSwKCQkJWyAidHJnciIgXSwKCQkJWyAidWR0YSIsIFsia2luZCJdIF0sCgkJCVsgImlwcnAiLCBbImlwbWEiXSBdLAoJCQlbICJpcGNvIl0KCQldLAoJCS8vIEJveGVzIGVmZmVjdGl2ZWx5IGNyZWF0ZWQKCQlib3hDb2RlcyA6IFtdLAoJCWZ1bGxCb3hDb2RlcyA6IFtdLAoJCWNvbnRhaW5lckJveENvZGVzIDogW10sCgkJc2FtcGxlRW50cnlDb2RlcyA6IHt9LAoJCXNhbXBsZUdyb3VwRW50cnlDb2RlczogW10sCgkJdHJhY2tHcm91cFR5cGVzOiBbXSwKCQlVVUlEQm94ZXM6IHt9LAoJCVVVSURzOiBbXSwKCQlpbml0aWFsaXplOiBmdW5jdGlvbigpIHsKCQkJQm94UGFyc2VyLkZ1bGxCb3gucHJvdG90eXBlID0gbmV3IEJveFBhcnNlci5Cb3goKTsKCQkJQm94UGFyc2VyLkNvbnRhaW5lckJveC5wcm90b3R5cGUgPSBuZXcgQm94UGFyc2VyLkJveCgpOwoJCQlCb3hQYXJzZXIuU2FtcGxlRW50cnkucHJvdG90eXBlID0gbmV3IEJveFBhcnNlci5Cb3goKTsKCQkJQm94UGFyc2VyLlRyYWNrR3JvdXBUeXBlQm94LnByb3RvdHlwZSA9IG5ldyBCb3hQYXJzZXIuRnVsbEJveCgpOwoKCQkJLyogY3JlYXRpbmcgY29uc3RydWN0b3JzIGZvciBzaW1wbGUgYm94ZXMgKi8KCQkJQm94UGFyc2VyLkJBU0lDX0JPWEVTLmZvckVhY2goZnVuY3Rpb24odHlwZSkgewoJCQkJQm94UGFyc2VyLmNyZWF0ZUJveEN0b3IodHlwZSk7CgkJCX0pOwoJCQlCb3hQYXJzZXIuRlVMTF9CT1hFUy5mb3JFYWNoKGZ1bmN0aW9uKHR5cGUpIHsKCQkJCUJveFBhcnNlci5jcmVhdGVGdWxsQm94Q3Rvcih0eXBlKTsKCQkJfSk7CgkJCUJveFBhcnNlci5DT05UQUlORVJfQk9YRVMuZm9yRWFjaChmdW5jdGlvbih0eXBlcykgewoJCQkJQm94UGFyc2VyLmNyZWF0ZUNvbnRhaW5lckJveEN0b3IodHlwZXNbMF0sIG51bGwsIHR5cGVzWzFdKTsKCQkJfSk7CgkJfSwKCQlCb3g6IGZ1bmN0aW9uKF90eXBlLCBfc2l6ZSwgX3V1aWQpIHsKCQkJdGhpcy50eXBlID0gX3R5cGU7CgkJCXRoaXMuc2l6ZSA9IF9zaXplOwoJCQl0aGlzLnV1aWQgPSBfdXVpZDsKCQl9LAoJCUZ1bGxCb3g6IGZ1bmN0aW9uKHR5cGUsIHNpemUsIHV1aWQpIHsKCQkJQm94UGFyc2VyLkJveC5jYWxsKHRoaXMsIHR5cGUsIHNpemUsIHV1aWQpOwoJCQl0aGlzLmZsYWdzID0gMDsKCQkJdGhpcy52ZXJzaW9uID0gMDsKCQl9LAoJCUNvbnRhaW5lckJveDogZnVuY3Rpb24odHlwZSwgc2l6ZSwgdXVpZCkgewoJCQlCb3hQYXJzZXIuQm94LmNhbGwodGhpcywgdHlwZSwgc2l6ZSwgdXVpZCk7CgkJCXRoaXMuYm94ZXMgPSBbXTsKCQl9LAoJCVNhbXBsZUVudHJ5OiBmdW5jdGlvbih0eXBlLCBzaXplLCBoZHJfc2l6ZSwgc3RhcnQpIHsKCQkJQm94UGFyc2VyLkNvbnRhaW5lckJveC5jYWxsKHRoaXMsIHR5cGUsIHNpemUpOwoJCQl0aGlzLmhkcl9zaXplID0gaGRyX3NpemU7CgkJCXRoaXMuc3RhcnQgPSBzdGFydDsKCQl9LAoJCVNhbXBsZUdyb3VwRW50cnk6IGZ1bmN0aW9uKHR5cGUpIHsKCQkJdGhpcy5ncm91cGluZ190eXBlID0gdHlwZTsKCQl9LAoJCVRyYWNrR3JvdXBUeXBlQm94OiBmdW5jdGlvbih0eXBlLCBzaXplKSB7CgkJCUJveFBhcnNlci5GdWxsQm94LmNhbGwodGhpcywgdHlwZSwgc2l6ZSk7CgkJfSwKCQljcmVhdGVCb3hDdG9yOiBmdW5jdGlvbih0eXBlLCBwYXJzZU1ldGhvZCl7CgkJCUJveFBhcnNlci5ib3hDb2Rlcy5wdXNoKHR5cGUpOwoJCQlCb3hQYXJzZXJbdHlwZSsiQm94Il0gPSBmdW5jdGlvbihzaXplKSB7CgkJCQlCb3hQYXJzZXIuQm94LmNhbGwodGhpcywgdHlwZSwgc2l6ZSk7CgkJCX07CgkJCUJveFBhcnNlclt0eXBlKyJCb3giXS5wcm90b3R5cGUgPSBuZXcgQm94UGFyc2VyLkJveCgpOwoJCQlpZiAocGFyc2VNZXRob2QpIEJveFBhcnNlclt0eXBlKyJCb3giXS5wcm90b3R5cGUucGFyc2UgPSBwYXJzZU1ldGhvZDsKCQl9LAoJCWNyZWF0ZUZ1bGxCb3hDdG9yOiBmdW5jdGlvbih0eXBlLCBwYXJzZU1ldGhvZCkgewoJCQkvL0JveFBhcnNlci5mdWxsQm94Q29kZXMucHVzaCh0eXBlKTsKCQkJQm94UGFyc2VyW3R5cGUrIkJveCJdID0gZnVuY3Rpb24oc2l6ZSkgewoJCQkJQm94UGFyc2VyLkZ1bGxCb3guY2FsbCh0aGlzLCB0eXBlLCBzaXplKTsKCQkJfTsKCQkJQm94UGFyc2VyW3R5cGUrIkJveCJdLnByb3RvdHlwZSA9IG5ldyBCb3hQYXJzZXIuRnVsbEJveCgpOwoJCQlCb3hQYXJzZXJbdHlwZSsiQm94Il0ucHJvdG90eXBlLnBhcnNlID0gZnVuY3Rpb24oc3RyZWFtKSB7CgkJCQl0aGlzLnBhcnNlRnVsbEhlYWRlcihzdHJlYW0pOwoJCQkJaWYgKHBhcnNlTWV0aG9kKSB7CgkJCQkJcGFyc2VNZXRob2QuY2FsbCh0aGlzLCBzdHJlYW0pOwoJCQkJfQoJCQl9OwoJCX0sCgkJYWRkU3ViQm94QXJyYXlzOiBmdW5jdGlvbihzdWJCb3hOYW1lcykgewoJCQlpZiAoc3ViQm94TmFtZXMpIHsKCQkJCXRoaXMuc3ViQm94TmFtZXMgPSBzdWJCb3hOYW1lczsKCQkJCXZhciBuYlN1YkJveGVzID0gc3ViQm94TmFtZXMubGVuZ3RoOwoJCQkJZm9yICh2YXIgayA9IDA7IGs8bmJTdWJCb3hlczsgaysrKSB7CgkJCQkJdGhpc1tzdWJCb3hOYW1lc1trXSsicyJdID0gW107CgkJCQl9CgkJCX0KCQl9LAoJCWNyZWF0ZUNvbnRhaW5lckJveEN0b3I6IGZ1bmN0aW9uKHR5cGUsIHBhcnNlTWV0aG9kLCBzdWJCb3hOYW1lcykgewoJCQkvL0JveFBhcnNlci5jb250YWluZXJCb3hDb2Rlcy5wdXNoKHR5cGUpOwoJCQlCb3hQYXJzZXJbdHlwZSsiQm94Il0gPSBmdW5jdGlvbihzaXplKSB7CgkJCQlCb3hQYXJzZXIuQ29udGFpbmVyQm94LmNhbGwodGhpcywgdHlwZSwgc2l6ZSk7CgkJCQlCb3hQYXJzZXIuYWRkU3ViQm94QXJyYXlzLmNhbGwodGhpcywgc3ViQm94TmFtZXMpOwoJCQl9OwoJCQlCb3hQYXJzZXJbdHlwZSsiQm94Il0ucHJvdG90eXBlID0gbmV3IEJveFBhcnNlci5Db250YWluZXJCb3goKTsKCQkJaWYgKHBhcnNlTWV0aG9kKSBCb3hQYXJzZXJbdHlwZSsiQm94Il0ucHJvdG90eXBlLnBhcnNlID0gcGFyc2VNZXRob2Q7CgkJfSwKCQljcmVhdGVNZWRpYVNhbXBsZUVudHJ5Q3RvcjogZnVuY3Rpb24obWVkaWFUeXBlLCBwYXJzZU1ldGhvZCwgc3ViQm94TmFtZXMpIHsKCQkJQm94UGFyc2VyLnNhbXBsZUVudHJ5Q29kZXNbbWVkaWFUeXBlXSA9IFtdOwoJCQlCb3hQYXJzZXJbbWVkaWFUeXBlKyJTYW1wbGVFbnRyeSJdID0gZnVuY3Rpb24odHlwZSwgc2l6ZSkgewoJCQkJQm94UGFyc2VyLlNhbXBsZUVudHJ5LmNhbGwodGhpcywgdHlwZSwgc2l6ZSk7CgkJCQlCb3hQYXJzZXIuYWRkU3ViQm94QXJyYXlzLmNhbGwodGhpcywgc3ViQm94TmFtZXMpOwoJCQl9OwoJCQlCb3hQYXJzZXJbbWVkaWFUeXBlKyJTYW1wbGVFbnRyeSJdLnByb3RvdHlwZSA9IG5ldyBCb3hQYXJzZXIuU2FtcGxlRW50cnkoKTsKCQkJaWYgKHBhcnNlTWV0aG9kKSBCb3hQYXJzZXJbbWVkaWFUeXBlKyJTYW1wbGVFbnRyeSJdLnByb3RvdHlwZSAucGFyc2UgPSBwYXJzZU1ldGhvZDsKCQl9LAoJCWNyZWF0ZVNhbXBsZUVudHJ5Q3RvcjogZnVuY3Rpb24obWVkaWFUeXBlLCB0eXBlLCBwYXJzZU1ldGhvZCwgc3ViQm94TmFtZXMpIHsKCQkJQm94UGFyc2VyLnNhbXBsZUVudHJ5Q29kZXNbbWVkaWFUeXBlXS5wdXNoKHR5cGUpOwoJCQlCb3hQYXJzZXJbdHlwZSsiU2FtcGxlRW50cnkiXSA9IGZ1bmN0aW9uKHNpemUpIHsKCQkJCUJveFBhcnNlclttZWRpYVR5cGUrIlNhbXBsZUVudHJ5Il0uY2FsbCh0aGlzLCB0eXBlLCBzaXplKTsKCQkJCUJveFBhcnNlci5hZGRTdWJCb3hBcnJheXMuY2FsbCh0aGlzLCBzdWJCb3hOYW1lcyk7CgkJCX07CgkJCUJveFBhcnNlclt0eXBlKyJTYW1wbGVFbnRyeSJdLnByb3RvdHlwZSA9IG5ldyBCb3hQYXJzZXJbbWVkaWFUeXBlKyJTYW1wbGVFbnRyeSJdKCk7CgkJCWlmIChwYXJzZU1ldGhvZCkgQm94UGFyc2VyW3R5cGUrIlNhbXBsZUVudHJ5Il0ucHJvdG90eXBlLnBhcnNlID0gcGFyc2VNZXRob2Q7CgkJfSwKCQljcmVhdGVFbmNyeXB0ZWRTYW1wbGVFbnRyeUN0b3I6IGZ1bmN0aW9uKG1lZGlhVHlwZSwgdHlwZSwgcGFyc2VNZXRob2QpIHsKCQkJQm94UGFyc2VyLmNyZWF0ZVNhbXBsZUVudHJ5Q3Rvci5jYWxsKHRoaXMsIG1lZGlhVHlwZSwgdHlwZSwgcGFyc2VNZXRob2QsIFsic2luZiJdKTsKCQl9LAoJCWNyZWF0ZVNhbXBsZUdyb3VwQ3RvcjogZnVuY3Rpb24odHlwZSwgcGFyc2VNZXRob2QpIHsKCQkJLy9Cb3hQYXJzZXIuc2FtcGxlR3JvdXBFbnRyeUNvZGVzLnB1c2godHlwZSk7CgkJCUJveFBhcnNlclt0eXBlKyJTYW1wbGVHcm91cEVudHJ5Il0gPSBmdW5jdGlvbihzaXplKSB7CgkJCQlCb3hQYXJzZXIuU2FtcGxlR3JvdXBFbnRyeS5jYWxsKHRoaXMsIHR5cGUsIHNpemUpOwoJCQl9OwoJCQlCb3hQYXJzZXJbdHlwZSsiU2FtcGxlR3JvdXBFbnRyeSJdLnByb3RvdHlwZSA9IG5ldyBCb3hQYXJzZXIuU2FtcGxlR3JvdXBFbnRyeSgpOwoJCQlpZiAocGFyc2VNZXRob2QpIEJveFBhcnNlclt0eXBlKyJTYW1wbGVHcm91cEVudHJ5Il0ucHJvdG90eXBlLnBhcnNlID0gcGFyc2VNZXRob2Q7CgkJfSwKCQljcmVhdGVUcmFja0dyb3VwQ3RvcjogZnVuY3Rpb24odHlwZSwgcGFyc2VNZXRob2QpIHsKCQkJLy9Cb3hQYXJzZXIudHJhY2tHcm91cFR5cGVzLnB1c2godHlwZSk7CgkJCUJveFBhcnNlclt0eXBlKyJUcmFja0dyb3VwVHlwZUJveCJdID0gZnVuY3Rpb24oc2l6ZSkgewoJCQkJQm94UGFyc2VyLlRyYWNrR3JvdXBUeXBlQm94LmNhbGwodGhpcywgdHlwZSwgc2l6ZSk7CgkJCX07CgkJCUJveFBhcnNlclt0eXBlKyJUcmFja0dyb3VwVHlwZUJveCJdLnByb3RvdHlwZSA9IG5ldyBCb3hQYXJzZXIuVHJhY2tHcm91cFR5cGVCb3goKTsKCQkJaWYgKHBhcnNlTWV0aG9kKSBCb3hQYXJzZXJbdHlwZSsiVHJhY2tHcm91cFR5cGVCb3giXS5wcm90b3R5cGUucGFyc2UgPSBwYXJzZU1ldGhvZDsKCQl9LAoJCWNyZWF0ZVVVSURCb3g6IGZ1bmN0aW9uKHV1aWQsIGlzRnVsbEJveCwgaXNDb250YWluZXJCb3gsIHBhcnNlTWV0aG9kKSB7CgkJCUJveFBhcnNlci5VVUlEcy5wdXNoKHV1aWQpOwoJCQlCb3hQYXJzZXIuVVVJREJveGVzW3V1aWRdID0gZnVuY3Rpb24oc2l6ZSkgewoJCQkJaWYgKGlzRnVsbEJveCkgewoJCQkJCUJveFBhcnNlci5GdWxsQm94LmNhbGwodGhpcywgInV1aWQiLCBzaXplLCB1dWlkKTsKCQkJCX0gZWxzZSB7CgkJCQkJaWYgKGlzQ29udGFpbmVyQm94KSB7CgkJCQkJCUJveFBhcnNlci5Db250YWluZXJCb3guY2FsbCh0aGlzLCAidXVpZCIsIHNpemUsIHV1aWQpOwoJCQkJCX0gZWxzZSB7CgkJCQkJCUJveFBhcnNlci5Cb3guY2FsbCh0aGlzLCAidXVpZCIsIHNpemUsIHV1aWQpOwoJCQkJCX0KCQkJCX0KCQkJfTsKCQkJQm94UGFyc2VyLlVVSURCb3hlc1t1dWlkXS5wcm90b3R5cGUgPSAoaXNGdWxsQm94ID8gbmV3IEJveFBhcnNlci5GdWxsQm94KCkgOiAoaXNDb250YWluZXJCb3ggPyBuZXcgQm94UGFyc2VyLkNvbnRhaW5lckJveCgpIDogbmV3IEJveFBhcnNlci5Cb3goKSkpOwoJCQlpZiAocGFyc2VNZXRob2QpIHsKCQkJCWlmIChpc0Z1bGxCb3gpIHsKCQkJCQlCb3hQYXJzZXIuVVVJREJveGVzW3V1aWRdLnByb3RvdHlwZS5wYXJzZSA9IGZ1bmN0aW9uKHN0cmVhbSkgewoJCQkJCQl0aGlzLnBhcnNlRnVsbEhlYWRlcihzdHJlYW0pOwoJCQkJCQlpZiAocGFyc2VNZXRob2QpIHsKCQkJCQkJCXBhcnNlTWV0aG9kLmNhbGwodGhpcywgc3RyZWFtKTsKCQkJCQkJfQoJCQkJCX07CgkJCQl9IGVsc2UgewoJCQkJCUJveFBhcnNlci5VVUlEQm94ZXNbdXVpZF0ucHJvdG90eXBlLnBhcnNlID0gcGFyc2VNZXRob2Q7CgkJCQl9CgkJCX0KCQl9Cgl9OwoKCUJveFBhcnNlci5pbml0aWFsaXplKCk7CgoJQm94UGFyc2VyLlRLSERfRkxBR19FTkFCTEVEICAgID0gMHgwMDAwMDE7CglCb3hQYXJzZXIuVEtIRF9GTEFHX0lOX01PVklFICAgPSAweDAwMDAwMjsKCUJveFBhcnNlci5US0hEX0ZMQUdfSU5fUFJFVklFVyA9IDB4MDAwMDA0OwoKCUJveFBhcnNlci5URkhEX0ZMQUdfQkFTRV9EQVRBX09GRlNFVAk9IDB4MDE7CglCb3hQYXJzZXIuVEZIRF9GTEFHX1NBTVBMRV9ERVNDCQkJPSAweDAyOwoJQm94UGFyc2VyLlRGSERfRkxBR19TQU1QTEVfRFVSCQkJPSAweDA4OwoJQm94UGFyc2VyLlRGSERfRkxBR19TQU1QTEVfU0laRQkJCT0gMHgxMDsKCUJveFBhcnNlci5URkhEX0ZMQUdfU0FNUExFX0ZMQUdTCQk9IDB4MjA7CglCb3hQYXJzZXIuVEZIRF9GTEFHX0RVUl9FTVBUWQkJCT0gMHgxMDAwMDsKCUJveFBhcnNlci5URkhEX0ZMQUdfREVGQVVMVF9CQVNFX0lTX01PT0Y9IDB4MjAwMDA7CgoJQm94UGFyc2VyLlRSVU5fRkxBR1NfREFUQV9PRkZTRVQ9IDB4MDE7CglCb3hQYXJzZXIuVFJVTl9GTEFHU19GSVJTVF9GTEFHCT0gMHgwNDsKCUJveFBhcnNlci5UUlVOX0ZMQUdTX0RVUkFUSU9OCT0gMHgxMDA7CglCb3hQYXJzZXIuVFJVTl9GTEFHU19TSVpFCQk9IDB4MjAwOwoJQm94UGFyc2VyLlRSVU5fRkxBR1NfRkxBR1MJCT0gMHg0MDA7CglCb3hQYXJzZXIuVFJVTl9GTEFHU19DVFNfT0ZGU0VUCT0gMHg4MDA7CgoJQm94UGFyc2VyLkJveC5wcm90b3R5cGUuYWRkID0gZnVuY3Rpb24obmFtZSkgewoJCXJldHVybiB0aGlzLmFkZEJveChuZXcgQm94UGFyc2VyW25hbWUrIkJveCJdKCkpOwoJfTsKCglCb3hQYXJzZXIuQm94LnByb3RvdHlwZS5hZGRCb3ggPSBmdW5jdGlvbihib3gpIHsKCQl0aGlzLmJveGVzLnB1c2goYm94KTsKCQlpZiAodGhpc1tib3gudHlwZSsicyJdKSB7CgkJCXRoaXNbYm94LnR5cGUrInMiXS5wdXNoKGJveCk7CgkJfSBlbHNlIHsKCQkJdGhpc1tib3gudHlwZV0gPSBib3g7CgkJfQoJCXJldHVybiBib3g7Cgl9OwoKCUJveFBhcnNlci5Cb3gucHJvdG90eXBlLnNldCA9IGZ1bmN0aW9uKHByb3AsIHZhbHVlKSB7CgkJdGhpc1twcm9wXSA9IHZhbHVlOwoJCXJldHVybiB0aGlzOwoJfTsKCglCb3hQYXJzZXIuQm94LnByb3RvdHlwZS5hZGRFbnRyeSA9IGZ1bmN0aW9uKHZhbHVlLCBfcHJvcCkgewoJCXZhciBwcm9wID0gX3Byb3AgfHwgImVudHJpZXMiOwoJCWlmICghdGhpc1twcm9wXSkgewoJCQl0aGlzW3Byb3BdID0gW107CgkJfQoJCXRoaXNbcHJvcF0ucHVzaCh2YWx1ZSk7CgkJcmV0dXJuIHRoaXM7Cgl9OwoKCXsKCQlleHBvcnRzLkJveFBhcnNlciA9IEJveFBhcnNlcjsKCX0KCS8vIGZpbGU6c3JjL2JveC1wYXJzZS5qcwoJLyogCgkgKiBDb3B5cmlnaHQgKGMpIFRlbGVjb20gUGFyaXNUZWNoL1RTSS9NTS9HUEFDIEN5cmlsIENvbmNvbGF0bwoJICogTGljZW5zZTogQlNELTMtQ2xhdXNlIChzZWUgTElDRU5TRSBmaWxlKQoJICovCglCb3hQYXJzZXIucGFyc2VVVUlEID0gZnVuY3Rpb24oc3RyZWFtKSB7CgkJcmV0dXJuIEJveFBhcnNlci5wYXJzZUhleDE2KHN0cmVhbSk7Cgl9OwoKCUJveFBhcnNlci5wYXJzZUhleDE2ID0gZnVuY3Rpb24oc3RyZWFtKSB7CgkJdmFyIGhleDE2ID0gIiI7CgkJZm9yICh2YXIgaSA9IDA7IGkgPDE2OyBpKyspIHsKCQkJdmFyIGhleCA9IHN0cmVhbS5yZWFkVWludDgoKS50b1N0cmluZygxNik7CgkJCWhleDE2ICs9IChoZXgubGVuZ3RoID09PSAxID8gIjAiK2hleCA6IGhleCk7CgkJfQoJCXJldHVybiBoZXgxNjsKCX07CgoJQm94UGFyc2VyLnBhcnNlT25lQm94ID0gZnVuY3Rpb24oc3RyZWFtLCBoZWFkZXJPbmx5LCBwYXJlbnRTaXplKSB7CgkJdmFyIGJveDsKCQl2YXIgc3RhcnQgPSBzdHJlYW0uZ2V0UG9zaXRpb24oKTsKCQl2YXIgaGRyX3NpemUgPSAwOwoJCXZhciBkaWZmOwoJCXZhciB1dWlkOwoJCWlmIChzdHJlYW0uZ2V0RW5kUG9zaXRpb24oKSAtIHN0YXJ0IDwgOCkgewoJCQlMb2cuZGVidWcoIkJveFBhcnNlciIsICJOb3QgZW5vdWdoIGRhdGEgaW4gc3RyZWFtIHRvIHBhcnNlIHRoZSB0eXBlIGFuZCBzaXplIG9mIHRoZSBib3giKTsKCQkJcmV0dXJuIHsgY29kZTogQm94UGFyc2VyLkVSUl9OT1RfRU5PVUdIX0RBVEEgfTsKCQl9CgkJaWYgKHBhcmVudFNpemUgJiYgcGFyZW50U2l6ZSA8IDgpIHsKCQkJTG9nLmRlYnVnKCJCb3hQYXJzZXIiLCAiTm90IGVub3VnaCBieXRlcyBsZWZ0IGluIHRoZSBwYXJlbnQgYm94IHRvIHBhcnNlIGEgbmV3IGJveCIpOwoJCQlyZXR1cm4geyBjb2RlOiBCb3hQYXJzZXIuRVJSX05PVF9FTk9VR0hfREFUQSB9OwoJCX0KCQl2YXIgc2l6ZSA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJdmFyIHR5cGUgPSBzdHJlYW0ucmVhZFN0cmluZyg0KTsKCQl2YXIgYm94X3R5cGUgPSB0eXBlOwoJCUxvZy5kZWJ1ZygiQm94UGFyc2VyIiwgIkZvdW5kIGJveCBvZiB0eXBlICciK3R5cGUrIicgYW5kIHNpemUgIitzaXplKyIgYXQgcG9zaXRpb24gIitzdGFydCk7CgkJaGRyX3NpemUgPSA4OwoJCWlmICh0eXBlID09ICJ1dWlkIikgewoJCQlpZiAoKHN0cmVhbS5nZXRFbmRQb3NpdGlvbigpIC0gc3RyZWFtLmdldFBvc2l0aW9uKCkgPCAxNikgfHwgKHBhcmVudFNpemUgLWhkcl9zaXplIDwgMTYpKSB7CgkJCQlzdHJlYW0uc2VlayhzdGFydCk7CgkJCQlMb2cuZGVidWcoIkJveFBhcnNlciIsICJOb3QgZW5vdWdoIGJ5dGVzIGxlZnQgaW4gdGhlIHBhcmVudCBib3ggdG8gcGFyc2UgYSBVVUlEIGJveCIpOwoJCQkJcmV0dXJuIHsgY29kZTogQm94UGFyc2VyLkVSUl9OT1RfRU5PVUdIX0RBVEEgfTsKCQkJfQoJCQl1dWlkID0gQm94UGFyc2VyLnBhcnNlVVVJRChzdHJlYW0pOwoJCQloZHJfc2l6ZSArPSAxNjsKCQkJYm94X3R5cGUgPSB1dWlkOwoJCX0KCQlpZiAoc2l6ZSA9PSAxKSB7CgkJCWlmICgoc3RyZWFtLmdldEVuZFBvc2l0aW9uKCkgLSBzdHJlYW0uZ2V0UG9zaXRpb24oKSA8IDgpIHx8IChwYXJlbnRTaXplICYmIChwYXJlbnRTaXplIC0gaGRyX3NpemUpIDwgOCkpIHsKCQkJCXN0cmVhbS5zZWVrKHN0YXJ0KTsKCQkJCUxvZy53YXJuKCJCb3hQYXJzZXIiLCAiTm90IGVub3VnaCBkYXRhIGluIHN0cmVhbSB0byBwYXJzZSB0aGUgZXh0ZW5kZWQgc2l6ZSBvZiB0aGUgXCIiK3R5cGUrIlwiIGJveCIpOwoJCQkJcmV0dXJuIHsgY29kZTogQm94UGFyc2VyLkVSUl9OT1RfRU5PVUdIX0RBVEEgfTsKCQkJfQoJCQlzaXplID0gc3RyZWFtLnJlYWRVaW50NjQoKTsKCQkJaGRyX3NpemUgKz0gODsKCQl9IGVsc2UgaWYgKHNpemUgPT09IDApIHsKCQkJLyogYm94IGV4dGVuZHMgdGlsbCB0aGUgZW5kIG9mIGZpbGUgb3IgaW52YWxpZCBmaWxlICovCgkJCWlmIChwYXJlbnRTaXplKSB7CgkJCQlzaXplID0gcGFyZW50U2l6ZTsKCQkJfSBlbHNlIHsKCQkJCS8qIGJveCBleHRlbmRzIHRpbGwgdGhlIGVuZCBvZiBmaWxlICovCgkJCQlpZiAodHlwZSAhPT0gIm1kYXQiKSB7CgkJCQkJTG9nLmVycm9yKCJCb3hQYXJzZXIiLCAiVW5saW1pdGVkIGJveCBzaXplIG5vdCBzdXBwb3J0ZWQgZm9yIHR5cGU6ICciK3R5cGUrIiciKTsKCQkJCQlib3ggPSBuZXcgQm94UGFyc2VyLkJveCh0eXBlLCBzaXplKTsKCQkJCQlyZXR1cm4geyBjb2RlOiBCb3hQYXJzZXIuT0ssIGJveDogYm94LCBzaXplOiBib3guc2l6ZSB9OwoJCQkJfQoJCQl9CgkJfQoJCWlmIChzaXplICE9PSAwICYmIHNpemUgPCBoZHJfc2l6ZSkgewoJCQlMb2cuZXJyb3IoIkJveFBhcnNlciIsICJCb3ggb2YgdHlwZSAiK3R5cGUrIiBoYXMgYW4gaW52YWxpZCBzaXplICIrc2l6ZSsiICh0b28gc21hbGwgdG8gYmUgYSBib3gpIik7CgkJCXJldHVybiB7IGNvZGU6IEJveFBhcnNlci5FUlJfTk9UX0VOT1VHSF9EQVRBLCB0eXBlOiB0eXBlLCBzaXplOiBzaXplLCBoZHJfc2l6ZTogaGRyX3NpemUsIHN0YXJ0OiBzdGFydCB9OwoJCX0KCQlpZiAoc2l6ZSAhPT0gMCAmJiBwYXJlbnRTaXplICYmIHNpemUgPiBwYXJlbnRTaXplKSB7CgkJCUxvZy5lcnJvcigiQm94UGFyc2VyIiwgIkJveCBvZiB0eXBlICciK3R5cGUrIicgaGFzIGEgc2l6ZSAiK3NpemUrIiBncmVhdGVyIHRoYW4gaXRzIGNvbnRhaW5lciBzaXplICIrcGFyZW50U2l6ZSk7CgkJCXJldHVybiB7IGNvZGU6IEJveFBhcnNlci5FUlJfTk9UX0VOT1VHSF9EQVRBLCB0eXBlOiB0eXBlLCBzaXplOiBzaXplLCBoZHJfc2l6ZTogaGRyX3NpemUsIHN0YXJ0OiBzdGFydCB9OwoJCX0KCQlpZiAoc2l6ZSAhPT0gMCAmJiBzdGFydCArIHNpemUgPiBzdHJlYW0uZ2V0RW5kUG9zaXRpb24oKSkgewoJCQlzdHJlYW0uc2VlayhzdGFydCk7CgkJCUxvZy5pbmZvKCJCb3hQYXJzZXIiLCAiTm90IGVub3VnaCBkYXRhIGluIHN0cmVhbSB0byBwYXJzZSB0aGUgZW50aXJlICciK3R5cGUrIicgYm94Iik7CgkJCXJldHVybiB7IGNvZGU6IEJveFBhcnNlci5FUlJfTk9UX0VOT1VHSF9EQVRBLCB0eXBlOiB0eXBlLCBzaXplOiBzaXplLCBoZHJfc2l6ZTogaGRyX3NpemUsIHN0YXJ0OiBzdGFydCB9OwoJCX0KCQlpZiAoaGVhZGVyT25seSkgewoJCQlyZXR1cm4geyBjb2RlOiBCb3hQYXJzZXIuT0ssIHR5cGU6IHR5cGUsIHNpemU6IHNpemUsIGhkcl9zaXplOiBoZHJfc2l6ZSwgc3RhcnQ6IHN0YXJ0IH07CgkJfSBlbHNlIHsKCQkJaWYgKEJveFBhcnNlclt0eXBlKyJCb3giXSkgewoJCQkJYm94ID0gbmV3IEJveFBhcnNlclt0eXBlKyJCb3giXShzaXplKTsKCQkJfSBlbHNlIHsKCQkJCWlmICh0eXBlICE9PSAidXVpZCIpIHsKCQkJCQlMb2cud2FybigiQm94UGFyc2VyIiwgIlVua25vd24gYm94IHR5cGU6ICciK3R5cGUrIiciKTsKCQkJCQlib3ggPSBuZXcgQm94UGFyc2VyLkJveCh0eXBlLCBzaXplKTsKCQkJCQlib3guaGFzX3VucGFyc2VkX2RhdGEgPSB0cnVlOwoJCQkJfSBlbHNlIHsKCQkJCQlpZiAoQm94UGFyc2VyLlVVSURCb3hlc1t1dWlkXSkgewoJCQkJCQlib3ggPSBuZXcgQm94UGFyc2VyLlVVSURCb3hlc1t1dWlkXShzaXplKTsKCQkJCQl9IGVsc2UgewoJCQkJCQlMb2cud2FybigiQm94UGFyc2VyIiwgIlVua25vd24gdXVpZCB0eXBlOiAnIit1dWlkKyInIik7CgkJCQkJCWJveCA9IG5ldyBCb3hQYXJzZXIuQm94KHR5cGUsIHNpemUpOwoJCQkJCQlib3gudXVpZCA9IHV1aWQ7CgkJCQkJCWJveC5oYXNfdW5wYXJzZWRfZGF0YSA9IHRydWU7CgkJCQkJfQoJCQkJfQoJCQl9CgkJfQoJCWJveC5oZHJfc2l6ZSA9IGhkcl9zaXplOwoJCS8qIHJlY29yZGluZyB0aGUgcG9zaXRpb24gb2YgdGhlIGJveCBpbiB0aGUgaW5wdXQgc3RyZWFtICovCgkJYm94LnN0YXJ0ID0gc3RhcnQ7CgkJaWYgKGJveC53cml0ZSA9PT0gQm94UGFyc2VyLkJveC5wcm90b3R5cGUud3JpdGUgJiYgYm94LnR5cGUgIT09ICJtZGF0IikgewoJCQlMb2cuaW5mbygiQm94UGFyc2VyIiwgIiciK2JveF90eXBlKyInIGJveCB3cml0aW5nIG5vdCB5ZXQgaW1wbGVtZW50ZWQsIGtlZXBpbmcgdW5wYXJzZWQgZGF0YSBpbiBtZW1vcnkgZm9yIGxhdGVyIHdyaXRlIik7CgkJCWJveC5wYXJzZURhdGFBbmRSZXdpbmQoc3RyZWFtKTsKCQl9CgkJYm94LnBhcnNlKHN0cmVhbSk7CgkJZGlmZiA9IHN0cmVhbS5nZXRQb3NpdGlvbigpIC0gKGJveC5zdGFydCtib3guc2l6ZSk7CgkJaWYgKGRpZmYgPCAwKSB7CgkJCUxvZy53YXJuKCJCb3hQYXJzZXIiLCAiUGFyc2luZyBvZiBib3ggJyIrYm94X3R5cGUrIicgZGlkIG5vdCByZWFkIHRoZSBlbnRpcmUgaW5kaWNhdGVkIGJveCBkYXRhIHNpemUgKG1pc3NpbmcgIisoLWRpZmYpKyIgYnl0ZXMpLCBzZWVraW5nIGZvcndhcmQiKTsKCQkJc3RyZWFtLnNlZWsoYm94LnN0YXJ0K2JveC5zaXplKTsKCQl9IGVsc2UgaWYgKGRpZmYgPiAwKSB7CgkJCUxvZy5lcnJvcigiQm94UGFyc2VyIiwgIlBhcnNpbmcgb2YgYm94ICciK2JveF90eXBlKyInIHJlYWQgIitkaWZmKyIgbW9yZSBieXRlcyB0aGFuIHRoZSBpbmRpY2F0ZWQgYm94IGRhdGEgc2l6ZSwgc2Vla2luZyBiYWNrd2FyZHMiKTsKCQkJaWYgKGJveC5zaXplICE9PSAwKSBzdHJlYW0uc2Vlayhib3guc3RhcnQrYm94LnNpemUpOwoJCX0KCQlyZXR1cm4geyBjb2RlOiBCb3hQYXJzZXIuT0ssIGJveDogYm94LCBzaXplOiBib3guc2l6ZSB9OwoJfTsKCglCb3hQYXJzZXIuQm94LnByb3RvdHlwZS5wYXJzZSA9IGZ1bmN0aW9uKHN0cmVhbSkgewoJCWlmICh0aGlzLnR5cGUgIT0gIm1kYXQiKSB7CgkJCXRoaXMuZGF0YSA9IHN0cmVhbS5yZWFkVWludDhBcnJheSh0aGlzLnNpemUtdGhpcy5oZHJfc2l6ZSk7CgkJfSBlbHNlIHsKCQkJaWYgKHRoaXMuc2l6ZSA9PT0gMCkgewoJCQkJc3RyZWFtLnNlZWsoc3RyZWFtLmdldEVuZFBvc2l0aW9uKCkpOwoJCQl9IGVsc2UgewoJCQkJc3RyZWFtLnNlZWsodGhpcy5zdGFydCt0aGlzLnNpemUpOwoJCQl9CgkJfQoJfTsKCgkvKiBVc2VkIHRvIHBhcnNlIGEgYm94IHdpdGhvdXQgY29uc3VtaW5nIGl0cyBkYXRhLCB0byBhbGxvdyBkZXRhaWxsZWQgcGFyc2luZwoJICAgVXNlZnVsIGZvciBib3hlcyBmb3Igd2hpY2ggYSB3cml0ZSBtZXRob2QgaXMgbm90IHlldCBpbXBsZW1lbnRlZCAqLwoJQm94UGFyc2VyLkJveC5wcm90b3R5cGUucGFyc2VEYXRhQW5kUmV3aW5kID0gZnVuY3Rpb24oc3RyZWFtKSB7CgkJdGhpcy5kYXRhID0gc3RyZWFtLnJlYWRVaW50OEFycmF5KHRoaXMuc2l6ZS10aGlzLmhkcl9zaXplKTsKCQkvLyByZXdpbmRpbmcKCQlzdHJlYW0ucG9zaXRpb24gLT0gdGhpcy5zaXplLXRoaXMuaGRyX3NpemU7Cgl9OwoKCUJveFBhcnNlci5GdWxsQm94LnByb3RvdHlwZS5wYXJzZURhdGFBbmRSZXdpbmQgPSBmdW5jdGlvbihzdHJlYW0pIHsKCQl0aGlzLnBhcnNlRnVsbEhlYWRlcihzdHJlYW0pOwoJCXRoaXMuZGF0YSA9IHN0cmVhbS5yZWFkVWludDhBcnJheSh0aGlzLnNpemUtdGhpcy5oZHJfc2l6ZSk7CgkJLy8gcmVzdG9yZSB0aGUgaGVhZGVyIHNpemUgYXMgaWYgdGhlIGZ1bGwgaGVhZGVyIGhhZCBub3QgYmVlbiBwYXJzZWQKCQl0aGlzLmhkcl9zaXplIC09IDQ7CgkJLy8gcmV3aW5kaW5nCgkJc3RyZWFtLnBvc2l0aW9uIC09IHRoaXMuc2l6ZS10aGlzLmhkcl9zaXplOwoJfTsKCglCb3hQYXJzZXIuRnVsbEJveC5wcm90b3R5cGUucGFyc2VGdWxsSGVhZGVyID0gZnVuY3Rpb24gKHN0cmVhbSkgewoJCXRoaXMudmVyc2lvbiA9IHN0cmVhbS5yZWFkVWludDgoKTsKCQl0aGlzLmZsYWdzID0gc3RyZWFtLnJlYWRVaW50MjQoKTsKCQl0aGlzLmhkcl9zaXplICs9IDQ7Cgl9OwoKCUJveFBhcnNlci5GdWxsQm94LnByb3RvdHlwZS5wYXJzZSA9IGZ1bmN0aW9uIChzdHJlYW0pIHsKCQl0aGlzLnBhcnNlRnVsbEhlYWRlcihzdHJlYW0pOwoJCXRoaXMuZGF0YSA9IHN0cmVhbS5yZWFkVWludDhBcnJheSh0aGlzLnNpemUtdGhpcy5oZHJfc2l6ZSk7Cgl9OwoKCUJveFBhcnNlci5Db250YWluZXJCb3gucHJvdG90eXBlLnBhcnNlID0gZnVuY3Rpb24oc3RyZWFtKSB7CgkJdmFyIHJldDsKCQl2YXIgYm94OwoJCXdoaWxlIChzdHJlYW0uZ2V0UG9zaXRpb24oKSA8IHRoaXMuc3RhcnQrdGhpcy5zaXplKSB7CgkJCXJldCA9IEJveFBhcnNlci5wYXJzZU9uZUJveChzdHJlYW0sIGZhbHNlLCB0aGlzLnNpemUgLSAoc3RyZWFtLmdldFBvc2l0aW9uKCkgLSB0aGlzLnN0YXJ0KSk7CgkJCWlmIChyZXQuY29kZSA9PT0gQm94UGFyc2VyLk9LKSB7CgkJCQlib3ggPSByZXQuYm94OwoJCQkJLyogc3RvcmUgdGhlIGJveCBpbiB0aGUgJ2JveGVzJyBhcnJheSB0byBwcmVzZXJ2ZSBib3ggb3JkZXIgKGZvciBvZmZzZXQpIGJ1dCBhbHNvIHN0b3JlIGJveCBpbiBhIHByb3BlcnR5IGZvciBtb3JlIGRpcmVjdCBhY2Nlc3MgKi8KCQkJCXRoaXMuYm94ZXMucHVzaChib3gpOwoJCQkJaWYgKHRoaXMuc3ViQm94TmFtZXMgJiYgdGhpcy5zdWJCb3hOYW1lcy5pbmRleE9mKGJveC50eXBlKSAhPSAtMSkgewoJCQkJCXRoaXNbdGhpcy5zdWJCb3hOYW1lc1t0aGlzLnN1YkJveE5hbWVzLmluZGV4T2YoYm94LnR5cGUpXSsicyJdLnB1c2goYm94KTsKCQkJCX0gZWxzZSB7CgkJCQkJdmFyIGJveF90eXBlID0gYm94LnR5cGUgIT09ICJ1dWlkIiA/IGJveC50eXBlIDogYm94LnV1aWQ7CgkJCQkJaWYgKHRoaXNbYm94X3R5cGVdKSB7CgkJCQkJCUxvZy53YXJuKCJCb3ggb2YgdHlwZSAiK2JveF90eXBlKyIgYWxyZWFkeSBzdG9yZWQgaW4gZmllbGQgb2YgdGhpcyB0eXBlIik7CgkJCQkJfSBlbHNlIHsKCQkJCQkJdGhpc1tib3hfdHlwZV0gPSBib3g7CgkJCQkJfQoJCQkJfQoJCQl9IGVsc2UgewoJCQkJcmV0dXJuOwoJCQl9CgkJfQoJfTsKCglCb3hQYXJzZXIuQm94LnByb3RvdHlwZS5wYXJzZUxhbmd1YWdlID0gZnVuY3Rpb24oc3RyZWFtKSB7CgkJdGhpcy5sYW5ndWFnZSA9IHN0cmVhbS5yZWFkVWludDE2KCk7CgkJdmFyIGNoYXJzID0gW107CgkJY2hhcnNbMF0gPSAodGhpcy5sYW5ndWFnZT4+MTApJjB4MUY7CgkJY2hhcnNbMV0gPSAodGhpcy5sYW5ndWFnZT4+NSkmMHgxRjsKCQljaGFyc1syXSA9ICh0aGlzLmxhbmd1YWdlKSYweDFGOwoJCXRoaXMubGFuZ3VhZ2VTdHJpbmcgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGNoYXJzWzBdKzB4NjAsIGNoYXJzWzFdKzB4NjAsIGNoYXJzWzJdKzB4NjApOwoJfTsKCgkvLyBmaWxlOnNyYy9wYXJzaW5nL3NhbXBsZWVudHJpZXMvc2FtcGxlZW50cnkuanMKCUJveFBhcnNlci5TQU1QTEVfRU5UUllfVFlQRV9WSVNVQUwgCQk9ICJWaXN1YWwiOwoJQm94UGFyc2VyLlNBTVBMRV9FTlRSWV9UWVBFX0FVRElPIAkJPSAiQXVkaW8iOwoJQm94UGFyc2VyLlNBTVBMRV9FTlRSWV9UWVBFX0hJTlQgCQk9ICJIaW50IjsKCUJveFBhcnNlci5TQU1QTEVfRU5UUllfVFlQRV9NRVRBREFUQSAJPSAiTWV0YWRhdGEiOwoJQm94UGFyc2VyLlNBTVBMRV9FTlRSWV9UWVBFX1NVQlRJVExFIAk9ICJTdWJ0aXRsZSI7CglCb3hQYXJzZXIuU0FNUExFX0VOVFJZX1RZUEVfU1lTVEVNIAkJPSAiU3lzdGVtIjsKCUJveFBhcnNlci5TQU1QTEVfRU5UUllfVFlQRV9URVhUIAkJPSAiVGV4dCI7CgoJQm94UGFyc2VyLlNhbXBsZUVudHJ5LnByb3RvdHlwZS5wYXJzZUhlYWRlciA9IGZ1bmN0aW9uKHN0cmVhbSkgewoJCXN0cmVhbS5yZWFkVWludDhBcnJheSg2KTsKCQl0aGlzLmRhdGFfcmVmZXJlbmNlX2luZGV4ID0gc3RyZWFtLnJlYWRVaW50MTYoKTsKCQl0aGlzLmhkcl9zaXplICs9IDg7Cgl9OwoKCUJveFBhcnNlci5TYW1wbGVFbnRyeS5wcm90b3R5cGUucGFyc2UgPSBmdW5jdGlvbihzdHJlYW0pIHsKCQl0aGlzLnBhcnNlSGVhZGVyKHN0cmVhbSk7CgkJdGhpcy5kYXRhID0gc3RyZWFtLnJlYWRVaW50OEFycmF5KHRoaXMuc2l6ZSAtIHRoaXMuaGRyX3NpemUpOwoJfTsKCglCb3hQYXJzZXIuU2FtcGxlRW50cnkucHJvdG90eXBlLnBhcnNlRGF0YUFuZFJld2luZCA9IGZ1bmN0aW9uKHN0cmVhbSkgewoJCXRoaXMucGFyc2VIZWFkZXIoc3RyZWFtKTsKCQl0aGlzLmRhdGEgPSBzdHJlYW0ucmVhZFVpbnQ4QXJyYXkodGhpcy5zaXplIC0gdGhpcy5oZHJfc2l6ZSk7CgkJLy8gcmVzdG9yZSB0aGUgaGVhZGVyIHNpemUgYXMgaWYgdGhlIHNhbXBsZSBlbnRyeSBoZWFkZXIgaGFkIG5vdCBiZWVuIHBhcnNlZAoJCXRoaXMuaGRyX3NpemUgLT0gODsKCQkvLyByZXdpbmRpbmcKCQlzdHJlYW0ucG9zaXRpb24gLT0gdGhpcy5zaXplLXRoaXMuaGRyX3NpemU7Cgl9OwoKCUJveFBhcnNlci5TYW1wbGVFbnRyeS5wcm90b3R5cGUucGFyc2VGb290ZXIgPSBmdW5jdGlvbihzdHJlYW0pIHsKCQlCb3hQYXJzZXIuQ29udGFpbmVyQm94LnByb3RvdHlwZS5wYXJzZS5jYWxsKHRoaXMsIHN0cmVhbSk7Cgl9OwoKCS8vIEJhc2UgU2FtcGxlRW50cnkgdHlwZXMgd2l0aCBkZWZhdWx0IHBhcnNpbmcKCUJveFBhcnNlci5jcmVhdGVNZWRpYVNhbXBsZUVudHJ5Q3RvcihCb3hQYXJzZXIuU0FNUExFX0VOVFJZX1RZUEVfSElOVCk7CglCb3hQYXJzZXIuY3JlYXRlTWVkaWFTYW1wbGVFbnRyeUN0b3IoQm94UGFyc2VyLlNBTVBMRV9FTlRSWV9UWVBFX01FVEFEQVRBKTsKCUJveFBhcnNlci5jcmVhdGVNZWRpYVNhbXBsZUVudHJ5Q3RvcihCb3hQYXJzZXIuU0FNUExFX0VOVFJZX1RZUEVfU1VCVElUTEUpOwoJQm94UGFyc2VyLmNyZWF0ZU1lZGlhU2FtcGxlRW50cnlDdG9yKEJveFBhcnNlci5TQU1QTEVfRU5UUllfVFlQRV9TWVNURU0pOwoJQm94UGFyc2VyLmNyZWF0ZU1lZGlhU2FtcGxlRW50cnlDdG9yKEJveFBhcnNlci5TQU1QTEVfRU5UUllfVFlQRV9URVhUKTsKCgkvL0Jhc2UgU2FtcGxlRW50cnkgdHlwZXMgZm9yIEF1ZGlvIGFuZCBWaWRlbyB3aXRoIHNwZWNpZmljIHBhcnNpbmcKCUJveFBhcnNlci5jcmVhdGVNZWRpYVNhbXBsZUVudHJ5Q3RvcihCb3hQYXJzZXIuU0FNUExFX0VOVFJZX1RZUEVfVklTVUFMLCBmdW5jdGlvbihzdHJlYW0pIHsKCQl2YXIgY29tcHJlc3Nvcm5hbWVfbGVuZ3RoOwoJCXRoaXMucGFyc2VIZWFkZXIoc3RyZWFtKTsKCQlzdHJlYW0ucmVhZFVpbnQxNigpOwoJCXN0cmVhbS5yZWFkVWludDE2KCk7CgkJc3RyZWFtLnJlYWRVaW50MzJBcnJheSgzKTsKCQl0aGlzLndpZHRoID0gc3RyZWFtLnJlYWRVaW50MTYoKTsKCQl0aGlzLmhlaWdodCA9IHN0cmVhbS5yZWFkVWludDE2KCk7CgkJdGhpcy5ob3JpenJlc29sdXRpb24gPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCXRoaXMudmVydHJlc29sdXRpb24gPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCXN0cmVhbS5yZWFkVWludDMyKCk7CgkJdGhpcy5mcmFtZV9jb3VudCA9IHN0cmVhbS5yZWFkVWludDE2KCk7CgkJY29tcHJlc3Nvcm5hbWVfbGVuZ3RoID0gTWF0aC5taW4oMzEsIHN0cmVhbS5yZWFkVWludDgoKSk7CgkJdGhpcy5jb21wcmVzc29ybmFtZSA9IHN0cmVhbS5yZWFkU3RyaW5nKGNvbXByZXNzb3JuYW1lX2xlbmd0aCk7CgkJaWYgKGNvbXByZXNzb3JuYW1lX2xlbmd0aCA8IDMxKSB7CgkJCXN0cmVhbS5yZWFkU3RyaW5nKDMxIC0gY29tcHJlc3Nvcm5hbWVfbGVuZ3RoKTsKCQl9CgkJdGhpcy5kZXB0aCA9IHN0cmVhbS5yZWFkVWludDE2KCk7CgkJc3RyZWFtLnJlYWRVaW50MTYoKTsKCQl0aGlzLnBhcnNlRm9vdGVyKHN0cmVhbSk7Cgl9KTsKCglCb3hQYXJzZXIuY3JlYXRlTWVkaWFTYW1wbGVFbnRyeUN0b3IoQm94UGFyc2VyLlNBTVBMRV9FTlRSWV9UWVBFX0FVRElPLCBmdW5jdGlvbihzdHJlYW0pIHsKCQl0aGlzLnBhcnNlSGVhZGVyKHN0cmVhbSk7CgkJc3RyZWFtLnJlYWRVaW50MzJBcnJheSgyKTsKCQl0aGlzLmNoYW5uZWxfY291bnQgPSBzdHJlYW0ucmVhZFVpbnQxNigpOwoJCXRoaXMuc2FtcGxlc2l6ZSA9IHN0cmVhbS5yZWFkVWludDE2KCk7CgkJc3RyZWFtLnJlYWRVaW50MTYoKTsKCQlzdHJlYW0ucmVhZFVpbnQxNigpOwoJCXRoaXMuc2FtcGxlcmF0ZSA9IChzdHJlYW0ucmVhZFVpbnQzMigpLygxPDwxNikpOwoJCXRoaXMucGFyc2VGb290ZXIoc3RyZWFtKTsKCX0pOwoKCS8vIFNhbXBsZSBlbnRyaWVzIGluaGVyaXRpbmcgZnJvbSBBdWRpbyBhbmQgVmlkZW8KCUJveFBhcnNlci5jcmVhdGVTYW1wbGVFbnRyeUN0b3IoQm94UGFyc2VyLlNBTVBMRV9FTlRSWV9UWVBFX1ZJU1VBTCwgImF2YzEiKTsKCUJveFBhcnNlci5jcmVhdGVTYW1wbGVFbnRyeUN0b3IoQm94UGFyc2VyLlNBTVBMRV9FTlRSWV9UWVBFX1ZJU1VBTCwgImF2YzIiKTsKCUJveFBhcnNlci5jcmVhdGVTYW1wbGVFbnRyeUN0b3IoQm94UGFyc2VyLlNBTVBMRV9FTlRSWV9UWVBFX1ZJU1VBTCwgImF2YzMiKTsKCUJveFBhcnNlci5jcmVhdGVTYW1wbGVFbnRyeUN0b3IoQm94UGFyc2VyLlNBTVBMRV9FTlRSWV9UWVBFX1ZJU1VBTCwgImF2YzQiKTsKCUJveFBhcnNlci5jcmVhdGVTYW1wbGVFbnRyeUN0b3IoQm94UGFyc2VyLlNBTVBMRV9FTlRSWV9UWVBFX1ZJU1VBTCwgImF2MDEiKTsKCUJveFBhcnNlci5jcmVhdGVTYW1wbGVFbnRyeUN0b3IoQm94UGFyc2VyLlNBTVBMRV9FTlRSWV9UWVBFX1ZJU1VBTCwgImh2YzEiKTsKCUJveFBhcnNlci5jcmVhdGVTYW1wbGVFbnRyeUN0b3IoQm94UGFyc2VyLlNBTVBMRV9FTlRSWV9UWVBFX1ZJU1VBTCwgImhldjEiKTsKCUJveFBhcnNlci5jcmVhdGVTYW1wbGVFbnRyeUN0b3IoQm94UGFyc2VyLlNBTVBMRV9FTlRSWV9UWVBFX1ZJU1VBTCwgInZ2YzEiKTsKCUJveFBhcnNlci5jcmVhdGVTYW1wbGVFbnRyeUN0b3IoQm94UGFyc2VyLlNBTVBMRV9FTlRSWV9UWVBFX1ZJU1VBTCwgInZ2aTEiKTsKCUJveFBhcnNlci5jcmVhdGVTYW1wbGVFbnRyeUN0b3IoQm94UGFyc2VyLlNBTVBMRV9FTlRSWV9UWVBFX1ZJU1VBTCwgInZ2czEiKTsKCUJveFBhcnNlci5jcmVhdGVTYW1wbGVFbnRyeUN0b3IoQm94UGFyc2VyLlNBTVBMRV9FTlRSWV9UWVBFX1ZJU1VBTCwgInZ2Y04iKTsKCUJveFBhcnNlci5jcmVhdGVTYW1wbGVFbnRyeUN0b3IoQm94UGFyc2VyLlNBTVBMRV9FTlRSWV9UWVBFX1ZJU1VBTCwgInZwMDgiKTsKCUJveFBhcnNlci5jcmVhdGVTYW1wbGVFbnRyeUN0b3IoQm94UGFyc2VyLlNBTVBMRV9FTlRSWV9UWVBFX1ZJU1VBTCwgInZwMDkiKTsKCUJveFBhcnNlci5jcmVhdGVTYW1wbGVFbnRyeUN0b3IoQm94UGFyc2VyLlNBTVBMRV9FTlRSWV9UWVBFX0FVRElPLCAJIm1wNGEiKTsKCUJveFBhcnNlci5jcmVhdGVTYW1wbGVFbnRyeUN0b3IoQm94UGFyc2VyLlNBTVBMRV9FTlRSWV9UWVBFX0FVRElPLCAJImFjLTMiKTsKCUJveFBhcnNlci5jcmVhdGVTYW1wbGVFbnRyeUN0b3IoQm94UGFyc2VyLlNBTVBMRV9FTlRSWV9UWVBFX0FVRElPLCAJImVjLTMiKTsKCUJveFBhcnNlci5jcmVhdGVTYW1wbGVFbnRyeUN0b3IoQm94UGFyc2VyLlNBTVBMRV9FTlRSWV9UWVBFX0FVRElPLCAJIk9wdXMiKTsKCgkvLyBFbmNyeXB0ZWQgc2FtcGxlIGVudHJpZXMKCUJveFBhcnNlci5jcmVhdGVFbmNyeXB0ZWRTYW1wbGVFbnRyeUN0b3IoQm94UGFyc2VyLlNBTVBMRV9FTlRSWV9UWVBFX1ZJU1VBTCwgCSJlbmN2Iik7CglCb3hQYXJzZXIuY3JlYXRlRW5jcnlwdGVkU2FtcGxlRW50cnlDdG9yKEJveFBhcnNlci5TQU1QTEVfRU5UUllfVFlQRV9BVURJTywgCSJlbmNhIik7CglCb3hQYXJzZXIuY3JlYXRlRW5jcnlwdGVkU2FtcGxlRW50cnlDdG9yKEJveFBhcnNlci5TQU1QTEVfRU5UUllfVFlQRV9TVUJUSVRMRSwgCSJlbmN1Iik7CglCb3hQYXJzZXIuY3JlYXRlRW5jcnlwdGVkU2FtcGxlRW50cnlDdG9yKEJveFBhcnNlci5TQU1QTEVfRU5UUllfVFlQRV9TWVNURU0sIAkiZW5jcyIpOwoJQm94UGFyc2VyLmNyZWF0ZUVuY3J5cHRlZFNhbXBsZUVudHJ5Q3RvcihCb3hQYXJzZXIuU0FNUExFX0VOVFJZX1RZUEVfVEVYVCwgCQkiZW5jdCIpOwoJQm94UGFyc2VyLmNyZWF0ZUVuY3J5cHRlZFNhbXBsZUVudHJ5Q3RvcihCb3hQYXJzZXIuU0FNUExFX0VOVFJZX1RZUEVfTUVUQURBVEEsIAkiZW5jbSIpOwoJLy8gZmlsZTpzcmMvcGFyc2luZy9hMWx4LmpzCglCb3hQYXJzZXIuY3JlYXRlQm94Q3RvcigiYTFseCIsIGZ1bmN0aW9uKHN0cmVhbSkgewoJCXZhciBsYXJnZV9zaXplID0gc3RyZWFtLnJlYWRVaW50OCgpICYgMTsKCQl2YXIgRmllbGRMZW5ndGggPSAoKGxhcmdlX3NpemUgJiAxKSArIDEpICogMTY7CgkJdGhpcy5sYXllcl9zaXplID0gW107CgkJZm9yICh2YXIgaSA9IDA7IGkgPCAzOyBpKyspIHsKCQkJaWYgKEZpZWxkTGVuZ3RoID09IDE2KSB7CgkJCQl0aGlzLmxheWVyX3NpemVbaV0gPSBzdHJlYW0ucmVhZFVpbnQxNigpOwoJCQl9IGVsc2UgewoJCQkJdGhpcy5sYXllcl9zaXplW2ldID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQkJfQoJCX0KCX0pOy8vIGZpbGU6c3JjL3BhcnNpbmcvYTFvcC5qcwoJQm94UGFyc2VyLmNyZWF0ZUJveEN0b3IoImExb3AiLCBmdW5jdGlvbihzdHJlYW0pIHsKCQl0aGlzLm9wX2luZGV4ID0gc3RyZWFtLnJlYWRVaW50OCgpOwoJfSk7Ly8gZmlsZTpzcmMvcGFyc2luZy9hdXhDLmpzCglCb3hQYXJzZXIuY3JlYXRlRnVsbEJveEN0b3IoImF1eEMiLCBmdW5jdGlvbihzdHJlYW0pIHsKCQl0aGlzLmF1eF90eXBlID0gc3RyZWFtLnJlYWRDU3RyaW5nKCk7CgkJdmFyIGF1eF9zdWJ0eXBlX2xlbmd0aCA9IHRoaXMuc2l6ZSAtIHRoaXMuaGRyX3NpemUgLSAodGhpcy5hdXhfdHlwZS5sZW5ndGggKyAxKTsKCQl0aGlzLmF1eF9zdWJ0eXBlID0gc3RyZWFtLnJlYWRVaW50OEFycmF5KGF1eF9zdWJ0eXBlX2xlbmd0aCk7Cgl9KTsvLyBmaWxlOnNyYy9wYXJzaW5nL2F2MUMuanMKCUJveFBhcnNlci5jcmVhdGVCb3hDdG9yKCJhdjFDIiwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJdmFyIHRtcCA9IHN0cmVhbS5yZWFkVWludDgoKTsKCQlpZiAoKHRtcCA+PiA3KSAmIDB4MSAhPT0gMSkgewoJCQlMb2cuZXJyb3IoImF2MUMgbWFya2VyIHByb2JsZW0iKTsKCQkJcmV0dXJuOwoJCX0KCQl0aGlzLnZlcnNpb24gPSB0bXAgJiAweDdGOwoJCWlmICh0aGlzLnZlcnNpb24gIT09IDEpIHsKCQkJTG9nLmVycm9yKCJhdjFDIHZlcnNpb24gIit0aGlzLnZlcnNpb24rIiBub3Qgc3VwcG9ydGVkIik7CgkJCXJldHVybjsKCQl9CgkJdG1wID0gc3RyZWFtLnJlYWRVaW50OCgpOwoJCXRoaXMuc2VxX3Byb2ZpbGUgPSAodG1wID4+IDUpICYgMHg3OwoJCXRoaXMuc2VxX2xldmVsX2lkeF8wID0gdG1wICYgMHgxRjsKCQl0bXAgPSBzdHJlYW0ucmVhZFVpbnQ4KCk7CgkJdGhpcy5zZXFfdGllcl8wID0gKHRtcCA+PiA3KSAmIDB4MTsKCQl0aGlzLmhpZ2hfYml0ZGVwdGggPSAodG1wID4+IDYpICYgMHgxOwoJCXRoaXMudHdlbHZlX2JpdCA9ICh0bXAgPj4gNSkgJiAweDE7CgkJdGhpcy5tb25vY2hyb21lID0gKHRtcCA+PiA0KSAmIDB4MTsKCQl0aGlzLmNocm9tYV9zdWJzYW1wbGluZ194ID0gKHRtcCA+PiAzKSAmIDB4MTsKCQl0aGlzLmNocm9tYV9zdWJzYW1wbGluZ195ID0gKHRtcCA+PiAyKSAmIDB4MTsKCQl0aGlzLmNocm9tYV9zYW1wbGVfcG9zaXRpb24gPSAodG1wICYgMHgzKTsKCQl0bXAgPSBzdHJlYW0ucmVhZFVpbnQ4KCk7CgkJdGhpcy5yZXNlcnZlZF8xID0gKHRtcCA+PiA1KSAmIDB4NzsKCQlpZiAodGhpcy5yZXNlcnZlZF8xICE9PSAwKSB7CgkJCUxvZy5lcnJvcigiYXYxQyByZXNlcnZlZF8xIHBhcnNpbmcgcHJvYmxlbSIpOwoJCQlyZXR1cm47CgkJfQoJCXRoaXMuaW5pdGlhbF9wcmVzZW50YXRpb25fZGVsYXlfcHJlc2VudCA9ICh0bXAgPj4gNCkgJiAweDE7CgkJaWYgKHRoaXMuaW5pdGlhbF9wcmVzZW50YXRpb25fZGVsYXlfcHJlc2VudCA9PT0gMSkgewoJCQl0aGlzLmluaXRpYWxfcHJlc2VudGF0aW9uX2RlbGF5X21pbnVzX29uZSA9ICh0bXAgJiAweEYpOwoJCX0gZWxzZSB7CgkJCXRoaXMucmVzZXJ2ZWRfMiA9ICh0bXAgJiAweEYpOwoJCQlpZiAodGhpcy5yZXNlcnZlZF8yICE9PSAwKSB7CgkJCQlMb2cuZXJyb3IoImF2MUMgcmVzZXJ2ZWRfMiBwYXJzaW5nIHByb2JsZW0iKTsKCQkJCXJldHVybjsKCQkJfQoJCX0KCgkJdmFyIGNvbmZpZ09CVXNfbGVuZ3RoID0gdGhpcy5zaXplIC0gdGhpcy5oZHJfc2l6ZSAtIDQ7CgkJdGhpcy5jb25maWdPQlVzID0gc3RyZWFtLnJlYWRVaW50OEFycmF5KGNvbmZpZ09CVXNfbGVuZ3RoKTsKCX0pOwoKCS8vIGZpbGU6c3JjL3BhcnNpbmcvYXZjQy5qcwoJQm94UGFyc2VyLmNyZWF0ZUJveEN0b3IoImF2Y0MiLCBmdW5jdGlvbihzdHJlYW0pIHsKCQl2YXIgaTsKCQl2YXIgdG9wYXJzZTsKCQl0aGlzLmNvbmZpZ3VyYXRpb25WZXJzaW9uID0gc3RyZWFtLnJlYWRVaW50OCgpOwoJCXRoaXMuQVZDUHJvZmlsZUluZGljYXRpb24gPSBzdHJlYW0ucmVhZFVpbnQ4KCk7CgkJdGhpcy5wcm9maWxlX2NvbXBhdGliaWxpdHkgPSBzdHJlYW0ucmVhZFVpbnQ4KCk7CgkJdGhpcy5BVkNMZXZlbEluZGljYXRpb24gPSBzdHJlYW0ucmVhZFVpbnQ4KCk7CgkJdGhpcy5sZW5ndGhTaXplTWludXNPbmUgPSAoc3RyZWFtLnJlYWRVaW50OCgpICYgMHgzKTsKCQl0aGlzLm5iX1NQU19uYWx1cyA9IChzdHJlYW0ucmVhZFVpbnQ4KCkgJiAweDFGKTsKCQl0b3BhcnNlID0gdGhpcy5zaXplIC0gdGhpcy5oZHJfc2l6ZSAtIDY7CgkJdGhpcy5TUFMgPSBbXTsKCQlmb3IgKGkgPSAwOyBpIDwgdGhpcy5uYl9TUFNfbmFsdXM7IGkrKykgewoJCQl0aGlzLlNQU1tpXSA9IHt9OwoJCQl0aGlzLlNQU1tpXS5sZW5ndGggPSBzdHJlYW0ucmVhZFVpbnQxNigpOwoJCQl0aGlzLlNQU1tpXS5uYWx1ID0gc3RyZWFtLnJlYWRVaW50OEFycmF5KHRoaXMuU1BTW2ldLmxlbmd0aCk7CgkJCXRvcGFyc2UgLT0gMit0aGlzLlNQU1tpXS5sZW5ndGg7CgkJfQoJCXRoaXMubmJfUFBTX25hbHVzID0gc3RyZWFtLnJlYWRVaW50OCgpOwoJCXRvcGFyc2UtLTsKCQl0aGlzLlBQUyA9IFtdOwoJCWZvciAoaSA9IDA7IGkgPCB0aGlzLm5iX1BQU19uYWx1czsgaSsrKSB7CgkJCXRoaXMuUFBTW2ldID0ge307CgkJCXRoaXMuUFBTW2ldLmxlbmd0aCA9IHN0cmVhbS5yZWFkVWludDE2KCk7CgkJCXRoaXMuUFBTW2ldLm5hbHUgPSBzdHJlYW0ucmVhZFVpbnQ4QXJyYXkodGhpcy5QUFNbaV0ubGVuZ3RoKTsKCQkJdG9wYXJzZSAtPSAyK3RoaXMuUFBTW2ldLmxlbmd0aDsKCQl9CgkJaWYgKHRvcGFyc2U+MCkgewoJCQl0aGlzLmV4dCA9IHN0cmVhbS5yZWFkVWludDhBcnJheSh0b3BhcnNlKTsKCQl9Cgl9KTsKCgkvLyBmaWxlOnNyYy9wYXJzaW5nL2J0cnQuanMKCUJveFBhcnNlci5jcmVhdGVCb3hDdG9yKCJidHJ0IiwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJdGhpcy5idWZmZXJTaXplREIgPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCXRoaXMubWF4Qml0cmF0ZSA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJdGhpcy5hdmdCaXRyYXRlID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCX0pOwoKCS8vIGZpbGU6c3JjL3BhcnNpbmcvY2xhcC5qcwoJQm94UGFyc2VyLmNyZWF0ZUJveEN0b3IoImNsYXAiLCBmdW5jdGlvbihzdHJlYW0pIHsKCQl0aGlzLmNsZWFuQXBlcnR1cmVXaWR0aE4gPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCXRoaXMuY2xlYW5BcGVydHVyZVdpZHRoRCA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJdGhpcy5jbGVhbkFwZXJ0dXJlSGVpZ2h0TiA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJdGhpcy5jbGVhbkFwZXJ0dXJlSGVpZ2h0RCA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJdGhpcy5ob3Jpek9mZk4gPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCXRoaXMuaG9yaXpPZmZEID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQl0aGlzLnZlcnRPZmZOID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQl0aGlzLnZlcnRPZmZEID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCX0pOy8vIGZpbGU6c3JjL3BhcnNpbmcvY2xsaS5qcwoJQm94UGFyc2VyLmNyZWF0ZUJveEN0b3IoImNsbGkiLCBmdW5jdGlvbihzdHJlYW0pIHsKCQl0aGlzLm1heF9jb250ZW50X2xpZ2h0X2xldmVsID0gc3RyZWFtLnJlYWRVaW50MTYoKTsKCSAgICB0aGlzLm1heF9waWNfYXZlcmFnZV9saWdodF9sZXZlbCA9IHN0cmVhbS5yZWFkVWludDE2KCk7Cgl9KTsKCgkvLyBmaWxlOnNyYy9wYXJzaW5nL2NvNjQuanMKCUJveFBhcnNlci5jcmVhdGVGdWxsQm94Q3RvcigiY282NCIsIGZ1bmN0aW9uKHN0cmVhbSkgewoJCXZhciBlbnRyeV9jb3VudDsKCQl2YXIgaTsKCQllbnRyeV9jb3VudCA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJdGhpcy5jaHVua19vZmZzZXRzID0gW107CgkJaWYgKHRoaXMudmVyc2lvbiA9PT0gMCkgewoJCQlmb3IoaT0wOyBpPGVudHJ5X2NvdW50OyBpKyspIHsKCQkJCXRoaXMuY2h1bmtfb2Zmc2V0cy5wdXNoKHN0cmVhbS5yZWFkVWludDY0KCkpOwoJCQl9CgkJfQoJfSk7CgoJLy8gZmlsZTpzcmMvcGFyc2luZy9Db0xMLmpzCglCb3hQYXJzZXIuY3JlYXRlRnVsbEJveEN0b3IoIkNvTEwiLCBmdW5jdGlvbihzdHJlYW0pIHsKCQl0aGlzLm1heENMTCA9IHN0cmVhbS5yZWFkVWludDE2KCk7CgkgICAgdGhpcy5tYXhGQUxMID0gc3RyZWFtLnJlYWRVaW50MTYoKTsKCX0pOwoKCS8vIGZpbGU6c3JjL3BhcnNpbmcvY29sci5qcwoJQm94UGFyc2VyLmNyZWF0ZUJveEN0b3IoImNvbHIiLCBmdW5jdGlvbihzdHJlYW0pIHsKCQl0aGlzLmNvbG91cl90eXBlID0gc3RyZWFtLnJlYWRTdHJpbmcoNCk7CgkJaWYgKHRoaXMuY29sb3VyX3R5cGUgPT09ICduY2x4JykgewoJCQl0aGlzLmNvbG91cl9wcmltYXJpZXMgPSBzdHJlYW0ucmVhZFVpbnQxNigpOwoJCQl0aGlzLnRyYW5zZmVyX2NoYXJhY3RlcmlzdGljcyA9IHN0cmVhbS5yZWFkVWludDE2KCk7CgkJCXRoaXMubWF0cml4X2NvZWZmaWNpZW50cyA9IHN0cmVhbS5yZWFkVWludDE2KCk7CgkJCXZhciB0bXAgPSBzdHJlYW0ucmVhZFVpbnQ4KCk7CgkJCXRoaXMuZnVsbF9yYW5nZV9mbGFnID0gdG1wID4+IDc7CgkJfSBlbHNlIGlmICh0aGlzLmNvbG91cl90eXBlID09PSAncklDQycpIHsKCQkJdGhpcy5JQ0NfcHJvZmlsZSA9IHN0cmVhbS5yZWFkVWludDhBcnJheSh0aGlzLnNpemUgLSA0KTsKCQl9IGVsc2UgaWYgKHRoaXMuY29sb3VyX3R5cGUgPT09ICdwcm9mJykgewoJCQl0aGlzLklDQ19wcm9maWxlID0gc3RyZWFtLnJlYWRVaW50OEFycmF5KHRoaXMuc2l6ZSAtIDQpOwoJCX0KCX0pOy8vIGZpbGU6c3JjL3BhcnNpbmcvY3BydC5qcwoJQm94UGFyc2VyLmNyZWF0ZUZ1bGxCb3hDdG9yKCJjcHJ0IiwgZnVuY3Rpb24gKHN0cmVhbSkgewoJCXRoaXMucGFyc2VMYW5ndWFnZShzdHJlYW0pOwoJCXRoaXMubm90aWNlID0gc3RyZWFtLnJlYWRDU3RyaW5nKCk7Cgl9KTsKCgkvLyBmaWxlOnNyYy9wYXJzaW5nL2NzbGcuanMKCUJveFBhcnNlci5jcmVhdGVGdWxsQm94Q3RvcigiY3NsZyIsIGZ1bmN0aW9uKHN0cmVhbSkgewoJCWlmICh0aGlzLnZlcnNpb24gPT09IDApIHsKCQkJdGhpcy5jb21wb3NpdGlvblRvRFRTU2hpZnQgPSBzdHJlYW0ucmVhZEludDMyKCk7IC8qIHNpZ25lZCAqLwoJCQl0aGlzLmxlYXN0RGVjb2RlVG9EaXNwbGF5RGVsdGEgPSBzdHJlYW0ucmVhZEludDMyKCk7IC8qIHNpZ25lZCAqLwoJCQl0aGlzLmdyZWF0ZXN0RGVjb2RlVG9EaXNwbGF5RGVsdGEgPSBzdHJlYW0ucmVhZEludDMyKCk7IC8qIHNpZ25lZCAqLwoJCQl0aGlzLmNvbXBvc2l0aW9uU3RhcnRUaW1lID0gc3RyZWFtLnJlYWRJbnQzMigpOyAvKiBzaWduZWQgKi8KCQkJdGhpcy5jb21wb3NpdGlvbkVuZFRpbWUgPSBzdHJlYW0ucmVhZEludDMyKCk7IC8qIHNpZ25lZCAqLwoJCX0KCX0pOwoKCS8vIGZpbGU6c3JjL3BhcnNpbmcvY3R0cy5qcwoJQm94UGFyc2VyLmNyZWF0ZUZ1bGxCb3hDdG9yKCJjdHRzIiwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJdmFyIGVudHJ5X2NvdW50OwoJCXZhciBpOwoJCWVudHJ5X2NvdW50ID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQl0aGlzLnNhbXBsZV9jb3VudHMgPSBbXTsKCQl0aGlzLnNhbXBsZV9vZmZzZXRzID0gW107CgkJaWYgKHRoaXMudmVyc2lvbiA9PT0gMCkgewoJCQlmb3IoaT0wOyBpPGVudHJ5X2NvdW50OyBpKyspIHsKCQkJCXRoaXMuc2FtcGxlX2NvdW50cy5wdXNoKHN0cmVhbS5yZWFkVWludDMyKCkpOwoJCQkJLyogc29tZSBmaWxlcyBhcmUgYnVnZ3kgYW5kIGRlY2xhcmUgdmVyc2lvbj0wIHdoaWxlIHVzaW5nIHNpZ25lZCBvZmZzZXRzLgoJCQkJICAgVGhlIGxpa2VseWhvb2Qgb2YgdXNpbmcgdGhlIG1vc3Qgc2lnbmlmaWNhbnQgYml0IGluIGEgMzItYml0cyB0aW1lIG9mZnNldCBpcyB2ZXJ5IGxvdywKCQkJCSAgIHNvIHVzaW5nIHNpZ25lZCB2YWx1ZSBoZXJlIGFzIHdlbGwgKi8KCQkJCSAgIHZhciB2YWx1ZSA9IHN0cmVhbS5yZWFkSW50MzIoKTsKCQkJCSAgIGlmICh2YWx1ZSA8IDApIHsKCQkJCSAgIAkJTG9nLndhcm4oIkJveFBhcnNlciIsICJjdHRzIGJveCB1c2VzIG5lZ2F0aXZlIHZhbHVlcyB3aXRob3V0IHVzaW5nIHZlcnNpb24gMSIpOwoJCQkJICAgfQoJCQkJdGhpcy5zYW1wbGVfb2Zmc2V0cy5wdXNoKHZhbHVlKTsKCQkJfQoJCX0gZWxzZSBpZiAodGhpcy52ZXJzaW9uID09IDEpIHsKCQkJZm9yKGk9MDsgaTxlbnRyeV9jb3VudDsgaSsrKSB7CgkJCQl0aGlzLnNhbXBsZV9jb3VudHMucHVzaChzdHJlYW0ucmVhZFVpbnQzMigpKTsKCQkJCXRoaXMuc2FtcGxlX29mZnNldHMucHVzaChzdHJlYW0ucmVhZEludDMyKCkpOyAvKiBzaWduZWQgKi8KCQkJfQoJCX0KCX0pOwoKCS8vIGZpbGU6c3JjL3BhcnNpbmcvZGFjMy5qcwoJQm94UGFyc2VyLmNyZWF0ZUJveEN0b3IoImRhYzMiLCBmdW5jdGlvbihzdHJlYW0pIHsKCQl2YXIgdG1wX2J5dGUxID0gc3RyZWFtLnJlYWRVaW50OCgpOwoJCXZhciB0bXBfYnl0ZTIgPSBzdHJlYW0ucmVhZFVpbnQ4KCk7CgkJdmFyIHRtcF9ieXRlMyA9IHN0cmVhbS5yZWFkVWludDgoKTsKCQl0aGlzLmZzY29kID0gdG1wX2J5dGUxID4+IDY7CgkJdGhpcy5ic2lkICA9ICgodG1wX2J5dGUxID4+IDEpICYgMHgxRik7CgkJdGhpcy5ic21vZCA9ICgodG1wX2J5dGUxICYgMHgxKSA8PCAgMikgfCAoKHRtcF9ieXRlMiA+PiA2KSAmIDB4Myk7CgkJdGhpcy5hY21vZCA9ICgodG1wX2J5dGUyID4+IDMpICYgMHg3KTsKCQl0aGlzLmxmZW9uID0gKCh0bXBfYnl0ZTIgPj4gMikgJiAweDEpOwoJCXRoaXMuYml0X3JhdGVfY29kZSA9ICh0bXBfYnl0ZTIgJiAweDMpIHwgKCh0bXBfYnl0ZTMgPj4gNSkgJiAweDcpOwoJfSk7CgoJLy8gZmlsZTpzcmMvcGFyc2luZy9kZWMzLmpzCglCb3hQYXJzZXIuY3JlYXRlQm94Q3RvcigiZGVjMyIsIGZ1bmN0aW9uKHN0cmVhbSkgewoJCXZhciB0bXBfMTYgPSBzdHJlYW0ucmVhZFVpbnQxNigpOwoJCXRoaXMuZGF0YV9yYXRlID0gdG1wXzE2ID4+IDM7CgkJdGhpcy5udW1faW5kX3N1YiA9IHRtcF8xNiAmIDB4NzsKCQl0aGlzLmluZF9zdWJzID0gW107CgkJZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLm51bV9pbmRfc3ViKzE7IGkrKykgewoJCQl2YXIgaW5kX3N1YiA9IHt9OwoJCQl0aGlzLmluZF9zdWJzLnB1c2goaW5kX3N1Yik7CgkJCXZhciB0bXBfYnl0ZTEgPSBzdHJlYW0ucmVhZFVpbnQ4KCk7CgkJCXZhciB0bXBfYnl0ZTIgPSBzdHJlYW0ucmVhZFVpbnQ4KCk7CgkJCXZhciB0bXBfYnl0ZTMgPSBzdHJlYW0ucmVhZFVpbnQ4KCk7CgkJCWluZF9zdWIuZnNjb2QgPSB0bXBfYnl0ZTEgPj4gNjsKCQkJaW5kX3N1Yi5ic2lkICA9ICgodG1wX2J5dGUxID4+IDEpICYgMHgxRik7CgkJCWluZF9zdWIuYnNtb2QgPSAoKHRtcF9ieXRlMSAmIDB4MSkgPDwgNCkgfCAoKHRtcF9ieXRlMiA+PiA0KSAmIDB4Rik7CgkJCWluZF9zdWIuYWNtb2QgPSAoKHRtcF9ieXRlMiA+PiAxKSAmIDB4Nyk7CgkJCWluZF9zdWIubGZlb24gPSAodG1wX2J5dGUyICYgMHgxKTsKCQkJaW5kX3N1Yi5udW1fZGVwX3N1YiA9ICgodG1wX2J5dGUzID4+IDEpICYgMHhGKTsKCQkJaWYgKGluZF9zdWIubnVtX2RlcF9zdWIgPiAwKSB7CgkJCQlpbmRfc3ViLmNoYW5fbG9jID0gKCh0bXBfYnl0ZTMgJiAweDEpIDw8IDgpIHwgc3RyZWFtLnJlYWRVaW50OCgpOwoJCQl9CgkJfQoJfSk7CgoJLy8gZmlsZTpzcmMvcGFyc2luZy9kZkxhLmpzCglCb3hQYXJzZXIuY3JlYXRlRnVsbEJveEN0b3IoImRmTGEiLCBmdW5jdGlvbihzdHJlYW0pIHsKCSAgICB2YXIgQkxPQ0tUWVBFX01BU0sgPSAweDdGOwoJICAgIHZhciBMQVNUTUVUQURBVEFCTE9DS0ZMQUdfTUFTSyA9IDB4ODA7CgoJICAgIHZhciBib3hlc0ZvdW5kID0gW107CgkgICAgdmFyIGtub3duQmxvY2tUeXBlcyA9IFsKCSAgICAgICAgIlNUUkVBTUlORk8iLAoJICAgICAgICAiUEFERElORyIsCgkgICAgICAgICJBUFBMSUNBVElPTiIsCgkgICAgICAgICJTRUVLVEFCTEUiLAoJICAgICAgICAiVk9SQklTX0NPTU1FTlQiLAoJICAgICAgICAiQ1VFU0hFRVQiLAoJICAgICAgICAiUElDVFVSRSIsCgkgICAgICAgICJSRVNFUlZFRCIKCSAgICBdOwoKCSAgICAvLyBkZkxhIGlzIGEgRnVsbEJveAoJICAgIHRoaXMucGFyc2VGdWxsSGVhZGVyKHN0cmVhbSk7CgoJICAgIC8vIGZvciAoaT0wOyA7IGkrKykgeyAvLyB0byBlbmQgb2YgYm94CgkgICAgZG8gewoJICAgICAgICB2YXIgZmxhZ0FuZFR5cGUgPSBzdHJlYW0ucmVhZFVpbnQ4KCk7CgoJICAgICAgICB2YXIgdHlwZSA9IE1hdGgubWluKAoJICAgICAgICAgICAgKGZsYWdBbmRUeXBlICYgQkxPQ0tUWVBFX01BU0spLAoJICAgICAgICAgICAgKGtub3duQmxvY2tUeXBlcy5sZW5ndGggLSAxKQoJICAgICAgICApOwoKCSAgICAgICAgLy8gaWYgdGhpcyBpcyBhIFNUUkVBTUlORk8gYmxvY2ssIHJlYWQgdGhlIHRydWUgc2FtcGxlcmF0ZSBzaW5jZSB0aGlzCgkgICAgICAgIC8vIGNhbiBiZSBkaWZmZXJlbnQgdG8gdGhlIEF1ZGlvU2FtcGxlRW50cnkgc2FtcGxlcmF0ZS4KCSAgICAgICAgaWYgKCEodHlwZSkpIHsKCSAgICAgICAgICAgIC8vIHJlYWQgcGFzdCBhbGwgdGhlIG90aGVyIHN0dWZmCgkgICAgICAgICAgICBzdHJlYW0ucmVhZFVpbnQ4QXJyYXkoMTMpOwoKCSAgICAgICAgICAgIC8vIGV4dHJhY3Qgc2FtcGxlcmF0ZQoJICAgICAgICAgICAgdGhpcy5zYW1wbGVyYXRlID0gKHN0cmVhbS5yZWFkVWludDMyKCkgPj4gMTIpOwoKCSAgICAgICAgICAgIC8vIHJlYWQgdG8gZW5kIG9mIFNUUkVBTUlORk8KCSAgICAgICAgICAgIHN0cmVhbS5yZWFkVWludDhBcnJheSgyMCk7CgkgICAgICAgIH0gZWxzZSB7CgkgICAgICAgICAgICAvLyBub3QgaW50ZXJlc3RlZCBpbiBvdGhlciBibG9jayB0eXBlcyBzbyBqdXN0IGRpc2NhcmQgbGVuZ3RoIGJ5dGVzCgkgICAgICAgICAgICBzdHJlYW0ucmVhZFVpbnQ4QXJyYXkoc3RyZWFtLnJlYWRVaW50MjQoKSk7CgkgICAgICAgIH0KCgkgICAgICAgIGJveGVzRm91bmQucHVzaChrbm93bkJsb2NrVHlwZXNbdHlwZV0pOwoKCSAgICAgICAgaWYgKCEhKGZsYWdBbmRUeXBlICYgTEFTVE1FVEFEQVRBQkxPQ0tGTEFHX01BU0spKSB7CgkgICAgICAgICAgICBicmVhazsKCSAgICAgICAgfQoJICAgIH0gd2hpbGUgKHRydWUpOwoKCSAgICB0aGlzLm51bU1ldGFkYXRhQmxvY2tzID0KCSAgICAgICAgYm94ZXNGb3VuZC5sZW5ndGggKyAiICgiICsgYm94ZXNGb3VuZC5qb2luKCIsICIpICsgIikiOwoJfSk7CgkvLyBmaWxlOnNyYy9wYXJzaW5nL2RpbW0uanMKCUJveFBhcnNlci5jcmVhdGVCb3hDdG9yKCJkaW1tIiwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJdGhpcy5ieXRlc3NlbnQgPSBzdHJlYW0ucmVhZFVpbnQ2NCgpOwoJfSk7CgoJLy8gZmlsZTpzcmMvcGFyc2luZy9kbWF4LmpzCglCb3hQYXJzZXIuY3JlYXRlQm94Q3RvcigiZG1heCIsIGZ1bmN0aW9uKHN0cmVhbSkgewoJCXRoaXMudGltZSA9IHN0cmVhbS5yZWFkVWludDMyKCk7Cgl9KTsKCgkvLyBmaWxlOnNyYy9wYXJzaW5nL2RtZWQuanMKCUJveFBhcnNlci5jcmVhdGVCb3hDdG9yKCJkbWVkIiwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJdGhpcy5ieXRlc3NlbnQgPSBzdHJlYW0ucmVhZFVpbnQ2NCgpOwoJfSk7CgoJLy8gZmlsZTpzcmMvcGFyc2luZy9kT3BzLmpzCglCb3hQYXJzZXIuY3JlYXRlQm94Q3RvcigiZE9wcyIsIGZ1bmN0aW9uKHN0cmVhbSkgewoJCXRoaXMuVmVyc2lvbiA9IHN0cmVhbS5yZWFkVWludDgoKTsKCQl0aGlzLk91dHB1dENoYW5uZWxDb3VudCA9IHN0cmVhbS5yZWFkVWludDgoKTsKCQl0aGlzLlByZVNraXAgPSBzdHJlYW0ucmVhZFVpbnQxNigpOwoJCXRoaXMuSW5wdXRTYW1wbGVSYXRlID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQl0aGlzLk91dHB1dEdhaW4gPSBzdHJlYW0ucmVhZEludDE2KCk7CgkJdGhpcy5DaGFubmVsTWFwcGluZ0ZhbWlseSA9IHN0cmVhbS5yZWFkVWludDgoKTsKCQlpZiAodGhpcy5DaGFubmVsTWFwcGluZ0ZhbWlseSAhPT0gMCkgewoJCQl0aGlzLlN0cmVhbUNvdW50ID0gc3RyZWFtLnJlYWRVaW50OCgpOwoJCQl0aGlzLkNvdXBsZWRDb3VudCA9IHN0cmVhbS5yZWFkVWludDgoKTsKCQkJdGhpcy5DaGFubmVsTWFwcGluZyA9IFtdOwoJCQlmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuT3V0cHV0Q2hhbm5lbENvdW50OyBpKyspIHsKCQkJCXRoaXMuQ2hhbm5lbE1hcHBpbmdbaV0gPSBzdHJlYW0ucmVhZFVpbnQ4KCk7CgkJCX0KCQl9Cgl9KTsKCgkvLyBmaWxlOnNyYy9wYXJzaW5nL2RyZWYuanMKCUJveFBhcnNlci5jcmVhdGVGdWxsQm94Q3RvcigiZHJlZiIsIGZ1bmN0aW9uKHN0cmVhbSkgewoJCXZhciByZXQ7CgkJdmFyIGJveDsKCQl0aGlzLmVudHJpZXMgPSBbXTsKCQl2YXIgZW50cnlfY291bnQgPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCWZvciAodmFyIGkgPSAwOyBpIDwgZW50cnlfY291bnQ7IGkrKykgewoJCQlyZXQgPSBCb3hQYXJzZXIucGFyc2VPbmVCb3goc3RyZWFtLCBmYWxzZSwgdGhpcy5zaXplIC0gKHN0cmVhbS5nZXRQb3NpdGlvbigpIC0gdGhpcy5zdGFydCkpOwoJCQlpZiAocmV0LmNvZGUgPT09IEJveFBhcnNlci5PSykgewoJCQkJYm94ID0gcmV0LmJveDsKCQkJCXRoaXMuZW50cmllcy5wdXNoKGJveCk7CgkJCX0gZWxzZSB7CgkJCQlyZXR1cm47CgkJCX0KCQl9Cgl9KTsKCgkvLyBmaWxlOnNyYy9wYXJzaW5nL2RyZXAuanMKCUJveFBhcnNlci5jcmVhdGVCb3hDdG9yKCJkcmVwIiwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJdGhpcy5ieXRlc3NlbnQgPSBzdHJlYW0ucmVhZFVpbnQ2NCgpOwoJfSk7CgoJLy8gZmlsZTpzcmMvcGFyc2luZy9lbG5nLmpzCglCb3hQYXJzZXIuY3JlYXRlRnVsbEJveEN0b3IoImVsbmciLCBmdW5jdGlvbihzdHJlYW0pIHsKCQl0aGlzLmV4dGVuZGVkX2xhbmd1YWdlID0gc3RyZWFtLnJlYWRTdHJpbmcodGhpcy5zaXplLXRoaXMuaGRyX3NpemUpOwoJfSk7CgoJLy8gZmlsZTpzcmMvcGFyc2luZy9lbHN0LmpzCglCb3hQYXJzZXIuY3JlYXRlRnVsbEJveEN0b3IoImVsc3QiLCBmdW5jdGlvbihzdHJlYW0pIHsKCQl0aGlzLmVudHJpZXMgPSBbXTsKCQl2YXIgZW50cnlfY291bnQgPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCWZvciAodmFyIGkgPSAwOyBpIDwgZW50cnlfY291bnQ7IGkrKykgewoJCQl2YXIgZW50cnkgPSB7fTsKCQkJdGhpcy5lbnRyaWVzLnB1c2goZW50cnkpOwoJCQlpZiAodGhpcy52ZXJzaW9uID09PSAxKSB7CgkJCQllbnRyeS5zZWdtZW50X2R1cmF0aW9uID0gc3RyZWFtLnJlYWRVaW50NjQoKTsKCQkJCWVudHJ5Lm1lZGlhX3RpbWUgPSBzdHJlYW0ucmVhZEludDY0KCk7CgkJCX0gZWxzZSB7CgkJCQllbnRyeS5zZWdtZW50X2R1cmF0aW9uID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQkJCWVudHJ5Lm1lZGlhX3RpbWUgPSBzdHJlYW0ucmVhZEludDMyKCk7CgkJCX0KCQkJZW50cnkubWVkaWFfcmF0ZV9pbnRlZ2VyID0gc3RyZWFtLnJlYWRJbnQxNigpOwoJCQllbnRyeS5tZWRpYV9yYXRlX2ZyYWN0aW9uID0gc3RyZWFtLnJlYWRJbnQxNigpOwoJCX0KCX0pOwoKCS8vIGZpbGU6c3JjL3BhcnNpbmcvZW1zZy5qcwoJQm94UGFyc2VyLmNyZWF0ZUZ1bGxCb3hDdG9yKCJlbXNnIiwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJaWYgKHRoaXMudmVyc2lvbiA9PSAxKSB7CgkJCXRoaXMudGltZXNjYWxlIAkJCQkJPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCQl0aGlzLnByZXNlbnRhdGlvbl90aW1lIAkJCT0gc3RyZWFtLnJlYWRVaW50NjQoKTsKCQkJdGhpcy5ldmVudF9kdXJhdGlvbgkJCSAJPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCQl0aGlzLmlkIAkJCQkJCT0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQkJdGhpcy5zY2hlbWVfaWRfdXJpIAkJCQk9IHN0cmVhbS5yZWFkQ1N0cmluZygpOwoJCQl0aGlzLnZhbHVlIAkJCQkJCT0gc3RyZWFtLnJlYWRDU3RyaW5nKCk7CgkJfSBlbHNlIHsKCQkJdGhpcy5zY2hlbWVfaWRfdXJpIAkJCQk9IHN0cmVhbS5yZWFkQ1N0cmluZygpOwoJCQl0aGlzLnZhbHVlIAkJCQkJCT0gc3RyZWFtLnJlYWRDU3RyaW5nKCk7CgkJCXRoaXMudGltZXNjYWxlIAkJCQkJPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCQl0aGlzLnByZXNlbnRhdGlvbl90aW1lX2RlbHRhIAk9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJCXRoaXMuZXZlbnRfZHVyYXRpb24JCQkgCT0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQkJdGhpcy5pZCAJCQkJCQk9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJfQoJCXZhciBtZXNzYWdlX3NpemUgPSB0aGlzLnNpemUgLSB0aGlzLmhkcl9zaXplIC0gKDQqNCArICh0aGlzLnNjaGVtZV9pZF91cmkubGVuZ3RoKzEpICsgKHRoaXMudmFsdWUubGVuZ3RoKzEpKTsKCQlpZiAodGhpcy52ZXJzaW9uID09IDEpIHsKCQkJbWVzc2FnZV9zaXplIC09IDQ7CgkJfQoJCXRoaXMubWVzc2FnZV9kYXRhID0gc3RyZWFtLnJlYWRVaW50OEFycmF5KG1lc3NhZ2Vfc2l6ZSk7Cgl9KTsKCgkvLyBmaWxlOnNyYy9wYXJzaW5nL2VzZHMuanMKCUJveFBhcnNlci5jcmVhdGVGdWxsQm94Q3RvcigiZXNkcyIsIGZ1bmN0aW9uKHN0cmVhbSkgewoJCXZhciBlc2RfZGF0YSA9IHN0cmVhbS5yZWFkVWludDhBcnJheSh0aGlzLnNpemUtdGhpcy5oZHJfc2l6ZSk7CgkJaWYgKHR5cGVvZiBNUEVHNERlc2NyaXB0b3JQYXJzZXIgIT09ICJ1bmRlZmluZWQiKSB7CgkJCXZhciBlc2RfcGFyc2VyID0gbmV3IE1QRUc0RGVzY3JpcHRvclBhcnNlcigpOwoJCQl0aGlzLmVzZCA9IGVzZF9wYXJzZXIucGFyc2VPbmVEZXNjcmlwdG9yKG5ldyBEYXRhU3RyZWFtKGVzZF9kYXRhLmJ1ZmZlciwgMCwgRGF0YVN0cmVhbS5CSUdfRU5ESUFOKSk7CgkJfQoJfSk7CgoJLy8gZmlsZTpzcmMvcGFyc2luZy9maWVsLmpzCglCb3hQYXJzZXIuY3JlYXRlQm94Q3RvcigiZmllbCIsIGZ1bmN0aW9uKHN0cmVhbSkgewoJCXRoaXMuZmllbGRDb3VudCA9IHN0cmVhbS5yZWFkVWludDgoKTsKCQl0aGlzLmZpZWxkT3JkZXJpbmcgPSBzdHJlYW0ucmVhZFVpbnQ4KCk7Cgl9KTsKCgkvLyBmaWxlOnNyYy9wYXJzaW5nL2ZybWEuanMKCUJveFBhcnNlci5jcmVhdGVCb3hDdG9yKCJmcm1hIiwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJdGhpcy5kYXRhX2Zvcm1hdCA9IHN0cmVhbS5yZWFkU3RyaW5nKDQpOwoJfSk7CgoJLy8gZmlsZTpzcmMvcGFyc2luZy9mdHlwLmpzCglCb3hQYXJzZXIuY3JlYXRlQm94Q3RvcigiZnR5cCIsIGZ1bmN0aW9uKHN0cmVhbSkgewoJCXZhciB0b3BhcnNlID0gdGhpcy5zaXplIC0gdGhpcy5oZHJfc2l6ZTsKCQl0aGlzLm1ham9yX2JyYW5kID0gc3RyZWFtLnJlYWRTdHJpbmcoNCk7CgkJdGhpcy5taW5vcl92ZXJzaW9uID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQl0b3BhcnNlIC09IDg7CgkJdGhpcy5jb21wYXRpYmxlX2JyYW5kcyA9IFtdOwoJCXZhciBpID0gMDsKCQl3aGlsZSAodG9wYXJzZT49NCkgewoJCQl0aGlzLmNvbXBhdGlibGVfYnJhbmRzW2ldID0gc3RyZWFtLnJlYWRTdHJpbmcoNCk7CgkJCXRvcGFyc2UgLT0gNDsKCQkJaSsrOwoJCX0KCX0pOwoKCS8vIGZpbGU6c3JjL3BhcnNpbmcvaGRsci5qcwoJQm94UGFyc2VyLmNyZWF0ZUZ1bGxCb3hDdG9yKCJoZGxyIiwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJaWYgKHRoaXMudmVyc2lvbiA9PT0gMCkgewoJCQlzdHJlYW0ucmVhZFVpbnQzMigpOwoJCQl0aGlzLmhhbmRsZXIgPSBzdHJlYW0ucmVhZFN0cmluZyg0KTsKCQkJc3RyZWFtLnJlYWRVaW50MzJBcnJheSgzKTsKCQkJdGhpcy5uYW1lID0gc3RyZWFtLnJlYWRTdHJpbmcodGhpcy5zaXplLXRoaXMuaGRyX3NpemUtMjApOwoJCQlpZiAodGhpcy5uYW1lW3RoaXMubmFtZS5sZW5ndGgtMV09PT0nXDAnKSB7CgkJCQl0aGlzLm5hbWUgPSB0aGlzLm5hbWUuc2xpY2UoMCwtMSk7CgkJCX0KCQl9Cgl9KTsKCgkvLyBmaWxlOnNyYy9wYXJzaW5nL2h2Y0MuanMKCUJveFBhcnNlci5jcmVhdGVCb3hDdG9yKCJodmNDIiwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJdmFyIGksIGo7CgkJdmFyIGxlbmd0aDsKCQl2YXIgdG1wX2J5dGU7CgkJdGhpcy5jb25maWd1cmF0aW9uVmVyc2lvbiA9IHN0cmVhbS5yZWFkVWludDgoKTsKCQl0bXBfYnl0ZSA9IHN0cmVhbS5yZWFkVWludDgoKTsKCQl0aGlzLmdlbmVyYWxfcHJvZmlsZV9zcGFjZSA9IHRtcF9ieXRlID4+IDY7CgkJdGhpcy5nZW5lcmFsX3RpZXJfZmxhZyA9ICh0bXBfYnl0ZSAmIDB4MjApID4+IDU7CgkJdGhpcy5nZW5lcmFsX3Byb2ZpbGVfaWRjID0gKHRtcF9ieXRlICYgMHgxRik7CgkJdGhpcy5nZW5lcmFsX3Byb2ZpbGVfY29tcGF0aWJpbGl0eSA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJdGhpcy5nZW5lcmFsX2NvbnN0cmFpbnRfaW5kaWNhdG9yID0gc3RyZWFtLnJlYWRVaW50OEFycmF5KDYpOwoJCXRoaXMuZ2VuZXJhbF9sZXZlbF9pZGMgPSBzdHJlYW0ucmVhZFVpbnQ4KCk7CgkJdGhpcy5taW5fc3BhdGlhbF9zZWdtZW50YXRpb25faWRjID0gc3RyZWFtLnJlYWRVaW50MTYoKSAmIDB4RkZGOwoJCXRoaXMucGFyYWxsZWxpc21UeXBlID0gKHN0cmVhbS5yZWFkVWludDgoKSAmIDB4Myk7CgkJdGhpcy5jaHJvbWFfZm9ybWF0X2lkYyA9IChzdHJlYW0ucmVhZFVpbnQ4KCkgJiAweDMpOwoJCXRoaXMuYml0X2RlcHRoX2x1bWFfbWludXM4ID0gKHN0cmVhbS5yZWFkVWludDgoKSAmIDB4Nyk7CgkJdGhpcy5iaXRfZGVwdGhfY2hyb21hX21pbnVzOCA9IChzdHJlYW0ucmVhZFVpbnQ4KCkgJiAweDcpOwoJCXRoaXMuYXZnRnJhbWVSYXRlID0gc3RyZWFtLnJlYWRVaW50MTYoKTsKCQl0bXBfYnl0ZSA9IHN0cmVhbS5yZWFkVWludDgoKTsKCQl0aGlzLmNvbnN0YW50RnJhbWVSYXRlID0gKHRtcF9ieXRlID4+IDYpOwoJCXRoaXMubnVtVGVtcG9yYWxMYXllcnMgPSAodG1wX2J5dGUgJiAwWEQpID4+IDM7CgkJdGhpcy50ZW1wb3JhbElkTmVzdGVkID0gKHRtcF9ieXRlICYgMFg0KSA+PiAyOwoJCXRoaXMubGVuZ3RoU2l6ZU1pbnVzT25lID0gKHRtcF9ieXRlICYgMFgzKTsKCgkJdGhpcy5uYWx1X2FycmF5cyA9IFtdOwoJCXZhciBudW1PZkFycmF5cyA9IHN0cmVhbS5yZWFkVWludDgoKTsKCQlmb3IgKGkgPSAwOyBpIDwgbnVtT2ZBcnJheXM7IGkrKykgewoJCQl2YXIgbmFsdV9hcnJheSA9IFtdOwoJCQl0aGlzLm5hbHVfYXJyYXlzLnB1c2gobmFsdV9hcnJheSk7CgkJCXRtcF9ieXRlID0gc3RyZWFtLnJlYWRVaW50OCgpOwoJCQluYWx1X2FycmF5LmNvbXBsZXRlbmVzcyA9ICh0bXBfYnl0ZSAmIDB4ODApID4+IDc7CgkJCW5hbHVfYXJyYXkubmFsdV90eXBlID0gdG1wX2J5dGUgJiAweDNGOwoJCQl2YXIgbnVtTmFsdXMgPSBzdHJlYW0ucmVhZFVpbnQxNigpOwoJCQlmb3IgKGogPSAwOyBqIDwgbnVtTmFsdXM7IGorKykgewoJCQkJdmFyIG5hbHUgPSB7fTsKCQkJCW5hbHVfYXJyYXkucHVzaChuYWx1KTsKCQkJCWxlbmd0aCA9IHN0cmVhbS5yZWFkVWludDE2KCk7CgkJCQluYWx1LmRhdGEgICA9IHN0cmVhbS5yZWFkVWludDhBcnJheShsZW5ndGgpOwoJCQl9CgkJfQoJfSk7CgoJLy8gZmlsZTpzcmMvcGFyc2luZy9paW5mLmpzCglCb3hQYXJzZXIuY3JlYXRlRnVsbEJveEN0b3IoImlpbmYiLCBmdW5jdGlvbihzdHJlYW0pIHsKCQl2YXIgcmV0OwoJCWlmICh0aGlzLnZlcnNpb24gPT09IDApIHsKCQkJdGhpcy5lbnRyeV9jb3VudCA9IHN0cmVhbS5yZWFkVWludDE2KCk7CgkJfSBlbHNlIHsKCQkJdGhpcy5lbnRyeV9jb3VudCA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJfQoJCXRoaXMuaXRlbV9pbmZvcyA9IFtdOwoJCWZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5lbnRyeV9jb3VudDsgaSsrKSB7CgkJCXJldCA9IEJveFBhcnNlci5wYXJzZU9uZUJveChzdHJlYW0sIGZhbHNlLCB0aGlzLnNpemUgLSAoc3RyZWFtLmdldFBvc2l0aW9uKCkgLSB0aGlzLnN0YXJ0KSk7CgkJCWlmIChyZXQuY29kZSA9PT0gQm94UGFyc2VyLk9LKSB7CgkJCQlpZiAocmV0LmJveC50eXBlICE9PSAiaW5mZSIpIHsKCQkJCQlMb2cuZXJyb3IoIkJveFBhcnNlciIsICJFeHBlY3RlZCAnaW5mZScgYm94LCBnb3QgIityZXQuYm94LnR5cGUpOwoJCQkJfQoJCQkJdGhpcy5pdGVtX2luZm9zW2ldID0gcmV0LmJveDsKCQkJfSBlbHNlIHsKCQkJCXJldHVybjsKCQkJfQoJCX0KCX0pOwoKCS8vIGZpbGU6c3JjL3BhcnNpbmcvaWxvYy5qcwoJQm94UGFyc2VyLmNyZWF0ZUZ1bGxCb3hDdG9yKCJpbG9jIiwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJdmFyIGJ5dGU7CgkJYnl0ZSA9IHN0cmVhbS5yZWFkVWludDgoKTsKCQl0aGlzLm9mZnNldF9zaXplID0gKGJ5dGUgPj4gNCkgJiAweEY7CgkJdGhpcy5sZW5ndGhfc2l6ZSA9IGJ5dGUgJiAweEY7CgkJYnl0ZSA9IHN0cmVhbS5yZWFkVWludDgoKTsKCQl0aGlzLmJhc2Vfb2Zmc2V0X3NpemUgPSAoYnl0ZSA+PiA0KSAmIDB4RjsKCQlpZiAodGhpcy52ZXJzaW9uID09PSAxIHx8IHRoaXMudmVyc2lvbiA9PT0gMikgewoJCQl0aGlzLmluZGV4X3NpemUgPSBieXRlICYgMHhGOwoJCX0gZWxzZSB7CgkJCXRoaXMuaW5kZXhfc2l6ZSA9IDA7CgkJCS8vIHJlc2VydmVkID0gYnl0ZSAmIDB4RjsKCQl9CgkJdGhpcy5pdGVtcyA9IFtdOwoJCXZhciBpdGVtX2NvdW50ID0gMDsKCQlpZiAodGhpcy52ZXJzaW9uIDwgMikgewoJCQlpdGVtX2NvdW50ID0gc3RyZWFtLnJlYWRVaW50MTYoKTsKCQl9IGVsc2UgaWYgKHRoaXMudmVyc2lvbiA9PT0gMikgewoJCQlpdGVtX2NvdW50ID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQl9IGVsc2UgewoJCQl0aHJvdyAidmVyc2lvbiBvZiBpbG9jIGJveCBub3Qgc3VwcG9ydGVkIjsKCQl9CgkJZm9yICh2YXIgaSA9IDA7IGkgPCBpdGVtX2NvdW50OyBpKyspIHsKCQkJdmFyIGl0ZW0gPSB7fTsKCQkJdGhpcy5pdGVtcy5wdXNoKGl0ZW0pOwoJCQlpZiAodGhpcy52ZXJzaW9uIDwgMikgewoJCQkJaXRlbS5pdGVtX0lEID0gc3RyZWFtLnJlYWRVaW50MTYoKTsKCQkJfSBlbHNlIGlmICh0aGlzLnZlcnNpb24gPT09IDIpIHsKCQkJCWl0ZW0uaXRlbV9JRCA9IHN0cmVhbS5yZWFkVWludDE2KCk7CgkJCX0gZWxzZSB7CgkJCQl0aHJvdyAidmVyc2lvbiBvZiBpbG9jIGJveCBub3Qgc3VwcG9ydGVkIjsKCQkJfQoJCQlpZiAodGhpcy52ZXJzaW9uID09PSAxIHx8IHRoaXMudmVyc2lvbiA9PT0gMikgewoJCQkJaXRlbS5jb25zdHJ1Y3Rpb25fbWV0aG9kID0gKHN0cmVhbS5yZWFkVWludDE2KCkgJiAweEYpOwoJCQl9IGVsc2UgewoJCQkJaXRlbS5jb25zdHJ1Y3Rpb25fbWV0aG9kID0gMDsKCQkJfQoJCQlpdGVtLmRhdGFfcmVmZXJlbmNlX2luZGV4ID0gc3RyZWFtLnJlYWRVaW50MTYoKTsKCQkJc3dpdGNoKHRoaXMuYmFzZV9vZmZzZXRfc2l6ZSkgewoJCQkJY2FzZSAwOgoJCQkJCWl0ZW0uYmFzZV9vZmZzZXQgPSAwOwoJCQkJCWJyZWFrOwoJCQkJY2FzZSA0OgoJCQkJCWl0ZW0uYmFzZV9vZmZzZXQgPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCQkJCWJyZWFrOwoJCQkJY2FzZSA4OgoJCQkJCWl0ZW0uYmFzZV9vZmZzZXQgPSBzdHJlYW0ucmVhZFVpbnQ2NCgpOwoJCQkJCWJyZWFrOwoJCQkJZGVmYXVsdDoKCQkJCQl0aHJvdyAiRXJyb3IgcmVhZGluZyBiYXNlIG9mZnNldCBzaXplIjsKCQkJfQoJCQl2YXIgZXh0ZW50X2NvdW50ID0gc3RyZWFtLnJlYWRVaW50MTYoKTsKCQkJaXRlbS5leHRlbnRzID0gW107CgkJCWZvciAodmFyIGo9MDsgaiA8IGV4dGVudF9jb3VudDsgaisrKSB7CgkJCQl2YXIgZXh0ZW50ID0ge307CgkJCQlpdGVtLmV4dGVudHMucHVzaChleHRlbnQpOwoJCQkJaWYgKHRoaXMudmVyc2lvbiA9PT0gMSB8fCB0aGlzLnZlcnNpb24gPT09IDIpIHsKCQkJCQlzd2l0Y2godGhpcy5pbmRleF9zaXplKSB7CgkJCQkJCWNhc2UgMDoKCQkJCQkJCWV4dGVudC5leHRlbnRfaW5kZXggPSAwOwoJCQkJCQkJYnJlYWs7CgkJCQkJCWNhc2UgNDoKCQkJCQkJCWV4dGVudC5leHRlbnRfaW5kZXggPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCQkJCQkJYnJlYWs7CgkJCQkJCWNhc2UgODoKCQkJCQkJCWV4dGVudC5leHRlbnRfaW5kZXggPSBzdHJlYW0ucmVhZFVpbnQ2NCgpOwoJCQkJCQkJYnJlYWs7CgkJCQkJCWRlZmF1bHQ6CgkJCQkJCQl0aHJvdyAiRXJyb3IgcmVhZGluZyBleHRlbnQgaW5kZXgiOwoJCQkJCX0KCQkJCX0KCQkJCXN3aXRjaCh0aGlzLm9mZnNldF9zaXplKSB7CgkJCQkJY2FzZSAwOgoJCQkJCQlleHRlbnQuZXh0ZW50X29mZnNldCA9IDA7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgNDoKCQkJCQkJZXh0ZW50LmV4dGVudF9vZmZzZXQgPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCQkJCQlicmVhazsKCQkJCQljYXNlIDg6CgkJCQkJCWV4dGVudC5leHRlbnRfb2Zmc2V0ID0gc3RyZWFtLnJlYWRVaW50NjQoKTsKCQkJCQkJYnJlYWs7CgkJCQkJZGVmYXVsdDoKCQkJCQkJdGhyb3cgIkVycm9yIHJlYWRpbmcgZXh0ZW50IGluZGV4IjsKCQkJCX0KCQkJCXN3aXRjaCh0aGlzLmxlbmd0aF9zaXplKSB7CgkJCQkJY2FzZSAwOgoJCQkJCQlleHRlbnQuZXh0ZW50X2xlbmd0aCA9IDA7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgNDoKCQkJCQkJZXh0ZW50LmV4dGVudF9sZW5ndGggPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCQkJCQlicmVhazsKCQkJCQljYXNlIDg6CgkJCQkJCWV4dGVudC5leHRlbnRfbGVuZ3RoID0gc3RyZWFtLnJlYWRVaW50NjQoKTsKCQkJCQkJYnJlYWs7CgkJCQkJZGVmYXVsdDoKCQkJCQkJdGhyb3cgIkVycm9yIHJlYWRpbmcgZXh0ZW50IGluZGV4IjsKCQkJCX0KCQkJfQoJCX0KCX0pOwoKCS8vIGZpbGU6c3JjL3BhcnNpbmcvaW1pci5qcwoJQm94UGFyc2VyLmNyZWF0ZUJveEN0b3IoImltaXIiLCBmdW5jdGlvbihzdHJlYW0pIHsKCQl2YXIgdG1wID0gc3RyZWFtLnJlYWRVaW50OCgpOwoJCXRoaXMucmVzZXJ2ZWQgPSB0bXAgPj4gNzsKCQl0aGlzLmF4aXMgPSB0bXAgJiAxOwoJfSk7Ly8gZmlsZTpzcmMvcGFyc2luZy9pbmZlLmpzCglCb3hQYXJzZXIuY3JlYXRlRnVsbEJveEN0b3IoImluZmUiLCBmdW5jdGlvbihzdHJlYW0pIHsKCQlpZiAodGhpcy52ZXJzaW9uID09PSAwIHx8IHRoaXMudmVyc2lvbiA9PT0gMSkgewoJCQl0aGlzLml0ZW1fSUQgPSBzdHJlYW0ucmVhZFVpbnQxNigpOwoJCQl0aGlzLml0ZW1fcHJvdGVjdGlvbl9pbmRleCA9IHN0cmVhbS5yZWFkVWludDE2KCk7CgkJCXRoaXMuaXRlbV9uYW1lID0gc3RyZWFtLnJlYWRDU3RyaW5nKCk7CgkJCXRoaXMuY29udGVudF90eXBlID0gc3RyZWFtLnJlYWRDU3RyaW5nKCk7CgkJCXRoaXMuY29udGVudF9lbmNvZGluZyA9IHN0cmVhbS5yZWFkQ1N0cmluZygpOwoJCX0KCQlpZiAodGhpcy52ZXJzaW9uID09PSAxKSB7CgkJCXRoaXMuZXh0ZW5zaW9uX3R5cGUgPSBzdHJlYW0ucmVhZFN0cmluZyg0KTsKCQkJTG9nLndhcm4oIkJveFBhcnNlciIsICJDYW5ub3QgcGFyc2UgZXh0ZW5zaW9uIHR5cGUiKTsKCQkJc3RyZWFtLnNlZWsodGhpcy5zdGFydCt0aGlzLnNpemUpOwoJCQlyZXR1cm47CgkJfQoJCWlmICh0aGlzLnZlcnNpb24gPj0gMikgewoJCQlpZiAodGhpcy52ZXJzaW9uID09PSAyKSB7CgkJCQl0aGlzLml0ZW1fSUQgPSBzdHJlYW0ucmVhZFVpbnQxNigpOwoJCQl9IGVsc2UgaWYgKHRoaXMudmVyc2lvbiA9PT0gMykgewoJCQkJdGhpcy5pdGVtX0lEID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQkJfQoJCQl0aGlzLml0ZW1fcHJvdGVjdGlvbl9pbmRleCA9IHN0cmVhbS5yZWFkVWludDE2KCk7CgkJCXRoaXMuaXRlbV90eXBlID0gc3RyZWFtLnJlYWRTdHJpbmcoNCk7CgkJCXRoaXMuaXRlbV9uYW1lID0gc3RyZWFtLnJlYWRDU3RyaW5nKCk7CgkJCWlmICh0aGlzLml0ZW1fdHlwZSA9PT0gIm1pbWUiKSB7CgkJCQl0aGlzLmNvbnRlbnRfdHlwZSA9IHN0cmVhbS5yZWFkQ1N0cmluZygpOwoJCQkJdGhpcy5jb250ZW50X2VuY29kaW5nID0gc3RyZWFtLnJlYWRDU3RyaW5nKCk7CgkJCX0gZWxzZSBpZiAodGhpcy5pdGVtX3R5cGUgPT09ICJ1cmkgIikgewoJCQkJdGhpcy5pdGVtX3VyaV90eXBlID0gc3RyZWFtLnJlYWRDU3RyaW5nKCk7CgkJCX0KCQl9Cgl9KTsKCS8vIGZpbGU6c3JjL3BhcnNpbmcvaXBtYS5qcwoJQm94UGFyc2VyLmNyZWF0ZUZ1bGxCb3hDdG9yKCJpcG1hIiwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJdmFyIGksIGo7CgkJZW50cnlfY291bnQgPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCXRoaXMuYXNzb2NpYXRpb25zID0gW107CgkJZm9yKGk9MDsgaTxlbnRyeV9jb3VudDsgaSsrKSB7CgkJCXZhciBpdGVtX2Fzc29jID0ge307CgkJCXRoaXMuYXNzb2NpYXRpb25zLnB1c2goaXRlbV9hc3NvYyk7CgkJCWlmICh0aGlzLnZlcnNpb24gPCAxKSB7CgkJCQlpdGVtX2Fzc29jLmlkID0gc3RyZWFtLnJlYWRVaW50MTYoKTsKCQkJfSBlbHNlIHsKCQkJCWl0ZW1fYXNzb2MuaWQgPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCQl9CgkJCXZhciBhc3NvY2lhdGlvbl9jb3VudCA9IHN0cmVhbS5yZWFkVWludDgoKTsKCQkJaXRlbV9hc3NvYy5wcm9wcyA9IFtdOwoJCQlmb3IgKGogPSAwOyBqIDwgYXNzb2NpYXRpb25fY291bnQ7IGorKykgewoJCQkJdmFyIHRtcCA9IHN0cmVhbS5yZWFkVWludDgoKTsKCQkJCXZhciBwID0ge307CgkJCQlpdGVtX2Fzc29jLnByb3BzLnB1c2gocCk7CgkJCQlwLmVzc2VudGlhbCA9ICgodG1wICYgMHg4MCkgPj4gNykgPT09IDE7CgkJCQlpZiAodGhpcy5mbGFncyAmIDB4MSkgewoJCQkJCXAucHJvcGVydHlfaW5kZXggPSAodG1wICYgMHg3RikgPDwgOCB8IHN0cmVhbS5yZWFkVWludDgoKTsKCQkJCX0gZWxzZSB7CgkJCQkJcC5wcm9wZXJ0eV9pbmRleCA9ICh0bXAgJiAweDdGKTsKCQkJCX0KCQkJfQoJCX0KCX0pOwoKCS8vIGZpbGU6c3JjL3BhcnNpbmcvaXJlZi5qcwoJQm94UGFyc2VyLmNyZWF0ZUZ1bGxCb3hDdG9yKCJpcmVmIiwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJdmFyIHJldDsKCQl2YXIgYm94OwoJCXRoaXMucmVmZXJlbmNlcyA9IFtdOwoKCQl3aGlsZSAoc3RyZWFtLmdldFBvc2l0aW9uKCkgPCB0aGlzLnN0YXJ0K3RoaXMuc2l6ZSkgewoJCQlyZXQgPSBCb3hQYXJzZXIucGFyc2VPbmVCb3goc3RyZWFtLCB0cnVlLCB0aGlzLnNpemUgLSAoc3RyZWFtLmdldFBvc2l0aW9uKCkgLSB0aGlzLnN0YXJ0KSk7CgkJCWlmIChyZXQuY29kZSA9PT0gQm94UGFyc2VyLk9LKSB7CgkJCQlpZiAodGhpcy52ZXJzaW9uID09PSAwKSB7CgkJCQkJYm94ID0gbmV3IEJveFBhcnNlci5TaW5nbGVJdGVtVHlwZVJlZmVyZW5jZUJveChyZXQudHlwZSwgcmV0LnNpemUsIHJldC5oZHJfc2l6ZSwgcmV0LnN0YXJ0KTsKCQkJCX0gZWxzZSB7CgkJCQkJYm94ID0gbmV3IEJveFBhcnNlci5TaW5nbGVJdGVtVHlwZVJlZmVyZW5jZUJveExhcmdlKHJldC50eXBlLCByZXQuc2l6ZSwgcmV0Lmhkcl9zaXplLCByZXQuc3RhcnQpOwoJCQkJfQoJCQkJaWYgKGJveC53cml0ZSA9PT0gQm94UGFyc2VyLkJveC5wcm90b3R5cGUud3JpdGUgJiYgYm94LnR5cGUgIT09ICJtZGF0IikgewoJCQkJCUxvZy53YXJuKCJCb3hQYXJzZXIiLCBib3gudHlwZSsiIGJveCB3cml0aW5nIG5vdCB5ZXQgaW1wbGVtZW50ZWQsIGtlZXBpbmcgdW5wYXJzZWQgZGF0YSBpbiBtZW1vcnkgZm9yIGxhdGVyIHdyaXRlIik7CgkJCQkJYm94LnBhcnNlRGF0YUFuZFJld2luZChzdHJlYW0pOwoJCQkJfQoJCQkJYm94LnBhcnNlKHN0cmVhbSk7CgkJCQl0aGlzLnJlZmVyZW5jZXMucHVzaChib3gpOwoJCQl9IGVsc2UgewoJCQkJcmV0dXJuOwoJCQl9CgkJfQoJfSk7CgkvLyBmaWxlOnNyYy9wYXJzaW5nL2lyb3QuanMKCUJveFBhcnNlci5jcmVhdGVCb3hDdG9yKCJpcm90IiwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJdGhpcy5hbmdsZSA9IHN0cmVhbS5yZWFkVWludDgoKSAmIDB4MzsKCX0pOwoKCS8vIGZpbGU6c3JjL3BhcnNpbmcvaXNwZS5qcwoJQm94UGFyc2VyLmNyZWF0ZUZ1bGxCb3hDdG9yKCJpc3BlIiwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJdGhpcy5pbWFnZV93aWR0aCA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJdGhpcy5pbWFnZV9oZWlnaHQgPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJfSk7Ly8gZmlsZTpzcmMvcGFyc2luZy9raW5kLmpzCglCb3hQYXJzZXIuY3JlYXRlRnVsbEJveEN0b3IoImtpbmQiLCBmdW5jdGlvbihzdHJlYW0pIHsKCQl0aGlzLnNjaGVtZVVSSSA9IHN0cmVhbS5yZWFkQ1N0cmluZygpOwoJCXRoaXMudmFsdWUgPSBzdHJlYW0ucmVhZENTdHJpbmcoKTsKCX0pOwoJLy8gZmlsZTpzcmMvcGFyc2luZy9sZXZhLmpzCglCb3hQYXJzZXIuY3JlYXRlRnVsbEJveEN0b3IoImxldmEiLCBmdW5jdGlvbihzdHJlYW0pIHsKCQl2YXIgY291bnQgPSBzdHJlYW0ucmVhZFVpbnQ4KCk7CgkJdGhpcy5sZXZlbHMgPSBbXTsKCQlmb3IgKHZhciBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKCQkJdmFyIGxldmVsID0ge307CgkJCXRoaXMubGV2ZWxzW2ldID0gbGV2ZWw7CgkJCWxldmVsLnRyYWNrX0lEID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQkJdmFyIHRtcF9ieXRlID0gc3RyZWFtLnJlYWRVaW50OCgpOwoJCQlsZXZlbC5wYWRkaW5nX2ZsYWcgPSB0bXBfYnl0ZSA+PiA3OwoJCQlsZXZlbC5hc3NpZ25tZW50X3R5cGUgPSB0bXBfYnl0ZSAmIDB4N0Y7CgkJCXN3aXRjaCAobGV2ZWwuYXNzaWdubWVudF90eXBlKSB7CgkJCQljYXNlIDA6CgkJCQkJbGV2ZWwuZ3JvdXBpbmdfdHlwZSA9IHN0cmVhbS5yZWFkU3RyaW5nKDQpOwoJCQkJCWJyZWFrOwoJCQkJY2FzZSAxOgoJCQkJCWxldmVsLmdyb3VwaW5nX3R5cGUgPSBzdHJlYW0ucmVhZFN0cmluZyg0KTsKCQkJCQlsZXZlbC5ncm91cGluZ190eXBlX3BhcmFtZXRlciA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJCQkJYnJlYWs7CgkJCQljYXNlIDI6CgkJCQkJYnJlYWs7CgkJCQljYXNlIDM6CgkJCQkJYnJlYWs7CgkJCQljYXNlIDQ6CgkJCQkJbGV2ZWwuc3ViX3RyYWNrX2lkID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQkJCQlicmVhazsKCQkJCWRlZmF1bHQ6CgkJCQkJTG9nLndhcm4oIkJveFBhcnNlciIsICJVbmtub3duIGxldmEgYXNzaWduZW1lbnQgdHlwZSIpOwoJCQl9CgkJfQoJfSk7CgoJLy8gZmlsZTpzcmMvcGFyc2luZy9sc2VsLmpzCglCb3hQYXJzZXIuY3JlYXRlQm94Q3RvcigibHNlbCIsIGZ1bmN0aW9uKHN0cmVhbSkgewoJCXRoaXMubGF5ZXJfaWQgPSBzdHJlYW0ucmVhZFVpbnQxNigpOwoJfSk7Ly8gZmlsZTpzcmMvcGFyc2luZy9tYXhyLmpzCglCb3hQYXJzZXIuY3JlYXRlQm94Q3RvcigibWF4ciIsIGZ1bmN0aW9uKHN0cmVhbSkgewoJCXRoaXMucGVyaW9kID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQl0aGlzLmJ5dGVzID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCX0pOwoKCS8vIGZpbGU6c3JjL3BhcnNpbmcvbWRjdi5qcwoJQm94UGFyc2VyLmNyZWF0ZUJveEN0b3IoIm1kY3YiLCBmdW5jdGlvbihzdHJlYW0pIHsKCSAgICB0aGlzLmRpc3BsYXlfcHJpbWFyaWVzID0gW107CgkgICAgdGhpcy5kaXNwbGF5X3ByaW1hcmllc1swXSA9IHt9OwoJICAgIHRoaXMuZGlzcGxheV9wcmltYXJpZXNbMF0ueCA9IHN0cmVhbS5yZWFkVWludDE2KCk7CgkgICAgdGhpcy5kaXNwbGF5X3ByaW1hcmllc1swXS55ID0gc3RyZWFtLnJlYWRVaW50MTYoKTsKCSAgICB0aGlzLmRpc3BsYXlfcHJpbWFyaWVzWzFdID0ge307CgkgICAgdGhpcy5kaXNwbGF5X3ByaW1hcmllc1sxXS54ID0gc3RyZWFtLnJlYWRVaW50MTYoKTsKCSAgICB0aGlzLmRpc3BsYXlfcHJpbWFyaWVzWzFdLnkgPSBzdHJlYW0ucmVhZFVpbnQxNigpOwoJICAgIHRoaXMuZGlzcGxheV9wcmltYXJpZXNbMl0gPSB7fTsKCSAgICB0aGlzLmRpc3BsYXlfcHJpbWFyaWVzWzJdLnggPSBzdHJlYW0ucmVhZFVpbnQxNigpOwoJICAgIHRoaXMuZGlzcGxheV9wcmltYXJpZXNbMl0ueSA9IHN0cmVhbS5yZWFkVWludDE2KCk7CgkgICAgdGhpcy53aGl0ZV9wb2ludCA9IHt9OwoJICAgIHRoaXMud2hpdGVfcG9pbnQueCA9IHN0cmVhbS5yZWFkVWludDE2KCk7CgkgICAgdGhpcy53aGl0ZV9wb2ludC55ID0gc3RyZWFtLnJlYWRVaW50MTYoKTsKCSAgICB0aGlzLm1heF9kaXNwbGF5X21hc3RlcmluZ19sdW1pbmFuY2UgPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJICAgIHRoaXMubWluX2Rpc3BsYXlfbWFzdGVyaW5nX2x1bWluYW5jZSA9IHN0cmVhbS5yZWFkVWludDMyKCk7Cgl9KTsKCgkvLyBmaWxlOnNyYy9wYXJzaW5nL21kaGQuanMKCUJveFBhcnNlci5jcmVhdGVGdWxsQm94Q3RvcigibWRoZCIsIGZ1bmN0aW9uKHN0cmVhbSkgewoJCWlmICh0aGlzLnZlcnNpb24gPT0gMSkgewoJCQl0aGlzLmNyZWF0aW9uX3RpbWUgPSBzdHJlYW0ucmVhZFVpbnQ2NCgpOwoJCQl0aGlzLm1vZGlmaWNhdGlvbl90aW1lID0gc3RyZWFtLnJlYWRVaW50NjQoKTsKCQkJdGhpcy50aW1lc2NhbGUgPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCQl0aGlzLmR1cmF0aW9uID0gc3RyZWFtLnJlYWRVaW50NjQoKTsKCQl9IGVsc2UgewoJCQl0aGlzLmNyZWF0aW9uX3RpbWUgPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCQl0aGlzLm1vZGlmaWNhdGlvbl90aW1lID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQkJdGhpcy50aW1lc2NhbGUgPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCQl0aGlzLmR1cmF0aW9uID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQl9CgkJdGhpcy5wYXJzZUxhbmd1YWdlKHN0cmVhbSk7CgkJc3RyZWFtLnJlYWRVaW50MTYoKTsKCX0pOwoKCS8vIGZpbGU6c3JjL3BhcnNpbmcvbWVoZC5qcwoJQm94UGFyc2VyLmNyZWF0ZUZ1bGxCb3hDdG9yKCJtZWhkIiwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJaWYgKHRoaXMuZmxhZ3MgJiAweDEpIHsKCQkJTG9nLndhcm4oIkJveFBhcnNlciIsICJtZWhkIGJveCBpbmNvcnJlY3RseSB1c2VzIGZsYWdzIHNldCB0byAxLCBjb252ZXJ0aW5nIHZlcnNpb24gdG8gMSIpOwoJCQl0aGlzLnZlcnNpb24gPSAxOwoJCX0KCQlpZiAodGhpcy52ZXJzaW9uID09IDEpIHsKCQkJdGhpcy5mcmFnbWVudF9kdXJhdGlvbiA9IHN0cmVhbS5yZWFkVWludDY0KCk7CgkJfSBlbHNlIHsKCQkJdGhpcy5mcmFnbWVudF9kdXJhdGlvbiA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJfQoJfSk7CgoJLy8gZmlsZTpzcmMvcGFyc2luZy9tZXRhLmpzCglCb3hQYXJzZXIuY3JlYXRlRnVsbEJveEN0b3IoIm1ldGEiLCBmdW5jdGlvbihzdHJlYW0pIHsKCQl0aGlzLmJveGVzID0gW107CgkJQm94UGFyc2VyLkNvbnRhaW5lckJveC5wcm90b3R5cGUucGFyc2UuY2FsbCh0aGlzLCBzdHJlYW0pOwoJfSk7CgkvLyBmaWxlOnNyYy9wYXJzaW5nL21maGQuanMKCUJveFBhcnNlci5jcmVhdGVGdWxsQm94Q3RvcigibWZoZCIsIGZ1bmN0aW9uKHN0cmVhbSkgewoJCXRoaXMuc2VxdWVuY2VfbnVtYmVyID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCX0pOwoKCS8vIGZpbGU6c3JjL3BhcnNpbmcvbWZyby5qcwoJQm94UGFyc2VyLmNyZWF0ZUZ1bGxCb3hDdG9yKCJtZnJvIiwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJdGhpcy5fc2l6ZSA9IHN0cmVhbS5yZWFkVWludDMyKCk7Cgl9KTsKCgkvLyBmaWxlOnNyYy9wYXJzaW5nL212aGQuanMKCUJveFBhcnNlci5jcmVhdGVGdWxsQm94Q3RvcigibXZoZCIsIGZ1bmN0aW9uKHN0cmVhbSkgewoJCWlmICh0aGlzLnZlcnNpb24gPT0gMSkgewoJCQl0aGlzLmNyZWF0aW9uX3RpbWUgPSBzdHJlYW0ucmVhZFVpbnQ2NCgpOwoJCQl0aGlzLm1vZGlmaWNhdGlvbl90aW1lID0gc3RyZWFtLnJlYWRVaW50NjQoKTsKCQkJdGhpcy50aW1lc2NhbGUgPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCQl0aGlzLmR1cmF0aW9uID0gc3RyZWFtLnJlYWRVaW50NjQoKTsKCQl9IGVsc2UgewoJCQl0aGlzLmNyZWF0aW9uX3RpbWUgPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCQl0aGlzLm1vZGlmaWNhdGlvbl90aW1lID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQkJdGhpcy50aW1lc2NhbGUgPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCQl0aGlzLmR1cmF0aW9uID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQl9CgkJdGhpcy5yYXRlID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQl0aGlzLnZvbHVtZSA9IHN0cmVhbS5yZWFkVWludDE2KCk+Pjg7CgkJc3RyZWFtLnJlYWRVaW50MTYoKTsKCQlzdHJlYW0ucmVhZFVpbnQzMkFycmF5KDIpOwoJCXRoaXMubWF0cml4ID0gc3RyZWFtLnJlYWRVaW50MzJBcnJheSg5KTsKCQlzdHJlYW0ucmVhZFVpbnQzMkFycmF5KDYpOwoJCXRoaXMubmV4dF90cmFja19pZCA9IHN0cmVhbS5yZWFkVWludDMyKCk7Cgl9KTsKCS8vIGZpbGU6c3JjL3BhcnNpbmcvbnBjay5qcwoJQm94UGFyc2VyLmNyZWF0ZUJveEN0b3IoIm5wY2siLCBmdW5jdGlvbihzdHJlYW0pIHsKCQl0aGlzLnBhY2tldHNzZW50ID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCX0pOwoKCS8vIGZpbGU6c3JjL3BhcnNpbmcvbnVtcC5qcwoJQm94UGFyc2VyLmNyZWF0ZUJveEN0b3IoIm51bXAiLCBmdW5jdGlvbihzdHJlYW0pIHsKCQl0aGlzLnBhY2tldHNzZW50ID0gc3RyZWFtLnJlYWRVaW50NjQoKTsKCX0pOwoKCS8vIGZpbGU6c3JjL3BhcnNpbmcvcGFkYi5qcwoJQm94UGFyc2VyLmNyZWF0ZUZ1bGxCb3hDdG9yKCJwYWRiIiwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJdmFyIHNhbXBsZV9jb3VudCA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJdGhpcy5wYWRiaXRzID0gW107CgkJZm9yICh2YXIgaSA9IDA7IGkgPCBNYXRoLmZsb29yKChzYW1wbGVfY291bnQrMSkvMik7IGkrKykgewoJCQl0aGlzLnBhZGJpdHMgPSBzdHJlYW0ucmVhZFVpbnQ4KCk7CgkJfQoJfSk7CgoJLy8gZmlsZTpzcmMvcGFyc2luZy9wYXNwLmpzCglCb3hQYXJzZXIuY3JlYXRlQm94Q3RvcigicGFzcCIsIGZ1bmN0aW9uKHN0cmVhbSkgewoJCXRoaXMuaFNwYWNpbmcgPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCXRoaXMudlNwYWNpbmcgPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJfSk7Ly8gZmlsZTpzcmMvcGFyc2luZy9wYXlsLmpzCglCb3hQYXJzZXIuY3JlYXRlQm94Q3RvcigicGF5bCIsIGZ1bmN0aW9uKHN0cmVhbSkgewoJCXRoaXMudGV4dCA9IHN0cmVhbS5yZWFkU3RyaW5nKHRoaXMuc2l6ZSAtIHRoaXMuaGRyX3NpemUpOwoJfSk7CgoJLy8gZmlsZTpzcmMvcGFyc2luZy9wYXl0LmpzCglCb3hQYXJzZXIuY3JlYXRlQm94Q3RvcigicGF5dCIsIGZ1bmN0aW9uKHN0cmVhbSkgewoJCXRoaXMucGF5bG9hZElEID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQl2YXIgY291bnQgPSBzdHJlYW0ucmVhZFVpbnQ4KCk7CgkJdGhpcy5ydHBtYXBfc3RyaW5nID0gc3RyZWFtLnJlYWRTdHJpbmcoY291bnQpOwoJfSk7CgoJLy8gZmlsZTpzcmMvcGFyc2luZy9wZGluLmpzCglCb3hQYXJzZXIuY3JlYXRlRnVsbEJveEN0b3IoInBkaW4iLCBmdW5jdGlvbihzdHJlYW0pIHsKCQl2YXIgY291bnQgPSAodGhpcy5zaXplIC0gdGhpcy5oZHJfc2l6ZSkvODsKCQl0aGlzLnJhdGUgPSBbXTsKCQl0aGlzLmluaXRpYWxfZGVsYXkgPSBbXTsKCQlmb3IgKHZhciBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKCQkJdGhpcy5yYXRlW2ldID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQkJdGhpcy5pbml0aWFsX2RlbGF5W2ldID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQl9Cgl9KTsKCgkvLyBmaWxlOnNyYy9wYXJzaW5nL3BpdG0uanMKCUJveFBhcnNlci5jcmVhdGVGdWxsQm94Q3RvcigicGl0bSIsIGZ1bmN0aW9uKHN0cmVhbSkgewoJCWlmICh0aGlzLnZlcnNpb24gPT09IDApIHsKCQkJdGhpcy5pdGVtX2lkID0gc3RyZWFtLnJlYWRVaW50MTYoKTsKCQl9IGVsc2UgewoJCQl0aGlzLml0ZW1faWQgPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCX0KCX0pOwoKCS8vIGZpbGU6c3JjL3BhcnNpbmcvcGl4aS5qcwoJQm94UGFyc2VyLmNyZWF0ZUZ1bGxCb3hDdG9yKCJwaXhpIiwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJdmFyIGk7CgkJdGhpcy5udW1fY2hhbm5lbHMgPSBzdHJlYW0ucmVhZFVpbnQ4KCk7CgkJdGhpcy5iaXRzX3Blcl9jaGFubmVscyA9IFtdOwoJCWZvciAoaSA9IDA7IGkgPCB0aGlzLm51bV9jaGFubmVsczsgaSsrKSB7CgkJCXRoaXMuYml0c19wZXJfY2hhbm5lbHNbaV0gPSBzdHJlYW0ucmVhZFVpbnQ4KCk7CgkJfQoJfSk7CgoJLy8gZmlsZTpzcmMvcGFyc2luZy9wbWF4LmpzCglCb3hQYXJzZXIuY3JlYXRlQm94Q3RvcigicG1heCIsIGZ1bmN0aW9uKHN0cmVhbSkgewoJCXRoaXMuYnl0ZXMgPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJfSk7CgoJLy8gZmlsZTpzcmMvcGFyc2luZy9wcmZ0LmpzCglCb3hQYXJzZXIuY3JlYXRlRnVsbEJveEN0b3IoInByZnQiLCBmdW5jdGlvbihzdHJlYW0pIHsKCQl0aGlzLnJlZl90cmFja19pZCA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJdGhpcy5udHBfdGltZXN0YW1wID0gc3RyZWFtLnJlYWRVaW50NjQoKTsKCQlpZiAodGhpcy52ZXJzaW9uID09PSAwKSB7CgkJCXRoaXMubWVkaWFfdGltZSA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJfSBlbHNlIHsKCQkJdGhpcy5tZWRpYV90aW1lID0gc3RyZWFtLnJlYWRVaW50NjQoKTsKCQl9Cgl9KTsKCgkvLyBmaWxlOnNyYy9wYXJzaW5nL3Bzc2guanMKCUJveFBhcnNlci5jcmVhdGVGdWxsQm94Q3RvcigicHNzaCIsIGZ1bmN0aW9uKHN0cmVhbSkgewoJCXRoaXMuc3lzdGVtX2lkID0gQm94UGFyc2VyLnBhcnNlSGV4MTYoc3RyZWFtKTsKCQlpZiAodGhpcy52ZXJzaW9uID4gMCkgewoJCQl2YXIgY291bnQgPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCQl0aGlzLmtpZCA9IFtdOwoJCQlmb3IgKHZhciBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKCQkJCXRoaXMua2lkW2ldID0gQm94UGFyc2VyLnBhcnNlSGV4MTYoc3RyZWFtKTsKCQkJfQoJCX0KCQl2YXIgZGF0YXNpemUgPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCWlmIChkYXRhc2l6ZSA+IDApIHsKCQkJdGhpcy5kYXRhID0gc3RyZWFtLnJlYWRVaW50OEFycmF5KGRhdGFzaXplKTsKCQl9Cgl9KTsKCgkvLyBmaWxlOnNyYy9wYXJzaW5nL3F0L2NsZWYuanMKCUJveFBhcnNlci5jcmVhdGVGdWxsQm94Q3RvcigiY2xlZiIsIGZ1bmN0aW9uKHN0cmVhbSkgewoJCXRoaXMud2lkdGggPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCXRoaXMuaGVpZ2h0ID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCX0pOy8vIGZpbGU6c3JjL3BhcnNpbmcvcXQvZW5vZi5qcwoJQm94UGFyc2VyLmNyZWF0ZUZ1bGxCb3hDdG9yKCJlbm9mIiwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJdGhpcy53aWR0aCA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJdGhpcy5oZWlnaHQgPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJfSk7Ly8gZmlsZTpzcmMvcGFyc2luZy9xdC9wcm9mLmpzCglCb3hQYXJzZXIuY3JlYXRlRnVsbEJveEN0b3IoInByb2YiLCBmdW5jdGlvbihzdHJlYW0pIHsKCQl0aGlzLndpZHRoID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQl0aGlzLmhlaWdodCA9IHN0cmVhbS5yZWFkVWludDMyKCk7Cgl9KTsvLyBmaWxlOnNyYy9wYXJzaW5nL3F0L3RhcHQuanMKCUJveFBhcnNlci5jcmVhdGVDb250YWluZXJCb3hDdG9yKCJ0YXB0IiwgbnVsbCwgWyAiY2xlZiIsICJwcm9mIiwgImVub2YiXSk7Ly8gZmlsZTpzcmMvcGFyc2luZy9ydHAuanMKCUJveFBhcnNlci5jcmVhdGVCb3hDdG9yKCJydHAgIiwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJdGhpcy5kZXNjcmlwdGlvbmZvcm1hdCA9IHN0cmVhbS5yZWFkU3RyaW5nKDQpOwoJCXRoaXMuc2RwdGV4dCA9IHN0cmVhbS5yZWFkU3RyaW5nKHRoaXMuc2l6ZSAtIHRoaXMuaGRyX3NpemUgLSA0KTsKCX0pOwoKCS8vIGZpbGU6c3JjL3BhcnNpbmcvc2Fpby5qcwoJQm94UGFyc2VyLmNyZWF0ZUZ1bGxCb3hDdG9yKCJzYWlvIiwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJaWYgKHRoaXMuZmxhZ3MgJiAweDEpIHsKCQkJdGhpcy5hdXhfaW5mb190eXBlID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQkJdGhpcy5hdXhfaW5mb190eXBlX3BhcmFtZXRlciA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJfQoJCXZhciBjb3VudCA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJdGhpcy5vZmZzZXQgPSBbXTsKCQlmb3IgKHZhciBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKCQkJaWYgKHRoaXMudmVyc2lvbiA9PT0gMCkgewoJCQkJdGhpcy5vZmZzZXRbaV0gPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCQl9IGVsc2UgewoJCQkJdGhpcy5vZmZzZXRbaV0gPSBzdHJlYW0ucmVhZFVpbnQ2NCgpOwoJCQl9CgkJfQoJfSk7CgkvLyBmaWxlOnNyYy9wYXJzaW5nL3NhaXouanMKCUJveFBhcnNlci5jcmVhdGVGdWxsQm94Q3Rvcigic2FpeiIsIGZ1bmN0aW9uKHN0cmVhbSkgewoJCWlmICh0aGlzLmZsYWdzICYgMHgxKSB7CgkJCXRoaXMuYXV4X2luZm9fdHlwZSA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJCXRoaXMuYXV4X2luZm9fdHlwZV9wYXJhbWV0ZXIgPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCX0KCQl0aGlzLmRlZmF1bHRfc2FtcGxlX2luZm9fc2l6ZSA9IHN0cmVhbS5yZWFkVWludDgoKTsKCQl2YXIgY291bnQgPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCXRoaXMuc2FtcGxlX2luZm9fc2l6ZSA9IFtdOwoJCWlmICh0aGlzLmRlZmF1bHRfc2FtcGxlX2luZm9fc2l6ZSA9PT0gMCkgewoJCQlmb3IgKHZhciBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKCQkJCXRoaXMuc2FtcGxlX2luZm9fc2l6ZVtpXSA9IHN0cmVhbS5yZWFkVWludDgoKTsKCQkJfQoJCX0KCX0pOwoKCS8vIGZpbGU6c3JjL3BhcnNpbmcvc2FtcGxlZW50cmllcy9tZXR0LmpzCglCb3hQYXJzZXIuY3JlYXRlU2FtcGxlRW50cnlDdG9yKEJveFBhcnNlci5TQU1QTEVfRU5UUllfVFlQRV9NRVRBREFUQSwgIm1ldHQiLCBmdW5jdGlvbihzdHJlYW0pIHsKCQl0aGlzLnBhcnNlSGVhZGVyKHN0cmVhbSk7CgkJdGhpcy5jb250ZW50X2VuY29kaW5nID0gc3RyZWFtLnJlYWRDU3RyaW5nKCk7CgkJdGhpcy5taW1lX2Zvcm1hdCA9IHN0cmVhbS5yZWFkQ1N0cmluZygpOwoJCXRoaXMucGFyc2VGb290ZXIoc3RyZWFtKTsKCX0pOwoKCS8vIGZpbGU6c3JjL3BhcnNpbmcvc2FtcGxlZW50cmllcy9tZXR4LmpzCglCb3hQYXJzZXIuY3JlYXRlU2FtcGxlRW50cnlDdG9yKEJveFBhcnNlci5TQU1QTEVfRU5UUllfVFlQRV9NRVRBREFUQSwgIm1ldHgiLCBmdW5jdGlvbihzdHJlYW0pIHsKCQl0aGlzLnBhcnNlSGVhZGVyKHN0cmVhbSk7CgkJdGhpcy5jb250ZW50X2VuY29kaW5nID0gc3RyZWFtLnJlYWRDU3RyaW5nKCk7CgkJdGhpcy5uYW1lc3BhY2UgPSBzdHJlYW0ucmVhZENTdHJpbmcoKTsKCQl0aGlzLnNjaGVtYV9sb2NhdGlvbiA9IHN0cmVhbS5yZWFkQ1N0cmluZygpOwoJCXRoaXMucGFyc2VGb290ZXIoc3RyZWFtKTsKCX0pOwoKCS8vIGZpbGU6c3JjL3BhcnNpbmcvc2FtcGxlZW50cmllcy9zYnR0LmpzCglCb3hQYXJzZXIuY3JlYXRlU2FtcGxlRW50cnlDdG9yKEJveFBhcnNlci5TQU1QTEVfRU5UUllfVFlQRV9TVUJUSVRMRSwgInNidHQiLCBmdW5jdGlvbihzdHJlYW0pIHsKCQl0aGlzLnBhcnNlSGVhZGVyKHN0cmVhbSk7CgkJdGhpcy5jb250ZW50X2VuY29kaW5nID0gc3RyZWFtLnJlYWRDU3RyaW5nKCk7CgkJdGhpcy5taW1lX2Zvcm1hdCA9IHN0cmVhbS5yZWFkQ1N0cmluZygpOwoJCXRoaXMucGFyc2VGb290ZXIoc3RyZWFtKTsKCX0pOwoKCS8vIGZpbGU6c3JjL3BhcnNpbmcvc2FtcGxlZW50cmllcy9zdHBwLmpzCglCb3hQYXJzZXIuY3JlYXRlU2FtcGxlRW50cnlDdG9yKEJveFBhcnNlci5TQU1QTEVfRU5UUllfVFlQRV9TVUJUSVRMRSwgInN0cHAiLCBmdW5jdGlvbihzdHJlYW0pIHsKCQl0aGlzLnBhcnNlSGVhZGVyKHN0cmVhbSk7CgkJdGhpcy5uYW1lc3BhY2UgPSBzdHJlYW0ucmVhZENTdHJpbmcoKTsKCQl0aGlzLnNjaGVtYV9sb2NhdGlvbiA9IHN0cmVhbS5yZWFkQ1N0cmluZygpOwoJCXRoaXMuYXV4aWxpYXJ5X21pbWVfdHlwZXMgPSBzdHJlYW0ucmVhZENTdHJpbmcoKTsKCQl0aGlzLnBhcnNlRm9vdGVyKHN0cmVhbSk7Cgl9KTsKCgkvLyBmaWxlOnNyYy9wYXJzaW5nL3NhbXBsZWVudHJpZXMvc3R4dC5qcwoJQm94UGFyc2VyLmNyZWF0ZVNhbXBsZUVudHJ5Q3RvcihCb3hQYXJzZXIuU0FNUExFX0VOVFJZX1RZUEVfU1VCVElUTEUsICJzdHh0IiwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJdGhpcy5wYXJzZUhlYWRlcihzdHJlYW0pOwoJCXRoaXMuY29udGVudF9lbmNvZGluZyA9IHN0cmVhbS5yZWFkQ1N0cmluZygpOwoJCXRoaXMubWltZV9mb3JtYXQgPSBzdHJlYW0ucmVhZENTdHJpbmcoKTsKCQl0aGlzLnBhcnNlRm9vdGVyKHN0cmVhbSk7Cgl9KTsKCgkvLyBmaWxlOnNyYy9wYXJzaW5nL3NhbXBsZWVudHJpZXMvdHgzZy5qcwoJQm94UGFyc2VyLmNyZWF0ZVNhbXBsZUVudHJ5Q3RvcihCb3hQYXJzZXIuU0FNUExFX0VOVFJZX1RZUEVfU1VCVElUTEUsICJ0eDNnIiwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJdGhpcy5wYXJzZUhlYWRlcihzdHJlYW0pOwoJCXRoaXMuZGlzcGxheUZsYWdzID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQl0aGlzLmhvcml6b250YWxfanVzdGlmaWNhdGlvbiA9IHN0cmVhbS5yZWFkSW50OCgpOwoJCXRoaXMudmVydGljYWxfanVzdGlmaWNhdGlvbiA9IHN0cmVhbS5yZWFkSW50OCgpOwoJCXRoaXMuYmdfY29sb3JfcmdiYSA9IHN0cmVhbS5yZWFkVWludDhBcnJheSg0KTsKCQl0aGlzLmJveF9yZWNvcmQgPSBzdHJlYW0ucmVhZEludDE2QXJyYXkoNCk7CgkJdGhpcy5zdHlsZV9yZWNvcmQgPSBzdHJlYW0ucmVhZFVpbnQ4QXJyYXkoMTIpOwoJCXRoaXMucGFyc2VGb290ZXIoc3RyZWFtKTsKCX0pOwoJLy8gZmlsZTpzcmMvcGFyc2luZy9zYW1wbGVlbnRyaWVzL3d2dHQuanMKCUJveFBhcnNlci5jcmVhdGVTYW1wbGVFbnRyeUN0b3IoQm94UGFyc2VyLlNBTVBMRV9FTlRSWV9UWVBFX01FVEFEQVRBLCAid3Z0dCIsIGZ1bmN0aW9uKHN0cmVhbSkgewoJCXRoaXMucGFyc2VIZWFkZXIoc3RyZWFtKTsKCQl0aGlzLnBhcnNlRm9vdGVyKHN0cmVhbSk7Cgl9KTsKCgkvLyBmaWxlOnNyYy9wYXJzaW5nL3NhbXBsZWdyb3Vwcy9hbHN0LmpzCglCb3hQYXJzZXIuY3JlYXRlU2FtcGxlR3JvdXBDdG9yKCJhbHN0IiwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJdmFyIGk7CgkJdmFyIHJvbGxfY291bnQgPSBzdHJlYW0ucmVhZFVpbnQxNigpOwoJCXRoaXMuZmlyc3Rfb3V0cHV0X3NhbXBsZSA9IHN0cmVhbS5yZWFkVWludDE2KCk7CgkJdGhpcy5zYW1wbGVfb2Zmc2V0ID0gW107CgkJZm9yIChpID0gMDsgaSA8IHJvbGxfY291bnQ7IGkrKykgewoJCQl0aGlzLnNhbXBsZV9vZmZzZXRbaV0gPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCX0KCQl2YXIgcmVtYWluaW5nID0gdGhpcy5kZXNjcmlwdGlvbl9sZW5ndGggLSA0IC0gNCpyb2xsX2NvdW50OwoJCXRoaXMubnVtX291dHB1dF9zYW1wbGVzID0gW107CgkJdGhpcy5udW1fdG90YWxfc2FtcGxlcyA9IFtdOwoJCWZvciAoaSA9IDA7IGkgPCByZW1haW5pbmcvNDsgaSsrKSB7CgkJCXRoaXMubnVtX291dHB1dF9zYW1wbGVzW2ldID0gc3RyZWFtLnJlYWRVaW50MTYoKTsKCQkJdGhpcy5udW1fdG90YWxfc2FtcGxlc1tpXSA9IHN0cmVhbS5yZWFkVWludDE2KCk7CgkJfQoJfSk7CgoJLy8gZmlsZTpzcmMvcGFyc2luZy9zYW1wbGVncm91cHMvYXZsbC5qcwoJQm94UGFyc2VyLmNyZWF0ZVNhbXBsZUdyb3VwQ3RvcigiYXZsbCIsIGZ1bmN0aW9uKHN0cmVhbSkgewoJCXRoaXMubGF5ZXJOdW1iZXIgPSBzdHJlYW0ucmVhZFVpbnQ4KCk7CgkJdGhpcy5hY2N1cmF0ZVN0YXRpc3RpY3NGbGFnID0gc3RyZWFtLnJlYWRVaW50OCgpOwoJCXRoaXMuYXZnQml0UmF0ZSA9IHN0cmVhbS5yZWFkVWludDE2KCk7CgkJdGhpcy5hdmdGcmFtZVJhdGUgPSBzdHJlYW0ucmVhZFVpbnQxNigpOwoJfSk7CgoJLy8gZmlsZTpzcmMvcGFyc2luZy9zYW1wbGVncm91cHMvYXZzcy5qcwoJQm94UGFyc2VyLmNyZWF0ZVNhbXBsZUdyb3VwQ3RvcigiYXZzcyIsIGZ1bmN0aW9uKHN0cmVhbSkgewoJCXRoaXMuc3ViU2VxdWVuY2VJZGVudGlmaWVyID0gc3RyZWFtLnJlYWRVaW50MTYoKTsKCQl0aGlzLmxheWVyTnVtYmVyID0gc3RyZWFtLnJlYWRVaW50OCgpOwoJCXZhciB0bXBfYnl0ZSA9IHN0cmVhbS5yZWFkVWludDgoKTsKCQl0aGlzLmR1cmF0aW9uRmxhZyA9IHRtcF9ieXRlID4+IDc7CgkJdGhpcy5hdmdSYXRlRmxhZyA9ICh0bXBfYnl0ZSA+PiA2KSAmIDB4MTsKCQlpZiAodGhpcy5kdXJhdGlvbkZsYWcpIHsKCQkJdGhpcy5kdXJhdGlvbiA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJfQoJCWlmICh0aGlzLmF2Z1JhdGVGbGFnKSB7CgkJCXRoaXMuYWNjdXJhdGVTdGF0aXN0aWNzRmxhZyA9IHN0cmVhbS5yZWFkVWludDgoKTsKCQkJdGhpcy5hdmdCaXRSYXRlID0gc3RyZWFtLnJlYWRVaW50MTYoKTsKCQkJdGhpcy5hdmdGcmFtZVJhdGUgPSBzdHJlYW0ucmVhZFVpbnQxNigpOwoJCX0KCQl0aGlzLmRlcGVuZGVuY3kgPSBbXTsKCQl2YXIgbnVtUmVmZXJlbmNlcyA9IHN0cmVhbS5yZWFkVWludDgoKTsKCQlmb3IgKHZhciBpID0gMDsgaSA8IG51bVJlZmVyZW5jZXM7IGkrKykgewoJCQl2YXIgZGVwZW5kZW5jeUluZm8gPSB7fTsKCQkJdGhpcy5kZXBlbmRlbmN5LnB1c2goZGVwZW5kZW5jeUluZm8pOwoJCQlkZXBlbmRlbmN5SW5mby5zdWJTZXFEaXJlY3Rpb25GbGFnID0gc3RyZWFtLnJlYWRVaW50OCgpOwoJCQlkZXBlbmRlbmN5SW5mby5sYXllck51bWJlciA9IHN0cmVhbS5yZWFkVWludDgoKTsKCQkJZGVwZW5kZW5jeUluZm8uc3ViU2VxdWVuY2VJZGVudGlmaWVyID0gc3RyZWFtLnJlYWRVaW50MTYoKTsKCQl9Cgl9KTsKCgkvLyBmaWxlOnNyYy9wYXJzaW5nL3NhbXBsZWdyb3Vwcy9kdHJ0LmpzCglCb3hQYXJzZXIuY3JlYXRlU2FtcGxlR3JvdXBDdG9yKCJkdHJ0IiwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJTG9nLndhcm4oIkJveFBhcnNlciIsICJTYW1wbGUgR3JvdXAgdHlwZTogIit0aGlzLmdyb3VwaW5nX3R5cGUrIiBub3QgZnVsbHkgcGFyc2VkIik7Cgl9KTsKCgkvLyBmaWxlOnNyYy9wYXJzaW5nL3NhbXBsZWdyb3Vwcy9tdmlmLmpzCglCb3hQYXJzZXIuY3JlYXRlU2FtcGxlR3JvdXBDdG9yKCJtdmlmIiwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJTG9nLndhcm4oIkJveFBhcnNlciIsICJTYW1wbGUgR3JvdXAgdHlwZTogIit0aGlzLmdyb3VwaW5nX3R5cGUrIiBub3QgZnVsbHkgcGFyc2VkIik7Cgl9KTsKCgkvLyBmaWxlOnNyYy9wYXJzaW5nL3NhbXBsZWdyb3Vwcy9wcm9sLmpzCglCb3hQYXJzZXIuY3JlYXRlU2FtcGxlR3JvdXBDdG9yKCJwcm9sIiwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJdGhpcy5yb2xsX2Rpc3RhbmNlID0gc3RyZWFtLnJlYWRJbnQxNigpOwoJfSk7CgoJLy8gZmlsZTpzcmMvcGFyc2luZy9zYW1wbGVncm91cHMvcmFwLmpzCglCb3hQYXJzZXIuY3JlYXRlU2FtcGxlR3JvdXBDdG9yKCJyYXAgIiwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJdmFyIHRtcF9ieXRlID0gc3RyZWFtLnJlYWRVaW50OCgpOwoJCXRoaXMubnVtX2xlYWRpbmdfc2FtcGxlc19rbm93biA9IHRtcF9ieXRlID4+IDc7CgkJdGhpcy5udW1fbGVhZGluZ19zYW1wbGVzID0gdG1wX2J5dGUgJiAweDdGOwoJfSk7CgoJLy8gZmlsZTpzcmMvcGFyc2luZy9zYW1wbGVncm91cHMvcmFzaC5qcwoJQm94UGFyc2VyLmNyZWF0ZVNhbXBsZUdyb3VwQ3RvcigicmFzaCIsIGZ1bmN0aW9uKHN0cmVhbSkgewoJCXRoaXMub3BlcmF0aW9uX3BvaW50X2NvdW50ID0gc3RyZWFtLnJlYWRVaW50MTYoKTsKCQlpZiAodGhpcy5kZXNjcmlwdGlvbl9sZW5ndGggIT09IDIrKHRoaXMub3BlcmF0aW9uX3BvaW50X2NvdW50ID09PSAxPzI6dGhpcy5vcGVyYXRpb25fcG9pbnRfY291bnQqNikrOSkgewoJCQlMb2cud2FybigiQm94UGFyc2VyIiwgIk1pc21hdGNoIGluICIrdGhpcy5ncm91cGluZ190eXBlKyIgc2FtcGxlIGdyb3VwIGxlbmd0aCIpOwoJCQl0aGlzLmRhdGEgPSAgc3RyZWFtLnJlYWRVaW50OEFycmF5KHRoaXMuZGVzY3JpcHRpb25fbGVuZ3RoLTIpOwoJCX0gZWxzZSB7CgkJCWlmICh0aGlzLm9wZXJhdGlvbl9wb2ludF9jb3VudCA9PT0gMSkgewoJCQkJdGhpcy50YXJnZXRfcmF0ZV9zaGFyZSA9IHN0cmVhbS5yZWFkVWludDE2KCk7CgkJCX0gZWxzZSB7CgkJCQl0aGlzLnRhcmdldF9yYXRlX3NoYXJlID0gW107CgkJCQl0aGlzLmF2YWlsYWJsZV9iaXRyYXRlID0gW107CgkJCQlmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMub3BlcmF0aW9uX3BvaW50X2NvdW50OyBpKyspIHsKCQkJCQl0aGlzLmF2YWlsYWJsZV9iaXRyYXRlW2ldID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQkJCQl0aGlzLnRhcmdldF9yYXRlX3NoYXJlW2ldID0gc3RyZWFtLnJlYWRVaW50MTYoKTsKCQkJCX0KCQkJfQoJCQl0aGlzLm1heGltdW1fYml0cmF0ZSA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJCXRoaXMubWluaW11bV9iaXRyYXRlID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQkJdGhpcy5kaXNjYXJkX3ByaW9yaXR5ID0gc3RyZWFtLnJlYWRVaW50OCgpOwoJCX0KCX0pOwoKCS8vIGZpbGU6c3JjL3BhcnNpbmcvc2FtcGxlZ3JvdXBzL3JvbGwuanMKCUJveFBhcnNlci5jcmVhdGVTYW1wbGVHcm91cEN0b3IoInJvbGwiLCBmdW5jdGlvbihzdHJlYW0pIHsKCQl0aGlzLnJvbGxfZGlzdGFuY2UgPSBzdHJlYW0ucmVhZEludDE2KCk7Cgl9KTsKCgkvLyBmaWxlOnNyYy9wYXJzaW5nL3NhbXBsZWdyb3Vwcy9zYW1wbGVncm91cC5qcwoJQm94UGFyc2VyLlNhbXBsZUdyb3VwRW50cnkucHJvdG90eXBlLnBhcnNlID0gZnVuY3Rpb24oc3RyZWFtKSB7CgkJTG9nLndhcm4oIkJveFBhcnNlciIsICJVbmtub3duIFNhbXBsZSBHcm91cCB0eXBlOiAiK3RoaXMuZ3JvdXBpbmdfdHlwZSk7CgkJdGhpcy5kYXRhID0gIHN0cmVhbS5yZWFkVWludDhBcnJheSh0aGlzLmRlc2NyaXB0aW9uX2xlbmd0aCk7Cgl9OwoKCS8vIGZpbGU6c3JjL3BhcnNpbmcvc2FtcGxlZ3JvdXBzL3NjaWYuanMKCUJveFBhcnNlci5jcmVhdGVTYW1wbGVHcm91cEN0b3IoInNjaWYiLCBmdW5jdGlvbihzdHJlYW0pIHsKCQlMb2cud2FybigiQm94UGFyc2VyIiwgIlNhbXBsZSBHcm91cCB0eXBlOiAiK3RoaXMuZ3JvdXBpbmdfdHlwZSsiIG5vdCBmdWxseSBwYXJzZWQiKTsKCX0pOwoKCS8vIGZpbGU6c3JjL3BhcnNpbmcvc2FtcGxlZ3JvdXBzL3Njbm0uanMKCUJveFBhcnNlci5jcmVhdGVTYW1wbGVHcm91cEN0b3IoInNjbm0iLCBmdW5jdGlvbihzdHJlYW0pIHsKCQlMb2cud2FybigiQm94UGFyc2VyIiwgIlNhbXBsZSBHcm91cCB0eXBlOiAiK3RoaXMuZ3JvdXBpbmdfdHlwZSsiIG5vdCBmdWxseSBwYXJzZWQiKTsKCX0pOwoKCS8vIGZpbGU6c3JjL3BhcnNpbmcvc2FtcGxlZ3JvdXBzL3NlaWcuanMKCUJveFBhcnNlci5jcmVhdGVTYW1wbGVHcm91cEN0b3IoInNlaWciLCBmdW5jdGlvbihzdHJlYW0pIHsKCQl0aGlzLnJlc2VydmVkID0gc3RyZWFtLnJlYWRVaW50OCgpOwoJCXZhciB0bXAgPSBzdHJlYW0ucmVhZFVpbnQ4KCk7CgkJdGhpcy5jcnlwdF9ieXRlX2Jsb2NrID0gdG1wID4+IDQ7CgkJdGhpcy5za2lwX2J5dGVfYmxvY2sgPSB0bXAgJiAweEY7CgkJdGhpcy5pc1Byb3RlY3RlZCA9IHN0cmVhbS5yZWFkVWludDgoKTsKCQl0aGlzLlBlcl9TYW1wbGVfSVZfU2l6ZSA9IHN0cmVhbS5yZWFkVWludDgoKTsKCQl0aGlzLktJRCA9IEJveFBhcnNlci5wYXJzZUhleDE2KHN0cmVhbSk7CgkJdGhpcy5jb25zdGFudF9JVl9zaXplID0gMDsKCQl0aGlzLmNvbnN0YW50X0lWID0gMDsKCQlpZiAodGhpcy5pc1Byb3RlY3RlZCA9PT0gMSAmJiB0aGlzLlBlcl9TYW1wbGVfSVZfU2l6ZSA9PT0gMCkgewoJCQl0aGlzLmNvbnN0YW50X0lWX3NpemUgPSBzdHJlYW0ucmVhZFVpbnQ4KCk7CgkJCXRoaXMuY29uc3RhbnRfSVYgPSBzdHJlYW0ucmVhZFVpbnQ4QXJyYXkodGhpcy5jb25zdGFudF9JVl9zaXplKTsKCQl9Cgl9KTsKCgkvLyBmaWxlOnNyYy9wYXJzaW5nL3NhbXBsZWdyb3Vwcy9zdHNhLmpzCglCb3hQYXJzZXIuY3JlYXRlU2FtcGxlR3JvdXBDdG9yKCJzdHNhIiwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJTG9nLndhcm4oIkJveFBhcnNlciIsICJTYW1wbGUgR3JvdXAgdHlwZTogIit0aGlzLmdyb3VwaW5nX3R5cGUrIiBub3QgZnVsbHkgcGFyc2VkIik7Cgl9KTsKCgkvLyBmaWxlOnNyYy9wYXJzaW5nL3NhbXBsZWdyb3Vwcy9zeW5jLmpzCglCb3hQYXJzZXIuY3JlYXRlU2FtcGxlR3JvdXBDdG9yKCJzeW5jIiwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJdmFyIHRtcF9ieXRlID0gc3RyZWFtLnJlYWRVaW50OCgpOwoJCXRoaXMuTkFMX3VuaXRfdHlwZSA9IHRtcF9ieXRlICYgMHgzRjsKCX0pOwoKCS8vIGZpbGU6c3JjL3BhcnNpbmcvc2FtcGxlZ3JvdXBzL3RlbGUuanMKCUJveFBhcnNlci5jcmVhdGVTYW1wbGVHcm91cEN0b3IoInRlbGUiLCBmdW5jdGlvbihzdHJlYW0pIHsKCQl2YXIgdG1wX2J5dGUgPSBzdHJlYW0ucmVhZFVpbnQ4KCk7CgkJdGhpcy5sZXZlbF9pbmRlcGVuZGVudGx5X2RlY29kYWJsZSA9IHRtcF9ieXRlID4+IDc7Cgl9KTsKCgkvLyBmaWxlOnNyYy9wYXJzaW5nL3NhbXBsZWdyb3Vwcy90c2FzLmpzCglCb3hQYXJzZXIuY3JlYXRlU2FtcGxlR3JvdXBDdG9yKCJ0c2FzIiwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJTG9nLndhcm4oIkJveFBhcnNlciIsICJTYW1wbGUgR3JvdXAgdHlwZTogIit0aGlzLmdyb3VwaW5nX3R5cGUrIiBub3QgZnVsbHkgcGFyc2VkIik7Cgl9KTsKCgkvLyBmaWxlOnNyYy9wYXJzaW5nL3NhbXBsZWdyb3Vwcy90c2NsLmpzCglCb3hQYXJzZXIuY3JlYXRlU2FtcGxlR3JvdXBDdG9yKCJ0c2NsIiwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJTG9nLndhcm4oIkJveFBhcnNlciIsICJTYW1wbGUgR3JvdXAgdHlwZTogIit0aGlzLmdyb3VwaW5nX3R5cGUrIiBub3QgZnVsbHkgcGFyc2VkIik7Cgl9KTsKCgkvLyBmaWxlOnNyYy9wYXJzaW5nL3NhbXBsZWdyb3Vwcy92aXByLmpzCglCb3hQYXJzZXIuY3JlYXRlU2FtcGxlR3JvdXBDdG9yKCJ2aXByIiwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJTG9nLndhcm4oIkJveFBhcnNlciIsICJTYW1wbGUgR3JvdXAgdHlwZTogIit0aGlzLmdyb3VwaW5nX3R5cGUrIiBub3QgZnVsbHkgcGFyc2VkIik7Cgl9KTsKCgkvLyBmaWxlOnNyYy9wYXJzaW5nL3NiZ3AuanMKCUJveFBhcnNlci5jcmVhdGVGdWxsQm94Q3Rvcigic2JncCIsIGZ1bmN0aW9uKHN0cmVhbSkgewoJCXRoaXMuZ3JvdXBpbmdfdHlwZSA9IHN0cmVhbS5yZWFkU3RyaW5nKDQpOwoJCWlmICh0aGlzLnZlcnNpb24gPT09IDEpIHsKCQkJdGhpcy5ncm91cGluZ190eXBlX3BhcmFtZXRlciA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJfSBlbHNlIHsKCQkJdGhpcy5ncm91cGluZ190eXBlX3BhcmFtZXRlciA9IDA7CgkJfQoJCXRoaXMuZW50cmllcyA9IFtdOwoJCXZhciBlbnRyeV9jb3VudCA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJZm9yICh2YXIgaSA9IDA7IGkgPCBlbnRyeV9jb3VudDsgaSsrKSB7CgkJCXZhciBlbnRyeSA9IHt9OwoJCQl0aGlzLmVudHJpZXMucHVzaChlbnRyeSk7CgkJCWVudHJ5LnNhbXBsZV9jb3VudCA9IHN0cmVhbS5yZWFkSW50MzIoKTsKCQkJZW50cnkuZ3JvdXBfZGVzY3JpcHRpb25faW5kZXggPSBzdHJlYW0ucmVhZEludDMyKCk7CgkJfQoJfSk7CgoJLy8gZmlsZTpzcmMvcGFyc2luZy9zY2htLmpzCglCb3hQYXJzZXIuY3JlYXRlRnVsbEJveEN0b3IoInNjaG0iLCBmdW5jdGlvbihzdHJlYW0pIHsKCQl0aGlzLnNjaGVtZV90eXBlID0gc3RyZWFtLnJlYWRTdHJpbmcoNCk7CgkJdGhpcy5zY2hlbWVfdmVyc2lvbiA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJaWYgKHRoaXMuZmxhZ3MgJiAweDAwMDAwMSkgewoJCQl0aGlzLnNjaGVtZV91cmkgPSBzdHJlYW0ucmVhZFN0cmluZyh0aGlzLnNpemUgLSB0aGlzLmhkcl9zaXplIC0gOCk7CgkJfQoJfSk7CgoJLy8gZmlsZTpzcmMvcGFyc2luZy9zZHAuanMKCUJveFBhcnNlci5jcmVhdGVCb3hDdG9yKCJzZHAgIiwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJdGhpcy5zZHB0ZXh0ID0gc3RyZWFtLnJlYWRTdHJpbmcodGhpcy5zaXplIC0gdGhpcy5oZHJfc2l6ZSk7Cgl9KTsKCgkvLyBmaWxlOnNyYy9wYXJzaW5nL3NkdHAuanMKCUJveFBhcnNlci5jcmVhdGVGdWxsQm94Q3Rvcigic2R0cCIsIGZ1bmN0aW9uKHN0cmVhbSkgewoJCXZhciB0bXBfYnl0ZTsKCQl2YXIgY291bnQgPSAodGhpcy5zaXplIC0gdGhpcy5oZHJfc2l6ZSk7CgkJdGhpcy5pc19sZWFkaW5nID0gW107CgkJdGhpcy5zYW1wbGVfZGVwZW5kc19vbiA9IFtdOwoJCXRoaXMuc2FtcGxlX2lzX2RlcGVuZGVkX29uID0gW107CgkJdGhpcy5zYW1wbGVfaGFzX3JlZHVuZGFuY3kgPSBbXTsKCQlmb3IgKHZhciBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKCQkJdG1wX2J5dGUgPSBzdHJlYW0ucmVhZFVpbnQ4KCk7CgkJCXRoaXMuaXNfbGVhZGluZ1tpXSA9IHRtcF9ieXRlID4+IDY7CgkJCXRoaXMuc2FtcGxlX2RlcGVuZHNfb25baV0gPSAodG1wX2J5dGUgPj4gNCkgJiAweDM7CgkJCXRoaXMuc2FtcGxlX2lzX2RlcGVuZGVkX29uW2ldID0gKHRtcF9ieXRlID4+IDIpICYgMHgzOwoJCQl0aGlzLnNhbXBsZV9oYXNfcmVkdW5kYW5jeVtpXSA9IHRtcF9ieXRlICYgMHgzOwoJCX0KCX0pOwoKCS8vIGZpbGU6c3JjL3BhcnNpbmcvc2VuYy5qcwoJLy8gQ2Fubm90IGJlIGZ1bGx5IHBhcnNlZCBiZWNhdXNlIFBlcl9TYW1wbGVfSVZfU2l6ZSBuZWVkcyB0byBiZSBrbm93bg0KCUJveFBhcnNlci5jcmVhdGVGdWxsQm94Q3Rvcigic2VuYyIgLyosIGZ1bmN0aW9uKHN0cmVhbSkgew0KCQl0aGlzLnBhcnNlRnVsbEhlYWRlcihzdHJlYW0pOw0KCQl2YXIgc2FtcGxlX2NvdW50ID0gc3RyZWFtLnJlYWRVaW50MzIoKTsNCgkJdGhpcy5zYW1wbGVzID0gW107DQoJCWZvciAodmFyIGkgPSAwOyBpIDwgc2FtcGxlX2NvdW50OyBpKyspIHsNCgkJCXZhciBzYW1wbGUgPSB7fTsNCgkJCS8vIHRlbmMuZGVmYXVsdF9QZXJfU2FtcGxlX0lWX1NpemUgb3Igc2VpZy5QZXJfU2FtcGxlX0lWX1NpemUNCgkJCXNhbXBsZS5Jbml0aWFsaXphdGlvblZlY3RvciA9IHRoaXMucmVhZFVpbnQ4QXJyYXkoUGVyX1NhbXBsZV9JVl9TaXplKjgpOw0KCQkJaWYgKHRoaXMuZmxhZ3MgJiAweDIpIHsNCgkJCQlzYW1wbGUuc3Vic2FtcGxlcyA9IFtdOw0KCQkJCXN1YnNhbXBsZV9jb3VudCA9IHN0cmVhbS5yZWFkVWludDE2KCk7DQoJCQkJZm9yICh2YXIgaiA9IDA7IGogPCBzdWJzYW1wbGVfY291bnQ7IGorKykgew0KCQkJCQl2YXIgc3Vic2FtcGxlID0ge307DQoJCQkJCXN1YnNhbXBsZS5CeXRlc09mQ2xlYXJEYXRhID0gc3RyZWFtLnJlYWRVaW50MTYoKTsNCgkJCQkJc3Vic2FtcGxlLkJ5dGVzT2ZQcm90ZWN0ZWREYXRhID0gc3RyZWFtLnJlYWRVaW50MzIoKTsNCgkJCQkJc2FtcGxlLnN1YnNhbXBsZXMucHVzaChzdWJzYW1wbGUpOw0KCQkJCX0NCgkJCX0NCgkJCS8vIFRPRE8NCgkJCXRoaXMuc2FtcGxlcy5wdXNoKHNhbXBsZSk7DQoJCX0NCgl9Ki8pOw0KCS8vIGZpbGU6c3JjL3BhcnNpbmcvc2dwZC5qcwoJQm94UGFyc2VyLmNyZWF0ZUZ1bGxCb3hDdG9yKCJzZ3BkIiwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJdGhpcy5ncm91cGluZ190eXBlID0gc3RyZWFtLnJlYWRTdHJpbmcoNCk7CgkJTG9nLmRlYnVnKCJCb3hQYXJzZXIiLCAiRm91bmQgU2FtcGxlIEdyb3VwcyBvZiB0eXBlICIrdGhpcy5ncm91cGluZ190eXBlKTsKCQlpZiAodGhpcy52ZXJzaW9uID09PSAxKSB7CgkJCXRoaXMuZGVmYXVsdF9sZW5ndGggPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCX0gZWxzZSB7CgkJCXRoaXMuZGVmYXVsdF9sZW5ndGggPSAwOwoJCX0KCQlpZiAodGhpcy52ZXJzaW9uID49IDIpIHsKCQkJdGhpcy5kZWZhdWx0X2dyb3VwX2Rlc2NyaXB0aW9uX2luZGV4ID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQl9CgkJdGhpcy5lbnRyaWVzID0gW107CgkJdmFyIGVudHJ5X2NvdW50ID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQlmb3IgKHZhciBpID0gMDsgaSA8IGVudHJ5X2NvdW50OyBpKyspIHsKCQkJdmFyIGVudHJ5OwoJCQlpZiAoQm94UGFyc2VyW3RoaXMuZ3JvdXBpbmdfdHlwZSsiU2FtcGxlR3JvdXBFbnRyeSJdKSB7CgkJCQllbnRyeSA9IG5ldyBCb3hQYXJzZXJbdGhpcy5ncm91cGluZ190eXBlKyJTYW1wbGVHcm91cEVudHJ5Il0odGhpcy5ncm91cGluZ190eXBlKTsKCQkJfSAgZWxzZSB7CgkJCQllbnRyeSA9IG5ldyBCb3hQYXJzZXIuU2FtcGxlR3JvdXBFbnRyeSh0aGlzLmdyb3VwaW5nX3R5cGUpOwoJCQl9CgkJCXRoaXMuZW50cmllcy5wdXNoKGVudHJ5KTsKCQkJaWYgKHRoaXMudmVyc2lvbiA9PT0gMSkgewoJCQkJaWYgKHRoaXMuZGVmYXVsdF9sZW5ndGggPT09IDApIHsKCQkJCQllbnRyeS5kZXNjcmlwdGlvbl9sZW5ndGggPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCQkJfSBlbHNlIHsKCQkJCQllbnRyeS5kZXNjcmlwdGlvbl9sZW5ndGggPSB0aGlzLmRlZmF1bHRfbGVuZ3RoOwoJCQkJfQoJCQl9IGVsc2UgewoJCQkJZW50cnkuZGVzY3JpcHRpb25fbGVuZ3RoID0gdGhpcy5kZWZhdWx0X2xlbmd0aDsKCQkJfQoJCQlpZiAoZW50cnkud3JpdGUgPT09IEJveFBhcnNlci5TYW1wbGVHcm91cEVudHJ5LnByb3RvdHlwZS53cml0ZSkgewoJCQkJTG9nLmluZm8oIkJveFBhcnNlciIsICJTYW1wbGVHcm91cCBmb3IgdHlwZSAiK3RoaXMuZ3JvdXBpbmdfdHlwZSsiIHdyaXRpbmcgbm90IHlldCBpbXBsZW1lbnRlZCwga2VlcGluZyB1bnBhcnNlZCBkYXRhIGluIG1lbW9yeSBmb3IgbGF0ZXIgd3JpdGUiKTsKCQkJCS8vIHN0b3JpbmcgZGF0YQoJCQkJZW50cnkuZGF0YSA9IHN0cmVhbS5yZWFkVWludDhBcnJheShlbnRyeS5kZXNjcmlwdGlvbl9sZW5ndGgpOwoJCQkJLy8gcmV3aW5kaW5nCgkJCQlzdHJlYW0ucG9zaXRpb24gLT0gZW50cnkuZGVzY3JpcHRpb25fbGVuZ3RoOwoJCQl9CgkJCWVudHJ5LnBhcnNlKHN0cmVhbSk7CgkJfQoJfSk7CgoJLy8gZmlsZTpzcmMvcGFyc2luZy9zaWR4LmpzCglCb3hQYXJzZXIuY3JlYXRlRnVsbEJveEN0b3IoInNpZHgiLCBmdW5jdGlvbihzdHJlYW0pIHsKCQl0aGlzLnJlZmVyZW5jZV9JRCA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJdGhpcy50aW1lc2NhbGUgPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCWlmICh0aGlzLnZlcnNpb24gPT09IDApIHsKCQkJdGhpcy5lYXJsaWVzdF9wcmVzZW50YXRpb25fdGltZSA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJCXRoaXMuZmlyc3Rfb2Zmc2V0ID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQl9IGVsc2UgewoJCQl0aGlzLmVhcmxpZXN0X3ByZXNlbnRhdGlvbl90aW1lID0gc3RyZWFtLnJlYWRVaW50NjQoKTsKCQkJdGhpcy5maXJzdF9vZmZzZXQgPSBzdHJlYW0ucmVhZFVpbnQ2NCgpOwoJCX0KCQlzdHJlYW0ucmVhZFVpbnQxNigpOwoJCXRoaXMucmVmZXJlbmNlcyA9IFtdOwoJCXZhciBjb3VudCA9IHN0cmVhbS5yZWFkVWludDE2KCk7CgkJZm9yICh2YXIgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7CgkJCXZhciByZWYgPSB7fTsKCQkJdGhpcy5yZWZlcmVuY2VzLnB1c2gocmVmKTsKCQkJdmFyIHRtcF8zMiA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJCXJlZi5yZWZlcmVuY2VfdHlwZSA9ICh0bXBfMzIgPj4gMzEpICYgMHgxOwoJCQlyZWYucmVmZXJlbmNlZF9zaXplID0gdG1wXzMyICYgMHg3RkZGRkZGRjsKCQkJcmVmLnN1YnNlZ21lbnRfZHVyYXRpb24gPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCQl0bXBfMzIgPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCQlyZWYuc3RhcnRzX3dpdGhfU0FQID0gKHRtcF8zMiA+PiAzMSkgJiAweDE7CgkJCXJlZi5TQVBfdHlwZSA9ICh0bXBfMzIgPj4gMjgpICYgMHg3OwoJCQlyZWYuU0FQX2RlbHRhX3RpbWUgPSB0bXBfMzIgJiAweEZGRkZGRkY7CgkJfQoJfSk7CgoJLy8gZmlsZTpzcmMvcGFyc2luZy9zaW5nbGVpdGVtdHlwZXJlZmVyZW5jZS5qcwoJQm94UGFyc2VyLlNpbmdsZUl0ZW1UeXBlUmVmZXJlbmNlQm94ID0gZnVuY3Rpb24odHlwZSwgc2l6ZSwgaGRyX3NpemUsIHN0YXJ0KSB7CgkJQm94UGFyc2VyLkJveC5jYWxsKHRoaXMsIHR5cGUsIHNpemUpOwoJCXRoaXMuaGRyX3NpemUgPSBoZHJfc2l6ZTsKCQl0aGlzLnN0YXJ0ID0gc3RhcnQ7Cgl9OwoJQm94UGFyc2VyLlNpbmdsZUl0ZW1UeXBlUmVmZXJlbmNlQm94LnByb3RvdHlwZSA9IG5ldyBCb3hQYXJzZXIuQm94KCk7CglCb3hQYXJzZXIuU2luZ2xlSXRlbVR5cGVSZWZlcmVuY2VCb3gucHJvdG90eXBlLnBhcnNlID0gZnVuY3Rpb24oc3RyZWFtKSB7CgkJdGhpcy5mcm9tX2l0ZW1fSUQgPSBzdHJlYW0ucmVhZFVpbnQxNigpOwoJCXZhciBjb3VudCA9ICBzdHJlYW0ucmVhZFVpbnQxNigpOwoJCXRoaXMucmVmZXJlbmNlcyA9IFtdOwoJCWZvcih2YXIgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7CgkJCXRoaXMucmVmZXJlbmNlc1tpXSA9IHN0cmVhbS5yZWFkVWludDE2KCk7CgkJfQoJfTsKCgkvLyBmaWxlOnNyYy9wYXJzaW5nL3NpbmdsZWl0ZW10eXBlcmVmZXJlbmNlbGFyZ2UuanMKCUJveFBhcnNlci5TaW5nbGVJdGVtVHlwZVJlZmVyZW5jZUJveExhcmdlID0gZnVuY3Rpb24odHlwZSwgc2l6ZSwgaGRyX3NpemUsIHN0YXJ0KSB7CgkJQm94UGFyc2VyLkJveC5jYWxsKHRoaXMsIHR5cGUsIHNpemUpOwoJCXRoaXMuaGRyX3NpemUgPSBoZHJfc2l6ZTsKCQl0aGlzLnN0YXJ0ID0gc3RhcnQ7Cgl9OwoJQm94UGFyc2VyLlNpbmdsZUl0ZW1UeXBlUmVmZXJlbmNlQm94TGFyZ2UucHJvdG90eXBlID0gbmV3IEJveFBhcnNlci5Cb3goKTsKCUJveFBhcnNlci5TaW5nbGVJdGVtVHlwZVJlZmVyZW5jZUJveExhcmdlLnByb3RvdHlwZS5wYXJzZSA9IGZ1bmN0aW9uKHN0cmVhbSkgewoJCXRoaXMuZnJvbV9pdGVtX0lEID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQl2YXIgY291bnQgPSAgc3RyZWFtLnJlYWRVaW50MTYoKTsKCQl0aGlzLnJlZmVyZW5jZXMgPSBbXTsKCQlmb3IodmFyIGkgPSAwOyBpIDwgY291bnQ7IGkrKykgewoJCQl0aGlzLnJlZmVyZW5jZXNbaV0gPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCX0KCX07CgoJLy8gZmlsZTpzcmMvcGFyc2luZy9TbURtLmpzCglCb3hQYXJzZXIuY3JlYXRlRnVsbEJveEN0b3IoIlNtRG0iLCBmdW5jdGlvbihzdHJlYW0pIHsKCQl0aGlzLnByaW1hcnlSQ2hyb21hdGljaXR5X3ggPSBzdHJlYW0ucmVhZFVpbnQxNigpOwoJICAgIHRoaXMucHJpbWFyeVJDaHJvbWF0aWNpdHlfeSA9IHN0cmVhbS5yZWFkVWludDE2KCk7CgkgICAgdGhpcy5wcmltYXJ5R0Nocm9tYXRpY2l0eV94ID0gc3RyZWFtLnJlYWRVaW50MTYoKTsKCSAgICB0aGlzLnByaW1hcnlHQ2hyb21hdGljaXR5X3kgPSBzdHJlYW0ucmVhZFVpbnQxNigpOwoJICAgIHRoaXMucHJpbWFyeUJDaHJvbWF0aWNpdHlfeCA9IHN0cmVhbS5yZWFkVWludDE2KCk7CgkgICAgdGhpcy5wcmltYXJ5QkNocm9tYXRpY2l0eV95ID0gc3RyZWFtLnJlYWRVaW50MTYoKTsKCSAgICB0aGlzLndoaXRlUG9pbnRDaHJvbWF0aWNpdHlfeCA9IHN0cmVhbS5yZWFkVWludDE2KCk7CgkgICAgdGhpcy53aGl0ZVBvaW50Q2hyb21hdGljaXR5X3kgPSBzdHJlYW0ucmVhZFVpbnQxNigpOwoJICAgIHRoaXMubHVtaW5hbmNlTWF4ID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCSAgICB0aGlzLmx1bWluYW5jZU1pbiA9IHN0cmVhbS5yZWFkVWludDMyKCk7Cgl9KTsKCgkvLyBmaWxlOnNyYy9wYXJzaW5nL3NtaGQuanMKCUJveFBhcnNlci5jcmVhdGVGdWxsQm94Q3Rvcigic21oZCIsIGZ1bmN0aW9uKHN0cmVhbSkgewoJCXRoaXMuYmFsYW5jZSA9IHN0cmVhbS5yZWFkVWludDE2KCk7CgkJc3RyZWFtLnJlYWRVaW50MTYoKTsKCX0pOwoKCS8vIGZpbGU6c3JjL3BhcnNpbmcvc3NpeC5qcwoJQm94UGFyc2VyLmNyZWF0ZUZ1bGxCb3hDdG9yKCJzc2l4IiwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJdGhpcy5zdWJzZWdtZW50cyA9IFtdOwoJCXZhciBzdWJzZWdtZW50X2NvdW50ID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQlmb3IgKHZhciBpID0gMDsgaSA8IHN1YnNlZ21lbnRfY291bnQ7IGkrKykgewoJCQl2YXIgc3Vic2VnbWVudCA9IHt9OwoJCQl0aGlzLnN1YnNlZ21lbnRzLnB1c2goc3Vic2VnbWVudCk7CgkJCXN1YnNlZ21lbnQucmFuZ2VzID0gW107CgkJCXZhciByYW5nZV9jb3VudCA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJCWZvciAodmFyIGogPSAwOyBqIDwgcmFuZ2VfY291bnQ7IGorKykgewoJCQkJdmFyIHJhbmdlID0ge307CgkJCQlzdWJzZWdtZW50LnJhbmdlcy5wdXNoKHJhbmdlKTsKCQkJCXJhbmdlLmxldmVsID0gc3RyZWFtLnJlYWRVaW50OCgpOwoJCQkJcmFuZ2UucmFuZ2Vfc2l6ZSA9IHN0cmVhbS5yZWFkVWludDI0KCk7CgkJCX0KCQl9Cgl9KTsKCgkvLyBmaWxlOnNyYy9wYXJzaW5nL3N0Y28uanMKCUJveFBhcnNlci5jcmVhdGVGdWxsQm94Q3Rvcigic3RjbyIsIGZ1bmN0aW9uKHN0cmVhbSkgewoJCXZhciBlbnRyeV9jb3VudDsKCQllbnRyeV9jb3VudCA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJdGhpcy5jaHVua19vZmZzZXRzID0gW107CgkJaWYgKHRoaXMudmVyc2lvbiA9PT0gMCkgewoJCQlmb3IgKHZhciBpID0gMDsgaSA8IGVudHJ5X2NvdW50OyBpKyspIHsKCQkJCXRoaXMuY2h1bmtfb2Zmc2V0cy5wdXNoKHN0cmVhbS5yZWFkVWludDMyKCkpOwoJCQl9CgkJfQoJfSk7CgoJLy8gZmlsZTpzcmMvcGFyc2luZy9zdGRwLmpzCglCb3hQYXJzZXIuY3JlYXRlRnVsbEJveEN0b3IoInN0ZHAiLCBmdW5jdGlvbihzdHJlYW0pIHsKCQl2YXIgY291bnQgPSAodGhpcy5zaXplIC0gdGhpcy5oZHJfc2l6ZSkvMjsKCQl0aGlzLnByaW9yaXR5ID0gW107CgkJZm9yICh2YXIgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7CgkJCXRoaXMucHJpb3JpdHlbaV0gPSBzdHJlYW0ucmVhZFVpbnQxNigpOwoJCX0KCX0pOwoKCS8vIGZpbGU6c3JjL3BhcnNpbmcvc3RoZC5qcwoJQm94UGFyc2VyLmNyZWF0ZUZ1bGxCb3hDdG9yKCJzdGhkIik7CgoJLy8gZmlsZTpzcmMvcGFyc2luZy9zdHJpLmpzCglCb3hQYXJzZXIuY3JlYXRlRnVsbEJveEN0b3IoInN0cmkiLCBmdW5jdGlvbihzdHJlYW0pIHsKCQl0aGlzLnN3aXRjaF9ncm91cCA9IHN0cmVhbS5yZWFkVWludDE2KCk7CgkJdGhpcy5hbHRlcm5hdGVfZ3JvdXAgPSBzdHJlYW0ucmVhZFVpbnQxNigpOwoJCXRoaXMuc3ViX3RyYWNrX2lkID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQl2YXIgY291bnQgPSAodGhpcy5zaXplIC0gdGhpcy5oZHJfc2l6ZSAtIDgpLzQ7CgkJdGhpcy5hdHRyaWJ1dGVfbGlzdCA9IFtdOwoJCWZvciAodmFyIGkgPSAwOyBpIDwgY291bnQ7IGkrKykgewoJCQl0aGlzLmF0dHJpYnV0ZV9saXN0W2ldID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQl9Cgl9KTsKCgkvLyBmaWxlOnNyYy9wYXJzaW5nL3N0c2MuanMKCUJveFBhcnNlci5jcmVhdGVGdWxsQm94Q3Rvcigic3RzYyIsIGZ1bmN0aW9uKHN0cmVhbSkgewoJCXZhciBlbnRyeV9jb3VudDsKCQl2YXIgaTsKCQllbnRyeV9jb3VudCA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJdGhpcy5maXJzdF9jaHVuayA9IFtdOwoJCXRoaXMuc2FtcGxlc19wZXJfY2h1bmsgPSBbXTsKCQl0aGlzLnNhbXBsZV9kZXNjcmlwdGlvbl9pbmRleCA9IFtdOwoJCWlmICh0aGlzLnZlcnNpb24gPT09IDApIHsKCQkJZm9yKGk9MDsgaTxlbnRyeV9jb3VudDsgaSsrKSB7CgkJCQl0aGlzLmZpcnN0X2NodW5rLnB1c2goc3RyZWFtLnJlYWRVaW50MzIoKSk7CgkJCQl0aGlzLnNhbXBsZXNfcGVyX2NodW5rLnB1c2goc3RyZWFtLnJlYWRVaW50MzIoKSk7CgkJCQl0aGlzLnNhbXBsZV9kZXNjcmlwdGlvbl9pbmRleC5wdXNoKHN0cmVhbS5yZWFkVWludDMyKCkpOwoJCQl9CgkJfQoJfSk7CgoJLy8gZmlsZTpzcmMvcGFyc2luZy9zdHNkLmpzCglCb3hQYXJzZXIuY3JlYXRlRnVsbEJveEN0b3IoInN0c2QiLCBmdW5jdGlvbihzdHJlYW0pIHsKCQl2YXIgaTsKCQl2YXIgcmV0OwoJCXZhciBlbnRyeUNvdW50OwoJCXZhciBib3g7CgkJdGhpcy5lbnRyaWVzID0gW107CgkJZW50cnlDb3VudCA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJZm9yIChpID0gMTsgaSA8PSBlbnRyeUNvdW50OyBpKyspIHsKCQkJcmV0ID0gQm94UGFyc2VyLnBhcnNlT25lQm94KHN0cmVhbSwgdHJ1ZSwgdGhpcy5zaXplIC0gKHN0cmVhbS5nZXRQb3NpdGlvbigpIC0gdGhpcy5zdGFydCkpOwoJCQlpZiAocmV0LmNvZGUgPT09IEJveFBhcnNlci5PSykgewoJCQkJaWYgKEJveFBhcnNlcltyZXQudHlwZSsiU2FtcGxlRW50cnkiXSkgewoJCQkJCWJveCA9IG5ldyBCb3hQYXJzZXJbcmV0LnR5cGUrIlNhbXBsZUVudHJ5Il0ocmV0LnNpemUpOwoJCQkJCWJveC5oZHJfc2l6ZSA9IHJldC5oZHJfc2l6ZTsKCQkJCQlib3guc3RhcnQgPSByZXQuc3RhcnQ7CgkJCQl9IGVsc2UgewoJCQkJCUxvZy53YXJuKCJCb3hQYXJzZXIiLCAiVW5rbm93biBzYW1wbGUgZW50cnkgdHlwZTogIityZXQudHlwZSk7CgkJCQkJYm94ID0gbmV3IEJveFBhcnNlci5TYW1wbGVFbnRyeShyZXQudHlwZSwgcmV0LnNpemUsIHJldC5oZHJfc2l6ZSwgcmV0LnN0YXJ0KTsKCQkJCX0KCQkJCWlmIChib3gud3JpdGUgPT09IEJveFBhcnNlci5TYW1wbGVFbnRyeS5wcm90b3R5cGUud3JpdGUpIHsKCQkJCQlMb2cuaW5mbygiQm94UGFyc2VyIiwgIlNhbXBsZUVudHJ5ICIrYm94LnR5cGUrIiBib3ggd3JpdGluZyBub3QgeWV0IGltcGxlbWVudGVkLCBrZWVwaW5nIHVucGFyc2VkIGRhdGEgaW4gbWVtb3J5IGZvciBsYXRlciB3cml0ZSIpOwoJCQkJCWJveC5wYXJzZURhdGFBbmRSZXdpbmQoc3RyZWFtKTsKCQkJCX0KCQkJCWJveC5wYXJzZShzdHJlYW0pOwoJCQkJdGhpcy5lbnRyaWVzLnB1c2goYm94KTsKCQkJfSBlbHNlIHsKCQkJCXJldHVybjsKCQkJfQoJCX0KCX0pOwoKCS8vIGZpbGU6c3JjL3BhcnNpbmcvc3RzZy5qcwoJQm94UGFyc2VyLmNyZWF0ZUZ1bGxCb3hDdG9yKCJzdHNnIiwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJdGhpcy5ncm91cGluZ190eXBlID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQl2YXIgY291bnQgPSBzdHJlYW0ucmVhZFVpbnQxNigpOwoJCXRoaXMuZ3JvdXBfZGVzY3JpcHRpb25faW5kZXggPSBbXTsKCQlmb3IgKHZhciBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKCQkJdGhpcy5ncm91cF9kZXNjcmlwdGlvbl9pbmRleFtpXSA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJfQoJfSk7CgoJLy8gZmlsZTpzcmMvcGFyc2luZy9zdHNoLmpzCglCb3hQYXJzZXIuY3JlYXRlRnVsbEJveEN0b3IoInN0c2giLCBmdW5jdGlvbihzdHJlYW0pIHsKCQl2YXIgZW50cnlfY291bnQ7CgkJdmFyIGk7CgkJZW50cnlfY291bnQgPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCXRoaXMuc2hhZG93ZWRfc2FtcGxlX251bWJlcnMgPSBbXTsKCQl0aGlzLnN5bmNfc2FtcGxlX251bWJlcnMgPSBbXTsKCQlpZiAodGhpcy52ZXJzaW9uID09PSAwKSB7CgkJCWZvcihpPTA7IGk8ZW50cnlfY291bnQ7IGkrKykgewoJCQkJdGhpcy5zaGFkb3dlZF9zYW1wbGVfbnVtYmVycy5wdXNoKHN0cmVhbS5yZWFkVWludDMyKCkpOwoJCQkJdGhpcy5zeW5jX3NhbXBsZV9udW1iZXJzLnB1c2goc3RyZWFtLnJlYWRVaW50MzIoKSk7CgkJCX0KCQl9Cgl9KTsKCgkvLyBmaWxlOnNyYy9wYXJzaW5nL3N0c3MuanMKCUJveFBhcnNlci5jcmVhdGVGdWxsQm94Q3Rvcigic3RzcyIsIGZ1bmN0aW9uKHN0cmVhbSkgewoJCXZhciBpOwoJCXZhciBlbnRyeV9jb3VudDsKCQllbnRyeV9jb3VudCA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJaWYgKHRoaXMudmVyc2lvbiA9PT0gMCkgewoJCQl0aGlzLnNhbXBsZV9udW1iZXJzID0gW107CgkJCWZvcihpPTA7IGk8ZW50cnlfY291bnQ7IGkrKykgewoJCQkJdGhpcy5zYW1wbGVfbnVtYmVycy5wdXNoKHN0cmVhbS5yZWFkVWludDMyKCkpOwoJCQl9CgkJfQoJfSk7CgoJLy8gZmlsZTpzcmMvcGFyc2luZy9zdHN6LmpzCglCb3hQYXJzZXIuY3JlYXRlRnVsbEJveEN0b3IoInN0c3oiLCBmdW5jdGlvbihzdHJlYW0pIHsKCQl2YXIgaTsKCQl0aGlzLnNhbXBsZV9zaXplcyA9IFtdOwoJCWlmICh0aGlzLnZlcnNpb24gPT09IDApIHsKCQkJdGhpcy5zYW1wbGVfc2l6ZSA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJCXRoaXMuc2FtcGxlX2NvdW50ID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQkJZm9yIChpID0gMDsgaSA8IHRoaXMuc2FtcGxlX2NvdW50OyBpKyspIHsKCQkJCWlmICh0aGlzLnNhbXBsZV9zaXplID09PSAwKSB7CgkJCQkJdGhpcy5zYW1wbGVfc2l6ZXMucHVzaChzdHJlYW0ucmVhZFVpbnQzMigpKTsKCQkJCX0gZWxzZSB7CgkJCQkJdGhpcy5zYW1wbGVfc2l6ZXNbaV0gPSB0aGlzLnNhbXBsZV9zaXplOwoJCQkJfQoJCQl9CgkJfQoJfSk7CgoJLy8gZmlsZTpzcmMvcGFyc2luZy9zdHRzLmpzCglCb3hQYXJzZXIuY3JlYXRlRnVsbEJveEN0b3IoInN0dHMiLCBmdW5jdGlvbihzdHJlYW0pIHsKCQl2YXIgZW50cnlfY291bnQ7CgkJdmFyIGk7CgkJdmFyIGRlbHRhOwoJCWVudHJ5X2NvdW50ID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQl0aGlzLnNhbXBsZV9jb3VudHMgPSBbXTsKCQl0aGlzLnNhbXBsZV9kZWx0YXMgPSBbXTsKCQlpZiAodGhpcy52ZXJzaW9uID09PSAwKSB7CgkJCWZvcihpPTA7IGk8ZW50cnlfY291bnQ7IGkrKykgewoJCQkJdGhpcy5zYW1wbGVfY291bnRzLnB1c2goc3RyZWFtLnJlYWRVaW50MzIoKSk7CgkJCQlkZWx0YSA9IHN0cmVhbS5yZWFkSW50MzIoKTsKCQkJCWlmIChkZWx0YSA8IDApIHsKCQkJCQlMb2cud2FybigiQm94UGFyc2VyIiwgIkZpbGUgdXNlcyBuZWdhdGl2ZSBzdHRzIHNhbXBsZSBkZWx0YSwgdXNpbmcgdmFsdWUgMSBpbnN0ZWFkLCBzeW5jIG1heSBiZSBsb3N0ISIpOwoJCQkJCWRlbHRhID0gMTsKCQkJCX0KCQkJCXRoaXMuc2FtcGxlX2RlbHRhcy5wdXNoKGRlbHRhKTsKCQkJfQoJCX0KCX0pOwoKCS8vIGZpbGU6c3JjL3BhcnNpbmcvc3R2aS5qcwoJQm94UGFyc2VyLmNyZWF0ZUZ1bGxCb3hDdG9yKCJzdHZpIiwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJdmFyIHRtcDMyID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQl0aGlzLnNpbmdsZV92aWV3X2FsbG93ZWQgPSB0bXAzMiAmIDB4MzsKCQl0aGlzLnN0ZXJlb19zY2hlbWUgPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCXZhciBsZW5ndGggPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCXRoaXMuc3RlcmVvX2luZGljYXRpb25fdHlwZSA9IHN0cmVhbS5yZWFkU3RyaW5nKGxlbmd0aCk7CgkJdmFyIHJldDsKCQl2YXIgYm94OwoJCXRoaXMuYm94ZXMgPSBbXTsKCQl3aGlsZSAoc3RyZWFtLmdldFBvc2l0aW9uKCkgPCB0aGlzLnN0YXJ0K3RoaXMuc2l6ZSkgewoJCQlyZXQgPSBCb3hQYXJzZXIucGFyc2VPbmVCb3goc3RyZWFtLCBmYWxzZSwgdGhpcy5zaXplIC0gKHN0cmVhbS5nZXRQb3NpdGlvbigpIC0gdGhpcy5zdGFydCkpOwoJCQlpZiAocmV0LmNvZGUgPT09IEJveFBhcnNlci5PSykgewoJCQkJYm94ID0gcmV0LmJveDsKCQkJCXRoaXMuYm94ZXMucHVzaChib3gpOwoJCQkJdGhpc1tib3gudHlwZV0gPSBib3g7CgkJCX0gZWxzZSB7CgkJCQlyZXR1cm47CgkJCX0KCQl9Cgl9KTsKCgkvLyBmaWxlOnNyYy9wYXJzaW5nL3N0eXAuanMKCUJveFBhcnNlci5jcmVhdGVCb3hDdG9yKCJzdHlwIiwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJQm94UGFyc2VyLmZ0eXBCb3gucHJvdG90eXBlLnBhcnNlLmNhbGwodGhpcywgc3RyZWFtKTsKCX0pOwoKCS8vIGZpbGU6c3JjL3BhcnNpbmcvc3R6Mi5qcwoJQm94UGFyc2VyLmNyZWF0ZUZ1bGxCb3hDdG9yKCJzdHoyIiwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJdmFyIGk7CgkJdmFyIHNhbXBsZV9jb3VudDsKCQl0aGlzLnNhbXBsZV9zaXplcyA9IFtdOwoJCWlmICh0aGlzLnZlcnNpb24gPT09IDApIHsKCQkJdGhpcy5yZXNlcnZlZCA9IHN0cmVhbS5yZWFkVWludDI0KCk7CgkJCXRoaXMuZmllbGRfc2l6ZSA9IHN0cmVhbS5yZWFkVWludDgoKTsKCQkJc2FtcGxlX2NvdW50ID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQkJaWYgKHRoaXMuZmllbGRfc2l6ZSA9PT0gNCkgewoJCQkJZm9yIChpID0gMDsgaSA8IHNhbXBsZV9jb3VudDsgaSs9MikgewoJCQkJCXZhciB0bXAgPSBzdHJlYW0ucmVhZFVpbnQ4KCk7CgkJCQkJdGhpcy5zYW1wbGVfc2l6ZXNbaV0gPSAodG1wID4+IDQpICYgMHhGOwoJCQkJCXRoaXMuc2FtcGxlX3NpemVzW2krMV0gPSB0bXAgJiAweEY7CgkJCQl9CgkJCX0gZWxzZSBpZiAodGhpcy5maWVsZF9zaXplID09PSA4KSB7CgkJCQlmb3IgKGkgPSAwOyBpIDwgc2FtcGxlX2NvdW50OyBpKyspIHsKCQkJCQl0aGlzLnNhbXBsZV9zaXplc1tpXSA9IHN0cmVhbS5yZWFkVWludDgoKTsKCQkJCX0KCQkJfSBlbHNlIGlmICh0aGlzLmZpZWxkX3NpemUgPT09IDE2KSB7CgkJCQlmb3IgKGkgPSAwOyBpIDwgc2FtcGxlX2NvdW50OyBpKyspIHsKCQkJCQl0aGlzLnNhbXBsZV9zaXplc1tpXSA9IHN0cmVhbS5yZWFkVWludDE2KCk7CgkJCQl9CgkJCX0gZWxzZSB7CgkJCQlMb2cuZXJyb3IoIkJveFBhcnNlciIsICJFcnJvciBpbiBsZW5ndGggZmllbGQgaW4gc3R6MiBib3giKTsKCQkJfQoJCX0KCX0pOwoKCS8vIGZpbGU6c3JjL3BhcnNpbmcvc3Vicy5qcwoJQm94UGFyc2VyLmNyZWF0ZUZ1bGxCb3hDdG9yKCJzdWJzIiwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJdmFyIGksajsKCQl2YXIgZW50cnlfY291bnQ7CgkJdmFyIHN1YnNhbXBsZV9jb3VudDsKCQllbnRyeV9jb3VudCA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJdGhpcy5lbnRyaWVzID0gW107CgkJZm9yIChpID0gMDsgaSA8IGVudHJ5X2NvdW50OyBpKyspIHsKCQkJdmFyIHNhbXBsZUluZm8gPSB7fTsKCQkJdGhpcy5lbnRyaWVzW2ldID0gc2FtcGxlSW5mbzsKCQkJc2FtcGxlSW5mby5zYW1wbGVfZGVsdGEgPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCQlzYW1wbGVJbmZvLnN1YnNhbXBsZXMgPSBbXTsKCQkJc3Vic2FtcGxlX2NvdW50ID0gc3RyZWFtLnJlYWRVaW50MTYoKTsKCQkJaWYgKHN1YnNhbXBsZV9jb3VudD4wKSB7CgkJCQlmb3IgKGogPSAwOyBqIDwgc3Vic2FtcGxlX2NvdW50OyBqKyspIHsKCQkJCQl2YXIgc3Vic2FtcGxlID0ge307CgkJCQkJc2FtcGxlSW5mby5zdWJzYW1wbGVzLnB1c2goc3Vic2FtcGxlKTsKCQkJCQlpZiAodGhpcy52ZXJzaW9uID09IDEpIHsKCQkJCQkJc3Vic2FtcGxlLnNpemUgPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCQkJCX0gZWxzZSB7CgkJCQkJCXN1YnNhbXBsZS5zaXplID0gc3RyZWFtLnJlYWRVaW50MTYoKTsKCQkJCQl9CgkJCQkJc3Vic2FtcGxlLnByaW9yaXR5ID0gc3RyZWFtLnJlYWRVaW50OCgpOwoJCQkJCXN1YnNhbXBsZS5kaXNjYXJkYWJsZSA9IHN0cmVhbS5yZWFkVWludDgoKTsKCQkJCQlzdWJzYW1wbGUuY29kZWNfc3BlY2lmaWNfcGFyYW1ldGVycyA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJCQl9CgkJCX0KCQl9Cgl9KTsKCgkvLyBmaWxlOnNyYy9wYXJzaW5nL3RlbmMuanMKCUJveFBhcnNlci5jcmVhdGVGdWxsQm94Q3RvcigidGVuYyIsIGZ1bmN0aW9uKHN0cmVhbSkgewoJCXN0cmVhbS5yZWFkVWludDgoKTsgLy8gcmVzZXJ2ZWQKCQlpZiAodGhpcy52ZXJzaW9uID09PSAwKSB7CgkJCXN0cmVhbS5yZWFkVWludDgoKTsKCQl9IGVsc2UgewoJCQl2YXIgdG1wID0gc3RyZWFtLnJlYWRVaW50OCgpOwoJCQl0aGlzLmRlZmF1bHRfY3J5cHRfYnl0ZV9ibG9jayA9ICh0bXAgPj4gNCkgJiAweEY7CgkJCXRoaXMuZGVmYXVsdF9za2lwX2J5dGVfYmxvY2sgPSB0bXAgJiAweEY7CgkJfQoJCXRoaXMuZGVmYXVsdF9pc1Byb3RlY3RlZCA9IHN0cmVhbS5yZWFkVWludDgoKTsKCQl0aGlzLmRlZmF1bHRfUGVyX1NhbXBsZV9JVl9TaXplID0gc3RyZWFtLnJlYWRVaW50OCgpOwoJCXRoaXMuZGVmYXVsdF9LSUQgPSBCb3hQYXJzZXIucGFyc2VIZXgxNihzdHJlYW0pOwoJCWlmICh0aGlzLmRlZmF1bHRfaXNQcm90ZWN0ZWQgPT09IDEgJiYgdGhpcy5kZWZhdWx0X1Blcl9TYW1wbGVfSVZfU2l6ZSA9PT0gMCkgewoJCQl0aGlzLmRlZmF1bHRfY29uc3RhbnRfSVZfc2l6ZSA9IHN0cmVhbS5yZWFkVWludDgoKTsKCQkJdGhpcy5kZWZhdWx0X2NvbnN0YW50X0lWID0gc3RyZWFtLnJlYWRVaW50OEFycmF5KHRoaXMuZGVmYXVsdF9jb25zdGFudF9JVl9zaXplKTsKCQl9Cgl9KTsvLyBmaWxlOnNyYy9wYXJzaW5nL3RmZHQuanMKCUJveFBhcnNlci5jcmVhdGVGdWxsQm94Q3RvcigidGZkdCIsIGZ1bmN0aW9uKHN0cmVhbSkgewoJCWlmICh0aGlzLnZlcnNpb24gPT0gMSkgewoJCQl0aGlzLmJhc2VNZWRpYURlY29kZVRpbWUgPSBzdHJlYW0ucmVhZFVpbnQ2NCgpOwoJCX0gZWxzZSB7CgkJCXRoaXMuYmFzZU1lZGlhRGVjb2RlVGltZSA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJfQoJfSk7CgoJLy8gZmlsZTpzcmMvcGFyc2luZy90ZmhkLmpzCglCb3hQYXJzZXIuY3JlYXRlRnVsbEJveEN0b3IoInRmaGQiLCBmdW5jdGlvbihzdHJlYW0pIHsKCQl2YXIgcmVhZEJ5dGVzID0gMDsKCQl0aGlzLnRyYWNrX2lkID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQlpZiAodGhpcy5zaXplIC0gdGhpcy5oZHJfc2l6ZSA+IHJlYWRCeXRlcyAmJiAodGhpcy5mbGFncyAmIEJveFBhcnNlci5URkhEX0ZMQUdfQkFTRV9EQVRBX09GRlNFVCkpIHsKCQkJdGhpcy5iYXNlX2RhdGFfb2Zmc2V0ID0gc3RyZWFtLnJlYWRVaW50NjQoKTsKCQkJcmVhZEJ5dGVzICs9IDg7CgkJfSBlbHNlIHsKCQkJdGhpcy5iYXNlX2RhdGFfb2Zmc2V0ID0gMDsKCQl9CgkJaWYgKHRoaXMuc2l6ZSAtIHRoaXMuaGRyX3NpemUgPiByZWFkQnl0ZXMgJiYgKHRoaXMuZmxhZ3MgJiBCb3hQYXJzZXIuVEZIRF9GTEFHX1NBTVBMRV9ERVNDKSkgewoJCQl0aGlzLmRlZmF1bHRfc2FtcGxlX2Rlc2NyaXB0aW9uX2luZGV4ID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQkJcmVhZEJ5dGVzICs9IDQ7CgkJfSBlbHNlIHsKCQkJdGhpcy5kZWZhdWx0X3NhbXBsZV9kZXNjcmlwdGlvbl9pbmRleCA9IDA7CgkJfQoJCWlmICh0aGlzLnNpemUgLSB0aGlzLmhkcl9zaXplID4gcmVhZEJ5dGVzICYmICh0aGlzLmZsYWdzICYgQm94UGFyc2VyLlRGSERfRkxBR19TQU1QTEVfRFVSKSkgewoJCQl0aGlzLmRlZmF1bHRfc2FtcGxlX2R1cmF0aW9uID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQkJcmVhZEJ5dGVzICs9IDQ7CgkJfSBlbHNlIHsKCQkJdGhpcy5kZWZhdWx0X3NhbXBsZV9kdXJhdGlvbiA9IDA7CgkJfQoJCWlmICh0aGlzLnNpemUgLSB0aGlzLmhkcl9zaXplID4gcmVhZEJ5dGVzICYmICh0aGlzLmZsYWdzICYgQm94UGFyc2VyLlRGSERfRkxBR19TQU1QTEVfU0laRSkpIHsKCQkJdGhpcy5kZWZhdWx0X3NhbXBsZV9zaXplID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQkJcmVhZEJ5dGVzICs9IDQ7CgkJfSBlbHNlIHsKCQkJdGhpcy5kZWZhdWx0X3NhbXBsZV9zaXplID0gMDsKCQl9CgkJaWYgKHRoaXMuc2l6ZSAtIHRoaXMuaGRyX3NpemUgPiByZWFkQnl0ZXMgJiYgKHRoaXMuZmxhZ3MgJiBCb3hQYXJzZXIuVEZIRF9GTEFHX1NBTVBMRV9GTEFHUykpIHsKCQkJdGhpcy5kZWZhdWx0X3NhbXBsZV9mbGFncyA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJCXJlYWRCeXRlcyArPSA0OwoJCX0gZWxzZSB7CgkJCXRoaXMuZGVmYXVsdF9zYW1wbGVfZmxhZ3MgPSAwOwoJCX0KCX0pOwoKCS8vIGZpbGU6c3JjL3BhcnNpbmcvdGZyYS5qcwoJQm94UGFyc2VyLmNyZWF0ZUZ1bGxCb3hDdG9yKCJ0ZnJhIiwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJdGhpcy50cmFja19JRCA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJc3RyZWFtLnJlYWRVaW50MjQoKTsKCQl2YXIgdG1wX2J5dGUgPSBzdHJlYW0ucmVhZFVpbnQ4KCk7CgkJdGhpcy5sZW5ndGhfc2l6ZV9vZl90cmFmX251bSA9ICh0bXBfYnl0ZSA+PiA0KSAmIDB4MzsKCQl0aGlzLmxlbmd0aF9zaXplX29mX3RydW5fbnVtID0gKHRtcF9ieXRlID4+IDIpICYgMHgzOwoJCXRoaXMubGVuZ3RoX3NpemVfb2Zfc2FtcGxlX251bSA9ICh0bXBfYnl0ZSkgJiAweDM7CgkJdGhpcy5lbnRyaWVzID0gW107CgkJdmFyIG51bWJlcl9vZl9lbnRyaWVzID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQlmb3IgKHZhciBpID0gMDsgaSA8IG51bWJlcl9vZl9lbnRyaWVzOyBpKyspIHsKCQkJaWYgKHRoaXMudmVyc2lvbiA9PT0gMSkgewoJCQkJdGhpcy50aW1lID0gc3RyZWFtLnJlYWRVaW50NjQoKTsKCQkJCXRoaXMubW9vZl9vZmZzZXQgPSBzdHJlYW0ucmVhZFVpbnQ2NCgpOwoJCQl9IGVsc2UgewoJCQkJdGhpcy50aW1lID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQkJCXRoaXMubW9vZl9vZmZzZXQgPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCQl9CgkJCXRoaXMudHJhZl9udW1iZXIgPSBzdHJlYW1bInJlYWRVaW50IisoOCoodGhpcy5sZW5ndGhfc2l6ZV9vZl90cmFmX251bSsxKSldKCk7CgkJCXRoaXMudHJ1bl9udW1iZXIgPSBzdHJlYW1bInJlYWRVaW50IisoOCoodGhpcy5sZW5ndGhfc2l6ZV9vZl90cnVuX251bSsxKSldKCk7CgkJCXRoaXMuc2FtcGxlX251bWJlciA9IHN0cmVhbVsicmVhZFVpbnQiKyg4Kih0aGlzLmxlbmd0aF9zaXplX29mX3NhbXBsZV9udW0rMSkpXSgpOwoJCX0KCX0pOwoKCS8vIGZpbGU6c3JjL3BhcnNpbmcvdGtoZC5qcwoJQm94UGFyc2VyLmNyZWF0ZUZ1bGxCb3hDdG9yKCJ0a2hkIiwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJaWYgKHRoaXMudmVyc2lvbiA9PSAxKSB7CgkJCXRoaXMuY3JlYXRpb25fdGltZSA9IHN0cmVhbS5yZWFkVWludDY0KCk7CgkJCXRoaXMubW9kaWZpY2F0aW9uX3RpbWUgPSBzdHJlYW0ucmVhZFVpbnQ2NCgpOwoJCQl0aGlzLnRyYWNrX2lkID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQkJc3RyZWFtLnJlYWRVaW50MzIoKTsKCQkJdGhpcy5kdXJhdGlvbiA9IHN0cmVhbS5yZWFkVWludDY0KCk7CgkJfSBlbHNlIHsKCQkJdGhpcy5jcmVhdGlvbl90aW1lID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQkJdGhpcy5tb2RpZmljYXRpb25fdGltZSA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJCXRoaXMudHJhY2tfaWQgPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCQlzdHJlYW0ucmVhZFVpbnQzMigpOwoJCQl0aGlzLmR1cmF0aW9uID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQl9CgkJc3RyZWFtLnJlYWRVaW50MzJBcnJheSgyKTsKCQl0aGlzLmxheWVyID0gc3RyZWFtLnJlYWRJbnQxNigpOwoJCXRoaXMuYWx0ZXJuYXRlX2dyb3VwID0gc3RyZWFtLnJlYWRJbnQxNigpOwoJCXRoaXMudm9sdW1lID0gc3RyZWFtLnJlYWRJbnQxNigpPj44OwoJCXN0cmVhbS5yZWFkVWludDE2KCk7CgkJdGhpcy5tYXRyaXggPSBzdHJlYW0ucmVhZEludDMyQXJyYXkoOSk7CgkJdGhpcy53aWR0aCA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJdGhpcy5oZWlnaHQgPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJfSk7CgoJLy8gZmlsZTpzcmMvcGFyc2luZy90bWF4LmpzCglCb3hQYXJzZXIuY3JlYXRlQm94Q3RvcigidG1heCIsIGZ1bmN0aW9uKHN0cmVhbSkgewoJCXRoaXMudGltZSA9IHN0cmVhbS5yZWFkVWludDMyKCk7Cgl9KTsKCgkvLyBmaWxlOnNyYy9wYXJzaW5nL3RtaW4uanMKCUJveFBhcnNlci5jcmVhdGVCb3hDdG9yKCJ0bWluIiwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJdGhpcy50aW1lID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCX0pOwoKCS8vIGZpbGU6c3JjL3BhcnNpbmcvdG90bC5qcwoJQm94UGFyc2VyLmNyZWF0ZUJveEN0b3IoInRvdGwiLGZ1bmN0aW9uKHN0cmVhbSkgewoJCXRoaXMuYnl0ZXNzZW50ID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCX0pOwoKCS8vIGZpbGU6c3JjL3BhcnNpbmcvdHBheS5qcwoJQm94UGFyc2VyLmNyZWF0ZUJveEN0b3IoInRwYXkiLCBmdW5jdGlvbihzdHJlYW0pIHsKCQl0aGlzLmJ5dGVzc2VudCA9IHN0cmVhbS5yZWFkVWludDMyKCk7Cgl9KTsKCgkvLyBmaWxlOnNyYy9wYXJzaW5nL3RweWwuanMKCUJveFBhcnNlci5jcmVhdGVCb3hDdG9yKCJ0cHlsIiwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJdGhpcy5ieXRlc3NlbnQgPSBzdHJlYW0ucmVhZFVpbnQ2NCgpOwoJfSk7CgoJLy8gZmlsZTpzcmMvcGFyc2luZy9UcmFja0dyb3VwLmpzCglCb3hQYXJzZXIuVHJhY2tHcm91cFR5cGVCb3gucHJvdG90eXBlLnBhcnNlID0gZnVuY3Rpb24oc3RyZWFtKSB7CgkJdGhpcy5wYXJzZUZ1bGxIZWFkZXIoc3RyZWFtKTsKCQl0aGlzLnRyYWNrX2dyb3VwX2lkID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCX07CgoJLy8gZmlsZTpzcmMvcGFyc2luZy90cmFja2dyb3Vwcy9tc3JjLmpzCglCb3hQYXJzZXIuY3JlYXRlVHJhY2tHcm91cEN0b3IoIm1zcmMiKTsvLyBmaWxlOnNyYy9wYXJzaW5nL1RyYWtSZWZlcmVuY2UuanMKCUJveFBhcnNlci5UcmFja1JlZmVyZW5jZVR5cGVCb3ggPSBmdW5jdGlvbih0eXBlLCBzaXplLCBoZHJfc2l6ZSwgc3RhcnQpIHsKCQlCb3hQYXJzZXIuQm94LmNhbGwodGhpcywgdHlwZSwgc2l6ZSk7CgkJdGhpcy5oZHJfc2l6ZSA9IGhkcl9zaXplOwoJCXRoaXMuc3RhcnQgPSBzdGFydDsKCX07CglCb3hQYXJzZXIuVHJhY2tSZWZlcmVuY2VUeXBlQm94LnByb3RvdHlwZSA9IG5ldyBCb3hQYXJzZXIuQm94KCk7CglCb3hQYXJzZXIuVHJhY2tSZWZlcmVuY2VUeXBlQm94LnByb3RvdHlwZS5wYXJzZSA9IGZ1bmN0aW9uKHN0cmVhbSkgewoJCXRoaXMudHJhY2tfaWRzID0gc3RyZWFtLnJlYWRVaW50MzJBcnJheSgodGhpcy5zaXplLXRoaXMuaGRyX3NpemUpLzQpOwoJfTsKCgkvLyBmaWxlOnNyYy9wYXJzaW5nL3RyZWYuanMKCUJveFBhcnNlci50cmVmQm94LnByb3RvdHlwZS5wYXJzZSA9IGZ1bmN0aW9uKHN0cmVhbSkgewoJCXZhciByZXQ7CgkJdmFyIGJveDsKCQl3aGlsZSAoc3RyZWFtLmdldFBvc2l0aW9uKCkgPCB0aGlzLnN0YXJ0K3RoaXMuc2l6ZSkgewoJCQlyZXQgPSBCb3hQYXJzZXIucGFyc2VPbmVCb3goc3RyZWFtLCB0cnVlLCB0aGlzLnNpemUgLSAoc3RyZWFtLmdldFBvc2l0aW9uKCkgLSB0aGlzLnN0YXJ0KSk7CgkJCWlmIChyZXQuY29kZSA9PT0gQm94UGFyc2VyLk9LKSB7CgkJCQlib3ggPSBuZXcgQm94UGFyc2VyLlRyYWNrUmVmZXJlbmNlVHlwZUJveChyZXQudHlwZSwgcmV0LnNpemUsIHJldC5oZHJfc2l6ZSwgcmV0LnN0YXJ0KTsKCQkJCWlmIChib3gud3JpdGUgPT09IEJveFBhcnNlci5Cb3gucHJvdG90eXBlLndyaXRlICYmIGJveC50eXBlICE9PSAibWRhdCIpIHsKCQkJCQlMb2cuaW5mbygiQm94UGFyc2VyIiwgIlRyYWNrUmVmZXJlbmNlICIrYm94LnR5cGUrIiBib3ggd3JpdGluZyBub3QgeWV0IGltcGxlbWVudGVkLCBrZWVwaW5nIHVucGFyc2VkIGRhdGEgaW4gbWVtb3J5IGZvciBsYXRlciB3cml0ZSIpOwoJCQkJCWJveC5wYXJzZURhdGFBbmRSZXdpbmQoc3RyZWFtKTsKCQkJCX0KCQkJCWJveC5wYXJzZShzdHJlYW0pOwoJCQkJdGhpcy5ib3hlcy5wdXNoKGJveCk7CgkJCX0gZWxzZSB7CgkJCQlyZXR1cm47CgkJCX0KCQl9Cgl9OwoKCS8vIGZpbGU6c3JjL3BhcnNpbmcvdHJlcC5qcwoJQm94UGFyc2VyLmNyZWF0ZUZ1bGxCb3hDdG9yKCJ0cmVwIiwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJdGhpcy50cmFja19JRCA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJdGhpcy5ib3hlcyA9IFtdOwoJCXdoaWxlIChzdHJlYW0uZ2V0UG9zaXRpb24oKSA8IHRoaXMuc3RhcnQrdGhpcy5zaXplKSB7CgkJCXJldCA9IEJveFBhcnNlci5wYXJzZU9uZUJveChzdHJlYW0sIGZhbHNlLCB0aGlzLnNpemUgLSAoc3RyZWFtLmdldFBvc2l0aW9uKCkgLSB0aGlzLnN0YXJ0KSk7CgkJCWlmIChyZXQuY29kZSA9PT0gQm94UGFyc2VyLk9LKSB7CgkJCQlib3ggPSByZXQuYm94OwoJCQkJdGhpcy5ib3hlcy5wdXNoKGJveCk7CgkJCX0gZWxzZSB7CgkJCQlyZXR1cm47CgkJCX0KCQl9Cgl9KTsKCgkvLyBmaWxlOnNyYy9wYXJzaW5nL3RyZXguanMKCUJveFBhcnNlci5jcmVhdGVGdWxsQm94Q3RvcigidHJleCIsIGZ1bmN0aW9uKHN0cmVhbSkgewoJCXRoaXMudHJhY2tfaWQgPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCXRoaXMuZGVmYXVsdF9zYW1wbGVfZGVzY3JpcHRpb25faW5kZXggPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCXRoaXMuZGVmYXVsdF9zYW1wbGVfZHVyYXRpb24gPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCXRoaXMuZGVmYXVsdF9zYW1wbGVfc2l6ZSA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJdGhpcy5kZWZhdWx0X3NhbXBsZV9mbGFncyA9IHN0cmVhbS5yZWFkVWludDMyKCk7Cgl9KTsKCgkvLyBmaWxlOnNyYy9wYXJzaW5nL3RycHkuanMKCUJveFBhcnNlci5jcmVhdGVCb3hDdG9yKCJ0cnB5IiwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJdGhpcy5ieXRlc3NlbnQgPSBzdHJlYW0ucmVhZFVpbnQ2NCgpOwoJfSk7CgoJLy8gZmlsZTpzcmMvcGFyc2luZy90cnVuLmpzCglCb3hQYXJzZXIuY3JlYXRlRnVsbEJveEN0b3IoInRydW4iLCBmdW5jdGlvbihzdHJlYW0pIHsKCQl2YXIgcmVhZEJ5dGVzID0gMDsKCQl0aGlzLnNhbXBsZV9jb3VudCA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJcmVhZEJ5dGVzKz0gNDsKCQlpZiAodGhpcy5zaXplIC0gdGhpcy5oZHJfc2l6ZSA+IHJlYWRCeXRlcyAmJiAodGhpcy5mbGFncyAmIEJveFBhcnNlci5UUlVOX0ZMQUdTX0RBVEFfT0ZGU0VUKSApIHsKCQkJdGhpcy5kYXRhX29mZnNldCA9IHN0cmVhbS5yZWFkSW50MzIoKTsgLy9zaWduZWQKCQkJcmVhZEJ5dGVzICs9IDQ7CgkJfSBlbHNlIHsKCQkJdGhpcy5kYXRhX29mZnNldCA9IDA7CgkJfQoJCWlmICh0aGlzLnNpemUgLSB0aGlzLmhkcl9zaXplID4gcmVhZEJ5dGVzICYmICh0aGlzLmZsYWdzICYgQm94UGFyc2VyLlRSVU5fRkxBR1NfRklSU1RfRkxBRykgKSB7CgkJCXRoaXMuZmlyc3Rfc2FtcGxlX2ZsYWdzID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQkJcmVhZEJ5dGVzICs9IDQ7CgkJfSBlbHNlIHsKCQkJdGhpcy5maXJzdF9zYW1wbGVfZmxhZ3MgPSAwOwoJCX0KCQl0aGlzLnNhbXBsZV9kdXJhdGlvbiA9IFtdOwoJCXRoaXMuc2FtcGxlX3NpemUgPSBbXTsKCQl0aGlzLnNhbXBsZV9mbGFncyA9IFtdOwoJCXRoaXMuc2FtcGxlX2NvbXBvc2l0aW9uX3RpbWVfb2Zmc2V0ID0gW107CgkJaWYgKHRoaXMuc2l6ZSAtIHRoaXMuaGRyX3NpemUgPiByZWFkQnl0ZXMpIHsKCQkJZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnNhbXBsZV9jb3VudDsgaSsrKSB7CgkJCQlpZiAodGhpcy5mbGFncyAmIEJveFBhcnNlci5UUlVOX0ZMQUdTX0RVUkFUSU9OKSB7CgkJCQkJdGhpcy5zYW1wbGVfZHVyYXRpb25baV0gPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCQkJfQoJCQkJaWYgKHRoaXMuZmxhZ3MgJiBCb3hQYXJzZXIuVFJVTl9GTEFHU19TSVpFKSB7CgkJCQkJdGhpcy5zYW1wbGVfc2l6ZVtpXSA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJCQl9CgkJCQlpZiAodGhpcy5mbGFncyAmIEJveFBhcnNlci5UUlVOX0ZMQUdTX0ZMQUdTKSB7CgkJCQkJdGhpcy5zYW1wbGVfZmxhZ3NbaV0gPSBzdHJlYW0ucmVhZFVpbnQzMigpOwoJCQkJfQoJCQkJaWYgKHRoaXMuZmxhZ3MgJiBCb3hQYXJzZXIuVFJVTl9GTEFHU19DVFNfT0ZGU0VUKSB7CgkJCQkJaWYgKHRoaXMudmVyc2lvbiA9PT0gMCkgewoJCQkJCQl0aGlzLnNhbXBsZV9jb21wb3NpdGlvbl90aW1lX29mZnNldFtpXSA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJCQkJfSBlbHNlIHsKCQkJCQkJdGhpcy5zYW1wbGVfY29tcG9zaXRpb25fdGltZV9vZmZzZXRbaV0gPSBzdHJlYW0ucmVhZEludDMyKCk7IC8vc2lnbmVkCgkJCQkJfQoJCQkJfQoJCQl9CgkJfQoJfSk7CgoJLy8gZmlsZTpzcmMvcGFyc2luZy90c2VsLmpzCglCb3hQYXJzZXIuY3JlYXRlRnVsbEJveEN0b3IoInRzZWwiLCBmdW5jdGlvbihzdHJlYW0pIHsKCQl0aGlzLnN3aXRjaF9ncm91cCA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJdmFyIGNvdW50ID0gKHRoaXMuc2l6ZSAtIHRoaXMuaGRyX3NpemUgLSA0KS80OwoJCXRoaXMuYXR0cmlidXRlX2xpc3QgPSBbXTsKCQlmb3IgKHZhciBpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKCQkJdGhpcy5hdHRyaWJ1dGVfbGlzdFtpXSA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJfQoJfSk7CgoJLy8gZmlsZTpzcmMvcGFyc2luZy90eHRDLmpzCglCb3hQYXJzZXIuY3JlYXRlRnVsbEJveEN0b3IoInR4dEMiLCBmdW5jdGlvbihzdHJlYW0pIHsKCQl0aGlzLmNvbmZpZyA9IHN0cmVhbS5yZWFkQ1N0cmluZygpOwoJfSk7CgoJLy8gZmlsZTpzcmMvcGFyc2luZy91cmwuanMKCUJveFBhcnNlci5jcmVhdGVGdWxsQm94Q3RvcigidXJsICIsIGZ1bmN0aW9uKHN0cmVhbSkgewoJCWlmICh0aGlzLmZsYWdzICE9PSAweDAwMDAwMSkgewoJCQl0aGlzLmxvY2F0aW9uID0gc3RyZWFtLnJlYWRDU3RyaW5nKCk7CgkJfQoJfSk7CgoJLy8gZmlsZTpzcmMvcGFyc2luZy91cm4uanMKCUJveFBhcnNlci5jcmVhdGVGdWxsQm94Q3RvcigidXJuICIsIGZ1bmN0aW9uKHN0cmVhbSkgewoJCXRoaXMubmFtZSA9IHN0cmVhbS5yZWFkQ1N0cmluZygpOwoJCWlmICh0aGlzLnNpemUgLSB0aGlzLmhkcl9zaXplIC0gdGhpcy5uYW1lLmxlbmd0aCAtIDEgPiAwKSB7CgkJCXRoaXMubG9jYXRpb24gPSBzdHJlYW0ucmVhZENTdHJpbmcoKTsKCQl9Cgl9KTsKCgkvLyBmaWxlOnNyYy9wYXJzaW5nL3V1aWQvcGlmZi9waWZmTHNtLmpzCglCb3hQYXJzZXIuY3JlYXRlVVVJREJveCgiYTVkNDBiMzBlODE0MTFkZGJhMmYwODAwMjAwYzlhNjYiLCB0cnVlLCBmYWxzZSwgZnVuY3Rpb24oc3RyZWFtKSB7CgkgICAgdGhpcy5MaXZlU2VydmVyTWFuaWZlc3QgPSBzdHJlYW0ucmVhZFN0cmluZyh0aGlzLnNpemUgLSB0aGlzLmhkcl9zaXplKQoJICAgICAgICAucmVwbGFjZSgvJi9nLCAiJmFtcDsiKQoJICAgICAgICAucmVwbGFjZSgvPC9nLCAiJmx0OyIpCgkgICAgICAgIC5yZXBsYWNlKC8+L2csICImZ3Q7IikKCSAgICAgICAgLnJlcGxhY2UoLyIvZywgIiZxdW90OyIpCgkgICAgICAgIC5yZXBsYWNlKC8nL2csICImIzAzOTsiKTsKCX0pOy8vIGZpbGU6c3JjL3BhcnNpbmcvdXVpZC9waWZmL3BpZmZQc3NoLmpzCglCb3hQYXJzZXIuY3JlYXRlVVVJREJveCgiZDA4YTRmMTgxMGYzNGE4MmI2YzgzMmQ4YWJhMTgzZDMiLCB0cnVlLCBmYWxzZSwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJdGhpcy5zeXN0ZW1faWQgPSBCb3hQYXJzZXIucGFyc2VIZXgxNihzdHJlYW0pOwoJCXZhciBkYXRhc2l6ZSA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkJaWYgKGRhdGFzaXplID4gMCkgewoJCQl0aGlzLmRhdGEgPSBzdHJlYW0ucmVhZFVpbnQ4QXJyYXkoZGF0YXNpemUpOwoJCX0KCX0pOwoKCS8vIGZpbGU6c3JjL3BhcnNpbmcvdXVpZC9waWZmL3BpZmZTZW5jLmpzCglCb3hQYXJzZXIuY3JlYXRlVVVJREJveCgiYTIzOTRmNTI1YTliNGYxNGEyNDQ2YzQyN2M2NDhkZjQiLCB0cnVlLCBmYWxzZSAvKiwgZnVuY3Rpb24oc3RyZWFtKSB7CgkJaWYgKHRoaXMuZmxhZ3MgJiAweDEpIHsKCQkJdGhpcy5BbGdvcml0aG1JRCA9IHN0cmVhbS5yZWFkVWludDI0KCk7CgkJCXRoaXMuSVZfc2l6ZSA9IHN0cmVhbS5yZWFkVWludDgoKTsKCQkJdGhpcy5LSUQgPSBCb3hQYXJzZXIucGFyc2VIZXgxNihzdHJlYW0pOwoJCX0KCQl2YXIgc2FtcGxlX2NvdW50ID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQl0aGlzLnNhbXBsZXMgPSBbXTsKCQlmb3IgKHZhciBpID0gMDsgaSA8IHNhbXBsZV9jb3VudDsgaSsrKSB7CgkJCXZhciBzYW1wbGUgPSB7fTsKCQkJc2FtcGxlLkluaXRpYWxpemF0aW9uVmVjdG9yID0gdGhpcy5yZWFkVWludDhBcnJheSh0aGlzLklWX3NpemUqOCk7CgkJCWlmICh0aGlzLmZsYWdzICYgMHgyKSB7CgkJCQlzYW1wbGUuc3Vic2FtcGxlcyA9IFtdOwoJCQkJc2FtcGxlLk51bWJlck9mRW50cmllcyA9IHN0cmVhbS5yZWFkVWludDE2KCk7CgkJCQlmb3IgKHZhciBqID0gMDsgaiA8IHNhbXBsZS5OdW1iZXJPZkVudHJpZXM7IGorKykgewoJCQkJCXZhciBzdWJzYW1wbGUgPSB7fTsKCQkJCQlzdWJzYW1wbGUuQnl0ZXNPZkNsZWFyRGF0YSA9IHN0cmVhbS5yZWFkVWludDE2KCk7CgkJCQkJc3Vic2FtcGxlLkJ5dGVzT2ZQcm90ZWN0ZWREYXRhID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCQkJCQlzYW1wbGUuc3Vic2FtcGxlcy5wdXNoKHN1YnNhbXBsZSk7CgkJCQl9CgkJCX0KCQkJdGhpcy5zYW1wbGVzLnB1c2goc2FtcGxlKTsKCQl9Cgl9Ki8pOwoJLy8gZmlsZTpzcmMvcGFyc2luZy91dWlkL3BpZmYvcGlmZlRlbmMuanMKCUJveFBhcnNlci5jcmVhdGVVVUlEQm94KCI4OTc0ZGJjZTdiZTc0YzUxODRmOTcxNDhmOTg4MjU1NCIsIHRydWUsIGZhbHNlLCBmdW5jdGlvbihzdHJlYW0pIHsKCQl0aGlzLmRlZmF1bHRfQWxnb3JpdGhtSUQgPSBzdHJlYW0ucmVhZFVpbnQyNCgpOwoJCXRoaXMuZGVmYXVsdF9JVl9zaXplID0gc3RyZWFtLnJlYWRVaW50OCgpOwoJCXRoaXMuZGVmYXVsdF9LSUQgPSBCb3hQYXJzZXIucGFyc2VIZXgxNihzdHJlYW0pOwoJfSk7Ly8gZmlsZTpzcmMvcGFyc2luZy91dWlkL3BpZmYvcGlmZlRmcmYuanMKCUJveFBhcnNlci5jcmVhdGVVVUlEQm94KCJkNDgwN2VmMmNhMzk0Njk1OGU1NDI2Y2I5ZTQ2YTc5ZiIsIHRydWUsIGZhbHNlLCBmdW5jdGlvbihzdHJlYW0pIHsKCSAgICB0aGlzLmZyYWdtZW50X2NvdW50ID0gc3RyZWFtLnJlYWRVaW50OCgpOwoJICAgIHRoaXMuZW50cmllcyA9IFtdOwoKCSAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuZnJhZ21lbnRfY291bnQ7IGkrKykgewoJICAgICAgICB2YXIgZW50cnkgPSB7fTsKCSAgICAgICAgdmFyIGFic29sdXRlX3RpbWUgPSAwOwoJICAgICAgICB2YXIgYWJzb2x1dGVfZHVyYXRpb24gPSAwOwoKCSAgICAgICAgaWYgKHRoaXMudmVyc2lvbiA9PT0gMSkgewoJICAgICAgICAgICAgYWJzb2x1dGVfdGltZSA9IHN0cmVhbS5yZWFkVWludDY0KCk7CgkgICAgICAgICAgICBhYnNvbHV0ZV9kdXJhdGlvbiA9IHN0cmVhbS5yZWFkVWludDY0KCk7CgkgICAgICAgIH0gZWxzZSB7CgkgICAgICAgICAgICBhYnNvbHV0ZV90aW1lID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCSAgICAgICAgICAgIGFic29sdXRlX2R1cmF0aW9uID0gc3RyZWFtLnJlYWRVaW50MzIoKTsKCSAgICAgICAgfQoKCSAgICAgICAgZW50cnkuYWJzb2x1dGVfdGltZSA9IGFic29sdXRlX3RpbWU7CgkgICAgICAgIGVudHJ5LmFic29sdXRlX2R1cmF0aW9uID0gYWJzb2x1dGVfZHVyYXRpb247CgoJICAgICAgICB0aGlzLmVudHJpZXMucHVzaChlbnRyeSk7CgkgICAgfQoJfSk7Ly8gZmlsZTpzcmMvcGFyc2luZy91dWlkL3BpZmYvcGlmZlRmeGQuanMKCUJveFBhcnNlci5jcmVhdGVVVUlEQm94KCI2ZDFkOWIwNTQyZDU0NGU2ODBlMjE0MWRhZmY3NTdiMiIsIHRydWUsIGZhbHNlLCBmdW5jdGlvbihzdHJlYW0pIHsKCSAgICBpZiAodGhpcy52ZXJzaW9uID09PSAxKSB7CgkgICAgICAgdGhpcy5hYnNvbHV0ZV90aW1lID0gc3RyZWFtLnJlYWRVaW50NjQoKTsKCSAgICAgICB0aGlzLmR1cmF0aW9uID0gc3RyZWFtLnJlYWRVaW50NjQoKTsKCSAgICB9IGVsc2UgewoJICAgICAgIHRoaXMuYWJzb2x1dGVfdGltZSA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkgICAgICAgdGhpcy5kdXJhdGlvbiA9IHN0cmVhbS5yZWFkVWludDMyKCk7CgkgICAgfQoJfSk7Ly8gZmlsZTpzcmMvcGFyc2luZy92bWhkLmpzCglCb3hQYXJzZXIuY3JlYXRlRnVsbEJveEN0b3IoInZtaGQiLCBmdW5jdGlvbihzdHJlYW0pIHsKCQl0aGlzLmdyYXBoaWNzbW9kZSA9IHN0cmVhbS5yZWFkVWludDE2KCk7CgkJdGhpcy5vcGNvbG9yID0gc3RyZWFtLnJlYWRVaW50MTZBcnJheSgzKTsKCX0pOwoKCS8vIGZpbGU6c3JjL3BhcnNpbmcvdnBjQy5qcwoJQm94UGFyc2VyLmNyZWF0ZUZ1bGxCb3hDdG9yKCJ2cGNDIiwgZnVuY3Rpb24gKHN0cmVhbSkgewoJCXZhciB0bXA7CgkJaWYgKHRoaXMudmVyc2lvbiA9PT0gMSkgewoJCQl0aGlzLnByb2ZpbGUgPSBzdHJlYW0ucmVhZFVpbnQ4KCk7CgkJCXRoaXMubGV2ZWwgPSBzdHJlYW0ucmVhZFVpbnQ4KCk7CgkJCXRtcCA9IHN0cmVhbS5yZWFkVWludDgoKTsKCQkJdGhpcy5iaXREZXB0aCA9IHRtcCA+PiA0OwoJCQl0aGlzLmNocm9tYVN1YnNhbXBsaW5nID0gKHRtcCA+PiAxKSAmIDB4NzsKCQkJdGhpcy52aWRlb0Z1bGxSYW5nZUZsYWcgPSB0bXAgJiAweDE7CgkJCXRoaXMuY29sb3VyUHJpbWFyaWVzID0gc3RyZWFtLnJlYWRVaW50OCgpOwoJCQl0aGlzLnRyYW5zZmVyQ2hhcmFjdGVyaXN0aWNzID0gc3RyZWFtLnJlYWRVaW50OCgpOwoJCQl0aGlzLm1hdHJpeENvZWZmaWNpZW50cyA9IHN0cmVhbS5yZWFkVWludDgoKTsKCQkJdGhpcy5jb2RlY0ludGlhbGl6YXRpb25EYXRhU2l6ZSA9IHN0cmVhbS5yZWFkVWludDE2KCk7CgkJCXRoaXMuY29kZWNJbnRpYWxpemF0aW9uRGF0YSA9IHN0cmVhbS5yZWFkVWludDhBcnJheSh0aGlzLmNvZGVjSW50aWFsaXphdGlvbkRhdGFTaXplKTsKCQl9IGVsc2UgewoJCQl0aGlzLnByb2ZpbGUgPSBzdHJlYW0ucmVhZFVpbnQ4KCk7CgkJCXRoaXMubGV2ZWwgPSBzdHJlYW0ucmVhZFVpbnQ4KCk7CgkJCXRtcCA9IHN0cmVhbS5yZWFkVWludDgoKTsKCQkJdGhpcy5iaXREZXB0aCA9ICh0bXAgPj4gNCkgJiAweEY7CgkJCXRoaXMuY29sb3JTcGFjZSA9IHRtcCAmIDB4RjsKCQkJdG1wID0gc3RyZWFtLnJlYWRVaW50OCgpOwoJCQl0aGlzLmNocm9tYVN1YnNhbXBsaW5nID0gKHRtcCA+PiA0KSAmIDB4RjsKCQkJdGhpcy50cmFuc2ZlckZ1bmN0aW9uID0gKHRtcCA+PiAxKSAmIDB4NzsKCQkJdGhpcy52aWRlb0Z1bGxSYW5nZUZsYWcgPSB0bXAgJiAweDE7CgkJCXRoaXMuY29kZWNJbnRpYWxpemF0aW9uRGF0YVNpemUgPSBzdHJlYW0ucmVhZFVpbnQxNigpOwoJCQl0aGlzLmNvZGVjSW50aWFsaXphdGlvbkRhdGEgPSBzdHJlYW0ucmVhZFVpbnQ4QXJyYXkodGhpcy5jb2RlY0ludGlhbGl6YXRpb25EYXRhU2l6ZSk7CgkJfQoJfSk7Ly8gZmlsZTpzcmMvcGFyc2luZy92dHRDLmpzCglCb3hQYXJzZXIuY3JlYXRlQm94Q3RvcigidnR0QyIsIGZ1bmN0aW9uKHN0cmVhbSkgewoJCXRoaXMudGV4dCA9IHN0cmVhbS5yZWFkU3RyaW5nKHRoaXMuc2l6ZSAtIHRoaXMuaGRyX3NpemUpOwoJfSk7CgoJLy8gZmlsZTpzcmMvcGFyc2luZy92dmNDLmpzCglCb3hQYXJzZXIuY3JlYXRlRnVsbEJveEN0b3IoInZ2Y0MiLCBmdW5jdGlvbiAoc3RyZWFtKSB7CgkgIHZhciBpLCBqOwoKCSAgLy8gaGVscGVyIG9iamVjdCB0byBzaW1wbGlmeSBleHRyYWN0aW5nIGluZGl2aWR1YWwgYml0cwoJICB2YXIgYml0UmVhZGVyID0gewoJICAgIGhlbGRfYml0czogdW5kZWZpbmVkLAoJICAgIG51bV9oZWxkX2JpdHM6IDAsCgoJICAgIHN0cmVhbV9yZWFkXzFfYnl0ZXM6IGZ1bmN0aW9uIChzdHJtKSB7CgkgICAgICB0aGlzLmhlbGRfYml0cyA9IHN0cm0ucmVhZFVpbnQ4KCk7CgkgICAgICB0aGlzLm51bV9oZWxkX2JpdHMgPSAxICogODsKCSAgICB9LAoJICAgIHN0cmVhbV9yZWFkXzJfYnl0ZXM6IGZ1bmN0aW9uIChzdHJtKSB7CgkgICAgICB0aGlzLmhlbGRfYml0cyA9IHN0cm0ucmVhZFVpbnQxNigpOwoJICAgICAgdGhpcy5udW1faGVsZF9iaXRzID0gMiAqIDg7CgkgICAgfSwKCgkgICAgZXh0cmFjdF9iaXRzOiBmdW5jdGlvbiAobnVtX2JpdHMpIHsKCSAgICAgIHZhciByZXQgPSAodGhpcy5oZWxkX2JpdHMgPj4gKHRoaXMubnVtX2hlbGRfYml0cyAtIG51bV9iaXRzKSkgJiAoKDEgPDwgbnVtX2JpdHMpIC0gMSk7CgkgICAgICB0aGlzLm51bV9oZWxkX2JpdHMgLT0gbnVtX2JpdHM7CgkgICAgICByZXR1cm4gcmV0OwoJICAgIH0KCSAgfTsKCgkgIC8vIFZ2Y0RlY29kZXJDb25maWd1cmF0aW9uUmVjb3JkCgkgIGJpdFJlYWRlci5zdHJlYW1fcmVhZF8xX2J5dGVzKHN0cmVhbSk7CgkgIGJpdFJlYWRlci5leHRyYWN0X2JpdHMoNSk7ICAvLyByZXNlcnZlZAoJICB0aGlzLmxlbmd0aFNpemVNaW51c09uZSA9IGJpdFJlYWRlci5leHRyYWN0X2JpdHMoMik7CgkgIHRoaXMucHRsX3ByZXNlbnRfZmxhZyA9IGJpdFJlYWRlci5leHRyYWN0X2JpdHMoMSk7CgoJICBpZiAodGhpcy5wdGxfcHJlc2VudF9mbGFnKSB7CgkgICAgYml0UmVhZGVyLnN0cmVhbV9yZWFkXzJfYnl0ZXMoc3RyZWFtKTsKCSAgICB0aGlzLm9sc19pZHggPSBiaXRSZWFkZXIuZXh0cmFjdF9iaXRzKDkpOwoJICAgIHRoaXMubnVtX3N1YmxheWVycyA9IGJpdFJlYWRlci5leHRyYWN0X2JpdHMoMyk7CgkgICAgdGhpcy5jb25zdGFudF9mcmFtZV9yYXRlID0gYml0UmVhZGVyLmV4dHJhY3RfYml0cygyKTsKCSAgICB0aGlzLmNocm9tYV9mb3JtYXRfaWRjID0gYml0UmVhZGVyLmV4dHJhY3RfYml0cygyKTsKCgkgICAgYml0UmVhZGVyLnN0cmVhbV9yZWFkXzFfYnl0ZXMoc3RyZWFtKTsKCSAgICB0aGlzLmJpdF9kZXB0aF9taW51czggPSBiaXRSZWFkZXIuZXh0cmFjdF9iaXRzKDMpOwoJICAgIGJpdFJlYWRlci5leHRyYWN0X2JpdHMoNSk7ICAvLyByZXNlcnZlZAoKCSAgICAvLyBWdmNQVExSZWNvcmQKCSAgICB7CgkgICAgICBiaXRSZWFkZXIuc3RyZWFtX3JlYWRfMl9ieXRlcyhzdHJlYW0pOwoJICAgICAgYml0UmVhZGVyLmV4dHJhY3RfYml0cygyKTsgIC8vIHJlc2VydmVkCgkgICAgICB0aGlzLm51bV9ieXRlc19jb25zdHJhaW50X2luZm8gPSBiaXRSZWFkZXIuZXh0cmFjdF9iaXRzKDYpOwoJICAgICAgdGhpcy5nZW5lcmFsX3Byb2ZpbGVfaWRjID0gYml0UmVhZGVyLmV4dHJhY3RfYml0cyg3KTsKCSAgICAgIHRoaXMuZ2VuZXJhbF90aWVyX2ZsYWcgPSBiaXRSZWFkZXIuZXh0cmFjdF9iaXRzKDEpOwoKCSAgICAgIHRoaXMuZ2VuZXJhbF9sZXZlbF9pZGMgPSBzdHJlYW0ucmVhZFVpbnQ4KCk7CgoJICAgICAgYml0UmVhZGVyLnN0cmVhbV9yZWFkXzFfYnl0ZXMoc3RyZWFtKTsKCSAgICAgIHRoaXMucHRsX2ZyYW1lX29ubHlfY29uc3RyYWludF9mbGFnID0gYml0UmVhZGVyLmV4dHJhY3RfYml0cygxKTsKCSAgICAgIHRoaXMucHRsX211bHRpbGF5ZXJfZW5hYmxlZF9mbGFnID0gYml0UmVhZGVyLmV4dHJhY3RfYml0cygxKTsKCgkgICAgICB0aGlzLmdlbmVyYWxfY29uc3RyYWludF9pbmZvID0gbmV3IFVpbnQ4QXJyYXkodGhpcy5udW1fYnl0ZXNfY29uc3RyYWludF9pbmZvKTsKCSAgICAgIGlmICh0aGlzLm51bV9ieXRlc19jb25zdHJhaW50X2luZm8pIHsKCSAgICAgICAgZm9yIChpID0gMDsgaSA8IHRoaXMubnVtX2J5dGVzX2NvbnN0cmFpbnRfaW5mbyAtIDE7IGkrKykgewoJICAgICAgICAgIHZhciBjbnN0cjEgPSBiaXRSZWFkZXIuZXh0cmFjdF9iaXRzKDYpOwoJICAgICAgICAgIGJpdFJlYWRlci5zdHJlYW1fcmVhZF8xX2J5dGVzKHN0cmVhbSk7CgkgICAgICAgICAgdmFyIGNuc3RyMiA9IGJpdFJlYWRlci5leHRyYWN0X2JpdHMoMik7CgoJICAgICAgICAgIHRoaXMuZ2VuZXJhbF9jb25zdHJhaW50X2luZm9baV0gPSAoKGNuc3RyMSA8PCAyKSB8IGNuc3RyMik7CgkgICAgICAgIH0KCSAgICAgICAgdGhpcy5nZW5lcmFsX2NvbnN0cmFpbnRfaW5mb1t0aGlzLm51bV9ieXRlc19jb25zdHJhaW50X2luZm8gLSAxXSA9IGJpdFJlYWRlci5leHRyYWN0X2JpdHMoNik7CgkgICAgICB9IGVsc2UgewoJICAgICAgICAvL2ZvcmJpZGRlbiBpbiBzcGVjIQoJICAgICAgICBiaXRSZWFkZXIuZXh0cmFjdF9iaXRzKDYpOwoJICAgICAgfQoKCSAgICAgIGJpdFJlYWRlci5zdHJlYW1fcmVhZF8xX2J5dGVzKHN0cmVhbSk7CgkgICAgICB0aGlzLnB0bF9zdWJsYXllcl9wcmVzZW50X21hc2sgPSAwOwoJICAgICAgZm9yIChqID0gdGhpcy5udW1fc3VibGF5ZXJzIC0gMjsgaiA+PSAwOyAtLWopIHsKCSAgICAgICAgdmFyIHZhbCA9IGJpdFJlYWRlci5leHRyYWN0X2JpdHMoMSk7CgkgICAgICAgIHRoaXMucHRsX3N1YmxheWVyX3ByZXNlbnRfbWFzayB8PSB2YWwgPDwgajsKCSAgICAgIH0KCSAgICAgIGZvciAoaiA9IHRoaXMubnVtX3N1YmxheWVyczsgaiA8PSA4ICYmIHRoaXMubnVtX3N1YmxheWVycyA+IDE7ICsraikgewoJICAgICAgICBiaXRSZWFkZXIuZXh0cmFjdF9iaXRzKDEpOyAgLy8gcHRsX3Jlc2VydmVkX3plcm9fYml0CgkgICAgICB9CgoJICAgICAgZm9yIChqID0gdGhpcy5udW1fc3VibGF5ZXJzIC0gMjsgaiA+PSAwOyAtLWopIHsKCSAgICAgICAgaWYgKHRoaXMucHRsX3N1YmxheWVyX3ByZXNlbnRfbWFzayAmICgxIDw8IGopKSB7CgkgICAgICAgICAgdGhpcy5zdWJsYXllcl9sZXZlbF9pZGNbal0gPSBzdHJlYW0ucmVhZFVpbnQ4KCk7CgkgICAgICAgIH0KCSAgICAgIH0KCgkgICAgICB0aGlzLnB0bF9udW1fc3ViX3Byb2ZpbGVzID0gc3RyZWFtLnJlYWRVaW50OCgpOwoJICAgICAgdGhpcy5nZW5lcmFsX3N1Yl9wcm9maWxlX2lkYyA9IFtdOwoJICAgICAgaWYgKHRoaXMucHRsX251bV9zdWJfcHJvZmlsZXMpIHsKCSAgICAgICAgZm9yIChpID0gMDsgaSA8IHRoaXMucHRsX251bV9zdWJfcHJvZmlsZXM7IGkrKykgewoJICAgICAgICAgIHRoaXMuZ2VuZXJhbF9zdWJfcHJvZmlsZV9pZGMucHVzaChzdHJlYW0ucmVhZFVpbnQzMigpKTsKCSAgICAgICAgfQoJICAgICAgfQoJICAgIH0gIC8vIGVuZCBWdmNQVExSZWNvcmQKCgkgICAgdGhpcy5tYXhfcGljdHVyZV93aWR0aCA9IHN0cmVhbS5yZWFkVWludDE2KCk7CgkgICAgdGhpcy5tYXhfcGljdHVyZV9oZWlnaHQgPSBzdHJlYW0ucmVhZFVpbnQxNigpOwoJICAgIHRoaXMuYXZnX2ZyYW1lX3JhdGUgPSBzdHJlYW0ucmVhZFVpbnQxNigpOwoJICB9CgoJICB2YXIgVlZDX05BTFVfT1BJID0gMTI7CgkgIHZhciBWVkNfTkFMVV9ERUNfUEFSQU0gPSAxMzsKCgkgIHRoaXMubmFsdV9hcnJheXMgPSBbXTsKCSAgdmFyIG51bV9vZl9hcnJheXMgPSBzdHJlYW0ucmVhZFVpbnQ4KCk7CgkgIGZvciAoaSA9IDA7IGkgPCBudW1fb2ZfYXJyYXlzOyBpKyspIHsKCSAgICB2YXIgbmFsdV9hcnJheSA9IFtdOwoJICAgIHRoaXMubmFsdV9hcnJheXMucHVzaChuYWx1X2FycmF5KTsKCgkgICAgYml0UmVhZGVyLnN0cmVhbV9yZWFkXzFfYnl0ZXMoc3RyZWFtKTsKCSAgICBuYWx1X2FycmF5LmNvbXBsZXRlbmVzcyA9IGJpdFJlYWRlci5leHRyYWN0X2JpdHMoMSk7CgkgICAgYml0UmVhZGVyLmV4dHJhY3RfYml0cygyKTsgIC8vIHJlc2VydmVkCgkgICAgbmFsdV9hcnJheS5uYWx1X3R5cGUgPSBiaXRSZWFkZXIuZXh0cmFjdF9iaXRzKDUpOwoKCSAgICB2YXIgbnVtTmFsdXMgPSAxOwoJICAgIGlmIChuYWx1X2FycmF5Lm5hbHVfdHlwZSAhPSBWVkNfTkFMVV9ERUNfUEFSQU0gJiYgbmFsdV9hcnJheS5uYWx1X3R5cGUgIT0gVlZDX05BTFVfT1BJKSB7CgkgICAgICBudW1OYWx1cyA9IHN0cmVhbS5yZWFkVWludDE2KCk7CgkgICAgfQoKCSAgICBmb3IgKGogPSAwOyBqIDwgbnVtTmFsdXM7IGorKykgewoJICAgICAgdmFyIGxlbiA9IHN0cmVhbS5yZWFkVWludDE2KCk7CgkgICAgICBuYWx1X2FycmF5LnB1c2goewoJICAgICAgICBkYXRhOiBzdHJlYW0ucmVhZFVpbnQ4QXJyYXkobGVuKSwKCSAgICAgICAgbGVuZ3RoOiBsZW4KCSAgICAgIH0pOwoJICAgIH0KCSAgfQoJfSk7CgkvLyBmaWxlOnNyYy9wYXJzaW5nL3Z2bkMuanMKCUJveFBhcnNlci5jcmVhdGVGdWxsQm94Q3RvcigidnZuQyIsIGZ1bmN0aW9uIChzdHJlYW0pIHsKCSAgLy8gVnZjTkFMVUNvbmZpZ0JveAoJICB2YXIgdG1wID0gc3RybS5yZWFkVWludDgoKTsKCSAgdGhpcy5sZW5ndGhTaXplTWludXNPbmUgPSAodG1wICYgMHgzKTsKCX0pOwoJLy8gZmlsZTpzcmMvYm94LWNvZGVjcy5qcwoJQm94UGFyc2VyLlNhbXBsZUVudHJ5LnByb3RvdHlwZS5pc1ZpZGVvID0gZnVuY3Rpb24oKSB7CgkJcmV0dXJuIGZhbHNlOwoJfTsKCglCb3hQYXJzZXIuU2FtcGxlRW50cnkucHJvdG90eXBlLmlzQXVkaW8gPSBmdW5jdGlvbigpIHsKCQlyZXR1cm4gZmFsc2U7Cgl9OwoKCUJveFBhcnNlci5TYW1wbGVFbnRyeS5wcm90b3R5cGUuaXNTdWJ0aXRsZSA9IGZ1bmN0aW9uKCkgewoJCXJldHVybiBmYWxzZTsKCX07CgoJQm94UGFyc2VyLlNhbXBsZUVudHJ5LnByb3RvdHlwZS5pc01ldGFkYXRhID0gZnVuY3Rpb24oKSB7CgkJcmV0dXJuIGZhbHNlOwoJfTsKCglCb3hQYXJzZXIuU2FtcGxlRW50cnkucHJvdG90eXBlLmlzSGludCA9IGZ1bmN0aW9uKCkgewoJCXJldHVybiBmYWxzZTsKCX07CgoJQm94UGFyc2VyLlNhbXBsZUVudHJ5LnByb3RvdHlwZS5nZXRDb2RlYyA9IGZ1bmN0aW9uKCkgewoJCXJldHVybiB0aGlzLnR5cGUucmVwbGFjZSgnLicsJycpOwoJfTsKCglCb3hQYXJzZXIuU2FtcGxlRW50cnkucHJvdG90eXBlLmdldFdpZHRoID0gZnVuY3Rpb24oKSB7CgkJcmV0dXJuICIiOwoJfTsKCglCb3hQYXJzZXIuU2FtcGxlRW50cnkucHJvdG90eXBlLmdldEhlaWdodCA9IGZ1bmN0aW9uKCkgewoJCXJldHVybiAiIjsKCX07CgoJQm94UGFyc2VyLlNhbXBsZUVudHJ5LnByb3RvdHlwZS5nZXRDaGFubmVsQ291bnQgPSBmdW5jdGlvbigpIHsKCQlyZXR1cm4gIiI7Cgl9OwoKCUJveFBhcnNlci5TYW1wbGVFbnRyeS5wcm90b3R5cGUuZ2V0U2FtcGxlUmF0ZSA9IGZ1bmN0aW9uKCkgewoJCXJldHVybiAiIjsKCX07CgoJQm94UGFyc2VyLlNhbXBsZUVudHJ5LnByb3RvdHlwZS5nZXRTYW1wbGVTaXplID0gZnVuY3Rpb24oKSB7CgkJcmV0dXJuICIiOwoJfTsKCglCb3hQYXJzZXIuVmlzdWFsU2FtcGxlRW50cnkucHJvdG90eXBlLmlzVmlkZW8gPSBmdW5jdGlvbigpIHsKCQlyZXR1cm4gdHJ1ZTsKCX07CgoJQm94UGFyc2VyLlZpc3VhbFNhbXBsZUVudHJ5LnByb3RvdHlwZS5nZXRXaWR0aCA9IGZ1bmN0aW9uKCkgewoJCXJldHVybiB0aGlzLndpZHRoOwoJfTsKCglCb3hQYXJzZXIuVmlzdWFsU2FtcGxlRW50cnkucHJvdG90eXBlLmdldEhlaWdodCA9IGZ1bmN0aW9uKCkgewoJCXJldHVybiB0aGlzLmhlaWdodDsKCX07CgoJQm94UGFyc2VyLkF1ZGlvU2FtcGxlRW50cnkucHJvdG90eXBlLmlzQXVkaW8gPSBmdW5jdGlvbigpIHsKCQlyZXR1cm4gdHJ1ZTsKCX07CgoJQm94UGFyc2VyLkF1ZGlvU2FtcGxlRW50cnkucHJvdG90eXBlLmdldENoYW5uZWxDb3VudCA9IGZ1bmN0aW9uKCkgewoJCXJldHVybiB0aGlzLmNoYW5uZWxfY291bnQ7Cgl9OwoKCUJveFBhcnNlci5BdWRpb1NhbXBsZUVudHJ5LnByb3RvdHlwZS5nZXRTYW1wbGVSYXRlID0gZnVuY3Rpb24oKSB7CgkJcmV0dXJuIHRoaXMuc2FtcGxlcmF0ZTsKCX07CgoJQm94UGFyc2VyLkF1ZGlvU2FtcGxlRW50cnkucHJvdG90eXBlLmdldFNhbXBsZVNpemUgPSBmdW5jdGlvbigpIHsKCQlyZXR1cm4gdGhpcy5zYW1wbGVzaXplOwoJfTsKCglCb3hQYXJzZXIuU3VidGl0bGVTYW1wbGVFbnRyeS5wcm90b3R5cGUuaXNTdWJ0aXRsZSA9IGZ1bmN0aW9uKCkgewoJCXJldHVybiB0cnVlOwoJfTsKCglCb3hQYXJzZXIuTWV0YWRhdGFTYW1wbGVFbnRyeS5wcm90b3R5cGUuaXNNZXRhZGF0YSA9IGZ1bmN0aW9uKCkgewoJCXJldHVybiB0cnVlOwoJfTsKCgoJQm94UGFyc2VyLmRlY2ltYWxUb0hleCA9IGZ1bmN0aW9uKGQsIHBhZGRpbmcpIHsKCQl2YXIgaGV4ID0gTnVtYmVyKGQpLnRvU3RyaW5nKDE2KTsKCQlwYWRkaW5nID0gdHlwZW9mIChwYWRkaW5nKSA9PT0gInVuZGVmaW5lZCIgfHwgcGFkZGluZyA9PT0gbnVsbCA/IHBhZGRpbmcgPSAyIDogcGFkZGluZzsKCQl3aGlsZSAoaGV4Lmxlbmd0aCA8IHBhZGRpbmcpIHsKCQkJaGV4ID0gIjAiICsgaGV4OwoJCX0KCQlyZXR1cm4gaGV4OwoJfTsKCglCb3hQYXJzZXIuYXZjMVNhbXBsZUVudHJ5LnByb3RvdHlwZS5nZXRDb2RlYyA9CglCb3hQYXJzZXIuYXZjMlNhbXBsZUVudHJ5LnByb3RvdHlwZS5nZXRDb2RlYyA9CglCb3hQYXJzZXIuYXZjM1NhbXBsZUVudHJ5LnByb3RvdHlwZS5nZXRDb2RlYyA9CglCb3hQYXJzZXIuYXZjNFNhbXBsZUVudHJ5LnByb3RvdHlwZS5nZXRDb2RlYyA9IGZ1bmN0aW9uKCkgewoJCXZhciBiYXNlQ29kZWMgPSBCb3hQYXJzZXIuU2FtcGxlRW50cnkucHJvdG90eXBlLmdldENvZGVjLmNhbGwodGhpcyk7CgkJaWYgKHRoaXMuYXZjQykgewoJCQlyZXR1cm4gYmFzZUNvZGVjKyIuIitCb3hQYXJzZXIuZGVjaW1hbFRvSGV4KHRoaXMuYXZjQy5BVkNQcm9maWxlSW5kaWNhdGlvbikrCgkJCQkJCQkgICIiK0JveFBhcnNlci5kZWNpbWFsVG9IZXgodGhpcy5hdmNDLnByb2ZpbGVfY29tcGF0aWJpbGl0eSkrCgkJCQkJCQkgICIiK0JveFBhcnNlci5kZWNpbWFsVG9IZXgodGhpcy5hdmNDLkFWQ0xldmVsSW5kaWNhdGlvbik7CgkJfSBlbHNlIHsKCQkJcmV0dXJuIGJhc2VDb2RlYzsKCQl9Cgl9OwoKCUJveFBhcnNlci5oZXYxU2FtcGxlRW50cnkucHJvdG90eXBlLmdldENvZGVjID0KCUJveFBhcnNlci5odmMxU2FtcGxlRW50cnkucHJvdG90eXBlLmdldENvZGVjID0gZnVuY3Rpb24oKSB7CgkJdmFyIGk7CgkJdmFyIGJhc2VDb2RlYyA9IEJveFBhcnNlci5TYW1wbGVFbnRyeS5wcm90b3R5cGUuZ2V0Q29kZWMuY2FsbCh0aGlzKTsKCQlpZiAodGhpcy5odmNDKSB7CgkJCWJhc2VDb2RlYyArPSAnLic7CgkJCXN3aXRjaCAodGhpcy5odmNDLmdlbmVyYWxfcHJvZmlsZV9zcGFjZSkgewoJCQkJY2FzZSAwOgoJCQkJCWJhc2VDb2RlYyArPSAnJzsKCQkJCQlicmVhazsKCQkJCWNhc2UgMToKCQkJCQliYXNlQ29kZWMgKz0gJ0EnOwoJCQkJCWJyZWFrOwoJCQkJY2FzZSAyOgoJCQkJCWJhc2VDb2RlYyArPSAnQic7CgkJCQkJYnJlYWs7CgkJCQljYXNlIDM6CgkJCQkJYmFzZUNvZGVjICs9ICdDJzsKCQkJCQlicmVhazsKCQkJfQoJCQliYXNlQ29kZWMgKz0gdGhpcy5odmNDLmdlbmVyYWxfcHJvZmlsZV9pZGM7CgkJCWJhc2VDb2RlYyArPSAnLic7CgkJCXZhciB2YWwgPSB0aGlzLmh2Y0MuZ2VuZXJhbF9wcm9maWxlX2NvbXBhdGliaWxpdHk7CgkJCXZhciByZXZlcnNlZCA9IDA7CgkJCWZvciAoaT0wOyBpPDMyOyBpKyspIHsKCQkJCXJldmVyc2VkIHw9IHZhbCAmIDE7CgkJCQlpZiAoaT09MzEpIGJyZWFrOwoJCQkJcmV2ZXJzZWQgPDw9IDE7CgkJCQl2YWwgPj49MTsKCQkJfQoJCQliYXNlQ29kZWMgKz0gQm94UGFyc2VyLmRlY2ltYWxUb0hleChyZXZlcnNlZCwgMCk7CgkJCWJhc2VDb2RlYyArPSAnLic7CgkJCWlmICh0aGlzLmh2Y0MuZ2VuZXJhbF90aWVyX2ZsYWcgPT09IDApIHsKCQkJCWJhc2VDb2RlYyArPSAnTCc7CgkJCX0gZWxzZSB7CgkJCQliYXNlQ29kZWMgKz0gJ0gnOwoJCQl9CgkJCWJhc2VDb2RlYyArPSB0aGlzLmh2Y0MuZ2VuZXJhbF9sZXZlbF9pZGM7CgkJCXZhciBoYXNCeXRlID0gZmFsc2U7CgkJCXZhciBjb25zdHJhaW50X3N0cmluZyA9ICIiOwoJCQlmb3IgKGkgPSA1OyBpID49IDA7IGktLSkgewoJCQkJaWYgKHRoaXMuaHZjQy5nZW5lcmFsX2NvbnN0cmFpbnRfaW5kaWNhdG9yW2ldIHx8IGhhc0J5dGUpIHsKCQkJCQljb25zdHJhaW50X3N0cmluZyA9ICIuIitCb3hQYXJzZXIuZGVjaW1hbFRvSGV4KHRoaXMuaHZjQy5nZW5lcmFsX2NvbnN0cmFpbnRfaW5kaWNhdG9yW2ldLCAwKStjb25zdHJhaW50X3N0cmluZzsKCQkJCQloYXNCeXRlID0gdHJ1ZTsKCQkJCX0KCQkJfQoJCQliYXNlQ29kZWMgKz0gY29uc3RyYWludF9zdHJpbmc7CgkJfQoJCXJldHVybiBiYXNlQ29kZWM7Cgl9OwoKCUJveFBhcnNlci52dmMxU2FtcGxlRW50cnkucHJvdG90eXBlLmdldENvZGVjID0KCUJveFBhcnNlci52dmkxU2FtcGxlRW50cnkucHJvdG90eXBlLmdldENvZGVjID0gZnVuY3Rpb24gKCkgewoJCXZhciBpOwoJCXZhciBiYXNlQ29kZWMgPSBCb3hQYXJzZXIuU2FtcGxlRW50cnkucHJvdG90eXBlLmdldENvZGVjLmNhbGwodGhpcyk7CgkJaWYgKHRoaXMudnZjQykgewoJCQliYXNlQ29kZWMgKz0gJy4nICsgdGhpcy52dmNDLmdlbmVyYWxfcHJvZmlsZV9pZGM7CgkJCWlmICh0aGlzLnZ2Y0MuZ2VuZXJhbF90aWVyX2ZsYWcpIHsKCQkJCWJhc2VDb2RlYyArPSAnLkgnOwoJCQl9IGVsc2UgewoJCQkJYmFzZUNvZGVjICs9ICcuTCc7CgkJCX0KCQkJYmFzZUNvZGVjICs9IHRoaXMudnZjQy5nZW5lcmFsX2xldmVsX2lkYzsKCgkJCXZhciBjb25zdHJhaW50X3N0cmluZyA9ICIiOwoJCQlpZiAodGhpcy52dmNDLmdlbmVyYWxfY29uc3RyYWludF9pbmZvKSB7CgkJCQl2YXIgYnl0ZXMgPSBbXTsKCQkJCXZhciBieXRlID0gMDsKCQkJCWJ5dGUgfD0gdGhpcy52dmNDLnB0bF9mcmFtZV9vbmx5X2NvbnN0cmFpbnQgPDwgNzsKCQkJCWJ5dGUgfD0gdGhpcy52dmNDLnB0bF9tdWx0aWxheWVyX2VuYWJsZWQgPDwgNjsKCQkJCXZhciBsYXN0X25vbnplcm87CgkJCQlmb3IgKGkgPSAwOyBpIDwgdGhpcy52dmNDLmdlbmVyYWxfY29uc3RyYWludF9pbmZvLmxlbmd0aDsgKytpKSB7CgkJCQkJYnl0ZSB8PSAodGhpcy52dmNDLmdlbmVyYWxfY29uc3RyYWludF9pbmZvW2ldID4+IDIpICYgMHgzZjsKCQkJCQlieXRlcy5wdXNoKGJ5dGUpOwoJCQkJCWlmIChieXRlKSB7CgkJCQkJCWxhc3Rfbm9uemVybyA9IGk7CgkJCQkJfQoKCQkJCQlieXRlID0gKHRoaXMudnZjQy5nZW5lcmFsX2NvbnN0cmFpbnRfaW5mb1tpXSA+PiAyKSAmIDB4MDM7CgkJCQl9CgoJCQkJaWYgKGxhc3Rfbm9uemVybyA9PT0gdW5kZWZpbmVkKSB7CgkJCQkJY29uc3RyYWludF9zdHJpbmcgPSAiLkNBIjsKCQkJCX0KCQkJCWVsc2UgewoJCQkJCWNvbnN0cmFpbnRfc3RyaW5nID0gIi5DIjsKCQkJCQl2YXIgYmFzZTMyX2NoYXJzID0gIkFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaMjM0NTY3IjsKCQkJCQl2YXIgaGVsZF9iaXRzID0gMDsKCQkJCQl2YXIgbnVtX2hlbGRfYml0cyA9IDA7CgkJCQkJZm9yIChpID0gMDsgaSA8PSBsYXN0X25vbnplcm87ICsraSkgewoJCQkJCQloZWxkX2JpdHMgPSAoaGVsZF9iaXRzIDw8IDgpIHwgYnl0ZXNbaV07CgkJCQkJCW51bV9oZWxkX2JpdHMgKz0gODsKCgkJCQkJCXdoaWxlIChudW1faGVsZF9iaXRzID49IDUpIHsKCQkJCQkJCXZhciB2YWwgPSAoaGVsZF9iaXRzID4+IChudW1faGVsZF9iaXRzIC0gNSkpICYgMHgxZjsKCQkJCQkJCWNvbnN0cmFpbnRfc3RyaW5nICs9IGJhc2UzMl9jaGFyc1t2YWxdOwoKCQkJCQkJCW51bV9oZWxkX2JpdHMgLT0gNTsKCQkJCQkJCWhlbGRfYml0cyAmPSAoMSA8PCBudW1faGVsZF9iaXRzKSAtIDE7CgkJCQkJCX0KCQkJCQl9CgkJCQkJaWYgKG51bV9oZWxkX2JpdHMpIHsKCQkJCQkJaGVsZF9iaXRzIDw8PSAoNSAtIG51bV9oZWxkX2JpdHMpOyAgLy8gcmlnaHQtcGFkIHdpdGggemVyb3MgdG8gNSBiaXRzIChpcyB0aGlzIGNvcnJlY3Q/KQoJCQkJCQljb25zdHJhaW50X3N0cmluZyArPSBiYXNlMzJfY2hhcnNbaGVsZF9iaXRzICYgMHgxZl07CgkJCQkJfQoJCQkJfQoJCQl9CgkJCWJhc2VDb2RlYyArPSBjb25zdHJhaW50X3N0cmluZzsKCQl9CgkJcmV0dXJuIGJhc2VDb2RlYzsKCX07CgoJQm94UGFyc2VyLm1wNGFTYW1wbGVFbnRyeS5wcm90b3R5cGUuZ2V0Q29kZWMgPSBmdW5jdGlvbigpIHsKCQl2YXIgYmFzZUNvZGVjID0gQm94UGFyc2VyLlNhbXBsZUVudHJ5LnByb3RvdHlwZS5nZXRDb2RlYy5jYWxsKHRoaXMpOwoJCWlmICh0aGlzLmVzZHMgJiYgdGhpcy5lc2RzLmVzZCkgewoJCQl2YXIgb3RpID0gdGhpcy5lc2RzLmVzZC5nZXRPVEkoKTsKCQkJdmFyIGRzaSA9IHRoaXMuZXNkcy5lc2QuZ2V0QXVkaW9Db25maWcoKTsKCQkJcmV0dXJuIGJhc2VDb2RlYysiLiIrQm94UGFyc2VyLmRlY2ltYWxUb0hleChvdGkpKyhkc2kgPyAiLiIrZHNpOiAiIik7CgkJfSBlbHNlIHsKCQkJcmV0dXJuIGJhc2VDb2RlYzsKCQl9Cgl9OwoKCUJveFBhcnNlci5zdHh0U2FtcGxlRW50cnkucHJvdG90eXBlLmdldENvZGVjID0gZnVuY3Rpb24oKSB7CgkJdmFyIGJhc2VDb2RlYyA9IEJveFBhcnNlci5TYW1wbGVFbnRyeS5wcm90b3R5cGUuZ2V0Q29kZWMuY2FsbCh0aGlzKTsKCQlpZih0aGlzLm1pbWVfZm9ybWF0KSB7CgkJCXJldHVybiBiYXNlQ29kZWMgKyAiLiIgKyB0aGlzLm1pbWVfZm9ybWF0OwoJCX0gZWxzZSB7CgkJCXJldHVybiBiYXNlQ29kZWMKCQl9Cgl9OwoKCUJveFBhcnNlci52cDA4U2FtcGxlRW50cnkucHJvdG90eXBlLmdldENvZGVjID0KCUJveFBhcnNlci52cDA5U2FtcGxlRW50cnkucHJvdG90eXBlLmdldENvZGVjID0gZnVuY3Rpb24oKSB7CgkJdmFyIGJhc2VDb2RlYyA9IEJveFBhcnNlci5TYW1wbGVFbnRyeS5wcm90b3R5cGUuZ2V0Q29kZWMuY2FsbCh0aGlzKTsKCQl2YXIgbGV2ZWwgPSB0aGlzLnZwY0MubGV2ZWw7CgkJaWYgKGxldmVsID09IDApIHsKCQkJbGV2ZWwgPSAiMDAiOwoJCX0KCQl2YXIgYml0RGVwdGggPSB0aGlzLnZwY0MuYml0RGVwdGg7CgkJaWYgKGJpdERlcHRoID09IDgpIHsKCQkJYml0RGVwdGggPSAiMDgiOwoJCX0KCQlyZXR1cm4gYmFzZUNvZGVjICsgIi4wIiArIHRoaXMudnBjQy5wcm9maWxlICsgIi4iICsgbGV2ZWwgKyAiLiIgKyBiaXREZXB0aDsKCX07CgoJQm94UGFyc2VyLmF2MDFTYW1wbGVFbnRyeS5wcm90b3R5cGUuZ2V0Q29kZWMgPSBmdW5jdGlvbigpIHsKCQl2YXIgYmFzZUNvZGVjID0gQm94UGFyc2VyLlNhbXBsZUVudHJ5LnByb3RvdHlwZS5nZXRDb2RlYy5jYWxsKHRoaXMpOwoJCXZhciBsZXZlbCA9IHRoaXMuYXYxQy5zZXFfbGV2ZWxfaWR4XzA7CgkJaWYgKGxldmVsIDwgMTApIHsKCQkJbGV2ZWwgPSAiMCIgKyBsZXZlbDsKCQl9CgkJdmFyIGJpdGRlcHRoOwoJCWlmICh0aGlzLmF2MUMuc2VxX3Byb2ZpbGUgPT09IDIgJiYgdGhpcy5hdjFDLmhpZ2hfYml0ZGVwdGggPT09IDEpIHsKCQkJYml0ZGVwdGggPSAodGhpcy5hdjFDLnR3ZWx2ZV9iaXQgPT09IDEpID8gIjEyIiA6ICIxMCI7CgkJfSBlbHNlIGlmICggdGhpcy5hdjFDLnNlcV9wcm9maWxlIDw9IDIgKSB7CgkJCWJpdGRlcHRoID0gKHRoaXMuYXYxQy5oaWdoX2JpdGRlcHRoID09PSAxKSA/ICIxMCIgOiAiMDgiOwoJCX0KCQkvLyBUT0RPIG5lZWQgdG8gcGFyc2UgdGhlIFNIIHRvIGZpbmQgY29sb3IgY29uZmlnCgkJcmV0dXJuIGJhc2VDb2RlYysiLiIrdGhpcy5hdjFDLnNlcV9wcm9maWxlKyIuIitsZXZlbCsodGhpcy5hdjFDLnNlcV90aWVyXzA/IkgiOiJNIikrIi4iK2JpdGRlcHRoOy8vKyIuIit0aGlzLmF2MUMubW9ub2Nocm9tZSsiLiIrdGhpcy5hdjFDLmNocm9tYV9zdWJzYW1wbGluZ194KyIiK3RoaXMuYXYxQy5jaHJvbWFfc3Vic2FtcGxpbmdfeSsiIit0aGlzLmF2MUMuY2hyb21hX3NhbXBsZV9wb3NpdGlvbjsKCX07CgkvLyBmaWxlOnNyYy9ib3gtd3JpdGUuanMKCS8qIAoJICogQ29weXJpZ2h0IChjKSBUZWxlY29tIFBhcmlzVGVjaC9UU0kvTU0vR1BBQyBDeXJpbCBDb25jb2xhdG8KCSAqIExpY2Vuc2U6IEJTRC0zLUNsYXVzZSAoc2VlIExJQ0VOU0UgZmlsZSkKCSAqLwoJQm94UGFyc2VyLkJveC5wcm90b3R5cGUud3JpdGVIZWFkZXIgPSBmdW5jdGlvbihzdHJlYW0sIG1zZykgewoJCXRoaXMuc2l6ZSArPSA4OwoJCWlmICh0aGlzLnNpemUgPiBNQVhfU0laRSkgewoJCQl0aGlzLnNpemUgKz0gODsKCQl9CgkJaWYgKHRoaXMudHlwZSA9PT0gInV1aWQiKSB7CgkJCXRoaXMuc2l6ZSArPSAxNjsKCQl9CgkJTG9nLmRlYnVnKCJCb3hXcml0ZXIiLCAiV3JpdGluZyBib3ggIit0aGlzLnR5cGUrIiBvZiBzaXplOiAiK3RoaXMuc2l6ZSsiIGF0IHBvc2l0aW9uICIrc3RyZWFtLmdldFBvc2l0aW9uKCkrKG1zZyB8fCAiIikpOwoJCWlmICh0aGlzLnNpemUgPiBNQVhfU0laRSkgewoJCQlzdHJlYW0ud3JpdGVVaW50MzIoMSk7CgkJfSBlbHNlIHsKCQkJdGhpcy5zaXplUG9zaXRpb24gPSBzdHJlYW0uZ2V0UG9zaXRpb24oKTsKCQkJc3RyZWFtLndyaXRlVWludDMyKHRoaXMuc2l6ZSk7CgkJfQoJCXN0cmVhbS53cml0ZVN0cmluZyh0aGlzLnR5cGUsIG51bGwsIDQpOwoJCWlmICh0aGlzLnR5cGUgPT09ICJ1dWlkIikgewoJCQlzdHJlYW0ud3JpdGVVaW50OEFycmF5KHRoaXMudXVpZCk7CgkJfQoJCWlmICh0aGlzLnNpemUgPiBNQVhfU0laRSkgewoJCQlzdHJlYW0ud3JpdGVVaW50NjQodGhpcy5zaXplKTsKCQl9IAoJfTsKCglCb3hQYXJzZXIuRnVsbEJveC5wcm90b3R5cGUud3JpdGVIZWFkZXIgPSBmdW5jdGlvbihzdHJlYW0pIHsKCQl0aGlzLnNpemUgKz0gNDsKCQlCb3hQYXJzZXIuQm94LnByb3RvdHlwZS53cml0ZUhlYWRlci5jYWxsKHRoaXMsIHN0cmVhbSwgIiB2PSIrdGhpcy52ZXJzaW9uKyIgZj0iK3RoaXMuZmxhZ3MpOwoJCXN0cmVhbS53cml0ZVVpbnQ4KHRoaXMudmVyc2lvbik7CgkJc3RyZWFtLndyaXRlVWludDI0KHRoaXMuZmxhZ3MpOwoJfTsKCglCb3hQYXJzZXIuQm94LnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uKHN0cmVhbSkgewoJCWlmICh0aGlzLnR5cGUgPT09ICJtZGF0IikgewoJCQkvKiBUT0RPOiBmaXggdGhpcyAqLwoJCQlpZiAodGhpcy5kYXRhKSB7CgkJCQl0aGlzLnNpemUgPSB0aGlzLmRhdGEubGVuZ3RoOwoJCQkJdGhpcy53cml0ZUhlYWRlcihzdHJlYW0pOwoJCQkJc3RyZWFtLndyaXRlVWludDhBcnJheSh0aGlzLmRhdGEpOwoJCQl9CgkJfSBlbHNlIHsKCQkJdGhpcy5zaXplID0gKHRoaXMuZGF0YSA/IHRoaXMuZGF0YS5sZW5ndGggOiAwKTsKCQkJdGhpcy53cml0ZUhlYWRlcihzdHJlYW0pOwoJCQlpZiAodGhpcy5kYXRhKSB7CgkJCQlzdHJlYW0ud3JpdGVVaW50OEFycmF5KHRoaXMuZGF0YSk7CgkJCX0KCQl9Cgl9OwoKCUJveFBhcnNlci5Db250YWluZXJCb3gucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24oc3RyZWFtKSB7CgkJdGhpcy5zaXplID0gMDsKCQl0aGlzLndyaXRlSGVhZGVyKHN0cmVhbSk7CgkJZm9yICh2YXIgaT0wOyBpPHRoaXMuYm94ZXMubGVuZ3RoOyBpKyspIHsKCQkJaWYgKHRoaXMuYm94ZXNbaV0pIHsKCQkJCXRoaXMuYm94ZXNbaV0ud3JpdGUoc3RyZWFtKTsKCQkJCXRoaXMuc2l6ZSArPSB0aGlzLmJveGVzW2ldLnNpemU7CgkJCX0KCQl9CgkJLyogYWRqdXN0aW5nIHRoZSBzaXplLCBub3cgdGhhdCBhbGwgc3ViLWJveGVzIGFyZSBrbm93biAqLwoJCUxvZy5kZWJ1ZygiQm94V3JpdGVyIiwgIkFkanVzdGluZyBib3ggIit0aGlzLnR5cGUrIiB3aXRoIG5ldyBzaXplICIrdGhpcy5zaXplKTsKCQlzdHJlYW0uYWRqdXN0VWludDMyKHRoaXMuc2l6ZVBvc2l0aW9uLCB0aGlzLnNpemUpOwoJfTsKCglCb3hQYXJzZXIuVHJhY2tSZWZlcmVuY2VUeXBlQm94LnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uKHN0cmVhbSkgewoJCXRoaXMuc2l6ZSA9IHRoaXMudHJhY2tfaWRzLmxlbmd0aCo0OwoJCXRoaXMud3JpdGVIZWFkZXIoc3RyZWFtKTsKCQlzdHJlYW0ud3JpdGVVaW50MzJBcnJheSh0aGlzLnRyYWNrX2lkcyk7Cgl9OwoKCS8vIGZpbGU6c3JjL3dyaXRpbmcvYXZjQy5qcwoJQm94UGFyc2VyLmF2Y0NCb3gucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24oc3RyZWFtKSB7CgkJdmFyIGk7CgkJdGhpcy5zaXplID0gNzsKCQlmb3IgKGkgPSAwOyBpIDwgdGhpcy5TUFMubGVuZ3RoOyBpKyspIHsKCQkJdGhpcy5zaXplICs9IDIrdGhpcy5TUFNbaV0ubGVuZ3RoOwoJCX0KCQlmb3IgKGkgPSAwOyBpIDwgdGhpcy5QUFMubGVuZ3RoOyBpKyspIHsKCQkJdGhpcy5zaXplICs9IDIrdGhpcy5QUFNbaV0ubGVuZ3RoOwoJCX0KCQlpZiAodGhpcy5leHQpIHsKCQkJdGhpcy5zaXplICs9IHRoaXMuZXh0Lmxlbmd0aDsKCQl9CgkJdGhpcy53cml0ZUhlYWRlcihzdHJlYW0pOwoJCXN0cmVhbS53cml0ZVVpbnQ4KHRoaXMuY29uZmlndXJhdGlvblZlcnNpb24pOwoJCXN0cmVhbS53cml0ZVVpbnQ4KHRoaXMuQVZDUHJvZmlsZUluZGljYXRpb24pOwoJCXN0cmVhbS53cml0ZVVpbnQ4KHRoaXMucHJvZmlsZV9jb21wYXRpYmlsaXR5KTsKCQlzdHJlYW0ud3JpdGVVaW50OCh0aGlzLkFWQ0xldmVsSW5kaWNhdGlvbik7CgkJc3RyZWFtLndyaXRlVWludDgodGhpcy5sZW5ndGhTaXplTWludXNPbmUgKyAoNjM8PDIpKTsKCQlzdHJlYW0ud3JpdGVVaW50OCh0aGlzLlNQUy5sZW5ndGggKyAoNzw8NSkpOwoJCWZvciAoaSA9IDA7IGkgPCB0aGlzLlNQUy5sZW5ndGg7IGkrKykgewoJCQlzdHJlYW0ud3JpdGVVaW50MTYodGhpcy5TUFNbaV0ubGVuZ3RoKTsKCQkJc3RyZWFtLndyaXRlVWludDhBcnJheSh0aGlzLlNQU1tpXS5uYWx1KTsKCQl9CgkJc3RyZWFtLndyaXRlVWludDgodGhpcy5QUFMubGVuZ3RoKTsKCQlmb3IgKGkgPSAwOyBpIDwgdGhpcy5QUFMubGVuZ3RoOyBpKyspIHsKCQkJc3RyZWFtLndyaXRlVWludDE2KHRoaXMuUFBTW2ldLmxlbmd0aCk7CgkJCXN0cmVhbS53cml0ZVVpbnQ4QXJyYXkodGhpcy5QUFNbaV0ubmFsdSk7CgkJfQoJCWlmICh0aGlzLmV4dCkgewoJCQlzdHJlYW0ud3JpdGVVaW50OEFycmF5KHRoaXMuZXh0KTsKCQl9Cgl9OwoKCS8vIGZpbGU6c3JjL3dyaXRpbmcvY282NC5qcwoJQm94UGFyc2VyLmNvNjRCb3gucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24oc3RyZWFtKSB7CgkJdmFyIGk7CgkJdGhpcy52ZXJzaW9uID0gMDsKCQl0aGlzLmZsYWdzID0gMDsKCQl0aGlzLnNpemUgPSA0KzgqdGhpcy5jaHVua19vZmZzZXRzLmxlbmd0aDsKCQl0aGlzLndyaXRlSGVhZGVyKHN0cmVhbSk7CgkJc3RyZWFtLndyaXRlVWludDMyKHRoaXMuY2h1bmtfb2Zmc2V0cy5sZW5ndGgpOwoJCWZvcihpPTA7IGk8dGhpcy5jaHVua19vZmZzZXRzLmxlbmd0aDsgaSsrKSB7CgkJCXN0cmVhbS53cml0ZVVpbnQ2NCh0aGlzLmNodW5rX29mZnNldHNbaV0pOwoJCX0KCX07CgoJLy8gZmlsZTpzcmMvd3JpdGluZy9jc2xnLmpzCglCb3hQYXJzZXIuY3NsZ0JveC5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbihzdHJlYW0pIHsKCQl0aGlzLnZlcnNpb24gPSAwOwoJCXRoaXMuZmxhZ3MgPSAwOwoJCXRoaXMuc2l6ZSA9IDQqNTsKCQl0aGlzLndyaXRlSGVhZGVyKHN0cmVhbSk7CgkJc3RyZWFtLndyaXRlSW50MzIodGhpcy5jb21wb3NpdGlvblRvRFRTU2hpZnQpOwoJCXN0cmVhbS53cml0ZUludDMyKHRoaXMubGVhc3REZWNvZGVUb0Rpc3BsYXlEZWx0YSk7CgkJc3RyZWFtLndyaXRlSW50MzIodGhpcy5ncmVhdGVzdERlY29kZVRvRGlzcGxheURlbHRhKTsKCQlzdHJlYW0ud3JpdGVJbnQzMih0aGlzLmNvbXBvc2l0aW9uU3RhcnRUaW1lKTsKCQlzdHJlYW0ud3JpdGVJbnQzMih0aGlzLmNvbXBvc2l0aW9uRW5kVGltZSk7Cgl9OwoKCS8vIGZpbGU6c3JjL3dyaXRpbmcvY3R0cy5qcwoJQm94UGFyc2VyLmN0dHNCb3gucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24oc3RyZWFtKSB7CgkJdmFyIGk7CgkJdGhpcy52ZXJzaW9uID0gMDsKCQl0aGlzLmZsYWdzID0gMDsKCQl0aGlzLnNpemUgPSA0KzgqdGhpcy5zYW1wbGVfY291bnRzLmxlbmd0aDsKCQl0aGlzLndyaXRlSGVhZGVyKHN0cmVhbSk7CgkJc3RyZWFtLndyaXRlVWludDMyKHRoaXMuc2FtcGxlX2NvdW50cy5sZW5ndGgpOwoJCWZvcihpPTA7IGk8dGhpcy5zYW1wbGVfY291bnRzLmxlbmd0aDsgaSsrKSB7CgkJCXN0cmVhbS53cml0ZVVpbnQzMih0aGlzLnNhbXBsZV9jb3VudHNbaV0pOwoJCQlpZiAodGhpcy52ZXJzaW9uID09PSAxKSB7CgkJCQlzdHJlYW0ud3JpdGVJbnQzMih0aGlzLnNhbXBsZV9vZmZzZXRzW2ldKTsgLyogc2lnbmVkICovCgkJCX0gZWxzZSB7CQkJCgkJCQlzdHJlYW0ud3JpdGVVaW50MzIodGhpcy5zYW1wbGVfb2Zmc2V0c1tpXSk7IC8qIHVuc2lnbmVkICovCgkJCX0KCQl9Cgl9OwoKCS8vIGZpbGU6c3JjL3dyaXRpbmcvZHJlZi5qcwoJQm94UGFyc2VyLmRyZWZCb3gucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24oc3RyZWFtKSB7CgkJdGhpcy52ZXJzaW9uID0gMDsKCQl0aGlzLmZsYWdzID0gMDsKCQl0aGlzLnNpemUgPSA0OyAvLwoJCXRoaXMud3JpdGVIZWFkZXIoc3RyZWFtKTsKCQlzdHJlYW0ud3JpdGVVaW50MzIodGhpcy5lbnRyaWVzLmxlbmd0aCk7CgkJZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmVudHJpZXMubGVuZ3RoOyBpKyspIHsKCQkJdGhpcy5lbnRyaWVzW2ldLndyaXRlKHN0cmVhbSk7CgkJCXRoaXMuc2l6ZSArPSB0aGlzLmVudHJpZXNbaV0uc2l6ZTsKCQl9CQoJCS8qIGFkanVzdGluZyB0aGUgc2l6ZSwgbm93IHRoYXQgYWxsIHN1Yi1ib3hlcyBhcmUga25vd24gKi8KCQlMb2cuZGVidWcoIkJveFdyaXRlciIsICJBZGp1c3RpbmcgYm94ICIrdGhpcy50eXBlKyIgd2l0aCBuZXcgc2l6ZSAiK3RoaXMuc2l6ZSk7CgkJc3RyZWFtLmFkanVzdFVpbnQzMih0aGlzLnNpemVQb3NpdGlvbiwgdGhpcy5zaXplKTsKCX07CgoJLy8gZmlsZTpzcmMvd3JpdGluZy9lbG5nLmpzCglCb3hQYXJzZXIuZWxuZ0JveC5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbihzdHJlYW0pIHsKCQl0aGlzLnZlcnNpb24gPSAwOwkKCQl0aGlzLmZsYWdzID0gMDsKCQl0aGlzLnNpemUgPSB0aGlzLmV4dGVuZGVkX2xhbmd1YWdlLmxlbmd0aDsKCQl0aGlzLndyaXRlSGVhZGVyKHN0cmVhbSk7CgkJc3RyZWFtLndyaXRlU3RyaW5nKHRoaXMuZXh0ZW5kZWRfbGFuZ3VhZ2UpOwoJfTsKCgkvLyBmaWxlOnNyYy93cml0aW5nL2Vsc3QuanMKCUJveFBhcnNlci5lbHN0Qm94LnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uKHN0cmVhbSkgewoJCXRoaXMudmVyc2lvbiA9IDA7CQoJCXRoaXMuZmxhZ3MgPSAwOwoJCXRoaXMuc2l6ZSA9IDQrMTIqdGhpcy5lbnRyaWVzLmxlbmd0aDsKCQl0aGlzLndyaXRlSGVhZGVyKHN0cmVhbSk7CgkJc3RyZWFtLndyaXRlVWludDMyKHRoaXMuZW50cmllcy5sZW5ndGgpOwoJCWZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5lbnRyaWVzLmxlbmd0aDsgaSsrKSB7CgkJCXZhciBlbnRyeSA9IHRoaXMuZW50cmllc1tpXTsKCQkJc3RyZWFtLndyaXRlVWludDMyKGVudHJ5LnNlZ21lbnRfZHVyYXRpb24pOwoJCQlzdHJlYW0ud3JpdGVJbnQzMihlbnRyeS5tZWRpYV90aW1lKTsKCQkJc3RyZWFtLndyaXRlSW50MTYoZW50cnkubWVkaWFfcmF0ZV9pbnRlZ2VyKTsKCQkJc3RyZWFtLndyaXRlSW50MTYoZW50cnkubWVkaWFfcmF0ZV9mcmFjdGlvbik7CgkJfQoJfTsKCgkvLyBmaWxlOnNyYy93cml0aW5nL2Vtc2cuanMKCUJveFBhcnNlci5lbXNnQm94LnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uKHN0cmVhbSkgewoJCXRoaXMudmVyc2lvbiA9IDA7CQoJCXRoaXMuZmxhZ3MgPSAwOwoJCXRoaXMuc2l6ZSA9IDQqNCt0aGlzLm1lc3NhZ2VfZGF0YS5sZW5ndGgrKHRoaXMuc2NoZW1lX2lkX3VyaS5sZW5ndGgrMSkrKHRoaXMudmFsdWUubGVuZ3RoKzEpOwoJCXRoaXMud3JpdGVIZWFkZXIoc3RyZWFtKTsKCQlzdHJlYW0ud3JpdGVDU3RyaW5nKHRoaXMuc2NoZW1lX2lkX3VyaSk7CgkJc3RyZWFtLndyaXRlQ1N0cmluZyh0aGlzLnZhbHVlKTsKCQlzdHJlYW0ud3JpdGVVaW50MzIodGhpcy50aW1lc2NhbGUpOwoJCXN0cmVhbS53cml0ZVVpbnQzMih0aGlzLnByZXNlbnRhdGlvbl90aW1lX2RlbHRhKTsKCQlzdHJlYW0ud3JpdGVVaW50MzIodGhpcy5ldmVudF9kdXJhdGlvbik7CgkJc3RyZWFtLndyaXRlVWludDMyKHRoaXMuaWQpOwoJCXN0cmVhbS53cml0ZVVpbnQ4QXJyYXkodGhpcy5tZXNzYWdlX2RhdGEpOwoJfTsKCgkvLyBmaWxlOnNyYy93cml0aW5nL2Z0eXAuanMKCUJveFBhcnNlci5mdHlwQm94LnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uKHN0cmVhbSkgewoJCXRoaXMuc2l6ZSA9IDgrNCp0aGlzLmNvbXBhdGlibGVfYnJhbmRzLmxlbmd0aDsKCQl0aGlzLndyaXRlSGVhZGVyKHN0cmVhbSk7CgkJc3RyZWFtLndyaXRlU3RyaW5nKHRoaXMubWFqb3JfYnJhbmQsIG51bGwsIDQpOwoJCXN0cmVhbS53cml0ZVVpbnQzMih0aGlzLm1pbm9yX3ZlcnNpb24pOwoJCWZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5jb21wYXRpYmxlX2JyYW5kcy5sZW5ndGg7IGkrKykgewoJCQlzdHJlYW0ud3JpdGVTdHJpbmcodGhpcy5jb21wYXRpYmxlX2JyYW5kc1tpXSwgbnVsbCwgNCk7CgkJfQoJfTsKCgkvLyBmaWxlOnNyYy93cml0aW5nL2hkbHIuanMKCUJveFBhcnNlci5oZGxyQm94LnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uKHN0cmVhbSkgewoJCXRoaXMuc2l6ZSA9IDUqNCt0aGlzLm5hbWUubGVuZ3RoKzE7CgkJdGhpcy52ZXJzaW9uID0gMDsKCQl0aGlzLmZsYWdzID0gMDsKCQl0aGlzLndyaXRlSGVhZGVyKHN0cmVhbSk7CgkJc3RyZWFtLndyaXRlVWludDMyKDApOwoJCXN0cmVhbS53cml0ZVN0cmluZyh0aGlzLmhhbmRsZXIsIG51bGwsIDQpOwoJCXN0cmVhbS53cml0ZVVpbnQzMigwKTsKCQlzdHJlYW0ud3JpdGVVaW50MzIoMCk7CgkJc3RyZWFtLndyaXRlVWludDMyKDApOwoJCXN0cmVhbS53cml0ZUNTdHJpbmcodGhpcy5uYW1lKTsKCX07CgoJLy8gZmlsZTpzcmMvd3JpdGluZy9raW5kLmpzCglCb3hQYXJzZXIua2luZEJveC5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbihzdHJlYW0pIHsKCQl0aGlzLnZlcnNpb24gPSAwOwkKCQl0aGlzLmZsYWdzID0gMDsKCQl0aGlzLnNpemUgPSAodGhpcy5zY2hlbWVVUkkubGVuZ3RoKzEpKyh0aGlzLnZhbHVlLmxlbmd0aCsxKTsKCQl0aGlzLndyaXRlSGVhZGVyKHN0cmVhbSk7CgkJc3RyZWFtLndyaXRlQ1N0cmluZyh0aGlzLnNjaGVtZVVSSSk7CgkJc3RyZWFtLndyaXRlQ1N0cmluZyh0aGlzLnZhbHVlKTsKCX07CgoJLy8gZmlsZTpzcmMvd3JpdGluZy9tZGhkLmpzCglCb3hQYXJzZXIubWRoZEJveC5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbihzdHJlYW0pIHsKCQl0aGlzLnNpemUgPSA0KjQrMioyOwoJCXRoaXMuZmxhZ3MgPSAwOwoJCXRoaXMudmVyc2lvbiA9IDA7CgkJdGhpcy53cml0ZUhlYWRlcihzdHJlYW0pOwoJCXN0cmVhbS53cml0ZVVpbnQzMih0aGlzLmNyZWF0aW9uX3RpbWUpOwoJCXN0cmVhbS53cml0ZVVpbnQzMih0aGlzLm1vZGlmaWNhdGlvbl90aW1lKTsKCQlzdHJlYW0ud3JpdGVVaW50MzIodGhpcy50aW1lc2NhbGUpOwoJCXN0cmVhbS53cml0ZVVpbnQzMih0aGlzLmR1cmF0aW9uKTsKCQlzdHJlYW0ud3JpdGVVaW50MTYodGhpcy5sYW5ndWFnZSk7CgkJc3RyZWFtLndyaXRlVWludDE2KDApOwoJfTsKCgkvLyBmaWxlOnNyYy93cml0aW5nL21laGQuanMKCUJveFBhcnNlci5tZWhkQm94LnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uKHN0cmVhbSkgewoJCXRoaXMudmVyc2lvbiA9IDA7CgkJdGhpcy5mbGFncyA9IDA7CgkJdGhpcy5zaXplID0gNDsKCQl0aGlzLndyaXRlSGVhZGVyKHN0cmVhbSk7CgkJc3RyZWFtLndyaXRlVWludDMyKHRoaXMuZnJhZ21lbnRfZHVyYXRpb24pOwoJfTsKCgkvLyBmaWxlOnNyYy93cml0aW5nL21maGQuanMKCUJveFBhcnNlci5tZmhkQm94LnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uKHN0cmVhbSkgewoJCXRoaXMudmVyc2lvbiA9IDA7CgkJdGhpcy5mbGFncyA9IDA7CgkJdGhpcy5zaXplID0gNDsKCQl0aGlzLndyaXRlSGVhZGVyKHN0cmVhbSk7CgkJc3RyZWFtLndyaXRlVWludDMyKHRoaXMuc2VxdWVuY2VfbnVtYmVyKTsKCX07CgoJLy8gZmlsZTpzcmMvd3JpdGluZy9tdmhkLmpzCglCb3hQYXJzZXIubXZoZEJveC5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbihzdHJlYW0pIHsKCQl0aGlzLnZlcnNpb24gPSAwOwoJCXRoaXMuZmxhZ3MgPSAwOwoJCXRoaXMuc2l6ZSA9IDIzKjQrMioyOwoJCXRoaXMud3JpdGVIZWFkZXIoc3RyZWFtKTsKCQlzdHJlYW0ud3JpdGVVaW50MzIodGhpcy5jcmVhdGlvbl90aW1lKTsKCQlzdHJlYW0ud3JpdGVVaW50MzIodGhpcy5tb2RpZmljYXRpb25fdGltZSk7CgkJc3RyZWFtLndyaXRlVWludDMyKHRoaXMudGltZXNjYWxlKTsKCQlzdHJlYW0ud3JpdGVVaW50MzIodGhpcy5kdXJhdGlvbik7CgkJc3RyZWFtLndyaXRlVWludDMyKHRoaXMucmF0ZSk7CgkJc3RyZWFtLndyaXRlVWludDE2KHRoaXMudm9sdW1lPDw4KTsKCQlzdHJlYW0ud3JpdGVVaW50MTYoMCk7CgkJc3RyZWFtLndyaXRlVWludDMyKDApOwoJCXN0cmVhbS53cml0ZVVpbnQzMigwKTsKCQlzdHJlYW0ud3JpdGVVaW50MzJBcnJheSh0aGlzLm1hdHJpeCk7CgkJc3RyZWFtLndyaXRlVWludDMyKDApOwoJCXN0cmVhbS53cml0ZVVpbnQzMigwKTsKCQlzdHJlYW0ud3JpdGVVaW50MzIoMCk7CgkJc3RyZWFtLndyaXRlVWludDMyKDApOwoJCXN0cmVhbS53cml0ZVVpbnQzMigwKTsKCQlzdHJlYW0ud3JpdGVVaW50MzIoMCk7CgkJc3RyZWFtLndyaXRlVWludDMyKHRoaXMubmV4dF90cmFja19pZCk7Cgl9OwoKCS8vIGZpbGU6c3JjL3dyaXRpbmcvc2FtcGxlZW50cnkuanMKCUJveFBhcnNlci5TYW1wbGVFbnRyeS5wcm90b3R5cGUud3JpdGVIZWFkZXIgPSBmdW5jdGlvbihzdHJlYW0pIHsKCQl0aGlzLnNpemUgPSA4OwoJCUJveFBhcnNlci5Cb3gucHJvdG90eXBlLndyaXRlSGVhZGVyLmNhbGwodGhpcywgc3RyZWFtKTsKCQlzdHJlYW0ud3JpdGVVaW50OCgwKTsKCQlzdHJlYW0ud3JpdGVVaW50OCgwKTsKCQlzdHJlYW0ud3JpdGVVaW50OCgwKTsKCQlzdHJlYW0ud3JpdGVVaW50OCgwKTsKCQlzdHJlYW0ud3JpdGVVaW50OCgwKTsKCQlzdHJlYW0ud3JpdGVVaW50OCgwKTsKCQlzdHJlYW0ud3JpdGVVaW50MTYodGhpcy5kYXRhX3JlZmVyZW5jZV9pbmRleCk7Cgl9OwoKCUJveFBhcnNlci5TYW1wbGVFbnRyeS5wcm90b3R5cGUud3JpdGVGb290ZXIgPSBmdW5jdGlvbihzdHJlYW0pIHsKCQlmb3IgKHZhciBpPTA7IGk8dGhpcy5ib3hlcy5sZW5ndGg7IGkrKykgewoJCQl0aGlzLmJveGVzW2ldLndyaXRlKHN0cmVhbSk7CgkJCXRoaXMuc2l6ZSArPSB0aGlzLmJveGVzW2ldLnNpemU7CgkJfQoJCUxvZy5kZWJ1ZygiQm94V3JpdGVyIiwgIkFkanVzdGluZyBib3ggIit0aGlzLnR5cGUrIiB3aXRoIG5ldyBzaXplICIrdGhpcy5zaXplKTsKCQlzdHJlYW0uYWRqdXN0VWludDMyKHRoaXMuc2l6ZVBvc2l0aW9uLCB0aGlzLnNpemUpOwkKCX07CgoJQm94UGFyc2VyLlNhbXBsZUVudHJ5LnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uKHN0cmVhbSkgewoJCXRoaXMud3JpdGVIZWFkZXIoc3RyZWFtKTsKCQlzdHJlYW0ud3JpdGVVaW50OEFycmF5KHRoaXMuZGF0YSk7CgkJdGhpcy5zaXplICs9IHRoaXMuZGF0YS5sZW5ndGg7CgkJTG9nLmRlYnVnKCJCb3hXcml0ZXIiLCAiQWRqdXN0aW5nIGJveCAiK3RoaXMudHlwZSsiIHdpdGggbmV3IHNpemUgIit0aGlzLnNpemUpOwoJCXN0cmVhbS5hZGp1c3RVaW50MzIodGhpcy5zaXplUG9zaXRpb24sIHRoaXMuc2l6ZSk7CQoJfTsKCglCb3hQYXJzZXIuVmlzdWFsU2FtcGxlRW50cnkucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24oc3RyZWFtKSB7CgkJdGhpcy53cml0ZUhlYWRlcihzdHJlYW0pOwoJCXRoaXMuc2l6ZSArPSAyKjcrNio0KzMyOwoJCXN0cmVhbS53cml0ZVVpbnQxNigwKTsgCgkJc3RyZWFtLndyaXRlVWludDE2KDApOwoJCXN0cmVhbS53cml0ZVVpbnQzMigwKTsKCQlzdHJlYW0ud3JpdGVVaW50MzIoMCk7CgkJc3RyZWFtLndyaXRlVWludDMyKDApOwoJCXN0cmVhbS53cml0ZVVpbnQxNih0aGlzLndpZHRoKTsKCQlzdHJlYW0ud3JpdGVVaW50MTYodGhpcy5oZWlnaHQpOwoJCXN0cmVhbS53cml0ZVVpbnQzMih0aGlzLmhvcml6cmVzb2x1dGlvbik7CgkJc3RyZWFtLndyaXRlVWludDMyKHRoaXMudmVydHJlc29sdXRpb24pOwoJCXN0cmVhbS53cml0ZVVpbnQzMigwKTsKCQlzdHJlYW0ud3JpdGVVaW50MTYodGhpcy5mcmFtZV9jb3VudCk7CgkJc3RyZWFtLndyaXRlVWludDgoTWF0aC5taW4oMzEsIHRoaXMuY29tcHJlc3Nvcm5hbWUubGVuZ3RoKSk7CgkJc3RyZWFtLndyaXRlU3RyaW5nKHRoaXMuY29tcHJlc3Nvcm5hbWUsIG51bGwsIDMxKTsKCQlzdHJlYW0ud3JpdGVVaW50MTYodGhpcy5kZXB0aCk7CgkJc3RyZWFtLndyaXRlSW50MTYoLTEpOwoJCXRoaXMud3JpdGVGb290ZXIoc3RyZWFtKTsKCX07CgoJQm94UGFyc2VyLkF1ZGlvU2FtcGxlRW50cnkucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24oc3RyZWFtKSB7CgkJdGhpcy53cml0ZUhlYWRlcihzdHJlYW0pOwoJCXRoaXMuc2l6ZSArPSAyKjQrMyo0OwoJCXN0cmVhbS53cml0ZVVpbnQzMigwKTsKCQlzdHJlYW0ud3JpdGVVaW50MzIoMCk7CgkJc3RyZWFtLndyaXRlVWludDE2KHRoaXMuY2hhbm5lbF9jb3VudCk7CgkJc3RyZWFtLndyaXRlVWludDE2KHRoaXMuc2FtcGxlc2l6ZSk7CgkJc3RyZWFtLndyaXRlVWludDE2KDApOwoJCXN0cmVhbS53cml0ZVVpbnQxNigwKTsKCQlzdHJlYW0ud3JpdGVVaW50MzIodGhpcy5zYW1wbGVyYXRlPDwxNik7CgkJdGhpcy53cml0ZUZvb3RlcihzdHJlYW0pOwoJfTsKCglCb3hQYXJzZXIuc3RwcFNhbXBsZUVudHJ5LnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uKHN0cmVhbSkgewoJCXRoaXMud3JpdGVIZWFkZXIoc3RyZWFtKTsKCQl0aGlzLnNpemUgKz0gdGhpcy5uYW1lc3BhY2UubGVuZ3RoKzErCgkJCQkJIHRoaXMuc2NoZW1hX2xvY2F0aW9uLmxlbmd0aCsxKwoJCQkJCSB0aGlzLmF1eGlsaWFyeV9taW1lX3R5cGVzLmxlbmd0aCsxOwoJCXN0cmVhbS53cml0ZUNTdHJpbmcodGhpcy5uYW1lc3BhY2UpOwoJCXN0cmVhbS53cml0ZUNTdHJpbmcodGhpcy5zY2hlbWFfbG9jYXRpb24pOwoJCXN0cmVhbS53cml0ZUNTdHJpbmcodGhpcy5hdXhpbGlhcnlfbWltZV90eXBlcyk7CgkJdGhpcy53cml0ZUZvb3RlcihzdHJlYW0pOwoJfTsKCgkvLyBmaWxlOnNyYy93cml0aW5nL3NhbXBsZWdyb3Vwcy9zYW1wbGVncm91cC5qcwoJQm94UGFyc2VyLlNhbXBsZUdyb3VwRW50cnkucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24oc3RyZWFtKSB7CgkJc3RyZWFtLndyaXRlVWludDhBcnJheSh0aGlzLmRhdGEpOwoJfTsKCgkvLyBmaWxlOnNyYy93cml0aW5nL3NiZ3AuanMKCUJveFBhcnNlci5zYmdwQm94LnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uKHN0cmVhbSkgewoJCXRoaXMudmVyc2lvbiA9IDE7CQoJCXRoaXMuZmxhZ3MgPSAwOwoJCXRoaXMuc2l6ZSA9IDEyKzgqdGhpcy5lbnRyaWVzLmxlbmd0aDsKCQl0aGlzLndyaXRlSGVhZGVyKHN0cmVhbSk7CgkJc3RyZWFtLndyaXRlU3RyaW5nKHRoaXMuZ3JvdXBpbmdfdHlwZSwgbnVsbCwgNCk7CgkJc3RyZWFtLndyaXRlVWludDMyKHRoaXMuZ3JvdXBpbmdfdHlwZV9wYXJhbWV0ZXIpOwoJCXN0cmVhbS53cml0ZVVpbnQzMih0aGlzLmVudHJpZXMubGVuZ3RoKTsKCQlmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuZW50cmllcy5sZW5ndGg7IGkrKykgewoJCQl2YXIgZW50cnkgPSB0aGlzLmVudHJpZXNbaV07CgkJCXN0cmVhbS53cml0ZUludDMyKGVudHJ5LnNhbXBsZV9jb3VudCk7CgkJCXN0cmVhbS53cml0ZUludDMyKGVudHJ5Lmdyb3VwX2Rlc2NyaXB0aW9uX2luZGV4KTsKCQl9Cgl9OwoKCS8vIGZpbGU6c3JjL3dyaXRpbmcvc2dwZC5qcwoJQm94UGFyc2VyLnNncGRCb3gucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24oc3RyZWFtKSB7CgkJdmFyIGk7CgkJdmFyIGVudHJ5OwoJCS8vIGxlYXZlIHZlcnNpb24gYXMgcmVhZAoJCS8vIHRoaXMudmVyc2lvbjsKCQl0aGlzLmZsYWdzID0gMDsKCQl0aGlzLnNpemUgPSAxMjsKCQlmb3IgKGkgPSAwOyBpIDwgdGhpcy5lbnRyaWVzLmxlbmd0aDsgaSsrKSB7CgkJCWVudHJ5ID0gdGhpcy5lbnRyaWVzW2ldOwoJCQlpZiAodGhpcy52ZXJzaW9uID09PSAxKSB7CgkJCQlpZiAodGhpcy5kZWZhdWx0X2xlbmd0aCA9PT0gMCkgewoJCQkJCXRoaXMuc2l6ZSArPSA0OwoJCQkJfQoJCQkJdGhpcy5zaXplICs9IGVudHJ5LmRhdGEubGVuZ3RoOwoJCQl9CgkJfQoJCXRoaXMud3JpdGVIZWFkZXIoc3RyZWFtKTsKCQlzdHJlYW0ud3JpdGVTdHJpbmcodGhpcy5ncm91cGluZ190eXBlLCBudWxsLCA0KTsKCQlpZiAodGhpcy52ZXJzaW9uID09PSAxKSB7CgkJCXN0cmVhbS53cml0ZVVpbnQzMih0aGlzLmRlZmF1bHRfbGVuZ3RoKTsKCQl9CgkJaWYgKHRoaXMudmVyc2lvbiA+PSAyKSB7CgkJCXN0cmVhbS53cml0ZVVpbnQzMih0aGlzLmRlZmF1bHRfc2FtcGxlX2Rlc2NyaXB0aW9uX2luZGV4KTsKCQl9CgkJc3RyZWFtLndyaXRlVWludDMyKHRoaXMuZW50cmllcy5sZW5ndGgpOwoJCWZvciAoaSA9IDA7IGkgPCB0aGlzLmVudHJpZXMubGVuZ3RoOyBpKyspIHsKCQkJZW50cnkgPSB0aGlzLmVudHJpZXNbaV07CgkJCWlmICh0aGlzLnZlcnNpb24gPT09IDEpIHsKCQkJCWlmICh0aGlzLmRlZmF1bHRfbGVuZ3RoID09PSAwKSB7CgkJCQkJc3RyZWFtLndyaXRlVWludDMyKGVudHJ5LmRlc2NyaXB0aW9uX2xlbmd0aCk7CgkJCQl9CgkJCX0KCQkJZW50cnkud3JpdGUoc3RyZWFtKTsKCQl9Cgl9OwoKCgkvLyBmaWxlOnNyYy93cml0aW5nL3NpZHguanMKCUJveFBhcnNlci5zaWR4Qm94LnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uKHN0cmVhbSkgewoJCXRoaXMudmVyc2lvbiA9IDA7CQoJCXRoaXMuZmxhZ3MgPSAwOwoJCXRoaXMuc2l6ZSA9IDQqNCsyKzIrMTIqdGhpcy5yZWZlcmVuY2VzLmxlbmd0aDsKCQl0aGlzLndyaXRlSGVhZGVyKHN0cmVhbSk7CgkJc3RyZWFtLndyaXRlVWludDMyKHRoaXMucmVmZXJlbmNlX0lEKTsKCQlzdHJlYW0ud3JpdGVVaW50MzIodGhpcy50aW1lc2NhbGUpOwoJCXN0cmVhbS53cml0ZVVpbnQzMih0aGlzLmVhcmxpZXN0X3ByZXNlbnRhdGlvbl90aW1lKTsKCQlzdHJlYW0ud3JpdGVVaW50MzIodGhpcy5maXJzdF9vZmZzZXQpOwoJCXN0cmVhbS53cml0ZVVpbnQxNigwKTsKCQlzdHJlYW0ud3JpdGVVaW50MTYodGhpcy5yZWZlcmVuY2VzLmxlbmd0aCk7CgkJZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnJlZmVyZW5jZXMubGVuZ3RoOyBpKyspIHsKCQkJdmFyIHJlZiA9IHRoaXMucmVmZXJlbmNlc1tpXTsKCQkJc3RyZWFtLndyaXRlVWludDMyKHJlZi5yZWZlcmVuY2VfdHlwZSA8PCAzMSB8IHJlZi5yZWZlcmVuY2VkX3NpemUpOwoJCQlzdHJlYW0ud3JpdGVVaW50MzIocmVmLnN1YnNlZ21lbnRfZHVyYXRpb24pOwoJCQlzdHJlYW0ud3JpdGVVaW50MzIocmVmLnN0YXJ0c193aXRoX1NBUCA8PCAzMSB8IHJlZi5TQVBfdHlwZSA8PCAyOCB8IHJlZi5TQVBfZGVsdGFfdGltZSk7CgkJfQoJfTsKCgkvLyBmaWxlOnNyYy93cml0aW5nL3NtaGQuanMKCUJveFBhcnNlci5zbWhkQm94LnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uKHN0cmVhbSkgewoJICB0aGlzLnZlcnNpb24gPSAwOwoJICB0aGlzLmZsYWdzID0gMTsKCSAgdGhpcy5zaXplID0gNDsKCSAgdGhpcy53cml0ZUhlYWRlcihzdHJlYW0pOwoJICBzdHJlYW0ud3JpdGVVaW50MTYodGhpcy5iYWxhbmNlKTsKCSAgc3RyZWFtLndyaXRlVWludDE2KDApOwoJfTsKCS8vIGZpbGU6c3JjL3dyaXRpbmcvc3Rjby5qcwoJQm94UGFyc2VyLnN0Y29Cb3gucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24oc3RyZWFtKSB7CgkJdGhpcy52ZXJzaW9uID0gMDsKCQl0aGlzLmZsYWdzID0gMDsKCQl0aGlzLnNpemUgPSA0KzQqdGhpcy5jaHVua19vZmZzZXRzLmxlbmd0aDsKCQl0aGlzLndyaXRlSGVhZGVyKHN0cmVhbSk7CgkJc3RyZWFtLndyaXRlVWludDMyKHRoaXMuY2h1bmtfb2Zmc2V0cy5sZW5ndGgpOwoJCXN0cmVhbS53cml0ZVVpbnQzMkFycmF5KHRoaXMuY2h1bmtfb2Zmc2V0cyk7Cgl9OwoKCS8vIGZpbGU6c3JjL3dyaXRpbmcvc3RzYy5qcwoJQm94UGFyc2VyLnN0c2NCb3gucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24oc3RyZWFtKSB7CgkJdmFyIGk7CgkJdGhpcy52ZXJzaW9uID0gMDsKCQl0aGlzLmZsYWdzID0gMDsKCQl0aGlzLnNpemUgPSA0KzEyKnRoaXMuZmlyc3RfY2h1bmsubGVuZ3RoOwoJCXRoaXMud3JpdGVIZWFkZXIoc3RyZWFtKTsKCQlzdHJlYW0ud3JpdGVVaW50MzIodGhpcy5maXJzdF9jaHVuay5sZW5ndGgpOwoJCWZvcihpPTA7IGk8dGhpcy5maXJzdF9jaHVuay5sZW5ndGg7IGkrKykgewoJCQlzdHJlYW0ud3JpdGVVaW50MzIodGhpcy5maXJzdF9jaHVua1tpXSk7CgkJCXN0cmVhbS53cml0ZVVpbnQzMih0aGlzLnNhbXBsZXNfcGVyX2NodW5rW2ldKTsKCQkJc3RyZWFtLndyaXRlVWludDMyKHRoaXMuc2FtcGxlX2Rlc2NyaXB0aW9uX2luZGV4W2ldKTsKCQl9Cgl9OwoKCS8vIGZpbGU6c3JjL3dyaXRpbmcvc3RzZC5qcwoJQm94UGFyc2VyLnN0c2RCb3gucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24oc3RyZWFtKSB7CgkJdmFyIGk7CgkJdGhpcy52ZXJzaW9uID0gMDsKCQl0aGlzLmZsYWdzID0gMDsKCQl0aGlzLnNpemUgPSAwOwoJCXRoaXMud3JpdGVIZWFkZXIoc3RyZWFtKTsKCQlzdHJlYW0ud3JpdGVVaW50MzIodGhpcy5lbnRyaWVzLmxlbmd0aCk7CgkJdGhpcy5zaXplICs9IDQ7CgkJZm9yIChpID0gMDsgaSA8IHRoaXMuZW50cmllcy5sZW5ndGg7IGkrKykgewoJCQl0aGlzLmVudHJpZXNbaV0ud3JpdGUoc3RyZWFtKTsKCQkJdGhpcy5zaXplICs9IHRoaXMuZW50cmllc1tpXS5zaXplOwoJCX0KCQkvKiBhZGp1c3RpbmcgdGhlIHNpemUsIG5vdyB0aGF0IGFsbCBzdWItYm94ZXMgYXJlIGtub3duICovCgkJTG9nLmRlYnVnKCJCb3hXcml0ZXIiLCAiQWRqdXN0aW5nIGJveCAiK3RoaXMudHlwZSsiIHdpdGggbmV3IHNpemUgIit0aGlzLnNpemUpOwoJCXN0cmVhbS5hZGp1c3RVaW50MzIodGhpcy5zaXplUG9zaXRpb24sIHRoaXMuc2l6ZSk7Cgl9OwoKCS8vIGZpbGU6c3JjL3dyaXRpbmcvc3RzaC5qcwoJQm94UGFyc2VyLnN0c2hCb3gucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24oc3RyZWFtKSB7CgkJdmFyIGk7CgkJdGhpcy52ZXJzaW9uID0gMDsKCQl0aGlzLmZsYWdzID0gMDsKCQl0aGlzLnNpemUgPSA0KzgqdGhpcy5zaGFkb3dlZF9zYW1wbGVfbnVtYmVycy5sZW5ndGg7CgkJdGhpcy53cml0ZUhlYWRlcihzdHJlYW0pOwoJCXN0cmVhbS53cml0ZVVpbnQzMih0aGlzLnNoYWRvd2VkX3NhbXBsZV9udW1iZXJzLmxlbmd0aCk7CgkJZm9yKGk9MDsgaTx0aGlzLnNoYWRvd2VkX3NhbXBsZV9udW1iZXJzLmxlbmd0aDsgaSsrKSB7CgkJCXN0cmVhbS53cml0ZVVpbnQzMih0aGlzLnNoYWRvd2VkX3NhbXBsZV9udW1iZXJzW2ldKTsKCQkJc3RyZWFtLndyaXRlVWludDMyKHRoaXMuc3luY19zYW1wbGVfbnVtYmVyc1tpXSk7CgkJfQoJfTsKCgkvLyBmaWxlOnNyYy93cml0aW5nL3N0c3MuanMKCUJveFBhcnNlci5zdHNzQm94LnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uKHN0cmVhbSkgewoJCXRoaXMudmVyc2lvbiA9IDA7CgkJdGhpcy5mbGFncyA9IDA7CgkJdGhpcy5zaXplID0gNCs0KnRoaXMuc2FtcGxlX251bWJlcnMubGVuZ3RoOwoJCXRoaXMud3JpdGVIZWFkZXIoc3RyZWFtKTsKCQlzdHJlYW0ud3JpdGVVaW50MzIodGhpcy5zYW1wbGVfbnVtYmVycy5sZW5ndGgpOwoJCXN0cmVhbS53cml0ZVVpbnQzMkFycmF5KHRoaXMuc2FtcGxlX251bWJlcnMpOwoJfTsKCgkvLyBmaWxlOnNyYy93cml0aW5nL3N0c3ouanMKCUJveFBhcnNlci5zdHN6Qm94LnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uKHN0cmVhbSkgewoJCXZhciBpOwoJCXZhciBjb25zdGFudCA9IHRydWU7CgkJdGhpcy52ZXJzaW9uID0gMDsKCQl0aGlzLmZsYWdzID0gMDsKCQlpZiAodGhpcy5zYW1wbGVfc2l6ZXMubGVuZ3RoID4gMCkgewoJCQlpID0gMDsKCQkJd2hpbGUgKGkrMSA8IHRoaXMuc2FtcGxlX3NpemVzLmxlbmd0aCkgewoJCQkJaWYgKHRoaXMuc2FtcGxlX3NpemVzW2krMV0gIT09ICB0aGlzLnNhbXBsZV9zaXplc1swXSkgewoJCQkJCWNvbnN0YW50ID0gZmFsc2U7CgkJCQkJYnJlYWs7CgkJCQl9IGVsc2UgewoJCQkJCWkrKzsKCQkJCX0KCQkJfQoJCX0gZWxzZSB7CgkJCWNvbnN0YW50ID0gZmFsc2U7CgkJfQoJCXRoaXMuc2l6ZSA9IDg7CgkJaWYgKCFjb25zdGFudCkgewoJCQl0aGlzLnNpemUgKz0gNCp0aGlzLnNhbXBsZV9zaXplcy5sZW5ndGg7CgkJfQoJCXRoaXMud3JpdGVIZWFkZXIoc3RyZWFtKTsKCQlpZiAoIWNvbnN0YW50KSB7CgkJCXN0cmVhbS53cml0ZVVpbnQzMigwKTsKCQl9IGVsc2UgewoJCQlzdHJlYW0ud3JpdGVVaW50MzIodGhpcy5zYW1wbGVfc2l6ZXNbMF0pOwoJCX0KCQlzdHJlYW0ud3JpdGVVaW50MzIodGhpcy5zYW1wbGVfc2l6ZXMubGVuZ3RoKTsKCQlpZiAoIWNvbnN0YW50KSB7CgkJCXN0cmVhbS53cml0ZVVpbnQzMkFycmF5KHRoaXMuc2FtcGxlX3NpemVzKTsKCQl9CQoJfTsKCgkvLyBmaWxlOnNyYy93cml0aW5nL3N0dHMuanMKCUJveFBhcnNlci5zdHRzQm94LnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uKHN0cmVhbSkgewoJCXZhciBpOwoJCXRoaXMudmVyc2lvbiA9IDA7CgkJdGhpcy5mbGFncyA9IDA7CgkJdGhpcy5zaXplID0gNCs4KnRoaXMuc2FtcGxlX2NvdW50cy5sZW5ndGg7CgkJdGhpcy53cml0ZUhlYWRlcihzdHJlYW0pOwoJCXN0cmVhbS53cml0ZVVpbnQzMih0aGlzLnNhbXBsZV9jb3VudHMubGVuZ3RoKTsKCQlmb3IoaT0wOyBpPHRoaXMuc2FtcGxlX2NvdW50cy5sZW5ndGg7IGkrKykgewoJCQlzdHJlYW0ud3JpdGVVaW50MzIodGhpcy5zYW1wbGVfY291bnRzW2ldKTsKCQkJc3RyZWFtLndyaXRlVWludDMyKHRoaXMuc2FtcGxlX2RlbHRhc1tpXSk7CgkJfQoJfTsKCgkvLyBmaWxlOnNyYy93cml0aW5nL3RmZHQuanMKCUJveFBhcnNlci50ZmR0Qm94LnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uKHN0cmVhbSkgewoJCXZhciBVSU5UMzJfTUFYID0gTWF0aC5wb3coMiwgMzIpIC0gMTsKCQkvLyB1c2UgdmVyc2lvbiAxIGlmIGJhc2VNZWRpYURlY29kZVRpbWUgZG9lcyBub3QgZml0IDMyIGJpdHMKCQl0aGlzLnZlcnNpb24gPSB0aGlzLmJhc2VNZWRpYURlY29kZVRpbWUgPiBVSU5UMzJfTUFYID8gMSA6IDA7CgkJdGhpcy5mbGFncyA9IDA7CgkJdGhpcy5zaXplID0gNDsKCQlpZiAodGhpcy52ZXJzaW9uID09PSAxKSB7CgkJCXRoaXMuc2l6ZSArPSA0OwoJCX0KCQl0aGlzLndyaXRlSGVhZGVyKHN0cmVhbSk7CgkJaWYgKHRoaXMudmVyc2lvbiA9PT0gMSkgewoJCQlzdHJlYW0ud3JpdGVVaW50NjQodGhpcy5iYXNlTWVkaWFEZWNvZGVUaW1lKTsKCQl9IGVsc2UgewoJCQlzdHJlYW0ud3JpdGVVaW50MzIodGhpcy5iYXNlTWVkaWFEZWNvZGVUaW1lKTsKCQl9Cgl9OwoKCS8vIGZpbGU6c3JjL3dyaXRpbmcvdGZoZC5qcwoJQm94UGFyc2VyLnRmaGRCb3gucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24oc3RyZWFtKSB7CgkJdGhpcy52ZXJzaW9uID0gMDsKCQl0aGlzLnNpemUgPSA0OwoJCWlmICh0aGlzLmZsYWdzICYgQm94UGFyc2VyLlRGSERfRkxBR19CQVNFX0RBVEFfT0ZGU0VUKSB7CgkJCXRoaXMuc2l6ZSArPSA4OwoJCX0KCQlpZiAodGhpcy5mbGFncyAmIEJveFBhcnNlci5URkhEX0ZMQUdfU0FNUExFX0RFU0MpIHsKCQkJdGhpcy5zaXplICs9IDQ7CgkJfQoJCWlmICh0aGlzLmZsYWdzICYgQm94UGFyc2VyLlRGSERfRkxBR19TQU1QTEVfRFVSKSB7CgkJCXRoaXMuc2l6ZSArPSA0OwoJCX0KCQlpZiAodGhpcy5mbGFncyAmIEJveFBhcnNlci5URkhEX0ZMQUdfU0FNUExFX1NJWkUpIHsKCQkJdGhpcy5zaXplICs9IDQ7CgkJfQoJCWlmICh0aGlzLmZsYWdzICYgQm94UGFyc2VyLlRGSERfRkxBR19TQU1QTEVfRkxBR1MpIHsKCQkJdGhpcy5zaXplICs9IDQ7CgkJfQoJCXRoaXMud3JpdGVIZWFkZXIoc3RyZWFtKTsKCQlzdHJlYW0ud3JpdGVVaW50MzIodGhpcy50cmFja19pZCk7CgkJaWYgKHRoaXMuZmxhZ3MgJiBCb3hQYXJzZXIuVEZIRF9GTEFHX0JBU0VfREFUQV9PRkZTRVQpIHsKCQkJc3RyZWFtLndyaXRlVWludDY0KHRoaXMuYmFzZV9kYXRhX29mZnNldCk7CgkJfQoJCWlmICh0aGlzLmZsYWdzICYgQm94UGFyc2VyLlRGSERfRkxBR19TQU1QTEVfREVTQykgewoJCQlzdHJlYW0ud3JpdGVVaW50MzIodGhpcy5kZWZhdWx0X3NhbXBsZV9kZXNjcmlwdGlvbl9pbmRleCk7CgkJfQoJCWlmICh0aGlzLmZsYWdzICYgQm94UGFyc2VyLlRGSERfRkxBR19TQU1QTEVfRFVSKSB7CgkJCXN0cmVhbS53cml0ZVVpbnQzMih0aGlzLmRlZmF1bHRfc2FtcGxlX2R1cmF0aW9uKTsKCQl9CgkJaWYgKHRoaXMuZmxhZ3MgJiBCb3hQYXJzZXIuVEZIRF9GTEFHX1NBTVBMRV9TSVpFKSB7CgkJCXN0cmVhbS53cml0ZVVpbnQzMih0aGlzLmRlZmF1bHRfc2FtcGxlX3NpemUpOwoJCX0KCQlpZiAodGhpcy5mbGFncyAmIEJveFBhcnNlci5URkhEX0ZMQUdfU0FNUExFX0ZMQUdTKSB7CgkJCXN0cmVhbS53cml0ZVVpbnQzMih0aGlzLmRlZmF1bHRfc2FtcGxlX2ZsYWdzKTsKCQl9Cgl9OwoKCS8vIGZpbGU6c3JjL3dyaXRpbmcvdGtoZC5qcwoJQm94UGFyc2VyLnRraGRCb3gucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24oc3RyZWFtKSB7CgkJdGhpcy52ZXJzaW9uID0gMDsKCQkvL3RoaXMuZmxhZ3MgPSAwOwoJCXRoaXMuc2l6ZSA9IDQqMTgrMio0OwoJCXRoaXMud3JpdGVIZWFkZXIoc3RyZWFtKTsKCQlzdHJlYW0ud3JpdGVVaW50MzIodGhpcy5jcmVhdGlvbl90aW1lKTsKCQlzdHJlYW0ud3JpdGVVaW50MzIodGhpcy5tb2RpZmljYXRpb25fdGltZSk7CgkJc3RyZWFtLndyaXRlVWludDMyKHRoaXMudHJhY2tfaWQpOwoJCXN0cmVhbS53cml0ZVVpbnQzMigwKTsKCQlzdHJlYW0ud3JpdGVVaW50MzIodGhpcy5kdXJhdGlvbik7CgkJc3RyZWFtLndyaXRlVWludDMyKDApOwoJCXN0cmVhbS53cml0ZVVpbnQzMigwKTsKCQlzdHJlYW0ud3JpdGVJbnQxNih0aGlzLmxheWVyKTsKCQlzdHJlYW0ud3JpdGVJbnQxNih0aGlzLmFsdGVybmF0ZV9ncm91cCk7CgkJc3RyZWFtLndyaXRlSW50MTYodGhpcy52b2x1bWU8PDgpOwoJCXN0cmVhbS53cml0ZVVpbnQxNigwKTsKCQlzdHJlYW0ud3JpdGVJbnQzMkFycmF5KHRoaXMubWF0cml4KTsKCQlzdHJlYW0ud3JpdGVVaW50MzIodGhpcy53aWR0aCk7CgkJc3RyZWFtLndyaXRlVWludDMyKHRoaXMuaGVpZ2h0KTsKCX07CgoJLy8gZmlsZTpzcmMvd3JpdGluZy90cmV4LmpzCglCb3hQYXJzZXIudHJleEJveC5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbihzdHJlYW0pIHsKCQl0aGlzLnZlcnNpb24gPSAwOwoJCXRoaXMuZmxhZ3MgPSAwOwoJCXRoaXMuc2l6ZSA9IDQqNTsKCQl0aGlzLndyaXRlSGVhZGVyKHN0cmVhbSk7CgkJc3RyZWFtLndyaXRlVWludDMyKHRoaXMudHJhY2tfaWQpOwoJCXN0cmVhbS53cml0ZVVpbnQzMih0aGlzLmRlZmF1bHRfc2FtcGxlX2Rlc2NyaXB0aW9uX2luZGV4KTsKCQlzdHJlYW0ud3JpdGVVaW50MzIodGhpcy5kZWZhdWx0X3NhbXBsZV9kdXJhdGlvbik7CgkJc3RyZWFtLndyaXRlVWludDMyKHRoaXMuZGVmYXVsdF9zYW1wbGVfc2l6ZSk7CgkJc3RyZWFtLndyaXRlVWludDMyKHRoaXMuZGVmYXVsdF9zYW1wbGVfZmxhZ3MpOwoJfTsKCgkvLyBmaWxlOnNyYy93cml0aW5nL3RydW4uanMKCUJveFBhcnNlci50cnVuQm94LnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uKHN0cmVhbSkgewoJCXRoaXMudmVyc2lvbiA9IDA7CgkJdGhpcy5zaXplID0gNDsKCQlpZiAodGhpcy5mbGFncyAmIEJveFBhcnNlci5UUlVOX0ZMQUdTX0RBVEFfT0ZGU0VUKSB7CgkJCXRoaXMuc2l6ZSArPSA0OwoJCX0KCQlpZiAodGhpcy5mbGFncyAmIEJveFBhcnNlci5UUlVOX0ZMQUdTX0ZJUlNUX0ZMQUcpIHsKCQkJdGhpcy5zaXplICs9IDQ7CgkJfQoJCWlmICh0aGlzLmZsYWdzICYgQm94UGFyc2VyLlRSVU5fRkxBR1NfRFVSQVRJT04pIHsKCQkJdGhpcy5zaXplICs9IDQqdGhpcy5zYW1wbGVfZHVyYXRpb24ubGVuZ3RoOwoJCX0KCQlpZiAodGhpcy5mbGFncyAmIEJveFBhcnNlci5UUlVOX0ZMQUdTX1NJWkUpIHsKCQkJdGhpcy5zaXplICs9IDQqdGhpcy5zYW1wbGVfc2l6ZS5sZW5ndGg7CgkJfQoJCWlmICh0aGlzLmZsYWdzICYgQm94UGFyc2VyLlRSVU5fRkxBR1NfRkxBR1MpIHsKCQkJdGhpcy5zaXplICs9IDQqdGhpcy5zYW1wbGVfZmxhZ3MubGVuZ3RoOwoJCX0KCQlpZiAodGhpcy5mbGFncyAmIEJveFBhcnNlci5UUlVOX0ZMQUdTX0NUU19PRkZTRVQpIHsKCQkJdGhpcy5zaXplICs9IDQqdGhpcy5zYW1wbGVfY29tcG9zaXRpb25fdGltZV9vZmZzZXQubGVuZ3RoOwoJCX0KCQl0aGlzLndyaXRlSGVhZGVyKHN0cmVhbSk7CgkJc3RyZWFtLndyaXRlVWludDMyKHRoaXMuc2FtcGxlX2NvdW50KTsKCQlpZiAodGhpcy5mbGFncyAmIEJveFBhcnNlci5UUlVOX0ZMQUdTX0RBVEFfT0ZGU0VUKSB7CgkJCXRoaXMuZGF0YV9vZmZzZXRfcG9zaXRpb24gPSBzdHJlYW0uZ2V0UG9zaXRpb24oKTsKCQkJc3RyZWFtLndyaXRlSW50MzIodGhpcy5kYXRhX29mZnNldCk7IC8vc2lnbmVkCgkJfQoJCWlmICh0aGlzLmZsYWdzICYgQm94UGFyc2VyLlRSVU5fRkxBR1NfRklSU1RfRkxBRykgewoJCQlzdHJlYW0ud3JpdGVVaW50MzIodGhpcy5maXJzdF9zYW1wbGVfZmxhZ3MpOwoJCX0KCQlmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuc2FtcGxlX2NvdW50OyBpKyspIHsKCQkJaWYgKHRoaXMuZmxhZ3MgJiBCb3hQYXJzZXIuVFJVTl9GTEFHU19EVVJBVElPTikgewoJCQkJc3RyZWFtLndyaXRlVWludDMyKHRoaXMuc2FtcGxlX2R1cmF0aW9uW2ldKTsKCQkJfQoJCQlpZiAodGhpcy5mbGFncyAmIEJveFBhcnNlci5UUlVOX0ZMQUdTX1NJWkUpIHsKCQkJCXN0cmVhbS53cml0ZVVpbnQzMih0aGlzLnNhbXBsZV9zaXplW2ldKTsKCQkJfQoJCQlpZiAodGhpcy5mbGFncyAmIEJveFBhcnNlci5UUlVOX0ZMQUdTX0ZMQUdTKSB7CgkJCQlzdHJlYW0ud3JpdGVVaW50MzIodGhpcy5zYW1wbGVfZmxhZ3NbaV0pOwoJCQl9CgkJCWlmICh0aGlzLmZsYWdzICYgQm94UGFyc2VyLlRSVU5fRkxBR1NfQ1RTX09GRlNFVCkgewoJCQkJaWYgKHRoaXMudmVyc2lvbiA9PT0gMCkgewoJCQkJCXN0cmVhbS53cml0ZVVpbnQzMih0aGlzLnNhbXBsZV9jb21wb3NpdGlvbl90aW1lX29mZnNldFtpXSk7CgkJCQl9IGVsc2UgewoJCQkJCXN0cmVhbS53cml0ZUludDMyKHRoaXMuc2FtcGxlX2NvbXBvc2l0aW9uX3RpbWVfb2Zmc2V0W2ldKTsgLy9zaWduZWQKCQkJCX0KCQkJfQoJCX0JCQoJfTsKCgkvLyBmaWxlOnNyYy93cml0aW5nL3VybC5qcwoJQm94UGFyc2VyWyJ1cmwgQm94Il0ucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24oc3RyZWFtKSB7CgkJdGhpcy52ZXJzaW9uID0gMDsJCgkJaWYgKHRoaXMubG9jYXRpb24pIHsKCQkJdGhpcy5mbGFncyA9IDA7CgkJCXRoaXMuc2l6ZSA9IHRoaXMubG9jYXRpb24ubGVuZ3RoKzE7CgkJfSBlbHNlIHsKCQkJdGhpcy5mbGFncyA9IDB4MDAwMDAxOwoJCQl0aGlzLnNpemUgPSAwOwoJCX0KCQl0aGlzLndyaXRlSGVhZGVyKHN0cmVhbSk7CgkJaWYgKHRoaXMubG9jYXRpb24pIHsKCQkJc3RyZWFtLndyaXRlQ1N0cmluZyh0aGlzLmxvY2F0aW9uKTsKCQl9Cgl9OwoKCS8vIGZpbGU6c3JjL3dyaXRpbmcvdXJuLmpzCglCb3hQYXJzZXJbInVybiBCb3giXS5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbihzdHJlYW0pIHsKCQl0aGlzLnZlcnNpb24gPSAwOwkKCQl0aGlzLmZsYWdzID0gMDsKCQl0aGlzLnNpemUgPSB0aGlzLm5hbWUubGVuZ3RoKzErKHRoaXMubG9jYXRpb24gPyB0aGlzLmxvY2F0aW9uLmxlbmd0aCsxIDogMCk7CgkJdGhpcy53cml0ZUhlYWRlcihzdHJlYW0pOwoJCXN0cmVhbS53cml0ZUNTdHJpbmcodGhpcy5uYW1lKTsKCQlpZiAodGhpcy5sb2NhdGlvbikgewoJCQlzdHJlYW0ud3JpdGVDU3RyaW5nKHRoaXMubG9jYXRpb24pOwoJCX0KCX07CgoJLy8gZmlsZTpzcmMvd3JpdGluZy92bWhkLmpzCglCb3hQYXJzZXIudm1oZEJveC5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbihzdHJlYW0pIHsKCQl0aGlzLnZlcnNpb24gPSAwOwoJCXRoaXMuZmxhZ3MgPSAxOwoJCXRoaXMuc2l6ZSA9IDg7CgkJdGhpcy53cml0ZUhlYWRlcihzdHJlYW0pOwoJCXN0cmVhbS53cml0ZVVpbnQxNih0aGlzLmdyYXBoaWNzbW9kZSk7CgkJc3RyZWFtLndyaXRlVWludDE2QXJyYXkodGhpcy5vcGNvbG9yKTsKCX07CgoJLy8gZmlsZTpzcmMvYm94LXVucGFjay5qcwoJLyogCgkgKiBDb3B5cmlnaHQgKGMpIFRlbGVjb20gUGFyaXNUZWNoL1RTSS9NTS9HUEFDIEN5cmlsIENvbmNvbGF0bwoJICogTGljZW5zZTogQlNELTMtQ2xhdXNlIChzZWUgTElDRU5TRSBmaWxlKQoJICovCglCb3hQYXJzZXIuY3R0c0JveC5wcm90b3R5cGUudW5wYWNrID0gZnVuY3Rpb24oc2FtcGxlcykgewoJCXZhciBpLCBqLCBrOwoJCWsgPSAwOwoJCWZvciAoaSA9IDA7IGkgPCB0aGlzLnNhbXBsZV9jb3VudHMubGVuZ3RoOyBpKyspIHsKCQkJZm9yIChqID0gMDsgaiA8IHRoaXMuc2FtcGxlX2NvdW50c1tpXTsgaisrKSB7CgkJCQlzYW1wbGVzW2tdLnB0cyA9IHNhbXBsZXNba10uZHRzICsgdGhpcy5zYW1wbGVfb2Zmc2V0c1tpXTsKCQkJCWsrKzsKCQkJfQoJCX0KCX07CgoJQm94UGFyc2VyLnN0dHNCb3gucHJvdG90eXBlLnVucGFjayA9IGZ1bmN0aW9uKHNhbXBsZXMpIHsKCQl2YXIgaSwgaiwgazsKCQlrID0gMDsKCQlmb3IgKGkgPSAwOyBpIDwgdGhpcy5zYW1wbGVfY291bnRzLmxlbmd0aDsgaSsrKSB7CgkJCWZvciAoaiA9IDA7IGogPCB0aGlzLnNhbXBsZV9jb3VudHNbaV07IGorKykgewoJCQkJaWYgKGsgPT09IDApIHsKCQkJCQlzYW1wbGVzW2tdLmR0cyA9IDA7CgkJCQl9IGVsc2UgewoJCQkJCXNhbXBsZXNba10uZHRzID0gc2FtcGxlc1trLTFdLmR0cyArIHRoaXMuc2FtcGxlX2RlbHRhc1tpXTsKCQkJCX0KCQkJCWsrKzsKCQkJfQoJCX0KCX07CgoJQm94UGFyc2VyLnN0Y29Cb3gucHJvdG90eXBlLnVucGFjayA9IGZ1bmN0aW9uKHNhbXBsZXMpIHsKCQl2YXIgaTsKCQlmb3IgKGkgPSAwOyBpIDwgdGhpcy5jaHVua19vZmZzZXRzLmxlbmd0aDsgaSsrKSB7CgkJCXNhbXBsZXNbaV0ub2Zmc2V0ID0gdGhpcy5jaHVua19vZmZzZXRzW2ldOwoJCX0KCX07CgoJQm94UGFyc2VyLnN0c2NCb3gucHJvdG90eXBlLnVucGFjayA9IGZ1bmN0aW9uKHNhbXBsZXMpIHsKCQl2YXIgaSwgaiwgaywgbCwgbTsKCQlsID0gMDsKCQltID0gMDsKCQlmb3IgKGkgPSAwOyBpIDwgdGhpcy5maXJzdF9jaHVuay5sZW5ndGg7IGkrKykgewoJCQlmb3IgKGogPSAwOyBqIDwgKGkrMSA8IHRoaXMuZmlyc3RfY2h1bmsubGVuZ3RoID8gdGhpcy5maXJzdF9jaHVua1tpKzFdIDogSW5maW5pdHkpOyBqKyspIHsKCQkJCW0rKzsKCQkJCWZvciAoayA9IDA7IGsgPCB0aGlzLnNhbXBsZXNfcGVyX2NodW5rW2ldOyBrKyspIHsKCQkJCQlpZiAoc2FtcGxlc1tsXSkgewoJCQkJCQlzYW1wbGVzW2xdLmRlc2NyaXB0aW9uX2luZGV4ID0gdGhpcy5zYW1wbGVfZGVzY3JpcHRpb25faW5kZXhbaV07CgkJCQkJCXNhbXBsZXNbbF0uY2h1bmtfaW5kZXggPSBtOwoJCQkJCX0gZWxzZSB7CgkJCQkJCXJldHVybjsKCQkJCQl9CgkJCQkJbCsrOwoJCQkJfQkJCQoJCQl9CgkJfQoJfTsKCglCb3hQYXJzZXIuc3RzekJveC5wcm90b3R5cGUudW5wYWNrID0gZnVuY3Rpb24oc2FtcGxlcykgewoJCXZhciBpOwoJCWZvciAoaSA9IDA7IGkgPCB0aGlzLnNhbXBsZV9zaXplcy5sZW5ndGg7IGkrKykgewoJCQlzYW1wbGVzW2ldLnNpemUgPSB0aGlzLnNhbXBsZV9zaXplc1tpXTsKCQl9Cgl9OwoJLy8gZmlsZTpzcmMvYm94LWRpZmYuanMKCglCb3hQYXJzZXIuRElGRl9CT1hFU19QUk9QX05BTUVTID0gWyAiYm94ZXMiLCAiZW50cmllcyIsICJyZWZlcmVuY2VzIiwgInN1YnNhbXBsZXMiLAoJCQkJCQkgCSAiaXRlbXMiLCAiaXRlbV9pbmZvcyIsICJleHRlbnRzIiwgImFzc29jaWF0aW9ucyIsCgkJCQkJCSAJICJzdWJzZWdtZW50cyIsICJyYW5nZXMiLCAic2Vla0xpc3RzIiwgInNlZWtQb2ludHMiLAoJCQkJCQkgCSAiZXNkIiwgImxldmVscyJdOwoKCUJveFBhcnNlci5ESUZGX1BSSU1JVElWRV9BUlJBWV9QUk9QX05BTUVTID0gWyAiY29tcGF0aWJsZV9icmFuZHMiLCAibWF0cml4IiwgIm9wY29sb3IiLCAic2FtcGxlX2NvdW50cyIsICJzYW1wbGVfY291bnRzIiwgInNhbXBsZV9kZWx0YXMiLAoJImZpcnN0X2NodW5rIiwgInNhbXBsZXNfcGVyX2NodW5rIiwgInNhbXBsZV9zaXplcyIsICJjaHVua19vZmZzZXRzIiwgInNhbXBsZV9vZmZzZXRzIiwgInNhbXBsZV9kZXNjcmlwdGlvbl9pbmRleCIsICJzYW1wbGVfZHVyYXRpb24iIF07CgoJQm94UGFyc2VyLmJveEVxdWFsRmllbGRzID0gZnVuY3Rpb24oYm94X2EsIGJveF9iKSB7CgkJaWYgKGJveF9hICYmICFib3hfYikgcmV0dXJuIGZhbHNlOwoJCXZhciBwcm9wOwoJCWZvciAocHJvcCBpbiBib3hfYSkgewoJCQlpZiAoQm94UGFyc2VyLkRJRkZfQk9YRVNfUFJPUF9OQU1FUy5pbmRleE9mKHByb3ApID4gLTEpIHsKCQkJCWNvbnRpbnVlOwoJCQkvLyB9IGVsc2UgaWYgKGV4Y2x1ZGVkX2ZpZWxkcyAmJiBleGNsdWRlZF9maWVsZHMuaW5kZXhPZihwcm9wKSA+IC0xKSB7CgkJCS8vIAljb250aW51ZTsKCQkJfSBlbHNlIGlmIChib3hfYVtwcm9wXSBpbnN0YW5jZW9mIEJveFBhcnNlci5Cb3ggfHwgYm94X2JbcHJvcF0gaW5zdGFuY2VvZiBCb3hQYXJzZXIuQm94KSB7CgkJCQljb250aW51ZTsKCQkJfSBlbHNlIGlmICh0eXBlb2YgYm94X2FbcHJvcF0gPT09ICJ1bmRlZmluZWQiIHx8IHR5cGVvZiBib3hfYltwcm9wXSA9PT0gInVuZGVmaW5lZCIpIHsKCQkJCWNvbnRpbnVlOwoJCQl9IGVsc2UgaWYgKHR5cGVvZiBib3hfYVtwcm9wXSA9PT0gImZ1bmN0aW9uIiB8fCB0eXBlb2YgYm94X2JbcHJvcF0gPT09ICJmdW5jdGlvbiIpIHsKCQkJCWNvbnRpbnVlOwoJCQl9IGVsc2UgaWYgKAoJCQkJKGJveF9hLnN1YkJveE5hbWVzICYmIGJveF9hLnN1YkJveE5hbWVzLmluZGV4T2YocHJvcC5zbGljZSgwLDQpKSA+IC0xKSB8fAoJCQkJKGJveF9iLnN1YkJveE5hbWVzICYmIGJveF9iLnN1YkJveE5hbWVzLmluZGV4T2YocHJvcC5zbGljZSgwLDQpKSA+IC0xKSkgIHsKCQkJCWNvbnRpbnVlOwoJCQl9IGVsc2UgewoJCQkJaWYgKHByb3AgPT09ICJkYXRhIiB8fCBwcm9wID09PSAic3RhcnQiIHx8IHByb3AgPT09ICJzaXplIiB8fCBwcm9wID09PSAiY3JlYXRpb25fdGltZSIgfHwgcHJvcCA9PT0gIm1vZGlmaWNhdGlvbl90aW1lIikgewoJCQkJCWNvbnRpbnVlOwoJCQkJfSBlbHNlIGlmIChCb3hQYXJzZXIuRElGRl9QUklNSVRJVkVfQVJSQVlfUFJPUF9OQU1FUy5pbmRleE9mKHByb3ApID4gLTEpIHsKCQkJCQljb250aW51ZTsKCQkJCX0gZWxzZSB7CgkJCQkJaWYgKGJveF9hW3Byb3BdICE9PSBib3hfYltwcm9wXSkgewoJCQkJCQlyZXR1cm4gZmFsc2U7CgkJCQkJfQoJCQkJfQoJCQl9CgkJfQoJCXJldHVybiB0cnVlOwoJfTsKCglCb3hQYXJzZXIuYm94RXF1YWwgPSBmdW5jdGlvbihib3hfYSwgYm94X2IpIHsKCQlpZiAoIUJveFBhcnNlci5ib3hFcXVhbEZpZWxkcyhib3hfYSwgYm94X2IpKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgkJZm9yICh2YXIgaiA9IDA7IGogPCBCb3hQYXJzZXIuRElGRl9CT1hFU19QUk9QX05BTUVTLmxlbmd0aDsgaisrKSB7CgkJCXZhciBuYW1lID0gQm94UGFyc2VyLkRJRkZfQk9YRVNfUFJPUF9OQU1FU1tqXTsKCQkJaWYgKGJveF9hW25hbWVdICYmIGJveF9iW25hbWVdKSB7CgkJCQlpZiAoIUJveFBhcnNlci5ib3hFcXVhbChib3hfYVtuYW1lXSwgYm94X2JbbmFtZV0pKSB7CgkJCQkJcmV0dXJuIGZhbHNlOwoJCQkJfQoJCQl9CgkJfQoJCXJldHVybiB0cnVlOwoJfTsvLyBmaWxlOnNyYy90ZXh0LW1wNC5qcwoKCXZhciBYTUxTdWJ0aXRsZWluNFBhcnNlciA9IGZ1bmN0aW9uKCkgewkKCX07CgoJWE1MU3VidGl0bGVpbjRQYXJzZXIucHJvdG90eXBlLnBhcnNlU2FtcGxlID0gZnVuY3Rpb24oc2FtcGxlKSB7CgkJdmFyIHJlcyA9IHt9OwkKCQl2YXIgaTsKCQlyZXMucmVzb3VyY2VzID0gW107CgkJdmFyIHN0cmVhbSA9IG5ldyBNUDRCb3hTdHJlYW0oc2FtcGxlLmRhdGEuYnVmZmVyKTsKCQlpZiAoIXNhbXBsZS5zdWJzYW1wbGVzIHx8IHNhbXBsZS5zdWJzYW1wbGVzLmxlbmd0aCA9PT0gMCkgewoJCQlyZXMuZG9jdW1lbnRTdHJpbmcgPSBzdHJlYW0ucmVhZFN0cmluZyhzYW1wbGUuZGF0YS5sZW5ndGgpOwoJCX0gZWxzZSB7CgkJCXJlcy5kb2N1bWVudFN0cmluZyA9IHN0cmVhbS5yZWFkU3RyaW5nKHNhbXBsZS5zdWJzYW1wbGVzWzBdLnNpemUpOwoJCQlpZiAoc2FtcGxlLnN1YnNhbXBsZXMubGVuZ3RoID4gMSkgewoJCQkJZm9yIChpID0gMTsgaSA8IHNhbXBsZS5zdWJzYW1wbGVzLmxlbmd0aDsgaSsrKSB7CgkJCQkJcmVzLnJlc291cmNlc1tpXSA9IHN0cmVhbS5yZWFkVWludDhBcnJheShzYW1wbGUuc3Vic2FtcGxlc1tpXS5zaXplKTsKCQkJCX0KCQkJfQoJCX0KCQlpZiAodHlwZW9mIChET01QYXJzZXIpICE9PSAidW5kZWZpbmVkIikgewoJCQlyZXMuZG9jdW1lbnQgPSAobmV3IERPTVBhcnNlcigpKS5wYXJzZUZyb21TdHJpbmcocmVzLmRvY3VtZW50U3RyaW5nLCAiYXBwbGljYXRpb24veG1sIik7CgkJfQoJCXJldHVybiByZXM7Cgl9OwoKCXZhciBUZXh0aW40UGFyc2VyID0gZnVuY3Rpb24oKSB7CQoJfTsKCglUZXh0aW40UGFyc2VyLnByb3RvdHlwZS5wYXJzZVNhbXBsZSA9IGZ1bmN0aW9uKHNhbXBsZSkgewoJCXZhciB0ZXh0U3RyaW5nOwoJCXZhciBzdHJlYW0gPSBuZXcgTVA0Qm94U3RyZWFtKHNhbXBsZS5kYXRhLmJ1ZmZlcik7CgkJdGV4dFN0cmluZyA9IHN0cmVhbS5yZWFkU3RyaW5nKHNhbXBsZS5kYXRhLmxlbmd0aCk7CgkJcmV0dXJuIHRleHRTdHJpbmc7Cgl9OwoKCVRleHRpbjRQYXJzZXIucHJvdG90eXBlLnBhcnNlQ29uZmlnID0gZnVuY3Rpb24oZGF0YSkgewoJCXZhciB0ZXh0U3RyaW5nOwoJCXZhciBzdHJlYW0gPSBuZXcgTVA0Qm94U3RyZWFtKGRhdGEuYnVmZmVyKTsKCQlzdHJlYW0ucmVhZFVpbnQzMigpOyAvLyB2ZXJzaW9uICYgZmxhZ3MKCQl0ZXh0U3RyaW5nID0gc3RyZWFtLnJlYWRDU3RyaW5nKCk7CgkJcmV0dXJuIHRleHRTdHJpbmc7Cgl9OwoKCXsKCQlleHBvcnRzLlhNTFN1YnRpdGxlaW40UGFyc2VyID0gWE1MU3VidGl0bGVpbjRQYXJzZXI7CgkJZXhwb3J0cy5UZXh0aW40UGFyc2VyID0gVGV4dGluNFBhcnNlcjsKCX0KCS8vIGZpbGU6c3JjL2lzb2ZpbGUuanMKCS8qCgkgKiBDb3B5cmlnaHQgKGMpIDIwMTItMjAxMy4gVGVsZWNvbSBQYXJpc1RlY2gvVFNJL01NL0dQQUMgQ3lyaWwgQ29uY29sYXRvCgkgKiBMaWNlbnNlOiBCU0QtMy1DbGF1c2UgKHNlZSBMSUNFTlNFIGZpbGUpCgkgKi8KCXZhciBJU09GaWxlID0gZnVuY3Rpb24gKHN0cmVhbSkgewoJCS8qIE11dGlCdWZmZXJTdHJlYW0gb2JqZWN0IHVzZWQgdG8gcGFyc2UgYm94ZXMgKi8KCQl0aGlzLnN0cmVhbSA9IHN0cmVhbSB8fCBuZXcgTXVsdGlCdWZmZXJTdHJlYW0oKTsKCQkvKiBBcnJheSBvZiBhbGwgYm94ZXMgKGluIG9yZGVyKSBmb3VuZCBpbiB0aGUgZmlsZSAqLwoJCXRoaXMuYm94ZXMgPSBbXTsKCQkvKiBBcnJheSBvZiBhbGwgbWRhdHMgKi8KCQl0aGlzLm1kYXRzID0gW107CgkJLyogQXJyYXkgb2YgYWxsIG1vb2ZzICovCgkJdGhpcy5tb29mcyA9IFtdOwoJCS8qIEJvb2xlYW4gaW5kaWNhdGluZyBpZiB0aGUgZmlsZSBpcyBjb21wYXRpYmxlIHdpdGggcHJvZ3Jlc3NpdmUgcGFyc2luZyAobW9vdiBmaXJzdCkgKi8KCQl0aGlzLmlzUHJvZ3Jlc3NpdmUgPSBmYWxzZTsKCQkvKiBCb29sZWFuIHVzZWQgdG8gZmlyZSBtb292IHN0YXJ0IGV2ZW50IG9ubHkgb25jZSAqLwoJCXRoaXMubW9vdlN0YXJ0Rm91bmQgPSBmYWxzZTsKCQkvKiBDYWxsYmFjayBjYWxsZWQgd2hlbiB0aGUgbW9vdiBwYXJzaW5nIHN0YXJ0cyAqLwoJCXRoaXMub25Nb292U3RhcnQgPSBudWxsOwoJCS8qIEJvb2xlYW4ga2VlcGluZyB0cmFjayBvZiB0aGUgY2FsbCB0byBvbk1vb3ZTdGFydCwgdG8gYXZvaWQgZG91YmxlIGNhbGxzICovCgkJdGhpcy5tb292U3RhcnRTZW50ID0gZmFsc2U7CgkJLyogQ2FsbGJhY2sgY2FsbGVkIHdoZW4gdGhlIG1vb3YgaXMgZW50aXJlbHkgcGFyc2VkICovCgkJdGhpcy5vblJlYWR5ID0gbnVsbDsKCQkvKiBCb29sZWFuIGtlZXBpbmcgdHJhY2sgb2YgdGhlIGNhbGwgdG8gb25SZWFkeSwgdG8gYXZvaWQgZG91YmxlIGNhbGxzICovCgkJdGhpcy5yZWFkeVNlbnQgPSBmYWxzZTsKCQkvKiBDYWxsYmFjayB0byBjYWxsIHdoZW4gc2VnbWVudHMgYXJlIHJlYWR5ICovCgkJdGhpcy5vblNlZ21lbnQgPSBudWxsOwoJCS8qIENhbGxiYWNrIHRvIGNhbGwgd2hlbiBzYW1wbGVzIGFyZSByZWFkeSAqLwoJCXRoaXMub25TYW1wbGVzID0gbnVsbDsKCQkvKiBDYWxsYmFjayB0byBjYWxsIHdoZW4gdGhlcmUgaXMgYW4gZXJyb3IgaW4gdGhlIHBhcnNpbmcgb3IgcHJvY2Vzc2luZyBvZiBzYW1wbGVzICovCgkJdGhpcy5vbkVycm9yID0gbnVsbDsKCQkvKiBCb29sZWFuIGluZGljYXRpbmcgaWYgdGhlIG1vb3YgYm94IHJ1bi1sZW5ndGggZW5jb2RlZCB0YWJsZXMgb2Ygc2FtcGxlIGluZm9ybWF0aW9uIGhhdmUgYmVlbiBwcm9jZXNzZWQgKi8KCQl0aGlzLnNhbXBsZUxpc3RCdWlsdCA9IGZhbHNlOwoJCS8qIEFycmF5IG9mIFRyYWNrIG9iamVjdHMgZm9yIHdoaWNoIGZyYWdtZW50YXRpb24gb2Ygc2FtcGxlcyBpcyByZXF1ZXN0ZWQgKi8KCQl0aGlzLmZyYWdtZW50ZWRUcmFja3MgPSBbXTsKCQkvKiBBcnJheSBvZiBUcmFjayBvYmplY3RzIGZvciB3aGljaCBleHRyYWN0aW9uIG9mIHNhbXBsZXMgaXMgcmVxdWVzdGVkICovCgkJdGhpcy5leHRyYWN0ZWRUcmFja3MgPSBbXTsKCQkvKiBCb29sZWFuIGluZGljYXRpbmcgdGhhdCBmcmFnbWVudGlvbiBpcyByZWFkeSAqLwoJCXRoaXMuaXNGcmFnbWVudGF0aW9uSW5pdGlhbGl6ZWQgPSBmYWxzZTsKCQkvKiBCb29sZWFuIGluZGljYXRpbmcgdGhhdCBmcmFnbWVudGVkIGhhcyBzdGFydGVkICovCgkJdGhpcy5zYW1wbGVQcm9jZXNzaW5nU3RhcnRlZCA9IGZhbHNlOwoJCS8qIE51bWJlciBvZiB0aGUgbmV4dCAnbW9vZicgdG8gZ2VuZXJhdGUgd2hlbiBmcmFnbWVudGluZyAqLwoJCXRoaXMubmV4dE1vb2ZOdW1iZXIgPSAwOwoJCS8qIEJvb2xlYW4gaW5kaWNhdGluZyBpZiB0aGUgaW5pdGlhbCBsaXN0IG9mIGl0ZW1zIGhhcyBiZWVuIHByb2R1Y2VkICovCgkJdGhpcy5pdGVtTGlzdEJ1aWx0ID0gZmFsc2U7CgkJLyogQ2FsbGJhY2sgY2FsbGVkIHdoZW4gdGhlIHNpZHggYm94IGlzIGVudGlyZWx5IHBhcnNlZCAqLwoJCXRoaXMub25TaWR4ID0gbnVsbDsKCQkvKiBCb29sZWFuIGtlZXBpbmcgdHJhY2sgb2YgdGhlIGNhbGwgdG8gb25TaWR4LCB0byBhdm9pZCBkb3VibGUgY2FsbHMgKi8KCQl0aGlzLnNpZHhTZW50ID0gZmFsc2U7Cgl9OwoKCUlTT0ZpbGUucHJvdG90eXBlLnNldFNlZ21lbnRPcHRpb25zID0gZnVuY3Rpb24oaWQsIHVzZXIsIG9wdGlvbnMpIHsKCQl2YXIgdHJhayA9IHRoaXMuZ2V0VHJhY2tCeUlkKGlkKTsKCQlpZiAodHJhaykgewoJCQl2YXIgZnJhZ1RyYWNrID0ge307CgkJCXRoaXMuZnJhZ21lbnRlZFRyYWNrcy5wdXNoKGZyYWdUcmFjayk7CgkJCWZyYWdUcmFjay5pZCA9IGlkOwoJCQlmcmFnVHJhY2sudXNlciA9IHVzZXI7CgkJCWZyYWdUcmFjay50cmFrID0gdHJhazsKCQkJdHJhay5uZXh0U2FtcGxlID0gMDsKCQkJZnJhZ1RyYWNrLnNlZ21lbnRTdHJlYW0gPSBudWxsOwoJCQlmcmFnVHJhY2submJfc2FtcGxlcyA9IDEwMDA7CgkJCWZyYWdUcmFjay5yYXBBbGlnbmVtZW50ID0gdHJ1ZTsKCQkJaWYgKG9wdGlvbnMpIHsKCQkJCWlmIChvcHRpb25zLm5iU2FtcGxlcykgZnJhZ1RyYWNrLm5iX3NhbXBsZXMgPSBvcHRpb25zLm5iU2FtcGxlczsKCQkJCWlmIChvcHRpb25zLnJhcEFsaWduZW1lbnQpIGZyYWdUcmFjay5yYXBBbGlnbmVtZW50ID0gb3B0aW9ucy5yYXBBbGlnbmVtZW50OwoJCQl9CgkJfQoJfTsKCglJU09GaWxlLnByb3RvdHlwZS51bnNldFNlZ21lbnRPcHRpb25zID0gZnVuY3Rpb24oaWQpIHsKCQl2YXIgaW5kZXggPSAtMTsKCQlmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuZnJhZ21lbnRlZFRyYWNrcy5sZW5ndGg7IGkrKykgewoJCQl2YXIgZnJhZ1RyYWNrID0gdGhpcy5mcmFnbWVudGVkVHJhY2tzW2ldOwoJCQlpZiAoZnJhZ1RyYWNrLmlkID09IGlkKSB7CgkJCQlpbmRleCA9IGk7CgkJCX0KCQl9CgkJaWYgKGluZGV4ID4gLTEpIHsKCQkJdGhpcy5mcmFnbWVudGVkVHJhY2tzLnNwbGljZShpbmRleCwgMSk7CgkJfQoJfTsKCglJU09GaWxlLnByb3RvdHlwZS5zZXRFeHRyYWN0aW9uT3B0aW9ucyA9IGZ1bmN0aW9uKGlkLCB1c2VyLCBvcHRpb25zKSB7CgkJdmFyIHRyYWsgPSB0aGlzLmdldFRyYWNrQnlJZChpZCk7CgkJaWYgKHRyYWspIHsKCQkJdmFyIGV4dHJhY3RUcmFjayA9IHt9OwoJCQl0aGlzLmV4dHJhY3RlZFRyYWNrcy5wdXNoKGV4dHJhY3RUcmFjayk7CgkJCWV4dHJhY3RUcmFjay5pZCA9IGlkOwoJCQlleHRyYWN0VHJhY2sudXNlciA9IHVzZXI7CgkJCWV4dHJhY3RUcmFjay50cmFrID0gdHJhazsKCQkJdHJhay5uZXh0U2FtcGxlID0gMDsKCQkJZXh0cmFjdFRyYWNrLm5iX3NhbXBsZXMgPSAxMDAwOwoJCQlleHRyYWN0VHJhY2suc2FtcGxlcyA9IFtdOwoJCQlpZiAob3B0aW9ucykgewoJCQkJaWYgKG9wdGlvbnMubmJTYW1wbGVzKSBleHRyYWN0VHJhY2submJfc2FtcGxlcyA9IG9wdGlvbnMubmJTYW1wbGVzOwoJCQl9CgkJfQoJfTsKCglJU09GaWxlLnByb3RvdHlwZS51bnNldEV4dHJhY3Rpb25PcHRpb25zID0gZnVuY3Rpb24oaWQpIHsKCQl2YXIgaW5kZXggPSAtMTsKCQlmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuZXh0cmFjdGVkVHJhY2tzLmxlbmd0aDsgaSsrKSB7CgkJCXZhciBleHRyYWN0VHJhY2sgPSB0aGlzLmV4dHJhY3RlZFRyYWNrc1tpXTsKCQkJaWYgKGV4dHJhY3RUcmFjay5pZCA9PSBpZCkgewoJCQkJaW5kZXggPSBpOwoJCQl9CgkJfQoJCWlmIChpbmRleCA+IC0xKSB7CgkJCXRoaXMuZXh0cmFjdGVkVHJhY2tzLnNwbGljZShpbmRleCwgMSk7CgkJfQoJfTsKCglJU09GaWxlLnByb3RvdHlwZS5wYXJzZSA9IGZ1bmN0aW9uKCkgewoJCXZhciByZXQ7CgkJdmFyIGJveDsKCQl2YXIgcGFyc2VCb3hIZWFkZXJzT25seSA9IGZhbHNlOwoKCQlpZiAodGhpcy5yZXN0b3JlUGFyc2VQb3NpdGlvbikJewoJCQlpZiAoIXRoaXMucmVzdG9yZVBhcnNlUG9zaXRpb24oKSkgewoJCQkJcmV0dXJuOwoJCQl9CgkJfQoKCQl3aGlsZSAodHJ1ZSkgewoKCQkJaWYgKHRoaXMuaGFzSW5jb21wbGV0ZU1kYXQgJiYgdGhpcy5oYXNJbmNvbXBsZXRlTWRhdCgpKSB7CgkJCQlpZiAodGhpcy5wcm9jZXNzSW5jb21wbGV0ZU1kYXQoKSkgewoJCQkJCWNvbnRpbnVlOwoJCQkJfSBlbHNlIHsKCQkJCQlyZXR1cm47CgkJCQl9CgkJCX0gZWxzZSB7CgkJCQlpZiAodGhpcy5zYXZlUGFyc2VQb3NpdGlvbikJewoJCQkJCXRoaXMuc2F2ZVBhcnNlUG9zaXRpb24oKTsKCQkJCX0KCQkJCXJldCA9IEJveFBhcnNlci5wYXJzZU9uZUJveCh0aGlzLnN0cmVhbSwgcGFyc2VCb3hIZWFkZXJzT25seSk7CgkJCQlpZiAocmV0LmNvZGUgPT09IEJveFBhcnNlci5FUlJfTk9UX0VOT1VHSF9EQVRBKSB7CgkJCQkJaWYgKHRoaXMucHJvY2Vzc0luY29tcGxldGVCb3gpIHsKCQkJCQkJaWYgKHRoaXMucHJvY2Vzc0luY29tcGxldGVCb3gocmV0KSkgewoJCQkJCQkJY29udGludWU7CgkJCQkJCX0gZWxzZSB7CgkJCQkJCQlyZXR1cm47CgkJCQkJCX0KCQkJCQl9IGVsc2UgewoJCQkJCQlyZXR1cm47CgkJCQkJfQoJCQkJfSBlbHNlIHsKCQkJCQl2YXIgYm94X3R5cGU7CgkJCQkJLyogdGhlIGJveCBpcyBlbnRpcmVseSBwYXJzZWQgKi8KCQkJCQlib3ggPSByZXQuYm94OwoJCQkJCWJveF90eXBlID0gKGJveC50eXBlICE9PSAidXVpZCIgPyBib3gudHlwZSA6IGJveC51dWlkKTsKCQkJCQkvKiBzdG9yZSB0aGUgYm94IGluIHRoZSAnYm94ZXMnIGFycmF5IHRvIHByZXNlcnZlIGJveCBvcmRlciAoZm9yIGZpbGUgcmV3cml0ZSBpZiBuZWVkZWQpICAqLwoJCQkJCXRoaXMuYm94ZXMucHVzaChib3gpOwoJCQkJCS8qIGJ1dCBhbHNvIHN0b3JlIGJveCBpbiBhIHByb3BlcnR5IGZvciBtb3JlIGRpcmVjdCBhY2Nlc3MgKi8KCQkJCQlzd2l0Y2ggKGJveF90eXBlKSB7CgkJCQkJCWNhc2UgIm1kYXQiOgoJCQkJCQkJdGhpcy5tZGF0cy5wdXNoKGJveCk7CgkJCQkJCQlicmVhazsKCQkJCQkJY2FzZSAibW9vZiI6CgkJCQkJCQl0aGlzLm1vb2ZzLnB1c2goYm94KTsKCQkJCQkJCWJyZWFrOwoJCQkJCQljYXNlICJtb292IjoKCQkJCQkJCXRoaXMubW9vdlN0YXJ0Rm91bmQgPSB0cnVlOwoJCQkJCQkJaWYgKHRoaXMubWRhdHMubGVuZ3RoID09PSAwKSB7CgkJCQkJCQkJdGhpcy5pc1Byb2dyZXNzaXZlID0gdHJ1ZTsKCQkJCQkJCX0KCQkJCQkJCS8qIG5vIGJyZWFrICovCgkJCQkJCQkvKiBmYWxscyB0aHJvdWdoICovCgkJCQkJCWRlZmF1bHQ6CgkJCQkJCQlpZiAodGhpc1tib3hfdHlwZV0gIT09IHVuZGVmaW5lZCkgewoJCQkJCQkJCUxvZy53YXJuKCJJU09GaWxlIiwgIkR1cGxpY2F0ZSBCb3ggb2YgdHlwZTogIitib3hfdHlwZSsiLCBvdmVycmlkaW5nIHByZXZpb3VzIG9jY3VycmVuY2UiKTsKCQkJCQkJCX0KCQkJCQkJCXRoaXNbYm94X3R5cGVdID0gYm94OwoJCQkJCQkJYnJlYWs7CgkJCQkJfQoJCQkJCWlmICh0aGlzLnVwZGF0ZVVzZWRCeXRlcykgewoJCQkJCQl0aGlzLnVwZGF0ZVVzZWRCeXRlcyhib3gsIHJldCk7CgkJCQkJfQoJCQkJfQoJCQl9CgkJfQoJfTsKCglJU09GaWxlLnByb3RvdHlwZS5jaGVja0J1ZmZlciA9IGZ1bmN0aW9uIChhYikgewoJCWlmIChhYiA9PT0gbnVsbCB8fCBhYiA9PT0gdW5kZWZpbmVkKSB7CgkJCXRocm93KCJCdWZmZXIgbXVzdCBiZSBkZWZpbmVkIGFuZCBub24gZW1wdHkiKTsKCQl9CgkJaWYgKGFiLmZpbGVTdGFydCA9PT0gdW5kZWZpbmVkKSB7CgkJCXRocm93KCJCdWZmZXIgbXVzdCBoYXZlIGEgZmlsZVN0YXJ0IHByb3BlcnR5Iik7CgkJfQoJCWlmIChhYi5ieXRlTGVuZ3RoID09PSAwKSB7CgkJCUxvZy53YXJuKCJJU09GaWxlIiwgIklnbm9yaW5nIGVtcHR5IGJ1ZmZlciAoZmlsZVN0YXJ0OiAiK2FiLmZpbGVTdGFydCsiKSIpOwoJCQl0aGlzLnN0cmVhbS5sb2dCdWZmZXJMZXZlbCgpOwoJCQlyZXR1cm4gZmFsc2U7CgkJfQoJCUxvZy5pbmZvKCJJU09GaWxlIiwgIlByb2Nlc3NpbmcgYnVmZmVyIChmaWxlU3RhcnQ6ICIrYWIuZmlsZVN0YXJ0KyIpIik7CgoJCS8qIG1hcmsgdGhlIGJ5dGVzIGluIHRoZSBidWZmZXIgYXMgbm90IGJlaW5nIHVzZWQgeWV0ICovCgkJYWIudXNlZEJ5dGVzID0gMDsKCQl0aGlzLnN0cmVhbS5pbnNlcnRCdWZmZXIoYWIpOwoJCXRoaXMuc3RyZWFtLmxvZ0J1ZmZlckxldmVsKCk7CgoJCWlmICghdGhpcy5zdHJlYW0uaW5pdGlhbGl6ZWQoKSkgewoJCQlMb2cud2FybigiSVNPRmlsZSIsICJOb3QgcmVhZHkgdG8gc3RhcnQgcGFyc2luZyIpOwoJCQlyZXR1cm4gZmFsc2U7CgkJfQoJCXJldHVybiB0cnVlOwoJfTsKCgkvKiBQcm9jZXNzZXMgYSBuZXcgQXJyYXlCdWZmZXIgKHdpdGggYSBmaWxlU3RhcnQgcHJvcGVydHkpCgkgICBSZXR1cm5zIHRoZSBuZXh0IGV4cGVjdGVkIGZpbGUgcG9zaXRpb24sIG9yIHVuZGVmaW5lZCBpZiBub3QgcmVhZHkgdG8gcGFyc2UgKi8KCUlTT0ZpbGUucHJvdG90eXBlLmFwcGVuZEJ1ZmZlciA9IGZ1bmN0aW9uKGFiLCBsYXN0KSB7CgkJdmFyIG5leHRGaWxlU3RhcnQ7CgkJaWYgKCF0aGlzLmNoZWNrQnVmZmVyKGFiKSkgewoJCQlyZXR1cm47CgkJfQoKCQkvKiBQYXJzZSB3aGF0ZXZlciBpcyBpbiB0aGUgZXhpc3RpbmcgYnVmZmVycyAqLwoJCXRoaXMucGFyc2UoKTsKCgkJLyogQ2hlY2sgaWYgdGhlIG1vb3ZTdGFydCBjYWxsYmFjayBuZWVkcyB0byBiZSBjYWxsZWQgKi8KCQlpZiAodGhpcy5tb292U3RhcnRGb3VuZCAmJiAhdGhpcy5tb292U3RhcnRTZW50KSB7CgkJCXRoaXMubW9vdlN0YXJ0U2VudCA9IHRydWU7CgkJCWlmICh0aGlzLm9uTW9vdlN0YXJ0KSB0aGlzLm9uTW9vdlN0YXJ0KCk7CgkJfQoKCQlpZiAodGhpcy5tb292KSB7CgkJCS8qIEEgbW9vdiBib3ggaGFzIGJlZW4gZW50aXJlbHkgcGFyc2VkICovCgoJCQkvKiBpZiB0aGlzIGlzIHRoZSBmaXJzdCBjYWxsIGFmdGVyIHRoZSBtb292IGlzIGZvdW5kIHdlIGluaXRpYWxpemUgdGhlIGxpc3Qgb2Ygc2FtcGxlcyAobWF5IGJlIGVtcHR5IGluIGZyYWdtZW50ZWQgZmlsZXMpICovCgkJCWlmICghdGhpcy5zYW1wbGVMaXN0QnVpbHQpIHsKCQkJCXRoaXMuYnVpbGRTYW1wbGVMaXN0cygpOwoJCQkJdGhpcy5zYW1wbGVMaXN0QnVpbHQgPSB0cnVlOwoJCQl9CgoJCQkvKiBXZSB1cGRhdGUgdGhlIHNhbXBsZSBpbmZvcm1hdGlvbiBpZiB0aGVyZSBhcmUgYW55IG5ldyBtb29mIGJveGVzICovCgkJCXRoaXMudXBkYXRlU2FtcGxlTGlzdHMoKTsKCgkJCS8qIElmIHRoZSBhcHBsaWNhdGlvbiBuZWVkcyB0byBiZSBpbmZvcm1lZCB0aGF0IHRoZSAnbW9vdicgaGFzIGJlZW4gZm91bmQsCgkJCSAgIHdlIGNyZWF0ZSB0aGUgaW5mb3JtYXRpb24gb2JqZWN0IGFuZCBjYWxsYmFjayB0aGUgYXBwbGljYXRpb24gKi8KCQkJaWYgKHRoaXMub25SZWFkeSAmJiAhdGhpcy5yZWFkeVNlbnQpIHsKCQkJCXRoaXMucmVhZHlTZW50ID0gdHJ1ZTsKCQkJCXRoaXMub25SZWFkeSh0aGlzLmdldEluZm8oKSk7CgkJCX0KCgkJCS8qIFNlZSBpZiBhbnkgc2FtcGxlIGV4dHJhY3Rpb24gb3Igc2VnbWVudCBjcmVhdGlvbiBuZWVkcyB0byBiZSBkb25lIHdpdGggdGhlIGF2YWlsYWJsZSBzYW1wbGVzICovCgkJCXRoaXMucHJvY2Vzc1NhbXBsZXMobGFzdCk7CgoJCQkvKiBJbmZvcm0gYWJvdXQgdGhlIGJlc3QgcmFuZ2UgdG8gZmV0Y2ggbmV4dCAqLwoJCQlpZiAodGhpcy5uZXh0U2Vla1Bvc2l0aW9uKSB7CgkJCQluZXh0RmlsZVN0YXJ0ID0gdGhpcy5uZXh0U2Vla1Bvc2l0aW9uOwoJCQkJdGhpcy5uZXh0U2Vla1Bvc2l0aW9uID0gdW5kZWZpbmVkOwoJCQl9IGVsc2UgewoJCQkJbmV4dEZpbGVTdGFydCA9IHRoaXMubmV4dFBhcnNlUG9zaXRpb247CgkJCX0KCQkJaWYgKHRoaXMuc3RyZWFtLmdldEVuZEZpbGVQb3NpdGlvbkFmdGVyKSB7CgkJCQluZXh0RmlsZVN0YXJ0ID0gdGhpcy5zdHJlYW0uZ2V0RW5kRmlsZVBvc2l0aW9uQWZ0ZXIobmV4dEZpbGVTdGFydCk7CgkJCX0KCQl9IGVsc2UgewoJCQlpZiAodGhpcy5uZXh0UGFyc2VQb3NpdGlvbikgewoJCQkJLyogbW9vdiBoYXMgbm90IGJlZW4gcGFyc2VkIGJ1dCB0aGUgZmlyc3QgYnVmZmVyIHdhcyByZWNlaXZlZCwKCQkJCSAgIHRoZSBuZXh0IGZldGNoIHNob3VsZCBwcm9iYWJseSBiZSB0aGUgbmV4dCBib3ggc3RhcnQgKi8KCQkJCW5leHRGaWxlU3RhcnQgPSB0aGlzLm5leHRQYXJzZVBvc2l0aW9uOwoJCQl9IGVsc2UgewoJCQkJLyogTm8gdmFsaWQgYnVmZmVyIGhhcyBiZWVuIHBhcnNlZCB5ZXQsIHdlIGNhbm5vdCBrbm93IHdoYXQgdG8gcGFyc2UgbmV4dCAqLwoJCQkJbmV4dEZpbGVTdGFydCA9IDA7CgkJCX0KCQl9CgkJaWYgKHRoaXMuc2lkeCkgewoJCQlpZiAodGhpcy5vblNpZHggJiYgIXRoaXMuc2lkeFNlbnQpIHsKCQkJCXRoaXMub25TaWR4KHRoaXMuc2lkeCk7CgkJCQl0aGlzLnNpZHhTZW50ID0gdHJ1ZTsKCQkJfQoJCX0KCQlpZiAodGhpcy5tZXRhKSB7CgkJCWlmICh0aGlzLmZsYXR0ZW5JdGVtSW5mbyAmJiAhdGhpcy5pdGVtTGlzdEJ1aWx0KSB7CgkJCQl0aGlzLmZsYXR0ZW5JdGVtSW5mbygpOwoJCQkJdGhpcy5pdGVtTGlzdEJ1aWx0ID0gdHJ1ZTsKCQkJfQoJCQlpZiAodGhpcy5wcm9jZXNzSXRlbXMpIHsKCQkJCXRoaXMucHJvY2Vzc0l0ZW1zKHRoaXMub25JdGVtKTsKCQkJfQoJCX0KCgkJaWYgKHRoaXMuc3RyZWFtLmNsZWFuQnVmZmVycykgewoJCQlMb2cuaW5mbygiSVNPRmlsZSIsICJEb25lIHByb2Nlc3NpbmcgYnVmZmVyIChmaWxlU3RhcnQ6ICIrYWIuZmlsZVN0YXJ0KyIpIC0gbmV4dCBidWZmZXIgdG8gZmV0Y2ggc2hvdWxkIGhhdmUgYSBmaWxlU3RhcnQgcG9zaXRpb24gb2YgIituZXh0RmlsZVN0YXJ0KTsKCQkJdGhpcy5zdHJlYW0ubG9nQnVmZmVyTGV2ZWwoKTsKCQkJdGhpcy5zdHJlYW0uY2xlYW5CdWZmZXJzKCk7CgkJCXRoaXMuc3RyZWFtLmxvZ0J1ZmZlckxldmVsKHRydWUpOwoJCQlMb2cuaW5mbygiSVNPRmlsZSIsICJTYW1wbGUgZGF0YSBzaXplIGluIG1lbW9yeTogIit0aGlzLmdldEFsbG9jYXRlZFNhbXBsZURhdGFTaXplKCkpOwoJCX0KCQlyZXR1cm4gbmV4dEZpbGVTdGFydDsKCX07CgoJSVNPRmlsZS5wcm90b3R5cGUuZ2V0SW5mbyA9IGZ1bmN0aW9uKCkgewoJCXZhciBpLCBqOwoJCXZhciBtb3ZpZSA9IHt9OwoJCXZhciB0cmFrOwoJCXZhciB0cmFjazsKCQl2YXIgcmVmOwoJCXZhciBzYW1wbGVfZGVzYzsKCQl2YXIgXzE5MDQgPSAobmV3IERhdGUoJzE5MDQtMDEtMDFUMDA6MDA6MDBaJykuZ2V0VGltZSgpKTsKCgkJaWYgKHRoaXMubW9vdikgewoJCQltb3ZpZS5oYXNNb292ID0gdHJ1ZTsKCQkJbW92aWUuZHVyYXRpb24gPSB0aGlzLm1vb3YubXZoZC5kdXJhdGlvbjsKCQkJbW92aWUudGltZXNjYWxlID0gdGhpcy5tb292Lm12aGQudGltZXNjYWxlOwoJCQltb3ZpZS5pc0ZyYWdtZW50ZWQgPSAodGhpcy5tb292Lm12ZXggIT0gbnVsbCk7CgkJCWlmIChtb3ZpZS5pc0ZyYWdtZW50ZWQgJiYgdGhpcy5tb292Lm12ZXgubWVoZCkgewoJCQkJbW92aWUuZnJhZ21lbnRfZHVyYXRpb24gPSB0aGlzLm1vb3YubXZleC5tZWhkLmZyYWdtZW50X2R1cmF0aW9uOwoJCQl9CgkJCW1vdmllLmlzUHJvZ3Jlc3NpdmUgPSB0aGlzLmlzUHJvZ3Jlc3NpdmU7CgkJCW1vdmllLmhhc0lPRCA9ICh0aGlzLm1vb3YuaW9kcyAhPSBudWxsKTsKCQkJbW92aWUuYnJhbmRzID0gW107CgkJCW1vdmllLmJyYW5kcy5wdXNoKHRoaXMuZnR5cC5tYWpvcl9icmFuZCk7CgkJCW1vdmllLmJyYW5kcyA9IG1vdmllLmJyYW5kcy5jb25jYXQodGhpcy5mdHlwLmNvbXBhdGlibGVfYnJhbmRzKTsKCQkJbW92aWUuY3JlYXRlZCA9IG5ldyBEYXRlKF8xOTA0K3RoaXMubW9vdi5tdmhkLmNyZWF0aW9uX3RpbWUqMTAwMCk7CgkJCW1vdmllLm1vZGlmaWVkID0gbmV3IERhdGUoXzE5MDQrdGhpcy5tb292Lm12aGQubW9kaWZpY2F0aW9uX3RpbWUqMTAwMCk7CgkJCW1vdmllLnRyYWNrcyA9IFtdOwoJCQltb3ZpZS5hdWRpb1RyYWNrcyA9IFtdOwoJCQltb3ZpZS52aWRlb1RyYWNrcyA9IFtdOwoJCQltb3ZpZS5zdWJ0aXRsZVRyYWNrcyA9IFtdOwoJCQltb3ZpZS5tZXRhZGF0YVRyYWNrcyA9IFtdOwoJCQltb3ZpZS5oaW50VHJhY2tzID0gW107CgkJCW1vdmllLm90aGVyVHJhY2tzID0gW107CgkJCWZvciAoaSA9IDA7IGkgPCB0aGlzLm1vb3YudHJha3MubGVuZ3RoOyBpKyspIHsKCQkJCXRyYWsgPSB0aGlzLm1vb3YudHJha3NbaV07CgkJCQlzYW1wbGVfZGVzYyA9IHRyYWsubWRpYS5taW5mLnN0Ymwuc3RzZC5lbnRyaWVzWzBdOwoJCQkJdHJhY2sgPSB7fTsKCQkJCW1vdmllLnRyYWNrcy5wdXNoKHRyYWNrKTsKCQkJCXRyYWNrLmlkID0gdHJhay50a2hkLnRyYWNrX2lkOwoJCQkJdHJhY2submFtZSA9IHRyYWsubWRpYS5oZGxyLm5hbWU7CgkJCQl0cmFjay5yZWZlcmVuY2VzID0gW107CgkJCQlpZiAodHJhay50cmVmKSB7CgkJCQkJZm9yIChqID0gMDsgaiA8IHRyYWsudHJlZi5ib3hlcy5sZW5ndGg7IGorKykgewoJCQkJCQlyZWYgPSB7fTsKCQkJCQkJdHJhY2sucmVmZXJlbmNlcy5wdXNoKHJlZik7CgkJCQkJCXJlZi50eXBlID0gdHJhay50cmVmLmJveGVzW2pdLnR5cGU7CgkJCQkJCXJlZi50cmFja19pZHMgPSB0cmFrLnRyZWYuYm94ZXNbal0udHJhY2tfaWRzOwoJCQkJCX0KCQkJCX0KCQkJCWlmICh0cmFrLmVkdHMpIHsKCQkJCQl0cmFjay5lZGl0cyA9IHRyYWsuZWR0cy5lbHN0LmVudHJpZXM7CgkJCQl9CgkJCQl0cmFjay5jcmVhdGVkID0gbmV3IERhdGUoXzE5MDQrdHJhay50a2hkLmNyZWF0aW9uX3RpbWUqMTAwMCk7CgkJCQl0cmFjay5tb2RpZmllZCA9IG5ldyBEYXRlKF8xOTA0K3RyYWsudGtoZC5tb2RpZmljYXRpb25fdGltZSoxMDAwKTsKCQkJCXRyYWNrLm1vdmllX2R1cmF0aW9uID0gdHJhay50a2hkLmR1cmF0aW9uOwoJCQkJdHJhY2subW92aWVfdGltZXNjYWxlID0gbW92aWUudGltZXNjYWxlOwoJCQkJdHJhY2subGF5ZXIgPSB0cmFrLnRraGQubGF5ZXI7CgkJCQl0cmFjay5hbHRlcm5hdGVfZ3JvdXAgPSB0cmFrLnRraGQuYWx0ZXJuYXRlX2dyb3VwOwoJCQkJdHJhY2sudm9sdW1lID0gdHJhay50a2hkLnZvbHVtZTsKCQkJCXRyYWNrLm1hdHJpeCA9IHRyYWsudGtoZC5tYXRyaXg7CgkJCQl0cmFjay50cmFja193aWR0aCA9IHRyYWsudGtoZC53aWR0aC8oMTw8MTYpOwoJCQkJdHJhY2sudHJhY2tfaGVpZ2h0ID0gdHJhay50a2hkLmhlaWdodC8oMTw8MTYpOwoJCQkJdHJhY2sudGltZXNjYWxlID0gdHJhay5tZGlhLm1kaGQudGltZXNjYWxlOwoJCQkJdHJhY2suY3RzX3NoaWZ0ID0gdHJhay5tZGlhLm1pbmYuc3RibC5jc2xnOwoJCQkJdHJhY2suZHVyYXRpb24gPSB0cmFrLm1kaWEubWRoZC5kdXJhdGlvbjsKCQkJCXRyYWNrLnNhbXBsZXNfZHVyYXRpb24gPSB0cmFrLnNhbXBsZXNfZHVyYXRpb247CgkJCQl0cmFjay5jb2RlYyA9IHNhbXBsZV9kZXNjLmdldENvZGVjKCk7CgkJCQl0cmFjay5raW5kID0gKHRyYWsudWR0YSAmJiB0cmFrLnVkdGEua2luZHMubGVuZ3RoID8gdHJhay51ZHRhLmtpbmRzWzBdIDogeyBzY2hlbWVVUkk6ICIiLCB2YWx1ZTogIiJ9KTsKCQkJCXRyYWNrLmxhbmd1YWdlID0gKHRyYWsubWRpYS5lbG5nID8gdHJhay5tZGlhLmVsbmcuZXh0ZW5kZWRfbGFuZ3VhZ2UgOiB0cmFrLm1kaWEubWRoZC5sYW5ndWFnZVN0cmluZyk7CgkJCQl0cmFjay5uYl9zYW1wbGVzID0gdHJhay5zYW1wbGVzLmxlbmd0aDsKCQkJCXRyYWNrLnNpemUgPSB0cmFrLnNhbXBsZXNfc2l6ZTsKCQkJCXRyYWNrLmJpdHJhdGUgPSAodHJhY2suc2l6ZSo4KnRyYWNrLnRpbWVzY2FsZSkvdHJhY2suc2FtcGxlc19kdXJhdGlvbjsKCQkJCWlmIChzYW1wbGVfZGVzYy5pc0F1ZGlvKCkpIHsKCQkJCQl0cmFjay50eXBlID0gImF1ZGlvIjsKCQkJCQltb3ZpZS5hdWRpb1RyYWNrcy5wdXNoKHRyYWNrKTsKCQkJCQl0cmFjay5hdWRpbyA9IHt9OwoJCQkJCXRyYWNrLmF1ZGlvLnNhbXBsZV9yYXRlID0gc2FtcGxlX2Rlc2MuZ2V0U2FtcGxlUmF0ZSgpOwoJCQkJCXRyYWNrLmF1ZGlvLmNoYW5uZWxfY291bnQgPSBzYW1wbGVfZGVzYy5nZXRDaGFubmVsQ291bnQoKTsKCQkJCQl0cmFjay5hdWRpby5zYW1wbGVfc2l6ZSA9IHNhbXBsZV9kZXNjLmdldFNhbXBsZVNpemUoKTsKCQkJCX0gZWxzZSBpZiAoc2FtcGxlX2Rlc2MuaXNWaWRlbygpKSB7CgkJCQkJdHJhY2sudHlwZSA9ICJ2aWRlbyI7CgkJCQkJbW92aWUudmlkZW9UcmFja3MucHVzaCh0cmFjayk7CgkJCQkJdHJhY2sudmlkZW8gPSB7fTsKCQkJCQl0cmFjay52aWRlby53aWR0aCA9IHNhbXBsZV9kZXNjLmdldFdpZHRoKCk7CgkJCQkJdHJhY2sudmlkZW8uaGVpZ2h0ID0gc2FtcGxlX2Rlc2MuZ2V0SGVpZ2h0KCk7CgkJCQl9IGVsc2UgaWYgKHNhbXBsZV9kZXNjLmlzU3VidGl0bGUoKSkgewoJCQkJCXRyYWNrLnR5cGUgPSAic3VidGl0bGVzIjsKCQkJCQltb3ZpZS5zdWJ0aXRsZVRyYWNrcy5wdXNoKHRyYWNrKTsKCQkJCX0gZWxzZSBpZiAoc2FtcGxlX2Rlc2MuaXNIaW50KCkpIHsKCQkJCQl0cmFjay50eXBlID0gIm1ldGFkYXRhIjsKCQkJCQltb3ZpZS5oaW50VHJhY2tzLnB1c2godHJhY2spOwoJCQkJfSBlbHNlIGlmIChzYW1wbGVfZGVzYy5pc01ldGFkYXRhKCkpIHsKCQkJCQl0cmFjay50eXBlID0gIm1ldGFkYXRhIjsKCQkJCQltb3ZpZS5tZXRhZGF0YVRyYWNrcy5wdXNoKHRyYWNrKTsKCQkJCX0gZWxzZSB7CgkJCQkJdHJhY2sudHlwZSA9ICJtZXRhZGF0YSI7CgkJCQkJbW92aWUub3RoZXJUcmFja3MucHVzaCh0cmFjayk7CgkJCQl9CgkJCX0KCQl9IGVsc2UgewoJCQltb3ZpZS5oYXNNb292ID0gZmFsc2U7CgkJfQoJCW1vdmllLm1pbWUgPSAiIjsKCQlpZiAobW92aWUuaGFzTW9vdiAmJiBtb3ZpZS50cmFja3MpIHsKCQkJaWYgKG1vdmllLnZpZGVvVHJhY2tzICYmIG1vdmllLnZpZGVvVHJhY2tzLmxlbmd0aCA+IDApIHsKCQkJCW1vdmllLm1pbWUgKz0gJ3ZpZGVvL21wNDsgY29kZWNzPVwiJzsKCQkJfSBlbHNlIGlmIChtb3ZpZS5hdWRpb1RyYWNrcyAmJiBtb3ZpZS5hdWRpb1RyYWNrcy5sZW5ndGggPiAwKSB7CgkJCQltb3ZpZS5taW1lICs9ICdhdWRpby9tcDQ7IGNvZGVjcz1cIic7CgkJCX0gZWxzZSB7CgkJCQltb3ZpZS5taW1lICs9ICdhcHBsaWNhdGlvbi9tcDQ7IGNvZGVjcz1cIic7CgkJCX0KCQkJZm9yIChpID0gMDsgaSA8IG1vdmllLnRyYWNrcy5sZW5ndGg7IGkrKykgewoJCQkJaWYgKGkgIT09IDApIG1vdmllLm1pbWUgKz0gJywnOwoJCQkJbW92aWUubWltZSs9IG1vdmllLnRyYWNrc1tpXS5jb2RlYzsKCQkJfQoJCQltb3ZpZS5taW1lICs9ICdcIjsgcHJvZmlsZXM9XCInOwoJCQltb3ZpZS5taW1lICs9IHRoaXMuZnR5cC5jb21wYXRpYmxlX2JyYW5kcy5qb2luKCk7CgkJCW1vdmllLm1pbWUgKz0gJ1wiJzsKCQl9CgkJcmV0dXJuIG1vdmllOwoJfTsKCglJU09GaWxlLnByb3RvdHlwZS5wcm9jZXNzU2FtcGxlcyA9IGZ1bmN0aW9uKGxhc3QpIHsKCQl2YXIgaTsKCQl2YXIgdHJhazsKCQlpZiAoIXRoaXMuc2FtcGxlUHJvY2Vzc2luZ1N0YXJ0ZWQpIHJldHVybjsKCgkJLyogRm9yIGVhY2ggdHJhY2sgbWFya2VkIGZvciBmcmFnbWVudGF0aW9uLAoJCSAgIGNoZWNrIGlmIHRoZSBuZXh0IHNhbXBsZSBpcyB0aGVyZSAoaS5lLiBpZiB0aGUgc2FtcGxlIGluZm9ybWF0aW9uIGlzIGtub3duIChpLmUuIG1vb2YgaGFzIGFycml2ZWQpIGFuZCBpZiBpdCBoYXMgYmVlbiBkb3dubG9hZGVkKQoJCSAgIGFuZCBjcmVhdGUgYSBmcmFnbWVudCB3aXRoIGl0ICovCgkJaWYgKHRoaXMuaXNGcmFnbWVudGF0aW9uSW5pdGlhbGl6ZWQgJiYgdGhpcy5vblNlZ21lbnQgIT09IG51bGwpIHsKCQkJZm9yIChpID0gMDsgaSA8IHRoaXMuZnJhZ21lbnRlZFRyYWNrcy5sZW5ndGg7IGkrKykgewoJCQkJdmFyIGZyYWdUcmFrID0gdGhpcy5mcmFnbWVudGVkVHJhY2tzW2ldOwoJCQkJdHJhayA9IGZyYWdUcmFrLnRyYWs7CgkJCQl3aGlsZSAodHJhay5uZXh0U2FtcGxlIDwgdHJhay5zYW1wbGVzLmxlbmd0aCAmJiB0aGlzLnNhbXBsZVByb2Nlc3NpbmdTdGFydGVkKSB7CgkJCQkJLyogVGhlIHNhbXBsZSBpbmZvcm1hdGlvbiBpcyB0aGVyZSAoZWl0aGVyIGJlY2F1c2UgdGhlIGZpbGUgaXMgbm90IGZyYWdtZW50ZWQgYW5kIHRoaXMgaXMgbm90IHRoZSBsYXN0IHNhbXBsZSwKCQkJCQlvciBiZWNhdXNlIHRoZSBmaWxlIGlzIGZyYWdtZW50ZWQgYW5kIHRoZSBtb29mIGZvciB0aGF0IHNhbXBsZSBoYXMgYmVlbiByZWNlaXZlZCAqLwoJCQkJCUxvZy5kZWJ1ZygiSVNPRmlsZSIsICJDcmVhdGluZyBtZWRpYSBmcmFnbWVudCBvbiB0cmFjayAjIitmcmFnVHJhay5pZCArIiBmb3Igc2FtcGxlICIrdHJhay5uZXh0U2FtcGxlKTsKCQkJCQl2YXIgcmVzdWx0ID0gdGhpcy5jcmVhdGVGcmFnbWVudChmcmFnVHJhay5pZCwgdHJhay5uZXh0U2FtcGxlLCBmcmFnVHJhay5zZWdtZW50U3RyZWFtKTsKCQkJCQlpZiAocmVzdWx0KSB7CgkJCQkJCWZyYWdUcmFrLnNlZ21lbnRTdHJlYW0gPSByZXN1bHQ7CgkJCQkJCXRyYWsubmV4dFNhbXBsZSsrOwoJCQkJCX0gZWxzZSB7CgkJCQkJCS8qIFRoZSBmcmFnbWVudCBjb3VsZCBub3QgYmUgY3JlYXRlZCBiZWNhdXNlIHRoZSBtZWRpYSBkYXRhIGlzIG5vdCB0aGVyZSAobm90IGRvd25sb2FkZWQpLCB3YWl0IGZvciBpdCAqLwoJCQkJCQlicmVhazsKCQkJCQl9CgkJCQkJLyogQSBmcmFnbWVudCBpcyBjcmVhdGVkIGJ5IHNhbXBsZSwgYnV0IHRoZSBzZWdtZW50IGlzIHRoZSBhY2N1bXVsYXRpb24gaW4gdGhlIGJ1ZmZlciBvZiB0aGVzZSBmcmFnbWVudHMuCgkJCQkJICAgSXQgaXMgZmx1c2hlZCBvbmx5IGFzIHJlcXVlc3RlZCBieSB0aGUgYXBwbGljYXRpb24gKG5iX3NhbXBsZXMpIHRvIGF2b2lkIHRvbyBtYW55IGNhbGxiYWNrcyAqLwoJCQkJCWlmICh0cmFrLm5leHRTYW1wbGUgJSBmcmFnVHJhay5uYl9zYW1wbGVzID09PSAwIHx8IChsYXN0IHx8IHRyYWsubmV4dFNhbXBsZSA+PSB0cmFrLnNhbXBsZXMubGVuZ3RoKSkgewoJCQkJCQlMb2cuaW5mbygiSVNPRmlsZSIsICJTZW5kaW5nIGZyYWdtZW50ZWQgZGF0YSBvbiB0cmFjayAjIitmcmFnVHJhay5pZCsiIGZvciBzYW1wbGVzIFsiK01hdGgubWF4KDAsdHJhay5uZXh0U2FtcGxlLWZyYWdUcmFrLm5iX3NhbXBsZXMpKyIsIisodHJhay5uZXh0U2FtcGxlLTEpKyJdIik7CgkJCQkJCUxvZy5pbmZvKCJJU09GaWxlIiwgIlNhbXBsZSBkYXRhIHNpemUgaW4gbWVtb3J5OiAiK3RoaXMuZ2V0QWxsb2NhdGVkU2FtcGxlRGF0YVNpemUoKSk7CgkJCQkJCWlmICh0aGlzLm9uU2VnbWVudCkgewoJCQkJCQkJdGhpcy5vblNlZ21lbnQoZnJhZ1RyYWsuaWQsIGZyYWdUcmFrLnVzZXIsIGZyYWdUcmFrLnNlZ21lbnRTdHJlYW0uYnVmZmVyLCB0cmFrLm5leHRTYW1wbGUsIChsYXN0IHx8IHRyYWsubmV4dFNhbXBsZSA+PSB0cmFrLnNhbXBsZXMubGVuZ3RoKSk7CgkJCQkJCX0KCQkJCQkJLyogZm9yY2UgdGhlIGNyZWF0aW9uIG9mIGEgbmV3IGJ1ZmZlciAqLwoJCQkJCQlmcmFnVHJhay5zZWdtZW50U3RyZWFtID0gbnVsbDsKCQkJCQkJaWYgKGZyYWdUcmFrICE9PSB0aGlzLmZyYWdtZW50ZWRUcmFja3NbaV0pIHsKCQkJCQkJCS8qIG1ha2Ugc3VyZSB3ZSBjYW4gc3RvcCBmcmFnbWVudGF0aW9uIGlmIG5lZWRlZCAqLwoJCQkJCQkJYnJlYWs7CgkJCQkJCX0KCQkJCQl9CgkJCQl9CgkJCX0KCQl9CgoJCWlmICh0aGlzLm9uU2FtcGxlcyAhPT0gbnVsbCkgewoJCQkvKiBGb3IgZWFjaCB0cmFjayBtYXJrZWQgZm9yIGRhdGEgZXhwb3J0LAoJCQkgICBjaGVjayBpZiB0aGUgbmV4dCBzYW1wbGUgaXMgdGhlcmUgKGkuZS4gaGFzIGJlZW4gZG93bmxvYWRlZCkgYW5kIHNlbmQgaXQgKi8KCQkJZm9yIChpID0gMDsgaSA8IHRoaXMuZXh0cmFjdGVkVHJhY2tzLmxlbmd0aDsgaSsrKSB7CgkJCQl2YXIgZXh0cmFjdFRyYWsgPSB0aGlzLmV4dHJhY3RlZFRyYWNrc1tpXTsKCQkJCXRyYWsgPSBleHRyYWN0VHJhay50cmFrOwoJCQkJd2hpbGUgKHRyYWsubmV4dFNhbXBsZSA8IHRyYWsuc2FtcGxlcy5sZW5ndGggJiYgdGhpcy5zYW1wbGVQcm9jZXNzaW5nU3RhcnRlZCkgewoJCQkJCUxvZy5kZWJ1ZygiSVNPRmlsZSIsICJFeHBvcnRpbmcgb24gdHJhY2sgIyIrZXh0cmFjdFRyYWsuaWQgKyIgc2FtcGxlICMiK3RyYWsubmV4dFNhbXBsZSk7CgkJCQkJdmFyIHNhbXBsZSA9IHRoaXMuZ2V0U2FtcGxlKHRyYWssIHRyYWsubmV4dFNhbXBsZSk7CgkJCQkJaWYgKHNhbXBsZSkgewoJCQkJCQl0cmFrLm5leHRTYW1wbGUrKzsKCQkJCQkJZXh0cmFjdFRyYWsuc2FtcGxlcy5wdXNoKHNhbXBsZSk7CgkJCQkJfSBlbHNlIHsKCQkJCQkJYnJlYWs7CgkJCQkJfQoJCQkJCWlmICh0cmFrLm5leHRTYW1wbGUgJSBleHRyYWN0VHJhay5uYl9zYW1wbGVzID09PSAwIHx8IHRyYWsubmV4dFNhbXBsZSA+PSB0cmFrLnNhbXBsZXMubGVuZ3RoKSB7CgkJCQkJCUxvZy5kZWJ1ZygiSVNPRmlsZSIsICJTZW5kaW5nIHNhbXBsZXMgb24gdHJhY2sgIyIrZXh0cmFjdFRyYWsuaWQrIiBmb3Igc2FtcGxlICIrdHJhay5uZXh0U2FtcGxlKTsKCQkJCQkJaWYgKHRoaXMub25TYW1wbGVzKSB7CgkJCQkJCQl0aGlzLm9uU2FtcGxlcyhleHRyYWN0VHJhay5pZCwgZXh0cmFjdFRyYWsudXNlciwgZXh0cmFjdFRyYWsuc2FtcGxlcyk7CgkJCQkJCX0KCQkJCQkJZXh0cmFjdFRyYWsuc2FtcGxlcyA9IFtdOwoJCQkJCQlpZiAoZXh0cmFjdFRyYWsgIT09IHRoaXMuZXh0cmFjdGVkVHJhY2tzW2ldKSB7CgkJCQkJCQkvKiBjaGVjayBpZiB0aGUgZXh0cmFjdGlvbiBuZWVkcyB0byBiZSBzdG9wcGVkICovCgkJCQkJCQlicmVhazsKCQkJCQkJfQoJCQkJCX0KCQkJCX0KCQkJfQoJCX0KCX07CgoJLyogRmluZCBhbmQgcmV0dXJuIHNwZWNpZmljIGJveGVzIHVzaW5nIHJlY3Vyc2lvbiBhbmQgZWFybHkgcmV0dXJuICovCglJU09GaWxlLnByb3RvdHlwZS5nZXRCb3ggPSBmdW5jdGlvbih0eXBlKSB7CgkgIHZhciByZXN1bHQgPSB0aGlzLmdldEJveGVzKHR5cGUsIHRydWUpOwoJICByZXR1cm4gKHJlc3VsdC5sZW5ndGggPyByZXN1bHRbMF0gOiBudWxsKTsKCX07CgoJSVNPRmlsZS5wcm90b3R5cGUuZ2V0Qm94ZXMgPSBmdW5jdGlvbih0eXBlLCByZXR1cm5FYXJseSkgewoJICB2YXIgcmVzdWx0ID0gW107CgkgIElTT0ZpbGUuX3N3ZWVwLmNhbGwodGhpcywgdHlwZSwgcmVzdWx0LCByZXR1cm5FYXJseSk7CgkgIHJldHVybiByZXN1bHQ7Cgl9OwoKCUlTT0ZpbGUuX3N3ZWVwID0gZnVuY3Rpb24odHlwZSwgcmVzdWx0LCByZXR1cm5FYXJseSkgewoJICBpZiAodGhpcy50eXBlICYmIHRoaXMudHlwZSA9PSB0eXBlKSByZXN1bHQucHVzaCh0aGlzKTsKCSAgZm9yICh2YXIgYm94IGluIHRoaXMuYm94ZXMpIHsKCSAgICBpZiAocmVzdWx0Lmxlbmd0aCAmJiByZXR1cm5FYXJseSkgcmV0dXJuOwoJICAgIElTT0ZpbGUuX3N3ZWVwLmNhbGwodGhpcy5ib3hlc1tib3hdLCB0eXBlLCByZXN1bHQsIHJldHVybkVhcmx5KTsKCSAgfQoJfTsKCglJU09GaWxlLnByb3RvdHlwZS5nZXRUcmFja1NhbXBsZXNJbmZvID0gZnVuY3Rpb24odHJhY2tfaWQpIHsKCQl2YXIgdHJhY2sgPSB0aGlzLmdldFRyYWNrQnlJZCh0cmFja19pZCk7CgkJaWYgKHRyYWNrKSB7CgkJCXJldHVybiB0cmFjay5zYW1wbGVzOwoJCX0gZWxzZSB7CgkJCXJldHVybjsKCQl9Cgl9OwoKCUlTT0ZpbGUucHJvdG90eXBlLmdldFRyYWNrU2FtcGxlID0gZnVuY3Rpb24odHJhY2tfaWQsIG51bWJlcikgewoJCXZhciB0cmFjayA9IHRoaXMuZ2V0VHJhY2tCeUlkKHRyYWNrX2lkKTsKCQl2YXIgc2FtcGxlID0gdGhpcy5nZXRTYW1wbGUodHJhY2ssIG51bWJlcik7CgkJcmV0dXJuIHNhbXBsZTsKCX07CgoJLyogQ2FsbGVkIGJ5IHRoZSBhcHBsaWNhdGlvbiB0byByZWxlYXNlIHRoZSByZXNvdXJjZXMgYXNzb2NpYXRlZCB0byBzYW1wbGVzIGFscmVhZHkgZm9yd2FyZGVkIHRvIHRoZSBhcHBsaWNhdGlvbiAqLwoJSVNPRmlsZS5wcm90b3R5cGUucmVsZWFzZVVzZWRTYW1wbGVzID0gZnVuY3Rpb24gKGlkLCBzYW1wbGVOdW0pIHsKCQl2YXIgc2l6ZSA9IDA7CgkJdmFyIHRyYWsgPSB0aGlzLmdldFRyYWNrQnlJZChpZCk7CgkJaWYgKCF0cmFrLmxhc3RWYWxpZFNhbXBsZSkgdHJhay5sYXN0VmFsaWRTYW1wbGUgPSAwOwoJCWZvciAodmFyIGkgPSB0cmFrLmxhc3RWYWxpZFNhbXBsZTsgaSA8IHNhbXBsZU51bTsgaSsrKSB7CgkJCXNpemUrPXRoaXMucmVsZWFzZVNhbXBsZSh0cmFrLCBpKTsKCQl9CgkJTG9nLmluZm8oIklTT0ZpbGUiLCAiVHJhY2sgIyIraWQrIiByZWxlYXNlZCBzYW1wbGVzIHVwIHRvICIrc2FtcGxlTnVtKyIgKHJlbGVhc2VkIHNpemU6ICIrc2l6ZSsiLCByZW1haW5pbmc6ICIrdGhpcy5zYW1wbGVzRGF0YVNpemUrIikiKTsKCQl0cmFrLmxhc3RWYWxpZFNhbXBsZSA9IHNhbXBsZU51bTsKCX07CgoJSVNPRmlsZS5wcm90b3R5cGUuc3RhcnQgPSBmdW5jdGlvbigpIHsKCQl0aGlzLnNhbXBsZVByb2Nlc3NpbmdTdGFydGVkID0gdHJ1ZTsKCQl0aGlzLnByb2Nlc3NTYW1wbGVzKGZhbHNlKTsKCX07CgoJSVNPRmlsZS5wcm90b3R5cGUuc3RvcCA9IGZ1bmN0aW9uKCkgewoJCXRoaXMuc2FtcGxlUHJvY2Vzc2luZ1N0YXJ0ZWQgPSBmYWxzZTsKCX07CgoJLyogQ2FsbGVkIGJ5IHRoZSBhcHBsaWNhdGlvbiB0byBmbHVzaCB0aGUgcmVtYWluaW5nIHNhbXBsZXMgKGUuZy4gb25jZSB0aGUgZG93bmxvYWQgaXMgZmluaXNoZWQgb3Igd2hlbiBubyBtb3JlIHNhbXBsZXMgd2lsbCBiZSBhZGRlZCkgKi8KCUlTT0ZpbGUucHJvdG90eXBlLmZsdXNoID0gZnVuY3Rpb24oKSB7CgkJTG9nLmluZm8oIklTT0ZpbGUiLCAiRmx1c2hpbmcgcmVtYWluaW5nIHNhbXBsZXMiKTsKCQl0aGlzLnVwZGF0ZVNhbXBsZUxpc3RzKCk7CgkJdGhpcy5wcm9jZXNzU2FtcGxlcyh0cnVlKTsKCQl0aGlzLnN0cmVhbS5jbGVhbkJ1ZmZlcnMoKTsKCQl0aGlzLnN0cmVhbS5sb2dCdWZmZXJMZXZlbCh0cnVlKTsKCX07CgoJLyogRmluZHMgdGhlIGJ5dGUgb2Zmc2V0IGZvciBhIGdpdmVuIHRpbWUgb24gYSBnaXZlbiB0cmFjawoJICAgYWxzbyByZXR1cm5zIHRoZSB0aW1lIG9mIHRoZSBwcmV2aW91cyByYXAgKi8KCUlTT0ZpbGUucHJvdG90eXBlLnNlZWtUcmFjayA9IGZ1bmN0aW9uKHRpbWUsIHVzZVJhcCwgdHJhaykgewoJCXZhciBqOwoJCXZhciBzYW1wbGU7CgkJdmFyIHNlZWtfb2Zmc2V0ID0gSW5maW5pdHk7CgkJdmFyIHJhcF9zZWVrX3NhbXBsZV9udW0gPSAwOwoJCXZhciBzZWVrX3NhbXBsZV9udW0gPSAwOwoJCXZhciB0aW1lc2NhbGU7CgoJCWlmICh0cmFrLnNhbXBsZXMubGVuZ3RoID09PSAwKSB7CgkJCUxvZy5pbmZvKCJJU09GaWxlIiwgIk5vIHNhbXBsZSBpbiB0cmFjaywgY2Fubm90IHNlZWshIFVzaW5nIHRpbWUgIitMb2cuZ2V0RHVyYXRpb25TdHJpbmcoMCwgMSkgKyIgYW5kIG9mZnNldDogIiswKTsKCQkJcmV0dXJuIHsgb2Zmc2V0OiAwLCB0aW1lOiAwIH07CgkJfQoKCQlmb3IgKGogPSAwOyBqIDwgdHJhay5zYW1wbGVzLmxlbmd0aDsgaisrKSB7CgkJCXNhbXBsZSA9IHRyYWsuc2FtcGxlc1tqXTsKCQkJaWYgKGogPT09IDApIHsKCQkJCXNlZWtfc2FtcGxlX251bSA9IDA7CgkJCQl0aW1lc2NhbGUgPSBzYW1wbGUudGltZXNjYWxlOwoJCQl9IGVsc2UgaWYgKHNhbXBsZS5jdHMgPiB0aW1lICogc2FtcGxlLnRpbWVzY2FsZSkgewoJCQkJc2Vla19zYW1wbGVfbnVtID0gai0xOwoJCQkJYnJlYWs7CgkJCX0KCQkJaWYgKHVzZVJhcCAmJiBzYW1wbGUuaXNfc3luYykgewoJCQkJcmFwX3NlZWtfc2FtcGxlX251bSA9IGo7CgkJCX0KCQl9CgkJaWYgKHVzZVJhcCkgewoJCQlzZWVrX3NhbXBsZV9udW0gPSByYXBfc2Vla19zYW1wbGVfbnVtOwoJCX0KCQl0aW1lID0gdHJhay5zYW1wbGVzW3NlZWtfc2FtcGxlX251bV0uY3RzOwoJCXRyYWsubmV4dFNhbXBsZSA9IHNlZWtfc2FtcGxlX251bTsKCQl3aGlsZSAodHJhay5zYW1wbGVzW3NlZWtfc2FtcGxlX251bV0uYWxyZWFkeVJlYWQgPT09IHRyYWsuc2FtcGxlc1tzZWVrX3NhbXBsZV9udW1dLnNpemUpIHsKCQkJLy8gTm8gcmVtYWluaW5nIHNhbXBsZXMgdG8gbG9vayBmb3IsIGFsbCBhcmUgZG93bmxvYWRlZC4KCQkJaWYgKCF0cmFrLnNhbXBsZXNbc2Vla19zYW1wbGVfbnVtICsgMV0pIHsKCQkJCWJyZWFrOwoJCQl9CgkJCXNlZWtfc2FtcGxlX251bSsrOwoJCX0KCQlzZWVrX29mZnNldCA9IHRyYWsuc2FtcGxlc1tzZWVrX3NhbXBsZV9udW1dLm9mZnNldCt0cmFrLnNhbXBsZXNbc2Vla19zYW1wbGVfbnVtXS5hbHJlYWR5UmVhZDsKCQlMb2cuaW5mbygiSVNPRmlsZSIsICJTZWVraW5nIHRvICIrKHVzZVJhcCA/ICJSQVAiOiAiIikrIiBzYW1wbGUgIyIrdHJhay5uZXh0U2FtcGxlKyIgb24gdHJhY2sgIit0cmFrLnRraGQudHJhY2tfaWQrIiwgdGltZSAiK0xvZy5nZXREdXJhdGlvblN0cmluZyh0aW1lLCB0aW1lc2NhbGUpICsiIGFuZCBvZmZzZXQ6ICIrc2Vla19vZmZzZXQpOwoJCXJldHVybiB7IG9mZnNldDogc2Vla19vZmZzZXQsIHRpbWU6IHRpbWUvdGltZXNjYWxlIH07Cgl9OwoKCS8qIEZpbmRzIHRoZSBieXRlIG9mZnNldCBpbiB0aGUgZmlsZSBjb3JyZXNwb25kaW5nIHRvIHRoZSBnaXZlbiB0aW1lIG9yIHRvIHRoZSB0aW1lIG9mIHRoZSBwcmV2aW91cyBSQVAgKi8KCUlTT0ZpbGUucHJvdG90eXBlLnNlZWsgPSBmdW5jdGlvbih0aW1lLCB1c2VSYXApIHsKCQl2YXIgbW9vdiA9IHRoaXMubW9vdjsKCQl2YXIgdHJhazsKCQl2YXIgdHJha19zZWVrX2luZm87CgkJdmFyIGk7CgkJdmFyIHNlZWtfaW5mbyA9IHsgb2Zmc2V0OiBJbmZpbml0eSwgdGltZTogSW5maW5pdHkgfTsKCQlpZiAoIXRoaXMubW9vdikgewoJCQl0aHJvdyAiQ2Fubm90IHNlZWs6IG1vb3Ygbm90IHJlY2VpdmVkISI7CgkJfSBlbHNlIHsKCQkJZm9yIChpID0gMDsgaTxtb292LnRyYWtzLmxlbmd0aDsgaSsrKSB7CgkJCQl0cmFrID0gbW9vdi50cmFrc1tpXTsKCQkJCXRyYWtfc2Vla19pbmZvID0gdGhpcy5zZWVrVHJhY2sodGltZSwgdXNlUmFwLCB0cmFrKTsKCQkJCWlmICh0cmFrX3NlZWtfaW5mby5vZmZzZXQgPCBzZWVrX2luZm8ub2Zmc2V0KSB7CgkJCQkJc2Vla19pbmZvLm9mZnNldCA9IHRyYWtfc2Vla19pbmZvLm9mZnNldDsKCQkJCX0KCQkJCWlmICh0cmFrX3NlZWtfaW5mby50aW1lIDwgc2Vla19pbmZvLnRpbWUpIHsKCQkJCQlzZWVrX2luZm8udGltZSA9IHRyYWtfc2Vla19pbmZvLnRpbWU7CgkJCQl9CgkJCX0KCQkJTG9nLmluZm8oIklTT0ZpbGUiLCAiU2Vla2luZyBhdCB0aW1lICIrTG9nLmdldER1cmF0aW9uU3RyaW5nKHNlZWtfaW5mby50aW1lLCAxKSsiIG5lZWRzIGEgYnVmZmVyIHdpdGggYSBmaWxlU3RhcnQgcG9zaXRpb24gb2YgIitzZWVrX2luZm8ub2Zmc2V0KTsKCQkJaWYgKHNlZWtfaW5mby5vZmZzZXQgPT09IEluZmluaXR5KSB7CgkJCQkvKiBObyBzYW1wbGUgaW5mbywgaW4gYWxsIHRyYWNrcywgY2Fubm90IHNlZWsgKi8KCQkJCXNlZWtfaW5mbyA9IHsgb2Zmc2V0OiB0aGlzLm5leHRQYXJzZVBvc2l0aW9uLCB0aW1lOiAwIH07CgkJCX0gZWxzZSB7CgkJCQkvKiBjaGVjayBpZiB0aGUgc2VlayBwb3NpdGlvbiBpcyBhbHJlYWR5IGluIHNvbWUgYnVmZmVyIGFuZAoJCQkJIGluIHRoYXQgY2FzZSByZXR1cm4gdGhlIGVuZCBvZiB0aGF0IGJ1ZmZlciAob3Igb2YgdGhlIGxhc3QgY29udGlndW91cyBidWZmZXIpICovCgkJCQkvKiBUT0RPOiBTaG91bGQgd2FpdCB1bnRpbCBhcHBlbmQgb3BlcmF0aW9ucyBhcmUgZG9uZSAqLwoJCQkJc2Vla19pbmZvLm9mZnNldCA9IHRoaXMuc3RyZWFtLmdldEVuZEZpbGVQb3NpdGlvbkFmdGVyKHNlZWtfaW5mby5vZmZzZXQpOwoJCQl9CgkJCUxvZy5pbmZvKCJJU09GaWxlIiwgIkFkanVzdGVkIHNlZWsgcG9zaXRpb24gKGFmdGVyIGNoZWNraW5nIGRhdGEgYWxyZWFkeSBpbiBidWZmZXIpOiAiK3NlZWtfaW5mby5vZmZzZXQpOwoJCQlyZXR1cm4gc2Vla19pbmZvOwoJCX0KCX07CgoJSVNPRmlsZS5wcm90b3R5cGUuZXF1YWwgPSBmdW5jdGlvbihiKSB7CgkJdmFyIGJveF9pbmRleCA9IDA7CgkJd2hpbGUgKGJveF9pbmRleCA8IHRoaXMuYm94ZXMubGVuZ3RoICYmIGJveF9pbmRleCA8IGIuYm94ZXMubGVuZ3RoKSB7CgkJCXZhciBhX2JveCA9IHRoaXMuYm94ZXNbYm94X2luZGV4XTsKCQkJdmFyIGJfYm94ID0gYi5ib3hlc1tib3hfaW5kZXhdOwoJCQlpZiAoIUJveFBhcnNlci5ib3hFcXVhbChhX2JveCwgYl9ib3gpKSB7CgkJCQlyZXR1cm4gZmFsc2U7CgkJCX0KCQkJYm94X2luZGV4Kys7CgkJfQoJCXJldHVybiB0cnVlOwoJfTsKCgl7CgkJZXhwb3J0cy5JU09GaWxlID0gSVNPRmlsZTsKCX0KCS8vIGZpbGU6c3JjL2lzb2ZpbGUtYWR2YW5jZWQtcGFyc2luZy5qcwoJLyogcG9zaXRpb24gaW4gdGhlIGN1cnJlbnQgYnVmZmVyIG9mIHRoZSBiZWdpbm5pbmcgb2YgdGhlIGxhc3QgYm94IHBhcnNlZCAqLwoJSVNPRmlsZS5wcm90b3R5cGUubGFzdEJveFN0YXJ0UG9zaXRpb24gPSAwOwoJLyogaW5kaWNhdG9yIGlmIHRoZSBwYXJzaW5nIGlzIHN0dWNrIGluIHRoZSBtaWRkbGUgb2YgYW4gbWRhdCBib3ggKi8KCUlTT0ZpbGUucHJvdG90eXBlLnBhcnNpbmdNZGF0ID0gbnVsbDsKCS8qIG5leHQgZmlsZSBwb3NpdGlvbiB0aGF0IHRoZSBwYXJzZXIgbmVlZHM6CgkgICAgLSAwIHVudGlsIHRoZSBmaXJzdCBidWZmZXIgKGkuZS4gZmlsZVN0YXJ0ID09PTApIGhhcyBiZWVuIHJlY2VpdmVkIAoJICAgIC0gb3RoZXJ3aXNlLCB0aGUgbmV4dCBib3ggc3RhcnQgdW50aWwgdGhlIG1vb3YgYm94IGhhcyBiZWVuIHBhcnNlZAoJICAgIC0gb3RoZXJ3aXNlLCB0aGUgcG9zaXRpb24gb2YgdGhlIG5leHQgc2FtcGxlIHRvIGZldGNoCgkgKi8KCUlTT0ZpbGUucHJvdG90eXBlLm5leHRQYXJzZVBvc2l0aW9uID0gMDsKCS8qIGtlZXAgbWRhdCBkYXRhICovCglJU09GaWxlLnByb3RvdHlwZS5kaXNjYXJkTWRhdERhdGEgPSBmYWxzZTsKCglJU09GaWxlLnByb3RvdHlwZS5wcm9jZXNzSW5jb21wbGV0ZUJveCA9IGZ1bmN0aW9uKHJldCkgewoJCXZhciBib3g7CgkJdmFyIG1lcmdlZDsKCQl2YXIgZm91bmQ7CgkJCgkJLyogd2UgZGlkIG5vdCBoYXZlIGVub3VnaCBieXRlcyBpbiB0aGUgY3VycmVudCBidWZmZXIgdG8gcGFyc2UgdGhlIGVudGlyZSBib3ggKi8KCQlpZiAocmV0LnR5cGUgPT09ICJtZGF0IikgeyAKCQkJLyogd2UgaGFkIGVub3VnaCBieXRlcyB0byBnZXQgaXRzIHR5cGUgYW5kIHNpemUgYW5kIGl0J3MgYW4gJ21kYXQnICovCgkJCQoJCQkvKiBzcGVjaWFsIGhhbmRsaW5nIGZvciBtZGF0IGJveGVzLCBzaW5jZSB3ZSBkb24ndCBhY3R1YWxseSBuZWVkIHRvIHBhcnNlIGl0IGxpbmVhcmx5IAoJCQkgICB3ZSBjcmVhdGUgdGhlIGJveCAqLwoJCQlib3ggPSBuZXcgQm94UGFyc2VyW3JldC50eXBlKyJCb3giXShyZXQuc2l6ZSk7CQoJCQl0aGlzLnBhcnNpbmdNZGF0ID0gYm94OwoJCQl0aGlzLmJveGVzLnB1c2goYm94KTsKCQkJdGhpcy5tZGF0cy5wdXNoKGJveCk7CQkJCgkJCWJveC5zdGFydCA9IHJldC5zdGFydDsKCQkJYm94Lmhkcl9zaXplID0gcmV0Lmhkcl9zaXplOwoJCQl0aGlzLnN0cmVhbS5hZGRVc2VkQnl0ZXMoYm94Lmhkcl9zaXplKTsKCgkJCS8qIGluZGljYXRlIHRoYXQgdGhlIHBhcnNpbmcgc2hvdWxkIHN0YXJ0IGZyb20gdGhlIGVuZCBvZiB0aGUgYm94ICovCgkJCXRoaXMubGFzdEJveFN0YXJ0UG9zaXRpb24gPSBib3guc3RhcnQgKyBib3guc2l6ZTsKCSAJCS8qIGxldCdzIHNlZSBpZiB3ZSBoYXZlIHRoZSBlbmQgb2YgdGhlIGJveCBpbiB0aGUgb3RoZXIgYnVmZmVycyAqLwoJCQlmb3VuZCA9IHRoaXMuc3RyZWFtLnNlZWsoYm94LnN0YXJ0ICsgYm94LnNpemUsIGZhbHNlLCB0aGlzLmRpc2NhcmRNZGF0RGF0YSk7CgkJCWlmIChmb3VuZCkgewoJCQkJLyogZm91bmQgdGhlIGVuZCBvZiB0aGUgYm94ICovCgkJCQl0aGlzLnBhcnNpbmdNZGF0ID0gbnVsbDsKCQkJCS8qIGxldCdzIHNlZSBpZiB3ZSBjYW4gcGFyc2UgbW9yZSBpbiB0aGlzIGJ1ZmZlciAqLwoJCQkJcmV0dXJuIHRydWU7CgkJCX0gZWxzZSB7CgkJCQkvKiAnbWRhdCcgZW5kIG5vdCBmb3VuZCBpbiB0aGUgZXhpc3RpbmcgYnVmZmVycyAqLwoJCQkJLyogZGV0ZXJtaW5lIHRoZSBuZXh0IHBvc2l0aW9uIGluIHRoZSBmaWxlIHRvIHN0YXJ0IHBhcnNpbmcgZnJvbSAqLwoJCQkJaWYgKCF0aGlzLm1vb3ZTdGFydEZvdW5kKSB7CgkJCQkJLyogbW9vdiBub3QgZmluZCB5ZXQsIAoJCQkJCSAgIHRoZSBmaWxlIHByb2JhYmx5IGhhcyAnbWRhdCcgYXQgdGhlIGJlZ2lubmluZywgYW5kICdtb292JyBhdCB0aGUgZW5kLCAKCQkJCQkgICBpbmRpY2F0ZSB0aGF0IHRoZSBkb3dubG9hZGVyIHNob3VsZCBub3QgdHJ5IHRvIGRvd25sb2FkIHRob3NlIGJ5dGVzIG5vdyAqLwoJCQkJCXRoaXMubmV4dFBhcnNlUG9zaXRpb24gPSBib3guc3RhcnQgKyBib3guc2l6ZTsKCQkJCX0gZWxzZSB7CgkJCQkJLyogd2UgaGF2ZSB0aGUgc3RhcnQgb2YgdGhlIG1vb3YgYm94LCAKCQkJCQkgICB0aGUgbmV4dCBieXRlcyBzaG91bGQgdHJ5IHRvIGNvbXBsZXRlIHRoZSBjdXJyZW50ICdtZGF0JyAqLwoJCQkJCXRoaXMubmV4dFBhcnNlUG9zaXRpb24gPSB0aGlzLnN0cmVhbS5maW5kRW5kQ29udGlndW91c0J1ZigpOwoJCQkJfQoJCQkJLyogbm90IG11Y2ggd2UgY2FuIGRvLCB3YWl0IGZvciBtb3JlIGJ1ZmZlcnMgdG8gYXJyaXZlICovCgkJCQlyZXR1cm4gZmFsc2U7CgkJCX0KCQl9IGVsc2UgewoJCQkvKiBib3ggaXMgaW5jb21wbGV0ZSwgd2UgbWF5IG5vdCBldmVuIGtub3cgaXRzIHR5cGUgKi8KCQkJaWYgKHJldC50eXBlID09PSAibW9vdiIpIHsgCgkJCQkvKiB0aGUgaW5jb21wbGV0ZSBib3ggaXMgYSAnbW9vdicgYm94ICovCgkJCQl0aGlzLm1vb3ZTdGFydEZvdW5kID0gdHJ1ZTsKCQkJCWlmICh0aGlzLm1kYXRzLmxlbmd0aCA9PT0gMCkgewoJCQkJCXRoaXMuaXNQcm9ncmVzc2l2ZSA9IHRydWU7CgkJCQl9CgkJCX0KCQkJLyogZWl0aGVyIGl0J3Mgbm90IGFuIG1kYXQgYm94IChhbmQgd2UgbmVlZCB0byBwYXJzZSBpdCwgd2UgY2Fubm90IHNraXAgaXQpCgkJCSAgIChUT0RPOiB3ZSBjb3VsZCBza2lwICdmcmVlJyBib3hlcyAuLi4pCgkJCQkgICBvciB3ZSBkaWQgbm90IGhhdmUgZW5vdWdoIGRhdGEgdG8gcGFyc2UgdGhlIHR5cGUgYW5kIHNpemUgb2YgdGhlIGJveCwgCgkJCSAgIHdlIHRyeSB0byBjb25jYXRlbmF0ZSB0aGUgY3VycmVudCBidWZmZXIgd2l0aCB0aGUgbmV4dCBidWZmZXIgdG8gcmVzdGFydCBwYXJzaW5nICovCgkJCW1lcmdlZCA9ICh0aGlzLnN0cmVhbS5tZXJnZU5leHRCdWZmZXIgPyB0aGlzLnN0cmVhbS5tZXJnZU5leHRCdWZmZXIoKSA6IGZhbHNlKTsKCQkJaWYgKG1lcmdlZCkgewoJCQkJLyogVGhlIG5leHQgYnVmZmVyIHdhcyBjb250aWd1b3VzLCB0aGUgbWVyZ2luZyBzdWNjZWVkZWQsCgkJCQkgICB3ZSBjYW4gbm93IGNvbnRpbnVlIHBhcnNpbmcsIAoJCQkJICAgdGhlIG5leHQgYmVzdCBwb3NpdGlvbiB0byBwYXJzZSBpcyBhdCB0aGUgZW5kIG9mIHRoaXMgbmV3IGJ1ZmZlciAqLwoJCQkJdGhpcy5uZXh0UGFyc2VQb3NpdGlvbiA9IHRoaXMuc3RyZWFtLmdldEVuZFBvc2l0aW9uKCk7CgkJCQlyZXR1cm4gdHJ1ZTsKCQkJfSBlbHNlIHsKCQkJCS8qIHdlIGNhbm5vdCBjb25jYXRlbmF0ZSBleGlzdGluZyBidWZmZXJzIGJlY2F1c2UgdGhleSBhcmUgbm90IGNvbnRpZ3VvdXMgb3IgYmVjYXVzZSB0aGVyZSBpcyBubyBhZGRpdGlvbmFsIGJ1ZmZlciAqLwoJCQkJLyogVGhlIG5leHQgYmVzdCBwb3NpdGlvbiB0byBwYXJzZSBpcyBzdGlsbCBhdCB0aGUgZW5kIG9mIHRoaXMgb2xkIGJ1ZmZlciAqLwoJCQkJaWYgKCFyZXQudHlwZSkgewoJCQkJCS8qIFRoZXJlIHdlcmUgbm90IGVub3VnaCBieXRlcyBpbiB0aGUgYnVmZmVyIHRvIHBhcnNlIHRoZSBib3ggdHlwZSBhbmQgbGVuZ3RoLAoJCQkJCSAgIHRoZSBuZXh0IGZldGNoIHNob3VsZCByZXRyaWV2ZSB0aG9zZSBtaXNzaW5nIGJ5dGVzLCBpLmUuIHRoZSBuZXh0IGJ5dGVzIGFmdGVyIHRoaXMgYnVmZmVyICovCgkJCQkJdGhpcy5uZXh0UGFyc2VQb3NpdGlvbiA9IHRoaXMuc3RyZWFtLmdldEVuZFBvc2l0aW9uKCk7CgkJCQl9IGVsc2UgewoJCQkJCS8qIHdlIGhhZCBlbm91Z2ggYnl0ZXMgdG8gcGFyc2Ugc2l6ZSBhbmQgdHlwZSBvZiB0aGUgaW5jb21wbGV0ZSBib3gKCQkJCQkgICBpZiB3ZSBoYXZlbid0IGZvdW5kIHlldCB0aGUgbW9vdiBib3gsIHNraXAgdGhpcyBvbmUgYW5kIHRyeSB0aGUgbmV4dCBvbmUgCgkJCQkJICAgaWYgd2UgaGF2ZSBmb3VuZCB0aGUgbW9vdiBib3gsIGxldCdzIGNvbnRpbnVlIGxpbmVhciBwYXJzaW5nICovCgkJCQkJaWYgKHRoaXMubW9vdlN0YXJ0Rm91bmQpIHsKCQkJCQkJdGhpcy5uZXh0UGFyc2VQb3NpdGlvbiA9IHRoaXMuc3RyZWFtLmdldEVuZFBvc2l0aW9uKCk7CgkJCQkJfSBlbHNlIHsKCQkJCQkJdGhpcy5uZXh0UGFyc2VQb3NpdGlvbiA9IHRoaXMuc3RyZWFtLmdldFBvc2l0aW9uKCkgKyByZXQuc2l6ZTsKCQkJCQl9CgkJCQl9CgkJCQlyZXR1cm4gZmFsc2U7CgkJCX0KCQl9Cgl9OwoKCUlTT0ZpbGUucHJvdG90eXBlLmhhc0luY29tcGxldGVNZGF0ID0gZnVuY3Rpb24gKCkgewoJCXJldHVybiAodGhpcy5wYXJzaW5nTWRhdCAhPT0gbnVsbCk7Cgl9OwoKCUlTT0ZpbGUucHJvdG90eXBlLnByb2Nlc3NJbmNvbXBsZXRlTWRhdCA9IGZ1bmN0aW9uICgpIHsKCQl2YXIgYm94OwoJCXZhciBmb3VuZDsKCQkKCQkvKiB3ZSBhcmUgaW4gdGhlIHBhcnNpbmcgb2YgYW4gaW5jb21wbGV0ZSBtZGF0IGJveCAqLwoJCWJveCA9IHRoaXMucGFyc2luZ01kYXQ7CgoJCWZvdW5kID0gdGhpcy5zdHJlYW0uc2Vlayhib3guc3RhcnQgKyBib3guc2l6ZSwgZmFsc2UsIHRoaXMuZGlzY2FyZE1kYXREYXRhKTsKCQlpZiAoZm91bmQpIHsKCQkJTG9nLmRlYnVnKCJJU09GaWxlIiwgIkZvdW5kICdtZGF0JyBlbmQgaW4gYnVmZmVyZWQgZGF0YSIpOwoJCQkvKiB0aGUgZW5kIG9mIHRoZSBtZGF0IGhhcyBiZWVuIGZvdW5kICovIAoJCQl0aGlzLnBhcnNpbmdNZGF0ID0gbnVsbDsKCQkJLyogd2UgY2FuIHBhcnNlIG1vcmUgaW4gdGhpcyBidWZmZXIgKi8KCQkJcmV0dXJuIHRydWU7CgkJfSBlbHNlIHsKCQkJLyogd2UgZG9uJ3QgaGF2ZSB0aGUgZW5kIG9mIHRoaXMgbWRhdCB5ZXQsIAoJCQkgICBpbmRpY2F0ZSB0aGF0IHRoZSBuZXh0IGJ5dGUgdG8gZmV0Y2ggaXMgdGhlIGVuZCBvZiB0aGUgYnVmZmVycyB3ZSBoYXZlIHNvIGZhciwgCgkJCSAgIHJldHVybiBhbmQgd2FpdCBmb3IgbW9yZSBidWZmZXIgdG8gY29tZSAqLwoJCQl0aGlzLm5leHRQYXJzZVBvc2l0aW9uID0gdGhpcy5zdHJlYW0uZmluZEVuZENvbnRpZ3VvdXNCdWYoKTsKCQkJcmV0dXJuIGZhbHNlOwoJCX0KCX07CgoJSVNPRmlsZS5wcm90b3R5cGUucmVzdG9yZVBhcnNlUG9zaXRpb24gPSBmdW5jdGlvbigpIHsKCQkvKiBSZXBvc2l0aW9uIGF0IHRoZSBzdGFydCBwb3NpdGlvbiBvZiB0aGUgcHJldmlvdXMgYm94IG5vdCBlbnRpcmVseSBwYXJzZWQgKi8KCQlyZXR1cm4gdGhpcy5zdHJlYW0uc2Vlayh0aGlzLmxhc3RCb3hTdGFydFBvc2l0aW9uLCB0cnVlLCB0aGlzLmRpc2NhcmRNZGF0RGF0YSk7Cgl9OwoKCUlTT0ZpbGUucHJvdG90eXBlLnNhdmVQYXJzZVBvc2l0aW9uID0gZnVuY3Rpb24oKSB7CgkJLyogcmVtZW1iZXIgdGhlIHBvc2l0aW9uIG9mIHRoZSBib3ggc3RhcnQgaW4gY2FzZSB3ZSBuZWVkIHRvIHJvbGwgYmFjayAoaWYgdGhlIGJveCBpcyBpbmNvbXBsZXRlKSAqLwoJCXRoaXMubGFzdEJveFN0YXJ0UG9zaXRpb24gPSB0aGlzLnN0cmVhbS5nZXRQb3NpdGlvbigpOwkKCX07CgoJSVNPRmlsZS5wcm90b3R5cGUudXBkYXRlVXNlZEJ5dGVzID0gZnVuY3Rpb24oYm94LCByZXQpIHsKCQlpZiAodGhpcy5zdHJlYW0uYWRkVXNlZEJ5dGVzKSB7CgkJCWlmIChib3gudHlwZSA9PT0gIm1kYXQiKSB7CgkJCQkvKiBmb3IgYW4gbWRhdCBib3gsIG9ubHkgaXRzIGhlYWRlciBpcyBjb25zaWRlcmVkIHVzZWQsIG90aGVyIGJ5dGVzIHdpbGwgYmUgdXNlZCB3aGVuIHNhbXBsZSBkYXRhIGlzIHJlcXVlc3RlZCAqLwoJCQkJdGhpcy5zdHJlYW0uYWRkVXNlZEJ5dGVzKGJveC5oZHJfc2l6ZSk7CgkJCQlpZiAodGhpcy5kaXNjYXJkTWRhdERhdGEpIHsKCQkJCQl0aGlzLnN0cmVhbS5hZGRVc2VkQnl0ZXMoYm94LnNpemUtYm94Lmhkcl9zaXplKTsKCQkJCX0KCQkJfSBlbHNlIHsKCQkJCS8qIGZvciBhbGwgb3RoZXIgYm94ZXMsIHRoZSBlbnRpcmUgYm94IGRhdGEgaXMgY29uc2lkZXJlZCB1c2VkICovCgkJCQl0aGlzLnN0cmVhbS5hZGRVc2VkQnl0ZXMoYm94LnNpemUpOwoJCQl9CQoJCX0KCX07CgkvLyBmaWxlOnNyYy9pc29maWxlLWFkdmFuY2VkLWNyZWF0aW9uLmpzCglJU09GaWxlLnByb3RvdHlwZS5hZGQgPSBCb3hQYXJzZXIuQm94LnByb3RvdHlwZS5hZGQ7CglJU09GaWxlLnByb3RvdHlwZS5hZGRCb3ggPSBCb3hQYXJzZXIuQm94LnByb3RvdHlwZS5hZGRCb3g7CgoJSVNPRmlsZS5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uIChfb3B0aW9ucykgewoJCXZhciBvcHRpb25zID0gX29wdGlvbnMgfHwge307IAoJCXRoaXMuYWRkKCJmdHlwIikuc2V0KCJtYWpvcl9icmFuZCIsIChvcHRpb25zLmJyYW5kcyAmJiBvcHRpb25zLmJyYW5kc1swXSkgfHwgImlzbzQiKQoJCQkJCQkJCSAgIC5zZXQoIm1pbm9yX3ZlcnNpb24iLCAwKQoJCQkJCQkJCSAgIC5zZXQoImNvbXBhdGlibGVfYnJhbmRzIiwgb3B0aW9ucy5icmFuZHMgfHwgWyJpc280Il0pOwoJCXZhciBtb292ID0gdGhpcy5hZGQoIm1vb3YiKTsKCQltb292LmFkZCgibXZoZCIpLnNldCgidGltZXNjYWxlIiwgb3B0aW9ucy50aW1lc2NhbGUgfHwgNjAwKQoJCQkJCQkuc2V0KCJyYXRlIiwgb3B0aW9ucy5yYXRlIHx8IDE8PDE2KQoJCQkJCQkuc2V0KCJjcmVhdGlvbl90aW1lIiwgMCkKCQkJCQkJLnNldCgibW9kaWZpY2F0aW9uX3RpbWUiLCAwKQoJCQkJCQkuc2V0KCJkdXJhdGlvbiIsIG9wdGlvbnMuZHVyYXRpb24gfHwgMCkKCQkJCQkJLnNldCgidm9sdW1lIiwgKG9wdGlvbnMud2lkdGgpID8gMCA6IDB4MDEwMCkKCQkJCQkJLnNldCgibWF0cml4IiwgWyAxPDwxNiwgMCwgMCwgMCwgMTw8MTYsIDAsIDAsIDAsIDB4NDAwMDAwMDBdKQoJCQkJCQkuc2V0KCJuZXh0X3RyYWNrX2lkIiwgMSk7CgkJbW9vdi5hZGQoIm12ZXgiKTsKCQlyZXR1cm4gdGhpczsKCX07CgoJSVNPRmlsZS5wcm90b3R5cGUuYWRkVHJhY2sgPSBmdW5jdGlvbiAoX29wdGlvbnMpIHsKCQlpZiAoIXRoaXMubW9vdikgewoJCQl0aGlzLmluaXQoX29wdGlvbnMpOwoJCX0KCgkJdmFyIG9wdGlvbnMgPSBfb3B0aW9ucyB8fCB7fTsgCgkJb3B0aW9ucy53aWR0aCA9IG9wdGlvbnMud2lkdGggfHwgMzIwOwoJCW9wdGlvbnMuaGVpZ2h0ID0gb3B0aW9ucy5oZWlnaHQgfHwgMzIwOwoJCW9wdGlvbnMuaWQgPSBvcHRpb25zLmlkIHx8IHRoaXMubW9vdi5tdmhkLm5leHRfdHJhY2tfaWQ7CgkJb3B0aW9ucy50eXBlID0gb3B0aW9ucy50eXBlIHx8ICJhdmMxIjsKCgkJdmFyIHRyYWsgPSB0aGlzLm1vb3YuYWRkKCJ0cmFrIik7CgkJdGhpcy5tb292Lm12aGQubmV4dF90cmFja19pZCA9IG9wdGlvbnMuaWQrMTsKCQl0cmFrLmFkZCgidGtoZCIpLnNldCgiZmxhZ3MiLEJveFBhcnNlci5US0hEX0ZMQUdfRU5BQkxFRCB8IAoJCQkJCQkJCQkgQm94UGFyc2VyLlRLSERfRkxBR19JTl9NT1ZJRSB8IAoJCQkJCQkJCQkgQm94UGFyc2VyLlRLSERfRkxBR19JTl9QUkVWSUVXKQoJCQkJCQkuc2V0KCJjcmVhdGlvbl90aW1lIiwwKQoJCQkJCQkuc2V0KCJtb2RpZmljYXRpb25fdGltZSIsIDApCgkJCQkJCS5zZXQoInRyYWNrX2lkIiwgb3B0aW9ucy5pZCkKCQkJCQkJLnNldCgiZHVyYXRpb24iLCBvcHRpb25zLmR1cmF0aW9uIHx8IDApCgkJCQkJCS5zZXQoImxheWVyIiwgb3B0aW9ucy5sYXllciB8fCAwKQoJCQkJCQkuc2V0KCJhbHRlcm5hdGVfZ3JvdXAiLCAwKQoJCQkJCQkuc2V0KCJ2b2x1bWUiLCAxKQoJCQkJCQkuc2V0KCJtYXRyaXgiLCBbIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAgXSkKCQkJCQkJLnNldCgid2lkdGgiLCBvcHRpb25zLndpZHRoIDw8IDE2KQoJCQkJCQkuc2V0KCJoZWlnaHQiLCBvcHRpb25zLmhlaWdodCA8PCAxNik7CgoJCXZhciBtZGlhID0gdHJhay5hZGQoIm1kaWEiKTsKCQltZGlhLmFkZCgibWRoZCIpLnNldCgiY3JlYXRpb25fdGltZSIsIDApCgkJCQkJCS5zZXQoIm1vZGlmaWNhdGlvbl90aW1lIiwgMCkKCQkJCQkJLnNldCgidGltZXNjYWxlIiwgb3B0aW9ucy50aW1lc2NhbGUgfHwgMSkKCQkJCQkJLnNldCgiZHVyYXRpb24iLCBvcHRpb25zLm1lZGlhX2R1cmF0aW9uIHx8IDApCgkJCQkJCS5zZXQoImxhbmd1YWdlIiwgb3B0aW9ucy5sYW5ndWFnZSB8fCAidW5kIik7CgoJCW1kaWEuYWRkKCJoZGxyIikuc2V0KCJoYW5kbGVyIiwgb3B0aW9ucy5oZGxyIHx8ICJ2aWRlIikKCQkJCQkJLnNldCgibmFtZSIsIG9wdGlvbnMubmFtZSB8fCAiVHJhY2sgY3JlYXRlZCB3aXRoIE1QNEJveC5qcyIpOwoKCQltZGlhLmFkZCgiZWxuZyIpLnNldCgiZXh0ZW5kZWRfbGFuZ3VhZ2UiLCBvcHRpb25zLmxhbmd1YWdlIHx8ICJmci1GUiIpOwoKCQl2YXIgbWluZiA9IG1kaWEuYWRkKCJtaW5mIik7CgkJaWYgKEJveFBhcnNlcltvcHRpb25zLnR5cGUrIlNhbXBsZUVudHJ5Il0gPT09IHVuZGVmaW5lZCkgcmV0dXJuOwoJCXZhciBzYW1wbGVfZGVzY3JpcHRpb25fZW50cnkgPSBuZXcgQm94UGFyc2VyW29wdGlvbnMudHlwZSsiU2FtcGxlRW50cnkiXSgpOwoJCXNhbXBsZV9kZXNjcmlwdGlvbl9lbnRyeS5kYXRhX3JlZmVyZW5jZV9pbmRleCA9IDE7CgkJdmFyIG1lZGlhX3R5cGUgPSAiIjsKCQlmb3IgKHZhciBtZWRpYVR5cGUgaW4gQm94UGFyc2VyLnNhbXBsZUVudHJ5Q29kZXMpIHsKCQkJdmFyIGNvZGVzID0gQm94UGFyc2VyLnNhbXBsZUVudHJ5Q29kZXNbbWVkaWFUeXBlXTsKCQkJZm9yICh2YXIgaSA9IDA7IGkgPCBjb2Rlcy5sZW5ndGg7IGkrKykgewoJCQkJaWYgKGNvZGVzLmluZGV4T2Yob3B0aW9ucy50eXBlKSA+IC0xKSB7CgkJCQkJbWVkaWFfdHlwZSA9IG1lZGlhVHlwZTsKCQkJCQlicmVhazsKCQkJCX0KCQkJfQoJCX0KCQlzd2l0Y2gobWVkaWFfdHlwZSkgewoJCQljYXNlICJWaXN1YWwiOgoJCQkJbWluZi5hZGQoInZtaGQiKS5zZXQoImdyYXBoaWNzbW9kZSIsMCkuc2V0KCJvcGNvbG9yIiwgWyAwLCAwLCAwIF0pOwoJCQkJc2FtcGxlX2Rlc2NyaXB0aW9uX2VudHJ5LnNldCgid2lkdGgiLCBvcHRpb25zLndpZHRoKQoJCQkJCQkJLnNldCgiaGVpZ2h0Iiwgb3B0aW9ucy5oZWlnaHQpCgkJCQkJCQkuc2V0KCJob3JpenJlc29sdXRpb24iLCAweDQ4PDwxNikKCQkJCQkJCS5zZXQoInZlcnRyZXNvbHV0aW9uIiwgMHg0ODw8MTYpCgkJCQkJCQkuc2V0KCJmcmFtZV9jb3VudCIsIDEpCgkJCQkJCQkuc2V0KCJjb21wcmVzc29ybmFtZSIsIG9wdGlvbnMudHlwZSsiIENvbXByZXNzb3IiKQoJCQkJCQkJLnNldCgiZGVwdGgiLCAweDE4KTsKCQkJCWlmIChvcHRpb25zLmF2Y0RlY29kZXJDb25maWdSZWNvcmQpIHsKCQkJCQl2YXIgYXZjQyA9IG5ldyBCb3hQYXJzZXIuYXZjQ0JveCgpOwoJCQkJCXZhciBzdHJlYW0gPSBuZXcgTVA0Qm94U3RyZWFtKG9wdGlvbnMuYXZjRGVjb2RlckNvbmZpZ1JlY29yZCk7CgkJCQkJYXZjQy5wYXJzZShzdHJlYW0pOwoJCQkJCXNhbXBsZV9kZXNjcmlwdGlvbl9lbnRyeS5hZGRCb3goYXZjQyk7CgkJCQl9CgkJCQlicmVhazsKCQkJY2FzZSAiQXVkaW8iOgoJCQkJbWluZi5hZGQoInNtaGQiKS5zZXQoImJhbGFuY2UiLCBvcHRpb25zLmJhbGFuY2UgfHwgMCk7CgkJCQlzYW1wbGVfZGVzY3JpcHRpb25fZW50cnkuc2V0KCJjaGFubmVsX2NvdW50Iiwgb3B0aW9ucy5jaGFubmVsX2NvdW50IHx8IDIpCgkJCQkJCQkuc2V0KCJzYW1wbGVzaXplIiwgb3B0aW9ucy5zYW1wbGVzaXplIHx8IDE2KQoJCQkJCQkJLnNldCgic2FtcGxlcmF0ZSIsIG9wdGlvbnMuc2FtcGxlcmF0ZSB8fCAxPDwxNik7CgkJCQlicmVhazsKCQkJY2FzZSAiSGludCI6CgkJCQltaW5mLmFkZCgiaG1oZCIpOyAvLyBUT0RPOiBhZGQgcHJvcGVydGllcwoJCQkJYnJlYWs7CgkJCWNhc2UgIlN1YnRpdGxlIjoKCQkJCW1pbmYuYWRkKCJzdGhkIik7CgkJCQlzd2l0Y2ggKG9wdGlvbnMudHlwZSkgewoJCQkJCWNhc2UgInN0cHAiOgoJCQkJCQlzYW1wbGVfZGVzY3JpcHRpb25fZW50cnkuc2V0KCJuYW1lc3BhY2UiLCBvcHRpb25zLm5hbWVzcGFjZSB8fCAibm9uYW1lc3BhY2UiKQoJCQkJCQkJCQkuc2V0KCJzY2hlbWFfbG9jYXRpb24iLCBvcHRpb25zLnNjaGVtYV9sb2NhdGlvbiB8fCAiIikKCQkJCQkJCQkJLnNldCgiYXV4aWxpYXJ5X21pbWVfdHlwZXMiLCBvcHRpb25zLmF1eGlsaWFyeV9taW1lX3R5cGVzIHx8ICIiKTsKCQkJCQkJYnJlYWs7CgkJCQl9CgkJCQlicmVhazsKCQkJY2FzZSAiTWV0YWRhdGEiOgoJCQkJbWluZi5hZGQoIm5taGQiKTsKCQkJCWJyZWFrOwoJCQljYXNlICJTeXN0ZW0iOgoJCQkJbWluZi5hZGQoIm5taGQiKTsKCQkJCWJyZWFrOwoJCQlkZWZhdWx0OgoJCQkJbWluZi5hZGQoIm5taGQiKTsKCQkJCWJyZWFrOwoJCX0KCQlpZiAob3B0aW9ucy5kZXNjcmlwdGlvbikgewoJCQlzYW1wbGVfZGVzY3JpcHRpb25fZW50cnkuYWRkQm94KG9wdGlvbnMuZGVzY3JpcHRpb24pOwoJCX0KCQlpZiAob3B0aW9ucy5kZXNjcmlwdGlvbl9ib3hlcykgewoJCQlvcHRpb25zLmRlc2NyaXB0aW9uX2JveGVzLmZvckVhY2goZnVuY3Rpb24gKGIpIHsKCQkJCXNhbXBsZV9kZXNjcmlwdGlvbl9lbnRyeS5hZGRCb3goYik7CgkJCX0pOwoJCX0KCQltaW5mLmFkZCgiZGluZiIpLmFkZCgiZHJlZiIpLmFkZEVudHJ5KChuZXcgQm94UGFyc2VyWyJ1cmwgQm94Il0oKSkuc2V0KCJmbGFncyIsIDB4MSkpOwoJCXZhciBzdGJsID0gbWluZi5hZGQoInN0YmwiKTsKCQlzdGJsLmFkZCgic3RzZCIpLmFkZEVudHJ5KHNhbXBsZV9kZXNjcmlwdGlvbl9lbnRyeSk7CgkJc3RibC5hZGQoInN0dHMiKS5zZXQoInNhbXBsZV9jb3VudHMiLCBbXSkKCQkJCQkJLnNldCgic2FtcGxlX2RlbHRhcyIsIFtdKTsKCQlzdGJsLmFkZCgic3RzYyIpLnNldCgiZmlyc3RfY2h1bmsiLCBbXSkKCQkJCQkJLnNldCgic2FtcGxlc19wZXJfY2h1bmsiLCBbXSkKCQkJCQkJLnNldCgic2FtcGxlX2Rlc2NyaXB0aW9uX2luZGV4IiwgW10pOwoJCXN0YmwuYWRkKCJzdGNvIikuc2V0KCJjaHVua19vZmZzZXRzIiwgW10pOwoJCXN0YmwuYWRkKCJzdHN6Iikuc2V0KCJzYW1wbGVfc2l6ZXMiLCBbXSk7CgoJCXRoaXMubW9vdi5tdmV4LmFkZCgidHJleCIpLnNldCgidHJhY2tfaWQiLCBvcHRpb25zLmlkKQoJCQkJCQkJCSAgLnNldCgiZGVmYXVsdF9zYW1wbGVfZGVzY3JpcHRpb25faW5kZXgiLCBvcHRpb25zLmRlZmF1bHRfc2FtcGxlX2Rlc2NyaXB0aW9uX2luZGV4IHx8IDEpCgkJCQkJCQkJICAuc2V0KCJkZWZhdWx0X3NhbXBsZV9kdXJhdGlvbiIsIG9wdGlvbnMuZGVmYXVsdF9zYW1wbGVfZHVyYXRpb24gfHwgMCkKCQkJCQkJCQkgIC5zZXQoImRlZmF1bHRfc2FtcGxlX3NpemUiLCBvcHRpb25zLmRlZmF1bHRfc2FtcGxlX3NpemUgfHwgMCkKCQkJCQkJCQkgIC5zZXQoImRlZmF1bHRfc2FtcGxlX2ZsYWdzIiwgb3B0aW9ucy5kZWZhdWx0X3NhbXBsZV9mbGFncyB8fCAwKTsKCQl0aGlzLmJ1aWxkVHJha1NhbXBsZUxpc3RzKHRyYWspOwoJCXJldHVybiBvcHRpb25zLmlkOwoJfTsKCglCb3hQYXJzZXIuQm94LnByb3RvdHlwZS5jb21wdXRlU2l6ZSA9IGZ1bmN0aW9uKHN0cmVhbV8pIHsKCQl2YXIgc3RyZWFtID0gc3RyZWFtXyB8fCBuZXcgRGF0YVN0cmVhbSgpOwoJCXN0cmVhbS5lbmRpYW5uZXNzID0gRGF0YVN0cmVhbS5CSUdfRU5ESUFOOwoJCXRoaXMud3JpdGUoc3RyZWFtKTsKCX07CgoJSVNPRmlsZS5wcm90b3R5cGUuYWRkU2FtcGxlID0gZnVuY3Rpb24gKHRyYWNrX2lkLCBkYXRhLCBfb3B0aW9ucykgewoJCXZhciBvcHRpb25zID0gX29wdGlvbnMgfHwge307CgkJdmFyIHNhbXBsZSA9IHt9OwoJCXZhciB0cmFrID0gdGhpcy5nZXRUcmFja0J5SWQodHJhY2tfaWQpOwoJCWlmICh0cmFrID09PSBudWxsKSByZXR1cm47CgkgICAgc2FtcGxlLm51bWJlciA9IHRyYWsuc2FtcGxlcy5sZW5ndGg7CgkJc2FtcGxlLnRyYWNrX2lkID0gdHJhay50a2hkLnRyYWNrX2lkOwoJCXNhbXBsZS50aW1lc2NhbGUgPSB0cmFrLm1kaWEubWRoZC50aW1lc2NhbGU7CgkJc2FtcGxlLmRlc2NyaXB0aW9uX2luZGV4ID0gKG9wdGlvbnMuc2FtcGxlX2Rlc2NyaXB0aW9uX2luZGV4ID8gb3B0aW9ucy5zYW1wbGVfZGVzY3JpcHRpb25faW5kZXggLSAxOiAwKTsKCQlzYW1wbGUuZGVzY3JpcHRpb24gPSB0cmFrLm1kaWEubWluZi5zdGJsLnN0c2QuZW50cmllc1tzYW1wbGUuZGVzY3JpcHRpb25faW5kZXhdOwoJCXNhbXBsZS5kYXRhID0gZGF0YTsKCQlzYW1wbGUuc2l6ZSA9IGRhdGEuYnl0ZUxlbmd0aDsKCQlzYW1wbGUuYWxyZWFkeVJlYWQgPSBzYW1wbGUuc2l6ZTsKCQlzYW1wbGUuZHVyYXRpb24gPSBvcHRpb25zLmR1cmF0aW9uIHx8IDE7CgkJc2FtcGxlLmN0cyA9IG9wdGlvbnMuY3RzIHx8IDA7CgkJc2FtcGxlLmR0cyA9IG9wdGlvbnMuZHRzIHx8IDA7CgkJc2FtcGxlLmlzX3N5bmMgPSBvcHRpb25zLmlzX3N5bmMgfHwgZmFsc2U7CgkJc2FtcGxlLmlzX2xlYWRpbmcgPSBvcHRpb25zLmlzX2xlYWRpbmcgfHwgMDsKCQlzYW1wbGUuZGVwZW5kc19vbiA9IG9wdGlvbnMuZGVwZW5kc19vbiB8fCAwOwoJCXNhbXBsZS5pc19kZXBlbmRlZF9vbiA9IG9wdGlvbnMuaXNfZGVwZW5kZWRfb24gfHwgMDsKCQlzYW1wbGUuaGFzX3JlZHVuZGFuY3kgPSBvcHRpb25zLmhhc19yZWR1bmRhbmN5IHx8IDA7CgkJc2FtcGxlLmRlZ3JhZGF0aW9uX3ByaW9yaXR5ID0gb3B0aW9ucy5kZWdyYWRhdGlvbl9wcmlvcml0eSB8fCAwOwoJCXNhbXBsZS5vZmZzZXQgPSAwOwoJCXNhbXBsZS5zdWJzYW1wbGVzID0gb3B0aW9ucy5zdWJzYW1wbGVzOwoJCXRyYWsuc2FtcGxlcy5wdXNoKHNhbXBsZSk7CgkJdHJhay5zYW1wbGVzX3NpemUgKz0gc2FtcGxlLnNpemU7CgkJdHJhay5zYW1wbGVzX2R1cmF0aW9uICs9IHNhbXBsZS5kdXJhdGlvbjsKCQlpZiAoIXRyYWsuZmlyc3RfZHRzKSB7CgkJCXRyYWsuZmlyc3RfZHRzID0gb3B0aW9ucy5kdHM7CgkJfQoKCQl0aGlzLnByb2Nlc3NTYW1wbGVzKCk7CgkJCgkJdmFyIG1vb2YgPSB0aGlzLmNyZWF0ZVNpbmdsZVNhbXBsZU1vb2Yoc2FtcGxlKTsKCQl0aGlzLmFkZEJveChtb29mKTsKCQltb29mLmNvbXB1dGVTaXplKCk7CgkJLyogYWRqdXN0aW5nIHRoZSBkYXRhX29mZnNldCBub3cgdGhhdCB0aGUgbW9vZiBzaXplIGlzIGtub3duKi8KCQltb29mLnRyYWZzWzBdLnRydW5zWzBdLmRhdGFfb2Zmc2V0ID0gbW9vZi5zaXplKzg7IC8vOCBpcyBtZGF0IGhlYWRlcgoJCXRoaXMuYWRkKCJtZGF0IikuZGF0YSA9IG5ldyBVaW50OEFycmF5KGRhdGEpOwoJCXJldHVybiBzYW1wbGU7Cgl9OwoKCUlTT0ZpbGUucHJvdG90eXBlLmNyZWF0ZVNpbmdsZVNhbXBsZU1vb2YgPSBmdW5jdGlvbihzYW1wbGUpIHsKCQl2YXIgc2FtcGxlX2ZsYWdzID0gMDsKCQlpZiAoc2FtcGxlLmlzX3N5bmMpCgkJCXNhbXBsZV9mbGFncyA9ICgxIDw8IDI1KTsgIC8vIHNhbXBsZV9kZXBlbmRzX29uX25vbmUgKEkgcGljdHVyZSkKCQllbHNlCgkJCXNhbXBsZV9mbGFncyA9ICgxIDw8IDE2KTsgIC8vIG5vbi1zeW5jCgoJCXZhciBtb29mID0gbmV3IEJveFBhcnNlci5tb29mQm94KCk7CgkJbW9vZi5hZGQoIm1maGQiKS5zZXQoInNlcXVlbmNlX251bWJlciIsIHRoaXMubmV4dE1vb2ZOdW1iZXIpOwoJCXRoaXMubmV4dE1vb2ZOdW1iZXIrKzsKCQl2YXIgdHJhZiA9IG1vb2YuYWRkKCJ0cmFmIik7CgkJdmFyIHRyYWsgPSB0aGlzLmdldFRyYWNrQnlJZChzYW1wbGUudHJhY2tfaWQpOwoJCXRyYWYuYWRkKCJ0ZmhkIikuc2V0KCJ0cmFja19pZCIsIHNhbXBsZS50cmFja19pZCkKCQkJCQkJLnNldCgiZmxhZ3MiLCBCb3hQYXJzZXIuVEZIRF9GTEFHX0RFRkFVTFRfQkFTRV9JU19NT09GKTsKCQl0cmFmLmFkZCgidGZkdCIpLnNldCgiYmFzZU1lZGlhRGVjb2RlVGltZSIsIChzYW1wbGUuZHRzIC0gKHRyYWsuZmlyc3RfZHRzIHx8IDApKSk7CgkJdHJhZi5hZGQoInRydW4iKS5zZXQoImZsYWdzIiwgQm94UGFyc2VyLlRSVU5fRkxBR1NfREFUQV9PRkZTRVQgfCBCb3hQYXJzZXIuVFJVTl9GTEFHU19EVVJBVElPTiB8IAoJCQkJCSAJCQkJICBCb3hQYXJzZXIuVFJVTl9GTEFHU19TSVpFIHwgQm94UGFyc2VyLlRSVU5fRkxBR1NfRkxBR1MgfCAKCQkJCQkgCQkJCSAgQm94UGFyc2VyLlRSVU5fRkxBR1NfQ1RTX09GRlNFVCkKCQkJCQkJLnNldCgiZGF0YV9vZmZzZXQiLDApCgkJCQkJCS5zZXQoImZpcnN0X3NhbXBsZV9mbGFncyIsMCkKCQkJCQkJLnNldCgic2FtcGxlX2NvdW50IiwxKQoJCQkJCQkuc2V0KCJzYW1wbGVfZHVyYXRpb24iLFtzYW1wbGUuZHVyYXRpb25dKQoJCQkJCQkuc2V0KCJzYW1wbGVfc2l6ZSIsW3NhbXBsZS5zaXplXSkKCQkJCQkJLnNldCgic2FtcGxlX2ZsYWdzIixbc2FtcGxlX2ZsYWdzXSkKCQkJCQkJLnNldCgic2FtcGxlX2NvbXBvc2l0aW9uX3RpbWVfb2Zmc2V0IiwgW3NhbXBsZS5jdHMgLSBzYW1wbGUuZHRzXSk7CgkJcmV0dXJuIG1vb2Y7Cgl9OwoKCS8vIGZpbGU6c3JjL2lzb2ZpbGUtc2FtcGxlLXByb2Nlc3NpbmcuanMKCS8qIEluZGV4IG9mIHRoZSBsYXN0IG1vb2YgYm94IHJlY2VpdmVkICovCglJU09GaWxlLnByb3RvdHlwZS5sYXN0TW9vZkluZGV4ID0gMDsKCgkvKiBzaXplIG9mIHRoZSBidWZmZXJzIGFsbG9jYXRlZCBmb3Igc2FtcGxlcyAqLwoJSVNPRmlsZS5wcm90b3R5cGUuc2FtcGxlc0RhdGFTaXplID0gMDsKCgkvKiBSZXNldHMgYWxsIHNhbXBsZSB0YWJsZXMgKi8KCUlTT0ZpbGUucHJvdG90eXBlLnJlc2V0VGFibGVzID0gZnVuY3Rpb24gKCkgewoJCXZhciBpOwoJCXZhciB0cmFrLCBzdGNvLCBzdHNjLCBzdHN6LCBzdHRzLCBjdHRzLCBzdHNzOwoJCXRoaXMuaW5pdGlhbF9kdXJhdGlvbiA9IHRoaXMubW9vdi5tdmhkLmR1cmF0aW9uOwoJCXRoaXMubW9vdi5tdmhkLmR1cmF0aW9uID0gMDsKCQlmb3IgKGkgPSAwOyBpIDwgdGhpcy5tb292LnRyYWtzLmxlbmd0aDsgaSsrKSB7CgkJCXRyYWsgPSB0aGlzLm1vb3YudHJha3NbaV07CgkJCXRyYWsudGtoZC5kdXJhdGlvbiA9IDA7CgkJCXRyYWsubWRpYS5tZGhkLmR1cmF0aW9uID0gMDsKCQkJc3RjbyA9IHRyYWsubWRpYS5taW5mLnN0Ymwuc3RjbyB8fCB0cmFrLm1kaWEubWluZi5zdGJsLmNvNjQ7CgkJCXN0Y28uY2h1bmtfb2Zmc2V0cyA9IFtdOwoJCQlzdHNjID0gdHJhay5tZGlhLm1pbmYuc3RibC5zdHNjOwoJCQlzdHNjLmZpcnN0X2NodW5rID0gW107CgkJCXN0c2Muc2FtcGxlc19wZXJfY2h1bmsgPSBbXTsKCQkJc3RzYy5zYW1wbGVfZGVzY3JpcHRpb25faW5kZXggPSBbXTsKCQkJc3RzeiA9IHRyYWsubWRpYS5taW5mLnN0Ymwuc3RzeiB8fCB0cmFrLm1kaWEubWluZi5zdGJsLnN0ejI7CgkJCXN0c3ouc2FtcGxlX3NpemVzID0gW107CgkJCXN0dHMgPSB0cmFrLm1kaWEubWluZi5zdGJsLnN0dHM7CgkJCXN0dHMuc2FtcGxlX2NvdW50cyA9IFtdOwoJCQlzdHRzLnNhbXBsZV9kZWx0YXMgPSBbXTsKCQkJY3R0cyA9IHRyYWsubWRpYS5taW5mLnN0YmwuY3R0czsKCQkJaWYgKGN0dHMpIHsKCQkJCWN0dHMuc2FtcGxlX2NvdW50cyA9IFtdOwoJCQkJY3R0cy5zYW1wbGVfb2Zmc2V0cyA9IFtdOwoJCQl9CgkJCXN0c3MgPSB0cmFrLm1kaWEubWluZi5zdGJsLnN0c3M7CgkJCXZhciBrID0gdHJhay5tZGlhLm1pbmYuc3RibC5ib3hlcy5pbmRleE9mKHN0c3MpOwoJCQlpZiAoayAhPSAtMSkgdHJhay5tZGlhLm1pbmYuc3RibC5ib3hlc1trXSA9IG51bGw7CgkJfQoJfTsKCglJU09GaWxlLmluaXRTYW1wbGVHcm91cHMgPSBmdW5jdGlvbih0cmFrLCB0cmFmLCBzYmdwcywgdHJha19zZ3BkcywgdHJhZl9zZ3BkcykgewoJCXZhciBsOwoJCXZhciBrOwoJCXZhciBzYW1wbGVfZ3JvdXBfaW5mbzsKCQl2YXIgc2FtcGxlX2dyb3VwX2tleTsKCQlmdW5jdGlvbiBTYW1wbGVHcm91cEluZm8oX3R5cGUsIF9wYXJhbWV0ZXIsIF9zYmdwKSB7CgkJCXRoaXMuZ3JvdXBpbmdfdHlwZSA9IF90eXBlOwoJCQl0aGlzLmdyb3VwaW5nX3R5cGVfcGFyYW1ldGVyID0gX3BhcmFtZXRlcjsKCQkJdGhpcy5zYmdwID0gX3NiZ3A7CgkJCXRoaXMubGFzdF9zYW1wbGVfaW5fcnVuID0gLTE7CgkJCXRoaXMuZW50cnlfaW5kZXggPSAtMTsJCQoJCX0KCQlpZiAodHJhZikgewoJCQl0cmFmLnNhbXBsZV9ncm91cHNfaW5mbyA9IFtdOwoJCX0gCgkJaWYgKCF0cmFrLnNhbXBsZV9ncm91cHNfaW5mbykgewoJCQl0cmFrLnNhbXBsZV9ncm91cHNfaW5mbyA9IFtdOwoJCX0KCQlmb3IgKGsgPSAwOyBrIDwgc2JncHMubGVuZ3RoOyBrKyspIHsKCQkJc2FtcGxlX2dyb3VwX2tleSA9IHNiZ3BzW2tdLmdyb3VwaW5nX3R5cGUgKyIvIisgc2JncHNba10uZ3JvdXBpbmdfdHlwZV9wYXJhbWV0ZXI7CgkJCXNhbXBsZV9ncm91cF9pbmZvID0gbmV3IFNhbXBsZUdyb3VwSW5mbyhzYmdwc1trXS5ncm91cGluZ190eXBlLCBzYmdwc1trXS5ncm91cGluZ190eXBlX3BhcmFtZXRlciwgc2JncHNba10pOwoJCQlpZiAodHJhZikgewoJCQkJdHJhZi5zYW1wbGVfZ3JvdXBzX2luZm9bc2FtcGxlX2dyb3VwX2tleV0gPSBzYW1wbGVfZ3JvdXBfaW5mbzsKCQkJfQoJCQlpZiAoIXRyYWsuc2FtcGxlX2dyb3Vwc19pbmZvW3NhbXBsZV9ncm91cF9rZXldKSB7CgkJCQl0cmFrLnNhbXBsZV9ncm91cHNfaW5mb1tzYW1wbGVfZ3JvdXBfa2V5XSA9IHNhbXBsZV9ncm91cF9pbmZvOwoJCQl9CgkJCWZvciAobD0wOyBsIDx0cmFrX3NncGRzLmxlbmd0aDsgbCsrKSB7CgkJCQlpZiAodHJha19zZ3Bkc1tsXS5ncm91cGluZ190eXBlID09PSBzYmdwc1trXS5ncm91cGluZ190eXBlKSB7CgkJCQkJc2FtcGxlX2dyb3VwX2luZm8uZGVzY3JpcHRpb24gPSB0cmFrX3NncGRzW2xdOwoJCQkJCXNhbXBsZV9ncm91cF9pbmZvLmRlc2NyaXB0aW9uLnVzZWQgPSB0cnVlOwoJCQkJfQoJCQl9CgkJCWlmICh0cmFmX3NncGRzKSB7CgkJCQlmb3IgKGw9MDsgbCA8dHJhZl9zZ3Bkcy5sZW5ndGg7IGwrKykgewoJCQkJCWlmICh0cmFmX3NncGRzW2xdLmdyb3VwaW5nX3R5cGUgPT09IHNiZ3BzW2tdLmdyb3VwaW5nX3R5cGUpIHsKCQkJCQkJc2FtcGxlX2dyb3VwX2luZm8uZnJhZ21lbnRfZGVzY3JpcHRpb24gPSB0cmFmX3NncGRzW2xdOwoJCQkJCQlzYW1wbGVfZ3JvdXBfaW5mby5mcmFnbWVudF9kZXNjcmlwdGlvbi51c2VkID0gdHJ1ZTsKCQkJCQkJc2FtcGxlX2dyb3VwX2luZm8uaXNfZnJhZ21lbnQgPSB0cnVlOwoJCQkJCX0KCQkJCX0JCQkKCQkJfQoJCX0KCQlpZiAoIXRyYWYpIHsKCQkJZm9yIChrID0gMDsgayA8IHRyYWtfc2dwZHMubGVuZ3RoOyBrKyspIHsKCQkJCWlmICghdHJha19zZ3Bkc1trXS51c2VkICYmIHRyYWtfc2dwZHNba10udmVyc2lvbiA+PSAyKSB7CgkJCQkJc2FtcGxlX2dyb3VwX2tleSA9IHRyYWtfc2dwZHNba10uZ3JvdXBpbmdfdHlwZSArIi8wIjsKCQkJCQlzYW1wbGVfZ3JvdXBfaW5mbyA9IG5ldyBTYW1wbGVHcm91cEluZm8odHJha19zZ3Bkc1trXS5ncm91cGluZ190eXBlLCAwKTsKCQkJCQlpZiAoIXRyYWsuc2FtcGxlX2dyb3Vwc19pbmZvW3NhbXBsZV9ncm91cF9rZXldKSB7CgkJCQkJCXRyYWsuc2FtcGxlX2dyb3Vwc19pbmZvW3NhbXBsZV9ncm91cF9rZXldID0gc2FtcGxlX2dyb3VwX2luZm87CgkJCQkJfQoJCQkJfQoJCQl9CgkJfSBlbHNlIHsKCQkJaWYgKHRyYWZfc2dwZHMpIHsKCQkJCWZvciAoayA9IDA7IGsgPCB0cmFmX3NncGRzLmxlbmd0aDsgaysrKSB7CgkJCQkJaWYgKCF0cmFmX3NncGRzW2tdLnVzZWQgJiYgdHJhZl9zZ3Bkc1trXS52ZXJzaW9uID49IDIpIHsKCQkJCQkJc2FtcGxlX2dyb3VwX2tleSA9IHRyYWZfc2dwZHNba10uZ3JvdXBpbmdfdHlwZSArIi8wIjsKCQkJCQkJc2FtcGxlX2dyb3VwX2luZm8gPSBuZXcgU2FtcGxlR3JvdXBJbmZvKHRyYWZfc2dwZHNba10uZ3JvdXBpbmdfdHlwZSwgMCk7CgkJCQkJCXNhbXBsZV9ncm91cF9pbmZvLmlzX2ZyYWdtZW50ID0gdHJ1ZTsKCQkJCQkJaWYgKCF0cmFmLnNhbXBsZV9ncm91cHNfaW5mb1tzYW1wbGVfZ3JvdXBfa2V5XSkgewoJCQkJCQkJdHJhZi5zYW1wbGVfZ3JvdXBzX2luZm9bc2FtcGxlX2dyb3VwX2tleV0gPSBzYW1wbGVfZ3JvdXBfaW5mbzsKCQkJCQkJfQoJCQkJCX0KCQkJCX0KCQkJfQoJCX0KCX07CgoJSVNPRmlsZS5zZXRTYW1wbGVHcm91cFByb3BlcnRpZXMgPSBmdW5jdGlvbih0cmFrLCBzYW1wbGUsIHNhbXBsZV9udW1iZXIsIHNhbXBsZV9ncm91cHNfaW5mbykgewoJCXZhciBrOwoJCXZhciBpbmRleDsKCQlzYW1wbGUuc2FtcGxlX2dyb3VwcyA9IFtdOwoJCWZvciAoayBpbiBzYW1wbGVfZ3JvdXBzX2luZm8pIHsKCQkJc2FtcGxlLnNhbXBsZV9ncm91cHNba10gPSB7fTsKCQkJc2FtcGxlLnNhbXBsZV9ncm91cHNba10uZ3JvdXBpbmdfdHlwZSA9IHNhbXBsZV9ncm91cHNfaW5mb1trXS5ncm91cGluZ190eXBlOwoJCQlzYW1wbGUuc2FtcGxlX2dyb3Vwc1trXS5ncm91cGluZ190eXBlX3BhcmFtZXRlciA9IHNhbXBsZV9ncm91cHNfaW5mb1trXS5ncm91cGluZ190eXBlX3BhcmFtZXRlcjsKCQkJaWYgKHNhbXBsZV9udW1iZXIgPj0gc2FtcGxlX2dyb3Vwc19pbmZvW2tdLmxhc3Rfc2FtcGxlX2luX3J1bikgewoJCQkJaWYgKHNhbXBsZV9ncm91cHNfaW5mb1trXS5sYXN0X3NhbXBsZV9pbl9ydW4gPCAwKSB7CgkJCQkJc2FtcGxlX2dyb3Vwc19pbmZvW2tdLmxhc3Rfc2FtcGxlX2luX3J1biA9IDA7CgkJCQl9CgkJCQlzYW1wbGVfZ3JvdXBzX2luZm9ba10uZW50cnlfaW5kZXgrKzsJCgkJCQlpZiAoc2FtcGxlX2dyb3Vwc19pbmZvW2tdLmVudHJ5X2luZGV4IDw9IHNhbXBsZV9ncm91cHNfaW5mb1trXS5zYmdwLmVudHJpZXMubGVuZ3RoIC0gMSkgewoJCQkJCXNhbXBsZV9ncm91cHNfaW5mb1trXS5sYXN0X3NhbXBsZV9pbl9ydW4gKz0gc2FtcGxlX2dyb3Vwc19pbmZvW2tdLnNiZ3AuZW50cmllc1tzYW1wbGVfZ3JvdXBzX2luZm9ba10uZW50cnlfaW5kZXhdLnNhbXBsZV9jb3VudDsKCQkJCX0KCQkJfQoJCQlpZiAoc2FtcGxlX2dyb3Vwc19pbmZvW2tdLmVudHJ5X2luZGV4IDw9IHNhbXBsZV9ncm91cHNfaW5mb1trXS5zYmdwLmVudHJpZXMubGVuZ3RoIC0gMSkgewoJCQkJc2FtcGxlLnNhbXBsZV9ncm91cHNba10uZ3JvdXBfZGVzY3JpcHRpb25faW5kZXggPSBzYW1wbGVfZ3JvdXBzX2luZm9ba10uc2JncC5lbnRyaWVzW3NhbXBsZV9ncm91cHNfaW5mb1trXS5lbnRyeV9pbmRleF0uZ3JvdXBfZGVzY3JpcHRpb25faW5kZXg7CgkJCX0gZWxzZSB7CgkJCQlzYW1wbGUuc2FtcGxlX2dyb3Vwc1trXS5ncm91cF9kZXNjcmlwdGlvbl9pbmRleCA9IC0xOyAvLyBzcGVjaWFsIHZhbHVlIGZvciBub3QgZGVmaW5lZAoJCQl9CgkJCWlmIChzYW1wbGUuc2FtcGxlX2dyb3Vwc1trXS5ncm91cF9kZXNjcmlwdGlvbl9pbmRleCAhPT0gMCkgewoJCQkJdmFyIGRlc2NyaXB0aW9uOwoJCQkJaWYgKHNhbXBsZV9ncm91cHNfaW5mb1trXS5mcmFnbWVudF9kZXNjcmlwdGlvbikgewoJCQkJCWRlc2NyaXB0aW9uID0gc2FtcGxlX2dyb3Vwc19pbmZvW2tdLmZyYWdtZW50X2Rlc2NyaXB0aW9uOwoJCQkJfSBlbHNlIHsKCQkJCQlkZXNjcmlwdGlvbiA9IHNhbXBsZV9ncm91cHNfaW5mb1trXS5kZXNjcmlwdGlvbjsKCQkJCX0KCQkJCWlmIChzYW1wbGUuc2FtcGxlX2dyb3Vwc1trXS5ncm91cF9kZXNjcmlwdGlvbl9pbmRleCA+IDApIHsKCQkJCQlpZiAoc2FtcGxlLnNhbXBsZV9ncm91cHNba10uZ3JvdXBfZGVzY3JpcHRpb25faW5kZXggPiA2NTUzNSkgewoJCQkJCQlpbmRleCA9IChzYW1wbGUuc2FtcGxlX2dyb3Vwc1trXS5ncm91cF9kZXNjcmlwdGlvbl9pbmRleCA+PiAxNiktMTsKCQkJCQl9IGVsc2UgewoJCQkJCQlpbmRleCA9IHNhbXBsZS5zYW1wbGVfZ3JvdXBzW2tdLmdyb3VwX2Rlc2NyaXB0aW9uX2luZGV4LTE7CgkJCQkJfQoJCQkJCWlmIChkZXNjcmlwdGlvbiAmJiBpbmRleCA+PSAwKSB7CgkJCQkJCXNhbXBsZS5zYW1wbGVfZ3JvdXBzW2tdLmRlc2NyaXB0aW9uID0gZGVzY3JpcHRpb24uZW50cmllc1tpbmRleF07CgkJCQkJfQoJCQkJfSBlbHNlIHsKCQkJCQlpZiAoZGVzY3JpcHRpb24gJiYgZGVzY3JpcHRpb24udmVyc2lvbiA+PSAyKSB7CgkJCQkJCWlmIChkZXNjcmlwdGlvbi5kZWZhdWx0X2dyb3VwX2Rlc2NyaXB0aW9uX2luZGV4ID4gMCkgewkJCQkJCQkJCgkJCQkJCQlzYW1wbGUuc2FtcGxlX2dyb3Vwc1trXS5kZXNjcmlwdGlvbiA9IGRlc2NyaXB0aW9uLmVudHJpZXNbZGVzY3JpcHRpb24uZGVmYXVsdF9ncm91cF9kZXNjcmlwdGlvbl9pbmRleC0xXTsKCQkJCQkJfQoJCQkJCX0KCQkJCX0KCQkJfQoJCX0KCX07CgoJSVNPRmlsZS5wcm9jZXNzX3NkdHAgPSBmdW5jdGlvbiAoc2R0cCwgc2FtcGxlLCBudW1iZXIpIHsKCQlpZiAoIXNhbXBsZSkgewoJCQlyZXR1cm47CgkJfQoJCWlmIChzZHRwKSB7CgkJCXNhbXBsZS5pc19sZWFkaW5nID0gc2R0cC5pc19sZWFkaW5nW251bWJlcl07CgkJCXNhbXBsZS5kZXBlbmRzX29uID0gc2R0cC5zYW1wbGVfZGVwZW5kc19vbltudW1iZXJdOwoJCQlzYW1wbGUuaXNfZGVwZW5kZWRfb24gPSBzZHRwLnNhbXBsZV9pc19kZXBlbmRlZF9vbltudW1iZXJdOwoJCQlzYW1wbGUuaGFzX3JlZHVuZGFuY3kgPSBzZHRwLnNhbXBsZV9oYXNfcmVkdW5kYW5jeVtudW1iZXJdOwoJCX0gZWxzZSB7CgkJCXNhbXBsZS5pc19sZWFkaW5nID0gMDsKCQkJc2FtcGxlLmRlcGVuZHNfb24gPSAwOwoJCQlzYW1wbGUuaXNfZGVwZW5kZWRfb24gPSAwOwoJCQlzYW1wbGUuaGFzX3JlZHVuZGFuY3kgPSAwOwoJCX0JCgl9OwoKCS8qIEJ1aWxkIGluaXRpYWwgc2FtcGxlIGxpc3QgZnJvbSAgc2FtcGxlIHRhYmxlcyAqLwoJSVNPRmlsZS5wcm90b3R5cGUuYnVpbGRTYW1wbGVMaXN0cyA9IGZ1bmN0aW9uKCkgewkKCQl2YXIgaTsKCQl2YXIgdHJhazsKCQlmb3IgKGkgPSAwOyBpIDwgdGhpcy5tb292LnRyYWtzLmxlbmd0aDsgaSsrKSB7CgkJCXRyYWsgPSB0aGlzLm1vb3YudHJha3NbaV07CgkJCXRoaXMuYnVpbGRUcmFrU2FtcGxlTGlzdHModHJhayk7CgkJfQoJfTsKCglJU09GaWxlLnByb3RvdHlwZS5idWlsZFRyYWtTYW1wbGVMaXN0cyA9IGZ1bmN0aW9uKHRyYWspIHsJCgkJdmFyIGo7CgkJdmFyIHN0Y28sIHN0c2MsIHN0c3osIHN0dHMsIGN0dHMsIHN0c3MsIHN0c2QsIHN1YnMsIHNiZ3BzLCBzZ3Bkcywgc3RkcDsKCQl2YXIgY2h1bmtfcnVuX2luZGV4LCBjaHVua19pbmRleCwgbGFzdF9jaHVua19pbl9ydW4sIG9mZnNldF9pbl9jaHVuaywgbGFzdF9zYW1wbGVfaW5fY2h1bms7CgkJdmFyIGxhc3Rfc2FtcGxlX2luX3N0dHNfcnVuLCBzdHRzX3J1bl9pbmRleCwgbGFzdF9zYW1wbGVfaW5fY3R0c19ydW4sIGN0dHNfcnVuX2luZGV4LCBsYXN0X3N0c3NfaW5kZXgsIHN1YnNfZW50cnlfaW5kZXgsIGxhc3Rfc3Vic19zYW1wbGVfaW5kZXg7CgoJCXRyYWsuc2FtcGxlcyA9IFtdOwoJCXRyYWsuc2FtcGxlc19kdXJhdGlvbiA9IDA7CgkJdHJhay5zYW1wbGVzX3NpemUgPSAwOwoJCXN0Y28gPSB0cmFrLm1kaWEubWluZi5zdGJsLnN0Y28gfHwgdHJhay5tZGlhLm1pbmYuc3RibC5jbzY0OwoJCXN0c2MgPSB0cmFrLm1kaWEubWluZi5zdGJsLnN0c2M7CgkJc3RzeiA9IHRyYWsubWRpYS5taW5mLnN0Ymwuc3RzeiB8fCB0cmFrLm1kaWEubWluZi5zdGJsLnN0ejI7CgkJc3R0cyA9IHRyYWsubWRpYS5taW5mLnN0Ymwuc3R0czsKCQljdHRzID0gdHJhay5tZGlhLm1pbmYuc3RibC5jdHRzOwoJCXN0c3MgPSB0cmFrLm1kaWEubWluZi5zdGJsLnN0c3M7CgkJc3RzZCA9IHRyYWsubWRpYS5taW5mLnN0Ymwuc3RzZDsKCQlzdWJzID0gdHJhay5tZGlhLm1pbmYuc3RibC5zdWJzOwoJCXN0ZHAgPSB0cmFrLm1kaWEubWluZi5zdGJsLnN0ZHA7CgkJc2JncHMgPSB0cmFrLm1kaWEubWluZi5zdGJsLnNiZ3BzOwoJCXNncGRzID0gdHJhay5tZGlhLm1pbmYuc3RibC5zZ3BkczsKCQkKCQlsYXN0X3NhbXBsZV9pbl9zdHRzX3J1biA9IC0xOwoJCXN0dHNfcnVuX2luZGV4ID0gLTE7CgkJbGFzdF9zYW1wbGVfaW5fY3R0c19ydW4gPSAtMTsKCQljdHRzX3J1bl9pbmRleCA9IC0xOwoJCWxhc3Rfc3Rzc19pbmRleCA9IDA7CgkJc3Vic19lbnRyeV9pbmRleCA9IDA7CgkJbGFzdF9zdWJzX3NhbXBsZV9pbmRleCA9IDA7CQkKCgkJSVNPRmlsZS5pbml0U2FtcGxlR3JvdXBzKHRyYWssIG51bGwsIHNiZ3BzLCBzZ3Bkcyk7CgoJCWlmICh0eXBlb2Ygc3RzeiA9PT0gInVuZGVmaW5lZCIpIHsKCQkJcmV0dXJuOwoJCX0KCgkJLyogd2UgYnVpbGQgdGhlIHNhbXBsZXMgb25lIGJ5IG9uZSBhbmQgY29tcHV0ZSB0aGVpciBwcm9wZXJ0aWVzICovCgkJZm9yIChqID0gMDsgaiA8IHN0c3ouc2FtcGxlX3NpemVzLmxlbmd0aDsgaisrKSB7CgkJCXZhciBzYW1wbGUgPSB7fTsKCQkJc2FtcGxlLm51bWJlciA9IGo7CgkJCXNhbXBsZS50cmFja19pZCA9IHRyYWsudGtoZC50cmFja19pZDsKCQkJc2FtcGxlLnRpbWVzY2FsZSA9IHRyYWsubWRpYS5tZGhkLnRpbWVzY2FsZTsKCQkJc2FtcGxlLmFscmVhZHlSZWFkID0gMDsKCQkJdHJhay5zYW1wbGVzW2pdID0gc2FtcGxlOwoJCQkvKiBzaXplIGNhbiBiZSBrbm93biBkaXJlY3RseSAqLwoJCQlzYW1wbGUuc2l6ZSA9IHN0c3ouc2FtcGxlX3NpemVzW2pdOwoJCQl0cmFrLnNhbXBsZXNfc2l6ZSArPSBzYW1wbGUuc2l6ZTsKCQkJLyogY29tcHV0aW5nIGNodW5rLWJhc2VkIHByb3BlcnRpZXMgKG9mZnNldCwgc2FtcGxlIGRlc2NyaXB0aW9uIGluZGV4KSovCgkJCWlmIChqID09PSAwKSB7CQkJCQoJCQkJY2h1bmtfaW5kZXggPSAxOyAvKiB0aGUgZmlyc3Qgc2FtcGxlIGlzIGluIHRoZSBmaXJzdCBjaHVuayAoY2h1bmsgaW5kZXhlcyBhcmUgMS1iYXNlZCkgKi8KCQkJCWNodW5rX3J1bl9pbmRleCA9IDA7IC8qIHRoZSBmaXJzdCBjaHVuayBpcyB0aGUgZmlyc3QgZW50cnkgaW4gdGhlIGZpcnN0X2NodW5rIHRhYmxlICovCgkJCQlzYW1wbGUuY2h1bmtfaW5kZXggPSBjaHVua19pbmRleDsKCQkJCXNhbXBsZS5jaHVua19ydW5faW5kZXggPSBjaHVua19ydW5faW5kZXg7CgkJCQlsYXN0X3NhbXBsZV9pbl9jaHVuayA9IHN0c2Muc2FtcGxlc19wZXJfY2h1bmtbY2h1bmtfcnVuX2luZGV4XTsKCQkJCW9mZnNldF9pbl9jaHVuayA9IDA7CgoJCQkJLyogSXMgdGhlcmUgYW5vdGhlciBlbnRyeSBpbiB0aGUgZmlyc3RfY2h1bmsgdGFibGUgPyAqLwoJCQkJaWYgKGNodW5rX3J1bl9pbmRleCArIDEgPCBzdHNjLmZpcnN0X2NodW5rLmxlbmd0aCkgewoJCQkJCS8qIFRoZSBsYXN0IGNodW5rIGluIHRoZSBydW4gaXMgdGhlIGNodW5rIGJlZm9yZSB0aGUgbmV4dCBmaXJzdCBjaHVuayAqLwoJCQkJCWxhc3RfY2h1bmtfaW5fcnVuID0gc3RzYy5maXJzdF9jaHVua1tjaHVua19ydW5faW5kZXgrMV0tMTsgCQoJCQkJfSBlbHNlIHsKCQkJCQkvKiBUaGVyZSBpcyBvbmx5IG9uZSBlbnRyeSBpbiB0aGUgdGFibGUsIGl0IGlzIHZhbGlkIGZvciBhbGwgZnV0dXJlIGNodW5rcyovCgkJCQkJbGFzdF9jaHVua19pbl9ydW4gPSBJbmZpbml0eTsKCQkJCX0KCQkJfSBlbHNlIHsKCQkJCWlmIChqIDwgbGFzdF9zYW1wbGVfaW5fY2h1bmspIHsKCQkJCQkvKiB0aGUgc2FtcGxlIGlzIHN0aWxsIGluIHRoZSBjdXJyZW50IGNodW5rICovCgkJCQkJc2FtcGxlLmNodW5rX2luZGV4ID0gY2h1bmtfaW5kZXg7CgkJCQkJc2FtcGxlLmNodW5rX3J1bl9pbmRleCA9IGNodW5rX3J1bl9pbmRleDsKCQkJCX0gZWxzZSB7CgkJCQkJLyogdGhlIHNhbXBsZSBpcyBpbiB0aGUgbmV4dCBjaHVuayAqLwoJCQkJCWNodW5rX2luZGV4Kys7CgkJCQkJc2FtcGxlLmNodW5rX2luZGV4ID0gY2h1bmtfaW5kZXg7CgkJCQkJLyogcmVzZXQgdGhlIGFjY3VtdWxhdGVkIG9mZnNldCBpbiB0aGUgY2h1bmsgKi8KCQkJCQlvZmZzZXRfaW5fY2h1bmsgPSAwOwoJCQkJCWlmIChjaHVua19pbmRleCA8PSBsYXN0X2NodW5rX2luX3J1bikgOyBlbHNlIHsKCQkJCQkJY2h1bmtfcnVuX2luZGV4Kys7CgkJCQkJCS8qIElzIHRoZXJlIGFub3RoZXIgZW50cnkgaW4gdGhlIGZpcnN0X2NodW5rIHRhYmxlID8gKi8KCQkJCQkJaWYgKGNodW5rX3J1bl9pbmRleCArIDEgPCBzdHNjLmZpcnN0X2NodW5rLmxlbmd0aCkgewoJCQkJCQkJLyogVGhlIGxhc3QgY2h1bmsgaW4gdGhlIHJ1biBpcyB0aGUgY2h1bmsgYmVmb3JlIHRoZSBuZXh0IGZpcnN0IGNodW5rICovCgkJCQkJCQlsYXN0X2NodW5rX2luX3J1biA9IHN0c2MuZmlyc3RfY2h1bmtbY2h1bmtfcnVuX2luZGV4KzFdLTE7IAkKCQkJCQkJfSBlbHNlIHsKCQkJCQkJCS8qIFRoZXJlIGlzIG9ubHkgb25lIGVudHJ5IGluIHRoZSB0YWJsZSwgaXQgaXMgdmFsaWQgZm9yIGFsbCBmdXR1cmUgY2h1bmtzKi8KCQkJCQkJCWxhc3RfY2h1bmtfaW5fcnVuID0gSW5maW5pdHk7CgkJCQkJCX0KCQkJCQkJCgkJCQkJfQoJCQkJCXNhbXBsZS5jaHVua19ydW5faW5kZXggPSBjaHVua19ydW5faW5kZXg7CgkJCQkJbGFzdF9zYW1wbGVfaW5fY2h1bmsgKz0gc3RzYy5zYW1wbGVzX3Blcl9jaHVua1tjaHVua19ydW5faW5kZXhdOwoJCQkJfQoJCQl9CgoJCQlzYW1wbGUuZGVzY3JpcHRpb25faW5kZXggPSBzdHNjLnNhbXBsZV9kZXNjcmlwdGlvbl9pbmRleFtzYW1wbGUuY2h1bmtfcnVuX2luZGV4XS0xOwoJCQlzYW1wbGUuZGVzY3JpcHRpb24gPSBzdHNkLmVudHJpZXNbc2FtcGxlLmRlc2NyaXB0aW9uX2luZGV4XTsKCQkJc2FtcGxlLm9mZnNldCA9IHN0Y28uY2h1bmtfb2Zmc2V0c1tzYW1wbGUuY2h1bmtfaW5kZXgtMV0gKyBvZmZzZXRfaW5fY2h1bms7IC8qIGNodW5rIGluZGV4ZXMgYXJlIDEtYmFzZWQgKi8KCQkJb2Zmc2V0X2luX2NodW5rICs9IHNhbXBsZS5zaXplOwoKCQkJLyogc2V0dGluZyBkdHMsIGN0cywgZHVyYXRpb24gYW5kIHJhcCBmbGFncyAqLwoJCQlpZiAoaiA+IGxhc3Rfc2FtcGxlX2luX3N0dHNfcnVuKSB7CgkJCQlzdHRzX3J1bl9pbmRleCsrOwoJCQkJaWYgKGxhc3Rfc2FtcGxlX2luX3N0dHNfcnVuIDwgMCkgewoJCQkJCWxhc3Rfc2FtcGxlX2luX3N0dHNfcnVuID0gMDsKCQkJCX0KCQkJCWxhc3Rfc2FtcGxlX2luX3N0dHNfcnVuICs9IHN0dHMuc2FtcGxlX2NvdW50c1tzdHRzX3J1bl9pbmRleF07CQkJCQoJCQl9CgkJCWlmIChqID4gMCkgewoJCQkJdHJhay5zYW1wbGVzW2otMV0uZHVyYXRpb24gPSBzdHRzLnNhbXBsZV9kZWx0YXNbc3R0c19ydW5faW5kZXhdOwoJCQkJdHJhay5zYW1wbGVzX2R1cmF0aW9uICs9IHRyYWsuc2FtcGxlc1tqLTFdLmR1cmF0aW9uOwoJCQkJc2FtcGxlLmR0cyA9IHRyYWsuc2FtcGxlc1tqLTFdLmR0cyArIHRyYWsuc2FtcGxlc1tqLTFdLmR1cmF0aW9uOwoJCQl9IGVsc2UgewoJCQkJc2FtcGxlLmR0cyA9IDA7CgkJCX0KCQkJaWYgKGN0dHMpIHsKCQkJCWlmIChqID49IGxhc3Rfc2FtcGxlX2luX2N0dHNfcnVuKSB7CgkJCQkJY3R0c19ydW5faW5kZXgrKzsKCQkJCQlpZiAobGFzdF9zYW1wbGVfaW5fY3R0c19ydW4gPCAwKSB7CgkJCQkJCWxhc3Rfc2FtcGxlX2luX2N0dHNfcnVuID0gMDsKCQkJCQl9CgkJCQkJbGFzdF9zYW1wbGVfaW5fY3R0c19ydW4gKz0gY3R0cy5zYW1wbGVfY291bnRzW2N0dHNfcnVuX2luZGV4XTsJCQkJCgkJCQl9CgkJCQlzYW1wbGUuY3RzID0gdHJhay5zYW1wbGVzW2pdLmR0cyArIGN0dHMuc2FtcGxlX29mZnNldHNbY3R0c19ydW5faW5kZXhdOwoJCQl9IGVsc2UgewoJCQkJc2FtcGxlLmN0cyA9IHNhbXBsZS5kdHM7CgkJCX0KCQkJaWYgKHN0c3MpIHsKCQkJCWlmIChqID09IHN0c3Muc2FtcGxlX251bWJlcnNbbGFzdF9zdHNzX2luZGV4XSAtIDEpIHsgLy8gc2FtcGxlIG51bWJlcnMgYXJlIDEtYmFzZWQKCQkJCQlzYW1wbGUuaXNfc3luYyA9IHRydWU7CgkJCQkJbGFzdF9zdHNzX2luZGV4Kys7CgkJCQl9IGVsc2UgewoJCQkJCXNhbXBsZS5pc19zeW5jID0gZmFsc2U7CQkJCQoJCQkJCXNhbXBsZS5kZWdyYWRhdGlvbl9wcmlvcml0eSA9IDA7CgkJCQl9CgkJCQlpZiAoc3VicykgewoJCQkJCWlmIChzdWJzLmVudHJpZXNbc3Vic19lbnRyeV9pbmRleF0uc2FtcGxlX2RlbHRhICsgbGFzdF9zdWJzX3NhbXBsZV9pbmRleCA9PSBqKzEpIHsKCQkJCQkJc2FtcGxlLnN1YnNhbXBsZXMgPSBzdWJzLmVudHJpZXNbc3Vic19lbnRyeV9pbmRleF0uc3Vic2FtcGxlczsKCQkJCQkJbGFzdF9zdWJzX3NhbXBsZV9pbmRleCArPSBzdWJzLmVudHJpZXNbc3Vic19lbnRyeV9pbmRleF0uc2FtcGxlX2RlbHRhOwoJCQkJCQlzdWJzX2VudHJ5X2luZGV4Kys7CgkJCQkJfQoJCQkJfQoJCQl9IGVsc2UgewoJCQkJc2FtcGxlLmlzX3N5bmMgPSB0cnVlOwoJCQl9CgkJCUlTT0ZpbGUucHJvY2Vzc19zZHRwKHRyYWsubWRpYS5taW5mLnN0Ymwuc2R0cCwgc2FtcGxlLCBzYW1wbGUubnVtYmVyKTsKCQkJaWYgKHN0ZHApIHsKCQkJCXNhbXBsZS5kZWdyYWRhdGlvbl9wcmlvcml0eSA9IHN0ZHAucHJpb3JpdHlbal07CgkJCX0gZWxzZSB7CgkJCQlzYW1wbGUuZGVncmFkYXRpb25fcHJpb3JpdHkgPSAwOwoJCQl9CgkJCWlmIChzdWJzKSB7CgkJCQlpZiAoc3Vicy5lbnRyaWVzW3N1YnNfZW50cnlfaW5kZXhdLnNhbXBsZV9kZWx0YSArIGxhc3Rfc3Vic19zYW1wbGVfaW5kZXggPT0gaikgewoJCQkJCXNhbXBsZS5zdWJzYW1wbGVzID0gc3Vicy5lbnRyaWVzW3N1YnNfZW50cnlfaW5kZXhdLnN1YnNhbXBsZXM7CgkJCQkJbGFzdF9zdWJzX3NhbXBsZV9pbmRleCArPSBzdWJzLmVudHJpZXNbc3Vic19lbnRyeV9pbmRleF0uc2FtcGxlX2RlbHRhOwoJCQkJfQoJCQl9CgkJCWlmIChzYmdwcy5sZW5ndGggPiAwIHx8IHNncGRzLmxlbmd0aCA+IDApIHsKCQkJCUlTT0ZpbGUuc2V0U2FtcGxlR3JvdXBQcm9wZXJ0aWVzKHRyYWssIHNhbXBsZSwgaiwgdHJhay5zYW1wbGVfZ3JvdXBzX2luZm8pOwoJCQl9CgkJfQoJCWlmIChqPjApIHsKCQkJdHJhay5zYW1wbGVzW2otMV0uZHVyYXRpb24gPSBNYXRoLm1heCh0cmFrLm1kaWEubWRoZC5kdXJhdGlvbiAtIHRyYWsuc2FtcGxlc1tqLTFdLmR0cywgMCk7CgkJCXRyYWsuc2FtcGxlc19kdXJhdGlvbiArPSB0cmFrLnNhbXBsZXNbai0xXS5kdXJhdGlvbjsKCQl9Cgl9OwoKCS8qIFVwZGF0ZSBzYW1wbGUgbGlzdCB3aGVuIG5ldyAnbW9vZicgYm94ZXMgYXJlIHJlY2VpdmVkICovCglJU09GaWxlLnByb3RvdHlwZS51cGRhdGVTYW1wbGVMaXN0cyA9IGZ1bmN0aW9uKCkgewkKCQl2YXIgaSwgaiwgazsKCQl2YXIgZGVmYXVsdF9zYW1wbGVfZGVzY3JpcHRpb25faW5kZXgsIGRlZmF1bHRfc2FtcGxlX2R1cmF0aW9uLCBkZWZhdWx0X3NhbXBsZV9zaXplLCBkZWZhdWx0X3NhbXBsZV9mbGFnczsKCQl2YXIgbGFzdF9ydW5fcG9zaXRpb247CgkJdmFyIGJveCwgbW9vZiwgdHJhZiwgdHJhaywgdHJleDsKCQl2YXIgc2FtcGxlOwoJCXZhciBzYW1wbGVfZmxhZ3M7CgkJCgkJaWYgKHRoaXMubW9vdiA9PT0gdW5kZWZpbmVkKSB7CgkJCXJldHVybjsKCQl9CgkJLyogaWYgdGhlIGlucHV0IGZpbGUgaXMgZnJhZ21lbnRlZCBhbmQgZmV0Y2hlZCBpbiBtdWx0aXBsZSBkb3dubG9hZHMsIHdlIG5lZWQgdG8gdXBkYXRlIHRoZSBsaXN0IG9mIHNhbXBsZXMgKi8KCQl3aGlsZSAodGhpcy5sYXN0TW9vZkluZGV4IDwgdGhpcy5tb29mcy5sZW5ndGgpIHsKCQkJYm94ID0gdGhpcy5tb29mc1t0aGlzLmxhc3RNb29mSW5kZXhdOwoJCQl0aGlzLmxhc3RNb29mSW5kZXgrKzsKCQkJaWYgKGJveC50eXBlID09ICJtb29mIikgewoJCQkJbW9vZiA9IGJveDsKCQkJCWZvciAoaSA9IDA7IGkgPCBtb29mLnRyYWZzLmxlbmd0aDsgaSsrKSB7CgkJCQkJdHJhZiA9IG1vb2YudHJhZnNbaV07CgkJCQkJdHJhayA9IHRoaXMuZ2V0VHJhY2tCeUlkKHRyYWYudGZoZC50cmFja19pZCk7CgkJCQkJdHJleCA9IHRoaXMuZ2V0VHJleEJ5SWQodHJhZi50ZmhkLnRyYWNrX2lkKTsKCQkJCQlpZiAodHJhZi50ZmhkLmZsYWdzICYgQm94UGFyc2VyLlRGSERfRkxBR19TQU1QTEVfREVTQykgewoJCQkJCQlkZWZhdWx0X3NhbXBsZV9kZXNjcmlwdGlvbl9pbmRleCA9IHRyYWYudGZoZC5kZWZhdWx0X3NhbXBsZV9kZXNjcmlwdGlvbl9pbmRleDsKCQkJCQl9IGVsc2UgewoJCQkJCQlkZWZhdWx0X3NhbXBsZV9kZXNjcmlwdGlvbl9pbmRleCA9ICh0cmV4ID8gdHJleC5kZWZhdWx0X3NhbXBsZV9kZXNjcmlwdGlvbl9pbmRleDogMSk7CgkJCQkJfQoJCQkJCWlmICh0cmFmLnRmaGQuZmxhZ3MgJiBCb3hQYXJzZXIuVEZIRF9GTEFHX1NBTVBMRV9EVVIpIHsKCQkJCQkJZGVmYXVsdF9zYW1wbGVfZHVyYXRpb24gPSB0cmFmLnRmaGQuZGVmYXVsdF9zYW1wbGVfZHVyYXRpb247CgkJCQkJfSBlbHNlIHsKCQkJCQkJZGVmYXVsdF9zYW1wbGVfZHVyYXRpb24gPSAodHJleCA/IHRyZXguZGVmYXVsdF9zYW1wbGVfZHVyYXRpb24gOiAwKTsKCQkJCQl9CgkJCQkJaWYgKHRyYWYudGZoZC5mbGFncyAmIEJveFBhcnNlci5URkhEX0ZMQUdfU0FNUExFX1NJWkUpIHsKCQkJCQkJZGVmYXVsdF9zYW1wbGVfc2l6ZSA9IHRyYWYudGZoZC5kZWZhdWx0X3NhbXBsZV9zaXplOwoJCQkJCX0gZWxzZSB7CgkJCQkJCWRlZmF1bHRfc2FtcGxlX3NpemUgPSAodHJleCA/IHRyZXguZGVmYXVsdF9zYW1wbGVfc2l6ZSA6IDApOwoJCQkJCX0KCQkJCQlpZiAodHJhZi50ZmhkLmZsYWdzICYgQm94UGFyc2VyLlRGSERfRkxBR19TQU1QTEVfRkxBR1MpIHsKCQkJCQkJZGVmYXVsdF9zYW1wbGVfZmxhZ3MgPSB0cmFmLnRmaGQuZGVmYXVsdF9zYW1wbGVfZmxhZ3M7CgkJCQkJfSBlbHNlIHsKCQkJCQkJZGVmYXVsdF9zYW1wbGVfZmxhZ3MgPSAodHJleCA/IHRyZXguZGVmYXVsdF9zYW1wbGVfZmxhZ3MgOiAwKTsKCQkJCQl9CgkJCQkJdHJhZi5zYW1wbGVfbnVtYmVyID0gMDsKCQkJCQkvKiBwcm9jZXNzIHNhbXBsZSBncm91cHMgKi8KCQkJCQlpZiAodHJhZi5zYmdwcy5sZW5ndGggPiAwKSB7CgkJCQkJCUlTT0ZpbGUuaW5pdFNhbXBsZUdyb3Vwcyh0cmFrLCB0cmFmLCB0cmFmLnNiZ3BzLCB0cmFrLm1kaWEubWluZi5zdGJsLnNncGRzLCB0cmFmLnNncGRzKTsKCQkJCQl9CgkJCQkJZm9yIChqID0gMDsgaiA8IHRyYWYudHJ1bnMubGVuZ3RoOyBqKyspIHsKCQkJCQkJdmFyIHRydW4gPSB0cmFmLnRydW5zW2pdOwoJCQkJCQlmb3IgKGsgPSAwOyBrIDwgdHJ1bi5zYW1wbGVfY291bnQ7IGsrKykgewoJCQkJCQkJc2FtcGxlID0ge307CgkJCQkJCQlzYW1wbGUubW9vZl9udW1iZXIgPSB0aGlzLmxhc3RNb29mSW5kZXg7CgkJCQkJCQlzYW1wbGUubnVtYmVyX2luX3RyYWYgPSB0cmFmLnNhbXBsZV9udW1iZXI7CgkJCQkJCQl0cmFmLnNhbXBsZV9udW1iZXIrKzsKCQkJCSAgICAgICAgICAgIHNhbXBsZS5udW1iZXIgPSB0cmFrLnNhbXBsZXMubGVuZ3RoOwoJCQkJCQkJdHJhZi5maXJzdF9zYW1wbGVfaW5kZXggPSB0cmFrLnNhbXBsZXMubGVuZ3RoOwoJCQkJCQkJdHJhay5zYW1wbGVzLnB1c2goc2FtcGxlKTsKCQkJCQkJCXNhbXBsZS50cmFja19pZCA9IHRyYWsudGtoZC50cmFja19pZDsKCQkJCQkJCXNhbXBsZS50aW1lc2NhbGUgPSB0cmFrLm1kaWEubWRoZC50aW1lc2NhbGU7CgkJCQkJCQlzYW1wbGUuZGVzY3JpcHRpb25faW5kZXggPSBkZWZhdWx0X3NhbXBsZV9kZXNjcmlwdGlvbl9pbmRleC0xOwoJCQkJCQkJc2FtcGxlLmRlc2NyaXB0aW9uID0gdHJhay5tZGlhLm1pbmYuc3RibC5zdHNkLmVudHJpZXNbc2FtcGxlLmRlc2NyaXB0aW9uX2luZGV4XTsKCQkJCQkJCXNhbXBsZS5zaXplID0gZGVmYXVsdF9zYW1wbGVfc2l6ZTsKCQkJCQkJCWlmICh0cnVuLmZsYWdzICYgQm94UGFyc2VyLlRSVU5fRkxBR1NfU0laRSkgewoJCQkJCQkJCXNhbXBsZS5zaXplID0gdHJ1bi5zYW1wbGVfc2l6ZVtrXTsKCQkJCQkJCX0KCQkJCQkJCXRyYWsuc2FtcGxlc19zaXplICs9IHNhbXBsZS5zaXplOwoJCQkJCQkJc2FtcGxlLmR1cmF0aW9uID0gZGVmYXVsdF9zYW1wbGVfZHVyYXRpb247CgkJCQkJCQlpZiAodHJ1bi5mbGFncyAmIEJveFBhcnNlci5UUlVOX0ZMQUdTX0RVUkFUSU9OKSB7CgkJCQkJCQkJc2FtcGxlLmR1cmF0aW9uID0gdHJ1bi5zYW1wbGVfZHVyYXRpb25ba107CgkJCQkJCQl9CgkJCQkJCQl0cmFrLnNhbXBsZXNfZHVyYXRpb24gKz0gc2FtcGxlLmR1cmF0aW9uOwoJCQkJCQkJaWYgKHRyYWsuZmlyc3RfdHJhZl9tZXJnZWQgfHwgayA+IDApIHsKCQkJCQkJCQlzYW1wbGUuZHRzID0gdHJhay5zYW1wbGVzW3RyYWsuc2FtcGxlcy5sZW5ndGgtMl0uZHRzK3RyYWsuc2FtcGxlc1t0cmFrLnNhbXBsZXMubGVuZ3RoLTJdLmR1cmF0aW9uOwoJCQkJCQkJfSBlbHNlIHsKCQkJCQkJCQlpZiAodHJhZi50ZmR0KSB7CgkJCQkJCQkJCXNhbXBsZS5kdHMgPSB0cmFmLnRmZHQuYmFzZU1lZGlhRGVjb2RlVGltZTsKCQkJCQkJCQl9IGVsc2UgewoJCQkJCQkJCQlzYW1wbGUuZHRzID0gMDsKCQkJCQkJCQl9CgkJCQkJCQkJdHJhay5maXJzdF90cmFmX21lcmdlZCA9IHRydWU7CgkJCQkJCQl9CgkJCQkJCQlzYW1wbGUuY3RzID0gc2FtcGxlLmR0czsKCQkJCQkJCWlmICh0cnVuLmZsYWdzICYgQm94UGFyc2VyLlRSVU5fRkxBR1NfQ1RTX09GRlNFVCkgewoJCQkJCQkJCXNhbXBsZS5jdHMgPSBzYW1wbGUuZHRzICsgdHJ1bi5zYW1wbGVfY29tcG9zaXRpb25fdGltZV9vZmZzZXRba107CgkJCQkJCQl9CgkJCQkJCQlzYW1wbGVfZmxhZ3MgPSBkZWZhdWx0X3NhbXBsZV9mbGFnczsKCQkJCQkJCWlmICh0cnVuLmZsYWdzICYgQm94UGFyc2VyLlRSVU5fRkxBR1NfRkxBR1MpIHsKCQkJCQkJCQlzYW1wbGVfZmxhZ3MgPSB0cnVuLnNhbXBsZV9mbGFnc1trXTsKCQkJCQkJCX0gZWxzZSBpZiAoayA9PT0gMCAmJiAodHJ1bi5mbGFncyAmIEJveFBhcnNlci5UUlVOX0ZMQUdTX0ZJUlNUX0ZMQUcpKSB7CgkJCQkJCQkJc2FtcGxlX2ZsYWdzID0gdHJ1bi5maXJzdF9zYW1wbGVfZmxhZ3M7CgkJCQkJCQl9CgkJCQkJCQlzYW1wbGUuaXNfc3luYyA9ICgoc2FtcGxlX2ZsYWdzID4+IDE2ICYgMHgxKSA/IGZhbHNlIDogdHJ1ZSk7CgkJCQkJCQlzYW1wbGUuaXNfbGVhZGluZyA9IChzYW1wbGVfZmxhZ3MgPj4gMjYgJiAweDMpOwoJCQkJCQkJc2FtcGxlLmRlcGVuZHNfb24gPSAoc2FtcGxlX2ZsYWdzID4+IDI0ICYgMHgzKTsKCQkJCQkJCXNhbXBsZS5pc19kZXBlbmRlZF9vbiA9IChzYW1wbGVfZmxhZ3MgPj4gMjIgJiAweDMpOwoJCQkJCQkJc2FtcGxlLmhhc19yZWR1bmRhbmN5ID0gKHNhbXBsZV9mbGFncyA+PiAyMCAmIDB4Myk7CgkJCQkJCQlzYW1wbGUuZGVncmFkYXRpb25fcHJpb3JpdHkgPSAoc2FtcGxlX2ZsYWdzICYgMHhGRkZGKTsKCQkJCQkJCS8vSVNPRmlsZS5wcm9jZXNzX3NkdHAodHJhZi5zZHRwLCBzYW1wbGUsIHNhbXBsZS5udW1iZXJfaW5fdHJhZik7CgkJCQkJCQl2YXIgYmRvcCA9ICh0cmFmLnRmaGQuZmxhZ3MgJiBCb3hQYXJzZXIuVEZIRF9GTEFHX0JBU0VfREFUQV9PRkZTRVQpID8gdHJ1ZSA6IGZhbHNlOwoJCQkJCQkJdmFyIGRiaW0gPSAodHJhZi50ZmhkLmZsYWdzICYgQm94UGFyc2VyLlRGSERfRkxBR19ERUZBVUxUX0JBU0VfSVNfTU9PRikgPyB0cnVlIDogZmFsc2U7CgkJCQkJCQl2YXIgZG9wID0gKHRydW4uZmxhZ3MgJiBCb3hQYXJzZXIuVFJVTl9GTEFHU19EQVRBX09GRlNFVCkgPyB0cnVlIDogZmFsc2U7CgkJCQkJCQl2YXIgYmRvID0gMDsKCQkJCQkJCWlmICghYmRvcCkgewoJCQkJCQkJCWlmICghZGJpbSkgewoJCQkJCQkJCQlpZiAoaiA9PT0gMCkgeyAvLyB0aGUgZmlyc3QgdHJhY2sgaW4gdGhlIG1vdmllIGZyYWdtZW50CgkJCQkJCQkJCQliZG8gPSBtb29mLnN0YXJ0OyAvLyB0aGUgcG9zaXRpb24gb2YgdGhlIGZpcnN0IGJ5dGUgb2YgdGhlIGVuY2xvc2luZyBNb3ZpZSBGcmFnbWVudCBCb3gKCQkJCQkJCQkJfSBlbHNlIHsKCQkJCQkJCQkJCWJkbyA9IGxhc3RfcnVuX3Bvc2l0aW9uOyAvLyBlbmQgb2YgdGhlIGRhdGEgZGVmaW5lZCBieSB0aGUgcHJlY2VkaW5nICp0cmFjayogKGlycmVzcGVjdGl2ZSBvZiB0aGUgdHJhY2sgaWQpIGZyYWdtZW50IGluIHRoZSBtb29mCgkJCQkJCQkJCX0KCQkJCQkJCQl9IGVsc2UgewoJCQkJCQkJCQliZG8gPSBtb29mLnN0YXJ0OwoJCQkJCQkJCX0KCQkJCQkJCX0gZWxzZSB7CgkJCQkJCQkJYmRvID0gdHJhZi50ZmhkLmJhc2VfZGF0YV9vZmZzZXQ7CgkJCQkJCQl9CgkJCQkJCQlpZiAoaiA9PT0gMCAmJiBrID09PSAwKSB7CgkJCQkJCQkJaWYgKGRvcCkgewoJCQkJCQkJCQlzYW1wbGUub2Zmc2V0ID0gYmRvICsgdHJ1bi5kYXRhX29mZnNldDsgLy8gSWYgdGhlIGRhdGEtb2Zmc2V0IGlzIHByZXNlbnQsIGl0IGlzIHJlbGF0aXZlIHRvIHRoZSBiYXNlLWRhdGEtb2Zmc2V0IGVzdGFibGlzaGVkIGluIHRoZSB0cmFjayBmcmFnbWVudCBoZWFkZXIKCQkJCQkJCQl9IGVsc2UgewoJCQkJCQkJCQlzYW1wbGUub2Zmc2V0ID0gYmRvOyAvLyB0aGUgZGF0YSBmb3IgdGhpcyBydW4gc3RhcnRzIHRoZSBiYXNlLWRhdGEtb2Zmc2V0IGRlZmluZWQgYnkgdGhlIHRyYWNrIGZyYWdtZW50IGhlYWRlcgoJCQkJCQkJCX0KCQkJCQkJCX0gZWxzZSB7CgkJCQkJCQkJc2FtcGxlLm9mZnNldCA9IGxhc3RfcnVuX3Bvc2l0aW9uOyAvLyB0aGlzIHJ1biBzdGFydHMgaW1tZWRpYXRlbHkgYWZ0ZXIgdGhlIGRhdGEgb2YgdGhlIHByZXZpb3VzIHJ1bgoJCQkJCQkJfQoJCQkJCQkJbGFzdF9ydW5fcG9zaXRpb24gPSBzYW1wbGUub2Zmc2V0ICsgc2FtcGxlLnNpemU7CgkJCQkJCQlpZiAodHJhZi5zYmdwcy5sZW5ndGggPiAwIHx8IHRyYWYuc2dwZHMubGVuZ3RoID4gMCB8fAoJCQkJCQkJCXRyYWsubWRpYS5taW5mLnN0Ymwuc2JncHMubGVuZ3RoID4gMCB8fCB0cmFrLm1kaWEubWluZi5zdGJsLnNncGRzLmxlbmd0aCA+IDApIHsKCQkJCQkJCQlJU09GaWxlLnNldFNhbXBsZUdyb3VwUHJvcGVydGllcyh0cmFrLCBzYW1wbGUsIHNhbXBsZS5udW1iZXJfaW5fdHJhZiwgdHJhZi5zYW1wbGVfZ3JvdXBzX2luZm8pOwoJCQkJCQkJfQoJCQkJCQl9CgkJCQkJfQoJCQkJCWlmICh0cmFmLnN1YnMpIHsKCQkJCQkJdHJhay5oYXNfZnJhZ21lbnRfc3Vic2FtcGxlcyA9IHRydWU7CgkJCQkJCXZhciBzYW1wbGVfaW5kZXggPSB0cmFmLmZpcnN0X3NhbXBsZV9pbmRleDsKCQkJCQkJZm9yIChqID0gMDsgaiA8IHRyYWYuc3Vicy5lbnRyaWVzLmxlbmd0aDsgaisrKSB7CgkJCQkJCQlzYW1wbGVfaW5kZXggKz0gdHJhZi5zdWJzLmVudHJpZXNbal0uc2FtcGxlX2RlbHRhOwoJCQkJCQkJc2FtcGxlID0gdHJhay5zYW1wbGVzW3NhbXBsZV9pbmRleC0xXTsKCQkJCQkJCXNhbXBsZS5zdWJzYW1wbGVzID0gdHJhZi5zdWJzLmVudHJpZXNbal0uc3Vic2FtcGxlczsKCQkJCQkJfQkJCQkJCgkJCQkJfQoJCQkJfQoJCQl9CgkJfQkKCX07CgoJLyogVHJ5IHRvIGdldCBzYW1wbGUgZGF0YSBmb3IgYSBnaXZlbiBzYW1wbGU6CgkgICByZXR1cm5zIG51bGwgaWYgbm90IGZvdW5kCgkgICByZXR1cm5zIHRoZSBzYW1lIHNhbXBsZSBpZiBhbHJlYWR5IHJlcXVlc3RlZAoJICovCglJU09GaWxlLnByb3RvdHlwZS5nZXRTYW1wbGUgPSBmdW5jdGlvbih0cmFrLCBzYW1wbGVOdW0pIHsJCgkJdmFyIGJ1ZmZlcjsKCQl2YXIgc2FtcGxlID0gdHJhay5zYW1wbGVzW3NhbXBsZU51bV07CgkJCgkJaWYgKCF0aGlzLm1vb3YpIHsKCQkJcmV0dXJuIG51bGw7CgkJfQoKCQlpZiAoIXNhbXBsZS5kYXRhKSB7CgkJCS8qIE5vdCB5ZXQgZmV0Y2hlZCAqLwoJCQlzYW1wbGUuZGF0YSA9IG5ldyBVaW50OEFycmF5KHNhbXBsZS5zaXplKTsKCQkJc2FtcGxlLmFscmVhZHlSZWFkID0gMDsKCQkJdGhpcy5zYW1wbGVzRGF0YVNpemUgKz0gc2FtcGxlLnNpemU7CgkJCUxvZy5kZWJ1ZygiSVNPRmlsZSIsICJBbGxvY2F0aW5nIHNhbXBsZSAjIitzYW1wbGVOdW0rIiBvbiB0cmFjayAjIit0cmFrLnRraGQudHJhY2tfaWQrIiBvZiBzaXplICIrc2FtcGxlLnNpemUrIiAodG90YWw6ICIrdGhpcy5zYW1wbGVzRGF0YVNpemUrIikiKTsKCQl9IGVsc2UgaWYgKHNhbXBsZS5hbHJlYWR5UmVhZCA9PSBzYW1wbGUuc2l6ZSkgewoJCQkvKiBBbHJlYWR5IGZldGNoZWQgZW50aXJlbHkgKi8KCQkJcmV0dXJuIHNhbXBsZTsKCQl9CgoJCS8qIFRoZSBzYW1wbGUgaGFzIG9ubHkgYmVlbiBwYXJ0aWFsbHkgZmV0Y2hlZCwgd2UgbmVlZCB0byBjaGVjayBpbiBhbGwgYnVmZmVycyAqLwoJCXdoaWxlKHRydWUpIHsKCQkJdmFyIGluZGV4ID0JdGhpcy5zdHJlYW0uZmluZFBvc2l0aW9uKHRydWUsIHNhbXBsZS5vZmZzZXQgKyBzYW1wbGUuYWxyZWFkeVJlYWQsIGZhbHNlKTsKCQkJaWYgKGluZGV4ID4gLTEpIHsKCQkJCWJ1ZmZlciA9IHRoaXMuc3RyZWFtLmJ1ZmZlcnNbaW5kZXhdOwoJCQkJdmFyIGxlbmd0aEFmdGVyU3RhcnQgPSBidWZmZXIuYnl0ZUxlbmd0aCAtIChzYW1wbGUub2Zmc2V0ICsgc2FtcGxlLmFscmVhZHlSZWFkIC0gYnVmZmVyLmZpbGVTdGFydCk7CgkJCQlpZiAoc2FtcGxlLnNpemUgLSBzYW1wbGUuYWxyZWFkeVJlYWQgPD0gbGVuZ3RoQWZ0ZXJTdGFydCkgewoJCQkJCS8qIHRoZSAocmVzdCBvZiB0aGUpIHNhbXBsZSBpcyBlbnRpcmVseSBjb250YWluZWQgaW4gdGhpcyBidWZmZXIgKi8KCgkJCQkJTG9nLmRlYnVnKCJJU09GaWxlIiwiR2V0dGluZyBzYW1wbGUgIyIrc2FtcGxlTnVtKyIgZGF0YSAoYWxyZWFkeVJlYWQ6ICIrc2FtcGxlLmFscmVhZHlSZWFkKyIgb2Zmc2V0OiAiKwoJCQkJCQkoc2FtcGxlLm9mZnNldCtzYW1wbGUuYWxyZWFkeVJlYWQgLSBidWZmZXIuZmlsZVN0YXJ0KSsiIHJlYWQgc2l6ZTogIisoc2FtcGxlLnNpemUgLSBzYW1wbGUuYWxyZWFkeVJlYWQpKyIgZnVsbCBzaXplOiAiK3NhbXBsZS5zaXplKyIpIik7CgoJCQkJCURhdGFTdHJlYW0ubWVtY3B5KHNhbXBsZS5kYXRhLmJ1ZmZlciwgc2FtcGxlLmFscmVhZHlSZWFkLAoJCQkJCSAgICAgICAgICAgICAgICAgIGJ1ZmZlciwgc2FtcGxlLm9mZnNldCtzYW1wbGUuYWxyZWFkeVJlYWQgLSBidWZmZXIuZmlsZVN0YXJ0LCBzYW1wbGUuc2l6ZSAtIHNhbXBsZS5hbHJlYWR5UmVhZCk7CgoJCQkJCS8qIHVwZGF0ZSB0aGUgbnVtYmVyIG9mIGJ5dGVzIHVzZWQgaW4gdGhpcyBidWZmZXIgYW5kIGNoZWNrIGlmIGl0IG5lZWRzIHRvIGJlIHJlbW92ZWQgKi8KCQkJCQlidWZmZXIudXNlZEJ5dGVzICs9IHNhbXBsZS5zaXplIC0gc2FtcGxlLmFscmVhZHlSZWFkOwoJCQkJCXRoaXMuc3RyZWFtLmxvZ0J1ZmZlckxldmVsKCk7CgoJCQkJCXNhbXBsZS5hbHJlYWR5UmVhZCA9IHNhbXBsZS5zaXplOwoKCQkJCQlyZXR1cm4gc2FtcGxlOwoJCQkJfSBlbHNlIHsKCQkJCQkvKiB0aGUgc2FtcGxlIGRvZXMgbm90IGVuZCBpbiB0aGlzIGJ1ZmZlciAqLwoKCQkJCQlpZiAobGVuZ3RoQWZ0ZXJTdGFydCA9PT0gMCkgcmV0dXJuIG51bGw7CgoJCQkJCUxvZy5kZWJ1ZygiSVNPRmlsZSIsIkdldHRpbmcgc2FtcGxlICMiK3NhbXBsZU51bSsiIHBhcnRpYWwgZGF0YSAoYWxyZWFkeVJlYWQ6ICIrc2FtcGxlLmFscmVhZHlSZWFkKyIgb2Zmc2V0OiAiKwoJCQkJCQkoc2FtcGxlLm9mZnNldCtzYW1wbGUuYWxyZWFkeVJlYWQgLSBidWZmZXIuZmlsZVN0YXJ0KSsiIHJlYWQgc2l6ZTogIitsZW5ndGhBZnRlclN0YXJ0KyIgZnVsbCBzaXplOiAiK3NhbXBsZS5zaXplKyIpIik7CgoJCQkJCURhdGFTdHJlYW0ubWVtY3B5KHNhbXBsZS5kYXRhLmJ1ZmZlciwgc2FtcGxlLmFscmVhZHlSZWFkLAoJCQkJCSAgICAgICAgICAgICAgICAgIGJ1ZmZlciwgc2FtcGxlLm9mZnNldCtzYW1wbGUuYWxyZWFkeVJlYWQgLSBidWZmZXIuZmlsZVN0YXJ0LCBsZW5ndGhBZnRlclN0YXJ0KTsKCQkJCQlzYW1wbGUuYWxyZWFkeVJlYWQgKz0gbGVuZ3RoQWZ0ZXJTdGFydDsKCgkJCQkJLyogdXBkYXRlIHRoZSBudW1iZXIgb2YgYnl0ZXMgdXNlZCBpbiB0aGlzIGJ1ZmZlciBhbmQgY2hlY2sgaWYgaXQgbmVlZHMgdG8gYmUgcmVtb3ZlZCAqLwoJCQkJCWJ1ZmZlci51c2VkQnl0ZXMgKz0gbGVuZ3RoQWZ0ZXJTdGFydDsKCQkJCQl0aGlzLnN0cmVhbS5sb2dCdWZmZXJMZXZlbCgpOwoKCQkJCQkvKiBrZWVwIGxvb2tpbmcgaW4gdGhlIG5leHQgYnVmZmVyICovCgkJCQl9CgkJCX0gZWxzZSB7CgkJCQlyZXR1cm4gbnVsbDsKCQkJfQoJCX0KCX07CgoJLyogUmVsZWFzZSB0aGUgbWVtb3J5IHVzZWQgdG8gc3RvcmUgdGhlIGRhdGEgb2YgdGhlIHNhbXBsZSAqLwoJSVNPRmlsZS5wcm90b3R5cGUucmVsZWFzZVNhbXBsZSA9IGZ1bmN0aW9uKHRyYWssIHNhbXBsZU51bSkgewkKCQl2YXIgc2FtcGxlID0gdHJhay5zYW1wbGVzW3NhbXBsZU51bV07CgkJaWYgKHNhbXBsZS5kYXRhKSB7CgkJCXRoaXMuc2FtcGxlc0RhdGFTaXplIC09IHNhbXBsZS5zaXplOwoJCQlzYW1wbGUuZGF0YSA9IG51bGw7CgkJCXNhbXBsZS5hbHJlYWR5UmVhZCA9IDA7CgkJCXJldHVybiBzYW1wbGUuc2l6ZTsKCQl9IGVsc2UgewoJCQlyZXR1cm4gMDsKCQl9Cgl9OwoKCUlTT0ZpbGUucHJvdG90eXBlLmdldEFsbG9jYXRlZFNhbXBsZURhdGFTaXplID0gZnVuY3Rpb24oKSB7CgkJcmV0dXJuIHRoaXMuc2FtcGxlc0RhdGFTaXplOwoJfTsKCgkvKiBCdWlsZHMgdGhlIE1JTUUgVHlwZSAnY29kZWNzJyBzdWItcGFyYW1ldGVycyBmb3IgdGhlIHdob2xlIGZpbGUgKi8KCUlTT0ZpbGUucHJvdG90eXBlLmdldENvZGVjcyA9IGZ1bmN0aW9uKCkgewkKCQl2YXIgaTsKCQl2YXIgY29kZWNzID0gIiI7CgkJZm9yIChpID0gMDsgaSA8IHRoaXMubW9vdi50cmFrcy5sZW5ndGg7IGkrKykgewoJCQl2YXIgdHJhayA9IHRoaXMubW9vdi50cmFrc1tpXTsKCQkJaWYgKGk+MCkgewoJCQkJY29kZWNzKz0iLCI7IAoJCQl9CgkJCWNvZGVjcyArPSB0cmFrLm1kaWEubWluZi5zdGJsLnN0c2QuZW50cmllc1swXS5nZXRDb2RlYygpOwkJCgkJfQoJCXJldHVybiBjb2RlY3M7Cgl9OwoKCS8qIEhlbHBlciBmdW5jdGlvbiAqLwoJSVNPRmlsZS5wcm90b3R5cGUuZ2V0VHJleEJ5SWQgPSBmdW5jdGlvbihpZCkgewkKCQl2YXIgaTsKCQlpZiAoIXRoaXMubW9vdiB8fCAhdGhpcy5tb292Lm12ZXgpIHJldHVybiBudWxsOwoJCWZvciAoaSA9IDA7IGkgPCB0aGlzLm1vb3YubXZleC50cmV4cy5sZW5ndGg7IGkrKykgewoJCQl2YXIgdHJleCA9IHRoaXMubW9vdi5tdmV4LnRyZXhzW2ldOwoJCQlpZiAodHJleC50cmFja19pZCA9PSBpZCkgcmV0dXJuIHRyZXg7CgkJfQoJCXJldHVybiBudWxsOwoJfTsKCgkvKiBIZWxwZXIgZnVuY3Rpb24gKi8KCUlTT0ZpbGUucHJvdG90eXBlLmdldFRyYWNrQnlJZCA9IGZ1bmN0aW9uKGlkKSB7CgkJaWYgKHRoaXMubW9vdiA9PT0gdW5kZWZpbmVkKSB7CgkJCXJldHVybiBudWxsOwoJCX0KCQlmb3IgKHZhciBqID0gMDsgaiA8IHRoaXMubW9vdi50cmFrcy5sZW5ndGg7IGorKykgewoJCQl2YXIgdHJhayA9IHRoaXMubW9vdi50cmFrc1tqXTsKCQkJaWYgKHRyYWsudGtoZC50cmFja19pZCA9PSBpZCkgcmV0dXJuIHRyYWs7CgkJfQoJCXJldHVybiBudWxsOwoJfTsKCS8vIGZpbGU6c3JjL2lzb2ZpbGUtaXRlbS1wcm9jZXNzaW5nLmpzCglJU09GaWxlLnByb3RvdHlwZS5pdGVtcyA9IFtdOwoJLyogc2l6ZSBvZiB0aGUgYnVmZmVycyBhbGxvY2F0ZWQgZm9yIHNhbXBsZXMgKi8KCUlTT0ZpbGUucHJvdG90eXBlLml0ZW1zRGF0YVNpemUgPSAwOwoKCUlTT0ZpbGUucHJvdG90eXBlLmZsYXR0ZW5JdGVtSW5mbyA9IGZ1bmN0aW9uKCkgewkKCQl2YXIgaXRlbXMgPSB0aGlzLml0ZW1zOwoJCXZhciBpLCBqOwoJCXZhciBpdGVtOwoJCXZhciBtZXRhID0gdGhpcy5tZXRhOwoJCWlmIChtZXRhID09PSBudWxsIHx8IG1ldGEgPT09IHVuZGVmaW5lZCkgcmV0dXJuOwoJCWlmIChtZXRhLmhkbHIgPT09IHVuZGVmaW5lZCkgcmV0dXJuOwoJCWlmIChtZXRhLmlpbmYgPT09IHVuZGVmaW5lZCkgcmV0dXJuOwoJCWZvciAoaSA9IDA7IGkgPCBtZXRhLmlpbmYuaXRlbV9pbmZvcy5sZW5ndGg7IGkrKykgewoJCQlpdGVtID0ge307CgkJCWl0ZW0uaWQgPSBtZXRhLmlpbmYuaXRlbV9pbmZvc1tpXS5pdGVtX0lEOwoJCQlpdGVtc1tpdGVtLmlkXSA9IGl0ZW07CgkJCWl0ZW0ucmVmX3RvID0gW107CgkJCWl0ZW0ubmFtZSA9IG1ldGEuaWluZi5pdGVtX2luZm9zW2ldLml0ZW1fbmFtZTsKCQkJaWYgKG1ldGEuaWluZi5pdGVtX2luZm9zW2ldLnByb3RlY3Rpb25faW5kZXggPiAwKSB7CgkJCQlpdGVtLnByb3RlY3Rpb24gPSBtZXRhLmlwcm8ucHJvdGVjdGlvbnNbbWV0YS5paW5mLml0ZW1faW5mb3NbaV0ucHJvdGVjdGlvbl9pbmRleC0xXTsKCQkJfQoJCQlpZiAobWV0YS5paW5mLml0ZW1faW5mb3NbaV0uaXRlbV90eXBlKSB7CgkJCQlpdGVtLnR5cGUgPSBtZXRhLmlpbmYuaXRlbV9pbmZvc1tpXS5pdGVtX3R5cGU7CgkJCX0gZWxzZSB7CgkJCQlpdGVtLnR5cGUgPSAibWltZSI7CgkJCX0KCQkJaXRlbS5jb250ZW50X3R5cGUgPSBtZXRhLmlpbmYuaXRlbV9pbmZvc1tpXS5jb250ZW50X3R5cGU7CgkJCWl0ZW0uY29udGVudF9lbmNvZGluZyA9IG1ldGEuaWluZi5pdGVtX2luZm9zW2ldLmNvbnRlbnRfZW5jb2Rpbmc7CgkJfQoJCWlmIChtZXRhLmlsb2MpIHsKCQkJZm9yKGkgPSAwOyBpIDwgbWV0YS5pbG9jLml0ZW1zLmxlbmd0aDsgaSsrKSB7CgkJCQl2YXIgaXRlbWxvYyA9IG1ldGEuaWxvYy5pdGVtc1tpXTsKCQkJCWl0ZW0gPSBpdGVtc1tpdGVtbG9jLml0ZW1fSURdOwoJCQkJaWYgKGl0ZW1sb2MuZGF0YV9yZWZlcmVuY2VfaW5kZXggIT09IDApIHsKCQkJCQlMb2cud2FybigiSXRlbSBzdG9yYWdlIHdpdGggcmVmZXJlbmNlIHRvIG90aGVyIGZpbGVzOiBub3Qgc3VwcG9ydGVkIik7CgkJCQkJaXRlbS5zb3VyY2UgPSBtZXRhLmRpbmYuYm94ZXNbaXRlbWxvYy5kYXRhX3JlZmVyZW5jZV9pbmRleC0xXTsKCQkJCX0KCQkJCXN3aXRjaChpdGVtbG9jLmNvbnN0cnVjdGlvbl9tZXRob2QpIHsKCQkJCQljYXNlIDA6IC8vIG9mZnNldCBpbnRvIHRoZSBmaWxlIHJlZmVyZW5jZWQgYnkgdGhlIGRhdGEgcmVmZXJlbmNlIGluZGV4CgkJCQkJYnJlYWs7CgkJCQkJY2FzZSAxOiAvLyBvZmZzZXQgaW50byB0aGUgaWRhdCBib3ggb2YgdGhpcyBtZXRhIGJveAoJCQkJCUxvZy53YXJuKCJJdGVtIHN0b3JhZ2Ugd2l0aCBjb25zdHJ1Y3Rpb25fbWV0aG9kIDogbm90IHN1cHBvcnRlZCIpOwoJCQkJCWJyZWFrOwoJCQkJCWNhc2UgMjogLy8gb2Zmc2V0IGludG8gYW5vdGhlciBpdGVtCgkJCQkJTG9nLndhcm4oIkl0ZW0gc3RvcmFnZSB3aXRoIGNvbnN0cnVjdGlvbl9tZXRob2QgOiBub3Qgc3VwcG9ydGVkIik7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCQlpdGVtLmV4dGVudHMgPSBbXTsKCQkJCWl0ZW0uc2l6ZSA9IDA7CgkJCQlmb3IgKGogPSAwOyBqIDwgaXRlbWxvYy5leHRlbnRzLmxlbmd0aDsgaisrKSB7CgkJCQkJaXRlbS5leHRlbnRzW2pdID0ge307CgkJCQkJaXRlbS5leHRlbnRzW2pdLm9mZnNldCA9IGl0ZW1sb2MuZXh0ZW50c1tqXS5leHRlbnRfb2Zmc2V0ICsgaXRlbWxvYy5iYXNlX29mZnNldDsKCQkJCQlpdGVtLmV4dGVudHNbal0ubGVuZ3RoID0gaXRlbWxvYy5leHRlbnRzW2pdLmV4dGVudF9sZW5ndGg7CgkJCQkJaXRlbS5leHRlbnRzW2pdLmFscmVhZHlSZWFkID0gMDsKCQkJCQlpdGVtLnNpemUgKz0gaXRlbS5leHRlbnRzW2pdLmxlbmd0aDsKCQkJCX0KCQkJfQoJCX0KCQlpZiAobWV0YS5waXRtKSB7CgkJCWl0ZW1zW21ldGEucGl0bS5pdGVtX2lkXS5wcmltYXJ5ID0gdHJ1ZTsKCQl9CgkJaWYgKG1ldGEuaXJlZikgewoJCQlmb3IgKGk9MDsgaSA8bWV0YS5pcmVmLnJlZmVyZW5jZXMubGVuZ3RoOyBpKyspIHsKCQkJCXZhciByZWYgPSBtZXRhLmlyZWYucmVmZXJlbmNlc1tpXTsKCQkJCWZvciAoaj0wOyBqPHJlZi5yZWZlcmVuY2VzLmxlbmd0aDsgaisrKSB7CgkJCQkJaXRlbXNbcmVmLmZyb21faXRlbV9JRF0ucmVmX3RvLnB1c2goe3R5cGU6IHJlZi50eXBlLCBpZDogcmVmLnJlZmVyZW5jZXNbal19KTsKCQkJCX0KCQkJfQoJCX0KCQlpZiAobWV0YS5pcHJwKSB7CgkJCWZvciAodmFyIGsgPSAwOyBrIDwgbWV0YS5pcHJwLmlwbWFzLmxlbmd0aDsgaysrKSB7CgkJCQl2YXIgaXBtYSA9IG1ldGEuaXBycC5pcG1hc1trXTsKCQkJCWZvciAoaSA9IDA7IGkgPCBpcG1hLmFzc29jaWF0aW9ucy5sZW5ndGg7IGkrKykgewoJCQkJCXZhciBhc3NvY2lhdGlvbiA9IGlwbWEuYXNzb2NpYXRpb25zW2ldOwoJCQkJCWl0ZW0gPSBpdGVtc1thc3NvY2lhdGlvbi5pZF07CgkJCQkJaWYgKGl0ZW0ucHJvcGVydGllcyA9PT0gdW5kZWZpbmVkKSB7CgkJCQkJCWl0ZW0ucHJvcGVydGllcyA9IHt9OwoJCQkJCQlpdGVtLnByb3BlcnRpZXMuYm94ZXMgPSBbXTsKCQkJCQl9CgkJCQkJZm9yIChqID0gMDsgaiA8IGFzc29jaWF0aW9uLnByb3BzLmxlbmd0aDsgaisrKSB7CgkJCQkJCXZhciBwcm9wRW50cnkgPSBhc3NvY2lhdGlvbi5wcm9wc1tqXTsKCQkJCQkJaWYgKHByb3BFbnRyeS5wcm9wZXJ0eV9pbmRleCA+IDAgJiYgcHJvcEVudHJ5LnByb3BlcnR5X2luZGV4LTEgPCBtZXRhLmlwcnAuaXBjby5ib3hlcy5sZW5ndGgpIHsKCQkJCQkJCXZhciBwcm9wYm94ID0gbWV0YS5pcHJwLmlwY28uYm94ZXNbcHJvcEVudHJ5LnByb3BlcnR5X2luZGV4LTFdOwoJCQkJCQkJaXRlbS5wcm9wZXJ0aWVzW3Byb3Bib3gudHlwZV0gPSBwcm9wYm94OwoJCQkJCQkJaXRlbS5wcm9wZXJ0aWVzLmJveGVzLnB1c2gocHJvcGJveCk7CgkJCQkJCX0KCQkJCQl9CgkJCQl9CgkJCX0KCQl9Cgl9OwoKCUlTT0ZpbGUucHJvdG90eXBlLmdldEl0ZW0gPSBmdW5jdGlvbihpdGVtX2lkKSB7CQoJCXZhciBidWZmZXI7CgkJdmFyIGl0ZW07CgkJCgkJaWYgKCF0aGlzLm1ldGEpIHsKCQkJcmV0dXJuIG51bGw7CgkJfQoKCSAJaXRlbSA9IHRoaXMuaXRlbXNbaXRlbV9pZF07CgkJaWYgKCFpdGVtLmRhdGEgJiYgaXRlbS5zaXplKSB7CgkJCS8qIE5vdCB5ZXQgZmV0Y2hlZCAqLwoJCQlpdGVtLmRhdGEgPSBuZXcgVWludDhBcnJheShpdGVtLnNpemUpOwoJCQlpdGVtLmFscmVhZHlSZWFkID0gMDsKCQkJdGhpcy5pdGVtc0RhdGFTaXplICs9IGl0ZW0uc2l6ZTsKCQkJTG9nLmRlYnVnKCJJU09GaWxlIiwgIkFsbG9jYXRpbmcgaXRlbSAjIitpdGVtX2lkKyIgb2Ygc2l6ZSAiK2l0ZW0uc2l6ZSsiICh0b3RhbDogIit0aGlzLml0ZW1zRGF0YVNpemUrIikiKTsKCQl9IGVsc2UgaWYgKGl0ZW0uYWxyZWFkeVJlYWQgPT09IGl0ZW0uc2l6ZSkgewoJCQkvKiBBbHJlYWR5IGZldGNoZWQgZW50aXJlbHkgKi8KCQkJcmV0dXJuIGl0ZW07CgkJfQoKCQkvKiBUaGUgaXRlbSBoYXMgb25seSBiZWVuIHBhcnRpYWxseSBmZXRjaGVkLCB3ZSBuZWVkIHRvIGNoZWNrIGluIGFsbCBidWZmZXJzIHRvIGZpbmQgdGhlIHJlbWFpbmluZyBleHRlbnRzKi8KCgkJZm9yICh2YXIgaSA9IDA7IGkgPCBpdGVtLmV4dGVudHMubGVuZ3RoOyBpKyspIHsKCQkJdmFyIGV4dGVudCA9IGl0ZW0uZXh0ZW50c1tpXTsKCQkJaWYgKGV4dGVudC5hbHJlYWR5UmVhZCA9PT0gZXh0ZW50Lmxlbmd0aCkgewoJCQkJY29udGludWU7CgkJCX0gZWxzZSB7CgkJCQl2YXIgaW5kZXggPQl0aGlzLnN0cmVhbS5maW5kUG9zaXRpb24odHJ1ZSwgZXh0ZW50Lm9mZnNldCArIGV4dGVudC5hbHJlYWR5UmVhZCwgZmFsc2UpOwoJCQkJaWYgKGluZGV4ID4gLTEpIHsKCQkJCQlidWZmZXIgPSB0aGlzLnN0cmVhbS5idWZmZXJzW2luZGV4XTsKCQkJCQl2YXIgbGVuZ3RoQWZ0ZXJTdGFydCA9IGJ1ZmZlci5ieXRlTGVuZ3RoIC0gKGV4dGVudC5vZmZzZXQgKyBleHRlbnQuYWxyZWFkeVJlYWQgLSBidWZmZXIuZmlsZVN0YXJ0KTsKCQkJCQlpZiAoZXh0ZW50Lmxlbmd0aCAtIGV4dGVudC5hbHJlYWR5UmVhZCA8PSBsZW5ndGhBZnRlclN0YXJ0KSB7CgkJCQkJCS8qIHRoZSAocmVzdCBvZiB0aGUpIGV4dGVudCBpcyBlbnRpcmVseSBjb250YWluZWQgaW4gdGhpcyBidWZmZXIgKi8KCgkJCQkJCUxvZy5kZWJ1ZygiSVNPRmlsZSIsIkdldHRpbmcgaXRlbSAjIitpdGVtX2lkKyIgZXh0ZW50ICMiK2krIiBkYXRhIChhbHJlYWR5UmVhZDogIitleHRlbnQuYWxyZWFkeVJlYWQrCgkJCQkJCQkiIG9mZnNldDogIisoZXh0ZW50Lm9mZnNldCtleHRlbnQuYWxyZWFkeVJlYWQgLSBidWZmZXIuZmlsZVN0YXJ0KSsiIHJlYWQgc2l6ZTogIisoZXh0ZW50Lmxlbmd0aCAtIGV4dGVudC5hbHJlYWR5UmVhZCkrCgkJCQkJCQkiIGZ1bGwgZXh0ZW50IHNpemU6ICIrZXh0ZW50Lmxlbmd0aCsiIGZ1bGwgaXRlbSBzaXplOiAiK2l0ZW0uc2l6ZSsiKSIpOwoKCQkJCQkJRGF0YVN0cmVhbS5tZW1jcHkoaXRlbS5kYXRhLmJ1ZmZlciwgaXRlbS5hbHJlYWR5UmVhZCwgCgkJCQkJCSAgICAgICAgICAgICAgICAgIGJ1ZmZlciwgZXh0ZW50Lm9mZnNldCtleHRlbnQuYWxyZWFkeVJlYWQgLSBidWZmZXIuZmlsZVN0YXJ0LCBleHRlbnQubGVuZ3RoIC0gZXh0ZW50LmFscmVhZHlSZWFkKTsKCgkJCQkJCS8qIHVwZGF0ZSB0aGUgbnVtYmVyIG9mIGJ5dGVzIHVzZWQgaW4gdGhpcyBidWZmZXIgYW5kIGNoZWNrIGlmIGl0IG5lZWRzIHRvIGJlIHJlbW92ZWQgKi8KCQkJCQkJYnVmZmVyLnVzZWRCeXRlcyArPSBleHRlbnQubGVuZ3RoIC0gZXh0ZW50LmFscmVhZHlSZWFkOwoJCQkJCQl0aGlzLnN0cmVhbS5sb2dCdWZmZXJMZXZlbCgpOwoKCQkJCQkJaXRlbS5hbHJlYWR5UmVhZCArPSAoZXh0ZW50Lmxlbmd0aCAtIGV4dGVudC5hbHJlYWR5UmVhZCk7CgkJCQkJCWV4dGVudC5hbHJlYWR5UmVhZCA9IGV4dGVudC5sZW5ndGg7CgkJCQkJfSBlbHNlIHsKCQkJCQkJLyogdGhlIHNhbXBsZSBkb2VzIG5vdCBlbmQgaW4gdGhpcyBidWZmZXIgKi8KCgkJCQkJCUxvZy5kZWJ1ZygiSVNPRmlsZSIsIkdldHRpbmcgaXRlbSAjIitpdGVtX2lkKyIgZXh0ZW50ICMiK2krIiBwYXJ0aWFsIGRhdGEgKGFscmVhZHlSZWFkOiAiK2V4dGVudC5hbHJlYWR5UmVhZCsiIG9mZnNldDogIisKCQkJCQkJCShleHRlbnQub2Zmc2V0K2V4dGVudC5hbHJlYWR5UmVhZCAtIGJ1ZmZlci5maWxlU3RhcnQpKyIgcmVhZCBzaXplOiAiK2xlbmd0aEFmdGVyU3RhcnQrCgkJCQkJCQkiIGZ1bGwgZXh0ZW50IHNpemU6ICIrZXh0ZW50Lmxlbmd0aCsiIGZ1bGwgaXRlbSBzaXplOiAiK2l0ZW0uc2l6ZSsiKSIpOwoKCQkJCQkJRGF0YVN0cmVhbS5tZW1jcHkoaXRlbS5kYXRhLmJ1ZmZlciwgaXRlbS5hbHJlYWR5UmVhZCwgCgkJCQkJCSAgICAgICAgICAgICAgICAgIGJ1ZmZlciwgZXh0ZW50Lm9mZnNldCtleHRlbnQuYWxyZWFkeVJlYWQgLSBidWZmZXIuZmlsZVN0YXJ0LCBsZW5ndGhBZnRlclN0YXJ0KTsKCQkJCQkJZXh0ZW50LmFscmVhZHlSZWFkICs9IGxlbmd0aEFmdGVyU3RhcnQ7CgkJCQkJCWl0ZW0uYWxyZWFkeVJlYWQgKz0gbGVuZ3RoQWZ0ZXJTdGFydDsKCgkJCQkJCS8qIHVwZGF0ZSB0aGUgbnVtYmVyIG9mIGJ5dGVzIHVzZWQgaW4gdGhpcyBidWZmZXIgYW5kIGNoZWNrIGlmIGl0IG5lZWRzIHRvIGJlIHJlbW92ZWQgKi8KCQkJCQkJYnVmZmVyLnVzZWRCeXRlcyArPSBsZW5ndGhBZnRlclN0YXJ0OwoJCQkJCQl0aGlzLnN0cmVhbS5sb2dCdWZmZXJMZXZlbCgpOwoJCQkJCQlyZXR1cm4gbnVsbDsKCQkJCQl9CgkJCQl9IGVsc2UgewoJCQkJCXJldHVybiBudWxsOwoJCQkJfQoJCQl9CgkJfQoJCWlmIChpdGVtLmFscmVhZHlSZWFkID09PSBpdGVtLnNpemUpIHsKCQkJLyogZmV0Y2hlZCBlbnRpcmVseSAqLwoJCQlyZXR1cm4gaXRlbTsKCQl9IGVsc2UgewoJCQlyZXR1cm4gbnVsbDsKCQl9Cgl9OwoKCS8qIFJlbGVhc2UgdGhlIG1lbW9yeSB1c2VkIHRvIHN0b3JlIHRoZSBkYXRhIG9mIHRoZSBpdGVtICovCglJU09GaWxlLnByb3RvdHlwZS5yZWxlYXNlSXRlbSA9IGZ1bmN0aW9uKGl0ZW1faWQpIHsJCgkJdmFyIGl0ZW0gPSB0aGlzLml0ZW1zW2l0ZW1faWRdOwoJCWlmIChpdGVtLmRhdGEpIHsKCQkJdGhpcy5pdGVtc0RhdGFTaXplIC09IGl0ZW0uc2l6ZTsKCQkJaXRlbS5kYXRhID0gbnVsbDsKCQkJaXRlbS5hbHJlYWR5UmVhZCA9IDA7CgkJCWZvciAodmFyIGkgPSAwOyBpIDwgaXRlbS5leHRlbnRzLmxlbmd0aDsgaSsrKSB7CgkJCQl2YXIgZXh0ZW50ID0gaXRlbS5leHRlbnRzW2ldOwoJCQkJZXh0ZW50LmFscmVhZHlSZWFkID0gMDsKCQkJfQoJCQlyZXR1cm4gaXRlbS5zaXplOwoJCX0gZWxzZSB7CgkJCXJldHVybiAwOwoJCX0KCX07CgoKCUlTT0ZpbGUucHJvdG90eXBlLnByb2Nlc3NJdGVtcyA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7CgkJZm9yKHZhciBpIGluIHRoaXMuaXRlbXMpIHsKCQkJdmFyIGl0ZW0gPSB0aGlzLml0ZW1zW2ldOwoJCQl0aGlzLmdldEl0ZW0oaXRlbS5pZCk7CgkJCWlmIChjYWxsYmFjayAmJiAhaXRlbS5zZW50KSB7CgkJCQljYWxsYmFjayhpdGVtKTsKCQkJCWl0ZW0uc2VudCA9IHRydWU7CgkJCQlpdGVtLmRhdGEgPSBudWxsOwoJCQl9CgkJfQoJfTsKCglJU09GaWxlLnByb3RvdHlwZS5oYXNJdGVtID0gZnVuY3Rpb24obmFtZSkgewoJCWZvcih2YXIgaSBpbiB0aGlzLml0ZW1zKSB7CgkJCXZhciBpdGVtID0gdGhpcy5pdGVtc1tpXTsKCQkJaWYgKGl0ZW0ubmFtZSA9PT0gbmFtZSkgewoJCQkJcmV0dXJuIGl0ZW0uaWQ7CgkJCX0KCQl9CgkJcmV0dXJuIC0xOwoJfTsKCglJU09GaWxlLnByb3RvdHlwZS5nZXRNZXRhSGFuZGxlciA9IGZ1bmN0aW9uKCkgewoJCWlmICghdGhpcy5tZXRhKSB7CgkJCXJldHVybiBudWxsOwoJCX0gZWxzZSB7CgkJCXJldHVybiB0aGlzLm1ldGEuaGRsci5oYW5kbGVyOwkJCgkJfQoJfTsKCglJU09GaWxlLnByb3RvdHlwZS5nZXRQcmltYXJ5SXRlbSA9IGZ1bmN0aW9uKCkgewoJCWlmICghdGhpcy5tZXRhIHx8ICF0aGlzLm1ldGEucGl0bSkgewoJCQlyZXR1cm4gbnVsbDsKCQl9IGVsc2UgewoJCQlyZXR1cm4gdGhpcy5nZXRJdGVtKHRoaXMubWV0YS5waXRtLml0ZW1faWQpOwoJCX0KCX07CgoJSVNPRmlsZS5wcm90b3R5cGUuaXRlbVRvRnJhZ21lbnRlZFRyYWNrRmlsZSA9IGZ1bmN0aW9uKF9vcHRpb25zKSB7CgkJdmFyIG9wdGlvbnMgPSBfb3B0aW9ucyB8fCB7fTsKCQl2YXIgaXRlbSA9IG51bGw7CgkJaWYgKG9wdGlvbnMuaXRlbUlkKSB7CgkJCWl0ZW0gPSB0aGlzLmdldEl0ZW0ob3B0aW9ucy5pdGVtSWQpOwoJCX0gZWxzZSB7CgkJCWl0ZW0gPSB0aGlzLmdldFByaW1hcnlJdGVtKCk7CgkJfQoJCWlmIChpdGVtID09IG51bGwpIHJldHVybiBudWxsOwoKCQl2YXIgZmlsZSA9IG5ldyBJU09GaWxlKCk7CgkJZmlsZS5kaXNjYXJkTWRhdERhdGEgPSBmYWxzZTsKCQkvLyBhc3N1bWluZyB0aGUgdHJhY2sgdHlwZSBpcyB0aGUgc2FtZSBhcyB0aGUgaXRlbSB0eXBlCgkJdmFyIHRyYWNrT3B0aW9ucyA9IHsgdHlwZTogaXRlbS50eXBlLCBkZXNjcmlwdGlvbl9ib3hlczogaXRlbS5wcm9wZXJ0aWVzLmJveGVzfTsKCQlpZiAoaXRlbS5wcm9wZXJ0aWVzLmlzcGUpIHsKCQkJdHJhY2tPcHRpb25zLndpZHRoID0gaXRlbS5wcm9wZXJ0aWVzLmlzcGUuaW1hZ2Vfd2lkdGg7CgkJCXRyYWNrT3B0aW9ucy5oZWlnaHQgPSBpdGVtLnByb3BlcnRpZXMuaXNwZS5pbWFnZV9oZWlnaHQ7CgkJfQoJCXZhciB0cmFja0lkID0gZmlsZS5hZGRUcmFjayh0cmFja09wdGlvbnMpOwoJCWlmICh0cmFja0lkKSB7CgkJCWZpbGUuYWRkU2FtcGxlKHRyYWNrSWQsIGl0ZW0uZGF0YSk7CgkJCXJldHVybiBmaWxlOwoJCX0gZWxzZSB7CgkJCXJldHVybiBudWxsOwoJCX0KCX07CgoJLy8gZmlsZTpzcmMvaXNvZmlsZS13cml0ZS5qcwoJLyogUmV3cml0ZSB0aGUgZW50aXJlIGZpbGUgKi8KCUlTT0ZpbGUucHJvdG90eXBlLndyaXRlID0gZnVuY3Rpb24ob3V0c3RyZWFtKSB7CgkJZm9yICh2YXIgaT0wOyBpPHRoaXMuYm94ZXMubGVuZ3RoOyBpKyspIHsKCQkJdGhpcy5ib3hlc1tpXS53cml0ZShvdXRzdHJlYW0pOwoJCX0KCX07CgoJSVNPRmlsZS5wcm90b3R5cGUuY3JlYXRlRnJhZ21lbnQgPSBmdW5jdGlvbih0cmFja19pZCwgc2FtcGxlTnVtYmVyLCBzdHJlYW1fKSB7CgkJdmFyIHRyYWsgPSB0aGlzLmdldFRyYWNrQnlJZCh0cmFja19pZCk7CgkJdmFyIHNhbXBsZSA9IHRoaXMuZ2V0U2FtcGxlKHRyYWssIHNhbXBsZU51bWJlcik7CgkJaWYgKHNhbXBsZSA9PSBudWxsKSB7CgkJCXNhbXBsZSA9IHRyYWsuc2FtcGxlc1tzYW1wbGVOdW1iZXJdOwoJCQlpZiAodGhpcy5uZXh0U2Vla1Bvc2l0aW9uKSB7CgkJCQl0aGlzLm5leHRTZWVrUG9zaXRpb24gPSBNYXRoLm1pbihzYW1wbGUub2Zmc2V0K3NhbXBsZS5hbHJlYWR5UmVhZCx0aGlzLm5leHRTZWVrUG9zaXRpb24pOwoJCQl9IGVsc2UgewoJCQkJdGhpcy5uZXh0U2Vla1Bvc2l0aW9uID0gdHJhay5zYW1wbGVzW3NhbXBsZU51bWJlcl0ub2Zmc2V0K3NhbXBsZS5hbHJlYWR5UmVhZDsKCQkJfQoJCQlyZXR1cm4gbnVsbDsKCQl9CgkJCgkJdmFyIHN0cmVhbSA9IHN0cmVhbV8gfHwgbmV3IERhdGFTdHJlYW0oKTsKCQlzdHJlYW0uZW5kaWFubmVzcyA9IERhdGFTdHJlYW0uQklHX0VORElBTjsKCgkJdmFyIG1vb2YgPSB0aGlzLmNyZWF0ZVNpbmdsZVNhbXBsZU1vb2Yoc2FtcGxlKTsKCQltb29mLndyaXRlKHN0cmVhbSk7CgoJCS8qIGFkanVzdGluZyB0aGUgZGF0YV9vZmZzZXQgbm93IHRoYXQgdGhlIG1vb2Ygc2l6ZSBpcyBrbm93biovCgkJbW9vZi50cmFmc1swXS50cnVuc1swXS5kYXRhX29mZnNldCA9IG1vb2Yuc2l6ZSs4OyAvLzggaXMgbWRhdCBoZWFkZXIKCQlMb2cuZGVidWcoIk1QNEJveCIsICJBZGp1c3RpbmcgZGF0YV9vZmZzZXQgd2l0aCBuZXcgdmFsdWUgIittb29mLnRyYWZzWzBdLnRydW5zWzBdLmRhdGFfb2Zmc2V0KTsKCQlzdHJlYW0uYWRqdXN0VWludDMyKG1vb2YudHJhZnNbMF0udHJ1bnNbMF0uZGF0YV9vZmZzZXRfcG9zaXRpb24sIG1vb2YudHJhZnNbMF0udHJ1bnNbMF0uZGF0YV9vZmZzZXQpOwoJCQkKCQl2YXIgbWRhdCA9IG5ldyBCb3hQYXJzZXIubWRhdEJveCgpOwoJCW1kYXQuZGF0YSA9IHNhbXBsZS5kYXRhOwoJCW1kYXQud3JpdGUoc3RyZWFtKTsKCQlyZXR1cm4gc3RyZWFtOwoJfTsKCgkvKiBNb2RpZnkgdGhlIGZpbGUgYW5kIGNyZWF0ZSB0aGUgaW5pdGlhbGl6YXRpb24gc2VnbWVudCAqLwoJSVNPRmlsZS53cml0ZUluaXRpYWxpemF0aW9uU2VnbWVudCA9IGZ1bmN0aW9uKGZ0eXAsIG1vb3YsIHRvdGFsX2R1cmF0aW9uLCBzYW1wbGVfZHVyYXRpb24pIHsKCQl2YXIgaTsKCQlMb2cuZGVidWcoIklTT0ZpbGUiLCAiR2VuZXJhdGluZyBpbml0aWFsaXphdGlvbiBzZWdtZW50Iik7CgoJCXZhciBzdHJlYW0gPSBuZXcgRGF0YVN0cmVhbSgpOwoJCXN0cmVhbS5lbmRpYW5uZXNzID0gRGF0YVN0cmVhbS5CSUdfRU5ESUFOOwoJCWZ0eXAud3JpdGUoc3RyZWFtKTsKCQkKCQkvKiB3ZSBjYW4gbm93IGNyZWF0ZSB0aGUgbmV3IG12ZXggYm94ICovCgkJdmFyIG12ZXggPSBtb292LmFkZCgibXZleCIpOwoJCWlmICh0b3RhbF9kdXJhdGlvbikgewoJCQltdmV4LmFkZCgibWVoZCIpLnNldCgiZnJhZ21lbnRfZHVyYXRpb24iLCB0b3RhbF9kdXJhdGlvbik7CgkJfQoJCWZvciAoaSA9IDA7IGkgPCBtb292LnRyYWtzLmxlbmd0aDsgaSsrKSB7CgkJCW12ZXguYWRkKCJ0cmV4Iikuc2V0KCJ0cmFja19pZCIsIG1vb3YudHJha3NbaV0udGtoZC50cmFja19pZCkKCQkJCQkJCS5zZXQoImRlZmF1bHRfc2FtcGxlX2Rlc2NyaXB0aW9uX2luZGV4IiwgMSkKCQkJCQkJCS5zZXQoImRlZmF1bHRfc2FtcGxlX2R1cmF0aW9uIiwgc2FtcGxlX2R1cmF0aW9uKQoJCQkJCQkJLnNldCgiZGVmYXVsdF9zYW1wbGVfc2l6ZSIsIDApCgkJCQkJCQkuc2V0KCJkZWZhdWx0X3NhbXBsZV9mbGFncyIsIDE8PDE2KTsKCQl9CgkJbW9vdi53cml0ZShzdHJlYW0pOwoKCQlyZXR1cm4gc3RyZWFtLmJ1ZmZlcjsKCgl9OwoKCUlTT0ZpbGUucHJvdG90eXBlLnNhdmUgPSBmdW5jdGlvbihuYW1lKSB7CgkJdmFyIHN0cmVhbSA9IG5ldyBEYXRhU3RyZWFtKCk7CgkJc3RyZWFtLmVuZGlhbm5lc3MgPSBEYXRhU3RyZWFtLkJJR19FTkRJQU47CgkJdGhpcy53cml0ZShzdHJlYW0pOwoJCXN0cmVhbS5zYXZlKG5hbWUpOwkKCX07CgoJSVNPRmlsZS5wcm90b3R5cGUuZ2V0QnVmZmVyID0gZnVuY3Rpb24oKSB7CgkJdmFyIHN0cmVhbSA9IG5ldyBEYXRhU3RyZWFtKCk7CgkJc3RyZWFtLmVuZGlhbm5lc3MgPSBEYXRhU3RyZWFtLkJJR19FTkRJQU47CgkJdGhpcy53cml0ZShzdHJlYW0pOwoJCXJldHVybiBzdHJlYW0uYnVmZmVyOwoJfTsKCglJU09GaWxlLnByb3RvdHlwZS5pbml0aWFsaXplU2VnbWVudGF0aW9uID0gZnVuY3Rpb24oKSB7CgkJdmFyIGk7CgkJdmFyIGluaXRTZWdzOwoJCXZhciB0cmFrOwoJCXZhciBzZWc7CgkJaWYgKHRoaXMub25TZWdtZW50ID09PSBudWxsKSB7CgkJCUxvZy53YXJuKCJNUDRCb3giLCAiTm8gc2VnbWVudGF0aW9uIGNhbGxiYWNrIHNldCEiKTsKCQl9CgkJaWYgKCF0aGlzLmlzRnJhZ21lbnRhdGlvbkluaXRpYWxpemVkKSB7CgkJCXRoaXMuaXNGcmFnbWVudGF0aW9uSW5pdGlhbGl6ZWQgPSB0cnVlOwkJCgkJCXRoaXMubmV4dE1vb2ZOdW1iZXIgPSAwOwoJCQl0aGlzLnJlc2V0VGFibGVzKCk7CgkJfQkKCQlpbml0U2VncyA9IFtdOwkKCQlmb3IgKGkgPSAwOyBpIDwgdGhpcy5mcmFnbWVudGVkVHJhY2tzLmxlbmd0aDsgaSsrKSB7CgkJCXZhciBtb292ID0gbmV3IEJveFBhcnNlci5tb292Qm94KCk7CgkJCW1vb3YubXZoZCA9IHRoaXMubW9vdi5tdmhkOwoJCSAgICBtb292LmJveGVzLnB1c2gobW9vdi5tdmhkKTsKCQkJdHJhayA9IHRoaXMuZ2V0VHJhY2tCeUlkKHRoaXMuZnJhZ21lbnRlZFRyYWNrc1tpXS5pZCk7CgkJCW1vb3YuYm94ZXMucHVzaCh0cmFrKTsKCQkJbW9vdi50cmFrcy5wdXNoKHRyYWspOwoJCQlzZWcgPSB7fTsKCQkJc2VnLmlkID0gdHJhay50a2hkLnRyYWNrX2lkOwoJCQlzZWcudXNlciA9IHRoaXMuZnJhZ21lbnRlZFRyYWNrc1tpXS51c2VyOwoJCQlzZWcuYnVmZmVyID0gSVNPRmlsZS53cml0ZUluaXRpYWxpemF0aW9uU2VnbWVudCh0aGlzLmZ0eXAsIG1vb3YsICh0aGlzLm1vb3YubXZleCAmJiB0aGlzLm1vb3YubXZleC5tZWhkID8gdGhpcy5tb292Lm12ZXgubWVoZC5mcmFnbWVudF9kdXJhdGlvbjogdW5kZWZpbmVkKSwgKHRoaXMubW9vdi50cmFrc1tpXS5zYW1wbGVzLmxlbmd0aD4wID8gdGhpcy5tb292LnRyYWtzW2ldLnNhbXBsZXNbMF0uZHVyYXRpb246IDApKTsKCQkJaW5pdFNlZ3MucHVzaChzZWcpOwoJCX0KCQlyZXR1cm4gaW5pdFNlZ3M7Cgl9OwoKCS8vIGZpbGU6c3JjL2JveC1wcmludC5qcwoJLyogCgkgKiBDb3B5cmlnaHQgKGMpIFRlbGVjb20gUGFyaXNUZWNoL1RTSS9NTS9HUEFDIEN5cmlsIENvbmNvbGF0bwoJICogTGljZW5zZTogQlNELTMtQ2xhdXNlIChzZWUgTElDRU5TRSBmaWxlKQoJICovCglCb3hQYXJzZXIuQm94LnByb3RvdHlwZS5wcmludEhlYWRlciA9IGZ1bmN0aW9uKG91dHB1dCkgewoJCXRoaXMuc2l6ZSArPSA4OwoJCWlmICh0aGlzLnNpemUgPiBNQVhfU0laRSkgewoJCQl0aGlzLnNpemUgKz0gODsKCQl9CgkJaWYgKHRoaXMudHlwZSA9PT0gInV1aWQiKSB7CgkJCXRoaXMuc2l6ZSArPSAxNjsKCQl9CgkJb3V0cHV0LmxvZyhvdXRwdXQuaW5kZW50KyJzaXplOiIrdGhpcy5zaXplKTsKCQlvdXRwdXQubG9nKG91dHB1dC5pbmRlbnQrInR5cGU6Iit0aGlzLnR5cGUpOwoJfTsKCglCb3hQYXJzZXIuRnVsbEJveC5wcm90b3R5cGUucHJpbnRIZWFkZXIgPSBmdW5jdGlvbihvdXRwdXQpIHsKCQl0aGlzLnNpemUgKz0gNDsKCQlCb3hQYXJzZXIuQm94LnByb3RvdHlwZS5wcmludEhlYWRlci5jYWxsKHRoaXMsIG91dHB1dCk7CgkJb3V0cHV0LmxvZyhvdXRwdXQuaW5kZW50KyJ2ZXJzaW9uOiIrdGhpcy52ZXJzaW9uKTsKCQlvdXRwdXQubG9nKG91dHB1dC5pbmRlbnQrImZsYWdzOiIrdGhpcy5mbGFncyk7Cgl9OwoKCUJveFBhcnNlci5Cb3gucHJvdG90eXBlLnByaW50ID0gZnVuY3Rpb24ob3V0cHV0KSB7CgkJdGhpcy5wcmludEhlYWRlcihvdXRwdXQpOwoJfTsKCglCb3hQYXJzZXIuQ29udGFpbmVyQm94LnByb3RvdHlwZS5wcmludCA9IGZ1bmN0aW9uKG91dHB1dCkgewoJCXRoaXMucHJpbnRIZWFkZXIob3V0cHV0KTsKCQlmb3IgKHZhciBpPTA7IGk8dGhpcy5ib3hlcy5sZW5ndGg7IGkrKykgewoJCQlpZiAodGhpcy5ib3hlc1tpXSkgewoJCQkJdmFyIHByZXZfaW5kZW50ID0gb3V0cHV0LmluZGVudDsKCQkJCW91dHB1dC5pbmRlbnQgKz0gIiAiOwoJCQkJdGhpcy5ib3hlc1tpXS5wcmludChvdXRwdXQpOwoJCQkJb3V0cHV0LmluZGVudCA9IHByZXZfaW5kZW50OwoJCQl9CgkJfQoJfTsKCglJU09GaWxlLnByb3RvdHlwZS5wcmludCA9IGZ1bmN0aW9uKG91dHB1dCkgewoJCW91dHB1dC5pbmRlbnQgPSAiIjsKCQlmb3IgKHZhciBpPTA7IGk8dGhpcy5ib3hlcy5sZW5ndGg7IGkrKykgewoJCQlpZiAodGhpcy5ib3hlc1tpXSkgewoJCQkJdGhpcy5ib3hlc1tpXS5wcmludChvdXRwdXQpOwoJCQl9CgkJfQkKCX07CgoJQm94UGFyc2VyLm12aGRCb3gucHJvdG90eXBlLnByaW50ID0gZnVuY3Rpb24ob3V0cHV0KSB7CgkJQm94UGFyc2VyLkZ1bGxCb3gucHJvdG90eXBlLnByaW50SGVhZGVyLmNhbGwodGhpcywgb3V0cHV0KTsKCQlvdXRwdXQubG9nKG91dHB1dC5pbmRlbnQrImNyZWF0aW9uX3RpbWU6ICIrdGhpcy5jcmVhdGlvbl90aW1lKTsKCQlvdXRwdXQubG9nKG91dHB1dC5pbmRlbnQrIm1vZGlmaWNhdGlvbl90aW1lOiAiK3RoaXMubW9kaWZpY2F0aW9uX3RpbWUpOwoJCW91dHB1dC5sb2cob3V0cHV0LmluZGVudCsidGltZXNjYWxlOiAiK3RoaXMudGltZXNjYWxlKTsKCQlvdXRwdXQubG9nKG91dHB1dC5pbmRlbnQrImR1cmF0aW9uOiAiK3RoaXMuZHVyYXRpb24pOwoJCW91dHB1dC5sb2cob3V0cHV0LmluZGVudCsicmF0ZTogIit0aGlzLnJhdGUpOwoJCW91dHB1dC5sb2cob3V0cHV0LmluZGVudCsidm9sdW1lOiAiKyh0aGlzLnZvbHVtZT4+OCkpOwoJCW91dHB1dC5sb2cob3V0cHV0LmluZGVudCsibWF0cml4OiAiK3RoaXMubWF0cml4LmpvaW4oIiwgIikpOwoJCW91dHB1dC5sb2cob3V0cHV0LmluZGVudCsibmV4dF90cmFja19pZDogIit0aGlzLm5leHRfdHJhY2tfaWQpOwoJfTsKCglCb3hQYXJzZXIudGtoZEJveC5wcm90b3R5cGUucHJpbnQgPSBmdW5jdGlvbihvdXRwdXQpIHsKCQlCb3hQYXJzZXIuRnVsbEJveC5wcm90b3R5cGUucHJpbnRIZWFkZXIuY2FsbCh0aGlzLCBvdXRwdXQpOwoJCW91dHB1dC5sb2cob3V0cHV0LmluZGVudCsiY3JlYXRpb25fdGltZTogIit0aGlzLmNyZWF0aW9uX3RpbWUpOwoJCW91dHB1dC5sb2cob3V0cHV0LmluZGVudCsibW9kaWZpY2F0aW9uX3RpbWU6ICIrdGhpcy5tb2RpZmljYXRpb25fdGltZSk7CgkJb3V0cHV0LmxvZyhvdXRwdXQuaW5kZW50KyJ0cmFja19pZDogIit0aGlzLnRyYWNrX2lkKTsKCQlvdXRwdXQubG9nKG91dHB1dC5pbmRlbnQrImR1cmF0aW9uOiAiK3RoaXMuZHVyYXRpb24pOwoJCW91dHB1dC5sb2cob3V0cHV0LmluZGVudCsidm9sdW1lOiAiKyh0aGlzLnZvbHVtZT4+OCkpOwoJCW91dHB1dC5sb2cob3V0cHV0LmluZGVudCsibWF0cml4OiAiK3RoaXMubWF0cml4LmpvaW4oIiwgIikpOwoJCW91dHB1dC5sb2cob3V0cHV0LmluZGVudCsibGF5ZXI6ICIrdGhpcy5sYXllcik7CgkJb3V0cHV0LmxvZyhvdXRwdXQuaW5kZW50KyJhbHRlcm5hdGVfZ3JvdXA6ICIrdGhpcy5hbHRlcm5hdGVfZ3JvdXApOwoJCW91dHB1dC5sb2cob3V0cHV0LmluZGVudCsid2lkdGg6ICIrdGhpcy53aWR0aCk7CgkJb3V0cHV0LmxvZyhvdXRwdXQuaW5kZW50KyJoZWlnaHQ6ICIrdGhpcy5oZWlnaHQpOwoJfTsvLyBmaWxlOnNyYy9tcDRib3guanMKCS8qCgkgKiBDb3B5cmlnaHQgKGMpIDIwMTItMjAxMy4gVGVsZWNvbSBQYXJpc1RlY2gvVFNJL01NL0dQQUMgQ3lyaWwgQ29uY29sYXRvCgkgKiBMaWNlbnNlOiBCU0QtMy1DbGF1c2UgKHNlZSBMSUNFTlNFIGZpbGUpCgkgKi8KCXZhciBNUDRCb3ggPSB7fTsKCglNUDRCb3guY3JlYXRlRmlsZSA9IGZ1bmN0aW9uIChfa2VlcE1kYXREYXRhLCBfc3RyZWFtKSB7CgkJLyogQm9vbGVhbiBpbmRpY2F0aW5nIGlmIGJ5dGVzIGNvbnRhaW5pbmcgbWVkaWEgZGF0YSBzaG91bGQgYmUga2VwdCBpbiBtZW1vcnkgKi8KCQl2YXIga2VlcE1kYXREYXRhID0gKF9rZWVwTWRhdERhdGEgIT09IHVuZGVmaW5lZCA/IF9rZWVwTWRhdERhdGEgOiB0cnVlKTsKCQl2YXIgZmlsZSA9IG5ldyBJU09GaWxlKF9zdHJlYW0pOwoJCWZpbGUuZGlzY2FyZE1kYXREYXRhID0gKGtlZXBNZGF0RGF0YSA/IGZhbHNlIDogdHJ1ZSk7CgkJcmV0dXJuIGZpbGU7Cgl9OwoKCXsKCQlleHBvcnRzLmNyZWF0ZUZpbGUgPSBNUDRCb3guY3JlYXRlRmlsZTsKCX0KCX0pOwoKCXNlbGYuTHggPSBmYWxzZTsNCg0KCXZhciB3cyA9IG51bGw7DQoJdmFyIGZsYWcgPSAxOw0KDQoJZnVuY3Rpb24gV3NPcGVuKGV2ZW50KSB7DQoJICBjb25zb2xlLmxvZygi6L+e5o6l5omT5byAIik7DQoJfQ0KCWZ1bmN0aW9uIFdzQ2xvc2UoZXZlbnQpIHsNCgkgIGNvbnNvbGUubG9nKCLov57mjqXlhbPpl60iKTsNCgl9DQoJZnVuY3Rpb24gV3NFcnJvcihldmVudCkgew0KCSAgY29uc29sZS5sb2coIndzIOWPkeeUn+mUmeivrzoiICsgZXZlbnQpOw0KCX0NCgljbGFzcyBNUDRGaWxlU2luayB7DQoJICAjZmlsZSA9IG51bGw7DQoJICAjb2Zmc2V0ID0gMDsNCgkgIGNvbnN0cnVjdG9yKGZpbGUpIHsNCgkgICAgdGhpcy4jZmlsZSA9IGZpbGU7DQoJICB9DQoJICB3cml0ZShjaHVuaykgew0KCSAgICBjaHVuay5maWxlU3RhcnQgPSB0aGlzLiNvZmZzZXQ7DQoJICAgIHRoaXMuI29mZnNldCArPSBjaHVuay5ieXRlTGVuZ3RoOw0KCSAgICB0aGlzLiNmaWxlLmFwcGVuZEJ1ZmZlcihjaHVuayk7DQoJICB9DQoJICBjbG9zZSgpIHsNCgkgICAgdGhpcy4jZmlsZS5mbHVzaCgpOw0KCSAgfQ0KCX0NCg0KCXZhciBmaWxlID0gbnVsbDsNCgl2YXIgc2hvd0RhdGEgPSBudWxsOw0KDQoJdmFyIFNhdmVTdGVwID0gMDsNCgl2YXIgU2F2ZUJ1ZmZlciA9IFtdOw0KCWxldCBNcDRIZWFyZEJ1ZmZlciA9IFtdOw0KDQoJdmFyIGtTYXZlQnVmZmVyU2l6ZSA9IDA7DQoJbGV0IE1wNEhlYXJkQnVmZmVyU2l6ZSA9IDA7DQoNCglmdW5jdGlvbiBXc01lc3NhZ2UoZXZlbnQpIHsNCgkgIGlmICh0eXBlb2YgZXZlbnQuZGF0YSA9PT0gInN0cmluZyIpIHsNCgkgICAgdmFyIERhdGFUeXBlID0gIk9wdCI7DQoJICAgIHNlbGYucG9zdE1lc3NhZ2UoeyBEYXRhVHlwZSwgZGF0YTogZXZlbnQuZGF0YSB9KTsNCgkgICAgcmV0dXJuOw0KCSAgfQ0KCSAgY29uc3QgZHYgPSBuZXcgRGF0YVZpZXcoZXZlbnQuZGF0YSk7DQoJICBjb25zdCBpbnQzMlZhbHVlID0gZHYuZ2V0SW50MzIoMCwgdHJ1ZSk7DQoJICBjb25zdCB0eXBlID0gTnVtYmVyKGludDMyVmFsdWUpOw0KCSAgbGV0IGpzb25PYmplY3QsIHZpZG9lRGF0YSwganNvbkRhdGE7DQoJICBzd2l0Y2ggKHR5cGUpIHsNCgkgICAgY2FzZSAxOg0KCSAgICAgIGZpbGUgPSBtcDRib3hfYWxsLmNyZWF0ZUZpbGUoKTsNCgkgICAgICBmaWxlLm9uUmVhZHkgPSBvblJlYWR5Ow0KCSAgICAgIGZpbGUub25TYW1wbGVzID0gb25TYW1wbGVzOw0KCSAgICAgIHRoaXMuZmlsZVNpbmsgPSBuZXcgTVA0RmlsZVNpbmsoZmlsZSk7DQoJICAgICAgdmlkb2VEYXRhID0gZHYuYnVmZmVyLnNsaWNlKDQpOw0KCSAgICAgIGlmIChTYXZlU3RlcCA9PT0gMCkgew0KCSAgICAgICAgTXA0SGVhcmRCdWZmZXIucHVzaChldmVudC5kYXRhLnNsaWNlKDQpKTsNCgkgICAgICAgIE1wNEhlYXJkQnVmZmVyU2l6ZSArPSBldmVudC5kYXRhLmJ5dGVMZW5ndGggLSA0Ow0KCSAgICAgICAgU2F2ZVN0ZXAgPSAxOw0KCSAgICAgIH0NCgkgICAgICB0aGlzLmZpbGVTaW5rLndyaXRlKHZpZG9lRGF0YSk7DQoJICAgICAgYnJlYWs7DQoJICAgIGNhc2UgMjoNCgkgICAgICB2aWRvZURhdGEgPSBkdi5idWZmZXIuc2xpY2UoNCk7DQoJICAgICAgaWYgKFNhdmVTdGVwID09PSAxKSB7DQoJICAgICAgICBNcDRIZWFyZEJ1ZmZlci5wdXNoKGV2ZW50LmRhdGEuc2xpY2UoNCkpOw0KCSAgICAgICAgTXA0SGVhcmRCdWZmZXJTaXplICs9IGV2ZW50LmRhdGEuYnl0ZUxlbmd0aCAtIDQ7DQoJICAgICAgICBTYXZlU3RlcCA9IDI7DQoJICAgICAgfQ0KCSAgICAgIHRoaXMuZmlsZVNpbmsud3JpdGUodmlkb2VEYXRhKTsNCgkgICAgICBicmVhazsNCgkgICAgY2FzZSAzOg0KCSAgICAgIHZpZG9lRGF0YSA9IGR2LmJ1ZmZlci5zbGljZSg0KTsNCgkgICAgICBpZiAoTHgpIHsNCgkgICAgICAgIFNhdmVCdWZmZXIucHVzaChldmVudC5kYXRhLnNsaWNlKDQpKTsNCgkgICAgICAgIGtTYXZlQnVmZmVyU2l6ZSArPSBldmVudC5kYXRhLmJ5dGVMZW5ndGggLSA0Ow0KCSAgICAgIH0NCgkgICAgICB0aGlzLmZpbGVTaW5rLndyaXRlKHZpZG9lRGF0YSk7DQoJICAgICAgYnJlYWs7DQoJICAgIGNhc2UgNDoNCgkgICAgICB2aWRvZURhdGEgPSBkdi5idWZmZXIuc2xpY2UoNCk7DQoJICAgICAgaWYgKEx4KSB7DQoJICAgICAgICBTYXZlQnVmZmVyLnB1c2goZXZlbnQuZGF0YS5zbGljZSg0KSk7DQoJICAgICAgICBrU2F2ZUJ1ZmZlclNpemUgKz0gZXZlbnQuZGF0YS5ieXRlTGVuZ3RoIC0gNDsNCgkgICAgICB9DQoJICAgICAgdGhpcy5maWxlU2luay53cml0ZSh2aWRvZURhdGEpOw0KCSAgICAgIGJyZWFrOw0KCSAgICBjYXNlIDU6DQoJICAgICAganNvbkRhdGEgPSBuZXcgVGV4dERlY29kZXIoKS5kZWNvZGUoZHYuYnVmZmVyLnNsaWNlKDQpKTsNCgkgICAgICAvKg0KCSAgICAgICAgICAgIHsNCgkgICAgICAgICAgICAgICAgIlBlcnNvbiI6IFsNCgkgICAgICAgICAgICAgICAgICAgIFsNCgkgICAgICAgICAgICAgICAgICAgICAgICAxLA0KCSAgICAgICAgICAgICAgICAgICAgICAgIDExOCwNCgkgICAgICAgICAgICAgICAgICAgICAgICA2MTQsDQoJICAgICAgICAgICAgICAgICAgICAgICAgMzgxOSwNCgkgICAgICAgICAgICAgICAgICAgICAgICA4NA0KCSAgICAgICAgICAgICAgICAgICAgXQ0KCSAgICAgICAgICAgICAgICBdLA0KCSAgICAgICAgICAgICAgICAiVCI6IDE3NTAwNDM0MjU3MDANCgkgICAgICAgICAgICB9DQoJICAgICAgICAgICAgKi8NCgkgICAgICBpZiAoanNvbkRhdGEpIHsNCgkgICAgICAgIGpzb25PYmplY3QgPSBKU09OLnBhcnNlKGpzb25EYXRhKTsNCgkgICAgICAgIGlmIChqc29uT2JqZWN0LlBlcnNvbikgew0KCSAgICAgICAgICBzaG93RGF0YSA9IGpzb25PYmplY3QuUGVyc29uOw0KCSAgICAgICAgfSBlbHNlIHsNCgkgICAgICAgICAgc2hvd0RhdGEgPSBbXTsNCgkgICAgICAgIH0NCgkgICAgICB9IGVsc2Ugew0KCSAgICAgICAgc2hvd0RhdGEgPSBbXTsNCgkgICAgICB9DQoJICAgICAgYnJlYWs7DQoJICB9DQoJfQ0KDQoJZnVuY3Rpb24gb25SZWFkeShpbmZvKSB7DQoJICBjb25zb2xlLmxvZygib25SZWFkeSIpOw0KCSAgY29uc3QgdHJhY2sgPSBpbmZvLnZpZGVvVHJhY2tzWzBdOw0KCSAgaWYgKGZsYWcgIT09IDIpIHsNCgkgICAgdmFyIERhdGFUeXBlID0gIlRyYWNrIjsNCgkgICAgdmFyIHRraW5mbyA9IGRlc2NyaXB0aW9uKGZpbGUuZ2V0VHJhY2tCeUlkKHRyYWNrLmlkKSk7DQoNCgkgICAgc2VsZi5wb3N0TWVzc2FnZSh7IERhdGFUeXBlLCB0cmFjaywgdGtpbmZvIH0pOw0KCSAgfQ0KCSAgZmxhZyA9IDI7DQoJICBmaWxlLnNldEV4dHJhY3Rpb25PcHRpb25zKHRyYWNrLmlkKTsNCgkgIGZpbGUuc3RhcnQoKTsNCgl9DQoNCglmdW5jdGlvbiBvblNhbXBsZXModHJhY2tfaWQsIHJlZiwgc2FtcGxlcykgew0KCSAgZm9yIChjb25zdCBzYW1wbGUgb2Ygc2FtcGxlcykgew0KCSAgICB2YXIgRGF0YVR5cGUgPSAiU2FtcGxlcyI7DQoJICAgIHNlbGYucG9zdE1lc3NhZ2UoeyBEYXRhVHlwZSwgc2FtcGxlLCBzaG93RGF0YSB9KTsNCgkgIH0NCgl9DQoNCglmdW5jdGlvbiBkZXNjcmlwdGlvbih0cmFrKSB7DQoJICBmb3IgKGNvbnN0IGVudHJ5IG9mIHRyYWsubWRpYS5taW5mLnN0Ymwuc3RzZC5lbnRyaWVzKSB7DQoJICAgIGNvbnN0IGJveCA9IGVudHJ5LmF2Y0MgfHwgZW50cnkuaHZjQyB8fCBlbnRyeS52cGNDIHx8IGVudHJ5LmF2MUM7DQoJICAgIGlmIChib3gpIHsNCgkgICAgICBjb25zdCBzdHJlYW0gPSBuZXcgbXA0Ym94X2FsbC5EYXRhU3RyZWFtKA0KCSAgICAgICAgdW5kZWZpbmVkLA0KCSAgICAgICAgMCwNCgkgICAgICAgIG1wNGJveF9hbGwuRGF0YVN0cmVhbS5CSUdfRU5ESUFODQoJICAgICAgKTsNCgkgICAgICBib3gud3JpdGUoc3RyZWFtKTsNCgkgICAgICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoc3RyZWFtLmJ1ZmZlciwgOCk7IC8vIFJlbW92ZSB0aGUgYm94IGhlYWRlci4NCgkgICAgfQ0KCSAgfQ0KCSAgdGhyb3cgbmV3IEVycm9yKCJhdmNDLCBodmNDLCB2cGNDLCBvciBhdjFDIGJveCBub3QgZm91bmQiKTsNCgl9DQoNCglzZWxmLmFkZEV2ZW50TGlzdGVuZXIoIm1lc3NhZ2UiLCAobWVzc2FnZSkgPT4gew0KCSAgaWYgKG1lc3NhZ2UuZGF0YS50eXBlID09PSAibHgiKSB7DQoJICAgIHNlbGYuTHggPSBtZXNzYWdlLmRhdGEubHg7DQoNCgkgICAgaWYgKCFtZXNzYWdlLmRhdGEubHgpIHsNCgkgICAgICBzZWxmLnBvc3RNZXNzYWdlKHsNCgkgICAgICAgIERhdGFUeXBlOiAibHgiLA0KCSAgICAgICAgRGF0YTogbWVyZ2VBbmREb3dubG9hZEJ1ZmZlcnMoTXA0SGVhcmRCdWZmZXIsIFNhdmVCdWZmZXIpLA0KCSAgICAgIH0pOw0KCSAgICB9DQoJICAgIHJldHVybjsNCgkgIH0NCgkgIHdzID0gbmV3IFdlYlNvY2tldChtZXNzYWdlLmRhdGEudXJsKTsNCgkgIHdzLmJpbmFyeVR5cGUgPSAiYXJyYXlidWZmZXIiOw0KCSAgd3Mub25vcGVuID0gV3NPcGVuOw0KCSAgd3Mub25jbG9zZSA9IFdzQ2xvc2U7DQoJICB3cy5vbmVycm9yID0gV3NFcnJvcjsNCgkgIHdzLm9ubWVzc2FnZSA9IFdzTWVzc2FnZTsNCgl9KTsNCg0KCWZ1bmN0aW9uIG1lcmdlQW5kRG93bmxvYWRCdWZmZXJzKGJ1ZmZlckFycmF5MSwgYnVmZmVyQXJyYXkyKSB7DQoJICAvLyDliJvlu7rkuIDkuKrmlrDnmoQgQXJyYXlCdWZmZXIg5p2l5a2Y5pS+5ZCI5bm25ZCO55qE5pWw5o2uDQoJICB2YXIgbWVyZ2VkQnVmZmVyID0gbmV3IFVpbnQ4QXJyYXkoTXA0SGVhcmRCdWZmZXJTaXplICsga1NhdmVCdWZmZXJTaXplKTsNCg0KCSAgLy8g6K6w5b2V5b2T5YmN5YaZ5YWl55qE5L2N572uDQoJICB2YXIgb2Zmc2V0ID0gMDsNCg0KCSAgLy8g5bCGIGJ1ZmZlckFycmF5MSDkuK3nmoTmr4/kuKogQXJyYXlCdWZmZXIg55qE5YaF5a655aSN5Yi25Yiw5paw55qEIEFycmF5QnVmZmVyIOS4rQ0KCSAgYnVmZmVyQXJyYXkxLmZvckVhY2goKGJ1ZmZlcikgPT4gew0KCSAgICBtZXJnZWRCdWZmZXIuc2V0KG5ldyBVaW50OEFycmF5KGJ1ZmZlciksIG9mZnNldCk7DQoJICAgIG9mZnNldCArPSBidWZmZXIuYnl0ZUxlbmd0aDsNCgkgIH0pOw0KDQoJICAvLyDlsIYgYnVmZmVyQXJyYXkyIOS4reeahOavj+S4qiBBcnJheUJ1ZmZlciDnmoTlhoXlrrnlpI3liLbliLDmlrDnmoQgQXJyYXlCdWZmZXIg5LitDQoJICBidWZmZXJBcnJheTIuZm9yRWFjaCgoYnVmZmVyKSA9PiB7DQoJICAgIG1lcmdlZEJ1ZmZlci5zZXQobmV3IFVpbnQ4QXJyYXkoYnVmZmVyKSwgb2Zmc2V0KTsNCgkgICAgb2Zmc2V0ICs9IGJ1ZmZlci5ieXRlTGVuZ3RoOw0KCSAgfSk7DQoJICBrU2F2ZUJ1ZmZlclNpemUgPSAwOw0KCSAgU2F2ZUJ1ZmZlciA9IFtdOw0KDQoJICByZXR1cm4gbmV3IEJsb2IoW21lcmdlZEJ1ZmZlcl0sIHsgdHlwZTogImFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbSIgfSk7DQoJfQoKfSkoKTsKLy8jIHNvdXJjZU1hcHBpbmdVUkw9R2V0VmlkZW9TdHJlYW1pbmcuanMubWFwCgo=");const w=new class{#l=null;#g={};#Z={};#J=[];#c=[];loaded=!1;#I=()=>{this.#l&&(this.#l.onmessage=({data:{id:l,type:g,data:Z}})=>{switch(g){case C.LOAD:this.loaded=!0,this.#g[l](Z);break;case C.MOUNT:case C.UNMOUNT:case C.EXEC:case C.WRITE_FILE:case C.READ_FILE:case C.DELETE_FILE:case C.RENAME:case C.CREATE_DIR:case C.LIST_DIR:case C.DELETE_DIR:this.#g[l](Z);break;case C.LOG:this.#J.forEach((C=>C(Z)));break;case C.PROGRESS:this.#c.forEach((C=>C(Z)));break;case C.ERROR:this.#Z[l](Z)}delete this.#g[l],delete this.#Z[l]})};#G=({type:C,data:Z},J=[],c)=>this.#l?new Promise(((g,I)=>{const G=l();this.#l&&this.#l.postMessage({id:G,type:C,data:Z},J),this.#g[G]=g,this.#Z[G]=I,c?.addEventListener("abort",(()=>{I(new DOMException(`Message # ${G} was aborted`,"AbortError"))}),{once:!0})})):Promise.reject(g);on(C,l){"log"===C?this.#J.push(l):"progress"===C&&this.#c.push(l)}off(C,l){"log"===C?this.#J=this.#J.filter((C=>C!==l)):"progress"===C&&(this.#c=this.#c.filter((C=>C!==l)))}load=({classWorkerURL:l,...g}={},{signal:Z}={})=>(this.#l||(this.#l=l?new Worker(new URL(l,import.meta.url).href,{type:"module"}):new Worker(new URL("./ffmpeg/worker.js",import.meta.url).href,{type:"module"}),this.#I()),this.#G({type:C.LOAD,data:g},void 0,Z));exec=(l,g=-1,{signal:Z}={})=>this.#G({type:C.EXEC,data:{args:l,timeout:g}},void 0,Z);terminate=()=>{const C=Object.keys(this.#Z);for(const l of C)this.#Z[l](Z),delete this.#Z[l],delete this.#g[l];this.#l&&(this.#l.terminate(),this.#l=null,this.loaded=!1)};writeFile=(l,g,{signal:Z}={})=>{const J=[];return g instanceof Uint8Array&&J.push(g.buffer),this.#G({type:C.WRITE_FILE,data:{path:l,data:g}},J,Z)};mount=(l,g,Z)=>this.#G({type:C.MOUNT,data:{fsType:l,options:g,mountPoint:Z}},[]);unmount=l=>this.#G({type:C.UNMOUNT,data:{mountPoint:l}},[]);readFile=(l,g="binary",{signal:Z}={})=>this.#G({type:C.READ_FILE,data:{path:l,encoding:g}},void 0,Z);deleteFile=(l,{signal:g}={})=>this.#G({type:C.DELETE_FILE,data:{path:l}},void 0,g);rename=(l,g,{signal:Z}={})=>this.#G({type:C.RENAME,data:{oldPath:l,newPath:g}},void 0,Z);createDir=(l,{signal:g}={})=>this.#G({type:C.CREATE_DIR,data:{path:l}},void 0,g);listDir=(l,{signal:g}={})=>this.#G({type:C.LIST_DIR,data:{path:l}},void 0,g);deleteDir=(l,{signal:g}={})=>this.#G({type:C.DELETE_DIR,data:{path:l}},void 0,g)};function L(C){function l(C){return C<10?"0"+C:C}return`${C.getFullYear()}${l(C.getMonth()+1)}${l(C.getDate())}${l(C.getHours())}${l(C.getMinutes())}${l(C.getSeconds())}${C.getMilliseconds()}`}async function e(C,l){const g={suggestedName:l,types:[{"image/png":["png"]}]},Z=await async function(C={}){if(d&&!C._preferPolyfill)return d(C);C._name&&(console.warn("deprecated _name, spec now have `suggestedName`"),C.suggestedName=C._name);const{FileSystemFileHandle:l}=await Promise.resolve().then((function(){return n})),{FileHandle:g}=await import("./Voo9FZRl.js");return new l(new g(C.suggestedName))}(g),J=await Z.createWritable();J.write(C),J.close()}function t(C,l,g=()=>{},Z){let J=document.querySelector(l);J=J.transferControlToOffscreen();const c=new A;c.addEventListener("message",(C=>{"img"===C.data.type?e(C.data.img,`${L(new Date)}.png`):g()}));const I=new z;var G="";return I.postMessage({url:C}),I.addEventListener("message",(async l=>{if("Opt"===l.data.DataType){G=l.data.data,c.postMessage({DataType:"Opt",data:l.data.data});let g="Start";c.postMessage({DataType:g,canvas:J,url:C,baseWH:Z?JSON.stringify(Z):null},[J])}if("Track"===l.data.DataType){let C="Track",g=l.data.track.codec.startsWith("vp08")?"vp8":l.data.track.codec,Z=l.data.track.video.height,J=l.data.track.video.width,I=l.data.tkinfo;c.postMessage({DataType:C,codec:g,codedHeight:Z,codedWidth:J,description:I})}if("Samples"===l.data.DataType){let C="Samples",g=l.data.sample.is_sync?"key":"delta",Z=1e6*l.data.sample.cts/l.data.sample.timescale,J=1e6*l.data.sample.duration/l.data.sample.timescale,I=l.data.sample.data,G=l.data.showData;c.postMessage({DataType:C,type:g,timestamp:Z,duration:J,data:I,showData:G})}if("lx"===l.data.DataType){w.on("log",(({message:C})=>{console.log(C)})),await w.writeFile("test.mp4",await m.fetchFile(l.data.Data)),w.exec(["-i","test.mp4","-c","copy","-metadata:s:v","rotate="+JSON.parse(G).Rotate,"out.mp4"]);const C=await w.readFile("out.mp4");w.deleteFile("test.mp4"),e(new Blob([C.buffer],{type:"video/mp4"}),`${L(new Date)}.mp4`),w.deleteFile("out.mp4")}})),{worker:c,WebSocketWork:I,close:()=>{I.terminate(),c.terminate()}}}(async()=>{await w.load({coreURL:await m.toBlobURL(new URL("./core/package/pkg/esm/ffmpeg-core.js",import.meta.url).href,"text/javascript"),wasmURL:await m.toBlobURL(new URL("./core/package/pkg/esm/ffmpeg-core.wasm",import.meta.url).href,"application/wasm")})})(),window.OmnimatrixVideoPayer=t;export{b as c,k as e,t as u};