DIR : /home/kozerus/public_html/index_sc.html
/home/kozerus/public_html
<html>
<head>
<title>index_sc.html 201800706_0300 </title>
<title>index_sc.html 201800702_1700 lost kup insert bugs</title>
<!--
<title>index_sc.html 20180621_1300 </title>
<title>index_sc.html 20180605_0500 css_label_input</title>
<title>index_sc.html 20180603_0800</title>
<title>index_sc.html 20180603_0600</title>
<title>index_sc_links.html 20180602_0100</title>
-->
<style>
body{ background-color:slategrey; }
</style>
<style id="style_input">
.fileContainer {
overflow: hidden;
position: relative;
}
.fileContainer [type=file] {
cursor: inherit;
display: block;
font-size: 999px;
filter: alpha(opacity=0);
min-height: 100%;
min-width: 100%;
opacity: 0;
position: absolute;
right: 0;
text-align: right;`
top: 0;
}
</style>
<!--
<style id="style_input2">
input[type=text] {
background-color: #BFBDBD;
border:solid 1px #BFBDBD;
color: #979797;
height: 28px;
padding-left:10px;
width: 191px;
box-shadow: 2px 2px 0 #828181 inset;
}
input[type=button] {
background-color: #1E1E1E;
color: #979797;
height: 24px;
width: 103px;
color: #bbbbbb;
text-transform:uppercase;
box-shadow:-1px 2px #6E6B6A inset;
}
input[type=button], input[type=text]
{border-radius: 5px; font-family: Sansation;}
{border-radius: 5px; font-family: yokkmokkOT;}
</style>
-->
<style id="style_popover" >
.popover {
position: relative;
float: left;
padding: 5px;
/*z-index_sc: 0;*/
}
.popover:hover {
background-color: slategrey;
// background-color: #e9e9e2;
/*z-index_sc: 50;*/
color: white;
// color: #335500;
text-decoration: none;
}
/*CSS for enlarged image*/
.popover span {
position: absolute;
// background-color: #e5e5e5;
background-color: slategrey;
padding: 5px;
/*left: -1000px;*/
border: 1px solid #666;
visibility: hidden;
color: black;
text-decoration: none;
}
/*CSS for enlarged image*/
.popover span img {
border-width: 0px;
/*padding: 2px;*/
}
/*CSS for enlarged image on hover*/
.popover:hover span {
visibility: visible;
// width: 200px;
top: 0px; /* use IF IE6 style to correct IE6 positions of larger image relative to thumb */
left: 0px;/*position where enlarged image should offset horizontally */
}
</style>
<style id="style_thumbnail" >
.thumbnail {
position: relative;
float: left;
padding: 5px;
/*z-index_sc: 0;*/
}
.thumbnail:hover {
background-color: #e9e9e2;
/*z-index_sc: 50;*/
color: #335500;
text-decoration: none;
}
/*CSS for enlarged image*/
.thumbnail span {
position: absolute;
background-color: #e5e5e5;
padding: 5px;
/*left: -1000px;*/
border: 1px solid #666;
visibility: hidden;
color: black;
text-decoration: none;
}
/*CSS for enlarged image*/
.thumbnail span img {
border-width: 0px;
/*padding: 2px;*/
}
/*CSS for enlarged image on hover*/
.thumbnail:hover span {
visibility: visible;
width: 200px;
top: 5px; /* use IF IE6 style to correct IE6 positions of larger image relative to thumb */
left: 300px;/*position where enlarged image should offset horizontally */
}
/*THUMBNAIL2 - thumbnail2 has border and border on hover*/
.thumbnail2 {
position: relative;
float: left;
padding: 5px;
/*z-index_sc: 0;*/
}
.thumbnail2:hover {
background-color: #e9e9e2;
/*z-index_sc: 50;*/
color: #335500;
text-decoration: none;
}
.thumbnail2 span { /*CSS for enlarged image*/
position: absolute;
background-color: #e5e5e5;
padding: 5px;
/*left: -1000px;*/
border: 1px solid #666;
visibility: hidden;
color: black;
text-decoration: none;
}
/*CSS for enlarged image*/
.thumbnail2 span img { border-width: 0px;}
/*CSS for enlarged image on hover*/
.thumbnail2:hover span {
visibility: visible; width: 208px;
top: 5px; /* use IF IE6 style to correct IE6 positions of larger image relative to thumb */
left: 300px;/*position where enlarged image should offset horizontally */
}
a.thumbnail2 img { text-decoration:none; z-index_sc: 50; }
/*if same attribute for all 4 states, then declare here in a.thumbnail2*/
a.thumbnail2 img:link { border: 2px solid #e9e9e2; background: transparent; }
a.thumbnail2 img:visited { border: 2px solid #e9e9e2; background : transparent; }
a.thumbnail2 img:hover { border: 2px solid #f00; background : transparent; }
a.thumbnail2 img:active { border: 2px solid #e9e9e2; background : transparent; }
a.thumbnail2 img { border: 2px solid #e9e9e2; }
</style>
<style id="style_buttons" >
body { text-align: center; background-color: "slategrey"; color:"white"; }
button {
// visibility: hidden;
// background: rgba(7, 99, 53, .1);
background: transparent;
// border: 3px solid rgba(7, 99, 53, 1);
border: 3px solid slategrey;
border-radius: 5px;
// color: rgba(7, 99, 53, 1);
color: slategrey;
cursor: pointer;
line-height: 40px;
font-size: 20px;
outline: none;
padding: 0 20px;
transition: all .3s;
}
button:hover {
// background: rgba(7, 99, 53, 1);
background: darkgreyslate;
// background: yellow;
// background: white;
// color: rgba(255,255,255,1);
color: white;
}
p {font-size: 20px; font-weight: bold;
</style>
<style id="style_input" >
body { text-align: center; background-color: "slategrey"; color:"white"; }
input {
// visibility: hidden;
// background: rgba(7, 99, 53, .1);
background: transparent;
// border: 3px solid rgba(7, 99, 53, 1);
border: 3px solid slategrey;
border-radius: 5px;
// color: rgba(7, 99, 53, 1);
color: slategrey;
cursor: pointer;
line-height: 40px;
font-size: 10px;
outline: none;
padding: 0 20px;
transition: all .3s;
}
button:hover {
// background: rgba(7, 99, 53, 1);
background: darkgreyslate;
// background: yellow;
// background: white;
// color: rgba(255,255,255,1);
color: white;
}
p {font-size: 10px; font-weight: bold;
</style>
<style type="text/css">
#drop {
width:200px;
height:150px;
margin:3px auto;
background:#eddaa8;
font-size:16px;
}
#drop #sw { text-decoration:underline; cursor:pointer; }
#drag {
width:450px;
height:180px;
margin:12px auto;
border:1px solid silver;
font-size:16px;
}
#drag .drg { margin:10px 12px; }
#drag div.drg {
width:150px;
height:50px;
background:#07da08;
border:2px solid blue;
}
</style>
<script type="text/javascript">
$(document).ready(function() {
// sets the draggable
$('#drag .drg').draggable({
cursor: 'move', // sets the cursor apperance
revert: 'valid'
});
// sets droppable
$('#drop').droppable({
drop: function(event, ui) {
// after the draggable is droped, hides it with a hide() effect
ui.draggable.hide(1000);
}
});
$('#drop1').droppable({
drop: function(event, ui) {
// after the draggable is droped, hides it with a hide() effect
ui.draggable.hide(1000);
}
});
$('#drop2').droppable({
drop: function(event, ui) {
// after the draggable is droped, hides it with a hide() effect
ui.draggable.hide(1000);
}
});
// when the "#sw" element (inside the "#drop") is clicked
// show the items with class "drg", contained in "#drag"
$('#drop #sw').click(function(){
// $('#drag .drg').slideDown(1000);
var url = "https://ka6//ko_center/ko_center.php?q=jqui/dragdrop1/"
$(location).attr('href',url);
});
});
</script>
</head>
<body>
<div name="div_dd" id="div_dd" hidden >
<div id="drop">
<span id="sw"><h1>drop jtfinc</h2></span>
<a href=./ko_jtf/zm/jtf_parcels/jtfdc_theater.html target=_blank>
<img height=200 width=300
src="./ko_jtf/zm/jtf_parcels/jtfdc_theater/TileGroup0/0-0-0.png" border=0 >
</a>
</div>
<div id="drag"> jtfdc:<br />
<img src="./imgs/jtf/jtf_takes/jtf29_eagle_north.png" alt="jtf29_eagle_north" width="50" class="drg"/>
<div class="drg"><h1>konet llc </h1>
<pre>timejask jkwii</pre>
<img class="drg" src="./imgs/btn/ko.png" alt="ko.png" width="50" >
<img class="drg" src="./imgs/btn/ok.png" alt="ok.png" width="50" >
<pre>timesak skwii</pre>
</div>
<div class="drg"><h1>jtf29 </h1>
<a href=./ko_jtf/zm/jtf_parcels/jtf29.html target=_blank>
<img height=200 width=100 src="./ko_jtf/zm/jtf_parcels/jtf29/TileGroup0/0-0-0.png" border=0 >
</a>
</div>
<div class="drg"><h1>dogheads</h1>
<div id="div_jtf_vid5">
<video controls="controls_jtf5" defaultmuted="" muted="true" style="width:320px;height:180px;" poster="index_sc4_mp4.png">
<source src="./kb/v/doghead_video.mp4" type="video/mp4;codecs="avc1.42E01E, mp4a.40.2"">
</video>
</div>
</div>
<div class="drg"><h1>jtfdc night court lights action 3720</h1>
<div id="div_vid">
<video controls="controls" defaultmuted="" muted="true" style="width:320px;height:180px;" poster="index_sc_mp4.png">
<source src="index_sc1_avril.mp4" type="video/mp4;codecs="avc1.42E01E, mp4a.40.2"">
<source src="index_sc_avril.webm" type="video/webm;codecs="vp8, vorbis"">
</video>
</div>
</div>
</div>
</div>
<script id="script_load_liks" >
var svc_links = new Array();
var ko_links = new Array();
var us_links = new Array();
var u_links = new Array();
var now_links = new Array();
var srv_links = new Array();
function load_svc_links() {
var j=0;
svc_links[j++]="./index_sc_av.html|./imgs/links/index_sc_av.png|index_sc_av|./imgs/btn/kob.png";
svc_links[j++]="./index_sc_bb.html|./imgs/links/index_sc_bb.png|index_sc_bb|./imgs/btn/kob.png";
svc_links[j++]="./index_sc_bp.html|./imgs/links/index_sc_bp.png|index_sc_bb|./imgs/btn/kob.png";
svc_links[j++]="./index_sc_dd.html|./imgs/links/index_sc_dd.png|index_sc_dd|./imgs/btn/kob.png";
svc_links[j++]="./index_sc_dl.html|./imgs/links/index_sc_dl.png|index_sc_dl|./imgs/btn/kob.png";
svc_links[j++]="./index_sc_dp.html|./imgs/links/index_sc_dp.png|index_sc_dp|./imgs/btn/kob.png";
svc_links[j++]="./index_sc_fl.html|./imgs/links/index_sc_fl.png|index_sc_fl|./imgs/btn/kob.png";
svc_links[j++]="./index_sc_jg.html|./imgs/links/index_sc_jg.png|index_sc_jg|./imgs/btn/kob.png";
svc_links[j++]="./index_sc_pn.html|./imgs/links/index_sc_pn.png|index_sc_pn|./imgs/btn/kob.png";
svc_links[j++]="./index_sc_sc.html|./imgs/links/index_sc_sc.png|index_sc_sc|./imgs/btn/kob.png";
svc_links[j++]="./index_sc_sl.html|./imgs/links/index_sc_sl.png|index_sc_sl|./imgs/btn/kob.png";
svc_links[j++]="./index_sc_tl.html|./imgs/links/index_sc_tl.png|index_sc_tl|./imgs/btn/kob.png";
svc_links[j++]="./index_sc_tm.html|./imgs/links/index_sc_tm.png|index_sc_tm|./imgs/btn/kob.png";
svc_links[j++]="./index_sc_us.html|./imgs/links/index_sc_us.png|index_sc_us|./imgs/btn/kob.png";
svc_links[j++]="./index_sc_wc.html|./imgs/links/index_sc_wc.png|index_sc_wc|./imgs/btn/kob.png";
svc_links[j++]="./index_sc_yt.html|./imgs/links/index_sc_yt.png|index_sc_yt|./imgs/btn/kob.png";
svc_links[j++]="./index_sc_zm.html|./imgs/links/index_sc_zm.png|index_sc_zm|./imgs/btn/kob.png";
return( svc_links );
}
function load_srv_links() {
srv_links[0]="ko0.us/index_sc.html|./imgs/btn/koeyeb.png|ko0us|./imgs/btn/kob.png";
srv_links[1]="ko1.us/index_sc.html|./imgs/btn/koeye.png|ko1us|./imgs/btn/kop1234.png";
srv_links[2]="ko2.us/index_sc.html|./imgs/btn/koeyew.png|ko2us|./imgs/btn/kow.png";
srv_links[3]="konet.org/index_sc.html|./imgs/btn/ko.png|konet-org|./imgs/btn/kib.png";
srv_links[4]="iperms.com/index_sc.html|./imgs/links/iperms.png|iperms-com|./imgs/btn/kop34.png";
srv_links[5]="kassil.com/index_sc.html|./imgs/links/kassil.png|kassil-com|./imgs/btn/kop12.png";
return( srv_links );
}
function load_ko_links() {
var j=0;
ko_links[j++]="./jkwii/blackboard.html|./imgs/links/blackboard.png|blackboard|./imgs/btn/koeye.png";
ko_links[j++]="./jkwii/js/threejs/examples/index_sc.html|./imgs/links/index_sc_js3d.png|index_sc_js3d|./imgs/btn/koeye.png";
ko_links[j++]="./ko/svc/js/stemkoskijs/Three.js/index_sc.html|./imgs/links/index_sc_js3d-stemkoski.png|index_sc_js3d-stemkoski|./imgs/btn/koeye.png";
ko_links[j++]="./jkwii/js/gojs/index_sc.html|./imgs/links/index_sc_jsgo.png|index_sc_jsgo|./imgs/btn/koeye.png";
ko_links[j++]="./index_sc_jsdk.html|./imgs/links/index_sc_jsdk.png|index_sc_jsdk|./imgs/btn/koeye.png";
ko_links[j++]="./jkwii/koh5_globe/koh5_globe.html|./imgs/links/koh5_globe.png|koh5_globe|./imgs/btn/koeye.png";
ko_links[j++]="./jkwii/aud/keybd/index_sc.html|./imgs/links/index_sc_jskb.png|index_sc_jskb|./imgs/btn/koeye.png";
ko_links[j++]="./svc/kokbdm/index_sc.html|./imgs/links/index_sc_jskb-dm.png|index_sc_jskb-dm|./imgs/btn/koeye.png";
ko_links[j++]="./svc/kokbdms/index_sc.html|./imgs/links/index_sc_jskb-dms.png|index_sc_jskb-dms|./imgs/btn/koeye.png";
ko_links[j++]="./piano.html|./imgs/links/index_sc_piano.png|index_sc_piano|./imgs/btn/koeye.png";
ko_links[j++]="./jkwii/aud/piano_uri/koh5_piano_uri.html|./imgs/links/index_sc_jskb-uri.png|index_sc_jskb_uri|./imgs/btn/koeye.png";
ko_links[j++]="./ko/svc/js/stemkoskijs/index_sc.html|./imgs/links/index_sc_js3d-stemkoski.png|index_sc_js3d-stemkoski|./imgs/btn/koeye.png";
ko_links[j++]="./ko/svc/aud/mrcoles/koh5_mrcoles.html|./imgs/links/mrcoles.png|mrcoles|./imgs/btn/koeye.png";
ko_links[j++]="http://effectgames.com/demos/canvascycle/|./imgs/links/index_sc_effectgames.png|index_sc_effectgames|./imgs/btn/koeye.png";
ko_links[j++]="https://www.leshylabs.com/apps/sfMaker/|./imgs/links/index_sc_sfmaker.png|index_sc_sfmaker|./imgs/btn/koeye.png";
ko_links[j++]="https://dragongoserver.net/|./imgs/links/index_sc_dgs.png|index_sc_dgs|./imgs/btn/koeye.png";
ko_links[j++]="./ko_center/ko_center.php|./imgs/links/ko_center.png|ko_center|./imgs/btn/kob.png";
ko_links[j++]="./ko_saic/ko_saic.php|./imgs/links/ko_saic.png|ko_saic|./imgs/btn/kob.png";
ko_links[j++]="./index_sc_kt.html|./imgs/links/index_sc_kt.png|index_sc_kt|./imgs/btn/kob.png";
ko_links[j++]="./index_sc_jtf.html|./imgs/links/index_sc_jtf.png|index_sc_jtf|./imgs/btn/kob.png";
ko_links[j++]="./index_sc2big.html|./imgs/links/index_sc2big.png|index_sc2big|./imgs/btn/kob.png";
ko_links[j++]="./index_sc2big.htm|./imgs/links/index_sc2big_noel.png|index_sc2big_noel|./imgs/btn/kob.png";
ko_links[j++]="./jkwii/whiteboard.html|./imgs/links/whiteboard.png|whiteboard|./imgs/btn/koeye.png";
return( ko_links );
}
function load_us_links() {
var j=0;
us_links[j++]="http://lawdonovan.com|./imgs/us/lawdonovan.png|law_donovan|./imgs/btn/koeye.png|law";
us_links[j++]="http://nathanscohen.com/|./imgs/us/law_cohen_nathan_s.png|law__cohen_nathan_s|./imgs/btn/koeye.png|law";
us_links[j++]="https://www.linkedin.com/in/alan-cohen-2314473b/|./imgs/us/law_cohen_alan_w.png|law__cohen_alan_w|./imgs/btn/koeye.png|law";
us_links[j++]="https://twitter.com/AlanWCohenEsq|./imgs/us/cohen_alan_w_twitter.png|cohen_alan_w_twitter|./imgs/btn/koeye.png|law";
us_links[j++]="http://www.primerus.com/attorneys/alexander-h-kuehling-esq-rosenblum-goldenhersh-st-louis-missouri-mo.htm|./imgs/us/law_kuehling_alexander.png|law_law_kuehling_alexander|./imgs/btn/koeye.png|law";
us_links[j++]="http://elsterlaw.com/henry-elster-attorney-missouri-best/|./imgs/us/law_elster_henry.png|law_elster_henry|./imgs/btn/koeye.png|law";
us_links[j++]="https://pview.findlaw.com/view/2830721_1|./imgs/us/law_walters_alan.png|law_walters_alan|./imgs/btn/koeye.png|law";
us_links[j++]="https://www.thompsoncoburn.com/|./imgs/us/law_thompson_coburn.png|law__thompson_coburn|./imgs/btn/koeye.png|law";
us_links[j++]="http://koreintillery.com/|./imgs/us/law_korein_tillery.png|law_korein_tillery|./imgs/btn/koeye.png|law";
us_links[j++]="http://www.smithbrownllc.com/|./imgs/us/law_smith_brown.png|law_smith_brown|./imgs/btn/koeye.png|law";
us_links[j++]="http://www.fdazol.com/|./imgs/us/law_azol.png|law_azol_f|./imgs/btn/koeye.png|law";
us_links[j++]="https://jmhalumni.com|./imgs/us/jmhalumni.png|ed_jmhalumni|./imgs/btn/koeye.png|edu";
us_links[j++]="https://johnmarshallhighschool.com|./imgs/us/johnmarshallhighschool.png|ed_johnmarshallhighschool|./imgs/btn/koeye.png|edu";
us_links[j++]="https://www.greatschools.org/kentucky/brandenburg/1993-Brandenburg-High-School/|./imgs/us/brandenburg_highschool.png|ed_brandenburg-highschool|./imgs/btn/koeye.png|edu";
us_links[j++]="https://www.hazelwoodschools.org/Page/3143|./imgs/us/hazelwood_schools.png|ed_hazelwood_schools|./imgs/btn/koeye.png|edu";
us_links[j++]="https://bw.edu|./imgs/us/bw.png|ed_bw|./imgs/btn/koeye.png|edu";
us_links[j++]="http://oldtowndonuts.com|./imgs/us/oldtowndonuts.png|food_oldtowndonuts|./imgs/btn/koeye.png|food";
us_links[j++]="http://farkaspastries.com|./imgs/us/farkaspastries.png|food_farkaspastries|./imgs/btn/koeye.png|food";
us_links[j++]="https://www.facebook.com/HansaImportHouse|./imgs/us/hansaimporthouse.png|food_hansaimporthouse|./imgs/btn/koeye.png|food";
us_links[j++]="http://havanagrillco.com|./imgs/us/havanagrillco.png|food_havanagrillco|./imgs/btn/koeye.png|food";
us_links[j++]="http://spiros-restaurant.com|./imgs/us/spiros_restaurant.png|food_spiros_restaurant|./imgs/btn/koeye.png|food";
us_links[j++]="https://www.opentable.com/jake-and-tellys-greek-taverna?page=1|./imgs/us/food_jake_tellys.png|food_jake_tellys|./imgs/btn/koeye.png|food";
us_links[j++]="http://edelweissrest.com|./imgs/us/edelweissrest.png|food_edelweissrest|./imgs/btn/koeye.png|food";
us_links[j++]="http://bierwerks.com|./imgs/us/food_bierwerks.png|food_bierwerks|./imgs/btn/koeye.png|food";
us_links[j++]="http://www.savellispizzapastasubs.com/|./imgs/us/food_savellispizza.png|food_savellispizza|./imgs/bmtn/koeye.png|food";
us_links[j++]="https://www.facebook.com/woohoogreekfood2/|./imgs/us/woohoogreekfood2.png|food_woohoogreekfood2|./imgs/btn/koeye.png|food";
us_links[j++]="https://bdo.com/about/us-locations/bdo-st-louis|./imgs/us/bdo-stl.png|acct_bdo-stl|./imgs/btn/koeye.png|acct";
us_links[j++]="https://bdo.com/about/us-locations/bdo-cleveland-office|./imgs/us/bdo-cle.png|acct_bdo-cle|./imgs/btn/koeye.png|acct";
us_links[j++]="http://www.gatewayloan.com/|./imgs/us/gateway_mortgage.png|gateway_mortgage|./imgs/btn/koeye.png|acct";
us_links[j++]="https://chesonsulting.com|./imgs/us/checonsulting.png|biz_checonsulting|./imgs/btn/koeye.png|biz";
us_links[j++]="http://saic.com|./imgs/us/saic.png|saic|./imgs/btn/koeye.png|biz";
us_links[j++]="http://leidos.com|./imgs/us/leidos.png|leidos|./imgs/btn/koeye.png|biz";
us_links[j++]="http://ko2.us/index_sc_focus.com|./imgs/us/focus_solutions.png|focus_solutions|./imgs/btn/koeye.png|biz";
us_links[j++]="http://www.finduslocal.com/hardware-stores/kentucky/brandenburg/allens-s-t-hardware-inc|./imgs/us/biz_allens_hardware.png|biz_allens_hardware|./imgs/btn/koeye.png|biz";
us_links[j++]="http://growwarehouse.com|./imgs/us/grow_warehouse.png|grow_warehouse|./imgs/btn/koeye.png|biz";
us_links[j++]="https://www.facebook.com/avondanceandmartialarts|./imgs/us/avondanceandmartialarts.png|avondanceandmartialarts|./imgs/btn/koeye.png|phy";
us_links[j++]="https://www.facebook.com/avondanceandmartialarts|./imgs/us/avondanceandmartialarts.png|avondanceandmartialarts|./imgs/btn/koeye.png|phy";
us_links[j++]="http://www.savellidanceandmartialarts.com/?load=html|./imgs/us/savelli_dance_martialarts.png|savelli_dance_martialarts|./imgs/btn/koeye.png|phy";
us_links[j++]="http://myfusiondance.com/?load=html|./imgs/us/fusion_dance.png|fusion_dance|./imgs/btn/koeye.png|phy";
us_links[j++]="http://www.superseriesbaseball.com/|./imgs/us/super_series_baseball.png|super_series_baseball|./imgs/btn/koeye.png|phy";
us_links[j++]="https://ftknox.afceachapters.org/|./imgs/us/afcea_knox.png|afcea_knox|./imgs/btn/koeye.png|org";
us_links[j++]="https://scott.afceachapters.org/|./imgs/us/afcea_scott.png|afcea_scott|./imgs/btn/koeye.png|org";
us_links[j++]="https://www.ble-t.org/|./imgs/us/ble.png|ble|./imgs/btn/koeye.png|org";
us_links[j++]="http://www.doevalley.org/|./imgs/us/doe_valley.png|doe_valley|./imgs/btn/koeye.png|org";
us_links[j++]="http://www.chapelofthecross.org/|./imgs/us/chapel_of_the_cross.png|chapel_of_the_cross|./imgs/btn/koeye.png|rel";
us_links[j++]="https://www.lds.org/temples/details/st.-louis-missouri-temple|./imgs/us/lds_stl.png|lds_stl|./imgs/btn/koeye.png|rel";
us_links[j++]="https://www.bethanyenglish.org/|./imgs/us/bethany_english_lutheran.png|bethany_english_lutheran|./imgs/btn/koeye.png|rel";
us_links[j++]="https://www.meadecountymessenger.com/|./imgs/us/meade_county_messenger.png|meade_county_messenger|./imgs/btn/koeye.png|media";
us_links[j++]="./index_sc_jtfdcr.html|./imgs/us/jtfdcr.png|jtfdcr|./imgs/btn/koeye.png|media";
us_links[j++]="https://mars.jpl.nasa.gov/msl/multimedia/raw/?s=#/?slide=2088|./imgs/us/mars_jpl_nasa.png|mars_jpl_nasa|./imgs/btn/koeye.png|sci";
us_links[j++]="https://mars.nasa.gov/mer/gallery/all/opportunity.html|./imgs/us/mars_nasa_gov.png|mars_nasa_gov|./imgs/btn/koeye.png|sci";
us_links[j++]="./index_sc_jtfdcr.html|./imgs/us/jtfdcr.png|jtfdcr|./imgs/btn/koeye.png|media";
return( us_links );
}
function load_u_links() {
var j=0;
u_links[j++]="http://lawdonovan.com|./imgs/us/lawdonovan.png|law_donovan|./imgs/btn/koeye.png|law";
u_links[j++]="http://nathanscohen.com/|./imgs/us/law_cohen_nathan_s.png|law__cohen_nathan_s|./imgs/btn/koeye.png|law";
u_links[j++]="https://www.linkedin.com/in/alan-cohen-2314473b/|./imgs/us/law_cohen_alan_w.png|law__cohen_alan_w|./imgs/btn/koeye.png|law";
u_links[j++]="https://twitter.com/AlanWCohenEsq|./imgs/us/cohen_alan_w_twitter.png|cohen_alan_w_twitter|./imgs/btn/koeye.png|law";
u_links[j++]="http://www.primerus.com/attorneys/alexander-h-kuehling-esq-rosenblum-goldenhersh-st-louis-missouri-mo.htm|./imgs/us/law_kuehling_alexander.png|law_law_kuehling_alexander|./imgs/btn/koeye.png|law";
u_links[j++]="http://elsterlaw.com/henry-elster-attorney-missouri-best/|./imgs/us/law_elster_henry.png|law_elster_henry|./imgs/btn/koeye.png|law";
u_links[j++]="https://pview.findlaw.com/view/2830721_1|./imgs/us/law_walters_alan.png|law_walters_alan|./imgs/btn/koeye.png|law";
u_links[j++]="https://www.thompsoncoburn.com/|./imgs/us/law_thompson_coburn.png|law__thompson_coburn|./imgs/btn/koeye.png|law";
u_links[j++]="http://koreintillery.com/|./imgs/us/law_korein_tillery.png|law_korein_tillery|./imgs/btn/koeye.png|law";
u_links[j++]="http://www.smithbrownllc.com/|./imgs/us/law_smith_brown.png|law_smith_brown|./imgs/btn/koeye.png|law";
return( u_links );
}
function load_now_links() {
var j=0;
now_links[j++]="http://index_sc_party.html|./imgs/us/lawdonovan.png|law_donovan|./imgs/btn/koeye.png|law";
now_links[j++]="http://index_sc_jtfdc.com/|./imgs/us/law_cohen_nathan_s.png|law__cohen_nathan_s|./imgs/btn/koeye.png|law";
now_links[j++]="http://index_sc_jtfinc.com/|./imgs/us/law_cohen_nathan_s.png|law__cohen_nathan_s|./imgs/btn/koeye.png|law";
now_links[j++]="http://index_sc_stlc.com/|./imgs/us/law_cohen_nathan_s.png|law__cohen_nathan_s|./imgs/btn/koeye.png|law";
now_links[j++]="http://index_sc_jtfdcr.com/|./imgs/us/law_cohen_nathan_s.png|law__cohen_nathan_s|./imgs/btn/koeye.png|law";
now_links[j++]="http://index_sc_byrdpucker.com/|./imgs/us/law_cohen_nathan_s.png|law__cohen_nathan_s|./imgs/btn/koeye.png|law";
return( now_links );
}
function show_svc_links(mode) {
svc_links = load_svc_links();
htmout_svc_links = "";
htmout_svc_linkz = "";
for (i = 0; i < svc_links.length; i++) {
my_btnimg = "./imgs/btn/kib.png";
my_href = svc_links[i].split("|")[0];
my_popimg = svc_links[i].split("|")[1];
my_alt = svc_links[i].split("|")[2];
// htmout_svc_linkz += '<div class="drag" name="'+my_alt+'" >\n';
htmout_svc_linkz += '<a class="drag" href="' + my_href + '" target=_blank>"';
htmout_svc_linkz += '<img id="drg" src="' + my_popimg + '" alt="' + my_alt + '" height=100></a>';
// htmout_svc_linkz += '</div >';
// htmout_svc_links += '<div class="drag" name="'+my_alt+'" >\n';
htmout_svc_links += '<a class="thumbnail" href="' + my_href + '" target=_blank>"';
htmout_svc_links += '<img class="drag" id="drg" src="' + my_btnimg + '" alt="' + my_alt + '" width=25px height=14px border=0>';
htmout_svc_links += '<span><img src="' + my_popimg + '" alt="' + my_alt + '"></span></a>';
// htmout_svc_links += '</div >';
}
if( mode === 'pop' ) {
htmout_svc_links += "<br><br>\n";
var div_svc_links = document.getElementById('div_svc_links');
div_svc_links.insertAdjacentHTML('beforeend', htmout_svc_links);
return( htmout_svc_links );
}
htmout_svc_linkz += "<br><br>\n";
var div_svc_linkz = document.getElementById('div_svc_linkz');
div_svc_linkz.insertAdjacentHTML('beforeend', htmout_svc_linkz);
return( htmout_svc_linkz );
}
function show_ko_links(mode) {
ko_links = load_ko_links();
htmout_ko_links = "";
htmout_ko_linkz = "";
for (i = 0; i < ko_links.length; i++) {
my_btnimg = "./imgs/btn/koeye.png";
my_href = ko_links[i].split("|")[0];
my_popimg = ko_links[i].split("|")[1];
my_alt = ko_links[i].split("|")[2];
htmout_ko_linkz += '<a class="drag" href="' + my_href + '" target=_blank>"';
htmout_ko_linkz += '<img src="' + my_popimg + '" alt="' + my_alt + '" height=100></a>';
htmout_ko_links += '<a class="thumbnail" href="' + my_href + '" target=_blank>"';
htmout_ko_links += '<img src="' + my_btnimg + '" alt="' + my_alt + '" width=25px height=14px border=0>';
htmout_ko_links += '<span><img src="' + my_popimg + '" alt="' + my_alt + '"></span></a>';
}
if( mode === 'pop' ) {
htmout_ko_links += "<br><br>";
var div_ko_links = document.getElementById('div_ko_links');
div_ko_links.insertAdjacentHTML('beforeend', htmout_ko_links);
return( htmout_ko_links );
}
htmout_ko_linkz += "<br><br>";
var div_ko_linkz = document.getElementById('div_ko_linkz');
div_ko_linkz.insertAdjacentHTML('beforeend', htmout_ko_linkz);
return( htmout_ko_linkz );
}
function show_us_links(mode) {
us_links = load_us_links();
htmout_us_links = "";
htmout_us_linkz = "";
for (i = 0; i < us_links.length; i++) {
my_btnimg = "./imgs/btn/koeye.png";
my_href = us_links[i].split("|")[0];
my_popimg = us_links[i].split("|")[1];
my_alt = us_links[i].split("|")[2];
htmout_us_linkz += '<a class="drag" href="' + my_href + '" target=_blank>"';
htmout_us_linkz += '<img src="' + my_popimg + '" alt="' + my_alt + '" height=100></a>';
htmout_us_links += '<a class="thumbnail" href="' + my_href + '" target=_blank>"';
htmout_us_links += '<img src="' + my_btnimg + '" alt="' + my_alt + '" width=25px height=14px border=0>';
htmout_us_links += '<span><img src="' + my_popimg + '" alt="' + my_alt + '"></span></a>';
}
if( mode === 'pop' ) {
htmout_us_links += "<br><br>";
var div_us_links = document.getElementById('div_us_links');
div_us_links.insertAdjacentHTML('beforeend', htmout_us_links);
return( htmout_us_links );
}
htmout_us_linkz += "<br><br>";
var div_us_linkz = document.getElementById('div_us_linkz');
div_us_linkz.insertAdjacentHTML('beforeend', htmout_us_linkz);
return( htmout_us_linkz );
}
function show_u_links(mode) {
u_links = load_u_links();
htmout_u_links = "";
htmout_u_linkz = "";
for (i = 0; i < u_links.length; i++) {
my_btnimg = "./imgs/btn/koeye.png";
my_href = u_links[i].split("|")[0];
my_popimg = u_links[i].split("|")[1];
my_alt = u_links[i].split("|")[2];
htmout_u_linkz += '<a class="drag" href="' + my_href + '" target=_blank>"';
htmout_u_linkz += '<img src="' + my_popimg + '" alt="' + my_alt + '" height=100></a>';
htmout_u_links += '<a class="thumbnail" href="' + my_href + '" target=_blank>"';
htmout_u_links += '<img src="' + my_btnimg + '" alt="' + my_alt + '" width=25px height=14px border=0>';
htmout_u_links += '<span><img src="' + my_popimg + '" alt="' + my_alt + '"></span></a>';
}
if( mode === 'pop' ) {
htmout_u_links += "<br><br>";
var div_u_links = document.getElementById('div_u_links');
div_u_links.insertAdjacentHTML('beforeend', htmout_u_links);
return( htmout_u_links );
}
htmout_u_linkz += "<br><br>";
var div_u_linkz = document.getElementById('div_u_linkz');
div_u_linkz.insertAdjacentHTML('beforeend', htmout_u_linkz);
return( htmout_u_linkz );
}
function show_now_links(mode) {
now_links = load_now_links();
htmout_now_links = "";
htmout_now_linkz = "";
for (i = 0; i < now_links.length; i++) {
my_btnimg = "./imgs/btn/koeye.png";
my_href = now_links[i].split("|")[0];
my_popimg = now_links[i].split("|")[1];
my_alt = now_links[i].split("|")[2];
htmout_now_linkz += '<a class="drag" href="' + my_href + '" target=_blank>"';
htmout_now_linkz += '<img src="' + my_popimg + '" alt="' + my_alt + '" height=100></a>';
htmout_now_links += '<a class="thumbnail" href="' + my_href + '" target=_blank>"';
htmout_now_links += '<img src="' + my_btnimg + '" alt="' + my_alt + '" width=25px height=14px border=0>';
htmout_now_links += '<span><img src="' + my_popimg + '" alt="' + my_alt + '"></span></a>';
}
if( mode === 'pop' ) {
htmout_now_links += "<br><br>";
var div_now_links = document.getElementById('div_now_links');
div_now_links.insertAdjacentHTML('beforeend', htmout_now_links);
return( htmout_now_links );
}
htmout_now_linkz += "<br><br>";
var div_now_linkz = document.getElementById('div_now_linkz');
div_now_linkz.insertAdjacentHTML('beforeend', htmout_now_linkz);
return( htmout_now_linkz );
}
function show_srv_links(mode) {
srv_links = load_srv_links();
htmout_srv_links = "";
htmout_srv_linkz = "";
for (i = 0; i < srv_links.length; i++) {
my_btnimg = "./imgs/btn/kiw.png";
my_href = srv_links[i].split("|")[0];
my_popimg = srv_links[i].split("|")[1];
my_alt = srv_links[i].split("|")[2];
htmout_srv_linkz += '<a class="drag" href="' + my_href + '" target=_blank>"';
htmout_srv_linkz += '<img src="' + my_popimg + '" alt="' + my_alt + '" height=100></a>';
htmout_srv_links += '<a class="thumbnail" href="' + my_href + '" target=_blank>"';
htmout_srv_links += '<img src="' + my_btnimg + '" alt="' + my_alt + '" width=25px height=14px border=0>';
htmout_srv_links += '<span><img src="' + my_popimg + '" alt="' + my_alt + '"></span></a>';
}
if( mode === 'pop' ) {
htmout_srv_links += "<br><br>\n"
var div_srv_links = document.getElementById('div_srv_links');
div_srv_links.insertAdjacentHTML('beforeend', htmout_srv_links);
return( htmout_srv_links );
}
htmout_srv_linkz += "<br><br>\n"
var div_srv_linkz = document.getElementById('div_srv_linkz');
div_srv_linkz.insertAdjacentHTML('beforeend', htmout_srv_linkz);
return( htmout_srv_linkz );
}
// document.write( htmout_svc_links );
// document.write( htmout_ko_links );
// document.write( htmout_srv_links );
// var div_ko_links = document.getElementById("div_ko_links");
// var div_ko_links_orig = div_ko_links.innerHTML;
// alert( "BUGS_500 div_ko_links_orig="+div_ko_links_orig );
// div_ko_links.innerHTML = "";
// div_ko_links.appendChild( htmout_ko_links);
// pqpqpqpqpqpqpqpqpqpqpqpqpqpqpqpqpqpqpqpqpqpqpqpqpqpqpqpqpqpqpqpqpqpqpq
//
// getElementById("foo").insertAdjacentHTML
// <!-- beforebegin / before -->
// <p>
// <!-- afterbegin / prepend -->
// foo
// <!-- beforeend / append -->
// </p>
// <!-- afterend / after-->
//
// document.getElementById('foo').insertAdjacentHTML("beforebegin", "<hr>")
// $('#foo').before("<hr>")
// document.getElementById('foo').insertAdjacentHTML("afterend", "<hr>")
// $('#foo').append("<hr>")
// document.getElementById('foo').insertAdjacentHTML("beforeend", "<hr>")
// $('#foo').append("<hr>")
// document.getElementById('foo').insertAdjacentHTML("afterbegin", "<hr>")
// $('#foo').prepend("<hr>")
//
// var btn = document.getElementById('btn'); // The button itself with an ID of 'btn'
// var newButton = '<button>New button</button>'; // New button to be inserted
// btn.insertAdjacentHTML('afterend', newButton);
//
// bdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdbdb
function show_all_links(mode) {
show_svc_links(mode);
show_ko_links(mode);
show_us_links(mode);
show_u_links(mode);
show_now_links(mode);
show_srv_links(mode);
}
</script>
<div id="div_links" >
<hr color=red>
<div id="div_svc_links" > </div>
<hr color=red>
<hr color=white>
<div id="div_ko_links" > </div>
<hr color=white>
<hr color=white>
<div id="div_us_links" > </div>
<hr color=white>
<hr color=white>
<div id="div_u_links" > </div>
<hr color=white>
<hr color=white>
<div id="div_now_links" > </div>
<hr color=white>
<hr color=blue>
<div id="div_srv_links" > </div>
<hr color=blue>
</div>
<div id="div_linkz" >
<hr color=red>
<div id="div_svc_linkz" > </div>
<hr color=red>
<hr color=black>
<div id="div_ko_linkz" > </div>
<hr color=black>
<hr color=black>
<div id="div_us_linkz" > </div>
<hr color=black>
<hr color=black>
<div id="div_u_linkz" > </div>
<hr color=black>
<hr color=black>
<div id="div_now_linkz" > </div>
<hr color=black>
<hr color=blue>
<div id="div_srv_linkz" > </div>
<hr color=blue>
</div>
<div id="div_cfaa" class=ko>
<!--
<style id=style_craa>
body {
// background: url("data:font/ttf;base64,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AEMARABFAEYARwBIAEkASgBLAEwATQBOAE8AUABRAFIAUwBUAFUAVgCjAFcAWABZAJYAWgChAFsAXABdAF4AXwBgAGEAYgBjAGQAZQBmAGcAaABpAGoAawBsAG0AbgBvAHAAcQByAHMAdAB1AHYAdwB4AHkAegB7AHwAfQB+AH8AgACBAIIAgwCEAIUAhgCHAIgAiQCKAIsAjACNAI4AjwCQAJEAkgCTAJQAlQCWAJcAmACZAJoAmwANAJwAnQCeAJ8AoAChAAAAAAAQAAAAqAkIBQABAQMCAwQFAwMEAgQCBQQCAwMDAwQDAgQCAgMEAwIGAwgFBAQEBAIEBAMGBQQEBQQCAwMEBgUEAwICAgQDBgQEAgQFAgQEAgYEAwQEBAICAwMGBQQDAwMFAgICBgYGBgYGCAgEBAQCAgIFBAQEBAQEAwMDAwMEBAQEBAQHBgQEBAICAgQDAwMDAwMDAwMDCAYCAgICAgIBAgIEAgICBgUBBQUAAAoJBQABAQMCBAUGAwMFAgQCBQUCBAMDBAUDAgQCAgMEAwMHAwkGBAQFBAIEBAMHBgUEBgQCBAQEBwUEAwICAwUDBwUEAgUGAgQEAgYFAwUFBQICAwMGBQQDAwMGAwIDBwcHBwcHCQkEBAQCAgIGBQUFBQUFBAQEBAMFBQUFBQUIBwQEBAICAgUDAwMDAwQDAwMDCAcDAwICAgIBAgIEAgICBwUBBQUAAAsKBgACAgQCBAUGAwMFAgQCBgUDBAQEBAUEAwUDAgMEAwMIAwoGBQUFBQIEBQMHBgUEBgUDBAQECAYFAwIDAwUDCAUFAwUGAgQEAgcFBAUFBQMDAwMHBgUDBAQGAwIDCAgICAgICQoFBQUCAgIGBQUFBQUFBAQEBAMFBQUFBQUJCAUFBQICAgUEBAQEBAQDAwMDCQgDAwICAwIBAgIEAgICBwYBBgYAAAwLBgACAgQDBAYHBAQGAgUDBgYDBQQEBAUEAwUDAwQFBAMIAwsHBQUFBQIFBQQIBwYFBwUDBQUFCAYFAwMDAwYDCQYFAwUHAgUFAggGBAYGBgMDBAQHBgUDBAQHAwMDCAgICAgICgsFBQUCAgIHBgYGBgYGBQUFBQMGBgYGBgYJCQUFBQICAgYEBAQEBAQEBAQECggDAwMDAwIBAwMFAwMDCAYBBgYAAA0MBwACAgQDBQYHBAQGAwUDBwYDBQQFBQYEAwYDAwQFBAMJBAwIBgYGBQMFBgQJBwYFCAUDBQUFCQcFBAMDAwYECQYGAwYIAwUFAggGBQYGBgMDBAQIBwYEBAQHAwMDCQkJCQkJCwwGBgYDAwMHBgYGBgYGBQUFBQQGBgYGBgYKCQYGBgMDAwYFBQUFBQUEBAQECwkDAwMDAwIBAwMFAwMDCQcCBwcAAA4NBwACAgUDBQcIBAQHAwUDBwcDBQUFBQYFAwYDAwQFBAQKBAwIBgYGBgMGBgQJCAcGCAYDBQUGCggGBAMDBAcECgcGAwYIAwYGAwkHBQcHBwMDBAQJBwYEBQUIBAMECgoKCgoKDA0GBgYDAwMIBwcHBwcHBQUFBQQHBwcHBwcLCgYGBgMDAwcFBQUFBQUEBAQEDAoEBAMDAwMBAwMGAwMDCQcCBwcAAA8OCAACAgUDBgcIBQUHAwYDCAcDBgUFBQcFBAcEAwUGBQQLBA0JBwcHBgMGBwUKCAcGCQYEBgYGCggGBAMEBAcECwcHBAcJAwYGAwkHBQcHBwQDBQUJCAYEBQUJBAMECwsLCwsLDQ4HBwcDAwMIBwcHBwcHBgYGBgQHBwcHBwcMCwcHBwMDAwcFBQUFBQUFBQUFDQoEBAMDBAMCAwMGAwMDCggCCAgAABAPCAACAgUEBggJBQUIAwYECAgEBgUGBgcFBAcEBAUGBQQLBQ4JBwcHBwMGBwULCQgGCQcEBgYGCwkHBAQEBAgFCwgHBAcJAwcGAwoHBggIBwQEBQUKCAcEBQUJBAMECwsLCwsLDg8HBwcDAwMJCAgICAgIBgYGBgUICAgICAgNCwcHBwMDAwcGBgYGBgYFBQUFDgsEBAQEBAMCAwMGBAQECwgCCAgAABEQCQACAgYEBggJBQUIAwcECQgEBwYGBggGBAcEBAUHBQUMBQ8KBwcIBwMHCAULCggHCgcEBgYHDAkHBQQEBAgFDAgHBAgKAwcHAwsIBggICAQEBQUKCQcFBgYKBAQFDAwMDAwMDxAHCAcDAwMKCAgICAgIBgYGBgUICAgICAgNDAcHBwMDAwgGBgYGBgYFBQUFDgwFBQQEBAMCBAQHBAQECwkCCQkAABIQCQADAwYEBwkKBgYJBAcECQkEBwYGBggGBAgEBAYHBgUNBRAKCAgICAQHCAUMCgkHCwcEBwcHDQoIBQQEBQkFDQkIBAgKBAcHAwsIBgkJCAQEBQYLCQgFBgYKBQQFDQ0NDQ0NDxAICAgEBAQKCQkJCQkJBwcHBwUJCQkJCQkODQgICAQEBAgGBgYGBgYFBQUFDwwFBQQEBAMCBAQHBAQEDAkCCQkAABMRCgADAwYEBwkLBgYJBAcECgkEBwYHBwkGBAgFBAYHBgUNBhELCAgJCAQICAYNCwkICwgEBwcIDQoIBQQFBQkFDQkIBAkLBAgIBAwJBwkJCQQEBgYMCggFBgYLBQQFDQ0NDQ0NEBEICAgEBAQLCQkJCQkJBwcHBwUJCQkJCQkPDQgICAQEBAkHBwcHBwcGBgYGEA0FBQQEBQQCBAQIBAQEDQoCCgoAABQSCgADAwcEBwoLBgYKBAgECgoFCAcHBwkHBQkFBAYIBgUOBhIMCQkJCAQICQYNCwoIDAgFCAgIDgsIBgUFBQoGDgoJBQkMBAgIBA0JBwoKCQUFBgYMCgkGBwcLBQQFDg4ODg4OERIJCQkEBAQLCgoKCgoKCAgICAYKCgoKCgoQDgkJCQQEBAkHBwcHBwcGBgYGEQ4FBQUFBQQCBAQIBQUEDgoCCgoAABUTCwADAwcFCAoMBgYKBAgFCwoFCAcHBwoHBQkFBQYIBgYPBhMMCQkJCQQJCQYODAoIDAkFCAgIDwsJBgUFBQoGDwoJBQoMBAkIBA0KBwoKCgUFBgcNCwkGBwcMBQQGDw8PDw8PEhMJCQkEBAQMCgoKCgoKCAgICAYKCgoKCgoRDwkJCQQEBAoHBwcHBwcGBgYGEg4GBgUFBQQCBAQIBQUFDgsDCwsAABYUCwADAwcFCAsMBwcLBAkFCwoFCAcICAoHBQoFBQcJBwYPBhQNCgoKCQQJCgcPDAoJDQkFCAgJDwwJBgUFBgsGEAsKBQoNBAkJBA4KCAsLCgUFBwcOCwkGBwcNBgUGDw8PDw8PExQKCgoEBAQMCgoKCgoLCAgICAYLCwsLCwsREAoKCgQEBAoICAgICAgHBwcHEw8GBgUFBQQCBQUJBQUFDwsDCwsAABcVDAADAwcFCQsNBwcLBQkFDAsFCQcICAsIBQoGBQcJBwYQBxQNCgoKCgUJCgcPDQsJDQoFCQkJEAwKBgUGBgsHEAsKBQoNBQkJBA4LCAsLCwUFBwcODAoGBwgNBgUGEBAQEBAQFBUKCgoFBQUNCwsLCwsLCQkJCQcLCwsLCwsSEAoKCgUFBQsICAgICAgHBwcHFBAGBgUFBgQCBQUJBQUFEAwDDAwAABgWDAADAwgFCQwNBwcMBQkFDAsGCQgICAsIBgoGBQcJBwYRBxUOCgoLCgUKCwcQDgsKDgoGCQkKEQ0KBwUGBgsHEQwKBgsOBQoKBA8LCAwMCwYGBwgPDAoHCAgOBgUGERERERERFRYKCwoFBQUOCwsLCwsMCQkJCQcLCwsLCwsTEQoKCgUFBQsICAgICAgHBwcHFBEGBgUFBgQCBQUKBQUFEAwDDAwAAAABAV0BkAAFAAICvAKKAAAAjwK8AooAAAHFADIBAwAAAAAEAAAAAAAAAAAAAAMAAAAAAAAAAAAAAABNQUNSAEAAICIZAyH/OQAAAyEAxwAAAAEAAAAAAAAAAQAAgAAAAACLAT8AAGAAAbQCdVlva2ttb2trICAgICAgICD/////N////llPS1IwMAAAAAAAAAABAAAAAQAAmJpL9V8PPPUAAAPoAAAAALfnFZIAAAAAt+cVkv+2/zkDawMhAAAAAwACAAEAAAAAAAEAAAMh/zkAAAOQ/7b/uANrAAEAAAAAAAAAAAAAAAAAAACkAAEAAACkAJgADQAAAAAAAgAIAEAACgAAAF0AvgABAAE=");
background-color: darkslategrey;
color: white;
font-size:62.5%;
// font-family: yokkmokkOT;
font-size: 38pt;
}
</style>
<script id=script_htm>
if( url.pathname == "/index_sc.htm" ) {
body { background-color: slategrey; color: white; }
}
</script>
<script id=script_cfaa>
</script>
-->
<script id="script_cfaa">
var text_cfaa =
`
pqpqpqpqpqpqpqpqpqpq Warning pqpqpqpqpqpqpqpqpqpq<br>
<br>
This site may be protected under the
<br>
<br>
<b>CFAA</b>
<br>
Computer Fraud and Abuse Act
<br>
<br>
your attemped access has been logged
<br>
repeated attemps by unauthorized guests will be reported
<br>
<br>
By continuing You are acknowledging
<br>
you are fully authorized and
<br>
understand the responsibilites to access the content on the site
<br>
<br>
This page must not be removed
<br>
bdbdbdbdbdbdbdbdbdbd Warning bdbdbdbdbdbdbdbdbdbd
<br>
<br>
unauthoriced users should
<br>
consider browsing elsewhere:
<hr color=black>
<hr color=ivory>
<hr color=red>
<hr color=blue>
<hr color=ebony>
<hr color=white>
<a href=duckduckgo.com > <img src="ok.png" alt="duckduckgo" height=10 border=0></a>
     
<a href=bing.com > <img src="ok.png" alt="bing" height=10 border=0></a>
     
<a href=google.com > <img src="ok.png" alt="google" height=10 border=0></a>
     
<a href=yahoo.com > <img src="ok.png" alt="yahoo" height=10 border=0></a>
     
<a href=https://mars.jpl.nasa.gov/msl/multimedia/raw target=_blank>
<img src="ok.png" border=0 height=10>
</a>
     
<a href=http://youtube.com target=_blank>
<img src="ok.png" border=0 height=10>
</a>
<hr color=white>
<hr color=ebony>
<hr color=blue>
<hr color=red>
<hr color=ivory>
<hr color=black>
<div id=warn2 class=ko>
<p id=p_warn2 class=ko>
<hr color=black>
<hr color=white>
<hr color=red>
If you are seeing this page
<br>
you are probably unauthorized
<br>
you should <b>NOT</b> continue
<br>
accessing site content here may be
<br>
protected under <b>CFAA</b>
<hr color=red>
<hr color=white>
<hr color=black>
</p>
authorized sites are available from bluehost
<a href=http://bluehost.com/track/konet/ko2.us target=_blank>
<img src=./imgs/bh/bh_anim.gif height=30 border=0 alt=bluehost.com affiliate></a>
<div id=kobh_offer class=ko>
bluehost offers
50 gb space
999 gb bandwidth
6 domains on 1 account
and more for only $6.95/month
</div>
</div>
<script id="script_url">
var url = document.createElement("a");
url.href=location.href
var output = "output"
url.pathname = url.pathname.replace(/(^\/?)/,"/");
// alert(location.href)
// alert(url.protocol)
// alert(url.hostname)
// alert(url.pathname)
// alert(url.search)
// alert(url.hash)
if( url.search == "" ) {document.write( text_cfaa );}
if( url.search == "?q=cfaa" ) {document.write( text_cfaa ); }
</script>
</div>
<!--
<iframe id="myframe" src="./svc/kokbdm/index_sc.html" width="1000" height="500"
frameborder="0" scrolling="yes"></iframe>
-->
<hr color=red><hr color=black><hr color=white>
<button type="button" onclick="show_all_links('pop')">show_all_links</button>
<!-- <button type="button" id="upload" value="Upload" onclick="Upload()">upload</button> -->
<hr color=red><hr color=white><hr color=blue>
<button type="button" onclick="show_svc_links('pop')">show_svc_links</button>
<button type="button" onclick="show_ko_links('pop')">show_ko_links</button>
<button type="button" onclick="show_us_links('pop')">show_us_links</button>
<button type="button" onclick="show_u_links('pop')">show_u_links</button>
<button type="button" onclick="show_now_links('pop')">show_now_links</button>
<button type="button" onclick="show_srv_links('pop')">show_srv_links</button>
<hr color=blue><hr color=white><hr color=black>
<!--
<img src="./imgs/btn/kib.png" height="50" size="150" alt="koeye" onclick="show_svc_links()">
<img src="./imgs/btn/ko.png" height="50" size="150" alt="koeyeb" onclick="show_ko_links()">
<img src="./imgs/btn/ko.png" height="50" size="150" alt="koeyeb" onclick="show_us_links()">
<img src="./imgs/btn/ko.png" height="50" size="150" alt="koeyeb" onclick="show_u_links()">
<img src="./imgs/btn/ko.png" height="50" size="150" alt="koeyeb" onclick="show_now_links()">
<img src="./imgs/btn/kiw.png" height="50" size="150" alt="koeyew" onclick="show_srv_links()">
-->
<a href=# class="popover" onclick="show_svc_links();">
<img src="./imgs/btn/kib.png" height="100" width="200" alt="koeyew" >
<span><img src="./imgs/btn/kiw.png" height="100" width="200" alt="koeyew" ></span>
</a>
<a href=# class="popover" onclick="show_ko_links();">
<img src="./imgs/btn/ko.png" height="100" size="200" alt="koeyeb" >
<span><img src="./imgs/btn/ok.png" height="100" size="200" alt="koeyeb" ></span>
</a>
<a href=# class="popover" onclick="show_us_links();">
<img src="./imgs/btn/ko.png" height="100" size="200" alt="koeyeb" >
<span><img src="./imgs/btn/ok.png" height="100" size="200" alt="koeyeb" ></span>
</a>
<a href=# class="popover" onclick="show_u_links();">
<img src="./imgs/btn/ko.png" height="100" size="200" alt="koeyeb" >
<span><img src="./imgs/btn/ok.png" height="100" size="200" alt="koeyeb" ></span>
</a>
<a href=# class="popover" onclick="show_now_links();">
<img src="./imgs/btn/ko.png" height="100" size="200" alt="koeyeb" >
<span><img src="./imgs/btn/ok.png" height="100" size="200" alt="koeyeb" ></span>
</a>
<a href=# class="popover" onclick="show_srv_links();">
<img src="./imgs/btn/kiw.png" height="100" width="200" alt="koeyew" >
<span><img src="./imgs/btn/kib.png" height="100" width="200" alt="koeyew" ></span>
</a>
<hr color=blue><hr color=white><hr color=red>
<div id="div_neave_im" >
<iframe frameborder='0' height='250' marginheight='0' marginwidth='0' scrolling='no'
src='/index_neave_im.html'
style='margin-bottom: 20px; box-shadow: 0 2px 2px rgba(0,0,0,0.3)' width='100%'>
</iframe>
<a class="popover" href="/index_neave_im.html" target=_blank>
<img height=50 width=1600 src="/imgs/links/index_neave_im.png" alt="index_neave_im" border=0>
<span><img height=50 width=1600 src="/imgs/links/index_neave_im_pop.png" border=0></span>
</a>
</div>
<div id="div_neave_wobble" >
<a class="popover" href="/index_neave_wobble.html" target=_blank>
<img height=50 width=1600 src="/imgs/links/index_neave_wobble.png" alt="index_neave_wobble" border=0>
<span><img height=50 width=1600 src="/imgs/links/index_neave_wobble_pop.png" border=0></span>
</a>
<iframe frameborder='0' height='150' marginheight='0' marginwidth='0' scrolling='no'
src='/index_neave_wobble.html'
style='margin-bottom: 20px; box-shadow: 0 2px 2px rgba(0,0,0,0.3)' width='100%'>
</iframe>
</div>
<div id="div_files" >
<output id="zonelist"></output>
<div id="dropzone">
dropzone
<div id="div_canvas" style="position:relative; width:400px; height:200px background:white">
<canvas id="canvas_dropzone" style="z-index_sc: 1;
position:absolute;
left:0px;
top:0px;
" height="100px" width="200" background-color="white" color="white">
WARN_1387 unauthorized access has been logged
</canvas>
</div>
<script name="script_fileselect">
function handleFileSelect(evt) {
evt.stopPropagation();
evt.preventDefault();
var files = evt.dataTransfer.files; // FileList object.
// files is a FileList of File objects. List some properties.
var output = [];
for (var i = 0, f; f = files[i]; i++) {
output.push('<li><strong>', escape(f.name), '</strong> (', f.type || 'n/a', ') - ',
f.size, ' bytes, last modified: ',
f.lastModifiedDate ? f.lastModifiedDate.toLocaleDateString() : 'n/a',
'</li>');
}
document.getElementById('zonelist').innerHTML = '<ul>' + output.join('') + '</ul>';
}
function handleDragOver(evt) {
evt.stopPropagation();
evt.preventDefault();
evt.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy.
}
// Setup the dnd listeners.
var dropZone = document.getElementById('dropzone');
dropZone.addEventListener('dragover', handleDragOver, false);
dropZone.addEventListener('drop', handleFileSelect, false);
</script>
<hr><hr><hr>
<style>
.thumb {
height: 75px;
border: 1px solid #000;
margin: 10px 5px 0 0;
}
</style>
<label class="fileContainer">
files
<input id="files" name="files[]" multiple="" type="file">
</label>
<output id="zonelist"></output>
<script>
function handleFileSelect(evt) {
var files = evt.target.files; // FileList object
// files is a FileList of File objects. List some properties.
var output = [];
for (var i = 0, f; f = files[i]; i++) {
output.push('<li><strong>', escape(f.name), '</strong> (', f.type || 'n/a', ') - ',
f.size, ' bytes, last modified: ',
f.lastModifiedDate ? f.lastModifiedDate.toLocaleDateString() : 'n/a',
'</li>');
}
document.getElementById('zonelist').innerHTML = '<ul>' + output.join('') + '</ul>';
}
document.getElementById('files').addEventListener('change', handleFileSelect, false);
</script>
<div id="div_files2" hidden >
<label class="fileContainer">
files2
<input id="files" name="files[]" multiple="" type="file">
</label>
<output id="zonelist"></output>
</div>
<script>
function handleFileSelect(evt) {
var files = evt.target.files; // FileList object
// Loop through the FileList and render image files as thumbnails.
for (var i = 0, f; f = files[i]; i++) {
// Only process image files.
if (!f.type.match('image.*')) { continue; }
var reader = new FileReader();
// Closure to capture the file information.
reader.onload = (function(theFile) {
return function(e) {
// Render thumbnail.
var span = document.createElement('span');
span.innerHTML = ['<img class="thumb" src="', e.target.result,
'" title="', escape(theFile.name), '"/>'].join('');
document.getElementById('zonelist').insertBefore(span, null);
};
})(f);
// Read in the image file as a data URL.
reader.readAsDataURL(f);
}
}
document.getElementById('files').addEventListener('change', handleFileSelect, false);
</script>
<hr color=black><hr color=black><hr color=black>
<style>
#byte_content {
margin: 5px 0;
max-height: 100px;
overflow-y: auto;
overflow-x: hidden;
}
#byte_range { margin-top: 5px; }
</style>
<script id="script_previewfile">
function previewfile(file) {
if (tests.filereader === true && acceptedTypes[file.type] === true) {
var reader = new FileReader();
reader.onload = function (event) {
var image = new Image();
image.src = event.target.result;
image.width = 250; // a fake resize
holder.appendChild(image);
};
reader.readAsDataURL(file);
}
else {
holder.innerHTML +=
'<p>done: koupload'
+ file.name
+ ' '
+ (file.size ? (file.size/1024|0) + 'K' : '');
console.log(file);
}
}
function readfiles(files) {
debugger;
var formData = tests.formdata ? new FormData() : null;
for (var i = 0; i < files.length; i++) {
if (tests.formdata) formData.append('file', files[i]);
previewfile(files[i]);
}
// now post a new XHR request
if (tests.formdata) {
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://ka6/ko/bin/php/ko.php?ko=ajax,upload,filenames,phpi,ok');
// xhr.open('POST', 'ka6/ko/bin/php/index_sc.php?q=upload,filenames');
xhr.onload = function() {
progress.value = progress.innerHTML = 100;
};
if (tests.progress) {
xhr.upload.onprogress = function (event) {
if (event.lengthComputable) {
var complete = (event.loaded / event.total * 100 | 0);
progress.value = progress.innerHTML = complete;
}
}
}
xhr.send(formData);
}
}
if (tests.dnd) {
holder.ondragover = function () { this.className = 'hover'; return false; };
holder.ondragend = function () { this.className = ''; return false; };
holder.ondrop = function (e) {
this.className = '';
e.preventDefault();
readfiles(e.dataTransfer.files);
}
}
else {
fileupload.className = 'hidden';
fileupload.querySelector('input').onchange = function () {
readfiles(this.files);
};
}
</script>
<script id="script_myfilework>
funtion myfilework( j, file ) {
alert( j+" file="+file );
}
</script>
<script id="script_upload_input">>
var upload = document.getElementsByTagName('input')[0],
holder2 = document.getElementById('holder2'),
state = document.getElementById('status');
if (typeof window.FileReader === 'undefined') {
state.className = 'fail';
}
else {
state.className = 'success';
state.innerHTML = 'File API & FileReader available';
}
upload.onchange = function (e) {
e.preventDefault();
var file = upload.files[0],
reader = new FileReader();
reader.onload = function (event) {
var img = new Image();
img.src = event.target.result;
// note: no onload required since we've got the dataurl...I think! :)
if (img.width > 560) { // holder width
img.width = 560;
}
holder2.innerHTML = '';
holder.appendChild(img);
};
reader.readAsDataURL(file);
return false;
};
// var formData = new FormData();
// formData.append("part_num", "123ABC");
// formData.append("part_price", 7.95);
// formData.append("part_image", somefile)
//
// var xhr = new XMLHttpRequest();
// xhr.open("POST", "http://ka6/ko/bin/php/ko.php?ko=ajax,upload/");
// xhr.send(formData);
</script>
<canvas color="darkslatgrey" height="100" width="400"></canvas>
<script>
var canvas = document.getElementsByTagName('canvas')[0],
ctx = null,
grad = null,
body = document.getElementsByTagName('body')[0],
color = 255;
color = lightblue;
if (canvas.getContext('2d')) {
ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, 600, 600);
ctx.save();
// Create radial gradient
// grad = ctx.createRadialGradient(0,0,0,0,0,600);
// grad.addColorStop(0, '#000');
// grad.addColorStop(1, 'rgb(' + color + ', ' + color + ', ' + color + ')');
// assign gradients to fill
// ctx.fillStyle = grad;
ctx.fillstyle = "lightblue";
// draw 600x600 fill
ctx.fillRect(0,0,600,600);
ctx.save();
body.onmousemove = function (event) {
var width = window.innerWidth,
height = window.innerHeight,
x = event.clientX,
y = event.clientY,
rx = 600 * x / width,
ry = 600 * y / height;
var xc = ~~(256 * x / width);
var yc = ~~(256 * y / height);
grad = ctx.createRadialGradient(rx, ry, 0, rx, ry, 600);
grad.addColorStop(0, '#000');
grad.addColorStop(1, ['rgb(', xc, ', ', (255 - xc), ', ', yc, ')'].join(''));
// ctx.restore();
// ctx.fillStyle = grad;
ctx.fillstyle="lightblue";
ctx.fillRect(0,0,600,600);
// ctx.save();
};
}
</script>
<div id="div_csv">
<style type="text/css">
body {
font-family: Arial;
font-size: 10pt;
}
table {
border: 1px solid #ccc;
}
table th {
background-color: #F7F7F7;
color: #333;
font-weight: bold;
}
table th, table td {
padding: 5px;
border-color: #ccc;
}
</style>
<script type="text/javascript">
function Upload() {
var fileUpload = document.getElementById("fileUpload");
var regex = /^([a-zA-Z0-9\s_\\.\-:])+(.csv|.txt|.psv|.py|.htm|.html|.php)$/;
if (regex.test(fileUpload.value.toLowerCase())) {
if (typeof (FileReader) != "undefined") {
var reader = new FileReader();
reader.onload = function (e) {
var table = document.createElement("table");
var rows = e.target.result.split("\n");
for (var i = 0; i < rows.length; i++) {
var row = table.insertRow(-1);
// var cells = rows[i].split("|");
var cells = rows[i].split(",");
for (var j = 0; j < cells.length; j++) {
var cell = row.insertCell(-1);
cell.innerHTML = cells[j];
}
}
var csv2tbl = document.getElementById("csv2tbl");
csv2tbl.innerHTML = "";
csv2tbl.appendChild(table);
}
reader.readAsText(fileUpload.files[0]);
}
else {
alert("csv2tbl warn: unauthorized access noted");
}
}
else {
alert("csv2tbl fail: unsuppoted format");
}
}
</script>
<label class="fileContainer">
files_csv_psv_ssv_tsv
<input id="fileUpload" type="file">
</label>
     
<label class="fileContainer">
parse_csv_psv_ssv_tsv
<input id="upload" value="Upload" onclick="Upload()" type="button">
</label>
</div>
<div id="csv2tbl"> </div>
<!-- <button type="button" id="fileUpload" type="file" >select</button> -->
<!-- <button type="button" id="upload" value="Upload" onclick="Upload()">upload</button> -->
</div>
</div>
<div id="div_showhide" hidden>
<script id="script_showhide" >
function show_files() {
var div_files = document.getElementbyID("div_files");
div_files.show();
}
function hide_files() {
var div_files = document.getElementbyID("div_files");
div_files.hide();
}
</script>
<button type="button" id="show">show</button>
<button type="button" id="hide">hide</button>
<button type="show_files" id="show_files" onclick="show_files()">Show_files</button>
<button type="hide_files" id="hide_files" onclick="hide_files()">Hide_files</button>
<button type="show_neave_wobble" id="show_neave_wobble">Show_neave_wobble</button>
<button type="hide_neave_wobble" id="hide_neave_wobble">Hide_neave_wobble</button>
<!--
<button type="show_dd" id="show_dd">Show_dd</button>
<button type="hide_dd" id="hide_dd">Hide_dd</button>
<button type="show_bb" id="show_bb">Show_bb</button>
<button type="hide_bb" id="hide_bb">Hide_bb</button>
<button type="show_tl" id="show_tl">Show_tl</button>
<button type="hide_tl" id="hide_tl">Hide_tl</button>
<button type="show_colors" id="show_colors">Show_colors</button>
<button type="hide_colors" id="hide_colors">Hide_colors</button>
<button type="show_fonts" id="show_fonts">Show_fonts</button>
<button type="hide_fonts" id="hide_fonts">Hide_fonts</button>
<button type="show_alldivs" id="show_alldivs">Show_alldivs</button>
<button type="hide_alldivs" id="hide_alldivs">Hide_alldivs</button>
-->
</div>
<div id="item" > </div>
<script id="script_showhide">
$( "#show" ).click(function() {$('#item').show(); });
$( "#hide" ).click(function() {$('#item').hide();});
$( "#show_files" ).click(function() {$('#div_files').show(); });
$( "#hide_files" ).click(function() {$('#div_files').hide();});
$( "#show_neave_wobble" ).click(function() {$('#div_neave_wobble').show(); });
$( "#hide_neave_wobble" ).click(function() {$('#div_neave_wobble').hide();});
// $( "#show_dd" ).click(function() {$('#div_dd').show(); });
// $( "#hide_dd" ).click(function() {$('#div_dd').hide();});
// $( "#show_bb" ).click(function() {$('#div_bb').show(); });
// $( "#hide_bb" ).click(function() {$('#div_bb').hide();});
// $( "#show_tl" ).click(function() {$('#div_tl').show(); });
// $( "#hide_tl" ).click(function() {$('#div_tl').hide();});
// $( "#show_jkwii" ).click(function() {$('#div_jkwii').show(); });
// $( "#hide_jkwii" ).click(function() {$('#div_jkwii').hide();});
// $( "#show_colors" ).click(function() {$('#div_colors').show(); });
// $( "#hide_colors" ).click(function() {$('#div_colors').hide();});
// $( "#show_fonts" ).click(function() {$('#div_fonts').show(); });
// $( "#hide_fonts" ).click(function() {$('#div_fonts').hide();});
// $( "#show_alldivs" ).click(function() {$('#div_alldivs').show(); });
// $( "#hide_alldivs" ).click(function() {$('#div_alldivs').hide();});
</script>
</div>
<!--[if IE]>
<!-- <script src="https://html5shiv.googlecode.com/svn/trunk/html5.js"></script> -->
<![endif]-->
<div class="la-anim-10" hidden></div>
<!-- .corner-preloader -->
<div id="wrapper" hidden>
<div id="upload-widget">
<h1>
<i class="fa fa-cloud-upload"></i> File Uploader
</h1>
<form id="file-upload-form">
<div class="file-input-wrap">
fups
<input type="file" name="file" id="file" multiple>
</div><!-- .file-input-wrap -->
</form><!-- #file-upload-form -->
</div><!-- #upload-widget -->
<div id="upload-result">
</div><!-- #upload-result -->
</div><!-- #wrapper -->
<div id="preloader">
<img height=50 src="./imgs/btn/kob.png" alt="preloader_up" />
</a>
</div>
<!-- SCRIPTS -->
<!-- <script type="text/javascript" src="js/libraries/jquery-2.1.1.min.js"></script> -->
<!-- <script type="text/javascript" src="./jquery-3.3.1.js" > -->
<script type="text/javascript" src="data:/text/plain;base64,LyohCiAqIGpRdWVyeSBKYXZhU2NyaXB0IExpYnJhcnkgdjMuMy4xCiAqIGh0dHBzOi8vanF1ZXJ5LmNvbS8KICoKICogSW5jbHVkZXMgU2l6emxlLmpzCiAqIGh0dHBzOi8vc2l6emxlanMuY29tLwogKgogKiBDb3B5cmlnaHQgSlMgRm91bmRhdGlvbiBhbmQgb3RoZXIgY29udHJpYnV0b3JzCiAqIFJlbGVhc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZQogKiBodHRwczovL2pxdWVyeS5vcmcvbGljZW5zZQogKgogKiBEYXRlOiAyMDE4LTAxLTIwVDE3OjI0WgogKi8KKCBmdW5jdGlvbiggZ2xvYmFsLCBmYWN0b3J5ICkgewoKCSJ1c2Ugc3RyaWN0IjsKCglpZiAoIHR5cGVvZiBtb2R1bGUgPT09ICJvYmplY3QiICYmIHR5cGVvZiBtb2R1bGUuZXhwb3J0cyA9PT0gIm9iamVjdCIgKSB7CgoJCS8vIEZvciBDb21tb25KUyBhbmQgQ29tbW9uSlMtbGlrZSBlbnZpcm9ubWVudHMgd2hlcmUgYSBwcm9wZXIgYHdpbmRvd2AKCQkvLyBpcyBwcmVzZW50LCBleGVjdXRlIHRoZSBmYWN0b3J5IGFuZCBnZXQgalF1ZXJ5LgoJCS8vIEZvciBlbnZpcm9ubWVudHMgdGhhdCBkbyBub3QgaGF2ZSBhIGB3aW5kb3dgIHdpdGggYSBgZG9jdW1lbnRgCgkJLy8gKHN1Y2ggYXMgTm9kZS5qcyksIGV4cG9zZSBhIGZhY3RvcnkgYXMgbW9kdWxlLmV4cG9ydHMuCgkJLy8gVGhpcyBhY2NlbnR1YXRlcyB0aGUgbmVlZCBmb3IgdGhlIGNyZWF0aW9uIG9mIGEgcmVhbCBgd2luZG93YC4KCQkvLyBlLmcuIHZhciBqUXVlcnkgPSByZXF1aXJlKCJqcXVlcnkiKSh3aW5kb3cpOwoJCS8vIFNlZSB0aWNrZXQgIzE0NTQ5IGZvciBtb3JlIGluZm8uCgkJbW9kdWxlLmV4cG9ydHMgPSBnbG9iYWwuZG9jdW1lbnQgPwoJCQlmYWN0b3J5KCBnbG9iYWwsIHRydWUgKSA6CgkJCWZ1bmN0aW9uKCB3ICkgewoJCQkJaWYgKCAhdy5kb2N1bWVudCApIHsKCQkJCQl0aHJvdyBuZXcgRXJyb3IoICJqUXVlcnkgcmVxdWlyZXMgYSB3aW5kb3cgd2l0aCBhIGRvY3VtZW50IiApOwoJCQkJfQoJCQkJcmV0dXJuIGZhY3RvcnkoIHcgKTsKCQkJfTsKCX0gZWxzZSB7CgkJZmFjdG9yeSggZ2xvYmFsICk7Cgl9CgovLyBQYXNzIHRoaXMgaWYgd2luZG93IGlzIG5vdCBkZWZpbmVkIHlldAp9ICkoIHR5cGVvZiB3aW5kb3cgIT09ICJ1bmRlZmluZWQiID8gd2luZG93IDogdGhpcywgZnVuY3Rpb24oIHdpbmRvdywgbm9HbG9iYWwgKSB7CgovLyBFZGdlIDw9IDEyIC0gMTMrLCBGaXJlZm94IDw9MTggLSA0NSssIElFIDEwIC0gMTEsIFNhZmFyaSA1LjEgLSA5KywgaU9TIDYgLSA5LjEKLy8gdGhyb3cgZXhjZXB0aW9ucyB3aGVuIG5vbi1zdHJpY3QgY29kZSAoZS5nLiwgQVNQLk5FVCA0LjUpIGFjY2Vzc2VzIHN0cmljdCBtb2RlCi8vIGFyZ3VtZW50cy5jYWxsZWUuY2FsbGVyICh0cmFjLTEzMzM1KS4gQnV0IGFzIG9mIGpRdWVyeSAzLjAgKDIwMTYpLCBzdHJpY3QgbW9kZSBzaG91bGQgYmUgY29tbW9uCi8vIGVub3VnaCB0aGF0IGFsbCBzdWNoIGF0dGVtcHRzIGFyZSBndWFyZGVkIGluIGEgdHJ5IGJsb2NrLgoidXNlIHN0cmljdCI7Cgp2YXIgYXJyID0gW107Cgp2YXIgZG9jdW1lbnQgPSB3aW5kb3cuZG9jdW1lbnQ7Cgp2YXIgZ2V0UHJvdG8gPSBPYmplY3QuZ2V0UHJvdG90eXBlT2Y7Cgp2YXIgc2xpY2UgPSBhcnIuc2xpY2U7Cgp2YXIgY29uY2F0ID0gYXJyLmNvbmNhdDsKCnZhciBwdXNoID0gYXJyLnB1c2g7Cgp2YXIgaW5kZXhPZiA9IGFyci5pbmRleE9mOwoKdmFyIGNsYXNzMnR5cGUgPSB7fTsKCnZhciB0b1N0cmluZyA9IGNsYXNzMnR5cGUudG9TdHJpbmc7Cgp2YXIgaGFzT3duID0gY2xhc3MydHlwZS5oYXNPd25Qcm9wZXJ0eTsKCnZhciBmblRvU3RyaW5nID0gaGFzT3duLnRvU3RyaW5nOwoKdmFyIE9iamVjdEZ1bmN0aW9uU3RyaW5nID0gZm5Ub1N0cmluZy5jYWxsKCBPYmplY3QgKTsKCnZhciBzdXBwb3J0ID0ge307Cgp2YXIgaXNGdW5jdGlvbiA9IGZ1bmN0aW9uIGlzRnVuY3Rpb24oIG9iaiApIHsKCiAgICAgIC8vIFN1cHBvcnQ6IENocm9tZSA8PTU3LCBGaXJlZm94IDw9NTIKICAgICAgLy8gSW4gc29tZSBicm93c2VycywgdHlwZW9mIHJldHVybnMgImZ1bmN0aW9uIiBmb3IgSFRNTCA8b2JqZWN0PiBlbGVtZW50cwogICAgICAvLyAoaS5lLiwgYHR5cGVvZiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCAib2JqZWN0IiApID09PSAiZnVuY3Rpb24iYCkuCiAgICAgIC8vIFdlIGRvbid0IHdhbnQgdG8gY2xhc3NpZnkgKmFueSogRE9NIG5vZGUgYXMgYSBmdW5jdGlvbi4KICAgICAgcmV0dXJuIHR5cGVvZiBvYmogPT09ICJmdW5jdGlvbiIgJiYgdHlwZW9mIG9iai5ub2RlVHlwZSAhPT0gIm51bWJlciI7CiAgfTsKCgp2YXIgaXNXaW5kb3cgPSBmdW5jdGlvbiBpc1dpbmRvdyggb2JqICkgewoJCXJldHVybiBvYmogIT0gbnVsbCAmJiBvYmogPT09IG9iai53aW5kb3c7Cgl9OwoKCgoKCXZhciBwcmVzZXJ2ZWRTY3JpcHRBdHRyaWJ1dGVzID0gewoJCXR5cGU6IHRydWUsCgkJc3JjOiB0cnVlLAoJCW5vTW9kdWxlOiB0cnVlCgl9OwoKCWZ1bmN0aW9uIERPTUV2YWwoIGNvZGUsIGRvYywgbm9kZSApIHsKCQlkb2MgPSBkb2MgfHwgZG9jdW1lbnQ7CgoJCXZhciBpLAoJCQlzY3JpcHQgPSBkb2MuY3JlYXRlRWxlbWVudCggInNjcmlwdCIgKTsKCgkJc2NyaXB0LnRleHQgPSBjb2RlOwoJCWlmICggbm9kZSApIHsKCQkJZm9yICggaSBpbiBwcmVzZXJ2ZWRTY3JpcHRBdHRyaWJ1dGVzICkgewoJCQkJaWYgKCBub2RlWyBpIF0gKSB7CgkJCQkJc2NyaXB0WyBpIF0gPSBub2RlWyBpIF07CgkJCQl9CgkJCX0KCQl9CgkJZG9jLmhlYWQuYXBwZW5kQ2hpbGQoIHNjcmlwdCApLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoIHNjcmlwdCApOwoJfQoKCmZ1bmN0aW9uIHRvVHlwZSggb2JqICkgewoJaWYgKCBvYmogPT0gbnVsbCApIHsKCQlyZXR1cm4gb2JqICsgIiI7Cgl9CgoJLy8gU3VwcG9ydDogQW5kcm9pZCA8PTIuMyBvbmx5IChmdW5jdGlvbmlzaCBSZWdFeHApCglyZXR1cm4gdHlwZW9mIG9iaiA9PT0gIm9iamVjdCIgfHwgdHlwZW9mIG9iaiA9PT0gImZ1bmN0aW9uIiA/CgkJY2xhc3MydHlwZVsgdG9TdHJpbmcuY2FsbCggb2JqICkgXSB8fCAib2JqZWN0IiA6CgkJdHlwZW9mIG9iajsKfQovKiBnbG9iYWwgU3ltYm9sICovCi8vIERlZmluaW5nIHRoaXMgZ2xvYmFsIGluIC5lc2xpbnRyYy5qc29uIHdvdWxkIGNyZWF0ZSBhIGRhbmdlciBvZiB1c2luZyB0aGUgZ2xvYmFsCi8vIHVuZ3VhcmRlZCBpbiBhbm90aGVyIHBsYWNlLCBpdCBzZWVtcyBzYWZlciB0byBkZWZpbmUgZ2xvYmFsIG9ubHkgZm9yIHRoaXMgbW9kdWxlCgoKCnZhcgoJdmVyc2lvbiA9ICIzLjMuMSIsCgoJLy8gRGVmaW5lIGEgbG9jYWwgY29weSBvZiBqUXVlcnkKCWpRdWVyeSA9IGZ1bmN0aW9uKCBzZWxlY3RvciwgY29udGV4dCApIHsKCgkJLy8gVGhlIGpRdWVyeSBvYmplY3QgaXMgYWN0dWFsbHkganVzdCB0aGUgaW5pdCBjb25zdHJ1Y3RvciAnZW5oYW5jZWQnCgkJLy8gTmVlZCBpbml0IGlmIGpRdWVyeSBpcyBjYWxsZWQgKGp1c3QgYWxsb3cgZXJyb3IgdG8gYmUgdGhyb3duIGlmIG5vdCBpbmNsdWRlZCkKCQlyZXR1cm4gbmV3IGpRdWVyeS5mbi5pbml0KCBzZWxlY3RvciwgY29udGV4dCApOwoJfSwKCgkvLyBTdXBwb3J0OiBBbmRyb2lkIDw9NC4wIG9ubHkKCS8vIE1ha2Ugc3VyZSB3ZSB0cmltIEJPTSBhbmQgTkJTUAoJcnRyaW0gPSAvXltcc1x1RkVGRlx4QTBdK3xbXHNcdUZFRkZceEEwXSskL2c7CgpqUXVlcnkuZm4gPSBqUXVlcnkucHJvdG90eXBlID0gewoKCS8vIFRoZSBjdXJyZW50IHZlcnNpb24gb2YgalF1ZXJ5IGJlaW5nIHVzZWQKCWpxdWVyeTogdmVyc2lvbiwKCgljb25zdHJ1Y3RvcjogalF1ZXJ5LAoKCS8vIFRoZSBkZWZhdWx0IGxlbmd0aCBvZiBhIGpRdWVyeSBvYmplY3QgaXMgMAoJbGVuZ3RoOiAwLAoKCXRvQXJyYXk6IGZ1bmN0aW9uKCkgewoJCXJldHVybiBzbGljZS5jYWxsKCB0aGlzICk7Cgl9LAoKCS8vIEdldCB0aGUgTnRoIGVsZW1lbnQgaW4gdGhlIG1hdGNoZWQgZWxlbWVudCBzZXQgT1IKCS8vIEdldCB0aGUgd2hvbGUgbWF0Y2hlZCBlbGVtZW50IHNldCBhcyBhIGNsZWFuIGFycmF5CglnZXQ6IGZ1bmN0aW9uKCBudW0gKSB7CgoJCS8vIFJldHVybiBhbGwgdGhlIGVsZW1lbnRzIGluIGEgY2xlYW4gYXJyYXkKCQlpZiAoIG51bSA9PSBudWxsICkgewoJCQlyZXR1cm4gc2xpY2UuY2FsbCggdGhpcyApOwoJCX0KCgkJLy8gUmV0dXJuIGp1c3QgdGhlIG9uZSBlbGVtZW50IGZyb20gdGhlIHNldAoJCXJldHVybiBudW0gPCAwID8gdGhpc1sgbnVtICsgdGhpcy5sZW5ndGggXSA6IHRoaXNbIG51bSBdOwoJfSwKCgkvLyBUYWtlIGFuIGFycmF5IG9mIGVsZW1lbnRzIGFuZCBwdXNoIGl0IG9udG8gdGhlIHN0YWNrCgkvLyAocmV0dXJuaW5nIHRoZSBuZXcgbWF0Y2hlZCBlbGVtZW50IHNldCkKCXB1c2hTdGFjazogZnVuY3Rpb24oIGVsZW1zICkgewoKCQkvLyBCdWlsZCBhIG5ldyBqUXVlcnkgbWF0Y2hlZCBlbGVtZW50IHNldAoJCXZhciByZXQgPSBqUXVlcnkubWVyZ2UoIHRoaXMuY29uc3RydWN0b3IoKSwgZWxlbXMgKTsKCgkJLy8gQWRkIHRoZSBvbGQgb2JqZWN0IG9udG8gdGhlIHN0YWNrIChhcyBhIHJlZmVyZW5jZSkKCQlyZXQucHJldk9iamVjdCA9IHRoaXM7CgoJCS8vIFJldHVybiB0aGUgbmV3bHktZm9ybWVkIGVsZW1lbnQgc2V0CgkJcmV0dXJuIHJldDsKCX0sCgoJLy8gRXhlY3V0ZSBhIGNhbGxiYWNrIGZvciBldmVyeSBlbGVtZW50IGluIHRoZSBtYXRjaGVkIHNldC4KCWVhY2g6IGZ1bmN0aW9uKCBjYWxsYmFjayApIHsKCQlyZXR1cm4galF1ZXJ5LmVhY2goIHRoaXMsIGNhbGxiYWNrICk7Cgl9LAoKCW1hcDogZnVuY3Rpb24oIGNhbGxiYWNrICkgewoJCXJldHVybiB0aGlzLnB1c2hTdGFjayggalF1ZXJ5Lm1hcCggdGhpcywgZnVuY3Rpb24oIGVsZW0sIGkgKSB7CgkJCXJldHVybiBjYWxsYmFjay5jYWxsKCBlbGVtLCBpLCBlbGVtICk7CgkJfSApICk7Cgl9LAoKCXNsaWNlOiBmdW5jdGlvbigpIHsKCQlyZXR1cm4gdGhpcy5wdXNoU3RhY2soIHNsaWNlLmFwcGx5KCB0aGlzLCBhcmd1bWVudHMgKSApOwoJfSwKCglmaXJzdDogZnVuY3Rpb24oKSB7CgkJcmV0dXJuIHRoaXMuZXEoIDAgKTsKCX0sCgoJbGFzdDogZnVuY3Rpb24oKSB7CgkJcmV0dXJuIHRoaXMuZXEoIC0xICk7Cgl9LAoKCWVxOiBmdW5jdGlvbiggaSApIHsKCQl2YXIgbGVuID0gdGhpcy5sZW5ndGgsCgkJCWogPSAraSArICggaSA8IDAgPyBsZW4gOiAwICk7CgkJcmV0dXJuIHRoaXMucHVzaFN0YWNrKCBqID49IDAgJiYgaiA8IGxlbiA/IFsgdGhpc1sgaiBdIF0gOiBbXSApOwoJfSwKCgllbmQ6IGZ1bmN0aW9uKCkgewoJCXJldHVybiB0aGlzLnByZXZPYmplY3QgfHwgdGhpcy5jb25zdHJ1Y3RvcigpOwoJfSwKCgkvLyBGb3IgaW50ZXJuYWwgdXNlIG9ubHkuCgkvLyBCZWhhdmVzIGxpa2UgYW4gQXJyYXkncyBtZXRob2QsIG5vdCBsaWtlIGEgalF1ZXJ5IG1ldGhvZC4KCXB1c2g6IHB1c2gsCglzb3J0OiBhcnIuc29ydCwKCXNwbGljZTogYXJyLnNwbGljZQp9OwoKalF1ZXJ5LmV4dGVuZCA9IGpRdWVyeS5mbi5leHRlbmQgPSBmdW5jdGlvbigpIHsKCXZhciBvcHRpb25zLCBuYW1lLCBzcmMsIGNvcHksIGNvcHlJc0FycmF5LCBjbG9uZSwKCQl0YXJnZXQgPSBhcmd1bWVudHNbIDAgXSB8fCB7fSwKCQlpID0gMSwKCQlsZW5ndGggPSBhcmd1bWVudHMubGVuZ3RoLAoJCWRlZXAgPSBmYWxzZTsKCgkvLyBIYW5kbGUgYSBkZWVwIGNvcHkgc2l0dWF0aW9uCglpZiAoIHR5cGVvZiB0YXJnZXQgPT09ICJib29sZWFuIiApIHsKCQlkZWVwID0gdGFyZ2V0OwoKCQkvLyBTa2lwIHRoZSBib29sZWFuIGFuZCB0aGUgdGFyZ2V0CgkJdGFyZ2V0ID0gYXJndW1lbnRzWyBpIF0gfHwge307CgkJaSsrOwoJfQoKCS8vIEhhbmRsZSBjYXNlIHdoZW4gdGFyZ2V0IGlzIGEgc3RyaW5nIG9yIHNvbWV0aGluZyAocG9zc2libGUgaW4gZGVlcCBjb3B5KQoJaWYgKCB0eXBlb2YgdGFyZ2V0ICE9PSAib2JqZWN0IiAmJiAhaXNGdW5jdGlvbiggdGFyZ2V0ICkgKSB7CgkJdGFyZ2V0ID0ge307Cgl9CgoJLy8gRXh0ZW5kIGpRdWVyeSBpdHNlbGYgaWYgb25seSBvbmUgYXJndW1lbnQgaXMgcGFzc2VkCglpZiAoIGkgPT09IGxlbmd0aCApIHsKCQl0YXJnZXQgPSB0aGlzOwoJCWktLTsKCX0KCglmb3IgKCA7IGkgPCBsZW5ndGg7IGkrKyApIHsKCgkJLy8gT25seSBkZWFsIHdpdGggbm9uLW51bGwvdW5kZWZpbmVkIHZhbHVlcwoJCWlmICggKCBvcHRpb25zID0gYXJndW1lbnRzWyBpIF0gKSAhPSBudWxsICkgewoKCQkJLy8gRXh0ZW5kIHRoZSBiYXNlIG9iamVjdAoJCQlmb3IgKCBuYW1lIGluIG9wdGlvbnMgKSB7CgkJCQlzcmMgPSB0YXJnZXRbIG5hbWUgXTsKCQkJCWNvcHkgPSBvcHRpb25zWyBuYW1lIF07CgoJCQkJLy8gUHJldmVudCBuZXZlci1lbmRpbmcgbG9vcAoJCQkJaWYgKCB0YXJnZXQgPT09IGNvcHkgKSB7CgkJCQkJY29udGludWU7CgkJCQl9CgoJCQkJLy8gUmVjdXJzZSBpZiB3ZSdyZSBtZXJnaW5nIHBsYWluIG9iamVjdHMgb3IgYXJyYXlzCgkJCQlpZiAoIGRlZXAgJiYgY29weSAmJiAoIGpRdWVyeS5pc1BsYWluT2JqZWN0KCBjb3B5ICkgfHwKCQkJCQkoIGNvcHlJc0FycmF5ID0gQXJyYXkuaXNBcnJheSggY29weSApICkgKSApIHsKCgkJCQkJaWYgKCBjb3B5SXNBcnJheSApIHsKCQkJCQkJY29weUlzQXJyYXkgPSBmYWxzZTsKCQkJCQkJY2xvbmUgPSBzcmMgJiYgQXJyYXkuaXNBcnJheSggc3JjICkgPyBzcmMgOiBbXTsKCgkJCQkJfSBlbHNlIHsKCQkJCQkJY2xvbmUgPSBzcmMgJiYgalF1ZXJ5LmlzUGxhaW5PYmplY3QoIHNyYyApID8gc3JjIDoge307CgkJCQkJfQoKCQkJCQkvLyBOZXZlciBtb3ZlIG9yaWdpbmFsIG9iamVjdHMsIGNsb25lIHRoZW0KCQkJCQl0YXJnZXRbIG5hbWUgXSA9IGpRdWVyeS5leHRlbmQoIGRlZXAsIGNsb25lLCBjb3B5ICk7CgoJCQkJLy8gRG9uJ3QgYnJpbmcgaW4gdW5kZWZpbmVkIHZhbHVlcwoJCQkJfSBlbHNlIGlmICggY29weSAhPT0gdW5kZWZpbmVkICkgewoJCQkJCXRhcmdldFsgbmFtZSBdID0gY29weTsKCQkJCX0KCQkJfQoJCX0KCX0KCgkvLyBSZXR1cm4gdGhlIG1vZGlmaWVkIG9iamVjdAoJcmV0dXJuIHRhcmdldDsKfTsKCmpRdWVyeS5leHRlbmQoIHsKCgkvLyBVbmlxdWUgZm9yIGVhY2ggY29weSBvZiBqUXVlcnkgb24gdGhlIHBhZ2UKCWV4cGFuZG86ICJqUXVlcnkiICsgKCB2ZXJzaW9uICsgTWF0aC5yYW5kb20oKSApLnJlcGxhY2UoIC9cRC9nLCAiIiApLAoKCS8vIEFzc3VtZSBqUXVlcnkgaXMgcmVhZHkgd2l0aG91dCB0aGUgcmVhZHkgbW9kdWxlCglpc1JlYWR5OiB0cnVlLAoKCWVycm9yOiBmdW5jdGlvbiggbXNnICkgewoJCXRocm93IG5ldyBFcnJvciggbXNnICk7Cgl9LAoKCW5vb3A6IGZ1bmN0aW9uKCkge30sCgoJaXNQbGFpbk9iamVjdDogZnVuY3Rpb24oIG9iaiApIHsKCQl2YXIgcHJvdG8sIEN0b3I7CgoJCS8vIERldGVjdCBvYnZpb3VzIG5lZ2F0aXZlcwoJCS8vIFVzZSB0b1N0cmluZyBpbnN0ZWFkIG9mIGpRdWVyeS50eXBlIHRvIGNhdGNoIGhvc3Qgb2JqZWN0cwoJCWlmICggIW9iaiB8fCB0b1N0cmluZy5jYWxsKCBvYmogKSAhPT0gIltvYmplY3QgT2JqZWN0XSIgKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgoJCXByb3RvID0gZ2V0UHJvdG8oIG9iaiApOwoKCQkvLyBPYmplY3RzIHdpdGggbm8gcHJvdG90eXBlIChlLmcuLCBgT2JqZWN0LmNyZWF0ZSggbnVsbCApYCkgYXJlIHBsYWluCgkJaWYgKCAhcHJvdG8gKSB7CgkJCXJldHVybiB0cnVlOwoJCX0KCgkJLy8gT2JqZWN0cyB3aXRoIHByb3RvdHlwZSBhcmUgcGxhaW4gaWZmIHRoZXkgd2VyZSBjb25zdHJ1Y3RlZCBieSBhIGdsb2JhbCBPYmplY3QgZnVuY3Rpb24KCQlDdG9yID0gaGFzT3duLmNhbGwoIHByb3RvLCAiY29uc3RydWN0b3IiICkgJiYgcHJvdG8uY29uc3RydWN0b3I7CgkJcmV0dXJuIHR5cGVvZiBDdG9yID09PSAiZnVuY3Rpb24iICYmIGZuVG9TdHJpbmcuY2FsbCggQ3RvciApID09PSBPYmplY3RGdW5jdGlvblN0cmluZzsKCX0sCgoJaXNFbXB0eU9iamVjdDogZnVuY3Rpb24oIG9iaiApIHsKCgkJLyogZXNsaW50LWRpc2FibGUgbm8tdW51c2VkLXZhcnMgKi8KCQkvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2VzbGludC9lc2xpbnQvaXNzdWVzLzYxMjUKCQl2YXIgbmFtZTsKCgkJZm9yICggbmFtZSBpbiBvYmogKSB7CgkJCXJldHVybiBmYWxzZTsKCQl9CgkJcmV0dXJuIHRydWU7Cgl9LAoKCS8vIEV2YWx1YXRlcyBhIHNjcmlwdCBpbiBhIGdsb2JhbCBjb250ZXh0CglnbG9iYWxFdmFsOiBmdW5jdGlvbiggY29kZSApIHsKCQlET01FdmFsKCBjb2RlICk7Cgl9LAoKCWVhY2g6IGZ1bmN0aW9uKCBvYmosIGNhbGxiYWNrICkgewoJCXZhciBsZW5ndGgsIGkgPSAwOwoKCQlpZiAoIGlzQXJyYXlMaWtlKCBvYmogKSApIHsKCQkJbGVuZ3RoID0gb2JqLmxlbmd0aDsKCQkJZm9yICggOyBpIDwgbGVuZ3RoOyBpKysgKSB7CgkJCQlpZiAoIGNhbGxiYWNrLmNhbGwoIG9ialsgaSBdLCBpLCBvYmpbIGkgXSApID09PSBmYWxzZSApIHsKCQkJCQlicmVhazsKCQkJCX0KCQkJfQoJCX0gZWxzZSB7CgkJCWZvciAoIGkgaW4gb2JqICkgewoJCQkJaWYgKCBjYWxsYmFjay5jYWxsKCBvYmpbIGkgXSwgaSwgb2JqWyBpIF0gKSA9PT0gZmFsc2UgKSB7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCX0KCQl9CgoJCXJldHVybiBvYmo7Cgl9LAoKCS8vIFN1cHBvcnQ6IEFuZHJvaWQgPD00LjAgb25seQoJdHJpbTogZnVuY3Rpb24oIHRleHQgKSB7CgkJcmV0dXJuIHRleHQgPT0gbnVsbCA/CgkJCSIiIDoKCQkJKCB0ZXh0ICsgIiIgKS5yZXBsYWNlKCBydHJpbSwgIiIgKTsKCX0sCgoJLy8gcmVzdWx0cyBpcyBmb3IgaW50ZXJuYWwgdXNhZ2Ugb25seQoJbWFrZUFycmF5OiBmdW5jdGlvbiggYXJyLCByZXN1bHRzICkgewoJCXZhciByZXQgPSByZXN1bHRzIHx8IFtdOwoKCQlpZiAoIGFyciAhPSBudWxsICkgewoJCQlpZiAoIGlzQXJyYXlMaWtlKCBPYmplY3QoIGFyciApICkgKSB7CgkJCQlqUXVlcnkubWVyZ2UoIHJldCwKCQkJCQl0eXBlb2YgYXJyID09PSAic3RyaW5nIiA/CgkJCQkJWyBhcnIgXSA6IGFycgoJCQkJKTsKCQkJfSBlbHNlIHsKCQkJCXB1c2guY2FsbCggcmV0LCBhcnIgKTsKCQkJfQoJCX0KCgkJcmV0dXJuIHJldDsKCX0sCgoJaW5BcnJheTogZnVuY3Rpb24oIGVsZW0sIGFyciwgaSApIHsKCQlyZXR1cm4gYXJyID09IG51bGwgPyAtMSA6IGluZGV4T2YuY2FsbCggYXJyLCBlbGVtLCBpICk7Cgl9LAoKCS8vIFN1cHBvcnQ6IEFuZHJvaWQgPD00LjAgb25seSwgUGhhbnRvbUpTIDEgb25seQoJLy8gcHVzaC5hcHBseShfLCBhcnJheWxpa2UpIHRocm93cyBvbiBhbmNpZW50IFdlYktpdAoJbWVyZ2U6IGZ1bmN0aW9uKCBmaXJzdCwgc2Vjb25kICkgewoJCXZhciBsZW4gPSArc2Vjb25kLmxlbmd0aCwKCQkJaiA9IDAsCgkJCWkgPSBmaXJzdC5sZW5ndGg7CgoJCWZvciAoIDsgaiA8IGxlbjsgaisrICkgewoJCQlmaXJzdFsgaSsrIF0gPSBzZWNvbmRbIGogXTsKCQl9CgoJCWZpcnN0Lmxlbmd0aCA9IGk7CgoJCXJldHVybiBmaXJzdDsKCX0sCgoJZ3JlcDogZnVuY3Rpb24oIGVsZW1zLCBjYWxsYmFjaywgaW52ZXJ0ICkgewoJCXZhciBjYWxsYmFja0ludmVyc2UsCgkJCW1hdGNoZXMgPSBbXSwKCQkJaSA9IDAsCgkJCWxlbmd0aCA9IGVsZW1zLmxlbmd0aCwKCQkJY2FsbGJhY2tFeHBlY3QgPSAhaW52ZXJ0OwoKCQkvLyBHbyB0aHJvdWdoIHRoZSBhcnJheSwgb25seSBzYXZpbmcgdGhlIGl0ZW1zCgkJLy8gdGhhdCBwYXNzIHRoZSB2YWxpZGF0b3IgZnVuY3Rpb24KCQlmb3IgKCA7IGkgPCBsZW5ndGg7IGkrKyApIHsKCQkJY2FsbGJhY2tJbnZlcnNlID0gIWNhbGxiYWNrKCBlbGVtc1sgaSBdLCBpICk7CgkJCWlmICggY2FsbGJhY2tJbnZlcnNlICE9PSBjYWxsYmFja0V4cGVjdCApIHsKCQkJCW1hdGNoZXMucHVzaCggZWxlbXNbIGkgXSApOwoJCQl9CgkJfQoKCQlyZXR1cm4gbWF0Y2hlczsKCX0sCgoJLy8gYXJnIGlzIGZvciBpbnRlcm5hbCB1c2FnZSBvbmx5CgltYXA6IGZ1bmN0aW9uKCBlbGVtcywgY2FsbGJhY2ssIGFyZyApIHsKCQl2YXIgbGVuZ3RoLCB2YWx1ZSwKCQkJaSA9IDAsCgkJCXJldCA9IFtdOwoKCQkvLyBHbyB0aHJvdWdoIHRoZSBhcnJheSwgdHJhbnNsYXRpbmcgZWFjaCBvZiB0aGUgaXRlbXMgdG8gdGhlaXIgbmV3IHZhbHVlcwoJCWlmICggaXNBcnJheUxpa2UoIGVsZW1zICkgKSB7CgkJCWxlbmd0aCA9IGVsZW1zLmxlbmd0aDsKCQkJZm9yICggOyBpIDwgbGVuZ3RoOyBpKysgKSB7CgkJCQl2YWx1ZSA9IGNhbGxiYWNrKCBlbGVtc1sgaSBdLCBpLCBhcmcgKTsKCgkJCQlpZiAoIHZhbHVlICE9IG51bGwgKSB7CgkJCQkJcmV0LnB1c2goIHZhbHVlICk7CgkJCQl9CgkJCX0KCgkJLy8gR28gdGhyb3VnaCBldmVyeSBrZXkgb24gdGhlIG9iamVjdCwKCQl9IGVsc2UgewoJCQlmb3IgKCBpIGluIGVsZW1zICkgewoJCQkJdmFsdWUgPSBjYWxsYmFjayggZWxlbXNbIGkgXSwgaSwgYXJnICk7CgoJCQkJaWYgKCB2YWx1ZSAhPSBudWxsICkgewoJCQkJCXJldC5wdXNoKCB2YWx1ZSApOwoJCQkJfQoJCQl9CgkJfQoKCQkvLyBGbGF0dGVuIGFueSBuZXN0ZWQgYXJyYXlzCgkJcmV0dXJuIGNvbmNhdC5hcHBseSggW10sIHJldCApOwoJfSwKCgkvLyBBIGdsb2JhbCBHVUlEIGNvdW50ZXIgZm9yIG9iamVjdHMKCWd1aWQ6IDEsCgoJLy8galF1ZXJ5LnN1cHBvcnQgaXMgbm90IHVzZWQgaW4gQ29yZSBidXQgb3RoZXIgcHJvamVjdHMgYXR0YWNoIHRoZWlyCgkvLyBwcm9wZXJ0aWVzIHRvIGl0IHNvIGl0IG5lZWRzIHRvIGV4aXN0LgoJc3VwcG9ydDogc3VwcG9ydAp9ICk7CgppZiAoIHR5cGVvZiBTeW1ib2wgPT09ICJmdW5jdGlvbiIgKSB7CglqUXVlcnkuZm5bIFN5bWJvbC5pdGVyYXRvciBdID0gYXJyWyBTeW1ib2wuaXRlcmF0b3IgXTsKfQoKLy8gUG9wdWxhdGUgdGhlIGNsYXNzMnR5cGUgbWFwCmpRdWVyeS5lYWNoKCAiQm9vbGVhbiBOdW1iZXIgU3RyaW5nIEZ1bmN0aW9uIEFycmF5IERhdGUgUmVnRXhwIE9iamVjdCBFcnJvciBTeW1ib2wiLnNwbGl0KCAiICIgKSwKZnVuY3Rpb24oIGksIG5hbWUgKSB7CgljbGFzczJ0eXBlWyAiW29iamVjdCAiICsgbmFtZSArICJdIiBdID0gbmFtZS50b0xvd2VyQ2FzZSgpOwp9ICk7CgpmdW5jdGlvbiBpc0FycmF5TGlrZSggb2JqICkgewoKCS8vIFN1cHBvcnQ6IHJlYWwgaU9TIDguMiBvbmx5IChub3QgcmVwcm9kdWNpYmxlIGluIHNpbXVsYXRvcikKCS8vIGBpbmAgY2hlY2sgdXNlZCB0byBwcmV2ZW50IEpJVCBlcnJvciAoZ2gtMjE0NSkKCS8vIGhhc093biBpc24ndCB1c2VkIGhlcmUgZHVlIHRvIGZhbHNlIG5lZ2F0aXZlcwoJLy8gcmVnYXJkaW5nIE5vZGVsaXN0IGxlbmd0aCBpbiBJRQoJdmFyIGxlbmd0aCA9ICEhb2JqICYmICJsZW5ndGgiIGluIG9iaiAmJiBvYmoubGVuZ3RoLAoJCXR5cGUgPSB0b1R5cGUoIG9iaiApOwoKCWlmICggaXNGdW5jdGlvbiggb2JqICkgfHwgaXNXaW5kb3coIG9iaiApICkgewoJCXJldHVybiBmYWxzZTsKCX0KCglyZXR1cm4gdHlwZSA9PT0gImFycmF5IiB8fCBsZW5ndGggPT09IDAgfHwKCQl0eXBlb2YgbGVuZ3RoID09PSAibnVtYmVyIiAmJiBsZW5ndGggPiAwICYmICggbGVuZ3RoIC0gMSApIGluIG9iajsKfQp2YXIgU2l6emxlID0KLyohCiAqIFNpenpsZSBDU1MgU2VsZWN0b3IgRW5naW5lIHYyLjMuMwogKiBodHRwczovL3NpenpsZWpzLmNvbS8KICoKICogQ29weXJpZ2h0IGpRdWVyeSBGb3VuZGF0aW9uIGFuZCBvdGhlciBjb250cmlidXRvcnMKICogUmVsZWFzZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlCiAqIGh0dHA6Ly9qcXVlcnkub3JnL2xpY2Vuc2UKICoKICogRGF0ZTogMjAxNi0wOC0wOAogKi8KKGZ1bmN0aW9uKCB3aW5kb3cgKSB7Cgp2YXIgaSwKCXN1cHBvcnQsCglFeHByLAoJZ2V0VGV4dCwKCWlzWE1MLAoJdG9rZW5pemUsCgljb21waWxlLAoJc2VsZWN0LAoJb3V0ZXJtb3N0Q29udGV4dCwKCXNvcnRJbnB1dCwKCWhhc0R1cGxpY2F0ZSwKCgkvLyBMb2NhbCBkb2N1bWVudCB2YXJzCglzZXREb2N1bWVudCwKCWRvY3VtZW50LAoJZG9jRWxlbSwKCWRvY3VtZW50SXNIVE1MLAoJcmJ1Z2d5UVNBLAoJcmJ1Z2d5TWF0Y2hlcywKCW1hdGNoZXMsCgljb250YWlucywKCgkvLyBJbnN0YW5jZS1zcGVjaWZpYyBkYXRhCglleHBhbmRvID0gInNpenpsZSIgKyAxICogbmV3IERhdGUoKSwKCXByZWZlcnJlZERvYyA9IHdpbmRvdy5kb2N1bWVudCwKCWRpcnJ1bnMgPSAwLAoJZG9uZSA9IDAsCgljbGFzc0NhY2hlID0gY3JlYXRlQ2FjaGUoKSwKCXRva2VuQ2FjaGUgPSBjcmVhdGVDYWNoZSgpLAoJY29tcGlsZXJDYWNoZSA9IGNyZWF0ZUNhY2hlKCksCglzb3J0T3JkZXIgPSBmdW5jdGlvbiggYSwgYiApIHsKCQlpZiAoIGEgPT09IGIgKSB7CgkJCWhhc0R1cGxpY2F0ZSA9IHRydWU7CgkJfQoJCXJldHVybiAwOwoJfSwKCgkvLyBJbnN0YW5jZSBtZXRob2RzCgloYXNPd24gPSAoe30pLmhhc093blByb3BlcnR5LAoJYXJyID0gW10sCglwb3AgPSBhcnIucG9wLAoJcHVzaF9uYXRpdmUgPSBhcnIucHVzaCwKCXB1c2ggPSBhcnIucHVzaCwKCXNsaWNlID0gYXJyLnNsaWNlLAoJLy8gVXNlIGEgc3RyaXBwZWQtZG93biBpbmRleE9mIGFzIGl0J3MgZmFzdGVyIHRoYW4gbmF0aXZlCgkvLyBodHRwczovL2pzcGVyZi5jb20vdGhvci1pbmRleG9mLXZzLWZvci81CglpbmRleE9mID0gZnVuY3Rpb24oIGxpc3QsIGVsZW0gKSB7CgkJdmFyIGkgPSAwLAoJCQlsZW4gPSBsaXN0Lmxlbmd0aDsKCQlmb3IgKCA7IGkgPCBsZW47IGkrKyApIHsKCQkJaWYgKCBsaXN0W2ldID09PSBlbGVtICkgewoJCQkJcmV0dXJuIGk7CgkJCX0KCQl9CgkJcmV0dXJuIC0xOwoJfSwKCglib29sZWFucyA9ICJjaGVja2VkfHNlbGVjdGVkfGFzeW5jfGF1dG9mb2N1c3xhdXRvcGxheXxjb250cm9sc3xkZWZlcnxkaXNhYmxlZHxoaWRkZW58aXNtYXB8bG9vcHxtdWx0aXBsZXxvcGVufHJlYWRvbmx5fHJlcXVpcmVkfHNjb3BlZCIsCgoJLy8gUmVndWxhciBleHByZXNzaW9ucwoKCS8vIGh0dHA6Ly93d3cudzMub3JnL1RSL2NzczMtc2VsZWN0b3JzLyN3aGl0ZXNwYWNlCgl3aGl0ZXNwYWNlID0gIltcXHgyMFxcdFxcclxcblxcZl0iLAoKCS8vIGh0dHA6Ly93d3cudzMub3JnL1RSL0NTUzIxL3N5bmRhdGEuaHRtbCN2YWx1ZS1kZWYtaWRlbnRpZmllcgoJaWRlbnRpZmllciA9ICIoPzpcXFxcLnxbXFx3LV18W15cMC1cXHhhMF0pKyIsCgoJLy8gQXR0cmlidXRlIHNlbGVjdG9yczogaHR0cDovL3d3dy53My5vcmcvVFIvc2VsZWN0b3JzLyNhdHRyaWJ1dGUtc2VsZWN0b3JzCglhdHRyaWJ1dGVzID0gIlxcWyIgKyB3aGl0ZXNwYWNlICsgIiooIiArIGlkZW50aWZpZXIgKyAiKSg/OiIgKyB3aGl0ZXNwYWNlICsKCQkvLyBPcGVyYXRvciAoY2FwdHVyZSAyKQoJCSIqKFsqXiR8IX5dPz0pIiArIHdoaXRlc3BhY2UgKwoJCS8vICJBdHRyaWJ1dGUgdmFsdWVzIG11c3QgYmUgQ1NTIGlkZW50aWZpZXJzIFtjYXB0dXJlIDVdIG9yIHN0cmluZ3MgW2NhcHR1cmUgMyBvciBjYXB0dXJlIDRdIgoJCSIqKD86JygoPzpcXFxcLnxbXlxcXFwnXSkqKSd8XCIoKD86XFxcXC58W15cXFxcXCJdKSopXCJ8KCIgKyBpZGVudGlmaWVyICsgIikpfCkiICsgd2hpdGVzcGFjZSArCgkJIipcXF0iLAoKCXBzZXVkb3MgPSAiOigiICsgaWRlbnRpZmllciArICIpKD86XFwoKCIgKwoJCS8vIFRvIHJlZHVjZSB0aGUgbnVtYmVyIG9mIHNlbGVjdG9ycyBuZWVkaW5nIHRva2VuaXplIGluIHRoZSBwcmVGaWx0ZXIsIHByZWZlciBhcmd1bWVudHM6CgkJLy8gMS4gcXVvdGVkIChjYXB0dXJlIDM7IGNhcHR1cmUgNCBvciBjYXB0dXJlIDUpCgkJIignKCg/OlxcXFwufFteXFxcXCddKSopJ3xcIigoPzpcXFxcLnxbXlxcXFxcIl0pKilcIil8IiArCgkJLy8gMi4gc2ltcGxlIChjYXB0dXJlIDYpCgkJIigoPzpcXFxcLnxbXlxcXFwoKVtcXF1dfCIgKyBhdHRyaWJ1dGVzICsgIikqKXwiICsKCQkvLyAzLiBhbnl0aGluZyBlbHNlIChjYXB0dXJlIDIpCgkJIi4qIiArCgkJIilcXCl8KSIsCgoJLy8gTGVhZGluZyBhbmQgbm9uLWVzY2FwZWQgdHJhaWxpbmcgd2hpdGVzcGFjZSwgY2FwdHVyaW5nIHNvbWUgbm9uLXdoaXRlc3BhY2UgY2hhcmFjdGVycyBwcmVjZWRpbmcgdGhlIGxhdHRlcgoJcndoaXRlc3BhY2UgPSBuZXcgUmVnRXhwKCB3aGl0ZXNwYWNlICsgIisiLCAiZyIgKSwKCXJ0cmltID0gbmV3IFJlZ0V4cCggIl4iICsgd2hpdGVzcGFjZSArICIrfCgoPzpefFteXFxcXF0pKD86XFxcXC4pKikiICsgd2hpdGVzcGFjZSArICIrJCIsICJnIiApLAoKCXJjb21tYSA9IG5ldyBSZWdFeHAoICJeIiArIHdoaXRlc3BhY2UgKyAiKiwiICsgd2hpdGVzcGFjZSArICIqIiApLAoJcmNvbWJpbmF0b3JzID0gbmV3IFJlZ0V4cCggIl4iICsgd2hpdGVzcGFjZSArICIqKFs+K35dfCIgKyB3aGl0ZXNwYWNlICsgIikiICsgd2hpdGVzcGFjZSArICIqIiApLAoKCXJhdHRyaWJ1dGVRdW90ZXMgPSBuZXcgUmVnRXhwKCAiPSIgKyB3aGl0ZXNwYWNlICsgIiooW15cXF0nXCJdKj8pIiArIHdoaXRlc3BhY2UgKyAiKlxcXSIsICJnIiApLAoKCXJwc2V1ZG8gPSBuZXcgUmVnRXhwKCBwc2V1ZG9zICksCglyaWRlbnRpZmllciA9IG5ldyBSZWdFeHAoICJeIiArIGlkZW50aWZpZXIgKyAiJCIgKSwKCgltYXRjaEV4cHIgPSB7CgkJIklEIjogbmV3IFJlZ0V4cCggIl4jKCIgKyBpZGVudGlmaWVyICsgIikiICksCgkJIkNMQVNTIjogbmV3IFJlZ0V4cCggIl5cXC4oIiArIGlkZW50aWZpZXIgKyAiKSIgKSwKCQkiVEFHIjogbmV3IFJlZ0V4cCggIl4oIiArIGlkZW50aWZpZXIgKyAifFsqXSkiICksCgkJIkFUVFIiOiBuZXcgUmVnRXhwKCAiXiIgKyBhdHRyaWJ1dGVzICksCgkJIlBTRVVETyI6IG5ldyBSZWdFeHAoICJeIiArIHBzZXVkb3MgKSwKCQkiQ0hJTEQiOiBuZXcgUmVnRXhwKCAiXjoob25seXxmaXJzdHxsYXN0fG50aHxudGgtbGFzdCktKGNoaWxkfG9mLXR5cGUpKD86XFwoIiArIHdoaXRlc3BhY2UgKwoJCQkiKihldmVufG9kZHwoKFsrLV18KShcXGQqKW58KSIgKyB3aGl0ZXNwYWNlICsgIiooPzooWystXXwpIiArIHdoaXRlc3BhY2UgKwoJCQkiKihcXGQrKXwpKSIgKyB3aGl0ZXNwYWNlICsgIipcXCl8KSIsICJpIiApLAoJCSJib29sIjogbmV3IFJlZ0V4cCggIl4oPzoiICsgYm9vbGVhbnMgKyAiKSQiLCAiaSIgKSwKCQkvLyBGb3IgdXNlIGluIGxpYnJhcmllcyBpbXBsZW1lbnRpbmcgLmlzKCkKCQkvLyBXZSB1c2UgdGhpcyBmb3IgUE9TIG1hdGNoaW5nIGluIGBzZWxlY3RgCgkJIm5lZWRzQ29udGV4dCI6IG5ldyBSZWdFeHAoICJeIiArIHdoaXRlc3BhY2UgKyAiKls+K35dfDooZXZlbnxvZGR8ZXF8Z3R8bHR8bnRofGZpcnN0fGxhc3QpKD86XFwoIiArCgkJCXdoaXRlc3BhY2UgKyAiKigoPzotXFxkKT9cXGQqKSIgKyB3aGl0ZXNwYWNlICsgIipcXCl8KSg/PVteLV18JCkiLCAiaSIgKQoJfSwKCglyaW5wdXRzID0gL14oPzppbnB1dHxzZWxlY3R8dGV4dGFyZWF8YnV0dG9uKSQvaSwKCXJoZWFkZXIgPSAvXmhcZCQvaSwKCglybmF0aXZlID0gL15bXntdK1x7XHMqXFtuYXRpdmUgXHcvLAoKCS8vIEVhc2lseS1wYXJzZWFibGUvcmV0cmlldmFibGUgSUQgb3IgVEFHIG9yIENMQVNTIHNlbGVjdG9ycwoJcnF1aWNrRXhwciA9IC9eKD86IyhbXHctXSspfChcdyspfFwuKFtcdy1dKykpJC8sCgoJcnNpYmxpbmcgPSAvWyt+XS8sCgoJLy8gQ1NTIGVzY2FwZXMKCS8vIGh0dHA6Ly93d3cudzMub3JnL1RSL0NTUzIxL3N5bmRhdGEuaHRtbCNlc2NhcGVkLWNoYXJhY3RlcnMKCXJ1bmVzY2FwZSA9IG5ldyBSZWdFeHAoICJcXFxcKFtcXGRhLWZdezEsNn0iICsgd2hpdGVzcGFjZSArICI/fCgiICsgd2hpdGVzcGFjZSArICIpfC4pIiwgImlnIiApLAoJZnVuZXNjYXBlID0gZnVuY3Rpb24oIF8sIGVzY2FwZWQsIGVzY2FwZWRXaGl0ZXNwYWNlICkgewoJCXZhciBoaWdoID0gIjB4IiArIGVzY2FwZWQgLSAweDEwMDAwOwoJCS8vIE5hTiBtZWFucyBub24tY29kZXBvaW50CgkJLy8gU3VwcG9ydDogRmlyZWZveDwyNAoJCS8vIFdvcmthcm91bmQgZXJyb25lb3VzIG51bWVyaWMgaW50ZXJwcmV0YXRpb24gb2YgKyIweCIKCQlyZXR1cm4gaGlnaCAhPT0gaGlnaCB8fCBlc2NhcGVkV2hpdGVzcGFjZSA/CgkJCWVzY2FwZWQgOgoJCQloaWdoIDwgMCA/CgkJCQkvLyBCTVAgY29kZXBvaW50CgkJCQlTdHJpbmcuZnJvbUNoYXJDb2RlKCBoaWdoICsgMHgxMDAwMCApIDoKCQkJCS8vIFN1cHBsZW1lbnRhbCBQbGFuZSBjb2RlcG9pbnQgKHN1cnJvZ2F0ZSBwYWlyKQoJCQkJU3RyaW5nLmZyb21DaGFyQ29kZSggaGlnaCA+PiAxMCB8IDB4RDgwMCwgaGlnaCAmIDB4M0ZGIHwgMHhEQzAwICk7Cgl9LAoKCS8vIENTUyBzdHJpbmcvaWRlbnRpZmllciBzZXJpYWxpemF0aW9uCgkvLyBodHRwczovL2RyYWZ0cy5jc3N3Zy5vcmcvY3Nzb20vI2NvbW1vbi1zZXJpYWxpemluZy1pZGlvbXMKCXJjc3Nlc2NhcGUgPSAvKFtcMC1ceDFmXHg3Zl18Xi0/XGQpfF4tJHxbXlwwLVx4MWZceDdmLVx1RkZGRlx3LV0vZywKCWZjc3Nlc2NhcGUgPSBmdW5jdGlvbiggY2gsIGFzQ29kZVBvaW50ICkgewoJCWlmICggYXNDb2RlUG9pbnQgKSB7CgoJCQkvLyBVKzAwMDAgTlVMTCBiZWNvbWVzIFUrRkZGRCBSRVBMQUNFTUVOVCBDSEFSQUNURVIKCQkJaWYgKCBjaCA9PT0gIlwwIiApIHsKCQkJCXJldHVybiAiXHVGRkZEIjsKCQkJfQoKCQkJLy8gQ29udHJvbCBjaGFyYWN0ZXJzIGFuZCAoZGVwZW5kZW50IHVwb24gcG9zaXRpb24pIG51bWJlcnMgZ2V0IGVzY2FwZWQgYXMgY29kZSBwb2ludHMKCQkJcmV0dXJuIGNoLnNsaWNlKCAwLCAtMSApICsgIlxcIiArIGNoLmNoYXJDb2RlQXQoIGNoLmxlbmd0aCAtIDEgKS50b1N0cmluZyggMTYgKSArICIgIjsKCQl9CgoJCS8vIE90aGVyIHBvdGVudGlhbGx5LXNwZWNpYWwgQVNDSUkgY2hhcmFjdGVycyBnZXQgYmFja3NsYXNoLWVzY2FwZWQKCQlyZXR1cm4gIlxcIiArIGNoOwoJfSwKCgkvLyBVc2VkIGZvciBpZnJhbWVzCgkvLyBTZWUgc2V0RG9jdW1lbnQoKQoJLy8gUmVtb3ZpbmcgdGhlIGZ1bmN0aW9uIHdyYXBwZXIgY2F1c2VzIGEgIlBlcm1pc3Npb24gRGVuaWVkIgoJLy8gZXJyb3IgaW4gSUUKCXVubG9hZEhhbmRsZXIgPSBmdW5jdGlvbigpIHsKCQlzZXREb2N1bWVudCgpOwoJfSwKCglkaXNhYmxlZEFuY2VzdG9yID0gYWRkQ29tYmluYXRvcigKCQlmdW5jdGlvbiggZWxlbSApIHsKCQkJcmV0dXJuIGVsZW0uZGlzYWJsZWQgPT09IHRydWUgJiYgKCJmb3JtIiBpbiBlbGVtIHx8ICJsYWJlbCIgaW4gZWxlbSk7CgkJfSwKCQl7IGRpcjogInBhcmVudE5vZGUiLCBuZXh0OiAibGVnZW5kIiB9CgkpOwoKLy8gT3B0aW1pemUgZm9yIHB1c2guYXBwbHkoIF8sIE5vZGVMaXN0ICkKdHJ5IHsKCXB1c2guYXBwbHkoCgkJKGFyciA9IHNsaWNlLmNhbGwoIHByZWZlcnJlZERvYy5jaGlsZE5vZGVzICkpLAoJCXByZWZlcnJlZERvYy5jaGlsZE5vZGVzCgkpOwoJLy8gU3VwcG9ydDogQW5kcm9pZDw0LjAKCS8vIERldGVjdCBzaWxlbnRseSBmYWlsaW5nIHB1c2guYXBwbHkKCWFyclsgcHJlZmVycmVkRG9jLmNoaWxkTm9kZXMubGVuZ3RoIF0ubm9kZVR5cGU7Cn0gY2F0Y2ggKCBlICkgewoJcHVzaCA9IHsgYXBwbHk6IGFyci5sZW5ndGggPwoKCQkvLyBMZXZlcmFnZSBzbGljZSBpZiBwb3NzaWJsZQoJCWZ1bmN0aW9uKCB0YXJnZXQsIGVscyApIHsKCQkJcHVzaF9uYXRpdmUuYXBwbHkoIHRhcmdldCwgc2xpY2UuY2FsbChlbHMpICk7CgkJfSA6CgoJCS8vIFN1cHBvcnQ6IElFPDkKCQkvLyBPdGhlcndpc2UgYXBwZW5kIGRpcmVjdGx5CgkJZnVuY3Rpb24oIHRhcmdldCwgZWxzICkgewoJCQl2YXIgaiA9IHRhcmdldC5sZW5ndGgsCgkJCQlpID0gMDsKCQkJLy8gQ2FuJ3QgdHJ1c3QgTm9kZUxpc3QubGVuZ3RoCgkJCXdoaWxlICggKHRhcmdldFtqKytdID0gZWxzW2krK10pICkge30KCQkJdGFyZ2V0Lmxlbmd0aCA9IGogLSAxOwoJCX0KCX07Cn0KCmZ1bmN0aW9uIFNpenpsZSggc2VsZWN0b3IsIGNvbnRleHQsIHJlc3VsdHMsIHNlZWQgKSB7Cgl2YXIgbSwgaSwgZWxlbSwgbmlkLCBtYXRjaCwgZ3JvdXBzLCBuZXdTZWxlY3RvciwKCQluZXdDb250ZXh0ID0gY29udGV4dCAmJiBjb250ZXh0Lm93bmVyRG9jdW1lbnQsCgoJCS8vIG5vZGVUeXBlIGRlZmF1bHRzIHRvIDksIHNpbmNlIGNvbnRleHQgZGVmYXVsdHMgdG8gZG9jdW1lbnQKCQlub2RlVHlwZSA9IGNvbnRleHQgPyBjb250ZXh0Lm5vZGVUeXBlIDogOTsKCglyZXN1bHRzID0gcmVzdWx0cyB8fCBbXTsKCgkvLyBSZXR1cm4gZWFybHkgZnJvbSBjYWxscyB3aXRoIGludmFsaWQgc2VsZWN0b3Igb3IgY29udGV4dAoJaWYgKCB0eXBlb2Ygc2VsZWN0b3IgIT09ICJzdHJpbmciIHx8ICFzZWxlY3RvciB8fAoJCW5vZGVUeXBlICE9PSAxICYmIG5vZGVUeXBlICE9PSA5ICYmIG5vZGVUeXBlICE9PSAxMSApIHsKCgkJcmV0dXJuIHJlc3VsdHM7Cgl9CgoJLy8gVHJ5IHRvIHNob3J0Y3V0IGZpbmQgb3BlcmF0aW9ucyAoYXMgb3Bwb3NlZCB0byBmaWx0ZXJzKSBpbiBIVE1MIGRvY3VtZW50cwoJaWYgKCAhc2VlZCApIHsKCgkJaWYgKCAoIGNvbnRleHQgPyBjb250ZXh0Lm93bmVyRG9jdW1lbnQgfHwgY29udGV4dCA6IHByZWZlcnJlZERvYyApICE9PSBkb2N1bWVudCApIHsKCQkJc2V0RG9jdW1lbnQoIGNvbnRleHQgKTsKCQl9CgkJY29udGV4dCA9IGNvbnRleHQgfHwgZG9jdW1lbnQ7CgoJCWlmICggZG9jdW1lbnRJc0hUTUwgKSB7CgoJCQkvLyBJZiB0aGUgc2VsZWN0b3IgaXMgc3VmZmljaWVudGx5IHNpbXBsZSwgdHJ5IHVzaW5nIGEgImdldCpCeSoiIERPTSBtZXRob2QKCQkJLy8gKGV4Y2VwdGluZyBEb2N1bWVudEZyYWdtZW50IGNvbnRleHQsIHdoZXJlIHRoZSBtZXRob2RzIGRvbid0IGV4aXN0KQoJCQlpZiAoIG5vZGVUeXBlICE9PSAxMSAmJiAobWF0Y2ggPSBycXVpY2tFeHByLmV4ZWMoIHNlbGVjdG9yICkpICkgewoKCQkJCS8vIElEIHNlbGVjdG9yCgkJCQlpZiAoIChtID0gbWF0Y2hbMV0pICkgewoKCQkJCQkvLyBEb2N1bWVudCBjb250ZXh0CgkJCQkJaWYgKCBub2RlVHlwZSA9PT0gOSApIHsKCQkJCQkJaWYgKCAoZWxlbSA9IGNvbnRleHQuZ2V0RWxlbWVudEJ5SWQoIG0gKSkgKSB7CgoJCQkJCQkJLy8gU3VwcG9ydDogSUUsIE9wZXJhLCBXZWJraXQKCQkJCQkJCS8vIFRPRE86IGlkZW50aWZ5IHZlcnNpb25zCgkJCQkJCQkvLyBnZXRFbGVtZW50QnlJZCBjYW4gbWF0Y2ggZWxlbWVudHMgYnkgbmFtZSBpbnN0ZWFkIG9mIElECgkJCQkJCQlpZiAoIGVsZW0uaWQgPT09IG0gKSB7CgkJCQkJCQkJcmVzdWx0cy5wdXNoKCBlbGVtICk7CgkJCQkJCQkJcmV0dXJuIHJlc3VsdHM7CgkJCQkJCQl9CgkJCQkJCX0gZWxzZSB7CgkJCQkJCQlyZXR1cm4gcmVzdWx0czsKCQkJCQkJfQoKCQkJCQkvLyBFbGVtZW50IGNvbnRleHQKCQkJCQl9IGVsc2UgewoKCQkJCQkJLy8gU3VwcG9ydDogSUUsIE9wZXJhLCBXZWJraXQKCQkJCQkJLy8gVE9ETzogaWRlbnRpZnkgdmVyc2lvbnMKCQkJCQkJLy8gZ2V0RWxlbWVudEJ5SWQgY2FuIG1hdGNoIGVsZW1lbnRzIGJ5IG5hbWUgaW5zdGVhZCBvZiBJRAoJCQkJCQlpZiAoIG5ld0NvbnRleHQgJiYgKGVsZW0gPSBuZXdDb250ZXh0LmdldEVsZW1lbnRCeUlkKCBtICkpICYmCgkJCQkJCQljb250YWlucyggY29udGV4dCwgZWxlbSApICYmCgkJCQkJCQllbGVtLmlkID09PSBtICkgewoKCQkJCQkJCXJlc3VsdHMucHVzaCggZWxlbSApOwoJCQkJCQkJcmV0dXJuIHJlc3VsdHM7CgkJCQkJCX0KCQkJCQl9CgoJCQkJLy8gVHlwZSBzZWxlY3RvcgoJCQkJfSBlbHNlIGlmICggbWF0Y2hbMl0gKSB7CgkJCQkJcHVzaC5hcHBseSggcmVzdWx0cywgY29udGV4dC5nZXRFbGVtZW50c0J5VGFnTmFtZSggc2VsZWN0b3IgKSApOwoJCQkJCXJldHVybiByZXN1bHRzOwoKCQkJCS8vIENsYXNzIHNlbGVjdG9yCgkJCQl9IGVsc2UgaWYgKCAobSA9IG1hdGNoWzNdKSAmJiBzdXBwb3J0LmdldEVsZW1lbnRzQnlDbGFzc05hbWUgJiYKCQkJCQljb250ZXh0LmdldEVsZW1lbnRzQnlDbGFzc05hbWUgKSB7CgoJCQkJCXB1c2guYXBwbHkoIHJlc3VsdHMsIGNvbnRleHQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSggbSApICk7CgkJCQkJcmV0dXJuIHJlc3VsdHM7CgkJCQl9CgkJCX0KCgkJCS8vIFRha2UgYWR2YW50YWdlIG9mIHF1ZXJ5U2VsZWN0b3JBbGwKCQkJaWYgKCBzdXBwb3J0LnFzYSAmJgoJCQkJIWNvbXBpbGVyQ2FjaGVbIHNlbGVjdG9yICsgIiAiIF0gJiYKCQkJCSghcmJ1Z2d5UVNBIHx8ICFyYnVnZ3lRU0EudGVzdCggc2VsZWN0b3IgKSkgKSB7CgoJCQkJaWYgKCBub2RlVHlwZSAhPT0gMSApIHsKCQkJCQluZXdDb250ZXh0ID0gY29udGV4dDsKCQkJCQluZXdTZWxlY3RvciA9IHNlbGVjdG9yOwoKCQkJCS8vIHFTQSBsb29rcyBvdXRzaWRlIEVsZW1lbnQgY29udGV4dCwgd2hpY2ggaXMgbm90IHdoYXQgd2Ugd2FudAoJCQkJLy8gVGhhbmtzIHRvIEFuZHJldyBEdXBvbnQgZm9yIHRoaXMgd29ya2Fyb3VuZCB0ZWNobmlxdWUKCQkJCS8vIFN1cHBvcnQ6IElFIDw9OAoJCQkJLy8gRXhjbHVkZSBvYmplY3QgZWxlbWVudHMKCQkJCX0gZWxzZSBpZiAoIGNvbnRleHQubm9kZU5hbWUudG9Mb3dlckNhc2UoKSAhPT0gIm9iamVjdCIgKSB7CgoJCQkJCS8vIENhcHR1cmUgdGhlIGNvbnRleHQgSUQsIHNldHRpbmcgaXQgZmlyc3QgaWYgbmVjZXNzYXJ5CgkJCQkJaWYgKCAobmlkID0gY29udGV4dC5nZXRBdHRyaWJ1dGUoICJpZCIgKSkgKSB7CgkJCQkJCW5pZCA9IG5pZC5yZXBsYWNlKCByY3NzZXNjYXBlLCBmY3NzZXNjYXBlICk7CgkJCQkJfSBlbHNlIHsKCQkJCQkJY29udGV4dC5zZXRBdHRyaWJ1dGUoICJpZCIsIChuaWQgPSBleHBhbmRvKSApOwoJCQkJCX0KCgkJCQkJLy8gUHJlZml4IGV2ZXJ5IHNlbGVjdG9yIGluIHRoZSBsaXN0CgkJCQkJZ3JvdXBzID0gdG9rZW5pemUoIHNlbGVjdG9yICk7CgkJCQkJaSA9IGdyb3Vwcy5sZW5ndGg7CgkJCQkJd2hpbGUgKCBpLS0gKSB7CgkJCQkJCWdyb3Vwc1tpXSA9ICIjIiArIG5pZCArICIgIiArIHRvU2VsZWN0b3IoIGdyb3Vwc1tpXSApOwoJCQkJCX0KCQkJCQluZXdTZWxlY3RvciA9IGdyb3Vwcy5qb2luKCAiLCIgKTsKCgkJCQkJLy8gRXhwYW5kIGNvbnRleHQgZm9yIHNpYmxpbmcgc2VsZWN0b3JzCgkJCQkJbmV3Q29udGV4dCA9IHJzaWJsaW5nLnRlc3QoIHNlbGVjdG9yICkgJiYgdGVzdENvbnRleHQoIGNvbnRleHQucGFyZW50Tm9kZSApIHx8CgkJCQkJCWNvbnRleHQ7CgkJCQl9CgoJCQkJaWYgKCBuZXdTZWxlY3RvciApIHsKCQkJCQl0cnkgewoJCQkJCQlwdXNoLmFwcGx5KCByZXN1bHRzLAoJCQkJCQkJbmV3Q29udGV4dC5xdWVyeVNlbGVjdG9yQWxsKCBuZXdTZWxlY3RvciApCgkJCQkJCSk7CgkJCQkJCXJldHVybiByZXN1bHRzOwoJCQkJCX0gY2F0Y2ggKCBxc2FFcnJvciApIHsKCQkJCQl9IGZpbmFsbHkgewoJCQkJCQlpZiAoIG5pZCA9PT0gZXhwYW5kbyApIHsKCQkJCQkJCWNvbnRleHQucmVtb3ZlQXR0cmlidXRlKCAiaWQiICk7CgkJCQkJCX0KCQkJCQl9CgkJCQl9CgkJCX0KCQl9Cgl9CgoJLy8gQWxsIG90aGVycwoJcmV0dXJuIHNlbGVjdCggc2VsZWN0b3IucmVwbGFjZSggcnRyaW0sICIkMSIgKSwgY29udGV4dCwgcmVzdWx0cywgc2VlZCApOwp9CgovKioKICogQ3JlYXRlIGtleS12YWx1ZSBjYWNoZXMgb2YgbGltaXRlZCBzaXplCiAqIEByZXR1cm5zIHtmdW5jdGlvbihzdHJpbmcsIG9iamVjdCl9IFJldHVybnMgdGhlIE9iamVjdCBkYXRhIGFmdGVyIHN0b3JpbmcgaXQgb24gaXRzZWxmIHdpdGgKICoJcHJvcGVydHkgbmFtZSB0aGUgKHNwYWNlLXN1ZmZpeGVkKSBzdHJpbmcgYW5kIChpZiB0aGUgY2FjaGUgaXMgbGFyZ2VyIHRoYW4gRXhwci5jYWNoZUxlbmd0aCkKICoJZGVsZXRpbmcgdGhlIG9sZGVzdCBlbnRyeQogKi8KZnVuY3Rpb24gY3JlYXRlQ2FjaGUoKSB7Cgl2YXIga2V5cyA9IFtdOwoKCWZ1bmN0aW9uIGNhY2hlKCBrZXksIHZhbHVlICkgewoJCS8vIFVzZSAoa2V5ICsgIiAiKSB0byBhdm9pZCBjb2xsaXNpb24gd2l0aCBuYXRpdmUgcHJvdG90eXBlIHByb3BlcnRpZXMgKHNlZSBJc3N1ZSAjMTU3KQoJCWlmICgga2V5cy5wdXNoKCBrZXkgKyAiICIgKSA+IEV4cHIuY2FjaGVMZW5ndGggKSB7CgkJCS8vIE9ubHkga2VlcCB0aGUgbW9zdCByZWNlbnQgZW50cmllcwoJCQlkZWxldGUgY2FjaGVbIGtleXMuc2hpZnQoKSBdOwoJCX0KCQlyZXR1cm4gKGNhY2hlWyBrZXkgKyAiICIgXSA9IHZhbHVlKTsKCX0KCXJldHVybiBjYWNoZTsKfQoKLyoqCiAqIE1hcmsgYSBmdW5jdGlvbiBmb3Igc3BlY2lhbCB1c2UgYnkgU2l6emxlCiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIFRoZSBmdW5jdGlvbiB0byBtYXJrCiAqLwpmdW5jdGlvbiBtYXJrRnVuY3Rpb24oIGZuICkgewoJZm5bIGV4cGFuZG8gXSA9IHRydWU7CglyZXR1cm4gZm47Cn0KCi8qKgogKiBTdXBwb3J0IHRlc3RpbmcgdXNpbmcgYW4gZWxlbWVudAogKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiBQYXNzZWQgdGhlIGNyZWF0ZWQgZWxlbWVudCBhbmQgcmV0dXJucyBhIGJvb2xlYW4gcmVzdWx0CiAqLwpmdW5jdGlvbiBhc3NlcnQoIGZuICkgewoJdmFyIGVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiZmllbGRzZXQiKTsKCgl0cnkgewoJCXJldHVybiAhIWZuKCBlbCApOwoJfSBjYXRjaCAoZSkgewoJCXJldHVybiBmYWxzZTsKCX0gZmluYWxseSB7CgkJLy8gUmVtb3ZlIGZyb20gaXRzIHBhcmVudCBieSBkZWZhdWx0CgkJaWYgKCBlbC5wYXJlbnROb2RlICkgewoJCQllbC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKCBlbCApOwoJCX0KCQkvLyByZWxlYXNlIG1lbW9yeSBpbiBJRQoJCWVsID0gbnVsbDsKCX0KfQoKLyoqCiAqIEFkZHMgdGhlIHNhbWUgaGFuZGxlciBmb3IgYWxsIG9mIHRoZSBzcGVjaWZpZWQgYXR0cnMKICogQHBhcmFtIHtTdHJpbmd9IGF0dHJzIFBpcGUtc2VwYXJhdGVkIGxpc3Qgb2YgYXR0cmlidXRlcwogKiBAcGFyYW0ge0Z1bmN0aW9ufSBoYW5kbGVyIFRoZSBtZXRob2QgdGhhdCB3aWxsIGJlIGFwcGxpZWQKICovCmZ1bmN0aW9uIGFkZEhhbmRsZSggYXR0cnMsIGhhbmRsZXIgKSB7Cgl2YXIgYXJyID0gYXR0cnMuc3BsaXQoInwiKSwKCQlpID0gYXJyLmxlbmd0aDsKCgl3aGlsZSAoIGktLSApIHsKCQlFeHByLmF0dHJIYW5kbGVbIGFycltpXSBdID0gaGFuZGxlcjsKCX0KfQoKLyoqCiAqIENoZWNrcyBkb2N1bWVudCBvcmRlciBvZiB0d28gc2libGluZ3MKICogQHBhcmFtIHtFbGVtZW50fSBhCiAqIEBwYXJhbSB7RWxlbWVudH0gYgogKiBAcmV0dXJucyB7TnVtYmVyfSBSZXR1cm5zIGxlc3MgdGhhbiAwIGlmIGEgcHJlY2VkZXMgYiwgZ3JlYXRlciB0aGFuIDAgaWYgYSBmb2xsb3dzIGIKICovCmZ1bmN0aW9uIHNpYmxpbmdDaGVjayggYSwgYiApIHsKCXZhciBjdXIgPSBiICYmIGEsCgkJZGlmZiA9IGN1ciAmJiBhLm5vZGVUeXBlID09PSAxICYmIGIubm9kZVR5cGUgPT09IDEgJiYKCQkJYS5zb3VyY2VJbmRleCAtIGIuc291cmNlSW5kZXg7CgoJLy8gVXNlIElFIHNvdXJjZUluZGV4IGlmIGF2YWlsYWJsZSBvbiBib3RoIG5vZGVzCglpZiAoIGRpZmYgKSB7CgkJcmV0dXJuIGRpZmY7Cgl9CgoJLy8gQ2hlY2sgaWYgYiBmb2xsb3dzIGEKCWlmICggY3VyICkgewoJCXdoaWxlICggKGN1ciA9IGN1ci5uZXh0U2libGluZykgKSB7CgkJCWlmICggY3VyID09PSBiICkgewoJCQkJcmV0dXJuIC0xOwoJCQl9CgkJfQoJfQoKCXJldHVybiBhID8gMSA6IC0xOwp9CgovKioKICogUmV0dXJucyBhIGZ1bmN0aW9uIHRvIHVzZSBpbiBwc2V1ZG9zIGZvciBpbnB1dCB0eXBlcwogKiBAcGFyYW0ge1N0cmluZ30gdHlwZQogKi8KZnVuY3Rpb24gY3JlYXRlSW5wdXRQc2V1ZG8oIHR5cGUgKSB7CglyZXR1cm4gZnVuY3Rpb24oIGVsZW0gKSB7CgkJdmFyIG5hbWUgPSBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7CgkJcmV0dXJuIG5hbWUgPT09ICJpbnB1dCIgJiYgZWxlbS50eXBlID09PSB0eXBlOwoJfTsKfQoKLyoqCiAqIFJldHVybnMgYSBmdW5jdGlvbiB0byB1c2UgaW4gcHNldWRvcyBmb3IgYnV0dG9ucwogKiBAcGFyYW0ge1N0cmluZ30gdHlwZQogKi8KZnVuY3Rpb24gY3JlYXRlQnV0dG9uUHNldWRvKCB0eXBlICkgewoJcmV0dXJuIGZ1bmN0aW9uKCBlbGVtICkgewoJCXZhciBuYW1lID0gZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpOwoJCXJldHVybiAobmFtZSA9PT0gImlucHV0IiB8fCBuYW1lID09PSAiYnV0dG9uIikgJiYgZWxlbS50eXBlID09PSB0eXBlOwoJfTsKfQoKLyoqCiAqIFJldHVybnMgYSBmdW5jdGlvbiB0byB1c2UgaW4gcHNldWRvcyBmb3IgOmVuYWJsZWQvOmRpc2FibGVkCiAqIEBwYXJhbSB7Qm9vbGVhbn0gZGlzYWJsZWQgdHJ1ZSBmb3IgOmRpc2FibGVkOyBmYWxzZSBmb3IgOmVuYWJsZWQKICovCmZ1bmN0aW9uIGNyZWF0ZURpc2FibGVkUHNldWRvKCBkaXNhYmxlZCApIHsKCgkvLyBLbm93biA6ZGlzYWJsZWQgZmFsc2UgcG9zaXRpdmVzOiBmaWVsZHNldFtkaXNhYmxlZF0gPiBsZWdlbmQ6bnRoLW9mLXR5cGUobisyKSA6Y2FuLWRpc2FibGUKCXJldHVybiBmdW5jdGlvbiggZWxlbSApIHsKCgkJLy8gT25seSBjZXJ0YWluIGVsZW1lbnRzIGNhbiBtYXRjaCA6ZW5hYmxlZCBvciA6ZGlzYWJsZWQKCQkvLyBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9zY3JpcHRpbmcuaHRtbCNzZWxlY3Rvci1lbmFibGVkCgkJLy8gaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2Uvc2NyaXB0aW5nLmh0bWwjc2VsZWN0b3ItZGlzYWJsZWQKCQlpZiAoICJmb3JtIiBpbiBlbGVtICkgewoKCQkJLy8gQ2hlY2sgZm9yIGluaGVyaXRlZCBkaXNhYmxlZG5lc3Mgb24gcmVsZXZhbnQgbm9uLWRpc2FibGVkIGVsZW1lbnRzOgoJCQkvLyAqIGxpc3RlZCBmb3JtLWFzc29jaWF0ZWQgZWxlbWVudHMgaW4gYSBkaXNhYmxlZCBmaWVsZHNldAoJCQkvLyAgIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL2Zvcm1zLmh0bWwjY2F0ZWdvcnktbGlzdGVkCgkJCS8vICAgaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2UvZm9ybXMuaHRtbCNjb25jZXB0LWZlLWRpc2FibGVkCgkJCS8vICogb3B0aW9uIGVsZW1lbnRzIGluIGEgZGlzYWJsZWQgb3B0Z3JvdXAKCQkJLy8gICBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9mb3Jtcy5odG1sI2NvbmNlcHQtb3B0aW9uLWRpc2FibGVkCgkJCS8vIEFsbCBzdWNoIGVsZW1lbnRzIGhhdmUgYSAiZm9ybSIgcHJvcGVydHkuCgkJCWlmICggZWxlbS5wYXJlbnROb2RlICYmIGVsZW0uZGlzYWJsZWQgPT09IGZhbHNlICkgewoKCQkJCS8vIE9wdGlvbiBlbGVtZW50cyBkZWZlciB0byBhIHBhcmVudCBvcHRncm91cCBpZiBwcmVzZW50CgkJCQlpZiAoICJsYWJlbCIgaW4gZWxlbSApIHsKCQkJCQlpZiAoICJsYWJlbCIgaW4gZWxlbS5wYXJlbnROb2RlICkgewoJCQkJCQlyZXR1cm4gZWxlbS5wYXJlbnROb2RlLmRpc2FibGVkID09PSBkaXNhYmxlZDsKCQkJCQl9IGVsc2UgewoJCQkJCQlyZXR1cm4gZWxlbS5kaXNhYmxlZCA9PT0gZGlzYWJsZWQ7CgkJCQkJfQoJCQkJfQoKCQkJCS8vIFN1cHBvcnQ6IElFIDYgLSAxMQoJCQkJLy8gVXNlIHRoZSBpc0Rpc2FibGVkIHNob3J0Y3V0IHByb3BlcnR5IHRvIGNoZWNrIGZvciBkaXNhYmxlZCBmaWVsZHNldCBhbmNlc3RvcnMKCQkJCXJldHVybiBlbGVtLmlzRGlzYWJsZWQgPT09IGRpc2FibGVkIHx8CgoJCQkJCS8vIFdoZXJlIHRoZXJlIGlzIG5vIGlzRGlzYWJsZWQsIGNoZWNrIG1hbnVhbGx5CgkJCQkJLyoganNoaW50IC1XMDE4ICovCgkJCQkJZWxlbS5pc0Rpc2FibGVkICE9PSAhZGlzYWJsZWQgJiYKCQkJCQkJZGlzYWJsZWRBbmNlc3RvciggZWxlbSApID09PSBkaXNhYmxlZDsKCQkJfQoKCQkJcmV0dXJuIGVsZW0uZGlzYWJsZWQgPT09IGRpc2FibGVkOwoKCQkvLyBUcnkgdG8gd2lubm93IG91dCBlbGVtZW50cyB0aGF0IGNhbid0IGJlIGRpc2FibGVkIGJlZm9yZSB0cnVzdGluZyB0aGUgZGlzYWJsZWQgcHJvcGVydHkuCgkJLy8gU29tZSB2aWN0aW1zIGdldCBjYXVnaHQgaW4gb3VyIG5ldCAobGFiZWwsIGxlZ2VuZCwgbWVudSwgdHJhY2spLCBidXQgaXQgc2hvdWxkbid0CgkJLy8gZXZlbiBleGlzdCBvbiB0aGVtLCBsZXQgYWxvbmUgaGF2ZSBhIGJvb2xlYW4gdmFsdWUuCgkJfSBlbHNlIGlmICggImxhYmVsIiBpbiBlbGVtICkgewoJCQlyZXR1cm4gZWxlbS5kaXNhYmxlZCA9PT0gZGlzYWJsZWQ7CgkJfQoKCQkvLyBSZW1haW5pbmcgZWxlbWVudHMgYXJlIG5laXRoZXIgOmVuYWJsZWQgbm9yIDpkaXNhYmxlZAoJCXJldHVybiBmYWxzZTsKCX07Cn0KCi8qKgogKiBSZXR1cm5zIGEgZnVuY3Rpb24gdG8gdXNlIGluIHBzZXVkb3MgZm9yIHBvc2l0aW9uYWxzCiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuCiAqLwpmdW5jdGlvbiBjcmVhdGVQb3NpdGlvbmFsUHNldWRvKCBmbiApIHsKCXJldHVybiBtYXJrRnVuY3Rpb24oZnVuY3Rpb24oIGFyZ3VtZW50ICkgewoJCWFyZ3VtZW50ID0gK2FyZ3VtZW50OwoJCXJldHVybiBtYXJrRnVuY3Rpb24oZnVuY3Rpb24oIHNlZWQsIG1hdGNoZXMgKSB7CgkJCXZhciBqLAoJCQkJbWF0Y2hJbmRleGVzID0gZm4oIFtdLCBzZWVkLmxlbmd0aCwgYXJndW1lbnQgKSwKCQkJCWkgPSBtYXRjaEluZGV4ZXMubGVuZ3RoOwoKCQkJLy8gTWF0Y2ggZWxlbWVudHMgZm91bmQgYXQgdGhlIHNwZWNpZmllZCBpbmRleGVzCgkJCXdoaWxlICggaS0tICkgewoJCQkJaWYgKCBzZWVkWyAoaiA9IG1hdGNoSW5kZXhlc1tpXSkgXSApIHsKCQkJCQlzZWVkW2pdID0gIShtYXRjaGVzW2pdID0gc2VlZFtqXSk7CgkJCQl9CgkJCX0KCQl9KTsKCX0pOwp9CgovKioKICogQ2hlY2tzIGEgbm9kZSBmb3IgdmFsaWRpdHkgYXMgYSBTaXp6bGUgY29udGV4dAogKiBAcGFyYW0ge0VsZW1lbnR8T2JqZWN0PX0gY29udGV4dAogKiBAcmV0dXJucyB7RWxlbWVudHxPYmplY3R8Qm9vbGVhbn0gVGhlIGlucHV0IG5vZGUgaWYgYWNjZXB0YWJsZSwgb3RoZXJ3aXNlIGEgZmFsc3kgdmFsdWUKICovCmZ1bmN0aW9uIHRlc3RDb250ZXh0KCBjb250ZXh0ICkgewoJcmV0dXJuIGNvbnRleHQgJiYgdHlwZW9mIGNvbnRleHQuZ2V0RWxlbWVudHNCeVRhZ05hbWUgIT09ICJ1bmRlZmluZWQiICYmIGNvbnRleHQ7Cn0KCi8vIEV4cG9zZSBzdXBwb3J0IHZhcnMgZm9yIGNvbnZlbmllbmNlCnN1cHBvcnQgPSBTaXp6bGUuc3VwcG9ydCA9IHt9OwoKLyoqCiAqIERldGVjdHMgWE1MIG5vZGVzCiAqIEBwYXJhbSB7RWxlbWVudHxPYmplY3R9IGVsZW0gQW4gZWxlbWVudCBvciBhIGRvY3VtZW50CiAqIEByZXR1cm5zIHtCb29sZWFufSBUcnVlIGlmZiBlbGVtIGlzIGEgbm9uLUhUTUwgWE1MIG5vZGUKICovCmlzWE1MID0gU2l6emxlLmlzWE1MID0gZnVuY3Rpb24oIGVsZW0gKSB7CgkvLyBkb2N1bWVudEVsZW1lbnQgaXMgdmVyaWZpZWQgZm9yIGNhc2VzIHdoZXJlIGl0IGRvZXNuJ3QgeWV0IGV4aXN0CgkvLyAoc3VjaCBhcyBsb2FkaW5nIGlmcmFtZXMgaW4gSUUgLSAjNDgzMykKCXZhciBkb2N1bWVudEVsZW1lbnQgPSBlbGVtICYmIChlbGVtLm93bmVyRG9jdW1lbnQgfHwgZWxlbSkuZG9jdW1lbnRFbGVtZW50OwoJcmV0dXJuIGRvY3VtZW50RWxlbWVudCA/IGRvY3VtZW50RWxlbWVudC5ub2RlTmFtZSAhPT0gIkhUTUwiIDogZmFsc2U7Cn07CgovKioKICogU2V0cyBkb2N1bWVudC1yZWxhdGVkIHZhcmlhYmxlcyBvbmNlIGJhc2VkIG9uIHRoZSBjdXJyZW50IGRvY3VtZW50CiAqIEBwYXJhbSB7RWxlbWVudHxPYmplY3R9IFtkb2NdIEFuIGVsZW1lbnQgb3IgZG9jdW1lbnQgb2JqZWN0IHRvIHVzZSB0byBzZXQgdGhlIGRvY3VtZW50CiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGN1cnJlbnQgZG9jdW1lbnQKICovCnNldERvY3VtZW50ID0gU2l6emxlLnNldERvY3VtZW50ID0gZnVuY3Rpb24oIG5vZGUgKSB7Cgl2YXIgaGFzQ29tcGFyZSwgc3ViV2luZG93LAoJCWRvYyA9IG5vZGUgPyBub2RlLm93bmVyRG9jdW1lbnQgfHwgbm9kZSA6IHByZWZlcnJlZERvYzsKCgkvLyBSZXR1cm4gZWFybHkgaWYgZG9jIGlzIGludmFsaWQgb3IgYWxyZWFkeSBzZWxlY3RlZAoJaWYgKCBkb2MgPT09IGRvY3VtZW50IHx8IGRvYy5ub2RlVHlwZSAhPT0gOSB8fCAhZG9jLmRvY3VtZW50RWxlbWVudCApIHsKCQlyZXR1cm4gZG9jdW1lbnQ7Cgl9CgoJLy8gVXBkYXRlIGdsb2JhbCB2YXJpYWJsZXMKCWRvY3VtZW50ID0gZG9jOwoJZG9jRWxlbSA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudDsKCWRvY3VtZW50SXNIVE1MID0gIWlzWE1MKCBkb2N1bWVudCApOwoKCS8vIFN1cHBvcnQ6IElFIDktMTEsIEVkZ2UKCS8vIEFjY2Vzc2luZyBpZnJhbWUgZG9jdW1lbnRzIGFmdGVyIHVubG9hZCB0aHJvd3MgInBlcm1pc3Npb24gZGVuaWVkIiBlcnJvcnMgKGpRdWVyeSAjMTM5MzYpCglpZiAoIHByZWZlcnJlZERvYyAhPT0gZG9jdW1lbnQgJiYKCQkoc3ViV2luZG93ID0gZG9jdW1lbnQuZGVmYXVsdFZpZXcpICYmIHN1YldpbmRvdy50b3AgIT09IHN1YldpbmRvdyApIHsKCgkJLy8gU3VwcG9ydDogSUUgMTEsIEVkZ2UKCQlpZiAoIHN1YldpbmRvdy5hZGRFdmVudExpc3RlbmVyICkgewoJCQlzdWJXaW5kb3cuYWRkRXZlbnRMaXN0ZW5lciggInVubG9hZCIsIHVubG9hZEhhbmRsZXIsIGZhbHNlICk7CgoJCS8vIFN1cHBvcnQ6IElFIDkgLSAxMCBvbmx5CgkJfSBlbHNlIGlmICggc3ViV2luZG93LmF0dGFjaEV2ZW50ICkgewoJCQlzdWJXaW5kb3cuYXR0YWNoRXZlbnQoICJvbnVubG9hZCIsIHVubG9hZEhhbmRsZXIgKTsKCQl9Cgl9CgoJLyogQXR0cmlidXRlcwoJLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKCS8vIFN1cHBvcnQ6IElFPDgKCS8vIFZlcmlmeSB0aGF0IGdldEF0dHJpYnV0ZSByZWFsbHkgcmV0dXJucyBhdHRyaWJ1dGVzIGFuZCBub3QgcHJvcGVydGllcwoJLy8gKGV4Y2VwdGluZyBJRTggYm9vbGVhbnMpCglzdXBwb3J0LmF0dHJpYnV0ZXMgPSBhc3NlcnQoZnVuY3Rpb24oIGVsICkgewoJCWVsLmNsYXNzTmFtZSA9ICJpIjsKCQlyZXR1cm4gIWVsLmdldEF0dHJpYnV0ZSgiY2xhc3NOYW1lIik7Cgl9KTsKCgkvKiBnZXRFbGVtZW50KHMpQnkqCgktLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgoJLy8gQ2hlY2sgaWYgZ2V0RWxlbWVudHNCeVRhZ05hbWUoIioiKSByZXR1cm5zIG9ubHkgZWxlbWVudHMKCXN1cHBvcnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUgPSBhc3NlcnQoZnVuY3Rpb24oIGVsICkgewoJCWVsLmFwcGVuZENoaWxkKCBkb2N1bWVudC5jcmVhdGVDb21tZW50KCIiKSApOwoJCXJldHVybiAhZWwuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIioiKS5sZW5ndGg7Cgl9KTsKCgkvLyBTdXBwb3J0OiBJRTw5CglzdXBwb3J0LmdldEVsZW1lbnRzQnlDbGFzc05hbWUgPSBybmF0aXZlLnRlc3QoIGRvY3VtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUgKTsKCgkvLyBTdXBwb3J0OiBJRTwxMAoJLy8gQ2hlY2sgaWYgZ2V0RWxlbWVudEJ5SWQgcmV0dXJucyBlbGVtZW50cyBieSBuYW1lCgkvLyBUaGUgYnJva2VuIGdldEVsZW1lbnRCeUlkIG1ldGhvZHMgZG9uJ3QgcGljayB1cCBwcm9ncmFtbWF0aWNhbGx5LXNldCBuYW1lcywKCS8vIHNvIHVzZSBhIHJvdW5kYWJvdXQgZ2V0RWxlbWVudHNCeU5hbWUgdGVzdAoJc3VwcG9ydC5nZXRCeUlkID0gYXNzZXJ0KGZ1bmN0aW9uKCBlbCApIHsKCQlkb2NFbGVtLmFwcGVuZENoaWxkKCBlbCApLmlkID0gZXhwYW5kbzsKCQlyZXR1cm4gIWRvY3VtZW50LmdldEVsZW1lbnRzQnlOYW1lIHx8ICFkb2N1bWVudC5nZXRFbGVtZW50c0J5TmFtZSggZXhwYW5kbyApLmxlbmd0aDsKCX0pOwoKCS8vIElEIGZpbHRlciBhbmQgZmluZAoJaWYgKCBzdXBwb3J0LmdldEJ5SWQgKSB7CgkJRXhwci5maWx0ZXJbIklEIl0gPSBmdW5jdGlvbiggaWQgKSB7CgkJCXZhciBhdHRySWQgPSBpZC5yZXBsYWNlKCBydW5lc2NhcGUsIGZ1bmVzY2FwZSApOwoJCQlyZXR1cm4gZnVuY3Rpb24oIGVsZW0gKSB7CgkJCQlyZXR1cm4gZWxlbS5nZXRBdHRyaWJ1dGUoImlkIikgPT09IGF0dHJJZDsKCQkJfTsKCQl9OwoJCUV4cHIuZmluZFsiSUQiXSA9IGZ1bmN0aW9uKCBpZCwgY29udGV4dCApIHsKCQkJaWYgKCB0eXBlb2YgY29udGV4dC5nZXRFbGVtZW50QnlJZCAhPT0gInVuZGVmaW5lZCIgJiYgZG9jdW1lbnRJc0hUTUwgKSB7CgkJCQl2YXIgZWxlbSA9IGNvbnRleHQuZ2V0RWxlbWVudEJ5SWQoIGlkICk7CgkJCQlyZXR1cm4gZWxlbSA/IFsgZWxlbSBdIDogW107CgkJCX0KCQl9OwoJfSBlbHNlIHsKCQlFeHByLmZpbHRlclsiSUQiXSA9ICBmdW5jdGlvbiggaWQgKSB7CgkJCXZhciBhdHRySWQgPSBpZC5yZXBsYWNlKCBydW5lc2NhcGUsIGZ1bmVzY2FwZSApOwoJCQlyZXR1cm4gZnVuY3Rpb24oIGVsZW0gKSB7CgkJCQl2YXIgbm9kZSA9IHR5cGVvZiBlbGVtLmdldEF0dHJpYnV0ZU5vZGUgIT09ICJ1bmRlZmluZWQiICYmCgkJCQkJZWxlbS5nZXRBdHRyaWJ1dGVOb2RlKCJpZCIpOwoJCQkJcmV0dXJuIG5vZGUgJiYgbm9kZS52YWx1ZSA9PT0gYXR0cklkOwoJCQl9OwoJCX07CgoJCS8vIFN1cHBvcnQ6IElFIDYgLSA3IG9ubHkKCQkvLyBnZXRFbGVtZW50QnlJZCBpcyBub3QgcmVsaWFibGUgYXMgYSBmaW5kIHNob3J0Y3V0CgkJRXhwci5maW5kWyJJRCJdID0gZnVuY3Rpb24oIGlkLCBjb250ZXh0ICkgewoJCQlpZiAoIHR5cGVvZiBjb250ZXh0LmdldEVsZW1lbnRCeUlkICE9PSAidW5kZWZpbmVkIiAmJiBkb2N1bWVudElzSFRNTCApIHsKCQkJCXZhciBub2RlLCBpLCBlbGVtcywKCQkJCQllbGVtID0gY29udGV4dC5nZXRFbGVtZW50QnlJZCggaWQgKTsKCgkJCQlpZiAoIGVsZW0gKSB7CgoJCQkJCS8vIFZlcmlmeSB0aGUgaWQgYXR0cmlidXRlCgkJCQkJbm9kZSA9IGVsZW0uZ2V0QXR0cmlidXRlTm9kZSgiaWQiKTsKCQkJCQlpZiAoIG5vZGUgJiYgbm9kZS52YWx1ZSA9PT0gaWQgKSB7CgkJCQkJCXJldHVybiBbIGVsZW0gXTsKCQkJCQl9CgoJCQkJCS8vIEZhbGwgYmFjayBvbiBnZXRFbGVtZW50c0J5TmFtZQoJCQkJCWVsZW1zID0gY29udGV4dC5nZXRFbGVtZW50c0J5TmFtZSggaWQgKTsKCQkJCQlpID0gMDsKCQkJCQl3aGlsZSAoIChlbGVtID0gZWxlbXNbaSsrXSkgKSB7CgkJCQkJCW5vZGUgPSBlbGVtLmdldEF0dHJpYnV0ZU5vZGUoImlkIik7CgkJCQkJCWlmICggbm9kZSAmJiBub2RlLnZhbHVlID09PSBpZCApIHsKCQkJCQkJCXJldHVybiBbIGVsZW0gXTsKCQkJCQkJfQoJCQkJCX0KCQkJCX0KCgkJCQlyZXR1cm4gW107CgkJCX0KCQl9OwoJfQoKCS8vIFRhZwoJRXhwci5maW5kWyJUQUciXSA9IHN1cHBvcnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUgPwoJCWZ1bmN0aW9uKCB0YWcsIGNvbnRleHQgKSB7CgkJCWlmICggdHlwZW9mIGNvbnRleHQuZ2V0RWxlbWVudHNCeVRhZ05hbWUgIT09ICJ1bmRlZmluZWQiICkgewoJCQkJcmV0dXJuIGNvbnRleHQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIHRhZyApOwoKCQkJLy8gRG9jdW1lbnRGcmFnbWVudCBub2RlcyBkb24ndCBoYXZlIGdFQlROCgkJCX0gZWxzZSBpZiAoIHN1cHBvcnQucXNhICkgewoJCQkJcmV0dXJuIGNvbnRleHQucXVlcnlTZWxlY3RvckFsbCggdGFnICk7CgkJCX0KCQl9IDoKCgkJZnVuY3Rpb24oIHRhZywgY29udGV4dCApIHsKCQkJdmFyIGVsZW0sCgkJCQl0bXAgPSBbXSwKCQkJCWkgPSAwLAoJCQkJLy8gQnkgaGFwcHkgY29pbmNpZGVuY2UsIGEgKGJyb2tlbikgZ0VCVE4gYXBwZWFycyBvbiBEb2N1bWVudEZyYWdtZW50IG5vZGVzIHRvbwoJCQkJcmVzdWx0cyA9IGNvbnRleHQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIHRhZyApOwoKCQkJLy8gRmlsdGVyIG91dCBwb3NzaWJsZSBjb21tZW50cwoJCQlpZiAoIHRhZyA9PT0gIioiICkgewoJCQkJd2hpbGUgKCAoZWxlbSA9IHJlc3VsdHNbaSsrXSkgKSB7CgkJCQkJaWYgKCBlbGVtLm5vZGVUeXBlID09PSAxICkgewoJCQkJCQl0bXAucHVzaCggZWxlbSApOwoJCQkJCX0KCQkJCX0KCgkJCQlyZXR1cm4gdG1wOwoJCQl9CgkJCXJldHVybiByZXN1bHRzOwoJCX07CgoJLy8gQ2xhc3MKCUV4cHIuZmluZFsiQ0xBU1MiXSA9IHN1cHBvcnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSAmJiBmdW5jdGlvbiggY2xhc3NOYW1lLCBjb250ZXh0ICkgewoJCWlmICggdHlwZW9mIGNvbnRleHQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSAhPT0gInVuZGVmaW5lZCIgJiYgZG9jdW1lbnRJc0hUTUwgKSB7CgkJCXJldHVybiBjb250ZXh0LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoIGNsYXNzTmFtZSApOwoJCX0KCX07CgoJLyogUVNBL21hdGNoZXNTZWxlY3RvcgoJLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKCS8vIFFTQSBhbmQgbWF0Y2hlc1NlbGVjdG9yIHN1cHBvcnQKCgkvLyBtYXRjaGVzU2VsZWN0b3IoOmFjdGl2ZSkgcmVwb3J0cyBmYWxzZSB3aGVuIHRydWUgKElFOS9PcGVyYSAxMS41KQoJcmJ1Z2d5TWF0Y2hlcyA9IFtdOwoKCS8vIHFTYSg6Zm9jdXMpIHJlcG9ydHMgZmFsc2Ugd2hlbiB0cnVlIChDaHJvbWUgMjEpCgkvLyBXZSBhbGxvdyB0aGlzIGJlY2F1c2Ugb2YgYSBidWcgaW4gSUU4LzkgdGhhdCB0aHJvd3MgYW4gZXJyb3IKCS8vIHdoZW5ldmVyIGBkb2N1bWVudC5hY3RpdmVFbGVtZW50YCBpcyBhY2Nlc3NlZCBvbiBhbiBpZnJhbWUKCS8vIFNvLCB3ZSBhbGxvdyA6Zm9jdXMgdG8gcGFzcyB0aHJvdWdoIFFTQSBhbGwgdGhlIHRpbWUgdG8gYXZvaWQgdGhlIElFIGVycm9yCgkvLyBTZWUgaHR0cHM6Ly9idWdzLmpxdWVyeS5jb20vdGlja2V0LzEzMzc4CglyYnVnZ3lRU0EgPSBbXTsKCglpZiAoIChzdXBwb3J0LnFzYSA9IHJuYXRpdmUudGVzdCggZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCApKSApIHsKCQkvLyBCdWlsZCBRU0EgcmVnZXgKCQkvLyBSZWdleCBzdHJhdGVneSBhZG9wdGVkIGZyb20gRGllZ28gUGVyaW5pCgkJYXNzZXJ0KGZ1bmN0aW9uKCBlbCApIHsKCQkJLy8gU2VsZWN0IGlzIHNldCB0byBlbXB0eSBzdHJpbmcgb24gcHVycG9zZQoJCQkvLyBUaGlzIGlzIHRvIHRlc3QgSUUncyB0cmVhdG1lbnQgb2Ygbm90IGV4cGxpY2l0bHkKCQkJLy8gc2V0dGluZyBhIGJvb2xlYW4gY29udGVudCBhdHRyaWJ1dGUsCgkJCS8vIHNpbmNlIGl0cyBwcmVzZW5jZSBzaG91bGQgYmUgZW5vdWdoCgkJCS8vIGh0dHBzOi8vYnVncy5qcXVlcnkuY29tL3RpY2tldC8xMjM1OQoJCQlkb2NFbGVtLmFwcGVuZENoaWxkKCBlbCApLmlubmVySFRNTCA9ICI8YSBpZD0nIiArIGV4cGFuZG8gKyAiJz48L2E+IiArCgkJCQkiPHNlbGVjdCBpZD0nIiArIGV4cGFuZG8gKyAiLVxyXFwnIG1zYWxsb3djYXB0dXJlPScnPiIgKwoJCQkJIjxvcHRpb24gc2VsZWN0ZWQ9Jyc+PC9vcHRpb24+PC9zZWxlY3Q+IjsKCgkJCS8vIFN1cHBvcnQ6IElFOCwgT3BlcmEgMTEtMTIuMTYKCQkJLy8gTm90aGluZyBzaG91bGQgYmUgc2VsZWN0ZWQgd2hlbiBlbXB0eSBzdHJpbmdzIGZvbGxvdyBePSBvciAkPSBvciAqPQoJCQkvLyBUaGUgdGVzdCBhdHRyaWJ1dGUgbXVzdCBiZSB1bmtub3duIGluIE9wZXJhIGJ1dCAic2FmZSIgZm9yIFdpblJUCgkJCS8vIGh0dHBzOi8vbXNkbi5taWNyb3NvZnQuY29tL2VuLXVzL2xpYnJhcnkvaWUvaGg0NjUzODguYXNweCNhdHRyaWJ1dGVfc2VjdGlvbgoJCQlpZiAoIGVsLnF1ZXJ5U2VsZWN0b3JBbGwoIlttc2FsbG93Y2FwdHVyZV49JyddIikubGVuZ3RoICkgewoJCQkJcmJ1Z2d5UVNBLnB1c2goICJbKl4kXT0iICsgd2hpdGVzcGFjZSArICIqKD86Jyd8XCJcIikiICk7CgkJCX0KCgkJCS8vIFN1cHBvcnQ6IElFOAoJCQkvLyBCb29sZWFuIGF0dHJpYnV0ZXMgYW5kICJ2YWx1ZSIgYXJlIG5vdCB0cmVhdGVkIGNvcnJlY3RseQoJCQlpZiAoICFlbC5xdWVyeVNlbGVjdG9yQWxsKCJbc2VsZWN0ZWRdIikubGVuZ3RoICkgewoJCQkJcmJ1Z2d5UVNBLnB1c2goICJcXFsiICsgd2hpdGVzcGFjZSArICIqKD86dmFsdWV8IiArIGJvb2xlYW5zICsgIikiICk7CgkJCX0KCgkJCS8vIFN1cHBvcnQ6IENocm9tZTwyOSwgQW5kcm9pZDw0LjQsIFNhZmFyaTw3LjArLCBpT1M8Ny4wKywgUGhhbnRvbUpTPDEuOS44KwoJCQlpZiAoICFlbC5xdWVyeVNlbGVjdG9yQWxsKCAiW2lkfj0iICsgZXhwYW5kbyArICItXSIgKS5sZW5ndGggKSB7CgkJCQlyYnVnZ3lRU0EucHVzaCgifj0iKTsKCQkJfQoKCQkJLy8gV2Via2l0L09wZXJhIC0gOmNoZWNrZWQgc2hvdWxkIHJldHVybiBzZWxlY3RlZCBvcHRpb24gZWxlbWVudHMKCQkJLy8gaHR0cDovL3d3dy53My5vcmcvVFIvMjAxMS9SRUMtY3NzMy1zZWxlY3RvcnMtMjAxMTA5MjkvI2NoZWNrZWQKCQkJLy8gSUU4IHRocm93cyBlcnJvciBoZXJlIGFuZCB3aWxsIG5vdCBzZWUgbGF0ZXIgdGVzdHMKCQkJaWYgKCAhZWwucXVlcnlTZWxlY3RvckFsbCgiOmNoZWNrZWQiKS5sZW5ndGggKSB7CgkJCQlyYnVnZ3lRU0EucHVzaCgiOmNoZWNrZWQiKTsKCQkJfQoKCQkJLy8gU3VwcG9ydDogU2FmYXJpIDgrLCBpT1MgOCsKCQkJLy8gaHR0cHM6Ly9idWdzLndlYmtpdC5vcmcvc2hvd19idWcuY2dpP2lkPTEzNjg1MQoJCQkvLyBJbi1wYWdlIGBzZWxlY3RvciNpZCBzaWJsaW5nLWNvbWJpbmF0b3Igc2VsZWN0b3JgIGZhaWxzCgkJCWlmICggIWVsLnF1ZXJ5U2VsZWN0b3JBbGwoICJhIyIgKyBleHBhbmRvICsgIisqIiApLmxlbmd0aCApIHsKCQkJCXJidWdneVFTQS5wdXNoKCIuIy4rWyt+XSIpOwoJCQl9CgkJfSk7CgoJCWFzc2VydChmdW5jdGlvbiggZWwgKSB7CgkJCWVsLmlubmVySFRNTCA9ICI8YSBocmVmPScnIGRpc2FibGVkPSdkaXNhYmxlZCc+PC9hPiIgKwoJCQkJIjxzZWxlY3QgZGlzYWJsZWQ9J2Rpc2FibGVkJz48b3B0aW9uLz48L3NlbGVjdD4iOwoKCQkJLy8gU3VwcG9ydDogV2luZG93cyA4IE5hdGl2ZSBBcHBzCgkJCS8vIFRoZSB0eXBlIGFuZCBuYW1lIGF0dHJpYnV0ZXMgYXJlIHJlc3RyaWN0ZWQgZHVyaW5nIC5pbm5lckhUTUwgYXNzaWdubWVudAoJCQl2YXIgaW5wdXQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJpbnB1dCIpOwoJCQlpbnB1dC5zZXRBdHRyaWJ1dGUoICJ0eXBlIiwgImhpZGRlbiIgKTsKCQkJZWwuYXBwZW5kQ2hpbGQoIGlucHV0ICkuc2V0QXR0cmlidXRlKCAibmFtZSIsICJEIiApOwoKCQkJLy8gU3VwcG9ydDogSUU4CgkJCS8vIEVuZm9yY2UgY2FzZS1zZW5zaXRpdml0eSBvZiBuYW1lIGF0dHJpYnV0ZQoJCQlpZiAoIGVsLnF1ZXJ5U2VsZWN0b3JBbGwoIltuYW1lPWRdIikubGVuZ3RoICkgewoJCQkJcmJ1Z2d5UVNBLnB1c2goICJuYW1lIiArIHdoaXRlc3BhY2UgKyAiKlsqXiR8IX5dPz0iICk7CgkJCX0KCgkJCS8vIEZGIDMuNSAtIDplbmFibGVkLzpkaXNhYmxlZCBhbmQgaGlkZGVuIGVsZW1lbnRzIChoaWRkZW4gZWxlbWVudHMgYXJlIHN0aWxsIGVuYWJsZWQpCgkJCS8vIElFOCB0aHJvd3MgZXJyb3IgaGVyZSBhbmQgd2lsbCBub3Qgc2VlIGxhdGVyIHRlc3RzCgkJCWlmICggZWwucXVlcnlTZWxlY3RvckFsbCgiOmVuYWJsZWQiKS5sZW5ndGggIT09IDIgKSB7CgkJCQlyYnVnZ3lRU0EucHVzaCggIjplbmFibGVkIiwgIjpkaXNhYmxlZCIgKTsKCQkJfQoKCQkJLy8gU3VwcG9ydDogSUU5LTExKwoJCQkvLyBJRSdzIDpkaXNhYmxlZCBzZWxlY3RvciBkb2VzIG5vdCBwaWNrIHVwIHRoZSBjaGlsZHJlbiBvZiBkaXNhYmxlZCBmaWVsZHNldHMKCQkJZG9jRWxlbS5hcHBlbmRDaGlsZCggZWwgKS5kaXNhYmxlZCA9IHRydWU7CgkJCWlmICggZWwucXVlcnlTZWxlY3RvckFsbCgiOmRpc2FibGVkIikubGVuZ3RoICE9PSAyICkgewoJCQkJcmJ1Z2d5UVNBLnB1c2goICI6ZW5hYmxlZCIsICI6ZGlzYWJsZWQiICk7CgkJCX0KCgkJCS8vIE9wZXJhIDEwLTExIGRvZXMgbm90IHRocm93IG9uIHBvc3QtY29tbWEgaW52YWxpZCBwc2V1ZG9zCgkJCWVsLnF1ZXJ5U2VsZWN0b3JBbGwoIiosOngiKTsKCQkJcmJ1Z2d5UVNBLnB1c2goIiwuKjoiKTsKCQl9KTsKCX0KCglpZiAoIChzdXBwb3J0Lm1hdGNoZXNTZWxlY3RvciA9IHJuYXRpdmUudGVzdCggKG1hdGNoZXMgPSBkb2NFbGVtLm1hdGNoZXMgfHwKCQlkb2NFbGVtLndlYmtpdE1hdGNoZXNTZWxlY3RvciB8fAoJCWRvY0VsZW0ubW96TWF0Y2hlc1NlbGVjdG9yIHx8CgkJZG9jRWxlbS5vTWF0Y2hlc1NlbGVjdG9yIHx8CgkJZG9jRWxlbS5tc01hdGNoZXNTZWxlY3RvcikgKSkgKSB7CgoJCWFzc2VydChmdW5jdGlvbiggZWwgKSB7CgkJCS8vIENoZWNrIHRvIHNlZSBpZiBpdCdzIHBvc3NpYmxlIHRvIGRvIG1hdGNoZXNTZWxlY3RvcgoJCQkvLyBvbiBhIGRpc2Nvbm5lY3RlZCBub2RlIChJRSA5KQoJCQlzdXBwb3J0LmRpc2Nvbm5lY3RlZE1hdGNoID0gbWF0Y2hlcy5jYWxsKCBlbCwgIioiICk7CgoJCQkvLyBUaGlzIHNob3VsZCBmYWlsIHdpdGggYW4gZXhjZXB0aW9uCgkJCS8vIEdlY2tvIGRvZXMgbm90IGVycm9yLCByZXR1cm5zIGZhbHNlIGluc3RlYWQKCQkJbWF0Y2hlcy5jYWxsKCBlbCwgIltzIT0nJ106eCIgKTsKCQkJcmJ1Z2d5TWF0Y2hlcy5wdXNoKCAiIT0iLCBwc2V1ZG9zICk7CgkJfSk7Cgl9CgoJcmJ1Z2d5UVNBID0gcmJ1Z2d5UVNBLmxlbmd0aCAmJiBuZXcgUmVnRXhwKCByYnVnZ3lRU0Euam9pbigifCIpICk7CglyYnVnZ3lNYXRjaGVzID0gcmJ1Z2d5TWF0Y2hlcy5sZW5ndGggJiYgbmV3IFJlZ0V4cCggcmJ1Z2d5TWF0Y2hlcy5qb2luKCJ8IikgKTsKCgkvKiBDb250YWlucwoJLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoJaGFzQ29tcGFyZSA9IHJuYXRpdmUudGVzdCggZG9jRWxlbS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbiApOwoKCS8vIEVsZW1lbnQgY29udGFpbnMgYW5vdGhlcgoJLy8gUHVycG9zZWZ1bGx5IHNlbGYtZXhjbHVzaXZlCgkvLyBBcyBpbiwgYW4gZWxlbWVudCBkb2VzIG5vdCBjb250YWluIGl0c2VsZgoJY29udGFpbnMgPSBoYXNDb21wYXJlIHx8IHJuYXRpdmUudGVzdCggZG9jRWxlbS5jb250YWlucyApID8KCQlmdW5jdGlvbiggYSwgYiApIHsKCQkJdmFyIGFkb3duID0gYS5ub2RlVHlwZSA9PT0gOSA/IGEuZG9jdW1lbnRFbGVtZW50IDogYSwKCQkJCWJ1cCA9IGIgJiYgYi5wYXJlbnROb2RlOwoJCQlyZXR1cm4gYSA9PT0gYnVwIHx8ICEhKCBidXAgJiYgYnVwLm5vZGVUeXBlID09PSAxICYmICgKCQkJCWFkb3duLmNvbnRhaW5zID8KCQkJCQlhZG93bi5jb250YWlucyggYnVwICkgOgoJCQkJCWEuY29tcGFyZURvY3VtZW50UG9zaXRpb24gJiYgYS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbiggYnVwICkgJiAxNgoJCQkpKTsKCQl9IDoKCQlmdW5jdGlvbiggYSwgYiApIHsKCQkJaWYgKCBiICkgewoJCQkJd2hpbGUgKCAoYiA9IGIucGFyZW50Tm9kZSkgKSB7CgkJCQkJaWYgKCBiID09PSBhICkgewoJCQkJCQlyZXR1cm4gdHJ1ZTsKCQkJCQl9CgkJCQl9CgkJCX0KCQkJcmV0dXJuIGZhbHNlOwoJCX07CgoJLyogU29ydGluZwoJLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKCS8vIERvY3VtZW50IG9yZGVyIHNvcnRpbmcKCXNvcnRPcmRlciA9IGhhc0NvbXBhcmUgPwoJZnVuY3Rpb24oIGEsIGIgKSB7CgoJCS8vIEZsYWcgZm9yIGR1cGxpY2F0ZSByZW1vdmFsCgkJaWYgKCBhID09PSBiICkgewoJCQloYXNEdXBsaWNhdGUgPSB0cnVlOwoJCQlyZXR1cm4gMDsKCQl9CgoJCS8vIFNvcnQgb24gbWV0aG9kIGV4aXN0ZW5jZSBpZiBvbmx5IG9uZSBpbnB1dCBoYXMgY29tcGFyZURvY3VtZW50UG9zaXRpb24KCQl2YXIgY29tcGFyZSA9ICFhLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uIC0gIWIuY29tcGFyZURvY3VtZW50UG9zaXRpb247CgkJaWYgKCBjb21wYXJlICkgewoJCQlyZXR1cm4gY29tcGFyZTsKCQl9CgoJCS8vIENhbGN1bGF0ZSBwb3NpdGlvbiBpZiBib3RoIGlucHV0cyBiZWxvbmcgdG8gdGhlIHNhbWUgZG9jdW1lbnQKCQljb21wYXJlID0gKCBhLm93bmVyRG9jdW1lbnQgfHwgYSApID09PSAoIGIub3duZXJEb2N1bWVudCB8fCBiICkgPwoJCQlhLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKCBiICkgOgoKCQkJLy8gT3RoZXJ3aXNlIHdlIGtub3cgdGhleSBhcmUgZGlzY29ubmVjdGVkCgkJCTE7CgoJCS8vIERpc2Nvbm5lY3RlZCBub2RlcwoJCWlmICggY29tcGFyZSAmIDEgfHwKCQkJKCFzdXBwb3J0LnNvcnREZXRhY2hlZCAmJiBiLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKCBhICkgPT09IGNvbXBhcmUpICkgewoKCQkJLy8gQ2hvb3NlIHRoZSBmaXJzdCBlbGVtZW50IHRoYXQgaXMgcmVsYXRlZCB0byBvdXIgcHJlZmVycmVkIGRvY3VtZW50CgkJCWlmICggYSA9PT0gZG9jdW1lbnQgfHwgYS5vd25lckRvY3VtZW50ID09PSBwcmVmZXJyZWREb2MgJiYgY29udGFpbnMocHJlZmVycmVkRG9jLCBhKSApIHsKCQkJCXJldHVybiAtMTsKCQkJfQoJCQlpZiAoIGIgPT09IGRvY3VtZW50IHx8IGIub3duZXJEb2N1bWVudCA9PT0gcHJlZmVycmVkRG9jICYmIGNvbnRhaW5zKHByZWZlcnJlZERvYywgYikgKSB7CgkJCQlyZXR1cm4gMTsKCQkJfQoKCQkJLy8gTWFpbnRhaW4gb3JpZ2luYWwgb3JkZXIKCQkJcmV0dXJuIHNvcnRJbnB1dCA/CgkJCQkoIGluZGV4T2YoIHNvcnRJbnB1dCwgYSApIC0gaW5kZXhPZiggc29ydElucHV0LCBiICkgKSA6CgkJCQkwOwoJCX0KCgkJcmV0dXJuIGNvbXBhcmUgJiA0ID8gLTEgOiAxOwoJfSA6CglmdW5jdGlvbiggYSwgYiApIHsKCQkvLyBFeGl0IGVhcmx5IGlmIHRoZSBub2RlcyBhcmUgaWRlbnRpY2FsCgkJaWYgKCBhID09PSBiICkgewoJCQloYXNEdXBsaWNhdGUgPSB0cnVlOwoJCQlyZXR1cm4gMDsKCQl9CgoJCXZhciBjdXIsCgkJCWkgPSAwLAoJCQlhdXAgPSBhLnBhcmVudE5vZGUsCgkJCWJ1cCA9IGIucGFyZW50Tm9kZSwKCQkJYXAgPSBbIGEgXSwKCQkJYnAgPSBbIGIgXTsKCgkJLy8gUGFyZW50bGVzcyBub2RlcyBhcmUgZWl0aGVyIGRvY3VtZW50cyBvciBkaXNjb25uZWN0ZWQKCQlpZiAoICFhdXAgfHwgIWJ1cCApIHsKCQkJcmV0dXJuIGEgPT09IGRvY3VtZW50ID8gLTEgOgoJCQkJYiA9PT0gZG9jdW1lbnQgPyAxIDoKCQkJCWF1cCA/IC0xIDoKCQkJCWJ1cCA/IDEgOgoJCQkJc29ydElucHV0ID8KCQkJCSggaW5kZXhPZiggc29ydElucHV0LCBhICkgLSBpbmRleE9mKCBzb3J0SW5wdXQsIGIgKSApIDoKCQkJCTA7CgoJCS8vIElmIHRoZSBub2RlcyBhcmUgc2libGluZ3MsIHdlIGNhbiBkbyBhIHF1aWNrIGNoZWNrCgkJfSBlbHNlIGlmICggYXVwID09PSBidXAgKSB7CgkJCXJldHVybiBzaWJsaW5nQ2hlY2soIGEsIGIgKTsKCQl9CgoJCS8vIE90aGVyd2lzZSB3ZSBuZWVkIGZ1bGwgbGlzdHMgb2YgdGhlaXIgYW5jZXN0b3JzIGZvciBjb21wYXJpc29uCgkJY3VyID0gYTsKCQl3aGlsZSAoIChjdXIgPSBjdXIucGFyZW50Tm9kZSkgKSB7CgkJCWFwLnVuc2hpZnQoIGN1ciApOwoJCX0KCQljdXIgPSBiOwoJCXdoaWxlICggKGN1ciA9IGN1ci5wYXJlbnROb2RlKSApIHsKCQkJYnAudW5zaGlmdCggY3VyICk7CgkJfQoKCQkvLyBXYWxrIGRvd24gdGhlIHRyZWUgbG9va2luZyBmb3IgYSBkaXNjcmVwYW5jeQoJCXdoaWxlICggYXBbaV0gPT09IGJwW2ldICkgewoJCQlpKys7CgkJfQoKCQlyZXR1cm4gaSA/CgkJCS8vIERvIGEgc2libGluZyBjaGVjayBpZiB0aGUgbm9kZXMgaGF2ZSBhIGNvbW1vbiBhbmNlc3RvcgoJCQlzaWJsaW5nQ2hlY2soIGFwW2ldLCBicFtpXSApIDoKCgkJCS8vIE90aGVyd2lzZSBub2RlcyBpbiBvdXIgZG9jdW1lbnQgc29ydCBmaXJzdAoJCQlhcFtpXSA9PT0gcHJlZmVycmVkRG9jID8gLTEgOgoJCQlicFtpXSA9PT0gcHJlZmVycmVkRG9jID8gMSA6CgkJCTA7Cgl9OwoKCXJldHVybiBkb2N1bWVudDsKfTsKClNpenpsZS5tYXRjaGVzID0gZnVuY3Rpb24oIGV4cHIsIGVsZW1lbnRzICkgewoJcmV0dXJuIFNpenpsZSggZXhwciwgbnVsbCwgbnVsbCwgZWxlbWVudHMgKTsKfTsKClNpenpsZS5tYXRjaGVzU2VsZWN0b3IgPSBmdW5jdGlvbiggZWxlbSwgZXhwciApIHsKCS8vIFNldCBkb2N1bWVudCB2YXJzIGlmIG5lZWRlZAoJaWYgKCAoIGVsZW0ub3duZXJEb2N1bWVudCB8fCBlbGVtICkgIT09IGRvY3VtZW50ICkgewoJCXNldERvY3VtZW50KCBlbGVtICk7Cgl9CgoJLy8gTWFrZSBzdXJlIHRoYXQgYXR0cmlidXRlIHNlbGVjdG9ycyBhcmUgcXVvdGVkCglleHByID0gZXhwci5yZXBsYWNlKCByYXR0cmlidXRlUXVvdGVzLCAiPSckMSddIiApOwoKCWlmICggc3VwcG9ydC5tYXRjaGVzU2VsZWN0b3IgJiYgZG9jdW1lbnRJc0hUTUwgJiYKCQkhY29tcGlsZXJDYWNoZVsgZXhwciArICIgIiBdICYmCgkJKCAhcmJ1Z2d5TWF0Y2hlcyB8fCAhcmJ1Z2d5TWF0Y2hlcy50ZXN0KCBleHByICkgKSAmJgoJCSggIXJidWdneVFTQSAgICAgfHwgIXJidWdneVFTQS50ZXN0KCBleHByICkgKSApIHsKCgkJdHJ5IHsKCQkJdmFyIHJldCA9IG1hdGNoZXMuY2FsbCggZWxlbSwgZXhwciApOwoKCQkJLy8gSUUgOSdzIG1hdGNoZXNTZWxlY3RvciByZXR1cm5zIGZhbHNlIG9uIGRpc2Nvbm5lY3RlZCBub2RlcwoJCQlpZiAoIHJldCB8fCBzdXBwb3J0LmRpc2Nvbm5lY3RlZE1hdGNoIHx8CgkJCQkJLy8gQXMgd2VsbCwgZGlzY29ubmVjdGVkIG5vZGVzIGFyZSBzYWlkIHRvIGJlIGluIGEgZG9jdW1lbnQKCQkJCQkvLyBmcmFnbWVudCBpbiBJRSA5CgkJCQkJZWxlbS5kb2N1bWVudCAmJiBlbGVtLmRvY3VtZW50Lm5vZGVUeXBlICE9PSAxMSApIHsKCQkJCXJldHVybiByZXQ7CgkJCX0KCQl9IGNhdGNoIChlKSB7fQoJfQoKCXJldHVybiBTaXp6bGUoIGV4cHIsIGRvY3VtZW50LCBudWxsLCBbIGVsZW0gXSApLmxlbmd0aCA+IDA7Cn07CgpTaXp6bGUuY29udGFpbnMgPSBmdW5jdGlvbiggY29udGV4dCwgZWxlbSApIHsKCS8vIFNldCBkb2N1bWVudCB2YXJzIGlmIG5lZWRlZAoJaWYgKCAoIGNvbnRleHQub3duZXJEb2N1bWVudCB8fCBjb250ZXh0ICkgIT09IGRvY3VtZW50ICkgewoJCXNldERvY3VtZW50KCBjb250ZXh0ICk7Cgl9CglyZXR1cm4gY29udGFpbnMoIGNvbnRleHQsIGVsZW0gKTsKfTsKClNpenpsZS5hdHRyID0gZnVuY3Rpb24oIGVsZW0sIG5hbWUgKSB7CgkvLyBTZXQgZG9jdW1lbnQgdmFycyBpZiBuZWVkZWQKCWlmICggKCBlbGVtLm93bmVyRG9jdW1lbnQgfHwgZWxlbSApICE9PSBkb2N1bWVudCApIHsKCQlzZXREb2N1bWVudCggZWxlbSApOwoJfQoKCXZhciBmbiA9IEV4cHIuYXR0ckhhbmRsZVsgbmFtZS50b0xvd2VyQ2FzZSgpIF0sCgkJLy8gRG9uJ3QgZ2V0IGZvb2xlZCBieSBPYmplY3QucHJvdG90eXBlIHByb3BlcnRpZXMgKGpRdWVyeSAjMTM4MDcpCgkJdmFsID0gZm4gJiYgaGFzT3duLmNhbGwoIEV4cHIuYXR0ckhhbmRsZSwgbmFtZS50b0xvd2VyQ2FzZSgpICkgPwoJCQlmbiggZWxlbSwgbmFtZSwgIWRvY3VtZW50SXNIVE1MICkgOgoJCQl1bmRlZmluZWQ7CgoJcmV0dXJuIHZhbCAhPT0gdW5kZWZpbmVkID8KCQl2YWwgOgoJCXN1cHBvcnQuYXR0cmlidXRlcyB8fCAhZG9jdW1lbnRJc0hUTUwgPwoJCQllbGVtLmdldEF0dHJpYnV0ZSggbmFtZSApIDoKCQkJKHZhbCA9IGVsZW0uZ2V0QXR0cmlidXRlTm9kZShuYW1lKSkgJiYgdmFsLnNwZWNpZmllZCA/CgkJCQl2YWwudmFsdWUgOgoJCQkJbnVsbDsKfTsKClNpenpsZS5lc2NhcGUgPSBmdW5jdGlvbiggc2VsICkgewoJcmV0dXJuIChzZWwgKyAiIikucmVwbGFjZSggcmNzc2VzY2FwZSwgZmNzc2VzY2FwZSApOwp9OwoKU2l6emxlLmVycm9yID0gZnVuY3Rpb24oIG1zZyApIHsKCXRocm93IG5ldyBFcnJvciggIlN5bnRheCBlcnJvciwgdW5yZWNvZ25pemVkIGV4cHJlc3Npb246ICIgKyBtc2cgKTsKfTsKCi8qKgogKiBEb2N1bWVudCBzb3J0aW5nIGFuZCByZW1vdmluZyBkdXBsaWNhdGVzCiAqIEBwYXJhbSB7QXJyYXlMaWtlfSByZXN1bHRzCiAqLwpTaXp6bGUudW5pcXVlU29ydCA9IGZ1bmN0aW9uKCByZXN1bHRzICkgewoJdmFyIGVsZW0sCgkJZHVwbGljYXRlcyA9IFtdLAoJCWogPSAwLAoJCWkgPSAwOwoKCS8vIFVubGVzcyB3ZSAqa25vdyogd2UgY2FuIGRldGVjdCBkdXBsaWNhdGVzLCBhc3N1bWUgdGhlaXIgcHJlc2VuY2UKCWhhc0R1cGxpY2F0ZSA9ICFzdXBwb3J0LmRldGVjdER1cGxpY2F0ZXM7Cglzb3J0SW5wdXQgPSAhc3VwcG9ydC5zb3J0U3RhYmxlICYmIHJlc3VsdHMuc2xpY2UoIDAgKTsKCXJlc3VsdHMuc29ydCggc29ydE9yZGVyICk7CgoJaWYgKCBoYXNEdXBsaWNhdGUgKSB7CgkJd2hpbGUgKCAoZWxlbSA9IHJlc3VsdHNbaSsrXSkgKSB7CgkJCWlmICggZWxlbSA9PT0gcmVzdWx0c1sgaSBdICkgewoJCQkJaiA9IGR1cGxpY2F0ZXMucHVzaCggaSApOwoJCQl9CgkJfQoJCXdoaWxlICggai0tICkgewoJCQlyZXN1bHRzLnNwbGljZSggZHVwbGljYXRlc1sgaiBdLCAxICk7CgkJfQoJfQoKCS8vIENsZWFyIGlucHV0IGFmdGVyIHNvcnRpbmcgdG8gcmVsZWFzZSBvYmplY3RzCgkvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2pxdWVyeS9zaXp6bGUvcHVsbC8yMjUKCXNvcnRJbnB1dCA9IG51bGw7CgoJcmV0dXJuIHJlc3VsdHM7Cn07CgovKioKICogVXRpbGl0eSBmdW5jdGlvbiBmb3IgcmV0cmlldmluZyB0aGUgdGV4dCB2YWx1ZSBvZiBhbiBhcnJheSBvZiBET00gbm9kZXMKICogQHBhcmFtIHtBcnJheXxFbGVtZW50fSBlbGVtCiAqLwpnZXRUZXh0ID0gU2l6emxlLmdldFRleHQgPSBmdW5jdGlvbiggZWxlbSApIHsKCXZhciBub2RlLAoJCXJldCA9ICIiLAoJCWkgPSAwLAoJCW5vZGVUeXBlID0gZWxlbS5ub2RlVHlwZTsKCglpZiAoICFub2RlVHlwZSApIHsKCQkvLyBJZiBubyBub2RlVHlwZSwgdGhpcyBpcyBleHBlY3RlZCB0byBiZSBhbiBhcnJheQoJCXdoaWxlICggKG5vZGUgPSBlbGVtW2krK10pICkgewoJCQkvLyBEbyBub3QgdHJhdmVyc2UgY29tbWVudCBub2RlcwoJCQlyZXQgKz0gZ2V0VGV4dCggbm9kZSApOwoJCX0KCX0gZWxzZSBpZiAoIG5vZGVUeXBlID09PSAxIHx8IG5vZGVUeXBlID09PSA5IHx8IG5vZGVUeXBlID09PSAxMSApIHsKCQkvLyBVc2UgdGV4dENvbnRlbnQgZm9yIGVsZW1lbnRzCgkJLy8gaW5uZXJUZXh0IHVzYWdlIHJlbW92ZWQgZm9yIGNvbnNpc3RlbmN5IG9mIG5ldyBsaW5lcyAoalF1ZXJ5ICMxMTE1MykKCQlpZiAoIHR5cGVvZiBlbGVtLnRleHRDb250ZW50ID09PSAic3RyaW5nIiApIHsKCQkJcmV0dXJuIGVsZW0udGV4dENvbnRlbnQ7CgkJfSBlbHNlIHsKCQkJLy8gVHJhdmVyc2UgaXRzIGNoaWxkcmVuCgkJCWZvciAoIGVsZW0gPSBlbGVtLmZpcnN0Q2hpbGQ7IGVsZW07IGVsZW0gPSBlbGVtLm5leHRTaWJsaW5nICkgewoJCQkJcmV0ICs9IGdldFRleHQoIGVsZW0gKTsKCQkJfQoJCX0KCX0gZWxzZSBpZiAoIG5vZGVUeXBlID09PSAzIHx8IG5vZGVUeXBlID09PSA0ICkgewoJCXJldHVybiBlbGVtLm5vZGVWYWx1ZTsKCX0KCS8vIERvIG5vdCBpbmNsdWRlIGNvbW1lbnQgb3IgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbiBub2RlcwoKCXJldHVybiByZXQ7Cn07CgpFeHByID0gU2l6emxlLnNlbGVjdG9ycyA9IHsKCgkvLyBDYW4gYmUgYWRqdXN0ZWQgYnkgdGhlIHVzZXIKCWNhY2hlTGVuZ3RoOiA1MCwKCgljcmVhdGVQc2V1ZG86IG1hcmtGdW5jdGlvbiwKCgltYXRjaDogbWF0Y2hFeHByLAoKCWF0dHJIYW5kbGU6IHt9LAoKCWZpbmQ6IHt9LAoKCXJlbGF0aXZlOiB7CgkJIj4iOiB7IGRpcjogInBhcmVudE5vZGUiLCBmaXJzdDogdHJ1ZSB9LAoJCSIgIjogeyBkaXI6ICJwYXJlbnROb2RlIiB9LAoJCSIrIjogeyBkaXI6ICJwcmV2aW91c1NpYmxpbmciLCBmaXJzdDogdHJ1ZSB9LAoJCSJ+IjogeyBkaXI6ICJwcmV2aW91c1NpYmxpbmciIH0KCX0sCgoJcHJlRmlsdGVyOiB7CgkJIkFUVFIiOiBmdW5jdGlvbiggbWF0Y2ggKSB7CgkJCW1hdGNoWzFdID0gbWF0Y2hbMV0ucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKTsKCgkJCS8vIE1vdmUgdGhlIGdpdmVuIHZhbHVlIHRvIG1hdGNoWzNdIHdoZXRoZXIgcXVvdGVkIG9yIHVucXVvdGVkCgkJCW1hdGNoWzNdID0gKCBtYXRjaFszXSB8fCBtYXRjaFs0XSB8fCBtYXRjaFs1XSB8fCAiIiApLnJlcGxhY2UoIHJ1bmVzY2FwZSwgZnVuZXNjYXBlICk7CgoJCQlpZiAoIG1hdGNoWzJdID09PSAifj0iICkgewoJCQkJbWF0Y2hbM10gPSAiICIgKyBtYXRjaFszXSArICIgIjsKCQkJfQoKCQkJcmV0dXJuIG1hdGNoLnNsaWNlKCAwLCA0ICk7CgkJfSwKCgkJIkNISUxEIjogZnVuY3Rpb24oIG1hdGNoICkgewoJCQkvKiBtYXRjaGVzIGZyb20gbWF0Y2hFeHByWyJDSElMRCJdCgkJCQkxIHR5cGUgKG9ubHl8bnRofC4uLikKCQkJCTIgd2hhdCAoY2hpbGR8b2YtdHlwZSkKCQkJCTMgYXJndW1lbnQgKGV2ZW58b2RkfFxkKnxcZCpuKFsrLV1cZCspP3wuLi4pCgkJCQk0IHhuLWNvbXBvbmVudCBvZiB4bit5IGFyZ3VtZW50IChbKy1dP1xkKm58KQoJCQkJNSBzaWduIG9mIHhuLWNvbXBvbmVudAoJCQkJNiB4IG9mIHhuLWNvbXBvbmVudAoJCQkJNyBzaWduIG9mIHktY29tcG9uZW50CgkJCQk4IHkgb2YgeS1jb21wb25lbnQKCQkJKi8KCQkJbWF0Y2hbMV0gPSBtYXRjaFsxXS50b0xvd2VyQ2FzZSgpOwoKCQkJaWYgKCBtYXRjaFsxXS5zbGljZSggMCwgMyApID09PSAibnRoIiApIHsKCQkJCS8vIG50aC0qIHJlcXVpcmVzIGFyZ3VtZW50CgkJCQlpZiAoICFtYXRjaFszXSApIHsKCQkJCQlTaXp6bGUuZXJyb3IoIG1hdGNoWzBdICk7CgkJCQl9CgoJCQkJLy8gbnVtZXJpYyB4IGFuZCB5IHBhcmFtZXRlcnMgZm9yIEV4cHIuZmlsdGVyLkNISUxECgkJCQkvLyByZW1lbWJlciB0aGF0IGZhbHNlL3RydWUgY2FzdCByZXNwZWN0aXZlbHkgdG8gMC8xCgkJCQltYXRjaFs0XSA9ICsoIG1hdGNoWzRdID8gbWF0Y2hbNV0gKyAobWF0Y2hbNl0gfHwgMSkgOiAyICogKCBtYXRjaFszXSA9PT0gImV2ZW4iIHx8IG1hdGNoWzNdID09PSAib2RkIiApICk7CgkJCQltYXRjaFs1XSA9ICsoICggbWF0Y2hbN10gKyBtYXRjaFs4XSApIHx8IG1hdGNoWzNdID09PSAib2RkIiApOwoKCQkJLy8gb3RoZXIgdHlwZXMgcHJvaGliaXQgYXJndW1lbnRzCgkJCX0gZWxzZSBpZiAoIG1hdGNoWzNdICkgewoJCQkJU2l6emxlLmVycm9yKCBtYXRjaFswXSApOwoJCQl9CgoJCQlyZXR1cm4gbWF0Y2g7CgkJfSwKCgkJIlBTRVVETyI6IGZ1bmN0aW9uKCBtYXRjaCApIHsKCQkJdmFyIGV4Y2VzcywKCQkJCXVucXVvdGVkID0gIW1hdGNoWzZdICYmIG1hdGNoWzJdOwoKCQkJaWYgKCBtYXRjaEV4cHJbIkNISUxEIl0udGVzdCggbWF0Y2hbMF0gKSApIHsKCQkJCXJldHVybiBudWxsOwoJCQl9CgoJCQkvLyBBY2NlcHQgcXVvdGVkIGFyZ3VtZW50cyBhcy1pcwoJCQlpZiAoIG1hdGNoWzNdICkgewoJCQkJbWF0Y2hbMl0gPSBtYXRjaFs0XSB8fCBtYXRjaFs1XSB8fCAiIjsKCgkJCS8vIFN0cmlwIGV4Y2VzcyBjaGFyYWN0ZXJzIGZyb20gdW5xdW90ZWQgYXJndW1lbnRzCgkJCX0gZWxzZSBpZiAoIHVucXVvdGVkICYmIHJwc2V1ZG8udGVzdCggdW5xdW90ZWQgKSAmJgoJCQkJLy8gR2V0IGV4Y2VzcyBmcm9tIHRva2VuaXplIChyZWN1cnNpdmVseSkKCQkJCShleGNlc3MgPSB0b2tlbml6ZSggdW5xdW90ZWQsIHRydWUgKSkgJiYKCQkJCS8vIGFkdmFuY2UgdG8gdGhlIG5leHQgY2xvc2luZyBwYXJlbnRoZXNpcwoJCQkJKGV4Y2VzcyA9IHVucXVvdGVkLmluZGV4T2YoICIpIiwgdW5xdW90ZWQubGVuZ3RoIC0gZXhjZXNzICkgLSB1bnF1b3RlZC5sZW5ndGgpICkgewoKCQkJCS8vIGV4Y2VzcyBpcyBhIG5lZ2F0aXZlIGluZGV4CgkJCQltYXRjaFswXSA9IG1hdGNoWzBdLnNsaWNlKCAwLCBleGNlc3MgKTsKCQkJCW1hdGNoWzJdID0gdW5xdW90ZWQuc2xpY2UoIDAsIGV4Y2VzcyApOwoJCQl9CgoJCQkvLyBSZXR1cm4gb25seSBjYXB0dXJlcyBuZWVkZWQgYnkgdGhlIHBzZXVkbyBmaWx0ZXIgbWV0aG9kICh0eXBlIGFuZCBhcmd1bWVudCkKCQkJcmV0dXJuIG1hdGNoLnNsaWNlKCAwLCAzICk7CgkJfQoJfSwKCglmaWx0ZXI6IHsKCgkJIlRBRyI6IGZ1bmN0aW9uKCBub2RlTmFtZVNlbGVjdG9yICkgewoJCQl2YXIgbm9kZU5hbWUgPSBub2RlTmFtZVNlbGVjdG9yLnJlcGxhY2UoIHJ1bmVzY2FwZSwgZnVuZXNjYXBlICkudG9Mb3dlckNhc2UoKTsKCQkJcmV0dXJuIG5vZGVOYW1lU2VsZWN0b3IgPT09ICIqIiA/CgkJCQlmdW5jdGlvbigpIHsgcmV0dXJuIHRydWU7IH0gOgoJCQkJZnVuY3Rpb24oIGVsZW0gKSB7CgkJCQkJcmV0dXJuIGVsZW0ubm9kZU5hbWUgJiYgZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpID09PSBub2RlTmFtZTsKCQkJCX07CgkJfSwKCgkJIkNMQVNTIjogZnVuY3Rpb24oIGNsYXNzTmFtZSApIHsKCQkJdmFyIHBhdHRlcm4gPSBjbGFzc0NhY2hlWyBjbGFzc05hbWUgKyAiICIgXTsKCgkJCXJldHVybiBwYXR0ZXJuIHx8CgkJCQkocGF0dGVybiA9IG5ldyBSZWdFeHAoICIoXnwiICsgd2hpdGVzcGFjZSArICIpIiArIGNsYXNzTmFtZSArICIoIiArIHdoaXRlc3BhY2UgKyAifCQpIiApKSAmJgoJCQkJY2xhc3NDYWNoZSggY2xhc3NOYW1lLCBmdW5jdGlvbiggZWxlbSApIHsKCQkJCQlyZXR1cm4gcGF0dGVybi50ZXN0KCB0eXBlb2YgZWxlbS5jbGFzc05hbWUgPT09ICJzdHJpbmciICYmIGVsZW0uY2xhc3NOYW1lIHx8IHR5cGVvZiBlbGVtLmdldEF0dHJpYnV0ZSAhPT0gInVuZGVmaW5lZCIgJiYgZWxlbS5nZXRBdHRyaWJ1dGUoImNsYXNzIikgfHwgIiIgKTsKCQkJCX0pOwoJCX0sCgoJCSJBVFRSIjogZnVuY3Rpb24oIG5hbWUsIG9wZXJhdG9yLCBjaGVjayApIHsKCQkJcmV0dXJuIGZ1bmN0aW9uKCBlbGVtICkgewoJCQkJdmFyIHJlc3VsdCA9IFNpenpsZS5hdHRyKCBlbGVtLCBuYW1lICk7CgoJCQkJaWYgKCByZXN1bHQgPT0gbnVsbCApIHsKCQkJCQlyZXR1cm4gb3BlcmF0b3IgPT09ICIhPSI7CgkJCQl9CgkJCQlpZiAoICFvcGVyYXRvciApIHsKCQkJCQlyZXR1cm4gdHJ1ZTsKCQkJCX0KCgkJCQlyZXN1bHQgKz0gIiI7CgoJCQkJcmV0dXJuIG9wZXJhdG9yID09PSAiPSIgPyByZXN1bHQgPT09IGNoZWNrIDoKCQkJCQlvcGVyYXRvciA9PT0gIiE9IiA/IHJlc3VsdCAhPT0gY2hlY2sgOgoJCQkJCW9wZXJhdG9yID09PSAiXj0iID8gY2hlY2sgJiYgcmVzdWx0LmluZGV4T2YoIGNoZWNrICkgPT09IDAgOgoJCQkJCW9wZXJhdG9yID09PSAiKj0iID8gY2hlY2sgJiYgcmVzdWx0LmluZGV4T2YoIGNoZWNrICkgPiAtMSA6CgkJCQkJb3BlcmF0b3IgPT09ICIkPSIgPyBjaGVjayAmJiByZXN1bHQuc2xpY2UoIC1jaGVjay5sZW5ndGggKSA9PT0gY2hlY2sgOgoJCQkJCW9wZXJhdG9yID09PSAifj0iID8gKCAiICIgKyByZXN1bHQucmVwbGFjZSggcndoaXRlc3BhY2UsICIgIiApICsgIiAiICkuaW5kZXhPZiggY2hlY2sgKSA+IC0xIDoKCQkJCQlvcGVyYXRvciA9PT0gInw9IiA/IHJlc3VsdCA9PT0gY2hlY2sgfHwgcmVzdWx0LnNsaWNlKCAwLCBjaGVjay5sZW5ndGggKyAxICkgPT09IGNoZWNrICsgIi0iIDoKCQkJCQlmYWxzZTsKCQkJfTsKCQl9LAoKCQkiQ0hJTEQiOiBmdW5jdGlvbiggdHlwZSwgd2hhdCwgYXJndW1lbnQsIGZpcnN0LCBsYXN0ICkgewoJCQl2YXIgc2ltcGxlID0gdHlwZS5zbGljZSggMCwgMyApICE9PSAibnRoIiwKCQkJCWZvcndhcmQgPSB0eXBlLnNsaWNlKCAtNCApICE9PSAibGFzdCIsCgkJCQlvZlR5cGUgPSB3aGF0ID09PSAib2YtdHlwZSI7CgoJCQlyZXR1cm4gZmlyc3QgPT09IDEgJiYgbGFzdCA9PT0gMCA/CgoJCQkJLy8gU2hvcnRjdXQgZm9yIDpudGgtKihuKQoJCQkJZnVuY3Rpb24oIGVsZW0gKSB7CgkJCQkJcmV0dXJuICEhZWxlbS5wYXJlbnROb2RlOwoJCQkJfSA6CgoJCQkJZnVuY3Rpb24oIGVsZW0sIGNvbnRleHQsIHhtbCApIHsKCQkJCQl2YXIgY2FjaGUsIHVuaXF1ZUNhY2hlLCBvdXRlckNhY2hlLCBub2RlLCBub2RlSW5kZXgsIHN0YXJ0LAoJCQkJCQlkaXIgPSBzaW1wbGUgIT09IGZvcndhcmQgPyAibmV4dFNpYmxpbmciIDogInByZXZpb3VzU2libGluZyIsCgkJCQkJCXBhcmVudCA9IGVsZW0ucGFyZW50Tm9kZSwKCQkJCQkJbmFtZSA9IG9mVHlwZSAmJiBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCksCgkJCQkJCXVzZUNhY2hlID0gIXhtbCAmJiAhb2ZUeXBlLAoJCQkJCQlkaWZmID0gZmFsc2U7CgoJCQkJCWlmICggcGFyZW50ICkgewoKCQkJCQkJLy8gOihmaXJzdHxsYXN0fG9ubHkpLShjaGlsZHxvZi10eXBlKQoJCQkJCQlpZiAoIHNpbXBsZSApIHsKCQkJCQkJCXdoaWxlICggZGlyICkgewoJCQkJCQkJCW5vZGUgPSBlbGVtOwoJCQkJCQkJCXdoaWxlICggKG5vZGUgPSBub2RlWyBkaXIgXSkgKSB7CgkJCQkJCQkJCWlmICggb2ZUeXBlID8KCQkJCQkJCQkJCW5vZGUubm9kZU5hbWUudG9Mb3dlckNhc2UoKSA9PT0gbmFtZSA6CgkJCQkJCQkJCQlub2RlLm5vZGVUeXBlID09PSAxICkgewoKCQkJCQkJCQkJCXJldHVybiBmYWxzZTsKCQkJCQkJCQkJfQoJCQkJCQkJCX0KCQkJCQkJCQkvLyBSZXZlcnNlIGRpcmVjdGlvbiBmb3IgOm9ubHktKiAoaWYgd2UgaGF2ZW4ndCB5ZXQgZG9uZSBzbykKCQkJCQkJCQlzdGFydCA9IGRpciA9IHR5cGUgPT09ICJvbmx5IiAmJiAhc3RhcnQgJiYgIm5leHRTaWJsaW5nIjsKCQkJCQkJCX0KCQkJCQkJCXJldHVybiB0cnVlOwoJCQkJCQl9CgoJCQkJCQlzdGFydCA9IFsgZm9yd2FyZCA/IHBhcmVudC5maXJzdENoaWxkIDogcGFyZW50Lmxhc3RDaGlsZCBdOwoKCQkJCQkJLy8gbm9uLXhtbCA6bnRoLWNoaWxkKC4uLikgc3RvcmVzIGNhY2hlIGRhdGEgb24gYHBhcmVudGAKCQkJCQkJaWYgKCBmb3J3YXJkICYmIHVzZUNhY2hlICkgewoKCQkJCQkJCS8vIFNlZWsgYGVsZW1gIGZyb20gYSBwcmV2aW91c2x5LWNhY2hlZCBpbmRleAoKCQkJCQkJCS8vIC4uLmluIGEgZ3ppcC1mcmllbmRseSB3YXkKCQkJCQkJCW5vZGUgPSBwYXJlbnQ7CgkJCQkJCQlvdXRlckNhY2hlID0gbm9kZVsgZXhwYW5kbyBdIHx8IChub2RlWyBleHBhbmRvIF0gPSB7fSk7CgoJCQkJCQkJLy8gU3VwcG9ydDogSUUgPDkgb25seQoJCQkJCQkJLy8gRGVmZW5kIGFnYWluc3QgY2xvbmVkIGF0dHJvcGVydGllcyAoalF1ZXJ5IGdoLTE3MDkpCgkJCQkJCQl1bmlxdWVDYWNoZSA9IG91dGVyQ2FjaGVbIG5vZGUudW5pcXVlSUQgXSB8fAoJCQkJCQkJCShvdXRlckNhY2hlWyBub2RlLnVuaXF1ZUlEIF0gPSB7fSk7CgoJCQkJCQkJY2FjaGUgPSB1bmlxdWVDYWNoZVsgdHlwZSBdIHx8IFtdOwoJCQkJCQkJbm9kZUluZGV4ID0gY2FjaGVbIDAgXSA9PT0gZGlycnVucyAmJiBjYWNoZVsgMSBdOwoJCQkJCQkJZGlmZiA9IG5vZGVJbmRleCAmJiBjYWNoZVsgMiBdOwoJCQkJCQkJbm9kZSA9IG5vZGVJbmRleCAmJiBwYXJlbnQuY2hpbGROb2Rlc1sgbm9kZUluZGV4IF07CgoJCQkJCQkJd2hpbGUgKCAobm9kZSA9ICsrbm9kZUluZGV4ICYmIG5vZGUgJiYgbm9kZVsgZGlyIF0gfHwKCgkJCQkJCQkJLy8gRmFsbGJhY2sgdG8gc2Vla2luZyBgZWxlbWAgZnJvbSB0aGUgc3RhcnQKCQkJCQkJCQkoZGlmZiA9IG5vZGVJbmRleCA9IDApIHx8IHN0YXJ0LnBvcCgpKSApIHsKCgkJCQkJCQkJLy8gV2hlbiBmb3VuZCwgY2FjaGUgaW5kZXhlcyBvbiBgcGFyZW50YCBhbmQgYnJlYWsKCQkJCQkJCQlpZiAoIG5vZGUubm9kZVR5cGUgPT09IDEgJiYgKytkaWZmICYmIG5vZGUgPT09IGVsZW0gKSB7CgkJCQkJCQkJCXVuaXF1ZUNhY2hlWyB0eXBlIF0gPSBbIGRpcnJ1bnMsIG5vZGVJbmRleCwgZGlmZiBdOwoJCQkJCQkJCQlicmVhazsKCQkJCQkJCQl9CgkJCQkJCQl9CgoJCQkJCQl9IGVsc2UgewoJCQkJCQkJLy8gVXNlIHByZXZpb3VzbHktY2FjaGVkIGVsZW1lbnQgaW5kZXggaWYgYXZhaWxhYmxlCgkJCQkJCQlpZiAoIHVzZUNhY2hlICkgewoJCQkJCQkJCS8vIC4uLmluIGEgZ3ppcC1mcmllbmRseSB3YXkKCQkJCQkJCQlub2RlID0gZWxlbTsKCQkJCQkJCQlvdXRlckNhY2hlID0gbm9kZVsgZXhwYW5kbyBdIHx8IChub2RlWyBleHBhbmRvIF0gPSB7fSk7CgoJCQkJCQkJCS8vIFN1cHBvcnQ6IElFIDw5IG9ubHkKCQkJCQkJCQkvLyBEZWZlbmQgYWdhaW5zdCBjbG9uZWQgYXR0cm9wZXJ0aWVzIChqUXVlcnkgZ2gtMTcwOSkKCQkJCQkJCQl1bmlxdWVDYWNoZSA9IG91dGVyQ2FjaGVbIG5vZGUudW5pcXVlSUQgXSB8fAoJCQkJCQkJCQkob3V0ZXJDYWNoZVsgbm9kZS51bmlxdWVJRCBdID0ge30pOwoKCQkJCQkJCQljYWNoZSA9IHVuaXF1ZUNhY2hlWyB0eXBlIF0gfHwgW107CgkJCQkJCQkJbm9kZUluZGV4ID0gY2FjaGVbIDAgXSA9PT0gZGlycnVucyAmJiBjYWNoZVsgMSBdOwoJCQkJCQkJCWRpZmYgPSBub2RlSW5kZXg7CgkJCQkJCQl9CgoJCQkJCQkJLy8geG1sIDpudGgtY2hpbGQoLi4uKQoJCQkJCQkJLy8gb3IgOm50aC1sYXN0LWNoaWxkKC4uLikgb3IgOm50aCgtbGFzdCk/LW9mLXR5cGUoLi4uKQoJCQkJCQkJaWYgKCBkaWZmID09PSBmYWxzZSApIHsKCQkJCQkJCQkvLyBVc2UgdGhlIHNhbWUgbG9vcCBhcyBhYm92ZSB0byBzZWVrIGBlbGVtYCBmcm9tIHRoZSBzdGFydAoJCQkJCQkJCXdoaWxlICggKG5vZGUgPSArK25vZGVJbmRleCAmJiBub2RlICYmIG5vZGVbIGRpciBdIHx8CgkJCQkJCQkJCShkaWZmID0gbm9kZUluZGV4ID0gMCkgfHwgc3RhcnQucG9wKCkpICkgewoKCQkJCQkJCQkJaWYgKCAoIG9mVHlwZSA/CgkJCQkJCQkJCQlub2RlLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgPT09IG5hbWUgOgoJCQkJCQkJCQkJbm9kZS5ub2RlVHlwZSA9PT0gMSApICYmCgkJCQkJCQkJCQkrK2RpZmYgKSB7CgoJCQkJCQkJCQkJLy8gQ2FjaGUgdGhlIGluZGV4IG9mIGVhY2ggZW5jb3VudGVyZWQgZWxlbWVudAoJCQkJCQkJCQkJaWYgKCB1c2VDYWNoZSApIHsKCQkJCQkJCQkJCQlvdXRlckNhY2hlID0gbm9kZVsgZXhwYW5kbyBdIHx8IChub2RlWyBleHBhbmRvIF0gPSB7fSk7CgoJCQkJCQkJCQkJCS8vIFN1cHBvcnQ6IElFIDw5IG9ubHkKCQkJCQkJCQkJCQkvLyBEZWZlbmQgYWdhaW5zdCBjbG9uZWQgYXR0cm9wZXJ0aWVzIChqUXVlcnkgZ2gtMTcwOSkKCQkJCQkJCQkJCQl1bmlxdWVDYWNoZSA9IG91dGVyQ2FjaGVbIG5vZGUudW5pcXVlSUQgXSB8fAoJCQkJCQkJCQkJCQkob3V0ZXJDYWNoZVsgbm9kZS51bmlxdWVJRCBdID0ge30pOwoKCQkJCQkJCQkJCQl1bmlxdWVDYWNoZVsgdHlwZSBdID0gWyBkaXJydW5zLCBkaWZmIF07CgkJCQkJCQkJCQl9CgoJCQkJCQkJCQkJaWYgKCBub2RlID09PSBlbGVtICkgewoJCQkJCQkJCQkJCWJyZWFrOwoJCQkJCQkJCQkJfQoJCQkJCQkJCQl9CgkJCQkJCQkJfQoJCQkJCQkJfQoJCQkJCQl9CgoJCQkJCQkvLyBJbmNvcnBvcmF0ZSB0aGUgb2Zmc2V0LCB0aGVuIGNoZWNrIGFnYWluc3QgY3ljbGUgc2l6ZQoJCQkJCQlkaWZmIC09IGxhc3Q7CgkJCQkJCXJldHVybiBkaWZmID09PSBmaXJzdCB8fCAoIGRpZmYgJSBmaXJzdCA9PT0gMCAmJiBkaWZmIC8gZmlyc3QgPj0gMCApOwoJCQkJCX0KCQkJCX07CgkJfSwKCgkJIlBTRVVETyI6IGZ1bmN0aW9uKCBwc2V1ZG8sIGFyZ3VtZW50ICkgewoJCQkvLyBwc2V1ZG8tY2xhc3MgbmFtZXMgYXJlIGNhc2UtaW5zZW5zaXRpdmUKCQkJLy8gaHR0cDovL3d3dy53My5vcmcvVFIvc2VsZWN0b3JzLyNwc2V1ZG8tY2xhc3NlcwoJCQkvLyBQcmlvcml0aXplIGJ5IGNhc2Ugc2Vuc2l0aXZpdHkgaW4gY2FzZSBjdXN0b20gcHNldWRvcyBhcmUgYWRkZWQgd2l0aCB1cHBlcmNhc2UgbGV0dGVycwoJCQkvLyBSZW1lbWJlciB0aGF0IHNldEZpbHRlcnMgaW5oZXJpdHMgZnJvbSBwc2V1ZG9zCgkJCXZhciBhcmdzLAoJCQkJZm4gPSBFeHByLnBzZXVkb3NbIHBzZXVkbyBdIHx8IEV4cHIuc2V0RmlsdGVyc1sgcHNldWRvLnRvTG93ZXJDYXNlKCkgXSB8fAoJCQkJCVNpenpsZS5lcnJvciggInVuc3VwcG9ydGVkIHBzZXVkbzogIiArIHBzZXVkbyApOwoKCQkJLy8gVGhlIHVzZXIgbWF5IHVzZSBjcmVhdGVQc2V1ZG8gdG8gaW5kaWNhdGUgdGhhdAoJCQkvLyBhcmd1bWVudHMgYXJlIG5lZWRlZCB0byBjcmVhdGUgdGhlIGZpbHRlciBmdW5jdGlvbgoJCQkvLyBqdXN0IGFzIFNpenpsZSBkb2VzCgkJCWlmICggZm5bIGV4cGFuZG8gXSApIHsKCQkJCXJldHVybiBmbiggYXJndW1lbnQgKTsKCQkJfQoKCQkJLy8gQnV0IG1haW50YWluIHN1cHBvcnQgZm9yIG9sZCBzaWduYXR1cmVzCgkJCWlmICggZm4ubGVuZ3RoID4gMSApIHsKCQkJCWFyZ3MgPSBbIHBzZXVkbywgcHNldWRvLCAiIiwgYXJndW1lbnQgXTsKCQkJCXJldHVybiBFeHByLnNldEZpbHRlcnMuaGFzT3duUHJvcGVydHkoIHBzZXVkby50b0xvd2VyQ2FzZSgpICkgPwoJCQkJCW1hcmtGdW5jdGlvbihmdW5jdGlvbiggc2VlZCwgbWF0Y2hlcyApIHsKCQkJCQkJdmFyIGlkeCwKCQkJCQkJCW1hdGNoZWQgPSBmbiggc2VlZCwgYXJndW1lbnQgKSwKCQkJCQkJCWkgPSBtYXRjaGVkLmxlbmd0aDsKCQkJCQkJd2hpbGUgKCBpLS0gKSB7CgkJCQkJCQlpZHggPSBpbmRleE9mKCBzZWVkLCBtYXRjaGVkW2ldICk7CgkJCQkJCQlzZWVkWyBpZHggXSA9ICEoIG1hdGNoZXNbIGlkeCBdID0gbWF0Y2hlZFtpXSApOwoJCQkJCQl9CgkJCQkJfSkgOgoJCQkJCWZ1bmN0aW9uKCBlbGVtICkgewoJCQkJCQlyZXR1cm4gZm4oIGVsZW0sIDAsIGFyZ3MgKTsKCQkJCQl9OwoJCQl9CgoJCQlyZXR1cm4gZm47CgkJfQoJfSwKCglwc2V1ZG9zOiB7CgkJLy8gUG90ZW50aWFsbHkgY29tcGxleCBwc2V1ZG9zCgkJIm5vdCI6IG1hcmtGdW5jdGlvbihmdW5jdGlvbiggc2VsZWN0b3IgKSB7CgkJCS8vIFRyaW0gdGhlIHNlbGVjdG9yIHBhc3NlZCB0byBjb21waWxlCgkJCS8vIHRvIGF2b2lkIHRyZWF0aW5nIGxlYWRpbmcgYW5kIHRyYWlsaW5nCgkJCS8vIHNwYWNlcyBhcyBjb21iaW5hdG9ycwoJCQl2YXIgaW5wdXQgPSBbXSwKCQkJCXJlc3VsdHMgPSBbXSwKCQkJCW1hdGNoZXIgPSBjb21waWxlKCBzZWxlY3Rvci5yZXBsYWNlKCBydHJpbSwgIiQxIiApICk7CgoJCQlyZXR1cm4gbWF0Y2hlclsgZXhwYW5kbyBdID8KCQkJCW1hcmtGdW5jdGlvbihmdW5jdGlvbiggc2VlZCwgbWF0Y2hlcywgY29udGV4dCwgeG1sICkgewoJCQkJCXZhciBlbGVtLAoJCQkJCQl1bm1hdGNoZWQgPSBtYXRjaGVyKCBzZWVkLCBudWxsLCB4bWwsIFtdICksCgkJCQkJCWkgPSBzZWVkLmxlbmd0aDsKCgkJCQkJLy8gTWF0Y2ggZWxlbWVudHMgdW5tYXRjaGVkIGJ5IGBtYXRjaGVyYAoJCQkJCXdoaWxlICggaS0tICkgewoJCQkJCQlpZiAoIChlbGVtID0gdW5tYXRjaGVkW2ldKSApIHsKCQkJCQkJCXNlZWRbaV0gPSAhKG1hdGNoZXNbaV0gPSBlbGVtKTsKCQkJCQkJfQoJCQkJCX0KCQkJCX0pIDoKCQkJCWZ1bmN0aW9uKCBlbGVtLCBjb250ZXh0LCB4bWwgKSB7CgkJCQkJaW5wdXRbMF0gPSBlbGVtOwoJCQkJCW1hdGNoZXIoIGlucHV0LCBudWxsLCB4bWwsIHJlc3VsdHMgKTsKCQkJCQkvLyBEb24ndCBrZWVwIHRoZSBlbGVtZW50IChpc3N1ZSAjMjk5KQoJCQkJCWlucHV0WzBdID0gbnVsbDsKCQkJCQlyZXR1cm4gIXJlc3VsdHMucG9wKCk7CgkJCQl9OwoJCX0pLAoKCQkiaGFzIjogbWFya0Z1bmN0aW9uKGZ1bmN0aW9uKCBzZWxlY3RvciApIHsKCQkJcmV0dXJuIGZ1bmN0aW9uKCBlbGVtICkgewoJCQkJcmV0dXJuIFNpenpsZSggc2VsZWN0b3IsIGVsZW0gKS5sZW5ndGggPiAwOwoJCQl9OwoJCX0pLAoKCQkiY29udGFpbnMiOiBtYXJrRnVuY3Rpb24oZnVuY3Rpb24oIHRleHQgKSB7CgkJCXRleHQgPSB0ZXh0LnJlcGxhY2UoIHJ1bmVzY2FwZSwgZnVuZXNjYXBlICk7CgkJCXJldHVybiBmdW5jdGlvbiggZWxlbSApIHsKCQkJCXJldHVybiAoIGVsZW0udGV4dENvbnRlbnQgfHwgZWxlbS5pbm5lclRleHQgfHwgZ2V0VGV4dCggZWxlbSApICkuaW5kZXhPZiggdGV4dCApID4gLTE7CgkJCX07CgkJfSksCgoJCS8vICJXaGV0aGVyIGFuIGVsZW1lbnQgaXMgcmVwcmVzZW50ZWQgYnkgYSA6bGFuZygpIHNlbGVjdG9yCgkJLy8gaXMgYmFzZWQgc29sZWx5IG9uIHRoZSBlbGVtZW50J3MgbGFuZ3VhZ2UgdmFsdWUKCQkvLyBiZWluZyBlcXVhbCB0byB0aGUgaWRlbnRpZmllciBDLAoJCS8vIG9yIGJlZ2lubmluZyB3aXRoIHRoZSBpZGVudGlmaWVyIEMgaW1tZWRpYXRlbHkgZm9sbG93ZWQgYnkgIi0iLgoJCS8vIFRoZSBtYXRjaGluZyBvZiBDIGFnYWluc3QgdGhlIGVsZW1lbnQncyBsYW5ndWFnZSB2YWx1ZSBpcyBwZXJmb3JtZWQgY2FzZS1pbnNlbnNpdGl2ZWx5LgoJCS8vIFRoZSBpZGVudGlmaWVyIEMgZG9lcyBub3QgaGF2ZSB0byBiZSBhIHZhbGlkIGxhbmd1YWdlIG5hbWUuIgoJCS8vIGh0dHA6Ly93d3cudzMub3JnL1RSL3NlbGVjdG9ycy8jbGFuZy1wc2V1ZG8KCQkibGFuZyI6IG1hcmtGdW5jdGlvbiggZnVuY3Rpb24oIGxhbmcgKSB7CgkJCS8vIGxhbmcgdmFsdWUgbXVzdCBiZSBhIHZhbGlkIGlkZW50aWZpZXIKCQkJaWYgKCAhcmlkZW50aWZpZXIudGVzdChsYW5nIHx8ICIiKSApIHsKCQkJCVNpenpsZS5lcnJvciggInVuc3VwcG9ydGVkIGxhbmc6ICIgKyBsYW5nICk7CgkJCX0KCQkJbGFuZyA9IGxhbmcucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKS50b0xvd2VyQ2FzZSgpOwoJCQlyZXR1cm4gZnVuY3Rpb24oIGVsZW0gKSB7CgkJCQl2YXIgZWxlbUxhbmc7CgkJCQlkbyB7CgkJCQkJaWYgKCAoZWxlbUxhbmcgPSBkb2N1bWVudElzSFRNTCA/CgkJCQkJCWVsZW0ubGFuZyA6CgkJCQkJCWVsZW0uZ2V0QXR0cmlidXRlKCJ4bWw6bGFuZyIpIHx8IGVsZW0uZ2V0QXR0cmlidXRlKCJsYW5nIikpICkgewoKCQkJCQkJZWxlbUxhbmcgPSBlbGVtTGFuZy50b0xvd2VyQ2FzZSgpOwoJCQkJCQlyZXR1cm4gZWxlbUxhbmcgPT09IGxhbmcgfHwgZWxlbUxhbmcuaW5kZXhPZiggbGFuZyArICItIiApID09PSAwOwoJCQkJCX0KCQkJCX0gd2hpbGUgKCAoZWxlbSA9IGVsZW0ucGFyZW50Tm9kZSkgJiYgZWxlbS5ub2RlVHlwZSA9PT0gMSApOwoJCQkJcmV0dXJuIGZhbHNlOwoJCQl9OwoJCX0pLAoKCQkvLyBNaXNjZWxsYW5lb3VzCgkJInRhcmdldCI6IGZ1bmN0aW9uKCBlbGVtICkgewoJCQl2YXIgaGFzaCA9IHdpbmRvdy5sb2NhdGlvbiAmJiB3aW5kb3cubG9jYXRpb24uaGFzaDsKCQkJcmV0dXJuIGhhc2ggJiYgaGFzaC5zbGljZSggMSApID09PSBlbGVtLmlkOwoJCX0sCgoJCSJyb290IjogZnVuY3Rpb24oIGVsZW0gKSB7CgkJCXJldHVybiBlbGVtID09PSBkb2NFbGVtOwoJCX0sCgoJCSJmb2N1cyI6IGZ1bmN0aW9uKCBlbGVtICkgewoJCQlyZXR1cm4gZWxlbSA9PT0gZG9jdW1lbnQuYWN0aXZlRWxlbWVudCAmJiAoIWRvY3VtZW50Lmhhc0ZvY3VzIHx8IGRvY3VtZW50Lmhhc0ZvY3VzKCkpICYmICEhKGVsZW0udHlwZSB8fCBlbGVtLmhyZWYgfHwgfmVsZW0udGFiSW5kZXgpOwoJCX0sCgoJCS8vIEJvb2xlYW4gcHJvcGVydGllcwoJCSJlbmFibGVkIjogY3JlYXRlRGlzYWJsZWRQc2V1ZG8oIGZhbHNlICksCgkJImRpc2FibGVkIjogY3JlYXRlRGlzYWJsZWRQc2V1ZG8oIHRydWUgKSwKCgkJImNoZWNrZWQiOiBmdW5jdGlvbiggZWxlbSApIHsKCQkJLy8gSW4gQ1NTMywgOmNoZWNrZWQgc2hvdWxkIHJldHVybiBib3RoIGNoZWNrZWQgYW5kIHNlbGVjdGVkIGVsZW1lbnRzCgkJCS8vIGh0dHA6Ly93d3cudzMub3JnL1RSLzIwMTEvUkVDLWNzczMtc2VsZWN0b3JzLTIwMTEwOTI5LyNjaGVja2VkCgkJCXZhciBub2RlTmFtZSA9IGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKTsKCQkJcmV0dXJuIChub2RlTmFtZSA9PT0gImlucHV0IiAmJiAhIWVsZW0uY2hlY2tlZCkgfHwgKG5vZGVOYW1lID09PSAib3B0aW9uIiAmJiAhIWVsZW0uc2VsZWN0ZWQpOwoJCX0sCgoJCSJzZWxlY3RlZCI6IGZ1bmN0aW9uKCBlbGVtICkgewoJCQkvLyBBY2Nlc3NpbmcgdGhpcyBwcm9wZXJ0eSBtYWtlcyBzZWxlY3RlZC1ieS1kZWZhdWx0CgkJCS8vIG9wdGlvbnMgaW4gU2FmYXJpIHdvcmsgcHJvcGVybHkKCQkJaWYgKCBlbGVtLnBhcmVudE5vZGUgKSB7CgkJCQllbGVtLnBhcmVudE5vZGUuc2VsZWN0ZWRJbmRleDsKCQkJfQoKCQkJcmV0dXJuIGVsZW0uc2VsZWN0ZWQgPT09IHRydWU7CgkJfSwKCgkJLy8gQ29udGVudHMKCQkiZW1wdHkiOiBmdW5jdGlvbiggZWxlbSApIHsKCQkJLy8gaHR0cDovL3d3dy53My5vcmcvVFIvc2VsZWN0b3JzLyNlbXB0eS1wc2V1ZG8KCQkJLy8gOmVtcHR5IGlzIG5lZ2F0ZWQgYnkgZWxlbWVudCAoMSkgb3IgY29udGVudCBub2RlcyAodGV4dDogMzsgY2RhdGE6IDQ7IGVudGl0eSByZWY6IDUpLAoJCQkvLyAgIGJ1dCBub3QgYnkgb3RoZXJzIChjb21tZW50OiA4OyBwcm9jZXNzaW5nIGluc3RydWN0aW9uOiA3OyBldGMuKQoJCQkvLyBub2RlVHlwZSA8IDYgd29ya3MgYmVjYXVzZSBhdHRyaWJ1dGVzICgyKSBkbyBub3QgYXBwZWFyIGFzIGNoaWxkcmVuCgkJCWZvciAoIGVsZW0gPSBlbGVtLmZpcnN0Q2hpbGQ7IGVsZW07IGVsZW0gPSBlbGVtLm5leHRTaWJsaW5nICkgewoJCQkJaWYgKCBlbGVtLm5vZGVUeXBlIDwgNiApIHsKCQkJCQlyZXR1cm4gZmFsc2U7CgkJCQl9CgkJCX0KCQkJcmV0dXJuIHRydWU7CgkJfSwKCgkJInBhcmVudCI6IGZ1bmN0aW9uKCBlbGVtICkgewoJCQlyZXR1cm4gIUV4cHIucHNldWRvc1siZW1wdHkiXSggZWxlbSApOwoJCX0sCgoJCS8vIEVsZW1lbnQvaW5wdXQgdHlwZXMKCQkiaGVhZGVyIjogZnVuY3Rpb24oIGVsZW0gKSB7CgkJCXJldHVybiByaGVhZGVyLnRlc3QoIGVsZW0ubm9kZU5hbWUgKTsKCQl9LAoKCQkiaW5wdXQiOiBmdW5jdGlvbiggZWxlbSApIHsKCQkJcmV0dXJuIHJpbnB1dHMudGVzdCggZWxlbS5ub2RlTmFtZSApOwoJCX0sCgoJCSJidXR0b24iOiBmdW5jdGlvbiggZWxlbSApIHsKCQkJdmFyIG5hbWUgPSBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7CgkJCXJldHVybiBuYW1lID09PSAiaW5wdXQiICYmIGVsZW0udHlwZSA9PT0gImJ1dHRvbiIgfHwgbmFtZSA9PT0gImJ1dHRvbiI7CgkJfSwKCgkJInRleHQiOiBmdW5jdGlvbiggZWxlbSApIHsKCQkJdmFyIGF0dHI7CgkJCXJldHVybiBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgPT09ICJpbnB1dCIgJiYKCQkJCWVsZW0udHlwZSA9PT0gInRleHQiICYmCgoJCQkJLy8gU3VwcG9ydDogSUU8OAoJCQkJLy8gTmV3IEhUTUw1IGF0dHJpYnV0ZSB2YWx1ZXMgKGUuZy4sICJzZWFyY2giKSBhcHBlYXIgd2l0aCBlbGVtLnR5cGUgPT09ICJ0ZXh0IgoJCQkJKCAoYXR0ciA9IGVsZW0uZ2V0QXR0cmlidXRlKCJ0eXBlIikpID09IG51bGwgfHwgYXR0ci50b0xvd2VyQ2FzZSgpID09PSAidGV4dCIgKTsKCQl9LAoKCQkvLyBQb3NpdGlvbi1pbi1jb2xsZWN0aW9uCgkJImZpcnN0IjogY3JlYXRlUG9zaXRpb25hbFBzZXVkbyhmdW5jdGlvbigpIHsKCQkJcmV0dXJuIFsgMCBdOwoJCX0pLAoKCQkibGFzdCI6IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oZnVuY3Rpb24oIG1hdGNoSW5kZXhlcywgbGVuZ3RoICkgewoJCQlyZXR1cm4gWyBsZW5ndGggLSAxIF07CgkJfSksCgoJCSJlcSI6IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oZnVuY3Rpb24oIG1hdGNoSW5kZXhlcywgbGVuZ3RoLCBhcmd1bWVudCApIHsKCQkJcmV0dXJuIFsgYXJndW1lbnQgPCAwID8gYXJndW1lbnQgKyBsZW5ndGggOiBhcmd1bWVudCBdOwoJCX0pLAoKCQkiZXZlbiI6IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oZnVuY3Rpb24oIG1hdGNoSW5kZXhlcywgbGVuZ3RoICkgewoJCQl2YXIgaSA9IDA7CgkJCWZvciAoIDsgaSA8IGxlbmd0aDsgaSArPSAyICkgewoJCQkJbWF0Y2hJbmRleGVzLnB1c2goIGkgKTsKCQkJfQoJCQlyZXR1cm4gbWF0Y2hJbmRleGVzOwoJCX0pLAoKCQkib2RkIjogY3JlYXRlUG9zaXRpb25hbFBzZXVkbyhmdW5jdGlvbiggbWF0Y2hJbmRleGVzLCBsZW5ndGggKSB7CgkJCXZhciBpID0gMTsKCQkJZm9yICggOyBpIDwgbGVuZ3RoOyBpICs9IDIgKSB7CgkJCQltYXRjaEluZGV4ZXMucHVzaCggaSApOwoJCQl9CgkJCXJldHVybiBtYXRjaEluZGV4ZXM7CgkJfSksCgoJCSJsdCI6IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oZnVuY3Rpb24oIG1hdGNoSW5kZXhlcywgbGVuZ3RoLCBhcmd1bWVudCApIHsKCQkJdmFyIGkgPSBhcmd1bWVudCA8IDAgPyBhcmd1bWVudCArIGxlbmd0aCA6IGFyZ3VtZW50OwoJCQlmb3IgKCA7IC0taSA+PSAwOyApIHsKCQkJCW1hdGNoSW5kZXhlcy5wdXNoKCBpICk7CgkJCX0KCQkJcmV0dXJuIG1hdGNoSW5kZXhlczsKCQl9KSwKCgkJImd0IjogY3JlYXRlUG9zaXRpb25hbFBzZXVkbyhmdW5jdGlvbiggbWF0Y2hJbmRleGVzLCBsZW5ndGgsIGFyZ3VtZW50ICkgewoJCQl2YXIgaSA9IGFyZ3VtZW50IDwgMCA/IGFyZ3VtZW50ICsgbGVuZ3RoIDogYXJndW1lbnQ7CgkJCWZvciAoIDsgKytpIDwgbGVuZ3RoOyApIHsKCQkJCW1hdGNoSW5kZXhlcy5wdXNoKCBpICk7CgkJCX0KCQkJcmV0dXJuIG1hdGNoSW5kZXhlczsKCQl9KQoJfQp9OwoKRXhwci5wc2V1ZG9zWyJudGgiXSA9IEV4cHIucHNldWRvc1siZXEiXTsKCi8vIEFkZCBidXR0b24vaW5wdXQgdHlwZSBwc2V1ZG9zCmZvciAoIGkgaW4geyByYWRpbzogdHJ1ZSwgY2hlY2tib3g6IHRydWUsIGZpbGU6IHRydWUsIHBhc3N3b3JkOiB0cnVlLCBpbWFnZTogdHJ1ZSB9ICkgewoJRXhwci5wc2V1ZG9zWyBpIF0gPSBjcmVhdGVJbnB1dFBzZXVkbyggaSApOwp9CmZvciAoIGkgaW4geyBzdWJtaXQ6IHRydWUsIHJlc2V0OiB0cnVlIH0gKSB7CglFeHByLnBzZXVkb3NbIGkgXSA9IGNyZWF0ZUJ1dHRvblBzZXVkbyggaSApOwp9CgovLyBFYXN5IEFQSSBmb3IgY3JlYXRpbmcgbmV3IHNldEZpbHRlcnMKZnVuY3Rpb24gc2V0RmlsdGVycygpIHt9CnNldEZpbHRlcnMucHJvdG90eXBlID0gRXhwci5maWx0ZXJzID0gRXhwci5wc2V1ZG9zOwpFeHByLnNldEZpbHRlcnMgPSBuZXcgc2V0RmlsdGVycygpOwoKdG9rZW5pemUgPSBTaXp6bGUudG9rZW5pemUgPSBmdW5jdGlvbiggc2VsZWN0b3IsIHBhcnNlT25seSApIHsKCXZhciBtYXRjaGVkLCBtYXRjaCwgdG9rZW5zLCB0eXBlLAoJCXNvRmFyLCBncm91cHMsIHByZUZpbHRlcnMsCgkJY2FjaGVkID0gdG9rZW5DYWNoZVsgc2VsZWN0b3IgKyAiICIgXTsKCglpZiAoIGNhY2hlZCApIHsKCQlyZXR1cm4gcGFyc2VPbmx5ID8gMCA6IGNhY2hlZC5zbGljZSggMCApOwoJfQoKCXNvRmFyID0gc2VsZWN0b3I7Cglncm91cHMgPSBbXTsKCXByZUZpbHRlcnMgPSBFeHByLnByZUZpbHRlcjsKCgl3aGlsZSAoIHNvRmFyICkgewoKCQkvLyBDb21tYSBhbmQgZmlyc3QgcnVuCgkJaWYgKCAhbWF0Y2hlZCB8fCAobWF0Y2ggPSByY29tbWEuZXhlYyggc29GYXIgKSkgKSB7CgkJCWlmICggbWF0Y2ggKSB7CgkJCQkvLyBEb24ndCBjb25zdW1lIHRyYWlsaW5nIGNvbW1hcyBhcyB2YWxpZAoJCQkJc29GYXIgPSBzb0Zhci5zbGljZSggbWF0Y2hbMF0ubGVuZ3RoICkgfHwgc29GYXI7CgkJCX0KCQkJZ3JvdXBzLnB1c2goICh0b2tlbnMgPSBbXSkgKTsKCQl9CgoJCW1hdGNoZWQgPSBmYWxzZTsKCgkJLy8gQ29tYmluYXRvcnMKCQlpZiAoIChtYXRjaCA9IHJjb21iaW5hdG9ycy5leGVjKCBzb0ZhciApKSApIHsKCQkJbWF0Y2hlZCA9IG1hdGNoLnNoaWZ0KCk7CgkJCXRva2Vucy5wdXNoKHsKCQkJCXZhbHVlOiBtYXRjaGVkLAoJCQkJLy8gQ2FzdCBkZXNjZW5kYW50IGNvbWJpbmF0b3JzIHRvIHNwYWNlCgkJCQl0eXBlOiBtYXRjaFswXS5yZXBsYWNlKCBydHJpbSwgIiAiICkKCQkJfSk7CgkJCXNvRmFyID0gc29GYXIuc2xpY2UoIG1hdGNoZWQubGVuZ3RoICk7CgkJfQoKCQkvLyBGaWx0ZXJzCgkJZm9yICggdHlwZSBpbiBFeHByLmZpbHRlciApIHsKCQkJaWYgKCAobWF0Y2ggPSBtYXRjaEV4cHJbIHR5cGUgXS5leGVjKCBzb0ZhciApKSAmJiAoIXByZUZpbHRlcnNbIHR5cGUgXSB8fAoJCQkJKG1hdGNoID0gcHJlRmlsdGVyc1sgdHlwZSBdKCBtYXRjaCApKSkgKSB7CgkJCQltYXRjaGVkID0gbWF0Y2guc2hpZnQoKTsKCQkJCXRva2Vucy5wdXNoKHsKCQkJCQl2YWx1ZTogbWF0Y2hlZCwKCQkJCQl0eXBlOiB0eXBlLAoJCQkJCW1hdGNoZXM6IG1hdGNoCgkJCQl9KTsKCQkJCXNvRmFyID0gc29GYXIuc2xpY2UoIG1hdGNoZWQubGVuZ3RoICk7CgkJCX0KCQl9CgoJCWlmICggIW1hdGNoZWQgKSB7CgkJCWJyZWFrOwoJCX0KCX0KCgkvLyBSZXR1cm4gdGhlIGxlbmd0aCBvZiB0aGUgaW52YWxpZCBleGNlc3MKCS8vIGlmIHdlJ3JlIGp1c3QgcGFyc2luZwoJLy8gT3RoZXJ3aXNlLCB0aHJvdyBhbiBlcnJvciBvciByZXR1cm4gdG9rZW5zCglyZXR1cm4gcGFyc2VPbmx5ID8KCQlzb0Zhci5sZW5ndGggOgoJCXNvRmFyID8KCQkJU2l6emxlLmVycm9yKCBzZWxlY3RvciApIDoKCQkJLy8gQ2FjaGUgdGhlIHRva2VucwoJCQl0b2tlbkNhY2hlKCBzZWxlY3RvciwgZ3JvdXBzICkuc2xpY2UoIDAgKTsKfTsKCmZ1bmN0aW9uIHRvU2VsZWN0b3IoIHRva2VucyApIHsKCXZhciBpID0gMCwKCQlsZW4gPSB0b2tlbnMubGVuZ3RoLAoJCXNlbGVjdG9yID0gIiI7Cglmb3IgKCA7IGkgPCBsZW47IGkrKyApIHsKCQlzZWxlY3RvciArPSB0b2tlbnNbaV0udmFsdWU7Cgl9CglyZXR1cm4gc2VsZWN0b3I7Cn0KCmZ1bmN0aW9uIGFkZENvbWJpbmF0b3IoIG1hdGNoZXIsIGNvbWJpbmF0b3IsIGJhc2UgKSB7Cgl2YXIgZGlyID0gY29tYmluYXRvci5kaXIsCgkJc2tpcCA9IGNvbWJpbmF0b3IubmV4dCwKCQlrZXkgPSBza2lwIHx8IGRpciwKCQljaGVja05vbkVsZW1lbnRzID0gYmFzZSAmJiBrZXkgPT09ICJwYXJlbnROb2RlIiwKCQlkb25lTmFtZSA9IGRvbmUrKzsKCglyZXR1cm4gY29tYmluYXRvci5maXJzdCA/CgkJLy8gQ2hlY2sgYWdhaW5zdCBjbG9zZXN0IGFuY2VzdG9yL3ByZWNlZGluZyBlbGVtZW50CgkJZnVuY3Rpb24oIGVsZW0sIGNvbnRleHQsIHhtbCApIHsKCQkJd2hpbGUgKCAoZWxlbSA9IGVsZW1bIGRpciBdKSApIHsKCQkJCWlmICggZWxlbS5ub2RlVHlwZSA9PT0gMSB8fCBjaGVja05vbkVsZW1lbnRzICkgewoJCQkJCXJldHVybiBtYXRjaGVyKCBlbGVtLCBjb250ZXh0LCB4bWwgKTsKCQkJCX0KCQkJfQoJCQlyZXR1cm4gZmFsc2U7CgkJfSA6CgoJCS8vIENoZWNrIGFnYWluc3QgYWxsIGFuY2VzdG9yL3ByZWNlZGluZyBlbGVtZW50cwoJCWZ1bmN0aW9uKCBlbGVtLCBjb250ZXh0LCB4bWwgKSB7CgkJCXZhciBvbGRDYWNoZSwgdW5pcXVlQ2FjaGUsIG91dGVyQ2FjaGUsCgkJCQluZXdDYWNoZSA9IFsgZGlycnVucywgZG9uZU5hbWUgXTsKCgkJCS8vIFdlIGNhbid0IHNldCBhcmJpdHJhcnkgZGF0YSBvbiBYTUwgbm9kZXMsIHNvIHRoZXkgZG9uJ3QgYmVuZWZpdCBmcm9tIGNvbWJpbmF0b3IgY2FjaGluZwoJCQlpZiAoIHhtbCApIHsKCQkJCXdoaWxlICggKGVsZW0gPSBlbGVtWyBkaXIgXSkgKSB7CgkJCQkJaWYgKCBlbGVtLm5vZGVUeXBlID09PSAxIHx8IGNoZWNrTm9uRWxlbWVudHMgKSB7CgkJCQkJCWlmICggbWF0Y2hlciggZWxlbSwgY29udGV4dCwgeG1sICkgKSB7CgkJCQkJCQlyZXR1cm4gdHJ1ZTsKCQkJCQkJfQoJCQkJCX0KCQkJCX0KCQkJfSBlbHNlIHsKCQkJCXdoaWxlICggKGVsZW0gPSBlbGVtWyBkaXIgXSkgKSB7CgkJCQkJaWYgKCBlbGVtLm5vZGVUeXBlID09PSAxIHx8IGNoZWNrTm9uRWxlbWVudHMgKSB7CgkJCQkJCW91dGVyQ2FjaGUgPSBlbGVtWyBleHBhbmRvIF0gfHwgKGVsZW1bIGV4cGFuZG8gXSA9IHt9KTsKCgkJCQkJCS8vIFN1cHBvcnQ6IElFIDw5IG9ubHkKCQkJCQkJLy8gRGVmZW5kIGFnYWluc3QgY2xvbmVkIGF0dHJvcGVydGllcyAoalF1ZXJ5IGdoLTE3MDkpCgkJCQkJCXVuaXF1ZUNhY2hlID0gb3V0ZXJDYWNoZVsgZWxlbS51bmlxdWVJRCBdIHx8IChvdXRlckNhY2hlWyBlbGVtLnVuaXF1ZUlEIF0gPSB7fSk7CgoJCQkJCQlpZiAoIHNraXAgJiYgc2tpcCA9PT0gZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpICkgewoJCQkJCQkJZWxlbSA9IGVsZW1bIGRpciBdIHx8IGVsZW07CgkJCQkJCX0gZWxzZSBpZiAoIChvbGRDYWNoZSA9IHVuaXF1ZUNhY2hlWyBrZXkgXSkgJiYKCQkJCQkJCW9sZENhY2hlWyAwIF0gPT09IGRpcnJ1bnMgJiYgb2xkQ2FjaGVbIDEgXSA9PT0gZG9uZU5hbWUgKSB7CgoJCQkJCQkJLy8gQXNzaWduIHRvIG5ld0NhY2hlIHNvIHJlc3VsdHMgYmFjay1wcm9wYWdhdGUgdG8gcHJldmlvdXMgZWxlbWVudHMKCQkJCQkJCXJldHVybiAobmV3Q2FjaGVbIDIgXSA9IG9sZENhY2hlWyAyIF0pOwoJCQkJCQl9IGVsc2UgewoJCQkJCQkJLy8gUmV1c2UgbmV3Y2FjaGUgc28gcmVzdWx0cyBiYWNrLXByb3BhZ2F0ZSB0byBwcmV2aW91cyBlbGVtZW50cwoJCQkJCQkJdW5pcXVlQ2FjaGVbIGtleSBdID0gbmV3Q2FjaGU7CgoJCQkJCQkJLy8gQSBtYXRjaCBtZWFucyB3ZSdyZSBkb25lOyBhIGZhaWwgbWVhbnMgd2UgaGF2ZSB0byBrZWVwIGNoZWNraW5nCgkJCQkJCQlpZiAoIChuZXdDYWNoZVsgMiBdID0gbWF0Y2hlciggZWxlbSwgY29udGV4dCwgeG1sICkpICkgewoJCQkJCQkJCXJldHVybiB0cnVlOwoJCQkJCQkJfQoJCQkJCQl9CgkJCQkJfQoJCQkJfQoJCQl9CgkJCXJldHVybiBmYWxzZTsKCQl9Owp9CgpmdW5jdGlvbiBlbGVtZW50TWF0Y2hlciggbWF0Y2hlcnMgKSB7CglyZXR1cm4gbWF0Y2hlcnMubGVuZ3RoID4gMSA/CgkJZnVuY3Rpb24oIGVsZW0sIGNvbnRleHQsIHhtbCApIHsKCQkJdmFyIGkgPSBtYXRjaGVycy5sZW5ndGg7CgkJCXdoaWxlICggaS0tICkgewoJCQkJaWYgKCAhbWF0Y2hlcnNbaV0oIGVsZW0sIGNvbnRleHQsIHhtbCApICkgewoJCQkJCXJldHVybiBmYWxzZTsKCQkJCX0KCQkJfQoJCQlyZXR1cm4gdHJ1ZTsKCQl9IDoKCQltYXRjaGVyc1swXTsKfQoKZnVuY3Rpb24gbXVsdGlwbGVDb250ZXh0cyggc2VsZWN0b3IsIGNvbnRleHRzLCByZXN1bHRzICkgewoJdmFyIGkgPSAwLAoJCWxlbiA9IGNvbnRleHRzLmxlbmd0aDsKCWZvciAoIDsgaSA8IGxlbjsgaSsrICkgewoJCVNpenpsZSggc2VsZWN0b3IsIGNvbnRleHRzW2ldLCByZXN1bHRzICk7Cgl9CglyZXR1cm4gcmVzdWx0czsKfQoKZnVuY3Rpb24gY29uZGVuc2UoIHVubWF0Y2hlZCwgbWFwLCBmaWx0ZXIsIGNvbnRleHQsIHhtbCApIHsKCXZhciBlbGVtLAoJCW5ld1VubWF0Y2hlZCA9IFtdLAoJCWkgPSAwLAoJCWxlbiA9IHVubWF0Y2hlZC5sZW5ndGgsCgkJbWFwcGVkID0gbWFwICE9IG51bGw7CgoJZm9yICggOyBpIDwgbGVuOyBpKysgKSB7CgkJaWYgKCAoZWxlbSA9IHVubWF0Y2hlZFtpXSkgKSB7CgkJCWlmICggIWZpbHRlciB8fCBmaWx0ZXIoIGVsZW0sIGNvbnRleHQsIHhtbCApICkgewoJCQkJbmV3VW5tYXRjaGVkLnB1c2goIGVsZW0gKTsKCQkJCWlmICggbWFwcGVkICkgewoJCQkJCW1hcC5wdXNoKCBpICk7CgkJCQl9CgkJCX0KCQl9Cgl9CgoJcmV0dXJuIG5ld1VubWF0Y2hlZDsKfQoKZnVuY3Rpb24gc2V0TWF0Y2hlciggcHJlRmlsdGVyLCBzZWxlY3RvciwgbWF0Y2hlciwgcG9zdEZpbHRlciwgcG9zdEZpbmRlciwgcG9zdFNlbGVjdG9yICkgewoJaWYgKCBwb3N0RmlsdGVyICYmICFwb3N0RmlsdGVyWyBleHBhbmRvIF0gKSB7CgkJcG9zdEZpbHRlciA9IHNldE1hdGNoZXIoIHBvc3RGaWx0ZXIgKTsKCX0KCWlmICggcG9zdEZpbmRlciAmJiAhcG9zdEZpbmRlclsgZXhwYW5kbyBdICkgewoJCXBvc3RGaW5kZXIgPSBzZXRNYXRjaGVyKCBwb3N0RmluZGVyLCBwb3N0U2VsZWN0b3IgKTsKCX0KCXJldHVybiBtYXJrRnVuY3Rpb24oZnVuY3Rpb24oIHNlZWQsIHJlc3VsdHMsIGNvbnRleHQsIHhtbCApIHsKCQl2YXIgdGVtcCwgaSwgZWxlbSwKCQkJcHJlTWFwID0gW10sCgkJCXBvc3RNYXAgPSBbXSwKCQkJcHJlZXhpc3RpbmcgPSByZXN1bHRzLmxlbmd0aCwKCgkJCS8vIEdldCBpbml0aWFsIGVsZW1lbnRzIGZyb20gc2VlZCBvciBjb250ZXh0CgkJCWVsZW1zID0gc2VlZCB8fCBtdWx0aXBsZUNvbnRleHRzKCBzZWxlY3RvciB8fCAiKiIsIGNvbnRleHQubm9kZVR5cGUgPyBbIGNvbnRleHQgXSA6IGNvbnRleHQsIFtdICksCgoJCQkvLyBQcmVmaWx0ZXIgdG8gZ2V0IG1hdGNoZXIgaW5wdXQsIHByZXNlcnZpbmcgYSBtYXAgZm9yIHNlZWQtcmVzdWx0cyBzeW5jaHJvbml6YXRpb24KCQkJbWF0Y2hlckluID0gcHJlRmlsdGVyICYmICggc2VlZCB8fCAhc2VsZWN0b3IgKSA/CgkJCQljb25kZW5zZSggZWxlbXMsIHByZU1hcCwgcHJlRmlsdGVyLCBjb250ZXh0LCB4bWwgKSA6CgkJCQllbGVtcywKCgkJCW1hdGNoZXJPdXQgPSBtYXRjaGVyID8KCQkJCS8vIElmIHdlIGhhdmUgYSBwb3N0RmluZGVyLCBvciBmaWx0ZXJlZCBzZWVkLCBvciBub24tc2VlZCBwb3N0RmlsdGVyIG9yIHByZWV4aXN0aW5nIHJlc3VsdHMsCgkJCQlwb3N0RmluZGVyIHx8ICggc2VlZCA/IHByZUZpbHRlciA6IHByZWV4aXN0aW5nIHx8IHBvc3RGaWx0ZXIgKSA/CgoJCQkJCS8vIC4uLmludGVybWVkaWF0ZSBwcm9jZXNzaW5nIGlzIG5lY2Vzc2FyeQoJCQkJCVtdIDoKCgkJCQkJLy8gLi4ub3RoZXJ3aXNlIHVzZSByZXN1bHRzIGRpcmVjdGx5CgkJCQkJcmVzdWx0cyA6CgkJCQltYXRjaGVySW47CgoJCS8vIEZpbmQgcHJpbWFyeSBtYXRjaGVzCgkJaWYgKCBtYXRjaGVyICkgewoJCQltYXRjaGVyKCBtYXRjaGVySW4sIG1hdGNoZXJPdXQsIGNvbnRleHQsIHhtbCApOwoJCX0KCgkJLy8gQXBwbHkgcG9zdEZpbHRlcgoJCWlmICggcG9zdEZpbHRlciApIHsKCQkJdGVtcCA9IGNvbmRlbnNlKCBtYXRjaGVyT3V0LCBwb3N0TWFwICk7CgkJCXBvc3RGaWx0ZXIoIHRlbXAsIFtdLCBjb250ZXh0LCB4bWwgKTsKCgkJCS8vIFVuLW1hdGNoIGZhaWxpbmcgZWxlbWVudHMgYnkgbW92aW5nIHRoZW0gYmFjayB0byBtYXRjaGVySW4KCQkJaSA9IHRlbXAubGVuZ3RoOwoJCQl3aGlsZSAoIGktLSApIHsKCQkJCWlmICggKGVsZW0gPSB0ZW1wW2ldKSApIHsKCQkJCQltYXRjaGVyT3V0WyBwb3N0TWFwW2ldIF0gPSAhKG1hdGNoZXJJblsgcG9zdE1hcFtpXSBdID0gZWxlbSk7CgkJCQl9CgkJCX0KCQl9CgoJCWlmICggc2VlZCApIHsKCQkJaWYgKCBwb3N0RmluZGVyIHx8IHByZUZpbHRlciApIHsKCQkJCWlmICggcG9zdEZpbmRlciApIHsKCQkJCQkvLyBHZXQgdGhlIGZpbmFsIG1hdGNoZXJPdXQgYnkgY29uZGVuc2luZyB0aGlzIGludGVybWVkaWF0ZSBpbnRvIHBvc3RGaW5kZXIgY29udGV4dHMKCQkJCQl0ZW1wID0gW107CgkJCQkJaSA9IG1hdGNoZXJPdXQubGVuZ3RoOwoJCQkJCXdoaWxlICggaS0tICkgewoJCQkJCQlpZiAoIChlbGVtID0gbWF0Y2hlck91dFtpXSkgKSB7CgkJCQkJCQkvLyBSZXN0b3JlIG1hdGNoZXJJbiBzaW5jZSBlbGVtIGlzIG5vdCB5ZXQgYSBmaW5hbCBtYXRjaAoJCQkJCQkJdGVtcC5wdXNoKCAobWF0Y2hlckluW2ldID0gZWxlbSkgKTsKCQkJCQkJfQoJCQkJCX0KCQkJCQlwb3N0RmluZGVyKCBudWxsLCAobWF0Y2hlck91dCA9IFtdKSwgdGVtcCwgeG1sICk7CgkJCQl9CgoJCQkJLy8gTW92ZSBtYXRjaGVkIGVsZW1lbnRzIGZyb20gc2VlZCB0byByZXN1bHRzIHRvIGtlZXAgdGhlbSBzeW5jaHJvbml6ZWQKCQkJCWkgPSBtYXRjaGVyT3V0Lmxlbmd0aDsKCQkJCXdoaWxlICggaS0tICkgewoJCQkJCWlmICggKGVsZW0gPSBtYXRjaGVyT3V0W2ldKSAmJgoJCQkJCQkodGVtcCA9IHBvc3RGaW5kZXIgPyBpbmRleE9mKCBzZWVkLCBlbGVtICkgOiBwcmVNYXBbaV0pID4gLTEgKSB7CgoJCQkJCQlzZWVkW3RlbXBdID0gIShyZXN1bHRzW3RlbXBdID0gZWxlbSk7CgkJCQkJfQoJCQkJfQoJCQl9CgoJCS8vIEFkZCBlbGVtZW50cyB0byByZXN1bHRzLCB0aHJvdWdoIHBvc3RGaW5kZXIgaWYgZGVmaW5lZAoJCX0gZWxzZSB7CgkJCW1hdGNoZXJPdXQgPSBjb25kZW5zZSgKCQkJCW1hdGNoZXJPdXQgPT09IHJlc3VsdHMgPwoJCQkJCW1hdGNoZXJPdXQuc3BsaWNlKCBwcmVleGlzdGluZywgbWF0Y2hlck91dC5sZW5ndGggKSA6CgkJCQkJbWF0Y2hlck91dAoJCQkpOwoJCQlpZiAoIHBvc3RGaW5kZXIgKSB7CgkJCQlwb3N0RmluZGVyKCBudWxsLCByZXN1bHRzLCBtYXRjaGVyT3V0LCB4bWwgKTsKCQkJfSBlbHNlIHsKCQkJCXB1c2guYXBwbHkoIHJlc3VsdHMsIG1hdGNoZXJPdXQgKTsKCQkJfQoJCX0KCX0pOwp9CgpmdW5jdGlvbiBtYXRjaGVyRnJvbVRva2VucyggdG9rZW5zICkgewoJdmFyIGNoZWNrQ29udGV4dCwgbWF0Y2hlciwgaiwKCQlsZW4gPSB0b2tlbnMubGVuZ3RoLAoJCWxlYWRpbmdSZWxhdGl2ZSA9IEV4cHIucmVsYXRpdmVbIHRva2Vuc1swXS50eXBlIF0sCgkJaW1wbGljaXRSZWxhdGl2ZSA9IGxlYWRpbmdSZWxhdGl2ZSB8fCBFeHByLnJlbGF0aXZlWyIgIl0sCgkJaSA9IGxlYWRpbmdSZWxhdGl2ZSA/IDEgOiAwLAoKCQkvLyBUaGUgZm91bmRhdGlvbmFsIG1hdGNoZXIgZW5zdXJlcyB0aGF0IGVsZW1lbnRzIGFyZSByZWFjaGFibGUgZnJvbSB0b3AtbGV2ZWwgY29udGV4dChzKQoJCW1hdGNoQ29udGV4dCA9IGFkZENvbWJpbmF0b3IoIGZ1bmN0aW9uKCBlbGVtICkgewoJCQlyZXR1cm4gZWxlbSA9PT0gY2hlY2tDb250ZXh0OwoJCX0sIGltcGxpY2l0UmVsYXRpdmUsIHRydWUgKSwKCQltYXRjaEFueUNvbnRleHQgPSBhZGRDb21iaW5hdG9yKCBmdW5jdGlvbiggZWxlbSApIHsKCQkJcmV0dXJuIGluZGV4T2YoIGNoZWNrQ29udGV4dCwgZWxlbSApID4gLTE7CgkJfSwgaW1wbGljaXRSZWxhdGl2ZSwgdHJ1ZSApLAoJCW1hdGNoZXJzID0gWyBmdW5jdGlvbiggZWxlbSwgY29udGV4dCwgeG1sICkgewoJCQl2YXIgcmV0ID0gKCAhbGVhZGluZ1JlbGF0aXZlICYmICggeG1sIHx8IGNvbnRleHQgIT09IG91dGVybW9zdENvbnRleHQgKSApIHx8ICgKCQkJCShjaGVja0NvbnRleHQgPSBjb250ZXh0KS5ub2RlVHlwZSA/CgkJCQkJbWF0Y2hDb250ZXh0KCBlbGVtLCBjb250ZXh0LCB4bWwgKSA6CgkJCQkJbWF0Y2hBbnlDb250ZXh0KCBlbGVtLCBjb250ZXh0LCB4bWwgKSApOwoJCQkvLyBBdm9pZCBoYW5naW5nIG9udG8gZWxlbWVudCAoaXNzdWUgIzI5OSkKCQkJY2hlY2tDb250ZXh0ID0gbnVsbDsKCQkJcmV0dXJuIHJldDsKCQl9IF07CgoJZm9yICggOyBpIDwgbGVuOyBpKysgKSB7CgkJaWYgKCAobWF0Y2hlciA9IEV4cHIucmVsYXRpdmVbIHRva2Vuc1tpXS50eXBlIF0pICkgewoJCQltYXRjaGVycyA9IFsgYWRkQ29tYmluYXRvcihlbGVtZW50TWF0Y2hlciggbWF0Y2hlcnMgKSwgbWF0Y2hlcikgXTsKCQl9IGVsc2UgewoJCQltYXRjaGVyID0gRXhwci5maWx0ZXJbIHRva2Vuc1tpXS50eXBlIF0uYXBwbHkoIG51bGwsIHRva2Vuc1tpXS5tYXRjaGVzICk7CgoJCQkvLyBSZXR1cm4gc3BlY2lhbCB1cG9uIHNlZWluZyBhIHBvc2l0aW9uYWwgbWF0Y2hlcgoJCQlpZiAoIG1hdGNoZXJbIGV4cGFuZG8gXSApIHsKCQkJCS8vIEZpbmQgdGhlIG5leHQgcmVsYXRpdmUgb3BlcmF0b3IgKGlmIGFueSkgZm9yIHByb3BlciBoYW5kbGluZwoJCQkJaiA9ICsraTsKCQkJCWZvciAoIDsgaiA8IGxlbjsgaisrICkgewoJCQkJCWlmICggRXhwci5yZWxhdGl2ZVsgdG9rZW5zW2pdLnR5cGUgXSApIHsKCQkJCQkJYnJlYWs7CgkJCQkJfQoJCQkJfQoJCQkJcmV0dXJuIHNldE1hdGNoZXIoCgkJCQkJaSA+IDEgJiYgZWxlbWVudE1hdGNoZXIoIG1hdGNoZXJzICksCgkJCQkJaSA+IDEgJiYgdG9TZWxlY3RvcigKCQkJCQkJLy8gSWYgdGhlIHByZWNlZGluZyB0b2tlbiB3YXMgYSBkZXNjZW5kYW50IGNvbWJpbmF0b3IsIGluc2VydCBhbiBpbXBsaWNpdCBhbnktZWxlbWVudCBgKmAKCQkJCQkJdG9rZW5zLnNsaWNlKCAwLCBpIC0gMSApLmNvbmNhdCh7IHZhbHVlOiB0b2tlbnNbIGkgLSAyIF0udHlwZSA9PT0gIiAiID8gIioiIDogIiIgfSkKCQkJCQkpLnJlcGxhY2UoIHJ0cmltLCAiJDEiICksCgkJCQkJbWF0Y2hlciwKCQkJCQlpIDwgaiAmJiBtYXRjaGVyRnJvbVRva2VucyggdG9rZW5zLnNsaWNlKCBpLCBqICkgKSwKCQkJCQlqIDwgbGVuICYmIG1hdGNoZXJGcm9tVG9rZW5zKCAodG9rZW5zID0gdG9rZW5zLnNsaWNlKCBqICkpICksCgkJCQkJaiA8IGxlbiAmJiB0b1NlbGVjdG9yKCB0b2tlbnMgKQoJCQkJKTsKCQkJfQoJCQltYXRjaGVycy5wdXNoKCBtYXRjaGVyICk7CgkJfQoJfQoKCXJldHVybiBlbGVtZW50TWF0Y2hlciggbWF0Y2hlcnMgKTsKfQoKZnVuY3Rpb24gbWF0Y2hlckZyb21Hcm91cE1hdGNoZXJzKCBlbGVtZW50TWF0Y2hlcnMsIHNldE1hdGNoZXJzICkgewoJdmFyIGJ5U2V0ID0gc2V0TWF0Y2hlcnMubGVuZ3RoID4gMCwKCQlieUVsZW1lbnQgPSBlbGVtZW50TWF0Y2hlcnMubGVuZ3RoID4gMCwKCQlzdXBlck1hdGNoZXIgPSBmdW5jdGlvbiggc2VlZCwgY29udGV4dCwgeG1sLCByZXN1bHRzLCBvdXRlcm1vc3QgKSB7CgkJCXZhciBlbGVtLCBqLCBtYXRjaGVyLAoJCQkJbWF0Y2hlZENvdW50ID0gMCwKCQkJCWkgPSAiMCIsCgkJCQl1bm1hdGNoZWQgPSBzZWVkICYmIFtdLAoJCQkJc2V0TWF0Y2hlZCA9IFtdLAoJCQkJY29udGV4dEJhY2t1cCA9IG91dGVybW9zdENvbnRleHQsCgkJCQkvLyBXZSBtdXN0IGFsd2F5cyBoYXZlIGVpdGhlciBzZWVkIGVsZW1lbnRzIG9yIG91dGVybW9zdCBjb250ZXh0CgkJCQllbGVtcyA9IHNlZWQgfHwgYnlFbGVtZW50ICYmIEV4cHIuZmluZFsiVEFHIl0oICIqIiwgb3V0ZXJtb3N0ICksCgkJCQkvLyBVc2UgaW50ZWdlciBkaXJydW5zIGlmZiB0aGlzIGlzIHRoZSBvdXRlcm1vc3QgbWF0Y2hlcgoJCQkJZGlycnVuc1VuaXF1ZSA9IChkaXJydW5zICs9IGNvbnRleHRCYWNrdXAgPT0gbnVsbCA/IDEgOiBNYXRoLnJhbmRvbSgpIHx8IDAuMSksCgkJCQlsZW4gPSBlbGVtcy5sZW5ndGg7CgoJCQlpZiAoIG91dGVybW9zdCApIHsKCQkJCW91dGVybW9zdENvbnRleHQgPSBjb250ZXh0ID09PSBkb2N1bWVudCB8fCBjb250ZXh0IHx8IG91dGVybW9zdDsKCQkJfQoKCQkJLy8gQWRkIGVsZW1lbnRzIHBhc3NpbmcgZWxlbWVudE1hdGNoZXJzIGRpcmVjdGx5IHRvIHJlc3VsdHMKCQkJLy8gU3VwcG9ydDogSUU8OSwgU2FmYXJpCgkJCS8vIFRvbGVyYXRlIE5vZGVMaXN0IHByb3BlcnRpZXMgKElFOiAibGVuZ3RoIjsgU2FmYXJpOiA8bnVtYmVyPikgbWF0Y2hpbmcgZWxlbWVudHMgYnkgaWQKCQkJZm9yICggOyBpICE9PSBsZW4gJiYgKGVsZW0gPSBlbGVtc1tpXSkgIT0gbnVsbDsgaSsrICkgewoJCQkJaWYgKCBieUVsZW1lbnQgJiYgZWxlbSApIHsKCQkJCQlqID0gMDsKCQkJCQlpZiAoICFjb250ZXh0ICYmIGVsZW0ub3duZXJEb2N1bWVudCAhPT0gZG9jdW1lbnQgKSB7CgkJCQkJCXNldERvY3VtZW50KCBlbGVtICk7CgkJCQkJCXhtbCA9ICFkb2N1bWVudElzSFRNTDsKCQkJCQl9CgkJCQkJd2hpbGUgKCAobWF0Y2hlciA9IGVsZW1lbnRNYXRjaGVyc1tqKytdKSApIHsKCQkJCQkJaWYgKCBtYXRjaGVyKCBlbGVtLCBjb250ZXh0IHx8IGRvY3VtZW50LCB4bWwpICkgewoJCQkJCQkJcmVzdWx0cy5wdXNoKCBlbGVtICk7CgkJCQkJCQlicmVhazsKCQkJCQkJfQoJCQkJCX0KCQkJCQlpZiAoIG91dGVybW9zdCApIHsKCQkJCQkJZGlycnVucyA9IGRpcnJ1bnNVbmlxdWU7CgkJCQkJfQoJCQkJfQoKCQkJCS8vIFRyYWNrIHVubWF0Y2hlZCBlbGVtZW50cyBmb3Igc2V0IGZpbHRlcnMKCQkJCWlmICggYnlTZXQgKSB7CgkJCQkJLy8gVGhleSB3aWxsIGhhdmUgZ29uZSB0aHJvdWdoIGFsbCBwb3NzaWJsZSBtYXRjaGVycwoJCQkJCWlmICggKGVsZW0gPSAhbWF0Y2hlciAmJiBlbGVtKSApIHsKCQkJCQkJbWF0Y2hlZENvdW50LS07CgkJCQkJfQoKCQkJCQkvLyBMZW5ndGhlbiB0aGUgYXJyYXkgZm9yIGV2ZXJ5IGVsZW1lbnQsIG1hdGNoZWQgb3Igbm90CgkJCQkJaWYgKCBzZWVkICkgewoJCQkJCQl1bm1hdGNoZWQucHVzaCggZWxlbSApOwoJCQkJCX0KCQkJCX0KCQkJfQoKCQkJLy8gYGlgIGlzIG5vdyB0aGUgY291bnQgb2YgZWxlbWVudHMgdmlzaXRlZCBhYm92ZSwgYW5kIGFkZGluZyBpdCB0byBgbWF0Y2hlZENvdW50YAoJCQkvLyBtYWtlcyB0aGUgbGF0dGVyIG5vbm5lZ2F0aXZlLgoJCQltYXRjaGVkQ291bnQgKz0gaTsKCgkJCS8vIEFwcGx5IHNldCBmaWx0ZXJzIHRvIHVubWF0Y2hlZCBlbGVtZW50cwoJCQkvLyBOT1RFOiBUaGlzIGNhbiBiZSBza2lwcGVkIGlmIHRoZXJlIGFyZSBubyB1bm1hdGNoZWQgZWxlbWVudHMgKGkuZS4sIGBtYXRjaGVkQ291bnRgCgkJCS8vIGVxdWFscyBgaWApLCB1bmxlc3Mgd2UgZGlkbid0IHZpc2l0IF9hbnlfIGVsZW1lbnRzIGluIHRoZSBhYm92ZSBsb29wIGJlY2F1c2Ugd2UgaGF2ZQoJCQkvLyBubyBlbGVtZW50IG1hdGNoZXJzIGFuZCBubyBzZWVkLgoJCQkvLyBJbmNyZW1lbnRpbmcgYW4gaW5pdGlhbGx5LXN0cmluZyAiMCIgYGlgIGFsbG93cyBgaWAgdG8gcmVtYWluIGEgc3RyaW5nIG9ubHkgaW4gdGhhdAoJCQkvLyBjYXNlLCB3aGljaCB3aWxsIHJlc3VsdCBpbiBhICIwMCIgYG1hdGNoZWRDb3VudGAgdGhhdCBkaWZmZXJzIGZyb20gYGlgIGJ1dCBpcyBhbHNvCgkJCS8vIG51bWVyaWNhbGx5IHplcm8uCgkJCWlmICggYnlTZXQgJiYgaSAhPT0gbWF0Y2hlZENvdW50ICkgewoJCQkJaiA9IDA7CgkJCQl3aGlsZSAoIChtYXRjaGVyID0gc2V0TWF0Y2hlcnNbaisrXSkgKSB7CgkJCQkJbWF0Y2hlciggdW5tYXRjaGVkLCBzZXRNYXRjaGVkLCBjb250ZXh0LCB4bWwgKTsKCQkJCX0KCgkJCQlpZiAoIHNlZWQgKSB7CgkJCQkJLy8gUmVpbnRlZ3JhdGUgZWxlbWVudCBtYXRjaGVzIHRvIGVsaW1pbmF0ZSB0aGUgbmVlZCBmb3Igc29ydGluZwoJCQkJCWlmICggbWF0Y2hlZENvdW50ID4gMCApIHsKCQkJCQkJd2hpbGUgKCBpLS0gKSB7CgkJCQkJCQlpZiAoICEodW5tYXRjaGVkW2ldIHx8IHNldE1hdGNoZWRbaV0pICkgewoJCQkJCQkJCXNldE1hdGNoZWRbaV0gPSBwb3AuY2FsbCggcmVzdWx0cyApOwoJCQkJCQkJfQoJCQkJCQl9CgkJCQkJfQoKCQkJCQkvLyBEaXNjYXJkIGluZGV4IHBsYWNlaG9sZGVyIHZhbHVlcyB0byBnZXQgb25seSBhY3R1YWwgbWF0Y2hlcwoJCQkJCXNldE1hdGNoZWQgPSBjb25kZW5zZSggc2V0TWF0Y2hlZCApOwoJCQkJfQoKCQkJCS8vIEFkZCBtYXRjaGVzIHRvIHJlc3VsdHMKCQkJCXB1c2guYXBwbHkoIHJlc3VsdHMsIHNldE1hdGNoZWQgKTsKCgkJCQkvLyBTZWVkbGVzcyBzZXQgbWF0Y2hlcyBzdWNjZWVkaW5nIG11bHRpcGxlIHN1Y2Nlc3NmdWwgbWF0Y2hlcnMgc3RpcHVsYXRlIHNvcnRpbmcKCQkJCWlmICggb3V0ZXJtb3N0ICYmICFzZWVkICYmIHNldE1hdGNoZWQubGVuZ3RoID4gMCAmJgoJCQkJCSggbWF0Y2hlZENvdW50ICsgc2V0TWF0Y2hlcnMubGVuZ3RoICkgPiAxICkgewoKCQkJCQlTaXp6bGUudW5pcXVlU29ydCggcmVzdWx0cyApOwoJCQkJfQoJCQl9CgoJCQkvLyBPdmVycmlkZSBtYW5pcHVsYXRpb24gb2YgZ2xvYmFscyBieSBuZXN0ZWQgbWF0Y2hlcnMKCQkJaWYgKCBvdXRlcm1vc3QgKSB7CgkJCQlkaXJydW5zID0gZGlycnVuc1VuaXF1ZTsKCQkJCW91dGVybW9zdENvbnRleHQgPSBjb250ZXh0QmFja3VwOwoJCQl9CgoJCQlyZXR1cm4gdW5tYXRjaGVkOwoJCX07CgoJcmV0dXJuIGJ5U2V0ID8KCQltYXJrRnVuY3Rpb24oIHN1cGVyTWF0Y2hlciApIDoKCQlzdXBlck1hdGNoZXI7Cn0KCmNvbXBpbGUgPSBTaXp6bGUuY29tcGlsZSA9IGZ1bmN0aW9uKCBzZWxlY3RvciwgbWF0Y2ggLyogSW50ZXJuYWwgVXNlIE9ubHkgKi8gKSB7Cgl2YXIgaSwKCQlzZXRNYXRjaGVycyA9IFtdLAoJCWVsZW1lbnRNYXRjaGVycyA9IFtdLAoJCWNhY2hlZCA9IGNvbXBpbGVyQ2FjaGVbIHNlbGVjdG9yICsgIiAiIF07CgoJaWYgKCAhY2FjaGVkICkgewoJCS8vIEdlbmVyYXRlIGEgZnVuY3Rpb24gb2YgcmVjdXJzaXZlIGZ1bmN0aW9ucyB0aGF0IGNhbiBiZSB1c2VkIHRvIGNoZWNrIGVhY2ggZWxlbWVudAoJCWlmICggIW1hdGNoICkgewoJCQltYXRjaCA9IHRva2VuaXplKCBzZWxlY3RvciApOwoJCX0KCQlpID0gbWF0Y2gubGVuZ3RoOwoJCXdoaWxlICggaS0tICkgewoJCQljYWNoZWQgPSBtYXRjaGVyRnJvbVRva2VucyggbWF0Y2hbaV0gKTsKCQkJaWYgKCBjYWNoZWRbIGV4cGFuZG8gXSApIHsKCQkJCXNldE1hdGNoZXJzLnB1c2goIGNhY2hlZCApOwoJCQl9IGVsc2UgewoJCQkJZWxlbWVudE1hdGNoZXJzLnB1c2goIGNhY2hlZCApOwoJCQl9CgkJfQoKCQkvLyBDYWNoZSB0aGUgY29tcGlsZWQgZnVuY3Rpb24KCQljYWNoZWQgPSBjb21waWxlckNhY2hlKCBzZWxlY3RvciwgbWF0Y2hlckZyb21Hcm91cE1hdGNoZXJzKCBlbGVtZW50TWF0Y2hlcnMsIHNldE1hdGNoZXJzICkgKTsKCgkJLy8gU2F2ZSBzZWxlY3RvciBhbmQgdG9rZW5pemF0aW9uCgkJY2FjaGVkLnNlbGVjdG9yID0gc2VsZWN0b3I7Cgl9CglyZXR1cm4gY2FjaGVkOwp9OwoKLyoqCiAqIEEgbG93LWxldmVsIHNlbGVjdGlvbiBmdW5jdGlvbiB0aGF0IHdvcmtzIHdpdGggU2l6emxlJ3MgY29tcGlsZWQKICogIHNlbGVjdG9yIGZ1bmN0aW9ucwogKiBAcGFyYW0ge1N0cmluZ3xGdW5jdGlvbn0gc2VsZWN0b3IgQSBzZWxlY3RvciBvciBhIHByZS1jb21waWxlZAogKiAgc2VsZWN0b3IgZnVuY3Rpb24gYnVpbHQgd2l0aCBTaXp6bGUuY29tcGlsZQogKiBAcGFyYW0ge0VsZW1lbnR9IGNvbnRleHQKICogQHBhcmFtIHtBcnJheX0gW3Jlc3VsdHNdCiAqIEBwYXJhbSB7QXJyYXl9IFtzZWVkXSBBIHNldCBvZiBlbGVtZW50cyB0byBtYXRjaCBhZ2FpbnN0CiAqLwpzZWxlY3QgPSBTaXp6bGUuc2VsZWN0ID0gZnVuY3Rpb24oIHNlbGVjdG9yLCBjb250ZXh0LCByZXN1bHRzLCBzZWVkICkgewoJdmFyIGksIHRva2VucywgdG9rZW4sIHR5cGUsIGZpbmQsCgkJY29tcGlsZWQgPSB0eXBlb2Ygc2VsZWN0b3IgPT09ICJmdW5jdGlvbiIgJiYgc2VsZWN0b3IsCgkJbWF0Y2ggPSAhc2VlZCAmJiB0b2tlbml6ZSggKHNlbGVjdG9yID0gY29tcGlsZWQuc2VsZWN0b3IgfHwgc2VsZWN0b3IpICk7CgoJcmVzdWx0cyA9IHJlc3VsdHMgfHwgW107CgoJLy8gVHJ5IHRvIG1pbmltaXplIG9wZXJhdGlvbnMgaWYgdGhlcmUgaXMgb25seSBvbmUgc2VsZWN0b3IgaW4gdGhlIGxpc3QgYW5kIG5vIHNlZWQKCS8vICh0aGUgbGF0dGVyIG9mIHdoaWNoIGd1YXJhbnRlZXMgdXMgY29udGV4dCkKCWlmICggbWF0Y2gubGVuZ3RoID09PSAxICkgewoKCQkvLyBSZWR1Y2UgY29udGV4dCBpZiB0aGUgbGVhZGluZyBjb21wb3VuZCBzZWxlY3RvciBpcyBhbiBJRAoJCXRva2VucyA9IG1hdGNoWzBdID0gbWF0Y2hbMF0uc2xpY2UoIDAgKTsKCQlpZiAoIHRva2Vucy5sZW5ndGggPiAyICYmICh0b2tlbiA9IHRva2Vuc1swXSkudHlwZSA9PT0gIklEIiAmJgoJCQkJY29udGV4dC5ub2RlVHlwZSA9PT0gOSAmJiBkb2N1bWVudElzSFRNTCAmJiBFeHByLnJlbGF0aXZlWyB0b2tlbnNbMV0udHlwZSBdICkgewoKCQkJY29udGV4dCA9ICggRXhwci5maW5kWyJJRCJdKCB0b2tlbi5tYXRjaGVzWzBdLnJlcGxhY2UocnVuZXNjYXBlLCBmdW5lc2NhcGUpLCBjb250ZXh0ICkgfHwgW10gKVswXTsKCQkJaWYgKCAhY29udGV4dCApIHsKCQkJCXJldHVybiByZXN1bHRzOwoKCQkJLy8gUHJlY29tcGlsZWQgbWF0Y2hlcnMgd2lsbCBzdGlsbCB2ZXJpZnkgYW5jZXN0cnksIHNvIHN0ZXAgdXAgYSBsZXZlbAoJCQl9IGVsc2UgaWYgKCBjb21waWxlZCApIHsKCQkJCWNvbnRleHQgPSBjb250ZXh0LnBhcmVudE5vZGU7CgkJCX0KCgkJCXNlbGVjdG9yID0gc2VsZWN0b3Iuc2xpY2UoIHRva2Vucy5zaGlmdCgpLnZhbHVlLmxlbmd0aCApOwoJCX0KCgkJLy8gRmV0Y2ggYSBzZWVkIHNldCBmb3IgcmlnaHQtdG8tbGVmdCBtYXRjaGluZwoJCWkgPSBtYXRjaEV4cHJbIm5lZWRzQ29udGV4dCJdLnRlc3QoIHNlbGVjdG9yICkgPyAwIDogdG9rZW5zLmxlbmd0aDsKCQl3aGlsZSAoIGktLSApIHsKCQkJdG9rZW4gPSB0b2tlbnNbaV07CgoJCQkvLyBBYm9ydCBpZiB3ZSBoaXQgYSBjb21iaW5hdG9yCgkJCWlmICggRXhwci5yZWxhdGl2ZVsgKHR5cGUgPSB0b2tlbi50eXBlKSBdICkgewoJCQkJYnJlYWs7CgkJCX0KCQkJaWYgKCAoZmluZCA9IEV4cHIuZmluZFsgdHlwZSBdKSApIHsKCQkJCS8vIFNlYXJjaCwgZXhwYW5kaW5nIGNvbnRleHQgZm9yIGxlYWRpbmcgc2libGluZyBjb21iaW5hdG9ycwoJCQkJaWYgKCAoc2VlZCA9IGZpbmQoCgkJCQkJdG9rZW4ubWF0Y2hlc1swXS5yZXBsYWNlKCBydW5lc2NhcGUsIGZ1bmVzY2FwZSApLAoJCQkJCXJzaWJsaW5nLnRlc3QoIHRva2Vuc1swXS50eXBlICkgJiYgdGVzdENvbnRleHQoIGNvbnRleHQucGFyZW50Tm9kZSApIHx8IGNvbnRleHQKCQkJCSkpICkgewoKCQkJCQkvLyBJZiBzZWVkIGlzIGVtcHR5IG9yIG5vIHRva2VucyByZW1haW4sIHdlIGNhbiByZXR1cm4gZWFybHkKCQkJCQl0b2tlbnMuc3BsaWNlKCBpLCAxICk7CgkJCQkJc2VsZWN0b3IgPSBzZWVkLmxlbmd0aCAmJiB0b1NlbGVjdG9yKCB0b2tlbnMgKTsKCQkJCQlpZiAoICFzZWxlY3RvciApIHsKCQkJCQkJcHVzaC5hcHBseSggcmVzdWx0cywgc2VlZCApOwoJCQkJCQlyZXR1cm4gcmVzdWx0czsKCQkJCQl9CgoJCQkJCWJyZWFrOwoJCQkJfQoJCQl9CgkJfQoJfQoKCS8vIENvbXBpbGUgYW5kIGV4ZWN1dGUgYSBmaWx0ZXJpbmcgZnVuY3Rpb24gaWYgb25lIGlzIG5vdCBwcm92aWRlZAoJLy8gUHJvdmlkZSBgbWF0Y2hgIHRvIGF2b2lkIHJldG9rZW5pemF0aW9uIGlmIHdlIG1vZGlmaWVkIHRoZSBzZWxlY3RvciBhYm92ZQoJKCBjb21waWxlZCB8fCBjb21waWxlKCBzZWxlY3RvciwgbWF0Y2ggKSApKAoJCXNlZWQsCgkJY29udGV4dCwKCQkhZG9jdW1lbnRJc0hUTUwsCgkJcmVzdWx0cywKCQkhY29udGV4dCB8fCByc2libGluZy50ZXN0KCBzZWxlY3RvciApICYmIHRlc3RDb250ZXh0KCBjb250ZXh0LnBhcmVudE5vZGUgKSB8fCBjb250ZXh0CgkpOwoJcmV0dXJuIHJlc3VsdHM7Cn07CgovLyBPbmUtdGltZSBhc3NpZ25tZW50cwoKLy8gU29ydCBzdGFiaWxpdHkKc3VwcG9ydC5zb3J0U3RhYmxlID0gZXhwYW5kby5zcGxpdCgiIikuc29ydCggc29ydE9yZGVyICkuam9pbigiIikgPT09IGV4cGFuZG87CgovLyBTdXBwb3J0OiBDaHJvbWUgMTQtMzUrCi8vIEFsd2F5cyBhc3N1bWUgZHVwbGljYXRlcyBpZiB0aGV5IGFyZW4ndCBwYXNzZWQgdG8gdGhlIGNvbXBhcmlzb24gZnVuY3Rpb24Kc3VwcG9ydC5kZXRlY3REdXBsaWNhdGVzID0gISFoYXNEdXBsaWNhdGU7CgovLyBJbml0aWFsaXplIGFnYWluc3QgdGhlIGRlZmF1bHQgZG9jdW1lbnQKc2V0RG9jdW1lbnQoKTsKCi8vIFN1cHBvcnQ6IFdlYmtpdDw1MzcuMzIgLSBTYWZhcmkgNi4wLjMvQ2hyb21lIDI1IChmaXhlZCBpbiBDaHJvbWUgMjcpCi8vIERldGFjaGVkIG5vZGVzIGNvbmZvdW5kaW5nbHkgZm9sbG93ICplYWNoIG90aGVyKgpzdXBwb3J0LnNvcnREZXRhY2hlZCA9IGFzc2VydChmdW5jdGlvbiggZWwgKSB7CgkvLyBTaG91bGQgcmV0dXJuIDEsIGJ1dCByZXR1cm5zIDQgKGZvbGxvd2luZykKCXJldHVybiBlbC5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbiggZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiZmllbGRzZXQiKSApICYgMTsKfSk7CgovLyBTdXBwb3J0OiBJRTw4Ci8vIFByZXZlbnQgYXR0cmlidXRlL3Byb3BlcnR5ICJpbnRlcnBvbGF0aW9uIgovLyBodHRwczovL21zZG4ubWljcm9zb2Z0LmNvbS9lbi11cy9saWJyYXJ5L21zNTM2NDI5JTI4VlMuODUlMjkuYXNweAppZiAoICFhc3NlcnQoZnVuY3Rpb24oIGVsICkgewoJZWwuaW5uZXJIVE1MID0gIjxhIGhyZWY9JyMnPjwvYT4iOwoJcmV0dXJuIGVsLmZpcnN0Q2hpbGQuZ2V0QXR0cmlidXRlKCJocmVmIikgPT09ICIjIiA7Cn0pICkgewoJYWRkSGFuZGxlKCAidHlwZXxocmVmfGhlaWdodHx3aWR0aCIsIGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCBpc1hNTCApIHsKCQlpZiAoICFpc1hNTCApIHsKCQkJcmV0dXJuIGVsZW0uZ2V0QXR0cmlidXRlKCBuYW1lLCBuYW1lLnRvTG93ZXJDYXNlKCkgPT09ICJ0eXBlIiA/IDEgOiAyICk7CgkJfQoJfSk7Cn0KCi8vIFN1cHBvcnQ6IElFPDkKLy8gVXNlIGRlZmF1bHRWYWx1ZSBpbiBwbGFjZSBvZiBnZXRBdHRyaWJ1dGUoInZhbHVlIikKaWYgKCAhc3VwcG9ydC5hdHRyaWJ1dGVzIHx8ICFhc3NlcnQoZnVuY3Rpb24oIGVsICkgewoJZWwuaW5uZXJIVE1MID0gIjxpbnB1dC8+IjsKCWVsLmZpcnN0Q2hpbGQuc2V0QXR0cmlidXRlKCAidmFsdWUiLCAiIiApOwoJcmV0dXJuIGVsLmZpcnN0Q2hpbGQuZ2V0QXR0cmlidXRlKCAidmFsdWUiICkgPT09ICIiOwp9KSApIHsKCWFkZEhhbmRsZSggInZhbHVlIiwgZnVuY3Rpb24oIGVsZW0sIG5hbWUsIGlzWE1MICkgewoJCWlmICggIWlzWE1MICYmIGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKSA9PT0gImlucHV0IiApIHsKCQkJcmV0dXJuIGVsZW0uZGVmYXVsdFZhbHVlOwoJCX0KCX0pOwp9CgovLyBTdXBwb3J0OiBJRTw5Ci8vIFVzZSBnZXRBdHRyaWJ1dGVOb2RlIHRvIGZldGNoIGJvb2xlYW5zIHdoZW4gZ2V0QXR0cmlidXRlIGxpZXMKaWYgKCAhYXNzZXJ0KGZ1bmN0aW9uKCBlbCApIHsKCXJldHVybiBlbC5nZXRBdHRyaWJ1dGUoImRpc2FibGVkIikgPT0gbnVsbDsKfSkgKSB7CglhZGRIYW5kbGUoIGJvb2xlYW5zLCBmdW5jdGlvbiggZWxlbSwgbmFtZSwgaXNYTUwgKSB7CgkJdmFyIHZhbDsKCQlpZiAoICFpc1hNTCApIHsKCQkJcmV0dXJuIGVsZW1bIG5hbWUgXSA9PT0gdHJ1ZSA/IG5hbWUudG9Mb3dlckNhc2UoKSA6CgkJCQkJKHZhbCA9IGVsZW0uZ2V0QXR0cmlidXRlTm9kZSggbmFtZSApKSAmJiB2YWwuc3BlY2lmaWVkID8KCQkJCQl2YWwudmFsdWUgOgoJCQkJbnVsbDsKCQl9Cgl9KTsKfQoKcmV0dXJuIFNpenpsZTsKCn0pKCB3aW5kb3cgKTsKCgoKalF1ZXJ5LmZpbmQgPSBTaXp6bGU7CmpRdWVyeS5leHByID0gU2l6emxlLnNlbGVjdG9yczsKCi8vIERlcHJlY2F0ZWQKalF1ZXJ5LmV4cHJbICI6IiBdID0galF1ZXJ5LmV4cHIucHNldWRvczsKalF1ZXJ5LnVuaXF1ZVNvcnQgPSBqUXVlcnkudW5pcXVlID0gU2l6emxlLnVuaXF1ZVNvcnQ7CmpRdWVyeS50ZXh0ID0gU2l6emxlLmdldFRleHQ7CmpRdWVyeS5pc1hNTERvYyA9IFNpenpsZS5pc1hNTDsKalF1ZXJ5LmNvbnRhaW5zID0gU2l6emxlLmNvbnRhaW5zOwpqUXVlcnkuZXNjYXBlU2VsZWN0b3IgPSBTaXp6bGUuZXNjYXBlOwoKCgoKdmFyIGRpciA9IGZ1bmN0aW9uKCBlbGVtLCBkaXIsIHVudGlsICkgewoJdmFyIG1hdGNoZWQgPSBbXSwKCQl0cnVuY2F0ZSA9IHVudGlsICE9PSB1bmRlZmluZWQ7CgoJd2hpbGUgKCAoIGVsZW0gPSBlbGVtWyBkaXIgXSApICYmIGVsZW0ubm9kZVR5cGUgIT09IDkgKSB7CgkJaWYgKCBlbGVtLm5vZGVUeXBlID09PSAxICkgewoJCQlpZiAoIHRydW5jYXRlICYmIGpRdWVyeSggZWxlbSApLmlzKCB1bnRpbCApICkgewoJCQkJYnJlYWs7CgkJCX0KCQkJbWF0Y2hlZC5wdXNoKCBlbGVtICk7CgkJfQoJfQoJcmV0dXJuIG1hdGNoZWQ7Cn07CgoKdmFyIHNpYmxpbmdzID0gZnVuY3Rpb24oIG4sIGVsZW0gKSB7Cgl2YXIgbWF0Y2hlZCA9IFtdOwoKCWZvciAoIDsgbjsgbiA9IG4ubmV4dFNpYmxpbmcgKSB7CgkJaWYgKCBuLm5vZGVUeXBlID09PSAxICYmIG4gIT09IGVsZW0gKSB7CgkJCW1hdGNoZWQucHVzaCggbiApOwoJCX0KCX0KCglyZXR1cm4gbWF0Y2hlZDsKfTsKCgp2YXIgcm5lZWRzQ29udGV4dCA9IGpRdWVyeS5leHByLm1hdGNoLm5lZWRzQ29udGV4dDsKCgoKZnVuY3Rpb24gbm9kZU5hbWUoIGVsZW0sIG5hbWUgKSB7CgogIHJldHVybiBlbGVtLm5vZGVOYW1lICYmIGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKSA9PT0gbmFtZS50b0xvd2VyQ2FzZSgpOwoKfTsKdmFyIHJzaW5nbGVUYWcgPSAoIC9ePChbYS16XVteXC9cMD46XHgyMFx0XHJcblxmXSopW1x4MjBcdFxyXG5cZl0qXC8/Pig/OjxcL1wxPnwpJC9pICk7CgoKCi8vIEltcGxlbWVudCB0aGUgaWRlbnRpY2FsIGZ1bmN0aW9uYWxpdHkgZm9yIGZpbHRlciBhbmQgbm90CmZ1bmN0aW9uIHdpbm5vdyggZWxlbWVudHMsIHF1YWxpZmllciwgbm90ICkgewoJaWYgKCBpc0Z1bmN0aW9uKCBxdWFsaWZpZXIgKSApIHsKCQlyZXR1cm4galF1ZXJ5LmdyZXAoIGVsZW1lbnRzLCBmdW5jdGlvbiggZWxlbSwgaSApIHsKCQkJcmV0dXJuICEhcXVhbGlmaWVyLmNhbGwoIGVsZW0sIGksIGVsZW0gKSAhPT0gbm90OwoJCX0gKTsKCX0KCgkvLyBTaW5nbGUgZWxlbWVudAoJaWYgKCBxdWFsaWZpZXIubm9kZVR5cGUgKSB7CgkJcmV0dXJuIGpRdWVyeS5ncmVwKCBlbGVtZW50cywgZnVuY3Rpb24oIGVsZW0gKSB7CgkJCXJldHVybiAoIGVsZW0gPT09IHF1YWxpZmllciApICE9PSBub3Q7CgkJfSApOwoJfQoKCS8vIEFycmF5bGlrZSBvZiBlbGVtZW50cyAoalF1ZXJ5LCBhcmd1bWVudHMsIEFycmF5KQoJaWYgKCB0eXBlb2YgcXVhbGlmaWVyICE9PSAic3RyaW5nIiApIHsKCQlyZXR1cm4galF1ZXJ5LmdyZXAoIGVsZW1lbnRzLCBmdW5jdGlvbiggZWxlbSApIHsKCQkJcmV0dXJuICggaW5kZXhPZi5jYWxsKCBxdWFsaWZpZXIsIGVsZW0gKSA+IC0xICkgIT09IG5vdDsKCQl9ICk7Cgl9CgoJLy8gRmlsdGVyZWQgZGlyZWN0bHkgZm9yIGJvdGggc2ltcGxlIGFuZCBjb21wbGV4IHNlbGVjdG9ycwoJcmV0dXJuIGpRdWVyeS5maWx0ZXIoIHF1YWxpZmllciwgZWxlbWVudHMsIG5vdCApOwp9CgpqUXVlcnkuZmlsdGVyID0gZnVuY3Rpb24oIGV4cHIsIGVsZW1zLCBub3QgKSB7Cgl2YXIgZWxlbSA9IGVsZW1zWyAwIF07CgoJaWYgKCBub3QgKSB7CgkJZXhwciA9ICI6bm90KCIgKyBleHByICsgIikiOwoJfQoKCWlmICggZWxlbXMubGVuZ3RoID09PSAxICYmIGVsZW0ubm9kZVR5cGUgPT09IDEgKSB7CgkJcmV0dXJuIGpRdWVyeS5maW5kLm1hdGNoZXNTZWxlY3RvciggZWxlbSwgZXhwciApID8gWyBlbGVtIF0gOiBbXTsKCX0KCglyZXR1cm4galF1ZXJ5LmZpbmQubWF0Y2hlcyggZXhwciwgalF1ZXJ5LmdyZXAoIGVsZW1zLCBmdW5jdGlvbiggZWxlbSApIHsKCQlyZXR1cm4gZWxlbS5ub2RlVHlwZSA9PT0gMTsKCX0gKSApOwp9OwoKalF1ZXJ5LmZuLmV4dGVuZCggewoJZmluZDogZnVuY3Rpb24oIHNlbGVjdG9yICkgewoJCXZhciBpLCByZXQsCgkJCWxlbiA9IHRoaXMubGVuZ3RoLAoJCQlzZWxmID0gdGhpczsKCgkJaWYgKCB0eXBlb2Ygc2VsZWN0b3IgIT09ICJzdHJpbmciICkgewoJCQlyZXR1cm4gdGhpcy5wdXNoU3RhY2soIGpRdWVyeSggc2VsZWN0b3IgKS5maWx0ZXIoIGZ1bmN0aW9uKCkgewoJCQkJZm9yICggaSA9IDA7IGkgPCBsZW47IGkrKyApIHsKCQkJCQlpZiAoIGpRdWVyeS5jb250YWlucyggc2VsZlsgaSBdLCB0aGlzICkgKSB7CgkJCQkJCXJldHVybiB0cnVlOwoJCQkJCX0KCQkJCX0KCQkJfSApICk7CgkJfQoKCQlyZXQgPSB0aGlzLnB1c2hTdGFjayggW10gKTsKCgkJZm9yICggaSA9IDA7IGkgPCBsZW47IGkrKyApIHsKCQkJalF1ZXJ5LmZpbmQoIHNlbGVjdG9yLCBzZWxmWyBpIF0sIHJldCApOwoJCX0KCgkJcmV0dXJuIGxlbiA+IDEgPyBqUXVlcnkudW5pcXVlU29ydCggcmV0ICkgOiByZXQ7Cgl9LAoJZmlsdGVyOiBmdW5jdGlvbiggc2VsZWN0b3IgKSB7CgkJcmV0dXJuIHRoaXMucHVzaFN0YWNrKCB3aW5ub3coIHRoaXMsIHNlbGVjdG9yIHx8IFtdLCBmYWxzZSApICk7Cgl9LAoJbm90OiBmdW5jdGlvbiggc2VsZWN0b3IgKSB7CgkJcmV0dXJuIHRoaXMucHVzaFN0YWNrKCB3aW5ub3coIHRoaXMsIHNlbGVjdG9yIHx8IFtdLCB0cnVlICkgKTsKCX0sCglpczogZnVuY3Rpb24oIHNlbGVjdG9yICkgewoJCXJldHVybiAhIXdpbm5vdygKCQkJdGhpcywKCgkJCS8vIElmIHRoaXMgaXMgYSBwb3NpdGlvbmFsL3JlbGF0aXZlIHNlbGVjdG9yLCBjaGVjayBtZW1iZXJzaGlwIGluIHRoZSByZXR1cm5lZCBzZXQKCQkJLy8gc28gJCgicDpmaXJzdCIpLmlzKCJwOmxhc3QiKSB3b24ndCByZXR1cm4gdHJ1ZSBmb3IgYSBkb2Mgd2l0aCB0d28gInAiLgoJCQl0eXBlb2Ygc2VsZWN0b3IgPT09ICJzdHJpbmciICYmIHJuZWVkc0NvbnRleHQudGVzdCggc2VsZWN0b3IgKSA/CgkJCQlqUXVlcnkoIHNlbGVjdG9yICkgOgoJCQkJc2VsZWN0b3IgfHwgW10sCgkJCWZhbHNlCgkJKS5sZW5ndGg7Cgl9Cn0gKTsKCgovLyBJbml0aWFsaXplIGEgalF1ZXJ5IG9iamVjdAoKCi8vIEEgY2VudHJhbCByZWZlcmVuY2UgdG8gdGhlIHJvb3QgalF1ZXJ5KGRvY3VtZW50KQp2YXIgcm9vdGpRdWVyeSwKCgkvLyBBIHNpbXBsZSB3YXkgdG8gY2hlY2sgZm9yIEhUTUwgc3RyaW5ncwoJLy8gUHJpb3JpdGl6ZSAjaWQgb3ZlciA8dGFnPiB0byBhdm9pZCBYU1MgdmlhIGxvY2F0aW9uLmhhc2ggKCM5NTIxKQoJLy8gU3RyaWN0IEhUTUwgcmVjb2duaXRpb24gKCMxMTI5MDogbXVzdCBzdGFydCB3aXRoIDwpCgkvLyBTaG9ydGN1dCBzaW1wbGUgI2lkIGNhc2UgZm9yIHNwZWVkCglycXVpY2tFeHByID0gL14oPzpccyooPFtcd1xXXSs+KVtePl0qfCMoW1x3LV0rKSkkLywKCglpbml0ID0galF1ZXJ5LmZuLmluaXQgPSBmdW5jdGlvbiggc2VsZWN0b3IsIGNvbnRleHQsIHJvb3QgKSB7CgkJdmFyIG1hdGNoLCBlbGVtOwoKCQkvLyBIQU5ETEU6ICQoIiIpLCAkKG51bGwpLCAkKHVuZGVmaW5lZCksICQoZmFsc2UpCgkJaWYgKCAhc2VsZWN0b3IgKSB7CgkJCXJldHVybiB0aGlzOwoJCX0KCgkJLy8gTWV0aG9kIGluaXQoKSBhY2NlcHRzIGFuIGFsdGVybmF0ZSByb290alF1ZXJ5CgkJLy8gc28gbWlncmF0ZSBjYW4gc3VwcG9ydCBqUXVlcnkuc3ViIChnaC0yMTAxKQoJCXJvb3QgPSByb290IHx8IHJvb3RqUXVlcnk7CgoJCS8vIEhhbmRsZSBIVE1MIHN0cmluZ3MKCQlpZiAoIHR5cGVvZiBzZWxlY3RvciA9PT0gInN0cmluZyIgKSB7CgkJCWlmICggc2VsZWN0b3JbIDAgXSA9PT0gIjwiICYmCgkJCQlzZWxlY3Rvclsgc2VsZWN0b3IubGVuZ3RoIC0gMSBdID09PSAiPiIgJiYKCQkJCXNlbGVjdG9yLmxlbmd0aCA+PSAzICkgewoKCQkJCS8vIEFzc3VtZSB0aGF0IHN0cmluZ3MgdGhhdCBzdGFydCBhbmQgZW5kIHdpdGggPD4gYXJlIEhUTUwgYW5kIHNraXAgdGhlIHJlZ2V4IGNoZWNrCgkJCQltYXRjaCA9IFsgbnVsbCwgc2VsZWN0b3IsIG51bGwgXTsKCgkJCX0gZWxzZSB7CgkJCQltYXRjaCA9IHJxdWlja0V4cHIuZXhlYyggc2VsZWN0b3IgKTsKCQkJfQoKCQkJLy8gTWF0Y2ggaHRtbCBvciBtYWtlIHN1cmUgbm8gY29udGV4dCBpcyBzcGVjaWZpZWQgZm9yICNpZAoJCQlpZiAoIG1hdGNoICYmICggbWF0Y2hbIDEgXSB8fCAhY29udGV4dCApICkgewoKCQkJCS8vIEhBTkRMRTogJChodG1sKSAtPiAkKGFycmF5KQoJCQkJaWYgKCBtYXRjaFsgMSBdICkgewoJCQkJCWNvbnRleHQgPSBjb250ZXh0IGluc3RhbmNlb2YgalF1ZXJ5ID8gY29udGV4dFsgMCBdIDogY29udGV4dDsKCgkJCQkJLy8gT3B0aW9uIHRvIHJ1biBzY3JpcHRzIGlzIHRydWUgZm9yIGJhY2stY29tcGF0CgkJCQkJLy8gSW50ZW50aW9uYWxseSBsZXQgdGhlIGVycm9yIGJlIHRocm93biBpZiBwYXJzZUhUTUwgaXMgbm90IHByZXNlbnQKCQkJCQlqUXVlcnkubWVyZ2UoIHRoaXMsIGpRdWVyeS5wYXJzZUhUTUwoCgkJCQkJCW1hdGNoWyAxIF0sCgkJCQkJCWNvbnRleHQgJiYgY29udGV4dC5ub2RlVHlwZSA/IGNvbnRleHQub3duZXJEb2N1bWVudCB8fCBjb250ZXh0IDogZG9jdW1lbnQsCgkJCQkJCXRydWUKCQkJCQkpICk7CgoJCQkJCS8vIEhBTkRMRTogJChodG1sLCBwcm9wcykKCQkJCQlpZiAoIHJzaW5nbGVUYWcudGVzdCggbWF0Y2hbIDEgXSApICYmIGpRdWVyeS5pc1BsYWluT2JqZWN0KCBjb250ZXh0ICkgKSB7CgkJCQkJCWZvciAoIG1hdGNoIGluIGNvbnRleHQgKSB7CgoJCQkJCQkJLy8gUHJvcGVydGllcyBvZiBjb250ZXh0IGFyZSBjYWxsZWQgYXMgbWV0aG9kcyBpZiBwb3NzaWJsZQoJCQkJCQkJaWYgKCBpc0Z1bmN0aW9uKCB0aGlzWyBtYXRjaCBdICkgKSB7CgkJCQkJCQkJdGhpc1sgbWF0Y2ggXSggY29udGV4dFsgbWF0Y2ggXSApOwoKCQkJCQkJCS8vIC4uLmFuZCBvdGhlcndpc2Ugc2V0IGFzIGF0dHJpYnV0ZXMKCQkJCQkJCX0gZWxzZSB7CgkJCQkJCQkJdGhpcy5hdHRyKCBtYXRjaCwgY29udGV4dFsgbWF0Y2ggXSApOwoJCQkJCQkJfQoJCQkJCQl9CgkJCQkJfQoKCQkJCQlyZXR1cm4gdGhpczsKCgkJCQkvLyBIQU5ETEU6ICQoI2lkKQoJCQkJfSBlbHNlIHsKCQkJCQllbGVtID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoIG1hdGNoWyAyIF0gKTsKCgkJCQkJaWYgKCBlbGVtICkgewoKCQkJCQkJLy8gSW5qZWN0IHRoZSBlbGVtZW50IGRpcmVjdGx5IGludG8gdGhlIGpRdWVyeSBvYmplY3QKCQkJCQkJdGhpc1sgMCBdID0gZWxlbTsKCQkJCQkJdGhpcy5sZW5ndGggPSAxOwoJCQkJCX0KCQkJCQlyZXR1cm4gdGhpczsKCQkJCX0KCgkJCS8vIEhBTkRMRTogJChleHByLCAkKC4uLikpCgkJCX0gZWxzZSBpZiAoICFjb250ZXh0IHx8IGNvbnRleHQuanF1ZXJ5ICkgewoJCQkJcmV0dXJuICggY29udGV4dCB8fCByb290ICkuZmluZCggc2VsZWN0b3IgKTsKCgkJCS8vIEhBTkRMRTogJChleHByLCBjb250ZXh0KQoJCQkvLyAod2hpY2ggaXMganVzdCBlcXVpdmFsZW50IHRvOiAkKGNvbnRleHQpLmZpbmQoZXhwcikKCQkJfSBlbHNlIHsKCQkJCXJldHVybiB0aGlzLmNvbnN0cnVjdG9yKCBjb250ZXh0ICkuZmluZCggc2VsZWN0b3IgKTsKCQkJfQoKCQkvLyBIQU5ETEU6ICQoRE9NRWxlbWVudCkKCQl9IGVsc2UgaWYgKCBzZWxlY3Rvci5ub2RlVHlwZSApIHsKCQkJdGhpc1sgMCBdID0gc2VsZWN0b3I7CgkJCXRoaXMubGVuZ3RoID0gMTsKCQkJcmV0dXJuIHRoaXM7CgoJCS8vIEhBTkRMRTogJChmdW5jdGlvbikKCQkvLyBTaG9ydGN1dCBmb3IgZG9jdW1lbnQgcmVhZHkKCQl9IGVsc2UgaWYgKCBpc0Z1bmN0aW9uKCBzZWxlY3RvciApICkgewoJCQlyZXR1cm4gcm9vdC5yZWFkeSAhPT0gdW5kZWZpbmVkID8KCQkJCXJvb3QucmVhZHkoIHNlbGVjdG9yICkgOgoKCQkJCS8vIEV4ZWN1dGUgaW1tZWRpYXRlbHkgaWYgcmVhZHkgaXMgbm90IHByZXNlbnQKCQkJCXNlbGVjdG9yKCBqUXVlcnkgKTsKCQl9CgoJCXJldHVybiBqUXVlcnkubWFrZUFycmF5KCBzZWxlY3RvciwgdGhpcyApOwoJfTsKCi8vIEdpdmUgdGhlIGluaXQgZnVuY3Rpb24gdGhlIGpRdWVyeSBwcm90b3R5cGUgZm9yIGxhdGVyIGluc3RhbnRpYXRpb24KaW5pdC5wcm90b3R5cGUgPSBqUXVlcnkuZm47CgovLyBJbml0aWFsaXplIGNlbnRyYWwgcmVmZXJlbmNlCnJvb3RqUXVlcnkgPSBqUXVlcnkoIGRvY3VtZW50ICk7CgoKdmFyIHJwYXJlbnRzcHJldiA9IC9eKD86cGFyZW50c3xwcmV2KD86VW50aWx8QWxsKSkvLAoKCS8vIE1ldGhvZHMgZ3VhcmFudGVlZCB0byBwcm9kdWNlIGEgdW5pcXVlIHNldCB3aGVuIHN0YXJ0aW5nIGZyb20gYSB1bmlxdWUgc2V0CglndWFyYW50ZWVkVW5pcXVlID0gewoJCWNoaWxkcmVuOiB0cnVlLAoJCWNvbnRlbnRzOiB0cnVlLAoJCW5leHQ6IHRydWUsCgkJcHJldjogdHJ1ZQoJfTsKCmpRdWVyeS5mbi5leHRlbmQoIHsKCWhhczogZnVuY3Rpb24oIHRhcmdldCApIHsKCQl2YXIgdGFyZ2V0cyA9IGpRdWVyeSggdGFyZ2V0LCB0aGlzICksCgkJCWwgPSB0YXJnZXRzLmxlbmd0aDsKCgkJcmV0dXJuIHRoaXMuZmlsdGVyKCBmdW5jdGlvbigpIHsKCQkJdmFyIGkgPSAwOwoJCQlmb3IgKCA7IGkgPCBsOyBpKysgKSB7CgkJCQlpZiAoIGpRdWVyeS5jb250YWlucyggdGhpcywgdGFyZ2V0c1sgaSBdICkgKSB7CgkJCQkJcmV0dXJuIHRydWU7CgkJCQl9CgkJCX0KCQl9ICk7Cgl9LAoKCWNsb3Nlc3Q6IGZ1bmN0aW9uKCBzZWxlY3RvcnMsIGNvbnRleHQgKSB7CgkJdmFyIGN1ciwKCQkJaSA9IDAsCgkJCWwgPSB0aGlzLmxlbmd0aCwKCQkJbWF0Y2hlZCA9IFtdLAoJCQl0YXJnZXRzID0gdHlwZW9mIHNlbGVjdG9ycyAhPT0gInN0cmluZyIgJiYgalF1ZXJ5KCBzZWxlY3RvcnMgKTsKCgkJLy8gUG9zaXRpb25hbCBzZWxlY3RvcnMgbmV2ZXIgbWF0Y2gsIHNpbmNlIHRoZXJlJ3Mgbm8gX3NlbGVjdGlvbl8gY29udGV4dAoJCWlmICggIXJuZWVkc0NvbnRleHQudGVzdCggc2VsZWN0b3JzICkgKSB7CgkJCWZvciAoIDsgaSA8IGw7IGkrKyApIHsKCQkJCWZvciAoIGN1ciA9IHRoaXNbIGkgXTsgY3VyICYmIGN1ciAhPT0gY29udGV4dDsgY3VyID0gY3VyLnBhcmVudE5vZGUgKSB7CgoJCQkJCS8vIEFsd2F5cyBza2lwIGRvY3VtZW50IGZyYWdtZW50cwoJCQkJCWlmICggY3VyLm5vZGVUeXBlIDwgMTEgJiYgKCB0YXJnZXRzID8KCQkJCQkJdGFyZ2V0cy5pbmRleCggY3VyICkgPiAtMSA6CgoJCQkJCQkvLyBEb24ndCBwYXNzIG5vbi1lbGVtZW50cyB0byBTaXp6bGUKCQkJCQkJY3VyLm5vZGVUeXBlID09PSAxICYmCgkJCQkJCQlqUXVlcnkuZmluZC5tYXRjaGVzU2VsZWN0b3IoIGN1ciwgc2VsZWN0b3JzICkgKSApIHsKCgkJCQkJCW1hdGNoZWQucHVzaCggY3VyICk7CgkJCQkJCWJyZWFrOwoJCQkJCX0KCQkJCX0KCQkJfQoJCX0KCgkJcmV0dXJuIHRoaXMucHVzaFN0YWNrKCBtYXRjaGVkLmxlbmd0aCA+IDEgPyBqUXVlcnkudW5pcXVlU29ydCggbWF0Y2hlZCApIDogbWF0Y2hlZCApOwoJfSwKCgkvLyBEZXRlcm1pbmUgdGhlIHBvc2l0aW9uIG9mIGFuIGVsZW1lbnQgd2l0aGluIHRoZSBzZXQKCWluZGV4OiBmdW5jdGlvbiggZWxlbSApIHsKCgkJLy8gTm8gYXJndW1lbnQsIHJldHVybiBpbmRleCBpbiBwYXJlbnQKCQlpZiAoICFlbGVtICkgewoJCQlyZXR1cm4gKCB0aGlzWyAwIF0gJiYgdGhpc1sgMCBdLnBhcmVudE5vZGUgKSA/IHRoaXMuZmlyc3QoKS5wcmV2QWxsKCkubGVuZ3RoIDogLTE7CgkJfQoKCQkvLyBJbmRleCBpbiBzZWxlY3RvcgoJCWlmICggdHlwZW9mIGVsZW0gPT09ICJzdHJpbmciICkgewoJCQlyZXR1cm4gaW5kZXhPZi5jYWxsKCBqUXVlcnkoIGVsZW0gKSwgdGhpc1sgMCBdICk7CgkJfQoKCQkvLyBMb2NhdGUgdGhlIHBvc2l0aW9uIG9mIHRoZSBkZXNpcmVkIGVsZW1lbnQKCQlyZXR1cm4gaW5kZXhPZi5jYWxsKCB0aGlzLAoKCQkJLy8gSWYgaXQgcmVjZWl2ZXMgYSBqUXVlcnkgb2JqZWN0LCB0aGUgZmlyc3QgZWxlbWVudCBpcyB1c2VkCgkJCWVsZW0uanF1ZXJ5ID8gZWxlbVsgMCBdIDogZWxlbQoJCSk7Cgl9LAoKCWFkZDogZnVuY3Rpb24oIHNlbGVjdG9yLCBjb250ZXh0ICkgewoJCXJldHVybiB0aGlzLnB1c2hTdGFjaygKCQkJalF1ZXJ5LnVuaXF1ZVNvcnQoCgkJCQlqUXVlcnkubWVyZ2UoIHRoaXMuZ2V0KCksIGpRdWVyeSggc2VsZWN0b3IsIGNvbnRleHQgKSApCgkJCSkKCQkpOwoJfSwKCglhZGRCYWNrOiBmdW5jdGlvbiggc2VsZWN0b3IgKSB7CgkJcmV0dXJuIHRoaXMuYWRkKCBzZWxlY3RvciA9PSBudWxsID8KCQkJdGhpcy5wcmV2T2JqZWN0IDogdGhpcy5wcmV2T2JqZWN0LmZpbHRlciggc2VsZWN0b3IgKQoJCSk7Cgl9Cn0gKTsKCmZ1bmN0aW9uIHNpYmxpbmcoIGN1ciwgZGlyICkgewoJd2hpbGUgKCAoIGN1ciA9IGN1clsgZGlyIF0gKSAmJiBjdXIubm9kZVR5cGUgIT09IDEgKSB7fQoJcmV0dXJuIGN1cjsKfQoKalF1ZXJ5LmVhY2goIHsKCXBhcmVudDogZnVuY3Rpb24oIGVsZW0gKSB7CgkJdmFyIHBhcmVudCA9IGVsZW0ucGFyZW50Tm9kZTsKCQlyZXR1cm4gcGFyZW50ICYmIHBhcmVudC5ub2RlVHlwZSAhPT0gMTEgPyBwYXJlbnQgOiBudWxsOwoJfSwKCXBhcmVudHM6IGZ1bmN0aW9uKCBlbGVtICkgewoJCXJldHVybiBkaXIoIGVsZW0sICJwYXJlbnROb2RlIiApOwoJfSwKCXBhcmVudHNVbnRpbDogZnVuY3Rpb24oIGVsZW0sIGksIHVudGlsICkgewoJCXJldHVybiBkaXIoIGVsZW0sICJwYXJlbnROb2RlIiwgdW50aWwgKTsKCX0sCgluZXh0OiBmdW5jdGlvbiggZWxlbSApIHsKCQlyZXR1cm4gc2libGluZyggZWxlbSwgIm5leHRTaWJsaW5nIiApOwoJfSwKCXByZXY6IGZ1bmN0aW9uKCBlbGVtICkgewoJCXJldHVybiBzaWJsaW5nKCBlbGVtLCAicHJldmlvdXNTaWJsaW5nIiApOwoJfSwKCW5leHRBbGw6IGZ1bmN0aW9uKCBlbGVtICkgewoJCXJldHVybiBkaXIoIGVsZW0sICJuZXh0U2libGluZyIgKTsKCX0sCglwcmV2QWxsOiBmdW5jdGlvbiggZWxlbSApIHsKCQlyZXR1cm4gZGlyKCBlbGVtLCAicHJldmlvdXNTaWJsaW5nIiApOwoJfSwKCW5leHRVbnRpbDogZnVuY3Rpb24oIGVsZW0sIGksIHVudGlsICkgewoJCXJldHVybiBkaXIoIGVsZW0sICJuZXh0U2libGluZyIsIHVudGlsICk7Cgl9LAoJcHJldlVudGlsOiBmdW5jdGlvbiggZWxlbSwgaSwgdW50aWwgKSB7CgkJcmV0dXJuIGRpciggZWxlbSwgInByZXZpb3VzU2libGluZyIsIHVudGlsICk7Cgl9LAoJc2libGluZ3M6IGZ1bmN0aW9uKCBlbGVtICkgewoJCXJldHVybiBzaWJsaW5ncyggKCBlbGVtLnBhcmVudE5vZGUgfHwge30gKS5maXJzdENoaWxkLCBlbGVtICk7Cgl9LAoJY2hpbGRyZW46IGZ1bmN0aW9uKCBlbGVtICkgewoJCXJldHVybiBzaWJsaW5ncyggZWxlbS5maXJzdENoaWxkICk7Cgl9LAoJY29udGVudHM6IGZ1bmN0aW9uKCBlbGVtICkgewogICAgICAgIGlmICggbm9kZU5hbWUoIGVsZW0sICJpZnJhbWUiICkgKSB7CiAgICAgICAgICAgIHJldHVybiBlbGVtLmNvbnRlbnREb2N1bWVudDsKICAgICAgICB9CgogICAgICAgIC8vIFN1cHBvcnQ6IElFIDkgLSAxMSBvbmx5LCBpT1MgNyBvbmx5LCBBbmRyb2lkIEJyb3dzZXIgPD00LjMgb25seQogICAgICAgIC8vIFRyZWF0IHRoZSB0ZW1wbGF0ZSBlbGVtZW50IGFzIGEgcmVndWxhciBvbmUgaW4gYnJvd3NlcnMgdGhhdAogICAgICAgIC8vIGRvbid0IHN1cHBvcnQgaXQuCiAgICAgICAgaWYgKCBub2RlTmFtZSggZWxlbSwgInRlbXBsYXRlIiApICkgewogICAgICAgICAgICBlbGVtID0gZWxlbS5jb250ZW50IHx8IGVsZW07CiAgICAgICAgfQoKICAgICAgICByZXR1cm4galF1ZXJ5Lm1lcmdlKCBbXSwgZWxlbS5jaGlsZE5vZGVzICk7Cgl9Cn0sIGZ1bmN0aW9uKCBuYW1lLCBmbiApIHsKCWpRdWVyeS5mblsgbmFtZSBdID0gZnVuY3Rpb24oIHVudGlsLCBzZWxlY3RvciApIHsKCQl2YXIgbWF0Y2hlZCA9IGpRdWVyeS5tYXAoIHRoaXMsIGZuLCB1bnRpbCApOwoKCQlpZiAoIG5hbWUuc2xpY2UoIC01ICkgIT09ICJVbnRpbCIgKSB7CgkJCXNlbGVjdG9yID0gdW50aWw7CgkJfQoKCQlpZiAoIHNlbGVjdG9yICYmIHR5cGVvZiBzZWxlY3RvciA9PT0gInN0cmluZyIgKSB7CgkJCW1hdGNoZWQgPSBqUXVlcnkuZmlsdGVyKCBzZWxlY3RvciwgbWF0Y2hlZCApOwoJCX0KCgkJaWYgKCB0aGlzLmxlbmd0aCA+IDEgKSB7CgoJCQkvLyBSZW1vdmUgZHVwbGljYXRlcwoJCQlpZiAoICFndWFyYW50ZWVkVW5pcXVlWyBuYW1lIF0gKSB7CgkJCQlqUXVlcnkudW5pcXVlU29ydCggbWF0Y2hlZCApOwoJCQl9CgoJCQkvLyBSZXZlcnNlIG9yZGVyIGZvciBwYXJlbnRzKiBhbmQgcHJldi1kZXJpdmF0aXZlcwoJCQlpZiAoIHJwYXJlbnRzcHJldi50ZXN0KCBuYW1lICkgKSB7CgkJCQltYXRjaGVkLnJldmVyc2UoKTsKCQkJfQoJCX0KCgkJcmV0dXJuIHRoaXMucHVzaFN0YWNrKCBtYXRjaGVkICk7Cgl9Owp9ICk7CnZhciBybm90aHRtbHdoaXRlID0gKCAvW15ceDIwXHRcclxuXGZdKy9nICk7CgoKCi8vIENvbnZlcnQgU3RyaW5nLWZvcm1hdHRlZCBvcHRpb25zIGludG8gT2JqZWN0LWZvcm1hdHRlZCBvbmVzCmZ1bmN0aW9uIGNyZWF0ZU9wdGlvbnMoIG9wdGlvbnMgKSB7Cgl2YXIgb2JqZWN0ID0ge307CglqUXVlcnkuZWFjaCggb3B0aW9ucy5tYXRjaCggcm5vdGh0bWx3aGl0ZSApIHx8IFtdLCBmdW5jdGlvbiggXywgZmxhZyApIHsKCQlvYmplY3RbIGZsYWcgXSA9IHRydWU7Cgl9ICk7CglyZXR1cm4gb2JqZWN0Owp9CgovKgogKiBDcmVhdGUgYSBjYWxsYmFjayBsaXN0IHVzaW5nIHRoZSBmb2xsb3dpbmcgcGFyYW1ldGVyczoKICoKICoJb3B0aW9uczogYW4gb3B0aW9uYWwgbGlzdCBvZiBzcGFjZS1zZXBhcmF0ZWQgb3B0aW9ucyB0aGF0IHdpbGwgY2hhbmdlIGhvdwogKgkJCXRoZSBjYWxsYmFjayBsaXN0IGJlaGF2ZXMgb3IgYSBtb3JlIHRyYWRpdGlvbmFsIG9wdGlvbiBvYmplY3QKICoKICogQnkgZGVmYXVsdCBhIGNhbGxiYWNrIGxpc3Qgd2lsbCBhY3QgbGlrZSBhbiBldmVudCBjYWxsYmFjayBsaXN0IGFuZCBjYW4gYmUKICogImZpcmVkIiBtdWx0aXBsZSB0aW1lcy4KICoKICogUG9zc2libGUgb3B0aW9uczoKICoKICoJb25jZToJCQl3aWxsIGVuc3VyZSB0aGUgY2FsbGJhY2sgbGlzdCBjYW4gb25seSBiZSBmaXJlZCBvbmNlIChsaWtlIGEgRGVmZXJyZWQpCiAqCiAqCW1lbW9yeToJCQl3aWxsIGtlZXAgdHJhY2sgb2YgcHJldmlvdXMgdmFsdWVzIGFuZCB3aWxsIGNhbGwgYW55IGNhbGxiYWNrIGFkZGVkCiAqCQkJCQlhZnRlciB0aGUgbGlzdCBoYXMgYmVlbiBmaXJlZCByaWdodCBhd2F5IHdpdGggdGhlIGxhdGVzdCAibWVtb3JpemVkIgogKgkJCQkJdmFsdWVzIChsaWtlIGEgRGVmZXJyZWQpCiAqCiAqCXVuaXF1ZToJCQl3aWxsIGVuc3VyZSBhIGNhbGxiYWNrIGNhbiBvbmx5IGJlIGFkZGVkIG9uY2UgKG5vIGR1cGxpY2F0ZSBpbiB0aGUgbGlzdCkKICoKICoJc3RvcE9uRmFsc2U6CWludGVycnVwdCBjYWxsaW5ncyB3aGVuIGEgY2FsbGJhY2sgcmV0dXJucyBmYWxzZQogKgogKi8KalF1ZXJ5LkNhbGxiYWNrcyA9IGZ1bmN0aW9uKCBvcHRpb25zICkgewoKCS8vIENvbnZlcnQgb3B0aW9ucyBmcm9tIFN0cmluZy1mb3JtYXR0ZWQgdG8gT2JqZWN0LWZvcm1hdHRlZCBpZiBuZWVkZWQKCS8vICh3ZSBjaGVjayBpbiBjYWNoZSBmaXJzdCkKCW9wdGlvbnMgPSB0eXBlb2Ygb3B0aW9ucyA9PT0gInN0cmluZyIgPwoJCWNyZWF0ZU9wdGlvbnMoIG9wdGlvbnMgKSA6CgkJalF1ZXJ5LmV4dGVuZCgge30sIG9wdGlvbnMgKTsKCgl2YXIgLy8gRmxhZyB0byBrbm93IGlmIGxpc3QgaXMgY3VycmVudGx5IGZpcmluZwoJCWZpcmluZywKCgkJLy8gTGFzdCBmaXJlIHZhbHVlIGZvciBub24tZm9yZ2V0dGFibGUgbGlzdHMKCQltZW1vcnksCgoJCS8vIEZsYWcgdG8ga25vdyBpZiBsaXN0IHdhcyBhbHJlYWR5IGZpcmVkCgkJZmlyZWQsCgoJCS8vIEZsYWcgdG8gcHJldmVudCBmaXJpbmcKCQlsb2NrZWQsCgoJCS8vIEFjdHVhbCBjYWxsYmFjayBsaXN0CgkJbGlzdCA9IFtdLAoKCQkvLyBRdWV1ZSBvZiBleGVjdXRpb24gZGF0YSBmb3IgcmVwZWF0YWJsZSBsaXN0cwoJCXF1ZXVlID0gW10sCgoJCS8vIEluZGV4IG9mIGN1cnJlbnRseSBmaXJpbmcgY2FsbGJhY2sgKG1vZGlmaWVkIGJ5IGFkZC9yZW1vdmUgYXMgbmVlZGVkKQoJCWZpcmluZ0luZGV4ID0gLTEsCgoJCS8vIEZpcmUgY2FsbGJhY2tzCgkJZmlyZSA9IGZ1bmN0aW9uKCkgewoKCQkJLy8gRW5mb3JjZSBzaW5nbGUtZmlyaW5nCgkJCWxvY2tlZCA9IGxvY2tlZCB8fCBvcHRpb25zLm9uY2U7CgoJCQkvLyBFeGVjdXRlIGNhbGxiYWNrcyBmb3IgYWxsIHBlbmRpbmcgZXhlY3V0aW9ucywKCQkJLy8gcmVzcGVjdGluZyBmaXJpbmdJbmRleCBvdmVycmlkZXMgYW5kIHJ1bnRpbWUgY2hhbmdlcwoJCQlmaXJlZCA9IGZpcmluZyA9IHRydWU7CgkJCWZvciAoIDsgcXVldWUubGVuZ3RoOyBmaXJpbmdJbmRleCA9IC0xICkgewoJCQkJbWVtb3J5ID0gcXVldWUuc2hpZnQoKTsKCQkJCXdoaWxlICggKytmaXJpbmdJbmRleCA8IGxpc3QubGVuZ3RoICkgewoKCQkJCQkvLyBSdW4gY2FsbGJhY2sgYW5kIGNoZWNrIGZvciBlYXJseSB0ZXJtaW5hdGlvbgoJCQkJCWlmICggbGlzdFsgZmlyaW5nSW5kZXggXS5hcHBseSggbWVtb3J5WyAwIF0sIG1lbW9yeVsgMSBdICkgPT09IGZhbHNlICYmCgkJCQkJCW9wdGlvbnMuc3RvcE9uRmFsc2UgKSB7CgoJCQkJCQkvLyBKdW1wIHRvIGVuZCBhbmQgZm9yZ2V0IHRoZSBkYXRhIHNvIC5hZGQgZG9lc24ndCByZS1maXJlCgkJCQkJCWZpcmluZ0luZGV4ID0gbGlzdC5sZW5ndGg7CgkJCQkJCW1lbW9yeSA9IGZhbHNlOwoJCQkJCX0KCQkJCX0KCQkJfQoKCQkJLy8gRm9yZ2V0IHRoZSBkYXRhIGlmIHdlJ3JlIGRvbmUgd2l0aCBpdAoJCQlpZiAoICFvcHRpb25zLm1lbW9yeSApIHsKCQkJCW1lbW9yeSA9IGZhbHNlOwoJCQl9CgoJCQlmaXJpbmcgPSBmYWxzZTsKCgkJCS8vIENsZWFuIHVwIGlmIHdlJ3JlIGRvbmUgZmlyaW5nIGZvciBnb29kCgkJCWlmICggbG9ja2VkICkgewoKCQkJCS8vIEtlZXAgYW4gZW1wdHkgbGlzdCBpZiB3ZSBoYXZlIGRhdGEgZm9yIGZ1dHVyZSBhZGQgY2FsbHMKCQkJCWlmICggbWVtb3J5ICkgewoJCQkJCWxpc3QgPSBbXTsKCgkJCQkvLyBPdGhlcndpc2UsIHRoaXMgb2JqZWN0IGlzIHNwZW50CgkJCQl9IGVsc2UgewoJCQkJCWxpc3QgPSAiIjsKCQkJCX0KCQkJfQoJCX0sCgoJCS8vIEFjdHVhbCBDYWxsYmFja3Mgb2JqZWN0CgkJc2VsZiA9IHsKCgkJCS8vIEFkZCBhIGNhbGxiYWNrIG9yIGEgY29sbGVjdGlvbiBvZiBjYWxsYmFja3MgdG8gdGhlIGxpc3QKCQkJYWRkOiBmdW5jdGlvbigpIHsKCQkJCWlmICggbGlzdCApIHsKCgkJCQkJLy8gSWYgd2UgaGF2ZSBtZW1vcnkgZnJvbSBhIHBhc3QgcnVuLCB3ZSBzaG91bGQgZmlyZSBhZnRlciBhZGRpbmcKCQkJCQlpZiAoIG1lbW9yeSAmJiAhZmlyaW5nICkgewoJCQkJCQlmaXJpbmdJbmRleCA9IGxpc3QubGVuZ3RoIC0gMTsKCQkJCQkJcXVldWUucHVzaCggbWVtb3J5ICk7CgkJCQkJfQoKCQkJCQkoIGZ1bmN0aW9uIGFkZCggYXJncyApIHsKCQkJCQkJalF1ZXJ5LmVhY2goIGFyZ3MsIGZ1bmN0aW9uKCBfLCBhcmcgKSB7CgkJCQkJCQlpZiAoIGlzRnVuY3Rpb24oIGFyZyApICkgewoJCQkJCQkJCWlmICggIW9wdGlvbnMudW5pcXVlIHx8ICFzZWxmLmhhcyggYXJnICkgKSB7CgkJCQkJCQkJCWxpc3QucHVzaCggYXJnICk7CgkJCQkJCQkJfQoJCQkJCQkJfSBlbHNlIGlmICggYXJnICYmIGFyZy5sZW5ndGggJiYgdG9UeXBlKCBhcmcgKSAhPT0gInN0cmluZyIgKSB7CgoJCQkJCQkJCS8vIEluc3BlY3QgcmVjdXJzaXZlbHkKCQkJCQkJCQlhZGQoIGFyZyApOwoJCQkJCQkJfQoJCQkJCQl9ICk7CgkJCQkJfSApKCBhcmd1bWVudHMgKTsKCgkJCQkJaWYgKCBtZW1vcnkgJiYgIWZpcmluZyApIHsKCQkJCQkJZmlyZSgpOwoJCQkJCX0KCQkJCX0KCQkJCXJldHVybiB0aGlzOwoJCQl9LAoKCQkJLy8gUmVtb3ZlIGEgY2FsbGJhY2sgZnJvbSB0aGUgbGlzdAoJCQlyZW1vdmU6IGZ1bmN0aW9uKCkgewoJCQkJalF1ZXJ5LmVhY2goIGFyZ3VtZW50cywgZnVuY3Rpb24oIF8sIGFyZyApIHsKCQkJCQl2YXIgaW5kZXg7CgkJCQkJd2hpbGUgKCAoIGluZGV4ID0galF1ZXJ5LmluQXJyYXkoIGFyZywgbGlzdCwgaW5kZXggKSApID4gLTEgKSB7CgkJCQkJCWxpc3Quc3BsaWNlKCBpbmRleCwgMSApOwoKCQkJCQkJLy8gSGFuZGxlIGZpcmluZyBpbmRleGVzCgkJCQkJCWlmICggaW5kZXggPD0gZmlyaW5nSW5kZXggKSB7CgkJCQkJCQlmaXJpbmdJbmRleC0tOwoJCQkJCQl9CgkJCQkJfQoJCQkJfSApOwoJCQkJcmV0dXJuIHRoaXM7CgkJCX0sCgoJCQkvLyBDaGVjayBpZiBhIGdpdmVuIGNhbGxiYWNrIGlzIGluIHRoZSBsaXN0LgoJCQkvLyBJZiBubyBhcmd1bWVudCBpcyBnaXZlbiwgcmV0dXJuIHdoZXRoZXIgb3Igbm90IGxpc3QgaGFzIGNhbGxiYWNrcyBhdHRhY2hlZC4KCQkJaGFzOiBmdW5jdGlvbiggZm4gKSB7CgkJCQlyZXR1cm4gZm4gPwoJCQkJCWpRdWVyeS5pbkFycmF5KCBmbiwgbGlzdCApID4gLTEgOgoJCQkJCWxpc3QubGVuZ3RoID4gMDsKCQkJfSwKCgkJCS8vIFJlbW92ZSBhbGwgY2FsbGJhY2tzIGZyb20gdGhlIGxpc3QKCQkJZW1wdHk6IGZ1bmN0aW9uKCkgewoJCQkJaWYgKCBsaXN0ICkgewoJCQkJCWxpc3QgPSBbXTsKCQkJCX0KCQkJCXJldHVybiB0aGlzOwoJCQl9LAoKCQkJLy8gRGlzYWJsZSAuZmlyZSBhbmQgLmFkZAoJCQkvLyBBYm9ydCBhbnkgY3VycmVudC9wZW5kaW5nIGV4ZWN1dGlvbnMKCQkJLy8gQ2xlYXIgYWxsIGNhbGxiYWNrcyBhbmQgdmFsdWVzCgkJCWRpc2FibGU6IGZ1bmN0aW9uKCkgewoJCQkJbG9ja2VkID0gcXVldWUgPSBbXTsKCQkJCWxpc3QgPSBtZW1vcnkgPSAiIjsKCQkJCXJldHVybiB0aGlzOwoJCQl9LAoJCQlkaXNhYmxlZDogZnVuY3Rpb24oKSB7CgkJCQlyZXR1cm4gIWxpc3Q7CgkJCX0sCgoJCQkvLyBEaXNhYmxlIC5maXJlCgkJCS8vIEFsc28gZGlzYWJsZSAuYWRkIHVubGVzcyB3ZSBoYXZlIG1lbW9yeSAoc2luY2UgaXQgd291bGQgaGF2ZSBubyBlZmZlY3QpCgkJCS8vIEFib3J0IGFueSBwZW5kaW5nIGV4ZWN1dGlvbnMKCQkJbG9jazogZnVuY3Rpb24oKSB7CgkJCQlsb2NrZWQgPSBxdWV1ZSA9IFtdOwoJCQkJaWYgKCAhbWVtb3J5ICYmICFmaXJpbmcgKSB7CgkJCQkJbGlzdCA9IG1lbW9yeSA9ICIiOwoJCQkJfQoJCQkJcmV0dXJuIHRoaXM7CgkJCX0sCgkJCWxvY2tlZDogZnVuY3Rpb24oKSB7CgkJCQlyZXR1cm4gISFsb2NrZWQ7CgkJCX0sCgoJCQkvLyBDYWxsIGFsbCBjYWxsYmFja3Mgd2l0aCB0aGUgZ2l2ZW4gY29udGV4dCBhbmQgYXJndW1lbnRzCgkJCWZpcmVXaXRoOiBmdW5jdGlvbiggY29udGV4dCwgYXJncyApIHsKCQkJCWlmICggIWxvY2tlZCApIHsKCQkJCQlhcmdzID0gYXJncyB8fCBbXTsKCQkJCQlhcmdzID0gWyBjb250ZXh0LCBhcmdzLnNsaWNlID8gYXJncy5zbGljZSgpIDogYXJncyBdOwoJCQkJCXF1ZXVlLnB1c2goIGFyZ3MgKTsKCQkJCQlpZiAoICFmaXJpbmcgKSB7CgkJCQkJCWZpcmUoKTsKCQkJCQl9CgkJCQl9CgkJCQlyZXR1cm4gdGhpczsKCQkJfSwKCgkJCS8vIENhbGwgYWxsIHRoZSBjYWxsYmFja3Mgd2l0aCB0aGUgZ2l2ZW4gYXJndW1lbnRzCgkJCWZpcmU6IGZ1bmN0aW9uKCkgewoJCQkJc2VsZi5maXJlV2l0aCggdGhpcywgYXJndW1lbnRzICk7CgkJCQlyZXR1cm4gdGhpczsKCQkJfSwKCgkJCS8vIFRvIGtub3cgaWYgdGhlIGNhbGxiYWNrcyBoYXZlIGFscmVhZHkgYmVlbiBjYWxsZWQgYXQgbGVhc3Qgb25jZQoJCQlmaXJlZDogZnVuY3Rpb24oKSB7CgkJCQlyZXR1cm4gISFmaXJlZDsKCQkJfQoJCX07CgoJcmV0dXJuIHNlbGY7Cn07CgoKZnVuY3Rpb24gSWRlbnRpdHkoIHYgKSB7CglyZXR1cm4gdjsKfQpmdW5jdGlvbiBUaHJvd2VyKCBleCApIHsKCXRocm93IGV4Owp9CgpmdW5jdGlvbiBhZG9wdFZhbHVlKCB2YWx1ZSwgcmVzb2x2ZSwgcmVqZWN0LCBub1ZhbHVlICkgewoJdmFyIG1ldGhvZDsKCgl0cnkgewoKCQkvLyBDaGVjayBmb3IgcHJvbWlzZSBhc3BlY3QgZmlyc3QgdG8gcHJpdmlsZWdlIHN5bmNocm9ub3VzIGJlaGF2aW9yCgkJaWYgKCB2YWx1ZSAmJiBpc0Z1bmN0aW9uKCAoIG1ldGhvZCA9IHZhbHVlLnByb21pc2UgKSApICkgewoJCQltZXRob2QuY2FsbCggdmFsdWUgKS5kb25lKCByZXNvbHZlICkuZmFpbCggcmVqZWN0ICk7CgoJCS8vIE90aGVyIHRoZW5hYmxlcwoJCX0gZWxzZSBpZiAoIHZhbHVlICYmIGlzRnVuY3Rpb24oICggbWV0aG9kID0gdmFsdWUudGhlbiApICkgKSB7CgkJCW1ldGhvZC5jYWxsKCB2YWx1ZSwgcmVzb2x2ZSwgcmVqZWN0ICk7CgoJCS8vIE90aGVyIG5vbi10aGVuYWJsZXMKCQl9IGVsc2UgewoKCQkJLy8gQ29udHJvbCBgcmVzb2x2ZWAgYXJndW1lbnRzIGJ5IGxldHRpbmcgQXJyYXkjc2xpY2UgY2FzdCBib29sZWFuIGBub1ZhbHVlYCB0byBpbnRlZ2VyOgoJCQkvLyAqIGZhbHNlOiBbIHZhbHVlIF0uc2xpY2UoIDAgKSA9PiByZXNvbHZlKCB2YWx1ZSApCgkJCS8vICogdHJ1ZTogWyB2YWx1ZSBdLnNsaWNlKCAxICkgPT4gcmVzb2x2ZSgpCgkJCXJlc29sdmUuYXBwbHkoIHVuZGVmaW5lZCwgWyB2YWx1ZSBdLnNsaWNlKCBub1ZhbHVlICkgKTsKCQl9CgoJLy8gRm9yIFByb21pc2VzL0ErLCBjb252ZXJ0IGV4Y2VwdGlvbnMgaW50byByZWplY3Rpb25zCgkvLyBTaW5jZSBqUXVlcnkud2hlbiBkb2Vzbid0IHVud3JhcCB0aGVuYWJsZXMsIHdlIGNhbiBza2lwIHRoZSBleHRyYSBjaGVja3MgYXBwZWFyaW5nIGluCgkvLyBEZWZlcnJlZCN0aGVuIHRvIGNvbmRpdGlvbmFsbHkgc3VwcHJlc3MgcmVqZWN0aW9uLgoJfSBjYXRjaCAoIHZhbHVlICkgewoKCQkvLyBTdXBwb3J0OiBBbmRyb2lkIDQuMCBvbmx5CgkJLy8gU3RyaWN0IG1vZGUgZnVuY3Rpb25zIGludm9rZWQgd2l0aG91dCAuY2FsbC8uYXBwbHkgZ2V0IGdsb2JhbC1vYmplY3QgY29udGV4dAoJCXJlamVjdC5hcHBseSggdW5kZWZpbmVkLCBbIHZhbHVlIF0gKTsKCX0KfQoKalF1ZXJ5LmV4dGVuZCggewoKCURlZmVycmVkOiBmdW5jdGlvbiggZnVuYyApIHsKCQl2YXIgdHVwbGVzID0gWwoKCQkJCS8vIGFjdGlvbiwgYWRkIGxpc3RlbmVyLCBjYWxsYmFja3MsCgkJCQkvLyAuLi4gLnRoZW4gaGFuZGxlcnMsIGFyZ3VtZW50IGluZGV4LCBbZmluYWwgc3RhdGVdCgkJCQlbICJub3RpZnkiLCAicHJvZ3Jlc3MiLCBqUXVlcnkuQ2FsbGJhY2tzKCAibWVtb3J5IiApLAoJCQkJCWpRdWVyeS5DYWxsYmFja3MoICJtZW1vcnkiICksIDIgXSwKCQkJCVsgInJlc29sdmUiLCAiZG9uZSIsIGpRdWVyeS5DYWxsYmFja3MoICJvbmNlIG1lbW9yeSIgKSwKCQkJCQlqUXVlcnkuQ2FsbGJhY2tzKCAib25jZSBtZW1vcnkiICksIDAsICJyZXNvbHZlZCIgXSwKCQkJCVsgInJlamVjdCIsICJmYWlsIiwgalF1ZXJ5LkNhbGxiYWNrcyggIm9uY2UgbWVtb3J5IiApLAoJCQkJCWpRdWVyeS5DYWxsYmFja3MoICJvbmNlIG1lbW9yeSIgKSwgMSwgInJlamVjdGVkIiBdCgkJCV0sCgkJCXN0YXRlID0gInBlbmRpbmciLAoJCQlwcm9taXNlID0gewoJCQkJc3RhdGU6IGZ1bmN0aW9uKCkgewoJCQkJCXJldHVybiBzdGF0ZTsKCQkJCX0sCgkJCQlhbHdheXM6IGZ1bmN0aW9uKCkgewoJCQkJCWRlZmVycmVkLmRvbmUoIGFyZ3VtZW50cyApLmZhaWwoIGFyZ3VtZW50cyApOwoJCQkJCXJldHVybiB0aGlzOwoJCQkJfSwKCQkJCSJjYXRjaCI6IGZ1bmN0aW9uKCBmbiApIHsKCQkJCQlyZXR1cm4gcHJvbWlzZS50aGVuKCBudWxsLCBmbiApOwoJCQkJfSwKCgkJCQkvLyBLZWVwIHBpcGUgZm9yIGJhY2stY29tcGF0CgkJCQlwaXBlOiBmdW5jdGlvbiggLyogZm5Eb25lLCBmbkZhaWwsIGZuUHJvZ3Jlc3MgKi8gKSB7CgkJCQkJdmFyIGZucyA9IGFyZ3VtZW50czsKCgkJCQkJcmV0dXJuIGpRdWVyeS5EZWZlcnJlZCggZnVuY3Rpb24oIG5ld0RlZmVyICkgewoJCQkJCQlqUXVlcnkuZWFjaCggdHVwbGVzLCBmdW5jdGlvbiggaSwgdHVwbGUgKSB7CgoJCQkJCQkJLy8gTWFwIHR1cGxlcyAocHJvZ3Jlc3MsIGRvbmUsIGZhaWwpIHRvIGFyZ3VtZW50cyAoZG9uZSwgZmFpbCwgcHJvZ3Jlc3MpCgkJCQkJCQl2YXIgZm4gPSBpc0Z1bmN0aW9uKCBmbnNbIHR1cGxlWyA0IF0gXSApICYmIGZuc1sgdHVwbGVbIDQgXSBdOwoKCQkJCQkJCS8vIGRlZmVycmVkLnByb2dyZXNzKGZ1bmN0aW9uKCkgeyBiaW5kIHRvIG5ld0RlZmVyIG9yIG5ld0RlZmVyLm5vdGlmeSB9KQoJCQkJCQkJLy8gZGVmZXJyZWQuZG9uZShmdW5jdGlvbigpIHsgYmluZCB0byBuZXdEZWZlciBvciBuZXdEZWZlci5yZXNvbHZlIH0pCgkJCQkJCQkvLyBkZWZlcnJlZC5mYWlsKGZ1bmN0aW9uKCkgeyBiaW5kIHRvIG5ld0RlZmVyIG9yIG5ld0RlZmVyLnJlamVjdCB9KQoJCQkJCQkJZGVmZXJyZWRbIHR1cGxlWyAxIF0gXSggZnVuY3Rpb24oKSB7CgkJCQkJCQkJdmFyIHJldHVybmVkID0gZm4gJiYgZm4uYXBwbHkoIHRoaXMsIGFyZ3VtZW50cyApOwoJCQkJCQkJCWlmICggcmV0dXJuZWQgJiYgaXNGdW5jdGlvbiggcmV0dXJuZWQucHJvbWlzZSApICkgewoJCQkJCQkJCQlyZXR1cm5lZC5wcm9taXNlKCkKCQkJCQkJCQkJCS5wcm9ncmVzcyggbmV3RGVmZXIubm90aWZ5ICkKCQkJCQkJCQkJCS5kb25lKCBuZXdEZWZlci5yZXNvbHZlICkKCQkJCQkJCQkJCS5mYWlsKCBuZXdEZWZlci5yZWplY3QgKTsKCQkJCQkJCQl9IGVsc2UgewoJCQkJCQkJCQluZXdEZWZlclsgdHVwbGVbIDAgXSArICJXaXRoIiBdKAoJCQkJCQkJCQkJdGhpcywKCQkJCQkJCQkJCWZuID8gWyByZXR1cm5lZCBdIDogYXJndW1lbnRzCgkJCQkJCQkJCSk7CgkJCQkJCQkJfQoJCQkJCQkJfSApOwoJCQkJCQl9ICk7CgkJCQkJCWZucyA9IG51bGw7CgkJCQkJfSApLnByb21pc2UoKTsKCQkJCX0sCgkJCQl0aGVuOiBmdW5jdGlvbiggb25GdWxmaWxsZWQsIG9uUmVqZWN0ZWQsIG9uUHJvZ3Jlc3MgKSB7CgkJCQkJdmFyIG1heERlcHRoID0gMDsKCQkJCQlmdW5jdGlvbiByZXNvbHZlKCBkZXB0aCwgZGVmZXJyZWQsIGhhbmRsZXIsIHNwZWNpYWwgKSB7CgkJCQkJCXJldHVybiBmdW5jdGlvbigpIHsKCQkJCQkJCXZhciB0aGF0ID0gdGhpcywKCQkJCQkJCQlhcmdzID0gYXJndW1lbnRzLAoJCQkJCQkJCW1pZ2h0VGhyb3cgPSBmdW5jdGlvbigpIHsKCQkJCQkJCQkJdmFyIHJldHVybmVkLCB0aGVuOwoKCQkJCQkJCQkJLy8gU3VwcG9ydDogUHJvbWlzZXMvQSsgc2VjdGlvbiAyLjMuMy4zLjMKCQkJCQkJCQkJLy8gaHR0cHM6Ly9wcm9taXNlc2FwbHVzLmNvbS8jcG9pbnQtNTkKCQkJCQkJCQkJLy8gSWdub3JlIGRvdWJsZS1yZXNvbHV0aW9uIGF0dGVtcHRzCgkJCQkJCQkJCWlmICggZGVwdGggPCBtYXhEZXB0aCApIHsKCQkJCQkJCQkJCXJldHVybjsKCQkJCQkJCQkJfQoKCQkJCQkJCQkJcmV0dXJuZWQgPSBoYW5kbGVyLmFwcGx5KCB0aGF0LCBhcmdzICk7CgoJCQkJCQkJCQkvLyBTdXBwb3J0OiBQcm9taXNlcy9BKyBzZWN0aW9uIDIuMy4xCgkJCQkJCQkJCS8vIGh0dHBzOi8vcHJvbWlzZXNhcGx1cy5jb20vI3BvaW50LTQ4CgkJCQkJCQkJCWlmICggcmV0dXJuZWQgPT09IGRlZmVycmVkLnByb21pc2UoKSApIHsKCQkJCQkJCQkJCXRocm93IG5ldyBUeXBlRXJyb3IoICJUaGVuYWJsZSBzZWxmLXJlc29sdXRpb24iICk7CgkJCQkJCQkJCX0KCgkJCQkJCQkJCS8vIFN1cHBvcnQ6IFByb21pc2VzL0ErIHNlY3Rpb25zIDIuMy4zLjEsIDMuNQoJCQkJCQkJCQkvLyBodHRwczovL3Byb21pc2VzYXBsdXMuY29tLyNwb2ludC01NAoJCQkJCQkJCQkvLyBodHRwczovL3Byb21pc2VzYXBsdXMuY29tLyNwb2ludC03NQoJCQkJCQkJCQkvLyBSZXRyaWV2ZSBgdGhlbmAgb25seSBvbmNlCgkJCQkJCQkJCXRoZW4gPSByZXR1cm5lZCAmJgoKCQkJCQkJCQkJCS8vIFN1cHBvcnQ6IFByb21pc2VzL0ErIHNlY3Rpb24gMi4zLjQKCQkJCQkJCQkJCS8vIGh0dHBzOi8vcHJvbWlzZXNhcGx1cy5jb20vI3BvaW50LTY0CgkJCQkJCQkJCQkvLyBPbmx5IGNoZWNrIG9iamVjdHMgYW5kIGZ1bmN0aW9ucyBmb3IgdGhlbmFiaWxpdHkKCQkJCQkJCQkJCSggdHlwZW9mIHJldHVybmVkID09PSAib2JqZWN0IiB8fAoJCQkJCQkJCQkJCXR5cGVvZiByZXR1cm5lZCA9PT0gImZ1bmN0aW9uIiApICYmCgkJCQkJCQkJCQlyZXR1cm5lZC50aGVuOwoKCQkJCQkJCQkJLy8gSGFuZGxlIGEgcmV0dXJuZWQgdGhlbmFibGUKCQkJCQkJCQkJaWYgKCBpc0Z1bmN0aW9uKCB0aGVuICkgKSB7CgoJCQkJCQkJCQkJLy8gU3BlY2lhbCBwcm9jZXNzb3JzIChub3RpZnkpIGp1c3Qgd2FpdCBmb3IgcmVzb2x1dGlvbgoJCQkJCQkJCQkJaWYgKCBzcGVjaWFsICkgewoJCQkJCQkJCQkJCXRoZW4uY2FsbCgKCQkJCQkJCQkJCQkJcmV0dXJuZWQsCgkJCQkJCQkJCQkJCXJlc29sdmUoIG1heERlcHRoLCBkZWZlcnJlZCwgSWRlbnRpdHksIHNwZWNpYWwgKSwKCQkJCQkJCQkJCQkJcmVzb2x2ZSggbWF4RGVwdGgsIGRlZmVycmVkLCBUaHJvd2VyLCBzcGVjaWFsICkKCQkJCQkJCQkJCQkpOwoKCQkJCQkJCQkJCS8vIE5vcm1hbCBwcm9jZXNzb3JzIChyZXNvbHZlKSBhbHNvIGhvb2sgaW50byBwcm9ncmVzcwoJCQkJCQkJCQkJfSBlbHNlIHsKCgkJCQkJCQkJCQkJLy8gLi4uYW5kIGRpc3JlZ2FyZCBvbGRlciByZXNvbHV0aW9uIHZhbHVlcwoJCQkJCQkJCQkJCW1heERlcHRoKys7CgoJCQkJCQkJCQkJCXRoZW4uY2FsbCgKCQkJCQkJCQkJCQkJcmV0dXJuZWQsCgkJCQkJCQkJCQkJCXJlc29sdmUoIG1heERlcHRoLCBkZWZlcnJlZCwgSWRlbnRpdHksIHNwZWNpYWwgKSwKCQkJCQkJCQkJCQkJcmVzb2x2ZSggbWF4RGVwdGgsIGRlZmVycmVkLCBUaHJvd2VyLCBzcGVjaWFsICksCgkJCQkJCQkJCQkJCXJlc29sdmUoIG1heERlcHRoLCBkZWZlcnJlZCwgSWRlbnRpdHksCgkJCQkJCQkJCQkJCQlkZWZlcnJlZC5ub3RpZnlXaXRoICkKCQkJCQkJCQkJCQkpOwoJCQkJCQkJCQkJfQoKCQkJCQkJCQkJLy8gSGFuZGxlIGFsbCBvdGhlciByZXR1cm5lZCB2YWx1ZXMKCQkJCQkJCQkJfSBlbHNlIHsKCgkJCQkJCQkJCQkvLyBPbmx5IHN1YnN0aXR1dGUgaGFuZGxlcnMgcGFzcyBvbiBjb250ZXh0CgkJCQkJCQkJCQkvLyBhbmQgbXVsdGlwbGUgdmFsdWVzIChub24tc3BlYyBiZWhhdmlvcikKCQkJCQkJCQkJCWlmICggaGFuZGxlciAhPT0gSWRlbnRpdHkgKSB7CgkJCQkJCQkJCQkJdGhhdCA9IHVuZGVmaW5lZDsKCQkJCQkJCQkJCQlhcmdzID0gWyByZXR1cm5lZCBdOwoJCQkJCQkJCQkJfQoKCQkJCQkJCQkJCS8vIFByb2Nlc3MgdGhlIHZhbHVlKHMpCgkJCQkJCQkJCQkvLyBEZWZhdWx0IHByb2Nlc3MgaXMgcmVzb2x2ZQoJCQkJCQkJCQkJKCBzcGVjaWFsIHx8IGRlZmVycmVkLnJlc29sdmVXaXRoICkoIHRoYXQsIGFyZ3MgKTsKCQkJCQkJCQkJfQoJCQkJCQkJCX0sCgoJCQkJCQkJCS8vIE9ubHkgbm9ybWFsIHByb2Nlc3NvcnMgKHJlc29sdmUpIGNhdGNoIGFuZCByZWplY3QgZXhjZXB0aW9ucwoJCQkJCQkJCXByb2Nlc3MgPSBzcGVjaWFsID8KCQkJCQkJCQkJbWlnaHRUaHJvdyA6CgkJCQkJCQkJCWZ1bmN0aW9uKCkgewoJCQkJCQkJCQkJdHJ5IHsKCQkJCQkJCQkJCQltaWdodFRocm93KCk7CgkJCQkJCQkJCQl9IGNhdGNoICggZSApIHsKCgkJCQkJCQkJCQkJaWYgKCBqUXVlcnkuRGVmZXJyZWQuZXhjZXB0aW9uSG9vayApIHsKCQkJCQkJCQkJCQkJalF1ZXJ5LkRlZmVycmVkLmV4Y2VwdGlvbkhvb2soIGUsCgkJCQkJCQkJCQkJCQlwcm9jZXNzLnN0YWNrVHJhY2UgKTsKCQkJCQkJCQkJCQl9CgoJCQkJCQkJCQkJCS8vIFN1cHBvcnQ6IFByb21pc2VzL0ErIHNlY3Rpb24gMi4zLjMuMy40LjEKCQkJCQkJCQkJCQkvLyBodHRwczovL3Byb21pc2VzYXBsdXMuY29tLyNwb2ludC02MQoJCQkJCQkJCQkJCS8vIElnbm9yZSBwb3N0LXJlc29sdXRpb24gZXhjZXB0aW9ucwoJCQkJCQkJCQkJCWlmICggZGVwdGggKyAxID49IG1heERlcHRoICkgewoKCQkJCQkJCQkJCQkJLy8gT25seSBzdWJzdGl0dXRlIGhhbmRsZXJzIHBhc3Mgb24gY29udGV4dAoJCQkJCQkJCQkJCQkvLyBhbmQgbXVsdGlwbGUgdmFsdWVzIChub24tc3BlYyBiZWhhdmlvcikKCQkJCQkJCQkJCQkJaWYgKCBoYW5kbGVyICE9PSBUaHJvd2VyICkgewoJCQkJCQkJCQkJCQkJdGhhdCA9IHVuZGVmaW5lZDsKCQkJCQkJCQkJCQkJCWFyZ3MgPSBbIGUgXTsKCQkJCQkJCQkJCQkJfQoKCQkJCQkJCQkJCQkJZGVmZXJyZWQucmVqZWN0V2l0aCggdGhhdCwgYXJncyApOwoJCQkJCQkJCQkJCX0KCQkJCQkJCQkJCX0KCQkJCQkJCQkJfTsKCgkJCQkJCQkvLyBTdXBwb3J0OiBQcm9taXNlcy9BKyBzZWN0aW9uIDIuMy4zLjMuMQoJCQkJCQkJLy8gaHR0cHM6Ly9wcm9taXNlc2FwbHVzLmNvbS8jcG9pbnQtNTcKCQkJCQkJCS8vIFJlLXJlc29sdmUgcHJvbWlzZXMgaW1tZWRpYXRlbHkgdG8gZG9kZ2UgZmFsc2UgcmVqZWN0aW9uIGZyb20KCQkJCQkJCS8vIHN1YnNlcXVlbnQgZXJyb3JzCgkJCQkJCQlpZiAoIGRlcHRoICkgewoJCQkJCQkJCXByb2Nlc3MoKTsKCQkJCQkJCX0gZWxzZSB7CgoJCQkJCQkJCS8vIENhbGwgYW4gb3B0aW9uYWwgaG9vayB0byByZWNvcmQgdGhlIHN0YWNrLCBpbiBjYXNlIG9mIGV4Y2VwdGlvbgoJCQkJCQkJCS8vIHNpbmNlIGl0J3Mgb3RoZXJ3aXNlIGxvc3Qgd2hlbiBleGVjdXRpb24gZ29lcyBhc3luYwoJCQkJCQkJCWlmICggalF1ZXJ5LkRlZmVycmVkLmdldFN0YWNrSG9vayApIHsKCQkJCQkJCQkJcHJvY2Vzcy5zdGFja1RyYWNlID0galF1ZXJ5LkRlZmVycmVkLmdldFN0YWNrSG9vaygpOwoJCQkJCQkJCX0KCQkJCQkJCQl3aW5kb3cuc2V0VGltZW91dCggcHJvY2VzcyApOwoJCQkJCQkJfQoJCQkJCQl9OwoJCQkJCX0KCgkJCQkJcmV0dXJuIGpRdWVyeS5EZWZlcnJlZCggZnVuY3Rpb24oIG5ld0RlZmVyICkgewoKCQkJCQkJLy8gcHJvZ3Jlc3NfaGFuZGxlcnMuYWRkKCAuLi4gKQoJCQkJCQl0dXBsZXNbIDAgXVsgMyBdLmFkZCgKCQkJCQkJCXJlc29sdmUoCgkJCQkJCQkJMCwKCQkJCQkJCQluZXdEZWZlciwKCQkJCQkJCQlpc0Z1bmN0aW9uKCBvblByb2dyZXNzICkgPwoJCQkJCQkJCQlvblByb2dyZXNzIDoKCQkJCQkJCQkJSWRlbnRpdHksCgkJCQkJCQkJbmV3RGVmZXIubm90aWZ5V2l0aAoJCQkJCQkJKQoJCQkJCQkpOwoKCQkJCQkJLy8gZnVsZmlsbGVkX2hhbmRsZXJzLmFkZCggLi4uICkKCQkJCQkJdHVwbGVzWyAxIF1bIDMgXS5hZGQoCgkJCQkJCQlyZXNvbHZlKAoJCQkJCQkJCTAsCgkJCQkJCQkJbmV3RGVmZXIsCgkJCQkJCQkJaXNGdW5jdGlvbiggb25GdWxmaWxsZWQgKSA/CgkJCQkJCQkJCW9uRnVsZmlsbGVkIDoKCQkJCQkJCQkJSWRlbnRpdHkKCQkJCQkJCSkKCQkJCQkJKTsKCgkJCQkJCS8vIHJlamVjdGVkX2hhbmRsZXJzLmFkZCggLi4uICkKCQkJCQkJdHVwbGVzWyAyIF1bIDMgXS5hZGQoCgkJCQkJCQlyZXNvbHZlKAoJCQkJCQkJCTAsCgkJCQkJCQkJbmV3RGVmZXIsCgkJCQkJCQkJaXNGdW5jdGlvbiggb25SZWplY3RlZCApID8KCQkJCQkJCQkJb25SZWplY3RlZCA6CgkJCQkJCQkJCVRocm93ZXIKCQkJCQkJCSkKCQkJCQkJKTsKCQkJCQl9ICkucHJvbWlzZSgpOwoJCQkJfSwKCgkJCQkvLyBHZXQgYSBwcm9taXNlIGZvciB0aGlzIGRlZmVycmVkCgkJCQkvLyBJZiBvYmogaXMgcHJvdmlkZWQsIHRoZSBwcm9taXNlIGFzcGVjdCBpcyBhZGRlZCB0byB0aGUgb2JqZWN0CgkJCQlwcm9taXNlOiBmdW5jdGlvbiggb2JqICkgewoJCQkJCXJldHVybiBvYmogIT0gbnVsbCA/IGpRdWVyeS5leHRlbmQoIG9iaiwgcHJvbWlzZSApIDogcHJvbWlzZTsKCQkJCX0KCQkJfSwKCQkJZGVmZXJyZWQgPSB7fTsKCgkJLy8gQWRkIGxpc3Qtc3BlY2lmaWMgbWV0aG9kcwoJCWpRdWVyeS5lYWNoKCB0dXBsZXMsIGZ1bmN0aW9uKCBpLCB0dXBsZSApIHsKCQkJdmFyIGxpc3QgPSB0dXBsZVsgMiBdLAoJCQkJc3RhdGVTdHJpbmcgPSB0dXBsZVsgNSBdOwoKCQkJLy8gcHJvbWlzZS5wcm9ncmVzcyA9IGxpc3QuYWRkCgkJCS8vIHByb21pc2UuZG9uZSA9IGxpc3QuYWRkCgkJCS8vIHByb21pc2UuZmFpbCA9IGxpc3QuYWRkCgkJCXByb21pc2VbIHR1cGxlWyAxIF0gXSA9IGxpc3QuYWRkOwoKCQkJLy8gSGFuZGxlIHN0YXRlCgkJCWlmICggc3RhdGVTdHJpbmcgKSB7CgkJCQlsaXN0LmFkZCgKCQkJCQlmdW5jdGlvbigpIHsKCgkJCQkJCS8vIHN0YXRlID0gInJlc29sdmVkIiAoaS5lLiwgZnVsZmlsbGVkKQoJCQkJCQkvLyBzdGF0ZSA9ICJyZWplY3RlZCIKCQkJCQkJc3RhdGUgPSBzdGF0ZVN0cmluZzsKCQkJCQl9LAoKCQkJCQkvLyByZWplY3RlZF9jYWxsYmFja3MuZGlzYWJsZQoJCQkJCS8vIGZ1bGZpbGxlZF9jYWxsYmFja3MuZGlzYWJsZQoJCQkJCXR1cGxlc1sgMyAtIGkgXVsgMiBdLmRpc2FibGUsCgoJCQkJCS8vIHJlamVjdGVkX2hhbmRsZXJzLmRpc2FibGUKCQkJCQkvLyBmdWxmaWxsZWRfaGFuZGxlcnMuZGlzYWJsZQoJCQkJCXR1cGxlc1sgMyAtIGkgXVsgMyBdLmRpc2FibGUsCgoJCQkJCS8vIHByb2dyZXNzX2NhbGxiYWNrcy5sb2NrCgkJCQkJdHVwbGVzWyAwIF1bIDIgXS5sb2NrLAoKCQkJCQkvLyBwcm9ncmVzc19oYW5kbGVycy5sb2NrCgkJCQkJdHVwbGVzWyAwIF1bIDMgXS5sb2NrCgkJCQkpOwoJCQl9CgoJCQkvLyBwcm9ncmVzc19oYW5kbGVycy5maXJlCgkJCS8vIGZ1bGZpbGxlZF9oYW5kbGVycy5maXJlCgkJCS8vIHJlamVjdGVkX2hhbmRsZXJzLmZpcmUKCQkJbGlzdC5hZGQoIHR1cGxlWyAzIF0uZmlyZSApOwoKCQkJLy8gZGVmZXJyZWQubm90aWZ5ID0gZnVuY3Rpb24oKSB7IGRlZmVycmVkLm5vdGlmeVdpdGgoLi4uKSB9CgkJCS8vIGRlZmVycmVkLnJlc29sdmUgPSBmdW5jdGlvbigpIHsgZGVmZXJyZWQucmVzb2x2ZVdpdGgoLi4uKSB9CgkJCS8vIGRlZmVycmVkLnJlamVjdCA9IGZ1bmN0aW9uKCkgeyBkZWZlcnJlZC5yZWplY3RXaXRoKC4uLikgfQoJCQlkZWZlcnJlZFsgdHVwbGVbIDAgXSBdID0gZnVuY3Rpb24oKSB7CgkJCQlkZWZlcnJlZFsgdHVwbGVbIDAgXSArICJXaXRoIiBdKCB0aGlzID09PSBkZWZlcnJlZCA/IHVuZGVmaW5lZCA6IHRoaXMsIGFyZ3VtZW50cyApOwoJCQkJcmV0dXJuIHRoaXM7CgkJCX07CgoJCQkvLyBkZWZlcnJlZC5ub3RpZnlXaXRoID0gbGlzdC5maXJlV2l0aAoJCQkvLyBkZWZlcnJlZC5yZXNvbHZlV2l0aCA9IGxpc3QuZmlyZVdpdGgKCQkJLy8gZGVmZXJyZWQucmVqZWN0V2l0aCA9IGxpc3QuZmlyZVdpdGgKCQkJZGVmZXJyZWRbIHR1cGxlWyAwIF0gKyAiV2l0aCIgXSA9IGxpc3QuZmlyZVdpdGg7CgkJfSApOwoKCQkvLyBNYWtlIHRoZSBkZWZlcnJlZCBhIHByb21pc2UKCQlwcm9taXNlLnByb21pc2UoIGRlZmVycmVkICk7CgoJCS8vIENhbGwgZ2l2ZW4gZnVuYyBpZiBhbnkKCQlpZiAoIGZ1bmMgKSB7CgkJCWZ1bmMuY2FsbCggZGVmZXJyZWQsIGRlZmVycmVkICk7CgkJfQoKCQkvLyBBbGwgZG9uZSEKCQlyZXR1cm4gZGVmZXJyZWQ7Cgl9LAoKCS8vIERlZmVycmVkIGhlbHBlcgoJd2hlbjogZnVuY3Rpb24oIHNpbmdsZVZhbHVlICkgewoJCXZhcgoKCQkJLy8gY291bnQgb2YgdW5jb21wbGV0ZWQgc3Vib3JkaW5hdGVzCgkJCXJlbWFpbmluZyA9IGFyZ3VtZW50cy5sZW5ndGgsCgoJCQkvLyBjb3VudCBvZiB1bnByb2Nlc3NlZCBhcmd1bWVudHMKCQkJaSA9IHJlbWFpbmluZywKCgkJCS8vIHN1Ym9yZGluYXRlIGZ1bGZpbGxtZW50IGRhdGEKCQkJcmVzb2x2ZUNvbnRleHRzID0gQXJyYXkoIGkgKSwKCQkJcmVzb2x2ZVZhbHVlcyA9IHNsaWNlLmNhbGwoIGFyZ3VtZW50cyApLAoKCQkJLy8gdGhlIG1hc3RlciBEZWZlcnJlZAoJCQltYXN0ZXIgPSBqUXVlcnkuRGVmZXJyZWQoKSwKCgkJCS8vIHN1Ym9yZGluYXRlIGNhbGxiYWNrIGZhY3RvcnkKCQkJdXBkYXRlRnVuYyA9IGZ1bmN0aW9uKCBpICkgewoJCQkJcmV0dXJuIGZ1bmN0aW9uKCB2YWx1ZSApIHsKCQkJCQlyZXNvbHZlQ29udGV4dHNbIGkgXSA9IHRoaXM7CgkJCQkJcmVzb2x2ZVZhbHVlc1sgaSBdID0gYXJndW1lbnRzLmxlbmd0aCA+IDEgPyBzbGljZS5jYWxsKCBhcmd1bWVudHMgKSA6IHZhbHVlOwoJCQkJCWlmICggISggLS1yZW1haW5pbmcgKSApIHsKCQkJCQkJbWFzdGVyLnJlc29sdmVXaXRoKCByZXNvbHZlQ29udGV4dHMsIHJlc29sdmVWYWx1ZXMgKTsKCQkJCQl9CgkJCQl9OwoJCQl9OwoKCQkvLyBTaW5nbGUtIGFuZCBlbXB0eSBhcmd1bWVudHMgYXJlIGFkb3B0ZWQgbGlrZSBQcm9taXNlLnJlc29sdmUKCQlpZiAoIHJlbWFpbmluZyA8PSAxICkgewoJCQlhZG9wdFZhbHVlKCBzaW5nbGVWYWx1ZSwgbWFzdGVyLmRvbmUoIHVwZGF0ZUZ1bmMoIGkgKSApLnJlc29sdmUsIG1hc3Rlci5yZWplY3QsCgkJCQkhcmVtYWluaW5nICk7CgoJCQkvLyBVc2UgLnRoZW4oKSB0byB1bndyYXAgc2Vjb25kYXJ5IHRoZW5hYmxlcyAoY2YuIGdoLTMwMDApCgkJCWlmICggbWFzdGVyLnN0YXRlKCkgPT09ICJwZW5kaW5nIiB8fAoJCQkJaXNGdW5jdGlvbiggcmVzb2x2ZVZhbHVlc1sgaSBdICYmIHJlc29sdmVWYWx1ZXNbIGkgXS50aGVuICkgKSB7CgoJCQkJcmV0dXJuIG1hc3Rlci50aGVuKCk7CgkJCX0KCQl9CgoJCS8vIE11bHRpcGxlIGFyZ3VtZW50cyBhcmUgYWdncmVnYXRlZCBsaWtlIFByb21pc2UuYWxsIGFycmF5IGVsZW1lbnRzCgkJd2hpbGUgKCBpLS0gKSB7CgkJCWFkb3B0VmFsdWUoIHJlc29sdmVWYWx1ZXNbIGkgXSwgdXBkYXRlRnVuYyggaSApLCBtYXN0ZXIucmVqZWN0ICk7CgkJfQoKCQlyZXR1cm4gbWFzdGVyLnByb21pc2UoKTsKCX0KfSApOwoKCi8vIFRoZXNlIHVzdWFsbHkgaW5kaWNhdGUgYSBwcm9ncmFtbWVyIG1pc3Rha2UgZHVyaW5nIGRldmVsb3BtZW50LAovLyB3YXJuIGFib3V0IHRoZW0gQVNBUCByYXRoZXIgdGhhbiBzd2FsbG93aW5nIHRoZW0gYnkgZGVmYXVsdC4KdmFyIHJlcnJvck5hbWVzID0gL14oRXZhbHxJbnRlcm5hbHxSYW5nZXxSZWZlcmVuY2V8U3ludGF4fFR5cGV8VVJJKUVycm9yJC87CgpqUXVlcnkuRGVmZXJyZWQuZXhjZXB0aW9uSG9vayA9IGZ1bmN0aW9uKCBlcnJvciwgc3RhY2sgKSB7CgoJLy8gU3VwcG9ydDogSUUgOCAtIDkgb25seQoJLy8gQ29uc29sZSBleGlzdHMgd2hlbiBkZXYgdG9vbHMgYXJlIG9wZW4sIHdoaWNoIGNhbiBoYXBwZW4gYXQgYW55IHRpbWUKCWlmICggd2luZG93LmNvbnNvbGUgJiYgd2luZG93LmNvbnNvbGUud2FybiAmJiBlcnJvciAmJiByZXJyb3JOYW1lcy50ZXN0KCBlcnJvci5uYW1lICkgKSB7CgkJd2luZG93LmNvbnNvbGUud2FybiggImpRdWVyeS5EZWZlcnJlZCBleGNlcHRpb246ICIgKyBlcnJvci5tZXNzYWdlLCBlcnJvci5zdGFjaywgc3RhY2sgKTsKCX0KfTsKCgoKCmpRdWVyeS5yZWFkeUV4Y2VwdGlvbiA9IGZ1bmN0aW9uKCBlcnJvciApIHsKCXdpbmRvdy5zZXRUaW1lb3V0KCBmdW5jdGlvbigpIHsKCQl0aHJvdyBlcnJvcjsKCX0gKTsKfTsKCgoKCi8vIFRoZSBkZWZlcnJlZCB1c2VkIG9uIERPTSByZWFkeQp2YXIgcmVhZHlMaXN0ID0galF1ZXJ5LkRlZmVycmVkKCk7CgpqUXVlcnkuZm4ucmVhZHkgPSBmdW5jdGlvbiggZm4gKSB7CgoJcmVhZHlMaXN0CgkJLnRoZW4oIGZuICkKCgkJLy8gV3JhcCBqUXVlcnkucmVhZHlFeGNlcHRpb24gaW4gYSBmdW5jdGlvbiBzbyB0aGF0IHRoZSBsb29rdXAKCQkvLyBoYXBwZW5zIGF0IHRoZSB0aW1lIG9mIGVycm9yIGhhbmRsaW5nIGluc3RlYWQgb2YgY2FsbGJhY2sKCQkvLyByZWdpc3RyYXRpb24uCgkJLmNhdGNoKCBmdW5jdGlvbiggZXJyb3IgKSB7CgkJCWpRdWVyeS5yZWFkeUV4Y2VwdGlvbiggZXJyb3IgKTsKCQl9ICk7CgoJcmV0dXJuIHRoaXM7Cn07CgpqUXVlcnkuZXh0ZW5kKCB7CgoJLy8gSXMgdGhlIERPTSByZWFkeSB0byBiZSB1c2VkPyBTZXQgdG8gdHJ1ZSBvbmNlIGl0IG9jY3Vycy4KCWlzUmVhZHk6IGZhbHNlLAoKCS8vIEEgY291bnRlciB0byB0cmFjayBob3cgbWFueSBpdGVtcyB0byB3YWl0IGZvciBiZWZvcmUKCS8vIHRoZSByZWFkeSBldmVudCBmaXJlcy4gU2VlICM2NzgxCglyZWFkeVdhaXQ6IDEsCgoJLy8gSGFuZGxlIHdoZW4gdGhlIERPTSBpcyByZWFkeQoJcmVhZHk6IGZ1bmN0aW9uKCB3YWl0ICkgewoKCQkvLyBBYm9ydCBpZiB0aGVyZSBhcmUgcGVuZGluZyBob2xkcyBvciB3ZSdyZSBhbHJlYWR5IHJlYWR5CgkJaWYgKCB3YWl0ID09PSB0cnVlID8gLS1qUXVlcnkucmVhZHlXYWl0IDogalF1ZXJ5LmlzUmVhZHkgKSB7CgkJCXJldHVybjsKCQl9CgoJCS8vIFJlbWVtYmVyIHRoYXQgdGhlIERPTSBpcyByZWFkeQoJCWpRdWVyeS5pc1JlYWR5ID0gdHJ1ZTsKCgkJLy8gSWYgYSBub3JtYWwgRE9NIFJlYWR5IGV2ZW50IGZpcmVkLCBkZWNyZW1lbnQsIGFuZCB3YWl0IGlmIG5lZWQgYmUKCQlpZiAoIHdhaXQgIT09IHRydWUgJiYgLS1qUXVlcnkucmVhZHlXYWl0ID4gMCApIHsKCQkJcmV0dXJuOwoJCX0KCgkJLy8gSWYgdGhlcmUgYXJlIGZ1bmN0aW9ucyBib3VuZCwgdG8gZXhlY3V0ZQoJCXJlYWR5TGlzdC5yZXNvbHZlV2l0aCggZG9jdW1lbnQsIFsgalF1ZXJ5IF0gKTsKCX0KfSApOwoKalF1ZXJ5LnJlYWR5LnRoZW4gPSByZWFkeUxpc3QudGhlbjsKCi8vIFRoZSByZWFkeSBldmVudCBoYW5kbGVyIGFuZCBzZWxmIGNsZWFudXAgbWV0aG9kCmZ1bmN0aW9uIGNvbXBsZXRlZCgpIHsKCWRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoICJET01Db250ZW50TG9hZGVkIiwgY29tcGxldGVkICk7Cgl3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lciggImxvYWQiLCBjb21wbGV0ZWQgKTsKCWpRdWVyeS5yZWFkeSgpOwp9CgovLyBDYXRjaCBjYXNlcyB3aGVyZSAkKGRvY3VtZW50KS5yZWFkeSgpIGlzIGNhbGxlZAovLyBhZnRlciB0aGUgYnJvd3NlciBldmVudCBoYXMgYWxyZWFkeSBvY2N1cnJlZC4KLy8gU3VwcG9ydDogSUUgPD05IC0gMTAgb25seQovLyBPbGRlciBJRSBzb21ldGltZXMgc2lnbmFscyAiaW50ZXJhY3RpdmUiIHRvbyBzb29uCmlmICggZG9jdW1lbnQucmVhZHlTdGF0ZSA9PT0gImNvbXBsZXRlIiB8fAoJKCBkb2N1bWVudC5yZWFkeVN0YXRlICE9PSAibG9hZGluZyIgJiYgIWRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5kb1Njcm9sbCApICkgewoKCS8vIEhhbmRsZSBpdCBhc3luY2hyb25vdXNseSB0byBhbGxvdyBzY3JpcHRzIHRoZSBvcHBvcnR1bml0eSB0byBkZWxheSByZWFkeQoJd2luZG93LnNldFRpbWVvdXQoIGpRdWVyeS5yZWFkeSApOwoKfSBlbHNlIHsKCgkvLyBVc2UgdGhlIGhhbmR5IGV2ZW50IGNhbGxiYWNrCglkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCAiRE9NQ29udGVudExvYWRlZCIsIGNvbXBsZXRlZCApOwoKCS8vIEEgZmFsbGJhY2sgdG8gd2luZG93Lm9ubG9hZCwgdGhhdCB3aWxsIGFsd2F5cyB3b3JrCgl3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lciggImxvYWQiLCBjb21wbGV0ZWQgKTsKfQoKCgoKLy8gTXVsdGlmdW5jdGlvbmFsIG1ldGhvZCB0byBnZXQgYW5kIHNldCB2YWx1ZXMgb2YgYSBjb2xsZWN0aW9uCi8vIFRoZSB2YWx1ZS9zIGNhbiBvcHRpb25hbGx5IGJlIGV4ZWN1dGVkIGlmIGl0J3MgYSBmdW5jdGlvbgp2YXIgYWNjZXNzID0gZnVuY3Rpb24oIGVsZW1zLCBmbiwga2V5LCB2YWx1ZSwgY2hhaW5hYmxlLCBlbXB0eUdldCwgcmF3ICkgewoJdmFyIGkgPSAwLAoJCWxlbiA9IGVsZW1zLmxlbmd0aCwKCQlidWxrID0ga2V5ID09IG51bGw7CgoJLy8gU2V0cyBtYW55IHZhbHVlcwoJaWYgKCB0b1R5cGUoIGtleSApID09PSAib2JqZWN0IiApIHsKCQljaGFpbmFibGUgPSB0cnVlOwoJCWZvciAoIGkgaW4ga2V5ICkgewoJCQlhY2Nlc3MoIGVsZW1zLCBmbiwgaSwga2V5WyBpIF0sIHRydWUsIGVtcHR5R2V0LCByYXcgKTsKCQl9CgoJLy8gU2V0cyBvbmUgdmFsdWUKCX0gZWxzZSBpZiAoIHZhbHVlICE9PSB1bmRlZmluZWQgKSB7CgkJY2hhaW5hYmxlID0gdHJ1ZTsKCgkJaWYgKCAhaXNGdW5jdGlvbiggdmFsdWUgKSApIHsKCQkJcmF3ID0gdHJ1ZTsKCQl9CgoJCWlmICggYnVsayApIHsKCgkJCS8vIEJ1bGsgb3BlcmF0aW9ucyBydW4gYWdhaW5zdCB0aGUgZW50aXJlIHNldAoJCQlpZiAoIHJhdyApIHsKCQkJCWZuLmNhbGwoIGVsZW1zLCB2YWx1ZSApOwoJCQkJZm4gPSBudWxsOwoKCQkJLy8gLi4uZXhjZXB0IHdoZW4gZXhlY3V0aW5nIGZ1bmN0aW9uIHZhbHVlcwoJCQl9IGVsc2UgewoJCQkJYnVsayA9IGZuOwoJCQkJZm4gPSBmdW5jdGlvbiggZWxlbSwga2V5LCB2YWx1ZSApIHsKCQkJCQlyZXR1cm4gYnVsay5jYWxsKCBqUXVlcnkoIGVsZW0gKSwgdmFsdWUgKTsKCQkJCX07CgkJCX0KCQl9CgoJCWlmICggZm4gKSB7CgkJCWZvciAoIDsgaSA8IGxlbjsgaSsrICkgewoJCQkJZm4oCgkJCQkJZWxlbXNbIGkgXSwga2V5LCByYXcgPwoJCQkJCXZhbHVlIDoKCQkJCQl2YWx1ZS5jYWxsKCBlbGVtc1sgaSBdLCBpLCBmbiggZWxlbXNbIGkgXSwga2V5ICkgKQoJCQkJKTsKCQkJfQoJCX0KCX0KCglpZiAoIGNoYWluYWJsZSApIHsKCQlyZXR1cm4gZWxlbXM7Cgl9CgoJLy8gR2V0cwoJaWYgKCBidWxrICkgewoJCXJldHVybiBmbi5jYWxsKCBlbGVtcyApOwoJfQoKCXJldHVybiBsZW4gPyBmbiggZWxlbXNbIDAgXSwga2V5ICkgOiBlbXB0eUdldDsKfTsKCgovLyBNYXRjaGVzIGRhc2hlZCBzdHJpbmcgZm9yIGNhbWVsaXppbmcKdmFyIHJtc1ByZWZpeCA9IC9eLW1zLS8sCglyZGFzaEFscGhhID0gLy0oW2Etel0pL2c7CgovLyBVc2VkIGJ5IGNhbWVsQ2FzZSBhcyBjYWxsYmFjayB0byByZXBsYWNlKCkKZnVuY3Rpb24gZmNhbWVsQ2FzZSggYWxsLCBsZXR0ZXIgKSB7CglyZXR1cm4gbGV0dGVyLnRvVXBwZXJDYXNlKCk7Cn0KCi8vIENvbnZlcnQgZGFzaGVkIHRvIGNhbWVsQ2FzZTsgdXNlZCBieSB0aGUgY3NzIGFuZCBkYXRhIG1vZHVsZXMKLy8gU3VwcG9ydDogSUUgPD05IC0gMTEsIEVkZ2UgMTIgLSAxNQovLyBNaWNyb3NvZnQgZm9yZ290IHRvIGh1bXAgdGhlaXIgdmVuZG9yIHByZWZpeCAoIzk1NzIpCmZ1bmN0aW9uIGNhbWVsQ2FzZSggc3RyaW5nICkgewoJcmV0dXJuIHN0cmluZy5yZXBsYWNlKCBybXNQcmVmaXgsICJtcy0iICkucmVwbGFjZSggcmRhc2hBbHBoYSwgZmNhbWVsQ2FzZSApOwp9CnZhciBhY2NlcHREYXRhID0gZnVuY3Rpb24oIG93bmVyICkgewoKCS8vIEFjY2VwdHMgb25seToKCS8vICAtIE5vZGUKCS8vICAgIC0gTm9kZS5FTEVNRU5UX05PREUKCS8vICAgIC0gTm9kZS5ET0NVTUVOVF9OT0RFCgkvLyAgLSBPYmplY3QKCS8vICAgIC0gQW55CglyZXR1cm4gb3duZXIubm9kZVR5cGUgPT09IDEgfHwgb3duZXIubm9kZVR5cGUgPT09IDkgfHwgISggK293bmVyLm5vZGVUeXBlICk7Cn07CgoKCgpmdW5jdGlvbiBEYXRhKCkgewoJdGhpcy5leHBhbmRvID0galF1ZXJ5LmV4cGFuZG8gKyBEYXRhLnVpZCsrOwp9CgpEYXRhLnVpZCA9IDE7CgpEYXRhLnByb3RvdHlwZSA9IHsKCgljYWNoZTogZnVuY3Rpb24oIG93bmVyICkgewoKCQkvLyBDaGVjayBpZiB0aGUgb3duZXIgb2JqZWN0IGFscmVhZHkgaGFzIGEgY2FjaGUKCQl2YXIgdmFsdWUgPSBvd25lclsgdGhpcy5leHBhbmRvIF07CgoJCS8vIElmIG5vdCwgY3JlYXRlIG9uZQoJCWlmICggIXZhbHVlICkgewoJCQl2YWx1ZSA9IHt9OwoKCQkJLy8gV2UgY2FuIGFjY2VwdCBkYXRhIGZvciBub24tZWxlbWVudCBub2RlcyBpbiBtb2Rlcm4gYnJvd3NlcnMsCgkJCS8vIGJ1dCB3ZSBzaG91bGQgbm90LCBzZWUgIzgzMzUuCgkJCS8vIEFsd2F5cyByZXR1cm4gYW4gZW1wdHkgb2JqZWN0LgoJCQlpZiAoIGFjY2VwdERhdGEoIG93bmVyICkgKSB7CgoJCQkJLy8gSWYgaXQgaXMgYSBub2RlIHVubGlrZWx5IHRvIGJlIHN0cmluZ2lmeS1lZCBvciBsb29wZWQgb3ZlcgoJCQkJLy8gdXNlIHBsYWluIGFzc2lnbm1lbnQKCQkJCWlmICggb3duZXIubm9kZVR5cGUgKSB7CgkJCQkJb3duZXJbIHRoaXMuZXhwYW5kbyBdID0gdmFsdWU7CgoJCQkJLy8gT3RoZXJ3aXNlIHNlY3VyZSBpdCBpbiBhIG5vbi1lbnVtZXJhYmxlIHByb3BlcnR5CgkJCQkvLyBjb25maWd1cmFibGUgbXVzdCBiZSB0cnVlIHRvIGFsbG93IHRoZSBwcm9wZXJ0eSB0byBiZQoJCQkJLy8gZGVsZXRlZCB3aGVuIGRhdGEgaXMgcmVtb3ZlZAoJCQkJfSBlbHNlIHsKCQkJCQlPYmplY3QuZGVmaW5lUHJvcGVydHkoIG93bmVyLCB0aGlzLmV4cGFuZG8sIHsKCQkJCQkJdmFsdWU6IHZhbHVlLAoJCQkJCQljb25maWd1cmFibGU6IHRydWUKCQkJCQl9ICk7CgkJCQl9CgkJCX0KCQl9CgoJCXJldHVybiB2YWx1ZTsKCX0sCglzZXQ6IGZ1bmN0aW9uKCBvd25lciwgZGF0YSwgdmFsdWUgKSB7CgkJdmFyIHByb3AsCgkJCWNhY2hlID0gdGhpcy5jYWNoZSggb3duZXIgKTsKCgkJLy8gSGFuZGxlOiBbIG93bmVyLCBrZXksIHZhbHVlIF0gYXJncwoJCS8vIEFsd2F5cyB1c2UgY2FtZWxDYXNlIGtleSAoZ2gtMjI1NykKCQlpZiAoIHR5cGVvZiBkYXRhID09PSAic3RyaW5nIiApIHsKCQkJY2FjaGVbIGNhbWVsQ2FzZSggZGF0YSApIF0gPSB2YWx1ZTsKCgkJLy8gSGFuZGxlOiBbIG93bmVyLCB7IHByb3BlcnRpZXMgfSBdIGFyZ3MKCQl9IGVsc2UgewoKCQkJLy8gQ29weSB0aGUgcHJvcGVydGllcyBvbmUtYnktb25lIHRvIHRoZSBjYWNoZSBvYmplY3QKCQkJZm9yICggcHJvcCBpbiBkYXRhICkgewoJCQkJY2FjaGVbIGNhbWVsQ2FzZSggcHJvcCApIF0gPSBkYXRhWyBwcm9wIF07CgkJCX0KCQl9CgkJcmV0dXJuIGNhY2hlOwoJfSwKCWdldDogZnVuY3Rpb24oIG93bmVyLCBrZXkgKSB7CgkJcmV0dXJuIGtleSA9PT0gdW5kZWZpbmVkID8KCQkJdGhpcy5jYWNoZSggb3duZXIgKSA6CgoJCQkvLyBBbHdheXMgdXNlIGNhbWVsQ2FzZSBrZXkgKGdoLTIyNTcpCgkJCW93bmVyWyB0aGlzLmV4cGFuZG8gXSAmJiBvd25lclsgdGhpcy5leHBhbmRvIF1bIGNhbWVsQ2FzZSgga2V5ICkgXTsKCX0sCglhY2Nlc3M6IGZ1bmN0aW9uKCBvd25lciwga2V5LCB2YWx1ZSApIHsKCgkJLy8gSW4gY2FzZXMgd2hlcmUgZWl0aGVyOgoJCS8vCgkJLy8gICAxLiBObyBrZXkgd2FzIHNwZWNpZmllZAoJCS8vICAgMi4gQSBzdHJpbmcga2V5IHdhcyBzcGVjaWZpZWQsIGJ1dCBubyB2YWx1ZSBwcm92aWRlZAoJCS8vCgkJLy8gVGFrZSB0aGUgInJlYWQiIHBhdGggYW5kIGFsbG93IHRoZSBnZXQgbWV0aG9kIHRvIGRldGVybWluZQoJCS8vIHdoaWNoIHZhbHVlIHRvIHJldHVybiwgcmVzcGVjdGl2ZWx5IGVpdGhlcjoKCQkvLwoJCS8vICAgMS4gVGhlIGVudGlyZSBjYWNoZSBvYmplY3QKCQkvLyAgIDIuIFRoZSBkYXRhIHN0b3JlZCBhdCB0aGUga2V5CgkJLy8KCQlpZiAoIGtleSA9PT0gdW5kZWZpbmVkIHx8CgkJCQkoICgga2V5ICYmIHR5cGVvZiBrZXkgPT09ICJzdHJpbmciICkgJiYgdmFsdWUgPT09IHVuZGVmaW5lZCApICkgewoKCQkJcmV0dXJuIHRoaXMuZ2V0KCBvd25lciwga2V5ICk7CgkJfQoKCQkvLyBXaGVuIHRoZSBrZXkgaXMgbm90IGEgc3RyaW5nLCBvciBib3RoIGEga2V5IGFuZCB2YWx1ZQoJCS8vIGFyZSBzcGVjaWZpZWQsIHNldCBvciBleHRlbmQgKGV4aXN0aW5nIG9iamVjdHMpIHdpdGggZWl0aGVyOgoJCS8vCgkJLy8gICAxLiBBbiBvYmplY3Qgb2YgcHJvcGVydGllcwoJCS8vICAgMi4gQSBrZXkgYW5kIHZhbHVlCgkJLy8KCQl0aGlzLnNldCggb3duZXIsIGtleSwgdmFsdWUgKTsKCgkJLy8gU2luY2UgdGhlICJzZXQiIHBhdGggY2FuIGhhdmUgdHdvIHBvc3NpYmxlIGVudHJ5IHBvaW50cwoJCS8vIHJldHVybiB0aGUgZXhwZWN0ZWQgZGF0YSBiYXNlZCBvbiB3aGljaCBwYXRoIHdhcyB0YWtlblsqXQoJCXJldHVybiB2YWx1ZSAhPT0gdW5kZWZpbmVkID8gdmFsdWUgOiBrZXk7Cgl9LAoJcmVtb3ZlOiBmdW5jdGlvbiggb3duZXIsIGtleSApIHsKCQl2YXIgaSwKCQkJY2FjaGUgPSBvd25lclsgdGhpcy5leHBhbmRvIF07CgoJCWlmICggY2FjaGUgPT09IHVuZGVmaW5lZCApIHsKCQkJcmV0dXJuOwoJCX0KCgkJaWYgKCBrZXkgIT09IHVuZGVmaW5lZCApIHsKCgkJCS8vIFN1cHBvcnQgYXJyYXkgb3Igc3BhY2Ugc2VwYXJhdGVkIHN0cmluZyBvZiBrZXlzCgkJCWlmICggQXJyYXkuaXNBcnJheSgga2V5ICkgKSB7CgoJCQkJLy8gSWYga2V5IGlzIGFuIGFycmF5IG9mIGtleXMuLi4KCQkJCS8vIFdlIGFsd2F5cyBzZXQgY2FtZWxDYXNlIGtleXMsIHNvIHJlbW92ZSB0aGF0LgoJCQkJa2V5ID0ga2V5Lm1hcCggY2FtZWxDYXNlICk7CgkJCX0gZWxzZSB7CgkJCQlrZXkgPSBjYW1lbENhc2UoIGtleSApOwoKCQkJCS8vIElmIGEga2V5IHdpdGggdGhlIHNwYWNlcyBleGlzdHMsIHVzZSBpdC4KCQkJCS8vIE90aGVyd2lzZSwgY3JlYXRlIGFuIGFycmF5IGJ5IG1hdGNoaW5nIG5vbi13aGl0ZXNwYWNlCgkJCQlrZXkgPSBrZXkgaW4gY2FjaGUgPwoJCQkJCVsga2V5IF0gOgoJCQkJCSgga2V5Lm1hdGNoKCBybm90aHRtbHdoaXRlICkgfHwgW10gKTsKCQkJfQoKCQkJaSA9IGtleS5sZW5ndGg7CgoJCQl3aGlsZSAoIGktLSApIHsKCQkJCWRlbGV0ZSBjYWNoZVsga2V5WyBpIF0gXTsKCQkJfQoJCX0KCgkJLy8gUmVtb3ZlIHRoZSBleHBhbmRvIGlmIHRoZXJlJ3Mgbm8gbW9yZSBkYXRhCgkJaWYgKCBrZXkgPT09IHVuZGVmaW5lZCB8fCBqUXVlcnkuaXNFbXB0eU9iamVjdCggY2FjaGUgKSApIHsKCgkJCS8vIFN1cHBvcnQ6IENocm9tZSA8PTM1IC0gNDUKCQkJLy8gV2Via2l0ICYgQmxpbmsgcGVyZm9ybWFuY2Ugc3VmZmVycyB3aGVuIGRlbGV0aW5nIHByb3BlcnRpZXMKCQkJLy8gZnJvbSBET00gbm9kZXMsIHNvIHNldCB0byB1bmRlZmluZWQgaW5zdGVhZAoJCQkvLyBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvY2hyb21pdW0vaXNzdWVzL2RldGFpbD9pZD0zNzg2MDcgKGJ1ZyByZXN0cmljdGVkKQoJCQlpZiAoIG93bmVyLm5vZGVUeXBlICkgewoJCQkJb3duZXJbIHRoaXMuZXhwYW5kbyBdID0gdW5kZWZpbmVkOwoJCQl9IGVsc2UgewoJCQkJZGVsZXRlIG93bmVyWyB0aGlzLmV4cGFuZG8gXTsKCQkJfQoJCX0KCX0sCgloYXNEYXRhOiBmdW5jdGlvbiggb3duZXIgKSB7CgkJdmFyIGNhY2hlID0gb3duZXJbIHRoaXMuZXhwYW5kbyBdOwoJCXJldHVybiBjYWNoZSAhPT0gdW5kZWZpbmVkICYmICFqUXVlcnkuaXNFbXB0eU9iamVjdCggY2FjaGUgKTsKCX0KfTsKdmFyIGRhdGFQcml2ID0gbmV3IERhdGEoKTsKCnZhciBkYXRhVXNlciA9IG5ldyBEYXRhKCk7CgoKCi8vCUltcGxlbWVudGF0aW9uIFN1bW1hcnkKLy8KLy8JMS4gRW5mb3JjZSBBUEkgc3VyZmFjZSBhbmQgc2VtYW50aWMgY29tcGF0aWJpbGl0eSB3aXRoIDEuOS54IGJyYW5jaAovLwkyLiBJbXByb3ZlIHRoZSBtb2R1bGUncyBtYWludGFpbmFiaWxpdHkgYnkgcmVkdWNpbmcgdGhlIHN0b3JhZ2UKLy8JCXBhdGhzIHRvIGEgc2luZ2xlIG1lY2hhbmlzbS4KLy8JMy4gVXNlIHRoZSBzYW1lIHNpbmdsZSBtZWNoYW5pc20gdG8gc3VwcG9ydCAicHJpdmF0ZSIgYW5kICJ1c2VyIiBkYXRhLgovLwk0LiBfTmV2ZXJfIGV4cG9zZSAicHJpdmF0ZSIgZGF0YSB0byB1c2VyIGNvZGUgKFRPRE86IERyb3AgX2RhdGEsIF9yZW1vdmVEYXRhKQovLwk1LiBBdm9pZCBleHBvc2luZyBpbXBsZW1lbnRhdGlvbiBkZXRhaWxzIG9uIHVzZXIgb2JqZWN0cyAoZWcuIGV4cGFuZG8gcHJvcGVydGllcykKLy8JNi4gUHJvdmlkZSBhIGNsZWFyIHBhdGggZm9yIGltcGxlbWVudGF0aW9uIHVwZ3JhZGUgdG8gV2Vha01hcCBpbiAyMDE0Cgp2YXIgcmJyYWNlID0gL14oPzpce1tcd1xXXSpcfXxcW1tcd1xXXSpcXSkkLywKCXJtdWx0aURhc2ggPSAvW0EtWl0vZzsKCmZ1bmN0aW9uIGdldERhdGEoIGRhdGEgKSB7CglpZiAoIGRhdGEgPT09ICJ0cnVlIiApIHsKCQlyZXR1cm4gdHJ1ZTsKCX0KCglpZiAoIGRhdGEgPT09ICJmYWxzZSIgKSB7CgkJcmV0dXJuIGZhbHNlOwoJfQoKCWlmICggZGF0YSA9PT0gIm51bGwiICkgewoJCXJldHVybiBudWxsOwoJfQoKCS8vIE9ubHkgY29udmVydCB0byBhIG51bWJlciBpZiBpdCBkb2Vzbid0IGNoYW5nZSB0aGUgc3RyaW5nCglpZiAoIGRhdGEgPT09ICtkYXRhICsgIiIgKSB7CgkJcmV0dXJuICtkYXRhOwoJfQoKCWlmICggcmJyYWNlLnRlc3QoIGRhdGEgKSApIHsKCQlyZXR1cm4gSlNPTi5wYXJzZSggZGF0YSApOwoJfQoKCXJldHVybiBkYXRhOwp9CgpmdW5jdGlvbiBkYXRhQXR0ciggZWxlbSwga2V5LCBkYXRhICkgewoJdmFyIG5hbWU7CgoJLy8gSWYgbm90aGluZyB3YXMgZm91bmQgaW50ZXJuYWxseSwgdHJ5IHRvIGZldGNoIGFueQoJLy8gZGF0YSBmcm9tIHRoZSBIVE1MNSBkYXRhLSogYXR0cmlidXRlCglpZiAoIGRhdGEgPT09IHVuZGVmaW5lZCAmJiBlbGVtLm5vZGVUeXBlID09PSAxICkgewoJCW5hbWUgPSAiZGF0YS0iICsga2V5LnJlcGxhY2UoIHJtdWx0aURhc2gsICItJCYiICkudG9Mb3dlckNhc2UoKTsKCQlkYXRhID0gZWxlbS5nZXRBdHRyaWJ1dGUoIG5hbWUgKTsKCgkJaWYgKCB0eXBlb2YgZGF0YSA9PT0gInN0cmluZyIgKSB7CgkJCXRyeSB7CgkJCQlkYXRhID0gZ2V0RGF0YSggZGF0YSApOwoJCQl9IGNhdGNoICggZSApIHt9CgoJCQkvLyBNYWtlIHN1cmUgd2Ugc2V0IHRoZSBkYXRhIHNvIGl0IGlzbid0IGNoYW5nZWQgbGF0ZXIKCQkJZGF0YVVzZXIuc2V0KCBlbGVtLCBrZXksIGRhdGEgKTsKCQl9IGVsc2UgewoJCQlkYXRhID0gdW5kZWZpbmVkOwoJCX0KCX0KCXJldHVybiBkYXRhOwp9CgpqUXVlcnkuZXh0ZW5kKCB7CgloYXNEYXRhOiBmdW5jdGlvbiggZWxlbSApIHsKCQlyZXR1cm4gZGF0YVVzZXIuaGFzRGF0YSggZWxlbSApIHx8IGRhdGFQcml2Lmhhc0RhdGEoIGVsZW0gKTsKCX0sCgoJZGF0YTogZnVuY3Rpb24oIGVsZW0sIG5hbWUsIGRhdGEgKSB7CgkJcmV0dXJuIGRhdGFVc2VyLmFjY2VzcyggZWxlbSwgbmFtZSwgZGF0YSApOwoJfSwKCglyZW1vdmVEYXRhOiBmdW5jdGlvbiggZWxlbSwgbmFtZSApIHsKCQlkYXRhVXNlci5yZW1vdmUoIGVsZW0sIG5hbWUgKTsKCX0sCgoJLy8gVE9ETzogTm93IHRoYXQgYWxsIGNhbGxzIHRvIF9kYXRhIGFuZCBfcmVtb3ZlRGF0YSBoYXZlIGJlZW4gcmVwbGFjZWQKCS8vIHdpdGggZGlyZWN0IGNhbGxzIHRvIGRhdGFQcml2IG1ldGhvZHMsIHRoZXNlIGNhbiBiZSBkZXByZWNhdGVkLgoJX2RhdGE6IGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCBkYXRhICkgewoJCXJldHVybiBkYXRhUHJpdi5hY2Nlc3MoIGVsZW0sIG5hbWUsIGRhdGEgKTsKCX0sCgoJX3JlbW92ZURhdGE6IGZ1bmN0aW9uKCBlbGVtLCBuYW1lICkgewoJCWRhdGFQcml2LnJlbW92ZSggZWxlbSwgbmFtZSApOwoJfQp9ICk7CgpqUXVlcnkuZm4uZXh0ZW5kKCB7CglkYXRhOiBmdW5jdGlvbigga2V5LCB2YWx1ZSApIHsKCQl2YXIgaSwgbmFtZSwgZGF0YSwKCQkJZWxlbSA9IHRoaXNbIDAgXSwKCQkJYXR0cnMgPSBlbGVtICYmIGVsZW0uYXR0cmlidXRlczsKCgkJLy8gR2V0cyBhbGwgdmFsdWVzCgkJaWYgKCBrZXkgPT09IHVuZGVmaW5lZCApIHsKCQkJaWYgKCB0aGlzLmxlbmd0aCApIHsKCQkJCWRhdGEgPSBkYXRhVXNlci5nZXQoIGVsZW0gKTsKCgkJCQlpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDEgJiYgIWRhdGFQcml2LmdldCggZWxlbSwgImhhc0RhdGFBdHRycyIgKSApIHsKCQkJCQlpID0gYXR0cnMubGVuZ3RoOwoJCQkJCXdoaWxlICggaS0tICkgewoKCQkJCQkJLy8gU3VwcG9ydDogSUUgMTEgb25seQoJCQkJCQkvLyBUaGUgYXR0cnMgZWxlbWVudHMgY2FuIGJlIG51bGwgKCMxNDg5NCkKCQkJCQkJaWYgKCBhdHRyc1sgaSBdICkgewoJCQkJCQkJbmFtZSA9IGF0dHJzWyBpIF0ubmFtZTsKCQkJCQkJCWlmICggbmFtZS5pbmRleE9mKCAiZGF0YS0iICkgPT09IDAgKSB7CgkJCQkJCQkJbmFtZSA9IGNhbWVsQ2FzZSggbmFtZS5zbGljZSggNSApICk7CgkJCQkJCQkJZGF0YUF0dHIoIGVsZW0sIG5hbWUsIGRhdGFbIG5hbWUgXSApOwoJCQkJCQkJfQoJCQkJCQl9CgkJCQkJfQoJCQkJCWRhdGFQcml2LnNldCggZWxlbSwgImhhc0RhdGFBdHRycyIsIHRydWUgKTsKCQkJCX0KCQkJfQoKCQkJcmV0dXJuIGRhdGE7CgkJfQoKCQkvLyBTZXRzIG11bHRpcGxlIHZhbHVlcwoJCWlmICggdHlwZW9mIGtleSA9PT0gIm9iamVjdCIgKSB7CgkJCXJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCkgewoJCQkJZGF0YVVzZXIuc2V0KCB0aGlzLCBrZXkgKTsKCQkJfSApOwoJCX0KCgkJcmV0dXJuIGFjY2VzcyggdGhpcywgZnVuY3Rpb24oIHZhbHVlICkgewoJCQl2YXIgZGF0YTsKCgkJCS8vIFRoZSBjYWxsaW5nIGpRdWVyeSBvYmplY3QgKGVsZW1lbnQgbWF0Y2hlcykgaXMgbm90IGVtcHR5CgkJCS8vIChhbmQgdGhlcmVmb3JlIGhhcyBhbiBlbGVtZW50IGFwcGVhcnMgYXQgdGhpc1sgMCBdKSBhbmQgdGhlCgkJCS8vIGB2YWx1ZWAgcGFyYW1ldGVyIHdhcyBub3QgdW5kZWZpbmVkLiBBbiBlbXB0eSBqUXVlcnkgb2JqZWN0CgkJCS8vIHdpbGwgcmVzdWx0IGluIGB1bmRlZmluZWRgIGZvciBlbGVtID0gdGhpc1sgMCBdIHdoaWNoIHdpbGwKCQkJLy8gdGhyb3cgYW4gZXhjZXB0aW9uIGlmIGFuIGF0dGVtcHQgdG8gcmVhZCBhIGRhdGEgY2FjaGUgaXMgbWFkZS4KCQkJaWYgKCBlbGVtICYmIHZhbHVlID09PSB1bmRlZmluZWQgKSB7CgoJCQkJLy8gQXR0ZW1wdCB0byBnZXQgZGF0YSBmcm9tIHRoZSBjYWNoZQoJCQkJLy8gVGhlIGtleSB3aWxsIGFsd2F5cyBiZSBjYW1lbENhc2VkIGluIERhdGEKCQkJCWRhdGEgPSBkYXRhVXNlci5nZXQoIGVsZW0sIGtleSApOwoJCQkJaWYgKCBkYXRhICE9PSB1bmRlZmluZWQgKSB7CgkJCQkJcmV0dXJuIGRhdGE7CgkJCQl9CgoJCQkJLy8gQXR0ZW1wdCB0byAiZGlzY292ZXIiIHRoZSBkYXRhIGluCgkJCQkvLyBIVE1MNSBjdXN0b20gZGF0YS0qIGF0dHJzCgkJCQlkYXRhID0gZGF0YUF0dHIoIGVsZW0sIGtleSApOwoJCQkJaWYgKCBkYXRhICE9PSB1bmRlZmluZWQgKSB7CgkJCQkJcmV0dXJuIGRhdGE7CgkJCQl9CgoJCQkJLy8gV2UgdHJpZWQgcmVhbGx5IGhhcmQsIGJ1dCB0aGUgZGF0YSBkb2Vzbid0IGV4aXN0LgoJCQkJcmV0dXJuOwoJCQl9CgoJCQkvLyBTZXQgdGhlIGRhdGEuLi4KCQkJdGhpcy5lYWNoKCBmdW5jdGlvbigpIHsKCgkJCQkvLyBXZSBhbHdheXMgc3RvcmUgdGhlIGNhbWVsQ2FzZWQga2V5CgkJCQlkYXRhVXNlci5zZXQoIHRoaXMsIGtleSwgdmFsdWUgKTsKCQkJfSApOwoJCX0sIG51bGwsIHZhbHVlLCBhcmd1bWVudHMubGVuZ3RoID4gMSwgbnVsbCwgdHJ1ZSApOwoJfSwKCglyZW1vdmVEYXRhOiBmdW5jdGlvbigga2V5ICkgewoJCXJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCkgewoJCQlkYXRhVXNlci5yZW1vdmUoIHRoaXMsIGtleSApOwoJCX0gKTsKCX0KfSApOwoKCmpRdWVyeS5leHRlbmQoIHsKCXF1ZXVlOiBmdW5jdGlvbiggZWxlbSwgdHlwZSwgZGF0YSApIHsKCQl2YXIgcXVldWU7CgoJCWlmICggZWxlbSApIHsKCQkJdHlwZSA9ICggdHlwZSB8fCAiZngiICkgKyAicXVldWUiOwoJCQlxdWV1ZSA9IGRhdGFQcml2LmdldCggZWxlbSwgdHlwZSApOwoKCQkJLy8gU3BlZWQgdXAgZGVxdWV1ZSBieSBnZXR0aW5nIG91dCBxdWlja2x5IGlmIHRoaXMgaXMganVzdCBhIGxvb2t1cAoJCQlpZiAoIGRhdGEgKSB7CgkJCQlpZiAoICFxdWV1ZSB8fCBBcnJheS5pc0FycmF5KCBkYXRhICkgKSB7CgkJCQkJcXVldWUgPSBkYXRhUHJpdi5hY2Nlc3MoIGVsZW0sIHR5cGUsIGpRdWVyeS5tYWtlQXJyYXkoIGRhdGEgKSApOwoJCQkJfSBlbHNlIHsKCQkJCQlxdWV1ZS5wdXNoKCBkYXRhICk7CgkJCQl9CgkJCX0KCQkJcmV0dXJuIHF1ZXVlIHx8IFtdOwoJCX0KCX0sCgoJZGVxdWV1ZTogZnVuY3Rpb24oIGVsZW0sIHR5cGUgKSB7CgkJdHlwZSA9IHR5cGUgfHwgImZ4IjsKCgkJdmFyIHF1ZXVlID0galF1ZXJ5LnF1ZXVlKCBlbGVtLCB0eXBlICksCgkJCXN0YXJ0TGVuZ3RoID0gcXVldWUubGVuZ3RoLAoJCQlmbiA9IHF1ZXVlLnNoaWZ0KCksCgkJCWhvb2tzID0galF1ZXJ5Ll9xdWV1ZUhvb2tzKCBlbGVtLCB0eXBlICksCgkJCW5leHQgPSBmdW5jdGlvbigpIHsKCQkJCWpRdWVyeS5kZXF1ZXVlKCBlbGVtLCB0eXBlICk7CgkJCX07CgoJCS8vIElmIHRoZSBmeCBxdWV1ZSBpcyBkZXF1ZXVlZCwgYWx3YXlzIHJlbW92ZSB0aGUgcHJvZ3Jlc3Mgc2VudGluZWwKCQlpZiAoIGZuID09PSAiaW5wcm9ncmVzcyIgKSB7CgkJCWZuID0gcXVldWUuc2hpZnQoKTsKCQkJc3RhcnRMZW5ndGgtLTsKCQl9CgoJCWlmICggZm4gKSB7CgoJCQkvLyBBZGQgYSBwcm9ncmVzcyBzZW50aW5lbCB0byBwcmV2ZW50IHRoZSBmeCBxdWV1ZSBmcm9tIGJlaW5nCgkJCS8vIGF1dG9tYXRpY2FsbHkgZGVxdWV1ZWQKCQkJaWYgKCB0eXBlID09PSAiZngiICkgewoJCQkJcXVldWUudW5zaGlmdCggImlucHJvZ3Jlc3MiICk7CgkJCX0KCgkJCS8vIENsZWFyIHVwIHRoZSBsYXN0IHF1ZXVlIHN0b3AgZnVuY3Rpb24KCQkJZGVsZXRlIGhvb2tzLnN0b3A7CgkJCWZuLmNhbGwoIGVsZW0sIG5leHQsIGhvb2tzICk7CgkJfQoKCQlpZiAoICFzdGFydExlbmd0aCAmJiBob29rcyApIHsKCQkJaG9va3MuZW1wdHkuZmlyZSgpOwoJCX0KCX0sCgoJLy8gTm90IHB1YmxpYyAtIGdlbmVyYXRlIGEgcXVldWVIb29rcyBvYmplY3QsIG9yIHJldHVybiB0aGUgY3VycmVudCBvbmUKCV9xdWV1ZUhvb2tzOiBmdW5jdGlvbiggZWxlbSwgdHlwZSApIHsKCQl2YXIga2V5ID0gdHlwZSArICJxdWV1ZUhvb2tzIjsKCQlyZXR1cm4gZGF0YVByaXYuZ2V0KCBlbGVtLCBrZXkgKSB8fCBkYXRhUHJpdi5hY2Nlc3MoIGVsZW0sIGtleSwgewoJCQllbXB0eTogalF1ZXJ5LkNhbGxiYWNrcyggIm9uY2UgbWVtb3J5IiApLmFkZCggZnVuY3Rpb24oKSB7CgkJCQlkYXRhUHJpdi5yZW1vdmUoIGVsZW0sIFsgdHlwZSArICJxdWV1ZSIsIGtleSBdICk7CgkJCX0gKQoJCX0gKTsKCX0KfSApOwoKalF1ZXJ5LmZuLmV4dGVuZCggewoJcXVldWU6IGZ1bmN0aW9uKCB0eXBlLCBkYXRhICkgewoJCXZhciBzZXR0ZXIgPSAyOwoKCQlpZiAoIHR5cGVvZiB0eXBlICE9PSAic3RyaW5nIiApIHsKCQkJZGF0YSA9IHR5cGU7CgkJCXR5cGUgPSAiZngiOwoJCQlzZXR0ZXItLTsKCQl9CgoJCWlmICggYXJndW1lbnRzLmxlbmd0aCA8IHNldHRlciApIHsKCQkJcmV0dXJuIGpRdWVyeS5xdWV1ZSggdGhpc1sgMCBdLCB0eXBlICk7CgkJfQoKCQlyZXR1cm4gZGF0YSA9PT0gdW5kZWZpbmVkID8KCQkJdGhpcyA6CgkJCXRoaXMuZWFjaCggZnVuY3Rpb24oKSB7CgkJCQl2YXIgcXVldWUgPSBqUXVlcnkucXVldWUoIHRoaXMsIHR5cGUsIGRhdGEgKTsKCgkJCQkvLyBFbnN1cmUgYSBob29rcyBmb3IgdGhpcyBxdWV1ZQoJCQkJalF1ZXJ5Ll9xdWV1ZUhvb2tzKCB0aGlzLCB0eXBlICk7CgoJCQkJaWYgKCB0eXBlID09PSAiZngiICYmIHF1ZXVlWyAwIF0gIT09ICJpbnByb2dyZXNzIiApIHsKCQkJCQlqUXVlcnkuZGVxdWV1ZSggdGhpcywgdHlwZSApOwoJCQkJfQoJCQl9ICk7Cgl9LAoJZGVxdWV1ZTogZnVuY3Rpb24oIHR5cGUgKSB7CgkJcmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24oKSB7CgkJCWpRdWVyeS5kZXF1ZXVlKCB0aGlzLCB0eXBlICk7CgkJfSApOwoJfSwKCWNsZWFyUXVldWU6IGZ1bmN0aW9uKCB0eXBlICkgewoJCXJldHVybiB0aGlzLnF1ZXVlKCB0eXBlIHx8ICJmeCIsIFtdICk7Cgl9LAoKCS8vIEdldCBhIHByb21pc2UgcmVzb2x2ZWQgd2hlbiBxdWV1ZXMgb2YgYSBjZXJ0YWluIHR5cGUKCS8vIGFyZSBlbXB0aWVkIChmeCBpcyB0aGUgdHlwZSBieSBkZWZhdWx0KQoJcHJvbWlzZTogZnVuY3Rpb24oIHR5cGUsIG9iaiApIHsKCQl2YXIgdG1wLAoJCQljb3VudCA9IDEsCgkJCWRlZmVyID0galF1ZXJ5LkRlZmVycmVkKCksCgkJCWVsZW1lbnRzID0gdGhpcywKCQkJaSA9IHRoaXMubGVuZ3RoLAoJCQlyZXNvbHZlID0gZnVuY3Rpb24oKSB7CgkJCQlpZiAoICEoIC0tY291bnQgKSApIHsKCQkJCQlkZWZlci5yZXNvbHZlV2l0aCggZWxlbWVudHMsIFsgZWxlbWVudHMgXSApOwoJCQkJfQoJCQl9OwoKCQlpZiAoIHR5cGVvZiB0eXBlICE9PSAic3RyaW5nIiApIHsKCQkJb2JqID0gdHlwZTsKCQkJdHlwZSA9IHVuZGVmaW5lZDsKCQl9CgkJdHlwZSA9IHR5cGUgfHwgImZ4IjsKCgkJd2hpbGUgKCBpLS0gKSB7CgkJCXRtcCA9IGRhdGFQcml2LmdldCggZWxlbWVudHNbIGkgXSwgdHlwZSArICJxdWV1ZUhvb2tzIiApOwoJCQlpZiAoIHRtcCAmJiB0bXAuZW1wdHkgKSB7CgkJCQljb3VudCsrOwoJCQkJdG1wLmVtcHR5LmFkZCggcmVzb2x2ZSApOwoJCQl9CgkJfQoJCXJlc29sdmUoKTsKCQlyZXR1cm4gZGVmZXIucHJvbWlzZSggb2JqICk7Cgl9Cn0gKTsKdmFyIHBudW0gPSAoIC9bKy1dPyg/OlxkKlwufClcZCsoPzpbZUVdWystXT9cZCt8KS8gKS5zb3VyY2U7Cgp2YXIgcmNzc051bSA9IG5ldyBSZWdFeHAoICJeKD86KFsrLV0pPXwpKCIgKyBwbnVtICsgIikoW2EteiVdKikkIiwgImkiICk7CgoKdmFyIGNzc0V4cGFuZCA9IFsgIlRvcCIsICJSaWdodCIsICJCb3R0b20iLCAiTGVmdCIgXTsKCnZhciBpc0hpZGRlbldpdGhpblRyZWUgPSBmdW5jdGlvbiggZWxlbSwgZWwgKSB7CgoJCS8vIGlzSGlkZGVuV2l0aGluVHJlZSBtaWdodCBiZSBjYWxsZWQgZnJvbSBqUXVlcnkjZmlsdGVyIGZ1bmN0aW9uOwoJCS8vIGluIHRoYXQgY2FzZSwgZWxlbWVudCB3aWxsIGJlIHNlY29uZCBhcmd1bWVudAoJCWVsZW0gPSBlbCB8fCBlbGVtOwoKCQkvLyBJbmxpbmUgc3R5bGUgdHJ1bXBzIGFsbAoJCXJldHVybiBlbGVtLnN0eWxlLmRpc3BsYXkgPT09ICJub25lIiB8fAoJCQllbGVtLnN0eWxlLmRpc3BsYXkgPT09ICIiICYmCgoJCQkvLyBPdGhlcndpc2UsIGNoZWNrIGNvbXB1dGVkIHN0eWxlCgkJCS8vIFN1cHBvcnQ6IEZpcmVmb3ggPD00MyAtIDQ1CgkJCS8vIERpc2Nvbm5lY3RlZCBlbGVtZW50cyBjYW4gaGF2ZSBjb21wdXRlZCBkaXNwbGF5OiBub25lLCBzbyBmaXJzdCBjb25maXJtIHRoYXQgZWxlbSBpcwoJCQkvLyBpbiB0aGUgZG9jdW1lbnQuCgkJCWpRdWVyeS5jb250YWlucyggZWxlbS5vd25lckRvY3VtZW50LCBlbGVtICkgJiYKCgkJCWpRdWVyeS5jc3MoIGVsZW0sICJkaXNwbGF5IiApID09PSAibm9uZSI7Cgl9OwoKdmFyIHN3YXAgPSBmdW5jdGlvbiggZWxlbSwgb3B0aW9ucywgY2FsbGJhY2ssIGFyZ3MgKSB7Cgl2YXIgcmV0LCBuYW1lLAoJCW9sZCA9IHt9OwoKCS8vIFJlbWVtYmVyIHRoZSBvbGQgdmFsdWVzLCBhbmQgaW5zZXJ0IHRoZSBuZXcgb25lcwoJZm9yICggbmFtZSBpbiBvcHRpb25zICkgewoJCW9sZFsgbmFtZSBdID0gZWxlbS5zdHlsZVsgbmFtZSBdOwoJCWVsZW0uc3R5bGVbIG5hbWUgXSA9IG9wdGlvbnNbIG5hbWUgXTsKCX0KCglyZXQgPSBjYWxsYmFjay5hcHBseSggZWxlbSwgYXJncyB8fCBbXSApOwoKCS8vIFJldmVydCB0aGUgb2xkIHZhbHVlcwoJZm9yICggbmFtZSBpbiBvcHRpb25zICkgewoJCWVsZW0uc3R5bGVbIG5hbWUgXSA9IG9sZFsgbmFtZSBdOwoJfQoKCXJldHVybiByZXQ7Cn07CgoKCgpmdW5jdGlvbiBhZGp1c3RDU1MoIGVsZW0sIHByb3AsIHZhbHVlUGFydHMsIHR3ZWVuICkgewoJdmFyIGFkanVzdGVkLCBzY2FsZSwKCQltYXhJdGVyYXRpb25zID0gMjAsCgkJY3VycmVudFZhbHVlID0gdHdlZW4gPwoJCQlmdW5jdGlvbigpIHsKCQkJCXJldHVybiB0d2Vlbi5jdXIoKTsKCQkJfSA6CgkJCWZ1bmN0aW9uKCkgewoJCQkJcmV0dXJuIGpRdWVyeS5jc3MoIGVsZW0sIHByb3AsICIiICk7CgkJCX0sCgkJaW5pdGlhbCA9IGN1cnJlbnRWYWx1ZSgpLAoJCXVuaXQgPSB2YWx1ZVBhcnRzICYmIHZhbHVlUGFydHNbIDMgXSB8fCAoIGpRdWVyeS5jc3NOdW1iZXJbIHByb3AgXSA/ICIiIDogInB4IiApLAoKCQkvLyBTdGFydGluZyB2YWx1ZSBjb21wdXRhdGlvbiBpcyByZXF1aXJlZCBmb3IgcG90ZW50aWFsIHVuaXQgbWlzbWF0Y2hlcwoJCWluaXRpYWxJblVuaXQgPSAoIGpRdWVyeS5jc3NOdW1iZXJbIHByb3AgXSB8fCB1bml0ICE9PSAicHgiICYmICtpbml0aWFsICkgJiYKCQkJcmNzc051bS5leGVjKCBqUXVlcnkuY3NzKCBlbGVtLCBwcm9wICkgKTsKCglpZiAoIGluaXRpYWxJblVuaXQgJiYgaW5pdGlhbEluVW5pdFsgMyBdICE9PSB1bml0ICkgewoKCQkvLyBTdXBwb3J0OiBGaXJlZm94IDw9NTQKCQkvLyBIYWx2ZSB0aGUgaXRlcmF0aW9uIHRhcmdldCB2YWx1ZSB0byBwcmV2ZW50IGludGVyZmVyZW5jZSBmcm9tIENTUyB1cHBlciBib3VuZHMgKGdoLTIxNDQpCgkJaW5pdGlhbCA9IGluaXRpYWwgLyAyOwoKCQkvLyBUcnVzdCB1bml0cyByZXBvcnRlZCBieSBqUXVlcnkuY3NzCgkJdW5pdCA9IHVuaXQgfHwgaW5pdGlhbEluVW5pdFsgMyBdOwoKCQkvLyBJdGVyYXRpdmVseSBhcHByb3hpbWF0ZSBmcm9tIGEgbm9uemVybyBzdGFydGluZyBwb2ludAoJCWluaXRpYWxJblVuaXQgPSAraW5pdGlhbCB8fCAxOwoKCQl3aGlsZSAoIG1heEl0ZXJhdGlvbnMtLSApIHsKCgkJCS8vIEV2YWx1YXRlIGFuZCB1cGRhdGUgb3VyIGJlc3QgZ3Vlc3MgKGRvdWJsaW5nIGd1ZXNzZXMgdGhhdCB6ZXJvIG91dCkuCgkJCS8vIEZpbmlzaCBpZiB0aGUgc2NhbGUgZXF1YWxzIG9yIGNyb3NzZXMgMSAobWFraW5nIHRoZSBvbGQqbmV3IHByb2R1Y3Qgbm9uLXBvc2l0aXZlKS4KCQkJalF1ZXJ5LnN0eWxlKCBlbGVtLCBwcm9wLCBpbml0aWFsSW5Vbml0ICsgdW5pdCApOwoJCQlpZiAoICggMSAtIHNjYWxlICkgKiAoIDEgLSAoIHNjYWxlID0gY3VycmVudFZhbHVlKCkgLyBpbml0aWFsIHx8IDAuNSApICkgPD0gMCApIHsKCQkJCW1heEl0ZXJhdGlvbnMgPSAwOwoJCQl9CgkJCWluaXRpYWxJblVuaXQgPSBpbml0aWFsSW5Vbml0IC8gc2NhbGU7CgoJCX0KCgkJaW5pdGlhbEluVW5pdCA9IGluaXRpYWxJblVuaXQgKiAyOwoJCWpRdWVyeS5zdHlsZSggZWxlbSwgcHJvcCwgaW5pdGlhbEluVW5pdCArIHVuaXQgKTsKCgkJLy8gTWFrZSBzdXJlIHdlIHVwZGF0ZSB0aGUgdHdlZW4gcHJvcGVydGllcyBsYXRlciBvbgoJCXZhbHVlUGFydHMgPSB2YWx1ZVBhcnRzIHx8IFtdOwoJfQoKCWlmICggdmFsdWVQYXJ0cyApIHsKCQlpbml0aWFsSW5Vbml0ID0gK2luaXRpYWxJblVuaXQgfHwgK2luaXRpYWwgfHwgMDsKCgkJLy8gQXBwbHkgcmVsYXRpdmUgb2Zmc2V0ICgrPS8tPSkgaWYgc3BlY2lmaWVkCgkJYWRqdXN0ZWQgPSB2YWx1ZVBhcnRzWyAxIF0gPwoJCQlpbml0aWFsSW5Vbml0ICsgKCB2YWx1ZVBhcnRzWyAxIF0gKyAxICkgKiB2YWx1ZVBhcnRzWyAyIF0gOgoJCQkrdmFsdWVQYXJ0c1sgMiBdOwoJCWlmICggdHdlZW4gKSB7CgkJCXR3ZWVuLnVuaXQgPSB1bml0OwoJCQl0d2Vlbi5zdGFydCA9IGluaXRpYWxJblVuaXQ7CgkJCXR3ZWVuLmVuZCA9IGFkanVzdGVkOwoJCX0KCX0KCXJldHVybiBhZGp1c3RlZDsKfQoKCnZhciBkZWZhdWx0RGlzcGxheU1hcCA9IHt9OwoKZnVuY3Rpb24gZ2V0RGVmYXVsdERpc3BsYXkoIGVsZW0gKSB7Cgl2YXIgdGVtcCwKCQlkb2MgPSBlbGVtLm93bmVyRG9jdW1lbnQsCgkJbm9kZU5hbWUgPSBlbGVtLm5vZGVOYW1lLAoJCWRpc3BsYXkgPSBkZWZhdWx0RGlzcGxheU1hcFsgbm9kZU5hbWUgXTsKCglpZiAoIGRpc3BsYXkgKSB7CgkJcmV0dXJuIGRpc3BsYXk7Cgl9CgoJdGVtcCA9IGRvYy5ib2R5LmFwcGVuZENoaWxkKCBkb2MuY3JlYXRlRWxlbWVudCggbm9kZU5hbWUgKSApOwoJZGlzcGxheSA9IGpRdWVyeS5jc3MoIHRlbXAsICJkaXNwbGF5IiApOwoKCXRlbXAucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCggdGVtcCApOwoKCWlmICggZGlzcGxheSA9PT0gIm5vbmUiICkgewoJCWRpc3BsYXkgPSAiYmxvY2siOwoJfQoJZGVmYXVsdERpc3BsYXlNYXBbIG5vZGVOYW1lIF0gPSBkaXNwbGF5OwoKCXJldHVybiBkaXNwbGF5Owp9CgpmdW5jdGlvbiBzaG93SGlkZSggZWxlbWVudHMsIHNob3cgKSB7Cgl2YXIgZGlzcGxheSwgZWxlbSwKCQl2YWx1ZXMgPSBbXSwKCQlpbmRleCA9IDAsCgkJbGVuZ3RoID0gZWxlbWVudHMubGVuZ3RoOwoKCS8vIERldGVybWluZSBuZXcgZGlzcGxheSB2YWx1ZSBmb3IgZWxlbWVudHMgdGhhdCBuZWVkIHRvIGNoYW5nZQoJZm9yICggOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKyApIHsKCQllbGVtID0gZWxlbWVudHNbIGluZGV4IF07CgkJaWYgKCAhZWxlbS5zdHlsZSApIHsKCQkJY29udGludWU7CgkJfQoKCQlkaXNwbGF5ID0gZWxlbS5zdHlsZS5kaXNwbGF5OwoJCWlmICggc2hvdyApIHsKCgkJCS8vIFNpbmNlIHdlIGZvcmNlIHZpc2liaWxpdHkgdXBvbiBjYXNjYWRlLWhpZGRlbiBlbGVtZW50cywgYW4gaW1tZWRpYXRlIChhbmQgc2xvdykKCQkJLy8gY2hlY2sgaXMgcmVxdWlyZWQgaW4gdGhpcyBmaXJzdCBsb29wIHVubGVzcyB3ZSBoYXZlIGEgbm9uZW1wdHkgZGlzcGxheSB2YWx1ZSAoZWl0aGVyCgkJCS8vIGlubGluZSBvciBhYm91dC10by1iZS1yZXN0b3JlZCkKCQkJaWYgKCBkaXNwbGF5ID09PSAibm9uZSIgKSB7CgkJCQl2YWx1ZXNbIGluZGV4IF0gPSBkYXRhUHJpdi5nZXQoIGVsZW0sICJkaXNwbGF5IiApIHx8IG51bGw7CgkJCQlpZiAoICF2YWx1ZXNbIGluZGV4IF0gKSB7CgkJCQkJZWxlbS5zdHlsZS5kaXNwbGF5ID0gIiI7CgkJCQl9CgkJCX0KCQkJaWYgKCBlbGVtLnN0eWxlLmRpc3BsYXkgPT09ICIiICYmIGlzSGlkZGVuV2l0aGluVHJlZSggZWxlbSApICkgewoJCQkJdmFsdWVzWyBpbmRleCBdID0gZ2V0RGVmYXVsdERpc3BsYXkoIGVsZW0gKTsKCQkJfQoJCX0gZWxzZSB7CgkJCWlmICggZGlzcGxheSAhPT0gIm5vbmUiICkgewoJCQkJdmFsdWVzWyBpbmRleCBdID0gIm5vbmUiOwoKCQkJCS8vIFJlbWVtYmVyIHdoYXQgd2UncmUgb3ZlcndyaXRpbmcKCQkJCWRhdGFQcml2LnNldCggZWxlbSwgImRpc3BsYXkiLCBkaXNwbGF5ICk7CgkJCX0KCQl9Cgl9CgoJLy8gU2V0IHRoZSBkaXNwbGF5IG9mIHRoZSBlbGVtZW50cyBpbiBhIHNlY29uZCBsb29wIHRvIGF2b2lkIGNvbnN0YW50IHJlZmxvdwoJZm9yICggaW5kZXggPSAwOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKyApIHsKCQlpZiAoIHZhbHVlc1sgaW5kZXggXSAhPSBudWxsICkgewoJCQllbGVtZW50c1sgaW5kZXggXS5zdHlsZS5kaXNwbGF5ID0gdmFsdWVzWyBpbmRleCBdOwoJCX0KCX0KCglyZXR1cm4gZWxlbWVudHM7Cn0KCmpRdWVyeS5mbi5leHRlbmQoIHsKCXNob3c6IGZ1bmN0aW9uKCkgewoJCXJldHVybiBzaG93SGlkZSggdGhpcywgdHJ1ZSApOwoJfSwKCWhpZGU6IGZ1bmN0aW9uKCkgewoJCXJldHVybiBzaG93SGlkZSggdGhpcyApOwoJfSwKCXRvZ2dsZTogZnVuY3Rpb24oIHN0YXRlICkgewoJCWlmICggdHlwZW9mIHN0YXRlID09PSAiYm9vbGVhbiIgKSB7CgkJCXJldHVybiBzdGF0ZSA/IHRoaXMuc2hvdygpIDogdGhpcy5oaWRlKCk7CgkJfQoKCQlyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbigpIHsKCQkJaWYgKCBpc0hpZGRlbldpdGhpblRyZWUoIHRoaXMgKSApIHsKCQkJCWpRdWVyeSggdGhpcyApLnNob3coKTsKCQkJfSBlbHNlIHsKCQkJCWpRdWVyeSggdGhpcyApLmhpZGUoKTsKCQkJfQoJCX0gKTsKCX0KfSApOwp2YXIgcmNoZWNrYWJsZVR5cGUgPSAoIC9eKD86Y2hlY2tib3h8cmFkaW8pJC9pICk7Cgp2YXIgcnRhZ05hbWUgPSAoIC88KFthLXpdW15cL1wwPlx4MjBcdFxyXG5cZl0rKS9pICk7Cgp2YXIgcnNjcmlwdFR5cGUgPSAoIC9eJHxebW9kdWxlJHxcLyg/OmphdmF8ZWNtYSlzY3JpcHQvaSApOwoKCgovLyBXZSBoYXZlIHRvIGNsb3NlIHRoZXNlIHRhZ3MgdG8gc3VwcG9ydCBYSFRNTCAoIzEzMjAwKQp2YXIgd3JhcE1hcCA9IHsKCgkvLyBTdXBwb3J0OiBJRSA8PTkgb25seQoJb3B0aW9uOiBbIDEsICI8c2VsZWN0IG11bHRpcGxlPSdtdWx0aXBsZSc+IiwgIjwvc2VsZWN0PiIgXSwKCgkvLyBYSFRNTCBwYXJzZXJzIGRvIG5vdCBtYWdpY2FsbHkgaW5zZXJ0IGVsZW1lbnRzIGluIHRoZQoJLy8gc2FtZSB3YXkgdGhhdCB0YWcgc291cCBwYXJzZXJzIGRvLiBTbyB3ZSBjYW5ub3Qgc2hvcnRlbgoJLy8gdGhpcyBieSBvbWl0dGluZyA8dGJvZHk+IG9yIG90aGVyIHJlcXVpcmVkIGVsZW1lbnRzLgoJdGhlYWQ6IFsgMSwgIjx0YWJsZT4iLCAiPC90YWJsZT4iIF0sCgljb2w6IFsgMiwgIjx0YWJsZT48Y29sZ3JvdXA+IiwgIjwvY29sZ3JvdXA+PC90YWJsZT4iIF0sCgl0cjogWyAyLCAiPHRhYmxlPjx0Ym9keT4iLCAiPC90Ym9keT48L3RhYmxlPiIgXSwKCXRkOiBbIDMsICI8dGFibGU+PHRib2R5Pjx0cj4iLCAiPC90cj48L3Rib2R5PjwvdGFibGU+IiBdLAoKCV9kZWZhdWx0OiBbIDAsICIiLCAiIiBdCn07CgovLyBTdXBwb3J0OiBJRSA8PTkgb25seQp3cmFwTWFwLm9wdGdyb3VwID0gd3JhcE1hcC5vcHRpb247Cgp3cmFwTWFwLnRib2R5ID0gd3JhcE1hcC50Zm9vdCA9IHdyYXBNYXAuY29sZ3JvdXAgPSB3cmFwTWFwLmNhcHRpb24gPSB3cmFwTWFwLnRoZWFkOwp3cmFwTWFwLnRoID0gd3JhcE1hcC50ZDsKCgpmdW5jdGlvbiBnZXRBbGwoIGNvbnRleHQsIHRhZyApIHsKCgkvLyBTdXBwb3J0OiBJRSA8PTkgLSAxMSBvbmx5CgkvLyBVc2UgdHlwZW9mIHRvIGF2b2lkIHplcm8tYXJndW1lbnQgbWV0aG9kIGludm9jYXRpb24gb24gaG9zdCBvYmplY3RzICgjMTUxNTEpCgl2YXIgcmV0OwoKCWlmICggdHlwZW9mIGNvbnRleHQuZ2V0RWxlbWVudHNCeVRhZ05hbWUgIT09ICJ1bmRlZmluZWQiICkgewoJCXJldCA9IGNvbnRleHQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIHRhZyB8fCAiKiIgKTsKCgl9IGVsc2UgaWYgKCB0eXBlb2YgY29udGV4dC5xdWVyeVNlbGVjdG9yQWxsICE9PSAidW5kZWZpbmVkIiApIHsKCQlyZXQgPSBjb250ZXh0LnF1ZXJ5U2VsZWN0b3JBbGwoIHRhZyB8fCAiKiIgKTsKCgl9IGVsc2UgewoJCXJldCA9IFtdOwoJfQoKCWlmICggdGFnID09PSB1bmRlZmluZWQgfHwgdGFnICYmIG5vZGVOYW1lKCBjb250ZXh0LCB0YWcgKSApIHsKCQlyZXR1cm4galF1ZXJ5Lm1lcmdlKCBbIGNvbnRleHQgXSwgcmV0ICk7Cgl9CgoJcmV0dXJuIHJldDsKfQoKCi8vIE1hcmsgc2NyaXB0cyBhcyBoYXZpbmcgYWxyZWFkeSBiZWVuIGV2YWx1YXRlZApmdW5jdGlvbiBzZXRHbG9iYWxFdmFsKCBlbGVtcywgcmVmRWxlbWVudHMgKSB7Cgl2YXIgaSA9IDAsCgkJbCA9IGVsZW1zLmxlbmd0aDsKCglmb3IgKCA7IGkgPCBsOyBpKysgKSB7CgkJZGF0YVByaXYuc2V0KAoJCQllbGVtc1sgaSBdLAoJCQkiZ2xvYmFsRXZhbCIsCgkJCSFyZWZFbGVtZW50cyB8fCBkYXRhUHJpdi5nZXQoIHJlZkVsZW1lbnRzWyBpIF0sICJnbG9iYWxFdmFsIiApCgkJKTsKCX0KfQoKCnZhciByaHRtbCA9IC88fCYjP1x3KzsvOwoKZnVuY3Rpb24gYnVpbGRGcmFnbWVudCggZWxlbXMsIGNvbnRleHQsIHNjcmlwdHMsIHNlbGVjdGlvbiwgaWdub3JlZCApIHsKCXZhciBlbGVtLCB0bXAsIHRhZywgd3JhcCwgY29udGFpbnMsIGosCgkJZnJhZ21lbnQgPSBjb250ZXh0LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKSwKCQlub2RlcyA9IFtdLAoJCWkgPSAwLAoJCWwgPSBlbGVtcy5sZW5ndGg7CgoJZm9yICggOyBpIDwgbDsgaSsrICkgewoJCWVsZW0gPSBlbGVtc1sgaSBdOwoKCQlpZiAoIGVsZW0gfHwgZWxlbSA9PT0gMCApIHsKCgkJCS8vIEFkZCBub2RlcyBkaXJlY3RseQoJCQlpZiAoIHRvVHlwZSggZWxlbSApID09PSAib2JqZWN0IiApIHsKCgkJCQkvLyBTdXBwb3J0OiBBbmRyb2lkIDw9NC4wIG9ubHksIFBoYW50b21KUyAxIG9ubHkKCQkJCS8vIHB1c2guYXBwbHkoXywgYXJyYXlsaWtlKSB0aHJvd3Mgb24gYW5jaWVudCBXZWJLaXQKCQkJCWpRdWVyeS5tZXJnZSggbm9kZXMsIGVsZW0ubm9kZVR5cGUgPyBbIGVsZW0gXSA6IGVsZW0gKTsKCgkJCS8vIENvbnZlcnQgbm9uLWh0bWwgaW50byBhIHRleHQgbm9kZQoJCQl9IGVsc2UgaWYgKCAhcmh0bWwudGVzdCggZWxlbSApICkgewoJCQkJbm9kZXMucHVzaCggY29udGV4dC5jcmVhdGVUZXh0Tm9kZSggZWxlbSApICk7CgoJCQkvLyBDb252ZXJ0IGh0bWwgaW50byBET00gbm9kZXMKCQkJfSBlbHNlIHsKCQkJCXRtcCA9IHRtcCB8fCBmcmFnbWVudC5hcHBlbmRDaGlsZCggY29udGV4dC5jcmVhdGVFbGVtZW50KCAiZGl2IiApICk7CgoJCQkJLy8gRGVzZXJpYWxpemUgYSBzdGFuZGFyZCByZXByZXNlbnRhdGlvbgoJCQkJdGFnID0gKCBydGFnTmFtZS5leGVjKCBlbGVtICkgfHwgWyAiIiwgIiIgXSApWyAxIF0udG9Mb3dlckNhc2UoKTsKCQkJCXdyYXAgPSB3cmFwTWFwWyB0YWcgXSB8fCB3cmFwTWFwLl9kZWZhdWx0OwoJCQkJdG1wLmlubmVySFRNTCA9IHdyYXBbIDEgXSArIGpRdWVyeS5odG1sUHJlZmlsdGVyKCBlbGVtICkgKyB3cmFwWyAyIF07CgoJCQkJLy8gRGVzY2VuZCB0aHJvdWdoIHdyYXBwZXJzIHRvIHRoZSByaWdodCBjb250ZW50CgkJCQlqID0gd3JhcFsgMCBdOwoJCQkJd2hpbGUgKCBqLS0gKSB7CgkJCQkJdG1wID0gdG1wLmxhc3RDaGlsZDsKCQkJCX0KCgkJCQkvLyBTdXBwb3J0OiBBbmRyb2lkIDw9NC4wIG9ubHksIFBoYW50b21KUyAxIG9ubHkKCQkJCS8vIHB1c2guYXBwbHkoXywgYXJyYXlsaWtlKSB0aHJvd3Mgb24gYW5jaWVudCBXZWJLaXQKCQkJCWpRdWVyeS5tZXJnZSggbm9kZXMsIHRtcC5jaGlsZE5vZGVzICk7CgoJCQkJLy8gUmVtZW1iZXIgdGhlIHRvcC1sZXZlbCBjb250YWluZXIKCQkJCXRtcCA9IGZyYWdtZW50LmZpcnN0Q2hpbGQ7CgoJCQkJLy8gRW5zdXJlIHRoZSBjcmVhdGVkIG5vZGVzIGFyZSBvcnBoYW5lZCAoIzEyMzkyKQoJCQkJdG1wLnRleHRDb250ZW50ID0gIiI7CgkJCX0KCQl9Cgl9CgoJLy8gUmVtb3ZlIHdyYXBwZXIgZnJvbSBmcmFnbWVudAoJZnJhZ21lbnQudGV4dENvbnRlbnQgPSAiIjsKCglpID0gMDsKCXdoaWxlICggKCBlbGVtID0gbm9kZXNbIGkrKyBdICkgKSB7CgoJCS8vIFNraXAgZWxlbWVudHMgYWxyZWFkeSBpbiB0aGUgY29udGV4dCBjb2xsZWN0aW9uICh0cmFjLTQwODcpCgkJaWYgKCBzZWxlY3Rpb24gJiYgalF1ZXJ5LmluQXJyYXkoIGVsZW0sIHNlbGVjdGlvbiApID4gLTEgKSB7CgkJCWlmICggaWdub3JlZCApIHsKCQkJCWlnbm9yZWQucHVzaCggZWxlbSApOwoJCQl9CgkJCWNvbnRpbnVlOwoJCX0KCgkJY29udGFpbnMgPSBqUXVlcnkuY29udGFpbnMoIGVsZW0ub3duZXJEb2N1bWVudCwgZWxlbSApOwoKCQkvLyBBcHBlbmQgdG8gZnJhZ21lbnQKCQl0bXAgPSBnZXRBbGwoIGZyYWdtZW50LmFwcGVuZENoaWxkKCBlbGVtICksICJzY3JpcHQiICk7CgoJCS8vIFByZXNlcnZlIHNjcmlwdCBldmFsdWF0aW9uIGhpc3RvcnkKCQlpZiAoIGNvbnRhaW5zICkgewoJCQlzZXRHbG9iYWxFdmFsKCB0bXAgKTsKCQl9CgoJCS8vIENhcHR1cmUgZXhlY3V0YWJsZXMKCQlpZiAoIHNjcmlwdHMgKSB7CgkJCWogPSAwOwoJCQl3aGlsZSAoICggZWxlbSA9IHRtcFsgaisrIF0gKSApIHsKCQkJCWlmICggcnNjcmlwdFR5cGUudGVzdCggZWxlbS50eXBlIHx8ICIiICkgKSB7CgkJCQkJc2NyaXB0cy5wdXNoKCBlbGVtICk7CgkJCQl9CgkJCX0KCQl9Cgl9CgoJcmV0dXJuIGZyYWdtZW50Owp9CgoKKCBmdW5jdGlvbigpIHsKCXZhciBmcmFnbWVudCA9IGRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKSwKCQlkaXYgPSBmcmFnbWVudC5hcHBlbmRDaGlsZCggZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggImRpdiIgKSApLAoJCWlucHV0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggImlucHV0IiApOwoKCS8vIFN1cHBvcnQ6IEFuZHJvaWQgNC4wIC0gNC4zIG9ubHkKCS8vIENoZWNrIHN0YXRlIGxvc3QgaWYgdGhlIG5hbWUgaXMgc2V0ICgjMTEyMTcpCgkvLyBTdXBwb3J0OiBXaW5kb3dzIFdlYiBBcHBzIChXV0EpCgkvLyBgbmFtZWAgYW5kIGB0eXBlYCBtdXN0IHVzZSAuc2V0QXR0cmlidXRlIGZvciBXV0EgKCMxNDkwMSkKCWlucHV0LnNldEF0dHJpYnV0ZSggInR5cGUiLCAicmFkaW8iICk7CglpbnB1dC5zZXRBdHRyaWJ1dGUoICJjaGVja2VkIiwgImNoZWNrZWQiICk7CglpbnB1dC5zZXRBdHRyaWJ1dGUoICJuYW1lIiwgInQiICk7CgoJZGl2LmFwcGVuZENoaWxkKCBpbnB1dCApOwoKCS8vIFN1cHBvcnQ6IEFuZHJvaWQgPD00LjEgb25seQoJLy8gT2xkZXIgV2ViS2l0IGRvZXNuJ3QgY2xvbmUgY2hlY2tlZCBzdGF0ZSBjb3JyZWN0bHkgaW4gZnJhZ21lbnRzCglzdXBwb3J0LmNoZWNrQ2xvbmUgPSBkaXYuY2xvbmVOb2RlKCB0cnVlICkuY2xvbmVOb2RlKCB0cnVlICkubGFzdENoaWxkLmNoZWNrZWQ7CgoJLy8gU3VwcG9ydDogSUUgPD0xMSBvbmx5CgkvLyBNYWtlIHN1cmUgdGV4dGFyZWEgKGFuZCBjaGVja2JveCkgZGVmYXVsdFZhbHVlIGlzIHByb3Blcmx5IGNsb25lZAoJZGl2LmlubmVySFRNTCA9ICI8dGV4dGFyZWE+eDwvdGV4dGFyZWE+IjsKCXN1cHBvcnQubm9DbG9uZUNoZWNrZWQgPSAhIWRpdi5jbG9uZU5vZGUoIHRydWUgKS5sYXN0Q2hpbGQuZGVmYXVsdFZhbHVlOwp9ICkoKTsKdmFyIGRvY3VtZW50RWxlbWVudCA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudDsKCgoKdmFyCglya2V5RXZlbnQgPSAvXmtleS8sCglybW91c2VFdmVudCA9IC9eKD86bW91c2V8cG9pbnRlcnxjb250ZXh0bWVudXxkcmFnfGRyb3ApfGNsaWNrLywKCXJ0eXBlbmFtZXNwYWNlID0gL14oW14uXSopKD86XC4oLispfCkvOwoKZnVuY3Rpb24gcmV0dXJuVHJ1ZSgpIHsKCXJldHVybiB0cnVlOwp9CgpmdW5jdGlvbiByZXR1cm5GYWxzZSgpIHsKCXJldHVybiBmYWxzZTsKfQoKLy8gU3VwcG9ydDogSUUgPD05IG9ubHkKLy8gU2VlICMxMzM5MyBmb3IgbW9yZSBpbmZvCmZ1bmN0aW9uIHNhZmVBY3RpdmVFbGVtZW50KCkgewoJdHJ5IHsKCQlyZXR1cm4gZG9jdW1lbnQuYWN0aXZlRWxlbWVudDsKCX0gY2F0Y2ggKCBlcnIgKSB7IH0KfQoKZnVuY3Rpb24gb24oIGVsZW0sIHR5cGVzLCBzZWxlY3RvciwgZGF0YSwgZm4sIG9uZSApIHsKCXZhciBvcmlnRm4sIHR5cGU7CgoJLy8gVHlwZXMgY2FuIGJlIGEgbWFwIG9mIHR5cGVzL2hhbmRsZXJzCglpZiAoIHR5cGVvZiB0eXBlcyA9PT0gIm9iamVjdCIgKSB7CgoJCS8vICggdHlwZXMtT2JqZWN0LCBzZWxlY3RvciwgZGF0YSApCgkJaWYgKCB0eXBlb2Ygc2VsZWN0b3IgIT09ICJzdHJpbmciICkgewoKCQkJLy8gKCB0eXBlcy1PYmplY3QsIGRhdGEgKQoJCQlkYXRhID0gZGF0YSB8fCBzZWxlY3RvcjsKCQkJc2VsZWN0b3IgPSB1bmRlZmluZWQ7CgkJfQoJCWZvciAoIHR5cGUgaW4gdHlwZXMgKSB7CgkJCW9uKCBlbGVtLCB0eXBlLCBzZWxlY3RvciwgZGF0YSwgdHlwZXNbIHR5cGUgXSwgb25lICk7CgkJfQoJCXJldHVybiBlbGVtOwoJfQoKCWlmICggZGF0YSA9PSBudWxsICYmIGZuID09IG51bGwgKSB7CgoJCS8vICggdHlwZXMsIGZuICkKCQlmbiA9IHNlbGVjdG9yOwoJCWRhdGEgPSBzZWxlY3RvciA9IHVuZGVmaW5lZDsKCX0gZWxzZSBpZiAoIGZuID09IG51bGwgKSB7CgkJaWYgKCB0eXBlb2Ygc2VsZWN0b3IgPT09ICJzdHJpbmciICkgewoKCQkJLy8gKCB0eXBlcywgc2VsZWN0b3IsIGZuICkKCQkJZm4gPSBkYXRhOwoJCQlkYXRhID0gdW5kZWZpbmVkOwoJCX0gZWxzZSB7CgoJCQkvLyAoIHR5cGVzLCBkYXRhLCBmbiApCgkJCWZuID0gZGF0YTsKCQkJZGF0YSA9IHNlbGVjdG9yOwoJCQlzZWxlY3RvciA9IHVuZGVmaW5lZDsKCQl9Cgl9CglpZiAoIGZuID09PSBmYWxzZSApIHsKCQlmbiA9IHJldHVybkZhbHNlOwoJfSBlbHNlIGlmICggIWZuICkgewoJCXJldHVybiBlbGVtOwoJfQoKCWlmICggb25lID09PSAxICkgewoJCW9yaWdGbiA9IGZuOwoJCWZuID0gZnVuY3Rpb24oIGV2ZW50ICkgewoKCQkJLy8gQ2FuIHVzZSBhbiBlbXB0eSBzZXQsIHNpbmNlIGV2ZW50IGNvbnRhaW5zIHRoZSBpbmZvCgkJCWpRdWVyeSgpLm9mZiggZXZlbnQgKTsKCQkJcmV0dXJuIG9yaWdGbi5hcHBseSggdGhpcywgYXJndW1lbnRzICk7CgkJfTsKCgkJLy8gVXNlIHNhbWUgZ3VpZCBzbyBjYWxsZXIgY2FuIHJlbW92ZSB1c2luZyBvcmlnRm4KCQlmbi5ndWlkID0gb3JpZ0ZuLmd1aWQgfHwgKCBvcmlnRm4uZ3VpZCA9IGpRdWVyeS5ndWlkKysgKTsKCX0KCXJldHVybiBlbGVtLmVhY2goIGZ1bmN0aW9uKCkgewoJCWpRdWVyeS5ldmVudC5hZGQoIHRoaXMsIHR5cGVzLCBmbiwgZGF0YSwgc2VsZWN0b3IgKTsKCX0gKTsKfQoKLyoKICogSGVscGVyIGZ1bmN0aW9ucyBmb3IgbWFuYWdpbmcgZXZlbnRzIC0tIG5vdCBwYXJ0IG9mIHRoZSBwdWJsaWMgaW50ZXJmYWNlLgogKiBQcm9wcyB0byBEZWFuIEVkd2FyZHMnIGFkZEV2ZW50IGxpYnJhcnkgZm9yIG1hbnkgb2YgdGhlIGlkZWFzLgogKi8KalF1ZXJ5LmV2ZW50ID0gewoKCWdsb2JhbDoge30sCgoJYWRkOiBmdW5jdGlvbiggZWxlbSwgdHlwZXMsIGhhbmRsZXIsIGRhdGEsIHNlbGVjdG9yICkgewoKCQl2YXIgaGFuZGxlT2JqSW4sIGV2ZW50SGFuZGxlLCB0bXAsCgkJCWV2ZW50cywgdCwgaGFuZGxlT2JqLAoJCQlzcGVjaWFsLCBoYW5kbGVycywgdHlwZSwgbmFtZXNwYWNlcywgb3JpZ1R5cGUsCgkJCWVsZW1EYXRhID0gZGF0YVByaXYuZ2V0KCBlbGVtICk7CgoJCS8vIERvbid0IGF0dGFjaCBldmVudHMgdG8gbm9EYXRhIG9yIHRleHQvY29tbWVudCBub2RlcyAoYnV0IGFsbG93IHBsYWluIG9iamVjdHMpCgkJaWYgKCAhZWxlbURhdGEgKSB7CgkJCXJldHVybjsKCQl9CgoJCS8vIENhbGxlciBjYW4gcGFzcyBpbiBhbiBvYmplY3Qgb2YgY3VzdG9tIGRhdGEgaW4gbGlldSBvZiB0aGUgaGFuZGxlcgoJCWlmICggaGFuZGxlci5oYW5kbGVyICkgewoJCQloYW5kbGVPYmpJbiA9IGhhbmRsZXI7CgkJCWhhbmRsZXIgPSBoYW5kbGVPYmpJbi5oYW5kbGVyOwoJCQlzZWxlY3RvciA9IGhhbmRsZU9iakluLnNlbGVjdG9yOwoJCX0KCgkJLy8gRW5zdXJlIHRoYXQgaW52YWxpZCBzZWxlY3RvcnMgdGhyb3cgZXhjZXB0aW9ucyBhdCBhdHRhY2ggdGltZQoJCS8vIEV2YWx1YXRlIGFnYWluc3QgZG9jdW1lbnRFbGVtZW50IGluIGNhc2UgZWxlbSBpcyBhIG5vbi1lbGVtZW50IG5vZGUgKGUuZy4sIGRvY3VtZW50KQoJCWlmICggc2VsZWN0b3IgKSB7CgkJCWpRdWVyeS5maW5kLm1hdGNoZXNTZWxlY3RvciggZG9jdW1lbnRFbGVtZW50LCBzZWxlY3RvciApOwoJCX0KCgkJLy8gTWFrZSBzdXJlIHRoYXQgdGhlIGhhbmRsZXIgaGFzIGEgdW5pcXVlIElELCB1c2VkIHRvIGZpbmQvcmVtb3ZlIGl0IGxhdGVyCgkJaWYgKCAhaGFuZGxlci5ndWlkICkgewoJCQloYW5kbGVyLmd1aWQgPSBqUXVlcnkuZ3VpZCsrOwoJCX0KCgkJLy8gSW5pdCB0aGUgZWxlbWVudCdzIGV2ZW50IHN0cnVjdHVyZSBhbmQgbWFpbiBoYW5kbGVyLCBpZiB0aGlzIGlzIHRoZSBmaXJzdAoJCWlmICggISggZXZlbnRzID0gZWxlbURhdGEuZXZlbnRzICkgKSB7CgkJCWV2ZW50cyA9IGVsZW1EYXRhLmV2ZW50cyA9IHt9OwoJCX0KCQlpZiAoICEoIGV2ZW50SGFuZGxlID0gZWxlbURhdGEuaGFuZGxlICkgKSB7CgkJCWV2ZW50SGFuZGxlID0gZWxlbURhdGEuaGFuZGxlID0gZnVuY3Rpb24oIGUgKSB7CgoJCQkJLy8gRGlzY2FyZCB0aGUgc2Vjb25kIGV2ZW50IG9mIGEgalF1ZXJ5LmV2ZW50LnRyaWdnZXIoKSBhbmQKCQkJCS8vIHdoZW4gYW4gZXZlbnQgaXMgY2FsbGVkIGFmdGVyIGEgcGFnZSBoYXMgdW5sb2FkZWQKCQkJCXJldHVybiB0eXBlb2YgalF1ZXJ5ICE9PSAidW5kZWZpbmVkIiAmJiBqUXVlcnkuZXZlbnQudHJpZ2dlcmVkICE9PSBlLnR5cGUgPwoJCQkJCWpRdWVyeS5ldmVudC5kaXNwYXRjaC5hcHBseSggZWxlbSwgYXJndW1lbnRzICkgOiB1bmRlZmluZWQ7CgkJCX07CgkJfQoKCQkvLyBIYW5kbGUgbXVsdGlwbGUgZXZlbnRzIHNlcGFyYXRlZCBieSBhIHNwYWNlCgkJdHlwZXMgPSAoIHR5cGVzIHx8ICIiICkubWF0Y2goIHJub3RodG1sd2hpdGUgKSB8fCBbICIiIF07CgkJdCA9IHR5cGVzLmxlbmd0aDsKCQl3aGlsZSAoIHQtLSApIHsKCQkJdG1wID0gcnR5cGVuYW1lc3BhY2UuZXhlYyggdHlwZXNbIHQgXSApIHx8IFtdOwoJCQl0eXBlID0gb3JpZ1R5cGUgPSB0bXBbIDEgXTsKCQkJbmFtZXNwYWNlcyA9ICggdG1wWyAyIF0gfHwgIiIgKS5zcGxpdCggIi4iICkuc29ydCgpOwoKCQkJLy8gVGhlcmUgKm11c3QqIGJlIGEgdHlwZSwgbm8gYXR0YWNoaW5nIG5hbWVzcGFjZS1vbmx5IGhhbmRsZXJzCgkJCWlmICggIXR5cGUgKSB7CgkJCQljb250aW51ZTsKCQkJfQoKCQkJLy8gSWYgZXZlbnQgY2hhbmdlcyBpdHMgdHlwZSwgdXNlIHRoZSBzcGVjaWFsIGV2ZW50IGhhbmRsZXJzIGZvciB0aGUgY2hhbmdlZCB0eXBlCgkJCXNwZWNpYWwgPSBqUXVlcnkuZXZlbnQuc3BlY2lhbFsgdHlwZSBdIHx8IHt9OwoKCQkJLy8gSWYgc2VsZWN0b3IgZGVmaW5lZCwgZGV0ZXJtaW5lIHNwZWNpYWwgZXZlbnQgYXBpIHR5cGUsIG90aGVyd2lzZSBnaXZlbiB0eXBlCgkJCXR5cGUgPSAoIHNlbGVjdG9yID8gc3BlY2lhbC5kZWxlZ2F0ZVR5cGUgOiBzcGVjaWFsLmJpbmRUeXBlICkgfHwgdHlwZTsKCgkJCS8vIFVwZGF0ZSBzcGVjaWFsIGJhc2VkIG9uIG5ld2x5IHJlc2V0IHR5cGUKCQkJc3BlY2lhbCA9IGpRdWVyeS5ldmVudC5zcGVjaWFsWyB0eXBlIF0gfHwge307CgoJCQkvLyBoYW5kbGVPYmogaXMgcGFzc2VkIHRvIGFsbCBldmVudCBoYW5kbGVycwoJCQloYW5kbGVPYmogPSBqUXVlcnkuZXh0ZW5kKCB7CgkJCQl0eXBlOiB0eXBlLAoJCQkJb3JpZ1R5cGU6IG9yaWdUeXBlLAoJCQkJZGF0YTogZGF0YSwKCQkJCWhhbmRsZXI6IGhhbmRsZXIsCgkJCQlndWlkOiBoYW5kbGVyLmd1aWQsCgkJCQlzZWxlY3Rvcjogc2VsZWN0b3IsCgkJCQluZWVkc0NvbnRleHQ6IHNlbGVjdG9yICYmIGpRdWVyeS5leHByLm1hdGNoLm5lZWRzQ29udGV4dC50ZXN0KCBzZWxlY3RvciApLAoJCQkJbmFtZXNwYWNlOiBuYW1lc3BhY2VzLmpvaW4oICIuIiApCgkJCX0sIGhhbmRsZU9iakluICk7CgoJCQkvLyBJbml0IHRoZSBldmVudCBoYW5kbGVyIHF1ZXVlIGlmIHdlJ3JlIHRoZSBmaXJzdAoJCQlpZiAoICEoIGhhbmRsZXJzID0gZXZlbnRzWyB0eXBlIF0gKSApIHsKCQkJCWhhbmRsZXJzID0gZXZlbnRzWyB0eXBlIF0gPSBbXTsKCQkJCWhhbmRsZXJzLmRlbGVnYXRlQ291bnQgPSAwOwoKCQkJCS8vIE9ubHkgdXNlIGFkZEV2ZW50TGlzdGVuZXIgaWYgdGhlIHNwZWNpYWwgZXZlbnRzIGhhbmRsZXIgcmV0dXJucyBmYWxzZQoJCQkJaWYgKCAhc3BlY2lhbC5zZXR1cCB8fAoJCQkJCXNwZWNpYWwuc2V0dXAuY2FsbCggZWxlbSwgZGF0YSwgbmFtZXNwYWNlcywgZXZlbnRIYW5kbGUgKSA9PT0gZmFsc2UgKSB7CgoJCQkJCWlmICggZWxlbS5hZGRFdmVudExpc3RlbmVyICkgewoJCQkJCQllbGVtLmFkZEV2ZW50TGlzdGVuZXIoIHR5cGUsIGV2ZW50SGFuZGxlICk7CgkJCQkJfQoJCQkJfQoJCQl9CgoJCQlpZiAoIHNwZWNpYWwuYWRkICkgewoJCQkJc3BlY2lhbC5hZGQuY2FsbCggZWxlbSwgaGFuZGxlT2JqICk7CgoJCQkJaWYgKCAhaGFuZGxlT2JqLmhhbmRsZXIuZ3VpZCApIHsKCQkJCQloYW5kbGVPYmouaGFuZGxlci5ndWlkID0gaGFuZGxlci5ndWlkOwoJCQkJfQoJCQl9CgoJCQkvLyBBZGQgdG8gdGhlIGVsZW1lbnQncyBoYW5kbGVyIGxpc3QsIGRlbGVnYXRlcyBpbiBmcm9udAoJCQlpZiAoIHNlbGVjdG9yICkgewoJCQkJaGFuZGxlcnMuc3BsaWNlKCBoYW5kbGVycy5kZWxlZ2F0ZUNvdW50KyssIDAsIGhhbmRsZU9iaiApOwoJCQl9IGVsc2UgewoJCQkJaGFuZGxlcnMucHVzaCggaGFuZGxlT2JqICk7CgkJCX0KCgkJCS8vIEtlZXAgdHJhY2sgb2Ygd2hpY2ggZXZlbnRzIGhhdmUgZXZlciBiZWVuIHVzZWQsIGZvciBldmVudCBvcHRpbWl6YXRpb24KCQkJalF1ZXJ5LmV2ZW50Lmdsb2JhbFsgdHlwZSBdID0gdHJ1ZTsKCQl9CgoJfSwKCgkvLyBEZXRhY2ggYW4gZXZlbnQgb3Igc2V0IG9mIGV2ZW50cyBmcm9tIGFuIGVsZW1lbnQKCXJlbW92ZTogZnVuY3Rpb24oIGVsZW0sIHR5cGVzLCBoYW5kbGVyLCBzZWxlY3RvciwgbWFwcGVkVHlwZXMgKSB7CgoJCXZhciBqLCBvcmlnQ291bnQsIHRtcCwKCQkJZXZlbnRzLCB0LCBoYW5kbGVPYmosCgkJCXNwZWNpYWwsIGhhbmRsZXJzLCB0eXBlLCBuYW1lc3BhY2VzLCBvcmlnVHlwZSwKCQkJZWxlbURhdGEgPSBkYXRhUHJpdi5oYXNEYXRhKCBlbGVtICkgJiYgZGF0YVByaXYuZ2V0KCBlbGVtICk7CgoJCWlmICggIWVsZW1EYXRhIHx8ICEoIGV2ZW50cyA9IGVsZW1EYXRhLmV2ZW50cyApICkgewoJCQlyZXR1cm47CgkJfQoKCQkvLyBPbmNlIGZvciBlYWNoIHR5cGUubmFtZXNwYWNlIGluIHR5cGVzOyB0eXBlIG1heSBiZSBvbWl0dGVkCgkJdHlwZXMgPSAoIHR5cGVzIHx8ICIiICkubWF0Y2goIHJub3RodG1sd2hpdGUgKSB8fCBbICIiIF07CgkJdCA9IHR5cGVzLmxlbmd0aDsKCQl3aGlsZSAoIHQtLSApIHsKCQkJdG1wID0gcnR5cGVuYW1lc3BhY2UuZXhlYyggdHlwZXNbIHQgXSApIHx8IFtdOwoJCQl0eXBlID0gb3JpZ1R5cGUgPSB0bXBbIDEgXTsKCQkJbmFtZXNwYWNlcyA9ICggdG1wWyAyIF0gfHwgIiIgKS5zcGxpdCggIi4iICkuc29ydCgpOwoKCQkJLy8gVW5iaW5kIGFsbCBldmVudHMgKG9uIHRoaXMgbmFtZXNwYWNlLCBpZiBwcm92aWRlZCkgZm9yIHRoZSBlbGVtZW50CgkJCWlmICggIXR5cGUgKSB7CgkJCQlmb3IgKCB0eXBlIGluIGV2ZW50cyApIHsKCQkJCQlqUXVlcnkuZXZlbnQucmVtb3ZlKCBlbGVtLCB0eXBlICsgdHlwZXNbIHQgXSwgaGFuZGxlciwgc2VsZWN0b3IsIHRydWUgKTsKCQkJCX0KCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQlzcGVjaWFsID0galF1ZXJ5LmV2ZW50LnNwZWNpYWxbIHR5cGUgXSB8fCB7fTsKCQkJdHlwZSA9ICggc2VsZWN0b3IgPyBzcGVjaWFsLmRlbGVnYXRlVHlwZSA6IHNwZWNpYWwuYmluZFR5cGUgKSB8fCB0eXBlOwoJCQloYW5kbGVycyA9IGV2ZW50c1sgdHlwZSBdIHx8IFtdOwoJCQl0bXAgPSB0bXBbIDIgXSAmJgoJCQkJbmV3IFJlZ0V4cCggIihefFxcLikiICsgbmFtZXNwYWNlcy5qb2luKCAiXFwuKD86LipcXC58KSIgKSArICIoXFwufCQpIiApOwoKCQkJLy8gUmVtb3ZlIG1hdGNoaW5nIGV2ZW50cwoJCQlvcmlnQ291bnQgPSBqID0gaGFuZGxlcnMubGVuZ3RoOwoJCQl3aGlsZSAoIGotLSApIHsKCQkJCWhhbmRsZU9iaiA9IGhhbmRsZXJzWyBqIF07CgoJCQkJaWYgKCAoIG1hcHBlZFR5cGVzIHx8IG9yaWdUeXBlID09PSBoYW5kbGVPYmoub3JpZ1R5cGUgKSAmJgoJCQkJCSggIWhhbmRsZXIgfHwgaGFuZGxlci5ndWlkID09PSBoYW5kbGVPYmouZ3VpZCApICYmCgkJCQkJKCAhdG1wIHx8IHRtcC50ZXN0KCBoYW5kbGVPYmoubmFtZXNwYWNlICkgKSAmJgoJCQkJCSggIXNlbGVjdG9yIHx8IHNlbGVjdG9yID09PSBoYW5kbGVPYmouc2VsZWN0b3IgfHwKCQkJCQkJc2VsZWN0b3IgPT09ICIqKiIgJiYgaGFuZGxlT2JqLnNlbGVjdG9yICkgKSB7CgkJCQkJaGFuZGxlcnMuc3BsaWNlKCBqLCAxICk7CgoJCQkJCWlmICggaGFuZGxlT2JqLnNlbGVjdG9yICkgewoJCQkJCQloYW5kbGVycy5kZWxlZ2F0ZUNvdW50LS07CgkJCQkJfQoJCQkJCWlmICggc3BlY2lhbC5yZW1vdmUgKSB7CgkJCQkJCXNwZWNpYWwucmVtb3ZlLmNhbGwoIGVsZW0sIGhhbmRsZU9iaiApOwoJCQkJCX0KCQkJCX0KCQkJfQoKCQkJLy8gUmVtb3ZlIGdlbmVyaWMgZXZlbnQgaGFuZGxlciBpZiB3ZSByZW1vdmVkIHNvbWV0aGluZyBhbmQgbm8gbW9yZSBoYW5kbGVycyBleGlzdAoJCQkvLyAoYXZvaWRzIHBvdGVudGlhbCBmb3IgZW5kbGVzcyByZWN1cnNpb24gZHVyaW5nIHJlbW92YWwgb2Ygc3BlY2lhbCBldmVudCBoYW5kbGVycykKCQkJaWYgKCBvcmlnQ291bnQgJiYgIWhhbmRsZXJzLmxlbmd0aCApIHsKCQkJCWlmICggIXNwZWNpYWwudGVhcmRvd24gfHwKCQkJCQlzcGVjaWFsLnRlYXJkb3duLmNhbGwoIGVsZW0sIG5hbWVzcGFjZXMsIGVsZW1EYXRhLmhhbmRsZSApID09PSBmYWxzZSApIHsKCgkJCQkJalF1ZXJ5LnJlbW92ZUV2ZW50KCBlbGVtLCB0eXBlLCBlbGVtRGF0YS5oYW5kbGUgKTsKCQkJCX0KCgkJCQlkZWxldGUgZXZlbnRzWyB0eXBlIF07CgkJCX0KCQl9CgoJCS8vIFJlbW92ZSBkYXRhIGFuZCB0aGUgZXhwYW5kbyBpZiBpdCdzIG5vIGxvbmdlciB1c2VkCgkJaWYgKCBqUXVlcnkuaXNFbXB0eU9iamVjdCggZXZlbnRzICkgKSB7CgkJCWRhdGFQcml2LnJlbW92ZSggZWxlbSwgImhhbmRsZSBldmVudHMiICk7CgkJfQoJfSwKCglkaXNwYXRjaDogZnVuY3Rpb24oIG5hdGl2ZUV2ZW50ICkgewoKCQkvLyBNYWtlIGEgd3JpdGFibGUgalF1ZXJ5LkV2ZW50IGZyb20gdGhlIG5hdGl2ZSBldmVudCBvYmplY3QKCQl2YXIgZXZlbnQgPSBqUXVlcnkuZXZlbnQuZml4KCBuYXRpdmVFdmVudCApOwoKCQl2YXIgaSwgaiwgcmV0LCBtYXRjaGVkLCBoYW5kbGVPYmosIGhhbmRsZXJRdWV1ZSwKCQkJYXJncyA9IG5ldyBBcnJheSggYXJndW1lbnRzLmxlbmd0aCApLAoJCQloYW5kbGVycyA9ICggZGF0YVByaXYuZ2V0KCB0aGlzLCAiZXZlbnRzIiApIHx8IHt9IClbIGV2ZW50LnR5cGUgXSB8fCBbXSwKCQkJc3BlY2lhbCA9IGpRdWVyeS5ldmVudC5zcGVjaWFsWyBldmVudC50eXBlIF0gfHwge307CgoJCS8vIFVzZSB0aGUgZml4LWVkIGpRdWVyeS5FdmVudCByYXRoZXIgdGhhbiB0aGUgKHJlYWQtb25seSkgbmF0aXZlIGV2ZW50CgkJYXJnc1sgMCBdID0gZXZlbnQ7CgoJCWZvciAoIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrICkgewoJCQlhcmdzWyBpIF0gPSBhcmd1bWVudHNbIGkgXTsKCQl9CgoJCWV2ZW50LmRlbGVnYXRlVGFyZ2V0ID0gdGhpczsKCgkJLy8gQ2FsbCB0aGUgcHJlRGlzcGF0Y2ggaG9vayBmb3IgdGhlIG1hcHBlZCB0eXBlLCBhbmQgbGV0IGl0IGJhaWwgaWYgZGVzaXJlZAoJCWlmICggc3BlY2lhbC5wcmVEaXNwYXRjaCAmJiBzcGVjaWFsLnByZURpc3BhdGNoLmNhbGwoIHRoaXMsIGV2ZW50ICkgPT09IGZhbHNlICkgewoJCQlyZXR1cm47CgkJfQoKCQkvLyBEZXRlcm1pbmUgaGFuZGxlcnMKCQloYW5kbGVyUXVldWUgPSBqUXVlcnkuZXZlbnQuaGFuZGxlcnMuY2FsbCggdGhpcywgZXZlbnQsIGhhbmRsZXJzICk7CgoJCS8vIFJ1biBkZWxlZ2F0ZXMgZmlyc3Q7IHRoZXkgbWF5IHdhbnQgdG8gc3RvcCBwcm9wYWdhdGlvbiBiZW5lYXRoIHVzCgkJaSA9IDA7CgkJd2hpbGUgKCAoIG1hdGNoZWQgPSBoYW5kbGVyUXVldWVbIGkrKyBdICkgJiYgIWV2ZW50LmlzUHJvcGFnYXRpb25TdG9wcGVkKCkgKSB7CgkJCWV2ZW50LmN1cnJlbnRUYXJnZXQgPSBtYXRjaGVkLmVsZW07CgoJCQlqID0gMDsKCQkJd2hpbGUgKCAoIGhhbmRsZU9iaiA9IG1hdGNoZWQuaGFuZGxlcnNbIGorKyBdICkgJiYKCQkJCSFldmVudC5pc0ltbWVkaWF0ZVByb3BhZ2F0aW9uU3RvcHBlZCgpICkgewoKCQkJCS8vIFRyaWdnZXJlZCBldmVudCBtdXN0IGVpdGhlciAxKSBoYXZlIG5vIG5hbWVzcGFjZSwgb3IgMikgaGF2ZSBuYW1lc3BhY2UocykKCQkJCS8vIGEgc3Vic2V0IG9yIGVxdWFsIHRvIHRob3NlIGluIHRoZSBib3VuZCBldmVudCAoYm90aCBjYW4gaGF2ZSBubyBuYW1lc3BhY2UpLgoJCQkJaWYgKCAhZXZlbnQucm5hbWVzcGFjZSB8fCBldmVudC5ybmFtZXNwYWNlLnRlc3QoIGhhbmRsZU9iai5uYW1lc3BhY2UgKSApIHsKCgkJCQkJZXZlbnQuaGFuZGxlT2JqID0gaGFuZGxlT2JqOwoJCQkJCWV2ZW50LmRhdGEgPSBoYW5kbGVPYmouZGF0YTsKCgkJCQkJcmV0ID0gKCAoIGpRdWVyeS5ldmVudC5zcGVjaWFsWyBoYW5kbGVPYmoub3JpZ1R5cGUgXSB8fCB7fSApLmhhbmRsZSB8fAoJCQkJCQloYW5kbGVPYmouaGFuZGxlciApLmFwcGx5KCBtYXRjaGVkLmVsZW0sIGFyZ3MgKTsKCgkJCQkJaWYgKCByZXQgIT09IHVuZGVmaW5lZCApIHsKCQkJCQkJaWYgKCAoIGV2ZW50LnJlc3VsdCA9IHJldCApID09PSBmYWxzZSApIHsKCQkJCQkJCWV2ZW50LnByZXZlbnREZWZhdWx0KCk7CgkJCQkJCQlldmVudC5zdG9wUHJvcGFnYXRpb24oKTsKCQkJCQkJfQoJCQkJCX0KCQkJCX0KCQkJfQoJCX0KCgkJLy8gQ2FsbCB0aGUgcG9zdERpc3BhdGNoIGhvb2sgZm9yIHRoZSBtYXBwZWQgdHlwZQoJCWlmICggc3BlY2lhbC5wb3N0RGlzcGF0Y2ggKSB7CgkJCXNwZWNpYWwucG9zdERpc3BhdGNoLmNhbGwoIHRoaXMsIGV2ZW50ICk7CgkJfQoKCQlyZXR1cm4gZXZlbnQucmVzdWx0OwoJfSwKCgloYW5kbGVyczogZnVuY3Rpb24oIGV2ZW50LCBoYW5kbGVycyApIHsKCQl2YXIgaSwgaGFuZGxlT2JqLCBzZWwsIG1hdGNoZWRIYW5kbGVycywgbWF0Y2hlZFNlbGVjdG9ycywKCQkJaGFuZGxlclF1ZXVlID0gW10sCgkJCWRlbGVnYXRlQ291bnQgPSBoYW5kbGVycy5kZWxlZ2F0ZUNvdW50LAoJCQljdXIgPSBldmVudC50YXJnZXQ7CgoJCS8vIEZpbmQgZGVsZWdhdGUgaGFuZGxlcnMKCQlpZiAoIGRlbGVnYXRlQ291bnQgJiYKCgkJCS8vIFN1cHBvcnQ6IElFIDw9OQoJCQkvLyBCbGFjay1ob2xlIFNWRyA8dXNlPiBpbnN0YW5jZSB0cmVlcyAodHJhYy0xMzE4MCkKCQkJY3VyLm5vZGVUeXBlICYmCgoJCQkvLyBTdXBwb3J0OiBGaXJlZm94IDw9NDIKCQkJLy8gU3VwcHJlc3Mgc3BlYy12aW9sYXRpbmcgY2xpY2tzIGluZGljYXRpbmcgYSBub24tcHJpbWFyeSBwb2ludGVyIGJ1dHRvbiAodHJhYy0zODYxKQoJCQkvLyBodHRwczovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTMtRXZlbnRzLyNldmVudC10eXBlLWNsaWNrCgkJCS8vIFN1cHBvcnQ6IElFIDExIG9ubHkKCQkJLy8gLi4uYnV0IG5vdCBhcnJvdyBrZXkgImNsaWNrcyIgb2YgcmFkaW8gaW5wdXRzLCB3aGljaCBjYW4gaGF2ZSBgYnV0dG9uYCAtMSAoZ2gtMjM0MykKCQkJISggZXZlbnQudHlwZSA9PT0gImNsaWNrIiAmJiBldmVudC5idXR0b24gPj0gMSApICkgewoKCQkJZm9yICggOyBjdXIgIT09IHRoaXM7IGN1ciA9IGN1ci5wYXJlbnROb2RlIHx8IHRoaXMgKSB7CgoJCQkJLy8gRG9uJ3QgY2hlY2sgbm9uLWVsZW1lbnRzICgjMTMyMDgpCgkJCQkvLyBEb24ndCBwcm9jZXNzIGNsaWNrcyBvbiBkaXNhYmxlZCBlbGVtZW50cyAoIzY5MTEsICM4MTY1LCAjMTEzODIsICMxMTc2NCkKCQkJCWlmICggY3VyLm5vZGVUeXBlID09PSAxICYmICEoIGV2ZW50LnR5cGUgPT09ICJjbGljayIgJiYgY3VyLmRpc2FibGVkID09PSB0cnVlICkgKSB7CgkJCQkJbWF0Y2hlZEhhbmRsZXJzID0gW107CgkJCQkJbWF0Y2hlZFNlbGVjdG9ycyA9IHt9OwoJCQkJCWZvciAoIGkgPSAwOyBpIDwgZGVsZWdhdGVDb3VudDsgaSsrICkgewoJCQkJCQloYW5kbGVPYmogPSBoYW5kbGVyc1sgaSBdOwoKCQkJCQkJLy8gRG9uJ3QgY29uZmxpY3Qgd2l0aCBPYmplY3QucHJvdG90eXBlIHByb3BlcnRpZXMgKCMxMzIwMykKCQkJCQkJc2VsID0gaGFuZGxlT2JqLnNlbGVjdG9yICsgIiAiOwoKCQkJCQkJaWYgKCBtYXRjaGVkU2VsZWN0b3JzWyBzZWwgXSA9PT0gdW5kZWZpbmVkICkgewoJCQkJCQkJbWF0Y2hlZFNlbGVjdG9yc1sgc2VsIF0gPSBoYW5kbGVPYmoubmVlZHNDb250ZXh0ID8KCQkJCQkJCQlqUXVlcnkoIHNlbCwgdGhpcyApLmluZGV4KCBjdXIgKSA+IC0xIDoKCQkJCQkJCQlqUXVlcnkuZmluZCggc2VsLCB0aGlzLCBudWxsLCBbIGN1ciBdICkubGVuZ3RoOwoJCQkJCQl9CgkJCQkJCWlmICggbWF0Y2hlZFNlbGVjdG9yc1sgc2VsIF0gKSB7CgkJCQkJCQltYXRjaGVkSGFuZGxlcnMucHVzaCggaGFuZGxlT2JqICk7CgkJCQkJCX0KCQkJCQl9CgkJCQkJaWYgKCBtYXRjaGVkSGFuZGxlcnMubGVuZ3RoICkgewoJCQkJCQloYW5kbGVyUXVldWUucHVzaCggeyBlbGVtOiBjdXIsIGhhbmRsZXJzOiBtYXRjaGVkSGFuZGxlcnMgfSApOwoJCQkJCX0KCQkJCX0KCQkJfQoJCX0KCgkJLy8gQWRkIHRoZSByZW1haW5pbmcgKGRpcmVjdGx5LWJvdW5kKSBoYW5kbGVycwoJCWN1ciA9IHRoaXM7CgkJaWYgKCBkZWxlZ2F0ZUNvdW50IDwgaGFuZGxlcnMubGVuZ3RoICkgewoJCQloYW5kbGVyUXVldWUucHVzaCggeyBlbGVtOiBjdXIsIGhhbmRsZXJzOiBoYW5kbGVycy5zbGljZSggZGVsZWdhdGVDb3VudCApIH0gKTsKCQl9CgoJCXJldHVybiBoYW5kbGVyUXVldWU7Cgl9LAoKCWFkZFByb3A6IGZ1bmN0aW9uKCBuYW1lLCBob29rICkgewoJCU9iamVjdC5kZWZpbmVQcm9wZXJ0eSggalF1ZXJ5LkV2ZW50LnByb3RvdHlwZSwgbmFtZSwgewoJCQllbnVtZXJhYmxlOiB0cnVlLAoJCQljb25maWd1cmFibGU6IHRydWUsCgoJCQlnZXQ6IGlzRnVuY3Rpb24oIGhvb2sgKSA/CgkJCQlmdW5jdGlvbigpIHsKCQkJCQlpZiAoIHRoaXMub3JpZ2luYWxFdmVudCApIHsKCQkJCQkJCXJldHVybiBob29rKCB0aGlzLm9yaWdpbmFsRXZlbnQgKTsKCQkJCQl9CgkJCQl9IDoKCQkJCWZ1bmN0aW9uKCkgewoJCQkJCWlmICggdGhpcy5vcmlnaW5hbEV2ZW50ICkgewoJCQkJCQkJcmV0dXJuIHRoaXMub3JpZ2luYWxFdmVudFsgbmFtZSBdOwoJCQkJCX0KCQkJCX0sCgoJCQlzZXQ6IGZ1bmN0aW9uKCB2YWx1ZSApIHsKCQkJCU9iamVjdC5kZWZpbmVQcm9wZXJ0eSggdGhpcywgbmFtZSwgewoJCQkJCWVudW1lcmFibGU6IHRydWUsCgkJCQkJY29uZmlndXJhYmxlOiB0cnVlLAoJCQkJCXdyaXRhYmxlOiB0cnVlLAoJCQkJCXZhbHVlOiB2YWx1ZQoJCQkJfSApOwoJCQl9CgkJfSApOwoJfSwKCglmaXg6IGZ1bmN0aW9uKCBvcmlnaW5hbEV2ZW50ICkgewoJCXJldHVybiBvcmlnaW5hbEV2ZW50WyBqUXVlcnkuZXhwYW5kbyBdID8KCQkJb3JpZ2luYWxFdmVudCA6CgkJCW5ldyBqUXVlcnkuRXZlbnQoIG9yaWdpbmFsRXZlbnQgKTsKCX0sCgoJc3BlY2lhbDogewoJCWxvYWQ6IHsKCgkJCS8vIFByZXZlbnQgdHJpZ2dlcmVkIGltYWdlLmxvYWQgZXZlbnRzIGZyb20gYnViYmxpbmcgdG8gd2luZG93LmxvYWQKCQkJbm9CdWJibGU6IHRydWUKCQl9LAoJCWZvY3VzOiB7CgoJCQkvLyBGaXJlIG5hdGl2ZSBldmVudCBpZiBwb3NzaWJsZSBzbyBibHVyL2ZvY3VzIHNlcXVlbmNlIGlzIGNvcnJlY3QKCQkJdHJpZ2dlcjogZnVuY3Rpb24oKSB7CgkJCQlpZiAoIHRoaXMgIT09IHNhZmVBY3RpdmVFbGVtZW50KCkgJiYgdGhpcy5mb2N1cyApIHsKCQkJCQl0aGlzLmZvY3VzKCk7CgkJCQkJcmV0dXJuIGZhbHNlOwoJCQkJfQoJCQl9LAoJCQlkZWxlZ2F0ZVR5cGU6ICJmb2N1c2luIgoJCX0sCgkJYmx1cjogewoJCQl0cmlnZ2VyOiBmdW5jdGlvbigpIHsKCQkJCWlmICggdGhpcyA9PT0gc2FmZUFjdGl2ZUVsZW1lbnQoKSAmJiB0aGlzLmJsdXIgKSB7CgkJCQkJdGhpcy5ibHVyKCk7CgkJCQkJcmV0dXJuIGZhbHNlOwoJCQkJfQoJCQl9LAoJCQlkZWxlZ2F0ZVR5cGU6ICJmb2N1c291dCIKCQl9LAoJCWNsaWNrOiB7CgoJCQkvLyBGb3IgY2hlY2tib3gsIGZpcmUgbmF0aXZlIGV2ZW50IHNvIGNoZWNrZWQgc3RhdGUgd2lsbCBiZSByaWdodAoJCQl0cmlnZ2VyOiBmdW5jdGlvbigpIHsKCQkJCWlmICggdGhpcy50eXBlID09PSAiY2hlY2tib3giICYmIHRoaXMuY2xpY2sgJiYgbm9kZU5hbWUoIHRoaXMsICJpbnB1dCIgKSApIHsKCQkJCQl0aGlzLmNsaWNrKCk7CgkJCQkJcmV0dXJuIGZhbHNlOwoJCQkJfQoJCQl9LAoKCQkJLy8gRm9yIGNyb3NzLWJyb3dzZXIgY29uc2lzdGVuY3ksIGRvbid0IGZpcmUgbmF0aXZlIC5jbGljaygpIG9uIGxpbmtzCgkJCV9kZWZhdWx0OiBmdW5jdGlvbiggZXZlbnQgKSB7CgkJCQlyZXR1cm4gbm9kZU5hbWUoIGV2ZW50LnRhcmdldCwgImEiICk7CgkJCX0KCQl9LAoKCQliZWZvcmV1bmxvYWQ6IHsKCQkJcG9zdERpc3BhdGNoOiBmdW5jdGlvbiggZXZlbnQgKSB7CgoJCQkJLy8gU3VwcG9ydDogRmlyZWZveCAyMCsKCQkJCS8vIEZpcmVmb3ggZG9lc24ndCBhbGVydCBpZiB0aGUgcmV0dXJuVmFsdWUgZmllbGQgaXMgbm90IHNldC4KCQkJCWlmICggZXZlbnQucmVzdWx0ICE9PSB1bmRlZmluZWQgJiYgZXZlbnQub3JpZ2luYWxFdmVudCApIHsKCQkJCQlldmVudC5vcmlnaW5hbEV2ZW50LnJldHVyblZhbHVlID0gZXZlbnQucmVzdWx0OwoJCQkJfQoJCQl9CgkJfQoJfQp9OwoKalF1ZXJ5LnJlbW92ZUV2ZW50ID0gZnVuY3Rpb24oIGVsZW0sIHR5cGUsIGhhbmRsZSApIHsKCgkvLyBUaGlzICJpZiIgaXMgbmVlZGVkIGZvciBwbGFpbiBvYmplY3RzCglpZiAoIGVsZW0ucmVtb3ZlRXZlbnRMaXN0ZW5lciApIHsKCQllbGVtLnJlbW92ZUV2ZW50TGlzdGVuZXIoIHR5cGUsIGhhbmRsZSApOwoJfQp9OwoKalF1ZXJ5LkV2ZW50ID0gZnVuY3Rpb24oIHNyYywgcHJvcHMgKSB7CgoJLy8gQWxsb3cgaW5zdGFudGlhdGlvbiB3aXRob3V0IHRoZSAnbmV3JyBrZXl3b3JkCglpZiAoICEoIHRoaXMgaW5zdGFuY2VvZiBqUXVlcnkuRXZlbnQgKSApIHsKCQlyZXR1cm4gbmV3IGpRdWVyeS5FdmVudCggc3JjLCBwcm9wcyApOwoJfQoKCS8vIEV2ZW50IG9iamVjdAoJaWYgKCBzcmMgJiYgc3JjLnR5cGUgKSB7CgkJdGhpcy5vcmlnaW5hbEV2ZW50ID0gc3JjOwoJCXRoaXMudHlwZSA9IHNyYy50eXBlOwoKCQkvLyBFdmVudHMgYnViYmxpbmcgdXAgdGhlIGRvY3VtZW50IG1heSBoYXZlIGJlZW4gbWFya2VkIGFzIHByZXZlbnRlZAoJCS8vIGJ5IGEgaGFuZGxlciBsb3dlciBkb3duIHRoZSB0cmVlOyByZWZsZWN0IHRoZSBjb3JyZWN0IHZhbHVlLgoJCXRoaXMuaXNEZWZhdWx0UHJldmVudGVkID0gc3JjLmRlZmF1bHRQcmV2ZW50ZWQgfHwKCQkJCXNyYy5kZWZhdWx0UHJldmVudGVkID09PSB1bmRlZmluZWQgJiYKCgkJCQkvLyBTdXBwb3J0OiBBbmRyb2lkIDw9Mi4zIG9ubHkKCQkJCXNyYy5yZXR1cm5WYWx1ZSA9PT0gZmFsc2UgPwoJCQlyZXR1cm5UcnVlIDoKCQkJcmV0dXJuRmFsc2U7CgoJCS8vIENyZWF0ZSB0YXJnZXQgcHJvcGVydGllcwoJCS8vIFN1cHBvcnQ6IFNhZmFyaSA8PTYgLSA3IG9ubHkKCQkvLyBUYXJnZXQgc2hvdWxkIG5vdCBiZSBhIHRleHQgbm9kZSAoIzUwNCwgIzEzMTQzKQoJCXRoaXMudGFyZ2V0ID0gKCBzcmMudGFyZ2V0ICYmIHNyYy50YXJnZXQubm9kZVR5cGUgPT09IDMgKSA/CgkJCXNyYy50YXJnZXQucGFyZW50Tm9kZSA6CgkJCXNyYy50YXJnZXQ7CgoJCXRoaXMuY3VycmVudFRhcmdldCA9IHNyYy5jdXJyZW50VGFyZ2V0OwoJCXRoaXMucmVsYXRlZFRhcmdldCA9IHNyYy5yZWxhdGVkVGFyZ2V0OwoKCS8vIEV2ZW50IHR5cGUKCX0gZWxzZSB7CgkJdGhpcy50eXBlID0gc3JjOwoJfQoKCS8vIFB1dCBleHBsaWNpdGx5IHByb3ZpZGVkIHByb3BlcnRpZXMgb250byB0aGUgZXZlbnQgb2JqZWN0CglpZiAoIHByb3BzICkgewoJCWpRdWVyeS5leHRlbmQoIHRoaXMsIHByb3BzICk7Cgl9CgoJLy8gQ3JlYXRlIGEgdGltZXN0YW1wIGlmIGluY29taW5nIGV2ZW50IGRvZXNuJ3QgaGF2ZSBvbmUKCXRoaXMudGltZVN0YW1wID0gc3JjICYmIHNyYy50aW1lU3RhbXAgfHwgRGF0ZS5ub3coKTsKCgkvLyBNYXJrIGl0IGFzIGZpeGVkCgl0aGlzWyBqUXVlcnkuZXhwYW5kbyBdID0gdHJ1ZTsKfTsKCi8vIGpRdWVyeS5FdmVudCBpcyBiYXNlZCBvbiBET00zIEV2ZW50cyBhcyBzcGVjaWZpZWQgYnkgdGhlIEVDTUFTY3JpcHQgTGFuZ3VhZ2UgQmluZGluZwovLyBodHRwczovL3d3dy53My5vcmcvVFIvMjAwMy9XRC1ET00tTGV2ZWwtMy1FdmVudHMtMjAwMzAzMzEvZWNtYS1zY3JpcHQtYmluZGluZy5odG1sCmpRdWVyeS5FdmVudC5wcm90b3R5cGUgPSB7Cgljb25zdHJ1Y3RvcjogalF1ZXJ5LkV2ZW50LAoJaXNEZWZhdWx0UHJldmVudGVkOiByZXR1cm5GYWxzZSwKCWlzUHJvcGFnYXRpb25TdG9wcGVkOiByZXR1cm5GYWxzZSwKCWlzSW1tZWRpYXRlUHJvcGFnYXRpb25TdG9wcGVkOiByZXR1cm5GYWxzZSwKCWlzU2ltdWxhdGVkOiBmYWxzZSwKCglwcmV2ZW50RGVmYXVsdDogZnVuY3Rpb24oKSB7CgkJdmFyIGUgPSB0aGlzLm9yaWdpbmFsRXZlbnQ7CgoJCXRoaXMuaXNEZWZhdWx0UHJldmVudGVkID0gcmV0dXJuVHJ1ZTsKCgkJaWYgKCBlICYmICF0aGlzLmlzU2ltdWxhdGVkICkgewoJCQllLnByZXZlbnREZWZhdWx0KCk7CgkJfQoJfSwKCXN0b3BQcm9wYWdhdGlvbjogZnVuY3Rpb24oKSB7CgkJdmFyIGUgPSB0aGlzLm9yaWdpbmFsRXZlbnQ7CgoJCXRoaXMuaXNQcm9wYWdhdGlvblN0b3BwZWQgPSByZXR1cm5UcnVlOwoKCQlpZiAoIGUgJiYgIXRoaXMuaXNTaW11bGF0ZWQgKSB7CgkJCWUuc3RvcFByb3BhZ2F0aW9uKCk7CgkJfQoJfSwKCXN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbjogZnVuY3Rpb24oKSB7CgkJdmFyIGUgPSB0aGlzLm9yaWdpbmFsRXZlbnQ7CgoJCXRoaXMuaXNJbW1lZGlhdGVQcm9wYWdhdGlvblN0b3BwZWQgPSByZXR1cm5UcnVlOwoKCQlpZiAoIGUgJiYgIXRoaXMuaXNTaW11bGF0ZWQgKSB7CgkJCWUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7CgkJfQoKCQl0aGlzLnN0b3BQcm9wYWdhdGlvbigpOwoJfQp9OwoKLy8gSW5jbHVkZXMgYWxsIGNvbW1vbiBldmVudCBwcm9wcyBpbmNsdWRpbmcgS2V5RXZlbnQgYW5kIE1vdXNlRXZlbnQgc3BlY2lmaWMgcHJvcHMKalF1ZXJ5LmVhY2goIHsKCWFsdEtleTogdHJ1ZSwKCWJ1YmJsZXM6IHRydWUsCgljYW5jZWxhYmxlOiB0cnVlLAoJY2hhbmdlZFRvdWNoZXM6IHRydWUsCgljdHJsS2V5OiB0cnVlLAoJZGV0YWlsOiB0cnVlLAoJZXZlbnRQaGFzZTogdHJ1ZSwKCW1ldGFLZXk6IHRydWUsCglwYWdlWDogdHJ1ZSwKCXBhZ2VZOiB0cnVlLAoJc2hpZnRLZXk6IHRydWUsCgl2aWV3OiB0cnVlLAoJImNoYXIiOiB0cnVlLAoJY2hhckNvZGU6IHRydWUsCglrZXk6IHRydWUsCglrZXlDb2RlOiB0cnVlLAoJYnV0dG9uOiB0cnVlLAoJYnV0dG9uczogdHJ1ZSwKCWNsaWVudFg6IHRydWUsCgljbGllbnRZOiB0cnVlLAoJb2Zmc2V0WDogdHJ1ZSwKCW9mZnNldFk6IHRydWUsCglwb2ludGVySWQ6IHRydWUsCglwb2ludGVyVHlwZTogdHJ1ZSwKCXNjcmVlblg6IHRydWUsCglzY3JlZW5ZOiB0cnVlLAoJdGFyZ2V0VG91Y2hlczogdHJ1ZSwKCXRvRWxlbWVudDogdHJ1ZSwKCXRvdWNoZXM6IHRydWUsCgoJd2hpY2g6IGZ1bmN0aW9uKCBldmVudCApIHsKCQl2YXIgYnV0dG9uID0gZXZlbnQuYnV0dG9uOwoKCQkvLyBBZGQgd2hpY2ggZm9yIGtleSBldmVudHMKCQlpZiAoIGV2ZW50LndoaWNoID09IG51bGwgJiYgcmtleUV2ZW50LnRlc3QoIGV2ZW50LnR5cGUgKSApIHsKCQkJcmV0dXJuIGV2ZW50LmNoYXJDb2RlICE9IG51bGwgPyBldmVudC5jaGFyQ29kZSA6IGV2ZW50LmtleUNvZGU7CgkJfQoKCQkvLyBBZGQgd2hpY2ggZm9yIGNsaWNrOiAxID09PSBsZWZ0OyAyID09PSBtaWRkbGU7IDMgPT09IHJpZ2h0CgkJaWYgKCAhZXZlbnQud2hpY2ggJiYgYnV0dG9uICE9PSB1bmRlZmluZWQgJiYgcm1vdXNlRXZlbnQudGVzdCggZXZlbnQudHlwZSApICkgewoJCQlpZiAoIGJ1dHRvbiAmIDEgKSB7CgkJCQlyZXR1cm4gMTsKCQkJfQoKCQkJaWYgKCBidXR0b24gJiAyICkgewoJCQkJcmV0dXJuIDM7CgkJCX0KCgkJCWlmICggYnV0dG9uICYgNCApIHsKCQkJCXJldHVybiAyOwoJCQl9CgoJCQlyZXR1cm4gMDsKCQl9CgoJCXJldHVybiBldmVudC53aGljaDsKCX0KfSwgalF1ZXJ5LmV2ZW50LmFkZFByb3AgKTsKCi8vIENyZWF0ZSBtb3VzZWVudGVyL2xlYXZlIGV2ZW50cyB1c2luZyBtb3VzZW92ZXIvb3V0IGFuZCBldmVudC10aW1lIGNoZWNrcwovLyBzbyB0aGF0IGV2ZW50IGRlbGVnYXRpb24gd29ya3MgaW4galF1ZXJ5LgovLyBEbyB0aGUgc2FtZSBmb3IgcG9pbnRlcmVudGVyL3BvaW50ZXJsZWF2ZSBhbmQgcG9pbnRlcm92ZXIvcG9pbnRlcm91dAovLwovLyBTdXBwb3J0OiBTYWZhcmkgNyBvbmx5Ci8vIFNhZmFyaSBzZW5kcyBtb3VzZWVudGVyIHRvbyBvZnRlbjsgc2VlOgovLyBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvY2hyb21pdW0vaXNzdWVzL2RldGFpbD9pZD00NzAyNTgKLy8gZm9yIHRoZSBkZXNjcmlwdGlvbiBvZiB0aGUgYnVnIChpdCBleGlzdGVkIGluIG9sZGVyIENocm9tZSB2ZXJzaW9ucyBhcyB3ZWxsKS4KalF1ZXJ5LmVhY2goIHsKCW1vdXNlZW50ZXI6ICJtb3VzZW92ZXIiLAoJbW91c2VsZWF2ZTogIm1vdXNlb3V0IiwKCXBvaW50ZXJlbnRlcjogInBvaW50ZXJvdmVyIiwKCXBvaW50ZXJsZWF2ZTogInBvaW50ZXJvdXQiCn0sIGZ1bmN0aW9uKCBvcmlnLCBmaXggKSB7CglqUXVlcnkuZXZlbnQuc3BlY2lhbFsgb3JpZyBdID0gewoJCWRlbGVnYXRlVHlwZTogZml4LAoJCWJpbmRUeXBlOiBmaXgsCgoJCWhhbmRsZTogZnVuY3Rpb24oIGV2ZW50ICkgewoJCQl2YXIgcmV0LAoJCQkJdGFyZ2V0ID0gdGhpcywKCQkJCXJlbGF0ZWQgPSBldmVudC5yZWxhdGVkVGFyZ2V0LAoJCQkJaGFuZGxlT2JqID0gZXZlbnQuaGFuZGxlT2JqOwoKCQkJLy8gRm9yIG1vdXNlZW50ZXIvbGVhdmUgY2FsbCB0aGUgaGFuZGxlciBpZiByZWxhdGVkIGlzIG91dHNpZGUgdGhlIHRhcmdldC4KCQkJLy8gTkI6IE5vIHJlbGF0ZWRUYXJnZXQgaWYgdGhlIG1vdXNlIGxlZnQvZW50ZXJlZCB0aGUgYnJvd3NlciB3aW5kb3cKCQkJaWYgKCAhcmVsYXRlZCB8fCAoIHJlbGF0ZWQgIT09IHRhcmdldCAmJiAhalF1ZXJ5LmNvbnRhaW5zKCB0YXJnZXQsIHJlbGF0ZWQgKSApICkgewoJCQkJZXZlbnQudHlwZSA9IGhhbmRsZU9iai5vcmlnVHlwZTsKCQkJCXJldCA9IGhhbmRsZU9iai5oYW5kbGVyLmFwcGx5KCB0aGlzLCBhcmd1bWVudHMgKTsKCQkJCWV2ZW50LnR5cGUgPSBmaXg7CgkJCX0KCQkJcmV0dXJuIHJldDsKCQl9Cgl9Owp9ICk7CgpqUXVlcnkuZm4uZXh0ZW5kKCB7CgoJb246IGZ1bmN0aW9uKCB0eXBlcywgc2VsZWN0b3IsIGRhdGEsIGZuICkgewoJCXJldHVybiBvbiggdGhpcywgdHlwZXMsIHNlbGVjdG9yLCBkYXRhLCBmbiApOwoJfSwKCW9uZTogZnVuY3Rpb24oIHR5cGVzLCBzZWxlY3RvciwgZGF0YSwgZm4gKSB7CgkJcmV0dXJuIG9uKCB0aGlzLCB0eXBlcywgc2VsZWN0b3IsIGRhdGEsIGZuLCAxICk7Cgl9LAoJb2ZmOiBmdW5jdGlvbiggdHlwZXMsIHNlbGVjdG9yLCBmbiApIHsKCQl2YXIgaGFuZGxlT2JqLCB0eXBlOwoJCWlmICggdHlwZXMgJiYgdHlwZXMucHJldmVudERlZmF1bHQgJiYgdHlwZXMuaGFuZGxlT2JqICkgewoKCQkJLy8gKCBldmVudCApICBkaXNwYXRjaGVkIGpRdWVyeS5FdmVudAoJCQloYW5kbGVPYmogPSB0eXBlcy5oYW5kbGVPYmo7CgkJCWpRdWVyeSggdHlwZXMuZGVsZWdhdGVUYXJnZXQgKS5vZmYoCgkJCQloYW5kbGVPYmoubmFtZXNwYWNlID8KCQkJCQloYW5kbGVPYmoub3JpZ1R5cGUgKyAiLiIgKyBoYW5kbGVPYmoubmFtZXNwYWNlIDoKCQkJCQloYW5kbGVPYmoub3JpZ1R5cGUsCgkJCQloYW5kbGVPYmouc2VsZWN0b3IsCgkJCQloYW5kbGVPYmouaGFuZGxlcgoJCQkpOwoJCQlyZXR1cm4gdGhpczsKCQl9CgkJaWYgKCB0eXBlb2YgdHlwZXMgPT09ICJvYmplY3QiICkgewoKCQkJLy8gKCB0eXBlcy1vYmplY3QgWywgc2VsZWN0b3JdICkKCQkJZm9yICggdHlwZSBpbiB0eXBlcyApIHsKCQkJCXRoaXMub2ZmKCB0eXBlLCBzZWxlY3RvciwgdHlwZXNbIHR5cGUgXSApOwoJCQl9CgkJCXJldHVybiB0aGlzOwoJCX0KCQlpZiAoIHNlbGVjdG9yID09PSBmYWxzZSB8fCB0eXBlb2Ygc2VsZWN0b3IgPT09ICJmdW5jdGlvbiIgKSB7CgoJCQkvLyAoIHR5cGVzIFssIGZuXSApCgkJCWZuID0gc2VsZWN0b3I7CgkJCXNlbGVjdG9yID0gdW5kZWZpbmVkOwoJCX0KCQlpZiAoIGZuID09PSBmYWxzZSApIHsKCQkJZm4gPSByZXR1cm5GYWxzZTsKCQl9CgkJcmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24oKSB7CgkJCWpRdWVyeS5ldmVudC5yZW1vdmUoIHRoaXMsIHR5cGVzLCBmbiwgc2VsZWN0b3IgKTsKCQl9ICk7Cgl9Cn0gKTsKCgp2YXIKCgkvKiBlc2xpbnQtZGlzYWJsZSBtYXgtbGVuICovCgoJLy8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9lc2xpbnQvZXNsaW50L2lzc3Vlcy8zMjI5CglyeGh0bWxUYWcgPSAvPCg/IWFyZWF8YnJ8Y29sfGVtYmVkfGhyfGltZ3xpbnB1dHxsaW5rfG1ldGF8cGFyYW0pKChbYS16XVteXC9cMD5ceDIwXHRcclxuXGZdKilbXj5dKilcLz4vZ2ksCgoJLyogZXNsaW50LWVuYWJsZSAqLwoKCS8vIFN1cHBvcnQ6IElFIDw9MTAgLSAxMSwgRWRnZSAxMiAtIDEzIG9ubHkKCS8vIEluIElFL0VkZ2UgdXNpbmcgcmVnZXggZ3JvdXBzIGhlcmUgY2F1c2VzIHNldmVyZSBzbG93ZG93bnMuCgkvLyBTZWUgaHR0cHM6Ly9jb25uZWN0Lm1pY3Jvc29mdC5jb20vSUUvZmVlZGJhY2svZGV0YWlscy8xNzM2NTEyLwoJcm5vSW5uZXJodG1sID0gLzxzY3JpcHR8PHN0eWxlfDxsaW5rL2ksCgoJLy8gY2hlY2tlZD0iY2hlY2tlZCIgb3IgY2hlY2tlZAoJcmNoZWNrZWQgPSAvY2hlY2tlZFxzKig/OltePV18PVxzKi5jaGVja2VkLikvaSwKCXJjbGVhblNjcmlwdCA9IC9eXHMqPCEoPzpcW0NEQVRBXFt8LS0pfCg/OlxdXF18LS0pPlxzKiQvZzsKCi8vIFByZWZlciBhIHRib2R5IG92ZXIgaXRzIHBhcmVudCB0YWJsZSBmb3IgY29udGFpbmluZyBuZXcgcm93cwpmdW5jdGlvbiBtYW5pcHVsYXRpb25UYXJnZXQoIGVsZW0sIGNvbnRlbnQgKSB7CglpZiAoIG5vZGVOYW1lKCBlbGVtLCAidGFibGUiICkgJiYKCQlub2RlTmFtZSggY29udGVudC5ub2RlVHlwZSAhPT0gMTEgPyBjb250ZW50IDogY29udGVudC5maXJzdENoaWxkLCAidHIiICkgKSB7CgoJCXJldHVybiBqUXVlcnkoIGVsZW0gKS5jaGlsZHJlbiggInRib2R5IiApWyAwIF0gfHwgZWxlbTsKCX0KCglyZXR1cm4gZWxlbTsKfQoKLy8gUmVwbGFjZS9yZXN0b3JlIHRoZSB0eXBlIGF0dHJpYnV0ZSBvZiBzY3JpcHQgZWxlbWVudHMgZm9yIHNhZmUgRE9NIG1hbmlwdWxhdGlvbgpmdW5jdGlvbiBkaXNhYmxlU2NyaXB0KCBlbGVtICkgewoJZWxlbS50eXBlID0gKCBlbGVtLmdldEF0dHJpYnV0ZSggInR5cGUiICkgIT09IG51bGwgKSArICIvIiArIGVsZW0udHlwZTsKCXJldHVybiBlbGVtOwp9CmZ1bmN0aW9uIHJlc3RvcmVTY3JpcHQoIGVsZW0gKSB7CglpZiAoICggZWxlbS50eXBlIHx8ICIiICkuc2xpY2UoIDAsIDUgKSA9PT0gInRydWUvIiApIHsKCQllbGVtLnR5cGUgPSBlbGVtLnR5cGUuc2xpY2UoIDUgKTsKCX0gZWxzZSB7CgkJZWxlbS5yZW1vdmVBdHRyaWJ1dGUoICJ0eXBlIiApOwoJfQoKCXJldHVybiBlbGVtOwp9CgpmdW5jdGlvbiBjbG9uZUNvcHlFdmVudCggc3JjLCBkZXN0ICkgewoJdmFyIGksIGwsIHR5cGUsIHBkYXRhT2xkLCBwZGF0YUN1ciwgdWRhdGFPbGQsIHVkYXRhQ3VyLCBldmVudHM7CgoJaWYgKCBkZXN0Lm5vZGVUeXBlICE9PSAxICkgewoJCXJldHVybjsKCX0KCgkvLyAxLiBDb3B5IHByaXZhdGUgZGF0YTogZXZlbnRzLCBoYW5kbGVycywgZXRjLgoJaWYgKCBkYXRhUHJpdi5oYXNEYXRhKCBzcmMgKSApIHsKCQlwZGF0YU9sZCA9IGRhdGFQcml2LmFjY2Vzcyggc3JjICk7CgkJcGRhdGFDdXIgPSBkYXRhUHJpdi5zZXQoIGRlc3QsIHBkYXRhT2xkICk7CgkJZXZlbnRzID0gcGRhdGFPbGQuZXZlbnRzOwoKCQlpZiAoIGV2ZW50cyApIHsKCQkJZGVsZXRlIHBkYXRhQ3VyLmhhbmRsZTsKCQkJcGRhdGFDdXIuZXZlbnRzID0ge307CgoJCQlmb3IgKCB0eXBlIGluIGV2ZW50cyApIHsKCQkJCWZvciAoIGkgPSAwLCBsID0gZXZlbnRzWyB0eXBlIF0ubGVuZ3RoOyBpIDwgbDsgaSsrICkgewoJCQkJCWpRdWVyeS5ldmVudC5hZGQoIGRlc3QsIHR5cGUsIGV2ZW50c1sgdHlwZSBdWyBpIF0gKTsKCQkJCX0KCQkJfQoJCX0KCX0KCgkvLyAyLiBDb3B5IHVzZXIgZGF0YQoJaWYgKCBkYXRhVXNlci5oYXNEYXRhKCBzcmMgKSApIHsKCQl1ZGF0YU9sZCA9IGRhdGFVc2VyLmFjY2Vzcyggc3JjICk7CgkJdWRhdGFDdXIgPSBqUXVlcnkuZXh0ZW5kKCB7fSwgdWRhdGFPbGQgKTsKCgkJZGF0YVVzZXIuc2V0KCBkZXN0LCB1ZGF0YUN1ciApOwoJfQp9CgovLyBGaXggSUUgYnVncywgc2VlIHN1cHBvcnQgdGVzdHMKZnVuY3Rpb24gZml4SW5wdXQoIHNyYywgZGVzdCApIHsKCXZhciBub2RlTmFtZSA9IGRlc3Qubm9kZU5hbWUudG9Mb3dlckNhc2UoKTsKCgkvLyBGYWlscyB0byBwZXJzaXN0IHRoZSBjaGVja2VkIHN0YXRlIG9mIGEgY2xvbmVkIGNoZWNrYm94IG9yIHJhZGlvIGJ1dHRvbi4KCWlmICggbm9kZU5hbWUgPT09ICJpbnB1dCIgJiYgcmNoZWNrYWJsZVR5cGUudGVzdCggc3JjLnR5cGUgKSApIHsKCQlkZXN0LmNoZWNrZWQgPSBzcmMuY2hlY2tlZDsKCgkvLyBGYWlscyB0byByZXR1cm4gdGhlIHNlbGVjdGVkIG9wdGlvbiB0byB0aGUgZGVmYXVsdCBzZWxlY3RlZCBzdGF0ZSB3aGVuIGNsb25pbmcgb3B0aW9ucwoJfSBlbHNlIGlmICggbm9kZU5hbWUgPT09ICJpbnB1dCIgfHwgbm9kZU5hbWUgPT09ICJ0ZXh0YXJlYSIgKSB7CgkJZGVzdC5kZWZhdWx0VmFsdWUgPSBzcmMuZGVmYXVsdFZhbHVlOwoJfQp9CgpmdW5jdGlvbiBkb21NYW5pcCggY29sbGVjdGlvbiwgYXJncywgY2FsbGJhY2ssIGlnbm9yZWQgKSB7CgoJLy8gRmxhdHRlbiBhbnkgbmVzdGVkIGFycmF5cwoJYXJncyA9IGNvbmNhdC5hcHBseSggW10sIGFyZ3MgKTsKCgl2YXIgZnJhZ21lbnQsIGZpcnN0LCBzY3JpcHRzLCBoYXNTY3JpcHRzLCBub2RlLCBkb2MsCgkJaSA9IDAsCgkJbCA9IGNvbGxlY3Rpb24ubGVuZ3RoLAoJCWlOb0Nsb25lID0gbCAtIDEsCgkJdmFsdWUgPSBhcmdzWyAwIF0sCgkJdmFsdWVJc0Z1bmN0aW9uID0gaXNGdW5jdGlvbiggdmFsdWUgKTsKCgkvLyBXZSBjYW4ndCBjbG9uZU5vZGUgZnJhZ21lbnRzIHRoYXQgY29udGFpbiBjaGVja2VkLCBpbiBXZWJLaXQKCWlmICggdmFsdWVJc0Z1bmN0aW9uIHx8CgkJCSggbCA+IDEgJiYgdHlwZW9mIHZhbHVlID09PSAic3RyaW5nIiAmJgoJCQkJIXN1cHBvcnQuY2hlY2tDbG9uZSAmJiByY2hlY2tlZC50ZXN0KCB2YWx1ZSApICkgKSB7CgkJcmV0dXJuIGNvbGxlY3Rpb24uZWFjaCggZnVuY3Rpb24oIGluZGV4ICkgewoJCQl2YXIgc2VsZiA9IGNvbGxlY3Rpb24uZXEoIGluZGV4ICk7CgkJCWlmICggdmFsdWVJc0Z1bmN0aW9uICkgewoJCQkJYXJnc1sgMCBdID0gdmFsdWUuY2FsbCggdGhpcywgaW5kZXgsIHNlbGYuaHRtbCgpICk7CgkJCX0KCQkJZG9tTWFuaXAoIHNlbGYsIGFyZ3MsIGNhbGxiYWNrLCBpZ25vcmVkICk7CgkJfSApOwoJfQoKCWlmICggbCApIHsKCQlmcmFnbWVudCA9IGJ1aWxkRnJhZ21lbnQoIGFyZ3MsIGNvbGxlY3Rpb25bIDAgXS5vd25lckRvY3VtZW50LCBmYWxzZSwgY29sbGVjdGlvbiwgaWdub3JlZCApOwoJCWZpcnN0ID0gZnJhZ21lbnQuZmlyc3RDaGlsZDsKCgkJaWYgKCBmcmFnbWVudC5jaGlsZE5vZGVzLmxlbmd0aCA9PT0gMSApIHsKCQkJZnJhZ21lbnQgPSBmaXJzdDsKCQl9CgoJCS8vIFJlcXVpcmUgZWl0aGVyIG5ldyBjb250ZW50IG9yIGFuIGludGVyZXN0IGluIGlnbm9yZWQgZWxlbWVudHMgdG8gaW52b2tlIHRoZSBjYWxsYmFjawoJCWlmICggZmlyc3QgfHwgaWdub3JlZCApIHsKCQkJc2NyaXB0cyA9IGpRdWVyeS5tYXAoIGdldEFsbCggZnJhZ21lbnQsICJzY3JpcHQiICksIGRpc2FibGVTY3JpcHQgKTsKCQkJaGFzU2NyaXB0cyA9IHNjcmlwdHMubGVuZ3RoOwoKCQkJLy8gVXNlIHRoZSBvcmlnaW5hbCBmcmFnbWVudCBmb3IgdGhlIGxhc3QgaXRlbQoJCQkvLyBpbnN0ZWFkIG9mIHRoZSBmaXJzdCBiZWNhdXNlIGl0IGNhbiBlbmQgdXAKCQkJLy8gYmVpbmcgZW1wdGllZCBpbmNvcnJlY3RseSBpbiBjZXJ0YWluIHNpdHVhdGlvbnMgKCM4MDcwKS4KCQkJZm9yICggOyBpIDwgbDsgaSsrICkgewoJCQkJbm9kZSA9IGZyYWdtZW50OwoKCQkJCWlmICggaSAhPT0gaU5vQ2xvbmUgKSB7CgkJCQkJbm9kZSA9IGpRdWVyeS5jbG9uZSggbm9kZSwgdHJ1ZSwgdHJ1ZSApOwoKCQkJCQkvLyBLZWVwIHJlZmVyZW5jZXMgdG8gY2xvbmVkIHNjcmlwdHMgZm9yIGxhdGVyIHJlc3RvcmF0aW9uCgkJCQkJaWYgKCBoYXNTY3JpcHRzICkgewoKCQkJCQkJLy8gU3VwcG9ydDogQW5kcm9pZCA8PTQuMCBvbmx5LCBQaGFudG9tSlMgMSBvbmx5CgkJCQkJCS8vIHB1c2guYXBwbHkoXywgYXJyYXlsaWtlKSB0aHJvd3Mgb24gYW5jaWVudCBXZWJLaXQKCQkJCQkJalF1ZXJ5Lm1lcmdlKCBzY3JpcHRzLCBnZXRBbGwoIG5vZGUsICJzY3JpcHQiICkgKTsKCQkJCQl9CgkJCQl9CgoJCQkJY2FsbGJhY2suY2FsbCggY29sbGVjdGlvblsgaSBdLCBub2RlLCBpICk7CgkJCX0KCgkJCWlmICggaGFzU2NyaXB0cyApIHsKCQkJCWRvYyA9IHNjcmlwdHNbIHNjcmlwdHMubGVuZ3RoIC0gMSBdLm93bmVyRG9jdW1lbnQ7CgoJCQkJLy8gUmVlbmFibGUgc2NyaXB0cwoJCQkJalF1ZXJ5Lm1hcCggc2NyaXB0cywgcmVzdG9yZVNjcmlwdCApOwoKCQkJCS8vIEV2YWx1YXRlIGV4ZWN1dGFibGUgc2NyaXB0cyBvbiBmaXJzdCBkb2N1bWVudCBpbnNlcnRpb24KCQkJCWZvciAoIGkgPSAwOyBpIDwgaGFzU2NyaXB0czsgaSsrICkgewoJCQkJCW5vZGUgPSBzY3JpcHRzWyBpIF07CgkJCQkJaWYgKCByc2NyaXB0VHlwZS50ZXN0KCBub2RlLnR5cGUgfHwgIiIgKSAmJgoJCQkJCQkhZGF0YVByaXYuYWNjZXNzKCBub2RlLCAiZ2xvYmFsRXZhbCIgKSAmJgoJCQkJCQlqUXVlcnkuY29udGFpbnMoIGRvYywgbm9kZSApICkgewoKCQkJCQkJaWYgKCBub2RlLnNyYyAmJiAoIG5vZGUudHlwZSB8fCAiIiApLnRvTG93ZXJDYXNlKCkgICE9PSAibW9kdWxlIiApIHsKCgkJCQkJCQkvLyBPcHRpb25hbCBBSkFYIGRlcGVuZGVuY3ksIGJ1dCB3b24ndCBydW4gc2NyaXB0cyBpZiBub3QgcHJlc2VudAoJCQkJCQkJaWYgKCBqUXVlcnkuX2V2YWxVcmwgKSB7CgkJCQkJCQkJalF1ZXJ5Ll9ldmFsVXJsKCBub2RlLnNyYyApOwoJCQkJCQkJfQoJCQkJCQl9IGVsc2UgewoJCQkJCQkJRE9NRXZhbCggbm9kZS50ZXh0Q29udGVudC5yZXBsYWNlKCByY2xlYW5TY3JpcHQsICIiICksIGRvYywgbm9kZSApOwoJCQkJCQl9CgkJCQkJfQoJCQkJfQoJCQl9CgkJfQoJfQoKCXJldHVybiBjb2xsZWN0aW9uOwp9CgpmdW5jdGlvbiByZW1vdmUoIGVsZW0sIHNlbGVjdG9yLCBrZWVwRGF0YSApIHsKCXZhciBub2RlLAoJCW5vZGVzID0gc2VsZWN0b3IgPyBqUXVlcnkuZmlsdGVyKCBzZWxlY3RvciwgZWxlbSApIDogZWxlbSwKCQlpID0gMDsKCglmb3IgKCA7ICggbm9kZSA9IG5vZGVzWyBpIF0gKSAhPSBudWxsOyBpKysgKSB7CgkJaWYgKCAha2VlcERhdGEgJiYgbm9kZS5ub2RlVHlwZSA9PT0gMSApIHsKCQkJalF1ZXJ5LmNsZWFuRGF0YSggZ2V0QWxsKCBub2RlICkgKTsKCQl9CgoJCWlmICggbm9kZS5wYXJlbnROb2RlICkgewoJCQlpZiAoIGtlZXBEYXRhICYmIGpRdWVyeS5jb250YWlucyggbm9kZS5vd25lckRvY3VtZW50LCBub2RlICkgKSB7CgkJCQlzZXRHbG9iYWxFdmFsKCBnZXRBbGwoIG5vZGUsICJzY3JpcHQiICkgKTsKCQkJfQoJCQlub2RlLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoIG5vZGUgKTsKCQl9Cgl9CgoJcmV0dXJuIGVsZW07Cn0KCmpRdWVyeS5leHRlbmQoIHsKCWh0bWxQcmVmaWx0ZXI6IGZ1bmN0aW9uKCBodG1sICkgewoJCXJldHVybiBodG1sLnJlcGxhY2UoIHJ4aHRtbFRhZywgIjwkMT48LyQyPiIgKTsKCX0sCgoJY2xvbmU6IGZ1bmN0aW9uKCBlbGVtLCBkYXRhQW5kRXZlbnRzLCBkZWVwRGF0YUFuZEV2ZW50cyApIHsKCQl2YXIgaSwgbCwgc3JjRWxlbWVudHMsIGRlc3RFbGVtZW50cywKCQkJY2xvbmUgPSBlbGVtLmNsb25lTm9kZSggdHJ1ZSApLAoJCQlpblBhZ2UgPSBqUXVlcnkuY29udGFpbnMoIGVsZW0ub3duZXJEb2N1bWVudCwgZWxlbSApOwoKCQkvLyBGaXggSUUgY2xvbmluZyBpc3N1ZXMKCQlpZiAoICFzdXBwb3J0Lm5vQ2xvbmVDaGVja2VkICYmICggZWxlbS5ub2RlVHlwZSA9PT0gMSB8fCBlbGVtLm5vZGVUeXBlID09PSAxMSApICYmCgkJCQkhalF1ZXJ5LmlzWE1MRG9jKCBlbGVtICkgKSB7CgoJCQkvLyBXZSBlc2NoZXcgU2l6emxlIGhlcmUgZm9yIHBlcmZvcm1hbmNlIHJlYXNvbnM6IGh0dHBzOi8vanNwZXJmLmNvbS9nZXRhbGwtdnMtc2l6emxlLzIKCQkJZGVzdEVsZW1lbnRzID0gZ2V0QWxsKCBjbG9uZSApOwoJCQlzcmNFbGVtZW50cyA9IGdldEFsbCggZWxlbSApOwoKCQkJZm9yICggaSA9IDAsIGwgPSBzcmNFbGVtZW50cy5sZW5ndGg7IGkgPCBsOyBpKysgKSB7CgkJCQlmaXhJbnB1dCggc3JjRWxlbWVudHNbIGkgXSwgZGVzdEVsZW1lbnRzWyBpIF0gKTsKCQkJfQoJCX0KCgkJLy8gQ29weSB0aGUgZXZlbnRzIGZyb20gdGhlIG9yaWdpbmFsIHRvIHRoZSBjbG9uZQoJCWlmICggZGF0YUFuZEV2ZW50cyApIHsKCQkJaWYgKCBkZWVwRGF0YUFuZEV2ZW50cyApIHsKCQkJCXNyY0VsZW1lbnRzID0gc3JjRWxlbWVudHMgfHwgZ2V0QWxsKCBlbGVtICk7CgkJCQlkZXN0RWxlbWVudHMgPSBkZXN0RWxlbWVudHMgfHwgZ2V0QWxsKCBjbG9uZSApOwoKCQkJCWZvciAoIGkgPSAwLCBsID0gc3JjRWxlbWVudHMubGVuZ3RoOyBpIDwgbDsgaSsrICkgewoJCQkJCWNsb25lQ29weUV2ZW50KCBzcmNFbGVtZW50c1sgaSBdLCBkZXN0RWxlbWVudHNbIGkgXSApOwoJCQkJfQoJCQl9IGVsc2UgewoJCQkJY2xvbmVDb3B5RXZlbnQoIGVsZW0sIGNsb25lICk7CgkJCX0KCQl9CgoJCS8vIFByZXNlcnZlIHNjcmlwdCBldmFsdWF0aW9uIGhpc3RvcnkKCQlkZXN0RWxlbWVudHMgPSBnZXRBbGwoIGNsb25lLCAic2NyaXB0IiApOwoJCWlmICggZGVzdEVsZW1lbnRzLmxlbmd0aCA+IDAgKSB7CgkJCXNldEdsb2JhbEV2YWwoIGRlc3RFbGVtZW50cywgIWluUGFnZSAmJiBnZXRBbGwoIGVsZW0sICJzY3JpcHQiICkgKTsKCQl9CgoJCS8vIFJldHVybiB0aGUgY2xvbmVkIHNldAoJCXJldHVybiBjbG9uZTsKCX0sCgoJY2xlYW5EYXRhOiBmdW5jdGlvbiggZWxlbXMgKSB7CgkJdmFyIGRhdGEsIGVsZW0sIHR5cGUsCgkJCXNwZWNpYWwgPSBqUXVlcnkuZXZlbnQuc3BlY2lhbCwKCQkJaSA9IDA7CgoJCWZvciAoIDsgKCBlbGVtID0gZWxlbXNbIGkgXSApICE9PSB1bmRlZmluZWQ7IGkrKyApIHsKCQkJaWYgKCBhY2NlcHREYXRhKCBlbGVtICkgKSB7CgkJCQlpZiAoICggZGF0YSA9IGVsZW1bIGRhdGFQcml2LmV4cGFuZG8gXSApICkgewoJCQkJCWlmICggZGF0YS5ldmVudHMgKSB7CgkJCQkJCWZvciAoIHR5cGUgaW4gZGF0YS5ldmVudHMgKSB7CgkJCQkJCQlpZiAoIHNwZWNpYWxbIHR5cGUgXSApIHsKCQkJCQkJCQlqUXVlcnkuZXZlbnQucmVtb3ZlKCBlbGVtLCB0eXBlICk7CgoJCQkJCQkJLy8gVGhpcyBpcyBhIHNob3J0Y3V0IHRvIGF2b2lkIGpRdWVyeS5ldmVudC5yZW1vdmUncyBvdmVyaGVhZAoJCQkJCQkJfSBlbHNlIHsKCQkJCQkJCQlqUXVlcnkucmVtb3ZlRXZlbnQoIGVsZW0sIHR5cGUsIGRhdGEuaGFuZGxlICk7CgkJCQkJCQl9CgkJCQkJCX0KCQkJCQl9CgoJCQkJCS8vIFN1cHBvcnQ6IENocm9tZSA8PTM1IC0gNDUrCgkJCQkJLy8gQXNzaWduIHVuZGVmaW5lZCBpbnN0ZWFkIG9mIHVzaW5nIGRlbGV0ZSwgc2VlIERhdGEjcmVtb3ZlCgkJCQkJZWxlbVsgZGF0YVByaXYuZXhwYW5kbyBdID0gdW5kZWZpbmVkOwoJCQkJfQoJCQkJaWYgKCBlbGVtWyBkYXRhVXNlci5leHBhbmRvIF0gKSB7CgoJCQkJCS8vIFN1cHBvcnQ6IENocm9tZSA8PTM1IC0gNDUrCgkJCQkJLy8gQXNzaWduIHVuZGVmaW5lZCBpbnN0ZWFkIG9mIHVzaW5nIGRlbGV0ZSwgc2VlIERhdGEjcmVtb3ZlCgkJCQkJZWxlbVsgZGF0YVVzZXIuZXhwYW5kbyBdID0gdW5kZWZpbmVkOwoJCQkJfQoJCQl9CgkJfQoJfQp9ICk7CgpqUXVlcnkuZm4uZXh0ZW5kKCB7CglkZXRhY2g6IGZ1bmN0aW9uKCBzZWxlY3RvciApIHsKCQlyZXR1cm4gcmVtb3ZlKCB0aGlzLCBzZWxlY3RvciwgdHJ1ZSApOwoJfSwKCglyZW1vdmU6IGZ1bmN0aW9uKCBzZWxlY3RvciApIHsKCQlyZXR1cm4gcmVtb3ZlKCB0aGlzLCBzZWxlY3RvciApOwoJfSwKCgl0ZXh0OiBmdW5jdGlvbiggdmFsdWUgKSB7CgkJcmV0dXJuIGFjY2VzcyggdGhpcywgZnVuY3Rpb24oIHZhbHVlICkgewoJCQlyZXR1cm4gdmFsdWUgPT09IHVuZGVmaW5lZCA/CgkJCQlqUXVlcnkudGV4dCggdGhpcyApIDoKCQkJCXRoaXMuZW1wdHkoKS5lYWNoKCBmdW5jdGlvbigpIHsKCQkJCQlpZiAoIHRoaXMubm9kZVR5cGUgPT09IDEgfHwgdGhpcy5ub2RlVHlwZSA9PT0gMTEgfHwgdGhpcy5ub2RlVHlwZSA9PT0gOSApIHsKCQkJCQkJdGhpcy50ZXh0Q29udGVudCA9IHZhbHVlOwoJCQkJCX0KCQkJCX0gKTsKCQl9LCBudWxsLCB2YWx1ZSwgYXJndW1lbnRzLmxlbmd0aCApOwoJfSwKCglhcHBlbmQ6IGZ1bmN0aW9uKCkgewoJCXJldHVybiBkb21NYW5pcCggdGhpcywgYXJndW1lbnRzLCBmdW5jdGlvbiggZWxlbSApIHsKCQkJaWYgKCB0aGlzLm5vZGVUeXBlID09PSAxIHx8IHRoaXMubm9kZVR5cGUgPT09IDExIHx8IHRoaXMubm9kZVR5cGUgPT09IDkgKSB7CgkJCQl2YXIgdGFyZ2V0ID0gbWFuaXB1bGF0aW9uVGFyZ2V0KCB0aGlzLCBlbGVtICk7CgkJCQl0YXJnZXQuYXBwZW5kQ2hpbGQoIGVsZW0gKTsKCQkJfQoJCX0gKTsKCX0sCgoJcHJlcGVuZDogZnVuY3Rpb24oKSB7CgkJcmV0dXJuIGRvbU1hbmlwKCB0aGlzLCBhcmd1bWVudHMsIGZ1bmN0aW9uKCBlbGVtICkgewoJCQlpZiAoIHRoaXMubm9kZVR5cGUgPT09IDEgfHwgdGhpcy5ub2RlVHlwZSA9PT0gMTEgfHwgdGhpcy5ub2RlVHlwZSA9PT0gOSApIHsKCQkJCXZhciB0YXJnZXQgPSBtYW5pcHVsYXRpb25UYXJnZXQoIHRoaXMsIGVsZW0gKTsKCQkJCXRhcmdldC5pbnNlcnRCZWZvcmUoIGVsZW0sIHRhcmdldC5maXJzdENoaWxkICk7CgkJCX0KCQl9ICk7Cgl9LAoKCWJlZm9yZTogZnVuY3Rpb24oKSB7CgkJcmV0dXJuIGRvbU1hbmlwKCB0aGlzLCBhcmd1bWVudHMsIGZ1bmN0aW9uKCBlbGVtICkgewoJCQlpZiAoIHRoaXMucGFyZW50Tm9kZSApIHsKCQkJCXRoaXMucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoIGVsZW0sIHRoaXMgKTsKCQkJfQoJCX0gKTsKCX0sCgoJYWZ0ZXI6IGZ1bmN0aW9uKCkgewoJCXJldHVybiBkb21NYW5pcCggdGhpcywgYXJndW1lbnRzLCBmdW5jdGlvbiggZWxlbSApIHsKCQkJaWYgKCB0aGlzLnBhcmVudE5vZGUgKSB7CgkJCQl0aGlzLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKCBlbGVtLCB0aGlzLm5leHRTaWJsaW5nICk7CgkJCX0KCQl9ICk7Cgl9LAoKCWVtcHR5OiBmdW5jdGlvbigpIHsKCQl2YXIgZWxlbSwKCQkJaSA9IDA7CgoJCWZvciAoIDsgKCBlbGVtID0gdGhpc1sgaSBdICkgIT0gbnVsbDsgaSsrICkgewoJCQlpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDEgKSB7CgoJCQkJLy8gUHJldmVudCBtZW1vcnkgbGVha3MKCQkJCWpRdWVyeS5jbGVhbkRhdGEoIGdldEFsbCggZWxlbSwgZmFsc2UgKSApOwoKCQkJCS8vIFJlbW92ZSBhbnkgcmVtYWluaW5nIG5vZGVzCgkJCQllbGVtLnRleHRDb250ZW50ID0gIiI7CgkJCX0KCQl9CgoJCXJldHVybiB0aGlzOwoJfSwKCgljbG9uZTogZnVuY3Rpb24oIGRhdGFBbmRFdmVudHMsIGRlZXBEYXRhQW5kRXZlbnRzICkgewoJCWRhdGFBbmRFdmVudHMgPSBkYXRhQW5kRXZlbnRzID09IG51bGwgPyBmYWxzZSA6IGRhdGFBbmRFdmVudHM7CgkJZGVlcERhdGFBbmRFdmVudHMgPSBkZWVwRGF0YUFuZEV2ZW50cyA9PSBudWxsID8gZGF0YUFuZEV2ZW50cyA6IGRlZXBEYXRhQW5kRXZlbnRzOwoKCQlyZXR1cm4gdGhpcy5tYXAoIGZ1bmN0aW9uKCkgewoJCQlyZXR1cm4galF1ZXJ5LmNsb25lKCB0aGlzLCBkYXRhQW5kRXZlbnRzLCBkZWVwRGF0YUFuZEV2ZW50cyApOwoJCX0gKTsKCX0sCgoJaHRtbDogZnVuY3Rpb24oIHZhbHVlICkgewoJCXJldHVybiBhY2Nlc3MoIHRoaXMsIGZ1bmN0aW9uKCB2YWx1ZSApIHsKCQkJdmFyIGVsZW0gPSB0aGlzWyAwIF0gfHwge30sCgkJCQlpID0gMCwKCQkJCWwgPSB0aGlzLmxlbmd0aDsKCgkJCWlmICggdmFsdWUgPT09IHVuZGVmaW5lZCAmJiBlbGVtLm5vZGVUeXBlID09PSAxICkgewoJCQkJcmV0dXJuIGVsZW0uaW5uZXJIVE1MOwoJCQl9CgoJCQkvLyBTZWUgaWYgd2UgY2FuIHRha2UgYSBzaG9ydGN1dCBhbmQganVzdCB1c2UgaW5uZXJIVE1MCgkJCWlmICggdHlwZW9mIHZhbHVlID09PSAic3RyaW5nIiAmJiAhcm5vSW5uZXJodG1sLnRlc3QoIHZhbHVlICkgJiYKCQkJCSF3cmFwTWFwWyAoIHJ0YWdOYW1lLmV4ZWMoIHZhbHVlICkgfHwgWyAiIiwgIiIgXSApWyAxIF0udG9Mb3dlckNhc2UoKSBdICkgewoKCQkJCXZhbHVlID0galF1ZXJ5Lmh0bWxQcmVmaWx0ZXIoIHZhbHVlICk7CgoJCQkJdHJ5IHsKCQkJCQlmb3IgKCA7IGkgPCBsOyBpKysgKSB7CgkJCQkJCWVsZW0gPSB0aGlzWyBpIF0gfHwge307CgoJCQkJCQkvLyBSZW1vdmUgZWxlbWVudCBub2RlcyBhbmQgcHJldmVudCBtZW1vcnkgbGVha3MKCQkJCQkJaWYgKCBlbGVtLm5vZGVUeXBlID09PSAxICkgewoJCQkJCQkJalF1ZXJ5LmNsZWFuRGF0YSggZ2V0QWxsKCBlbGVtLCBmYWxzZSApICk7CgkJCQkJCQllbGVtLmlubmVySFRNTCA9IHZhbHVlOwoJCQkJCQl9CgkJCQkJfQoKCQkJCQllbGVtID0gMDsKCgkJCQkvLyBJZiB1c2luZyBpbm5lckhUTUwgdGhyb3dzIGFuIGV4Y2VwdGlvbiwgdXNlIHRoZSBmYWxsYmFjayBtZXRob2QKCQkJCX0gY2F0Y2ggKCBlICkge30KCQkJfQoKCQkJaWYgKCBlbGVtICkgewoJCQkJdGhpcy5lbXB0eSgpLmFwcGVuZCggdmFsdWUgKTsKCQkJfQoJCX0sIG51bGwsIHZhbHVlLCBhcmd1bWVudHMubGVuZ3RoICk7Cgl9LAoKCXJlcGxhY2VXaXRoOiBmdW5jdGlvbigpIHsKCQl2YXIgaWdub3JlZCA9IFtdOwoKCQkvLyBNYWtlIHRoZSBjaGFuZ2VzLCByZXBsYWNpbmcgZWFjaCBub24taWdub3JlZCBjb250ZXh0IGVsZW1lbnQgd2l0aCB0aGUgbmV3IGNvbnRlbnQKCQlyZXR1cm4gZG9tTWFuaXAoIHRoaXMsIGFyZ3VtZW50cywgZnVuY3Rpb24oIGVsZW0gKSB7CgkJCXZhciBwYXJlbnQgPSB0aGlzLnBhcmVudE5vZGU7CgoJCQlpZiAoIGpRdWVyeS5pbkFycmF5KCB0aGlzLCBpZ25vcmVkICkgPCAwICkgewoJCQkJalF1ZXJ5LmNsZWFuRGF0YSggZ2V0QWxsKCB0aGlzICkgKTsKCQkJCWlmICggcGFyZW50ICkgewoJCQkJCXBhcmVudC5yZXBsYWNlQ2hpbGQoIGVsZW0sIHRoaXMgKTsKCQkJCX0KCQkJfQoKCQkvLyBGb3JjZSBjYWxsYmFjayBpbnZvY2F0aW9uCgkJfSwgaWdub3JlZCApOwoJfQp9ICk7CgpqUXVlcnkuZWFjaCggewoJYXBwZW5kVG86ICJhcHBlbmQiLAoJcHJlcGVuZFRvOiAicHJlcGVuZCIsCglpbnNlcnRCZWZvcmU6ICJiZWZvcmUiLAoJaW5zZXJ0QWZ0ZXI6ICJhZnRlciIsCglyZXBsYWNlQWxsOiAicmVwbGFjZVdpdGgiCn0sIGZ1bmN0aW9uKCBuYW1lLCBvcmlnaW5hbCApIHsKCWpRdWVyeS5mblsgbmFtZSBdID0gZnVuY3Rpb24oIHNlbGVjdG9yICkgewoJCXZhciBlbGVtcywKCQkJcmV0ID0gW10sCgkJCWluc2VydCA9IGpRdWVyeSggc2VsZWN0b3IgKSwKCQkJbGFzdCA9IGluc2VydC5sZW5ndGggLSAxLAoJCQlpID0gMDsKCgkJZm9yICggOyBpIDw9IGxhc3Q7IGkrKyApIHsKCQkJZWxlbXMgPSBpID09PSBsYXN0ID8gdGhpcyA6IHRoaXMuY2xvbmUoIHRydWUgKTsKCQkJalF1ZXJ5KCBpbnNlcnRbIGkgXSApWyBvcmlnaW5hbCBdKCBlbGVtcyApOwoKCQkJLy8gU3VwcG9ydDogQW5kcm9pZCA8PTQuMCBvbmx5LCBQaGFudG9tSlMgMSBvbmx5CgkJCS8vIC5nZXQoKSBiZWNhdXNlIHB1c2guYXBwbHkoXywgYXJyYXlsaWtlKSB0aHJvd3Mgb24gYW5jaWVudCBXZWJLaXQKCQkJcHVzaC5hcHBseSggcmV0LCBlbGVtcy5nZXQoKSApOwoJCX0KCgkJcmV0dXJuIHRoaXMucHVzaFN0YWNrKCByZXQgKTsKCX07Cn0gKTsKdmFyIHJudW1ub25weCA9IG5ldyBSZWdFeHAoICJeKCIgKyBwbnVtICsgIikoPyFweClbYS16JV0rJCIsICJpIiApOwoKdmFyIGdldFN0eWxlcyA9IGZ1bmN0aW9uKCBlbGVtICkgewoKCQkvLyBTdXBwb3J0OiBJRSA8PTExIG9ubHksIEZpcmVmb3ggPD0zMCAoIzE1MDk4LCAjMTQxNTApCgkJLy8gSUUgdGhyb3dzIG9uIGVsZW1lbnRzIGNyZWF0ZWQgaW4gcG9wdXBzCgkJLy8gRkYgbWVhbndoaWxlIHRocm93cyBvbiBmcmFtZSBlbGVtZW50cyB0aHJvdWdoICJkZWZhdWx0Vmlldy5nZXRDb21wdXRlZFN0eWxlIgoJCXZhciB2aWV3ID0gZWxlbS5vd25lckRvY3VtZW50LmRlZmF1bHRWaWV3OwoKCQlpZiAoICF2aWV3IHx8ICF2aWV3Lm9wZW5lciApIHsKCQkJdmlldyA9IHdpbmRvdzsKCQl9CgoJCXJldHVybiB2aWV3LmdldENvbXB1dGVkU3R5bGUoIGVsZW0gKTsKCX07Cgp2YXIgcmJveFN0eWxlID0gbmV3IFJlZ0V4cCggY3NzRXhwYW5kLmpvaW4oICJ8IiApLCAiaSIgKTsKCgoKKCBmdW5jdGlvbigpIHsKCgkvLyBFeGVjdXRpbmcgYm90aCBwaXhlbFBvc2l0aW9uICYgYm94U2l6aW5nUmVsaWFibGUgdGVzdHMgcmVxdWlyZSBvbmx5IG9uZSBsYXlvdXQKCS8vIHNvIHRoZXkncmUgZXhlY3V0ZWQgYXQgdGhlIHNhbWUgdGltZSB0byBzYXZlIHRoZSBzZWNvbmQgY29tcHV0YXRpb24uCglmdW5jdGlvbiBjb21wdXRlU3R5bGVUZXN0cygpIHsKCgkJLy8gVGhpcyBpcyBhIHNpbmdsZXRvbiwgd2UgbmVlZCB0byBleGVjdXRlIGl0IG9ubHkgb25jZQoJCWlmICggIWRpdiApIHsKCQkJcmV0dXJuOwoJCX0KCgkJY29udGFpbmVyLnN0eWxlLmNzc1RleHQgPSAicG9zaXRpb246YWJzb2x1dGU7bGVmdDotMTExMTFweDt3aWR0aDo2MHB4OyIgKwoJCQkibWFyZ2luLXRvcDoxcHg7cGFkZGluZzowO2JvcmRlcjowIjsKCQlkaXYuc3R5bGUuY3NzVGV4dCA9CgkJCSJwb3NpdGlvbjpyZWxhdGl2ZTtkaXNwbGF5OmJsb2NrO2JveC1zaXppbmc6Ym9yZGVyLWJveDtvdmVyZmxvdzpzY3JvbGw7IiArCgkJCSJtYXJnaW46YXV0bztib3JkZXI6MXB4O3BhZGRpbmc6MXB4OyIgKwoJCQkid2lkdGg6NjAlO3RvcDoxJSI7CgkJZG9jdW1lbnRFbGVtZW50LmFwcGVuZENoaWxkKCBjb250YWluZXIgKS5hcHBlbmRDaGlsZCggZGl2ICk7CgoJCXZhciBkaXZTdHlsZSA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKCBkaXYgKTsKCQlwaXhlbFBvc2l0aW9uVmFsID0gZGl2U3R5bGUudG9wICE9PSAiMSUiOwoKCQkvLyBTdXBwb3J0OiBBbmRyb2lkIDQuMCAtIDQuMyBvbmx5LCBGaXJlZm94IDw9MyAtIDQ0CgkJcmVsaWFibGVNYXJnaW5MZWZ0VmFsID0gcm91bmRQaXhlbE1lYXN1cmVzKCBkaXZTdHlsZS5tYXJnaW5MZWZ0ICkgPT09IDEyOwoKCQkvLyBTdXBwb3J0OiBBbmRyb2lkIDQuMCAtIDQuMyBvbmx5LCBTYWZhcmkgPD05LjEgLSAxMC4xLCBpT1MgPD03LjAgLSA5LjMKCQkvLyBTb21lIHN0eWxlcyBjb21lIGJhY2sgd2l0aCBwZXJjZW50YWdlIHZhbHVlcywgZXZlbiB0aG91Z2ggdGhleSBzaG91bGRuJ3QKCQlkaXYuc3R5bGUucmlnaHQgPSAiNjAlIjsKCQlwaXhlbEJveFN0eWxlc1ZhbCA9IHJvdW5kUGl4ZWxNZWFzdXJlcyggZGl2U3R5bGUucmlnaHQgKSA9PT0gMzY7CgoJCS8vIFN1cHBvcnQ6IElFIDkgLSAxMSBvbmx5CgkJLy8gRGV0ZWN0IG1pc3JlcG9ydGluZyBvZiBjb250ZW50IGRpbWVuc2lvbnMgZm9yIGJveC1zaXppbmc6Ym9yZGVyLWJveCBlbGVtZW50cwoJCWJveFNpemluZ1JlbGlhYmxlVmFsID0gcm91bmRQaXhlbE1lYXN1cmVzKCBkaXZTdHlsZS53aWR0aCApID09PSAzNjsKCgkJLy8gU3VwcG9ydDogSUUgOSBvbmx5CgkJLy8gRGV0ZWN0IG92ZXJmbG93OnNjcm9sbCBzY3Jld2luZXNzIChnaC0zNjk5KQoJCWRpdi5zdHlsZS5wb3NpdGlvbiA9ICJhYnNvbHV0ZSI7CgkJc2Nyb2xsYm94U2l6ZVZhbCA9IGRpdi5vZmZzZXRXaWR0aCA9PT0gMzYgfHwgImFic29sdXRlIjsKCgkJZG9jdW1lbnRFbGVtZW50LnJlbW92ZUNoaWxkKCBjb250YWluZXIgKTsKCgkJLy8gTnVsbGlmeSB0aGUgZGl2IHNvIGl0IHdvdWxkbid0IGJlIHN0b3JlZCBpbiB0aGUgbWVtb3J5IGFuZAoJCS8vIGl0IHdpbGwgYWxzbyBiZSBhIHNpZ24gdGhhdCBjaGVja3MgYWxyZWFkeSBwZXJmb3JtZWQKCQlkaXYgPSBudWxsOwoJfQoKCWZ1bmN0aW9uIHJvdW5kUGl4ZWxNZWFzdXJlcyggbWVhc3VyZSApIHsKCQlyZXR1cm4gTWF0aC5yb3VuZCggcGFyc2VGbG9hdCggbWVhc3VyZSApICk7Cgl9CgoJdmFyIHBpeGVsUG9zaXRpb25WYWwsIGJveFNpemluZ1JlbGlhYmxlVmFsLCBzY3JvbGxib3hTaXplVmFsLCBwaXhlbEJveFN0eWxlc1ZhbCwKCQlyZWxpYWJsZU1hcmdpbkxlZnRWYWwsCgkJY29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggImRpdiIgKSwKCQlkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCAiZGl2IiApOwoKCS8vIEZpbmlzaCBlYXJseSBpbiBsaW1pdGVkIChub24tYnJvd3NlcikgZW52aXJvbm1lbnRzCglpZiAoICFkaXYuc3R5bGUgKSB7CgkJcmV0dXJuOwoJfQoKCS8vIFN1cHBvcnQ6IElFIDw9OSAtIDExIG9ubHkKCS8vIFN0eWxlIG9mIGNsb25lZCBlbGVtZW50IGFmZmVjdHMgc291cmNlIGVsZW1lbnQgY2xvbmVkICgjODkwOCkKCWRpdi5zdHlsZS5iYWNrZ3JvdW5kQ2xpcCA9ICJjb250ZW50LWJveCI7CglkaXYuY2xvbmVOb2RlKCB0cnVlICkuc3R5bGUuYmFja2dyb3VuZENsaXAgPSAiIjsKCXN1cHBvcnQuY2xlYXJDbG9uZVN0eWxlID0gZGl2LnN0eWxlLmJhY2tncm91bmRDbGlwID09PSAiY29udGVudC1ib3giOwoKCWpRdWVyeS5leHRlbmQoIHN1cHBvcnQsIHsKCQlib3hTaXppbmdSZWxpYWJsZTogZnVuY3Rpb24oKSB7CgkJCWNvbXB1dGVTdHlsZVRlc3RzKCk7CgkJCXJldHVybiBib3hTaXppbmdSZWxpYWJsZVZhbDsKCQl9LAoJCXBpeGVsQm94U3R5bGVzOiBmdW5jdGlvbigpIHsKCQkJY29tcHV0ZVN0eWxlVGVzdHMoKTsKCQkJcmV0dXJuIHBpeGVsQm94U3R5bGVzVmFsOwoJCX0sCgkJcGl4ZWxQb3NpdGlvbjogZnVuY3Rpb24oKSB7CgkJCWNvbXB1dGVTdHlsZVRlc3RzKCk7CgkJCXJldHVybiBwaXhlbFBvc2l0aW9uVmFsOwoJCX0sCgkJcmVsaWFibGVNYXJnaW5MZWZ0OiBmdW5jdGlvbigpIHsKCQkJY29tcHV0ZVN0eWxlVGVzdHMoKTsKCQkJcmV0dXJuIHJlbGlhYmxlTWFyZ2luTGVmdFZhbDsKCQl9LAoJCXNjcm9sbGJveFNpemU6IGZ1bmN0aW9uKCkgewoJCQljb21wdXRlU3R5bGVUZXN0cygpOwoJCQlyZXR1cm4gc2Nyb2xsYm94U2l6ZVZhbDsKCQl9Cgl9ICk7Cn0gKSgpOwoKCmZ1bmN0aW9uIGN1ckNTUyggZWxlbSwgbmFtZSwgY29tcHV0ZWQgKSB7Cgl2YXIgd2lkdGgsIG1pbldpZHRoLCBtYXhXaWR0aCwgcmV0LAoKCQkvLyBTdXBwb3J0OiBGaXJlZm94IDUxKwoJCS8vIFJldHJpZXZpbmcgc3R5bGUgYmVmb3JlIGNvbXB1dGVkIHNvbWVob3cKCQkvLyBmaXhlcyBhbiBpc3N1ZSB3aXRoIGdldHRpbmcgd3JvbmcgdmFsdWVzCgkJLy8gb24gZGV0YWNoZWQgZWxlbWVudHMKCQlzdHlsZSA9IGVsZW0uc3R5bGU7CgoJY29tcHV0ZWQgPSBjb21wdXRlZCB8fCBnZXRTdHlsZXMoIGVsZW0gKTsKCgkvLyBnZXRQcm9wZXJ0eVZhbHVlIGlzIG5lZWRlZCBmb3I6CgkvLyAgIC5jc3MoJ2ZpbHRlcicpIChJRSA5IG9ubHksICMxMjUzNykKCS8vICAgLmNzcygnLS1jdXN0b21Qcm9wZXJ0eSkgKCMzMTQ0KQoJaWYgKCBjb21wdXRlZCApIHsKCQlyZXQgPSBjb21wdXRlZC5nZXRQcm9wZXJ0eVZhbHVlKCBuYW1lICkgfHwgY29tcHV0ZWRbIG5hbWUgXTsKCgkJaWYgKCByZXQgPT09ICIiICYmICFqUXVlcnkuY29udGFpbnMoIGVsZW0ub3duZXJEb2N1bWVudCwgZWxlbSApICkgewoJCQlyZXQgPSBqUXVlcnkuc3R5bGUoIGVsZW0sIG5hbWUgKTsKCQl9CgoJCS8vIEEgdHJpYnV0ZSB0byB0aGUgImF3ZXNvbWUgaGFjayBieSBEZWFuIEVkd2FyZHMiCgkJLy8gQW5kcm9pZCBCcm93c2VyIHJldHVybnMgcGVyY2VudGFnZSBmb3Igc29tZSB2YWx1ZXMsCgkJLy8gYnV0IHdpZHRoIHNlZW1zIHRvIGJlIHJlbGlhYmx5IHBpeGVscy4KCQkvLyBUaGlzIGlzIGFnYWluc3QgdGhlIENTU09NIGRyYWZ0IHNwZWM6CgkJLy8gaHR0cHM6Ly9kcmFmdHMuY3Nzd2cub3JnL2Nzc29tLyNyZXNvbHZlZC12YWx1ZXMKCQlpZiAoICFzdXBwb3J0LnBpeGVsQm94U3R5bGVzKCkgJiYgcm51bW5vbnB4LnRlc3QoIHJldCApICYmIHJib3hTdHlsZS50ZXN0KCBuYW1lICkgKSB7CgoJCQkvLyBSZW1lbWJlciB0aGUgb3JpZ2luYWwgdmFsdWVzCgkJCXdpZHRoID0gc3R5bGUud2lkdGg7CgkJCW1pbldpZHRoID0gc3R5bGUubWluV2lkdGg7CgkJCW1heFdpZHRoID0gc3R5bGUubWF4V2lkdGg7CgoJCQkvLyBQdXQgaW4gdGhlIG5ldyB2YWx1ZXMgdG8gZ2V0IGEgY29tcHV0ZWQgdmFsdWUgb3V0CgkJCXN0eWxlLm1pbldpZHRoID0gc3R5bGUubWF4V2lkdGggPSBzdHlsZS53aWR0aCA9IHJldDsKCQkJcmV0ID0gY29tcHV0ZWQud2lkdGg7CgoJCQkvLyBSZXZlcnQgdGhlIGNoYW5nZWQgdmFsdWVzCgkJCXN0eWxlLndpZHRoID0gd2lkdGg7CgkJCXN0eWxlLm1pbldpZHRoID0gbWluV2lkdGg7CgkJCXN0eWxlLm1heFdpZHRoID0gbWF4V2lkdGg7CgkJfQoJfQoKCXJldHVybiByZXQgIT09IHVuZGVmaW5lZCA/CgoJCS8vIFN1cHBvcnQ6IElFIDw9OSAtIDExIG9ubHkKCQkvLyBJRSByZXR1cm5zIHpJbmRleCB2YWx1ZSBhcyBhbiBpbnRlZ2VyLgoJCXJldCArICIiIDoKCQlyZXQ7Cn0KCgpmdW5jdGlvbiBhZGRHZXRIb29rSWYoIGNvbmRpdGlvbkZuLCBob29rRm4gKSB7CgoJLy8gRGVmaW5lIHRoZSBob29rLCB3ZSdsbCBjaGVjayBvbiB0aGUgZmlyc3QgcnVuIGlmIGl0J3MgcmVhbGx5IG5lZWRlZC4KCXJldHVybiB7CgkJZ2V0OiBmdW5jdGlvbigpIHsKCQkJaWYgKCBjb25kaXRpb25GbigpICkgewoKCQkJCS8vIEhvb2sgbm90IG5lZWRlZCAob3IgaXQncyBub3QgcG9zc2libGUgdG8gdXNlIGl0IGR1ZQoJCQkJLy8gdG8gbWlzc2luZyBkZXBlbmRlbmN5KSwgcmVtb3ZlIGl0LgoJCQkJZGVsZXRlIHRoaXMuZ2V0OwoJCQkJcmV0dXJuOwoJCQl9CgoJCQkvLyBIb29rIG5lZWRlZDsgcmVkZWZpbmUgaXQgc28gdGhhdCB0aGUgc3VwcG9ydCB0ZXN0IGlzIG5vdCBleGVjdXRlZCBhZ2Fpbi4KCQkJcmV0dXJuICggdGhpcy5nZXQgPSBob29rRm4gKS5hcHBseSggdGhpcywgYXJndW1lbnRzICk7CgkJfQoJfTsKfQoKCnZhcgoKCS8vIFN3YXBwYWJsZSBpZiBkaXNwbGF5IGlzIG5vbmUgb3Igc3RhcnRzIHdpdGggdGFibGUKCS8vIGV4Y2VwdCAidGFibGUiLCAidGFibGUtY2VsbCIsIG9yICJ0YWJsZS1jYXB0aW9uIgoJLy8gU2VlIGhlcmUgZm9yIGRpc3BsYXkgdmFsdWVzOiBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL0NTUy9kaXNwbGF5CglyZGlzcGxheXN3YXAgPSAvXihub25lfHRhYmxlKD8hLWNbZWFdKS4rKS8sCglyY3VzdG9tUHJvcCA9IC9eLS0vLAoJY3NzU2hvdyA9IHsgcG9zaXRpb246ICJhYnNvbHV0ZSIsIHZpc2liaWxpdHk6ICJoaWRkZW4iLCBkaXNwbGF5OiAiYmxvY2siIH0sCgljc3NOb3JtYWxUcmFuc2Zvcm0gPSB7CgkJbGV0dGVyU3BhY2luZzogIjAiLAoJCWZvbnRXZWlnaHQ6ICI0MDAiCgl9LAoKCWNzc1ByZWZpeGVzID0gWyAiV2Via2l0IiwgIk1veiIsICJtcyIgXSwKCWVtcHR5U3R5bGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCAiZGl2IiApLnN0eWxlOwoKLy8gUmV0dXJuIGEgY3NzIHByb3BlcnR5IG1hcHBlZCB0byBhIHBvdGVudGlhbGx5IHZlbmRvciBwcmVmaXhlZCBwcm9wZXJ0eQpmdW5jdGlvbiB2ZW5kb3JQcm9wTmFtZSggbmFtZSApIHsKCgkvLyBTaG9ydGN1dCBmb3IgbmFtZXMgdGhhdCBhcmUgbm90IHZlbmRvciBwcmVmaXhlZAoJaWYgKCBuYW1lIGluIGVtcHR5U3R5bGUgKSB7CgkJcmV0dXJuIG5hbWU7Cgl9CgoJLy8gQ2hlY2sgZm9yIHZlbmRvciBwcmVmaXhlZCBuYW1lcwoJdmFyIGNhcE5hbWUgPSBuYW1lWyAwIF0udG9VcHBlckNhc2UoKSArIG5hbWUuc2xpY2UoIDEgKSwKCQlpID0gY3NzUHJlZml4ZXMubGVuZ3RoOwoKCXdoaWxlICggaS0tICkgewoJCW5hbWUgPSBjc3NQcmVmaXhlc1sgaSBdICsgY2FwTmFtZTsKCQlpZiAoIG5hbWUgaW4gZW1wdHlTdHlsZSApIHsKCQkJcmV0dXJuIG5hbWU7CgkJfQoJfQp9CgovLyBSZXR1cm4gYSBwcm9wZXJ0eSBtYXBwZWQgYWxvbmcgd2hhdCBqUXVlcnkuY3NzUHJvcHMgc3VnZ2VzdHMgb3IgdG8KLy8gYSB2ZW5kb3IgcHJlZml4ZWQgcHJvcGVydHkuCmZ1bmN0aW9uIGZpbmFsUHJvcE5hbWUoIG5hbWUgKSB7Cgl2YXIgcmV0ID0galF1ZXJ5LmNzc1Byb3BzWyBuYW1lIF07CglpZiAoICFyZXQgKSB7CgkJcmV0ID0galF1ZXJ5LmNzc1Byb3BzWyBuYW1lIF0gPSB2ZW5kb3JQcm9wTmFtZSggbmFtZSApIHx8IG5hbWU7Cgl9CglyZXR1cm4gcmV0Owp9CgpmdW5jdGlvbiBzZXRQb3NpdGl2ZU51bWJlciggZWxlbSwgdmFsdWUsIHN1YnRyYWN0ICkgewoKCS8vIEFueSByZWxhdGl2ZSAoKy8tKSB2YWx1ZXMgaGF2ZSBhbHJlYWR5IGJlZW4KCS8vIG5vcm1hbGl6ZWQgYXQgdGhpcyBwb2ludAoJdmFyIG1hdGNoZXMgPSByY3NzTnVtLmV4ZWMoIHZhbHVlICk7CglyZXR1cm4gbWF0Y2hlcyA/CgoJCS8vIEd1YXJkIGFnYWluc3QgdW5kZWZpbmVkICJzdWJ0cmFjdCIsIGUuZy4sIHdoZW4gdXNlZCBhcyBpbiBjc3NIb29rcwoJCU1hdGgubWF4KCAwLCBtYXRjaGVzWyAyIF0gLSAoIHN1YnRyYWN0IHx8IDAgKSApICsgKCBtYXRjaGVzWyAzIF0gfHwgInB4IiApIDoKCQl2YWx1ZTsKfQoKZnVuY3Rpb24gYm94TW9kZWxBZGp1c3RtZW50KCBlbGVtLCBkaW1lbnNpb24sIGJveCwgaXNCb3JkZXJCb3gsIHN0eWxlcywgY29tcHV0ZWRWYWwgKSB7Cgl2YXIgaSA9IGRpbWVuc2lvbiA9PT0gIndpZHRoIiA/IDEgOiAwLAoJCWV4dHJhID0gMCwKCQlkZWx0YSA9IDA7CgoJLy8gQWRqdXN0bWVudCBtYXkgbm90IGJlIG5lY2Vzc2FyeQoJaWYgKCBib3ggPT09ICggaXNCb3JkZXJCb3ggPyAiYm9yZGVyIiA6ICJjb250ZW50IiApICkgewoJCXJldHVybiAwOwoJfQoKCWZvciAoIDsgaSA8IDQ7IGkgKz0gMiApIHsKCgkJLy8gQm90aCBib3ggbW9kZWxzIGV4Y2x1ZGUgbWFyZ2luCgkJaWYgKCBib3ggPT09ICJtYXJnaW4iICkgewoJCQlkZWx0YSArPSBqUXVlcnkuY3NzKCBlbGVtLCBib3ggKyBjc3NFeHBhbmRbIGkgXSwgdHJ1ZSwgc3R5bGVzICk7CgkJfQoKCQkvLyBJZiB3ZSBnZXQgaGVyZSB3aXRoIGEgY29udGVudC1ib3gsIHdlJ3JlIHNlZWtpbmcgInBhZGRpbmciIG9yICJib3JkZXIiIG9yICJtYXJnaW4iCgkJaWYgKCAhaXNCb3JkZXJCb3ggKSB7CgoJCQkvLyBBZGQgcGFkZGluZwoJCQlkZWx0YSArPSBqUXVlcnkuY3NzKCBlbGVtLCAicGFkZGluZyIgKyBjc3NFeHBhbmRbIGkgXSwgdHJ1ZSwgc3R5bGVzICk7CgoJCQkvLyBGb3IgImJvcmRlciIgb3IgIm1hcmdpbiIsIGFkZCBib3JkZXIKCQkJaWYgKCBib3ggIT09ICJwYWRkaW5nIiApIHsKCQkJCWRlbHRhICs9IGpRdWVyeS5jc3MoIGVsZW0sICJib3JkZXIiICsgY3NzRXhwYW5kWyBpIF0gKyAiV2lkdGgiLCB0cnVlLCBzdHlsZXMgKTsKCgkJCS8vIEJ1dCBzdGlsbCBrZWVwIHRyYWNrIG9mIGl0IG90aGVyd2lzZQoJCQl9IGVsc2UgewoJCQkJZXh0cmEgKz0galF1ZXJ5LmNzcyggZWxlbSwgImJvcmRlciIgKyBjc3NFeHBhbmRbIGkgXSArICJXaWR0aCIsIHRydWUsIHN0eWxlcyApOwoJCQl9CgoJCS8vIElmIHdlIGdldCBoZXJlIHdpdGggYSBib3JkZXItYm94IChjb250ZW50ICsgcGFkZGluZyArIGJvcmRlciksIHdlJ3JlIHNlZWtpbmcgImNvbnRlbnQiIG9yCgkJLy8gInBhZGRpbmciIG9yICJtYXJnaW4iCgkJfSBlbHNlIHsKCgkJCS8vIEZvciAiY29udGVudCIsIHN1YnRyYWN0IHBhZGRpbmcKCQkJaWYgKCBib3ggPT09ICJjb250ZW50IiApIHsKCQkJCWRlbHRhIC09IGpRdWVyeS5jc3MoIGVsZW0sICJwYWRkaW5nIiArIGNzc0V4cGFuZFsgaSBdLCB0cnVlLCBzdHlsZXMgKTsKCQkJfQoKCQkJLy8gRm9yICJjb250ZW50IiBvciAicGFkZGluZyIsIHN1YnRyYWN0IGJvcmRlcgoJCQlpZiAoIGJveCAhPT0gIm1hcmdpbiIgKSB7CgkJCQlkZWx0YSAtPSBqUXVlcnkuY3NzKCBlbGVtLCAiYm9yZGVyIiArIGNzc0V4cGFuZFsgaSBdICsgIldpZHRoIiwgdHJ1ZSwgc3R5bGVzICk7CgkJCX0KCQl9Cgl9CgoJLy8gQWNjb3VudCBmb3IgcG9zaXRpdmUgY29udGVudC1ib3ggc2Nyb2xsIGd1dHRlciB3aGVuIHJlcXVlc3RlZCBieSBwcm92aWRpbmcgY29tcHV0ZWRWYWwKCWlmICggIWlzQm9yZGVyQm94ICYmIGNvbXB1dGVkVmFsID49IDAgKSB7CgoJCS8vIG9mZnNldFdpZHRoL29mZnNldEhlaWdodCBpcyBhIHJvdW5kZWQgc3VtIG9mIGNvbnRlbnQsIHBhZGRpbmcsIHNjcm9sbCBndXR0ZXIsIGFuZCBib3JkZXIKCQkvLyBBc3N1bWluZyBpbnRlZ2VyIHNjcm9sbCBndXR0ZXIsIHN1YnRyYWN0IHRoZSByZXN0IGFuZCByb3VuZCBkb3duCgkJZGVsdGEgKz0gTWF0aC5tYXgoIDAsIE1hdGguY2VpbCgKCQkJZWxlbVsgIm9mZnNldCIgKyBkaW1lbnNpb25bIDAgXS50b1VwcGVyQ2FzZSgpICsgZGltZW5zaW9uLnNsaWNlKCAxICkgXSAtCgkJCWNvbXB1dGVkVmFsIC0KCQkJZGVsdGEgLQoJCQlleHRyYSAtCgkJCTAuNQoJCSkgKTsKCX0KCglyZXR1cm4gZGVsdGE7Cn0KCmZ1bmN0aW9uIGdldFdpZHRoT3JIZWlnaHQoIGVsZW0sIGRpbWVuc2lvbiwgZXh0cmEgKSB7CgoJLy8gU3RhcnQgd2l0aCBjb21wdXRlZCBzdHlsZQoJdmFyIHN0eWxlcyA9IGdldFN0eWxlcyggZWxlbSApLAoJCXZhbCA9IGN1ckNTUyggZWxlbSwgZGltZW5zaW9uLCBzdHlsZXMgKSwKCQlpc0JvcmRlckJveCA9IGpRdWVyeS5jc3MoIGVsZW0sICJib3hTaXppbmciLCBmYWxzZSwgc3R5bGVzICkgPT09ICJib3JkZXItYm94IiwKCQl2YWx1ZUlzQm9yZGVyQm94ID0gaXNCb3JkZXJCb3g7CgoJLy8gU3VwcG9ydDogRmlyZWZveCA8PTU0CgkvLyBSZXR1cm4gYSBjb25mb3VuZGluZyBub24tcGl4ZWwgdmFsdWUgb3IgZmVpZ24gaWdub3JhbmNlLCBhcyBhcHByb3ByaWF0ZS4KCWlmICggcm51bW5vbnB4LnRlc3QoIHZhbCApICkgewoJCWlmICggIWV4dHJhICkgewoJCQlyZXR1cm4gdmFsOwoJCX0KCQl2YWwgPSAiYXV0byI7Cgl9CgoJLy8gQ2hlY2sgZm9yIHN0eWxlIGluIGNhc2UgYSBicm93c2VyIHdoaWNoIHJldHVybnMgdW5yZWxpYWJsZSB2YWx1ZXMKCS8vIGZvciBnZXRDb21wdXRlZFN0eWxlIHNpbGVudGx5IGZhbGxzIGJhY2sgdG8gdGhlIHJlbGlhYmxlIGVsZW0uc3R5bGUKCXZhbHVlSXNCb3JkZXJCb3ggPSB2YWx1ZUlzQm9yZGVyQm94ICYmCgkJKCBzdXBwb3J0LmJveFNpemluZ1JlbGlhYmxlKCkgfHwgdmFsID09PSBlbGVtLnN0eWxlWyBkaW1lbnNpb24gXSApOwoKCS8vIEZhbGwgYmFjayB0byBvZmZzZXRXaWR0aC9vZmZzZXRIZWlnaHQgd2hlbiB2YWx1ZSBpcyAiYXV0byIKCS8vIFRoaXMgaGFwcGVucyBmb3IgaW5saW5lIGVsZW1lbnRzIHdpdGggbm8gZXhwbGljaXQgc2V0dGluZyAoZ2gtMzU3MSkKCS8vIFN1cHBvcnQ6IEFuZHJvaWQgPD00LjEgLSA0LjMgb25seQoJLy8gQWxzbyB1c2Ugb2Zmc2V0V2lkdGgvb2Zmc2V0SGVpZ2h0IGZvciBtaXNyZXBvcnRlZCBpbmxpbmUgZGltZW5zaW9ucyAoZ2gtMzYwMikKCWlmICggdmFsID09PSAiYXV0byIgfHwKCQkhcGFyc2VGbG9hdCggdmFsICkgJiYgalF1ZXJ5LmNzcyggZWxlbSwgImRpc3BsYXkiLCBmYWxzZSwgc3R5bGVzICkgPT09ICJpbmxpbmUiICkgewoKCQl2YWwgPSBlbGVtWyAib2Zmc2V0IiArIGRpbWVuc2lvblsgMCBdLnRvVXBwZXJDYXNlKCkgKyBkaW1lbnNpb24uc2xpY2UoIDEgKSBdOwoKCQkvLyBvZmZzZXRXaWR0aC9vZmZzZXRIZWlnaHQgcHJvdmlkZSBib3JkZXItYm94IHZhbHVlcwoJCXZhbHVlSXNCb3JkZXJCb3ggPSB0cnVlOwoJfQoKCS8vIE5vcm1hbGl6ZSAiIiBhbmQgYXV0bwoJdmFsID0gcGFyc2VGbG9hdCggdmFsICkgfHwgMDsKCgkvLyBBZGp1c3QgZm9yIHRoZSBlbGVtZW50J3MgYm94IG1vZGVsCglyZXR1cm4gKCB2YWwgKwoJCWJveE1vZGVsQWRqdXN0bWVudCgKCQkJZWxlbSwKCQkJZGltZW5zaW9uLAoJCQlleHRyYSB8fCAoIGlzQm9yZGVyQm94ID8gImJvcmRlciIgOiAiY29udGVudCIgKSwKCQkJdmFsdWVJc0JvcmRlckJveCwKCQkJc3R5bGVzLAoKCQkJLy8gUHJvdmlkZSB0aGUgY3VycmVudCBjb21wdXRlZCBzaXplIHRvIHJlcXVlc3Qgc2Nyb2xsIGd1dHRlciBjYWxjdWxhdGlvbiAoZ2gtMzU4OSkKCQkJdmFsCgkJKQoJKSArICJweCI7Cn0KCmpRdWVyeS5leHRlbmQoIHsKCgkvLyBBZGQgaW4gc3R5bGUgcHJvcGVydHkgaG9va3MgZm9yIG92ZXJyaWRpbmcgdGhlIGRlZmF1bHQKCS8vIGJlaGF2aW9yIG9mIGdldHRpbmcgYW5kIHNldHRpbmcgYSBzdHlsZSBwcm9wZXJ0eQoJY3NzSG9va3M6IHsKCQlvcGFjaXR5OiB7CgkJCWdldDogZnVuY3Rpb24oIGVsZW0sIGNvbXB1dGVkICkgewoJCQkJaWYgKCBjb21wdXRlZCApIHsKCgkJCQkJLy8gV2Ugc2hvdWxkIGFsd2F5cyBnZXQgYSBudW1iZXIgYmFjayBmcm9tIG9wYWNpdHkKCQkJCQl2YXIgcmV0ID0gY3VyQ1NTKCBlbGVtLCAib3BhY2l0eSIgKTsKCQkJCQlyZXR1cm4gcmV0ID09PSAiIiA/ICIxIiA6IHJldDsKCQkJCX0KCQkJfQoJCX0KCX0sCgoJLy8gRG9uJ3QgYXV0b21hdGljYWxseSBhZGQgInB4IiB0byB0aGVzZSBwb3NzaWJseS11bml0bGVzcyBwcm9wZXJ0aWVzCgljc3NOdW1iZXI6IHsKCQkiYW5pbWF0aW9uSXRlcmF0aW9uQ291bnQiOiB0cnVlLAoJCSJjb2x1bW5Db3VudCI6IHRydWUsCgkJImZpbGxPcGFjaXR5IjogdHJ1ZSwKCQkiZmxleEdyb3ciOiB0cnVlLAoJCSJmbGV4U2hyaW5rIjogdHJ1ZSwKCQkiZm9udFdlaWdodCI6IHRydWUsCgkJImxpbmVIZWlnaHQiOiB0cnVlLAoJCSJvcGFjaXR5IjogdHJ1ZSwKCQkib3JkZXIiOiB0cnVlLAoJCSJvcnBoYW5zIjogdHJ1ZSwKCQkid2lkb3dzIjogdHJ1ZSwKCQkiekluZGV4IjogdHJ1ZSwKCQkiem9vbSI6IHRydWUKCX0sCgoJLy8gQWRkIGluIHByb3BlcnRpZXMgd2hvc2UgbmFtZXMgeW91IHdpc2ggdG8gZml4IGJlZm9yZQoJLy8gc2V0dGluZyBvciBnZXR0aW5nIHRoZSB2YWx1ZQoJY3NzUHJvcHM6IHt9LAoKCS8vIEdldCBhbmQgc2V0IHRoZSBzdHlsZSBwcm9wZXJ0eSBvbiBhIERPTSBOb2RlCglzdHlsZTogZnVuY3Rpb24oIGVsZW0sIG5hbWUsIHZhbHVlLCBleHRyYSApIHsKCgkJLy8gRG9uJ3Qgc2V0IHN0eWxlcyBvbiB0ZXh0IGFuZCBjb21tZW50IG5vZGVzCgkJaWYgKCAhZWxlbSB8fCBlbGVtLm5vZGVUeXBlID09PSAzIHx8IGVsZW0ubm9kZVR5cGUgPT09IDggfHwgIWVsZW0uc3R5bGUgKSB7CgkJCXJldHVybjsKCQl9CgoJCS8vIE1ha2Ugc3VyZSB0aGF0IHdlJ3JlIHdvcmtpbmcgd2l0aCB0aGUgcmlnaHQgbmFtZQoJCXZhciByZXQsIHR5cGUsIGhvb2tzLAoJCQlvcmlnTmFtZSA9IGNhbWVsQ2FzZSggbmFtZSApLAoJCQlpc0N1c3RvbVByb3AgPSByY3VzdG9tUHJvcC50ZXN0KCBuYW1lICksCgkJCXN0eWxlID0gZWxlbS5zdHlsZTsKCgkJLy8gTWFrZSBzdXJlIHRoYXQgd2UncmUgd29ya2luZyB3aXRoIHRoZSByaWdodCBuYW1lLiBXZSBkb24ndAoJCS8vIHdhbnQgdG8gcXVlcnkgdGhlIHZhbHVlIGlmIGl0IGlzIGEgQ1NTIGN1c3RvbSBwcm9wZXJ0eQoJCS8vIHNpbmNlIHRoZXkgYXJlIHVzZXItZGVmaW5lZC4KCQlpZiAoICFpc0N1c3RvbVByb3AgKSB7CgkJCW5hbWUgPSBmaW5hbFByb3BOYW1lKCBvcmlnTmFtZSApOwoJCX0KCgkJLy8gR2V0cyBob29rIGZvciB0aGUgcHJlZml4ZWQgdmVyc2lvbiwgdGhlbiB1bnByZWZpeGVkIHZlcnNpb24KCQlob29rcyA9IGpRdWVyeS5jc3NIb29rc1sgbmFtZSBdIHx8IGpRdWVyeS5jc3NIb29rc1sgb3JpZ05hbWUgXTsKCgkJLy8gQ2hlY2sgaWYgd2UncmUgc2V0dGluZyBhIHZhbHVlCgkJaWYgKCB2YWx1ZSAhPT0gdW5kZWZpbmVkICkgewoJCQl0eXBlID0gdHlwZW9mIHZhbHVlOwoKCQkJLy8gQ29udmVydCAiKz0iIG9yICItPSIgdG8gcmVsYXRpdmUgbnVtYmVycyAoIzczNDUpCgkJCWlmICggdHlwZSA9PT0gInN0cmluZyIgJiYgKCByZXQgPSByY3NzTnVtLmV4ZWMoIHZhbHVlICkgKSAmJiByZXRbIDEgXSApIHsKCQkJCXZhbHVlID0gYWRqdXN0Q1NTKCBlbGVtLCBuYW1lLCByZXQgKTsKCgkJCQkvLyBGaXhlcyBidWcgIzkyMzcKCQkJCXR5cGUgPSAibnVtYmVyIjsKCQkJfQoKCQkJLy8gTWFrZSBzdXJlIHRoYXQgbnVsbCBhbmQgTmFOIHZhbHVlcyBhcmVuJ3Qgc2V0ICgjNzExNikKCQkJaWYgKCB2YWx1ZSA9PSBudWxsIHx8IHZhbHVlICE9PSB2YWx1ZSApIHsKCQkJCXJldHVybjsKCQkJfQoKCQkJLy8gSWYgYSBudW1iZXIgd2FzIHBhc3NlZCBpbiwgYWRkIHRoZSB1bml0IChleGNlcHQgZm9yIGNlcnRhaW4gQ1NTIHByb3BlcnRpZXMpCgkJCWlmICggdHlwZSA9PT0gIm51bWJlciIgKSB7CgkJCQl2YWx1ZSArPSByZXQgJiYgcmV0WyAzIF0gfHwgKCBqUXVlcnkuY3NzTnVtYmVyWyBvcmlnTmFtZSBdID8gIiIgOiAicHgiICk7CgkJCX0KCgkJCS8vIGJhY2tncm91bmQtKiBwcm9wcyBhZmZlY3Qgb3JpZ2luYWwgY2xvbmUncyB2YWx1ZXMKCQkJaWYgKCAhc3VwcG9ydC5jbGVhckNsb25lU3R5bGUgJiYgdmFsdWUgPT09ICIiICYmIG5hbWUuaW5kZXhPZiggImJhY2tncm91bmQiICkgPT09IDAgKSB7CgkJCQlzdHlsZVsgbmFtZSBdID0gImluaGVyaXQiOwoJCQl9CgoJCQkvLyBJZiBhIGhvb2sgd2FzIHByb3ZpZGVkLCB1c2UgdGhhdCB2YWx1ZSwgb3RoZXJ3aXNlIGp1c3Qgc2V0IHRoZSBzcGVjaWZpZWQgdmFsdWUKCQkJaWYgKCAhaG9va3MgfHwgISggInNldCIgaW4gaG9va3MgKSB8fAoJCQkJKCB2YWx1ZSA9IGhvb2tzLnNldCggZWxlbSwgdmFsdWUsIGV4dHJhICkgKSAhPT0gdW5kZWZpbmVkICkgewoKCQkJCWlmICggaXNDdXN0b21Qcm9wICkgewoJCQkJCXN0eWxlLnNldFByb3BlcnR5KCBuYW1lLCB2YWx1ZSApOwoJCQkJfSBlbHNlIHsKCQkJCQlzdHlsZVsgbmFtZSBdID0gdmFsdWU7CgkJCQl9CgkJCX0KCgkJfSBlbHNlIHsKCgkJCS8vIElmIGEgaG9vayB3YXMgcHJvdmlkZWQgZ2V0IHRoZSBub24tY29tcHV0ZWQgdmFsdWUgZnJvbSB0aGVyZQoJCQlpZiAoIGhvb2tzICYmICJnZXQiIGluIGhvb2tzICYmCgkJCQkoIHJldCA9IGhvb2tzLmdldCggZWxlbSwgZmFsc2UsIGV4dHJhICkgKSAhPT0gdW5kZWZpbmVkICkgewoKCQkJCXJldHVybiByZXQ7CgkJCX0KCgkJCS8vIE90aGVyd2lzZSBqdXN0IGdldCB0aGUgdmFsdWUgZnJvbSB0aGUgc3R5bGUgb2JqZWN0CgkJCXJldHVybiBzdHlsZVsgbmFtZSBdOwoJCX0KCX0sCgoJY3NzOiBmdW5jdGlvbiggZWxlbSwgbmFtZSwgZXh0cmEsIHN0eWxlcyApIHsKCQl2YXIgdmFsLCBudW0sIGhvb2tzLAoJCQlvcmlnTmFtZSA9IGNhbWVsQ2FzZSggbmFtZSApLAoJCQlpc0N1c3RvbVByb3AgPSByY3VzdG9tUHJvcC50ZXN0KCBuYW1lICk7CgoJCS8vIE1ha2Ugc3VyZSB0aGF0IHdlJ3JlIHdvcmtpbmcgd2l0aCB0aGUgcmlnaHQgbmFtZS4gV2UgZG9uJ3QKCQkvLyB3YW50IHRvIG1vZGlmeSB0aGUgdmFsdWUgaWYgaXQgaXMgYSBDU1MgY3VzdG9tIHByb3BlcnR5CgkJLy8gc2luY2UgdGhleSBhcmUgdXNlci1kZWZpbmVkLgoJCWlmICggIWlzQ3VzdG9tUHJvcCApIHsKCQkJbmFtZSA9IGZpbmFsUHJvcE5hbWUoIG9yaWdOYW1lICk7CgkJfQoKCQkvLyBUcnkgcHJlZml4ZWQgbmFtZSBmb2xsb3dlZCBieSB0aGUgdW5wcmVmaXhlZCBuYW1lCgkJaG9va3MgPSBqUXVlcnkuY3NzSG9va3NbIG5hbWUgXSB8fCBqUXVlcnkuY3NzSG9va3NbIG9yaWdOYW1lIF07CgoJCS8vIElmIGEgaG9vayB3YXMgcHJvdmlkZWQgZ2V0IHRoZSBjb21wdXRlZCB2YWx1ZSBmcm9tIHRoZXJlCgkJaWYgKCBob29rcyAmJiAiZ2V0IiBpbiBob29rcyApIHsKCQkJdmFsID0gaG9va3MuZ2V0KCBlbGVtLCB0cnVlLCBleHRyYSApOwoJCX0KCgkJLy8gT3RoZXJ3aXNlLCBpZiBhIHdheSB0byBnZXQgdGhlIGNvbXB1dGVkIHZhbHVlIGV4aXN0cywgdXNlIHRoYXQKCQlpZiAoIHZhbCA9PT0gdW5kZWZpbmVkICkgewoJCQl2YWwgPSBjdXJDU1MoIGVsZW0sIG5hbWUsIHN0eWxlcyApOwoJCX0KCgkJLy8gQ29udmVydCAibm9ybWFsIiB0byBjb21wdXRlZCB2YWx1ZQoJCWlmICggdmFsID09PSAibm9ybWFsIiAmJiBuYW1lIGluIGNzc05vcm1hbFRyYW5zZm9ybSApIHsKCQkJdmFsID0gY3NzTm9ybWFsVHJhbnNmb3JtWyBuYW1lIF07CgkJfQoKCQkvLyBNYWtlIG51bWVyaWMgaWYgZm9yY2VkIG9yIGEgcXVhbGlmaWVyIHdhcyBwcm92aWRlZCBhbmQgdmFsIGxvb2tzIG51bWVyaWMKCQlpZiAoIGV4dHJhID09PSAiIiB8fCBleHRyYSApIHsKCQkJbnVtID0gcGFyc2VGbG9hdCggdmFsICk7CgkJCXJldHVybiBleHRyYSA9PT0gdHJ1ZSB8fCBpc0Zpbml0ZSggbnVtICkgPyBudW0gfHwgMCA6IHZhbDsKCQl9CgoJCXJldHVybiB2YWw7Cgl9Cn0gKTsKCmpRdWVyeS5lYWNoKCBbICJoZWlnaHQiLCAid2lkdGgiIF0sIGZ1bmN0aW9uKCBpLCBkaW1lbnNpb24gKSB7CglqUXVlcnkuY3NzSG9va3NbIGRpbWVuc2lvbiBdID0gewoJCWdldDogZnVuY3Rpb24oIGVsZW0sIGNvbXB1dGVkLCBleHRyYSApIHsKCQkJaWYgKCBjb21wdXRlZCApIHsKCgkJCQkvLyBDZXJ0YWluIGVsZW1lbnRzIGNhbiBoYXZlIGRpbWVuc2lvbiBpbmZvIGlmIHdlIGludmlzaWJseSBzaG93IHRoZW0KCQkJCS8vIGJ1dCBpdCBtdXN0IGhhdmUgYSBjdXJyZW50IGRpc3BsYXkgc3R5bGUgdGhhdCB3b3VsZCBiZW5lZml0CgkJCQlyZXR1cm4gcmRpc3BsYXlzd2FwLnRlc3QoIGpRdWVyeS5jc3MoIGVsZW0sICJkaXNwbGF5IiApICkgJiYKCgkJCQkJLy8gU3VwcG9ydDogU2FmYXJpIDgrCgkJCQkJLy8gVGFibGUgY29sdW1ucyBpbiBTYWZhcmkgaGF2ZSBub24temVybyBvZmZzZXRXaWR0aCAmIHplcm8KCQkJCQkvLyBnZXRCb3VuZGluZ0NsaWVudFJlY3QoKS53aWR0aCB1bmxlc3MgZGlzcGxheSBpcyBjaGFuZ2VkLgoJCQkJCS8vIFN1cHBvcnQ6IElFIDw9MTEgb25seQoJCQkJCS8vIFJ1bm5pbmcgZ2V0Qm91bmRpbmdDbGllbnRSZWN0IG9uIGEgZGlzY29ubmVjdGVkIG5vZGUKCQkJCQkvLyBpbiBJRSB0aHJvd3MgYW4gZXJyb3IuCgkJCQkJKCAhZWxlbS5nZXRDbGllbnRSZWN0cygpLmxlbmd0aCB8fCAhZWxlbS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS53aWR0aCApID8KCQkJCQkJc3dhcCggZWxlbSwgY3NzU2hvdywgZnVuY3Rpb24oKSB7CgkJCQkJCQlyZXR1cm4gZ2V0V2lkdGhPckhlaWdodCggZWxlbSwgZGltZW5zaW9uLCBleHRyYSApOwoJCQkJCQl9ICkgOgoJCQkJCQlnZXRXaWR0aE9ySGVpZ2h0KCBlbGVtLCBkaW1lbnNpb24sIGV4dHJhICk7CgkJCX0KCQl9LAoKCQlzZXQ6IGZ1bmN0aW9uKCBlbGVtLCB2YWx1ZSwgZXh0cmEgKSB7CgkJCXZhciBtYXRjaGVzLAoJCQkJc3R5bGVzID0gZ2V0U3R5bGVzKCBlbGVtICksCgkJCQlpc0JvcmRlckJveCA9IGpRdWVyeS5jc3MoIGVsZW0sICJib3hTaXppbmciLCBmYWxzZSwgc3R5bGVzICkgPT09ICJib3JkZXItYm94IiwKCQkJCXN1YnRyYWN0ID0gZXh0cmEgJiYgYm94TW9kZWxBZGp1c3RtZW50KAoJCQkJCWVsZW0sCgkJCQkJZGltZW5zaW9uLAoJCQkJCWV4dHJhLAoJCQkJCWlzQm9yZGVyQm94LAoJCQkJCXN0eWxlcwoJCQkJKTsKCgkJCS8vIEFjY291bnQgZm9yIHVucmVsaWFibGUgYm9yZGVyLWJveCBkaW1lbnNpb25zIGJ5IGNvbXBhcmluZyBvZmZzZXQqIHRvIGNvbXB1dGVkIGFuZAoJCQkvLyBmYWtpbmcgYSBjb250ZW50LWJveCB0byBnZXQgYm9yZGVyIGFuZCBwYWRkaW5nIChnaC0zNjk5KQoJCQlpZiAoIGlzQm9yZGVyQm94ICYmIHN1cHBvcnQuc2Nyb2xsYm94U2l6ZSgpID09PSBzdHlsZXMucG9zaXRpb24gKSB7CgkJCQlzdWJ0cmFjdCAtPSBNYXRoLmNlaWwoCgkJCQkJZWxlbVsgIm9mZnNldCIgKyBkaW1lbnNpb25bIDAgXS50b1VwcGVyQ2FzZSgpICsgZGltZW5zaW9uLnNsaWNlKCAxICkgXSAtCgkJCQkJcGFyc2VGbG9hdCggc3R5bGVzWyBkaW1lbnNpb24gXSApIC0KCQkJCQlib3hNb2RlbEFkanVzdG1lbnQoIGVsZW0sIGRpbWVuc2lvbiwgImJvcmRlciIsIGZhbHNlLCBzdHlsZXMgKSAtCgkJCQkJMC41CgkJCQkpOwoJCQl9CgoJCQkvLyBDb252ZXJ0IHRvIHBpeGVscyBpZiB2YWx1ZSBhZGp1c3RtZW50IGlzIG5lZWRlZAoJCQlpZiAoIHN1YnRyYWN0ICYmICggbWF0Y2hlcyA9IHJjc3NOdW0uZXhlYyggdmFsdWUgKSApICYmCgkJCQkoIG1hdGNoZXNbIDMgXSB8fCAicHgiICkgIT09ICJweCIgKSB7CgoJCQkJZWxlbS5zdHlsZVsgZGltZW5zaW9uIF0gPSB2YWx1ZTsKCQkJCXZhbHVlID0galF1ZXJ5LmNzcyggZWxlbSwgZGltZW5zaW9uICk7CgkJCX0KCgkJCXJldHVybiBzZXRQb3NpdGl2ZU51bWJlciggZWxlbSwgdmFsdWUsIHN1YnRyYWN0ICk7CgkJfQoJfTsKfSApOwoKalF1ZXJ5LmNzc0hvb2tzLm1hcmdpbkxlZnQgPSBhZGRHZXRIb29rSWYoIHN1cHBvcnQucmVsaWFibGVNYXJnaW5MZWZ0LAoJZnVuY3Rpb24oIGVsZW0sIGNvbXB1dGVkICkgewoJCWlmICggY29tcHV0ZWQgKSB7CgkJCXJldHVybiAoIHBhcnNlRmxvYXQoIGN1ckNTUyggZWxlbSwgIm1hcmdpbkxlZnQiICkgKSB8fAoJCQkJZWxlbS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5sZWZ0IC0KCQkJCQlzd2FwKCBlbGVtLCB7IG1hcmdpbkxlZnQ6IDAgfSwgZnVuY3Rpb24oKSB7CgkJCQkJCXJldHVybiBlbGVtLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLmxlZnQ7CgkJCQkJfSApCgkJCQkpICsgInB4IjsKCQl9Cgl9Cik7CgovLyBUaGVzZSBob29rcyBhcmUgdXNlZCBieSBhbmltYXRlIHRvIGV4cGFuZCBwcm9wZXJ0aWVzCmpRdWVyeS5lYWNoKCB7CgltYXJnaW46ICIiLAoJcGFkZGluZzogIiIsCglib3JkZXI6ICJXaWR0aCIKfSwgZnVuY3Rpb24oIHByZWZpeCwgc3VmZml4ICkgewoJalF1ZXJ5LmNzc0hvb2tzWyBwcmVmaXggKyBzdWZmaXggXSA9IHsKCQlleHBhbmQ6IGZ1bmN0aW9uKCB2YWx1ZSApIHsKCQkJdmFyIGkgPSAwLAoJCQkJZXhwYW5kZWQgPSB7fSwKCgkJCQkvLyBBc3N1bWVzIGEgc2luZ2xlIG51bWJlciBpZiBub3QgYSBzdHJpbmcKCQkJCXBhcnRzID0gdHlwZW9mIHZhbHVlID09PSAic3RyaW5nIiA/IHZhbHVlLnNwbGl0KCAiICIgKSA6IFsgdmFsdWUgXTsKCgkJCWZvciAoIDsgaSA8IDQ7IGkrKyApIHsKCQkJCWV4cGFuZGVkWyBwcmVmaXggKyBjc3NFeHBhbmRbIGkgXSArIHN1ZmZpeCBdID0KCQkJCQlwYXJ0c1sgaSBdIHx8IHBhcnRzWyBpIC0gMiBdIHx8IHBhcnRzWyAwIF07CgkJCX0KCgkJCXJldHVybiBleHBhbmRlZDsKCQl9Cgl9OwoKCWlmICggcHJlZml4ICE9PSAibWFyZ2luIiApIHsKCQlqUXVlcnkuY3NzSG9va3NbIHByZWZpeCArIHN1ZmZpeCBdLnNldCA9IHNldFBvc2l0aXZlTnVtYmVyOwoJfQp9ICk7CgpqUXVlcnkuZm4uZXh0ZW5kKCB7Cgljc3M6IGZ1bmN0aW9uKCBuYW1lLCB2YWx1ZSApIHsKCQlyZXR1cm4gYWNjZXNzKCB0aGlzLCBmdW5jdGlvbiggZWxlbSwgbmFtZSwgdmFsdWUgKSB7CgkJCXZhciBzdHlsZXMsIGxlbiwKCQkJCW1hcCA9IHt9LAoJCQkJaSA9IDA7CgoJCQlpZiAoIEFycmF5LmlzQXJyYXkoIG5hbWUgKSApIHsKCQkJCXN0eWxlcyA9IGdldFN0eWxlcyggZWxlbSApOwoJCQkJbGVuID0gbmFtZS5sZW5ndGg7CgoJCQkJZm9yICggOyBpIDwgbGVuOyBpKysgKSB7CgkJCQkJbWFwWyBuYW1lWyBpIF0gXSA9IGpRdWVyeS5jc3MoIGVsZW0sIG5hbWVbIGkgXSwgZmFsc2UsIHN0eWxlcyApOwoJCQkJfQoKCQkJCXJldHVybiBtYXA7CgkJCX0KCgkJCXJldHVybiB2YWx1ZSAhPT0gdW5kZWZpbmVkID8KCQkJCWpRdWVyeS5zdHlsZSggZWxlbSwgbmFtZSwgdmFsdWUgKSA6CgkJCQlqUXVlcnkuY3NzKCBlbGVtLCBuYW1lICk7CgkJfSwgbmFtZSwgdmFsdWUsIGFyZ3VtZW50cy5sZW5ndGggPiAxICk7Cgl9Cn0gKTsKCgpmdW5jdGlvbiBUd2VlbiggZWxlbSwgb3B0aW9ucywgcHJvcCwgZW5kLCBlYXNpbmcgKSB7CglyZXR1cm4gbmV3IFR3ZWVuLnByb3RvdHlwZS5pbml0KCBlbGVtLCBvcHRpb25zLCBwcm9wLCBlbmQsIGVhc2luZyApOwp9CmpRdWVyeS5Ud2VlbiA9IFR3ZWVuOwoKVHdlZW4ucHJvdG90eXBlID0gewoJY29uc3RydWN0b3I6IFR3ZWVuLAoJaW5pdDogZnVuY3Rpb24oIGVsZW0sIG9wdGlvbnMsIHByb3AsIGVuZCwgZWFzaW5nLCB1bml0ICkgewoJCXRoaXMuZWxlbSA9IGVsZW07CgkJdGhpcy5wcm9wID0gcHJvcDsKCQl0aGlzLmVhc2luZyA9IGVhc2luZyB8fCBqUXVlcnkuZWFzaW5nLl9kZWZhdWx0OwoJCXRoaXMub3B0aW9ucyA9IG9wdGlvbnM7CgkJdGhpcy5zdGFydCA9IHRoaXMubm93ID0gdGhpcy5jdXIoKTsKCQl0aGlzLmVuZCA9IGVuZDsKCQl0aGlzLnVuaXQgPSB1bml0IHx8ICggalF1ZXJ5LmNzc051bWJlclsgcHJvcCBdID8gIiIgOiAicHgiICk7Cgl9LAoJY3VyOiBmdW5jdGlvbigpIHsKCQl2YXIgaG9va3MgPSBUd2Vlbi5wcm9wSG9va3NbIHRoaXMucHJvcCBdOwoKCQlyZXR1cm4gaG9va3MgJiYgaG9va3MuZ2V0ID8KCQkJaG9va3MuZ2V0KCB0aGlzICkgOgoJCQlUd2Vlbi5wcm9wSG9va3MuX2RlZmF1bHQuZ2V0KCB0aGlzICk7Cgl9LAoJcnVuOiBmdW5jdGlvbiggcGVyY2VudCApIHsKCQl2YXIgZWFzZWQsCgkJCWhvb2tzID0gVHdlZW4ucHJvcEhvb2tzWyB0aGlzLnByb3AgXTsKCgkJaWYgKCB0aGlzLm9wdGlvbnMuZHVyYXRpb24gKSB7CgkJCXRoaXMucG9zID0gZWFzZWQgPSBqUXVlcnkuZWFzaW5nWyB0aGlzLmVhc2luZyBdKAoJCQkJcGVyY2VudCwgdGhpcy5vcHRpb25zLmR1cmF0aW9uICogcGVyY2VudCwgMCwgMSwgdGhpcy5vcHRpb25zLmR1cmF0aW9uCgkJCSk7CgkJfSBlbHNlIHsKCQkJdGhpcy5wb3MgPSBlYXNlZCA9IHBlcmNlbnQ7CgkJfQoJCXRoaXMubm93ID0gKCB0aGlzLmVuZCAtIHRoaXMuc3RhcnQgKSAqIGVhc2VkICsgdGhpcy5zdGFydDsKCgkJaWYgKCB0aGlzLm9wdGlvbnMuc3RlcCApIHsKCQkJdGhpcy5vcHRpb25zLnN0ZXAuY2FsbCggdGhpcy5lbGVtLCB0aGlzLm5vdywgdGhpcyApOwoJCX0KCgkJaWYgKCBob29rcyAmJiBob29rcy5zZXQgKSB7CgkJCWhvb2tzLnNldCggdGhpcyApOwoJCX0gZWxzZSB7CgkJCVR3ZWVuLnByb3BIb29rcy5fZGVmYXVsdC5zZXQoIHRoaXMgKTsKCQl9CgkJcmV0dXJuIHRoaXM7Cgl9Cn07CgpUd2Vlbi5wcm90b3R5cGUuaW5pdC5wcm90b3R5cGUgPSBUd2Vlbi5wcm90b3R5cGU7CgpUd2Vlbi5wcm9wSG9va3MgPSB7CglfZGVmYXVsdDogewoJCWdldDogZnVuY3Rpb24oIHR3ZWVuICkgewoJCQl2YXIgcmVzdWx0OwoKCQkJLy8gVXNlIGEgcHJvcGVydHkgb24gdGhlIGVsZW1lbnQgZGlyZWN0bHkgd2hlbiBpdCBpcyBub3QgYSBET00gZWxlbWVudCwKCQkJLy8gb3Igd2hlbiB0aGVyZSBpcyBubyBtYXRjaGluZyBzdHlsZSBwcm9wZXJ0eSB0aGF0IGV4aXN0cy4KCQkJaWYgKCB0d2Vlbi5lbGVtLm5vZGVUeXBlICE9PSAxIHx8CgkJCQl0d2Vlbi5lbGVtWyB0d2Vlbi5wcm9wIF0gIT0gbnVsbCAmJiB0d2Vlbi5lbGVtLnN0eWxlWyB0d2Vlbi5wcm9wIF0gPT0gbnVsbCApIHsKCQkJCXJldHVybiB0d2Vlbi5lbGVtWyB0d2Vlbi5wcm9wIF07CgkJCX0KCgkJCS8vIFBhc3NpbmcgYW4gZW1wdHkgc3RyaW5nIGFzIGEgM3JkIHBhcmFtZXRlciB0byAuY3NzIHdpbGwgYXV0b21hdGljYWxseQoJCQkvLyBhdHRlbXB0IGEgcGFyc2VGbG9hdCBhbmQgZmFsbGJhY2sgdG8gYSBzdHJpbmcgaWYgdGhlIHBhcnNlIGZhaWxzLgoJCQkvLyBTaW1wbGUgdmFsdWVzIHN1Y2ggYXMgIjEwcHgiIGFyZSBwYXJzZWQgdG8gRmxvYXQ7CgkJCS8vIGNvbXBsZXggdmFsdWVzIHN1Y2ggYXMgInJvdGF0ZSgxcmFkKSIgYXJlIHJldHVybmVkIGFzLWlzLgoJCQlyZXN1bHQgPSBqUXVlcnkuY3NzKCB0d2Vlbi5lbGVtLCB0d2Vlbi5wcm9wLCAiIiApOwoKCQkJLy8gRW1wdHkgc3RyaW5ncywgbnVsbCwgdW5kZWZpbmVkIGFuZCAiYXV0byIgYXJlIGNvbnZlcnRlZCB0byAwLgoJCQlyZXR1cm4gIXJlc3VsdCB8fCByZXN1bHQgPT09ICJhdXRvIiA/IDAgOiByZXN1bHQ7CgkJfSwKCQlzZXQ6IGZ1bmN0aW9uKCB0d2VlbiApIHsKCgkJCS8vIFVzZSBzdGVwIGhvb2sgZm9yIGJhY2sgY29tcGF0LgoJCQkvLyBVc2UgY3NzSG9vayBpZiBpdHMgdGhlcmUuCgkJCS8vIFVzZSAuc3R5bGUgaWYgYXZhaWxhYmxlIGFuZCB1c2UgcGxhaW4gcHJvcGVydGllcyB3aGVyZSBhdmFpbGFibGUuCgkJCWlmICggalF1ZXJ5LmZ4LnN0ZXBbIHR3ZWVuLnByb3AgXSApIHsKCQkJCWpRdWVyeS5meC5zdGVwWyB0d2Vlbi5wcm9wIF0oIHR3ZWVuICk7CgkJCX0gZWxzZSBpZiAoIHR3ZWVuLmVsZW0ubm9kZVR5cGUgPT09IDEgJiYKCQkJCSggdHdlZW4uZWxlbS5zdHlsZVsgalF1ZXJ5LmNzc1Byb3BzWyB0d2Vlbi5wcm9wIF0gXSAhPSBudWxsIHx8CgkJCQkJalF1ZXJ5LmNzc0hvb2tzWyB0d2Vlbi5wcm9wIF0gKSApIHsKCQkJCWpRdWVyeS5zdHlsZSggdHdlZW4uZWxlbSwgdHdlZW4ucHJvcCwgdHdlZW4ubm93ICsgdHdlZW4udW5pdCApOwoJCQl9IGVsc2UgewoJCQkJdHdlZW4uZWxlbVsgdHdlZW4ucHJvcCBdID0gdHdlZW4ubm93OwoJCQl9CgkJfQoJfQp9OwoKLy8gU3VwcG9ydDogSUUgPD05IG9ubHkKLy8gUGFuaWMgYmFzZWQgYXBwcm9hY2ggdG8gc2V0dGluZyB0aGluZ3Mgb24gZGlzY29ubmVjdGVkIG5vZGVzClR3ZWVuLnByb3BIb29rcy5zY3JvbGxUb3AgPSBUd2Vlbi5wcm9wSG9va3Muc2Nyb2xsTGVmdCA9IHsKCXNldDogZnVuY3Rpb24oIHR3ZWVuICkgewoJCWlmICggdHdlZW4uZWxlbS5ub2RlVHlwZSAmJiB0d2Vlbi5lbGVtLnBhcmVudE5vZGUgKSB7CgkJCXR3ZWVuLmVsZW1bIHR3ZWVuLnByb3AgXSA9IHR3ZWVuLm5vdzsKCQl9Cgl9Cn07CgpqUXVlcnkuZWFzaW5nID0gewoJbGluZWFyOiBmdW5jdGlvbiggcCApIHsKCQlyZXR1cm4gcDsKCX0sCglzd2luZzogZnVuY3Rpb24oIHAgKSB7CgkJcmV0dXJuIDAuNSAtIE1hdGguY29zKCBwICogTWF0aC5QSSApIC8gMjsKCX0sCglfZGVmYXVsdDogInN3aW5nIgp9OwoKalF1ZXJ5LmZ4ID0gVHdlZW4ucHJvdG90eXBlLmluaXQ7CgovLyBCYWNrIGNvbXBhdCA8MS44IGV4dGVuc2lvbiBwb2ludApqUXVlcnkuZnguc3RlcCA9IHt9OwoKCgoKdmFyCglmeE5vdywgaW5Qcm9ncmVzcywKCXJmeHR5cGVzID0gL14oPzp0b2dnbGV8c2hvd3xoaWRlKSQvLAoJcnJ1biA9IC9xdWV1ZUhvb2tzJC87CgpmdW5jdGlvbiBzY2hlZHVsZSgpIHsKCWlmICggaW5Qcm9ncmVzcyApIHsKCQlpZiAoIGRvY3VtZW50LmhpZGRlbiA9PT0gZmFsc2UgJiYgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSApIHsKCQkJd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSggc2NoZWR1bGUgKTsKCQl9IGVsc2UgewoJCQl3aW5kb3cuc2V0VGltZW91dCggc2NoZWR1bGUsIGpRdWVyeS5meC5pbnRlcnZhbCApOwoJCX0KCgkJalF1ZXJ5LmZ4LnRpY2soKTsKCX0KfQoKLy8gQW5pbWF0aW9ucyBjcmVhdGVkIHN5bmNocm9ub3VzbHkgd2lsbCBydW4gc3luY2hyb25vdXNseQpmdW5jdGlvbiBjcmVhdGVGeE5vdygpIHsKCXdpbmRvdy5zZXRUaW1lb3V0KCBmdW5jdGlvbigpIHsKCQlmeE5vdyA9IHVuZGVmaW5lZDsKCX0gKTsKCXJldHVybiAoIGZ4Tm93ID0gRGF0ZS5ub3coKSApOwp9CgovLyBHZW5lcmF0ZSBwYXJhbWV0ZXJzIHRvIGNyZWF0ZSBhIHN0YW5kYXJkIGFuaW1hdGlvbgpmdW5jdGlvbiBnZW5GeCggdHlwZSwgaW5jbHVkZVdpZHRoICkgewoJdmFyIHdoaWNoLAoJCWkgPSAwLAoJCWF0dHJzID0geyBoZWlnaHQ6IHR5cGUgfTsKCgkvLyBJZiB3ZSBpbmNsdWRlIHdpZHRoLCBzdGVwIHZhbHVlIGlzIDEgdG8gZG8gYWxsIGNzc0V4cGFuZCB2YWx1ZXMsCgkvLyBvdGhlcndpc2Ugc3RlcCB2YWx1ZSBpcyAyIHRvIHNraXAgb3ZlciBMZWZ0IGFuZCBSaWdodAoJaW5jbHVkZVdpZHRoID0gaW5jbHVkZVdpZHRoID8gMSA6IDA7Cglmb3IgKCA7IGkgPCA0OyBpICs9IDIgLSBpbmNsdWRlV2lkdGggKSB7CgkJd2hpY2ggPSBjc3NFeHBhbmRbIGkgXTsKCQlhdHRyc1sgIm1hcmdpbiIgKyB3aGljaCBdID0gYXR0cnNbICJwYWRkaW5nIiArIHdoaWNoIF0gPSB0eXBlOwoJfQoKCWlmICggaW5jbHVkZVdpZHRoICkgewoJCWF0dHJzLm9wYWNpdHkgPSBhdHRycy53aWR0aCA9IHR5cGU7Cgl9CgoJcmV0dXJuIGF0dHJzOwp9CgpmdW5jdGlvbiBjcmVhdGVUd2VlbiggdmFsdWUsIHByb3AsIGFuaW1hdGlvbiApIHsKCXZhciB0d2VlbiwKCQljb2xsZWN0aW9uID0gKCBBbmltYXRpb24udHdlZW5lcnNbIHByb3AgXSB8fCBbXSApLmNvbmNhdCggQW5pbWF0aW9uLnR3ZWVuZXJzWyAiKiIgXSApLAoJCWluZGV4ID0gMCwKCQlsZW5ndGggPSBjb2xsZWN0aW9uLmxlbmd0aDsKCWZvciAoIDsgaW5kZXggPCBsZW5ndGg7IGluZGV4KysgKSB7CgkJaWYgKCAoIHR3ZWVuID0gY29sbGVjdGlvblsgaW5kZXggXS5jYWxsKCBhbmltYXRpb24sIHByb3AsIHZhbHVlICkgKSApIHsKCgkJCS8vIFdlJ3JlIGRvbmUgd2l0aCB0aGlzIHByb3BlcnR5CgkJCXJldHVybiB0d2VlbjsKCQl9Cgl9Cn0KCmZ1bmN0aW9uIGRlZmF1bHRQcmVmaWx0ZXIoIGVsZW0sIHByb3BzLCBvcHRzICkgewoJdmFyIHByb3AsIHZhbHVlLCB0b2dnbGUsIGhvb2tzLCBvbGRmaXJlLCBwcm9wVHdlZW4sIHJlc3RvcmVEaXNwbGF5LCBkaXNwbGF5LAoJCWlzQm94ID0gIndpZHRoIiBpbiBwcm9wcyB8fCAiaGVpZ2h0IiBpbiBwcm9wcywKCQlhbmltID0gdGhpcywKCQlvcmlnID0ge30sCgkJc3R5bGUgPSBlbGVtLnN0eWxlLAoJCWhpZGRlbiA9IGVsZW0ubm9kZVR5cGUgJiYgaXNIaWRkZW5XaXRoaW5UcmVlKCBlbGVtICksCgkJZGF0YVNob3cgPSBkYXRhUHJpdi5nZXQoIGVsZW0sICJmeHNob3ciICk7CgoJLy8gUXVldWUtc2tpcHBpbmcgYW5pbWF0aW9ucyBoaWphY2sgdGhlIGZ4IGhvb2tzCglpZiAoICFvcHRzLnF1ZXVlICkgewoJCWhvb2tzID0galF1ZXJ5Ll9xdWV1ZUhvb2tzKCBlbGVtLCAiZngiICk7CgkJaWYgKCBob29rcy51bnF1ZXVlZCA9PSBudWxsICkgewoJCQlob29rcy51bnF1ZXVlZCA9IDA7CgkJCW9sZGZpcmUgPSBob29rcy5lbXB0eS5maXJlOwoJCQlob29rcy5lbXB0eS5maXJlID0gZnVuY3Rpb24oKSB7CgkJCQlpZiAoICFob29rcy51bnF1ZXVlZCApIHsKCQkJCQlvbGRmaXJlKCk7CgkJCQl9CgkJCX07CgkJfQoJCWhvb2tzLnVucXVldWVkKys7CgoJCWFuaW0uYWx3YXlzKCBmdW5jdGlvbigpIHsKCgkJCS8vIEVuc3VyZSB0aGUgY29tcGxldGUgaGFuZGxlciBpcyBjYWxsZWQgYmVmb3JlIHRoaXMgY29tcGxldGVzCgkJCWFuaW0uYWx3YXlzKCBmdW5jdGlvbigpIHsKCQkJCWhvb2tzLnVucXVldWVkLS07CgkJCQlpZiAoICFqUXVlcnkucXVldWUoIGVsZW0sICJmeCIgKS5sZW5ndGggKSB7CgkJCQkJaG9va3MuZW1wdHkuZmlyZSgpOwoJCQkJfQoJCQl9ICk7CgkJfSApOwoJfQoKCS8vIERldGVjdCBzaG93L2hpZGUgYW5pbWF0aW9ucwoJZm9yICggcHJvcCBpbiBwcm9wcyApIHsKCQl2YWx1ZSA9IHByb3BzWyBwcm9wIF07CgkJaWYgKCByZnh0eXBlcy50ZXN0KCB2YWx1ZSApICkgewoJCQlkZWxldGUgcHJvcHNbIHByb3AgXTsKCQkJdG9nZ2xlID0gdG9nZ2xlIHx8IHZhbHVlID09PSAidG9nZ2xlIjsKCQkJaWYgKCB2YWx1ZSA9PT0gKCBoaWRkZW4gPyAiaGlkZSIgOiAic2hvdyIgKSApIHsKCgkJCQkvLyBQcmV0ZW5kIHRvIGJlIGhpZGRlbiBpZiB0aGlzIGlzIGEgInNob3ciIGFuZAoJCQkJLy8gdGhlcmUgaXMgc3RpbGwgZGF0YSBmcm9tIGEgc3RvcHBlZCBzaG93L2hpZGUKCQkJCWlmICggdmFsdWUgPT09ICJzaG93IiAmJiBkYXRhU2hvdyAmJiBkYXRhU2hvd1sgcHJvcCBdICE9PSB1bmRlZmluZWQgKSB7CgkJCQkJaGlkZGVuID0gdHJ1ZTsKCgkJCQkvLyBJZ25vcmUgYWxsIG90aGVyIG5vLW9wIHNob3cvaGlkZSBkYXRhCgkJCQl9IGVsc2UgewoJCQkJCWNvbnRpbnVlOwoJCQkJfQoJCQl9CgkJCW9yaWdbIHByb3AgXSA9IGRhdGFTaG93ICYmIGRhdGFTaG93WyBwcm9wIF0gfHwgalF1ZXJ5LnN0eWxlKCBlbGVtLCBwcm9wICk7CgkJfQoJfQoKCS8vIEJhaWwgb3V0IGlmIHRoaXMgaXMgYSBuby1vcCBsaWtlIC5oaWRlKCkuaGlkZSgpCglwcm9wVHdlZW4gPSAhalF1ZXJ5LmlzRW1wdHlPYmplY3QoIHByb3BzICk7CglpZiAoICFwcm9wVHdlZW4gJiYgalF1ZXJ5LmlzRW1wdHlPYmplY3QoIG9yaWcgKSApIHsKCQlyZXR1cm47Cgl9CgoJLy8gUmVzdHJpY3QgIm92ZXJmbG93IiBhbmQgImRpc3BsYXkiIHN0eWxlcyBkdXJpbmcgYm94IGFuaW1hdGlvbnMKCWlmICggaXNCb3ggJiYgZWxlbS5ub2RlVHlwZSA9PT0gMSApIHsKCgkJLy8gU3VwcG9ydDogSUUgPD05IC0gMTEsIEVkZ2UgMTIgLSAxNQoJCS8vIFJlY29yZCBhbGwgMyBvdmVyZmxvdyBhdHRyaWJ1dGVzIGJlY2F1c2UgSUUgZG9lcyBub3QgaW5mZXIgdGhlIHNob3J0aGFuZAoJCS8vIGZyb20gaWRlbnRpY2FsbHktdmFsdWVkIG92ZXJmbG93WCBhbmQgb3ZlcmZsb3dZIGFuZCBFZGdlIGp1c3QgbWlycm9ycwoJCS8vIHRoZSBvdmVyZmxvd1ggdmFsdWUgdGhlcmUuCgkJb3B0cy5vdmVyZmxvdyA9IFsgc3R5bGUub3ZlcmZsb3csIHN0eWxlLm92ZXJmbG93WCwgc3R5bGUub3ZlcmZsb3dZIF07CgoJCS8vIElkZW50aWZ5IGEgZGlzcGxheSB0eXBlLCBwcmVmZXJyaW5nIG9sZCBzaG93L2hpZGUgZGF0YSBvdmVyIHRoZSBDU1MgY2FzY2FkZQoJCXJlc3RvcmVEaXNwbGF5ID0gZGF0YVNob3cgJiYgZGF0YVNob3cuZGlzcGxheTsKCQlpZiAoIHJlc3RvcmVEaXNwbGF5ID09IG51bGwgKSB7CgkJCXJlc3RvcmVEaXNwbGF5ID0gZGF0YVByaXYuZ2V0KCBlbGVtLCAiZGlzcGxheSIgKTsKCQl9CgkJZGlzcGxheSA9IGpRdWVyeS5jc3MoIGVsZW0sICJkaXNwbGF5IiApOwoJCWlmICggZGlzcGxheSA9PT0gIm5vbmUiICkgewoJCQlpZiAoIHJlc3RvcmVEaXNwbGF5ICkgewoJCQkJZGlzcGxheSA9IHJlc3RvcmVEaXNwbGF5OwoJCQl9IGVsc2UgewoKCQkJCS8vIEdldCBub25lbXB0eSB2YWx1ZShzKSBieSB0ZW1wb3JhcmlseSBmb3JjaW5nIHZpc2liaWxpdHkKCQkJCXNob3dIaWRlKCBbIGVsZW0gXSwgdHJ1ZSApOwoJCQkJcmVzdG9yZURpc3BsYXkgPSBlbGVtLnN0eWxlLmRpc3BsYXkgfHwgcmVzdG9yZURpc3BsYXk7CgkJCQlkaXNwbGF5ID0galF1ZXJ5LmNzcyggZWxlbSwgImRpc3BsYXkiICk7CgkJCQlzaG93SGlkZSggWyBlbGVtIF0gKTsKCQkJfQoJCX0KCgkJLy8gQW5pbWF0ZSBpbmxpbmUgZWxlbWVudHMgYXMgaW5saW5lLWJsb2NrCgkJaWYgKCBkaXNwbGF5ID09PSAiaW5saW5lIiB8fCBkaXNwbGF5ID09PSAiaW5saW5lLWJsb2NrIiAmJiByZXN0b3JlRGlzcGxheSAhPSBudWxsICkgewoJCQlpZiAoIGpRdWVyeS5jc3MoIGVsZW0sICJmbG9hdCIgKSA9PT0gIm5vbmUiICkgewoKCQkJCS8vIFJlc3RvcmUgdGhlIG9yaWdpbmFsIGRpc3BsYXkgdmFsdWUgYXQgdGhlIGVuZCBvZiBwdXJlIHNob3cvaGlkZSBhbmltYXRpb25zCgkJCQlpZiAoICFwcm9wVHdlZW4gKSB7CgkJCQkJYW5pbS5kb25lKCBmdW5jdGlvbigpIHsKCQkJCQkJc3R5bGUuZGlzcGxheSA9IHJlc3RvcmVEaXNwbGF5OwoJCQkJCX0gKTsKCQkJCQlpZiAoIHJlc3RvcmVEaXNwbGF5ID09IG51bGwgKSB7CgkJCQkJCWRpc3BsYXkgPSBzdHlsZS5kaXNwbGF5OwoJCQkJCQlyZXN0b3JlRGlzcGxheSA9IGRpc3BsYXkgPT09ICJub25lIiA/ICIiIDogZGlzcGxheTsKCQkJCQl9CgkJCQl9CgkJCQlzdHlsZS5kaXNwbGF5ID0gImlubGluZS1ibG9jayI7CgkJCX0KCQl9Cgl9CgoJaWYgKCBvcHRzLm92ZXJmbG93ICkgewoJCXN0eWxlLm92ZXJmbG93ID0gImhpZGRlbiI7CgkJYW5pbS5hbHdheXMoIGZ1bmN0aW9uKCkgewoJCQlzdHlsZS5vdmVyZmxvdyA9IG9wdHMub3ZlcmZsb3dbIDAgXTsKCQkJc3R5bGUub3ZlcmZsb3dYID0gb3B0cy5vdmVyZmxvd1sgMSBdOwoJCQlzdHlsZS5vdmVyZmxvd1kgPSBvcHRzLm92ZXJmbG93WyAyIF07CgkJfSApOwoJfQoKCS8vIEltcGxlbWVudCBzaG93L2hpZGUgYW5pbWF0aW9ucwoJcHJvcFR3ZWVuID0gZmFsc2U7Cglmb3IgKCBwcm9wIGluIG9yaWcgKSB7CgoJCS8vIEdlbmVyYWwgc2hvdy9oaWRlIHNldHVwIGZvciB0aGlzIGVsZW1lbnQgYW5pbWF0aW9uCgkJaWYgKCAhcHJvcFR3ZWVuICkgewoJCQlpZiAoIGRhdGFTaG93ICkgewoJCQkJaWYgKCAiaGlkZGVuIiBpbiBkYXRhU2hvdyApIHsKCQkJCQloaWRkZW4gPSBkYXRhU2hvdy5oaWRkZW47CgkJCQl9CgkJCX0gZWxzZSB7CgkJCQlkYXRhU2hvdyA9IGRhdGFQcml2LmFjY2VzcyggZWxlbSwgImZ4c2hvdyIsIHsgZGlzcGxheTogcmVzdG9yZURpc3BsYXkgfSApOwoJCQl9CgoJCQkvLyBTdG9yZSBoaWRkZW4vdmlzaWJsZSBmb3IgdG9nZ2xlIHNvIGAuc3RvcCgpLnRvZ2dsZSgpYCAicmV2ZXJzZXMiCgkJCWlmICggdG9nZ2xlICkgewoJCQkJZGF0YVNob3cuaGlkZGVuID0gIWhpZGRlbjsKCQkJfQoKCQkJLy8gU2hvdyBlbGVtZW50cyBiZWZvcmUgYW5pbWF0aW5nIHRoZW0KCQkJaWYgKCBoaWRkZW4gKSB7CgkJCQlzaG93SGlkZSggWyBlbGVtIF0sIHRydWUgKTsKCQkJfQoKCQkJLyogZXNsaW50LWRpc2FibGUgbm8tbG9vcC1mdW5jICovCgoJCQlhbmltLmRvbmUoIGZ1bmN0aW9uKCkgewoKCQkJLyogZXNsaW50LWVuYWJsZSBuby1sb29wLWZ1bmMgKi8KCgkJCQkvLyBUaGUgZmluYWwgc3RlcCBvZiBhICJoaWRlIiBhbmltYXRpb24gaXMgYWN0dWFsbHkgaGlkaW5nIHRoZSBlbGVtZW50CgkJCQlpZiAoICFoaWRkZW4gKSB7CgkJCQkJc2hvd0hpZGUoIFsgZWxlbSBdICk7CgkJCQl9CgkJCQlkYXRhUHJpdi5yZW1vdmUoIGVsZW0sICJmeHNob3ciICk7CgkJCQlmb3IgKCBwcm9wIGluIG9yaWcgKSB7CgkJCQkJalF1ZXJ5LnN0eWxlKCBlbGVtLCBwcm9wLCBvcmlnWyBwcm9wIF0gKTsKCQkJCX0KCQkJfSApOwoJCX0KCgkJLy8gUGVyLXByb3BlcnR5IHNldHVwCgkJcHJvcFR3ZWVuID0gY3JlYXRlVHdlZW4oIGhpZGRlbiA/IGRhdGFTaG93WyBwcm9wIF0gOiAwLCBwcm9wLCBhbmltICk7CgkJaWYgKCAhKCBwcm9wIGluIGRhdGFTaG93ICkgKSB7CgkJCWRhdGFTaG93WyBwcm9wIF0gPSBwcm9wVHdlZW4uc3RhcnQ7CgkJCWlmICggaGlkZGVuICkgewoJCQkJcHJvcFR3ZWVuLmVuZCA9IHByb3BUd2Vlbi5zdGFydDsKCQkJCXByb3BUd2Vlbi5zdGFydCA9IDA7CgkJCX0KCQl9Cgl9Cn0KCmZ1bmN0aW9uIHByb3BGaWx0ZXIoIHByb3BzLCBzcGVjaWFsRWFzaW5nICkgewoJdmFyIGluZGV4LCBuYW1lLCBlYXNpbmcsIHZhbHVlLCBob29rczsKCgkvLyBjYW1lbENhc2UsIHNwZWNpYWxFYXNpbmcgYW5kIGV4cGFuZCBjc3NIb29rIHBhc3MKCWZvciAoIGluZGV4IGluIHByb3BzICkgewoJCW5hbWUgPSBjYW1lbENhc2UoIGluZGV4ICk7CgkJZWFzaW5nID0gc3BlY2lhbEVhc2luZ1sgbmFtZSBdOwoJCXZhbHVlID0gcHJvcHNbIGluZGV4IF07CgkJaWYgKCBBcnJheS5pc0FycmF5KCB2YWx1ZSApICkgewoJCQllYXNpbmcgPSB2YWx1ZVsgMSBdOwoJCQl2YWx1ZSA9IHByb3BzWyBpbmRleCBdID0gdmFsdWVbIDAgXTsKCQl9CgoJCWlmICggaW5kZXggIT09IG5hbWUgKSB7CgkJCXByb3BzWyBuYW1lIF0gPSB2YWx1ZTsKCQkJZGVsZXRlIHByb3BzWyBpbmRleCBdOwoJCX0KCgkJaG9va3MgPSBqUXVlcnkuY3NzSG9va3NbIG5hbWUgXTsKCQlpZiAoIGhvb2tzICYmICJleHBhbmQiIGluIGhvb2tzICkgewoJCQl2YWx1ZSA9IGhvb2tzLmV4cGFuZCggdmFsdWUgKTsKCQkJZGVsZXRlIHByb3BzWyBuYW1lIF07CgoJCQkvLyBOb3QgcXVpdGUgJC5leHRlbmQsIHRoaXMgd29uJ3Qgb3ZlcndyaXRlIGV4aXN0aW5nIGtleXMuCgkJCS8vIFJldXNpbmcgJ2luZGV4JyBiZWNhdXNlIHdlIGhhdmUgdGhlIGNvcnJlY3QgIm5hbWUiCgkJCWZvciAoIGluZGV4IGluIHZhbHVlICkgewoJCQkJaWYgKCAhKCBpbmRleCBpbiBwcm9wcyApICkgewoJCQkJCXByb3BzWyBpbmRleCBdID0gdmFsdWVbIGluZGV4IF07CgkJCQkJc3BlY2lhbEVhc2luZ1sgaW5kZXggXSA9IGVhc2luZzsKCQkJCX0KCQkJfQoJCX0gZWxzZSB7CgkJCXNwZWNpYWxFYXNpbmdbIG5hbWUgXSA9IGVhc2luZzsKCQl9Cgl9Cn0KCmZ1bmN0aW9uIEFuaW1hdGlvbiggZWxlbSwgcHJvcGVydGllcywgb3B0aW9ucyApIHsKCXZhciByZXN1bHQsCgkJc3RvcHBlZCwKCQlpbmRleCA9IDAsCgkJbGVuZ3RoID0gQW5pbWF0aW9uLnByZWZpbHRlcnMubGVuZ3RoLAoJCWRlZmVycmVkID0galF1ZXJ5LkRlZmVycmVkKCkuYWx3YXlzKCBmdW5jdGlvbigpIHsKCgkJCS8vIERvbid0IG1hdGNoIGVsZW0gaW4gdGhlIDphbmltYXRlZCBzZWxlY3RvcgoJCQlkZWxldGUgdGljay5lbGVtOwoJCX0gKSwKCQl0aWNrID0gZnVuY3Rpb24oKSB7CgkJCWlmICggc3RvcHBlZCApIHsKCQkJCXJldHVybiBmYWxzZTsKCQkJfQoJCQl2YXIgY3VycmVudFRpbWUgPSBmeE5vdyB8fCBjcmVhdGVGeE5vdygpLAoJCQkJcmVtYWluaW5nID0gTWF0aC5tYXgoIDAsIGFuaW1hdGlvbi5zdGFydFRpbWUgKyBhbmltYXRpb24uZHVyYXRpb24gLSBjdXJyZW50VGltZSApLAoKCQkJCS8vIFN1cHBvcnQ6IEFuZHJvaWQgMi4zIG9ubHkKCQkJCS8vIEFyY2hhaWMgY3Jhc2ggYnVnIHdvbid0IGFsbG93IHVzIHRvIHVzZSBgMSAtICggMC41IHx8IDAgKWAgKCMxMjQ5NykKCQkJCXRlbXAgPSByZW1haW5pbmcgLyBhbmltYXRpb24uZHVyYXRpb24gfHwgMCwKCQkJCXBlcmNlbnQgPSAxIC0gdGVtcCwKCQkJCWluZGV4ID0gMCwKCQkJCWxlbmd0aCA9IGFuaW1hdGlvbi50d2VlbnMubGVuZ3RoOwoKCQkJZm9yICggOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKyApIHsKCQkJCWFuaW1hdGlvbi50d2VlbnNbIGluZGV4IF0ucnVuKCBwZXJjZW50ICk7CgkJCX0KCgkJCWRlZmVycmVkLm5vdGlmeVdpdGgoIGVsZW0sIFsgYW5pbWF0aW9uLCBwZXJjZW50LCByZW1haW5pbmcgXSApOwoKCQkJLy8gSWYgdGhlcmUncyBtb3JlIHRvIGRvLCB5aWVsZAoJCQlpZiAoIHBlcmNlbnQgPCAxICYmIGxlbmd0aCApIHsKCQkJCXJldHVybiByZW1haW5pbmc7CgkJCX0KCgkJCS8vIElmIHRoaXMgd2FzIGFuIGVtcHR5IGFuaW1hdGlvbiwgc3ludGhlc2l6ZSBhIGZpbmFsIHByb2dyZXNzIG5vdGlmaWNhdGlvbgoJCQlpZiAoICFsZW5ndGggKSB7CgkJCQlkZWZlcnJlZC5ub3RpZnlXaXRoKCBlbGVtLCBbIGFuaW1hdGlvbiwgMSwgMCBdICk7CgkJCX0KCgkJCS8vIFJlc29sdmUgdGhlIGFuaW1hdGlvbiBhbmQgcmVwb3J0IGl0cyBjb25jbHVzaW9uCgkJCWRlZmVycmVkLnJlc29sdmVXaXRoKCBlbGVtLCBbIGFuaW1hdGlvbiBdICk7CgkJCXJldHVybiBmYWxzZTsKCQl9LAoJCWFuaW1hdGlvbiA9IGRlZmVycmVkLnByb21pc2UoIHsKCQkJZWxlbTogZWxlbSwKCQkJcHJvcHM6IGpRdWVyeS5leHRlbmQoIHt9LCBwcm9wZXJ0aWVzICksCgkJCW9wdHM6IGpRdWVyeS5leHRlbmQoIHRydWUsIHsKCQkJCXNwZWNpYWxFYXNpbmc6IHt9LAoJCQkJZWFzaW5nOiBqUXVlcnkuZWFzaW5nLl9kZWZhdWx0CgkJCX0sIG9wdGlvbnMgKSwKCQkJb3JpZ2luYWxQcm9wZXJ0aWVzOiBwcm9wZXJ0aWVzLAoJCQlvcmlnaW5hbE9wdGlvbnM6IG9wdGlvbnMsCgkJCXN0YXJ0VGltZTogZnhOb3cgfHwgY3JlYXRlRnhOb3coKSwKCQkJZHVyYXRpb246IG9wdGlvbnMuZHVyYXRpb24sCgkJCXR3ZWVuczogW10sCgkJCWNyZWF0ZVR3ZWVuOiBmdW5jdGlvbiggcHJvcCwgZW5kICkgewoJCQkJdmFyIHR3ZWVuID0galF1ZXJ5LlR3ZWVuKCBlbGVtLCBhbmltYXRpb24ub3B0cywgcHJvcCwgZW5kLAoJCQkJCQlhbmltYXRpb24ub3B0cy5zcGVjaWFsRWFzaW5nWyBwcm9wIF0gfHwgYW5pbWF0aW9uLm9wdHMuZWFzaW5nICk7CgkJCQlhbmltYXRpb24udHdlZW5zLnB1c2goIHR3ZWVuICk7CgkJCQlyZXR1cm4gdHdlZW47CgkJCX0sCgkJCXN0b3A6IGZ1bmN0aW9uKCBnb3RvRW5kICkgewoJCQkJdmFyIGluZGV4ID0gMCwKCgkJCQkJLy8gSWYgd2UgYXJlIGdvaW5nIHRvIHRoZSBlbmQsIHdlIHdhbnQgdG8gcnVuIGFsbCB0aGUgdHdlZW5zCgkJCQkJLy8gb3RoZXJ3aXNlIHdlIHNraXAgdGhpcyBwYXJ0CgkJCQkJbGVuZ3RoID0gZ290b0VuZCA/IGFuaW1hdGlvbi50d2VlbnMubGVuZ3RoIDogMDsKCQkJCWlmICggc3RvcHBlZCApIHsKCQkJCQlyZXR1cm4gdGhpczsKCQkJCX0KCQkJCXN0b3BwZWQgPSB0cnVlOwoJCQkJZm9yICggOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKyApIHsKCQkJCQlhbmltYXRpb24udHdlZW5zWyBpbmRleCBdLnJ1biggMSApOwoJCQkJfQoKCQkJCS8vIFJlc29sdmUgd2hlbiB3ZSBwbGF5ZWQgdGhlIGxhc3QgZnJhbWU7IG90aGVyd2lzZSwgcmVqZWN0CgkJCQlpZiAoIGdvdG9FbmQgKSB7CgkJCQkJZGVmZXJyZWQubm90aWZ5V2l0aCggZWxlbSwgWyBhbmltYXRpb24sIDEsIDAgXSApOwoJCQkJCWRlZmVycmVkLnJlc29sdmVXaXRoKCBlbGVtLCBbIGFuaW1hdGlvbiwgZ290b0VuZCBdICk7CgkJCQl9IGVsc2UgewoJCQkJCWRlZmVycmVkLnJlamVjdFdpdGgoIGVsZW0sIFsgYW5pbWF0aW9uLCBnb3RvRW5kIF0gKTsKCQkJCX0KCQkJCXJldHVybiB0aGlzOwoJCQl9CgkJfSApLAoJCXByb3BzID0gYW5pbWF0aW9uLnByb3BzOwoKCXByb3BGaWx0ZXIoIHByb3BzLCBhbmltYXRpb24ub3B0cy5zcGVjaWFsRWFzaW5nICk7CgoJZm9yICggOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKyApIHsKCQlyZXN1bHQgPSBBbmltYXRpb24ucHJlZmlsdGVyc1sgaW5kZXggXS5jYWxsKCBhbmltYXRpb24sIGVsZW0sIHByb3BzLCBhbmltYXRpb24ub3B0cyApOwoJCWlmICggcmVzdWx0ICkgewoJCQlpZiAoIGlzRnVuY3Rpb24oIHJlc3VsdC5zdG9wICkgKSB7CgkJCQlqUXVlcnkuX3F1ZXVlSG9va3MoIGFuaW1hdGlvbi5lbGVtLCBhbmltYXRpb24ub3B0cy5xdWV1ZSApLnN0b3AgPQoJCQkJCXJlc3VsdC5zdG9wLmJpbmQoIHJlc3VsdCApOwoJCQl9CgkJCXJldHVybiByZXN1bHQ7CgkJfQoJfQoKCWpRdWVyeS5tYXAoIHByb3BzLCBjcmVhdGVUd2VlbiwgYW5pbWF0aW9uICk7CgoJaWYgKCBpc0Z1bmN0aW9uKCBhbmltYXRpb24ub3B0cy5zdGFydCApICkgewoJCWFuaW1hdGlvbi5vcHRzLnN0YXJ0LmNhbGwoIGVsZW0sIGFuaW1hdGlvbiApOwoJfQoKCS8vIEF0dGFjaCBjYWxsYmFja3MgZnJvbSBvcHRpb25zCglhbmltYXRpb24KCQkucHJvZ3Jlc3MoIGFuaW1hdGlvbi5vcHRzLnByb2dyZXNzICkKCQkuZG9uZSggYW5pbWF0aW9uLm9wdHMuZG9uZSwgYW5pbWF0aW9uLm9wdHMuY29tcGxldGUgKQoJCS5mYWlsKCBhbmltYXRpb24ub3B0cy5mYWlsICkKCQkuYWx3YXlzKCBhbmltYXRpb24ub3B0cy5hbHdheXMgKTsKCglqUXVlcnkuZngudGltZXIoCgkJalF1ZXJ5LmV4dGVuZCggdGljaywgewoJCQllbGVtOiBlbGVtLAoJCQlhbmltOiBhbmltYXRpb24sCgkJCXF1ZXVlOiBhbmltYXRpb24ub3B0cy5xdWV1ZQoJCX0gKQoJKTsKCglyZXR1cm4gYW5pbWF0aW9uOwp9CgpqUXVlcnkuQW5pbWF0aW9uID0galF1ZXJ5LmV4dGVuZCggQW5pbWF0aW9uLCB7CgoJdHdlZW5lcnM6IHsKCQkiKiI6IFsgZnVuY3Rpb24oIHByb3AsIHZhbHVlICkgewoJCQl2YXIgdHdlZW4gPSB0aGlzLmNyZWF0ZVR3ZWVuKCBwcm9wLCB2YWx1ZSApOwoJCQlhZGp1c3RDU1MoIHR3ZWVuLmVsZW0sIHByb3AsIHJjc3NOdW0uZXhlYyggdmFsdWUgKSwgdHdlZW4gKTsKCQkJcmV0dXJuIHR3ZWVuOwoJCX0gXQoJfSwKCgl0d2VlbmVyOiBmdW5jdGlvbiggcHJvcHMsIGNhbGxiYWNrICkgewoJCWlmICggaXNGdW5jdGlvbiggcHJvcHMgKSApIHsKCQkJY2FsbGJhY2sgPSBwcm9wczsKCQkJcHJvcHMgPSBbICIqIiBdOwoJCX0gZWxzZSB7CgkJCXByb3BzID0gcHJvcHMubWF0Y2goIHJub3RodG1sd2hpdGUgKTsKCQl9CgoJCXZhciBwcm9wLAoJCQlpbmRleCA9IDAsCgkJCWxlbmd0aCA9IHByb3BzLmxlbmd0aDsKCgkJZm9yICggOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKyApIHsKCQkJcHJvcCA9IHByb3BzWyBpbmRleCBdOwoJCQlBbmltYXRpb24udHdlZW5lcnNbIHByb3AgXSA9IEFuaW1hdGlvbi50d2VlbmVyc1sgcHJvcCBdIHx8IFtdOwoJCQlBbmltYXRpb24udHdlZW5lcnNbIHByb3AgXS51bnNoaWZ0KCBjYWxsYmFjayApOwoJCX0KCX0sCgoJcHJlZmlsdGVyczogWyBkZWZhdWx0UHJlZmlsdGVyIF0sCgoJcHJlZmlsdGVyOiBmdW5jdGlvbiggY2FsbGJhY2ssIHByZXBlbmQgKSB7CgkJaWYgKCBwcmVwZW5kICkgewoJCQlBbmltYXRpb24ucHJlZmlsdGVycy51bnNoaWZ0KCBjYWxsYmFjayApOwoJCX0gZWxzZSB7CgkJCUFuaW1hdGlvbi5wcmVmaWx0ZXJzLnB1c2goIGNhbGxiYWNrICk7CgkJfQoJfQp9ICk7CgpqUXVlcnkuc3BlZWQgPSBmdW5jdGlvbiggc3BlZWQsIGVhc2luZywgZm4gKSB7Cgl2YXIgb3B0ID0gc3BlZWQgJiYgdHlwZW9mIHNwZWVkID09PSAib2JqZWN0IiA/IGpRdWVyeS5leHRlbmQoIHt9LCBzcGVlZCApIDogewoJCWNvbXBsZXRlOiBmbiB8fCAhZm4gJiYgZWFzaW5nIHx8CgkJCWlzRnVuY3Rpb24oIHNwZWVkICkgJiYgc3BlZWQsCgkJZHVyYXRpb246IHNwZWVkLAoJCWVhc2luZzogZm4gJiYgZWFzaW5nIHx8IGVhc2luZyAmJiAhaXNGdW5jdGlvbiggZWFzaW5nICkgJiYgZWFzaW5nCgl9OwoKCS8vIEdvIHRvIHRoZSBlbmQgc3RhdGUgaWYgZnggYXJlIG9mZgoJaWYgKCBqUXVlcnkuZngub2ZmICkgewoJCW9wdC5kdXJhdGlvbiA9IDA7CgoJfSBlbHNlIHsKCQlpZiAoIHR5cGVvZiBvcHQuZHVyYXRpb24gIT09ICJudW1iZXIiICkgewoJCQlpZiAoIG9wdC5kdXJhdGlvbiBpbiBqUXVlcnkuZnguc3BlZWRzICkgewoJCQkJb3B0LmR1cmF0aW9uID0galF1ZXJ5LmZ4LnNwZWVkc1sgb3B0LmR1cmF0aW9uIF07CgoJCQl9IGVsc2UgewoJCQkJb3B0LmR1cmF0aW9uID0galF1ZXJ5LmZ4LnNwZWVkcy5fZGVmYXVsdDsKCQkJfQoJCX0KCX0KCgkvLyBOb3JtYWxpemUgb3B0LnF1ZXVlIC0gdHJ1ZS91bmRlZmluZWQvbnVsbCAtPiAiZngiCglpZiAoIG9wdC5xdWV1ZSA9PSBudWxsIHx8IG9wdC5xdWV1ZSA9PT0gdHJ1ZSApIHsKCQlvcHQucXVldWUgPSAiZngiOwoJfQoKCS8vIFF1ZXVlaW5nCglvcHQub2xkID0gb3B0LmNvbXBsZXRlOwoKCW9wdC5jb21wbGV0ZSA9IGZ1bmN0aW9uKCkgewoJCWlmICggaXNGdW5jdGlvbiggb3B0Lm9sZCApICkgewoJCQlvcHQub2xkLmNhbGwoIHRoaXMgKTsKCQl9CgoJCWlmICggb3B0LnF1ZXVlICkgewoJCQlqUXVlcnkuZGVxdWV1ZSggdGhpcywgb3B0LnF1ZXVlICk7CgkJfQoJfTsKCglyZXR1cm4gb3B0Owp9OwoKalF1ZXJ5LmZuLmV4dGVuZCggewoJZmFkZVRvOiBmdW5jdGlvbiggc3BlZWQsIHRvLCBlYXNpbmcsIGNhbGxiYWNrICkgewoKCQkvLyBTaG93IGFueSBoaWRkZW4gZWxlbWVudHMgYWZ0ZXIgc2V0dGluZyBvcGFjaXR5IHRvIDAKCQlyZXR1cm4gdGhpcy5maWx0ZXIoIGlzSGlkZGVuV2l0aGluVHJlZSApLmNzcyggIm9wYWNpdHkiLCAwICkuc2hvdygpCgoJCQkvLyBBbmltYXRlIHRvIHRoZSB2YWx1ZSBzcGVjaWZpZWQKCQkJLmVuZCgpLmFuaW1hdGUoIHsgb3BhY2l0eTogdG8gfSwgc3BlZWQsIGVhc2luZywgY2FsbGJhY2sgKTsKCX0sCglhbmltYXRlOiBmdW5jdGlvbiggcHJvcCwgc3BlZWQsIGVhc2luZywgY2FsbGJhY2sgKSB7CgkJdmFyIGVtcHR5ID0galF1ZXJ5LmlzRW1wdHlPYmplY3QoIHByb3AgKSwKCQkJb3B0YWxsID0galF1ZXJ5LnNwZWVkKCBzcGVlZCwgZWFzaW5nLCBjYWxsYmFjayApLAoJCQlkb0FuaW1hdGlvbiA9IGZ1bmN0aW9uKCkgewoKCQkJCS8vIE9wZXJhdGUgb24gYSBjb3B5IG9mIHByb3Agc28gcGVyLXByb3BlcnR5IGVhc2luZyB3b24ndCBiZSBsb3N0CgkJCQl2YXIgYW5pbSA9IEFuaW1hdGlvbiggdGhpcywgalF1ZXJ5LmV4dGVuZCgge30sIHByb3AgKSwgb3B0YWxsICk7CgoJCQkJLy8gRW1wdHkgYW5pbWF0aW9ucywgb3IgZmluaXNoaW5nIHJlc29sdmVzIGltbWVkaWF0ZWx5CgkJCQlpZiAoIGVtcHR5IHx8IGRhdGFQcml2LmdldCggdGhpcywgImZpbmlzaCIgKSApIHsKCQkJCQlhbmltLnN0b3AoIHRydWUgKTsKCQkJCX0KCQkJfTsKCQkJZG9BbmltYXRpb24uZmluaXNoID0gZG9BbmltYXRpb247CgoJCXJldHVybiBlbXB0eSB8fCBvcHRhbGwucXVldWUgPT09IGZhbHNlID8KCQkJdGhpcy5lYWNoKCBkb0FuaW1hdGlvbiApIDoKCQkJdGhpcy5xdWV1ZSggb3B0YWxsLnF1ZXVlLCBkb0FuaW1hdGlvbiApOwoJfSwKCXN0b3A6IGZ1bmN0aW9uKCB0eXBlLCBjbGVhclF1ZXVlLCBnb3RvRW5kICkgewoJCXZhciBzdG9wUXVldWUgPSBmdW5jdGlvbiggaG9va3MgKSB7CgkJCXZhciBzdG9wID0gaG9va3Muc3RvcDsKCQkJZGVsZXRlIGhvb2tzLnN0b3A7CgkJCXN0b3AoIGdvdG9FbmQgKTsKCQl9OwoKCQlpZiAoIHR5cGVvZiB0eXBlICE9PSAic3RyaW5nIiApIHsKCQkJZ290b0VuZCA9IGNsZWFyUXVldWU7CgkJCWNsZWFyUXVldWUgPSB0eXBlOwoJCQl0eXBlID0gdW5kZWZpbmVkOwoJCX0KCQlpZiAoIGNsZWFyUXVldWUgJiYgdHlwZSAhPT0gZmFsc2UgKSB7CgkJCXRoaXMucXVldWUoIHR5cGUgfHwgImZ4IiwgW10gKTsKCQl9CgoJCXJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCkgewoJCQl2YXIgZGVxdWV1ZSA9IHRydWUsCgkJCQlpbmRleCA9IHR5cGUgIT0gbnVsbCAmJiB0eXBlICsgInF1ZXVlSG9va3MiLAoJCQkJdGltZXJzID0galF1ZXJ5LnRpbWVycywKCQkJCWRhdGEgPSBkYXRhUHJpdi5nZXQoIHRoaXMgKTsKCgkJCWlmICggaW5kZXggKSB7CgkJCQlpZiAoIGRhdGFbIGluZGV4IF0gJiYgZGF0YVsgaW5kZXggXS5zdG9wICkgewoJCQkJCXN0b3BRdWV1ZSggZGF0YVsgaW5kZXggXSApOwoJCQkJfQoJCQl9IGVsc2UgewoJCQkJZm9yICggaW5kZXggaW4gZGF0YSApIHsKCQkJCQlpZiAoIGRhdGFbIGluZGV4IF0gJiYgZGF0YVsgaW5kZXggXS5zdG9wICYmIHJydW4udGVzdCggaW5kZXggKSApIHsKCQkJCQkJc3RvcFF1ZXVlKCBkYXRhWyBpbmRleCBdICk7CgkJCQkJfQoJCQkJfQoJCQl9CgoJCQlmb3IgKCBpbmRleCA9IHRpbWVycy5sZW5ndGg7IGluZGV4LS07ICkgewoJCQkJaWYgKCB0aW1lcnNbIGluZGV4IF0uZWxlbSA9PT0gdGhpcyAmJgoJCQkJCSggdHlwZSA9PSBudWxsIHx8IHRpbWVyc1sgaW5kZXggXS5xdWV1ZSA9PT0gdHlwZSApICkgewoKCQkJCQl0aW1lcnNbIGluZGV4IF0uYW5pbS5zdG9wKCBnb3RvRW5kICk7CgkJCQkJZGVxdWV1ZSA9IGZhbHNlOwoJCQkJCXRpbWVycy5zcGxpY2UoIGluZGV4LCAxICk7CgkJCQl9CgkJCX0KCgkJCS8vIFN0YXJ0IHRoZSBuZXh0IGluIHRoZSBxdWV1ZSBpZiB0aGUgbGFzdCBzdGVwIHdhc24ndCBmb3JjZWQuCgkJCS8vIFRpbWVycyBjdXJyZW50bHkgd2lsbCBjYWxsIHRoZWlyIGNvbXBsZXRlIGNhbGxiYWNrcywgd2hpY2gKCQkJLy8gd2lsbCBkZXF1ZXVlIGJ1dCBvbmx5IGlmIHRoZXkgd2VyZSBnb3RvRW5kLgoJCQlpZiAoIGRlcXVldWUgfHwgIWdvdG9FbmQgKSB7CgkJCQlqUXVlcnkuZGVxdWV1ZSggdGhpcywgdHlwZSApOwoJCQl9CgkJfSApOwoJfSwKCWZpbmlzaDogZnVuY3Rpb24oIHR5cGUgKSB7CgkJaWYgKCB0eXBlICE9PSBmYWxzZSApIHsKCQkJdHlwZSA9IHR5cGUgfHwgImZ4IjsKCQl9CgkJcmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24oKSB7CgkJCXZhciBpbmRleCwKCQkJCWRhdGEgPSBkYXRhUHJpdi5nZXQoIHRoaXMgKSwKCQkJCXF1ZXVlID0gZGF0YVsgdHlwZSArICJxdWV1ZSIgXSwKCQkJCWhvb2tzID0gZGF0YVsgdHlwZSArICJxdWV1ZUhvb2tzIiBdLAoJCQkJdGltZXJzID0galF1ZXJ5LnRpbWVycywKCQkJCWxlbmd0aCA9IHF1ZXVlID8gcXVldWUubGVuZ3RoIDogMDsKCgkJCS8vIEVuYWJsZSBmaW5pc2hpbmcgZmxhZyBvbiBwcml2YXRlIGRhdGEKCQkJZGF0YS5maW5pc2ggPSB0cnVlOwoKCQkJLy8gRW1wdHkgdGhlIHF1ZXVlIGZpcnN0CgkJCWpRdWVyeS5xdWV1ZSggdGhpcywgdHlwZSwgW10gKTsKCgkJCWlmICggaG9va3MgJiYgaG9va3Muc3RvcCApIHsKCQkJCWhvb2tzLnN0b3AuY2FsbCggdGhpcywgdHJ1ZSApOwoJCQl9CgoJCQkvLyBMb29rIGZvciBhbnkgYWN0aXZlIGFuaW1hdGlvbnMsIGFuZCBmaW5pc2ggdGhlbQoJCQlmb3IgKCBpbmRleCA9IHRpbWVycy5sZW5ndGg7IGluZGV4LS07ICkgewoJCQkJaWYgKCB0aW1lcnNbIGluZGV4IF0uZWxlbSA9PT0gdGhpcyAmJiB0aW1lcnNbIGluZGV4IF0ucXVldWUgPT09IHR5cGUgKSB7CgkJCQkJdGltZXJzWyBpbmRleCBdLmFuaW0uc3RvcCggdHJ1ZSApOwoJCQkJCXRpbWVycy5zcGxpY2UoIGluZGV4LCAxICk7CgkJCQl9CgkJCX0KCgkJCS8vIExvb2sgZm9yIGFueSBhbmltYXRpb25zIGluIHRoZSBvbGQgcXVldWUgYW5kIGZpbmlzaCB0aGVtCgkJCWZvciAoIGluZGV4ID0gMDsgaW5kZXggPCBsZW5ndGg7IGluZGV4KysgKSB7CgkJCQlpZiAoIHF1ZXVlWyBpbmRleCBdICYmIHF1ZXVlWyBpbmRleCBdLmZpbmlzaCApIHsKCQkJCQlxdWV1ZVsgaW5kZXggXS5maW5pc2guY2FsbCggdGhpcyApOwoJCQkJfQoJCQl9CgoJCQkvLyBUdXJuIG9mZiBmaW5pc2hpbmcgZmxhZwoJCQlkZWxldGUgZGF0YS5maW5pc2g7CgkJfSApOwoJfQp9ICk7CgpqUXVlcnkuZWFjaCggWyAidG9nZ2xlIiwgInNob3ciLCAiaGlkZSIgXSwgZnVuY3Rpb24oIGksIG5hbWUgKSB7Cgl2YXIgY3NzRm4gPSBqUXVlcnkuZm5bIG5hbWUgXTsKCWpRdWVyeS5mblsgbmFtZSBdID0gZnVuY3Rpb24oIHNwZWVkLCBlYXNpbmcsIGNhbGxiYWNrICkgewoJCXJldHVybiBzcGVlZCA9PSBudWxsIHx8IHR5cGVvZiBzcGVlZCA9PT0gImJvb2xlYW4iID8KCQkJY3NzRm4uYXBwbHkoIHRoaXMsIGFyZ3VtZW50cyApIDoKCQkJdGhpcy5hbmltYXRlKCBnZW5GeCggbmFtZSwgdHJ1ZSApLCBzcGVlZCwgZWFzaW5nLCBjYWxsYmFjayApOwoJfTsKfSApOwoKLy8gR2VuZXJhdGUgc2hvcnRjdXRzIGZvciBjdXN0b20gYW5pbWF0aW9ucwpqUXVlcnkuZWFjaCggewoJc2xpZGVEb3duOiBnZW5GeCggInNob3ciICksCglzbGlkZVVwOiBnZW5GeCggImhpZGUiICksCglzbGlkZVRvZ2dsZTogZ2VuRngoICJ0b2dnbGUiICksCglmYWRlSW46IHsgb3BhY2l0eTogInNob3ciIH0sCglmYWRlT3V0OiB7IG9wYWNpdHk6ICJoaWRlIiB9LAoJZmFkZVRvZ2dsZTogeyBvcGFjaXR5OiAidG9nZ2xlIiB9Cn0sIGZ1bmN0aW9uKCBuYW1lLCBwcm9wcyApIHsKCWpRdWVyeS5mblsgbmFtZSBdID0gZnVuY3Rpb24oIHNwZWVkLCBlYXNpbmcsIGNhbGxiYWNrICkgewoJCXJldHVybiB0aGlzLmFuaW1hdGUoIHByb3BzLCBzcGVlZCwgZWFzaW5nLCBjYWxsYmFjayApOwoJfTsKfSApOwoKalF1ZXJ5LnRpbWVycyA9IFtdOwpqUXVlcnkuZngudGljayA9IGZ1bmN0aW9uKCkgewoJdmFyIHRpbWVyLAoJCWkgPSAwLAoJCXRpbWVycyA9IGpRdWVyeS50aW1lcnM7CgoJZnhOb3cgPSBEYXRlLm5vdygpOwoKCWZvciAoIDsgaSA8IHRpbWVycy5sZW5ndGg7IGkrKyApIHsKCQl0aW1lciA9IHRpbWVyc1sgaSBdOwoKCQkvLyBSdW4gdGhlIHRpbWVyIGFuZCBzYWZlbHkgcmVtb3ZlIGl0IHdoZW4gZG9uZSAoYWxsb3dpbmcgZm9yIGV4dGVybmFsIHJlbW92YWwpCgkJaWYgKCAhdGltZXIoKSAmJiB0aW1lcnNbIGkgXSA9PT0gdGltZXIgKSB7CgkJCXRpbWVycy5zcGxpY2UoIGktLSwgMSApOwoJCX0KCX0KCglpZiAoICF0aW1lcnMubGVuZ3RoICkgewoJCWpRdWVyeS5meC5zdG9wKCk7Cgl9CglmeE5vdyA9IHVuZGVmaW5lZDsKfTsKCmpRdWVyeS5meC50aW1lciA9IGZ1bmN0aW9uKCB0aW1lciApIHsKCWpRdWVyeS50aW1lcnMucHVzaCggdGltZXIgKTsKCWpRdWVyeS5meC5zdGFydCgpOwp9OwoKalF1ZXJ5LmZ4LmludGVydmFsID0gMTM7CmpRdWVyeS5meC5zdGFydCA9IGZ1bmN0aW9uKCkgewoJaWYgKCBpblByb2dyZXNzICkgewoJCXJldHVybjsKCX0KCglpblByb2dyZXNzID0gdHJ1ZTsKCXNjaGVkdWxlKCk7Cn07CgpqUXVlcnkuZnguc3RvcCA9IGZ1bmN0aW9uKCkgewoJaW5Qcm9ncmVzcyA9IG51bGw7Cn07CgpqUXVlcnkuZnguc3BlZWRzID0gewoJc2xvdzogNjAwLAoJZmFzdDogMjAwLAoKCS8vIERlZmF1bHQgc3BlZWQKCV9kZWZhdWx0OiA0MDAKfTsKCgovLyBCYXNlZCBvZmYgb2YgdGhlIHBsdWdpbiBieSBDbGludCBIZWxmZXJzLCB3aXRoIHBlcm1pc3Npb24uCi8vIGh0dHBzOi8vd2ViLmFyY2hpdmUub3JnL3dlYi8yMDEwMDMyNDAxNDc0Ny9odHRwOi8vYmxpbmRzaWduYWxzLmNvbS9pbmRleC5waHAvMjAwOS8wNy9qcXVlcnktZGVsYXkvCmpRdWVyeS5mbi5kZWxheSA9IGZ1bmN0aW9uKCB0aW1lLCB0eXBlICkgewoJdGltZSA9IGpRdWVyeS5meCA/IGpRdWVyeS5meC5zcGVlZHNbIHRpbWUgXSB8fCB0aW1lIDogdGltZTsKCXR5cGUgPSB0eXBlIHx8ICJmeCI7CgoJcmV0dXJuIHRoaXMucXVldWUoIHR5cGUsIGZ1bmN0aW9uKCBuZXh0LCBob29rcyApIHsKCQl2YXIgdGltZW91dCA9IHdpbmRvdy5zZXRUaW1lb3V0KCBuZXh0LCB0aW1lICk7CgkJaG9va3Muc3RvcCA9IGZ1bmN0aW9uKCkgewoJCQl3aW5kb3cuY2xlYXJUaW1lb3V0KCB0aW1lb3V0ICk7CgkJfTsKCX0gKTsKfTsKCgooIGZ1bmN0aW9uKCkgewoJdmFyIGlucHV0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggImlucHV0IiApLAoJCXNlbGVjdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoICJzZWxlY3QiICksCgkJb3B0ID0gc2VsZWN0LmFwcGVuZENoaWxkKCBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCAib3B0aW9uIiApICk7CgoJaW5wdXQudHlwZSA9ICJjaGVja2JveCI7CgoJLy8gU3VwcG9ydDogQW5kcm9pZCA8PTQuMyBvbmx5CgkvLyBEZWZhdWx0IHZhbHVlIGZvciBhIGNoZWNrYm94IHNob3VsZCBiZSAib24iCglzdXBwb3J0LmNoZWNrT24gPSBpbnB1dC52YWx1ZSAhPT0gIiI7CgoJLy8gU3VwcG9ydDogSUUgPD0xMSBvbmx5CgkvLyBNdXN0IGFjY2VzcyBzZWxlY3RlZEluZGV4IHRvIG1ha2UgZGVmYXVsdCBvcHRpb25zIHNlbGVjdAoJc3VwcG9ydC5vcHRTZWxlY3RlZCA9IG9wdC5zZWxlY3RlZDsKCgkvLyBTdXBwb3J0OiBJRSA8PTExIG9ubHkKCS8vIEFuIGlucHV0IGxvc2VzIGl0cyB2YWx1ZSBhZnRlciBiZWNvbWluZyBhIHJhZGlvCglpbnB1dCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoICJpbnB1dCIgKTsKCWlucHV0LnZhbHVlID0gInQiOwoJaW5wdXQudHlwZSA9ICJyYWRpbyI7CglzdXBwb3J0LnJhZGlvVmFsdWUgPSBpbnB1dC52YWx1ZSA9PT0gInQiOwp9ICkoKTsKCgp2YXIgYm9vbEhvb2ssCglhdHRySGFuZGxlID0galF1ZXJ5LmV4cHIuYXR0ckhhbmRsZTsKCmpRdWVyeS5mbi5leHRlbmQoIHsKCWF0dHI6IGZ1bmN0aW9uKCBuYW1lLCB2YWx1ZSApIHsKCQlyZXR1cm4gYWNjZXNzKCB0aGlzLCBqUXVlcnkuYXR0ciwgbmFtZSwgdmFsdWUsIGFyZ3VtZW50cy5sZW5ndGggPiAxICk7Cgl9LAoKCXJlbW92ZUF0dHI6IGZ1bmN0aW9uKCBuYW1lICkgewoJCXJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCkgewoJCQlqUXVlcnkucmVtb3ZlQXR0ciggdGhpcywgbmFtZSApOwoJCX0gKTsKCX0KfSApOwoKalF1ZXJ5LmV4dGVuZCggewoJYXR0cjogZnVuY3Rpb24oIGVsZW0sIG5hbWUsIHZhbHVlICkgewoJCXZhciByZXQsIGhvb2tzLAoJCQluVHlwZSA9IGVsZW0ubm9kZVR5cGU7CgoJCS8vIERvbid0IGdldC9zZXQgYXR0cmlidXRlcyBvbiB0ZXh0LCBjb21tZW50IGFuZCBhdHRyaWJ1dGUgbm9kZXMKCQlpZiAoIG5UeXBlID09PSAzIHx8IG5UeXBlID09PSA4IHx8IG5UeXBlID09PSAyICkgewoJCQlyZXR1cm47CgkJfQoKCQkvLyBGYWxsYmFjayB0byBwcm9wIHdoZW4gYXR0cmlidXRlcyBhcmUgbm90IHN1cHBvcnRlZAoJCWlmICggdHlwZW9mIGVsZW0uZ2V0QXR0cmlidXRlID09PSAidW5kZWZpbmVkIiApIHsKCQkJcmV0dXJuIGpRdWVyeS5wcm9wKCBlbGVtLCBuYW1lLCB2YWx1ZSApOwoJCX0KCgkJLy8gQXR0cmlidXRlIGhvb2tzIGFyZSBkZXRlcm1pbmVkIGJ5IHRoZSBsb3dlcmNhc2UgdmVyc2lvbgoJCS8vIEdyYWIgbmVjZXNzYXJ5IGhvb2sgaWYgb25lIGlzIGRlZmluZWQKCQlpZiAoIG5UeXBlICE9PSAxIHx8ICFqUXVlcnkuaXNYTUxEb2MoIGVsZW0gKSApIHsKCQkJaG9va3MgPSBqUXVlcnkuYXR0ckhvb2tzWyBuYW1lLnRvTG93ZXJDYXNlKCkgXSB8fAoJCQkJKCBqUXVlcnkuZXhwci5tYXRjaC5ib29sLnRlc3QoIG5hbWUgKSA/IGJvb2xIb29rIDogdW5kZWZpbmVkICk7CgkJfQoKCQlpZiAoIHZhbHVlICE9PSB1bmRlZmluZWQgKSB7CgkJCWlmICggdmFsdWUgPT09IG51bGwgKSB7CgkJCQlqUXVlcnkucmVtb3ZlQXR0ciggZWxlbSwgbmFtZSApOwoJCQkJcmV0dXJuOwoJCQl9CgoJCQlpZiAoIGhvb2tzICYmICJzZXQiIGluIGhvb2tzICYmCgkJCQkoIHJldCA9IGhvb2tzLnNldCggZWxlbSwgdmFsdWUsIG5hbWUgKSApICE9PSB1bmRlZmluZWQgKSB7CgkJCQlyZXR1cm4gcmV0OwoJCQl9CgoJCQllbGVtLnNldEF0dHJpYnV0ZSggbmFtZSwgdmFsdWUgKyAiIiApOwoJCQlyZXR1cm4gdmFsdWU7CgkJfQoKCQlpZiAoIGhvb2tzICYmICJnZXQiIGluIGhvb2tzICYmICggcmV0ID0gaG9va3MuZ2V0KCBlbGVtLCBuYW1lICkgKSAhPT0gbnVsbCApIHsKCQkJcmV0dXJuIHJldDsKCQl9CgoJCXJldCA9IGpRdWVyeS5maW5kLmF0dHIoIGVsZW0sIG5hbWUgKTsKCgkJLy8gTm9uLWV4aXN0ZW50IGF0dHJpYnV0ZXMgcmV0dXJuIG51bGwsIHdlIG5vcm1hbGl6ZSB0byB1bmRlZmluZWQKCQlyZXR1cm4gcmV0ID09IG51bGwgPyB1bmRlZmluZWQgOiByZXQ7Cgl9LAoKCWF0dHJIb29rczogewoJCXR5cGU6IHsKCQkJc2V0OiBmdW5jdGlvbiggZWxlbSwgdmFsdWUgKSB7CgkJCQlpZiAoICFzdXBwb3J0LnJhZGlvVmFsdWUgJiYgdmFsdWUgPT09ICJyYWRpbyIgJiYKCQkJCQlub2RlTmFtZSggZWxlbSwgImlucHV0IiApICkgewoJCQkJCXZhciB2YWwgPSBlbGVtLnZhbHVlOwoJCQkJCWVsZW0uc2V0QXR0cmlidXRlKCAidHlwZSIsIHZhbHVlICk7CgkJCQkJaWYgKCB2YWwgKSB7CgkJCQkJCWVsZW0udmFsdWUgPSB2YWw7CgkJCQkJfQoJCQkJCXJldHVybiB2YWx1ZTsKCQkJCX0KCQkJfQoJCX0KCX0sCgoJcmVtb3ZlQXR0cjogZnVuY3Rpb24oIGVsZW0sIHZhbHVlICkgewoJCXZhciBuYW1lLAoJCQlpID0gMCwKCgkJCS8vIEF0dHJpYnV0ZSBuYW1lcyBjYW4gY29udGFpbiBub24tSFRNTCB3aGl0ZXNwYWNlIGNoYXJhY3RlcnMKCQkJLy8gaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2Uvc3ludGF4Lmh0bWwjYXR0cmlidXRlcy0yCgkJCWF0dHJOYW1lcyA9IHZhbHVlICYmIHZhbHVlLm1hdGNoKCBybm90aHRtbHdoaXRlICk7CgoJCWlmICggYXR0ck5hbWVzICYmIGVsZW0ubm9kZVR5cGUgPT09IDEgKSB7CgkJCXdoaWxlICggKCBuYW1lID0gYXR0ck5hbWVzWyBpKysgXSApICkgewoJCQkJZWxlbS5yZW1vdmVBdHRyaWJ1dGUoIG5hbWUgKTsKCQkJfQoJCX0KCX0KfSApOwoKLy8gSG9va3MgZm9yIGJvb2xlYW4gYXR0cmlidXRlcwpib29sSG9vayA9IHsKCXNldDogZnVuY3Rpb24oIGVsZW0sIHZhbHVlLCBuYW1lICkgewoJCWlmICggdmFsdWUgPT09IGZhbHNlICkgewoKCQkJLy8gUmVtb3ZlIGJvb2xlYW4gYXR0cmlidXRlcyB3aGVuIHNldCB0byBmYWxzZQoJCQlqUXVlcnkucmVtb3ZlQXR0ciggZWxlbSwgbmFtZSApOwoJCX0gZWxzZSB7CgkJCWVsZW0uc2V0QXR0cmlidXRlKCBuYW1lLCBuYW1lICk7CgkJfQoJCXJldHVybiBuYW1lOwoJfQp9OwoKalF1ZXJ5LmVhY2goIGpRdWVyeS5leHByLm1hdGNoLmJvb2wuc291cmNlLm1hdGNoKCAvXHcrL2cgKSwgZnVuY3Rpb24oIGksIG5hbWUgKSB7Cgl2YXIgZ2V0dGVyID0gYXR0ckhhbmRsZVsgbmFtZSBdIHx8IGpRdWVyeS5maW5kLmF0dHI7CgoJYXR0ckhhbmRsZVsgbmFtZSBdID0gZnVuY3Rpb24oIGVsZW0sIG5hbWUsIGlzWE1MICkgewoJCXZhciByZXQsIGhhbmRsZSwKCQkJbG93ZXJjYXNlTmFtZSA9IG5hbWUudG9Mb3dlckNhc2UoKTsKCgkJaWYgKCAhaXNYTUwgKSB7CgoJCQkvLyBBdm9pZCBhbiBpbmZpbml0ZSBsb29wIGJ5IHRlbXBvcmFyaWx5IHJlbW92aW5nIHRoaXMgZnVuY3Rpb24gZnJvbSB0aGUgZ2V0dGVyCgkJCWhhbmRsZSA9IGF0dHJIYW5kbGVbIGxvd2VyY2FzZU5hbWUgXTsKCQkJYXR0ckhhbmRsZVsgbG93ZXJjYXNlTmFtZSBdID0gcmV0OwoJCQlyZXQgPSBnZXR0ZXIoIGVsZW0sIG5hbWUsIGlzWE1MICkgIT0gbnVsbCA/CgkJCQlsb3dlcmNhc2VOYW1lIDoKCQkJCW51bGw7CgkJCWF0dHJIYW5kbGVbIGxvd2VyY2FzZU5hbWUgXSA9IGhhbmRsZTsKCQl9CgkJcmV0dXJuIHJldDsKCX07Cn0gKTsKCgoKCnZhciByZm9jdXNhYmxlID0gL14oPzppbnB1dHxzZWxlY3R8dGV4dGFyZWF8YnV0dG9uKSQvaSwKCXJjbGlja2FibGUgPSAvXig/OmF8YXJlYSkkL2k7CgpqUXVlcnkuZm4uZXh0ZW5kKCB7Cglwcm9wOiBmdW5jdGlvbiggbmFtZSwgdmFsdWUgKSB7CgkJcmV0dXJuIGFjY2VzcyggdGhpcywgalF1ZXJ5LnByb3AsIG5hbWUsIHZhbHVlLCBhcmd1bWVudHMubGVuZ3RoID4gMSApOwoJfSwKCglyZW1vdmVQcm9wOiBmdW5jdGlvbiggbmFtZSApIHsKCQlyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbigpIHsKCQkJZGVsZXRlIHRoaXNbIGpRdWVyeS5wcm9wRml4WyBuYW1lIF0gfHwgbmFtZSBdOwoJCX0gKTsKCX0KfSApOwoKalF1ZXJ5LmV4dGVuZCggewoJcHJvcDogZnVuY3Rpb24oIGVsZW0sIG5hbWUsIHZhbHVlICkgewoJCXZhciByZXQsIGhvb2tzLAoJCQluVHlwZSA9IGVsZW0ubm9kZVR5cGU7CgoJCS8vIERvbid0IGdldC9zZXQgcHJvcGVydGllcyBvbiB0ZXh0LCBjb21tZW50IGFuZCBhdHRyaWJ1dGUgbm9kZXMKCQlpZiAoIG5UeXBlID09PSAzIHx8IG5UeXBlID09PSA4IHx8IG5UeXBlID09PSAyICkgewoJCQlyZXR1cm47CgkJfQoKCQlpZiAoIG5UeXBlICE9PSAxIHx8ICFqUXVlcnkuaXNYTUxEb2MoIGVsZW0gKSApIHsKCgkJCS8vIEZpeCBuYW1lIGFuZCBhdHRhY2ggaG9va3MKCQkJbmFtZSA9IGpRdWVyeS5wcm9wRml4WyBuYW1lIF0gfHwgbmFtZTsKCQkJaG9va3MgPSBqUXVlcnkucHJvcEhvb2tzWyBuYW1lIF07CgkJfQoKCQlpZiAoIHZhbHVlICE9PSB1bmRlZmluZWQgKSB7CgkJCWlmICggaG9va3MgJiYgInNldCIgaW4gaG9va3MgJiYKCQkJCSggcmV0ID0gaG9va3Muc2V0KCBlbGVtLCB2YWx1ZSwgbmFtZSApICkgIT09IHVuZGVmaW5lZCApIHsKCQkJCXJldHVybiByZXQ7CgkJCX0KCgkJCXJldHVybiAoIGVsZW1bIG5hbWUgXSA9IHZhbHVlICk7CgkJfQoKCQlpZiAoIGhvb2tzICYmICJnZXQiIGluIGhvb2tzICYmICggcmV0ID0gaG9va3MuZ2V0KCBlbGVtLCBuYW1lICkgKSAhPT0gbnVsbCApIHsKCQkJcmV0dXJuIHJldDsKCQl9CgoJCXJldHVybiBlbGVtWyBuYW1lIF07Cgl9LAoKCXByb3BIb29rczogewoJCXRhYkluZGV4OiB7CgkJCWdldDogZnVuY3Rpb24oIGVsZW0gKSB7CgoJCQkJLy8gU3VwcG9ydDogSUUgPD05IC0gMTEgb25seQoJCQkJLy8gZWxlbS50YWJJbmRleCBkb2Vzbid0IGFsd2F5cyByZXR1cm4gdGhlCgkJCQkvLyBjb3JyZWN0IHZhbHVlIHdoZW4gaXQgaGFzbid0IGJlZW4gZXhwbGljaXRseSBzZXQKCQkJCS8vIGh0dHBzOi8vd2ViLmFyY2hpdmUub3JnL3dlYi8yMDE0MTExNjIzMzM0Ny9odHRwOi8vZmx1aWRwcm9qZWN0Lm9yZy9ibG9nLzIwMDgvMDEvMDkvZ2V0dGluZy1zZXR0aW5nLWFuZC1yZW1vdmluZy10YWJpbmRleC12YWx1ZXMtd2l0aC1qYXZhc2NyaXB0LwoJCQkJLy8gVXNlIHByb3BlciBhdHRyaWJ1dGUgcmV0cmlldmFsKCMxMjA3MikKCQkJCXZhciB0YWJpbmRleCA9IGpRdWVyeS5maW5kLmF0dHIoIGVsZW0sICJ0YWJpbmRleCIgKTsKCgkJCQlpZiAoIHRhYmluZGV4ICkgewoJCQkJCXJldHVybiBwYXJzZUludCggdGFiaW5kZXgsIDEwICk7CgkJCQl9CgoJCQkJaWYgKAoJCQkJCXJmb2N1c2FibGUudGVzdCggZWxlbS5ub2RlTmFtZSApIHx8CgkJCQkJcmNsaWNrYWJsZS50ZXN0KCBlbGVtLm5vZGVOYW1lICkgJiYKCQkJCQllbGVtLmhyZWYKCQkJCSkgewoJCQkJCXJldHVybiAwOwoJCQkJfQoKCQkJCXJldHVybiAtMTsKCQkJfQoJCX0KCX0sCgoJcHJvcEZpeDogewoJCSJmb3IiOiAiaHRtbEZvciIsCgkJImNsYXNzIjogImNsYXNzTmFtZSIKCX0KfSApOwoKLy8gU3VwcG9ydDogSUUgPD0xMSBvbmx5Ci8vIEFjY2Vzc2luZyB0aGUgc2VsZWN0ZWRJbmRleCBwcm9wZXJ0eQovLyBmb3JjZXMgdGhlIGJyb3dzZXIgdG8gcmVzcGVjdCBzZXR0aW5nIHNlbGVjdGVkCi8vIG9uIHRoZSBvcHRpb24KLy8gVGhlIGdldHRlciBlbnN1cmVzIGEgZGVmYXVsdCBvcHRpb24gaXMgc2VsZWN0ZWQKLy8gd2hlbiBpbiBhbiBvcHRncm91cAovLyBlc2xpbnQgcnVsZSAibm8tdW51c2VkLWV4cHJlc3Npb25zIiBpcyBkaXNhYmxlZCBmb3IgdGhpcyBjb2RlCi8vIHNpbmNlIGl0IGNvbnNpZGVycyBzdWNoIGFjY2Vzc2lvbnMgbm9vcAppZiAoICFzdXBwb3J0Lm9wdFNlbGVjdGVkICkgewoJalF1ZXJ5LnByb3BIb29rcy5zZWxlY3RlZCA9IHsKCQlnZXQ6IGZ1bmN0aW9uKCBlbGVtICkgewoKCQkJLyogZXNsaW50IG5vLXVudXNlZC1leHByZXNzaW9uczogIm9mZiIgKi8KCgkJCXZhciBwYXJlbnQgPSBlbGVtLnBhcmVudE5vZGU7CgkJCWlmICggcGFyZW50ICYmIHBhcmVudC5wYXJlbnROb2RlICkgewoJCQkJcGFyZW50LnBhcmVudE5vZGUuc2VsZWN0ZWRJbmRleDsKCQkJfQoJCQlyZXR1cm4gbnVsbDsKCQl9LAoJCXNldDogZnVuY3Rpb24oIGVsZW0gKSB7CgoJCQkvKiBlc2xpbnQgbm8tdW51c2VkLWV4cHJlc3Npb25zOiAib2ZmIiAqLwoKCQkJdmFyIHBhcmVudCA9IGVsZW0ucGFyZW50Tm9kZTsKCQkJaWYgKCBwYXJlbnQgKSB7CgkJCQlwYXJlbnQuc2VsZWN0ZWRJbmRleDsKCgkJCQlpZiAoIHBhcmVudC5wYXJlbnROb2RlICkgewoJCQkJCXBhcmVudC5wYXJlbnROb2RlLnNlbGVjdGVkSW5kZXg7CgkJCQl9CgkJCX0KCQl9Cgl9Owp9CgpqUXVlcnkuZWFjaCggWwoJInRhYkluZGV4IiwKCSJyZWFkT25seSIsCgkibWF4TGVuZ3RoIiwKCSJjZWxsU3BhY2luZyIsCgkiY2VsbFBhZGRpbmciLAoJInJvd1NwYW4iLAoJImNvbFNwYW4iLAoJInVzZU1hcCIsCgkiZnJhbWVCb3JkZXIiLAoJImNvbnRlbnRFZGl0YWJsZSIKXSwgZnVuY3Rpb24oKSB7CglqUXVlcnkucHJvcEZpeFsgdGhpcy50b0xvd2VyQ2FzZSgpIF0gPSB0aGlzOwp9ICk7CgoKCgoJLy8gU3RyaXAgYW5kIGNvbGxhcHNlIHdoaXRlc3BhY2UgYWNjb3JkaW5nIHRvIEhUTUwgc3BlYwoJLy8gaHR0cHM6Ly9pbmZyYS5zcGVjLndoYXR3Zy5vcmcvI3N0cmlwLWFuZC1jb2xsYXBzZS1hc2NpaS13aGl0ZXNwYWNlCglmdW5jdGlvbiBzdHJpcEFuZENvbGxhcHNlKCB2YWx1ZSApIHsKCQl2YXIgdG9rZW5zID0gdmFsdWUubWF0Y2goIHJub3RodG1sd2hpdGUgKSB8fCBbXTsKCQlyZXR1cm4gdG9rZW5zLmpvaW4oICIgIiApOwoJfQoKCmZ1bmN0aW9uIGdldENsYXNzKCBlbGVtICkgewoJcmV0dXJuIGVsZW0uZ2V0QXR0cmlidXRlICYmIGVsZW0uZ2V0QXR0cmlidXRlKCAiY2xhc3MiICkgfHwgIiI7Cn0KCmZ1bmN0aW9uIGNsYXNzZXNUb0FycmF5KCB2YWx1ZSApIHsKCWlmICggQXJyYXkuaXNBcnJheSggdmFsdWUgKSApIHsKCQlyZXR1cm4gdmFsdWU7Cgl9CglpZiAoIHR5cGVvZiB2YWx1ZSA9PT0gInN0cmluZyIgKSB7CgkJcmV0dXJuIHZhbHVlLm1hdGNoKCBybm90aHRtbHdoaXRlICkgfHwgW107Cgl9CglyZXR1cm4gW107Cn0KCmpRdWVyeS5mbi5leHRlbmQoIHsKCWFkZENsYXNzOiBmdW5jdGlvbiggdmFsdWUgKSB7CgkJdmFyIGNsYXNzZXMsIGVsZW0sIGN1ciwgY3VyVmFsdWUsIGNsYXp6LCBqLCBmaW5hbFZhbHVlLAoJCQlpID0gMDsKCgkJaWYgKCBpc0Z1bmN0aW9uKCB2YWx1ZSApICkgewoJCQlyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbiggaiApIHsKCQkJCWpRdWVyeSggdGhpcyApLmFkZENsYXNzKCB2YWx1ZS5jYWxsKCB0aGlzLCBqLCBnZXRDbGFzcyggdGhpcyApICkgKTsKCQkJfSApOwoJCX0KCgkJY2xhc3NlcyA9IGNsYXNzZXNUb0FycmF5KCB2YWx1ZSApOwoKCQlpZiAoIGNsYXNzZXMubGVuZ3RoICkgewoJCQl3aGlsZSAoICggZWxlbSA9IHRoaXNbIGkrKyBdICkgKSB7CgkJCQljdXJWYWx1ZSA9IGdldENsYXNzKCBlbGVtICk7CgkJCQljdXIgPSBlbGVtLm5vZGVUeXBlID09PSAxICYmICggIiAiICsgc3RyaXBBbmRDb2xsYXBzZSggY3VyVmFsdWUgKSArICIgIiApOwoKCQkJCWlmICggY3VyICkgewoJCQkJCWogPSAwOwoJCQkJCXdoaWxlICggKCBjbGF6eiA9IGNsYXNzZXNbIGorKyBdICkgKSB7CgkJCQkJCWlmICggY3VyLmluZGV4T2YoICIgIiArIGNsYXp6ICsgIiAiICkgPCAwICkgewoJCQkJCQkJY3VyICs9IGNsYXp6ICsgIiAiOwoJCQkJCQl9CgkJCQkJfQoKCQkJCQkvLyBPbmx5IGFzc2lnbiBpZiBkaWZmZXJlbnQgdG8gYXZvaWQgdW5uZWVkZWQgcmVuZGVyaW5nLgoJCQkJCWZpbmFsVmFsdWUgPSBzdHJpcEFuZENvbGxhcHNlKCBjdXIgKTsKCQkJCQlpZiAoIGN1clZhbHVlICE9PSBmaW5hbFZhbHVlICkgewoJCQkJCQllbGVtLnNldEF0dHJpYnV0ZSggImNsYXNzIiwgZmluYWxWYWx1ZSApOwoJCQkJCX0KCQkJCX0KCQkJfQoJCX0KCgkJcmV0dXJuIHRoaXM7Cgl9LAoKCXJlbW92ZUNsYXNzOiBmdW5jdGlvbiggdmFsdWUgKSB7CgkJdmFyIGNsYXNzZXMsIGVsZW0sIGN1ciwgY3VyVmFsdWUsIGNsYXp6LCBqLCBmaW5hbFZhbHVlLAoJCQlpID0gMDsKCgkJaWYgKCBpc0Z1bmN0aW9uKCB2YWx1ZSApICkgewoJCQlyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbiggaiApIHsKCQkJCWpRdWVyeSggdGhpcyApLnJlbW92ZUNsYXNzKCB2YWx1ZS5jYWxsKCB0aGlzLCBqLCBnZXRDbGFzcyggdGhpcyApICkgKTsKCQkJfSApOwoJCX0KCgkJaWYgKCAhYXJndW1lbnRzLmxlbmd0aCApIHsKCQkJcmV0dXJuIHRoaXMuYXR0ciggImNsYXNzIiwgIiIgKTsKCQl9CgoJCWNsYXNzZXMgPSBjbGFzc2VzVG9BcnJheSggdmFsdWUgKTsKCgkJaWYgKCBjbGFzc2VzLmxlbmd0aCApIHsKCQkJd2hpbGUgKCAoIGVsZW0gPSB0aGlzWyBpKysgXSApICkgewoJCQkJY3VyVmFsdWUgPSBnZXRDbGFzcyggZWxlbSApOwoKCQkJCS8vIFRoaXMgZXhwcmVzc2lvbiBpcyBoZXJlIGZvciBiZXR0ZXIgY29tcHJlc3NpYmlsaXR5IChzZWUgYWRkQ2xhc3MpCgkJCQljdXIgPSBlbGVtLm5vZGVUeXBlID09PSAxICYmICggIiAiICsgc3RyaXBBbmRDb2xsYXBzZSggY3VyVmFsdWUgKSArICIgIiApOwoKCQkJCWlmICggY3VyICkgewoJCQkJCWogPSAwOwoJCQkJCXdoaWxlICggKCBjbGF6eiA9IGNsYXNzZXNbIGorKyBdICkgKSB7CgoJCQkJCQkvLyBSZW1vdmUgKmFsbCogaW5zdGFuY2VzCgkJCQkJCXdoaWxlICggY3VyLmluZGV4T2YoICIgIiArIGNsYXp6ICsgIiAiICkgPiAtMSApIHsKCQkJCQkJCWN1ciA9IGN1ci5yZXBsYWNlKCAiICIgKyBjbGF6eiArICIgIiwgIiAiICk7CgkJCQkJCX0KCQkJCQl9CgoJCQkJCS8vIE9ubHkgYXNzaWduIGlmIGRpZmZlcmVudCB0byBhdm9pZCB1bm5lZWRlZCByZW5kZXJpbmcuCgkJCQkJZmluYWxWYWx1ZSA9IHN0cmlwQW5kQ29sbGFwc2UoIGN1ciApOwoJCQkJCWlmICggY3VyVmFsdWUgIT09IGZpbmFsVmFsdWUgKSB7CgkJCQkJCWVsZW0uc2V0QXR0cmlidXRlKCAiY2xhc3MiLCBmaW5hbFZhbHVlICk7CgkJCQkJfQoJCQkJfQoJCQl9CgkJfQoKCQlyZXR1cm4gdGhpczsKCX0sCgoJdG9nZ2xlQ2xhc3M6IGZ1bmN0aW9uKCB2YWx1ZSwgc3RhdGVWYWwgKSB7CgkJdmFyIHR5cGUgPSB0eXBlb2YgdmFsdWUsCgkJCWlzVmFsaWRWYWx1ZSA9IHR5cGUgPT09ICJzdHJpbmciIHx8IEFycmF5LmlzQXJyYXkoIHZhbHVlICk7CgoJCWlmICggdHlwZW9mIHN0YXRlVmFsID09PSAiYm9vbGVhbiIgJiYgaXNWYWxpZFZhbHVlICkgewoJCQlyZXR1cm4gc3RhdGVWYWwgPyB0aGlzLmFkZENsYXNzKCB2YWx1ZSApIDogdGhpcy5yZW1vdmVDbGFzcyggdmFsdWUgKTsKCQl9CgoJCWlmICggaXNGdW5jdGlvbiggdmFsdWUgKSApIHsKCQkJcmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24oIGkgKSB7CgkJCQlqUXVlcnkoIHRoaXMgKS50b2dnbGVDbGFzcygKCQkJCQl2YWx1ZS5jYWxsKCB0aGlzLCBpLCBnZXRDbGFzcyggdGhpcyApLCBzdGF0ZVZhbCApLAoJCQkJCXN0YXRlVmFsCgkJCQkpOwoJCQl9ICk7CgkJfQoKCQlyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbigpIHsKCQkJdmFyIGNsYXNzTmFtZSwgaSwgc2VsZiwgY2xhc3NOYW1lczsKCgkJCWlmICggaXNWYWxpZFZhbHVlICkgewoKCQkJCS8vIFRvZ2dsZSBpbmRpdmlkdWFsIGNsYXNzIG5hbWVzCgkJCQlpID0gMDsKCQkJCXNlbGYgPSBqUXVlcnkoIHRoaXMgKTsKCQkJCWNsYXNzTmFtZXMgPSBjbGFzc2VzVG9BcnJheSggdmFsdWUgKTsKCgkJCQl3aGlsZSAoICggY2xhc3NOYW1lID0gY2xhc3NOYW1lc1sgaSsrIF0gKSApIHsKCgkJCQkJLy8gQ2hlY2sgZWFjaCBjbGFzc05hbWUgZ2l2ZW4sIHNwYWNlIHNlcGFyYXRlZCBsaXN0CgkJCQkJaWYgKCBzZWxmLmhhc0NsYXNzKCBjbGFzc05hbWUgKSApIHsKCQkJCQkJc2VsZi5yZW1vdmVDbGFzcyggY2xhc3NOYW1lICk7CgkJCQkJfSBlbHNlIHsKCQkJCQkJc2VsZi5hZGRDbGFzcyggY2xhc3NOYW1lICk7CgkJCQkJfQoJCQkJfQoKCQkJLy8gVG9nZ2xlIHdob2xlIGNsYXNzIG5hbWUKCQkJfSBlbHNlIGlmICggdmFsdWUgPT09IHVuZGVmaW5lZCB8fCB0eXBlID09PSAiYm9vbGVhbiIgKSB7CgkJCQljbGFzc05hbWUgPSBnZXRDbGFzcyggdGhpcyApOwoJCQkJaWYgKCBjbGFzc05hbWUgKSB7CgoJCQkJCS8vIFN0b3JlIGNsYXNzTmFtZSBpZiBzZXQKCQkJCQlkYXRhUHJpdi5zZXQoIHRoaXMsICJfX2NsYXNzTmFtZV9fIiwgY2xhc3NOYW1lICk7CgkJCQl9CgoJCQkJLy8gSWYgdGhlIGVsZW1lbnQgaGFzIGEgY2xhc3MgbmFtZSBvciBpZiB3ZSdyZSBwYXNzZWQgYGZhbHNlYCwKCQkJCS8vIHRoZW4gcmVtb3ZlIHRoZSB3aG9sZSBjbGFzc25hbWUgKGlmIHRoZXJlIHdhcyBvbmUsIHRoZSBhYm92ZSBzYXZlZCBpdCkuCgkJCQkvLyBPdGhlcndpc2UgYnJpbmcgYmFjayB3aGF0ZXZlciB3YXMgcHJldmlvdXNseSBzYXZlZCAoaWYgYW55dGhpbmcpLAoJCQkJLy8gZmFsbGluZyBiYWNrIHRvIHRoZSBlbXB0eSBzdHJpbmcgaWYgbm90aGluZyB3YXMgc3RvcmVkLgoJCQkJaWYgKCB0aGlzLnNldEF0dHJpYnV0ZSApIHsKCQkJCQl0aGlzLnNldEF0dHJpYnV0ZSggImNsYXNzIiwKCQkJCQkJY2xhc3NOYW1lIHx8IHZhbHVlID09PSBmYWxzZSA/CgkJCQkJCSIiIDoKCQkJCQkJZGF0YVByaXYuZ2V0KCB0aGlzLCAiX19jbGFzc05hbWVfXyIgKSB8fCAiIgoJCQkJCSk7CgkJCQl9CgkJCX0KCQl9ICk7Cgl9LAoKCWhhc0NsYXNzOiBmdW5jdGlvbiggc2VsZWN0b3IgKSB7CgkJdmFyIGNsYXNzTmFtZSwgZWxlbSwKCQkJaSA9IDA7CgoJCWNsYXNzTmFtZSA9ICIgIiArIHNlbGVjdG9yICsgIiAiOwoJCXdoaWxlICggKCBlbGVtID0gdGhpc1sgaSsrIF0gKSApIHsKCQkJaWYgKCBlbGVtLm5vZGVUeXBlID09PSAxICYmCgkJCQkoICIgIiArIHN0cmlwQW5kQ29sbGFwc2UoIGdldENsYXNzKCBlbGVtICkgKSArICIgIiApLmluZGV4T2YoIGNsYXNzTmFtZSApID4gLTEgKSB7CgkJCQkJcmV0dXJuIHRydWU7CgkJCX0KCQl9CgoJCXJldHVybiBmYWxzZTsKCX0KfSApOwoKCgoKdmFyIHJyZXR1cm4gPSAvXHIvZzsKCmpRdWVyeS5mbi5leHRlbmQoIHsKCXZhbDogZnVuY3Rpb24oIHZhbHVlICkgewoJCXZhciBob29rcywgcmV0LCB2YWx1ZUlzRnVuY3Rpb24sCgkJCWVsZW0gPSB0aGlzWyAwIF07CgoJCWlmICggIWFyZ3VtZW50cy5sZW5ndGggKSB7CgkJCWlmICggZWxlbSApIHsKCQkJCWhvb2tzID0galF1ZXJ5LnZhbEhvb2tzWyBlbGVtLnR5cGUgXSB8fAoJCQkJCWpRdWVyeS52YWxIb29rc1sgZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpIF07CgoJCQkJaWYgKCBob29rcyAmJgoJCQkJCSJnZXQiIGluIGhvb2tzICYmCgkJCQkJKCByZXQgPSBob29rcy5nZXQoIGVsZW0sICJ2YWx1ZSIgKSApICE9PSB1bmRlZmluZWQKCQkJCSkgewoJCQkJCXJldHVybiByZXQ7CgkJCQl9CgoJCQkJcmV0ID0gZWxlbS52YWx1ZTsKCgkJCQkvLyBIYW5kbGUgbW9zdCBjb21tb24gc3RyaW5nIGNhc2VzCgkJCQlpZiAoIHR5cGVvZiByZXQgPT09ICJzdHJpbmciICkgewoJCQkJCXJldHVybiByZXQucmVwbGFjZSggcnJldHVybiwgIiIgKTsKCQkJCX0KCgkJCQkvLyBIYW5kbGUgY2FzZXMgd2hlcmUgdmFsdWUgaXMgbnVsbC91bmRlZiBvciBudW1iZXIKCQkJCXJldHVybiByZXQgPT0gbnVsbCA/ICIiIDogcmV0OwoJCQl9CgoJCQlyZXR1cm47CgkJfQoKCQl2YWx1ZUlzRnVuY3Rpb24gPSBpc0Z1bmN0aW9uKCB2YWx1ZSApOwoKCQlyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbiggaSApIHsKCQkJdmFyIHZhbDsKCgkJCWlmICggdGhpcy5ub2RlVHlwZSAhPT0gMSApIHsKCQkJCXJldHVybjsKCQkJfQoKCQkJaWYgKCB2YWx1ZUlzRnVuY3Rpb24gKSB7CgkJCQl2YWwgPSB2YWx1ZS5jYWxsKCB0aGlzLCBpLCBqUXVlcnkoIHRoaXMgKS52YWwoKSApOwoJCQl9IGVsc2UgewoJCQkJdmFsID0gdmFsdWU7CgkJCX0KCgkJCS8vIFRyZWF0IG51bGwvdW5kZWZpbmVkIGFzICIiOyBjb252ZXJ0IG51bWJlcnMgdG8gc3RyaW5nCgkJCWlmICggdmFsID09IG51bGwgKSB7CgkJCQl2YWwgPSAiIjsKCgkJCX0gZWxzZSBpZiAoIHR5cGVvZiB2YWwgPT09ICJudW1iZXIiICkgewoJCQkJdmFsICs9ICIiOwoKCQkJfSBlbHNlIGlmICggQXJyYXkuaXNBcnJheSggdmFsICkgKSB7CgkJCQl2YWwgPSBqUXVlcnkubWFwKCB2YWwsIGZ1bmN0aW9uKCB2YWx1ZSApIHsKCQkJCQlyZXR1cm4gdmFsdWUgPT0gbnVsbCA/ICIiIDogdmFsdWUgKyAiIjsKCQkJCX0gKTsKCQkJfQoKCQkJaG9va3MgPSBqUXVlcnkudmFsSG9va3NbIHRoaXMudHlwZSBdIHx8IGpRdWVyeS52YWxIb29rc1sgdGhpcy5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpIF07CgoJCQkvLyBJZiBzZXQgcmV0dXJucyB1bmRlZmluZWQsIGZhbGwgYmFjayB0byBub3JtYWwgc2V0dGluZwoJCQlpZiAoICFob29rcyB8fCAhKCAic2V0IiBpbiBob29rcyApIHx8IGhvb2tzLnNldCggdGhpcywgdmFsLCAidmFsdWUiICkgPT09IHVuZGVmaW5lZCApIHsKCQkJCXRoaXMudmFsdWUgPSB2YWw7CgkJCX0KCQl9ICk7Cgl9Cn0gKTsKCmpRdWVyeS5leHRlbmQoIHsKCXZhbEhvb2tzOiB7CgkJb3B0aW9uOiB7CgkJCWdldDogZnVuY3Rpb24oIGVsZW0gKSB7CgoJCQkJdmFyIHZhbCA9IGpRdWVyeS5maW5kLmF0dHIoIGVsZW0sICJ2YWx1ZSIgKTsKCQkJCXJldHVybiB2YWwgIT0gbnVsbCA/CgkJCQkJdmFsIDoKCgkJCQkJLy8gU3VwcG9ydDogSUUgPD0xMCAtIDExIG9ubHkKCQkJCQkvLyBvcHRpb24udGV4dCB0aHJvd3MgZXhjZXB0aW9ucyAoIzE0Njg2LCAjMTQ4NTgpCgkJCQkJLy8gU3RyaXAgYW5kIGNvbGxhcHNlIHdoaXRlc3BhY2UKCQkJCQkvLyBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnLyNzdHJpcC1hbmQtY29sbGFwc2Utd2hpdGVzcGFjZQoJCQkJCXN0cmlwQW5kQ29sbGFwc2UoIGpRdWVyeS50ZXh0KCBlbGVtICkgKTsKCQkJfQoJCX0sCgkJc2VsZWN0OiB7CgkJCWdldDogZnVuY3Rpb24oIGVsZW0gKSB7CgkJCQl2YXIgdmFsdWUsIG9wdGlvbiwgaSwKCQkJCQlvcHRpb25zID0gZWxlbS5vcHRpb25zLAoJCQkJCWluZGV4ID0gZWxlbS5zZWxlY3RlZEluZGV4LAoJCQkJCW9uZSA9IGVsZW0udHlwZSA9PT0gInNlbGVjdC1vbmUiLAoJCQkJCXZhbHVlcyA9IG9uZSA/IG51bGwgOiBbXSwKCQkJCQltYXggPSBvbmUgPyBpbmRleCArIDEgOiBvcHRpb25zLmxlbmd0aDsKCgkJCQlpZiAoIGluZGV4IDwgMCApIHsKCQkJCQlpID0gbWF4OwoKCQkJCX0gZWxzZSB7CgkJCQkJaSA9IG9uZSA/IGluZGV4IDogMDsKCQkJCX0KCgkJCQkvLyBMb29wIHRocm91Z2ggYWxsIHRoZSBzZWxlY3RlZCBvcHRpb25zCgkJCQlmb3IgKCA7IGkgPCBtYXg7IGkrKyApIHsKCQkJCQlvcHRpb24gPSBvcHRpb25zWyBpIF07CgoJCQkJCS8vIFN1cHBvcnQ6IElFIDw9OSBvbmx5CgkJCQkJLy8gSUU4LTkgZG9lc24ndCB1cGRhdGUgc2VsZWN0ZWQgYWZ0ZXIgZm9ybSByZXNldCAoIzI1NTEpCgkJCQkJaWYgKCAoIG9wdGlvbi5zZWxlY3RlZCB8fCBpID09PSBpbmRleCApICYmCgoJCQkJCQkJLy8gRG9uJ3QgcmV0dXJuIG9wdGlvbnMgdGhhdCBhcmUgZGlzYWJsZWQgb3IgaW4gYSBkaXNhYmxlZCBvcHRncm91cAoJCQkJCQkJIW9wdGlvbi5kaXNhYmxlZCAmJgoJCQkJCQkJKCAhb3B0aW9uLnBhcmVudE5vZGUuZGlzYWJsZWQgfHwKCQkJCQkJCQkhbm9kZU5hbWUoIG9wdGlvbi5wYXJlbnROb2RlLCAib3B0Z3JvdXAiICkgKSApIHsKCgkJCQkJCS8vIEdldCB0aGUgc3BlY2lmaWMgdmFsdWUgZm9yIHRoZSBvcHRpb24KCQkJCQkJdmFsdWUgPSBqUXVlcnkoIG9wdGlvbiApLnZhbCgpOwoKCQkJCQkJLy8gV2UgZG9uJ3QgbmVlZCBhbiBhcnJheSBmb3Igb25lIHNlbGVjdHMKCQkJCQkJaWYgKCBvbmUgKSB7CgkJCQkJCQlyZXR1cm4gdmFsdWU7CgkJCQkJCX0KCgkJCQkJCS8vIE11bHRpLVNlbGVjdHMgcmV0dXJuIGFuIGFycmF5CgkJCQkJCXZhbHVlcy5wdXNoKCB2YWx1ZSApOwoJCQkJCX0KCQkJCX0KCgkJCQlyZXR1cm4gdmFsdWVzOwoJCQl9LAoKCQkJc2V0OiBmdW5jdGlvbiggZWxlbSwgdmFsdWUgKSB7CgkJCQl2YXIgb3B0aW9uU2V0LCBvcHRpb24sCgkJCQkJb3B0aW9ucyA9IGVsZW0ub3B0aW9ucywKCQkJCQl2YWx1ZXMgPSBqUXVlcnkubWFrZUFycmF5KCB2YWx1ZSApLAoJCQkJCWkgPSBvcHRpb25zLmxlbmd0aDsKCgkJCQl3aGlsZSAoIGktLSApIHsKCQkJCQlvcHRpb24gPSBvcHRpb25zWyBpIF07CgoJCQkJCS8qIGVzbGludC1kaXNhYmxlIG5vLWNvbmQtYXNzaWduICovCgoJCQkJCWlmICggb3B0aW9uLnNlbGVjdGVkID0KCQkJCQkJalF1ZXJ5LmluQXJyYXkoIGpRdWVyeS52YWxIb29rcy5vcHRpb24uZ2V0KCBvcHRpb24gKSwgdmFsdWVzICkgPiAtMQoJCQkJCSkgewoJCQkJCQlvcHRpb25TZXQgPSB0cnVlOwoJCQkJCX0KCgkJCQkJLyogZXNsaW50LWVuYWJsZSBuby1jb25kLWFzc2lnbiAqLwoJCQkJfQoKCQkJCS8vIEZvcmNlIGJyb3dzZXJzIHRvIGJlaGF2ZSBjb25zaXN0ZW50bHkgd2hlbiBub24tbWF0Y2hpbmcgdmFsdWUgaXMgc2V0CgkJCQlpZiAoICFvcHRpb25TZXQgKSB7CgkJCQkJZWxlbS5zZWxlY3RlZEluZGV4ID0gLTE7CgkJCQl9CgkJCQlyZXR1cm4gdmFsdWVzOwoJCQl9CgkJfQoJfQp9ICk7CgovLyBSYWRpb3MgYW5kIGNoZWNrYm94ZXMgZ2V0dGVyL3NldHRlcgpqUXVlcnkuZWFjaCggWyAicmFkaW8iLCAiY2hlY2tib3giIF0sIGZ1bmN0aW9uKCkgewoJalF1ZXJ5LnZhbEhvb2tzWyB0aGlzIF0gPSB7CgkJc2V0OiBmdW5jdGlvbiggZWxlbSwgdmFsdWUgKSB7CgkJCWlmICggQXJyYXkuaXNBcnJheSggdmFsdWUgKSApIHsKCQkJCXJldHVybiAoIGVsZW0uY2hlY2tlZCA9IGpRdWVyeS5pbkFycmF5KCBqUXVlcnkoIGVsZW0gKS52YWwoKSwgdmFsdWUgKSA+IC0xICk7CgkJCX0KCQl9Cgl9OwoJaWYgKCAhc3VwcG9ydC5jaGVja09uICkgewoJCWpRdWVyeS52YWxIb29rc1sgdGhpcyBdLmdldCA9IGZ1bmN0aW9uKCBlbGVtICkgewoJCQlyZXR1cm4gZWxlbS5nZXRBdHRyaWJ1dGUoICJ2YWx1ZSIgKSA9PT0gbnVsbCA/ICJvbiIgOiBlbGVtLnZhbHVlOwoJCX07Cgl9Cn0gKTsKCgoKCi8vIFJldHVybiBqUXVlcnkgZm9yIGF0dHJpYnV0ZXMtb25seSBpbmNsdXNpb24KCgpzdXBwb3J0LmZvY3VzaW4gPSAib25mb2N1c2luIiBpbiB3aW5kb3c7CgoKdmFyIHJmb2N1c01vcnBoID0gL14oPzpmb2N1c2luZm9jdXN8Zm9jdXNvdXRibHVyKSQvLAoJc3RvcFByb3BhZ2F0aW9uQ2FsbGJhY2sgPSBmdW5jdGlvbiggZSApIHsKCQllLnN0b3BQcm9wYWdhdGlvbigpOwoJfTsKCmpRdWVyeS5leHRlbmQoIGpRdWVyeS5ldmVudCwgewoKCXRyaWdnZXI6IGZ1bmN0aW9uKCBldmVudCwgZGF0YSwgZWxlbSwgb25seUhhbmRsZXJzICkgewoKCQl2YXIgaSwgY3VyLCB0bXAsIGJ1YmJsZVR5cGUsIG9udHlwZSwgaGFuZGxlLCBzcGVjaWFsLCBsYXN0RWxlbWVudCwKCQkJZXZlbnRQYXRoID0gWyBlbGVtIHx8IGRvY3VtZW50IF0sCgkJCXR5cGUgPSBoYXNPd24uY2FsbCggZXZlbnQsICJ0eXBlIiApID8gZXZlbnQudHlwZSA6IGV2ZW50LAoJCQluYW1lc3BhY2VzID0gaGFzT3duLmNhbGwoIGV2ZW50LCAibmFtZXNwYWNlIiApID8gZXZlbnQubmFtZXNwYWNlLnNwbGl0KCAiLiIgKSA6IFtdOwoKCQljdXIgPSBsYXN0RWxlbWVudCA9IHRtcCA9IGVsZW0gPSBlbGVtIHx8IGRvY3VtZW50OwoKCQkvLyBEb24ndCBkbyBldmVudHMgb24gdGV4dCBhbmQgY29tbWVudCBub2RlcwoJCWlmICggZWxlbS5ub2RlVHlwZSA9PT0gMyB8fCBlbGVtLm5vZGVUeXBlID09PSA4ICkgewoJCQlyZXR1cm47CgkJfQoKCQkvLyBmb2N1cy9ibHVyIG1vcnBocyB0byBmb2N1c2luL291dDsgZW5zdXJlIHdlJ3JlIG5vdCBmaXJpbmcgdGhlbSByaWdodCBub3cKCQlpZiAoIHJmb2N1c01vcnBoLnRlc3QoIHR5cGUgKyBqUXVlcnkuZXZlbnQudHJpZ2dlcmVkICkgKSB7CgkJCXJldHVybjsKCQl9CgoJCWlmICggdHlwZS5pbmRleE9mKCAiLiIgKSA+IC0xICkgewoKCQkJLy8gTmFtZXNwYWNlZCB0cmlnZ2VyOyBjcmVhdGUgYSByZWdleHAgdG8gbWF0Y2ggZXZlbnQgdHlwZSBpbiBoYW5kbGUoKQoJCQluYW1lc3BhY2VzID0gdHlwZS5zcGxpdCggIi4iICk7CgkJCXR5cGUgPSBuYW1lc3BhY2VzLnNoaWZ0KCk7CgkJCW5hbWVzcGFjZXMuc29ydCgpOwoJCX0KCQlvbnR5cGUgPSB0eXBlLmluZGV4T2YoICI6IiApIDwgMCAmJiAib24iICsgdHlwZTsKCgkJLy8gQ2FsbGVyIGNhbiBwYXNzIGluIGEgalF1ZXJ5LkV2ZW50IG9iamVjdCwgT2JqZWN0LCBvciBqdXN0IGFuIGV2ZW50IHR5cGUgc3RyaW5nCgkJZXZlbnQgPSBldmVudFsgalF1ZXJ5LmV4cGFuZG8gXSA/CgkJCWV2ZW50IDoKCQkJbmV3IGpRdWVyeS5FdmVudCggdHlwZSwgdHlwZW9mIGV2ZW50ID09PSAib2JqZWN0IiAmJiBldmVudCApOwoKCQkvLyBUcmlnZ2VyIGJpdG1hc2s6ICYgMSBmb3IgbmF0aXZlIGhhbmRsZXJzOyAmIDIgZm9yIGpRdWVyeSAoYWx3YXlzIHRydWUpCgkJZXZlbnQuaXNUcmlnZ2VyID0gb25seUhhbmRsZXJzID8gMiA6IDM7CgkJZXZlbnQubmFtZXNwYWNlID0gbmFtZXNwYWNlcy5qb2luKCAiLiIgKTsKCQlldmVudC5ybmFtZXNwYWNlID0gZXZlbnQubmFtZXNwYWNlID8KCQkJbmV3IFJlZ0V4cCggIihefFxcLikiICsgbmFtZXNwYWNlcy5qb2luKCAiXFwuKD86LipcXC58KSIgKSArICIoXFwufCQpIiApIDoKCQkJbnVsbDsKCgkJLy8gQ2xlYW4gdXAgdGhlIGV2ZW50IGluIGNhc2UgaXQgaXMgYmVpbmcgcmV1c2VkCgkJZXZlbnQucmVzdWx0ID0gdW5kZWZpbmVkOwoJCWlmICggIWV2ZW50LnRhcmdldCApIHsKCQkJZXZlbnQudGFyZ2V0ID0gZWxlbTsKCQl9CgoJCS8vIENsb25lIGFueSBpbmNvbWluZyBkYXRhIGFuZCBwcmVwZW5kIHRoZSBldmVudCwgY3JlYXRpbmcgdGhlIGhhbmRsZXIgYXJnIGxpc3QKCQlkYXRhID0gZGF0YSA9PSBudWxsID8KCQkJWyBldmVudCBdIDoKCQkJalF1ZXJ5Lm1ha2VBcnJheSggZGF0YSwgWyBldmVudCBdICk7CgoJCS8vIEFsbG93IHNwZWNpYWwgZXZlbnRzIHRvIGRyYXcgb3V0c2lkZSB0aGUgbGluZXMKCQlzcGVjaWFsID0galF1ZXJ5LmV2ZW50LnNwZWNpYWxbIHR5cGUgXSB8fCB7fTsKCQlpZiAoICFvbmx5SGFuZGxlcnMgJiYgc3BlY2lhbC50cmlnZ2VyICYmIHNwZWNpYWwudHJpZ2dlci5hcHBseSggZWxlbSwgZGF0YSApID09PSBmYWxzZSApIHsKCQkJcmV0dXJuOwoJCX0KCgkJLy8gRGV0ZXJtaW5lIGV2ZW50IHByb3BhZ2F0aW9uIHBhdGggaW4gYWR2YW5jZSwgcGVyIFczQyBldmVudHMgc3BlYyAoIzk5NTEpCgkJLy8gQnViYmxlIHVwIHRvIGRvY3VtZW50LCB0aGVuIHRvIHdpbmRvdzsgd2F0Y2ggZm9yIGEgZ2xvYmFsIG93bmVyRG9jdW1lbnQgdmFyICgjOTcyNCkKCQlpZiAoICFvbmx5SGFuZGxlcnMgJiYgIXNwZWNpYWwubm9CdWJibGUgJiYgIWlzV2luZG93KCBlbGVtICkgKSB7CgoJCQlidWJibGVUeXBlID0gc3BlY2lhbC5kZWxlZ2F0ZVR5cGUgfHwgdHlwZTsKCQkJaWYgKCAhcmZvY3VzTW9ycGgudGVzdCggYnViYmxlVHlwZSArIHR5cGUgKSApIHsKCQkJCWN1ciA9IGN1ci5wYXJlbnROb2RlOwoJCQl9CgkJCWZvciAoIDsgY3VyOyBjdXIgPSBjdXIucGFyZW50Tm9kZSApIHsKCQkJCWV2ZW50UGF0aC5wdXNoKCBjdXIgKTsKCQkJCXRtcCA9IGN1cjsKCQkJfQoKCQkJLy8gT25seSBhZGQgd2luZG93IGlmIHdlIGdvdCB0byBkb2N1bWVudCAoZS5nLiwgbm90IHBsYWluIG9iaiBvciBkZXRhY2hlZCBET00pCgkJCWlmICggdG1wID09PSAoIGVsZW0ub3duZXJEb2N1bWVudCB8fCBkb2N1bWVudCApICkgewoJCQkJZXZlbnRQYXRoLnB1c2goIHRtcC5kZWZhdWx0VmlldyB8fCB0bXAucGFyZW50V2luZG93IHx8IHdpbmRvdyApOwoJCQl9CgkJfQoKCQkvLyBGaXJlIGhhbmRsZXJzIG9uIHRoZSBldmVudCBwYXRoCgkJaSA9IDA7CgkJd2hpbGUgKCAoIGN1ciA9IGV2ZW50UGF0aFsgaSsrIF0gKSAmJiAhZXZlbnQuaXNQcm9wYWdhdGlvblN0b3BwZWQoKSApIHsKCQkJbGFzdEVsZW1lbnQgPSBjdXI7CgkJCWV2ZW50LnR5cGUgPSBpID4gMSA/CgkJCQlidWJibGVUeXBlIDoKCQkJCXNwZWNpYWwuYmluZFR5cGUgfHwgdHlwZTsKCgkJCS8vIGpRdWVyeSBoYW5kbGVyCgkJCWhhbmRsZSA9ICggZGF0YVByaXYuZ2V0KCBjdXIsICJldmVudHMiICkgfHwge30gKVsgZXZlbnQudHlwZSBdICYmCgkJCQlkYXRhUHJpdi5nZXQoIGN1ciwgImhhbmRsZSIgKTsKCQkJaWYgKCBoYW5kbGUgKSB7CgkJCQloYW5kbGUuYXBwbHkoIGN1ciwgZGF0YSApOwoJCQl9CgoJCQkvLyBOYXRpdmUgaGFuZGxlcgoJCQloYW5kbGUgPSBvbnR5cGUgJiYgY3VyWyBvbnR5cGUgXTsKCQkJaWYgKCBoYW5kbGUgJiYgaGFuZGxlLmFwcGx5ICYmIGFjY2VwdERhdGEoIGN1ciApICkgewoJCQkJZXZlbnQucmVzdWx0ID0gaGFuZGxlLmFwcGx5KCBjdXIsIGRhdGEgKTsKCQkJCWlmICggZXZlbnQucmVzdWx0ID09PSBmYWxzZSApIHsKCQkJCQlldmVudC5wcmV2ZW50RGVmYXVsdCgpOwoJCQkJfQoJCQl9CgkJfQoJCWV2ZW50LnR5cGUgPSB0eXBlOwoKCQkvLyBJZiBub2JvZHkgcHJldmVudGVkIHRoZSBkZWZhdWx0IGFjdGlvbiwgZG8gaXQgbm93CgkJaWYgKCAhb25seUhhbmRsZXJzICYmICFldmVudC5pc0RlZmF1bHRQcmV2ZW50ZWQoKSApIHsKCgkJCWlmICggKCAhc3BlY2lhbC5fZGVmYXVsdCB8fAoJCQkJc3BlY2lhbC5fZGVmYXVsdC5hcHBseSggZXZlbnRQYXRoLnBvcCgpLCBkYXRhICkgPT09IGZhbHNlICkgJiYKCQkJCWFjY2VwdERhdGEoIGVsZW0gKSApIHsKCgkJCQkvLyBDYWxsIGEgbmF0aXZlIERPTSBtZXRob2Qgb24gdGhlIHRhcmdldCB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgdGhlIGV2ZW50LgoJCQkJLy8gRG9uJ3QgZG8gZGVmYXVsdCBhY3Rpb25zIG9uIHdpbmRvdywgdGhhdCdzIHdoZXJlIGdsb2JhbCB2YXJpYWJsZXMgYmUgKCM2MTcwKQoJCQkJaWYgKCBvbnR5cGUgJiYgaXNGdW5jdGlvbiggZWxlbVsgdHlwZSBdICkgJiYgIWlzV2luZG93KCBlbGVtICkgKSB7CgoJCQkJCS8vIERvbid0IHJlLXRyaWdnZXIgYW4gb25GT08gZXZlbnQgd2hlbiB3ZSBjYWxsIGl0cyBGT08oKSBtZXRob2QKCQkJCQl0bXAgPSBlbGVtWyBvbnR5cGUgXTsKCgkJCQkJaWYgKCB0bXAgKSB7CgkJCQkJCWVsZW1bIG9udHlwZSBdID0gbnVsbDsKCQkJCQl9CgoJCQkJCS8vIFByZXZlbnQgcmUtdHJpZ2dlcmluZyBvZiB0aGUgc2FtZSBldmVudCwgc2luY2Ugd2UgYWxyZWFkeSBidWJibGVkIGl0IGFib3ZlCgkJCQkJalF1ZXJ5LmV2ZW50LnRyaWdnZXJlZCA9IHR5cGU7CgoJCQkJCWlmICggZXZlbnQuaXNQcm9wYWdhdGlvblN0b3BwZWQoKSApIHsKCQkJCQkJbGFzdEVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lciggdHlwZSwgc3RvcFByb3BhZ2F0aW9uQ2FsbGJhY2sgKTsKCQkJCQl9CgoJCQkJCWVsZW1bIHR5cGUgXSgpOwoKCQkJCQlpZiAoIGV2ZW50LmlzUHJvcGFnYXRpb25TdG9wcGVkKCkgKSB7CgkJCQkJCWxhc3RFbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoIHR5cGUsIHN0b3BQcm9wYWdhdGlvbkNhbGxiYWNrICk7CgkJCQkJfQoKCQkJCQlqUXVlcnkuZXZlbnQudHJpZ2dlcmVkID0gdW5kZWZpbmVkOwoKCQkJCQlpZiAoIHRtcCApIHsKCQkJCQkJZWxlbVsgb250eXBlIF0gPSB0bXA7CgkJCQkJfQoJCQkJfQoJCQl9CgkJfQoKCQlyZXR1cm4gZXZlbnQucmVzdWx0OwoJfSwKCgkvLyBQaWdneWJhY2sgb24gYSBkb25vciBldmVudCB0byBzaW11bGF0ZSBhIGRpZmZlcmVudCBvbmUKCS8vIFVzZWQgb25seSBmb3IgYGZvY3VzKGluIHwgb3V0KWAgZXZlbnRzCglzaW11bGF0ZTogZnVuY3Rpb24oIHR5cGUsIGVsZW0sIGV2ZW50ICkgewoJCXZhciBlID0galF1ZXJ5LmV4dGVuZCgKCQkJbmV3IGpRdWVyeS5FdmVudCgpLAoJCQlldmVudCwKCQkJewoJCQkJdHlwZTogdHlwZSwKCQkJCWlzU2ltdWxhdGVkOiB0cnVlCgkJCX0KCQkpOwoKCQlqUXVlcnkuZXZlbnQudHJpZ2dlciggZSwgbnVsbCwgZWxlbSApOwoJfQoKfSApOwoKalF1ZXJ5LmZuLmV4dGVuZCggewoKCXRyaWdnZXI6IGZ1bmN0aW9uKCB0eXBlLCBkYXRhICkgewoJCXJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCkgewoJCQlqUXVlcnkuZXZlbnQudHJpZ2dlciggdHlwZSwgZGF0YSwgdGhpcyApOwoJCX0gKTsKCX0sCgl0cmlnZ2VySGFuZGxlcjogZnVuY3Rpb24oIHR5cGUsIGRhdGEgKSB7CgkJdmFyIGVsZW0gPSB0aGlzWyAwIF07CgkJaWYgKCBlbGVtICkgewoJCQlyZXR1cm4galF1ZXJ5LmV2ZW50LnRyaWdnZXIoIHR5cGUsIGRhdGEsIGVsZW0sIHRydWUgKTsKCQl9Cgl9Cn0gKTsKCgovLyBTdXBwb3J0OiBGaXJlZm94IDw9NDQKLy8gRmlyZWZveCBkb2Vzbid0IGhhdmUgZm9jdXMoaW4gfCBvdXQpIGV2ZW50cwovLyBSZWxhdGVkIHRpY2tldCAtIGh0dHBzOi8vYnVnemlsbGEubW96aWxsYS5vcmcvc2hvd19idWcuY2dpP2lkPTY4Nzc4NwovLwovLyBTdXBwb3J0OiBDaHJvbWUgPD00OCAtIDQ5LCBTYWZhcmkgPD05LjAgLSA5LjEKLy8gZm9jdXMoaW4gfCBvdXQpIGV2ZW50cyBmaXJlIGFmdGVyIGZvY3VzICYgYmx1ciBldmVudHMsCi8vIHdoaWNoIGlzIHNwZWMgdmlvbGF0aW9uIC0gaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTMtRXZlbnRzLyNldmVudHMtZm9jdXNldmVudC1ldmVudC1vcmRlcgovLyBSZWxhdGVkIHRpY2tldCAtIGh0dHBzOi8vYnVncy5jaHJvbWl1bS5vcmcvcC9jaHJvbWl1bS9pc3N1ZXMvZGV0YWlsP2lkPTQ0OTg1NwppZiAoICFzdXBwb3J0LmZvY3VzaW4gKSB7CglqUXVlcnkuZWFjaCggeyBmb2N1czogImZvY3VzaW4iLCBibHVyOiAiZm9jdXNvdXQiIH0sIGZ1bmN0aW9uKCBvcmlnLCBmaXggKSB7CgoJCS8vIEF0dGFjaCBhIHNpbmdsZSBjYXB0dXJpbmcgaGFuZGxlciBvbiB0aGUgZG9jdW1lbnQgd2hpbGUgc29tZW9uZSB3YW50cyBmb2N1c2luL2ZvY3Vzb3V0CgkJdmFyIGhhbmRsZXIgPSBmdW5jdGlvbiggZXZlbnQgKSB7CgkJCWpRdWVyeS5ldmVudC5zaW11bGF0ZSggZml4LCBldmVudC50YXJnZXQsIGpRdWVyeS5ldmVudC5maXgoIGV2ZW50ICkgKTsKCQl9OwoKCQlqUXVlcnkuZXZlbnQuc3BlY2lhbFsgZml4IF0gPSB7CgkJCXNldHVwOiBmdW5jdGlvbigpIHsKCQkJCXZhciBkb2MgPSB0aGlzLm93bmVyRG9jdW1lbnQgfHwgdGhpcywKCQkJCQlhdHRhY2hlcyA9IGRhdGFQcml2LmFjY2VzcyggZG9jLCBmaXggKTsKCgkJCQlpZiAoICFhdHRhY2hlcyApIHsKCQkJCQlkb2MuYWRkRXZlbnRMaXN0ZW5lciggb3JpZywgaGFuZGxlciwgdHJ1ZSApOwoJCQkJfQoJCQkJZGF0YVByaXYuYWNjZXNzKCBkb2MsIGZpeCwgKCBhdHRhY2hlcyB8fCAwICkgKyAxICk7CgkJCX0sCgkJCXRlYXJkb3duOiBmdW5jdGlvbigpIHsKCQkJCXZhciBkb2MgPSB0aGlzLm93bmVyRG9jdW1lbnQgfHwgdGhpcywKCQkJCQlhdHRhY2hlcyA9IGRhdGFQcml2LmFjY2VzcyggZG9jLCBmaXggKSAtIDE7CgoJCQkJaWYgKCAhYXR0YWNoZXMgKSB7CgkJCQkJZG9jLnJlbW92ZUV2ZW50TGlzdGVuZXIoIG9yaWcsIGhhbmRsZXIsIHRydWUgKTsKCQkJCQlkYXRhUHJpdi5yZW1vdmUoIGRvYywgZml4ICk7CgoJCQkJfSBlbHNlIHsKCQkJCQlkYXRhUHJpdi5hY2Nlc3MoIGRvYywgZml4LCBhdHRhY2hlcyApOwoJCQkJfQoJCQl9CgkJfTsKCX0gKTsKfQp2YXIgbG9jYXRpb24gPSB3aW5kb3cubG9jYXRpb247Cgp2YXIgbm9uY2UgPSBEYXRlLm5vdygpOwoKdmFyIHJxdWVyeSA9ICggL1w/LyApOwoKCgovLyBDcm9zcy1icm93c2VyIHhtbCBwYXJzaW5nCmpRdWVyeS5wYXJzZVhNTCA9IGZ1bmN0aW9uKCBkYXRhICkgewoJdmFyIHhtbDsKCWlmICggIWRhdGEgfHwgdHlwZW9mIGRhdGEgIT09ICJzdHJpbmciICkgewoJCXJldHVybiBudWxsOwoJfQoKCS8vIFN1cHBvcnQ6IElFIDkgLSAxMSBvbmx5CgkvLyBJRSB0aHJvd3Mgb24gcGFyc2VGcm9tU3RyaW5nIHdpdGggaW52YWxpZCBpbnB1dC4KCXRyeSB7CgkJeG1sID0gKCBuZXcgd2luZG93LkRPTVBhcnNlcigpICkucGFyc2VGcm9tU3RyaW5nKCBkYXRhLCAidGV4dC94bWwiICk7Cgl9IGNhdGNoICggZSApIHsKCQl4bWwgPSB1bmRlZmluZWQ7Cgl9CgoJaWYgKCAheG1sIHx8IHhtbC5nZXRFbGVtZW50c0J5VGFnTmFtZSggInBhcnNlcmVycm9yIiApLmxlbmd0aCApIHsKCQlqUXVlcnkuZXJyb3IoICJJbnZhbGlkIFhNTDogIiArIGRhdGEgKTsKCX0KCXJldHVybiB4bWw7Cn07CgoKdmFyCglyYnJhY2tldCA9IC9cW1xdJC8sCglyQ1JMRiA9IC9ccj9cbi9nLAoJcnN1Ym1pdHRlclR5cGVzID0gL14oPzpzdWJtaXR8YnV0dG9ufGltYWdlfHJlc2V0fGZpbGUpJC9pLAoJcnN1Ym1pdHRhYmxlID0gL14oPzppbnB1dHxzZWxlY3R8dGV4dGFyZWF8a2V5Z2VuKS9pOwoKZnVuY3Rpb24gYnVpbGRQYXJhbXMoIHByZWZpeCwgb2JqLCB0cmFkaXRpb25hbCwgYWRkICkgewoJdmFyIG5hbWU7CgoJaWYgKCBBcnJheS5pc0FycmF5KCBvYmogKSApIHsKCgkJLy8gU2VyaWFsaXplIGFycmF5IGl0ZW0uCgkJalF1ZXJ5LmVhY2goIG9iaiwgZnVuY3Rpb24oIGksIHYgKSB7CgkJCWlmICggdHJhZGl0aW9uYWwgfHwgcmJyYWNrZXQudGVzdCggcHJlZml4ICkgKSB7CgoJCQkJLy8gVHJlYXQgZWFjaCBhcnJheSBpdGVtIGFzIGEgc2NhbGFyLgoJCQkJYWRkKCBwcmVmaXgsIHYgKTsKCgkJCX0gZWxzZSB7CgoJCQkJLy8gSXRlbSBpcyBub24tc2NhbGFyIChhcnJheSBvciBvYmplY3QpLCBlbmNvZGUgaXRzIG51bWVyaWMgaW5kZXguCgkJCQlidWlsZFBhcmFtcygKCQkJCQlwcmVmaXggKyAiWyIgKyAoIHR5cGVvZiB2ID09PSAib2JqZWN0IiAmJiB2ICE9IG51bGwgPyBpIDogIiIgKSArICJdIiwKCQkJCQl2LAoJCQkJCXRyYWRpdGlvbmFsLAoJCQkJCWFkZAoJCQkJKTsKCQkJfQoJCX0gKTsKCgl9IGVsc2UgaWYgKCAhdHJhZGl0aW9uYWwgJiYgdG9UeXBlKCBvYmogKSA9PT0gIm9iamVjdCIgKSB7CgoJCS8vIFNlcmlhbGl6ZSBvYmplY3QgaXRlbS4KCQlmb3IgKCBuYW1lIGluIG9iaiApIHsKCQkJYnVpbGRQYXJhbXMoIHByZWZpeCArICJbIiArIG5hbWUgKyAiXSIsIG9ialsgbmFtZSBdLCB0cmFkaXRpb25hbCwgYWRkICk7CgkJfQoKCX0gZWxzZSB7CgoJCS8vIFNlcmlhbGl6ZSBzY2FsYXIgaXRlbS4KCQlhZGQoIHByZWZpeCwgb2JqICk7Cgl9Cn0KCi8vIFNlcmlhbGl6ZSBhbiBhcnJheSBvZiBmb3JtIGVsZW1lbnRzIG9yIGEgc2V0IG9mCi8vIGtleS92YWx1ZXMgaW50byBhIHF1ZXJ5IHN0cmluZwpqUXVlcnkucGFyYW0gPSBmdW5jdGlvbiggYSwgdHJhZGl0aW9uYWwgKSB7Cgl2YXIgcHJlZml4LAoJCXMgPSBbXSwKCQlhZGQgPSBmdW5jdGlvbigga2V5LCB2YWx1ZU9yRnVuY3Rpb24gKSB7CgoJCQkvLyBJZiB2YWx1ZSBpcyBhIGZ1bmN0aW9uLCBpbnZva2UgaXQgYW5kIHVzZSBpdHMgcmV0dXJuIHZhbHVlCgkJCXZhciB2YWx1ZSA9IGlzRnVuY3Rpb24oIHZhbHVlT3JGdW5jdGlvbiApID8KCQkJCXZhbHVlT3JGdW5jdGlvbigpIDoKCQkJCXZhbHVlT3JGdW5jdGlvbjsKCgkJCXNbIHMubGVuZ3RoIF0gPSBlbmNvZGVVUklDb21wb25lbnQoIGtleSApICsgIj0iICsKCQkJCWVuY29kZVVSSUNvbXBvbmVudCggdmFsdWUgPT0gbnVsbCA/ICIiIDogdmFsdWUgKTsKCQl9OwoKCS8vIElmIGFuIGFycmF5IHdhcyBwYXNzZWQgaW4sIGFzc3VtZSB0aGF0IGl0IGlzIGFuIGFycmF5IG9mIGZvcm0gZWxlbWVudHMuCglpZiAoIEFycmF5LmlzQXJyYXkoIGEgKSB8fCAoIGEuanF1ZXJ5ICYmICFqUXVlcnkuaXNQbGFpbk9iamVjdCggYSApICkgKSB7CgoJCS8vIFNlcmlhbGl6ZSB0aGUgZm9ybSBlbGVtZW50cwoJCWpRdWVyeS5lYWNoKCBhLCBmdW5jdGlvbigpIHsKCQkJYWRkKCB0aGlzLm5hbWUsIHRoaXMudmFsdWUgKTsKCQl9ICk7CgoJfSBlbHNlIHsKCgkJLy8gSWYgdHJhZGl0aW9uYWwsIGVuY29kZSB0aGUgIm9sZCIgd2F5ICh0aGUgd2F5IDEuMy4yIG9yIG9sZGVyCgkJLy8gZGlkIGl0KSwgb3RoZXJ3aXNlIGVuY29kZSBwYXJhbXMgcmVjdXJzaXZlbHkuCgkJZm9yICggcHJlZml4IGluIGEgKSB7CgkJCWJ1aWxkUGFyYW1zKCBwcmVmaXgsIGFbIHByZWZpeCBdLCB0cmFkaXRpb25hbCwgYWRkICk7CgkJfQoJfQoKCS8vIFJldHVybiB0aGUgcmVzdWx0aW5nIHNlcmlhbGl6YXRpb24KCXJldHVybiBzLmpvaW4oICImIiApOwp9OwoKalF1ZXJ5LmZuLmV4dGVuZCggewoJc2VyaWFsaXplOiBmdW5jdGlvbigpIHsKCQlyZXR1cm4galF1ZXJ5LnBhcmFtKCB0aGlzLnNlcmlhbGl6ZUFycmF5KCkgKTsKCX0sCglzZXJpYWxpemVBcnJheTogZnVuY3Rpb24oKSB7CgkJcmV0dXJuIHRoaXMubWFwKCBmdW5jdGlvbigpIHsKCgkJCS8vIENhbiBhZGQgcHJvcEhvb2sgZm9yICJlbGVtZW50cyIgdG8gZmlsdGVyIG9yIGFkZCBmb3JtIGVsZW1lbnRzCgkJCXZhciBlbGVtZW50cyA9IGpRdWVyeS5wcm9wKCB0aGlzLCAiZWxlbWVudHMiICk7CgkJCXJldHVybiBlbGVtZW50cyA/IGpRdWVyeS5tYWtlQXJyYXkoIGVsZW1lbnRzICkgOiB0aGlzOwoJCX0gKQoJCS5maWx0ZXIoIGZ1bmN0aW9uKCkgewoJCQl2YXIgdHlwZSA9IHRoaXMudHlwZTsKCgkJCS8vIFVzZSAuaXMoICI6ZGlzYWJsZWQiICkgc28gdGhhdCBmaWVsZHNldFtkaXNhYmxlZF0gd29ya3MKCQkJcmV0dXJuIHRoaXMubmFtZSAmJiAhalF1ZXJ5KCB0aGlzICkuaXMoICI6ZGlzYWJsZWQiICkgJiYKCQkJCXJzdWJtaXR0YWJsZS50ZXN0KCB0aGlzLm5vZGVOYW1lICkgJiYgIXJzdWJtaXR0ZXJUeXBlcy50ZXN0KCB0eXBlICkgJiYKCQkJCSggdGhpcy5jaGVja2VkIHx8ICFyY2hlY2thYmxlVHlwZS50ZXN0KCB0eXBlICkgKTsKCQl9ICkKCQkubWFwKCBmdW5jdGlvbiggaSwgZWxlbSApIHsKCQkJdmFyIHZhbCA9IGpRdWVyeSggdGhpcyApLnZhbCgpOwoKCQkJaWYgKCB2YWwgPT0gbnVsbCApIHsKCQkJCXJldHVybiBudWxsOwoJCQl9CgoJCQlpZiAoIEFycmF5LmlzQXJyYXkoIHZhbCApICkgewoJCQkJcmV0dXJuIGpRdWVyeS5tYXAoIHZhbCwgZnVuY3Rpb24oIHZhbCApIHsKCQkJCQlyZXR1cm4geyBuYW1lOiBlbGVtLm5hbWUsIHZhbHVlOiB2YWwucmVwbGFjZSggckNSTEYsICJcclxuIiApIH07CgkJCQl9ICk7CgkJCX0KCgkJCXJldHVybiB7IG5hbWU6IGVsZW0ubmFtZSwgdmFsdWU6IHZhbC5yZXBsYWNlKCByQ1JMRiwgIlxyXG4iICkgfTsKCQl9ICkuZ2V0KCk7Cgl9Cn0gKTsKCgp2YXIKCXIyMCA9IC8lMjAvZywKCXJoYXNoID0gLyMuKiQvLAoJcmFudGlDYWNoZSA9IC8oWz8mXSlfPVteJl0qLywKCXJoZWFkZXJzID0gL14oLio/KTpbIFx0XSooW15cclxuXSopJC9tZywKCgkvLyAjNzY1MywgIzgxMjUsICM4MTUyOiBsb2NhbCBwcm90b2NvbCBkZXRlY3Rpb24KCXJsb2NhbFByb3RvY29sID0gL14oPzphYm91dHxhcHB8YXBwLXN0b3JhZ2V8ListZXh0ZW5zaW9ufGZpbGV8cmVzfHdpZGdldCk6JC8sCglybm9Db250ZW50ID0gL14oPzpHRVR8SEVBRCkkLywKCXJwcm90b2NvbCA9IC9eXC9cLy8sCgoJLyogUHJlZmlsdGVycwoJICogMSkgVGhleSBhcmUgdXNlZnVsIHRvIGludHJvZHVjZSBjdXN0b20gZGF0YVR5cGVzIChzZWUgYWpheC9qc29ucC5qcyBmb3IgYW4gZXhhbXBsZSkKCSAqIDIpIFRoZXNlIGFyZSBjYWxsZWQ6CgkgKiAgICAtIEJFRk9SRSBhc2tpbmcgZm9yIGEgdHJhbnNwb3J0CgkgKiAgICAtIEFGVEVSIHBhcmFtIHNlcmlhbGl6YXRpb24gKHMuZGF0YSBpcyBhIHN0cmluZyBpZiBzLnByb2Nlc3NEYXRhIGlzIHRydWUpCgkgKiAzKSBrZXkgaXMgdGhlIGRhdGFUeXBlCgkgKiA0KSB0aGUgY2F0Y2hhbGwgc3ltYm9sICIqIiBjYW4gYmUgdXNlZAoJICogNSkgZXhlY3V0aW9uIHdpbGwgc3RhcnQgd2l0aCB0cmFuc3BvcnQgZGF0YVR5cGUgYW5kIFRIRU4gY29udGludWUgZG93biB0byAiKiIgaWYgbmVlZGVkCgkgKi8KCXByZWZpbHRlcnMgPSB7fSwKCgkvKiBUcmFuc3BvcnRzIGJpbmRpbmdzCgkgKiAxKSBrZXkgaXMgdGhlIGRhdGFUeXBlCgkgKiAyKSB0aGUgY2F0Y2hhbGwgc3ltYm9sICIqIiBjYW4gYmUgdXNlZAoJICogMykgc2VsZWN0aW9uIHdpbGwgc3RhcnQgd2l0aCB0cmFuc3BvcnQgZGF0YVR5cGUgYW5kIFRIRU4gZ28gdG8gIioiIGlmIG5lZWRlZAoJICovCgl0cmFuc3BvcnRzID0ge30sCgoJLy8gQXZvaWQgY29tbWVudC1wcm9sb2cgY2hhciBzZXF1ZW5jZSAoIzEwMDk4KTsgbXVzdCBhcHBlYXNlIGxpbnQgYW5kIGV2YWRlIGNvbXByZXNzaW9uCglhbGxUeXBlcyA9ICIqLyIuY29uY2F0KCAiKiIgKSwKCgkvLyBBbmNob3IgdGFnIGZvciBwYXJzaW5nIHRoZSBkb2N1bWVudCBvcmlnaW4KCW9yaWdpbkFuY2hvciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoICJhIiApOwoJb3JpZ2luQW5jaG9yLmhyZWYgPSBsb2NhdGlvbi5ocmVmOwoKLy8gQmFzZSAiY29uc3RydWN0b3IiIGZvciBqUXVlcnkuYWpheFByZWZpbHRlciBhbmQgalF1ZXJ5LmFqYXhUcmFuc3BvcnQKZnVuY3Rpb24gYWRkVG9QcmVmaWx0ZXJzT3JUcmFuc3BvcnRzKCBzdHJ1Y3R1cmUgKSB7CgoJLy8gZGF0YVR5cGVFeHByZXNzaW9uIGlzIG9wdGlvbmFsIGFuZCBkZWZhdWx0cyB0byAiKiIKCXJldHVybiBmdW5jdGlvbiggZGF0YVR5cGVFeHByZXNzaW9uLCBmdW5jICkgewoKCQlpZiAoIHR5cGVvZiBkYXRhVHlwZUV4cHJlc3Npb24gIT09ICJzdHJpbmciICkgewoJCQlmdW5jID0gZGF0YVR5cGVFeHByZXNzaW9uOwoJCQlkYXRhVHlwZUV4cHJlc3Npb24gPSAiKiI7CgkJfQoKCQl2YXIgZGF0YVR5cGUsCgkJCWkgPSAwLAoJCQlkYXRhVHlwZXMgPSBkYXRhVHlwZUV4cHJlc3Npb24udG9Mb3dlckNhc2UoKS5tYXRjaCggcm5vdGh0bWx3aGl0ZSApIHx8IFtdOwoKCQlpZiAoIGlzRnVuY3Rpb24oIGZ1bmMgKSApIHsKCgkJCS8vIEZvciBlYWNoIGRhdGFUeXBlIGluIHRoZSBkYXRhVHlwZUV4cHJlc3Npb24KCQkJd2hpbGUgKCAoIGRhdGFUeXBlID0gZGF0YVR5cGVzWyBpKysgXSApICkgewoKCQkJCS8vIFByZXBlbmQgaWYgcmVxdWVzdGVkCgkJCQlpZiAoIGRhdGFUeXBlWyAwIF0gPT09ICIrIiApIHsKCQkJCQlkYXRhVHlwZSA9IGRhdGFUeXBlLnNsaWNlKCAxICkgfHwgIioiOwoJCQkJCSggc3RydWN0dXJlWyBkYXRhVHlwZSBdID0gc3RydWN0dXJlWyBkYXRhVHlwZSBdIHx8IFtdICkudW5zaGlmdCggZnVuYyApOwoKCQkJCS8vIE90aGVyd2lzZSBhcHBlbmQKCQkJCX0gZWxzZSB7CgkJCQkJKCBzdHJ1Y3R1cmVbIGRhdGFUeXBlIF0gPSBzdHJ1Y3R1cmVbIGRhdGFUeXBlIF0gfHwgW10gKS5wdXNoKCBmdW5jICk7CgkJCQl9CgkJCX0KCQl9Cgl9Owp9CgovLyBCYXNlIGluc3BlY3Rpb24gZnVuY3Rpb24gZm9yIHByZWZpbHRlcnMgYW5kIHRyYW5zcG9ydHMKZnVuY3Rpb24gaW5zcGVjdFByZWZpbHRlcnNPclRyYW5zcG9ydHMoIHN0cnVjdHVyZSwgb3B0aW9ucywgb3JpZ2luYWxPcHRpb25zLCBqcVhIUiApIHsKCgl2YXIgaW5zcGVjdGVkID0ge30sCgkJc2Vla2luZ1RyYW5zcG9ydCA9ICggc3RydWN0dXJlID09PSB0cmFuc3BvcnRzICk7CgoJZnVuY3Rpb24gaW5zcGVjdCggZGF0YVR5cGUgKSB7CgkJdmFyIHNlbGVjdGVkOwoJCWluc3BlY3RlZFsgZGF0YVR5cGUgXSA9IHRydWU7CgkJalF1ZXJ5LmVhY2goIHN0cnVjdHVyZVsgZGF0YVR5cGUgXSB8fCBbXSwgZnVuY3Rpb24oIF8sIHByZWZpbHRlck9yRmFjdG9yeSApIHsKCQkJdmFyIGRhdGFUeXBlT3JUcmFuc3BvcnQgPSBwcmVmaWx0ZXJPckZhY3RvcnkoIG9wdGlvbnMsIG9yaWdpbmFsT3B0aW9ucywganFYSFIgKTsKCQkJaWYgKCB0eXBlb2YgZGF0YVR5cGVPclRyYW5zcG9ydCA9PT0gInN0cmluZyIgJiYKCQkJCSFzZWVraW5nVHJhbnNwb3J0ICYmICFpbnNwZWN0ZWRbIGRhdGFUeXBlT3JUcmFuc3BvcnQgXSApIHsKCgkJCQlvcHRpb25zLmRhdGFUeXBlcy51bnNoaWZ0KCBkYXRhVHlwZU9yVHJhbnNwb3J0ICk7CgkJCQlpbnNwZWN0KCBkYXRhVHlwZU9yVHJhbnNwb3J0ICk7CgkJCQlyZXR1cm4gZmFsc2U7CgkJCX0gZWxzZSBpZiAoIHNlZWtpbmdUcmFuc3BvcnQgKSB7CgkJCQlyZXR1cm4gISggc2VsZWN0ZWQgPSBkYXRhVHlwZU9yVHJhbnNwb3J0ICk7CgkJCX0KCQl9ICk7CgkJcmV0dXJuIHNlbGVjdGVkOwoJfQoKCXJldHVybiBpbnNwZWN0KCBvcHRpb25zLmRhdGFUeXBlc1sgMCBdICkgfHwgIWluc3BlY3RlZFsgIioiIF0gJiYgaW5zcGVjdCggIioiICk7Cn0KCi8vIEEgc3BlY2lhbCBleHRlbmQgZm9yIGFqYXggb3B0aW9ucwovLyB0aGF0IHRha2VzICJmbGF0IiBvcHRpb25zIChub3QgdG8gYmUgZGVlcCBleHRlbmRlZCkKLy8gRml4ZXMgIzk4ODcKZnVuY3Rpb24gYWpheEV4dGVuZCggdGFyZ2V0LCBzcmMgKSB7Cgl2YXIga2V5LCBkZWVwLAoJCWZsYXRPcHRpb25zID0galF1ZXJ5LmFqYXhTZXR0aW5ncy5mbGF0T3B0aW9ucyB8fCB7fTsKCglmb3IgKCBrZXkgaW4gc3JjICkgewoJCWlmICggc3JjWyBrZXkgXSAhPT0gdW5kZWZpbmVkICkgewoJCQkoIGZsYXRPcHRpb25zWyBrZXkgXSA/IHRhcmdldCA6ICggZGVlcCB8fCAoIGRlZXAgPSB7fSApICkgKVsga2V5IF0gPSBzcmNbIGtleSBdOwoJCX0KCX0KCWlmICggZGVlcCApIHsKCQlqUXVlcnkuZXh0ZW5kKCB0cnVlLCB0YXJnZXQsIGRlZXAgKTsKCX0KCglyZXR1cm4gdGFyZ2V0Owp9CgovKiBIYW5kbGVzIHJlc3BvbnNlcyB0byBhbiBhamF4IHJlcXVlc3Q6CiAqIC0gZmluZHMgdGhlIHJpZ2h0IGRhdGFUeXBlIChtZWRpYXRlcyBiZXR3ZWVuIGNvbnRlbnQtdHlwZSBhbmQgZXhwZWN0ZWQgZGF0YVR5cGUpCiAqIC0gcmV0dXJucyB0aGUgY29ycmVzcG9uZGluZyByZXNwb25zZQogKi8KZnVuY3Rpb24gYWpheEhhbmRsZVJlc3BvbnNlcyggcywganFYSFIsIHJlc3BvbnNlcyApIHsKCgl2YXIgY3QsIHR5cGUsIGZpbmFsRGF0YVR5cGUsIGZpcnN0RGF0YVR5cGUsCgkJY29udGVudHMgPSBzLmNvbnRlbnRzLAoJCWRhdGFUeXBlcyA9IHMuZGF0YVR5cGVzOwoKCS8vIFJlbW92ZSBhdXRvIGRhdGFUeXBlIGFuZCBnZXQgY29udGVudC10eXBlIGluIHRoZSBwcm9jZXNzCgl3aGlsZSAoIGRhdGFUeXBlc1sgMCBdID09PSAiKiIgKSB7CgkJZGF0YVR5cGVzLnNoaWZ0KCk7CgkJaWYgKCBjdCA9PT0gdW5kZWZpbmVkICkgewoJCQljdCA9IHMubWltZVR5cGUgfHwganFYSFIuZ2V0UmVzcG9uc2VIZWFkZXIoICJDb250ZW50LVR5cGUiICk7CgkJfQoJfQoKCS8vIENoZWNrIGlmIHdlJ3JlIGRlYWxpbmcgd2l0aCBhIGtub3duIGNvbnRlbnQtdHlwZQoJaWYgKCBjdCApIHsKCQlmb3IgKCB0eXBlIGluIGNvbnRlbnRzICkgewoJCQlpZiAoIGNvbnRlbnRzWyB0eXBlIF0gJiYgY29udGVudHNbIHR5cGUgXS50ZXN0KCBjdCApICkgewoJCQkJZGF0YVR5cGVzLnVuc2hpZnQoIHR5cGUgKTsKCQkJCWJyZWFrOwoJCQl9CgkJfQoJfQoKCS8vIENoZWNrIHRvIHNlZSBpZiB3ZSBoYXZlIGEgcmVzcG9uc2UgZm9yIHRoZSBleHBlY3RlZCBkYXRhVHlwZQoJaWYgKCBkYXRhVHlwZXNbIDAgXSBpbiByZXNwb25zZXMgKSB7CgkJZmluYWxEYXRhVHlwZSA9IGRhdGFUeXBlc1sgMCBdOwoJfSBlbHNlIHsKCgkJLy8gVHJ5IGNvbnZlcnRpYmxlIGRhdGFUeXBlcwoJCWZvciAoIHR5cGUgaW4gcmVzcG9uc2VzICkgewoJCQlpZiAoICFkYXRhVHlwZXNbIDAgXSB8fCBzLmNvbnZlcnRlcnNbIHR5cGUgKyAiICIgKyBkYXRhVHlwZXNbIDAgXSBdICkgewoJCQkJZmluYWxEYXRhVHlwZSA9IHR5cGU7CgkJCQlicmVhazsKCQkJfQoJCQlpZiAoICFmaXJzdERhdGFUeXBlICkgewoJCQkJZmlyc3REYXRhVHlwZSA9IHR5cGU7CgkJCX0KCQl9CgoJCS8vIE9yIGp1c3QgdXNlIGZpcnN0IG9uZQoJCWZpbmFsRGF0YVR5cGUgPSBmaW5hbERhdGFUeXBlIHx8IGZpcnN0RGF0YVR5cGU7Cgl9CgoJLy8gSWYgd2UgZm91bmQgYSBkYXRhVHlwZQoJLy8gV2UgYWRkIHRoZSBkYXRhVHlwZSB0byB0aGUgbGlzdCBpZiBuZWVkZWQKCS8vIGFuZCByZXR1cm4gdGhlIGNvcnJlc3BvbmRpbmcgcmVzcG9uc2UKCWlmICggZmluYWxEYXRhVHlwZSApIHsKCQlpZiAoIGZpbmFsRGF0YVR5cGUgIT09IGRhdGFUeXBlc1sgMCBdICkgewoJCQlkYXRhVHlwZXMudW5zaGlmdCggZmluYWxEYXRhVHlwZSApOwoJCX0KCQlyZXR1cm4gcmVzcG9uc2VzWyBmaW5hbERhdGFUeXBlIF07Cgl9Cn0KCi8qIENoYWluIGNvbnZlcnNpb25zIGdpdmVuIHRoZSByZXF1ZXN0IGFuZCB0aGUgb3JpZ2luYWwgcmVzcG9uc2UKICogQWxzbyBzZXRzIHRoZSByZXNwb25zZVhYWCBmaWVsZHMgb24gdGhlIGpxWEhSIGluc3RhbmNlCiAqLwpmdW5jdGlvbiBhamF4Q29udmVydCggcywgcmVzcG9uc2UsIGpxWEhSLCBpc1N1Y2Nlc3MgKSB7Cgl2YXIgY29udjIsIGN1cnJlbnQsIGNvbnYsIHRtcCwgcHJldiwKCQljb252ZXJ0ZXJzID0ge30sCgoJCS8vIFdvcmsgd2l0aCBhIGNvcHkgb2YgZGF0YVR5cGVzIGluIGNhc2Ugd2UgbmVlZCB0byBtb2RpZnkgaXQgZm9yIGNvbnZlcnNpb24KCQlkYXRhVHlwZXMgPSBzLmRhdGFUeXBlcy5zbGljZSgpOwoKCS8vIENyZWF0ZSBjb252ZXJ0ZXJzIG1hcCB3aXRoIGxvd2VyY2FzZWQga2V5cwoJaWYgKCBkYXRhVHlwZXNbIDEgXSApIHsKCQlmb3IgKCBjb252IGluIHMuY29udmVydGVycyApIHsKCQkJY29udmVydGVyc1sgY29udi50b0xvd2VyQ2FzZSgpIF0gPSBzLmNvbnZlcnRlcnNbIGNvbnYgXTsKCQl9Cgl9CgoJY3VycmVudCA9IGRhdGFUeXBlcy5zaGlmdCgpOwoKCS8vIENvbnZlcnQgdG8gZWFjaCBzZXF1ZW50aWFsIGRhdGFUeXBlCgl3aGlsZSAoIGN1cnJlbnQgKSB7CgoJCWlmICggcy5yZXNwb25zZUZpZWxkc1sgY3VycmVudCBdICkgewoJCQlqcVhIUlsgcy5yZXNwb25zZUZpZWxkc1sgY3VycmVudCBdIF0gPSByZXNwb25zZTsKCQl9CgoJCS8vIEFwcGx5IHRoZSBkYXRhRmlsdGVyIGlmIHByb3ZpZGVkCgkJaWYgKCAhcHJldiAmJiBpc1N1Y2Nlc3MgJiYgcy5kYXRhRmlsdGVyICkgewoJCQlyZXNwb25zZSA9IHMuZGF0YUZpbHRlciggcmVzcG9uc2UsIHMuZGF0YVR5cGUgKTsKCQl9CgoJCXByZXYgPSBjdXJyZW50OwoJCWN1cnJlbnQgPSBkYXRhVHlwZXMuc2hpZnQoKTsKCgkJaWYgKCBjdXJyZW50ICkgewoKCQkJLy8gVGhlcmUncyBvbmx5IHdvcmsgdG8gZG8gaWYgY3VycmVudCBkYXRhVHlwZSBpcyBub24tYXV0bwoJCQlpZiAoIGN1cnJlbnQgPT09ICIqIiApIHsKCgkJCQljdXJyZW50ID0gcHJldjsKCgkJCS8vIENvbnZlcnQgcmVzcG9uc2UgaWYgcHJldiBkYXRhVHlwZSBpcyBub24tYXV0byBhbmQgZGlmZmVycyBmcm9tIGN1cnJlbnQKCQkJfSBlbHNlIGlmICggcHJldiAhPT0gIioiICYmIHByZXYgIT09IGN1cnJlbnQgKSB7CgoJCQkJLy8gU2VlayBhIGRpcmVjdCBjb252ZXJ0ZXIKCQkJCWNvbnYgPSBjb252ZXJ0ZXJzWyBwcmV2ICsgIiAiICsgY3VycmVudCBdIHx8IGNvbnZlcnRlcnNbICIqICIgKyBjdXJyZW50IF07CgoJCQkJLy8gSWYgbm9uZSBmb3VuZCwgc2VlayBhIHBhaXIKCQkJCWlmICggIWNvbnYgKSB7CgkJCQkJZm9yICggY29udjIgaW4gY29udmVydGVycyApIHsKCgkJCQkJCS8vIElmIGNvbnYyIG91dHB1dHMgY3VycmVudAoJCQkJCQl0bXAgPSBjb252Mi5zcGxpdCggIiAiICk7CgkJCQkJCWlmICggdG1wWyAxIF0gPT09IGN1cnJlbnQgKSB7CgoJCQkJCQkJLy8gSWYgcHJldiBjYW4gYmUgY29udmVydGVkIHRvIGFjY2VwdGVkIGlucHV0CgkJCQkJCQljb252ID0gY29udmVydGVyc1sgcHJldiArICIgIiArIHRtcFsgMCBdIF0gfHwKCQkJCQkJCQljb252ZXJ0ZXJzWyAiKiAiICsgdG1wWyAwIF0gXTsKCQkJCQkJCWlmICggY29udiApIHsKCgkJCQkJCQkJLy8gQ29uZGVuc2UgZXF1aXZhbGVuY2UgY29udmVydGVycwoJCQkJCQkJCWlmICggY29udiA9PT0gdHJ1ZSApIHsKCQkJCQkJCQkJY29udiA9IGNvbnZlcnRlcnNbIGNvbnYyIF07CgoJCQkJCQkJCS8vIE90aGVyd2lzZSwgaW5zZXJ0IHRoZSBpbnRlcm1lZGlhdGUgZGF0YVR5cGUKCQkJCQkJCQl9IGVsc2UgaWYgKCBjb252ZXJ0ZXJzWyBjb252MiBdICE9PSB0cnVlICkgewoJCQkJCQkJCQljdXJyZW50ID0gdG1wWyAwIF07CgkJCQkJCQkJCWRhdGFUeXBlcy51bnNoaWZ0KCB0bXBbIDEgXSApOwoJCQkJCQkJCX0KCQkJCQkJCQlicmVhazsKCQkJCQkJCX0KCQkJCQkJfQoJCQkJCX0KCQkJCX0KCgkJCQkvLyBBcHBseSBjb252ZXJ0ZXIgKGlmIG5vdCBhbiBlcXVpdmFsZW5jZSkKCQkJCWlmICggY29udiAhPT0gdHJ1ZSApIHsKCgkJCQkJLy8gVW5sZXNzIGVycm9ycyBhcmUgYWxsb3dlZCB0byBidWJibGUsIGNhdGNoIGFuZCByZXR1cm4gdGhlbQoJCQkJCWlmICggY29udiAmJiBzLnRocm93cyApIHsKCQkJCQkJcmVzcG9uc2UgPSBjb252KCByZXNwb25zZSApOwoJCQkJCX0gZWxzZSB7CgkJCQkJCXRyeSB7CgkJCQkJCQlyZXNwb25zZSA9IGNvbnYoIHJlc3BvbnNlICk7CgkJCQkJCX0gY2F0Y2ggKCBlICkgewoJCQkJCQkJcmV0dXJuIHsKCQkJCQkJCQlzdGF0ZTogInBhcnNlcmVycm9yIiwKCQkJCQkJCQllcnJvcjogY29udiA/IGUgOiAiTm8gY29udmVyc2lvbiBmcm9tICIgKyBwcmV2ICsgIiB0byAiICsgY3VycmVudAoJCQkJCQkJfTsKCQkJCQkJfQoJCQkJCX0KCQkJCX0KCQkJfQoJCX0KCX0KCglyZXR1cm4geyBzdGF0ZTogInN1Y2Nlc3MiLCBkYXRhOiByZXNwb25zZSB9Owp9CgpqUXVlcnkuZXh0ZW5kKCB7CgoJLy8gQ291bnRlciBmb3IgaG9sZGluZyB0aGUgbnVtYmVyIG9mIGFjdGl2ZSBxdWVyaWVzCglhY3RpdmU6IDAsCgoJLy8gTGFzdC1Nb2RpZmllZCBoZWFkZXIgY2FjaGUgZm9yIG5leHQgcmVxdWVzdAoJbGFzdE1vZGlmaWVkOiB7fSwKCWV0YWc6IHt9LAoKCWFqYXhTZXR0aW5nczogewoJCXVybDogbG9jYXRpb24uaHJlZiwKCQl0eXBlOiAiR0VUIiwKCQlpc0xvY2FsOiBybG9jYWxQcm90b2NvbC50ZXN0KCBsb2NhdGlvbi5wcm90b2NvbCApLAoJCWdsb2JhbDogdHJ1ZSwKCQlwcm9jZXNzRGF0YTogdHJ1ZSwKCQlhc3luYzogdHJ1ZSwKCQljb250ZW50VHlwZTogImFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZDsgY2hhcnNldD1VVEYtOCIsCgoJCS8qCgkJdGltZW91dDogMCwKCQlkYXRhOiBudWxsLAoJCWRhdGFUeXBlOiBudWxsLAoJCXVzZXJuYW1lOiBudWxsLAoJCXBhc3N3b3JkOiBudWxsLAoJCWNhY2hlOiBudWxsLAoJCXRocm93czogZmFsc2UsCgkJdHJhZGl0aW9uYWw6IGZhbHNlLAoJCWhlYWRlcnM6IHt9LAoJCSovCgoJCWFjY2VwdHM6IHsKCQkJIioiOiBhbGxUeXBlcywKCQkJdGV4dDogInRleHQvcGxhaW4iLAoJCQlodG1sOiAidGV4dC9odG1sIiwKCQkJeG1sOiAiYXBwbGljYXRpb24veG1sLCB0ZXh0L3htbCIsCgkJCWpzb246ICJhcHBsaWNhdGlvbi9qc29uLCB0ZXh0L2phdmFzY3JpcHQiCgkJfSwKCgkJY29udGVudHM6IHsKCQkJeG1sOiAvXGJ4bWxcYi8sCgkJCWh0bWw6IC9cYmh0bWwvLAoJCQlqc29uOiAvXGJqc29uXGIvCgkJfSwKCgkJcmVzcG9uc2VGaWVsZHM6IHsKCQkJeG1sOiAicmVzcG9uc2VYTUwiLAoJCQl0ZXh0OiAicmVzcG9uc2VUZXh0IiwKCQkJanNvbjogInJlc3BvbnNlSlNPTiIKCQl9LAoKCQkvLyBEYXRhIGNvbnZlcnRlcnMKCQkvLyBLZXlzIHNlcGFyYXRlIHNvdXJjZSAob3IgY2F0Y2hhbGwgIioiKSBhbmQgZGVzdGluYXRpb24gdHlwZXMgd2l0aCBhIHNpbmdsZSBzcGFjZQoJCWNvbnZlcnRlcnM6IHsKCgkJCS8vIENvbnZlcnQgYW55dGhpbmcgdG8gdGV4dAoJCQkiKiB0ZXh0IjogU3RyaW5nLAoKCQkJLy8gVGV4dCB0byBodG1sICh0cnVlID0gbm8gdHJhbnNmb3JtYXRpb24pCgkJCSJ0ZXh0IGh0bWwiOiB0cnVlLAoKCQkJLy8gRXZhbHVhdGUgdGV4dCBhcyBhIGpzb24gZXhwcmVzc2lvbgoJCQkidGV4dCBqc29uIjogSlNPTi5wYXJzZSwKCgkJCS8vIFBhcnNlIHRleHQgYXMgeG1sCgkJCSJ0ZXh0IHhtbCI6IGpRdWVyeS5wYXJzZVhNTAoJCX0sCgoJCS8vIEZvciBvcHRpb25zIHRoYXQgc2hvdWxkbid0IGJlIGRlZXAgZXh0ZW5kZWQ6CgkJLy8geW91IGNhbiBhZGQgeW91ciBvd24gY3VzdG9tIG9wdGlvbnMgaGVyZSBpZgoJCS8vIGFuZCB3aGVuIHlvdSBjcmVhdGUgb25lIHRoYXQgc2hvdWxkbid0IGJlCgkJLy8gZGVlcCBleHRlbmRlZCAoc2VlIGFqYXhFeHRlbmQpCgkJZmxhdE9wdGlvbnM6IHsKCQkJdXJsOiB0cnVlLAoJCQljb250ZXh0OiB0cnVlCgkJfQoJfSwKCgkvLyBDcmVhdGVzIGEgZnVsbCBmbGVkZ2VkIHNldHRpbmdzIG9iamVjdCBpbnRvIHRhcmdldAoJLy8gd2l0aCBib3RoIGFqYXhTZXR0aW5ncyBhbmQgc2V0dGluZ3MgZmllbGRzLgoJLy8gSWYgdGFyZ2V0IGlzIG9taXR0ZWQsIHdyaXRlcyBpbnRvIGFqYXhTZXR0aW5ncy4KCWFqYXhTZXR1cDogZnVuY3Rpb24oIHRhcmdldCwgc2V0dGluZ3MgKSB7CgkJcmV0dXJuIHNldHRpbmdzID8KCgkJCS8vIEJ1aWxkaW5nIGEgc2V0dGluZ3Mgb2JqZWN0CgkJCWFqYXhFeHRlbmQoIGFqYXhFeHRlbmQoIHRhcmdldCwgalF1ZXJ5LmFqYXhTZXR0aW5ncyApLCBzZXR0aW5ncyApIDoKCgkJCS8vIEV4dGVuZGluZyBhamF4U2V0dGluZ3MKCQkJYWpheEV4dGVuZCggalF1ZXJ5LmFqYXhTZXR0aW5ncywgdGFyZ2V0ICk7Cgl9LAoKCWFqYXhQcmVmaWx0ZXI6IGFkZFRvUHJlZmlsdGVyc09yVHJhbnNwb3J0cyggcHJlZmlsdGVycyApLAoJYWpheFRyYW5zcG9ydDogYWRkVG9QcmVmaWx0ZXJzT3JUcmFuc3BvcnRzKCB0cmFuc3BvcnRzICksCgoJLy8gTWFpbiBtZXRob2QKCWFqYXg6IGZ1bmN0aW9uKCB1cmwsIG9wdGlvbnMgKSB7CgoJCS8vIElmIHVybCBpcyBhbiBvYmplY3QsIHNpbXVsYXRlIHByZS0xLjUgc2lnbmF0dXJlCgkJaWYgKCB0eXBlb2YgdXJsID09PSAib2JqZWN0IiApIHsKCQkJb3B0aW9ucyA9IHVybDsKCQkJdXJsID0gdW5kZWZpbmVkOwoJCX0KCgkJLy8gRm9yY2Ugb3B0aW9ucyB0byBiZSBhbiBvYmplY3QKCQlvcHRpb25zID0gb3B0aW9ucyB8fCB7fTsKCgkJdmFyIHRyYW5zcG9ydCwKCgkJCS8vIFVSTCB3aXRob3V0IGFudGktY2FjaGUgcGFyYW0KCQkJY2FjaGVVUkwsCgoJCQkvLyBSZXNwb25zZSBoZWFkZXJzCgkJCXJlc3BvbnNlSGVhZGVyc1N0cmluZywKCQkJcmVzcG9uc2VIZWFkZXJzLAoKCQkJLy8gdGltZW91dCBoYW5kbGUKCQkJdGltZW91dFRpbWVyLAoKCQkJLy8gVXJsIGNsZWFudXAgdmFyCgkJCXVybEFuY2hvciwKCgkJCS8vIFJlcXVlc3Qgc3RhdGUgKGJlY29tZXMgZmFsc2UgdXBvbiBzZW5kIGFuZCB0cnVlIHVwb24gY29tcGxldGlvbikKCQkJY29tcGxldGVkLAoKCQkJLy8gVG8ga25vdyBpZiBnbG9iYWwgZXZlbnRzIGFyZSB0byBiZSBkaXNwYXRjaGVkCgkJCWZpcmVHbG9iYWxzLAoKCQkJLy8gTG9vcCB2YXJpYWJsZQoJCQlpLAoKCQkJLy8gdW5jYWNoZWQgcGFydCBvZiB0aGUgdXJsCgkJCXVuY2FjaGVkLAoKCQkJLy8gQ3JlYXRlIHRoZSBmaW5hbCBvcHRpb25zIG9iamVjdAoJCQlzID0galF1ZXJ5LmFqYXhTZXR1cCgge30sIG9wdGlvbnMgKSwKCgkJCS8vIENhbGxiYWNrcyBjb250ZXh0CgkJCWNhbGxiYWNrQ29udGV4dCA9IHMuY29udGV4dCB8fCBzLAoKCQkJLy8gQ29udGV4dCBmb3IgZ2xvYmFsIGV2ZW50cyBpcyBjYWxsYmFja0NvbnRleHQgaWYgaXQgaXMgYSBET00gbm9kZSBvciBqUXVlcnkgY29sbGVjdGlvbgoJCQlnbG9iYWxFdmVudENvbnRleHQgPSBzLmNvbnRleHQgJiYKCQkJCSggY2FsbGJhY2tDb250ZXh0Lm5vZGVUeXBlIHx8IGNhbGxiYWNrQ29udGV4dC5qcXVlcnkgKSA/CgkJCQkJalF1ZXJ5KCBjYWxsYmFja0NvbnRleHQgKSA6CgkJCQkJalF1ZXJ5LmV2ZW50LAoKCQkJLy8gRGVmZXJyZWRzCgkJCWRlZmVycmVkID0galF1ZXJ5LkRlZmVycmVkKCksCgkJCWNvbXBsZXRlRGVmZXJyZWQgPSBqUXVlcnkuQ2FsbGJhY2tzKCAib25jZSBtZW1vcnkiICksCgoJCQkvLyBTdGF0dXMtZGVwZW5kZW50IGNhbGxiYWNrcwoJCQlzdGF0dXNDb2RlID0gcy5zdGF0dXNDb2RlIHx8IHt9LAoKCQkJLy8gSGVhZGVycyAodGhleSBhcmUgc2VudCBhbGwgYXQgb25jZSkKCQkJcmVxdWVzdEhlYWRlcnMgPSB7fSwKCQkJcmVxdWVzdEhlYWRlcnNOYW1lcyA9IHt9LAoKCQkJLy8gRGVmYXVsdCBhYm9ydCBtZXNzYWdlCgkJCXN0ckFib3J0ID0gImNhbmNlbGVkIiwKCgkJCS8vIEZha2UgeGhyCgkJCWpxWEhSID0gewoJCQkJcmVhZHlTdGF0ZTogMCwKCgkJCQkvLyBCdWlsZHMgaGVhZGVycyBoYXNodGFibGUgaWYgbmVlZGVkCgkJCQlnZXRSZXNwb25zZUhlYWRlcjogZnVuY3Rpb24oIGtleSApIHsKCQkJCQl2YXIgbWF0Y2g7CgkJCQkJaWYgKCBjb21wbGV0ZWQgKSB7CgkJCQkJCWlmICggIXJlc3BvbnNlSGVhZGVycyApIHsKCQkJCQkJCXJlc3BvbnNlSGVhZGVycyA9IHt9OwoJCQkJCQkJd2hpbGUgKCAoIG1hdGNoID0gcmhlYWRlcnMuZXhlYyggcmVzcG9uc2VIZWFkZXJzU3RyaW5nICkgKSApIHsKCQkJCQkJCQlyZXNwb25zZUhlYWRlcnNbIG1hdGNoWyAxIF0udG9Mb3dlckNhc2UoKSBdID0gbWF0Y2hbIDIgXTsKCQkJCQkJCX0KCQkJCQkJfQoJCQkJCQltYXRjaCA9IHJlc3BvbnNlSGVhZGVyc1sga2V5LnRvTG93ZXJDYXNlKCkgXTsKCQkJCQl9CgkJCQkJcmV0dXJuIG1hdGNoID09IG51bGwgPyBudWxsIDogbWF0Y2g7CgkJCQl9LAoKCQkJCS8vIFJhdyBzdHJpbmcKCQkJCWdldEFsbFJlc3BvbnNlSGVhZGVyczogZnVuY3Rpb24oKSB7CgkJCQkJcmV0dXJuIGNvbXBsZXRlZCA/IHJlc3BvbnNlSGVhZGVyc1N0cmluZyA6IG51bGw7CgkJCQl9LAoKCQkJCS8vIENhY2hlcyB0aGUgaGVhZGVyCgkJCQlzZXRSZXF1ZXN0SGVhZGVyOiBmdW5jdGlvbiggbmFtZSwgdmFsdWUgKSB7CgkJCQkJaWYgKCBjb21wbGV0ZWQgPT0gbnVsbCApIHsKCQkJCQkJbmFtZSA9IHJlcXVlc3RIZWFkZXJzTmFtZXNbIG5hbWUudG9Mb3dlckNhc2UoKSBdID0KCQkJCQkJCXJlcXVlc3RIZWFkZXJzTmFtZXNbIG5hbWUudG9Mb3dlckNhc2UoKSBdIHx8IG5hbWU7CgkJCQkJCXJlcXVlc3RIZWFkZXJzWyBuYW1lIF0gPSB2YWx1ZTsKCQkJCQl9CgkJCQkJcmV0dXJuIHRoaXM7CgkJCQl9LAoKCQkJCS8vIE92ZXJyaWRlcyByZXNwb25zZSBjb250ZW50LXR5cGUgaGVhZGVyCgkJCQlvdmVycmlkZU1pbWVUeXBlOiBmdW5jdGlvbiggdHlwZSApIHsKCQkJCQlpZiAoIGNvbXBsZXRlZCA9PSBudWxsICkgewoJCQkJCQlzLm1pbWVUeXBlID0gdHlwZTsKCQkJCQl9CgkJCQkJcmV0dXJuIHRoaXM7CgkJCQl9LAoKCQkJCS8vIFN0YXR1cy1kZXBlbmRlbnQgY2FsbGJhY2tzCgkJCQlzdGF0dXNDb2RlOiBmdW5jdGlvbiggbWFwICkgewoJCQkJCXZhciBjb2RlOwoJCQkJCWlmICggbWFwICkgewoJCQkJCQlpZiAoIGNvbXBsZXRlZCApIHsKCgkJCQkJCQkvLyBFeGVjdXRlIHRoZSBhcHByb3ByaWF0ZSBjYWxsYmFja3MKCQkJCQkJCWpxWEhSLmFsd2F5cyggbWFwWyBqcVhIUi5zdGF0dXMgXSApOwoJCQkJCQl9IGVsc2UgewoKCQkJCQkJCS8vIExhenktYWRkIHRoZSBuZXcgY2FsbGJhY2tzIGluIGEgd2F5IHRoYXQgcHJlc2VydmVzIG9sZCBvbmVzCgkJCQkJCQlmb3IgKCBjb2RlIGluIG1hcCApIHsKCQkJCQkJCQlzdGF0dXNDb2RlWyBjb2RlIF0gPSBbIHN0YXR1c0NvZGVbIGNvZGUgXSwgbWFwWyBjb2RlIF0gXTsKCQkJCQkJCX0KCQkJCQkJfQoJCQkJCX0KCQkJCQlyZXR1cm4gdGhpczsKCQkJCX0sCgoJCQkJLy8gQ2FuY2VsIHRoZSByZXF1ZXN0CgkJCQlhYm9ydDogZnVuY3Rpb24oIHN0YXR1c1RleHQgKSB7CgkJCQkJdmFyIGZpbmFsVGV4dCA9IHN0YXR1c1RleHQgfHwgc3RyQWJvcnQ7CgkJCQkJaWYgKCB0cmFuc3BvcnQgKSB7CgkJCQkJCXRyYW5zcG9ydC5hYm9ydCggZmluYWxUZXh0ICk7CgkJCQkJfQoJCQkJCWRvbmUoIDAsIGZpbmFsVGV4dCApOwoJCQkJCXJldHVybiB0aGlzOwoJCQkJfQoJCQl9OwoKCQkvLyBBdHRhY2ggZGVmZXJyZWRzCgkJZGVmZXJyZWQucHJvbWlzZSgganFYSFIgKTsKCgkJLy8gQWRkIHByb3RvY29sIGlmIG5vdCBwcm92aWRlZCAocHJlZmlsdGVycyBtaWdodCBleHBlY3QgaXQpCgkJLy8gSGFuZGxlIGZhbHN5IHVybCBpbiB0aGUgc2V0dGluZ3Mgb2JqZWN0ICgjMTAwOTM6IGNvbnNpc3RlbmN5IHdpdGggb2xkIHNpZ25hdHVyZSkKCQkvLyBXZSBhbHNvIHVzZSB0aGUgdXJsIHBhcmFtZXRlciBpZiBhdmFpbGFibGUKCQlzLnVybCA9ICggKCB1cmwgfHwgcy51cmwgfHwgbG9jYXRpb24uaHJlZiApICsgIiIgKQoJCQkucmVwbGFjZSggcnByb3RvY29sLCBsb2NhdGlvbi5wcm90b2NvbCArICIvLyIgKTsKCgkJLy8gQWxpYXMgbWV0aG9kIG9wdGlvbiB0byB0eXBlIGFzIHBlciB0aWNrZXQgIzEyMDA0CgkJcy50eXBlID0gb3B0aW9ucy5tZXRob2QgfHwgb3B0aW9ucy50eXBlIHx8IHMubWV0aG9kIHx8IHMudHlwZTsKCgkJLy8gRXh0cmFjdCBkYXRhVHlwZXMgbGlzdAoJCXMuZGF0YVR5cGVzID0gKCBzLmRhdGFUeXBlIHx8ICIqIiApLnRvTG93ZXJDYXNlKCkubWF0Y2goIHJub3RodG1sd2hpdGUgKSB8fCBbICIiIF07CgoJCS8vIEEgY3Jvc3MtZG9tYWluIHJlcXVlc3QgaXMgaW4gb3JkZXIgd2hlbiB0aGUgb3JpZ2luIGRvZXNuJ3QgbWF0Y2ggdGhlIGN1cnJlbnQgb3JpZ2luLgoJCWlmICggcy5jcm9zc0RvbWFpbiA9PSBudWxsICkgewoJCQl1cmxBbmNob3IgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCAiYSIgKTsKCgkJCS8vIFN1cHBvcnQ6IElFIDw9OCAtIDExLCBFZGdlIDEyIC0gMTUKCQkJLy8gSUUgdGhyb3dzIGV4Y2VwdGlvbiBvbiBhY2Nlc3NpbmcgdGhlIGhyZWYgcHJvcGVydHkgaWYgdXJsIGlzIG1hbGZvcm1lZCwKCQkJLy8gZS5nLiBodHRwOi8vZXhhbXBsZS5jb206ODB4LwoJCQl0cnkgewoJCQkJdXJsQW5jaG9yLmhyZWYgPSBzLnVybDsKCgkJCQkvLyBTdXBwb3J0OiBJRSA8PTggLSAxMSBvbmx5CgkJCQkvLyBBbmNob3IncyBob3N0IHByb3BlcnR5IGlzbid0IGNvcnJlY3RseSBzZXQgd2hlbiBzLnVybCBpcyByZWxhdGl2ZQoJCQkJdXJsQW5jaG9yLmhyZWYgPSB1cmxBbmNob3IuaHJlZjsKCQkJCXMuY3Jvc3NEb21haW4gPSBvcmlnaW5BbmNob3IucHJvdG9jb2wgKyAiLy8iICsgb3JpZ2luQW5jaG9yLmhvc3QgIT09CgkJCQkJdXJsQW5jaG9yLnByb3RvY29sICsgIi8vIiArIHVybEFuY2hvci5ob3N0OwoJCQl9IGNhdGNoICggZSApIHsKCgkJCQkvLyBJZiB0aGVyZSBpcyBhbiBlcnJvciBwYXJzaW5nIHRoZSBVUkwsIGFzc3VtZSBpdCBpcyBjcm9zc0RvbWFpbiwKCQkJCS8vIGl0IGNhbiBiZSByZWplY3RlZCBieSB0aGUgdHJhbnNwb3J0IGlmIGl0IGlzIGludmFsaWQKCQkJCXMuY3Jvc3NEb21haW4gPSB0cnVlOwoJCQl9CgkJfQoKCQkvLyBDb252ZXJ0IGRhdGEgaWYgbm90IGFscmVhZHkgYSBzdHJpbmcKCQlpZiAoIHMuZGF0YSAmJiBzLnByb2Nlc3NEYXRhICYmIHR5cGVvZiBzLmRhdGEgIT09ICJzdHJpbmciICkgewoJCQlzLmRhdGEgPSBqUXVlcnkucGFyYW0oIHMuZGF0YSwgcy50cmFkaXRpb25hbCApOwoJCX0KCgkJLy8gQXBwbHkgcHJlZmlsdGVycwoJCWluc3BlY3RQcmVmaWx0ZXJzT3JUcmFuc3BvcnRzKCBwcmVmaWx0ZXJzLCBzLCBvcHRpb25zLCBqcVhIUiApOwoKCQkvLyBJZiByZXF1ZXN0IHdhcyBhYm9ydGVkIGluc2lkZSBhIHByZWZpbHRlciwgc3RvcCB0aGVyZQoJCWlmICggY29tcGxldGVkICkgewoJCQlyZXR1cm4ganFYSFI7CgkJfQoKCQkvLyBXZSBjYW4gZmlyZSBnbG9iYWwgZXZlbnRzIGFzIG9mIG5vdyBpZiBhc2tlZCB0bwoJCS8vIERvbid0IGZpcmUgZXZlbnRzIGlmIGpRdWVyeS5ldmVudCBpcyB1bmRlZmluZWQgaW4gYW4gQU1ELXVzYWdlIHNjZW5hcmlvICgjMTUxMTgpCgkJZmlyZUdsb2JhbHMgPSBqUXVlcnkuZXZlbnQgJiYgcy5nbG9iYWw7CgoJCS8vIFdhdGNoIGZvciBhIG5ldyBzZXQgb2YgcmVxdWVzdHMKCQlpZiAoIGZpcmVHbG9iYWxzICYmIGpRdWVyeS5hY3RpdmUrKyA9PT0gMCApIHsKCQkJalF1ZXJ5LmV2ZW50LnRyaWdnZXIoICJhamF4U3RhcnQiICk7CgkJfQoKCQkvLyBVcHBlcmNhc2UgdGhlIHR5cGUKCQlzLnR5cGUgPSBzLnR5cGUudG9VcHBlckNhc2UoKTsKCgkJLy8gRGV0ZXJtaW5lIGlmIHJlcXVlc3QgaGFzIGNvbnRlbnQKCQlzLmhhc0NvbnRlbnQgPSAhcm5vQ29udGVudC50ZXN0KCBzLnR5cGUgKTsKCgkJLy8gU2F2ZSB0aGUgVVJMIGluIGNhc2Ugd2UncmUgdG95aW5nIHdpdGggdGhlIElmLU1vZGlmaWVkLVNpbmNlCgkJLy8gYW5kL29yIElmLU5vbmUtTWF0Y2ggaGVhZGVyIGxhdGVyIG9uCgkJLy8gUmVtb3ZlIGhhc2ggdG8gc2ltcGxpZnkgdXJsIG1hbmlwdWxhdGlvbgoJCWNhY2hlVVJMID0gcy51cmwucmVwbGFjZSggcmhhc2gsICIiICk7CgoJCS8vIE1vcmUgb3B0aW9ucyBoYW5kbGluZyBmb3IgcmVxdWVzdHMgd2l0aCBubyBjb250ZW50CgkJaWYgKCAhcy5oYXNDb250ZW50ICkgewoKCQkJLy8gUmVtZW1iZXIgdGhlIGhhc2ggc28gd2UgY2FuIHB1dCBpdCBiYWNrCgkJCXVuY2FjaGVkID0gcy51cmwuc2xpY2UoIGNhY2hlVVJMLmxlbmd0aCApOwoKCQkJLy8gSWYgZGF0YSBpcyBhdmFpbGFibGUgYW5kIHNob3VsZCBiZSBwcm9jZXNzZWQsIGFwcGVuZCBkYXRhIHRvIHVybAoJCQlpZiAoIHMuZGF0YSAmJiAoIHMucHJvY2Vzc0RhdGEgfHwgdHlwZW9mIHMuZGF0YSA9PT0gInN0cmluZyIgKSApIHsKCQkJCWNhY2hlVVJMICs9ICggcnF1ZXJ5LnRlc3QoIGNhY2hlVVJMICkgPyAiJiIgOiAiPyIgKSArIHMuZGF0YTsKCgkJCQkvLyAjOTY4MjogcmVtb3ZlIGRhdGEgc28gdGhhdCBpdCdzIG5vdCB1c2VkIGluIGFuIGV2ZW50dWFsIHJldHJ5CgkJCQlkZWxldGUgcy5kYXRhOwoJCQl9CgoJCQkvLyBBZGQgb3IgdXBkYXRlIGFudGktY2FjaGUgcGFyYW0gaWYgbmVlZGVkCgkJCWlmICggcy5jYWNoZSA9PT0gZmFsc2UgKSB7CgkJCQljYWNoZVVSTCA9IGNhY2hlVVJMLnJlcGxhY2UoIHJhbnRpQ2FjaGUsICIkMSIgKTsKCQkJCXVuY2FjaGVkID0gKCBycXVlcnkudGVzdCggY2FjaGVVUkwgKSA/ICImIiA6ICI/IiApICsgIl89IiArICggbm9uY2UrKyApICsgdW5jYWNoZWQ7CgkJCX0KCgkJCS8vIFB1dCBoYXNoIGFuZCBhbnRpLWNhY2hlIG9uIHRoZSBVUkwgdGhhdCB3aWxsIGJlIHJlcXVlc3RlZCAoZ2gtMTczMikKCQkJcy51cmwgPSBjYWNoZVVSTCArIHVuY2FjaGVkOwoKCQkvLyBDaGFuZ2UgJyUyMCcgdG8gJysnIGlmIHRoaXMgaXMgZW5jb2RlZCBmb3JtIGJvZHkgY29udGVudCAoZ2gtMjY1OCkKCQl9IGVsc2UgaWYgKCBzLmRhdGEgJiYgcy5wcm9jZXNzRGF0YSAmJgoJCQkoIHMuY29udGVudFR5cGUgfHwgIiIgKS5pbmRleE9mKCAiYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkIiApID09PSAwICkgewoJCQlzLmRhdGEgPSBzLmRhdGEucmVwbGFjZSggcjIwLCAiKyIgKTsKCQl9CgoJCS8vIFNldCB0aGUgSWYtTW9kaWZpZWQtU2luY2UgYW5kL29yIElmLU5vbmUtTWF0Y2ggaGVhZGVyLCBpZiBpbiBpZk1vZGlmaWVkIG1vZGUuCgkJaWYgKCBzLmlmTW9kaWZpZWQgKSB7CgkJCWlmICggalF1ZXJ5Lmxhc3RNb2RpZmllZFsgY2FjaGVVUkwgXSApIHsKCQkJCWpxWEhSLnNldFJlcXVlc3RIZWFkZXIoICJJZi1Nb2RpZmllZC1TaW5jZSIsIGpRdWVyeS5sYXN0TW9kaWZpZWRbIGNhY2hlVVJMIF0gKTsKCQkJfQoJCQlpZiAoIGpRdWVyeS5ldGFnWyBjYWNoZVVSTCBdICkgewoJCQkJanFYSFIuc2V0UmVxdWVzdEhlYWRlciggIklmLU5vbmUtTWF0Y2giLCBqUXVlcnkuZXRhZ1sgY2FjaGVVUkwgXSApOwoJCQl9CgkJfQoKCQkvLyBTZXQgdGhlIGNvcnJlY3QgaGVhZGVyLCBpZiBkYXRhIGlzIGJlaW5nIHNlbnQKCQlpZiAoIHMuZGF0YSAmJiBzLmhhc0NvbnRlbnQgJiYgcy5jb250ZW50VHlwZSAhPT0gZmFsc2UgfHwgb3B0aW9ucy5jb250ZW50VHlwZSApIHsKCQkJanFYSFIuc2V0UmVxdWVzdEhlYWRlciggIkNvbnRlbnQtVHlwZSIsIHMuY29udGVudFR5cGUgKTsKCQl9CgoJCS8vIFNldCB0aGUgQWNjZXB0cyBoZWFkZXIgZm9yIHRoZSBzZXJ2ZXIsIGRlcGVuZGluZyBvbiB0aGUgZGF0YVR5cGUKCQlqcVhIUi5zZXRSZXF1ZXN0SGVhZGVyKAoJCQkiQWNjZXB0IiwKCQkJcy5kYXRhVHlwZXNbIDAgXSAmJiBzLmFjY2VwdHNbIHMuZGF0YVR5cGVzWyAwIF0gXSA/CgkJCQlzLmFjY2VwdHNbIHMuZGF0YVR5cGVzWyAwIF0gXSArCgkJCQkJKCBzLmRhdGFUeXBlc1sgMCBdICE9PSAiKiIgPyAiLCAiICsgYWxsVHlwZXMgKyAiOyBxPTAuMDEiIDogIiIgKSA6CgkJCQlzLmFjY2VwdHNbICIqIiBdCgkJKTsKCgkJLy8gQ2hlY2sgZm9yIGhlYWRlcnMgb3B0aW9uCgkJZm9yICggaSBpbiBzLmhlYWRlcnMgKSB7CgkJCWpxWEhSLnNldFJlcXVlc3RIZWFkZXIoIGksIHMuaGVhZGVyc1sgaSBdICk7CgkJfQoKCQkvLyBBbGxvdyBjdXN0b20gaGVhZGVycy9taW1ldHlwZXMgYW5kIGVhcmx5IGFib3J0CgkJaWYgKCBzLmJlZm9yZVNlbmQgJiYKCQkJKCBzLmJlZm9yZVNlbmQuY2FsbCggY2FsbGJhY2tDb250ZXh0LCBqcVhIUiwgcyApID09PSBmYWxzZSB8fCBjb21wbGV0ZWQgKSApIHsKCgkJCS8vIEFib3J0IGlmIG5vdCBkb25lIGFscmVhZHkgYW5kIHJldHVybgoJCQlyZXR1cm4ganFYSFIuYWJvcnQoKTsKCQl9CgoJCS8vIEFib3J0aW5nIGlzIG5vIGxvbmdlciBhIGNhbmNlbGxhdGlvbgoJCXN0ckFib3J0ID0gImFib3J0IjsKCgkJLy8gSW5zdGFsbCBjYWxsYmFja3Mgb24gZGVmZXJyZWRzCgkJY29tcGxldGVEZWZlcnJlZC5hZGQoIHMuY29tcGxldGUgKTsKCQlqcVhIUi5kb25lKCBzLnN1Y2Nlc3MgKTsKCQlqcVhIUi5mYWlsKCBzLmVycm9yICk7CgoJCS8vIEdldCB0cmFuc3BvcnQKCQl0cmFuc3BvcnQgPSBpbnNwZWN0UHJlZmlsdGVyc09yVHJhbnNwb3J0cyggdHJhbnNwb3J0cywgcywgb3B0aW9ucywganFYSFIgKTsKCgkJLy8gSWYgbm8gdHJhbnNwb3J0LCB3ZSBhdXRvLWFib3J0CgkJaWYgKCAhdHJhbnNwb3J0ICkgewoJCQlkb25lKCAtMSwgIk5vIFRyYW5zcG9ydCIgKTsKCQl9IGVsc2UgewoJCQlqcVhIUi5yZWFkeVN0YXRlID0gMTsKCgkJCS8vIFNlbmQgZ2xvYmFsIGV2ZW50CgkJCWlmICggZmlyZUdsb2JhbHMgKSB7CgkJCQlnbG9iYWxFdmVudENvbnRleHQudHJpZ2dlciggImFqYXhTZW5kIiwgWyBqcVhIUiwgcyBdICk7CgkJCX0KCgkJCS8vIElmIHJlcXVlc3Qgd2FzIGFib3J0ZWQgaW5zaWRlIGFqYXhTZW5kLCBzdG9wIHRoZXJlCgkJCWlmICggY29tcGxldGVkICkgewoJCQkJcmV0dXJuIGpxWEhSOwoJCQl9CgoJCQkvLyBUaW1lb3V0CgkJCWlmICggcy5hc3luYyAmJiBzLnRpbWVvdXQgPiAwICkgewoJCQkJdGltZW91dFRpbWVyID0gd2luZG93LnNldFRpbWVvdXQoIGZ1bmN0aW9uKCkgewoJCQkJCWpxWEhSLmFib3J0KCAidGltZW91dCIgKTsKCQkJCX0sIHMudGltZW91dCApOwoJCQl9CgoJCQl0cnkgewoJCQkJY29tcGxldGVkID0gZmFsc2U7CgkJCQl0cmFuc3BvcnQuc2VuZCggcmVxdWVzdEhlYWRlcnMsIGRvbmUgKTsKCQkJfSBjYXRjaCAoIGUgKSB7CgoJCQkJLy8gUmV0aHJvdyBwb3N0LWNvbXBsZXRpb24gZXhjZXB0aW9ucwoJCQkJaWYgKCBjb21wbGV0ZWQgKSB7CgkJCQkJdGhyb3cgZTsKCQkJCX0KCgkJCQkvLyBQcm9wYWdhdGUgb3RoZXJzIGFzIHJlc3VsdHMKCQkJCWRvbmUoIC0xLCBlICk7CgkJCX0KCQl9CgoJCS8vIENhbGxiYWNrIGZvciB3aGVuIGV2ZXJ5dGhpbmcgaXMgZG9uZQoJCWZ1bmN0aW9uIGRvbmUoIHN0YXR1cywgbmF0aXZlU3RhdHVzVGV4dCwgcmVzcG9uc2VzLCBoZWFkZXJzICkgewoJCQl2YXIgaXNTdWNjZXNzLCBzdWNjZXNzLCBlcnJvciwgcmVzcG9uc2UsIG1vZGlmaWVkLAoJCQkJc3RhdHVzVGV4dCA9IG5hdGl2ZVN0YXR1c1RleHQ7CgoJCQkvLyBJZ25vcmUgcmVwZWF0IGludm9jYXRpb25zCgkJCWlmICggY29tcGxldGVkICkgewoJCQkJcmV0dXJuOwoJCQl9CgoJCQljb21wbGV0ZWQgPSB0cnVlOwoKCQkJLy8gQ2xlYXIgdGltZW91dCBpZiBpdCBleGlzdHMKCQkJaWYgKCB0aW1lb3V0VGltZXIgKSB7CgkJCQl3aW5kb3cuY2xlYXJUaW1lb3V0KCB0aW1lb3V0VGltZXIgKTsKCQkJfQoKCQkJLy8gRGVyZWZlcmVuY2UgdHJhbnNwb3J0IGZvciBlYXJseSBnYXJiYWdlIGNvbGxlY3Rpb24KCQkJLy8gKG5vIG1hdHRlciBob3cgbG9uZyB0aGUganFYSFIgb2JqZWN0IHdpbGwgYmUgdXNlZCkKCQkJdHJhbnNwb3J0ID0gdW5kZWZpbmVkOwoKCQkJLy8gQ2FjaGUgcmVzcG9uc2UgaGVhZGVycwoJCQlyZXNwb25zZUhlYWRlcnNTdHJpbmcgPSBoZWFkZXJzIHx8ICIiOwoKCQkJLy8gU2V0IHJlYWR5U3RhdGUKCQkJanFYSFIucmVhZHlTdGF0ZSA9IHN0YXR1cyA+IDAgPyA0IDogMDsKCgkJCS8vIERldGVybWluZSBpZiBzdWNjZXNzZnVsCgkJCWlzU3VjY2VzcyA9IHN0YXR1cyA+PSAyMDAgJiYgc3RhdHVzIDwgMzAwIHx8IHN0YXR1cyA9PT0gMzA0OwoKCQkJLy8gR2V0IHJlc3BvbnNlIGRhdGEKCQkJaWYgKCByZXNwb25zZXMgKSB7CgkJCQlyZXNwb25zZSA9IGFqYXhIYW5kbGVSZXNwb25zZXMoIHMsIGpxWEhSLCByZXNwb25zZXMgKTsKCQkJfQoKCQkJLy8gQ29udmVydCBubyBtYXR0ZXIgd2hhdCAodGhhdCB3YXkgcmVzcG9uc2VYWFggZmllbGRzIGFyZSBhbHdheXMgc2V0KQoJCQlyZXNwb25zZSA9IGFqYXhDb252ZXJ0KCBzLCByZXNwb25zZSwganFYSFIsIGlzU3VjY2VzcyApOwoKCQkJLy8gSWYgc3VjY2Vzc2Z1bCwgaGFuZGxlIHR5cGUgY2hhaW5pbmcKCQkJaWYgKCBpc1N1Y2Nlc3MgKSB7CgoJCQkJLy8gU2V0IHRoZSBJZi1Nb2RpZmllZC1TaW5jZSBhbmQvb3IgSWYtTm9uZS1NYXRjaCBoZWFkZXIsIGlmIGluIGlmTW9kaWZpZWQgbW9kZS4KCQkJCWlmICggcy5pZk1vZGlmaWVkICkgewoJCQkJCW1vZGlmaWVkID0ganFYSFIuZ2V0UmVzcG9uc2VIZWFkZXIoICJMYXN0LU1vZGlmaWVkIiApOwoJCQkJCWlmICggbW9kaWZpZWQgKSB7CgkJCQkJCWpRdWVyeS5sYXN0TW9kaWZpZWRbIGNhY2hlVVJMIF0gPSBtb2RpZmllZDsKCQkJCQl9CgkJCQkJbW9kaWZpZWQgPSBqcVhIUi5nZXRSZXNwb25zZUhlYWRlciggImV0YWciICk7CgkJCQkJaWYgKCBtb2RpZmllZCApIHsKCQkJCQkJalF1ZXJ5LmV0YWdbIGNhY2hlVVJMIF0gPSBtb2RpZmllZDsKCQkJCQl9CgkJCQl9CgoJCQkJLy8gaWYgbm8gY29udGVudAoJCQkJaWYgKCBzdGF0dXMgPT09IDIwNCB8fCBzLnR5cGUgPT09ICJIRUFEIiApIHsKCQkJCQlzdGF0dXNUZXh0ID0gIm5vY29udGVudCI7CgoJCQkJLy8gaWYgbm90IG1vZGlmaWVkCgkJCQl9IGVsc2UgaWYgKCBzdGF0dXMgPT09IDMwNCApIHsKCQkJCQlzdGF0dXNUZXh0ID0gIm5vdG1vZGlmaWVkIjsKCgkJCQkvLyBJZiB3ZSBoYXZlIGRhdGEsIGxldCdzIGNvbnZlcnQgaXQKCQkJCX0gZWxzZSB7CgkJCQkJc3RhdHVzVGV4dCA9IHJlc3BvbnNlLnN0YXRlOwoJCQkJCXN1Y2Nlc3MgPSByZXNwb25zZS5kYXRhOwoJCQkJCWVycm9yID0gcmVzcG9uc2UuZXJyb3I7CgkJCQkJaXNTdWNjZXNzID0gIWVycm9yOwoJCQkJfQoJCQl9IGVsc2UgewoKCQkJCS8vIEV4dHJhY3QgZXJyb3IgZnJvbSBzdGF0dXNUZXh0IGFuZCBub3JtYWxpemUgZm9yIG5vbi1hYm9ydHMKCQkJCWVycm9yID0gc3RhdHVzVGV4dDsKCQkJCWlmICggc3RhdHVzIHx8ICFzdGF0dXNUZXh0ICkgewoJCQkJCXN0YXR1c1RleHQgPSAiZXJyb3IiOwoJCQkJCWlmICggc3RhdHVzIDwgMCApIHsKCQkJCQkJc3RhdHVzID0gMDsKCQkJCQl9CgkJCQl9CgkJCX0KCgkJCS8vIFNldCBkYXRhIGZvciB0aGUgZmFrZSB4aHIgb2JqZWN0CgkJCWpxWEhSLnN0YXR1cyA9IHN0YXR1czsKCQkJanFYSFIuc3RhdHVzVGV4dCA9ICggbmF0aXZlU3RhdHVzVGV4dCB8fCBzdGF0dXNUZXh0ICkgKyAiIjsKCgkJCS8vIFN1Y2Nlc3MvRXJyb3IKCQkJaWYgKCBpc1N1Y2Nlc3MgKSB7CgkJCQlkZWZlcnJlZC5yZXNvbHZlV2l0aCggY2FsbGJhY2tDb250ZXh0LCBbIHN1Y2Nlc3MsIHN0YXR1c1RleHQsIGpxWEhSIF0gKTsKCQkJfSBlbHNlIHsKCQkJCWRlZmVycmVkLnJlamVjdFdpdGgoIGNhbGxiYWNrQ29udGV4dCwgWyBqcVhIUiwgc3RhdHVzVGV4dCwgZXJyb3IgXSApOwoJCQl9CgoJCQkvLyBTdGF0dXMtZGVwZW5kZW50IGNhbGxiYWNrcwoJCQlqcVhIUi5zdGF0dXNDb2RlKCBzdGF0dXNDb2RlICk7CgkJCXN0YXR1c0NvZGUgPSB1bmRlZmluZWQ7CgoJCQlpZiAoIGZpcmVHbG9iYWxzICkgewoJCQkJZ2xvYmFsRXZlbnRDb250ZXh0LnRyaWdnZXIoIGlzU3VjY2VzcyA/ICJhamF4U3VjY2VzcyIgOiAiYWpheEVycm9yIiwKCQkJCQlbIGpxWEhSLCBzLCBpc1N1Y2Nlc3MgPyBzdWNjZXNzIDogZXJyb3IgXSApOwoJCQl9CgoJCQkvLyBDb21wbGV0ZQoJCQljb21wbGV0ZURlZmVycmVkLmZpcmVXaXRoKCBjYWxsYmFja0NvbnRleHQsIFsganFYSFIsIHN0YXR1c1RleHQgXSApOwoKCQkJaWYgKCBmaXJlR2xvYmFscyApIHsKCQkJCWdsb2JhbEV2ZW50Q29udGV4dC50cmlnZ2VyKCAiYWpheENvbXBsZXRlIiwgWyBqcVhIUiwgcyBdICk7CgoJCQkJLy8gSGFuZGxlIHRoZSBnbG9iYWwgQUpBWCBjb3VudGVyCgkJCQlpZiAoICEoIC0talF1ZXJ5LmFjdGl2ZSApICkgewoJCQkJCWpRdWVyeS5ldmVudC50cmlnZ2VyKCAiYWpheFN0b3AiICk7CgkJCQl9CgkJCX0KCQl9CgoJCXJldHVybiBqcVhIUjsKCX0sCgoJZ2V0SlNPTjogZnVuY3Rpb24oIHVybCwgZGF0YSwgY2FsbGJhY2sgKSB7CgkJcmV0dXJuIGpRdWVyeS5nZXQoIHVybCwgZGF0YSwgY2FsbGJhY2ssICJqc29uIiApOwoJfSwKCglnZXRTY3JpcHQ6IGZ1bmN0aW9uKCB1cmwsIGNhbGxiYWNrICkgewoJCXJldHVybiBqUXVlcnkuZ2V0KCB1cmwsIHVuZGVmaW5lZCwgY2FsbGJhY2ssICJzY3JpcHQiICk7Cgl9Cn0gKTsKCmpRdWVyeS5lYWNoKCBbICJnZXQiLCAicG9zdCIgXSwgZnVuY3Rpb24oIGksIG1ldGhvZCApIHsKCWpRdWVyeVsgbWV0aG9kIF0gPSBmdW5jdGlvbiggdXJsLCBkYXRhLCBjYWxsYmFjaywgdHlwZSApIHsKCgkJLy8gU2hpZnQgYXJndW1lbnRzIGlmIGRhdGEgYXJndW1lbnQgd2FzIG9taXR0ZWQKCQlpZiAoIGlzRnVuY3Rpb24oIGRhdGEgKSApIHsKCQkJdHlwZSA9IHR5cGUgfHwgY2FsbGJhY2s7CgkJCWNhbGxiYWNrID0gZGF0YTsKCQkJZGF0YSA9IHVuZGVmaW5lZDsKCQl9CgoJCS8vIFRoZSB1cmwgY2FuIGJlIGFuIG9wdGlvbnMgb2JqZWN0ICh3aGljaCB0aGVuIG11c3QgaGF2ZSAudXJsKQoJCXJldHVybiBqUXVlcnkuYWpheCggalF1ZXJ5LmV4dGVuZCggewoJCQl1cmw6IHVybCwKCQkJdHlwZTogbWV0aG9kLAoJCQlkYXRhVHlwZTogdHlwZSwKCQkJZGF0YTogZGF0YSwKCQkJc3VjY2VzczogY2FsbGJhY2sKCQl9LCBqUXVlcnkuaXNQbGFpbk9iamVjdCggdXJsICkgJiYgdXJsICkgKTsKCX07Cn0gKTsKCgpqUXVlcnkuX2V2YWxVcmwgPSBmdW5jdGlvbiggdXJsICkgewoJcmV0dXJuIGpRdWVyeS5hamF4KCB7CgkJdXJsOiB1cmwsCgoJCS8vIE1ha2UgdGhpcyBleHBsaWNpdCwgc2luY2UgdXNlciBjYW4gb3ZlcnJpZGUgdGhpcyB0aHJvdWdoIGFqYXhTZXR1cCAoIzExMjY0KQoJCXR5cGU6ICJHRVQiLAoJCWRhdGFUeXBlOiAic2NyaXB0IiwKCQljYWNoZTogdHJ1ZSwKCQlhc3luYzogZmFsc2UsCgkJZ2xvYmFsOiBmYWxzZSwKCQkidGhyb3dzIjogdHJ1ZQoJfSApOwp9OwoKCmpRdWVyeS5mbi5leHRlbmQoIHsKCXdyYXBBbGw6IGZ1bmN0aW9uKCBodG1sICkgewoJCXZhciB3cmFwOwoKCQlpZiAoIHRoaXNbIDAgXSApIHsKCQkJaWYgKCBpc0Z1bmN0aW9uKCBodG1sICkgKSB7CgkJCQlodG1sID0gaHRtbC5jYWxsKCB0aGlzWyAwIF0gKTsKCQkJfQoKCQkJLy8gVGhlIGVsZW1lbnRzIHRvIHdyYXAgdGhlIHRhcmdldCBhcm91bmQKCQkJd3JhcCA9IGpRdWVyeSggaHRtbCwgdGhpc1sgMCBdLm93bmVyRG9jdW1lbnQgKS5lcSggMCApLmNsb25lKCB0cnVlICk7CgoJCQlpZiAoIHRoaXNbIDAgXS5wYXJlbnROb2RlICkgewoJCQkJd3JhcC5pbnNlcnRCZWZvcmUoIHRoaXNbIDAgXSApOwoJCQl9CgoJCQl3cmFwLm1hcCggZnVuY3Rpb24oKSB7CgkJCQl2YXIgZWxlbSA9IHRoaXM7CgoJCQkJd2hpbGUgKCBlbGVtLmZpcnN0RWxlbWVudENoaWxkICkgewoJCQkJCWVsZW0gPSBlbGVtLmZpcnN0RWxlbWVudENoaWxkOwoJCQkJfQoKCQkJCXJldHVybiBlbGVtOwoJCQl9ICkuYXBwZW5kKCB0aGlzICk7CgkJfQoKCQlyZXR1cm4gdGhpczsKCX0sCgoJd3JhcElubmVyOiBmdW5jdGlvbiggaHRtbCApIHsKCQlpZiAoIGlzRnVuY3Rpb24oIGh0bWwgKSApIHsKCQkJcmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24oIGkgKSB7CgkJCQlqUXVlcnkoIHRoaXMgKS53cmFwSW5uZXIoIGh0bWwuY2FsbCggdGhpcywgaSApICk7CgkJCX0gKTsKCQl9CgoJCXJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCkgewoJCQl2YXIgc2VsZiA9IGpRdWVyeSggdGhpcyApLAoJCQkJY29udGVudHMgPSBzZWxmLmNvbnRlbnRzKCk7CgoJCQlpZiAoIGNvbnRlbnRzLmxlbmd0aCApIHsKCQkJCWNvbnRlbnRzLndyYXBBbGwoIGh0bWwgKTsKCgkJCX0gZWxzZSB7CgkJCQlzZWxmLmFwcGVuZCggaHRtbCApOwoJCQl9CgkJfSApOwoJfSwKCgl3cmFwOiBmdW5jdGlvbiggaHRtbCApIHsKCQl2YXIgaHRtbElzRnVuY3Rpb24gPSBpc0Z1bmN0aW9uKCBodG1sICk7CgoJCXJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCBpICkgewoJCQlqUXVlcnkoIHRoaXMgKS53cmFwQWxsKCBodG1sSXNGdW5jdGlvbiA/IGh0bWwuY2FsbCggdGhpcywgaSApIDogaHRtbCApOwoJCX0gKTsKCX0sCgoJdW53cmFwOiBmdW5jdGlvbiggc2VsZWN0b3IgKSB7CgkJdGhpcy5wYXJlbnQoIHNlbGVjdG9yICkubm90KCAiYm9keSIgKS5lYWNoKCBmdW5jdGlvbigpIHsKCQkJalF1ZXJ5KCB0aGlzICkucmVwbGFjZVdpdGgoIHRoaXMuY2hpbGROb2RlcyApOwoJCX0gKTsKCQlyZXR1cm4gdGhpczsKCX0KfSApOwoKCmpRdWVyeS5leHByLnBzZXVkb3MuaGlkZGVuID0gZnVuY3Rpb24oIGVsZW0gKSB7CglyZXR1cm4gIWpRdWVyeS5leHByLnBzZXVkb3MudmlzaWJsZSggZWxlbSApOwp9OwpqUXVlcnkuZXhwci5wc2V1ZG9zLnZpc2libGUgPSBmdW5jdGlvbiggZWxlbSApIHsKCXJldHVybiAhISggZWxlbS5vZmZzZXRXaWR0aCB8fCBlbGVtLm9mZnNldEhlaWdodCB8fCBlbGVtLmdldENsaWVudFJlY3RzKCkubGVuZ3RoICk7Cn07CgoKCgpqUXVlcnkuYWpheFNldHRpbmdzLnhociA9IGZ1bmN0aW9uKCkgewoJdHJ5IHsKCQlyZXR1cm4gbmV3IHdpbmRvdy5YTUxIdHRwUmVxdWVzdCgpOwoJfSBjYXRjaCAoIGUgKSB7fQp9OwoKdmFyIHhoclN1Y2Nlc3NTdGF0dXMgPSB7CgoJCS8vIEZpbGUgcHJvdG9jb2wgYWx3YXlzIHlpZWxkcyBzdGF0dXMgY29kZSAwLCBhc3N1bWUgMjAwCgkJMDogMjAwLAoKCQkvLyBTdXBwb3J0OiBJRSA8PTkgb25seQoJCS8vICMxNDUwOiBzb21ldGltZXMgSUUgcmV0dXJucyAxMjIzIHdoZW4gaXQgc2hvdWxkIGJlIDIwNAoJCTEyMjM6IDIwNAoJfSwKCXhoclN1cHBvcnRlZCA9IGpRdWVyeS5hamF4U2V0dGluZ3MueGhyKCk7CgpzdXBwb3J0LmNvcnMgPSAhIXhoclN1cHBvcnRlZCAmJiAoICJ3aXRoQ3JlZGVudGlhbHMiIGluIHhoclN1cHBvcnRlZCApOwpzdXBwb3J0LmFqYXggPSB4aHJTdXBwb3J0ZWQgPSAhIXhoclN1cHBvcnRlZDsKCmpRdWVyeS5hamF4VHJhbnNwb3J0KCBmdW5jdGlvbiggb3B0aW9ucyApIHsKCXZhciBjYWxsYmFjaywgZXJyb3JDYWxsYmFjazsKCgkvLyBDcm9zcyBkb21haW4gb25seSBhbGxvd2VkIGlmIHN1cHBvcnRlZCB0aHJvdWdoIFhNTEh0dHBSZXF1ZXN0CglpZiAoIHN1cHBvcnQuY29ycyB8fCB4aHJTdXBwb3J0ZWQgJiYgIW9wdGlvbnMuY3Jvc3NEb21haW4gKSB7CgkJcmV0dXJuIHsKCQkJc2VuZDogZnVuY3Rpb24oIGhlYWRlcnMsIGNvbXBsZXRlICkgewoJCQkJdmFyIGksCgkJCQkJeGhyID0gb3B0aW9ucy54aHIoKTsKCgkJCQl4aHIub3BlbigKCQkJCQlvcHRpb25zLnR5cGUsCgkJCQkJb3B0aW9ucy51cmwsCgkJCQkJb3B0aW9ucy5hc3luYywKCQkJCQlvcHRpb25zLnVzZXJuYW1lLAoJCQkJCW9wdGlvbnMucGFzc3dvcmQKCQkJCSk7CgoJCQkJLy8gQXBwbHkgY3VzdG9tIGZpZWxkcyBpZiBwcm92aWRlZAoJCQkJaWYgKCBvcHRpb25zLnhockZpZWxkcyApIHsKCQkJCQlmb3IgKCBpIGluIG9wdGlvbnMueGhyRmllbGRzICkgewoJCQkJCQl4aHJbIGkgXSA9IG9wdGlvbnMueGhyRmllbGRzWyBpIF07CgkJCQkJfQoJCQkJfQoKCQkJCS8vIE92ZXJyaWRlIG1pbWUgdHlwZSBpZiBuZWVkZWQKCQkJCWlmICggb3B0aW9ucy5taW1lVHlwZSAmJiB4aHIub3ZlcnJpZGVNaW1lVHlwZSApIHsKCQkJCQl4aHIub3ZlcnJpZGVNaW1lVHlwZSggb3B0aW9ucy5taW1lVHlwZSApOwoJCQkJfQoKCQkJCS8vIFgtUmVxdWVzdGVkLVdpdGggaGVhZGVyCgkJCQkvLyBGb3IgY3Jvc3MtZG9tYWluIHJlcXVlc3RzLCBzZWVpbmcgYXMgY29uZGl0aW9ucyBmb3IgYSBwcmVmbGlnaHQgYXJlCgkJCQkvLyBha2luIHRvIGEgamlnc2F3IHB1enpsZSwgd2Ugc2ltcGx5IG5ldmVyIHNldCBpdCB0byBiZSBzdXJlLgoJCQkJLy8gKGl0IGNhbiBhbHdheXMgYmUgc2V0IG9uIGEgcGVyLXJlcXVlc3QgYmFzaXMgb3IgZXZlbiB1c2luZyBhamF4U2V0dXApCgkJCQkvLyBGb3Igc2FtZS1kb21haW4gcmVxdWVzdHMsIHdvbid0IGNoYW5nZSBoZWFkZXIgaWYgYWxyZWFkeSBwcm92aWRlZC4KCQkJCWlmICggIW9wdGlvbnMuY3Jvc3NEb21haW4gJiYgIWhlYWRlcnNbICJYLVJlcXVlc3RlZC1XaXRoIiBdICkgewoJCQkJCWhlYWRlcnNbICJYLVJlcXVlc3RlZC1XaXRoIiBdID0gIlhNTEh0dHBSZXF1ZXN0IjsKCQkJCX0KCgkJCQkvLyBTZXQgaGVhZGVycwoJCQkJZm9yICggaSBpbiBoZWFkZXJzICkgewoJCQkJCXhoci5zZXRSZXF1ZXN0SGVhZGVyKCBpLCBoZWFkZXJzWyBpIF0gKTsKCQkJCX0KCgkJCQkvLyBDYWxsYmFjawoJCQkJY2FsbGJhY2sgPSBmdW5jdGlvbiggdHlwZSApIHsKCQkJCQlyZXR1cm4gZnVuY3Rpb24oKSB7CgkJCQkJCWlmICggY2FsbGJhY2sgKSB7CgkJCQkJCQljYWxsYmFjayA9IGVycm9yQ2FsbGJhY2sgPSB4aHIub25sb2FkID0KCQkJCQkJCQl4aHIub25lcnJvciA9IHhoci5vbmFib3J0ID0geGhyLm9udGltZW91dCA9CgkJCQkJCQkJCXhoci5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBudWxsOwoKCQkJCQkJCWlmICggdHlwZSA9PT0gImFib3J0IiApIHsKCQkJCQkJCQl4aHIuYWJvcnQoKTsKCQkJCQkJCX0gZWxzZSBpZiAoIHR5cGUgPT09ICJlcnJvciIgKSB7CgoJCQkJCQkJCS8vIFN1cHBvcnQ6IElFIDw9OSBvbmx5CgkJCQkJCQkJLy8gT24gYSBtYW51YWwgbmF0aXZlIGFib3J0LCBJRTkgdGhyb3dzCgkJCQkJCQkJLy8gZXJyb3JzIG9uIGFueSBwcm9wZXJ0eSBhY2Nlc3MgdGhhdCBpcyBub3QgcmVhZHlTdGF0ZQoJCQkJCQkJCWlmICggdHlwZW9mIHhoci5zdGF0dXMgIT09ICJudW1iZXIiICkgewoJCQkJCQkJCQljb21wbGV0ZSggMCwgImVycm9yIiApOwoJCQkJCQkJCX0gZWxzZSB7CgkJCQkJCQkJCWNvbXBsZXRlKAoKCQkJCQkJCQkJCS8vIEZpbGU6IHByb3RvY29sIGFsd2F5cyB5aWVsZHMgc3RhdHVzIDA7IHNlZSAjODYwNSwgIzE0MjA3CgkJCQkJCQkJCQl4aHIuc3RhdHVzLAoJCQkJCQkJCQkJeGhyLnN0YXR1c1RleHQKCQkJCQkJCQkJKTsKCQkJCQkJCQl9CgkJCQkJCQl9IGVsc2UgewoJCQkJCQkJCWNvbXBsZXRlKAoJCQkJCQkJCQl4aHJTdWNjZXNzU3RhdHVzWyB4aHIuc3RhdHVzIF0gfHwgeGhyLnN0YXR1cywKCQkJCQkJCQkJeGhyLnN0YXR1c1RleHQsCgoJCQkJCQkJCQkvLyBTdXBwb3J0OiBJRSA8PTkgb25seQoJCQkJCQkJCQkvLyBJRTkgaGFzIG5vIFhIUjIgYnV0IHRocm93cyBvbiBiaW5hcnkgKHRyYWMtMTE0MjYpCgkJCQkJCQkJCS8vIEZvciBYSFIyIG5vbi10ZXh0LCBsZXQgdGhlIGNhbGxlciBoYW5kbGUgaXQgKGdoLTI0OTgpCgkJCQkJCQkJCSggeGhyLnJlc3BvbnNlVHlwZSB8fCAidGV4dCIgKSAhPT0gInRleHQiICB8fAoJCQkJCQkJCQl0eXBlb2YgeGhyLnJlc3BvbnNlVGV4dCAhPT0gInN0cmluZyIgPwoJCQkJCQkJCQkJeyBiaW5hcnk6IHhoci5yZXNwb25zZSB9IDoKCQkJCQkJCQkJCXsgdGV4dDogeGhyLnJlc3BvbnNlVGV4dCB9LAoJCQkJCQkJCQl4aHIuZ2V0QWxsUmVzcG9uc2VIZWFkZXJzKCkKCQkJCQkJCQkpOwoJCQkJCQkJfQoJCQkJCQl9CgkJCQkJfTsKCQkJCX07CgoJCQkJLy8gTGlzdGVuIHRvIGV2ZW50cwoJCQkJeGhyLm9ubG9hZCA9IGNhbGxiYWNrKCk7CgkJCQllcnJvckNhbGxiYWNrID0geGhyLm9uZXJyb3IgPSB4aHIub250aW1lb3V0ID0gY2FsbGJhY2soICJlcnJvciIgKTsKCgkJCQkvLyBTdXBwb3J0OiBJRSA5IG9ubHkKCQkJCS8vIFVzZSBvbnJlYWR5c3RhdGVjaGFuZ2UgdG8gcmVwbGFjZSBvbmFib3J0CgkJCQkvLyB0byBoYW5kbGUgdW5jYXVnaHQgYWJvcnRzCgkJCQlpZiAoIHhoci5vbmFib3J0ICE9PSB1bmRlZmluZWQgKSB7CgkJCQkJeGhyLm9uYWJvcnQgPSBlcnJvckNhbGxiYWNrOwoJCQkJfSBlbHNlIHsKCQkJCQl4aHIub25yZWFkeXN0YXRlY2hhbmdlID0gZnVuY3Rpb24oKSB7CgoJCQkJCQkvLyBDaGVjayByZWFkeVN0YXRlIGJlZm9yZSB0aW1lb3V0IGFzIGl0IGNoYW5nZXMKCQkJCQkJaWYgKCB4aHIucmVhZHlTdGF0ZSA9PT0gNCApIHsKCgkJCQkJCQkvLyBBbGxvdyBvbmVycm9yIHRvIGJlIGNhbGxlZCBmaXJzdCwKCQkJCQkJCS8vIGJ1dCB0aGF0IHdpbGwgbm90IGhhbmRsZSBhIG5hdGl2ZSBhYm9ydAoJCQkJCQkJLy8gQWxzbywgc2F2ZSBlcnJvckNhbGxiYWNrIHRvIGEgdmFyaWFibGUKCQkJCQkJCS8vIGFzIHhoci5vbmVycm9yIGNhbm5vdCBiZSBhY2Nlc3NlZAoJCQkJCQkJd2luZG93LnNldFRpbWVvdXQoIGZ1bmN0aW9uKCkgewoJCQkJCQkJCWlmICggY2FsbGJhY2sgKSB7CgkJCQkJCQkJCWVycm9yQ2FsbGJhY2soKTsKCQkJCQkJCQl9CgkJCQkJCQl9ICk7CgkJCQkJCX0KCQkJCQl9OwoJCQkJfQoKCQkJCS8vIENyZWF0ZSB0aGUgYWJvcnQgY2FsbGJhY2sKCQkJCWNhbGxiYWNrID0gY2FsbGJhY2soICJhYm9ydCIgKTsKCgkJCQl0cnkgewoKCQkJCQkvLyBEbyBzZW5kIHRoZSByZXF1ZXN0ICh0aGlzIG1heSByYWlzZSBhbiBleGNlcHRpb24pCgkJCQkJeGhyLnNlbmQoIG9wdGlvbnMuaGFzQ29udGVudCAmJiBvcHRpb25zLmRhdGEgfHwgbnVsbCApOwoJCQkJfSBjYXRjaCAoIGUgKSB7CgoJCQkJCS8vICMxNDY4MzogT25seSByZXRocm93IGlmIHRoaXMgaGFzbid0IGJlZW4gbm90aWZpZWQgYXMgYW4gZXJyb3IgeWV0CgkJCQkJaWYgKCBjYWxsYmFjayApIHsKCQkJCQkJdGhyb3cgZTsKCQkJCQl9CgkJCQl9CgkJCX0sCgoJCQlhYm9ydDogZnVuY3Rpb24oKSB7CgkJCQlpZiAoIGNhbGxiYWNrICkgewoJCQkJCWNhbGxiYWNrKCk7CgkJCQl9CgkJCX0KCQl9OwoJfQp9ICk7CgoKCgovLyBQcmV2ZW50IGF1dG8tZXhlY3V0aW9uIG9mIHNjcmlwdHMgd2hlbiBubyBleHBsaWNpdCBkYXRhVHlwZSB3YXMgcHJvdmlkZWQgKFNlZSBnaC0yNDMyKQpqUXVlcnkuYWpheFByZWZpbHRlciggZnVuY3Rpb24oIHMgKSB7CglpZiAoIHMuY3Jvc3NEb21haW4gKSB7CgkJcy5jb250ZW50cy5zY3JpcHQgPSBmYWxzZTsKCX0KfSApOwoKLy8gSW5zdGFsbCBzY3JpcHQgZGF0YVR5cGUKalF1ZXJ5LmFqYXhTZXR1cCggewoJYWNjZXB0czogewoJCXNjcmlwdDogInRleHQvamF2YXNjcmlwdCwgYXBwbGljYXRpb24vamF2YXNjcmlwdCwgIiArCgkJCSJhcHBsaWNhdGlvbi9lY21hc2NyaXB0LCBhcHBsaWNhdGlvbi94LWVjbWFzY3JpcHQiCgl9LAoJY29udGVudHM6IHsKCQlzY3JpcHQ6IC9cYig/OmphdmF8ZWNtYSlzY3JpcHRcYi8KCX0sCgljb252ZXJ0ZXJzOiB7CgkJInRleHQgc2NyaXB0IjogZnVuY3Rpb24oIHRleHQgKSB7CgkJCWpRdWVyeS5nbG9iYWxFdmFsKCB0ZXh0ICk7CgkJCXJldHVybiB0ZXh0OwoJCX0KCX0KfSApOwoKLy8gSGFuZGxlIGNhY2hlJ3Mgc3BlY2lhbCBjYXNlIGFuZCBjcm9zc0RvbWFpbgpqUXVlcnkuYWpheFByZWZpbHRlciggInNjcmlwdCIsIGZ1bmN0aW9uKCBzICkgewoJaWYgKCBzLmNhY2hlID09PSB1bmRlZmluZWQgKSB7CgkJcy5jYWNoZSA9IGZhbHNlOwoJfQoJaWYgKCBzLmNyb3NzRG9tYWluICkgewoJCXMudHlwZSA9ICJHRVQiOwoJfQp9ICk7CgovLyBCaW5kIHNjcmlwdCB0YWcgaGFjayB0cmFuc3BvcnQKalF1ZXJ5LmFqYXhUcmFuc3BvcnQoICJzY3JpcHQiLCBmdW5jdGlvbiggcyApIHsKCgkvLyBUaGlzIHRyYW5zcG9ydCBvbmx5IGRlYWxzIHdpdGggY3Jvc3MgZG9tYWluIHJlcXVlc3RzCglpZiAoIHMuY3Jvc3NEb21haW4gKSB7CgkJdmFyIHNjcmlwdCwgY2FsbGJhY2s7CgkJcmV0dXJuIHsKCQkJc2VuZDogZnVuY3Rpb24oIF8sIGNvbXBsZXRlICkgewoJCQkJc2NyaXB0ID0galF1ZXJ5KCAiPHNjcmlwdD4iICkucHJvcCggewoJCQkJCWNoYXJzZXQ6IHMuc2NyaXB0Q2hhcnNldCwKCQkJCQlzcmM6IHMudXJsCgkJCQl9ICkub24oCgkJCQkJImxvYWQgZXJyb3IiLAoJCQkJCWNhbGxiYWNrID0gZnVuY3Rpb24oIGV2dCApIHsKCQkJCQkJc2NyaXB0LnJlbW92ZSgpOwoJCQkJCQljYWxsYmFjayA9IG51bGw7CgkJCQkJCWlmICggZXZ0ICkgewoJCQkJCQkJY29tcGxldGUoIGV2dC50eXBlID09PSAiZXJyb3IiID8gNDA0IDogMjAwLCBldnQudHlwZSApOwoJCQkJCQl9CgkJCQkJfQoJCQkJKTsKCgkJCQkvLyBVc2UgbmF0aXZlIERPTSBtYW5pcHVsYXRpb24gdG8gYXZvaWQgb3VyIGRvbU1hbmlwIEFKQVggdHJpY2tlcnkKCQkJCWRvY3VtZW50LmhlYWQuYXBwZW5kQ2hpbGQoIHNjcmlwdFsgMCBdICk7CgkJCX0sCgkJCWFib3J0OiBmdW5jdGlvbigpIHsKCQkJCWlmICggY2FsbGJhY2sgKSB7CgkJCQkJY2FsbGJhY2soKTsKCQkJCX0KCQkJfQoJCX07Cgl9Cn0gKTsKCgoKCnZhciBvbGRDYWxsYmFja3MgPSBbXSwKCXJqc29ucCA9IC8oPSlcPyg/PSZ8JCl8XD9cPy87CgovLyBEZWZhdWx0IGpzb25wIHNldHRpbmdzCmpRdWVyeS5hamF4U2V0dXAoIHsKCWpzb25wOiAiY2FsbGJhY2siLAoJanNvbnBDYWxsYmFjazogZnVuY3Rpb24oKSB7CgkJdmFyIGNhbGxiYWNrID0gb2xkQ2FsbGJhY2tzLnBvcCgpIHx8ICggalF1ZXJ5LmV4cGFuZG8gKyAiXyIgKyAoIG5vbmNlKysgKSApOwoJCXRoaXNbIGNhbGxiYWNrIF0gPSB0cnVlOwoJCXJldHVybiBjYWxsYmFjazsKCX0KfSApOwoKLy8gRGV0ZWN0LCBub3JtYWxpemUgb3B0aW9ucyBhbmQgaW5zdGFsbCBjYWxsYmFja3MgZm9yIGpzb25wIHJlcXVlc3RzCmpRdWVyeS5hamF4UHJlZmlsdGVyKCAianNvbiBqc29ucCIsIGZ1bmN0aW9uKCBzLCBvcmlnaW5hbFNldHRpbmdzLCBqcVhIUiApIHsKCgl2YXIgY2FsbGJhY2tOYW1lLCBvdmVyd3JpdHRlbiwgcmVzcG9uc2VDb250YWluZXIsCgkJanNvblByb3AgPSBzLmpzb25wICE9PSBmYWxzZSAmJiAoIHJqc29ucC50ZXN0KCBzLnVybCApID8KCQkJInVybCIgOgoJCQl0eXBlb2Ygcy5kYXRhID09PSAic3RyaW5nIiAmJgoJCQkJKCBzLmNvbnRlbnRUeXBlIHx8ICIiICkKCQkJCQkuaW5kZXhPZiggImFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCIgKSA9PT0gMCAmJgoJCQkJcmpzb25wLnRlc3QoIHMuZGF0YSApICYmICJkYXRhIgoJCSk7CgoJLy8gSGFuZGxlIGlmZiB0aGUgZXhwZWN0ZWQgZGF0YSB0eXBlIGlzICJqc29ucCIgb3Igd2UgaGF2ZSBhIHBhcmFtZXRlciB0byBzZXQKCWlmICgganNvblByb3AgfHwgcy5kYXRhVHlwZXNbIDAgXSA9PT0gImpzb25wIiApIHsKCgkJLy8gR2V0IGNhbGxiYWNrIG5hbWUsIHJlbWVtYmVyaW5nIHByZWV4aXN0aW5nIHZhbHVlIGFzc29jaWF0ZWQgd2l0aCBpdAoJCWNhbGxiYWNrTmFtZSA9IHMuanNvbnBDYWxsYmFjayA9IGlzRnVuY3Rpb24oIHMuanNvbnBDYWxsYmFjayApID8KCQkJcy5qc29ucENhbGxiYWNrKCkgOgoJCQlzLmpzb25wQ2FsbGJhY2s7CgoJCS8vIEluc2VydCBjYWxsYmFjayBpbnRvIHVybCBvciBmb3JtIGRhdGEKCQlpZiAoIGpzb25Qcm9wICkgewoJCQlzWyBqc29uUHJvcCBdID0gc1sganNvblByb3AgXS5yZXBsYWNlKCByanNvbnAsICIkMSIgKyBjYWxsYmFja05hbWUgKTsKCQl9IGVsc2UgaWYgKCBzLmpzb25wICE9PSBmYWxzZSApIHsKCQkJcy51cmwgKz0gKCBycXVlcnkudGVzdCggcy51cmwgKSA/ICImIiA6ICI/IiApICsgcy5qc29ucCArICI9IiArIGNhbGxiYWNrTmFtZTsKCQl9CgoJCS8vIFVzZSBkYXRhIGNvbnZlcnRlciB0byByZXRyaWV2ZSBqc29uIGFmdGVyIHNjcmlwdCBleGVjdXRpb24KCQlzLmNvbnZlcnRlcnNbICJzY3JpcHQganNvbiIgXSA9IGZ1bmN0aW9uKCkgewoJCQlpZiAoICFyZXNwb25zZUNvbnRhaW5lciApIHsKCQkJCWpRdWVyeS5lcnJvciggY2FsbGJhY2tOYW1lICsgIiB3YXMgbm90IGNhbGxlZCIgKTsKCQkJfQoJCQlyZXR1cm4gcmVzcG9uc2VDb250YWluZXJbIDAgXTsKCQl9OwoKCQkvLyBGb3JjZSBqc29uIGRhdGFUeXBlCgkJcy5kYXRhVHlwZXNbIDAgXSA9ICJqc29uIjsKCgkJLy8gSW5zdGFsbCBjYWxsYmFjawoJCW92ZXJ3cml0dGVuID0gd2luZG93WyBjYWxsYmFja05hbWUgXTsKCQl3aW5kb3dbIGNhbGxiYWNrTmFtZSBdID0gZnVuY3Rpb24oKSB7CgkJCXJlc3BvbnNlQ29udGFpbmVyID0gYXJndW1lbnRzOwoJCX07CgoJCS8vIENsZWFuLXVwIGZ1bmN0aW9uIChmaXJlcyBhZnRlciBjb252ZXJ0ZXJzKQoJCWpxWEhSLmFsd2F5cyggZnVuY3Rpb24oKSB7CgoJCQkvLyBJZiBwcmV2aW91cyB2YWx1ZSBkaWRuJ3QgZXhpc3QgLSByZW1vdmUgaXQKCQkJaWYgKCBvdmVyd3JpdHRlbiA9PT0gdW5kZWZpbmVkICkgewoJCQkJalF1ZXJ5KCB3aW5kb3cgKS5yZW1vdmVQcm9wKCBjYWxsYmFja05hbWUgKTsKCgkJCS8vIE90aGVyd2lzZSByZXN0b3JlIHByZWV4aXN0aW5nIHZhbHVlCgkJCX0gZWxzZSB7CgkJCQl3aW5kb3dbIGNhbGxiYWNrTmFtZSBdID0gb3ZlcndyaXR0ZW47CgkJCX0KCgkJCS8vIFNhdmUgYmFjayBhcyBmcmVlCgkJCWlmICggc1sgY2FsbGJhY2tOYW1lIF0gKSB7CgoJCQkJLy8gTWFrZSBzdXJlIHRoYXQgcmUtdXNpbmcgdGhlIG9wdGlvbnMgZG9lc24ndCBzY3JldyB0aGluZ3MgYXJvdW5kCgkJCQlzLmpzb25wQ2FsbGJhY2sgPSBvcmlnaW5hbFNldHRpbmdzLmpzb25wQ2FsbGJhY2s7CgoJCQkJLy8gU2F2ZSB0aGUgY2FsbGJhY2sgbmFtZSBmb3IgZnV0dXJlIHVzZQoJCQkJb2xkQ2FsbGJhY2tzLnB1c2goIGNhbGxiYWNrTmFtZSApOwoJCQl9CgoJCQkvLyBDYWxsIGlmIGl0IHdhcyBhIGZ1bmN0aW9uIGFuZCB3ZSBoYXZlIGEgcmVzcG9uc2UKCQkJaWYgKCByZXNwb25zZUNvbnRhaW5lciAmJiBpc0Z1bmN0aW9uKCBvdmVyd3JpdHRlbiApICkgewoJCQkJb3ZlcndyaXR0ZW4oIHJlc3BvbnNlQ29udGFpbmVyWyAwIF0gKTsKCQkJfQoKCQkJcmVzcG9uc2VDb250YWluZXIgPSBvdmVyd3JpdHRlbiA9IHVuZGVmaW5lZDsKCQl9ICk7CgoJCS8vIERlbGVnYXRlIHRvIHNjcmlwdAoJCXJldHVybiAic2NyaXB0IjsKCX0KfSApOwoKCgoKLy8gU3VwcG9ydDogU2FmYXJpIDggb25seQovLyBJbiBTYWZhcmkgOCBkb2N1bWVudHMgY3JlYXRlZCB2aWEgZG9jdW1lbnQuaW1wbGVtZW50YXRpb24uY3JlYXRlSFRNTERvY3VtZW50Ci8vIGNvbGxhcHNlIHNpYmxpbmcgZm9ybXM6IHRoZSBzZWNvbmQgb25lIGJlY29tZXMgYSBjaGlsZCBvZiB0aGUgZmlyc3Qgb25lLgovLyBCZWNhdXNlIG9mIHRoYXQsIHRoaXMgc2VjdXJpdHkgbWVhc3VyZSBoYXMgdG8gYmUgZGlzYWJsZWQgaW4gU2FmYXJpIDguCi8vIGh0dHBzOi8vYnVncy53ZWJraXQub3JnL3Nob3dfYnVnLmNnaT9pZD0xMzczMzcKc3VwcG9ydC5jcmVhdGVIVE1MRG9jdW1lbnQgPSAoIGZ1bmN0aW9uKCkgewoJdmFyIGJvZHkgPSBkb2N1bWVudC5pbXBsZW1lbnRhdGlvbi5jcmVhdGVIVE1MRG9jdW1lbnQoICIiICkuYm9keTsKCWJvZHkuaW5uZXJIVE1MID0gIjxmb3JtPjwvZm9ybT48Zm9ybT48L2Zvcm0+IjsKCXJldHVybiBib2R5LmNoaWxkTm9kZXMubGVuZ3RoID09PSAyOwp9ICkoKTsKCgovLyBBcmd1bWVudCAiZGF0YSIgc2hvdWxkIGJlIHN0cmluZyBvZiBodG1sCi8vIGNvbnRleHQgKG9wdGlvbmFsKTogSWYgc3BlY2lmaWVkLCB0aGUgZnJhZ21lbnQgd2lsbCBiZSBjcmVhdGVkIGluIHRoaXMgY29udGV4dCwKLy8gZGVmYXVsdHMgdG8gZG9jdW1lbnQKLy8ga2VlcFNjcmlwdHMgKG9wdGlvbmFsKTogSWYgdHJ1ZSwgd2lsbCBpbmNsdWRlIHNjcmlwdHMgcGFzc2VkIGluIHRoZSBodG1sIHN0cmluZwpqUXVlcnkucGFyc2VIVE1MID0gZnVuY3Rpb24oIGRhdGEsIGNvbnRleHQsIGtlZXBTY3JpcHRzICkgewoJaWYgKCB0eXBlb2YgZGF0YSAhPT0gInN0cmluZyIgKSB7CgkJcmV0dXJuIFtdOwoJfQoJaWYgKCB0eXBlb2YgY29udGV4dCA9PT0gImJvb2xlYW4iICkgewoJCWtlZXBTY3JpcHRzID0gY29udGV4dDsKCQljb250ZXh0ID0gZmFsc2U7Cgl9CgoJdmFyIGJhc2UsIHBhcnNlZCwgc2NyaXB0czsKCglpZiAoICFjb250ZXh0ICkgewoKCQkvLyBTdG9wIHNjcmlwdHMgb3IgaW5saW5lIGV2ZW50IGhhbmRsZXJzIGZyb20gYmVpbmcgZXhlY3V0ZWQgaW1tZWRpYXRlbHkKCQkvLyBieSB1c2luZyBkb2N1bWVudC5pbXBsZW1lbnRhdGlvbgoJCWlmICggc3VwcG9ydC5jcmVhdGVIVE1MRG9jdW1lbnQgKSB7CgkJCWNvbnRleHQgPSBkb2N1bWVudC5pbXBsZW1lbnRhdGlvbi5jcmVhdGVIVE1MRG9jdW1lbnQoICIiICk7CgoJCQkvLyBTZXQgdGhlIGJhc2UgaHJlZiBmb3IgdGhlIGNyZWF0ZWQgZG9jdW1lbnQKCQkJLy8gc28gYW55IHBhcnNlZCBlbGVtZW50cyB3aXRoIFVSTHMKCQkJLy8gYXJlIGJhc2VkIG9uIHRoZSBkb2N1bWVudCdzIFVSTCAoZ2gtMjk2NSkKCQkJYmFzZSA9IGNvbnRleHQuY3JlYXRlRWxlbWVudCggImJhc2UiICk7CgkJCWJhc2UuaHJlZiA9IGRvY3VtZW50LmxvY2F0aW9uLmhyZWY7CgkJCWNvbnRleHQuaGVhZC5hcHBlbmRDaGlsZCggYmFzZSApOwoJCX0gZWxzZSB7CgkJCWNvbnRleHQgPSBkb2N1bWVudDsKCQl9Cgl9CgoJcGFyc2VkID0gcnNpbmdsZVRhZy5leGVjKCBkYXRhICk7CglzY3JpcHRzID0gIWtlZXBTY3JpcHRzICYmIFtdOwoKCS8vIFNpbmdsZSB0YWcKCWlmICggcGFyc2VkICkgewoJCXJldHVybiBbIGNvbnRleHQuY3JlYXRlRWxlbWVudCggcGFyc2VkWyAxIF0gKSBdOwoJfQoKCXBhcnNlZCA9IGJ1aWxkRnJhZ21lbnQoIFsgZGF0YSBdLCBjb250ZXh0LCBzY3JpcHRzICk7CgoJaWYgKCBzY3JpcHRzICYmIHNjcmlwdHMubGVuZ3RoICkgewoJCWpRdWVyeSggc2NyaXB0cyApLnJlbW92ZSgpOwoJfQoKCXJldHVybiBqUXVlcnkubWVyZ2UoIFtdLCBwYXJzZWQuY2hpbGROb2RlcyApOwp9OwoKCi8qKgogKiBMb2FkIGEgdXJsIGludG8gYSBwYWdlCiAqLwpqUXVlcnkuZm4ubG9hZCA9IGZ1bmN0aW9uKCB1cmwsIHBhcmFtcywgY2FsbGJhY2sgKSB7Cgl2YXIgc2VsZWN0b3IsIHR5cGUsIHJlc3BvbnNlLAoJCXNlbGYgPSB0aGlzLAoJCW9mZiA9IHVybC5pbmRleE9mKCAiICIgKTsKCglpZiAoIG9mZiA+IC0xICkgewoJCXNlbGVjdG9yID0gc3RyaXBBbmRDb2xsYXBzZSggdXJsLnNsaWNlKCBvZmYgKSApOwoJCXVybCA9IHVybC5zbGljZSggMCwgb2ZmICk7Cgl9CgoJLy8gSWYgaXQncyBhIGZ1bmN0aW9uCglpZiAoIGlzRnVuY3Rpb24oIHBhcmFtcyApICkgewoKCQkvLyBXZSBhc3N1bWUgdGhhdCBpdCdzIHRoZSBjYWxsYmFjawoJCWNhbGxiYWNrID0gcGFyYW1zOwoJCXBhcmFtcyA9IHVuZGVmaW5lZDsKCgkvLyBPdGhlcndpc2UsIGJ1aWxkIGEgcGFyYW0gc3RyaW5nCgl9IGVsc2UgaWYgKCBwYXJhbXMgJiYgdHlwZW9mIHBhcmFtcyA9PT0gIm9iamVjdCIgKSB7CgkJdHlwZSA9ICJQT1NUIjsKCX0KCgkvLyBJZiB3ZSBoYXZlIGVsZW1lbnRzIHRvIG1vZGlmeSwgbWFrZSB0aGUgcmVxdWVzdAoJaWYgKCBzZWxmLmxlbmd0aCA+IDAgKSB7CgkJalF1ZXJ5LmFqYXgoIHsKCQkJdXJsOiB1cmwsCgoJCQkvLyBJZiAidHlwZSIgdmFyaWFibGUgaXMgdW5kZWZpbmVkLCB0aGVuICJHRVQiIG1ldGhvZCB3aWxsIGJlIHVzZWQuCgkJCS8vIE1ha2UgdmFsdWUgb2YgdGhpcyBmaWVsZCBleHBsaWNpdCBzaW5jZQoJCQkvLyB1c2VyIGNhbiBvdmVycmlkZSBpdCB0aHJvdWdoIGFqYXhTZXR1cCBtZXRob2QKCQkJdHlwZTogdHlwZSB8fCAiR0VUIiwKCQkJZGF0YVR5cGU6ICJodG1sIiwKCQkJZGF0YTogcGFyYW1zCgkJfSApLmRvbmUoIGZ1bmN0aW9uKCByZXNwb25zZVRleHQgKSB7CgoJCQkvLyBTYXZlIHJlc3BvbnNlIGZvciB1c2UgaW4gY29tcGxldGUgY2FsbGJhY2sKCQkJcmVzcG9uc2UgPSBhcmd1bWVudHM7CgoJCQlzZWxmLmh0bWwoIHNlbGVjdG9yID8KCgkJCQkvLyBJZiBhIHNlbGVjdG9yIHdhcyBzcGVjaWZpZWQsIGxvY2F0ZSB0aGUgcmlnaHQgZWxlbWVudHMgaW4gYSBkdW1teSBkaXYKCQkJCS8vIEV4Y2x1ZGUgc2NyaXB0cyB0byBhdm9pZCBJRSAnUGVybWlzc2lvbiBEZW5pZWQnIGVycm9ycwoJCQkJalF1ZXJ5KCAiPGRpdj4iICkuYXBwZW5kKCBqUXVlcnkucGFyc2VIVE1MKCByZXNwb25zZVRleHQgKSApLmZpbmQoIHNlbGVjdG9yICkgOgoKCQkJCS8vIE90aGVyd2lzZSB1c2UgdGhlIGZ1bGwgcmVzdWx0CgkJCQlyZXNwb25zZVRleHQgKTsKCgkJLy8gSWYgdGhlIHJlcXVlc3Qgc3VjY2VlZHMsIHRoaXMgZnVuY3Rpb24gZ2V0cyAiZGF0YSIsICJzdGF0dXMiLCAianFYSFIiCgkJLy8gYnV0IHRoZXkgYXJlIGlnbm9yZWQgYmVjYXVzZSByZXNwb25zZSB3YXMgc2V0IGFib3ZlLgoJCS8vIElmIGl0IGZhaWxzLCB0aGlzIGZ1bmN0aW9uIGdldHMgImpxWEhSIiwgInN0YXR1cyIsICJlcnJvciIKCQl9ICkuYWx3YXlzKCBjYWxsYmFjayAmJiBmdW5jdGlvbigganFYSFIsIHN0YXR1cyApIHsKCQkJc2VsZi5lYWNoKCBmdW5jdGlvbigpIHsKCQkJCWNhbGxiYWNrLmFwcGx5KCB0aGlzLCByZXNwb25zZSB8fCBbIGpxWEhSLnJlc3BvbnNlVGV4dCwgc3RhdHVzLCBqcVhIUiBdICk7CgkJCX0gKTsKCQl9ICk7Cgl9CgoJcmV0dXJuIHRoaXM7Cn07CgoKCgovLyBBdHRhY2ggYSBidW5jaCBvZiBmdW5jdGlvbnMgZm9yIGhhbmRsaW5nIGNvbW1vbiBBSkFYIGV2ZW50cwpqUXVlcnkuZWFjaCggWwoJImFqYXhTdGFydCIsCgkiYWpheFN0b3AiLAoJImFqYXhDb21wbGV0ZSIsCgkiYWpheEVycm9yIiwKCSJhamF4U3VjY2VzcyIsCgkiYWpheFNlbmQiCl0sIGZ1bmN0aW9uKCBpLCB0eXBlICkgewoJalF1ZXJ5LmZuWyB0eXBlIF0gPSBmdW5jdGlvbiggZm4gKSB7CgkJcmV0dXJuIHRoaXMub24oIHR5cGUsIGZuICk7Cgl9Owp9ICk7CgoKCgpqUXVlcnkuZXhwci5wc2V1ZG9zLmFuaW1hdGVkID0gZnVuY3Rpb24oIGVsZW0gKSB7CglyZXR1cm4galF1ZXJ5LmdyZXAoIGpRdWVyeS50aW1lcnMsIGZ1bmN0aW9uKCBmbiApIHsKCQlyZXR1cm4gZWxlbSA9PT0gZm4uZWxlbTsKCX0gKS5sZW5ndGg7Cn07CgoKCgpqUXVlcnkub2Zmc2V0ID0gewoJc2V0T2Zmc2V0OiBmdW5jdGlvbiggZWxlbSwgb3B0aW9ucywgaSApIHsKCQl2YXIgY3VyUG9zaXRpb24sIGN1ckxlZnQsIGN1ckNTU1RvcCwgY3VyVG9wLCBjdXJPZmZzZXQsIGN1ckNTU0xlZnQsIGNhbGN1bGF0ZVBvc2l0aW9uLAoJCQlwb3NpdGlvbiA9IGpRdWVyeS5jc3MoIGVsZW0sICJwb3NpdGlvbiIgKSwKCQkJY3VyRWxlbSA9IGpRdWVyeSggZWxlbSApLAoJCQlwcm9wcyA9IHt9OwoKCQkvLyBTZXQgcG9zaXRpb24gZmlyc3QsIGluLWNhc2UgdG9wL2xlZnQgYXJlIHNldCBldmVuIG9uIHN0YXRpYyBlbGVtCgkJaWYgKCBwb3NpdGlvbiA9PT0gInN0YXRpYyIgKSB7CgkJCWVsZW0uc3R5bGUucG9zaXRpb24gPSAicmVsYXRpdmUiOwoJCX0KCgkJY3VyT2Zmc2V0ID0gY3VyRWxlbS5vZmZzZXQoKTsKCQljdXJDU1NUb3AgPSBqUXVlcnkuY3NzKCBlbGVtLCAidG9wIiApOwoJCWN1ckNTU0xlZnQgPSBqUXVlcnkuY3NzKCBlbGVtLCAibGVmdCIgKTsKCQljYWxjdWxhdGVQb3NpdGlvbiA9ICggcG9zaXRpb24gPT09ICJhYnNvbHV0ZSIgfHwgcG9zaXRpb24gPT09ICJmaXhlZCIgKSAmJgoJCQkoIGN1ckNTU1RvcCArIGN1ckNTU0xlZnQgKS5pbmRleE9mKCAiYXV0byIgKSA+IC0xOwoKCQkvLyBOZWVkIHRvIGJlIGFibGUgdG8gY2FsY3VsYXRlIHBvc2l0aW9uIGlmIGVpdGhlcgoJCS8vIHRvcCBvciBsZWZ0IGlzIGF1dG8gYW5kIHBvc2l0aW9uIGlzIGVpdGhlciBhYnNvbHV0ZSBvciBmaXhlZAoJCWlmICggY2FsY3VsYXRlUG9zaXRpb24gKSB7CgkJCWN1clBvc2l0aW9uID0gY3VyRWxlbS5wb3NpdGlvbigpOwoJCQljdXJUb3AgPSBjdXJQb3NpdGlvbi50b3A7CgkJCWN1ckxlZnQgPSBjdXJQb3NpdGlvbi5sZWZ0OwoKCQl9IGVsc2UgewoJCQljdXJUb3AgPSBwYXJzZUZsb2F0KCBjdXJDU1NUb3AgKSB8fCAwOwoJCQljdXJMZWZ0ID0gcGFyc2VGbG9hdCggY3VyQ1NTTGVmdCApIHx8IDA7CgkJfQoKCQlpZiAoIGlzRnVuY3Rpb24oIG9wdGlvbnMgKSApIHsKCgkJCS8vIFVzZSBqUXVlcnkuZXh0ZW5kIGhlcmUgdG8gYWxsb3cgbW9kaWZpY2F0aW9uIG9mIGNvb3JkaW5hdGVzIGFyZ3VtZW50IChnaC0xODQ4KQoJCQlvcHRpb25zID0gb3B0aW9ucy5jYWxsKCBlbGVtLCBpLCBqUXVlcnkuZXh0ZW5kKCB7fSwgY3VyT2Zmc2V0ICkgKTsKCQl9CgoJCWlmICggb3B0aW9ucy50b3AgIT0gbnVsbCApIHsKCQkJcHJvcHMudG9wID0gKCBvcHRpb25zLnRvcCAtIGN1ck9mZnNldC50b3AgKSArIGN1clRvcDsKCQl9CgkJaWYgKCBvcHRpb25zLmxlZnQgIT0gbnVsbCApIHsKCQkJcHJvcHMubGVmdCA9ICggb3B0aW9ucy5sZWZ0IC0gY3VyT2Zmc2V0LmxlZnQgKSArIGN1ckxlZnQ7CgkJfQoKCQlpZiAoICJ1c2luZyIgaW4gb3B0aW9ucyApIHsKCQkJb3B0aW9ucy51c2luZy5jYWxsKCBlbGVtLCBwcm9wcyApOwoKCQl9IGVsc2UgewoJCQljdXJFbGVtLmNzcyggcHJvcHMgKTsKCQl9Cgl9Cn07CgpqUXVlcnkuZm4uZXh0ZW5kKCB7CgoJLy8gb2Zmc2V0KCkgcmVsYXRlcyBhbiBlbGVtZW50J3MgYm9yZGVyIGJveCB0byB0aGUgZG9jdW1lbnQgb3JpZ2luCglvZmZzZXQ6IGZ1bmN0aW9uKCBvcHRpb25zICkgewoKCQkvLyBQcmVzZXJ2ZSBjaGFpbmluZyBmb3Igc2V0dGVyCgkJaWYgKCBhcmd1bWVudHMubGVuZ3RoICkgewoJCQlyZXR1cm4gb3B0aW9ucyA9PT0gdW5kZWZpbmVkID8KCQkJCXRoaXMgOgoJCQkJdGhpcy5lYWNoKCBmdW5jdGlvbiggaSApIHsKCQkJCQlqUXVlcnkub2Zmc2V0LnNldE9mZnNldCggdGhpcywgb3B0aW9ucywgaSApOwoJCQkJfSApOwoJCX0KCgkJdmFyIHJlY3QsIHdpbiwKCQkJZWxlbSA9IHRoaXNbIDAgXTsKCgkJaWYgKCAhZWxlbSApIHsKCQkJcmV0dXJuOwoJCX0KCgkJLy8gUmV0dXJuIHplcm9zIGZvciBkaXNjb25uZWN0ZWQgYW5kIGhpZGRlbiAoZGlzcGxheTogbm9uZSkgZWxlbWVudHMgKGdoLTIzMTApCgkJLy8gU3VwcG9ydDogSUUgPD0xMSBvbmx5CgkJLy8gUnVubmluZyBnZXRCb3VuZGluZ0NsaWVudFJlY3Qgb24gYQoJCS8vIGRpc2Nvbm5lY3RlZCBub2RlIGluIElFIHRocm93cyBhbiBlcnJvcgoJCWlmICggIWVsZW0uZ2V0Q2xpZW50UmVjdHMoKS5sZW5ndGggKSB7CgkJCXJldHVybiB7IHRvcDogMCwgbGVmdDogMCB9OwoJCX0KCgkJLy8gR2V0IGRvY3VtZW50LXJlbGF0aXZlIHBvc2l0aW9uIGJ5IGFkZGluZyB2aWV3cG9ydCBzY3JvbGwgdG8gdmlld3BvcnQtcmVsYXRpdmUgZ0JDUgoJCXJlY3QgPSBlbGVtLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpOwoJCXdpbiA9IGVsZW0ub3duZXJEb2N1bWVudC5kZWZhdWx0VmlldzsKCQlyZXR1cm4gewoJCQl0b3A6IHJlY3QudG9wICsgd2luLnBhZ2VZT2Zmc2V0LAoJCQlsZWZ0OiByZWN0LmxlZnQgKyB3aW4ucGFnZVhPZmZzZXQKCQl9OwoJfSwKCgkvLyBwb3NpdGlvbigpIHJlbGF0ZXMgYW4gZWxlbWVudCdzIG1hcmdpbiBib3ggdG8gaXRzIG9mZnNldCBwYXJlbnQncyBwYWRkaW5nIGJveAoJLy8gVGhpcyBjb3JyZXNwb25kcyB0byB0aGUgYmVoYXZpb3Igb2YgQ1NTIGFic29sdXRlIHBvc2l0aW9uaW5nCglwb3NpdGlvbjogZnVuY3Rpb24oKSB7CgkJaWYgKCAhdGhpc1sgMCBdICkgewoJCQlyZXR1cm47CgkJfQoKCQl2YXIgb2Zmc2V0UGFyZW50LCBvZmZzZXQsIGRvYywKCQkJZWxlbSA9IHRoaXNbIDAgXSwKCQkJcGFyZW50T2Zmc2V0ID0geyB0b3A6IDAsIGxlZnQ6IDAgfTsKCgkJLy8gcG9zaXRpb246Zml4ZWQgZWxlbWVudHMgYXJlIG9mZnNldCBmcm9tIHRoZSB2aWV3cG9ydCwgd2hpY2ggaXRzZWxmIGFsd2F5cyBoYXMgemVybyBvZmZzZXQKCQlpZiAoIGpRdWVyeS5jc3MoIGVsZW0sICJwb3NpdGlvbiIgKSA9PT0gImZpeGVkIiApIHsKCgkJCS8vIEFzc3VtZSBwb3NpdGlvbjpmaXhlZCBpbXBsaWVzIGF2YWlsYWJpbGl0eSBvZiBnZXRCb3VuZGluZ0NsaWVudFJlY3QKCQkJb2Zmc2V0ID0gZWxlbS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTsKCgkJfSBlbHNlIHsKCQkJb2Zmc2V0ID0gdGhpcy5vZmZzZXQoKTsKCgkJCS8vIEFjY291bnQgZm9yIHRoZSAqcmVhbCogb2Zmc2V0IHBhcmVudCwgd2hpY2ggY2FuIGJlIHRoZSBkb2N1bWVudCBvciBpdHMgcm9vdCBlbGVtZW50CgkJCS8vIHdoZW4gYSBzdGF0aWNhbGx5IHBvc2l0aW9uZWQgZWxlbWVudCBpcyBpZGVudGlmaWVkCgkJCWRvYyA9IGVsZW0ub3duZXJEb2N1bWVudDsKCQkJb2Zmc2V0UGFyZW50ID0gZWxlbS5vZmZzZXRQYXJlbnQgfHwgZG9jLmRvY3VtZW50RWxlbWVudDsKCQkJd2hpbGUgKCBvZmZzZXRQYXJlbnQgJiYKCQkJCSggb2Zmc2V0UGFyZW50ID09PSBkb2MuYm9keSB8fCBvZmZzZXRQYXJlbnQgPT09IGRvYy5kb2N1bWVudEVsZW1lbnQgKSAmJgoJCQkJalF1ZXJ5LmNzcyggb2Zmc2V0UGFyZW50LCAicG9zaXRpb24iICkgPT09ICJzdGF0aWMiICkgewoKCQkJCW9mZnNldFBhcmVudCA9IG9mZnNldFBhcmVudC5wYXJlbnROb2RlOwoJCQl9CgkJCWlmICggb2Zmc2V0UGFyZW50ICYmIG9mZnNldFBhcmVudCAhPT0gZWxlbSAmJiBvZmZzZXRQYXJlbnQubm9kZVR5cGUgPT09IDEgKSB7CgoJCQkJLy8gSW5jb3Jwb3JhdGUgYm9yZGVycyBpbnRvIGl0cyBvZmZzZXQsIHNpbmNlIHRoZXkgYXJlIG91dHNpZGUgaXRzIGNvbnRlbnQgb3JpZ2luCgkJCQlwYXJlbnRPZmZzZXQgPSBqUXVlcnkoIG9mZnNldFBhcmVudCApLm9mZnNldCgpOwoJCQkJcGFyZW50T2Zmc2V0LnRvcCArPSBqUXVlcnkuY3NzKCBvZmZzZXRQYXJlbnQsICJib3JkZXJUb3BXaWR0aCIsIHRydWUgKTsKCQkJCXBhcmVudE9mZnNldC5sZWZ0ICs9IGpRdWVyeS5jc3MoIG9mZnNldFBhcmVudCwgImJvcmRlckxlZnRXaWR0aCIsIHRydWUgKTsKCQkJfQoJCX0KCgkJLy8gU3VidHJhY3QgcGFyZW50IG9mZnNldHMgYW5kIGVsZW1lbnQgbWFyZ2lucwoJCXJldHVybiB7CgkJCXRvcDogb2Zmc2V0LnRvcCAtIHBhcmVudE9mZnNldC50b3AgLSBqUXVlcnkuY3NzKCBlbGVtLCAibWFyZ2luVG9wIiwgdHJ1ZSApLAoJCQlsZWZ0OiBvZmZzZXQubGVmdCAtIHBhcmVudE9mZnNldC5sZWZ0IC0galF1ZXJ5LmNzcyggZWxlbSwgIm1hcmdpbkxlZnQiLCB0cnVlICkKCQl9OwoJfSwKCgkvLyBUaGlzIG1ldGhvZCB3aWxsIHJldHVybiBkb2N1bWVudEVsZW1lbnQgaW4gdGhlIGZvbGxvd2luZyBjYXNlczoKCS8vIDEpIEZvciB0aGUgZWxlbWVudCBpbnNpZGUgdGhlIGlmcmFtZSB3aXRob3V0IG9mZnNldFBhcmVudCwgdGhpcyBtZXRob2Qgd2lsbCByZXR1cm4KCS8vICAgIGRvY3VtZW50RWxlbWVudCBvZiB0aGUgcGFyZW50IHdpbmRvdwoJLy8gMikgRm9yIHRoZSBoaWRkZW4gb3IgZGV0YWNoZWQgZWxlbWVudAoJLy8gMykgRm9yIGJvZHkgb3IgaHRtbCBlbGVtZW50LCBpLmUuIGluIGNhc2Ugb2YgdGhlIGh0bWwgbm9kZSAtIGl0IHdpbGwgcmV0dXJuIGl0c2VsZgoJLy8KCS8vIGJ1dCB0aG9zZSBleGNlcHRpb25zIHdlcmUgbmV2ZXIgcHJlc2VudGVkIGFzIGEgcmVhbCBsaWZlIHVzZS1jYXNlcwoJLy8gYW5kIG1pZ2h0IGJlIGNvbnNpZGVyZWQgYXMgbW9yZSBwcmVmZXJhYmxlIHJlc3VsdHMuCgkvLwoJLy8gVGhpcyBsb2dpYywgaG93ZXZlciwgaXMgbm90IGd1YXJhbnRlZWQgYW5kIGNhbiBjaGFuZ2UgYXQgYW55IHBvaW50IGluIHRoZSBmdXR1cmUKCW9mZnNldFBhcmVudDogZnVuY3Rpb24oKSB7CgkJcmV0dXJuIHRoaXMubWFwKCBmdW5jdGlvbigpIHsKCQkJdmFyIG9mZnNldFBhcmVudCA9IHRoaXMub2Zmc2V0UGFyZW50OwoKCQkJd2hpbGUgKCBvZmZzZXRQYXJlbnQgJiYgalF1ZXJ5LmNzcyggb2Zmc2V0UGFyZW50LCAicG9zaXRpb24iICkgPT09ICJzdGF0aWMiICkgewoJCQkJb2Zmc2V0UGFyZW50ID0gb2Zmc2V0UGFyZW50Lm9mZnNldFBhcmVudDsKCQkJfQoKCQkJcmV0dXJuIG9mZnNldFBhcmVudCB8fCBkb2N1bWVudEVsZW1lbnQ7CgkJfSApOwoJfQp9ICk7CgovLyBDcmVhdGUgc2Nyb2xsTGVmdCBhbmQgc2Nyb2xsVG9wIG1ldGhvZHMKalF1ZXJ5LmVhY2goIHsgc2Nyb2xsTGVmdDogInBhZ2VYT2Zmc2V0Iiwgc2Nyb2xsVG9wOiAicGFnZVlPZmZzZXQiIH0sIGZ1bmN0aW9uKCBtZXRob2QsIHByb3AgKSB7Cgl2YXIgdG9wID0gInBhZ2VZT2Zmc2V0IiA9PT0gcHJvcDsKCglqUXVlcnkuZm5bIG1ldGhvZCBdID0gZnVuY3Rpb24oIHZhbCApIHsKCQlyZXR1cm4gYWNjZXNzKCB0aGlzLCBmdW5jdGlvbiggZWxlbSwgbWV0aG9kLCB2YWwgKSB7CgoJCQkvLyBDb2FsZXNjZSBkb2N1bWVudHMgYW5kIHdpbmRvd3MKCQkJdmFyIHdpbjsKCQkJaWYgKCBpc1dpbmRvdyggZWxlbSApICkgewoJCQkJd2luID0gZWxlbTsKCQkJfSBlbHNlIGlmICggZWxlbS5ub2RlVHlwZSA9PT0gOSApIHsKCQkJCXdpbiA9IGVsZW0uZGVmYXVsdFZpZXc7CgkJCX0KCgkJCWlmICggdmFsID09PSB1bmRlZmluZWQgKSB7CgkJCQlyZXR1cm4gd2luID8gd2luWyBwcm9wIF0gOiBlbGVtWyBtZXRob2QgXTsKCQkJfQoKCQkJaWYgKCB3aW4gKSB7CgkJCQl3aW4uc2Nyb2xsVG8oCgkJCQkJIXRvcCA/IHZhbCA6IHdpbi5wYWdlWE9mZnNldCwKCQkJCQl0b3AgPyB2YWwgOiB3aW4ucGFnZVlPZmZzZXQKCQkJCSk7CgoJCQl9IGVsc2UgewoJCQkJZWxlbVsgbWV0aG9kIF0gPSB2YWw7CgkJCX0KCQl9LCBtZXRob2QsIHZhbCwgYXJndW1lbnRzLmxlbmd0aCApOwoJfTsKfSApOwoKLy8gU3VwcG9ydDogU2FmYXJpIDw9NyAtIDkuMSwgQ2hyb21lIDw9MzcgLSA0OQovLyBBZGQgdGhlIHRvcC9sZWZ0IGNzc0hvb2tzIHVzaW5nIGpRdWVyeS5mbi5wb3NpdGlvbgovLyBXZWJraXQgYnVnOiBodHRwczovL2J1Z3Mud2Via2l0Lm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MjkwODQKLy8gQmxpbmsgYnVnOiBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvY2hyb21pdW0vaXNzdWVzL2RldGFpbD9pZD01ODkzNDcKLy8gZ2V0Q29tcHV0ZWRTdHlsZSByZXR1cm5zIHBlcmNlbnQgd2hlbiBzcGVjaWZpZWQgZm9yIHRvcC9sZWZ0L2JvdHRvbS9yaWdodDsKLy8gcmF0aGVyIHRoYW4gbWFrZSB0aGUgY3NzIG1vZHVsZSBkZXBlbmQgb24gdGhlIG9mZnNldCBtb2R1bGUsIGp1c3QgY2hlY2sgZm9yIGl0IGhlcmUKalF1ZXJ5LmVhY2goIFsgInRvcCIsICJsZWZ0IiBdLCBmdW5jdGlvbiggaSwgcHJvcCApIHsKCWpRdWVyeS5jc3NIb29rc1sgcHJvcCBdID0gYWRkR2V0SG9va0lmKCBzdXBwb3J0LnBpeGVsUG9zaXRpb24sCgkJZnVuY3Rpb24oIGVsZW0sIGNvbXB1dGVkICkgewoJCQlpZiAoIGNvbXB1dGVkICkgewoJCQkJY29tcHV0ZWQgPSBjdXJDU1MoIGVsZW0sIHByb3AgKTsKCgkJCQkvLyBJZiBjdXJDU1MgcmV0dXJucyBwZXJjZW50YWdlLCBmYWxsYmFjayB0byBvZmZzZXQKCQkJCXJldHVybiBybnVtbm9ucHgudGVzdCggY29tcHV0ZWQgKSA/CgkJCQkJalF1ZXJ5KCBlbGVtICkucG9zaXRpb24oKVsgcHJvcCBdICsgInB4IiA6CgkJCQkJY29tcHV0ZWQ7CgkJCX0KCQl9CgkpOwp9ICk7CgoKLy8gQ3JlYXRlIGlubmVySGVpZ2h0LCBpbm5lcldpZHRoLCBoZWlnaHQsIHdpZHRoLCBvdXRlckhlaWdodCBhbmQgb3V0ZXJXaWR0aCBtZXRob2RzCmpRdWVyeS5lYWNoKCB7IEhlaWdodDogImhlaWdodCIsIFdpZHRoOiAid2lkdGgiIH0sIGZ1bmN0aW9uKCBuYW1lLCB0eXBlICkgewoJalF1ZXJ5LmVhY2goIHsgcGFkZGluZzogImlubmVyIiArIG5hbWUsIGNvbnRlbnQ6IHR5cGUsICIiOiAib3V0ZXIiICsgbmFtZSB9LAoJCWZ1bmN0aW9uKCBkZWZhdWx0RXh0cmEsIGZ1bmNOYW1lICkgewoKCQkvLyBNYXJnaW4gaXMgb25seSBmb3Igb3V0ZXJIZWlnaHQsIG91dGVyV2lkdGgKCQlqUXVlcnkuZm5bIGZ1bmNOYW1lIF0gPSBmdW5jdGlvbiggbWFyZ2luLCB2YWx1ZSApIHsKCQkJdmFyIGNoYWluYWJsZSA9IGFyZ3VtZW50cy5sZW5ndGggJiYgKCBkZWZhdWx0RXh0cmEgfHwgdHlwZW9mIG1hcmdpbiAhPT0gImJvb2xlYW4iICksCgkJCQlleHRyYSA9IGRlZmF1bHRFeHRyYSB8fCAoIG1hcmdpbiA9PT0gdHJ1ZSB8fCB2YWx1ZSA9PT0gdHJ1ZSA/ICJtYXJnaW4iIDogImJvcmRlciIgKTsKCgkJCXJldHVybiBhY2Nlc3MoIHRoaXMsIGZ1bmN0aW9uKCBlbGVtLCB0eXBlLCB2YWx1ZSApIHsKCQkJCXZhciBkb2M7CgoJCQkJaWYgKCBpc1dpbmRvdyggZWxlbSApICkgewoKCQkJCQkvLyAkKCB3aW5kb3cgKS5vdXRlcldpZHRoL0hlaWdodCByZXR1cm4gdy9oIGluY2x1ZGluZyBzY3JvbGxiYXJzIChnaC0xNzI5KQoJCQkJCXJldHVybiBmdW5jTmFtZS5pbmRleE9mKCAib3V0ZXIiICkgPT09IDAgPwoJCQkJCQllbGVtWyAiaW5uZXIiICsgbmFtZSBdIDoKCQkJCQkJZWxlbS5kb2N1bWVudC5kb2N1bWVudEVsZW1lbnRbICJjbGllbnQiICsgbmFtZSBdOwoJCQkJfQoKCQkJCS8vIEdldCBkb2N1bWVudCB3aWR0aCBvciBoZWlnaHQKCQkJCWlmICggZWxlbS5ub2RlVHlwZSA9PT0gOSApIHsKCQkJCQlkb2MgPSBlbGVtLmRvY3VtZW50RWxlbWVudDsKCgkJCQkJLy8gRWl0aGVyIHNjcm9sbFtXaWR0aC9IZWlnaHRdIG9yIG9mZnNldFtXaWR0aC9IZWlnaHRdIG9yIGNsaWVudFtXaWR0aC9IZWlnaHRdLAoJCQkJCS8vIHdoaWNoZXZlciBpcyBncmVhdGVzdAoJCQkJCXJldHVybiBNYXRoLm1heCgKCQkJCQkJZWxlbS5ib2R5WyAic2Nyb2xsIiArIG5hbWUgXSwgZG9jWyAic2Nyb2xsIiArIG5hbWUgXSwKCQkJCQkJZWxlbS5ib2R5WyAib2Zmc2V0IiArIG5hbWUgXSwgZG9jWyAib2Zmc2V0IiArIG5hbWUgXSwKCQkJCQkJZG9jWyAiY2xpZW50IiArIG5hbWUgXQoJCQkJCSk7CgkJCQl9CgoJCQkJcmV0dXJuIHZhbHVlID09PSB1bmRlZmluZWQgPwoKCQkJCQkvLyBHZXQgd2lkdGggb3IgaGVpZ2h0IG9uIHRoZSBlbGVtZW50LCByZXF1ZXN0aW5nIGJ1dCBub3QgZm9yY2luZyBwYXJzZUZsb2F0CgkJCQkJalF1ZXJ5LmNzcyggZWxlbSwgdHlwZSwgZXh0cmEgKSA6CgoJCQkJCS8vIFNldCB3aWR0aCBvciBoZWlnaHQgb24gdGhlIGVsZW1lbnQKCQkJCQlqUXVlcnkuc3R5bGUoIGVsZW0sIHR5cGUsIHZhbHVlLCBleHRyYSApOwoJCQl9LCB0eXBlLCBjaGFpbmFibGUgPyBtYXJnaW4gOiB1bmRlZmluZWQsIGNoYWluYWJsZSApOwoJCX07Cgl9ICk7Cn0gKTsKCgpqUXVlcnkuZWFjaCggKCAiYmx1ciBmb2N1cyBmb2N1c2luIGZvY3Vzb3V0IHJlc2l6ZSBzY3JvbGwgY2xpY2sgZGJsY2xpY2sgIiArCgkibW91c2Vkb3duIG1vdXNldXAgbW91c2Vtb3ZlIG1vdXNlb3ZlciBtb3VzZW91dCBtb3VzZWVudGVyIG1vdXNlbGVhdmUgIiArCgkiY2hhbmdlIHNlbGVjdCBzdWJtaXQga2V5ZG93biBrZXlwcmVzcyBrZXl1cCBjb250ZXh0bWVudSIgKS5zcGxpdCggIiAiICksCglmdW5jdGlvbiggaSwgbmFtZSApIHsKCgkvLyBIYW5kbGUgZXZlbnQgYmluZGluZwoJalF1ZXJ5LmZuWyBuYW1lIF0gPSBmdW5jdGlvbiggZGF0YSwgZm4gKSB7CgkJcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPiAwID8KCQkJdGhpcy5vbiggbmFtZSwgbnVsbCwgZGF0YSwgZm4gKSA6CgkJCXRoaXMudHJpZ2dlciggbmFtZSApOwoJfTsKfSApOwoKalF1ZXJ5LmZuLmV4dGVuZCggewoJaG92ZXI6IGZ1bmN0aW9uKCBmbk92ZXIsIGZuT3V0ICkgewoJCXJldHVybiB0aGlzLm1vdXNlZW50ZXIoIGZuT3ZlciApLm1vdXNlbGVhdmUoIGZuT3V0IHx8IGZuT3ZlciApOwoJfQp9ICk7CgoKCgpqUXVlcnkuZm4uZXh0ZW5kKCB7CgoJYmluZDogZnVuY3Rpb24oIHR5cGVzLCBkYXRhLCBmbiApIHsKCQlyZXR1cm4gdGhpcy5vbiggdHlwZXMsIG51bGwsIGRhdGEsIGZuICk7Cgl9LAoJdW5iaW5kOiBmdW5jdGlvbiggdHlwZXMsIGZuICkgewoJCXJldHVybiB0aGlzLm9mZiggdHlwZXMsIG51bGwsIGZuICk7Cgl9LAoKCWRlbGVnYXRlOiBmdW5jdGlvbiggc2VsZWN0b3IsIHR5cGVzLCBkYXRhLCBmbiApIHsKCQlyZXR1cm4gdGhpcy5vbiggdHlwZXMsIHNlbGVjdG9yLCBkYXRhLCBmbiApOwoJfSwKCXVuZGVsZWdhdGU6IGZ1bmN0aW9uKCBzZWxlY3RvciwgdHlwZXMsIGZuICkgewoKCQkvLyAoIG5hbWVzcGFjZSApIG9yICggc2VsZWN0b3IsIHR5cGVzIFssIGZuXSApCgkJcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPT09IDEgPwoJCQl0aGlzLm9mZiggc2VsZWN0b3IsICIqKiIgKSA6CgkJCXRoaXMub2ZmKCB0eXBlcywgc2VsZWN0b3IgfHwgIioqIiwgZm4gKTsKCX0KfSApOwoKLy8gQmluZCBhIGZ1bmN0aW9uIHRvIGEgY29udGV4dCwgb3B0aW9uYWxseSBwYXJ0aWFsbHkgYXBwbHlpbmcgYW55Ci8vIGFyZ3VtZW50cy4KLy8galF1ZXJ5LnByb3h5IGlzIGRlcHJlY2F0ZWQgdG8gcHJvbW90ZSBzdGFuZGFyZHMgKHNwZWNpZmljYWxseSBGdW5jdGlvbiNiaW5kKQovLyBIb3dldmVyLCBpdCBpcyBub3Qgc2xhdGVkIGZvciByZW1vdmFsIGFueSB0aW1lIHNvb24KalF1ZXJ5LnByb3h5ID0gZnVuY3Rpb24oIGZuLCBjb250ZXh0ICkgewoJdmFyIHRtcCwgYXJncywgcHJveHk7CgoJaWYgKCB0eXBlb2YgY29udGV4dCA9PT0gInN0cmluZyIgKSB7CgkJdG1wID0gZm5bIGNvbnRleHQgXTsKCQljb250ZXh0ID0gZm47CgkJZm4gPSB0bXA7Cgl9CgoJLy8gUXVpY2sgY2hlY2sgdG8gZGV0ZXJtaW5lIGlmIHRhcmdldCBpcyBjYWxsYWJsZSwgaW4gdGhlIHNwZWMKCS8vIHRoaXMgdGhyb3dzIGEgVHlwZUVycm9yLCBidXQgd2Ugd2lsbCBqdXN0IHJldHVybiB1bmRlZmluZWQuCglpZiAoICFpc0Z1bmN0aW9uKCBmbiApICkgewoJCXJldHVybiB1bmRlZmluZWQ7Cgl9CgoJLy8gU2ltdWxhdGVkIGJpbmQKCWFyZ3MgPSBzbGljZS5jYWxsKCBhcmd1bWVudHMsIDIgKTsKCXByb3h5ID0gZnVuY3Rpb24oKSB7CgkJcmV0dXJuIGZuLmFwcGx5KCBjb250ZXh0IHx8IHRoaXMsIGFyZ3MuY29uY2F0KCBzbGljZS5jYWxsKCBhcmd1bWVudHMgKSApICk7Cgl9OwoKCS8vIFNldCB0aGUgZ3VpZCBvZiB1bmlxdWUgaGFuZGxlciB0byB0aGUgc2FtZSBvZiBvcmlnaW5hbCBoYW5kbGVyLCBzbyBpdCBjYW4gYmUgcmVtb3ZlZAoJcHJveHkuZ3VpZCA9IGZuLmd1aWQgPSBmbi5ndWlkIHx8IGpRdWVyeS5ndWlkKys7CgoJcmV0dXJuIHByb3h5Owp9OwoKalF1ZXJ5LmhvbGRSZWFkeSA9IGZ1bmN0aW9uKCBob2xkICkgewoJaWYgKCBob2xkICkgewoJCWpRdWVyeS5yZWFkeVdhaXQrKzsKCX0gZWxzZSB7CgkJalF1ZXJ5LnJlYWR5KCB0cnVlICk7Cgl9Cn07CmpRdWVyeS5pc0FycmF5ID0gQXJyYXkuaXNBcnJheTsKalF1ZXJ5LnBhcnNlSlNPTiA9IEpTT04ucGFyc2U7CmpRdWVyeS5ub2RlTmFtZSA9IG5vZGVOYW1lOwpqUXVlcnkuaXNGdW5jdGlvbiA9IGlzRnVuY3Rpb247CmpRdWVyeS5pc1dpbmRvdyA9IGlzV2luZG93OwpqUXVlcnkuY2FtZWxDYXNlID0gY2FtZWxDYXNlOwpqUXVlcnkudHlwZSA9IHRvVHlwZTsKCmpRdWVyeS5ub3cgPSBEYXRlLm5vdzsKCmpRdWVyeS5pc051bWVyaWMgPSBmdW5jdGlvbiggb2JqICkgewoKCS8vIEFzIG9mIGpRdWVyeSAzLjAsIGlzTnVtZXJpYyBpcyBsaW1pdGVkIHRvCgkvLyBzdHJpbmdzIGFuZCBudW1iZXJzIChwcmltaXRpdmVzIG9yIG9iamVjdHMpCgkvLyB0aGF0IGNhbiBiZSBjb2VyY2VkIHRvIGZpbml0ZSBudW1iZXJzIChnaC0yNjYyKQoJdmFyIHR5cGUgPSBqUXVlcnkudHlwZSggb2JqICk7CglyZXR1cm4gKCB0eXBlID09PSAibnVtYmVyIiB8fCB0eXBlID09PSAic3RyaW5nIiApICYmCgoJCS8vIHBhcnNlRmxvYXQgTmFOcyBudW1lcmljLWNhc3QgZmFsc2UgcG9zaXRpdmVzICgiIikKCQkvLyAuLi5idXQgbWlzaW50ZXJwcmV0cyBsZWFkaW5nLW51bWJlciBzdHJpbmdzLCBwYXJ0aWN1bGFybHkgaGV4IGxpdGVyYWxzICgiMHguLi4iKQoJCS8vIHN1YnRyYWN0aW9uIGZvcmNlcyBpbmZpbml0aWVzIHRvIE5hTgoJCSFpc05hTiggb2JqIC0gcGFyc2VGbG9hdCggb2JqICkgKTsKfTsKCgoKCi8vIFJlZ2lzdGVyIGFzIGEgbmFtZWQgQU1EIG1vZHVsZSwgc2luY2UgalF1ZXJ5IGNhbiBiZSBjb25jYXRlbmF0ZWQgd2l0aCBvdGhlcgovLyBmaWxlcyB0aGF0IG1heSB1c2UgZGVmaW5lLCBidXQgbm90IHZpYSBhIHByb3BlciBjb25jYXRlbmF0aW9uIHNjcmlwdCB0aGF0Ci8vIHVuZGVyc3RhbmRzIGFub255bW91cyBBTUQgbW9kdWxlcy4gQSBuYW1lZCBBTUQgaXMgc2FmZXN0IGFuZCBtb3N0IHJvYnVzdAovLyB3YXkgdG8gcmVnaXN0ZXIuIExvd2VyY2FzZSBqcXVlcnkgaXMgdXNlZCBiZWNhdXNlIEFNRCBtb2R1bGUgbmFtZXMgYXJlCi8vIGRlcml2ZWQgZnJvbSBmaWxlIG5hbWVzLCBhbmQgalF1ZXJ5IGlzIG5vcm1hbGx5IGRlbGl2ZXJlZCBpbiBhIGxvd2VyY2FzZQovLyBmaWxlIG5hbWUuIERvIHRoaXMgYWZ0ZXIgY3JlYXRpbmcgdGhlIGdsb2JhbCBzbyB0aGF0IGlmIGFuIEFNRCBtb2R1bGUgd2FudHMKLy8gdG8gY2FsbCBub0NvbmZsaWN0IHRvIGhpZGUgdGhpcyB2ZXJzaW9uIG9mIGpRdWVyeSwgaXQgd2lsbCB3b3JrLgoKLy8gTm90ZSB0aGF0IGZvciBtYXhpbXVtIHBvcnRhYmlsaXR5LCBsaWJyYXJpZXMgdGhhdCBhcmUgbm90IGpRdWVyeSBzaG91bGQKLy8gZGVjbGFyZSB0aGVtc2VsdmVzIGFzIGFub255bW91cyBtb2R1bGVzLCBhbmQgYXZvaWQgc2V0dGluZyBhIGdsb2JhbCBpZiBhbgovLyBBTUQgbG9hZGVyIGlzIHByZXNlbnQuIGpRdWVyeSBpcyBhIHNwZWNpYWwgY2FzZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZQovLyBodHRwczovL2dpdGh1Yi5jb20vanJidXJrZS9yZXF1aXJlanMvd2lraS9VcGRhdGluZy1leGlzdGluZy1saWJyYXJpZXMjd2lraS1hbm9uCgppZiAoIHR5cGVvZiBkZWZpbmUgPT09ICJmdW5jdGlvbiIgJiYgZGVmaW5lLmFtZCApIHsKCWRlZmluZSggImpxdWVyeSIsIFtdLCBmdW5jdGlvbigpIHsKCQlyZXR1cm4galF1ZXJ5OwoJfSApOwp9CgoKCgp2YXIKCgkvLyBNYXAgb3ZlciBqUXVlcnkgaW4gY2FzZSBvZiBvdmVyd3JpdGUKCV9qUXVlcnkgPSB3aW5kb3cualF1ZXJ5LAoKCS8vIE1hcCBvdmVyIHRoZSAkIGluIGNhc2Ugb2Ygb3ZlcndyaXRlCglfJCA9IHdpbmRvdy4kOwoKalF1ZXJ5Lm5vQ29uZmxpY3QgPSBmdW5jdGlvbiggZGVlcCApIHsKCWlmICggd2luZG93LiQgPT09IGpRdWVyeSApIHsKCQl3aW5kb3cuJCA9IF8kOwoJfQoKCWlmICggZGVlcCAmJiB3aW5kb3cualF1ZXJ5ID09PSBqUXVlcnkgKSB7CgkJd2luZG93LmpRdWVyeSA9IF9qUXVlcnk7Cgl9CgoJcmV0dXJuIGpRdWVyeTsKfTsKCi8vIEV4cG9zZSBqUXVlcnkgYW5kICQgaWRlbnRpZmllcnMsIGV2ZW4gaW4gQU1ECi8vICgjNzEwMiNjb21tZW50OjEwLCBodHRwczovL2dpdGh1Yi5jb20vanF1ZXJ5L2pxdWVyeS9wdWxsLzU1NykKLy8gYW5kIENvbW1vbkpTIGZvciBicm93c2VyIGVtdWxhdG9ycyAoIzEzNTY2KQppZiAoICFub0dsb2JhbCApIHsKCXdpbmRvdy5qUXVlcnkgPSB3aW5kb3cuJCA9IGpRdWVyeTsKfQoKCgoKcmV0dXJuIGpRdWVyeTsKfSApOwo=" >
</script>
<!-- <script type="text/javascript" src="js/custom.js"></script> -->
<!-- <script type="text/javascript" src="js/custom.js"></script> -->
<script type="text/javascript">
$(function() {
// grab the file input and bind a change event onto it
$('#file').bind("change", function() {
// new html5 formdata object.
var formData = new FormData();
// for each entry, add to formdata to later access via $_FILES["file" + i]
for (var i = 0, len = document.getElementById('file').files.length; i < len; i++) {
formData.append("file" + i, document.getElementById('file').files[i]);
}
//send formdata to server-side
$.ajax({
// url: "file-upload.php", // our php file
// url: "index_sc_fileupload.php", // our php file
// nurl: "http://index_sc.php?q=up", // our php file
// url: "./kup.php", // our php file
// url: "./index_sc_up.php", // our php file
// url: "./index_sc.php?q=kup", // our php file
// url: "./ko0.php?q=kup", // our php file
// url: "./ko1.php?q=kup", // our php file
url: "./ko2.php?q=kup", // our php file
// bugs url: "10.0.0.112:/index_sc.php?q=up", // our php file
type: 'post',
data: formData,
dataType: 'html', // we return html from our php file
async: true,
processData: false, // tell jQuery not to process the data
contentType: false, // tell jQuery not to set contentType
success : function(data) {
$('#upload-result').append('<div class="alert alert-success"><p>File(s) uploaded successfully!</p><br />');
$('#upload-result .alert').append(data);
},
error : function(request) {
console.log(request.responseText);
}
});
});
});
</script>
<hr color=white>
<hr color=black>
<div id='editableDiv' contenteditable='true'>paste</div>
<hr color=black>
<hr color=white>
<hr color=black>
<div id='div' contenteditable='true'>ffpaste</div>
<hr color=black>
<hr color=white>
<script id="script_clipboard" >
function handlePaste (e) {
var clipboardData, pastedData;
// Stop data actually being pasted into div
e.stopPropagation();
e.preventDefault();
// Get pasted data via clipboard API
clipboardData = e.clipboardData || window.clipboardData;
pastedData = clipboardData.getData('Text');
// Do whatever with pasteddata
alert(pastedData);
}
document.getElementById('editableDiv').addEventListener('paste', handlePaste);
</script>
<script id="script_clipboard_ff" >
function handlepaste_ff (e) {
var types, pastedData, savedContent;
// Browsers that support the 'text/html' type in the Clipboard API (Chrome, Firefox 22+)
if (e && e.clipboardData && e.clipboardData.types && e.clipboardData.getData) {
// Check for 'text/html' in types list. See abligh's answer below for deatils on
// why the DOMStringList bit is needed. We cannot fall back to 'text/plain' as
// Safari/Edge don't advertise HTML data even if it is available
types = e.clipboardData.types;
if (((types instanceof DOMStringList) && types.contains("text/html")) || (types.index_scOf && types.index_scOf('text/html') !== -1)) {
// Extract data and pass it to callback
pastedData = e.clipboardData.getData('text/html');
// processPaste(editableDiv, pastedData);
processPaste_ff(editableDiv, pastedData);
// Stop the data from actually being pasted
e.stopPropagation();
e.preventDefault();
return false;
}
}
// Everything else: Move existing element contents to a DocumentFragment for safekeeping
savedContent = document.createDocumentFragment();
while(editableDiv.childNodes.length > 0) {
savedContent.appendChild(editableDiv.childNodes[0]);
}
// Then wait for browser to paste content into it and cleanup
waitForPastedData(editableDiv, savedContent);
return true;
}
function waitForPastedData (elem, savedContent) {
// If data has been processes by browser, process it
if (elem.childNodes && elem.childNodes.length > 0) {
// Retrieve pasted content via innerHTML
// (Alternatively loop through elem.childNodes or elem.getElementsByTagName here)
var pastedData = elem.innerHTML;
// Restore saved content
elem.innerHTML = "";
elem.appendChild(savedContent);
// Call callback
processPaste_ff(elem, pastedData);
}
// Else wait 20ms and try again
else {
setTimeout(function () {
waitForPastedData(elem, savedContent)
}, 20);
}
}
function processPaste_ff (elem, pastedData) {
// Do whatever with gathered data;
alert(pastedData);
elem.focus();
}
// Modern browsers. Note: 3rd argument is required for Firefox <= 6
if (editableDiv.addEventListener) {
editableDiv.addEventListener('paste', handlepaste, false);
}
// IE <= 8
else {
editableDiv.attachEvent('onpaste', handlepaste);
}
$(document).on('paste','[contenteditable]',function(e) {
e.preventDefault();
var text = (e.originalEvent || e).clipboardData.getData('text/plain');
window.document.execCommand('insertText', false, text);
});
</script>
<script id="script_clipboard_jskit" >
function getSelectionText(){
var selectedText = ""
if (window.getSelection){ // all modern browsers and IE9+
selectedText = window.getSelection().toString()
}
return selectedText
}
document.addEventListener('mouseup', function(){
var thetext = getSelectionText()
if (thetext.length > 0){ // check there's some text selected
console.log(thetext) // logs whatever textual content the user has selected on the page
}
}, false)
function copySelectionText(){
var copysuccess // var to check whether execCommand successfully executed
try{
copysuccess = document.execCommand("copy") // run command to copy selected text to clipboard
}
catch(e){
copysuccess = false
}
return copysuccess
}
</script>
<div name="div_dd" id="div_dd" hidden>
<div id="drop">
<span id="sw"><h1>drop jtfinc</h2></span>
<a href=./ko_jtf/zm/jtf_parcels/jtfdc_theater.html target=_blank>
<img height=200 width=300
src="./ko_jtf/zm/jtf_parcels/jtfdc_theater/TileGroup0/0-0-0.png" border=0 >
</a>
</div>
<div id="drag"> jtfdc:<br />
<img src="./imgs/jtf/jtf_takes/jtf29_eagle_north.png" alt="jtf29_eagle_north" width="50" class="drg"/>
<div class="drg"><h1>konet llc </h1>
<pre>timejask jkwii</pre>
<img class="drg" src="./imgs/btn/ko.png" alt="ko.png" width="50" >
<img class="drg" src="./imgs/btn/ok.png" alt="ok.png" width="50" >
<pre>timesak skwii</pre>
</div>
<div class="drg"><h1>jtf29 </h1>
<a href=./ko_jtf/zm/jtf_parcels/jtf29.html target=_blank>
<img height=200 width=100 src="./ko_jtf/zm/jtf_parcels/jtf29/TileGroup0/0-0-0.png" border=0 >
</a>
</div>
<div class="drg"><h1>dogheads</h1>
<div id="div_jtf_vid5">
<video controls="controls_jtf5" defaultmuted="" muted="true" style="width:320px;height:180px;" poster="index_sc4_mp4.png">
<source src="./kb/v/doghead_video.mp4" type="video/mp4;codecs="avc1.42E01E, mp4a.40.2"">
</video>
</div>
</div>
<div class="drg"><h1>jtfdc night court lights action 3720</h1>
<div id="div_vid">
<video controls="controls" defaultmuted="" muted="true" style="width:320px;height:180px;" poster="index_sc_mp4.png">
<source src="index_sc1_avril.mp4" type="video/mp4;codecs="avc1.42E01E, mp4a.40.2"">
<source src="index_sc_avril.webm" type="video/webm;codecs="vp8, vorbis"">
</video>
</div>
</div>
</div>
</div>
<!--
<iframe id="iframe_dd" src="./index_sc_dd.html" width="1000" height="500"
frameborder="0" scrolling="yes">
</iframe>
-->
<a class="popover" href="./kup.html?q=kup" target=_blank >
<img src="./imgs/btn/koeye.png" height="100" width="200" alt="koeyew" >
<span><img src="./imgs/anim/eyes/koeye_hand.gif" height="100" width="200" alt="koeyew" ></span>
</a>
</body>
</html>
//
koh5_pano
Drag mouse to navigate.
Navigation
- Left/Right Mouse drag: Changes camera heading.
- Up/Sown Mouse drag: Changes camera pitch.
- Scroll wheel: Changes camera field of view.
- I-Key: Displays Info panel with canvas size, image size and FPS.
17.Aug.2010, Martin Wengenmayer