This repository was archived by the owner on Jun 10, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmaplibre-gl-vector-text-protocol.min.js
More file actions
2 lines (2 loc) · 157 KB
/
maplibre-gl-vector-text-protocol.min.js
File metadata and controls
2 lines (2 loc) · 157 KB
1
2
!function(g,C){"object"==typeof exports&&"undefined"!=typeof module?C(exports):"function"==typeof define&&define.amd?define(["exports"],C):C((g="undefined"!=typeof globalThis?globalThis:g||self).VectorTextProtocol={})}(this,(function(g){"use strict";function C(g){return g&&g.__esModule&&Object.prototype.hasOwnProperty.call(g,"default")?g.default:g}function I(g){if(g.__esModule)return g;var C=g.default;if("function"==typeof C){var I=function g(){if(this instanceof g){var I=[null];return I.push.apply(I,arguments),new(Function.bind.apply(C,I))}return C.apply(this,arguments)};I.prototype=C.prototype}else I={};return Object.defineProperty(I,"__esModule",{value:!0}),Object.keys(g).forEach((function(C){var A=Object.getOwnPropertyDescriptor(g,C);Object.defineProperty(I,C,A.get?A:{enumerable:!0,get:function(){return g[C]}})})),I}function A(g){return new Function("d","return {"+g.map((function(g,C){return JSON.stringify(g)+": d["+C+"]"})).join(",")+"}")}function l(g){var C=new RegExp('["'+g+"\n]"),I=g.charCodeAt(0);function l(g,C){var A,l,b={},c={},o=[],Z=g.length,d=0,G=0;function s(){if(d>=Z)return c;if(l)return l=!1,b;var C,A=d;if(34===g.charCodeAt(A)){for(var o=A;o++<Z;)if(34===g.charCodeAt(o)){if(34!==g.charCodeAt(o+1))break;++o}return d=o+2,13===(C=g.charCodeAt(o+1))?(l=!0,10===g.charCodeAt(o+2)&&++d):10===C&&(l=!0),g.slice(A+1,o).replace(/""/g,'"')}for(;d<Z;){var G=1;if(10===(C=g.charCodeAt(d++)))l=!0;else if(13===C)l=!0,10===g.charCodeAt(d)&&(++d,++G);else if(C!==I)continue;return g.slice(A,d-G)}return g.slice(A)}for(;(A=s())!==c;){for(var e=[];A!==b&&A!==c;)e.push(A),A=s();C&&null==(e=C(e,G++))||o.push(e)}return o}function b(C){return C.map(c).join(g)}function c(g){return null==g?"":C.test(g+="")?'"'+g.replace(/\"/g,'""')+'"':g}return{parse:function(g,C){var I,b,c=l(g,(function(g,l){if(I)return I(g,l-1);b=g,I=C?function(g,C){var I=A(g);return function(A,l){return C(I(A),l,g)}}(g,C):A(g)}));return c.columns=b,c},parseRows:l,format:function(C,I){return null==I&&(I=function(g){var C=Object.create(null),I=[];return g.forEach((function(g){for(var A in g)A in C||I.push(C[A]=A)})),I}(C)),[I.map(c).join(g)].concat(C.map((function(C){return I.map((function(g){return c(C[g])})).join(g)}))).join("\n")},formatRows:function(g){return g.map(b).join("\n")}}}var b=l(","),c=b.parse,o=b.parseRows,Z=b.format,d=b.formatRows,G=l("\t"),s=G.parse,e=G.parseRows,n=G.format,t=G.formatRows,m=I(Object.freeze({__proto__:null,dsvFormat:l,csvParse:c,csvParseRows:o,csvFormat:Z,csvFormatRows:d,tsvParse:s,tsvParseRows:e,tsvFormat:n,tsvFormatRows:t})),B={exports:{}};function i(g,C){var I=W(g,C);return I.whole+"° "+(I.minutes?I.minutes+"' ":"")+(I.seconds?I.seconds+'" ':"")+I.dir}function W(g,C){var I=({lat:["N","S"],lon:["E","W"]}[C]||"")[g>=0?0:1],A=Math.abs(g),l=Math.floor(A),b=60*(A-l),c=Math.floor(b);return{whole:l,minutes:c,seconds:Math.floor(60*(b-c)),dir:I}}function J(g,C){if(C||(C="NSEW"),"string"!=typeof g)return null;var I=(g=g.toUpperCase()).match(/^[\s\,]*([NSEW])?\s*([\-|\—|\―]?[0-9.]+)[°º˚]?\s*(?:([0-9.]+)['’′‘]\s*)?(?:([0-9.]+)(?:''|"|”|″)\s*)?([NSEW])?/);if(!I)return null;var A,l=I[0];if(I[1]&&I[5]?(A=I[1],l=l.slice(0,-1)):A=I[1]||I[5],A&&-1===C.indexOf(A))return null;var b=I[2]?parseFloat(I[2]):0,c=I[3]?parseFloat(I[3])/60:0,o=I[4]?parseFloat(I[4])/3600:0,Z=b<0?-1:1;return"S"!==A&&"W"!==A||(Z*=-1),{val:(Math.abs(b)+c+o)*Z,dim:A,matched:l,remain:g.slice(l.length)}}B.exports=function(g,C){var I=J(g,C);return null===I?null:I.val},B.exports.pair=function(g,C){var I=J(g=g.trim(),C);if(!I)return null;var A=J(g=I.remain.trim(),C);if(!A||A.remain)return null;return I.dim?function(g,C,I){if("N"===I||"S"===I)return[g,C];if("W"===I||"E"===I)return[C,g]}(I.val,A.val,I.dim):[I.val,A.val]},B.exports.format=i,B.exports.formatPair=function(g){return i(g.lat,"lat")+" "+i(g.lon,"lon")},B.exports.coordToDMS=W;var a=B.exports,S=m,K=a,k=/(Lat)(itude)?/gi,u=/(L)(on|ng)(gitude)?/i;function h(g,C){var I,A,l;for(var b in g)(A=b.match(C))&&(!I||A[0].length/b.length>l)&&(l=A[0].length/b.length,I=b);return I}function y(g){return h(g,k)}function V(g){return h(g,u)}function X(g){return"object"==typeof g?Object.keys(g).length:0}function p(g){var C=[];return[",",";","\t","|"].forEach((function(I){var A=S.dsvFormat(I).parse(g);if(A.length>=1){for(var l=X(A[0]),b=0;b<A.length;b++)if(X(A[b])!==l)return;C.push({delimiter:I,arity:Object.keys(A[0]).length})}})),C.length?C.sort((function(g,C){return C.arity-g.arity}))[0].delimiter:null}var H={isLon:function(g){return!!g.match(u)},isLat:function(g){return!!g.match(k)},guessLatHeader:y,guessLonHeader:V,csv:S.csvParse,tsv:S.tsvParse,dsv:S,auto:function(g){var C=p(g);return C?function(g){return delete g.columns,g}(S.dsvFormat(C).parse(g)):null},csv2geojson:function(g,C,I){I||(I=C,C={}),C.delimiter=C.delimiter||",";var A=C.latfield||"",l=C.lonfield||"",b=C.crs||"",c=[],o={type:"FeatureCollection",features:c};if(""!==b&&(o.crs={type:"name",properties:{name:b}}),"auto"!==C.delimiter||"string"!=typeof g||(C.delimiter=p(g),C.delimiter)){var Z=C.numericFields?C.numericFields.split(","):null,d="string"==typeof g?S.dsvFormat(C.delimiter).parse(g,(function(g){if(Z)for(var C in g)Z.includes(C)&&(g[C]=+g[C]);return g})):g;if(d.length){var G,s=[];if(A||(A=y(d[0])),l||(l=V(d[0])),!A||!l){for(G=0;G<d.length;G++)c.push({type:"Feature",properties:d[G],geometry:null});I(s.length?s:null,o)}else{for(G=0;G<d.length;G++)if(void 0!==d[G][l]&&void 0!==d[G][A]){var e,n,t,m=d[G][l],B=d[G][A];(t=K(m,"EW"))&&(m=t),(t=K(B,"NS"))&&(B=t),e=parseFloat(m),n=parseFloat(B),isNaN(e)||isNaN(n)?s.push({message:"A row contained an invalid value for latitude or longitude",row:d[G],index:G}):(C.includeLatLon||(delete d[G][l],delete d[G][A]),c.push({type:"Feature",properties:d[G],geometry:{type:"Point",coordinates:[parseFloat(e),parseFloat(n)]}}))}I(s.length?s:null,o)}}else I(null,o)}else I({type:"Error",message:"Could not autodetect delimiter"})},toLine:function(g){for(var C=g.features,I={type:"Feature",geometry:{type:"LineString",coordinates:[]}},A=0;A<C.length;A++)I.geometry.coordinates.push(C[A].geometry.coordinates);return I.properties=C.reduce((function(g,C){for(var I in C.properties)g[I]||(g[I]=[]),g[I].push(C.properties[I]);return g}),{}),{type:"FeatureCollection",features:[I]}},toPolygon:function(g){for(var C=g.features,I={type:"Feature",geometry:{type:"Polygon",coordinates:[[]]}},A=0;A<C.length;A++)I.geometry.coordinates[0].push(C[A].geometry.coordinates);return I.properties=C.reduce((function(g,C){for(var I in C.properties)g[I]||(g[I]=[]),g[I].push(C.properties[I]);return g}),{}),{type:"FeatureCollection",features:[I]}}};function Y(g){return g}function R(g,C){var I=C.id,A=C.bbox,l=null==C.properties?{}:C.properties,b=function(g,C){var I=function(g){if(null==g)return Y;var C,I,A=g.scale[0],l=g.scale[1],b=g.translate[0],c=g.translate[1];return function(g,o){o||(C=I=0);var Z=2,d=g.length,G=new Array(d);for(G[0]=(C+=g[0])*A+b,G[1]=(I+=g[1])*l+c;Z<d;)G[Z]=g[Z],++Z;return G}}(g.transform),A=g.arcs;function l(g,C){C.length&&C.pop();for(var l=A[g<0?~g:g],b=0,c=l.length;b<c;++b)C.push(I(l[b],b));g<0&&function(g,C){for(var I,A=g.length,l=A-C;l<--A;)I=g[l],g[l++]=g[A],g[A]=I}(C,c)}function b(g){return I(g)}function c(g){for(var C=[],I=0,A=g.length;I<A;++I)l(g[I],C);return C.length<2&&C.push(C[0]),C}function o(g){for(var C=c(g);C.length<4;)C.push(C[0]);return C}function Z(g){return g.map(o)}function d(g){var C,I=g.type;switch(I){case"GeometryCollection":return{type:I,geometries:g.geometries.map(d)};case"Point":C=b(g.coordinates);break;case"MultiPoint":C=g.coordinates.map(b);break;case"LineString":C=c(g.arcs);break;case"MultiLineString":C=g.arcs.map(c);break;case"Polygon":C=Z(g.arcs);break;case"MultiPolygon":C=g.arcs.map(Z);break;default:return null}return{type:I,coordinates:C}}return d(C)}(g,C);return null==I&&null==A?{type:"Feature",properties:l,geometry:b}:null==A?{type:"Feature",id:I,properties:l,geometry:b}:{type:"Feature",id:I,bbox:A,properties:l,geometry:b}}function r(g,C){return Array.from(g.getElementsByTagName(C))}function w(g){return"#"===g[0]?g:`#${g}`}function v(g){return g?.normalize(),g&&g.textContent||""}function F(g,C,I){const A=g.getElementsByTagName(C),l=A.length?A[0]:null;return l&&I&&I(l),l}function N(g,C,I){const A={};if(!g)return A;const l=g.getElementsByTagName(C),b=l.length?l[0]:null;return b&&I?I(b,A):A}function z(g,C,I){const A=v(F(g,C));return A&&I&&I(A)||{}}function L(g,C,I){const A=parseFloat(v(F(g,C)));if(!isNaN(A))return A&&I&&I(A)||{}}function f(g,C,I){const A=parseFloat(v(F(g,C)));if(!isNaN(A))return A&&I&&I(A),A}function x(g,C){const I={};for(const A of C)z(g,A,(g=>{I[A]=g}));return I}function Q(g){return 1===g?.nodeType}function T(g){return N(g,"line",(g=>Object.assign({},z(g,"color",(g=>({stroke:`#${g}`}))),L(g,"opacity",(g=>({"stroke-opacity":g}))),L(g,"width",(g=>({"stroke-width":96*g/25.4}))))))}function U(g){let C=[];if(null===g)return C;for(const I of Array.from(g.childNodes)){if(!Q(I))continue;const g=M(I.nodeName);if("gpxtpx:TrackPointExtension"===g)C=C.concat(U(I));else{const A=v(I);C.push([g,O(A)])}}return C}function M(g){return["heart","gpxtpx:hr","hr"].includes(g)?"heart":g}function O(g){const C=parseFloat(g);return isNaN(C)?g:C}function j(g){const C=[parseFloat(g.getAttribute("lon")||""),parseFloat(g.getAttribute("lat")||"")];if(isNaN(C[0])||isNaN(C[1]))return null;f(g,"ele",(g=>{C.push(g)}));const I=F(g,"time");return{coordinates:C,time:I?v(I):null,extendedValues:U(F(g,"extensions"))}}function D(g){const C=x(g,["name","cmt","desc","type","time","keywords"]),I=Array.from(g.getElementsByTagNameNS("http://www.garmin.com/xmlschemas/GpxExtensions/v3","*"));for(const A of I)A.parentNode?.parentNode===g&&(C[A.tagName.replace(":","_")]=v(A));const A=r(g,"link");return A.length&&(C.links=A.map((g=>Object.assign({href:g.getAttribute("href")},x(g,["text","type"]))))),C}function P(g,C){const I=r(g,C),A=[],l=[],b={};for(let g=0;g<I.length;g++){const C=j(I[g]);if(C){A.push(C.coordinates),C.time&&l.push(C.time);for(const[A,l]of C.extendedValues){const C="heart"===A?A:A.replace("gpxtpx:","")+"s";b[C]||(b[C]=Array(I.length).fill(null)),b[C][g]=l}}}if(!(A.length<2))return{line:A,times:l,extendedValues:b}}function E(g){const C=P(g,"rtept");if(C)return{type:"Feature",properties:Object.assign({_gpxType:"rte"},D(g),T(F(g,"extensions"))),geometry:{type:"LineString",coordinates:C.line}}}function q(g){const C=r(g,"trkseg"),I=[],A=[],l=[];for(const g of C){const C=P(g,"trkpt");C&&(l.push(C),C.times&&C.times.length&&A.push(C.times))}if(0===l.length)return null;const b=l.length>1,c=Object.assign({_gpxType:"trk"},D(g),T(F(g,"extensions")),A.length?{coordinateProperties:{times:b?A:A[0]}}:{});for(const g of l){I.push(g.line),c.coordinateProperties||(c.coordinateProperties={});const C=c.coordinateProperties,A=Object.entries(g.extendedValues);for(let g=0;g<A.length;g++){const[I,c]=A[g];b?(C[I]||(C[I]=l.map((g=>new Array(g.line.length).fill(null)))),C[I][g]=c):C[I]=c}}return{type:"Feature",properties:c,geometry:b?{type:"MultiLineString",coordinates:I}:{type:"LineString",coordinates:I[0]}}}function _(g){const C=Object.assign(D(g),x(g,["sym"])),I=j(g);return I?{type:"Feature",properties:C,geometry:{type:"Point",coordinates:I.coordinates}}:null}function*$(g){for(const C of r(g,"trk")){const g=q(C);g&&(yield g)}for(const C of r(g,"rte")){const g=E(C);g&&(yield g)}for(const C of r(g,"wpt")){const g=_(C);g&&(yield g)}}const gg="http://www.garmin.com/xmlschemas/ActivityExtension/v2",Cg=[["heartRate","heartRates"],["Cadence","cadences"],["Speed","speeds"],["Watts","watts"]],Ig=[["TotalTimeSeconds","totalTimeSeconds"],["DistanceMeters","distanceMeters"],["MaximumSpeed","maxSpeed"],["AverageHeartRateBpm","avgHeartRate"],["MaximumHeartRateBpm","maxHeartRate"],["AvgSpeed","avgSpeed"],["AvgWatts","avgWatts"],["MaxWatts","maxWatts"]];function Ag(g,C){const I=[];for(const[A,l]of C){let C=F(g,A);if(!C){const I=g.getElementsByTagNameNS(gg,A);I.length&&(C=I[0])}const b=parseFloat(v(C));isNaN(b)||I.push([l,b])}return I}function lg(g){const C=[f(g,"LongitudeDegrees"),f(g,"LatitudeDegrees")];if(void 0===C[0]||isNaN(C[0])||void 0===C[1]||isNaN(C[1]))return null;const I=F(g,"HeartRateBpm"),A=v(F(g,"Time"));return F(g,"AltitudeMeters",(g=>{const I=parseFloat(v(g));isNaN(I)||C.push(I)})),{coordinates:C,time:A||null,heartRate:I?parseFloat(v(I)):null,extensions:Ag(g,Cg)}}function bg(g){const C=r(g,"Trackpoint"),I=[],A=[],l=[];if(C.length<2)return null;const b={},c={extendedProperties:b};for(let g=0;g<C.length;g++){const c=lg(C[g]);if(null===c)continue;I.push(c.coordinates);const{time:o,heartRate:Z,extensions:d}=c;o&&A.push(o),Z&&l.push(Z);for(const[I,A]of d)b[I]||(b[I]=Array(C.length).fill(null)),b[I][g]=A}return I.length<2?null:Object.assign(c,{line:I,times:A,heartRates:l})}function cg(g){const C=r(g,"Track"),I=[],A=[],l=[],b=[];let c;const o=Object.assign(Object.fromEntries(Ag(g,Ig)),N(g,"Name",(g=>({name:v(g)}))));for(const g of C)c=bg(g),c&&(I.push(c.line),c.times.length&&A.push(c.times),c.heartRates.length&&l.push(c.heartRates),b.push(c.extendedProperties));for(let g=0;g<b.length;g++){const A=b[g];for(const l in A)1===C.length?c&&(o[l]=c.extendedProperties[l]):(o[l]||(o[l]=I.map((g=>Array(g.length).fill(null)))),o[l][g]=A[l])}return 0===I.length?null:((A.length||l.length)&&(o.coordinateProperties=Object.assign(A.length?{times:1===I.length?A[0]:A}:{},l.length?{heart:1===I.length?l[0]:l}:{})),{type:"Feature",properties:o,geometry:1===I.length?{type:"LineString",coordinates:I[0]}:{type:"MultiLineString",coordinates:I}})}function*og(g){for(const C of r(g,"Lap")){const g=cg(C);g&&(yield g)}for(const C of r(g,"Courses")){const g=cg(C);g&&(yield g)}}function Zg(g,C){const I={},A="stroke"==C||"fill"===C?C:C+"-color";return"#"===g[0]&&(g=g.substring(1)),6===g.length||3===g.length?I[A]="#"+g:8===g.length&&(I[C+"-opacity"]=parseInt(g.substring(0,2),16)/255,I[A]="#"+g.substring(6,8)+g.substring(4,6)+g.substring(2,4)),I}function dg(g,C,I){const A={};return f(g,C,(g=>{A[I]=g})),A}function Gg(g,C){return N(g,"color",(g=>Zg(v(g),C)))}function sg(g){return N(g,"Icon",((g,C)=>(z(g,"href",(g=>{C.icon=g})),C)))}function eg(g){return Object.assign({},function(g){return N(g,"PolyStyle",((g,C)=>Object.assign(C,N(g,"color",(g=>Zg(v(g),"fill"))),z(g,"fill",(g=>{if("0"===g)return{"fill-opacity":0}})),z(g,"outline",(g=>{if("0"===g)return{"stroke-opacity":0}})))))}(g),function(g){return N(g,"LineStyle",(g=>Object.assign(Gg(g,"stroke"),dg(g,"width","stroke-width"))))}(g),function(g){return N(g,"LabelStyle",(g=>Object.assign(Gg(g,"label"),dg(g,"scale","label-scale"))))}(g),function(g){return N(g,"IconStyle",(g=>Object.assign(Gg(g,"icon"),dg(g,"scale","icon-scale"),dg(g,"heading","icon-heading"),N(g,"hotSpot",(g=>{const C=parseFloat(g.getAttribute("x")||""),I=parseFloat(g.getAttribute("y")||""),A=g.getAttribute("xunits")||"",l=g.getAttribute("yunits")||"";return isNaN(C)||isNaN(I)?{}:{"icon-offset":[C,I],"icon-offset-units":[A,l]}})),sg(g))))}(g))}const ng=g=>Number(g),tg={string:g=>g,int:ng,uint:ng,short:ng,ushort:ng,float:ng,double:ng,bool:g=>Boolean(g)};function mg(g,C){return N(g,"ExtendedData",((g,I)=>{for(const C of r(g,"Data"))I[C.getAttribute("name")||""]=v(F(C,"value"));for(const A of r(g,"SimpleData")){const g=A.getAttribute("name")||"",l=C[g]||tg.string;I[g]=l(v(A))}return I}))}function Bg(g){const C=F(g,"description");for(const g of Array.from(C?.childNodes||[]))if(4===g.nodeType)return{description:{"@type":"html",value:v(g)}};return{}}function ig(g){return N(g,"TimeSpan",(g=>({timespan:{begin:v(F(g,"begin")),end:v(F(g,"end"))}})))}function Wg(g){return N(g,"TimeStamp",(g=>({timestamp:v(F(g,"when"))})))}function Jg(g,C){return z(g,"styleUrl",(g=>(g=w(g),C[g]?Object.assign({styleUrl:g},C[g]):{styleUrl:g})))}const ag=/\s*/g,Sg=/^\s*|\s*$/g,Kg=/\s+/;function kg(g){return g.replace(ag,"").split(",").map(parseFloat).filter((g=>!isNaN(g))).slice(0,3)}function ug(g){return g.replace(Sg,"").split(Kg).map(kg).filter((g=>g.length>=2))}function hg(g){let C=r(g,"coord");0===C.length&&(C=function(g,C,I){return Array.from(g.getElementsByTagNameNS(I,C))}(g,"coord","*"));const I=C.map((g=>v(g).split(" ").map(parseFloat)));return 0===I.length?null:{geometry:I.length>2?{type:"LineString",coordinates:I}:{type:"Point",coordinates:I[0]},times:r(g,"when").map((g=>v(g)))}}function yg(g){if(0===g.length)return g;const C=g[0],I=g[g.length-1];let A=!0;for(let g=0;g<Math.max(C.length,I.length);g++)if(C[g]!==I[g]){A=!1;break}return A?g:g.concat([g[0]])}function Vg(g){return v(F(g,"coordinates"))}function Xg(g){let C=[],I=[];for(let A=0;A<g.childNodes.length;A++){const l=g.childNodes.item(A);if(Q(l))switch(l.tagName){case"MultiGeometry":case"MultiTrack":case"gx:MultiTrack":{const g=Xg(l);C=C.concat(g.geometries),I=I.concat(g.coordTimes);break}case"Point":{const g=kg(Vg(l));g.length>=2&&C.push({type:"Point",coordinates:g});break}case"LinearRing":case"LineString":{const g=ug(Vg(l));g.length>=2&&C.push({type:"LineString",coordinates:g});break}case"Polygon":{const g=[];for(const C of r(l,"LinearRing")){const I=yg(ug(Vg(C)));I.length>=4&&g.push(I)}g.length&&C.push({type:"Polygon",coordinates:g});break}case"Track":case"gx:Track":{const g=hg(l);if(!g)break;const{times:A,geometry:b}=g;C.push(b),A.length&&I.push(A);break}}}return{geometries:C,coordTimes:I}}function pg(g){return 0===g.length?null:1===g.length?g[0]:{type:"GeometryCollection",geometries:g}}function Hg(g,C,I){const{coordTimes:A,geometries:l}=Xg(g),b={type:"Feature",geometry:pg(l),properties:Object.assign(x(g,["name","address","visibility","open","phoneNumber","description"]),Bg(g),Jg(g,C),eg(g),mg(g,I),ig(g),Wg(g),A.length?{coordinateProperties:{times:1===A.length?A[0]:A}}:{})};void 0!==b.properties?.visibility&&(b.properties.visibility="0"!==b.properties.visibility);const c=g.getAttribute("id");return null!==c&&""!==c&&(b.id=c),b}function Yg(g){if(F(g,"gx:LatLonQuad")){return{type:"Polygon",coordinates:[yg(ug(Vg(g)))]}}return function(g){const C=F(g,"LatLonBox");if(C){const g=f(C,"north"),I=f(C,"west"),A=f(C,"east"),l=f(C,"south"),b=f(C,"rotation");if("number"==typeof g&&"number"==typeof l&&"number"==typeof I&&"number"==typeof A){let C=[[[I,g],[A,g],[A,l],[I,l],[I,g]]];return"number"==typeof b&&(C=function(g,C,I){const A=[(g[0]+g[2])/2,(g[1]+g[3])/2];return[C[0].map((g=>{const C=g[1]-A[1],l=g[0]-A[0],b=Math.sqrt(Math.pow(C,2)+Math.pow(l,2)),c=Math.atan2(C,l)-I*Rg;return[A[0]+Math.cos(c)*b,A[1]+Math.sin(c)*b]}))]}([I,l,A,g],C,b)),{type:"Polygon",coordinates:C}}}return null}(g)}const Rg=Math.PI/180;function rg(g,C,I){const A={type:"Feature",geometry:Yg(g),properties:Object.assign({"@geometry-type":"groundoverlay"},x(g,["name","address","visibility","open","phoneNumber","description"]),Bg(g),Jg(g,C),eg(g),sg(g),mg(g,I),ig(g),Wg(g))};void 0!==A.properties?.visibility&&(A.properties.visibility="0"!==A.properties.visibility);const l=g.getAttribute("id");return null!==l&&""!==l&&(A.id=l),A}function wg(g){let C=g.getAttribute("id");const I=g.parentNode;return!C&&Q(I)&&"CascadingStyle"===I.localName&&(C=I.getAttribute("kml:id")||I.getAttribute("id")),w(C||"")}function vg(g){const C={};for(const I of r(g,"Style"))C[wg(I)]=eg(I);for(const I of r(g,"StyleMap")){const g=w(I.getAttribute("id")||"");z(I,"styleUrl",(I=>{I=w(I),C[I]&&(C[g]=C[I])}))}return C}function Fg(g){const C={};for(const I of r(g,"SimpleField"))C[I.getAttribute("name")||""]=tg[I.getAttribute("type")||""]||tg.string;return C}const Ng=["name","visibility","open","address","description","phoneNumber","visibility"];function*zg(g){const C=vg(g),I=Fg(g);for(const A of r(g,"Placemark")){const g=Hg(A,C,I);g&&(yield g)}for(const A of r(g,"GroundOverlay")){const g=rg(A,C,I);g&&(yield g)}}var Lg=Object.freeze({__proto__:null,gpx:function(g){return{type:"FeatureCollection",features:Array.from($(g))}},gpxGen:$,kml:function(g){return{type:"FeatureCollection",features:Array.from(zg(g))}},kmlGen:zg,kmlWithFolders:function(g){const C=vg(g),I=Fg(g),A={type:"root",children:[]};return function g(A,l){if(Q(A))switch(A.tagName){case"GroundOverlay":{const g=rg(A,C,I);g&&l.children.push(g);break}case"Placemark":{const g=Hg(A,C,I);g&&l.children.push(g);break}case"Folder":{const g=function(g){const C={};for(const I of Array.from(g.childNodes))Q(I)&&Ng.includes(I.tagName)&&(C[I.tagName]=v(I));return{type:"folder",meta:C,children:[]}}(A);l.children.push(g),l=g;break}}if(A.childNodes)for(let C=0;C<A.childNodes.length;C++)g(A.childNodes[C],l)}(g,A),A},tcx:function(g){return{type:"FeatureCollection",features:Array.from(og(g))}},tcxGen:og}),fg=(()=>{const g=g=>g[0],C=g=>g[g.length-1],I=g=>g.join(","),A=(g,C,I)=>{let A=g[C];A?A.push(I):g[C]=[I]},l=(g,C,I)=>{let A=g[C],l=null;A&&(l=A.indexOf(I))>=0&&A.splice(l,1)},b=(g,C)=>{let I=g[C];return I&&I.length>0?I[0]:null},c=A=>A.length>3&&I(g(A))===I(C(A)),o=(g,C,I)=>{C=C||0,I=I||1;let A=g.reduce(((I,A,l)=>g[I][C]>A[C]?I:l),0),l=A<=0?g.length-2:A-1,b=A>=g.length-1?1:A+1,c=g[l][C],o=g[A][C],Z=g[b][C],d=g[l][I],G=g[A][I];return(o-c)*(g[b][I]-d)-(Z-c)*(G-d)<0?"clockwise":"counterclockwise"},Z=g=>g instanceof Array?g.map(Z):parseFloat(g);class d extends Map{constructor(){super(),this.binders=[]}add(g,C){this.has(g)||this.set(g,C)}addBinder(g){this.binders.push(g)}bindAll(){this.binders.forEach((g=>g.bind()))}}return{purgeProps:(g,C)=>{if(g){let I=Object.assign({},g);if(C)for(let g of C)delete I[g];return I}return{}},mergeProps:(g,C)=>(g=g||{},C=C||{},Object.assign(g,C)),first:g,last:C,coordsToKey:I,addToMap:A,removeFromMap:l,getFirstFromMap:b,isRing:c,ringDirection:o,ptInsidePolygon:(g,C,I,A)=>{I=I||0,A=A||1;let l=!1;for(let b=0,c=C.length-1;b<C.length;c=b++)(C[b][I]<=g[I]&&g[I]<C[c][I]||C[c][I]<=g[I]&&g[I]<C[b][I])&&g[A]<(C[c][A]-C[b][A])*(g[I]-C[b][I])/(C[c][I]-C[b][I])+C[b][A]&&(l=!l);return l},strToFloat:Z,RefElements:d,LateBinder:class{constructor(g,C,I,A){this.container=g,this.valueFunc=C,this.ctx=I,this.args=A}bind(){let g=this.valueFunc.apply(this.ctx,this.args);if(this.container instanceof Array){let C=this.container.indexOf(this);if(C>=0){let I=[C,1];g&&I.push(g),[].splice.apply(this.container,I)}}else if("object"==typeof this.container){let C=Object.keys(this.container).find((g=>this.container[g]===this));C&&(g?this.container[C]=g:delete this.container[C])}}},WayCollection:class extends Array{constructor(){super(),this.firstMap={},this.lastMap={}}addWay(l){(l=l.toCoordsArray()).length>0&&(this.push(l),A(this.firstMap,I(g(l)),l),A(this.lastMap,I(C(l)),l))}toStrings(){let A=[],c=null;for(;c=this.shift();){l(this.firstMap,I(g(c)),c),l(this.lastMap,I(C(c)),c);let o=c,d=null;do{let A=I(C(o)),c=!1;d=b(this.firstMap,A),d||(d=b(this.lastMap,A),c=!0),d&&(this.splice(this.indexOf(d),1),l(this.firstMap,I(g(d)),d),l(this.lastMap,I(C(d)),d),c&&(d.length>o.length&&([o,d]=[d,o]),d.reverse()),o=o.concat(d.slice(1)))}while(d);A.push(Z(o))}return A}toRings(g){let C=this.toStrings(),I=[],A=null;for(;A=C.shift();)c(A)&&(o(A)!==g&&A.reverse(),I.push(A));return I}}}})(),xg={building:{},highway:{whitelist:["services","rest_area","escape","elevator"]},natural:{blacklist:["coastline","cliff","ridge","arete","tree_row"]},landuse:{},waterway:{whitelist:["riverbank","dock","boatyard","dam"]},amenity:{},leisure:{},barrier:{whitelist:["city_wall","ditch","hedge","retaining_wall","wall","spikes"]},railway:{whitelist:["station","turntable","roundhouse","platform"]},area:{},boundary:{},man_made:{blacklist:["cutline","embankment","pipeline"]},power:{whitelist:["plant","substation","generator","transformer"]},place:{},shop:{},aeroway:{blacklist:["taxiway"]},tourism:{},historic:{},public_transport:{},office:{},"building:part":{},military:{},ruins:{},"area:highway":{},craft:{},golf:{},indoor:{}},Qg=(()=>{const{first:g,last:C,coordsToKey:I,addToMap:A,removeFromMap:l,getFirstFromMap:b,isRing:c,ringDirection:o,ptInsidePolygon:Z,strToFloat:d,LateBinder:G,WayCollection:s}=fg,e=xg;class n{constructor(g,C,I){this.type=g,this.id=C,this.refElems=I,this.tags={},this.props={id:this.getCompositeId()},this.refCount=0,this.hasTag=!1,I&&I.add(this.getCompositeId(),this)}addTags(g){this.tags=Object.assign(this.tags,g),this.hasTag=!!g}addTag(g,C){this.tags[g]=C,this.hasTag=!!g}addProp(g,C){this.props[g]=C}addProps(g){this.props=Object.assign(this.props,g)}getCompositeId(){return`${this.type}/${this.id}`}getProps(){return Object.assign(this.props,this.tags)}toFeatureArray(){return[]}}class t extends n{constructor(g,C){super("node",g,C),this.latLng=null}setLatLng(g){this.latLng=g}toFeatureArray(){return this.latLng?[{type:"Feature",id:this.getCompositeId(),properties:this.getProps(),geometry:{type:"Point",coordinates:d([this.latLng.lon,this.latLng.lat])}}]:[]}getLatLng(){return this.latLng}}class m extends n{constructor(g,C){super("way",g,C),this.latLngArray=[],this.isPolygon=!1}addLatLng(g){this.latLngArray.push(g)}setLatLngArray(g){this.latLngArray=g}addNodeRef(g){let C=new G(this.latLngArray,(function(g){let C=this.refElems.get(`node/${g}`);if(C)return C.refCount++,C.getLatLng()}),this,[g]);this.latLngArray.push(C),this.refElems.addBinder(C)}analyzeTag(g,C){let I=e[g];I&&(this.isPolygon=!0,I.whitelist?this.isPolygon=I.whitelist.indexOf(C)>=0:I.blacklist&&(this.isPolygon=!(I.blacklist.indexOf(C)>=0)))}addTags(g){super.addTags(g);for(let[C,I]of Object.entries(g))this.analyzeTag(C,I)}addTag(g,C){super.addTag(g,C),this.analyzeTag(g,C)}toCoordsArray(){return this.latLngArray.map((g=>[g.lon,g.lat]))}toFeatureArray(){let g=this.toCoordsArray();if(g.length>1){g=d(g);let C={type:"Feature",id:this.getCompositeId(),properties:this.getProps(),geometry:{type:"LineString",coordinates:g}};return this.isPolygon&&c(g)?("counterclockwise"!==o(g)&&g.reverse(),C.geometry={type:"Polygon",coordinates:[g]},[C]):[C]}return[]}}return{Node:t,Way:m,Relation:class extends n{constructor(g,C){super("relation",g,C),this.relations=[],this.nodes=[],this.bounds=null}setBounds(g){this.bounds=g}addMember(g){switch(g.type){case"relation":let C=new G(this.relations,(function(g){let C=this.refElems.get(`relation/${g}`);if(C)return C.refCount++,C}),this,[g.ref]);this.relations.push(C),this.refElems.addBinder(C);break;case"way":g.role||(g.role="");let I=this[g.role];if(I||(I=this[g.role]=[]),g.geometry){let C=new m(g.ref,this.refElems);C.setLatLngArray(g.geometry),C.refCount++,I.push(C)}else if(g.nodes){let C=new m(g.ref,this.refElems);for(let I of g.nodes)C.addNodeRef(I);C.refCount++,I.push(C)}else{let C=new G(I,(function(g){let C=this.refElems.get(`way/${g}`);if(C)return C.refCount++,C}),this,[g.ref]);I.push(C),this.refElems.addBinder(C)}break;case"node":let A=null;if(g.lat&&g.lon){A=new t(g.ref,this.refElems),A.setLatLng({lon:g.lon,lat:g.lat}),g.tags&&A.addTags(g.tags);for(let[C,I]of Object.entries(g))["id","type","lat","lon"].indexOf(C)<0&&A.addProp(C,I);A.refCount++,this.nodes.push(A)}else{let C=new G(this.nodes,(function(g){let C=this.refElems.get(`node/${g}`);if(C)return C.refCount++,C}),this,[g.ref]);this.nodes.push(C),this.refElems.addBinder(C)}}}toFeatureArray(){let C=[],I=[],A=[];const l=["outer","inner",""];for(let g of this.relations)if(g)for(let C of l){let I=g[C];if(I){let g=this[C];g?[].splice.apply(g,[g.length,0].concat(I)):this[C]=I}}for(let g of l){let C=this[g];if(C){this[g]=new s;for(let I of C)this[g].addWay(I)}}let b=null,c={type:"Feature",id:this.getCompositeId(),bbox:this.bounds,properties:this.getProps()};this.bounds||delete c.bbox,this.outer?(b=((C,I)=>{let A=C?C.toRings("counterclockwise"):[],l=I?I.toRings("clockwise"):[];if(A.length>0){let C=[],I=null;for(I of A)C.push([I]);for(;I=l.shift();)for(let l in A)if(Z(g(I),A[l])){C[l].push(I);break}return 1===C.length?{type:"Polygon",coordinates:C[0]}:{type:"MultiPolygon",coordinates:C}}return null})(this.outer,this.inner),b&&(c.geometry=b,C.push(c))):this[""]&&(b=(g=>{let C=g?g.toStrings():[];return C.length>0?1===C.length?{type:"LineString",coordinates:C[0]}:{type:"MultiLineString",coordinates:C}:null})(this[""]),b&&(c.geometry=b,I.push(c)));for(let g of this.nodes)A=A.concat(g.toFeatureArray());return C.concat(I).concat(A)}}}})(),Tg=(()=>{function g(g){return null!=g.match(/^(.+?)\[(.+?)\]>$/g)}function C(g){let C=/^(.+?)\[(.+?)\]>$/g.exec(g);return C?{evt:C[1]+">",exp:C[2]}:{evt:g}}return class{constructor(g){g&&(this.queryParent=!!g.queryParent,this.progressive=g.progressive,this.queryParent&&(this.parentMap=new WeakMap)),this.evtListeners={}}parse(g,C,I){I=I?I+".":"";let A=/<([^ >\/]+)(.*?)>/gm,l=null,b=[];for(;l=A.exec(g);){let c=l[1],o={$tag:c},Z=I+c,d=l[2].trim(),G=!1;(d.endsWith("/")||c.startsWith("?")||c.startsWith("!"))&&(G=!0);let s=/([^ ]+?)="(.+?)"/g,e=/([^ ]+?)='(.+?)'/g,n=null,t=!1;for(;n=s.exec(d);)t=!0,o[n[1]]=n[2];if(!t)for(;n=e.exec(d);)t=!0,o[n[1]]=n[2];if(t||""===d||(o.text=d),this.progressive&&this.emit(`<${Z}>`,o,C),!G){let C=new RegExp(`([^]+?)</${c}>`,"g");C.lastIndex=A.lastIndex;let I=C.exec(g);if(I&&I[1]){A.lastIndex=C.lastIndex;let g=this.parse(I[1],o,Z);g.length>0?o.$innerNodes=g:o.$innerText=I[1]}}this.queryParent&&C&&this.parentMap.set(o,C),this.progressive&&this.emit(`</${Z}>`,o,C),b.push(o)}return b}getParent(g){return this.queryParent?this.parentMap.get(g):null}$addListener(g,C){let I=this.evtListeners[g];I?I.push(C):this.evtListeners[g]=[C]}addListener(I,A){g(I)&&(I=C(I),A.condition=function(g){let C="return "+g.replace(/(\$.+?)(?=[=!.])/g,"node.$&")+";";return new Function("node",C)}(I.exp),I=I.evt),this.$addListener(I,A)}$removeListener(g,C){let I=this.evtListeners[g],A=null;I&&(A=I.indexOf(C))>=0&&I.splice(A,1)}removeListener(I,A){g(I)&&(I=(I=C(I)).evt),this.$removeListener(I,A)}emit(g,...C){let I=this.evtListeners[g];if(I)for(let g of I)g.condition?!0===g.condition.apply(null,C)&&g.apply(null,C):g.apply(null,C)}on(g,C){this.addListener(g,C)}off(g,C){this.removeListener(g,C)}}})();const{Node:Ug,Way:Mg,Relation:Og}=Qg,{purgeProps:jg,RefElements:Dg}=fg,Pg=Tg;var Eg=(g,C)=>{let I=!1,A=!1,l=!0;(g=>{if(g){I=!(!g.completeFeature&&!g.allFeatures),A=!!g.renderTagged;let C=g.suppressWay||g.excludeWay;void 0===C||C||(l=!1)}})(C);let b=(g=>g.elements?"json":g.indexOf("<osm")>=0?"xml":g.trim().startsWith("{")?"json-raw":"invalid")(g),c=new Dg,o=[];"json-raw"===b&&(b=(g=JSON.parse(g)).elements?"json":"invalid"),"json"===b?(g=>{for(let C of g.elements)switch(C.type){case"node":let g=new Ug(C.id,c);C.tags&&g.addTags(C.tags),g.addProps(jg(C,["id","type","tags","lat","lon"])),g.setLatLng(C);break;case"way":let I=new Mg(C.id,c);if(C.tags&&I.addTags(C.tags),I.addProps(jg(C,["id","type","tags","nodes","geometry"])),C.nodes)for(let g of C.nodes)I.addNodeRef(g);else C.geometry&&I.setLatLngArray(C.geometry);break;case"relation":let A=new Og(C.id,c);if(C.bounds&&A.setBounds([parseFloat(C.bounds.minlon),parseFloat(C.bounds.minlat),parseFloat(C.bounds.maxlon),parseFloat(C.bounds.maxlat)]),C.tags&&A.addTags(C.tags),A.addProps(jg(C,["id","type","tags","bounds","members"])),C.members)for(let g of C.members)A.addMember(g)}})(g):"xml"===b&&(g=>{const C=new Pg({progressive:!0});C.on("</osm.node>",(g=>{let C=new Ug(g.id,c);for(let[I,A]of Object.entries(g))!I.startsWith("$")&&["id","lon","lat"].indexOf(I)<0&&C.addProp(I,A);if(C.setLatLng(g),g.$innerNodes)for(let I of g.$innerNodes)"tag"===I.$tag&&C.addTag(I.k,I.v)})),C.on("</osm.way>",(g=>{let C=new Mg(g.id,c);for(let[I,A]of Object.entries(g))!I.startsWith("$")&&["id"].indexOf(I)<0&&C.addProp(I,A);if(g.$innerNodes)for(let I of g.$innerNodes)"nd"===I.$tag?I.lon&&I.lat?C.addLatLng(I):I.ref&&C.addNodeRef(I.ref):"tag"===I.$tag&&C.addTag(I.k,I.v)})),C.on("<osm.relation>",(g=>{new Og(g.id,c)})),C.on("</osm.relation.member>",((g,C)=>{let I=c.get(`relation/${C.id}`),A={type:g.type,role:g.role?g.role:"",ref:g.ref};if(g.lat&&g.lon){A.lat=g.lat,A.lon=g.lon,A.tags={};for(let[C,I]of Object.entries(g))!C.startsWith("$")&&["type","lat","lon"].indexOf(C)<0&&(A[C]=I)}if(g.$innerNodes){let C=[],I=[];for(let A of g.$innerNodes)A.lat&&A.lon?C.push(A):I.push(A.ref);C.length>0?A.geometry=C:I.length>0&&(A.nodes=I)}I.addMember(A)})),C.on("</osm.relation.bounds>",((g,C)=>{c.get(`relation/${C.id}`).setBounds([parseFloat(g.minlon),parseFloat(g.minlat),parseFloat(g.maxlon),parseFloat(g.maxlat)])})),C.on("</osm.relation.tag>",((g,C)=>{c.get(`relation/${C.id}`).addTag(g.k,g.v)})),C.parse(g)})(g),c.bindAll();for(let g of c.values())if(g.refCount<=0||g.hasTag&&A&&!(g instanceof Mg&&l)){let C=g.toFeatureArray();if(g instanceof Og&&!I&&C.length>0)return C[0].geometry;o=o.concat(C)}return{type:"FeatureCollection",features:o}},qg=C(Eg);const _g=["topojson","osm","kml","gpx","tcx","csv","tsv"];class $g{constructor(g,C){this.blankGeoJSON=()=>({type:"FeatureCollection",features:[]}),this._rawData=C,this._format=g;const I={topojson:this.loadTopoJson,osm:this.loadOsm,kml:this.loadXml,gpx:this.loadXml,tcx:this.loadXml,csv:this.loadCsv,tsv:this.loadCsv};this._conversionFn=I[g]}async convert(){return this._conversionFn?this._conversionFn():new Promise(((g,C)=>C(`No converter exists for ${this._format}`)))}async loadXml(){return Lg[this._format]((new DOMParser).parseFromString(this._rawData,"text/xml"))}async loadCsv(){let g={};"tsv"===this._format&&(g.delimiter="\t");return await new Promise(((C,I)=>{H.csv2geojson(this._rawData,g,((g,A)=>{g?I(g):C(A)}))}))}async loadTopoJson(){let g={};try{g=JSON.parse(this._rawData)}catch(g){throw"Invalid TopoJson"}let C=this.blankGeoJSON();return"Topology"===g.type&&void 0!==g.objects&&(C={type:"FeatureCollection",features:C.features=Object.keys(g.objects).map((C=>{return I=g,"string"==typeof(A=C)&&(A=I.objects[A]),"GeometryCollection"===A.type?{type:"FeatureCollection",features:A.geometries.map((function(g){return R(I,g)}))}:R(I,A);var I,A})).reduce(((g,C)=>[...g,...C.features]),[])}),C}async loadOsm(){return qg(this._rawData)}}var gC=null;try{var CC="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");gC=CC.Worker}catch(g){}function IC(g,C,I){var A=void 0===C?null:C,l=function(g,C){return Buffer.from(g,"base64").toString(C?"utf16":"utf8")}(g,void 0!==I&&I),b=l.indexOf("\n",10)+1,c=l.substring(b)+(A?"//# sourceMappingURL="+A:"");return function(g){return new gC(c,Object.assign({},g,{eval:!0}))}}function AC(g,C,I){var A=void 0===C?null:C,l=function(g,C){var I=atob(g);if(C){for(var A=new Uint8Array(I.length),l=0,b=I.length;l<b;++l)A[l]=I.charCodeAt(l);return String.fromCharCode.apply(null,new Uint16Array(A.buffer))}return I}(g,void 0!==I&&I),b=l.indexOf("\n",10)+1,c=l.substring(b)+(A?"//# sourceMappingURL="+A:""),o=new Blob([c],{type:"application/javascript"});return URL.createObjectURL(o)}var lC="[object process]"===Object.prototype.toString.call("undefined"!=typeof process?process:0);var bC,cC,oC,ZC=(bC="Lyogcm9sbHVwLXBsdWdpbi13ZWItd29ya2VyLWxvYWRlciAqLwooZnVuY3Rpb24gKCkgewoJJ3VzZSBzdHJpY3QnOwoKCWZ1bmN0aW9uIGdldERlZmF1bHRFeHBvcnRGcm9tQ2pzICh4KSB7CgkJcmV0dXJuIHggJiYgeC5fX2VzTW9kdWxlICYmIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh4LCAnZGVmYXVsdCcpID8geFsnZGVmYXVsdCddIDogeDsKCX0KCglmdW5jdGlvbiBnZXRBdWdtZW50ZWROYW1lc3BhY2UobikgewoJICBpZiAobi5fX2VzTW9kdWxlKSByZXR1cm4gbjsKCSAgdmFyIGYgPSBuLmRlZmF1bHQ7CgkJaWYgKHR5cGVvZiBmID09ICJmdW5jdGlvbiIpIHsKCQkJdmFyIGEgPSBmdW5jdGlvbiBhICgpIHsKCQkJCWlmICh0aGlzIGluc3RhbmNlb2YgYSkgewoJCQkJCXZhciBhcmdzID0gW251bGxdOwoJCQkJCWFyZ3MucHVzaC5hcHBseShhcmdzLCBhcmd1bWVudHMpOwoJCQkJCXZhciBDdG9yID0gRnVuY3Rpb24uYmluZC5hcHBseShmLCBhcmdzKTsKCQkJCQlyZXR1cm4gbmV3IEN0b3IoKTsKCQkJCX0KCQkJCXJldHVybiBmLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CgkJCX07CgkJCWEucHJvdG90eXBlID0gZi5wcm90b3R5cGU7CgkgIH0gZWxzZSBhID0ge307CgkgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShhLCAnX19lc01vZHVsZScsIHt2YWx1ZTogdHJ1ZX0pOwoJCU9iamVjdC5rZXlzKG4pLmZvckVhY2goZnVuY3Rpb24gKGspIHsKCQkJdmFyIGQgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKG4sIGspOwoJCQlPYmplY3QuZGVmaW5lUHJvcGVydHkoYSwgaywgZC5nZXQgPyBkIDogewoJCQkJZW51bWVyYWJsZTogdHJ1ZSwKCQkJCWdldDogZnVuY3Rpb24gKCkgewoJCQkJCXJldHVybiBuW2tdOwoJCQkJfQoJCQl9KTsKCQl9KTsKCQlyZXR1cm4gYTsKCX0KCglmdW5jdGlvbiBvYmplY3RDb252ZXJ0ZXIoY29sdW1ucykgewoJICByZXR1cm4gbmV3IEZ1bmN0aW9uKCJkIiwgInJldHVybiB7IiArIGNvbHVtbnMubWFwKGZ1bmN0aW9uKG5hbWUsIGkpIHsKCSAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkobmFtZSkgKyAiOiBkWyIgKyBpICsgIl0iOwoJICB9KS5qb2luKCIsIikgKyAifSIpOwoJfQoKCWZ1bmN0aW9uIGN1c3RvbUNvbnZlcnRlcihjb2x1bW5zLCBmKSB7CgkgIHZhciBvYmplY3QgPSBvYmplY3RDb252ZXJ0ZXIoY29sdW1ucyk7CgkgIHJldHVybiBmdW5jdGlvbihyb3csIGkpIHsKCSAgICByZXR1cm4gZihvYmplY3Qocm93KSwgaSwgY29sdW1ucyk7CgkgIH07Cgl9CgoJLy8gQ29tcHV0ZSB1bmlxdWUgY29sdW1ucyBpbiBvcmRlciBvZiBkaXNjb3ZlcnkuCglmdW5jdGlvbiBpbmZlckNvbHVtbnMocm93cykgewoJICB2YXIgY29sdW1uU2V0ID0gT2JqZWN0LmNyZWF0ZShudWxsKSwKCSAgICAgIGNvbHVtbnMgPSBbXTsKCgkgIHJvd3MuZm9yRWFjaChmdW5jdGlvbihyb3cpIHsKCSAgICBmb3IgKHZhciBjb2x1bW4gaW4gcm93KSB7CgkgICAgICBpZiAoIShjb2x1bW4gaW4gY29sdW1uU2V0KSkgewoJICAgICAgICBjb2x1bW5zLnB1c2goY29sdW1uU2V0W2NvbHVtbl0gPSBjb2x1bW4pOwoJICAgICAgfQoJICAgIH0KCSAgfSk7CgoJICByZXR1cm4gY29sdW1uczsKCX0KCglmdW5jdGlvbiBkc3YkMShkZWxpbWl0ZXIpIHsKCSAgdmFyIHJlRm9ybWF0ID0gbmV3IFJlZ0V4cCgiW1wiIiArIGRlbGltaXRlciArICJcbl0iKSwKCSAgICAgIGRlbGltaXRlckNvZGUgPSBkZWxpbWl0ZXIuY2hhckNvZGVBdCgwKTsKCgkgIGZ1bmN0aW9uIHBhcnNlKHRleHQsIGYpIHsKCSAgICB2YXIgY29udmVydCwgY29sdW1ucywgcm93cyA9IHBhcnNlUm93cyh0ZXh0LCBmdW5jdGlvbihyb3csIGkpIHsKCSAgICAgIGlmIChjb252ZXJ0KSByZXR1cm4gY29udmVydChyb3csIGkgLSAxKTsKCSAgICAgIGNvbHVtbnMgPSByb3csIGNvbnZlcnQgPSBmID8gY3VzdG9tQ29udmVydGVyKHJvdywgZikgOiBvYmplY3RDb252ZXJ0ZXIocm93KTsKCSAgICB9KTsKCSAgICByb3dzLmNvbHVtbnMgPSBjb2x1bW5zOwoJICAgIHJldHVybiByb3dzOwoJICB9CgoJICBmdW5jdGlvbiBwYXJzZVJvd3ModGV4dCwgZikgewoJICAgIHZhciBFT0wgPSB7fSwgLy8gc2VudGluZWwgdmFsdWUgZm9yIGVuZC1vZi1saW5lCgkgICAgICAgIEVPRiA9IHt9LCAvLyBzZW50aW5lbCB2YWx1ZSBmb3IgZW5kLW9mLWZpbGUKCSAgICAgICAgcm93cyA9IFtdLCAvLyBvdXRwdXQgcm93cwoJICAgICAgICBOID0gdGV4dC5sZW5ndGgsCgkgICAgICAgIEkgPSAwLCAvLyBjdXJyZW50IGNoYXJhY3RlciBpbmRleAoJICAgICAgICBuID0gMCwgLy8gdGhlIGN1cnJlbnQgbGluZSBudW1iZXIKCSAgICAgICAgdCwgLy8gdGhlIGN1cnJlbnQgdG9rZW4KCSAgICAgICAgZW9sOyAvLyBpcyB0aGUgY3VycmVudCB0b2tlbiBmb2xsb3dlZCBieSBFT0w/CgoJICAgIGZ1bmN0aW9uIHRva2VuKCkgewoJICAgICAgaWYgKEkgPj0gTikgcmV0dXJuIEVPRjsgLy8gc3BlY2lhbCBjYXNlOiBlbmQgb2YgZmlsZQoJICAgICAgaWYgKGVvbCkgcmV0dXJuIGVvbCA9IGZhbHNlLCBFT0w7IC8vIHNwZWNpYWwgY2FzZTogZW5kIG9mIGxpbmUKCgkgICAgICAvLyBzcGVjaWFsIGNhc2U6IHF1b3RlcwoJICAgICAgdmFyIGogPSBJLCBjOwoJICAgICAgaWYgKHRleHQuY2hhckNvZGVBdChqKSA9PT0gMzQpIHsKCSAgICAgICAgdmFyIGkgPSBqOwoJICAgICAgICB3aGlsZSAoaSsrIDwgTikgewoJICAgICAgICAgIGlmICh0ZXh0LmNoYXJDb2RlQXQoaSkgPT09IDM0KSB7CgkgICAgICAgICAgICBpZiAodGV4dC5jaGFyQ29kZUF0KGkgKyAxKSAhPT0gMzQpIGJyZWFrOwoJICAgICAgICAgICAgKytpOwoJICAgICAgICAgIH0KCSAgICAgICAgfQoJICAgICAgICBJID0gaSArIDI7CgkgICAgICAgIGMgPSB0ZXh0LmNoYXJDb2RlQXQoaSArIDEpOwoJICAgICAgICBpZiAoYyA9PT0gMTMpIHsKCSAgICAgICAgICBlb2wgPSB0cnVlOwoJICAgICAgICAgIGlmICh0ZXh0LmNoYXJDb2RlQXQoaSArIDIpID09PSAxMCkgKytJOwoJICAgICAgICB9IGVsc2UgaWYgKGMgPT09IDEwKSB7CgkgICAgICAgICAgZW9sID0gdHJ1ZTsKCSAgICAgICAgfQoJICAgICAgICByZXR1cm4gdGV4dC5zbGljZShqICsgMSwgaSkucmVwbGFjZSgvIiIvZywgIlwiIik7CgkgICAgICB9CgoJICAgICAgLy8gY29tbW9uIGNhc2U6IGZpbmQgbmV4dCBkZWxpbWl0ZXIgb3IgbmV3bGluZQoJICAgICAgd2hpbGUgKEkgPCBOKSB7CgkgICAgICAgIHZhciBrID0gMTsKCSAgICAgICAgYyA9IHRleHQuY2hhckNvZGVBdChJKyspOwoJICAgICAgICBpZiAoYyA9PT0gMTApIGVvbCA9IHRydWU7IC8vIFxuCgkgICAgICAgIGVsc2UgaWYgKGMgPT09IDEzKSB7IGVvbCA9IHRydWU7IGlmICh0ZXh0LmNoYXJDb2RlQXQoSSkgPT09IDEwKSArK0ksICsrazsgfSAvLyBccnxcclxuCgkgICAgICAgIGVsc2UgaWYgKGMgIT09IGRlbGltaXRlckNvZGUpIGNvbnRpbnVlOwoJICAgICAgICByZXR1cm4gdGV4dC5zbGljZShqLCBJIC0gayk7CgkgICAgICB9CgoJICAgICAgLy8gc3BlY2lhbCBjYXNlOiBsYXN0IHRva2VuIGJlZm9yZSBFT0YKCSAgICAgIHJldHVybiB0ZXh0LnNsaWNlKGopOwoJICAgIH0KCgkgICAgd2hpbGUgKCh0ID0gdG9rZW4oKSkgIT09IEVPRikgewoJICAgICAgdmFyIGEgPSBbXTsKCSAgICAgIHdoaWxlICh0ICE9PSBFT0wgJiYgdCAhPT0gRU9GKSB7CgkgICAgICAgIGEucHVzaCh0KTsKCSAgICAgICAgdCA9IHRva2VuKCk7CgkgICAgICB9CgkgICAgICBpZiAoZiAmJiAoYSA9IGYoYSwgbisrKSkgPT0gbnVsbCkgY29udGludWU7CgkgICAgICByb3dzLnB1c2goYSk7CgkgICAgfQoKCSAgICByZXR1cm4gcm93czsKCSAgfQoKCSAgZnVuY3Rpb24gZm9ybWF0KHJvd3MsIGNvbHVtbnMpIHsKCSAgICBpZiAoY29sdW1ucyA9PSBudWxsKSBjb2x1bW5zID0gaW5mZXJDb2x1bW5zKHJvd3MpOwoJICAgIHJldHVybiBbY29sdW1ucy5tYXAoZm9ybWF0VmFsdWUpLmpvaW4oZGVsaW1pdGVyKV0uY29uY2F0KHJvd3MubWFwKGZ1bmN0aW9uKHJvdykgewoJICAgICAgcmV0dXJuIGNvbHVtbnMubWFwKGZ1bmN0aW9uKGNvbHVtbikgewoJICAgICAgICByZXR1cm4gZm9ybWF0VmFsdWUocm93W2NvbHVtbl0pOwoJICAgICAgfSkuam9pbihkZWxpbWl0ZXIpOwoJICAgIH0pKS5qb2luKCJcbiIpOwoJICB9CgoJICBmdW5jdGlvbiBmb3JtYXRSb3dzKHJvd3MpIHsKCSAgICByZXR1cm4gcm93cy5tYXAoZm9ybWF0Um93KS5qb2luKCJcbiIpOwoJICB9CgoJICBmdW5jdGlvbiBmb3JtYXRSb3cocm93KSB7CgkgICAgcmV0dXJuIHJvdy5tYXAoZm9ybWF0VmFsdWUpLmpvaW4oZGVsaW1pdGVyKTsKCSAgfQoKCSAgZnVuY3Rpb24gZm9ybWF0VmFsdWUodGV4dCkgewoJICAgIHJldHVybiB0ZXh0ID09IG51bGwgPyAiIgoJICAgICAgICA6IHJlRm9ybWF0LnRlc3QodGV4dCArPSAiIikgPyAiXCIiICsgdGV4dC5yZXBsYWNlKC9cIi9nLCAiXCJcIiIpICsgIlwiIgoJICAgICAgICA6IHRleHQ7CgkgIH0KCgkgIHJldHVybiB7CgkgICAgcGFyc2U6IHBhcnNlLAoJICAgIHBhcnNlUm93czogcGFyc2VSb3dzLAoJICAgIGZvcm1hdDogZm9ybWF0LAoJICAgIGZvcm1hdFJvd3M6IGZvcm1hdFJvd3MKCSAgfTsKCX0KCgl2YXIgY3N2ID0gZHN2JDEoIiwiKTsKCgl2YXIgY3N2UGFyc2UgPSBjc3YucGFyc2U7Cgl2YXIgY3N2UGFyc2VSb3dzID0gY3N2LnBhcnNlUm93czsKCXZhciBjc3ZGb3JtYXQgPSBjc3YuZm9ybWF0OwoJdmFyIGNzdkZvcm1hdFJvd3MgPSBjc3YuZm9ybWF0Um93czsKCgl2YXIgdHN2ID0gZHN2JDEoIlx0Iik7CgoJdmFyIHRzdlBhcnNlID0gdHN2LnBhcnNlOwoJdmFyIHRzdlBhcnNlUm93cyA9IHRzdi5wYXJzZVJvd3M7Cgl2YXIgdHN2Rm9ybWF0ID0gdHN2LmZvcm1hdDsKCXZhciB0c3ZGb3JtYXRSb3dzID0gdHN2LmZvcm1hdFJvd3M7CgoJdmFyIGQzRHN2ID0gLyojX19QVVJFX18qL09iamVjdC5mcmVlemUoewoJCV9fcHJvdG9fXzogbnVsbCwKCQlkc3ZGb3JtYXQ6IGRzdiQxLAoJCWNzdlBhcnNlOiBjc3ZQYXJzZSwKCQljc3ZQYXJzZVJvd3M6IGNzdlBhcnNlUm93cywKCQljc3ZGb3JtYXQ6IGNzdkZvcm1hdCwKCQljc3ZGb3JtYXRSb3dzOiBjc3ZGb3JtYXRSb3dzLAoJCXRzdlBhcnNlOiB0c3ZQYXJzZSwKCQl0c3ZQYXJzZVJvd3M6IHRzdlBhcnNlUm93cywKCQl0c3ZGb3JtYXQ6IHRzdkZvcm1hdCwKCQl0c3ZGb3JtYXRSb3dzOiB0c3ZGb3JtYXRSb3dzCgl9KTsKCgl2YXIgcmVxdWlyZSQkMCA9IC8qQF9fUFVSRV9fKi9nZXRBdWdtZW50ZWROYW1lc3BhY2UoZDNEc3YpOwoKCXZhciBzZXhhZ2VzaW1hbCQxID0ge2V4cG9ydHM6IHt9fTsKCglzZXhhZ2VzaW1hbCQxLmV4cG9ydHMgPSBlbGVtZW50OwoJc2V4YWdlc2ltYWwkMS5leHBvcnRzLnBhaXIgPSBwYWlyOwoJc2V4YWdlc2ltYWwkMS5leHBvcnRzLmZvcm1hdCA9IGZvcm1hdDsKCXNleGFnZXNpbWFsJDEuZXhwb3J0cy5mb3JtYXRQYWlyID0gZm9ybWF0UGFpcjsKCXNleGFnZXNpbWFsJDEuZXhwb3J0cy5jb29yZFRvRE1TID0gY29vcmRUb0RNUzsKCgoJZnVuY3Rpb24gZWxlbWVudChpbnB1dCwgZGltcykgewoJICB2YXIgcmVzdWx0ID0gc2VhcmNoKGlucHV0LCBkaW1zKTsKCSAgcmV0dXJuIChyZXN1bHQgPT09IG51bGwpID8gbnVsbCA6IHJlc3VsdC52YWw7Cgl9CgoKCWZ1bmN0aW9uIGZvcm1hdFBhaXIoaW5wdXQpIHsKCSAgcmV0dXJuIGZvcm1hdChpbnB1dC5sYXQsICdsYXQnKSArICcgJyArIGZvcm1hdChpbnB1dC5sb24sICdsb24nKTsKCX0KCgoJLy8gSXMgMCBOb3J0aCBvciBTb3V0aD8KCWZ1bmN0aW9uIGZvcm1hdChpbnB1dCwgZGltKSB7CgkgIHZhciBkbXMgPSBjb29yZFRvRE1TKGlucHV0LCBkaW0pOwoJICByZXR1cm4gZG1zLndob2xlICsgJ8KwICcgKwoJICAgIChkbXMubWludXRlcyA/IGRtcy5taW51dGVzICsgJ1wnICcgOiAnJykgKwoJICAgIChkbXMuc2Vjb25kcyA/IGRtcy5zZWNvbmRzICsgJyIgJyA6ICcnKSArIGRtcy5kaXI7Cgl9CgoKCWZ1bmN0aW9uIGNvb3JkVG9ETVMoaW5wdXQsIGRpbSkgewoJICB2YXIgZGlycyA9IHsgbGF0OiBbJ04nLCAnUyddLCBsb246IFsnRScsICdXJ10gfVtkaW1dIHx8ICcnOwoJICB2YXIgZGlyID0gZGlyc1tpbnB1dCA+PSAwID8gMCA6IDFdOwoJICB2YXIgYWJzID0gTWF0aC5hYnMoaW5wdXQpOwoJICB2YXIgd2hvbGUgPSBNYXRoLmZsb29yKGFicyk7CgkgIHZhciBmcmFjdGlvbiA9IGFicyAtIHdob2xlOwoJICB2YXIgZnJhY3Rpb25NaW51dGVzID0gZnJhY3Rpb24gKiA2MDsKCSAgdmFyIG1pbnV0ZXMgPSBNYXRoLmZsb29yKGZyYWN0aW9uTWludXRlcyk7CgkgIHZhciBzZWNvbmRzID0gTWF0aC5mbG9vcigoZnJhY3Rpb25NaW51dGVzIC0gbWludXRlcykgKiA2MCk7CgoJICByZXR1cm4gewoJICAgIHdob2xlOiB3aG9sZSwKCSAgICBtaW51dGVzOiBtaW51dGVzLAoJICAgIHNlY29uZHM6IHNlY29uZHMsCgkgICAgZGlyOiBkaXIKCSAgfTsKCX0KCgoJZnVuY3Rpb24gc2VhcmNoKGlucHV0LCBkaW1zKSB7CgkgIGlmICghZGltcykgZGltcyA9ICdOU0VXJzsKCSAgaWYgKHR5cGVvZiBpbnB1dCAhPT0gJ3N0cmluZycpIHJldHVybiBudWxsOwoKCSAgaW5wdXQgPSBpbnB1dC50b1VwcGVyQ2FzZSgpOwoJICB2YXIgcmVnZXggPSAvXltcc1wsXSooW05TRVddKT9ccyooW1wtfFzigJR8XOKAlV0/WzAtOS5dKylbwrDCusuaXT9ccyooPzooWzAtOS5dKylbJ+KAmeKAsuKAmF1ccyopPyg/OihbMC05Ll0rKSg/OicnfCJ84oCdfOKAsylccyopPyhbTlNFV10pPy87CgoJICB2YXIgbSA9IGlucHV0Lm1hdGNoKHJlZ2V4KTsKCSAgaWYgKCFtKSByZXR1cm4gbnVsbDsgIC8vIG5vIG1hdGNoCgoJICB2YXIgbWF0Y2hlZCA9IG1bMF07CgoJICAvLyBleHRyYWN0IGRpbWVuc2lvbi4uIG1bMV0gPSBsZWFkaW5nLCBtWzVdID0gdHJhaWxpbmcKCSAgdmFyIGRpbTsKCSAgaWYgKG1bMV0gJiYgbVs1XSkgeyAgICAgICAgICAgICAgICAgLy8gaWYgbWF0Y2hlZCBib3RoLi4KCSAgICBkaW0gPSBtWzFdOyAgICAgICAgICAgICAgICAgICAgICAgLy8ga2VlcCBsZWFkaW5nCgkgICAgbWF0Y2hlZCA9IG1hdGNoZWQuc2xpY2UoMCwgLTEpOyAgIC8vIHJlbW92ZSB0cmFpbGluZyBkaW1lbnNpb24gZnJvbSBtYXRjaAoJICB9IGVsc2UgewoJICAgIGRpbSA9IG1bMV0gfHwgbVs1XTsKCSAgfQoKCSAgLy8gaWYgdW5yZWNvZ25pemVkIGRpbWVuc2lvbgoJICBpZiAoZGltICYmIGRpbXMuaW5kZXhPZihkaW0pID09PSAtMSkgcmV0dXJuIG51bGw7CgoJICAvLyBleHRyYWN0IERNUwoJICB2YXIgZGVnID0gbVsyXSA/IHBhcnNlRmxvYXQobVsyXSkgOiAwOwoJICB2YXIgbWluID0gbVszXSA/IHBhcnNlRmxvYXQobVszXSkgLyA2MCA6IDA7CgkgIHZhciBzZWMgPSBtWzRdID8gcGFyc2VGbG9hdChtWzRdKSAvIDM2MDAgOiAwOwoJICB2YXIgc2lnbiA9IChkZWcgPCAwKSA/IC0xIDogMTsKCSAgaWYgKGRpbSA9PT0gJ1MnIHx8IGRpbSA9PT0gJ1cnKSBzaWduICo9IC0xOwoKCSAgcmV0dXJuIHsKCSAgICB2YWw6IChNYXRoLmFicyhkZWcpICsgbWluICsgc2VjKSAqIHNpZ24sCgkgICAgZGltOiBkaW0sCgkgICAgbWF0Y2hlZDogbWF0Y2hlZCwKCSAgICByZW1haW46IGlucHV0LnNsaWNlKG1hdGNoZWQubGVuZ3RoKQoJICB9OwoJfQoKCglmdW5jdGlvbiBwYWlyKGlucHV0LCBkaW1zKSB7CgkgIGlucHV0ID0gaW5wdXQudHJpbSgpOwoJICB2YXIgb25lID0gc2VhcmNoKGlucHV0LCBkaW1zKTsKCSAgaWYgKCFvbmUpIHJldHVybiBudWxsOwoKCSAgaW5wdXQgPSBvbmUucmVtYWluLnRyaW0oKTsKCSAgdmFyIHR3byA9IHNlYXJjaChpbnB1dCwgZGltcyk7CgkgIGlmICghdHdvIHx8IHR3by5yZW1haW4pIHJldHVybiBudWxsOwoKCSAgaWYgKG9uZS5kaW0pIHsKCSAgICByZXR1cm4gc3dhcGRpbShvbmUudmFsLCB0d28udmFsLCBvbmUuZGltKTsKCSAgfSBlbHNlIHsKCSAgICByZXR1cm4gW29uZS52YWwsIHR3by52YWxdOwoJICB9Cgl9CgoKCWZ1bmN0aW9uIHN3YXBkaW0oYSwgYiwgZGltKSB7CgkgIGlmIChkaW0gPT09ICdOJyB8fCBkaW0gPT09ICdTJykgcmV0dXJuIFthLCBiXTsKCSAgaWYgKGRpbSA9PT0gJ1cnIHx8IGRpbSA9PT0gJ0UnKSByZXR1cm4gW2IsIGFdOwoJfQoKCXZhciBzZXhhZ2VzaW1hbEV4cG9ydHMgPSBzZXhhZ2VzaW1hbCQxLmV4cG9ydHM7CgoJdmFyIGRzdiA9IHJlcXVpcmUkJDAsCgkgICAgc2V4YWdlc2ltYWwgPSBzZXhhZ2VzaW1hbEV4cG9ydHM7CgoJdmFyIGxhdFJlZ2V4ID0gLyhMYXQpKGl0dWRlKT8vZ2ksCgkgICAgbG9uUmVnZXggPSAvKEwpKG9ufG5nKShnaXR1ZGUpPy9pOwoKCWZ1bmN0aW9uIGd1ZXNzSGVhZGVyKHJvdywgcmVnZXhwKSB7CgkgICAgdmFyIG5hbWUsIG1hdGNoLCBzY29yZTsKCSAgICBmb3IgKHZhciBmIGluIHJvdykgewoJICAgICAgICBtYXRjaCA9IGYubWF0Y2gocmVnZXhwKTsKCSAgICAgICAgaWYgKG1hdGNoICYmICghbmFtZSB8fCBtYXRjaFswXS5sZW5ndGggLyBmLmxlbmd0aCA+IHNjb3JlKSkgewoJICAgICAgICAgICAgc2NvcmUgPSBtYXRjaFswXS5sZW5ndGggLyBmLmxlbmd0aDsKCSAgICAgICAgICAgIG5hbWUgPSBmOwoJICAgICAgICB9CgkgICAgfQoJICAgIHJldHVybiBuYW1lOwoJfQoKCWZ1bmN0aW9uIGd1ZXNzTGF0SGVhZGVyKHJvdykgeyByZXR1cm4gZ3Vlc3NIZWFkZXIocm93LCBsYXRSZWdleCk7IH0KCWZ1bmN0aW9uIGd1ZXNzTG9uSGVhZGVyKHJvdykgeyByZXR1cm4gZ3Vlc3NIZWFkZXIocm93LCBsb25SZWdleCk7IH0KCglmdW5jdGlvbiBpc0xhdChmKSB7IHJldHVybiAhIWYubWF0Y2gobGF0UmVnZXgpOyB9CglmdW5jdGlvbiBpc0xvbihmKSB7IHJldHVybiAhIWYubWF0Y2gobG9uUmVnZXgpOyB9CgoJZnVuY3Rpb24ga2V5Q291bnQobykgewoJICAgIHJldHVybiAodHlwZW9mIG8gPT0gJ29iamVjdCcpID8gT2JqZWN0LmtleXMobykubGVuZ3RoIDogMDsKCX0KCglmdW5jdGlvbiBhdXRvRGVsaW1pdGVyKHgpIHsKCSAgICB2YXIgZGVsaW1pdGVycyA9IFsnLCcsICc7JywgJ1x0JywgJ3wnXTsKCSAgICB2YXIgcmVzdWx0cyA9IFtdOwoKCSAgICBkZWxpbWl0ZXJzLmZvckVhY2goZnVuY3Rpb24gKGRlbGltaXRlcikgewoJICAgICAgICB2YXIgcmVzID0gZHN2LmRzdkZvcm1hdChkZWxpbWl0ZXIpLnBhcnNlKHgpOwoJICAgICAgICBpZiAocmVzLmxlbmd0aCA+PSAxKSB7CgkgICAgICAgICAgICB2YXIgY291bnQgPSBrZXlDb3VudChyZXNbMF0pOwoJICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCByZXMubGVuZ3RoOyBpKyspIHsKCSAgICAgICAgICAgICAgICBpZiAoa2V5Q291bnQocmVzW2ldKSAhPT0gY291bnQpIHJldHVybjsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIHJlc3VsdHMucHVzaCh7CgkgICAgICAgICAgICAgICAgZGVsaW1pdGVyOiBkZWxpbWl0ZXIsCgkgICAgICAgICAgICAgICAgYXJpdHk6IE9iamVjdC5rZXlzKHJlc1swXSkubGVuZ3RoLAoJICAgICAgICAgICAgfSk7CgkgICAgICAgIH0KCSAgICB9KTsKCgkgICAgaWYgKHJlc3VsdHMubGVuZ3RoKSB7CgkgICAgICAgIHJldHVybiByZXN1bHRzLnNvcnQoZnVuY3Rpb24gKGEsIGIpIHsKCSAgICAgICAgICAgIHJldHVybiBiLmFyaXR5IC0gYS5hcml0eTsKCSAgICAgICAgfSlbMF0uZGVsaW1pdGVyOwoJICAgIH0gZWxzZSB7CgkgICAgICAgIHJldHVybiBudWxsOwoJICAgIH0KCX0KCgkvKioKCSAqIFNpbGx5IHN0b3BnYXAgZm9yIGRzdiB0byBkMy1kc3YgdXBncmFkZQoJICoKCSAqIEBwYXJhbSB7QXJyYXl9IHggZHN2IG91dHB1dAoJICogQHJldHVybnMge0FycmF5fSBhcnJheSB3aXRob3V0IGNvbHVtbnMgbWVtYmVyCgkgKi8KCWZ1bmN0aW9uIGRlbGV0ZUNvbHVtbnMoeCkgewoJICAgIGRlbGV0ZSB4LmNvbHVtbnM7CgkgICAgcmV0dXJuIHg7Cgl9CgoJZnVuY3Rpb24gYXV0byh4KSB7CgkgICAgdmFyIGRlbGltaXRlciA9IGF1dG9EZWxpbWl0ZXIoeCk7CgkgICAgaWYgKCFkZWxpbWl0ZXIpIHJldHVybiBudWxsOwoJICAgIHJldHVybiBkZWxldGVDb2x1bW5zKGRzdi5kc3ZGb3JtYXQoZGVsaW1pdGVyKS5wYXJzZSh4KSk7Cgl9CgoJZnVuY3Rpb24gY3N2Mmdlb2pzb24oeCwgb3B0aW9ucywgY2FsbGJhY2spIHsKCgkgICAgaWYgKCFjYWxsYmFjaykgewoJICAgICAgICBjYWxsYmFjayA9IG9wdGlvbnM7CgkgICAgICAgIG9wdGlvbnMgPSB7fTsKCSAgICB9CgoJICAgIG9wdGlvbnMuZGVsaW1pdGVyID0gb3B0aW9ucy5kZWxpbWl0ZXIgfHwgJywnOwoKCSAgICB2YXIgbGF0ZmllbGQgPSBvcHRpb25zLmxhdGZpZWxkIHx8ICcnLAoJICAgICAgICBsb25maWVsZCA9IG9wdGlvbnMubG9uZmllbGQgfHwgJycsCgkgICAgICAgIGNycyA9IG9wdGlvbnMuY3JzIHx8ICcnOwoKCSAgICB2YXIgZmVhdHVyZXMgPSBbXSwKCSAgICAgICAgZmVhdHVyZWNvbGxlY3Rpb24gPSB7dHlwZTogJ0ZlYXR1cmVDb2xsZWN0aW9uJywgZmVhdHVyZXM6IGZlYXR1cmVzfTsKCgkgICAgaWYgKGNycyAhPT0gJycpIHsKCSAgICAgICAgZmVhdHVyZWNvbGxlY3Rpb24uY3JzID0ge3R5cGU6ICduYW1lJywgcHJvcGVydGllczoge25hbWU6IGNyc319OwoJICAgIH0KCgkgICAgaWYgKG9wdGlvbnMuZGVsaW1pdGVyID09PSAnYXV0bycgJiYgdHlwZW9mIHggPT0gJ3N0cmluZycpIHsKCSAgICAgICAgb3B0aW9ucy5kZWxpbWl0ZXIgPSBhdXRvRGVsaW1pdGVyKHgpOwoJICAgICAgICBpZiAoIW9wdGlvbnMuZGVsaW1pdGVyKSB7CgkgICAgICAgICAgICBjYWxsYmFjayh7CgkgICAgICAgICAgICAgICAgdHlwZTogJ0Vycm9yJywKCSAgICAgICAgICAgICAgICBtZXNzYWdlOiAnQ291bGQgbm90IGF1dG9kZXRlY3QgZGVsaW1pdGVyJwoJICAgICAgICAgICAgfSk7CgkgICAgICAgICAgICByZXR1cm47CgkgICAgICAgIH0KCSAgICB9CgoJICAgIHZhciBudW1lcmljRmllbGRzID0gb3B0aW9ucy5udW1lcmljRmllbGRzID8gb3B0aW9ucy5udW1lcmljRmllbGRzLnNwbGl0KCcsJykgOiBudWxsOwoKCSAgICB2YXIgcGFyc2VkID0gKHR5cGVvZiB4ID09ICdzdHJpbmcnKSA/CgkgICAgICAgIGRzdi5kc3ZGb3JtYXQob3B0aW9ucy5kZWxpbWl0ZXIpLnBhcnNlKHgsIGZ1bmN0aW9uIChkKSB7CgkgICAgICAgICAgICBpZiAobnVtZXJpY0ZpZWxkcykgewoJICAgICAgICAgICAgICAgIGZvciAodmFyIGtleSBpbiBkKSB7CgkgICAgICAgICAgICAgICAgICAgIGlmIChudW1lcmljRmllbGRzLmluY2x1ZGVzKGtleSkpIHsKCSAgICAgICAgICAgICAgICAgICAgICAgIGRba2V5XSA9ICtkW2tleV07CgkgICAgICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICByZXR1cm4gZDsKCSAgICAgICAgfSkgOiB4OwoKCSAgICBpZiAoIXBhcnNlZC5sZW5ndGgpIHsKCSAgICAgICAgY2FsbGJhY2sobnVsbCwgZmVhdHVyZWNvbGxlY3Rpb24pOwoJICAgICAgICByZXR1cm47CgkgICAgfQoKCSAgICB2YXIgZXJyb3JzID0gW107CgkgICAgdmFyIGk7CgoKCSAgICBpZiAoIWxhdGZpZWxkKSBsYXRmaWVsZCA9IGd1ZXNzTGF0SGVhZGVyKHBhcnNlZFswXSk7CgkgICAgaWYgKCFsb25maWVsZCkgbG9uZmllbGQgPSBndWVzc0xvbkhlYWRlcihwYXJzZWRbMF0pOwoJICAgIHZhciBub0dlb21ldHJ5ID0gKCFsYXRmaWVsZCB8fCAhbG9uZmllbGQpOwoKCSAgICBpZiAobm9HZW9tZXRyeSkgewoJICAgICAgICBmb3IgKGkgPSAwOyBpIDwgcGFyc2VkLmxlbmd0aDsgaSsrKSB7CgkgICAgICAgICAgICBmZWF0dXJlcy5wdXNoKHsKCSAgICAgICAgICAgICAgICB0eXBlOiAnRmVhdHVyZScsCgkgICAgICAgICAgICAgICAgcHJvcGVydGllczogcGFyc2VkW2ldLAoJICAgICAgICAgICAgICAgIGdlb21ldHJ5OiBudWxsCgkgICAgICAgICAgICB9KTsKCSAgICAgICAgfQoJICAgICAgICBjYWxsYmFjayhlcnJvcnMubGVuZ3RoID8gZXJyb3JzIDogbnVsbCwgZmVhdHVyZWNvbGxlY3Rpb24pOwoJICAgICAgICByZXR1cm47CgkgICAgfQoKCSAgICBmb3IgKGkgPSAwOyBpIDwgcGFyc2VkLmxlbmd0aDsgaSsrKSB7CgkgICAgICAgIGlmIChwYXJzZWRbaV1bbG9uZmllbGRdICE9PSB1bmRlZmluZWQgJiYKCSAgICAgICAgICAgIHBhcnNlZFtpXVtsYXRmaWVsZF0gIT09IHVuZGVmaW5lZCkgewoKCSAgICAgICAgICAgIHZhciBsb25rID0gcGFyc2VkW2ldW2xvbmZpZWxkXSwKCSAgICAgICAgICAgICAgICBsYXRrID0gcGFyc2VkW2ldW2xhdGZpZWxkXSwKCSAgICAgICAgICAgICAgICBsb25mLCBsYXRmLAoJICAgICAgICAgICAgICAgIGE7CgoJICAgICAgICAgICAgYSA9IHNleGFnZXNpbWFsKGxvbmssICdFVycpOwoJICAgICAgICAgICAgaWYgKGEpIGxvbmsgPSBhOwoJICAgICAgICAgICAgYSA9IHNleGFnZXNpbWFsKGxhdGssICdOUycpOwoJICAgICAgICAgICAgaWYgKGEpIGxhdGsgPSBhOwoKCSAgICAgICAgICAgIGxvbmYgPSBwYXJzZUZsb2F0KGxvbmspOwoJICAgICAgICAgICAgbGF0ZiA9IHBhcnNlRmxvYXQobGF0ayk7CgoJICAgICAgICAgICAgaWYgKGlzTmFOKGxvbmYpIHx8CgkgICAgICAgICAgICAgICAgaXNOYU4obGF0ZikpIHsKCSAgICAgICAgICAgICAgICBlcnJvcnMucHVzaCh7CgkgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6ICdBIHJvdyBjb250YWluZWQgYW4gaW52YWxpZCB2YWx1ZSBmb3IgbGF0aXR1ZGUgb3IgbG9uZ2l0dWRlJywKCSAgICAgICAgICAgICAgICAgICAgcm93OiBwYXJzZWRbaV0sCgkgICAgICAgICAgICAgICAgICAgIGluZGV4OiBpCgkgICAgICAgICAgICAgICAgfSk7CgkgICAgICAgICAgICB9IGVsc2UgewoJICAgICAgICAgICAgICAgIGlmICghb3B0aW9ucy5pbmNsdWRlTGF0TG9uKSB7CgkgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBwYXJzZWRbaV1bbG9uZmllbGRdOwoJICAgICAgICAgICAgICAgICAgICBkZWxldGUgcGFyc2VkW2ldW2xhdGZpZWxkXTsKCSAgICAgICAgICAgICAgICB9CgoJICAgICAgICAgICAgICAgIGZlYXR1cmVzLnB1c2goewoJICAgICAgICAgICAgICAgICAgICB0eXBlOiAnRmVhdHVyZScsCgkgICAgICAgICAgICAgICAgICAgIHByb3BlcnRpZXM6IHBhcnNlZFtpXSwKCSAgICAgICAgICAgICAgICAgICAgZ2VvbWV0cnk6IHsKCSAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdQb2ludCcsCgkgICAgICAgICAgICAgICAgICAgICAgICBjb29yZGluYXRlczogWwoJICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcnNlRmxvYXQobG9uZiksCgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VGbG9hdChsYXRmKQoJICAgICAgICAgICAgICAgICAgICAgICAgXQoJICAgICAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICAgICAgfSk7CgkgICAgICAgICAgICB9CgkgICAgICAgIH0KCSAgICB9CgoJICAgIGNhbGxiYWNrKGVycm9ycy5sZW5ndGggPyBlcnJvcnMgOiBudWxsLCBmZWF0dXJlY29sbGVjdGlvbik7Cgl9CgoJZnVuY3Rpb24gdG9MaW5lKGdqKSB7CgkgICAgdmFyIGZlYXR1cmVzID0gZ2ouZmVhdHVyZXM7CgkgICAgdmFyIGxpbmUgPSB7CgkgICAgICAgIHR5cGU6ICdGZWF0dXJlJywKCSAgICAgICAgZ2VvbWV0cnk6IHsKCSAgICAgICAgICAgIHR5cGU6ICdMaW5lU3RyaW5nJywKCSAgICAgICAgICAgIGNvb3JkaW5hdGVzOiBbXQoJICAgICAgICB9CgkgICAgfTsKCSAgICBmb3IgKHZhciBpID0gMDsgaSA8IGZlYXR1cmVzLmxlbmd0aDsgaSsrKSB7CgkgICAgICAgIGxpbmUuZ2VvbWV0cnkuY29vcmRpbmF0ZXMucHVzaChmZWF0dXJlc1tpXS5nZW9tZXRyeS5jb29yZGluYXRlcyk7CgkgICAgfQoJICAgIGxpbmUucHJvcGVydGllcyA9IGZlYXR1cmVzLnJlZHVjZShmdW5jdGlvbiAoYWdncmVnYXRlZFByb3BlcnRpZXMsIG5ld0ZlYXR1cmUpIHsKCSAgICAgICAgZm9yICh2YXIga2V5IGluIG5ld0ZlYXR1cmUucHJvcGVydGllcykgewoJICAgICAgICAgICAgaWYgKCFhZ2dyZWdhdGVkUHJvcGVydGllc1trZXldKSB7CgkgICAgICAgICAgICAgICAgYWdncmVnYXRlZFByb3BlcnRpZXNba2V5XSA9IFtdOwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgYWdncmVnYXRlZFByb3BlcnRpZXNba2V5XS5wdXNoKG5ld0ZlYXR1cmUucHJvcGVydGllc1trZXldKTsKCSAgICAgICAgfQoJICAgICAgICByZXR1cm4gYWdncmVnYXRlZFByb3BlcnRpZXM7CgkgICAgfSwge30pOwoJICAgIHJldHVybiB7CgkgICAgICAgIHR5cGU6ICdGZWF0dXJlQ29sbGVjdGlvbicsCgkgICAgICAgIGZlYXR1cmVzOiBbbGluZV0KCSAgICB9OwoJfQoKCWZ1bmN0aW9uIHRvUG9seWdvbihnaikgewoJICAgIHZhciBmZWF0dXJlcyA9IGdqLmZlYXR1cmVzOwoJICAgIHZhciBwb2x5ID0gewoJICAgICAgICB0eXBlOiAnRmVhdHVyZScsCgkgICAgICAgIGdlb21ldHJ5OiB7CgkgICAgICAgICAgICB0eXBlOiAnUG9seWdvbicsCgkgICAgICAgICAgICBjb29yZGluYXRlczogW1tdXQoJICAgICAgICB9CgkgICAgfTsKCSAgICBmb3IgKHZhciBpID0gMDsgaSA8IGZlYXR1cmVzLmxlbmd0aDsgaSsrKSB7CgkgICAgICAgIHBvbHkuZ2VvbWV0cnkuY29vcmRpbmF0ZXNbMF0ucHVzaChmZWF0dXJlc1tpXS5nZW9tZXRyeS5jb29yZGluYXRlcyk7CgkgICAgfQoJICAgIHBvbHkucHJvcGVydGllcyA9IGZlYXR1cmVzLnJlZHVjZShmdW5jdGlvbiAoYWdncmVnYXRlZFByb3BlcnRpZXMsIG5ld0ZlYXR1cmUpIHsKCSAgICAgICAgZm9yICh2YXIga2V5IGluIG5ld0ZlYXR1cmUucHJvcGVydGllcykgewoJICAgICAgICAgICAgaWYgKCFhZ2dyZWdhdGVkUHJvcGVydGllc1trZXldKSB7CgkgICAgICAgICAgICAgICAgYWdncmVnYXRlZFByb3BlcnRpZXNba2V5XSA9IFtdOwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgYWdncmVnYXRlZFByb3BlcnRpZXNba2V5XS5wdXNoKG5ld0ZlYXR1cmUucHJvcGVydGllc1trZXldKTsKCSAgICAgICAgfQoJICAgICAgICByZXR1cm4gYWdncmVnYXRlZFByb3BlcnRpZXM7CgkgICAgfSwge30pOwoJICAgIHJldHVybiB7CgkgICAgICAgIHR5cGU6ICdGZWF0dXJlQ29sbGVjdGlvbicsCgkgICAgICAgIGZlYXR1cmVzOiBbcG9seV0KCSAgICB9OwoJfQoKCXZhciBjc3YyZ2VvanNvbl8xID0gewoJICAgIGlzTG9uOiBpc0xvbiwKCSAgICBpc0xhdDogaXNMYXQsCgkgICAgZ3Vlc3NMYXRIZWFkZXI6IGd1ZXNzTGF0SGVhZGVyLAoJICAgIGd1ZXNzTG9uSGVhZGVyOiBndWVzc0xvbkhlYWRlciwKCSAgICBjc3Y6IGRzdi5jc3ZQYXJzZSwKCSAgICB0c3Y6IGRzdi50c3ZQYXJzZSwKCSAgICBkc3Y6IGRzdiwKCSAgICBhdXRvOiBhdXRvLAoJICAgIGNzdjJnZW9qc29uOiBjc3YyZ2VvanNvbiwKCSAgICB0b0xpbmU6IHRvTGluZSwKCSAgICB0b1BvbHlnb246IHRvUG9seWdvbgoJfTsKCglmdW5jdGlvbiBpZGVudGl0eSh4KSB7CgkgIHJldHVybiB4OwoJfQoKCWZ1bmN0aW9uIHRyYW5zZm9ybSh0cmFuc2Zvcm0pIHsKCSAgaWYgKHRyYW5zZm9ybSA9PSBudWxsKSByZXR1cm4gaWRlbnRpdHk7CgkgIHZhciB4MCwKCSAgICAgIHkwLAoJICAgICAga3ggPSB0cmFuc2Zvcm0uc2NhbGVbMF0sCgkgICAgICBreSA9IHRyYW5zZm9ybS5zY2FsZVsxXSwKCSAgICAgIGR4ID0gdHJhbnNmb3JtLnRyYW5zbGF0ZVswXSwKCSAgICAgIGR5ID0gdHJhbnNmb3JtLnRyYW5zbGF0ZVsxXTsKCSAgcmV0dXJuIGZ1bmN0aW9uKGlucHV0LCBpKSB7CgkgICAgaWYgKCFpKSB4MCA9IHkwID0gMDsKCSAgICB2YXIgaiA9IDIsIG4gPSBpbnB1dC5sZW5ndGgsIG91dHB1dCA9IG5ldyBBcnJheShuKTsKCSAgICBvdXRwdXRbMF0gPSAoeDAgKz0gaW5wdXRbMF0pICoga3ggKyBkeDsKCSAgICBvdXRwdXRbMV0gPSAoeTAgKz0gaW5wdXRbMV0pICoga3kgKyBkeTsKCSAgICB3aGlsZSAoaiA8IG4pIG91dHB1dFtqXSA9IGlucHV0W2pdLCArK2o7CgkgICAgcmV0dXJuIG91dHB1dDsKCSAgfTsKCX0KCglmdW5jdGlvbiByZXZlcnNlKGFycmF5LCBuKSB7CgkgIHZhciB0LCBqID0gYXJyYXkubGVuZ3RoLCBpID0gaiAtIG47CgkgIHdoaWxlIChpIDwgLS1qKSB0ID0gYXJyYXlbaV0sIGFycmF5W2krK10gPSBhcnJheVtqXSwgYXJyYXlbal0gPSB0OwoJfQoKCWZ1bmN0aW9uIHRvcG9qc29uRmVhdHVyZSh0b3BvbG9neSwgbykgewoJICBpZiAodHlwZW9mIG8gPT09ICJzdHJpbmciKSBvID0gdG9wb2xvZ3kub2JqZWN0c1tvXTsKCSAgcmV0dXJuIG8udHlwZSA9PT0gIkdlb21ldHJ5Q29sbGVjdGlvbiIKCSAgICAgID8ge3R5cGU6ICJGZWF0dXJlQ29sbGVjdGlvbiIsIGZlYXR1cmVzOiBvLmdlb21ldHJpZXMubWFwKGZ1bmN0aW9uKG8pIHsgcmV0dXJuIGZlYXR1cmUodG9wb2xvZ3ksIG8pOyB9KX0KCSAgICAgIDogZmVhdHVyZSh0b3BvbG9neSwgbyk7Cgl9CgoJZnVuY3Rpb24gZmVhdHVyZSh0b3BvbG9neSwgbykgewoJICB2YXIgaWQgPSBvLmlkLAoJICAgICAgYmJveCA9IG8uYmJveCwKCSAgICAgIHByb3BlcnRpZXMgPSBvLnByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogby5wcm9wZXJ0aWVzLAoJICAgICAgZ2VvbWV0cnkgPSBvYmplY3QodG9wb2xvZ3ksIG8pOwoJICByZXR1cm4gaWQgPT0gbnVsbCAmJiBiYm94ID09IG51bGwgPyB7dHlwZTogIkZlYXR1cmUiLCBwcm9wZXJ0aWVzOiBwcm9wZXJ0aWVzLCBnZW9tZXRyeTogZ2VvbWV0cnl9CgkgICAgICA6IGJib3ggPT0gbnVsbCA/IHt0eXBlOiAiRmVhdHVyZSIsIGlkOiBpZCwgcHJvcGVydGllczogcHJvcGVydGllcywgZ2VvbWV0cnk6IGdlb21ldHJ5fQoJICAgICAgOiB7dHlwZTogIkZlYXR1cmUiLCBpZDogaWQsIGJib3g6IGJib3gsIHByb3BlcnRpZXM6IHByb3BlcnRpZXMsIGdlb21ldHJ5OiBnZW9tZXRyeX07Cgl9CgoJZnVuY3Rpb24gb2JqZWN0KHRvcG9sb2d5LCBvKSB7CgkgIHZhciB0cmFuc2Zvcm1Qb2ludCA9IHRyYW5zZm9ybSh0b3BvbG9neS50cmFuc2Zvcm0pLAoJICAgICAgYXJjcyA9IHRvcG9sb2d5LmFyY3M7CgoJICBmdW5jdGlvbiBhcmMoaSwgcG9pbnRzKSB7CgkgICAgaWYgKHBvaW50cy5sZW5ndGgpIHBvaW50cy5wb3AoKTsKCSAgICBmb3IgKHZhciBhID0gYXJjc1tpIDwgMCA/IH5pIDogaV0sIGsgPSAwLCBuID0gYS5sZW5ndGg7IGsgPCBuOyArK2spIHsKCSAgICAgIHBvaW50cy5wdXNoKHRyYW5zZm9ybVBvaW50KGFba10sIGspKTsKCSAgICB9CgkgICAgaWYgKGkgPCAwKSByZXZlcnNlKHBvaW50cywgbik7CgkgIH0KCgkgIGZ1bmN0aW9uIHBvaW50KHApIHsKCSAgICByZXR1cm4gdHJhbnNmb3JtUG9pbnQocCk7CgkgIH0KCgkgIGZ1bmN0aW9uIGxpbmUoYXJjcykgewoJICAgIHZhciBwb2ludHMgPSBbXTsKCSAgICBmb3IgKHZhciBpID0gMCwgbiA9IGFyY3MubGVuZ3RoOyBpIDwgbjsgKytpKSBhcmMoYXJjc1tpXSwgcG9pbnRzKTsKCSAgICBpZiAocG9pbnRzLmxlbmd0aCA8IDIpIHBvaW50cy5wdXNoKHBvaW50c1swXSk7IC8vIFRoaXMgc2hvdWxkIG5ldmVyIGhhcHBlbiBwZXIgdGhlIHNwZWNpZmljYXRpb24uCgkgICAgcmV0dXJuIHBvaW50czsKCSAgfQoKCSAgZnVuY3Rpb24gcmluZyhhcmNzKSB7CgkgICAgdmFyIHBvaW50cyA9IGxpbmUoYXJjcyk7CgkgICAgd2hpbGUgKHBvaW50cy5sZW5ndGggPCA0KSBwb2ludHMucHVzaChwb2ludHNbMF0pOyAvLyBUaGlzIG1heSBoYXBwZW4gaWYgYW4gYXJjIGhhcyBvbmx5IHR3byBwb2ludHMuCgkgICAgcmV0dXJuIHBvaW50czsKCSAgfQoKCSAgZnVuY3Rpb24gcG9seWdvbihhcmNzKSB7CgkgICAgcmV0dXJuIGFyY3MubWFwKHJpbmcpOwoJICB9CgoJICBmdW5jdGlvbiBnZW9tZXRyeShvKSB7CgkgICAgdmFyIHR5cGUgPSBvLnR5cGUsIGNvb3JkaW5hdGVzOwoJICAgIHN3aXRjaCAodHlwZSkgewoJICAgICAgY2FzZSAiR2VvbWV0cnlDb2xsZWN0aW9uIjogcmV0dXJuIHt0eXBlOiB0eXBlLCBnZW9tZXRyaWVzOiBvLmdlb21ldHJpZXMubWFwKGdlb21ldHJ5KX07CgkgICAgICBjYXNlICJQb2ludCI6IGNvb3JkaW5hdGVzID0gcG9pbnQoby5jb29yZGluYXRlcyk7IGJyZWFrOwoJICAgICAgY2FzZSAiTXVsdGlQb2ludCI6IGNvb3JkaW5hdGVzID0gby5jb29yZGluYXRlcy5tYXAocG9pbnQpOyBicmVhazsKCSAgICAgIGNhc2UgIkxpbmVTdHJpbmciOiBjb29yZGluYXRlcyA9IGxpbmUoby5hcmNzKTsgYnJlYWs7CgkgICAgICBjYXNlICJNdWx0aUxpbmVTdHJpbmciOiBjb29yZGluYXRlcyA9IG8uYXJjcy5tYXAobGluZSk7IGJyZWFrOwoJICAgICAgY2FzZSAiUG9seWdvbiI6IGNvb3JkaW5hdGVzID0gcG9seWdvbihvLmFyY3MpOyBicmVhazsKCSAgICAgIGNhc2UgIk11bHRpUG9seWdvbiI6IGNvb3JkaW5hdGVzID0gby5hcmNzLm1hcChwb2x5Z29uKTsgYnJlYWs7CgkgICAgICBkZWZhdWx0OiByZXR1cm4gbnVsbDsKCSAgICB9CgkgICAgcmV0dXJuIHt0eXBlOiB0eXBlLCBjb29yZGluYXRlczogY29vcmRpbmF0ZXN9OwoJICB9CgoJICByZXR1cm4gZ2VvbWV0cnkobyk7Cgl9CgoJZnVuY3Rpb24gJChlbGVtZW50LCB0YWdOYW1lKSB7CgkgICAgcmV0dXJuIEFycmF5LmZyb20oZWxlbWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSh0YWdOYW1lKSk7Cgl9CglmdW5jdGlvbiBub3JtYWxpemVJZChpZCkgewoJICAgIHJldHVybiBpZFswXSA9PT0gIiMiID8gaWQgOiBgIyR7aWR9YDsKCX0KCWZ1bmN0aW9uICRucyhlbGVtZW50LCB0YWdOYW1lLCBucykgewoJICAgIHJldHVybiBBcnJheS5mcm9tKGVsZW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWVOUyhucywgdGFnTmFtZSkpOwoJfQoJLyoqCgkgKiBnZXQgdGhlIGNvbnRlbnQgb2YgYSB0ZXh0IG5vZGUsIGlmIGFueQoJICovCglmdW5jdGlvbiBub2RlVmFsKG5vZGUpIHsKCSAgICBub2RlPy5ub3JtYWxpemUoKTsKCSAgICByZXR1cm4gKG5vZGUgJiYgbm9kZS50ZXh0Q29udGVudCkgfHwgIiI7Cgl9CgkvKioKCSAqIEdldCBvbmUgWSBjaGlsZCBvZiBYLCBpZiBhbnksIG90aGVyd2lzZSBudWxsCgkgKi8KCWZ1bmN0aW9uIGdldDEobm9kZSwgdGFnTmFtZSwgY2FsbGJhY2spIHsKCSAgICBjb25zdCBuID0gbm9kZS5nZXRFbGVtZW50c0J5VGFnTmFtZSh0YWdOYW1lKTsKCSAgICBjb25zdCByZXN1bHQgPSBuLmxlbmd0aCA/IG5bMF0gOiBudWxsOwoJICAgIGlmIChyZXN1bHQgJiYgY2FsbGJhY2spCgkgICAgICAgIGNhbGxiYWNrKHJlc3VsdCk7CgkgICAgcmV0dXJuIHJlc3VsdDsKCX0KCWZ1bmN0aW9uIGdldChub2RlLCB0YWdOYW1lLCBjYWxsYmFjaykgewoJICAgIGNvbnN0IHByb3BlcnRpZXMgPSB7fTsKCSAgICBpZiAoIW5vZGUpCgkgICAgICAgIHJldHVybiBwcm9wZXJ0aWVzOwoJICAgIGNvbnN0IG4gPSBub2RlLmdldEVsZW1lbnRzQnlUYWdOYW1lKHRhZ05hbWUpOwoJICAgIGNvbnN0IHJlc3VsdCA9IG4ubGVuZ3RoID8gblswXSA6IG51bGw7CgkgICAgaWYgKHJlc3VsdCAmJiBjYWxsYmFjaykgewoJICAgICAgICByZXR1cm4gY2FsbGJhY2socmVzdWx0LCBwcm9wZXJ0aWVzKTsKCSAgICB9CgkgICAgcmV0dXJuIHByb3BlcnRpZXM7Cgl9CglmdW5jdGlvbiB2YWwxKG5vZGUsIHRhZ05hbWUsIGNhbGxiYWNrKSB7CgkgICAgY29uc3QgdmFsID0gbm9kZVZhbChnZXQxKG5vZGUsIHRhZ05hbWUpKTsKCSAgICBpZiAodmFsICYmIGNhbGxiYWNrKQoJICAgICAgICByZXR1cm4gY2FsbGJhY2sodmFsKSB8fCB7fTsKCSAgICByZXR1cm4ge307Cgl9CglmdW5jdGlvbiAkbnVtKG5vZGUsIHRhZ05hbWUsIGNhbGxiYWNrKSB7CgkgICAgY29uc3QgdmFsID0gcGFyc2VGbG9hdChub2RlVmFsKGdldDEobm9kZSwgdGFnTmFtZSkpKTsKCSAgICBpZiAoaXNOYU4odmFsKSkKCSAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDsKCSAgICBpZiAodmFsICYmIGNhbGxiYWNrKQoJICAgICAgICByZXR1cm4gY2FsbGJhY2sodmFsKSB8fCB7fTsKCSAgICByZXR1cm4ge307Cgl9CglmdW5jdGlvbiBudW0xKG5vZGUsIHRhZ05hbWUsIGNhbGxiYWNrKSB7CgkgICAgY29uc3QgdmFsID0gcGFyc2VGbG9hdChub2RlVmFsKGdldDEobm9kZSwgdGFnTmFtZSkpKTsKCSAgICBpZiAoaXNOYU4odmFsKSkKCSAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDsKCSAgICBpZiAodmFsICYmIGNhbGxiYWNrKQoJICAgICAgICBjYWxsYmFjayh2YWwpOwoJICAgIHJldHVybiB2YWw7Cgl9CglmdW5jdGlvbiBnZXRNdWx0aShub2RlLCBwcm9wZXJ0eU5hbWVzKSB7CgkgICAgY29uc3QgcHJvcGVydGllcyA9IHt9OwoJICAgIGZvciAoY29uc3QgcHJvcGVydHkgb2YgcHJvcGVydHlOYW1lcykgewoJICAgICAgICB2YWwxKG5vZGUsIHByb3BlcnR5LCAodmFsKSA9PiB7CgkgICAgICAgICAgICBwcm9wZXJ0aWVzW3Byb3BlcnR5XSA9IHZhbDsKCSAgICAgICAgfSk7CgkgICAgfQoJICAgIHJldHVybiBwcm9wZXJ0aWVzOwoJfQoJZnVuY3Rpb24gaXNFbGVtZW50KG5vZGUpIHsKCSAgICByZXR1cm4gbm9kZT8ubm9kZVR5cGUgPT09IDE7Cgl9CgoJZnVuY3Rpb24gZ2V0TGluZVN0eWxlKG5vZGUpIHsKCSAgICByZXR1cm4gZ2V0KG5vZGUsICJsaW5lIiwgKGxpbmVTdHlsZSkgPT4gewoJICAgICAgICBjb25zdCB2YWwgPSBPYmplY3QuYXNzaWduKHt9LCB2YWwxKGxpbmVTdHlsZSwgImNvbG9yIiwgKGNvbG9yKSA9PiB7CgkgICAgICAgICAgICByZXR1cm4geyBzdHJva2U6IGAjJHtjb2xvcn1gIH07CgkgICAgICAgIH0pLCAkbnVtKGxpbmVTdHlsZSwgIm9wYWNpdHkiLCAob3BhY2l0eSkgPT4gewoJICAgICAgICAgICAgcmV0dXJuIHsgInN0cm9rZS1vcGFjaXR5Ijogb3BhY2l0eSB9OwoJICAgICAgICB9KSwgJG51bShsaW5lU3R5bGUsICJ3aWR0aCIsICh3aWR0aCkgPT4gewoJICAgICAgICAgICAgLy8gR1BYIHdpZHRoIGlzIGluIG1tLCBjb252ZXJ0IHRvIHB4IHdpdGggOTYgcHggcGVyIGluY2gKCSAgICAgICAgICAgIHJldHVybiB7ICJzdHJva2Utd2lkdGgiOiAod2lkdGggKiA5NikgLyAyNS40IH07CgkgICAgICAgIH0pKTsKCSAgICAgICAgcmV0dXJuIHZhbDsKCSAgICB9KTsKCX0KCglmdW5jdGlvbiBnZXRFeHRlbnNpb25zKG5vZGUpIHsKCSAgICBsZXQgdmFsdWVzID0gW107CgkgICAgaWYgKG5vZGUgPT09IG51bGwpCgkgICAgICAgIHJldHVybiB2YWx1ZXM7CgkgICAgZm9yIChjb25zdCBjaGlsZCBvZiBBcnJheS5mcm9tKG5vZGUuY2hpbGROb2RlcykpIHsKCSAgICAgICAgaWYgKCFpc0VsZW1lbnQoY2hpbGQpKQoJICAgICAgICAgICAgY29udGludWU7CgkgICAgICAgIGNvbnN0IG5hbWUgPSBhYmJyZXZpYXRlTmFtZShjaGlsZC5ub2RlTmFtZSk7CgkgICAgICAgIGlmIChuYW1lID09PSAiZ3B4dHB4OlRyYWNrUG9pbnRFeHRlbnNpb24iKSB7CgkgICAgICAgICAgICAvLyBsb29wIGFnYWluIGZvciBuZXN0ZWQgZ2FybWluIGV4dGVuc2lvbnMgKGVnLiAiZ3B4dHB4OmhyIikKCSAgICAgICAgICAgIHZhbHVlcyA9IHZhbHVlcy5jb25jYXQoZ2V0RXh0ZW5zaW9ucyhjaGlsZCkpOwoJICAgICAgICB9CgkgICAgICAgIGVsc2UgewoJICAgICAgICAgICAgLy8gcHVzaCBjdXN0b20gZXh0ZW5zaW9uIChlZy4gInBvd2VyIikKCSAgICAgICAgICAgIGNvbnN0IHZhbCA9IG5vZGVWYWwoY2hpbGQpOwoJICAgICAgICAgICAgdmFsdWVzLnB1c2goW25hbWUsIHBhcnNlTnVtZXJpYyh2YWwpXSk7CgkgICAgICAgIH0KCSAgICB9CgkgICAgcmV0dXJuIHZhbHVlczsKCX0KCWZ1bmN0aW9uIGFiYnJldmlhdGVOYW1lKG5hbWUpIHsKCSAgICByZXR1cm4gWyJoZWFydCIsICJncHh0cHg6aHIiLCAiaHIiXS5pbmNsdWRlcyhuYW1lKSA/ICJoZWFydCIgOiBuYW1lOwoJfQoJZnVuY3Rpb24gcGFyc2VOdW1lcmljKHZhbCkgewoJICAgIGNvbnN0IG51bSA9IHBhcnNlRmxvYXQodmFsKTsKCSAgICByZXR1cm4gaXNOYU4obnVtKSA/IHZhbCA6IG51bTsKCX0KCglmdW5jdGlvbiBjb29yZFBhaXIkMShub2RlKSB7CgkgICAgY29uc3QgbGwgPSBbCgkgICAgICAgIHBhcnNlRmxvYXQobm9kZS5nZXRBdHRyaWJ1dGUoImxvbiIpIHx8ICIiKSwKCSAgICAgICAgcGFyc2VGbG9hdChub2RlLmdldEF0dHJpYnV0ZSgibGF0IikgfHwgIiIpLAoJICAgIF07CgkgICAgaWYgKGlzTmFOKGxsWzBdKSB8fCBpc05hTihsbFsxXSkpIHsKCSAgICAgICAgcmV0dXJuIG51bGw7CgkgICAgfQoJICAgIG51bTEobm9kZSwgImVsZSIsICh2YWwpID0+IHsKCSAgICAgICAgbGwucHVzaCh2YWwpOwoJICAgIH0pOwoJICAgIGNvbnN0IHRpbWUgPSBnZXQxKG5vZGUsICJ0aW1lIik7CgkgICAgcmV0dXJuIHsKCSAgICAgICAgY29vcmRpbmF0ZXM6IGxsLAoJICAgICAgICB0aW1lOiB0aW1lID8gbm9kZVZhbCh0aW1lKSA6IG51bGwsCgkgICAgICAgIGV4dGVuZGVkVmFsdWVzOiBnZXRFeHRlbnNpb25zKGdldDEobm9kZSwgImV4dGVuc2lvbnMiKSksCgkgICAgfTsKCX0KCglmdW5jdGlvbiBleHRyYWN0UHJvcGVydGllcyhub2RlKSB7CgkgICAgY29uc3QgcHJvcGVydGllcyA9IGdldE11bHRpKG5vZGUsIFsKCSAgICAgICAgIm5hbWUiLAoJICAgICAgICAiY210IiwKCSAgICAgICAgImRlc2MiLAoJICAgICAgICAidHlwZSIsCgkgICAgICAgICJ0aW1lIiwKCSAgICAgICAgImtleXdvcmRzIiwKCSAgICBdKTsKCSAgICBjb25zdCBleHRlbnNpb25zID0gQXJyYXkuZnJvbShub2RlLmdldEVsZW1lbnRzQnlUYWdOYW1lTlMoImh0dHA6Ly93d3cuZ2FybWluLmNvbS94bWxzY2hlbWFzL0dweEV4dGVuc2lvbnMvdjMiLCAiKiIpKTsKCSAgICBmb3IgKGNvbnN0IGNoaWxkIG9mIGV4dGVuc2lvbnMpIHsKCSAgICAgICAgaWYgKGNoaWxkLnBhcmVudE5vZGU/LnBhcmVudE5vZGUgPT09IG5vZGUpIHsKCSAgICAgICAgICAgIHByb3BlcnRpZXNbY2hpbGQudGFnTmFtZS5yZXBsYWNlKCI6IiwgIl8iKV0gPSBub2RlVmFsKGNoaWxkKTsKCSAgICAgICAgfQoJICAgIH0KCSAgICBjb25zdCBsaW5rcyA9ICQobm9kZSwgImxpbmsiKTsKCSAgICBpZiAobGlua3MubGVuZ3RoKSB7CgkgICAgICAgIHByb3BlcnRpZXMubGlua3MgPSBsaW5rcy5tYXAoKGxpbmspID0+IE9iamVjdC5hc3NpZ24oeyBocmVmOiBsaW5rLmdldEF0dHJpYnV0ZSgiaHJlZiIpIH0sIGdldE11bHRpKGxpbmssIFsidGV4dCIsICJ0eXBlIl0pKSk7CgkgICAgfQoJICAgIHJldHVybiBwcm9wZXJ0aWVzOwoJfQoKCS8qKgoJICogRXh0cmFjdCBwb2ludHMgZnJvbSBhIHRya3NlZyBvciBydGUgZWxlbWVudC4KCSAqLwoJZnVuY3Rpb24gZ2V0UG9pbnRzJDEobm9kZSwgcG9pbnRuYW1lKSB7CgkgICAgY29uc3QgcHRzID0gJChub2RlLCBwb2ludG5hbWUpOwoJICAgIGNvbnN0IGxpbmUgPSBbXTsKCSAgICBjb25zdCB0aW1lcyA9IFtdOwoJICAgIGNvbnN0IGV4dGVuZGVkVmFsdWVzID0ge307CgkgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwdHMubGVuZ3RoOyBpKyspIHsKCSAgICAgICAgY29uc3QgYyA9IGNvb3JkUGFpciQxKHB0c1tpXSk7CgkgICAgICAgIGlmICghYykgewoJICAgICAgICAgICAgY29udGludWU7CgkgICAgICAgIH0KCSAgICAgICAgbGluZS5wdXNoKGMuY29vcmRpbmF0ZXMpOwoJICAgICAgICBpZiAoYy50aW1lKQoJICAgICAgICAgICAgdGltZXMucHVzaChjLnRpbWUpOwoJICAgICAgICBmb3IgKGNvbnN0IFtuYW1lLCB2YWxdIG9mIGMuZXh0ZW5kZWRWYWx1ZXMpIHsKCSAgICAgICAgICAgIGNvbnN0IHBsdXJhbCA9IG5hbWUgPT09ICJoZWFydCIgPyBuYW1lIDogbmFtZS5yZXBsYWNlKCJncHh0cHg6IiwgIiIpICsgInMiOwoJICAgICAgICAgICAgaWYgKCFleHRlbmRlZFZhbHVlc1twbHVyYWxdKSB7CgkgICAgICAgICAgICAgICAgZXh0ZW5kZWRWYWx1ZXNbcGx1cmFsXSA9IEFycmF5KHB0cy5sZW5ndGgpLmZpbGwobnVsbCk7CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICBleHRlbmRlZFZhbHVlc1twbHVyYWxdW2ldID0gdmFsOwoJICAgICAgICB9CgkgICAgfQoJICAgIGlmIChsaW5lLmxlbmd0aCA8IDIpCgkgICAgICAgIHJldHVybjsgLy8gSW52YWxpZCBsaW5lIGluIEdlb0pTT04KCSAgICByZXR1cm4gewoJICAgICAgICBsaW5lOiBsaW5lLAoJICAgICAgICB0aW1lczogdGltZXMsCgkgICAgICAgIGV4dGVuZGVkVmFsdWVzOiBleHRlbmRlZFZhbHVlcywKCSAgICB9OwoJfQoJLyoqCgkgKiBFeHRyYWN0IGEgTGluZVN0cmluZyBnZW9tZXRyeSBmcm9tIGEgcnRlCgkgKiBlbGVtZW50LgoJICovCglmdW5jdGlvbiBnZXRSb3V0ZShub2RlKSB7CgkgICAgY29uc3QgbGluZSA9IGdldFBvaW50cyQxKG5vZGUsICJydGVwdCIpOwoJICAgIGlmICghbGluZSkKCSAgICAgICAgcmV0dXJuOwoJICAgIHJldHVybiB7CgkgICAgICAgIHR5cGU6ICJGZWF0dXJlIiwKCSAgICAgICAgcHJvcGVydGllczogT2JqZWN0LmFzc2lnbih7IF9ncHhUeXBlOiAicnRlIiB9LCBleHRyYWN0UHJvcGVydGllcyhub2RlKSwgZ2V0TGluZVN0eWxlKGdldDEobm9kZSwgImV4dGVuc2lvbnMiKSkpLAoJICAgICAgICBnZW9tZXRyeTogewoJICAgICAgICAgICAgdHlwZTogIkxpbmVTdHJpbmciLAoJICAgICAgICAgICAgY29vcmRpbmF0ZXM6IGxpbmUubGluZSwKCSAgICAgICAgfSwKCSAgICB9OwoJfQoJZnVuY3Rpb24gZ2V0VHJhY2sobm9kZSkgewoJICAgIGNvbnN0IHNlZ21lbnRzID0gJChub2RlLCAidHJrc2VnIik7CgkgICAgY29uc3QgdHJhY2sgPSBbXTsKCSAgICBjb25zdCB0aW1lcyA9IFtdOwoJICAgIGNvbnN0IGV4dHJhY3RlZExpbmVzID0gW107CgkgICAgZm9yIChjb25zdCBzZWdtZW50IG9mIHNlZ21lbnRzKSB7CgkgICAgICAgIGNvbnN0IGxpbmUgPSBnZXRQb2ludHMkMShzZWdtZW50LCAidHJrcHQiKTsKCSAgICAgICAgaWYgKGxpbmUpIHsKCSAgICAgICAgICAgIGV4dHJhY3RlZExpbmVzLnB1c2gobGluZSk7CgkgICAgICAgICAgICBpZiAobGluZS50aW1lcyAmJiBsaW5lLnRpbWVzLmxlbmd0aCkKCSAgICAgICAgICAgICAgICB0aW1lcy5wdXNoKGxpbmUudGltZXMpOwoJICAgICAgICB9CgkgICAgfQoJICAgIGlmIChleHRyYWN0ZWRMaW5lcy5sZW5ndGggPT09IDApCgkgICAgICAgIHJldHVybiBudWxsOwoJICAgIGNvbnN0IG11bHRpID0gZXh0cmFjdGVkTGluZXMubGVuZ3RoID4gMTsKCSAgICBjb25zdCBwcm9wZXJ0aWVzID0gT2JqZWN0LmFzc2lnbih7IF9ncHhUeXBlOiAidHJrIiB9LCBleHRyYWN0UHJvcGVydGllcyhub2RlKSwgZ2V0TGluZVN0eWxlKGdldDEobm9kZSwgImV4dGVuc2lvbnMiKSksIHRpbWVzLmxlbmd0aAoJICAgICAgICA/IHsKCSAgICAgICAgICAgIGNvb3JkaW5hdGVQcm9wZXJ0aWVzOiB7CgkgICAgICAgICAgICAgICAgdGltZXM6IG11bHRpID8gdGltZXMgOiB0aW1lc1swXSwKCSAgICAgICAgICAgIH0sCgkgICAgICAgIH0KCSAgICAgICAgOiB7fSk7CgkgICAgZm9yIChjb25zdCBsaW5lIG9mIGV4dHJhY3RlZExpbmVzKSB7CgkgICAgICAgIHRyYWNrLnB1c2gobGluZS5saW5lKTsKCSAgICAgICAgaWYgKCFwcm9wZXJ0aWVzLmNvb3JkaW5hdGVQcm9wZXJ0aWVzKSB7CgkgICAgICAgICAgICBwcm9wZXJ0aWVzLmNvb3JkaW5hdGVQcm9wZXJ0aWVzID0ge307CgkgICAgICAgIH0KCSAgICAgICAgY29uc3QgcHJvcHMgPSBwcm9wZXJ0aWVzLmNvb3JkaW5hdGVQcm9wZXJ0aWVzOwoJICAgICAgICBjb25zdCBlbnRyaWVzID0gT2JqZWN0LmVudHJpZXMobGluZS5leHRlbmRlZFZhbHVlcyk7CgkgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZW50cmllcy5sZW5ndGg7IGkrKykgewoJICAgICAgICAgICAgY29uc3QgW25hbWUsIHZhbF0gPSBlbnRyaWVzW2ldOwoJICAgICAgICAgICAgaWYgKG11bHRpKSB7CgkgICAgICAgICAgICAgICAgaWYgKCFwcm9wc1tuYW1lXSkgewoJICAgICAgICAgICAgICAgICAgICBwcm9wc1tuYW1lXSA9IGV4dHJhY3RlZExpbmVzLm1hcCgobGluZSkgPT4gbmV3IEFycmF5KGxpbmUubGluZS5sZW5ndGgpLmZpbGwobnVsbCkpOwoJICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgICAgICBwcm9wc1tuYW1lXVtpXSA9IHZhbDsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIGVsc2UgewoJICAgICAgICAgICAgICAgIHByb3BzW25hbWVdID0gdmFsOwoJICAgICAgICAgICAgfQoJICAgICAgICB9CgkgICAgfQoJICAgIHJldHVybiB7CgkgICAgICAgIHR5cGU6ICJGZWF0dXJlIiwKCSAgICAgICAgcHJvcGVydGllczogcHJvcGVydGllcywKCSAgICAgICAgZ2VvbWV0cnk6IG11bHRpCgkgICAgICAgICAgICA/IHsKCSAgICAgICAgICAgICAgICB0eXBlOiAiTXVsdGlMaW5lU3RyaW5nIiwKCSAgICAgICAgICAgICAgICBjb29yZGluYXRlczogdHJhY2ssCgkgICAgICAgICAgICB9CgkgICAgICAgICAgICA6IHsKCSAgICAgICAgICAgICAgICB0eXBlOiAiTGluZVN0cmluZyIsCgkgICAgICAgICAgICAgICAgY29vcmRpbmF0ZXM6IHRyYWNrWzBdLAoJICAgICAgICAgICAgfSwKCSAgICB9OwoJfQoJLyoqCgkgKiBFeHRyYWN0IGEgcG9pbnQsIGlmIHBvc3NpYmxlLCBmcm9tIGEgZ2l2ZW4gbm9kZSwKCSAqIHdoaWNoIGlzIHVzdWFsbHkgYSB3cHQgb3IgdHJrcHQKCSAqLwoJZnVuY3Rpb24gZ2V0UG9pbnQobm9kZSkgewoJICAgIGNvbnN0IHByb3BlcnRpZXMgPSBPYmplY3QuYXNzaWduKGV4dHJhY3RQcm9wZXJ0aWVzKG5vZGUpLCBnZXRNdWx0aShub2RlLCBbInN5bSJdKSk7CgkgICAgY29uc3QgcGFpciA9IGNvb3JkUGFpciQxKG5vZGUpOwoJICAgIGlmICghcGFpcikKCSAgICAgICAgcmV0dXJuIG51bGw7CgkgICAgcmV0dXJuIHsKCSAgICAgICAgdHlwZTogIkZlYXR1cmUiLAoJICAgICAgICBwcm9wZXJ0aWVzLAoJICAgICAgICBnZW9tZXRyeTogewoJICAgICAgICAgICAgdHlwZTogIlBvaW50IiwKCSAgICAgICAgICAgIGNvb3JkaW5hdGVzOiBwYWlyLmNvb3JkaW5hdGVzLAoJICAgICAgICB9LAoJICAgIH07Cgl9CgkvKioKCSAqIENvbnZlcnQgR1BYIHRvIEdlb0pTT04gaW5jcmVtZW50YWxseSwgcmV0dXJuaW5nCgkgKiBhIFtHZW5lcmF0b3JdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvR3VpZGUvSXRlcmF0b3JzX2FuZF9HZW5lcmF0b3JzKQoJICogdGhhdCB5aWVsZHMgb3V0cHV0IGZlYXR1cmUgYnkgZmVhdHVyZS4KCSAqLwoJZnVuY3Rpb24qIGdweEdlbihub2RlKSB7CgkgICAgZm9yIChjb25zdCB0cmFjayBvZiAkKG5vZGUsICJ0cmsiKSkgewoJICAgICAgICBjb25zdCBmZWF0dXJlID0gZ2V0VHJhY2sodHJhY2spOwoJICAgICAgICBpZiAoZmVhdHVyZSkKCSAgICAgICAgICAgIHlpZWxkIGZlYXR1cmU7CgkgICAgfQoJICAgIGZvciAoY29uc3Qgcm91dGUgb2YgJChub2RlLCAicnRlIikpIHsKCSAgICAgICAgY29uc3QgZmVhdHVyZSA9IGdldFJvdXRlKHJvdXRlKTsKCSAgICAgICAgaWYgKGZlYXR1cmUpCgkgICAgICAgICAgICB5aWVsZCBmZWF0dXJlOwoJICAgIH0KCSAgICBmb3IgKGNvbnN0IHdheXBvaW50IG9mICQobm9kZSwgIndwdCIpKSB7CgkgICAgICAgIGNvbnN0IHBvaW50ID0gZ2V0UG9pbnQod2F5cG9pbnQpOwoJICAgICAgICBpZiAocG9pbnQpCgkgICAgICAgICAgICB5aWVsZCBwb2ludDsKCSAgICB9Cgl9CgkvKioKCSAqCgkgKiBDb252ZXJ0IGEgR1BYIGRvY3VtZW50IHRvIEdlb0pTT04uIFRoZSBmaXJzdCBhcmd1bWVudCwgYGRvY2AsIG11c3QgYmUgYSBHUFgKCSAqIGRvY3VtZW50IGFzIGFuIFhNTCBET00gLSBub3QgYXMgYSBzdHJpbmcuIFlvdSBjYW4gZ2V0IHRoaXMgdXNpbmcgalF1ZXJ5J3MgZGVmYXVsdAoJICogYC5hamF4YCBmdW5jdGlvbiBvciB1c2luZyBhIGJhcmUgWE1MSHR0cFJlcXVlc3Qgd2l0aCB0aGUgYC5yZXNwb25zZWAgcHJvcGVydHkKCSAqIGhvbGRpbmcgYW4gWE1MIERPTS4KCSAqCgkgKiBUaGUgb3V0cHV0IGlzIGEgSmF2YVNjcmlwdCBvYmplY3Qgb2YgR2VvSlNPTiBkYXRhLCBzYW1lIGFzIGAua21sYCBvdXRwdXRzLCB3aXRoIHRoZQoJICogYWRkaXRpb24gb2YgYSBgX2dweFR5cGVgIHByb3BlcnR5IG9uIGVhY2ggYExpbmVTdHJpbmdgIGZlYXR1cmUgdGhhdCBpbmRpY2F0ZXMgd2hldGhlcgoJICogdGhlIGZlYXR1cmUgd2FzIGVuY29kZWQgYXMgYSByb3V0ZSAoYHJ0ZWApIG9yIHRyYWNrIChgdHJrYCkgaW4gdGhlIEdQWCBkb2N1bWVudC4KCSAqLwoJZnVuY3Rpb24gZ3B4KG5vZGUpIHsKCSAgICByZXR1cm4gewoJICAgICAgICB0eXBlOiAiRmVhdHVyZUNvbGxlY3Rpb24iLAoJICAgICAgICBmZWF0dXJlczogQXJyYXkuZnJvbShncHhHZW4obm9kZSkpLAoJICAgIH07Cgl9CgoJY29uc3QgRVhURU5TSU9OU19OUyA9ICJodHRwOi8vd3d3Lmdhcm1pbi5jb20veG1sc2NoZW1hcy9BY3Rpdml0eUV4dGVuc2lvbi92MiI7Cgljb25zdCBUUkFDS1BPSU5UX0FUVFJJQlVURVMgPSBbCgkgICAgWyJoZWFydFJhdGUiLCAiaGVhcnRSYXRlcyJdLAoJICAgIFsiQ2FkZW5jZSIsICJjYWRlbmNlcyJdLAoJICAgIC8vIEV4dGVuZGVkIFRyYWNrcG9pbnQgYXR0cmlidXRlcwoJICAgIFsiU3BlZWQiLCAic3BlZWRzIl0sCgkgICAgWyJXYXR0cyIsICJ3YXR0cyJdLAoJXTsKCWNvbnN0IExBUF9BVFRSSUJVVEVTID0gWwoJICAgIFsiVG90YWxUaW1lU2Vjb25kcyIsICJ0b3RhbFRpbWVTZWNvbmRzIl0sCgkgICAgWyJEaXN0YW5jZU1ldGVycyIsICJkaXN0YW5jZU1ldGVycyJdLAoJICAgIFsiTWF4aW11bVNwZWVkIiwgIm1heFNwZWVkIl0sCgkgICAgWyJBdmVyYWdlSGVhcnRSYXRlQnBtIiwgImF2Z0hlYXJ0UmF0ZSJdLAoJICAgIFsiTWF4aW11bUhlYXJ0UmF0ZUJwbSIsICJtYXhIZWFydFJhdGUiXSwKCSAgICAvLyBFeHRlbmRlZCBMYXAgYXR0cmlidXRlcwoJICAgIFsiQXZnU3BlZWQiLCAiYXZnU3BlZWQiXSwKCSAgICBbIkF2Z1dhdHRzIiwgImF2Z1dhdHRzIl0sCgkgICAgWyJNYXhXYXR0cyIsICJtYXhXYXR0cyJdLAoJXTsKCWZ1bmN0aW9uIGdldFByb3BlcnRpZXMobm9kZSwgYXR0cmlidXRlTmFtZXMpIHsKCSAgICBjb25zdCBwcm9wZXJ0aWVzID0gW107CgkgICAgZm9yIChjb25zdCBbdGFnLCBhbGlhc10gb2YgYXR0cmlidXRlTmFtZXMpIHsKCSAgICAgICAgbGV0IGVsZW0gPSBnZXQxKG5vZGUsIHRhZyk7CgkgICAgICAgIGlmICghZWxlbSkgewoJICAgICAgICAgICAgY29uc3QgZWxlbWVudHMgPSBub2RlLmdldEVsZW1lbnRzQnlUYWdOYW1lTlMoRVhURU5TSU9OU19OUywgdGFnKTsKCSAgICAgICAgICAgIGlmIChlbGVtZW50cy5sZW5ndGgpIHsKCSAgICAgICAgICAgICAgICBlbGVtID0gZWxlbWVudHNbMF07CgkgICAgICAgICAgICB9CgkgICAgICAgIH0KCSAgICAgICAgY29uc3QgdmFsID0gcGFyc2VGbG9hdChub2RlVmFsKGVsZW0pKTsKCSAgICAgICAgaWYgKCFpc05hTih2YWwpKSB7CgkgICAgICAgICAgICBwcm9wZXJ0aWVzLnB1c2goW2FsaWFzLCB2YWxdKTsKCSAgICAgICAgfQoJICAgIH0KCSAgICByZXR1cm4gcHJvcGVydGllczsKCX0KCWZ1bmN0aW9uIGNvb3JkUGFpcihub2RlKSB7CgkgICAgY29uc3QgbGwgPSBbbnVtMShub2RlLCAiTG9uZ2l0dWRlRGVncmVlcyIpLCBudW0xKG5vZGUsICJMYXRpdHVkZURlZ3JlZXMiKV07CgkgICAgaWYgKGxsWzBdID09PSB1bmRlZmluZWQgfHwKCSAgICAgICAgaXNOYU4obGxbMF0pIHx8CgkgICAgICAgIGxsWzFdID09PSB1bmRlZmluZWQgfHwKCSAgICAgICAgaXNOYU4obGxbMV0pKSB7CgkgICAgICAgIHJldHVybiBudWxsOwoJICAgIH0KCSAgICBjb25zdCBoZWFydFJhdGUgPSBnZXQxKG5vZGUsICJIZWFydFJhdGVCcG0iKTsKCSAgICBjb25zdCB0aW1lID0gbm9kZVZhbChnZXQxKG5vZGUsICJUaW1lIikpOwoJICAgIGdldDEobm9kZSwgIkFsdGl0dWRlTWV0ZXJzIiwgKGFsdCkgPT4gewoJICAgICAgICBjb25zdCBhID0gcGFyc2VGbG9hdChub2RlVmFsKGFsdCkpOwoJICAgICAgICBpZiAoIWlzTmFOKGEpKSB7CgkgICAgICAgICAgICBsbC5wdXNoKGEpOwoJICAgICAgICB9CgkgICAgfSk7CgkgICAgcmV0dXJuIHsKCSAgICAgICAgY29vcmRpbmF0ZXM6IGxsLAoJICAgICAgICB0aW1lOiB0aW1lIHx8IG51bGwsCgkgICAgICAgIGhlYXJ0UmF0ZTogaGVhcnRSYXRlID8gcGFyc2VGbG9hdChub2RlVmFsKGhlYXJ0UmF0ZSkpIDogbnVsbCwKCSAgICAgICAgZXh0ZW5zaW9uczogZ2V0UHJvcGVydGllcyhub2RlLCBUUkFDS1BPSU5UX0FUVFJJQlVURVMpLAoJICAgIH07Cgl9CglmdW5jdGlvbiBnZXRQb2ludHMobm9kZSkgewoJICAgIGNvbnN0IHB0cyA9ICQobm9kZSwgIlRyYWNrcG9pbnQiKTsKCSAgICBjb25zdCBsaW5lID0gW107CgkgICAgY29uc3QgdGltZXMgPSBbXTsKCSAgICBjb25zdCBoZWFydFJhdGVzID0gW107CgkgICAgaWYgKHB0cy5sZW5ndGggPCAyKQoJICAgICAgICByZXR1cm4gbnVsbDsgLy8gSW52YWxpZCBsaW5lIGluIEdlb0pTT04KCSAgICBjb25zdCBleHRlbmRlZFByb3BlcnRpZXMgPSB7fTsKCSAgICBjb25zdCByZXN1bHQgPSB7IGV4dGVuZGVkUHJvcGVydGllcyB9OwoJICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcHRzLmxlbmd0aDsgaSsrKSB7CgkgICAgICAgIGNvbnN0IGMgPSBjb29yZFBhaXIocHRzW2ldKTsKCSAgICAgICAgaWYgKGMgPT09IG51bGwpCgkgICAgICAgICAgICBjb250aW51ZTsKCSAgICAgICAgbGluZS5wdXNoKGMuY29vcmRpbmF0ZXMpOwoJICAgICAgICBjb25zdCB7IHRpbWUsIGhlYXJ0UmF0ZSwgZXh0ZW5zaW9ucyB9ID0gYzsKCSAgICAgICAgaWYgKHRpbWUpCgkgICAgICAgICAgICB0aW1lcy5wdXNoKHRpbWUpOwoJICAgICAgICBpZiAoaGVhcnRSYXRlKQoJICAgICAgICAgICAgaGVhcnRSYXRlcy5wdXNoKGhlYXJ0UmF0ZSk7CgkgICAgICAgIGZvciAoY29uc3QgW2FsaWFzLCB2YWx1ZV0gb2YgZXh0ZW5zaW9ucykgewoJICAgICAgICAgICAgaWYgKCFleHRlbmRlZFByb3BlcnRpZXNbYWxpYXNdKSB7CgkgICAgICAgICAgICAgICAgZXh0ZW5kZWRQcm9wZXJ0aWVzW2FsaWFzXSA9IEFycmF5KHB0cy5sZW5ndGgpLmZpbGwobnVsbCk7CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICBleHRlbmRlZFByb3BlcnRpZXNbYWxpYXNdW2ldID0gdmFsdWU7CgkgICAgICAgIH0KCSAgICB9CgkgICAgaWYgKGxpbmUubGVuZ3RoIDwgMikKCSAgICAgICAgcmV0dXJuIG51bGw7CgkgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24ocmVzdWx0LCB7CgkgICAgICAgIGxpbmU6IGxpbmUsCgkgICAgICAgIHRpbWVzOiB0aW1lcywKCSAgICAgICAgaGVhcnRSYXRlczogaGVhcnRSYXRlcywKCSAgICB9KTsKCX0KCWZ1bmN0aW9uIGdldExhcChub2RlKSB7CgkgICAgY29uc3Qgc2VnbWVudHMgPSAkKG5vZGUsICJUcmFjayIpOwoJICAgIGNvbnN0IHRyYWNrID0gW107CgkgICAgY29uc3QgdGltZXMgPSBbXTsKCSAgICBjb25zdCBoZWFydFJhdGVzID0gW107CgkgICAgY29uc3QgYWxsRXh0ZW5kZWRQcm9wZXJ0aWVzID0gW107CgkgICAgbGV0IGxpbmU7CgkgICAgY29uc3QgcHJvcGVydGllcyA9IE9iamVjdC5hc3NpZ24oT2JqZWN0LmZyb21FbnRyaWVzKGdldFByb3BlcnRpZXMobm9kZSwgTEFQX0FUVFJJQlVURVMpKSwgZ2V0KG5vZGUsICJOYW1lIiwgKG5hbWVFbGVtZW50KSA9PiB7CgkgICAgICAgIHJldHVybiB7IG5hbWU6IG5vZGVWYWwobmFtZUVsZW1lbnQpIH07CgkgICAgfSkpOwoJICAgIGZvciAoY29uc3Qgc2VnbWVudCBvZiBzZWdtZW50cykgewoJICAgICAgICBsaW5lID0gZ2V0UG9pbnRzKHNlZ21lbnQpOwoJICAgICAgICBpZiAobGluZSkgewoJICAgICAgICAgICAgdHJhY2sucHVzaChsaW5lLmxpbmUpOwoJICAgICAgICAgICAgaWYgKGxpbmUudGltZXMubGVuZ3RoKQoJICAgICAgICAgICAgICAgIHRpbWVzLnB1c2gobGluZS50aW1lcyk7CgkgICAgICAgICAgICBpZiAobGluZS5oZWFydFJhdGVzLmxlbmd0aCkKCSAgICAgICAgICAgICAgICBoZWFydFJhdGVzLnB1c2gobGluZS5oZWFydFJhdGVzKTsKCSAgICAgICAgICAgIGFsbEV4dGVuZGVkUHJvcGVydGllcy5wdXNoKGxpbmUuZXh0ZW5kZWRQcm9wZXJ0aWVzKTsKCSAgICAgICAgfQoJICAgIH0KCSAgICBmb3IgKGxldCBpID0gMDsgaSA8IGFsbEV4dGVuZGVkUHJvcGVydGllcy5sZW5ndGg7IGkrKykgewoJICAgICAgICBjb25zdCBleHRlbmRlZFByb3BlcnRpZXMgPSBhbGxFeHRlbmRlZFByb3BlcnRpZXNbaV07CgkgICAgICAgIGZvciAoY29uc3QgcHJvcGVydHkgaW4gZXh0ZW5kZWRQcm9wZXJ0aWVzKSB7CgkgICAgICAgICAgICBpZiAoc2VnbWVudHMubGVuZ3RoID09PSAxKSB7CgkgICAgICAgICAgICAgICAgaWYgKGxpbmUpIHsKCSAgICAgICAgICAgICAgICAgICAgcHJvcGVydGllc1twcm9wZXJ0eV0gPSBsaW5lLmV4dGVuZGVkUHJvcGVydGllc1twcm9wZXJ0eV07CgkgICAgICAgICAgICAgICAgfQoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgZWxzZSB7CgkgICAgICAgICAgICAgICAgaWYgKCFwcm9wZXJ0aWVzW3Byb3BlcnR5XSkgewoJICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0aWVzW3Byb3BlcnR5XSA9IHRyYWNrLm1hcCgodHJhY2spID0+IEFycmF5KHRyYWNrLmxlbmd0aCkuZmlsbChudWxsKSk7CgkgICAgICAgICAgICAgICAgfQoJICAgICAgICAgICAgICAgIHByb3BlcnRpZXNbcHJvcGVydHldW2ldID0gZXh0ZW5kZWRQcm9wZXJ0aWVzW3Byb3BlcnR5XTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgfQoJICAgIH0KCSAgICBpZiAodHJhY2subGVuZ3RoID09PSAwKQoJICAgICAgICByZXR1cm4gbnVsbDsKCSAgICBpZiAodGltZXMubGVuZ3RoIHx8IGhlYXJ0UmF0ZXMubGVuZ3RoKSB7CgkgICAgICAgIHByb3BlcnRpZXMuY29vcmRpbmF0ZVByb3BlcnRpZXMgPSBPYmplY3QuYXNzaWduKHRpbWVzLmxlbmd0aAoJICAgICAgICAgICAgPyB7CgkgICAgICAgICAgICAgICAgdGltZXM6IHRyYWNrLmxlbmd0aCA9PT0gMSA/IHRpbWVzWzBdIDogdGltZXMsCgkgICAgICAgICAgICB9CgkgICAgICAgICAgICA6IHt9LCBoZWFydFJhdGVzLmxlbmd0aAoJICAgICAgICAgICAgPyB7CgkgICAgICAgICAgICAgICAgaGVhcnQ6IHRyYWNrLmxlbmd0aCA9PT0gMSA/IGhlYXJ0UmF0ZXNbMF0gOiBoZWFydFJhdGVzLAoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgOiB7fSk7CgkgICAgfQoJICAgIHJldHVybiB7CgkgICAgICAgIHR5cGU6ICJGZWF0dXJlIiwKCSAgICAgICAgcHJvcGVydGllczogcHJvcGVydGllcywKCSAgICAgICAgZ2VvbWV0cnk6IHRyYWNrLmxlbmd0aCA9PT0gMQoJICAgICAgICAgICAgPyB7CgkgICAgICAgICAgICAgICAgdHlwZTogIkxpbmVTdHJpbmciLAoJICAgICAgICAgICAgICAgIGNvb3JkaW5hdGVzOiB0cmFja1swXSwKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIDogewoJICAgICAgICAgICAgICAgIHR5cGU6ICJNdWx0aUxpbmVTdHJpbmciLAoJICAgICAgICAgICAgICAgIGNvb3JkaW5hdGVzOiB0cmFjaywKCSAgICAgICAgICAgIH0sCgkgICAgfTsKCX0KCS8qKgoJICogSW5jcmVtZW50YWxseSBjb252ZXJ0IGEgVENYIGRvY3VtZW50IHRvIEdlb0pTT04uIFRoZQoJICogZmlyc3QgYXJndW1lbnQsIGBkb2NgLCBtdXN0IGJlIGEgVENYCgkgKiBkb2N1bWVudCBhcyBhbiBYTUwgRE9NIC0gbm90IGFzIGEgc3RyaW5nLgoJICovCglmdW5jdGlvbiogdGN4R2VuKG5vZGUpIHsKCSAgICBmb3IgKGNvbnN0IGxhcCBvZiAkKG5vZGUsICJMYXAiKSkgewoJICAgICAgICBjb25zdCBmZWF0dXJlID0gZ2V0TGFwKGxhcCk7CgkgICAgICAgIGlmIChmZWF0dXJlKQoJICAgICAgICAgICAgeWllbGQgZmVhdHVyZTsKCSAgICB9CgkgICAgZm9yIChjb25zdCBjb3Vyc2Ugb2YgJChub2RlLCAiQ291cnNlcyIpKSB7CgkgICAgICAgIGNvbnN0IGZlYXR1cmUgPSBnZXRMYXAoY291cnNlKTsKCSAgICAgICAgaWYgKGZlYXR1cmUpCgkgICAgICAgICAgICB5aWVsZCBmZWF0dXJlOwoJICAgIH0KCX0KCS8qKgoJICogQ29udmVydCBhIFRDWCBkb2N1bWVudCB0byBHZW9KU09OLiBUaGUgZmlyc3QgYXJndW1lbnQsIGBkb2NgLCBtdXN0IGJlIGEgVENYCgkgKiBkb2N1bWVudCBhcyBhbiBYTUwgRE9NIC0gbm90IGFzIGEgc3RyaW5nLgoJICovCglmdW5jdGlvbiB0Y3gobm9kZSkgewoJICAgIHJldHVybiB7CgkgICAgICAgIHR5cGU6ICJGZWF0dXJlQ29sbGVjdGlvbiIsCgkgICAgICAgIGZlYXR1cmVzOiBBcnJheS5mcm9tKHRjeEdlbihub2RlKSksCgkgICAgfTsKCX0KCglmdW5jdGlvbiBmaXhDb2xvcih2LCBwcmVmaXgpIHsKCSAgICBjb25zdCBwcm9wZXJ0aWVzID0ge307CgkgICAgY29uc3QgY29sb3JQcm9wID0gcHJlZml4ID09ICJzdHJva2UiIHx8IHByZWZpeCA9PT0gImZpbGwiID8gcHJlZml4IDogcHJlZml4ICsgIi1jb2xvciI7CgkgICAgaWYgKHZbMF0gPT09ICIjIikgewoJICAgICAgICB2ID0gdi5zdWJzdHJpbmcoMSk7CgkgICAgfQoJICAgIGlmICh2Lmxlbmd0aCA9PT0gNiB8fCB2Lmxlbmd0aCA9PT0gMykgewoJICAgICAgICBwcm9wZXJ0aWVzW2NvbG9yUHJvcF0gPSAiIyIgKyB2OwoJICAgIH0KCSAgICBlbHNlIGlmICh2Lmxlbmd0aCA9PT0gOCkgewoJICAgICAgICBwcm9wZXJ0aWVzW3ByZWZpeCArICItb3BhY2l0eSJdID0gcGFyc2VJbnQodi5zdWJzdHJpbmcoMCwgMiksIDE2KSAvIDI1NTsKCSAgICAgICAgcHJvcGVydGllc1tjb2xvclByb3BdID0KCSAgICAgICAgICAgICIjIiArIHYuc3Vic3RyaW5nKDYsIDgpICsgdi5zdWJzdHJpbmcoNCwgNikgKyB2LnN1YnN0cmluZygyLCA0KTsKCSAgICB9CgkgICAgcmV0dXJuIHByb3BlcnRpZXM7Cgl9CgoJZnVuY3Rpb24gbnVtZXJpY1Byb3BlcnR5KG5vZGUsIHNvdXJjZSwgdGFyZ2V0KSB7CgkgICAgY29uc3QgcHJvcGVydGllcyA9IHt9OwoJICAgIG51bTEobm9kZSwgc291cmNlLCAodmFsKSA9PiB7CgkgICAgICAgIHByb3BlcnRpZXNbdGFyZ2V0XSA9IHZhbDsKCSAgICB9KTsKCSAgICByZXR1cm4gcHJvcGVydGllczsKCX0KCWZ1bmN0aW9uIGdldENvbG9yKG5vZGUsIG91dHB1dCkgewoJICAgIHJldHVybiBnZXQobm9kZSwgImNvbG9yIiwgKGVsZW0pID0+IGZpeENvbG9yKG5vZGVWYWwoZWxlbSksIG91dHB1dCkpOwoJfQoJZnVuY3Rpb24gZXh0cmFjdEljb25IcmVmKG5vZGUpIHsKCSAgICByZXR1cm4gZ2V0KG5vZGUsICJJY29uIiwgKGljb24sIHByb3BlcnRpZXMpID0+IHsKCSAgICAgICAgdmFsMShpY29uLCAiaHJlZiIsIChocmVmKSA9PiB7CgkgICAgICAgICAgICBwcm9wZXJ0aWVzLmljb24gPSBocmVmOwoJICAgICAgICB9KTsKCSAgICAgICAgcmV0dXJuIHByb3BlcnRpZXM7CgkgICAgfSk7Cgl9CglmdW5jdGlvbiBleHRyYWN0SWNvbihub2RlKSB7CgkgICAgcmV0dXJuIGdldChub2RlLCAiSWNvblN0eWxlIiwgKGljb25TdHlsZSkgPT4gewoJICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihnZXRDb2xvcihpY29uU3R5bGUsICJpY29uIiksIG51bWVyaWNQcm9wZXJ0eShpY29uU3R5bGUsICJzY2FsZSIsICJpY29uLXNjYWxlIiksIG51bWVyaWNQcm9wZXJ0eShpY29uU3R5bGUsICJoZWFkaW5nIiwgImljb24taGVhZGluZyIpLCBnZXQoaWNvblN0eWxlLCAiaG90U3BvdCIsIChob3RzcG90KSA9PiB7CgkgICAgICAgICAgICBjb25zdCBsZWZ0ID0gcGFyc2VGbG9hdChob3RzcG90LmdldEF0dHJpYnV0ZSgieCIpIHx8ICIiKTsKCSAgICAgICAgICAgIGNvbnN0IHRvcCA9IHBhcnNlRmxvYXQoaG90c3BvdC5nZXRBdHRyaWJ1dGUoInkiKSB8fCAiIik7CgkgICAgICAgICAgICBjb25zdCB4dW5pdHMgPSBob3RzcG90LmdldEF0dHJpYnV0ZSgieHVuaXRzIikgfHwgIiI7CgkgICAgICAgICAgICBjb25zdCB5dW5pdHMgPSBob3RzcG90LmdldEF0dHJpYnV0ZSgieXVuaXRzIikgfHwgIiI7CgkgICAgICAgICAgICBpZiAoIWlzTmFOKGxlZnQpICYmICFpc05hTih0b3ApKQoJICAgICAgICAgICAgICAgIHJldHVybiB7CgkgICAgICAgICAgICAgICAgICAgICJpY29uLW9mZnNldCI6IFtsZWZ0LCB0b3BdLAoJICAgICAgICAgICAgICAgICAgICAiaWNvbi1vZmZzZXQtdW5pdHMiOiBbeHVuaXRzLCB5dW5pdHNdLAoJICAgICAgICAgICAgICAgIH07CgkgICAgICAgICAgICByZXR1cm4ge307CgkgICAgICAgIH0pLCBleHRyYWN0SWNvbkhyZWYoaWNvblN0eWxlKSk7CgkgICAgfSk7Cgl9CglmdW5jdGlvbiBleHRyYWN0TGFiZWwobm9kZSkgewoJICAgIHJldHVybiBnZXQobm9kZSwgIkxhYmVsU3R5bGUiLCAobGFiZWxTdHlsZSkgPT4gewoJICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihnZXRDb2xvcihsYWJlbFN0eWxlLCAibGFiZWwiKSwgbnVtZXJpY1Byb3BlcnR5KGxhYmVsU3R5bGUsICJzY2FsZSIsICJsYWJlbC1zY2FsZSIpKTsKCSAgICB9KTsKCX0KCWZ1bmN0aW9uIGV4dHJhY3RMaW5lKG5vZGUpIHsKCSAgICByZXR1cm4gZ2V0KG5vZGUsICJMaW5lU3R5bGUiLCAobGluZVN0eWxlKSA9PiB7CgkgICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKGdldENvbG9yKGxpbmVTdHlsZSwgInN0cm9rZSIpLCBudW1lcmljUHJvcGVydHkobGluZVN0eWxlLCAid2lkdGgiLCAic3Ryb2tlLXdpZHRoIikpOwoJICAgIH0pOwoJfQoJZnVuY3Rpb24gZXh0cmFjdFBvbHkobm9kZSkgewoJICAgIHJldHVybiBnZXQobm9kZSwgIlBvbHlTdHlsZSIsIChwb2x5U3R5bGUsIHByb3BlcnRpZXMpID0+IHsKCSAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24ocHJvcGVydGllcywgZ2V0KHBvbHlTdHlsZSwgImNvbG9yIiwgKGVsZW0pID0+IGZpeENvbG9yKG5vZGVWYWwoZWxlbSksICJmaWxsIikpLCB2YWwxKHBvbHlTdHlsZSwgImZpbGwiLCAoZmlsbCkgPT4gewoJICAgICAgICAgICAgaWYgKGZpbGwgPT09ICIwIikKCSAgICAgICAgICAgICAgICByZXR1cm4geyAiZmlsbC1vcGFjaXR5IjogMCB9OwoJICAgICAgICB9KSwgdmFsMShwb2x5U3R5bGUsICJvdXRsaW5lIiwgKG91dGxpbmUpID0+IHsKCSAgICAgICAgICAgIGlmIChvdXRsaW5lID09PSAiMCIpCgkgICAgICAgICAgICAgICAgcmV0dXJuIHsgInN0cm9rZS1vcGFjaXR5IjogMCB9OwoJICAgICAgICB9KSk7CgkgICAgfSk7Cgl9CglmdW5jdGlvbiBleHRyYWN0U3R5bGUobm9kZSkgewoJICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBleHRyYWN0UG9seShub2RlKSwgZXh0cmFjdExpbmUobm9kZSksIGV4dHJhY3RMYWJlbChub2RlKSwgZXh0cmFjdEljb24obm9kZSkpOwoJfQoKCWNvbnN0IHRvTnVtYmVyID0gKHgpID0+IE51bWJlcih4KTsKCWNvbnN0IHR5cGVDb252ZXJ0ZXJzID0gewoJICAgIHN0cmluZzogKHgpID0+IHgsCgkgICAgaW50OiB0b051bWJlciwKCSAgICB1aW50OiB0b051bWJlciwKCSAgICBzaG9ydDogdG9OdW1iZXIsCgkgICAgdXNob3J0OiB0b051bWJlciwKCSAgICBmbG9hdDogdG9OdW1iZXIsCgkgICAgZG91YmxlOiB0b051bWJlciwKCSAgICBib29sOiAoeCkgPT4gQm9vbGVhbih4KSwKCX07CglmdW5jdGlvbiBleHRyYWN0RXh0ZW5kZWREYXRhKG5vZGUsIHNjaGVtYSkgewoJICAgIHJldHVybiBnZXQobm9kZSwgIkV4dGVuZGVkRGF0YSIsIChleHRlbmRlZERhdGEsIHByb3BlcnRpZXMpID0+IHsKCSAgICAgICAgZm9yIChjb25zdCBkYXRhIG9mICQoZXh0ZW5kZWREYXRhLCAiRGF0YSIpKSB7CgkgICAgICAgICAgICBwcm9wZXJ0aWVzW2RhdGEuZ2V0QXR0cmlidXRlKCJuYW1lIikgfHwgIiJdID0gbm9kZVZhbChnZXQxKGRhdGEsICJ2YWx1ZSIpKTsKCSAgICAgICAgfQoJICAgICAgICBmb3IgKGNvbnN0IHNpbXBsZURhdGEgb2YgJChleHRlbmRlZERhdGEsICJTaW1wbGVEYXRhIikpIHsKCSAgICAgICAgICAgIGNvbnN0IG5hbWUgPSBzaW1wbGVEYXRhLmdldEF0dHJpYnV0ZSgibmFtZSIpIHx8ICIiOwoJICAgICAgICAgICAgY29uc3QgdHlwZUNvbnZlcnRlciA9IHNjaGVtYVtuYW1lXSB8fCB0eXBlQ29udmVydGVycy5zdHJpbmc7CgkgICAgICAgICAgICBwcm9wZXJ0aWVzW25hbWVdID0gdHlwZUNvbnZlcnRlcihub2RlVmFsKHNpbXBsZURhdGEpKTsKCSAgICAgICAgfQoJICAgICAgICByZXR1cm4gcHJvcGVydGllczsKCSAgICB9KTsKCX0KCWZ1bmN0aW9uIGdldE1heWJlSFRNTERlc2NyaXB0aW9uKG5vZGUpIHsKCSAgICBjb25zdCBkZXNjcmlwdGlvbk5vZGUgPSBnZXQxKG5vZGUsICJkZXNjcmlwdGlvbiIpOwoJICAgIGZvciAoY29uc3QgYyBvZiBBcnJheS5mcm9tKGRlc2NyaXB0aW9uTm9kZT8uY2hpbGROb2RlcyB8fCBbXSkpIHsKCSAgICAgICAgaWYgKGMubm9kZVR5cGUgPT09IDQpIHsKCSAgICAgICAgICAgIHJldHVybiB7CgkgICAgICAgICAgICAgICAgZGVzY3JpcHRpb246IHsKCSAgICAgICAgICAgICAgICAgICAgIkB0eXBlIjogImh0bWwiLAoJICAgICAgICAgICAgICAgICAgICB2YWx1ZTogbm9kZVZhbChjKSwKCSAgICAgICAgICAgICAgICB9LAoJICAgICAgICAgICAgfTsKCSAgICAgICAgfQoJICAgIH0KCSAgICByZXR1cm4ge307Cgl9CglmdW5jdGlvbiBleHRyYWN0VGltZVNwYW4obm9kZSkgewoJICAgIHJldHVybiBnZXQobm9kZSwgIlRpbWVTcGFuIiwgKHRpbWVTcGFuKSA9PiB7CgkgICAgICAgIHJldHVybiB7CgkgICAgICAgICAgICB0aW1lc3BhbjogewoJICAgICAgICAgICAgICAgIGJlZ2luOiBub2RlVmFsKGdldDEodGltZVNwYW4sICJiZWdpbiIpKSwKCSAgICAgICAgICAgICAgICBlbmQ6IG5vZGVWYWwoZ2V0MSh0aW1lU3BhbiwgImVuZCIpKSwKCSAgICAgICAgICAgIH0sCgkgICAgICAgIH07CgkgICAgfSk7Cgl9CglmdW5jdGlvbiBleHRyYWN0VGltZVN0YW1wKG5vZGUpIHsKCSAgICByZXR1cm4gZ2V0KG5vZGUsICJUaW1lU3RhbXAiLCAodGltZVN0YW1wKSA9PiB7CgkgICAgICAgIHJldHVybiB7IHRpbWVzdGFtcDogbm9kZVZhbChnZXQxKHRpbWVTdGFtcCwgIndoZW4iKSkgfTsKCSAgICB9KTsKCX0KCWZ1bmN0aW9uIGV4dHJhY3RDYXNjYWRlZFN0eWxlKG5vZGUsIHN0eWxlTWFwKSB7CgkgICAgcmV0dXJuIHZhbDEobm9kZSwgInN0eWxlVXJsIiwgKHN0eWxlVXJsKSA9PiB7CgkgICAgICAgIHN0eWxlVXJsID0gbm9ybWFsaXplSWQoc3R5bGVVcmwpOwoJICAgICAgICBpZiAoc3R5bGVNYXBbc3R5bGVVcmxdKSB7CgkgICAgICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7IHN0eWxlVXJsIH0sIHN0eWxlTWFwW3N0eWxlVXJsXSk7CgkgICAgICAgIH0KCSAgICAgICAgLy8gRm9yIGJhY2t3YXJkLWNvbXBhdGliaWxpdHkuIFNob3VsZCB3ZSBzdGlsbCBpbmNsdWRlCgkgICAgICAgIC8vIHN0eWxlVXJsIGV2ZW4gaWYgaXQncyBub3QgcmVzb2x2ZWQ/CgkgICAgICAgIHJldHVybiB7IHN0eWxlVXJsIH07CgkgICAgfSk7Cgl9CgoJY29uc3QgcmVtb3ZlU3BhY2UgPSAvXHMqL2c7Cgljb25zdCB0cmltU3BhY2UgPSAvXlxzKnxccyokL2c7Cgljb25zdCBzcGxpdFNwYWNlID0gL1xzKy87CgkvKioKCSAqIEdldCBvbmUgY29vcmRpbmF0ZSBmcm9tIGEgY29vcmRpbmF0ZSBhcnJheSwgaWYgYW55CgkgKi8KCWZ1bmN0aW9uIGNvb3JkMSh2YWx1ZSkgewoJICAgIHJldHVybiB2YWx1ZQoJICAgICAgICAucmVwbGFjZShyZW1vdmVTcGFjZSwgIiIpCgkgICAgICAgIC5zcGxpdCgiLCIpCgkgICAgICAgIC5tYXAocGFyc2VGbG9hdCkKCSAgICAgICAgLmZpbHRlcigobnVtKSA9PiAhaXNOYU4obnVtKSkKCSAgICAgICAgLnNsaWNlKDAsIDMpOwoJfQoJLyoqCgkgKiBHZXQgYWxsIGNvb3JkaW5hdGVzIGZyb20gYSBjb29yZGluYXRlIGFycmF5IGFzIFtbXSxbXV0KCSAqLwoJZnVuY3Rpb24gY29vcmQodmFsdWUpIHsKCSAgICByZXR1cm4gdmFsdWUKCSAgICAgICAgLnJlcGxhY2UodHJpbVNwYWNlLCAiIikKCSAgICAgICAgLnNwbGl0KHNwbGl0U3BhY2UpCgkgICAgICAgIC5tYXAoY29vcmQxKQoJICAgICAgICAuZmlsdGVyKChjb29yZCkgPT4gewoJICAgICAgICByZXR1cm4gY29vcmQubGVuZ3RoID49IDI7CgkgICAgfSk7Cgl9CglmdW5jdGlvbiBneENvb3Jkcyhub2RlKSB7CgkgICAgbGV0IGVsZW1zID0gJChub2RlLCAiY29vcmQiKTsKCSAgICBpZiAoZWxlbXMubGVuZ3RoID09PSAwKSB7CgkgICAgICAgIGVsZW1zID0gJG5zKG5vZGUsICJjb29yZCIsICIqIik7CgkgICAgfQoJICAgIGNvbnN0IGNvb3JkaW5hdGVzID0gZWxlbXMubWFwKChlbGVtKSA9PiB7CgkgICAgICAgIHJldHVybiBub2RlVmFsKGVsZW0pLnNwbGl0KCIgIikubWFwKHBhcnNlRmxvYXQpOwoJICAgIH0pOwoJICAgIGlmIChjb29yZGluYXRlcy5sZW5ndGggPT09IDApIHsKCSAgICAgICAgcmV0dXJuIG51bGw7CgkgICAgfQoJICAgIHJldHVybiB7CgkgICAgICAgIGdlb21ldHJ5OiBjb29yZGluYXRlcy5sZW5ndGggPiAyCgkgICAgICAgICAgICA/IHsKCSAgICAgICAgICAgICAgICB0eXBlOiAiTGluZVN0cmluZyIsCgkgICAgICAgICAgICAgICAgY29vcmRpbmF0ZXMsCgkgICAgICAgICAgICB9CgkgICAgICAgICAgICA6IHsKCSAgICAgICAgICAgICAgICB0eXBlOiAiUG9pbnQiLAoJICAgICAgICAgICAgICAgIGNvb3JkaW5hdGVzOiBjb29yZGluYXRlc1swXSwKCSAgICAgICAgICAgIH0sCgkgICAgICAgIHRpbWVzOiAkKG5vZGUsICJ3aGVuIikubWFwKChlbGVtKSA9PiBub2RlVmFsKGVsZW0pKSwKCSAgICB9OwoJfQoJZnVuY3Rpb24gZml4UmluZyhyaW5nKSB7CgkgICAgaWYgKHJpbmcubGVuZ3RoID09PSAwKQoJICAgICAgICByZXR1cm4gcmluZzsKCSAgICBjb25zdCBmaXJzdCA9IHJpbmdbMF07CgkgICAgY29uc3QgbGFzdCA9IHJpbmdbcmluZy5sZW5ndGggLSAxXTsKCSAgICBsZXQgZXF1YWwgPSB0cnVlOwoJICAgIGZvciAobGV0IGkgPSAwOyBpIDwgTWF0aC5tYXgoZmlyc3QubGVuZ3RoLCBsYXN0Lmxlbmd0aCk7IGkrKykgewoJICAgICAgICBpZiAoZmlyc3RbaV0gIT09IGxhc3RbaV0pIHsKCSAgICAgICAgICAgIGVxdWFsID0gZmFsc2U7CgkgICAgICAgICAgICBicmVhazsKCSAgICAgICAgfQoJICAgIH0KCSAgICBpZiAoIWVxdWFsKSB7CgkgICAgICAgIHJldHVybiByaW5nLmNvbmNhdChbcmluZ1swXV0pOwoJICAgIH0KCSAgICByZXR1cm4gcmluZzsKCX0KCWZ1bmN0aW9uIGdldENvb3JkaW5hdGVzKG5vZGUpIHsKCSAgICByZXR1cm4gbm9kZVZhbChnZXQxKG5vZGUsICJjb29yZGluYXRlcyIpKTsKCX0KCWZ1bmN0aW9uIGdldEdlb21ldHJ5KG5vZGUpIHsKCSAgICBsZXQgZ2VvbWV0cmllcyA9IFtdOwoJICAgIGxldCBjb29yZFRpbWVzID0gW107CgkgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBub2RlLmNoaWxkTm9kZXMubGVuZ3RoOyBpKyspIHsKCSAgICAgICAgY29uc3QgY2hpbGQgPSBub2RlLmNoaWxkTm9kZXMuaXRlbShpKTsKCSAgICAgICAgaWYgKGlzRWxlbWVudChjaGlsZCkpIHsKCSAgICAgICAgICAgIHN3aXRjaCAoY2hpbGQudGFnTmFtZSkgewoJICAgICAgICAgICAgICAgIGNhc2UgIk11bHRpR2VvbWV0cnkiOgoJICAgICAgICAgICAgICAgIGNhc2UgIk11bHRpVHJhY2siOgoJICAgICAgICAgICAgICAgIGNhc2UgImd4Ok11bHRpVHJhY2siOiB7CgkgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoaWxkR2VvbWV0cmllcyA9IGdldEdlb21ldHJ5KGNoaWxkKTsKCSAgICAgICAgICAgICAgICAgICAgZ2VvbWV0cmllcyA9IGdlb21ldHJpZXMuY29uY2F0KGNoaWxkR2VvbWV0cmllcy5nZW9tZXRyaWVzKTsKCSAgICAgICAgICAgICAgICAgICAgY29vcmRUaW1lcyA9IGNvb3JkVGltZXMuY29uY2F0KGNoaWxkR2VvbWV0cmllcy5jb29yZFRpbWVzKTsKCSAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgkgICAgICAgICAgICAgICAgfQoJICAgICAgICAgICAgICAgIGNhc2UgIlBvaW50IjogewoJICAgICAgICAgICAgICAgICAgICBjb25zdCBjb29yZGluYXRlcyA9IGNvb3JkMShnZXRDb29yZGluYXRlcyhjaGlsZCkpOwoJICAgICAgICAgICAgICAgICAgICBpZiAoY29vcmRpbmF0ZXMubGVuZ3RoID49IDIpIHsKCSAgICAgICAgICAgICAgICAgICAgICAgIGdlb21ldHJpZXMucHVzaCh7CgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogIlBvaW50IiwKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb29yZGluYXRlcywKCSAgICAgICAgICAgICAgICAgICAgICAgIH0pOwoJICAgICAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoJICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgICAgICBjYXNlICJMaW5lYXJSaW5nIjoKCSAgICAgICAgICAgICAgICBjYXNlICJMaW5lU3RyaW5nIjogewoJICAgICAgICAgICAgICAgICAgICBjb25zdCBjb29yZGluYXRlcyA9IGNvb3JkKGdldENvb3JkaW5hdGVzKGNoaWxkKSk7CgkgICAgICAgICAgICAgICAgICAgIGlmIChjb29yZGluYXRlcy5sZW5ndGggPj0gMikgewoJICAgICAgICAgICAgICAgICAgICAgICAgZ2VvbWV0cmllcy5wdXNoKHsKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAiTGluZVN0cmluZyIsCgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29vcmRpbmF0ZXMsCgkgICAgICAgICAgICAgICAgICAgICAgICB9KTsKCSAgICAgICAgICAgICAgICAgICAgfQoJICAgICAgICAgICAgICAgICAgICBicmVhazsKCSAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICAgICAgY2FzZSAiUG9seWdvbiI6IHsKCSAgICAgICAgICAgICAgICAgICAgY29uc3QgY29vcmRzID0gW107CgkgICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgbGluZWFyUmluZyBvZiAkKGNoaWxkLCAiTGluZWFyUmluZyIpKSB7CgkgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCByaW5nID0gZml4UmluZyhjb29yZChnZXRDb29yZGluYXRlcyhsaW5lYXJSaW5nKSkpOwoJICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJpbmcubGVuZ3RoID49IDQpIHsKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb29yZHMucHVzaChyaW5nKTsKCSAgICAgICAgICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgICAgICAgICAgfQoJICAgICAgICAgICAgICAgICAgICBpZiAoY29vcmRzLmxlbmd0aCkgewoJICAgICAgICAgICAgICAgICAgICAgICAgZ2VvbWV0cmllcy5wdXNoKHsKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAiUG9seWdvbiIsCgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29vcmRpbmF0ZXM6IGNvb3JkcywKCSAgICAgICAgICAgICAgICAgICAgICAgIH0pOwoJICAgICAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoJICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgICAgICBjYXNlICJUcmFjayI6CgkgICAgICAgICAgICAgICAgY2FzZSAiZ3g6VHJhY2siOiB7CgkgICAgICAgICAgICAgICAgICAgIGNvbnN0IGd4ID0gZ3hDb29yZHMoY2hpbGQpOwoJICAgICAgICAgICAgICAgICAgICBpZiAoIWd4KQoJICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgkgICAgICAgICAgICAgICAgICAgIGNvbnN0IHsgdGltZXMsIGdlb21ldHJ5IH0gPSBneDsKCSAgICAgICAgICAgICAgICAgICAgZ2VvbWV0cmllcy5wdXNoKGdlb21ldHJ5KTsKCSAgICAgICAgICAgICAgICAgICAgaWYgKHRpbWVzLmxlbmd0aCkKCSAgICAgICAgICAgICAgICAgICAgICAgIGNvb3JkVGltZXMucHVzaCh0aW1lcyk7CgkgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoJICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgIH0KCSAgICAgICAgfQoJICAgIH0KCSAgICByZXR1cm4gewoJICAgICAgICBnZW9tZXRyaWVzLAoJICAgICAgICBjb29yZFRpbWVzLAoJICAgIH07Cgl9CgoJZnVuY3Rpb24gZ2VvbWV0cnlMaXN0VG9HZW9tZXRyeShnZW9tZXRyaWVzKSB7CgkgICAgcmV0dXJuIGdlb21ldHJpZXMubGVuZ3RoID09PSAwCgkgICAgICAgID8gbnVsbAoJICAgICAgICA6IGdlb21ldHJpZXMubGVuZ3RoID09PSAxCgkgICAgICAgICAgICA/IGdlb21ldHJpZXNbMF0KCSAgICAgICAgICAgIDogewoJICAgICAgICAgICAgICAgIHR5cGU6ICJHZW9tZXRyeUNvbGxlY3Rpb24iLAoJICAgICAgICAgICAgICAgIGdlb21ldHJpZXMsCgkgICAgICAgICAgICB9OwoJfQoJZnVuY3Rpb24gZ2V0UGxhY2VtYXJrKG5vZGUsIHN0eWxlTWFwLCBzY2hlbWEpIHsKCSAgICBjb25zdCB7IGNvb3JkVGltZXMsIGdlb21ldHJpZXMgfSA9IGdldEdlb21ldHJ5KG5vZGUpOwoJICAgIGNvbnN0IGZlYXR1cmUgPSB7CgkgICAgICAgIHR5cGU6ICJGZWF0dXJlIiwKCSAgICAgICAgZ2VvbWV0cnk6IGdlb21ldHJ5TGlzdFRvR2VvbWV0cnkoZ2VvbWV0cmllcyksCgkgICAgICAgIHByb3BlcnRpZXM6IE9iamVjdC5hc3NpZ24oZ2V0TXVsdGkobm9kZSwgWwoJICAgICAgICAgICAgIm5hbWUiLAoJICAgICAgICAgICAgImFkZHJlc3MiLAoJICAgICAgICAgICAgInZpc2liaWxpdHkiLAoJICAgICAgICAgICAgIm9wZW4iLAoJICAgICAgICAgICAgInBob25lTnVtYmVyIiwKCSAgICAgICAgICAgICJkZXNjcmlwdGlvbiIsCgkgICAgICAgIF0pLCBnZXRNYXliZUhUTUxEZXNjcmlwdGlvbihub2RlKSwgZXh0cmFjdENhc2NhZGVkU3R5bGUobm9kZSwgc3R5bGVNYXApLCBleHRyYWN0U3R5bGUobm9kZSksIGV4dHJhY3RFeHRlbmRlZERhdGEobm9kZSwgc2NoZW1hKSwgZXh0cmFjdFRpbWVTcGFuKG5vZGUpLCBleHRyYWN0VGltZVN0YW1wKG5vZGUpLCBjb29yZFRpbWVzLmxlbmd0aAoJICAgICAgICAgICAgPyB7CgkgICAgICAgICAgICAgICAgY29vcmRpbmF0ZVByb3BlcnRpZXM6IHsKCSAgICAgICAgICAgICAgICAgICAgdGltZXM6IGNvb3JkVGltZXMubGVuZ3RoID09PSAxID8gY29vcmRUaW1lc1swXSA6IGNvb3JkVGltZXMsCgkgICAgICAgICAgICAgICAgfSwKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIDoge30pLAoJICAgIH07CgkgICAgaWYgKGZlYXR1cmUucHJvcGVydGllcz8udmlzaWJpbGl0eSAhPT0gdW5kZWZpbmVkKSB7CgkgICAgICAgIGZlYXR1cmUucHJvcGVydGllcy52aXNpYmlsaXR5ID0gZmVhdHVyZS5wcm9wZXJ0aWVzLnZpc2liaWxpdHkgIT09ICIwIjsKCSAgICB9CgkgICAgY29uc3QgaWQgPSBub2RlLmdldEF0dHJpYnV0ZSgiaWQiKTsKCSAgICBpZiAoaWQgIT09IG51bGwgJiYgaWQgIT09ICIiKQoJICAgICAgICBmZWF0dXJlLmlkID0gaWQ7CgkgICAgcmV0dXJuIGZlYXR1cmU7Cgl9CgoJZnVuY3Rpb24gZ2V0R3JvdW5kT3ZlcmxheUJveChub2RlKSB7CgkgICAgY29uc3QgbGF0TG9uUXVhZCA9IGdldDEobm9kZSwgImd4OkxhdExvblF1YWQiKTsKCSAgICBpZiAobGF0TG9uUXVhZCkgewoJICAgICAgICBjb25zdCByaW5nID0gZml4UmluZyhjb29yZChnZXRDb29yZGluYXRlcyhub2RlKSkpOwoJICAgICAgICByZXR1cm4gewoJICAgICAgICAgICAgdHlwZTogIlBvbHlnb24iLAoJICAgICAgICAgICAgY29vcmRpbmF0ZXM6IFtyaW5nXSwKCSAgICAgICAgfTsKCSAgICB9CgkgICAgcmV0dXJuIGdldExhdExvbkJveChub2RlKTsKCX0KCWNvbnN0IERFR1JFRVNfVE9fUkFESUFOUyA9IE1hdGguUEkgLyAxODA7CglmdW5jdGlvbiByb3RhdGVCb3goYmJveCwgY29vcmRpbmF0ZXMsIHJvdGF0aW9uKSB7CgkgICAgY29uc3QgY2VudGVyID0gWyhiYm94WzBdICsgYmJveFsyXSkgLyAyLCAoYmJveFsxXSArIGJib3hbM10pIC8gMl07CgkgICAgcmV0dXJuIFsKCSAgICAgICAgY29vcmRpbmF0ZXNbMF0ubWFwKChjb29yZGluYXRlKSA9PiB7CgkgICAgICAgICAgICBjb25zdCBkeSA9IGNvb3JkaW5hdGVbMV0gLSBjZW50ZXJbMV07CgkgICAgICAgICAgICBjb25zdCBkeCA9IGNvb3JkaW5hdGVbMF0gLSBjZW50ZXJbMF07CgkgICAgICAgICAgICBjb25zdCBkaXN0YW5jZSA9IE1hdGguc3FydChNYXRoLnBvdyhkeSwgMikgKyBNYXRoLnBvdyhkeCwgMikpOwoJICAgICAgICAgICAgY29uc3QgYW5nbGUgPSBNYXRoLmF0YW4yKGR5LCBkeCkgLSByb3RhdGlvbiAqIERFR1JFRVNfVE9fUkFESUFOUzsKCSAgICAgICAgICAgIHJldHVybiBbCgkgICAgICAgICAgICAgICAgY2VudGVyWzBdICsgTWF0aC5jb3MoYW5nbGUpICogZGlzdGFuY2UsCgkgICAgICAgICAgICAgICAgY2VudGVyWzFdICsgTWF0aC5zaW4oYW5nbGUpICogZGlzdGFuY2UsCgkgICAgICAgICAgICBdOwoJICAgICAgICB9KSwKCSAgICBdOwoJfQoJZnVuY3Rpb24gZ2V0TGF0TG9uQm94KG5vZGUpIHsKCSAgICBjb25zdCBsYXRMb25Cb3ggPSBnZXQxKG5vZGUsICJMYXRMb25Cb3giKTsKCSAgICBpZiAobGF0TG9uQm94KSB7CgkgICAgICAgIGNvbnN0IG5vcnRoID0gbnVtMShsYXRMb25Cb3gsICJub3J0aCIpOwoJICAgICAgICBjb25zdCB3ZXN0ID0gbnVtMShsYXRMb25Cb3gsICJ3ZXN0Iik7CgkgICAgICAgIGNvbnN0IGVhc3QgPSBudW0xKGxhdExvbkJveCwgImVhc3QiKTsKCSAgICAgICAgY29uc3Qgc291dGggPSBudW0xKGxhdExvbkJveCwgInNvdXRoIik7CgkgICAgICAgIGNvbnN0IHJvdGF0aW9uID0gbnVtMShsYXRMb25Cb3gsICJyb3RhdGlvbiIpOwoJICAgICAgICBpZiAodHlwZW9mIG5vcnRoID09PSAibnVtYmVyIiAmJgoJICAgICAgICAgICAgdHlwZW9mIHNvdXRoID09PSAibnVtYmVyIiAmJgoJICAgICAgICAgICAgdHlwZW9mIHdlc3QgPT09ICJudW1iZXIiICYmCgkgICAgICAgICAgICB0eXBlb2YgZWFzdCA9PT0gIm51bWJlciIpIHsKCSAgICAgICAgICAgIGNvbnN0IGJib3ggPSBbd2VzdCwgc291dGgsIGVhc3QsIG5vcnRoXTsKCSAgICAgICAgICAgIGxldCBjb29yZGluYXRlcyA9IFsKCSAgICAgICAgICAgICAgICBbCgkgICAgICAgICAgICAgICAgICAgIFt3ZXN0LCBub3J0aF0sCgkgICAgICAgICAgICAgICAgICAgIFtlYXN0LCBub3J0aF0sCgkgICAgICAgICAgICAgICAgICAgIFtlYXN0LCBzb3V0aF0sCgkgICAgICAgICAgICAgICAgICAgIFt3ZXN0LCBzb3V0aF0sCgkgICAgICAgICAgICAgICAgICAgIFt3ZXN0LCBub3J0aF0sIC8vIHRvcCBsZWZ0IChhZ2FpbikKCSAgICAgICAgICAgICAgICBdLAoJICAgICAgICAgICAgXTsKCSAgICAgICAgICAgIGlmICh0eXBlb2Ygcm90YXRpb24gPT09ICJudW1iZXIiKSB7CgkgICAgICAgICAgICAgICAgY29vcmRpbmF0ZXMgPSByb3RhdGVCb3goYmJveCwgY29vcmRpbmF0ZXMsIHJvdGF0aW9uKTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIHJldHVybiB7CgkgICAgICAgICAgICAgICAgdHlwZTogIlBvbHlnb24iLAoJICAgICAgICAgICAgICAgIGNvb3JkaW5hdGVzLAoJICAgICAgICAgICAgfTsKCSAgICAgICAgfQoJICAgIH0KCSAgICByZXR1cm4gbnVsbDsKCX0KCWZ1bmN0aW9uIGdldEdyb3VuZE92ZXJsYXkobm9kZSwgc3R5bGVNYXAsIHNjaGVtYSkgewoJICAgIGNvbnN0IGdlb21ldHJ5ID0gZ2V0R3JvdW5kT3ZlcmxheUJveChub2RlKTsKCSAgICBjb25zdCBmZWF0dXJlID0gewoJICAgICAgICB0eXBlOiAiRmVhdHVyZSIsCgkgICAgICAgIGdlb21ldHJ5LAoJICAgICAgICBwcm9wZXJ0aWVzOiBPYmplY3QuYXNzaWduKAoJICAgICAgICAvKioKCSAgICAgICAgICogUmVsYXRlZCB0bwoJICAgICAgICAgKiBodHRwczovL2dpc3QuZ2l0aHViLmNvbS90bWN3LzAzN2ExY2I2NjYwZDc0YTM5MmU5ZGE3NDQ2NTQwZjQ2CgkgICAgICAgICAqLwoJICAgICAgICB7ICJAZ2VvbWV0cnktdHlwZSI6ICJncm91bmRvdmVybGF5IiB9LCBnZXRNdWx0aShub2RlLCBbCgkgICAgICAgICAgICAibmFtZSIsCgkgICAgICAgICAgICAiYWRkcmVzcyIsCgkgICAgICAgICAgICAidmlzaWJpbGl0eSIsCgkgICAgICAgICAgICAib3BlbiIsCgkgICAgICAgICAgICAicGhvbmVOdW1iZXIiLAoJICAgICAgICAgICAgImRlc2NyaXB0aW9uIiwKCSAgICAgICAgXSksIGdldE1heWJlSFRNTERlc2NyaXB0aW9uKG5vZGUpLCBleHRyYWN0Q2FzY2FkZWRTdHlsZShub2RlLCBzdHlsZU1hcCksIGV4dHJhY3RTdHlsZShub2RlKSwgZXh0cmFjdEljb25IcmVmKG5vZGUpLCBleHRyYWN0RXh0ZW5kZWREYXRhKG5vZGUsIHNjaGVtYSksIGV4dHJhY3RUaW1lU3Bhbihub2RlKSwgZXh0cmFjdFRpbWVTdGFtcChub2RlKSksCgkgICAgfTsKCSAgICBpZiAoZmVhdHVyZS5wcm9wZXJ0aWVzPy52aXNpYmlsaXR5ICE9PSB1bmRlZmluZWQpIHsKCSAgICAgICAgZmVhdHVyZS5wcm9wZXJ0aWVzLnZpc2liaWxpdHkgPSBmZWF0dXJlLnByb3BlcnRpZXMudmlzaWJpbGl0eSAhPT0gIjAiOwoJICAgIH0KCSAgICBjb25zdCBpZCA9IG5vZGUuZ2V0QXR0cmlidXRlKCJpZCIpOwoJICAgIGlmIChpZCAhPT0gbnVsbCAmJiBpZCAhPT0gIiIpCgkgICAgICAgIGZlYXR1cmUuaWQgPSBpZDsKCSAgICByZXR1cm4gZmVhdHVyZTsKCX0KCglmdW5jdGlvbiBnZXRTdHlsZUlkKHN0eWxlKSB7CgkgICAgbGV0IGlkID0gc3R5bGUuZ2V0QXR0cmlidXRlKCJpZCIpOwoJICAgIGNvbnN0IHBhcmVudE5vZGUgPSBzdHlsZS5wYXJlbnROb2RlOwoJICAgIGlmICghaWQgJiYKCSAgICAgICAgaXNFbGVtZW50KHBhcmVudE5vZGUpICYmCgkgICAgICAgIHBhcmVudE5vZGUubG9jYWxOYW1lID09PSAiQ2FzY2FkaW5nU3R5bGUiKSB7CgkgICAgICAgIGlkID0gcGFyZW50Tm9kZS5nZXRBdHRyaWJ1dGUoImttbDppZCIpIHx8IHBhcmVudE5vZGUuZ2V0QXR0cmlidXRlKCJpZCIpOwoJICAgIH0KCSAgICByZXR1cm4gbm9ybWFsaXplSWQoaWQgfHwgIiIpOwoJfQoJZnVuY3Rpb24gYnVpbGRTdHlsZU1hcChub2RlKSB7CgkgICAgY29uc3Qgc3R5bGVNYXAgPSB7fTsKCSAgICBmb3IgKGNvbnN0IHN0eWxlIG9mICQobm9kZSwgIlN0eWxlIikpIHsKCSAgICAgICAgc3R5bGVNYXBbZ2V0U3R5bGVJZChzdHlsZSldID0gZXh0cmFjdFN0eWxlKHN0eWxlKTsKCSAgICB9CgkgICAgZm9yIChjb25zdCBtYXAgb2YgJChub2RlLCAiU3R5bGVNYXAiKSkgewoJICAgICAgICBjb25zdCBpZCA9IG5vcm1hbGl6ZUlkKG1hcC5nZXRBdHRyaWJ1dGUoImlkIikgfHwgIiIpOwoJICAgICAgICB2YWwxKG1hcCwgInN0eWxlVXJsIiwgKHN0eWxlVXJsKSA9PiB7CgkgICAgICAgICAgICBzdHlsZVVybCA9IG5vcm1hbGl6ZUlkKHN0eWxlVXJsKTsKCSAgICAgICAgICAgIGlmIChzdHlsZU1hcFtzdHlsZVVybF0pIHsKCSAgICAgICAgICAgICAgICBzdHlsZU1hcFtpZF0gPSBzdHlsZU1hcFtzdHlsZVVybF07CgkgICAgICAgICAgICB9CgkgICAgICAgIH0pOwoJICAgIH0KCSAgICByZXR1cm4gc3R5bGVNYXA7Cgl9CglmdW5jdGlvbiBidWlsZFNjaGVtYShub2RlKSB7CgkgICAgY29uc3Qgc2NoZW1hID0ge307CgkgICAgZm9yIChjb25zdCBmaWVsZCBvZiAkKG5vZGUsICJTaW1wbGVGaWVsZCIpKSB7CgkgICAgICAgIHNjaGVtYVtmaWVsZC5nZXRBdHRyaWJ1dGUoIm5hbWUiKSB8fCAiIl0gPQoJICAgICAgICAgICAgdHlwZUNvbnZlcnRlcnNbZmllbGQuZ2V0QXR0cmlidXRlKCJ0eXBlIikgfHwgIiJdIHx8CgkgICAgICAgICAgICAgICAgdHlwZUNvbnZlcnRlcnNbInN0cmluZyJdOwoJICAgIH0KCSAgICByZXR1cm4gc2NoZW1hOwoJfQoJY29uc3QgRk9MREVSX1BST1BTID0gWwoJICAgICJuYW1lIiwKCSAgICAidmlzaWJpbGl0eSIsCgkgICAgIm9wZW4iLAoJICAgICJhZGRyZXNzIiwKCSAgICAiZGVzY3JpcHRpb24iLAoJICAgICJwaG9uZU51bWJlciIsCgkgICAgInZpc2liaWxpdHkiLAoJXTsKCWZ1bmN0aW9uIGdldEZvbGRlcihub2RlKSB7CgkgICAgY29uc3QgbWV0YSA9IHt9OwoJICAgIGZvciAoY29uc3QgY2hpbGQgb2YgQXJyYXkuZnJvbShub2RlLmNoaWxkTm9kZXMpKSB7CgkgICAgICAgIGlmIChpc0VsZW1lbnQoY2hpbGQpICYmIEZPTERFUl9QUk9QUy5pbmNsdWRlcyhjaGlsZC50YWdOYW1lKSkgewoJICAgICAgICAgICAgbWV0YVtjaGlsZC50YWdOYW1lXSA9IG5vZGVWYWwoY2hpbGQpOwoJICAgICAgICB9CgkgICAgfQoJICAgIHJldHVybiB7CgkgICAgICAgIHR5cGU6ICJmb2xkZXIiLAoJICAgICAgICBtZXRhLAoJICAgICAgICBjaGlsZHJlbjogW10sCgkgICAgfTsKCX0KCS8qKgoJICogWWllbGQgYSBuZXN0ZWQgdHJlZSB3aXRoIEtNTCBmb2xkZXIgc3RydWN0dXJlCgkgKgoJICogVGhpcyBnZW5lcmF0ZXMgYSB0cmVlIHdpdGggdGhlIGdpdmVuIHN0cnVjdHVyZToKCSAqCgkgKiBgYGBqcwoJICogewoJICogICAidHlwZSI6ICJyb290IiwKCSAqICAgImNoaWxkcmVuIjogWwoJICogICAgIHsKCSAqICAgICAgICJ0eXBlIjogImZvbGRlciIsCgkgKiAgICAgICAibWV0YSI6IHsKCSAqICAgICAgICAgIm5hbWUiOiAiVGVzdCIKCSAqICAgICAgIH0sCgkgKiAgICAgICAiY2hpbGRyZW4iOiBbCgkgKiAgICAgICAgICAvLyAuLi5mZWF0dXJlcyBhbmQgZm9sZGVycwoJICogICAgICAgXQoJICogICAgIH0KCSAqICAgICAvLyAuLi5mZWF0dXJlcwoJICogICBdCgkgKiB9CgkgKiBgYGAKCSAqCgkgKiAjIyMgR3JvdW5kT3ZlcmxheQoJICoKCSAqIEdyb3VuZE92ZXJsYXkgZWxlbWVudHMgYXJlIGNvbnZlcnRlZCBpbnRvCgkgKiBgRmVhdHVyZWAgb2JqZWN0cyB3aXRoIGBQb2x5Z29uYCBnZW9tZXRyaWVzLAoJICogYSBwcm9wZXJ0eSBsaWtlOgoJICoKCSAqIGBgYGpzb24KCSAqIHsKCSAqICAgIkBnZW9tZXRyeS10eXBlIjogImdyb3VuZG92ZXJsYXkiCgkgKiB9CgkgKiBgYGAKCSAqCgkgKiBBbmQgdGhlIGdyb3VuZCBvdmVybGF5J3MgaW1hZ2UgVVJMIGluIHRoZSBgaHJlZmAKCSAqIHByb3BlcnR5LiBHcm91bmQgb3ZlcmxheXMgd2lsbCBuZWVkIHRvIGJlIGRpc3BsYXllZAoJICogd2l0aCBhIHNlcGFyYXRlIG1ldGhvZCB0byBvdGhlciBmZWF0dXJlcywgZGVwZW5kaW5nCgkgKiBvbiB3aGljaCBtYXAgZnJhbWV3b3JrIHlvdSdyZSB1c2luZy4KCSAqLwoJZnVuY3Rpb24ga21sV2l0aEZvbGRlcnMobm9kZSkgewoJICAgIGNvbnN0IHN0eWxlTWFwID0gYnVpbGRTdHlsZU1hcChub2RlKTsKCSAgICBjb25zdCBzY2hlbWEgPSBidWlsZFNjaGVtYShub2RlKTsKCSAgICBjb25zdCB0cmVlID0geyB0eXBlOiAicm9vdCIsIGNoaWxkcmVuOiBbXSB9OwoJICAgIGZ1bmN0aW9uIHRyYXZlcnNlKG5vZGUsIHBvaW50ZXIpIHsKCSAgICAgICAgaWYgKGlzRWxlbWVudChub2RlKSkgewoJICAgICAgICAgICAgc3dpdGNoIChub2RlLnRhZ05hbWUpIHsKCSAgICAgICAgICAgICAgICBjYXNlICJHcm91bmRPdmVybGF5IjogewoJICAgICAgICAgICAgICAgICAgICBjb25zdCBwbGFjZW1hcmsgPSBnZXRHcm91bmRPdmVybGF5KG5vZGUsIHN0eWxlTWFwLCBzY2hlbWEpOwoJICAgICAgICAgICAgICAgICAgICBpZiAocGxhY2VtYXJrKSB7CgkgICAgICAgICAgICAgICAgICAgICAgICBwb2ludGVyLmNoaWxkcmVuLnB1c2gocGxhY2VtYXJrKTsKCSAgICAgICAgICAgICAgICAgICAgfQoJICAgICAgICAgICAgICAgICAgICBicmVhazsKCSAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICAgICAgY2FzZSAiUGxhY2VtYXJrIjogewoJICAgICAgICAgICAgICAgICAgICBjb25zdCBwbGFjZW1hcmsgPSBnZXRQbGFjZW1hcmsobm9kZSwgc3R5bGVNYXAsIHNjaGVtYSk7CgkgICAgICAgICAgICAgICAgICAgIGlmIChwbGFjZW1hcmspIHsKCSAgICAgICAgICAgICAgICAgICAgICAgIHBvaW50ZXIuY2hpbGRyZW4ucHVzaChwbGFjZW1hcmspOwoJICAgICAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoJICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgICAgICBjYXNlICJGb2xkZXIiOiB7CgkgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZvbGRlciA9IGdldEZvbGRlcihub2RlKTsKCSAgICAgICAgICAgICAgICAgICAgcG9pbnRlci5jaGlsZHJlbi5wdXNoKGZvbGRlcik7CgkgICAgICAgICAgICAgICAgICAgIHBvaW50ZXIgPSBmb2xkZXI7CgkgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoJICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgIH0KCSAgICAgICAgfQoJICAgICAgICBpZiAobm9kZS5jaGlsZE5vZGVzKSB7CgkgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5vZGUuY2hpbGROb2Rlcy5sZW5ndGg7IGkrKykgewoJICAgICAgICAgICAgICAgIHRyYXZlcnNlKG5vZGUuY2hpbGROb2Rlc1tpXSwgcG9pbnRlcik7CgkgICAgICAgICAgICB9CgkgICAgICAgIH0KCSAgICB9CgkgICAgdHJhdmVyc2Uobm9kZSwgdHJlZSk7CgkgICAgcmV0dXJuIHRyZWU7Cgl9CgkvKioKCSAqIENvbnZlcnQgS01MIHRvIEdlb0pTT04gaW5jcmVtZW50YWxseSwgcmV0dXJuaW5nCgkgKiBhIFtHZW5lcmF0b3JdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvR3VpZGUvSXRlcmF0b3JzX2FuZF9HZW5lcmF0b3JzKQoJICogdGhhdCB5aWVsZHMgb3V0cHV0IGZlYXR1cmUgYnkgZmVhdHVyZS4KCSAqLwoJZnVuY3Rpb24qIGttbEdlbihub2RlKSB7CgkgICAgY29uc3Qgc3R5bGVNYXAgPSBidWlsZFN0eWxlTWFwKG5vZGUpOwoJICAgIGNvbnN0IHNjaGVtYSA9IGJ1aWxkU2NoZW1hKG5vZGUpOwoJICAgIGZvciAoY29uc3QgcGxhY2VtYXJrIG9mICQobm9kZSwgIlBsYWNlbWFyayIpKSB7CgkgICAgICAgIGNvbnN0IGZlYXR1cmUgPSBnZXRQbGFjZW1hcmsocGxhY2VtYXJrLCBzdHlsZU1hcCwgc2NoZW1hKTsKCSAgICAgICAgaWYgKGZlYXR1cmUpCgkgICAgICAgICAgICB5aWVsZCBmZWF0dXJlOwoJICAgIH0KCSAgICBmb3IgKGNvbnN0IGdyb3VuZE92ZXJsYXkgb2YgJChub2RlLCAiR3JvdW5kT3ZlcmxheSIpKSB7CgkgICAgICAgIGNvbnN0IGZlYXR1cmUgPSBnZXRHcm91bmRPdmVybGF5KGdyb3VuZE92ZXJsYXksIHN0eWxlTWFwLCBzY2hlbWEpOwoJICAgICAgICBpZiAoZmVhdHVyZSkKCSAgICAgICAgICAgIHlpZWxkIGZlYXR1cmU7CgkgICAgfQoJfQoJLyoqCgkgKiBDb252ZXJ0IGEgS01MIGRvY3VtZW50IHRvIEdlb0pTT04uIFRoZSBmaXJzdCBhcmd1bWVudCwgYGRvY2AsIG11c3QgYmUgYSBLTUwKCSAqIGRvY3VtZW50IGFzIGFuIFhNTCBET00gLSBub3QgYXMgYSBzdHJpbmcuIFlvdSBjYW4gZ2V0IHRoaXMgdXNpbmcgalF1ZXJ5J3MgZGVmYXVsdAoJICogYC5hamF4YCBmdW5jdGlvbiBvciB1c2luZyBhIGJhcmUgWE1MSHR0cFJlcXVlc3Qgd2l0aCB0aGUgYC5yZXNwb25zZWAgcHJvcGVydHkKCSAqIGhvbGRpbmcgYW4gWE1MIERPTS4KCSAqCgkgKiBUaGUgb3V0cHV0IGlzIGEgSmF2YVNjcmlwdCBvYmplY3Qgb2YgR2VvSlNPTiBkYXRhLiBZb3UgY2FuIGNvbnZlcnQgaXQgdG8gYSBzdHJpbmcKCSAqIHdpdGggW0pTT04uc3RyaW5naWZ5XShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9KU09OL3N0cmluZ2lmeSkKCSAqIG9yIHVzZSBpdCBkaXJlY3RseSBpbiBsaWJyYXJpZXMuCgkgKi8KCWZ1bmN0aW9uIGttbChub2RlKSB7CgkgICAgcmV0dXJuIHsKCSAgICAgICAgdHlwZTogIkZlYXR1cmVDb2xsZWN0aW9uIiwKCSAgICAgICAgZmVhdHVyZXM6IEFycmF5LmZyb20oa21sR2VuKG5vZGUpKSwKCSAgICB9OwoJfQoKCXZhciB0b0dlb0pzb24gPSAvKiNfX1BVUkVfXyovT2JqZWN0LmZyZWV6ZSh7CgkJX19wcm90b19fOiBudWxsLAoJCWdweDogZ3B4LAoJCWdweEdlbjogZ3B4R2VuLAoJCWttbDoga21sLAoJCWttbEdlbjoga21sR2VuLAoJCWttbFdpdGhGb2xkZXJzOiBrbWxXaXRoRm9sZGVycywKCQl0Y3g6IHRjeCwKCQl0Y3hHZW46IHRjeEdlbgoJfSk7CgoJdmFyIHV0aWxzID0gKCgpID0+IHsKCgkgICAgY29uc3QgcHVyZ2VQcm9wcyA9IChvYmosIGJsYWNrbGlzdCkgPT4gewoJICAgICAgICBpZiAob2JqKSB7CgkgICAgICAgICAgICBsZXQgcnMgPSBPYmplY3QuYXNzaWduKHt9LCBvYmopOwoJICAgICAgICAgICAgaWYgKGJsYWNrbGlzdCkgewoJICAgICAgICAgICAgICAgIGZvciAobGV0IHByb3Agb2YgYmxhY2tsaXN0KSB7CgkgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSByc1twcm9wXTsKCSAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICByZXR1cm4gcnM7CgkgICAgICAgIH0KCSAgICAgICAgcmV0dXJuIHt9OwoJICAgIH07CgoJICAgIGNvbnN0IG1lcmdlUHJvcHMgPSAob2JqMSwgb2JqMikgPT4gewoJICAgICAgICBvYmoxID0gb2JqMT8gb2JqMSA6IHt9OwoJICAgICAgICBvYmoyID0gb2JqMj8gb2JqMiA6IHt9OwoJICAgICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihvYmoxLCBvYmoyKTsKCSAgICB9OwoKCSAgICBjb25zdCBmaXJzdCA9IGEgPT4gYVswXTsKCSAgICBjb25zdCBsYXN0ID0gYSA9PiBhW2EubGVuZ3RoIC0gMV07CgkgICAgY29uc3QgY29vcmRzVG9LZXkgPSBhID0+IGEuam9pbignLCcpOwoKCSAgICBjb25zdCBhZGRUb01hcCA9IChtLCBrLCB2KSA9PiB7CgkgICAgICAgIGxldCBhID0gbVtrXTsKCSAgICAgICAgaWYgKGEpIHsKCSAgICAgICAgICAgIGEucHVzaCh2KTsKCSAgICAgICAgfSBlbHNlIHsKCSAgICAgICAgICAgIG1ba10gPSBbdl07CgkgICAgICAgIH0KCSAgICB9OwoJICAgIAoJICAgIGNvbnN0IHJlbW92ZUZyb21NYXAgPSAobSwgaywgdikgPT4gewoJICAgICAgICBsZXQgYSA9IG1ba107CgkgICAgICAgIGxldCBpZHggPSBudWxsOwoJICAgICAgICBpZiAoYSAmJiAoaWR4ID0gYS5pbmRleE9mKHYpKSA+PSAwKSB7CgkgICAgICAgICAgICBhLnNwbGljZShpZHgsIDEpOwoJICAgICAgICB9CgkgICAgfTsKCSAgICAKCSAgICBjb25zdCBnZXRGaXJzdEZyb21NYXAgPSAobSwgaykgPT4gewoJICAgICAgICBsZXQgYSA9IG1ba107CgkgICAgICAgIGlmIChhICYmIGEubGVuZ3RoID4gMCkgewoJICAgICAgICAgICAgcmV0dXJuIGFbMF07CgkgICAgICAgIH0KCSAgICAgICAgcmV0dXJuIG51bGw7CgkgICAgfTsKCgkgICAgLy8gbmVlZCAzKyBkaWZmZXJlbnQgcG9pbnRzIHRvIGZvcm0gYSByaW5nLCBoZXJlIHVzaW5nID4gMyBpcyAnY296IGEgdGhlIGZpcnN0IGFuZCB0aGUgbGFzdCBwb2ludHMgYXJlIGFjdHVhbGx5IHRoZSBzYW1lCgkgICAgY29uc3QgaXNSaW5nID0gYSA9PiBhLmxlbmd0aCA+IDMgJiYgY29vcmRzVG9LZXkoZmlyc3QoYSkpID09PSBjb29yZHNUb0tleShsYXN0KGEpKTsKCgkgICAgY29uc3QgcmluZ0RpcmVjdGlvbiA9IChhLCB4SWR4LCB5SWR4KSA9PiB7CgkgICAgICAgIHhJZHggPSB4SWR4IHx8IDAsIHlJZHggPSB5SWR4IHx8IDE7CgkgICAgICAgIC8vIGdldCB0aGUgaW5kZXggb2YgdGhlIHBvaW50IHdoaWNoIGhhcyB0aGUgbWF4aW11bSB4IHZhbHVlCgkgICAgICAgIGxldCBtID0gYS5yZWR1Y2UoKG1heHhJZHgsIHYsIGlkeCkgPT4gYVttYXh4SWR4XVt4SWR4XSA+IHZbeElkeF0gPyBtYXh4SWR4IDogaWR4LCAwKTsKCSAgICAgICAgLy8gJ2NveiB0aGUgZmlyc3QgcG9pbnQgaXMgdmlydHVhbGx5IHRoZSBzYW1lIG9uZSBhcyB0aGUgbGFzdCBwb2ludCwgCgkgICAgICAgIC8vIHdlIG5lZWQgdG8gc2tpcCBhLmxlbmd0aCAtIDEgZm9yIGxlZnQgd2hlbiBtID0gMCwKCSAgICAgICAgLy8gYW5kIHNraXAgMCBmb3IgcmlnaHQgd2hlbiBtID0gYS5sZW5ndGggLSAxOwoJICAgICAgICBsZXQgbCA9IG0gPD0gMD8gYS5sZW5ndGggLSAyIDogbSAtIDEsIHIgPSBtID49IGEubGVuZ3RoIC0gMT8gMSA6IG0gKyAxOwoJICAgICAgICBsZXQgeGEgPSBhW2xdW3hJZHhdLCB4YiA9IGFbbV1beElkeF0sIHhjID0gYVtyXVt4SWR4XTsKCSAgICAgICAgbGV0IHlhID0gYVtsXVt5SWR4XSwgeWIgPSBhW21dW3lJZHhdLCB5YyA9IGFbcl1beUlkeF07CgkgICAgICAgIGxldCBkZXQgPSAoeGIgLSB4YSkgKiAoeWMgLSB5YSkgLSAoeGMgLSB4YSkgKiAoeWIgLSB5YSk7CgkgICAgICAgIHJldHVybiBkZXQgPCAwID8gJ2Nsb2Nrd2lzZScgOiAnY291bnRlcmNsb2Nrd2lzZSc7CgkgICAgfTsKCgkgICAgY29uc3QgcHRJbnNpZGVQb2x5Z29uID0gKHB0LCBwb2x5Z29uLCB4SWR4LCB5SWR4KSA9PiB7CgkgICAgICAgIHhJZHggPSB4SWR4IHx8IDAsIHlJZHggPSB5SWR4IHx8IDE7CgkgICAgICAgIGxldCByZXN1bHQgPSBmYWxzZTsKCSAgICAgICAgZm9yIChsZXQgaSA9IDAsIGogPSBwb2x5Z29uLmxlbmd0aCAtIDE7IGkgPCBwb2x5Z29uLmxlbmd0aDsgaiA9IGkrKykgewoJICAgICAgICAgICAgaWYgKChwb2x5Z29uW2ldW3hJZHhdIDw9IHB0W3hJZHhdICYmIHB0W3hJZHhdIDwgcG9seWdvbltqXVt4SWR4XSB8fAoJICAgICAgICAgICAgICAgIHBvbHlnb25bal1beElkeF0gPD0gcHRbeElkeF0gJiYgcHRbeElkeF0gPCBwb2x5Z29uW2ldW3hJZHhdKSAmJgoJICAgICAgICAgICAgICAgIHB0W3lJZHhdIDwgKHBvbHlnb25bal1beUlkeF0gLSBwb2x5Z29uW2ldW3lJZHhdKSAqIChwdFt4SWR4XSAtIHBvbHlnb25baV1beElkeF0pIC8gKHBvbHlnb25bal1beElkeF0gLSBwb2x5Z29uW2ldW3hJZHhdKSArIHBvbHlnb25baV1beUlkeF0pIHsKCSAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gIXJlc3VsdDsKCSAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICAgICAgCgkgICAgICAgIH0KCSAgICAgICAgcmV0dXJuIHJlc3VsdDsKCSAgICB9OwoKCSAgICBjb25zdCBzdHJUb0Zsb2F0ID0gZWwgPT4gZWwgaW5zdGFuY2VvZiBBcnJheT8gZWwubWFwKHN0clRvRmxvYXQpIDogcGFyc2VGbG9hdChlbCk7CgkgICAgCgkgICAgY2xhc3MgUmVmRWxlbWVudHMgZXh0ZW5kcyBNYXAgewoJICAgICAgICBjb25zdHJ1Y3RvcigpIHsKCSAgICAgICAgICAgIHN1cGVyKCk7CgkgICAgICAgICAgICB0aGlzLmJpbmRlcnMgPSBbXTsKCSAgICAgICAgfQoKCSAgICAgICAgYWRkKGssIHYpIHsKCSAgICAgICAgICAgIGlmICghdGhpcy5oYXMoaykpIHsKCSAgICAgICAgICAgICAgICB0aGlzLnNldChrLCB2KTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIC8vIHN1cHByZXNzIGR1cGxjYXRlZCBrZXkgZXJyb3IKCSAgICAgICAgICAgIC8vIGVsc2UKCSAgICAgICAgICAgIC8vIHRocm93IGBFcnJvcjogYWRkaW5nIGR1cGxpY2F0ZWQga2V5ICcke2t9JyB0byBSZWZFbGVtZW50c2A7CgkgICAgICAgIH0KCgkgICAgICAgIGFkZEJpbmRlcihiaW5kZXIpIHsKCSAgICAgICAgICAgIHRoaXMuYmluZGVycy5wdXNoKGJpbmRlcik7CgkgICAgICAgIH0KCgkgICAgICAgIGJpbmRBbGwoKSB7CgkgICAgICAgICAgICB0aGlzLmJpbmRlcnMuZm9yRWFjaChiaW5kZXIgPT4gYmluZGVyLmJpbmQoKSk7CgkgICAgICAgIH0KCSAgICB9CgoJICAgIGNsYXNzIExhdGVCaW5kZXIgewoJICAgICAgICBjb25zdHJ1Y3Rvcihjb250YWluZXIsIHZhbHVlRnVuYywgY3R4LCBhcmdzKSB7CgkgICAgICAgICAgICB0aGlzLmNvbnRhaW5lciA9IGNvbnRhaW5lcjsKCSAgICAgICAgICAgIHRoaXMudmFsdWVGdW5jID0gdmFsdWVGdW5jOwoJICAgICAgICAgICAgdGhpcy5jdHggPSBjdHg7CgkgICAgICAgICAgICB0aGlzLmFyZ3MgPSBhcmdzOwoJICAgICAgICB9CgoJICAgICAgICBiaW5kKCkgewoJICAgICAgICAgICAgbGV0IHYgPSB0aGlzLnZhbHVlRnVuYy5hcHBseSh0aGlzLmN0eCwgdGhpcy5hcmdzKTsKCSAgICAgICAgICAgIGlmICh0aGlzLmNvbnRhaW5lciBpbnN0YW5jZW9mIEFycmF5KSB7CgkgICAgICAgICAgICAgICAgbGV0IGlkeCA9IHRoaXMuY29udGFpbmVyLmluZGV4T2YodGhpcyk7CgkgICAgICAgICAgICAgICAgaWYgKGlkeCA+PSAwKSB7CgkgICAgICAgICAgICAgICAgICAgIGxldCBhcmdzID0gW2lkeCwgMV07CgkgICAgICAgICAgICAgICAgICAgIGlmICh2KSB7CgkgICAgICAgICAgICAgICAgICAgICAgICBhcmdzLnB1c2godik7CgkgICAgICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgICAgICAgICAgW10uc3BsaWNlLmFwcGx5KHRoaXMuY29udGFpbmVyLCBhcmdzKTsKCSAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiB0aGlzLmNvbnRhaW5lciA9PT0gJ29iamVjdCcpIHsKCSAgICAgICAgICAgICAgICBsZXQgayA9IE9iamVjdC5rZXlzKHRoaXMuY29udGFpbmVyKS5maW5kKHYgPT4gdGhpcy5jb250YWluZXJbdl0gPT09IHRoaXMpOwoJICAgICAgICAgICAgICAgIGlmIChrKSB7CgkgICAgICAgICAgICAgICAgICAgIGlmICh2KSB7CgkgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNvbnRhaW5lcltrXSA9IHY7CgkgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CgkgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5jb250YWluZXJba107CgkgICAgICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICB9CgkgICAgICAgIH0KCSAgICB9CgoJICAgIGNsYXNzIFdheUNvbGxlY3Rpb24gZXh0ZW5kcyBBcnJheSB7CgkgICAgICAgIGNvbnN0cnVjdG9yKCkgewoJICAgICAgICAgICAgc3VwZXIoKTsKCSAgICAgICAgICAgIHRoaXMuZmlyc3RNYXAgPSB7fTsKCSAgICAgICAgICAgIHRoaXMubGFzdE1hcCA9IHt9OwoJICAgICAgICB9CgoJICAgICAgICBhZGRXYXkod2F5KSB7CgkgICAgICAgICAgICB3YXkgPSB3YXkudG9Db29yZHNBcnJheSgpOwoJICAgICAgICAgICAgaWYgKHdheS5sZW5ndGggPiAwKSB7CgkgICAgICAgICAgICAgICAgdGhpcy5wdXNoKHdheSk7CgkgICAgICAgICAgICAgICAgYWRkVG9NYXAodGhpcy5maXJzdE1hcCwgY29vcmRzVG9LZXkoZmlyc3Qod2F5KSksIHdheSk7CgkgICAgICAgICAgICAgICAgYWRkVG9NYXAodGhpcy5sYXN0TWFwLCBjb29yZHNUb0tleShsYXN0KHdheSkpLCB3YXkpOwoJICAgICAgICAgICAgfQoJICAgICAgICB9CgoJICAgICAgICB0b1N0cmluZ3MoKSB7CgkgICAgICAgICAgICBsZXQgc3RyaW5ncyA9IFtdLCB3YXkgPSBudWxsOwoJICAgICAgICAgICAgd2hpbGUgKHdheSA9IHRoaXMuc2hpZnQoKSkgewoJICAgICAgICAgICAgICAgIHJlbW92ZUZyb21NYXAodGhpcy5maXJzdE1hcCwgY29vcmRzVG9LZXkoZmlyc3Qod2F5KSksIHdheSk7CgkgICAgICAgICAgICAgICAgcmVtb3ZlRnJvbU1hcCh0aGlzLmxhc3RNYXAsIGNvb3Jkc1RvS2V5KGxhc3Qod2F5KSksIHdheSk7CgkgICAgICAgICAgICAgICAgbGV0IGN1cnJlbnQgPSB3YXksIG5leHQgPSBudWxsOwoJICAgICAgICAgICAgICAgIGRvIHsKCSAgICAgICAgICAgICAgICAgICAgbGV0IGtleSA9IGNvb3Jkc1RvS2V5KGxhc3QoY3VycmVudCkpLCBzaG91bGRSZXZlcnNlID0gZmFsc2U7CgoJICAgICAgICAgICAgICAgICAgICBuZXh0ID0gZ2V0Rmlyc3RGcm9tTWFwKHRoaXMuZmlyc3RNYXAsIGtleSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAoJICAgICAgICAgICAgICAgICAgICBpZiAoIW5leHQpIHsKCSAgICAgICAgICAgICAgICAgICAgICAgIG5leHQgPSBnZXRGaXJzdEZyb21NYXAodGhpcy5sYXN0TWFwLCBrZXkpOwoJICAgICAgICAgICAgICAgICAgICAgICAgc2hvdWxkUmV2ZXJzZSA9IHRydWU7CgkgICAgICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgICAgICAgICAgCgkgICAgICAgICAgICAgICAgICAgIGlmIChuZXh0KSB7CgkgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNwbGljZSh0aGlzLmluZGV4T2YobmV4dCksIDEpOwoJICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlRnJvbU1hcCh0aGlzLmZpcnN0TWFwLCBjb29yZHNUb0tleShmaXJzdChuZXh0KSksIG5leHQpOwoJICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlRnJvbU1hcCh0aGlzLmxhc3RNYXAsIGNvb3Jkc1RvS2V5KGxhc3QobmV4dCkpLCBuZXh0KTsKCSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzaG91bGRSZXZlcnNlKSB7CgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYWx3YXlzIHJldmVyc2Ugc2hvcnRlciBvbmUgdG8gc2F2ZSB0aW1lCgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5leHQubGVuZ3RoID4gY3VycmVudC5sZW5ndGgpIHsKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2N1cnJlbnQsIG5leHRdID0gW25leHQsIGN1cnJlbnRdOwoJICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXh0LnJldmVyc2UoKTsKCSAgICAgICAgICAgICAgICAgICAgICAgIH0KCgkgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50ID0gY3VycmVudC5jb25jYXQobmV4dC5zbGljZSgxKSk7CgkgICAgICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgICAgICB9IHdoaWxlIChuZXh0KTsKCSAgICAgICAgICAgICAgICBzdHJpbmdzLnB1c2goc3RyVG9GbG9hdChjdXJyZW50KSk7CgkgICAgICAgICAgICB9CgoJICAgICAgICAgICAgcmV0dXJuIHN0cmluZ3M7CgkgICAgICAgIH0KCgkgICAgICAgIHRvUmluZ3MoZGlyZWN0aW9uKSB7CgkgICAgICAgICAgICBsZXQgc3RyaW5ncyA9IHRoaXMudG9TdHJpbmdzKCk7CgkgICAgICAgICAgICBsZXQgcmluZ3MgPSBbXSwgc3RyaW5nID0gbnVsbDsKCSAgICAgICAgICAgIHdoaWxlIChzdHJpbmcgPSBzdHJpbmdzLnNoaWZ0KCkpIHsKCSAgICAgICAgICAgICAgICBpZiAoaXNSaW5nKHN0cmluZykpIHsKCSAgICAgICAgICAgICAgICAgICAgaWYgKHJpbmdEaXJlY3Rpb24oc3RyaW5nKSAhPT0gZGlyZWN0aW9uKSB7CgkgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcucmV2ZXJzZSgpOwoJICAgICAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICAgICAgICAgIHJpbmdzLnB1c2goc3RyaW5nKTsKCSAgICAgICAgICAgICAgICB9ICAgIAoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgcmV0dXJuIHJpbmdzOwoJICAgICAgICB9CgkgICAgfQoKCSAgICByZXR1cm4ge3B1cmdlUHJvcHMsIG1lcmdlUHJvcHMsCgkgICAgICAgIGZpcnN0LCBsYXN0LCBjb29yZHNUb0tleSwKCSAgICAgICAgYWRkVG9NYXAsIHJlbW92ZUZyb21NYXAsIGdldEZpcnN0RnJvbU1hcCwKCSAgICAgICAgaXNSaW5nLCByaW5nRGlyZWN0aW9uLCBwdEluc2lkZVBvbHlnb24sIHN0clRvRmxvYXQsCgkgICAgICAgIFJlZkVsZW1lbnRzLCBMYXRlQmluZGVyLCBXYXlDb2xsZWN0aW9ufTsKCX0pKCk7CgoJdmFyIGJ1aWxkaW5nID0gewoJfTsKCXZhciBoaWdod2F5ID0gewoJCXdoaXRlbGlzdDogWwoJCQkic2VydmljZXMiLAoJCQkicmVzdF9hcmVhIiwKCQkJImVzY2FwZSIsCgkJCSJlbGV2YXRvciIKCQldCgl9OwoJdmFyIG5hdHVyYWwgPSB7CgkJYmxhY2tsaXN0OiBbCgkJCSJjb2FzdGxpbmUiLAoJCQkiY2xpZmYiLAoJCQkicmlkZ2UiLAoJCQkiYXJldGUiLAoJCQkidHJlZV9yb3ciCgkJXQoJfTsKCXZhciBsYW5kdXNlID0gewoJfTsKCXZhciB3YXRlcndheSA9IHsKCQl3aGl0ZWxpc3Q6IFsKCQkJInJpdmVyYmFuayIsCgkJCSJkb2NrIiwKCQkJImJvYXR5YXJkIiwKCQkJImRhbSIKCQldCgl9OwoJdmFyIGFtZW5pdHkgPSB7Cgl9OwoJdmFyIGxlaXN1cmUgPSB7Cgl9OwoJdmFyIGJhcnJpZXIgPSB7CgkJd2hpdGVsaXN0OiBbCgkJCSJjaXR5X3dhbGwiLAoJCQkiZGl0Y2giLAoJCQkiaGVkZ2UiLAoJCQkicmV0YWluaW5nX3dhbGwiLAoJCQkid2FsbCIsCgkJCSJzcGlrZXMiCgkJXQoJfTsKCXZhciByYWlsd2F5ID0gewoJCXdoaXRlbGlzdDogWwoJCQkic3RhdGlvbiIsCgkJCSJ0dXJudGFibGUiLAoJCQkicm91bmRob3VzZSIsCgkJCSJwbGF0Zm9ybSIKCQldCgl9OwoJdmFyIGFyZWEgPSB7Cgl9OwoJdmFyIGJvdW5kYXJ5ID0gewoJfTsKCXZhciBtYW5fbWFkZSA9IHsKCQlibGFja2xpc3Q6IFsKCQkJImN1dGxpbmUiLAoJCQkiZW1iYW5rbWVudCIsCgkJCSJwaXBlbGluZSIKCQldCgl9OwoJdmFyIHBvd2VyID0gewoJCXdoaXRlbGlzdDogWwoJCQkicGxhbnQiLAoJCQkic3Vic3RhdGlvbiIsCgkJCSJnZW5lcmF0b3IiLAoJCQkidHJhbnNmb3JtZXIiCgkJXQoJfTsKCXZhciBwbGFjZSA9IHsKCX07Cgl2YXIgc2hvcCA9IHsKCX07Cgl2YXIgYWVyb3dheSA9IHsKCQlibGFja2xpc3Q6IFsKCQkJInRheGl3YXkiCgkJXQoJfTsKCXZhciB0b3VyaXNtID0gewoJfTsKCXZhciBoaXN0b3JpYyA9IHsKCX07Cgl2YXIgcHVibGljX3RyYW5zcG9ydCA9IHsKCX07Cgl2YXIgb2ZmaWNlID0gewoJfTsKCXZhciBtaWxpdGFyeSA9IHsKCX07Cgl2YXIgcnVpbnMgPSB7Cgl9OwoJdmFyIGNyYWZ0ID0gewoJfTsKCXZhciBnb2xmID0gewoJfTsKCXZhciBpbmRvb3IgPSB7Cgl9OwoJdmFyIHJlcXVpcmUkJDEgPSB7CgkJYnVpbGRpbmc6IGJ1aWxkaW5nLAoJCWhpZ2h3YXk6IGhpZ2h3YXksCgkJbmF0dXJhbDogbmF0dXJhbCwKCQlsYW5kdXNlOiBsYW5kdXNlLAoJCXdhdGVyd2F5OiB3YXRlcndheSwKCQlhbWVuaXR5OiBhbWVuaXR5LAoJCWxlaXN1cmU6IGxlaXN1cmUsCgkJYmFycmllcjogYmFycmllciwKCQlyYWlsd2F5OiByYWlsd2F5LAoJCWFyZWE6IGFyZWEsCgkJYm91bmRhcnk6IGJvdW5kYXJ5LAoJCW1hbl9tYWRlOiBtYW5fbWFkZSwKCQlwb3dlcjogcG93ZXIsCgkJcGxhY2U6IHBsYWNlLAoJCXNob3A6IHNob3AsCgkJYWVyb3dheTogYWVyb3dheSwKCQl0b3VyaXNtOiB0b3VyaXNtLAoJCWhpc3RvcmljOiBoaXN0b3JpYywKCQlwdWJsaWNfdHJhbnNwb3J0OiBwdWJsaWNfdHJhbnNwb3J0LAoJCW9mZmljZTogb2ZmaWNlLAoJCSJidWlsZGluZzpwYXJ0IjogewoJfSwKCQltaWxpdGFyeTogbWlsaXRhcnksCgkJcnVpbnM6IHJ1aW5zLAoJCSJhcmVhOmhpZ2h3YXkiOiB7Cgl9LAoJCWNyYWZ0OiBjcmFmdCwKCQlnb2xmOiBnb2xmLAoJCWluZG9vcjogaW5kb29yCgl9OwoKCXZhciBvc21vYmpzID0gKCgpID0+IHsKCgkgICAgY29uc3Qge2ZpcnN0LCBsYXN0LCBjb29yZHNUb0tleSwKCSAgICAgICAgYWRkVG9NYXAsIHJlbW92ZUZyb21NYXAsIGdldEZpcnN0RnJvbU1hcCwgCgkgICAgICAgIGlzUmluZywgcmluZ0RpcmVjdGlvbiwgcHRJbnNpZGVQb2x5Z29uLCBzdHJUb0Zsb2F0LCAKCSAgICAgICAgTGF0ZUJpbmRlciwgV2F5Q29sbGVjdGlvbn0gPSB1dGlscywKCSAgICAgICAgcG9seWdvblRhZ3MgPSByZXF1aXJlJCQxOwoKCSAgICBjbGFzcyBPc21PYmplY3QgewoJICAgICAgICBjb25zdHJ1Y3Rvcih0eXBlLCBpZCwgcmVmRWxlbXMpIHsKCSAgICAgICAgICAgIHRoaXMudHlwZSA9IHR5cGU7CgkgICAgICAgICAgICB0aGlzLmlkID0gaWQ7CgkgICAgICAgICAgICB0aGlzLnJlZkVsZW1zID0gcmVmRWxlbXM7CgkgICAgICAgICAgICB0aGlzLnRhZ3MgPSB7fTsKCSAgICAgICAgICAgIHRoaXMucHJvcHMgPSB7aWQ6IHRoaXMuZ2V0Q29tcG9zaXRlSWQoKX07CgkgICAgICAgICAgICB0aGlzLnJlZkNvdW50ID0gMDsKCSAgICAgICAgICAgIHRoaXMuaGFzVGFnID0gZmFsc2U7CgkgICAgICAgICAgICBpZiAocmVmRWxlbXMpIHsKCSAgICAgICAgICAgICAgICByZWZFbGVtcy5hZGQodGhpcy5nZXRDb21wb3NpdGVJZCgpLCB0aGlzKTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgfQoKCSAgICAgICAgYWRkVGFncyh0YWdzKSB7CgkgICAgICAgICAgICB0aGlzLnRhZ3MgPSBPYmplY3QuYXNzaWduKHRoaXMudGFncywgdGFncyk7CgkgICAgICAgICAgICB0aGlzLmhhc1RhZyA9IHRhZ3M/IHRydWUgOiBmYWxzZTsKCSAgICAgICAgfQoKCSAgICAgICAgYWRkVGFnKGssIHYpIHsKCSAgICAgICAgICAgIHRoaXMudGFnc1trXSA9IHY7CgkgICAgICAgICAgICB0aGlzLmhhc1RhZyA9IGs/IHRydWUgOiBmYWxzZTsKCSAgICAgICAgfQoKCSAgICAgICAgYWRkUHJvcChrLCB2KSB7CgkgICAgICAgICAgICB0aGlzLnByb3BzW2tdID0gdjsKCSAgICAgICAgfQoKCSAgICAgICAgYWRkUHJvcHMocHJvcHMpIHsKCSAgICAgICAgICAgIHRoaXMucHJvcHMgPSBPYmplY3QuYXNzaWduKHRoaXMucHJvcHMsIHByb3BzKTsgICAgCgkgICAgICAgIH0KCgkgICAgICAgIGdldENvbXBvc2l0ZUlkKCkgewoJICAgICAgICAgICAgcmV0dXJuIGAke3RoaXMudHlwZX0vJHt0aGlzLmlkfWA7CgkgICAgICAgIH0KCgkgICAgICAgIGdldFByb3BzKCkgewoJICAgICAgICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24odGhpcy5wcm9wcywgdGhpcy50YWdzKTsKCSAgICAgICAgfSAgICAgICAgCgoJICAgICAgICB0b0ZlYXR1cmVBcnJheSgpIHsKCSAgICAgICAgICAgIHJldHVybiBbXTsKCSAgICAgICAgfQoJICAgIH0KCgkgICAgY2xhc3MgTm9kZSBleHRlbmRzIE9zbU9iamVjdCB7CgkgICAgICAgIGNvbnN0cnVjdG9yKGlkLCByZWZFbGVtcykgewoJICAgICAgICAgICAgc3VwZXIoJ25vZGUnLCBpZCwgcmVmRWxlbXMpOwoJICAgICAgICAgICAgdGhpcy5sYXRMbmcgPSBudWxsOwoJICAgICAgICB9CgoJICAgICAgICBzZXRMYXRMbmcobGF0TG5nKSB7CgkgICAgICAgICAgICB0aGlzLmxhdExuZyA9IGxhdExuZzsKCSAgICAgICAgfQoKCSAgICAgICAgdG9GZWF0dXJlQXJyYXkoKSB7CgkgICAgICAgICAgICBpZiAodGhpcy5sYXRMbmcpIHsKCSAgICAgICAgICAgICAgICByZXR1cm4gW3sKCSAgICAgICAgICAgICAgICAgICAgdHlwZTogJ0ZlYXR1cmUnLAoJICAgICAgICAgICAgICAgICAgICBpZDogdGhpcy5nZXRDb21wb3NpdGVJZCgpLAoJICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0aWVzOiB0aGlzLmdldFByb3BzKCksCgkgICAgICAgICAgICAgICAgICAgIGdlb21ldHJ5OiB7CgkgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAnUG9pbnQnLAoJICAgICAgICAgICAgICAgICAgICAgICAgY29vcmRpbmF0ZXM6IHN0clRvRmxvYXQoW3RoaXMubGF0TG5nLmxvbiwgdGhpcy5sYXRMbmcubGF0XSkKCSAgICAgICAgICAgICAgICAgICAgfQoJICAgICAgICAgICAgICAgIH1dOwoJICAgICAgICAgICAgfQoKCSAgICAgICAgICAgIHJldHVybiBbXTsKCSAgICAgICAgfQoKCSAgICAgICAgZ2V0TGF0TG5nKCkgewoJICAgICAgICAgICAgcmV0dXJuIHRoaXMubGF0TG5nOwoJICAgICAgICB9CgkgICAgfQoKCSAgICBjbGFzcyBXYXkgZXh0ZW5kcyBPc21PYmplY3QgewoJICAgICAgICBjb25zdHJ1Y3RvcihpZCwgcmVmRWxlbXMpIHsKCSAgICAgICAgICAgIHN1cGVyKCd3YXknLCBpZCwgcmVmRWxlbXMpOwoJICAgICAgICAgICAgdGhpcy5sYXRMbmdBcnJheSA9IFtdOwoJICAgICAgICAgICAgdGhpcy5pc1BvbHlnb24gPSBmYWxzZTsKCSAgICAgICAgfQoKCSAgICAgICAgYWRkTGF0TG5nKGxhdExuZykgewoJICAgICAgICAgICAgdGhpcy5sYXRMbmdBcnJheS5wdXNoKGxhdExuZyk7CgkgICAgICAgIH0KCgkgICAgICAgIHNldExhdExuZ0FycmF5KGxhdExuZ0FycmF5KSB7CgkgICAgICAgICAgICB0aGlzLmxhdExuZ0FycmF5ID0gbGF0TG5nQXJyYXk7CgkgICAgICAgIH0KCgkgICAgICAgIGFkZE5vZGVSZWYocmVmKSB7CgkgICAgICAgICAgICBsZXQgYmluZGVyID0gbmV3IExhdGVCaW5kZXIodGhpcy5sYXRMbmdBcnJheSwgZnVuY3Rpb24oaWQpIHsKCSAgICAgICAgICAgICAgICBsZXQgbm9kZSA9IHRoaXMucmVmRWxlbXMuZ2V0KGBub2RlLyR7aWR9YCk7CgkgICAgICAgICAgICAgICAgaWYgKG5vZGUpIHsKCSAgICAgICAgICAgICAgICAgICAgbm9kZS5yZWZDb3VudCsrOwoJICAgICAgICAgICAgICAgICAgICByZXR1cm4gbm9kZS5nZXRMYXRMbmcoKTsKCSAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICB9LCB0aGlzLCBbcmVmXSk7CgoJICAgICAgICAgICAgdGhpcy5sYXRMbmdBcnJheS5wdXNoKGJpbmRlcik7CgkgICAgICAgICAgICB0aGlzLnJlZkVsZW1zLmFkZEJpbmRlcihiaW5kZXIpOwoJICAgICAgICB9CgoJICAgICAgICBhbmFseXplVGFnKGssIHYpIHsKCSAgICAgICAgICAgIGxldCBvID0gcG9seWdvblRhZ3Nba107CgkgICAgICAgICAgICBpZiAobykgewoJICAgICAgICAgICAgICAgIHRoaXMuaXNQb2x5Z29uID0gdHJ1ZTsKCSAgICAgICAgICAgICAgICBpZiAoby53aGl0ZWxpc3QpIHsKCSAgICAgICAgICAgICAgICAgICAgdGhpcy5pc1BvbHlnb24gPSBvLndoaXRlbGlzdC5pbmRleE9mKHYpID49IDA/IHRydWUgOiBmYWxzZTsKCSAgICAgICAgICAgICAgICB9IGVsc2UgaWYoby5ibGFja2xpc3QpIHsKCSAgICAgICAgICAgICAgICAgICAgdGhpcy5pc1BvbHlnb24gPSBvLmJsYWNrbGlzdC5pbmRleE9mKHYpID49IDA/IGZhbHNlIDogdHJ1ZTsKCSAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICB9CgkgICAgICAgIH0KCgkgICAgICAgIGFkZFRhZ3ModGFncykgewoJICAgICAgICAgICAgc3VwZXIuYWRkVGFncyh0YWdzKTsKCSAgICAgICAgICAgIGZvciAobGV0IFtrLCB2XSBvZiBPYmplY3QuZW50cmllcyh0YWdzKSkgewoJICAgICAgICAgICAgICAgIHRoaXMuYW5hbHl6ZVRhZyhrLCB2KTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgfQoKCSAgICAgICAgYWRkVGFnKGssIHYpIHsKCSAgICAgICAgICAgIHN1cGVyLmFkZFRhZyhrLCB2KTsKCSAgICAgICAgICAgIHRoaXMuYW5hbHl6ZVRhZyhrLCB2KTsKCSAgICAgICAgfQoKCSAgICAgICAgdG9Db29yZHNBcnJheSgpIHsKCSAgICAgICAgICAgIHJldHVybiB0aGlzLmxhdExuZ0FycmF5Lm1hcChsYXRMbmcgPT4gW2xhdExuZy5sb24sIGxhdExuZy5sYXRdKTsKCSAgICAgICAgfQoKCSAgICAgICAgdG9GZWF0dXJlQXJyYXkoKSB7CgkgICAgICAgICAgICBsZXQgY29vcmRzQXJyYXkgPSB0aGlzLnRvQ29vcmRzQXJyYXkoKTsKCSAgICAgICAgICAgIGlmIChjb29yZHNBcnJheS5sZW5ndGggPiAxKSB7CgkgICAgICAgICAgICAgICAgY29vcmRzQXJyYXkgPSBzdHJUb0Zsb2F0KGNvb3Jkc0FycmF5KTsKCSAgICAgICAgICAgICAgICBsZXQgZmVhdHVyZSA9IHsKCSAgICAgICAgICAgICAgICAgICAgdHlwZTogJ0ZlYXR1cmUnLAoJICAgICAgICAgICAgICAgICAgICBpZDogdGhpcy5nZXRDb21wb3NpdGVJZCgpLAoJICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0aWVzOiB0aGlzLmdldFByb3BzKCksCgkgICAgICAgICAgICAgICAgICAgIGdlb21ldHJ5OiB7CgkgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAnTGluZVN0cmluZycsCgkgICAgICAgICAgICAgICAgICAgICAgICBjb29yZGluYXRlczogY29vcmRzQXJyYXkKCSAgICAgICAgICAgICAgICAgICAgfQoJICAgICAgICAgICAgICAgIH07CgoJICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzUG9seWdvbiAmJiBpc1JpbmcoY29vcmRzQXJyYXkpKSB7CgkgICAgICAgICAgICAgICAgICAgIGlmIChyaW5nRGlyZWN0aW9uKGNvb3Jkc0FycmF5KSAhPT0gJ2NvdW50ZXJjbG9ja3dpc2UnKSB7CgkgICAgICAgICAgICAgICAgICAgICAgICBjb29yZHNBcnJheS5yZXZlcnNlKCk7CgkgICAgICAgICAgICAgICAgICAgIH0KCgkgICAgICAgICAgICAgICAgICAgIGZlYXR1cmUuZ2VvbWV0cnkgPSB7CgkgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAnUG9seWdvbicsCgkgICAgICAgICAgICAgICAgICAgICAgICBjb29yZGluYXRlczogW2Nvb3Jkc0FycmF5XQoJICAgICAgICAgICAgICAgICAgICB9OwoKCSAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFtmZWF0dXJlXTsKCSAgICAgICAgICAgICAgICB9CgoJICAgICAgICAgICAgICAgIHJldHVybiBbZmVhdHVyZV07CgkgICAgICAgICAgICB9CgoJICAgICAgICAgICAgcmV0dXJuIFtdOwoJICAgICAgICB9CgkgICAgfQoKCSAgICBjbGFzcyBSZWxhdGlvbiBleHRlbmRzIE9zbU9iamVjdCB7CgkgICAgICAgIGNvbnN0cnVjdG9yKGlkLCByZWZFbGVtcykgewoJICAgICAgICAgICAgc3VwZXIoJ3JlbGF0aW9uJywgaWQsIHJlZkVsZW1zKTsKCSAgICAgICAgICAgIHRoaXMucmVsYXRpb25zID0gW107CgkgICAgICAgICAgICB0aGlzLm5vZGVzID0gW107CgkgICAgICAgICAgICB0aGlzLmJvdW5kcyA9IG51bGw7CgkgICAgICAgIH0KCgkgICAgICAgIHNldEJvdW5kcyhib3VuZHMpIHsKCSAgICAgICAgICAgIHRoaXMuYm91bmRzID0gYm91bmRzOwoJICAgICAgICB9CgoJICAgICAgICBhZGRNZW1iZXIobWVtYmVyKSB7CgkgICAgICAgICAgICBzd2l0Y2ggKG1lbWJlci50eXBlKSB7CgkgICAgICAgICAgICAgICAgLy8gc3VwZXIgcmVsYXRpb24sIG5lZWQgdG8gZG8gY29tYmluYXRpb24KCSAgICAgICAgICAgICAgICBjYXNlICdyZWxhdGlvbic6CgkgICAgICAgICAgICAgICAgICAgIGxldCBiaW5kZXIgPSBuZXcgTGF0ZUJpbmRlcih0aGlzLnJlbGF0aW9ucywgZnVuY3Rpb24oaWQpIHsKCSAgICAgICAgICAgICAgICAgICAgICAgIGxldCByZWxhdGlvbiA9IHRoaXMucmVmRWxlbXMuZ2V0KGByZWxhdGlvbi8ke2lkfWApOwoJICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlbGF0aW9uKSB7CgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVsYXRpb24ucmVmQ291bnQrKzsKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVsYXRpb247CgkgICAgICAgICAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICAgICAgICAgIH0sIHRoaXMsIFttZW1iZXIucmVmXSk7CgkgICAgICAgICAgICAgICAgICAgIHRoaXMucmVsYXRpb25zLnB1c2goYmluZGVyKTsKCSAgICAgICAgICAgICAgICAgICAgdGhpcy5yZWZFbGVtcy5hZGRCaW5kZXIoYmluZGVyKTsKCSAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgoJICAgICAgICAgICAgICAgIGNhc2UgJ3dheSc6CgkgICAgICAgICAgICAgICAgICAgIGlmICghbWVtYmVyLnJvbGUpIHsKCSAgICAgICAgICAgICAgICAgICAgICAgIG1lbWJlci5yb2xlID0gJyc7CgkgICAgICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgICAgICAgICAgbGV0IHdheXMgPSB0aGlzW21lbWJlci5yb2xlXTsKCSAgICAgICAgICAgICAgICAgICAgaWYgKCF3YXlzKSB7CgkgICAgICAgICAgICAgICAgICAgICAgICB3YXlzID0gdGhpc1ttZW1iZXIucm9sZV0gPSBbXTsKCSAgICAgICAgICAgICAgICAgICAgfQoJICAgICAgICAgICAgICAgICAgICBpZiAobWVtYmVyLmdlb21ldHJ5KSB7CgkgICAgICAgICAgICAgICAgICAgICAgICBsZXQgd2F5ID0gbmV3IFdheShtZW1iZXIucmVmLCB0aGlzLnJlZkVsZW1zKTsKCSAgICAgICAgICAgICAgICAgICAgICAgIHdheS5zZXRMYXRMbmdBcnJheShtZW1iZXIuZ2VvbWV0cnkpOwoJICAgICAgICAgICAgICAgICAgICAgICAgd2F5LnJlZkNvdW50Kys7CgkgICAgICAgICAgICAgICAgICAgICAgICB3YXlzLnB1c2god2F5KTsKCSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChtZW1iZXIubm9kZXMpIHsKCSAgICAgICAgICAgICAgICAgICAgICAgIGxldCB3YXkgPSBuZXcgV2F5KG1lbWJlci5yZWYsIHRoaXMucmVmRWxlbXMpOwoJICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgbmlkIG9mIG1lbWJlci5ub2RlcykgewoJICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdheS5hZGROb2RlUmVmKG5pZCk7CgkgICAgICAgICAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICAgICAgICAgICAgICB3YXkucmVmQ291bnQrKzsKCSAgICAgICAgICAgICAgICAgICAgICAgIHdheXMucHVzaCh3YXkpOwoJICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewoJICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGJpbmRlciA9IG5ldyBMYXRlQmluZGVyKHdheXMsIGZ1bmN0aW9uKGlkKSB7CgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHdheSA9IHRoaXMucmVmRWxlbXMuZ2V0KGB3YXkvJHtpZH1gKTsKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAod2F5KSB7CgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdheS5yZWZDb3VudCsrOwoJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gd2F5OwoJICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgICAgICAgICAgICAgIH0sIHRoaXMsIFttZW1iZXIucmVmXSk7CgkgICAgICAgICAgICAgICAgICAgICAgICB3YXlzLnB1c2goYmluZGVyKTsKCSAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucmVmRWxlbXMuYWRkQmluZGVyKGJpbmRlcik7CgkgICAgICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgoJICAgICAgICAgICAgICAgIGNhc2UgJ25vZGUnOgoJICAgICAgICAgICAgICAgICAgICBsZXQgbm9kZSA9IG51bGw7CgkgICAgICAgICAgICAgICAgICAgIGlmIChtZW1iZXIubGF0ICYmIG1lbWJlci5sb24pIHsKCSAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUgPSBuZXcgTm9kZShtZW1iZXIucmVmLCB0aGlzLnJlZkVsZW1zKTsKCSAgICAgICAgICAgICAgICAgICAgICAgIG5vZGUuc2V0TGF0TG5nKHtsb246IG1lbWJlci5sb24sIGxhdDogbWVtYmVyLmxhdH0pOwoJICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1lbWJlci50YWdzKSB7CgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZS5hZGRUYWdzKG1lbWJlci50YWdzKTsKCSAgICAgICAgICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgICAgICAgICAgICAgIGZvciAobGV0IFtrLCB2XSBvZiBPYmplY3QuZW50cmllcyhtZW1iZXIpKSB7CgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKFsnaWQnLCAndHlwZScsICdsYXQnLCAnbG9uJ10uaW5kZXhPZihrKSA8IDApIHsKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZS5hZGRQcm9wKGssIHYpOwoJICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgICAgICAgICAgICAgIH0KCgkgICAgICAgICAgICAgICAgICAgICAgICBub2RlLnJlZkNvdW50Kys7CgkgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm5vZGVzLnB1c2gobm9kZSk7CgkgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CgkgICAgICAgICAgICAgICAgICAgICAgICBsZXQgYmluZGVyID0gbmV3IExhdGVCaW5kZXIodGhpcy5ub2RlcywgZnVuY3Rpb24oaWQpIHsKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgbm9kZSA9IHRoaXMucmVmRWxlbXMuZ2V0KGBub2RlLyR7aWR9YCk7CgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5vZGUpIHsKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZS5yZWZDb3VudCsrOwoJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbm9kZTsKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICAgICAgICAgICAgICB9LCB0aGlzLCBbbWVtYmVyLnJlZl0pOwoJICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5ub2Rlcy5wdXNoKGJpbmRlcik7CgkgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnJlZkVsZW1zLmFkZEJpbmRlcihiaW5kZXIpOwoJICAgICAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoJICAgICAgICAgICAgfQoJICAgICAgICB9CgoJICAgICAgICB0b0ZlYXR1cmVBcnJheSgpIHsKCSAgICAgICAgICAgIGNvbnN0IGNvbnN0cnVjdFN0cmluZ0dlb21ldHJ5ID0gKHdzKSA9PiB7CgkgICAgICAgICAgICAgICAgbGV0IHN0cmluZ3MgPSB3cz8gd3MudG9TdHJpbmdzKCkgOiBbXTsKCSAgICAgICAgICAgICAgICBpZiAoc3RyaW5ncy5sZW5ndGggPiAwKSB7CgkgICAgICAgICAgICAgICAgICAgIGlmIChzdHJpbmdzLmxlbmd0aCA9PT0gMSkgcmV0dXJuIHsKCSAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdMaW5lU3RyaW5nJywKCSAgICAgICAgICAgICAgICAgICAgICAgIGNvb3JkaW5hdGVzOiBzdHJpbmdzWzBdCgkgICAgICAgICAgICAgICAgICAgIH0KCgkgICAgICAgICAgICAgICAgICAgIHJldHVybiB7CgkgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAnTXVsdGlMaW5lU3RyaW5nJywKCSAgICAgICAgICAgICAgICAgICAgICAgIGNvb3JkaW5hdGVzOiBzdHJpbmdzCgkgICAgICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICAgICAgcmV0dXJuIG51bGw7CgkgICAgICAgICAgICB9OwoKCSAgICAgICAgICAgIGNvbnN0IGNvbnN0cnVjdFBvbHlnb25HZW9tZXRyeSA9IChvd3MsIGl3cykgPT4gewoJICAgICAgICAgICAgICAgIGxldCBvdXRlclJpbmdzID0gb3dzPyBvd3MudG9SaW5ncygnY291bnRlcmNsb2Nrd2lzZScpIDogW10sCgkgICAgICAgICAgICAgICAgICAgIGlubmVyUmluZ3MgPSBpd3M/IGl3cy50b1JpbmdzKCdjbG9ja3dpc2UnKSA6IFtdOwoJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKCSAgICAgICAgICAgICAgICBpZiAob3V0ZXJSaW5ncy5sZW5ndGggPiAwKSB7CgkgICAgICAgICAgICAgICAgICAgIGxldCBjb21wb3NpdFBvbHlvbnMgPSBbXTsKCgkgICAgICAgICAgICAgICAgICAgIGxldCByaW5nID0gbnVsbDsKCSAgICAgICAgICAgICAgICAgICAgZm9yIChyaW5nIG9mIG91dGVyUmluZ3MpCgkgICAgICAgICAgICAgICAgICAgICAgICBjb21wb3NpdFBvbHlvbnMucHVzaChbcmluZ10pOwoJICAgICAgICAgICAgICAgICAgICAKCSAgICAgICAgICAgICAgICAgICAgLy8gbGluayBpbm5lciBwb2x5Z29ucyB0byBvdXRlciBjb250YWluZXJzCgkgICAgICAgICAgICAgICAgICAgIHdoaWxlIChyaW5nID0gaW5uZXJSaW5ncy5zaGlmdCgpKSB7CgkgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBpZHggaW4gb3V0ZXJSaW5ncykgewoJICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwdEluc2lkZVBvbHlnb24oZmlyc3QocmluZyksIG91dGVyUmluZ3NbaWR4XSkpIHsKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tcG9zaXRQb2x5b25zW2lkeF0ucHVzaChyaW5nKTsKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoJICAgICAgICAgICAgICAgICAgICAgICAgfQoJICAgICAgICAgICAgICAgICAgICB9CgoJICAgICAgICAgICAgICAgICAgICAvLyBjb25zdHJ1Y3QgdGhlIFBvbHlnb24vTXVsdGlQb2x5Z29uIGdlb21ldHJ5CgkgICAgICAgICAgICAgICAgICAgIGlmIChjb21wb3NpdFBvbHlvbnMubGVuZ3RoID09PSAxKSB7CgkgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gewoJICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdQb2x5Z29uJywKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb29yZGluYXRlczogY29tcG9zaXRQb2x5b25zWzBdCgkgICAgICAgICAgICAgICAgICAgICAgICB9OwoJICAgICAgICAgICAgICAgICAgICB9CgoJICAgICAgICAgICAgICAgICAgICByZXR1cm4gewoJICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ011bHRpUG9seWdvbicsCgkgICAgICAgICAgICAgICAgICAgICAgICBjb29yZGluYXRlczogY29tcG9zaXRQb2x5b25zCgkgICAgICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgICAgICB9CgoJICAgICAgICAgICAgICAgIHJldHVybiBudWxsOwoJICAgICAgICAgICAgfTsKCgkgICAgICAgICAgICBsZXQgcG9seWdvbkZlYXR1cmVzID0gW10sIHN0cmluZ0ZlYXR1cmVzID0gW10sIHBvaW50RmVhdHVyZXMgPSBbXTsKCSAgICAgICAgICAgIGNvbnN0IHdheXNGaWVsZE5hbWVzID0gWydvdXRlcicsICdpbm5lcicsICcnXTsKCSAgICAgICAgICAgIC8vIG5lZWQgdG8gZG8gY29tYmluYXRpb24gd2hlbiB0aGVyZSdyZSBuZXN0ZWQgcmVsYXRpb25zCgkgICAgICAgICAgICBmb3IgKGxldCByZWxhdGlvbiBvZiB0aGlzLnJlbGF0aW9ucykgewoJICAgICAgICAgICAgICAgIGlmIChyZWxhdGlvbikgewoJICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBmaWVsZE5hbWUgb2Ygd2F5c0ZpZWxkTmFtZXMpIHsKCSAgICAgICAgICAgICAgICAgICAgICAgIGxldCB3YXlzID0gcmVsYXRpb25bZmllbGROYW1lXTsKCSAgICAgICAgICAgICAgICAgICAgICAgIGlmICh3YXlzKSB7CgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IHRoaXNXYXlzID0gdGhpc1tmaWVsZE5hbWVdOwoJICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzV2F5cykgewoJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbXS5zcGxpY2UuYXBwbHkodGhpc1dheXMsIFt0aGlzV2F5cy5sZW5ndGgsIDBdLmNvbmNhdCh3YXlzKSk7CgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpc1tmaWVsZE5hbWVdID0gd2F5czsKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICB9CgoJICAgICAgICAgICAgZm9yIChsZXQgZmllbGROYW1lIG9mIHdheXNGaWVsZE5hbWVzKSB7CgkgICAgICAgICAgICAgICAgbGV0IHdheXMgPSB0aGlzW2ZpZWxkTmFtZV07CgkgICAgICAgICAgICAgICAgaWYgKHdheXMpIHsKCSAgICAgICAgICAgICAgICAgICAgdGhpc1tmaWVsZE5hbWVdID0gbmV3IFdheUNvbGxlY3Rpb24oKTsKCSAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgd2F5IG9mIHdheXMpIHsKCSAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNbZmllbGROYW1lXS5hZGRXYXkod2F5KTsKCSAgICAgICAgICAgICAgICAgICAgfQoJICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgIH0KCgkgICAgICAgICAgICBsZXQgZ2VvbWV0cnkgPSBudWxsOwoJICAgICAgICAgICAgCgkgICAgICAgICAgICBsZXQgZmVhdHVyZSA9IHsKCSAgICAgICAgICAgICAgICB0eXBlOiAnRmVhdHVyZScsCgkgICAgICAgICAgICAgICAgaWQ6IHRoaXMuZ2V0Q29tcG9zaXRlSWQoKSwKCSAgICAgICAgICAgICAgICBiYm94OiB0aGlzLmJvdW5kcywKCSAgICAgICAgICAgICAgICBwcm9wZXJ0aWVzOiB0aGlzLmdldFByb3BzKCkKCSAgICAgICAgICAgIH07CgoJICAgICAgICAgICAgaWYgKCF0aGlzLmJvdW5kcykgewoJICAgICAgICAgICAgICAgIGRlbGV0ZSBmZWF0dXJlLmJib3g7CgkgICAgICAgICAgICB9CgoJICAgICAgICAgICAgaWYgKHRoaXMub3V0ZXIpIHsKCSAgICAgICAgICAgICAgICBnZW9tZXRyeSA9IGNvbnN0cnVjdFBvbHlnb25HZW9tZXRyeSh0aGlzLm91dGVyLCB0aGlzLmlubmVyKTsKCSAgICAgICAgICAgICAgICBpZiAoZ2VvbWV0cnkpIHsKCSAgICAgICAgICAgICAgICAgICAgZmVhdHVyZS5nZW9tZXRyeSA9IGdlb21ldHJ5OwoJICAgICAgICAgICAgICAgICAgICBwb2x5Z29uRmVhdHVyZXMucHVzaChmZWF0dXJlKTsKCSAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICBlbHNlIGlmICh0aGlzWycnXSkgewoJICAgICAgICAgICAgICAgIGdlb21ldHJ5ID0gY29uc3RydWN0U3RyaW5nR2VvbWV0cnkodGhpc1snJ10pOwoJICAgICAgICAgICAgICAgIGlmIChnZW9tZXRyeSkgewoJICAgICAgICAgICAgICAgICAgICBmZWF0dXJlLmdlb21ldHJ5ID0gZ2VvbWV0cnk7CgkgICAgICAgICAgICAgICAgICAgIHN0cmluZ0ZlYXR1cmVzLnB1c2goZmVhdHVyZSk7CgkgICAgICAgICAgICAgICAgfQoJICAgICAgICAgICAgfQoKCSAgICAgICAgICAgIGZvciAobGV0IG5vZGUgb2YgdGhpcy5ub2RlcykgewoJICAgICAgICAgICAgICAgIHBvaW50RmVhdHVyZXMgPSBwb2ludEZlYXR1cmVzLmNvbmNhdChub2RlLnRvRmVhdHVyZUFycmF5KCkpOwoJICAgICAgICAgICAgfQoKCSAgICAgICAgICAgIHJldHVybiBwb2x5Z29uRmVhdHVyZXMuY29uY2F0KHN0cmluZ0ZlYXR1cmVzKS5jb25jYXQocG9pbnRGZWF0dXJlcyk7CgkgICAgICAgIH0KCSAgICB9CgoJICAgIHJldHVybiB7Tm9kZSwgV2F5LCBSZWxhdGlvbn07IAoJfSkoKTsKCgl2YXIgeG1scGFyc2VyID0gKCgpID0+IHsKCSAgICAKCSAgICBmdW5jdGlvbiBjb25kaXRpb25lZChldnQpIHsKCSAgICAgICAgcmV0dXJuIGV2dC5tYXRjaCgvXiguKz8pXFsoLis/KVxdPiQvZykgIT0gbnVsbDsKCSAgICB9CgoJICAgIGZ1bmN0aW9uIHBhcnNlRXZlbnQoZXZ0KSB7CgkgICAgICAgIGxldCBtYXRjaCA9IC9eKC4rPylcWyguKz8pXF0+JC9nLmV4ZWMoZXZ0KTsKCSAgICAgICAgaWYgKG1hdGNoKSB7CgkgICAgICAgICAgICByZXR1cm4ge2V2dDogbWF0Y2hbMV0gKyAnPicsIGV4cDogbWF0Y2hbMl19OwoJICAgICAgICB9CgkgICAgICAgIHJldHVybiB7ZXZ0OiBldnR9OwoJICAgIH0KCgkgICAgZnVuY3Rpb24gZ2VuQ29uZGl0aW9uRnVuYyhjb25kKSB7CgkgICAgICAgIGxldCBib2R5ID0gJ3JldHVybiAnICsgY29uZC5yZXBsYWNlKC8oXCQuKz8pKD89Wz0hLl0pL2csICdub2RlLiQmJykgKyAnOyc7CgkgICAgICAgIHJldHVybiBuZXcgRnVuY3Rpb24oJ25vZGUnLCBib2R5KTsKCSAgICB9CgoJICAgIHJldHVybiBjbGFzcyB7CgkgICAgICAgIGNvbnN0cnVjdG9yKG9wdHMpIHsKCSAgICAgICAgICAgIGlmIChvcHRzKSB7CgkgICAgICAgICAgICAgICAgdGhpcy5xdWVyeVBhcmVudCA9IG9wdHMucXVlcnlQYXJlbnQ/IHRydWUgOiBmYWxzZTsKCSAgICAgICAgICAgICAgICB0aGlzLnByb2dyZXNzaXZlID0gb3B0cy5wcm9ncmVzc2l2ZTsKCSAgICAgICAgICAgICAgICBpZiAodGhpcy5xdWVyeVBhcmVudCkgewoJICAgICAgICAgICAgICAgICAgICB0aGlzLnBhcmVudE1hcCA9IG5ldyBXZWFrTWFwKCk7CgkgICAgICAgICAgICAgICAgfQoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgdGhpcy5ldnRMaXN0ZW5lcnMgPSB7fTsKCSAgICAgICAgfQoKCSAgICAgICAgcGFyc2UoeG1sLCBwYXJlbnQsIGRpcikgewoJICAgICAgICAgICAgZGlyID0gZGlyPyBkaXIgKyAnLicgOiAnJzsKCSAgICAgICAgICAgIGxldCBub2RlUmVnRXggPSAvPChbXiA+XC9dKykoLio/KT4vbWcsIG5vZGVNYXRjaCA9IG51bGwsIG5vZGVzID0gW107CgkgICAgICAgICAgICB3aGlsZSAobm9kZU1hdGNoID0gbm9kZVJlZ0V4LmV4ZWMoeG1sKSkgewoJICAgICAgICAgICAgICAgIGxldCB0YWcgPSBub2RlTWF0Y2hbMV0sIG5vZGUgPSB7JHRhZzogdGFnfSwgZnVsbFRhZyA9IGRpciArIHRhZzsgCgoJICAgICAgICAgICAgICAgIGxldCBhdHRyVGV4dCA9IG5vZGVNYXRjaFsyXS50cmltKCksIGNsb3NlZCA9IGZhbHNlOwoJICAgICAgICAgICAgICAgIGlmIChhdHRyVGV4dC5lbmRzV2l0aCgnLycpIHx8IHRhZy5zdGFydHNXaXRoKCc/JykgfHwgdGFnLnN0YXJ0c1dpdGgoJyEnKSkgewoJICAgICAgICAgICAgICAgICAgICBjbG9zZWQgPSB0cnVlOwoJICAgICAgICAgICAgICAgIH0KCgkgICAgICAgICAgICAgICAgbGV0IGF0dFJlZ0V4MSA9IC8oW14gXSs/KT0iKC4rPykiL2csIGF0dFJlZ0V4MiA9IC8oW14gXSs/KT0nKC4rPyknL2c7CgkgICAgICAgICAgICAgICAgbGV0IGF0dE1hdGNoID0gbnVsbCwgaGFzQXR0cnMgPSBmYWxzZTsKCSAgICAgICAgICAgICAgICB3aGlsZSAoYXR0TWF0Y2ggPSBhdHRSZWdFeDEuZXhlYyhhdHRyVGV4dCkpIHsKCSAgICAgICAgICAgICAgICAgICAgaGFzQXR0cnMgPSB0cnVlOwoJICAgICAgICAgICAgICAgICAgICBub2RlW2F0dE1hdGNoWzFdXSA9IGF0dE1hdGNoWzJdOwoJICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgICAgICBpZiAoIWhhc0F0dHJzKQoJICAgICAgICAgICAgICAgICAgICB3aGlsZSAoYXR0TWF0Y2ggPSBhdHRSZWdFeDIuZXhlYyhhdHRyVGV4dCkpIHsKCSAgICAgICAgICAgICAgICAgICAgICAgIGhhc0F0dHJzID0gdHJ1ZTsKCSAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVbYXR0TWF0Y2hbMV1dID0gYXR0TWF0Y2hbMl07CgkgICAgICAgICAgICAgICAgICAgIH0KCgkgICAgICAgICAgICAgICAgaWYgKCFoYXNBdHRycyAmJiBhdHRyVGV4dCAhPT0gJycpIHsKCSAgICAgICAgICAgICAgICAgICAgbm9kZS50ZXh0ID0gYXR0clRleHQ7CgkgICAgICAgICAgICAgICAgfQoJICAgICAgICAgICAgICAgIGlmICh0aGlzLnByb2dyZXNzaXZlKSB7CgkgICAgICAgICAgICAgICAgICAgIHRoaXMuZW1pdChgPCR7ZnVsbFRhZ30+YCwgbm9kZSwgcGFyZW50KTsKCSAgICAgICAgICAgICAgICB9CgoJICAgICAgICAgICAgICAgIGlmICghY2xvc2VkKSB7CgkgICAgICAgICAgICAgICAgICAgIGxldCBpbm5lclJlZ0V4ID0gbmV3IFJlZ0V4cChgKFteXSs/KTxcLyR7dGFnfT5gLCAnZycpOwoJICAgICAgICAgICAgICAgICAgICBpbm5lclJlZ0V4Lmxhc3RJbmRleCA9IG5vZGVSZWdFeC5sYXN0SW5kZXg7CgkgICAgICAgICAgICAgICAgICAgIGxldCBpbm5lck1hdGNoID0gaW5uZXJSZWdFeC5leGVjKHhtbCk7CgkgICAgICAgICAgICAgICAgICAgIGlmIChpbm5lck1hdGNoICYmIGlubmVyTWF0Y2hbMV0pIHsKCSAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVSZWdFeC5sYXN0SW5kZXggPSBpbm5lclJlZ0V4Lmxhc3RJbmRleDsKCSAgICAgICAgICAgICAgICAgICAgICAgIGxldCBpbm5lck5vZGVzID0gdGhpcy5wYXJzZShpbm5lck1hdGNoWzFdLCBub2RlLCBmdWxsVGFnKTsKCSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbm5lck5vZGVzLmxlbmd0aCA+IDApIHsKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlLiRpbm5lck5vZGVzID0gaW5uZXJOb2RlczsKCSAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZS4kaW5uZXJUZXh0ID0gaW5uZXJNYXRjaFsxXTsKCSAgICAgICAgICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgICAgICAgICAgfQoJICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgICAgICBpZiAodGhpcy5xdWVyeVBhcmVudCAmJiBwYXJlbnQpIHsKCSAgICAgICAgICAgICAgICAgICAgdGhpcy5wYXJlbnRNYXAuc2V0KG5vZGUsIHBhcmVudCk7CgkgICAgICAgICAgICAgICAgfQoKCSAgICAgICAgICAgICAgICBpZiAodGhpcy5wcm9ncmVzc2l2ZSkgewoJICAgICAgICAgICAgICAgICAgICB0aGlzLmVtaXQoYDwvJHtmdWxsVGFnfT5gLCBub2RlLCBwYXJlbnQpOwoJICAgICAgICAgICAgICAgIH0KCgkgICAgICAgICAgICAgICAgbm9kZXMucHVzaChub2RlKTsKCSAgICAgICAgICAgIH0KCgkgICAgICAgICAgICByZXR1cm4gbm9kZXM7CgkgICAgICAgIH0KCgkgICAgICAgIGdldFBhcmVudChub2RlKSB7CgkgICAgICAgICAgICBpZiAodGhpcy5xdWVyeVBhcmVudCkgewoJICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnBhcmVudE1hcC5nZXQobm9kZSk7CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICByZXR1cm4gbnVsbDsKCSAgICAgICAgfQoKCSAgICAgICAgJGFkZExpc3RlbmVyKGV2dCwgZnVuYykgewoJICAgICAgICAgICAgbGV0IGZ1bmNzID0gdGhpcy5ldnRMaXN0ZW5lcnNbZXZ0XTsKCSAgICAgICAgICAgIGlmIChmdW5jcykgewoJICAgICAgICAgICAgICAgIGZ1bmNzLnB1c2goZnVuYyk7CgkgICAgICAgICAgICB9IGVsc2UgewoJICAgICAgICAgICAgICAgIHRoaXMuZXZ0TGlzdGVuZXJzW2V2dF0gPSBbZnVuY107CgkgICAgICAgICAgICB9CgkgICAgICAgIH0KCgkgICAgICAgIC8vIHN1cHBvcnQgamF2YXNjcmlwdCBjb25kaXRpb24gZm9yIHRoZSBsYXN0IHRhZwoJICAgICAgICBhZGRMaXN0ZW5lcihldnQsIGZ1bmMpIHsKCSAgICAgICAgICAgIGlmIChjb25kaXRpb25lZChldnQpKSB7CgkgICAgICAgICAgICAgICAgLy8gZnVuYy5wcm90b3R5cGUgPSBldnQ7CgkgICAgICAgICAgICAgICAgZXZ0ID0gcGFyc2VFdmVudChldnQpOyAgICAKCSAgICAgICAgICAgICAgICBmdW5jLmNvbmRpdGlvbiA9IGdlbkNvbmRpdGlvbkZ1bmMoZXZ0LmV4cCk7CgkgICAgICAgICAgICAgICAgZXZ0ID0gZXZ0LmV2dDsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIHRoaXMuJGFkZExpc3RlbmVyKGV2dCwgZnVuYyk7CgkgICAgICAgIH0KCgkgICAgICAgICRyZW1vdmVMaXN0ZW5lcihldnQsIGZ1bmMpIHsKCSAgICAgICAgICAgIGxldCBmdW5jcyA9IHRoaXMuZXZ0TGlzdGVuZXJzW2V2dF07CgkgICAgICAgICAgICBsZXQgaWR4ID0gbnVsbDsKCSAgICAgICAgICAgIGlmIChmdW5jcyAmJiAoaWR4ID0gZnVuY3MuaW5kZXhPZihmdW5jKSkgPj0gMCkgewoJICAgICAgICAgICAgICAgIGZ1bmNzLnNwbGljZShpZHgsIDEpOwoJICAgICAgICAgICAgfQoJICAgICAgICB9CgoJICAgICAgICByZW1vdmVMaXN0ZW5lcihldnQsIGZ1bmMpIHsKCSAgICAgICAgICAgIGlmIChjb25kaXRpb25lZChldnQpKSB7CgkgICAgICAgICAgICAgICAgZXZ0ID0gcGFyc2VFdmVudChldnQpOyAgICAKCSAgICAgICAgICAgICAgICBldnQgPSBldnQuZXZ0OwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgdGhpcy4kcmVtb3ZlTGlzdGVuZXIoZXZ0LCBmdW5jKTsKCSAgICAgICAgfQoKCSAgICAgICAgZW1pdChldnQsIC4uLmFyZ3MpIHsKCSAgICAgICAgICAgIGxldCBmdW5jcyA9IHRoaXMuZXZ0TGlzdGVuZXJzW2V2dF07CgkgICAgICAgICAgICBpZiAoZnVuY3MpIHsKCSAgICAgICAgICAgICAgICBmb3IgKGxldCBmdW5jIG9mIGZ1bmNzKSB7CgkgICAgICAgICAgICAgICAgICAgIGlmIChmdW5jLmNvbmRpdGlvbikgewoJICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZ1bmMuY29uZGl0aW9uLmFwcGx5KG51bGwsIGFyZ3MpID09PSB0cnVlKSB7CgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnVuYy5hcHBseShudWxsLCBhcmdzKTsKCSAgICAgICAgICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKCSAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmMuYXBwbHkobnVsbCwgYXJncyk7CgkgICAgICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICB9CgkgICAgICAgIH0KCgkgICAgICAgIG9uKGV2dCwgZnVuYykgewoJICAgICAgICAgICAgdGhpcy5hZGRMaXN0ZW5lcihldnQsIGZ1bmMpOwoJICAgICAgICB9CgoJICAgICAgICBvZmYoZXZ0LCBmdW5jKSB7CgkgICAgICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKGV2dCwgZnVuYyk7CgkgICAgICAgIH0KCSAgICB9OwoJfSkoKTsKCgljb25zdCB7Tm9kZSwgV2F5LCBSZWxhdGlvbn0gPSBvc21vYmpzLAoJICAgIHtwdXJnZVByb3BzLCBSZWZFbGVtZW50c30gPSB1dGlscywKCSAgICBYbWxQYXJzZXIgPSB4bWxwYXJzZXI7CgoJdmFyIGxpYiA9IChvc20sIG9wdHMpID0+IHsKCSAgICBsZXQgY29tcGxldGVGZWF0dXJlID0gZmFsc2UsIHJlbmRlclRhZ2dlZCA9IGZhbHNlLCBleGNsdWRlV2F5ID0gdHJ1ZTsKCgkgICAgY29uc3QgcGFyc2VPcHRzID0gb3B0cyA9PiB7CgkgICAgICAgIGlmIChvcHRzKSB7CgkgICAgICAgICAgICBjb21wbGV0ZUZlYXR1cmUgPSBvcHRzLmNvbXBsZXRlRmVhdHVyZSB8fCBvcHRzLmFsbEZlYXR1cmVzPyB0cnVlIDogZmFsc2U7CgkgICAgICAgICAgICByZW5kZXJUYWdnZWQgPSBvcHRzLnJlbmRlclRhZ2dlZD8gdHJ1ZSA6IGZhbHNlOwoJICAgICAgICAgICAgbGV0IHdheU9wdCA9IG9wdHMuc3VwcHJlc3NXYXkgfHwgb3B0cy5leGNsdWRlV2F5OwoJICAgICAgICAgICAgaWYgKHdheU9wdCAhPT0gdW5kZWZpbmVkICYmICF3YXlPcHQpIHsKCSAgICAgICAgICAgICAgICBleGNsdWRlV2F5ID0gZmFsc2U7CgkgICAgICAgICAgICB9CgkgICAgICAgIH0KCSAgICB9OwoKCSAgICBwYXJzZU9wdHMob3B0cyk7CgoJICAgIGNvbnN0IGRldGVjdEZvcm1hdCA9IG9zbSA9PiB7CgkgICAgICAgIGlmIChvc20uZWxlbWVudHMpIHsKCSAgICAgICAgICAgIHJldHVybiAnanNvbic7CgkgICAgICAgIH0KCSAgICAgICAgaWYgKG9zbS5pbmRleE9mKCc8b3NtJykgPj0gMCkgewoJICAgICAgICAgICAgcmV0dXJuICd4bWwnOwoJICAgICAgICB9CgkgICAgICAgIGlmIChvc20udHJpbSgpLnN0YXJ0c1dpdGgoJ3snKSkgewoJICAgICAgICAgICAgcmV0dXJuICdqc29uLXJhdyc7CgkgICAgICAgIH0KCSAgICAgICAgcmV0dXJuICdpbnZhbGlkJzsKCSAgICB9OwoKCSAgICBsZXQgZm9ybWF0ID0gZGV0ZWN0Rm9ybWF0KG9zbSk7CgoJICAgIGxldCByZWZFbGVtZW50cyA9IG5ldyBSZWZFbGVtZW50cygpLCBmZWF0dXJlQXJyYXkgPSBbXTsKCgkgICAgY29uc3QgYW5hbHl6ZUZlYXR1cmVzRnJvbUpzb24gPSBvc20gPT4gewoJICAgICAgICBmb3IgKGxldCBlbGVtIG9mIG9zbS5lbGVtZW50cykgewoJICAgICAgICAgICAgc3dpdGNoKGVsZW0udHlwZSkgewoJICAgICAgICAgICAgICAgIGNhc2UgJ25vZGUnOgoJICAgICAgICAgICAgICAgICAgICBsZXQgbm9kZSA9IG5ldyBOb2RlKGVsZW0uaWQsIHJlZkVsZW1lbnRzKTsKCSAgICAgICAgICAgICAgICAgICAgaWYgKGVsZW0udGFncykgewoJICAgICAgICAgICAgICAgICAgICAgICAgbm9kZS5hZGRUYWdzKGVsZW0udGFncyk7CgkgICAgICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgICAgICAgICAgbm9kZS5hZGRQcm9wcyhwdXJnZVByb3BzKGVsZW0sIFsnaWQnLCAndHlwZScsICd0YWdzJywgJ2xhdCcsICdsb24nXSkpOwoJICAgICAgICAgICAgICAgICAgICBub2RlLnNldExhdExuZyhlbGVtKTsKCSAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgoJICAgICAgICAgICAgICAgIGNhc2UgJ3dheSc6CgkgICAgICAgICAgICAgICAgICAgIGxldCB3YXkgPSBuZXcgV2F5KGVsZW0uaWQsIHJlZkVsZW1lbnRzKTsKCSAgICAgICAgICAgICAgICAgICAgaWYgKGVsZW0udGFncykgewoJICAgICAgICAgICAgICAgICAgICAgICAgd2F5LmFkZFRhZ3MoZWxlbS50YWdzKTsKCSAgICAgICAgICAgICAgICAgICAgfQoJICAgICAgICAgICAgICAgICAgICB3YXkuYWRkUHJvcHMocHVyZ2VQcm9wcyhlbGVtLCBbJ2lkJywgJ3R5cGUnLCAndGFncycsICdub2RlcycsICdnZW9tZXRyeSddKSk7CgkgICAgICAgICAgICAgICAgICAgIGlmIChlbGVtLm5vZGVzKSB7CgkgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBuIG9mIGVsZW0ubm9kZXMpIHsKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICB3YXkuYWRkTm9kZVJlZihuKTsKCSAgICAgICAgICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChlbGVtLmdlb21ldHJ5KSB7CgkgICAgICAgICAgICAgICAgICAgICAgICB3YXkuc2V0TGF0TG5nQXJyYXkoZWxlbS5nZW9tZXRyeSk7CgkgICAgICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgoJICAgICAgICAgICAgICAgIGNhc2UgJ3JlbGF0aW9uJzoKCSAgICAgICAgICAgICAgICAgICAgbGV0IHJlbGF0aW9uID0gbmV3IFJlbGF0aW9uKGVsZW0uaWQsIHJlZkVsZW1lbnRzKTsKCSAgICAgICAgICAgICAgICAgICAgICBpZiAoZWxlbS5ib3VuZHMpIHsKCSAgICAgICAgICAgICAgICAgICAgICAgIHJlbGF0aW9uLnNldEJvdW5kcyhbcGFyc2VGbG9hdChlbGVtLmJvdW5kcy5taW5sb24pLCBwYXJzZUZsb2F0KGVsZW0uYm91bmRzLm1pbmxhdCksIHBhcnNlRmxvYXQoZWxlbS5ib3VuZHMubWF4bG9uKSwgcGFyc2VGbG9hdChlbGVtLmJvdW5kcy5tYXhsYXQpXSk7CgkgICAgICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgICAgICAgICAgaWYgKGVsZW0udGFncykgewoJICAgICAgICAgICAgICAgICAgICAgICAgcmVsYXRpb24uYWRkVGFncyhlbGVtLnRhZ3MpOwoJICAgICAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICAgICAgICAgIHJlbGF0aW9uLmFkZFByb3BzKHB1cmdlUHJvcHMoZWxlbSwgWydpZCcsICd0eXBlJywgJ3RhZ3MnLCAnYm91bmRzJywgJ21lbWJlcnMnXSkpOwoJICAgICAgICAgICAgICAgICAgICBpZiAoZWxlbS5tZW1iZXJzKSB7CgkgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxldCBtZW1iZXIgb2YgZWxlbS5tZW1iZXJzKSB7CgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVsYXRpb24uYWRkTWVtYmVyKG1lbWJlcik7CgkgICAgICAgICAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgkgICAgICAgICAgICB9CgkgICAgICAgIH0KCSAgICB9OwoKCSAgICBjb25zdCBhbmFseXplRmVhdHVyZXNGcm9tWG1sID0gb3NtID0+IHsKCSAgICAgICAgY29uc3QgeG1sUGFyc2VyID0gbmV3IFhtbFBhcnNlcih7cHJvZ3Jlc3NpdmU6IHRydWV9KTsKCgkgICAgICAgIHhtbFBhcnNlci5vbignPC9vc20ubm9kZT4nLCBub2RlID0+IHsKCSAgICAgICAgICAgIGxldCBuZCA9IG5ldyBOb2RlKG5vZGUuaWQsIHJlZkVsZW1lbnRzKTsKCSAgICAgICAgICAgIGZvciAobGV0IFtrLCB2XSBvZiBPYmplY3QuZW50cmllcyhub2RlKSkKCSAgICAgICAgICAgICAgICBpZiAoIWsuc3RhcnRzV2l0aCgnJCcpICYmIFsnaWQnLCAnbG9uJywgJ2xhdCddLmluZGV4T2YoaykgPCAwKSB7CgkgICAgICAgICAgICAgICAgICAgIG5kLmFkZFByb3Aoaywgdik7CgkgICAgICAgICAgICAgICAgfQoJICAgICAgICAgICAgbmQuc2V0TGF0TG5nKG5vZGUpOwoJICAgICAgICAgICAgaWYgKG5vZGUuJGlubmVyTm9kZXMpIHsKCSAgICAgICAgICAgICAgICBmb3IgKGxldCBpbmQgb2Ygbm9kZS4kaW5uZXJOb2RlcykgewoJICAgICAgICAgICAgICAgICAgICBpZihpbmQuJHRhZyA9PT0gJ3RhZycpIHsKCSAgICAgICAgICAgICAgICAgICAgICAgIG5kLmFkZFRhZyhpbmQuaywgaW5kLnYpOwoJICAgICAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICAgICAgfQoJICAgICAgICAgICAgfQoJICAgICAgICB9KTsKCgkgICAgICAgIHhtbFBhcnNlci5vbignPC9vc20ud2F5PicsIG5vZGUgPT4gewoJICAgICAgICAgICAgbGV0IHdheSA9IG5ldyBXYXkobm9kZS5pZCwgcmVmRWxlbWVudHMpOwoJICAgICAgICAgICAgZm9yIChsZXQgW2ssIHZdIG9mIE9iamVjdC5lbnRyaWVzKG5vZGUpKSB7CgkgICAgICAgICAgICAgICAgaWYgKCFrLnN0YXJ0c1dpdGgoJyQnKSAmJiBbJ2lkJ10uaW5kZXhPZihrKSA8IDApIHsKCSAgICAgICAgICAgICAgICAgICAgd2F5LmFkZFByb3Aoaywgdik7CgkgICAgICAgICAgICAgICAgfQoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgaWYgKG5vZGUuJGlubmVyTm9kZXMpIHsKCSAgICAgICAgICAgICAgICBmb3IgKGxldCBpbmQgb2Ygbm9kZS4kaW5uZXJOb2RlcykgewoJICAgICAgICAgICAgICAgICAgICBpZiAoaW5kLiR0YWcgPT09ICduZCcpIHsKCSAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbmQubG9uICYmIGluZC5sYXQpIHsKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICB3YXkuYWRkTGF0TG5nKGluZCk7CgkgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGluZC5yZWYpIHsKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICB3YXkuYWRkTm9kZVJlZihpbmQucmVmKTsKCSAgICAgICAgICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChpbmQuJHRhZyA9PT0gJ3RhZycpCgkgICAgICAgICAgICAgICAgICAgICAgICB3YXkuYWRkVGFnKGluZC5rLCBpbmQudik7CgkgICAgICAgICAgICAgICAgfQoJICAgICAgICAgICAgfQoJICAgICAgICB9KTsKCgkgICAgICAgIHhtbFBhcnNlci5vbignPG9zbS5yZWxhdGlvbj4nLCBub2RlID0+IHsKCSAgICAgICAgICAgIG5ldyBSZWxhdGlvbihub2RlLmlkLCByZWZFbGVtZW50cyk7CgkgICAgICAgIH0pOwoKCSAgICAgICAgeG1sUGFyc2VyLm9uKCc8L29zbS5yZWxhdGlvbi5tZW1iZXI+JywgKG5vZGUsIHBhcmVudCkgPT4gewoJICAgICAgICAgICAgbGV0IHJlbGF0aW9uID0gcmVmRWxlbWVudHMuZ2V0KGByZWxhdGlvbi8ke3BhcmVudC5pZH1gKTsKCSAgICAgICAgICAgIGxldCBtZW1iZXIgPSB7CgkgICAgICAgICAgICAgICAgdHlwZTogbm9kZS50eXBlLAoJICAgICAgICAgICAgICAgIHJvbGU6IG5vZGUucm9sZT8gbm9kZS5yb2xlIDogJycsCgkgICAgICAgICAgICAgICAgcmVmOiBub2RlLnJlZgoJICAgICAgICAgICAgfTsKCSAgICAgICAgICAgIGlmIChub2RlLmxhdCAmJiBub2RlLmxvbikgewoJICAgICAgICAgICAgICAgIG1lbWJlci5sYXQgPSBub2RlLmxhdCwgbWVtYmVyLmxvbiA9IG5vZGUubG9uLCBtZW1iZXIudGFncyA9IHt9OwoJICAgICAgICAgICAgICAgIGZvciAobGV0IFtrLCB2XSBvZiBPYmplY3QuZW50cmllcyhub2RlKSkgewoJICAgICAgICAgICAgICAgICAgICBpZiAoIWsuc3RhcnRzV2l0aCgnJCcpICYmIFsndHlwZScsICdsYXQnLCAnbG9uJ10uaW5kZXhPZihrKSA8IDApIHsKCSAgICAgICAgICAgICAgICAgICAgICAgIG1lbWJlcltrXSA9IHY7CgkgICAgICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICBpZiAobm9kZS4kaW5uZXJOb2RlcykgewoJICAgICAgICAgICAgICAgIGxldCBnZW9tZXRyeSA9IFtdOwoJICAgICAgICAgICAgICAgIGxldCBub2RlcyA9IFtdOwoJICAgICAgICAgICAgICAgIGZvciAobGV0IGluZCBvZiBub2RlLiRpbm5lck5vZGVzKSB7CgkgICAgICAgICAgICAgICAgICAgIGlmIChpbmQubGF0ICYmIGluZC5sb24pIHsKCSAgICAgICAgICAgICAgICAgICAgICAgIGdlb21ldHJ5LnB1c2goaW5kKTsKCSAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKCSAgICAgICAgICAgICAgICAgICAgICAgIG5vZGVzLnB1c2goaW5kLnJlZik7CgkgICAgICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICAgICAgaWYgKGdlb21ldHJ5Lmxlbmd0aCA+IDApIHsKCSAgICAgICAgICAgICAgICAgICAgbWVtYmVyLmdlb21ldHJ5ID0gZ2VvbWV0cnk7CgkgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChub2Rlcy5sZW5ndGggPiAwKSB7CgkgICAgICAgICAgICAgICAgICAgIG1lbWJlci5ub2RlcyA9IG5vZGVzOwoJICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIHJlbGF0aW9uLmFkZE1lbWJlcihtZW1iZXIpOwoJICAgICAgICB9KTsKCgkgICAgICAgIHhtbFBhcnNlci5vbignPC9vc20ucmVsYXRpb24uYm91bmRzPicsIChub2RlLCBwYXJlbnQpID0+IHsKCSAgICAgICAgICAgIHJlZkVsZW1lbnRzLmdldChgcmVsYXRpb24vJHtwYXJlbnQuaWR9YCkuc2V0Qm91bmRzKFtwYXJzZUZsb2F0KG5vZGUubWlubG9uKSwgcGFyc2VGbG9hdChub2RlLm1pbmxhdCksIHBhcnNlRmxvYXQobm9kZS5tYXhsb24pLCBwYXJzZUZsb2F0KG5vZGUubWF4bGF0KV0pOwoJICAgICAgICB9KTsKCgkgICAgICAgIHhtbFBhcnNlci5vbignPC9vc20ucmVsYXRpb24udGFnPicsIChub2RlLCBwYXJlbnQpID0+IHsKCSAgICAgICAgICAgIHJlZkVsZW1lbnRzLmdldChgcmVsYXRpb24vJHtwYXJlbnQuaWR9YCkuYWRkVGFnKG5vZGUuaywgbm9kZS52KTsKCSAgICAgICAgfSk7CgkgICAgICAgIAoJICAgICAgICB4bWxQYXJzZXIucGFyc2Uob3NtKTsKCSAgICB9OwoKCSAgICBpZiAoZm9ybWF0ID09PSAnanNvbi1yYXcnKSB7CgkgICAgICAgIG9zbSA9IEpTT04ucGFyc2Uob3NtKTsKCSAgICAgICAgaWYgKG9zbS5lbGVtZW50cykgewoJICAgICAgICAgICAgZm9ybWF0ID0gJ2pzb24nOwoJICAgICAgICB9IGVsc2UgewoJICAgICAgICAgICAgZm9ybWF0ID0gJ2ludmFsaWQnOwoJICAgICAgICB9CgkgICAgfQoKCSAgICBpZiAoZm9ybWF0ID09PSAnanNvbicpIHsKCSAgICAgICAgYW5hbHl6ZUZlYXR1cmVzRnJvbUpzb24ob3NtKTsKCSAgICB9IGVsc2UgaWYgKGZvcm1hdCA9PT0gJ3htbCcpIHsKCSAgICAgICAgYW5hbHl6ZUZlYXR1cmVzRnJvbVhtbChvc20pOwoJICAgIH0KCgkgICAgcmVmRWxlbWVudHMuYmluZEFsbCgpOwoKCSAgICBmb3IgKGxldCB2IG9mIHJlZkVsZW1lbnRzLnZhbHVlcygpKSB7CgkgICAgICAgIGlmICh2LnJlZkNvdW50IDw9IDAgfHwgKHYuaGFzVGFnICYmIHJlbmRlclRhZ2dlZCAmJiAhKHYgaW5zdGFuY2VvZiBXYXkgJiYgZXhjbHVkZVdheSkpKSB7CgkgICAgICAgICAgICBsZXQgZmVhdHVyZXMgPSB2LnRvRmVhdHVyZUFycmF5KCk7CgkgICAgICAgICAgICAvLyByZXR1cm4gdGhlIGZpcnN0IGdlb21ldHJ5IG9mIHRoZSBmaXJzdCByZWxhdGlvbiBlbGVtZW50CgkgICAgICAgICAgICBpZiAodiBpbnN0YW5jZW9mIFJlbGF0aW9uICYmICFjb21wbGV0ZUZlYXR1cmUgJiYgZmVhdHVyZXMubGVuZ3RoID4gMCkgewoJICAgICAgICAgICAgICAgIHJldHVybiBmZWF0dXJlc1swXS5nZW9tZXRyeTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIGZlYXR1cmVBcnJheSA9IGZlYXR1cmVBcnJheS5jb25jYXQoZmVhdHVyZXMpOwoJICAgICAgICB9CgkgICAgfQoKCSAgICByZXR1cm4ge3R5cGU6ICdGZWF0dXJlQ29sbGVjdGlvbicsIGZlYXR1cmVzOiBmZWF0dXJlQXJyYXl9OwoJfTsKCgl2YXIgb3NtMmdlb2pzb24gPSAvKkBfX1BVUkVfXyovZ2V0RGVmYXVsdEV4cG9ydEZyb21DanMobGliKTsKCgljbGFzcyBDb252ZXJ0ZXIgewoJICAgIGNvbnN0cnVjdG9yKGZvcm1hdCwgZGF0YSkgewoJICAgICAgICAvKioKCSAgICAgICAgICogQ3JlYXRlcyBhIGJsYW5rIEdlb0pTT04gZmVhdHVyZSBjb2xsZWN0aW9uLgoJICAgICAgICAgKiBAcmV0dXJucyBBIG5ldyBHZW9KU09OIGZlYXR1cmUgY29sbGVjdGlvbiB3aXRoIG5vIGZlYXR1cmVzLgoJICAgICAgICAgKi8KCSAgICAgICAgdGhpcy5ibGFua0dlb0pTT04gPSAoKSA9PiAoewoJICAgICAgICAgICAgdHlwZTogJ0ZlYXR1cmVDb2xsZWN0aW9uJywKCSAgICAgICAgICAgIGZlYXR1cmVzOiBbXSwKCSAgICAgICAgfSk7CgkgICAgICAgIHRoaXMuX3Jhd0RhdGEgPSBkYXRhOwoJICAgICAgICB0aGlzLl9mb3JtYXQgPSBmb3JtYXQ7CgkgICAgICAgIGNvbnN0IGNvbnZlcnRlcnMgPSB7CgkgICAgICAgICAgICAndG9wb2pzb24nOiB0aGlzLmxvYWRUb3BvSnNvbiwKCSAgICAgICAgICAgICdvc20nOiB0aGlzLmxvYWRPc20sCgkgICAgICAgICAgICAna21sJzogdGhpcy5sb2FkWG1sLAoJICAgICAgICAgICAgJ2dweCc6IHRoaXMubG9hZFhtbCwKCSAgICAgICAgICAgICd0Y3gnOiB0aGlzLmxvYWRYbWwsCgkgICAgICAgICAgICAnY3N2JzogdGhpcy5sb2FkQ3N2LAoJICAgICAgICAgICAgJ3Rzdic6IHRoaXMubG9hZENzdgoJICAgICAgICB9OwoJICAgICAgICB0aGlzLl9jb252ZXJzaW9uRm4gPSBjb252ZXJ0ZXJzW2Zvcm1hdF07CgkgICAgfQoJICAgIGFzeW5jIGNvbnZlcnQoKSB7CgkgICAgICAgIGlmICghdGhpcy5fY29udmVyc2lvbkZuKSB7CgkgICAgICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKF8sIHJlaikgPT4gcmVqKGBObyBjb252ZXJ0ZXIgZXhpc3RzIGZvciAke3RoaXMuX2Zvcm1hdH1gKSk7CgkgICAgICAgIH0KCSAgICAgICAgZWxzZSB7CgkgICAgICAgICAgICByZXR1cm4gdGhpcy5fY29udmVyc2lvbkZuKCk7CgkgICAgICAgIH0KCSAgICB9CgkgICAgLyoqCgkgICAgICogTG9hZCB0aGUgWE1MIGRhdGEgYXMgR2VvSlNPTgoJICAgICAqIEByZXR1cm5zIEEgcHJvbWlzZSByZXNvbHZpbmcgdG8gYSBHZW9KU09OIEZlYXR1cmVDb2xsZWN0aW9uCgkgICAgICovCgkgICAgYXN5bmMgbG9hZFhtbCgpIHsKCSAgICAgICAgLy8gVXNlIHRoZSBhcHByb3ByaWF0ZSBwYXJzZXIgYmFzZWQgb24gdGhlIGZvcm1hdAoJICAgICAgICBjb25zdCBnZW9qc29uID0gdG9HZW9Kc29uW3RoaXMuX2Zvcm1hdF0obmV3IERPTVBhcnNlcigpLnBhcnNlRnJvbVN0cmluZyh0aGlzLl9yYXdEYXRhLCAidGV4dC94bWwiKSk7CgkgICAgICAgIHJldHVybiBnZW9qc29uOwoJICAgIH0KCSAgICAvKioKCSAgICAgKiBMb2FkcyBhbmQgcGFyc2VzIENTViBkYXRhIGludG8gYSBHZW9KU09OIEZlYXR1cmVDb2xsZWN0aW9uLgoJICAgICAqIEByZXR1cm5zIEEgUHJvbWlzZSB0aGF0IHJlc29sdmVzIHdpdGggdGhlIEdlb0pTT04gRmVhdHVyZUNvbGxlY3Rpb24uCgkgICAgICovCgkgICAgYXN5bmMgbG9hZENzdigpIHsKCSAgICAgICAgLy8gRGVmaW5lIG9wdGlvbnMgZm9yIHRoZSBjc3YyZ2VvanNvbiBsaWJyYXJ5CgkgICAgICAgIGxldCBvcHRpb25zID0ge307IC8vIFRPRE8gYWxsb3cgQ1NWIG9wdGlvbnMKCSAgICAgICAgaWYgKHRoaXMuX2Zvcm1hdCA9PT0gJ3RzdicpIHsKCSAgICAgICAgICAgIG9wdGlvbnMuZGVsaW1pdGVyID0gJ1x0JzsKCSAgICAgICAgfQoJICAgICAgICAvLyBVc2UgdGhlIGNzdjJnZW9qc29uIGxpYnJhcnkgdG8gY29udmVydCB0aGUgQ1NWIHRvIEdlb0pTT04KCSAgICAgICAgY29uc3QgZ2VvanNvbiA9IGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHsKCSAgICAgICAgICAgIGNzdjJnZW9qc29uXzEuY3N2Mmdlb2pzb24odGhpcy5fcmF3RGF0YSwgb3B0aW9ucywgKGVyciwgZGF0YSkgPT4gewoJICAgICAgICAgICAgICAgIGlmIChlcnIpIHsKCSAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGVycik7CgkgICAgICAgICAgICAgICAgfQoJICAgICAgICAgICAgICAgIGVsc2UgewoJICAgICAgICAgICAgICAgICAgICByZXNvbHZlKGRhdGEpOwoJICAgICAgICAgICAgICAgIH0KCSAgICAgICAgICAgIH0pOwoJICAgICAgICB9KTsKCSAgICAgICAgcmV0dXJuIGdlb2pzb247CgkgICAgfQoJICAgIC8qKgoJICAgICAqIExvYWRzIFRvcG9KU09OIGRhdGEgYW5kIGNvbnZlcnRzIGl0IGludG8gYSBHZW9KU09OIEZlYXR1cmVDb2xsZWN0aW9uCgkgICAgICovCgkgICAgYXN5bmMgbG9hZFRvcG9Kc29uKCkgewoJICAgICAgICBsZXQgdG9wb0pzb25EYXRhID0ge307CgkgICAgICAgIHRyeSB7CgkgICAgICAgICAgICB0b3BvSnNvbkRhdGEgPSBKU09OLnBhcnNlKHRoaXMuX3Jhd0RhdGEpOwoJICAgICAgICB9CgkgICAgICAgIGNhdGNoIChlKSB7CgkgICAgICAgICAgICB0aHJvdyAiSW52YWxpZCBUb3BvSnNvbiI7CgkgICAgICAgIH0KCSAgICAgICAgLy8gQ29udmVydCB0aGUgZGF0YQoJICAgICAgICBsZXQgcmVzdWx0ID0gdGhpcy5ibGFua0dlb0pTT04oKTsKCSAgICAgICAgaWYgKHRvcG9Kc29uRGF0YS50eXBlID09PSAiVG9wb2xvZ3kiICYmIHRvcG9Kc29uRGF0YS5vYmplY3RzICE9PSB1bmRlZmluZWQpIHsKCSAgICAgICAgICAgIHJlc3VsdCA9IHsKCSAgICAgICAgICAgICAgICB0eXBlOiAiRmVhdHVyZUNvbGxlY3Rpb24iLAoJICAgICAgICAgICAgICAgIGZlYXR1cmVzOiByZXN1bHQuZmVhdHVyZXMgPSBPYmplY3Qua2V5cyh0b3BvSnNvbkRhdGEub2JqZWN0cykubWFwKGtleSA9PiB0b3BvanNvbkZlYXR1cmUodG9wb0pzb25EYXRhLCBrZXkpKS5yZWR1Y2UoKGEsIHYpID0+IFsuLi5hLCAuLi52LmZlYXR1cmVzXSwgW10pCgkgICAgICAgICAgICB9OwoJICAgICAgICB9CgkgICAgICAgIHJldHVybiByZXN1bHQ7CgkgICAgfQoJICAgIDsKCSAgICAvKioKCSAgICAgKiBMb2FkcyBPU00gZGF0YSBhbmQgY29udmVydHMgaXQgaW50byBhIEdlb0pTT04gRmVhdHVyZUNvbGxlY3Rpb24KCSAgICAgKi8KCSAgICBhc3luYyBsb2FkT3NtKCkgewoJICAgICAgICByZXR1cm4gb3NtMmdlb2pzb24odGhpcy5fcmF3RGF0YSk7CgkgICAgfQoJfQoKCWNvbnN0IGxpYnJhcmllcyA9IHsKCSAgICAnQ29udmVydGVyJzogQ29udmVydGVyCgl9OwoJbGV0IHN1YkNsYXNzOwoJc2VsZi5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgZSA9PiB7CgkgICAgY29uc3QgZGF0YSA9IChlLmRhdGEgfHwgZSk7CgkgICAgY29uc3QgcG9zdCA9IChpZCwgZXJyLCByZXMsIHR5cGUpID0+IHsKCSAgICAgICAgcG9zdE1lc3NhZ2UoewoJICAgICAgICAgICAgdHlwZTogdHlwZSA/IHR5cGUgOiAoZXJyID8gJ2Vycm9yJyA6ICdyZXNwb25zZScpLAoJICAgICAgICAgICAgaWQ6IGlkLAoJICAgICAgICAgICAgbWVzc2FnZTogcmVzLAoJICAgICAgICAgICAgZXJyb3I6IGVycgoJICAgICAgICB9KTsKCSAgICB9OwoJICAgIGNvbnN0IGNvbW1hbmRzID0gewoJICAgICAgICAnaW5pdCc6IChtc2cpID0+IHsKCSAgICAgICAgICAgIGNvbnN0IHsgaWQsIGNvbW1hbmQsIG1lc3NhZ2UgfSA9IG1zZzsKCSAgICAgICAgICAgIHN1YkNsYXNzID0gbmV3IGxpYnJhcmllc1tjb21tYW5kXShtZXNzYWdlWzBdLCBtZXNzYWdlWzFdKTsKCSAgICAgICAgICAgIC8vIHJldHVybiB0aGUgY2xhc3MnIG1ldGhvZHMKCSAgICAgICAgICAgIGNvbnN0IGZucyA9IFsKCSAgICAgICAgICAgICAgICAuLi5PYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhsaWJyYXJpZXNbY29tbWFuZF0ucHJvdG90eXBlKSwKCSAgICAgICAgICAgICAgICAuLi5PYmplY3Qua2V5cyhzdWJDbGFzcykKCSAgICAgICAgICAgIF0ubWFwKGtleSA9PiBba2V5LCB0eXBlb2YgbGlicmFyaWVzW2NvbW1hbmRdLnByb3RvdHlwZVtrZXldXSkKCSAgICAgICAgICAgICAgICAucmVkdWNlKChhLCBjKSA9PiAoeyAuLi5hLCAuLi57IFtjWzBdXTogY1sxXSB9IH0pLCB7fSk7CgkgICAgICAgICAgICBwb3N0KGlkLCB1bmRlZmluZWQsIGZucywgJ2luaXRfcmVzcG9uc2UnKTsKCSAgICAgICAgfSwKCSAgICAgICAgJ2dldCc6IGZ1bmN0aW9uIChtc2cpIHsKCSAgICAgICAgICAgIGNvbnN0IHsgaWQsIGNvbW1hbmQgfSA9IG1zZzsKCSAgICAgICAgICAgIGlmIChzdWJDbGFzcyAmJiBzdWJDbGFzc1tjb21tYW5kXSkgewoJICAgICAgICAgICAgICAgIHBvc3QoaWQsIHVuZGVmaW5lZCwgc3ViQ2xhc3NbY29tbWFuZF0pOwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgZWxzZSB7CgkgICAgICAgICAgICAgICAgcG9zdChpZCwgdW5kZWZpbmVkLCB1bmRlZmluZWQpOwoJICAgICAgICAgICAgfQoJICAgICAgICB9LAoJICAgICAgICAnZXhlYyc6IGZ1bmN0aW9uIChtc2cpIHsKCSAgICAgICAgICAgIGNvbnN0IHsgaWQsIGNvbW1hbmQsIG1lc3NhZ2UgfSA9IG1zZzsKCSAgICAgICAgICAgIGlmIChzdWJDbGFzcyAmJiBzdWJDbGFzc1tjb21tYW5kXSAmJiB0eXBlb2Ygc3ViQ2xhc3NbY29tbWFuZF0gPT09ICdmdW5jdGlvbicpIHsKCSAgICAgICAgICAgICAgICBjb25zdCBjbWQgPSBzdWJDbGFzc1tjb21tYW5kXQoJICAgICAgICAgICAgICAgICAgICAuYXBwbHkoc3ViQ2xhc3MsIG1lc3NhZ2UpOwoJICAgICAgICAgICAgICAgIGlmICghIWNtZCAmJiB0eXBlb2YgY21kLnRoZW4gPT09ICdmdW5jdGlvbicpIHsKCSAgICAgICAgICAgICAgICAgICAgLy8gSXQncyBhIHByb21pc2UsIHNvIHdhaXQgZm9yIGl0CgkgICAgICAgICAgICAgICAgICAgIGNtZAoJICAgICAgICAgICAgICAgICAgICAgICAgLnRoZW4ocmVzID0+IHBvc3QoaWQsIHVuZGVmaW5lZCwgcmVzKSkKCSAgICAgICAgICAgICAgICAgICAgICAgIC5jYXRjaChlID0+IHBvc3QoaWQsIGUpKTsKCSAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICAgICAgZWxzZSB7CgkgICAgICAgICAgICAgICAgICAgIC8vIE5vdCBhIHByb21pc2UsIGp1c3QgcmV0dXJuIGl0CgkgICAgICAgICAgICAgICAgICAgIHBvc3QoaWQsIHVuZGVmaW5lZCwgY21kKTsKCSAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICBlbHNlIHsKCSAgICAgICAgICAgICAgICAvLyBFcnJvcgoJICAgICAgICAgICAgICAgIHBvc3QoaWQsIG5ldyBFcnJvcihgY29tbWFuZCAiJHtjb21tYW5kfSIgbm90IGZvdW5kYCkpOwoJICAgICAgICAgICAgfQoJICAgICAgICB9CgkgICAgfTsKCSAgICBpZiAoY29tbWFuZHNbZGF0YS50eXBlXSkgewoJICAgICAgICBjb21tYW5kc1tkYXRhLnR5cGVdKGRhdGEpOwoJICAgIH0KCX0pOwoKfSkoKTsKCg==",cC=null,oC=!1,lC?IC(bC,cC,oC):function(g,C,I){var A;return function(l){return A=A||AC(g,C,I),new Worker(A,l)}}(bC,cC,oC));const dC=()=>Math.random().toString(36).substring(2);class GC{constructor(g,C){this.initId=dC()+"-"+g,this.worker=new ZC,this.handlers=new Map,this.worker.onmessage=C=>{const I=C.data,A=this.handlers.get(I.id),l=this;if(A){if("response"===I.type&&A.resolve(I.message),"error"===I.type){const C=I.error||new Error(`Unknown error with ${g}`);A.reject(C)}"init_response"===I.type&&(this._=Object.keys(I.message).map((g=>{const C="function"==typeof I.message[g];return[g,function(){return C?l.exec(g)(...arguments):l.get(g)}]})).reduce(((g,C)=>({...g,[C[0]]:C[1]})),{}),A.resolve(this._))}},this.worker.postMessage({type:"init",id:this.initId,command:g,message:C})}onLoad(){return new Promise((g=>{void 0===this._?this.handlers.set(this.initId,{resolve:g,reject:g}):g(this._)}))}exec(g){const C=this;return function(...I){return new Promise(((A,l)=>{const b=dC()+"-"+g;C.handlers.set(b,{resolve:A,reject:l}),C.worker.postMessage({type:"exec",id:b,command:g,message:[...I]})}))}}get(g){return new Promise(((C,I)=>{const A=dC()+"-"+g;this.handlers.set(A,{resolve:C,reject:I}),this.worker.postMessage({type:"get",id:A,command:g,message:[]})}))}}const sC="test://http://example.com"!==new URL("test://http://example.com").href;async function eC(g,C,I){const A=await fetch(g,I?{signal:I.signal}:void 0);if(200==A.status){const g=await A.text();let I,l;return["kml","tcx","gpx"].indexOf(C)>=0||!(()=>{let g=!1;try{g="function"==typeof window.Worker}catch(C){g=!1}return g})()?(I=new $g(C,g),l=I.convert()):(I=new GC("Converter",[C,g]),l=I.exec("convert")()),await l}throw new Error(`Data fetch error: ${A.statusText}`)}const nC=(g,C)=>{const I=new AbortController,A=g.url.split("://")[0],l=g.url.replace(new RegExp(`^${A}://`),""),b=sC?(g=>{const C=new RegExp("^(https?)(//)");return g.replace(C,"$1:$2")})(l):l;return b&&eC(b,A,I).then((g=>C(null,g))).catch((g=>C(g))),{cancel:()=>{I.abort()}}};g.VectorTextProtocol=nC,g.addProtocols=g=>{_g.forEach((C=>{g.addProtocol(C,nC)}))},Object.defineProperty(g,"__esModule",{value:!0})}));
//# sourceMappingURL=maplibre-gl-vector-text-protocol.min.js.map